diff options
author | Jens Axboe <jaxboe@fusionio.com> | 2010-10-19 03:13:04 -0400 |
---|---|---|
committer | Jens Axboe <jaxboe@fusionio.com> | 2010-10-19 03:13:04 -0400 |
commit | fa251f89903d73989e2f63e13d0eaed1e07ce0da (patch) | |
tree | 3f7fe779941e3b6d67754dd7c44a32f48ea47c74 | |
parent | dd3932eddf428571762596e17b65f5dc92ca361b (diff) | |
parent | cd07202cc8262e1669edff0d97715f3dd9260917 (diff) |
Merge branch 'v2.6.36-rc8' into for-2.6.37/barrier
Conflicts:
block/blk-core.c
drivers/block/loop.c
mm/swapfile.c
Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
1408 files changed, 17043 insertions, 13737 deletions
@@ -3554,12 +3554,12 @@ E: cvance@nai.com | |||
3554 | D: portions of the Linux Security Module (LSM) framework and security modules | 3554 | D: portions of the Linux Security Module (LSM) framework and security modules |
3555 | 3555 | ||
3556 | N: Petr Vandrovec | 3556 | N: Petr Vandrovec |
3557 | E: vandrove@vc.cvut.cz | 3557 | E: petr@vandrovec.name |
3558 | D: Small contributions to ncpfs | 3558 | D: Small contributions to ncpfs |
3559 | D: Matrox framebuffer driver | 3559 | D: Matrox framebuffer driver |
3560 | S: Chudenicka 8 | 3560 | S: 21513 Conradia Ct |
3561 | S: 10200 Prague 10, Hostivar | 3561 | S: Cupertino, CA 95014 |
3562 | S: Czech Republic | 3562 | S: USA |
3563 | 3563 | ||
3564 | N: Thibaut Varene | 3564 | N: Thibaut Varene |
3565 | E: T-Bone@parisc-linux.org | 3565 | E: T-Bone@parisc-linux.org |
diff --git a/Documentation/DocBook/device-drivers.tmpl b/Documentation/DocBook/device-drivers.tmpl index ecd35e9d441..feca0758391 100644 --- a/Documentation/DocBook/device-drivers.tmpl +++ b/Documentation/DocBook/device-drivers.tmpl | |||
@@ -46,7 +46,6 @@ | |||
46 | 46 | ||
47 | <sect1><title>Atomic and pointer manipulation</title> | 47 | <sect1><title>Atomic and pointer manipulation</title> |
48 | !Iarch/x86/include/asm/atomic.h | 48 | !Iarch/x86/include/asm/atomic.h |
49 | !Iarch/x86/include/asm/unaligned.h | ||
50 | </sect1> | 49 | </sect1> |
51 | 50 | ||
52 | <sect1><title>Delaying, scheduling, and timer routines</title> | 51 | <sect1><title>Delaying, scheduling, and timer routines</title> |
diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl index a20c6f6fffc..6899f471fb1 100644 --- a/Documentation/DocBook/kernel-api.tmpl +++ b/Documentation/DocBook/kernel-api.tmpl | |||
@@ -57,7 +57,6 @@ | |||
57 | </para> | 57 | </para> |
58 | 58 | ||
59 | <sect1><title>String Conversions</title> | 59 | <sect1><title>String Conversions</title> |
60 | !Ilib/vsprintf.c | ||
61 | !Elib/vsprintf.c | 60 | !Elib/vsprintf.c |
62 | </sect1> | 61 | </sect1> |
63 | <sect1><title>String Manipulation</title> | 62 | <sect1><title>String Manipulation</title> |
diff --git a/Documentation/DocBook/kernel-locking.tmpl b/Documentation/DocBook/kernel-locking.tmpl index 0b1a3f97f28..a0d479d1e1d 100644 --- a/Documentation/DocBook/kernel-locking.tmpl +++ b/Documentation/DocBook/kernel-locking.tmpl | |||
@@ -1961,6 +1961,12 @@ machines due to caching. | |||
1961 | </sect1> | 1961 | </sect1> |
1962 | </chapter> | 1962 | </chapter> |
1963 | 1963 | ||
1964 | <chapter id="apiref"> | ||
1965 | <title>Mutex API reference</title> | ||
1966 | !Iinclude/linux/mutex.h | ||
1967 | !Ekernel/mutex.c | ||
1968 | </chapter> | ||
1969 | |||
1964 | <chapter id="references"> | 1970 | <chapter id="references"> |
1965 | <title>Further reading</title> | 1971 | <title>Further reading</title> |
1966 | 1972 | ||
diff --git a/Documentation/DocBook/tracepoint.tmpl b/Documentation/DocBook/tracepoint.tmpl index e8473eae2a2..b57a9ede322 100644 --- a/Documentation/DocBook/tracepoint.tmpl +++ b/Documentation/DocBook/tracepoint.tmpl | |||
@@ -104,4 +104,9 @@ | |||
104 | <title>Block IO</title> | 104 | <title>Block IO</title> |
105 | !Iinclude/trace/events/block.h | 105 | !Iinclude/trace/events/block.h |
106 | </chapter> | 106 | </chapter> |
107 | |||
108 | <chapter id="workqueue"> | ||
109 | <title>Workqueue</title> | ||
110 | !Iinclude/trace/events/workqueue.h | ||
111 | </chapter> | ||
107 | </book> | 112 | </book> |
diff --git a/Documentation/block/cfq-iosched.txt b/Documentation/block/cfq-iosched.txt new file mode 100644 index 00000000000..e578feed6d8 --- /dev/null +++ b/Documentation/block/cfq-iosched.txt | |||
@@ -0,0 +1,45 @@ | |||
1 | CFQ ioscheduler tunables | ||
2 | ======================== | ||
3 | |||
4 | slice_idle | ||
5 | ---------- | ||
6 | This specifies how long CFQ should idle for next request on certain cfq queues | ||
7 | (for sequential workloads) and service trees (for random workloads) before | ||
8 | queue is expired and CFQ selects next queue to dispatch from. | ||
9 | |||
10 | By default slice_idle is a non-zero value. That means by default we idle on | ||
11 | queues/service trees. This can be very helpful on highly seeky media like | ||
12 | single spindle SATA/SAS disks where we can cut down on overall number of | ||
13 | seeks and see improved throughput. | ||
14 | |||
15 | Setting slice_idle to 0 will remove all the idling on queues/service tree | ||
16 | level and one should see an overall improved throughput on faster storage | ||
17 | devices like multiple SATA/SAS disks in hardware RAID configuration. The down | ||
18 | side is that isolation provided from WRITES also goes down and notion of | ||
19 | IO priority becomes weaker. | ||
20 | |||
21 | So depending on storage and workload, it might be useful to set slice_idle=0. | ||
22 | In general I think for SATA/SAS disks and software RAID of SATA/SAS disks | ||
23 | keeping slice_idle enabled should be useful. For any configurations where | ||
24 | there are multiple spindles behind single LUN (Host based hardware RAID | ||
25 | controller or for storage arrays), setting slice_idle=0 might end up in better | ||
26 | throughput and acceptable latencies. | ||
27 | |||
28 | CFQ IOPS Mode for group scheduling | ||
29 | =================================== | ||
30 | Basic CFQ design is to provide priority based time slices. Higher priority | ||
31 | process gets bigger time slice and lower priority process gets smaller time | ||
32 | slice. Measuring time becomes harder if storage is fast and supports NCQ and | ||
33 | it would be better to dispatch multiple requests from multiple cfq queues in | ||
34 | request queue at a time. In such scenario, it is not possible to measure time | ||
35 | consumed by single queue accurately. | ||
36 | |||
37 | What is possible though is to measure number of requests dispatched from a | ||
38 | single queue and also allow dispatch from multiple cfq queue at the same time. | ||
39 | This effectively becomes the fairness in terms of IOPS (IO operations per | ||
40 | second). | ||
41 | |||
42 | If one sets slice_idle=0 and if storage supports NCQ, CFQ internally switches | ||
43 | to IOPS mode and starts providing fairness in terms of number of requests | ||
44 | dispatched. Note that this mode switching takes effect only for group | ||
45 | scheduling. For non-cgroup users nothing should change. | ||
diff --git a/Documentation/cgroups/blkio-controller.txt b/Documentation/cgroups/blkio-controller.txt index 48e0b21b005..6919d62591d 100644 --- a/Documentation/cgroups/blkio-controller.txt +++ b/Documentation/cgroups/blkio-controller.txt | |||
@@ -217,6 +217,7 @@ Details of cgroup files | |||
217 | CFQ sysfs tunable | 217 | CFQ sysfs tunable |
218 | ================= | 218 | ================= |
219 | /sys/block/<disk>/queue/iosched/group_isolation | 219 | /sys/block/<disk>/queue/iosched/group_isolation |
220 | ----------------------------------------------- | ||
220 | 221 | ||
221 | If group_isolation=1, it provides stronger isolation between groups at the | 222 | If group_isolation=1, it provides stronger isolation between groups at the |
222 | expense of throughput. By default group_isolation is 0. In general that | 223 | expense of throughput. By default group_isolation is 0. In general that |
@@ -243,6 +244,33 @@ By default one should run with group_isolation=0. If that is not sufficient | |||
243 | and one wants stronger isolation between groups, then set group_isolation=1 | 244 | and one wants stronger isolation between groups, then set group_isolation=1 |
244 | but this will come at cost of reduced throughput. | 245 | but this will come at cost of reduced throughput. |
245 | 246 | ||
247 | /sys/block/<disk>/queue/iosched/slice_idle | ||
248 | ------------------------------------------ | ||
249 | On a faster hardware CFQ can be slow, especially with sequential workload. | ||
250 | This happens because CFQ idles on a single queue and single queue might not | ||
251 | drive deeper request queue depths to keep the storage busy. In such scenarios | ||
252 | one can try setting slice_idle=0 and that would switch CFQ to IOPS | ||
253 | (IO operations per second) mode on NCQ supporting hardware. | ||
254 | |||
255 | That means CFQ will not idle between cfq queues of a cfq group and hence be | ||
256 | able to driver higher queue depth and achieve better throughput. That also | ||
257 | means that cfq provides fairness among groups in terms of IOPS and not in | ||
258 | terms of disk time. | ||
259 | |||
260 | /sys/block/<disk>/queue/iosched/group_idle | ||
261 | ------------------------------------------ | ||
262 | If one disables idling on individual cfq queues and cfq service trees by | ||
263 | setting slice_idle=0, group_idle kicks in. That means CFQ will still idle | ||
264 | on the group in an attempt to provide fairness among groups. | ||
265 | |||
266 | By default group_idle is same as slice_idle and does not do anything if | ||
267 | slice_idle is enabled. | ||
268 | |||
269 | One can experience an overall throughput drop if you have created multiple | ||
270 | groups and put applications in that group which are not driving enough | ||
271 | IO to keep disk busy. In that case set group_idle=0, and CFQ will not idle | ||
272 | on individual groups and throughput should improve. | ||
273 | |||
246 | What works | 274 | What works |
247 | ========== | 275 | ========== |
248 | - Currently only sync IO queues are support. All the buffered writes are | 276 | - Currently only sync IO queues are support. All the buffered writes are |
diff --git a/Documentation/gpio.txt b/Documentation/gpio.txt index d96a6dba574..9633da01ff4 100644 --- a/Documentation/gpio.txt +++ b/Documentation/gpio.txt | |||
@@ -109,17 +109,19 @@ use numbers 2000-2063 to identify GPIOs in a bank of I2C GPIO expanders. | |||
109 | 109 | ||
110 | If you want to initialize a structure with an invalid GPIO number, use | 110 | If you want to initialize a structure with an invalid GPIO number, use |
111 | some negative number (perhaps "-EINVAL"); that will never be valid. To | 111 | some negative number (perhaps "-EINVAL"); that will never be valid. To |
112 | test if a number could reference a GPIO, you may use this predicate: | 112 | test if such number from such a structure could reference a GPIO, you |
113 | may use this predicate: | ||
113 | 114 | ||
114 | int gpio_is_valid(int number); | 115 | int gpio_is_valid(int number); |
115 | 116 | ||
116 | A number that's not valid will be rejected by calls which may request | 117 | A number that's not valid will be rejected by calls which may request |
117 | or free GPIOs (see below). Other numbers may also be rejected; for | 118 | or free GPIOs (see below). Other numbers may also be rejected; for |
118 | example, a number might be valid but unused on a given board. | 119 | example, a number might be valid but temporarily unused on a given board. |
119 | |||
120 | Whether a platform supports multiple GPIO controllers is currently a | ||
121 | platform-specific implementation issue. | ||
122 | 120 | ||
121 | Whether a platform supports multiple GPIO controllers is a platform-specific | ||
122 | implementation issue, as are whether that support can leave "holes" in the space | ||
123 | of GPIO numbers, and whether new controllers can be added at runtime. Such issues | ||
124 | can affect things including whether adjacent GPIO numbers are both valid. | ||
123 | 125 | ||
124 | Using GPIOs | 126 | Using GPIOs |
125 | ----------- | 127 | ----------- |
@@ -480,12 +482,16 @@ To support this framework, a platform's Kconfig will "select" either | |||
480 | ARCH_REQUIRE_GPIOLIB or ARCH_WANT_OPTIONAL_GPIOLIB | 482 | ARCH_REQUIRE_GPIOLIB or ARCH_WANT_OPTIONAL_GPIOLIB |
481 | and arrange that its <asm/gpio.h> includes <asm-generic/gpio.h> and defines | 483 | and arrange that its <asm/gpio.h> includes <asm-generic/gpio.h> and defines |
482 | three functions: gpio_get_value(), gpio_set_value(), and gpio_cansleep(). | 484 | three functions: gpio_get_value(), gpio_set_value(), and gpio_cansleep(). |
483 | They may also want to provide a custom value for ARCH_NR_GPIOS. | ||
484 | 485 | ||
485 | ARCH_REQUIRE_GPIOLIB means that the gpio-lib code will always get compiled | 486 | It may also provide a custom value for ARCH_NR_GPIOS, so that it better |
487 | reflects the number of GPIOs in actual use on that platform, without | ||
488 | wasting static table space. (It should count both built-in/SoC GPIOs and | ||
489 | also ones on GPIO expanders. | ||
490 | |||
491 | ARCH_REQUIRE_GPIOLIB means that the gpiolib code will always get compiled | ||
486 | into the kernel on that architecture. | 492 | into the kernel on that architecture. |
487 | 493 | ||
488 | ARCH_WANT_OPTIONAL_GPIOLIB means the gpio-lib code defaults to off and the user | 494 | ARCH_WANT_OPTIONAL_GPIOLIB means the gpiolib code defaults to off and the user |
489 | can enable it and build it into the kernel optionally. | 495 | can enable it and build it into the kernel optionally. |
490 | 496 | ||
491 | If neither of these options are selected, the platform does not support | 497 | If neither of these options are selected, the platform does not support |
diff --git a/Documentation/hwmon/sysfs-interface b/Documentation/hwmon/sysfs-interface index ff45d1f837c..48ceabedf55 100644 --- a/Documentation/hwmon/sysfs-interface +++ b/Documentation/hwmon/sysfs-interface | |||
@@ -91,12 +91,11 @@ name The chip name. | |||
91 | I2C devices get this attribute created automatically. | 91 | I2C devices get this attribute created automatically. |
92 | RO | 92 | RO |
93 | 93 | ||
94 | update_rate The rate at which the chip will update readings. | 94 | update_interval The interval at which the chip will update readings. |
95 | Unit: millisecond | 95 | Unit: millisecond |
96 | RW | 96 | RW |
97 | Some devices have a variable update rate. This attribute | 97 | Some devices have a variable update rate or interval. |
98 | can be used to change the update rate to the desired | 98 | This attribute can be used to change it to the desired value. |
99 | frequency. | ||
100 | 99 | ||
101 | 100 | ||
102 | ************ | 101 | ************ |
diff --git a/Documentation/kernel-doc-nano-HOWTO.txt b/Documentation/kernel-doc-nano-HOWTO.txt index 27a52b35d55..3d8a97747f7 100644 --- a/Documentation/kernel-doc-nano-HOWTO.txt +++ b/Documentation/kernel-doc-nano-HOWTO.txt | |||
@@ -345,5 +345,10 @@ documentation, in <filename>, for the functions listed. | |||
345 | section titled <section title> from <filename>. | 345 | section titled <section title> from <filename>. |
346 | Spaces are allowed in <section title>; do not quote the <section title>. | 346 | Spaces are allowed in <section title>; do not quote the <section title>. |
347 | 347 | ||
348 | !C<filename> is replaced by nothing, but makes the tools check that | ||
349 | all DOC: sections and documented functions, symbols, etc. are used. | ||
350 | This makes sense to use when you use !F/!P only and want to verify | ||
351 | that all documentation is included. | ||
352 | |||
348 | Tim. | 353 | Tim. |
349 | */ <twaugh@redhat.com> | 354 | */ <twaugh@redhat.com> |
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 2c85c0692b0..8dd7248508a 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -1974,15 +1974,18 @@ and is between 256 and 4096 characters. It is defined in the file | |||
1974 | force Enable ASPM even on devices that claim not to support it. | 1974 | force Enable ASPM even on devices that claim not to support it. |
1975 | WARNING: Forcing ASPM on may cause system lockups. | 1975 | WARNING: Forcing ASPM on may cause system lockups. |
1976 | 1976 | ||
1977 | pcie_ports= [PCIE] PCIe ports handling: | ||
1978 | auto Ask the BIOS whether or not to use native PCIe services | ||
1979 | associated with PCIe ports (PME, hot-plug, AER). Use | ||
1980 | them only if that is allowed by the BIOS. | ||
1981 | native Use native PCIe services associated with PCIe ports | ||
1982 | unconditionally. | ||
1983 | compat Treat PCIe ports as PCI-to-PCI bridges, disable the PCIe | ||
1984 | ports driver. | ||
1985 | |||
1977 | pcie_pme= [PCIE,PM] Native PCIe PME signaling options: | 1986 | pcie_pme= [PCIE,PM] Native PCIe PME signaling options: |
1978 | Format: {auto|force}[,nomsi] | ||
1979 | auto Use native PCIe PME signaling if the BIOS allows the | ||
1980 | kernel to control PCIe config registers of root ports. | ||
1981 | force Use native PCIe PME signaling even if the BIOS refuses | ||
1982 | to allow the kernel to control the relevant PCIe config | ||
1983 | registers. | ||
1984 | nomsi Do not use MSI for native PCIe PME signaling (this makes | 1987 | nomsi Do not use MSI for native PCIe PME signaling (this makes |
1985 | all PCIe root ports use INTx for everything). | 1988 | all PCIe root ports use INTx for all services). |
1986 | 1989 | ||
1987 | pcmv= [HW,PCMCIA] BadgePAD 4 | 1990 | pcmv= [HW,PCMCIA] BadgePAD 4 |
1988 | 1991 | ||
@@ -2629,8 +2632,10 @@ and is between 256 and 4096 characters. It is defined in the file | |||
2629 | aux-ide-disks -- unplug non-primary-master IDE devices | 2632 | aux-ide-disks -- unplug non-primary-master IDE devices |
2630 | nics -- unplug network devices | 2633 | nics -- unplug network devices |
2631 | all -- unplug all emulated devices (NICs and IDE disks) | 2634 | all -- unplug all emulated devices (NICs and IDE disks) |
2632 | ignore -- continue loading the Xen platform PCI driver even | 2635 | unnecessary -- unplugging emulated devices is |
2633 | if the version check failed | 2636 | unnecessary even if the host did not respond to |
2637 | the unplug protocol | ||
2638 | never -- do not unplug even if version check succeeds | ||
2634 | 2639 | ||
2635 | xirc2ps_cs= [NET,PCMCIA] | 2640 | xirc2ps_cs= [NET,PCMCIA] |
2636 | Format: | 2641 | Format: |
diff --git a/Documentation/lguest/Makefile b/Documentation/lguest/Makefile index 28c8cdfcafd..bebac6b4f33 100644 --- a/Documentation/lguest/Makefile +++ b/Documentation/lguest/Makefile | |||
@@ -1,5 +1,6 @@ | |||
1 | # This creates the demonstration utility "lguest" which runs a Linux guest. | 1 | # This creates the demonstration utility "lguest" which runs a Linux guest. |
2 | CFLAGS:=-m32 -Wall -Wmissing-declarations -Wmissing-prototypes -O3 -I../../include -I../../arch/x86/include -U_FORTIFY_SOURCE | 2 | # Missing headers? Add "-I../../include -I../../arch/x86/include" |
3 | CFLAGS:=-m32 -Wall -Wmissing-declarations -Wmissing-prototypes -O3 -U_FORTIFY_SOURCE | ||
3 | 4 | ||
4 | all: lguest | 5 | all: lguest |
5 | 6 | ||
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c index fbc64b33143..dc73bc54cc4 100644 --- a/Documentation/lguest/lguest.c +++ b/Documentation/lguest/lguest.c | |||
@@ -39,14 +39,14 @@ | |||
39 | #include <limits.h> | 39 | #include <limits.h> |
40 | #include <stddef.h> | 40 | #include <stddef.h> |
41 | #include <signal.h> | 41 | #include <signal.h> |
42 | #include "linux/lguest_launcher.h" | 42 | #include <linux/virtio_config.h> |
43 | #include "linux/virtio_config.h" | 43 | #include <linux/virtio_net.h> |
44 | #include "linux/virtio_net.h" | 44 | #include <linux/virtio_blk.h> |
45 | #include "linux/virtio_blk.h" | 45 | #include <linux/virtio_console.h> |
46 | #include "linux/virtio_console.h" | 46 | #include <linux/virtio_rng.h> |
47 | #include "linux/virtio_rng.h" | 47 | #include <linux/virtio_ring.h> |
48 | #include "linux/virtio_ring.h" | 48 | #include <asm/bootparam.h> |
49 | #include "asm/bootparam.h" | 49 | #include "../../include/linux/lguest_launcher.h" |
50 | /*L:110 | 50 | /*L:110 |
51 | * We can ignore the 42 include files we need for this program, but I do want | 51 | * We can ignore the 42 include files we need for this program, but I do want |
52 | * to draw attention to the use of kernel-style types. | 52 | * to draw attention to the use of kernel-style types. |
@@ -1447,14 +1447,15 @@ static void add_to_bridge(int fd, const char *if_name, const char *br_name) | |||
1447 | static void configure_device(int fd, const char *tapif, u32 ipaddr) | 1447 | static void configure_device(int fd, const char *tapif, u32 ipaddr) |
1448 | { | 1448 | { |
1449 | struct ifreq ifr; | 1449 | struct ifreq ifr; |
1450 | struct sockaddr_in *sin = (struct sockaddr_in *)&ifr.ifr_addr; | 1450 | struct sockaddr_in sin; |
1451 | 1451 | ||
1452 | memset(&ifr, 0, sizeof(ifr)); | 1452 | memset(&ifr, 0, sizeof(ifr)); |
1453 | strcpy(ifr.ifr_name, tapif); | 1453 | strcpy(ifr.ifr_name, tapif); |
1454 | 1454 | ||
1455 | /* Don't read these incantations. Just cut & paste them like I did! */ | 1455 | /* Don't read these incantations. Just cut & paste them like I did! */ |
1456 | sin->sin_family = AF_INET; | 1456 | sin.sin_family = AF_INET; |
1457 | sin->sin_addr.s_addr = htonl(ipaddr); | 1457 | sin.sin_addr.s_addr = htonl(ipaddr); |
1458 | memcpy(&ifr.ifr_addr, &sin, sizeof(sin)); | ||
1458 | if (ioctl(fd, SIOCSIFADDR, &ifr) != 0) | 1459 | if (ioctl(fd, SIOCSIFADDR, &ifr) != 0) |
1459 | err(1, "Setting %s interface address", tapif); | 1460 | err(1, "Setting %s interface address", tapif); |
1460 | ifr.ifr_flags = IFF_UP; | 1461 | ifr.ifr_flags = IFF_UP; |
diff --git a/Documentation/mutex-design.txt b/Documentation/mutex-design.txt index c91ccc0720f..38c10fd7f41 100644 --- a/Documentation/mutex-design.txt +++ b/Documentation/mutex-design.txt | |||
@@ -9,7 +9,7 @@ firstly, there's nothing wrong with semaphores. But if the simpler | |||
9 | mutex semantics are sufficient for your code, then there are a couple | 9 | mutex semantics are sufficient for your code, then there are a couple |
10 | of advantages of mutexes: | 10 | of advantages of mutexes: |
11 | 11 | ||
12 | - 'struct mutex' is smaller on most architectures: .e.g on x86, | 12 | - 'struct mutex' is smaller on most architectures: E.g. on x86, |
13 | 'struct semaphore' is 20 bytes, 'struct mutex' is 16 bytes. | 13 | 'struct semaphore' is 20 bytes, 'struct mutex' is 16 bytes. |
14 | A smaller structure size means less RAM footprint, and better | 14 | A smaller structure size means less RAM footprint, and better |
15 | CPU-cache utilization. | 15 | CPU-cache utilization. |
@@ -136,3 +136,4 @@ the APIs of 'struct mutex' have been streamlined: | |||
136 | void mutex_lock_nested(struct mutex *lock, unsigned int subclass); | 136 | void mutex_lock_nested(struct mutex *lock, unsigned int subclass); |
137 | int mutex_lock_interruptible_nested(struct mutex *lock, | 137 | int mutex_lock_interruptible_nested(struct mutex *lock, |
138 | unsigned int subclass); | 138 | unsigned int subclass); |
139 | int atomic_dec_and_mutex_lock(atomic_t *cnt, struct mutex *lock); | ||
diff --git a/Documentation/networking/e1000.txt b/Documentation/networking/e1000.txt index 2df71861e57..d9271e74e48 100644 --- a/Documentation/networking/e1000.txt +++ b/Documentation/networking/e1000.txt | |||
@@ -1,82 +1,35 @@ | |||
1 | Linux* Base Driver for the Intel(R) PRO/1000 Family of Adapters | 1 | Linux* Base Driver for the Intel(R) PRO/1000 Family of Adapters |
2 | =============================================================== | 2 | =============================================================== |
3 | 3 | ||
4 | September 26, 2006 | 4 | Intel Gigabit Linux driver. |
5 | 5 | Copyright(c) 1999 - 2010 Intel Corporation. | |
6 | 6 | ||
7 | Contents | 7 | Contents |
8 | ======== | 8 | ======== |
9 | 9 | ||
10 | - In This Release | ||
11 | - Identifying Your Adapter | 10 | - Identifying Your Adapter |
12 | - Building and Installation | ||
13 | - Command Line Parameters | 11 | - Command Line Parameters |
14 | - Speed and Duplex Configuration | 12 | - Speed and Duplex Configuration |
15 | - Additional Configurations | 13 | - Additional Configurations |
16 | - Known Issues | ||
17 | - Support | 14 | - Support |
18 | 15 | ||
19 | |||
20 | In This Release | ||
21 | =============== | ||
22 | |||
23 | This file describes the Linux* Base Driver for the Intel(R) PRO/1000 Family | ||
24 | of Adapters. This driver includes support for Itanium(R)2-based systems. | ||
25 | |||
26 | For questions related to hardware requirements, refer to the documentation | ||
27 | supplied with your Intel PRO/1000 adapter. All hardware requirements listed | ||
28 | apply to use with Linux. | ||
29 | |||
30 | The following features are now available in supported kernels: | ||
31 | - Native VLANs | ||
32 | - Channel Bonding (teaming) | ||
33 | - SNMP | ||
34 | |||
35 | Channel Bonding documentation can be found in the Linux kernel source: | ||
36 | /Documentation/networking/bonding.txt | ||
37 | |||
38 | The driver information previously displayed in the /proc filesystem is not | ||
39 | supported in this release. Alternatively, you can use ethtool (version 1.6 | ||
40 | or later), lspci, and ifconfig to obtain the same information. | ||
41 | |||
42 | Instructions on updating ethtool can be found in the section "Additional | ||
43 | Configurations" later in this document. | ||
44 | |||
45 | NOTE: The Intel(R) 82562v 10/100 Network Connection only provides 10/100 | ||
46 | support. | ||
47 | |||
48 | |||
49 | Identifying Your Adapter | 16 | Identifying Your Adapter |
50 | ======================== | 17 | ======================== |
51 | 18 | ||
52 | For more information on how to identify your adapter, go to the Adapter & | 19 | For more information on how to identify your adapter, go to the Adapter & |
53 | Driver ID Guide at: | 20 | Driver ID Guide at: |
54 | 21 | ||
55 | http://support.intel.com/support/network/adapter/pro100/21397.htm | 22 | http://support.intel.com/support/go/network/adapter/idguide.htm |
56 | 23 | ||
57 | For the latest Intel network drivers for Linux, refer to the following | 24 | For the latest Intel network drivers for Linux, refer to the following |
58 | website. In the search field, enter your adapter name or type, or use the | 25 | website. In the search field, enter your adapter name or type, or use the |
59 | networking link on the left to search for your adapter: | 26 | networking link on the left to search for your adapter: |
60 | 27 | ||
61 | http://downloadfinder.intel.com/scripts-df/support_intel.asp | 28 | http://support.intel.com/support/go/network/adapter/home.htm |
62 | |||
63 | 29 | ||
64 | Command Line Parameters | 30 | Command Line Parameters |
65 | ======================= | 31 | ======================= |
66 | 32 | ||
67 | If the driver is built as a module, the following optional parameters | ||
68 | are used by entering them on the command line with the modprobe command | ||
69 | using this syntax: | ||
70 | |||
71 | modprobe e1000 [<option>=<VAL1>,<VAL2>,...] | ||
72 | |||
73 | For example, with two PRO/1000 PCI adapters, entering: | ||
74 | |||
75 | modprobe e1000 TxDescriptors=80,128 | ||
76 | |||
77 | loads the e1000 driver with 80 TX descriptors for the first adapter and | ||
78 | 128 TX descriptors for the second adapter. | ||
79 | |||
80 | The default value for each parameter is generally the recommended setting, | 33 | The default value for each parameter is generally the recommended setting, |
81 | unless otherwise noted. | 34 | unless otherwise noted. |
82 | 35 | ||
@@ -89,10 +42,6 @@ NOTES: For more information about the AutoNeg, Duplex, and Speed | |||
89 | parameters, see the application note at: | 42 | parameters, see the application note at: |
90 | http://www.intel.com/design/network/applnots/ap450.htm | 43 | http://www.intel.com/design/network/applnots/ap450.htm |
91 | 44 | ||
92 | A descriptor describes a data buffer and attributes related to | ||
93 | the data buffer. This information is accessed by the hardware. | ||
94 | |||
95 | |||
96 | AutoNeg | 45 | AutoNeg |
97 | ------- | 46 | ------- |
98 | (Supported only on adapters with copper connections) | 47 | (Supported only on adapters with copper connections) |
@@ -106,7 +55,6 @@ Duplex parameters must not be specified. | |||
106 | NOTE: Refer to the Speed and Duplex section of this readme for more | 55 | NOTE: Refer to the Speed and Duplex section of this readme for more |
107 | information on the AutoNeg parameter. | 56 | information on the AutoNeg parameter. |
108 | 57 | ||
109 | |||
110 | Duplex | 58 | Duplex |
111 | ------ | 59 | ------ |
112 | (Supported only on adapters with copper connections) | 60 | (Supported only on adapters with copper connections) |
@@ -119,7 +67,6 @@ set to auto-negotiate, the board auto-detects the correct duplex. If the | |||
119 | link partner is forced (either full or half), Duplex defaults to half- | 67 | link partner is forced (either full or half), Duplex defaults to half- |
120 | duplex. | 68 | duplex. |
121 | 69 | ||
122 | |||
123 | FlowControl | 70 | FlowControl |
124 | ----------- | 71 | ----------- |
125 | Valid Range: 0-3 (0=none, 1=Rx only, 2=Tx only, 3=Rx&Tx) | 72 | Valid Range: 0-3 (0=none, 1=Rx only, 2=Tx only, 3=Rx&Tx) |
@@ -128,16 +75,16 @@ Default Value: Reads flow control settings from the EEPROM | |||
128 | This parameter controls the automatic generation(Tx) and response(Rx) | 75 | This parameter controls the automatic generation(Tx) and response(Rx) |
129 | to Ethernet PAUSE frames. | 76 | to Ethernet PAUSE frames. |
130 | 77 | ||
131 | |||
132 | InterruptThrottleRate | 78 | InterruptThrottleRate |
133 | --------------------- | 79 | --------------------- |
134 | (not supported on Intel(R) 82542, 82543 or 82544-based adapters) | 80 | (not supported on Intel(R) 82542, 82543 or 82544-based adapters) |
135 | Valid Range: 0,1,3,100-100000 (0=off, 1=dynamic, 3=dynamic conservative) | 81 | Valid Range: 0,1,3,4,100-100000 (0=off, 1=dynamic, 3=dynamic conservative, |
82 | 4=simplified balancing) | ||
136 | Default Value: 3 | 83 | Default Value: 3 |
137 | 84 | ||
138 | The driver can limit the amount of interrupts per second that the adapter | 85 | The driver can limit the amount of interrupts per second that the adapter |
139 | will generate for incoming packets. It does this by writing a value to the | 86 | will generate for incoming packets. It does this by writing a value to the |
140 | adapter that is based on the maximum amount of interrupts that the adapter | 87 | adapter that is based on the maximum amount of interrupts that the adapter |
141 | will generate per second. | 88 | will generate per second. |
142 | 89 | ||
143 | Setting InterruptThrottleRate to a value greater or equal to 100 | 90 | Setting InterruptThrottleRate to a value greater or equal to 100 |
@@ -146,37 +93,43 @@ per second, even if more packets have come in. This reduces interrupt | |||
146 | load on the system and can lower CPU utilization under heavy load, | 93 | load on the system and can lower CPU utilization under heavy load, |
147 | but will increase latency as packets are not processed as quickly. | 94 | but will increase latency as packets are not processed as quickly. |
148 | 95 | ||
149 | The default behaviour of the driver previously assumed a static | 96 | The default behaviour of the driver previously assumed a static |
150 | InterruptThrottleRate value of 8000, providing a good fallback value for | 97 | InterruptThrottleRate value of 8000, providing a good fallback value for |
151 | all traffic types,but lacking in small packet performance and latency. | 98 | all traffic types,but lacking in small packet performance and latency. |
152 | The hardware can handle many more small packets per second however, and | 99 | The hardware can handle many more small packets per second however, and |
153 | for this reason an adaptive interrupt moderation algorithm was implemented. | 100 | for this reason an adaptive interrupt moderation algorithm was implemented. |
154 | 101 | ||
155 | Since 7.3.x, the driver has two adaptive modes (setting 1 or 3) in which | 102 | Since 7.3.x, the driver has two adaptive modes (setting 1 or 3) in which |
156 | it dynamically adjusts the InterruptThrottleRate value based on the traffic | 103 | it dynamically adjusts the InterruptThrottleRate value based on the traffic |
157 | that it receives. After determining the type of incoming traffic in the last | 104 | that it receives. After determining the type of incoming traffic in the last |
158 | timeframe, it will adjust the InterruptThrottleRate to an appropriate value | 105 | timeframe, it will adjust the InterruptThrottleRate to an appropriate value |
159 | for that traffic. | 106 | for that traffic. |
160 | 107 | ||
161 | The algorithm classifies the incoming traffic every interval into | 108 | The algorithm classifies the incoming traffic every interval into |
162 | classes. Once the class is determined, the InterruptThrottleRate value is | 109 | classes. Once the class is determined, the InterruptThrottleRate value is |
163 | adjusted to suit that traffic type the best. There are three classes defined: | 110 | adjusted to suit that traffic type the best. There are three classes defined: |
164 | "Bulk traffic", for large amounts of packets of normal size; "Low latency", | 111 | "Bulk traffic", for large amounts of packets of normal size; "Low latency", |
165 | for small amounts of traffic and/or a significant percentage of small | 112 | for small amounts of traffic and/or a significant percentage of small |
166 | packets; and "Lowest latency", for almost completely small packets or | 113 | packets; and "Lowest latency", for almost completely small packets or |
167 | minimal traffic. | 114 | minimal traffic. |
168 | 115 | ||
169 | In dynamic conservative mode, the InterruptThrottleRate value is set to 4000 | 116 | In dynamic conservative mode, the InterruptThrottleRate value is set to 4000 |
170 | for traffic that falls in class "Bulk traffic". If traffic falls in the "Low | 117 | for traffic that falls in class "Bulk traffic". If traffic falls in the "Low |
171 | latency" or "Lowest latency" class, the InterruptThrottleRate is increased | 118 | latency" or "Lowest latency" class, the InterruptThrottleRate is increased |
172 | stepwise to 20000. This default mode is suitable for most applications. | 119 | stepwise to 20000. This default mode is suitable for most applications. |
173 | 120 | ||
174 | For situations where low latency is vital such as cluster or | 121 | For situations where low latency is vital such as cluster or |
175 | grid computing, the algorithm can reduce latency even more when | 122 | grid computing, the algorithm can reduce latency even more when |
176 | InterruptThrottleRate is set to mode 1. In this mode, which operates | 123 | InterruptThrottleRate is set to mode 1. In this mode, which operates |
177 | the same as mode 3, the InterruptThrottleRate will be increased stepwise to | 124 | the same as mode 3, the InterruptThrottleRate will be increased stepwise to |
178 | 70000 for traffic in class "Lowest latency". | 125 | 70000 for traffic in class "Lowest latency". |
179 | 126 | ||
127 | In simplified mode the interrupt rate is based on the ratio of Tx and | ||
128 | Rx traffic. If the bytes per second rate is approximately equal, the | ||
129 | interrupt rate will drop as low as 2000 interrupts per second. If the | ||
130 | traffic is mostly transmit or mostly receive, the interrupt rate could | ||
131 | be as high as 8000. | ||
132 | |||
180 | Setting InterruptThrottleRate to 0 turns off any interrupt moderation | 133 | Setting InterruptThrottleRate to 0 turns off any interrupt moderation |
181 | and may improve small packet latency, but is generally not suitable | 134 | and may improve small packet latency, but is generally not suitable |
182 | for bulk throughput traffic. | 135 | for bulk throughput traffic. |
@@ -212,8 +165,6 @@ NOTE: When e1000 is loaded with default settings and multiple adapters | |||
212 | be platform-specific. If CPU utilization is not a concern, use | 165 | be platform-specific. If CPU utilization is not a concern, use |
213 | RX_POLLING (NAPI) and default driver settings. | 166 | RX_POLLING (NAPI) and default driver settings. |
214 | 167 | ||
215 | |||
216 | |||
217 | RxDescriptors | 168 | RxDescriptors |
218 | ------------- | 169 | ------------- |
219 | Valid Range: 80-256 for 82542 and 82543-based adapters | 170 | Valid Range: 80-256 for 82542 and 82543-based adapters |
@@ -225,15 +176,14 @@ by the driver. Increasing this value allows the driver to buffer more | |||
225 | incoming packets, at the expense of increased system memory utilization. | 176 | incoming packets, at the expense of increased system memory utilization. |
226 | 177 | ||
227 | Each descriptor is 16 bytes. A receive buffer is also allocated for each | 178 | Each descriptor is 16 bytes. A receive buffer is also allocated for each |
228 | descriptor and can be either 2048, 4096, 8192, or 16384 bytes, depending | 179 | descriptor and can be either 2048, 4096, 8192, or 16384 bytes, depending |
229 | on the MTU setting. The maximum MTU size is 16110. | 180 | on the MTU setting. The maximum MTU size is 16110. |
230 | 181 | ||
231 | NOTE: MTU designates the frame size. It only needs to be set for Jumbo | 182 | NOTE: MTU designates the frame size. It only needs to be set for Jumbo |
232 | Frames. Depending on the available system resources, the request | 183 | Frames. Depending on the available system resources, the request |
233 | for a higher number of receive descriptors may be denied. In this | 184 | for a higher number of receive descriptors may be denied. In this |
234 | case, use a lower number. | 185 | case, use a lower number. |
235 | 186 | ||
236 | |||
237 | RxIntDelay | 187 | RxIntDelay |
238 | ---------- | 188 | ---------- |
239 | Valid Range: 0-65535 (0=off) | 189 | Valid Range: 0-65535 (0=off) |
@@ -254,7 +204,6 @@ CAUTION: When setting RxIntDelay to a value other than 0, adapters may | |||
254 | restoring the network connection. To eliminate the potential | 204 | restoring the network connection. To eliminate the potential |
255 | for the hang ensure that RxIntDelay is set to 0. | 205 | for the hang ensure that RxIntDelay is set to 0. |
256 | 206 | ||
257 | |||
258 | RxAbsIntDelay | 207 | RxAbsIntDelay |
259 | ------------- | 208 | ------------- |
260 | (This parameter is supported only on 82540, 82545 and later adapters.) | 209 | (This parameter is supported only on 82540, 82545 and later adapters.) |
@@ -268,7 +217,6 @@ packet is received within the set amount of time. Proper tuning, | |||
268 | along with RxIntDelay, may improve traffic throughput in specific network | 217 | along with RxIntDelay, may improve traffic throughput in specific network |
269 | conditions. | 218 | conditions. |
270 | 219 | ||
271 | |||
272 | Speed | 220 | Speed |
273 | ----- | 221 | ----- |
274 | (This parameter is supported only on adapters with copper connections.) | 222 | (This parameter is supported only on adapters with copper connections.) |
@@ -280,7 +228,6 @@ Speed forces the line speed to the specified value in megabits per second | |||
280 | partner is set to auto-negotiate, the board will auto-detect the correct | 228 | partner is set to auto-negotiate, the board will auto-detect the correct |
281 | speed. Duplex should also be set when Speed is set to either 10 or 100. | 229 | speed. Duplex should also be set when Speed is set to either 10 or 100. |
282 | 230 | ||
283 | |||
284 | TxDescriptors | 231 | TxDescriptors |
285 | ------------- | 232 | ------------- |
286 | Valid Range: 80-256 for 82542 and 82543-based adapters | 233 | Valid Range: 80-256 for 82542 and 82543-based adapters |
@@ -295,6 +242,36 @@ NOTE: Depending on the available system resources, the request for a | |||
295 | higher number of transmit descriptors may be denied. In this case, | 242 | higher number of transmit descriptors may be denied. In this case, |
296 | use a lower number. | 243 | use a lower number. |
297 | 244 | ||
245 | TxDescriptorStep | ||
246 | ---------------- | ||
247 | Valid Range: 1 (use every Tx Descriptor) | ||
248 | 4 (use every 4th Tx Descriptor) | ||
249 | |||
250 | Default Value: 1 (use every Tx Descriptor) | ||
251 | |||
252 | On certain non-Intel architectures, it has been observed that intense TX | ||
253 | traffic bursts of short packets may result in an improper descriptor | ||
254 | writeback. If this occurs, the driver will report a "TX Timeout" and reset | ||
255 | the adapter, after which the transmit flow will restart, though data may | ||
256 | have stalled for as much as 10 seconds before it resumes. | ||
257 | |||
258 | The improper writeback does not occur on the first descriptor in a system | ||
259 | memory cache-line, which is typically 32 bytes, or 4 descriptors long. | ||
260 | |||
261 | Setting TxDescriptorStep to a value of 4 will ensure that all TX descriptors | ||
262 | are aligned to the start of a system memory cache line, and so this problem | ||
263 | will not occur. | ||
264 | |||
265 | NOTES: Setting TxDescriptorStep to 4 effectively reduces the number of | ||
266 | TxDescriptors available for transmits to 1/4 of the normal allocation. | ||
267 | This has a possible negative performance impact, which may be | ||
268 | compensated for by allocating more descriptors using the TxDescriptors | ||
269 | module parameter. | ||
270 | |||
271 | There are other conditions which may result in "TX Timeout", which will | ||
272 | not be resolved by the use of the TxDescriptorStep parameter. As the | ||
273 | issue addressed by this parameter has never been observed on Intel | ||
274 | Architecture platforms, it should not be used on Intel platforms. | ||
298 | 275 | ||
299 | TxIntDelay | 276 | TxIntDelay |
300 | ---------- | 277 | ---------- |
@@ -307,7 +284,6 @@ efficiency if properly tuned for specific network traffic. If the | |||
307 | system is reporting dropped transmits, this value may be set too high | 284 | system is reporting dropped transmits, this value may be set too high |
308 | causing the driver to run out of available transmit descriptors. | 285 | causing the driver to run out of available transmit descriptors. |
309 | 286 | ||
310 | |||
311 | TxAbsIntDelay | 287 | TxAbsIntDelay |
312 | ------------- | 288 | ------------- |
313 | (This parameter is supported only on 82540, 82545 and later adapters.) | 289 | (This parameter is supported only on 82540, 82545 and later adapters.) |
@@ -330,6 +306,35 @@ Default Value: 1 | |||
330 | A value of '1' indicates that the driver should enable IP checksum | 306 | A value of '1' indicates that the driver should enable IP checksum |
331 | offload for received packets (both UDP and TCP) to the adapter hardware. | 307 | offload for received packets (both UDP and TCP) to the adapter hardware. |
332 | 308 | ||
309 | Copybreak | ||
310 | --------- | ||
311 | Valid Range: 0-xxxxxxx (0=off) | ||
312 | Default Value: 256 | ||
313 | Usage: insmod e1000.ko copybreak=128 | ||
314 | |||
315 | Driver copies all packets below or equaling this size to a fresh Rx | ||
316 | buffer before handing it up the stack. | ||
317 | |||
318 | This parameter is different than other parameters, in that it is a | ||
319 | single (not 1,1,1 etc.) parameter applied to all driver instances and | ||
320 | it is also available during runtime at | ||
321 | /sys/module/e1000/parameters/copybreak | ||
322 | |||
323 | SmartPowerDownEnable | ||
324 | -------------------- | ||
325 | Valid Range: 0-1 | ||
326 | Default Value: 0 (disabled) | ||
327 | |||
328 | Allows PHY to turn off in lower power states. The user can turn off | ||
329 | this parameter in supported chipsets. | ||
330 | |||
331 | KumeranLockLoss | ||
332 | --------------- | ||
333 | Valid Range: 0-1 | ||
334 | Default Value: 1 (enabled) | ||
335 | |||
336 | This workaround skips resetting the PHY at shutdown for the initial | ||
337 | silicon releases of ICH8 systems. | ||
333 | 338 | ||
334 | Speed and Duplex Configuration | 339 | Speed and Duplex Configuration |
335 | ============================== | 340 | ============================== |
@@ -385,40 +390,9 @@ If the link partner is forced to a specific speed and duplex, then this | |||
385 | parameter should not be used. Instead, use the Speed and Duplex parameters | 390 | parameter should not be used. Instead, use the Speed and Duplex parameters |
386 | previously mentioned to force the adapter to the same speed and duplex. | 391 | previously mentioned to force the adapter to the same speed and duplex. |
387 | 392 | ||
388 | |||
389 | Additional Configurations | 393 | Additional Configurations |
390 | ========================= | 394 | ========================= |
391 | 395 | ||
392 | Configuring the Driver on Different Distributions | ||
393 | ------------------------------------------------- | ||
394 | Configuring a network driver to load properly when the system is started | ||
395 | is distribution dependent. Typically, the configuration process involves | ||
396 | adding an alias line to /etc/modules.conf or /etc/modprobe.conf as well | ||
397 | as editing other system startup scripts and/or configuration files. Many | ||
398 | popular Linux distributions ship with tools to make these changes for you. | ||
399 | To learn the proper way to configure a network device for your system, | ||
400 | refer to your distribution documentation. If during this process you are | ||
401 | asked for the driver or module name, the name for the Linux Base Driver | ||
402 | for the Intel(R) PRO/1000 Family of Adapters is e1000. | ||
403 | |||
404 | As an example, if you install the e1000 driver for two PRO/1000 adapters | ||
405 | (eth0 and eth1) and set the speed and duplex to 10full and 100half, add | ||
406 | the following to modules.conf or or modprobe.conf: | ||
407 | |||
408 | alias eth0 e1000 | ||
409 | alias eth1 e1000 | ||
410 | options e1000 Speed=10,100 Duplex=2,1 | ||
411 | |||
412 | Viewing Link Messages | ||
413 | --------------------- | ||
414 | Link messages will not be displayed to the console if the distribution is | ||
415 | restricting system messages. In order to see network driver link messages | ||
416 | on your console, set dmesg to eight by entering the following: | ||
417 | |||
418 | dmesg -n 8 | ||
419 | |||
420 | NOTE: This setting is not saved across reboots. | ||
421 | |||
422 | Jumbo Frames | 396 | Jumbo Frames |
423 | ------------ | 397 | ------------ |
424 | Jumbo Frames support is enabled by changing the MTU to a value larger than | 398 | Jumbo Frames support is enabled by changing the MTU to a value larger than |
@@ -437,9 +411,11 @@ Additional Configurations | |||
437 | setting in a different location. | 411 | setting in a different location. |
438 | 412 | ||
439 | Notes: | 413 | Notes: |
440 | 414 | Degradation in throughput performance may be observed in some Jumbo frames | |
441 | - To enable Jumbo Frames, increase the MTU size on the interface beyond | 415 | environments. If this is observed, increasing the application's socket buffer |
442 | 1500. | 416 | size and/or increasing the /proc/sys/net/ipv4/tcp_*mem entry values may help. |
417 | See the specific application manual and /usr/src/linux*/Documentation/ | ||
418 | networking/ip-sysctl.txt for more details. | ||
443 | 419 | ||
444 | - The maximum MTU setting for Jumbo Frames is 16110. This value coincides | 420 | - The maximum MTU setting for Jumbo Frames is 16110. This value coincides |
445 | with the maximum Jumbo Frames size of 16128. | 421 | with the maximum Jumbo Frames size of 16128. |
@@ -447,40 +423,11 @@ Additional Configurations | |||
447 | - Using Jumbo Frames at 10 or 100 Mbps may result in poor performance or | 423 | - Using Jumbo Frames at 10 or 100 Mbps may result in poor performance or |
448 | loss of link. | 424 | loss of link. |
449 | 425 | ||
450 | - Some Intel gigabit adapters that support Jumbo Frames have a frame size | ||
451 | limit of 9238 bytes, with a corresponding MTU size limit of 9216 bytes. | ||
452 | The adapters with this limitation are based on the Intel(R) 82571EB, | ||
453 | 82572EI, 82573L and 80003ES2LAN controller. These correspond to the | ||
454 | following product names: | ||
455 | Intel(R) PRO/1000 PT Server Adapter | ||
456 | Intel(R) PRO/1000 PT Desktop Adapter | ||
457 | Intel(R) PRO/1000 PT Network Connection | ||
458 | Intel(R) PRO/1000 PT Dual Port Server Adapter | ||
459 | Intel(R) PRO/1000 PT Dual Port Network Connection | ||
460 | Intel(R) PRO/1000 PF Server Adapter | ||
461 | Intel(R) PRO/1000 PF Network Connection | ||
462 | Intel(R) PRO/1000 PF Dual Port Server Adapter | ||
463 | Intel(R) PRO/1000 PB Server Connection | ||
464 | Intel(R) PRO/1000 PL Network Connection | ||
465 | Intel(R) PRO/1000 EB Network Connection with I/O Acceleration | ||
466 | Intel(R) PRO/1000 EB Backplane Connection with I/O Acceleration | ||
467 | Intel(R) PRO/1000 PT Quad Port Server Adapter | ||
468 | |||
469 | - Adapters based on the Intel(R) 82542 and 82573V/E controller do not | 426 | - Adapters based on the Intel(R) 82542 and 82573V/E controller do not |
470 | support Jumbo Frames. These correspond to the following product names: | 427 | support Jumbo Frames. These correspond to the following product names: |
471 | Intel(R) PRO/1000 Gigabit Server Adapter | 428 | Intel(R) PRO/1000 Gigabit Server Adapter |
472 | Intel(R) PRO/1000 PM Network Connection | 429 | Intel(R) PRO/1000 PM Network Connection |
473 | 430 | ||
474 | - The following adapters do not support Jumbo Frames: | ||
475 | Intel(R) 82562V 10/100 Network Connection | ||
476 | Intel(R) 82566DM Gigabit Network Connection | ||
477 | Intel(R) 82566DC Gigabit Network Connection | ||
478 | Intel(R) 82566MM Gigabit Network Connection | ||
479 | Intel(R) 82566MC Gigabit Network Connection | ||
480 | Intel(R) 82562GT 10/100 Network Connection | ||
481 | Intel(R) 82562G 10/100 Network Connection | ||
482 | |||
483 | |||
484 | Ethtool | 431 | Ethtool |
485 | ------- | 432 | ------- |
486 | The driver utilizes the ethtool interface for driver configuration and | 433 | The driver utilizes the ethtool interface for driver configuration and |
@@ -490,142 +437,14 @@ Additional Configurations | |||
490 | The latest release of ethtool can be found from | 437 | The latest release of ethtool can be found from |
491 | http://sourceforge.net/projects/gkernel. | 438 | http://sourceforge.net/projects/gkernel. |
492 | 439 | ||
493 | NOTE: Ethtool 1.6 only supports a limited set of ethtool options. Support | ||
494 | for a more complete ethtool feature set can be enabled by upgrading | ||
495 | ethtool to ethtool-1.8.1. | ||
496 | |||
497 | Enabling Wake on LAN* (WoL) | 440 | Enabling Wake on LAN* (WoL) |
498 | --------------------------- | 441 | --------------------------- |
499 | WoL is configured through the Ethtool* utility. Ethtool is included with | 442 | WoL is configured through the Ethtool* utility. |
500 | all versions of Red Hat after Red Hat 7.2. For other Linux distributions, | ||
501 | download and install Ethtool from the following website: | ||
502 | http://sourceforge.net/projects/gkernel. | ||
503 | |||
504 | For instructions on enabling WoL with Ethtool, refer to the website listed | ||
505 | above. | ||
506 | 443 | ||
507 | WoL will be enabled on the system during the next shut down or reboot. | 444 | WoL will be enabled on the system during the next shut down or reboot. |
508 | For this driver version, in order to enable WoL, the e1000 driver must be | 445 | For this driver version, in order to enable WoL, the e1000 driver must be |
509 | loaded when shutting down or rebooting the system. | 446 | loaded when shutting down or rebooting the system. |
510 | 447 | ||
511 | Wake On LAN is only supported on port A for the following devices: | ||
512 | Intel(R) PRO/1000 PT Dual Port Network Connection | ||
513 | Intel(R) PRO/1000 PT Dual Port Server Connection | ||
514 | Intel(R) PRO/1000 PT Dual Port Server Adapter | ||
515 | Intel(R) PRO/1000 PF Dual Port Server Adapter | ||
516 | Intel(R) PRO/1000 PT Quad Port Server Adapter | ||
517 | |||
518 | NAPI | ||
519 | ---- | ||
520 | NAPI (Rx polling mode) is enabled in the e1000 driver. | ||
521 | |||
522 | See www.cyberus.ca/~hadi/usenix-paper.tgz for more information on NAPI. | ||
523 | |||
524 | |||
525 | Known Issues | ||
526 | ============ | ||
527 | |||
528 | Dropped Receive Packets on Half-duplex 10/100 Networks | ||
529 | ------------------------------------------------------ | ||
530 | If you have an Intel PCI Express adapter running at 10mbps or 100mbps, half- | ||
531 | duplex, you may observe occasional dropped receive packets. There are no | ||
532 | workarounds for this problem in this network configuration. The network must | ||
533 | be updated to operate in full-duplex, and/or 1000mbps only. | ||
534 | |||
535 | Jumbo Frames System Requirement | ||
536 | ------------------------------- | ||
537 | Memory allocation failures have been observed on Linux systems with 64 MB | ||
538 | of RAM or less that are running Jumbo Frames. If you are using Jumbo | ||
539 | Frames, your system may require more than the advertised minimum | ||
540 | requirement of 64 MB of system memory. | ||
541 | |||
542 | Performance Degradation with Jumbo Frames | ||
543 | ----------------------------------------- | ||
544 | Degradation in throughput performance may be observed in some Jumbo frames | ||
545 | environments. If this is observed, increasing the application's socket | ||
546 | buffer size and/or increasing the /proc/sys/net/ipv4/tcp_*mem entry values | ||
547 | may help. See the specific application manual and | ||
548 | /usr/src/linux*/Documentation/ | ||
549 | networking/ip-sysctl.txt for more details. | ||
550 | |||
551 | Jumbo Frames on Foundry BigIron 8000 switch | ||
552 | ------------------------------------------- | ||
553 | There is a known issue using Jumbo frames when connected to a Foundry | ||
554 | BigIron 8000 switch. This is a 3rd party limitation. If you experience | ||
555 | loss of packets, lower the MTU size. | ||
556 | |||
557 | Allocating Rx Buffers when Using Jumbo Frames | ||
558 | --------------------------------------------- | ||
559 | Allocating Rx buffers when using Jumbo Frames on 2.6.x kernels may fail if | ||
560 | the available memory is heavily fragmented. This issue may be seen with PCI-X | ||
561 | adapters or with packet split disabled. This can be reduced or eliminated | ||
562 | by changing the amount of available memory for receive buffer allocation, by | ||
563 | increasing /proc/sys/vm/min_free_kbytes. | ||
564 | |||
565 | Multiple Interfaces on Same Ethernet Broadcast Network | ||
566 | ------------------------------------------------------ | ||
567 | Due to the default ARP behavior on Linux, it is not possible to have | ||
568 | one system on two IP networks in the same Ethernet broadcast domain | ||
569 | (non-partitioned switch) behave as expected. All Ethernet interfaces | ||
570 | will respond to IP traffic for any IP address assigned to the system. | ||
571 | This results in unbalanced receive traffic. | ||
572 | |||
573 | If you have multiple interfaces in a server, either turn on ARP | ||
574 | filtering by entering: | ||
575 | |||
576 | echo 1 > /proc/sys/net/ipv4/conf/all/arp_filter | ||
577 | (this only works if your kernel's version is higher than 2.4.5), | ||
578 | |||
579 | NOTE: This setting is not saved across reboots. The configuration | ||
580 | change can be made permanent by adding the line: | ||
581 | net.ipv4.conf.all.arp_filter = 1 | ||
582 | to the file /etc/sysctl.conf | ||
583 | |||
584 | or, | ||
585 | |||
586 | install the interfaces in separate broadcast domains (either in | ||
587 | different switches or in a switch partitioned to VLANs). | ||
588 | |||
589 | 82541/82547 can't link or are slow to link with some link partners | ||
590 | ----------------------------------------------------------------- | ||
591 | There is a known compatibility issue with 82541/82547 and some | ||
592 | low-end switches where the link will not be established, or will | ||
593 | be slow to establish. In particular, these switches are known to | ||
594 | be incompatible with 82541/82547: | ||
595 | |||
596 | Planex FXG-08TE | ||
597 | I-O Data ETG-SH8 | ||
598 | |||
599 | To workaround this issue, the driver can be compiled with an override | ||
600 | of the PHY's master/slave setting. Forcing master or forcing slave | ||
601 | mode will improve time-to-link. | ||
602 | |||
603 | # make CFLAGS_EXTRA=-DE1000_MASTER_SLAVE=<n> | ||
604 | |||
605 | Where <n> is: | ||
606 | |||
607 | 0 = Hardware default | ||
608 | 1 = Master mode | ||
609 | 2 = Slave mode | ||
610 | 3 = Auto master/slave | ||
611 | |||
612 | Disable rx flow control with ethtool | ||
613 | ------------------------------------ | ||
614 | In order to disable receive flow control using ethtool, you must turn | ||
615 | off auto-negotiation on the same command line. | ||
616 | |||
617 | For example: | ||
618 | |||
619 | ethtool -A eth? autoneg off rx off | ||
620 | |||
621 | Unplugging network cable while ethtool -p is running | ||
622 | ---------------------------------------------------- | ||
623 | In kernel versions 2.5.50 and later (including 2.6 kernel), unplugging | ||
624 | the network cable while ethtool -p is running will cause the system to | ||
625 | become unresponsive to keyboard commands, except for control-alt-delete. | ||
626 | Restarting the system appears to be the only remedy. | ||
627 | |||
628 | |||
629 | Support | 448 | Support |
630 | ======= | 449 | ======= |
631 | 450 | ||
diff --git a/Documentation/networking/e1000e.txt b/Documentation/networking/e1000e.txt new file mode 100644 index 00000000000..6aa048badf3 --- /dev/null +++ b/Documentation/networking/e1000e.txt | |||
@@ -0,0 +1,302 @@ | |||
1 | Linux* Driver for Intel(R) Network Connection | ||
2 | =============================================================== | ||
3 | |||
4 | Intel Gigabit Linux driver. | ||
5 | Copyright(c) 1999 - 2010 Intel Corporation. | ||
6 | |||
7 | Contents | ||
8 | ======== | ||
9 | |||
10 | - Identifying Your Adapter | ||
11 | - Command Line Parameters | ||
12 | - Additional Configurations | ||
13 | - Support | ||
14 | |||
15 | Identifying Your Adapter | ||
16 | ======================== | ||
17 | |||
18 | The e1000e driver supports all PCI Express Intel(R) Gigabit Network | ||
19 | Connections, except those that are 82575, 82576 and 82580-based*. | ||
20 | |||
21 | * NOTE: The Intel(R) PRO/1000 P Dual Port Server Adapter is supported by | ||
22 | the e1000 driver, not the e1000e driver due to the 82546 part being used | ||
23 | behind a PCI Express bridge. | ||
24 | |||
25 | For more information on how to identify your adapter, go to the Adapter & | ||
26 | Driver ID Guide at: | ||
27 | |||
28 | http://support.intel.com/support/go/network/adapter/idguide.htm | ||
29 | |||
30 | For the latest Intel network drivers for Linux, refer to the following | ||
31 | website. In the search field, enter your adapter name or type, or use the | ||
32 | networking link on the left to search for your adapter: | ||
33 | |||
34 | http://support.intel.com/support/go/network/adapter/home.htm | ||
35 | |||
36 | Command Line Parameters | ||
37 | ======================= | ||
38 | |||
39 | The default value for each parameter is generally the recommended setting, | ||
40 | unless otherwise noted. | ||
41 | |||
42 | NOTES: For more information about the InterruptThrottleRate, | ||
43 | RxIntDelay, TxIntDelay, RxAbsIntDelay, and TxAbsIntDelay | ||
44 | parameters, see the application note at: | ||
45 | http://www.intel.com/design/network/applnots/ap450.htm | ||
46 | |||
47 | InterruptThrottleRate | ||
48 | --------------------- | ||
49 | Valid Range: 0,1,3,4,100-100000 (0=off, 1=dynamic, 3=dynamic conservative, | ||
50 | 4=simplified balancing) | ||
51 | Default Value: 3 | ||
52 | |||
53 | The driver can limit the amount of interrupts per second that the adapter | ||
54 | will generate for incoming packets. It does this by writing a value to the | ||
55 | adapter that is based on the maximum amount of interrupts that the adapter | ||
56 | will generate per second. | ||
57 | |||
58 | Setting InterruptThrottleRate to a value greater or equal to 100 | ||
59 | will program the adapter to send out a maximum of that many interrupts | ||
60 | per second, even if more packets have come in. This reduces interrupt | ||
61 | load on the system and can lower CPU utilization under heavy load, | ||
62 | but will increase latency as packets are not processed as quickly. | ||
63 | |||
64 | The driver has two adaptive modes (setting 1 or 3) in which | ||
65 | it dynamically adjusts the InterruptThrottleRate value based on the traffic | ||
66 | that it receives. After determining the type of incoming traffic in the last | ||
67 | timeframe, it will adjust the InterruptThrottleRate to an appropriate value | ||
68 | for that traffic. | ||
69 | |||
70 | The algorithm classifies the incoming traffic every interval into | ||
71 | classes. Once the class is determined, the InterruptThrottleRate value is | ||
72 | adjusted to suit that traffic type the best. There are three classes defined: | ||
73 | "Bulk traffic", for large amounts of packets of normal size; "Low latency", | ||
74 | for small amounts of traffic and/or a significant percentage of small | ||
75 | packets; and "Lowest latency", for almost completely small packets or | ||
76 | minimal traffic. | ||
77 | |||
78 | In dynamic conservative mode, the InterruptThrottleRate value is set to 4000 | ||
79 | for traffic that falls in class "Bulk traffic". If traffic falls in the "Low | ||
80 | latency" or "Lowest latency" class, the InterruptThrottleRate is increased | ||
81 | stepwise to 20000. This default mode is suitable for most applications. | ||
82 | |||
83 | For situations where low latency is vital such as cluster or | ||
84 | grid computing, the algorithm can reduce latency even more when | ||
85 | InterruptThrottleRate is set to mode 1. In this mode, which operates | ||
86 | the same as mode 3, the InterruptThrottleRate will be increased stepwise to | ||
87 | 70000 for traffic in class "Lowest latency". | ||
88 | |||
89 | In simplified mode the interrupt rate is based on the ratio of Tx and | ||
90 | Rx traffic. If the bytes per second rate is approximately equal the | ||
91 | interrupt rate will drop as low as 2000 interrupts per second. If the | ||
92 | traffic is mostly transmit or mostly receive, the interrupt rate could | ||
93 | be as high as 8000. | ||
94 | |||
95 | Setting InterruptThrottleRate to 0 turns off any interrupt moderation | ||
96 | and may improve small packet latency, but is generally not suitable | ||
97 | for bulk throughput traffic. | ||
98 | |||
99 | NOTE: InterruptThrottleRate takes precedence over the TxAbsIntDelay and | ||
100 | RxAbsIntDelay parameters. In other words, minimizing the receive | ||
101 | and/or transmit absolute delays does not force the controller to | ||
102 | generate more interrupts than what the Interrupt Throttle Rate | ||
103 | allows. | ||
104 | |||
105 | NOTE: When e1000e is loaded with default settings and multiple adapters | ||
106 | are in use simultaneously, the CPU utilization may increase non- | ||
107 | linearly. In order to limit the CPU utilization without impacting | ||
108 | the overall throughput, we recommend that you load the driver as | ||
109 | follows: | ||
110 | |||
111 | modprobe e1000e InterruptThrottleRate=3000,3000,3000 | ||
112 | |||
113 | This sets the InterruptThrottleRate to 3000 interrupts/sec for | ||
114 | the first, second, and third instances of the driver. The range | ||
115 | of 2000 to 3000 interrupts per second works on a majority of | ||
116 | systems and is a good starting point, but the optimal value will | ||
117 | be platform-specific. If CPU utilization is not a concern, use | ||
118 | RX_POLLING (NAPI) and default driver settings. | ||
119 | |||
120 | RxIntDelay | ||
121 | ---------- | ||
122 | Valid Range: 0-65535 (0=off) | ||
123 | Default Value: 0 | ||
124 | |||
125 | This value delays the generation of receive interrupts in units of 1.024 | ||
126 | microseconds. Receive interrupt reduction can improve CPU efficiency if | ||
127 | properly tuned for specific network traffic. Increasing this value adds | ||
128 | extra latency to frame reception and can end up decreasing the throughput | ||
129 | of TCP traffic. If the system is reporting dropped receives, this value | ||
130 | may be set too high, causing the driver to run out of available receive | ||
131 | descriptors. | ||
132 | |||
133 | CAUTION: When setting RxIntDelay to a value other than 0, adapters may | ||
134 | hang (stop transmitting) under certain network conditions. If | ||
135 | this occurs a NETDEV WATCHDOG message is logged in the system | ||
136 | event log. In addition, the controller is automatically reset, | ||
137 | restoring the network connection. To eliminate the potential | ||
138 | for the hang ensure that RxIntDelay is set to 0. | ||
139 | |||
140 | RxAbsIntDelay | ||
141 | ------------- | ||
142 | Valid Range: 0-65535 (0=off) | ||
143 | Default Value: 8 | ||
144 | |||
145 | This value, in units of 1.024 microseconds, limits the delay in which a | ||
146 | receive interrupt is generated. Useful only if RxIntDelay is non-zero, | ||
147 | this value ensures that an interrupt is generated after the initial | ||
148 | packet is received within the set amount of time. Proper tuning, | ||
149 | along with RxIntDelay, may improve traffic throughput in specific network | ||
150 | conditions. | ||
151 | |||
152 | TxIntDelay | ||
153 | ---------- | ||
154 | Valid Range: 0-65535 (0=off) | ||
155 | Default Value: 8 | ||
156 | |||
157 | This value delays the generation of transmit interrupts in units of | ||
158 | 1.024 microseconds. Transmit interrupt reduction can improve CPU | ||
159 | efficiency if properly tuned for specific network traffic. If the | ||
160 | system is reporting dropped transmits, this value may be set too high | ||
161 | causing the driver to run out of available transmit descriptors. | ||
162 | |||
163 | TxAbsIntDelay | ||
164 | ------------- | ||
165 | Valid Range: 0-65535 (0=off) | ||
166 | Default Value: 32 | ||
167 | |||
168 | This value, in units of 1.024 microseconds, limits the delay in which a | ||
169 | transmit interrupt is generated. Useful only if TxIntDelay is non-zero, | ||
170 | this value ensures that an interrupt is generated after the initial | ||
171 | packet is sent on the wire within the set amount of time. Proper tuning, | ||
172 | along with TxIntDelay, may improve traffic throughput in specific | ||
173 | network conditions. | ||
174 | |||
175 | Copybreak | ||
176 | --------- | ||
177 | Valid Range: 0-xxxxxxx (0=off) | ||
178 | Default Value: 256 | ||
179 | |||
180 | Driver copies all packets below or equaling this size to a fresh Rx | ||
181 | buffer before handing it up the stack. | ||
182 | |||
183 | This parameter is different than other parameters, in that it is a | ||
184 | single (not 1,1,1 etc.) parameter applied to all driver instances and | ||
185 | it is also available during runtime at | ||
186 | /sys/module/e1000e/parameters/copybreak | ||
187 | |||
188 | SmartPowerDownEnable | ||
189 | -------------------- | ||
190 | Valid Range: 0-1 | ||
191 | Default Value: 0 (disabled) | ||
192 | |||
193 | Allows PHY to turn off in lower power states. The user can set this parameter | ||
194 | in supported chipsets. | ||
195 | |||
196 | KumeranLockLoss | ||
197 | --------------- | ||
198 | Valid Range: 0-1 | ||
199 | Default Value: 1 (enabled) | ||
200 | |||
201 | This workaround skips resetting the PHY at shutdown for the initial | ||
202 | silicon releases of ICH8 systems. | ||
203 | |||
204 | IntMode | ||
205 | ------- | ||
206 | Valid Range: 0-2 (0=legacy, 1=MSI, 2=MSI-X) | ||
207 | Default Value: 2 | ||
208 | |||
209 | Allows changing the interrupt mode at module load time, without requiring a | ||
210 | recompile. If the driver load fails to enable a specific interrupt mode, the | ||
211 | driver will try other interrupt modes, from least to most compatible. The | ||
212 | interrupt order is MSI-X, MSI, Legacy. If specifying MSI (IntMode=1) | ||
213 | interrupts, only MSI and Legacy will be attempted. | ||
214 | |||
215 | CrcStripping | ||
216 | ------------ | ||
217 | Valid Range: 0-1 | ||
218 | Default Value: 1 (enabled) | ||
219 | |||
220 | Strip the CRC from received packets before sending up the network stack. If | ||
221 | you have a machine with a BMC enabled but cannot receive IPMI traffic after | ||
222 | loading or enabling the driver, try disabling this feature. | ||
223 | |||
224 | WriteProtectNVM | ||
225 | --------------- | ||
226 | Valid Range: 0-1 | ||
227 | Default Value: 1 (enabled) | ||
228 | |||
229 | Set the hardware to ignore all write/erase cycles to the GbE region in the | ||
230 | ICHx NVM (non-volatile memory). This feature can be disabled by the | ||
231 | WriteProtectNVM module parameter (enabled by default) only after a hardware | ||
232 | reset, but the machine must be power cycled before trying to enable writes. | ||
233 | |||
234 | Note: the kernel boot option iomem=relaxed may need to be set if the kernel | ||
235 | config option CONFIG_STRICT_DEVMEM=y, if the root user wants to write the | ||
236 | NVM from user space via ethtool. | ||
237 | |||
238 | Additional Configurations | ||
239 | ========================= | ||
240 | |||
241 | Jumbo Frames | ||
242 | ------------ | ||
243 | Jumbo Frames support is enabled by changing the MTU to a value larger than | ||
244 | the default of 1500. Use the ifconfig command to increase the MTU size. | ||
245 | For example: | ||
246 | |||
247 | ifconfig eth<x> mtu 9000 up | ||
248 | |||
249 | This setting is not saved across reboots. | ||
250 | |||
251 | Notes: | ||
252 | |||
253 | - The maximum MTU setting for Jumbo Frames is 9216. This value coincides | ||
254 | with the maximum Jumbo Frames size of 9234 bytes. | ||
255 | |||
256 | - Using Jumbo Frames at 10 or 100 Mbps is not supported and may result in | ||
257 | poor performance or loss of link. | ||
258 | |||
259 | - Some adapters limit Jumbo Frames sized packets to a maximum of | ||
260 | 4096 bytes and some adapters do not support Jumbo Frames. | ||
261 | |||
262 | |||
263 | Ethtool | ||
264 | ------- | ||
265 | The driver utilizes the ethtool interface for driver configuration and | ||
266 | diagnostics, as well as displaying statistical information. We | ||
267 | strongly recommend downloading the latest version of Ethtool at: | ||
268 | |||
269 | http://sourceforge.net/projects/gkernel. | ||
270 | |||
271 | Speed and Duplex | ||
272 | ---------------- | ||
273 | Speed and Duplex are configured through the Ethtool* utility. For | ||
274 | instructions, refer to the Ethtool man page. | ||
275 | |||
276 | Enabling Wake on LAN* (WoL) | ||
277 | --------------------------- | ||
278 | WoL is configured through the Ethtool* utility. For instructions on | ||
279 | enabling WoL with Ethtool, refer to the Ethtool man page. | ||
280 | |||
281 | WoL will be enabled on the system during the next shut down or reboot. | ||
282 | For this driver version, in order to enable WoL, the e1000e driver must be | ||
283 | loaded when shutting down or rebooting the system. | ||
284 | |||
285 | In most cases Wake On LAN is only supported on port A for multiple port | ||
286 | adapters. To verify if a port supports Wake on LAN run ethtool eth<X>. | ||
287 | |||
288 | |||
289 | Support | ||
290 | ======= | ||
291 | |||
292 | For general information, go to the Intel support website at: | ||
293 | |||
294 | www.intel.com/support/ | ||
295 | |||
296 | or the Intel Wired Networking project hosted by Sourceforge at: | ||
297 | |||
298 | http://sourceforge.net/projects/e1000 | ||
299 | |||
300 | If an issue is identified with the released source code on the supported | ||
301 | kernel with a supported adapter, email the specific information related | ||
302 | to the issue to e1000-devel@lists.sf.net | ||
diff --git a/Documentation/networking/ixgbevf.txt b/Documentation/networking/ixgbevf.txt index 19015de6725..21dd5d15b6b 100755..100644 --- a/Documentation/networking/ixgbevf.txt +++ b/Documentation/networking/ixgbevf.txt | |||
@@ -1,19 +1,16 @@ | |||
1 | Linux* Base Driver for Intel(R) Network Connection | 1 | Linux* Base Driver for Intel(R) Network Connection |
2 | ================================================== | 2 | ================================================== |
3 | 3 | ||
4 | November 24, 2009 | 4 | Intel Gigabit Linux driver. |
5 | Copyright(c) 1999 - 2010 Intel Corporation. | ||
5 | 6 | ||
6 | Contents | 7 | Contents |
7 | ======== | 8 | ======== |
8 | 9 | ||
9 | - In This Release | ||
10 | - Identifying Your Adapter | 10 | - Identifying Your Adapter |
11 | - Known Issues/Troubleshooting | 11 | - Known Issues/Troubleshooting |
12 | - Support | 12 | - Support |
13 | 13 | ||
14 | In This Release | ||
15 | =============== | ||
16 | |||
17 | This file describes the ixgbevf Linux* Base Driver for Intel Network | 14 | This file describes the ixgbevf Linux* Base Driver for Intel Network |
18 | Connection. | 15 | Connection. |
19 | 16 | ||
@@ -33,7 +30,7 @@ Identifying Your Adapter | |||
33 | For more information on how to identify your adapter, go to the Adapter & | 30 | For more information on how to identify your adapter, go to the Adapter & |
34 | Driver ID Guide at: | 31 | Driver ID Guide at: |
35 | 32 | ||
36 | http://support.intel.com/support/network/sb/CS-008441.htm | 33 | http://support.intel.com/support/go/network/adapter/idguide.htm |
37 | 34 | ||
38 | Known Issues/Troubleshooting | 35 | Known Issues/Troubleshooting |
39 | ============================ | 36 | ============================ |
@@ -57,34 +54,3 @@ or the Intel Wired Networking project hosted by Sourceforge at: | |||
57 | If an issue is identified with the released source code on the supported | 54 | If an issue is identified with the released source code on the supported |
58 | kernel with a supported adapter, email the specific information related | 55 | kernel with a supported adapter, email the specific information related |
59 | to the issue to e1000-devel@lists.sf.net | 56 | to the issue to e1000-devel@lists.sf.net |
60 | |||
61 | License | ||
62 | ======= | ||
63 | |||
64 | Intel 10 Gigabit Linux driver. | ||
65 | Copyright(c) 1999 - 2009 Intel Corporation. | ||
66 | |||
67 | This program is free software; you can redistribute it and/or modify it | ||
68 | under the terms and conditions of the GNU General Public License, | ||
69 | version 2, as published by the Free Software Foundation. | ||
70 | |||
71 | This program is distributed in the hope it will be useful, but WITHOUT | ||
72 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
73 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
74 | more details. | ||
75 | |||
76 | You should have received a copy of the GNU General Public License along with | ||
77 | this program; if not, write to the Free Software Foundation, Inc., | ||
78 | 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
79 | |||
80 | The full GNU General Public License is included in this distribution in | ||
81 | the file called "COPYING". | ||
82 | |||
83 | Trademarks | ||
84 | ========== | ||
85 | |||
86 | Intel, Itanium, and Pentium are trademarks or registered trademarks of | ||
87 | Intel Corporation or its subsidiaries in the United States and other | ||
88 | countries. | ||
89 | |||
90 | * Other names and brands may be claimed as the property of others. | ||
diff --git a/Documentation/power/regulator/overview.txt b/Documentation/power/regulator/overview.txt index 9363e056188..8ed17587a74 100644 --- a/Documentation/power/regulator/overview.txt +++ b/Documentation/power/regulator/overview.txt | |||
@@ -13,7 +13,7 @@ regulators (where voltage output is controllable) and current sinks (where | |||
13 | current limit is controllable). | 13 | current limit is controllable). |
14 | 14 | ||
15 | (C) 2008 Wolfson Microelectronics PLC. | 15 | (C) 2008 Wolfson Microelectronics PLC. |
16 | Author: Liam Girdwood <lg@opensource.wolfsonmicro.com> | 16 | Author: Liam Girdwood <lrg@slimlogic.co.uk> |
17 | 17 | ||
18 | 18 | ||
19 | Nomenclature | 19 | Nomenclature |
diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt index ce46fa1e643..37c6aad5e59 100644 --- a/Documentation/sound/alsa/HD-Audio-Models.txt +++ b/Documentation/sound/alsa/HD-Audio-Models.txt | |||
@@ -296,6 +296,7 @@ Conexant 5051 | |||
296 | Conexant 5066 | 296 | Conexant 5066 |
297 | ============= | 297 | ============= |
298 | laptop Basic Laptop config (default) | 298 | laptop Basic Laptop config (default) |
299 | hp-laptop HP laptops, e g G60 | ||
299 | dell-laptop Dell laptops | 300 | dell-laptop Dell laptops |
300 | dell-vostro Dell Vostro | 301 | dell-vostro Dell Vostro |
301 | olpc-xo-1_5 OLPC XO 1.5 | 302 | olpc-xo-1_5 OLPC XO 1.5 |
diff --git a/Documentation/vm/page-types.c b/Documentation/vm/page-types.c index ccd951fa94e..cc96ee2666f 100644 --- a/Documentation/vm/page-types.c +++ b/Documentation/vm/page-types.c | |||
@@ -478,7 +478,7 @@ static void prepare_hwpoison_fd(void) | |||
478 | } | 478 | } |
479 | 479 | ||
480 | if (opt_unpoison && !hwpoison_forget_fd) { | 480 | if (opt_unpoison && !hwpoison_forget_fd) { |
481 | sprintf(buf, "%s/renew-pfn", hwpoison_debug_fs); | 481 | sprintf(buf, "%s/unpoison-pfn", hwpoison_debug_fs); |
482 | hwpoison_forget_fd = checked_open(buf, O_WRONLY); | 482 | hwpoison_forget_fd = checked_open(buf, O_WRONLY); |
483 | } | 483 | } |
484 | } | 484 | } |
diff --git a/Documentation/workqueue.txt b/Documentation/workqueue.txt new file mode 100644 index 00000000000..e4498a2872c --- /dev/null +++ b/Documentation/workqueue.txt | |||
@@ -0,0 +1,380 @@ | |||
1 | |||
2 | Concurrency Managed Workqueue (cmwq) | ||
3 | |||
4 | September, 2010 Tejun Heo <tj@kernel.org> | ||
5 | Florian Mickler <florian@mickler.org> | ||
6 | |||
7 | CONTENTS | ||
8 | |||
9 | 1. Introduction | ||
10 | 2. Why cmwq? | ||
11 | 3. The Design | ||
12 | 4. Application Programming Interface (API) | ||
13 | 5. Example Execution Scenarios | ||
14 | 6. Guidelines | ||
15 | |||
16 | |||
17 | 1. Introduction | ||
18 | |||
19 | There are many cases where an asynchronous process execution context | ||
20 | is needed and the workqueue (wq) API is the most commonly used | ||
21 | mechanism for such cases. | ||
22 | |||
23 | When such an asynchronous execution context is needed, a work item | ||
24 | describing which function to execute is put on a queue. An | ||
25 | independent thread serves as the asynchronous execution context. The | ||
26 | queue is called workqueue and the thread is called worker. | ||
27 | |||
28 | While there are work items on the workqueue the worker executes the | ||
29 | functions associated with the work items one after the other. When | ||
30 | there is no work item left on the workqueue the worker becomes idle. | ||
31 | When a new work item gets queued, the worker begins executing again. | ||
32 | |||
33 | |||
34 | 2. Why cmwq? | ||
35 | |||
36 | In the original wq implementation, a multi threaded (MT) wq had one | ||
37 | worker thread per CPU and a single threaded (ST) wq had one worker | ||
38 | thread system-wide. A single MT wq needed to keep around the same | ||
39 | number of workers as the number of CPUs. The kernel grew a lot of MT | ||
40 | wq users over the years and with the number of CPU cores continuously | ||
41 | rising, some systems saturated the default 32k PID space just booting | ||
42 | up. | ||
43 | |||
44 | Although MT wq wasted a lot of resource, the level of concurrency | ||
45 | provided was unsatisfactory. The limitation was common to both ST and | ||
46 | MT wq albeit less severe on MT. Each wq maintained its own separate | ||
47 | worker pool. A MT wq could provide only one execution context per CPU | ||
48 | while a ST wq one for the whole system. Work items had to compete for | ||
49 | those very limited execution contexts leading to various problems | ||
50 | including proneness to deadlocks around the single execution context. | ||
51 | |||
52 | The tension between the provided level of concurrency and resource | ||
53 | usage also forced its users to make unnecessary tradeoffs like libata | ||
54 | choosing to use ST wq for polling PIOs and accepting an unnecessary | ||
55 | limitation that no two polling PIOs can progress at the same time. As | ||
56 | MT wq don't provide much better concurrency, users which require | ||
57 | higher level of concurrency, like async or fscache, had to implement | ||
58 | their own thread pool. | ||
59 | |||
60 | Concurrency Managed Workqueue (cmwq) is a reimplementation of wq with | ||
61 | focus on the following goals. | ||
62 | |||
63 | * Maintain compatibility with the original workqueue API. | ||
64 | |||
65 | * Use per-CPU unified worker pools shared by all wq to provide | ||
66 | flexible level of concurrency on demand without wasting a lot of | ||
67 | resource. | ||
68 | |||
69 | * Automatically regulate worker pool and level of concurrency so that | ||
70 | the API users don't need to worry about such details. | ||
71 | |||
72 | |||
73 | 3. The Design | ||
74 | |||
75 | In order to ease the asynchronous execution of functions a new | ||
76 | abstraction, the work item, is introduced. | ||
77 | |||
78 | A work item is a simple struct that holds a pointer to the function | ||
79 | that is to be executed asynchronously. Whenever a driver or subsystem | ||
80 | wants a function to be executed asynchronously it has to set up a work | ||
81 | item pointing to that function and queue that work item on a | ||
82 | workqueue. | ||
83 | |||
84 | Special purpose threads, called worker threads, execute the functions | ||
85 | off of the queue, one after the other. If no work is queued, the | ||
86 | worker threads become idle. These worker threads are managed in so | ||
87 | called thread-pools. | ||
88 | |||
89 | The cmwq design differentiates between the user-facing workqueues that | ||
90 | subsystems and drivers queue work items on and the backend mechanism | ||
91 | which manages thread-pool and processes the queued work items. | ||
92 | |||
93 | The backend is called gcwq. There is one gcwq for each possible CPU | ||
94 | and one gcwq to serve work items queued on unbound workqueues. | ||
95 | |||
96 | Subsystems and drivers can create and queue work items through special | ||
97 | workqueue API functions as they see fit. They can influence some | ||
98 | aspects of the way the work items are executed by setting flags on the | ||
99 | workqueue they are putting the work item on. These flags include | ||
100 | things like CPU locality, reentrancy, concurrency limits and more. To | ||
101 | get a detailed overview refer to the API description of | ||
102 | alloc_workqueue() below. | ||
103 | |||
104 | When a work item is queued to a workqueue, the target gcwq is | ||
105 | determined according to the queue parameters and workqueue attributes | ||
106 | and appended on the shared worklist of the gcwq. For example, unless | ||
107 | specifically overridden, a work item of a bound workqueue will be | ||
108 | queued on the worklist of exactly that gcwq that is associated to the | ||
109 | CPU the issuer is running on. | ||
110 | |||
111 | For any worker pool implementation, managing the concurrency level | ||
112 | (how many execution contexts are active) is an important issue. cmwq | ||
113 | tries to keep the concurrency at a minimal but sufficient level. | ||
114 | Minimal to save resources and sufficient in that the system is used at | ||
115 | its full capacity. | ||
116 | |||
117 | Each gcwq bound to an actual CPU implements concurrency management by | ||
118 | hooking into the scheduler. The gcwq is notified whenever an active | ||
119 | worker wakes up or sleeps and keeps track of the number of the | ||
120 | currently runnable workers. Generally, work items are not expected to | ||
121 | hog a CPU and consume many cycles. That means maintaining just enough | ||
122 | concurrency to prevent work processing from stalling should be | ||
123 | optimal. As long as there are one or more runnable workers on the | ||
124 | CPU, the gcwq doesn't start execution of a new work, but, when the | ||
125 | last running worker goes to sleep, it immediately schedules a new | ||
126 | worker so that the CPU doesn't sit idle while there are pending work | ||
127 | items. This allows using a minimal number of workers without losing | ||
128 | execution bandwidth. | ||
129 | |||
130 | Keeping idle workers around doesn't cost other than the memory space | ||
131 | for kthreads, so cmwq holds onto idle ones for a while before killing | ||
132 | them. | ||
133 | |||
134 | For an unbound wq, the above concurrency management doesn't apply and | ||
135 | the gcwq for the pseudo unbound CPU tries to start executing all work | ||
136 | items as soon as possible. The responsibility of regulating | ||
137 | concurrency level is on the users. There is also a flag to mark a | ||
138 | bound wq to ignore the concurrency management. Please refer to the | ||
139 | API section for details. | ||
140 | |||
141 | Forward progress guarantee relies on that workers can be created when | ||
142 | more execution contexts are necessary, which in turn is guaranteed | ||
143 | through the use of rescue workers. All work items which might be used | ||
144 | on code paths that handle memory reclaim are required to be queued on | ||
145 | wq's that have a rescue-worker reserved for execution under memory | ||
146 | pressure. Else it is possible that the thread-pool deadlocks waiting | ||
147 | for execution contexts to free up. | ||
148 | |||
149 | |||
150 | 4. Application Programming Interface (API) | ||
151 | |||
152 | alloc_workqueue() allocates a wq. The original create_*workqueue() | ||
153 | functions are deprecated and scheduled for removal. alloc_workqueue() | ||
154 | takes three arguments - @name, @flags and @max_active. @name is the | ||
155 | name of the wq and also used as the name of the rescuer thread if | ||
156 | there is one. | ||
157 | |||
158 | A wq no longer manages execution resources but serves as a domain for | ||
159 | forward progress guarantee, flush and work item attributes. @flags | ||
160 | and @max_active control how work items are assigned execution | ||
161 | resources, scheduled and executed. | ||
162 | |||
163 | @flags: | ||
164 | |||
165 | WQ_NON_REENTRANT | ||
166 | |||
167 | By default, a wq guarantees non-reentrance only on the same | ||
168 | CPU. A work item may not be executed concurrently on the same | ||
169 | CPU by multiple workers but is allowed to be executed | ||
170 | concurrently on multiple CPUs. This flag makes sure | ||
171 | non-reentrance is enforced across all CPUs. Work items queued | ||
172 | to a non-reentrant wq are guaranteed to be executed by at most | ||
173 | one worker system-wide at any given time. | ||
174 | |||
175 | WQ_UNBOUND | ||
176 | |||
177 | Work items queued to an unbound wq are served by a special | ||
178 | gcwq which hosts workers which are not bound to any specific | ||
179 | CPU. This makes the wq behave as a simple execution context | ||
180 | provider without concurrency management. The unbound gcwq | ||
181 | tries to start execution of work items as soon as possible. | ||
182 | Unbound wq sacrifices locality but is useful for the following | ||
183 | cases. | ||
184 | |||
185 | * Wide fluctuation in the concurrency level requirement is | ||
186 | expected and using bound wq may end up creating large number | ||
187 | of mostly unused workers across different CPUs as the issuer | ||
188 | hops through different CPUs. | ||
189 | |||
190 | * Long running CPU intensive workloads which can be better | ||
191 | managed by the system scheduler. | ||
192 | |||
193 | WQ_FREEZEABLE | ||
194 | |||
195 | A freezeable wq participates in the freeze phase of the system | ||
196 | suspend operations. Work items on the wq are drained and no | ||
197 | new work item starts execution until thawed. | ||
198 | |||
199 | WQ_RESCUER | ||
200 | |||
201 | All wq which might be used in the memory reclaim paths _MUST_ | ||
202 | have this flag set. This reserves one worker exclusively for | ||
203 | the execution of this wq under memory pressure. | ||
204 | |||
205 | WQ_HIGHPRI | ||
206 | |||
207 | Work items of a highpri wq are queued at the head of the | ||
208 | worklist of the target gcwq and start execution regardless of | ||
209 | the current concurrency level. In other words, highpri work | ||
210 | items will always start execution as soon as execution | ||
211 | resource is available. | ||
212 | |||
213 | Ordering among highpri work items is preserved - a highpri | ||
214 | work item queued after another highpri work item will start | ||
215 | execution after the earlier highpri work item starts. | ||
216 | |||
217 | Although highpri work items are not held back by other | ||
218 | runnable work items, they still contribute to the concurrency | ||
219 | level. Highpri work items in runnable state will prevent | ||
220 | non-highpri work items from starting execution. | ||
221 | |||
222 | This flag is meaningless for unbound wq. | ||
223 | |||
224 | WQ_CPU_INTENSIVE | ||
225 | |||
226 | Work items of a CPU intensive wq do not contribute to the | ||
227 | concurrency level. In other words, runnable CPU intensive | ||
228 | work items will not prevent other work items from starting | ||
229 | execution. This is useful for bound work items which are | ||
230 | expected to hog CPU cycles so that their execution is | ||
231 | regulated by the system scheduler. | ||
232 | |||
233 | Although CPU intensive work items don't contribute to the | ||
234 | concurrency level, start of their executions is still | ||
235 | regulated by the concurrency management and runnable | ||
236 | non-CPU-intensive work items can delay execution of CPU | ||
237 | intensive work items. | ||
238 | |||
239 | This flag is meaningless for unbound wq. | ||
240 | |||
241 | WQ_HIGHPRI | WQ_CPU_INTENSIVE | ||
242 | |||
243 | This combination makes the wq avoid interaction with | ||
244 | concurrency management completely and behave as a simple | ||
245 | per-CPU execution context provider. Work items queued on a | ||
246 | highpri CPU-intensive wq start execution as soon as resources | ||
247 | are available and don't affect execution of other work items. | ||
248 | |||
249 | @max_active: | ||
250 | |||
251 | @max_active determines the maximum number of execution contexts per | ||
252 | CPU which can be assigned to the work items of a wq. For example, | ||
253 | with @max_active of 16, at most 16 work items of the wq can be | ||
254 | executing at the same time per CPU. | ||
255 | |||
256 | Currently, for a bound wq, the maximum limit for @max_active is 512 | ||
257 | and the default value used when 0 is specified is 256. For an unbound | ||
258 | wq, the limit is higher of 512 and 4 * num_possible_cpus(). These | ||
259 | values are chosen sufficiently high such that they are not the | ||
260 | limiting factor while providing protection in runaway cases. | ||
261 | |||
262 | The number of active work items of a wq is usually regulated by the | ||
263 | users of the wq, more specifically, by how many work items the users | ||
264 | may queue at the same time. Unless there is a specific need for | ||
265 | throttling the number of active work items, specifying '0' is | ||
266 | recommended. | ||
267 | |||
268 | Some users depend on the strict execution ordering of ST wq. The | ||
269 | combination of @max_active of 1 and WQ_UNBOUND is used to achieve this | ||
270 | behavior. Work items on such wq are always queued to the unbound gcwq | ||
271 | and only one work item can be active at any given time thus achieving | ||
272 | the same ordering property as ST wq. | ||
273 | |||
274 | |||
275 | 5. Example Execution Scenarios | ||
276 | |||
277 | The following example execution scenarios try to illustrate how cmwq | ||
278 | behave under different configurations. | ||
279 | |||
280 | Work items w0, w1, w2 are queued to a bound wq q0 on the same CPU. | ||
281 | w0 burns CPU for 5ms then sleeps for 10ms then burns CPU for 5ms | ||
282 | again before finishing. w1 and w2 burn CPU for 5ms then sleep for | ||
283 | 10ms. | ||
284 | |||
285 | Ignoring all other tasks, works and processing overhead, and assuming | ||
286 | simple FIFO scheduling, the following is one highly simplified version | ||
287 | of possible sequences of events with the original wq. | ||
288 | |||
289 | TIME IN MSECS EVENT | ||
290 | 0 w0 starts and burns CPU | ||
291 | 5 w0 sleeps | ||
292 | 15 w0 wakes up and burns CPU | ||
293 | 20 w0 finishes | ||
294 | 20 w1 starts and burns CPU | ||
295 | 25 w1 sleeps | ||
296 | 35 w1 wakes up and finishes | ||
297 | 35 w2 starts and burns CPU | ||
298 | 40 w2 sleeps | ||
299 | 50 w2 wakes up and finishes | ||
300 | |||
301 | And with cmwq with @max_active >= 3, | ||
302 | |||
303 | TIME IN MSECS EVENT | ||
304 | 0 w0 starts and burns CPU | ||
305 | 5 w0 sleeps | ||
306 | 5 w1 starts and burns CPU | ||
307 | 10 w1 sleeps | ||
308 | 10 w2 starts and burns CPU | ||
309 | 15 w2 sleeps | ||
310 | 15 w0 wakes up and burns CPU | ||
311 | 20 w0 finishes | ||
312 | 20 w1 wakes up and finishes | ||
313 | 25 w2 wakes up and finishes | ||
314 | |||
315 | If @max_active == 2, | ||
316 | |||
317 | TIME IN MSECS EVENT | ||
318 | 0 w0 starts and burns CPU | ||
319 | 5 w0 sleeps | ||
320 | 5 w1 starts and burns CPU | ||
321 | 10 w1 sleeps | ||
322 | 15 w0 wakes up and burns CPU | ||
323 | 20 w0 finishes | ||
324 | 20 w1 wakes up and finishes | ||
325 | 20 w2 starts and burns CPU | ||
326 | 25 w2 sleeps | ||
327 | 35 w2 wakes up and finishes | ||
328 | |||
329 | Now, let's assume w1 and w2 are queued to a different wq q1 which has | ||
330 | WQ_HIGHPRI set, | ||
331 | |||
332 | TIME IN MSECS EVENT | ||
333 | 0 w1 and w2 start and burn CPU | ||
334 | 5 w1 sleeps | ||
335 | 10 w2 sleeps | ||
336 | 10 w0 starts and burns CPU | ||
337 | 15 w0 sleeps | ||
338 | 15 w1 wakes up and finishes | ||
339 | 20 w2 wakes up and finishes | ||
340 | 25 w0 wakes up and burns CPU | ||
341 | 30 w0 finishes | ||
342 | |||
343 | If q1 has WQ_CPU_INTENSIVE set, | ||
344 | |||
345 | TIME IN MSECS EVENT | ||
346 | 0 w0 starts and burns CPU | ||
347 | 5 w0 sleeps | ||
348 | 5 w1 and w2 start and burn CPU | ||
349 | 10 w1 sleeps | ||
350 | 15 w2 sleeps | ||
351 | 15 w0 wakes up and burns CPU | ||
352 | 20 w0 finishes | ||
353 | 20 w1 wakes up and finishes | ||
354 | 25 w2 wakes up and finishes | ||
355 | |||
356 | |||
357 | 6. Guidelines | ||
358 | |||
359 | * Do not forget to use WQ_RESCUER if a wq may process work items which | ||
360 | are used during memory reclaim. Each wq with WQ_RESCUER set has one | ||
361 | rescuer thread reserved for it. If there is dependency among | ||
362 | multiple work items used during memory reclaim, they should be | ||
363 | queued to separate wq each with WQ_RESCUER. | ||
364 | |||
365 | * Unless strict ordering is required, there is no need to use ST wq. | ||
366 | |||
367 | * Unless there is a specific need, using 0 for @max_active is | ||
368 | recommended. In most use cases, concurrency level usually stays | ||
369 | well under the default limit. | ||
370 | |||
371 | * A wq serves as a domain for forward progress guarantee (WQ_RESCUER), | ||
372 | flush and work item attributes. Work items which are not involved | ||
373 | in memory reclaim and don't need to be flushed as a part of a group | ||
374 | of work items, and don't require any special attribute, can use one | ||
375 | of the system wq. There is no difference in execution | ||
376 | characteristics between using a dedicated wq and a system wq. | ||
377 | |||
378 | * Unless work items are expected to consume a huge amount of CPU | ||
379 | cycles, using a bound wq is usually beneficial due to the increased | ||
380 | level of locality in wq operations and work item execution. | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 433f3538575..7679bf32f7b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -454,6 +454,17 @@ L: linux-rdma@vger.kernel.org | |||
454 | S: Maintained | 454 | S: Maintained |
455 | F: drivers/infiniband/hw/amso1100/ | 455 | F: drivers/infiniband/hw/amso1100/ |
456 | 456 | ||
457 | ANALOG DEVICES INC ASOC DRIVERS | ||
458 | L: uclinux-dist-devel@blackfin.uclinux.org | ||
459 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) | ||
460 | W: http://blackfin.uclinux.org/ | ||
461 | S: Supported | ||
462 | F: sound/soc/blackfin/* | ||
463 | F: sound/soc/codecs/ad1* | ||
464 | F: sound/soc/codecs/adau* | ||
465 | F: sound/soc/codecs/adav* | ||
466 | F: sound/soc/codecs/ssm* | ||
467 | |||
457 | AOA (Apple Onboard Audio) ALSA DRIVER | 468 | AOA (Apple Onboard Audio) ALSA DRIVER |
458 | M: Johannes Berg <johannes@sipsolutions.net> | 469 | M: Johannes Berg <johannes@sipsolutions.net> |
459 | L: linuxppc-dev@lists.ozlabs.org | 470 | L: linuxppc-dev@lists.ozlabs.org |
@@ -951,6 +962,23 @@ W: http://www.fluff.org/ben/linux/ | |||
951 | S: Maintained | 962 | S: Maintained |
952 | F: arch/arm/mach-s3c6410/ | 963 | F: arch/arm/mach-s3c6410/ |
953 | 964 | ||
965 | ARM/S5P ARM ARCHITECTURES | ||
966 | M: Kukjin Kim <kgene.kim@samsung.com> | ||
967 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | ||
968 | L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) | ||
969 | S: Maintained | ||
970 | F: arch/arm/mach-s5p*/ | ||
971 | |||
972 | ARM/SAMSUNG S5P SERIES FIMC SUPPORT | ||
973 | M: Kyungmin Park <kyungmin.park@samsung.com> | ||
974 | M: Sylwester Nawrocki <s.nawrocki@samsung.com> | ||
975 | L: linux-arm-kernel@lists.infradead.org | ||
976 | L: linux-media@vger.kernel.org | ||
977 | S: Maintained | ||
978 | F: arch/arm/plat-s5p/dev-fimc* | ||
979 | F: arch/arm/plat-samsung/include/plat/*fimc* | ||
980 | F: drivers/media/video/s5p-fimc/ | ||
981 | |||
954 | ARM/SHMOBILE ARM ARCHITECTURE | 982 | ARM/SHMOBILE ARM ARCHITECTURE |
955 | M: Paul Mundt <lethal@linux-sh.org> | 983 | M: Paul Mundt <lethal@linux-sh.org> |
956 | M: Magnus Damm <magnus.damm@gmail.com> | 984 | M: Magnus Damm <magnus.damm@gmail.com> |
@@ -1124,7 +1152,7 @@ ATLX ETHERNET DRIVERS | |||
1124 | M: Jay Cliburn <jcliburn@gmail.com> | 1152 | M: Jay Cliburn <jcliburn@gmail.com> |
1125 | M: Chris Snook <chris.snook@gmail.com> | 1153 | M: Chris Snook <chris.snook@gmail.com> |
1126 | M: Jie Yang <jie.yang@atheros.com> | 1154 | M: Jie Yang <jie.yang@atheros.com> |
1127 | L: atl1-devel@lists.sourceforge.net | 1155 | L: netdev@vger.kernel.org |
1128 | W: http://sourceforge.net/projects/atl1 | 1156 | W: http://sourceforge.net/projects/atl1 |
1129 | W: http://atl1.sourceforge.net | 1157 | W: http://atl1.sourceforge.net |
1130 | S: Maintained | 1158 | S: Maintained |
@@ -1209,7 +1237,7 @@ F: drivers/auxdisplay/ | |||
1209 | F: include/linux/cfag12864b.h | 1237 | F: include/linux/cfag12864b.h |
1210 | 1238 | ||
1211 | AVR32 ARCHITECTURE | 1239 | AVR32 ARCHITECTURE |
1212 | M: Haavard Skinnemoen <hskinnemoen@atmel.com> | 1240 | M: Hans-Christian Egtvedt <hans-christian.egtvedt@atmel.com> |
1213 | W: http://www.atmel.com/products/AVR32/ | 1241 | W: http://www.atmel.com/products/AVR32/ |
1214 | W: http://avr32linux.org/ | 1242 | W: http://avr32linux.org/ |
1215 | W: http://avrfreaks.net/ | 1243 | W: http://avrfreaks.net/ |
@@ -1217,7 +1245,7 @@ S: Supported | |||
1217 | F: arch/avr32/ | 1245 | F: arch/avr32/ |
1218 | 1246 | ||
1219 | AVR32/AT32AP MACHINE SUPPORT | 1247 | AVR32/AT32AP MACHINE SUPPORT |
1220 | M: Haavard Skinnemoen <hskinnemoen@atmel.com> | 1248 | M: Hans-Christian Egtvedt <hans-christian.egtvedt@atmel.com> |
1221 | S: Supported | 1249 | S: Supported |
1222 | F: arch/avr32/mach-at32ap/ | 1250 | F: arch/avr32/mach-at32ap/ |
1223 | 1251 | ||
@@ -1434,6 +1462,16 @@ S: Maintained | |||
1434 | F: Documentation/video4linux/cafe_ccic | 1462 | F: Documentation/video4linux/cafe_ccic |
1435 | F: drivers/media/video/cafe_ccic* | 1463 | F: drivers/media/video/cafe_ccic* |
1436 | 1464 | ||
1465 | CAIF NETWORK LAYER | ||
1466 | M: Sjur Braendeland <sjur.brandeland@stericsson.com> | ||
1467 | L: netdev@vger.kernel.org | ||
1468 | S: Supported | ||
1469 | F: Documentation/networking/caif/ | ||
1470 | F: drivers/net/caif/ | ||
1471 | F: include/linux/caif/ | ||
1472 | F: include/net/caif/ | ||
1473 | F: net/caif/ | ||
1474 | |||
1437 | CALGARY x86-64 IOMMU | 1475 | CALGARY x86-64 IOMMU |
1438 | M: Muli Ben-Yehuda <muli@il.ibm.com> | 1476 | M: Muli Ben-Yehuda <muli@il.ibm.com> |
1439 | M: "Jon D. Mason" <jdmason@kudzu.us> | 1477 | M: "Jon D. Mason" <jdmason@kudzu.us> |
@@ -1665,8 +1703,7 @@ F: kernel/cgroup* | |||
1665 | F: mm/*cgroup* | 1703 | F: mm/*cgroup* |
1666 | 1704 | ||
1667 | CORETEMP HARDWARE MONITORING DRIVER | 1705 | CORETEMP HARDWARE MONITORING DRIVER |
1668 | M: Rudolf Marek <r.marek@assembler.cz> | 1706 | M: Fenghua Yu <fenghua.yu@intel.com> |
1669 | M: Huaxu Wan <huaxu.wan@intel.com> | ||
1670 | L: lm-sensors@lm-sensors.org | 1707 | L: lm-sensors@lm-sensors.org |
1671 | S: Maintained | 1708 | S: Maintained |
1672 | F: Documentation/hwmon/coretemp | 1709 | F: Documentation/hwmon/coretemp |
@@ -2179,6 +2216,12 @@ W: http://acpi4asus.sf.net | |||
2179 | S: Maintained | 2216 | S: Maintained |
2180 | F: drivers/platform/x86/eeepc-laptop.c | 2217 | F: drivers/platform/x86/eeepc-laptop.c |
2181 | 2218 | ||
2219 | EFIFB FRAMEBUFFER DRIVER | ||
2220 | L: linux-fbdev@vger.kernel.org | ||
2221 | M: Peter Jones <pjones@redhat.com> | ||
2222 | S: Maintained | ||
2223 | F: drivers/video/efifb.c | ||
2224 | |||
2182 | EFS FILESYSTEM | 2225 | EFS FILESYSTEM |
2183 | W: http://aeschi.ch.eu.org/efs/ | 2226 | W: http://aeschi.ch.eu.org/efs/ |
2184 | S: Orphan | 2227 | S: Orphan |
@@ -2191,6 +2234,12 @@ L: linux-rdma@vger.kernel.org | |||
2191 | S: Supported | 2234 | S: Supported |
2192 | F: drivers/infiniband/hw/ehca/ | 2235 | F: drivers/infiniband/hw/ehca/ |
2193 | 2236 | ||
2237 | EHEA (IBM pSeries eHEA 10Gb ethernet adapter) DRIVER | ||
2238 | M: Breno Leitao <leitao@linux.vnet.ibm.com> | ||
2239 | L: netdev@vger.kernel.org | ||
2240 | S: Maintained | ||
2241 | F: drivers/net/ehea/ | ||
2242 | |||
2194 | EMBEDDED LINUX | 2243 | EMBEDDED LINUX |
2195 | M: Paul Gortmaker <paul.gortmaker@windriver.com> | 2244 | M: Paul Gortmaker <paul.gortmaker@windriver.com> |
2196 | M: Matt Mackall <mpm@selenic.com> | 2245 | M: Matt Mackall <mpm@selenic.com> |
@@ -2286,6 +2335,12 @@ S: Maintained | |||
2286 | F: Documentation/hwmon/f71805f | 2335 | F: Documentation/hwmon/f71805f |
2287 | F: drivers/hwmon/f71805f.c | 2336 | F: drivers/hwmon/f71805f.c |
2288 | 2337 | ||
2338 | FANOTIFY | ||
2339 | M: Eric Paris <eparis@redhat.com> | ||
2340 | S: Maintained | ||
2341 | F: fs/notify/fanotify/ | ||
2342 | F: include/linux/fanotify.h | ||
2343 | |||
2289 | FARSYNC SYNCHRONOUS DRIVER | 2344 | FARSYNC SYNCHRONOUS DRIVER |
2290 | M: Kevin Curtis <kevin.curtis@farsite.co.uk> | 2345 | M: Kevin Curtis <kevin.curtis@farsite.co.uk> |
2291 | W: http://www.farsite.co.uk/ | 2346 | W: http://www.farsite.co.uk/ |
@@ -2490,7 +2545,7 @@ S: Supported | |||
2490 | F: drivers/scsi/gdt* | 2545 | F: drivers/scsi/gdt* |
2491 | 2546 | ||
2492 | GENERIC GPIO I2C DRIVER | 2547 | GENERIC GPIO I2C DRIVER |
2493 | M: Haavard Skinnemoen <hskinnemoen@atmel.com> | 2548 | M: Haavard Skinnemoen <hskinnemoen@gmail.com> |
2494 | S: Supported | 2549 | S: Supported |
2495 | F: drivers/i2c/busses/i2c-gpio.c | 2550 | F: drivers/i2c/busses/i2c-gpio.c |
2496 | F: include/linux/i2c-gpio.h | 2551 | F: include/linux/i2c-gpio.h |
@@ -2625,9 +2680,14 @@ S: Maintained | |||
2625 | F: drivers/media/video/gspca/ | 2680 | F: drivers/media/video/gspca/ |
2626 | 2681 | ||
2627 | HARDWARE MONITORING | 2682 | HARDWARE MONITORING |
2683 | M: Jean Delvare <khali@linux-fr.org> | ||
2684 | M: Guenter Roeck <guenter.roeck@ericsson.com> | ||
2628 | L: lm-sensors@lm-sensors.org | 2685 | L: lm-sensors@lm-sensors.org |
2629 | W: http://www.lm-sensors.org/ | 2686 | W: http://www.lm-sensors.org/ |
2630 | S: Orphan | 2687 | T: quilt kernel.org/pub/linux/kernel/people/jdelvare/linux-2.6/jdelvare-hwmon/ |
2688 | T: quilt kernel.org/pub/linux/kernel/people/groeck/linux-staging/ | ||
2689 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git | ||
2690 | S: Maintained | ||
2631 | F: Documentation/hwmon/ | 2691 | F: Documentation/hwmon/ |
2632 | F: drivers/hwmon/ | 2692 | F: drivers/hwmon/ |
2633 | F: include/linux/hwmon*.h | 2693 | F: include/linux/hwmon*.h |
@@ -2765,11 +2825,6 @@ S: Maintained | |||
2765 | F: arch/x86/kernel/hpet.c | 2825 | F: arch/x86/kernel/hpet.c |
2766 | F: arch/x86/include/asm/hpet.h | 2826 | F: arch/x86/include/asm/hpet.h |
2767 | 2827 | ||
2768 | HPET: ACPI | ||
2769 | M: Bob Picco <bob.picco@hp.com> | ||
2770 | S: Maintained | ||
2771 | F: drivers/char/hpet.c | ||
2772 | |||
2773 | HPFS FILESYSTEM | 2828 | HPFS FILESYSTEM |
2774 | M: Mikulas Patocka <mikulas@artax.karlin.mff.cuni.cz> | 2829 | M: Mikulas Patocka <mikulas@artax.karlin.mff.cuni.cz> |
2775 | W: http://artax.karlin.mff.cuni.cz/~mikulas/vyplody/hpfs/index-e.cgi | 2830 | W: http://artax.karlin.mff.cuni.cz/~mikulas/vyplody/hpfs/index-e.cgi |
@@ -3018,16 +3073,27 @@ L: netdev@vger.kernel.org | |||
3018 | S: Maintained | 3073 | S: Maintained |
3019 | F: drivers/net/ixp2000/ | 3074 | F: drivers/net/ixp2000/ |
3020 | 3075 | ||
3021 | INTEL ETHERNET DRIVERS (e100/e1000/e1000e/igb/igbvf/ixgb/ixgbe) | 3076 | INTEL ETHERNET DRIVERS (e100/e1000/e1000e/igb/igbvf/ixgb/ixgbe/ixgbevf) |
3022 | M: Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 3077 | M: Jeff Kirsher <jeffrey.t.kirsher@intel.com> |
3023 | M: Jesse Brandeburg <jesse.brandeburg@intel.com> | 3078 | M: Jesse Brandeburg <jesse.brandeburg@intel.com> |
3024 | M: Bruce Allan <bruce.w.allan@intel.com> | 3079 | M: Bruce Allan <bruce.w.allan@intel.com> |
3025 | M: Alex Duyck <alexander.h.duyck@intel.com> | 3080 | M: Carolyn Wyborny <carolyn.wyborny@intel.com> |
3081 | M: Don Skidmore <donald.c.skidmore@intel.com> | ||
3082 | M: Greg Rose <gregory.v.rose@intel.com> | ||
3026 | M: PJ Waskiewicz <peter.p.waskiewicz.jr@intel.com> | 3083 | M: PJ Waskiewicz <peter.p.waskiewicz.jr@intel.com> |
3084 | M: Alex Duyck <alexander.h.duyck@intel.com> | ||
3027 | M: John Ronciak <john.ronciak@intel.com> | 3085 | M: John Ronciak <john.ronciak@intel.com> |
3028 | L: e1000-devel@lists.sourceforge.net | 3086 | L: e1000-devel@lists.sourceforge.net |
3029 | W: http://e1000.sourceforge.net/ | 3087 | W: http://e1000.sourceforge.net/ |
3030 | S: Supported | 3088 | S: Supported |
3089 | F: Documentation/networking/e100.txt | ||
3090 | F: Documentation/networking/e1000.txt | ||
3091 | F: Documentation/networking/e1000e.txt | ||
3092 | F: Documentation/networking/igb.txt | ||
3093 | F: Documentation/networking/igbvf.txt | ||
3094 | F: Documentation/networking/ixgb.txt | ||
3095 | F: Documentation/networking/ixgbe.txt | ||
3096 | F: Documentation/networking/ixgbevf.txt | ||
3031 | F: drivers/net/e100.c | 3097 | F: drivers/net/e100.c |
3032 | F: drivers/net/e1000/ | 3098 | F: drivers/net/e1000/ |
3033 | F: drivers/net/e1000e/ | 3099 | F: drivers/net/e1000e/ |
@@ -3035,6 +3101,7 @@ F: drivers/net/igb/ | |||
3035 | F: drivers/net/igbvf/ | 3101 | F: drivers/net/igbvf/ |
3036 | F: drivers/net/ixgb/ | 3102 | F: drivers/net/ixgb/ |
3037 | F: drivers/net/ixgbe/ | 3103 | F: drivers/net/ixgbe/ |
3104 | F: drivers/net/ixgbevf/ | ||
3038 | 3105 | ||
3039 | INTEL PRO/WIRELESS 2100 NETWORK CONNECTION SUPPORT | 3106 | INTEL PRO/WIRELESS 2100 NETWORK CONNECTION SUPPORT |
3040 | L: linux-wireless@vger.kernel.org | 3107 | L: linux-wireless@vger.kernel.org |
@@ -3382,7 +3449,7 @@ F: drivers/s390/kvm/ | |||
3382 | 3449 | ||
3383 | KEXEC | 3450 | KEXEC |
3384 | M: Eric Biederman <ebiederm@xmission.com> | 3451 | M: Eric Biederman <ebiederm@xmission.com> |
3385 | W: http://ftp.kernel.org/pub/linux/kernel/people/horms/kexec-tools/ | 3452 | W: http://kernel.org/pub/linux/utils/kernel/kexec/ |
3386 | L: kexec@lists.infradead.org | 3453 | L: kexec@lists.infradead.org |
3387 | S: Maintained | 3454 | S: Maintained |
3388 | F: include/linux/kexec.h | 3455 | F: include/linux/kexec.h |
@@ -3478,7 +3545,7 @@ LGUEST | |||
3478 | M: Rusty Russell <rusty@rustcorp.com.au> | 3545 | M: Rusty Russell <rusty@rustcorp.com.au> |
3479 | L: lguest@lists.ozlabs.org | 3546 | L: lguest@lists.ozlabs.org |
3480 | W: http://lguest.ozlabs.org/ | 3547 | W: http://lguest.ozlabs.org/ |
3481 | S: Maintained | 3548 | S: Odd Fixes |
3482 | F: Documentation/lguest/ | 3549 | F: Documentation/lguest/ |
3483 | F: arch/x86/lguest/ | 3550 | F: arch/x86/lguest/ |
3484 | F: drivers/lguest/ | 3551 | F: drivers/lguest/ |
@@ -3743,9 +3810,8 @@ W: http://www.syskonnect.com | |||
3743 | S: Supported | 3810 | S: Supported |
3744 | 3811 | ||
3745 | MATROX FRAMEBUFFER DRIVER | 3812 | MATROX FRAMEBUFFER DRIVER |
3746 | M: Petr Vandrovec <vandrove@vc.cvut.cz> | ||
3747 | L: linux-fbdev@vger.kernel.org | 3813 | L: linux-fbdev@vger.kernel.org |
3748 | S: Maintained | 3814 | S: Orphan |
3749 | F: drivers/video/matrox/matroxfb_* | 3815 | F: drivers/video/matrox/matroxfb_* |
3750 | F: include/linux/matroxfb.h | 3816 | F: include/linux/matroxfb.h |
3751 | 3817 | ||
@@ -3869,10 +3935,8 @@ F: Documentation/serial/moxa-smartio | |||
3869 | F: drivers/char/mxser.* | 3935 | F: drivers/char/mxser.* |
3870 | 3936 | ||
3871 | MSI LAPTOP SUPPORT | 3937 | MSI LAPTOP SUPPORT |
3872 | M: Lennart Poettering <mzxreary@0pointer.de> | 3938 | M: Lee, Chun-Yi <jlee@novell.com> |
3873 | L: platform-driver-x86@vger.kernel.org | 3939 | L: platform-driver-x86@vger.kernel.org |
3874 | W: https://tango.0pointer.de/mailman/listinfo/s270-linux | ||
3875 | W: http://0pointer.de/lennart/tchibo.html | ||
3876 | S: Maintained | 3940 | S: Maintained |
3877 | F: drivers/platform/x86/msi-laptop.c | 3941 | F: drivers/platform/x86/msi-laptop.c |
3878 | 3942 | ||
@@ -3889,8 +3953,10 @@ S: Supported | |||
3889 | F: drivers/mfd/ | 3953 | F: drivers/mfd/ |
3890 | 3954 | ||
3891 | MULTIMEDIA CARD (MMC), SECURE DIGITAL (SD) AND SDIO SUBSYSTEM | 3955 | MULTIMEDIA CARD (MMC), SECURE DIGITAL (SD) AND SDIO SUBSYSTEM |
3892 | S: Orphan | 3956 | M: Chris Ball <cjb@laptop.org> |
3893 | L: linux-mmc@vger.kernel.org | 3957 | L: linux-mmc@vger.kernel.org |
3958 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc.git | ||
3959 | S: Maintained | ||
3894 | F: drivers/mmc/ | 3960 | F: drivers/mmc/ |
3895 | F: include/linux/mmc/ | 3961 | F: include/linux/mmc/ |
3896 | 3962 | ||
@@ -3907,13 +3973,12 @@ F: Documentation/sound/oss/MultiSound | |||
3907 | F: sound/oss/msnd* | 3973 | F: sound/oss/msnd* |
3908 | 3974 | ||
3909 | MULTITECH MULTIPORT CARD (ISICOM) | 3975 | MULTITECH MULTIPORT CARD (ISICOM) |
3910 | M: Jiri Slaby <jirislaby@gmail.com> | 3976 | S: Orphan |
3911 | S: Maintained | ||
3912 | F: drivers/char/isicom.c | 3977 | F: drivers/char/isicom.c |
3913 | F: include/linux/isicom.h | 3978 | F: include/linux/isicom.h |
3914 | 3979 | ||
3915 | MUSB MULTIPOINT HIGH SPEED DUAL-ROLE CONTROLLER | 3980 | MUSB MULTIPOINT HIGH SPEED DUAL-ROLE CONTROLLER |
3916 | M: Felipe Balbi <felipe.balbi@nokia.com> | 3981 | M: Felipe Balbi <balbi@ti.com> |
3917 | L: linux-usb@vger.kernel.org | 3982 | L: linux-usb@vger.kernel.org |
3918 | T: git git://gitorious.org/usb/usb.git | 3983 | T: git git://gitorious.org/usb/usb.git |
3919 | S: Maintained | 3984 | S: Maintained |
@@ -3933,8 +3998,8 @@ S: Maintained | |||
3933 | F: drivers/net/natsemi.c | 3998 | F: drivers/net/natsemi.c |
3934 | 3999 | ||
3935 | NCP FILESYSTEM | 4000 | NCP FILESYSTEM |
3936 | M: Petr Vandrovec <vandrove@vc.cvut.cz> | 4001 | M: Petr Vandrovec <petr@vandrovec.name> |
3937 | S: Maintained | 4002 | S: Odd Fixes |
3938 | F: fs/ncpfs/ | 4003 | F: fs/ncpfs/ |
3939 | 4004 | ||
3940 | NCR DUAL 700 SCSI DRIVER (MICROCHANNEL) | 4005 | NCR DUAL 700 SCSI DRIVER (MICROCHANNEL) |
@@ -4211,7 +4276,7 @@ S: Maintained | |||
4211 | F: drivers/char/hw_random/omap-rng.c | 4276 | F: drivers/char/hw_random/omap-rng.c |
4212 | 4277 | ||
4213 | OMAP USB SUPPORT | 4278 | OMAP USB SUPPORT |
4214 | M: Felipe Balbi <felipe.balbi@nokia.com> | 4279 | M: Felipe Balbi <balbi@ti.com> |
4215 | M: David Brownell <dbrownell@users.sourceforge.net> | 4280 | M: David Brownell <dbrownell@users.sourceforge.net> |
4216 | L: linux-usb@vger.kernel.org | 4281 | L: linux-usb@vger.kernel.org |
4217 | L: linux-omap@vger.kernel.org | 4282 | L: linux-omap@vger.kernel.org |
@@ -4588,7 +4653,7 @@ F: include/linux/preempt.h | |||
4588 | PRISM54 WIRELESS DRIVER | 4653 | PRISM54 WIRELESS DRIVER |
4589 | M: "Luis R. Rodriguez" <mcgrof@gmail.com> | 4654 | M: "Luis R. Rodriguez" <mcgrof@gmail.com> |
4590 | L: linux-wireless@vger.kernel.org | 4655 | L: linux-wireless@vger.kernel.org |
4591 | W: http://prism54.org | 4656 | W: http://wireless.kernel.org/en/users/Drivers/p54 |
4592 | S: Obsolete | 4657 | S: Obsolete |
4593 | F: drivers/net/wireless/prism54/ | 4658 | F: drivers/net/wireless/prism54/ |
4594 | 4659 | ||
@@ -4789,6 +4854,7 @@ RCUTORTURE MODULE | |||
4789 | M: Josh Triplett <josh@freedesktop.org> | 4854 | M: Josh Triplett <josh@freedesktop.org> |
4790 | M: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> | 4855 | M: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> |
4791 | S: Supported | 4856 | S: Supported |
4857 | T: git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-2.6-rcu.git | ||
4792 | F: Documentation/RCU/torture.txt | 4858 | F: Documentation/RCU/torture.txt |
4793 | F: kernel/rcutorture.c | 4859 | F: kernel/rcutorture.c |
4794 | 4860 | ||
@@ -4813,6 +4879,7 @@ M: Dipankar Sarma <dipankar@in.ibm.com> | |||
4813 | M: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> | 4879 | M: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> |
4814 | W: http://www.rdrop.com/users/paulmck/rclock/ | 4880 | W: http://www.rdrop.com/users/paulmck/rclock/ |
4815 | S: Supported | 4881 | S: Supported |
4882 | T: git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-2.6-rcu.git | ||
4816 | F: Documentation/RCU/ | 4883 | F: Documentation/RCU/ |
4817 | F: include/linux/rcu* | 4884 | F: include/linux/rcu* |
4818 | F: include/linux/srcu* | 4885 | F: include/linux/srcu* |
@@ -4820,12 +4887,10 @@ F: kernel/rcu* | |||
4820 | F: kernel/srcu* | 4887 | F: kernel/srcu* |
4821 | X: kernel/rcutorture.c | 4888 | X: kernel/rcutorture.c |
4822 | 4889 | ||
4823 | REAL TIME CLOCK DRIVER | 4890 | REAL TIME CLOCK DRIVER (LEGACY) |
4824 | M: Paul Gortmaker <p_gortmaker@yahoo.com> | 4891 | M: Paul Gortmaker <p_gortmaker@yahoo.com> |
4825 | S: Maintained | 4892 | S: Maintained |
4826 | F: Documentation/rtc.txt | 4893 | F: drivers/char/rtc.c |
4827 | F: drivers/rtc/ | ||
4828 | F: include/linux/rtc.h | ||
4829 | 4894 | ||
4830 | REAL TIME CLOCK (RTC) SUBSYSTEM | 4895 | REAL TIME CLOCK (RTC) SUBSYSTEM |
4831 | M: Alessandro Zummo <a.zummo@towertech.it> | 4896 | M: Alessandro Zummo <a.zummo@towertech.it> |
@@ -4965,6 +5030,12 @@ F: drivers/media/common/saa7146* | |||
4965 | F: drivers/media/video/*7146* | 5030 | F: drivers/media/video/*7146* |
4966 | F: include/media/*7146* | 5031 | F: include/media/*7146* |
4967 | 5032 | ||
5033 | SAMSUNG AUDIO (ASoC) DRIVERS | ||
5034 | M: Jassi Brar <jassi.brar@samsung.com> | ||
5035 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) | ||
5036 | S: Supported | ||
5037 | F: sound/soc/s3c24xx | ||
5038 | |||
4968 | TLG2300 VIDEO4LINUX-2 DRIVER | 5039 | TLG2300 VIDEO4LINUX-2 DRIVER |
4969 | M: Huang Shijie <shijie8@gmail.com> | 5040 | M: Huang Shijie <shijie8@gmail.com> |
4970 | M: Kang Yong <kangyong@telegent.com> | 5041 | M: Kang Yong <kangyong@telegent.com> |
@@ -5062,8 +5133,10 @@ S: Maintained | |||
5062 | F: drivers/mmc/host/sdricoh_cs.c | 5133 | F: drivers/mmc/host/sdricoh_cs.c |
5063 | 5134 | ||
5064 | SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) DRIVER | 5135 | SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) DRIVER |
5065 | S: Orphan | 5136 | M: Chris Ball <cjb@laptop.org> |
5066 | L: linux-mmc@vger.kernel.org | 5137 | L: linux-mmc@vger.kernel.org |
5138 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc.git | ||
5139 | S: Maintained | ||
5067 | F: drivers/mmc/host/sdhci.* | 5140 | F: drivers/mmc/host/sdhci.* |
5068 | 5141 | ||
5069 | SECURE DIGITAL HOST CONTROLLER INTERFACE, OPEN FIRMWARE BINDINGS (SDHCI-OF) | 5142 | SECURE DIGITAL HOST CONTROLLER INTERFACE, OPEN FIRMWARE BINDINGS (SDHCI-OF) |
@@ -6405,8 +6478,10 @@ F: include/linux/wm97xx.h | |||
6405 | WOLFSON MICROELECTRONICS DRIVERS | 6478 | WOLFSON MICROELECTRONICS DRIVERS |
6406 | M: Mark Brown <broonie@opensource.wolfsonmicro.com> | 6479 | M: Mark Brown <broonie@opensource.wolfsonmicro.com> |
6407 | M: Ian Lartey <ian@opensource.wolfsonmicro.com> | 6480 | M: Ian Lartey <ian@opensource.wolfsonmicro.com> |
6481 | M: Dimitris Papastamos <dp@opensource.wolfsonmicro.com> | ||
6482 | T: git git://opensource.wolfsonmicro.com/linux-2.6-asoc | ||
6408 | T: git git://opensource.wolfsonmicro.com/linux-2.6-audioplus | 6483 | T: git git://opensource.wolfsonmicro.com/linux-2.6-audioplus |
6409 | W: http://opensource.wolfsonmicro.com/node/8 | 6484 | W: http://opensource.wolfsonmicro.com/content/linux-drivers-wolfson-devices |
6410 | S: Supported | 6485 | S: Supported |
6411 | F: Documentation/hwmon/wm83?? | 6486 | F: Documentation/hwmon/wm83?? |
6412 | F: drivers/leds/leds-wm83*.c | 6487 | F: drivers/leds/leds-wm83*.c |
@@ -1,8 +1,8 @@ | |||
1 | VERSION = 2 | 1 | VERSION = 2 |
2 | PATCHLEVEL = 6 | 2 | PATCHLEVEL = 6 |
3 | SUBLEVEL = 36 | 3 | SUBLEVEL = 36 |
4 | EXTRAVERSION = -rc2 | 4 | EXTRAVERSION = -rc8 |
5 | NAME = Sheep on Meth | 5 | NAME = Flesh-Eating Bats with Fangs |
6 | 6 | ||
7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
8 | # To see a list of typical targets execute "make help" | 8 | # To see a list of typical targets execute "make help" |
@@ -1408,8 +1408,8 @@ checkstack: | |||
1408 | $(OBJDUMP) -d vmlinux $$(find . -name '*.ko') | \ | 1408 | $(OBJDUMP) -d vmlinux $$(find . -name '*.ko') | \ |
1409 | $(PERL) $(src)/scripts/checkstack.pl $(CHECKSTACK_ARCH) | 1409 | $(PERL) $(src)/scripts/checkstack.pl $(CHECKSTACK_ARCH) |
1410 | 1410 | ||
1411 | kernelrelease: include/config/kernel.release | 1411 | kernelrelease: |
1412 | @echo $(KERNELRELEASE) | 1412 | @echo "$(KERNELVERSION)$$($(CONFIG_SHELL) $(srctree)/scripts/setlocalversion $(srctree))" |
1413 | 1413 | ||
1414 | kernelversion: | 1414 | kernelversion: |
1415 | @echo $(KERNELVERSION) | 1415 | @echo $(KERNELVERSION) |
diff --git a/arch/Kconfig b/arch/Kconfig index 4877a8c8ee1..fe48fc7a3eb 100644 --- a/arch/Kconfig +++ b/arch/Kconfig | |||
@@ -32,8 +32,9 @@ config HAVE_OPROFILE | |||
32 | 32 | ||
33 | config KPROBES | 33 | config KPROBES |
34 | bool "Kprobes" | 34 | bool "Kprobes" |
35 | depends on KALLSYMS && MODULES | 35 | depends on MODULES |
36 | depends on HAVE_KPROBES | 36 | depends on HAVE_KPROBES |
37 | select KALLSYMS | ||
37 | help | 38 | help |
38 | Kprobes allows you to trap at almost any kernel address and | 39 | Kprobes allows you to trap at almost any kernel address and |
39 | execute a callback function. register_kprobe() establishes | 40 | execute a callback function. register_kprobe() establishes |
@@ -45,7 +46,6 @@ config OPTPROBES | |||
45 | def_bool y | 46 | def_bool y |
46 | depends on KPROBES && HAVE_OPTPROBES | 47 | depends on KPROBES && HAVE_OPTPROBES |
47 | depends on !PREEMPT | 48 | depends on !PREEMPT |
48 | select KALLSYMS_ALL | ||
49 | 49 | ||
50 | config HAVE_EFFICIENT_UNALIGNED_ACCESS | 50 | config HAVE_EFFICIENT_UNALIGNED_ACCESS |
51 | bool | 51 | bool |
diff --git a/arch/alpha/include/asm/cache.h b/arch/alpha/include/asm/cache.h index f199e69a5d0..ad368a93a46 100644 --- a/arch/alpha/include/asm/cache.h +++ b/arch/alpha/include/asm/cache.h | |||
@@ -17,7 +17,6 @@ | |||
17 | # define L1_CACHE_SHIFT 5 | 17 | # define L1_CACHE_SHIFT 5 |
18 | #endif | 18 | #endif |
19 | 19 | ||
20 | #define L1_CACHE_ALIGN(x) (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1)) | ||
21 | #define SMP_CACHE_BYTES L1_CACHE_BYTES | 20 | #define SMP_CACHE_BYTES L1_CACHE_BYTES |
22 | 21 | ||
23 | #endif | 22 | #endif |
diff --git a/arch/alpha/include/asm/cacheflush.h b/arch/alpha/include/asm/cacheflush.h index 01d71e1c8a9..012f1243b1c 100644 --- a/arch/alpha/include/asm/cacheflush.h +++ b/arch/alpha/include/asm/cacheflush.h | |||
@@ -43,6 +43,8 @@ extern void smp_imb(void); | |||
43 | /* ??? Ought to use this in arch/alpha/kernel/signal.c too. */ | 43 | /* ??? Ought to use this in arch/alpha/kernel/signal.c too. */ |
44 | 44 | ||
45 | #ifndef CONFIG_SMP | 45 | #ifndef CONFIG_SMP |
46 | #include <linux/sched.h> | ||
47 | |||
46 | extern void __load_new_mm_context(struct mm_struct *); | 48 | extern void __load_new_mm_context(struct mm_struct *); |
47 | static inline void | 49 | static inline void |
48 | flush_icache_user_range(struct vm_area_struct *vma, struct page *page, | 50 | flush_icache_user_range(struct vm_area_struct *vma, struct page *page, |
diff --git a/arch/alpha/include/asm/unistd.h b/arch/alpha/include/asm/unistd.h index 804e5311c84..058937bf5a7 100644 --- a/arch/alpha/include/asm/unistd.h +++ b/arch/alpha/include/asm/unistd.h | |||
@@ -449,10 +449,13 @@ | |||
449 | #define __NR_pwritev 491 | 449 | #define __NR_pwritev 491 |
450 | #define __NR_rt_tgsigqueueinfo 492 | 450 | #define __NR_rt_tgsigqueueinfo 492 |
451 | #define __NR_perf_event_open 493 | 451 | #define __NR_perf_event_open 493 |
452 | #define __NR_fanotify_init 494 | ||
453 | #define __NR_fanotify_mark 495 | ||
454 | #define __NR_prlimit64 496 | ||
452 | 455 | ||
453 | #ifdef __KERNEL__ | 456 | #ifdef __KERNEL__ |
454 | 457 | ||
455 | #define NR_SYSCALLS 494 | 458 | #define NR_SYSCALLS 497 |
456 | 459 | ||
457 | #define __ARCH_WANT_IPC_PARSE_VERSION | 460 | #define __ARCH_WANT_IPC_PARSE_VERSION |
458 | #define __ARCH_WANT_OLD_READDIR | 461 | #define __ARCH_WANT_OLD_READDIR |
@@ -463,6 +466,7 @@ | |||
463 | #define __ARCH_WANT_SYS_OLD_GETRLIMIT | 466 | #define __ARCH_WANT_SYS_OLD_GETRLIMIT |
464 | #define __ARCH_WANT_SYS_OLDUMOUNT | 467 | #define __ARCH_WANT_SYS_OLDUMOUNT |
465 | #define __ARCH_WANT_SYS_SIGPENDING | 468 | #define __ARCH_WANT_SYS_SIGPENDING |
469 | #define __ARCH_WANT_SYS_RT_SIGSUSPEND | ||
466 | 470 | ||
467 | /* "Conditional" syscalls. What we want is | 471 | /* "Conditional" syscalls. What we want is |
468 | 472 | ||
diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S index b45d913a51c..6d159cee5f2 100644 --- a/arch/alpha/kernel/entry.S +++ b/arch/alpha/kernel/entry.S | |||
@@ -73,8 +73,6 @@ | |||
73 | ldq $20, HAE_REG($19); \ | 73 | ldq $20, HAE_REG($19); \ |
74 | stq $21, HAE_CACHE($19); \ | 74 | stq $21, HAE_CACHE($19); \ |
75 | stq $21, 0($20); \ | 75 | stq $21, 0($20); \ |
76 | ldq $0, 0($sp); \ | ||
77 | ldq $1, 8($sp); \ | ||
78 | 99:; \ | 76 | 99:; \ |
79 | ldq $19, 72($sp); \ | 77 | ldq $19, 72($sp); \ |
80 | ldq $20, 80($sp); \ | 78 | ldq $20, 80($sp); \ |
@@ -316,19 +314,24 @@ ret_from_sys_call: | |||
316 | cmovne $26, 0, $19 /* $19 = 0 => non-restartable */ | 314 | cmovne $26, 0, $19 /* $19 = 0 => non-restartable */ |
317 | ldq $0, SP_OFF($sp) | 315 | ldq $0, SP_OFF($sp) |
318 | and $0, 8, $0 | 316 | and $0, 8, $0 |
319 | beq $0, restore_all | 317 | beq $0, ret_to_kernel |
320 | ret_from_reschedule: | 318 | ret_to_user: |
321 | /* Make sure need_resched and sigpending don't change between | 319 | /* Make sure need_resched and sigpending don't change between |
322 | sampling and the rti. */ | 320 | sampling and the rti. */ |
323 | lda $16, 7 | 321 | lda $16, 7 |
324 | call_pal PAL_swpipl | 322 | call_pal PAL_swpipl |
325 | ldl $5, TI_FLAGS($8) | 323 | ldl $5, TI_FLAGS($8) |
326 | and $5, _TIF_WORK_MASK, $2 | 324 | and $5, _TIF_WORK_MASK, $2 |
327 | bne $5, work_pending | 325 | bne $2, work_pending |
328 | restore_all: | 326 | restore_all: |
329 | RESTORE_ALL | 327 | RESTORE_ALL |
330 | call_pal PAL_rti | 328 | call_pal PAL_rti |
331 | 329 | ||
330 | ret_to_kernel: | ||
331 | lda $16, 7 | ||
332 | call_pal PAL_swpipl | ||
333 | br restore_all | ||
334 | |||
332 | .align 3 | 335 | .align 3 |
333 | $syscall_error: | 336 | $syscall_error: |
334 | /* | 337 | /* |
@@ -363,7 +366,7 @@ $ret_success: | |||
363 | * $8: current. | 366 | * $8: current. |
364 | * $19: The old syscall number, or zero if this is not a return | 367 | * $19: The old syscall number, or zero if this is not a return |
365 | * from a syscall that errored and is possibly restartable. | 368 | * from a syscall that errored and is possibly restartable. |
366 | * $20: Error indication. | 369 | * $20: The old a3 value |
367 | */ | 370 | */ |
368 | 371 | ||
369 | .align 4 | 372 | .align 4 |
@@ -392,12 +395,18 @@ $work_resched: | |||
392 | 395 | ||
393 | $work_notifysig: | 396 | $work_notifysig: |
394 | mov $sp, $16 | 397 | mov $sp, $16 |
395 | br $1, do_switch_stack | 398 | bsr $1, do_switch_stack |
396 | mov $sp, $17 | 399 | mov $sp, $17 |
397 | mov $5, $18 | 400 | mov $5, $18 |
401 | mov $19, $9 /* save old syscall number */ | ||
402 | mov $20, $10 /* save old a3 */ | ||
403 | and $5, _TIF_SIGPENDING, $2 | ||
404 | cmovne $2, 0, $9 /* we don't want double syscall restarts */ | ||
398 | jsr $26, do_notify_resume | 405 | jsr $26, do_notify_resume |
406 | mov $9, $19 | ||
407 | mov $10, $20 | ||
399 | bsr $1, undo_switch_stack | 408 | bsr $1, undo_switch_stack |
400 | br restore_all | 409 | br ret_to_user |
401 | .end work_pending | 410 | .end work_pending |
402 | 411 | ||
403 | /* | 412 | /* |
@@ -430,6 +439,7 @@ strace: | |||
430 | beq $1, 1f | 439 | beq $1, 1f |
431 | ldq $27, 0($2) | 440 | ldq $27, 0($2) |
432 | 1: jsr $26, ($27), sys_gettimeofday | 441 | 1: jsr $26, ($27), sys_gettimeofday |
442 | ret_from_straced: | ||
433 | ldgp $gp, 0($26) | 443 | ldgp $gp, 0($26) |
434 | 444 | ||
435 | /* check return.. */ | 445 | /* check return.. */ |
@@ -650,7 +660,7 @@ kernel_thread: | |||
650 | /* We don't actually care for a3 success widgetry in the kernel. | 660 | /* We don't actually care for a3 success widgetry in the kernel. |
651 | Not for positive errno values. */ | 661 | Not for positive errno values. */ |
652 | stq $0, 0($sp) /* $0 */ | 662 | stq $0, 0($sp) /* $0 */ |
653 | br restore_all | 663 | br ret_to_kernel |
654 | .end kernel_thread | 664 | .end kernel_thread |
655 | 665 | ||
656 | /* | 666 | /* |
@@ -757,11 +767,15 @@ sys_vfork: | |||
757 | .ent sys_sigreturn | 767 | .ent sys_sigreturn |
758 | sys_sigreturn: | 768 | sys_sigreturn: |
759 | .prologue 0 | 769 | .prologue 0 |
770 | lda $9, ret_from_straced | ||
771 | cmpult $26, $9, $9 | ||
760 | mov $sp, $17 | 772 | mov $sp, $17 |
761 | lda $18, -SWITCH_STACK_SIZE($sp) | 773 | lda $18, -SWITCH_STACK_SIZE($sp) |
762 | lda $sp, -SWITCH_STACK_SIZE($sp) | 774 | lda $sp, -SWITCH_STACK_SIZE($sp) |
763 | jsr $26, do_sigreturn | 775 | jsr $26, do_sigreturn |
764 | br $1, undo_switch_stack | 776 | bne $9, 1f |
777 | jsr $26, syscall_trace | ||
778 | 1: br $1, undo_switch_stack | ||
765 | br ret_from_sys_call | 779 | br ret_from_sys_call |
766 | .end sys_sigreturn | 780 | .end sys_sigreturn |
767 | 781 | ||
@@ -770,47 +784,19 @@ sys_sigreturn: | |||
770 | .ent sys_rt_sigreturn | 784 | .ent sys_rt_sigreturn |
771 | sys_rt_sigreturn: | 785 | sys_rt_sigreturn: |
772 | .prologue 0 | 786 | .prologue 0 |
787 | lda $9, ret_from_straced | ||
788 | cmpult $26, $9, $9 | ||
773 | mov $sp, $17 | 789 | mov $sp, $17 |
774 | lda $18, -SWITCH_STACK_SIZE($sp) | 790 | lda $18, -SWITCH_STACK_SIZE($sp) |
775 | lda $sp, -SWITCH_STACK_SIZE($sp) | 791 | lda $sp, -SWITCH_STACK_SIZE($sp) |
776 | jsr $26, do_rt_sigreturn | 792 | jsr $26, do_rt_sigreturn |
777 | br $1, undo_switch_stack | 793 | bne $9, 1f |
794 | jsr $26, syscall_trace | ||
795 | 1: br $1, undo_switch_stack | ||
778 | br ret_from_sys_call | 796 | br ret_from_sys_call |
779 | .end sys_rt_sigreturn | 797 | .end sys_rt_sigreturn |
780 | 798 | ||
781 | .align 4 | 799 | .align 4 |
782 | .globl sys_sigsuspend | ||
783 | .ent sys_sigsuspend | ||
784 | sys_sigsuspend: | ||
785 | .prologue 0 | ||
786 | mov $sp, $17 | ||
787 | br $1, do_switch_stack | ||
788 | mov $sp, $18 | ||
789 | subq $sp, 16, $sp | ||
790 | stq $26, 0($sp) | ||
791 | jsr $26, do_sigsuspend | ||
792 | ldq $26, 0($sp) | ||
793 | lda $sp, SWITCH_STACK_SIZE+16($sp) | ||
794 | ret | ||
795 | .end sys_sigsuspend | ||
796 | |||
797 | .align 4 | ||
798 | .globl sys_rt_sigsuspend | ||
799 | .ent sys_rt_sigsuspend | ||
800 | sys_rt_sigsuspend: | ||
801 | .prologue 0 | ||
802 | mov $sp, $18 | ||
803 | br $1, do_switch_stack | ||
804 | mov $sp, $19 | ||
805 | subq $sp, 16, $sp | ||
806 | stq $26, 0($sp) | ||
807 | jsr $26, do_rt_sigsuspend | ||
808 | ldq $26, 0($sp) | ||
809 | lda $sp, SWITCH_STACK_SIZE+16($sp) | ||
810 | ret | ||
811 | .end sys_rt_sigsuspend | ||
812 | |||
813 | .align 4 | ||
814 | .globl sys_sethae | 800 | .globl sys_sethae |
815 | .ent sys_sethae | 801 | .ent sys_sethae |
816 | sys_sethae: | 802 | sys_sethae: |
@@ -929,15 +915,6 @@ sys_execve: | |||
929 | .end sys_execve | 915 | .end sys_execve |
930 | 916 | ||
931 | .align 4 | 917 | .align 4 |
932 | .globl osf_sigprocmask | ||
933 | .ent osf_sigprocmask | ||
934 | osf_sigprocmask: | ||
935 | .prologue 0 | ||
936 | mov $sp, $18 | ||
937 | jmp $31, sys_osf_sigprocmask | ||
938 | .end osf_sigprocmask | ||
939 | |||
940 | .align 4 | ||
941 | .globl alpha_ni_syscall | 918 | .globl alpha_ni_syscall |
942 | .ent alpha_ni_syscall | 919 | .ent alpha_ni_syscall |
943 | alpha_ni_syscall: | 920 | alpha_ni_syscall: |
diff --git a/arch/alpha/kernel/err_ev6.c b/arch/alpha/kernel/err_ev6.c index 8ca6345bf13..253cf1a8748 100644 --- a/arch/alpha/kernel/err_ev6.c +++ b/arch/alpha/kernel/err_ev6.c | |||
@@ -90,11 +90,13 @@ static int | |||
90 | ev6_parse_cbox(u64 c_addr, u64 c1_syn, u64 c2_syn, | 90 | ev6_parse_cbox(u64 c_addr, u64 c1_syn, u64 c2_syn, |
91 | u64 c_stat, u64 c_sts, int print) | 91 | u64 c_stat, u64 c_sts, int print) |
92 | { | 92 | { |
93 | char *sourcename[] = { "UNKNOWN", "UNKNOWN", "UNKNOWN", | 93 | static const char * const sourcename[] = { |
94 | "MEMORY", "BCACHE", "DCACHE", | 94 | "UNKNOWN", "UNKNOWN", "UNKNOWN", |
95 | "BCACHE PROBE", "BCACHE PROBE" }; | 95 | "MEMORY", "BCACHE", "DCACHE", |
96 | char *streamname[] = { "D", "I" }; | 96 | "BCACHE PROBE", "BCACHE PROBE" |
97 | char *bitsname[] = { "SINGLE", "DOUBLE" }; | 97 | }; |
98 | static const char * const streamname[] = { "D", "I" }; | ||
99 | static const char * const bitsname[] = { "SINGLE", "DOUBLE" }; | ||
98 | int status = MCHK_DISPOSITION_REPORT; | 100 | int status = MCHK_DISPOSITION_REPORT; |
99 | int source = -1, stream = -1, bits = -1; | 101 | int source = -1, stream = -1, bits = -1; |
100 | 102 | ||
diff --git a/arch/alpha/kernel/err_marvel.c b/arch/alpha/kernel/err_marvel.c index 52a79dfc13c..648ae88aeb8 100644 --- a/arch/alpha/kernel/err_marvel.c +++ b/arch/alpha/kernel/err_marvel.c | |||
@@ -109,7 +109,7 @@ marvel_print_err_cyc(u64 err_cyc) | |||
109 | #define IO7__ERR_CYC__CYCLE__M (0x7) | 109 | #define IO7__ERR_CYC__CYCLE__M (0x7) |
110 | 110 | ||
111 | printk("%s Packet In Error: %s\n" | 111 | printk("%s Packet In Error: %s\n" |
112 | "%s Error in %s, cycle %ld%s%s\n", | 112 | "%s Error in %s, cycle %lld%s%s\n", |
113 | err_print_prefix, | 113 | err_print_prefix, |
114 | packet_desc[EXTRACT(err_cyc, IO7__ERR_CYC__PACKET)], | 114 | packet_desc[EXTRACT(err_cyc, IO7__ERR_CYC__PACKET)], |
115 | err_print_prefix, | 115 | err_print_prefix, |
@@ -313,7 +313,7 @@ marvel_print_po7_ugbge_sym(u64 ugbge_sym) | |||
313 | } | 313 | } |
314 | 314 | ||
315 | printk("%s Up Hose Garbage Symptom:\n" | 315 | printk("%s Up Hose Garbage Symptom:\n" |
316 | "%s Source Port: %ld - Dest PID: %ld - OpCode: %s\n", | 316 | "%s Source Port: %lld - Dest PID: %lld - OpCode: %s\n", |
317 | err_print_prefix, | 317 | err_print_prefix, |
318 | err_print_prefix, | 318 | err_print_prefix, |
319 | EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_SRC_PORT), | 319 | EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_SRC_PORT), |
@@ -552,7 +552,7 @@ marvel_print_pox_spl_cmplt(u64 spl_cmplt) | |||
552 | #define IO7__POX_SPLCMPLT__REM_BYTE_COUNT__M (0xfff) | 552 | #define IO7__POX_SPLCMPLT__REM_BYTE_COUNT__M (0xfff) |
553 | 553 | ||
554 | printk("%s Split Completion Error:\n" | 554 | printk("%s Split Completion Error:\n" |
555 | "%s Source (Bus:Dev:Func): %ld:%ld:%ld\n", | 555 | "%s Source (Bus:Dev:Func): %lld:%lld:%lld\n", |
556 | err_print_prefix, | 556 | err_print_prefix, |
557 | err_print_prefix, | 557 | err_print_prefix, |
558 | EXTRACT(spl_cmplt, IO7__POX_SPLCMPLT__SOURCE_BUS), | 558 | EXTRACT(spl_cmplt, IO7__POX_SPLCMPLT__SOURCE_BUS), |
@@ -589,22 +589,23 @@ marvel_print_pox_spl_cmplt(u64 spl_cmplt) | |||
589 | static void | 589 | static void |
590 | marvel_print_pox_trans_sum(u64 trans_sum) | 590 | marvel_print_pox_trans_sum(u64 trans_sum) |
591 | { | 591 | { |
592 | char *pcix_cmd[] = { "Interrupt Acknowledge", | 592 | static const char * const pcix_cmd[] = { |
593 | "Special Cycle", | 593 | "Interrupt Acknowledge", |
594 | "I/O Read", | 594 | "Special Cycle", |
595 | "I/O Write", | 595 | "I/O Read", |
596 | "Reserved", | 596 | "I/O Write", |
597 | "Reserved / Device ID Message", | 597 | "Reserved", |
598 | "Memory Read", | 598 | "Reserved / Device ID Message", |
599 | "Memory Write", | 599 | "Memory Read", |
600 | "Reserved / Alias to Memory Read Block", | 600 | "Memory Write", |
601 | "Reserved / Alias to Memory Write Block", | 601 | "Reserved / Alias to Memory Read Block", |
602 | "Configuration Read", | 602 | "Reserved / Alias to Memory Write Block", |
603 | "Configuration Write", | 603 | "Configuration Read", |
604 | "Memory Read Multiple / Split Completion", | 604 | "Configuration Write", |
605 | "Dual Address Cycle", | 605 | "Memory Read Multiple / Split Completion", |
606 | "Memory Read Line / Memory Read Block", | 606 | "Dual Address Cycle", |
607 | "Memory Write and Invalidate / Memory Write Block" | 607 | "Memory Read Line / Memory Read Block", |
608 | "Memory Write and Invalidate / Memory Write Block" | ||
608 | }; | 609 | }; |
609 | 610 | ||
610 | #define IO7__POX_TRANSUM__PCI_ADDR__S (0) | 611 | #define IO7__POX_TRANSUM__PCI_ADDR__S (0) |
diff --git a/arch/alpha/kernel/err_titan.c b/arch/alpha/kernel/err_titan.c index f7ed97ce0df..c3b3781a03d 100644 --- a/arch/alpha/kernel/err_titan.c +++ b/arch/alpha/kernel/err_titan.c | |||
@@ -75,8 +75,12 @@ titan_parse_p_serror(int which, u64 serror, int print) | |||
75 | int status = MCHK_DISPOSITION_REPORT; | 75 | int status = MCHK_DISPOSITION_REPORT; |
76 | 76 | ||
77 | #ifdef CONFIG_VERBOSE_MCHECK | 77 | #ifdef CONFIG_VERBOSE_MCHECK |
78 | char *serror_src[] = {"GPCI", "APCI", "AGP HP", "AGP LP"}; | 78 | static const char * const serror_src[] = { |
79 | char *serror_cmd[] = {"DMA Read", "DMA RMW", "SGTE Read", "Reserved"}; | 79 | "GPCI", "APCI", "AGP HP", "AGP LP" |
80 | }; | ||
81 | static const char * const serror_cmd[] = { | ||
82 | "DMA Read", "DMA RMW", "SGTE Read", "Reserved" | ||
83 | }; | ||
80 | #endif /* CONFIG_VERBOSE_MCHECK */ | 84 | #endif /* CONFIG_VERBOSE_MCHECK */ |
81 | 85 | ||
82 | #define TITAN__PCHIP_SERROR__LOST_UECC (1UL << 0) | 86 | #define TITAN__PCHIP_SERROR__LOST_UECC (1UL << 0) |
@@ -140,14 +144,15 @@ titan_parse_p_perror(int which, int port, u64 perror, int print) | |||
140 | int status = MCHK_DISPOSITION_REPORT; | 144 | int status = MCHK_DISPOSITION_REPORT; |
141 | 145 | ||
142 | #ifdef CONFIG_VERBOSE_MCHECK | 146 | #ifdef CONFIG_VERBOSE_MCHECK |
143 | char *perror_cmd[] = { "Interrupt Acknowledge", "Special Cycle", | 147 | static const char * const perror_cmd[] = { |
144 | "I/O Read", "I/O Write", | 148 | "Interrupt Acknowledge", "Special Cycle", |
145 | "Reserved", "Reserved", | 149 | "I/O Read", "I/O Write", |
146 | "Memory Read", "Memory Write", | 150 | "Reserved", "Reserved", |
147 | "Reserved", "Reserved", | 151 | "Memory Read", "Memory Write", |
148 | "Configuration Read", "Configuration Write", | 152 | "Reserved", "Reserved", |
149 | "Memory Read Multiple", "Dual Address Cycle", | 153 | "Configuration Read", "Configuration Write", |
150 | "Memory Read Line","Memory Write and Invalidate" | 154 | "Memory Read Multiple", "Dual Address Cycle", |
155 | "Memory Read Line", "Memory Write and Invalidate" | ||
151 | }; | 156 | }; |
152 | #endif /* CONFIG_VERBOSE_MCHECK */ | 157 | #endif /* CONFIG_VERBOSE_MCHECK */ |
153 | 158 | ||
@@ -273,11 +278,11 @@ titan_parse_p_agperror(int which, u64 agperror, int print) | |||
273 | int cmd, len; | 278 | int cmd, len; |
274 | unsigned long addr; | 279 | unsigned long addr; |
275 | 280 | ||
276 | char *agperror_cmd[] = { "Read (low-priority)", "Read (high-priority)", | 281 | static const char * const agperror_cmd[] = { |
277 | "Write (low-priority)", | 282 | "Read (low-priority)", "Read (high-priority)", |
278 | "Write (high-priority)", | 283 | "Write (low-priority)", "Write (high-priority)", |
279 | "Reserved", "Reserved", | 284 | "Reserved", "Reserved", |
280 | "Flush", "Fence" | 285 | "Flush", "Fence" |
281 | }; | 286 | }; |
282 | #endif /* CONFIG_VERBOSE_MCHECK */ | 287 | #endif /* CONFIG_VERBOSE_MCHECK */ |
283 | 288 | ||
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index fb58150a7e8..547e8b84b2f 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/mm.h> | 16 | #include <linux/mm.h> |
17 | #include <linux/smp.h> | 17 | #include <linux/smp.h> |
18 | #include <linux/smp_lock.h> | ||
19 | #include <linux/stddef.h> | 18 | #include <linux/stddef.h> |
20 | #include <linux/syscalls.h> | 19 | #include <linux/syscalls.h> |
21 | #include <linux/unistd.h> | 20 | #include <linux/unistd.h> |
@@ -69,7 +68,6 @@ SYSCALL_DEFINE4(osf_set_program_attributes, unsigned long, text_start, | |||
69 | { | 68 | { |
70 | struct mm_struct *mm; | 69 | struct mm_struct *mm; |
71 | 70 | ||
72 | lock_kernel(); | ||
73 | mm = current->mm; | 71 | mm = current->mm; |
74 | mm->end_code = bss_start + bss_len; | 72 | mm->end_code = bss_start + bss_len; |
75 | mm->start_brk = bss_start + bss_len; | 73 | mm->start_brk = bss_start + bss_len; |
@@ -78,7 +76,6 @@ SYSCALL_DEFINE4(osf_set_program_attributes, unsigned long, text_start, | |||
78 | printk("set_program_attributes(%lx %lx %lx %lx)\n", | 76 | printk("set_program_attributes(%lx %lx %lx %lx)\n", |
79 | text_start, text_len, bss_start, bss_len); | 77 | text_start, text_len, bss_start, bss_len); |
80 | #endif | 78 | #endif |
81 | unlock_kernel(); | ||
82 | return 0; | 79 | return 0; |
83 | } | 80 | } |
84 | 81 | ||
@@ -252,7 +249,7 @@ SYSCALL_DEFINE3(osf_statfs, const char __user *, pathname, | |||
252 | 249 | ||
253 | retval = user_path(pathname, &path); | 250 | retval = user_path(pathname, &path); |
254 | if (!retval) { | 251 | if (!retval) { |
255 | retval = do_osf_statfs(&path buffer, bufsiz); | 252 | retval = do_osf_statfs(&path, buffer, bufsiz); |
256 | path_put(&path); | 253 | path_put(&path); |
257 | } | 254 | } |
258 | return retval; | 255 | return retval; |
@@ -517,7 +514,6 @@ SYSCALL_DEFINE2(osf_proplist_syscall, enum pl_code, code, | |||
517 | long error; | 514 | long error; |
518 | int __user *min_buf_size_ptr; | 515 | int __user *min_buf_size_ptr; |
519 | 516 | ||
520 | lock_kernel(); | ||
521 | switch (code) { | 517 | switch (code) { |
522 | case PL_SET: | 518 | case PL_SET: |
523 | if (get_user(error, &args->set.nbytes)) | 519 | if (get_user(error, &args->set.nbytes)) |
@@ -547,7 +543,6 @@ SYSCALL_DEFINE2(osf_proplist_syscall, enum pl_code, code, | |||
547 | error = -EOPNOTSUPP; | 543 | error = -EOPNOTSUPP; |
548 | break; | 544 | break; |
549 | }; | 545 | }; |
550 | unlock_kernel(); | ||
551 | return error; | 546 | return error; |
552 | } | 547 | } |
553 | 548 | ||
@@ -594,7 +589,7 @@ SYSCALL_DEFINE2(osf_sigstack, struct sigstack __user *, uss, | |||
594 | 589 | ||
595 | SYSCALL_DEFINE3(osf_sysinfo, int, command, char __user *, buf, long, count) | 590 | SYSCALL_DEFINE3(osf_sysinfo, int, command, char __user *, buf, long, count) |
596 | { | 591 | { |
597 | char *sysinfo_table[] = { | 592 | const char *sysinfo_table[] = { |
598 | utsname()->sysname, | 593 | utsname()->sysname, |
599 | utsname()->nodename, | 594 | utsname()->nodename, |
600 | utsname()->release, | 595 | utsname()->release, |
@@ -606,7 +601,7 @@ SYSCALL_DEFINE3(osf_sysinfo, int, command, char __user *, buf, long, count) | |||
606 | "dummy", /* secure RPC domain */ | 601 | "dummy", /* secure RPC domain */ |
607 | }; | 602 | }; |
608 | unsigned long offset; | 603 | unsigned long offset; |
609 | char *res; | 604 | const char *res; |
610 | long len, err = -EINVAL; | 605 | long len, err = -EINVAL; |
611 | 606 | ||
612 | offset = command-1; | 607 | offset = command-1; |
diff --git a/arch/alpha/kernel/pci-sysfs.c b/arch/alpha/kernel/pci-sysfs.c index 738fc824e2e..b899e95f79f 100644 --- a/arch/alpha/kernel/pci-sysfs.c +++ b/arch/alpha/kernel/pci-sysfs.c | |||
@@ -66,7 +66,7 @@ static int pci_mmap_resource(struct kobject *kobj, | |||
66 | { | 66 | { |
67 | struct pci_dev *pdev = to_pci_dev(container_of(kobj, | 67 | struct pci_dev *pdev = to_pci_dev(container_of(kobj, |
68 | struct device, kobj)); | 68 | struct device, kobj)); |
69 | struct resource *res = (struct resource *)attr->private; | 69 | struct resource *res = attr->private; |
70 | enum pci_mmap_state mmap_type; | 70 | enum pci_mmap_state mmap_type; |
71 | struct pci_bus_region bar; | 71 | struct pci_bus_region bar; |
72 | int i; | 72 | int i; |
diff --git a/arch/alpha/kernel/perf_event.c b/arch/alpha/kernel/perf_event.c index 51c39fa4169..85d8e4f58c8 100644 --- a/arch/alpha/kernel/perf_event.c +++ b/arch/alpha/kernel/perf_event.c | |||
@@ -241,20 +241,20 @@ static inline unsigned long alpha_read_pmc(int idx) | |||
241 | static int alpha_perf_event_set_period(struct perf_event *event, | 241 | static int alpha_perf_event_set_period(struct perf_event *event, |
242 | struct hw_perf_event *hwc, int idx) | 242 | struct hw_perf_event *hwc, int idx) |
243 | { | 243 | { |
244 | long left = atomic64_read(&hwc->period_left); | 244 | long left = local64_read(&hwc->period_left); |
245 | long period = hwc->sample_period; | 245 | long period = hwc->sample_period; |
246 | int ret = 0; | 246 | int ret = 0; |
247 | 247 | ||
248 | if (unlikely(left <= -period)) { | 248 | if (unlikely(left <= -period)) { |
249 | left = period; | 249 | left = period; |
250 | atomic64_set(&hwc->period_left, left); | 250 | local64_set(&hwc->period_left, left); |
251 | hwc->last_period = period; | 251 | hwc->last_period = period; |
252 | ret = 1; | 252 | ret = 1; |
253 | } | 253 | } |
254 | 254 | ||
255 | if (unlikely(left <= 0)) { | 255 | if (unlikely(left <= 0)) { |
256 | left += period; | 256 | left += period; |
257 | atomic64_set(&hwc->period_left, left); | 257 | local64_set(&hwc->period_left, left); |
258 | hwc->last_period = period; | 258 | hwc->last_period = period; |
259 | ret = 1; | 259 | ret = 1; |
260 | } | 260 | } |
@@ -269,7 +269,7 @@ static int alpha_perf_event_set_period(struct perf_event *event, | |||
269 | if (left > (long)alpha_pmu->pmc_max_period[idx]) | 269 | if (left > (long)alpha_pmu->pmc_max_period[idx]) |
270 | left = alpha_pmu->pmc_max_period[idx]; | 270 | left = alpha_pmu->pmc_max_period[idx]; |
271 | 271 | ||
272 | atomic64_set(&hwc->prev_count, (unsigned long)(-left)); | 272 | local64_set(&hwc->prev_count, (unsigned long)(-left)); |
273 | 273 | ||
274 | alpha_write_pmc(idx, (unsigned long)(-left)); | 274 | alpha_write_pmc(idx, (unsigned long)(-left)); |
275 | 275 | ||
@@ -300,10 +300,10 @@ static unsigned long alpha_perf_event_update(struct perf_event *event, | |||
300 | long delta; | 300 | long delta; |
301 | 301 | ||
302 | again: | 302 | again: |
303 | prev_raw_count = atomic64_read(&hwc->prev_count); | 303 | prev_raw_count = local64_read(&hwc->prev_count); |
304 | new_raw_count = alpha_read_pmc(idx); | 304 | new_raw_count = alpha_read_pmc(idx); |
305 | 305 | ||
306 | if (atomic64_cmpxchg(&hwc->prev_count, prev_raw_count, | 306 | if (local64_cmpxchg(&hwc->prev_count, prev_raw_count, |
307 | new_raw_count) != prev_raw_count) | 307 | new_raw_count) != prev_raw_count) |
308 | goto again; | 308 | goto again; |
309 | 309 | ||
@@ -316,8 +316,8 @@ again: | |||
316 | delta += alpha_pmu->pmc_max_period[idx] + 1; | 316 | delta += alpha_pmu->pmc_max_period[idx] + 1; |
317 | } | 317 | } |
318 | 318 | ||
319 | atomic64_add(delta, &event->count); | 319 | local64_add(delta, &event->count); |
320 | atomic64_sub(delta, &hwc->period_left); | 320 | local64_sub(delta, &hwc->period_left); |
321 | 321 | ||
322 | return new_raw_count; | 322 | return new_raw_count; |
323 | } | 323 | } |
@@ -636,7 +636,7 @@ static int __hw_perf_event_init(struct perf_event *event) | |||
636 | if (!hwc->sample_period) { | 636 | if (!hwc->sample_period) { |
637 | hwc->sample_period = alpha_pmu->pmc_max_period[0]; | 637 | hwc->sample_period = alpha_pmu->pmc_max_period[0]; |
638 | hwc->last_period = hwc->sample_period; | 638 | hwc->last_period = hwc->sample_period; |
639 | atomic64_set(&hwc->period_left, hwc->sample_period); | 639 | local64_set(&hwc->period_left, hwc->sample_period); |
640 | } | 640 | } |
641 | 641 | ||
642 | return 0; | 642 | return 0; |
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c index 842dba308ea..3ec35066f1d 100644 --- a/arch/alpha/kernel/process.c +++ b/arch/alpha/kernel/process.c | |||
@@ -356,7 +356,7 @@ dump_elf_thread(elf_greg_t *dest, struct pt_regs *pt, struct thread_info *ti) | |||
356 | dest[27] = pt->r27; | 356 | dest[27] = pt->r27; |
357 | dest[28] = pt->r28; | 357 | dest[28] = pt->r28; |
358 | dest[29] = pt->gp; | 358 | dest[29] = pt->gp; |
359 | dest[30] = rdusp(); | 359 | dest[30] = ti == current_thread_info() ? rdusp() : ti->pcb.usp; |
360 | dest[31] = pt->pc; | 360 | dest[31] = pt->pc; |
361 | 361 | ||
362 | /* Once upon a time this was the PS value. Which is stupid | 362 | /* Once upon a time this was the PS value. Which is stupid |
diff --git a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h index 3d2627ec986..d3e52d3fd59 100644 --- a/arch/alpha/kernel/proto.h +++ b/arch/alpha/kernel/proto.h | |||
@@ -156,9 +156,6 @@ extern void SMC669_Init(int); | |||
156 | /* es1888.c */ | 156 | /* es1888.c */ |
157 | extern void es1888_init(void); | 157 | extern void es1888_init(void); |
158 | 158 | ||
159 | /* ns87312.c */ | ||
160 | extern void ns87312_enable_ide(long ide_base); | ||
161 | |||
162 | /* ../lib/fpreg.c */ | 159 | /* ../lib/fpreg.c */ |
163 | extern void alpha_write_fp_reg (unsigned long reg, unsigned long val); | 160 | extern void alpha_write_fp_reg (unsigned long reg, unsigned long val); |
164 | extern unsigned long alpha_read_fp_reg (unsigned long reg); | 161 | extern unsigned long alpha_read_fp_reg (unsigned long reg); |
diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c index 0932dbb1ef8..6f7feb5db27 100644 --- a/arch/alpha/kernel/signal.c +++ b/arch/alpha/kernel/signal.c | |||
@@ -41,46 +41,20 @@ static void do_signal(struct pt_regs *, struct switch_stack *, | |||
41 | /* | 41 | /* |
42 | * The OSF/1 sigprocmask calling sequence is different from the | 42 | * The OSF/1 sigprocmask calling sequence is different from the |
43 | * C sigprocmask() sequence.. | 43 | * C sigprocmask() sequence.. |
44 | * | ||
45 | * how: | ||
46 | * 1 - SIG_BLOCK | ||
47 | * 2 - SIG_UNBLOCK | ||
48 | * 3 - SIG_SETMASK | ||
49 | * | ||
50 | * We change the range to -1 .. 1 in order to let gcc easily | ||
51 | * use the conditional move instructions. | ||
52 | * | ||
53 | * Note that we don't need to acquire the kernel lock for SMP | ||
54 | * operation, as all of this is local to this thread. | ||
55 | */ | 44 | */ |
56 | SYSCALL_DEFINE3(osf_sigprocmask, int, how, unsigned long, newmask, | 45 | SYSCALL_DEFINE2(osf_sigprocmask, int, how, unsigned long, newmask) |
57 | struct pt_regs *, regs) | ||
58 | { | 46 | { |
59 | unsigned long oldmask = -EINVAL; | 47 | sigset_t oldmask; |
60 | 48 | sigset_t mask; | |
61 | if ((unsigned long)how-1 <= 2) { | 49 | unsigned long res; |
62 | long sign = how-2; /* -1 .. 1 */ | 50 | |
63 | unsigned long block, unblock; | 51 | siginitset(&mask, newmask & _BLOCKABLE); |
64 | 52 | res = sigprocmask(how, &mask, &oldmask); | |
65 | newmask &= _BLOCKABLE; | 53 | if (!res) { |
66 | spin_lock_irq(¤t->sighand->siglock); | 54 | force_successful_syscall_return(); |
67 | oldmask = current->blocked.sig[0]; | 55 | res = oldmask.sig[0]; |
68 | |||
69 | unblock = oldmask & ~newmask; | ||
70 | block = oldmask | newmask; | ||
71 | if (!sign) | ||
72 | block = unblock; | ||
73 | if (sign <= 0) | ||
74 | newmask = block; | ||
75 | if (_NSIG_WORDS > 1 && sign > 0) | ||
76 | sigemptyset(¤t->blocked); | ||
77 | current->blocked.sig[0] = newmask; | ||
78 | recalc_sigpending(); | ||
79 | spin_unlock_irq(¤t->sighand->siglock); | ||
80 | |||
81 | regs->r0 = 0; /* special no error return */ | ||
82 | } | 56 | } |
83 | return oldmask; | 57 | return res; |
84 | } | 58 | } |
85 | 59 | ||
86 | SYSCALL_DEFINE3(osf_sigaction, int, sig, | 60 | SYSCALL_DEFINE3(osf_sigaction, int, sig, |
@@ -94,9 +68,9 @@ SYSCALL_DEFINE3(osf_sigaction, int, sig, | |||
94 | old_sigset_t mask; | 68 | old_sigset_t mask; |
95 | if (!access_ok(VERIFY_READ, act, sizeof(*act)) || | 69 | if (!access_ok(VERIFY_READ, act, sizeof(*act)) || |
96 | __get_user(new_ka.sa.sa_handler, &act->sa_handler) || | 70 | __get_user(new_ka.sa.sa_handler, &act->sa_handler) || |
97 | __get_user(new_ka.sa.sa_flags, &act->sa_flags)) | 71 | __get_user(new_ka.sa.sa_flags, &act->sa_flags) || |
72 | __get_user(mask, &act->sa_mask)) | ||
98 | return -EFAULT; | 73 | return -EFAULT; |
99 | __get_user(mask, &act->sa_mask); | ||
100 | siginitset(&new_ka.sa.sa_mask, mask); | 74 | siginitset(&new_ka.sa.sa_mask, mask); |
101 | new_ka.ka_restorer = NULL; | 75 | new_ka.ka_restorer = NULL; |
102 | } | 76 | } |
@@ -106,9 +80,9 @@ SYSCALL_DEFINE3(osf_sigaction, int, sig, | |||
106 | if (!ret && oact) { | 80 | if (!ret && oact) { |
107 | if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || | 81 | if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || |
108 | __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || | 82 | __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || |
109 | __put_user(old_ka.sa.sa_flags, &oact->sa_flags)) | 83 | __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || |
84 | __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) | ||
110 | return -EFAULT; | 85 | return -EFAULT; |
111 | __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); | ||
112 | } | 86 | } |
113 | 87 | ||
114 | return ret; | 88 | return ret; |
@@ -144,8 +118,7 @@ SYSCALL_DEFINE5(rt_sigaction, int, sig, const struct sigaction __user *, act, | |||
144 | /* | 118 | /* |
145 | * Atomically swap in the new signal mask, and wait for a signal. | 119 | * Atomically swap in the new signal mask, and wait for a signal. |
146 | */ | 120 | */ |
147 | asmlinkage int | 121 | SYSCALL_DEFINE1(sigsuspend, old_sigset_t, mask) |
148 | do_sigsuspend(old_sigset_t mask, struct pt_regs *regs, struct switch_stack *sw) | ||
149 | { | 122 | { |
150 | mask &= _BLOCKABLE; | 123 | mask &= _BLOCKABLE; |
151 | spin_lock_irq(¤t->sighand->siglock); | 124 | spin_lock_irq(¤t->sighand->siglock); |
@@ -154,41 +127,6 @@ do_sigsuspend(old_sigset_t mask, struct pt_regs *regs, struct switch_stack *sw) | |||
154 | recalc_sigpending(); | 127 | recalc_sigpending(); |
155 | spin_unlock_irq(¤t->sighand->siglock); | 128 | spin_unlock_irq(¤t->sighand->siglock); |
156 | 129 | ||
157 | /* Indicate EINTR on return from any possible signal handler, | ||
158 | which will not come back through here, but via sigreturn. */ | ||
159 | regs->r0 = EINTR; | ||
160 | regs->r19 = 1; | ||
161 | |||
162 | current->state = TASK_INTERRUPTIBLE; | ||
163 | schedule(); | ||
164 | set_thread_flag(TIF_RESTORE_SIGMASK); | ||
165 | return -ERESTARTNOHAND; | ||
166 | } | ||
167 | |||
168 | asmlinkage int | ||
169 | do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize, | ||
170 | struct pt_regs *regs, struct switch_stack *sw) | ||
171 | { | ||
172 | sigset_t set; | ||
173 | |||
174 | /* XXX: Don't preclude handling different sized sigset_t's. */ | ||
175 | if (sigsetsize != sizeof(sigset_t)) | ||
176 | return -EINVAL; | ||
177 | if (copy_from_user(&set, uset, sizeof(set))) | ||
178 | return -EFAULT; | ||
179 | |||
180 | sigdelsetmask(&set, ~_BLOCKABLE); | ||
181 | spin_lock_irq(¤t->sighand->siglock); | ||
182 | current->saved_sigmask = current->blocked; | ||
183 | current->blocked = set; | ||
184 | recalc_sigpending(); | ||
185 | spin_unlock_irq(¤t->sighand->siglock); | ||
186 | |||
187 | /* Indicate EINTR on return from any possible signal handler, | ||
188 | which will not come back through here, but via sigreturn. */ | ||
189 | regs->r0 = EINTR; | ||
190 | regs->r19 = 1; | ||
191 | |||
192 | current->state = TASK_INTERRUPTIBLE; | 130 | current->state = TASK_INTERRUPTIBLE; |
193 | schedule(); | 131 | schedule(); |
194 | set_thread_flag(TIF_RESTORE_SIGMASK); | 132 | set_thread_flag(TIF_RESTORE_SIGMASK); |
@@ -239,6 +177,8 @@ restore_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, | |||
239 | unsigned long usp; | 177 | unsigned long usp; |
240 | long i, err = __get_user(regs->pc, &sc->sc_pc); | 178 | long i, err = __get_user(regs->pc, &sc->sc_pc); |
241 | 179 | ||
180 | current_thread_info()->restart_block.fn = do_no_restart_syscall; | ||
181 | |||
242 | sw->r26 = (unsigned long) ret_from_sys_call; | 182 | sw->r26 = (unsigned long) ret_from_sys_call; |
243 | 183 | ||
244 | err |= __get_user(regs->r0, sc->sc_regs+0); | 184 | err |= __get_user(regs->r0, sc->sc_regs+0); |
@@ -591,7 +531,6 @@ syscall_restart(unsigned long r0, unsigned long r19, | |||
591 | regs->pc -= 4; | 531 | regs->pc -= 4; |
592 | break; | 532 | break; |
593 | case ERESTART_RESTARTBLOCK: | 533 | case ERESTART_RESTARTBLOCK: |
594 | current_thread_info()->restart_block.fn = do_no_restart_syscall; | ||
595 | regs->r0 = EINTR; | 534 | regs->r0 = EINTR; |
596 | break; | 535 | break; |
597 | } | 536 | } |
diff --git a/arch/alpha/kernel/srm_env.c b/arch/alpha/kernel/srm_env.c index 4afc1a1e2e5..f0df3fbd840 100644 --- a/arch/alpha/kernel/srm_env.c +++ b/arch/alpha/kernel/srm_env.c | |||
@@ -87,7 +87,7 @@ static int srm_env_proc_show(struct seq_file *m, void *v) | |||
87 | srm_env_t *entry; | 87 | srm_env_t *entry; |
88 | char *page; | 88 | char *page; |
89 | 89 | ||
90 | entry = (srm_env_t *)m->private; | 90 | entry = m->private; |
91 | page = (char *)__get_free_page(GFP_USER); | 91 | page = (char *)__get_free_page(GFP_USER); |
92 | if (!page) | 92 | if (!page) |
93 | return -ENOMEM; | 93 | return -ENOMEM; |
diff --git a/arch/alpha/kernel/sys_cabriolet.c b/arch/alpha/kernel/sys_cabriolet.c index affd0f3f25d..14c8898d19e 100644 --- a/arch/alpha/kernel/sys_cabriolet.c +++ b/arch/alpha/kernel/sys_cabriolet.c | |||
@@ -33,7 +33,7 @@ | |||
33 | #include "irq_impl.h" | 33 | #include "irq_impl.h" |
34 | #include "pci_impl.h" | 34 | #include "pci_impl.h" |
35 | #include "machvec_impl.h" | 35 | #include "machvec_impl.h" |
36 | 36 | #include "pc873xx.h" | |
37 | 37 | ||
38 | /* Note mask bit is true for DISABLED irqs. */ | 38 | /* Note mask bit is true for DISABLED irqs. */ |
39 | static unsigned long cached_irq_mask = ~0UL; | 39 | static unsigned long cached_irq_mask = ~0UL; |
@@ -236,17 +236,30 @@ cabriolet_map_irq(struct pci_dev *dev, u8 slot, u8 pin) | |||
236 | } | 236 | } |
237 | 237 | ||
238 | static inline void __init | 238 | static inline void __init |
239 | cabriolet_enable_ide(void) | ||
240 | { | ||
241 | if (pc873xx_probe() == -1) { | ||
242 | printk(KERN_ERR "Probing for PC873xx Super IO chip failed.\n"); | ||
243 | } else { | ||
244 | printk(KERN_INFO "Found %s Super IO chip at 0x%x\n", | ||
245 | pc873xx_get_model(), pc873xx_get_base()); | ||
246 | |||
247 | pc873xx_enable_ide(); | ||
248 | } | ||
249 | } | ||
250 | |||
251 | static inline void __init | ||
239 | cabriolet_init_pci(void) | 252 | cabriolet_init_pci(void) |
240 | { | 253 | { |
241 | common_init_pci(); | 254 | common_init_pci(); |
242 | ns87312_enable_ide(0x398); | 255 | cabriolet_enable_ide(); |
243 | } | 256 | } |
244 | 257 | ||
245 | static inline void __init | 258 | static inline void __init |
246 | cia_cab_init_pci(void) | 259 | cia_cab_init_pci(void) |
247 | { | 260 | { |
248 | cia_init_pci(); | 261 | cia_init_pci(); |
249 | ns87312_enable_ide(0x398); | 262 | cabriolet_enable_ide(); |
250 | } | 263 | } |
251 | 264 | ||
252 | /* | 265 | /* |
diff --git a/arch/alpha/kernel/sys_takara.c b/arch/alpha/kernel/sys_takara.c index 230464885b5..4da596b6adb 100644 --- a/arch/alpha/kernel/sys_takara.c +++ b/arch/alpha/kernel/sys_takara.c | |||
@@ -29,7 +29,7 @@ | |||
29 | #include "irq_impl.h" | 29 | #include "irq_impl.h" |
30 | #include "pci_impl.h" | 30 | #include "pci_impl.h" |
31 | #include "machvec_impl.h" | 31 | #include "machvec_impl.h" |
32 | 32 | #include "pc873xx.h" | |
33 | 33 | ||
34 | /* Note mask bit is true for DISABLED irqs. */ | 34 | /* Note mask bit is true for DISABLED irqs. */ |
35 | static unsigned long cached_irq_mask[2] = { -1, -1 }; | 35 | static unsigned long cached_irq_mask[2] = { -1, -1 }; |
@@ -264,7 +264,14 @@ takara_init_pci(void) | |||
264 | alpha_mv.pci_map_irq = takara_map_irq_srm; | 264 | alpha_mv.pci_map_irq = takara_map_irq_srm; |
265 | 265 | ||
266 | cia_init_pci(); | 266 | cia_init_pci(); |
267 | ns87312_enable_ide(0x26e); | 267 | |
268 | if (pc873xx_probe() == -1) { | ||
269 | printk(KERN_ERR "Probing for PC873xx Super IO chip failed.\n"); | ||
270 | } else { | ||
271 | printk(KERN_INFO "Found %s Super IO chip at 0x%x\n", | ||
272 | pc873xx_get_model(), pc873xx_get_base()); | ||
273 | pc873xx_enable_ide(); | ||
274 | } | ||
268 | } | 275 | } |
269 | 276 | ||
270 | 277 | ||
diff --git a/arch/alpha/kernel/systbls.S b/arch/alpha/kernel/systbls.S index 09acb786e72..a6a1de9db16 100644 --- a/arch/alpha/kernel/systbls.S +++ b/arch/alpha/kernel/systbls.S | |||
@@ -58,7 +58,7 @@ sys_call_table: | |||
58 | .quad sys_open /* 45 */ | 58 | .quad sys_open /* 45 */ |
59 | .quad alpha_ni_syscall | 59 | .quad alpha_ni_syscall |
60 | .quad sys_getxgid | 60 | .quad sys_getxgid |
61 | .quad osf_sigprocmask | 61 | .quad sys_osf_sigprocmask |
62 | .quad alpha_ni_syscall | 62 | .quad alpha_ni_syscall |
63 | .quad alpha_ni_syscall /* 50 */ | 63 | .quad alpha_ni_syscall /* 50 */ |
64 | .quad sys_acct | 64 | .quad sys_acct |
@@ -512,6 +512,9 @@ sys_call_table: | |||
512 | .quad sys_pwritev | 512 | .quad sys_pwritev |
513 | .quad sys_rt_tgsigqueueinfo | 513 | .quad sys_rt_tgsigqueueinfo |
514 | .quad sys_perf_event_open | 514 | .quad sys_perf_event_open |
515 | .quad sys_fanotify_init | ||
516 | .quad sys_fanotify_mark /* 495 */ | ||
517 | .quad sys_prlimit64 | ||
515 | 518 | ||
516 | .size sys_call_table, . - sys_call_table | 519 | .size sys_call_table, . - sys_call_table |
517 | .type sys_call_table, @object | 520 | .type sys_call_table, @object |
diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c index eacceb26d9c..396af1799ea 100644 --- a/arch/alpha/kernel/time.c +++ b/arch/alpha/kernel/time.c | |||
@@ -191,16 +191,16 @@ irqreturn_t timer_interrupt(int irq, void *dev) | |||
191 | 191 | ||
192 | write_sequnlock(&xtime_lock); | 192 | write_sequnlock(&xtime_lock); |
193 | 193 | ||
194 | #ifndef CONFIG_SMP | ||
195 | while (nticks--) | ||
196 | update_process_times(user_mode(get_irq_regs())); | ||
197 | #endif | ||
198 | |||
199 | if (test_perf_event_pending()) { | 194 | if (test_perf_event_pending()) { |
200 | clear_perf_event_pending(); | 195 | clear_perf_event_pending(); |
201 | perf_event_do_pending(); | 196 | perf_event_do_pending(); |
202 | } | 197 | } |
203 | 198 | ||
199 | #ifndef CONFIG_SMP | ||
200 | while (nticks--) | ||
201 | update_process_times(user_mode(get_irq_regs())); | ||
202 | #endif | ||
203 | |||
204 | return IRQ_HANDLED; | 204 | return IRQ_HANDLED; |
205 | } | 205 | } |
206 | 206 | ||
diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c index b14f015008a..0414e021a91 100644 --- a/arch/alpha/kernel/traps.c +++ b/arch/alpha/kernel/traps.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/sched.h> | 13 | #include <linux/sched.h> |
14 | #include <linux/tty.h> | 14 | #include <linux/tty.h> |
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/smp_lock.h> | ||
17 | #include <linux/module.h> | 16 | #include <linux/module.h> |
18 | #include <linux/init.h> | 17 | #include <linux/init.h> |
19 | #include <linux/kallsyms.h> | 18 | #include <linux/kallsyms.h> |
@@ -623,7 +622,6 @@ do_entUna(void * va, unsigned long opcode, unsigned long reg, | |||
623 | return; | 622 | return; |
624 | } | 623 | } |
625 | 624 | ||
626 | lock_kernel(); | ||
627 | printk("Bad unaligned kernel access at %016lx: %p %lx %lu\n", | 625 | printk("Bad unaligned kernel access at %016lx: %p %lx %lu\n", |
628 | pc, va, opcode, reg); | 626 | pc, va, opcode, reg); |
629 | do_exit(SIGSEGV); | 627 | do_exit(SIGSEGV); |
@@ -646,7 +644,6 @@ got_exception: | |||
646 | * Yikes! No one to forward the exception to. | 644 | * Yikes! No one to forward the exception to. |
647 | * Since the registers are in a weird format, dump them ourselves. | 645 | * Since the registers are in a weird format, dump them ourselves. |
648 | */ | 646 | */ |
649 | lock_kernel(); | ||
650 | 647 | ||
651 | printk("%s(%d): unhandled unaligned exception\n", | 648 | printk("%s(%d): unhandled unaligned exception\n", |
652 | current->comm, task_pid_nr(current)); | 649 | current->comm, task_pid_nr(current)); |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 92951103255..9c26ba7244f 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -271,7 +271,6 @@ config ARCH_AT91 | |||
271 | bool "Atmel AT91" | 271 | bool "Atmel AT91" |
272 | select ARCH_REQUIRE_GPIOLIB | 272 | select ARCH_REQUIRE_GPIOLIB |
273 | select HAVE_CLK | 273 | select HAVE_CLK |
274 | select ARCH_USES_GETTIMEOFFSET | ||
275 | help | 274 | help |
276 | This enables support for systems based on the Atmel AT91RM9200, | 275 | This enables support for systems based on the Atmel AT91RM9200, |
277 | AT91SAM9 and AT91CAP9 processors. | 276 | AT91SAM9 and AT91CAP9 processors. |
@@ -1051,6 +1050,32 @@ config ARM_ERRATA_460075 | |||
1051 | ACTLR register. Note that setting specific bits in the ACTLR register | 1050 | ACTLR register. Note that setting specific bits in the ACTLR register |
1052 | may not be available in non-secure mode. | 1051 | may not be available in non-secure mode. |
1053 | 1052 | ||
1053 | config ARM_ERRATA_742230 | ||
1054 | bool "ARM errata: DMB operation may be faulty" | ||
1055 | depends on CPU_V7 && SMP | ||
1056 | help | ||
1057 | This option enables the workaround for the 742230 Cortex-A9 | ||
1058 | (r1p0..r2p2) erratum. Under rare circumstances, a DMB instruction | ||
1059 | between two write operations may not ensure the correct visibility | ||
1060 | ordering of the two writes. This workaround sets a specific bit in | ||
1061 | the diagnostic register of the Cortex-A9 which causes the DMB | ||
1062 | instruction to behave as a DSB, ensuring the correct behaviour of | ||
1063 | the two writes. | ||
1064 | |||
1065 | config ARM_ERRATA_742231 | ||
1066 | bool "ARM errata: Incorrect hazard handling in the SCU may lead to data corruption" | ||
1067 | depends on CPU_V7 && SMP | ||
1068 | help | ||
1069 | This option enables the workaround for the 742231 Cortex-A9 | ||
1070 | (r2p0..r2p2) erratum. Under certain conditions, specific to the | ||
1071 | Cortex-A9 MPCore micro-architecture, two CPUs working in SMP mode, | ||
1072 | accessing some data located in the same cache line, may get corrupted | ||
1073 | data due to bad handling of the address hazard when the line gets | ||
1074 | replaced from one of the CPUs at the same time as another CPU is | ||
1075 | accessing it. This workaround sets specific bits in the diagnostic | ||
1076 | register of the Cortex-A9 which reduces the linefill issuing | ||
1077 | capabilities of the processor. | ||
1078 | |||
1054 | config PL310_ERRATA_588369 | 1079 | config PL310_ERRATA_588369 |
1055 | bool "Clean & Invalidate maintenance operations do not invalidate clean lines" | 1080 | bool "Clean & Invalidate maintenance operations do not invalidate clean lines" |
1056 | depends on CACHE_L2X0 && ARCH_OMAP4 | 1081 | depends on CACHE_L2X0 && ARCH_OMAP4 |
@@ -1076,6 +1101,20 @@ config ARM_ERRATA_720789 | |||
1076 | invalidated are not, resulting in an incoherency in the system page | 1101 | invalidated are not, resulting in an incoherency in the system page |
1077 | tables. The workaround changes the TLB flushing routines to invalidate | 1102 | tables. The workaround changes the TLB flushing routines to invalidate |
1078 | entries regardless of the ASID. | 1103 | entries regardless of the ASID. |
1104 | |||
1105 | config ARM_ERRATA_743622 | ||
1106 | bool "ARM errata: Faulty hazard checking in the Store Buffer may lead to data corruption" | ||
1107 | depends on CPU_V7 | ||
1108 | help | ||
1109 | This option enables the workaround for the 743622 Cortex-A9 | ||
1110 | (r2p0..r2p2) erratum. Under very rare conditions, a faulty | ||
1111 | optimisation in the Cortex-A9 Store Buffer may lead to data | ||
1112 | corruption. This workaround sets a specific bit in the diagnostic | ||
1113 | register of the Cortex-A9 which disables the Store Buffer | ||
1114 | optimisation, preventing the defect from occurring. This has no | ||
1115 | visible impact on the overall performance or power consumption of the | ||
1116 | processor. | ||
1117 | |||
1079 | endmenu | 1118 | endmenu |
1080 | 1119 | ||
1081 | source "arch/arm/common/Kconfig" | 1120 | source "arch/arm/common/Kconfig" |
@@ -1576,95 +1615,6 @@ config AUTO_ZRELADDR | |||
1576 | 0xf8000000. This assumes the zImage being placed in the first 128MB | 1615 | 0xf8000000. This assumes the zImage being placed in the first 128MB |
1577 | from start of memory. | 1616 | from start of memory. |
1578 | 1617 | ||
1579 | config ZRELADDR | ||
1580 | hex "Physical address of the decompressed kernel image" | ||
1581 | depends on !AUTO_ZRELADDR | ||
1582 | default 0x00008000 if ARCH_BCMRING ||\ | ||
1583 | ARCH_CNS3XXX ||\ | ||
1584 | ARCH_DOVE ||\ | ||
1585 | ARCH_EBSA110 ||\ | ||
1586 | ARCH_FOOTBRIDGE ||\ | ||
1587 | ARCH_INTEGRATOR ||\ | ||
1588 | ARCH_IOP13XX ||\ | ||
1589 | ARCH_IOP33X ||\ | ||
1590 | ARCH_IXP2000 ||\ | ||
1591 | ARCH_IXP23XX ||\ | ||
1592 | ARCH_IXP4XX ||\ | ||
1593 | ARCH_KIRKWOOD ||\ | ||
1594 | ARCH_KS8695 ||\ | ||
1595 | ARCH_LOKI ||\ | ||
1596 | ARCH_MMP ||\ | ||
1597 | ARCH_MV78XX0 ||\ | ||
1598 | ARCH_NOMADIK ||\ | ||
1599 | ARCH_NUC93X ||\ | ||
1600 | ARCH_NS9XXX ||\ | ||
1601 | ARCH_ORION5X ||\ | ||
1602 | ARCH_SPEAR3XX ||\ | ||
1603 | ARCH_SPEAR6XX ||\ | ||
1604 | ARCH_U8500 ||\ | ||
1605 | ARCH_VERSATILE ||\ | ||
1606 | ARCH_W90X900 | ||
1607 | default 0x08008000 if ARCH_MX1 ||\ | ||
1608 | ARCH_SHARK | ||
1609 | default 0x10008000 if ARCH_MSM ||\ | ||
1610 | ARCH_OMAP1 ||\ | ||
1611 | ARCH_RPC | ||
1612 | default 0x20008000 if ARCH_S5P6440 ||\ | ||
1613 | ARCH_S5P6442 ||\ | ||
1614 | ARCH_S5PC100 ||\ | ||
1615 | ARCH_S5PV210 | ||
1616 | default 0x30008000 if ARCH_S3C2410 ||\ | ||
1617 | ARCH_S3C2400 ||\ | ||
1618 | ARCH_S3C2412 ||\ | ||
1619 | ARCH_S3C2416 ||\ | ||
1620 | ARCH_S3C2440 ||\ | ||
1621 | ARCH_S3C2443 | ||
1622 | default 0x40008000 if ARCH_STMP378X ||\ | ||
1623 | ARCH_STMP37XX ||\ | ||
1624 | ARCH_SH7372 ||\ | ||
1625 | ARCH_SH7377 | ||
1626 | default 0x50008000 if ARCH_S3C64XX ||\ | ||
1627 | ARCH_SH7367 | ||
1628 | default 0x60008000 if ARCH_VEXPRESS | ||
1629 | default 0x80008000 if ARCH_MX25 ||\ | ||
1630 | ARCH_MX3 ||\ | ||
1631 | ARCH_NETX ||\ | ||
1632 | ARCH_OMAP2PLUS ||\ | ||
1633 | ARCH_PNX4008 | ||
1634 | default 0x90008000 if ARCH_MX5 ||\ | ||
1635 | ARCH_MX91231 | ||
1636 | default 0xa0008000 if ARCH_IOP32X ||\ | ||
1637 | ARCH_PXA ||\ | ||
1638 | MACH_MX27 | ||
1639 | default 0xc0008000 if ARCH_LH7A40X ||\ | ||
1640 | MACH_MX21 | ||
1641 | default 0xf0008000 if ARCH_AAEC2000 ||\ | ||
1642 | ARCH_L7200 | ||
1643 | default 0xc0028000 if ARCH_CLPS711X | ||
1644 | default 0x70008000 if ARCH_AT91 && (ARCH_AT91CAP9 || ARCH_AT91SAM9G45) | ||
1645 | default 0x20008000 if ARCH_AT91 && !(ARCH_AT91CAP9 || ARCH_AT91SAM9G45) | ||
1646 | default 0xc0008000 if ARCH_DAVINCI && ARCH_DAVINCI_DA8XX | ||
1647 | default 0x80008000 if ARCH_DAVINCI && !ARCH_DAVINCI_DA8XX | ||
1648 | default 0x00008000 if ARCH_EP93XX && EP93XX_SDCE3_SYNC_PHYS_OFFSET | ||
1649 | default 0xc0008000 if ARCH_EP93XX && EP93XX_SDCE0_PHYS_OFFSET | ||
1650 | default 0xd0008000 if ARCH_EP93XX && EP93XX_SDCE1_PHYS_OFFSET | ||
1651 | default 0xe0008000 if ARCH_EP93XX && EP93XX_SDCE2_PHYS_OFFSET | ||
1652 | default 0xf0008000 if ARCH_EP93XX && EP93XX_SDCE3_ASYNC_PHYS_OFFSET | ||
1653 | default 0x00008000 if ARCH_GEMINI && GEMINI_MEM_SWAP | ||
1654 | default 0x10008000 if ARCH_GEMINI && !GEMINI_MEM_SWAP | ||
1655 | default 0x70008000 if ARCH_REALVIEW && REALVIEW_HIGH_PHYS_OFFSET | ||
1656 | default 0x00008000 if ARCH_REALVIEW && !REALVIEW_HIGH_PHYS_OFFSET | ||
1657 | default 0xc0208000 if ARCH_SA1100 && SA1111 | ||
1658 | default 0xc0008000 if ARCH_SA1100 && !SA1111 | ||
1659 | default 0x30108000 if ARCH_S3C2410 && PM_H1940 | ||
1660 | default 0x28E08000 if ARCH_U300 && MACH_U300_SINGLE_RAM | ||
1661 | default 0x48008000 if ARCH_U300 && !MACH_U300_SINGLE_RAM | ||
1662 | help | ||
1663 | ZRELADDR is the physical address where the decompressed kernel | ||
1664 | image will be placed. ZRELADDR has to be specified when the | ||
1665 | assumption of AUTO_ZRELADDR is not valid, or when ZBOOT_ROM is | ||
1666 | selected. | ||
1667 | |||
1668 | endmenu | 1618 | endmenu |
1669 | 1619 | ||
1670 | menu "CPU Power Management" | 1620 | menu "CPU Power Management" |
diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile index f705213caa8..4a590f4113e 100644 --- a/arch/arm/boot/Makefile +++ b/arch/arm/boot/Makefile | |||
@@ -14,16 +14,18 @@ | |||
14 | MKIMAGE := $(srctree)/scripts/mkuboot.sh | 14 | MKIMAGE := $(srctree)/scripts/mkuboot.sh |
15 | 15 | ||
16 | ifneq ($(MACHINE),) | 16 | ifneq ($(MACHINE),) |
17 | -include $(srctree)/$(MACHINE)/Makefile.boot | 17 | include $(srctree)/$(MACHINE)/Makefile.boot |
18 | endif | 18 | endif |
19 | 19 | ||
20 | # Note: the following conditions must always be true: | 20 | # Note: the following conditions must always be true: |
21 | # ZRELADDR == virt_to_phys(PAGE_OFFSET + TEXT_OFFSET) | ||
21 | # PARAMS_PHYS must be within 4MB of ZRELADDR | 22 | # PARAMS_PHYS must be within 4MB of ZRELADDR |
22 | # INITRD_PHYS must be in RAM | 23 | # INITRD_PHYS must be in RAM |
24 | ZRELADDR := $(zreladdr-y) | ||
23 | PARAMS_PHYS := $(params_phys-y) | 25 | PARAMS_PHYS := $(params_phys-y) |
24 | INITRD_PHYS := $(initrd_phys-y) | 26 | INITRD_PHYS := $(initrd_phys-y) |
25 | 27 | ||
26 | export INITRD_PHYS PARAMS_PHYS | 28 | export ZRELADDR INITRD_PHYS PARAMS_PHYS |
27 | 29 | ||
28 | targets := Image zImage xipImage bootpImage uImage | 30 | targets := Image zImage xipImage bootpImage uImage |
29 | 31 | ||
@@ -65,7 +67,7 @@ quiet_cmd_uimage = UIMAGE $@ | |||
65 | ifeq ($(CONFIG_ZBOOT_ROM),y) | 67 | ifeq ($(CONFIG_ZBOOT_ROM),y) |
66 | $(obj)/uImage: LOADADDR=$(CONFIG_ZBOOT_ROM_TEXT) | 68 | $(obj)/uImage: LOADADDR=$(CONFIG_ZBOOT_ROM_TEXT) |
67 | else | 69 | else |
68 | $(obj)/uImage: LOADADDR=$(CONFIG_ZRELADDR) | 70 | $(obj)/uImage: LOADADDR=$(ZRELADDR) |
69 | endif | 71 | endif |
70 | 72 | ||
71 | ifeq ($(CONFIG_THUMB2_KERNEL),y) | 73 | ifeq ($(CONFIG_THUMB2_KERNEL),y) |
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index 68775e33476..65a7c1c588a 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile | |||
@@ -79,6 +79,10 @@ endif | |||
79 | EXTRA_CFLAGS := -fpic -fno-builtin | 79 | EXTRA_CFLAGS := -fpic -fno-builtin |
80 | EXTRA_AFLAGS := -Wa,-march=all | 80 | EXTRA_AFLAGS := -Wa,-march=all |
81 | 81 | ||
82 | # Supply ZRELADDR to the decompressor via a linker symbol. | ||
83 | ifneq ($(CONFIG_AUTO_ZRELADDR),y) | ||
84 | LDFLAGS_vmlinux := --defsym zreladdr=$(ZRELADDR) | ||
85 | endif | ||
82 | ifeq ($(CONFIG_CPU_ENDIAN_BE8),y) | 86 | ifeq ($(CONFIG_CPU_ENDIAN_BE8),y) |
83 | LDFLAGS_vmlinux += --be8 | 87 | LDFLAGS_vmlinux += --be8 |
84 | endif | 88 | endif |
@@ -112,5 +116,5 @@ CFLAGS_font.o := -Dstatic= | |||
112 | $(obj)/font.c: $(FONTC) | 116 | $(obj)/font.c: $(FONTC) |
113 | $(call cmd,shipped) | 117 | $(call cmd,shipped) |
114 | 118 | ||
115 | $(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/arm/boot/Makefile .config | 119 | $(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/arm/boot/Makefile $(KCONFIG_CONFIG) |
116 | @sed "$(SEDFLAGS)" < $< > $@ | 120 | @sed "$(SEDFLAGS)" < $< > $@ |
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 6af9907c3b5..6825c34646d 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S | |||
@@ -177,7 +177,7 @@ not_angel: | |||
177 | and r4, pc, #0xf8000000 | 177 | and r4, pc, #0xf8000000 |
178 | add r4, r4, #TEXT_OFFSET | 178 | add r4, r4, #TEXT_OFFSET |
179 | #else | 179 | #else |
180 | ldr r4, =CONFIG_ZRELADDR | 180 | ldr r4, =zreladdr |
181 | #endif | 181 | #endif |
182 | subs r0, r0, r1 @ calculate the delta offset | 182 | subs r0, r0, r1 @ calculate the delta offset |
183 | 183 | ||
diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c index 6c091356245..1bec96e8519 100644 --- a/arch/arm/common/it8152.c +++ b/arch/arm/common/it8152.c | |||
@@ -263,6 +263,22 @@ static int it8152_pci_platform_notify_remove(struct device *dev) | |||
263 | return 0; | 263 | return 0; |
264 | } | 264 | } |
265 | 265 | ||
266 | int dma_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size) | ||
267 | { | ||
268 | dev_dbg(dev, "%s: dma_addr %08x, size %08x\n", | ||
269 | __func__, dma_addr, size); | ||
270 | return (dev->bus == &pci_bus_type) && | ||
271 | ((dma_addr + size - PHYS_OFFSET) >= SZ_64M); | ||
272 | } | ||
273 | |||
274 | int dma_set_coherent_mask(struct device *dev, u64 mask) | ||
275 | { | ||
276 | if (mask >= PHYS_OFFSET + SZ_64M - 1) | ||
277 | return 0; | ||
278 | |||
279 | return -EIO; | ||
280 | } | ||
281 | |||
266 | int __init it8152_pci_setup(int nr, struct pci_sys_data *sys) | 282 | int __init it8152_pci_setup(int nr, struct pci_sys_data *sys) |
267 | { | 283 | { |
268 | it8152_io.start = IT8152_IO_BASE + 0x12000; | 284 | it8152_io.start = IT8152_IO_BASE + 0x12000; |
diff --git a/arch/arm/configs/omap_4430sdp_defconfig b/arch/arm/configs/omap_4430sdp_defconfig index 63e0c2d50f3..14c1e18c648 100644 --- a/arch/arm/configs/omap_4430sdp_defconfig +++ b/arch/arm/configs/omap_4430sdp_defconfig | |||
@@ -13,6 +13,9 @@ CONFIG_MODULE_SRCVERSION_ALL=y | |||
13 | # CONFIG_BLK_DEV_BSG is not set | 13 | # CONFIG_BLK_DEV_BSG is not set |
14 | CONFIG_ARCH_OMAP=y | 14 | CONFIG_ARCH_OMAP=y |
15 | CONFIG_ARCH_OMAP4=y | 15 | CONFIG_ARCH_OMAP4=y |
16 | # CONFIG_ARCH_OMAP2PLUS_TYPICAL is not set | ||
17 | # CONFIG_ARCH_OMAP2 is not set | ||
18 | # CONFIG_ARCH_OMAP3 is not set | ||
16 | # CONFIG_OMAP_MUX is not set | 19 | # CONFIG_OMAP_MUX is not set |
17 | CONFIG_OMAP_32K_TIMER=y | 20 | CONFIG_OMAP_32K_TIMER=y |
18 | CONFIG_OMAP_DM_TIMER=y | 21 | CONFIG_OMAP_DM_TIMER=y |
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h index c226fe10553..c568da7dcae 100644 --- a/arch/arm/include/asm/dma-mapping.h +++ b/arch/arm/include/asm/dma-mapping.h | |||
@@ -288,15 +288,7 @@ extern void dmabounce_unregister_dev(struct device *); | |||
288 | * DMA access and 1 if the buffer needs to be bounced. | 288 | * DMA access and 1 if the buffer needs to be bounced. |
289 | * | 289 | * |
290 | */ | 290 | */ |
291 | #ifdef CONFIG_SA1111 | ||
292 | extern int dma_needs_bounce(struct device*, dma_addr_t, size_t); | 291 | extern int dma_needs_bounce(struct device*, dma_addr_t, size_t); |
293 | #else | ||
294 | static inline int dma_needs_bounce(struct device *dev, dma_addr_t addr, | ||
295 | size_t size) | ||
296 | { | ||
297 | return 0; | ||
298 | } | ||
299 | #endif | ||
300 | 292 | ||
301 | /* | 293 | /* |
302 | * The DMA API, implemented by dmabounce.c. See below for descriptions. | 294 | * The DMA API, implemented by dmabounce.c. See below for descriptions. |
diff --git a/arch/arm/include/asm/perf_event.h b/arch/arm/include/asm/perf_event.h index 48837e6d888..b5799a3b711 100644 --- a/arch/arm/include/asm/perf_event.h +++ b/arch/arm/include/asm/perf_event.h | |||
@@ -17,7 +17,7 @@ | |||
17 | * counter interrupts are regular interrupts and not an NMI. This | 17 | * counter interrupts are regular interrupts and not an NMI. This |
18 | * means that when we receive the interrupt we can call | 18 | * means that when we receive the interrupt we can call |
19 | * perf_event_do_pending() that handles all of the work with | 19 | * perf_event_do_pending() that handles all of the work with |
20 | * interrupts enabled. | 20 | * interrupts disabled. |
21 | */ | 21 | */ |
22 | static inline void | 22 | static inline void |
23 | set_perf_event_pending(void) | 23 | set_perf_event_pending(void) |
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h index ab68cf1ef80..e90b167ea84 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h | |||
@@ -317,6 +317,10 @@ static inline pte_t pte_mkspecial(pte_t pte) { return pte; } | |||
317 | #ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE | 317 | #ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE |
318 | #define pgprot_dmacoherent(prot) \ | 318 | #define pgprot_dmacoherent(prot) \ |
319 | __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_BUFFERABLE) | 319 | __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_BUFFERABLE) |
320 | #define __HAVE_PHYS_MEM_ACCESS_PROT | ||
321 | struct file; | ||
322 | extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, | ||
323 | unsigned long size, pgprot_t vma_prot); | ||
320 | #else | 324 | #else |
321 | #define pgprot_dmacoherent(prot) \ | 325 | #define pgprot_dmacoherent(prot) \ |
322 | __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_UNCACHED) | 326 | __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_UNCACHED) |
diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h index d02cfb68348..c891eb76c0e 100644 --- a/arch/arm/include/asm/unistd.h +++ b/arch/arm/include/asm/unistd.h | |||
@@ -393,6 +393,9 @@ | |||
393 | #define __NR_perf_event_open (__NR_SYSCALL_BASE+364) | 393 | #define __NR_perf_event_open (__NR_SYSCALL_BASE+364) |
394 | #define __NR_recvmmsg (__NR_SYSCALL_BASE+365) | 394 | #define __NR_recvmmsg (__NR_SYSCALL_BASE+365) |
395 | #define __NR_accept4 (__NR_SYSCALL_BASE+366) | 395 | #define __NR_accept4 (__NR_SYSCALL_BASE+366) |
396 | #define __NR_fanotify_init (__NR_SYSCALL_BASE+367) | ||
397 | #define __NR_fanotify_mark (__NR_SYSCALL_BASE+368) | ||
398 | #define __NR_prlimit64 (__NR_SYSCALL_BASE+369) | ||
396 | 399 | ||
397 | /* | 400 | /* |
398 | * The following SWIs are ARM private. | 401 | * The following SWIs are ARM private. |
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index afeb71fa72c..5c26eccef99 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S | |||
@@ -376,6 +376,9 @@ | |||
376 | CALL(sys_perf_event_open) | 376 | CALL(sys_perf_event_open) |
377 | /* 365 */ CALL(sys_recvmmsg) | 377 | /* 365 */ CALL(sys_recvmmsg) |
378 | CALL(sys_accept4) | 378 | CALL(sys_accept4) |
379 | CALL(sys_fanotify_init) | ||
380 | CALL(sys_fanotify_mark) | ||
381 | CALL(sys_prlimit64) | ||
379 | #ifndef syscalls_counted | 382 | #ifndef syscalls_counted |
380 | .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls | 383 | .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls |
381 | #define syscalls_counted | 384 | #define syscalls_counted |
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index f05a35a5969..7885722bdf4 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S | |||
@@ -48,6 +48,8 @@ work_pending: | |||
48 | beq no_work_pending | 48 | beq no_work_pending |
49 | mov r0, sp @ 'regs' | 49 | mov r0, sp @ 'regs' |
50 | mov r2, why @ 'syscall' | 50 | mov r2, why @ 'syscall' |
51 | tst r1, #_TIF_SIGPENDING @ delivering a signal? | ||
52 | movne why, #0 @ prevent further restarts | ||
51 | bl do_notify_resume | 53 | bl do_notify_resume |
52 | b ret_slow_syscall @ Check work again | 54 | b ret_slow_syscall @ Check work again |
53 | 55 | ||
@@ -418,11 +420,13 @@ ENDPROC(sys_clone_wrapper) | |||
418 | 420 | ||
419 | sys_sigreturn_wrapper: | 421 | sys_sigreturn_wrapper: |
420 | add r0, sp, #S_OFF | 422 | add r0, sp, #S_OFF |
423 | mov why, #0 @ prevent syscall restart handling | ||
421 | b sys_sigreturn | 424 | b sys_sigreturn |
422 | ENDPROC(sys_sigreturn_wrapper) | 425 | ENDPROC(sys_sigreturn_wrapper) |
423 | 426 | ||
424 | sys_rt_sigreturn_wrapper: | 427 | sys_rt_sigreturn_wrapper: |
425 | add r0, sp, #S_OFF | 428 | add r0, sp, #S_OFF |
429 | mov why, #0 @ prevent syscall restart handling | ||
426 | b sys_rt_sigreturn | 430 | b sys_rt_sigreturn |
427 | ENDPROC(sys_rt_sigreturn_wrapper) | 431 | ENDPROC(sys_rt_sigreturn_wrapper) |
428 | 432 | ||
diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c index 56418f98cd0..33c7077174d 100644 --- a/arch/arm/kernel/etm.c +++ b/arch/arm/kernel/etm.c | |||
@@ -230,7 +230,7 @@ static void etm_dump(void) | |||
230 | etb_lock(t); | 230 | etb_lock(t); |
231 | } | 231 | } |
232 | 232 | ||
233 | static void sysrq_etm_dump(int key, struct tty_struct *tty) | 233 | static void sysrq_etm_dump(int key) |
234 | { | 234 | { |
235 | dev_dbg(tracer.dev, "Dumping ETB buffer\n"); | 235 | dev_dbg(tracer.dev, "Dumping ETB buffer\n"); |
236 | etm_dump(); | 236 | etm_dump(); |
diff --git a/arch/arm/kernel/kprobes-decode.c b/arch/arm/kernel/kprobes-decode.c index 8bccbfa693f..2c1f0050c9c 100644 --- a/arch/arm/kernel/kprobes-decode.c +++ b/arch/arm/kernel/kprobes-decode.c | |||
@@ -1162,11 +1162,12 @@ space_cccc_001x(kprobe_opcode_t insn, struct arch_specific_insn *asi) | |||
1162 | { | 1162 | { |
1163 | /* | 1163 | /* |
1164 | * MSR : cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx | 1164 | * MSR : cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx |
1165 | * Undef : cccc 0011 0x00 xxxx xxxx xxxx xxxx xxxx | 1165 | * Undef : cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx |
1166 | * ALU op with S bit and Rd == 15 : | 1166 | * ALU op with S bit and Rd == 15 : |
1167 | * cccc 001x xxx1 xxxx 1111 xxxx xxxx xxxx | 1167 | * cccc 001x xxx1 xxxx 1111 xxxx xxxx xxxx |
1168 | */ | 1168 | */ |
1169 | if ((insn & 0x0f900000) == 0x03200000 || /* MSR & Undef */ | 1169 | if ((insn & 0x0fb00000) == 0x03200000 || /* MSR */ |
1170 | (insn & 0x0ff00000) == 0x03400000 || /* Undef */ | ||
1170 | (insn & 0x0e10f000) == 0x0210f000) /* ALU s-bit, R15 */ | 1171 | (insn & 0x0e10f000) == 0x0210f000) /* ALU s-bit, R15 */ |
1171 | return INSN_REJECTED; | 1172 | return INSN_REJECTED; |
1172 | 1173 | ||
@@ -1177,7 +1178,7 @@ space_cccc_001x(kprobe_opcode_t insn, struct arch_specific_insn *asi) | |||
1177 | * *S (bit 20) updates condition codes | 1178 | * *S (bit 20) updates condition codes |
1178 | * ADC/SBC/RSC reads the C flag | 1179 | * ADC/SBC/RSC reads the C flag |
1179 | */ | 1180 | */ |
1180 | insn &= 0xfff00fff; /* Rn = r0, Rd = r0 */ | 1181 | insn &= 0xffff0fff; /* Rd = r0 */ |
1181 | asi->insn[0] = insn; | 1182 | asi->insn[0] = insn; |
1182 | asi->insn_handler = (insn & (1 << 20)) ? /* S-bit */ | 1183 | asi->insn_handler = (insn & (1 << 20)) ? /* S-bit */ |
1183 | emulate_alu_imm_rwflags : emulate_alu_imm_rflags; | 1184 | emulate_alu_imm_rwflags : emulate_alu_imm_rflags; |
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index 417c392ddf1..ecbb0288e5d 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c | |||
@@ -319,8 +319,8 @@ validate_event(struct cpu_hw_events *cpuc, | |||
319 | { | 319 | { |
320 | struct hw_perf_event fake_event = event->hw; | 320 | struct hw_perf_event fake_event = event->hw; |
321 | 321 | ||
322 | if (event->pmu && event->pmu != &pmu) | 322 | if (event->pmu != &pmu || event->state <= PERF_EVENT_STATE_OFF) |
323 | return 0; | 323 | return 1; |
324 | 324 | ||
325 | return armpmu->get_event_idx(cpuc, &fake_event) >= 0; | 325 | return armpmu->get_event_idx(cpuc, &fake_event) >= 0; |
326 | } | 326 | } |
@@ -1041,8 +1041,8 @@ armv6pmu_handle_irq(int irq_num, | |||
1041 | /* | 1041 | /* |
1042 | * Handle the pending perf events. | 1042 | * Handle the pending perf events. |
1043 | * | 1043 | * |
1044 | * Note: this call *must* be run with interrupts enabled. For | 1044 | * Note: this call *must* be run with interrupts disabled. For |
1045 | * platforms that can have the PMU interrupts raised as a PMI, this | 1045 | * platforms that can have the PMU interrupts raised as an NMI, this |
1046 | * will not work. | 1046 | * will not work. |
1047 | */ | 1047 | */ |
1048 | perf_event_do_pending(); | 1048 | perf_event_do_pending(); |
@@ -2017,8 +2017,8 @@ static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev) | |||
2017 | /* | 2017 | /* |
2018 | * Handle the pending perf events. | 2018 | * Handle the pending perf events. |
2019 | * | 2019 | * |
2020 | * Note: this call *must* be run with interrupts enabled. For | 2020 | * Note: this call *must* be run with interrupts disabled. For |
2021 | * platforms that can have the PMU interrupts raised as a PMI, this | 2021 | * platforms that can have the PMU interrupts raised as an NMI, this |
2022 | * will not work. | 2022 | * will not work. |
2023 | */ | 2023 | */ |
2024 | perf_event_do_pending(); | 2024 | perf_event_do_pending(); |
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index 753c0d31a3d..c67b47f1c0f 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c | |||
@@ -121,8 +121,8 @@ static struct clk ssc1_clk = { | |||
121 | .pmc_mask = 1 << AT91SAM9G45_ID_SSC1, | 121 | .pmc_mask = 1 << AT91SAM9G45_ID_SSC1, |
122 | .type = CLK_TYPE_PERIPHERAL, | 122 | .type = CLK_TYPE_PERIPHERAL, |
123 | }; | 123 | }; |
124 | static struct clk tcb_clk = { | 124 | static struct clk tcb0_clk = { |
125 | .name = "tcb_clk", | 125 | .name = "tcb0_clk", |
126 | .pmc_mask = 1 << AT91SAM9G45_ID_TCB, | 126 | .pmc_mask = 1 << AT91SAM9G45_ID_TCB, |
127 | .type = CLK_TYPE_PERIPHERAL, | 127 | .type = CLK_TYPE_PERIPHERAL, |
128 | }; | 128 | }; |
@@ -192,6 +192,14 @@ static struct clk ohci_clk = { | |||
192 | .parent = &uhphs_clk, | 192 | .parent = &uhphs_clk, |
193 | }; | 193 | }; |
194 | 194 | ||
195 | /* One additional fake clock for second TC block */ | ||
196 | static struct clk tcb1_clk = { | ||
197 | .name = "tcb1_clk", | ||
198 | .pmc_mask = 0, | ||
199 | .type = CLK_TYPE_PERIPHERAL, | ||
200 | .parent = &tcb0_clk, | ||
201 | }; | ||
202 | |||
195 | static struct clk *periph_clocks[] __initdata = { | 203 | static struct clk *periph_clocks[] __initdata = { |
196 | &pioA_clk, | 204 | &pioA_clk, |
197 | &pioB_clk, | 205 | &pioB_clk, |
@@ -208,7 +216,7 @@ static struct clk *periph_clocks[] __initdata = { | |||
208 | &spi1_clk, | 216 | &spi1_clk, |
209 | &ssc0_clk, | 217 | &ssc0_clk, |
210 | &ssc1_clk, | 218 | &ssc1_clk, |
211 | &tcb_clk, | 219 | &tcb0_clk, |
212 | &pwm_clk, | 220 | &pwm_clk, |
213 | &tsc_clk, | 221 | &tsc_clk, |
214 | &dma_clk, | 222 | &dma_clk, |
@@ -221,6 +229,7 @@ static struct clk *periph_clocks[] __initdata = { | |||
221 | &mmc1_clk, | 229 | &mmc1_clk, |
222 | // irq0 | 230 | // irq0 |
223 | &ohci_clk, | 231 | &ohci_clk, |
232 | &tcb1_clk, | ||
224 | }; | 233 | }; |
225 | 234 | ||
226 | /* | 235 | /* |
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index 809114d5a5a..1276babf84d 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c | |||
@@ -46,7 +46,7 @@ static struct resource hdmac_resources[] = { | |||
46 | .end = AT91_BASE_SYS + AT91_DMA + SZ_512 - 1, | 46 | .end = AT91_BASE_SYS + AT91_DMA + SZ_512 - 1, |
47 | .flags = IORESOURCE_MEM, | 47 | .flags = IORESOURCE_MEM, |
48 | }, | 48 | }, |
49 | [2] = { | 49 | [1] = { |
50 | .start = AT91SAM9G45_ID_DMA, | 50 | .start = AT91SAM9G45_ID_DMA, |
51 | .end = AT91SAM9G45_ID_DMA, | 51 | .end = AT91SAM9G45_ID_DMA, |
52 | .flags = IORESOURCE_IRQ, | 52 | .flags = IORESOURCE_IRQ, |
@@ -426,7 +426,7 @@ static struct i2c_gpio_platform_data pdata_i2c0 = { | |||
426 | .sda_is_open_drain = 1, | 426 | .sda_is_open_drain = 1, |
427 | .scl_pin = AT91_PIN_PA21, | 427 | .scl_pin = AT91_PIN_PA21, |
428 | .scl_is_open_drain = 1, | 428 | .scl_is_open_drain = 1, |
429 | .udelay = 2, /* ~100 kHz */ | 429 | .udelay = 5, /* ~100 kHz */ |
430 | }; | 430 | }; |
431 | 431 | ||
432 | static struct platform_device at91sam9g45_twi0_device = { | 432 | static struct platform_device at91sam9g45_twi0_device = { |
@@ -440,7 +440,7 @@ static struct i2c_gpio_platform_data pdata_i2c1 = { | |||
440 | .sda_is_open_drain = 1, | 440 | .sda_is_open_drain = 1, |
441 | .scl_pin = AT91_PIN_PB11, | 441 | .scl_pin = AT91_PIN_PB11, |
442 | .scl_is_open_drain = 1, | 442 | .scl_is_open_drain = 1, |
443 | .udelay = 2, /* ~100 kHz */ | 443 | .udelay = 5, /* ~100 kHz */ |
444 | }; | 444 | }; |
445 | 445 | ||
446 | static struct platform_device at91sam9g45_twi1_device = { | 446 | static struct platform_device at91sam9g45_twi1_device = { |
@@ -835,9 +835,9 @@ static struct platform_device at91sam9g45_tcb1_device = { | |||
835 | static void __init at91_add_device_tc(void) | 835 | static void __init at91_add_device_tc(void) |
836 | { | 836 | { |
837 | /* this chip has one clock and irq for all six TC channels */ | 837 | /* this chip has one clock and irq for all six TC channels */ |
838 | at91_clock_associate("tcb_clk", &at91sam9g45_tcb0_device.dev, "t0_clk"); | 838 | at91_clock_associate("tcb0_clk", &at91sam9g45_tcb0_device.dev, "t0_clk"); |
839 | platform_device_register(&at91sam9g45_tcb0_device); | 839 | platform_device_register(&at91sam9g45_tcb0_device); |
840 | at91_clock_associate("tcb_clk", &at91sam9g45_tcb1_device.dev, "t0_clk"); | 840 | at91_clock_associate("tcb1_clk", &at91sam9g45_tcb1_device.dev, "t0_clk"); |
841 | platform_device_register(&at91sam9g45_tcb1_device); | 841 | platform_device_register(&at91sam9g45_tcb1_device); |
842 | } | 842 | } |
843 | #else | 843 | #else |
diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c index c4c8865d52d..65eb0943194 100644 --- a/arch/arm/mach-at91/board-sam9261ek.c +++ b/arch/arm/mach-at91/board-sam9261ek.c | |||
@@ -93,11 +93,12 @@ static struct resource dm9000_resource[] = { | |||
93 | .start = AT91_PIN_PC11, | 93 | .start = AT91_PIN_PC11, |
94 | .end = AT91_PIN_PC11, | 94 | .end = AT91_PIN_PC11, |
95 | .flags = IORESOURCE_IRQ | 95 | .flags = IORESOURCE_IRQ |
96 | | IORESOURCE_IRQ_LOWEDGE | IORESOURCE_IRQ_HIGHEDGE, | ||
96 | } | 97 | } |
97 | }; | 98 | }; |
98 | 99 | ||
99 | static struct dm9000_plat_data dm9000_platdata = { | 100 | static struct dm9000_plat_data dm9000_platdata = { |
100 | .flags = DM9000_PLATF_16BITONLY, | 101 | .flags = DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM, |
101 | }; | 102 | }; |
102 | 103 | ||
103 | static struct platform_device dm9000_device = { | 104 | static struct platform_device dm9000_device = { |
@@ -168,17 +169,6 @@ static struct at91_udc_data __initdata ek_udc_data = { | |||
168 | 169 | ||
169 | 170 | ||
170 | /* | 171 | /* |
171 | * MCI (SD/MMC) | ||
172 | */ | ||
173 | static struct at91_mmc_data __initdata ek_mmc_data = { | ||
174 | .wire4 = 1, | ||
175 | // .det_pin = ... not connected | ||
176 | // .wp_pin = ... not connected | ||
177 | // .vcc_pin = ... not connected | ||
178 | }; | ||
179 | |||
180 | |||
181 | /* | ||
182 | * NAND flash | 172 | * NAND flash |
183 | */ | 173 | */ |
184 | static struct mtd_partition __initdata ek_nand_partition[] = { | 174 | static struct mtd_partition __initdata ek_nand_partition[] = { |
@@ -246,6 +236,10 @@ static void __init ek_add_device_nand(void) | |||
246 | at91_add_device_nand(&ek_nand_data); | 236 | at91_add_device_nand(&ek_nand_data); |
247 | } | 237 | } |
248 | 238 | ||
239 | /* | ||
240 | * SPI related devices | ||
241 | */ | ||
242 | #if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) | ||
249 | 243 | ||
250 | /* | 244 | /* |
251 | * ADS7846 Touchscreen | 245 | * ADS7846 Touchscreen |
@@ -356,6 +350,19 @@ static struct spi_board_info ek_spi_devices[] = { | |||
356 | #endif | 350 | #endif |
357 | }; | 351 | }; |
358 | 352 | ||
353 | #else /* CONFIG_SPI_ATMEL_* */ | ||
354 | /* spi0 and mmc/sd share the same PIO pins: cannot be used at the same time */ | ||
355 | |||
356 | /* | ||
357 | * MCI (SD/MMC) | ||
358 | * det_pin, wp_pin and vcc_pin are not connected | ||
359 | */ | ||
360 | static struct at91_mmc_data __initdata ek_mmc_data = { | ||
361 | .wire4 = 1, | ||
362 | }; | ||
363 | |||
364 | #endif /* CONFIG_SPI_ATMEL_* */ | ||
365 | |||
359 | 366 | ||
360 | /* | 367 | /* |
361 | * LCD Controller | 368 | * LCD Controller |
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c index 7f7da439341..7525cee3983 100644 --- a/arch/arm/mach-at91/clock.c +++ b/arch/arm/mach-at91/clock.c | |||
@@ -501,7 +501,8 @@ postcore_initcall(at91_clk_debugfs_init); | |||
501 | int __init clk_register(struct clk *clk) | 501 | int __init clk_register(struct clk *clk) |
502 | { | 502 | { |
503 | if (clk_is_peripheral(clk)) { | 503 | if (clk_is_peripheral(clk)) { |
504 | clk->parent = &mck; | 504 | if (!clk->parent) |
505 | clk->parent = &mck; | ||
505 | clk->mode = pmc_periph_mode; | 506 | clk->mode = pmc_periph_mode; |
506 | list_add_tail(&clk->node, &clocks); | 507 | list_add_tail(&clk->node, &clocks); |
507 | } | 508 | } |
diff --git a/arch/arm/mach-at91/include/mach/system.h b/arch/arm/mach-at91/include/mach/system.h index c80e090b367..ee8db152592 100644 --- a/arch/arm/mach-at91/include/mach/system.h +++ b/arch/arm/mach-at91/include/mach/system.h | |||
@@ -28,17 +28,16 @@ | |||
28 | 28 | ||
29 | static inline void arch_idle(void) | 29 | static inline void arch_idle(void) |
30 | { | 30 | { |
31 | #ifndef CONFIG_DEBUG_KERNEL | ||
32 | /* | 31 | /* |
33 | * Disable the processor clock. The processor will be automatically | 32 | * Disable the processor clock. The processor will be automatically |
34 | * re-enabled by an interrupt or by a reset. | 33 | * re-enabled by an interrupt or by a reset. |
35 | */ | 34 | */ |
36 | at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK); | 35 | at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK); |
37 | #else | 36 | #ifndef CONFIG_CPU_ARM920T |
38 | /* | 37 | /* |
39 | * Set the processor (CP15) into 'Wait for Interrupt' mode. | 38 | * Set the processor (CP15) into 'Wait for Interrupt' mode. |
40 | * Unlike disabling the processor clock via the PMC (above) | 39 | * Post-RM9200 processors need this in conjunction with the above |
41 | * this allows the processor to be woken via JTAG. | 40 | * to save power when idle. |
42 | */ | 41 | */ |
43 | cpu_do_idle(); | 42 | cpu_do_idle(); |
44 | #endif | 43 | #endif |
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index 3d996b659ff..9be261beae7 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c | |||
@@ -769,8 +769,7 @@ static struct map_desc dm355_io_desc[] = { | |||
769 | .virtual = SRAM_VIRT, | 769 | .virtual = SRAM_VIRT, |
770 | .pfn = __phys_to_pfn(0x00010000), | 770 | .pfn = __phys_to_pfn(0x00010000), |
771 | .length = SZ_32K, | 771 | .length = SZ_32K, |
772 | /* MT_MEMORY_NONCACHED requires supersection alignment */ | 772 | .type = MT_MEMORY_NONCACHED, |
773 | .type = MT_DEVICE, | ||
774 | }, | 773 | }, |
775 | }; | 774 | }; |
776 | 775 | ||
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index 6b6f4c64370..7781e35daec 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c | |||
@@ -969,8 +969,7 @@ static struct map_desc dm365_io_desc[] = { | |||
969 | .virtual = SRAM_VIRT, | 969 | .virtual = SRAM_VIRT, |
970 | .pfn = __phys_to_pfn(0x00010000), | 970 | .pfn = __phys_to_pfn(0x00010000), |
971 | .length = SZ_32K, | 971 | .length = SZ_32K, |
972 | /* MT_MEMORY_NONCACHED requires supersection alignment */ | 972 | .type = MT_MEMORY_NONCACHED, |
973 | .type = MT_DEVICE, | ||
974 | }, | 973 | }, |
975 | }; | 974 | }; |
976 | 975 | ||
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 40fec315c99..5e5b0a7831f 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c | |||
@@ -653,8 +653,7 @@ static struct map_desc dm644x_io_desc[] = { | |||
653 | .virtual = SRAM_VIRT, | 653 | .virtual = SRAM_VIRT, |
654 | .pfn = __phys_to_pfn(0x00008000), | 654 | .pfn = __phys_to_pfn(0x00008000), |
655 | .length = SZ_16K, | 655 | .length = SZ_16K, |
656 | /* MT_MEMORY_NONCACHED requires supersection alignment */ | 656 | .type = MT_MEMORY_NONCACHED, |
657 | .type = MT_DEVICE, | ||
658 | }, | 657 | }, |
659 | }; | 658 | }; |
660 | 659 | ||
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index e4a3df1872a..26e8a9c7f50 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c | |||
@@ -737,8 +737,7 @@ static struct map_desc dm646x_io_desc[] = { | |||
737 | .virtual = SRAM_VIRT, | 737 | .virtual = SRAM_VIRT, |
738 | .pfn = __phys_to_pfn(0x00010000), | 738 | .pfn = __phys_to_pfn(0x00010000), |
739 | .length = SZ_32K, | 739 | .length = SZ_32K, |
740 | /* MT_MEMORY_NONCACHED requires supersection alignment */ | 740 | .type = MT_MEMORY_NONCACHED, |
741 | .type = MT_DEVICE, | ||
742 | }, | 741 | }, |
743 | }; | 742 | }; |
744 | 743 | ||
diff --git a/arch/arm/mach-dove/include/mach/io.h b/arch/arm/mach-dove/include/mach/io.h index 3b3e4721ce2..eb4936ff90a 100644 --- a/arch/arm/mach-dove/include/mach/io.h +++ b/arch/arm/mach-dove/include/mach/io.h | |||
@@ -13,8 +13,8 @@ | |||
13 | 13 | ||
14 | #define IO_SPACE_LIMIT 0xffffffff | 14 | #define IO_SPACE_LIMIT 0xffffffff |
15 | 15 | ||
16 | #define __io(a) ((void __iomem *)(((a) - DOVE_PCIE0_IO_PHYS_BASE) +\ | 16 | #define __io(a) ((void __iomem *)(((a) - DOVE_PCIE0_IO_BUS_BASE) + \ |
17 | DOVE_PCIE0_IO_VIRT_BASE)) | 17 | DOVE_PCIE0_IO_VIRT_BASE)) |
18 | #define __mem_pci(a) (a) | 18 | #define __mem_pci(a) (a) |
19 | 19 | ||
20 | #endif | 20 | #endif |
diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c index 8bf3cec98cf..4566bd1c866 100644 --- a/arch/arm/mach-ep93xx/clock.c +++ b/arch/arm/mach-ep93xx/clock.c | |||
@@ -560,4 +560,4 @@ static int __init ep93xx_clock_init(void) | |||
560 | clkdev_add_table(clocks, ARRAY_SIZE(clocks)); | 560 | clkdev_add_table(clocks, ARRAY_SIZE(clocks)); |
561 | return 0; | 561 | return 0; |
562 | } | 562 | } |
563 | arch_initcall(ep93xx_clock_init); | 563 | postcore_initcall(ep93xx_clock_init); |
diff --git a/arch/arm/mach-ep93xx/dma-m2p.c b/arch/arm/mach-ep93xx/dma-m2p.c index 8904ca4e2e2..a696d354b1f 100644 --- a/arch/arm/mach-ep93xx/dma-m2p.c +++ b/arch/arm/mach-ep93xx/dma-m2p.c | |||
@@ -276,7 +276,7 @@ static void channel_disable(struct m2p_channel *ch) | |||
276 | v &= ~(M2P_CONTROL_STALL_IRQ_EN | M2P_CONTROL_NFB_IRQ_EN); | 276 | v &= ~(M2P_CONTROL_STALL_IRQ_EN | M2P_CONTROL_NFB_IRQ_EN); |
277 | m2p_set_control(ch, v); | 277 | m2p_set_control(ch, v); |
278 | 278 | ||
279 | while (m2p_channel_state(ch) == STATE_ON) | 279 | while (m2p_channel_state(ch) >= STATE_ON) |
280 | cpu_relax(); | 280 | cpu_relax(); |
281 | 281 | ||
282 | m2p_set_control(ch, 0x0); | 282 | m2p_set_control(ch, 0x0); |
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index c5c0369bb48..2f7e2728970 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig | |||
@@ -122,6 +122,7 @@ config MACH_CPUIMX27 | |||
122 | select IMX_HAVE_PLATFORM_IMX_I2C | 122 | select IMX_HAVE_PLATFORM_IMX_I2C |
123 | select IMX_HAVE_PLATFORM_IMX_UART | 123 | select IMX_HAVE_PLATFORM_IMX_UART |
124 | select IMX_HAVE_PLATFORM_MXC_NAND | 124 | select IMX_HAVE_PLATFORM_MXC_NAND |
125 | select MXC_ULPI if USB_ULPI | ||
125 | help | 126 | help |
126 | Include support for Eukrea CPUIMX27 platform. This includes | 127 | Include support for Eukrea CPUIMX27 platform. This includes |
127 | specific configurations for the module and its peripherals. | 128 | specific configurations for the module and its peripherals. |
diff --git a/arch/arm/mach-imx/mach-cpuimx27.c b/arch/arm/mach-imx/mach-cpuimx27.c index 575ff1ae85a..6830afd1d2b 100644 --- a/arch/arm/mach-imx/mach-cpuimx27.c +++ b/arch/arm/mach-imx/mach-cpuimx27.c | |||
@@ -259,7 +259,7 @@ static void __init eukrea_cpuimx27_init(void) | |||
259 | i2c_register_board_info(0, eukrea_cpuimx27_i2c_devices, | 259 | i2c_register_board_info(0, eukrea_cpuimx27_i2c_devices, |
260 | ARRAY_SIZE(eukrea_cpuimx27_i2c_devices)); | 260 | ARRAY_SIZE(eukrea_cpuimx27_i2c_devices)); |
261 | 261 | ||
262 | imx27_add_i2c_imx1(&cpuimx27_i2c1_data); | 262 | imx27_add_i2c_imx0(&cpuimx27_i2c1_data); |
263 | 263 | ||
264 | platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); | 264 | platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); |
265 | 265 | ||
@@ -279,13 +279,13 @@ static void __init eukrea_cpuimx27_init(void) | |||
279 | #if defined(CONFIG_USB_ULPI) | 279 | #if defined(CONFIG_USB_ULPI) |
280 | if (otg_mode_host) { | 280 | if (otg_mode_host) { |
281 | otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, | 281 | otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, |
282 | USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); | 282 | ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT); |
283 | 283 | ||
284 | mxc_register_device(&mxc_otg_host, &otg_pdata); | 284 | mxc_register_device(&mxc_otg_host, &otg_pdata); |
285 | } | 285 | } |
286 | 286 | ||
287 | usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, | 287 | usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, |
288 | USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); | 288 | ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT); |
289 | 289 | ||
290 | mxc_register_device(&mxc_usbh2, &usbh2_pdata); | 290 | mxc_register_device(&mxc_usbh2, &usbh2_pdata); |
291 | #endif | 291 | #endif |
diff --git a/arch/arm/mach-imx/mach-pca100.c b/arch/arm/mach-imx/mach-pca100.c index a389d1148f1..23c9e1f37b9 100644 --- a/arch/arm/mach-imx/mach-pca100.c +++ b/arch/arm/mach-imx/mach-pca100.c | |||
@@ -419,13 +419,13 @@ static void __init pca100_init(void) | |||
419 | #if defined(CONFIG_USB_ULPI) | 419 | #if defined(CONFIG_USB_ULPI) |
420 | if (otg_mode_host) { | 420 | if (otg_mode_host) { |
421 | otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, | 421 | otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, |
422 | USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); | 422 | ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT); |
423 | 423 | ||
424 | mxc_register_device(&mxc_otg_host, &otg_pdata); | 424 | mxc_register_device(&mxc_otg_host, &otg_pdata); |
425 | } | 425 | } |
426 | 426 | ||
427 | usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, | 427 | usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, |
428 | USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); | 428 | ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT); |
429 | 429 | ||
430 | mxc_register_device(&mxc_usbh2, &usbh2_pdata); | 430 | mxc_register_device(&mxc_usbh2, &usbh2_pdata); |
431 | #endif | 431 | #endif |
diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c index 61cd4d64b98..24498a932ba 100644 --- a/arch/arm/mach-ixp4xx/common-pci.c +++ b/arch/arm/mach-ixp4xx/common-pci.c | |||
@@ -503,6 +503,14 @@ struct pci_bus * __devinit ixp4xx_scan_bus(int nr, struct pci_sys_data *sys) | |||
503 | return pci_scan_bus(sys->busnr, &ixp4xx_ops, sys); | 503 | return pci_scan_bus(sys->busnr, &ixp4xx_ops, sys); |
504 | } | 504 | } |
505 | 505 | ||
506 | int dma_set_coherent_mask(struct device *dev, u64 mask) | ||
507 | { | ||
508 | if (mask >= SZ_64M - 1) | ||
509 | return 0; | ||
510 | |||
511 | return -EIO; | ||
512 | } | ||
513 | |||
506 | EXPORT_SYMBOL(ixp4xx_pci_read); | 514 | EXPORT_SYMBOL(ixp4xx_pci_read); |
507 | EXPORT_SYMBOL(ixp4xx_pci_write); | 515 | EXPORT_SYMBOL(ixp4xx_pci_write); |
508 | 516 | ||
diff --git a/arch/arm/mach-ixp4xx/include/mach/hardware.h b/arch/arm/mach-ixp4xx/include/mach/hardware.h index f91ca6d4fbe..8138371c406 100644 --- a/arch/arm/mach-ixp4xx/include/mach/hardware.h +++ b/arch/arm/mach-ixp4xx/include/mach/hardware.h | |||
@@ -26,6 +26,8 @@ | |||
26 | #define PCIBIOS_MAX_MEM 0x4BFFFFFF | 26 | #define PCIBIOS_MAX_MEM 0x4BFFFFFF |
27 | #endif | 27 | #endif |
28 | 28 | ||
29 | #define ARCH_HAS_DMA_SET_COHERENT_MASK | ||
30 | |||
29 | #define pcibios_assign_all_busses() 1 | 31 | #define pcibios_assign_all_busses() 1 |
30 | 32 | ||
31 | /* Register locations and bits */ | 33 | /* Register locations and bits */ |
diff --git a/arch/arm/mach-kirkwood/include/mach/kirkwood.h b/arch/arm/mach-kirkwood/include/mach/kirkwood.h index 93fc2ec95e7..6e924b39891 100644 --- a/arch/arm/mach-kirkwood/include/mach/kirkwood.h +++ b/arch/arm/mach-kirkwood/include/mach/kirkwood.h | |||
@@ -38,7 +38,7 @@ | |||
38 | 38 | ||
39 | #define KIRKWOOD_PCIE1_IO_PHYS_BASE 0xf3000000 | 39 | #define KIRKWOOD_PCIE1_IO_PHYS_BASE 0xf3000000 |
40 | #define KIRKWOOD_PCIE1_IO_VIRT_BASE 0xfef00000 | 40 | #define KIRKWOOD_PCIE1_IO_VIRT_BASE 0xfef00000 |
41 | #define KIRKWOOD_PCIE1_IO_BUS_BASE 0x00000000 | 41 | #define KIRKWOOD_PCIE1_IO_BUS_BASE 0x00100000 |
42 | #define KIRKWOOD_PCIE1_IO_SIZE SZ_1M | 42 | #define KIRKWOOD_PCIE1_IO_SIZE SZ_1M |
43 | 43 | ||
44 | #define KIRKWOOD_PCIE_IO_PHYS_BASE 0xf2000000 | 44 | #define KIRKWOOD_PCIE_IO_PHYS_BASE 0xf2000000 |
diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c index 55e7f00836b..513ad3102d7 100644 --- a/arch/arm/mach-kirkwood/pcie.c +++ b/arch/arm/mach-kirkwood/pcie.c | |||
@@ -117,7 +117,7 @@ static void __init pcie0_ioresources_init(struct pcie_port *pp) | |||
117 | * IORESOURCE_IO | 117 | * IORESOURCE_IO |
118 | */ | 118 | */ |
119 | pp->res[0].name = "PCIe 0 I/O Space"; | 119 | pp->res[0].name = "PCIe 0 I/O Space"; |
120 | pp->res[0].start = KIRKWOOD_PCIE_IO_PHYS_BASE; | 120 | pp->res[0].start = KIRKWOOD_PCIE_IO_BUS_BASE; |
121 | pp->res[0].end = pp->res[0].start + KIRKWOOD_PCIE_IO_SIZE - 1; | 121 | pp->res[0].end = pp->res[0].start + KIRKWOOD_PCIE_IO_SIZE - 1; |
122 | pp->res[0].flags = IORESOURCE_IO; | 122 | pp->res[0].flags = IORESOURCE_IO; |
123 | 123 | ||
@@ -139,7 +139,7 @@ static void __init pcie1_ioresources_init(struct pcie_port *pp) | |||
139 | * IORESOURCE_IO | 139 | * IORESOURCE_IO |
140 | */ | 140 | */ |
141 | pp->res[0].name = "PCIe 1 I/O Space"; | 141 | pp->res[0].name = "PCIe 1 I/O Space"; |
142 | pp->res[0].start = KIRKWOOD_PCIE1_IO_PHYS_BASE; | 142 | pp->res[0].start = KIRKWOOD_PCIE1_IO_BUS_BASE; |
143 | pp->res[0].end = pp->res[0].start + KIRKWOOD_PCIE1_IO_SIZE - 1; | 143 | pp->res[0].end = pp->res[0].start + KIRKWOOD_PCIE1_IO_SIZE - 1; |
144 | pp->res[0].flags = IORESOURCE_IO; | 144 | pp->res[0].flags = IORESOURCE_IO; |
145 | 145 | ||
diff --git a/arch/arm/mach-mmp/include/mach/system.h b/arch/arm/mach-mmp/include/mach/system.h index 4f5b0e0ce6c..1a8a25edb1b 100644 --- a/arch/arm/mach-mmp/include/mach/system.h +++ b/arch/arm/mach-mmp/include/mach/system.h | |||
@@ -9,6 +9,8 @@ | |||
9 | #ifndef __ASM_MACH_SYSTEM_H | 9 | #ifndef __ASM_MACH_SYSTEM_H |
10 | #define __ASM_MACH_SYSTEM_H | 10 | #define __ASM_MACH_SYSTEM_H |
11 | 11 | ||
12 | #include <mach/cputype.h> | ||
13 | |||
12 | static inline void arch_idle(void) | 14 | static inline void arch_idle(void) |
13 | { | 15 | { |
14 | cpu_do_idle(); | 16 | cpu_do_idle(); |
@@ -16,6 +18,9 @@ static inline void arch_idle(void) | |||
16 | 18 | ||
17 | static inline void arch_reset(char mode, const char *cmd) | 19 | static inline void arch_reset(char mode, const char *cmd) |
18 | { | 20 | { |
19 | cpu_reset(0); | 21 | if (cpu_is_pxa168()) |
22 | cpu_reset(0xffff0000); | ||
23 | else | ||
24 | cpu_reset(0); | ||
20 | } | 25 | } |
21 | #endif /* __ASM_MACH_SYSTEM_H */ | 26 | #endif /* __ASM_MACH_SYSTEM_H */ |
diff --git a/arch/arm/mach-mx25/eukrea_mbimxsd-baseboard.c b/arch/arm/mach-mx25/eukrea_mbimxsd-baseboard.c index 91931dcb068..4aaadc753d3 100644 --- a/arch/arm/mach-mx25/eukrea_mbimxsd-baseboard.c +++ b/arch/arm/mach-mx25/eukrea_mbimxsd-baseboard.c | |||
@@ -215,7 +215,7 @@ struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata = { | |||
215 | * Add platform devices present on this baseboard and init | 215 | * Add platform devices present on this baseboard and init |
216 | * them from CPU side as far as required to use them later on | 216 | * them from CPU side as far as required to use them later on |
217 | */ | 217 | */ |
218 | void __init eukrea_mbimxsd_baseboard_init(void) | 218 | void __init eukrea_mbimxsd25_baseboard_init(void) |
219 | { | 219 | { |
220 | if (mxc_iomux_v3_setup_multiple_pads(eukrea_mbimxsd_pads, | 220 | if (mxc_iomux_v3_setup_multiple_pads(eukrea_mbimxsd_pads, |
221 | ARRAY_SIZE(eukrea_mbimxsd_pads))) | 221 | ARRAY_SIZE(eukrea_mbimxsd_pads))) |
diff --git a/arch/arm/mach-mx25/mach-cpuimx25.c b/arch/arm/mach-mx25/mach-cpuimx25.c index 56b2e26d23b..e064bb3d691 100644 --- a/arch/arm/mach-mx25/mach-cpuimx25.c +++ b/arch/arm/mach-mx25/mach-cpuimx25.c | |||
@@ -138,7 +138,7 @@ static void __init eukrea_cpuimx25_init(void) | |||
138 | #if defined(CONFIG_USB_ULPI) | 138 | #if defined(CONFIG_USB_ULPI) |
139 | if (otg_mode_host) { | 139 | if (otg_mode_host) { |
140 | otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, | 140 | otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, |
141 | USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); | 141 | ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT); |
142 | 142 | ||
143 | mxc_register_device(&mxc_otg, &otg_pdata); | 143 | mxc_register_device(&mxc_otg, &otg_pdata); |
144 | } | 144 | } |
@@ -147,8 +147,8 @@ static void __init eukrea_cpuimx25_init(void) | |||
147 | if (!otg_mode_host) | 147 | if (!otg_mode_host) |
148 | mxc_register_device(&otg_udc_device, &otg_device_pdata); | 148 | mxc_register_device(&otg_udc_device, &otg_device_pdata); |
149 | 149 | ||
150 | #ifdef CONFIG_MACH_EUKREA_MBIMXSD_BASEBOARD | 150 | #ifdef CONFIG_MACH_EUKREA_MBIMXSD25_BASEBOARD |
151 | eukrea_mbimxsd_baseboard_init(); | 151 | eukrea_mbimxsd25_baseboard_init(); |
152 | #endif | 152 | #endif |
153 | } | 153 | } |
154 | 154 | ||
diff --git a/arch/arm/mach-mx3/clock-imx35.c b/arch/arm/mach-mx3/clock-imx35.c index d3af0fdf847..7a62e744a8b 100644 --- a/arch/arm/mach-mx3/clock-imx35.c +++ b/arch/arm/mach-mx3/clock-imx35.c | |||
@@ -155,7 +155,7 @@ static unsigned long get_rate_arm(void) | |||
155 | 155 | ||
156 | aad = &clk_consumer[(pdr0 >> 16) & 0xf]; | 156 | aad = &clk_consumer[(pdr0 >> 16) & 0xf]; |
157 | if (aad->sel) | 157 | if (aad->sel) |
158 | fref = fref * 2 / 3; | 158 | fref = fref * 3 / 4; |
159 | 159 | ||
160 | return fref / aad->arm; | 160 | return fref / aad->arm; |
161 | } | 161 | } |
@@ -164,7 +164,7 @@ static unsigned long get_rate_ahb(struct clk *clk) | |||
164 | { | 164 | { |
165 | unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0); | 165 | unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0); |
166 | struct arm_ahb_div *aad; | 166 | struct arm_ahb_div *aad; |
167 | unsigned long fref = get_rate_mpll(); | 167 | unsigned long fref = get_rate_arm(); |
168 | 168 | ||
169 | aad = &clk_consumer[(pdr0 >> 16) & 0xf]; | 169 | aad = &clk_consumer[(pdr0 >> 16) & 0xf]; |
170 | 170 | ||
@@ -176,16 +176,11 @@ static unsigned long get_rate_ipg(struct clk *clk) | |||
176 | return get_rate_ahb(NULL) >> 1; | 176 | return get_rate_ahb(NULL) >> 1; |
177 | } | 177 | } |
178 | 178 | ||
179 | static unsigned long get_3_3_div(unsigned long in) | ||
180 | { | ||
181 | return (((in >> 3) & 0x7) + 1) * ((in & 0x7) + 1); | ||
182 | } | ||
183 | |||
184 | static unsigned long get_rate_uart(struct clk *clk) | 179 | static unsigned long get_rate_uart(struct clk *clk) |
185 | { | 180 | { |
186 | unsigned long pdr3 = __raw_readl(CCM_BASE + CCM_PDR3); | 181 | unsigned long pdr3 = __raw_readl(CCM_BASE + CCM_PDR3); |
187 | unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4); | 182 | unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4); |
188 | unsigned long div = get_3_3_div(pdr4 >> 10); | 183 | unsigned long div = ((pdr4 >> 10) & 0x3f) + 1; |
189 | 184 | ||
190 | if (pdr3 & (1 << 14)) | 185 | if (pdr3 & (1 << 14)) |
191 | return get_rate_arm() / div; | 186 | return get_rate_arm() / div; |
@@ -216,7 +211,7 @@ static unsigned long get_rate_sdhc(struct clk *clk) | |||
216 | break; | 211 | break; |
217 | } | 212 | } |
218 | 213 | ||
219 | return rate / get_3_3_div(div); | 214 | return rate / (div + 1); |
220 | } | 215 | } |
221 | 216 | ||
222 | static unsigned long get_rate_mshc(struct clk *clk) | 217 | static unsigned long get_rate_mshc(struct clk *clk) |
@@ -270,7 +265,7 @@ static unsigned long get_rate_csi(struct clk *clk) | |||
270 | else | 265 | else |
271 | rate = get_rate_ppll(); | 266 | rate = get_rate_ppll(); |
272 | 267 | ||
273 | return rate / get_3_3_div((pdr2 >> 16) & 0x3f); | 268 | return rate / (((pdr2 >> 16) & 0x3f) + 1); |
274 | } | 269 | } |
275 | 270 | ||
276 | static unsigned long get_rate_otg(struct clk *clk) | 271 | static unsigned long get_rate_otg(struct clk *clk) |
@@ -283,25 +278,51 @@ static unsigned long get_rate_otg(struct clk *clk) | |||
283 | else | 278 | else |
284 | rate = get_rate_ppll(); | 279 | rate = get_rate_ppll(); |
285 | 280 | ||
286 | return rate / get_3_3_div((pdr4 >> 22) & 0x3f); | 281 | return rate / (((pdr4 >> 22) & 0x3f) + 1); |
287 | } | 282 | } |
288 | 283 | ||
289 | static unsigned long get_rate_ipg_per(struct clk *clk) | 284 | static unsigned long get_rate_ipg_per(struct clk *clk) |
290 | { | 285 | { |
291 | unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0); | 286 | unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0); |
292 | unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4); | 287 | unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4); |
293 | unsigned long div1, div2; | 288 | unsigned long div; |
294 | 289 | ||
295 | if (pdr0 & (1 << 26)) { | 290 | if (pdr0 & (1 << 26)) { |
296 | div1 = (pdr4 >> 19) & 0x7; | 291 | div = (pdr4 >> 16) & 0x3f; |
297 | div2 = (pdr4 >> 16) & 0x7; | 292 | return get_rate_arm() / (div + 1); |
298 | return get_rate_arm() / ((div1 + 1) * (div2 + 1)); | ||
299 | } else { | 293 | } else { |
300 | div1 = (pdr0 >> 12) & 0x7; | 294 | div = (pdr0 >> 12) & 0x7; |
301 | return get_rate_ahb(NULL) / div1; | 295 | return get_rate_ahb(NULL) / (div + 1); |
302 | } | 296 | } |
303 | } | 297 | } |
304 | 298 | ||
299 | static unsigned long get_rate_hsp(struct clk *clk) | ||
300 | { | ||
301 | unsigned long hsp_podf = (__raw_readl(CCM_BASE + CCM_PDR0) >> 20) & 0x03; | ||
302 | unsigned long fref = get_rate_mpll(); | ||
303 | |||
304 | if (fref > 400 * 1000 * 1000) { | ||
305 | switch (hsp_podf) { | ||
306 | case 0: | ||
307 | return fref >> 2; | ||
308 | case 1: | ||
309 | return fref >> 3; | ||
310 | case 2: | ||
311 | return fref / 3; | ||
312 | } | ||
313 | } else { | ||
314 | switch (hsp_podf) { | ||
315 | case 0: | ||
316 | case 2: | ||
317 | return fref / 3; | ||
318 | case 1: | ||
319 | return fref / 6; | ||
320 | } | ||
321 | } | ||
322 | |||
323 | return 0; | ||
324 | } | ||
325 | |||
305 | static int clk_cgr_enable(struct clk *clk) | 326 | static int clk_cgr_enable(struct clk *clk) |
306 | { | 327 | { |
307 | u32 reg; | 328 | u32 reg; |
@@ -359,7 +380,7 @@ DEFINE_CLOCK(i2c1_clk, 0, CCM_CGR1, 10, get_rate_ipg_per, NULL); | |||
359 | DEFINE_CLOCK(i2c2_clk, 1, CCM_CGR1, 12, get_rate_ipg_per, NULL); | 380 | DEFINE_CLOCK(i2c2_clk, 1, CCM_CGR1, 12, get_rate_ipg_per, NULL); |
360 | DEFINE_CLOCK(i2c3_clk, 2, CCM_CGR1, 14, get_rate_ipg_per, NULL); | 381 | DEFINE_CLOCK(i2c3_clk, 2, CCM_CGR1, 14, get_rate_ipg_per, NULL); |
361 | DEFINE_CLOCK(iomuxc_clk, 0, CCM_CGR1, 16, NULL, NULL); | 382 | DEFINE_CLOCK(iomuxc_clk, 0, CCM_CGR1, 16, NULL, NULL); |
362 | DEFINE_CLOCK(ipu_clk, 0, CCM_CGR1, 18, get_rate_ahb, NULL); | 383 | DEFINE_CLOCK(ipu_clk, 0, CCM_CGR1, 18, get_rate_hsp, NULL); |
363 | DEFINE_CLOCK(kpp_clk, 0, CCM_CGR1, 20, get_rate_ipg, NULL); | 384 | DEFINE_CLOCK(kpp_clk, 0, CCM_CGR1, 20, get_rate_ipg, NULL); |
364 | DEFINE_CLOCK(mlb_clk, 0, CCM_CGR1, 22, get_rate_ahb, NULL); | 385 | DEFINE_CLOCK(mlb_clk, 0, CCM_CGR1, 22, get_rate_ahb, NULL); |
365 | DEFINE_CLOCK(mshc_clk, 0, CCM_CGR1, 24, get_rate_mshc, NULL); | 386 | DEFINE_CLOCK(mshc_clk, 0, CCM_CGR1, 24, get_rate_mshc, NULL); |
@@ -485,10 +506,10 @@ static struct clk_lookup lookups[] = { | |||
485 | 506 | ||
486 | int __init mx35_clocks_init() | 507 | int __init mx35_clocks_init() |
487 | { | 508 | { |
488 | unsigned int ll = 0; | 509 | unsigned int cgr2 = 3 << 26, cgr3 = 0; |
489 | 510 | ||
490 | #if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC) | 511 | #if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC) |
491 | ll = (3 << 16); | 512 | cgr2 |= 3 << 16; |
492 | #endif | 513 | #endif |
493 | 514 | ||
494 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); | 515 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); |
@@ -499,8 +520,20 @@ int __init mx35_clocks_init() | |||
499 | __raw_writel((3 << 18), CCM_BASE + CCM_CGR0); | 520 | __raw_writel((3 << 18), CCM_BASE + CCM_CGR0); |
500 | __raw_writel((3 << 2) | (3 << 4) | (3 << 6) | (3 << 8) | (3 << 16), | 521 | __raw_writel((3 << 2) | (3 << 4) | (3 << 6) | (3 << 8) | (3 << 16), |
501 | CCM_BASE + CCM_CGR1); | 522 | CCM_BASE + CCM_CGR1); |
502 | __raw_writel((3 << 26) | ll, CCM_BASE + CCM_CGR2); | 523 | |
503 | __raw_writel(0, CCM_BASE + CCM_CGR3); | 524 | /* |
525 | * Check if we came up in internal boot mode. If yes, we need some | ||
526 | * extra clocks turned on, otherwise the MX35 boot ROM code will | ||
527 | * hang after a watchdog reset. | ||
528 | */ | ||
529 | if (!(__raw_readl(CCM_BASE + CCM_RCSR) & (3 << 10))) { | ||
530 | /* Additionally turn on UART1, SCC, and IIM clocks */ | ||
531 | cgr2 |= 3 << 16 | 3 << 4; | ||
532 | cgr3 |= 3 << 2; | ||
533 | } | ||
534 | |||
535 | __raw_writel(cgr2, CCM_BASE + CCM_CGR2); | ||
536 | __raw_writel(cgr3, CCM_BASE + CCM_CGR3); | ||
504 | 537 | ||
505 | mxc_timer_init(&gpt_clk, | 538 | mxc_timer_init(&gpt_clk, |
506 | MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR), MX35_INT_GPT); | 539 | MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR), MX35_INT_GPT); |
diff --git a/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c b/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c index 1dc5004df86..f8f15e3ac7a 100644 --- a/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c +++ b/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c | |||
@@ -216,7 +216,7 @@ struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata = { | |||
216 | * Add platform devices present on this baseboard and init | 216 | * Add platform devices present on this baseboard and init |
217 | * them from CPU side as far as required to use them later on | 217 | * them from CPU side as far as required to use them later on |
218 | */ | 218 | */ |
219 | void __init eukrea_mbimxsd_baseboard_init(void) | 219 | void __init eukrea_mbimxsd35_baseboard_init(void) |
220 | { | 220 | { |
221 | if (mxc_iomux_v3_setup_multiple_pads(eukrea_mbimxsd_pads, | 221 | if (mxc_iomux_v3_setup_multiple_pads(eukrea_mbimxsd_pads, |
222 | ARRAY_SIZE(eukrea_mbimxsd_pads))) | 222 | ARRAY_SIZE(eukrea_mbimxsd_pads))) |
diff --git a/arch/arm/mach-mx3/mach-cpuimx35.c b/arch/arm/mach-mx3/mach-cpuimx35.c index 63f970f340a..2a4f8b781ba 100644 --- a/arch/arm/mach-mx3/mach-cpuimx35.c +++ b/arch/arm/mach-mx3/mach-cpuimx35.c | |||
@@ -192,7 +192,7 @@ static void __init mxc_board_init(void) | |||
192 | #if defined(CONFIG_USB_ULPI) | 192 | #if defined(CONFIG_USB_ULPI) |
193 | if (otg_mode_host) { | 193 | if (otg_mode_host) { |
194 | otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, | 194 | otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, |
195 | USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); | 195 | ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT); |
196 | 196 | ||
197 | mxc_register_device(&mxc_otg_host, &otg_pdata); | 197 | mxc_register_device(&mxc_otg_host, &otg_pdata); |
198 | } | 198 | } |
@@ -201,8 +201,8 @@ static void __init mxc_board_init(void) | |||
201 | if (!otg_mode_host) | 201 | if (!otg_mode_host) |
202 | mxc_register_device(&mxc_otg_udc_device, &otg_device_pdata); | 202 | mxc_register_device(&mxc_otg_udc_device, &otg_device_pdata); |
203 | 203 | ||
204 | #ifdef CONFIG_MACH_EUKREA_MBIMXSD_BASEBOARD | 204 | #ifdef CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD |
205 | eukrea_mbimxsd_baseboard_init(); | 205 | eukrea_mbimxsd35_baseboard_init(); |
206 | #endif | 206 | #endif |
207 | } | 207 | } |
208 | 208 | ||
diff --git a/arch/arm/mach-mx5/clock-mx51.c b/arch/arm/mach-mx5/clock-mx51.c index 6af69def357..57c10a9926c 100644 --- a/arch/arm/mach-mx5/clock-mx51.c +++ b/arch/arm/mach-mx5/clock-mx51.c | |||
@@ -56,7 +56,7 @@ static void _clk_ccgr_disable(struct clk *clk) | |||
56 | { | 56 | { |
57 | u32 reg; | 57 | u32 reg; |
58 | reg = __raw_readl(clk->enable_reg); | 58 | reg = __raw_readl(clk->enable_reg); |
59 | reg &= ~(MXC_CCM_CCGRx_MOD_OFF << clk->enable_shift); | 59 | reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift); |
60 | __raw_writel(reg, clk->enable_reg); | 60 | __raw_writel(reg, clk->enable_reg); |
61 | 61 | ||
62 | } | 62 | } |
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 63b2d8859c3..88d3a1e920f 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile | |||
@@ -25,6 +25,7 @@ obj-$(CONFIG_LOCAL_TIMERS) += timer-mpu.o | |||
25 | obj-$(CONFIG_HOTPLUG_CPU) += omap-hotplug.o | 25 | obj-$(CONFIG_HOTPLUG_CPU) += omap-hotplug.o |
26 | obj-$(CONFIG_ARCH_OMAP4) += omap44xx-smc.o omap4-common.o | 26 | obj-$(CONFIG_ARCH_OMAP4) += omap44xx-smc.o omap4-common.o |
27 | 27 | ||
28 | AFLAGS_omap-headsmp.o :=-Wa,-march=armv7-a | ||
28 | AFLAGS_omap44xx-smc.o :=-Wa,-march=armv7-a | 29 | AFLAGS_omap44xx-smc.o :=-Wa,-march=armv7-a |
29 | 30 | ||
30 | # Functions loaded to SRAM | 31 | # Functions loaded to SRAM |
diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index 138646deac8..dfdce2d8277 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c | |||
@@ -3417,7 +3417,13 @@ int __init omap3xxx_clk_init(void) | |||
3417 | struct omap_clk *c; | 3417 | struct omap_clk *c; |
3418 | u32 cpu_clkflg = CK_3XXX; | 3418 | u32 cpu_clkflg = CK_3XXX; |
3419 | 3419 | ||
3420 | if (cpu_is_omap34xx()) { | 3420 | if (cpu_is_omap3517()) { |
3421 | cpu_mask = RATE_IN_3XXX | RATE_IN_3430ES2PLUS; | ||
3422 | cpu_clkflg |= CK_3517; | ||
3423 | } else if (cpu_is_omap3505()) { | ||
3424 | cpu_mask = RATE_IN_3XXX | RATE_IN_3430ES2PLUS; | ||
3425 | cpu_clkflg |= CK_3505; | ||
3426 | } else if (cpu_is_omap34xx()) { | ||
3421 | cpu_mask = RATE_IN_3XXX; | 3427 | cpu_mask = RATE_IN_3XXX; |
3422 | cpu_clkflg |= CK_343X; | 3428 | cpu_clkflg |= CK_343X; |
3423 | 3429 | ||
@@ -3432,12 +3438,6 @@ int __init omap3xxx_clk_init(void) | |||
3432 | cpu_mask |= RATE_IN_3430ES2PLUS; | 3438 | cpu_mask |= RATE_IN_3430ES2PLUS; |
3433 | cpu_clkflg |= CK_3430ES2; | 3439 | cpu_clkflg |= CK_3430ES2; |
3434 | } | 3440 | } |
3435 | } else if (cpu_is_omap3517()) { | ||
3436 | cpu_mask = RATE_IN_3XXX | RATE_IN_3430ES2PLUS; | ||
3437 | cpu_clkflg |= CK_3517; | ||
3438 | } else if (cpu_is_omap3505()) { | ||
3439 | cpu_mask = RATE_IN_3XXX | RATE_IN_3430ES2PLUS; | ||
3440 | cpu_clkflg |= CK_3505; | ||
3441 | } | 3441 | } |
3442 | 3442 | ||
3443 | if (omap3_has_192mhz_clk()) | 3443 | if (omap3_has_192mhz_clk()) |
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index e8256a2ed8e..9a879f95950 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c | |||
@@ -284,8 +284,8 @@ static void __init omap3_check_revision(void) | |||
284 | default: | 284 | default: |
285 | omap_revision = OMAP3630_REV_ES1_2; | 285 | omap_revision = OMAP3630_REV_ES1_2; |
286 | omap_chip.oc |= CHIP_IS_OMAP3630ES1_2; | 286 | omap_chip.oc |= CHIP_IS_OMAP3630ES1_2; |
287 | break; | ||
288 | } | 287 | } |
288 | break; | ||
289 | default: | 289 | default: |
290 | /* Unknown default to latest silicon rev as default*/ | 290 | /* Unknown default to latest silicon rev as default*/ |
291 | omap_revision = OMAP3630_REV_ES1_2; | 291 | omap_revision = OMAP3630_REV_ES1_2; |
diff --git a/arch/arm/mach-omap2/include/mach/entry-macro.S b/arch/arm/mach-omap2/include/mach/entry-macro.S index 50fd7491664..06e64e1fc28 100644 --- a/arch/arm/mach-omap2/include/mach/entry-macro.S +++ b/arch/arm/mach-omap2/include/mach/entry-macro.S | |||
@@ -177,7 +177,10 @@ omap_irq_base: .word 0 | |||
177 | cmpne \irqnr, \tmp | 177 | cmpne \irqnr, \tmp |
178 | cmpcs \irqnr, \irqnr | 178 | cmpcs \irqnr, \irqnr |
179 | .endm | 179 | .endm |
180 | #endif | ||
181 | #endif /* MULTI_OMAP2 */ | ||
180 | 182 | ||
183 | #ifdef CONFIG_SMP | ||
181 | /* We assume that irqstat (the raw value of the IRQ acknowledge | 184 | /* We assume that irqstat (the raw value of the IRQ acknowledge |
182 | * register) is preserved from the macro above. | 185 | * register) is preserved from the macro above. |
183 | * If there is an IPI, we immediately signal end of interrupt | 186 | * If there is an IPI, we immediately signal end of interrupt |
@@ -205,8 +208,7 @@ omap_irq_base: .word 0 | |||
205 | streq \irqstat, [\base, #GIC_CPU_EOI] | 208 | streq \irqstat, [\base, #GIC_CPU_EOI] |
206 | cmp \tmp, #0 | 209 | cmp \tmp, #0 |
207 | .endm | 210 | .endm |
208 | #endif | 211 | #endif /* CONFIG_SMP */ |
209 | #endif /* MULTI_OMAP2 */ | ||
210 | 212 | ||
211 | .macro irq_prio_table | 213 | .macro irq_prio_table |
212 | .endm | 214 | .endm |
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index af3c20c8d3f..9e9f70e18e3 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c | |||
@@ -102,8 +102,7 @@ static void __init wakeup_secondary(void) | |||
102 | * Send a 'sev' to wake the secondary core from WFE. | 102 | * Send a 'sev' to wake the secondary core from WFE. |
103 | * Drain the outstanding writes to memory | 103 | * Drain the outstanding writes to memory |
104 | */ | 104 | */ |
105 | dsb(); | 105 | dsb_sev(); |
106 | set_event(); | ||
107 | mb(); | 106 | mb(); |
108 | } | 107 | } |
109 | 108 | ||
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index fb4994ad622..7b03426c72a 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c | |||
@@ -480,7 +480,9 @@ void omap_sram_idle(void) | |||
480 | } | 480 | } |
481 | 481 | ||
482 | /* Disable IO-PAD and IO-CHAIN wakeup */ | 482 | /* Disable IO-PAD and IO-CHAIN wakeup */ |
483 | if (omap3_has_io_wakeup() && core_next_state < PWRDM_POWER_ON) { | 483 | if (omap3_has_io_wakeup() && |
484 | (per_next_state < PWRDM_POWER_ON || | ||
485 | core_next_state < PWRDM_POWER_ON)) { | ||
484 | prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN); | 486 | prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN); |
485 | omap3_disable_io_chain(); | 487 | omap3_disable_io_chain(); |
486 | } | 488 | } |
diff --git a/arch/arm/mach-pxa/cpufreq-pxa2xx.c b/arch/arm/mach-pxa/cpufreq-pxa2xx.c index 268a9bc6be8..58093d9e07b 100644 --- a/arch/arm/mach-pxa/cpufreq-pxa2xx.c +++ b/arch/arm/mach-pxa/cpufreq-pxa2xx.c | |||
@@ -312,8 +312,7 @@ static int pxa_set_target(struct cpufreq_policy *policy, | |||
312 | freqs.cpu = policy->cpu; | 312 | freqs.cpu = policy->cpu; |
313 | 313 | ||
314 | if (freq_debug) | 314 | if (freq_debug) |
315 | pr_debug(KERN_INFO "Changing CPU frequency to %d Mhz, " | 315 | pr_debug("Changing CPU frequency to %d Mhz, (SDRAM %d Mhz)\n", |
316 | "(SDRAM %d Mhz)\n", | ||
317 | freqs.new / 1000, (pxa_freq_settings[idx].div2) ? | 316 | freqs.new / 1000, (pxa_freq_settings[idx].div2) ? |
318 | (new_freq_mem / 2000) : (new_freq_mem / 1000)); | 317 | (new_freq_mem / 2000) : (new_freq_mem / 1000)); |
319 | 318 | ||
@@ -398,7 +397,7 @@ static int pxa_set_target(struct cpufreq_policy *policy, | |||
398 | return 0; | 397 | return 0; |
399 | } | 398 | } |
400 | 399 | ||
401 | static __init int pxa_cpufreq_init(struct cpufreq_policy *policy) | 400 | static int pxa_cpufreq_init(struct cpufreq_policy *policy) |
402 | { | 401 | { |
403 | int i; | 402 | int i; |
404 | unsigned int freq; | 403 | unsigned int freq; |
diff --git a/arch/arm/mach-pxa/cpufreq-pxa3xx.c b/arch/arm/mach-pxa/cpufreq-pxa3xx.c index 27fa329d9a8..0a0d0fe9922 100644 --- a/arch/arm/mach-pxa/cpufreq-pxa3xx.c +++ b/arch/arm/mach-pxa/cpufreq-pxa3xx.c | |||
@@ -204,7 +204,7 @@ static int pxa3xx_cpufreq_set(struct cpufreq_policy *policy, | |||
204 | return 0; | 204 | return 0; |
205 | } | 205 | } |
206 | 206 | ||
207 | static __init int pxa3xx_cpufreq_init(struct cpufreq_policy *policy) | 207 | static int pxa3xx_cpufreq_init(struct cpufreq_policy *policy) |
208 | { | 208 | { |
209 | int ret = -EINVAL; | 209 | int ret = -EINVAL; |
210 | 210 | ||
diff --git a/arch/arm/mach-pxa/include/mach/hardware.h b/arch/arm/mach-pxa/include/mach/hardware.h index 7f64d24cd56..814f1458a06 100644 --- a/arch/arm/mach-pxa/include/mach/hardware.h +++ b/arch/arm/mach-pxa/include/mach/hardware.h | |||
@@ -264,23 +264,35 @@ | |||
264 | * <= 0x2 for pxa21x/pxa25x/pxa26x/pxa27x | 264 | * <= 0x2 for pxa21x/pxa25x/pxa26x/pxa27x |
265 | * == 0x3 for pxa300/pxa310/pxa320 | 265 | * == 0x3 for pxa300/pxa310/pxa320 |
266 | */ | 266 | */ |
267 | #if defined(CONFIG_PXA25x) || defined(CONFIG_PXA27x) | ||
267 | #define __cpu_is_pxa2xx(id) \ | 268 | #define __cpu_is_pxa2xx(id) \ |
268 | ({ \ | 269 | ({ \ |
269 | unsigned int _id = (id) >> 13 & 0x7; \ | 270 | unsigned int _id = (id) >> 13 & 0x7; \ |
270 | _id <= 0x2; \ | 271 | _id <= 0x2; \ |
271 | }) | 272 | }) |
273 | #else | ||
274 | #define __cpu_is_pxa2xx(id) (0) | ||
275 | #endif | ||
272 | 276 | ||
277 | #ifdef CONFIG_PXA3xx | ||
273 | #define __cpu_is_pxa3xx(id) \ | 278 | #define __cpu_is_pxa3xx(id) \ |
274 | ({ \ | 279 | ({ \ |
275 | unsigned int _id = (id) >> 13 & 0x7; \ | 280 | unsigned int _id = (id) >> 13 & 0x7; \ |
276 | _id == 0x3; \ | 281 | _id == 0x3; \ |
277 | }) | 282 | }) |
283 | #else | ||
284 | #define __cpu_is_pxa3xx(id) (0) | ||
285 | #endif | ||
278 | 286 | ||
287 | #if defined(CONFIG_CPU_PXA930) || defined(CONFIG_CPU_PXA935) | ||
279 | #define __cpu_is_pxa93x(id) \ | 288 | #define __cpu_is_pxa93x(id) \ |
280 | ({ \ | 289 | ({ \ |
281 | unsigned int _id = (id) >> 4 & 0xfff; \ | 290 | unsigned int _id = (id) >> 4 & 0xfff; \ |
282 | _id == 0x683 || _id == 0x693; \ | 291 | _id == 0x683 || _id == 0x693; \ |
283 | }) | 292 | }) |
293 | #else | ||
294 | #define __cpu_is_pxa93x(id) (0) | ||
295 | #endif | ||
284 | 296 | ||
285 | #define cpu_is_pxa2xx() \ | 297 | #define cpu_is_pxa2xx() \ |
286 | ({ \ | 298 | ({ \ |
@@ -309,7 +321,7 @@ extern unsigned long get_clock_tick_rate(void); | |||
309 | #define PCIBIOS_MIN_IO 0 | 321 | #define PCIBIOS_MIN_IO 0 |
310 | #define PCIBIOS_MIN_MEM 0 | 322 | #define PCIBIOS_MIN_MEM 0 |
311 | #define pcibios_assign_all_busses() 1 | 323 | #define pcibios_assign_all_busses() 1 |
324 | #define ARCH_HAS_DMA_SET_COHERENT_MASK | ||
312 | #endif | 325 | #endif |
313 | 326 | ||
314 | |||
315 | #endif /* _ASM_ARCH_HARDWARE_H */ | 327 | #endif /* _ASM_ARCH_HARDWARE_H */ |
diff --git a/arch/arm/mach-pxa/include/mach/io.h b/arch/arm/mach-pxa/include/mach/io.h index 262691fb97d..fdca3be47d9 100644 --- a/arch/arm/mach-pxa/include/mach/io.h +++ b/arch/arm/mach-pxa/include/mach/io.h | |||
@@ -6,6 +6,8 @@ | |||
6 | #ifndef __ASM_ARM_ARCH_IO_H | 6 | #ifndef __ASM_ARM_ARCH_IO_H |
7 | #define __ASM_ARM_ARCH_IO_H | 7 | #define __ASM_ARM_ARCH_IO_H |
8 | 8 | ||
9 | #include <mach/hardware.h> | ||
10 | |||
9 | #define IO_SPACE_LIMIT 0xffffffff | 11 | #define IO_SPACE_LIMIT 0xffffffff |
10 | 12 | ||
11 | /* | 13 | /* |
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa300.h b/arch/arm/mach-pxa/include/mach/mfp-pxa300.h index 7139e0dc26d..4e1287070d2 100644 --- a/arch/arm/mach-pxa/include/mach/mfp-pxa300.h +++ b/arch/arm/mach-pxa/include/mach/mfp-pxa300.h | |||
@@ -71,10 +71,10 @@ | |||
71 | #define GPIO46_CI_DD_7 MFP_CFG_DRV(GPIO46, AF0, DS04X) | 71 | #define GPIO46_CI_DD_7 MFP_CFG_DRV(GPIO46, AF0, DS04X) |
72 | #define GPIO47_CI_DD_8 MFP_CFG_DRV(GPIO47, AF1, DS04X) | 72 | #define GPIO47_CI_DD_8 MFP_CFG_DRV(GPIO47, AF1, DS04X) |
73 | #define GPIO48_CI_DD_9 MFP_CFG_DRV(GPIO48, AF1, DS04X) | 73 | #define GPIO48_CI_DD_9 MFP_CFG_DRV(GPIO48, AF1, DS04X) |
74 | #define GPIO52_CI_HSYNC MFP_CFG_DRV(GPIO52, AF0, DS04X) | ||
75 | #define GPIO51_CI_VSYNC MFP_CFG_DRV(GPIO51, AF0, DS04X) | ||
76 | #define GPIO49_CI_MCLK MFP_CFG_DRV(GPIO49, AF0, DS04X) | 74 | #define GPIO49_CI_MCLK MFP_CFG_DRV(GPIO49, AF0, DS04X) |
77 | #define GPIO50_CI_PCLK MFP_CFG_DRV(GPIO50, AF0, DS04X) | 75 | #define GPIO50_CI_PCLK MFP_CFG_DRV(GPIO50, AF0, DS04X) |
76 | #define GPIO51_CI_HSYNC MFP_CFG_DRV(GPIO51, AF0, DS04X) | ||
77 | #define GPIO52_CI_VSYNC MFP_CFG_DRV(GPIO52, AF0, DS04X) | ||
78 | 78 | ||
79 | /* KEYPAD */ | 79 | /* KEYPAD */ |
80 | #define GPIO3_KP_DKIN_6 MFP_CFG_LPM(GPIO3, AF2, FLOAT) | 80 | #define GPIO3_KP_DKIN_6 MFP_CFG_LPM(GPIO3, AF2, FLOAT) |
diff --git a/arch/arm/mach-pxa/palm27x.c b/arch/arm/mach-pxa/palm27x.c index 77ad6d34ab5..405b92a2979 100644 --- a/arch/arm/mach-pxa/palm27x.c +++ b/arch/arm/mach-pxa/palm27x.c | |||
@@ -469,9 +469,13 @@ static struct i2c_board_info __initdata palm27x_pi2c_board_info[] = { | |||
469 | }, | 469 | }, |
470 | }; | 470 | }; |
471 | 471 | ||
472 | static struct i2c_pxa_platform_data palm27x_i2c_power_info = { | ||
473 | .use_pio = 1, | ||
474 | }; | ||
475 | |||
472 | void __init palm27x_pmic_init(void) | 476 | void __init palm27x_pmic_init(void) |
473 | { | 477 | { |
474 | i2c_register_board_info(1, ARRAY_AND_SIZE(palm27x_pi2c_board_info)); | 478 | i2c_register_board_info(1, ARRAY_AND_SIZE(palm27x_pi2c_board_info)); |
475 | pxa27x_set_i2c_power_info(NULL); | 479 | pxa27x_set_i2c_power_info(&palm27x_i2c_power_info); |
476 | } | 480 | } |
477 | #endif | 481 | #endif |
diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c index c9b747cedea..37d6173bbb6 100644 --- a/arch/arm/mach-pxa/vpac270.c +++ b/arch/arm/mach-pxa/vpac270.c | |||
@@ -240,6 +240,7 @@ static void __init vpac270_onenand_init(void) {} | |||
240 | #if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE) | 240 | #if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE) |
241 | static struct pxamci_platform_data vpac270_mci_platform_data = { | 241 | static struct pxamci_platform_data vpac270_mci_platform_data = { |
242 | .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, | 242 | .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, |
243 | .gpio_power = -1, | ||
243 | .gpio_card_detect = GPIO53_VPAC270_SD_DETECT_N, | 244 | .gpio_card_detect = GPIO53_VPAC270_SD_DETECT_N, |
244 | .gpio_card_ro = GPIO52_VPAC270_SD_READONLY, | 245 | .gpio_card_ro = GPIO52_VPAC270_SD_READONLY, |
245 | .detect_delay_ms = 200, | 246 | .detect_delay_ms = 200, |
diff --git a/arch/arm/mach-s3c2410/include/mach/vmalloc.h b/arch/arm/mach-s3c2410/include/mach/vmalloc.h index 315b0078a34..54297eb0bf5 100644 --- a/arch/arm/mach-s3c2410/include/mach/vmalloc.h +++ b/arch/arm/mach-s3c2410/include/mach/vmalloc.h | |||
@@ -15,6 +15,6 @@ | |||
15 | #ifndef __ASM_ARCH_VMALLOC_H | 15 | #ifndef __ASM_ARCH_VMALLOC_H |
16 | #define __ASM_ARCH_VMALLOC_H | 16 | #define __ASM_ARCH_VMALLOC_H |
17 | 17 | ||
18 | #define VMALLOC_END (0xE0000000) | 18 | #define VMALLOC_END 0xE0000000UL |
19 | 19 | ||
20 | #endif /* __ASM_ARCH_VMALLOC_H */ | 20 | #endif /* __ASM_ARCH_VMALLOC_H */ |
diff --git a/arch/arm/mach-s3c64xx/dev-spi.c b/arch/arm/mach-s3c64xx/dev-spi.c index a492b982aa0..405e6212891 100644 --- a/arch/arm/mach-s3c64xx/dev-spi.c +++ b/arch/arm/mach-s3c64xx/dev-spi.c | |||
@@ -18,10 +18,11 @@ | |||
18 | #include <mach/map.h> | 18 | #include <mach/map.h> |
19 | #include <mach/gpio-bank-c.h> | 19 | #include <mach/gpio-bank-c.h> |
20 | #include <mach/spi-clocks.h> | 20 | #include <mach/spi-clocks.h> |
21 | #include <mach/irqs.h> | ||
21 | 22 | ||
22 | #include <plat/s3c64xx-spi.h> | 23 | #include <plat/s3c64xx-spi.h> |
23 | #include <plat/gpio-cfg.h> | 24 | #include <plat/gpio-cfg.h> |
24 | #include <plat/irqs.h> | 25 | #include <plat/devs.h> |
25 | 26 | ||
26 | static char *spi_src_clks[] = { | 27 | static char *spi_src_clks[] = { |
27 | [S3C64XX_SPI_SRCCLK_PCLK] = "pclk", | 28 | [S3C64XX_SPI_SRCCLK_PCLK] = "pclk", |
diff --git a/arch/arm/mach-s3c64xx/include/mach/vmalloc.h b/arch/arm/mach-s3c64xx/include/mach/vmalloc.h index 7411ef3711a..bc0e9138986 100644 --- a/arch/arm/mach-s3c64xx/include/mach/vmalloc.h +++ b/arch/arm/mach-s3c64xx/include/mach/vmalloc.h | |||
@@ -15,6 +15,6 @@ | |||
15 | #ifndef __ASM_ARCH_VMALLOC_H | 15 | #ifndef __ASM_ARCH_VMALLOC_H |
16 | #define __ASM_ARCH_VMALLOC_H | 16 | #define __ASM_ARCH_VMALLOC_H |
17 | 17 | ||
18 | #define VMALLOC_END (0xE0000000) | 18 | #define VMALLOC_END 0xE0000000UL |
19 | 19 | ||
20 | #endif /* __ASM_ARCH_VMALLOC_H */ | 20 | #endif /* __ASM_ARCH_VMALLOC_H */ |
diff --git a/arch/arm/mach-s3c64xx/mach-real6410.c b/arch/arm/mach-s3c64xx/mach-real6410.c index 5c07d013b23..e130379ba0e 100644 --- a/arch/arm/mach-s3c64xx/mach-real6410.c +++ b/arch/arm/mach-s3c64xx/mach-real6410.c | |||
@@ -30,73 +30,73 @@ | |||
30 | #include <plat/devs.h> | 30 | #include <plat/devs.h> |
31 | #include <plat/regs-serial.h> | 31 | #include <plat/regs-serial.h> |
32 | 32 | ||
33 | #define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK | 33 | #define UCON (S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK) |
34 | #define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB | 34 | #define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB) |
35 | #define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE | 35 | #define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE) |
36 | 36 | ||
37 | static struct s3c2410_uartcfg real6410_uartcfgs[] __initdata = { | 37 | static struct s3c2410_uartcfg real6410_uartcfgs[] __initdata = { |
38 | [0] = { | 38 | [0] = { |
39 | .hwport = 0, | 39 | .hwport = 0, |
40 | .flags = 0, | 40 | .flags = 0, |
41 | .ucon = UCON, | 41 | .ucon = UCON, |
42 | .ulcon = ULCON, | 42 | .ulcon = ULCON, |
43 | .ufcon = UFCON, | 43 | .ufcon = UFCON, |
44 | }, | 44 | }, |
45 | [1] = { | 45 | [1] = { |
46 | .hwport = 1, | 46 | .hwport = 1, |
47 | .flags = 0, | 47 | .flags = 0, |
48 | .ucon = UCON, | 48 | .ucon = UCON, |
49 | .ulcon = ULCON, | 49 | .ulcon = ULCON, |
50 | .ufcon = UFCON, | 50 | .ufcon = UFCON, |
51 | }, | 51 | }, |
52 | [2] = { | 52 | [2] = { |
53 | .hwport = 2, | 53 | .hwport = 2, |
54 | .flags = 0, | 54 | .flags = 0, |
55 | .ucon = UCON, | 55 | .ucon = UCON, |
56 | .ulcon = ULCON, | 56 | .ulcon = ULCON, |
57 | .ufcon = UFCON, | 57 | .ufcon = UFCON, |
58 | }, | 58 | }, |
59 | [3] = { | 59 | [3] = { |
60 | .hwport = 3, | 60 | .hwport = 3, |
61 | .flags = 0, | 61 | .flags = 0, |
62 | .ucon = UCON, | 62 | .ucon = UCON, |
63 | .ulcon = ULCON, | 63 | .ulcon = ULCON, |
64 | .ufcon = UFCON, | 64 | .ufcon = UFCON, |
65 | }, | 65 | }, |
66 | }; | 66 | }; |
67 | 67 | ||
68 | /* DM9000AEP 10/100 ethernet controller */ | 68 | /* DM9000AEP 10/100 ethernet controller */ |
69 | 69 | ||
70 | static struct resource real6410_dm9k_resource[] = { | 70 | static struct resource real6410_dm9k_resource[] = { |
71 | [0] = { | 71 | [0] = { |
72 | .start = S3C64XX_PA_XM0CSN1, | 72 | .start = S3C64XX_PA_XM0CSN1, |
73 | .end = S3C64XX_PA_XM0CSN1 + 1, | 73 | .end = S3C64XX_PA_XM0CSN1 + 1, |
74 | .flags = IORESOURCE_MEM | 74 | .flags = IORESOURCE_MEM |
75 | }, | 75 | }, |
76 | [1] = { | 76 | [1] = { |
77 | .start = S3C64XX_PA_XM0CSN1 + 4, | 77 | .start = S3C64XX_PA_XM0CSN1 + 4, |
78 | .end = S3C64XX_PA_XM0CSN1 + 5, | 78 | .end = S3C64XX_PA_XM0CSN1 + 5, |
79 | .flags = IORESOURCE_MEM | 79 | .flags = IORESOURCE_MEM |
80 | }, | 80 | }, |
81 | [2] = { | 81 | [2] = { |
82 | .start = S3C_EINT(7), | 82 | .start = S3C_EINT(7), |
83 | .end = S3C_EINT(7), | 83 | .end = S3C_EINT(7), |
84 | .flags = IORESOURCE_IRQ, | 84 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL |
85 | } | 85 | } |
86 | }; | 86 | }; |
87 | 87 | ||
88 | static struct dm9000_plat_data real6410_dm9k_pdata = { | 88 | static struct dm9000_plat_data real6410_dm9k_pdata = { |
89 | .flags = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM), | 89 | .flags = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM), |
90 | }; | 90 | }; |
91 | 91 | ||
92 | static struct platform_device real6410_device_eth = { | 92 | static struct platform_device real6410_device_eth = { |
93 | .name = "dm9000", | 93 | .name = "dm9000", |
94 | .id = -1, | 94 | .id = -1, |
95 | .num_resources = ARRAY_SIZE(real6410_dm9k_resource), | 95 | .num_resources = ARRAY_SIZE(real6410_dm9k_resource), |
96 | .resource = real6410_dm9k_resource, | 96 | .resource = real6410_dm9k_resource, |
97 | .dev = { | 97 | .dev = { |
98 | .platform_data = &real6410_dm9k_pdata, | 98 | .platform_data = &real6410_dm9k_pdata, |
99 | }, | 99 | }, |
100 | }; | 100 | }; |
101 | 101 | ||
102 | static struct platform_device *real6410_devices[] __initdata = { | 102 | static struct platform_device *real6410_devices[] __initdata = { |
@@ -129,12 +129,12 @@ static void __init real6410_machine_init(void) | |||
129 | /* set timing for nCS1 suitable for ethernet chip */ | 129 | /* set timing for nCS1 suitable for ethernet chip */ |
130 | 130 | ||
131 | __raw_writel((0 << S3C64XX_SROM_BCX__PMC__SHIFT) | | 131 | __raw_writel((0 << S3C64XX_SROM_BCX__PMC__SHIFT) | |
132 | (6 << S3C64XX_SROM_BCX__TACP__SHIFT) | | 132 | (6 << S3C64XX_SROM_BCX__TACP__SHIFT) | |
133 | (4 << S3C64XX_SROM_BCX__TCAH__SHIFT) | | 133 | (4 << S3C64XX_SROM_BCX__TCAH__SHIFT) | |
134 | (1 << S3C64XX_SROM_BCX__TCOH__SHIFT) | | 134 | (1 << S3C64XX_SROM_BCX__TCOH__SHIFT) | |
135 | (13 << S3C64XX_SROM_BCX__TACC__SHIFT) | | 135 | (13 << S3C64XX_SROM_BCX__TACC__SHIFT) | |
136 | (4 << S3C64XX_SROM_BCX__TCOS__SHIFT) | | 136 | (4 << S3C64XX_SROM_BCX__TCOS__SHIFT) | |
137 | (0 << S3C64XX_SROM_BCX__TACS__SHIFT), S3C64XX_SROM_BC1); | 137 | (0 << S3C64XX_SROM_BCX__TACS__SHIFT), S3C64XX_SROM_BC1); |
138 | 138 | ||
139 | platform_add_devices(real6410_devices, ARRAY_SIZE(real6410_devices)); | 139 | platform_add_devices(real6410_devices, ARRAY_SIZE(real6410_devices)); |
140 | } | 140 | } |
diff --git a/arch/arm/mach-s5p6440/cpu.c b/arch/arm/mach-s5p6440/cpu.c index 526f33adb31..ec592e86605 100644 --- a/arch/arm/mach-s5p6440/cpu.c +++ b/arch/arm/mach-s5p6440/cpu.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/sysdev.h> | 19 | #include <linux/sysdev.h> |
20 | #include <linux/serial_core.h> | 20 | #include <linux/serial_core.h> |
21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
22 | #include <linux/sched.h> | ||
22 | 23 | ||
23 | #include <asm/mach/arch.h> | 24 | #include <asm/mach/arch.h> |
24 | #include <asm/mach/map.h> | 25 | #include <asm/mach/map.h> |
diff --git a/arch/arm/mach-s5p6440/include/mach/vmalloc.h b/arch/arm/mach-s5p6440/include/mach/vmalloc.h index 16df257b1dc..e3f0eebf520 100644 --- a/arch/arm/mach-s5p6440/include/mach/vmalloc.h +++ b/arch/arm/mach-s5p6440/include/mach/vmalloc.h | |||
@@ -12,6 +12,6 @@ | |||
12 | #ifndef __ASM_ARCH_VMALLOC_H | 12 | #ifndef __ASM_ARCH_VMALLOC_H |
13 | #define __ASM_ARCH_VMALLOC_H | 13 | #define __ASM_ARCH_VMALLOC_H |
14 | 14 | ||
15 | #define VMALLOC_END (0xE0000000) | 15 | #define VMALLOC_END 0xE0000000UL |
16 | 16 | ||
17 | #endif /* __ASM_ARCH_VMALLOC_H */ | 17 | #endif /* __ASM_ARCH_VMALLOC_H */ |
diff --git a/arch/arm/mach-s5p6442/cpu.c b/arch/arm/mach-s5p6442/cpu.c index a48fb553fd0..70ac681af72 100644 --- a/arch/arm/mach-s5p6442/cpu.c +++ b/arch/arm/mach-s5p6442/cpu.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/sysdev.h> | 19 | #include <linux/sysdev.h> |
20 | #include <linux/serial_core.h> | 20 | #include <linux/serial_core.h> |
21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
22 | #include <linux/sched.h> | ||
22 | 23 | ||
23 | #include <asm/mach/arch.h> | 24 | #include <asm/mach/arch.h> |
24 | #include <asm/mach/map.h> | 25 | #include <asm/mach/map.h> |
diff --git a/arch/arm/mach-s5p6442/include/mach/vmalloc.h b/arch/arm/mach-s5p6442/include/mach/vmalloc.h index be3333688c2..f5c83f02c18 100644 --- a/arch/arm/mach-s5p6442/include/mach/vmalloc.h +++ b/arch/arm/mach-s5p6442/include/mach/vmalloc.h | |||
@@ -12,6 +12,6 @@ | |||
12 | #ifndef __ASM_ARCH_VMALLOC_H | 12 | #ifndef __ASM_ARCH_VMALLOC_H |
13 | #define __ASM_ARCH_VMALLOC_H | 13 | #define __ASM_ARCH_VMALLOC_H |
14 | 14 | ||
15 | #define VMALLOC_END (0xE0000000) | 15 | #define VMALLOC_END 0xE0000000UL |
16 | 16 | ||
17 | #endif /* __ASM_ARCH_VMALLOC_H */ | 17 | #endif /* __ASM_ARCH_VMALLOC_H */ |
diff --git a/arch/arm/mach-s5pc100/cpu.c b/arch/arm/mach-s5pc100/cpu.c index 251c92ac5b2..cd1afbce83e 100644 --- a/arch/arm/mach-s5pc100/cpu.c +++ b/arch/arm/mach-s5pc100/cpu.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/sysdev.h> | 21 | #include <linux/sysdev.h> |
22 | #include <linux/serial_core.h> | 22 | #include <linux/serial_core.h> |
23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
24 | #include <linux/sched.h> | ||
24 | 25 | ||
25 | #include <asm/mach/arch.h> | 26 | #include <asm/mach/arch.h> |
26 | #include <asm/mach/map.h> | 27 | #include <asm/mach/map.h> |
diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c index af91fefef2c..d562670e1b0 100644 --- a/arch/arm/mach-s5pv210/clock.c +++ b/arch/arm/mach-s5pv210/clock.c | |||
@@ -173,11 +173,6 @@ static int s5pv210_clk_ip3_ctrl(struct clk *clk, int enable) | |||
173 | return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable); | 173 | return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable); |
174 | } | 174 | } |
175 | 175 | ||
176 | static int s5pv210_clk_ip4_ctrl(struct clk *clk, int enable) | ||
177 | { | ||
178 | return s5p_gatectrl(S5P_CLKGATE_IP4, clk, enable); | ||
179 | } | ||
180 | |||
181 | static int s5pv210_clk_mask0_ctrl(struct clk *clk, int enable) | 176 | static int s5pv210_clk_mask0_ctrl(struct clk *clk, int enable) |
182 | { | 177 | { |
183 | return s5p_gatectrl(S5P_CLK_SRC_MASK0, clk, enable); | 178 | return s5p_gatectrl(S5P_CLK_SRC_MASK0, clk, enable); |
@@ -281,6 +276,24 @@ static struct clk init_clocks_disable[] = { | |||
281 | .enable = s5pv210_clk_ip0_ctrl, | 276 | .enable = s5pv210_clk_ip0_ctrl, |
282 | .ctrlbit = (1<<29), | 277 | .ctrlbit = (1<<29), |
283 | }, { | 278 | }, { |
279 | .name = "fimc", | ||
280 | .id = 0, | ||
281 | .parent = &clk_hclk_dsys.clk, | ||
282 | .enable = s5pv210_clk_ip0_ctrl, | ||
283 | .ctrlbit = (1 << 24), | ||
284 | }, { | ||
285 | .name = "fimc", | ||
286 | .id = 1, | ||
287 | .parent = &clk_hclk_dsys.clk, | ||
288 | .enable = s5pv210_clk_ip0_ctrl, | ||
289 | .ctrlbit = (1 << 25), | ||
290 | }, { | ||
291 | .name = "fimc", | ||
292 | .id = 2, | ||
293 | .parent = &clk_hclk_dsys.clk, | ||
294 | .enable = s5pv210_clk_ip0_ctrl, | ||
295 | .ctrlbit = (1 << 26), | ||
296 | }, { | ||
284 | .name = "otg", | 297 | .name = "otg", |
285 | .id = -1, | 298 | .id = -1, |
286 | .parent = &clk_hclk_psys.clk, | 299 | .parent = &clk_hclk_psys.clk, |
@@ -357,7 +370,7 @@ static struct clk init_clocks_disable[] = { | |||
357 | .id = 1, | 370 | .id = 1, |
358 | .parent = &clk_pclk_psys.clk, | 371 | .parent = &clk_pclk_psys.clk, |
359 | .enable = s5pv210_clk_ip3_ctrl, | 372 | .enable = s5pv210_clk_ip3_ctrl, |
360 | .ctrlbit = (1<<8), | 373 | .ctrlbit = (1 << 10), |
361 | }, { | 374 | }, { |
362 | .name = "i2c", | 375 | .name = "i2c", |
363 | .id = 2, | 376 | .id = 2, |
diff --git a/arch/arm/mach-s5pv210/cpu.c b/arch/arm/mach-s5pv210/cpu.c index b9f4d677cf5..245b82b53df 100644 --- a/arch/arm/mach-s5pv210/cpu.c +++ b/arch/arm/mach-s5pv210/cpu.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/io.h> | 19 | #include <linux/io.h> |
20 | #include <linux/sysdev.h> | 20 | #include <linux/sysdev.h> |
21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
22 | #include <linux/sched.h> | ||
22 | 23 | ||
23 | #include <asm/mach/arch.h> | 24 | #include <asm/mach/arch.h> |
24 | #include <asm/mach/map.h> | 25 | #include <asm/mach/map.h> |
@@ -47,7 +48,7 @@ static struct map_desc s5pv210_iodesc[] __initdata = { | |||
47 | { | 48 | { |
48 | .virtual = (unsigned long)S5P_VA_SYSTIMER, | 49 | .virtual = (unsigned long)S5P_VA_SYSTIMER, |
49 | .pfn = __phys_to_pfn(S5PV210_PA_SYSTIMER), | 50 | .pfn = __phys_to_pfn(S5PV210_PA_SYSTIMER), |
50 | .length = SZ_1M, | 51 | .length = SZ_4K, |
51 | .type = MT_DEVICE, | 52 | .type = MT_DEVICE, |
52 | }, { | 53 | }, { |
53 | .virtual = (unsigned long)VA_VIC2, | 54 | .virtual = (unsigned long)VA_VIC2, |
diff --git a/arch/arm/mach-s5pv210/include/mach/vmalloc.h b/arch/arm/mach-s5pv210/include/mach/vmalloc.h index 58f515e0747..df9a2880832 100644 --- a/arch/arm/mach-s5pv210/include/mach/vmalloc.h +++ b/arch/arm/mach-s5pv210/include/mach/vmalloc.h | |||
@@ -17,6 +17,6 @@ | |||
17 | #ifndef __ASM_ARCH_VMALLOC_H | 17 | #ifndef __ASM_ARCH_VMALLOC_H |
18 | #define __ASM_ARCH_VMALLOC_H __FILE__ | 18 | #define __ASM_ARCH_VMALLOC_H __FILE__ |
19 | 19 | ||
20 | #define VMALLOC_END (0xE0000000) | 20 | #define VMALLOC_END (0xE0000000UL) |
21 | 21 | ||
22 | #endif /* __ASM_ARCH_VMALLOC_H */ | 22 | #endif /* __ASM_ARCH_VMALLOC_H */ |
diff --git a/arch/arm/mach-s5pv310/clock.c b/arch/arm/mach-s5pv310/clock.c index 77f2b4d85e6..26a0f03df8e 100644 --- a/arch/arm/mach-s5pv310/clock.c +++ b/arch/arm/mach-s5pv310/clock.c | |||
@@ -30,6 +30,16 @@ static struct clk clk_sclk_hdmi27m = { | |||
30 | .rate = 27000000, | 30 | .rate = 27000000, |
31 | }; | 31 | }; |
32 | 32 | ||
33 | static int s5pv310_clksrc_mask_peril0_ctrl(struct clk *clk, int enable) | ||
34 | { | ||
35 | return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL0, clk, enable); | ||
36 | } | ||
37 | |||
38 | static int s5pv310_clk_ip_peril_ctrl(struct clk *clk, int enable) | ||
39 | { | ||
40 | return s5p_gatectrl(S5P_CLKGATE_IP_PERIL, clk, enable); | ||
41 | } | ||
42 | |||
33 | /* Core list of CMU_CPU side */ | 43 | /* Core list of CMU_CPU side */ |
34 | 44 | ||
35 | static struct clksrc_clk clk_mout_apll = { | 45 | static struct clksrc_clk clk_mout_apll = { |
@@ -39,6 +49,14 @@ static struct clksrc_clk clk_mout_apll = { | |||
39 | }, | 49 | }, |
40 | .sources = &clk_src_apll, | 50 | .sources = &clk_src_apll, |
41 | .reg_src = { .reg = S5P_CLKSRC_CPU, .shift = 0, .size = 1 }, | 51 | .reg_src = { .reg = S5P_CLKSRC_CPU, .shift = 0, .size = 1 }, |
52 | }; | ||
53 | |||
54 | static struct clksrc_clk clk_sclk_apll = { | ||
55 | .clk = { | ||
56 | .name = "sclk_apll", | ||
57 | .id = -1, | ||
58 | .parent = &clk_mout_apll.clk, | ||
59 | }, | ||
42 | .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 24, .size = 3 }, | 60 | .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 24, .size = 3 }, |
43 | }; | 61 | }; |
44 | 62 | ||
@@ -61,7 +79,7 @@ static struct clksrc_clk clk_mout_mpll = { | |||
61 | }; | 79 | }; |
62 | 80 | ||
63 | static struct clk *clkset_moutcore_list[] = { | 81 | static struct clk *clkset_moutcore_list[] = { |
64 | [0] = &clk_mout_apll.clk, | 82 | [0] = &clk_sclk_apll.clk, |
65 | [1] = &clk_mout_mpll.clk, | 83 | [1] = &clk_mout_mpll.clk, |
66 | }; | 84 | }; |
67 | 85 | ||
@@ -154,7 +172,7 @@ static struct clksrc_clk clk_pclk_dbg = { | |||
154 | 172 | ||
155 | static struct clk *clkset_corebus_list[] = { | 173 | static struct clk *clkset_corebus_list[] = { |
156 | [0] = &clk_mout_mpll.clk, | 174 | [0] = &clk_mout_mpll.clk, |
157 | [1] = &clk_mout_apll.clk, | 175 | [1] = &clk_sclk_apll.clk, |
158 | }; | 176 | }; |
159 | 177 | ||
160 | static struct clksrc_sources clkset_mout_corebus = { | 178 | static struct clksrc_sources clkset_mout_corebus = { |
@@ -220,7 +238,7 @@ static struct clksrc_clk clk_pclk_acp = { | |||
220 | 238 | ||
221 | static struct clk *clkset_aclk_top_list[] = { | 239 | static struct clk *clkset_aclk_top_list[] = { |
222 | [0] = &clk_mout_mpll.clk, | 240 | [0] = &clk_mout_mpll.clk, |
223 | [1] = &clk_mout_apll.clk, | 241 | [1] = &clk_sclk_apll.clk, |
224 | }; | 242 | }; |
225 | 243 | ||
226 | static struct clksrc_sources clkset_aclk_200 = { | 244 | static struct clksrc_sources clkset_aclk_200 = { |
@@ -321,11 +339,6 @@ static struct clksrc_clk clk_sclk_vpll = { | |||
321 | .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 8, .size = 1 }, | 339 | .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 8, .size = 1 }, |
322 | }; | 340 | }; |
323 | 341 | ||
324 | static int s5pv310_clk_ip_peril_ctrl(struct clk *clk, int enable) | ||
325 | { | ||
326 | return s5p_gatectrl(S5P_CLKGATE_IP_PERIL, clk, enable); | ||
327 | } | ||
328 | |||
329 | static struct clk init_clocks_disable[] = { | 342 | static struct clk init_clocks_disable[] = { |
330 | { | 343 | { |
331 | .name = "timers", | 344 | .name = "timers", |
@@ -337,7 +350,37 @@ static struct clk init_clocks_disable[] = { | |||
337 | }; | 350 | }; |
338 | 351 | ||
339 | static struct clk init_clocks[] = { | 352 | static struct clk init_clocks[] = { |
340 | /* Nothing here yet */ | 353 | { |
354 | .name = "uart", | ||
355 | .id = 0, | ||
356 | .enable = s5pv310_clk_ip_peril_ctrl, | ||
357 | .ctrlbit = (1 << 0), | ||
358 | }, { | ||
359 | .name = "uart", | ||
360 | .id = 1, | ||
361 | .enable = s5pv310_clk_ip_peril_ctrl, | ||
362 | .ctrlbit = (1 << 1), | ||
363 | }, { | ||
364 | .name = "uart", | ||
365 | .id = 2, | ||
366 | .enable = s5pv310_clk_ip_peril_ctrl, | ||
367 | .ctrlbit = (1 << 2), | ||
368 | }, { | ||
369 | .name = "uart", | ||
370 | .id = 3, | ||
371 | .enable = s5pv310_clk_ip_peril_ctrl, | ||
372 | .ctrlbit = (1 << 3), | ||
373 | }, { | ||
374 | .name = "uart", | ||
375 | .id = 4, | ||
376 | .enable = s5pv310_clk_ip_peril_ctrl, | ||
377 | .ctrlbit = (1 << 4), | ||
378 | }, { | ||
379 | .name = "uart", | ||
380 | .id = 5, | ||
381 | .enable = s5pv310_clk_ip_peril_ctrl, | ||
382 | .ctrlbit = (1 << 5), | ||
383 | } | ||
341 | }; | 384 | }; |
342 | 385 | ||
343 | static struct clk *clkset_group_list[] = { | 386 | static struct clk *clkset_group_list[] = { |
@@ -359,8 +402,8 @@ static struct clksrc_clk clksrcs[] = { | |||
359 | .clk = { | 402 | .clk = { |
360 | .name = "uclk1", | 403 | .name = "uclk1", |
361 | .id = 0, | 404 | .id = 0, |
405 | .enable = s5pv310_clksrc_mask_peril0_ctrl, | ||
362 | .ctrlbit = (1 << 0), | 406 | .ctrlbit = (1 << 0), |
363 | .enable = s5pv310_clk_ip_peril_ctrl, | ||
364 | }, | 407 | }, |
365 | .sources = &clkset_group, | 408 | .sources = &clkset_group, |
366 | .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 0, .size = 4 }, | 409 | .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 0, .size = 4 }, |
@@ -369,8 +412,8 @@ static struct clksrc_clk clksrcs[] = { | |||
369 | .clk = { | 412 | .clk = { |
370 | .name = "uclk1", | 413 | .name = "uclk1", |
371 | .id = 1, | 414 | .id = 1, |
372 | .enable = s5pv310_clk_ip_peril_ctrl, | 415 | .enable = s5pv310_clksrc_mask_peril0_ctrl, |
373 | .ctrlbit = (1 << 1), | 416 | .ctrlbit = (1 << 4), |
374 | }, | 417 | }, |
375 | .sources = &clkset_group, | 418 | .sources = &clkset_group, |
376 | .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 4, .size = 4 }, | 419 | .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 4, .size = 4 }, |
@@ -379,8 +422,8 @@ static struct clksrc_clk clksrcs[] = { | |||
379 | .clk = { | 422 | .clk = { |
380 | .name = "uclk1", | 423 | .name = "uclk1", |
381 | .id = 2, | 424 | .id = 2, |
382 | .enable = s5pv310_clk_ip_peril_ctrl, | 425 | .enable = s5pv310_clksrc_mask_peril0_ctrl, |
383 | .ctrlbit = (1 << 2), | 426 | .ctrlbit = (1 << 8), |
384 | }, | 427 | }, |
385 | .sources = &clkset_group, | 428 | .sources = &clkset_group, |
386 | .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 8, .size = 4 }, | 429 | .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 8, .size = 4 }, |
@@ -389,8 +432,8 @@ static struct clksrc_clk clksrcs[] = { | |||
389 | .clk = { | 432 | .clk = { |
390 | .name = "uclk1", | 433 | .name = "uclk1", |
391 | .id = 3, | 434 | .id = 3, |
392 | .enable = s5pv310_clk_ip_peril_ctrl, | 435 | .enable = s5pv310_clksrc_mask_peril0_ctrl, |
393 | .ctrlbit = (1 << 3), | 436 | .ctrlbit = (1 << 12), |
394 | }, | 437 | }, |
395 | .sources = &clkset_group, | 438 | .sources = &clkset_group, |
396 | .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 12, .size = 4 }, | 439 | .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 12, .size = 4 }, |
@@ -399,7 +442,7 @@ static struct clksrc_clk clksrcs[] = { | |||
399 | .clk = { | 442 | .clk = { |
400 | .name = "sclk_pwm", | 443 | .name = "sclk_pwm", |
401 | .id = -1, | 444 | .id = -1, |
402 | .enable = s5pv310_clk_ip_peril_ctrl, | 445 | .enable = s5pv310_clksrc_mask_peril0_ctrl, |
403 | .ctrlbit = (1 << 24), | 446 | .ctrlbit = (1 << 24), |
404 | }, | 447 | }, |
405 | .sources = &clkset_group, | 448 | .sources = &clkset_group, |
@@ -411,6 +454,7 @@ static struct clksrc_clk clksrcs[] = { | |||
411 | /* Clock initialization code */ | 454 | /* Clock initialization code */ |
412 | static struct clksrc_clk *sysclks[] = { | 455 | static struct clksrc_clk *sysclks[] = { |
413 | &clk_mout_apll, | 456 | &clk_mout_apll, |
457 | &clk_sclk_apll, | ||
414 | &clk_mout_epll, | 458 | &clk_mout_epll, |
415 | &clk_mout_mpll, | 459 | &clk_mout_mpll, |
416 | &clk_moutcore, | 460 | &clk_moutcore, |
@@ -470,11 +514,11 @@ void __init_or_cpufreq s5pv310_setup_clocks(void) | |||
470 | apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON0), pll_4508); | 514 | apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON0), pll_4508); |
471 | mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON0), pll_4508); | 515 | mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON0), pll_4508); |
472 | epll = s5p_get_pll46xx(xtal, __raw_readl(S5P_EPLL_CON0), | 516 | epll = s5p_get_pll46xx(xtal, __raw_readl(S5P_EPLL_CON0), |
473 | __raw_readl(S5P_EPLL_CON1), pll_4500); | 517 | __raw_readl(S5P_EPLL_CON1), pll_4600); |
474 | 518 | ||
475 | vpllsrc = clk_get_rate(&clk_vpllsrc.clk); | 519 | vpllsrc = clk_get_rate(&clk_vpllsrc.clk); |
476 | vpll = s5p_get_pll46xx(vpllsrc, __raw_readl(S5P_VPLL_CON0), | 520 | vpll = s5p_get_pll46xx(vpllsrc, __raw_readl(S5P_VPLL_CON0), |
477 | __raw_readl(S5P_VPLL_CON1), pll_4502); | 521 | __raw_readl(S5P_VPLL_CON1), pll_4650); |
478 | 522 | ||
479 | clk_fout_apll.rate = apll; | 523 | clk_fout_apll.rate = apll; |
480 | clk_fout_mpll.rate = mpll; | 524 | clk_fout_mpll.rate = mpll; |
diff --git a/arch/arm/mach-s5pv310/cpu.c b/arch/arm/mach-s5pv310/cpu.c index 196c9f12ed8..e5b261a99ab 100644 --- a/arch/arm/mach-s5pv310/cpu.c +++ b/arch/arm/mach-s5pv310/cpu.c | |||
@@ -45,6 +45,16 @@ static struct map_desc s5pv310_iodesc[] __initdata = { | |||
45 | .pfn = __phys_to_pfn(S5PV310_PA_L2CC), | 45 | .pfn = __phys_to_pfn(S5PV310_PA_L2CC), |
46 | .length = SZ_4K, | 46 | .length = SZ_4K, |
47 | .type = MT_DEVICE, | 47 | .type = MT_DEVICE, |
48 | }, { | ||
49 | .virtual = (unsigned long)S5P_VA_SYSRAM, | ||
50 | .pfn = __phys_to_pfn(S5PV310_PA_SYSRAM), | ||
51 | .length = SZ_4K, | ||
52 | .type = MT_DEVICE, | ||
53 | }, { | ||
54 | .virtual = (unsigned long)S5P_VA_CMU, | ||
55 | .pfn = __phys_to_pfn(S5PV310_PA_CMU), | ||
56 | .length = SZ_128K, | ||
57 | .type = MT_DEVICE, | ||
48 | }, | 58 | }, |
49 | }; | 59 | }; |
50 | 60 | ||
diff --git a/arch/arm/mach-s5pv310/include/mach/irqs.h b/arch/arm/mach-s5pv310/include/mach/irqs.h index 56885ca3773..4cdedda6e65 100644 --- a/arch/arm/mach-s5pv310/include/mach/irqs.h +++ b/arch/arm/mach-s5pv310/include/mach/irqs.h | |||
@@ -15,12 +15,14 @@ | |||
15 | 15 | ||
16 | #include <plat/irqs.h> | 16 | #include <plat/irqs.h> |
17 | 17 | ||
18 | /* Private Peripheral Interrupt */ | 18 | /* PPI: Private Peripheral Interrupt */ |
19 | |||
19 | #define IRQ_PPI(x) S5P_IRQ(x+16) | 20 | #define IRQ_PPI(x) S5P_IRQ(x+16) |
20 | 21 | ||
21 | #define IRQ_LOCALTIMER IRQ_PPI(13) | 22 | #define IRQ_LOCALTIMER IRQ_PPI(13) |
22 | 23 | ||
23 | /* Shared Peripheral Interrupt */ | 24 | /* SPI: Shared Peripheral Interrupt */ |
25 | |||
24 | #define IRQ_SPI(x) S5P_IRQ(x+32) | 26 | #define IRQ_SPI(x) S5P_IRQ(x+32) |
25 | 27 | ||
26 | #define IRQ_EINT0 IRQ_SPI(40) | 28 | #define IRQ_EINT0 IRQ_SPI(40) |
@@ -36,7 +38,7 @@ | |||
36 | #define IRQ_PCIE IRQ_SPI(50) | 38 | #define IRQ_PCIE IRQ_SPI(50) |
37 | #define IRQ_SYSTEM_TIMER IRQ_SPI(51) | 39 | #define IRQ_SYSTEM_TIMER IRQ_SPI(51) |
38 | #define IRQ_MFC IRQ_SPI(52) | 40 | #define IRQ_MFC IRQ_SPI(52) |
39 | #define IRQ_WTD IRQ_SPI(53) | 41 | #define IRQ_WDT IRQ_SPI(53) |
40 | #define IRQ_AUDIO_SS IRQ_SPI(54) | 42 | #define IRQ_AUDIO_SS IRQ_SPI(54) |
41 | #define IRQ_AC97 IRQ_SPI(55) | 43 | #define IRQ_AC97 IRQ_SPI(55) |
42 | #define IRQ_SPDIF IRQ_SPI(56) | 44 | #define IRQ_SPDIF IRQ_SPI(56) |
@@ -67,8 +69,9 @@ | |||
67 | #define IRQ_IIC COMBINER_IRQ(27, 0) | 69 | #define IRQ_IIC COMBINER_IRQ(27, 0) |
68 | 70 | ||
69 | /* Set the default NR_IRQS */ | 71 | /* Set the default NR_IRQS */ |
72 | |||
70 | #define NR_IRQS COMBINER_IRQ(MAX_COMBINER_NR, 0) | 73 | #define NR_IRQS COMBINER_IRQ(MAX_COMBINER_NR, 0) |
71 | 74 | ||
72 | #define MAX_COMBINER_NR 39 | 75 | #define MAX_COMBINER_NR 39 |
73 | 76 | ||
74 | #endif /* ASM_ARCH_IRQS_H */ | 77 | #endif /* __ASM_ARCH_IRQS_H */ |
diff --git a/arch/arm/mach-s5pv310/include/mach/map.h b/arch/arm/mach-s5pv310/include/mach/map.h index 87697c9fca5..213e1101a3b 100644 --- a/arch/arm/mach-s5pv310/include/mach/map.h +++ b/arch/arm/mach-s5pv310/include/mach/map.h | |||
@@ -23,12 +23,16 @@ | |||
23 | 23 | ||
24 | #include <plat/map-s5p.h> | 24 | #include <plat/map-s5p.h> |
25 | 25 | ||
26 | #define S5PV310_PA_SYSRAM (0x02025000) | ||
27 | |||
26 | #define S5PV310_PA_CHIPID (0x10000000) | 28 | #define S5PV310_PA_CHIPID (0x10000000) |
27 | #define S5P_PA_CHIPID S5PV310_PA_CHIPID | 29 | #define S5P_PA_CHIPID S5PV310_PA_CHIPID |
28 | 30 | ||
29 | #define S5PV310_PA_SYSCON (0x10020000) | 31 | #define S5PV310_PA_SYSCON (0x10020000) |
30 | #define S5P_PA_SYSCON S5PV310_PA_SYSCON | 32 | #define S5P_PA_SYSCON S5PV310_PA_SYSCON |
31 | 33 | ||
34 | #define S5PV310_PA_CMU (0x10030000) | ||
35 | |||
32 | #define S5PV310_PA_WATCHDOG (0x10060000) | 36 | #define S5PV310_PA_WATCHDOG (0x10060000) |
33 | 37 | ||
34 | #define S5PV310_PA_COMBINER (0x10448000) | 38 | #define S5PV310_PA_COMBINER (0x10448000) |
@@ -39,8 +43,12 @@ | |||
39 | #define S5PV310_PA_GIC_DIST (0x10501000) | 43 | #define S5PV310_PA_GIC_DIST (0x10501000) |
40 | #define S5PV310_PA_L2CC (0x10502000) | 44 | #define S5PV310_PA_L2CC (0x10502000) |
41 | 45 | ||
42 | #define S5PV310_PA_GPIO (0x11000000) | 46 | #define S5PV310_PA_GPIO1 (0x11400000) |
43 | #define S5P_PA_GPIO S5PV310_PA_GPIO | 47 | #define S5PV310_PA_GPIO2 (0x11000000) |
48 | #define S5PV310_PA_GPIO3 (0x03860000) | ||
49 | #define S5P_PA_GPIO S5PV310_PA_GPIO1 | ||
50 | |||
51 | #define S5PV310_PA_HSMMC(x) (0x12510000 + ((x) * 0x10000)) | ||
44 | 52 | ||
45 | #define S5PV310_PA_UART (0x13800000) | 53 | #define S5PV310_PA_UART (0x13800000) |
46 | 54 | ||
@@ -63,6 +71,10 @@ | |||
63 | 71 | ||
64 | /* compatibiltiy defines. */ | 72 | /* compatibiltiy defines. */ |
65 | #define S3C_PA_UART S5PV310_PA_UART | 73 | #define S3C_PA_UART S5PV310_PA_UART |
74 | #define S3C_PA_HSMMC0 S5PV310_PA_HSMMC(0) | ||
75 | #define S3C_PA_HSMMC1 S5PV310_PA_HSMMC(1) | ||
76 | #define S3C_PA_HSMMC2 S5PV310_PA_HSMMC(2) | ||
77 | #define S3C_PA_HSMMC3 S5PV310_PA_HSMMC(3) | ||
66 | #define S3C_PA_IIC S5PV310_PA_IIC0 | 78 | #define S3C_PA_IIC S5PV310_PA_IIC0 |
67 | #define S3C_PA_WDT S5PV310_PA_WATCHDOG | 79 | #define S3C_PA_WDT S5PV310_PA_WATCHDOG |
68 | 80 | ||
diff --git a/arch/arm/mach-s5pv310/include/mach/regs-clock.h b/arch/arm/mach-s5pv310/include/mach/regs-clock.h index 59e3a7e94d8..4013553cd9b 100644 --- a/arch/arm/mach-s5pv310/include/mach/regs-clock.h +++ b/arch/arm/mach-s5pv310/include/mach/regs-clock.h | |||
@@ -15,48 +15,49 @@ | |||
15 | 15 | ||
16 | #include <mach/map.h> | 16 | #include <mach/map.h> |
17 | 17 | ||
18 | #define S5P_CLKREG(x) (S3C_VA_SYS + (x)) | 18 | #define S5P_CLKREG(x) (S5P_VA_CMU + (x)) |
19 | 19 | ||
20 | #define S5P_INFORM0 S5P_CLKREG(0x800) | 20 | #define S5P_INFORM0 S5P_CLKREG(0x800) |
21 | 21 | ||
22 | #define S5P_EPLL_CON0 S5P_CLKREG(0x1C110) | 22 | #define S5P_EPLL_CON0 S5P_CLKREG(0x0C110) |
23 | #define S5P_EPLL_CON1 S5P_CLKREG(0x1C114) | 23 | #define S5P_EPLL_CON1 S5P_CLKREG(0x0C114) |
24 | #define S5P_VPLL_CON0 S5P_CLKREG(0x1C120) | 24 | #define S5P_VPLL_CON0 S5P_CLKREG(0x0C120) |
25 | #define S5P_VPLL_CON1 S5P_CLKREG(0x1C124) | 25 | #define S5P_VPLL_CON1 S5P_CLKREG(0x0C124) |
26 | 26 | ||
27 | #define S5P_CLKSRC_TOP0 S5P_CLKREG(0x1C210) | 27 | #define S5P_CLKSRC_TOP0 S5P_CLKREG(0x0C210) |
28 | #define S5P_CLKSRC_TOP1 S5P_CLKREG(0x1C214) | 28 | #define S5P_CLKSRC_TOP1 S5P_CLKREG(0x0C214) |
29 | 29 | ||
30 | #define S5P_CLKSRC_PERIL0 S5P_CLKREG(0x1C250) | 30 | #define S5P_CLKSRC_PERIL0 S5P_CLKREG(0x0C250) |
31 | 31 | ||
32 | #define S5P_CLKDIV_TOP S5P_CLKREG(0x1C510) | 32 | #define S5P_CLKDIV_TOP S5P_CLKREG(0x0C510) |
33 | 33 | ||
34 | #define S5P_CLKDIV_PERIL0 S5P_CLKREG(0x1C550) | 34 | #define S5P_CLKDIV_PERIL0 S5P_CLKREG(0x0C550) |
35 | #define S5P_CLKDIV_PERIL1 S5P_CLKREG(0x1C554) | 35 | #define S5P_CLKDIV_PERIL1 S5P_CLKREG(0x0C554) |
36 | #define S5P_CLKDIV_PERIL2 S5P_CLKREG(0x1C558) | 36 | #define S5P_CLKDIV_PERIL2 S5P_CLKREG(0x0C558) |
37 | #define S5P_CLKDIV_PERIL3 S5P_CLKREG(0x1C55C) | 37 | #define S5P_CLKDIV_PERIL3 S5P_CLKREG(0x0C55C) |
38 | #define S5P_CLKDIV_PERIL4 S5P_CLKREG(0x1C560) | 38 | #define S5P_CLKDIV_PERIL4 S5P_CLKREG(0x0C560) |
39 | #define S5P_CLKDIV_PERIL5 S5P_CLKREG(0x1C564) | 39 | #define S5P_CLKDIV_PERIL5 S5P_CLKREG(0x0C564) |
40 | 40 | ||
41 | #define S5P_CLKGATE_IP_PERIL S5P_CLKREG(0x1C950) | 41 | #define S5P_CLKSRC_MASK_PERIL0 S5P_CLKREG(0x0C350) |
42 | 42 | ||
43 | #define S5P_CLKSRC_CORE S5P_CLKREG(0x20200) | 43 | #define S5P_CLKGATE_IP_PERIL S5P_CLKREG(0x0C950) |
44 | 44 | ||
45 | #define S5P_CLKDIV_CORE0 S5P_CLKREG(0x20500) | 45 | #define S5P_CLKSRC_CORE S5P_CLKREG(0x10200) |
46 | #define S5P_CLKDIV_CORE0 S5P_CLKREG(0x10500) | ||
46 | 47 | ||
47 | #define S5P_APLL_LOCK S5P_CLKREG(0x24000) | 48 | #define S5P_APLL_LOCK S5P_CLKREG(0x14000) |
48 | #define S5P_MPLL_LOCK S5P_CLKREG(0x24004) | 49 | #define S5P_MPLL_LOCK S5P_CLKREG(0x14004) |
49 | #define S5P_APLL_CON0 S5P_CLKREG(0x24100) | 50 | #define S5P_APLL_CON0 S5P_CLKREG(0x14100) |
50 | #define S5P_APLL_CON1 S5P_CLKREG(0x24104) | 51 | #define S5P_APLL_CON1 S5P_CLKREG(0x14104) |
51 | #define S5P_MPLL_CON0 S5P_CLKREG(0x24108) | 52 | #define S5P_MPLL_CON0 S5P_CLKREG(0x14108) |
52 | #define S5P_MPLL_CON1 S5P_CLKREG(0x2410C) | 53 | #define S5P_MPLL_CON1 S5P_CLKREG(0x1410C) |
53 | 54 | ||
54 | #define S5P_CLKSRC_CPU S5P_CLKREG(0x24200) | 55 | #define S5P_CLKSRC_CPU S5P_CLKREG(0x14200) |
55 | #define S5P_CLKMUX_STATCPU S5P_CLKREG(0x24400) | 56 | #define S5P_CLKMUX_STATCPU S5P_CLKREG(0x14400) |
56 | 57 | ||
57 | #define S5P_CLKDIV_CPU S5P_CLKREG(0x24500) | 58 | #define S5P_CLKDIV_CPU S5P_CLKREG(0x14500) |
58 | #define S5P_CLKDIV_STATCPU S5P_CLKREG(0x24600) | 59 | #define S5P_CLKDIV_STATCPU S5P_CLKREG(0x14600) |
59 | 60 | ||
60 | #define S5P_CLKGATE_SCLKCPU S5P_CLKREG(0x24800) | 61 | #define S5P_CLKGATE_SCLKCPU S5P_CLKREG(0x14800) |
61 | 62 | ||
62 | #endif /* __ASM_ARCH_REGS_CLOCK_H */ | 63 | #endif /* __ASM_ARCH_REGS_CLOCK_H */ |
diff --git a/arch/arm/mach-s5pv310/include/mach/vmalloc.h b/arch/arm/mach-s5pv310/include/mach/vmalloc.h index 3f565ebb7da..256f221edf3 100644 --- a/arch/arm/mach-s5pv310/include/mach/vmalloc.h +++ b/arch/arm/mach-s5pv310/include/mach/vmalloc.h | |||
@@ -17,6 +17,6 @@ | |||
17 | #ifndef __ASM_ARCH_VMALLOC_H | 17 | #ifndef __ASM_ARCH_VMALLOC_H |
18 | #define __ASM_ARCH_VMALLOC_H __FILE__ | 18 | #define __ASM_ARCH_VMALLOC_H __FILE__ |
19 | 19 | ||
20 | #define VMALLOC_END (0xF0000000) | 20 | #define VMALLOC_END (0xF0000000UL) |
21 | 21 | ||
22 | #endif /* __ASM_ARCH_VMALLOC_H */ | 22 | #endif /* __ASM_ARCH_VMALLOC_H */ |
diff --git a/arch/arm/mach-s5pv310/platsmp.c b/arch/arm/mach-s5pv310/platsmp.c index fe9469abd00..d357c198ede 100644 --- a/arch/arm/mach-s5pv310/platsmp.c +++ b/arch/arm/mach-s5pv310/platsmp.c | |||
@@ -187,6 +187,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
187 | * until it receives a soft interrupt, and then the | 187 | * until it receives a soft interrupt, and then the |
188 | * secondary CPU branches to this address. | 188 | * secondary CPU branches to this address. |
189 | */ | 189 | */ |
190 | __raw_writel(BSYM(virt_to_phys(s5pv310_secondary_startup)), S5P_INFORM0); | 190 | __raw_writel(BSYM(virt_to_phys(s5pv310_secondary_startup)), S5P_VA_SYSRAM); |
191 | } | 191 | } |
192 | } | 192 | } |
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile index 5e16b4c6922..ae416fe7daf 100644 --- a/arch/arm/mach-shmobile/Makefile +++ b/arch/arm/mach-shmobile/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | # Common objects | 5 | # Common objects |
6 | obj-y := timer.o console.o clock.o | 6 | obj-y := timer.o console.o clock.o pm_runtime.o |
7 | 7 | ||
8 | # CPU objects | 8 | # CPU objects |
9 | obj-$(CONFIG_ARCH_SH7367) += setup-sh7367.o clock-sh7367.o intc-sh7367.o | 9 | obj-$(CONFIG_ARCH_SH7367) += setup-sh7367.o clock-sh7367.o intc-sh7367.o |
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index 23d472f9525..95935c83c30 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
26 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
27 | #include <linux/mfd/sh_mobile_sdhi.h> | 27 | #include <linux/mfd/sh_mobile_sdhi.h> |
28 | #include <linux/mfd/tmio.h> | ||
28 | #include <linux/mmc/host.h> | 29 | #include <linux/mmc/host.h> |
29 | #include <linux/mtd/mtd.h> | 30 | #include <linux/mtd/mtd.h> |
30 | #include <linux/mtd/partitions.h> | 31 | #include <linux/mtd/partitions.h> |
@@ -39,6 +40,7 @@ | |||
39 | #include <linux/sh_clk.h> | 40 | #include <linux/sh_clk.h> |
40 | #include <linux/gpio.h> | 41 | #include <linux/gpio.h> |
41 | #include <linux/input.h> | 42 | #include <linux/input.h> |
43 | #include <linux/leds.h> | ||
42 | #include <linux/input/sh_keysc.h> | 44 | #include <linux/input/sh_keysc.h> |
43 | #include <linux/usb/r8a66597.h> | 45 | #include <linux/usb/r8a66597.h> |
44 | 46 | ||
@@ -307,6 +309,7 @@ static struct sh_mobile_sdhi_info sdhi1_info = { | |||
307 | .dma_slave_tx = SHDMA_SLAVE_SDHI1_TX, | 309 | .dma_slave_tx = SHDMA_SLAVE_SDHI1_TX, |
308 | .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX, | 310 | .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX, |
309 | .tmio_ocr_mask = MMC_VDD_165_195, | 311 | .tmio_ocr_mask = MMC_VDD_165_195, |
312 | .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE, | ||
310 | }; | 313 | }; |
311 | 314 | ||
312 | static struct resource sdhi1_resources[] = { | 315 | static struct resource sdhi1_resources[] = { |
@@ -558,7 +561,7 @@ static struct resource fsi_resources[] = { | |||
558 | 561 | ||
559 | static struct platform_device fsi_device = { | 562 | static struct platform_device fsi_device = { |
560 | .name = "sh_fsi2", | 563 | .name = "sh_fsi2", |
561 | .id = 0, | 564 | .id = -1, |
562 | .num_resources = ARRAY_SIZE(fsi_resources), | 565 | .num_resources = ARRAY_SIZE(fsi_resources), |
563 | .resource = fsi_resources, | 566 | .resource = fsi_resources, |
564 | .dev = { | 567 | .dev = { |
@@ -650,7 +653,44 @@ static struct platform_device hdmi_device = { | |||
650 | }, | 653 | }, |
651 | }; | 654 | }; |
652 | 655 | ||
656 | static struct gpio_led ap4evb_leds[] = { | ||
657 | { | ||
658 | .name = "led4", | ||
659 | .gpio = GPIO_PORT185, | ||
660 | .default_state = LEDS_GPIO_DEFSTATE_ON, | ||
661 | }, | ||
662 | { | ||
663 | .name = "led2", | ||
664 | .gpio = GPIO_PORT186, | ||
665 | .default_state = LEDS_GPIO_DEFSTATE_ON, | ||
666 | }, | ||
667 | { | ||
668 | .name = "led3", | ||
669 | .gpio = GPIO_PORT187, | ||
670 | .default_state = LEDS_GPIO_DEFSTATE_ON, | ||
671 | }, | ||
672 | { | ||
673 | .name = "led1", | ||
674 | .gpio = GPIO_PORT188, | ||
675 | .default_state = LEDS_GPIO_DEFSTATE_ON, | ||
676 | } | ||
677 | }; | ||
678 | |||
679 | static struct gpio_led_platform_data ap4evb_leds_pdata = { | ||
680 | .num_leds = ARRAY_SIZE(ap4evb_leds), | ||
681 | .leds = ap4evb_leds, | ||
682 | }; | ||
683 | |||
684 | static struct platform_device leds_device = { | ||
685 | .name = "leds-gpio", | ||
686 | .id = 0, | ||
687 | .dev = { | ||
688 | .platform_data = &ap4evb_leds_pdata, | ||
689 | }, | ||
690 | }; | ||
691 | |||
653 | static struct platform_device *ap4evb_devices[] __initdata = { | 692 | static struct platform_device *ap4evb_devices[] __initdata = { |
693 | &leds_device, | ||
654 | &nor_flash_device, | 694 | &nor_flash_device, |
655 | &smc911x_device, | 695 | &smc911x_device, |
656 | &sdhi0_device, | 696 | &sdhi0_device, |
@@ -840,20 +880,6 @@ static void __init ap4evb_init(void) | |||
840 | gpio_request(GPIO_FN_CS5A, NULL); | 880 | gpio_request(GPIO_FN_CS5A, NULL); |
841 | gpio_request(GPIO_FN_IRQ6_39, NULL); | 881 | gpio_request(GPIO_FN_IRQ6_39, NULL); |
842 | 882 | ||
843 | /* enable LED 1 - 4 */ | ||
844 | gpio_request(GPIO_PORT185, NULL); | ||
845 | gpio_request(GPIO_PORT186, NULL); | ||
846 | gpio_request(GPIO_PORT187, NULL); | ||
847 | gpio_request(GPIO_PORT188, NULL); | ||
848 | gpio_direction_output(GPIO_PORT185, 1); | ||
849 | gpio_direction_output(GPIO_PORT186, 1); | ||
850 | gpio_direction_output(GPIO_PORT187, 1); | ||
851 | gpio_direction_output(GPIO_PORT188, 1); | ||
852 | gpio_export(GPIO_PORT185, 0); | ||
853 | gpio_export(GPIO_PORT186, 0); | ||
854 | gpio_export(GPIO_PORT187, 0); | ||
855 | gpio_export(GPIO_PORT188, 0); | ||
856 | |||
857 | /* enable Debug switch (S6) */ | 883 | /* enable Debug switch (S6) */ |
858 | gpio_request(GPIO_PORT32, NULL); | 884 | gpio_request(GPIO_PORT32, NULL); |
859 | gpio_request(GPIO_PORT33, NULL); | 885 | gpio_request(GPIO_PORT33, NULL); |
diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c index fb4e9b1d788..759468992ad 100644 --- a/arch/arm/mach-shmobile/clock-sh7372.c +++ b/arch/arm/mach-shmobile/clock-sh7372.c | |||
@@ -286,7 +286,6 @@ static struct clk_ops pllc2_clk_ops = { | |||
286 | 286 | ||
287 | struct clk pllc2_clk = { | 287 | struct clk pllc2_clk = { |
288 | .ops = &pllc2_clk_ops, | 288 | .ops = &pllc2_clk_ops, |
289 | .flags = CLK_ENABLE_ON_INIT, | ||
290 | .parent = &extal1_div2_clk, | 289 | .parent = &extal1_div2_clk, |
291 | .freq_table = pllc2_freq_table, | 290 | .freq_table = pllc2_freq_table, |
292 | .parent_table = pllc2_parent, | 291 | .parent_table = pllc2_parent, |
@@ -395,7 +394,7 @@ static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = { | |||
395 | 394 | ||
396 | enum { MSTP001, | 395 | enum { MSTP001, |
397 | MSTP131, MSTP130, | 396 | MSTP131, MSTP130, |
398 | MSTP129, MSTP128, | 397 | MSTP129, MSTP128, MSTP127, MSTP126, |
399 | MSTP118, MSTP117, MSTP116, | 398 | MSTP118, MSTP117, MSTP116, |
400 | MSTP106, MSTP101, MSTP100, | 399 | MSTP106, MSTP101, MSTP100, |
401 | MSTP223, | 400 | MSTP223, |
@@ -413,6 +412,8 @@ static struct clk mstp_clks[MSTP_NR] = { | |||
413 | [MSTP130] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 30, 0), /* VEU2 */ | 412 | [MSTP130] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 30, 0), /* VEU2 */ |
414 | [MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* VEU1 */ | 413 | [MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* VEU1 */ |
415 | [MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* VEU0 */ | 414 | [MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* VEU0 */ |
415 | [MSTP127] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 27, 0), /* CEU */ | ||
416 | [MSTP126] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 26, 0), /* CSI2 */ | ||
416 | [MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX */ | 417 | [MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX */ |
417 | [MSTP117] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */ | 418 | [MSTP117] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */ |
418 | [MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */ | 419 | [MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */ |
@@ -428,7 +429,7 @@ static struct clk mstp_clks[MSTP_NR] = { | |||
428 | [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */ | 429 | [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */ |
429 | [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */ | 430 | [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */ |
430 | [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */ | 431 | [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */ |
431 | [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, CLK_ENABLE_ON_INIT), /* FSIA */ | 432 | [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, 0), /* FSIA */ |
432 | [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */ | 433 | [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */ |
433 | [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */ | 434 | [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */ |
434 | [MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */ | 435 | [MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */ |
@@ -498,6 +499,8 @@ static struct clk_lookup lookups[] = { | |||
498 | CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */ | 499 | CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */ |
499 | CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[MSTP129]), /* VEU1 */ | 500 | CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[MSTP129]), /* VEU1 */ |
500 | CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[MSTP128]), /* VEU0 */ | 501 | CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[MSTP128]), /* VEU0 */ |
502 | CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU */ | ||
503 | CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]), /* CSI2 */ | ||
501 | CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */ | 504 | CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */ |
502 | CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */ | 505 | CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */ |
503 | CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */ | 506 | CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */ |
diff --git a/arch/arm/mach-shmobile/clock.c b/arch/arm/mach-shmobile/clock.c index b7c705a213a..6b7c7c42bc8 100644 --- a/arch/arm/mach-shmobile/clock.c +++ b/arch/arm/mach-shmobile/clock.c | |||
@@ -1,8 +1,10 @@ | |||
1 | /* | 1 | /* |
2 | * SH-Mobile Timer | 2 | * SH-Mobile Clock Framework |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Magnus Damm | 4 | * Copyright (C) 2010 Magnus Damm |
5 | * | 5 | * |
6 | * Used together with arch/arm/common/clkdev.c and drivers/sh/clk.c. | ||
7 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
8 | * the Free Software Foundation; version 2 of the License. | 10 | * the Free Software Foundation; version 2 of the License. |
diff --git a/arch/arm/mach-shmobile/pm_runtime.c b/arch/arm/mach-shmobile/pm_runtime.c new file mode 100644 index 00000000000..94912d3944d --- /dev/null +++ b/arch/arm/mach-shmobile/pm_runtime.c | |||
@@ -0,0 +1,169 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-shmobile/pm_runtime.c | ||
3 | * | ||
4 | * Runtime PM support code for SuperH Mobile ARM | ||
5 | * | ||
6 | * Copyright (C) 2009-2010 Magnus Damm | ||
7 | * | ||
8 | * This file is subject to the terms and conditions of the GNU General Public | ||
9 | * License. See the file "COPYING" in the main directory of this archive | ||
10 | * for more details. | ||
11 | */ | ||
12 | |||
13 | #include <linux/init.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/io.h> | ||
16 | #include <linux/pm_runtime.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/clk.h> | ||
19 | #include <linux/sh_clk.h> | ||
20 | #include <linux/bitmap.h> | ||
21 | |||
22 | #ifdef CONFIG_PM_RUNTIME | ||
23 | #define BIT_ONCE 0 | ||
24 | #define BIT_ACTIVE 1 | ||
25 | #define BIT_CLK_ENABLED 2 | ||
26 | |||
27 | struct pm_runtime_data { | ||
28 | unsigned long flags; | ||
29 | struct clk *clk; | ||
30 | }; | ||
31 | |||
32 | static void __devres_release(struct device *dev, void *res) | ||
33 | { | ||
34 | struct pm_runtime_data *prd = res; | ||
35 | |||
36 | dev_dbg(dev, "__devres_release()\n"); | ||
37 | |||
38 | if (test_bit(BIT_CLK_ENABLED, &prd->flags)) | ||
39 | clk_disable(prd->clk); | ||
40 | |||
41 | if (test_bit(BIT_ACTIVE, &prd->flags)) | ||
42 | clk_put(prd->clk); | ||
43 | } | ||
44 | |||
45 | static struct pm_runtime_data *__to_prd(struct device *dev) | ||
46 | { | ||
47 | return devres_find(dev, __devres_release, NULL, NULL); | ||
48 | } | ||
49 | |||
50 | static void platform_pm_runtime_init(struct device *dev, | ||
51 | struct pm_runtime_data *prd) | ||
52 | { | ||
53 | if (prd && !test_and_set_bit(BIT_ONCE, &prd->flags)) { | ||
54 | prd->clk = clk_get(dev, NULL); | ||
55 | if (!IS_ERR(prd->clk)) { | ||
56 | set_bit(BIT_ACTIVE, &prd->flags); | ||
57 | dev_info(dev, "clocks managed by runtime pm\n"); | ||
58 | } | ||
59 | } | ||
60 | } | ||
61 | |||
62 | static void platform_pm_runtime_bug(struct device *dev, | ||
63 | struct pm_runtime_data *prd) | ||
64 | { | ||
65 | if (prd && !test_and_set_bit(BIT_ONCE, &prd->flags)) | ||
66 | dev_err(dev, "runtime pm suspend before resume\n"); | ||
67 | } | ||
68 | |||
69 | int platform_pm_runtime_suspend(struct device *dev) | ||
70 | { | ||
71 | struct pm_runtime_data *prd = __to_prd(dev); | ||
72 | |||
73 | dev_dbg(dev, "platform_pm_runtime_suspend()\n"); | ||
74 | |||
75 | platform_pm_runtime_bug(dev, prd); | ||
76 | |||
77 | if (prd && test_bit(BIT_ACTIVE, &prd->flags)) { | ||
78 | clk_disable(prd->clk); | ||
79 | clear_bit(BIT_CLK_ENABLED, &prd->flags); | ||
80 | } | ||
81 | |||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | int platform_pm_runtime_resume(struct device *dev) | ||
86 | { | ||
87 | struct pm_runtime_data *prd = __to_prd(dev); | ||
88 | |||
89 | dev_dbg(dev, "platform_pm_runtime_resume()\n"); | ||
90 | |||
91 | platform_pm_runtime_init(dev, prd); | ||
92 | |||
93 | if (prd && test_bit(BIT_ACTIVE, &prd->flags)) { | ||
94 | clk_enable(prd->clk); | ||
95 | set_bit(BIT_CLK_ENABLED, &prd->flags); | ||
96 | } | ||
97 | |||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | int platform_pm_runtime_idle(struct device *dev) | ||
102 | { | ||
103 | /* suspend synchronously to disable clocks immediately */ | ||
104 | return pm_runtime_suspend(dev); | ||
105 | } | ||
106 | |||
107 | static int platform_bus_notify(struct notifier_block *nb, | ||
108 | unsigned long action, void *data) | ||
109 | { | ||
110 | struct device *dev = data; | ||
111 | struct pm_runtime_data *prd; | ||
112 | |||
113 | dev_dbg(dev, "platform_bus_notify() %ld !\n", action); | ||
114 | |||
115 | if (action == BUS_NOTIFY_BIND_DRIVER) { | ||
116 | prd = devres_alloc(__devres_release, sizeof(*prd), GFP_KERNEL); | ||
117 | if (prd) | ||
118 | devres_add(dev, prd); | ||
119 | else | ||
120 | dev_err(dev, "unable to alloc memory for runtime pm\n"); | ||
121 | } | ||
122 | |||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | #else /* CONFIG_PM_RUNTIME */ | ||
127 | |||
128 | static int platform_bus_notify(struct notifier_block *nb, | ||
129 | unsigned long action, void *data) | ||
130 | { | ||
131 | struct device *dev = data; | ||
132 | struct clk *clk; | ||
133 | |||
134 | dev_dbg(dev, "platform_bus_notify() %ld !\n", action); | ||
135 | |||
136 | switch (action) { | ||
137 | case BUS_NOTIFY_BIND_DRIVER: | ||
138 | clk = clk_get(dev, NULL); | ||
139 | if (!IS_ERR(clk)) { | ||
140 | clk_enable(clk); | ||
141 | clk_put(clk); | ||
142 | dev_info(dev, "runtime pm disabled, clock forced on\n"); | ||
143 | } | ||
144 | break; | ||
145 | case BUS_NOTIFY_UNBOUND_DRIVER: | ||
146 | clk = clk_get(dev, NULL); | ||
147 | if (!IS_ERR(clk)) { | ||
148 | clk_disable(clk); | ||
149 | clk_put(clk); | ||
150 | dev_info(dev, "runtime pm disabled, clock forced off\n"); | ||
151 | } | ||
152 | break; | ||
153 | } | ||
154 | |||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | #endif /* CONFIG_PM_RUNTIME */ | ||
159 | |||
160 | static struct notifier_block platform_bus_notifier = { | ||
161 | .notifier_call = platform_bus_notify | ||
162 | }; | ||
163 | |||
164 | static int __init sh_pm_runtime_init(void) | ||
165 | { | ||
166 | bus_register_notifier(&platform_bus_type, &platform_bus_notifier); | ||
167 | return 0; | ||
168 | } | ||
169 | core_initcall(sh_pm_runtime_init); | ||
diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c index 05e78dd9b50..9e305de56be 100644 --- a/arch/arm/mach-tegra/board-harmony.c +++ b/arch/arm/mach-tegra/board-harmony.c | |||
@@ -91,10 +91,8 @@ static void __init tegra_harmony_fixup(struct machine_desc *desc, | |||
91 | { | 91 | { |
92 | mi->nr_banks = 2; | 92 | mi->nr_banks = 2; |
93 | mi->bank[0].start = PHYS_OFFSET; | 93 | mi->bank[0].start = PHYS_OFFSET; |
94 | mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET); | ||
95 | mi->bank[0].size = 448 * SZ_1M; | 94 | mi->bank[0].size = 448 * SZ_1M; |
96 | mi->bank[1].start = SZ_512M; | 95 | mi->bank[1].start = SZ_512M; |
97 | mi->bank[1].node = PHYS_TO_NID(SZ_512M); | ||
98 | mi->bank[1].size = SZ_512M; | 96 | mi->bank[1].size = SZ_512M; |
99 | } | 97 | } |
100 | 98 | ||
diff --git a/arch/arm/mach-tegra/include/mach/vmalloc.h b/arch/arm/mach-tegra/include/mach/vmalloc.h index 267a141730d..fd6aa65b2dc 100644 --- a/arch/arm/mach-tegra/include/mach/vmalloc.h +++ b/arch/arm/mach-tegra/include/mach/vmalloc.h | |||
@@ -23,6 +23,6 @@ | |||
23 | 23 | ||
24 | #include <asm/sizes.h> | 24 | #include <asm/sizes.h> |
25 | 25 | ||
26 | #define VMALLOC_END 0xFE000000 | 26 | #define VMALLOC_END 0xFE000000UL |
27 | 27 | ||
28 | #endif | 28 | #endif |
diff --git a/arch/arm/mach-u300/include/mach/gpio.h b/arch/arm/mach-u300/include/mach/gpio.h index 7b1fc984abb..d5a71abcbae 100644 --- a/arch/arm/mach-u300/include/mach/gpio.h +++ b/arch/arm/mach-u300/include/mach/gpio.h | |||
@@ -273,6 +273,9 @@ extern void gpio_pullup(unsigned gpio, int value); | |||
273 | extern int gpio_get_value(unsigned gpio); | 273 | extern int gpio_get_value(unsigned gpio); |
274 | extern void gpio_set_value(unsigned gpio, int value); | 274 | extern void gpio_set_value(unsigned gpio, int value); |
275 | 275 | ||
276 | #define gpio_get_value_cansleep gpio_get_value | ||
277 | #define gpio_set_value_cansleep gpio_set_value | ||
278 | |||
276 | /* wrappers to sleep-enable the previous two functions */ | 279 | /* wrappers to sleep-enable the previous two functions */ |
277 | static inline unsigned gpio_to_irq(unsigned gpio) | 280 | static inline unsigned gpio_to_irq(unsigned gpio) |
278 | { | 281 | { |
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c index 577df6cccb0..71fb1734952 100644 --- a/arch/arm/mach-vexpress/ct-ca9x4.c +++ b/arch/arm/mach-vexpress/ct-ca9x4.c | |||
@@ -68,7 +68,7 @@ static void __init ct_ca9x4_init_irq(void) | |||
68 | } | 68 | } |
69 | 69 | ||
70 | #if 0 | 70 | #if 0 |
71 | static void ct_ca9x4_timer_init(void) | 71 | static void __init ct_ca9x4_timer_init(void) |
72 | { | 72 | { |
73 | writel(0, MMIO_P2V(CT_CA9X4_TIMER0) + TIMER_CTRL); | 73 | writel(0, MMIO_P2V(CT_CA9X4_TIMER0) + TIMER_CTRL); |
74 | writel(0, MMIO_P2V(CT_CA9X4_TIMER1) + TIMER_CTRL); | 74 | writel(0, MMIO_P2V(CT_CA9X4_TIMER1) + TIMER_CTRL); |
@@ -222,12 +222,18 @@ static struct platform_device pmu_device = { | |||
222 | .resource = pmu_resources, | 222 | .resource = pmu_resources, |
223 | }; | 223 | }; |
224 | 224 | ||
225 | static void ct_ca9x4_init(void) | 225 | static void __init ct_ca9x4_init(void) |
226 | { | 226 | { |
227 | int i; | 227 | int i; |
228 | 228 | ||
229 | #ifdef CONFIG_CACHE_L2X0 | 229 | #ifdef CONFIG_CACHE_L2X0 |
230 | l2x0_init(MMIO_P2V(CT_CA9X4_L2CC), 0x00000000, 0xfe0fffff); | 230 | void __iomem *l2x0_base = MMIO_P2V(CT_CA9X4_L2CC); |
231 | |||
232 | /* set RAM latencies to 1 cycle for this core tile. */ | ||
233 | writel(0, l2x0_base + L2X0_TAG_LATENCY_CTRL); | ||
234 | writel(0, l2x0_base + L2X0_DATA_LATENCY_CTRL); | ||
235 | |||
236 | l2x0_init(l2x0_base, 0x00400000, 0xfe0fffff); | ||
231 | #endif | 237 | #endif |
232 | 238 | ||
233 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); | 239 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); |
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c index 817f0ad38a0..7eaa232180a 100644 --- a/arch/arm/mach-vexpress/v2m.c +++ b/arch/arm/mach-vexpress/v2m.c | |||
@@ -48,7 +48,7 @@ void __init v2m_map_io(struct map_desc *tile, size_t num) | |||
48 | } | 48 | } |
49 | 49 | ||
50 | 50 | ||
51 | static void v2m_timer_init(void) | 51 | static void __init v2m_timer_init(void) |
52 | { | 52 | { |
53 | writel(0, MMIO_P2V(V2M_TIMER0) + TIMER_CTRL); | 53 | writel(0, MMIO_P2V(V2M_TIMER0) + TIMER_CTRL); |
54 | writel(0, MMIO_P2V(V2M_TIMER1) + TIMER_CTRL); | 54 | writel(0, MMIO_P2V(V2M_TIMER1) + TIMER_CTRL); |
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 33c3f570aaa..a0a2928ae4d 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig | |||
@@ -398,7 +398,7 @@ config CPU_V6 | |||
398 | # ARMv6k | 398 | # ARMv6k |
399 | config CPU_32v6K | 399 | config CPU_32v6K |
400 | bool "Support ARM V6K processor extensions" if !SMP | 400 | bool "Support ARM V6K processor extensions" if !SMP |
401 | depends on CPU_V6 | 401 | depends on CPU_V6 || CPU_V7 |
402 | default y if SMP && !(ARCH_MX3 || ARCH_OMAP2) | 402 | default y if SMP && !(ARCH_MX3 || ARCH_OMAP2) |
403 | help | 403 | help |
404 | Say Y here if your ARMv6 processor supports the 'K' extension. | 404 | Say Y here if your ARMv6 processor supports the 'K' extension. |
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index d073b64ae87..724ba3bce72 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c | |||
@@ -885,8 +885,23 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | |||
885 | 885 | ||
886 | if (ai_usermode & UM_SIGNAL) | 886 | if (ai_usermode & UM_SIGNAL) |
887 | force_sig(SIGBUS, current); | 887 | force_sig(SIGBUS, current); |
888 | else | 888 | else { |
889 | set_cr(cr_no_alignment); | 889 | /* |
890 | * We're about to disable the alignment trap and return to | ||
891 | * user space. But if an interrupt occurs before actually | ||
892 | * reaching user space, then the IRQ vector entry code will | ||
893 | * notice that we were still in kernel space and therefore | ||
894 | * the alignment trap won't be re-enabled in that case as it | ||
895 | * is presumed to be always on from kernel space. | ||
896 | * Let's prevent that race by disabling interrupts here (they | ||
897 | * are disabled on the way back to user space anyway in | ||
898 | * entry-common.S) and disable the alignment trap only if | ||
899 | * there is no work pending for this thread. | ||
900 | */ | ||
901 | raw_local_irq_disable(); | ||
902 | if (!(current_thread_info()->flags & _TIF_WORK_MASK)) | ||
903 | set_cr(cr_no_alignment); | ||
904 | } | ||
890 | 905 | ||
891 | return 0; | 906 | return 0; |
892 | } | 907 | } |
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index c704eed63c5..4bc43e535d3 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c | |||
@@ -229,6 +229,8 @@ __dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot) | |||
229 | } | 229 | } |
230 | } while (size -= PAGE_SIZE); | 230 | } while (size -= PAGE_SIZE); |
231 | 231 | ||
232 | dsb(); | ||
233 | |||
232 | return (void *)c->vm_start; | 234 | return (void *)c->vm_start; |
233 | } | 235 | } |
234 | return NULL; | 236 | return NULL; |
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c index ab506272b2d..17e7b0b57e4 100644 --- a/arch/arm/mm/ioremap.c +++ b/arch/arm/mm/ioremap.c | |||
@@ -204,8 +204,12 @@ void __iomem * __arm_ioremap_pfn_caller(unsigned long pfn, | |||
204 | /* | 204 | /* |
205 | * Don't allow RAM to be mapped - this causes problems with ARMv6+ | 205 | * Don't allow RAM to be mapped - this causes problems with ARMv6+ |
206 | */ | 206 | */ |
207 | if (WARN_ON(pfn_valid(pfn))) | 207 | if (pfn_valid(pfn)) { |
208 | return NULL; | 208 | printk(KERN_WARNING "BUG: Your driver calls ioremap() on system memory. This leads\n" |
209 | KERN_WARNING "to architecturally unpredictable behaviour on ARMv6+, and ioremap()\n" | ||
210 | KERN_WARNING "will fail in the next kernel release. Please fix your driver.\n"); | ||
211 | WARN_ON(1); | ||
212 | } | ||
209 | 213 | ||
210 | type = get_mem_type(mtype); | 214 | type = get_mem_type(mtype); |
211 | if (!type) | 215 | if (!type) |
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 6e1c4f6a2b3..e8ed9dc461f 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/nodemask.h> | 15 | #include <linux/nodemask.h> |
16 | #include <linux/memblock.h> | 16 | #include <linux/memblock.h> |
17 | #include <linux/sort.h> | 17 | #include <linux/sort.h> |
18 | #include <linux/fs.h> | ||
18 | 19 | ||
19 | #include <asm/cputype.h> | 20 | #include <asm/cputype.h> |
20 | #include <asm/sections.h> | 21 | #include <asm/sections.h> |
@@ -246,6 +247,9 @@ static struct mem_type mem_types[] = { | |||
246 | .domain = DOMAIN_USER, | 247 | .domain = DOMAIN_USER, |
247 | }, | 248 | }, |
248 | [MT_MEMORY] = { | 249 | [MT_MEMORY] = { |
250 | .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | | ||
251 | L_PTE_WRITE | L_PTE_EXEC, | ||
252 | .prot_l1 = PMD_TYPE_TABLE, | ||
249 | .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, | 253 | .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, |
250 | .domain = DOMAIN_KERNEL, | 254 | .domain = DOMAIN_KERNEL, |
251 | }, | 255 | }, |
@@ -254,6 +258,9 @@ static struct mem_type mem_types[] = { | |||
254 | .domain = DOMAIN_KERNEL, | 258 | .domain = DOMAIN_KERNEL, |
255 | }, | 259 | }, |
256 | [MT_MEMORY_NONCACHED] = { | 260 | [MT_MEMORY_NONCACHED] = { |
261 | .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | | ||
262 | L_PTE_WRITE | L_PTE_EXEC | L_PTE_MT_BUFFERABLE, | ||
263 | .prot_l1 = PMD_TYPE_TABLE, | ||
257 | .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, | 264 | .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, |
258 | .domain = DOMAIN_KERNEL, | 265 | .domain = DOMAIN_KERNEL, |
259 | }, | 266 | }, |
@@ -411,9 +418,12 @@ static void __init build_mem_type_table(void) | |||
411 | * Enable CPU-specific coherency if supported. | 418 | * Enable CPU-specific coherency if supported. |
412 | * (Only available on XSC3 at the moment.) | 419 | * (Only available on XSC3 at the moment.) |
413 | */ | 420 | */ |
414 | if (arch_is_coherent() && cpu_is_xsc3()) | 421 | if (arch_is_coherent() && cpu_is_xsc3()) { |
415 | mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; | 422 | mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; |
416 | 423 | mem_types[MT_MEMORY].prot_pte |= L_PTE_SHARED; | |
424 | mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S; | ||
425 | mem_types[MT_MEMORY_NONCACHED].prot_pte |= L_PTE_SHARED; | ||
426 | } | ||
417 | /* | 427 | /* |
418 | * ARMv6 and above have extended page tables. | 428 | * ARMv6 and above have extended page tables. |
419 | */ | 429 | */ |
@@ -438,7 +448,9 @@ static void __init build_mem_type_table(void) | |||
438 | mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_S; | 448 | mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_S; |
439 | mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED; | 449 | mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED; |
440 | mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; | 450 | mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; |
451 | mem_types[MT_MEMORY].prot_pte |= L_PTE_SHARED; | ||
441 | mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S; | 452 | mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S; |
453 | mem_types[MT_MEMORY_NONCACHED].prot_pte |= L_PTE_SHARED; | ||
442 | #endif | 454 | #endif |
443 | } | 455 | } |
444 | 456 | ||
@@ -475,6 +487,8 @@ static void __init build_mem_type_table(void) | |||
475 | mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask; | 487 | mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask; |
476 | mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask; | 488 | mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask; |
477 | mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd; | 489 | mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd; |
490 | mem_types[MT_MEMORY].prot_pte |= kern_pgprot; | ||
491 | mem_types[MT_MEMORY_NONCACHED].prot_sect |= ecc_mask; | ||
478 | mem_types[MT_ROM].prot_sect |= cp->pmd; | 492 | mem_types[MT_ROM].prot_sect |= cp->pmd; |
479 | 493 | ||
480 | switch (cp->pmd) { | 494 | switch (cp->pmd) { |
@@ -498,6 +512,19 @@ static void __init build_mem_type_table(void) | |||
498 | } | 512 | } |
499 | } | 513 | } |
500 | 514 | ||
515 | #ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE | ||
516 | pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, | ||
517 | unsigned long size, pgprot_t vma_prot) | ||
518 | { | ||
519 | if (!pfn_valid(pfn)) | ||
520 | return pgprot_noncached(vma_prot); | ||
521 | else if (file->f_flags & O_SYNC) | ||
522 | return pgprot_writecombine(vma_prot); | ||
523 | return vma_prot; | ||
524 | } | ||
525 | EXPORT_SYMBOL(phys_mem_access_prot); | ||
526 | #endif | ||
527 | |||
501 | #define vectors_base() (vectors_high() ? 0xffff0000 : 0) | 528 | #define vectors_base() (vectors_high() ? 0xffff0000 : 0) |
502 | 529 | ||
503 | static void __init *early_alloc(unsigned long sz) | 530 | static void __init *early_alloc(unsigned long sz) |
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index 6a8506d99ee..197f21bed5e 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S | |||
@@ -186,13 +186,14 @@ cpu_v7_name: | |||
186 | * It is assumed that: | 186 | * It is assumed that: |
187 | * - cache type register is implemented | 187 | * - cache type register is implemented |
188 | */ | 188 | */ |
189 | __v7_setup: | 189 | __v7_ca9mp_setup: |
190 | #ifdef CONFIG_SMP | 190 | #ifdef CONFIG_SMP |
191 | mrc p15, 0, r0, c1, c0, 1 | 191 | mrc p15, 0, r0, c1, c0, 1 |
192 | tst r0, #(1 << 6) @ SMP/nAMP mode enabled? | 192 | tst r0, #(1 << 6) @ SMP/nAMP mode enabled? |
193 | orreq r0, r0, #(1 << 6) | (1 << 0) @ Enable SMP/nAMP mode and | 193 | orreq r0, r0, #(1 << 6) | (1 << 0) @ Enable SMP/nAMP mode and |
194 | mcreq p15, 0, r0, c1, c0, 1 @ TLB ops broadcasting | 194 | mcreq p15, 0, r0, c1, c0, 1 @ TLB ops broadcasting |
195 | #endif | 195 | #endif |
196 | __v7_setup: | ||
196 | adr r12, __v7_setup_stack @ the local stack | 197 | adr r12, __v7_setup_stack @ the local stack |
197 | stmia r12, {r0-r5, r7, r9, r11, lr} | 198 | stmia r12, {r0-r5, r7, r9, r11, lr} |
198 | bl v7_flush_dcache_all | 199 | bl v7_flush_dcache_all |
@@ -201,11 +202,16 @@ __v7_setup: | |||
201 | mrc p15, 0, r0, c0, c0, 0 @ read main ID register | 202 | mrc p15, 0, r0, c0, c0, 0 @ read main ID register |
202 | and r10, r0, #0xff000000 @ ARM? | 203 | and r10, r0, #0xff000000 @ ARM? |
203 | teq r10, #0x41000000 | 204 | teq r10, #0x41000000 |
204 | bne 2f | 205 | bne 3f |
205 | and r5, r0, #0x00f00000 @ variant | 206 | and r5, r0, #0x00f00000 @ variant |
206 | and r6, r0, #0x0000000f @ revision | 207 | and r6, r0, #0x0000000f @ revision |
207 | orr r0, r6, r5, lsr #20-4 @ combine variant and revision | 208 | orr r6, r6, r5, lsr #20-4 @ combine variant and revision |
209 | ubfx r0, r0, #4, #12 @ primary part number | ||
208 | 210 | ||
211 | /* Cortex-A8 Errata */ | ||
212 | ldr r10, =0x00000c08 @ Cortex-A8 primary part number | ||
213 | teq r0, r10 | ||
214 | bne 2f | ||
209 | #ifdef CONFIG_ARM_ERRATA_430973 | 215 | #ifdef CONFIG_ARM_ERRATA_430973 |
210 | teq r5, #0x00100000 @ only present in r1p* | 216 | teq r5, #0x00100000 @ only present in r1p* |
211 | mrceq p15, 0, r10, c1, c0, 1 @ read aux control register | 217 | mrceq p15, 0, r10, c1, c0, 1 @ read aux control register |
@@ -213,21 +219,50 @@ __v7_setup: | |||
213 | mcreq p15, 0, r10, c1, c0, 1 @ write aux control register | 219 | mcreq p15, 0, r10, c1, c0, 1 @ write aux control register |
214 | #endif | 220 | #endif |
215 | #ifdef CONFIG_ARM_ERRATA_458693 | 221 | #ifdef CONFIG_ARM_ERRATA_458693 |
216 | teq r0, #0x20 @ only present in r2p0 | 222 | teq r6, #0x20 @ only present in r2p0 |
217 | mrceq p15, 0, r10, c1, c0, 1 @ read aux control register | 223 | mrceq p15, 0, r10, c1, c0, 1 @ read aux control register |
218 | orreq r10, r10, #(1 << 5) @ set L1NEON to 1 | 224 | orreq r10, r10, #(1 << 5) @ set L1NEON to 1 |
219 | orreq r10, r10, #(1 << 9) @ set PLDNOP to 1 | 225 | orreq r10, r10, #(1 << 9) @ set PLDNOP to 1 |
220 | mcreq p15, 0, r10, c1, c0, 1 @ write aux control register | 226 | mcreq p15, 0, r10, c1, c0, 1 @ write aux control register |
221 | #endif | 227 | #endif |
222 | #ifdef CONFIG_ARM_ERRATA_460075 | 228 | #ifdef CONFIG_ARM_ERRATA_460075 |
223 | teq r0, #0x20 @ only present in r2p0 | 229 | teq r6, #0x20 @ only present in r2p0 |
224 | mrceq p15, 1, r10, c9, c0, 2 @ read L2 cache aux ctrl register | 230 | mrceq p15, 1, r10, c9, c0, 2 @ read L2 cache aux ctrl register |
225 | tsteq r10, #1 << 22 | 231 | tsteq r10, #1 << 22 |
226 | orreq r10, r10, #(1 << 22) @ set the Write Allocate disable bit | 232 | orreq r10, r10, #(1 << 22) @ set the Write Allocate disable bit |
227 | mcreq p15, 1, r10, c9, c0, 2 @ write the L2 cache aux ctrl register | 233 | mcreq p15, 1, r10, c9, c0, 2 @ write the L2 cache aux ctrl register |
228 | #endif | 234 | #endif |
235 | b 3f | ||
229 | 236 | ||
230 | 2: mov r10, #0 | 237 | /* Cortex-A9 Errata */ |
238 | 2: ldr r10, =0x00000c09 @ Cortex-A9 primary part number | ||
239 | teq r0, r10 | ||
240 | bne 3f | ||
241 | #ifdef CONFIG_ARM_ERRATA_742230 | ||
242 | cmp r6, #0x22 @ only present up to r2p2 | ||
243 | mrcle p15, 0, r10, c15, c0, 1 @ read diagnostic register | ||
244 | orrle r10, r10, #1 << 4 @ set bit #4 | ||
245 | mcrle p15, 0, r10, c15, c0, 1 @ write diagnostic register | ||
246 | #endif | ||
247 | #ifdef CONFIG_ARM_ERRATA_742231 | ||
248 | teq r6, #0x20 @ present in r2p0 | ||
249 | teqne r6, #0x21 @ present in r2p1 | ||
250 | teqne r6, #0x22 @ present in r2p2 | ||
251 | mrceq p15, 0, r10, c15, c0, 1 @ read diagnostic register | ||
252 | orreq r10, r10, #1 << 12 @ set bit #12 | ||
253 | orreq r10, r10, #1 << 22 @ set bit #22 | ||
254 | mcreq p15, 0, r10, c15, c0, 1 @ write diagnostic register | ||
255 | #endif | ||
256 | #ifdef CONFIG_ARM_ERRATA_743622 | ||
257 | teq r6, #0x20 @ present in r2p0 | ||
258 | teqne r6, #0x21 @ present in r2p1 | ||
259 | teqne r6, #0x22 @ present in r2p2 | ||
260 | mrceq p15, 0, r10, c15, c0, 1 @ read diagnostic register | ||
261 | orreq r10, r10, #1 << 6 @ set bit #6 | ||
262 | mcreq p15, 0, r10, c15, c0, 1 @ write diagnostic register | ||
263 | #endif | ||
264 | |||
265 | 3: mov r10, #0 | ||
231 | #ifdef HARVARD_CACHE | 266 | #ifdef HARVARD_CACHE |
232 | mcr p15, 0, r10, c7, c5, 0 @ I+BTB cache invalidate | 267 | mcr p15, 0, r10, c7, c5, 0 @ I+BTB cache invalidate |
233 | #endif | 268 | #endif |
@@ -323,6 +358,29 @@ cpu_elf_name: | |||
323 | 358 | ||
324 | .section ".proc.info.init", #alloc, #execinstr | 359 | .section ".proc.info.init", #alloc, #execinstr |
325 | 360 | ||
361 | .type __v7_ca9mp_proc_info, #object | ||
362 | __v7_ca9mp_proc_info: | ||
363 | .long 0x410fc090 @ Required ID value | ||
364 | .long 0xff0ffff0 @ Mask for ID | ||
365 | .long PMD_TYPE_SECT | \ | ||
366 | PMD_SECT_AP_WRITE | \ | ||
367 | PMD_SECT_AP_READ | \ | ||
368 | PMD_FLAGS | ||
369 | .long PMD_TYPE_SECT | \ | ||
370 | PMD_SECT_XN | \ | ||
371 | PMD_SECT_AP_WRITE | \ | ||
372 | PMD_SECT_AP_READ | ||
373 | b __v7_ca9mp_setup | ||
374 | .long cpu_arch_name | ||
375 | .long cpu_elf_name | ||
376 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_TLS | ||
377 | .long cpu_v7_name | ||
378 | .long v7_processor_functions | ||
379 | .long v7wbi_tlb_fns | ||
380 | .long v6_user_fns | ||
381 | .long v7_cache_fns | ||
382 | .size __v7_ca9mp_proc_info, . - __v7_ca9mp_proc_info | ||
383 | |||
326 | /* | 384 | /* |
327 | * Match any ARMv7 processor core. | 385 | * Match any ARMv7 processor core. |
328 | */ | 386 | */ |
diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c index 0691176899f..72e09eb642d 100644 --- a/arch/arm/oprofile/common.c +++ b/arch/arm/oprofile/common.c | |||
@@ -102,6 +102,7 @@ static int op_create_counter(int cpu, int event) | |||
102 | if (IS_ERR(pevent)) { | 102 | if (IS_ERR(pevent)) { |
103 | ret = PTR_ERR(pevent); | 103 | ret = PTR_ERR(pevent); |
104 | } else if (pevent->state != PERF_EVENT_STATE_ACTIVE) { | 104 | } else if (pevent->state != PERF_EVENT_STATE_ACTIVE) { |
105 | perf_event_release_kernel(pevent); | ||
105 | pr_warning("oprofile: failed to enable event %d " | 106 | pr_warning("oprofile: failed to enable event %d " |
106 | "on CPU %d\n", event, cpu); | 107 | "on CPU %d\n", event, cpu); |
107 | ret = -EBUSY; | 108 | ret = -EBUSY; |
@@ -365,6 +366,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) | |||
365 | ret = init_driverfs(); | 366 | ret = init_driverfs(); |
366 | if (ret) { | 367 | if (ret) { |
367 | kfree(counter_config); | 368 | kfree(counter_config); |
369 | counter_config = NULL; | ||
368 | return ret; | 370 | return ret; |
369 | } | 371 | } |
370 | 372 | ||
@@ -402,7 +404,6 @@ void oprofile_arch_exit(void) | |||
402 | struct perf_event *event; | 404 | struct perf_event *event; |
403 | 405 | ||
404 | if (*perf_events) { | 406 | if (*perf_events) { |
405 | exit_driverfs(); | ||
406 | for_each_possible_cpu(cpu) { | 407 | for_each_possible_cpu(cpu) { |
407 | for (id = 0; id < perf_num_counters; ++id) { | 408 | for (id = 0; id < perf_num_counters; ++id) { |
408 | event = perf_events[cpu][id]; | 409 | event = perf_events[cpu][id]; |
@@ -413,8 +414,10 @@ void oprofile_arch_exit(void) | |||
413 | } | 414 | } |
414 | } | 415 | } |
415 | 416 | ||
416 | if (counter_config) | 417 | if (counter_config) { |
417 | kfree(counter_config); | 418 | kfree(counter_config); |
419 | exit_driverfs(); | ||
420 | } | ||
418 | } | 421 | } |
419 | #else | 422 | #else |
420 | int __init oprofile_arch_init(struct oprofile_operations *ops) | 423 | int __init oprofile_arch_init(struct oprofile_operations *ops) |
diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig index 0527e65318f..6785db4179b 100644 --- a/arch/arm/plat-mxc/Kconfig +++ b/arch/arm/plat-mxc/Kconfig | |||
@@ -43,6 +43,7 @@ config ARCH_MXC91231 | |||
43 | config ARCH_MX5 | 43 | config ARCH_MX5 |
44 | bool "MX5-based" | 44 | bool "MX5-based" |
45 | select CPU_V7 | 45 | select CPU_V7 |
46 | select ARM_L1_CACHE_SHIFT_6 | ||
46 | help | 47 | help |
47 | This enables support for systems based on the Freescale i.MX51 family | 48 | This enables support for systems based on the Freescale i.MX51 family |
48 | 49 | ||
diff --git a/arch/arm/plat-mxc/include/mach/eukrea-baseboards.h b/arch/arm/plat-mxc/include/mach/eukrea-baseboards.h index 634e3f4c454..656acb45d43 100644 --- a/arch/arm/plat-mxc/include/mach/eukrea-baseboards.h +++ b/arch/arm/plat-mxc/include/mach/eukrea-baseboards.h | |||
@@ -37,9 +37,9 @@ | |||
37 | * mach-mx5/eukrea_mbimx51-baseboard.c for cpuimx51 | 37 | * mach-mx5/eukrea_mbimx51-baseboard.c for cpuimx51 |
38 | */ | 38 | */ |
39 | 39 | ||
40 | extern void eukrea_mbimx25_baseboard_init(void); | 40 | extern void eukrea_mbimxsd25_baseboard_init(void); |
41 | extern void eukrea_mbimx27_baseboard_init(void); | 41 | extern void eukrea_mbimx27_baseboard_init(void); |
42 | extern void eukrea_mbimx35_baseboard_init(void); | 42 | extern void eukrea_mbimxsd35_baseboard_init(void); |
43 | extern void eukrea_mbimx51_baseboard_init(void); | 43 | extern void eukrea_mbimx51_baseboard_init(void); |
44 | 44 | ||
45 | #endif | 45 | #endif |
diff --git a/arch/arm/plat-mxc/tzic.c b/arch/arm/plat-mxc/tzic.c index b3da9aad429..3703ab28257 100644 --- a/arch/arm/plat-mxc/tzic.c +++ b/arch/arm/plat-mxc/tzic.c | |||
@@ -164,8 +164,9 @@ int tzic_enable_wake(int is_idle) | |||
164 | return -EAGAIN; | 164 | return -EAGAIN; |
165 | 165 | ||
166 | for (i = 0; i < 4; i++) { | 166 | for (i = 0; i < 4; i++) { |
167 | v = is_idle ? __raw_readl(TZIC_ENSET0(i)) : wakeup_intr[i]; | 167 | v = is_idle ? __raw_readl(tzic_base + TZIC_ENSET0(i)) : |
168 | __raw_writel(v, TZIC_WAKEUP0(i)); | 168 | wakeup_intr[i]; |
169 | __raw_writel(v, tzic_base + TZIC_WAKEUP0(i)); | ||
169 | } | 170 | } |
170 | 171 | ||
171 | return 0; | 172 | return 0; |
diff --git a/arch/arm/plat-nomadik/timer.c b/arch/arm/plat-nomadik/timer.c index ea3ca86c528..aedf9c1d645 100644 --- a/arch/arm/plat-nomadik/timer.c +++ b/arch/arm/plat-nomadik/timer.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/arch/arm/mach-nomadik/timer.c | 2 | * linux/arch/arm/plat-nomadik/timer.c |
3 | * | 3 | * |
4 | * Copyright (C) 2008 STMicroelectronics | 4 | * Copyright (C) 2008 STMicroelectronics |
5 | * Copyright (C) 2010 Alessandro Rubini | 5 | * Copyright (C) 2010 Alessandro Rubini |
@@ -75,7 +75,7 @@ static void nmdk_clkevt_mode(enum clock_event_mode mode, | |||
75 | cr = readl(mtu_base + MTU_CR(1)); | 75 | cr = readl(mtu_base + MTU_CR(1)); |
76 | writel(0, mtu_base + MTU_LR(1)); | 76 | writel(0, mtu_base + MTU_LR(1)); |
77 | writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(1)); | 77 | writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(1)); |
78 | writel(0x2, mtu_base + MTU_IMSC); | 78 | writel(1 << 1, mtu_base + MTU_IMSC); |
79 | break; | 79 | break; |
80 | case CLOCK_EVT_MODE_SHUTDOWN: | 80 | case CLOCK_EVT_MODE_SHUTDOWN: |
81 | case CLOCK_EVT_MODE_UNUSED: | 81 | case CLOCK_EVT_MODE_UNUSED: |
@@ -131,25 +131,23 @@ void __init nmdk_timer_init(void) | |||
131 | { | 131 | { |
132 | unsigned long rate; | 132 | unsigned long rate; |
133 | struct clk *clk0; | 133 | struct clk *clk0; |
134 | struct clk *clk1; | 134 | u32 cr = MTU_CRn_32BITS; |
135 | u32 cr; | ||
136 | 135 | ||
137 | clk0 = clk_get_sys("mtu0", NULL); | 136 | clk0 = clk_get_sys("mtu0", NULL); |
138 | BUG_ON(IS_ERR(clk0)); | 137 | BUG_ON(IS_ERR(clk0)); |
139 | 138 | ||
140 | clk1 = clk_get_sys("mtu1", NULL); | ||
141 | BUG_ON(IS_ERR(clk1)); | ||
142 | |||
143 | clk_enable(clk0); | 139 | clk_enable(clk0); |
144 | clk_enable(clk1); | ||
145 | 140 | ||
146 | /* | 141 | /* |
147 | * Tick rate is 2.4MHz for Nomadik and 110MHz for ux500: | 142 | * Tick rate is 2.4MHz for Nomadik and 2.4Mhz, 100MHz or 133 MHz |
148 | * use a divide-by-16 counter if it's more than 16MHz | 143 | * for ux500. |
144 | * Use a divide-by-16 counter if the tick rate is more than 32MHz. | ||
145 | * At 32 MHz, the timer (with 32 bit counter) can be programmed | ||
146 | * to wake-up at a max 127s a head in time. Dividing a 2.4 MHz timer | ||
147 | * with 16 gives too low timer resolution. | ||
149 | */ | 148 | */ |
150 | cr = MTU_CRn_32BITS;; | ||
151 | rate = clk_get_rate(clk0); | 149 | rate = clk_get_rate(clk0); |
152 | if (rate > 16 << 20) { | 150 | if (rate > 32000000) { |
153 | rate /= 16; | 151 | rate /= 16; |
154 | cr |= MTU_CRn_PRESCALE_16; | 152 | cr |= MTU_CRn_PRESCALE_16; |
155 | } else { | 153 | } else { |
@@ -170,15 +168,8 @@ void __init nmdk_timer_init(void) | |||
170 | pr_err("timer: failed to initialize clock source %s\n", | 168 | pr_err("timer: failed to initialize clock source %s\n", |
171 | nmdk_clksrc.name); | 169 | nmdk_clksrc.name); |
172 | 170 | ||
173 | /* Timer 1 is used for events, fix according to rate */ | 171 | /* Timer 1 is used for events */ |
174 | cr = MTU_CRn_32BITS; | 172 | |
175 | rate = clk_get_rate(clk1); | ||
176 | if (rate > 16 << 20) { | ||
177 | rate /= 16; | ||
178 | cr |= MTU_CRn_PRESCALE_16; | ||
179 | } else { | ||
180 | cr |= MTU_CRn_PRESCALE_1; | ||
181 | } | ||
182 | clockevents_calc_mult_shift(&nmdk_clkevt, rate, MTU_MIN_RANGE); | 173 | clockevents_calc_mult_shift(&nmdk_clkevt, rate, MTU_MIN_RANGE); |
183 | 174 | ||
184 | writel(cr | MTU_CRn_ONESHOT, mtu_base + MTU_CR(1)); /* off, currently */ | 175 | writel(cr | MTU_CRn_ONESHOT, mtu_base + MTU_CR(1)); /* off, currently */ |
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig index e39a417a368..a92cb499313 100644 --- a/arch/arm/plat-omap/Kconfig +++ b/arch/arm/plat-omap/Kconfig | |||
@@ -33,7 +33,7 @@ config OMAP_DEBUG_DEVICES | |||
33 | config OMAP_DEBUG_LEDS | 33 | config OMAP_DEBUG_LEDS |
34 | bool | 34 | bool |
35 | depends on OMAP_DEBUG_DEVICES | 35 | depends on OMAP_DEBUG_DEVICES |
36 | default y if LEDS | 36 | default y if LEDS_CLASS |
37 | 37 | ||
38 | config OMAP_RESET_CLOCKS | 38 | config OMAP_RESET_CLOCKS |
39 | bool "Reset unused clocks during boot" | 39 | bool "Reset unused clocks during boot" |
diff --git a/arch/arm/plat-omap/include/plat/smp.h b/arch/arm/plat-omap/include/plat/smp.h index 6a3ff65c030..5177a9c5a25 100644 --- a/arch/arm/plat-omap/include/plat/smp.h +++ b/arch/arm/plat-omap/include/plat/smp.h | |||
@@ -19,13 +19,6 @@ | |||
19 | 19 | ||
20 | #include <asm/hardware/gic.h> | 20 | #include <asm/hardware/gic.h> |
21 | 21 | ||
22 | /* | ||
23 | * set_event() is used to wake up secondary core from wfe using sev. ROM | ||
24 | * code puts the second core into wfe(standby). | ||
25 | * | ||
26 | */ | ||
27 | #define set_event() __asm__ __volatile__ ("sev" : : : "memory") | ||
28 | |||
29 | /* Needed for secondary core boot */ | 22 | /* Needed for secondary core boot */ |
30 | extern void omap_secondary_startup(void); | 23 | extern void omap_secondary_startup(void); |
31 | extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask); | 24 | extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask); |
diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c index a202a2ce6e3..6cd151b31bc 100644 --- a/arch/arm/plat-omap/iommu.c +++ b/arch/arm/plat-omap/iommu.c | |||
@@ -320,6 +320,7 @@ void flush_iotlb_page(struct iommu *obj, u32 da) | |||
320 | if ((start <= da) && (da < start + bytes)) { | 320 | if ((start <= da) && (da < start + bytes)) { |
321 | dev_dbg(obj->dev, "%s: %08x<=%08x(%x)\n", | 321 | dev_dbg(obj->dev, "%s: %08x<=%08x(%x)\n", |
322 | __func__, start, da, bytes); | 322 | __func__, start, da, bytes); |
323 | iotlb_load_cr(obj, &cr); | ||
323 | iommu_write_reg(obj, 1, MMU_FLUSH_ENTRY); | 324 | iommu_write_reg(obj, 1, MMU_FLUSH_ENTRY); |
324 | } | 325 | } |
325 | } | 326 | } |
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index e31496e35b0..0c8612fd831 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c | |||
@@ -156,7 +156,7 @@ static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id) | |||
156 | /* Writing zero to RSYNC_ERR clears the IRQ */ | 156 | /* Writing zero to RSYNC_ERR clears the IRQ */ |
157 | MCBSP_WRITE(mcbsp_rx, SPCR1, MCBSP_READ_CACHE(mcbsp_rx, SPCR1)); | 157 | MCBSP_WRITE(mcbsp_rx, SPCR1, MCBSP_READ_CACHE(mcbsp_rx, SPCR1)); |
158 | } else { | 158 | } else { |
159 | complete(&mcbsp_rx->tx_irq_completion); | 159 | complete(&mcbsp_rx->rx_irq_completion); |
160 | } | 160 | } |
161 | 161 | ||
162 | return IRQ_HANDLED; | 162 | return IRQ_HANDLED; |
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index 226b2e858d6..10b3b4c6337 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c | |||
@@ -220,20 +220,7 @@ void __init omap_map_sram(void) | |||
220 | if (omap_sram_size == 0) | 220 | if (omap_sram_size == 0) |
221 | return; | 221 | return; |
222 | 222 | ||
223 | if (cpu_is_omap24xx()) { | ||
224 | omap_sram_io_desc[0].virtual = OMAP2_SRAM_VA; | ||
225 | |||
226 | base = OMAP2_SRAM_PA; | ||
227 | base = ROUND_DOWN(base, PAGE_SIZE); | ||
228 | omap_sram_io_desc[0].pfn = __phys_to_pfn(base); | ||
229 | } | ||
230 | |||
231 | if (cpu_is_omap34xx()) { | 223 | if (cpu_is_omap34xx()) { |
232 | omap_sram_io_desc[0].virtual = OMAP3_SRAM_VA; | ||
233 | base = OMAP3_SRAM_PA; | ||
234 | base = ROUND_DOWN(base, PAGE_SIZE); | ||
235 | omap_sram_io_desc[0].pfn = __phys_to_pfn(base); | ||
236 | |||
237 | /* | 224 | /* |
238 | * SRAM must be marked as non-cached on OMAP3 since the | 225 | * SRAM must be marked as non-cached on OMAP3 since the |
239 | * CORE DPLL M2 divider change code (in SRAM) runs with the | 226 | * CORE DPLL M2 divider change code (in SRAM) runs with the |
@@ -244,13 +231,11 @@ void __init omap_map_sram(void) | |||
244 | omap_sram_io_desc[0].type = MT_MEMORY_NONCACHED; | 231 | omap_sram_io_desc[0].type = MT_MEMORY_NONCACHED; |
245 | } | 232 | } |
246 | 233 | ||
247 | if (cpu_is_omap44xx()) { | 234 | omap_sram_io_desc[0].virtual = omap_sram_base; |
248 | omap_sram_io_desc[0].virtual = OMAP4_SRAM_VA; | 235 | base = omap_sram_start; |
249 | base = OMAP4_SRAM_PA; | 236 | base = ROUND_DOWN(base, PAGE_SIZE); |
250 | base = ROUND_DOWN(base, PAGE_SIZE); | 237 | omap_sram_io_desc[0].pfn = __phys_to_pfn(base); |
251 | omap_sram_io_desc[0].pfn = __phys_to_pfn(base); | 238 | omap_sram_io_desc[0].length = ROUND_DOWN(omap_sram_size, PAGE_SIZE); |
252 | } | ||
253 | omap_sram_io_desc[0].length = 1024 * 1024; /* Use section desc */ | ||
254 | iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc)); | 239 | iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc)); |
255 | 240 | ||
256 | printk(KERN_INFO "SRAM: Mapped pa 0x%08lx to va 0x%08lx size: 0x%lx\n", | 241 | printk(KERN_INFO "SRAM: Mapped pa 0x%08lx to va 0x%08lx size: 0x%lx\n", |
diff --git a/arch/arm/plat-pxa/pwm.c b/arch/arm/plat-pxa/pwm.c index 0732c6c8d51..ef32686feef 100644 --- a/arch/arm/plat-pxa/pwm.c +++ b/arch/arm/plat-pxa/pwm.c | |||
@@ -176,7 +176,7 @@ static inline void __add_pwm(struct pwm_device *pwm) | |||
176 | 176 | ||
177 | static int __devinit pwm_probe(struct platform_device *pdev) | 177 | static int __devinit pwm_probe(struct platform_device *pdev) |
178 | { | 178 | { |
179 | struct platform_device_id *id = platform_get_device_id(pdev); | 179 | const struct platform_device_id *id = platform_get_device_id(pdev); |
180 | struct pwm_device *pwm, *secondary = NULL; | 180 | struct pwm_device *pwm, *secondary = NULL; |
181 | struct resource *r; | 181 | struct resource *r; |
182 | int ret = 0; | 182 | int ret = 0; |
diff --git a/arch/arm/plat-s5p/dev-fimc0.c b/arch/arm/plat-s5p/dev-fimc0.c index d3f1a9b5d2b..608770fc153 100644 --- a/arch/arm/plat-s5p/dev-fimc0.c +++ b/arch/arm/plat-s5p/dev-fimc0.c | |||
@@ -10,6 +10,7 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/dma-mapping.h> | ||
13 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
14 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
15 | #include <linux/ioport.h> | 16 | #include <linux/ioport.h> |
@@ -18,7 +19,7 @@ | |||
18 | static struct resource s5p_fimc0_resource[] = { | 19 | static struct resource s5p_fimc0_resource[] = { |
19 | [0] = { | 20 | [0] = { |
20 | .start = S5P_PA_FIMC0, | 21 | .start = S5P_PA_FIMC0, |
21 | .end = S5P_PA_FIMC0 + SZ_1M - 1, | 22 | .end = S5P_PA_FIMC0 + SZ_4K - 1, |
22 | .flags = IORESOURCE_MEM, | 23 | .flags = IORESOURCE_MEM, |
23 | }, | 24 | }, |
24 | [1] = { | 25 | [1] = { |
@@ -28,9 +29,15 @@ static struct resource s5p_fimc0_resource[] = { | |||
28 | }, | 29 | }, |
29 | }; | 30 | }; |
30 | 31 | ||
32 | static u64 s5p_fimc0_dma_mask = DMA_BIT_MASK(32); | ||
33 | |||
31 | struct platform_device s5p_device_fimc0 = { | 34 | struct platform_device s5p_device_fimc0 = { |
32 | .name = "s5p-fimc", | 35 | .name = "s5p-fimc", |
33 | .id = 0, | 36 | .id = 0, |
34 | .num_resources = ARRAY_SIZE(s5p_fimc0_resource), | 37 | .num_resources = ARRAY_SIZE(s5p_fimc0_resource), |
35 | .resource = s5p_fimc0_resource, | 38 | .resource = s5p_fimc0_resource, |
39 | .dev = { | ||
40 | .dma_mask = &s5p_fimc0_dma_mask, | ||
41 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
42 | }, | ||
36 | }; | 43 | }; |
diff --git a/arch/arm/plat-s5p/dev-fimc1.c b/arch/arm/plat-s5p/dev-fimc1.c index 41bd6986d0a..76e3a97a87d 100644 --- a/arch/arm/plat-s5p/dev-fimc1.c +++ b/arch/arm/plat-s5p/dev-fimc1.c | |||
@@ -10,6 +10,7 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/dma-mapping.h> | ||
13 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
14 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
15 | #include <linux/ioport.h> | 16 | #include <linux/ioport.h> |
@@ -18,7 +19,7 @@ | |||
18 | static struct resource s5p_fimc1_resource[] = { | 19 | static struct resource s5p_fimc1_resource[] = { |
19 | [0] = { | 20 | [0] = { |
20 | .start = S5P_PA_FIMC1, | 21 | .start = S5P_PA_FIMC1, |
21 | .end = S5P_PA_FIMC1 + SZ_1M - 1, | 22 | .end = S5P_PA_FIMC1 + SZ_4K - 1, |
22 | .flags = IORESOURCE_MEM, | 23 | .flags = IORESOURCE_MEM, |
23 | }, | 24 | }, |
24 | [1] = { | 25 | [1] = { |
@@ -28,9 +29,15 @@ static struct resource s5p_fimc1_resource[] = { | |||
28 | }, | 29 | }, |
29 | }; | 30 | }; |
30 | 31 | ||
32 | static u64 s5p_fimc1_dma_mask = DMA_BIT_MASK(32); | ||
33 | |||
31 | struct platform_device s5p_device_fimc1 = { | 34 | struct platform_device s5p_device_fimc1 = { |
32 | .name = "s5p-fimc", | 35 | .name = "s5p-fimc", |
33 | .id = 1, | 36 | .id = 1, |
34 | .num_resources = ARRAY_SIZE(s5p_fimc1_resource), | 37 | .num_resources = ARRAY_SIZE(s5p_fimc1_resource), |
35 | .resource = s5p_fimc1_resource, | 38 | .resource = s5p_fimc1_resource, |
39 | .dev = { | ||
40 | .dma_mask = &s5p_fimc1_dma_mask, | ||
41 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
42 | }, | ||
36 | }; | 43 | }; |
diff --git a/arch/arm/plat-s5p/dev-fimc2.c b/arch/arm/plat-s5p/dev-fimc2.c index dfddeda6d4a..24d29816fa2 100644 --- a/arch/arm/plat-s5p/dev-fimc2.c +++ b/arch/arm/plat-s5p/dev-fimc2.c | |||
@@ -10,6 +10,7 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/dma-mapping.h> | ||
13 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
14 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
15 | #include <linux/ioport.h> | 16 | #include <linux/ioport.h> |
@@ -18,7 +19,7 @@ | |||
18 | static struct resource s5p_fimc2_resource[] = { | 19 | static struct resource s5p_fimc2_resource[] = { |
19 | [0] = { | 20 | [0] = { |
20 | .start = S5P_PA_FIMC2, | 21 | .start = S5P_PA_FIMC2, |
21 | .end = S5P_PA_FIMC2 + SZ_1M - 1, | 22 | .end = S5P_PA_FIMC2 + SZ_4K - 1, |
22 | .flags = IORESOURCE_MEM, | 23 | .flags = IORESOURCE_MEM, |
23 | }, | 24 | }, |
24 | [1] = { | 25 | [1] = { |
@@ -28,9 +29,15 @@ static struct resource s5p_fimc2_resource[] = { | |||
28 | }, | 29 | }, |
29 | }; | 30 | }; |
30 | 31 | ||
32 | static u64 s5p_fimc2_dma_mask = DMA_BIT_MASK(32); | ||
33 | |||
31 | struct platform_device s5p_device_fimc2 = { | 34 | struct platform_device s5p_device_fimc2 = { |
32 | .name = "s5p-fimc", | 35 | .name = "s5p-fimc", |
33 | .id = 2, | 36 | .id = 2, |
34 | .num_resources = ARRAY_SIZE(s5p_fimc2_resource), | 37 | .num_resources = ARRAY_SIZE(s5p_fimc2_resource), |
35 | .resource = s5p_fimc2_resource, | 38 | .resource = s5p_fimc2_resource, |
39 | .dev = { | ||
40 | .dma_mask = &s5p_fimc2_dma_mask, | ||
41 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
42 | }, | ||
36 | }; | 43 | }; |
diff --git a/arch/arm/plat-s5p/include/plat/map-s5p.h b/arch/arm/plat-s5p/include/plat/map-s5p.h index 54e9fb9d315..c4ff88bf647 100644 --- a/arch/arm/plat-s5p/include/plat/map-s5p.h +++ b/arch/arm/plat-s5p/include/plat/map-s5p.h | |||
@@ -17,6 +17,7 @@ | |||
17 | #define S5P_VA_GPIO S3C_ADDR(0x00500000) | 17 | #define S5P_VA_GPIO S3C_ADDR(0x00500000) |
18 | #define S5P_VA_SYSTIMER S3C_ADDR(0x01200000) | 18 | #define S5P_VA_SYSTIMER S3C_ADDR(0x01200000) |
19 | #define S5P_VA_SROMC S3C_ADDR(0x01100000) | 19 | #define S5P_VA_SROMC S3C_ADDR(0x01100000) |
20 | #define S5P_VA_SYSRAM S3C_ADDR(0x01180000) | ||
20 | 21 | ||
21 | #define S5P_VA_COMBINER_BASE S3C_ADDR(0x00600000) | 22 | #define S5P_VA_COMBINER_BASE S3C_ADDR(0x00600000) |
22 | #define S5P_VA_COMBINER(x) (S5P_VA_COMBINER_BASE + ((x) >> 2) * 0x10) | 23 | #define S5P_VA_COMBINER(x) (S5P_VA_COMBINER_BASE + ((x) >> 2) * 0x10) |
@@ -29,6 +30,7 @@ | |||
29 | #define S5P_VA_GIC_DIST S5P_VA_COREPERI(0x1000) | 30 | #define S5P_VA_GIC_DIST S5P_VA_COREPERI(0x1000) |
30 | 31 | ||
31 | #define S5P_VA_L2CC S3C_ADDR(0x00900000) | 32 | #define S5P_VA_L2CC S3C_ADDR(0x00900000) |
33 | #define S5P_VA_CMU S3C_ADDR(0x00920000) | ||
32 | 34 | ||
33 | #define S5P_VA_UART(x) (S3C_VA_UART + ((x) * S3C_UART_OFFSET)) | 35 | #define S5P_VA_UART(x) (S3C_VA_UART + ((x) * S3C_UART_OFFSET)) |
34 | #define S5P_VA_UART0 S5P_VA_UART(0) | 36 | #define S5P_VA_UART0 S5P_VA_UART(0) |
diff --git a/arch/arm/plat-samsung/adc.c b/arch/arm/plat-samsung/adc.c index 04d9521ddc9..e8f2be2d67f 100644 --- a/arch/arm/plat-samsung/adc.c +++ b/arch/arm/plat-samsung/adc.c | |||
@@ -435,7 +435,6 @@ static int s3c_adc_suspend(struct platform_device *pdev, pm_message_t state) | |||
435 | static int s3c_adc_resume(struct platform_device *pdev) | 435 | static int s3c_adc_resume(struct platform_device *pdev) |
436 | { | 436 | { |
437 | struct adc_device *adc = platform_get_drvdata(pdev); | 437 | struct adc_device *adc = platform_get_drvdata(pdev); |
438 | unsigned long flags; | ||
439 | 438 | ||
440 | clk_enable(adc->clk); | 439 | clk_enable(adc->clk); |
441 | enable_irq(adc->irq); | 440 | enable_irq(adc->irq); |
diff --git a/arch/arm/plat-samsung/clock.c b/arch/arm/plat-samsung/clock.c index 90a20512d68..e8d20b0bc50 100644 --- a/arch/arm/plat-samsung/clock.c +++ b/arch/arm/plat-samsung/clock.c | |||
@@ -48,6 +48,9 @@ | |||
48 | #include <plat/clock.h> | 48 | #include <plat/clock.h> |
49 | #include <plat/cpu.h> | 49 | #include <plat/cpu.h> |
50 | 50 | ||
51 | #include <linux/serial_core.h> | ||
52 | #include <plat/regs-serial.h> /* for s3c24xx_uart_devs */ | ||
53 | |||
51 | /* clock information */ | 54 | /* clock information */ |
52 | 55 | ||
53 | static LIST_HEAD(clocks); | 56 | static LIST_HEAD(clocks); |
@@ -65,6 +68,28 @@ static int clk_null_enable(struct clk *clk, int enable) | |||
65 | return 0; | 68 | return 0; |
66 | } | 69 | } |
67 | 70 | ||
71 | static int dev_is_s3c_uart(struct device *dev) | ||
72 | { | ||
73 | struct platform_device **pdev = s3c24xx_uart_devs; | ||
74 | int i; | ||
75 | for (i = 0; i < ARRAY_SIZE(s3c24xx_uart_devs); i++, pdev++) | ||
76 | if (*pdev && dev == &(*pdev)->dev) | ||
77 | return 1; | ||
78 | return 0; | ||
79 | } | ||
80 | |||
81 | /* | ||
82 | * Serial drivers call get_clock() very early, before platform bus | ||
83 | * has been set up, this requires a special check to let them get | ||
84 | * a proper clock | ||
85 | */ | ||
86 | |||
87 | static int dev_is_platform_device(struct device *dev) | ||
88 | { | ||
89 | return dev->bus == &platform_bus_type || | ||
90 | (dev->bus == NULL && dev_is_s3c_uart(dev)); | ||
91 | } | ||
92 | |||
68 | /* Clock API calls */ | 93 | /* Clock API calls */ |
69 | 94 | ||
70 | struct clk *clk_get(struct device *dev, const char *id) | 95 | struct clk *clk_get(struct device *dev, const char *id) |
@@ -73,7 +98,7 @@ struct clk *clk_get(struct device *dev, const char *id) | |||
73 | struct clk *clk = ERR_PTR(-ENOENT); | 98 | struct clk *clk = ERR_PTR(-ENOENT); |
74 | int idno; | 99 | int idno; |
75 | 100 | ||
76 | if (dev == NULL || dev->bus != &platform_bus_type) | 101 | if (dev == NULL || !dev_is_platform_device(dev)) |
77 | idno = -1; | 102 | idno = -1; |
78 | else | 103 | else |
79 | idno = to_platform_device(dev)->id; | 104 | idno = to_platform_device(dev)->id; |
diff --git a/arch/arm/plat-samsung/gpio-config.c b/arch/arm/plat-samsung/gpio-config.c index 57b68a50f45..e3d41eaed1f 100644 --- a/arch/arm/plat-samsung/gpio-config.c +++ b/arch/arm/plat-samsung/gpio-config.c | |||
@@ -273,13 +273,13 @@ s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin) | |||
273 | if (!chip) | 273 | if (!chip) |
274 | return -EINVAL; | 274 | return -EINVAL; |
275 | 275 | ||
276 | off = chip->chip.base - pin; | 276 | off = pin - chip->chip.base; |
277 | shift = off * 2; | 277 | shift = off * 2; |
278 | reg = chip->base + 0x0C; | 278 | reg = chip->base + 0x0C; |
279 | 279 | ||
280 | drvstr = __raw_readl(reg); | 280 | drvstr = __raw_readl(reg); |
281 | drvstr = 0xffff & (0x3 << shift); | ||
282 | drvstr = drvstr >> shift; | 281 | drvstr = drvstr >> shift; |
282 | drvstr &= 0x3; | ||
283 | 283 | ||
284 | return (__force s5p_gpio_drvstr_t)drvstr; | 284 | return (__force s5p_gpio_drvstr_t)drvstr; |
285 | } | 285 | } |
@@ -296,11 +296,12 @@ int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr) | |||
296 | if (!chip) | 296 | if (!chip) |
297 | return -EINVAL; | 297 | return -EINVAL; |
298 | 298 | ||
299 | off = chip->chip.base - pin; | 299 | off = pin - chip->chip.base; |
300 | shift = off * 2; | 300 | shift = off * 2; |
301 | reg = chip->base + 0x0C; | 301 | reg = chip->base + 0x0C; |
302 | 302 | ||
303 | tmp = __raw_readl(reg); | 303 | tmp = __raw_readl(reg); |
304 | tmp &= ~(0x3 << shift); | ||
304 | tmp |= drvstr << shift; | 305 | tmp |= drvstr << shift; |
305 | 306 | ||
306 | __raw_writel(tmp, reg); | 307 | __raw_writel(tmp, reg); |
diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg.h b/arch/arm/plat-samsung/include/plat/gpio-cfg.h index db4112c6f2b..1c6b92947c5 100644 --- a/arch/arm/plat-samsung/include/plat/gpio-cfg.h +++ b/arch/arm/plat-samsung/include/plat/gpio-cfg.h | |||
@@ -143,12 +143,12 @@ extern s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin); | |||
143 | /* Define values for the drvstr available for each gpio pin. | 143 | /* Define values for the drvstr available for each gpio pin. |
144 | * | 144 | * |
145 | * These values control the value of the output signal driver strength, | 145 | * These values control the value of the output signal driver strength, |
146 | * configurable on most pins on the S5C series. | 146 | * configurable on most pins on the S5P series. |
147 | */ | 147 | */ |
148 | #define S5P_GPIO_DRVSTR_LV1 ((__force s5p_gpio_drvstr_t)0x00) | 148 | #define S5P_GPIO_DRVSTR_LV1 ((__force s5p_gpio_drvstr_t)0x0) |
149 | #define S5P_GPIO_DRVSTR_LV2 ((__force s5p_gpio_drvstr_t)0x01) | 149 | #define S5P_GPIO_DRVSTR_LV2 ((__force s5p_gpio_drvstr_t)0x2) |
150 | #define S5P_GPIO_DRVSTR_LV3 ((__force s5p_gpio_drvstr_t)0x10) | 150 | #define S5P_GPIO_DRVSTR_LV3 ((__force s5p_gpio_drvstr_t)0x1) |
151 | #define S5P_GPIO_DRVSTR_LV4 ((__force s5p_gpio_drvstr_t)0x11) | 151 | #define S5P_GPIO_DRVSTR_LV4 ((__force s5p_gpio_drvstr_t)0x3) |
152 | 152 | ||
153 | /** | 153 | /** |
154 | * s5c_gpio_get_drvstr() - get the driver streght value of a gpio pin | 154 | * s5c_gpio_get_drvstr() - get the driver streght value of a gpio pin |
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index 48cbdcb6bbd..55590a4d87c 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types | |||
@@ -12,7 +12,7 @@ | |||
12 | # | 12 | # |
13 | # http://www.arm.linux.org.uk/developer/machines/?action=new | 13 | # http://www.arm.linux.org.uk/developer/machines/?action=new |
14 | # | 14 | # |
15 | # Last update: Mon Jul 12 21:10:14 2010 | 15 | # Last update: Thu Sep 9 22:43:01 2010 |
16 | # | 16 | # |
17 | # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number | 17 | # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number |
18 | # | 18 | # |
@@ -2622,7 +2622,7 @@ kraken MACH_KRAKEN KRAKEN 2634 | |||
2622 | gw2388 MACH_GW2388 GW2388 2635 | 2622 | gw2388 MACH_GW2388 GW2388 2635 |
2623 | jadecpu MACH_JADECPU JADECPU 2636 | 2623 | jadecpu MACH_JADECPU JADECPU 2636 |
2624 | carlisle MACH_CARLISLE CARLISLE 2637 | 2624 | carlisle MACH_CARLISLE CARLISLE 2637 |
2625 | lux_sf9 MACH_LUX_SFT9 LUX_SFT9 2638 | 2625 | lux_sf9 MACH_LUX_SF9 LUX_SF9 2638 |
2626 | nemid_tb MACH_NEMID_TB NEMID_TB 2639 | 2626 | nemid_tb MACH_NEMID_TB NEMID_TB 2639 |
2627 | terrier MACH_TERRIER TERRIER 2640 | 2627 | terrier MACH_TERRIER TERRIER 2640 |
2628 | turbot MACH_TURBOT TURBOT 2641 | 2628 | turbot MACH_TURBOT TURBOT 2641 |
@@ -2950,3 +2950,97 @@ davinci_dm365_dvr MACH_DAVINCI_DM365_DVR DAVINCI_DM365_DVR 2963 | |||
2950 | netviz MACH_NETVIZ NETVIZ 2964 | 2950 | netviz MACH_NETVIZ NETVIZ 2964 |
2951 | flexibity MACH_FLEXIBITY FLEXIBITY 2965 | 2951 | flexibity MACH_FLEXIBITY FLEXIBITY 2965 |
2952 | wlan_computer MACH_WLAN_COMPUTER WLAN_COMPUTER 2966 | 2952 | wlan_computer MACH_WLAN_COMPUTER WLAN_COMPUTER 2966 |
2953 | lpc24xx MACH_LPC24XX LPC24XX 2967 | ||
2954 | spica MACH_SPICA SPICA 2968 | ||
2955 | gpsdisplay MACH_GPSDISPLAY GPSDISPLAY 2969 | ||
2956 | bipnet MACH_BIPNET BIPNET 2970 | ||
2957 | overo_ctu_inertial MACH_OVERO_CTU_INERTIAL OVERO_CTU_INERTIAL 2971 | ||
2958 | davinci_dm355_mmm MACH_DAVINCI_DM355_MMM DAVINCI_DM355_MMM 2972 | ||
2959 | pc9260_v2 MACH_PC9260_V2 PC9260_V2 2973 | ||
2960 | ptx7545 MACH_PTX7545 PTX7545 2974 | ||
2961 | tm_efdc MACH_TM_EFDC TM_EFDC 2975 | ||
2962 | omap3_waldo1 MACH_OMAP3_WALDO1 OMAP3_WALDO1 2977 | ||
2963 | flyer MACH_FLYER FLYER 2978 | ||
2964 | tornado3240 MACH_TORNADO3240 TORNADO3240 2979 | ||
2965 | soli_01 MACH_SOLI_01 SOLI_01 2980 | ||
2966 | omapl138_europalc MACH_OMAPL138_EUROPALC OMAPL138_EUROPALC 2981 | ||
2967 | helios_v1 MACH_HELIOS_V1 HELIOS_V1 2982 | ||
2968 | netspace_lite_v2 MACH_NETSPACE_LITE_V2 NETSPACE_LITE_V2 2983 | ||
2969 | ssc MACH_SSC SSC 2984 | ||
2970 | premierwave_en MACH_PREMIERWAVE_EN PREMIERWAVE_EN 2985 | ||
2971 | wasabi MACH_WASABI WASABI 2986 | ||
2972 | vivow MACH_VIVOW VIVOW 2987 | ||
2973 | mx50_rdp MACH_MX50_RDP MX50_RDP 2988 | ||
2974 | universal MACH_UNIVERSAL UNIVERSAL 2989 | ||
2975 | real6410 MACH_REAL6410 REAL6410 2990 | ||
2976 | spx_sakura MACH_SPX_SAKURA SPX_SAKURA 2991 | ||
2977 | ij3k_2440 MACH_IJ3K_2440 IJ3K_2440 2992 | ||
2978 | omap3_bc10 MACH_OMAP3_BC10 OMAP3_BC10 2993 | ||
2979 | thebe MACH_THEBE THEBE 2994 | ||
2980 | rv082 MACH_RV082 RV082 2995 | ||
2981 | armlguest MACH_ARMLGUEST ARMLGUEST 2996 | ||
2982 | tjinc1000 MACH_TJINC1000 TJINC1000 2997 | ||
2983 | dockstar MACH_DOCKSTAR DOCKSTAR 2998 | ||
2984 | ax8008 MACH_AX8008 AX8008 2999 | ||
2985 | gnet_sgce MACH_GNET_SGCE GNET_SGCE 3000 | ||
2986 | pxwnas_500_1000 MACH_PXWNAS_500_1000 PXWNAS_500_1000 3001 | ||
2987 | ea20 MACH_EA20 EA20 3002 | ||
2988 | awm2 MACH_AWM2 AWM2 3003 | ||
2989 | ti8148evm MACH_TI8148EVM TI8148EVM 3004 | ||
2990 | tegra_seaboard MACH_TEGRA_SEABOARD TEGRA_SEABOARD 3005 | ||
2991 | linkstation_chlv2 MACH_LINKSTATION_CHLV2 LINKSTATION_CHLV2 3006 | ||
2992 | tera_pro2_rack MACH_TERA_PRO2_RACK TERA_PRO2_RACK 3007 | ||
2993 | rubys MACH_RUBYS RUBYS 3008 | ||
2994 | aquarius MACH_AQUARIUS AQUARIUS 3009 | ||
2995 | mx53_ard MACH_MX53_ARD MX53_ARD 3010 | ||
2996 | mx53_smd MACH_MX53_SMD MX53_SMD 3011 | ||
2997 | lswxl MACH_LSWXL LSWXL 3012 | ||
2998 | dove_avng_v3 MACH_DOVE_AVNG_V3 DOVE_AVNG_V3 3013 | ||
2999 | sdi_ess_9263 MACH_SDI_ESS_9263 SDI_ESS_9263 3014 | ||
3000 | jocpu550 MACH_JOCPU550 JOCPU550 3015 | ||
3001 | msm8x60_rumi3 MACH_MSM8X60_RUMI3 MSM8X60_RUMI3 3016 | ||
3002 | msm8x60_ffa MACH_MSM8X60_FFA MSM8X60_FFA 3017 | ||
3003 | yanomami MACH_YANOMAMI YANOMAMI 3018 | ||
3004 | gta04 MACH_GTA04 GTA04 3019 | ||
3005 | cm_a510 MACH_CM_A510 CM_A510 3020 | ||
3006 | omap3_rfs200 MACH_OMAP3_RFS200 OMAP3_RFS200 3021 | ||
3007 | kx33xx MACH_KX33XX KX33XX 3022 | ||
3008 | ptx7510 MACH_PTX7510 PTX7510 3023 | ||
3009 | top9000 MACH_TOP9000 TOP9000 3024 | ||
3010 | teenote MACH_TEENOTE TEENOTE 3025 | ||
3011 | ts3 MACH_TS3 TS3 3026 | ||
3012 | a0 MACH_A0 A0 3027 | ||
3013 | fsm9xxx_surf MACH_FSM9XXX_SURF FSM9XXX_SURF 3028 | ||
3014 | fsm9xxx_ffa MACH_FSM9XXX_FFA FSM9XXX_FFA 3029 | ||
3015 | frrhwcdma60w MACH_FRRHWCDMA60W FRRHWCDMA60W 3030 | ||
3016 | remus MACH_REMUS REMUS 3031 | ||
3017 | at91cap7xdk MACH_AT91CAP7XDK AT91CAP7XDK 3032 | ||
3018 | at91cap7stk MACH_AT91CAP7STK AT91CAP7STK 3033 | ||
3019 | kt_sbc_sam9_1 MACH_KT_SBC_SAM9_1 KT_SBC_SAM9_1 3034 | ||
3020 | oratisrouter MACH_ORATISROUTER ORATISROUTER 3035 | ||
3021 | armada_xp_db MACH_ARMADA_XP_DB ARMADA_XP_DB 3036 | ||
3022 | spdm MACH_SPDM SPDM 3037 | ||
3023 | gtib MACH_GTIB GTIB 3038 | ||
3024 | dgm3240 MACH_DGM3240 DGM3240 3039 | ||
3025 | atlas_i_lpe MACH_ATLAS_I_LPE ATLAS_I_LPE 3040 | ||
3026 | htcmega MACH_HTCMEGA HTCMEGA 3041 | ||
3027 | tricorder MACH_TRICORDER TRICORDER 3042 | ||
3028 | tx28 MACH_TX28 TX28 3043 | ||
3029 | bstbrd MACH_BSTBRD BSTBRD 3044 | ||
3030 | pwb3090 MACH_PWB3090 PWB3090 3045 | ||
3031 | idea6410 MACH_IDEA6410 IDEA6410 3046 | ||
3032 | qbc9263 MACH_QBC9263 QBC9263 3047 | ||
3033 | borabora MACH_BORABORA BORABORA 3048 | ||
3034 | valdez MACH_VALDEZ VALDEZ 3049 | ||
3035 | ls9g20 MACH_LS9G20 LS9G20 3050 | ||
3036 | mios_v1 MACH_MIOS_V1 MIOS_V1 3051 | ||
3037 | s5pc110_crespo MACH_S5PC110_CRESPO S5PC110_CRESPO 3052 | ||
3038 | controltek9g20 MACH_CONTROLTEK9G20 CONTROLTEK9G20 3053 | ||
3039 | tin307 MACH_TIN307 TIN307 3054 | ||
3040 | tin510 MACH_TIN510 TIN510 3055 | ||
3041 | bluecheese MACH_BLUECHEESE BLUECHEESE 3057 | ||
3042 | tem3x30 MACH_TEM3X30 TEM3X30 3058 | ||
3043 | harvest_desoto MACH_HARVEST_DESOTO HARVEST_DESOTO 3059 | ||
3044 | msm8x60_qrdc MACH_MSM8X60_QRDC MSM8X60_QRDC 3060 | ||
3045 | spear900 MACH_SPEAR900 SPEAR900 3061 | ||
3046 | pcontrol_g20 MACH_PCONTROL_G20 PCONTROL_G20 3062 | ||
diff --git a/arch/avr32/kernel/module.c b/arch/avr32/kernel/module.c index 98f94d041d9..a727f54d64d 100644 --- a/arch/avr32/kernel/module.c +++ b/arch/avr32/kernel/module.c | |||
@@ -314,10 +314,9 @@ int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, | |||
314 | vfree(module->arch.syminfo); | 314 | vfree(module->arch.syminfo); |
315 | module->arch.syminfo = NULL; | 315 | module->arch.syminfo = NULL; |
316 | 316 | ||
317 | return module_bug_finalize(hdr, sechdrs, module); | 317 | return 0; |
318 | } | 318 | } |
319 | 319 | ||
320 | void module_arch_cleanup(struct module *module) | 320 | void module_arch_cleanup(struct module *module) |
321 | { | 321 | { |
322 | module_bug_cleanup(module); | ||
323 | } | 322 | } |
diff --git a/arch/blackfin/include/asm/bfin_sport.h b/arch/blackfin/include/asm/bfin_sport.h index 9626cf7e425..d27600c262c 100644 --- a/arch/blackfin/include/asm/bfin_sport.h +++ b/arch/blackfin/include/asm/bfin_sport.h | |||
@@ -115,12 +115,6 @@ struct sport_register { | |||
115 | 115 | ||
116 | #endif | 116 | #endif |
117 | 117 | ||
118 | /* Workaround defBF*.h SPORT MMRs till they get cleansed */ | ||
119 | #undef DTYPE_NORM | ||
120 | #undef SLEN | ||
121 | #undef SP_WOFF | ||
122 | #undef SP_WSIZE | ||
123 | |||
124 | /* SPORT_TCR1 Masks */ | 118 | /* SPORT_TCR1 Masks */ |
125 | #define TSPEN 0x0001 /* TX enable */ | 119 | #define TSPEN 0x0001 /* TX enable */ |
126 | #define ITCLK 0x0002 /* Internal TX Clock Select */ | 120 | #define ITCLK 0x0002 /* Internal TX Clock Select */ |
diff --git a/arch/blackfin/include/asm/bitops.h b/arch/blackfin/include/asm/bitops.h index d5872cd967a..3f7ef4d9779 100644 --- a/arch/blackfin/include/asm/bitops.h +++ b/arch/blackfin/include/asm/bitops.h | |||
@@ -22,7 +22,9 @@ | |||
22 | 22 | ||
23 | #include <asm-generic/bitops/sched.h> | 23 | #include <asm-generic/bitops/sched.h> |
24 | #include <asm-generic/bitops/ffs.h> | 24 | #include <asm-generic/bitops/ffs.h> |
25 | #include <asm-generic/bitops/const_hweight.h> | ||
25 | #include <asm-generic/bitops/lock.h> | 26 | #include <asm-generic/bitops/lock.h> |
27 | |||
26 | #include <asm-generic/bitops/ext2-non-atomic.h> | 28 | #include <asm-generic/bitops/ext2-non-atomic.h> |
27 | #include <asm-generic/bitops/ext2-atomic.h> | 29 | #include <asm-generic/bitops/ext2-atomic.h> |
28 | #include <asm-generic/bitops/minix.h> | 30 | #include <asm-generic/bitops/minix.h> |
@@ -115,7 +117,7 @@ static inline int test_and_change_bit(int nr, volatile unsigned long *addr) | |||
115 | * of bits set) of a N-bit word | 117 | * of bits set) of a N-bit word |
116 | */ | 118 | */ |
117 | 119 | ||
118 | static inline unsigned int hweight32(unsigned int w) | 120 | static inline unsigned int __arch_hweight32(unsigned int w) |
119 | { | 121 | { |
120 | unsigned int res; | 122 | unsigned int res; |
121 | 123 | ||
@@ -125,19 +127,20 @@ static inline unsigned int hweight32(unsigned int w) | |||
125 | return res; | 127 | return res; |
126 | } | 128 | } |
127 | 129 | ||
128 | static inline unsigned int hweight64(__u64 w) | 130 | static inline unsigned int __arch_hweight64(__u64 w) |
129 | { | 131 | { |
130 | return hweight32((unsigned int)(w >> 32)) + hweight32((unsigned int)w); | 132 | return __arch_hweight32((unsigned int)(w >> 32)) + |
133 | __arch_hweight32((unsigned int)w); | ||
131 | } | 134 | } |
132 | 135 | ||
133 | static inline unsigned int hweight16(unsigned int w) | 136 | static inline unsigned int __arch_hweight16(unsigned int w) |
134 | { | 137 | { |
135 | return hweight32(w & 0xffff); | 138 | return __arch_hweight32(w & 0xffff); |
136 | } | 139 | } |
137 | 140 | ||
138 | static inline unsigned int hweight8(unsigned int w) | 141 | static inline unsigned int __arch_hweight8(unsigned int w) |
139 | { | 142 | { |
140 | return hweight32(w & 0xff); | 143 | return __arch_hweight32(w & 0xff); |
141 | } | 144 | } |
142 | 145 | ||
143 | #endif /* _BLACKFIN_BITOPS_H */ | 146 | #endif /* _BLACKFIN_BITOPS_H */ |
diff --git a/arch/blackfin/include/asm/unistd.h b/arch/blackfin/include/asm/unistd.h index 22886cbdae7..14fcd254b18 100644 --- a/arch/blackfin/include/asm/unistd.h +++ b/arch/blackfin/include/asm/unistd.h | |||
@@ -389,8 +389,11 @@ | |||
389 | #define __NR_rt_tgsigqueueinfo 368 | 389 | #define __NR_rt_tgsigqueueinfo 368 |
390 | #define __NR_perf_event_open 369 | 390 | #define __NR_perf_event_open 369 |
391 | #define __NR_recvmmsg 370 | 391 | #define __NR_recvmmsg 370 |
392 | #define __NR_fanotify_init 371 | ||
393 | #define __NR_fanotify_mark 372 | ||
394 | #define __NR_prlimit64 373 | ||
392 | 395 | ||
393 | #define __NR_syscall 371 | 396 | #define __NR_syscall 374 |
394 | #define NR_syscalls __NR_syscall | 397 | #define NR_syscalls __NR_syscall |
395 | 398 | ||
396 | /* Old optional stuff no one actually uses */ | 399 | /* Old optional stuff no one actually uses */ |
diff --git a/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h b/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h index 2bc8f4f9801..037a51fd8e9 100644 --- a/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h +++ b/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h | |||
@@ -913,88 +913,6 @@ | |||
913 | #define PH6 0x0040 | 913 | #define PH6 0x0040 |
914 | #define PH7 0x0080 | 914 | #define PH7 0x0080 |
915 | 915 | ||
916 | |||
917 | /* ******************* SERIAL PORT MASKS **************************************/ | ||
918 | /* SPORTx_TCR1 Masks */ | ||
919 | #define TSPEN 0x0001 /* Transmit Enable */ | ||
920 | #define ITCLK 0x0002 /* Internal Transmit Clock Select */ | ||
921 | #define DTYPE_NORM 0x0004 /* Data Format Normal */ | ||
922 | #define DTYPE_ULAW 0x0008 /* Compand Using u-Law */ | ||
923 | #define DTYPE_ALAW 0x000C /* Compand Using A-Law */ | ||
924 | #define TLSBIT 0x0010 /* Transmit Bit Order */ | ||
925 | #define ITFS 0x0200 /* Internal Transmit Frame Sync Select */ | ||
926 | #define TFSR 0x0400 /* Transmit Frame Sync Required Select */ | ||
927 | #define DITFS 0x0800 /* Data-Independent Transmit Frame Sync Select */ | ||
928 | #define LTFS 0x1000 /* Low Transmit Frame Sync Select */ | ||
929 | #define LATFS 0x2000 /* Late Transmit Frame Sync Select */ | ||
930 | #define TCKFE 0x4000 /* Clock Falling Edge Select */ | ||
931 | |||
932 | /* SPORTx_TCR2 Masks and Macro */ | ||
933 | #define SLEN(x) ((x)&0x1F) /* SPORT TX Word Length (2 - 31) */ | ||
934 | #define TXSE 0x0100 /* TX Secondary Enable */ | ||
935 | #define TSFSE 0x0200 /* Transmit Stereo Frame Sync Enable */ | ||
936 | #define TRFST 0x0400 /* Left/Right Order (1 = Right Channel 1st) */ | ||
937 | |||
938 | /* SPORTx_RCR1 Masks */ | ||
939 | #define RSPEN 0x0001 /* Receive Enable */ | ||
940 | #define IRCLK 0x0002 /* Internal Receive Clock Select */ | ||
941 | #define DTYPE_NORM 0x0004 /* Data Format Normal */ | ||
942 | #define DTYPE_ULAW 0x0008 /* Compand Using u-Law */ | ||
943 | #define DTYPE_ALAW 0x000C /* Compand Using A-Law */ | ||
944 | #define RLSBIT 0x0010 /* Receive Bit Order */ | ||
945 | #define IRFS 0x0200 /* Internal Receive Frame Sync Select */ | ||
946 | #define RFSR 0x0400 /* Receive Frame Sync Required Select */ | ||
947 | #define LRFS 0x1000 /* Low Receive Frame Sync Select */ | ||
948 | #define LARFS 0x2000 /* Late Receive Frame Sync Select */ | ||
949 | #define RCKFE 0x4000 /* Clock Falling Edge Select */ | ||
950 | |||
951 | /* SPORTx_RCR2 Masks */ | ||
952 | #define SLEN(x) ((x)&0x1F) /* SPORT RX Word Length (2 - 31) */ | ||
953 | #define RXSE 0x0100 /* RX Secondary Enable */ | ||
954 | #define RSFSE 0x0200 /* RX Stereo Frame Sync Enable */ | ||
955 | #define RRFST 0x0400 /* Right-First Data Order */ | ||
956 | |||
957 | /* SPORTx_STAT Masks */ | ||
958 | #define RXNE 0x0001 /* Receive FIFO Not Empty Status */ | ||
959 | #define RUVF 0x0002 /* Sticky Receive Underflow Status */ | ||
960 | #define ROVF 0x0004 /* Sticky Receive Overflow Status */ | ||
961 | #define TXF 0x0008 /* Transmit FIFO Full Status */ | ||
962 | #define TUVF 0x0010 /* Sticky Transmit Underflow Status */ | ||
963 | #define TOVF 0x0020 /* Sticky Transmit Overflow Status */ | ||
964 | #define TXHRE 0x0040 /* Transmit Hold Register Empty */ | ||
965 | |||
966 | /* SPORTx_MCMC1 Macros */ | ||
967 | #define SP_WOFF(x) ((x) & 0x3FF) /* Multichannel Window Offset Field */ | ||
968 | |||
969 | /* Only use WSIZE Macro With Logic OR While Setting Lower Order Bits */ | ||
970 | #define SP_WSIZE(x) (((((x)>>0x3)-1)&0xF) << 0xC) /* Multichannel Window Size = (x/8)-1 */ | ||
971 | |||
972 | /* SPORTx_MCMC2 Masks */ | ||
973 | #define REC_BYPASS 0x0000 /* Bypass Mode (No Clock Recovery) */ | ||
974 | #define REC_2FROM4 0x0002 /* Recover 2 MHz Clock from 4 MHz Clock */ | ||
975 | #define REC_8FROM16 0x0003 /* Recover 8 MHz Clock from 16 MHz Clock */ | ||
976 | #define MCDTXPE 0x0004 /* Multichannel DMA Transmit Packing */ | ||
977 | #define MCDRXPE 0x0008 /* Multichannel DMA Receive Packing */ | ||
978 | #define MCMEN 0x0010 /* Multichannel Frame Mode Enable */ | ||
979 | #define FSDR 0x0080 /* Multichannel Frame Sync to Data Relationship */ | ||
980 | #define MFD_0 0x0000 /* Multichannel Frame Delay = 0 */ | ||
981 | #define MFD_1 0x1000 /* Multichannel Frame Delay = 1 */ | ||
982 | #define MFD_2 0x2000 /* Multichannel Frame Delay = 2 */ | ||
983 | #define MFD_3 0x3000 /* Multichannel Frame Delay = 3 */ | ||
984 | #define MFD_4 0x4000 /* Multichannel Frame Delay = 4 */ | ||
985 | #define MFD_5 0x5000 /* Multichannel Frame Delay = 5 */ | ||
986 | #define MFD_6 0x6000 /* Multichannel Frame Delay = 6 */ | ||
987 | #define MFD_7 0x7000 /* Multichannel Frame Delay = 7 */ | ||
988 | #define MFD_8 0x8000 /* Multichannel Frame Delay = 8 */ | ||
989 | #define MFD_9 0x9000 /* Multichannel Frame Delay = 9 */ | ||
990 | #define MFD_10 0xA000 /* Multichannel Frame Delay = 10 */ | ||
991 | #define MFD_11 0xB000 /* Multichannel Frame Delay = 11 */ | ||
992 | #define MFD_12 0xC000 /* Multichannel Frame Delay = 12 */ | ||
993 | #define MFD_13 0xD000 /* Multichannel Frame Delay = 13 */ | ||
994 | #define MFD_14 0xE000 /* Multichannel Frame Delay = 14 */ | ||
995 | #define MFD_15 0xF000 /* Multichannel Frame Delay = 15 */ | ||
996 | |||
997 | |||
998 | /* ********************* ASYNCHRONOUS MEMORY CONTROLLER MASKS *************************/ | 916 | /* ********************* ASYNCHRONOUS MEMORY CONTROLLER MASKS *************************/ |
999 | /* EBIU_AMGCTL Masks */ | 917 | /* EBIU_AMGCTL Masks */ |
1000 | #define AMCKEN 0x0001 /* Enable CLKOUT */ | 918 | #define AMCKEN 0x0001 /* Enable CLKOUT */ |
diff --git a/arch/blackfin/mach-bf527/boards/cm_bf527.c b/arch/blackfin/mach-bf527/boards/cm_bf527.c index f392af64165..645ba5c8077 100644 --- a/arch/blackfin/mach-bf527/boards/cm_bf527.c +++ b/arch/blackfin/mach-bf527/boards/cm_bf527.c | |||
@@ -145,7 +145,6 @@ static struct mtd_partition partition_info[] = { | |||
145 | }; | 145 | }; |
146 | 146 | ||
147 | static struct bf5xx_nand_platform bf5xx_nand_platform = { | 147 | static struct bf5xx_nand_platform bf5xx_nand_platform = { |
148 | .page_size = NFC_PG_SIZE_256, | ||
149 | .data_width = NFC_NWIDTH_8, | 148 | .data_width = NFC_NWIDTH_8, |
150 | .partitions = partition_info, | 149 | .partitions = partition_info, |
151 | .nr_partitions = ARRAY_SIZE(partition_info), | 150 | .nr_partitions = ARRAY_SIZE(partition_info), |
diff --git a/arch/blackfin/mach-bf527/boards/ezbrd.c b/arch/blackfin/mach-bf527/boards/ezbrd.c index 606eb36b9d6..c975fe88eba 100644 --- a/arch/blackfin/mach-bf527/boards/ezbrd.c +++ b/arch/blackfin/mach-bf527/boards/ezbrd.c | |||
@@ -149,7 +149,6 @@ static struct mtd_partition partition_info[] = { | |||
149 | }; | 149 | }; |
150 | 150 | ||
151 | static struct bf5xx_nand_platform bf5xx_nand_platform = { | 151 | static struct bf5xx_nand_platform bf5xx_nand_platform = { |
152 | .page_size = NFC_PG_SIZE_256, | ||
153 | .data_width = NFC_NWIDTH_8, | 152 | .data_width = NFC_NWIDTH_8, |
154 | .partitions = partition_info, | 153 | .partitions = partition_info, |
155 | .nr_partitions = ARRAY_SIZE(partition_info), | 154 | .nr_partitions = ARRAY_SIZE(partition_info), |
diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c index a05c967a24c..87b41e994ba 100644 --- a/arch/blackfin/mach-bf527/boards/ezkit.c +++ b/arch/blackfin/mach-bf527/boards/ezkit.c | |||
@@ -234,7 +234,6 @@ static struct mtd_partition partition_info[] = { | |||
234 | }; | 234 | }; |
235 | 235 | ||
236 | static struct bf5xx_nand_platform bf5xx_nand_platform = { | 236 | static struct bf5xx_nand_platform bf5xx_nand_platform = { |
237 | .page_size = NFC_PG_SIZE_256, | ||
238 | .data_width = NFC_NWIDTH_8, | 237 | .data_width = NFC_NWIDTH_8, |
239 | .partitions = partition_info, | 238 | .partitions = partition_info, |
240 | .nr_partitions = ARRAY_SIZE(partition_info), | 239 | .nr_partitions = ARRAY_SIZE(partition_info), |
diff --git a/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h b/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h index 5f97f01fcda..3e000756aac 100644 --- a/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h +++ b/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h | |||
@@ -922,88 +922,6 @@ | |||
922 | #define PH14 0x4000 | 922 | #define PH14 0x4000 |
923 | #define PH15 0x8000 | 923 | #define PH15 0x8000 |
924 | 924 | ||
925 | |||
926 | /* ******************* SERIAL PORT MASKS **************************************/ | ||
927 | /* SPORTx_TCR1 Masks */ | ||
928 | #define TSPEN 0x0001 /* Transmit Enable */ | ||
929 | #define ITCLK 0x0002 /* Internal Transmit Clock Select */ | ||
930 | #define DTYPE_NORM 0x0004 /* Data Format Normal */ | ||
931 | #define DTYPE_ULAW 0x0008 /* Compand Using u-Law */ | ||
932 | #define DTYPE_ALAW 0x000C /* Compand Using A-Law */ | ||
933 | #define TLSBIT 0x0010 /* Transmit Bit Order */ | ||
934 | #define ITFS 0x0200 /* Internal Transmit Frame Sync Select */ | ||
935 | #define TFSR 0x0400 /* Transmit Frame Sync Required Select */ | ||
936 | #define DITFS 0x0800 /* Data-Independent Transmit Frame Sync Select */ | ||
937 | #define LTFS 0x1000 /* Low Transmit Frame Sync Select */ | ||
938 | #define LATFS 0x2000 /* Late Transmit Frame Sync Select */ | ||
939 | #define TCKFE 0x4000 /* Clock Falling Edge Select */ | ||
940 | |||
941 | /* SPORTx_TCR2 Masks and Macro */ | ||
942 | #define SLEN(x) ((x)&0x1F) /* SPORT TX Word Length (2 - 31) */ | ||
943 | #define TXSE 0x0100 /* TX Secondary Enable */ | ||
944 | #define TSFSE 0x0200 /* Transmit Stereo Frame Sync Enable */ | ||
945 | #define TRFST 0x0400 /* Left/Right Order (1 = Right Channel 1st) */ | ||
946 | |||
947 | /* SPORTx_RCR1 Masks */ | ||
948 | #define RSPEN 0x0001 /* Receive Enable */ | ||
949 | #define IRCLK 0x0002 /* Internal Receive Clock Select */ | ||
950 | #define DTYPE_NORM 0x0004 /* Data Format Normal */ | ||
951 | #define DTYPE_ULAW 0x0008 /* Compand Using u-Law */ | ||
952 | #define DTYPE_ALAW 0x000C /* Compand Using A-Law */ | ||
953 | #define RLSBIT 0x0010 /* Receive Bit Order */ | ||
954 | #define IRFS 0x0200 /* Internal Receive Frame Sync Select */ | ||
955 | #define RFSR 0x0400 /* Receive Frame Sync Required Select */ | ||
956 | #define LRFS 0x1000 /* Low Receive Frame Sync Select */ | ||
957 | #define LARFS 0x2000 /* Late Receive Frame Sync Select */ | ||
958 | #define RCKFE 0x4000 /* Clock Falling Edge Select */ | ||
959 | |||
960 | /* SPORTx_RCR2 Masks */ | ||
961 | #define SLEN(x) ((x)&0x1F) /* SPORT RX Word Length (2 - 31) */ | ||
962 | #define RXSE 0x0100 /* RX Secondary Enable */ | ||
963 | #define RSFSE 0x0200 /* RX Stereo Frame Sync Enable */ | ||
964 | #define RRFST 0x0400 /* Right-First Data Order */ | ||
965 | |||
966 | /* SPORTx_STAT Masks */ | ||
967 | #define RXNE 0x0001 /* Receive FIFO Not Empty Status */ | ||
968 | #define RUVF 0x0002 /* Sticky Receive Underflow Status */ | ||
969 | #define ROVF 0x0004 /* Sticky Receive Overflow Status */ | ||
970 | #define TXF 0x0008 /* Transmit FIFO Full Status */ | ||
971 | #define TUVF 0x0010 /* Sticky Transmit Underflow Status */ | ||
972 | #define TOVF 0x0020 /* Sticky Transmit Overflow Status */ | ||
973 | #define TXHRE 0x0040 /* Transmit Hold Register Empty */ | ||
974 | |||
975 | /* SPORTx_MCMC1 Macros */ | ||
976 | #define SP_WOFF(x) ((x) & 0x3FF) /* Multichannel Window Offset Field */ | ||
977 | |||
978 | /* Only use WSIZE Macro With Logic OR While Setting Lower Order Bits */ | ||
979 | #define SP_WSIZE(x) (((((x)>>0x3)-1)&0xF) << 0xC) /* Multichannel Window Size = (x/8)-1 */ | ||
980 | |||
981 | /* SPORTx_MCMC2 Masks */ | ||
982 | #define REC_BYPASS 0x0000 /* Bypass Mode (No Clock Recovery) */ | ||
983 | #define REC_2FROM4 0x0002 /* Recover 2 MHz Clock from 4 MHz Clock */ | ||
984 | #define REC_8FROM16 0x0003 /* Recover 8 MHz Clock from 16 MHz Clock */ | ||
985 | #define MCDTXPE 0x0004 /* Multichannel DMA Transmit Packing */ | ||
986 | #define MCDRXPE 0x0008 /* Multichannel DMA Receive Packing */ | ||
987 | #define MCMEN 0x0010 /* Multichannel Frame Mode Enable */ | ||
988 | #define FSDR 0x0080 /* Multichannel Frame Sync to Data Relationship */ | ||
989 | #define MFD_0 0x0000 /* Multichannel Frame Delay = 0 */ | ||
990 | #define MFD_1 0x1000 /* Multichannel Frame Delay = 1 */ | ||
991 | #define MFD_2 0x2000 /* Multichannel Frame Delay = 2 */ | ||
992 | #define MFD_3 0x3000 /* Multichannel Frame Delay = 3 */ | ||
993 | #define MFD_4 0x4000 /* Multichannel Frame Delay = 4 */ | ||
994 | #define MFD_5 0x5000 /* Multichannel Frame Delay = 5 */ | ||
995 | #define MFD_6 0x6000 /* Multichannel Frame Delay = 6 */ | ||
996 | #define MFD_7 0x7000 /* Multichannel Frame Delay = 7 */ | ||
997 | #define MFD_8 0x8000 /* Multichannel Frame Delay = 8 */ | ||
998 | #define MFD_9 0x9000 /* Multichannel Frame Delay = 9 */ | ||
999 | #define MFD_10 0xA000 /* Multichannel Frame Delay = 10 */ | ||
1000 | #define MFD_11 0xB000 /* Multichannel Frame Delay = 11 */ | ||
1001 | #define MFD_12 0xC000 /* Multichannel Frame Delay = 12 */ | ||
1002 | #define MFD_13 0xD000 /* Multichannel Frame Delay = 13 */ | ||
1003 | #define MFD_14 0xE000 /* Multichannel Frame Delay = 14 */ | ||
1004 | #define MFD_15 0xF000 /* Multichannel Frame Delay = 15 */ | ||
1005 | |||
1006 | |||
1007 | /* ********************* ASYNCHRONOUS MEMORY CONTROLLER MASKS *************************/ | 925 | /* ********************* ASYNCHRONOUS MEMORY CONTROLLER MASKS *************************/ |
1008 | /* EBIU_AMGCTL Masks */ | 926 | /* EBIU_AMGCTL Masks */ |
1009 | #define AMCKEN 0x0001 /* Enable CLKOUT */ | 927 | #define AMCKEN 0x0001 /* Enable CLKOUT */ |
diff --git a/arch/blackfin/mach-bf533/include/mach/defBF532.h b/arch/blackfin/mach-bf533/include/mach/defBF532.h index e9ff491c095..04acf1ed10f 100644 --- a/arch/blackfin/mach-bf533/include/mach/defBF532.h +++ b/arch/blackfin/mach-bf533/include/mach/defBF532.h | |||
@@ -509,98 +509,6 @@ | |||
509 | #define IREN_P 0x01 | 509 | #define IREN_P 0x01 |
510 | #define UCEN_P 0x00 | 510 | #define UCEN_P 0x00 |
511 | 511 | ||
512 | /* ********** SERIAL PORT MASKS ********************** */ | ||
513 | |||
514 | /* SPORTx_TCR1 Masks */ | ||
515 | #define TSPEN 0x0001 /* TX enable */ | ||
516 | #define ITCLK 0x0002 /* Internal TX Clock Select */ | ||
517 | #define TDTYPE 0x000C /* TX Data Formatting Select */ | ||
518 | #define DTYPE_NORM 0x0000 /* Data Format Normal */ | ||
519 | #define DTYPE_ULAW 0x0008 /* Compand Using u-Law */ | ||
520 | #define DTYPE_ALAW 0x000C /* Compand Using A-Law */ | ||
521 | #define TLSBIT 0x0010 /* TX Bit Order */ | ||
522 | #define ITFS 0x0200 /* Internal TX Frame Sync Select */ | ||
523 | #define TFSR 0x0400 /* TX Frame Sync Required Select */ | ||
524 | #define DITFS 0x0800 /* Data Independent TX Frame Sync Select */ | ||
525 | #define LTFS 0x1000 /* Low TX Frame Sync Select */ | ||
526 | #define LATFS 0x2000 /* Late TX Frame Sync Select */ | ||
527 | #define TCKFE 0x4000 /* TX Clock Falling Edge Select */ | ||
528 | |||
529 | /* SPORTx_TCR2 Masks */ | ||
530 | #if defined(__ADSPBF531__) || defined(__ADSPBF532__) || \ | ||
531 | defined(__ADSPBF533__) | ||
532 | # define SLEN 0x001F /*TX Word Length */ | ||
533 | #else | ||
534 | # define SLEN(x) ((x)&0x1F) /* SPORT TX Word Length (2 - 31) */ | ||
535 | #endif | ||
536 | #define TXSE 0x0100 /*TX Secondary Enable */ | ||
537 | #define TSFSE 0x0200 /*TX Stereo Frame Sync Enable */ | ||
538 | #define TRFST 0x0400 /*TX Right-First Data Order */ | ||
539 | |||
540 | /* SPORTx_RCR1 Masks */ | ||
541 | #define RSPEN 0x0001 /* RX enable */ | ||
542 | #define IRCLK 0x0002 /* Internal RX Clock Select */ | ||
543 | #define RDTYPE 0x000C /* RX Data Formatting Select */ | ||
544 | #define DTYPE_NORM 0x0000 /* no companding */ | ||
545 | #define DTYPE_ULAW 0x0008 /* Compand Using u-Law */ | ||
546 | #define DTYPE_ALAW 0x000C /* Compand Using A-Law */ | ||
547 | #define RLSBIT 0x0010 /* RX Bit Order */ | ||
548 | #define IRFS 0x0200 /* Internal RX Frame Sync Select */ | ||
549 | #define RFSR 0x0400 /* RX Frame Sync Required Select */ | ||
550 | #define LRFS 0x1000 /* Low RX Frame Sync Select */ | ||
551 | #define LARFS 0x2000 /* Late RX Frame Sync Select */ | ||
552 | #define RCKFE 0x4000 /* RX Clock Falling Edge Select */ | ||
553 | |||
554 | /* SPORTx_RCR2 Masks */ | ||
555 | /* SLEN defined above */ | ||
556 | #define RXSE 0x0100 /*RX Secondary Enable */ | ||
557 | #define RSFSE 0x0200 /*RX Stereo Frame Sync Enable */ | ||
558 | #define RRFST 0x0400 /*Right-First Data Order */ | ||
559 | |||
560 | /*SPORTx_STAT Masks */ | ||
561 | #define RXNE 0x0001 /*RX FIFO Not Empty Status */ | ||
562 | #define RUVF 0x0002 /*RX Underflow Status */ | ||
563 | #define ROVF 0x0004 /*RX Overflow Status */ | ||
564 | #define TXF 0x0008 /*TX FIFO Full Status */ | ||
565 | #define TUVF 0x0010 /*TX Underflow Status */ | ||
566 | #define TOVF 0x0020 /*TX Overflow Status */ | ||
567 | #define TXHRE 0x0040 /*TX Hold Register Empty */ | ||
568 | |||
569 | /*SPORTx_MCMC1 Masks */ | ||
570 | #define SP_WSIZE 0x0000F000 /*Multichannel Window Size Field */ | ||
571 | #define SP_WOFF 0x000003FF /*Multichannel Window Offset Field */ | ||
572 | /* SPORTx_MCMC1 Macros */ | ||
573 | #define SET_SP_WOFF(x) ((x) & 0x3FF) /* Multichannel Window Offset Field */ | ||
574 | /* Only use SET_WSIZE Macro With Logic OR While Setting Lower Order Bits */ | ||
575 | #define SET_SP_WSIZE(x) (((((x)>>0x3)-1)&0xF) << 0xC) /* Multichannel Window Size = (x/8)-1 */ | ||
576 | |||
577 | /*SPORTx_MCMC2 Masks */ | ||
578 | #define MCCRM 0x00000003 /*Multichannel Clock Recovery Mode */ | ||
579 | #define REC_BYPASS 0x0000 /* Bypass Mode (No Clock Recovery) */ | ||
580 | #define REC_2FROM4 0x0002 /* Recover 2 MHz Clock from 4 MHz Clock */ | ||
581 | #define REC_8FROM16 0x0003 /* Recover 8 MHz Clock from 16 MHz Clock */ | ||
582 | #define MCDTXPE 0x00000004 /*Multichannel DMA Transmit Packing */ | ||
583 | #define MCDRXPE 0x00000008 /*Multichannel DMA Receive Packing */ | ||
584 | #define MCMEN 0x00000010 /*Multichannel Frame Mode Enable */ | ||
585 | #define FSDR 0x00000080 /*Multichannel Frame Sync to Data Relationship */ | ||
586 | #define MFD 0x0000F000 /*Multichannel Frame Delay */ | ||
587 | #define MFD_0 0x0000 /* Multichannel Frame Delay = 0 */ | ||
588 | #define MFD_1 0x1000 /* Multichannel Frame Delay = 1 */ | ||
589 | #define MFD_2 0x2000 /* Multichannel Frame Delay = 2 */ | ||
590 | #define MFD_3 0x3000 /* Multichannel Frame Delay = 3 */ | ||
591 | #define MFD_4 0x4000 /* Multichannel Frame Delay = 4 */ | ||
592 | #define MFD_5 0x5000 /* Multichannel Frame Delay = 5 */ | ||
593 | #define MFD_6 0x6000 /* Multichannel Frame Delay = 6 */ | ||
594 | #define MFD_7 0x7000 /* Multichannel Frame Delay = 7 */ | ||
595 | #define MFD_8 0x8000 /* Multichannel Frame Delay = 8 */ | ||
596 | #define MFD_9 0x9000 /* Multichannel Frame Delay = 9 */ | ||
597 | #define MFD_10 0xA000 /* Multichannel Frame Delay = 10 */ | ||
598 | #define MFD_11 0xB000 /* Multichannel Frame Delay = 11 */ | ||
599 | #define MFD_12 0xC000 /* Multichannel Frame Delay = 12 */ | ||
600 | #define MFD_13 0xD000 /* Multichannel Frame Delay = 13 */ | ||
601 | #define MFD_14 0xE000 /* Multichannel Frame Delay = 14 */ | ||
602 | #define MFD_15 0xF000 /* Multichannel Frame Delay = 15 */ | ||
603 | |||
604 | /* ********* PARALLEL PERIPHERAL INTERFACE (PPI) MASKS **************** */ | 512 | /* ********* PARALLEL PERIPHERAL INTERFACE (PPI) MASKS **************** */ |
605 | 513 | ||
606 | /* PPI_CONTROL Masks */ | 514 | /* PPI_CONTROL Masks */ |
diff --git a/arch/blackfin/mach-bf537/include/mach/defBF534.h b/arch/blackfin/mach-bf537/include/mach/defBF534.h index aad61b88737..6f56907a18c 100644 --- a/arch/blackfin/mach-bf537/include/mach/defBF534.h +++ b/arch/blackfin/mach-bf537/include/mach/defBF534.h | |||
@@ -1241,86 +1241,6 @@ | |||
1241 | #define PH14 0x4000 | 1241 | #define PH14 0x4000 |
1242 | #define PH15 0x8000 | 1242 | #define PH15 0x8000 |
1243 | 1243 | ||
1244 | /* ******************* SERIAL PORT MASKS **************************************/ | ||
1245 | /* SPORTx_TCR1 Masks */ | ||
1246 | #define TSPEN 0x0001 /* Transmit Enable */ | ||
1247 | #define ITCLK 0x0002 /* Internal Transmit Clock Select */ | ||
1248 | #define DTYPE_NORM 0x0004 /* Data Format Normal */ | ||
1249 | #define DTYPE_ULAW 0x0008 /* Compand Using u-Law */ | ||
1250 | #define DTYPE_ALAW 0x000C /* Compand Using A-Law */ | ||
1251 | #define TLSBIT 0x0010 /* Transmit Bit Order */ | ||
1252 | #define ITFS 0x0200 /* Internal Transmit Frame Sync Select */ | ||
1253 | #define TFSR 0x0400 /* Transmit Frame Sync Required Select */ | ||
1254 | #define DITFS 0x0800 /* Data-Independent Transmit Frame Sync Select */ | ||
1255 | #define LTFS 0x1000 /* Low Transmit Frame Sync Select */ | ||
1256 | #define LATFS 0x2000 /* Late Transmit Frame Sync Select */ | ||
1257 | #define TCKFE 0x4000 /* Clock Falling Edge Select */ | ||
1258 | |||
1259 | /* SPORTx_TCR2 Masks and Macro */ | ||
1260 | #define SLEN(x) ((x)&0x1F) /* SPORT TX Word Length (2 - 31) */ | ||
1261 | #define TXSE 0x0100 /* TX Secondary Enable */ | ||
1262 | #define TSFSE 0x0200 /* Transmit Stereo Frame Sync Enable */ | ||
1263 | #define TRFST 0x0400 /* Left/Right Order (1 = Right Channel 1st) */ | ||
1264 | |||
1265 | /* SPORTx_RCR1 Masks */ | ||
1266 | #define RSPEN 0x0001 /* Receive Enable */ | ||
1267 | #define IRCLK 0x0002 /* Internal Receive Clock Select */ | ||
1268 | #define DTYPE_NORM 0x0004 /* Data Format Normal */ | ||
1269 | #define DTYPE_ULAW 0x0008 /* Compand Using u-Law */ | ||
1270 | #define DTYPE_ALAW 0x000C /* Compand Using A-Law */ | ||
1271 | #define RLSBIT 0x0010 /* Receive Bit Order */ | ||
1272 | #define IRFS 0x0200 /* Internal Receive Frame Sync Select */ | ||
1273 | #define RFSR 0x0400 /* Receive Frame Sync Required Select */ | ||
1274 | #define LRFS 0x1000 /* Low Receive Frame Sync Select */ | ||
1275 | #define LARFS 0x2000 /* Late Receive Frame Sync Select */ | ||
1276 | #define RCKFE 0x4000 /* Clock Falling Edge Select */ | ||
1277 | |||
1278 | /* SPORTx_RCR2 Masks */ | ||
1279 | #define SLEN(x) ((x)&0x1F) /* SPORT RX Word Length (2 - 31) */ | ||
1280 | #define RXSE 0x0100 /* RX Secondary Enable */ | ||
1281 | #define RSFSE 0x0200 /* RX Stereo Frame Sync Enable */ | ||
1282 | #define RRFST 0x0400 /* Right-First Data Order */ | ||
1283 | |||
1284 | /* SPORTx_STAT Masks */ | ||
1285 | #define RXNE 0x0001 /* Receive FIFO Not Empty Status */ | ||
1286 | #define RUVF 0x0002 /* Sticky Receive Underflow Status */ | ||
1287 | #define ROVF 0x0004 /* Sticky Receive Overflow Status */ | ||
1288 | #define TXF 0x0008 /* Transmit FIFO Full Status */ | ||
1289 | #define TUVF 0x0010 /* Sticky Transmit Underflow Status */ | ||
1290 | #define TOVF 0x0020 /* Sticky Transmit Overflow Status */ | ||
1291 | #define TXHRE 0x0040 /* Transmit Hold Register Empty */ | ||
1292 | |||
1293 | /* SPORTx_MCMC1 Macros */ | ||
1294 | #define SP_WOFF(x) ((x) & 0x3FF) /* Multichannel Window Offset Field */ | ||
1295 | |||
1296 | /* Only use WSIZE Macro With Logic OR While Setting Lower Order Bits */ | ||
1297 | #define SP_WSIZE(x) (((((x)>>0x3)-1)&0xF) << 0xC) /* Multichannel Window Size = (x/8)-1 */ | ||
1298 | |||
1299 | /* SPORTx_MCMC2 Masks */ | ||
1300 | #define REC_BYPASS 0x0000 /* Bypass Mode (No Clock Recovery) */ | ||
1301 | #define REC_2FROM4 0x0002 /* Recover 2 MHz Clock from 4 MHz Clock */ | ||
1302 | #define REC_8FROM16 0x0003 /* Recover 8 MHz Clock from 16 MHz Clock */ | ||
1303 | #define MCDTXPE 0x0004 /* Multichannel DMA Transmit Packing */ | ||
1304 | #define MCDRXPE 0x0008 /* Multichannel DMA Receive Packing */ | ||
1305 | #define MCMEN 0x0010 /* Multichannel Frame Mode Enable */ | ||
1306 | #define FSDR 0x0080 /* Multichannel Frame Sync to Data Relationship */ | ||
1307 | #define MFD_0 0x0000 /* Multichannel Frame Delay = 0 */ | ||
1308 | #define MFD_1 0x1000 /* Multichannel Frame Delay = 1 */ | ||
1309 | #define MFD_2 0x2000 /* Multichannel Frame Delay = 2 */ | ||
1310 | #define MFD_3 0x3000 /* Multichannel Frame Delay = 3 */ | ||
1311 | #define MFD_4 0x4000 /* Multichannel Frame Delay = 4 */ | ||
1312 | #define MFD_5 0x5000 /* Multichannel Frame Delay = 5 */ | ||
1313 | #define MFD_6 0x6000 /* Multichannel Frame Delay = 6 */ | ||
1314 | #define MFD_7 0x7000 /* Multichannel Frame Delay = 7 */ | ||
1315 | #define MFD_8 0x8000 /* Multichannel Frame Delay = 8 */ | ||
1316 | #define MFD_9 0x9000 /* Multichannel Frame Delay = 9 */ | ||
1317 | #define MFD_10 0xA000 /* Multichannel Frame Delay = 10 */ | ||
1318 | #define MFD_11 0xB000 /* Multichannel Frame Delay = 11 */ | ||
1319 | #define MFD_12 0xC000 /* Multichannel Frame Delay = 12 */ | ||
1320 | #define MFD_13 0xD000 /* Multichannel Frame Delay = 13 */ | ||
1321 | #define MFD_14 0xE000 /* Multichannel Frame Delay = 14 */ | ||
1322 | #define MFD_15 0xF000 /* Multichannel Frame Delay = 15 */ | ||
1323 | |||
1324 | /* ********************* ASYNCHRONOUS MEMORY CONTROLLER MASKS *************************/ | 1244 | /* ********************* ASYNCHRONOUS MEMORY CONTROLLER MASKS *************************/ |
1325 | /* EBIU_AMGCTL Masks */ | 1245 | /* EBIU_AMGCTL Masks */ |
1326 | #define AMCKEN 0x0001 /* Enable CLKOUT */ | 1246 | #define AMCKEN 0x0001 /* Enable CLKOUT */ |
diff --git a/arch/blackfin/mach-bf538/include/mach/defBF539.h b/arch/blackfin/mach-bf538/include/mach/defBF539.h index b674a1c4aef..fe43062b497 100644 --- a/arch/blackfin/mach-bf538/include/mach/defBF539.h +++ b/arch/blackfin/mach-bf538/include/mach/defBF539.h | |||
@@ -1610,113 +1610,6 @@ | |||
1610 | #define UCEN_P 0x00 | 1610 | #define UCEN_P 0x00 |
1611 | 1611 | ||
1612 | 1612 | ||
1613 | /* ********** SERIAL PORT MASKS ********************** */ | ||
1614 | /* SPORTx_TCR1 Masks */ | ||
1615 | #define TSPEN 0x0001 /* TX enable */ | ||
1616 | #define ITCLK 0x0002 /* Internal TX Clock Select */ | ||
1617 | #define TDTYPE 0x000C /* TX Data Formatting Select */ | ||
1618 | #define DTYPE_NORM 0x0000 /* Data Format Normal */ | ||
1619 | #define DTYPE_ULAW 0x0008 /* Compand Using u-Law */ | ||
1620 | #define DTYPE_ALAW 0x000C /* Compand Using A-Law */ | ||
1621 | #define TLSBIT 0x0010 /* TX Bit Order */ | ||
1622 | #define ITFS 0x0200 /* Internal TX Frame Sync Select */ | ||
1623 | #define TFSR 0x0400 /* TX Frame Sync Required Select */ | ||
1624 | #define DITFS 0x0800 /* Data Independent TX Frame Sync Select */ | ||
1625 | #define LTFS 0x1000 /* Low TX Frame Sync Select */ | ||
1626 | #define LATFS 0x2000 /* Late TX Frame Sync Select */ | ||
1627 | #define TCKFE 0x4000 /* TX Clock Falling Edge Select */ | ||
1628 | /* SPORTx_RCR1 Deprecated Masks */ | ||
1629 | #define TULAW DTYPE_ULAW /* Compand Using u-Law */ | ||
1630 | #define TALAW DTYPE_ALAW /* Compand Using A-Law */ | ||
1631 | |||
1632 | /* SPORTx_TCR2 Masks */ | ||
1633 | #ifdef _MISRA_RULES | ||
1634 | #define SLEN(x) ((x)&0x1Fu) /* SPORT TX Word Length (2 - 31) */ | ||
1635 | #else | ||
1636 | #define SLEN(x) ((x)&0x1F) /* SPORT TX Word Length (2 - 31) */ | ||
1637 | #endif /* _MISRA_RULES */ | ||
1638 | #define TXSE 0x0100 /*TX Secondary Enable */ | ||
1639 | #define TSFSE 0x0200 /*TX Stereo Frame Sync Enable */ | ||
1640 | #define TRFST 0x0400 /*TX Right-First Data Order */ | ||
1641 | |||
1642 | /* SPORTx_RCR1 Masks */ | ||
1643 | #define RSPEN 0x0001 /* RX enable */ | ||
1644 | #define IRCLK 0x0002 /* Internal RX Clock Select */ | ||
1645 | #define RDTYPE 0x000C /* RX Data Formatting Select */ | ||
1646 | #define DTYPE_NORM 0x0000 /* no companding */ | ||
1647 | #define DTYPE_ULAW 0x0008 /* Compand Using u-Law */ | ||
1648 | #define DTYPE_ALAW 0x000C /* Compand Using A-Law */ | ||
1649 | #define RLSBIT 0x0010 /* RX Bit Order */ | ||
1650 | #define IRFS 0x0200 /* Internal RX Frame Sync Select */ | ||
1651 | #define RFSR 0x0400 /* RX Frame Sync Required Select */ | ||
1652 | #define LRFS 0x1000 /* Low RX Frame Sync Select */ | ||
1653 | #define LARFS 0x2000 /* Late RX Frame Sync Select */ | ||
1654 | #define RCKFE 0x4000 /* RX Clock Falling Edge Select */ | ||
1655 | /* SPORTx_RCR1 Deprecated Masks */ | ||
1656 | #define RULAW DTYPE_ULAW /* Compand Using u-Law */ | ||
1657 | #define RALAW DTYPE_ALAW /* Compand Using A-Law */ | ||
1658 | |||
1659 | /* SPORTx_RCR2 Masks */ | ||
1660 | #ifdef _MISRA_RULES | ||
1661 | #define SLEN(x) ((x)&0x1Fu) /* SPORT RX Word Length (2 - 31) */ | ||
1662 | #else | ||
1663 | #define SLEN(x) ((x)&0x1F) /* SPORT RX Word Length (2 - 31) */ | ||
1664 | #endif /* _MISRA_RULES */ | ||
1665 | #define RXSE 0x0100 /*RX Secondary Enable */ | ||
1666 | #define RSFSE 0x0200 /*RX Stereo Frame Sync Enable */ | ||
1667 | #define RRFST 0x0400 /*Right-First Data Order */ | ||
1668 | |||
1669 | /*SPORTx_STAT Masks */ | ||
1670 | #define RXNE 0x0001 /*RX FIFO Not Empty Status */ | ||
1671 | #define RUVF 0x0002 /*RX Underflow Status */ | ||
1672 | #define ROVF 0x0004 /*RX Overflow Status */ | ||
1673 | #define TXF 0x0008 /*TX FIFO Full Status */ | ||
1674 | #define TUVF 0x0010 /*TX Underflow Status */ | ||
1675 | #define TOVF 0x0020 /*TX Overflow Status */ | ||
1676 | #define TXHRE 0x0040 /*TX Hold Register Empty */ | ||
1677 | |||
1678 | /*SPORTx_MCMC1 Masks */ | ||
1679 | #define WOFF 0x000003FF /*Multichannel Window Offset Field */ | ||
1680 | /* SPORTx_MCMC1 Macros */ | ||
1681 | #ifdef _MISRA_RULES | ||
1682 | #define SET_WOFF(x) ((x) & 0x3FFu) /* Multichannel Window Offset Field */ | ||
1683 | /* Only use SET_WSIZE Macro With Logic OR While Setting Lower Order Bits */ | ||
1684 | #define SET_WSIZE(x) (((((x)>>0x3)-1u)&0xFu) << 0xC) /* Multichannel Window Size = (x/8)-1 */ | ||
1685 | #else | ||
1686 | #define SET_WOFF(x) ((x) & 0x3FF) /* Multichannel Window Offset Field */ | ||
1687 | /* Only use SET_WSIZE Macro With Logic OR While Setting Lower Order Bits */ | ||
1688 | #define SET_WSIZE(x) (((((x)>>0x3)-1)&0xF) << 0xC) /* Multichannel Window Size = (x/8)-1 */ | ||
1689 | #endif /* _MISRA_RULES */ | ||
1690 | |||
1691 | |||
1692 | /*SPORTx_MCMC2 Masks */ | ||
1693 | #define MCCRM 0x0003 /*Multichannel Clock Recovery Mode */ | ||
1694 | #define REC_BYPASS 0x0000 /* Bypass Mode (No Clock Recovery) */ | ||
1695 | #define REC_2FROM4 0x0002 /* Recover 2 MHz Clock from 4 MHz Clock */ | ||
1696 | #define REC_8FROM16 0x0003 /* Recover 8 MHz Clock from 16 MHz Clock */ | ||
1697 | #define MCDTXPE 0x0004 /*Multichannel DMA Transmit Packing */ | ||
1698 | #define MCDRXPE 0x0008 /*Multichannel DMA Receive Packing */ | ||
1699 | #define MCMEN 0x0010 /*Multichannel Frame Mode Enable */ | ||
1700 | #define FSDR 0x0080 /*Multichannel Frame Sync to Data Relationship */ | ||
1701 | #define MFD 0xF000 /*Multichannel Frame Delay */ | ||
1702 | #define MFD_0 0x0000 /* Multichannel Frame Delay = 0 */ | ||
1703 | #define MFD_1 0x1000 /* Multichannel Frame Delay = 1 */ | ||
1704 | #define MFD_2 0x2000 /* Multichannel Frame Delay = 2 */ | ||
1705 | #define MFD_3 0x3000 /* Multichannel Frame Delay = 3 */ | ||
1706 | #define MFD_4 0x4000 /* Multichannel Frame Delay = 4 */ | ||
1707 | #define MFD_5 0x5000 /* Multichannel Frame Delay = 5 */ | ||
1708 | #define MFD_6 0x6000 /* Multichannel Frame Delay = 6 */ | ||
1709 | #define MFD_7 0x7000 /* Multichannel Frame Delay = 7 */ | ||
1710 | #define MFD_8 0x8000 /* Multichannel Frame Delay = 8 */ | ||
1711 | #define MFD_9 0x9000 /* Multichannel Frame Delay = 9 */ | ||
1712 | #define MFD_10 0xA000 /* Multichannel Frame Delay = 10 */ | ||
1713 | #define MFD_11 0xB000 /* Multichannel Frame Delay = 11 */ | ||
1714 | #define MFD_12 0xC000 /* Multichannel Frame Delay = 12 */ | ||
1715 | #define MFD_13 0xD000 /* Multichannel Frame Delay = 13 */ | ||
1716 | #define MFD_14 0xE000 /* Multichannel Frame Delay = 14 */ | ||
1717 | #define MFD_15 0xF000 /* Multichannel Frame Delay = 15 */ | ||
1718 | |||
1719 | |||
1720 | /* ********* PARALLEL PERIPHERAL INTERFACE (PPI) MASKS **************** */ | 1613 | /* ********* PARALLEL PERIPHERAL INTERFACE (PPI) MASKS **************** */ |
1721 | /* PPI_CONTROL Masks */ | 1614 | /* PPI_CONTROL Masks */ |
1722 | #define PORT_EN 0x0001 /* PPI Port Enable */ | 1615 | #define PORT_EN 0x0001 /* PPI Port Enable */ |
diff --git a/arch/blackfin/mach-bf548/boards/cm_bf548.c b/arch/blackfin/mach-bf548/boards/cm_bf548.c index dbb6b1d83f6..0c38eec9ade 100644 --- a/arch/blackfin/mach-bf548/boards/cm_bf548.c +++ b/arch/blackfin/mach-bf548/boards/cm_bf548.c | |||
@@ -706,7 +706,6 @@ static struct mtd_partition partition_info[] = { | |||
706 | }; | 706 | }; |
707 | 707 | ||
708 | static struct bf5xx_nand_platform bf5xx_nand_platform = { | 708 | static struct bf5xx_nand_platform bf5xx_nand_platform = { |
709 | .page_size = NFC_PG_SIZE_256, | ||
710 | .data_width = NFC_NWIDTH_8, | 709 | .data_width = NFC_NWIDTH_8, |
711 | .partitions = partition_info, | 710 | .partitions = partition_info, |
712 | .nr_partitions = ARRAY_SIZE(partition_info), | 711 | .nr_partitions = ARRAY_SIZE(partition_info), |
diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c index 6fcfb9187c3..56682a36e42 100644 --- a/arch/blackfin/mach-bf548/boards/ezkit.c +++ b/arch/blackfin/mach-bf548/boards/ezkit.c | |||
@@ -849,7 +849,6 @@ static struct mtd_partition partition_info[] = { | |||
849 | }; | 849 | }; |
850 | 850 | ||
851 | static struct bf5xx_nand_platform bf5xx_nand_platform = { | 851 | static struct bf5xx_nand_platform bf5xx_nand_platform = { |
852 | .page_size = NFC_PG_SIZE_256, | ||
853 | .data_width = NFC_NWIDTH_8, | 852 | .data_width = NFC_NWIDTH_8, |
854 | .partitions = partition_info, | 853 | .partitions = partition_info, |
855 | .nr_partitions = ARRAY_SIZE(partition_info), | 854 | .nr_partitions = ARRAY_SIZE(partition_info), |
diff --git a/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h b/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h index 95ff44601fd..7866197f548 100644 --- a/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h +++ b/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h | |||
@@ -2221,73 +2221,6 @@ | |||
2221 | 2221 | ||
2222 | #define RCVDATA16 0xffff /* Receive FIFO 16-Bit Data */ | 2222 | #define RCVDATA16 0xffff /* Receive FIFO 16-Bit Data */ |
2223 | 2223 | ||
2224 | /* Bit masks for SPORTx_TCR1 */ | ||
2225 | |||
2226 | #define TCKFE 0x4000 /* Clock Falling Edge Select */ | ||
2227 | #define LATFS 0x2000 /* Late Transmit Frame Sync */ | ||
2228 | #define LTFS 0x1000 /* Low Transmit Frame Sync Select */ | ||
2229 | #define DITFS 0x800 /* Data-Independent Transmit Frame Sync Select */ | ||
2230 | #define TFSR 0x400 /* Transmit Frame Sync Required Select */ | ||
2231 | #define ITFS 0x200 /* Internal Transmit Frame Sync Select */ | ||
2232 | #define TLSBIT 0x10 /* Transmit Bit Order */ | ||
2233 | #define TDTYPE 0xc /* Data Formatting Type Select */ | ||
2234 | #define ITCLK 0x2 /* Internal Transmit Clock Select */ | ||
2235 | #define TSPEN 0x1 /* Transmit Enable */ | ||
2236 | |||
2237 | /* Bit masks for SPORTx_TCR2 */ | ||
2238 | |||
2239 | #define TRFST 0x400 /* Left/Right Order */ | ||
2240 | #define TSFSE 0x200 /* Transmit Stereo Frame Sync Enable */ | ||
2241 | #define TXSE 0x100 /* TxSEC Enable */ | ||
2242 | #define SLEN_T 0x1f /* SPORT Word Length */ | ||
2243 | |||
2244 | /* Bit masks for SPORTx_RCR1 */ | ||
2245 | |||
2246 | #define RCKFE 0x4000 /* Clock Falling Edge Select */ | ||
2247 | #define LARFS 0x2000 /* Late Receive Frame Sync */ | ||
2248 | #define LRFS 0x1000 /* Low Receive Frame Sync Select */ | ||
2249 | #define RFSR 0x400 /* Receive Frame Sync Required Select */ | ||
2250 | #define IRFS 0x200 /* Internal Receive Frame Sync Select */ | ||
2251 | #define RLSBIT 0x10 /* Receive Bit Order */ | ||
2252 | #define RDTYPE 0xc /* Data Formatting Type Select */ | ||
2253 | #define IRCLK 0x2 /* Internal Receive Clock Select */ | ||
2254 | #define RSPEN 0x1 /* Receive Enable */ | ||
2255 | |||
2256 | /* Bit masks for SPORTx_RCR2 */ | ||
2257 | |||
2258 | #define RRFST 0x400 /* Left/Right Order */ | ||
2259 | #define RSFSE 0x200 /* Receive Stereo Frame Sync Enable */ | ||
2260 | #define RXSE 0x100 /* RxSEC Enable */ | ||
2261 | #define SLEN_R 0x1f /* SPORT Word Length */ | ||
2262 | |||
2263 | /* Bit masks for SPORTx_STAT */ | ||
2264 | |||
2265 | #define TXHRE 0x40 /* Transmit Hold Register Empty */ | ||
2266 | #define TOVF 0x20 /* Sticky Transmit Overflow Status */ | ||
2267 | #define TUVF 0x10 /* Sticky Transmit Underflow Status */ | ||
2268 | #define TXF 0x8 /* Transmit FIFO Full Status */ | ||
2269 | #define ROVF 0x4 /* Sticky Receive Overflow Status */ | ||
2270 | #define RUVF 0x2 /* Sticky Receive Underflow Status */ | ||
2271 | #define RXNE 0x1 /* Receive FIFO Not Empty Status */ | ||
2272 | |||
2273 | /* Bit masks for SPORTx_MCMC1 */ | ||
2274 | |||
2275 | #define SP_WSIZE 0xf000 /* Window Size */ | ||
2276 | #define SP_WOFF 0x3ff /* Windows Offset */ | ||
2277 | |||
2278 | /* Bit masks for SPORTx_MCMC2 */ | ||
2279 | |||
2280 | #define MFD 0xf000 /* Multi channel Frame Delay */ | ||
2281 | #define FSDR 0x80 /* Frame Sync to Data Relationship */ | ||
2282 | #define MCMEN 0x10 /* Multi channel Frame Mode Enable */ | ||
2283 | #define MCDRXPE 0x8 /* Multi channel DMA Receive Packing */ | ||
2284 | #define MCDTXPE 0x4 /* Multi channel DMA Transmit Packing */ | ||
2285 | #define MCCRM 0x3 /* 2X Clock Recovery Mode */ | ||
2286 | |||
2287 | /* Bit masks for SPORTx_CHNL */ | ||
2288 | |||
2289 | #define CUR_CHNL 0x3ff /* Current Channel Indicator */ | ||
2290 | |||
2291 | /* Bit masks for UARTx_LCR */ | 2224 | /* Bit masks for UARTx_LCR */ |
2292 | 2225 | ||
2293 | #if 0 | 2226 | #if 0 |
diff --git a/arch/blackfin/mach-bf561/include/mach/defBF561.h b/arch/blackfin/mach-bf561/include/mach/defBF561.h index 4c8e36b7fb3..2674f009757 100644 --- a/arch/blackfin/mach-bf561/include/mach/defBF561.h +++ b/arch/blackfin/mach-bf561/include/mach/defBF561.h | |||
@@ -1007,66 +1007,6 @@ | |||
1007 | #define IREN_P 0x01 | 1007 | #define IREN_P 0x01 |
1008 | #define UCEN_P 0x00 | 1008 | #define UCEN_P 0x00 |
1009 | 1009 | ||
1010 | /* ********** SERIAL PORT MASKS ********************** */ | ||
1011 | |||
1012 | /* SPORTx_TCR1 Masks */ | ||
1013 | #define TSPEN 0x0001 /* TX enable */ | ||
1014 | #define ITCLK 0x0002 /* Internal TX Clock Select */ | ||
1015 | #define TDTYPE 0x000C /* TX Data Formatting Select */ | ||
1016 | #define TLSBIT 0x0010 /* TX Bit Order */ | ||
1017 | #define ITFS 0x0200 /* Internal TX Frame Sync Select */ | ||
1018 | #define TFSR 0x0400 /* TX Frame Sync Required Select */ | ||
1019 | #define DITFS 0x0800 /* Data Independent TX Frame Sync Select */ | ||
1020 | #define LTFS 0x1000 /* Low TX Frame Sync Select */ | ||
1021 | #define LATFS 0x2000 /* Late TX Frame Sync Select */ | ||
1022 | #define TCKFE 0x4000 /* TX Clock Falling Edge Select */ | ||
1023 | |||
1024 | /* SPORTx_TCR2 Masks */ | ||
1025 | #define SLEN 0x001F /*TX Word Length */ | ||
1026 | #define TXSE 0x0100 /*TX Secondary Enable */ | ||
1027 | #define TSFSE 0x0200 /*TX Stereo Frame Sync Enable */ | ||
1028 | #define TRFST 0x0400 /*TX Right-First Data Order */ | ||
1029 | |||
1030 | /* SPORTx_RCR1 Masks */ | ||
1031 | #define RSPEN 0x0001 /* RX enable */ | ||
1032 | #define IRCLK 0x0002 /* Internal RX Clock Select */ | ||
1033 | #define RDTYPE 0x000C /* RX Data Formatting Select */ | ||
1034 | #define RULAW 0x0008 /* u-Law enable */ | ||
1035 | #define RALAW 0x000C /* A-Law enable */ | ||
1036 | #define RLSBIT 0x0010 /* RX Bit Order */ | ||
1037 | #define IRFS 0x0200 /* Internal RX Frame Sync Select */ | ||
1038 | #define RFSR 0x0400 /* RX Frame Sync Required Select */ | ||
1039 | #define LRFS 0x1000 /* Low RX Frame Sync Select */ | ||
1040 | #define LARFS 0x2000 /* Late RX Frame Sync Select */ | ||
1041 | #define RCKFE 0x4000 /* RX Clock Falling Edge Select */ | ||
1042 | |||
1043 | /* SPORTx_RCR2 Masks */ | ||
1044 | #define SLEN 0x001F /*RX Word Length */ | ||
1045 | #define RXSE 0x0100 /*RX Secondary Enable */ | ||
1046 | #define RSFSE 0x0200 /*RX Stereo Frame Sync Enable */ | ||
1047 | #define RRFST 0x0400 /*Right-First Data Order */ | ||
1048 | |||
1049 | /*SPORTx_STAT Masks */ | ||
1050 | #define RXNE 0x0001 /*RX FIFO Not Empty Status */ | ||
1051 | #define RUVF 0x0002 /*RX Underflow Status */ | ||
1052 | #define ROVF 0x0004 /*RX Overflow Status */ | ||
1053 | #define TXF 0x0008 /*TX FIFO Full Status */ | ||
1054 | #define TUVF 0x0010 /*TX Underflow Status */ | ||
1055 | #define TOVF 0x0020 /*TX Overflow Status */ | ||
1056 | #define TXHRE 0x0040 /*TX Hold Register Empty */ | ||
1057 | |||
1058 | /*SPORTx_MCMC1 Masks */ | ||
1059 | #define SP_WSIZE 0x0000F000 /*Multichannel Window Size Field */ | ||
1060 | #define SP_WOFF 0x000003FF /*Multichannel Window Offset Field */ | ||
1061 | |||
1062 | /*SPORTx_MCMC2 Masks */ | ||
1063 | #define MCCRM 0x00000003 /*Multichannel Clock Recovery Mode */ | ||
1064 | #define MCDTXPE 0x00000004 /*Multichannel DMA Transmit Packing */ | ||
1065 | #define MCDRXPE 0x00000008 /*Multichannel DMA Receive Packing */ | ||
1066 | #define MCMEN 0x00000010 /*Multichannel Frame Mode Enable */ | ||
1067 | #define FSDR 0x00000080 /*Multichannel Frame Sync to Data Relationship */ | ||
1068 | #define MFD 0x0000F000 /*Multichannel Frame Delay */ | ||
1069 | |||
1070 | /* ********* PARALLEL PERIPHERAL INTERFACE (PPI) MASKS **************** */ | 1010 | /* ********* PARALLEL PERIPHERAL INTERFACE (PPI) MASKS **************** */ |
1071 | 1011 | ||
1072 | /* PPI_CONTROL Masks */ | 1012 | /* PPI_CONTROL Masks */ |
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index a5847f5d67c..af1bffa21dc 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S | |||
@@ -1628,6 +1628,9 @@ ENTRY(_sys_call_table) | |||
1628 | .long _sys_rt_tgsigqueueinfo | 1628 | .long _sys_rt_tgsigqueueinfo |
1629 | .long _sys_perf_event_open | 1629 | .long _sys_perf_event_open |
1630 | .long _sys_recvmmsg /* 370 */ | 1630 | .long _sys_recvmmsg /* 370 */ |
1631 | .long _sys_fanotify_init | ||
1632 | .long _sys_fanotify_mark | ||
1633 | .long _sys_prlimit64 | ||
1631 | 1634 | ||
1632 | .rept NR_syscalls-(.-_sys_call_table)/4 | 1635 | .rept NR_syscalls-(.-_sys_call_table)/4 |
1633 | .long _sys_ni_syscall | 1636 | .long _sys_ni_syscall |
diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c index 0974c0ecc59..bab01298b58 100644 --- a/arch/frv/kernel/signal.c +++ b/arch/frv/kernel/signal.c | |||
@@ -121,6 +121,9 @@ static int restore_sigcontext(struct sigcontext __user *sc, int *_gr8) | |||
121 | struct user_context *user = current->thread.user; | 121 | struct user_context *user = current->thread.user; |
122 | unsigned long tbr, psr; | 122 | unsigned long tbr, psr; |
123 | 123 | ||
124 | /* Always make any pending restarted system calls return -EINTR */ | ||
125 | current_thread_info()->restart_block.fn = do_no_restart_syscall; | ||
126 | |||
124 | tbr = user->i.tbr; | 127 | tbr = user->i.tbr; |
125 | psr = user->i.psr; | 128 | psr = user->i.psr; |
126 | if (copy_from_user(user, &sc->sc_context, sizeof(sc->sc_context))) | 129 | if (copy_from_user(user, &sc->sc_context, sizeof(sc->sc_context))) |
@@ -250,6 +253,8 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set) | |||
250 | struct sigframe __user *frame; | 253 | struct sigframe __user *frame; |
251 | int rsig; | 254 | int rsig; |
252 | 255 | ||
256 | set_fs(USER_DS); | ||
257 | |||
253 | frame = get_sigframe(ka, sizeof(*frame)); | 258 | frame = get_sigframe(ka, sizeof(*frame)); |
254 | 259 | ||
255 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) | 260 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) |
@@ -293,22 +298,23 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set) | |||
293 | (unsigned long) (frame->retcode + 2)); | 298 | (unsigned long) (frame->retcode + 2)); |
294 | } | 299 | } |
295 | 300 | ||
296 | /* set up registers for signal handler */ | 301 | /* Set up registers for the signal handler */ |
297 | __frame->sp = (unsigned long) frame; | ||
298 | __frame->lr = (unsigned long) &frame->retcode; | ||
299 | __frame->gr8 = sig; | ||
300 | |||
301 | if (current->personality & FDPIC_FUNCPTRS) { | 302 | if (current->personality & FDPIC_FUNCPTRS) { |
302 | struct fdpic_func_descriptor __user *funcptr = | 303 | struct fdpic_func_descriptor __user *funcptr = |
303 | (struct fdpic_func_descriptor __user *) ka->sa.sa_handler; | 304 | (struct fdpic_func_descriptor __user *) ka->sa.sa_handler; |
304 | __get_user(__frame->pc, &funcptr->text); | 305 | struct fdpic_func_descriptor desc; |
305 | __get_user(__frame->gr15, &funcptr->GOT); | 306 | if (copy_from_user(&desc, funcptr, sizeof(desc))) |
307 | goto give_sigsegv; | ||
308 | __frame->pc = desc.text; | ||
309 | __frame->gr15 = desc.GOT; | ||
306 | } else { | 310 | } else { |
307 | __frame->pc = (unsigned long) ka->sa.sa_handler; | 311 | __frame->pc = (unsigned long) ka->sa.sa_handler; |
308 | __frame->gr15 = 0; | 312 | __frame->gr15 = 0; |
309 | } | 313 | } |
310 | 314 | ||
311 | set_fs(USER_DS); | 315 | __frame->sp = (unsigned long) frame; |
316 | __frame->lr = (unsigned long) &frame->retcode; | ||
317 | __frame->gr8 = sig; | ||
312 | 318 | ||
313 | /* the tracer may want to single-step inside the handler */ | 319 | /* the tracer may want to single-step inside the handler */ |
314 | if (test_thread_flag(TIF_SINGLESTEP)) | 320 | if (test_thread_flag(TIF_SINGLESTEP)) |
@@ -323,7 +329,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set) | |||
323 | return 0; | 329 | return 0; |
324 | 330 | ||
325 | give_sigsegv: | 331 | give_sigsegv: |
326 | force_sig(SIGSEGV, current); | 332 | force_sigsegv(sig, current); |
327 | return -EFAULT; | 333 | return -EFAULT; |
328 | 334 | ||
329 | } /* end setup_frame() */ | 335 | } /* end setup_frame() */ |
@@ -338,6 +344,8 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
338 | struct rt_sigframe __user *frame; | 344 | struct rt_sigframe __user *frame; |
339 | int rsig; | 345 | int rsig; |
340 | 346 | ||
347 | set_fs(USER_DS); | ||
348 | |||
341 | frame = get_sigframe(ka, sizeof(*frame)); | 349 | frame = get_sigframe(ka, sizeof(*frame)); |
342 | 350 | ||
343 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) | 351 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) |
@@ -392,22 +400,23 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
392 | } | 400 | } |
393 | 401 | ||
394 | /* Set up registers for signal handler */ | 402 | /* Set up registers for signal handler */ |
395 | __frame->sp = (unsigned long) frame; | ||
396 | __frame->lr = (unsigned long) &frame->retcode; | ||
397 | __frame->gr8 = sig; | ||
398 | __frame->gr9 = (unsigned long) &frame->info; | ||
399 | |||
400 | if (current->personality & FDPIC_FUNCPTRS) { | 403 | if (current->personality & FDPIC_FUNCPTRS) { |
401 | struct fdpic_func_descriptor __user *funcptr = | 404 | struct fdpic_func_descriptor __user *funcptr = |
402 | (struct fdpic_func_descriptor __user *) ka->sa.sa_handler; | 405 | (struct fdpic_func_descriptor __user *) ka->sa.sa_handler; |
403 | __get_user(__frame->pc, &funcptr->text); | 406 | struct fdpic_func_descriptor desc; |
404 | __get_user(__frame->gr15, &funcptr->GOT); | 407 | if (copy_from_user(&desc, funcptr, sizeof(desc))) |
408 | goto give_sigsegv; | ||
409 | __frame->pc = desc.text; | ||
410 | __frame->gr15 = desc.GOT; | ||
405 | } else { | 411 | } else { |
406 | __frame->pc = (unsigned long) ka->sa.sa_handler; | 412 | __frame->pc = (unsigned long) ka->sa.sa_handler; |
407 | __frame->gr15 = 0; | 413 | __frame->gr15 = 0; |
408 | } | 414 | } |
409 | 415 | ||
410 | set_fs(USER_DS); | 416 | __frame->sp = (unsigned long) frame; |
417 | __frame->lr = (unsigned long) &frame->retcode; | ||
418 | __frame->gr8 = sig; | ||
419 | __frame->gr9 = (unsigned long) &frame->info; | ||
411 | 420 | ||
412 | /* the tracer may want to single-step inside the handler */ | 421 | /* the tracer may want to single-step inside the handler */ |
413 | if (test_thread_flag(TIF_SINGLESTEP)) | 422 | if (test_thread_flag(TIF_SINGLESTEP)) |
@@ -422,7 +431,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
422 | return 0; | 431 | return 0; |
423 | 432 | ||
424 | give_sigsegv: | 433 | give_sigsegv: |
425 | force_sig(SIGSEGV, current); | 434 | force_sigsegv(sig, current); |
426 | return -EFAULT; | 435 | return -EFAULT; |
427 | 436 | ||
428 | } /* end setup_rt_frame() */ | 437 | } /* end setup_rt_frame() */ |
@@ -437,7 +446,7 @@ static int handle_signal(unsigned long sig, siginfo_t *info, | |||
437 | int ret; | 446 | int ret; |
438 | 447 | ||
439 | /* Are we from a system call? */ | 448 | /* Are we from a system call? */ |
440 | if (in_syscall(__frame)) { | 449 | if (__frame->syscallno != -1) { |
441 | /* If so, check system call restarting.. */ | 450 | /* If so, check system call restarting.. */ |
442 | switch (__frame->gr8) { | 451 | switch (__frame->gr8) { |
443 | case -ERESTART_RESTARTBLOCK: | 452 | case -ERESTART_RESTARTBLOCK: |
@@ -456,6 +465,7 @@ static int handle_signal(unsigned long sig, siginfo_t *info, | |||
456 | __frame->gr8 = __frame->orig_gr8; | 465 | __frame->gr8 = __frame->orig_gr8; |
457 | __frame->pc -= 4; | 466 | __frame->pc -= 4; |
458 | } | 467 | } |
468 | __frame->syscallno = -1; | ||
459 | } | 469 | } |
460 | 470 | ||
461 | /* Set up the stack frame */ | 471 | /* Set up the stack frame */ |
@@ -538,10 +548,11 @@ no_signal: | |||
538 | break; | 548 | break; |
539 | 549 | ||
540 | case -ERESTART_RESTARTBLOCK: | 550 | case -ERESTART_RESTARTBLOCK: |
541 | __frame->gr8 = __NR_restart_syscall; | 551 | __frame->gr7 = __NR_restart_syscall; |
542 | __frame->pc -= 4; | 552 | __frame->pc -= 4; |
543 | break; | 553 | break; |
544 | } | 554 | } |
555 | __frame->syscallno = -1; | ||
545 | } | 556 | } |
546 | 557 | ||
547 | /* if there's no signal to deliver, we just put the saved sigmask | 558 | /* if there's no signal to deliver, we just put the saved sigmask |
diff --git a/arch/h8300/include/asm/atomic.h b/arch/h8300/include/asm/atomic.h index e936804b750..984221abb66 100644 --- a/arch/h8300/include/asm/atomic.h +++ b/arch/h8300/include/asm/atomic.h | |||
@@ -18,7 +18,8 @@ | |||
18 | 18 | ||
19 | static __inline__ int atomic_add_return(int i, atomic_t *v) | 19 | static __inline__ int atomic_add_return(int i, atomic_t *v) |
20 | { | 20 | { |
21 | int ret,flags; | 21 | unsigned long flags; |
22 | int ret; | ||
22 | local_irq_save(flags); | 23 | local_irq_save(flags); |
23 | ret = v->counter += i; | 24 | ret = v->counter += i; |
24 | local_irq_restore(flags); | 25 | local_irq_restore(flags); |
@@ -30,7 +31,8 @@ static __inline__ int atomic_add_return(int i, atomic_t *v) | |||
30 | 31 | ||
31 | static __inline__ int atomic_sub_return(int i, atomic_t *v) | 32 | static __inline__ int atomic_sub_return(int i, atomic_t *v) |
32 | { | 33 | { |
33 | int ret,flags; | 34 | unsigned long flags; |
35 | int ret; | ||
34 | local_irq_save(flags); | 36 | local_irq_save(flags); |
35 | ret = v->counter -= i; | 37 | ret = v->counter -= i; |
36 | local_irq_restore(flags); | 38 | local_irq_restore(flags); |
@@ -42,7 +44,8 @@ static __inline__ int atomic_sub_return(int i, atomic_t *v) | |||
42 | 44 | ||
43 | static __inline__ int atomic_inc_return(atomic_t *v) | 45 | static __inline__ int atomic_inc_return(atomic_t *v) |
44 | { | 46 | { |
45 | int ret,flags; | 47 | unsigned long flags; |
48 | int ret; | ||
46 | local_irq_save(flags); | 49 | local_irq_save(flags); |
47 | v->counter++; | 50 | v->counter++; |
48 | ret = v->counter; | 51 | ret = v->counter; |
@@ -64,7 +67,8 @@ static __inline__ int atomic_inc_return(atomic_t *v) | |||
64 | 67 | ||
65 | static __inline__ int atomic_dec_return(atomic_t *v) | 68 | static __inline__ int atomic_dec_return(atomic_t *v) |
66 | { | 69 | { |
67 | int ret,flags; | 70 | unsigned long flags; |
71 | int ret; | ||
68 | local_irq_save(flags); | 72 | local_irq_save(flags); |
69 | --v->counter; | 73 | --v->counter; |
70 | ret = v->counter; | 74 | ret = v->counter; |
@@ -76,7 +80,8 @@ static __inline__ int atomic_dec_return(atomic_t *v) | |||
76 | 80 | ||
77 | static __inline__ int atomic_dec_and_test(atomic_t *v) | 81 | static __inline__ int atomic_dec_and_test(atomic_t *v) |
78 | { | 82 | { |
79 | int ret,flags; | 83 | unsigned long flags; |
84 | int ret; | ||
80 | local_irq_save(flags); | 85 | local_irq_save(flags); |
81 | --v->counter; | 86 | --v->counter; |
82 | ret = v->counter; | 87 | ret = v->counter; |
diff --git a/arch/h8300/include/asm/system.h b/arch/h8300/include/asm/system.h index d98d97685f0..16bf1560ff6 100644 --- a/arch/h8300/include/asm/system.h +++ b/arch/h8300/include/asm/system.h | |||
@@ -3,6 +3,8 @@ | |||
3 | 3 | ||
4 | #include <linux/linkage.h> | 4 | #include <linux/linkage.h> |
5 | 5 | ||
6 | struct pt_regs; | ||
7 | |||
6 | /* | 8 | /* |
7 | * switch_to(n) should switch tasks to task ptr, first checking that | 9 | * switch_to(n) should switch tasks to task ptr, first checking that |
8 | * ptr isn't the current task, in which case it does nothing. This | 10 | * ptr isn't the current task, in which case it does nothing. This |
@@ -155,6 +157,6 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz | |||
155 | 157 | ||
156 | #define arch_align_stack(x) (x) | 158 | #define arch_align_stack(x) (x) |
157 | 159 | ||
158 | void die(char *str, struct pt_regs *fp, unsigned long err); | 160 | extern void die(const char *str, struct pt_regs *fp, unsigned long err); |
159 | 161 | ||
160 | #endif /* _H8300_SYSTEM_H */ | 162 | #endif /* _H8300_SYSTEM_H */ |
diff --git a/arch/h8300/kernel/module.c b/arch/h8300/kernel/module.c index 0865e291c20..db4953dc4e1 100644 --- a/arch/h8300/kernel/module.c +++ b/arch/h8300/kernel/module.c | |||
@@ -112,10 +112,9 @@ int module_finalize(const Elf_Ehdr *hdr, | |||
112 | const Elf_Shdr *sechdrs, | 112 | const Elf_Shdr *sechdrs, |
113 | struct module *me) | 113 | struct module *me) |
114 | { | 114 | { |
115 | return module_bug_finalize(hdr, sechdrs, me); | 115 | return 0; |
116 | } | 116 | } |
117 | 117 | ||
118 | void module_arch_cleanup(struct module *mod) | 118 | void module_arch_cleanup(struct module *mod) |
119 | { | 119 | { |
120 | module_bug_cleanup(mod); | ||
121 | } | 120 | } |
diff --git a/arch/h8300/kernel/sys_h8300.c b/arch/h8300/kernel/sys_h8300.c index dc1ac0243b7..aaf5e5a48f9 100644 --- a/arch/h8300/kernel/sys_h8300.c +++ b/arch/h8300/kernel/sys_h8300.c | |||
@@ -56,8 +56,8 @@ int kernel_execve(const char *filename, | |||
56 | const char *const envp[]) | 56 | const char *const envp[]) |
57 | { | 57 | { |
58 | register long res __asm__("er0"); | 58 | register long res __asm__("er0"); |
59 | register char *const *_c __asm__("er3") = envp; | 59 | register const char *const *_c __asm__("er3") = envp; |
60 | register char *const *_b __asm__("er2") = argv; | 60 | register const char *const *_b __asm__("er2") = argv; |
61 | register const char * _a __asm__("er1") = filename; | 61 | register const char * _a __asm__("er1") = filename; |
62 | __asm__ __volatile__ ("mov.l %1,er0\n\t" | 62 | __asm__ __volatile__ ("mov.l %1,er0\n\t" |
63 | "trapa #0\n\t" | 63 | "trapa #0\n\t" |
diff --git a/arch/h8300/kernel/traps.c b/arch/h8300/kernel/traps.c index 3c0b66bc669..dfa05bd908b 100644 --- a/arch/h8300/kernel/traps.c +++ b/arch/h8300/kernel/traps.c | |||
@@ -96,7 +96,7 @@ static void dump(struct pt_regs *fp) | |||
96 | printk("\n\n"); | 96 | printk("\n\n"); |
97 | } | 97 | } |
98 | 98 | ||
99 | void die(char *str, struct pt_regs *fp, unsigned long err) | 99 | void die(const char *str, struct pt_regs *fp, unsigned long err) |
100 | { | 100 | { |
101 | static int diecount; | 101 | static int diecount; |
102 | 102 | ||
diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c index 2bef5261d96..1e8d71ad93e 100644 --- a/arch/ia64/hp/sim/simserial.c +++ b/arch/ia64/hp/sim/simserial.c | |||
@@ -149,7 +149,7 @@ static void receive_chars(struct tty_struct *tty) | |||
149 | ch = ia64_ssc(0, 0, 0, 0, | 149 | ch = ia64_ssc(0, 0, 0, 0, |
150 | SSC_GETCHAR); | 150 | SSC_GETCHAR); |
151 | while (!ch); | 151 | while (!ch); |
152 | handle_sysrq(ch, NULL); | 152 | handle_sysrq(ch); |
153 | } | 153 | } |
154 | #endif | 154 | #endif |
155 | seen_esc = 0; | 155 | seen_esc = 0; |
diff --git a/arch/ia64/include/asm/compat.h b/arch/ia64/include/asm/compat.h index f90edc85b50..9301a282161 100644 --- a/arch/ia64/include/asm/compat.h +++ b/arch/ia64/include/asm/compat.h | |||
@@ -199,7 +199,7 @@ ptr_to_compat(void __user *uptr) | |||
199 | } | 199 | } |
200 | 200 | ||
201 | static __inline__ void __user * | 201 | static __inline__ void __user * |
202 | compat_alloc_user_space (long len) | 202 | arch_compat_alloc_user_space (long len) |
203 | { | 203 | { |
204 | struct pt_regs *regs = task_pt_regs(current); | 204 | struct pt_regs *regs = task_pt_regs(current); |
205 | return (void __user *) (((regs->r12 & 0xffffffff) & -16) - len); | 205 | return (void __user *) (((regs->r12 & 0xffffffff) & -16) - len); |
diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S index 3567d54f8ce..331d42bda77 100644 --- a/arch/ia64/kernel/fsys.S +++ b/arch/ia64/kernel/fsys.S | |||
@@ -420,22 +420,31 @@ EX(.fail_efault, ld8 r14=[r33]) // r14 <- *set | |||
420 | ;; | 420 | ;; |
421 | 421 | ||
422 | RSM_PSR_I(p0, r18, r19) // mask interrupt delivery | 422 | RSM_PSR_I(p0, r18, r19) // mask interrupt delivery |
423 | mov ar.ccv=0 | ||
424 | andcm r14=r14,r17 // filter out SIGKILL & SIGSTOP | 423 | andcm r14=r14,r17 // filter out SIGKILL & SIGSTOP |
424 | mov r8=EINVAL // default to EINVAL | ||
425 | 425 | ||
426 | #ifdef CONFIG_SMP | 426 | #ifdef CONFIG_SMP |
427 | mov r17=1 | 427 | // __ticket_spin_trylock(r31) |
428 | ld4 r17=[r31] | ||
428 | ;; | 429 | ;; |
429 | cmpxchg4.acq r18=[r31],r17,ar.ccv // try to acquire the lock | 430 | mov.m ar.ccv=r17 |
430 | mov r8=EINVAL // default to EINVAL | 431 | extr.u r9=r17,17,15 |
432 | adds r19=1,r17 | ||
433 | extr.u r18=r17,0,15 | ||
434 | ;; | ||
435 | cmp.eq p6,p7=r9,r18 | ||
431 | ;; | 436 | ;; |
437 | (p6) cmpxchg4.acq r9=[r31],r19,ar.ccv | ||
438 | (p6) dep.z r20=r19,1,15 // next serving ticket for unlock | ||
439 | (p7) br.cond.spnt.many .lock_contention | ||
440 | ;; | ||
441 | cmp4.eq p0,p7=r9,r17 | ||
442 | adds r31=2,r31 | ||
443 | (p7) br.cond.spnt.many .lock_contention | ||
432 | ld8 r3=[r2] // re-read current->blocked now that we hold the lock | 444 | ld8 r3=[r2] // re-read current->blocked now that we hold the lock |
433 | cmp4.ne p6,p0=r18,r0 | ||
434 | (p6) br.cond.spnt.many .lock_contention | ||
435 | ;; | 445 | ;; |
436 | #else | 446 | #else |
437 | ld8 r3=[r2] // re-read current->blocked now that we hold the lock | 447 | ld8 r3=[r2] // re-read current->blocked now that we hold the lock |
438 | mov r8=EINVAL // default to EINVAL | ||
439 | #endif | 448 | #endif |
440 | add r18=IA64_TASK_PENDING_OFFSET+IA64_SIGPENDING_SIGNAL_OFFSET,r16 | 449 | add r18=IA64_TASK_PENDING_OFFSET+IA64_SIGPENDING_SIGNAL_OFFSET,r16 |
441 | add r19=IA64_TASK_SIGNAL_OFFSET,r16 | 450 | add r19=IA64_TASK_SIGNAL_OFFSET,r16 |
@@ -490,7 +499,9 @@ EX(.fail_efault, ld8 r14=[r33]) // r14 <- *set | |||
490 | (p6) br.cond.spnt.few 1b // yes -> retry | 499 | (p6) br.cond.spnt.few 1b // yes -> retry |
491 | 500 | ||
492 | #ifdef CONFIG_SMP | 501 | #ifdef CONFIG_SMP |
493 | st4.rel [r31]=r0 // release the lock | 502 | // __ticket_spin_unlock(r31) |
503 | st2.rel [r31]=r20 | ||
504 | mov r20=0 // i must not leak kernel bits... | ||
494 | #endif | 505 | #endif |
495 | SSM_PSR_I(p0, p9, r31) | 506 | SSM_PSR_I(p0, p9, r31) |
496 | ;; | 507 | ;; |
@@ -512,7 +523,8 @@ EX(.fail_efault, (p15) st8 [r34]=r3) | |||
512 | 523 | ||
513 | .sig_pending: | 524 | .sig_pending: |
514 | #ifdef CONFIG_SMP | 525 | #ifdef CONFIG_SMP |
515 | st4.rel [r31]=r0 // release the lock | 526 | // __ticket_spin_unlock(r31) |
527 | st2.rel [r31]=r20 // release the lock | ||
516 | #endif | 528 | #endif |
517 | SSM_PSR_I(p0, p9, r17) | 529 | SSM_PSR_I(p0, p9, r17) |
518 | ;; | 530 | ;; |
diff --git a/arch/m32r/include/asm/signal.h b/arch/m32r/include/asm/signal.h index 9c1acb2b1a9..b2eeb0de1c8 100644 --- a/arch/m32r/include/asm/signal.h +++ b/arch/m32r/include/asm/signal.h | |||
@@ -157,7 +157,6 @@ typedef struct sigaltstack { | |||
157 | #undef __HAVE_ARCH_SIG_BITOPS | 157 | #undef __HAVE_ARCH_SIG_BITOPS |
158 | 158 | ||
159 | struct pt_regs; | 159 | struct pt_regs; |
160 | extern int do_signal(struct pt_regs *regs, sigset_t *oldset); | ||
161 | 160 | ||
162 | #define ptrace_signal_deliver(regs, cookie) do { } while (0) | 161 | #define ptrace_signal_deliver(regs, cookie) do { } while (0) |
163 | 162 | ||
diff --git a/arch/m32r/include/asm/unistd.h b/arch/m32r/include/asm/unistd.h index 76125777483..c70545689da 100644 --- a/arch/m32r/include/asm/unistd.h +++ b/arch/m32r/include/asm/unistd.h | |||
@@ -351,6 +351,7 @@ | |||
351 | #define __ARCH_WANT_SYS_OLD_GETRLIMIT /*will be unused*/ | 351 | #define __ARCH_WANT_SYS_OLD_GETRLIMIT /*will be unused*/ |
352 | #define __ARCH_WANT_SYS_OLDUMOUNT | 352 | #define __ARCH_WANT_SYS_OLDUMOUNT |
353 | #define __ARCH_WANT_SYS_RT_SIGACTION | 353 | #define __ARCH_WANT_SYS_RT_SIGACTION |
354 | #define __ARCH_WANT_SYS_RT_SIGSUSPEND | ||
354 | 355 | ||
355 | #define __IGNORE_lchown | 356 | #define __IGNORE_lchown |
356 | #define __IGNORE_setuid | 357 | #define __IGNORE_setuid |
diff --git a/arch/m32r/kernel/entry.S b/arch/m32r/kernel/entry.S index 403869833b9..225412bc227 100644 --- a/arch/m32r/kernel/entry.S +++ b/arch/m32r/kernel/entry.S | |||
@@ -235,10 +235,9 @@ work_resched: | |||
235 | work_notifysig: ; deal with pending signals and | 235 | work_notifysig: ; deal with pending signals and |
236 | ; notify-resume requests | 236 | ; notify-resume requests |
237 | mv r0, sp ; arg1 : struct pt_regs *regs | 237 | mv r0, sp ; arg1 : struct pt_regs *regs |
238 | ldi r1, #0 ; arg2 : sigset_t *oldset | 238 | mv r1, r9 ; arg2 : __u32 thread_info_flags |
239 | mv r2, r9 ; arg3 : __u32 thread_info_flags | ||
240 | bl do_notify_resume | 239 | bl do_notify_resume |
241 | bra restore_all | 240 | bra resume_userspace |
242 | 241 | ||
243 | ; perform syscall exit tracing | 242 | ; perform syscall exit tracing |
244 | ALIGN | 243 | ALIGN |
diff --git a/arch/m32r/kernel/ptrace.c b/arch/m32r/kernel/ptrace.c index e555091eb97..0021ade4cba 100644 --- a/arch/m32r/kernel/ptrace.c +++ b/arch/m32r/kernel/ptrace.c | |||
@@ -592,16 +592,17 @@ void user_enable_single_step(struct task_struct *child) | |||
592 | 592 | ||
593 | if (access_process_vm(child, pc&~3, &insn, sizeof(insn), 0) | 593 | if (access_process_vm(child, pc&~3, &insn, sizeof(insn), 0) |
594 | != sizeof(insn)) | 594 | != sizeof(insn)) |
595 | break; | 595 | return -EIO; |
596 | 596 | ||
597 | compute_next_pc(insn, pc, &next_pc, child); | 597 | compute_next_pc(insn, pc, &next_pc, child); |
598 | if (next_pc & 0x80000000) | 598 | if (next_pc & 0x80000000) |
599 | break; | 599 | return -EIO; |
600 | 600 | ||
601 | if (embed_debug_trap(child, next_pc)) | 601 | if (embed_debug_trap(child, next_pc)) |
602 | break; | 602 | return -EIO; |
603 | 603 | ||
604 | invalidate_cache(); | 604 | invalidate_cache(); |
605 | return 0; | ||
605 | } | 606 | } |
606 | 607 | ||
607 | void user_disable_single_step(struct task_struct *child) | 608 | void user_disable_single_step(struct task_struct *child) |
diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c index 144b0f124fc..7bbe38645ed 100644 --- a/arch/m32r/kernel/signal.c +++ b/arch/m32r/kernel/signal.c | |||
@@ -28,37 +28,6 @@ | |||
28 | 28 | ||
29 | #define DEBUG_SIG 0 | 29 | #define DEBUG_SIG 0 |
30 | 30 | ||
31 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | ||
32 | |||
33 | int do_signal(struct pt_regs *, sigset_t *); | ||
34 | |||
35 | asmlinkage int | ||
36 | sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, | ||
37 | unsigned long r2, unsigned long r3, unsigned long r4, | ||
38 | unsigned long r5, unsigned long r6, struct pt_regs *regs) | ||
39 | { | ||
40 | sigset_t newset; | ||
41 | |||
42 | /* XXX: Don't preclude handling different sized sigset_t's. */ | ||
43 | if (sigsetsize != sizeof(sigset_t)) | ||
44 | return -EINVAL; | ||
45 | |||
46 | if (copy_from_user(&newset, unewset, sizeof(newset))) | ||
47 | return -EFAULT; | ||
48 | sigdelsetmask(&newset, sigmask(SIGKILL)|sigmask(SIGSTOP)); | ||
49 | |||
50 | spin_lock_irq(¤t->sighand->siglock); | ||
51 | current->saved_sigmask = current->blocked; | ||
52 | current->blocked = newset; | ||
53 | recalc_sigpending(); | ||
54 | spin_unlock_irq(¤t->sighand->siglock); | ||
55 | |||
56 | current->state = TASK_INTERRUPTIBLE; | ||
57 | schedule(); | ||
58 | set_thread_flag(TIF_RESTORE_SIGMASK); | ||
59 | return -ERESTARTNOHAND; | ||
60 | } | ||
61 | |||
62 | asmlinkage int | 31 | asmlinkage int |
63 | sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, | 32 | sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, |
64 | unsigned long r2, unsigned long r3, unsigned long r4, | 33 | unsigned long r2, unsigned long r3, unsigned long r4, |
@@ -218,7 +187,7 @@ get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size) | |||
218 | return (void __user *)((sp - frame_size) & -8ul); | 187 | return (void __user *)((sp - frame_size) & -8ul); |
219 | } | 188 | } |
220 | 189 | ||
221 | static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | 190 | static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, |
222 | sigset_t *set, struct pt_regs *regs) | 191 | sigset_t *set, struct pt_regs *regs) |
223 | { | 192 | { |
224 | struct rt_sigframe __user *frame; | 193 | struct rt_sigframe __user *frame; |
@@ -275,22 +244,34 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
275 | current->comm, current->pid, frame, regs->pc); | 244 | current->comm, current->pid, frame, regs->pc); |
276 | #endif | 245 | #endif |
277 | 246 | ||
278 | return; | 247 | return 0; |
279 | 248 | ||
280 | give_sigsegv: | 249 | give_sigsegv: |
281 | force_sigsegv(sig, current); | 250 | force_sigsegv(sig, current); |
251 | return -EFAULT; | ||
252 | } | ||
253 | |||
254 | static int prev_insn(struct pt_regs *regs) | ||
255 | { | ||
256 | u16 inst; | ||
257 | if (get_user(&inst, (u16 __user *)(regs->bpc - 2))) | ||
258 | return -EFAULT; | ||
259 | if ((inst & 0xfff0) == 0x10f0) /* trap ? */ | ||
260 | regs->bpc -= 2; | ||
261 | else | ||
262 | regs->bpc -= 4; | ||
263 | regs->syscall_nr = -1; | ||
264 | return 0; | ||
282 | } | 265 | } |
283 | 266 | ||
284 | /* | 267 | /* |
285 | * OK, we're invoking a handler | 268 | * OK, we're invoking a handler |
286 | */ | 269 | */ |
287 | 270 | ||
288 | static void | 271 | static int |
289 | handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, | 272 | handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, |
290 | sigset_t *oldset, struct pt_regs *regs) | 273 | sigset_t *oldset, struct pt_regs *regs) |
291 | { | 274 | { |
292 | unsigned short inst; | ||
293 | |||
294 | /* Are we from a system call? */ | 275 | /* Are we from a system call? */ |
295 | if (regs->syscall_nr >= 0) { | 276 | if (regs->syscall_nr >= 0) { |
296 | /* If so, check system call restarting.. */ | 277 | /* If so, check system call restarting.. */ |
@@ -308,16 +289,14 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, | |||
308 | /* fallthrough */ | 289 | /* fallthrough */ |
309 | case -ERESTARTNOINTR: | 290 | case -ERESTARTNOINTR: |
310 | regs->r0 = regs->orig_r0; | 291 | regs->r0 = regs->orig_r0; |
311 | inst = *(unsigned short *)(regs->bpc - 2); | 292 | if (prev_insn(regs) < 0) |
312 | if ((inst & 0xfff0) == 0x10f0) /* trap ? */ | 293 | return -EFAULT; |
313 | regs->bpc -= 2; | ||
314 | else | ||
315 | regs->bpc -= 4; | ||
316 | } | 294 | } |
317 | } | 295 | } |
318 | 296 | ||
319 | /* Set up the stack frame */ | 297 | /* Set up the stack frame */ |
320 | setup_rt_frame(sig, ka, info, oldset, regs); | 298 | if (setup_rt_frame(sig, ka, info, oldset, regs)) |
299 | return -EFAULT; | ||
321 | 300 | ||
322 | spin_lock_irq(¤t->sighand->siglock); | 301 | spin_lock_irq(¤t->sighand->siglock); |
323 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 302 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
@@ -325,6 +304,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, | |||
325 | sigaddset(¤t->blocked,sig); | 304 | sigaddset(¤t->blocked,sig); |
326 | recalc_sigpending(); | 305 | recalc_sigpending(); |
327 | spin_unlock_irq(¤t->sighand->siglock); | 306 | spin_unlock_irq(¤t->sighand->siglock); |
307 | return 0; | ||
328 | } | 308 | } |
329 | 309 | ||
330 | /* | 310 | /* |
@@ -332,12 +312,12 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, | |||
332 | * want to handle. Thus you cannot kill init even with a SIGKILL even by | 312 | * want to handle. Thus you cannot kill init even with a SIGKILL even by |
333 | * mistake. | 313 | * mistake. |
334 | */ | 314 | */ |
335 | int do_signal(struct pt_regs *regs, sigset_t *oldset) | 315 | static void do_signal(struct pt_regs *regs) |
336 | { | 316 | { |
337 | siginfo_t info; | 317 | siginfo_t info; |
338 | int signr; | 318 | int signr; |
339 | struct k_sigaction ka; | 319 | struct k_sigaction ka; |
340 | unsigned short inst; | 320 | sigset_t *oldset; |
341 | 321 | ||
342 | /* | 322 | /* |
343 | * We want the common case to go fast, which | 323 | * We want the common case to go fast, which |
@@ -346,12 +326,14 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) | |||
346 | * if so. | 326 | * if so. |
347 | */ | 327 | */ |
348 | if (!user_mode(regs)) | 328 | if (!user_mode(regs)) |
349 | return 1; | 329 | return; |
350 | 330 | ||
351 | if (try_to_freeze()) | 331 | if (try_to_freeze()) |
352 | goto no_signal; | 332 | goto no_signal; |
353 | 333 | ||
354 | if (!oldset) | 334 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) |
335 | oldset = ¤t->saved_sigmask; | ||
336 | else | ||
355 | oldset = ¤t->blocked; | 337 | oldset = ¤t->blocked; |
356 | 338 | ||
357 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | 339 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); |
@@ -363,8 +345,10 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) | |||
363 | */ | 345 | */ |
364 | 346 | ||
365 | /* Whee! Actually deliver the signal. */ | 347 | /* Whee! Actually deliver the signal. */ |
366 | handle_signal(signr, &ka, &info, oldset, regs); | 348 | if (handle_signal(signr, &ka, &info, oldset, regs) == 0) |
367 | return 1; | 349 | clear_thread_flag(TIF_RESTORE_SIGMASK); |
350 | |||
351 | return; | ||
368 | } | 352 | } |
369 | 353 | ||
370 | no_signal: | 354 | no_signal: |
@@ -375,31 +359,24 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) | |||
375 | regs->r0 == -ERESTARTSYS || | 359 | regs->r0 == -ERESTARTSYS || |
376 | regs->r0 == -ERESTARTNOINTR) { | 360 | regs->r0 == -ERESTARTNOINTR) { |
377 | regs->r0 = regs->orig_r0; | 361 | regs->r0 = regs->orig_r0; |
378 | inst = *(unsigned short *)(regs->bpc - 2); | 362 | prev_insn(regs); |
379 | if ((inst & 0xfff0) == 0x10f0) /* trap ? */ | 363 | } else if (regs->r0 == -ERESTART_RESTARTBLOCK){ |
380 | regs->bpc -= 2; | ||
381 | else | ||
382 | regs->bpc -= 4; | ||
383 | } | ||
384 | if (regs->r0 == -ERESTART_RESTARTBLOCK){ | ||
385 | regs->r0 = regs->orig_r0; | 364 | regs->r0 = regs->orig_r0; |
386 | regs->r7 = __NR_restart_syscall; | 365 | regs->r7 = __NR_restart_syscall; |
387 | inst = *(unsigned short *)(regs->bpc - 2); | 366 | prev_insn(regs); |
388 | if ((inst & 0xfff0) == 0x10f0) /* trap ? */ | ||
389 | regs->bpc -= 2; | ||
390 | else | ||
391 | regs->bpc -= 4; | ||
392 | } | 367 | } |
393 | } | 368 | } |
394 | return 0; | 369 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) { |
370 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
371 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | ||
372 | } | ||
395 | } | 373 | } |
396 | 374 | ||
397 | /* | 375 | /* |
398 | * notification of userspace execution resumption | 376 | * notification of userspace execution resumption |
399 | * - triggered by current->work.notify_resume | 377 | * - triggered by current->work.notify_resume |
400 | */ | 378 | */ |
401 | void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, | 379 | void do_notify_resume(struct pt_regs *regs, __u32 thread_info_flags) |
402 | __u32 thread_info_flags) | ||
403 | { | 380 | { |
404 | /* Pending single-step? */ | 381 | /* Pending single-step? */ |
405 | if (thread_info_flags & _TIF_SINGLESTEP) | 382 | if (thread_info_flags & _TIF_SINGLESTEP) |
@@ -407,7 +384,7 @@ void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, | |||
407 | 384 | ||
408 | /* deal with pending signal delivery */ | 385 | /* deal with pending signal delivery */ |
409 | if (thread_info_flags & _TIF_SIGPENDING) | 386 | if (thread_info_flags & _TIF_SIGPENDING) |
410 | do_signal(regs,oldset); | 387 | do_signal(regs); |
411 | 388 | ||
412 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { | 389 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { |
413 | clear_thread_flag(TIF_NOTIFY_RESUME); | 390 | clear_thread_flag(TIF_NOTIFY_RESUME); |
diff --git a/arch/m68k/include/asm/unistd.h b/arch/m68k/include/asm/unistd.h index 60b15d0aa07..b43b36beafe 100644 --- a/arch/m68k/include/asm/unistd.h +++ b/arch/m68k/include/asm/unistd.h | |||
@@ -340,10 +340,13 @@ | |||
340 | #define __NR_set_thread_area 334 | 340 | #define __NR_set_thread_area 334 |
341 | #define __NR_atomic_cmpxchg_32 335 | 341 | #define __NR_atomic_cmpxchg_32 335 |
342 | #define __NR_atomic_barrier 336 | 342 | #define __NR_atomic_barrier 336 |
343 | #define __NR_fanotify_init 337 | ||
344 | #define __NR_fanotify_mark 338 | ||
345 | #define __NR_prlimit64 339 | ||
343 | 346 | ||
344 | #ifdef __KERNEL__ | 347 | #ifdef __KERNEL__ |
345 | 348 | ||
346 | #define NR_syscalls 337 | 349 | #define NR_syscalls 340 |
347 | 350 | ||
348 | #define __ARCH_WANT_IPC_PARSE_VERSION | 351 | #define __ARCH_WANT_IPC_PARSE_VERSION |
349 | #define __ARCH_WANT_OLD_READDIR | 352 | #define __ARCH_WANT_OLD_READDIR |
diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S index 2391bdff099..6360c437dcf 100644 --- a/arch/m68k/kernel/entry.S +++ b/arch/m68k/kernel/entry.S | |||
@@ -765,4 +765,7 @@ sys_call_table: | |||
765 | .long sys_set_thread_area | 765 | .long sys_set_thread_area |
766 | .long sys_atomic_cmpxchg_32 /* 335 */ | 766 | .long sys_atomic_cmpxchg_32 /* 335 */ |
767 | .long sys_atomic_barrier | 767 | .long sys_atomic_barrier |
768 | .long sys_fanotify_init | ||
769 | .long sys_fanotify_mark | ||
770 | .long sys_prlimit64 | ||
768 | 771 | ||
diff --git a/arch/m68k/mac/macboing.c b/arch/m68k/mac/macboing.c index 8f0640847ad..05285d08e54 100644 --- a/arch/m68k/mac/macboing.c +++ b/arch/m68k/mac/macboing.c | |||
@@ -162,7 +162,7 @@ static void mac_init_asc( void ) | |||
162 | void mac_mksound( unsigned int freq, unsigned int length ) | 162 | void mac_mksound( unsigned int freq, unsigned int length ) |
163 | { | 163 | { |
164 | __u32 cfreq = ( freq << 5 ) / 468; | 164 | __u32 cfreq = ( freq << 5 ) / 468; |
165 | __u32 flags; | 165 | unsigned long flags; |
166 | int i; | 166 | int i; |
167 | 167 | ||
168 | if ( mac_special_bell == NULL ) | 168 | if ( mac_special_bell == NULL ) |
@@ -224,7 +224,7 @@ static void mac_nosound( unsigned long ignored ) | |||
224 | */ | 224 | */ |
225 | static void mac_quadra_start_bell( unsigned int freq, unsigned int length, unsigned int volume ) | 225 | static void mac_quadra_start_bell( unsigned int freq, unsigned int length, unsigned int volume ) |
226 | { | 226 | { |
227 | __u32 flags; | 227 | unsigned long flags; |
228 | 228 | ||
229 | /* if the bell is already ringing, ring longer */ | 229 | /* if the bell is already ringing, ring longer */ |
230 | if ( mac_bell_duration > 0 ) | 230 | if ( mac_bell_duration > 0 ) |
@@ -271,7 +271,7 @@ static void mac_quadra_start_bell( unsigned int freq, unsigned int length, unsig | |||
271 | static void mac_quadra_ring_bell( unsigned long ignored ) | 271 | static void mac_quadra_ring_bell( unsigned long ignored ) |
272 | { | 272 | { |
273 | int i, count = mac_asc_samplespersec / HZ; | 273 | int i, count = mac_asc_samplespersec / HZ; |
274 | __u32 flags; | 274 | unsigned long flags; |
275 | 275 | ||
276 | /* | 276 | /* |
277 | * we neither want a sound buffer overflow nor underflow, so we need to match | 277 | * we neither want a sound buffer overflow nor underflow, so we need to match |
diff --git a/arch/m68knommu/kernel/syscalltable.S b/arch/m68knommu/kernel/syscalltable.S index b30b3eb197a..79b1ed198c0 100644 --- a/arch/m68knommu/kernel/syscalltable.S +++ b/arch/m68knommu/kernel/syscalltable.S | |||
@@ -355,6 +355,9 @@ ENTRY(sys_call_table) | |||
355 | .long sys_set_thread_area | 355 | .long sys_set_thread_area |
356 | .long sys_atomic_cmpxchg_32 /* 335 */ | 356 | .long sys_atomic_cmpxchg_32 /* 335 */ |
357 | .long sys_atomic_barrier | 357 | .long sys_atomic_barrier |
358 | .long sys_fanotify_init | ||
359 | .long sys_fanotify_mark | ||
360 | .long sys_prlimit64 | ||
358 | 361 | ||
359 | .rept NR_syscalls-(.-sys_call_table)/4 | 362 | .rept NR_syscalls-(.-sys_call_table)/4 |
360 | .long sys_ni_syscall | 363 | .long sys_ni_syscall |
diff --git a/arch/m68knommu/kernel/vmlinux.lds.S b/arch/m68knommu/kernel/vmlinux.lds.S index a91b2713451..ef332136f96 100644 --- a/arch/m68knommu/kernel/vmlinux.lds.S +++ b/arch/m68knommu/kernel/vmlinux.lds.S | |||
@@ -150,6 +150,8 @@ SECTIONS { | |||
150 | _sdata = . ; | 150 | _sdata = . ; |
151 | DATA_DATA | 151 | DATA_DATA |
152 | CACHELINE_ALIGNED_DATA(32) | 152 | CACHELINE_ALIGNED_DATA(32) |
153 | PAGE_ALIGNED_DATA(PAGE_SIZE) | ||
154 | *(.data..shared_aligned) | ||
153 | INIT_TASK_DATA(THREAD_SIZE) | 155 | INIT_TASK_DATA(THREAD_SIZE) |
154 | _edata = . ; | 156 | _edata = . ; |
155 | } > DATA | 157 | } > DATA |
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 3ad59dde485..5526faabfc2 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -13,6 +13,7 @@ config MIPS | |||
13 | select HAVE_KPROBES | 13 | select HAVE_KPROBES |
14 | select HAVE_KRETPROBES | 14 | select HAVE_KRETPROBES |
15 | select RTC_LIB if !MACH_LOONGSON | 15 | select RTC_LIB if !MACH_LOONGSON |
16 | select GENERIC_ATOMIC64 if !64BIT | ||
16 | 17 | ||
17 | mainmenu "Linux/MIPS Kernel Configuration" | 18 | mainmenu "Linux/MIPS Kernel Configuration" |
18 | 19 | ||
@@ -1646,8 +1647,16 @@ config MIPS_MT_SMP | |||
1646 | select SYS_SUPPORTS_SMP | 1647 | select SYS_SUPPORTS_SMP |
1647 | select SMP_UP | 1648 | select SMP_UP |
1648 | help | 1649 | help |
1649 | This is a kernel model which is also known a VSMP or lately | 1650 | This is a kernel model which is known a VSMP but lately has been |
1650 | has been marketesed into SMVP. | 1651 | marketesed into SMVP. |
1652 | Virtual SMP uses the processor's VPEs to implement virtual | ||
1653 | processors. In currently available configuration of the 34K processor | ||
1654 | this allows for a dual processor. Both processors will share the same | ||
1655 | primary caches; each will obtain the half of the TLB for it's own | ||
1656 | exclusive use. For a layman this model can be described as similar to | ||
1657 | what Intel calls Hyperthreading. | ||
1658 | |||
1659 | For further information see http://www.linux-mips.org/wiki/34K#VSMP | ||
1651 | 1660 | ||
1652 | config MIPS_MT_SMTC | 1661 | config MIPS_MT_SMTC |
1653 | bool "SMTC: Use all TCs on all VPEs for SMP" | 1662 | bool "SMTC: Use all TCs on all VPEs for SMP" |
@@ -1664,6 +1673,14 @@ config MIPS_MT_SMTC | |||
1664 | help | 1673 | help |
1665 | This is a kernel model which is known a SMTC or lately has been | 1674 | This is a kernel model which is known a SMTC or lately has been |
1666 | marketesed into SMVP. | 1675 | marketesed into SMVP. |
1676 | is presenting the available TC's of the core as processors to Linux. | ||
1677 | On currently available 34K processors this means a Linux system will | ||
1678 | see up to 5 processors. The implementation of the SMTC kernel differs | ||
1679 | significantly from VSMP and cannot efficiently coexist in the same | ||
1680 | kernel binary so the choice between VSMP and SMTC is a compile time | ||
1681 | decision. | ||
1682 | |||
1683 | For further information see http://www.linux-mips.org/wiki/34K#SMTC | ||
1667 | 1684 | ||
1668 | endchoice | 1685 | endchoice |
1669 | 1686 | ||
diff --git a/arch/mips/alchemy/common/prom.c b/arch/mips/alchemy/common/prom.c index c29511b11d4..53402105962 100644 --- a/arch/mips/alchemy/common/prom.c +++ b/arch/mips/alchemy/common/prom.c | |||
@@ -43,7 +43,7 @@ int prom_argc; | |||
43 | char **prom_argv; | 43 | char **prom_argv; |
44 | char **prom_envp; | 44 | char **prom_envp; |
45 | 45 | ||
46 | void prom_init_cmdline(void) | 46 | void __init prom_init_cmdline(void) |
47 | { | 47 | { |
48 | int i; | 48 | int i; |
49 | 49 | ||
@@ -104,7 +104,7 @@ static inline void str2eaddr(unsigned char *ea, unsigned char *str) | |||
104 | } | 104 | } |
105 | } | 105 | } |
106 | 106 | ||
107 | int prom_get_ethernet_addr(char *ethernet_addr) | 107 | int __init prom_get_ethernet_addr(char *ethernet_addr) |
108 | { | 108 | { |
109 | char *ethaddr_str; | 109 | char *ethaddr_str; |
110 | 110 | ||
@@ -123,7 +123,6 @@ int prom_get_ethernet_addr(char *ethernet_addr) | |||
123 | 123 | ||
124 | return 0; | 124 | return 0; |
125 | } | 125 | } |
126 | EXPORT_SYMBOL(prom_get_ethernet_addr); | ||
127 | 126 | ||
128 | void __init prom_free_prom_memory(void) | 127 | void __init prom_free_prom_memory(void) |
129 | { | 128 | { |
diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile index ed9bb709c9a..5fd7f7a58b7 100644 --- a/arch/mips/boot/compressed/Makefile +++ b/arch/mips/boot/compressed/Makefile | |||
@@ -59,7 +59,7 @@ $(obj)/piggy.o: $(obj)/dummy.o $(obj)/vmlinux.bin.z FORCE | |||
59 | hostprogs-y := calc_vmlinuz_load_addr | 59 | hostprogs-y := calc_vmlinuz_load_addr |
60 | 60 | ||
61 | VMLINUZ_LOAD_ADDRESS = $(shell $(obj)/calc_vmlinuz_load_addr \ | 61 | VMLINUZ_LOAD_ADDRESS = $(shell $(obj)/calc_vmlinuz_load_addr \ |
62 | $(objtree)/$(KBUILD_IMAGE) $(VMLINUX_LOAD_ADDRESS)) | 62 | $(obj)/vmlinux.bin $(VMLINUX_LOAD_ADDRESS)) |
63 | 63 | ||
64 | vmlinuzobjs-y += $(obj)/piggy.o | 64 | vmlinuzobjs-y += $(obj)/piggy.o |
65 | 65 | ||
diff --git a/arch/mips/cavium-octeon/Kconfig b/arch/mips/cavium-octeon/Kconfig index 094c17e38e1..47323ca452d 100644 --- a/arch/mips/cavium-octeon/Kconfig +++ b/arch/mips/cavium-octeon/Kconfig | |||
@@ -83,3 +83,7 @@ config ARCH_SPARSEMEM_ENABLE | |||
83 | def_bool y | 83 | def_bool y |
84 | select SPARSEMEM_STATIC | 84 | select SPARSEMEM_STATIC |
85 | depends on CPU_CAVIUM_OCTEON | 85 | depends on CPU_CAVIUM_OCTEON |
86 | |||
87 | config CAVIUM_OCTEON_HELPER | ||
88 | def_bool y | ||
89 | depends on OCTEON_ETHERNET || PCI | ||
diff --git a/arch/mips/cavium-octeon/cpu.c b/arch/mips/cavium-octeon/cpu.c index c664c8cc2b4..a5b427909b5 100644 --- a/arch/mips/cavium-octeon/cpu.c +++ b/arch/mips/cavium-octeon/cpu.c | |||
@@ -41,7 +41,7 @@ static int cnmips_cu2_call(struct notifier_block *nfb, unsigned long action, | |||
41 | return NOTIFY_OK; /* Let default notifier send signals */ | 41 | return NOTIFY_OK; /* Let default notifier send signals */ |
42 | } | 42 | } |
43 | 43 | ||
44 | static int cnmips_cu2_setup(void) | 44 | static int __init cnmips_cu2_setup(void) |
45 | { | 45 | { |
46 | return cu2_notifier(cnmips_cu2_call, 0); | 46 | return cu2_notifier(cnmips_cu2_call, 0); |
47 | } | 47 | } |
diff --git a/arch/mips/cavium-octeon/executive/Makefile b/arch/mips/cavium-octeon/executive/Makefile index 2fd66db6939..7f41c5be219 100644 --- a/arch/mips/cavium-octeon/executive/Makefile +++ b/arch/mips/cavium-octeon/executive/Makefile | |||
@@ -11,4 +11,4 @@ | |||
11 | 11 | ||
12 | obj-y += cvmx-bootmem.o cvmx-l2c.o cvmx-sysinfo.o octeon-model.o | 12 | obj-y += cvmx-bootmem.o cvmx-l2c.o cvmx-sysinfo.o octeon-model.o |
13 | 13 | ||
14 | obj-$(CONFIG_PCI) += cvmx-helper-errata.o cvmx-helper-jtag.o | 14 | obj-$(CONFIG_CAVIUM_OCTEON_HELPER) += cvmx-helper-errata.o cvmx-helper-jtag.o |
diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h index c63c56bfd18..47d87da379f 100644 --- a/arch/mips/include/asm/atomic.h +++ b/arch/mips/include/asm/atomic.h | |||
@@ -782,6 +782,10 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) | |||
782 | */ | 782 | */ |
783 | #define atomic64_add_negative(i, v) (atomic64_add_return(i, (v)) < 0) | 783 | #define atomic64_add_negative(i, v) (atomic64_add_return(i, (v)) < 0) |
784 | 784 | ||
785 | #else /* !CONFIG_64BIT */ | ||
786 | |||
787 | #include <asm-generic/atomic64.h> | ||
788 | |||
785 | #endif /* CONFIG_64BIT */ | 789 | #endif /* CONFIG_64BIT */ |
786 | 790 | ||
787 | /* | 791 | /* |
diff --git a/arch/mips/include/asm/compat.h b/arch/mips/include/asm/compat.h index 613f6912dfc..dbc51065df5 100644 --- a/arch/mips/include/asm/compat.h +++ b/arch/mips/include/asm/compat.h | |||
@@ -145,7 +145,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) | |||
145 | return (u32)(unsigned long)uptr; | 145 | return (u32)(unsigned long)uptr; |
146 | } | 146 | } |
147 | 147 | ||
148 | static inline void __user *compat_alloc_user_space(long len) | 148 | static inline void __user *arch_compat_alloc_user_space(long len) |
149 | { | 149 | { |
150 | struct pt_regs *regs = (struct pt_regs *) | 150 | struct pt_regs *regs = (struct pt_regs *) |
151 | ((unsigned long) current_thread_info() + THREAD_SIZE - 32) - 1; | 151 | ((unsigned long) current_thread_info() + THREAD_SIZE - 32) - 1; |
diff --git a/arch/mips/include/asm/cop2.h b/arch/mips/include/asm/cop2.h index 2cb2f0c2c4f..3532e2c5f09 100644 --- a/arch/mips/include/asm/cop2.h +++ b/arch/mips/include/asm/cop2.h | |||
@@ -24,7 +24,7 @@ extern int cu2_notifier_call_chain(unsigned long val, void *v); | |||
24 | 24 | ||
25 | #define cu2_notifier(fn, pri) \ | 25 | #define cu2_notifier(fn, pri) \ |
26 | ({ \ | 26 | ({ \ |
27 | static struct notifier_block fn##_nb __cpuinitdata = { \ | 27 | static struct notifier_block fn##_nb = { \ |
28 | .notifier_call = fn, \ | 28 | .notifier_call = fn, \ |
29 | .priority = pri \ | 29 | .priority = pri \ |
30 | }; \ | 30 | }; \ |
diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h index 9b9436a4d81..86548da650e 100644 --- a/arch/mips/include/asm/gic.h +++ b/arch/mips/include/asm/gic.h | |||
@@ -321,6 +321,7 @@ struct gic_intrmask_regs { | |||
321 | */ | 321 | */ |
322 | struct gic_intr_map { | 322 | struct gic_intr_map { |
323 | unsigned int cpunum; /* Directed to this CPU */ | 323 | unsigned int cpunum; /* Directed to this CPU */ |
324 | #define GIC_UNUSED 0xdead /* Dummy data */ | ||
324 | unsigned int pin; /* Directed to this Pin */ | 325 | unsigned int pin; /* Directed to this Pin */ |
325 | unsigned int polarity; /* Polarity : +/- */ | 326 | unsigned int polarity; /* Polarity : +/- */ |
326 | unsigned int trigtype; /* Trigger : Edge/Levl */ | 327 | unsigned int trigtype; /* Trigger : Edge/Levl */ |
diff --git a/arch/mips/include/asm/mach-tx49xx/kmalloc.h b/arch/mips/include/asm/mach-tx49xx/kmalloc.h index b74caf65482..ff9a8b86cb9 100644 --- a/arch/mips/include/asm/mach-tx49xx/kmalloc.h +++ b/arch/mips/include/asm/mach-tx49xx/kmalloc.h | |||
@@ -1,6 +1,6 @@ | |||
1 | #ifndef __ASM_MACH_TX49XX_KMALLOC_H | 1 | #ifndef __ASM_MACH_TX49XX_KMALLOC_H |
2 | #define __ASM_MACH_TX49XX_KMALLOC_H | 2 | #define __ASM_MACH_TX49XX_KMALLOC_H |
3 | 3 | ||
4 | #define ARCH_KMALLOC_MINALIGN L1_CACHE_BYTES | 4 | #define ARCH_DMA_MINALIGN L1_CACHE_BYTES |
5 | 5 | ||
6 | #endif /* __ASM_MACH_TX49XX_KMALLOC_H */ | 6 | #endif /* __ASM_MACH_TX49XX_KMALLOC_H */ |
diff --git a/arch/mips/include/asm/mips-boards/maltaint.h b/arch/mips/include/asm/mips-boards/maltaint.h index cea872fc6f5..d11aa02a956 100644 --- a/arch/mips/include/asm/mips-boards/maltaint.h +++ b/arch/mips/include/asm/mips-boards/maltaint.h | |||
@@ -88,9 +88,6 @@ | |||
88 | 88 | ||
89 | #define GIC_EXT_INTR(x) x | 89 | #define GIC_EXT_INTR(x) x |
90 | 90 | ||
91 | /* Dummy data */ | ||
92 | #define X 0xdead | ||
93 | |||
94 | /* External Interrupts used for IPI */ | 91 | /* External Interrupts used for IPI */ |
95 | #define GIC_IPI_EXT_INTR_RESCHED_VPE0 16 | 92 | #define GIC_IPI_EXT_INTR_RESCHED_VPE0 16 |
96 | #define GIC_IPI_EXT_INTR_CALLFNC_VPE0 17 | 93 | #define GIC_IPI_EXT_INTR_CALLFNC_VPE0 17 |
diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h index a16beafcea9..e59cd1ac09c 100644 --- a/arch/mips/include/asm/page.h +++ b/arch/mips/include/asm/page.h | |||
@@ -150,6 +150,20 @@ typedef struct { unsigned long pgprot; } pgprot_t; | |||
150 | ((unsigned long)(x) - PAGE_OFFSET + PHYS_OFFSET) | 150 | ((unsigned long)(x) - PAGE_OFFSET + PHYS_OFFSET) |
151 | #endif | 151 | #endif |
152 | #define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET - PHYS_OFFSET)) | 152 | #define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET - PHYS_OFFSET)) |
153 | |||
154 | /* | ||
155 | * RELOC_HIDE was originally added by 6007b903dfe5f1d13e0c711ac2894bdd4a61b1ad | ||
156 | * (lmo) rsp. 8431fd094d625b94d364fe393076ccef88e6ce18 (kernel.org). The | ||
157 | * discussion can be found in lkml posting | ||
158 | * <a2ebde260608230500o3407b108hc03debb9da6e62c@mail.gmail.com> which is | ||
159 | * archived at http://lists.linuxcoding.com/kernel/2006-q3/msg17360.html | ||
160 | * | ||
161 | * It is unclear if the misscompilations mentioned in | ||
162 | * http://lkml.org/lkml/2010/8/8/138 also affect MIPS so we keep this one | ||
163 | * until GCC 3.x has been retired before we can apply | ||
164 | * https://patchwork.linux-mips.org/patch/1541/ | ||
165 | */ | ||
166 | |||
153 | #define __pa_symbol(x) __pa(RELOC_HIDE((unsigned long)(x), 0)) | 167 | #define __pa_symbol(x) __pa(RELOC_HIDE((unsigned long)(x), 0)) |
154 | 168 | ||
155 | #define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) | 169 | #define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) |
diff --git a/arch/mips/include/asm/siginfo.h b/arch/mips/include/asm/siginfo.h index 96e28f18dad..1ca64b4d33d 100644 --- a/arch/mips/include/asm/siginfo.h +++ b/arch/mips/include/asm/siginfo.h | |||
@@ -88,6 +88,7 @@ typedef struct siginfo { | |||
88 | #ifdef __ARCH_SI_TRAPNO | 88 | #ifdef __ARCH_SI_TRAPNO |
89 | int _trapno; /* TRAP # which caused the signal */ | 89 | int _trapno; /* TRAP # which caused the signal */ |
90 | #endif | 90 | #endif |
91 | short _addr_lsb; | ||
91 | } _sigfault; | 92 | } _sigfault; |
92 | 93 | ||
93 | /* SIGPOLL, SIGXFSZ (To do ...) */ | 94 | /* SIGPOLL, SIGXFSZ (To do ...) */ |
diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h index 2376f2e06e4..70df9c0d3c5 100644 --- a/arch/mips/include/asm/thread_info.h +++ b/arch/mips/include/asm/thread_info.h | |||
@@ -146,7 +146,8 @@ register struct thread_info *__current_thread_info __asm__("$28"); | |||
146 | #define _TIF_LOAD_WATCH (1<<TIF_LOAD_WATCH) | 146 | #define _TIF_LOAD_WATCH (1<<TIF_LOAD_WATCH) |
147 | 147 | ||
148 | /* work to do on interrupt/exception return */ | 148 | /* work to do on interrupt/exception return */ |
149 | #define _TIF_WORK_MASK (0x0000ffef & ~_TIF_SECCOMP) | 149 | #define _TIF_WORK_MASK (0x0000ffef & \ |
150 | ~(_TIF_SECCOMP | _TIF_SYSCALL_AUDIT)) | ||
150 | /* work to do on any return to u-space */ | 151 | /* work to do on any return to u-space */ |
151 | #define _TIF_ALLWORK_MASK (0x8000ffff & ~_TIF_SECCOMP) | 152 | #define _TIF_ALLWORK_MASK (0x8000ffff & ~_TIF_SECCOMP) |
152 | 153 | ||
diff --git a/arch/mips/include/asm/unistd.h b/arch/mips/include/asm/unistd.h index baa318a59c9..550725b881d 100644 --- a/arch/mips/include/asm/unistd.h +++ b/arch/mips/include/asm/unistd.h | |||
@@ -356,16 +356,19 @@ | |||
356 | #define __NR_perf_event_open (__NR_Linux + 333) | 356 | #define __NR_perf_event_open (__NR_Linux + 333) |
357 | #define __NR_accept4 (__NR_Linux + 334) | 357 | #define __NR_accept4 (__NR_Linux + 334) |
358 | #define __NR_recvmmsg (__NR_Linux + 335) | 358 | #define __NR_recvmmsg (__NR_Linux + 335) |
359 | #define __NR_fanotify_init (__NR_Linux + 336) | ||
360 | #define __NR_fanotify_mark (__NR_Linux + 337) | ||
361 | #define __NR_prlimit64 (__NR_Linux + 338) | ||
359 | 362 | ||
360 | /* | 363 | /* |
361 | * Offset of the last Linux o32 flavoured syscall | 364 | * Offset of the last Linux o32 flavoured syscall |
362 | */ | 365 | */ |
363 | #define __NR_Linux_syscalls 335 | 366 | #define __NR_Linux_syscalls 338 |
364 | 367 | ||
365 | #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ | 368 | #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ |
366 | 369 | ||
367 | #define __NR_O32_Linux 4000 | 370 | #define __NR_O32_Linux 4000 |
368 | #define __NR_O32_Linux_syscalls 335 | 371 | #define __NR_O32_Linux_syscalls 338 |
369 | 372 | ||
370 | #if _MIPS_SIM == _MIPS_SIM_ABI64 | 373 | #if _MIPS_SIM == _MIPS_SIM_ABI64 |
371 | 374 | ||
@@ -668,16 +671,19 @@ | |||
668 | #define __NR_perf_event_open (__NR_Linux + 292) | 671 | #define __NR_perf_event_open (__NR_Linux + 292) |
669 | #define __NR_accept4 (__NR_Linux + 293) | 672 | #define __NR_accept4 (__NR_Linux + 293) |
670 | #define __NR_recvmmsg (__NR_Linux + 294) | 673 | #define __NR_recvmmsg (__NR_Linux + 294) |
674 | #define __NR_fanotify_init (__NR_Linux + 295) | ||
675 | #define __NR_fanotify_mark (__NR_Linux + 296) | ||
676 | #define __NR_prlimit64 (__NR_Linux + 297) | ||
671 | 677 | ||
672 | /* | 678 | /* |
673 | * Offset of the last Linux 64-bit flavoured syscall | 679 | * Offset of the last Linux 64-bit flavoured syscall |
674 | */ | 680 | */ |
675 | #define __NR_Linux_syscalls 294 | 681 | #define __NR_Linux_syscalls 297 |
676 | 682 | ||
677 | #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ | 683 | #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ |
678 | 684 | ||
679 | #define __NR_64_Linux 5000 | 685 | #define __NR_64_Linux 5000 |
680 | #define __NR_64_Linux_syscalls 294 | 686 | #define __NR_64_Linux_syscalls 297 |
681 | 687 | ||
682 | #if _MIPS_SIM == _MIPS_SIM_NABI32 | 688 | #if _MIPS_SIM == _MIPS_SIM_NABI32 |
683 | 689 | ||
@@ -985,16 +991,19 @@ | |||
985 | #define __NR_accept4 (__NR_Linux + 297) | 991 | #define __NR_accept4 (__NR_Linux + 297) |
986 | #define __NR_recvmmsg (__NR_Linux + 298) | 992 | #define __NR_recvmmsg (__NR_Linux + 298) |
987 | #define __NR_getdents64 (__NR_Linux + 299) | 993 | #define __NR_getdents64 (__NR_Linux + 299) |
994 | #define __NR_fanotify_init (__NR_Linux + 300) | ||
995 | #define __NR_fanotify_mark (__NR_Linux + 301) | ||
996 | #define __NR_prlimit64 (__NR_Linux + 302) | ||
988 | 997 | ||
989 | /* | 998 | /* |
990 | * Offset of the last N32 flavoured syscall | 999 | * Offset of the last N32 flavoured syscall |
991 | */ | 1000 | */ |
992 | #define __NR_Linux_syscalls 299 | 1001 | #define __NR_Linux_syscalls 302 |
993 | 1002 | ||
994 | #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ | 1003 | #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ |
995 | 1004 | ||
996 | #define __NR_N32_Linux 6000 | 1005 | #define __NR_N32_Linux 6000 |
997 | #define __NR_N32_Linux_syscalls 299 | 1006 | #define __NR_N32_Linux_syscalls 302 |
998 | 1007 | ||
999 | #ifdef __KERNEL__ | 1008 | #ifdef __KERNEL__ |
1000 | 1009 | ||
diff --git a/arch/mips/kernel/irq-gic.c b/arch/mips/kernel/irq-gic.c index b181f2f0ea8..82ba9f62f49 100644 --- a/arch/mips/kernel/irq-gic.c +++ b/arch/mips/kernel/irq-gic.c | |||
@@ -7,7 +7,6 @@ | |||
7 | #include <asm/io.h> | 7 | #include <asm/io.h> |
8 | #include <asm/gic.h> | 8 | #include <asm/gic.h> |
9 | #include <asm/gcmpregs.h> | 9 | #include <asm/gcmpregs.h> |
10 | #include <asm/mips-boards/maltaint.h> | ||
11 | #include <asm/irq.h> | 10 | #include <asm/irq.h> |
12 | #include <linux/hardirq.h> | 11 | #include <linux/hardirq.h> |
13 | #include <asm-generic/bitops/find.h> | 12 | #include <asm-generic/bitops/find.h> |
@@ -131,7 +130,7 @@ static int gic_set_affinity(unsigned int irq, const struct cpumask *cpumask) | |||
131 | int i; | 130 | int i; |
132 | 131 | ||
133 | irq -= _irqbase; | 132 | irq -= _irqbase; |
134 | pr_debug(KERN_DEBUG "%s(%d) called\n", __func__, irq); | 133 | pr_debug("%s(%d) called\n", __func__, irq); |
135 | cpumask_and(&tmp, cpumask, cpu_online_mask); | 134 | cpumask_and(&tmp, cpumask, cpu_online_mask); |
136 | if (cpus_empty(tmp)) | 135 | if (cpus_empty(tmp)) |
137 | return -1; | 136 | return -1; |
@@ -222,7 +221,7 @@ static void __init gic_basic_init(int numintrs, int numvpes, | |||
222 | /* Setup specifics */ | 221 | /* Setup specifics */ |
223 | for (i = 0; i < mapsize; i++) { | 222 | for (i = 0; i < mapsize; i++) { |
224 | cpu = intrmap[i].cpunum; | 223 | cpu = intrmap[i].cpunum; |
225 | if (cpu == X) | 224 | if (cpu == GIC_UNUSED) |
226 | continue; | 225 | continue; |
227 | if (cpu == 0 && i != 0 && intrmap[i].flags == 0) | 226 | if (cpu == 0 && i != 0 && intrmap[i].flags == 0) |
228 | continue; | 227 | continue; |
diff --git a/arch/mips/kernel/kgdb.c b/arch/mips/kernel/kgdb.c index 1f4e2fa6414..f4546e97c60 100644 --- a/arch/mips/kernel/kgdb.c +++ b/arch/mips/kernel/kgdb.c | |||
@@ -283,7 +283,7 @@ static int kgdb_mips_notify(struct notifier_block *self, unsigned long cmd, | |||
283 | struct pt_regs *regs = args->regs; | 283 | struct pt_regs *regs = args->regs; |
284 | int trap = (regs->cp0_cause & 0x7c) >> 2; | 284 | int trap = (regs->cp0_cause & 0x7c) >> 2; |
285 | 285 | ||
286 | /* Userpace events, ignore. */ | 286 | /* Userspace events, ignore. */ |
287 | if (user_mode(regs)) | 287 | if (user_mode(regs)) |
288 | return NOTIFY_DONE; | 288 | return NOTIFY_DONE; |
289 | 289 | ||
diff --git a/arch/mips/kernel/kspd.c b/arch/mips/kernel/kspd.c index 80e2ba694ba..29811f04339 100644 --- a/arch/mips/kernel/kspd.c +++ b/arch/mips/kernel/kspd.c | |||
@@ -251,7 +251,7 @@ void sp_work_handle_request(void) | |||
251 | memset(&tz, 0, sizeof(tz)); | 251 | memset(&tz, 0, sizeof(tz)); |
252 | if ((ret.retval = sp_syscall(__NR_gettimeofday, (int)&tv, | 252 | if ((ret.retval = sp_syscall(__NR_gettimeofday, (int)&tv, |
253 | (int)&tz, 0, 0)) == 0) | 253 | (int)&tz, 0, 0)) == 0) |
254 | ret.retval = tv.tv_sec; | 254 | ret.retval = tv.tv_sec; |
255 | break; | 255 | break; |
256 | 256 | ||
257 | case MTSP_SYSCALL_EXIT: | 257 | case MTSP_SYSCALL_EXIT: |
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index c2dab140dc9..6343b4a5b83 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c | |||
@@ -341,3 +341,10 @@ asmlinkage long sys32_lookup_dcookie(u32 a0, u32 a1, char __user *buf, | |||
341 | { | 341 | { |
342 | return sys_lookup_dcookie(merge_64(a0, a1), buf, len); | 342 | return sys_lookup_dcookie(merge_64(a0, a1), buf, len); |
343 | } | 343 | } |
344 | |||
345 | SYSCALL_DEFINE6(32_fanotify_mark, int, fanotify_fd, unsigned int, flags, | ||
346 | u64, a3, u64, a4, int, dfd, const char __user *, pathname) | ||
347 | { | ||
348 | return sys_fanotify_mark(fanotify_fd, flags, merge_64(a3, a4), | ||
349 | dfd, pathname); | ||
350 | } | ||
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index 17202bbe843..584415eef8c 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S | |||
@@ -583,7 +583,10 @@ einval: li v0, -ENOSYS | |||
583 | sys sys_rt_tgsigqueueinfo 4 | 583 | sys sys_rt_tgsigqueueinfo 4 |
584 | sys sys_perf_event_open 5 | 584 | sys sys_perf_event_open 5 |
585 | sys sys_accept4 4 | 585 | sys sys_accept4 4 |
586 | sys sys_recvmmsg 5 | 586 | sys sys_recvmmsg 5 /* 4335 */ |
587 | sys sys_fanotify_init 2 | ||
588 | sys sys_fanotify_mark 6 | ||
589 | sys sys_prlimit64 4 | ||
587 | .endm | 590 | .endm |
588 | 591 | ||
589 | /* We pre-compute the number of _instruction_ bytes needed to | 592 | /* We pre-compute the number of _instruction_ bytes needed to |
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index a8a6c596eb0..5573f8e4e32 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S | |||
@@ -416,9 +416,12 @@ sys_call_table: | |||
416 | PTR sys_pipe2 | 416 | PTR sys_pipe2 |
417 | PTR sys_inotify_init1 | 417 | PTR sys_inotify_init1 |
418 | PTR sys_preadv | 418 | PTR sys_preadv |
419 | PTR sys_pwritev /* 5390 */ | 419 | PTR sys_pwritev /* 5290 */ |
420 | PTR sys_rt_tgsigqueueinfo | 420 | PTR sys_rt_tgsigqueueinfo |
421 | PTR sys_perf_event_open | 421 | PTR sys_perf_event_open |
422 | PTR sys_accept4 | 422 | PTR sys_accept4 |
423 | PTR sys_recvmmsg | 423 | PTR sys_recvmmsg |
424 | PTR sys_fanotify_init /* 5295 */ | ||
425 | PTR sys_fanotify_mark | ||
426 | PTR sys_prlimit64 | ||
424 | .size sys_call_table,.-sys_call_table | 427 | .size sys_call_table,.-sys_call_table |
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index a3d66137731..1e38ec97672 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S | |||
@@ -419,5 +419,8 @@ EXPORT(sysn32_call_table) | |||
419 | PTR sys_perf_event_open | 419 | PTR sys_perf_event_open |
420 | PTR sys_accept4 | 420 | PTR sys_accept4 |
421 | PTR compat_sys_recvmmsg | 421 | PTR compat_sys_recvmmsg |
422 | PTR sys_getdents | 422 | PTR sys_getdents64 |
423 | PTR sys_fanotify_init /* 6300 */ | ||
424 | PTR sys_fanotify_mark | ||
425 | PTR sys_prlimit64 | ||
423 | .size sysn32_call_table,.-sysn32_call_table | 426 | .size sysn32_call_table,.-sysn32_call_table |
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 813689ef238..171979fc98e 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S | |||
@@ -538,5 +538,8 @@ sys_call_table: | |||
538 | PTR compat_sys_rt_tgsigqueueinfo | 538 | PTR compat_sys_rt_tgsigqueueinfo |
539 | PTR sys_perf_event_open | 539 | PTR sys_perf_event_open |
540 | PTR sys_accept4 | 540 | PTR sys_accept4 |
541 | PTR compat_sys_recvmmsg | 541 | PTR compat_sys_recvmmsg /* 4335 */ |
542 | PTR sys_fanotify_init | ||
543 | PTR sys_32_fanotify_mark | ||
544 | PTR sys_prlimit64 | ||
542 | .size sys_call_table,.-sys_call_table | 545 | .size sys_call_table,.-sys_call_table |
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index 7ba890860d9..469d4019f79 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c | |||
@@ -44,27 +44,39 @@ static inline int cpu_is_noncoherent_r10000(struct device *dev) | |||
44 | 44 | ||
45 | static gfp_t massage_gfp_flags(const struct device *dev, gfp_t gfp) | 45 | static gfp_t massage_gfp_flags(const struct device *dev, gfp_t gfp) |
46 | { | 46 | { |
47 | gfp_t dma_flag; | ||
48 | |||
47 | /* ignore region specifiers */ | 49 | /* ignore region specifiers */ |
48 | gfp &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM); | 50 | gfp &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM); |
49 | 51 | ||
50 | #ifdef CONFIG_ZONE_DMA | 52 | #ifdef CONFIG_ISA |
51 | if (dev == NULL) | 53 | if (dev == NULL) |
52 | gfp |= __GFP_DMA; | 54 | dma_flag = __GFP_DMA; |
53 | else if (dev->coherent_dma_mask < DMA_BIT_MASK(24)) | ||
54 | gfp |= __GFP_DMA; | ||
55 | else | 55 | else |
56 | #endif | 56 | #endif |
57 | #ifdef CONFIG_ZONE_DMA32 | 57 | #if defined(CONFIG_ZONE_DMA32) && defined(CONFIG_ZONE_DMA) |
58 | if (dev->coherent_dma_mask < DMA_BIT_MASK(32)) | 58 | if (dev->coherent_dma_mask < DMA_BIT_MASK(32)) |
59 | gfp |= __GFP_DMA32; | 59 | dma_flag = __GFP_DMA; |
60 | else if (dev->coherent_dma_mask < DMA_BIT_MASK(64)) | ||
61 | dma_flag = __GFP_DMA32; | ||
62 | else | ||
63 | #endif | ||
64 | #if defined(CONFIG_ZONE_DMA32) && !defined(CONFIG_ZONE_DMA) | ||
65 | if (dev->coherent_dma_mask < DMA_BIT_MASK(64)) | ||
66 | dma_flag = __GFP_DMA32; | ||
67 | else | ||
68 | #endif | ||
69 | #if defined(CONFIG_ZONE_DMA) && !defined(CONFIG_ZONE_DMA32) | ||
70 | if (dev->coherent_dma_mask < DMA_BIT_MASK(64)) | ||
71 | dma_flag = __GFP_DMA; | ||
60 | else | 72 | else |
61 | #endif | 73 | #endif |
62 | ; | 74 | dma_flag = 0; |
63 | 75 | ||
64 | /* Don't invoke OOM killer */ | 76 | /* Don't invoke OOM killer */ |
65 | gfp |= __GFP_NORETRY; | 77 | gfp |= __GFP_NORETRY; |
66 | 78 | ||
67 | return gfp; | 79 | return gfp | dma_flag; |
68 | } | 80 | } |
69 | 81 | ||
70 | void *dma_alloc_noncoherent(struct device *dev, size_t size, | 82 | void *dma_alloc_noncoherent(struct device *dev, size_t size, |
diff --git a/arch/mips/mm/sc-rm7k.c b/arch/mips/mm/sc-rm7k.c index 1ef75cd80a0..274af3be144 100644 --- a/arch/mips/mm/sc-rm7k.c +++ b/arch/mips/mm/sc-rm7k.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #define tc_lsize 32 | 30 | #define tc_lsize 32 |
31 | 31 | ||
32 | extern unsigned long icache_way_size, dcache_way_size; | 32 | extern unsigned long icache_way_size, dcache_way_size; |
33 | unsigned long tcache_size; | 33 | static unsigned long tcache_size; |
34 | 34 | ||
35 | #include <asm/r4kcache.h> | 35 | #include <asm/r4kcache.h> |
36 | 36 | ||
diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c index 15949b0be81..b79b24afe3a 100644 --- a/arch/mips/mti-malta/malta-int.c +++ b/arch/mips/mti-malta/malta-int.c | |||
@@ -385,6 +385,8 @@ static int __initdata msc_nr_eicirqs = ARRAY_SIZE(msc_eicirqmap); | |||
385 | */ | 385 | */ |
386 | 386 | ||
387 | #define GIC_CPU_NMI GIC_MAP_TO_NMI_MSK | 387 | #define GIC_CPU_NMI GIC_MAP_TO_NMI_MSK |
388 | #define X GIC_UNUSED | ||
389 | |||
388 | static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = { | 390 | static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = { |
389 | { X, X, X, X, 0 }, | 391 | { X, X, X, X, 0 }, |
390 | { X, X, X, X, 0 }, | 392 | { X, X, X, X, 0 }, |
@@ -404,6 +406,7 @@ static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = { | |||
404 | { X, X, X, X, 0 }, | 406 | { X, X, X, X, 0 }, |
405 | /* The remainder of this table is initialised by fill_ipi_map */ | 407 | /* The remainder of this table is initialised by fill_ipi_map */ |
406 | }; | 408 | }; |
409 | #undef X | ||
407 | 410 | ||
408 | /* | 411 | /* |
409 | * GCMP needs to be detected before any SMP initialisation | 412 | * GCMP needs to be detected before any SMP initialisation |
diff --git a/arch/mips/pci/pci-rc32434.c b/arch/mips/pci/pci-rc32434.c index 71f7d27b0d4..f31218e17d3 100644 --- a/arch/mips/pci/pci-rc32434.c +++ b/arch/mips/pci/pci-rc32434.c | |||
@@ -118,7 +118,7 @@ static int __init rc32434_pcibridge_init(void) | |||
118 | if (!((pcicvalue == PCIM_H_EA) || | 118 | if (!((pcicvalue == PCIM_H_EA) || |
119 | (pcicvalue == PCIM_H_IA_FIX) || | 119 | (pcicvalue == PCIM_H_IA_FIX) || |
120 | (pcicvalue == PCIM_H_IA_RR))) { | 120 | (pcicvalue == PCIM_H_IA_RR))) { |
121 | pr_err(KERN_ERR "PCI init error!!!\n"); | 121 | pr_err("PCI init error!!!\n"); |
122 | /* Not in Host Mode, return ERROR */ | 122 | /* Not in Host Mode, return ERROR */ |
123 | return -1; | 123 | return -1; |
124 | } | 124 | } |
diff --git a/arch/mips/pnx8550/common/reset.c b/arch/mips/pnx8550/common/reset.c index fadd8744a6b..e7a12ff304b 100644 --- a/arch/mips/pnx8550/common/reset.c +++ b/arch/mips/pnx8550/common/reset.c | |||
@@ -22,29 +22,19 @@ | |||
22 | */ | 22 | */ |
23 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
24 | 24 | ||
25 | #include <asm/processor.h> | ||
25 | #include <asm/reboot.h> | 26 | #include <asm/reboot.h> |
26 | #include <glb.h> | 27 | #include <glb.h> |
27 | 28 | ||
28 | void pnx8550_machine_restart(char *command) | 29 | void pnx8550_machine_restart(char *command) |
29 | { | 30 | { |
30 | char head[] = "************* Machine restart *************"; | ||
31 | char foot[] = "*******************************************"; | ||
32 | |||
33 | printk("\n\n"); | ||
34 | printk("%s\n", head); | ||
35 | if (command != NULL) | ||
36 | printk("* %s\n", command); | ||
37 | printk("%s\n", foot); | ||
38 | |||
39 | PNX8550_RST_CTL = PNX8550_RST_DO_SW_RST; | 31 | PNX8550_RST_CTL = PNX8550_RST_DO_SW_RST; |
40 | } | 32 | } |
41 | 33 | ||
42 | void pnx8550_machine_halt(void) | 34 | void pnx8550_machine_halt(void) |
43 | { | 35 | { |
44 | printk("*** Machine halt. (Not implemented) ***\n"); | 36 | while (1) { |
45 | } | 37 | if (cpu_wait) |
46 | 38 | cpu_wait(); | |
47 | void pnx8550_machine_power_off(void) | 39 | } |
48 | { | ||
49 | printk("*** Machine power off. (Not implemented) ***\n"); | ||
50 | } | 40 | } |
diff --git a/arch/mips/pnx8550/common/setup.c b/arch/mips/pnx8550/common/setup.c index 64246c9c875..43cb3945fdb 100644 --- a/arch/mips/pnx8550/common/setup.c +++ b/arch/mips/pnx8550/common/setup.c | |||
@@ -44,7 +44,6 @@ | |||
44 | extern void __init board_setup(void); | 44 | extern void __init board_setup(void); |
45 | extern void pnx8550_machine_restart(char *); | 45 | extern void pnx8550_machine_restart(char *); |
46 | extern void pnx8550_machine_halt(void); | 46 | extern void pnx8550_machine_halt(void); |
47 | extern void pnx8550_machine_power_off(void); | ||
48 | extern struct resource ioport_resource; | 47 | extern struct resource ioport_resource; |
49 | extern struct resource iomem_resource; | 48 | extern struct resource iomem_resource; |
50 | extern char *prom_getcmdline(void); | 49 | extern char *prom_getcmdline(void); |
@@ -100,7 +99,7 @@ void __init plat_mem_setup(void) | |||
100 | 99 | ||
101 | _machine_restart = pnx8550_machine_restart; | 100 | _machine_restart = pnx8550_machine_restart; |
102 | _machine_halt = pnx8550_machine_halt; | 101 | _machine_halt = pnx8550_machine_halt; |
103 | pm_power_off = pnx8550_machine_power_off; | 102 | pm_power_off = pnx8550_machine_halt; |
104 | 103 | ||
105 | /* Clear the Global 2 Register, PCI Inta Output Enable Registers | 104 | /* Clear the Global 2 Register, PCI Inta Output Enable Registers |
106 | Bit 1:Enable DAC Powerdown | 105 | Bit 1:Enable DAC Powerdown |
diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig index 444b9f918fd..7c2a2f7f8dc 100644 --- a/arch/mn10300/Kconfig +++ b/arch/mn10300/Kconfig | |||
@@ -8,7 +8,6 @@ mainmenu "Linux Kernel Configuration" | |||
8 | config MN10300 | 8 | config MN10300 |
9 | def_bool y | 9 | def_bool y |
10 | select HAVE_OPROFILE | 10 | select HAVE_OPROFILE |
11 | select HAVE_ARCH_TRACEHOOK | ||
12 | 11 | ||
13 | config AM33 | 12 | config AM33 |
14 | def_bool y | 13 | def_bool y |
diff --git a/arch/mn10300/Kconfig.debug b/arch/mn10300/Kconfig.debug index ff80e86b9bd..ce83c74b3fd 100644 --- a/arch/mn10300/Kconfig.debug +++ b/arch/mn10300/Kconfig.debug | |||
@@ -101,7 +101,7 @@ config GDBSTUB_DEBUG_BREAKPOINT | |||
101 | 101 | ||
102 | choice | 102 | choice |
103 | prompt "GDB stub port" | 103 | prompt "GDB stub port" |
104 | default GDBSTUB_TTYSM0 | 104 | default GDBSTUB_ON_TTYSM0 |
105 | depends on GDBSTUB | 105 | depends on GDBSTUB |
106 | help | 106 | help |
107 | Select the serial port used for GDB-stub. | 107 | Select the serial port used for GDB-stub. |
diff --git a/arch/mn10300/include/asm/bitops.h b/arch/mn10300/include/asm/bitops.h index f49ac49e09a..3f50e966107 100644 --- a/arch/mn10300/include/asm/bitops.h +++ b/arch/mn10300/include/asm/bitops.h | |||
@@ -229,9 +229,9 @@ int ffs(int x) | |||
229 | #include <asm-generic/bitops/hweight.h> | 229 | #include <asm-generic/bitops/hweight.h> |
230 | 230 | ||
231 | #define ext2_set_bit_atomic(lock, nr, addr) \ | 231 | #define ext2_set_bit_atomic(lock, nr, addr) \ |
232 | test_and_set_bit((nr) ^ 0x18, (addr)) | 232 | test_and_set_bit((nr), (addr)) |
233 | #define ext2_clear_bit_atomic(lock, nr, addr) \ | 233 | #define ext2_clear_bit_atomic(lock, nr, addr) \ |
234 | test_and_clear_bit((nr) ^ 0x18, (addr)) | 234 | test_and_clear_bit((nr), (addr)) |
235 | 235 | ||
236 | #include <asm-generic/bitops/ext2-non-atomic.h> | 236 | #include <asm-generic/bitops/ext2-non-atomic.h> |
237 | #include <asm-generic/bitops/minix-le.h> | 237 | #include <asm-generic/bitops/minix-le.h> |
diff --git a/arch/mn10300/include/asm/signal.h b/arch/mn10300/include/asm/signal.h index 7e891fce237..1865d72a86f 100644 --- a/arch/mn10300/include/asm/signal.h +++ b/arch/mn10300/include/asm/signal.h | |||
@@ -78,7 +78,7 @@ typedef unsigned long sigset_t; | |||
78 | 78 | ||
79 | /* These should not be considered constants from userland. */ | 79 | /* These should not be considered constants from userland. */ |
80 | #define SIGRTMIN 32 | 80 | #define SIGRTMIN 32 |
81 | #define SIGRTMAX (_NSIG-1) | 81 | #define SIGRTMAX _NSIG |
82 | 82 | ||
83 | /* | 83 | /* |
84 | * SA_FLAGS values: | 84 | * SA_FLAGS values: |
diff --git a/arch/mn10300/kernel/mn10300-serial.c b/arch/mn10300/kernel/mn10300-serial.c index 9d49073e827..db509dd8056 100644 --- a/arch/mn10300/kernel/mn10300-serial.c +++ b/arch/mn10300/kernel/mn10300-serial.c | |||
@@ -156,17 +156,17 @@ struct mn10300_serial_port mn10300_serial_port_sif0 = { | |||
156 | ._intr = &SC0ICR, | 156 | ._intr = &SC0ICR, |
157 | ._rxb = &SC0RXB, | 157 | ._rxb = &SC0RXB, |
158 | ._txb = &SC0TXB, | 158 | ._txb = &SC0TXB, |
159 | .rx_name = "ttySM0/Rx", | 159 | .rx_name = "ttySM0:Rx", |
160 | .tx_name = "ttySM0/Tx", | 160 | .tx_name = "ttySM0:Tx", |
161 | #ifdef CONFIG_MN10300_TTYSM0_TIMER8 | 161 | #ifdef CONFIG_MN10300_TTYSM0_TIMER8 |
162 | .tm_name = "ttySM0/Timer8", | 162 | .tm_name = "ttySM0:Timer8", |
163 | ._tmxmd = &TM8MD, | 163 | ._tmxmd = &TM8MD, |
164 | ._tmxbr = &TM8BR, | 164 | ._tmxbr = &TM8BR, |
165 | ._tmicr = &TM8ICR, | 165 | ._tmicr = &TM8ICR, |
166 | .tm_irq = TM8IRQ, | 166 | .tm_irq = TM8IRQ, |
167 | .div_timer = MNSCx_DIV_TIMER_16BIT, | 167 | .div_timer = MNSCx_DIV_TIMER_16BIT, |
168 | #else /* CONFIG_MN10300_TTYSM0_TIMER2 */ | 168 | #else /* CONFIG_MN10300_TTYSM0_TIMER2 */ |
169 | .tm_name = "ttySM0/Timer2", | 169 | .tm_name = "ttySM0:Timer2", |
170 | ._tmxmd = &TM2MD, | 170 | ._tmxmd = &TM2MD, |
171 | ._tmxbr = (volatile u16 *) &TM2BR, | 171 | ._tmxbr = (volatile u16 *) &TM2BR, |
172 | ._tmicr = &TM2ICR, | 172 | ._tmicr = &TM2ICR, |
@@ -209,17 +209,17 @@ struct mn10300_serial_port mn10300_serial_port_sif1 = { | |||
209 | ._intr = &SC1ICR, | 209 | ._intr = &SC1ICR, |
210 | ._rxb = &SC1RXB, | 210 | ._rxb = &SC1RXB, |
211 | ._txb = &SC1TXB, | 211 | ._txb = &SC1TXB, |
212 | .rx_name = "ttySM1/Rx", | 212 | .rx_name = "ttySM1:Rx", |
213 | .tx_name = "ttySM1/Tx", | 213 | .tx_name = "ttySM1:Tx", |
214 | #ifdef CONFIG_MN10300_TTYSM1_TIMER9 | 214 | #ifdef CONFIG_MN10300_TTYSM1_TIMER9 |
215 | .tm_name = "ttySM1/Timer9", | 215 | .tm_name = "ttySM1:Timer9", |
216 | ._tmxmd = &TM9MD, | 216 | ._tmxmd = &TM9MD, |
217 | ._tmxbr = &TM9BR, | 217 | ._tmxbr = &TM9BR, |
218 | ._tmicr = &TM9ICR, | 218 | ._tmicr = &TM9ICR, |
219 | .tm_irq = TM9IRQ, | 219 | .tm_irq = TM9IRQ, |
220 | .div_timer = MNSCx_DIV_TIMER_16BIT, | 220 | .div_timer = MNSCx_DIV_TIMER_16BIT, |
221 | #else /* CONFIG_MN10300_TTYSM1_TIMER3 */ | 221 | #else /* CONFIG_MN10300_TTYSM1_TIMER3 */ |
222 | .tm_name = "ttySM1/Timer3", | 222 | .tm_name = "ttySM1:Timer3", |
223 | ._tmxmd = &TM3MD, | 223 | ._tmxmd = &TM3MD, |
224 | ._tmxbr = (volatile u16 *) &TM3BR, | 224 | ._tmxbr = (volatile u16 *) &TM3BR, |
225 | ._tmicr = &TM3ICR, | 225 | ._tmicr = &TM3ICR, |
@@ -260,9 +260,9 @@ struct mn10300_serial_port mn10300_serial_port_sif2 = { | |||
260 | .uart.lock = | 260 | .uart.lock = |
261 | __SPIN_LOCK_UNLOCKED(mn10300_serial_port_sif2.uart.lock), | 261 | __SPIN_LOCK_UNLOCKED(mn10300_serial_port_sif2.uart.lock), |
262 | .name = "ttySM2", | 262 | .name = "ttySM2", |
263 | .rx_name = "ttySM2/Rx", | 263 | .rx_name = "ttySM2:Rx", |
264 | .tx_name = "ttySM2/Tx", | 264 | .tx_name = "ttySM2:Tx", |
265 | .tm_name = "ttySM2/Timer10", | 265 | .tm_name = "ttySM2:Timer10", |
266 | ._iobase = &SC2CTR, | 266 | ._iobase = &SC2CTR, |
267 | ._control = &SC2CTR, | 267 | ._control = &SC2CTR, |
268 | ._status = &SC2STR, | 268 | ._status = &SC2STR, |
diff --git a/arch/mn10300/kernel/module.c b/arch/mn10300/kernel/module.c index 6aea7fd7699..196a111e2e2 100644 --- a/arch/mn10300/kernel/module.c +++ b/arch/mn10300/kernel/module.c | |||
@@ -206,7 +206,7 @@ int module_finalize(const Elf_Ehdr *hdr, | |||
206 | const Elf_Shdr *sechdrs, | 206 | const Elf_Shdr *sechdrs, |
207 | struct module *me) | 207 | struct module *me) |
208 | { | 208 | { |
209 | return module_bug_finalize(hdr, sechdrs, me); | 209 | return 0; |
210 | } | 210 | } |
211 | 211 | ||
212 | /* | 212 | /* |
@@ -214,5 +214,4 @@ int module_finalize(const Elf_Ehdr *hdr, | |||
214 | */ | 214 | */ |
215 | void module_arch_cleanup(struct module *mod) | 215 | void module_arch_cleanup(struct module *mod) |
216 | { | 216 | { |
217 | module_bug_cleanup(mod); | ||
218 | } | 217 | } |
diff --git a/arch/mn10300/kernel/signal.c b/arch/mn10300/kernel/signal.c index 717db14c2cc..d4de05ab786 100644 --- a/arch/mn10300/kernel/signal.c +++ b/arch/mn10300/kernel/signal.c | |||
@@ -65,10 +65,10 @@ asmlinkage long sys_sigaction(int sig, | |||
65 | old_sigset_t mask; | 65 | old_sigset_t mask; |
66 | if (verify_area(VERIFY_READ, act, sizeof(*act)) || | 66 | if (verify_area(VERIFY_READ, act, sizeof(*act)) || |
67 | __get_user(new_ka.sa.sa_handler, &act->sa_handler) || | 67 | __get_user(new_ka.sa.sa_handler, &act->sa_handler) || |
68 | __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) | 68 | __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) || |
69 | __get_user(new_ka.sa.sa_flags, &act->sa_flags) || | ||
70 | __get_user(mask, &act->sa_mask)) | ||
69 | return -EFAULT; | 71 | return -EFAULT; |
70 | __get_user(new_ka.sa.sa_flags, &act->sa_flags); | ||
71 | __get_user(mask, &act->sa_mask); | ||
72 | siginitset(&new_ka.sa.sa_mask, mask); | 72 | siginitset(&new_ka.sa.sa_mask, mask); |
73 | } | 73 | } |
74 | 74 | ||
@@ -77,10 +77,10 @@ asmlinkage long sys_sigaction(int sig, | |||
77 | if (!ret && oact) { | 77 | if (!ret && oact) { |
78 | if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) || | 78 | if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) || |
79 | __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || | 79 | __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || |
80 | __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) | 80 | __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) || |
81 | __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || | ||
82 | __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) | ||
81 | return -EFAULT; | 83 | return -EFAULT; |
82 | __put_user(old_ka.sa.sa_flags, &oact->sa_flags); | ||
83 | __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); | ||
84 | } | 84 | } |
85 | 85 | ||
86 | return ret; | 86 | return ret; |
@@ -102,6 +102,9 @@ static int restore_sigcontext(struct pt_regs *regs, | |||
102 | { | 102 | { |
103 | unsigned int err = 0; | 103 | unsigned int err = 0; |
104 | 104 | ||
105 | /* Always make any pending restarted system calls return -EINTR */ | ||
106 | current_thread_info()->restart_block.fn = do_no_restart_syscall; | ||
107 | |||
105 | if (is_using_fpu(current)) | 108 | if (is_using_fpu(current)) |
106 | fpu_kill_state(current); | 109 | fpu_kill_state(current); |
107 | 110 | ||
@@ -330,8 +333,6 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, | |||
330 | regs->d0 = sig; | 333 | regs->d0 = sig; |
331 | regs->d1 = (unsigned long) &frame->sc; | 334 | regs->d1 = (unsigned long) &frame->sc; |
332 | 335 | ||
333 | set_fs(USER_DS); | ||
334 | |||
335 | /* the tracer may want to single-step inside the handler */ | 336 | /* the tracer may want to single-step inside the handler */ |
336 | if (test_thread_flag(TIF_SINGLESTEP)) | 337 | if (test_thread_flag(TIF_SINGLESTEP)) |
337 | ptrace_notify(SIGTRAP); | 338 | ptrace_notify(SIGTRAP); |
@@ -345,7 +346,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, | |||
345 | return 0; | 346 | return 0; |
346 | 347 | ||
347 | give_sigsegv: | 348 | give_sigsegv: |
348 | force_sig(SIGSEGV, current); | 349 | force_sigsegv(sig, current); |
349 | return -EFAULT; | 350 | return -EFAULT; |
350 | } | 351 | } |
351 | 352 | ||
@@ -413,8 +414,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
413 | regs->d0 = sig; | 414 | regs->d0 = sig; |
414 | regs->d1 = (long) &frame->info; | 415 | regs->d1 = (long) &frame->info; |
415 | 416 | ||
416 | set_fs(USER_DS); | ||
417 | |||
418 | /* the tracer may want to single-step inside the handler */ | 417 | /* the tracer may want to single-step inside the handler */ |
419 | if (test_thread_flag(TIF_SINGLESTEP)) | 418 | if (test_thread_flag(TIF_SINGLESTEP)) |
420 | ptrace_notify(SIGTRAP); | 419 | ptrace_notify(SIGTRAP); |
@@ -428,10 +427,16 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
428 | return 0; | 427 | return 0; |
429 | 428 | ||
430 | give_sigsegv: | 429 | give_sigsegv: |
431 | force_sig(SIGSEGV, current); | 430 | force_sigsegv(sig, current); |
432 | return -EFAULT; | 431 | return -EFAULT; |
433 | } | 432 | } |
434 | 433 | ||
434 | static inline void stepback(struct pt_regs *regs) | ||
435 | { | ||
436 | regs->pc -= 2; | ||
437 | regs->orig_d0 = -1; | ||
438 | } | ||
439 | |||
435 | /* | 440 | /* |
436 | * handle the actual delivery of a signal to userspace | 441 | * handle the actual delivery of a signal to userspace |
437 | */ | 442 | */ |
@@ -459,7 +464,7 @@ static int handle_signal(int sig, | |||
459 | /* fallthrough */ | 464 | /* fallthrough */ |
460 | case -ERESTARTNOINTR: | 465 | case -ERESTARTNOINTR: |
461 | regs->d0 = regs->orig_d0; | 466 | regs->d0 = regs->orig_d0; |
462 | regs->pc -= 2; | 467 | stepback(regs); |
463 | } | 468 | } |
464 | } | 469 | } |
465 | 470 | ||
@@ -527,12 +532,12 @@ static void do_signal(struct pt_regs *regs) | |||
527 | case -ERESTARTSYS: | 532 | case -ERESTARTSYS: |
528 | case -ERESTARTNOINTR: | 533 | case -ERESTARTNOINTR: |
529 | regs->d0 = regs->orig_d0; | 534 | regs->d0 = regs->orig_d0; |
530 | regs->pc -= 2; | 535 | stepback(regs); |
531 | break; | 536 | break; |
532 | 537 | ||
533 | case -ERESTART_RESTARTBLOCK: | 538 | case -ERESTART_RESTARTBLOCK: |
534 | regs->d0 = __NR_restart_syscall; | 539 | regs->d0 = __NR_restart_syscall; |
535 | regs->pc -= 2; | 540 | stepback(regs); |
536 | break; | 541 | break; |
537 | } | 542 | } |
538 | } | 543 | } |
diff --git a/arch/mn10300/mm/Makefile b/arch/mn10300/mm/Makefile index 28b9d983db0..1557277fbc5 100644 --- a/arch/mn10300/mm/Makefile +++ b/arch/mn10300/mm/Makefile | |||
@@ -2,13 +2,11 @@ | |||
2 | # Makefile for the MN10300-specific memory management code | 2 | # Makefile for the MN10300-specific memory management code |
3 | # | 3 | # |
4 | 4 | ||
5 | cacheflush-y := cache.o cache-mn10300.o | ||
6 | cacheflush-$(CONFIG_MN10300_CACHE_WBACK) += cache-flush-mn10300.o | ||
7 | |||
8 | cacheflush-$(CONFIG_MN10300_CACHE_DISABLED) := cache-disabled.o | ||
9 | |||
5 | obj-y := \ | 10 | obj-y := \ |
6 | init.o fault.o pgtable.o extable.o tlb-mn10300.o mmu-context.o \ | 11 | init.o fault.o pgtable.o extable.o tlb-mn10300.o mmu-context.o \ |
7 | misalignment.o dma-alloc.o | 12 | misalignment.o dma-alloc.o $(cacheflush-y) |
8 | |||
9 | ifneq ($(CONFIG_MN10300_CACHE_DISABLED),y) | ||
10 | obj-y += cache.o cache-mn10300.o | ||
11 | ifeq ($(CONFIG_MN10300_CACHE_WBACK),y) | ||
12 | obj-y += cache-flush-mn10300.o | ||
13 | endif | ||
14 | endif | ||
diff --git a/arch/mn10300/mm/cache-disabled.c b/arch/mn10300/mm/cache-disabled.c new file mode 100644 index 00000000000..f669ea42aba --- /dev/null +++ b/arch/mn10300/mm/cache-disabled.c | |||
@@ -0,0 +1,21 @@ | |||
1 | /* Handle the cache being disabled | ||
2 | * | ||
3 | * Copyright (C) 2010 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public Licence | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the Licence, or (at your option) any later version. | ||
10 | */ | ||
11 | #include <linux/mm.h> | ||
12 | |||
13 | /* | ||
14 | * allow userspace to flush the instruction cache | ||
15 | */ | ||
16 | asmlinkage long sys_cacheflush(unsigned long start, unsigned long end) | ||
17 | { | ||
18 | if (end < start) | ||
19 | return -EINVAL; | ||
20 | return 0; | ||
21 | } | ||
diff --git a/arch/mn10300/mm/cache.c b/arch/mn10300/mm/cache.c index 1b76719ec1c..9261217e8d2 100644 --- a/arch/mn10300/mm/cache.c +++ b/arch/mn10300/mm/cache.c | |||
@@ -54,13 +54,30 @@ EXPORT_SYMBOL(flush_icache_page); | |||
54 | void flush_icache_range(unsigned long start, unsigned long end) | 54 | void flush_icache_range(unsigned long start, unsigned long end) |
55 | { | 55 | { |
56 | #ifdef CONFIG_MN10300_CACHE_WBACK | 56 | #ifdef CONFIG_MN10300_CACHE_WBACK |
57 | unsigned long addr, size, off; | 57 | unsigned long addr, size, base, off; |
58 | struct page *page; | 58 | struct page *page; |
59 | pgd_t *pgd; | 59 | pgd_t *pgd; |
60 | pud_t *pud; | 60 | pud_t *pud; |
61 | pmd_t *pmd; | 61 | pmd_t *pmd; |
62 | pte_t *ppte, pte; | 62 | pte_t *ppte, pte; |
63 | 63 | ||
64 | if (end > 0x80000000UL) { | ||
65 | /* addresses above 0xa0000000 do not go through the cache */ | ||
66 | if (end > 0xa0000000UL) { | ||
67 | end = 0xa0000000UL; | ||
68 | if (start >= end) | ||
69 | return; | ||
70 | } | ||
71 | |||
72 | /* kernel addresses between 0x80000000 and 0x9fffffff do not | ||
73 | * require page tables, so we just map such addresses directly */ | ||
74 | base = (start >= 0x80000000UL) ? start : 0x80000000UL; | ||
75 | mn10300_dcache_flush_range(base, end); | ||
76 | if (base == start) | ||
77 | goto invalidate; | ||
78 | end = base; | ||
79 | } | ||
80 | |||
64 | for (; start < end; start += size) { | 81 | for (; start < end; start += size) { |
65 | /* work out how much of the page to flush */ | 82 | /* work out how much of the page to flush */ |
66 | off = start & (PAGE_SIZE - 1); | 83 | off = start & (PAGE_SIZE - 1); |
@@ -104,6 +121,7 @@ void flush_icache_range(unsigned long start, unsigned long end) | |||
104 | } | 121 | } |
105 | #endif | 122 | #endif |
106 | 123 | ||
124 | invalidate: | ||
107 | mn10300_icache_inv(); | 125 | mn10300_icache_inv(); |
108 | } | 126 | } |
109 | EXPORT_SYMBOL(flush_icache_range); | 127 | EXPORT_SYMBOL(flush_icache_range); |
diff --git a/arch/mn10300/mm/dma-alloc.c b/arch/mn10300/mm/dma-alloc.c index 4e34880bea0..159acb02cfd 100644 --- a/arch/mn10300/mm/dma-alloc.c +++ b/arch/mn10300/mm/dma-alloc.c | |||
@@ -25,7 +25,8 @@ void *dma_alloc_coherent(struct device *dev, size_t size, | |||
25 | unsigned long addr; | 25 | unsigned long addr; |
26 | void *ret; | 26 | void *ret; |
27 | 27 | ||
28 | printk("dma_alloc_coherent(%s,%zu,,%x)\n", dev_name(dev), size, gfp); | 28 | pr_debug("dma_alloc_coherent(%s,%zu,%x)\n", |
29 | dev ? dev_name(dev) : "?", size, gfp); | ||
29 | 30 | ||
30 | if (0xbe000000 - pci_sram_allocated >= size) { | 31 | if (0xbe000000 - pci_sram_allocated >= size) { |
31 | size = (size + 255) & ~255; | 32 | size = (size + 255) & ~255; |
diff --git a/arch/parisc/include/asm/compat.h b/arch/parisc/include/asm/compat.h index 02b77baa5da..efa0b60c63f 100644 --- a/arch/parisc/include/asm/compat.h +++ b/arch/parisc/include/asm/compat.h | |||
@@ -147,7 +147,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) | |||
147 | return (u32)(unsigned long)uptr; | 147 | return (u32)(unsigned long)uptr; |
148 | } | 148 | } |
149 | 149 | ||
150 | static __inline__ void __user *compat_alloc_user_space(long len) | 150 | static __inline__ void __user *arch_compat_alloc_user_space(long len) |
151 | { | 151 | { |
152 | struct pt_regs *regs = ¤t->thread.regs; | 152 | struct pt_regs *regs = ¤t->thread.regs; |
153 | return (void __user *)regs->gr[30]; | 153 | return (void __user *)regs->gr[30]; |
diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c index 159a2b81e90..6e81bb596e5 100644 --- a/arch/parisc/kernel/module.c +++ b/arch/parisc/kernel/module.c | |||
@@ -941,11 +941,10 @@ int module_finalize(const Elf_Ehdr *hdr, | |||
941 | nsyms = newptr - (Elf_Sym *)symhdr->sh_addr; | 941 | nsyms = newptr - (Elf_Sym *)symhdr->sh_addr; |
942 | DEBUGP("NEW num_symtab %lu\n", nsyms); | 942 | DEBUGP("NEW num_symtab %lu\n", nsyms); |
943 | symhdr->sh_size = nsyms * sizeof(Elf_Sym); | 943 | symhdr->sh_size = nsyms * sizeof(Elf_Sym); |
944 | return module_bug_finalize(hdr, sechdrs, me); | 944 | return 0; |
945 | } | 945 | } |
946 | 946 | ||
947 | void module_arch_cleanup(struct module *mod) | 947 | void module_arch_cleanup(struct module *mod) |
948 | { | 948 | { |
949 | deregister_unwind_table(mod); | 949 | deregister_unwind_table(mod); |
950 | module_bug_cleanup(mod); | ||
951 | } | 950 | } |
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index e3ea151c959..b7212b619c5 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile | |||
@@ -164,7 +164,7 @@ drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ | |||
164 | all: zImage | 164 | all: zImage |
165 | 165 | ||
166 | # With make 3.82 we cannot mix normal and wildcard targets | 166 | # With make 3.82 we cannot mix normal and wildcard targets |
167 | BOOT_TARGETS1 := zImage zImage.initrd uImaged | 167 | BOOT_TARGETS1 := zImage zImage.initrd uImage |
168 | BOOT_TARGETS2 := zImage% dtbImage% treeImage.% cuImage.% simpleImage.% | 168 | BOOT_TARGETS2 := zImage% dtbImage% treeImage.% cuImage.% simpleImage.% |
169 | 169 | ||
170 | PHONY += $(BOOT_TARGETS1) $(BOOT_TARGETS2) | 170 | PHONY += $(BOOT_TARGETS1) $(BOOT_TARGETS2) |
diff --git a/arch/powerpc/boot/dts/canyonlands.dts b/arch/powerpc/boot/dts/canyonlands.dts index 5806ef0b860..a3037039625 100644 --- a/arch/powerpc/boot/dts/canyonlands.dts +++ b/arch/powerpc/boot/dts/canyonlands.dts | |||
@@ -163,6 +163,14 @@ | |||
163 | interrupts = <0x1e 4>; | 163 | interrupts = <0x1e 4>; |
164 | }; | 164 | }; |
165 | 165 | ||
166 | SATA0: sata@bffd1000 { | ||
167 | compatible = "amcc,sata-460ex"; | ||
168 | reg = <4 0xbffd1000 0x800 4 0xbffd0800 0x400>; | ||
169 | interrupt-parent = <&UIC3>; | ||
170 | interrupts = <0x0 0x4 /* SATA */ | ||
171 | 0x5 0x4>; /* AHBDMA */ | ||
172 | }; | ||
173 | |||
166 | POB0: opb { | 174 | POB0: opb { |
167 | compatible = "ibm,opb-460ex", "ibm,opb"; | 175 | compatible = "ibm,opb-460ex", "ibm,opb"; |
168 | #address-cells = <1>; | 176 | #address-cells = <1>; |
diff --git a/arch/powerpc/include/asm/compat.h b/arch/powerpc/include/asm/compat.h index 396d21a8005..a11d4eac4f9 100644 --- a/arch/powerpc/include/asm/compat.h +++ b/arch/powerpc/include/asm/compat.h | |||
@@ -134,7 +134,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) | |||
134 | return (u32)(unsigned long)uptr; | 134 | return (u32)(unsigned long)uptr; |
135 | } | 135 | } |
136 | 136 | ||
137 | static inline void __user *compat_alloc_user_space(long len) | 137 | static inline void __user *arch_compat_alloc_user_space(long len) |
138 | { | 138 | { |
139 | struct pt_regs *regs = current->thread.regs; | 139 | struct pt_regs *regs = current->thread.regs; |
140 | unsigned long usp = regs->gpr[1]; | 140 | unsigned long usp = regs->gpr[1]; |
diff --git a/arch/powerpc/include/asm/fsldma.h b/arch/powerpc/include/asm/fsldma.h index a67aeed17d4..debc5ed96d6 100644 --- a/arch/powerpc/include/asm/fsldma.h +++ b/arch/powerpc/include/asm/fsldma.h | |||
@@ -11,6 +11,7 @@ | |||
11 | #ifndef __ARCH_POWERPC_ASM_FSLDMA_H__ | 11 | #ifndef __ARCH_POWERPC_ASM_FSLDMA_H__ |
12 | #define __ARCH_POWERPC_ASM_FSLDMA_H__ | 12 | #define __ARCH_POWERPC_ASM_FSLDMA_H__ |
13 | 13 | ||
14 | #include <linux/slab.h> | ||
14 | #include <linux/dmaengine.h> | 15 | #include <linux/dmaengine.h> |
15 | 16 | ||
16 | /* | 17 | /* |
diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h index 0e398cfee2c..acac35d5b38 100644 --- a/arch/powerpc/include/asm/mmu-hash64.h +++ b/arch/powerpc/include/asm/mmu-hash64.h | |||
@@ -433,7 +433,7 @@ typedef struct { | |||
433 | * with. However gcc is not clever enough to compute the | 433 | * with. However gcc is not clever enough to compute the |
434 | * modulus (2^n-1) without a second multiply. | 434 | * modulus (2^n-1) without a second multiply. |
435 | */ | 435 | */ |
436 | #define vsid_scrample(protovsid, size) \ | 436 | #define vsid_scramble(protovsid, size) \ |
437 | ((((protovsid) * VSID_MULTIPLIER_##size) % VSID_MODULUS_##size)) | 437 | ((((protovsid) * VSID_MULTIPLIER_##size) % VSID_MODULUS_##size)) |
438 | 438 | ||
439 | #else /* 1 */ | 439 | #else /* 1 */ |
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index d8be016d2ed..ff0005eec7d 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h | |||
@@ -951,7 +951,14 @@ | |||
951 | #ifdef CONFIG_PPC64 | 951 | #ifdef CONFIG_PPC64 |
952 | 952 | ||
953 | extern void ppc64_runlatch_on(void); | 953 | extern void ppc64_runlatch_on(void); |
954 | extern void ppc64_runlatch_off(void); | 954 | extern void __ppc64_runlatch_off(void); |
955 | |||
956 | #define ppc64_runlatch_off() \ | ||
957 | do { \ | ||
958 | if (cpu_has_feature(CPU_FTR_CTRL) && \ | ||
959 | test_thread_flag(TIF_RUNLATCH)) \ | ||
960 | __ppc64_runlatch_off(); \ | ||
961 | } while (0) | ||
955 | 962 | ||
956 | extern unsigned long scom970_read(unsigned int address); | 963 | extern unsigned long scom970_read(unsigned int address); |
957 | extern void scom970_write(unsigned int address, unsigned long value); | 964 | extern void scom970_write(unsigned int address, unsigned long value); |
diff --git a/arch/powerpc/include/asm/rwsem.h b/arch/powerpc/include/asm/rwsem.h index 24cd9281ec3..8447d89fbe7 100644 --- a/arch/powerpc/include/asm/rwsem.h +++ b/arch/powerpc/include/asm/rwsem.h | |||
@@ -21,15 +21,20 @@ | |||
21 | /* | 21 | /* |
22 | * the semaphore definition | 22 | * the semaphore definition |
23 | */ | 23 | */ |
24 | struct rw_semaphore { | 24 | #ifdef CONFIG_PPC64 |
25 | /* XXX this should be able to be an atomic_t -- paulus */ | 25 | # define RWSEM_ACTIVE_MASK 0xffffffffL |
26 | signed int count; | 26 | #else |
27 | #define RWSEM_UNLOCKED_VALUE 0x00000000 | 27 | # define RWSEM_ACTIVE_MASK 0x0000ffffL |
28 | #define RWSEM_ACTIVE_BIAS 0x00000001 | 28 | #endif |
29 | #define RWSEM_ACTIVE_MASK 0x0000ffff | 29 | |
30 | #define RWSEM_WAITING_BIAS (-0x00010000) | 30 | #define RWSEM_UNLOCKED_VALUE 0x00000000L |
31 | #define RWSEM_ACTIVE_BIAS 0x00000001L | ||
32 | #define RWSEM_WAITING_BIAS (-RWSEM_ACTIVE_MASK-1) | ||
31 | #define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS | 33 | #define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS |
32 | #define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) | 34 | #define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) |
35 | |||
36 | struct rw_semaphore { | ||
37 | long count; | ||
33 | spinlock_t wait_lock; | 38 | spinlock_t wait_lock; |
34 | struct list_head wait_list; | 39 | struct list_head wait_list; |
35 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 40 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
@@ -43,9 +48,13 @@ struct rw_semaphore { | |||
43 | # define __RWSEM_DEP_MAP_INIT(lockname) | 48 | # define __RWSEM_DEP_MAP_INIT(lockname) |
44 | #endif | 49 | #endif |
45 | 50 | ||
46 | #define __RWSEM_INITIALIZER(name) \ | 51 | #define __RWSEM_INITIALIZER(name) \ |
47 | { RWSEM_UNLOCKED_VALUE, __SPIN_LOCK_UNLOCKED((name).wait_lock), \ | 52 | { \ |
48 | LIST_HEAD_INIT((name).wait_list) __RWSEM_DEP_MAP_INIT(name) } | 53 | RWSEM_UNLOCKED_VALUE, \ |
54 | __SPIN_LOCK_UNLOCKED((name).wait_lock), \ | ||
55 | LIST_HEAD_INIT((name).wait_list) \ | ||
56 | __RWSEM_DEP_MAP_INIT(name) \ | ||
57 | } | ||
49 | 58 | ||
50 | #define DECLARE_RWSEM(name) \ | 59 | #define DECLARE_RWSEM(name) \ |
51 | struct rw_semaphore name = __RWSEM_INITIALIZER(name) | 60 | struct rw_semaphore name = __RWSEM_INITIALIZER(name) |
@@ -70,13 +79,13 @@ extern void __init_rwsem(struct rw_semaphore *sem, const char *name, | |||
70 | */ | 79 | */ |
71 | static inline void __down_read(struct rw_semaphore *sem) | 80 | static inline void __down_read(struct rw_semaphore *sem) |
72 | { | 81 | { |
73 | if (unlikely(atomic_inc_return((atomic_t *)(&sem->count)) <= 0)) | 82 | if (unlikely(atomic_long_inc_return((atomic_long_t *)&sem->count) <= 0)) |
74 | rwsem_down_read_failed(sem); | 83 | rwsem_down_read_failed(sem); |
75 | } | 84 | } |
76 | 85 | ||
77 | static inline int __down_read_trylock(struct rw_semaphore *sem) | 86 | static inline int __down_read_trylock(struct rw_semaphore *sem) |
78 | { | 87 | { |
79 | int tmp; | 88 | long tmp; |
80 | 89 | ||
81 | while ((tmp = sem->count) >= 0) { | 90 | while ((tmp = sem->count) >= 0) { |
82 | if (tmp == cmpxchg(&sem->count, tmp, | 91 | if (tmp == cmpxchg(&sem->count, tmp, |
@@ -92,10 +101,10 @@ static inline int __down_read_trylock(struct rw_semaphore *sem) | |||
92 | */ | 101 | */ |
93 | static inline void __down_write_nested(struct rw_semaphore *sem, int subclass) | 102 | static inline void __down_write_nested(struct rw_semaphore *sem, int subclass) |
94 | { | 103 | { |
95 | int tmp; | 104 | long tmp; |
96 | 105 | ||
97 | tmp = atomic_add_return(RWSEM_ACTIVE_WRITE_BIAS, | 106 | tmp = atomic_long_add_return(RWSEM_ACTIVE_WRITE_BIAS, |
98 | (atomic_t *)(&sem->count)); | 107 | (atomic_long_t *)&sem->count); |
99 | if (unlikely(tmp != RWSEM_ACTIVE_WRITE_BIAS)) | 108 | if (unlikely(tmp != RWSEM_ACTIVE_WRITE_BIAS)) |
100 | rwsem_down_write_failed(sem); | 109 | rwsem_down_write_failed(sem); |
101 | } | 110 | } |
@@ -107,7 +116,7 @@ static inline void __down_write(struct rw_semaphore *sem) | |||
107 | 116 | ||
108 | static inline int __down_write_trylock(struct rw_semaphore *sem) | 117 | static inline int __down_write_trylock(struct rw_semaphore *sem) |
109 | { | 118 | { |
110 | int tmp; | 119 | long tmp; |
111 | 120 | ||
112 | tmp = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE, | 121 | tmp = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE, |
113 | RWSEM_ACTIVE_WRITE_BIAS); | 122 | RWSEM_ACTIVE_WRITE_BIAS); |
@@ -119,9 +128,9 @@ static inline int __down_write_trylock(struct rw_semaphore *sem) | |||
119 | */ | 128 | */ |
120 | static inline void __up_read(struct rw_semaphore *sem) | 129 | static inline void __up_read(struct rw_semaphore *sem) |
121 | { | 130 | { |
122 | int tmp; | 131 | long tmp; |
123 | 132 | ||
124 | tmp = atomic_dec_return((atomic_t *)(&sem->count)); | 133 | tmp = atomic_long_dec_return((atomic_long_t *)&sem->count); |
125 | if (unlikely(tmp < -1 && (tmp & RWSEM_ACTIVE_MASK) == 0)) | 134 | if (unlikely(tmp < -1 && (tmp & RWSEM_ACTIVE_MASK) == 0)) |
126 | rwsem_wake(sem); | 135 | rwsem_wake(sem); |
127 | } | 136 | } |
@@ -131,17 +140,17 @@ static inline void __up_read(struct rw_semaphore *sem) | |||
131 | */ | 140 | */ |
132 | static inline void __up_write(struct rw_semaphore *sem) | 141 | static inline void __up_write(struct rw_semaphore *sem) |
133 | { | 142 | { |
134 | if (unlikely(atomic_sub_return(RWSEM_ACTIVE_WRITE_BIAS, | 143 | if (unlikely(atomic_long_sub_return(RWSEM_ACTIVE_WRITE_BIAS, |
135 | (atomic_t *)(&sem->count)) < 0)) | 144 | (atomic_long_t *)&sem->count) < 0)) |
136 | rwsem_wake(sem); | 145 | rwsem_wake(sem); |
137 | } | 146 | } |
138 | 147 | ||
139 | /* | 148 | /* |
140 | * implement atomic add functionality | 149 | * implement atomic add functionality |
141 | */ | 150 | */ |
142 | static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem) | 151 | static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem) |
143 | { | 152 | { |
144 | atomic_add(delta, (atomic_t *)(&sem->count)); | 153 | atomic_long_add(delta, (atomic_long_t *)&sem->count); |
145 | } | 154 | } |
146 | 155 | ||
147 | /* | 156 | /* |
@@ -149,9 +158,10 @@ static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem) | |||
149 | */ | 158 | */ |
150 | static inline void __downgrade_write(struct rw_semaphore *sem) | 159 | static inline void __downgrade_write(struct rw_semaphore *sem) |
151 | { | 160 | { |
152 | int tmp; | 161 | long tmp; |
153 | 162 | ||
154 | tmp = atomic_add_return(-RWSEM_WAITING_BIAS, (atomic_t *)(&sem->count)); | 163 | tmp = atomic_long_add_return(-RWSEM_WAITING_BIAS, |
164 | (atomic_long_t *)&sem->count); | ||
155 | if (tmp < 0) | 165 | if (tmp < 0) |
156 | rwsem_downgrade_wake(sem); | 166 | rwsem_downgrade_wake(sem); |
157 | } | 167 | } |
@@ -159,14 +169,14 @@ static inline void __downgrade_write(struct rw_semaphore *sem) | |||
159 | /* | 169 | /* |
160 | * implement exchange and add functionality | 170 | * implement exchange and add functionality |
161 | */ | 171 | */ |
162 | static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem) | 172 | static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem) |
163 | { | 173 | { |
164 | return atomic_add_return(delta, (atomic_t *)(&sem->count)); | 174 | return atomic_long_add_return(delta, (atomic_long_t *)&sem->count); |
165 | } | 175 | } |
166 | 176 | ||
167 | static inline int rwsem_is_locked(struct rw_semaphore *sem) | 177 | static inline int rwsem_is_locked(struct rw_semaphore *sem) |
168 | { | 178 | { |
169 | return (sem->count != 0); | 179 | return sem->count != 0; |
170 | } | 180 | } |
171 | 181 | ||
172 | #endif /* __KERNEL__ */ | 182 | #endif /* __KERNEL__ */ |
diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h index a5ee345b6a5..3d212669a13 100644 --- a/arch/powerpc/include/asm/systbl.h +++ b/arch/powerpc/include/asm/systbl.h | |||
@@ -326,3 +326,6 @@ SYSCALL_SPU(perf_event_open) | |||
326 | COMPAT_SYS_SPU(preadv) | 326 | COMPAT_SYS_SPU(preadv) |
327 | COMPAT_SYS_SPU(pwritev) | 327 | COMPAT_SYS_SPU(pwritev) |
328 | COMPAT_SYS(rt_tgsigqueueinfo) | 328 | COMPAT_SYS(rt_tgsigqueueinfo) |
329 | SYSCALL(fanotify_init) | ||
330 | COMPAT_SYS(fanotify_mark) | ||
331 | SYSCALL_SPU(prlimit64) | ||
diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h index f0a10266e7f..597e6f9d094 100644 --- a/arch/powerpc/include/asm/unistd.h +++ b/arch/powerpc/include/asm/unistd.h | |||
@@ -345,10 +345,13 @@ | |||
345 | #define __NR_preadv 320 | 345 | #define __NR_preadv 320 |
346 | #define __NR_pwritev 321 | 346 | #define __NR_pwritev 321 |
347 | #define __NR_rt_tgsigqueueinfo 322 | 347 | #define __NR_rt_tgsigqueueinfo 322 |
348 | #define __NR_fanotify_init 323 | ||
349 | #define __NR_fanotify_mark 324 | ||
350 | #define __NR_prlimit64 325 | ||
348 | 351 | ||
349 | #ifdef __KERNEL__ | 352 | #ifdef __KERNEL__ |
350 | 353 | ||
351 | #define __NR_syscalls 323 | 354 | #define __NR_syscalls 326 |
352 | 355 | ||
353 | #define __NR__exit __NR_exit | 356 | #define __NR__exit __NR_exit |
354 | #define NR_syscalls __NR_syscalls | 357 | #define NR_syscalls __NR_syscalls |
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 65e2b4e10f9..1f9123f412e 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c | |||
@@ -1826,7 +1826,6 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1826 | .cpu_features = CPU_FTRS_47X, | 1826 | .cpu_features = CPU_FTRS_47X, |
1827 | .cpu_user_features = COMMON_USER_BOOKE | | 1827 | .cpu_user_features = COMMON_USER_BOOKE | |
1828 | PPC_FEATURE_HAS_FPU, | 1828 | PPC_FEATURE_HAS_FPU, |
1829 | .cpu_user_features = COMMON_USER_BOOKE, | ||
1830 | .mmu_features = MMU_FTR_TYPE_47x | | 1829 | .mmu_features = MMU_FTR_TYPE_47x | |
1831 | MMU_FTR_USE_TLBIVAX_BCAST | MMU_FTR_LOCK_BCAST_INVAL, | 1830 | MMU_FTR_USE_TLBIVAX_BCAST | MMU_FTR_LOCK_BCAST_INVAL, |
1832 | .icache_bsize = 32, | 1831 | .icache_bsize = 32, |
diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c index 417f7b05a9c..4457382f866 100644 --- a/arch/powerpc/kernel/crash.c +++ b/arch/powerpc/kernel/crash.c | |||
@@ -402,6 +402,18 @@ void default_machine_crash_shutdown(struct pt_regs *regs) | |||
402 | */ | 402 | */ |
403 | hard_irq_disable(); | 403 | hard_irq_disable(); |
404 | 404 | ||
405 | /* | ||
406 | * Make a note of crashing cpu. Will be used in machine_kexec | ||
407 | * such that another IPI will not be sent. | ||
408 | */ | ||
409 | crashing_cpu = smp_processor_id(); | ||
410 | crash_save_cpu(regs, crashing_cpu); | ||
411 | crash_kexec_prepare_cpus(crashing_cpu); | ||
412 | cpu_set(crashing_cpu, cpus_in_crash); | ||
413 | #if defined(CONFIG_PPC_STD_MMU_64) && defined(CONFIG_SMP) | ||
414 | crash_kexec_wait_realmode(crashing_cpu); | ||
415 | #endif | ||
416 | |||
405 | for_each_irq(i) { | 417 | for_each_irq(i) { |
406 | struct irq_desc *desc = irq_to_desc(i); | 418 | struct irq_desc *desc = irq_to_desc(i); |
407 | 419 | ||
@@ -438,18 +450,8 @@ void default_machine_crash_shutdown(struct pt_regs *regs) | |||
438 | crash_shutdown_cpu = -1; | 450 | crash_shutdown_cpu = -1; |
439 | __debugger_fault_handler = old_handler; | 451 | __debugger_fault_handler = old_handler; |
440 | 452 | ||
441 | /* | ||
442 | * Make a note of crashing cpu. Will be used in machine_kexec | ||
443 | * such that another IPI will not be sent. | ||
444 | */ | ||
445 | crashing_cpu = smp_processor_id(); | ||
446 | crash_save_cpu(regs, crashing_cpu); | ||
447 | crash_kexec_prepare_cpus(crashing_cpu); | ||
448 | cpu_set(crashing_cpu, cpus_in_crash); | ||
449 | crash_kexec_stop_spus(); | 453 | crash_kexec_stop_spus(); |
450 | #if defined(CONFIG_PPC_STD_MMU_64) && defined(CONFIG_SMP) | 454 | |
451 | crash_kexec_wait_realmode(crashing_cpu); | ||
452 | #endif | ||
453 | if (ppc_md.kexec_cpu_down) | 455 | if (ppc_md.kexec_cpu_down) |
454 | ppc_md.kexec_cpu_down(1, 0); | 456 | ppc_md.kexec_cpu_down(1, 0); |
455 | } | 457 | } |
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S index 5ab484ef06a..562305b40a8 100644 --- a/arch/powerpc/kernel/head_44x.S +++ b/arch/powerpc/kernel/head_44x.S | |||
@@ -113,6 +113,10 @@ _ENTRY(_start); | |||
113 | stw r5, 0(r4) /* Save abatron_pteptrs at a fixed location */ | 113 | stw r5, 0(r4) /* Save abatron_pteptrs at a fixed location */ |
114 | stw r6, 0(r5) | 114 | stw r6, 0(r5) |
115 | 115 | ||
116 | /* Clear the Machine Check Syndrome Register */ | ||
117 | li r0,0 | ||
118 | mtspr SPRN_MCSR,r0 | ||
119 | |||
116 | /* Let's move on */ | 120 | /* Let's move on */ |
117 | lis r4,start_kernel@h | 121 | lis r4,start_kernel@h |
118 | ori r4,r4,start_kernel@l | 122 | ori r4,r4,start_kernel@l |
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 844a44b6447..c571cd3c145 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S | |||
@@ -572,15 +572,21 @@ __secondary_start: | |||
572 | /* Set thread priority to MEDIUM */ | 572 | /* Set thread priority to MEDIUM */ |
573 | HMT_MEDIUM | 573 | HMT_MEDIUM |
574 | 574 | ||
575 | /* Do early setup for that CPU (stab, slb, hash table pointer) */ | ||
576 | bl .early_setup_secondary | ||
577 | |||
578 | /* Initialize the kernel stack. Just a repeat for iSeries. */ | 575 | /* Initialize the kernel stack. Just a repeat for iSeries. */ |
579 | LOAD_REG_ADDR(r3, current_set) | 576 | LOAD_REG_ADDR(r3, current_set) |
580 | sldi r28,r24,3 /* get current_set[cpu#] */ | 577 | sldi r28,r24,3 /* get current_set[cpu#] */ |
581 | ldx r1,r3,r28 | 578 | ldx r14,r3,r28 |
582 | addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD | 579 | addi r14,r14,THREAD_SIZE-STACK_FRAME_OVERHEAD |
583 | std r1,PACAKSAVE(r13) | 580 | std r14,PACAKSAVE(r13) |
581 | |||
582 | /* Do early setup for that CPU (stab, slb, hash table pointer) */ | ||
583 | bl .early_setup_secondary | ||
584 | |||
585 | /* | ||
586 | * setup the new stack pointer, but *don't* use this until | ||
587 | * translation is on. | ||
588 | */ | ||
589 | mr r1, r14 | ||
584 | 590 | ||
585 | /* Clear backchain so we get nice backtraces */ | 591 | /* Clear backchain so we get nice backtraces */ |
586 | li r7,0 | 592 | li r7,0 |
diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c index 049dda60e47..39a2baa6ad5 100644 --- a/arch/powerpc/kernel/idle.c +++ b/arch/powerpc/kernel/idle.c | |||
@@ -94,9 +94,9 @@ void cpu_idle(void) | |||
94 | HMT_medium(); | 94 | HMT_medium(); |
95 | ppc64_runlatch_on(); | 95 | ppc64_runlatch_on(); |
96 | tick_nohz_restart_sched_tick(); | 96 | tick_nohz_restart_sched_tick(); |
97 | preempt_enable_no_resched(); | ||
97 | if (cpu_should_die()) | 98 | if (cpu_should_die()) |
98 | cpu_die(); | 99 | cpu_die(); |
99 | preempt_enable_no_resched(); | ||
100 | schedule(); | 100 | schedule(); |
101 | preempt_disable(); | 101 | preempt_disable(); |
102 | } | 102 | } |
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index d3ce67cf03b..4a65386995d 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
@@ -67,6 +67,7 @@ | |||
67 | #include <asm/machdep.h> | 67 | #include <asm/machdep.h> |
68 | #include <asm/udbg.h> | 68 | #include <asm/udbg.h> |
69 | #include <asm/dbell.h> | 69 | #include <asm/dbell.h> |
70 | #include <asm/smp.h> | ||
70 | 71 | ||
71 | #ifdef CONFIG_PPC64 | 72 | #ifdef CONFIG_PPC64 |
72 | #include <asm/paca.h> | 73 | #include <asm/paca.h> |
@@ -446,22 +447,23 @@ struct thread_info *mcheckirq_ctx[NR_CPUS] __read_mostly; | |||
446 | void exc_lvl_ctx_init(void) | 447 | void exc_lvl_ctx_init(void) |
447 | { | 448 | { |
448 | struct thread_info *tp; | 449 | struct thread_info *tp; |
449 | int i; | 450 | int i, hw_cpu; |
450 | 451 | ||
451 | for_each_possible_cpu(i) { | 452 | for_each_possible_cpu(i) { |
452 | memset((void *)critirq_ctx[i], 0, THREAD_SIZE); | 453 | hw_cpu = get_hard_smp_processor_id(i); |
453 | tp = critirq_ctx[i]; | 454 | memset((void *)critirq_ctx[hw_cpu], 0, THREAD_SIZE); |
455 | tp = critirq_ctx[hw_cpu]; | ||
454 | tp->cpu = i; | 456 | tp->cpu = i; |
455 | tp->preempt_count = 0; | 457 | tp->preempt_count = 0; |
456 | 458 | ||
457 | #ifdef CONFIG_BOOKE | 459 | #ifdef CONFIG_BOOKE |
458 | memset((void *)dbgirq_ctx[i], 0, THREAD_SIZE); | 460 | memset((void *)dbgirq_ctx[hw_cpu], 0, THREAD_SIZE); |
459 | tp = dbgirq_ctx[i]; | 461 | tp = dbgirq_ctx[hw_cpu]; |
460 | tp->cpu = i; | 462 | tp->cpu = i; |
461 | tp->preempt_count = 0; | 463 | tp->preempt_count = 0; |
462 | 464 | ||
463 | memset((void *)mcheckirq_ctx[i], 0, THREAD_SIZE); | 465 | memset((void *)mcheckirq_ctx[hw_cpu], 0, THREAD_SIZE); |
464 | tp = mcheckirq_ctx[i]; | 466 | tp = mcheckirq_ctx[hw_cpu]; |
465 | tp->cpu = i; | 467 | tp->cpu = i; |
466 | tp->preempt_count = HARDIRQ_OFFSET; | 468 | tp->preempt_count = HARDIRQ_OFFSET; |
467 | #endif | 469 | #endif |
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index 6bbd7a604d2..a7a570dcdd5 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S | |||
@@ -810,6 +810,9 @@ relocate_new_kernel: | |||
810 | isync | 810 | isync |
811 | sync | 811 | sync |
812 | 812 | ||
813 | mfspr r3, SPRN_PIR /* current core we are running on */ | ||
814 | mr r4, r5 /* load physical address of chunk called */ | ||
815 | |||
813 | /* jump to the entry point, usually the setup routine */ | 816 | /* jump to the entry point, usually the setup routine */ |
814 | mtlr r5 | 817 | mtlr r5 |
815 | blrl | 818 | blrl |
diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c index 477c663e014..49cee9df225 100644 --- a/arch/powerpc/kernel/module.c +++ b/arch/powerpc/kernel/module.c | |||
@@ -63,11 +63,6 @@ int module_finalize(const Elf_Ehdr *hdr, | |||
63 | const Elf_Shdr *sechdrs, struct module *me) | 63 | const Elf_Shdr *sechdrs, struct module *me) |
64 | { | 64 | { |
65 | const Elf_Shdr *sect; | 65 | const Elf_Shdr *sect; |
66 | int err; | ||
67 | |||
68 | err = module_bug_finalize(hdr, sechdrs, me); | ||
69 | if (err) | ||
70 | return err; | ||
71 | 66 | ||
72 | /* Apply feature fixups */ | 67 | /* Apply feature fixups */ |
73 | sect = find_section(hdr, sechdrs, "__ftr_fixup"); | 68 | sect = find_section(hdr, sechdrs, "__ftr_fixup"); |
@@ -101,5 +96,4 @@ int module_finalize(const Elf_Ehdr *hdr, | |||
101 | 96 | ||
102 | void module_arch_cleanup(struct module *mod) | 97 | void module_arch_cleanup(struct module *mod) |
103 | { | 98 | { |
104 | module_bug_cleanup(mod); | ||
105 | } | 99 | } |
diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c index 6ddb795f83e..e751506323b 100644 --- a/arch/powerpc/kernel/pci_of_scan.c +++ b/arch/powerpc/kernel/pci_of_scan.c | |||
@@ -336,7 +336,7 @@ static void __devinit __of_scan_bus(struct device_node *node, | |||
336 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || | 336 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || |
337 | dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) { | 337 | dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) { |
338 | struct device_node *child = pci_device_to_OF_node(dev); | 338 | struct device_node *child = pci_device_to_OF_node(dev); |
339 | if (dev) | 339 | if (child) |
340 | of_scan_pci_bridge(child, dev); | 340 | of_scan_pci_bridge(child, dev); |
341 | } | 341 | } |
342 | } | 342 | } |
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 91356ffda2c..b1c648a36b0 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c | |||
@@ -728,7 +728,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
728 | p->thread.regs = childregs; | 728 | p->thread.regs = childregs; |
729 | if (clone_flags & CLONE_SETTLS) { | 729 | if (clone_flags & CLONE_SETTLS) { |
730 | #ifdef CONFIG_PPC64 | 730 | #ifdef CONFIG_PPC64 |
731 | if (!test_thread_flag(TIF_32BIT)) | 731 | if (!is_32bit_task()) |
732 | childregs->gpr[13] = childregs->gpr[6]; | 732 | childregs->gpr[13] = childregs->gpr[6]; |
733 | else | 733 | else |
734 | #endif | 734 | #endif |
@@ -823,7 +823,7 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) | |||
823 | regs->nip = start; | 823 | regs->nip = start; |
824 | regs->msr = MSR_USER; | 824 | regs->msr = MSR_USER; |
825 | #else | 825 | #else |
826 | if (!test_thread_flag(TIF_32BIT)) { | 826 | if (!is_32bit_task()) { |
827 | unsigned long entry, toc; | 827 | unsigned long entry, toc; |
828 | 828 | ||
829 | /* start is a relocated pointer to the function descriptor for | 829 | /* start is a relocated pointer to the function descriptor for |
@@ -995,7 +995,7 @@ int sys_clone(unsigned long clone_flags, unsigned long usp, | |||
995 | if (usp == 0) | 995 | if (usp == 0) |
996 | usp = regs->gpr[1]; /* stack pointer for child */ | 996 | usp = regs->gpr[1]; /* stack pointer for child */ |
997 | #ifdef CONFIG_PPC64 | 997 | #ifdef CONFIG_PPC64 |
998 | if (test_thread_flag(TIF_32BIT)) { | 998 | if (is_32bit_task()) { |
999 | parent_tidp = TRUNC_PTR(parent_tidp); | 999 | parent_tidp = TRUNC_PTR(parent_tidp); |
1000 | child_tidp = TRUNC_PTR(child_tidp); | 1000 | child_tidp = TRUNC_PTR(child_tidp); |
1001 | } | 1001 | } |
@@ -1199,19 +1199,17 @@ void ppc64_runlatch_on(void) | |||
1199 | } | 1199 | } |
1200 | } | 1200 | } |
1201 | 1201 | ||
1202 | void ppc64_runlatch_off(void) | 1202 | void __ppc64_runlatch_off(void) |
1203 | { | 1203 | { |
1204 | unsigned long ctrl; | 1204 | unsigned long ctrl; |
1205 | 1205 | ||
1206 | if (cpu_has_feature(CPU_FTR_CTRL) && test_thread_flag(TIF_RUNLATCH)) { | 1206 | HMT_medium(); |
1207 | HMT_medium(); | ||
1208 | 1207 | ||
1209 | clear_thread_flag(TIF_RUNLATCH); | 1208 | clear_thread_flag(TIF_RUNLATCH); |
1210 | 1209 | ||
1211 | ctrl = mfspr(SPRN_CTRLF); | 1210 | ctrl = mfspr(SPRN_CTRLF); |
1212 | ctrl &= ~CTRL_RUNLATCH; | 1211 | ctrl &= ~CTRL_RUNLATCH; |
1213 | mtspr(SPRN_CTRLT, ctrl); | 1212 | mtspr(SPRN_CTRLT, ctrl); |
1214 | } | ||
1215 | } | 1213 | } |
1216 | #endif | 1214 | #endif |
1217 | 1215 | ||
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index a10ffc85ada..93666f9cabf 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c | |||
@@ -258,17 +258,18 @@ static void __init irqstack_early_init(void) | |||
258 | #if defined(CONFIG_BOOKE) || defined(CONFIG_40x) | 258 | #if defined(CONFIG_BOOKE) || defined(CONFIG_40x) |
259 | static void __init exc_lvl_early_init(void) | 259 | static void __init exc_lvl_early_init(void) |
260 | { | 260 | { |
261 | unsigned int i; | 261 | unsigned int i, hw_cpu; |
262 | 262 | ||
263 | /* interrupt stacks must be in lowmem, we get that for free on ppc32 | 263 | /* interrupt stacks must be in lowmem, we get that for free on ppc32 |
264 | * as the memblock is limited to lowmem by MEMBLOCK_REAL_LIMIT */ | 264 | * as the memblock is limited to lowmem by MEMBLOCK_REAL_LIMIT */ |
265 | for_each_possible_cpu(i) { | 265 | for_each_possible_cpu(i) { |
266 | critirq_ctx[i] = (struct thread_info *) | 266 | hw_cpu = get_hard_smp_processor_id(i); |
267 | critirq_ctx[hw_cpu] = (struct thread_info *) | ||
267 | __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE)); | 268 | __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE)); |
268 | #ifdef CONFIG_BOOKE | 269 | #ifdef CONFIG_BOOKE |
269 | dbgirq_ctx[i] = (struct thread_info *) | 270 | dbgirq_ctx[hw_cpu] = (struct thread_info *) |
270 | __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE)); | 271 | __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE)); |
271 | mcheckirq_ctx[i] = (struct thread_info *) | 272 | mcheckirq_ctx[hw_cpu] = (struct thread_info *) |
272 | __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE)); | 273 | __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE)); |
273 | #endif | 274 | #endif |
274 | } | 275 | } |
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 1bee4b68fa4..e72690ec9b8 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
@@ -95,7 +95,7 @@ int ucache_bsize; | |||
95 | 95 | ||
96 | #ifdef CONFIG_SMP | 96 | #ifdef CONFIG_SMP |
97 | 97 | ||
98 | static int smt_enabled_cmdline; | 98 | static char *smt_enabled_cmdline; |
99 | 99 | ||
100 | /* Look for ibm,smt-enabled OF option */ | 100 | /* Look for ibm,smt-enabled OF option */ |
101 | static void check_smt_enabled(void) | 101 | static void check_smt_enabled(void) |
@@ -103,37 +103,46 @@ static void check_smt_enabled(void) | |||
103 | struct device_node *dn; | 103 | struct device_node *dn; |
104 | const char *smt_option; | 104 | const char *smt_option; |
105 | 105 | ||
106 | /* Allow the command line to overrule the OF option */ | 106 | /* Default to enabling all threads */ |
107 | if (smt_enabled_cmdline) | 107 | smt_enabled_at_boot = threads_per_core; |
108 | return; | ||
109 | |||
110 | dn = of_find_node_by_path("/options"); | ||
111 | |||
112 | if (dn) { | ||
113 | smt_option = of_get_property(dn, "ibm,smt-enabled", NULL); | ||
114 | 108 | ||
115 | if (smt_option) { | 109 | /* Allow the command line to overrule the OF option */ |
116 | if (!strcmp(smt_option, "on")) | 110 | if (smt_enabled_cmdline) { |
117 | smt_enabled_at_boot = 1; | 111 | if (!strcmp(smt_enabled_cmdline, "on")) |
118 | else if (!strcmp(smt_option, "off")) | 112 | smt_enabled_at_boot = threads_per_core; |
119 | smt_enabled_at_boot = 0; | 113 | else if (!strcmp(smt_enabled_cmdline, "off")) |
120 | } | 114 | smt_enabled_at_boot = 0; |
121 | } | 115 | else { |
116 | long smt; | ||
117 | int rc; | ||
118 | |||
119 | rc = strict_strtol(smt_enabled_cmdline, 10, &smt); | ||
120 | if (!rc) | ||
121 | smt_enabled_at_boot = | ||
122 | min(threads_per_core, (int)smt); | ||
123 | } | ||
124 | } else { | ||
125 | dn = of_find_node_by_path("/options"); | ||
126 | if (dn) { | ||
127 | smt_option = of_get_property(dn, "ibm,smt-enabled", | ||
128 | NULL); | ||
129 | |||
130 | if (smt_option) { | ||
131 | if (!strcmp(smt_option, "on")) | ||
132 | smt_enabled_at_boot = threads_per_core; | ||
133 | else if (!strcmp(smt_option, "off")) | ||
134 | smt_enabled_at_boot = 0; | ||
135 | } | ||
136 | |||
137 | of_node_put(dn); | ||
138 | } | ||
139 | } | ||
122 | } | 140 | } |
123 | 141 | ||
124 | /* Look for smt-enabled= cmdline option */ | 142 | /* Look for smt-enabled= cmdline option */ |
125 | static int __init early_smt_enabled(char *p) | 143 | static int __init early_smt_enabled(char *p) |
126 | { | 144 | { |
127 | smt_enabled_cmdline = 1; | 145 | smt_enabled_cmdline = p; |
128 | |||
129 | if (!p) | ||
130 | return 0; | ||
131 | |||
132 | if (!strcmp(p, "on") || !strcmp(p, "1")) | ||
133 | smt_enabled_at_boot = 1; | ||
134 | else if (!strcmp(p, "off") || !strcmp(p, "0")) | ||
135 | smt_enabled_at_boot = 0; | ||
136 | |||
137 | return 0; | 146 | return 0; |
138 | } | 147 | } |
139 | early_param("smt-enabled", early_smt_enabled); | 148 | early_param("smt-enabled", early_smt_enabled); |
@@ -380,8 +389,8 @@ void __init setup_system(void) | |||
380 | */ | 389 | */ |
381 | xmon_setup(); | 390 | xmon_setup(); |
382 | 391 | ||
383 | check_smt_enabled(); | ||
384 | smp_setup_cpu_maps(); | 392 | smp_setup_cpu_maps(); |
393 | check_smt_enabled(); | ||
385 | 394 | ||
386 | #ifdef CONFIG_SMP | 395 | #ifdef CONFIG_SMP |
387 | /* Release secondary cpus out of their spinloops at 0x60 now that | 396 | /* Release secondary cpus out of their spinloops at 0x60 now that |
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c index 7109f5b1baa..2300426e531 100644 --- a/arch/powerpc/kernel/signal.c +++ b/arch/powerpc/kernel/signal.c | |||
@@ -138,6 +138,7 @@ static int do_signal_pending(sigset_t *oldset, struct pt_regs *regs) | |||
138 | ti->local_flags &= ~_TLF_RESTORE_SIGMASK; | 138 | ti->local_flags &= ~_TLF_RESTORE_SIGMASK; |
139 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | 139 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); |
140 | } | 140 | } |
141 | regs->trap = 0; | ||
141 | return 0; /* no signals delivered */ | 142 | return 0; /* no signals delivered */ |
142 | } | 143 | } |
143 | 144 | ||
@@ -164,6 +165,7 @@ static int do_signal_pending(sigset_t *oldset, struct pt_regs *regs) | |||
164 | ret = handle_rt_signal64(signr, &ka, &info, oldset, regs); | 165 | ret = handle_rt_signal64(signr, &ka, &info, oldset, regs); |
165 | } | 166 | } |
166 | 167 | ||
168 | regs->trap = 0; | ||
167 | if (ret) { | 169 | if (ret) { |
168 | spin_lock_irq(¤t->sighand->siglock); | 170 | spin_lock_irq(¤t->sighand->siglock); |
169 | sigorsets(¤t->blocked, ¤t->blocked, | 171 | sigorsets(¤t->blocked, ¤t->blocked, |
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 266610119f6..b96a3a010c2 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c | |||
@@ -511,6 +511,7 @@ static long restore_user_regs(struct pt_regs *regs, | |||
511 | if (!sig) | 511 | if (!sig) |
512 | save_r2 = (unsigned int)regs->gpr[2]; | 512 | save_r2 = (unsigned int)regs->gpr[2]; |
513 | err = restore_general_regs(regs, sr); | 513 | err = restore_general_regs(regs, sr); |
514 | regs->trap = 0; | ||
514 | err |= __get_user(msr, &sr->mc_gregs[PT_MSR]); | 515 | err |= __get_user(msr, &sr->mc_gregs[PT_MSR]); |
515 | if (!sig) | 516 | if (!sig) |
516 | regs->gpr[2] = (unsigned long) save_r2; | 517 | regs->gpr[2] = (unsigned long) save_r2; |
@@ -884,7 +885,6 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka, | |||
884 | regs->nip = (unsigned long) ka->sa.sa_handler; | 885 | regs->nip = (unsigned long) ka->sa.sa_handler; |
885 | /* enter the signal handler in big-endian mode */ | 886 | /* enter the signal handler in big-endian mode */ |
886 | regs->msr &= ~MSR_LE; | 887 | regs->msr &= ~MSR_LE; |
887 | regs->trap = 0; | ||
888 | return 1; | 888 | return 1; |
889 | 889 | ||
890 | badframe: | 890 | badframe: |
@@ -1228,7 +1228,6 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka, | |||
1228 | regs->nip = (unsigned long) ka->sa.sa_handler; | 1228 | regs->nip = (unsigned long) ka->sa.sa_handler; |
1229 | /* enter the signal handler in big-endian mode */ | 1229 | /* enter the signal handler in big-endian mode */ |
1230 | regs->msr &= ~MSR_LE; | 1230 | regs->msr &= ~MSR_LE; |
1231 | regs->trap = 0; | ||
1232 | 1231 | ||
1233 | return 1; | 1232 | return 1; |
1234 | 1233 | ||
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index 2fe6fc64b61..27c4a4584f8 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c | |||
@@ -178,7 +178,7 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig, | |||
178 | err |= __get_user(regs->xer, &sc->gp_regs[PT_XER]); | 178 | err |= __get_user(regs->xer, &sc->gp_regs[PT_XER]); |
179 | err |= __get_user(regs->ccr, &sc->gp_regs[PT_CCR]); | 179 | err |= __get_user(regs->ccr, &sc->gp_regs[PT_CCR]); |
180 | /* skip SOFTE */ | 180 | /* skip SOFTE */ |
181 | err |= __get_user(regs->trap, &sc->gp_regs[PT_TRAP]); | 181 | regs->trap = 0; |
182 | err |= __get_user(regs->dar, &sc->gp_regs[PT_DAR]); | 182 | err |= __get_user(regs->dar, &sc->gp_regs[PT_DAR]); |
183 | err |= __get_user(regs->dsisr, &sc->gp_regs[PT_DSISR]); | 183 | err |= __get_user(regs->dsisr, &sc->gp_regs[PT_DSISR]); |
184 | err |= __get_user(regs->result, &sc->gp_regs[PT_RESULT]); | 184 | err |= __get_user(regs->result, &sc->gp_regs[PT_RESULT]); |
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index a61b3ddd7bb..0008bc58e82 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c | |||
@@ -427,11 +427,11 @@ int __cpuinit __cpu_up(unsigned int cpu) | |||
427 | #endif | 427 | #endif |
428 | 428 | ||
429 | if (!cpu_callin_map[cpu]) { | 429 | if (!cpu_callin_map[cpu]) { |
430 | printk("Processor %u is stuck.\n", cpu); | 430 | printk(KERN_ERR "Processor %u is stuck.\n", cpu); |
431 | return -ENOENT; | 431 | return -ENOENT; |
432 | } | 432 | } |
433 | 433 | ||
434 | printk("Processor %u found.\n", cpu); | 434 | DBG("Processor %u found.\n", cpu); |
435 | 435 | ||
436 | if (smp_ops->give_timebase) | 436 | if (smp_ops->give_timebase) |
437 | smp_ops->give_timebase(); | 437 | smp_ops->give_timebase(); |
diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c index 20fd701a686..b1b6043a56c 100644 --- a/arch/powerpc/kernel/sys_ppc32.c +++ b/arch/powerpc/kernel/sys_ppc32.c | |||
@@ -616,3 +616,11 @@ asmlinkage long compat_sys_sync_file_range2(int fd, unsigned int flags, | |||
616 | 616 | ||
617 | return sys_sync_file_range(fd, offset, nbytes, flags); | 617 | return sys_sync_file_range(fd, offset, nbytes, flags); |
618 | } | 618 | } |
619 | |||
620 | asmlinkage long compat_sys_fanotify_mark(int fanotify_fd, unsigned int flags, | ||
621 | unsigned mask_hi, unsigned mask_lo, | ||
622 | int dfd, const char __user *pathname) | ||
623 | { | ||
624 | u64 mask = ((u64)mask_hi << 32) | mask_lo; | ||
625 | return sys_fanotify_mark(fanotify_fd, flags, mask, dfd, pathname); | ||
626 | } | ||
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index ce53dfa7130..8533b3b83f5 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
@@ -577,20 +577,11 @@ void timer_interrupt(struct pt_regs * regs) | |||
577 | * some CPUs will continuue to take decrementer exceptions */ | 577 | * some CPUs will continuue to take decrementer exceptions */ |
578 | set_dec(DECREMENTER_MAX); | 578 | set_dec(DECREMENTER_MAX); |
579 | 579 | ||
580 | #ifdef CONFIG_PPC32 | 580 | #if defined(CONFIG_PPC32) && defined(CONFIG_PMAC) |
581 | if (atomic_read(&ppc_n_lost_interrupts) != 0) | 581 | if (atomic_read(&ppc_n_lost_interrupts) != 0) |
582 | do_IRQ(regs); | 582 | do_IRQ(regs); |
583 | #endif | 583 | #endif |
584 | 584 | ||
585 | now = get_tb_or_rtc(); | ||
586 | if (now < decrementer->next_tb) { | ||
587 | /* not time for this event yet */ | ||
588 | now = decrementer->next_tb - now; | ||
589 | if (now <= DECREMENTER_MAX) | ||
590 | set_dec((int)now); | ||
591 | trace_timer_interrupt_exit(regs); | ||
592 | return; | ||
593 | } | ||
594 | old_regs = set_irq_regs(regs); | 585 | old_regs = set_irq_regs(regs); |
595 | irq_enter(); | 586 | irq_enter(); |
596 | 587 | ||
@@ -606,8 +597,16 @@ void timer_interrupt(struct pt_regs * regs) | |||
606 | get_lppaca()->int_dword.fields.decr_int = 0; | 597 | get_lppaca()->int_dword.fields.decr_int = 0; |
607 | #endif | 598 | #endif |
608 | 599 | ||
609 | if (evt->event_handler) | 600 | now = get_tb_or_rtc(); |
610 | evt->event_handler(evt); | 601 | if (now >= decrementer->next_tb) { |
602 | decrementer->next_tb = ~(u64)0; | ||
603 | if (evt->event_handler) | ||
604 | evt->event_handler(evt); | ||
605 | } else { | ||
606 | now = decrementer->next_tb - now; | ||
607 | if (now <= DECREMENTER_MAX) | ||
608 | set_dec((int)now); | ||
609 | } | ||
611 | 610 | ||
612 | #ifdef CONFIG_PPC_ISERIES | 611 | #ifdef CONFIG_PPC_ISERIES |
613 | if (firmware_has_feature(FW_FEATURE_ISERIES) && hvlpevent_is_pending()) | 612 | if (firmware_has_feature(FW_FEATURE_ISERIES) && hvlpevent_is_pending()) |
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index 00b9436f765..fa3469ddaef 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c | |||
@@ -1059,7 +1059,7 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev) | |||
1059 | if (!dma_window) | 1059 | if (!dma_window) |
1060 | return NULL; | 1060 | return NULL; |
1061 | 1061 | ||
1062 | tbl = kmalloc(sizeof(*tbl), GFP_KERNEL); | 1062 | tbl = kzalloc(sizeof(*tbl), GFP_KERNEL); |
1063 | if (tbl == NULL) | 1063 | if (tbl == NULL) |
1064 | return NULL; | 1064 | return NULL; |
1065 | 1065 | ||
@@ -1072,6 +1072,7 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev) | |||
1072 | tbl->it_offset = offset >> IOMMU_PAGE_SHIFT; | 1072 | tbl->it_offset = offset >> IOMMU_PAGE_SHIFT; |
1073 | tbl->it_busno = 0; | 1073 | tbl->it_busno = 0; |
1074 | tbl->it_type = TCE_VB; | 1074 | tbl->it_type = TCE_VB; |
1075 | tbl->it_blocksize = 16; | ||
1075 | 1076 | ||
1076 | return iommu_init_table(tbl, -1); | 1077 | return iommu_init_table(tbl, -1); |
1077 | } | 1078 | } |
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c index 71f1415e247..ace85fa74b2 100644 --- a/arch/powerpc/mm/init_64.c +++ b/arch/powerpc/mm/init_64.c | |||
@@ -79,7 +79,9 @@ | |||
79 | #endif /* CONFIG_PPC_STD_MMU_64 */ | 79 | #endif /* CONFIG_PPC_STD_MMU_64 */ |
80 | 80 | ||
81 | phys_addr_t memstart_addr = ~0; | 81 | phys_addr_t memstart_addr = ~0; |
82 | EXPORT_SYMBOL_GPL(memstart_addr); | ||
82 | phys_addr_t kernstart_addr; | 83 | phys_addr_t kernstart_addr; |
84 | EXPORT_SYMBOL_GPL(kernstart_addr); | ||
83 | 85 | ||
84 | void free_initmem(void) | 86 | void free_initmem(void) |
85 | { | 87 | { |
diff --git a/arch/powerpc/mm/tlb_nohash_low.S b/arch/powerpc/mm/tlb_nohash_low.S index cfa768203d0..b9d9fed8f36 100644 --- a/arch/powerpc/mm/tlb_nohash_low.S +++ b/arch/powerpc/mm/tlb_nohash_low.S | |||
@@ -200,6 +200,7 @@ _GLOBAL(_tlbivax_bcast) | |||
200 | rlwimi r5,r4,0,16,31 | 200 | rlwimi r5,r4,0,16,31 |
201 | wrteei 0 | 201 | wrteei 0 |
202 | mtspr SPRN_MMUCR,r5 | 202 | mtspr SPRN_MMUCR,r5 |
203 | isync | ||
203 | /* tlbivax 0,r3 - use .long to avoid binutils deps */ | 204 | /* tlbivax 0,r3 - use .long to avoid binutils deps */ |
204 | .long 0x7c000624 | (r3 << 11) | 205 | .long 0x7c000624 | (r3 << 11) |
205 | isync | 206 | isync |
diff --git a/arch/powerpc/platforms/512x/clock.c b/arch/powerpc/platforms/512x/clock.c index 5b243bd3eb3..3dc2a8d262b 100644 --- a/arch/powerpc/platforms/512x/clock.c +++ b/arch/powerpc/platforms/512x/clock.c | |||
@@ -57,7 +57,7 @@ static struct clk *mpc5121_clk_get(struct device *dev, const char *id) | |||
57 | int id_match = 0; | 57 | int id_match = 0; |
58 | 58 | ||
59 | if (dev == NULL || id == NULL) | 59 | if (dev == NULL || id == NULL) |
60 | return NULL; | 60 | return clk; |
61 | 61 | ||
62 | mutex_lock(&clocks_mutex); | 62 | mutex_lock(&clocks_mutex); |
63 | list_for_each_entry(p, &clocks, node) { | 63 | list_for_each_entry(p, &clocks, node) { |
diff --git a/arch/powerpc/platforms/52xx/efika.c b/arch/powerpc/platforms/52xx/efika.c index 45c0cb9b67e..18c10482019 100644 --- a/arch/powerpc/platforms/52xx/efika.c +++ b/arch/powerpc/platforms/52xx/efika.c | |||
@@ -99,7 +99,7 @@ static void __init efika_pcisetup(void) | |||
99 | if (bus_range == NULL || len < 2 * sizeof(int)) { | 99 | if (bus_range == NULL || len < 2 * sizeof(int)) { |
100 | printk(KERN_WARNING EFIKA_PLATFORM_NAME | 100 | printk(KERN_WARNING EFIKA_PLATFORM_NAME |
101 | ": Can't get bus-range for %s\n", pcictrl->full_name); | 101 | ": Can't get bus-range for %s\n", pcictrl->full_name); |
102 | return; | 102 | goto out_put; |
103 | } | 103 | } |
104 | 104 | ||
105 | if (bus_range[1] == bus_range[0]) | 105 | if (bus_range[1] == bus_range[0]) |
@@ -111,12 +111,12 @@ static void __init efika_pcisetup(void) | |||
111 | printk(" controlled by %s\n", pcictrl->full_name); | 111 | printk(" controlled by %s\n", pcictrl->full_name); |
112 | printk("\n"); | 112 | printk("\n"); |
113 | 113 | ||
114 | hose = pcibios_alloc_controller(of_node_get(pcictrl)); | 114 | hose = pcibios_alloc_controller(pcictrl); |
115 | if (!hose) { | 115 | if (!hose) { |
116 | printk(KERN_WARNING EFIKA_PLATFORM_NAME | 116 | printk(KERN_WARNING EFIKA_PLATFORM_NAME |
117 | ": Can't allocate PCI controller structure for %s\n", | 117 | ": Can't allocate PCI controller structure for %s\n", |
118 | pcictrl->full_name); | 118 | pcictrl->full_name); |
119 | return; | 119 | goto out_put; |
120 | } | 120 | } |
121 | 121 | ||
122 | hose->first_busno = bus_range[0]; | 122 | hose->first_busno = bus_range[0]; |
@@ -124,6 +124,9 @@ static void __init efika_pcisetup(void) | |||
124 | hose->ops = &rtas_pci_ops; | 124 | hose->ops = &rtas_pci_ops; |
125 | 125 | ||
126 | pci_process_bridge_OF_ranges(hose, pcictrl, 0); | 126 | pci_process_bridge_OF_ranges(hose, pcictrl, 0); |
127 | return; | ||
128 | out_put: | ||
129 | of_node_put(pcictrl); | ||
127 | } | 130 | } |
128 | 131 | ||
129 | #else | 132 | #else |
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c index 6e905314ad5..41f3a7eda1d 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_common.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c | |||
@@ -325,12 +325,16 @@ int mpc5200_psc_ac97_gpio_reset(int psc_number) | |||
325 | clrbits32(&simple_gpio->simple_dvo, sync | out); | 325 | clrbits32(&simple_gpio->simple_dvo, sync | out); |
326 | clrbits8(&wkup_gpio->wkup_dvo, reset); | 326 | clrbits8(&wkup_gpio->wkup_dvo, reset); |
327 | 327 | ||
328 | /* wait at lease 1 us */ | 328 | /* wait for 1 us */ |
329 | udelay(2); | 329 | udelay(1); |
330 | 330 | ||
331 | /* Deassert reset */ | 331 | /* Deassert reset */ |
332 | setbits8(&wkup_gpio->wkup_dvo, reset); | 332 | setbits8(&wkup_gpio->wkup_dvo, reset); |
333 | 333 | ||
334 | /* wait at least 200ns */ | ||
335 | /* 7 ~= (200ns * timebase) / ns2sec */ | ||
336 | __delay(7); | ||
337 | |||
334 | /* Restore pin-muxing */ | 338 | /* Restore pin-muxing */ |
335 | out_be32(&simple_gpio->port_config, mux); | 339 | out_be32(&simple_gpio->port_config, mux); |
336 | 340 | ||
diff --git a/arch/powerpc/platforms/83xx/mpc837x_mds.c b/arch/powerpc/platforms/83xx/mpc837x_mds.c index f9751c8905b..83068322abd 100644 --- a/arch/powerpc/platforms/83xx/mpc837x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc837x_mds.c | |||
@@ -48,8 +48,10 @@ static int mpc837xmds_usb_cfg(void) | |||
48 | return -1; | 48 | return -1; |
49 | 49 | ||
50 | np = of_find_node_by_name(NULL, "usb"); | 50 | np = of_find_node_by_name(NULL, "usb"); |
51 | if (!np) | 51 | if (!np) { |
52 | return -ENODEV; | 52 | ret = -ENODEV; |
53 | goto out; | ||
54 | } | ||
53 | phy_type = of_get_property(np, "phy_type", NULL); | 55 | phy_type = of_get_property(np, "phy_type", NULL); |
54 | if (phy_type && !strcmp(phy_type, "ulpi")) { | 56 | if (phy_type && !strcmp(phy_type, "ulpi")) { |
55 | clrbits8(bcsr_regs + 12, BCSR12_USB_SER_PIN); | 57 | clrbits8(bcsr_regs + 12, BCSR12_USB_SER_PIN); |
@@ -65,8 +67,9 @@ static int mpc837xmds_usb_cfg(void) | |||
65 | } | 67 | } |
66 | 68 | ||
67 | of_node_put(np); | 69 | of_node_put(np); |
70 | out: | ||
68 | iounmap(bcsr_regs); | 71 | iounmap(bcsr_regs); |
69 | return 0; | 72 | return ret; |
70 | } | 73 | } |
71 | 74 | ||
72 | /* ************************************************************************ | 75 | /* ************************************************************************ |
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c index da64be19d09..aa34cac4eb5 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c | |||
@@ -357,6 +357,7 @@ static void __init mpc85xx_mds_setup_arch(void) | |||
357 | { | 357 | { |
358 | #ifdef CONFIG_PCI | 358 | #ifdef CONFIG_PCI |
359 | struct pci_controller *hose; | 359 | struct pci_controller *hose; |
360 | struct device_node *np; | ||
360 | #endif | 361 | #endif |
361 | dma_addr_t max = 0xffffffff; | 362 | dma_addr_t max = 0xffffffff; |
362 | 363 | ||
diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c index e1467c93745..34e00902ce8 100644 --- a/arch/powerpc/platforms/85xx/p1022_ds.c +++ b/arch/powerpc/platforms/85xx/p1022_ds.c | |||
@@ -19,7 +19,7 @@ | |||
19 | 19 | ||
20 | #include <linux/pci.h> | 20 | #include <linux/pci.h> |
21 | #include <linux/of_platform.h> | 21 | #include <linux/of_platform.h> |
22 | #include <linux/lmb.h> | 22 | #include <linux/memblock.h> |
23 | 23 | ||
24 | #include <asm/mpic.h> | 24 | #include <asm/mpic.h> |
25 | #include <asm/swiotlb.h> | 25 | #include <asm/swiotlb.h> |
@@ -97,7 +97,7 @@ static void __init p1022_ds_setup_arch(void) | |||
97 | #endif | 97 | #endif |
98 | 98 | ||
99 | #ifdef CONFIG_SWIOTLB | 99 | #ifdef CONFIG_SWIOTLB |
100 | if (lmb_end_of_DRAM() > max) { | 100 | if (memblock_end_of_DRAM() > max) { |
101 | ppc_swiotlb_enable = 1; | 101 | ppc_swiotlb_enable = 1; |
102 | set_pci_dma_ops(&swiotlb_dma_ops); | 102 | set_pci_dma_ops(&swiotlb_dma_ops); |
103 | ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; | 103 | ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; |
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig index d1663db7810..81c9208025f 100644 --- a/arch/powerpc/platforms/Kconfig +++ b/arch/powerpc/platforms/Kconfig | |||
@@ -106,8 +106,7 @@ config MMIO_NVRAM | |||
106 | 106 | ||
107 | config MPIC_U3_HT_IRQS | 107 | config MPIC_U3_HT_IRQS |
108 | bool | 108 | bool |
109 | depends on PPC_MAPLE | 109 | default n |
110 | default y | ||
111 | 110 | ||
112 | config MPIC_BROKEN_REGREAD | 111 | config MPIC_BROKEN_REGREAD |
113 | bool | 112 | bool |
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index 58b13ce3847..26a067122a5 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c | |||
@@ -477,7 +477,7 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np, | |||
477 | 477 | ||
478 | ioid = cell_iommu_get_ioid(np); | 478 | ioid = cell_iommu_get_ioid(np); |
479 | 479 | ||
480 | window = kmalloc_node(sizeof(*window), GFP_KERNEL, iommu->nid); | 480 | window = kzalloc_node(sizeof(*window), GFP_KERNEL, iommu->nid); |
481 | BUG_ON(window == NULL); | 481 | BUG_ON(window == NULL); |
482 | 482 | ||
483 | window->offset = offset; | 483 | window->offset = offset; |
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c index ce61cea0afb..d8b76335bd1 100644 --- a/arch/powerpc/platforms/iseries/iommu.c +++ b/arch/powerpc/platforms/iseries/iommu.c | |||
@@ -184,7 +184,7 @@ static void pci_dma_dev_setup_iseries(struct pci_dev *pdev) | |||
184 | 184 | ||
185 | BUG_ON(lsn == NULL); | 185 | BUG_ON(lsn == NULL); |
186 | 186 | ||
187 | tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); | 187 | tbl = kzalloc(sizeof(struct iommu_table), GFP_KERNEL); |
188 | 188 | ||
189 | iommu_table_getparms_iSeries(pdn->busno, *lsn, 0, tbl); | 189 | iommu_table_getparms_iSeries(pdn->busno, *lsn, 0, tbl); |
190 | 190 | ||
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c index 39df6ab1735..df423993f17 100644 --- a/arch/powerpc/platforms/powermac/feature.c +++ b/arch/powerpc/platforms/powermac/feature.c | |||
@@ -2873,12 +2873,11 @@ set_initial_features(void) | |||
2873 | 2873 | ||
2874 | /* Switch airport off */ | 2874 | /* Switch airport off */ |
2875 | for_each_node_by_name(np, "radio") { | 2875 | for_each_node_by_name(np, "radio") { |
2876 | if (np && np->parent == macio_chips[0].of_node) { | 2876 | if (np->parent == macio_chips[0].of_node) { |
2877 | macio_chips[0].flags |= MACIO_FLAG_AIRPORT_ON; | 2877 | macio_chips[0].flags |= MACIO_FLAG_AIRPORT_ON; |
2878 | core99_airport_enable(np, 0, 0); | 2878 | core99_airport_enable(np, 0, 0); |
2879 | } | 2879 | } |
2880 | } | 2880 | } |
2881 | of_node_put(np); | ||
2882 | } | 2881 | } |
2883 | 2882 | ||
2884 | /* On all machines that support sound PM, switch sound off */ | 2883 | /* On all machines that support sound PM, switch sound off */ |
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c index ab2027cdf89..3bc075c788e 100644 --- a/arch/powerpc/platforms/powermac/pci.c +++ b/arch/powerpc/platforms/powermac/pci.c | |||
@@ -1155,13 +1155,11 @@ void __init pmac_pcibios_after_init(void) | |||
1155 | pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, nd, 0, 0); | 1155 | pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, nd, 0, 0); |
1156 | } | 1156 | } |
1157 | } | 1157 | } |
1158 | of_node_put(nd); | ||
1159 | for_each_node_by_name(nd, "ethernet") { | 1158 | for_each_node_by_name(nd, "ethernet") { |
1160 | if (nd->parent && of_device_is_compatible(nd, "gmac") | 1159 | if (nd->parent && of_device_is_compatible(nd, "gmac") |
1161 | && of_device_is_compatible(nd->parent, "uni-north")) | 1160 | && of_device_is_compatible(nd->parent, "uni-north")) |
1162 | pmac_call_feature(PMAC_FTR_GMAC_ENABLE, nd, 0, 0); | 1161 | pmac_call_feature(PMAC_FTR_GMAC_ENABLE, nd, 0, 0); |
1163 | } | 1162 | } |
1164 | of_node_put(nd); | ||
1165 | } | 1163 | } |
1166 | 1164 | ||
1167 | void pmac_pci_fixup_cardbus(struct pci_dev* dev) | 1165 | void pmac_pci_fixup_cardbus(struct pci_dev* dev) |
diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index 227c1c3d585..72d8054fa73 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c | |||
@@ -129,20 +129,35 @@ struct device_node *dlpar_configure_connector(u32 drc_index) | |||
129 | struct property *property; | 129 | struct property *property; |
130 | struct property *last_property = NULL; | 130 | struct property *last_property = NULL; |
131 | struct cc_workarea *ccwa; | 131 | struct cc_workarea *ccwa; |
132 | char *data_buf; | ||
132 | int cc_token; | 133 | int cc_token; |
133 | int rc; | 134 | int rc = -1; |
134 | 135 | ||
135 | cc_token = rtas_token("ibm,configure-connector"); | 136 | cc_token = rtas_token("ibm,configure-connector"); |
136 | if (cc_token == RTAS_UNKNOWN_SERVICE) | 137 | if (cc_token == RTAS_UNKNOWN_SERVICE) |
137 | return NULL; | 138 | return NULL; |
138 | 139 | ||
139 | spin_lock(&rtas_data_buf_lock); | 140 | data_buf = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL); |
140 | ccwa = (struct cc_workarea *)&rtas_data_buf[0]; | 141 | if (!data_buf) |
142 | return NULL; | ||
143 | |||
144 | ccwa = (struct cc_workarea *)&data_buf[0]; | ||
141 | ccwa->drc_index = drc_index; | 145 | ccwa->drc_index = drc_index; |
142 | ccwa->zero = 0; | 146 | ccwa->zero = 0; |
143 | 147 | ||
144 | rc = rtas_call(cc_token, 2, 1, NULL, rtas_data_buf, NULL); | 148 | do { |
145 | while (rc) { | 149 | /* Since we release the rtas_data_buf lock between configure |
150 | * connector calls we want to re-populate the rtas_data_buffer | ||
151 | * with the contents of the previous call. | ||
152 | */ | ||
153 | spin_lock(&rtas_data_buf_lock); | ||
154 | |||
155 | memcpy(rtas_data_buf, data_buf, RTAS_DATA_BUF_SIZE); | ||
156 | rc = rtas_call(cc_token, 2, 1, NULL, rtas_data_buf, NULL); | ||
157 | memcpy(data_buf, rtas_data_buf, RTAS_DATA_BUF_SIZE); | ||
158 | |||
159 | spin_unlock(&rtas_data_buf_lock); | ||
160 | |||
146 | switch (rc) { | 161 | switch (rc) { |
147 | case NEXT_SIBLING: | 162 | case NEXT_SIBLING: |
148 | dn = dlpar_parse_cc_node(ccwa); | 163 | dn = dlpar_parse_cc_node(ccwa); |
@@ -197,18 +212,19 @@ struct device_node *dlpar_configure_connector(u32 drc_index) | |||
197 | "returned from configure-connector\n", rc); | 212 | "returned from configure-connector\n", rc); |
198 | goto cc_error; | 213 | goto cc_error; |
199 | } | 214 | } |
215 | } while (rc); | ||
200 | 216 | ||
201 | rc = rtas_call(cc_token, 2, 1, NULL, rtas_data_buf, NULL); | 217 | cc_error: |
218 | kfree(data_buf); | ||
219 | |||
220 | if (rc) { | ||
221 | if (first_dn) | ||
222 | dlpar_free_cc_nodes(first_dn); | ||
223 | |||
224 | return NULL; | ||
202 | } | 225 | } |
203 | 226 | ||
204 | spin_unlock(&rtas_data_buf_lock); | ||
205 | return first_dn; | 227 | return first_dn; |
206 | |||
207 | cc_error: | ||
208 | if (first_dn) | ||
209 | dlpar_free_cc_nodes(first_dn); | ||
210 | spin_unlock(&rtas_data_buf_lock); | ||
211 | return NULL; | ||
212 | } | 228 | } |
213 | 229 | ||
214 | static struct device_node *derive_parent(const char *path) | 230 | static struct device_node *derive_parent(const char *path) |
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 395848e30c5..a77bcaed80a 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c | |||
@@ -403,7 +403,7 @@ static void pci_dma_bus_setup_pSeries(struct pci_bus *bus) | |||
403 | pci->phb->dma_window_size = 0x8000000ul; | 403 | pci->phb->dma_window_size = 0x8000000ul; |
404 | pci->phb->dma_window_base_cur = 0x8000000ul; | 404 | pci->phb->dma_window_base_cur = 0x8000000ul; |
405 | 405 | ||
406 | tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL, | 406 | tbl = kzalloc_node(sizeof(struct iommu_table), GFP_KERNEL, |
407 | pci->phb->node); | 407 | pci->phb->node); |
408 | 408 | ||
409 | iommu_table_setparms(pci->phb, dn, tbl); | 409 | iommu_table_setparms(pci->phb, dn, tbl); |
@@ -448,7 +448,7 @@ static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus) | |||
448 | pdn->full_name, ppci->iommu_table); | 448 | pdn->full_name, ppci->iommu_table); |
449 | 449 | ||
450 | if (!ppci->iommu_table) { | 450 | if (!ppci->iommu_table) { |
451 | tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL, | 451 | tbl = kzalloc_node(sizeof(struct iommu_table), GFP_KERNEL, |
452 | ppci->phb->node); | 452 | ppci->phb->node); |
453 | iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window, | 453 | iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window, |
454 | bus->number); | 454 | bus->number); |
@@ -478,7 +478,7 @@ static void pci_dma_dev_setup_pSeries(struct pci_dev *dev) | |||
478 | struct pci_controller *phb = PCI_DN(dn)->phb; | 478 | struct pci_controller *phb = PCI_DN(dn)->phb; |
479 | 479 | ||
480 | pr_debug(" --> first child, no bridge. Allocating iommu table.\n"); | 480 | pr_debug(" --> first child, no bridge. Allocating iommu table.\n"); |
481 | tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL, | 481 | tbl = kzalloc_node(sizeof(struct iommu_table), GFP_KERNEL, |
482 | phb->node); | 482 | phb->node); |
483 | iommu_table_setparms(phb, dn, tbl); | 483 | iommu_table_setparms(phb, dn, tbl); |
484 | PCI_DN(dn)->iommu_table = iommu_init_table(tbl, phb->node); | 484 | PCI_DN(dn)->iommu_table = iommu_init_table(tbl, phb->node); |
@@ -544,7 +544,7 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev) | |||
544 | 544 | ||
545 | pci = PCI_DN(pdn); | 545 | pci = PCI_DN(pdn); |
546 | if (!pci->iommu_table) { | 546 | if (!pci->iommu_table) { |
547 | tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL, | 547 | tbl = kzalloc_node(sizeof(struct iommu_table), GFP_KERNEL, |
548 | pci->phb->node); | 548 | pci->phb->node); |
549 | iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window, | 549 | iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window, |
550 | pci->phb->bus->number); | 550 | pci->phb->bus->number); |
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index 3b1bf61c45b..0317cce877c 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c | |||
@@ -182,10 +182,13 @@ static int smp_pSeries_cpu_bootable(unsigned int nr) | |||
182 | /* Special case - we inhibit secondary thread startup | 182 | /* Special case - we inhibit secondary thread startup |
183 | * during boot if the user requests it. | 183 | * during boot if the user requests it. |
184 | */ | 184 | */ |
185 | if (system_state < SYSTEM_RUNNING && | 185 | if (system_state < SYSTEM_RUNNING && cpu_has_feature(CPU_FTR_SMT)) { |
186 | cpu_has_feature(CPU_FTR_SMT) && | 186 | if (!smt_enabled_at_boot && cpu_thread_in_core(nr) != 0) |
187 | !smt_enabled_at_boot && cpu_thread_in_core(nr) != 0) | 187 | return 0; |
188 | return 0; | 188 | if (smt_enabled_at_boot |
189 | && cpu_thread_in_core(nr) >= smt_enabled_at_boot) | ||
190 | return 0; | ||
191 | } | ||
189 | 192 | ||
190 | return 1; | 193 | return 1; |
191 | } | 194 | } |
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c index 5b22b07c8f6..93834b0d827 100644 --- a/arch/powerpc/platforms/pseries/xics.c +++ b/arch/powerpc/platforms/pseries/xics.c | |||
@@ -928,8 +928,10 @@ void xics_migrate_irqs_away(void) | |||
928 | if (xics_status[0] != hw_cpu) | 928 | if (xics_status[0] != hw_cpu) |
929 | goto unlock; | 929 | goto unlock; |
930 | 930 | ||
931 | printk(KERN_WARNING "IRQ %u affinity broken off cpu %u\n", | 931 | /* This is expected during cpu offline. */ |
932 | virq, cpu); | 932 | if (cpu_online(cpu)) |
933 | printk(KERN_WARNING "IRQ %u affinity broken off cpu %u\n", | ||
934 | virq, cpu); | ||
933 | 935 | ||
934 | /* Reset affinity to all cpus */ | 936 | /* Reset affinity to all cpus */ |
935 | cpumask_setall(irq_to_desc(virq)->affinity); | 937 | cpumask_setall(irq_to_desc(virq)->affinity); |
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 209384b6e03..4ae93322525 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c | |||
@@ -399,6 +399,8 @@ DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1013E, quirk_fsl_pcie_header); | |||
399 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1013, quirk_fsl_pcie_header); | 399 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1013, quirk_fsl_pcie_header); |
400 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1020E, quirk_fsl_pcie_header); | 400 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1020E, quirk_fsl_pcie_header); |
401 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1020, quirk_fsl_pcie_header); | 401 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1020, quirk_fsl_pcie_header); |
402 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1021E, quirk_fsl_pcie_header); | ||
403 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1021, quirk_fsl_pcie_header); | ||
402 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1022E, quirk_fsl_pcie_header); | 404 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1022E, quirk_fsl_pcie_header); |
403 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1022, quirk_fsl_pcie_header); | 405 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P1022, quirk_fsl_pcie_header); |
404 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P2010E, quirk_fsl_pcie_header); | 406 | DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P2010E, quirk_fsl_pcie_header); |
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index 6425abe5b7d..3017532319c 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c | |||
@@ -240,12 +240,13 @@ struct rio_priv { | |||
240 | 240 | ||
241 | static void __iomem *rio_regs_win; | 241 | static void __iomem *rio_regs_win; |
242 | 242 | ||
243 | #ifdef CONFIG_E500 | ||
243 | static int (*saved_mcheck_exception)(struct pt_regs *regs); | 244 | static int (*saved_mcheck_exception)(struct pt_regs *regs); |
244 | 245 | ||
245 | static int fsl_rio_mcheck_exception(struct pt_regs *regs) | 246 | static int fsl_rio_mcheck_exception(struct pt_regs *regs) |
246 | { | 247 | { |
247 | const struct exception_table_entry *entry = NULL; | 248 | const struct exception_table_entry *entry = NULL; |
248 | unsigned long reason = (mfspr(SPRN_MCSR) & MCSR_MASK); | 249 | unsigned long reason = mfspr(SPRN_MCSR); |
249 | 250 | ||
250 | if (reason & MCSR_BUS_RBERR) { | 251 | if (reason & MCSR_BUS_RBERR) { |
251 | reason = in_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR)); | 252 | reason = in_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR)); |
@@ -269,6 +270,7 @@ static int fsl_rio_mcheck_exception(struct pt_regs *regs) | |||
269 | else | 270 | else |
270 | return cur_cpu_spec->machine_check(regs); | 271 | return cur_cpu_spec->machine_check(regs); |
271 | } | 272 | } |
273 | #endif | ||
272 | 274 | ||
273 | /** | 275 | /** |
274 | * fsl_rio_doorbell_send - Send a MPC85xx doorbell message | 276 | * fsl_rio_doorbell_send - Send a MPC85xx doorbell message |
@@ -1517,8 +1519,10 @@ int fsl_rio_setup(struct platform_device *dev) | |||
1517 | fsl_rio_doorbell_init(port); | 1519 | fsl_rio_doorbell_init(port); |
1518 | fsl_rio_port_write_init(port); | 1520 | fsl_rio_port_write_init(port); |
1519 | 1521 | ||
1522 | #ifdef CONFIG_E500 | ||
1520 | saved_mcheck_exception = ppc_md.machine_check_exception; | 1523 | saved_mcheck_exception = ppc_md.machine_check_exception; |
1521 | ppc_md.machine_check_exception = fsl_rio_mcheck_exception; | 1524 | ppc_md.machine_check_exception = fsl_rio_mcheck_exception; |
1525 | #endif | ||
1522 | /* Ensure that RFXE is set */ | 1526 | /* Ensure that RFXE is set */ |
1523 | mtspr(SPRN_HID1, (mfspr(SPRN_HID1) | 0x20000)); | 1527 | mtspr(SPRN_HID1, (mfspr(SPRN_HID1) | 0x20000)); |
1524 | 1528 | ||
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c index 3da8014931c..90020de4dcf 100644 --- a/arch/powerpc/sysdev/qe_lib/qe.c +++ b/arch/powerpc/sysdev/qe_lib/qe.c | |||
@@ -640,6 +640,7 @@ unsigned int qe_get_num_of_snums(void) | |||
640 | if ((num_of_snums < 28) || (num_of_snums > QE_NUM_OF_SNUM)) { | 640 | if ((num_of_snums < 28) || (num_of_snums > QE_NUM_OF_SNUM)) { |
641 | /* No QE ever has fewer than 28 SNUMs */ | 641 | /* No QE ever has fewer than 28 SNUMs */ |
642 | pr_err("QE: number of snum is invalid\n"); | 642 | pr_err("QE: number of snum is invalid\n"); |
643 | of_node_put(qe); | ||
643 | return -EINVAL; | 644 | return -EINVAL; |
644 | } | 645 | } |
645 | } | 646 | } |
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 0554445200b..d17d04cfb2c 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c | |||
@@ -2880,15 +2880,14 @@ static void xmon_init(int enable) | |||
2880 | } | 2880 | } |
2881 | 2881 | ||
2882 | #ifdef CONFIG_MAGIC_SYSRQ | 2882 | #ifdef CONFIG_MAGIC_SYSRQ |
2883 | static void sysrq_handle_xmon(int key, struct tty_struct *tty) | 2883 | static void sysrq_handle_xmon(int key) |
2884 | { | 2884 | { |
2885 | /* ensure xmon is enabled */ | 2885 | /* ensure xmon is enabled */ |
2886 | xmon_init(1); | 2886 | xmon_init(1); |
2887 | debugger(get_irq_regs()); | 2887 | debugger(get_irq_regs()); |
2888 | } | 2888 | } |
2889 | 2889 | ||
2890 | static struct sysrq_key_op sysrq_xmon_op = | 2890 | static struct sysrq_key_op sysrq_xmon_op = { |
2891 | { | ||
2892 | .handler = sysrq_handle_xmon, | 2891 | .handler = sysrq_handle_xmon, |
2893 | .help_msg = "Xmon", | 2892 | .help_msg = "Xmon", |
2894 | .action_msg = "Entering xmon", | 2893 | .action_msg = "Entering xmon", |
diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h index 104f2007f09..a875c2f542e 100644 --- a/arch/s390/include/asm/compat.h +++ b/arch/s390/include/asm/compat.h | |||
@@ -181,7 +181,7 @@ static inline int is_compat_task(void) | |||
181 | 181 | ||
182 | #endif | 182 | #endif |
183 | 183 | ||
184 | static inline void __user *compat_alloc_user_space(long len) | 184 | static inline void __user *arch_compat_alloc_user_space(long len) |
185 | { | 185 | { |
186 | unsigned long stack; | 186 | unsigned long stack; |
187 | 187 | ||
diff --git a/arch/s390/include/asm/hugetlb.h b/arch/s390/include/asm/hugetlb.h index 670a1d1745d..bb8343d157b 100644 --- a/arch/s390/include/asm/hugetlb.h +++ b/arch/s390/include/asm/hugetlb.h | |||
@@ -97,6 +97,7 @@ static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm, | |||
97 | { | 97 | { |
98 | pte_t pte = huge_ptep_get(ptep); | 98 | pte_t pte = huge_ptep_get(ptep); |
99 | 99 | ||
100 | mm->context.flush_mm = 1; | ||
100 | pmd_clear((pmd_t *) ptep); | 101 | pmd_clear((pmd_t *) ptep); |
101 | return pte; | 102 | return pte; |
102 | } | 103 | } |
@@ -167,7 +168,8 @@ static inline void huge_ptep_invalidate(struct mm_struct *mm, | |||
167 | ({ \ | 168 | ({ \ |
168 | pte_t __pte = huge_ptep_get(__ptep); \ | 169 | pte_t __pte = huge_ptep_get(__ptep); \ |
169 | if (pte_write(__pte)) { \ | 170 | if (pte_write(__pte)) { \ |
170 | if (atomic_read(&(__mm)->mm_users) > 1 || \ | 171 | (__mm)->context.flush_mm = 1; \ |
172 | if (atomic_read(&(__mm)->context.attach_count) > 1 || \ | ||
171 | (__mm) != current->active_mm) \ | 173 | (__mm) != current->active_mm) \ |
172 | huge_ptep_invalidate(__mm, __addr, __ptep); \ | 174 | huge_ptep_invalidate(__mm, __addr, __ptep); \ |
173 | set_huge_pte_at(__mm, __addr, __ptep, \ | 175 | set_huge_pte_at(__mm, __addr, __ptep, \ |
diff --git a/arch/s390/include/asm/mmu.h b/arch/s390/include/asm/mmu.h index 99e3409102b..78522cdefdd 100644 --- a/arch/s390/include/asm/mmu.h +++ b/arch/s390/include/asm/mmu.h | |||
@@ -2,6 +2,8 @@ | |||
2 | #define __MMU_H | 2 | #define __MMU_H |
3 | 3 | ||
4 | typedef struct { | 4 | typedef struct { |
5 | atomic_t attach_count; | ||
6 | unsigned int flush_mm; | ||
5 | spinlock_t list_lock; | 7 | spinlock_t list_lock; |
6 | struct list_head crst_list; | 8 | struct list_head crst_list; |
7 | struct list_head pgtable_list; | 9 | struct list_head pgtable_list; |
diff --git a/arch/s390/include/asm/mmu_context.h b/arch/s390/include/asm/mmu_context.h index 976e273988c..a6f0e7cc9cd 100644 --- a/arch/s390/include/asm/mmu_context.h +++ b/arch/s390/include/asm/mmu_context.h | |||
@@ -11,11 +11,14 @@ | |||
11 | 11 | ||
12 | #include <asm/pgalloc.h> | 12 | #include <asm/pgalloc.h> |
13 | #include <asm/uaccess.h> | 13 | #include <asm/uaccess.h> |
14 | #include <asm/tlbflush.h> | ||
14 | #include <asm-generic/mm_hooks.h> | 15 | #include <asm-generic/mm_hooks.h> |
15 | 16 | ||
16 | static inline int init_new_context(struct task_struct *tsk, | 17 | static inline int init_new_context(struct task_struct *tsk, |
17 | struct mm_struct *mm) | 18 | struct mm_struct *mm) |
18 | { | 19 | { |
20 | atomic_set(&mm->context.attach_count, 0); | ||
21 | mm->context.flush_mm = 0; | ||
19 | mm->context.asce_bits = _ASCE_TABLE_LENGTH | _ASCE_USER_BITS; | 22 | mm->context.asce_bits = _ASCE_TABLE_LENGTH | _ASCE_USER_BITS; |
20 | #ifdef CONFIG_64BIT | 23 | #ifdef CONFIG_64BIT |
21 | mm->context.asce_bits |= _ASCE_TYPE_REGION3; | 24 | mm->context.asce_bits |= _ASCE_TYPE_REGION3; |
@@ -76,6 +79,12 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, | |||
76 | { | 79 | { |
77 | cpumask_set_cpu(smp_processor_id(), mm_cpumask(next)); | 80 | cpumask_set_cpu(smp_processor_id(), mm_cpumask(next)); |
78 | update_mm(next, tsk); | 81 | update_mm(next, tsk); |
82 | atomic_dec(&prev->context.attach_count); | ||
83 | WARN_ON(atomic_read(&prev->context.attach_count) < 0); | ||
84 | atomic_inc(&next->context.attach_count); | ||
85 | /* Check for TLBs not flushed yet */ | ||
86 | if (next->context.flush_mm) | ||
87 | __tlb_flush_mm(next); | ||
79 | } | 88 | } |
80 | 89 | ||
81 | #define enter_lazy_tlb(mm,tsk) do { } while (0) | 90 | #define enter_lazy_tlb(mm,tsk) do { } while (0) |
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 89a504c3f12..3157441ee1d 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h | |||
@@ -880,7 +880,8 @@ static inline void ptep_invalidate(struct mm_struct *mm, | |||
880 | #define ptep_get_and_clear(__mm, __address, __ptep) \ | 880 | #define ptep_get_and_clear(__mm, __address, __ptep) \ |
881 | ({ \ | 881 | ({ \ |
882 | pte_t __pte = *(__ptep); \ | 882 | pte_t __pte = *(__ptep); \ |
883 | if (atomic_read(&(__mm)->mm_users) > 1 || \ | 883 | (__mm)->context.flush_mm = 1; \ |
884 | if (atomic_read(&(__mm)->context.attach_count) > 1 || \ | ||
884 | (__mm) != current->active_mm) \ | 885 | (__mm) != current->active_mm) \ |
885 | ptep_invalidate(__mm, __address, __ptep); \ | 886 | ptep_invalidate(__mm, __address, __ptep); \ |
886 | else \ | 887 | else \ |
@@ -923,7 +924,8 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, | |||
923 | ({ \ | 924 | ({ \ |
924 | pte_t __pte = *(__ptep); \ | 925 | pte_t __pte = *(__ptep); \ |
925 | if (pte_write(__pte)) { \ | 926 | if (pte_write(__pte)) { \ |
926 | if (atomic_read(&(__mm)->mm_users) > 1 || \ | 927 | (__mm)->context.flush_mm = 1; \ |
928 | if (atomic_read(&(__mm)->context.attach_count) > 1 || \ | ||
927 | (__mm) != current->active_mm) \ | 929 | (__mm) != current->active_mm) \ |
928 | ptep_invalidate(__mm, __addr, __ptep); \ | 930 | ptep_invalidate(__mm, __addr, __ptep); \ |
929 | set_pte_at(__mm, __addr, __ptep, pte_wrprotect(__pte)); \ | 931 | set_pte_at(__mm, __addr, __ptep, pte_wrprotect(__pte)); \ |
diff --git a/arch/s390/include/asm/tlb.h b/arch/s390/include/asm/tlb.h index 81150b05368..fd1c00d08bf 100644 --- a/arch/s390/include/asm/tlb.h +++ b/arch/s390/include/asm/tlb.h | |||
@@ -50,8 +50,7 @@ static inline struct mmu_gather *tlb_gather_mmu(struct mm_struct *mm, | |||
50 | struct mmu_gather *tlb = &get_cpu_var(mmu_gathers); | 50 | struct mmu_gather *tlb = &get_cpu_var(mmu_gathers); |
51 | 51 | ||
52 | tlb->mm = mm; | 52 | tlb->mm = mm; |
53 | tlb->fullmm = full_mm_flush || (num_online_cpus() == 1) || | 53 | tlb->fullmm = full_mm_flush; |
54 | (atomic_read(&mm->mm_users) <= 1 && mm == current->active_mm); | ||
55 | tlb->nr_ptes = 0; | 54 | tlb->nr_ptes = 0; |
56 | tlb->nr_pxds = TLB_NR_PTRS; | 55 | tlb->nr_pxds = TLB_NR_PTRS; |
57 | if (tlb->fullmm) | 56 | if (tlb->fullmm) |
diff --git a/arch/s390/include/asm/tlbflush.h b/arch/s390/include/asm/tlbflush.h index 304cffa623e..29d5d6d4bec 100644 --- a/arch/s390/include/asm/tlbflush.h +++ b/arch/s390/include/asm/tlbflush.h | |||
@@ -94,8 +94,12 @@ static inline void __tlb_flush_mm(struct mm_struct * mm) | |||
94 | 94 | ||
95 | static inline void __tlb_flush_mm_cond(struct mm_struct * mm) | 95 | static inline void __tlb_flush_mm_cond(struct mm_struct * mm) |
96 | { | 96 | { |
97 | if (atomic_read(&mm->mm_users) <= 1 && mm == current->active_mm) | 97 | spin_lock(&mm->page_table_lock); |
98 | if (mm->context.flush_mm) { | ||
98 | __tlb_flush_mm(mm); | 99 | __tlb_flush_mm(mm); |
100 | mm->context.flush_mm = 0; | ||
101 | } | ||
102 | spin_unlock(&mm->page_table_lock); | ||
99 | } | 103 | } |
100 | 104 | ||
101 | /* | 105 | /* |
diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h index 403fb430a89..ff579b6bde0 100644 --- a/arch/s390/kernel/entry.h +++ b/arch/s390/kernel/entry.h | |||
@@ -42,8 +42,8 @@ long sys_clone(unsigned long newsp, unsigned long clone_flags, | |||
42 | int __user *parent_tidptr, int __user *child_tidptr); | 42 | int __user *parent_tidptr, int __user *child_tidptr); |
43 | long sys_vfork(void); | 43 | long sys_vfork(void); |
44 | void execve_tail(void); | 44 | void execve_tail(void); |
45 | long sys_execve(const char __user *name, char __user * __user *argv, | 45 | long sys_execve(const char __user *name, const char __user *const __user *argv, |
46 | char __user * __user *envp); | 46 | const char __user *const __user *envp); |
47 | long sys_sigsuspend(int history0, int history1, old_sigset_t mask); | 47 | long sys_sigsuspend(int history0, int history1, old_sigset_t mask); |
48 | long sys_sigaction(int sig, const struct old_sigaction __user *act, | 48 | long sys_sigaction(int sig, const struct old_sigaction __user *act, |
49 | struct old_sigaction __user *oact); | 49 | struct old_sigaction __user *oact); |
diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c index 22cfd634c35..f7167ee4604 100644 --- a/arch/s390/kernel/module.c +++ b/arch/s390/kernel/module.c | |||
@@ -407,10 +407,9 @@ int module_finalize(const Elf_Ehdr *hdr, | |||
407 | { | 407 | { |
408 | vfree(me->arch.syminfo); | 408 | vfree(me->arch.syminfo); |
409 | me->arch.syminfo = NULL; | 409 | me->arch.syminfo = NULL; |
410 | return module_bug_finalize(hdr, sechdrs, me); | 410 | return 0; |
411 | } | 411 | } |
412 | 412 | ||
413 | void module_arch_cleanup(struct module *mod) | 413 | void module_arch_cleanup(struct module *mod) |
414 | { | 414 | { |
415 | module_bug_cleanup(mod); | ||
416 | } | 415 | } |
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 541053ed234..8127ebd59c4 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
@@ -583,6 +583,7 @@ int __cpuinit __cpu_up(unsigned int cpu) | |||
583 | sf->gprs[9] = (unsigned long) sf; | 583 | sf->gprs[9] = (unsigned long) sf; |
584 | cpu_lowcore->save_area[15] = (unsigned long) sf; | 584 | cpu_lowcore->save_area[15] = (unsigned long) sf; |
585 | __ctl_store(cpu_lowcore->cregs_save_area, 0, 15); | 585 | __ctl_store(cpu_lowcore->cregs_save_area, 0, 15); |
586 | atomic_inc(&init_mm.context.attach_count); | ||
586 | asm volatile( | 587 | asm volatile( |
587 | " stam 0,15,0(%0)" | 588 | " stam 0,15,0(%0)" |
588 | : : "a" (&cpu_lowcore->access_regs_save_area) : "memory"); | 589 | : : "a" (&cpu_lowcore->access_regs_save_area) : "memory"); |
@@ -659,6 +660,7 @@ void __cpu_die(unsigned int cpu) | |||
659 | while (sigp_p(0, cpu, sigp_set_prefix) == sigp_busy) | 660 | while (sigp_p(0, cpu, sigp_set_prefix) == sigp_busy) |
660 | udelay(10); | 661 | udelay(10); |
661 | smp_free_lowcore(cpu); | 662 | smp_free_lowcore(cpu); |
663 | atomic_dec(&init_mm.context.attach_count); | ||
662 | pr_info("Processor %d stopped\n", cpu); | 664 | pr_info("Processor %d stopped\n", cpu); |
663 | } | 665 | } |
664 | 666 | ||
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index acc91c75bc9..30eb6d02ddb 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c | |||
@@ -74,6 +74,8 @@ void __init paging_init(void) | |||
74 | __ctl_load(S390_lowcore.kernel_asce, 13, 13); | 74 | __ctl_load(S390_lowcore.kernel_asce, 13, 13); |
75 | __raw_local_irq_ssm(ssm_mask); | 75 | __raw_local_irq_ssm(ssm_mask); |
76 | 76 | ||
77 | atomic_set(&init_mm.context.attach_count, 1); | ||
78 | |||
77 | sparse_memory_present_with_active_regions(MAX_NUMNODES); | 79 | sparse_memory_present_with_active_regions(MAX_NUMNODES); |
78 | sparse_init(); | 80 | sparse_init(); |
79 | memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); | 81 | memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); |
diff --git a/arch/sh/kernel/module.c b/arch/sh/kernel/module.c index 43adddfe4c0..ae0be697a89 100644 --- a/arch/sh/kernel/module.c +++ b/arch/sh/kernel/module.c | |||
@@ -149,13 +149,11 @@ int module_finalize(const Elf_Ehdr *hdr, | |||
149 | int ret = 0; | 149 | int ret = 0; |
150 | 150 | ||
151 | ret |= module_dwarf_finalize(hdr, sechdrs, me); | 151 | ret |= module_dwarf_finalize(hdr, sechdrs, me); |
152 | ret |= module_bug_finalize(hdr, sechdrs, me); | ||
153 | 152 | ||
154 | return ret; | 153 | return ret; |
155 | } | 154 | } |
156 | 155 | ||
157 | void module_arch_cleanup(struct module *mod) | 156 | void module_arch_cleanup(struct module *mod) |
158 | { | 157 | { |
159 | module_bug_cleanup(mod); | ||
160 | module_dwarf_cleanup(mod); | 158 | module_dwarf_cleanup(mod); |
161 | } | 159 | } |
diff --git a/arch/sparc/include/asm/atomic_64.h b/arch/sparc/include/asm/atomic_64.h index f0c74227c73..bdb2ff880bd 100644 --- a/arch/sparc/include/asm/atomic_64.h +++ b/arch/sparc/include/asm/atomic_64.h | |||
@@ -20,14 +20,14 @@ | |||
20 | #define atomic64_set(v, i) (((v)->counter) = i) | 20 | #define atomic64_set(v, i) (((v)->counter) = i) |
21 | 21 | ||
22 | extern void atomic_add(int, atomic_t *); | 22 | extern void atomic_add(int, atomic_t *); |
23 | extern void atomic64_add(int, atomic64_t *); | 23 | extern void atomic64_add(long, atomic64_t *); |
24 | extern void atomic_sub(int, atomic_t *); | 24 | extern void atomic_sub(int, atomic_t *); |
25 | extern void atomic64_sub(int, atomic64_t *); | 25 | extern void atomic64_sub(long, atomic64_t *); |
26 | 26 | ||
27 | extern int atomic_add_ret(int, atomic_t *); | 27 | extern int atomic_add_ret(int, atomic_t *); |
28 | extern long atomic64_add_ret(int, atomic64_t *); | 28 | extern long atomic64_add_ret(long, atomic64_t *); |
29 | extern int atomic_sub_ret(int, atomic_t *); | 29 | extern int atomic_sub_ret(int, atomic_t *); |
30 | extern long atomic64_sub_ret(int, atomic64_t *); | 30 | extern long atomic64_sub_ret(long, atomic64_t *); |
31 | 31 | ||
32 | #define atomic_dec_return(v) atomic_sub_ret(1, v) | 32 | #define atomic_dec_return(v) atomic_sub_ret(1, v) |
33 | #define atomic64_dec_return(v) atomic64_sub_ret(1, v) | 33 | #define atomic64_dec_return(v) atomic64_sub_ret(1, v) |
diff --git a/arch/sparc/include/asm/backoff.h b/arch/sparc/include/asm/backoff.h index fa1fdf67e35..db3af0d30fb 100644 --- a/arch/sparc/include/asm/backoff.h +++ b/arch/sparc/include/asm/backoff.h | |||
@@ -8,6 +8,9 @@ | |||
8 | #define BACKOFF_SETUP(reg) \ | 8 | #define BACKOFF_SETUP(reg) \ |
9 | mov 1, reg | 9 | mov 1, reg |
10 | 10 | ||
11 | #define BACKOFF_LABEL(spin_label, continue_label) \ | ||
12 | spin_label | ||
13 | |||
11 | #define BACKOFF_SPIN(reg, tmp, label) \ | 14 | #define BACKOFF_SPIN(reg, tmp, label) \ |
12 | mov reg, tmp; \ | 15 | mov reg, tmp; \ |
13 | 88: brnz,pt tmp, 88b; \ | 16 | 88: brnz,pt tmp, 88b; \ |
@@ -22,9 +25,11 @@ | |||
22 | #else | 25 | #else |
23 | 26 | ||
24 | #define BACKOFF_SETUP(reg) | 27 | #define BACKOFF_SETUP(reg) |
25 | #define BACKOFF_SPIN(reg, tmp, label) \ | 28 | |
26 | ba,pt %xcc, label; \ | 29 | #define BACKOFF_LABEL(spin_label, continue_label) \ |
27 | nop; | 30 | continue_label |
31 | |||
32 | #define BACKOFF_SPIN(reg, tmp, label) | ||
28 | 33 | ||
29 | #endif | 34 | #endif |
30 | 35 | ||
diff --git a/arch/sparc/include/asm/compat.h b/arch/sparc/include/asm/compat.h index 5016f76ea98..6f57325bb88 100644 --- a/arch/sparc/include/asm/compat.h +++ b/arch/sparc/include/asm/compat.h | |||
@@ -167,7 +167,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) | |||
167 | return (u32)(unsigned long)uptr; | 167 | return (u32)(unsigned long)uptr; |
168 | } | 168 | } |
169 | 169 | ||
170 | static inline void __user *compat_alloc_user_space(long len) | 170 | static inline void __user *arch_compat_alloc_user_space(long len) |
171 | { | 171 | { |
172 | struct pt_regs *regs = current_thread_info()->kregs; | 172 | struct pt_regs *regs = current_thread_info()->kregs; |
173 | unsigned long usp = regs->u_regs[UREG_I6]; | 173 | unsigned long usp = regs->u_regs[UREG_I6]; |
diff --git a/arch/sparc/include/asm/oplib_64.h b/arch/sparc/include/asm/oplib_64.h index a5db0317b5f..3e0b2d62303 100644 --- a/arch/sparc/include/asm/oplib_64.h +++ b/arch/sparc/include/asm/oplib_64.h | |||
@@ -185,9 +185,8 @@ extern int prom_getunumber(int syndrome_code, | |||
185 | char *buf, int buflen); | 185 | char *buf, int buflen); |
186 | 186 | ||
187 | /* Retain physical memory to the caller across soft resets. */ | 187 | /* Retain physical memory to the caller across soft resets. */ |
188 | extern unsigned long prom_retain(const char *name, | 188 | extern int prom_retain(const char *name, unsigned long size, |
189 | unsigned long pa_low, unsigned long pa_high, | 189 | unsigned long align, unsigned long *paddr); |
190 | long size, long align); | ||
191 | 190 | ||
192 | /* Load explicit I/D TLB entries into the calling processor. */ | 191 | /* Load explicit I/D TLB entries into the calling processor. */ |
193 | extern long prom_itlb_load(unsigned long index, | 192 | extern long prom_itlb_load(unsigned long index, |
@@ -287,26 +286,6 @@ extern void prom_sun4v_guest_soft_state(void); | |||
287 | extern int prom_ihandle2path(int handle, char *buffer, int bufsize); | 286 | extern int prom_ihandle2path(int handle, char *buffer, int bufsize); |
288 | 287 | ||
289 | /* Client interface level routines. */ | 288 | /* Client interface level routines. */ |
290 | extern long p1275_cmd(const char *, long, ...); | 289 | extern void p1275_cmd_direct(unsigned long *); |
291 | |||
292 | #if 0 | ||
293 | #define P1275_SIZE(x) ((((long)((x) / 32)) << 32) | (x)) | ||
294 | #else | ||
295 | #define P1275_SIZE(x) x | ||
296 | #endif | ||
297 | |||
298 | /* We support at most 16 input and 1 output argument */ | ||
299 | #define P1275_ARG_NUMBER 0 | ||
300 | #define P1275_ARG_IN_STRING 1 | ||
301 | #define P1275_ARG_OUT_BUF 2 | ||
302 | #define P1275_ARG_OUT_32B 3 | ||
303 | #define P1275_ARG_IN_FUNCTION 4 | ||
304 | #define P1275_ARG_IN_BUF 5 | ||
305 | #define P1275_ARG_IN_64B 6 | ||
306 | |||
307 | #define P1275_IN(x) ((x) & 0xf) | ||
308 | #define P1275_OUT(x) (((x) << 4) & 0xf0) | ||
309 | #define P1275_INOUT(i,o) (P1275_IN(i)|P1275_OUT(o)) | ||
310 | #define P1275_ARG(n,x) ((x) << ((n)*3 + 8)) | ||
311 | 290 | ||
312 | #endif /* !(__SPARC64_OPLIB_H) */ | 291 | #endif /* !(__SPARC64_OPLIB_H) */ |
diff --git a/arch/sparc/include/asm/rwsem-const.h b/arch/sparc/include/asm/rwsem-const.h deleted file mode 100644 index e4c61a18bb2..00000000000 --- a/arch/sparc/include/asm/rwsem-const.h +++ /dev/null | |||
@@ -1,12 +0,0 @@ | |||
1 | /* rwsem-const.h: RW semaphore counter constants. */ | ||
2 | #ifndef _SPARC64_RWSEM_CONST_H | ||
3 | #define _SPARC64_RWSEM_CONST_H | ||
4 | |||
5 | #define RWSEM_UNLOCKED_VALUE 0x00000000 | ||
6 | #define RWSEM_ACTIVE_BIAS 0x00000001 | ||
7 | #define RWSEM_ACTIVE_MASK 0x0000ffff | ||
8 | #define RWSEM_WAITING_BIAS (-0x00010000) | ||
9 | #define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS | ||
10 | #define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) | ||
11 | |||
12 | #endif /* _SPARC64_RWSEM_CONST_H */ | ||
diff --git a/arch/sparc/include/asm/rwsem.h b/arch/sparc/include/asm/rwsem.h index 6e5621006f8..a2b4302869b 100644 --- a/arch/sparc/include/asm/rwsem.h +++ b/arch/sparc/include/asm/rwsem.h | |||
@@ -15,16 +15,21 @@ | |||
15 | 15 | ||
16 | #include <linux/list.h> | 16 | #include <linux/list.h> |
17 | #include <linux/spinlock.h> | 17 | #include <linux/spinlock.h> |
18 | #include <asm/rwsem-const.h> | ||
19 | 18 | ||
20 | struct rwsem_waiter; | 19 | struct rwsem_waiter; |
21 | 20 | ||
22 | struct rw_semaphore { | 21 | struct rw_semaphore { |
23 | signed int count; | 22 | signed long count; |
24 | spinlock_t wait_lock; | 23 | #define RWSEM_UNLOCKED_VALUE 0x00000000L |
25 | struct list_head wait_list; | 24 | #define RWSEM_ACTIVE_BIAS 0x00000001L |
25 | #define RWSEM_ACTIVE_MASK 0xffffffffL | ||
26 | #define RWSEM_WAITING_BIAS (-RWSEM_ACTIVE_MASK-1) | ||
27 | #define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS | ||
28 | #define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) | ||
29 | spinlock_t wait_lock; | ||
30 | struct list_head wait_list; | ||
26 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 31 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
27 | struct lockdep_map dep_map; | 32 | struct lockdep_map dep_map; |
28 | #endif | 33 | #endif |
29 | }; | 34 | }; |
30 | 35 | ||
@@ -41,6 +46,11 @@ struct rw_semaphore { | |||
41 | #define DECLARE_RWSEM(name) \ | 46 | #define DECLARE_RWSEM(name) \ |
42 | struct rw_semaphore name = __RWSEM_INITIALIZER(name) | 47 | struct rw_semaphore name = __RWSEM_INITIALIZER(name) |
43 | 48 | ||
49 | extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem); | ||
50 | extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem); | ||
51 | extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem); | ||
52 | extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem); | ||
53 | |||
44 | extern void __init_rwsem(struct rw_semaphore *sem, const char *name, | 54 | extern void __init_rwsem(struct rw_semaphore *sem, const char *name, |
45 | struct lock_class_key *key); | 55 | struct lock_class_key *key); |
46 | 56 | ||
@@ -51,27 +61,103 @@ do { \ | |||
51 | __init_rwsem((sem), #sem, &__key); \ | 61 | __init_rwsem((sem), #sem, &__key); \ |
52 | } while (0) | 62 | } while (0) |
53 | 63 | ||
54 | extern void __down_read(struct rw_semaphore *sem); | 64 | /* |
55 | extern int __down_read_trylock(struct rw_semaphore *sem); | 65 | * lock for reading |
56 | extern void __down_write(struct rw_semaphore *sem); | 66 | */ |
57 | extern int __down_write_trylock(struct rw_semaphore *sem); | 67 | static inline void __down_read(struct rw_semaphore *sem) |
58 | extern void __up_read(struct rw_semaphore *sem); | 68 | { |
59 | extern void __up_write(struct rw_semaphore *sem); | 69 | if (unlikely(atomic64_inc_return((atomic64_t *)(&sem->count)) <= 0L)) |
60 | extern void __downgrade_write(struct rw_semaphore *sem); | 70 | rwsem_down_read_failed(sem); |
71 | } | ||
72 | |||
73 | static inline int __down_read_trylock(struct rw_semaphore *sem) | ||
74 | { | ||
75 | long tmp; | ||
76 | |||
77 | while ((tmp = sem->count) >= 0L) { | ||
78 | if (tmp == cmpxchg(&sem->count, tmp, | ||
79 | tmp + RWSEM_ACTIVE_READ_BIAS)) { | ||
80 | return 1; | ||
81 | } | ||
82 | } | ||
83 | return 0; | ||
84 | } | ||
61 | 85 | ||
86 | /* | ||
87 | * lock for writing | ||
88 | */ | ||
62 | static inline void __down_write_nested(struct rw_semaphore *sem, int subclass) | 89 | static inline void __down_write_nested(struct rw_semaphore *sem, int subclass) |
63 | { | 90 | { |
64 | __down_write(sem); | 91 | long tmp; |
92 | |||
93 | tmp = atomic64_add_return(RWSEM_ACTIVE_WRITE_BIAS, | ||
94 | (atomic64_t *)(&sem->count)); | ||
95 | if (unlikely(tmp != RWSEM_ACTIVE_WRITE_BIAS)) | ||
96 | rwsem_down_write_failed(sem); | ||
65 | } | 97 | } |
66 | 98 | ||
67 | static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem) | 99 | static inline void __down_write(struct rw_semaphore *sem) |
68 | { | 100 | { |
69 | return atomic_add_return(delta, (atomic_t *)(&sem->count)); | 101 | __down_write_nested(sem, 0); |
102 | } | ||
103 | |||
104 | static inline int __down_write_trylock(struct rw_semaphore *sem) | ||
105 | { | ||
106 | long tmp; | ||
107 | |||
108 | tmp = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE, | ||
109 | RWSEM_ACTIVE_WRITE_BIAS); | ||
110 | return tmp == RWSEM_UNLOCKED_VALUE; | ||
70 | } | 111 | } |
71 | 112 | ||
72 | static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem) | 113 | /* |
114 | * unlock after reading | ||
115 | */ | ||
116 | static inline void __up_read(struct rw_semaphore *sem) | ||
117 | { | ||
118 | long tmp; | ||
119 | |||
120 | tmp = atomic64_dec_return((atomic64_t *)(&sem->count)); | ||
121 | if (unlikely(tmp < -1L && (tmp & RWSEM_ACTIVE_MASK) == 0L)) | ||
122 | rwsem_wake(sem); | ||
123 | } | ||
124 | |||
125 | /* | ||
126 | * unlock after writing | ||
127 | */ | ||
128 | static inline void __up_write(struct rw_semaphore *sem) | ||
129 | { | ||
130 | if (unlikely(atomic64_sub_return(RWSEM_ACTIVE_WRITE_BIAS, | ||
131 | (atomic64_t *)(&sem->count)) < 0L)) | ||
132 | rwsem_wake(sem); | ||
133 | } | ||
134 | |||
135 | /* | ||
136 | * implement atomic add functionality | ||
137 | */ | ||
138 | static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem) | ||
139 | { | ||
140 | atomic64_add(delta, (atomic64_t *)(&sem->count)); | ||
141 | } | ||
142 | |||
143 | /* | ||
144 | * downgrade write lock to read lock | ||
145 | */ | ||
146 | static inline void __downgrade_write(struct rw_semaphore *sem) | ||
147 | { | ||
148 | long tmp; | ||
149 | |||
150 | tmp = atomic64_add_return(-RWSEM_WAITING_BIAS, (atomic64_t *)(&sem->count)); | ||
151 | if (tmp < 0L) | ||
152 | rwsem_downgrade_wake(sem); | ||
153 | } | ||
154 | |||
155 | /* | ||
156 | * implement exchange and add functionality | ||
157 | */ | ||
158 | static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem) | ||
73 | { | 159 | { |
74 | atomic_add(delta, (atomic_t *)(&sem->count)); | 160 | return atomic64_add_return(delta, (atomic64_t *)(&sem->count)); |
75 | } | 161 | } |
76 | 162 | ||
77 | static inline int rwsem_is_locked(struct rw_semaphore *sem) | 163 | static inline int rwsem_is_locked(struct rw_semaphore *sem) |
diff --git a/arch/sparc/include/asm/system_64.h b/arch/sparc/include/asm/system_64.h index d24cfe16afc..e3b65d8cf41 100644 --- a/arch/sparc/include/asm/system_64.h +++ b/arch/sparc/include/asm/system_64.h | |||
@@ -106,6 +106,7 @@ do { __asm__ __volatile__("ba,pt %%xcc, 1f\n\t" \ | |||
106 | */ | 106 | */ |
107 | #define write_pic(__p) \ | 107 | #define write_pic(__p) \ |
108 | __asm__ __volatile__("ba,pt %%xcc, 99f\n\t" \ | 108 | __asm__ __volatile__("ba,pt %%xcc, 99f\n\t" \ |
109 | " nop\n\t" \ | ||
109 | ".align 64\n" \ | 110 | ".align 64\n" \ |
110 | "99:wr %0, 0x0, %%pic\n\t" \ | 111 | "99:wr %0, 0x0, %%pic\n\t" \ |
111 | "rd %%pic, %%g0" : : "r" (__p)) | 112 | "rd %%pic, %%g0" : : "r" (__p)) |
diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c index 357ced3c33f..6318e622cfb 100644 --- a/arch/sparc/kernel/perf_event.c +++ b/arch/sparc/kernel/perf_event.c | |||
@@ -1038,6 +1038,7 @@ static int __hw_perf_event_init(struct perf_event *event) | |||
1038 | if (atomic_read(&nmi_active) < 0) | 1038 | if (atomic_read(&nmi_active) < 0) |
1039 | return -ENODEV; | 1039 | return -ENODEV; |
1040 | 1040 | ||
1041 | pmap = NULL; | ||
1041 | if (attr->type == PERF_TYPE_HARDWARE) { | 1042 | if (attr->type == PERF_TYPE_HARDWARE) { |
1042 | if (attr->config >= sparc_pmu->max_events) | 1043 | if (attr->config >= sparc_pmu->max_events) |
1043 | return -EINVAL; | 1044 | return -EINVAL; |
@@ -1046,9 +1047,18 @@ static int __hw_perf_event_init(struct perf_event *event) | |||
1046 | pmap = sparc_map_cache_event(attr->config); | 1047 | pmap = sparc_map_cache_event(attr->config); |
1047 | if (IS_ERR(pmap)) | 1048 | if (IS_ERR(pmap)) |
1048 | return PTR_ERR(pmap); | 1049 | return PTR_ERR(pmap); |
1049 | } else | 1050 | } else if (attr->type != PERF_TYPE_RAW) |
1050 | return -EOPNOTSUPP; | 1051 | return -EOPNOTSUPP; |
1051 | 1052 | ||
1053 | if (pmap) { | ||
1054 | hwc->event_base = perf_event_encode(pmap); | ||
1055 | } else { | ||
1056 | /* User gives us "(encoding << 16) | pic_mask" for | ||
1057 | * PERF_TYPE_RAW events. | ||
1058 | */ | ||
1059 | hwc->event_base = attr->config; | ||
1060 | } | ||
1061 | |||
1052 | /* We save the enable bits in the config_base. */ | 1062 | /* We save the enable bits in the config_base. */ |
1053 | hwc->config_base = sparc_pmu->irq_bit; | 1063 | hwc->config_base = sparc_pmu->irq_bit; |
1054 | if (!attr->exclude_user) | 1064 | if (!attr->exclude_user) |
@@ -1058,8 +1068,6 @@ static int __hw_perf_event_init(struct perf_event *event) | |||
1058 | if (!attr->exclude_hv) | 1068 | if (!attr->exclude_hv) |
1059 | hwc->config_base |= sparc_pmu->hv_bit; | 1069 | hwc->config_base |= sparc_pmu->hv_bit; |
1060 | 1070 | ||
1061 | hwc->event_base = perf_event_encode(pmap); | ||
1062 | |||
1063 | n = 0; | 1071 | n = 0; |
1064 | if (event->group_leader != event) { | 1072 | if (event->group_leader != event) { |
1065 | n = collect_events(event->group_leader, | 1073 | n = collect_events(event->group_leader, |
diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c index 485f5474838..c158a95ec66 100644 --- a/arch/sparc/kernel/process_64.c +++ b/arch/sparc/kernel/process_64.c | |||
@@ -303,7 +303,7 @@ void arch_trigger_all_cpu_backtrace(void) | |||
303 | 303 | ||
304 | #ifdef CONFIG_MAGIC_SYSRQ | 304 | #ifdef CONFIG_MAGIC_SYSRQ |
305 | 305 | ||
306 | static void sysrq_handle_globreg(int key, struct tty_struct *tty) | 306 | static void sysrq_handle_globreg(int key) |
307 | { | 307 | { |
308 | arch_trigger_all_cpu_backtrace(); | 308 | arch_trigger_all_cpu_backtrace(); |
309 | } | 309 | } |
diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c index ea22cd373c6..75fad425e24 100644 --- a/arch/sparc/kernel/signal32.c +++ b/arch/sparc/kernel/signal32.c | |||
@@ -453,8 +453,66 @@ static int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) | |||
453 | return err; | 453 | return err; |
454 | } | 454 | } |
455 | 455 | ||
456 | static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, | 456 | /* The I-cache flush instruction only works in the primary ASI, which |
457 | int signo, sigset_t *oldset) | 457 | * right now is the nucleus, aka. kernel space. |
458 | * | ||
459 | * Therefore we have to kick the instructions out using the kernel | ||
460 | * side linear mapping of the physical address backing the user | ||
461 | * instructions. | ||
462 | */ | ||
463 | static void flush_signal_insns(unsigned long address) | ||
464 | { | ||
465 | unsigned long pstate, paddr; | ||
466 | pte_t *ptep, pte; | ||
467 | pgd_t *pgdp; | ||
468 | pud_t *pudp; | ||
469 | pmd_t *pmdp; | ||
470 | |||
471 | /* Commit all stores of the instructions we are about to flush. */ | ||
472 | wmb(); | ||
473 | |||
474 | /* Disable cross-call reception. In this way even a very wide | ||
475 | * munmap() on another cpu can't tear down the page table | ||
476 | * hierarchy from underneath us, since that can't complete | ||
477 | * until the IPI tlb flush returns. | ||
478 | */ | ||
479 | |||
480 | __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate)); | ||
481 | __asm__ __volatile__("wrpr %0, %1, %%pstate" | ||
482 | : : "r" (pstate), "i" (PSTATE_IE)); | ||
483 | |||
484 | pgdp = pgd_offset(current->mm, address); | ||
485 | if (pgd_none(*pgdp)) | ||
486 | goto out_irqs_on; | ||
487 | pudp = pud_offset(pgdp, address); | ||
488 | if (pud_none(*pudp)) | ||
489 | goto out_irqs_on; | ||
490 | pmdp = pmd_offset(pudp, address); | ||
491 | if (pmd_none(*pmdp)) | ||
492 | goto out_irqs_on; | ||
493 | |||
494 | ptep = pte_offset_map(pmdp, address); | ||
495 | pte = *ptep; | ||
496 | if (!pte_present(pte)) | ||
497 | goto out_unmap; | ||
498 | |||
499 | paddr = (unsigned long) page_address(pte_page(pte)); | ||
500 | |||
501 | __asm__ __volatile__("flush %0 + %1" | ||
502 | : /* no outputs */ | ||
503 | : "r" (paddr), | ||
504 | "r" (address & (PAGE_SIZE - 1)) | ||
505 | : "memory"); | ||
506 | |||
507 | out_unmap: | ||
508 | pte_unmap(ptep); | ||
509 | out_irqs_on: | ||
510 | __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate)); | ||
511 | |||
512 | } | ||
513 | |||
514 | static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, | ||
515 | int signo, sigset_t *oldset) | ||
458 | { | 516 | { |
459 | struct signal_frame32 __user *sf; | 517 | struct signal_frame32 __user *sf; |
460 | int sigframe_size; | 518 | int sigframe_size; |
@@ -547,13 +605,7 @@ static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, | |||
547 | if (ka->ka_restorer) { | 605 | if (ka->ka_restorer) { |
548 | regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; | 606 | regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; |
549 | } else { | 607 | } else { |
550 | /* Flush instruction space. */ | ||
551 | unsigned long address = ((unsigned long)&(sf->insns[0])); | 608 | unsigned long address = ((unsigned long)&(sf->insns[0])); |
552 | pgd_t *pgdp = pgd_offset(current->mm, address); | ||
553 | pud_t *pudp = pud_offset(pgdp, address); | ||
554 | pmd_t *pmdp = pmd_offset(pudp, address); | ||
555 | pte_t *ptep; | ||
556 | pte_t pte; | ||
557 | 609 | ||
558 | regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2); | 610 | regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2); |
559 | 611 | ||
@@ -562,34 +614,22 @@ static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, | |||
562 | if (err) | 614 | if (err) |
563 | goto sigsegv; | 615 | goto sigsegv; |
564 | 616 | ||
565 | preempt_disable(); | 617 | flush_signal_insns(address); |
566 | ptep = pte_offset_map(pmdp, address); | ||
567 | pte = *ptep; | ||
568 | if (pte_present(pte)) { | ||
569 | unsigned long page = (unsigned long) | ||
570 | page_address(pte_page(pte)); | ||
571 | |||
572 | wmb(); | ||
573 | __asm__ __volatile__("flush %0 + %1" | ||
574 | : /* no outputs */ | ||
575 | : "r" (page), | ||
576 | "r" (address & (PAGE_SIZE - 1)) | ||
577 | : "memory"); | ||
578 | } | ||
579 | pte_unmap(ptep); | ||
580 | preempt_enable(); | ||
581 | } | 618 | } |
582 | return; | 619 | return 0; |
583 | 620 | ||
584 | sigill: | 621 | sigill: |
585 | do_exit(SIGILL); | 622 | do_exit(SIGILL); |
623 | return -EINVAL; | ||
624 | |||
586 | sigsegv: | 625 | sigsegv: |
587 | force_sigsegv(signo, current); | 626 | force_sigsegv(signo, current); |
627 | return -EFAULT; | ||
588 | } | 628 | } |
589 | 629 | ||
590 | static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, | 630 | static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, |
591 | unsigned long signr, sigset_t *oldset, | 631 | unsigned long signr, sigset_t *oldset, |
592 | siginfo_t *info) | 632 | siginfo_t *info) |
593 | { | 633 | { |
594 | struct rt_signal_frame32 __user *sf; | 634 | struct rt_signal_frame32 __user *sf; |
595 | int sigframe_size; | 635 | int sigframe_size; |
@@ -687,12 +727,7 @@ static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, | |||
687 | if (ka->ka_restorer) | 727 | if (ka->ka_restorer) |
688 | regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; | 728 | regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; |
689 | else { | 729 | else { |
690 | /* Flush instruction space. */ | ||
691 | unsigned long address = ((unsigned long)&(sf->insns[0])); | 730 | unsigned long address = ((unsigned long)&(sf->insns[0])); |
692 | pgd_t *pgdp = pgd_offset(current->mm, address); | ||
693 | pud_t *pudp = pud_offset(pgdp, address); | ||
694 | pmd_t *pmdp = pmd_offset(pudp, address); | ||
695 | pte_t *ptep; | ||
696 | 731 | ||
697 | regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2); | 732 | regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2); |
698 | 733 | ||
@@ -704,38 +739,32 @@ static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, | |||
704 | if (err) | 739 | if (err) |
705 | goto sigsegv; | 740 | goto sigsegv; |
706 | 741 | ||
707 | preempt_disable(); | 742 | flush_signal_insns(address); |
708 | ptep = pte_offset_map(pmdp, address); | ||
709 | if (pte_present(*ptep)) { | ||
710 | unsigned long page = (unsigned long) | ||
711 | page_address(pte_page(*ptep)); | ||
712 | |||
713 | wmb(); | ||
714 | __asm__ __volatile__("flush %0 + %1" | ||
715 | : /* no outputs */ | ||
716 | : "r" (page), | ||
717 | "r" (address & (PAGE_SIZE - 1)) | ||
718 | : "memory"); | ||
719 | } | ||
720 | pte_unmap(ptep); | ||
721 | preempt_enable(); | ||
722 | } | 743 | } |
723 | return; | 744 | return 0; |
724 | 745 | ||
725 | sigill: | 746 | sigill: |
726 | do_exit(SIGILL); | 747 | do_exit(SIGILL); |
748 | return -EINVAL; | ||
749 | |||
727 | sigsegv: | 750 | sigsegv: |
728 | force_sigsegv(signr, current); | 751 | force_sigsegv(signr, current); |
752 | return -EFAULT; | ||
729 | } | 753 | } |
730 | 754 | ||
731 | static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka, | 755 | static inline int handle_signal32(unsigned long signr, struct k_sigaction *ka, |
732 | siginfo_t *info, | 756 | siginfo_t *info, |
733 | sigset_t *oldset, struct pt_regs *regs) | 757 | sigset_t *oldset, struct pt_regs *regs) |
734 | { | 758 | { |
759 | int err; | ||
760 | |||
735 | if (ka->sa.sa_flags & SA_SIGINFO) | 761 | if (ka->sa.sa_flags & SA_SIGINFO) |
736 | setup_rt_frame32(ka, regs, signr, oldset, info); | 762 | err = setup_rt_frame32(ka, regs, signr, oldset, info); |
737 | else | 763 | else |
738 | setup_frame32(ka, regs, signr, oldset); | 764 | err = setup_frame32(ka, regs, signr, oldset); |
765 | |||
766 | if (err) | ||
767 | return err; | ||
739 | 768 | ||
740 | spin_lock_irq(¤t->sighand->siglock); | 769 | spin_lock_irq(¤t->sighand->siglock); |
741 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 770 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
@@ -743,6 +772,10 @@ static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka, | |||
743 | sigaddset(¤t->blocked,signr); | 772 | sigaddset(¤t->blocked,signr); |
744 | recalc_sigpending(); | 773 | recalc_sigpending(); |
745 | spin_unlock_irq(¤t->sighand->siglock); | 774 | spin_unlock_irq(¤t->sighand->siglock); |
775 | |||
776 | tracehook_signal_handler(signr, info, ka, regs, 0); | ||
777 | |||
778 | return 0; | ||
746 | } | 779 | } |
747 | 780 | ||
748 | static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs, | 781 | static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs, |
@@ -789,16 +822,14 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs, | |||
789 | if (signr > 0) { | 822 | if (signr > 0) { |
790 | if (restart_syscall) | 823 | if (restart_syscall) |
791 | syscall_restart32(orig_i0, regs, &ka.sa); | 824 | syscall_restart32(orig_i0, regs, &ka.sa); |
792 | handle_signal32(signr, &ka, &info, oldset, regs); | 825 | if (handle_signal32(signr, &ka, &info, oldset, regs) == 0) { |
793 | 826 | /* A signal was successfully delivered; the saved | |
794 | /* A signal was successfully delivered; the saved | 827 | * sigmask will have been stored in the signal frame, |
795 | * sigmask will have been stored in the signal frame, | 828 | * and will be restored by sigreturn, so we can simply |
796 | * and will be restored by sigreturn, so we can simply | 829 | * clear the TS_RESTORE_SIGMASK flag. |
797 | * clear the TS_RESTORE_SIGMASK flag. | 830 | */ |
798 | */ | 831 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; |
799 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; | 832 | } |
800 | |||
801 | tracehook_signal_handler(signr, &info, &ka, regs, 0); | ||
802 | return; | 833 | return; |
803 | } | 834 | } |
804 | if (restart_syscall && | 835 | if (restart_syscall && |
@@ -809,12 +840,14 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs, | |||
809 | regs->u_regs[UREG_I0] = orig_i0; | 840 | regs->u_regs[UREG_I0] = orig_i0; |
810 | regs->tpc -= 4; | 841 | regs->tpc -= 4; |
811 | regs->tnpc -= 4; | 842 | regs->tnpc -= 4; |
843 | pt_regs_clear_syscall(regs); | ||
812 | } | 844 | } |
813 | if (restart_syscall && | 845 | if (restart_syscall && |
814 | regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { | 846 | regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { |
815 | regs->u_regs[UREG_G1] = __NR_restart_syscall; | 847 | regs->u_regs[UREG_G1] = __NR_restart_syscall; |
816 | regs->tpc -= 4; | 848 | regs->tpc -= 4; |
817 | regs->tnpc -= 4; | 849 | regs->tnpc -= 4; |
850 | pt_regs_clear_syscall(regs); | ||
818 | } | 851 | } |
819 | 852 | ||
820 | /* If there's no signal to deliver, we just put the saved sigmask | 853 | /* If there's no signal to deliver, we just put the saved sigmask |
diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c index 9882df92ba0..5e5c5fd0378 100644 --- a/arch/sparc/kernel/signal_32.c +++ b/arch/sparc/kernel/signal_32.c | |||
@@ -315,8 +315,8 @@ save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) | |||
315 | return err; | 315 | return err; |
316 | } | 316 | } |
317 | 317 | ||
318 | static void setup_frame(struct k_sigaction *ka, struct pt_regs *regs, | 318 | static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs, |
319 | int signo, sigset_t *oldset) | 319 | int signo, sigset_t *oldset) |
320 | { | 320 | { |
321 | struct signal_frame __user *sf; | 321 | struct signal_frame __user *sf; |
322 | int sigframe_size, err; | 322 | int sigframe_size, err; |
@@ -384,16 +384,19 @@ static void setup_frame(struct k_sigaction *ka, struct pt_regs *regs, | |||
384 | /* Flush instruction space. */ | 384 | /* Flush instruction space. */ |
385 | flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0])); | 385 | flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0])); |
386 | } | 386 | } |
387 | return; | 387 | return 0; |
388 | 388 | ||
389 | sigill_and_return: | 389 | sigill_and_return: |
390 | do_exit(SIGILL); | 390 | do_exit(SIGILL); |
391 | return -EINVAL; | ||
392 | |||
391 | sigsegv: | 393 | sigsegv: |
392 | force_sigsegv(signo, current); | 394 | force_sigsegv(signo, current); |
395 | return -EFAULT; | ||
393 | } | 396 | } |
394 | 397 | ||
395 | static void setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, | 398 | static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, |
396 | int signo, sigset_t *oldset, siginfo_t *info) | 399 | int signo, sigset_t *oldset, siginfo_t *info) |
397 | { | 400 | { |
398 | struct rt_signal_frame __user *sf; | 401 | struct rt_signal_frame __user *sf; |
399 | int sigframe_size; | 402 | int sigframe_size; |
@@ -466,22 +469,30 @@ static void setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, | |||
466 | /* Flush instruction space. */ | 469 | /* Flush instruction space. */ |
467 | flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0])); | 470 | flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0])); |
468 | } | 471 | } |
469 | return; | 472 | return 0; |
470 | 473 | ||
471 | sigill: | 474 | sigill: |
472 | do_exit(SIGILL); | 475 | do_exit(SIGILL); |
476 | return -EINVAL; | ||
477 | |||
473 | sigsegv: | 478 | sigsegv: |
474 | force_sigsegv(signo, current); | 479 | force_sigsegv(signo, current); |
480 | return -EFAULT; | ||
475 | } | 481 | } |
476 | 482 | ||
477 | static inline void | 483 | static inline int |
478 | handle_signal(unsigned long signr, struct k_sigaction *ka, | 484 | handle_signal(unsigned long signr, struct k_sigaction *ka, |
479 | siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) | 485 | siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) |
480 | { | 486 | { |
487 | int err; | ||
488 | |||
481 | if (ka->sa.sa_flags & SA_SIGINFO) | 489 | if (ka->sa.sa_flags & SA_SIGINFO) |
482 | setup_rt_frame(ka, regs, signr, oldset, info); | 490 | err = setup_rt_frame(ka, regs, signr, oldset, info); |
483 | else | 491 | else |
484 | setup_frame(ka, regs, signr, oldset); | 492 | err = setup_frame(ka, regs, signr, oldset); |
493 | |||
494 | if (err) | ||
495 | return err; | ||
485 | 496 | ||
486 | spin_lock_irq(¤t->sighand->siglock); | 497 | spin_lock_irq(¤t->sighand->siglock); |
487 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 498 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
@@ -489,6 +500,10 @@ handle_signal(unsigned long signr, struct k_sigaction *ka, | |||
489 | sigaddset(¤t->blocked, signr); | 500 | sigaddset(¤t->blocked, signr); |
490 | recalc_sigpending(); | 501 | recalc_sigpending(); |
491 | spin_unlock_irq(¤t->sighand->siglock); | 502 | spin_unlock_irq(¤t->sighand->siglock); |
503 | |||
504 | tracehook_signal_handler(signr, info, ka, regs, 0); | ||
505 | |||
506 | return 0; | ||
492 | } | 507 | } |
493 | 508 | ||
494 | static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, | 509 | static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, |
@@ -546,17 +561,15 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) | |||
546 | if (signr > 0) { | 561 | if (signr > 0) { |
547 | if (restart_syscall) | 562 | if (restart_syscall) |
548 | syscall_restart(orig_i0, regs, &ka.sa); | 563 | syscall_restart(orig_i0, regs, &ka.sa); |
549 | handle_signal(signr, &ka, &info, oldset, regs); | 564 | if (handle_signal(signr, &ka, &info, oldset, regs) == 0) { |
550 | 565 | /* a signal was successfully delivered; the saved | |
551 | /* a signal was successfully delivered; the saved | 566 | * sigmask will have been stored in the signal frame, |
552 | * sigmask will have been stored in the signal frame, | 567 | * and will be restored by sigreturn, so we can simply |
553 | * and will be restored by sigreturn, so we can simply | 568 | * clear the TIF_RESTORE_SIGMASK flag. |
554 | * clear the TIF_RESTORE_SIGMASK flag. | 569 | */ |
555 | */ | 570 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) |
556 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | 571 | clear_thread_flag(TIF_RESTORE_SIGMASK); |
557 | clear_thread_flag(TIF_RESTORE_SIGMASK); | 572 | } |
558 | |||
559 | tracehook_signal_handler(signr, &info, &ka, regs, 0); | ||
560 | return; | 573 | return; |
561 | } | 574 | } |
562 | if (restart_syscall && | 575 | if (restart_syscall && |
@@ -567,12 +580,14 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) | |||
567 | regs->u_regs[UREG_I0] = orig_i0; | 580 | regs->u_regs[UREG_I0] = orig_i0; |
568 | regs->pc -= 4; | 581 | regs->pc -= 4; |
569 | regs->npc -= 4; | 582 | regs->npc -= 4; |
583 | pt_regs_clear_syscall(regs); | ||
570 | } | 584 | } |
571 | if (restart_syscall && | 585 | if (restart_syscall && |
572 | regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { | 586 | regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { |
573 | regs->u_regs[UREG_G1] = __NR_restart_syscall; | 587 | regs->u_regs[UREG_G1] = __NR_restart_syscall; |
574 | regs->pc -= 4; | 588 | regs->pc -= 4; |
575 | regs->npc -= 4; | 589 | regs->npc -= 4; |
590 | pt_regs_clear_syscall(regs); | ||
576 | } | 591 | } |
577 | 592 | ||
578 | /* if there's no signal to deliver, we just put the saved sigmask | 593 | /* if there's no signal to deliver, we just put the saved sigmask |
diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c index 9fa48c30037..006fe451588 100644 --- a/arch/sparc/kernel/signal_64.c +++ b/arch/sparc/kernel/signal_64.c | |||
@@ -409,7 +409,7 @@ static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs * | |||
409 | return (void __user *) sp; | 409 | return (void __user *) sp; |
410 | } | 410 | } |
411 | 411 | ||
412 | static inline void | 412 | static inline int |
413 | setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, | 413 | setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, |
414 | int signo, sigset_t *oldset, siginfo_t *info) | 414 | int signo, sigset_t *oldset, siginfo_t *info) |
415 | { | 415 | { |
@@ -483,26 +483,37 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, | |||
483 | } | 483 | } |
484 | /* 4. return to kernel instructions */ | 484 | /* 4. return to kernel instructions */ |
485 | regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; | 485 | regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; |
486 | return; | 486 | return 0; |
487 | 487 | ||
488 | sigill: | 488 | sigill: |
489 | do_exit(SIGILL); | 489 | do_exit(SIGILL); |
490 | return -EINVAL; | ||
491 | |||
490 | sigsegv: | 492 | sigsegv: |
491 | force_sigsegv(signo, current); | 493 | force_sigsegv(signo, current); |
494 | return -EFAULT; | ||
492 | } | 495 | } |
493 | 496 | ||
494 | static inline void handle_signal(unsigned long signr, struct k_sigaction *ka, | 497 | static inline int handle_signal(unsigned long signr, struct k_sigaction *ka, |
495 | siginfo_t *info, | 498 | siginfo_t *info, |
496 | sigset_t *oldset, struct pt_regs *regs) | 499 | sigset_t *oldset, struct pt_regs *regs) |
497 | { | 500 | { |
498 | setup_rt_frame(ka, regs, signr, oldset, | 501 | int err; |
499 | (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL); | 502 | |
503 | err = setup_rt_frame(ka, regs, signr, oldset, | ||
504 | (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL); | ||
505 | if (err) | ||
506 | return err; | ||
500 | spin_lock_irq(¤t->sighand->siglock); | 507 | spin_lock_irq(¤t->sighand->siglock); |
501 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 508 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
502 | if (!(ka->sa.sa_flags & SA_NOMASK)) | 509 | if (!(ka->sa.sa_flags & SA_NOMASK)) |
503 | sigaddset(¤t->blocked,signr); | 510 | sigaddset(¤t->blocked,signr); |
504 | recalc_sigpending(); | 511 | recalc_sigpending(); |
505 | spin_unlock_irq(¤t->sighand->siglock); | 512 | spin_unlock_irq(¤t->sighand->siglock); |
513 | |||
514 | tracehook_signal_handler(signr, info, ka, regs, 0); | ||
515 | |||
516 | return 0; | ||
506 | } | 517 | } |
507 | 518 | ||
508 | static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, | 519 | static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, |
@@ -571,16 +582,14 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) | |||
571 | if (signr > 0) { | 582 | if (signr > 0) { |
572 | if (restart_syscall) | 583 | if (restart_syscall) |
573 | syscall_restart(orig_i0, regs, &ka.sa); | 584 | syscall_restart(orig_i0, regs, &ka.sa); |
574 | handle_signal(signr, &ka, &info, oldset, regs); | 585 | if (handle_signal(signr, &ka, &info, oldset, regs) == 0) { |
575 | 586 | /* A signal was successfully delivered; the saved | |
576 | /* A signal was successfully delivered; the saved | 587 | * sigmask will have been stored in the signal frame, |
577 | * sigmask will have been stored in the signal frame, | 588 | * and will be restored by sigreturn, so we can simply |
578 | * and will be restored by sigreturn, so we can simply | 589 | * clear the TS_RESTORE_SIGMASK flag. |
579 | * clear the TS_RESTORE_SIGMASK flag. | 590 | */ |
580 | */ | 591 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; |
581 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; | 592 | } |
582 | |||
583 | tracehook_signal_handler(signr, &info, &ka, regs, 0); | ||
584 | return; | 593 | return; |
585 | } | 594 | } |
586 | if (restart_syscall && | 595 | if (restart_syscall && |
@@ -591,12 +600,14 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) | |||
591 | regs->u_regs[UREG_I0] = orig_i0; | 600 | regs->u_regs[UREG_I0] = orig_i0; |
592 | regs->tpc -= 4; | 601 | regs->tpc -= 4; |
593 | regs->tnpc -= 4; | 602 | regs->tnpc -= 4; |
603 | pt_regs_clear_syscall(regs); | ||
594 | } | 604 | } |
595 | if (restart_syscall && | 605 | if (restart_syscall && |
596 | regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { | 606 | regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { |
597 | regs->u_regs[UREG_G1] = __NR_restart_syscall; | 607 | regs->u_regs[UREG_G1] = __NR_restart_syscall; |
598 | regs->tpc -= 4; | 608 | regs->tpc -= 4; |
599 | regs->tnpc -= 4; | 609 | regs->tnpc -= 4; |
610 | pt_regs_clear_syscall(regs); | ||
600 | } | 611 | } |
601 | 612 | ||
602 | /* If there's no signal to deliver, we just put the saved sigmask | 613 | /* If there's no signal to deliver, we just put the saved sigmask |
diff --git a/arch/sparc/kernel/sys_sparc_32.c b/arch/sparc/kernel/sys_sparc_32.c index 50794137d71..675c9e11ada 100644 --- a/arch/sparc/kernel/sys_sparc_32.c +++ b/arch/sparc/kernel/sys_sparc_32.c | |||
@@ -166,7 +166,6 @@ sparc_breakpoint (struct pt_regs *regs) | |||
166 | { | 166 | { |
167 | siginfo_t info; | 167 | siginfo_t info; |
168 | 168 | ||
169 | lock_kernel(); | ||
170 | #ifdef DEBUG_SPARC_BREAKPOINT | 169 | #ifdef DEBUG_SPARC_BREAKPOINT |
171 | printk ("TRAP: Entering kernel PC=%x, nPC=%x\n", regs->pc, regs->npc); | 170 | printk ("TRAP: Entering kernel PC=%x, nPC=%x\n", regs->pc, regs->npc); |
172 | #endif | 171 | #endif |
@@ -180,7 +179,6 @@ sparc_breakpoint (struct pt_regs *regs) | |||
180 | #ifdef DEBUG_SPARC_BREAKPOINT | 179 | #ifdef DEBUG_SPARC_BREAKPOINT |
181 | printk ("TRAP: Returning to space: PC=%x nPC=%x\n", regs->pc, regs->npc); | 180 | printk ("TRAP: Returning to space: PC=%x nPC=%x\n", regs->pc, regs->npc); |
182 | #endif | 181 | #endif |
183 | unlock_kernel(); | ||
184 | } | 182 | } |
185 | 183 | ||
186 | asmlinkage int | 184 | asmlinkage int |
diff --git a/arch/sparc/kernel/unaligned_32.c b/arch/sparc/kernel/unaligned_32.c index f8514e291e1..12b9f352595 100644 --- a/arch/sparc/kernel/unaligned_32.c +++ b/arch/sparc/kernel/unaligned_32.c | |||
@@ -323,7 +323,6 @@ asmlinkage void user_unaligned_trap(struct pt_regs *regs, unsigned int insn) | |||
323 | { | 323 | { |
324 | enum direction dir; | 324 | enum direction dir; |
325 | 325 | ||
326 | lock_kernel(); | ||
327 | if(!(current->thread.flags & SPARC_FLAG_UNALIGNED) || | 326 | if(!(current->thread.flags & SPARC_FLAG_UNALIGNED) || |
328 | (((insn >> 30) & 3) != 3)) | 327 | (((insn >> 30) & 3) != 3)) |
329 | goto kill_user; | 328 | goto kill_user; |
@@ -377,5 +376,5 @@ asmlinkage void user_unaligned_trap(struct pt_regs *regs, unsigned int insn) | |||
377 | kill_user: | 376 | kill_user: |
378 | user_mna_trap_fault(regs, insn); | 377 | user_mna_trap_fault(regs, insn); |
379 | out: | 378 | out: |
380 | unlock_kernel(); | 379 | ; |
381 | } | 380 | } |
diff --git a/arch/sparc/kernel/windows.c b/arch/sparc/kernel/windows.c index f24d298bda2..b351770cbdd 100644 --- a/arch/sparc/kernel/windows.c +++ b/arch/sparc/kernel/windows.c | |||
@@ -112,7 +112,6 @@ void try_to_clear_window_buffer(struct pt_regs *regs, int who) | |||
112 | struct thread_info *tp = current_thread_info(); | 112 | struct thread_info *tp = current_thread_info(); |
113 | int window; | 113 | int window; |
114 | 114 | ||
115 | lock_kernel(); | ||
116 | flush_user_windows(); | 115 | flush_user_windows(); |
117 | for(window = 0; window < tp->w_saved; window++) { | 116 | for(window = 0; window < tp->w_saved; window++) { |
118 | unsigned long sp = tp->rwbuf_stkptrs[window]; | 117 | unsigned long sp = tp->rwbuf_stkptrs[window]; |
@@ -123,5 +122,4 @@ void try_to_clear_window_buffer(struct pt_regs *regs, int who) | |||
123 | do_exit(SIGILL); | 122 | do_exit(SIGILL); |
124 | } | 123 | } |
125 | tp->w_saved = 0; | 124 | tp->w_saved = 0; |
126 | unlock_kernel(); | ||
127 | } | 125 | } |
diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile index c4b5e03af11..846d1c4374e 100644 --- a/arch/sparc/lib/Makefile +++ b/arch/sparc/lib/Makefile | |||
@@ -15,7 +15,7 @@ lib-$(CONFIG_SPARC32) += divdi3.o udivdi3.o | |||
15 | lib-$(CONFIG_SPARC32) += copy_user.o locks.o | 15 | lib-$(CONFIG_SPARC32) += copy_user.o locks.o |
16 | lib-y += atomic_$(BITS).o | 16 | lib-y += atomic_$(BITS).o |
17 | lib-$(CONFIG_SPARC32) += lshrdi3.o ashldi3.o | 17 | lib-$(CONFIG_SPARC32) += lshrdi3.o ashldi3.o |
18 | lib-y += rwsem_$(BITS).o | 18 | lib-$(CONFIG_SPARC32) += rwsem_32.o |
19 | lib-$(CONFIG_SPARC32) += muldi3.o bitext.o cmpdi2.o | 19 | lib-$(CONFIG_SPARC32) += muldi3.o bitext.o cmpdi2.o |
20 | 20 | ||
21 | lib-$(CONFIG_SPARC64) += copy_page.o clear_page.o bzero.o | 21 | lib-$(CONFIG_SPARC64) += copy_page.o clear_page.o bzero.o |
diff --git a/arch/sparc/lib/atomic_64.S b/arch/sparc/lib/atomic_64.S index 0268210ca16..59186e0fcf3 100644 --- a/arch/sparc/lib/atomic_64.S +++ b/arch/sparc/lib/atomic_64.S | |||
@@ -21,7 +21,7 @@ atomic_add: /* %o0 = increment, %o1 = atomic_ptr */ | |||
21 | add %g1, %o0, %g7 | 21 | add %g1, %o0, %g7 |
22 | cas [%o1], %g1, %g7 | 22 | cas [%o1], %g1, %g7 |
23 | cmp %g1, %g7 | 23 | cmp %g1, %g7 |
24 | bne,pn %icc, 2f | 24 | bne,pn %icc, BACKOFF_LABEL(2f, 1b) |
25 | nop | 25 | nop |
26 | retl | 26 | retl |
27 | nop | 27 | nop |
@@ -36,7 +36,7 @@ atomic_sub: /* %o0 = decrement, %o1 = atomic_ptr */ | |||
36 | sub %g1, %o0, %g7 | 36 | sub %g1, %o0, %g7 |
37 | cas [%o1], %g1, %g7 | 37 | cas [%o1], %g1, %g7 |
38 | cmp %g1, %g7 | 38 | cmp %g1, %g7 |
39 | bne,pn %icc, 2f | 39 | bne,pn %icc, BACKOFF_LABEL(2f, 1b) |
40 | nop | 40 | nop |
41 | retl | 41 | retl |
42 | nop | 42 | nop |
@@ -51,11 +51,10 @@ atomic_add_ret: /* %o0 = increment, %o1 = atomic_ptr */ | |||
51 | add %g1, %o0, %g7 | 51 | add %g1, %o0, %g7 |
52 | cas [%o1], %g1, %g7 | 52 | cas [%o1], %g1, %g7 |
53 | cmp %g1, %g7 | 53 | cmp %g1, %g7 |
54 | bne,pn %icc, 2f | 54 | bne,pn %icc, BACKOFF_LABEL(2f, 1b) |
55 | add %g7, %o0, %g7 | 55 | add %g1, %o0, %g1 |
56 | sra %g7, 0, %o0 | ||
57 | retl | 56 | retl |
58 | nop | 57 | sra %g1, 0, %o0 |
59 | 2: BACKOFF_SPIN(%o2, %o3, 1b) | 58 | 2: BACKOFF_SPIN(%o2, %o3, 1b) |
60 | .size atomic_add_ret, .-atomic_add_ret | 59 | .size atomic_add_ret, .-atomic_add_ret |
61 | 60 | ||
@@ -67,11 +66,10 @@ atomic_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */ | |||
67 | sub %g1, %o0, %g7 | 66 | sub %g1, %o0, %g7 |
68 | cas [%o1], %g1, %g7 | 67 | cas [%o1], %g1, %g7 |
69 | cmp %g1, %g7 | 68 | cmp %g1, %g7 |
70 | bne,pn %icc, 2f | 69 | bne,pn %icc, BACKOFF_LABEL(2f, 1b) |
71 | sub %g7, %o0, %g7 | 70 | sub %g1, %o0, %g1 |
72 | sra %g7, 0, %o0 | ||
73 | retl | 71 | retl |
74 | nop | 72 | sra %g1, 0, %o0 |
75 | 2: BACKOFF_SPIN(%o2, %o3, 1b) | 73 | 2: BACKOFF_SPIN(%o2, %o3, 1b) |
76 | .size atomic_sub_ret, .-atomic_sub_ret | 74 | .size atomic_sub_ret, .-atomic_sub_ret |
77 | 75 | ||
@@ -83,7 +81,7 @@ atomic64_add: /* %o0 = increment, %o1 = atomic_ptr */ | |||
83 | add %g1, %o0, %g7 | 81 | add %g1, %o0, %g7 |
84 | casx [%o1], %g1, %g7 | 82 | casx [%o1], %g1, %g7 |
85 | cmp %g1, %g7 | 83 | cmp %g1, %g7 |
86 | bne,pn %xcc, 2f | 84 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) |
87 | nop | 85 | nop |
88 | retl | 86 | retl |
89 | nop | 87 | nop |
@@ -98,7 +96,7 @@ atomic64_sub: /* %o0 = decrement, %o1 = atomic_ptr */ | |||
98 | sub %g1, %o0, %g7 | 96 | sub %g1, %o0, %g7 |
99 | casx [%o1], %g1, %g7 | 97 | casx [%o1], %g1, %g7 |
100 | cmp %g1, %g7 | 98 | cmp %g1, %g7 |
101 | bne,pn %xcc, 2f | 99 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) |
102 | nop | 100 | nop |
103 | retl | 101 | retl |
104 | nop | 102 | nop |
@@ -113,11 +111,10 @@ atomic64_add_ret: /* %o0 = increment, %o1 = atomic_ptr */ | |||
113 | add %g1, %o0, %g7 | 111 | add %g1, %o0, %g7 |
114 | casx [%o1], %g1, %g7 | 112 | casx [%o1], %g1, %g7 |
115 | cmp %g1, %g7 | 113 | cmp %g1, %g7 |
116 | bne,pn %xcc, 2f | 114 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) |
117 | add %g7, %o0, %g7 | ||
118 | mov %g7, %o0 | ||
119 | retl | ||
120 | nop | 115 | nop |
116 | retl | ||
117 | add %g1, %o0, %o0 | ||
121 | 2: BACKOFF_SPIN(%o2, %o3, 1b) | 118 | 2: BACKOFF_SPIN(%o2, %o3, 1b) |
122 | .size atomic64_add_ret, .-atomic64_add_ret | 119 | .size atomic64_add_ret, .-atomic64_add_ret |
123 | 120 | ||
@@ -129,10 +126,9 @@ atomic64_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */ | |||
129 | sub %g1, %o0, %g7 | 126 | sub %g1, %o0, %g7 |
130 | casx [%o1], %g1, %g7 | 127 | casx [%o1], %g1, %g7 |
131 | cmp %g1, %g7 | 128 | cmp %g1, %g7 |
132 | bne,pn %xcc, 2f | 129 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) |
133 | sub %g7, %o0, %g7 | ||
134 | mov %g7, %o0 | ||
135 | retl | ||
136 | nop | 130 | nop |
131 | retl | ||
132 | sub %g1, %o0, %o0 | ||
137 | 2: BACKOFF_SPIN(%o2, %o3, 1b) | 133 | 2: BACKOFF_SPIN(%o2, %o3, 1b) |
138 | .size atomic64_sub_ret, .-atomic64_sub_ret | 134 | .size atomic64_sub_ret, .-atomic64_sub_ret |
diff --git a/arch/sparc/lib/bitops.S b/arch/sparc/lib/bitops.S index 2b7228cb8c2..3dc61d5537c 100644 --- a/arch/sparc/lib/bitops.S +++ b/arch/sparc/lib/bitops.S | |||
@@ -22,7 +22,7 @@ test_and_set_bit: /* %o0=nr, %o1=addr */ | |||
22 | or %g7, %o2, %g1 | 22 | or %g7, %o2, %g1 |
23 | casx [%o1], %g7, %g1 | 23 | casx [%o1], %g7, %g1 |
24 | cmp %g7, %g1 | 24 | cmp %g7, %g1 |
25 | bne,pn %xcc, 2f | 25 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) |
26 | and %g7, %o2, %g2 | 26 | and %g7, %o2, %g2 |
27 | clr %o0 | 27 | clr %o0 |
28 | movrne %g2, 1, %o0 | 28 | movrne %g2, 1, %o0 |
@@ -45,7 +45,7 @@ test_and_clear_bit: /* %o0=nr, %o1=addr */ | |||
45 | andn %g7, %o2, %g1 | 45 | andn %g7, %o2, %g1 |
46 | casx [%o1], %g7, %g1 | 46 | casx [%o1], %g7, %g1 |
47 | cmp %g7, %g1 | 47 | cmp %g7, %g1 |
48 | bne,pn %xcc, 2f | 48 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) |
49 | and %g7, %o2, %g2 | 49 | and %g7, %o2, %g2 |
50 | clr %o0 | 50 | clr %o0 |
51 | movrne %g2, 1, %o0 | 51 | movrne %g2, 1, %o0 |
@@ -68,7 +68,7 @@ test_and_change_bit: /* %o0=nr, %o1=addr */ | |||
68 | xor %g7, %o2, %g1 | 68 | xor %g7, %o2, %g1 |
69 | casx [%o1], %g7, %g1 | 69 | casx [%o1], %g7, %g1 |
70 | cmp %g7, %g1 | 70 | cmp %g7, %g1 |
71 | bne,pn %xcc, 2f | 71 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) |
72 | and %g7, %o2, %g2 | 72 | and %g7, %o2, %g2 |
73 | clr %o0 | 73 | clr %o0 |
74 | movrne %g2, 1, %o0 | 74 | movrne %g2, 1, %o0 |
@@ -91,7 +91,7 @@ set_bit: /* %o0=nr, %o1=addr */ | |||
91 | or %g7, %o2, %g1 | 91 | or %g7, %o2, %g1 |
92 | casx [%o1], %g7, %g1 | 92 | casx [%o1], %g7, %g1 |
93 | cmp %g7, %g1 | 93 | cmp %g7, %g1 |
94 | bne,pn %xcc, 2f | 94 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) |
95 | nop | 95 | nop |
96 | retl | 96 | retl |
97 | nop | 97 | nop |
@@ -112,7 +112,7 @@ clear_bit: /* %o0=nr, %o1=addr */ | |||
112 | andn %g7, %o2, %g1 | 112 | andn %g7, %o2, %g1 |
113 | casx [%o1], %g7, %g1 | 113 | casx [%o1], %g7, %g1 |
114 | cmp %g7, %g1 | 114 | cmp %g7, %g1 |
115 | bne,pn %xcc, 2f | 115 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) |
116 | nop | 116 | nop |
117 | retl | 117 | retl |
118 | nop | 118 | nop |
@@ -133,7 +133,7 @@ change_bit: /* %o0=nr, %o1=addr */ | |||
133 | xor %g7, %o2, %g1 | 133 | xor %g7, %o2, %g1 |
134 | casx [%o1], %g7, %g1 | 134 | casx [%o1], %g7, %g1 |
135 | cmp %g7, %g1 | 135 | cmp %g7, %g1 |
136 | bne,pn %xcc, 2f | 136 | bne,pn %xcc, BACKOFF_LABEL(2f, 1b) |
137 | nop | 137 | nop |
138 | retl | 138 | retl |
139 | nop | 139 | nop |
diff --git a/arch/sparc/lib/rwsem_64.S b/arch/sparc/lib/rwsem_64.S deleted file mode 100644 index 91a7d29a79d..00000000000 --- a/arch/sparc/lib/rwsem_64.S +++ /dev/null | |||
@@ -1,163 +0,0 @@ | |||
1 | /* rwsem.S: RW semaphore assembler. | ||
2 | * | ||
3 | * Written by David S. Miller (davem@redhat.com), 2001. | ||
4 | * Derived from asm-i386/rwsem.h | ||
5 | */ | ||
6 | |||
7 | #include <asm/rwsem-const.h> | ||
8 | |||
9 | .section .sched.text, "ax" | ||
10 | |||
11 | .globl __down_read | ||
12 | __down_read: | ||
13 | 1: lduw [%o0], %g1 | ||
14 | add %g1, 1, %g7 | ||
15 | cas [%o0], %g1, %g7 | ||
16 | cmp %g1, %g7 | ||
17 | bne,pn %icc, 1b | ||
18 | add %g7, 1, %g7 | ||
19 | cmp %g7, 0 | ||
20 | bl,pn %icc, 3f | ||
21 | nop | ||
22 | 2: | ||
23 | retl | ||
24 | nop | ||
25 | 3: | ||
26 | save %sp, -192, %sp | ||
27 | call rwsem_down_read_failed | ||
28 | mov %i0, %o0 | ||
29 | ret | ||
30 | restore | ||
31 | .size __down_read, .-__down_read | ||
32 | |||
33 | .globl __down_read_trylock | ||
34 | __down_read_trylock: | ||
35 | 1: lduw [%o0], %g1 | ||
36 | add %g1, 1, %g7 | ||
37 | cmp %g7, 0 | ||
38 | bl,pn %icc, 2f | ||
39 | mov 0, %o1 | ||
40 | cas [%o0], %g1, %g7 | ||
41 | cmp %g1, %g7 | ||
42 | bne,pn %icc, 1b | ||
43 | mov 1, %o1 | ||
44 | 2: retl | ||
45 | mov %o1, %o0 | ||
46 | .size __down_read_trylock, .-__down_read_trylock | ||
47 | |||
48 | .globl __down_write | ||
49 | __down_write: | ||
50 | sethi %hi(RWSEM_ACTIVE_WRITE_BIAS), %g1 | ||
51 | or %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1 | ||
52 | 1: | ||
53 | lduw [%o0], %g3 | ||
54 | add %g3, %g1, %g7 | ||
55 | cas [%o0], %g3, %g7 | ||
56 | cmp %g3, %g7 | ||
57 | bne,pn %icc, 1b | ||
58 | cmp %g7, 0 | ||
59 | bne,pn %icc, 3f | ||
60 | nop | ||
61 | 2: retl | ||
62 | nop | ||
63 | 3: | ||
64 | save %sp, -192, %sp | ||
65 | call rwsem_down_write_failed | ||
66 | mov %i0, %o0 | ||
67 | ret | ||
68 | restore | ||
69 | .size __down_write, .-__down_write | ||
70 | |||
71 | .globl __down_write_trylock | ||
72 | __down_write_trylock: | ||
73 | sethi %hi(RWSEM_ACTIVE_WRITE_BIAS), %g1 | ||
74 | or %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1 | ||
75 | 1: | ||
76 | lduw [%o0], %g3 | ||
77 | cmp %g3, 0 | ||
78 | bne,pn %icc, 2f | ||
79 | mov 0, %o1 | ||
80 | add %g3, %g1, %g7 | ||
81 | cas [%o0], %g3, %g7 | ||
82 | cmp %g3, %g7 | ||
83 | bne,pn %icc, 1b | ||
84 | mov 1, %o1 | ||
85 | 2: retl | ||
86 | mov %o1, %o0 | ||
87 | .size __down_write_trylock, .-__down_write_trylock | ||
88 | |||
89 | .globl __up_read | ||
90 | __up_read: | ||
91 | 1: | ||
92 | lduw [%o0], %g1 | ||
93 | sub %g1, 1, %g7 | ||
94 | cas [%o0], %g1, %g7 | ||
95 | cmp %g1, %g7 | ||
96 | bne,pn %icc, 1b | ||
97 | cmp %g7, 0 | ||
98 | bl,pn %icc, 3f | ||
99 | nop | ||
100 | 2: retl | ||
101 | nop | ||
102 | 3: sethi %hi(RWSEM_ACTIVE_MASK), %g1 | ||
103 | sub %g7, 1, %g7 | ||
104 | or %g1, %lo(RWSEM_ACTIVE_MASK), %g1 | ||
105 | andcc %g7, %g1, %g0 | ||
106 | bne,pn %icc, 2b | ||
107 | nop | ||
108 | save %sp, -192, %sp | ||
109 | call rwsem_wake | ||
110 | mov %i0, %o0 | ||
111 | ret | ||
112 | restore | ||
113 | .size __up_read, .-__up_read | ||
114 | |||
115 | .globl __up_write | ||
116 | __up_write: | ||
117 | sethi %hi(RWSEM_ACTIVE_WRITE_BIAS), %g1 | ||
118 | or %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1 | ||
119 | 1: | ||
120 | lduw [%o0], %g3 | ||
121 | sub %g3, %g1, %g7 | ||
122 | cas [%o0], %g3, %g7 | ||
123 | cmp %g3, %g7 | ||
124 | bne,pn %icc, 1b | ||
125 | sub %g7, %g1, %g7 | ||
126 | cmp %g7, 0 | ||
127 | bl,pn %icc, 3f | ||
128 | nop | ||
129 | 2: | ||
130 | retl | ||
131 | nop | ||
132 | 3: | ||
133 | save %sp, -192, %sp | ||
134 | call rwsem_wake | ||
135 | mov %i0, %o0 | ||
136 | ret | ||
137 | restore | ||
138 | .size __up_write, .-__up_write | ||
139 | |||
140 | .globl __downgrade_write | ||
141 | __downgrade_write: | ||
142 | sethi %hi(RWSEM_WAITING_BIAS), %g1 | ||
143 | or %g1, %lo(RWSEM_WAITING_BIAS), %g1 | ||
144 | 1: | ||
145 | lduw [%o0], %g3 | ||
146 | sub %g3, %g1, %g7 | ||
147 | cas [%o0], %g3, %g7 | ||
148 | cmp %g3, %g7 | ||
149 | bne,pn %icc, 1b | ||
150 | sub %g7, %g1, %g7 | ||
151 | cmp %g7, 0 | ||
152 | bl,pn %icc, 3f | ||
153 | nop | ||
154 | 2: | ||
155 | retl | ||
156 | nop | ||
157 | 3: | ||
158 | save %sp, -192, %sp | ||
159 | call rwsem_downgrade_wake | ||
160 | mov %i0, %o0 | ||
161 | ret | ||
162 | restore | ||
163 | .size __downgrade_write, .-__downgrade_write | ||
diff --git a/arch/sparc/prom/cif.S b/arch/sparc/prom/cif.S index 5f27ad779c0..9c86b4b7d42 100644 --- a/arch/sparc/prom/cif.S +++ b/arch/sparc/prom/cif.S | |||
@@ -9,18 +9,18 @@ | |||
9 | #include <asm/thread_info.h> | 9 | #include <asm/thread_info.h> |
10 | 10 | ||
11 | .text | 11 | .text |
12 | .globl prom_cif_interface | 12 | .globl prom_cif_direct |
13 | prom_cif_interface: | 13 | prom_cif_direct: |
14 | sethi %hi(p1275buf), %o0 | 14 | sethi %hi(p1275buf), %o1 |
15 | or %o0, %lo(p1275buf), %o0 | 15 | or %o1, %lo(p1275buf), %o1 |
16 | ldx [%o0 + 0x010], %o1 ! prom_cif_stack | 16 | ldx [%o1 + 0x0010], %o2 ! prom_cif_stack |
17 | save %o1, -192, %sp | 17 | save %o2, -192, %sp |
18 | ldx [%i0 + 0x008], %l2 ! prom_cif_handler | 18 | ldx [%i1 + 0x0008], %l2 ! prom_cif_handler |
19 | mov %g4, %l0 | 19 | mov %g4, %l0 |
20 | mov %g5, %l1 | 20 | mov %g5, %l1 |
21 | mov %g6, %l3 | 21 | mov %g6, %l3 |
22 | call %l2 | 22 | call %l2 |
23 | add %i0, 0x018, %o0 ! prom_args | 23 | mov %i0, %o0 ! prom_args |
24 | mov %l0, %g4 | 24 | mov %l0, %g4 |
25 | mov %l1, %g5 | 25 | mov %l1, %g5 |
26 | mov %l3, %g6 | 26 | mov %l3, %g6 |
diff --git a/arch/sparc/prom/console_64.c b/arch/sparc/prom/console_64.c index f55d58a8a15..10322dc2f55 100644 --- a/arch/sparc/prom/console_64.c +++ b/arch/sparc/prom/console_64.c | |||
@@ -21,14 +21,22 @@ extern int prom_stdin, prom_stdout; | |||
21 | inline int | 21 | inline int |
22 | prom_nbgetchar(void) | 22 | prom_nbgetchar(void) |
23 | { | 23 | { |
24 | unsigned long args[7]; | ||
24 | char inc; | 25 | char inc; |
25 | 26 | ||
26 | if (p1275_cmd("read", P1275_ARG(1,P1275_ARG_OUT_BUF)| | 27 | args[0] = (unsigned long) "read"; |
27 | P1275_INOUT(3,1), | 28 | args[1] = 3; |
28 | prom_stdin, &inc, P1275_SIZE(1)) == 1) | 29 | args[2] = 1; |
30 | args[3] = (unsigned int) prom_stdin; | ||
31 | args[4] = (unsigned long) &inc; | ||
32 | args[5] = 1; | ||
33 | args[6] = (unsigned long) -1; | ||
34 | |||
35 | p1275_cmd_direct(args); | ||
36 | |||
37 | if (args[6] == 1) | ||
29 | return inc; | 38 | return inc; |
30 | else | 39 | return -1; |
31 | return -1; | ||
32 | } | 40 | } |
33 | 41 | ||
34 | /* Non blocking put character to console device, returns -1 if | 42 | /* Non blocking put character to console device, returns -1 if |
@@ -37,12 +45,22 @@ prom_nbgetchar(void) | |||
37 | inline int | 45 | inline int |
38 | prom_nbputchar(char c) | 46 | prom_nbputchar(char c) |
39 | { | 47 | { |
48 | unsigned long args[7]; | ||
40 | char outc; | 49 | char outc; |
41 | 50 | ||
42 | outc = c; | 51 | outc = c; |
43 | if (p1275_cmd("write", P1275_ARG(1,P1275_ARG_IN_BUF)| | 52 | |
44 | P1275_INOUT(3,1), | 53 | args[0] = (unsigned long) "write"; |
45 | prom_stdout, &outc, P1275_SIZE(1)) == 1) | 54 | args[1] = 3; |
55 | args[2] = 1; | ||
56 | args[3] = (unsigned int) prom_stdout; | ||
57 | args[4] = (unsigned long) &outc; | ||
58 | args[5] = 1; | ||
59 | args[6] = (unsigned long) -1; | ||
60 | |||
61 | p1275_cmd_direct(args); | ||
62 | |||
63 | if (args[6] == 1) | ||
46 | return 0; | 64 | return 0; |
47 | else | 65 | else |
48 | return -1; | 66 | return -1; |
@@ -67,7 +85,15 @@ prom_putchar(char c) | |||
67 | void | 85 | void |
68 | prom_puts(const char *s, int len) | 86 | prom_puts(const char *s, int len) |
69 | { | 87 | { |
70 | p1275_cmd("write", P1275_ARG(1,P1275_ARG_IN_BUF)| | 88 | unsigned long args[7]; |
71 | P1275_INOUT(3,1), | 89 | |
72 | prom_stdout, s, P1275_SIZE(len)); | 90 | args[0] = (unsigned long) "write"; |
91 | args[1] = 3; | ||
92 | args[2] = 1; | ||
93 | args[3] = (unsigned int) prom_stdout; | ||
94 | args[4] = (unsigned long) s; | ||
95 | args[5] = len; | ||
96 | args[6] = (unsigned long) -1; | ||
97 | |||
98 | p1275_cmd_direct(args); | ||
73 | } | 99 | } |
diff --git a/arch/sparc/prom/devops_64.c b/arch/sparc/prom/devops_64.c index 9dbd803e46e..a017119e7ef 100644 --- a/arch/sparc/prom/devops_64.c +++ b/arch/sparc/prom/devops_64.c | |||
@@ -18,16 +18,32 @@ | |||
18 | int | 18 | int |
19 | prom_devopen(const char *dstr) | 19 | prom_devopen(const char *dstr) |
20 | { | 20 | { |
21 | return p1275_cmd ("open", P1275_ARG(0,P1275_ARG_IN_STRING)| | 21 | unsigned long args[5]; |
22 | P1275_INOUT(1,1), | 22 | |
23 | dstr); | 23 | args[0] = (unsigned long) "open"; |
24 | args[1] = 1; | ||
25 | args[2] = 1; | ||
26 | args[3] = (unsigned long) dstr; | ||
27 | args[4] = (unsigned long) -1; | ||
28 | |||
29 | p1275_cmd_direct(args); | ||
30 | |||
31 | return (int) args[4]; | ||
24 | } | 32 | } |
25 | 33 | ||
26 | /* Close the device described by device handle 'dhandle'. */ | 34 | /* Close the device described by device handle 'dhandle'. */ |
27 | int | 35 | int |
28 | prom_devclose(int dhandle) | 36 | prom_devclose(int dhandle) |
29 | { | 37 | { |
30 | p1275_cmd ("close", P1275_INOUT(1,0), dhandle); | 38 | unsigned long args[4]; |
39 | |||
40 | args[0] = (unsigned long) "close"; | ||
41 | args[1] = 1; | ||
42 | args[2] = 0; | ||
43 | args[3] = (unsigned int) dhandle; | ||
44 | |||
45 | p1275_cmd_direct(args); | ||
46 | |||
31 | return 0; | 47 | return 0; |
32 | } | 48 | } |
33 | 49 | ||
@@ -37,5 +53,15 @@ prom_devclose(int dhandle) | |||
37 | void | 53 | void |
38 | prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo) | 54 | prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo) |
39 | { | 55 | { |
40 | p1275_cmd ("seek", P1275_INOUT(3,1), dhandle, seekhi, seeklo); | 56 | unsigned long args[7]; |
57 | |||
58 | args[0] = (unsigned long) "seek"; | ||
59 | args[1] = 3; | ||
60 | args[2] = 1; | ||
61 | args[3] = (unsigned int) dhandle; | ||
62 | args[4] = seekhi; | ||
63 | args[5] = seeklo; | ||
64 | args[6] = (unsigned long) -1; | ||
65 | |||
66 | p1275_cmd_direct(args); | ||
41 | } | 67 | } |
diff --git a/arch/sparc/prom/misc_64.c b/arch/sparc/prom/misc_64.c index 39fc6af21b7..6cb1581d6ae 100644 --- a/arch/sparc/prom/misc_64.c +++ b/arch/sparc/prom/misc_64.c | |||
@@ -20,10 +20,17 @@ | |||
20 | 20 | ||
21 | int prom_service_exists(const char *service_name) | 21 | int prom_service_exists(const char *service_name) |
22 | { | 22 | { |
23 | int err = p1275_cmd("test", P1275_ARG(0, P1275_ARG_IN_STRING) | | 23 | unsigned long args[5]; |
24 | P1275_INOUT(1, 1), service_name); | ||
25 | 24 | ||
26 | if (err) | 25 | args[0] = (unsigned long) "test"; |
26 | args[1] = 1; | ||
27 | args[2] = 1; | ||
28 | args[3] = (unsigned long) service_name; | ||
29 | args[4] = (unsigned long) -1; | ||
30 | |||
31 | p1275_cmd_direct(args); | ||
32 | |||
33 | if (args[4]) | ||
27 | return 0; | 34 | return 0; |
28 | return 1; | 35 | return 1; |
29 | } | 36 | } |
@@ -31,30 +38,47 @@ int prom_service_exists(const char *service_name) | |||
31 | void prom_sun4v_guest_soft_state(void) | 38 | void prom_sun4v_guest_soft_state(void) |
32 | { | 39 | { |
33 | const char *svc = "SUNW,soft-state-supported"; | 40 | const char *svc = "SUNW,soft-state-supported"; |
41 | unsigned long args[3]; | ||
34 | 42 | ||
35 | if (!prom_service_exists(svc)) | 43 | if (!prom_service_exists(svc)) |
36 | return; | 44 | return; |
37 | p1275_cmd(svc, P1275_INOUT(0, 0)); | 45 | args[0] = (unsigned long) svc; |
46 | args[1] = 0; | ||
47 | args[2] = 0; | ||
48 | p1275_cmd_direct(args); | ||
38 | } | 49 | } |
39 | 50 | ||
40 | /* Reset and reboot the machine with the command 'bcommand'. */ | 51 | /* Reset and reboot the machine with the command 'bcommand'. */ |
41 | void prom_reboot(const char *bcommand) | 52 | void prom_reboot(const char *bcommand) |
42 | { | 53 | { |
54 | unsigned long args[4]; | ||
55 | |||
43 | #ifdef CONFIG_SUN_LDOMS | 56 | #ifdef CONFIG_SUN_LDOMS |
44 | if (ldom_domaining_enabled) | 57 | if (ldom_domaining_enabled) |
45 | ldom_reboot(bcommand); | 58 | ldom_reboot(bcommand); |
46 | #endif | 59 | #endif |
47 | p1275_cmd("boot", P1275_ARG(0, P1275_ARG_IN_STRING) | | 60 | args[0] = (unsigned long) "boot"; |
48 | P1275_INOUT(1, 0), bcommand); | 61 | args[1] = 1; |
62 | args[2] = 0; | ||
63 | args[3] = (unsigned long) bcommand; | ||
64 | |||
65 | p1275_cmd_direct(args); | ||
49 | } | 66 | } |
50 | 67 | ||
51 | /* Forth evaluate the expression contained in 'fstring'. */ | 68 | /* Forth evaluate the expression contained in 'fstring'. */ |
52 | void prom_feval(const char *fstring) | 69 | void prom_feval(const char *fstring) |
53 | { | 70 | { |
71 | unsigned long args[5]; | ||
72 | |||
54 | if (!fstring || fstring[0] == 0) | 73 | if (!fstring || fstring[0] == 0) |
55 | return; | 74 | return; |
56 | p1275_cmd("interpret", P1275_ARG(0, P1275_ARG_IN_STRING) | | 75 | args[0] = (unsigned long) "interpret"; |
57 | P1275_INOUT(1, 1), fstring); | 76 | args[1] = 1; |
77 | args[2] = 1; | ||
78 | args[3] = (unsigned long) fstring; | ||
79 | args[4] = (unsigned long) -1; | ||
80 | |||
81 | p1275_cmd_direct(args); | ||
58 | } | 82 | } |
59 | EXPORT_SYMBOL(prom_feval); | 83 | EXPORT_SYMBOL(prom_feval); |
60 | 84 | ||
@@ -68,6 +92,7 @@ extern void smp_release(void); | |||
68 | */ | 92 | */ |
69 | void prom_cmdline(void) | 93 | void prom_cmdline(void) |
70 | { | 94 | { |
95 | unsigned long args[3]; | ||
71 | unsigned long flags; | 96 | unsigned long flags; |
72 | 97 | ||
73 | local_irq_save(flags); | 98 | local_irq_save(flags); |
@@ -76,7 +101,11 @@ void prom_cmdline(void) | |||
76 | smp_capture(); | 101 | smp_capture(); |
77 | #endif | 102 | #endif |
78 | 103 | ||
79 | p1275_cmd("enter", P1275_INOUT(0, 0)); | 104 | args[0] = (unsigned long) "enter"; |
105 | args[1] = 0; | ||
106 | args[2] = 0; | ||
107 | |||
108 | p1275_cmd_direct(args); | ||
80 | 109 | ||
81 | #ifdef CONFIG_SMP | 110 | #ifdef CONFIG_SMP |
82 | smp_release(); | 111 | smp_release(); |
@@ -90,22 +119,32 @@ void prom_cmdline(void) | |||
90 | */ | 119 | */ |
91 | void notrace prom_halt(void) | 120 | void notrace prom_halt(void) |
92 | { | 121 | { |
122 | unsigned long args[3]; | ||
123 | |||
93 | #ifdef CONFIG_SUN_LDOMS | 124 | #ifdef CONFIG_SUN_LDOMS |
94 | if (ldom_domaining_enabled) | 125 | if (ldom_domaining_enabled) |
95 | ldom_power_off(); | 126 | ldom_power_off(); |
96 | #endif | 127 | #endif |
97 | again: | 128 | again: |
98 | p1275_cmd("exit", P1275_INOUT(0, 0)); | 129 | args[0] = (unsigned long) "exit"; |
130 | args[1] = 0; | ||
131 | args[2] = 0; | ||
132 | p1275_cmd_direct(args); | ||
99 | goto again; /* PROM is out to get me -DaveM */ | 133 | goto again; /* PROM is out to get me -DaveM */ |
100 | } | 134 | } |
101 | 135 | ||
102 | void prom_halt_power_off(void) | 136 | void prom_halt_power_off(void) |
103 | { | 137 | { |
138 | unsigned long args[3]; | ||
139 | |||
104 | #ifdef CONFIG_SUN_LDOMS | 140 | #ifdef CONFIG_SUN_LDOMS |
105 | if (ldom_domaining_enabled) | 141 | if (ldom_domaining_enabled) |
106 | ldom_power_off(); | 142 | ldom_power_off(); |
107 | #endif | 143 | #endif |
108 | p1275_cmd("SUNW,power-off", P1275_INOUT(0, 0)); | 144 | args[0] = (unsigned long) "SUNW,power-off"; |
145 | args[1] = 0; | ||
146 | args[2] = 0; | ||
147 | p1275_cmd_direct(args); | ||
109 | 148 | ||
110 | /* if nothing else helps, we just halt */ | 149 | /* if nothing else helps, we just halt */ |
111 | prom_halt(); | 150 | prom_halt(); |
@@ -114,10 +153,15 @@ void prom_halt_power_off(void) | |||
114 | /* Set prom sync handler to call function 'funcp'. */ | 153 | /* Set prom sync handler to call function 'funcp'. */ |
115 | void prom_setcallback(callback_func_t funcp) | 154 | void prom_setcallback(callback_func_t funcp) |
116 | { | 155 | { |
156 | unsigned long args[5]; | ||
117 | if (!funcp) | 157 | if (!funcp) |
118 | return; | 158 | return; |
119 | p1275_cmd("set-callback", P1275_ARG(0, P1275_ARG_IN_FUNCTION) | | 159 | args[0] = (unsigned long) "set-callback"; |
120 | P1275_INOUT(1, 1), funcp); | 160 | args[1] = 1; |
161 | args[2] = 1; | ||
162 | args[3] = (unsigned long) funcp; | ||
163 | args[4] = (unsigned long) -1; | ||
164 | p1275_cmd_direct(args); | ||
121 | } | 165 | } |
122 | 166 | ||
123 | /* Get the idprom and stuff it into buffer 'idbuf'. Returns the | 167 | /* Get the idprom and stuff it into buffer 'idbuf'. Returns the |
@@ -173,57 +217,61 @@ static int prom_get_memory_ihandle(void) | |||
173 | } | 217 | } |
174 | 218 | ||
175 | /* Load explicit I/D TLB entries. */ | 219 | /* Load explicit I/D TLB entries. */ |
220 | static long tlb_load(const char *type, unsigned long index, | ||
221 | unsigned long tte_data, unsigned long vaddr) | ||
222 | { | ||
223 | unsigned long args[9]; | ||
224 | |||
225 | args[0] = (unsigned long) prom_callmethod_name; | ||
226 | args[1] = 5; | ||
227 | args[2] = 1; | ||
228 | args[3] = (unsigned long) type; | ||
229 | args[4] = (unsigned int) prom_get_mmu_ihandle(); | ||
230 | args[5] = vaddr; | ||
231 | args[6] = tte_data; | ||
232 | args[7] = index; | ||
233 | args[8] = (unsigned long) -1; | ||
234 | |||
235 | p1275_cmd_direct(args); | ||
236 | |||
237 | return (long) args[8]; | ||
238 | } | ||
239 | |||
176 | long prom_itlb_load(unsigned long index, | 240 | long prom_itlb_load(unsigned long index, |
177 | unsigned long tte_data, | 241 | unsigned long tte_data, |
178 | unsigned long vaddr) | 242 | unsigned long vaddr) |
179 | { | 243 | { |
180 | return p1275_cmd(prom_callmethod_name, | 244 | return tlb_load("SUNW,itlb-load", index, tte_data, vaddr); |
181 | (P1275_ARG(0, P1275_ARG_IN_STRING) | | ||
182 | P1275_ARG(2, P1275_ARG_IN_64B) | | ||
183 | P1275_ARG(3, P1275_ARG_IN_64B) | | ||
184 | P1275_INOUT(5, 1)), | ||
185 | "SUNW,itlb-load", | ||
186 | prom_get_mmu_ihandle(), | ||
187 | /* And then our actual args are pushed backwards. */ | ||
188 | vaddr, | ||
189 | tte_data, | ||
190 | index); | ||
191 | } | 245 | } |
192 | 246 | ||
193 | long prom_dtlb_load(unsigned long index, | 247 | long prom_dtlb_load(unsigned long index, |
194 | unsigned long tte_data, | 248 | unsigned long tte_data, |
195 | unsigned long vaddr) | 249 | unsigned long vaddr) |
196 | { | 250 | { |
197 | return p1275_cmd(prom_callmethod_name, | 251 | return tlb_load("SUNW,dtlb-load", index, tte_data, vaddr); |
198 | (P1275_ARG(0, P1275_ARG_IN_STRING) | | ||
199 | P1275_ARG(2, P1275_ARG_IN_64B) | | ||
200 | P1275_ARG(3, P1275_ARG_IN_64B) | | ||
201 | P1275_INOUT(5, 1)), | ||
202 | "SUNW,dtlb-load", | ||
203 | prom_get_mmu_ihandle(), | ||
204 | /* And then our actual args are pushed backwards. */ | ||
205 | vaddr, | ||
206 | tte_data, | ||
207 | index); | ||
208 | } | 252 | } |
209 | 253 | ||
210 | int prom_map(int mode, unsigned long size, | 254 | int prom_map(int mode, unsigned long size, |
211 | unsigned long vaddr, unsigned long paddr) | 255 | unsigned long vaddr, unsigned long paddr) |
212 | { | 256 | { |
213 | int ret = p1275_cmd(prom_callmethod_name, | 257 | unsigned long args[11]; |
214 | (P1275_ARG(0, P1275_ARG_IN_STRING) | | 258 | int ret; |
215 | P1275_ARG(3, P1275_ARG_IN_64B) | | 259 | |
216 | P1275_ARG(4, P1275_ARG_IN_64B) | | 260 | args[0] = (unsigned long) prom_callmethod_name; |
217 | P1275_ARG(6, P1275_ARG_IN_64B) | | 261 | args[1] = 7; |
218 | P1275_INOUT(7, 1)), | 262 | args[2] = 1; |
219 | prom_map_name, | 263 | args[3] = (unsigned long) prom_map_name; |
220 | prom_get_mmu_ihandle(), | 264 | args[4] = (unsigned int) prom_get_mmu_ihandle(); |
221 | mode, | 265 | args[5] = (unsigned int) mode; |
222 | size, | 266 | args[6] = size; |
223 | vaddr, | 267 | args[7] = vaddr; |
224 | 0, | 268 | args[8] = 0; |
225 | paddr); | 269 | args[9] = paddr; |
226 | 270 | args[10] = (unsigned long) -1; | |
271 | |||
272 | p1275_cmd_direct(args); | ||
273 | |||
274 | ret = (int) args[10]; | ||
227 | if (ret == 0) | 275 | if (ret == 0) |
228 | ret = -1; | 276 | ret = -1; |
229 | return ret; | 277 | return ret; |
@@ -231,40 +279,51 @@ int prom_map(int mode, unsigned long size, | |||
231 | 279 | ||
232 | void prom_unmap(unsigned long size, unsigned long vaddr) | 280 | void prom_unmap(unsigned long size, unsigned long vaddr) |
233 | { | 281 | { |
234 | p1275_cmd(prom_callmethod_name, | 282 | unsigned long args[7]; |
235 | (P1275_ARG(0, P1275_ARG_IN_STRING) | | 283 | |
236 | P1275_ARG(2, P1275_ARG_IN_64B) | | 284 | args[0] = (unsigned long) prom_callmethod_name; |
237 | P1275_ARG(3, P1275_ARG_IN_64B) | | 285 | args[1] = 4; |
238 | P1275_INOUT(4, 0)), | 286 | args[2] = 0; |
239 | prom_unmap_name, | 287 | args[3] = (unsigned long) prom_unmap_name; |
240 | prom_get_mmu_ihandle(), | 288 | args[4] = (unsigned int) prom_get_mmu_ihandle(); |
241 | size, | 289 | args[5] = size; |
242 | vaddr); | 290 | args[6] = vaddr; |
291 | |||
292 | p1275_cmd_direct(args); | ||
243 | } | 293 | } |
244 | 294 | ||
245 | /* Set aside physical memory which is not touched or modified | 295 | /* Set aside physical memory which is not touched or modified |
246 | * across soft resets. | 296 | * across soft resets. |
247 | */ | 297 | */ |
248 | unsigned long prom_retain(const char *name, | 298 | int prom_retain(const char *name, unsigned long size, |
249 | unsigned long pa_low, unsigned long pa_high, | 299 | unsigned long align, unsigned long *paddr) |
250 | long size, long align) | ||
251 | { | 300 | { |
252 | /* XXX I don't think we return multiple values correctly. | 301 | unsigned long args[11]; |
253 | * XXX OBP supposedly returns pa_low/pa_high here, how does | 302 | |
254 | * XXX it work? | 303 | args[0] = (unsigned long) prom_callmethod_name; |
304 | args[1] = 5; | ||
305 | args[2] = 3; | ||
306 | args[3] = (unsigned long) "SUNW,retain"; | ||
307 | args[4] = (unsigned int) prom_get_memory_ihandle(); | ||
308 | args[5] = align; | ||
309 | args[6] = size; | ||
310 | args[7] = (unsigned long) name; | ||
311 | args[8] = (unsigned long) -1; | ||
312 | args[9] = (unsigned long) -1; | ||
313 | args[10] = (unsigned long) -1; | ||
314 | |||
315 | p1275_cmd_direct(args); | ||
316 | |||
317 | if (args[8]) | ||
318 | return (int) args[8]; | ||
319 | |||
320 | /* Next we get "phys_high" then "phys_low". On 64-bit | ||
321 | * the phys_high cell is don't care since the phys_low | ||
322 | * cell has the full value. | ||
255 | */ | 323 | */ |
324 | *paddr = args[10]; | ||
256 | 325 | ||
257 | /* If align is zero, the pa_low/pa_high args are passed, | 326 | return 0; |
258 | * else they are not. | ||
259 | */ | ||
260 | if (align == 0) | ||
261 | return p1275_cmd("SUNW,retain", | ||
262 | (P1275_ARG(0, P1275_ARG_IN_BUF) | P1275_INOUT(5, 2)), | ||
263 | name, pa_low, pa_high, size, align); | ||
264 | else | ||
265 | return p1275_cmd("SUNW,retain", | ||
266 | (P1275_ARG(0, P1275_ARG_IN_BUF) | P1275_INOUT(3, 2)), | ||
267 | name, size, align); | ||
268 | } | 327 | } |
269 | 328 | ||
270 | /* Get "Unumber" string for the SIMM at the given | 329 | /* Get "Unumber" string for the SIMM at the given |
@@ -277,62 +336,129 @@ int prom_getunumber(int syndrome_code, | |||
277 | unsigned long phys_addr, | 336 | unsigned long phys_addr, |
278 | char *buf, int buflen) | 337 | char *buf, int buflen) |
279 | { | 338 | { |
280 | return p1275_cmd(prom_callmethod_name, | 339 | unsigned long args[12]; |
281 | (P1275_ARG(0, P1275_ARG_IN_STRING) | | 340 | |
282 | P1275_ARG(3, P1275_ARG_OUT_BUF) | | 341 | args[0] = (unsigned long) prom_callmethod_name; |
283 | P1275_ARG(6, P1275_ARG_IN_64B) | | 342 | args[1] = 7; |
284 | P1275_INOUT(8, 2)), | 343 | args[2] = 2; |
285 | "SUNW,get-unumber", prom_get_memory_ihandle(), | 344 | args[3] = (unsigned long) "SUNW,get-unumber"; |
286 | buflen, buf, P1275_SIZE(buflen), | 345 | args[4] = (unsigned int) prom_get_memory_ihandle(); |
287 | 0, phys_addr, syndrome_code); | 346 | args[5] = buflen; |
347 | args[6] = (unsigned long) buf; | ||
348 | args[7] = 0; | ||
349 | args[8] = phys_addr; | ||
350 | args[9] = (unsigned int) syndrome_code; | ||
351 | args[10] = (unsigned long) -1; | ||
352 | args[11] = (unsigned long) -1; | ||
353 | |||
354 | p1275_cmd_direct(args); | ||
355 | |||
356 | return (int) args[10]; | ||
288 | } | 357 | } |
289 | 358 | ||
290 | /* Power management extensions. */ | 359 | /* Power management extensions. */ |
291 | void prom_sleepself(void) | 360 | void prom_sleepself(void) |
292 | { | 361 | { |
293 | p1275_cmd("SUNW,sleep-self", P1275_INOUT(0, 0)); | 362 | unsigned long args[3]; |
363 | |||
364 | args[0] = (unsigned long) "SUNW,sleep-self"; | ||
365 | args[1] = 0; | ||
366 | args[2] = 0; | ||
367 | p1275_cmd_direct(args); | ||
294 | } | 368 | } |
295 | 369 | ||
296 | int prom_sleepsystem(void) | 370 | int prom_sleepsystem(void) |
297 | { | 371 | { |
298 | return p1275_cmd("SUNW,sleep-system", P1275_INOUT(0, 1)); | 372 | unsigned long args[4]; |
373 | |||
374 | args[0] = (unsigned long) "SUNW,sleep-system"; | ||
375 | args[1] = 0; | ||
376 | args[2] = 1; | ||
377 | args[3] = (unsigned long) -1; | ||
378 | p1275_cmd_direct(args); | ||
379 | |||
380 | return (int) args[3]; | ||
299 | } | 381 | } |
300 | 382 | ||
301 | int prom_wakeupsystem(void) | 383 | int prom_wakeupsystem(void) |
302 | { | 384 | { |
303 | return p1275_cmd("SUNW,wakeup-system", P1275_INOUT(0, 1)); | 385 | unsigned long args[4]; |
386 | |||
387 | args[0] = (unsigned long) "SUNW,wakeup-system"; | ||
388 | args[1] = 0; | ||
389 | args[2] = 1; | ||
390 | args[3] = (unsigned long) -1; | ||
391 | p1275_cmd_direct(args); | ||
392 | |||
393 | return (int) args[3]; | ||
304 | } | 394 | } |
305 | 395 | ||
306 | #ifdef CONFIG_SMP | 396 | #ifdef CONFIG_SMP |
307 | void prom_startcpu(int cpunode, unsigned long pc, unsigned long arg) | 397 | void prom_startcpu(int cpunode, unsigned long pc, unsigned long arg) |
308 | { | 398 | { |
309 | p1275_cmd("SUNW,start-cpu", P1275_INOUT(3, 0), cpunode, pc, arg); | 399 | unsigned long args[6]; |
400 | |||
401 | args[0] = (unsigned long) "SUNW,start-cpu"; | ||
402 | args[1] = 3; | ||
403 | args[2] = 0; | ||
404 | args[3] = (unsigned int) cpunode; | ||
405 | args[4] = pc; | ||
406 | args[5] = arg; | ||
407 | p1275_cmd_direct(args); | ||
310 | } | 408 | } |
311 | 409 | ||
312 | void prom_startcpu_cpuid(int cpuid, unsigned long pc, unsigned long arg) | 410 | void prom_startcpu_cpuid(int cpuid, unsigned long pc, unsigned long arg) |
313 | { | 411 | { |
314 | p1275_cmd("SUNW,start-cpu-by-cpuid", P1275_INOUT(3, 0), | 412 | unsigned long args[6]; |
315 | cpuid, pc, arg); | 413 | |
414 | args[0] = (unsigned long) "SUNW,start-cpu-by-cpuid"; | ||
415 | args[1] = 3; | ||
416 | args[2] = 0; | ||
417 | args[3] = (unsigned int) cpuid; | ||
418 | args[4] = pc; | ||
419 | args[5] = arg; | ||
420 | p1275_cmd_direct(args); | ||
316 | } | 421 | } |
317 | 422 | ||
318 | void prom_stopcpu_cpuid(int cpuid) | 423 | void prom_stopcpu_cpuid(int cpuid) |
319 | { | 424 | { |
320 | p1275_cmd("SUNW,stop-cpu-by-cpuid", P1275_INOUT(1, 0), | 425 | unsigned long args[4]; |
321 | cpuid); | 426 | |
427 | args[0] = (unsigned long) "SUNW,stop-cpu-by-cpuid"; | ||
428 | args[1] = 1; | ||
429 | args[2] = 0; | ||
430 | args[3] = (unsigned int) cpuid; | ||
431 | p1275_cmd_direct(args); | ||
322 | } | 432 | } |
323 | 433 | ||
324 | void prom_stopself(void) | 434 | void prom_stopself(void) |
325 | { | 435 | { |
326 | p1275_cmd("SUNW,stop-self", P1275_INOUT(0, 0)); | 436 | unsigned long args[3]; |
437 | |||
438 | args[0] = (unsigned long) "SUNW,stop-self"; | ||
439 | args[1] = 0; | ||
440 | args[2] = 0; | ||
441 | p1275_cmd_direct(args); | ||
327 | } | 442 | } |
328 | 443 | ||
329 | void prom_idleself(void) | 444 | void prom_idleself(void) |
330 | { | 445 | { |
331 | p1275_cmd("SUNW,idle-self", P1275_INOUT(0, 0)); | 446 | unsigned long args[3]; |
447 | |||
448 | args[0] = (unsigned long) "SUNW,idle-self"; | ||
449 | args[1] = 0; | ||
450 | args[2] = 0; | ||
451 | p1275_cmd_direct(args); | ||
332 | } | 452 | } |
333 | 453 | ||
334 | void prom_resumecpu(int cpunode) | 454 | void prom_resumecpu(int cpunode) |
335 | { | 455 | { |
336 | p1275_cmd("SUNW,resume-cpu", P1275_INOUT(1, 0), cpunode); | 456 | unsigned long args[4]; |
457 | |||
458 | args[0] = (unsigned long) "SUNW,resume-cpu"; | ||
459 | args[1] = 1; | ||
460 | args[2] = 0; | ||
461 | args[3] = (unsigned int) cpunode; | ||
462 | p1275_cmd_direct(args); | ||
337 | } | 463 | } |
338 | #endif | 464 | #endif |
diff --git a/arch/sparc/prom/p1275.c b/arch/sparc/prom/p1275.c index 2d8b70d397f..fa6e4e219b9 100644 --- a/arch/sparc/prom/p1275.c +++ b/arch/sparc/prom/p1275.c | |||
@@ -22,13 +22,11 @@ struct { | |||
22 | long prom_callback; /* 0x00 */ | 22 | long prom_callback; /* 0x00 */ |
23 | void (*prom_cif_handler)(long *); /* 0x08 */ | 23 | void (*prom_cif_handler)(long *); /* 0x08 */ |
24 | unsigned long prom_cif_stack; /* 0x10 */ | 24 | unsigned long prom_cif_stack; /* 0x10 */ |
25 | unsigned long prom_args [23]; /* 0x18 */ | ||
26 | char prom_buffer [3000]; | ||
27 | } p1275buf; | 25 | } p1275buf; |
28 | 26 | ||
29 | extern void prom_world(int); | 27 | extern void prom_world(int); |
30 | 28 | ||
31 | extern void prom_cif_interface(void); | 29 | extern void prom_cif_direct(unsigned long *args); |
32 | extern void prom_cif_callback(void); | 30 | extern void prom_cif_callback(void); |
33 | 31 | ||
34 | /* | 32 | /* |
@@ -36,114 +34,20 @@ extern void prom_cif_callback(void); | |||
36 | */ | 34 | */ |
37 | DEFINE_RAW_SPINLOCK(prom_entry_lock); | 35 | DEFINE_RAW_SPINLOCK(prom_entry_lock); |
38 | 36 | ||
39 | long p1275_cmd(const char *service, long fmt, ...) | 37 | void p1275_cmd_direct(unsigned long *args) |
40 | { | 38 | { |
41 | char *p, *q; | ||
42 | unsigned long flags; | 39 | unsigned long flags; |
43 | int nargs, nrets, i; | ||
44 | va_list list; | ||
45 | long attrs, x; | ||
46 | |||
47 | p = p1275buf.prom_buffer; | ||
48 | 40 | ||
49 | raw_local_save_flags(flags); | 41 | raw_local_save_flags(flags); |
50 | raw_local_irq_restore(PIL_NMI); | 42 | raw_local_irq_restore(PIL_NMI); |
51 | raw_spin_lock(&prom_entry_lock); | 43 | raw_spin_lock(&prom_entry_lock); |
52 | 44 | ||
53 | p1275buf.prom_args[0] = (unsigned long)p; /* service */ | ||
54 | strcpy (p, service); | ||
55 | p = (char *)(((long)(strchr (p, 0) + 8)) & ~7); | ||
56 | p1275buf.prom_args[1] = nargs = (fmt & 0x0f); /* nargs */ | ||
57 | p1275buf.prom_args[2] = nrets = ((fmt & 0xf0) >> 4); /* nrets */ | ||
58 | attrs = fmt >> 8; | ||
59 | va_start(list, fmt); | ||
60 | for (i = 0; i < nargs; i++, attrs >>= 3) { | ||
61 | switch (attrs & 0x7) { | ||
62 | case P1275_ARG_NUMBER: | ||
63 | p1275buf.prom_args[i + 3] = | ||
64 | (unsigned)va_arg(list, long); | ||
65 | break; | ||
66 | case P1275_ARG_IN_64B: | ||
67 | p1275buf.prom_args[i + 3] = | ||
68 | va_arg(list, unsigned long); | ||
69 | break; | ||
70 | case P1275_ARG_IN_STRING: | ||
71 | strcpy (p, va_arg(list, char *)); | ||
72 | p1275buf.prom_args[i + 3] = (unsigned long)p; | ||
73 | p = (char *)(((long)(strchr (p, 0) + 8)) & ~7); | ||
74 | break; | ||
75 | case P1275_ARG_OUT_BUF: | ||
76 | (void) va_arg(list, char *); | ||
77 | p1275buf.prom_args[i + 3] = (unsigned long)p; | ||
78 | x = va_arg(list, long); | ||
79 | i++; attrs >>= 3; | ||
80 | p = (char *)(((long)(p + (int)x + 7)) & ~7); | ||
81 | p1275buf.prom_args[i + 3] = x; | ||
82 | break; | ||
83 | case P1275_ARG_IN_BUF: | ||
84 | q = va_arg(list, char *); | ||
85 | p1275buf.prom_args[i + 3] = (unsigned long)p; | ||
86 | x = va_arg(list, long); | ||
87 | i++; attrs >>= 3; | ||
88 | memcpy (p, q, (int)x); | ||
89 | p = (char *)(((long)(p + (int)x + 7)) & ~7); | ||
90 | p1275buf.prom_args[i + 3] = x; | ||
91 | break; | ||
92 | case P1275_ARG_OUT_32B: | ||
93 | (void) va_arg(list, char *); | ||
94 | p1275buf.prom_args[i + 3] = (unsigned long)p; | ||
95 | p += 32; | ||
96 | break; | ||
97 | case P1275_ARG_IN_FUNCTION: | ||
98 | p1275buf.prom_args[i + 3] = | ||
99 | (unsigned long)prom_cif_callback; | ||
100 | p1275buf.prom_callback = va_arg(list, long); | ||
101 | break; | ||
102 | } | ||
103 | } | ||
104 | va_end(list); | ||
105 | |||
106 | prom_world(1); | 45 | prom_world(1); |
107 | prom_cif_interface(); | 46 | prom_cif_direct(args); |
108 | prom_world(0); | 47 | prom_world(0); |
109 | 48 | ||
110 | attrs = fmt >> 8; | ||
111 | va_start(list, fmt); | ||
112 | for (i = 0; i < nargs; i++, attrs >>= 3) { | ||
113 | switch (attrs & 0x7) { | ||
114 | case P1275_ARG_NUMBER: | ||
115 | (void) va_arg(list, long); | ||
116 | break; | ||
117 | case P1275_ARG_IN_STRING: | ||
118 | (void) va_arg(list, char *); | ||
119 | break; | ||
120 | case P1275_ARG_IN_FUNCTION: | ||
121 | (void) va_arg(list, long); | ||
122 | break; | ||
123 | case P1275_ARG_IN_BUF: | ||
124 | (void) va_arg(list, char *); | ||
125 | (void) va_arg(list, long); | ||
126 | i++; attrs >>= 3; | ||
127 | break; | ||
128 | case P1275_ARG_OUT_BUF: | ||
129 | p = va_arg(list, char *); | ||
130 | x = va_arg(list, long); | ||
131 | memcpy (p, (char *)(p1275buf.prom_args[i + 3]), (int)x); | ||
132 | i++; attrs >>= 3; | ||
133 | break; | ||
134 | case P1275_ARG_OUT_32B: | ||
135 | p = va_arg(list, char *); | ||
136 | memcpy (p, (char *)(p1275buf.prom_args[i + 3]), 32); | ||
137 | break; | ||
138 | } | ||
139 | } | ||
140 | va_end(list); | ||
141 | x = p1275buf.prom_args [nargs + 3]; | ||
142 | |||
143 | raw_spin_unlock(&prom_entry_lock); | 49 | raw_spin_unlock(&prom_entry_lock); |
144 | raw_local_irq_restore(flags); | 50 | raw_local_irq_restore(flags); |
145 | |||
146 | return x; | ||
147 | } | 51 | } |
148 | 52 | ||
149 | void prom_cif_init(void *cif_handler, void *cif_stack) | 53 | void prom_cif_init(void *cif_handler, void *cif_stack) |
diff --git a/arch/sparc/prom/tree_64.c b/arch/sparc/prom/tree_64.c index 3c0d2dd9f69..9d3f9137a43 100644 --- a/arch/sparc/prom/tree_64.c +++ b/arch/sparc/prom/tree_64.c | |||
@@ -16,22 +16,39 @@ | |||
16 | #include <asm/oplib.h> | 16 | #include <asm/oplib.h> |
17 | #include <asm/ldc.h> | 17 | #include <asm/ldc.h> |
18 | 18 | ||
19 | static int prom_node_to_node(const char *type, int node) | ||
20 | { | ||
21 | unsigned long args[5]; | ||
22 | |||
23 | args[0] = (unsigned long) type; | ||
24 | args[1] = 1; | ||
25 | args[2] = 1; | ||
26 | args[3] = (unsigned int) node; | ||
27 | args[4] = (unsigned long) -1; | ||
28 | |||
29 | p1275_cmd_direct(args); | ||
30 | |||
31 | return (int) args[4]; | ||
32 | } | ||
33 | |||
19 | /* Return the child of node 'node' or zero if no this node has no | 34 | /* Return the child of node 'node' or zero if no this node has no |
20 | * direct descendent. | 35 | * direct descendent. |
21 | */ | 36 | */ |
22 | inline int __prom_getchild(int node) | 37 | inline int __prom_getchild(int node) |
23 | { | 38 | { |
24 | return p1275_cmd ("child", P1275_INOUT(1, 1), node); | 39 | return prom_node_to_node("child", node); |
25 | } | 40 | } |
26 | 41 | ||
27 | inline int prom_getchild(int node) | 42 | inline int prom_getchild(int node) |
28 | { | 43 | { |
29 | int cnode; | 44 | int cnode; |
30 | 45 | ||
31 | if(node == -1) return 0; | 46 | if (node == -1) |
47 | return 0; | ||
32 | cnode = __prom_getchild(node); | 48 | cnode = __prom_getchild(node); |
33 | if(cnode == -1) return 0; | 49 | if (cnode == -1) |
34 | return (int)cnode; | 50 | return 0; |
51 | return cnode; | ||
35 | } | 52 | } |
36 | EXPORT_SYMBOL(prom_getchild); | 53 | EXPORT_SYMBOL(prom_getchild); |
37 | 54 | ||
@@ -39,10 +56,12 @@ inline int prom_getparent(int node) | |||
39 | { | 56 | { |
40 | int cnode; | 57 | int cnode; |
41 | 58 | ||
42 | if(node == -1) return 0; | 59 | if (node == -1) |
43 | cnode = p1275_cmd ("parent", P1275_INOUT(1, 1), node); | 60 | return 0; |
44 | if(cnode == -1) return 0; | 61 | cnode = prom_node_to_node("parent", node); |
45 | return (int)cnode; | 62 | if (cnode == -1) |
63 | return 0; | ||
64 | return cnode; | ||
46 | } | 65 | } |
47 | 66 | ||
48 | /* Return the next sibling of node 'node' or zero if no more siblings | 67 | /* Return the next sibling of node 'node' or zero if no more siblings |
@@ -50,7 +69,7 @@ inline int prom_getparent(int node) | |||
50 | */ | 69 | */ |
51 | inline int __prom_getsibling(int node) | 70 | inline int __prom_getsibling(int node) |
52 | { | 71 | { |
53 | return p1275_cmd(prom_peer_name, P1275_INOUT(1, 1), node); | 72 | return prom_node_to_node(prom_peer_name, node); |
54 | } | 73 | } |
55 | 74 | ||
56 | inline int prom_getsibling(int node) | 75 | inline int prom_getsibling(int node) |
@@ -72,11 +91,21 @@ EXPORT_SYMBOL(prom_getsibling); | |||
72 | */ | 91 | */ |
73 | inline int prom_getproplen(int node, const char *prop) | 92 | inline int prom_getproplen(int node, const char *prop) |
74 | { | 93 | { |
75 | if((!node) || (!prop)) return -1; | 94 | unsigned long args[6]; |
76 | return p1275_cmd ("getproplen", | 95 | |
77 | P1275_ARG(1,P1275_ARG_IN_STRING)| | 96 | if (!node || !prop) |
78 | P1275_INOUT(2, 1), | 97 | return -1; |
79 | node, prop); | 98 | |
99 | args[0] = (unsigned long) "getproplen"; | ||
100 | args[1] = 2; | ||
101 | args[2] = 1; | ||
102 | args[3] = (unsigned int) node; | ||
103 | args[4] = (unsigned long) prop; | ||
104 | args[5] = (unsigned long) -1; | ||
105 | |||
106 | p1275_cmd_direct(args); | ||
107 | |||
108 | return (int) args[5]; | ||
80 | } | 109 | } |
81 | EXPORT_SYMBOL(prom_getproplen); | 110 | EXPORT_SYMBOL(prom_getproplen); |
82 | 111 | ||
@@ -87,19 +116,25 @@ EXPORT_SYMBOL(prom_getproplen); | |||
87 | inline int prom_getproperty(int node, const char *prop, | 116 | inline int prom_getproperty(int node, const char *prop, |
88 | char *buffer, int bufsize) | 117 | char *buffer, int bufsize) |
89 | { | 118 | { |
119 | unsigned long args[8]; | ||
90 | int plen; | 120 | int plen; |
91 | 121 | ||
92 | plen = prom_getproplen(node, prop); | 122 | plen = prom_getproplen(node, prop); |
93 | if ((plen > bufsize) || (plen == 0) || (plen == -1)) { | 123 | if ((plen > bufsize) || (plen == 0) || (plen == -1)) |
94 | return -1; | 124 | return -1; |
95 | } else { | 125 | |
96 | /* Ok, things seem all right. */ | 126 | args[0] = (unsigned long) prom_getprop_name; |
97 | return p1275_cmd(prom_getprop_name, | 127 | args[1] = 4; |
98 | P1275_ARG(1,P1275_ARG_IN_STRING)| | 128 | args[2] = 1; |
99 | P1275_ARG(2,P1275_ARG_OUT_BUF)| | 129 | args[3] = (unsigned int) node; |
100 | P1275_INOUT(4, 1), | 130 | args[4] = (unsigned long) prop; |
101 | node, prop, buffer, P1275_SIZE(plen)); | 131 | args[5] = (unsigned long) buffer; |
102 | } | 132 | args[6] = bufsize; |
133 | args[7] = (unsigned long) -1; | ||
134 | |||
135 | p1275_cmd_direct(args); | ||
136 | |||
137 | return (int) args[7]; | ||
103 | } | 138 | } |
104 | EXPORT_SYMBOL(prom_getproperty); | 139 | EXPORT_SYMBOL(prom_getproperty); |
105 | 140 | ||
@@ -110,7 +145,7 @@ inline int prom_getint(int node, const char *prop) | |||
110 | { | 145 | { |
111 | int intprop; | 146 | int intprop; |
112 | 147 | ||
113 | if(prom_getproperty(node, prop, (char *) &intprop, sizeof(int)) != -1) | 148 | if (prom_getproperty(node, prop, (char *) &intprop, sizeof(int)) != -1) |
114 | return intprop; | 149 | return intprop; |
115 | 150 | ||
116 | return -1; | 151 | return -1; |
@@ -126,7 +161,8 @@ int prom_getintdefault(int node, const char *property, int deflt) | |||
126 | int retval; | 161 | int retval; |
127 | 162 | ||
128 | retval = prom_getint(node, property); | 163 | retval = prom_getint(node, property); |
129 | if(retval == -1) return deflt; | 164 | if (retval == -1) |
165 | return deflt; | ||
130 | 166 | ||
131 | return retval; | 167 | return retval; |
132 | } | 168 | } |
@@ -138,7 +174,8 @@ int prom_getbool(int node, const char *prop) | |||
138 | int retval; | 174 | int retval; |
139 | 175 | ||
140 | retval = prom_getproplen(node, prop); | 176 | retval = prom_getproplen(node, prop); |
141 | if(retval == -1) return 0; | 177 | if (retval == -1) |
178 | return 0; | ||
142 | return 1; | 179 | return 1; |
143 | } | 180 | } |
144 | EXPORT_SYMBOL(prom_getbool); | 181 | EXPORT_SYMBOL(prom_getbool); |
@@ -152,7 +189,8 @@ void prom_getstring(int node, const char *prop, char *user_buf, int ubuf_size) | |||
152 | int len; | 189 | int len; |
153 | 190 | ||
154 | len = prom_getproperty(node, prop, user_buf, ubuf_size); | 191 | len = prom_getproperty(node, prop, user_buf, ubuf_size); |
155 | if(len != -1) return; | 192 | if (len != -1) |
193 | return; | ||
156 | user_buf[0] = 0; | 194 | user_buf[0] = 0; |
157 | } | 195 | } |
158 | EXPORT_SYMBOL(prom_getstring); | 196 | EXPORT_SYMBOL(prom_getstring); |
@@ -164,7 +202,8 @@ int prom_nodematch(int node, const char *name) | |||
164 | { | 202 | { |
165 | char namebuf[128]; | 203 | char namebuf[128]; |
166 | prom_getproperty(node, "name", namebuf, sizeof(namebuf)); | 204 | prom_getproperty(node, "name", namebuf, sizeof(namebuf)); |
167 | if(strcmp(namebuf, name) == 0) return 1; | 205 | if (strcmp(namebuf, name) == 0) |
206 | return 1; | ||
168 | return 0; | 207 | return 0; |
169 | } | 208 | } |
170 | 209 | ||
@@ -190,16 +229,29 @@ int prom_searchsiblings(int node_start, const char *nodename) | |||
190 | } | 229 | } |
191 | EXPORT_SYMBOL(prom_searchsiblings); | 230 | EXPORT_SYMBOL(prom_searchsiblings); |
192 | 231 | ||
232 | static const char *prom_nextprop_name = "nextprop"; | ||
233 | |||
193 | /* Return the first property type for node 'node'. | 234 | /* Return the first property type for node 'node'. |
194 | * buffer should be at least 32B in length | 235 | * buffer should be at least 32B in length |
195 | */ | 236 | */ |
196 | inline char *prom_firstprop(int node, char *buffer) | 237 | inline char *prom_firstprop(int node, char *buffer) |
197 | { | 238 | { |
239 | unsigned long args[7]; | ||
240 | |||
198 | *buffer = 0; | 241 | *buffer = 0; |
199 | if(node == -1) return buffer; | 242 | if (node == -1) |
200 | p1275_cmd ("nextprop", P1275_ARG(2,P1275_ARG_OUT_32B)| | 243 | return buffer; |
201 | P1275_INOUT(3, 0), | 244 | |
202 | node, (char *) 0x0, buffer); | 245 | args[0] = (unsigned long) prom_nextprop_name; |
246 | args[1] = 3; | ||
247 | args[2] = 1; | ||
248 | args[3] = (unsigned int) node; | ||
249 | args[4] = 0; | ||
250 | args[5] = (unsigned long) buffer; | ||
251 | args[6] = (unsigned long) -1; | ||
252 | |||
253 | p1275_cmd_direct(args); | ||
254 | |||
203 | return buffer; | 255 | return buffer; |
204 | } | 256 | } |
205 | EXPORT_SYMBOL(prom_firstprop); | 257 | EXPORT_SYMBOL(prom_firstprop); |
@@ -210,9 +262,10 @@ EXPORT_SYMBOL(prom_firstprop); | |||
210 | */ | 262 | */ |
211 | inline char *prom_nextprop(int node, const char *oprop, char *buffer) | 263 | inline char *prom_nextprop(int node, const char *oprop, char *buffer) |
212 | { | 264 | { |
265 | unsigned long args[7]; | ||
213 | char buf[32]; | 266 | char buf[32]; |
214 | 267 | ||
215 | if(node == -1) { | 268 | if (node == -1) { |
216 | *buffer = 0; | 269 | *buffer = 0; |
217 | return buffer; | 270 | return buffer; |
218 | } | 271 | } |
@@ -220,10 +273,17 @@ inline char *prom_nextprop(int node, const char *oprop, char *buffer) | |||
220 | strcpy (buf, oprop); | 273 | strcpy (buf, oprop); |
221 | oprop = buf; | 274 | oprop = buf; |
222 | } | 275 | } |
223 | p1275_cmd ("nextprop", P1275_ARG(1,P1275_ARG_IN_STRING)| | 276 | |
224 | P1275_ARG(2,P1275_ARG_OUT_32B)| | 277 | args[0] = (unsigned long) prom_nextprop_name; |
225 | P1275_INOUT(3, 0), | 278 | args[1] = 3; |
226 | node, oprop, buffer); | 279 | args[2] = 1; |
280 | args[3] = (unsigned int) node; | ||
281 | args[4] = (unsigned long) oprop; | ||
282 | args[5] = (unsigned long) buffer; | ||
283 | args[6] = (unsigned long) -1; | ||
284 | |||
285 | p1275_cmd_direct(args); | ||
286 | |||
227 | return buffer; | 287 | return buffer; |
228 | } | 288 | } |
229 | EXPORT_SYMBOL(prom_nextprop); | 289 | EXPORT_SYMBOL(prom_nextprop); |
@@ -231,12 +291,19 @@ EXPORT_SYMBOL(prom_nextprop); | |||
231 | int | 291 | int |
232 | prom_finddevice(const char *name) | 292 | prom_finddevice(const char *name) |
233 | { | 293 | { |
294 | unsigned long args[5]; | ||
295 | |||
234 | if (!name) | 296 | if (!name) |
235 | return 0; | 297 | return 0; |
236 | return p1275_cmd(prom_finddev_name, | 298 | args[0] = (unsigned long) "finddevice"; |
237 | P1275_ARG(0,P1275_ARG_IN_STRING)| | 299 | args[1] = 1; |
238 | P1275_INOUT(1, 1), | 300 | args[2] = 1; |
239 | name); | 301 | args[3] = (unsigned long) name; |
302 | args[4] = (unsigned long) -1; | ||
303 | |||
304 | p1275_cmd_direct(args); | ||
305 | |||
306 | return (int) args[4]; | ||
240 | } | 307 | } |
241 | EXPORT_SYMBOL(prom_finddevice); | 308 | EXPORT_SYMBOL(prom_finddevice); |
242 | 309 | ||
@@ -247,7 +314,7 @@ int prom_node_has_property(int node, const char *prop) | |||
247 | *buf = 0; | 314 | *buf = 0; |
248 | do { | 315 | do { |
249 | prom_nextprop(node, buf, buf); | 316 | prom_nextprop(node, buf, buf); |
250 | if(!strcmp(buf, prop)) | 317 | if (!strcmp(buf, prop)) |
251 | return 1; | 318 | return 1; |
252 | } while (*buf); | 319 | } while (*buf); |
253 | return 0; | 320 | return 0; |
@@ -260,6 +327,8 @@ EXPORT_SYMBOL(prom_node_has_property); | |||
260 | int | 327 | int |
261 | prom_setprop(int node, const char *pname, char *value, int size) | 328 | prom_setprop(int node, const char *pname, char *value, int size) |
262 | { | 329 | { |
330 | unsigned long args[8]; | ||
331 | |||
263 | if (size == 0) | 332 | if (size == 0) |
264 | return 0; | 333 | return 0; |
265 | if ((pname == 0) || (value == 0)) | 334 | if ((pname == 0) || (value == 0)) |
@@ -271,19 +340,37 @@ prom_setprop(int node, const char *pname, char *value, int size) | |||
271 | return 0; | 340 | return 0; |
272 | } | 341 | } |
273 | #endif | 342 | #endif |
274 | return p1275_cmd ("setprop", P1275_ARG(1,P1275_ARG_IN_STRING)| | 343 | args[0] = (unsigned long) "setprop"; |
275 | P1275_ARG(2,P1275_ARG_IN_BUF)| | 344 | args[1] = 4; |
276 | P1275_INOUT(4, 1), | 345 | args[2] = 1; |
277 | node, pname, value, P1275_SIZE(size)); | 346 | args[3] = (unsigned int) node; |
347 | args[4] = (unsigned long) pname; | ||
348 | args[5] = (unsigned long) value; | ||
349 | args[6] = size; | ||
350 | args[7] = (unsigned long) -1; | ||
351 | |||
352 | p1275_cmd_direct(args); | ||
353 | |||
354 | return (int) args[7]; | ||
278 | } | 355 | } |
279 | EXPORT_SYMBOL(prom_setprop); | 356 | EXPORT_SYMBOL(prom_setprop); |
280 | 357 | ||
281 | inline int prom_inst2pkg(int inst) | 358 | inline int prom_inst2pkg(int inst) |
282 | { | 359 | { |
360 | unsigned long args[5]; | ||
283 | int node; | 361 | int node; |
284 | 362 | ||
285 | node = p1275_cmd ("instance-to-package", P1275_INOUT(1, 1), inst); | 363 | args[0] = (unsigned long) "instance-to-package"; |
286 | if (node == -1) return 0; | 364 | args[1] = 1; |
365 | args[2] = 1; | ||
366 | args[3] = (unsigned int) inst; | ||
367 | args[4] = (unsigned long) -1; | ||
368 | |||
369 | p1275_cmd_direct(args); | ||
370 | |||
371 | node = (int) args[4]; | ||
372 | if (node == -1) | ||
373 | return 0; | ||
287 | return node; | 374 | return node; |
288 | } | 375 | } |
289 | 376 | ||
@@ -296,17 +383,28 @@ prom_pathtoinode(const char *path) | |||
296 | int node, inst; | 383 | int node, inst; |
297 | 384 | ||
298 | inst = prom_devopen (path); | 385 | inst = prom_devopen (path); |
299 | if (inst == 0) return 0; | 386 | if (inst == 0) |
300 | node = prom_inst2pkg (inst); | 387 | return 0; |
301 | prom_devclose (inst); | 388 | node = prom_inst2pkg(inst); |
302 | if (node == -1) return 0; | 389 | prom_devclose(inst); |
390 | if (node == -1) | ||
391 | return 0; | ||
303 | return node; | 392 | return node; |
304 | } | 393 | } |
305 | 394 | ||
306 | int prom_ihandle2path(int handle, char *buffer, int bufsize) | 395 | int prom_ihandle2path(int handle, char *buffer, int bufsize) |
307 | { | 396 | { |
308 | return p1275_cmd("instance-to-path", | 397 | unsigned long args[7]; |
309 | P1275_ARG(1,P1275_ARG_OUT_BUF)| | 398 | |
310 | P1275_INOUT(3, 1), | 399 | args[0] = (unsigned long) "instance-to-path"; |
311 | handle, buffer, P1275_SIZE(bufsize)); | 400 | args[1] = 3; |
401 | args[2] = 1; | ||
402 | args[3] = (unsigned int) handle; | ||
403 | args[4] = (unsigned long) buffer; | ||
404 | args[5] = bufsize; | ||
405 | args[6] = (unsigned long) -1; | ||
406 | |||
407 | p1275_cmd_direct(args); | ||
408 | |||
409 | return (int) args[6]; | ||
312 | } | 410 | } |
diff --git a/arch/tile/include/arch/chip_tile64.h b/arch/tile/include/arch/chip_tile64.h index 1246573be59..261aaba092d 100644 --- a/arch/tile/include/arch/chip_tile64.h +++ b/arch/tile/include/arch/chip_tile64.h | |||
@@ -150,6 +150,9 @@ | |||
150 | /** Is the PROC_STATUS SPR supported? */ | 150 | /** Is the PROC_STATUS SPR supported? */ |
151 | #define CHIP_HAS_PROC_STATUS_SPR() 0 | 151 | #define CHIP_HAS_PROC_STATUS_SPR() 0 |
152 | 152 | ||
153 | /** Is the DSTREAM_PF SPR supported? */ | ||
154 | #define CHIP_HAS_DSTREAM_PF() 0 | ||
155 | |||
153 | /** Log of the number of mshims we have. */ | 156 | /** Log of the number of mshims we have. */ |
154 | #define CHIP_LOG_NUM_MSHIMS() 2 | 157 | #define CHIP_LOG_NUM_MSHIMS() 2 |
155 | 158 | ||
diff --git a/arch/tile/include/arch/chip_tilepro.h b/arch/tile/include/arch/chip_tilepro.h index e864c47fc89..70017699a74 100644 --- a/arch/tile/include/arch/chip_tilepro.h +++ b/arch/tile/include/arch/chip_tilepro.h | |||
@@ -150,6 +150,9 @@ | |||
150 | /** Is the PROC_STATUS SPR supported? */ | 150 | /** Is the PROC_STATUS SPR supported? */ |
151 | #define CHIP_HAS_PROC_STATUS_SPR() 1 | 151 | #define CHIP_HAS_PROC_STATUS_SPR() 1 |
152 | 152 | ||
153 | /** Is the DSTREAM_PF SPR supported? */ | ||
154 | #define CHIP_HAS_DSTREAM_PF() 0 | ||
155 | |||
153 | /** Log of the number of mshims we have. */ | 156 | /** Log of the number of mshims we have. */ |
154 | #define CHIP_LOG_NUM_MSHIMS() 2 | 157 | #define CHIP_LOG_NUM_MSHIMS() 2 |
155 | 158 | ||
diff --git a/arch/tile/include/asm/compat.h b/arch/tile/include/asm/compat.h index 5a34da6cdd7..8b60ec8b2d1 100644 --- a/arch/tile/include/asm/compat.h +++ b/arch/tile/include/asm/compat.h | |||
@@ -195,7 +195,7 @@ static inline unsigned long ptr_to_compat_reg(void __user *uptr) | |||
195 | return (long)(int)(long __force)uptr; | 195 | return (long)(int)(long __force)uptr; |
196 | } | 196 | } |
197 | 197 | ||
198 | static inline void __user *compat_alloc_user_space(long len) | 198 | static inline void __user *arch_compat_alloc_user_space(long len) |
199 | { | 199 | { |
200 | struct pt_regs *regs = task_pt_regs(current); | 200 | struct pt_regs *regs = task_pt_regs(current); |
201 | return (void __user *)regs->sp - len; | 201 | return (void __user *)regs->sp - len; |
@@ -214,8 +214,9 @@ extern int compat_setup_rt_frame(int sig, struct k_sigaction *ka, | |||
214 | struct compat_sigaction; | 214 | struct compat_sigaction; |
215 | struct compat_siginfo; | 215 | struct compat_siginfo; |
216 | struct compat_sigaltstack; | 216 | struct compat_sigaltstack; |
217 | long compat_sys_execve(char __user *path, compat_uptr_t __user *argv, | 217 | long compat_sys_execve(const char __user *path, |
218 | compat_uptr_t __user *envp); | 218 | const compat_uptr_t __user *argv, |
219 | const compat_uptr_t __user *envp); | ||
219 | long compat_sys_rt_sigaction(int sig, struct compat_sigaction __user *act, | 220 | long compat_sys_rt_sigaction(int sig, struct compat_sigaction __user *act, |
220 | struct compat_sigaction __user *oact, | 221 | struct compat_sigaction __user *oact, |
221 | size_t sigsetsize); | 222 | size_t sigsetsize); |
diff --git a/arch/tile/include/asm/io.h b/arch/tile/include/asm/io.h index 8c95bef3fa4..ee43328713a 100644 --- a/arch/tile/include/asm/io.h +++ b/arch/tile/include/asm/io.h | |||
@@ -164,22 +164,22 @@ static inline void _tile_writeq(u64 val, unsigned long addr) | |||
164 | #define iowrite32 writel | 164 | #define iowrite32 writel |
165 | #define iowrite64 writeq | 165 | #define iowrite64 writeq |
166 | 166 | ||
167 | static inline void *memcpy_fromio(void *dst, void *src, int len) | 167 | static inline void memcpy_fromio(void *dst, const volatile void __iomem *src, |
168 | size_t len) | ||
168 | { | 169 | { |
169 | int x; | 170 | int x; |
170 | BUG_ON((unsigned long)src & 0x3); | 171 | BUG_ON((unsigned long)src & 0x3); |
171 | for (x = 0; x < len; x += 4) | 172 | for (x = 0; x < len; x += 4) |
172 | *(u32 *)(dst + x) = readl(src + x); | 173 | *(u32 *)(dst + x) = readl(src + x); |
173 | return dst; | ||
174 | } | 174 | } |
175 | 175 | ||
176 | static inline void *memcpy_toio(void *dst, void *src, int len) | 176 | static inline void memcpy_toio(volatile void __iomem *dst, const void *src, |
177 | size_t len) | ||
177 | { | 178 | { |
178 | int x; | 179 | int x; |
179 | BUG_ON((unsigned long)dst & 0x3); | 180 | BUG_ON((unsigned long)dst & 0x3); |
180 | for (x = 0; x < len; x += 4) | 181 | for (x = 0; x < len; x += 4) |
181 | writel(*(u32 *)(src + x), dst + x); | 182 | writel(*(u32 *)(src + x), dst + x); |
182 | return dst; | ||
183 | } | 183 | } |
184 | 184 | ||
185 | /* | 185 | /* |
diff --git a/arch/tile/include/asm/processor.h b/arch/tile/include/asm/processor.h index d942d09b252..ccd5f842568 100644 --- a/arch/tile/include/asm/processor.h +++ b/arch/tile/include/asm/processor.h | |||
@@ -103,6 +103,18 @@ struct thread_struct { | |||
103 | /* Any other miscellaneous processor state bits */ | 103 | /* Any other miscellaneous processor state bits */ |
104 | unsigned long proc_status; | 104 | unsigned long proc_status; |
105 | #endif | 105 | #endif |
106 | #if !CHIP_HAS_FIXED_INTVEC_BASE() | ||
107 | /* Interrupt base for PL0 interrupts */ | ||
108 | unsigned long interrupt_vector_base; | ||
109 | #endif | ||
110 | #if CHIP_HAS_TILE_RTF_HWM() | ||
111 | /* Tile cache retry fifo high-water mark */ | ||
112 | unsigned long tile_rtf_hwm; | ||
113 | #endif | ||
114 | #if CHIP_HAS_DSTREAM_PF() | ||
115 | /* Data stream prefetch control */ | ||
116 | unsigned long dstream_pf; | ||
117 | #endif | ||
106 | #ifdef CONFIG_HARDWALL | 118 | #ifdef CONFIG_HARDWALL |
107 | /* Is this task tied to an activated hardwall? */ | 119 | /* Is this task tied to an activated hardwall? */ |
108 | struct hardwall_info *hardwall; | 120 | struct hardwall_info *hardwall; |
diff --git a/arch/tile/include/asm/ptrace.h b/arch/tile/include/asm/ptrace.h index acdae814e01..4a02bb07397 100644 --- a/arch/tile/include/asm/ptrace.h +++ b/arch/tile/include/asm/ptrace.h | |||
@@ -51,10 +51,7 @@ typedef uint_reg_t pt_reg_t; | |||
51 | 51 | ||
52 | /* | 52 | /* |
53 | * This struct defines the way the registers are stored on the stack during a | 53 | * This struct defines the way the registers are stored on the stack during a |
54 | * system call/exception. It should be a multiple of 8 bytes to preserve | 54 | * system call or exception. "struct sigcontext" has the same shape. |
55 | * normal stack alignment rules. | ||
56 | * | ||
57 | * Must track <sys/ucontext.h> and <sys/procfs.h> | ||
58 | */ | 55 | */ |
59 | struct pt_regs { | 56 | struct pt_regs { |
60 | /* Saved main processor registers; 56..63 are special. */ | 57 | /* Saved main processor registers; 56..63 are special. */ |
@@ -80,11 +77,6 @@ struct pt_regs { | |||
80 | 77 | ||
81 | #endif /* __ASSEMBLY__ */ | 78 | #endif /* __ASSEMBLY__ */ |
82 | 79 | ||
83 | /* Flag bits in pt_regs.flags */ | ||
84 | #define PT_FLAGS_DISABLE_IRQ 1 /* on return to kernel, disable irqs */ | ||
85 | #define PT_FLAGS_CALLER_SAVES 2 /* caller-save registers are valid */ | ||
86 | #define PT_FLAGS_RESTORE_REGS 4 /* restore callee-save regs on return */ | ||
87 | |||
88 | #define PTRACE_GETREGS 12 | 80 | #define PTRACE_GETREGS 12 |
89 | #define PTRACE_SETREGS 13 | 81 | #define PTRACE_SETREGS 13 |
90 | #define PTRACE_GETFPREGS 14 | 82 | #define PTRACE_GETFPREGS 14 |
@@ -101,6 +93,11 @@ struct pt_regs { | |||
101 | 93 | ||
102 | #ifdef __KERNEL__ | 94 | #ifdef __KERNEL__ |
103 | 95 | ||
96 | /* Flag bits in pt_regs.flags */ | ||
97 | #define PT_FLAGS_DISABLE_IRQ 1 /* on return to kernel, disable irqs */ | ||
98 | #define PT_FLAGS_CALLER_SAVES 2 /* caller-save registers are valid */ | ||
99 | #define PT_FLAGS_RESTORE_REGS 4 /* restore callee-save regs on return */ | ||
100 | |||
104 | #ifndef __ASSEMBLY__ | 101 | #ifndef __ASSEMBLY__ |
105 | 102 | ||
106 | #define instruction_pointer(regs) ((regs)->pc) | 103 | #define instruction_pointer(regs) ((regs)->pc) |
diff --git a/arch/tile/include/asm/sigcontext.h b/arch/tile/include/asm/sigcontext.h index 7cd7672e3ad..5e2d03336f5 100644 --- a/arch/tile/include/asm/sigcontext.h +++ b/arch/tile/include/asm/sigcontext.h | |||
@@ -15,13 +15,21 @@ | |||
15 | #ifndef _ASM_TILE_SIGCONTEXT_H | 15 | #ifndef _ASM_TILE_SIGCONTEXT_H |
16 | #define _ASM_TILE_SIGCONTEXT_H | 16 | #define _ASM_TILE_SIGCONTEXT_H |
17 | 17 | ||
18 | /* NOTE: we can't include <linux/ptrace.h> due to #include dependencies. */ | 18 | #include <arch/abi.h> |
19 | #include <asm/ptrace.h> | ||
20 | |||
21 | /* Must track <sys/ucontext.h> */ | ||
22 | 19 | ||
20 | /* | ||
21 | * struct sigcontext has the same shape as struct pt_regs, | ||
22 | * but is simplified since we know the fault is from userspace. | ||
23 | */ | ||
23 | struct sigcontext { | 24 | struct sigcontext { |
24 | struct pt_regs regs; | 25 | uint_reg_t gregs[53]; /* General-purpose registers. */ |
26 | uint_reg_t tp; /* Aliases gregs[TREG_TP]. */ | ||
27 | uint_reg_t sp; /* Aliases gregs[TREG_SP]. */ | ||
28 | uint_reg_t lr; /* Aliases gregs[TREG_LR]. */ | ||
29 | uint_reg_t pc; /* Program counter. */ | ||
30 | uint_reg_t ics; /* In Interrupt Critical Section? */ | ||
31 | uint_reg_t faultnum; /* Fault number. */ | ||
32 | uint_reg_t pad[5]; | ||
25 | }; | 33 | }; |
26 | 34 | ||
27 | #endif /* _ASM_TILE_SIGCONTEXT_H */ | 35 | #endif /* _ASM_TILE_SIGCONTEXT_H */ |
diff --git a/arch/tile/include/asm/signal.h b/arch/tile/include/asm/signal.h index eb0253f3220..c1ee1d61d44 100644 --- a/arch/tile/include/asm/signal.h +++ b/arch/tile/include/asm/signal.h | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <asm-generic/signal.h> | 24 | #include <asm-generic/signal.h> |
25 | 25 | ||
26 | #if defined(__KERNEL__) && !defined(__ASSEMBLY__) | 26 | #if defined(__KERNEL__) && !defined(__ASSEMBLY__) |
27 | struct pt_regs; | ||
27 | int restore_sigcontext(struct pt_regs *, struct sigcontext __user *, long *); | 28 | int restore_sigcontext(struct pt_regs *, struct sigcontext __user *, long *); |
28 | int setup_sigcontext(struct sigcontext __user *, struct pt_regs *); | 29 | int setup_sigcontext(struct sigcontext __user *, struct pt_regs *); |
29 | void do_signal(struct pt_regs *regs); | 30 | void do_signal(struct pt_regs *regs); |
diff --git a/arch/tile/include/asm/syscalls.h b/arch/tile/include/asm/syscalls.h index af165a74537..ce99ffefeac 100644 --- a/arch/tile/include/asm/syscalls.h +++ b/arch/tile/include/asm/syscalls.h | |||
@@ -62,10 +62,12 @@ long sys_fork(void); | |||
62 | long _sys_fork(struct pt_regs *regs); | 62 | long _sys_fork(struct pt_regs *regs); |
63 | long sys_vfork(void); | 63 | long sys_vfork(void); |
64 | long _sys_vfork(struct pt_regs *regs); | 64 | long _sys_vfork(struct pt_regs *regs); |
65 | long sys_execve(char __user *filename, char __user * __user *argv, | 65 | long sys_execve(const char __user *filename, |
66 | char __user * __user *envp); | 66 | const char __user *const __user *argv, |
67 | long _sys_execve(char __user *filename, char __user * __user *argv, | 67 | const char __user *const __user *envp); |
68 | char __user * __user *envp, struct pt_regs *regs); | 68 | long _sys_execve(const char __user *filename, |
69 | const char __user *const __user *argv, | ||
70 | const char __user *const __user *envp, struct pt_regs *regs); | ||
69 | 71 | ||
70 | /* kernel/signal.c */ | 72 | /* kernel/signal.c */ |
71 | long sys_sigaltstack(const stack_t __user *, stack_t __user *); | 73 | long sys_sigaltstack(const stack_t __user *, stack_t __user *); |
@@ -86,10 +88,13 @@ int _sys_cmpxchg_badaddr(unsigned long address, struct pt_regs *); | |||
86 | #endif | 88 | #endif |
87 | 89 | ||
88 | #ifdef CONFIG_COMPAT | 90 | #ifdef CONFIG_COMPAT |
89 | long compat_sys_execve(char __user *path, compat_uptr_t __user *argv, | 91 | long compat_sys_execve(const char __user *path, |
90 | compat_uptr_t __user *envp); | 92 | const compat_uptr_t __user *argv, |
91 | long _compat_sys_execve(char __user *path, compat_uptr_t __user *argv, | 93 | const compat_uptr_t __user *envp); |
92 | compat_uptr_t __user *envp, struct pt_regs *regs); | 94 | long _compat_sys_execve(const char __user *path, |
95 | const compat_uptr_t __user *argv, | ||
96 | const compat_uptr_t __user *envp, | ||
97 | struct pt_regs *regs); | ||
93 | long compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr, | 98 | long compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr, |
94 | struct compat_sigaltstack __user *uoss_ptr); | 99 | struct compat_sigaltstack __user *uoss_ptr); |
95 | long _compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr, | 100 | long _compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr, |
diff --git a/arch/tile/kernel/intvec_32.S b/arch/tile/kernel/intvec_32.S index 84f296ca9e6..8f58bdff20d 100644 --- a/arch/tile/kernel/intvec_32.S +++ b/arch/tile/kernel/intvec_32.S | |||
@@ -1506,13 +1506,6 @@ handle_ill: | |||
1506 | } | 1506 | } |
1507 | STD_ENDPROC(handle_ill) | 1507 | STD_ENDPROC(handle_ill) |
1508 | 1508 | ||
1509 | .pushsection .rodata, "a" | ||
1510 | .align 8 | ||
1511 | bpt_code: | ||
1512 | bpt | ||
1513 | ENDPROC(bpt_code) | ||
1514 | .popsection | ||
1515 | |||
1516 | /* Various stub interrupt handlers and syscall handlers */ | 1509 | /* Various stub interrupt handlers and syscall handlers */ |
1517 | 1510 | ||
1518 | STD_ENTRY_LOCAL(_kernel_double_fault) | 1511 | STD_ENTRY_LOCAL(_kernel_double_fault) |
diff --git a/arch/tile/kernel/process.c b/arch/tile/kernel/process.c index 985cc28c74c..84c29111756 100644 --- a/arch/tile/kernel/process.c +++ b/arch/tile/kernel/process.c | |||
@@ -408,6 +408,15 @@ static void save_arch_state(struct thread_struct *t) | |||
408 | #if CHIP_HAS_PROC_STATUS_SPR() | 408 | #if CHIP_HAS_PROC_STATUS_SPR() |
409 | t->proc_status = __insn_mfspr(SPR_PROC_STATUS); | 409 | t->proc_status = __insn_mfspr(SPR_PROC_STATUS); |
410 | #endif | 410 | #endif |
411 | #if !CHIP_HAS_FIXED_INTVEC_BASE() | ||
412 | t->interrupt_vector_base = __insn_mfspr(SPR_INTERRUPT_VECTOR_BASE_0); | ||
413 | #endif | ||
414 | #if CHIP_HAS_TILE_RTF_HWM() | ||
415 | t->tile_rtf_hwm = __insn_mfspr(SPR_TILE_RTF_HWM); | ||
416 | #endif | ||
417 | #if CHIP_HAS_DSTREAM_PF() | ||
418 | t->dstream_pf = __insn_mfspr(SPR_DSTREAM_PF); | ||
419 | #endif | ||
411 | } | 420 | } |
412 | 421 | ||
413 | static void restore_arch_state(const struct thread_struct *t) | 422 | static void restore_arch_state(const struct thread_struct *t) |
@@ -428,14 +437,14 @@ static void restore_arch_state(const struct thread_struct *t) | |||
428 | #if CHIP_HAS_PROC_STATUS_SPR() | 437 | #if CHIP_HAS_PROC_STATUS_SPR() |
429 | __insn_mtspr(SPR_PROC_STATUS, t->proc_status); | 438 | __insn_mtspr(SPR_PROC_STATUS, t->proc_status); |
430 | #endif | 439 | #endif |
440 | #if !CHIP_HAS_FIXED_INTVEC_BASE() | ||
441 | __insn_mtspr(SPR_INTERRUPT_VECTOR_BASE_0, t->interrupt_vector_base); | ||
442 | #endif | ||
431 | #if CHIP_HAS_TILE_RTF_HWM() | 443 | #if CHIP_HAS_TILE_RTF_HWM() |
432 | /* | 444 | __insn_mtspr(SPR_TILE_RTF_HWM, t->tile_rtf_hwm); |
433 | * Clear this whenever we switch back to a process in case | 445 | #endif |
434 | * the previous process was monkeying with it. Even if enabled | 446 | #if CHIP_HAS_DSTREAM_PF() |
435 | * in CBOX_MSR1 via TILE_RTF_HWM_MIN, it's still just a | 447 | __insn_mtspr(SPR_DSTREAM_PF, t->dstream_pf); |
436 | * performance hint, so isn't worth a full save/restore. | ||
437 | */ | ||
438 | __insn_mtspr(SPR_TILE_RTF_HWM, 0); | ||
439 | #endif | 448 | #endif |
440 | } | 449 | } |
441 | 450 | ||
@@ -561,8 +570,9 @@ out: | |||
561 | } | 570 | } |
562 | 571 | ||
563 | #ifdef CONFIG_COMPAT | 572 | #ifdef CONFIG_COMPAT |
564 | long _compat_sys_execve(char __user *path, compat_uptr_t __user *argv, | 573 | long _compat_sys_execve(const char __user *path, |
565 | compat_uptr_t __user *envp, struct pt_regs *regs) | 574 | const compat_uptr_t __user *argv, |
575 | const compat_uptr_t __user *envp, struct pt_regs *regs) | ||
566 | { | 576 | { |
567 | long error; | 577 | long error; |
568 | char *filename; | 578 | char *filename; |
@@ -657,7 +667,7 @@ void show_regs(struct pt_regs *regs) | |||
657 | regs->regs[51], regs->regs[52], regs->tp); | 667 | regs->regs[51], regs->regs[52], regs->tp); |
658 | pr_err(" sp : "REGFMT" lr : "REGFMT"\n", regs->sp, regs->lr); | 668 | pr_err(" sp : "REGFMT" lr : "REGFMT"\n", regs->sp, regs->lr); |
659 | #else | 669 | #else |
660 | for (i = 0; i < 52; i += 3) | 670 | for (i = 0; i < 52; i += 4) |
661 | pr_err(" r%-2d: "REGFMT" r%-2d: "REGFMT | 671 | pr_err(" r%-2d: "REGFMT" r%-2d: "REGFMT |
662 | " r%-2d: "REGFMT" r%-2d: "REGFMT"\n", | 672 | " r%-2d: "REGFMT" r%-2d: "REGFMT"\n", |
663 | i, regs->regs[i], i+1, regs->regs[i+1], | 673 | i, regs->regs[i], i+1, regs->regs[i+1], |
diff --git a/arch/tile/kernel/signal.c b/arch/tile/kernel/signal.c index 45b66a3c991..ce183aa1492 100644 --- a/arch/tile/kernel/signal.c +++ b/arch/tile/kernel/signal.c | |||
@@ -61,13 +61,19 @@ int restore_sigcontext(struct pt_regs *regs, | |||
61 | /* Always make any pending restarted system calls return -EINTR */ | 61 | /* Always make any pending restarted system calls return -EINTR */ |
62 | current_thread_info()->restart_block.fn = do_no_restart_syscall; | 62 | current_thread_info()->restart_block.fn = do_no_restart_syscall; |
63 | 63 | ||
64 | /* | ||
65 | * Enforce that sigcontext is like pt_regs, and doesn't mess | ||
66 | * up our stack alignment rules. | ||
67 | */ | ||
68 | BUILD_BUG_ON(sizeof(struct sigcontext) != sizeof(struct pt_regs)); | ||
69 | BUILD_BUG_ON(sizeof(struct sigcontext) % 8 != 0); | ||
70 | |||
64 | for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i) | 71 | for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i) |
65 | err |= __get_user(((long *)regs)[i], | 72 | err |= __get_user(regs->regs[i], &sc->gregs[i]); |
66 | &((long __user *)(&sc->regs))[i]); | ||
67 | 73 | ||
68 | regs->faultnum = INT_SWINT_1_SIGRETURN; | 74 | regs->faultnum = INT_SWINT_1_SIGRETURN; |
69 | 75 | ||
70 | err |= __get_user(*pr0, &sc->regs.regs[0]); | 76 | err |= __get_user(*pr0, &sc->gregs[0]); |
71 | return err; | 77 | return err; |
72 | } | 78 | } |
73 | 79 | ||
@@ -112,8 +118,7 @@ int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs) | |||
112 | int i, err = 0; | 118 | int i, err = 0; |
113 | 119 | ||
114 | for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i) | 120 | for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i) |
115 | err |= __put_user(((long *)regs)[i], | 121 | err |= __put_user(regs->regs[i], &sc->gregs[i]); |
116 | &((long __user *)(&sc->regs))[i]); | ||
117 | 122 | ||
118 | return err; | 123 | return err; |
119 | } | 124 | } |
@@ -203,19 +208,17 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
203 | * Set up registers for signal handler. | 208 | * Set up registers for signal handler. |
204 | * Registers that we don't modify keep the value they had from | 209 | * Registers that we don't modify keep the value they had from |
205 | * user-space at the time we took the signal. | 210 | * user-space at the time we took the signal. |
211 | * We always pass siginfo and mcontext, regardless of SA_SIGINFO, | ||
212 | * since some things rely on this (e.g. glibc's debug/segfault.c). | ||
206 | */ | 213 | */ |
207 | regs->pc = (unsigned long) ka->sa.sa_handler; | 214 | regs->pc = (unsigned long) ka->sa.sa_handler; |
208 | regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */ | 215 | regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */ |
209 | regs->sp = (unsigned long) frame; | 216 | regs->sp = (unsigned long) frame; |
210 | regs->lr = restorer; | 217 | regs->lr = restorer; |
211 | regs->regs[0] = (unsigned long) usig; | 218 | regs->regs[0] = (unsigned long) usig; |
212 | 219 | regs->regs[1] = (unsigned long) &frame->info; | |
213 | if (ka->sa.sa_flags & SA_SIGINFO) { | 220 | regs->regs[2] = (unsigned long) &frame->uc; |
214 | /* Need extra arguments, so mark to restore caller-saves. */ | 221 | regs->flags |= PT_FLAGS_CALLER_SAVES; |
215 | regs->regs[1] = (unsigned long) &frame->info; | ||
216 | regs->regs[2] = (unsigned long) &frame->uc; | ||
217 | regs->flags |= PT_FLAGS_CALLER_SAVES; | ||
218 | } | ||
219 | 222 | ||
220 | /* | 223 | /* |
221 | * Notify any tracer that was single-stepping it. | 224 | * Notify any tracer that was single-stepping it. |
diff --git a/arch/tile/kernel/stack.c b/arch/tile/kernel/stack.c index 38a68b0b458..ea2e0ce2838 100644 --- a/arch/tile/kernel/stack.c +++ b/arch/tile/kernel/stack.c | |||
@@ -175,7 +175,7 @@ static struct pt_regs *valid_sigframe(struct KBacktraceIterator* kbt) | |||
175 | pr_err(" <received signal %d>\n", | 175 | pr_err(" <received signal %d>\n", |
176 | frame->info.si_signo); | 176 | frame->info.si_signo); |
177 | } | 177 | } |
178 | return &frame->uc.uc_mcontext.regs; | 178 | return (struct pt_regs *)&frame->uc.uc_mcontext; |
179 | } | 179 | } |
180 | return NULL; | 180 | return NULL; |
181 | } | 181 | } |
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index de317d0c329..ebc680717e5 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c | |||
@@ -690,7 +690,7 @@ static void with_console(struct mc_request *req, void (*proc)(void *), | |||
690 | static void sysrq_proc(void *arg) | 690 | static void sysrq_proc(void *arg) |
691 | { | 691 | { |
692 | char *op = arg; | 692 | char *op = arg; |
693 | handle_sysrq(*op, NULL); | 693 | handle_sysrq(*op); |
694 | } | 694 | } |
695 | 695 | ||
696 | void mconsole_sysrq(struct mc_request *req) | 696 | void mconsole_sysrq(struct mc_request *req) |
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 2ab233ba32c..47d0c37897d 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c | |||
@@ -255,18 +255,6 @@ static void uml_net_tx_timeout(struct net_device *dev) | |||
255 | netif_wake_queue(dev); | 255 | netif_wake_queue(dev); |
256 | } | 256 | } |
257 | 257 | ||
258 | static int uml_net_set_mac(struct net_device *dev, void *addr) | ||
259 | { | ||
260 | struct uml_net_private *lp = netdev_priv(dev); | ||
261 | struct sockaddr *hwaddr = addr; | ||
262 | |||
263 | spin_lock_irq(&lp->lock); | ||
264 | eth_mac_addr(dev, hwaddr->sa_data); | ||
265 | spin_unlock_irq(&lp->lock); | ||
266 | |||
267 | return 0; | ||
268 | } | ||
269 | |||
270 | static int uml_net_change_mtu(struct net_device *dev, int new_mtu) | 258 | static int uml_net_change_mtu(struct net_device *dev, int new_mtu) |
271 | { | 259 | { |
272 | dev->mtu = new_mtu; | 260 | dev->mtu = new_mtu; |
@@ -373,7 +361,7 @@ static const struct net_device_ops uml_netdev_ops = { | |||
373 | .ndo_start_xmit = uml_net_start_xmit, | 361 | .ndo_start_xmit = uml_net_start_xmit, |
374 | .ndo_set_multicast_list = uml_net_set_multicast_list, | 362 | .ndo_set_multicast_list = uml_net_set_multicast_list, |
375 | .ndo_tx_timeout = uml_net_tx_timeout, | 363 | .ndo_tx_timeout = uml_net_tx_timeout, |
376 | .ndo_set_mac_address = uml_net_set_mac, | 364 | .ndo_set_mac_address = eth_mac_addr, |
377 | .ndo_change_mtu = uml_net_change_mtu, | 365 | .ndo_change_mtu = uml_net_change_mtu, |
378 | .ndo_validate_addr = eth_validate_addr, | 366 | .ndo_validate_addr = eth_validate_addr, |
379 | }; | 367 | }; |
@@ -472,7 +460,8 @@ static void eth_configure(int n, void *init, char *mac, | |||
472 | ((*transport->user->init)(&lp->user, dev) != 0)) | 460 | ((*transport->user->init)(&lp->user, dev) != 0)) |
473 | goto out_unregister; | 461 | goto out_unregister; |
474 | 462 | ||
475 | eth_mac_addr(dev, device->mac); | 463 | /* don't use eth_mac_addr, it will not work here */ |
464 | memcpy(dev->dev_addr, device->mac, ETH_ALEN); | ||
476 | dev->mtu = transport->user->mtu; | 465 | dev->mtu = transport->user->mtu; |
477 | dev->netdev_ops = ¨_netdev_ops; | 466 | dev->netdev_ops = ¨_netdev_ops; |
478 | dev->ethtool_ops = ¨_net_ethtool_ops; | 467 | dev->ethtool_ops = ¨_net_ethtool_ops; |
diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c index cd145eda357..49b5e1eb326 100644 --- a/arch/um/kernel/exec.c +++ b/arch/um/kernel/exec.c | |||
@@ -62,7 +62,7 @@ static long execve1(const char *file, | |||
62 | return error; | 62 | return error; |
63 | } | 63 | } |
64 | 64 | ||
65 | long um_execve(const char *file, char __user *__user *argv, char __user *__user *env) | 65 | long um_execve(const char *file, const char __user *const __user *argv, const char __user *const __user *env) |
66 | { | 66 | { |
67 | long err; | 67 | long err; |
68 | 68 | ||
@@ -72,8 +72,8 @@ long um_execve(const char *file, char __user *__user *argv, char __user *__user | |||
72 | return err; | 72 | return err; |
73 | } | 73 | } |
74 | 74 | ||
75 | long sys_execve(const char __user *file, char __user *__user *argv, | 75 | long sys_execve(const char __user *file, const char __user *const __user *argv, |
76 | char __user *__user *env) | 76 | const char __user *const __user *env) |
77 | { | 77 | { |
78 | long error; | 78 | long error; |
79 | char *filename; | 79 | char *filename; |
diff --git a/arch/um/kernel/internal.h b/arch/um/kernel/internal.h index 1303a105fe9..5bf97db24a0 100644 --- a/arch/um/kernel/internal.h +++ b/arch/um/kernel/internal.h | |||
@@ -1 +1 @@ | |||
extern long um_execve(const char *file, char __user *__user *argv, char __user *__user *env); | extern long um_execve(const char *file, const char __user *const __user *argv, const char __user *const __user *env); | ||
diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c index 5ddb246626d..f958cb876ee 100644 --- a/arch/um/kernel/syscall.c +++ b/arch/um/kernel/syscall.c | |||
@@ -60,8 +60,8 @@ int kernel_execve(const char *filename, | |||
60 | 60 | ||
61 | fs = get_fs(); | 61 | fs = get_fs(); |
62 | set_fs(KERNEL_DS); | 62 | set_fs(KERNEL_DS); |
63 | ret = um_execve(filename, (char __user *__user *)argv, | 63 | ret = um_execve(filename, (const char __user *const __user *)argv, |
64 | (char __user *__user *) envp); | 64 | (const char __user *const __user *) envp); |
65 | set_fs(fs); | 65 | set_fs(fs); |
66 | 66 | ||
67 | return ret; | 67 | return ret; |
diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 8aa1b59b907..e8c8881351b 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile | |||
@@ -74,7 +74,7 @@ endif | |||
74 | 74 | ||
75 | ifdef CONFIG_CC_STACKPROTECTOR | 75 | ifdef CONFIG_CC_STACKPROTECTOR |
76 | cc_has_sp := $(srctree)/scripts/gcc-x86_$(BITS)-has-stack-protector.sh | 76 | cc_has_sp := $(srctree)/scripts/gcc-x86_$(BITS)-has-stack-protector.sh |
77 | ifeq ($(shell $(CONFIG_SHELL) $(cc_has_sp) $(CC) $(biarch)),y) | 77 | ifeq ($(shell $(CONFIG_SHELL) $(cc_has_sp) $(CC) $(KBUILD_CPPFLAGS) $(biarch)),y) |
78 | stackp-y := -fstack-protector | 78 | stackp-y := -fstack-protector |
79 | KBUILD_CFLAGS += $(stackp-y) | 79 | KBUILD_CFLAGS += $(stackp-y) |
80 | else | 80 | else |
diff --git a/arch/x86/boot/early_serial_console.c b/arch/x86/boot/early_serial_console.c index 030f4b93e25..5df2869c874 100644 --- a/arch/x86/boot/early_serial_console.c +++ b/arch/x86/boot/early_serial_console.c | |||
@@ -58,7 +58,19 @@ static void parse_earlyprintk(void) | |||
58 | if (arg[pos] == ',') | 58 | if (arg[pos] == ',') |
59 | pos++; | 59 | pos++; |
60 | 60 | ||
61 | if (!strncmp(arg, "ttyS", 4)) { | 61 | /* |
62 | * make sure we have | ||
63 | * "serial,0x3f8,115200" | ||
64 | * "serial,ttyS0,115200" | ||
65 | * "ttyS0,115200" | ||
66 | */ | ||
67 | if (pos == 7 && !strncmp(arg + pos, "0x", 2)) { | ||
68 | port = simple_strtoull(arg + pos, &e, 16); | ||
69 | if (port == 0 || arg + pos == e) | ||
70 | port = DEFAULT_SERIAL_PORT; | ||
71 | else | ||
72 | pos = e - arg; | ||
73 | } else if (!strncmp(arg + pos, "ttyS", 4)) { | ||
62 | static const int bases[] = { 0x3f8, 0x2f8 }; | 74 | static const int bases[] = { 0x3f8, 0x2f8 }; |
63 | int idx = 0; | 75 | int idx = 0; |
64 | 76 | ||
diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c index 0350311906a..2d93bdbc9ac 100644 --- a/arch/x86/ia32/ia32_aout.c +++ b/arch/x86/ia32/ia32_aout.c | |||
@@ -34,7 +34,7 @@ | |||
34 | #include <asm/ia32.h> | 34 | #include <asm/ia32.h> |
35 | 35 | ||
36 | #undef WARN_OLD | 36 | #undef WARN_OLD |
37 | #undef CORE_DUMP /* probably broken */ | 37 | #undef CORE_DUMP /* definitely broken */ |
38 | 38 | ||
39 | static int load_aout_binary(struct linux_binprm *, struct pt_regs *regs); | 39 | static int load_aout_binary(struct linux_binprm *, struct pt_regs *regs); |
40 | static int load_aout_library(struct file *); | 40 | static int load_aout_library(struct file *); |
@@ -131,21 +131,15 @@ static void set_brk(unsigned long start, unsigned long end) | |||
131 | * macros to write out all the necessary info. | 131 | * macros to write out all the necessary info. |
132 | */ | 132 | */ |
133 | 133 | ||
134 | static int dump_write(struct file *file, const void *addr, int nr) | 134 | #include <linux/coredump.h> |
135 | { | ||
136 | return file->f_op->write(file, addr, nr, &file->f_pos) == nr; | ||
137 | } | ||
138 | 135 | ||
139 | #define DUMP_WRITE(addr, nr) \ | 136 | #define DUMP_WRITE(addr, nr) \ |
140 | if (!dump_write(file, (void *)(addr), (nr))) \ | 137 | if (!dump_write(file, (void *)(addr), (nr))) \ |
141 | goto end_coredump; | 138 | goto end_coredump; |
142 | 139 | ||
143 | #define DUMP_SEEK(offset) \ | 140 | #define DUMP_SEEK(offset) \ |
144 | if (file->f_op->llseek) { \ | 141 | if (!dump_seek(file, offset)) \ |
145 | if (file->f_op->llseek(file, (offset), 0) != (offset)) \ | 142 | goto end_coredump; |
146 | goto end_coredump; \ | ||
147 | } else \ | ||
148 | file->f_pos = (offset) | ||
149 | 143 | ||
150 | #define START_DATA() (u.u_tsize << PAGE_SHIFT) | 144 | #define START_DATA() (u.u_tsize << PAGE_SHIFT) |
151 | #define START_STACK(u) (u.start_stack) | 145 | #define START_STACK(u) (u.start_stack) |
@@ -217,12 +211,6 @@ static int aout_core_dump(long signr, struct pt_regs *regs, struct file *file, | |||
217 | dump_size = dump.u_ssize << PAGE_SHIFT; | 211 | dump_size = dump.u_ssize << PAGE_SHIFT; |
218 | DUMP_WRITE(dump_start, dump_size); | 212 | DUMP_WRITE(dump_start, dump_size); |
219 | } | 213 | } |
220 | /* | ||
221 | * Finally dump the task struct. Not be used by gdb, but | ||
222 | * could be useful | ||
223 | */ | ||
224 | set_fs(KERNEL_DS); | ||
225 | DUMP_WRITE(current, sizeof(*current)); | ||
226 | end_coredump: | 214 | end_coredump: |
227 | set_fs(fs); | 215 | set_fs(fs); |
228 | return has_dumped; | 216 | return has_dumped; |
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index b86feabed69..518bb99c339 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S | |||
@@ -50,7 +50,12 @@ | |||
50 | /* | 50 | /* |
51 | * Reload arg registers from stack in case ptrace changed them. | 51 | * Reload arg registers from stack in case ptrace changed them. |
52 | * We don't reload %eax because syscall_trace_enter() returned | 52 | * We don't reload %eax because syscall_trace_enter() returned |
53 | * the value it wants us to use in the table lookup. | 53 | * the %rax value we should see. Instead, we just truncate that |
54 | * value to 32 bits again as we did on entry from user mode. | ||
55 | * If it's a new value set by user_regset during entry tracing, | ||
56 | * this matches the normal truncation of the user-mode value. | ||
57 | * If it's -1 to make us punt the syscall, then (u32)-1 is still | ||
58 | * an appropriately invalid value. | ||
54 | */ | 59 | */ |
55 | .macro LOAD_ARGS32 offset, _r9=0 | 60 | .macro LOAD_ARGS32 offset, _r9=0 |
56 | .if \_r9 | 61 | .if \_r9 |
@@ -60,6 +65,7 @@ | |||
60 | movl \offset+48(%rsp),%edx | 65 | movl \offset+48(%rsp),%edx |
61 | movl \offset+56(%rsp),%esi | 66 | movl \offset+56(%rsp),%esi |
62 | movl \offset+64(%rsp),%edi | 67 | movl \offset+64(%rsp),%edi |
68 | movl %eax,%eax /* zero extension */ | ||
63 | .endm | 69 | .endm |
64 | 70 | ||
65 | .macro CFI_STARTPROC32 simple | 71 | .macro CFI_STARTPROC32 simple |
@@ -153,7 +159,7 @@ ENTRY(ia32_sysenter_target) | |||
153 | testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10) | 159 | testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10) |
154 | CFI_REMEMBER_STATE | 160 | CFI_REMEMBER_STATE |
155 | jnz sysenter_tracesys | 161 | jnz sysenter_tracesys |
156 | cmpl $(IA32_NR_syscalls-1),%eax | 162 | cmpq $(IA32_NR_syscalls-1),%rax |
157 | ja ia32_badsys | 163 | ja ia32_badsys |
158 | sysenter_do_call: | 164 | sysenter_do_call: |
159 | IA32_ARG_FIXUP | 165 | IA32_ARG_FIXUP |
@@ -195,7 +201,7 @@ sysexit_from_sys_call: | |||
195 | movl $AUDIT_ARCH_I386,%edi /* 1st arg: audit arch */ | 201 | movl $AUDIT_ARCH_I386,%edi /* 1st arg: audit arch */ |
196 | call audit_syscall_entry | 202 | call audit_syscall_entry |
197 | movl RAX-ARGOFFSET(%rsp),%eax /* reload syscall number */ | 203 | movl RAX-ARGOFFSET(%rsp),%eax /* reload syscall number */ |
198 | cmpl $(IA32_NR_syscalls-1),%eax | 204 | cmpq $(IA32_NR_syscalls-1),%rax |
199 | ja ia32_badsys | 205 | ja ia32_badsys |
200 | movl %ebx,%edi /* reload 1st syscall arg */ | 206 | movl %ebx,%edi /* reload 1st syscall arg */ |
201 | movl RCX-ARGOFFSET(%rsp),%esi /* reload 2nd syscall arg */ | 207 | movl RCX-ARGOFFSET(%rsp),%esi /* reload 2nd syscall arg */ |
@@ -248,7 +254,7 @@ sysenter_tracesys: | |||
248 | call syscall_trace_enter | 254 | call syscall_trace_enter |
249 | LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */ | 255 | LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */ |
250 | RESTORE_REST | 256 | RESTORE_REST |
251 | cmpl $(IA32_NR_syscalls-1),%eax | 257 | cmpq $(IA32_NR_syscalls-1),%rax |
252 | ja int_ret_from_sys_call /* sysenter_tracesys has set RAX(%rsp) */ | 258 | ja int_ret_from_sys_call /* sysenter_tracesys has set RAX(%rsp) */ |
253 | jmp sysenter_do_call | 259 | jmp sysenter_do_call |
254 | CFI_ENDPROC | 260 | CFI_ENDPROC |
@@ -314,7 +320,7 @@ ENTRY(ia32_cstar_target) | |||
314 | testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10) | 320 | testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10) |
315 | CFI_REMEMBER_STATE | 321 | CFI_REMEMBER_STATE |
316 | jnz cstar_tracesys | 322 | jnz cstar_tracesys |
317 | cmpl $IA32_NR_syscalls-1,%eax | 323 | cmpq $IA32_NR_syscalls-1,%rax |
318 | ja ia32_badsys | 324 | ja ia32_badsys |
319 | cstar_do_call: | 325 | cstar_do_call: |
320 | IA32_ARG_FIXUP 1 | 326 | IA32_ARG_FIXUP 1 |
@@ -367,7 +373,7 @@ cstar_tracesys: | |||
367 | LOAD_ARGS32 ARGOFFSET, 1 /* reload args from stack in case ptrace changed it */ | 373 | LOAD_ARGS32 ARGOFFSET, 1 /* reload args from stack in case ptrace changed it */ |
368 | RESTORE_REST | 374 | RESTORE_REST |
369 | xchgl %ebp,%r9d | 375 | xchgl %ebp,%r9d |
370 | cmpl $(IA32_NR_syscalls-1),%eax | 376 | cmpq $(IA32_NR_syscalls-1),%rax |
371 | ja int_ret_from_sys_call /* cstar_tracesys has set RAX(%rsp) */ | 377 | ja int_ret_from_sys_call /* cstar_tracesys has set RAX(%rsp) */ |
372 | jmp cstar_do_call | 378 | jmp cstar_do_call |
373 | END(ia32_cstar_target) | 379 | END(ia32_cstar_target) |
@@ -425,7 +431,7 @@ ENTRY(ia32_syscall) | |||
425 | orl $TS_COMPAT,TI_status(%r10) | 431 | orl $TS_COMPAT,TI_status(%r10) |
426 | testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10) | 432 | testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10) |
427 | jnz ia32_tracesys | 433 | jnz ia32_tracesys |
428 | cmpl $(IA32_NR_syscalls-1),%eax | 434 | cmpq $(IA32_NR_syscalls-1),%rax |
429 | ja ia32_badsys | 435 | ja ia32_badsys |
430 | ia32_do_call: | 436 | ia32_do_call: |
431 | IA32_ARG_FIXUP | 437 | IA32_ARG_FIXUP |
@@ -444,7 +450,7 @@ ia32_tracesys: | |||
444 | call syscall_trace_enter | 450 | call syscall_trace_enter |
445 | LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */ | 451 | LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */ |
446 | RESTORE_REST | 452 | RESTORE_REST |
447 | cmpl $(IA32_NR_syscalls-1),%eax | 453 | cmpq $(IA32_NR_syscalls-1),%rax |
448 | ja int_ret_from_sys_call /* ia32_tracesys has set RAX(%rsp) */ | 454 | ja int_ret_from_sys_call /* ia32_tracesys has set RAX(%rsp) */ |
449 | jmp ia32_do_call | 455 | jmp ia32_do_call |
450 | END(ia32_syscall) | 456 | END(ia32_syscall) |
diff --git a/arch/x86/include/asm/amd_iommu_proto.h b/arch/x86/include/asm/amd_iommu_proto.h index d2544f1d705..cb030374b90 100644 --- a/arch/x86/include/asm/amd_iommu_proto.h +++ b/arch/x86/include/asm/amd_iommu_proto.h | |||
@@ -38,4 +38,10 @@ static inline void amd_iommu_stats_init(void) { } | |||
38 | 38 | ||
39 | #endif /* !CONFIG_AMD_IOMMU_STATS */ | 39 | #endif /* !CONFIG_AMD_IOMMU_STATS */ |
40 | 40 | ||
41 | static inline bool is_rd890_iommu(struct pci_dev *pdev) | ||
42 | { | ||
43 | return (pdev->vendor == PCI_VENDOR_ID_ATI) && | ||
44 | (pdev->device == PCI_DEVICE_ID_RD890_IOMMU); | ||
45 | } | ||
46 | |||
41 | #endif /* _ASM_X86_AMD_IOMMU_PROTO_H */ | 47 | #endif /* _ASM_X86_AMD_IOMMU_PROTO_H */ |
diff --git a/arch/x86/include/asm/amd_iommu_types.h b/arch/x86/include/asm/amd_iommu_types.h index 7014e88bc77..08616180dea 100644 --- a/arch/x86/include/asm/amd_iommu_types.h +++ b/arch/x86/include/asm/amd_iommu_types.h | |||
@@ -368,6 +368,9 @@ struct amd_iommu { | |||
368 | /* capabilities of that IOMMU read from ACPI */ | 368 | /* capabilities of that IOMMU read from ACPI */ |
369 | u32 cap; | 369 | u32 cap; |
370 | 370 | ||
371 | /* flags read from acpi table */ | ||
372 | u8 acpi_flags; | ||
373 | |||
371 | /* | 374 | /* |
372 | * Capability pointer. There could be more than one IOMMU per PCI | 375 | * Capability pointer. There could be more than one IOMMU per PCI |
373 | * device function if there are more than one AMD IOMMU capability | 376 | * device function if there are more than one AMD IOMMU capability |
@@ -411,6 +414,15 @@ struct amd_iommu { | |||
411 | 414 | ||
412 | /* default dma_ops domain for that IOMMU */ | 415 | /* default dma_ops domain for that IOMMU */ |
413 | struct dma_ops_domain *default_dom; | 416 | struct dma_ops_domain *default_dom; |
417 | |||
418 | /* | ||
419 | * This array is required to work around a potential BIOS bug. | ||
420 | * The BIOS may miss to restore parts of the PCI configuration | ||
421 | * space when the system resumes from S3. The result is that the | ||
422 | * IOMMU does not execute commands anymore which leads to system | ||
423 | * failure. | ||
424 | */ | ||
425 | u32 cache_cfg[4]; | ||
414 | }; | 426 | }; |
415 | 427 | ||
416 | /* | 428 | /* |
diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h index 545776efeb1..bafd80defa4 100644 --- a/arch/x86/include/asm/bitops.h +++ b/arch/x86/include/asm/bitops.h | |||
@@ -309,7 +309,7 @@ static inline int test_and_change_bit(int nr, volatile unsigned long *addr) | |||
309 | static __always_inline int constant_test_bit(unsigned int nr, const volatile unsigned long *addr) | 309 | static __always_inline int constant_test_bit(unsigned int nr, const volatile unsigned long *addr) |
310 | { | 310 | { |
311 | return ((1UL << (nr % BITS_PER_LONG)) & | 311 | return ((1UL << (nr % BITS_PER_LONG)) & |
312 | (((unsigned long *)addr)[nr / BITS_PER_LONG])) != 0; | 312 | (addr[nr / BITS_PER_LONG])) != 0; |
313 | } | 313 | } |
314 | 314 | ||
315 | static inline int variable_test_bit(int nr, volatile const unsigned long *addr) | 315 | static inline int variable_test_bit(int nr, volatile const unsigned long *addr) |
diff --git a/arch/x86/include/asm/compat.h b/arch/x86/include/asm/compat.h index 306160e58b4..1d9cd27c292 100644 --- a/arch/x86/include/asm/compat.h +++ b/arch/x86/include/asm/compat.h | |||
@@ -205,7 +205,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) | |||
205 | return (u32)(unsigned long)uptr; | 205 | return (u32)(unsigned long)uptr; |
206 | } | 206 | } |
207 | 207 | ||
208 | static inline void __user *compat_alloc_user_space(long len) | 208 | static inline void __user *arch_compat_alloc_user_space(long len) |
209 | { | 209 | { |
210 | struct pt_regs *regs = task_pt_regs(current); | 210 | struct pt_regs *regs = task_pt_regs(current); |
211 | return (void __user *)regs->sp - len; | 211 | return (void __user *)regs->sp - len; |
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index 781a50b29a4..3f76523589a 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h | |||
@@ -168,6 +168,7 @@ | |||
168 | #define X86_FEATURE_XSAVEOPT (7*32+ 4) /* Optimized Xsave */ | 168 | #define X86_FEATURE_XSAVEOPT (7*32+ 4) /* Optimized Xsave */ |
169 | #define X86_FEATURE_PLN (7*32+ 5) /* Intel Power Limit Notification */ | 169 | #define X86_FEATURE_PLN (7*32+ 5) /* Intel Power Limit Notification */ |
170 | #define X86_FEATURE_PTS (7*32+ 6) /* Intel Package Thermal Status */ | 170 | #define X86_FEATURE_PTS (7*32+ 6) /* Intel Package Thermal Status */ |
171 | #define X86_FEATURE_DTS (7*32+ 7) /* Digital Thermal Sensor */ | ||
171 | 172 | ||
172 | /* Virtualization flags: Linux defined, word 8 */ | 173 | /* Virtualization flags: Linux defined, word 8 */ |
173 | #define X86_FEATURE_TPR_SHADOW (8*32+ 0) /* Intel TPR Shadow */ | 174 | #define X86_FEATURE_TPR_SHADOW (8*32+ 0) /* Intel TPR Shadow */ |
@@ -296,6 +297,7 @@ extern const char * const x86_power_flags[32]; | |||
296 | 297 | ||
297 | #endif /* CONFIG_X86_64 */ | 298 | #endif /* CONFIG_X86_64 */ |
298 | 299 | ||
300 | #if __GNUC__ >= 4 | ||
299 | /* | 301 | /* |
300 | * Static testing of CPU features. Used the same as boot_cpu_has(). | 302 | * Static testing of CPU features. Used the same as boot_cpu_has(). |
301 | * These are only valid after alternatives have run, but will statically | 303 | * These are only valid after alternatives have run, but will statically |
@@ -304,7 +306,7 @@ extern const char * const x86_power_flags[32]; | |||
304 | */ | 306 | */ |
305 | static __always_inline __pure bool __static_cpu_has(u16 bit) | 307 | static __always_inline __pure bool __static_cpu_has(u16 bit) |
306 | { | 308 | { |
307 | #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) | 309 | #if __GNUC__ > 4 || __GNUC_MINOR__ >= 5 |
308 | asm goto("1: jmp %l[t_no]\n" | 310 | asm goto("1: jmp %l[t_no]\n" |
309 | "2:\n" | 311 | "2:\n" |
310 | ".section .altinstructions,\"a\"\n" | 312 | ".section .altinstructions,\"a\"\n" |
@@ -345,7 +347,6 @@ static __always_inline __pure bool __static_cpu_has(u16 bit) | |||
345 | #endif | 347 | #endif |
346 | } | 348 | } |
347 | 349 | ||
348 | #if __GNUC__ >= 4 | ||
349 | #define static_cpu_has(bit) \ | 350 | #define static_cpu_has(bit) \ |
350 | ( \ | 351 | ( \ |
351 | __builtin_constant_p(boot_cpu_has(bit)) ? \ | 352 | __builtin_constant_p(boot_cpu_has(bit)) ? \ |
diff --git a/arch/x86/include/asm/hpet.h b/arch/x86/include/asm/hpet.h index 004e6e25e91..1d5c08a1bdf 100644 --- a/arch/x86/include/asm/hpet.h +++ b/arch/x86/include/asm/hpet.h | |||
@@ -68,7 +68,6 @@ extern unsigned long force_hpet_address; | |||
68 | extern u8 hpet_blockid; | 68 | extern u8 hpet_blockid; |
69 | extern int hpet_force_user; | 69 | extern int hpet_force_user; |
70 | extern u8 hpet_msi_disable; | 70 | extern u8 hpet_msi_disable; |
71 | extern u8 hpet_readback_cmp; | ||
72 | extern int is_hpet_enabled(void); | 71 | extern int is_hpet_enabled(void); |
73 | extern int hpet_enable(void); | 72 | extern int hpet_enable(void); |
74 | extern void hpet_disable(void); | 73 | extern void hpet_disable(void); |
diff --git a/arch/x86/include/asm/hw_breakpoint.h b/arch/x86/include/asm/hw_breakpoint.h index 528a11e8d3e..824ca07860d 100644 --- a/arch/x86/include/asm/hw_breakpoint.h +++ b/arch/x86/include/asm/hw_breakpoint.h | |||
@@ -20,7 +20,7 @@ struct arch_hw_breakpoint { | |||
20 | #include <linux/list.h> | 20 | #include <linux/list.h> |
21 | 21 | ||
22 | /* Available HW breakpoint length encodings */ | 22 | /* Available HW breakpoint length encodings */ |
23 | #define X86_BREAKPOINT_LEN_X 0x00 | 23 | #define X86_BREAKPOINT_LEN_X 0x40 |
24 | #define X86_BREAKPOINT_LEN_1 0x40 | 24 | #define X86_BREAKPOINT_LEN_1 0x40 |
25 | #define X86_BREAKPOINT_LEN_2 0x44 | 25 | #define X86_BREAKPOINT_LEN_2 0x44 |
26 | #define X86_BREAKPOINT_LEN_4 0x4c | 26 | #define X86_BREAKPOINT_LEN_4 0x4c |
diff --git a/arch/x86/include/asm/iomap.h b/arch/x86/include/asm/iomap.h index f35eb45d657..c4191b3b705 100644 --- a/arch/x86/include/asm/iomap.h +++ b/arch/x86/include/asm/iomap.h | |||
@@ -26,11 +26,11 @@ | |||
26 | #include <asm/pgtable.h> | 26 | #include <asm/pgtable.h> |
27 | #include <asm/tlbflush.h> | 27 | #include <asm/tlbflush.h> |
28 | 28 | ||
29 | void * | 29 | void __iomem * |
30 | iomap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot); | 30 | iomap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot); |
31 | 31 | ||
32 | void | 32 | void |
33 | iounmap_atomic(void *kvaddr, enum km_type type); | 33 | iounmap_atomic(void __iomem *kvaddr, enum km_type type); |
34 | 34 | ||
35 | int | 35 | int |
36 | iomap_create_wc(resource_size_t base, unsigned long size, pgprot_t *prot); | 36 | iomap_create_wc(resource_size_t base, unsigned long size, pgprot_t *prot); |
diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h index 51cfd730ac5..1f99ecfc48e 100644 --- a/arch/x86/include/asm/kvm_emulate.h +++ b/arch/x86/include/asm/kvm_emulate.h | |||
@@ -152,9 +152,14 @@ struct x86_emulate_ops { | |||
152 | struct operand { | 152 | struct operand { |
153 | enum { OP_REG, OP_MEM, OP_IMM, OP_NONE } type; | 153 | enum { OP_REG, OP_MEM, OP_IMM, OP_NONE } type; |
154 | unsigned int bytes; | 154 | unsigned int bytes; |
155 | unsigned long orig_val, *ptr; | 155 | union { |
156 | unsigned long orig_val; | ||
157 | u64 orig_val64; | ||
158 | }; | ||
159 | unsigned long *ptr; | ||
156 | union { | 160 | union { |
157 | unsigned long val; | 161 | unsigned long val; |
162 | u64 val64; | ||
158 | char valptr[sizeof(unsigned long) + 2]; | 163 | char valptr[sizeof(unsigned long) + 2]; |
159 | }; | 164 | }; |
160 | }; | 165 | }; |
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h index 404a880ea32..d395540ff89 100644 --- a/arch/x86/include/asm/pci.h +++ b/arch/x86/include/asm/pci.h | |||
@@ -27,6 +27,9 @@ extern struct pci_bus *pci_scan_bus_on_node(int busno, struct pci_ops *ops, | |||
27 | int node); | 27 | int node); |
28 | extern struct pci_bus *pci_scan_bus_with_sysdata(int busno); | 28 | extern struct pci_bus *pci_scan_bus_with_sysdata(int busno); |
29 | 29 | ||
30 | #ifdef CONFIG_PCI | ||
31 | |||
32 | #ifdef CONFIG_PCI_DOMAINS | ||
30 | static inline int pci_domain_nr(struct pci_bus *bus) | 33 | static inline int pci_domain_nr(struct pci_bus *bus) |
31 | { | 34 | { |
32 | struct pci_sysdata *sd = bus->sysdata; | 35 | struct pci_sysdata *sd = bus->sysdata; |
@@ -37,13 +40,12 @@ static inline int pci_proc_domain(struct pci_bus *bus) | |||
37 | { | 40 | { |
38 | return pci_domain_nr(bus); | 41 | return pci_domain_nr(bus); |
39 | } | 42 | } |
40 | 43 | #endif | |
41 | 44 | ||
42 | /* Can be used to override the logic in pci_scan_bus for skipping | 45 | /* Can be used to override the logic in pci_scan_bus for skipping |
43 | already-configured bus numbers - to be used for buggy BIOSes | 46 | already-configured bus numbers - to be used for buggy BIOSes |
44 | or architectures with incomplete PCI setup by the loader */ | 47 | or architectures with incomplete PCI setup by the loader */ |
45 | 48 | ||
46 | #ifdef CONFIG_PCI | ||
47 | extern unsigned int pcibios_assign_all_busses(void); | 49 | extern unsigned int pcibios_assign_all_busses(void); |
48 | extern int pci_legacy_init(void); | 50 | extern int pci_legacy_init(void); |
49 | # ifdef CONFIG_ACPI | 51 | # ifdef CONFIG_ACPI |
diff --git a/arch/x86/include/asm/tsc.h b/arch/x86/include/asm/tsc.h index c0427295e8f..1ca132fc0d0 100644 --- a/arch/x86/include/asm/tsc.h +++ b/arch/x86/include/asm/tsc.h | |||
@@ -59,5 +59,7 @@ extern void check_tsc_sync_source(int cpu); | |||
59 | extern void check_tsc_sync_target(void); | 59 | extern void check_tsc_sync_target(void); |
60 | 60 | ||
61 | extern int notsc_setup(char *); | 61 | extern int notsc_setup(char *); |
62 | extern void save_sched_clock_state(void); | ||
63 | extern void restore_sched_clock_state(void); | ||
62 | 64 | ||
63 | #endif /* _ASM_X86_TSC_H */ | 65 | #endif /* _ASM_X86_TSC_H */ |
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 0925676266b..fedf32a8c3e 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile | |||
@@ -11,6 +11,8 @@ ifdef CONFIG_FUNCTION_TRACER | |||
11 | CFLAGS_REMOVE_tsc.o = -pg | 11 | CFLAGS_REMOVE_tsc.o = -pg |
12 | CFLAGS_REMOVE_rtc.o = -pg | 12 | CFLAGS_REMOVE_rtc.o = -pg |
13 | CFLAGS_REMOVE_paravirt-spinlocks.o = -pg | 13 | CFLAGS_REMOVE_paravirt-spinlocks.o = -pg |
14 | CFLAGS_REMOVE_pvclock.o = -pg | ||
15 | CFLAGS_REMOVE_kvmclock.o = -pg | ||
14 | CFLAGS_REMOVE_ftrace.o = -pg | 16 | CFLAGS_REMOVE_ftrace.o = -pg |
15 | CFLAGS_REMOVE_early_printk.o = -pg | 17 | CFLAGS_REMOVE_early_printk.o = -pg |
16 | endif | 18 | endif |
diff --git a/arch/x86/kernel/acpi/cstate.c b/arch/x86/kernel/acpi/cstate.c index fb7a5f052e2..fb16f17e59b 100644 --- a/arch/x86/kernel/acpi/cstate.c +++ b/arch/x86/kernel/acpi/cstate.c | |||
@@ -61,7 +61,7 @@ struct cstate_entry { | |||
61 | unsigned int ecx; | 61 | unsigned int ecx; |
62 | } states[ACPI_PROCESSOR_MAX_POWER]; | 62 | } states[ACPI_PROCESSOR_MAX_POWER]; |
63 | }; | 63 | }; |
64 | static struct cstate_entry *cpu_cstate_entry; /* per CPU ptr */ | 64 | static struct cstate_entry __percpu *cpu_cstate_entry; /* per CPU ptr */ |
65 | 65 | ||
66 | static short mwait_supported[ACPI_PROCESSOR_MAX_POWER]; | 66 | static short mwait_supported[ACPI_PROCESSOR_MAX_POWER]; |
67 | 67 | ||
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index fa044e1e30a..679b6450382 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c | |||
@@ -1953,6 +1953,7 @@ static void __unmap_single(struct dma_ops_domain *dma_dom, | |||
1953 | size_t size, | 1953 | size_t size, |
1954 | int dir) | 1954 | int dir) |
1955 | { | 1955 | { |
1956 | dma_addr_t flush_addr; | ||
1956 | dma_addr_t i, start; | 1957 | dma_addr_t i, start; |
1957 | unsigned int pages; | 1958 | unsigned int pages; |
1958 | 1959 | ||
@@ -1960,6 +1961,7 @@ static void __unmap_single(struct dma_ops_domain *dma_dom, | |||
1960 | (dma_addr + size > dma_dom->aperture_size)) | 1961 | (dma_addr + size > dma_dom->aperture_size)) |
1961 | return; | 1962 | return; |
1962 | 1963 | ||
1964 | flush_addr = dma_addr; | ||
1963 | pages = iommu_num_pages(dma_addr, size, PAGE_SIZE); | 1965 | pages = iommu_num_pages(dma_addr, size, PAGE_SIZE); |
1964 | dma_addr &= PAGE_MASK; | 1966 | dma_addr &= PAGE_MASK; |
1965 | start = dma_addr; | 1967 | start = dma_addr; |
@@ -1974,7 +1976,7 @@ static void __unmap_single(struct dma_ops_domain *dma_dom, | |||
1974 | dma_ops_free_addresses(dma_dom, dma_addr, pages); | 1976 | dma_ops_free_addresses(dma_dom, dma_addr, pages); |
1975 | 1977 | ||
1976 | if (amd_iommu_unmap_flush || dma_dom->need_flush) { | 1978 | if (amd_iommu_unmap_flush || dma_dom->need_flush) { |
1977 | iommu_flush_pages(&dma_dom->domain, dma_addr, size); | 1979 | iommu_flush_pages(&dma_dom->domain, flush_addr, size); |
1978 | dma_dom->need_flush = false; | 1980 | dma_dom->need_flush = false; |
1979 | } | 1981 | } |
1980 | } | 1982 | } |
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index 3cc63e2b8dd..5a170cbbbed 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c | |||
@@ -632,6 +632,13 @@ static void __init init_iommu_from_pci(struct amd_iommu *iommu) | |||
632 | iommu->last_device = calc_devid(MMIO_GET_BUS(range), | 632 | iommu->last_device = calc_devid(MMIO_GET_BUS(range), |
633 | MMIO_GET_LD(range)); | 633 | MMIO_GET_LD(range)); |
634 | iommu->evt_msi_num = MMIO_MSI_NUM(misc); | 634 | iommu->evt_msi_num = MMIO_MSI_NUM(misc); |
635 | |||
636 | if (is_rd890_iommu(iommu->dev)) { | ||
637 | pci_read_config_dword(iommu->dev, 0xf0, &iommu->cache_cfg[0]); | ||
638 | pci_read_config_dword(iommu->dev, 0xf4, &iommu->cache_cfg[1]); | ||
639 | pci_read_config_dword(iommu->dev, 0xf8, &iommu->cache_cfg[2]); | ||
640 | pci_read_config_dword(iommu->dev, 0xfc, &iommu->cache_cfg[3]); | ||
641 | } | ||
635 | } | 642 | } |
636 | 643 | ||
637 | /* | 644 | /* |
@@ -649,29 +656,9 @@ static void __init init_iommu_from_acpi(struct amd_iommu *iommu, | |||
649 | struct ivhd_entry *e; | 656 | struct ivhd_entry *e; |
650 | 657 | ||
651 | /* | 658 | /* |
652 | * First set the recommended feature enable bits from ACPI | 659 | * First save the recommended feature enable bits from ACPI |
653 | * into the IOMMU control registers | ||
654 | */ | 660 | */ |
655 | h->flags & IVHD_FLAG_HT_TUN_EN_MASK ? | 661 | iommu->acpi_flags = h->flags; |
656 | iommu_feature_enable(iommu, CONTROL_HT_TUN_EN) : | ||
657 | iommu_feature_disable(iommu, CONTROL_HT_TUN_EN); | ||
658 | |||
659 | h->flags & IVHD_FLAG_PASSPW_EN_MASK ? | ||
660 | iommu_feature_enable(iommu, CONTROL_PASSPW_EN) : | ||
661 | iommu_feature_disable(iommu, CONTROL_PASSPW_EN); | ||
662 | |||
663 | h->flags & IVHD_FLAG_RESPASSPW_EN_MASK ? | ||
664 | iommu_feature_enable(iommu, CONTROL_RESPASSPW_EN) : | ||
665 | iommu_feature_disable(iommu, CONTROL_RESPASSPW_EN); | ||
666 | |||
667 | h->flags & IVHD_FLAG_ISOC_EN_MASK ? | ||
668 | iommu_feature_enable(iommu, CONTROL_ISOC_EN) : | ||
669 | iommu_feature_disable(iommu, CONTROL_ISOC_EN); | ||
670 | |||
671 | /* | ||
672 | * make IOMMU memory accesses cache coherent | ||
673 | */ | ||
674 | iommu_feature_enable(iommu, CONTROL_COHERENT_EN); | ||
675 | 662 | ||
676 | /* | 663 | /* |
677 | * Done. Now parse the device entries | 664 | * Done. Now parse the device entries |
@@ -1116,6 +1103,40 @@ static void init_device_table(void) | |||
1116 | } | 1103 | } |
1117 | } | 1104 | } |
1118 | 1105 | ||
1106 | static void iommu_init_flags(struct amd_iommu *iommu) | ||
1107 | { | ||
1108 | iommu->acpi_flags & IVHD_FLAG_HT_TUN_EN_MASK ? | ||
1109 | iommu_feature_enable(iommu, CONTROL_HT_TUN_EN) : | ||
1110 | iommu_feature_disable(iommu, CONTROL_HT_TUN_EN); | ||
1111 | |||
1112 | iommu->acpi_flags & IVHD_FLAG_PASSPW_EN_MASK ? | ||
1113 | iommu_feature_enable(iommu, CONTROL_PASSPW_EN) : | ||
1114 | iommu_feature_disable(iommu, CONTROL_PASSPW_EN); | ||
1115 | |||
1116 | iommu->acpi_flags & IVHD_FLAG_RESPASSPW_EN_MASK ? | ||
1117 | iommu_feature_enable(iommu, CONTROL_RESPASSPW_EN) : | ||
1118 | iommu_feature_disable(iommu, CONTROL_RESPASSPW_EN); | ||
1119 | |||
1120 | iommu->acpi_flags & IVHD_FLAG_ISOC_EN_MASK ? | ||
1121 | iommu_feature_enable(iommu, CONTROL_ISOC_EN) : | ||
1122 | iommu_feature_disable(iommu, CONTROL_ISOC_EN); | ||
1123 | |||
1124 | /* | ||
1125 | * make IOMMU memory accesses cache coherent | ||
1126 | */ | ||
1127 | iommu_feature_enable(iommu, CONTROL_COHERENT_EN); | ||
1128 | } | ||
1129 | |||
1130 | static void iommu_apply_quirks(struct amd_iommu *iommu) | ||
1131 | { | ||
1132 | if (is_rd890_iommu(iommu->dev)) { | ||
1133 | pci_write_config_dword(iommu->dev, 0xf0, iommu->cache_cfg[0]); | ||
1134 | pci_write_config_dword(iommu->dev, 0xf4, iommu->cache_cfg[1]); | ||
1135 | pci_write_config_dword(iommu->dev, 0xf8, iommu->cache_cfg[2]); | ||
1136 | pci_write_config_dword(iommu->dev, 0xfc, iommu->cache_cfg[3]); | ||
1137 | } | ||
1138 | } | ||
1139 | |||
1119 | /* | 1140 | /* |
1120 | * This function finally enables all IOMMUs found in the system after | 1141 | * This function finally enables all IOMMUs found in the system after |
1121 | * they have been initialized | 1142 | * they have been initialized |
@@ -1126,6 +1147,8 @@ static void enable_iommus(void) | |||
1126 | 1147 | ||
1127 | for_each_iommu(iommu) { | 1148 | for_each_iommu(iommu) { |
1128 | iommu_disable(iommu); | 1149 | iommu_disable(iommu); |
1150 | iommu_apply_quirks(iommu); | ||
1151 | iommu_init_flags(iommu); | ||
1129 | iommu_set_device_table(iommu); | 1152 | iommu_set_device_table(iommu); |
1130 | iommu_enable_command_buffer(iommu); | 1153 | iommu_enable_command_buffer(iommu); |
1131 | iommu_enable_event_buffer(iommu); | 1154 | iommu_enable_event_buffer(iommu); |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index f1efebaf551..5c5b8f3dddb 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -306,14 +306,19 @@ void arch_init_copy_chip_data(struct irq_desc *old_desc, | |||
306 | 306 | ||
307 | old_cfg = old_desc->chip_data; | 307 | old_cfg = old_desc->chip_data; |
308 | 308 | ||
309 | memcpy(cfg, old_cfg, sizeof(struct irq_cfg)); | 309 | cfg->vector = old_cfg->vector; |
310 | cfg->move_in_progress = old_cfg->move_in_progress; | ||
311 | cpumask_copy(cfg->domain, old_cfg->domain); | ||
312 | cpumask_copy(cfg->old_domain, old_cfg->old_domain); | ||
310 | 313 | ||
311 | init_copy_irq_2_pin(old_cfg, cfg, node); | 314 | init_copy_irq_2_pin(old_cfg, cfg, node); |
312 | } | 315 | } |
313 | 316 | ||
314 | static void free_irq_cfg(struct irq_cfg *old_cfg) | 317 | static void free_irq_cfg(struct irq_cfg *cfg) |
315 | { | 318 | { |
316 | kfree(old_cfg); | 319 | free_cpumask_var(cfg->domain); |
320 | free_cpumask_var(cfg->old_domain); | ||
321 | kfree(cfg); | ||
317 | } | 322 | } |
318 | 323 | ||
319 | void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc) | 324 | void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc) |
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index 7b598b84c90..f744f54cb24 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c | |||
@@ -698,9 +698,11 @@ void __init uv_system_init(void) | |||
698 | for (j = 0; j < 64; j++) { | 698 | for (j = 0; j < 64; j++) { |
699 | if (!test_bit(j, &present)) | 699 | if (!test_bit(j, &present)) |
700 | continue; | 700 | continue; |
701 | uv_blade_info[blade].pnode = (i * 64 + j); | 701 | pnode = (i * 64 + j); |
702 | uv_blade_info[blade].pnode = pnode; | ||
702 | uv_blade_info[blade].nr_possible_cpus = 0; | 703 | uv_blade_info[blade].nr_possible_cpus = 0; |
703 | uv_blade_info[blade].nr_online_cpus = 0; | 704 | uv_blade_info[blade].nr_online_cpus = 0; |
705 | max_pnode = max(pnode, max_pnode); | ||
704 | blade++; | 706 | blade++; |
705 | } | 707 | } |
706 | } | 708 | } |
@@ -738,7 +740,6 @@ void __init uv_system_init(void) | |||
738 | uv_cpu_hub_info(cpu)->scir.offset = uv_scir_offset(apicid); | 740 | uv_cpu_hub_info(cpu)->scir.offset = uv_scir_offset(apicid); |
739 | uv_node_to_blade[nid] = blade; | 741 | uv_node_to_blade[nid] = blade; |
740 | uv_cpu_to_blade[cpu] = blade; | 742 | uv_cpu_to_blade[cpu] = blade; |
741 | max_pnode = max(pnode, max_pnode); | ||
742 | } | 743 | } |
743 | 744 | ||
744 | /* Add blade/pnode info for nodes without cpus */ | 745 | /* Add blade/pnode info for nodes without cpus */ |
@@ -750,7 +751,6 @@ void __init uv_system_init(void) | |||
750 | pnode = (paddr >> m_val) & pnode_mask; | 751 | pnode = (paddr >> m_val) & pnode_mask; |
751 | blade = boot_pnode_to_blade(pnode); | 752 | blade = boot_pnode_to_blade(pnode); |
752 | uv_node_to_blade[nid] = blade; | 753 | uv_node_to_blade[nid] = blade; |
753 | max_pnode = max(pnode, max_pnode); | ||
754 | } | 754 | } |
755 | 755 | ||
756 | map_gru_high(max_pnode); | 756 | map_gru_high(max_pnode); |
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 490dac63c2d..f2f9ac7da25 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -545,7 +545,7 @@ void __cpuinit cpu_detect(struct cpuinfo_x86 *c) | |||
545 | } | 545 | } |
546 | } | 546 | } |
547 | 547 | ||
548 | static void __cpuinit get_cpu_cap(struct cpuinfo_x86 *c) | 548 | void __cpuinit get_cpu_cap(struct cpuinfo_x86 *c) |
549 | { | 549 | { |
550 | u32 tfms, xlvl; | 550 | u32 tfms, xlvl; |
551 | u32 ebx; | 551 | u32 ebx; |
diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h index 3624e8a0f71..f668bb1f7d4 100644 --- a/arch/x86/kernel/cpu/cpu.h +++ b/arch/x86/kernel/cpu/cpu.h | |||
@@ -33,5 +33,6 @@ extern const struct cpu_dev *const __x86_cpu_dev_start[], | |||
33 | *const __x86_cpu_dev_end[]; | 33 | *const __x86_cpu_dev_end[]; |
34 | 34 | ||
35 | extern void cpu_detect_cache_sizes(struct cpuinfo_x86 *c); | 35 | extern void cpu_detect_cache_sizes(struct cpuinfo_x86 *c); |
36 | extern void get_cpu_cap(struct cpuinfo_x86 *c); | ||
36 | 37 | ||
37 | #endif | 38 | #endif |
diff --git a/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c index 994230d4dc4..4f6f679f279 100644 --- a/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c | |||
@@ -368,16 +368,22 @@ static int __init pcc_cpufreq_do_osc(acpi_handle *handle) | |||
368 | return -ENODEV; | 368 | return -ENODEV; |
369 | 369 | ||
370 | out_obj = output.pointer; | 370 | out_obj = output.pointer; |
371 | if (out_obj->type != ACPI_TYPE_BUFFER) | 371 | if (out_obj->type != ACPI_TYPE_BUFFER) { |
372 | return -ENODEV; | 372 | ret = -ENODEV; |
373 | goto out_free; | ||
374 | } | ||
373 | 375 | ||
374 | errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0); | 376 | errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0); |
375 | if (errors) | 377 | if (errors) { |
376 | return -ENODEV; | 378 | ret = -ENODEV; |
379 | goto out_free; | ||
380 | } | ||
377 | 381 | ||
378 | supported = *((u32 *)(out_obj->buffer.pointer + 4)); | 382 | supported = *((u32 *)(out_obj->buffer.pointer + 4)); |
379 | if (!(supported & 0x1)) | 383 | if (!(supported & 0x1)) { |
380 | return -ENODEV; | 384 | ret = -ENODEV; |
385 | goto out_free; | ||
386 | } | ||
381 | 387 | ||
382 | out_free: | 388 | out_free: |
383 | kfree(output.pointer); | 389 | kfree(output.pointer); |
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 85f69cdeae1..b4389441efb 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c | |||
@@ -39,6 +39,7 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c) | |||
39 | misc_enable &= ~MSR_IA32_MISC_ENABLE_LIMIT_CPUID; | 39 | misc_enable &= ~MSR_IA32_MISC_ENABLE_LIMIT_CPUID; |
40 | wrmsrl(MSR_IA32_MISC_ENABLE, misc_enable); | 40 | wrmsrl(MSR_IA32_MISC_ENABLE, misc_enable); |
41 | c->cpuid_level = cpuid_eax(0); | 41 | c->cpuid_level = cpuid_eax(0); |
42 | get_cpu_cap(c); | ||
42 | } | 43 | } |
43 | } | 44 | } |
44 | 45 | ||
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index 224392d8fe8..39aaee5c1ab 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c | |||
@@ -141,6 +141,7 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c) | |||
141 | address = (low & MASK_BLKPTR_LO) >> 21; | 141 | address = (low & MASK_BLKPTR_LO) >> 21; |
142 | if (!address) | 142 | if (!address) |
143 | break; | 143 | break; |
144 | |||
144 | address += MCG_XBLK_ADDR; | 145 | address += MCG_XBLK_ADDR; |
145 | } else | 146 | } else |
146 | ++address; | 147 | ++address; |
@@ -148,12 +149,8 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c) | |||
148 | if (rdmsr_safe(address, &low, &high)) | 149 | if (rdmsr_safe(address, &low, &high)) |
149 | break; | 150 | break; |
150 | 151 | ||
151 | if (!(high & MASK_VALID_HI)) { | 152 | if (!(high & MASK_VALID_HI)) |
152 | if (block) | 153 | continue; |
153 | continue; | ||
154 | else | ||
155 | break; | ||
156 | } | ||
157 | 154 | ||
158 | if (!(high & MASK_CNTP_HI) || | 155 | if (!(high & MASK_CNTP_HI) || |
159 | (high & MASK_LOCKED_HI)) | 156 | (high & MASK_LOCKED_HI)) |
@@ -530,7 +527,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank) | |||
530 | err = -ENOMEM; | 527 | err = -ENOMEM; |
531 | goto out; | 528 | goto out; |
532 | } | 529 | } |
533 | if (!alloc_cpumask_var(&b->cpus, GFP_KERNEL)) { | 530 | if (!zalloc_cpumask_var(&b->cpus, GFP_KERNEL)) { |
534 | kfree(b); | 531 | kfree(b); |
535 | err = -ENOMEM; | 532 | err = -ENOMEM; |
536 | goto out; | 533 | goto out; |
@@ -543,7 +540,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank) | |||
543 | #ifndef CONFIG_SMP | 540 | #ifndef CONFIG_SMP |
544 | cpumask_setall(b->cpus); | 541 | cpumask_setall(b->cpus); |
545 | #else | 542 | #else |
546 | cpumask_copy(b->cpus, c->llc_shared_map); | 543 | cpumask_set_cpu(cpu, b->cpus); |
547 | #endif | 544 | #endif |
548 | 545 | ||
549 | per_cpu(threshold_banks, cpu)[bank] = b; | 546 | per_cpu(threshold_banks, cpu)[bank] = b; |
diff --git a/arch/x86/kernel/cpu/mcheck/therm_throt.c b/arch/x86/kernel/cpu/mcheck/therm_throt.c index c2a8b26d4fe..169d8804a9f 100644 --- a/arch/x86/kernel/cpu/mcheck/therm_throt.c +++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c | |||
@@ -202,10 +202,11 @@ static int therm_throt_process(bool new_event, int event, int level) | |||
202 | 202 | ||
203 | #ifdef CONFIG_SYSFS | 203 | #ifdef CONFIG_SYSFS |
204 | /* Add/Remove thermal_throttle interface for CPU device: */ | 204 | /* Add/Remove thermal_throttle interface for CPU device: */ |
205 | static __cpuinit int thermal_throttle_add_dev(struct sys_device *sys_dev) | 205 | static __cpuinit int thermal_throttle_add_dev(struct sys_device *sys_dev, |
206 | unsigned int cpu) | ||
206 | { | 207 | { |
207 | int err; | 208 | int err; |
208 | struct cpuinfo_x86 *c = &cpu_data(smp_processor_id()); | 209 | struct cpuinfo_x86 *c = &cpu_data(cpu); |
209 | 210 | ||
210 | err = sysfs_create_group(&sys_dev->kobj, &thermal_attr_group); | 211 | err = sysfs_create_group(&sys_dev->kobj, &thermal_attr_group); |
211 | if (err) | 212 | if (err) |
@@ -215,7 +216,7 @@ static __cpuinit int thermal_throttle_add_dev(struct sys_device *sys_dev) | |||
215 | err = sysfs_add_file_to_group(&sys_dev->kobj, | 216 | err = sysfs_add_file_to_group(&sys_dev->kobj, |
216 | &attr_core_power_limit_count.attr, | 217 | &attr_core_power_limit_count.attr, |
217 | thermal_attr_group.name); | 218 | thermal_attr_group.name); |
218 | if (cpu_has(c, X86_FEATURE_PTS)) | 219 | if (cpu_has(c, X86_FEATURE_PTS)) { |
219 | err = sysfs_add_file_to_group(&sys_dev->kobj, | 220 | err = sysfs_add_file_to_group(&sys_dev->kobj, |
220 | &attr_package_throttle_count.attr, | 221 | &attr_package_throttle_count.attr, |
221 | thermal_attr_group.name); | 222 | thermal_attr_group.name); |
@@ -223,6 +224,7 @@ static __cpuinit int thermal_throttle_add_dev(struct sys_device *sys_dev) | |||
223 | err = sysfs_add_file_to_group(&sys_dev->kobj, | 224 | err = sysfs_add_file_to_group(&sys_dev->kobj, |
224 | &attr_package_power_limit_count.attr, | 225 | &attr_package_power_limit_count.attr, |
225 | thermal_attr_group.name); | 226 | thermal_attr_group.name); |
227 | } | ||
226 | 228 | ||
227 | return err; | 229 | return err; |
228 | } | 230 | } |
@@ -251,7 +253,7 @@ thermal_throttle_cpu_callback(struct notifier_block *nfb, | |||
251 | case CPU_UP_PREPARE: | 253 | case CPU_UP_PREPARE: |
252 | case CPU_UP_PREPARE_FROZEN: | 254 | case CPU_UP_PREPARE_FROZEN: |
253 | mutex_lock(&therm_cpu_lock); | 255 | mutex_lock(&therm_cpu_lock); |
254 | err = thermal_throttle_add_dev(sys_dev); | 256 | err = thermal_throttle_add_dev(sys_dev, cpu); |
255 | mutex_unlock(&therm_cpu_lock); | 257 | mutex_unlock(&therm_cpu_lock); |
256 | WARN_ON(err); | 258 | WARN_ON(err); |
257 | break; | 259 | break; |
@@ -287,7 +289,7 @@ static __init int thermal_throttle_init_device(void) | |||
287 | #endif | 289 | #endif |
288 | /* connect live CPUs to sysfs */ | 290 | /* connect live CPUs to sysfs */ |
289 | for_each_online_cpu(cpu) { | 291 | for_each_online_cpu(cpu) { |
290 | err = thermal_throttle_add_dev(get_cpu_sysdev(cpu)); | 292 | err = thermal_throttle_add_dev(get_cpu_sysdev(cpu), cpu); |
291 | WARN_ON(err); | 293 | WARN_ON(err); |
292 | } | 294 | } |
293 | #ifdef CONFIG_HOTPLUG_CPU | 295 | #ifdef CONFIG_HOTPLUG_CPU |
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index f2da20fda02..03a5b0385ad 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c | |||
@@ -102,6 +102,7 @@ struct cpu_hw_events { | |||
102 | */ | 102 | */ |
103 | struct perf_event *events[X86_PMC_IDX_MAX]; /* in counter order */ | 103 | struct perf_event *events[X86_PMC_IDX_MAX]; /* in counter order */ |
104 | unsigned long active_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; | 104 | unsigned long active_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; |
105 | unsigned long running[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; | ||
105 | int enabled; | 106 | int enabled; |
106 | 107 | ||
107 | int n_events; | 108 | int n_events; |
@@ -1010,6 +1011,7 @@ static int x86_pmu_start(struct perf_event *event) | |||
1010 | x86_perf_event_set_period(event); | 1011 | x86_perf_event_set_period(event); |
1011 | cpuc->events[idx] = event; | 1012 | cpuc->events[idx] = event; |
1012 | __set_bit(idx, cpuc->active_mask); | 1013 | __set_bit(idx, cpuc->active_mask); |
1014 | __set_bit(idx, cpuc->running); | ||
1013 | x86_pmu.enable(event); | 1015 | x86_pmu.enable(event); |
1014 | perf_event_update_userpage(event); | 1016 | perf_event_update_userpage(event); |
1015 | 1017 | ||
@@ -1141,8 +1143,16 @@ static int x86_pmu_handle_irq(struct pt_regs *regs) | |||
1141 | cpuc = &__get_cpu_var(cpu_hw_events); | 1143 | cpuc = &__get_cpu_var(cpu_hw_events); |
1142 | 1144 | ||
1143 | for (idx = 0; idx < x86_pmu.num_counters; idx++) { | 1145 | for (idx = 0; idx < x86_pmu.num_counters; idx++) { |
1144 | if (!test_bit(idx, cpuc->active_mask)) | 1146 | if (!test_bit(idx, cpuc->active_mask)) { |
1147 | /* | ||
1148 | * Though we deactivated the counter some cpus | ||
1149 | * might still deliver spurious interrupts still | ||
1150 | * in flight. Catch them: | ||
1151 | */ | ||
1152 | if (__test_and_clear_bit(idx, cpuc->running)) | ||
1153 | handled++; | ||
1145 | continue; | 1154 | continue; |
1155 | } | ||
1146 | 1156 | ||
1147 | event = cpuc->events[idx]; | 1157 | event = cpuc->events[idx]; |
1148 | hwc = &event->hw; | 1158 | hwc = &event->hw; |
@@ -1154,7 +1164,7 @@ static int x86_pmu_handle_irq(struct pt_regs *regs) | |||
1154 | /* | 1164 | /* |
1155 | * event overflow | 1165 | * event overflow |
1156 | */ | 1166 | */ |
1157 | handled = 1; | 1167 | handled++; |
1158 | data.period = event->hw.last_period; | 1168 | data.period = event->hw.last_period; |
1159 | 1169 | ||
1160 | if (!x86_perf_event_set_period(event)) | 1170 | if (!x86_perf_event_set_period(event)) |
@@ -1200,12 +1210,20 @@ void perf_events_lapic_init(void) | |||
1200 | apic_write(APIC_LVTPC, APIC_DM_NMI); | 1210 | apic_write(APIC_LVTPC, APIC_DM_NMI); |
1201 | } | 1211 | } |
1202 | 1212 | ||
1213 | struct pmu_nmi_state { | ||
1214 | unsigned int marked; | ||
1215 | int handled; | ||
1216 | }; | ||
1217 | |||
1218 | static DEFINE_PER_CPU(struct pmu_nmi_state, pmu_nmi); | ||
1219 | |||
1203 | static int __kprobes | 1220 | static int __kprobes |
1204 | perf_event_nmi_handler(struct notifier_block *self, | 1221 | perf_event_nmi_handler(struct notifier_block *self, |
1205 | unsigned long cmd, void *__args) | 1222 | unsigned long cmd, void *__args) |
1206 | { | 1223 | { |
1207 | struct die_args *args = __args; | 1224 | struct die_args *args = __args; |
1208 | struct pt_regs *regs; | 1225 | unsigned int this_nmi; |
1226 | int handled; | ||
1209 | 1227 | ||
1210 | if (!atomic_read(&active_events)) | 1228 | if (!atomic_read(&active_events)) |
1211 | return NOTIFY_DONE; | 1229 | return NOTIFY_DONE; |
@@ -1214,22 +1232,47 @@ perf_event_nmi_handler(struct notifier_block *self, | |||
1214 | case DIE_NMI: | 1232 | case DIE_NMI: |
1215 | case DIE_NMI_IPI: | 1233 | case DIE_NMI_IPI: |
1216 | break; | 1234 | break; |
1217 | 1235 | case DIE_NMIUNKNOWN: | |
1236 | this_nmi = percpu_read(irq_stat.__nmi_count); | ||
1237 | if (this_nmi != __get_cpu_var(pmu_nmi).marked) | ||
1238 | /* let the kernel handle the unknown nmi */ | ||
1239 | return NOTIFY_DONE; | ||
1240 | /* | ||
1241 | * This one is a PMU back-to-back nmi. Two events | ||
1242 | * trigger 'simultaneously' raising two back-to-back | ||
1243 | * NMIs. If the first NMI handles both, the latter | ||
1244 | * will be empty and daze the CPU. So, we drop it to | ||
1245 | * avoid false-positive 'unknown nmi' messages. | ||
1246 | */ | ||
1247 | return NOTIFY_STOP; | ||
1218 | default: | 1248 | default: |
1219 | return NOTIFY_DONE; | 1249 | return NOTIFY_DONE; |
1220 | } | 1250 | } |
1221 | 1251 | ||
1222 | regs = args->regs; | ||
1223 | |||
1224 | apic_write(APIC_LVTPC, APIC_DM_NMI); | 1252 | apic_write(APIC_LVTPC, APIC_DM_NMI); |
1225 | /* | 1253 | |
1226 | * Can't rely on the handled return value to say it was our NMI, two | 1254 | handled = x86_pmu.handle_irq(args->regs); |
1227 | * events could trigger 'simultaneously' raising two back-to-back NMIs. | 1255 | if (!handled) |
1228 | * | 1256 | return NOTIFY_DONE; |
1229 | * If the first NMI handles both, the latter will be empty and daze | 1257 | |
1230 | * the CPU. | 1258 | this_nmi = percpu_read(irq_stat.__nmi_count); |
1231 | */ | 1259 | if ((handled > 1) || |
1232 | x86_pmu.handle_irq(regs); | 1260 | /* the next nmi could be a back-to-back nmi */ |
1261 | ((__get_cpu_var(pmu_nmi).marked == this_nmi) && | ||
1262 | (__get_cpu_var(pmu_nmi).handled > 1))) { | ||
1263 | /* | ||
1264 | * We could have two subsequent back-to-back nmis: The | ||
1265 | * first handles more than one counter, the 2nd | ||
1266 | * handles only one counter and the 3rd handles no | ||
1267 | * counter. | ||
1268 | * | ||
1269 | * This is the 2nd nmi because the previous was | ||
1270 | * handling more than one counter. We will mark the | ||
1271 | * next (3rd) and then drop it if unhandled. | ||
1272 | */ | ||
1273 | __get_cpu_var(pmu_nmi).marked = this_nmi + 1; | ||
1274 | __get_cpu_var(pmu_nmi).handled = handled; | ||
1275 | } | ||
1233 | 1276 | ||
1234 | return NOTIFY_STOP; | 1277 | return NOTIFY_STOP; |
1235 | } | 1278 | } |
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index d8d86d01400..ee05c90012d 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c | |||
@@ -712,7 +712,8 @@ static int intel_pmu_handle_irq(struct pt_regs *regs) | |||
712 | struct perf_sample_data data; | 712 | struct perf_sample_data data; |
713 | struct cpu_hw_events *cpuc; | 713 | struct cpu_hw_events *cpuc; |
714 | int bit, loops; | 714 | int bit, loops; |
715 | u64 ack, status; | 715 | u64 status; |
716 | int handled = 0; | ||
716 | 717 | ||
717 | perf_sample_data_init(&data, 0); | 718 | perf_sample_data_init(&data, 0); |
718 | 719 | ||
@@ -728,6 +729,7 @@ static int intel_pmu_handle_irq(struct pt_regs *regs) | |||
728 | 729 | ||
729 | loops = 0; | 730 | loops = 0; |
730 | again: | 731 | again: |
732 | intel_pmu_ack_status(status); | ||
731 | if (++loops > 100) { | 733 | if (++loops > 100) { |
732 | WARN_ONCE(1, "perfevents: irq loop stuck!\n"); | 734 | WARN_ONCE(1, "perfevents: irq loop stuck!\n"); |
733 | perf_event_print_debug(); | 735 | perf_event_print_debug(); |
@@ -736,19 +738,22 @@ again: | |||
736 | } | 738 | } |
737 | 739 | ||
738 | inc_irq_stat(apic_perf_irqs); | 740 | inc_irq_stat(apic_perf_irqs); |
739 | ack = status; | ||
740 | 741 | ||
741 | intel_pmu_lbr_read(); | 742 | intel_pmu_lbr_read(); |
742 | 743 | ||
743 | /* | 744 | /* |
744 | * PEBS overflow sets bit 62 in the global status register | 745 | * PEBS overflow sets bit 62 in the global status register |
745 | */ | 746 | */ |
746 | if (__test_and_clear_bit(62, (unsigned long *)&status)) | 747 | if (__test_and_clear_bit(62, (unsigned long *)&status)) { |
748 | handled++; | ||
747 | x86_pmu.drain_pebs(regs); | 749 | x86_pmu.drain_pebs(regs); |
750 | } | ||
748 | 751 | ||
749 | for_each_set_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) { | 752 | for_each_set_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) { |
750 | struct perf_event *event = cpuc->events[bit]; | 753 | struct perf_event *event = cpuc->events[bit]; |
751 | 754 | ||
755 | handled++; | ||
756 | |||
752 | if (!test_bit(bit, cpuc->active_mask)) | 757 | if (!test_bit(bit, cpuc->active_mask)) |
753 | continue; | 758 | continue; |
754 | 759 | ||
@@ -761,8 +766,6 @@ again: | |||
761 | x86_pmu_stop(event); | 766 | x86_pmu_stop(event); |
762 | } | 767 | } |
763 | 768 | ||
764 | intel_pmu_ack_status(ack); | ||
765 | |||
766 | /* | 769 | /* |
767 | * Repeat if there is more work to be done: | 770 | * Repeat if there is more work to be done: |
768 | */ | 771 | */ |
@@ -772,7 +775,7 @@ again: | |||
772 | 775 | ||
773 | done: | 776 | done: |
774 | intel_pmu_enable_all(0); | 777 | intel_pmu_enable_all(0); |
775 | return 1; | 778 | return handled; |
776 | } | 779 | } |
777 | 780 | ||
778 | static struct event_constraint * | 781 | static struct event_constraint * |
diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c index febb12cea79..24901517399 100644 --- a/arch/x86/kernel/cpu/perf_event_p4.c +++ b/arch/x86/kernel/cpu/perf_event_p4.c | |||
@@ -497,6 +497,8 @@ static int p4_hw_config(struct perf_event *event) | |||
497 | event->hw.config |= event->attr.config & | 497 | event->hw.config |= event->attr.config & |
498 | (p4_config_pack_escr(P4_ESCR_MASK_HT) | | 498 | (p4_config_pack_escr(P4_ESCR_MASK_HT) | |
499 | p4_config_pack_cccr(P4_CCCR_MASK_HT | P4_CCCR_RESERVED)); | 499 | p4_config_pack_cccr(P4_CCCR_MASK_HT | P4_CCCR_RESERVED)); |
500 | |||
501 | event->hw.config &= ~P4_CCCR_FORCE_OVF; | ||
500 | } | 502 | } |
501 | 503 | ||
502 | rc = x86_setup_perfctr(event); | 504 | rc = x86_setup_perfctr(event); |
@@ -658,8 +660,12 @@ static int p4_pmu_handle_irq(struct pt_regs *regs) | |||
658 | for (idx = 0; idx < x86_pmu.num_counters; idx++) { | 660 | for (idx = 0; idx < x86_pmu.num_counters; idx++) { |
659 | int overflow; | 661 | int overflow; |
660 | 662 | ||
661 | if (!test_bit(idx, cpuc->active_mask)) | 663 | if (!test_bit(idx, cpuc->active_mask)) { |
664 | /* catch in-flight IRQs */ | ||
665 | if (__test_and_clear_bit(idx, cpuc->running)) | ||
666 | handled++; | ||
662 | continue; | 667 | continue; |
668 | } | ||
663 | 669 | ||
664 | event = cpuc->events[idx]; | 670 | event = cpuc->events[idx]; |
665 | hwc = &event->hw; | 671 | hwc = &event->hw; |
@@ -690,7 +696,7 @@ static int p4_pmu_handle_irq(struct pt_regs *regs) | |||
690 | inc_irq_stat(apic_perf_irqs); | 696 | inc_irq_stat(apic_perf_irqs); |
691 | } | 697 | } |
692 | 698 | ||
693 | return handled > 0; | 699 | return handled; |
694 | } | 700 | } |
695 | 701 | ||
696 | /* | 702 | /* |
diff --git a/arch/x86/kernel/cpu/scattered.c b/arch/x86/kernel/cpu/scattered.c index 34b4dad6f0b..d4907951512 100644 --- a/arch/x86/kernel/cpu/scattered.c +++ b/arch/x86/kernel/cpu/scattered.c | |||
@@ -31,6 +31,7 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c) | |||
31 | const struct cpuid_bit *cb; | 31 | const struct cpuid_bit *cb; |
32 | 32 | ||
33 | static const struct cpuid_bit __cpuinitconst cpuid_bits[] = { | 33 | static const struct cpuid_bit __cpuinitconst cpuid_bits[] = { |
34 | { X86_FEATURE_DTS, CR_EAX, 0, 0x00000006, 0 }, | ||
34 | { X86_FEATURE_IDA, CR_EAX, 1, 0x00000006, 0 }, | 35 | { X86_FEATURE_IDA, CR_EAX, 1, 0x00000006, 0 }, |
35 | { X86_FEATURE_ARAT, CR_EAX, 2, 0x00000006, 0 }, | 36 | { X86_FEATURE_ARAT, CR_EAX, 2, 0x00000006, 0 }, |
36 | { X86_FEATURE_PLN, CR_EAX, 4, 0x00000006, 0 }, | 37 | { X86_FEATURE_PLN, CR_EAX, 4, 0x00000006, 0 }, |
diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c index e5cc7e82e60..ebdb85cf268 100644 --- a/arch/x86/kernel/early-quirks.c +++ b/arch/x86/kernel/early-quirks.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <asm/apic.h> | 18 | #include <asm/apic.h> |
19 | #include <asm/iommu.h> | 19 | #include <asm/iommu.h> |
20 | #include <asm/gart.h> | 20 | #include <asm/gart.h> |
21 | #include <asm/hpet.h> | ||
22 | 21 | ||
23 | static void __init fix_hypertransport_config(int num, int slot, int func) | 22 | static void __init fix_hypertransport_config(int num, int slot, int func) |
24 | { | 23 | { |
@@ -192,21 +191,6 @@ static void __init ati_bugs_contd(int num, int slot, int func) | |||
192 | } | 191 | } |
193 | #endif | 192 | #endif |
194 | 193 | ||
195 | /* | ||
196 | * Force the read back of the CMP register in hpet_next_event() | ||
197 | * to work around the problem that the CMP register write seems to be | ||
198 | * delayed. See hpet_next_event() for details. | ||
199 | * | ||
200 | * We do this on all SMBUS incarnations for now until we have more | ||
201 | * information about the affected chipsets. | ||
202 | */ | ||
203 | static void __init ati_hpet_bugs(int num, int slot, int func) | ||
204 | { | ||
205 | #ifdef CONFIG_HPET_TIMER | ||
206 | hpet_readback_cmp = 1; | ||
207 | #endif | ||
208 | } | ||
209 | |||
210 | #define QFLAG_APPLY_ONCE 0x1 | 194 | #define QFLAG_APPLY_ONCE 0x1 |
211 | #define QFLAG_APPLIED 0x2 | 195 | #define QFLAG_APPLIED 0x2 |
212 | #define QFLAG_DONE (QFLAG_APPLY_ONCE|QFLAG_APPLIED) | 196 | #define QFLAG_DONE (QFLAG_APPLY_ONCE|QFLAG_APPLIED) |
@@ -236,8 +220,6 @@ static struct chipset early_qrk[] __initdata = { | |||
236 | PCI_CLASS_SERIAL_SMBUS, PCI_ANY_ID, 0, ati_bugs }, | 220 | PCI_CLASS_SERIAL_SMBUS, PCI_ANY_ID, 0, ati_bugs }, |
237 | { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS, | 221 | { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS, |
238 | PCI_CLASS_SERIAL_SMBUS, PCI_ANY_ID, 0, ati_bugs_contd }, | 222 | PCI_CLASS_SERIAL_SMBUS, PCI_ANY_ID, 0, ati_bugs_contd }, |
239 | { PCI_VENDOR_ID_ATI, PCI_ANY_ID, | ||
240 | PCI_CLASS_SERIAL_SMBUS, PCI_ANY_ID, 0, ati_hpet_bugs }, | ||
241 | {} | 223 | {} |
242 | }; | 224 | }; |
243 | 225 | ||
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index 351f9c0fea1..7494999141b 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c | |||
@@ -35,7 +35,6 @@ | |||
35 | unsigned long hpet_address; | 35 | unsigned long hpet_address; |
36 | u8 hpet_blockid; /* OS timer block num */ | 36 | u8 hpet_blockid; /* OS timer block num */ |
37 | u8 hpet_msi_disable; | 37 | u8 hpet_msi_disable; |
38 | u8 hpet_readback_cmp; | ||
39 | 38 | ||
40 | #ifdef CONFIG_PCI_MSI | 39 | #ifdef CONFIG_PCI_MSI |
41 | static unsigned long hpet_num_timers; | 40 | static unsigned long hpet_num_timers; |
@@ -395,23 +394,27 @@ static int hpet_next_event(unsigned long delta, | |||
395 | * at that point and we would wait for the next hpet interrupt | 394 | * at that point and we would wait for the next hpet interrupt |
396 | * forever. We found out that reading the CMP register back | 395 | * forever. We found out that reading the CMP register back |
397 | * forces the transfer so we can rely on the comparison with | 396 | * forces the transfer so we can rely on the comparison with |
398 | * the counter register below. | 397 | * the counter register below. If the read back from the |
398 | * compare register does not match the value we programmed | ||
399 | * then we might have a real hardware problem. We can not do | ||
400 | * much about it here, but at least alert the user/admin with | ||
401 | * a prominent warning. | ||
399 | * | 402 | * |
400 | * That works fine on those ATI chipsets, but on newer Intel | 403 | * An erratum on some chipsets (ICH9,..), results in |
401 | * chipsets (ICH9...) this triggers due to an erratum: Reading | 404 | * comparator read immediately following a write returning old |
402 | * the comparator immediately following a write is returning | 405 | * value. Workaround for this is to read this value second |
403 | * the old value. | 406 | * time, when first read returns old value. |
404 | * | 407 | * |
405 | * We restrict the read back to the affected ATI chipsets (set | 408 | * In fact the write to the comparator register is delayed up |
406 | * by quirks) and also run it with hpet=verbose for debugging | 409 | * to two HPET cycles so the workaround we tried to restrict |
407 | * purposes. | 410 | * the readback to those known to be borked ATI chipsets |
411 | * failed miserably. So we give up on optimizations forever | ||
412 | * and penalize all HPET incarnations unconditionally. | ||
408 | */ | 413 | */ |
409 | if (hpet_readback_cmp || hpet_verbose) { | 414 | if (unlikely((u32)hpet_readl(HPET_Tn_CMP(timer)) != cnt)) { |
410 | u32 cmp = hpet_readl(HPET_Tn_CMP(timer)); | 415 | if (hpet_readl(HPET_Tn_CMP(timer)) != cnt) |
411 | |||
412 | if (cmp != cnt) | ||
413 | printk_once(KERN_WARNING | 416 | printk_once(KERN_WARNING |
414 | "hpet: compare register read back failed.\n"); | 417 | "hpet: compare register read back failed.\n"); |
415 | } | 418 | } |
416 | 419 | ||
417 | return (s32)(hpet_readl(HPET_COUNTER) - cnt) >= 0 ? -ETIME : 0; | 420 | return (s32)(hpet_readl(HPET_COUNTER) - cnt) >= 0 ? -ETIME : 0; |
@@ -503,7 +506,7 @@ static int hpet_assign_irq(struct hpet_dev *dev) | |||
503 | { | 506 | { |
504 | unsigned int irq; | 507 | unsigned int irq; |
505 | 508 | ||
506 | irq = create_irq(); | 509 | irq = create_irq_nr(0, -1); |
507 | if (!irq) | 510 | if (!irq) |
508 | return -EINVAL; | 511 | return -EINVAL; |
509 | 512 | ||
diff --git a/arch/x86/kernel/hw_breakpoint.c b/arch/x86/kernel/hw_breakpoint.c index a474ec37c32..ff15c9dcc25 100644 --- a/arch/x86/kernel/hw_breakpoint.c +++ b/arch/x86/kernel/hw_breakpoint.c | |||
@@ -206,11 +206,27 @@ int arch_check_bp_in_kernelspace(struct perf_event *bp) | |||
206 | int arch_bp_generic_fields(int x86_len, int x86_type, | 206 | int arch_bp_generic_fields(int x86_len, int x86_type, |
207 | int *gen_len, int *gen_type) | 207 | int *gen_len, int *gen_type) |
208 | { | 208 | { |
209 | /* Len */ | 209 | /* Type */ |
210 | switch (x86_len) { | 210 | switch (x86_type) { |
211 | case X86_BREAKPOINT_LEN_X: | 211 | case X86_BREAKPOINT_EXECUTE: |
212 | if (x86_len != X86_BREAKPOINT_LEN_X) | ||
213 | return -EINVAL; | ||
214 | |||
215 | *gen_type = HW_BREAKPOINT_X; | ||
212 | *gen_len = sizeof(long); | 216 | *gen_len = sizeof(long); |
217 | return 0; | ||
218 | case X86_BREAKPOINT_WRITE: | ||
219 | *gen_type = HW_BREAKPOINT_W; | ||
213 | break; | 220 | break; |
221 | case X86_BREAKPOINT_RW: | ||
222 | *gen_type = HW_BREAKPOINT_W | HW_BREAKPOINT_R; | ||
223 | break; | ||
224 | default: | ||
225 | return -EINVAL; | ||
226 | } | ||
227 | |||
228 | /* Len */ | ||
229 | switch (x86_len) { | ||
214 | case X86_BREAKPOINT_LEN_1: | 230 | case X86_BREAKPOINT_LEN_1: |
215 | *gen_len = HW_BREAKPOINT_LEN_1; | 231 | *gen_len = HW_BREAKPOINT_LEN_1; |
216 | break; | 232 | break; |
@@ -229,21 +245,6 @@ int arch_bp_generic_fields(int x86_len, int x86_type, | |||
229 | return -EINVAL; | 245 | return -EINVAL; |
230 | } | 246 | } |
231 | 247 | ||
232 | /* Type */ | ||
233 | switch (x86_type) { | ||
234 | case X86_BREAKPOINT_EXECUTE: | ||
235 | *gen_type = HW_BREAKPOINT_X; | ||
236 | break; | ||
237 | case X86_BREAKPOINT_WRITE: | ||
238 | *gen_type = HW_BREAKPOINT_W; | ||
239 | break; | ||
240 | case X86_BREAKPOINT_RW: | ||
241 | *gen_type = HW_BREAKPOINT_W | HW_BREAKPOINT_R; | ||
242 | break; | ||
243 | default: | ||
244 | return -EINVAL; | ||
245 | } | ||
246 | |||
247 | return 0; | 248 | return 0; |
248 | } | 249 | } |
249 | 250 | ||
@@ -316,9 +317,6 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp) | |||
316 | ret = -EINVAL; | 317 | ret = -EINVAL; |
317 | 318 | ||
318 | switch (info->len) { | 319 | switch (info->len) { |
319 | case X86_BREAKPOINT_LEN_X: | ||
320 | align = sizeof(long) -1; | ||
321 | break; | ||
322 | case X86_BREAKPOINT_LEN_1: | 320 | case X86_BREAKPOINT_LEN_1: |
323 | align = 0; | 321 | align = 0; |
324 | break; | 322 | break; |
diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c index e0bc186d750..1c355c55096 100644 --- a/arch/x86/kernel/module.c +++ b/arch/x86/kernel/module.c | |||
@@ -239,11 +239,10 @@ int module_finalize(const Elf_Ehdr *hdr, | |||
239 | apply_paravirt(pseg, pseg + para->sh_size); | 239 | apply_paravirt(pseg, pseg + para->sh_size); |
240 | } | 240 | } |
241 | 241 | ||
242 | return module_bug_finalize(hdr, sechdrs, me); | 242 | return 0; |
243 | } | 243 | } |
244 | 244 | ||
245 | void module_arch_cleanup(struct module *mod) | 245 | void module_arch_cleanup(struct module *mod) |
246 | { | 246 | { |
247 | alternatives_smp_module_del(mod); | 247 | alternatives_smp_module_del(mod); |
248 | module_bug_cleanup(mod); | ||
249 | } | 248 | } |
diff --git a/arch/x86/kernel/trampoline.c b/arch/x86/kernel/trampoline.c index a874495b367..e2a59525739 100644 --- a/arch/x86/kernel/trampoline.c +++ b/arch/x86/kernel/trampoline.c | |||
@@ -45,8 +45,7 @@ void __init setup_trampoline_page_table(void) | |||
45 | /* Copy kernel address range */ | 45 | /* Copy kernel address range */ |
46 | clone_pgd_range(trampoline_pg_dir + KERNEL_PGD_BOUNDARY, | 46 | clone_pgd_range(trampoline_pg_dir + KERNEL_PGD_BOUNDARY, |
47 | swapper_pg_dir + KERNEL_PGD_BOUNDARY, | 47 | swapper_pg_dir + KERNEL_PGD_BOUNDARY, |
48 | min_t(unsigned long, KERNEL_PGD_PTRS, | 48 | KERNEL_PGD_PTRS); |
49 | KERNEL_PGD_BOUNDARY)); | ||
50 | 49 | ||
51 | /* Initialize low mappings */ | 50 | /* Initialize low mappings */ |
52 | clone_pgd_range(trampoline_pg_dir, | 51 | clone_pgd_range(trampoline_pg_dir, |
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index ce8e5023933..26a863a9c2a 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c | |||
@@ -626,6 +626,44 @@ static void set_cyc2ns_scale(unsigned long cpu_khz, int cpu) | |||
626 | local_irq_restore(flags); | 626 | local_irq_restore(flags); |
627 | } | 627 | } |
628 | 628 | ||
629 | static unsigned long long cyc2ns_suspend; | ||
630 | |||
631 | void save_sched_clock_state(void) | ||
632 | { | ||
633 | if (!sched_clock_stable) | ||
634 | return; | ||
635 | |||
636 | cyc2ns_suspend = sched_clock(); | ||
637 | } | ||
638 | |||
639 | /* | ||
640 | * Even on processors with invariant TSC, TSC gets reset in some the | ||
641 | * ACPI system sleep states. And in some systems BIOS seem to reinit TSC to | ||
642 | * arbitrary value (still sync'd across cpu's) during resume from such sleep | ||
643 | * states. To cope up with this, recompute the cyc2ns_offset for each cpu so | ||
644 | * that sched_clock() continues from the point where it was left off during | ||
645 | * suspend. | ||
646 | */ | ||
647 | void restore_sched_clock_state(void) | ||
648 | { | ||
649 | unsigned long long offset; | ||
650 | unsigned long flags; | ||
651 | int cpu; | ||
652 | |||
653 | if (!sched_clock_stable) | ||
654 | return; | ||
655 | |||
656 | local_irq_save(flags); | ||
657 | |||
658 | __get_cpu_var(cyc2ns_offset) = 0; | ||
659 | offset = cyc2ns_suspend - sched_clock(); | ||
660 | |||
661 | for_each_possible_cpu(cpu) | ||
662 | per_cpu(cyc2ns_offset, cpu) = offset; | ||
663 | |||
664 | local_irq_restore(flags); | ||
665 | } | ||
666 | |||
629 | #ifdef CONFIG_CPU_FREQ | 667 | #ifdef CONFIG_CPU_FREQ |
630 | 668 | ||
631 | /* Frequency scaling support. Adjust the TSC based timer when the cpu frequency | 669 | /* Frequency scaling support. Adjust the TSC based timer when the cpu frequency |
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index b38bd8b92aa..66ca98aafdd 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -1870,17 +1870,16 @@ static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt, | |||
1870 | struct x86_emulate_ops *ops) | 1870 | struct x86_emulate_ops *ops) |
1871 | { | 1871 | { |
1872 | struct decode_cache *c = &ctxt->decode; | 1872 | struct decode_cache *c = &ctxt->decode; |
1873 | u64 old = c->dst.orig_val; | 1873 | u64 old = c->dst.orig_val64; |
1874 | 1874 | ||
1875 | if (((u32) (old >> 0) != (u32) c->regs[VCPU_REGS_RAX]) || | 1875 | if (((u32) (old >> 0) != (u32) c->regs[VCPU_REGS_RAX]) || |
1876 | ((u32) (old >> 32) != (u32) c->regs[VCPU_REGS_RDX])) { | 1876 | ((u32) (old >> 32) != (u32) c->regs[VCPU_REGS_RDX])) { |
1877 | |||
1878 | c->regs[VCPU_REGS_RAX] = (u32) (old >> 0); | 1877 | c->regs[VCPU_REGS_RAX] = (u32) (old >> 0); |
1879 | c->regs[VCPU_REGS_RDX] = (u32) (old >> 32); | 1878 | c->regs[VCPU_REGS_RDX] = (u32) (old >> 32); |
1880 | ctxt->eflags &= ~EFLG_ZF; | 1879 | ctxt->eflags &= ~EFLG_ZF; |
1881 | } else { | 1880 | } else { |
1882 | c->dst.val = ((u64)c->regs[VCPU_REGS_RCX] << 32) | | 1881 | c->dst.val64 = ((u64)c->regs[VCPU_REGS_RCX] << 32) | |
1883 | (u32) c->regs[VCPU_REGS_RBX]; | 1882 | (u32) c->regs[VCPU_REGS_RBX]; |
1884 | 1883 | ||
1885 | ctxt->eflags |= EFLG_ZF; | 1884 | ctxt->eflags |= EFLG_ZF; |
1886 | } | 1885 | } |
@@ -2616,7 +2615,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) | |||
2616 | c->src.valptr, c->src.bytes); | 2615 | c->src.valptr, c->src.bytes); |
2617 | if (rc != X86EMUL_CONTINUE) | 2616 | if (rc != X86EMUL_CONTINUE) |
2618 | goto done; | 2617 | goto done; |
2619 | c->src.orig_val = c->src.val; | 2618 | c->src.orig_val64 = c->src.val64; |
2620 | } | 2619 | } |
2621 | 2620 | ||
2622 | if (c->src2.type == OP_MEM) { | 2621 | if (c->src2.type == OP_MEM) { |
diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c index 8d10c063d7f..4b7b73ce209 100644 --- a/arch/x86/kvm/i8259.c +++ b/arch/x86/kvm/i8259.c | |||
@@ -64,6 +64,9 @@ static void pic_unlock(struct kvm_pic *s) | |||
64 | if (!found) | 64 | if (!found) |
65 | found = s->kvm->bsp_vcpu; | 65 | found = s->kvm->bsp_vcpu; |
66 | 66 | ||
67 | if (!found) | ||
68 | return; | ||
69 | |||
67 | kvm_vcpu_kick(found); | 70 | kvm_vcpu_kick(found); |
68 | } | 71 | } |
69 | } | 72 | } |
diff --git a/arch/x86/kvm/irq.h b/arch/x86/kvm/irq.h index ffed06871c5..63c31450299 100644 --- a/arch/x86/kvm/irq.h +++ b/arch/x86/kvm/irq.h | |||
@@ -43,7 +43,6 @@ struct kvm_kpic_state { | |||
43 | u8 irr; /* interrupt request register */ | 43 | u8 irr; /* interrupt request register */ |
44 | u8 imr; /* interrupt mask register */ | 44 | u8 imr; /* interrupt mask register */ |
45 | u8 isr; /* interrupt service register */ | 45 | u8 isr; /* interrupt service register */ |
46 | u8 isr_ack; /* interrupt ack detection */ | ||
47 | u8 priority_add; /* highest irq priority */ | 46 | u8 priority_add; /* highest irq priority */ |
48 | u8 irq_base; | 47 | u8 irq_base; |
49 | u8 read_reg_select; | 48 | u8 read_reg_select; |
@@ -56,6 +55,7 @@ struct kvm_kpic_state { | |||
56 | u8 init4; /* true if 4 byte init */ | 55 | u8 init4; /* true if 4 byte init */ |
57 | u8 elcr; /* PIIX edge/trigger selection */ | 56 | u8 elcr; /* PIIX edge/trigger selection */ |
58 | u8 elcr_mask; | 57 | u8 elcr_mask; |
58 | u8 isr_ack; /* interrupt ack detection */ | ||
59 | struct kvm_pic *pics_state; | 59 | struct kvm_pic *pics_state; |
60 | }; | 60 | }; |
61 | 61 | ||
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index bc5b9b8d4a3..81ed28cb36e 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -766,7 +766,6 @@ static void init_vmcb(struct vcpu_svm *svm) | |||
766 | 766 | ||
767 | control->iopm_base_pa = iopm_base; | 767 | control->iopm_base_pa = iopm_base; |
768 | control->msrpm_base_pa = __pa(svm->msrpm); | 768 | control->msrpm_base_pa = __pa(svm->msrpm); |
769 | control->tsc_offset = 0; | ||
770 | control->int_ctl = V_INTR_MASKING_MASK; | 769 | control->int_ctl = V_INTR_MASKING_MASK; |
771 | 770 | ||
772 | init_seg(&save->es); | 771 | init_seg(&save->es); |
@@ -902,6 +901,7 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id) | |||
902 | svm->vmcb_pa = page_to_pfn(page) << PAGE_SHIFT; | 901 | svm->vmcb_pa = page_to_pfn(page) << PAGE_SHIFT; |
903 | svm->asid_generation = 0; | 902 | svm->asid_generation = 0; |
904 | init_vmcb(svm); | 903 | init_vmcb(svm); |
904 | svm->vmcb->control.tsc_offset = 0-native_read_tsc(); | ||
905 | 905 | ||
906 | err = fx_init(&svm->vcpu); | 906 | err = fx_init(&svm->vcpu); |
907 | if (err) | 907 | if (err) |
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index 9257510b483..9d5f5584845 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c | |||
@@ -324,9 +324,8 @@ static void lguest_load_gdt(const struct desc_ptr *desc) | |||
324 | } | 324 | } |
325 | 325 | ||
326 | /* | 326 | /* |
327 | * For a single GDT entry which changes, we do the lazy thing: alter our GDT, | 327 | * For a single GDT entry which changes, we simply change our copy and |
328 | * then tell the Host to reload the entire thing. This operation is so rare | 328 | * then tell the host about it. |
329 | * that this naive implementation is reasonable. | ||
330 | */ | 329 | */ |
331 | static void lguest_write_gdt_entry(struct desc_struct *dt, int entrynum, | 330 | static void lguest_write_gdt_entry(struct desc_struct *dt, int entrynum, |
332 | const void *desc, int type) | 331 | const void *desc, int type) |
@@ -338,9 +337,13 @@ static void lguest_write_gdt_entry(struct desc_struct *dt, int entrynum, | |||
338 | } | 337 | } |
339 | 338 | ||
340 | /* | 339 | /* |
341 | * OK, I lied. There are three "thread local storage" GDT entries which change | 340 | * There are three "thread local storage" GDT entries which change |
342 | * on every context switch (these three entries are how glibc implements | 341 | * on every context switch (these three entries are how glibc implements |
343 | * __thread variables). So we have a hypercall specifically for this case. | 342 | * __thread variables). As an optimization, we have a hypercall |
343 | * specifically for this case. | ||
344 | * | ||
345 | * Wouldn't it be nicer to have a general LOAD_GDT_ENTRIES hypercall | ||
346 | * which took a range of entries? | ||
344 | */ | 347 | */ |
345 | static void lguest_load_tls(struct thread_struct *t, unsigned int cpu) | 348 | static void lguest_load_tls(struct thread_struct *t, unsigned int cpu) |
346 | { | 349 | { |
diff --git a/arch/x86/mm/iomap_32.c b/arch/x86/mm/iomap_32.c index 84e236ce76b..72fc70cf618 100644 --- a/arch/x86/mm/iomap_32.c +++ b/arch/x86/mm/iomap_32.c | |||
@@ -74,7 +74,7 @@ void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot) | |||
74 | /* | 74 | /* |
75 | * Map 'pfn' using fixed map 'type' and protections 'prot' | 75 | * Map 'pfn' using fixed map 'type' and protections 'prot' |
76 | */ | 76 | */ |
77 | void * | 77 | void __iomem * |
78 | iomap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot) | 78 | iomap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot) |
79 | { | 79 | { |
80 | /* | 80 | /* |
@@ -86,12 +86,12 @@ iomap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot) | |||
86 | if (!pat_enabled && pgprot_val(prot) == pgprot_val(PAGE_KERNEL_WC)) | 86 | if (!pat_enabled && pgprot_val(prot) == pgprot_val(PAGE_KERNEL_WC)) |
87 | prot = PAGE_KERNEL_UC_MINUS; | 87 | prot = PAGE_KERNEL_UC_MINUS; |
88 | 88 | ||
89 | return kmap_atomic_prot_pfn(pfn, type, prot); | 89 | return (void __force __iomem *) kmap_atomic_prot_pfn(pfn, type, prot); |
90 | } | 90 | } |
91 | EXPORT_SYMBOL_GPL(iomap_atomic_prot_pfn); | 91 | EXPORT_SYMBOL_GPL(iomap_atomic_prot_pfn); |
92 | 92 | ||
93 | void | 93 | void |
94 | iounmap_atomic(void *kvaddr, enum km_type type) | 94 | iounmap_atomic(void __iomem *kvaddr, enum km_type type) |
95 | { | 95 | { |
96 | unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; | 96 | unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; |
97 | enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); | 97 | enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); |
diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c index f9897f7a9ef..9c0d0d399c3 100644 --- a/arch/x86/mm/srat_64.c +++ b/arch/x86/mm/srat_64.c | |||
@@ -420,9 +420,11 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end) | |||
420 | return -1; | 420 | return -1; |
421 | } | 421 | } |
422 | 422 | ||
423 | for_each_node_mask(i, nodes_parsed) | 423 | for (i = 0; i < num_node_memblks; i++) |
424 | e820_register_active_regions(i, nodes[i].start >> PAGE_SHIFT, | 424 | e820_register_active_regions(memblk_nodeid[i], |
425 | nodes[i].end >> PAGE_SHIFT); | 425 | node_memblk_range[i].start >> PAGE_SHIFT, |
426 | node_memblk_range[i].end >> PAGE_SHIFT); | ||
427 | |||
426 | /* for out of order entries in SRAT */ | 428 | /* for out of order entries in SRAT */ |
427 | sort_node_map(); | 429 | sort_node_map(); |
428 | if (!nodes_cover_memory(nodes)) { | 430 | if (!nodes_cover_memory(nodes)) { |
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index f6b48f6c595..f1575c9a257 100644 --- a/arch/x86/oprofile/nmi_int.c +++ b/arch/x86/oprofile/nmi_int.c | |||
@@ -568,8 +568,13 @@ static int __init init_sysfs(void) | |||
568 | int error; | 568 | int error; |
569 | 569 | ||
570 | error = sysdev_class_register(&oprofile_sysclass); | 570 | error = sysdev_class_register(&oprofile_sysclass); |
571 | if (!error) | 571 | if (error) |
572 | error = sysdev_register(&device_oprofile); | 572 | return error; |
573 | |||
574 | error = sysdev_register(&device_oprofile); | ||
575 | if (error) | ||
576 | sysdev_class_unregister(&oprofile_sysclass); | ||
577 | |||
573 | return error; | 578 | return error; |
574 | } | 579 | } |
575 | 580 | ||
@@ -580,8 +585,10 @@ static void exit_sysfs(void) | |||
580 | } | 585 | } |
581 | 586 | ||
582 | #else | 587 | #else |
583 | #define init_sysfs() do { } while (0) | 588 | |
584 | #define exit_sysfs() do { } while (0) | 589 | static inline int init_sysfs(void) { return 0; } |
590 | static inline void exit_sysfs(void) { } | ||
591 | |||
585 | #endif /* CONFIG_PM */ | 592 | #endif /* CONFIG_PM */ |
586 | 593 | ||
587 | static int __init p4_init(char **cpu_type) | 594 | static int __init p4_init(char **cpu_type) |
@@ -664,7 +671,10 @@ static int __init ppro_init(char **cpu_type) | |||
664 | case 14: | 671 | case 14: |
665 | *cpu_type = "i386/core"; | 672 | *cpu_type = "i386/core"; |
666 | break; | 673 | break; |
667 | case 15: case 23: | 674 | case 0x0f: |
675 | case 0x16: | ||
676 | case 0x17: | ||
677 | case 0x1d: | ||
668 | *cpu_type = "i386/core_2"; | 678 | *cpu_type = "i386/core_2"; |
669 | break; | 679 | break; |
670 | case 0x1a: | 680 | case 0x1a: |
@@ -695,6 +705,8 @@ int __init op_nmi_init(struct oprofile_operations *ops) | |||
695 | char *cpu_type = NULL; | 705 | char *cpu_type = NULL; |
696 | int ret = 0; | 706 | int ret = 0; |
697 | 707 | ||
708 | using_nmi = 0; | ||
709 | |||
698 | if (!cpu_has_apic) | 710 | if (!cpu_has_apic) |
699 | return -ENODEV; | 711 | return -ENODEV; |
700 | 712 | ||
@@ -774,7 +786,10 @@ int __init op_nmi_init(struct oprofile_operations *ops) | |||
774 | 786 | ||
775 | mux_init(ops); | 787 | mux_init(ops); |
776 | 788 | ||
777 | init_sysfs(); | 789 | ret = init_sysfs(); |
790 | if (ret) | ||
791 | return ret; | ||
792 | |||
778 | using_nmi = 1; | 793 | using_nmi = 1; |
779 | printk(KERN_INFO "oprofile: using NMI interrupt.\n"); | 794 | printk(KERN_INFO "oprofile: using NMI interrupt.\n"); |
780 | return 0; | 795 | return 0; |
diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c index e7e8c5f5495..87bb35e34ef 100644 --- a/arch/x86/power/cpu.c +++ b/arch/x86/power/cpu.c | |||
@@ -113,6 +113,7 @@ static void __save_processor_state(struct saved_context *ctxt) | |||
113 | void save_processor_state(void) | 113 | void save_processor_state(void) |
114 | { | 114 | { |
115 | __save_processor_state(&saved_context); | 115 | __save_processor_state(&saved_context); |
116 | save_sched_clock_state(); | ||
116 | } | 117 | } |
117 | #ifdef CONFIG_X86_32 | 118 | #ifdef CONFIG_X86_32 |
118 | EXPORT_SYMBOL(save_processor_state); | 119 | EXPORT_SYMBOL(save_processor_state); |
@@ -229,6 +230,7 @@ static void __restore_processor_state(struct saved_context *ctxt) | |||
229 | void restore_processor_state(void) | 230 | void restore_processor_state(void) |
230 | { | 231 | { |
231 | __restore_processor_state(&saved_context); | 232 | __restore_processor_state(&saved_context); |
233 | restore_sched_clock_state(); | ||
232 | } | 234 | } |
233 | #ifdef CONFIG_X86_32 | 235 | #ifdef CONFIG_X86_32 |
234 | EXPORT_SYMBOL(restore_processor_state); | 236 | EXPORT_SYMBOL(restore_processor_state); |
diff --git a/arch/x86/xen/platform-pci-unplug.c b/arch/x86/xen/platform-pci-unplug.c index 554c002a1e1..0f456386cce 100644 --- a/arch/x86/xen/platform-pci-unplug.c +++ b/arch/x86/xen/platform-pci-unplug.c | |||
@@ -72,13 +72,17 @@ void __init xen_unplug_emulated_devices(void) | |||
72 | { | 72 | { |
73 | int r; | 73 | int r; |
74 | 74 | ||
75 | /* user explicitly requested no unplug */ | ||
76 | if (xen_emul_unplug & XEN_UNPLUG_NEVER) | ||
77 | return; | ||
75 | /* check the version of the xen platform PCI device */ | 78 | /* check the version of the xen platform PCI device */ |
76 | r = check_platform_magic(); | 79 | r = check_platform_magic(); |
77 | /* If the version matches enable the Xen platform PCI driver. | 80 | /* If the version matches enable the Xen platform PCI driver. |
78 | * Also enable the Xen platform PCI driver if the version is really old | 81 | * Also enable the Xen platform PCI driver if the host does |
79 | * and the user told us to ignore it. */ | 82 | * not support the unplug protocol (XEN_PLATFORM_ERR_MAGIC) |
83 | * but the user told us that unplugging is unnecessary. */ | ||
80 | if (r && !(r == XEN_PLATFORM_ERR_MAGIC && | 84 | if (r && !(r == XEN_PLATFORM_ERR_MAGIC && |
81 | (xen_emul_unplug & XEN_UNPLUG_IGNORE))) | 85 | (xen_emul_unplug & XEN_UNPLUG_UNNECESSARY))) |
82 | return; | 86 | return; |
83 | /* Set the default value of xen_emul_unplug depending on whether or | 87 | /* Set the default value of xen_emul_unplug depending on whether or |
84 | * not the Xen PV frontends and the Xen platform PCI driver have | 88 | * not the Xen PV frontends and the Xen platform PCI driver have |
@@ -99,7 +103,7 @@ void __init xen_unplug_emulated_devices(void) | |||
99 | } | 103 | } |
100 | } | 104 | } |
101 | /* Now unplug the emulated devices */ | 105 | /* Now unplug the emulated devices */ |
102 | if (!(xen_emul_unplug & XEN_UNPLUG_IGNORE)) | 106 | if (!(xen_emul_unplug & XEN_UNPLUG_UNNECESSARY)) |
103 | outw(xen_emul_unplug, XEN_IOPORT_UNPLUG); | 107 | outw(xen_emul_unplug, XEN_IOPORT_UNPLUG); |
104 | xen_platform_pci_unplug = xen_emul_unplug; | 108 | xen_platform_pci_unplug = xen_emul_unplug; |
105 | } | 109 | } |
@@ -125,8 +129,10 @@ static int __init parse_xen_emul_unplug(char *arg) | |||
125 | xen_emul_unplug |= XEN_UNPLUG_AUX_IDE_DISKS; | 129 | xen_emul_unplug |= XEN_UNPLUG_AUX_IDE_DISKS; |
126 | else if (!strncmp(p, "nics", l)) | 130 | else if (!strncmp(p, "nics", l)) |
127 | xen_emul_unplug |= XEN_UNPLUG_ALL_NICS; | 131 | xen_emul_unplug |= XEN_UNPLUG_ALL_NICS; |
128 | else if (!strncmp(p, "ignore", l)) | 132 | else if (!strncmp(p, "unnecessary", l)) |
129 | xen_emul_unplug |= XEN_UNPLUG_IGNORE; | 133 | xen_emul_unplug |= XEN_UNPLUG_UNNECESSARY; |
134 | else if (!strncmp(p, "never", l)) | ||
135 | xen_emul_unplug |= XEN_UNPLUG_NEVER; | ||
130 | else | 136 | else |
131 | printk(KERN_WARNING "unrecognised option '%s' " | 137 | printk(KERN_WARNING "unrecognised option '%s' " |
132 | "in parameter 'xen_emul_unplug'\n", p); | 138 | "in parameter 'xen_emul_unplug'\n", p); |
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c index 1a5353a753f..b2bb5aa3b05 100644 --- a/arch/x86/xen/time.c +++ b/arch/x86/xen/time.c | |||
@@ -489,8 +489,9 @@ static void xen_hvm_setup_cpu_clockevents(void) | |||
489 | __init void xen_hvm_init_time_ops(void) | 489 | __init void xen_hvm_init_time_ops(void) |
490 | { | 490 | { |
491 | /* vector callback is needed otherwise we cannot receive interrupts | 491 | /* vector callback is needed otherwise we cannot receive interrupts |
492 | * on cpu > 0 */ | 492 | * on cpu > 0 and at this point we don't know how many cpus are |
493 | if (!xen_have_vector_callback && num_present_cpus() > 1) | 493 | * available */ |
494 | if (!xen_have_vector_callback) | ||
494 | return; | 495 | return; |
495 | if (!xen_feature(XENFEAT_hvm_safe_pvclock)) { | 496 | if (!xen_feature(XENFEAT_hvm_safe_pvclock)) { |
496 | printk(KERN_INFO "Xen doesn't support pvclock on HVM," | 497 | printk(KERN_INFO "Xen doesn't support pvclock on HVM," |
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index a6809645d21..2fef1ef931a 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c | |||
@@ -966,7 +966,7 @@ blkiocg_create(struct cgroup_subsys *subsys, struct cgroup *cgroup) | |||
966 | 966 | ||
967 | /* Currently we do not support hierarchy deeper than two level (0,1) */ | 967 | /* Currently we do not support hierarchy deeper than two level (0,1) */ |
968 | if (parent != cgroup->top_cgroup) | 968 | if (parent != cgroup->top_cgroup) |
969 | return ERR_PTR(-EINVAL); | 969 | return ERR_PTR(-EPERM); |
970 | 970 | ||
971 | blkcg = kzalloc(sizeof(*blkcg), GFP_KERNEL); | 971 | blkcg = kzalloc(sizeof(*blkcg), GFP_KERNEL); |
972 | if (!blkcg) | 972 | if (!blkcg) |
diff --git a/block/blk-core.c b/block/blk-core.c index 2a5b1920454..a840523e3b4 100644 --- a/block/blk-core.c +++ b/block/blk-core.c | |||
@@ -1182,9 +1182,9 @@ static int __make_request(struct request_queue *q, struct bio *bio) | |||
1182 | int el_ret; | 1182 | int el_ret; |
1183 | unsigned int bytes = bio->bi_size; | 1183 | unsigned int bytes = bio->bi_size; |
1184 | const unsigned short prio = bio_prio(bio); | 1184 | const unsigned short prio = bio_prio(bio); |
1185 | const bool sync = (bio->bi_rw & REQ_SYNC); | 1185 | const bool sync = !!(bio->bi_rw & REQ_SYNC); |
1186 | const bool unplug = (bio->bi_rw & REQ_UNPLUG); | 1186 | const bool unplug = !!(bio->bi_rw & REQ_UNPLUG); |
1187 | const unsigned int ff = bio->bi_rw & REQ_FAILFAST_MASK; | 1187 | const unsigned long ff = bio->bi_rw & REQ_FAILFAST_MASK; |
1188 | int where = ELEVATOR_INSERT_SORT; | 1188 | int where = ELEVATOR_INSERT_SORT; |
1189 | int rw_flags; | 1189 | int rw_flags; |
1190 | 1190 | ||
diff --git a/block/blk-map.c b/block/blk-map.c index c65d7593f7f..ade0a08c909 100644 --- a/block/blk-map.c +++ b/block/blk-map.c | |||
@@ -307,7 +307,7 @@ int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf, | |||
307 | return PTR_ERR(bio); | 307 | return PTR_ERR(bio); |
308 | 308 | ||
309 | if (rq_data_dir(rq) == WRITE) | 309 | if (rq_data_dir(rq) == WRITE) |
310 | bio->bi_rw |= (1 << REQ_WRITE); | 310 | bio->bi_rw |= REQ_WRITE; |
311 | 311 | ||
312 | if (do_copy) | 312 | if (do_copy) |
313 | rq->cmd_flags |= REQ_COPY_USER; | 313 | rq->cmd_flags |= REQ_COPY_USER; |
diff --git a/block/blk-merge.c b/block/blk-merge.c index 3b0cd424967..eafc94f68d7 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c | |||
@@ -362,6 +362,18 @@ static int attempt_merge(struct request_queue *q, struct request *req, | |||
362 | return 0; | 362 | return 0; |
363 | 363 | ||
364 | /* | 364 | /* |
365 | * Don't merge file system requests and discard requests | ||
366 | */ | ||
367 | if ((req->cmd_flags & REQ_DISCARD) != (next->cmd_flags & REQ_DISCARD)) | ||
368 | return 0; | ||
369 | |||
370 | /* | ||
371 | * Don't merge discard requests and secure discard requests | ||
372 | */ | ||
373 | if ((req->cmd_flags & REQ_SECURE) != (next->cmd_flags & REQ_SECURE)) | ||
374 | return 0; | ||
375 | |||
376 | /* | ||
365 | * not contiguous | 377 | * not contiguous |
366 | */ | 378 | */ |
367 | if (blk_rq_pos(req) + blk_rq_sectors(req) != blk_rq_pos(next)) | 379 | if (blk_rq_pos(req) + blk_rq_sectors(req) != blk_rq_pos(next)) |
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index 001ab18078f..0749b89c688 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c | |||
@@ -511,6 +511,7 @@ int blk_register_queue(struct gendisk *disk) | |||
511 | kobject_uevent(&q->kobj, KOBJ_REMOVE); | 511 | kobject_uevent(&q->kobj, KOBJ_REMOVE); |
512 | kobject_del(&q->kobj); | 512 | kobject_del(&q->kobj); |
513 | blk_trace_remove_sysfs(disk_to_dev(disk)); | 513 | blk_trace_remove_sysfs(disk_to_dev(disk)); |
514 | kobject_put(&dev->kobj); | ||
514 | return ret; | 515 | return ret; |
515 | } | 516 | } |
516 | 517 | ||
diff --git a/block/blk.h b/block/blk.h index a09c18b1911..faf94f2acb1 100644 --- a/block/blk.h +++ b/block/blk.h | |||
@@ -148,14 +148,18 @@ static inline int queue_congestion_off_threshold(struct request_queue *q) | |||
148 | 148 | ||
149 | static inline int blk_cpu_to_group(int cpu) | 149 | static inline int blk_cpu_to_group(int cpu) |
150 | { | 150 | { |
151 | int group = NR_CPUS; | ||
151 | #ifdef CONFIG_SCHED_MC | 152 | #ifdef CONFIG_SCHED_MC |
152 | const struct cpumask *mask = cpu_coregroup_mask(cpu); | 153 | const struct cpumask *mask = cpu_coregroup_mask(cpu); |
153 | return cpumask_first(mask); | 154 | group = cpumask_first(mask); |
154 | #elif defined(CONFIG_SCHED_SMT) | 155 | #elif defined(CONFIG_SCHED_SMT) |
155 | return cpumask_first(topology_thread_cpumask(cpu)); | 156 | group = cpumask_first(topology_thread_cpumask(cpu)); |
156 | #else | 157 | #else |
157 | return cpu; | 158 | return cpu; |
158 | #endif | 159 | #endif |
160 | if (likely(group < NR_CPUS)) | ||
161 | return group; | ||
162 | return cpu; | ||
159 | } | 163 | } |
160 | 164 | ||
161 | /* | 165 | /* |
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index eb4086f7dfe..9eba291eb6f 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
@@ -30,6 +30,7 @@ static const int cfq_slice_sync = HZ / 10; | |||
30 | static int cfq_slice_async = HZ / 25; | 30 | static int cfq_slice_async = HZ / 25; |
31 | static const int cfq_slice_async_rq = 2; | 31 | static const int cfq_slice_async_rq = 2; |
32 | static int cfq_slice_idle = HZ / 125; | 32 | static int cfq_slice_idle = HZ / 125; |
33 | static int cfq_group_idle = HZ / 125; | ||
33 | static const int cfq_target_latency = HZ * 3/10; /* 300 ms */ | 34 | static const int cfq_target_latency = HZ * 3/10; /* 300 ms */ |
34 | static const int cfq_hist_divisor = 4; | 35 | static const int cfq_hist_divisor = 4; |
35 | 36 | ||
@@ -147,6 +148,8 @@ struct cfq_queue { | |||
147 | struct cfq_queue *new_cfqq; | 148 | struct cfq_queue *new_cfqq; |
148 | struct cfq_group *cfqg; | 149 | struct cfq_group *cfqg; |
149 | struct cfq_group *orig_cfqg; | 150 | struct cfq_group *orig_cfqg; |
151 | /* Number of sectors dispatched from queue in single dispatch round */ | ||
152 | unsigned long nr_sectors; | ||
150 | }; | 153 | }; |
151 | 154 | ||
152 | /* | 155 | /* |
@@ -198,6 +201,8 @@ struct cfq_group { | |||
198 | struct hlist_node cfqd_node; | 201 | struct hlist_node cfqd_node; |
199 | atomic_t ref; | 202 | atomic_t ref; |
200 | #endif | 203 | #endif |
204 | /* number of requests that are on the dispatch list or inside driver */ | ||
205 | int dispatched; | ||
201 | }; | 206 | }; |
202 | 207 | ||
203 | /* | 208 | /* |
@@ -271,6 +276,7 @@ struct cfq_data { | |||
271 | unsigned int cfq_slice[2]; | 276 | unsigned int cfq_slice[2]; |
272 | unsigned int cfq_slice_async_rq; | 277 | unsigned int cfq_slice_async_rq; |
273 | unsigned int cfq_slice_idle; | 278 | unsigned int cfq_slice_idle; |
279 | unsigned int cfq_group_idle; | ||
274 | unsigned int cfq_latency; | 280 | unsigned int cfq_latency; |
275 | unsigned int cfq_group_isolation; | 281 | unsigned int cfq_group_isolation; |
276 | 282 | ||
@@ -378,6 +384,21 @@ CFQ_CFQQ_FNS(wait_busy); | |||
378 | &cfqg->service_trees[i][j]: NULL) \ | 384 | &cfqg->service_trees[i][j]: NULL) \ |
379 | 385 | ||
380 | 386 | ||
387 | static inline bool iops_mode(struct cfq_data *cfqd) | ||
388 | { | ||
389 | /* | ||
390 | * If we are not idling on queues and it is a NCQ drive, parallel | ||
391 | * execution of requests is on and measuring time is not possible | ||
392 | * in most of the cases until and unless we drive shallower queue | ||
393 | * depths and that becomes a performance bottleneck. In such cases | ||
394 | * switch to start providing fairness in terms of number of IOs. | ||
395 | */ | ||
396 | if (!cfqd->cfq_slice_idle && cfqd->hw_tag) | ||
397 | return true; | ||
398 | else | ||
399 | return false; | ||
400 | } | ||
401 | |||
381 | static inline enum wl_prio_t cfqq_prio(struct cfq_queue *cfqq) | 402 | static inline enum wl_prio_t cfqq_prio(struct cfq_queue *cfqq) |
382 | { | 403 | { |
383 | if (cfq_class_idle(cfqq)) | 404 | if (cfq_class_idle(cfqq)) |
@@ -906,7 +927,6 @@ static inline unsigned int cfq_cfqq_slice_usage(struct cfq_queue *cfqq) | |||
906 | slice_used = cfqq->allocated_slice; | 927 | slice_used = cfqq->allocated_slice; |
907 | } | 928 | } |
908 | 929 | ||
909 | cfq_log_cfqq(cfqq->cfqd, cfqq, "sl_used=%u", slice_used); | ||
910 | return slice_used; | 930 | return slice_used; |
911 | } | 931 | } |
912 | 932 | ||
@@ -914,19 +934,21 @@ static void cfq_group_served(struct cfq_data *cfqd, struct cfq_group *cfqg, | |||
914 | struct cfq_queue *cfqq) | 934 | struct cfq_queue *cfqq) |
915 | { | 935 | { |
916 | struct cfq_rb_root *st = &cfqd->grp_service_tree; | 936 | struct cfq_rb_root *st = &cfqd->grp_service_tree; |
917 | unsigned int used_sl, charge_sl; | 937 | unsigned int used_sl, charge; |
918 | int nr_sync = cfqg->nr_cfqq - cfqg_busy_async_queues(cfqd, cfqg) | 938 | int nr_sync = cfqg->nr_cfqq - cfqg_busy_async_queues(cfqd, cfqg) |
919 | - cfqg->service_tree_idle.count; | 939 | - cfqg->service_tree_idle.count; |
920 | 940 | ||
921 | BUG_ON(nr_sync < 0); | 941 | BUG_ON(nr_sync < 0); |
922 | used_sl = charge_sl = cfq_cfqq_slice_usage(cfqq); | 942 | used_sl = charge = cfq_cfqq_slice_usage(cfqq); |
923 | 943 | ||
924 | if (!cfq_cfqq_sync(cfqq) && !nr_sync) | 944 | if (iops_mode(cfqd)) |
925 | charge_sl = cfqq->allocated_slice; | 945 | charge = cfqq->slice_dispatch; |
946 | else if (!cfq_cfqq_sync(cfqq) && !nr_sync) | ||
947 | charge = cfqq->allocated_slice; | ||
926 | 948 | ||
927 | /* Can't update vdisktime while group is on service tree */ | 949 | /* Can't update vdisktime while group is on service tree */ |
928 | cfq_rb_erase(&cfqg->rb_node, st); | 950 | cfq_rb_erase(&cfqg->rb_node, st); |
929 | cfqg->vdisktime += cfq_scale_slice(charge_sl, cfqg); | 951 | cfqg->vdisktime += cfq_scale_slice(charge, cfqg); |
930 | __cfq_group_service_tree_add(st, cfqg); | 952 | __cfq_group_service_tree_add(st, cfqg); |
931 | 953 | ||
932 | /* This group is being expired. Save the context */ | 954 | /* This group is being expired. Save the context */ |
@@ -940,6 +962,9 @@ static void cfq_group_served(struct cfq_data *cfqd, struct cfq_group *cfqg, | |||
940 | 962 | ||
941 | cfq_log_cfqg(cfqd, cfqg, "served: vt=%llu min_vt=%llu", cfqg->vdisktime, | 963 | cfq_log_cfqg(cfqd, cfqg, "served: vt=%llu min_vt=%llu", cfqg->vdisktime, |
942 | st->min_vdisktime); | 964 | st->min_vdisktime); |
965 | cfq_log_cfqq(cfqq->cfqd, cfqq, "sl_used=%u disp=%u charge=%u iops=%u" | ||
966 | " sect=%u", used_sl, cfqq->slice_dispatch, charge, | ||
967 | iops_mode(cfqd), cfqq->nr_sectors); | ||
943 | cfq_blkiocg_update_timeslice_used(&cfqg->blkg, used_sl); | 968 | cfq_blkiocg_update_timeslice_used(&cfqg->blkg, used_sl); |
944 | cfq_blkiocg_set_start_empty_time(&cfqg->blkg); | 969 | cfq_blkiocg_set_start_empty_time(&cfqg->blkg); |
945 | } | 970 | } |
@@ -994,10 +1019,20 @@ cfq_find_alloc_cfqg(struct cfq_data *cfqd, struct cgroup *cgroup, int create) | |||
994 | */ | 1019 | */ |
995 | atomic_set(&cfqg->ref, 1); | 1020 | atomic_set(&cfqg->ref, 1); |
996 | 1021 | ||
997 | /* Add group onto cgroup list */ | 1022 | /* |
998 | sscanf(dev_name(bdi->dev), "%u:%u", &major, &minor); | 1023 | * Add group onto cgroup list. It might happen that bdi->dev is |
999 | cfq_blkiocg_add_blkio_group(blkcg, &cfqg->blkg, (void *)cfqd, | 1024 | * not initiliazed yet. Initialize this new group without major |
1025 | * and minor info and this info will be filled in once a new thread | ||
1026 | * comes for IO. See code above. | ||
1027 | */ | ||
1028 | if (bdi->dev) { | ||
1029 | sscanf(dev_name(bdi->dev), "%u:%u", &major, &minor); | ||
1030 | cfq_blkiocg_add_blkio_group(blkcg, &cfqg->blkg, (void *)cfqd, | ||
1000 | MKDEV(major, minor)); | 1031 | MKDEV(major, minor)); |
1032 | } else | ||
1033 | cfq_blkiocg_add_blkio_group(blkcg, &cfqg->blkg, (void *)cfqd, | ||
1034 | 0); | ||
1035 | |||
1001 | cfqg->weight = blkcg_get_weight(blkcg, cfqg->blkg.dev); | 1036 | cfqg->weight = blkcg_get_weight(blkcg, cfqg->blkg.dev); |
1002 | 1037 | ||
1003 | /* Add group on cfqd list */ | 1038 | /* Add group on cfqd list */ |
@@ -1587,6 +1622,7 @@ static void __cfq_set_active_queue(struct cfq_data *cfqd, | |||
1587 | cfqq->allocated_slice = 0; | 1622 | cfqq->allocated_slice = 0; |
1588 | cfqq->slice_end = 0; | 1623 | cfqq->slice_end = 0; |
1589 | cfqq->slice_dispatch = 0; | 1624 | cfqq->slice_dispatch = 0; |
1625 | cfqq->nr_sectors = 0; | ||
1590 | 1626 | ||
1591 | cfq_clear_cfqq_wait_request(cfqq); | 1627 | cfq_clear_cfqq_wait_request(cfqq); |
1592 | cfq_clear_cfqq_must_dispatch(cfqq); | 1628 | cfq_clear_cfqq_must_dispatch(cfqq); |
@@ -1839,6 +1875,9 @@ static bool cfq_should_idle(struct cfq_data *cfqd, struct cfq_queue *cfqq) | |||
1839 | BUG_ON(!service_tree); | 1875 | BUG_ON(!service_tree); |
1840 | BUG_ON(!service_tree->count); | 1876 | BUG_ON(!service_tree->count); |
1841 | 1877 | ||
1878 | if (!cfqd->cfq_slice_idle) | ||
1879 | return false; | ||
1880 | |||
1842 | /* We never do for idle class queues. */ | 1881 | /* We never do for idle class queues. */ |
1843 | if (prio == IDLE_WORKLOAD) | 1882 | if (prio == IDLE_WORKLOAD) |
1844 | return false; | 1883 | return false; |
@@ -1863,7 +1902,7 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd) | |||
1863 | { | 1902 | { |
1864 | struct cfq_queue *cfqq = cfqd->active_queue; | 1903 | struct cfq_queue *cfqq = cfqd->active_queue; |
1865 | struct cfq_io_context *cic; | 1904 | struct cfq_io_context *cic; |
1866 | unsigned long sl; | 1905 | unsigned long sl, group_idle = 0; |
1867 | 1906 | ||
1868 | /* | 1907 | /* |
1869 | * SSD device without seek penalty, disable idling. But only do so | 1908 | * SSD device without seek penalty, disable idling. But only do so |
@@ -1879,8 +1918,13 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd) | |||
1879 | /* | 1918 | /* |
1880 | * idle is disabled, either manually or by past process history | 1919 | * idle is disabled, either manually or by past process history |
1881 | */ | 1920 | */ |
1882 | if (!cfqd->cfq_slice_idle || !cfq_should_idle(cfqd, cfqq)) | 1921 | if (!cfq_should_idle(cfqd, cfqq)) { |
1883 | return; | 1922 | /* no queue idling. Check for group idling */ |
1923 | if (cfqd->cfq_group_idle) | ||
1924 | group_idle = cfqd->cfq_group_idle; | ||
1925 | else | ||
1926 | return; | ||
1927 | } | ||
1884 | 1928 | ||
1885 | /* | 1929 | /* |
1886 | * still active requests from this queue, don't idle | 1930 | * still active requests from this queue, don't idle |
@@ -1907,13 +1951,21 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd) | |||
1907 | return; | 1951 | return; |
1908 | } | 1952 | } |
1909 | 1953 | ||
1954 | /* There are other queues in the group, don't do group idle */ | ||
1955 | if (group_idle && cfqq->cfqg->nr_cfqq > 1) | ||
1956 | return; | ||
1957 | |||
1910 | cfq_mark_cfqq_wait_request(cfqq); | 1958 | cfq_mark_cfqq_wait_request(cfqq); |
1911 | 1959 | ||
1912 | sl = cfqd->cfq_slice_idle; | 1960 | if (group_idle) |
1961 | sl = cfqd->cfq_group_idle; | ||
1962 | else | ||
1963 | sl = cfqd->cfq_slice_idle; | ||
1913 | 1964 | ||
1914 | mod_timer(&cfqd->idle_slice_timer, jiffies + sl); | 1965 | mod_timer(&cfqd->idle_slice_timer, jiffies + sl); |
1915 | cfq_blkiocg_update_set_idle_time_stats(&cfqq->cfqg->blkg); | 1966 | cfq_blkiocg_update_set_idle_time_stats(&cfqq->cfqg->blkg); |
1916 | cfq_log_cfqq(cfqd, cfqq, "arm_idle: %lu", sl); | 1967 | cfq_log_cfqq(cfqd, cfqq, "arm_idle: %lu group_idle: %d", sl, |
1968 | group_idle ? 1 : 0); | ||
1917 | } | 1969 | } |
1918 | 1970 | ||
1919 | /* | 1971 | /* |
@@ -1929,9 +1981,11 @@ static void cfq_dispatch_insert(struct request_queue *q, struct request *rq) | |||
1929 | cfqq->next_rq = cfq_find_next_rq(cfqd, cfqq, rq); | 1981 | cfqq->next_rq = cfq_find_next_rq(cfqd, cfqq, rq); |
1930 | cfq_remove_request(rq); | 1982 | cfq_remove_request(rq); |
1931 | cfqq->dispatched++; | 1983 | cfqq->dispatched++; |
1984 | (RQ_CFQG(rq))->dispatched++; | ||
1932 | elv_dispatch_sort(q, rq); | 1985 | elv_dispatch_sort(q, rq); |
1933 | 1986 | ||
1934 | cfqd->rq_in_flight[cfq_cfqq_sync(cfqq)]++; | 1987 | cfqd->rq_in_flight[cfq_cfqq_sync(cfqq)]++; |
1988 | cfqq->nr_sectors += blk_rq_sectors(rq); | ||
1935 | cfq_blkiocg_update_dispatch_stats(&cfqq->cfqg->blkg, blk_rq_bytes(rq), | 1989 | cfq_blkiocg_update_dispatch_stats(&cfqq->cfqg->blkg, blk_rq_bytes(rq), |
1936 | rq_data_dir(rq), rq_is_sync(rq)); | 1990 | rq_data_dir(rq), rq_is_sync(rq)); |
1937 | } | 1991 | } |
@@ -2198,7 +2252,7 @@ static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd) | |||
2198 | cfqq = NULL; | 2252 | cfqq = NULL; |
2199 | goto keep_queue; | 2253 | goto keep_queue; |
2200 | } else | 2254 | } else |
2201 | goto expire; | 2255 | goto check_group_idle; |
2202 | } | 2256 | } |
2203 | 2257 | ||
2204 | /* | 2258 | /* |
@@ -2226,8 +2280,23 @@ static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd) | |||
2226 | * flight or is idling for a new request, allow either of these | 2280 | * flight or is idling for a new request, allow either of these |
2227 | * conditions to happen (or time out) before selecting a new queue. | 2281 | * conditions to happen (or time out) before selecting a new queue. |
2228 | */ | 2282 | */ |
2229 | if (timer_pending(&cfqd->idle_slice_timer) || | 2283 | if (timer_pending(&cfqd->idle_slice_timer)) { |
2230 | (cfqq->dispatched && cfq_should_idle(cfqd, cfqq))) { | 2284 | cfqq = NULL; |
2285 | goto keep_queue; | ||
2286 | } | ||
2287 | |||
2288 | if (cfqq->dispatched && cfq_should_idle(cfqd, cfqq)) { | ||
2289 | cfqq = NULL; | ||
2290 | goto keep_queue; | ||
2291 | } | ||
2292 | |||
2293 | /* | ||
2294 | * If group idle is enabled and there are requests dispatched from | ||
2295 | * this group, wait for requests to complete. | ||
2296 | */ | ||
2297 | check_group_idle: | ||
2298 | if (cfqd->cfq_group_idle && cfqq->cfqg->nr_cfqq == 1 | ||
2299 | && cfqq->cfqg->dispatched) { | ||
2231 | cfqq = NULL; | 2300 | cfqq = NULL; |
2232 | goto keep_queue; | 2301 | goto keep_queue; |
2233 | } | 2302 | } |
@@ -3375,6 +3444,7 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq) | |||
3375 | WARN_ON(!cfqq->dispatched); | 3444 | WARN_ON(!cfqq->dispatched); |
3376 | cfqd->rq_in_driver--; | 3445 | cfqd->rq_in_driver--; |
3377 | cfqq->dispatched--; | 3446 | cfqq->dispatched--; |
3447 | (RQ_CFQG(rq))->dispatched--; | ||
3378 | cfq_blkiocg_update_completion_stats(&cfqq->cfqg->blkg, | 3448 | cfq_blkiocg_update_completion_stats(&cfqq->cfqg->blkg, |
3379 | rq_start_time_ns(rq), rq_io_start_time_ns(rq), | 3449 | rq_start_time_ns(rq), rq_io_start_time_ns(rq), |
3380 | rq_data_dir(rq), rq_is_sync(rq)); | 3450 | rq_data_dir(rq), rq_is_sync(rq)); |
@@ -3404,7 +3474,10 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq) | |||
3404 | * the queue. | 3474 | * the queue. |
3405 | */ | 3475 | */ |
3406 | if (cfq_should_wait_busy(cfqd, cfqq)) { | 3476 | if (cfq_should_wait_busy(cfqd, cfqq)) { |
3407 | cfqq->slice_end = jiffies + cfqd->cfq_slice_idle; | 3477 | unsigned long extend_sl = cfqd->cfq_slice_idle; |
3478 | if (!cfqd->cfq_slice_idle) | ||
3479 | extend_sl = cfqd->cfq_group_idle; | ||
3480 | cfqq->slice_end = jiffies + extend_sl; | ||
3408 | cfq_mark_cfqq_wait_busy(cfqq); | 3481 | cfq_mark_cfqq_wait_busy(cfqq); |
3409 | cfq_log_cfqq(cfqd, cfqq, "will busy wait"); | 3482 | cfq_log_cfqq(cfqd, cfqq, "will busy wait"); |
3410 | } | 3483 | } |
@@ -3850,6 +3923,7 @@ static void *cfq_init_queue(struct request_queue *q) | |||
3850 | cfqd->cfq_slice[1] = cfq_slice_sync; | 3923 | cfqd->cfq_slice[1] = cfq_slice_sync; |
3851 | cfqd->cfq_slice_async_rq = cfq_slice_async_rq; | 3924 | cfqd->cfq_slice_async_rq = cfq_slice_async_rq; |
3852 | cfqd->cfq_slice_idle = cfq_slice_idle; | 3925 | cfqd->cfq_slice_idle = cfq_slice_idle; |
3926 | cfqd->cfq_group_idle = cfq_group_idle; | ||
3853 | cfqd->cfq_latency = 1; | 3927 | cfqd->cfq_latency = 1; |
3854 | cfqd->cfq_group_isolation = 0; | 3928 | cfqd->cfq_group_isolation = 0; |
3855 | cfqd->hw_tag = -1; | 3929 | cfqd->hw_tag = -1; |
@@ -3922,6 +3996,7 @@ SHOW_FUNCTION(cfq_fifo_expire_async_show, cfqd->cfq_fifo_expire[0], 1); | |||
3922 | SHOW_FUNCTION(cfq_back_seek_max_show, cfqd->cfq_back_max, 0); | 3996 | SHOW_FUNCTION(cfq_back_seek_max_show, cfqd->cfq_back_max, 0); |
3923 | SHOW_FUNCTION(cfq_back_seek_penalty_show, cfqd->cfq_back_penalty, 0); | 3997 | SHOW_FUNCTION(cfq_back_seek_penalty_show, cfqd->cfq_back_penalty, 0); |
3924 | SHOW_FUNCTION(cfq_slice_idle_show, cfqd->cfq_slice_idle, 1); | 3998 | SHOW_FUNCTION(cfq_slice_idle_show, cfqd->cfq_slice_idle, 1); |
3999 | SHOW_FUNCTION(cfq_group_idle_show, cfqd->cfq_group_idle, 1); | ||
3925 | SHOW_FUNCTION(cfq_slice_sync_show, cfqd->cfq_slice[1], 1); | 4000 | SHOW_FUNCTION(cfq_slice_sync_show, cfqd->cfq_slice[1], 1); |
3926 | SHOW_FUNCTION(cfq_slice_async_show, cfqd->cfq_slice[0], 1); | 4001 | SHOW_FUNCTION(cfq_slice_async_show, cfqd->cfq_slice[0], 1); |
3927 | SHOW_FUNCTION(cfq_slice_async_rq_show, cfqd->cfq_slice_async_rq, 0); | 4002 | SHOW_FUNCTION(cfq_slice_async_rq_show, cfqd->cfq_slice_async_rq, 0); |
@@ -3954,6 +4029,7 @@ STORE_FUNCTION(cfq_back_seek_max_store, &cfqd->cfq_back_max, 0, UINT_MAX, 0); | |||
3954 | STORE_FUNCTION(cfq_back_seek_penalty_store, &cfqd->cfq_back_penalty, 1, | 4029 | STORE_FUNCTION(cfq_back_seek_penalty_store, &cfqd->cfq_back_penalty, 1, |
3955 | UINT_MAX, 0); | 4030 | UINT_MAX, 0); |
3956 | STORE_FUNCTION(cfq_slice_idle_store, &cfqd->cfq_slice_idle, 0, UINT_MAX, 1); | 4031 | STORE_FUNCTION(cfq_slice_idle_store, &cfqd->cfq_slice_idle, 0, UINT_MAX, 1); |
4032 | STORE_FUNCTION(cfq_group_idle_store, &cfqd->cfq_group_idle, 0, UINT_MAX, 1); | ||
3957 | STORE_FUNCTION(cfq_slice_sync_store, &cfqd->cfq_slice[1], 1, UINT_MAX, 1); | 4033 | STORE_FUNCTION(cfq_slice_sync_store, &cfqd->cfq_slice[1], 1, UINT_MAX, 1); |
3958 | STORE_FUNCTION(cfq_slice_async_store, &cfqd->cfq_slice[0], 1, UINT_MAX, 1); | 4034 | STORE_FUNCTION(cfq_slice_async_store, &cfqd->cfq_slice[0], 1, UINT_MAX, 1); |
3959 | STORE_FUNCTION(cfq_slice_async_rq_store, &cfqd->cfq_slice_async_rq, 1, | 4035 | STORE_FUNCTION(cfq_slice_async_rq_store, &cfqd->cfq_slice_async_rq, 1, |
@@ -3975,6 +4051,7 @@ static struct elv_fs_entry cfq_attrs[] = { | |||
3975 | CFQ_ATTR(slice_async), | 4051 | CFQ_ATTR(slice_async), |
3976 | CFQ_ATTR(slice_async_rq), | 4052 | CFQ_ATTR(slice_async_rq), |
3977 | CFQ_ATTR(slice_idle), | 4053 | CFQ_ATTR(slice_idle), |
4054 | CFQ_ATTR(group_idle), | ||
3978 | CFQ_ATTR(low_latency), | 4055 | CFQ_ATTR(low_latency), |
3979 | CFQ_ATTR(group_isolation), | 4056 | CFQ_ATTR(group_isolation), |
3980 | __ATTR_NULL | 4057 | __ATTR_NULL |
@@ -4028,6 +4105,12 @@ static int __init cfq_init(void) | |||
4028 | if (!cfq_slice_idle) | 4105 | if (!cfq_slice_idle) |
4029 | cfq_slice_idle = 1; | 4106 | cfq_slice_idle = 1; |
4030 | 4107 | ||
4108 | #ifdef CONFIG_CFQ_GROUP_IOSCHED | ||
4109 | if (!cfq_group_idle) | ||
4110 | cfq_group_idle = 1; | ||
4111 | #else | ||
4112 | cfq_group_idle = 0; | ||
4113 | #endif | ||
4031 | if (cfq_slab_setup()) | 4114 | if (cfq_slab_setup()) |
4032 | return -ENOMEM; | 4115 | return -ENOMEM; |
4033 | 4116 | ||
diff --git a/block/elevator.c b/block/elevator.c index 241c69c45c5..282e8308f7e 100644 --- a/block/elevator.c +++ b/block/elevator.c | |||
@@ -877,6 +877,7 @@ int elv_register_queue(struct request_queue *q) | |||
877 | } | 877 | } |
878 | } | 878 | } |
879 | kobject_uevent(&e->kobj, KOBJ_ADD); | 879 | kobject_uevent(&e->kobj, KOBJ_ADD); |
880 | e->registered = 1; | ||
880 | } | 881 | } |
881 | return error; | 882 | return error; |
882 | } | 883 | } |
@@ -886,6 +887,7 @@ static void __elv_unregister_queue(struct elevator_queue *e) | |||
886 | { | 887 | { |
887 | kobject_uevent(&e->kobj, KOBJ_REMOVE); | 888 | kobject_uevent(&e->kobj, KOBJ_REMOVE); |
888 | kobject_del(&e->kobj); | 889 | kobject_del(&e->kobj); |
890 | e->registered = 0; | ||
889 | } | 891 | } |
890 | 892 | ||
891 | void elv_unregister_queue(struct request_queue *q) | 893 | void elv_unregister_queue(struct request_queue *q) |
@@ -948,18 +950,19 @@ static int elevator_switch(struct request_queue *q, struct elevator_type *new_e) | |||
948 | { | 950 | { |
949 | struct elevator_queue *old_elevator, *e; | 951 | struct elevator_queue *old_elevator, *e; |
950 | void *data; | 952 | void *data; |
953 | int err; | ||
951 | 954 | ||
952 | /* | 955 | /* |
953 | * Allocate new elevator | 956 | * Allocate new elevator |
954 | */ | 957 | */ |
955 | e = elevator_alloc(q, new_e); | 958 | e = elevator_alloc(q, new_e); |
956 | if (!e) | 959 | if (!e) |
957 | return 0; | 960 | return -ENOMEM; |
958 | 961 | ||
959 | data = elevator_init_queue(q, e); | 962 | data = elevator_init_queue(q, e); |
960 | if (!data) { | 963 | if (!data) { |
961 | kobject_put(&e->kobj); | 964 | kobject_put(&e->kobj); |
962 | return 0; | 965 | return -ENOMEM; |
963 | } | 966 | } |
964 | 967 | ||
965 | /* | 968 | /* |
@@ -980,10 +983,13 @@ static int elevator_switch(struct request_queue *q, struct elevator_type *new_e) | |||
980 | 983 | ||
981 | spin_unlock_irq(q->queue_lock); | 984 | spin_unlock_irq(q->queue_lock); |
982 | 985 | ||
983 | __elv_unregister_queue(old_elevator); | 986 | if (old_elevator->registered) { |
987 | __elv_unregister_queue(old_elevator); | ||
984 | 988 | ||
985 | if (elv_register_queue(q)) | 989 | err = elv_register_queue(q); |
986 | goto fail_register; | 990 | if (err) |
991 | goto fail_register; | ||
992 | } | ||
987 | 993 | ||
988 | /* | 994 | /* |
989 | * finally exit old elevator and turn off BYPASS. | 995 | * finally exit old elevator and turn off BYPASS. |
@@ -995,7 +1001,7 @@ static int elevator_switch(struct request_queue *q, struct elevator_type *new_e) | |||
995 | 1001 | ||
996 | blk_add_trace_msg(q, "elv switch: %s", e->elevator_type->elevator_name); | 1002 | blk_add_trace_msg(q, "elv switch: %s", e->elevator_type->elevator_name); |
997 | 1003 | ||
998 | return 1; | 1004 | return 0; |
999 | 1005 | ||
1000 | fail_register: | 1006 | fail_register: |
1001 | /* | 1007 | /* |
@@ -1010,17 +1016,19 @@ fail_register: | |||
1010 | queue_flag_clear(QUEUE_FLAG_ELVSWITCH, q); | 1016 | queue_flag_clear(QUEUE_FLAG_ELVSWITCH, q); |
1011 | spin_unlock_irq(q->queue_lock); | 1017 | spin_unlock_irq(q->queue_lock); |
1012 | 1018 | ||
1013 | return 0; | 1019 | return err; |
1014 | } | 1020 | } |
1015 | 1021 | ||
1016 | ssize_t elv_iosched_store(struct request_queue *q, const char *name, | 1022 | /* |
1017 | size_t count) | 1023 | * Switch this queue to the given IO scheduler. |
1024 | */ | ||
1025 | int elevator_change(struct request_queue *q, const char *name) | ||
1018 | { | 1026 | { |
1019 | char elevator_name[ELV_NAME_MAX]; | 1027 | char elevator_name[ELV_NAME_MAX]; |
1020 | struct elevator_type *e; | 1028 | struct elevator_type *e; |
1021 | 1029 | ||
1022 | if (!q->elevator) | 1030 | if (!q->elevator) |
1023 | return count; | 1031 | return -ENXIO; |
1024 | 1032 | ||
1025 | strlcpy(elevator_name, name, sizeof(elevator_name)); | 1033 | strlcpy(elevator_name, name, sizeof(elevator_name)); |
1026 | e = elevator_get(strstrip(elevator_name)); | 1034 | e = elevator_get(strstrip(elevator_name)); |
@@ -1031,13 +1039,27 @@ ssize_t elv_iosched_store(struct request_queue *q, const char *name, | |||
1031 | 1039 | ||
1032 | if (!strcmp(elevator_name, q->elevator->elevator_type->elevator_name)) { | 1040 | if (!strcmp(elevator_name, q->elevator->elevator_type->elevator_name)) { |
1033 | elevator_put(e); | 1041 | elevator_put(e); |
1034 | return count; | 1042 | return 0; |
1035 | } | 1043 | } |
1036 | 1044 | ||
1037 | if (!elevator_switch(q, e)) | 1045 | return elevator_switch(q, e); |
1038 | printk(KERN_ERR "elevator: switch to %s failed\n", | 1046 | } |
1039 | elevator_name); | 1047 | EXPORT_SYMBOL(elevator_change); |
1040 | return count; | 1048 | |
1049 | ssize_t elv_iosched_store(struct request_queue *q, const char *name, | ||
1050 | size_t count) | ||
1051 | { | ||
1052 | int ret; | ||
1053 | |||
1054 | if (!q->elevator) | ||
1055 | return count; | ||
1056 | |||
1057 | ret = elevator_change(q, name); | ||
1058 | if (!ret) | ||
1059 | return count; | ||
1060 | |||
1061 | printk(KERN_ERR "elevator: switch to %s failed\n", name); | ||
1062 | return ret; | ||
1041 | } | 1063 | } |
1042 | 1064 | ||
1043 | ssize_t elv_iosched_show(struct request_queue *q, char *name) | 1065 | ssize_t elv_iosched_show(struct request_queue *q, char *name) |
diff --git a/crypto/Kconfig b/crypto/Kconfig index 1cd497d7a15..e573077f167 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig | |||
@@ -101,13 +101,13 @@ config CRYPTO_MANAGER2 | |||
101 | select CRYPTO_BLKCIPHER2 | 101 | select CRYPTO_BLKCIPHER2 |
102 | select CRYPTO_PCOMP2 | 102 | select CRYPTO_PCOMP2 |
103 | 103 | ||
104 | config CRYPTO_MANAGER_TESTS | 104 | config CRYPTO_MANAGER_DISABLE_TESTS |
105 | bool "Run algolithms' self-tests" | 105 | bool "Disable run-time self tests" |
106 | default y | 106 | default y |
107 | depends on CRYPTO_MANAGER2 | 107 | depends on CRYPTO_MANAGER2 |
108 | help | 108 | help |
109 | Run cryptomanager's tests for the new crypto algorithms being | 109 | Disable run-time self tests that normally take place at |
110 | registered. | 110 | algorithm registration. |
111 | 111 | ||
112 | config CRYPTO_GF128MUL | 112 | config CRYPTO_GF128MUL |
113 | tristate "GF(2^128) multiplication functions (EXPERIMENTAL)" | 113 | tristate "GF(2^128) multiplication functions (EXPERIMENTAL)" |
diff --git a/crypto/ahash.c b/crypto/ahash.c index b8c59b889c6..f669822a7a4 100644 --- a/crypto/ahash.c +++ b/crypto/ahash.c | |||
@@ -47,8 +47,11 @@ static int hash_walk_next(struct crypto_hash_walk *walk) | |||
47 | walk->data = crypto_kmap(walk->pg, 0); | 47 | walk->data = crypto_kmap(walk->pg, 0); |
48 | walk->data += offset; | 48 | walk->data += offset; |
49 | 49 | ||
50 | if (offset & alignmask) | 50 | if (offset & alignmask) { |
51 | nbytes = alignmask + 1 - (offset & alignmask); | 51 | unsigned int unaligned = alignmask + 1 - (offset & alignmask); |
52 | if (nbytes > unaligned) | ||
53 | nbytes = unaligned; | ||
54 | } | ||
52 | 55 | ||
53 | walk->entrylen -= nbytes; | 56 | walk->entrylen -= nbytes; |
54 | return nbytes; | 57 | return nbytes; |
diff --git a/crypto/algboss.c b/crypto/algboss.c index 40bd391f34d..791d194958f 100644 --- a/crypto/algboss.c +++ b/crypto/algboss.c | |||
@@ -206,13 +206,16 @@ err: | |||
206 | return NOTIFY_OK; | 206 | return NOTIFY_OK; |
207 | } | 207 | } |
208 | 208 | ||
209 | #ifdef CONFIG_CRYPTO_MANAGER_TESTS | ||
210 | static int cryptomgr_test(void *data) | 209 | static int cryptomgr_test(void *data) |
211 | { | 210 | { |
212 | struct crypto_test_param *param = data; | 211 | struct crypto_test_param *param = data; |
213 | u32 type = param->type; | 212 | u32 type = param->type; |
214 | int err = 0; | 213 | int err = 0; |
215 | 214 | ||
215 | #ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS | ||
216 | goto skiptest; | ||
217 | #endif | ||
218 | |||
216 | if (type & CRYPTO_ALG_TESTED) | 219 | if (type & CRYPTO_ALG_TESTED) |
217 | goto skiptest; | 220 | goto skiptest; |
218 | 221 | ||
@@ -267,7 +270,6 @@ err_put_module: | |||
267 | err: | 270 | err: |
268 | return NOTIFY_OK; | 271 | return NOTIFY_OK; |
269 | } | 272 | } |
270 | #endif /* CONFIG_CRYPTO_MANAGER_TESTS */ | ||
271 | 273 | ||
272 | static int cryptomgr_notify(struct notifier_block *this, unsigned long msg, | 274 | static int cryptomgr_notify(struct notifier_block *this, unsigned long msg, |
273 | void *data) | 275 | void *data) |
@@ -275,10 +277,8 @@ static int cryptomgr_notify(struct notifier_block *this, unsigned long msg, | |||
275 | switch (msg) { | 277 | switch (msg) { |
276 | case CRYPTO_MSG_ALG_REQUEST: | 278 | case CRYPTO_MSG_ALG_REQUEST: |
277 | return cryptomgr_schedule_probe(data); | 279 | return cryptomgr_schedule_probe(data); |
278 | #ifdef CONFIG_CRYPTO_MANAGER_TESTS | ||
279 | case CRYPTO_MSG_ALG_REGISTER: | 280 | case CRYPTO_MSG_ALG_REGISTER: |
280 | return cryptomgr_schedule_test(data); | 281 | return cryptomgr_schedule_test(data); |
281 | #endif | ||
282 | } | 282 | } |
283 | 283 | ||
284 | return NOTIFY_DONE; | 284 | return NOTIFY_DONE; |
diff --git a/crypto/testmgr.c b/crypto/testmgr.c index abd980c729e..fa8c8f78c8d 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c | |||
@@ -23,7 +23,7 @@ | |||
23 | 23 | ||
24 | #include "internal.h" | 24 | #include "internal.h" |
25 | 25 | ||
26 | #ifndef CONFIG_CRYPTO_MANAGER_TESTS | 26 | #ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS |
27 | 27 | ||
28 | /* a perfect nop */ | 28 | /* a perfect nop */ |
29 | int alg_test(const char *driver, const char *alg, u32 type, u32 mask) | 29 | int alg_test(const char *driver, const char *alg, u32 type, u32 mask) |
@@ -2542,6 +2542,6 @@ non_fips_alg: | |||
2542 | return -EINVAL; | 2542 | return -EINVAL; |
2543 | } | 2543 | } |
2544 | 2544 | ||
2545 | #endif /* CONFIG_CRYPTO_MANAGER_TESTS */ | 2545 | #endif /* CONFIG_CRYPTO_MANAGER_DISABLE_TESTS */ |
2546 | 2546 | ||
2547 | EXPORT_SYMBOL_GPL(alg_test); | 2547 | EXPORT_SYMBOL_GPL(alg_test); |
diff --git a/drivers/Makefile b/drivers/Makefile index ae473445ad6..a2aea53a75e 100644 --- a/drivers/Makefile +++ b/drivers/Makefile | |||
@@ -50,7 +50,7 @@ obj-$(CONFIG_SPI) += spi/ | |||
50 | obj-y += net/ | 50 | obj-y += net/ |
51 | obj-$(CONFIG_ATM) += atm/ | 51 | obj-$(CONFIG_ATM) += atm/ |
52 | obj-$(CONFIG_FUSION) += message/ | 52 | obj-$(CONFIG_FUSION) += message/ |
53 | obj-$(CONFIG_FIREWIRE) += firewire/ | 53 | obj-y += firewire/ |
54 | obj-y += ieee1394/ | 54 | obj-y += ieee1394/ |
55 | obj-$(CONFIG_UIO) += uio/ | 55 | obj-$(CONFIG_UIO) += uio/ |
56 | obj-y += cdrom/ | 56 | obj-y += cdrom/ |
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index b811f2173f6..88681aca88c 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -105,7 +105,7 @@ config ACPI_EC_DEBUGFS | |||
105 | 105 | ||
106 | Be aware that using this interface can confuse your Embedded | 106 | Be aware that using this interface can confuse your Embedded |
107 | Controller in a way that a normal reboot is not enough. You then | 107 | Controller in a way that a normal reboot is not enough. You then |
108 | have to power of your system, and remove the laptop battery for | 108 | have to power off your system, and remove the laptop battery for |
109 | some seconds. | 109 | some seconds. |
110 | An Embedded Controller typically is available on laptops and reads | 110 | An Embedded Controller typically is available on laptops and reads |
111 | sensor values like battery state and temperature. | 111 | sensor values like battery state and temperature. |
diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index b76848c80be..6b115f6c431 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c | |||
@@ -382,31 +382,32 @@ static void acpi_pad_remove_sysfs(struct acpi_device *device) | |||
382 | device_remove_file(&device->dev, &dev_attr_rrtime); | 382 | device_remove_file(&device->dev, &dev_attr_rrtime); |
383 | } | 383 | } |
384 | 384 | ||
385 | /* Query firmware how many CPUs should be idle */ | 385 | /* |
386 | static int acpi_pad_pur(acpi_handle handle, int *num_cpus) | 386 | * Query firmware how many CPUs should be idle |
387 | * return -1 on failure | ||
388 | */ | ||
389 | static int acpi_pad_pur(acpi_handle handle) | ||
387 | { | 390 | { |
388 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; | 391 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; |
389 | union acpi_object *package; | 392 | union acpi_object *package; |
390 | int rev, num, ret = -EINVAL; | 393 | int num = -1; |
391 | 394 | ||
392 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_PUR", NULL, &buffer))) | 395 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_PUR", NULL, &buffer))) |
393 | return -EINVAL; | 396 | return num; |
394 | 397 | ||
395 | if (!buffer.length || !buffer.pointer) | 398 | if (!buffer.length || !buffer.pointer) |
396 | return -EINVAL; | 399 | return num; |
397 | 400 | ||
398 | package = buffer.pointer; | 401 | package = buffer.pointer; |
399 | if (package->type != ACPI_TYPE_PACKAGE || package->package.count != 2) | 402 | |
400 | goto out; | 403 | if (package->type == ACPI_TYPE_PACKAGE && |
401 | rev = package->package.elements[0].integer.value; | 404 | package->package.count == 2 && |
402 | num = package->package.elements[1].integer.value; | 405 | package->package.elements[0].integer.value == 1) /* rev 1 */ |
403 | if (rev != 1 || num < 0) | 406 | |
404 | goto out; | 407 | num = package->package.elements[1].integer.value; |
405 | *num_cpus = num; | 408 | |
406 | ret = 0; | ||
407 | out: | ||
408 | kfree(buffer.pointer); | 409 | kfree(buffer.pointer); |
409 | return ret; | 410 | return num; |
410 | } | 411 | } |
411 | 412 | ||
412 | /* Notify firmware how many CPUs are idle */ | 413 | /* Notify firmware how many CPUs are idle */ |
@@ -433,7 +434,8 @@ static void acpi_pad_handle_notify(acpi_handle handle) | |||
433 | uint32_t idle_cpus; | 434 | uint32_t idle_cpus; |
434 | 435 | ||
435 | mutex_lock(&isolated_cpus_lock); | 436 | mutex_lock(&isolated_cpus_lock); |
436 | if (acpi_pad_pur(handle, &num_cpus)) { | 437 | num_cpus = acpi_pad_pur(handle); |
438 | if (num_cpus < 0) { | ||
437 | mutex_unlock(&isolated_cpus_lock); | 439 | mutex_unlock(&isolated_cpus_lock); |
438 | return; | 440 | return; |
439 | } | 441 | } |
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index df85b53a674..7dad9160f20 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h | |||
@@ -854,6 +854,7 @@ struct acpi_bit_register_info { | |||
854 | ACPI_BITMASK_POWER_BUTTON_STATUS | \ | 854 | ACPI_BITMASK_POWER_BUTTON_STATUS | \ |
855 | ACPI_BITMASK_SLEEP_BUTTON_STATUS | \ | 855 | ACPI_BITMASK_SLEEP_BUTTON_STATUS | \ |
856 | ACPI_BITMASK_RT_CLOCK_STATUS | \ | 856 | ACPI_BITMASK_RT_CLOCK_STATUS | \ |
857 | ACPI_BITMASK_PCIEXP_WAKE_DISABLE | \ | ||
857 | ACPI_BITMASK_WAKE_STATUS) | 858 | ACPI_BITMASK_WAKE_STATUS) |
858 | 859 | ||
859 | #define ACPI_BITMASK_TIMER_ENABLE 0x0001 | 860 | #define ACPI_BITMASK_TIMER_ENABLE 0x0001 |
diff --git a/drivers/acpi/acpica/exutils.c b/drivers/acpi/acpica/exutils.c index 74c24d517f8..4093522eed4 100644 --- a/drivers/acpi/acpica/exutils.c +++ b/drivers/acpi/acpica/exutils.c | |||
@@ -109,7 +109,7 @@ void acpi_ex_enter_interpreter(void) | |||
109 | * | 109 | * |
110 | * DESCRIPTION: Reacquire the interpreter execution region from within the | 110 | * DESCRIPTION: Reacquire the interpreter execution region from within the |
111 | * interpreter code. Failure to enter the interpreter region is a | 111 | * interpreter code. Failure to enter the interpreter region is a |
112 | * fatal system error. Used in conjuction with | 112 | * fatal system error. Used in conjunction with |
113 | * relinquish_interpreter | 113 | * relinquish_interpreter |
114 | * | 114 | * |
115 | ******************************************************************************/ | 115 | ******************************************************************************/ |
diff --git a/drivers/acpi/acpica/rsutils.c b/drivers/acpi/acpica/rsutils.c index 22cfcfbd9ff..491191e6cf6 100644 --- a/drivers/acpi/acpica/rsutils.c +++ b/drivers/acpi/acpica/rsutils.c | |||
@@ -149,7 +149,7 @@ acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type) | |||
149 | 149 | ||
150 | /* | 150 | /* |
151 | * 16-, 32-, and 64-bit cases must use the move macros that perform | 151 | * 16-, 32-, and 64-bit cases must use the move macros that perform |
152 | * endian conversion and/or accomodate hardware that cannot perform | 152 | * endian conversion and/or accommodate hardware that cannot perform |
153 | * misaligned memory transfers | 153 | * misaligned memory transfers |
154 | */ | 154 | */ |
155 | case ACPI_RSC_MOVE16: | 155 | case ACPI_RSC_MOVE16: |
diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig index 907e350f1c7..fca34ccfd29 100644 --- a/drivers/acpi/apei/Kconfig +++ b/drivers/acpi/apei/Kconfig | |||
@@ -34,6 +34,6 @@ config ACPI_APEI_ERST_DEBUG | |||
34 | depends on ACPI_APEI | 34 | depends on ACPI_APEI |
35 | help | 35 | help |
36 | ERST is a way provided by APEI to save and retrieve hardware | 36 | ERST is a way provided by APEI to save and retrieve hardware |
37 | error infomation to and from a persistent store. Enable this | 37 | error information to and from a persistent store. Enable this |
38 | if you want to debugging and testing the ERST kernel support | 38 | if you want to debugging and testing the ERST kernel support |
39 | and firmware implementation. | 39 | and firmware implementation. |
diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c index 73fd0c7487c..4a904a4bf05 100644 --- a/drivers/acpi/apei/apei-base.c +++ b/drivers/acpi/apei/apei-base.c | |||
@@ -445,11 +445,15 @@ EXPORT_SYMBOL_GPL(apei_resources_sub); | |||
445 | int apei_resources_request(struct apei_resources *resources, | 445 | int apei_resources_request(struct apei_resources *resources, |
446 | const char *desc) | 446 | const char *desc) |
447 | { | 447 | { |
448 | struct apei_res *res, *res_bak; | 448 | struct apei_res *res, *res_bak = NULL; |
449 | struct resource *r; | 449 | struct resource *r; |
450 | int rc; | ||
450 | 451 | ||
451 | apei_resources_sub(resources, &apei_resources_all); | 452 | rc = apei_resources_sub(resources, &apei_resources_all); |
453 | if (rc) | ||
454 | return rc; | ||
452 | 455 | ||
456 | rc = -EINVAL; | ||
453 | list_for_each_entry(res, &resources->iomem, list) { | 457 | list_for_each_entry(res, &resources->iomem, list) { |
454 | r = request_mem_region(res->start, res->end - res->start, | 458 | r = request_mem_region(res->start, res->end - res->start, |
455 | desc); | 459 | desc); |
@@ -475,7 +479,11 @@ int apei_resources_request(struct apei_resources *resources, | |||
475 | } | 479 | } |
476 | } | 480 | } |
477 | 481 | ||
478 | apei_resources_merge(&apei_resources_all, resources); | 482 | rc = apei_resources_merge(&apei_resources_all, resources); |
483 | if (rc) { | ||
484 | pr_err(APEI_PFX "Fail to merge resources!\n"); | ||
485 | goto err_unmap_ioport; | ||
486 | } | ||
479 | 487 | ||
480 | return 0; | 488 | return 0; |
481 | err_unmap_ioport: | 489 | err_unmap_ioport: |
@@ -491,12 +499,13 @@ err_unmap_iomem: | |||
491 | break; | 499 | break; |
492 | release_mem_region(res->start, res->end - res->start); | 500 | release_mem_region(res->start, res->end - res->start); |
493 | } | 501 | } |
494 | return -EINVAL; | 502 | return rc; |
495 | } | 503 | } |
496 | EXPORT_SYMBOL_GPL(apei_resources_request); | 504 | EXPORT_SYMBOL_GPL(apei_resources_request); |
497 | 505 | ||
498 | void apei_resources_release(struct apei_resources *resources) | 506 | void apei_resources_release(struct apei_resources *resources) |
499 | { | 507 | { |
508 | int rc; | ||
500 | struct apei_res *res; | 509 | struct apei_res *res; |
501 | 510 | ||
502 | list_for_each_entry(res, &resources->iomem, list) | 511 | list_for_each_entry(res, &resources->iomem, list) |
@@ -504,7 +513,9 @@ void apei_resources_release(struct apei_resources *resources) | |||
504 | list_for_each_entry(res, &resources->ioport, list) | 513 | list_for_each_entry(res, &resources->ioport, list) |
505 | release_region(res->start, res->end - res->start); | 514 | release_region(res->start, res->end - res->start); |
506 | 515 | ||
507 | apei_resources_sub(&apei_resources_all, resources); | 516 | rc = apei_resources_sub(&apei_resources_all, resources); |
517 | if (rc) | ||
518 | pr_err(APEI_PFX "Fail to sub resources!\n"); | ||
508 | } | 519 | } |
509 | EXPORT_SYMBOL_GPL(apei_resources_release); | 520 | EXPORT_SYMBOL_GPL(apei_resources_release); |
510 | 521 | ||
diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c index 465c885938e..cf29df69380 100644 --- a/drivers/acpi/apei/einj.c +++ b/drivers/acpi/apei/einj.c | |||
@@ -426,7 +426,9 @@ DEFINE_SIMPLE_ATTRIBUTE(error_inject_fops, NULL, | |||
426 | 426 | ||
427 | static int einj_check_table(struct acpi_table_einj *einj_tab) | 427 | static int einj_check_table(struct acpi_table_einj *einj_tab) |
428 | { | 428 | { |
429 | if (einj_tab->header_length != sizeof(struct acpi_table_einj)) | 429 | if ((einj_tab->header_length != |
430 | (sizeof(struct acpi_table_einj) - sizeof(einj_tab->header))) | ||
431 | && (einj_tab->header_length != sizeof(struct acpi_table_einj))) | ||
430 | return -EINVAL; | 432 | return -EINVAL; |
431 | if (einj_tab->header.length < sizeof(struct acpi_table_einj)) | 433 | if (einj_tab->header.length < sizeof(struct acpi_table_einj)) |
432 | return -EINVAL; | 434 | return -EINVAL; |
diff --git a/drivers/acpi/apei/erst-dbg.c b/drivers/acpi/apei/erst-dbg.c index 5281ddda277..da1228a9a54 100644 --- a/drivers/acpi/apei/erst-dbg.c +++ b/drivers/acpi/apei/erst-dbg.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * APEI Error Record Serialization Table debug support | 2 | * APEI Error Record Serialization Table debug support |
3 | * | 3 | * |
4 | * ERST is a way provided by APEI to save and retrieve hardware error | 4 | * ERST is a way provided by APEI to save and retrieve hardware error |
5 | * infomation to and from a persistent store. This file provide the | 5 | * information to and from a persistent store. This file provide the |
6 | * debugging/testing support for ERST kernel support and firmware | 6 | * debugging/testing support for ERST kernel support and firmware |
7 | * implementation. | 7 | * implementation. |
8 | * | 8 | * |
@@ -111,11 +111,13 @@ retry: | |||
111 | goto out; | 111 | goto out; |
112 | } | 112 | } |
113 | if (len > erst_dbg_buf_len) { | 113 | if (len > erst_dbg_buf_len) { |
114 | kfree(erst_dbg_buf); | 114 | void *p; |
115 | rc = -ENOMEM; | 115 | rc = -ENOMEM; |
116 | erst_dbg_buf = kmalloc(len, GFP_KERNEL); | 116 | p = kmalloc(len, GFP_KERNEL); |
117 | if (!erst_dbg_buf) | 117 | if (!p) |
118 | goto out; | 118 | goto out; |
119 | kfree(erst_dbg_buf); | ||
120 | erst_dbg_buf = p; | ||
119 | erst_dbg_buf_len = len; | 121 | erst_dbg_buf_len = len; |
120 | goto retry; | 122 | goto retry; |
121 | } | 123 | } |
@@ -150,11 +152,13 @@ static ssize_t erst_dbg_write(struct file *filp, const char __user *ubuf, | |||
150 | if (mutex_lock_interruptible(&erst_dbg_mutex)) | 152 | if (mutex_lock_interruptible(&erst_dbg_mutex)) |
151 | return -EINTR; | 153 | return -EINTR; |
152 | if (usize > erst_dbg_buf_len) { | 154 | if (usize > erst_dbg_buf_len) { |
153 | kfree(erst_dbg_buf); | 155 | void *p; |
154 | rc = -ENOMEM; | 156 | rc = -ENOMEM; |
155 | erst_dbg_buf = kmalloc(usize, GFP_KERNEL); | 157 | p = kmalloc(usize, GFP_KERNEL); |
156 | if (!erst_dbg_buf) | 158 | if (!p) |
157 | goto out; | 159 | goto out; |
160 | kfree(erst_dbg_buf); | ||
161 | erst_dbg_buf = p; | ||
158 | erst_dbg_buf_len = usize; | 162 | erst_dbg_buf_len = usize; |
159 | } | 163 | } |
160 | rc = copy_from_user(erst_dbg_buf, ubuf, usize); | 164 | rc = copy_from_user(erst_dbg_buf, ubuf, usize); |
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c index 18645f4e83c..1211c03149e 100644 --- a/drivers/acpi/apei/erst.c +++ b/drivers/acpi/apei/erst.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * APEI Error Record Serialization Table support | 2 | * APEI Error Record Serialization Table support |
3 | * | 3 | * |
4 | * ERST is a way provided by APEI to save and retrieve hardware error | 4 | * ERST is a way provided by APEI to save and retrieve hardware error |
5 | * infomation to and from a persistent store. | 5 | * information to and from a persistent store. |
6 | * | 6 | * |
7 | * For more information about ERST, please refer to ACPI Specification | 7 | * For more information about ERST, please refer to ACPI Specification |
8 | * version 4.0, section 17.4. | 8 | * version 4.0, section 17.4. |
@@ -266,13 +266,30 @@ static int erst_exec_move_data(struct apei_exec_context *ctx, | |||
266 | { | 266 | { |
267 | int rc; | 267 | int rc; |
268 | u64 offset; | 268 | u64 offset; |
269 | void *src, *dst; | ||
270 | |||
271 | /* ioremap does not work in interrupt context */ | ||
272 | if (in_interrupt()) { | ||
273 | pr_warning(ERST_PFX | ||
274 | "MOVE_DATA can not be used in interrupt context"); | ||
275 | return -EBUSY; | ||
276 | } | ||
269 | 277 | ||
270 | rc = __apei_exec_read_register(entry, &offset); | 278 | rc = __apei_exec_read_register(entry, &offset); |
271 | if (rc) | 279 | if (rc) |
272 | return rc; | 280 | return rc; |
273 | memmove((void *)ctx->dst_base + offset, | 281 | |
274 | (void *)ctx->src_base + offset, | 282 | src = ioremap(ctx->src_base + offset, ctx->var2); |
275 | ctx->var2); | 283 | if (!src) |
284 | return -ENOMEM; | ||
285 | dst = ioremap(ctx->dst_base + offset, ctx->var2); | ||
286 | if (!dst) | ||
287 | return -ENOMEM; | ||
288 | |||
289 | memmove(dst, src, ctx->var2); | ||
290 | |||
291 | iounmap(src); | ||
292 | iounmap(dst); | ||
276 | 293 | ||
277 | return 0; | 294 | return 0; |
278 | } | 295 | } |
@@ -750,7 +767,9 @@ __setup("erst_disable", setup_erst_disable); | |||
750 | 767 | ||
751 | static int erst_check_table(struct acpi_table_erst *erst_tab) | 768 | static int erst_check_table(struct acpi_table_erst *erst_tab) |
752 | { | 769 | { |
753 | if (erst_tab->header_length != sizeof(struct acpi_table_erst)) | 770 | if ((erst_tab->header_length != |
771 | (sizeof(struct acpi_table_erst) - sizeof(erst_tab->header))) | ||
772 | && (erst_tab->header_length != sizeof(struct acpi_table_einj))) | ||
754 | return -EINVAL; | 773 | return -EINVAL; |
755 | if (erst_tab->header.length < sizeof(struct acpi_table_erst)) | 774 | if (erst_tab->header.length < sizeof(struct acpi_table_erst)) |
756 | return -EINVAL; | 775 | return -EINVAL; |
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 385a6059714..0d505e59214 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c | |||
@@ -302,7 +302,7 @@ static int __devinit ghes_probe(struct platform_device *ghes_dev) | |||
302 | struct ghes *ghes = NULL; | 302 | struct ghes *ghes = NULL; |
303 | int rc = -EINVAL; | 303 | int rc = -EINVAL; |
304 | 304 | ||
305 | generic = ghes_dev->dev.platform_data; | 305 | generic = *(struct acpi_hest_generic **)ghes_dev->dev.platform_data; |
306 | if (!generic->enabled) | 306 | if (!generic->enabled) |
307 | return -ENODEV; | 307 | return -ENODEV; |
308 | 308 | ||
diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c index 343168d1826..1a3508a7fe0 100644 --- a/drivers/acpi/apei/hest.c +++ b/drivers/acpi/apei/hest.c | |||
@@ -137,20 +137,23 @@ static int hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data) | |||
137 | 137 | ||
138 | static int hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data) | 138 | static int hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data) |
139 | { | 139 | { |
140 | struct acpi_hest_generic *generic; | ||
141 | struct platform_device *ghes_dev; | 140 | struct platform_device *ghes_dev; |
142 | struct ghes_arr *ghes_arr = data; | 141 | struct ghes_arr *ghes_arr = data; |
143 | int rc; | 142 | int rc; |
144 | 143 | ||
145 | if (hest_hdr->type != ACPI_HEST_TYPE_GENERIC_ERROR) | 144 | if (hest_hdr->type != ACPI_HEST_TYPE_GENERIC_ERROR) |
146 | return 0; | 145 | return 0; |
147 | generic = (struct acpi_hest_generic *)hest_hdr; | 146 | |
148 | if (!generic->enabled) | 147 | if (!((struct acpi_hest_generic *)hest_hdr)->enabled) |
149 | return 0; | 148 | return 0; |
150 | ghes_dev = platform_device_alloc("GHES", hest_hdr->source_id); | 149 | ghes_dev = platform_device_alloc("GHES", hest_hdr->source_id); |
151 | if (!ghes_dev) | 150 | if (!ghes_dev) |
152 | return -ENOMEM; | 151 | return -ENOMEM; |
153 | ghes_dev->dev.platform_data = generic; | 152 | |
153 | rc = platform_device_add_data(ghes_dev, &hest_hdr, sizeof(void *)); | ||
154 | if (rc) | ||
155 | goto err; | ||
156 | |||
154 | rc = platform_device_add(ghes_dev); | 157 | rc = platform_device_add(ghes_dev); |
155 | if (rc) | 158 | if (rc) |
156 | goto err; | 159 | goto err; |
diff --git a/drivers/acpi/atomicio.c b/drivers/acpi/atomicio.c index 8f8bd736d4f..542e5390389 100644 --- a/drivers/acpi/atomicio.c +++ b/drivers/acpi/atomicio.c | |||
@@ -142,7 +142,7 @@ static void __iomem *acpi_pre_map(phys_addr_t paddr, | |||
142 | list_add_tail_rcu(&map->list, &acpi_iomaps); | 142 | list_add_tail_rcu(&map->list, &acpi_iomaps); |
143 | spin_unlock_irqrestore(&acpi_iomaps_lock, flags); | 143 | spin_unlock_irqrestore(&acpi_iomaps_lock, flags); |
144 | 144 | ||
145 | return vaddr + (paddr - pg_off); | 145 | return map->vaddr + (paddr - map->paddr); |
146 | err_unmap: | 146 | err_unmap: |
147 | iounmap(vaddr); | 147 | iounmap(vaddr); |
148 | return NULL; | 148 | return NULL; |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index dc58402b0a1..98417201e9c 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -273,7 +273,6 @@ static enum power_supply_property energy_battery_props[] = { | |||
273 | POWER_SUPPLY_PROP_CYCLE_COUNT, | 273 | POWER_SUPPLY_PROP_CYCLE_COUNT, |
274 | POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, | 274 | POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, |
275 | POWER_SUPPLY_PROP_VOLTAGE_NOW, | 275 | POWER_SUPPLY_PROP_VOLTAGE_NOW, |
276 | POWER_SUPPLY_PROP_CURRENT_NOW, | ||
277 | POWER_SUPPLY_PROP_POWER_NOW, | 276 | POWER_SUPPLY_PROP_POWER_NOW, |
278 | POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, | 277 | POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, |
279 | POWER_SUPPLY_PROP_ENERGY_FULL, | 278 | POWER_SUPPLY_PROP_ENERGY_FULL, |
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index 2bb28b9d91c..af308d03f49 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c | |||
@@ -183,6 +183,8 @@ static int __init dmi_disable_osi_vista(const struct dmi_system_id *d) | |||
183 | { | 183 | { |
184 | printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); | 184 | printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); |
185 | acpi_osi_setup("!Windows 2006"); | 185 | acpi_osi_setup("!Windows 2006"); |
186 | acpi_osi_setup("!Windows 2006 SP1"); | ||
187 | acpi_osi_setup("!Windows 2006 SP2"); | ||
186 | return 0; | 188 | return 0; |
187 | } | 189 | } |
188 | static int __init dmi_disable_osi_win7(const struct dmi_system_id *d) | 190 | static int __init dmi_disable_osi_win7(const struct dmi_system_id *d) |
@@ -202,6 +204,23 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | |||
202 | }, | 204 | }, |
203 | }, | 205 | }, |
204 | { | 206 | { |
207 | /* | ||
208 | * There have a NVIF method in MSI GX723 DSDT need call by Nvidia | ||
209 | * driver (e.g. nouveau) when user press brightness hotkey. | ||
210 | * Currently, nouveau driver didn't do the job and it causes there | ||
211 | * have a infinite while loop in DSDT when user press hotkey. | ||
212 | * We add MSI GX723's dmi information to this table for workaround | ||
213 | * this issue. | ||
214 | * Will remove MSI GX723 from the table after nouveau grows support. | ||
215 | */ | ||
216 | .callback = dmi_disable_osi_vista, | ||
217 | .ident = "MSI GX723", | ||
218 | .matches = { | ||
219 | DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"), | ||
220 | DMI_MATCH(DMI_PRODUCT_NAME, "GX723"), | ||
221 | }, | ||
222 | }, | ||
223 | { | ||
205 | .callback = dmi_disable_osi_vista, | 224 | .callback = dmi_disable_osi_vista, |
206 | .ident = "Sony VGN-NS10J_S", | 225 | .ident = "Sony VGN-NS10J_S", |
207 | .matches = { | 226 | .matches = { |
@@ -226,6 +245,14 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | |||
226 | }, | 245 | }, |
227 | }, | 246 | }, |
228 | { | 247 | { |
248 | .callback = dmi_disable_osi_vista, | ||
249 | .ident = "Toshiba Satellite L355", | ||
250 | .matches = { | ||
251 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
252 | DMI_MATCH(DMI_PRODUCT_VERSION, "Satellite L355"), | ||
253 | }, | ||
254 | }, | ||
255 | { | ||
229 | .callback = dmi_disable_osi_win7, | 256 | .callback = dmi_disable_osi_win7, |
230 | .ident = "ASUS K50IJ", | 257 | .ident = "ASUS K50IJ", |
231 | .matches = { | 258 | .matches = { |
@@ -233,6 +260,14 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | |||
233 | DMI_MATCH(DMI_PRODUCT_NAME, "K50IJ"), | 260 | DMI_MATCH(DMI_PRODUCT_NAME, "K50IJ"), |
234 | }, | 261 | }, |
235 | }, | 262 | }, |
263 | { | ||
264 | .callback = dmi_disable_osi_vista, | ||
265 | .ident = "Toshiba P305D", | ||
266 | .matches = { | ||
267 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
268 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P305D"), | ||
269 | }, | ||
270 | }, | ||
236 | 271 | ||
237 | /* | 272 | /* |
238 | * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. | 273 | * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. |
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 5c221ab535d..310e3b9749c 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -55,7 +55,7 @@ EXPORT_SYMBOL(acpi_root_dir); | |||
55 | static int set_power_nocheck(const struct dmi_system_id *id) | 55 | static int set_power_nocheck(const struct dmi_system_id *id) |
56 | { | 56 | { |
57 | printk(KERN_NOTICE PREFIX "%s detected - " | 57 | printk(KERN_NOTICE PREFIX "%s detected - " |
58 | "disable power check in power transistion\n", id->ident); | 58 | "disable power check in power transition\n", id->ident); |
59 | acpi_power_nocheck = 1; | 59 | acpi_power_nocheck = 1; |
60 | return 0; | 60 | return 0; |
61 | } | 61 | } |
@@ -80,23 +80,15 @@ static int set_copy_dsdt(const struct dmi_system_id *id) | |||
80 | 80 | ||
81 | static struct dmi_system_id dsdt_dmi_table[] __initdata = { | 81 | static struct dmi_system_id dsdt_dmi_table[] __initdata = { |
82 | /* | 82 | /* |
83 | * Insyde BIOS on some TOSHIBA machines corrupt the DSDT. | 83 | * Invoke DSDT corruption work-around on all Toshiba Satellite. |
84 | * https://bugzilla.kernel.org/show_bug.cgi?id=14679 | 84 | * https://bugzilla.kernel.org/show_bug.cgi?id=14679 |
85 | */ | 85 | */ |
86 | { | 86 | { |
87 | .callback = set_copy_dsdt, | 87 | .callback = set_copy_dsdt, |
88 | .ident = "TOSHIBA Satellite A505", | 88 | .ident = "TOSHIBA Satellite", |
89 | .matches = { | 89 | .matches = { |
90 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | 90 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), |
91 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A505"), | 91 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite"), |
92 | }, | ||
93 | }, | ||
94 | { | ||
95 | .callback = set_copy_dsdt, | ||
96 | .ident = "TOSHIBA Satellite L505D", | ||
97 | .matches = { | ||
98 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
99 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite L505D"), | ||
100 | }, | 92 | }, |
101 | }, | 93 | }, |
102 | {} | 94 | {} |
@@ -1027,7 +1019,7 @@ static int __init acpi_init(void) | |||
1027 | 1019 | ||
1028 | /* | 1020 | /* |
1029 | * If the laptop falls into the DMI check table, the power state check | 1021 | * If the laptop falls into the DMI check table, the power state check |
1030 | * will be disabled in the course of device power transistion. | 1022 | * will be disabled in the course of device power transition. |
1031 | */ | 1023 | */ |
1032 | dmi_check_system(power_nocheck_dmi_table); | 1024 | dmi_check_system(power_nocheck_dmi_table); |
1033 | 1025 | ||
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 8a3b840c0bb..d94d2953c97 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c | |||
@@ -369,7 +369,9 @@ static void __exit acpi_fan_exit(void) | |||
369 | 369 | ||
370 | acpi_bus_unregister_driver(&acpi_fan_driver); | 370 | acpi_bus_unregister_driver(&acpi_fan_driver); |
371 | 371 | ||
372 | #ifdef CONFIG_ACPI_PROCFS | ||
372 | remove_proc_entry(ACPI_FAN_CLASS, acpi_root_dir); | 373 | remove_proc_entry(ACPI_FAN_CLASS, acpi_root_dir); |
374 | #endif | ||
373 | 375 | ||
374 | return; | 376 | return; |
375 | } | 377 | } |
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 1f67057af2a..3ba8d1f44a7 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include <linux/pm_runtime.h> | 33 | #include <linux/pm_runtime.h> |
34 | #include <linux/pci.h> | 34 | #include <linux/pci.h> |
35 | #include <linux/pci-acpi.h> | 35 | #include <linux/pci-acpi.h> |
36 | #include <linux/pci-aspm.h> | ||
37 | #include <linux/acpi.h> | 36 | #include <linux/acpi.h> |
38 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
39 | #include <acpi/acpi_bus.h> | 38 | #include <acpi/acpi_bus.h> |
@@ -226,22 +225,31 @@ static acpi_status acpi_pci_run_osc(acpi_handle handle, | |||
226 | return status; | 225 | return status; |
227 | } | 226 | } |
228 | 227 | ||
229 | static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root, u32 flags) | 228 | static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root, |
229 | u32 support, | ||
230 | u32 *control) | ||
230 | { | 231 | { |
231 | acpi_status status; | 232 | acpi_status status; |
232 | u32 support_set, result, capbuf[3]; | 233 | u32 result, capbuf[3]; |
234 | |||
235 | support &= OSC_PCI_SUPPORT_MASKS; | ||
236 | support |= root->osc_support_set; | ||
233 | 237 | ||
234 | /* do _OSC query for all possible controls */ | ||
235 | support_set = root->osc_support_set | (flags & OSC_PCI_SUPPORT_MASKS); | ||
236 | capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE; | 238 | capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE; |
237 | capbuf[OSC_SUPPORT_TYPE] = support_set; | 239 | capbuf[OSC_SUPPORT_TYPE] = support; |
238 | capbuf[OSC_CONTROL_TYPE] = OSC_PCI_CONTROL_MASKS; | 240 | if (control) { |
241 | *control &= OSC_PCI_CONTROL_MASKS; | ||
242 | capbuf[OSC_CONTROL_TYPE] = *control | root->osc_control_set; | ||
243 | } else { | ||
244 | /* Run _OSC query for all possible controls. */ | ||
245 | capbuf[OSC_CONTROL_TYPE] = OSC_PCI_CONTROL_MASKS; | ||
246 | } | ||
239 | 247 | ||
240 | status = acpi_pci_run_osc(root->device->handle, capbuf, &result); | 248 | status = acpi_pci_run_osc(root->device->handle, capbuf, &result); |
241 | if (ACPI_SUCCESS(status)) { | 249 | if (ACPI_SUCCESS(status)) { |
242 | root->osc_support_set = support_set; | 250 | root->osc_support_set = support; |
243 | root->osc_control_qry = result; | 251 | if (control) |
244 | root->osc_queried = 1; | 252 | *control = result; |
245 | } | 253 | } |
246 | return status; | 254 | return status; |
247 | } | 255 | } |
@@ -255,7 +263,7 @@ static acpi_status acpi_pci_osc_support(struct acpi_pci_root *root, u32 flags) | |||
255 | if (ACPI_FAILURE(status)) | 263 | if (ACPI_FAILURE(status)) |
256 | return status; | 264 | return status; |
257 | mutex_lock(&osc_lock); | 265 | mutex_lock(&osc_lock); |
258 | status = acpi_pci_query_osc(root, flags); | 266 | status = acpi_pci_query_osc(root, flags, NULL); |
259 | mutex_unlock(&osc_lock); | 267 | mutex_unlock(&osc_lock); |
260 | return status; | 268 | return status; |
261 | } | 269 | } |
@@ -365,55 +373,70 @@ out: | |||
365 | EXPORT_SYMBOL_GPL(acpi_get_pci_dev); | 373 | EXPORT_SYMBOL_GPL(acpi_get_pci_dev); |
366 | 374 | ||
367 | /** | 375 | /** |
368 | * acpi_pci_osc_control_set - commit requested control to Firmware | 376 | * acpi_pci_osc_control_set - Request control of PCI root _OSC features. |
369 | * @handle: acpi_handle for the target ACPI object | 377 | * @handle: ACPI handle of a PCI root bridge (or PCIe Root Complex). |
370 | * @flags: driver's requested control bits | 378 | * @mask: Mask of _OSC bits to request control of, place to store control mask. |
379 | * @req: Mask of _OSC bits the control of is essential to the caller. | ||
380 | * | ||
381 | * Run _OSC query for @mask and if that is successful, compare the returned | ||
382 | * mask of control bits with @req. If all of the @req bits are set in the | ||
383 | * returned mask, run _OSC request for it. | ||
371 | * | 384 | * |
372 | * Attempt to take control from Firmware on requested control bits. | 385 | * The variable at the @mask address may be modified regardless of whether or |
386 | * not the function returns success. On success it will contain the mask of | ||
387 | * _OSC bits the BIOS has granted control of, but its contents are meaningless | ||
388 | * on failure. | ||
373 | **/ | 389 | **/ |
374 | acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 flags) | 390 | acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 req) |
375 | { | 391 | { |
392 | struct acpi_pci_root *root; | ||
376 | acpi_status status; | 393 | acpi_status status; |
377 | u32 control_req, result, capbuf[3]; | 394 | u32 ctrl, capbuf[3]; |
378 | acpi_handle tmp; | 395 | acpi_handle tmp; |
379 | struct acpi_pci_root *root; | ||
380 | 396 | ||
381 | status = acpi_get_handle(handle, "_OSC", &tmp); | 397 | if (!mask) |
382 | if (ACPI_FAILURE(status)) | 398 | return AE_BAD_PARAMETER; |
383 | return status; | ||
384 | 399 | ||
385 | control_req = (flags & OSC_PCI_CONTROL_MASKS); | 400 | ctrl = *mask & OSC_PCI_CONTROL_MASKS; |
386 | if (!control_req) | 401 | if ((ctrl & req) != req) |
387 | return AE_TYPE; | 402 | return AE_TYPE; |
388 | 403 | ||
389 | root = acpi_pci_find_root(handle); | 404 | root = acpi_pci_find_root(handle); |
390 | if (!root) | 405 | if (!root) |
391 | return AE_NOT_EXIST; | 406 | return AE_NOT_EXIST; |
392 | 407 | ||
408 | status = acpi_get_handle(handle, "_OSC", &tmp); | ||
409 | if (ACPI_FAILURE(status)) | ||
410 | return status; | ||
411 | |||
393 | mutex_lock(&osc_lock); | 412 | mutex_lock(&osc_lock); |
413 | |||
414 | *mask = ctrl | root->osc_control_set; | ||
394 | /* No need to evaluate _OSC if the control was already granted. */ | 415 | /* No need to evaluate _OSC if the control was already granted. */ |
395 | if ((root->osc_control_set & control_req) == control_req) | 416 | if ((root->osc_control_set & ctrl) == ctrl) |
396 | goto out; | 417 | goto out; |
397 | 418 | ||
398 | /* Need to query controls first before requesting them */ | 419 | /* Need to check the available controls bits before requesting them. */ |
399 | if (!root->osc_queried) { | 420 | while (*mask) { |
400 | status = acpi_pci_query_osc(root, root->osc_support_set); | 421 | status = acpi_pci_query_osc(root, root->osc_support_set, mask); |
401 | if (ACPI_FAILURE(status)) | 422 | if (ACPI_FAILURE(status)) |
402 | goto out; | 423 | goto out; |
424 | if (ctrl == *mask) | ||
425 | break; | ||
426 | ctrl = *mask; | ||
403 | } | 427 | } |
404 | if ((root->osc_control_qry & control_req) != control_req) { | 428 | |
405 | printk(KERN_DEBUG | 429 | if ((ctrl & req) != req) { |
406 | "Firmware did not grant requested _OSC control\n"); | ||
407 | status = AE_SUPPORT; | 430 | status = AE_SUPPORT; |
408 | goto out; | 431 | goto out; |
409 | } | 432 | } |
410 | 433 | ||
411 | capbuf[OSC_QUERY_TYPE] = 0; | 434 | capbuf[OSC_QUERY_TYPE] = 0; |
412 | capbuf[OSC_SUPPORT_TYPE] = root->osc_support_set; | 435 | capbuf[OSC_SUPPORT_TYPE] = root->osc_support_set; |
413 | capbuf[OSC_CONTROL_TYPE] = root->osc_control_set | control_req; | 436 | capbuf[OSC_CONTROL_TYPE] = ctrl; |
414 | status = acpi_pci_run_osc(handle, capbuf, &result); | 437 | status = acpi_pci_run_osc(handle, capbuf, mask); |
415 | if (ACPI_SUCCESS(status)) | 438 | if (ACPI_SUCCESS(status)) |
416 | root->osc_control_set = result; | 439 | root->osc_control_set = *mask; |
417 | out: | 440 | out: |
418 | mutex_unlock(&osc_lock); | 441 | mutex_unlock(&osc_lock); |
419 | return status; | 442 | return status; |
@@ -544,14 +567,6 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
544 | if (flags != base_flags) | 567 | if (flags != base_flags) |
545 | acpi_pci_osc_support(root, flags); | 568 | acpi_pci_osc_support(root, flags); |
546 | 569 | ||
547 | status = acpi_pci_osc_control_set(root->device->handle, | ||
548 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); | ||
549 | |||
550 | if (ACPI_FAILURE(status)) { | ||
551 | printk(KERN_INFO "Unable to assume PCIe control: Disabling ASPM\n"); | ||
552 | pcie_no_aspm(); | ||
553 | } | ||
554 | |||
555 | pci_acpi_add_bus_pm_notifier(device, root->bus); | 570 | pci_acpi_add_bus_pm_notifier(device, root->bus); |
556 | if (device->wakeup.flags.run_wake) | 571 | if (device->wakeup.flags.run_wake) |
557 | device_set_run_wake(root->bus->bridge, true); | 572 | device_set_run_wake(root->bus->bridge, true); |
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index e9699aaed10..bec561c14be 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -29,12 +29,6 @@ static int set_no_mwait(const struct dmi_system_id *id) | |||
29 | 29 | ||
30 | static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = { | 30 | static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = { |
31 | { | 31 | { |
32 | set_no_mwait, "IFL91 board", { | ||
33 | DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"), | ||
34 | DMI_MATCH(DMI_SYS_VENDOR, "ZEPTO"), | ||
35 | DMI_MATCH(DMI_PRODUCT_VERSION, "3215W"), | ||
36 | DMI_MATCH(DMI_BOARD_NAME, "IFL91") }, NULL}, | ||
37 | { | ||
38 | set_no_mwait, "Extensa 5220", { | 32 | set_no_mwait, "Extensa 5220", { |
39 | DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), | 33 | DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), |
40 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 34 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
@@ -352,4 +346,5 @@ void __init acpi_early_processor_set_pdc(void) | |||
352 | acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, | 346 | acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, |
353 | ACPI_UINT32_MAX, | 347 | ACPI_UINT32_MAX, |
354 | early_init_pdc, NULL, NULL, NULL); | 348 | early_init_pdc, NULL, NULL, NULL); |
349 | acpi_get_devices("ACPI0007", early_init_pdc, NULL, NULL); | ||
355 | } | 350 | } |
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 15602189238..347eb21b235 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c | |||
@@ -850,7 +850,7 @@ static int __init acpi_processor_init(void) | |||
850 | printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n", | 850 | printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n", |
851 | acpi_idle_driver.name); | 851 | acpi_idle_driver.name); |
852 | } else { | 852 | } else { |
853 | printk(KERN_DEBUG "ACPI: acpi_idle yielding to %s", | 853 | printk(KERN_DEBUG "ACPI: acpi_idle yielding to %s\n", |
854 | cpuidle_get_driver()->name); | 854 | cpuidle_get_driver()->name); |
855 | } | 855 | } |
856 | 856 | ||
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index ba1bd263d90..3a73a93596e 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c | |||
@@ -447,8 +447,8 @@ int acpi_processor_notify_smm(struct module *calling_module) | |||
447 | if (!try_module_get(calling_module)) | 447 | if (!try_module_get(calling_module)) |
448 | return -EINVAL; | 448 | return -EINVAL; |
449 | 449 | ||
450 | /* is_done is set to negative if an error occured, | 450 | /* is_done is set to negative if an error occurred, |
451 | * and to postitive if _no_ error occured, but SMM | 451 | * and to postitive if _no_ error occurred, but SMM |
452 | * was already notified. This avoids double notification | 452 | * was already notified. This avoids double notification |
453 | * which might lead to unexpected results... | 453 | * which might lead to unexpected results... |
454 | */ | 454 | */ |
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index cf82989ae75..4754ff6e70e 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -363,6 +363,12 @@ static int __init init_old_suspend_ordering(const struct dmi_system_id *d) | |||
363 | return 0; | 363 | return 0; |
364 | } | 364 | } |
365 | 365 | ||
366 | static int __init init_nvs_nosave(const struct dmi_system_id *d) | ||
367 | { | ||
368 | acpi_nvs_nosave(); | ||
369 | return 0; | ||
370 | } | ||
371 | |||
366 | static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | 372 | static struct dmi_system_id __initdata acpisleep_dmi_table[] = { |
367 | { | 373 | { |
368 | .callback = init_old_suspend_ordering, | 374 | .callback = init_old_suspend_ordering, |
@@ -397,6 +403,22 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | |||
397 | DMI_MATCH(DMI_BOARD_NAME, "CF51-2L"), | 403 | DMI_MATCH(DMI_BOARD_NAME, "CF51-2L"), |
398 | }, | 404 | }, |
399 | }, | 405 | }, |
406 | { | ||
407 | .callback = init_nvs_nosave, | ||
408 | .ident = "Sony Vaio VGN-SR11M", | ||
409 | .matches = { | ||
410 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
411 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR11M"), | ||
412 | }, | ||
413 | }, | ||
414 | { | ||
415 | .callback = init_nvs_nosave, | ||
416 | .ident = "Everex StepNote Series", | ||
417 | .matches = { | ||
418 | DMI_MATCH(DMI_SYS_VENDOR, "Everex Systems, Inc."), | ||
419 | DMI_MATCH(DMI_PRODUCT_NAME, "Everex StepNote Series"), | ||
420 | }, | ||
421 | }, | ||
400 | {}, | 422 | {}, |
401 | }; | 423 | }; |
402 | #endif /* CONFIG_SUSPEND */ | 424 | #endif /* CONFIG_SUSPEND */ |
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 68e2e4582fa..f8588f81048 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c | |||
@@ -100,7 +100,7 @@ static const struct acpi_dlevel acpi_debug_levels[] = { | |||
100 | ACPI_DEBUG_INIT(ACPI_LV_EVENTS), | 100 | ACPI_DEBUG_INIT(ACPI_LV_EVENTS), |
101 | }; | 101 | }; |
102 | 102 | ||
103 | static int param_get_debug_layer(char *buffer, struct kernel_param *kp) | 103 | static int param_get_debug_layer(char *buffer, const struct kernel_param *kp) |
104 | { | 104 | { |
105 | int result = 0; | 105 | int result = 0; |
106 | int i; | 106 | int i; |
@@ -128,7 +128,7 @@ static int param_get_debug_layer(char *buffer, struct kernel_param *kp) | |||
128 | return result; | 128 | return result; |
129 | } | 129 | } |
130 | 130 | ||
131 | static int param_get_debug_level(char *buffer, struct kernel_param *kp) | 131 | static int param_get_debug_level(char *buffer, const struct kernel_param *kp) |
132 | { | 132 | { |
133 | int result = 0; | 133 | int result = 0; |
134 | int i; | 134 | int i; |
@@ -149,10 +149,18 @@ static int param_get_debug_level(char *buffer, struct kernel_param *kp) | |||
149 | return result; | 149 | return result; |
150 | } | 150 | } |
151 | 151 | ||
152 | module_param_call(debug_layer, param_set_uint, param_get_debug_layer, | 152 | static struct kernel_param_ops param_ops_debug_layer = { |
153 | &acpi_dbg_layer, 0644); | 153 | .set = param_set_uint, |
154 | module_param_call(debug_level, param_set_uint, param_get_debug_level, | 154 | .get = param_get_debug_layer, |
155 | &acpi_dbg_level, 0644); | 155 | }; |
156 | |||
157 | static struct kernel_param_ops param_ops_debug_level = { | ||
158 | .set = param_set_uint, | ||
159 | .get = param_get_debug_level, | ||
160 | }; | ||
161 | |||
162 | module_param_cb(debug_layer, ¶m_ops_debug_layer, &acpi_dbg_layer, 0644); | ||
163 | module_param_cb(debug_level, ¶m_ops_debug_level, &acpi_dbg_level, 0644); | ||
156 | 164 | ||
157 | static char trace_method_name[6]; | 165 | static char trace_method_name[6]; |
158 | module_param_string(trace_method_name, trace_method_name, 6, 0644); | 166 | module_param_string(trace_method_name, trace_method_name, 6, 0644); |
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index c5fef01b3c9..b8367612659 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c | |||
@@ -59,8 +59,8 @@ acpi_backlight_cap_match(acpi_handle handle, u32 level, void *context, | |||
59 | "support\n")); | 59 | "support\n")); |
60 | *cap |= ACPI_VIDEO_BACKLIGHT; | 60 | *cap |= ACPI_VIDEO_BACKLIGHT; |
61 | if (ACPI_FAILURE(acpi_get_handle(handle, "_BQC", &h_dummy))) | 61 | if (ACPI_FAILURE(acpi_get_handle(handle, "_BQC", &h_dummy))) |
62 | printk(KERN_WARNING FW_BUG PREFIX "ACPI brightness " | 62 | printk(KERN_WARNING FW_BUG PREFIX "No _BQC method, " |
63 | "control misses _BQC function\n"); | 63 | "cannot determine initial brightness\n"); |
64 | /* We have backlight support, no need to scan further */ | 64 | /* We have backlight support, no need to scan further */ |
65 | return AE_CTRL_TERMINATE; | 65 | return AE_CTRL_TERMINATE; |
66 | } | 66 | } |
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 65e3e270837..11ec911016c 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig | |||
@@ -828,6 +828,7 @@ config PATA_SAMSUNG_CF | |||
828 | config PATA_WINBOND_VLB | 828 | config PATA_WINBOND_VLB |
829 | tristate "Winbond W83759A VLB PATA support (Experimental)" | 829 | tristate "Winbond W83759A VLB PATA support (Experimental)" |
830 | depends on ISA && EXPERIMENTAL | 830 | depends on ISA && EXPERIMENTAL |
831 | select PATA_LEGACY | ||
831 | help | 832 | help |
832 | Support for the Winbond W83759A controller on Vesa Local Bus | 833 | Support for the Winbond W83759A controller on Vesa Local Bus |
833 | systems. | 834 | systems. |
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index 158eaa961b1..d5df04a395c 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile | |||
@@ -89,7 +89,6 @@ obj-$(CONFIG_PATA_QDI) += pata_qdi.o | |||
89 | obj-$(CONFIG_PATA_RB532) += pata_rb532_cf.o | 89 | obj-$(CONFIG_PATA_RB532) += pata_rb532_cf.o |
90 | obj-$(CONFIG_PATA_RZ1000) += pata_rz1000.o | 90 | obj-$(CONFIG_PATA_RZ1000) += pata_rz1000.o |
91 | obj-$(CONFIG_PATA_SAMSUNG_CF) += pata_samsung_cf.o | 91 | obj-$(CONFIG_PATA_SAMSUNG_CF) += pata_samsung_cf.o |
92 | obj-$(CONFIG_PATA_WINBOND_VLB) += pata_winbond.o | ||
93 | 92 | ||
94 | obj-$(CONFIG_PATA_PXA) += pata_pxa.o | 93 | obj-$(CONFIG_PATA_PXA) += pata_pxa.o |
95 | 94 | ||
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index fe75d8befc3..99d0e5a5114 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -60,6 +60,7 @@ enum board_ids { | |||
60 | board_ahci, | 60 | board_ahci, |
61 | board_ahci_ign_iferr, | 61 | board_ahci_ign_iferr, |
62 | board_ahci_nosntf, | 62 | board_ahci_nosntf, |
63 | board_ahci_yes_fbs, | ||
63 | 64 | ||
64 | /* board IDs for specific chipsets in alphabetical order */ | 65 | /* board IDs for specific chipsets in alphabetical order */ |
65 | board_ahci_mcp65, | 66 | board_ahci_mcp65, |
@@ -89,6 +90,10 @@ static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); | |||
89 | static int ahci_pci_device_resume(struct pci_dev *pdev); | 90 | static int ahci_pci_device_resume(struct pci_dev *pdev); |
90 | #endif | 91 | #endif |
91 | 92 | ||
93 | static struct scsi_host_template ahci_sht = { | ||
94 | AHCI_SHT("ahci"), | ||
95 | }; | ||
96 | |||
92 | static struct ata_port_operations ahci_vt8251_ops = { | 97 | static struct ata_port_operations ahci_vt8251_ops = { |
93 | .inherits = &ahci_ops, | 98 | .inherits = &ahci_ops, |
94 | .hardreset = ahci_vt8251_hardreset, | 99 | .hardreset = ahci_vt8251_hardreset, |
@@ -132,6 +137,14 @@ static const struct ata_port_info ahci_port_info[] = { | |||
132 | .udma_mask = ATA_UDMA6, | 137 | .udma_mask = ATA_UDMA6, |
133 | .port_ops = &ahci_ops, | 138 | .port_ops = &ahci_ops, |
134 | }, | 139 | }, |
140 | [board_ahci_yes_fbs] = | ||
141 | { | ||
142 | AHCI_HFLAGS (AHCI_HFLAG_YES_FBS), | ||
143 | .flags = AHCI_FLAG_COMMON, | ||
144 | .pio_mask = ATA_PIO4, | ||
145 | .udma_mask = ATA_UDMA6, | ||
146 | .port_ops = &ahci_ops, | ||
147 | }, | ||
135 | /* by chipsets */ | 148 | /* by chipsets */ |
136 | [board_ahci_mcp65] = | 149 | [board_ahci_mcp65] = |
137 | { | 150 | { |
@@ -244,6 +257,9 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
244 | { PCI_VDEVICE(INTEL, 0x1c05), board_ahci }, /* CPT RAID */ | 257 | { PCI_VDEVICE(INTEL, 0x1c05), board_ahci }, /* CPT RAID */ |
245 | { PCI_VDEVICE(INTEL, 0x1c06), board_ahci }, /* CPT RAID */ | 258 | { PCI_VDEVICE(INTEL, 0x1c06), board_ahci }, /* CPT RAID */ |
246 | { PCI_VDEVICE(INTEL, 0x1c07), board_ahci }, /* CPT RAID */ | 259 | { PCI_VDEVICE(INTEL, 0x1c07), board_ahci }, /* CPT RAID */ |
260 | { PCI_VDEVICE(INTEL, 0x1d02), board_ahci }, /* PBG AHCI */ | ||
261 | { PCI_VDEVICE(INTEL, 0x1d04), board_ahci }, /* PBG RAID */ | ||
262 | { PCI_VDEVICE(INTEL, 0x1d06), board_ahci }, /* PBG RAID */ | ||
247 | 263 | ||
248 | /* JMicron 360/1/3/5/6, match class to avoid IDE function */ | 264 | /* JMicron 360/1/3/5/6, match class to avoid IDE function */ |
249 | { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | 265 | { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, |
@@ -362,6 +378,8 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
362 | /* Marvell */ | 378 | /* Marvell */ |
363 | { PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv }, /* 6145 */ | 379 | { PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv }, /* 6145 */ |
364 | { PCI_VDEVICE(MARVELL, 0x6121), board_ahci_mv }, /* 6121 */ | 380 | { PCI_VDEVICE(MARVELL, 0x6121), board_ahci_mv }, /* 6121 */ |
381 | { PCI_DEVICE(0x1b4b, 0x9123), | ||
382 | .driver_data = board_ahci_yes_fbs }, /* 88se9128 */ | ||
365 | 383 | ||
366 | /* Promise */ | 384 | /* Promise */ |
367 | { PCI_VDEVICE(PROMISE, 0x3f20), board_ahci }, /* PDC42819 */ | 385 | { PCI_VDEVICE(PROMISE, 0x3f20), board_ahci }, /* PDC42819 */ |
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index 7113c572447..e5fdeebf9ef 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h | |||
@@ -209,6 +209,7 @@ enum { | |||
209 | link offline */ | 209 | link offline */ |
210 | AHCI_HFLAG_NO_SNTF = (1 << 12), /* no sntf */ | 210 | AHCI_HFLAG_NO_SNTF = (1 << 12), /* no sntf */ |
211 | AHCI_HFLAG_NO_FPDMA_AA = (1 << 13), /* no FPDMA AA */ | 211 | AHCI_HFLAG_NO_FPDMA_AA = (1 << 13), /* no FPDMA AA */ |
212 | AHCI_HFLAG_YES_FBS = (1 << 14), /* force FBS cap on */ | ||
212 | 213 | ||
213 | /* ap->flags bits */ | 214 | /* ap->flags bits */ |
214 | 215 | ||
@@ -297,7 +298,17 @@ struct ahci_host_priv { | |||
297 | 298 | ||
298 | extern int ahci_ignore_sss; | 299 | extern int ahci_ignore_sss; |
299 | 300 | ||
300 | extern struct scsi_host_template ahci_sht; | 301 | extern struct device_attribute *ahci_shost_attrs[]; |
302 | extern struct device_attribute *ahci_sdev_attrs[]; | ||
303 | |||
304 | #define AHCI_SHT(drv_name) \ | ||
305 | ATA_NCQ_SHT(drv_name), \ | ||
306 | .can_queue = AHCI_MAX_CMDS - 1, \ | ||
307 | .sg_tablesize = AHCI_MAX_SG, \ | ||
308 | .dma_boundary = AHCI_DMA_BOUNDARY, \ | ||
309 | .shost_attrs = ahci_shost_attrs, \ | ||
310 | .sdev_attrs = ahci_sdev_attrs | ||
311 | |||
301 | extern struct ata_port_operations ahci_ops; | 312 | extern struct ata_port_operations ahci_ops; |
302 | 313 | ||
303 | void ahci_save_initial_config(struct device *dev, | 314 | void ahci_save_initial_config(struct device *dev, |
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index 4e97f33cca4..84b643270e7 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c | |||
@@ -23,6 +23,10 @@ | |||
23 | #include <linux/ahci_platform.h> | 23 | #include <linux/ahci_platform.h> |
24 | #include "ahci.h" | 24 | #include "ahci.h" |
25 | 25 | ||
26 | static struct scsi_host_template ahci_platform_sht = { | ||
27 | AHCI_SHT("ahci_platform"), | ||
28 | }; | ||
29 | |||
26 | static int __init ahci_probe(struct platform_device *pdev) | 30 | static int __init ahci_probe(struct platform_device *pdev) |
27 | { | 31 | { |
28 | struct device *dev = &pdev->dev; | 32 | struct device *dev = &pdev->dev; |
@@ -145,7 +149,7 @@ static int __init ahci_probe(struct platform_device *pdev) | |||
145 | ahci_print_info(host, "platform"); | 149 | ahci_print_info(host, "platform"); |
146 | 150 | ||
147 | rc = ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED, | 151 | rc = ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED, |
148 | &ahci_sht); | 152 | &ahci_platform_sht); |
149 | if (rc) | 153 | if (rc) |
150 | goto err0; | 154 | goto err0; |
151 | 155 | ||
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 3971bc0a483..d712675d0a9 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c | |||
@@ -302,6 +302,10 @@ static const struct pci_device_id piix_pci_tbl[] = { | |||
302 | { 0x8086, 0x1c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, | 302 | { 0x8086, 0x1c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, |
303 | /* SATA Controller IDE (CPT) */ | 303 | /* SATA Controller IDE (CPT) */ |
304 | { 0x8086, 0x1c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, | 304 | { 0x8086, 0x1c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, |
305 | /* SATA Controller IDE (PBG) */ | ||
306 | { 0x8086, 0x1d00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, | ||
307 | /* SATA Controller IDE (PBG) */ | ||
308 | { 0x8086, 0x1d08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, | ||
305 | { } /* terminate list */ | 309 | { } /* terminate list */ |
306 | }; | 310 | }; |
307 | 311 | ||
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 81e772a94d5..8eea309ea21 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c | |||
@@ -121,7 +121,7 @@ static DEVICE_ATTR(ahci_port_cmd, S_IRUGO, ahci_show_port_cmd, NULL); | |||
121 | static DEVICE_ATTR(em_buffer, S_IWUSR | S_IRUGO, | 121 | static DEVICE_ATTR(em_buffer, S_IWUSR | S_IRUGO, |
122 | ahci_read_em_buffer, ahci_store_em_buffer); | 122 | ahci_read_em_buffer, ahci_store_em_buffer); |
123 | 123 | ||
124 | static struct device_attribute *ahci_shost_attrs[] = { | 124 | struct device_attribute *ahci_shost_attrs[] = { |
125 | &dev_attr_link_power_management_policy, | 125 | &dev_attr_link_power_management_policy, |
126 | &dev_attr_em_message_type, | 126 | &dev_attr_em_message_type, |
127 | &dev_attr_em_message, | 127 | &dev_attr_em_message, |
@@ -132,22 +132,14 @@ static struct device_attribute *ahci_shost_attrs[] = { | |||
132 | &dev_attr_em_buffer, | 132 | &dev_attr_em_buffer, |
133 | NULL | 133 | NULL |
134 | }; | 134 | }; |
135 | EXPORT_SYMBOL_GPL(ahci_shost_attrs); | ||
135 | 136 | ||
136 | static struct device_attribute *ahci_sdev_attrs[] = { | 137 | struct device_attribute *ahci_sdev_attrs[] = { |
137 | &dev_attr_sw_activity, | 138 | &dev_attr_sw_activity, |
138 | &dev_attr_unload_heads, | 139 | &dev_attr_unload_heads, |
139 | NULL | 140 | NULL |
140 | }; | 141 | }; |
141 | 142 | EXPORT_SYMBOL_GPL(ahci_sdev_attrs); | |
142 | struct scsi_host_template ahci_sht = { | ||
143 | ATA_NCQ_SHT("ahci"), | ||
144 | .can_queue = AHCI_MAX_CMDS - 1, | ||
145 | .sg_tablesize = AHCI_MAX_SG, | ||
146 | .dma_boundary = AHCI_DMA_BOUNDARY, | ||
147 | .shost_attrs = ahci_shost_attrs, | ||
148 | .sdev_attrs = ahci_sdev_attrs, | ||
149 | }; | ||
150 | EXPORT_SYMBOL_GPL(ahci_sht); | ||
151 | 143 | ||
152 | struct ata_port_operations ahci_ops = { | 144 | struct ata_port_operations ahci_ops = { |
153 | .inherits = &sata_pmp_port_ops, | 145 | .inherits = &sata_pmp_port_ops, |
@@ -430,6 +422,12 @@ void ahci_save_initial_config(struct device *dev, | |||
430 | cap &= ~HOST_CAP_SNTF; | 422 | cap &= ~HOST_CAP_SNTF; |
431 | } | 423 | } |
432 | 424 | ||
425 | if (!(cap & HOST_CAP_FBS) && (hpriv->flags & AHCI_HFLAG_YES_FBS)) { | ||
426 | dev_printk(KERN_INFO, dev, | ||
427 | "controller can do FBS, turning on CAP_FBS\n"); | ||
428 | cap |= HOST_CAP_FBS; | ||
429 | } | ||
430 | |||
433 | if (force_port_map && port_map != force_port_map) { | 431 | if (force_port_map && port_map != force_port_map) { |
434 | dev_printk(KERN_INFO, dev, "forcing port_map 0x%x -> 0x%x\n", | 432 | dev_printk(KERN_INFO, dev, "forcing port_map 0x%x -> 0x%x\n", |
435 | port_map, force_port_map); | 433 | port_map, force_port_map); |
@@ -1320,7 +1318,7 @@ int ahci_do_softreset(struct ata_link *link, unsigned int *class, | |||
1320 | /* issue the first D2H Register FIS */ | 1318 | /* issue the first D2H Register FIS */ |
1321 | msecs = 0; | 1319 | msecs = 0; |
1322 | now = jiffies; | 1320 | now = jiffies; |
1323 | if (time_after(now, deadline)) | 1321 | if (time_after(deadline, now)) |
1324 | msecs = jiffies_to_msecs(deadline - now); | 1322 | msecs = jiffies_to_msecs(deadline - now); |
1325 | 1323 | ||
1326 | tf.ctl |= ATA_SRST; | 1324 | tf.ctl |= ATA_SRST; |
@@ -2036,9 +2034,15 @@ static int ahci_port_start(struct ata_port *ap) | |||
2036 | u32 cmd = readl(port_mmio + PORT_CMD); | 2034 | u32 cmd = readl(port_mmio + PORT_CMD); |
2037 | if (cmd & PORT_CMD_FBSCP) | 2035 | if (cmd & PORT_CMD_FBSCP) |
2038 | pp->fbs_supported = true; | 2036 | pp->fbs_supported = true; |
2039 | else | 2037 | else if (hpriv->flags & AHCI_HFLAG_YES_FBS) { |
2038 | dev_printk(KERN_INFO, dev, | ||
2039 | "port %d can do FBS, forcing FBSCP\n", | ||
2040 | ap->port_no); | ||
2041 | pp->fbs_supported = true; | ||
2042 | } else | ||
2040 | dev_printk(KERN_WARNING, dev, | 2043 | dev_printk(KERN_WARNING, dev, |
2041 | "The port is not capable of FBS\n"); | 2044 | "port %d is not capable of FBS\n", |
2045 | ap->port_no); | ||
2042 | } | 2046 | } |
2043 | 2047 | ||
2044 | if (pp->fbs_supported) { | 2048 | if (pp->fbs_supported) { |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 7ef7c4f216f..932eaee5024 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -5111,15 +5111,18 @@ void ata_qc_issue(struct ata_queued_cmd *qc) | |||
5111 | qc->flags |= ATA_QCFLAG_ACTIVE; | 5111 | qc->flags |= ATA_QCFLAG_ACTIVE; |
5112 | ap->qc_active |= 1 << qc->tag; | 5112 | ap->qc_active |= 1 << qc->tag; |
5113 | 5113 | ||
5114 | /* We guarantee to LLDs that they will have at least one | 5114 | /* |
5115 | * We guarantee to LLDs that they will have at least one | ||
5115 | * non-zero sg if the command is a data command. | 5116 | * non-zero sg if the command is a data command. |
5116 | */ | 5117 | */ |
5117 | BUG_ON(ata_is_data(prot) && (!qc->sg || !qc->n_elem || !qc->nbytes)); | 5118 | if (WARN_ON_ONCE(ata_is_data(prot) && |
5119 | (!qc->sg || !qc->n_elem || !qc->nbytes))) | ||
5120 | goto sys_err; | ||
5118 | 5121 | ||
5119 | if (ata_is_dma(prot) || (ata_is_pio(prot) && | 5122 | if (ata_is_dma(prot) || (ata_is_pio(prot) && |
5120 | (ap->flags & ATA_FLAG_PIO_DMA))) | 5123 | (ap->flags & ATA_FLAG_PIO_DMA))) |
5121 | if (ata_sg_setup(qc)) | 5124 | if (ata_sg_setup(qc)) |
5122 | goto sg_err; | 5125 | goto sys_err; |
5123 | 5126 | ||
5124 | /* if device is sleeping, schedule reset and abort the link */ | 5127 | /* if device is sleeping, schedule reset and abort the link */ |
5125 | if (unlikely(qc->dev->flags & ATA_DFLAG_SLEEPING)) { | 5128 | if (unlikely(qc->dev->flags & ATA_DFLAG_SLEEPING)) { |
@@ -5136,7 +5139,7 @@ void ata_qc_issue(struct ata_queued_cmd *qc) | |||
5136 | goto err; | 5139 | goto err; |
5137 | return; | 5140 | return; |
5138 | 5141 | ||
5139 | sg_err: | 5142 | sys_err: |
5140 | qc->err_mask |= AC_ERR_SYSTEM; | 5143 | qc->err_mask |= AC_ERR_SYSTEM; |
5141 | err: | 5144 | err: |
5142 | ata_qc_complete(qc); | 5145 | ata_qc_complete(qc); |
@@ -5415,6 +5418,7 @@ static int ata_host_request_pm(struct ata_host *host, pm_message_t mesg, | |||
5415 | */ | 5418 | */ |
5416 | int ata_host_suspend(struct ata_host *host, pm_message_t mesg) | 5419 | int ata_host_suspend(struct ata_host *host, pm_message_t mesg) |
5417 | { | 5420 | { |
5421 | unsigned int ehi_flags = ATA_EHI_QUIET; | ||
5418 | int rc; | 5422 | int rc; |
5419 | 5423 | ||
5420 | /* | 5424 | /* |
@@ -5423,7 +5427,18 @@ int ata_host_suspend(struct ata_host *host, pm_message_t mesg) | |||
5423 | */ | 5427 | */ |
5424 | ata_lpm_enable(host); | 5428 | ata_lpm_enable(host); |
5425 | 5429 | ||
5426 | rc = ata_host_request_pm(host, mesg, 0, ATA_EHI_QUIET, 1); | 5430 | /* |
5431 | * On some hardware, device fails to respond after spun down | ||
5432 | * for suspend. As the device won't be used before being | ||
5433 | * resumed, we don't need to touch the device. Ask EH to skip | ||
5434 | * the usual stuff and proceed directly to suspend. | ||
5435 | * | ||
5436 | * http://thread.gmane.org/gmane.linux.ide/46764 | ||
5437 | */ | ||
5438 | if (mesg.event == PM_EVENT_SUSPEND) | ||
5439 | ehi_flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_NO_RECOVERY; | ||
5440 | |||
5441 | rc = ata_host_request_pm(host, mesg, 0, ehi_flags, 1); | ||
5427 | if (rc == 0) | 5442 | if (rc == 0) |
5428 | host->dev->power.power_state = mesg; | 5443 | host->dev->power.power_state = mesg; |
5429 | return rc; | 5444 | return rc; |
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index c9ae299b834..e48302eae55 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
@@ -3235,6 +3235,10 @@ static int ata_eh_skip_recovery(struct ata_link *link) | |||
3235 | if (link->flags & ATA_LFLAG_DISABLED) | 3235 | if (link->flags & ATA_LFLAG_DISABLED) |
3236 | return 1; | 3236 | return 1; |
3237 | 3237 | ||
3238 | /* skip if explicitly requested */ | ||
3239 | if (ehc->i.flags & ATA_EHI_NO_RECOVERY) | ||
3240 | return 1; | ||
3241 | |||
3238 | /* thaw frozen port and recover failed devices */ | 3242 | /* thaw frozen port and recover failed devices */ |
3239 | if ((ap->pflags & ATA_PFLAG_FROZEN) || ata_link_nr_enabled(link)) | 3243 | if ((ap->pflags & ATA_PFLAG_FROZEN) || ata_link_nr_enabled(link)) |
3240 | return 0; | 3244 | return 0; |
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 674c1436491..e30c537cce3 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
@@ -418,6 +418,7 @@ void ata_sff_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) | |||
418 | if (ioaddr->ctl_addr) | 418 | if (ioaddr->ctl_addr) |
419 | iowrite8(tf->ctl, ioaddr->ctl_addr); | 419 | iowrite8(tf->ctl, ioaddr->ctl_addr); |
420 | ap->last_ctl = tf->ctl; | 420 | ap->last_ctl = tf->ctl; |
421 | ata_wait_idle(ap); | ||
421 | } | 422 | } |
422 | 423 | ||
423 | if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { | 424 | if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { |
@@ -453,6 +454,8 @@ void ata_sff_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) | |||
453 | iowrite8(tf->device, ioaddr->device_addr); | 454 | iowrite8(tf->device, ioaddr->device_addr); |
454 | VPRINTK("device 0x%X\n", tf->device); | 455 | VPRINTK("device 0x%X\n", tf->device); |
455 | } | 456 | } |
457 | |||
458 | ata_wait_idle(ap); | ||
456 | } | 459 | } |
457 | EXPORT_SYMBOL_GPL(ata_sff_tf_load); | 460 | EXPORT_SYMBOL_GPL(ata_sff_tf_load); |
458 | 461 | ||
@@ -1042,7 +1045,8 @@ static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq) | |||
1042 | int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc, | 1045 | int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc, |
1043 | u8 status, int in_wq) | 1046 | u8 status, int in_wq) |
1044 | { | 1047 | { |
1045 | struct ata_eh_info *ehi = &ap->link.eh_info; | 1048 | struct ata_link *link = qc->dev->link; |
1049 | struct ata_eh_info *ehi = &link->eh_info; | ||
1046 | unsigned long flags = 0; | 1050 | unsigned long flags = 0; |
1047 | int poll_next; | 1051 | int poll_next; |
1048 | 1052 | ||
@@ -1298,8 +1302,14 @@ fsm_start: | |||
1298 | } | 1302 | } |
1299 | EXPORT_SYMBOL_GPL(ata_sff_hsm_move); | 1303 | EXPORT_SYMBOL_GPL(ata_sff_hsm_move); |
1300 | 1304 | ||
1301 | void ata_sff_queue_pio_task(struct ata_port *ap, unsigned long delay) | 1305 | void ata_sff_queue_pio_task(struct ata_link *link, unsigned long delay) |
1302 | { | 1306 | { |
1307 | struct ata_port *ap = link->ap; | ||
1308 | |||
1309 | WARN_ON((ap->sff_pio_task_link != NULL) && | ||
1310 | (ap->sff_pio_task_link != link)); | ||
1311 | ap->sff_pio_task_link = link; | ||
1312 | |||
1303 | /* may fail if ata_sff_flush_pio_task() in progress */ | 1313 | /* may fail if ata_sff_flush_pio_task() in progress */ |
1304 | queue_delayed_work(ata_sff_wq, &ap->sff_pio_task, | 1314 | queue_delayed_work(ata_sff_wq, &ap->sff_pio_task, |
1305 | msecs_to_jiffies(delay)); | 1315 | msecs_to_jiffies(delay)); |
@@ -1321,14 +1331,18 @@ static void ata_sff_pio_task(struct work_struct *work) | |||
1321 | { | 1331 | { |
1322 | struct ata_port *ap = | 1332 | struct ata_port *ap = |
1323 | container_of(work, struct ata_port, sff_pio_task.work); | 1333 | container_of(work, struct ata_port, sff_pio_task.work); |
1334 | struct ata_link *link = ap->sff_pio_task_link; | ||
1324 | struct ata_queued_cmd *qc; | 1335 | struct ata_queued_cmd *qc; |
1325 | u8 status; | 1336 | u8 status; |
1326 | int poll_next; | 1337 | int poll_next; |
1327 | 1338 | ||
1339 | BUG_ON(ap->sff_pio_task_link == NULL); | ||
1328 | /* qc can be NULL if timeout occurred */ | 1340 | /* qc can be NULL if timeout occurred */ |
1329 | qc = ata_qc_from_tag(ap, ap->link.active_tag); | 1341 | qc = ata_qc_from_tag(ap, link->active_tag); |
1330 | if (!qc) | 1342 | if (!qc) { |
1343 | ap->sff_pio_task_link = NULL; | ||
1331 | return; | 1344 | return; |
1345 | } | ||
1332 | 1346 | ||
1333 | fsm_start: | 1347 | fsm_start: |
1334 | WARN_ON_ONCE(ap->hsm_task_state == HSM_ST_IDLE); | 1348 | WARN_ON_ONCE(ap->hsm_task_state == HSM_ST_IDLE); |
@@ -1345,11 +1359,16 @@ fsm_start: | |||
1345 | msleep(2); | 1359 | msleep(2); |
1346 | status = ata_sff_busy_wait(ap, ATA_BUSY, 10); | 1360 | status = ata_sff_busy_wait(ap, ATA_BUSY, 10); |
1347 | if (status & ATA_BUSY) { | 1361 | if (status & ATA_BUSY) { |
1348 | ata_sff_queue_pio_task(ap, ATA_SHORT_PAUSE); | 1362 | ata_sff_queue_pio_task(link, ATA_SHORT_PAUSE); |
1349 | return; | 1363 | return; |
1350 | } | 1364 | } |
1351 | } | 1365 | } |
1352 | 1366 | ||
1367 | /* | ||
1368 | * hsm_move() may trigger another command to be processed. | ||
1369 | * clean the link beforehand. | ||
1370 | */ | ||
1371 | ap->sff_pio_task_link = NULL; | ||
1353 | /* move the HSM */ | 1372 | /* move the HSM */ |
1354 | poll_next = ata_sff_hsm_move(ap, qc, status, 1); | 1373 | poll_next = ata_sff_hsm_move(ap, qc, status, 1); |
1355 | 1374 | ||
@@ -1376,6 +1395,7 @@ fsm_start: | |||
1376 | unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc) | 1395 | unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc) |
1377 | { | 1396 | { |
1378 | struct ata_port *ap = qc->ap; | 1397 | struct ata_port *ap = qc->ap; |
1398 | struct ata_link *link = qc->dev->link; | ||
1379 | 1399 | ||
1380 | /* Use polling pio if the LLD doesn't handle | 1400 | /* Use polling pio if the LLD doesn't handle |
1381 | * interrupt driven pio and atapi CDB interrupt. | 1401 | * interrupt driven pio and atapi CDB interrupt. |
@@ -1396,7 +1416,7 @@ unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc) | |||
1396 | ap->hsm_task_state = HSM_ST_LAST; | 1416 | ap->hsm_task_state = HSM_ST_LAST; |
1397 | 1417 | ||
1398 | if (qc->tf.flags & ATA_TFLAG_POLLING) | 1418 | if (qc->tf.flags & ATA_TFLAG_POLLING) |
1399 | ata_sff_queue_pio_task(ap, 0); | 1419 | ata_sff_queue_pio_task(link, 0); |
1400 | 1420 | ||
1401 | break; | 1421 | break; |
1402 | 1422 | ||
@@ -1409,7 +1429,7 @@ unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc) | |||
1409 | if (qc->tf.flags & ATA_TFLAG_WRITE) { | 1429 | if (qc->tf.flags & ATA_TFLAG_WRITE) { |
1410 | /* PIO data out protocol */ | 1430 | /* PIO data out protocol */ |
1411 | ap->hsm_task_state = HSM_ST_FIRST; | 1431 | ap->hsm_task_state = HSM_ST_FIRST; |
1412 | ata_sff_queue_pio_task(ap, 0); | 1432 | ata_sff_queue_pio_task(link, 0); |
1413 | 1433 | ||
1414 | /* always send first data block using the | 1434 | /* always send first data block using the |
1415 | * ata_sff_pio_task() codepath. | 1435 | * ata_sff_pio_task() codepath. |
@@ -1419,7 +1439,7 @@ unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc) | |||
1419 | ap->hsm_task_state = HSM_ST; | 1439 | ap->hsm_task_state = HSM_ST; |
1420 | 1440 | ||
1421 | if (qc->tf.flags & ATA_TFLAG_POLLING) | 1441 | if (qc->tf.flags & ATA_TFLAG_POLLING) |
1422 | ata_sff_queue_pio_task(ap, 0); | 1442 | ata_sff_queue_pio_task(link, 0); |
1423 | 1443 | ||
1424 | /* if polling, ata_sff_pio_task() handles the | 1444 | /* if polling, ata_sff_pio_task() handles the |
1425 | * rest. otherwise, interrupt handler takes | 1445 | * rest. otherwise, interrupt handler takes |
@@ -1441,7 +1461,7 @@ unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc) | |||
1441 | /* send cdb by polling if no cdb interrupt */ | 1461 | /* send cdb by polling if no cdb interrupt */ |
1442 | if ((!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) || | 1462 | if ((!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) || |
1443 | (qc->tf.flags & ATA_TFLAG_POLLING)) | 1463 | (qc->tf.flags & ATA_TFLAG_POLLING)) |
1444 | ata_sff_queue_pio_task(ap, 0); | 1464 | ata_sff_queue_pio_task(link, 0); |
1445 | break; | 1465 | break; |
1446 | 1466 | ||
1447 | default: | 1467 | default: |
@@ -2734,10 +2754,7 @@ EXPORT_SYMBOL_GPL(ata_bmdma_dumb_qc_prep); | |||
2734 | unsigned int ata_bmdma_qc_issue(struct ata_queued_cmd *qc) | 2754 | unsigned int ata_bmdma_qc_issue(struct ata_queued_cmd *qc) |
2735 | { | 2755 | { |
2736 | struct ata_port *ap = qc->ap; | 2756 | struct ata_port *ap = qc->ap; |
2737 | 2757 | struct ata_link *link = qc->dev->link; | |
2738 | /* see ata_dma_blacklisted() */ | ||
2739 | BUG_ON((ap->flags & ATA_FLAG_PIO_POLLING) && | ||
2740 | qc->tf.protocol == ATAPI_PROT_DMA); | ||
2741 | 2758 | ||
2742 | /* defer PIO handling to sff_qc_issue */ | 2759 | /* defer PIO handling to sff_qc_issue */ |
2743 | if (!ata_is_dma(qc->tf.protocol)) | 2760 | if (!ata_is_dma(qc->tf.protocol)) |
@@ -2766,7 +2783,7 @@ unsigned int ata_bmdma_qc_issue(struct ata_queued_cmd *qc) | |||
2766 | 2783 | ||
2767 | /* send cdb by polling if no cdb interrupt */ | 2784 | /* send cdb by polling if no cdb interrupt */ |
2768 | if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) | 2785 | if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) |
2769 | ata_sff_queue_pio_task(ap, 0); | 2786 | ata_sff_queue_pio_task(link, 0); |
2770 | break; | 2787 | break; |
2771 | 2788 | ||
2772 | default: | 2789 | default: |
diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c index ba43f0f8c88..2215632e4b3 100644 --- a/drivers/ata/pata_artop.c +++ b/drivers/ata/pata_artop.c | |||
@@ -74,7 +74,8 @@ static int artop6260_pre_reset(struct ata_link *link, unsigned long deadline) | |||
74 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | 74 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); |
75 | 75 | ||
76 | /* Odd numbered device ids are the units with enable bits (the -R cards) */ | 76 | /* Odd numbered device ids are the units with enable bits (the -R cards) */ |
77 | if (pdev->device % 1 && !pci_test_config_bits(pdev, &artop_enable_bits[ap->port_no])) | 77 | if ((pdev->device & 1) && |
78 | !pci_test_config_bits(pdev, &artop_enable_bits[ap->port_no])) | ||
78 | return -ENOENT; | 79 | return -ENOENT; |
79 | 80 | ||
80 | return ata_sff_prereset(link, deadline); | 81 | return ata_sff_prereset(link, deadline); |
diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c index 9f5da1c7454..905ff76d3cb 100644 --- a/drivers/ata/pata_cmd64x.c +++ b/drivers/ata/pata_cmd64x.c | |||
@@ -121,14 +121,8 @@ static void cmd64x_set_timing(struct ata_port *ap, struct ata_device *adev, u8 m | |||
121 | 121 | ||
122 | if (pair) { | 122 | if (pair) { |
123 | struct ata_timing tp; | 123 | struct ata_timing tp; |
124 | |||
125 | ata_timing_compute(pair, pair->pio_mode, &tp, T, 0); | 124 | ata_timing_compute(pair, pair->pio_mode, &tp, T, 0); |
126 | ata_timing_merge(&t, &tp, &t, ATA_TIMING_SETUP); | 125 | ata_timing_merge(&t, &tp, &t, ATA_TIMING_SETUP); |
127 | if (pair->dma_mode) { | ||
128 | ata_timing_compute(pair, pair->dma_mode, | ||
129 | &tp, T, 0); | ||
130 | ata_timing_merge(&tp, &t, &t, ATA_TIMING_SETUP); | ||
131 | } | ||
132 | } | 126 | } |
133 | } | 127 | } |
134 | 128 | ||
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index 9df1ff7e1ea..eaf194138f2 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c | |||
@@ -44,6 +44,9 @@ | |||
44 | * Specific support is included for the ht6560a/ht6560b/opti82c611a/ | 44 | * Specific support is included for the ht6560a/ht6560b/opti82c611a/ |
45 | * opti82c465mv/promise 20230c/20630/qdi65x0/winbond83759A | 45 | * opti82c465mv/promise 20230c/20630/qdi65x0/winbond83759A |
46 | * | 46 | * |
47 | * Support for the Winbond 83759A when operating in advanced mode. | ||
48 | * Multichip mode is not currently supported. | ||
49 | * | ||
47 | * Use the autospeed and pio_mask options with: | 50 | * Use the autospeed and pio_mask options with: |
48 | * Appian ADI/2 aka CLPD7220 or AIC25VL01. | 51 | * Appian ADI/2 aka CLPD7220 or AIC25VL01. |
49 | * Use the jumpers, autospeed and set pio_mask to the mode on the jumpers with | 52 | * Use the jumpers, autospeed and set pio_mask to the mode on the jumpers with |
@@ -135,12 +138,18 @@ static int ht6560b; /* HT 6560A on primary 1, second 2, both 3 */ | |||
135 | static int opti82c611a; /* Opti82c611A on primary 1, sec 2, both 3 */ | 138 | static int opti82c611a; /* Opti82c611A on primary 1, sec 2, both 3 */ |
136 | static int opti82c46x; /* Opti 82c465MV present(pri/sec autodetect) */ | 139 | static int opti82c46x; /* Opti 82c465MV present(pri/sec autodetect) */ |
137 | static int qdi; /* Set to probe QDI controllers */ | 140 | static int qdi; /* Set to probe QDI controllers */ |
138 | static int winbond; /* Set to probe Winbond controllers, | ||
139 | give I/O port if non standard */ | ||
140 | static int autospeed; /* Chip present which snoops speed changes */ | 141 | static int autospeed; /* Chip present which snoops speed changes */ |
141 | static int pio_mask = ATA_PIO4; /* PIO range for autospeed devices */ | 142 | static int pio_mask = ATA_PIO4; /* PIO range for autospeed devices */ |
142 | static int iordy_mask = 0xFFFFFFFF; /* Use iordy if available */ | 143 | static int iordy_mask = 0xFFFFFFFF; /* Use iordy if available */ |
143 | 144 | ||
145 | #ifdef PATA_WINBOND_VLB_MODULE | ||
146 | static int winbond = 1; /* Set to probe Winbond controllers, | ||
147 | give I/O port if non standard */ | ||
148 | #else | ||
149 | static int winbond; /* Set to probe Winbond controllers, | ||
150 | give I/O port if non standard */ | ||
151 | #endif | ||
152 | |||
144 | /** | 153 | /** |
145 | * legacy_probe_add - Add interface to probe list | 154 | * legacy_probe_add - Add interface to probe list |
146 | * @port: Controller port | 155 | * @port: Controller port |
@@ -1297,6 +1306,7 @@ MODULE_AUTHOR("Alan Cox"); | |||
1297 | MODULE_DESCRIPTION("low-level driver for legacy ATA"); | 1306 | MODULE_DESCRIPTION("low-level driver for legacy ATA"); |
1298 | MODULE_LICENSE("GPL"); | 1307 | MODULE_LICENSE("GPL"); |
1299 | MODULE_VERSION(DRV_VERSION); | 1308 | MODULE_VERSION(DRV_VERSION); |
1309 | MODULE_ALIAS("pata_winbond"); | ||
1300 | 1310 | ||
1301 | module_param(probe_all, int, 0); | 1311 | module_param(probe_all, int, 0); |
1302 | module_param(autospeed, int, 0); | 1312 | module_param(autospeed, int, 0); |
@@ -1305,6 +1315,7 @@ module_param(ht6560b, int, 0); | |||
1305 | module_param(opti82c611a, int, 0); | 1315 | module_param(opti82c611a, int, 0); |
1306 | module_param(opti82c46x, int, 0); | 1316 | module_param(opti82c46x, int, 0); |
1307 | module_param(qdi, int, 0); | 1317 | module_param(qdi, int, 0); |
1318 | module_param(winbond, int, 0); | ||
1308 | module_param(pio_mask, int, 0); | 1319 | module_param(pio_mask, int, 0); |
1309 | module_param(iordy_mask, int, 0); | 1320 | module_param(iordy_mask, int, 0); |
1310 | 1321 | ||
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index 5e659885de1..ac8d7d97e40 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c | |||
@@ -417,6 +417,8 @@ static void via_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) | |||
417 | tf->lbam, | 417 | tf->lbam, |
418 | tf->lbah); | 418 | tf->lbah); |
419 | } | 419 | } |
420 | |||
421 | ata_wait_idle(ap); | ||
420 | } | 422 | } |
421 | 423 | ||
422 | static int via_port_start(struct ata_port *ap) | 424 | static int via_port_start(struct ata_port *ap) |
diff --git a/drivers/ata/pata_winbond.c b/drivers/ata/pata_winbond.c deleted file mode 100644 index 6d8619b6f67..00000000000 --- a/drivers/ata/pata_winbond.c +++ /dev/null | |||
@@ -1,282 +0,0 @@ | |||
1 | /* | ||
2 | * pata_winbond.c - Winbond VLB ATA controllers | ||
3 | * (C) 2006 Red Hat | ||
4 | * | ||
5 | * Support for the Winbond 83759A when operating in advanced mode. | ||
6 | * Multichip mode is not currently supported. | ||
7 | */ | ||
8 | |||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/blkdev.h> | ||
13 | #include <linux/delay.h> | ||
14 | #include <scsi/scsi_host.h> | ||
15 | #include <linux/libata.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | |||
18 | #define DRV_NAME "pata_winbond" | ||
19 | #define DRV_VERSION "0.0.3" | ||
20 | |||
21 | #define NR_HOST 4 /* Two winbond controllers, two channels each */ | ||
22 | |||
23 | struct winbond_data { | ||
24 | unsigned long config; | ||
25 | struct platform_device *platform_dev; | ||
26 | }; | ||
27 | |||
28 | static struct ata_host *winbond_host[NR_HOST]; | ||
29 | static struct winbond_data winbond_data[NR_HOST]; | ||
30 | static int nr_winbond_host; | ||
31 | |||
32 | #ifdef MODULE | ||
33 | static int probe_winbond = 1; | ||
34 | #else | ||
35 | static int probe_winbond; | ||
36 | #endif | ||
37 | |||
38 | static DEFINE_SPINLOCK(winbond_lock); | ||
39 | |||
40 | static void winbond_writecfg(unsigned long port, u8 reg, u8 val) | ||
41 | { | ||
42 | unsigned long flags; | ||
43 | spin_lock_irqsave(&winbond_lock, flags); | ||
44 | outb(reg, port + 0x01); | ||
45 | outb(val, port + 0x02); | ||
46 | spin_unlock_irqrestore(&winbond_lock, flags); | ||
47 | } | ||
48 | |||
49 | static u8 winbond_readcfg(unsigned long port, u8 reg) | ||
50 | { | ||
51 | u8 val; | ||
52 | |||
53 | unsigned long flags; | ||
54 | spin_lock_irqsave(&winbond_lock, flags); | ||
55 | outb(reg, port + 0x01); | ||
56 | val = inb(port + 0x02); | ||
57 | spin_unlock_irqrestore(&winbond_lock, flags); | ||
58 | |||
59 | return val; | ||
60 | } | ||
61 | |||
62 | static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev) | ||
63 | { | ||
64 | struct ata_timing t; | ||
65 | struct winbond_data *winbond = ap->host->private_data; | ||
66 | int active, recovery; | ||
67 | u8 reg; | ||
68 | int timing = 0x88 + (ap->port_no * 4) + (adev->devno * 2); | ||
69 | |||
70 | reg = winbond_readcfg(winbond->config, 0x81); | ||
71 | |||
72 | /* Get the timing data in cycles */ | ||
73 | if (reg & 0x40) /* Fast VLB bus, assume 50MHz */ | ||
74 | ata_timing_compute(adev, adev->pio_mode, &t, 20000, 1000); | ||
75 | else | ||
76 | ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); | ||
77 | |||
78 | active = (clamp_val(t.active, 3, 17) - 1) & 0x0F; | ||
79 | recovery = (clamp_val(t.recover, 1, 15) + 1) & 0x0F; | ||
80 | timing = (active << 4) | recovery; | ||
81 | winbond_writecfg(winbond->config, timing, reg); | ||
82 | |||
83 | /* Load the setup timing */ | ||
84 | |||
85 | reg = 0x35; | ||
86 | if (adev->class != ATA_DEV_ATA) | ||
87 | reg |= 0x08; /* FIFO off */ | ||
88 | if (!ata_pio_need_iordy(adev)) | ||
89 | reg |= 0x02; /* IORDY off */ | ||
90 | reg |= (clamp_val(t.setup, 0, 3) << 6); | ||
91 | winbond_writecfg(winbond->config, timing + 1, reg); | ||
92 | } | ||
93 | |||
94 | |||
95 | static unsigned int winbond_data_xfer(struct ata_device *dev, | ||
96 | unsigned char *buf, unsigned int buflen, int rw) | ||
97 | { | ||
98 | struct ata_port *ap = dev->link->ap; | ||
99 | int slop = buflen & 3; | ||
100 | |||
101 | if (ata_id_has_dword_io(dev->id)) { | ||
102 | if (rw == READ) | ||
103 | ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); | ||
104 | else | ||
105 | iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); | ||
106 | |||
107 | if (unlikely(slop)) { | ||
108 | __le32 pad; | ||
109 | if (rw == READ) { | ||
110 | pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr)); | ||
111 | memcpy(buf + buflen - slop, &pad, slop); | ||
112 | } else { | ||
113 | memcpy(&pad, buf + buflen - slop, slop); | ||
114 | iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr); | ||
115 | } | ||
116 | buflen += 4 - slop; | ||
117 | } | ||
118 | } else | ||
119 | buflen = ata_sff_data_xfer(dev, buf, buflen, rw); | ||
120 | |||
121 | return buflen; | ||
122 | } | ||
123 | |||
124 | static struct scsi_host_template winbond_sht = { | ||
125 | ATA_PIO_SHT(DRV_NAME), | ||
126 | }; | ||
127 | |||
128 | static struct ata_port_operations winbond_port_ops = { | ||
129 | .inherits = &ata_sff_port_ops, | ||
130 | .sff_data_xfer = winbond_data_xfer, | ||
131 | .cable_detect = ata_cable_40wire, | ||
132 | .set_piomode = winbond_set_piomode, | ||
133 | }; | ||
134 | |||
135 | /** | ||
136 | * winbond_init_one - attach a winbond interface | ||
137 | * @type: Type to display | ||
138 | * @io: I/O port start | ||
139 | * @irq: interrupt line | ||
140 | * @fast: True if on a > 33Mhz VLB | ||
141 | * | ||
142 | * Register a VLB bus IDE interface. Such interfaces are PIO and we | ||
143 | * assume do not support IRQ sharing. | ||
144 | */ | ||
145 | |||
146 | static __init int winbond_init_one(unsigned long port) | ||
147 | { | ||
148 | struct platform_device *pdev; | ||
149 | u8 reg; | ||
150 | int i, rc; | ||
151 | |||
152 | reg = winbond_readcfg(port, 0x81); | ||
153 | reg |= 0x80; /* jumpered mode off */ | ||
154 | winbond_writecfg(port, 0x81, reg); | ||
155 | reg = winbond_readcfg(port, 0x83); | ||
156 | reg |= 0xF0; /* local control */ | ||
157 | winbond_writecfg(port, 0x83, reg); | ||
158 | reg = winbond_readcfg(port, 0x85); | ||
159 | reg |= 0xF0; /* programmable timing */ | ||
160 | winbond_writecfg(port, 0x85, reg); | ||
161 | |||
162 | reg = winbond_readcfg(port, 0x81); | ||
163 | |||
164 | if (!(reg & 0x03)) /* Disabled */ | ||
165 | return -ENODEV; | ||
166 | |||
167 | for (i = 0; i < 2 ; i ++) { | ||
168 | unsigned long cmd_port = 0x1F0 - (0x80 * i); | ||
169 | unsigned long ctl_port = cmd_port + 0x206; | ||
170 | struct ata_host *host; | ||
171 | struct ata_port *ap; | ||
172 | void __iomem *cmd_addr, *ctl_addr; | ||
173 | |||
174 | if (!(reg & (1 << i))) | ||
175 | continue; | ||
176 | |||
177 | pdev = platform_device_register_simple(DRV_NAME, nr_winbond_host, NULL, 0); | ||
178 | if (IS_ERR(pdev)) | ||
179 | return PTR_ERR(pdev); | ||
180 | |||
181 | rc = -ENOMEM; | ||
182 | host = ata_host_alloc(&pdev->dev, 1); | ||
183 | if (!host) | ||
184 | goto err_unregister; | ||
185 | ap = host->ports[0]; | ||
186 | |||
187 | rc = -ENOMEM; | ||
188 | cmd_addr = devm_ioport_map(&pdev->dev, cmd_port, 8); | ||
189 | ctl_addr = devm_ioport_map(&pdev->dev, ctl_port, 1); | ||
190 | if (!cmd_addr || !ctl_addr) | ||
191 | goto err_unregister; | ||
192 | |||
193 | ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", cmd_port, ctl_port); | ||
194 | |||
195 | ap->ops = &winbond_port_ops; | ||
196 | ap->pio_mask = ATA_PIO4; | ||
197 | ap->flags |= ATA_FLAG_SLAVE_POSS; | ||
198 | ap->ioaddr.cmd_addr = cmd_addr; | ||
199 | ap->ioaddr.altstatus_addr = ctl_addr; | ||
200 | ap->ioaddr.ctl_addr = ctl_addr; | ||
201 | ata_sff_std_ports(&ap->ioaddr); | ||
202 | |||
203 | /* hook in a private data structure per channel */ | ||
204 | host->private_data = &winbond_data[nr_winbond_host]; | ||
205 | winbond_data[nr_winbond_host].config = port; | ||
206 | winbond_data[nr_winbond_host].platform_dev = pdev; | ||
207 | |||
208 | /* activate */ | ||
209 | rc = ata_host_activate(host, 14 + i, ata_sff_interrupt, 0, | ||
210 | &winbond_sht); | ||
211 | if (rc) | ||
212 | goto err_unregister; | ||
213 | |||
214 | winbond_host[nr_winbond_host++] = dev_get_drvdata(&pdev->dev); | ||
215 | } | ||
216 | |||
217 | return 0; | ||
218 | |||
219 | err_unregister: | ||
220 | platform_device_unregister(pdev); | ||
221 | return rc; | ||
222 | } | ||
223 | |||
224 | /** | ||
225 | * winbond_init - attach winbond interfaces | ||
226 | * | ||
227 | * Attach winbond IDE interfaces by scanning the ports it may occupy. | ||
228 | */ | ||
229 | |||
230 | static __init int winbond_init(void) | ||
231 | { | ||
232 | static const unsigned long config[2] = { 0x130, 0x1B0 }; | ||
233 | |||
234 | int ct = 0; | ||
235 | int i; | ||
236 | |||
237 | if (probe_winbond == 0) | ||
238 | return -ENODEV; | ||
239 | |||
240 | /* | ||
241 | * Check both base addresses | ||
242 | */ | ||
243 | |||
244 | for (i = 0; i < 2; i++) { | ||
245 | if (probe_winbond & (1<<i)) { | ||
246 | int ret = 0; | ||
247 | unsigned long port = config[i]; | ||
248 | |||
249 | if (request_region(port, 2, "pata_winbond")) { | ||
250 | ret = winbond_init_one(port); | ||
251 | if (ret <= 0) | ||
252 | release_region(port, 2); | ||
253 | else ct+= ret; | ||
254 | } | ||
255 | } | ||
256 | } | ||
257 | if (ct != 0) | ||
258 | return 0; | ||
259 | return -ENODEV; | ||
260 | } | ||
261 | |||
262 | static __exit void winbond_exit(void) | ||
263 | { | ||
264 | int i; | ||
265 | |||
266 | for (i = 0; i < nr_winbond_host; i++) { | ||
267 | ata_host_detach(winbond_host[i]); | ||
268 | release_region(winbond_data[i].config, 2); | ||
269 | platform_device_unregister(winbond_data[i].platform_dev); | ||
270 | } | ||
271 | } | ||
272 | |||
273 | MODULE_AUTHOR("Alan Cox"); | ||
274 | MODULE_DESCRIPTION("low-level driver for Winbond VL ATA"); | ||
275 | MODULE_LICENSE("GPL"); | ||
276 | MODULE_VERSION(DRV_VERSION); | ||
277 | |||
278 | module_init(winbond_init); | ||
279 | module_exit(winbond_exit); | ||
280 | |||
281 | module_param(probe_winbond, int, 0); | ||
282 | |||
diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c index 2673a3d1480..6cf57c5c2b5 100644 --- a/drivers/ata/sata_dwc_460ex.c +++ b/drivers/ata/sata_dwc_460ex.c | |||
@@ -1459,7 +1459,7 @@ static void sata_dwc_qc_prep_by_tag(struct ata_queued_cmd *qc, u8 tag) | |||
1459 | { | 1459 | { |
1460 | struct scatterlist *sg = qc->sg; | 1460 | struct scatterlist *sg = qc->sg; |
1461 | struct ata_port *ap = qc->ap; | 1461 | struct ata_port *ap = qc->ap; |
1462 | u32 dma_chan; | 1462 | int dma_chan; |
1463 | struct sata_dwc_device *hsdev = HSDEV_FROM_AP(ap); | 1463 | struct sata_dwc_device *hsdev = HSDEV_FROM_AP(ap); |
1464 | struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap); | 1464 | struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap); |
1465 | int err; | 1465 | int err; |
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 9463c71dd38..a9fd9709c26 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -1898,19 +1898,25 @@ static void mv_bmdma_start(struct ata_queued_cmd *qc) | |||
1898 | * LOCKING: | 1898 | * LOCKING: |
1899 | * Inherited from caller. | 1899 | * Inherited from caller. |
1900 | */ | 1900 | */ |
1901 | static void mv_bmdma_stop(struct ata_queued_cmd *qc) | 1901 | static void mv_bmdma_stop_ap(struct ata_port *ap) |
1902 | { | 1902 | { |
1903 | struct ata_port *ap = qc->ap; | ||
1904 | void __iomem *port_mmio = mv_ap_base(ap); | 1903 | void __iomem *port_mmio = mv_ap_base(ap); |
1905 | u32 cmd; | 1904 | u32 cmd; |
1906 | 1905 | ||
1907 | /* clear start/stop bit */ | 1906 | /* clear start/stop bit */ |
1908 | cmd = readl(port_mmio + BMDMA_CMD); | 1907 | cmd = readl(port_mmio + BMDMA_CMD); |
1909 | cmd &= ~ATA_DMA_START; | 1908 | if (cmd & ATA_DMA_START) { |
1910 | writelfl(cmd, port_mmio + BMDMA_CMD); | 1909 | cmd &= ~ATA_DMA_START; |
1910 | writelfl(cmd, port_mmio + BMDMA_CMD); | ||
1911 | |||
1912 | /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */ | ||
1913 | ata_sff_dma_pause(ap); | ||
1914 | } | ||
1915 | } | ||
1911 | 1916 | ||
1912 | /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */ | 1917 | static void mv_bmdma_stop(struct ata_queued_cmd *qc) |
1913 | ata_sff_dma_pause(ap); | 1918 | { |
1919 | mv_bmdma_stop_ap(qc->ap); | ||
1914 | } | 1920 | } |
1915 | 1921 | ||
1916 | /** | 1922 | /** |
@@ -1934,8 +1940,21 @@ static u8 mv_bmdma_status(struct ata_port *ap) | |||
1934 | reg = readl(port_mmio + BMDMA_STATUS); | 1940 | reg = readl(port_mmio + BMDMA_STATUS); |
1935 | if (reg & ATA_DMA_ACTIVE) | 1941 | if (reg & ATA_DMA_ACTIVE) |
1936 | status = ATA_DMA_ACTIVE; | 1942 | status = ATA_DMA_ACTIVE; |
1937 | else | 1943 | else if (reg & ATA_DMA_ERR) |
1938 | status = (reg & ATA_DMA_ERR) | ATA_DMA_INTR; | 1944 | status = (reg & ATA_DMA_ERR) | ATA_DMA_INTR; |
1945 | else { | ||
1946 | /* | ||
1947 | * Just because DMA_ACTIVE is 0 (DMA completed), | ||
1948 | * this does _not_ mean the device is "done". | ||
1949 | * So we should not yet be signalling ATA_DMA_INTR | ||
1950 | * in some cases. Eg. DSM/TRIM, and perhaps others. | ||
1951 | */ | ||
1952 | mv_bmdma_stop_ap(ap); | ||
1953 | if (ioread8(ap->ioaddr.altstatus_addr) & ATA_BUSY) | ||
1954 | status = 0; | ||
1955 | else | ||
1956 | status = ATA_DMA_INTR; | ||
1957 | } | ||
1939 | return status; | 1958 | return status; |
1940 | } | 1959 | } |
1941 | 1960 | ||
@@ -1995,6 +2014,9 @@ static void mv_qc_prep(struct ata_queued_cmd *qc) | |||
1995 | 2014 | ||
1996 | switch (tf->protocol) { | 2015 | switch (tf->protocol) { |
1997 | case ATA_PROT_DMA: | 2016 | case ATA_PROT_DMA: |
2017 | if (tf->command == ATA_CMD_DSM) | ||
2018 | return; | ||
2019 | /* fall-thru */ | ||
1998 | case ATA_PROT_NCQ: | 2020 | case ATA_PROT_NCQ: |
1999 | break; /* continue below */ | 2021 | break; /* continue below */ |
2000 | case ATA_PROT_PIO: | 2022 | case ATA_PROT_PIO: |
@@ -2094,6 +2116,8 @@ static void mv_qc_prep_iie(struct ata_queued_cmd *qc) | |||
2094 | if ((tf->protocol != ATA_PROT_DMA) && | 2116 | if ((tf->protocol != ATA_PROT_DMA) && |
2095 | (tf->protocol != ATA_PROT_NCQ)) | 2117 | (tf->protocol != ATA_PROT_NCQ)) |
2096 | return; | 2118 | return; |
2119 | if (tf->command == ATA_CMD_DSM) | ||
2120 | return; /* use bmdma for this */ | ||
2097 | 2121 | ||
2098 | /* Fill in Gen IIE command request block */ | 2122 | /* Fill in Gen IIE command request block */ |
2099 | if (!(tf->flags & ATA_TFLAG_WRITE)) | 2123 | if (!(tf->flags & ATA_TFLAG_WRITE)) |
@@ -2260,7 +2284,7 @@ static unsigned int mv_qc_issue_fis(struct ata_queued_cmd *qc) | |||
2260 | } | 2284 | } |
2261 | 2285 | ||
2262 | if (qc->tf.flags & ATA_TFLAG_POLLING) | 2286 | if (qc->tf.flags & ATA_TFLAG_POLLING) |
2263 | ata_sff_queue_pio_task(ap, 0); | 2287 | ata_sff_queue_pio_task(link, 0); |
2264 | return 0; | 2288 | return 0; |
2265 | } | 2289 | } |
2266 | 2290 | ||
@@ -2289,6 +2313,12 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc) | |||
2289 | 2313 | ||
2290 | switch (qc->tf.protocol) { | 2314 | switch (qc->tf.protocol) { |
2291 | case ATA_PROT_DMA: | 2315 | case ATA_PROT_DMA: |
2316 | if (qc->tf.command == ATA_CMD_DSM) { | ||
2317 | if (!ap->ops->bmdma_setup) /* no bmdma on GEN_I */ | ||
2318 | return AC_ERR_OTHER; | ||
2319 | break; /* use bmdma for this */ | ||
2320 | } | ||
2321 | /* fall thru */ | ||
2292 | case ATA_PROT_NCQ: | 2322 | case ATA_PROT_NCQ: |
2293 | mv_start_edma(ap, port_mmio, pp, qc->tf.protocol); | 2323 | mv_start_edma(ap, port_mmio, pp, qc->tf.protocol); |
2294 | pp->req_idx = (pp->req_idx + 1) & MV_MAX_Q_DEPTH_MASK; | 2324 | pp->req_idx = (pp->req_idx + 1) & MV_MAX_Q_DEPTH_MASK; |
diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c index ee9ddeb5341..8cb0347dec2 100644 --- a/drivers/atm/iphase.c +++ b/drivers/atm/iphase.c | |||
@@ -3156,7 +3156,6 @@ static int __devinit ia_init_one(struct pci_dev *pdev, | |||
3156 | { | 3156 | { |
3157 | struct atm_dev *dev; | 3157 | struct atm_dev *dev; |
3158 | IADEV *iadev; | 3158 | IADEV *iadev; |
3159 | unsigned long flags; | ||
3160 | int ret; | 3159 | int ret; |
3161 | 3160 | ||
3162 | iadev = kzalloc(sizeof(*iadev), GFP_KERNEL); | 3161 | iadev = kzalloc(sizeof(*iadev), GFP_KERNEL); |
@@ -3188,19 +3187,14 @@ static int __devinit ia_init_one(struct pci_dev *pdev, | |||
3188 | ia_dev[iadev_count] = iadev; | 3187 | ia_dev[iadev_count] = iadev; |
3189 | _ia_dev[iadev_count] = dev; | 3188 | _ia_dev[iadev_count] = dev; |
3190 | iadev_count++; | 3189 | iadev_count++; |
3191 | spin_lock_init(&iadev->misc_lock); | ||
3192 | /* First fixes first. I don't want to think about this now. */ | ||
3193 | spin_lock_irqsave(&iadev->misc_lock, flags); | ||
3194 | if (ia_init(dev) || ia_start(dev)) { | 3190 | if (ia_init(dev) || ia_start(dev)) { |
3195 | IF_INIT(printk("IA register failed!\n");) | 3191 | IF_INIT(printk("IA register failed!\n");) |
3196 | iadev_count--; | 3192 | iadev_count--; |
3197 | ia_dev[iadev_count] = NULL; | 3193 | ia_dev[iadev_count] = NULL; |
3198 | _ia_dev[iadev_count] = NULL; | 3194 | _ia_dev[iadev_count] = NULL; |
3199 | spin_unlock_irqrestore(&iadev->misc_lock, flags); | ||
3200 | ret = -EINVAL; | 3195 | ret = -EINVAL; |
3201 | goto err_out_deregister_dev; | 3196 | goto err_out_deregister_dev; |
3202 | } | 3197 | } |
3203 | spin_unlock_irqrestore(&iadev->misc_lock, flags); | ||
3204 | IF_EVENT(printk("iadev_count = %d\n", iadev_count);) | 3198 | IF_EVENT(printk("iadev_count = %d\n", iadev_count);) |
3205 | 3199 | ||
3206 | iadev->next_board = ia_boards; | 3200 | iadev->next_board = ia_boards; |
diff --git a/drivers/atm/iphase.h b/drivers/atm/iphase.h index b2cd20f549c..077735e0e04 100644 --- a/drivers/atm/iphase.h +++ b/drivers/atm/iphase.h | |||
@@ -1022,7 +1022,7 @@ typedef struct iadev_t { | |||
1022 | struct dle_q rx_dle_q; | 1022 | struct dle_q rx_dle_q; |
1023 | struct free_desc_q *rx_free_desc_qhead; | 1023 | struct free_desc_q *rx_free_desc_qhead; |
1024 | struct sk_buff_head rx_dma_q; | 1024 | struct sk_buff_head rx_dma_q; |
1025 | spinlock_t rx_lock, misc_lock; | 1025 | spinlock_t rx_lock; |
1026 | struct atm_vcc **rx_open; /* list of all open VCs */ | 1026 | struct atm_vcc **rx_open; /* list of all open VCs */ |
1027 | u16 num_rx_desc, rx_buf_sz, rxing; | 1027 | u16 num_rx_desc, rx_buf_sz, rxing; |
1028 | u32 rx_pkt_ram, rx_tmp_cnt; | 1028 | u32 rx_pkt_ram, rx_tmp_cnt; |
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c index f916ddf6393..f46138ab38b 100644 --- a/drivers/atm/solos-pci.c +++ b/drivers/atm/solos-pci.c | |||
@@ -444,6 +444,7 @@ static ssize_t console_show(struct device *dev, struct device_attribute *attr, | |||
444 | struct atm_dev *atmdev = container_of(dev, struct atm_dev, class_dev); | 444 | struct atm_dev *atmdev = container_of(dev, struct atm_dev, class_dev); |
445 | struct solos_card *card = atmdev->dev_data; | 445 | struct solos_card *card = atmdev->dev_data; |
446 | struct sk_buff *skb; | 446 | struct sk_buff *skb; |
447 | unsigned int len; | ||
447 | 448 | ||
448 | spin_lock(&card->cli_queue_lock); | 449 | spin_lock(&card->cli_queue_lock); |
449 | skb = skb_dequeue(&card->cli_queue[SOLOS_CHAN(atmdev)]); | 450 | skb = skb_dequeue(&card->cli_queue[SOLOS_CHAN(atmdev)]); |
@@ -451,11 +452,12 @@ static ssize_t console_show(struct device *dev, struct device_attribute *attr, | |||
451 | if(skb == NULL) | 452 | if(skb == NULL) |
452 | return sprintf(buf, "No data.\n"); | 453 | return sprintf(buf, "No data.\n"); |
453 | 454 | ||
454 | memcpy(buf, skb->data, skb->len); | 455 | len = skb->len; |
455 | dev_dbg(&card->dev->dev, "len: %d\n", skb->len); | 456 | memcpy(buf, skb->data, len); |
457 | dev_dbg(&card->dev->dev, "len: %d\n", len); | ||
456 | 458 | ||
457 | kfree_skb(skb); | 459 | kfree_skb(skb); |
458 | return skb->len; | 460 | return len; |
459 | } | 461 | } |
460 | 462 | ||
461 | static int send_command(struct solos_card *card, int dev, const char *buf, size_t size) | 463 | static int send_command(struct solos_card *card, int dev, const char *buf, size_t size) |
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index c8a44f5e058..40af43ebd92 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
@@ -568,7 +568,7 @@ static int _request_firmware(const struct firmware **firmware_p, | |||
568 | out: | 568 | out: |
569 | if (retval) { | 569 | if (retval) { |
570 | release_firmware(firmware); | 570 | release_firmware(firmware); |
571 | firmware_p = NULL; | 571 | *firmware_p = NULL; |
572 | } | 572 | } |
573 | 573 | ||
574 | return retval; | 574 | return retval; |
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 5419a49ff13..276d5a701dc 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c | |||
@@ -59,6 +59,7 @@ void device_pm_init(struct device *dev) | |||
59 | { | 59 | { |
60 | dev->power.status = DPM_ON; | 60 | dev->power.status = DPM_ON; |
61 | init_completion(&dev->power.completion); | 61 | init_completion(&dev->power.completion); |
62 | complete_all(&dev->power.completion); | ||
62 | dev->power.wakeup_count = 0; | 63 | dev->power.wakeup_count = 0; |
63 | pm_runtime_init(dev); | 64 | pm_runtime_init(dev); |
64 | } | 65 | } |
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 31064df1370..5e4fadcdece 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -297,6 +297,8 @@ static void enqueue_cmd_and_start_io(ctlr_info_t *h, | |||
297 | spin_lock_irqsave(&h->lock, flags); | 297 | spin_lock_irqsave(&h->lock, flags); |
298 | addQ(&h->reqQ, c); | 298 | addQ(&h->reqQ, c); |
299 | h->Qdepth++; | 299 | h->Qdepth++; |
300 | if (h->Qdepth > h->maxQsinceinit) | ||
301 | h->maxQsinceinit = h->Qdepth; | ||
300 | start_io(h); | 302 | start_io(h); |
301 | spin_unlock_irqrestore(&h->lock, flags); | 303 | spin_unlock_irqrestore(&h->lock, flags); |
302 | } | 304 | } |
@@ -4519,6 +4521,12 @@ static __devinit int cciss_kdump_hard_reset_controller(struct pci_dev *pdev) | |||
4519 | misc_fw_support = readl(&cfgtable->misc_fw_support); | 4521 | misc_fw_support = readl(&cfgtable->misc_fw_support); |
4520 | use_doorbell = misc_fw_support & MISC_FW_DOORBELL_RESET; | 4522 | use_doorbell = misc_fw_support & MISC_FW_DOORBELL_RESET; |
4521 | 4523 | ||
4524 | /* The doorbell reset seems to cause lockups on some Smart | ||
4525 | * Arrays (e.g. P410, P410i, maybe others). Until this is | ||
4526 | * fixed or at least isolated, avoid the doorbell reset. | ||
4527 | */ | ||
4528 | use_doorbell = 0; | ||
4529 | |||
4522 | rc = cciss_controller_hard_reset(pdev, vaddr, use_doorbell); | 4530 | rc = cciss_controller_hard_reset(pdev, vaddr, use_doorbell); |
4523 | if (rc) | 4531 | if (rc) |
4524 | goto unmap_cfgtable; | 4532 | goto unmap_cfgtable; |
@@ -4712,6 +4720,9 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
4712 | h->scatter_list = kmalloc(h->max_commands * | 4720 | h->scatter_list = kmalloc(h->max_commands * |
4713 | sizeof(struct scatterlist *), | 4721 | sizeof(struct scatterlist *), |
4714 | GFP_KERNEL); | 4722 | GFP_KERNEL); |
4723 | if (!h->scatter_list) | ||
4724 | goto clean4; | ||
4725 | |||
4715 | for (k = 0; k < h->nr_cmds; k++) { | 4726 | for (k = 0; k < h->nr_cmds; k++) { |
4716 | h->scatter_list[k] = kmalloc(sizeof(struct scatterlist) * | 4727 | h->scatter_list[k] = kmalloc(sizeof(struct scatterlist) * |
4717 | h->maxsgentries, | 4728 | h->maxsgentries, |
@@ -4781,7 +4792,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
4781 | clean4: | 4792 | clean4: |
4782 | kfree(h->cmd_pool_bits); | 4793 | kfree(h->cmd_pool_bits); |
4783 | /* Free up sg elements */ | 4794 | /* Free up sg elements */ |
4784 | for (k = 0; k < h->nr_cmds; k++) | 4795 | for (k-- ; k >= 0; k--) |
4785 | kfree(h->scatter_list[k]); | 4796 | kfree(h->scatter_list[k]); |
4786 | kfree(h->scatter_list); | 4797 | kfree(h->scatter_list); |
4787 | cciss_free_sg_chain_blocks(h->cmd_sg_list, h->nr_cmds); | 4798 | cciss_free_sg_chain_blocks(h->cmd_sg_list, h->nr_cmds); |
diff --git a/drivers/block/mg_disk.c b/drivers/block/mg_disk.c index b82c5ce5e9d..76fa3deaee8 100644 --- a/drivers/block/mg_disk.c +++ b/drivers/block/mg_disk.c | |||
@@ -974,8 +974,7 @@ static int mg_probe(struct platform_device *plat_dev) | |||
974 | host->breq->queuedata = host; | 974 | host->breq->queuedata = host; |
975 | 975 | ||
976 | /* mflash is random device, thanx for the noop */ | 976 | /* mflash is random device, thanx for the noop */ |
977 | elevator_exit(host->breq->elevator); | 977 | err = elevator_change(host->breq, "noop"); |
978 | err = elevator_init(host->breq, "noop"); | ||
979 | if (err) { | 978 | if (err) { |
980 | printk(KERN_ERR "%s:%d (elevator_init) fail\n", | 979 | printk(KERN_ERR "%s:%d (elevator_init) fail\n", |
981 | __func__, __LINE__); | 980 | __func__, __LINE__); |
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 0166ea13604..1b5cfcccd65 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c | |||
@@ -2368,7 +2368,7 @@ static void pkt_release_dev(struct pktcdvd_device *pd, int flush) | |||
2368 | pkt_shrink_pktlist(pd); | 2368 | pkt_shrink_pktlist(pd); |
2369 | } | 2369 | } |
2370 | 2370 | ||
2371 | static struct pktcdvd_device *pkt_find_dev_from_minor(int dev_minor) | 2371 | static struct pktcdvd_device *pkt_find_dev_from_minor(unsigned int dev_minor) |
2372 | { | 2372 | { |
2373 | if (dev_minor >= MAX_WRITERS) | 2373 | if (dev_minor >= MAX_WRITERS) |
2374 | return NULL; | 2374 | return NULL; |
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 126062802cb..831e75caea3 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c | |||
@@ -199,6 +199,7 @@ static int virtblk_get_id(struct gendisk *disk, char *id_str) | |||
199 | struct virtio_blk *vblk = disk->private_data; | 199 | struct virtio_blk *vblk = disk->private_data; |
200 | struct request *req; | 200 | struct request *req; |
201 | struct bio *bio; | 201 | struct bio *bio; |
202 | int err; | ||
202 | 203 | ||
203 | bio = bio_map_kern(vblk->disk->queue, id_str, VIRTIO_BLK_ID_BYTES, | 204 | bio = bio_map_kern(vblk->disk->queue, id_str, VIRTIO_BLK_ID_BYTES, |
204 | GFP_KERNEL); | 205 | GFP_KERNEL); |
@@ -212,7 +213,10 @@ static int virtblk_get_id(struct gendisk *disk, char *id_str) | |||
212 | } | 213 | } |
213 | 214 | ||
214 | req->cmd_type = REQ_TYPE_SPECIAL; | 215 | req->cmd_type = REQ_TYPE_SPECIAL; |
215 | return blk_execute_rq(vblk->disk->queue, vblk->disk, req, false); | 216 | err = blk_execute_rq(vblk->disk->queue, vblk->disk, req, false); |
217 | blk_put_request(req); | ||
218 | |||
219 | return err; | ||
216 | } | 220 | } |
217 | 221 | ||
218 | static int virtblk_locked_ioctl(struct block_device *bdev, fmode_t mode, | 222 | static int virtblk_locked_ioctl(struct block_device *bdev, fmode_t mode, |
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 0b1eea64326..f2ffc46644d 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c | |||
@@ -820,7 +820,7 @@ static int blkfront_probe(struct xenbus_device *dev, | |||
820 | char *type; | 820 | char *type; |
821 | int len; | 821 | int len; |
822 | /* no unplug has been done: do not hook devices != xen vbds */ | 822 | /* no unplug has been done: do not hook devices != xen vbds */ |
823 | if (xen_platform_pci_unplug & XEN_UNPLUG_IGNORE) { | 823 | if (xen_platform_pci_unplug & XEN_UNPLUG_UNNECESSARY) { |
824 | int major; | 824 | int major; |
825 | 825 | ||
826 | if (!VDEV_IS_EXTENDED(vdevice)) | 826 | if (!VDEV_IS_EXTENDED(vdevice)) |
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 710af89b176..cd18493c952 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <asm/smp.h> | 12 | #include <asm/smp.h> |
13 | #include "agp.h" | 13 | #include "agp.h" |
14 | #include "intel-agp.h" | 14 | #include "intel-agp.h" |
15 | #include <linux/intel-gtt.h> | ||
15 | 16 | ||
16 | #include "intel-gtt.c" | 17 | #include "intel-gtt.c" |
17 | 18 | ||
@@ -805,6 +806,8 @@ static const struct intel_driver_description { | |||
805 | "G45/G43", NULL, &intel_i965_driver }, | 806 | "G45/G43", NULL, &intel_i965_driver }, |
806 | { PCI_DEVICE_ID_INTEL_B43_HB, PCI_DEVICE_ID_INTEL_B43_IG, | 807 | { PCI_DEVICE_ID_INTEL_B43_HB, PCI_DEVICE_ID_INTEL_B43_IG, |
807 | "B43", NULL, &intel_i965_driver }, | 808 | "B43", NULL, &intel_i965_driver }, |
809 | { PCI_DEVICE_ID_INTEL_B43_1_HB, PCI_DEVICE_ID_INTEL_B43_1_IG, | ||
810 | "B43", NULL, &intel_i965_driver }, | ||
808 | { PCI_DEVICE_ID_INTEL_G41_HB, PCI_DEVICE_ID_INTEL_G41_IG, | 811 | { PCI_DEVICE_ID_INTEL_G41_HB, PCI_DEVICE_ID_INTEL_G41_IG, |
809 | "G41", NULL, &intel_i965_driver }, | 812 | "G41", NULL, &intel_i965_driver }, |
810 | { PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG, | 813 | { PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG, |
@@ -815,11 +818,19 @@ static const struct intel_driver_description { | |||
815 | "HD Graphics", NULL, &intel_i965_driver }, | 818 | "HD Graphics", NULL, &intel_i965_driver }, |
816 | { PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, | 819 | { PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, |
817 | "HD Graphics", NULL, &intel_i965_driver }, | 820 | "HD Graphics", NULL, &intel_i965_driver }, |
818 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_IG, | 821 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT1_IG, |
822 | "Sandybridge", NULL, &intel_gen6_driver }, | ||
823 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT2_IG, | ||
824 | "Sandybridge", NULL, &intel_gen6_driver }, | ||
825 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT2_PLUS_IG, | ||
826 | "Sandybridge", NULL, &intel_gen6_driver }, | ||
827 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT1_IG, | ||
828 | "Sandybridge", NULL, &intel_gen6_driver }, | ||
829 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT2_IG, | ||
819 | "Sandybridge", NULL, &intel_gen6_driver }, | 830 | "Sandybridge", NULL, &intel_gen6_driver }, |
820 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_IG, | 831 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT2_PLUS_IG, |
821 | "Sandybridge", NULL, &intel_gen6_driver }, | 832 | "Sandybridge", NULL, &intel_gen6_driver }, |
822 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_D0_IG, | 833 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_IG, |
823 | "Sandybridge", NULL, &intel_gen6_driver }, | 834 | "Sandybridge", NULL, &intel_gen6_driver }, |
824 | { 0, 0, NULL, NULL, NULL } | 835 | { 0, 0, NULL, NULL, NULL } |
825 | }; | 836 | }; |
@@ -1044,6 +1055,7 @@ static struct pci_device_id agp_intel_pci_table[] = { | |||
1044 | ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB), | 1055 | ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB), |
1045 | ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB), | 1056 | ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB), |
1046 | ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB), | 1057 | ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB), |
1058 | ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB), | ||
1047 | { } | 1059 | { } |
1048 | }; | 1060 | }; |
1049 | 1061 | ||
diff --git a/drivers/char/agp/intel-agp.h b/drivers/char/agp/intel-agp.h index 08d47532e60..d09b1ab7e8a 100644 --- a/drivers/char/agp/intel-agp.h +++ b/drivers/char/agp/intel-agp.h | |||
@@ -1,6 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * Common Intel AGPGART and GTT definitions. | 2 | * Common Intel AGPGART and GTT definitions. |
3 | */ | 3 | */ |
4 | #ifndef _INTEL_AGP_H | ||
5 | #define _INTEL_AGP_H | ||
4 | 6 | ||
5 | /* Intel registers */ | 7 | /* Intel registers */ |
6 | #define INTEL_APSIZE 0xb4 | 8 | #define INTEL_APSIZE 0xb4 |
@@ -184,6 +186,8 @@ | |||
184 | #define PCI_DEVICE_ID_INTEL_Q33_IG 0x29D2 | 186 | #define PCI_DEVICE_ID_INTEL_Q33_IG 0x29D2 |
185 | #define PCI_DEVICE_ID_INTEL_B43_HB 0x2E40 | 187 | #define PCI_DEVICE_ID_INTEL_B43_HB 0x2E40 |
186 | #define PCI_DEVICE_ID_INTEL_B43_IG 0x2E42 | 188 | #define PCI_DEVICE_ID_INTEL_B43_IG 0x2E42 |
189 | #define PCI_DEVICE_ID_INTEL_B43_1_HB 0x2E90 | ||
190 | #define PCI_DEVICE_ID_INTEL_B43_1_IG 0x2E92 | ||
187 | #define PCI_DEVICE_ID_INTEL_GM45_HB 0x2A40 | 191 | #define PCI_DEVICE_ID_INTEL_GM45_HB 0x2A40 |
188 | #define PCI_DEVICE_ID_INTEL_GM45_IG 0x2A42 | 192 | #define PCI_DEVICE_ID_INTEL_GM45_IG 0x2A42 |
189 | #define PCI_DEVICE_ID_INTEL_EAGLELAKE_HB 0x2E00 | 193 | #define PCI_DEVICE_ID_INTEL_EAGLELAKE_HB 0x2E00 |
@@ -200,11 +204,16 @@ | |||
200 | #define PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB 0x0062 | 204 | #define PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB 0x0062 |
201 | #define PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB 0x006a | 205 | #define PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB 0x006a |
202 | #define PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG 0x0046 | 206 | #define PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG 0x0046 |
203 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB 0x0100 | 207 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB 0x0100 /* Desktop */ |
204 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_IG 0x0102 | 208 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT1_IG 0x0102 |
205 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB 0x0104 | 209 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT2_IG 0x0112 |
206 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_IG 0x0106 | 210 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT2_PLUS_IG 0x0122 |
207 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_D0_IG 0x0126 | 211 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB 0x0104 /* Mobile */ |
212 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT1_IG 0x0106 | ||
213 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT2_IG 0x0116 | ||
214 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT2_PLUS_IG 0x0126 | ||
215 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB 0x0108 /* Server */ | ||
216 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_IG 0x010A | ||
208 | 217 | ||
209 | /* cover 915 and 945 variants */ | 218 | /* cover 915 and 945 variants */ |
210 | #define IS_I915 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB || \ | 219 | #define IS_I915 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB || \ |
@@ -231,7 +240,8 @@ | |||
231 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_HB) | 240 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_HB) |
232 | 241 | ||
233 | #define IS_SNB (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB || \ | 242 | #define IS_SNB (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB || \ |
234 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB) | 243 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB || \ |
244 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB) | ||
235 | 245 | ||
236 | #define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_EAGLELAKE_HB || \ | 246 | #define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_EAGLELAKE_HB || \ |
237 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \ | 247 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \ |
@@ -244,3 +254,5 @@ | |||
244 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB || \ | 254 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB || \ |
245 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB || \ | 255 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB || \ |
246 | IS_SNB) | 256 | IS_SNB) |
257 | |||
258 | #endif | ||
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index d22ffb811bf..75e0a349788 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c | |||
@@ -49,6 +49,26 @@ static struct gatt_mask intel_i810_masks[] = | |||
49 | .type = INTEL_AGP_CACHED_MEMORY} | 49 | .type = INTEL_AGP_CACHED_MEMORY} |
50 | }; | 50 | }; |
51 | 51 | ||
52 | #define INTEL_AGP_UNCACHED_MEMORY 0 | ||
53 | #define INTEL_AGP_CACHED_MEMORY_LLC 1 | ||
54 | #define INTEL_AGP_CACHED_MEMORY_LLC_GFDT 2 | ||
55 | #define INTEL_AGP_CACHED_MEMORY_LLC_MLC 3 | ||
56 | #define INTEL_AGP_CACHED_MEMORY_LLC_MLC_GFDT 4 | ||
57 | |||
58 | static struct gatt_mask intel_gen6_masks[] = | ||
59 | { | ||
60 | {.mask = I810_PTE_VALID | GEN6_PTE_UNCACHED, | ||
61 | .type = INTEL_AGP_UNCACHED_MEMORY }, | ||
62 | {.mask = I810_PTE_VALID | GEN6_PTE_LLC, | ||
63 | .type = INTEL_AGP_CACHED_MEMORY_LLC }, | ||
64 | {.mask = I810_PTE_VALID | GEN6_PTE_LLC | GEN6_PTE_GFDT, | ||
65 | .type = INTEL_AGP_CACHED_MEMORY_LLC_GFDT }, | ||
66 | {.mask = I810_PTE_VALID | GEN6_PTE_LLC_MLC, | ||
67 | .type = INTEL_AGP_CACHED_MEMORY_LLC_MLC }, | ||
68 | {.mask = I810_PTE_VALID | GEN6_PTE_LLC_MLC | GEN6_PTE_GFDT, | ||
69 | .type = INTEL_AGP_CACHED_MEMORY_LLC_MLC_GFDT }, | ||
70 | }; | ||
71 | |||
52 | static struct _intel_private { | 72 | static struct _intel_private { |
53 | struct pci_dev *pcidev; /* device one */ | 73 | struct pci_dev *pcidev; /* device one */ |
54 | u8 __iomem *registers; | 74 | u8 __iomem *registers; |
@@ -178,13 +198,6 @@ static void intel_agp_insert_sg_entries(struct agp_memory *mem, | |||
178 | off_t pg_start, int mask_type) | 198 | off_t pg_start, int mask_type) |
179 | { | 199 | { |
180 | int i, j; | 200 | int i, j; |
181 | u32 cache_bits = 0; | ||
182 | |||
183 | if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB || | ||
184 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB) | ||
185 | { | ||
186 | cache_bits = GEN6_PTE_LLC_MLC; | ||
187 | } | ||
188 | 201 | ||
189 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { | 202 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { |
190 | writel(agp_bridge->driver->mask_memory(agp_bridge, | 203 | writel(agp_bridge->driver->mask_memory(agp_bridge, |
@@ -317,6 +330,23 @@ static int intel_i830_type_to_mask_type(struct agp_bridge_data *bridge, | |||
317 | return 0; | 330 | return 0; |
318 | } | 331 | } |
319 | 332 | ||
333 | static int intel_gen6_type_to_mask_type(struct agp_bridge_data *bridge, | ||
334 | int type) | ||
335 | { | ||
336 | unsigned int type_mask = type & ~AGP_USER_CACHED_MEMORY_GFDT; | ||
337 | unsigned int gfdt = type & AGP_USER_CACHED_MEMORY_GFDT; | ||
338 | |||
339 | if (type_mask == AGP_USER_UNCACHED_MEMORY) | ||
340 | return INTEL_AGP_UNCACHED_MEMORY; | ||
341 | else if (type_mask == AGP_USER_CACHED_MEMORY_LLC_MLC) | ||
342 | return gfdt ? INTEL_AGP_CACHED_MEMORY_LLC_MLC_GFDT : | ||
343 | INTEL_AGP_CACHED_MEMORY_LLC_MLC; | ||
344 | else /* set 'normal'/'cached' to LLC by default */ | ||
345 | return gfdt ? INTEL_AGP_CACHED_MEMORY_LLC_GFDT : | ||
346 | INTEL_AGP_CACHED_MEMORY_LLC; | ||
347 | } | ||
348 | |||
349 | |||
320 | static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start, | 350 | static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start, |
321 | int type) | 351 | int type) |
322 | { | 352 | { |
@@ -588,8 +618,7 @@ static void intel_i830_init_gtt_entries(void) | |||
588 | gtt_entries = 0; | 618 | gtt_entries = 0; |
589 | break; | 619 | break; |
590 | } | 620 | } |
591 | } else if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB || | 621 | } else if (IS_SNB) { |
592 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB) { | ||
593 | /* | 622 | /* |
594 | * SandyBridge has new memory control reg at 0x50.w | 623 | * SandyBridge has new memory control reg at 0x50.w |
595 | */ | 624 | */ |
@@ -1068,11 +1097,11 @@ static void intel_i9xx_setup_flush(void) | |||
1068 | intel_i915_setup_chipset_flush(); | 1097 | intel_i915_setup_chipset_flush(); |
1069 | } | 1098 | } |
1070 | 1099 | ||
1071 | if (intel_private.ifp_resource.start) { | 1100 | if (intel_private.ifp_resource.start) |
1072 | intel_private.i9xx_flush_page = ioremap_nocache(intel_private.ifp_resource.start, PAGE_SIZE); | 1101 | intel_private.i9xx_flush_page = ioremap_nocache(intel_private.ifp_resource.start, PAGE_SIZE); |
1073 | if (!intel_private.i9xx_flush_page) | 1102 | if (!intel_private.i9xx_flush_page) |
1074 | dev_info(&intel_private.pcidev->dev, "can't ioremap flush page - no chipset flushing"); | 1103 | dev_err(&intel_private.pcidev->dev, |
1075 | } | 1104 | "can't ioremap flush page - no chipset flushing\n"); |
1076 | } | 1105 | } |
1077 | 1106 | ||
1078 | static int intel_i9xx_configure(void) | 1107 | static int intel_i9xx_configure(void) |
@@ -1163,7 +1192,7 @@ static int intel_i915_insert_entries(struct agp_memory *mem, off_t pg_start, | |||
1163 | 1192 | ||
1164 | mask_type = agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type); | 1193 | mask_type = agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type); |
1165 | 1194 | ||
1166 | if (mask_type != 0 && mask_type != AGP_PHYS_MEMORY && | 1195 | if (!IS_SNB && mask_type != 0 && mask_type != AGP_PHYS_MEMORY && |
1167 | mask_type != INTEL_AGP_CACHED_MEMORY) | 1196 | mask_type != INTEL_AGP_CACHED_MEMORY) |
1168 | goto out_err; | 1197 | goto out_err; |
1169 | 1198 | ||
@@ -1333,8 +1362,8 @@ static unsigned long intel_i965_mask_memory(struct agp_bridge_data *bridge, | |||
1333 | static unsigned long intel_gen6_mask_memory(struct agp_bridge_data *bridge, | 1362 | static unsigned long intel_gen6_mask_memory(struct agp_bridge_data *bridge, |
1334 | dma_addr_t addr, int type) | 1363 | dma_addr_t addr, int type) |
1335 | { | 1364 | { |
1336 | /* Shift high bits down */ | 1365 | /* gen6 has bit11-4 for physical addr bit39-32 */ |
1337 | addr |= (addr >> 28) & 0xff; | 1366 | addr |= (addr >> 28) & 0xff0; |
1338 | 1367 | ||
1339 | /* Type checking must be done elsewhere */ | 1368 | /* Type checking must be done elsewhere */ |
1340 | return addr | bridge->driver->masks[type].mask; | 1369 | return addr | bridge->driver->masks[type].mask; |
@@ -1359,6 +1388,7 @@ static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size) | |||
1359 | break; | 1388 | break; |
1360 | case PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB: | 1389 | case PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB: |
1361 | case PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB: | 1390 | case PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB: |
1391 | case PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB: | ||
1362 | *gtt_offset = MB(2); | 1392 | *gtt_offset = MB(2); |
1363 | 1393 | ||
1364 | pci_read_config_word(intel_private.pcidev, SNB_GMCH_CTRL, &snb_gmch_ctl); | 1394 | pci_read_config_word(intel_private.pcidev, SNB_GMCH_CTRL, &snb_gmch_ctl); |
@@ -1563,7 +1593,7 @@ static const struct agp_bridge_driver intel_gen6_driver = { | |||
1563 | .fetch_size = intel_i9xx_fetch_size, | 1593 | .fetch_size = intel_i9xx_fetch_size, |
1564 | .cleanup = intel_i915_cleanup, | 1594 | .cleanup = intel_i915_cleanup, |
1565 | .mask_memory = intel_gen6_mask_memory, | 1595 | .mask_memory = intel_gen6_mask_memory, |
1566 | .masks = intel_i810_masks, | 1596 | .masks = intel_gen6_masks, |
1567 | .agp_enable = intel_i810_agp_enable, | 1597 | .agp_enable = intel_i810_agp_enable, |
1568 | .cache_flush = global_cache_flush, | 1598 | .cache_flush = global_cache_flush, |
1569 | .create_gatt_table = intel_i965_create_gatt_table, | 1599 | .create_gatt_table = intel_i965_create_gatt_table, |
@@ -1576,7 +1606,7 @@ static const struct agp_bridge_driver intel_gen6_driver = { | |||
1576 | .agp_alloc_pages = agp_generic_alloc_pages, | 1606 | .agp_alloc_pages = agp_generic_alloc_pages, |
1577 | .agp_destroy_page = agp_generic_destroy_page, | 1607 | .agp_destroy_page = agp_generic_destroy_page, |
1578 | .agp_destroy_pages = agp_generic_destroy_pages, | 1608 | .agp_destroy_pages = agp_generic_destroy_pages, |
1579 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, | 1609 | .agp_type_to_mask_type = intel_gen6_type_to_mask_type, |
1580 | .chipset_flush = intel_i915_chipset_flush, | 1610 | .chipset_flush = intel_i915_chipset_flush, |
1581 | #ifdef USE_PCI_DMA_API | 1611 | #ifdef USE_PCI_DMA_API |
1582 | .agp_map_page = intel_agp_map_page, | 1612 | .agp_map_page = intel_agp_map_page, |
diff --git a/drivers/char/hangcheck-timer.c b/drivers/char/hangcheck-timer.c index e0249722d25..f953c96efc8 100644 --- a/drivers/char/hangcheck-timer.c +++ b/drivers/char/hangcheck-timer.c | |||
@@ -159,7 +159,7 @@ static void hangcheck_fire(unsigned long data) | |||
159 | if (hangcheck_dump_tasks) { | 159 | if (hangcheck_dump_tasks) { |
160 | printk(KERN_CRIT "Hangcheck: Task state:\n"); | 160 | printk(KERN_CRIT "Hangcheck: Task state:\n"); |
161 | #ifdef CONFIG_MAGIC_SYSRQ | 161 | #ifdef CONFIG_MAGIC_SYSRQ |
162 | handle_sysrq('t', NULL); | 162 | handle_sysrq('t'); |
163 | #endif /* CONFIG_MAGIC_SYSRQ */ | 163 | #endif /* CONFIG_MAGIC_SYSRQ */ |
164 | } | 164 | } |
165 | if (hangcheck_reboot) { | 165 | if (hangcheck_reboot) { |
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index fa27d1676ee..3afd62e856e 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c | |||
@@ -651,7 +651,7 @@ int hvc_poll(struct hvc_struct *hp) | |||
651 | if (sysrq_pressed) | 651 | if (sysrq_pressed) |
652 | continue; | 652 | continue; |
653 | } else if (sysrq_pressed) { | 653 | } else if (sysrq_pressed) { |
654 | handle_sysrq(buf[i], tty); | 654 | handle_sysrq(buf[i]); |
655 | sysrq_pressed = 0; | 655 | sysrq_pressed = 0; |
656 | continue; | 656 | continue; |
657 | } | 657 | } |
diff --git a/drivers/char/hvsi.c b/drivers/char/hvsi.c index 1f4b6de65a2..a2bc885ce60 100644 --- a/drivers/char/hvsi.c +++ b/drivers/char/hvsi.c | |||
@@ -403,7 +403,7 @@ static void hvsi_insert_chars(struct hvsi_struct *hp, const char *buf, int len) | |||
403 | hp->sysrq = 1; | 403 | hp->sysrq = 1; |
404 | continue; | 404 | continue; |
405 | } else if (hp->sysrq) { | 405 | } else if (hp->sysrq) { |
406 | handle_sysrq(c, hp->tty); | 406 | handle_sysrq(c); |
407 | hp->sysrq = 0; | 407 | hp->sysrq = 0; |
408 | continue; | 408 | continue; |
409 | } | 409 | } |
diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c index 1acdb250951..a3f5e381e74 100644 --- a/drivers/char/hw_random/n2-drv.c +++ b/drivers/char/hw_random/n2-drv.c | |||
@@ -387,7 +387,7 @@ static int n2rng_init_control(struct n2rng *np) | |||
387 | 387 | ||
388 | static int n2rng_data_read(struct hwrng *rng, u32 *data) | 388 | static int n2rng_data_read(struct hwrng *rng, u32 *data) |
389 | { | 389 | { |
390 | struct n2rng *np = rng->priv; | 390 | struct n2rng *np = (struct n2rng *) rng->priv; |
391 | unsigned long ra = __pa(&np->test_data); | 391 | unsigned long ra = __pa(&np->test_data); |
392 | int len; | 392 | int len; |
393 | 393 | ||
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c index 07f3ea38b58..d4b71e8d0d2 100644 --- a/drivers/char/ip2/ip2main.c +++ b/drivers/char/ip2/ip2main.c | |||
@@ -1650,7 +1650,7 @@ ip2_close( PTTY tty, struct file *pFile ) | |||
1650 | /* disable DSS reporting */ | 1650 | /* disable DSS reporting */ |
1651 | i2QueueCommands(PTYPE_INLINE, pCh, 100, 4, | 1651 | i2QueueCommands(PTYPE_INLINE, pCh, 100, 4, |
1652 | CMD_DCD_NREP, CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP); | 1652 | CMD_DCD_NREP, CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP); |
1653 | if ( !tty || (tty->termios->c_cflag & HUPCL) ) { | 1653 | if (tty->termios->c_cflag & HUPCL) { |
1654 | i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN); | 1654 | i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN); |
1655 | pCh->dataSetOut &= ~(I2_DTR | I2_RTS); | 1655 | pCh->dataSetOut &= ~(I2_DTR | I2_RTS); |
1656 | i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25)); | 1656 | i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25)); |
@@ -2930,6 +2930,8 @@ ip2_ipl_ioctl (struct file *pFile, UINT cmd, ULONG arg ) | |||
2930 | if ( pCh ) | 2930 | if ( pCh ) |
2931 | { | 2931 | { |
2932 | rc = copy_to_user(argp, pCh, sizeof(i2ChanStr)); | 2932 | rc = copy_to_user(argp, pCh, sizeof(i2ChanStr)); |
2933 | if (rc) | ||
2934 | rc = -EFAULT; | ||
2933 | } else { | 2935 | } else { |
2934 | rc = -ENODEV; | 2936 | rc = -ENODEV; |
2935 | } | 2937 | } |
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 3822b4f49c8..7bd7c45b53e 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -305,6 +305,9 @@ static int num_force_kipmid; | |||
305 | #ifdef CONFIG_PCI | 305 | #ifdef CONFIG_PCI |
306 | static int pci_registered; | 306 | static int pci_registered; |
307 | #endif | 307 | #endif |
308 | #ifdef CONFIG_ACPI | ||
309 | static int pnp_registered; | ||
310 | #endif | ||
308 | #ifdef CONFIG_PPC_OF | 311 | #ifdef CONFIG_PPC_OF |
309 | static int of_registered; | 312 | static int of_registered; |
310 | #endif | 313 | #endif |
@@ -2126,7 +2129,7 @@ static int __devinit ipmi_pnp_probe(struct pnp_dev *dev, | |||
2126 | { | 2129 | { |
2127 | struct acpi_device *acpi_dev; | 2130 | struct acpi_device *acpi_dev; |
2128 | struct smi_info *info; | 2131 | struct smi_info *info; |
2129 | struct resource *res; | 2132 | struct resource *res, *res_second; |
2130 | acpi_handle handle; | 2133 | acpi_handle handle; |
2131 | acpi_status status; | 2134 | acpi_status status; |
2132 | unsigned long long tmp; | 2135 | unsigned long long tmp; |
@@ -2182,13 +2185,13 @@ static int __devinit ipmi_pnp_probe(struct pnp_dev *dev, | |||
2182 | info->io.addr_data = res->start; | 2185 | info->io.addr_data = res->start; |
2183 | 2186 | ||
2184 | info->io.regspacing = DEFAULT_REGSPACING; | 2187 | info->io.regspacing = DEFAULT_REGSPACING; |
2185 | res = pnp_get_resource(dev, | 2188 | res_second = pnp_get_resource(dev, |
2186 | (info->io.addr_type == IPMI_IO_ADDR_SPACE) ? | 2189 | (info->io.addr_type == IPMI_IO_ADDR_SPACE) ? |
2187 | IORESOURCE_IO : IORESOURCE_MEM, | 2190 | IORESOURCE_IO : IORESOURCE_MEM, |
2188 | 1); | 2191 | 1); |
2189 | if (res) { | 2192 | if (res_second) { |
2190 | if (res->start > info->io.addr_data) | 2193 | if (res_second->start > info->io.addr_data) |
2191 | info->io.regspacing = res->start - info->io.addr_data; | 2194 | info->io.regspacing = res_second->start - info->io.addr_data; |
2192 | } | 2195 | } |
2193 | info->io.regsize = DEFAULT_REGSPACING; | 2196 | info->io.regsize = DEFAULT_REGSPACING; |
2194 | info->io.regshift = 0; | 2197 | info->io.regshift = 0; |
@@ -3359,6 +3362,7 @@ static __devinit int init_ipmi_si(void) | |||
3359 | 3362 | ||
3360 | #ifdef CONFIG_ACPI | 3363 | #ifdef CONFIG_ACPI |
3361 | pnp_register_driver(&ipmi_pnp_driver); | 3364 | pnp_register_driver(&ipmi_pnp_driver); |
3365 | pnp_registered = 1; | ||
3362 | #endif | 3366 | #endif |
3363 | 3367 | ||
3364 | #ifdef CONFIG_DMI | 3368 | #ifdef CONFIG_DMI |
@@ -3526,7 +3530,8 @@ static __exit void cleanup_ipmi_si(void) | |||
3526 | pci_unregister_driver(&ipmi_pci_driver); | 3530 | pci_unregister_driver(&ipmi_pci_driver); |
3527 | #endif | 3531 | #endif |
3528 | #ifdef CONFIG_ACPI | 3532 | #ifdef CONFIG_ACPI |
3529 | pnp_unregister_driver(&ipmi_pnp_driver); | 3533 | if (pnp_registered) |
3534 | pnp_unregister_driver(&ipmi_pnp_driver); | ||
3530 | #endif | 3535 | #endif |
3531 | 3536 | ||
3532 | #ifdef CONFIG_PPC_OF | 3537 | #ifdef CONFIG_PPC_OF |
diff --git a/drivers/char/mem.c b/drivers/char/mem.c index a398ecdbd75..1f528fad351 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c | |||
@@ -788,10 +788,11 @@ static const struct file_operations zero_fops = { | |||
788 | /* | 788 | /* |
789 | * capabilities for /dev/zero | 789 | * capabilities for /dev/zero |
790 | * - permits private mappings, "copies" are taken of the source of zeros | 790 | * - permits private mappings, "copies" are taken of the source of zeros |
791 | * - no writeback happens | ||
791 | */ | 792 | */ |
792 | static struct backing_dev_info zero_bdi = { | 793 | static struct backing_dev_info zero_bdi = { |
793 | .name = "char/mem", | 794 | .name = "char/mem", |
794 | .capabilities = BDI_CAP_MAP_COPY, | 795 | .capabilities = BDI_CAP_MAP_COPY | BDI_CAP_NO_ACCT_AND_WRITEBACK, |
795 | }; | 796 | }; |
796 | 797 | ||
797 | static const struct file_operations full_fops = { | 798 | static const struct file_operations full_fops = { |
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c index 79c3bc69165..7c79d243acc 100644 --- a/drivers/char/rocket.c +++ b/drivers/char/rocket.c | |||
@@ -1244,6 +1244,7 @@ static int set_config(struct tty_struct *tty, struct r_port *info, | |||
1244 | } | 1244 | } |
1245 | info->flags = ((info->flags & ~ROCKET_USR_MASK) | (new_serial.flags & ROCKET_USR_MASK)); | 1245 | info->flags = ((info->flags & ~ROCKET_USR_MASK) | (new_serial.flags & ROCKET_USR_MASK)); |
1246 | configure_r_port(tty, info, NULL); | 1246 | configure_r_port(tty, info, NULL); |
1247 | mutex_unlock(&info->port.mutex); | ||
1247 | return 0; | 1248 | return 0; |
1248 | } | 1249 | } |
1249 | 1250 | ||
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index fef80cfcab5..e63b830c86c 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c | |||
@@ -691,8 +691,10 @@ static int open(struct tty_struct *tty, struct file *filp) | |||
691 | if (info->port.count == 1) { | 691 | if (info->port.count == 1) { |
692 | /* 1st open on this device, init hardware */ | 692 | /* 1st open on this device, init hardware */ |
693 | retval = startup(info); | 693 | retval = startup(info); |
694 | if (retval < 0) | 694 | if (retval < 0) { |
695 | mutex_unlock(&info->port.mutex); | ||
695 | goto cleanup; | 696 | goto cleanup; |
697 | } | ||
696 | } | 698 | } |
697 | mutex_unlock(&info->port.mutex); | 699 | mutex_unlock(&info->port.mutex); |
698 | retval = block_til_ready(tty, filp, info); | 700 | retval = block_til_ready(tty, filp, info); |
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index 878ac0c2cc6..ef31bb81e84 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
19 | #include <linux/mm.h> | 19 | #include <linux/mm.h> |
20 | #include <linux/fs.h> | 20 | #include <linux/fs.h> |
21 | #include <linux/tty.h> | ||
22 | #include <linux/mount.h> | 21 | #include <linux/mount.h> |
23 | #include <linux/kdev_t.h> | 22 | #include <linux/kdev_t.h> |
24 | #include <linux/major.h> | 23 | #include <linux/major.h> |
@@ -76,7 +75,7 @@ static int __init sysrq_always_enabled_setup(char *str) | |||
76 | __setup("sysrq_always_enabled", sysrq_always_enabled_setup); | 75 | __setup("sysrq_always_enabled", sysrq_always_enabled_setup); |
77 | 76 | ||
78 | 77 | ||
79 | static void sysrq_handle_loglevel(int key, struct tty_struct *tty) | 78 | static void sysrq_handle_loglevel(int key) |
80 | { | 79 | { |
81 | int i; | 80 | int i; |
82 | 81 | ||
@@ -93,7 +92,7 @@ static struct sysrq_key_op sysrq_loglevel_op = { | |||
93 | }; | 92 | }; |
94 | 93 | ||
95 | #ifdef CONFIG_VT | 94 | #ifdef CONFIG_VT |
96 | static void sysrq_handle_SAK(int key, struct tty_struct *tty) | 95 | static void sysrq_handle_SAK(int key) |
97 | { | 96 | { |
98 | struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work; | 97 | struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work; |
99 | schedule_work(SAK_work); | 98 | schedule_work(SAK_work); |
@@ -109,7 +108,7 @@ static struct sysrq_key_op sysrq_SAK_op = { | |||
109 | #endif | 108 | #endif |
110 | 109 | ||
111 | #ifdef CONFIG_VT | 110 | #ifdef CONFIG_VT |
112 | static void sysrq_handle_unraw(int key, struct tty_struct *tty) | 111 | static void sysrq_handle_unraw(int key) |
113 | { | 112 | { |
114 | struct kbd_struct *kbd = &kbd_table[fg_console]; | 113 | struct kbd_struct *kbd = &kbd_table[fg_console]; |
115 | 114 | ||
@@ -126,7 +125,7 @@ static struct sysrq_key_op sysrq_unraw_op = { | |||
126 | #define sysrq_unraw_op (*(struct sysrq_key_op *)NULL) | 125 | #define sysrq_unraw_op (*(struct sysrq_key_op *)NULL) |
127 | #endif /* CONFIG_VT */ | 126 | #endif /* CONFIG_VT */ |
128 | 127 | ||
129 | static void sysrq_handle_crash(int key, struct tty_struct *tty) | 128 | static void sysrq_handle_crash(int key) |
130 | { | 129 | { |
131 | char *killer = NULL; | 130 | char *killer = NULL; |
132 | 131 | ||
@@ -141,7 +140,7 @@ static struct sysrq_key_op sysrq_crash_op = { | |||
141 | .enable_mask = SYSRQ_ENABLE_DUMP, | 140 | .enable_mask = SYSRQ_ENABLE_DUMP, |
142 | }; | 141 | }; |
143 | 142 | ||
144 | static void sysrq_handle_reboot(int key, struct tty_struct *tty) | 143 | static void sysrq_handle_reboot(int key) |
145 | { | 144 | { |
146 | lockdep_off(); | 145 | lockdep_off(); |
147 | local_irq_enable(); | 146 | local_irq_enable(); |
@@ -154,7 +153,7 @@ static struct sysrq_key_op sysrq_reboot_op = { | |||
154 | .enable_mask = SYSRQ_ENABLE_BOOT, | 153 | .enable_mask = SYSRQ_ENABLE_BOOT, |
155 | }; | 154 | }; |
156 | 155 | ||
157 | static void sysrq_handle_sync(int key, struct tty_struct *tty) | 156 | static void sysrq_handle_sync(int key) |
158 | { | 157 | { |
159 | emergency_sync(); | 158 | emergency_sync(); |
160 | } | 159 | } |
@@ -165,7 +164,7 @@ static struct sysrq_key_op sysrq_sync_op = { | |||
165 | .enable_mask = SYSRQ_ENABLE_SYNC, | 164 | .enable_mask = SYSRQ_ENABLE_SYNC, |
166 | }; | 165 | }; |
167 | 166 | ||
168 | static void sysrq_handle_show_timers(int key, struct tty_struct *tty) | 167 | static void sysrq_handle_show_timers(int key) |
169 | { | 168 | { |
170 | sysrq_timer_list_show(); | 169 | sysrq_timer_list_show(); |
171 | } | 170 | } |
@@ -176,7 +175,7 @@ static struct sysrq_key_op sysrq_show_timers_op = { | |||
176 | .action_msg = "Show clockevent devices & pending hrtimers (no others)", | 175 | .action_msg = "Show clockevent devices & pending hrtimers (no others)", |
177 | }; | 176 | }; |
178 | 177 | ||
179 | static void sysrq_handle_mountro(int key, struct tty_struct *tty) | 178 | static void sysrq_handle_mountro(int key) |
180 | { | 179 | { |
181 | emergency_remount(); | 180 | emergency_remount(); |
182 | } | 181 | } |
@@ -188,7 +187,7 @@ static struct sysrq_key_op sysrq_mountro_op = { | |||
188 | }; | 187 | }; |
189 | 188 | ||
190 | #ifdef CONFIG_LOCKDEP | 189 | #ifdef CONFIG_LOCKDEP |
191 | static void sysrq_handle_showlocks(int key, struct tty_struct *tty) | 190 | static void sysrq_handle_showlocks(int key) |
192 | { | 191 | { |
193 | debug_show_all_locks(); | 192 | debug_show_all_locks(); |
194 | } | 193 | } |
@@ -226,7 +225,7 @@ static void sysrq_showregs_othercpus(struct work_struct *dummy) | |||
226 | 225 | ||
227 | static DECLARE_WORK(sysrq_showallcpus, sysrq_showregs_othercpus); | 226 | static DECLARE_WORK(sysrq_showallcpus, sysrq_showregs_othercpus); |
228 | 227 | ||
229 | static void sysrq_handle_showallcpus(int key, struct tty_struct *tty) | 228 | static void sysrq_handle_showallcpus(int key) |
230 | { | 229 | { |
231 | /* | 230 | /* |
232 | * Fall back to the workqueue based printing if the | 231 | * Fall back to the workqueue based printing if the |
@@ -252,7 +251,7 @@ static struct sysrq_key_op sysrq_showallcpus_op = { | |||
252 | }; | 251 | }; |
253 | #endif | 252 | #endif |
254 | 253 | ||
255 | static void sysrq_handle_showregs(int key, struct tty_struct *tty) | 254 | static void sysrq_handle_showregs(int key) |
256 | { | 255 | { |
257 | struct pt_regs *regs = get_irq_regs(); | 256 | struct pt_regs *regs = get_irq_regs(); |
258 | if (regs) | 257 | if (regs) |
@@ -266,7 +265,7 @@ static struct sysrq_key_op sysrq_showregs_op = { | |||
266 | .enable_mask = SYSRQ_ENABLE_DUMP, | 265 | .enable_mask = SYSRQ_ENABLE_DUMP, |
267 | }; | 266 | }; |
268 | 267 | ||
269 | static void sysrq_handle_showstate(int key, struct tty_struct *tty) | 268 | static void sysrq_handle_showstate(int key) |
270 | { | 269 | { |
271 | show_state(); | 270 | show_state(); |
272 | } | 271 | } |
@@ -277,7 +276,7 @@ static struct sysrq_key_op sysrq_showstate_op = { | |||
277 | .enable_mask = SYSRQ_ENABLE_DUMP, | 276 | .enable_mask = SYSRQ_ENABLE_DUMP, |
278 | }; | 277 | }; |
279 | 278 | ||
280 | static void sysrq_handle_showstate_blocked(int key, struct tty_struct *tty) | 279 | static void sysrq_handle_showstate_blocked(int key) |
281 | { | 280 | { |
282 | show_state_filter(TASK_UNINTERRUPTIBLE); | 281 | show_state_filter(TASK_UNINTERRUPTIBLE); |
283 | } | 282 | } |
@@ -291,7 +290,7 @@ static struct sysrq_key_op sysrq_showstate_blocked_op = { | |||
291 | #ifdef CONFIG_TRACING | 290 | #ifdef CONFIG_TRACING |
292 | #include <linux/ftrace.h> | 291 | #include <linux/ftrace.h> |
293 | 292 | ||
294 | static void sysrq_ftrace_dump(int key, struct tty_struct *tty) | 293 | static void sysrq_ftrace_dump(int key) |
295 | { | 294 | { |
296 | ftrace_dump(DUMP_ALL); | 295 | ftrace_dump(DUMP_ALL); |
297 | } | 296 | } |
@@ -305,7 +304,7 @@ static struct sysrq_key_op sysrq_ftrace_dump_op = { | |||
305 | #define sysrq_ftrace_dump_op (*(struct sysrq_key_op *)NULL) | 304 | #define sysrq_ftrace_dump_op (*(struct sysrq_key_op *)NULL) |
306 | #endif | 305 | #endif |
307 | 306 | ||
308 | static void sysrq_handle_showmem(int key, struct tty_struct *tty) | 307 | static void sysrq_handle_showmem(int key) |
309 | { | 308 | { |
310 | show_mem(); | 309 | show_mem(); |
311 | } | 310 | } |
@@ -330,7 +329,7 @@ static void send_sig_all(int sig) | |||
330 | } | 329 | } |
331 | } | 330 | } |
332 | 331 | ||
333 | static void sysrq_handle_term(int key, struct tty_struct *tty) | 332 | static void sysrq_handle_term(int key) |
334 | { | 333 | { |
335 | send_sig_all(SIGTERM); | 334 | send_sig_all(SIGTERM); |
336 | console_loglevel = 8; | 335 | console_loglevel = 8; |
@@ -349,7 +348,7 @@ static void moom_callback(struct work_struct *ignored) | |||
349 | 348 | ||
350 | static DECLARE_WORK(moom_work, moom_callback); | 349 | static DECLARE_WORK(moom_work, moom_callback); |
351 | 350 | ||
352 | static void sysrq_handle_moom(int key, struct tty_struct *tty) | 351 | static void sysrq_handle_moom(int key) |
353 | { | 352 | { |
354 | schedule_work(&moom_work); | 353 | schedule_work(&moom_work); |
355 | } | 354 | } |
@@ -361,7 +360,7 @@ static struct sysrq_key_op sysrq_moom_op = { | |||
361 | }; | 360 | }; |
362 | 361 | ||
363 | #ifdef CONFIG_BLOCK | 362 | #ifdef CONFIG_BLOCK |
364 | static void sysrq_handle_thaw(int key, struct tty_struct *tty) | 363 | static void sysrq_handle_thaw(int key) |
365 | { | 364 | { |
366 | emergency_thaw_all(); | 365 | emergency_thaw_all(); |
367 | } | 366 | } |
@@ -373,7 +372,7 @@ static struct sysrq_key_op sysrq_thaw_op = { | |||
373 | }; | 372 | }; |
374 | #endif | 373 | #endif |
375 | 374 | ||
376 | static void sysrq_handle_kill(int key, struct tty_struct *tty) | 375 | static void sysrq_handle_kill(int key) |
377 | { | 376 | { |
378 | send_sig_all(SIGKILL); | 377 | send_sig_all(SIGKILL); |
379 | console_loglevel = 8; | 378 | console_loglevel = 8; |
@@ -385,7 +384,7 @@ static struct sysrq_key_op sysrq_kill_op = { | |||
385 | .enable_mask = SYSRQ_ENABLE_SIGNAL, | 384 | .enable_mask = SYSRQ_ENABLE_SIGNAL, |
386 | }; | 385 | }; |
387 | 386 | ||
388 | static void sysrq_handle_unrt(int key, struct tty_struct *tty) | 387 | static void sysrq_handle_unrt(int key) |
389 | { | 388 | { |
390 | normalize_rt_tasks(); | 389 | normalize_rt_tasks(); |
391 | } | 390 | } |
@@ -493,7 +492,7 @@ static void __sysrq_put_key_op(int key, struct sysrq_key_op *op_p) | |||
493 | sysrq_key_table[i] = op_p; | 492 | sysrq_key_table[i] = op_p; |
494 | } | 493 | } |
495 | 494 | ||
496 | void __handle_sysrq(int key, struct tty_struct *tty, int check_mask) | 495 | void __handle_sysrq(int key, bool check_mask) |
497 | { | 496 | { |
498 | struct sysrq_key_op *op_p; | 497 | struct sysrq_key_op *op_p; |
499 | int orig_log_level; | 498 | int orig_log_level; |
@@ -520,7 +519,7 @@ void __handle_sysrq(int key, struct tty_struct *tty, int check_mask) | |||
520 | if (!check_mask || sysrq_on_mask(op_p->enable_mask)) { | 519 | if (!check_mask || sysrq_on_mask(op_p->enable_mask)) { |
521 | printk("%s\n", op_p->action_msg); | 520 | printk("%s\n", op_p->action_msg); |
522 | console_loglevel = orig_log_level; | 521 | console_loglevel = orig_log_level; |
523 | op_p->handler(key, tty); | 522 | op_p->handler(key); |
524 | } else { | 523 | } else { |
525 | printk("This sysrq operation is disabled.\n"); | 524 | printk("This sysrq operation is disabled.\n"); |
526 | } | 525 | } |
@@ -545,10 +544,10 @@ void __handle_sysrq(int key, struct tty_struct *tty, int check_mask) | |||
545 | spin_unlock_irqrestore(&sysrq_key_table_lock, flags); | 544 | spin_unlock_irqrestore(&sysrq_key_table_lock, flags); |
546 | } | 545 | } |
547 | 546 | ||
548 | void handle_sysrq(int key, struct tty_struct *tty) | 547 | void handle_sysrq(int key) |
549 | { | 548 | { |
550 | if (sysrq_on()) | 549 | if (sysrq_on()) |
551 | __handle_sysrq(key, tty, 1); | 550 | __handle_sysrq(key, true); |
552 | } | 551 | } |
553 | EXPORT_SYMBOL(handle_sysrq); | 552 | EXPORT_SYMBOL(handle_sysrq); |
554 | 553 | ||
@@ -597,7 +596,7 @@ static bool sysrq_filter(struct input_handle *handle, unsigned int type, | |||
597 | 596 | ||
598 | default: | 597 | default: |
599 | if (sysrq_down && value && value != 2) | 598 | if (sysrq_down && value && value != 2) |
600 | __handle_sysrq(sysrq_xlate[code], NULL, 1); | 599 | __handle_sysrq(sysrq_xlate[code], true); |
601 | break; | 600 | break; |
602 | } | 601 | } |
603 | 602 | ||
@@ -765,7 +764,7 @@ static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf, | |||
765 | 764 | ||
766 | if (get_user(c, buf)) | 765 | if (get_user(c, buf)) |
767 | return -EFAULT; | 766 | return -EFAULT; |
768 | __handle_sysrq(c, NULL, 0); | 767 | __handle_sysrq(c, false); |
769 | } | 768 | } |
770 | 769 | ||
771 | return count; | 770 | return count; |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 949067a0bd4..613c852ee0f 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -355,7 +355,7 @@ struct tty_driver *tty_find_polling_driver(char *name, int *line) | |||
355 | if (*stp == '\0') | 355 | if (*stp == '\0') |
356 | stp = NULL; | 356 | stp = NULL; |
357 | 357 | ||
358 | if (tty_line >= 0 && tty_line <= p->num && p->ops && | 358 | if (tty_line >= 0 && tty_line < p->num && p->ops && |
359 | p->ops->poll_init && !p->ops->poll_init(p, tty_line, stp)) { | 359 | p->ops->poll_init && !p->ops->poll_init(p, tty_line, stp)) { |
360 | res = tty_driver_kref_get(p); | 360 | res = tty_driver_kref_get(p); |
361 | *line = tty_line; | 361 | *line = tty_line; |
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 942a9826bd2..c810481a5bc 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c | |||
@@ -596,6 +596,10 @@ static ssize_t port_fops_write(struct file *filp, const char __user *ubuf, | |||
596 | ssize_t ret; | 596 | ssize_t ret; |
597 | bool nonblock; | 597 | bool nonblock; |
598 | 598 | ||
599 | /* Userspace could be out to fool us */ | ||
600 | if (!count) | ||
601 | return 0; | ||
602 | |||
599 | port = filp->private_data; | 603 | port = filp->private_data; |
600 | 604 | ||
601 | nonblock = filp->f_flags & O_NONBLOCK; | 605 | nonblock = filp->f_flags & O_NONBLOCK; |
@@ -642,7 +646,7 @@ static unsigned int port_fops_poll(struct file *filp, poll_table *wait) | |||
642 | poll_wait(filp, &port->waitqueue, wait); | 646 | poll_wait(filp, &port->waitqueue, wait); |
643 | 647 | ||
644 | ret = 0; | 648 | ret = 0; |
645 | if (port->inbuf) | 649 | if (!will_read_block(port)) |
646 | ret |= POLLIN | POLLRDNORM; | 650 | ret |= POLLIN | POLLRDNORM; |
647 | if (!will_write_block(port)) | 651 | if (!will_write_block(port)) |
648 | ret |= POLLOUT; | 652 | ret |= POLLOUT; |
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 50590c7f2c0..281aada7b4a 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -906,22 +906,16 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc, | |||
906 | * bottom of buffer | 906 | * bottom of buffer |
907 | */ | 907 | */ |
908 | old_origin += (old_rows - new_rows) * old_row_size; | 908 | old_origin += (old_rows - new_rows) * old_row_size; |
909 | end = vc->vc_scr_end; | ||
910 | } else { | 909 | } else { |
911 | /* | 910 | /* |
912 | * Cursor is in no man's land, copy 1/2 screenful | 911 | * Cursor is in no man's land, copy 1/2 screenful |
913 | * from the top and bottom of cursor position | 912 | * from the top and bottom of cursor position |
914 | */ | 913 | */ |
915 | old_origin += (vc->vc_y - new_rows/2) * old_row_size; | 914 | old_origin += (vc->vc_y - new_rows/2) * old_row_size; |
916 | end = old_origin + (old_row_size * new_rows); | ||
917 | } | 915 | } |
918 | } else | 916 | } |
919 | /* | 917 | |
920 | * Cursor near the top, copy contents from the top of buffer | 918 | end = old_origin + old_row_size * min(old_rows, new_rows); |
921 | */ | ||
922 | end = (old_rows > new_rows) ? old_origin + | ||
923 | (old_row_size * new_rows) : | ||
924 | vc->vc_scr_end; | ||
925 | 919 | ||
926 | update_attr(vc); | 920 | update_attr(vc); |
927 | 921 | ||
@@ -3075,8 +3069,7 @@ static int bind_con_driver(const struct consw *csw, int first, int last, | |||
3075 | 3069 | ||
3076 | old_was_color = vc->vc_can_do_color; | 3070 | old_was_color = vc->vc_can_do_color; |
3077 | vc->vc_sw->con_deinit(vc); | 3071 | vc->vc_sw->con_deinit(vc); |
3078 | if (!vc->vc_origin) | 3072 | vc->vc_origin = (unsigned long)vc->vc_screenbuf; |
3079 | vc->vc_origin = (unsigned long)vc->vc_screenbuf; | ||
3080 | visual_init(vc, i, 0); | 3073 | visual_init(vc, i, 0); |
3081 | set_origin(vc); | 3074 | set_origin(vc); |
3082 | update_attr(vc); | 3075 | update_attr(vc); |
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index 2bbeaaea46e..38df8c19e74 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c | |||
@@ -533,11 +533,14 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
533 | case KIOCSOUND: | 533 | case KIOCSOUND: |
534 | if (!perm) | 534 | if (!perm) |
535 | goto eperm; | 535 | goto eperm; |
536 | /* FIXME: This is an old broken API but we need to keep it | 536 | /* |
537 | supported and somehow separate the historic advertised | 537 | * The use of PIT_TICK_RATE is historic, it used to be |
538 | tick rate from any real one */ | 538 | * the platform-dependent CLOCK_TICK_RATE between 2.6.12 |
539 | * and 2.6.36, which was a minor but unfortunate ABI | ||
540 | * change. | ||
541 | */ | ||
539 | if (arg) | 542 | if (arg) |
540 | arg = CLOCK_TICK_RATE / arg; | 543 | arg = PIT_TICK_RATE / arg; |
541 | kd_mksound(arg, 0); | 544 | kd_mksound(arg, 0); |
542 | break; | 545 | break; |
543 | 546 | ||
@@ -553,11 +556,8 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
553 | */ | 556 | */ |
554 | ticks = HZ * ((arg >> 16) & 0xffff) / 1000; | 557 | ticks = HZ * ((arg >> 16) & 0xffff) / 1000; |
555 | count = ticks ? (arg & 0xffff) : 0; | 558 | count = ticks ? (arg & 0xffff) : 0; |
556 | /* FIXME: This is an old broken API but we need to keep it | ||
557 | supported and somehow separate the historic advertised | ||
558 | tick rate from any real one */ | ||
559 | if (count) | 559 | if (count) |
560 | count = CLOCK_TICK_RATE / count; | 560 | count = PIT_TICK_RATE / count; |
561 | kd_mksound(count, ticks); | 561 | kd_mksound(count, ticks); |
562 | break; | 562 | break; |
563 | } | 563 | } |
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index c2408bbe9c2..f508690eb95 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c | |||
@@ -80,7 +80,7 @@ | |||
80 | * Limiting Performance Impact | 80 | * Limiting Performance Impact |
81 | * --------------------------- | 81 | * --------------------------- |
82 | * C states, especially those with large exit latencies, can have a real | 82 | * C states, especially those with large exit latencies, can have a real |
83 | * noticable impact on workloads, which is not acceptable for most sysadmins, | 83 | * noticeable impact on workloads, which is not acceptable for most sysadmins, |
84 | * and in addition, less performance has a power price of its own. | 84 | * and in addition, less performance has a power price of its own. |
85 | * | 85 | * |
86 | * As a general rule of thumb, menu assumes that the following heuristic | 86 | * As a general rule of thumb, menu assumes that the following heuristic |
diff --git a/drivers/dca/dca-core.c b/drivers/dca/dca-core.c index 8661c84a105..b98c67664ae 100644 --- a/drivers/dca/dca-core.c +++ b/drivers/dca/dca-core.c | |||
@@ -39,6 +39,10 @@ static DEFINE_SPINLOCK(dca_lock); | |||
39 | 39 | ||
40 | static LIST_HEAD(dca_domains); | 40 | static LIST_HEAD(dca_domains); |
41 | 41 | ||
42 | static BLOCKING_NOTIFIER_HEAD(dca_provider_chain); | ||
43 | |||
44 | static int dca_providers_blocked; | ||
45 | |||
42 | static struct pci_bus *dca_pci_rc_from_dev(struct device *dev) | 46 | static struct pci_bus *dca_pci_rc_from_dev(struct device *dev) |
43 | { | 47 | { |
44 | struct pci_dev *pdev = to_pci_dev(dev); | 48 | struct pci_dev *pdev = to_pci_dev(dev); |
@@ -70,6 +74,60 @@ static void dca_free_domain(struct dca_domain *domain) | |||
70 | kfree(domain); | 74 | kfree(domain); |
71 | } | 75 | } |
72 | 76 | ||
77 | static int dca_provider_ioat_ver_3_0(struct device *dev) | ||
78 | { | ||
79 | struct pci_dev *pdev = to_pci_dev(dev); | ||
80 | |||
81 | return ((pdev->vendor == PCI_VENDOR_ID_INTEL) && | ||
82 | ((pdev->device == PCI_DEVICE_ID_INTEL_IOAT_TBG0) || | ||
83 | (pdev->device == PCI_DEVICE_ID_INTEL_IOAT_TBG1) || | ||
84 | (pdev->device == PCI_DEVICE_ID_INTEL_IOAT_TBG2) || | ||
85 | (pdev->device == PCI_DEVICE_ID_INTEL_IOAT_TBG3) || | ||
86 | (pdev->device == PCI_DEVICE_ID_INTEL_IOAT_TBG4) || | ||
87 | (pdev->device == PCI_DEVICE_ID_INTEL_IOAT_TBG5) || | ||
88 | (pdev->device == PCI_DEVICE_ID_INTEL_IOAT_TBG6) || | ||
89 | (pdev->device == PCI_DEVICE_ID_INTEL_IOAT_TBG7))); | ||
90 | } | ||
91 | |||
92 | static void unregister_dca_providers(void) | ||
93 | { | ||
94 | struct dca_provider *dca, *_dca; | ||
95 | struct list_head unregistered_providers; | ||
96 | struct dca_domain *domain; | ||
97 | unsigned long flags; | ||
98 | |||
99 | blocking_notifier_call_chain(&dca_provider_chain, | ||
100 | DCA_PROVIDER_REMOVE, NULL); | ||
101 | |||
102 | INIT_LIST_HEAD(&unregistered_providers); | ||
103 | |||
104 | spin_lock_irqsave(&dca_lock, flags); | ||
105 | |||
106 | if (list_empty(&dca_domains)) { | ||
107 | spin_unlock_irqrestore(&dca_lock, flags); | ||
108 | return; | ||
109 | } | ||
110 | |||
111 | /* at this point only one domain in the list is expected */ | ||
112 | domain = list_first_entry(&dca_domains, struct dca_domain, node); | ||
113 | if (!domain) | ||
114 | return; | ||
115 | |||
116 | list_for_each_entry_safe(dca, _dca, &domain->dca_providers, node) { | ||
117 | list_del(&dca->node); | ||
118 | list_add(&dca->node, &unregistered_providers); | ||
119 | } | ||
120 | |||
121 | dca_free_domain(domain); | ||
122 | |||
123 | spin_unlock_irqrestore(&dca_lock, flags); | ||
124 | |||
125 | list_for_each_entry_safe(dca, _dca, &unregistered_providers, node) { | ||
126 | dca_sysfs_remove_provider(dca); | ||
127 | list_del(&dca->node); | ||
128 | } | ||
129 | } | ||
130 | |||
73 | static struct dca_domain *dca_find_domain(struct pci_bus *rc) | 131 | static struct dca_domain *dca_find_domain(struct pci_bus *rc) |
74 | { | 132 | { |
75 | struct dca_domain *domain; | 133 | struct dca_domain *domain; |
@@ -90,9 +148,13 @@ static struct dca_domain *dca_get_domain(struct device *dev) | |||
90 | domain = dca_find_domain(rc); | 148 | domain = dca_find_domain(rc); |
91 | 149 | ||
92 | if (!domain) { | 150 | if (!domain) { |
93 | domain = dca_allocate_domain(rc); | 151 | if (dca_provider_ioat_ver_3_0(dev) && !list_empty(&dca_domains)) { |
94 | if (domain) | 152 | dca_providers_blocked = 1; |
95 | list_add(&domain->node, &dca_domains); | 153 | } else { |
154 | domain = dca_allocate_domain(rc); | ||
155 | if (domain) | ||
156 | list_add(&domain->node, &dca_domains); | ||
157 | } | ||
96 | } | 158 | } |
97 | 159 | ||
98 | return domain; | 160 | return domain; |
@@ -293,8 +355,6 @@ void free_dca_provider(struct dca_provider *dca) | |||
293 | } | 355 | } |
294 | EXPORT_SYMBOL_GPL(free_dca_provider); | 356 | EXPORT_SYMBOL_GPL(free_dca_provider); |
295 | 357 | ||
296 | static BLOCKING_NOTIFIER_HEAD(dca_provider_chain); | ||
297 | |||
298 | /** | 358 | /** |
299 | * register_dca_provider - register a dca provider | 359 | * register_dca_provider - register a dca provider |
300 | * @dca - struct created by alloc_dca_provider() | 360 | * @dca - struct created by alloc_dca_provider() |
@@ -306,6 +366,13 @@ int register_dca_provider(struct dca_provider *dca, struct device *dev) | |||
306 | unsigned long flags; | 366 | unsigned long flags; |
307 | struct dca_domain *domain; | 367 | struct dca_domain *domain; |
308 | 368 | ||
369 | spin_lock_irqsave(&dca_lock, flags); | ||
370 | if (dca_providers_blocked) { | ||
371 | spin_unlock_irqrestore(&dca_lock, flags); | ||
372 | return -ENODEV; | ||
373 | } | ||
374 | spin_unlock_irqrestore(&dca_lock, flags); | ||
375 | |||
309 | err = dca_sysfs_add_provider(dca, dev); | 376 | err = dca_sysfs_add_provider(dca, dev); |
310 | if (err) | 377 | if (err) |
311 | return err; | 378 | return err; |
@@ -313,7 +380,13 @@ int register_dca_provider(struct dca_provider *dca, struct device *dev) | |||
313 | spin_lock_irqsave(&dca_lock, flags); | 380 | spin_lock_irqsave(&dca_lock, flags); |
314 | domain = dca_get_domain(dev); | 381 | domain = dca_get_domain(dev); |
315 | if (!domain) { | 382 | if (!domain) { |
316 | spin_unlock_irqrestore(&dca_lock, flags); | 383 | if (dca_providers_blocked) { |
384 | spin_unlock_irqrestore(&dca_lock, flags); | ||
385 | dca_sysfs_remove_provider(dca); | ||
386 | unregister_dca_providers(); | ||
387 | } else { | ||
388 | spin_unlock_irqrestore(&dca_lock, flags); | ||
389 | } | ||
317 | return -ENODEV; | 390 | return -ENODEV; |
318 | } | 391 | } |
319 | list_add(&dca->node, &domain->dca_providers); | 392 | list_add(&dca->node, &domain->dca_providers); |
diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c index 216f9d383b5..effd140fc04 100644 --- a/drivers/dma/ioat/dma_v2.c +++ b/drivers/dma/ioat/dma_v2.c | |||
@@ -879,7 +879,7 @@ int __devinit ioat2_dma_probe(struct ioatdma_device *device, int dca) | |||
879 | dma->device_issue_pending = ioat2_issue_pending; | 879 | dma->device_issue_pending = ioat2_issue_pending; |
880 | dma->device_alloc_chan_resources = ioat2_alloc_chan_resources; | 880 | dma->device_alloc_chan_resources = ioat2_alloc_chan_resources; |
881 | dma->device_free_chan_resources = ioat2_free_chan_resources; | 881 | dma->device_free_chan_resources = ioat2_free_chan_resources; |
882 | dma->device_tx_status = ioat_tx_status; | 882 | dma->device_tx_status = ioat_dma_tx_status; |
883 | 883 | ||
884 | err = ioat_probe(device); | 884 | err = ioat_probe(device); |
885 | if (err) | 885 | if (err) |
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 86c5ae9fde3..411d5bf50fc 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c | |||
@@ -162,7 +162,7 @@ static int mv_is_err_intr(u32 intr_cause) | |||
162 | 162 | ||
163 | static void mv_xor_device_clear_eoc_cause(struct mv_xor_chan *chan) | 163 | static void mv_xor_device_clear_eoc_cause(struct mv_xor_chan *chan) |
164 | { | 164 | { |
165 | u32 val = (1 << (1 + (chan->idx * 16))); | 165 | u32 val = ~(1 << (chan->idx * 16)); |
166 | dev_dbg(chan->device->common.dev, "%s, val 0x%08x\n", __func__, val); | 166 | dev_dbg(chan->device->common.dev, "%s, val 0x%08x\n", __func__, val); |
167 | __raw_writel(val, XOR_INTR_CAUSE(chan)); | 167 | __raw_writel(val, XOR_INTR_CAUSE(chan)); |
168 | } | 168 | } |
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index fb64cf36ba6..eb6b54dbb80 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c | |||
@@ -580,7 +580,6 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_slave_sg( | |||
580 | 580 | ||
581 | sh_chan = to_sh_chan(chan); | 581 | sh_chan = to_sh_chan(chan); |
582 | param = chan->private; | 582 | param = chan->private; |
583 | slave_addr = param->config->addr; | ||
584 | 583 | ||
585 | /* Someone calling slave DMA on a public channel? */ | 584 | /* Someone calling slave DMA on a public channel? */ |
586 | if (!param || !sg_len) { | 585 | if (!param || !sg_len) { |
@@ -589,6 +588,8 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_slave_sg( | |||
589 | return NULL; | 588 | return NULL; |
590 | } | 589 | } |
591 | 590 | ||
591 | slave_addr = param->config->addr; | ||
592 | |||
592 | /* | 593 | /* |
593 | * if (param != NULL), this is a successfully requested slave channel, | 594 | * if (param != NULL), this is a successfully requested slave channel, |
594 | * therefore param->config != NULL too. | 595 | * therefore param->config != NULL too. |
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 670239ab751..e7d5d6b5dcf 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c | |||
@@ -2071,16 +2071,6 @@ static inline void __amd64_decode_bus_error(struct mem_ctl_info *mci, | |||
2071 | amd64_handle_ce(mci, info); | 2071 | amd64_handle_ce(mci, info); |
2072 | else if (ecc_type == 1) | 2072 | else if (ecc_type == 1) |
2073 | amd64_handle_ue(mci, info); | 2073 | amd64_handle_ue(mci, info); |
2074 | |||
2075 | /* | ||
2076 | * If main error is CE then overflow must be CE. If main error is UE | ||
2077 | * then overflow is unknown. We'll call the overflow a CE - if | ||
2078 | * panic_on_ue is set then we're already panic'ed and won't arrive | ||
2079 | * here. Else, then apparently someone doesn't think that UE's are | ||
2080 | * catastrophic. | ||
2081 | */ | ||
2082 | if (info->nbsh & K8_NBSH_OVERFLOW) | ||
2083 | edac_mc_handle_ce_no_info(mci, EDAC_MOD_STR " Error Overflow"); | ||
2084 | } | 2074 | } |
2085 | 2075 | ||
2086 | void amd64_decode_bus_error(int node_id, struct err_regs *regs) | 2076 | void amd64_decode_bus_error(int node_id, struct err_regs *regs) |
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index 3630308e7b8..6b21e25f7a8 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c | |||
@@ -339,6 +339,9 @@ static void edac_mc_workq_teardown(struct mem_ctl_info *mci) | |||
339 | { | 339 | { |
340 | int status; | 340 | int status; |
341 | 341 | ||
342 | if (mci->op_state != OP_RUNNING_POLL) | ||
343 | return; | ||
344 | |||
342 | status = cancel_delayed_work(&mci->work); | 345 | status = cancel_delayed_work(&mci->work); |
343 | if (status == 0) { | 346 | if (status == 0) { |
344 | debugf0("%s() not canceled, flush the queue\n", | 347 | debugf0("%s() not canceled, flush the queue\n", |
diff --git a/drivers/edac/edac_mce_amd.c b/drivers/edac/edac_mce_amd.c index bae9351e947..9014df6f605 100644 --- a/drivers/edac/edac_mce_amd.c +++ b/drivers/edac/edac_mce_amd.c | |||
@@ -365,11 +365,10 @@ static int amd_decode_mce(struct notifier_block *nb, unsigned long val, | |||
365 | 365 | ||
366 | pr_emerg("MC%d_STATUS: ", m->bank); | 366 | pr_emerg("MC%d_STATUS: ", m->bank); |
367 | 367 | ||
368 | pr_cont("%sorrected error, report: %s, MiscV: %svalid, " | 368 | pr_cont("%sorrected error, other errors lost: %s, " |
369 | "CPU context corrupt: %s", | 369 | "CPU context corrupt: %s", |
370 | ((m->status & MCI_STATUS_UC) ? "Unc" : "C"), | 370 | ((m->status & MCI_STATUS_UC) ? "Unc" : "C"), |
371 | ((m->status & MCI_STATUS_EN) ? "yes" : "no"), | 371 | ((m->status & MCI_STATUS_OVER) ? "yes" : "no"), |
372 | ((m->status & MCI_STATUS_MISCV) ? "" : "in"), | ||
373 | ((m->status & MCI_STATUS_PCC) ? "yes" : "no")); | 372 | ((m->status & MCI_STATUS_PCC) ? "yes" : "no")); |
374 | 373 | ||
375 | /* do the two bits[14:13] together */ | 374 | /* do the two bits[14:13] together */ |
@@ -426,11 +425,15 @@ static struct notifier_block amd_mce_dec_nb = { | |||
426 | static int __init mce_amd_init(void) | 425 | static int __init mce_amd_init(void) |
427 | { | 426 | { |
428 | /* | 427 | /* |
429 | * We can decode MCEs for Opteron and later CPUs: | 428 | * We can decode MCEs for K8, F10h and F11h CPUs: |
430 | */ | 429 | */ |
431 | if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && | 430 | if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) |
432 | (boot_cpu_data.x86 >= 0xf)) | 431 | return 0; |
433 | atomic_notifier_chain_register(&x86_mce_decoder_chain, &amd_mce_dec_nb); | 432 | |
433 | if (boot_cpu_data.x86 < 0xf || boot_cpu_data.x86 > 0x11) | ||
434 | return 0; | ||
435 | |||
436 | atomic_notifier_chain_register(&x86_mce_decoder_chain, &amd_mce_dec_nb); | ||
434 | 437 | ||
435 | return 0; | 438 | return 0; |
436 | } | 439 | } |
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index e0187d16dd7..0fd5b85a0f7 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c | |||
@@ -1140,6 +1140,7 @@ static struct mcidev_sysfs_attribute i7core_udimm_counters_attrs[] = { | |||
1140 | ATTR_COUNTER(0), | 1140 | ATTR_COUNTER(0), |
1141 | ATTR_COUNTER(1), | 1141 | ATTR_COUNTER(1), |
1142 | ATTR_COUNTER(2), | 1142 | ATTR_COUNTER(2), |
1143 | { .attr = { .name = NULL } } | ||
1143 | }; | 1144 | }; |
1144 | 1145 | ||
1145 | static struct mcidev_sysfs_group i7core_udimm_counters = { | 1146 | static struct mcidev_sysfs_group i7core_udimm_counters = { |
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c index ca7ca56661e..b42a0bde849 100644 --- a/drivers/firewire/core-transaction.c +++ b/drivers/firewire/core-transaction.c | |||
@@ -81,6 +81,10 @@ static int close_transaction(struct fw_transaction *transaction, | |||
81 | spin_lock_irqsave(&card->lock, flags); | 81 | spin_lock_irqsave(&card->lock, flags); |
82 | list_for_each_entry(t, &card->transaction_list, link) { | 82 | list_for_each_entry(t, &card->transaction_list, link) { |
83 | if (t == transaction) { | 83 | if (t == transaction) { |
84 | if (!del_timer(&t->split_timeout_timer)) { | ||
85 | spin_unlock_irqrestore(&card->lock, flags); | ||
86 | goto timed_out; | ||
87 | } | ||
84 | list_del_init(&t->link); | 88 | list_del_init(&t->link); |
85 | card->tlabel_mask &= ~(1ULL << t->tlabel); | 89 | card->tlabel_mask &= ~(1ULL << t->tlabel); |
86 | break; | 90 | break; |
@@ -89,11 +93,11 @@ static int close_transaction(struct fw_transaction *transaction, | |||
89 | spin_unlock_irqrestore(&card->lock, flags); | 93 | spin_unlock_irqrestore(&card->lock, flags); |
90 | 94 | ||
91 | if (&t->link != &card->transaction_list) { | 95 | if (&t->link != &card->transaction_list) { |
92 | del_timer_sync(&t->split_timeout_timer); | ||
93 | t->callback(card, rcode, NULL, 0, t->callback_data); | 96 | t->callback(card, rcode, NULL, 0, t->callback_data); |
94 | return 0; | 97 | return 0; |
95 | } | 98 | } |
96 | 99 | ||
100 | timed_out: | ||
97 | return -ENOENT; | 101 | return -ENOENT; |
98 | } | 102 | } |
99 | 103 | ||
@@ -921,6 +925,10 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p) | |||
921 | spin_lock_irqsave(&card->lock, flags); | 925 | spin_lock_irqsave(&card->lock, flags); |
922 | list_for_each_entry(t, &card->transaction_list, link) { | 926 | list_for_each_entry(t, &card->transaction_list, link) { |
923 | if (t->node_id == source && t->tlabel == tlabel) { | 927 | if (t->node_id == source && t->tlabel == tlabel) { |
928 | if (!del_timer(&t->split_timeout_timer)) { | ||
929 | spin_unlock_irqrestore(&card->lock, flags); | ||
930 | goto timed_out; | ||
931 | } | ||
924 | list_del_init(&t->link); | 932 | list_del_init(&t->link); |
925 | card->tlabel_mask &= ~(1ULL << t->tlabel); | 933 | card->tlabel_mask &= ~(1ULL << t->tlabel); |
926 | break; | 934 | break; |
@@ -929,6 +937,7 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p) | |||
929 | spin_unlock_irqrestore(&card->lock, flags); | 937 | spin_unlock_irqrestore(&card->lock, flags); |
930 | 938 | ||
931 | if (&t->link == &card->transaction_list) { | 939 | if (&t->link == &card->transaction_list) { |
940 | timed_out: | ||
932 | fw_notify("Unsolicited response (source %x, tlabel %x)\n", | 941 | fw_notify("Unsolicited response (source %x, tlabel %x)\n", |
933 | source, tlabel); | 942 | source, tlabel); |
934 | return; | 943 | return; |
@@ -963,8 +972,6 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p) | |||
963 | break; | 972 | break; |
964 | } | 973 | } |
965 | 974 | ||
966 | del_timer_sync(&t->split_timeout_timer); | ||
967 | |||
968 | /* | 975 | /* |
969 | * The response handler may be executed while the request handler | 976 | * The response handler may be executed while the request handler |
970 | * is still pending. Cancel the request handler. | 977 | * is still pending. Cancel the request handler. |
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index da17d409a24..33f8421c71c 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c | |||
@@ -579,7 +579,7 @@ static int fwnet_finish_incoming_packet(struct net_device *net, | |||
579 | if (!peer) { | 579 | if (!peer) { |
580 | fw_notify("No peer for ARP packet from %016llx\n", | 580 | fw_notify("No peer for ARP packet from %016llx\n", |
581 | (unsigned long long)peer_guid); | 581 | (unsigned long long)peer_guid); |
582 | goto failed_proto; | 582 | goto no_peer; |
583 | } | 583 | } |
584 | 584 | ||
585 | /* | 585 | /* |
@@ -656,7 +656,7 @@ static int fwnet_finish_incoming_packet(struct net_device *net, | |||
656 | 656 | ||
657 | return 0; | 657 | return 0; |
658 | 658 | ||
659 | failed_proto: | 659 | no_peer: |
660 | net->stats.rx_errors++; | 660 | net->stats.rx_errors++; |
661 | net->stats.rx_dropped++; | 661 | net->stats.rx_dropped++; |
662 | 662 | ||
@@ -664,7 +664,7 @@ static int fwnet_finish_incoming_packet(struct net_device *net, | |||
664 | if (netif_queue_stopped(net)) | 664 | if (netif_queue_stopped(net)) |
665 | netif_wake_queue(net); | 665 | netif_wake_queue(net); |
666 | 666 | ||
667 | return 0; | 667 | return -ENOENT; |
668 | } | 668 | } |
669 | 669 | ||
670 | static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | 670 | static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, |
@@ -701,7 +701,7 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
701 | fw_error("out of memory\n"); | 701 | fw_error("out of memory\n"); |
702 | net->stats.rx_dropped++; | 702 | net->stats.rx_dropped++; |
703 | 703 | ||
704 | return -1; | 704 | return -ENOMEM; |
705 | } | 705 | } |
706 | skb_reserve(skb, (net->hard_header_len + 15) & ~15); | 706 | skb_reserve(skb, (net->hard_header_len + 15) & ~15); |
707 | memcpy(skb_put(skb, len), buf, len); | 707 | memcpy(skb_put(skb, len), buf, len); |
@@ -726,8 +726,10 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
726 | spin_lock_irqsave(&dev->lock, flags); | 726 | spin_lock_irqsave(&dev->lock, flags); |
727 | 727 | ||
728 | peer = fwnet_peer_find_by_node_id(dev, source_node_id, generation); | 728 | peer = fwnet_peer_find_by_node_id(dev, source_node_id, generation); |
729 | if (!peer) | 729 | if (!peer) { |
730 | goto bad_proto; | 730 | retval = -ENOENT; |
731 | goto fail; | ||
732 | } | ||
731 | 733 | ||
732 | pd = fwnet_pd_find(peer, datagram_label); | 734 | pd = fwnet_pd_find(peer, datagram_label); |
733 | if (pd == NULL) { | 735 | if (pd == NULL) { |
@@ -741,7 +743,7 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
741 | dg_size, buf, fg_off, len); | 743 | dg_size, buf, fg_off, len); |
742 | if (pd == NULL) { | 744 | if (pd == NULL) { |
743 | retval = -ENOMEM; | 745 | retval = -ENOMEM; |
744 | goto bad_proto; | 746 | goto fail; |
745 | } | 747 | } |
746 | peer->pdg_size++; | 748 | peer->pdg_size++; |
747 | } else { | 749 | } else { |
@@ -755,9 +757,9 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
755 | pd = fwnet_pd_new(net, peer, datagram_label, | 757 | pd = fwnet_pd_new(net, peer, datagram_label, |
756 | dg_size, buf, fg_off, len); | 758 | dg_size, buf, fg_off, len); |
757 | if (pd == NULL) { | 759 | if (pd == NULL) { |
758 | retval = -ENOMEM; | ||
759 | peer->pdg_size--; | 760 | peer->pdg_size--; |
760 | goto bad_proto; | 761 | retval = -ENOMEM; |
762 | goto fail; | ||
761 | } | 763 | } |
762 | } else { | 764 | } else { |
763 | if (!fwnet_pd_update(peer, pd, buf, fg_off, len)) { | 765 | if (!fwnet_pd_update(peer, pd, buf, fg_off, len)) { |
@@ -768,7 +770,8 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
768 | */ | 770 | */ |
769 | fwnet_pd_delete(pd); | 771 | fwnet_pd_delete(pd); |
770 | peer->pdg_size--; | 772 | peer->pdg_size--; |
771 | goto bad_proto; | 773 | retval = -ENOMEM; |
774 | goto fail; | ||
772 | } | 775 | } |
773 | } | 776 | } |
774 | } /* new datagram or add to existing one */ | 777 | } /* new datagram or add to existing one */ |
@@ -794,14 +797,13 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
794 | spin_unlock_irqrestore(&dev->lock, flags); | 797 | spin_unlock_irqrestore(&dev->lock, flags); |
795 | 798 | ||
796 | return 0; | 799 | return 0; |
797 | 800 | fail: | |
798 | bad_proto: | ||
799 | spin_unlock_irqrestore(&dev->lock, flags); | 801 | spin_unlock_irqrestore(&dev->lock, flags); |
800 | 802 | ||
801 | if (netif_queue_stopped(net)) | 803 | if (netif_queue_stopped(net)) |
802 | netif_wake_queue(net); | 804 | netif_wake_queue(net); |
803 | 805 | ||
804 | return 0; | 806 | return retval; |
805 | } | 807 | } |
806 | 808 | ||
807 | static void fwnet_receive_packet(struct fw_card *card, struct fw_request *r, | 809 | static void fwnet_receive_packet(struct fw_card *card, struct fw_request *r, |
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 7f03540cabe..1b05896648b 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c | |||
@@ -263,6 +263,7 @@ static const struct { | |||
263 | {PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_FW, QUIRK_NO_MSI}, | 263 | {PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_FW, QUIRK_NO_MSI}, |
264 | {PCI_VENDOR_ID_NEC, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, | 264 | {PCI_VENDOR_ID_NEC, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, |
265 | {PCI_VENDOR_ID_VIA, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, | 265 | {PCI_VENDOR_ID_VIA, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, |
266 | {PCI_VENDOR_ID_RICOH, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, | ||
266 | {PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_FW, QUIRK_BE_HEADERS}, | 267 | {PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_FW, QUIRK_BE_HEADERS}, |
267 | }; | 268 | }; |
268 | 269 | ||
@@ -694,7 +695,15 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer) | |||
694 | log_ar_at_event('R', p.speed, p.header, evt); | 695 | log_ar_at_event('R', p.speed, p.header, evt); |
695 | 696 | ||
696 | /* | 697 | /* |
697 | * The OHCI bus reset handler synthesizes a phy packet with | 698 | * Several controllers, notably from NEC and VIA, forget to |
699 | * write ack_complete status at PHY packet reception. | ||
700 | */ | ||
701 | if (evt == OHCI1394_evt_no_status && | ||
702 | (p.header[0] & 0xff) == (OHCI1394_phy_tcode << 4)) | ||
703 | p.ack = ACK_COMPLETE; | ||
704 | |||
705 | /* | ||
706 | * The OHCI bus reset handler synthesizes a PHY packet with | ||
698 | * the new generation number when a bus reset happens (see | 707 | * the new generation number when a bus reset happens (see |
699 | * section 8.4.2.3). This helps us determine when a request | 708 | * section 8.4.2.3). This helps us determine when a request |
700 | * was received and make sure we send the response in the same | 709 | * was received and make sure we send the response in the same |
diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c index 9f76171717e..bfae4b30979 100644 --- a/drivers/firewire/sbp2.c +++ b/drivers/firewire/sbp2.c | |||
@@ -450,7 +450,7 @@ static void sbp2_status_write(struct fw_card *card, struct fw_request *request, | |||
450 | 450 | ||
451 | if (&orb->link != &lu->orb_list) { | 451 | if (&orb->link != &lu->orb_list) { |
452 | orb->callback(orb, &status); | 452 | orb->callback(orb, &status); |
453 | kref_put(&orb->kref, free_orb); | 453 | kref_put(&orb->kref, free_orb); /* orb callback reference */ |
454 | } else { | 454 | } else { |
455 | fw_error("status write for unknown orb\n"); | 455 | fw_error("status write for unknown orb\n"); |
456 | } | 456 | } |
@@ -472,20 +472,28 @@ static void complete_transaction(struct fw_card *card, int rcode, | |||
472 | * So this callback only sets the rcode if it hasn't already | 472 | * So this callback only sets the rcode if it hasn't already |
473 | * been set and only does the cleanup if the transaction | 473 | * been set and only does the cleanup if the transaction |
474 | * failed and we didn't already get a status write. | 474 | * failed and we didn't already get a status write. |
475 | * | ||
476 | * Here we treat RCODE_CANCELLED like RCODE_COMPLETE because some | ||
477 | * OXUF936QSE firmwares occasionally respond after Split_Timeout and | ||
478 | * complete the ORB just fine. Note, we also get RCODE_CANCELLED | ||
479 | * from sbp2_cancel_orbs() if fw_cancel_transaction() == 0. | ||
475 | */ | 480 | */ |
476 | spin_lock_irqsave(&card->lock, flags); | 481 | spin_lock_irqsave(&card->lock, flags); |
477 | 482 | ||
478 | if (orb->rcode == -1) | 483 | if (orb->rcode == -1) |
479 | orb->rcode = rcode; | 484 | orb->rcode = rcode; |
480 | if (orb->rcode != RCODE_COMPLETE) { | 485 | |
486 | if (orb->rcode != RCODE_COMPLETE && orb->rcode != RCODE_CANCELLED) { | ||
481 | list_del(&orb->link); | 487 | list_del(&orb->link); |
482 | spin_unlock_irqrestore(&card->lock, flags); | 488 | spin_unlock_irqrestore(&card->lock, flags); |
489 | |||
483 | orb->callback(orb, NULL); | 490 | orb->callback(orb, NULL); |
491 | kref_put(&orb->kref, free_orb); /* orb callback reference */ | ||
484 | } else { | 492 | } else { |
485 | spin_unlock_irqrestore(&card->lock, flags); | 493 | spin_unlock_irqrestore(&card->lock, flags); |
486 | } | 494 | } |
487 | 495 | ||
488 | kref_put(&orb->kref, free_orb); | 496 | kref_put(&orb->kref, free_orb); /* transaction callback reference */ |
489 | } | 497 | } |
490 | 498 | ||
491 | static void sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu, | 499 | static void sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu, |
@@ -501,9 +509,8 @@ static void sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu, | |||
501 | list_add_tail(&orb->link, &lu->orb_list); | 509 | list_add_tail(&orb->link, &lu->orb_list); |
502 | spin_unlock_irqrestore(&device->card->lock, flags); | 510 | spin_unlock_irqrestore(&device->card->lock, flags); |
503 | 511 | ||
504 | /* Take a ref for the orb list and for the transaction callback. */ | 512 | kref_get(&orb->kref); /* transaction callback reference */ |
505 | kref_get(&orb->kref); | 513 | kref_get(&orb->kref); /* orb callback reference */ |
506 | kref_get(&orb->kref); | ||
507 | 514 | ||
508 | fw_send_request(device->card, &orb->t, TCODE_WRITE_BLOCK_REQUEST, | 515 | fw_send_request(device->card, &orb->t, TCODE_WRITE_BLOCK_REQUEST, |
509 | node_id, generation, device->max_speed, offset, | 516 | node_id, generation, device->max_speed, offset, |
@@ -525,11 +532,11 @@ static int sbp2_cancel_orbs(struct sbp2_logical_unit *lu) | |||
525 | 532 | ||
526 | list_for_each_entry_safe(orb, next, &list, link) { | 533 | list_for_each_entry_safe(orb, next, &list, link) { |
527 | retval = 0; | 534 | retval = 0; |
528 | if (fw_cancel_transaction(device->card, &orb->t) == 0) | 535 | fw_cancel_transaction(device->card, &orb->t); |
529 | continue; | ||
530 | 536 | ||
531 | orb->rcode = RCODE_CANCELLED; | 537 | orb->rcode = RCODE_CANCELLED; |
532 | orb->callback(orb, NULL); | 538 | orb->callback(orb, NULL); |
539 | kref_put(&orb->kref, free_orb); /* orb callback reference */ | ||
533 | } | 540 | } |
534 | 541 | ||
535 | return retval; | 542 | return retval; |
diff --git a/drivers/gpio/sx150x.c b/drivers/gpio/sx150x.c index b42f42ca70c..823559ab0e2 100644 --- a/drivers/gpio/sx150x.c +++ b/drivers/gpio/sx150x.c | |||
@@ -459,17 +459,33 @@ static int sx150x_init_io(struct sx150x_chip *chip, u8 base, u16 cfg) | |||
459 | return err; | 459 | return err; |
460 | } | 460 | } |
461 | 461 | ||
462 | static int sx150x_init_hw(struct sx150x_chip *chip, | 462 | static int sx150x_reset(struct sx150x_chip *chip) |
463 | struct sx150x_platform_data *pdata) | ||
464 | { | 463 | { |
465 | int err = 0; | 464 | int err; |
466 | 465 | ||
467 | err = i2c_smbus_write_word_data(chip->client, | 466 | err = i2c_smbus_write_byte_data(chip->client, |
468 | chip->dev_cfg->reg_reset, | 467 | chip->dev_cfg->reg_reset, |
469 | 0x3412); | 468 | 0x12); |
470 | if (err < 0) | 469 | if (err < 0) |
471 | return err; | 470 | return err; |
472 | 471 | ||
472 | err = i2c_smbus_write_byte_data(chip->client, | ||
473 | chip->dev_cfg->reg_reset, | ||
474 | 0x34); | ||
475 | return err; | ||
476 | } | ||
477 | |||
478 | static int sx150x_init_hw(struct sx150x_chip *chip, | ||
479 | struct sx150x_platform_data *pdata) | ||
480 | { | ||
481 | int err = 0; | ||
482 | |||
483 | if (pdata->reset_during_probe) { | ||
484 | err = sx150x_reset(chip); | ||
485 | if (err < 0) | ||
486 | return err; | ||
487 | } | ||
488 | |||
473 | err = sx150x_i2c_write(chip->client, | 489 | err = sx150x_i2c_write(chip->client, |
474 | chip->dev_cfg->reg_misc, | 490 | chip->dev_cfg->reg_misc, |
475 | 0x01); | 491 | 0x01); |
diff --git a/drivers/gpu/drm/drm_buffer.c b/drivers/gpu/drm/drm_buffer.c index 55d03ed0500..529a0dbe9fc 100644 --- a/drivers/gpu/drm/drm_buffer.c +++ b/drivers/gpu/drm/drm_buffer.c | |||
@@ -98,8 +98,8 @@ EXPORT_SYMBOL(drm_buffer_alloc); | |||
98 | * user_data: A pointer the data that is copied to the buffer. | 98 | * user_data: A pointer the data that is copied to the buffer. |
99 | * size: The Number of bytes to copy. | 99 | * size: The Number of bytes to copy. |
100 | */ | 100 | */ |
101 | extern int drm_buffer_copy_from_user(struct drm_buffer *buf, | 101 | int drm_buffer_copy_from_user(struct drm_buffer *buf, |
102 | void __user *user_data, int size) | 102 | void __user *user_data, int size) |
103 | { | 103 | { |
104 | int nr_pages = size / PAGE_SIZE + 1; | 104 | int nr_pages = size / PAGE_SIZE + 1; |
105 | int idx; | 105 | int idx; |
@@ -163,7 +163,7 @@ void *drm_buffer_read_object(struct drm_buffer *buf, | |||
163 | { | 163 | { |
164 | int idx = drm_buffer_index(buf); | 164 | int idx = drm_buffer_index(buf); |
165 | int page = drm_buffer_page(buf); | 165 | int page = drm_buffer_page(buf); |
166 | void *obj = 0; | 166 | void *obj = NULL; |
167 | 167 | ||
168 | if (idx + objsize <= PAGE_SIZE) { | 168 | if (idx + objsize <= PAGE_SIZE) { |
169 | obj = &buf->data[page][idx]; | 169 | obj = &buf->data[page][idx]; |
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 7e31d434834..dcbeb98f195 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c | |||
@@ -34,6 +34,9 @@ | |||
34 | #include "drm_crtc_helper.h" | 34 | #include "drm_crtc_helper.h" |
35 | #include "drm_fb_helper.h" | 35 | #include "drm_fb_helper.h" |
36 | 36 | ||
37 | static bool drm_kms_helper_poll = true; | ||
38 | module_param_named(poll, drm_kms_helper_poll, bool, 0600); | ||
39 | |||
37 | static void drm_mode_validate_flag(struct drm_connector *connector, | 40 | static void drm_mode_validate_flag(struct drm_connector *connector, |
38 | int flags) | 41 | int flags) |
39 | { | 42 | { |
@@ -99,8 +102,10 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, | |||
99 | connector->status = connector_status_disconnected; | 102 | connector->status = connector_status_disconnected; |
100 | if (connector->funcs->force) | 103 | if (connector->funcs->force) |
101 | connector->funcs->force(connector); | 104 | connector->funcs->force(connector); |
102 | } else | 105 | } else { |
103 | connector->status = connector->funcs->detect(connector); | 106 | connector->status = connector->funcs->detect(connector, true); |
107 | drm_kms_helper_poll_enable(dev); | ||
108 | } | ||
104 | 109 | ||
105 | if (connector->status == connector_status_disconnected) { | 110 | if (connector->status == connector_status_disconnected) { |
106 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n", | 111 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n", |
@@ -110,11 +115,10 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, | |||
110 | } | 115 | } |
111 | 116 | ||
112 | count = (*connector_funcs->get_modes)(connector); | 117 | count = (*connector_funcs->get_modes)(connector); |
113 | if (!count) { | 118 | if (count == 0 && connector->status == connector_status_connected) |
114 | count = drm_add_modes_noedid(connector, 1024, 768); | 119 | count = drm_add_modes_noedid(connector, 1024, 768); |
115 | if (!count) | 120 | if (count == 0) |
116 | return 0; | 121 | goto prune; |
117 | } | ||
118 | 122 | ||
119 | drm_mode_connector_list_update(connector); | 123 | drm_mode_connector_list_update(connector); |
120 | 124 | ||
@@ -633,13 +637,13 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
633 | mode_changed = true; | 637 | mode_changed = true; |
634 | 638 | ||
635 | if (mode_changed) { | 639 | if (mode_changed) { |
636 | old_fb = set->crtc->fb; | ||
637 | set->crtc->fb = set->fb; | ||
638 | set->crtc->enabled = (set->mode != NULL); | 640 | set->crtc->enabled = (set->mode != NULL); |
639 | if (set->mode != NULL) { | 641 | if (set->mode != NULL) { |
640 | DRM_DEBUG_KMS("attempting to set mode from" | 642 | DRM_DEBUG_KMS("attempting to set mode from" |
641 | " userspace\n"); | 643 | " userspace\n"); |
642 | drm_mode_debug_printmodeline(set->mode); | 644 | drm_mode_debug_printmodeline(set->mode); |
645 | old_fb = set->crtc->fb; | ||
646 | set->crtc->fb = set->fb; | ||
643 | if (!drm_crtc_helper_set_mode(set->crtc, set->mode, | 647 | if (!drm_crtc_helper_set_mode(set->crtc, set->mode, |
644 | set->x, set->y, | 648 | set->x, set->y, |
645 | old_fb)) { | 649 | old_fb)) { |
@@ -840,6 +844,9 @@ static void output_poll_execute(struct work_struct *work) | |||
840 | enum drm_connector_status old_status, status; | 844 | enum drm_connector_status old_status, status; |
841 | bool repoll = false, changed = false; | 845 | bool repoll = false, changed = false; |
842 | 846 | ||
847 | if (!drm_kms_helper_poll) | ||
848 | return; | ||
849 | |||
843 | mutex_lock(&dev->mode_config.mutex); | 850 | mutex_lock(&dev->mode_config.mutex); |
844 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 851 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
845 | 852 | ||
@@ -859,7 +866,7 @@ static void output_poll_execute(struct work_struct *work) | |||
859 | !(connector->polled & DRM_CONNECTOR_POLL_HPD)) | 866 | !(connector->polled & DRM_CONNECTOR_POLL_HPD)) |
860 | continue; | 867 | continue; |
861 | 868 | ||
862 | status = connector->funcs->detect(connector); | 869 | status = connector->funcs->detect(connector, false); |
863 | if (old_status != status) | 870 | if (old_status != status) |
864 | changed = true; | 871 | changed = true; |
865 | } | 872 | } |
@@ -890,6 +897,9 @@ void drm_kms_helper_poll_enable(struct drm_device *dev) | |||
890 | bool poll = false; | 897 | bool poll = false; |
891 | struct drm_connector *connector; | 898 | struct drm_connector *connector; |
892 | 899 | ||
900 | if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll) | ||
901 | return; | ||
902 | |||
893 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 903 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
894 | if (connector->polled) | 904 | if (connector->polled) |
895 | poll = true; | 905 | poll = true; |
@@ -919,8 +929,10 @@ void drm_helper_hpd_irq_event(struct drm_device *dev) | |||
919 | { | 929 | { |
920 | if (!dev->mode_config.poll_enabled) | 930 | if (!dev->mode_config.poll_enabled) |
921 | return; | 931 | return; |
932 | |||
922 | /* kill timer and schedule immediate execution, this doesn't block */ | 933 | /* kill timer and schedule immediate execution, this doesn't block */ |
923 | cancel_delayed_work(&dev->mode_config.output_poll_work); | 934 | cancel_delayed_work(&dev->mode_config.output_poll_work); |
924 | queue_delayed_work(system_nrt_wq, &dev->mode_config.output_poll_work, 0); | 935 | if (drm_kms_helper_poll) |
936 | queue_delayed_work(system_nrt_wq, &dev->mode_config.output_poll_work, 0); | ||
925 | } | 937 | } |
926 | EXPORT_SYMBOL(drm_helper_hpd_irq_event); | 938 | EXPORT_SYMBOL(drm_helper_hpd_irq_event); |
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 90288ec7c28..84da748555b 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c | |||
@@ -55,6 +55,9 @@ | |||
55 | static int drm_version(struct drm_device *dev, void *data, | 55 | static int drm_version(struct drm_device *dev, void *data, |
56 | struct drm_file *file_priv); | 56 | struct drm_file *file_priv); |
57 | 57 | ||
58 | #define DRM_IOCTL_DEF(ioctl, _func, _flags) \ | ||
59 | [DRM_IOCTL_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, .cmd_drv = 0} | ||
60 | |||
58 | /** Ioctl table */ | 61 | /** Ioctl table */ |
59 | static struct drm_ioctl_desc drm_ioctls[] = { | 62 | static struct drm_ioctl_desc drm_ioctls[] = { |
60 | DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, 0), | 63 | DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, 0), |
@@ -421,6 +424,7 @@ long drm_ioctl(struct file *filp, | |||
421 | int retcode = -EINVAL; | 424 | int retcode = -EINVAL; |
422 | char stack_kdata[128]; | 425 | char stack_kdata[128]; |
423 | char *kdata = NULL; | 426 | char *kdata = NULL; |
427 | unsigned int usize, asize; | ||
424 | 428 | ||
425 | dev = file_priv->minor->dev; | 429 | dev = file_priv->minor->dev; |
426 | atomic_inc(&dev->ioctl_count); | 430 | atomic_inc(&dev->ioctl_count); |
@@ -436,11 +440,18 @@ long drm_ioctl(struct file *filp, | |||
436 | ((nr < DRM_COMMAND_BASE) || (nr >= DRM_COMMAND_END))) | 440 | ((nr < DRM_COMMAND_BASE) || (nr >= DRM_COMMAND_END))) |
437 | goto err_i1; | 441 | goto err_i1; |
438 | if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) && | 442 | if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) && |
439 | (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) | 443 | (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) { |
444 | u32 drv_size; | ||
440 | ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE]; | 445 | ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE]; |
446 | drv_size = _IOC_SIZE(ioctl->cmd_drv); | ||
447 | usize = asize = _IOC_SIZE(cmd); | ||
448 | if (drv_size > asize) | ||
449 | asize = drv_size; | ||
450 | } | ||
441 | else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE)) { | 451 | else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE)) { |
442 | ioctl = &drm_ioctls[nr]; | 452 | ioctl = &drm_ioctls[nr]; |
443 | cmd = ioctl->cmd; | 453 | cmd = ioctl->cmd; |
454 | usize = asize = _IOC_SIZE(cmd); | ||
444 | } else | 455 | } else |
445 | goto err_i1; | 456 | goto err_i1; |
446 | 457 | ||
@@ -460,10 +471,10 @@ long drm_ioctl(struct file *filp, | |||
460 | retcode = -EACCES; | 471 | retcode = -EACCES; |
461 | } else { | 472 | } else { |
462 | if (cmd & (IOC_IN | IOC_OUT)) { | 473 | if (cmd & (IOC_IN | IOC_OUT)) { |
463 | if (_IOC_SIZE(cmd) <= sizeof(stack_kdata)) { | 474 | if (asize <= sizeof(stack_kdata)) { |
464 | kdata = stack_kdata; | 475 | kdata = stack_kdata; |
465 | } else { | 476 | } else { |
466 | kdata = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL); | 477 | kdata = kmalloc(asize, GFP_KERNEL); |
467 | if (!kdata) { | 478 | if (!kdata) { |
468 | retcode = -ENOMEM; | 479 | retcode = -ENOMEM; |
469 | goto err_i1; | 480 | goto err_i1; |
@@ -473,11 +484,13 @@ long drm_ioctl(struct file *filp, | |||
473 | 484 | ||
474 | if (cmd & IOC_IN) { | 485 | if (cmd & IOC_IN) { |
475 | if (copy_from_user(kdata, (void __user *)arg, | 486 | if (copy_from_user(kdata, (void __user *)arg, |
476 | _IOC_SIZE(cmd)) != 0) { | 487 | usize) != 0) { |
477 | retcode = -EFAULT; | 488 | retcode = -EFAULT; |
478 | goto err_i1; | 489 | goto err_i1; |
479 | } | 490 | } |
480 | } | 491 | } else |
492 | memset(kdata, 0, usize); | ||
493 | |||
481 | if (ioctl->flags & DRM_UNLOCKED) | 494 | if (ioctl->flags & DRM_UNLOCKED) |
482 | retcode = func(dev, kdata, file_priv); | 495 | retcode = func(dev, kdata, file_priv); |
483 | else { | 496 | else { |
@@ -488,7 +501,7 @@ long drm_ioctl(struct file *filp, | |||
488 | 501 | ||
489 | if (cmd & IOC_OUT) { | 502 | if (cmd & IOC_OUT) { |
490 | if (copy_to_user((void __user *)arg, kdata, | 503 | if (copy_to_user((void __user *)arg, kdata, |
491 | _IOC_SIZE(cmd)) != 0) | 504 | usize) != 0) |
492 | retcode = -EFAULT; | 505 | retcode = -EFAULT; |
493 | } | 506 | } |
494 | } | 507 | } |
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index de82e201d68..6a5e403f9aa 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c | |||
@@ -94,10 +94,11 @@ static bool drm_fb_helper_connector_parse_command_line(struct drm_fb_helper_conn | |||
94 | int i; | 94 | int i; |
95 | enum drm_connector_force force = DRM_FORCE_UNSPECIFIED; | 95 | enum drm_connector_force force = DRM_FORCE_UNSPECIFIED; |
96 | struct drm_fb_helper_cmdline_mode *cmdline_mode; | 96 | struct drm_fb_helper_cmdline_mode *cmdline_mode; |
97 | struct drm_connector *connector = fb_helper_conn->connector; | 97 | struct drm_connector *connector; |
98 | 98 | ||
99 | if (!fb_helper_conn) | 99 | if (!fb_helper_conn) |
100 | return false; | 100 | return false; |
101 | connector = fb_helper_conn->connector; | ||
101 | 102 | ||
102 | cmdline_mode = &fb_helper_conn->cmdline_mode; | 103 | cmdline_mode = &fb_helper_conn->cmdline_mode; |
103 | if (!mode_option) | 104 | if (!mode_option) |
@@ -369,7 +370,7 @@ static void drm_fb_helper_restore_work_fn(struct work_struct *ignored) | |||
369 | } | 370 | } |
370 | static DECLARE_WORK(drm_fb_helper_restore_work, drm_fb_helper_restore_work_fn); | 371 | static DECLARE_WORK(drm_fb_helper_restore_work, drm_fb_helper_restore_work_fn); |
371 | 372 | ||
372 | static void drm_fb_helper_sysrq(int dummy1, struct tty_struct *dummy3) | 373 | static void drm_fb_helper_sysrq(int dummy1) |
373 | { | 374 | { |
374 | schedule_work(&drm_fb_helper_restore_work); | 375 | schedule_work(&drm_fb_helper_restore_work); |
375 | } | 376 | } |
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 3a652a65546..b744dad5c23 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c | |||
@@ -41,6 +41,7 @@ | |||
41 | 41 | ||
42 | /* from BKL pushdown: note that nothing else serializes idr_find() */ | 42 | /* from BKL pushdown: note that nothing else serializes idr_find() */ |
43 | DEFINE_MUTEX(drm_global_mutex); | 43 | DEFINE_MUTEX(drm_global_mutex); |
44 | EXPORT_SYMBOL(drm_global_mutex); | ||
44 | 45 | ||
45 | static int drm_open_helper(struct inode *inode, struct file *filp, | 46 | static int drm_open_helper(struct inode *inode, struct file *filp, |
46 | struct drm_device * dev); | 47 | struct drm_device * dev); |
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index bf92d07510d..5663d271906 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c | |||
@@ -148,7 +148,7 @@ int drm_gem_object_init(struct drm_device *dev, | |||
148 | return -ENOMEM; | 148 | return -ENOMEM; |
149 | 149 | ||
150 | kref_init(&obj->refcount); | 150 | kref_init(&obj->refcount); |
151 | kref_init(&obj->handlecount); | 151 | atomic_set(&obj->handle_count, 0); |
152 | obj->size = size; | 152 | obj->size = size; |
153 | 153 | ||
154 | atomic_inc(&dev->object_count); | 154 | atomic_inc(&dev->object_count); |
@@ -462,28 +462,6 @@ drm_gem_object_free(struct kref *kref) | |||
462 | } | 462 | } |
463 | EXPORT_SYMBOL(drm_gem_object_free); | 463 | EXPORT_SYMBOL(drm_gem_object_free); |
464 | 464 | ||
465 | /** | ||
466 | * Called after the last reference to the object has been lost. | ||
467 | * Must be called without holding struct_mutex | ||
468 | * | ||
469 | * Frees the object | ||
470 | */ | ||
471 | void | ||
472 | drm_gem_object_free_unlocked(struct kref *kref) | ||
473 | { | ||
474 | struct drm_gem_object *obj = (struct drm_gem_object *) kref; | ||
475 | struct drm_device *dev = obj->dev; | ||
476 | |||
477 | if (dev->driver->gem_free_object_unlocked != NULL) | ||
478 | dev->driver->gem_free_object_unlocked(obj); | ||
479 | else if (dev->driver->gem_free_object != NULL) { | ||
480 | mutex_lock(&dev->struct_mutex); | ||
481 | dev->driver->gem_free_object(obj); | ||
482 | mutex_unlock(&dev->struct_mutex); | ||
483 | } | ||
484 | } | ||
485 | EXPORT_SYMBOL(drm_gem_object_free_unlocked); | ||
486 | |||
487 | static void drm_gem_object_ref_bug(struct kref *list_kref) | 465 | static void drm_gem_object_ref_bug(struct kref *list_kref) |
488 | { | 466 | { |
489 | BUG(); | 467 | BUG(); |
@@ -496,12 +474,8 @@ static void drm_gem_object_ref_bug(struct kref *list_kref) | |||
496 | * called before drm_gem_object_free or we'll be touching | 474 | * called before drm_gem_object_free or we'll be touching |
497 | * freed memory | 475 | * freed memory |
498 | */ | 476 | */ |
499 | void | 477 | void drm_gem_object_handle_free(struct drm_gem_object *obj) |
500 | drm_gem_object_handle_free(struct kref *kref) | ||
501 | { | 478 | { |
502 | struct drm_gem_object *obj = container_of(kref, | ||
503 | struct drm_gem_object, | ||
504 | handlecount); | ||
505 | struct drm_device *dev = obj->dev; | 479 | struct drm_device *dev = obj->dev; |
506 | 480 | ||
507 | /* Remove any name for this object */ | 481 | /* Remove any name for this object */ |
@@ -528,6 +502,10 @@ void drm_gem_vm_open(struct vm_area_struct *vma) | |||
528 | struct drm_gem_object *obj = vma->vm_private_data; | 502 | struct drm_gem_object *obj = vma->vm_private_data; |
529 | 503 | ||
530 | drm_gem_object_reference(obj); | 504 | drm_gem_object_reference(obj); |
505 | |||
506 | mutex_lock(&obj->dev->struct_mutex); | ||
507 | drm_vm_open_locked(vma); | ||
508 | mutex_unlock(&obj->dev->struct_mutex); | ||
531 | } | 509 | } |
532 | EXPORT_SYMBOL(drm_gem_vm_open); | 510 | EXPORT_SYMBOL(drm_gem_vm_open); |
533 | 511 | ||
@@ -535,7 +513,10 @@ void drm_gem_vm_close(struct vm_area_struct *vma) | |||
535 | { | 513 | { |
536 | struct drm_gem_object *obj = vma->vm_private_data; | 514 | struct drm_gem_object *obj = vma->vm_private_data; |
537 | 515 | ||
538 | drm_gem_object_unreference_unlocked(obj); | 516 | mutex_lock(&obj->dev->struct_mutex); |
517 | drm_vm_close_locked(vma); | ||
518 | drm_gem_object_unreference(obj); | ||
519 | mutex_unlock(&obj->dev->struct_mutex); | ||
539 | } | 520 | } |
540 | EXPORT_SYMBOL(drm_gem_vm_close); | 521 | EXPORT_SYMBOL(drm_gem_vm_close); |
541 | 522 | ||
diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c index 2ef2c782724..974e970ce3f 100644 --- a/drivers/gpu/drm/drm_info.c +++ b/drivers/gpu/drm/drm_info.c | |||
@@ -255,7 +255,7 @@ int drm_gem_one_name_info(int id, void *ptr, void *data) | |||
255 | 255 | ||
256 | seq_printf(m, "%6d %8zd %7d %8d\n", | 256 | seq_printf(m, "%6d %8zd %7d %8d\n", |
257 | obj->name, obj->size, | 257 | obj->name, obj->size, |
258 | atomic_read(&obj->handlecount.refcount), | 258 | atomic_read(&obj->handle_count), |
259 | atomic_read(&obj->refcount.refcount)); | 259 | atomic_read(&obj->refcount.refcount)); |
260 | return 0; | 260 | return 0; |
261 | } | 261 | } |
diff --git a/drivers/gpu/drm/drm_lock.c b/drivers/gpu/drm/drm_lock.c index e2f70a516c3..9bf93bc9a32 100644 --- a/drivers/gpu/drm/drm_lock.c +++ b/drivers/gpu/drm/drm_lock.c | |||
@@ -92,7 +92,9 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv) | |||
92 | } | 92 | } |
93 | 93 | ||
94 | /* Contention */ | 94 | /* Contention */ |
95 | mutex_unlock(&drm_global_mutex); | ||
95 | schedule(); | 96 | schedule(); |
97 | mutex_lock(&drm_global_mutex); | ||
96 | if (signal_pending(current)) { | 98 | if (signal_pending(current)) { |
97 | ret = -EINTR; | 99 | ret = -EINTR; |
98 | break; | 100 | break; |
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index da99edc5088..a6bfc302ed9 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c | |||
@@ -285,21 +285,21 @@ void drm_mm_put_block(struct drm_mm_node *cur) | |||
285 | 285 | ||
286 | EXPORT_SYMBOL(drm_mm_put_block); | 286 | EXPORT_SYMBOL(drm_mm_put_block); |
287 | 287 | ||
288 | static int check_free_mm_node(struct drm_mm_node *entry, unsigned long size, | 288 | static int check_free_hole(unsigned long start, unsigned long end, |
289 | unsigned alignment) | 289 | unsigned long size, unsigned alignment) |
290 | { | 290 | { |
291 | unsigned wasted = 0; | 291 | unsigned wasted = 0; |
292 | 292 | ||
293 | if (entry->size < size) | 293 | if (end - start < size) |
294 | return 0; | 294 | return 0; |
295 | 295 | ||
296 | if (alignment) { | 296 | if (alignment) { |
297 | register unsigned tmp = entry->start % alignment; | 297 | unsigned tmp = start % alignment; |
298 | if (tmp) | 298 | if (tmp) |
299 | wasted = alignment - tmp; | 299 | wasted = alignment - tmp; |
300 | } | 300 | } |
301 | 301 | ||
302 | if (entry->size >= size + wasted) { | 302 | if (end >= start + size + wasted) { |
303 | return 1; | 303 | return 1; |
304 | } | 304 | } |
305 | 305 | ||
@@ -320,7 +320,8 @@ struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, | |||
320 | best_size = ~0UL; | 320 | best_size = ~0UL; |
321 | 321 | ||
322 | list_for_each_entry(entry, &mm->free_stack, free_stack) { | 322 | list_for_each_entry(entry, &mm->free_stack, free_stack) { |
323 | if (!check_free_mm_node(entry, size, alignment)) | 323 | if (!check_free_hole(entry->start, entry->start + entry->size, |
324 | size, alignment)) | ||
324 | continue; | 325 | continue; |
325 | 326 | ||
326 | if (!best_match) | 327 | if (!best_match) |
@@ -353,10 +354,12 @@ struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm, | |||
353 | best_size = ~0UL; | 354 | best_size = ~0UL; |
354 | 355 | ||
355 | list_for_each_entry(entry, &mm->free_stack, free_stack) { | 356 | list_for_each_entry(entry, &mm->free_stack, free_stack) { |
356 | if (entry->start > end || (entry->start+entry->size) < start) | 357 | unsigned long adj_start = entry->start < start ? |
357 | continue; | 358 | start : entry->start; |
359 | unsigned long adj_end = entry->start + entry->size > end ? | ||
360 | end : entry->start + entry->size; | ||
358 | 361 | ||
359 | if (!check_free_mm_node(entry, size, alignment)) | 362 | if (!check_free_hole(adj_start, adj_end, size, alignment)) |
360 | continue; | 363 | continue; |
361 | 364 | ||
362 | if (!best_match) | 365 | if (!best_match) |
@@ -449,7 +452,8 @@ int drm_mm_scan_add_block(struct drm_mm_node *node) | |||
449 | node->free_stack.prev = prev_free; | 452 | node->free_stack.prev = prev_free; |
450 | node->free_stack.next = next_free; | 453 | node->free_stack.next = next_free; |
451 | 454 | ||
452 | if (check_free_mm_node(node, mm->scan_size, mm->scan_alignment)) { | 455 | if (check_free_hole(node->start, node->start + node->size, |
456 | mm->scan_size, mm->scan_alignment)) { | ||
453 | mm->scan_hit_start = node->start; | 457 | mm->scan_hit_start = node->start; |
454 | mm->scan_hit_size = node->size; | 458 | mm->scan_hit_size = node->size; |
455 | 459 | ||
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index f1f473ea97d..949326d2a8e 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c | |||
@@ -251,7 +251,10 @@ struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, int hdisplay, | |||
251 | drm_mode->htotal = drm_mode->hdisplay + CVT_RB_H_BLANK; | 251 | drm_mode->htotal = drm_mode->hdisplay + CVT_RB_H_BLANK; |
252 | /* Fill in HSync values */ | 252 | /* Fill in HSync values */ |
253 | drm_mode->hsync_end = drm_mode->hdisplay + CVT_RB_H_BLANK / 2; | 253 | drm_mode->hsync_end = drm_mode->hdisplay + CVT_RB_H_BLANK / 2; |
254 | drm_mode->hsync_start = drm_mode->hsync_end = CVT_RB_H_SYNC; | 254 | drm_mode->hsync_start = drm_mode->hsync_end - CVT_RB_H_SYNC; |
255 | /* Fill in VSync values */ | ||
256 | drm_mode->vsync_start = drm_mode->vdisplay + CVT_RB_VFPORCH; | ||
257 | drm_mode->vsync_end = drm_mode->vsync_start + vsync; | ||
255 | } | 258 | } |
256 | /* 15/13. Find pixel clock frequency (kHz for xf86) */ | 259 | /* 15/13. Find pixel clock frequency (kHz for xf86) */ |
257 | drm_mode->clock = drm_mode->htotal * HV_FACTOR * 1000 / hperiod; | 260 | drm_mode->clock = drm_mode->htotal * HV_FACTOR * 1000 / hperiod; |
diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c index e20f78b542a..f5bd9e590c8 100644 --- a/drivers/gpu/drm/drm_pci.c +++ b/drivers/gpu/drm/drm_pci.c | |||
@@ -164,6 +164,8 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent, | |||
164 | dev->hose = pdev->sysdata; | 164 | dev->hose = pdev->sysdata; |
165 | #endif | 165 | #endif |
166 | 166 | ||
167 | mutex_lock(&drm_global_mutex); | ||
168 | |||
167 | if ((ret = drm_fill_in_dev(dev, ent, driver))) { | 169 | if ((ret = drm_fill_in_dev(dev, ent, driver))) { |
168 | printk(KERN_ERR "DRM: Fill_in_dev failed.\n"); | 170 | printk(KERN_ERR "DRM: Fill_in_dev failed.\n"); |
169 | goto err_g2; | 171 | goto err_g2; |
@@ -199,6 +201,7 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent, | |||
199 | driver->name, driver->major, driver->minor, driver->patchlevel, | 201 | driver->name, driver->major, driver->minor, driver->patchlevel, |
200 | driver->date, pci_name(pdev), dev->primary->index); | 202 | driver->date, pci_name(pdev), dev->primary->index); |
201 | 203 | ||
204 | mutex_unlock(&drm_global_mutex); | ||
202 | return 0; | 205 | return 0; |
203 | 206 | ||
204 | err_g4: | 207 | err_g4: |
@@ -210,6 +213,7 @@ err_g2: | |||
210 | pci_disable_device(pdev); | 213 | pci_disable_device(pdev); |
211 | err_g1: | 214 | err_g1: |
212 | kfree(dev); | 215 | kfree(dev); |
216 | mutex_unlock(&drm_global_mutex); | ||
213 | return ret; | 217 | return ret; |
214 | } | 218 | } |
215 | EXPORT_SYMBOL(drm_get_pci_dev); | 219 | EXPORT_SYMBOL(drm_get_pci_dev); |
diff --git a/drivers/gpu/drm/drm_platform.c b/drivers/gpu/drm/drm_platform.c index 460e9a3afa8..92d1d0fb7b7 100644 --- a/drivers/gpu/drm/drm_platform.c +++ b/drivers/gpu/drm/drm_platform.c | |||
@@ -53,6 +53,8 @@ int drm_get_platform_dev(struct platform_device *platdev, | |||
53 | dev->platformdev = platdev; | 53 | dev->platformdev = platdev; |
54 | dev->dev = &platdev->dev; | 54 | dev->dev = &platdev->dev; |
55 | 55 | ||
56 | mutex_lock(&drm_global_mutex); | ||
57 | |||
56 | ret = drm_fill_in_dev(dev, NULL, driver); | 58 | ret = drm_fill_in_dev(dev, NULL, driver); |
57 | 59 | ||
58 | if (ret) { | 60 | if (ret) { |
@@ -87,6 +89,8 @@ int drm_get_platform_dev(struct platform_device *platdev, | |||
87 | 89 | ||
88 | list_add_tail(&dev->driver_item, &driver->device_list); | 90 | list_add_tail(&dev->driver_item, &driver->device_list); |
89 | 91 | ||
92 | mutex_unlock(&drm_global_mutex); | ||
93 | |||
90 | DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", | 94 | DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", |
91 | driver->name, driver->major, driver->minor, driver->patchlevel, | 95 | driver->name, driver->major, driver->minor, driver->patchlevel, |
92 | driver->date, dev->primary->index); | 96 | driver->date, dev->primary->index); |
@@ -100,6 +104,7 @@ err_g2: | |||
100 | drm_put_minor(&dev->control); | 104 | drm_put_minor(&dev->control); |
101 | err_g1: | 105 | err_g1: |
102 | kfree(dev); | 106 | kfree(dev); |
107 | mutex_unlock(&drm_global_mutex); | ||
103 | return ret; | 108 | return ret; |
104 | } | 109 | } |
105 | EXPORT_SYMBOL(drm_get_platform_dev); | 110 | EXPORT_SYMBOL(drm_get_platform_dev); |
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 86118a74223..85da4c40694 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c | |||
@@ -159,7 +159,7 @@ static ssize_t status_show(struct device *device, | |||
159 | struct drm_connector *connector = to_drm_connector(device); | 159 | struct drm_connector *connector = to_drm_connector(device); |
160 | enum drm_connector_status status; | 160 | enum drm_connector_status status; |
161 | 161 | ||
162 | status = connector->funcs->detect(connector); | 162 | status = connector->funcs->detect(connector, true); |
163 | return snprintf(buf, PAGE_SIZE, "%s\n", | 163 | return snprintf(buf, PAGE_SIZE, "%s\n", |
164 | drm_get_connector_status_name(status)); | 164 | drm_get_connector_status_name(status)); |
165 | } | 165 | } |
diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c index 3778360ecee..5df450683aa 100644 --- a/drivers/gpu/drm/drm_vm.c +++ b/drivers/gpu/drm/drm_vm.c | |||
@@ -138,7 +138,7 @@ static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
138 | break; | 138 | break; |
139 | } | 139 | } |
140 | 140 | ||
141 | if (!agpmem) | 141 | if (&agpmem->head == &dev->agp->memory) |
142 | goto vm_fault_error; | 142 | goto vm_fault_error; |
143 | 143 | ||
144 | /* | 144 | /* |
@@ -433,15 +433,7 @@ static void drm_vm_open(struct vm_area_struct *vma) | |||
433 | mutex_unlock(&dev->struct_mutex); | 433 | mutex_unlock(&dev->struct_mutex); |
434 | } | 434 | } |
435 | 435 | ||
436 | /** | 436 | void drm_vm_close_locked(struct vm_area_struct *vma) |
437 | * \c close method for all virtual memory types. | ||
438 | * | ||
439 | * \param vma virtual memory area. | ||
440 | * | ||
441 | * Search the \p vma private data entry in drm_device::vmalist, unlink it, and | ||
442 | * free it. | ||
443 | */ | ||
444 | static void drm_vm_close(struct vm_area_struct *vma) | ||
445 | { | 437 | { |
446 | struct drm_file *priv = vma->vm_file->private_data; | 438 | struct drm_file *priv = vma->vm_file->private_data; |
447 | struct drm_device *dev = priv->minor->dev; | 439 | struct drm_device *dev = priv->minor->dev; |
@@ -451,7 +443,6 @@ static void drm_vm_close(struct vm_area_struct *vma) | |||
451 | vma->vm_start, vma->vm_end - vma->vm_start); | 443 | vma->vm_start, vma->vm_end - vma->vm_start); |
452 | atomic_dec(&dev->vma_count); | 444 | atomic_dec(&dev->vma_count); |
453 | 445 | ||
454 | mutex_lock(&dev->struct_mutex); | ||
455 | list_for_each_entry_safe(pt, temp, &dev->vmalist, head) { | 446 | list_for_each_entry_safe(pt, temp, &dev->vmalist, head) { |
456 | if (pt->vma == vma) { | 447 | if (pt->vma == vma) { |
457 | list_del(&pt->head); | 448 | list_del(&pt->head); |
@@ -459,6 +450,23 @@ static void drm_vm_close(struct vm_area_struct *vma) | |||
459 | break; | 450 | break; |
460 | } | 451 | } |
461 | } | 452 | } |
453 | } | ||
454 | |||
455 | /** | ||
456 | * \c close method for all virtual memory types. | ||
457 | * | ||
458 | * \param vma virtual memory area. | ||
459 | * | ||
460 | * Search the \p vma private data entry in drm_device::vmalist, unlink it, and | ||
461 | * free it. | ||
462 | */ | ||
463 | static void drm_vm_close(struct vm_area_struct *vma) | ||
464 | { | ||
465 | struct drm_file *priv = vma->vm_file->private_data; | ||
466 | struct drm_device *dev = priv->minor->dev; | ||
467 | |||
468 | mutex_lock(&dev->struct_mutex); | ||
469 | drm_vm_close_locked(vma); | ||
462 | mutex_unlock(&dev->struct_mutex); | 470 | mutex_unlock(&dev->struct_mutex); |
463 | } | 471 | } |
464 | 472 | ||
diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c index 0e6c131313d..fb07e73581e 100644 --- a/drivers/gpu/drm/i810/i810_dma.c +++ b/drivers/gpu/drm/i810/i810_dma.c | |||
@@ -116,7 +116,7 @@ static int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma) | |||
116 | static const struct file_operations i810_buffer_fops = { | 116 | static const struct file_operations i810_buffer_fops = { |
117 | .open = drm_open, | 117 | .open = drm_open, |
118 | .release = drm_release, | 118 | .release = drm_release, |
119 | .unlocked_ioctl = drm_ioctl, | 119 | .unlocked_ioctl = i810_ioctl, |
120 | .mmap = i810_mmap_buffers, | 120 | .mmap = i810_mmap_buffers, |
121 | .fasync = drm_fasync, | 121 | .fasync = drm_fasync, |
122 | }; | 122 | }; |
@@ -1255,21 +1255,21 @@ long i810_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
1255 | } | 1255 | } |
1256 | 1256 | ||
1257 | struct drm_ioctl_desc i810_ioctls[] = { | 1257 | struct drm_ioctl_desc i810_ioctls[] = { |
1258 | DRM_IOCTL_DEF(DRM_I810_INIT, i810_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), | 1258 | DRM_IOCTL_DEF_DRV(I810_INIT, i810_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), |
1259 | DRM_IOCTL_DEF(DRM_I810_VERTEX, i810_dma_vertex, DRM_AUTH|DRM_UNLOCKED), | 1259 | DRM_IOCTL_DEF_DRV(I810_VERTEX, i810_dma_vertex, DRM_AUTH|DRM_UNLOCKED), |
1260 | DRM_IOCTL_DEF(DRM_I810_CLEAR, i810_clear_bufs, DRM_AUTH|DRM_UNLOCKED), | 1260 | DRM_IOCTL_DEF_DRV(I810_CLEAR, i810_clear_bufs, DRM_AUTH|DRM_UNLOCKED), |
1261 | DRM_IOCTL_DEF(DRM_I810_FLUSH, i810_flush_ioctl, DRM_AUTH|DRM_UNLOCKED), | 1261 | DRM_IOCTL_DEF_DRV(I810_FLUSH, i810_flush_ioctl, DRM_AUTH|DRM_UNLOCKED), |
1262 | DRM_IOCTL_DEF(DRM_I810_GETAGE, i810_getage, DRM_AUTH|DRM_UNLOCKED), | 1262 | DRM_IOCTL_DEF_DRV(I810_GETAGE, i810_getage, DRM_AUTH|DRM_UNLOCKED), |
1263 | DRM_IOCTL_DEF(DRM_I810_GETBUF, i810_getbuf, DRM_AUTH|DRM_UNLOCKED), | 1263 | DRM_IOCTL_DEF_DRV(I810_GETBUF, i810_getbuf, DRM_AUTH|DRM_UNLOCKED), |
1264 | DRM_IOCTL_DEF(DRM_I810_SWAP, i810_swap_bufs, DRM_AUTH|DRM_UNLOCKED), | 1264 | DRM_IOCTL_DEF_DRV(I810_SWAP, i810_swap_bufs, DRM_AUTH|DRM_UNLOCKED), |
1265 | DRM_IOCTL_DEF(DRM_I810_COPY, i810_copybuf, DRM_AUTH|DRM_UNLOCKED), | 1265 | DRM_IOCTL_DEF_DRV(I810_COPY, i810_copybuf, DRM_AUTH|DRM_UNLOCKED), |
1266 | DRM_IOCTL_DEF(DRM_I810_DOCOPY, i810_docopy, DRM_AUTH|DRM_UNLOCKED), | 1266 | DRM_IOCTL_DEF_DRV(I810_DOCOPY, i810_docopy, DRM_AUTH|DRM_UNLOCKED), |
1267 | DRM_IOCTL_DEF(DRM_I810_OV0INFO, i810_ov0_info, DRM_AUTH|DRM_UNLOCKED), | 1267 | DRM_IOCTL_DEF_DRV(I810_OV0INFO, i810_ov0_info, DRM_AUTH|DRM_UNLOCKED), |
1268 | DRM_IOCTL_DEF(DRM_I810_FSTATUS, i810_fstatus, DRM_AUTH|DRM_UNLOCKED), | 1268 | DRM_IOCTL_DEF_DRV(I810_FSTATUS, i810_fstatus, DRM_AUTH|DRM_UNLOCKED), |
1269 | DRM_IOCTL_DEF(DRM_I810_OV0FLIP, i810_ov0_flip, DRM_AUTH|DRM_UNLOCKED), | 1269 | DRM_IOCTL_DEF_DRV(I810_OV0FLIP, i810_ov0_flip, DRM_AUTH|DRM_UNLOCKED), |
1270 | DRM_IOCTL_DEF(DRM_I810_MC, i810_dma_mc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), | 1270 | DRM_IOCTL_DEF_DRV(I810_MC, i810_dma_mc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), |
1271 | DRM_IOCTL_DEF(DRM_I810_RSTATUS, i810_rstatus, DRM_AUTH|DRM_UNLOCKED), | 1271 | DRM_IOCTL_DEF_DRV(I810_RSTATUS, i810_rstatus, DRM_AUTH|DRM_UNLOCKED), |
1272 | DRM_IOCTL_DEF(DRM_I810_FLIP, i810_flip_bufs, DRM_AUTH|DRM_UNLOCKED), | 1272 | DRM_IOCTL_DEF_DRV(I810_FLIP, i810_flip_bufs, DRM_AUTH|DRM_UNLOCKED), |
1273 | }; | 1273 | }; |
1274 | 1274 | ||
1275 | int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls); | 1275 | int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls); |
diff --git a/drivers/gpu/drm/i830/i830_dma.c b/drivers/gpu/drm/i830/i830_dma.c index 5168862c922..cc92c7e6236 100644 --- a/drivers/gpu/drm/i830/i830_dma.c +++ b/drivers/gpu/drm/i830/i830_dma.c | |||
@@ -118,7 +118,7 @@ static int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma) | |||
118 | static const struct file_operations i830_buffer_fops = { | 118 | static const struct file_operations i830_buffer_fops = { |
119 | .open = drm_open, | 119 | .open = drm_open, |
120 | .release = drm_release, | 120 | .release = drm_release, |
121 | .unlocked_ioctl = drm_ioctl, | 121 | .unlocked_ioctl = i830_ioctl, |
122 | .mmap = i830_mmap_buffers, | 122 | .mmap = i830_mmap_buffers, |
123 | .fasync = drm_fasync, | 123 | .fasync = drm_fasync, |
124 | }; | 124 | }; |
@@ -1524,20 +1524,20 @@ long i830_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
1524 | } | 1524 | } |
1525 | 1525 | ||
1526 | struct drm_ioctl_desc i830_ioctls[] = { | 1526 | struct drm_ioctl_desc i830_ioctls[] = { |
1527 | DRM_IOCTL_DEF(DRM_I830_INIT, i830_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), | 1527 | DRM_IOCTL_DEF_DRV(I830_INIT, i830_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), |
1528 | DRM_IOCTL_DEF(DRM_I830_VERTEX, i830_dma_vertex, DRM_AUTH|DRM_UNLOCKED), | 1528 | DRM_IOCTL_DEF_DRV(I830_VERTEX, i830_dma_vertex, DRM_AUTH|DRM_UNLOCKED), |
1529 | DRM_IOCTL_DEF(DRM_I830_CLEAR, i830_clear_bufs, DRM_AUTH|DRM_UNLOCKED), | 1529 | DRM_IOCTL_DEF_DRV(I830_CLEAR, i830_clear_bufs, DRM_AUTH|DRM_UNLOCKED), |
1530 | DRM_IOCTL_DEF(DRM_I830_FLUSH, i830_flush_ioctl, DRM_AUTH|DRM_UNLOCKED), | 1530 | DRM_IOCTL_DEF_DRV(I830_FLUSH, i830_flush_ioctl, DRM_AUTH|DRM_UNLOCKED), |
1531 | DRM_IOCTL_DEF(DRM_I830_GETAGE, i830_getage, DRM_AUTH|DRM_UNLOCKED), | 1531 | DRM_IOCTL_DEF_DRV(I830_GETAGE, i830_getage, DRM_AUTH|DRM_UNLOCKED), |
1532 | DRM_IOCTL_DEF(DRM_I830_GETBUF, i830_getbuf, DRM_AUTH|DRM_UNLOCKED), | 1532 | DRM_IOCTL_DEF_DRV(I830_GETBUF, i830_getbuf, DRM_AUTH|DRM_UNLOCKED), |
1533 | DRM_IOCTL_DEF(DRM_I830_SWAP, i830_swap_bufs, DRM_AUTH|DRM_UNLOCKED), | 1533 | DRM_IOCTL_DEF_DRV(I830_SWAP, i830_swap_bufs, DRM_AUTH|DRM_UNLOCKED), |
1534 | DRM_IOCTL_DEF(DRM_I830_COPY, i830_copybuf, DRM_AUTH|DRM_UNLOCKED), | 1534 | DRM_IOCTL_DEF_DRV(I830_COPY, i830_copybuf, DRM_AUTH|DRM_UNLOCKED), |
1535 | DRM_IOCTL_DEF(DRM_I830_DOCOPY, i830_docopy, DRM_AUTH|DRM_UNLOCKED), | 1535 | DRM_IOCTL_DEF_DRV(I830_DOCOPY, i830_docopy, DRM_AUTH|DRM_UNLOCKED), |
1536 | DRM_IOCTL_DEF(DRM_I830_FLIP, i830_flip_bufs, DRM_AUTH|DRM_UNLOCKED), | 1536 | DRM_IOCTL_DEF_DRV(I830_FLIP, i830_flip_bufs, DRM_AUTH|DRM_UNLOCKED), |
1537 | DRM_IOCTL_DEF(DRM_I830_IRQ_EMIT, i830_irq_emit, DRM_AUTH|DRM_UNLOCKED), | 1537 | DRM_IOCTL_DEF_DRV(I830_IRQ_EMIT, i830_irq_emit, DRM_AUTH|DRM_UNLOCKED), |
1538 | DRM_IOCTL_DEF(DRM_I830_IRQ_WAIT, i830_irq_wait, DRM_AUTH|DRM_UNLOCKED), | 1538 | DRM_IOCTL_DEF_DRV(I830_IRQ_WAIT, i830_irq_wait, DRM_AUTH|DRM_UNLOCKED), |
1539 | DRM_IOCTL_DEF(DRM_I830_GETPARAM, i830_getparam, DRM_AUTH|DRM_UNLOCKED), | 1539 | DRM_IOCTL_DEF_DRV(I830_GETPARAM, i830_getparam, DRM_AUTH|DRM_UNLOCKED), |
1540 | DRM_IOCTL_DEF(DRM_I830_SETPARAM, i830_setparam, DRM_AUTH|DRM_UNLOCKED), | 1540 | DRM_IOCTL_DEF_DRV(I830_SETPARAM, i830_setparam, DRM_AUTH|DRM_UNLOCKED), |
1541 | }; | 1541 | }; |
1542 | 1542 | ||
1543 | int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls); | 1543 | int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls); |
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 92d5605a34d..5e43d707678 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
32 | #include "drmP.h" | 32 | #include "drmP.h" |
33 | #include "drm.h" | 33 | #include "drm.h" |
34 | #include "intel_drv.h" | ||
34 | #include "i915_drm.h" | 35 | #include "i915_drm.h" |
35 | #include "i915_drv.h" | 36 | #include "i915_drv.h" |
36 | 37 | ||
@@ -121,6 +122,54 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) | |||
121 | return 0; | 122 | return 0; |
122 | } | 123 | } |
123 | 124 | ||
125 | static int i915_gem_pageflip_info(struct seq_file *m, void *data) | ||
126 | { | ||
127 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
128 | struct drm_device *dev = node->minor->dev; | ||
129 | unsigned long flags; | ||
130 | struct intel_crtc *crtc; | ||
131 | |||
132 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) { | ||
133 | const char *pipe = crtc->pipe ? "B" : "A"; | ||
134 | const char *plane = crtc->plane ? "B" : "A"; | ||
135 | struct intel_unpin_work *work; | ||
136 | |||
137 | spin_lock_irqsave(&dev->event_lock, flags); | ||
138 | work = crtc->unpin_work; | ||
139 | if (work == NULL) { | ||
140 | seq_printf(m, "No flip due on pipe %s (plane %s)\n", | ||
141 | pipe, plane); | ||
142 | } else { | ||
143 | if (!work->pending) { | ||
144 | seq_printf(m, "Flip queued on pipe %s (plane %s)\n", | ||
145 | pipe, plane); | ||
146 | } else { | ||
147 | seq_printf(m, "Flip pending (waiting for vsync) on pipe %s (plane %s)\n", | ||
148 | pipe, plane); | ||
149 | } | ||
150 | if (work->enable_stall_check) | ||
151 | seq_printf(m, "Stall check enabled, "); | ||
152 | else | ||
153 | seq_printf(m, "Stall check waiting for page flip ioctl, "); | ||
154 | seq_printf(m, "%d prepares\n", work->pending); | ||
155 | |||
156 | if (work->old_fb_obj) { | ||
157 | struct drm_i915_gem_object *obj_priv = to_intel_bo(work->old_fb_obj); | ||
158 | if(obj_priv) | ||
159 | seq_printf(m, "Old framebuffer gtt_offset 0x%08x\n", obj_priv->gtt_offset ); | ||
160 | } | ||
161 | if (work->pending_flip_obj) { | ||
162 | struct drm_i915_gem_object *obj_priv = to_intel_bo(work->pending_flip_obj); | ||
163 | if(obj_priv) | ||
164 | seq_printf(m, "New framebuffer gtt_offset 0x%08x\n", obj_priv->gtt_offset ); | ||
165 | } | ||
166 | } | ||
167 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
168 | } | ||
169 | |||
170 | return 0; | ||
171 | } | ||
172 | |||
124 | static int i915_gem_request_info(struct seq_file *m, void *data) | 173 | static int i915_gem_request_info(struct seq_file *m, void *data) |
125 | { | 174 | { |
126 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 175 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
@@ -777,6 +826,7 @@ static struct drm_info_list i915_debugfs_list[] = { | |||
777 | {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST}, | 826 | {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST}, |
778 | {"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST}, | 827 | {"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST}, |
779 | {"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST}, | 828 | {"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST}, |
829 | {"i915_gem_pageflip", i915_gem_pageflip_info, 0}, | ||
780 | {"i915_gem_request", i915_gem_request_info, 0}, | 830 | {"i915_gem_request", i915_gem_request_info, 0}, |
781 | {"i915_gem_seqno", i915_gem_seqno_info, 0}, | 831 | {"i915_gem_seqno", i915_gem_seqno_info, 0}, |
782 | {"i915_gem_fence_regs", i915_gem_fence_regs_info, 0}, | 832 | {"i915_gem_fence_regs", i915_gem_fence_regs_info, 0}, |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 44af317731b..2dd2c93ebfa 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -620,8 +620,10 @@ static int i915_batchbuffer(struct drm_device *dev, void *data, | |||
620 | ret = copy_from_user(cliprects, batch->cliprects, | 620 | ret = copy_from_user(cliprects, batch->cliprects, |
621 | batch->num_cliprects * | 621 | batch->num_cliprects * |
622 | sizeof(struct drm_clip_rect)); | 622 | sizeof(struct drm_clip_rect)); |
623 | if (ret != 0) | 623 | if (ret != 0) { |
624 | ret = -EFAULT; | ||
624 | goto fail_free; | 625 | goto fail_free; |
626 | } | ||
625 | } | 627 | } |
626 | 628 | ||
627 | mutex_lock(&dev->struct_mutex); | 629 | mutex_lock(&dev->struct_mutex); |
@@ -662,8 +664,10 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, | |||
662 | return -ENOMEM; | 664 | return -ENOMEM; |
663 | 665 | ||
664 | ret = copy_from_user(batch_data, cmdbuf->buf, cmdbuf->sz); | 666 | ret = copy_from_user(batch_data, cmdbuf->buf, cmdbuf->sz); |
665 | if (ret != 0) | 667 | if (ret != 0) { |
668 | ret = -EFAULT; | ||
666 | goto fail_batch_free; | 669 | goto fail_batch_free; |
670 | } | ||
667 | 671 | ||
668 | if (cmdbuf->num_cliprects) { | 672 | if (cmdbuf->num_cliprects) { |
669 | cliprects = kcalloc(cmdbuf->num_cliprects, | 673 | cliprects = kcalloc(cmdbuf->num_cliprects, |
@@ -676,8 +680,10 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, | |||
676 | ret = copy_from_user(cliprects, cmdbuf->cliprects, | 680 | ret = copy_from_user(cliprects, cmdbuf->cliprects, |
677 | cmdbuf->num_cliprects * | 681 | cmdbuf->num_cliprects * |
678 | sizeof(struct drm_clip_rect)); | 682 | sizeof(struct drm_clip_rect)); |
679 | if (ret != 0) | 683 | if (ret != 0) { |
684 | ret = -EFAULT; | ||
680 | goto fail_clip_free; | 685 | goto fail_clip_free; |
686 | } | ||
681 | } | 687 | } |
682 | 688 | ||
683 | mutex_lock(&dev->struct_mutex); | 689 | mutex_lock(&dev->struct_mutex); |
@@ -885,7 +891,7 @@ intel_alloc_mchbar_resource(struct drm_device *dev) | |||
885 | int reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915; | 891 | int reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915; |
886 | u32 temp_lo, temp_hi = 0; | 892 | u32 temp_lo, temp_hi = 0; |
887 | u64 mchbar_addr; | 893 | u64 mchbar_addr; |
888 | int ret = 0; | 894 | int ret; |
889 | 895 | ||
890 | if (IS_I965G(dev)) | 896 | if (IS_I965G(dev)) |
891 | pci_read_config_dword(dev_priv->bridge_dev, reg + 4, &temp_hi); | 897 | pci_read_config_dword(dev_priv->bridge_dev, reg + 4, &temp_hi); |
@@ -895,22 +901,23 @@ intel_alloc_mchbar_resource(struct drm_device *dev) | |||
895 | /* If ACPI doesn't have it, assume we need to allocate it ourselves */ | 901 | /* If ACPI doesn't have it, assume we need to allocate it ourselves */ |
896 | #ifdef CONFIG_PNP | 902 | #ifdef CONFIG_PNP |
897 | if (mchbar_addr && | 903 | if (mchbar_addr && |
898 | pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE)) { | 904 | pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE)) |
899 | ret = 0; | 905 | return 0; |
900 | goto out; | ||
901 | } | ||
902 | #endif | 906 | #endif |
903 | 907 | ||
904 | /* Get some space for it */ | 908 | /* Get some space for it */ |
905 | ret = pci_bus_alloc_resource(dev_priv->bridge_dev->bus, &dev_priv->mch_res, | 909 | dev_priv->mch_res.name = "i915 MCHBAR"; |
910 | dev_priv->mch_res.flags = IORESOURCE_MEM; | ||
911 | ret = pci_bus_alloc_resource(dev_priv->bridge_dev->bus, | ||
912 | &dev_priv->mch_res, | ||
906 | MCHBAR_SIZE, MCHBAR_SIZE, | 913 | MCHBAR_SIZE, MCHBAR_SIZE, |
907 | PCIBIOS_MIN_MEM, | 914 | PCIBIOS_MIN_MEM, |
908 | 0, pcibios_align_resource, | 915 | 0, pcibios_align_resource, |
909 | dev_priv->bridge_dev); | 916 | dev_priv->bridge_dev); |
910 | if (ret) { | 917 | if (ret) { |
911 | DRM_DEBUG_DRIVER("failed bus alloc: %d\n", ret); | 918 | DRM_DEBUG_DRIVER("failed bus alloc: %d\n", ret); |
912 | dev_priv->mch_res.start = 0; | 919 | dev_priv->mch_res.start = 0; |
913 | goto out; | 920 | return ret; |
914 | } | 921 | } |
915 | 922 | ||
916 | if (IS_I965G(dev)) | 923 | if (IS_I965G(dev)) |
@@ -919,8 +926,7 @@ intel_alloc_mchbar_resource(struct drm_device *dev) | |||
919 | 926 | ||
920 | pci_write_config_dword(dev_priv->bridge_dev, reg, | 927 | pci_write_config_dword(dev_priv->bridge_dev, reg, |
921 | lower_32_bits(dev_priv->mch_res.start)); | 928 | lower_32_bits(dev_priv->mch_res.start)); |
922 | out: | 929 | return 0; |
923 | return ret; | ||
924 | } | 930 | } |
925 | 931 | ||
926 | /* Setup MCHBAR if possible, return true if we should disable it again */ | 932 | /* Setup MCHBAR if possible, return true if we should disable it again */ |
@@ -1781,9 +1787,9 @@ unsigned long i915_chipset_val(struct drm_i915_private *dev_priv) | |||
1781 | } | 1787 | } |
1782 | } | 1788 | } |
1783 | 1789 | ||
1784 | div_u64(diff, diff1); | 1790 | diff = div_u64(diff, diff1); |
1785 | ret = ((m * diff) + c); | 1791 | ret = ((m * diff) + c); |
1786 | div_u64(ret, 10); | 1792 | ret = div_u64(ret, 10); |
1787 | 1793 | ||
1788 | dev_priv->last_count1 = total_count; | 1794 | dev_priv->last_count1 = total_count; |
1789 | dev_priv->last_time1 = now; | 1795 | dev_priv->last_time1 = now; |
@@ -1852,7 +1858,7 @@ void i915_update_gfx_val(struct drm_i915_private *dev_priv) | |||
1852 | 1858 | ||
1853 | /* More magic constants... */ | 1859 | /* More magic constants... */ |
1854 | diff = diff * 1181; | 1860 | diff = diff * 1181; |
1855 | div_u64(diff, diffms * 10); | 1861 | diff = div_u64(diff, diffms * 10); |
1856 | dev_priv->gfx_power = diff; | 1862 | dev_priv->gfx_power = diff; |
1857 | } | 1863 | } |
1858 | 1864 | ||
@@ -2082,6 +2088,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2082 | goto free_priv; | 2088 | goto free_priv; |
2083 | } | 2089 | } |
2084 | 2090 | ||
2091 | /* overlay on gen2 is broken and can't address above 1G */ | ||
2092 | if (IS_GEN2(dev)) | ||
2093 | dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(30)); | ||
2094 | |||
2085 | dev_priv->regs = ioremap(base, size); | 2095 | dev_priv->regs = ioremap(base, size); |
2086 | if (!dev_priv->regs) { | 2096 | if (!dev_priv->regs) { |
2087 | DRM_ERROR("failed to map registers\n"); | 2097 | DRM_ERROR("failed to map registers\n"); |
@@ -2221,6 +2231,9 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2221 | dev_priv->mchdev_lock = &mchdev_lock; | 2231 | dev_priv->mchdev_lock = &mchdev_lock; |
2222 | spin_unlock(&mchdev_lock); | 2232 | spin_unlock(&mchdev_lock); |
2223 | 2233 | ||
2234 | /* XXX Prevent module unload due to memory corruption bugs. */ | ||
2235 | __module_get(THIS_MODULE); | ||
2236 | |||
2224 | return 0; | 2237 | return 0; |
2225 | 2238 | ||
2226 | out_workqueue_free: | 2239 | out_workqueue_free: |
@@ -2367,46 +2380,46 @@ void i915_driver_postclose(struct drm_device *dev, struct drm_file *file_priv) | |||
2367 | } | 2380 | } |
2368 | 2381 | ||
2369 | struct drm_ioctl_desc i915_ioctls[] = { | 2382 | struct drm_ioctl_desc i915_ioctls[] = { |
2370 | DRM_IOCTL_DEF(DRM_I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 2383 | DRM_IOCTL_DEF_DRV(I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
2371 | DRM_IOCTL_DEF(DRM_I915_FLUSH, i915_flush_ioctl, DRM_AUTH), | 2384 | DRM_IOCTL_DEF_DRV(I915_FLUSH, i915_flush_ioctl, DRM_AUTH), |
2372 | DRM_IOCTL_DEF(DRM_I915_FLIP, i915_flip_bufs, DRM_AUTH), | 2385 | DRM_IOCTL_DEF_DRV(I915_FLIP, i915_flip_bufs, DRM_AUTH), |
2373 | DRM_IOCTL_DEF(DRM_I915_BATCHBUFFER, i915_batchbuffer, DRM_AUTH), | 2386 | DRM_IOCTL_DEF_DRV(I915_BATCHBUFFER, i915_batchbuffer, DRM_AUTH), |
2374 | DRM_IOCTL_DEF(DRM_I915_IRQ_EMIT, i915_irq_emit, DRM_AUTH), | 2387 | DRM_IOCTL_DEF_DRV(I915_IRQ_EMIT, i915_irq_emit, DRM_AUTH), |
2375 | DRM_IOCTL_DEF(DRM_I915_IRQ_WAIT, i915_irq_wait, DRM_AUTH), | 2388 | DRM_IOCTL_DEF_DRV(I915_IRQ_WAIT, i915_irq_wait, DRM_AUTH), |
2376 | DRM_IOCTL_DEF(DRM_I915_GETPARAM, i915_getparam, DRM_AUTH), | 2389 | DRM_IOCTL_DEF_DRV(I915_GETPARAM, i915_getparam, DRM_AUTH), |
2377 | DRM_IOCTL_DEF(DRM_I915_SETPARAM, i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 2390 | DRM_IOCTL_DEF_DRV(I915_SETPARAM, i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
2378 | DRM_IOCTL_DEF(DRM_I915_ALLOC, i915_mem_alloc, DRM_AUTH), | 2391 | DRM_IOCTL_DEF_DRV(I915_ALLOC, i915_mem_alloc, DRM_AUTH), |
2379 | DRM_IOCTL_DEF(DRM_I915_FREE, i915_mem_free, DRM_AUTH), | 2392 | DRM_IOCTL_DEF_DRV(I915_FREE, i915_mem_free, DRM_AUTH), |
2380 | DRM_IOCTL_DEF(DRM_I915_INIT_HEAP, i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 2393 | DRM_IOCTL_DEF_DRV(I915_INIT_HEAP, i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
2381 | DRM_IOCTL_DEF(DRM_I915_CMDBUFFER, i915_cmdbuffer, DRM_AUTH), | 2394 | DRM_IOCTL_DEF_DRV(I915_CMDBUFFER, i915_cmdbuffer, DRM_AUTH), |
2382 | DRM_IOCTL_DEF(DRM_I915_DESTROY_HEAP, i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ), | 2395 | DRM_IOCTL_DEF_DRV(I915_DESTROY_HEAP, i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
2383 | DRM_IOCTL_DEF(DRM_I915_SET_VBLANK_PIPE, i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ), | 2396 | DRM_IOCTL_DEF_DRV(I915_SET_VBLANK_PIPE, i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
2384 | DRM_IOCTL_DEF(DRM_I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH ), | 2397 | DRM_IOCTL_DEF_DRV(I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH), |
2385 | DRM_IOCTL_DEF(DRM_I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH), | 2398 | DRM_IOCTL_DEF_DRV(I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH), |
2386 | DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 2399 | DRM_IOCTL_DEF_DRV(I915_HWS_ADDR, i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
2387 | DRM_IOCTL_DEF(DRM_I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), | 2400 | DRM_IOCTL_DEF_DRV(I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), |
2388 | DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH|DRM_UNLOCKED), | 2401 | DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH|DRM_UNLOCKED), |
2389 | DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER2, i915_gem_execbuffer2, DRM_AUTH|DRM_UNLOCKED), | 2402 | DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER2, i915_gem_execbuffer2, DRM_AUTH|DRM_UNLOCKED), |
2390 | DRM_IOCTL_DEF(DRM_I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED), | 2403 | DRM_IOCTL_DEF_DRV(I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED), |
2391 | DRM_IOCTL_DEF(DRM_I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED), | 2404 | DRM_IOCTL_DEF_DRV(I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED), |
2392 | DRM_IOCTL_DEF(DRM_I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED), | 2405 | DRM_IOCTL_DEF_DRV(I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED), |
2393 | DRM_IOCTL_DEF(DRM_I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH|DRM_UNLOCKED), | 2406 | DRM_IOCTL_DEF_DRV(I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH|DRM_UNLOCKED), |
2394 | DRM_IOCTL_DEF(DRM_I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), | 2407 | DRM_IOCTL_DEF_DRV(I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), |
2395 | DRM_IOCTL_DEF(DRM_I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), | 2408 | DRM_IOCTL_DEF_DRV(I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), |
2396 | DRM_IOCTL_DEF(DRM_I915_GEM_CREATE, i915_gem_create_ioctl, DRM_UNLOCKED), | 2409 | DRM_IOCTL_DEF_DRV(I915_GEM_CREATE, i915_gem_create_ioctl, DRM_UNLOCKED), |
2397 | DRM_IOCTL_DEF(DRM_I915_GEM_PREAD, i915_gem_pread_ioctl, DRM_UNLOCKED), | 2410 | DRM_IOCTL_DEF_DRV(I915_GEM_PREAD, i915_gem_pread_ioctl, DRM_UNLOCKED), |
2398 | DRM_IOCTL_DEF(DRM_I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_UNLOCKED), | 2411 | DRM_IOCTL_DEF_DRV(I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_UNLOCKED), |
2399 | DRM_IOCTL_DEF(DRM_I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_UNLOCKED), | 2412 | DRM_IOCTL_DEF_DRV(I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_UNLOCKED), |
2400 | DRM_IOCTL_DEF(DRM_I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, DRM_UNLOCKED), | 2413 | DRM_IOCTL_DEF_DRV(I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, DRM_UNLOCKED), |
2401 | DRM_IOCTL_DEF(DRM_I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, DRM_UNLOCKED), | 2414 | DRM_IOCTL_DEF_DRV(I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, DRM_UNLOCKED), |
2402 | DRM_IOCTL_DEF(DRM_I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, DRM_UNLOCKED), | 2415 | DRM_IOCTL_DEF_DRV(I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, DRM_UNLOCKED), |
2403 | DRM_IOCTL_DEF(DRM_I915_GEM_SET_TILING, i915_gem_set_tiling, DRM_UNLOCKED), | 2416 | DRM_IOCTL_DEF_DRV(I915_GEM_SET_TILING, i915_gem_set_tiling, DRM_UNLOCKED), |
2404 | DRM_IOCTL_DEF(DRM_I915_GEM_GET_TILING, i915_gem_get_tiling, DRM_UNLOCKED), | 2417 | DRM_IOCTL_DEF_DRV(I915_GEM_GET_TILING, i915_gem_get_tiling, DRM_UNLOCKED), |
2405 | DRM_IOCTL_DEF(DRM_I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, DRM_UNLOCKED), | 2418 | DRM_IOCTL_DEF_DRV(I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, DRM_UNLOCKED), |
2406 | DRM_IOCTL_DEF(DRM_I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, DRM_UNLOCKED), | 2419 | DRM_IOCTL_DEF_DRV(I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, DRM_UNLOCKED), |
2407 | DRM_IOCTL_DEF(DRM_I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_UNLOCKED), | 2420 | DRM_IOCTL_DEF_DRV(I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_UNLOCKED), |
2408 | DRM_IOCTL_DEF(DRM_I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 2421 | DRM_IOCTL_DEF_DRV(I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
2409 | DRM_IOCTL_DEF(DRM_I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 2422 | DRM_IOCTL_DEF_DRV(I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
2410 | }; | 2423 | }; |
2411 | 2424 | ||
2412 | int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); | 2425 | int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 00befce8fbb..6dbe14cc4f7 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -61,91 +61,86 @@ extern int intel_agp_enabled; | |||
61 | .driver_data = (unsigned long) info } | 61 | .driver_data = (unsigned long) info } |
62 | 62 | ||
63 | static const struct intel_device_info intel_i830_info = { | 63 | static const struct intel_device_info intel_i830_info = { |
64 | .is_i8xx = 1, .is_mobile = 1, .cursor_needs_physical = 1, | 64 | .gen = 2, .is_i8xx = 1, .is_mobile = 1, .cursor_needs_physical = 1, |
65 | }; | 65 | }; |
66 | 66 | ||
67 | static const struct intel_device_info intel_845g_info = { | 67 | static const struct intel_device_info intel_845g_info = { |
68 | .is_i8xx = 1, | 68 | .gen = 2, .is_i8xx = 1, |
69 | }; | 69 | }; |
70 | 70 | ||
71 | static const struct intel_device_info intel_i85x_info = { | 71 | static const struct intel_device_info intel_i85x_info = { |
72 | .is_i8xx = 1, .is_i85x = 1, .is_mobile = 1, | 72 | .gen = 2, .is_i8xx = 1, .is_i85x = 1, .is_mobile = 1, |
73 | .cursor_needs_physical = 1, | 73 | .cursor_needs_physical = 1, |
74 | }; | 74 | }; |
75 | 75 | ||
76 | static const struct intel_device_info intel_i865g_info = { | 76 | static const struct intel_device_info intel_i865g_info = { |
77 | .is_i8xx = 1, | 77 | .gen = 2, .is_i8xx = 1, |
78 | }; | 78 | }; |
79 | 79 | ||
80 | static const struct intel_device_info intel_i915g_info = { | 80 | static const struct intel_device_info intel_i915g_info = { |
81 | .is_i915g = 1, .is_i9xx = 1, .cursor_needs_physical = 1, | 81 | .gen = 3, .is_i915g = 1, .is_i9xx = 1, .cursor_needs_physical = 1, |
82 | }; | 82 | }; |
83 | static const struct intel_device_info intel_i915gm_info = { | 83 | static const struct intel_device_info intel_i915gm_info = { |
84 | .is_i9xx = 1, .is_mobile = 1, | 84 | .gen = 3, .is_i9xx = 1, .is_mobile = 1, |
85 | .cursor_needs_physical = 1, | 85 | .cursor_needs_physical = 1, |
86 | }; | 86 | }; |
87 | static const struct intel_device_info intel_i945g_info = { | 87 | static const struct intel_device_info intel_i945g_info = { |
88 | .is_i9xx = 1, .has_hotplug = 1, .cursor_needs_physical = 1, | 88 | .gen = 3, .is_i9xx = 1, .has_hotplug = 1, .cursor_needs_physical = 1, |
89 | }; | 89 | }; |
90 | static const struct intel_device_info intel_i945gm_info = { | 90 | static const struct intel_device_info intel_i945gm_info = { |
91 | .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1, | 91 | .gen = 3, .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1, |
92 | .has_hotplug = 1, .cursor_needs_physical = 1, | 92 | .has_hotplug = 1, .cursor_needs_physical = 1, |
93 | }; | 93 | }; |
94 | 94 | ||
95 | static const struct intel_device_info intel_i965g_info = { | 95 | static const struct intel_device_info intel_i965g_info = { |
96 | .is_broadwater = 1, .is_i965g = 1, .is_i9xx = 1, .has_hotplug = 1, | 96 | .gen = 4, .is_broadwater = 1, .is_i965g = 1, .is_i9xx = 1, |
97 | .has_hotplug = 1, | ||
97 | }; | 98 | }; |
98 | 99 | ||
99 | static const struct intel_device_info intel_i965gm_info = { | 100 | static const struct intel_device_info intel_i965gm_info = { |
100 | .is_crestline = 1, .is_i965g = 1, .is_i965gm = 1, .is_i9xx = 1, | 101 | .gen = 4, .is_crestline = 1, .is_i965g = 1, .is_i965gm = 1, .is_i9xx = 1, |
101 | .is_mobile = 1, .has_fbc = 1, .has_rc6 = 1, | 102 | .is_mobile = 1, .has_fbc = 1, .has_rc6 = 1, .has_hotplug = 1, |
102 | .has_hotplug = 1, | ||
103 | }; | 103 | }; |
104 | 104 | ||
105 | static const struct intel_device_info intel_g33_info = { | 105 | static const struct intel_device_info intel_g33_info = { |
106 | .is_g33 = 1, .is_i9xx = 1, .need_gfx_hws = 1, | 106 | .gen = 3, .is_g33 = 1, .is_i9xx = 1, |
107 | .has_hotplug = 1, | 107 | .need_gfx_hws = 1, .has_hotplug = 1, |
108 | }; | 108 | }; |
109 | 109 | ||
110 | static const struct intel_device_info intel_g45_info = { | 110 | static const struct intel_device_info intel_g45_info = { |
111 | .is_i965g = 1, .is_g4x = 1, .is_i9xx = 1, .need_gfx_hws = 1, | 111 | .gen = 4, .is_i965g = 1, .is_g4x = 1, .is_i9xx = 1, .need_gfx_hws = 1, |
112 | .has_pipe_cxsr = 1, | 112 | .has_pipe_cxsr = 1, .has_hotplug = 1, |
113 | .has_hotplug = 1, | ||
114 | }; | 113 | }; |
115 | 114 | ||
116 | static const struct intel_device_info intel_gm45_info = { | 115 | static const struct intel_device_info intel_gm45_info = { |
117 | .is_i965g = 1, .is_g4x = 1, .is_i9xx = 1, | 116 | .gen = 4, .is_i965g = 1, .is_g4x = 1, .is_i9xx = 1, |
118 | .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1, | 117 | .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1, |
119 | .has_pipe_cxsr = 1, | 118 | .has_pipe_cxsr = 1, .has_hotplug = 1, |
120 | .has_hotplug = 1, | ||
121 | }; | 119 | }; |
122 | 120 | ||
123 | static const struct intel_device_info intel_pineview_info = { | 121 | static const struct intel_device_info intel_pineview_info = { |
124 | .is_g33 = 1, .is_pineview = 1, .is_mobile = 1, .is_i9xx = 1, | 122 | .gen = 3, .is_g33 = 1, .is_pineview = 1, .is_mobile = 1, .is_i9xx = 1, |
125 | .need_gfx_hws = 1, | 123 | .need_gfx_hws = 1, .has_hotplug = 1, |
126 | .has_hotplug = 1, | ||
127 | }; | 124 | }; |
128 | 125 | ||
129 | static const struct intel_device_info intel_ironlake_d_info = { | 126 | static const struct intel_device_info intel_ironlake_d_info = { |
130 | .is_ironlake = 1, .is_i965g = 1, .is_i9xx = 1, .need_gfx_hws = 1, | 127 | .gen = 5, .is_ironlake = 1, .is_i965g = 1, .is_i9xx = 1, |
131 | .has_pipe_cxsr = 1, | 128 | .need_gfx_hws = 1, .has_pipe_cxsr = 1, .has_hotplug = 1, |
132 | .has_hotplug = 1, | ||
133 | }; | 129 | }; |
134 | 130 | ||
135 | static const struct intel_device_info intel_ironlake_m_info = { | 131 | static const struct intel_device_info intel_ironlake_m_info = { |
136 | .is_ironlake = 1, .is_mobile = 1, .is_i965g = 1, .is_i9xx = 1, | 132 | .gen = 5, .is_ironlake = 1, .is_mobile = 1, .is_i965g = 1, .is_i9xx = 1, |
137 | .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1, | 133 | .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1, .has_hotplug = 1, |
138 | .has_hotplug = 1, | ||
139 | }; | 134 | }; |
140 | 135 | ||
141 | static const struct intel_device_info intel_sandybridge_d_info = { | 136 | static const struct intel_device_info intel_sandybridge_d_info = { |
142 | .is_i965g = 1, .is_i9xx = 1, .need_gfx_hws = 1, | 137 | .gen = 6, .is_i965g = 1, .is_i9xx = 1, |
143 | .has_hotplug = 1, .is_gen6 = 1, | 138 | .need_gfx_hws = 1, .has_hotplug = 1, |
144 | }; | 139 | }; |
145 | 140 | ||
146 | static const struct intel_device_info intel_sandybridge_m_info = { | 141 | static const struct intel_device_info intel_sandybridge_m_info = { |
147 | .is_i965g = 1, .is_mobile = 1, .is_i9xx = 1, .need_gfx_hws = 1, | 142 | .gen = 6, .is_i965g = 1, .is_mobile = 1, .is_i9xx = 1, |
148 | .has_hotplug = 1, .is_gen6 = 1, | 143 | .need_gfx_hws = 1, .has_hotplug = 1, |
149 | }; | 144 | }; |
150 | 145 | ||
151 | static const struct pci_device_id pciidlist[] = { /* aka */ | 146 | static const struct pci_device_id pciidlist[] = { /* aka */ |
@@ -175,13 +170,18 @@ static const struct pci_device_id pciidlist[] = { /* aka */ | |||
175 | INTEL_VGA_DEVICE(0x2e22, &intel_g45_info), /* G45_G */ | 170 | INTEL_VGA_DEVICE(0x2e22, &intel_g45_info), /* G45_G */ |
176 | INTEL_VGA_DEVICE(0x2e32, &intel_g45_info), /* G41_G */ | 171 | INTEL_VGA_DEVICE(0x2e32, &intel_g45_info), /* G41_G */ |
177 | INTEL_VGA_DEVICE(0x2e42, &intel_g45_info), /* B43_G */ | 172 | INTEL_VGA_DEVICE(0x2e42, &intel_g45_info), /* B43_G */ |
173 | INTEL_VGA_DEVICE(0x2e92, &intel_g45_info), /* B43_G.1 */ | ||
178 | INTEL_VGA_DEVICE(0xa001, &intel_pineview_info), | 174 | INTEL_VGA_DEVICE(0xa001, &intel_pineview_info), |
179 | INTEL_VGA_DEVICE(0xa011, &intel_pineview_info), | 175 | INTEL_VGA_DEVICE(0xa011, &intel_pineview_info), |
180 | INTEL_VGA_DEVICE(0x0042, &intel_ironlake_d_info), | 176 | INTEL_VGA_DEVICE(0x0042, &intel_ironlake_d_info), |
181 | INTEL_VGA_DEVICE(0x0046, &intel_ironlake_m_info), | 177 | INTEL_VGA_DEVICE(0x0046, &intel_ironlake_m_info), |
182 | INTEL_VGA_DEVICE(0x0102, &intel_sandybridge_d_info), | 178 | INTEL_VGA_DEVICE(0x0102, &intel_sandybridge_d_info), |
179 | INTEL_VGA_DEVICE(0x0112, &intel_sandybridge_d_info), | ||
180 | INTEL_VGA_DEVICE(0x0122, &intel_sandybridge_d_info), | ||
183 | INTEL_VGA_DEVICE(0x0106, &intel_sandybridge_m_info), | 181 | INTEL_VGA_DEVICE(0x0106, &intel_sandybridge_m_info), |
182 | INTEL_VGA_DEVICE(0x0116, &intel_sandybridge_m_info), | ||
184 | INTEL_VGA_DEVICE(0x0126, &intel_sandybridge_m_info), | 183 | INTEL_VGA_DEVICE(0x0126, &intel_sandybridge_m_info), |
184 | INTEL_VGA_DEVICE(0x010A, &intel_sandybridge_d_info), | ||
185 | {0, 0, 0} | 185 | {0, 0, 0} |
186 | }; | 186 | }; |
187 | 187 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 047cd7ce7e1..af4a263cf25 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -191,6 +191,7 @@ struct drm_i915_display_funcs { | |||
191 | }; | 191 | }; |
192 | 192 | ||
193 | struct intel_device_info { | 193 | struct intel_device_info { |
194 | u8 gen; | ||
194 | u8 is_mobile : 1; | 195 | u8 is_mobile : 1; |
195 | u8 is_i8xx : 1; | 196 | u8 is_i8xx : 1; |
196 | u8 is_i85x : 1; | 197 | u8 is_i85x : 1; |
@@ -206,7 +207,6 @@ struct intel_device_info { | |||
206 | u8 is_broadwater : 1; | 207 | u8 is_broadwater : 1; |
207 | u8 is_crestline : 1; | 208 | u8 is_crestline : 1; |
208 | u8 is_ironlake : 1; | 209 | u8 is_ironlake : 1; |
209 | u8 is_gen6 : 1; | ||
210 | u8 has_fbc : 1; | 210 | u8 has_fbc : 1; |
211 | u8 has_rc6 : 1; | 211 | u8 has_rc6 : 1; |
212 | u8 has_pipe_cxsr : 1; | 212 | u8 has_pipe_cxsr : 1; |
@@ -1162,7 +1162,6 @@ extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_ove | |||
1162 | #define IS_845G(dev) ((dev)->pci_device == 0x2562) | 1162 | #define IS_845G(dev) ((dev)->pci_device == 0x2562) |
1163 | #define IS_I85X(dev) (INTEL_INFO(dev)->is_i85x) | 1163 | #define IS_I85X(dev) (INTEL_INFO(dev)->is_i85x) |
1164 | #define IS_I865G(dev) ((dev)->pci_device == 0x2572) | 1164 | #define IS_I865G(dev) ((dev)->pci_device == 0x2572) |
1165 | #define IS_GEN2(dev) (INTEL_INFO(dev)->is_i8xx) | ||
1166 | #define IS_I915G(dev) (INTEL_INFO(dev)->is_i915g) | 1165 | #define IS_I915G(dev) (INTEL_INFO(dev)->is_i915g) |
1167 | #define IS_I915GM(dev) ((dev)->pci_device == 0x2592) | 1166 | #define IS_I915GM(dev) ((dev)->pci_device == 0x2592) |
1168 | #define IS_I945G(dev) ((dev)->pci_device == 0x2772) | 1167 | #define IS_I945G(dev) ((dev)->pci_device == 0x2772) |
@@ -1181,27 +1180,13 @@ extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_ove | |||
1181 | #define IS_IRONLAKE_M(dev) ((dev)->pci_device == 0x0046) | 1180 | #define IS_IRONLAKE_M(dev) ((dev)->pci_device == 0x0046) |
1182 | #define IS_IRONLAKE(dev) (INTEL_INFO(dev)->is_ironlake) | 1181 | #define IS_IRONLAKE(dev) (INTEL_INFO(dev)->is_ironlake) |
1183 | #define IS_I9XX(dev) (INTEL_INFO(dev)->is_i9xx) | 1182 | #define IS_I9XX(dev) (INTEL_INFO(dev)->is_i9xx) |
1184 | #define IS_GEN6(dev) (INTEL_INFO(dev)->is_gen6) | ||
1185 | #define IS_MOBILE(dev) (INTEL_INFO(dev)->is_mobile) | 1183 | #define IS_MOBILE(dev) (INTEL_INFO(dev)->is_mobile) |
1186 | 1184 | ||
1187 | #define IS_GEN3(dev) (IS_I915G(dev) || \ | 1185 | #define IS_GEN2(dev) (INTEL_INFO(dev)->gen == 2) |
1188 | IS_I915GM(dev) || \ | 1186 | #define IS_GEN3(dev) (INTEL_INFO(dev)->gen == 3) |
1189 | IS_I945G(dev) || \ | 1187 | #define IS_GEN4(dev) (INTEL_INFO(dev)->gen == 4) |
1190 | IS_I945GM(dev) || \ | 1188 | #define IS_GEN5(dev) (INTEL_INFO(dev)->gen == 5) |
1191 | IS_G33(dev) || \ | 1189 | #define IS_GEN6(dev) (INTEL_INFO(dev)->gen == 6) |
1192 | IS_PINEVIEW(dev)) | ||
1193 | #define IS_GEN4(dev) ((dev)->pci_device == 0x2972 || \ | ||
1194 | (dev)->pci_device == 0x2982 || \ | ||
1195 | (dev)->pci_device == 0x2992 || \ | ||
1196 | (dev)->pci_device == 0x29A2 || \ | ||
1197 | (dev)->pci_device == 0x2A02 || \ | ||
1198 | (dev)->pci_device == 0x2A12 || \ | ||
1199 | (dev)->pci_device == 0x2E02 || \ | ||
1200 | (dev)->pci_device == 0x2E12 || \ | ||
1201 | (dev)->pci_device == 0x2E22 || \ | ||
1202 | (dev)->pci_device == 0x2E32 || \ | ||
1203 | (dev)->pci_device == 0x2A42 || \ | ||
1204 | (dev)->pci_device == 0x2E42) | ||
1205 | 1190 | ||
1206 | #define HAS_BSD(dev) (IS_IRONLAKE(dev) || IS_G4X(dev)) | 1191 | #define HAS_BSD(dev) (IS_IRONLAKE(dev) || IS_G4X(dev)) |
1207 | #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) | 1192 | #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index df5a7135c26..90b1d6753b9 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | #include <linux/swap.h> | 35 | #include <linux/swap.h> |
36 | #include <linux/pci.h> | 36 | #include <linux/pci.h> |
37 | #include <linux/intel-gtt.h> | ||
37 | 38 | ||
38 | static uint32_t i915_gem_get_gtt_alignment(struct drm_gem_object *obj); | 39 | static uint32_t i915_gem_get_gtt_alignment(struct drm_gem_object *obj); |
39 | static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj); | 40 | static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj); |
@@ -135,12 +136,13 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data, | |||
135 | return -ENOMEM; | 136 | return -ENOMEM; |
136 | 137 | ||
137 | ret = drm_gem_handle_create(file_priv, obj, &handle); | 138 | ret = drm_gem_handle_create(file_priv, obj, &handle); |
139 | /* drop reference from allocate - handle holds it now */ | ||
138 | drm_gem_object_unreference_unlocked(obj); | 140 | drm_gem_object_unreference_unlocked(obj); |
139 | if (ret) | 141 | if (ret) { |
140 | return ret; | 142 | return ret; |
143 | } | ||
141 | 144 | ||
142 | args->handle = handle; | 145 | args->handle = handle; |
143 | |||
144 | return 0; | 146 | return 0; |
145 | } | 147 | } |
146 | 148 | ||
@@ -467,14 +469,17 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, | |||
467 | return -ENOENT; | 469 | return -ENOENT; |
468 | obj_priv = to_intel_bo(obj); | 470 | obj_priv = to_intel_bo(obj); |
469 | 471 | ||
470 | /* Bounds check source. | 472 | /* Bounds check source. */ |
471 | * | 473 | if (args->offset > obj->size || args->size > obj->size - args->offset) { |
472 | * XXX: This could use review for overflow issues... | 474 | ret = -EINVAL; |
473 | */ | 475 | goto err; |
474 | if (args->offset > obj->size || args->size > obj->size || | 476 | } |
475 | args->offset + args->size > obj->size) { | 477 | |
476 | drm_gem_object_unreference_unlocked(obj); | 478 | if (!access_ok(VERIFY_WRITE, |
477 | return -EINVAL; | 479 | (char __user *)(uintptr_t)args->data_ptr, |
480 | args->size)) { | ||
481 | ret = -EFAULT; | ||
482 | goto err; | ||
478 | } | 483 | } |
479 | 484 | ||
480 | if (i915_gem_object_needs_bit17_swizzle(obj)) { | 485 | if (i915_gem_object_needs_bit17_swizzle(obj)) { |
@@ -486,8 +491,8 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, | |||
486 | file_priv); | 491 | file_priv); |
487 | } | 492 | } |
488 | 493 | ||
494 | err: | ||
489 | drm_gem_object_unreference_unlocked(obj); | 495 | drm_gem_object_unreference_unlocked(obj); |
490 | |||
491 | return ret; | 496 | return ret; |
492 | } | 497 | } |
493 | 498 | ||
@@ -576,8 +581,6 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj, | |||
576 | 581 | ||
577 | user_data = (char __user *) (uintptr_t) args->data_ptr; | 582 | user_data = (char __user *) (uintptr_t) args->data_ptr; |
578 | remain = args->size; | 583 | remain = args->size; |
579 | if (!access_ok(VERIFY_READ, user_data, remain)) | ||
580 | return -EFAULT; | ||
581 | 584 | ||
582 | 585 | ||
583 | mutex_lock(&dev->struct_mutex); | 586 | mutex_lock(&dev->struct_mutex); |
@@ -930,14 +933,17 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, | |||
930 | return -ENOENT; | 933 | return -ENOENT; |
931 | obj_priv = to_intel_bo(obj); | 934 | obj_priv = to_intel_bo(obj); |
932 | 935 | ||
933 | /* Bounds check destination. | 936 | /* Bounds check destination. */ |
934 | * | 937 | if (args->offset > obj->size || args->size > obj->size - args->offset) { |
935 | * XXX: This could use review for overflow issues... | 938 | ret = -EINVAL; |
936 | */ | 939 | goto err; |
937 | if (args->offset > obj->size || args->size > obj->size || | 940 | } |
938 | args->offset + args->size > obj->size) { | 941 | |
939 | drm_gem_object_unreference_unlocked(obj); | 942 | if (!access_ok(VERIFY_READ, |
940 | return -EINVAL; | 943 | (char __user *)(uintptr_t)args->data_ptr, |
944 | args->size)) { | ||
945 | ret = -EFAULT; | ||
946 | goto err; | ||
941 | } | 947 | } |
942 | 948 | ||
943 | /* We can only do the GTT pwrite on untiled buffers, as otherwise | 949 | /* We can only do the GTT pwrite on untiled buffers, as otherwise |
@@ -971,8 +977,8 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, | |||
971 | DRM_INFO("pwrite failed %d\n", ret); | 977 | DRM_INFO("pwrite failed %d\n", ret); |
972 | #endif | 978 | #endif |
973 | 979 | ||
980 | err: | ||
974 | drm_gem_object_unreference_unlocked(obj); | 981 | drm_gem_object_unreference_unlocked(obj); |
975 | |||
976 | return ret; | 982 | return ret; |
977 | } | 983 | } |
978 | 984 | ||
@@ -2347,14 +2353,21 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj) | |||
2347 | 2353 | ||
2348 | reg->obj = obj; | 2354 | reg->obj = obj; |
2349 | 2355 | ||
2350 | if (IS_GEN6(dev)) | 2356 | switch (INTEL_INFO(dev)->gen) { |
2357 | case 6: | ||
2351 | sandybridge_write_fence_reg(reg); | 2358 | sandybridge_write_fence_reg(reg); |
2352 | else if (IS_I965G(dev)) | 2359 | break; |
2360 | case 5: | ||
2361 | case 4: | ||
2353 | i965_write_fence_reg(reg); | 2362 | i965_write_fence_reg(reg); |
2354 | else if (IS_I9XX(dev)) | 2363 | break; |
2364 | case 3: | ||
2355 | i915_write_fence_reg(reg); | 2365 | i915_write_fence_reg(reg); |
2356 | else | 2366 | break; |
2367 | case 2: | ||
2357 | i830_write_fence_reg(reg); | 2368 | i830_write_fence_reg(reg); |
2369 | break; | ||
2370 | } | ||
2358 | 2371 | ||
2359 | trace_i915_gem_object_get_fence(obj, obj_priv->fence_reg, | 2372 | trace_i915_gem_object_get_fence(obj, obj_priv->fence_reg, |
2360 | obj_priv->tiling_mode); | 2373 | obj_priv->tiling_mode); |
@@ -2377,22 +2390,26 @@ i915_gem_clear_fence_reg(struct drm_gem_object *obj) | |||
2377 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 2390 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
2378 | struct drm_i915_fence_reg *reg = | 2391 | struct drm_i915_fence_reg *reg = |
2379 | &dev_priv->fence_regs[obj_priv->fence_reg]; | 2392 | &dev_priv->fence_regs[obj_priv->fence_reg]; |
2393 | uint32_t fence_reg; | ||
2380 | 2394 | ||
2381 | if (IS_GEN6(dev)) { | 2395 | switch (INTEL_INFO(dev)->gen) { |
2396 | case 6: | ||
2382 | I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + | 2397 | I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + |
2383 | (obj_priv->fence_reg * 8), 0); | 2398 | (obj_priv->fence_reg * 8), 0); |
2384 | } else if (IS_I965G(dev)) { | 2399 | break; |
2400 | case 5: | ||
2401 | case 4: | ||
2385 | I915_WRITE64(FENCE_REG_965_0 + (obj_priv->fence_reg * 8), 0); | 2402 | I915_WRITE64(FENCE_REG_965_0 + (obj_priv->fence_reg * 8), 0); |
2386 | } else { | 2403 | break; |
2387 | uint32_t fence_reg; | 2404 | case 3: |
2388 | 2405 | if (obj_priv->fence_reg >= 8) | |
2389 | if (obj_priv->fence_reg < 8) | 2406 | fence_reg = FENCE_REG_945_8 + (obj_priv->fence_reg - 8) * 4; |
2390 | fence_reg = FENCE_REG_830_0 + obj_priv->fence_reg * 4; | ||
2391 | else | 2407 | else |
2392 | fence_reg = FENCE_REG_945_8 + (obj_priv->fence_reg - | 2408 | case 2: |
2393 | 8) * 4; | 2409 | fence_reg = FENCE_REG_830_0 + obj_priv->fence_reg * 4; |
2394 | 2410 | ||
2395 | I915_WRITE(fence_reg, 0); | 2411 | I915_WRITE(fence_reg, 0); |
2412 | break; | ||
2396 | } | 2413 | } |
2397 | 2414 | ||
2398 | reg->obj = NULL; | 2415 | reg->obj = NULL; |
@@ -3243,6 +3260,8 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, | |||
3243 | (int) reloc->offset, | 3260 | (int) reloc->offset, |
3244 | reloc->read_domains, | 3261 | reloc->read_domains, |
3245 | reloc->write_domain); | 3262 | reloc->write_domain); |
3263 | drm_gem_object_unreference(target_obj); | ||
3264 | i915_gem_object_unpin(obj); | ||
3246 | return -EINVAL; | 3265 | return -EINVAL; |
3247 | } | 3266 | } |
3248 | if (reloc->write_domain & I915_GEM_DOMAIN_CPU || | 3267 | if (reloc->write_domain & I915_GEM_DOMAIN_CPU || |
@@ -3585,6 +3604,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
3585 | if (ret != 0) { | 3604 | if (ret != 0) { |
3586 | DRM_ERROR("copy %d cliprects failed: %d\n", | 3605 | DRM_ERROR("copy %d cliprects failed: %d\n", |
3587 | args->num_cliprects, ret); | 3606 | args->num_cliprects, ret); |
3607 | ret = -EFAULT; | ||
3588 | goto pre_mutex_err; | 3608 | goto pre_mutex_err; |
3589 | } | 3609 | } |
3590 | } | 3610 | } |
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index 72cae3cccad..5c428fa3e0b 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c | |||
@@ -79,6 +79,7 @@ mark_free(struct drm_i915_gem_object *obj_priv, | |||
79 | struct list_head *unwind) | 79 | struct list_head *unwind) |
80 | { | 80 | { |
81 | list_add(&obj_priv->evict_list, unwind); | 81 | list_add(&obj_priv->evict_list, unwind); |
82 | drm_gem_object_reference(&obj_priv->base); | ||
82 | return drm_mm_scan_add_block(obj_priv->gtt_space); | 83 | return drm_mm_scan_add_block(obj_priv->gtt_space); |
83 | } | 84 | } |
84 | 85 | ||
@@ -92,7 +93,7 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignmen | |||
92 | { | 93 | { |
93 | drm_i915_private_t *dev_priv = dev->dev_private; | 94 | drm_i915_private_t *dev_priv = dev->dev_private; |
94 | struct list_head eviction_list, unwind_list; | 95 | struct list_head eviction_list, unwind_list; |
95 | struct drm_i915_gem_object *obj_priv, *tmp_obj_priv; | 96 | struct drm_i915_gem_object *obj_priv; |
96 | struct list_head *render_iter, *bsd_iter; | 97 | struct list_head *render_iter, *bsd_iter; |
97 | int ret = 0; | 98 | int ret = 0; |
98 | 99 | ||
@@ -165,6 +166,7 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignmen | |||
165 | list_for_each_entry(obj_priv, &unwind_list, evict_list) { | 166 | list_for_each_entry(obj_priv, &unwind_list, evict_list) { |
166 | ret = drm_mm_scan_remove_block(obj_priv->gtt_space); | 167 | ret = drm_mm_scan_remove_block(obj_priv->gtt_space); |
167 | BUG_ON(ret); | 168 | BUG_ON(ret); |
169 | drm_gem_object_unreference(&obj_priv->base); | ||
168 | } | 170 | } |
169 | 171 | ||
170 | /* We expect the caller to unpin, evict all and try again, or give up. | 172 | /* We expect the caller to unpin, evict all and try again, or give up. |
@@ -173,36 +175,34 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignmen | |||
173 | return -ENOSPC; | 175 | return -ENOSPC; |
174 | 176 | ||
175 | found: | 177 | found: |
178 | /* drm_mm doesn't allow any other other operations while | ||
179 | * scanning, therefore store to be evicted objects on a | ||
180 | * temporary list. */ | ||
176 | INIT_LIST_HEAD(&eviction_list); | 181 | INIT_LIST_HEAD(&eviction_list); |
177 | list_for_each_entry_safe(obj_priv, tmp_obj_priv, | 182 | while (!list_empty(&unwind_list)) { |
178 | &unwind_list, evict_list) { | 183 | obj_priv = list_first_entry(&unwind_list, |
184 | struct drm_i915_gem_object, | ||
185 | evict_list); | ||
179 | if (drm_mm_scan_remove_block(obj_priv->gtt_space)) { | 186 | if (drm_mm_scan_remove_block(obj_priv->gtt_space)) { |
180 | /* drm_mm doesn't allow any other other operations while | ||
181 | * scanning, therefore store to be evicted objects on a | ||
182 | * temporary list. */ | ||
183 | list_move(&obj_priv->evict_list, &eviction_list); | 187 | list_move(&obj_priv->evict_list, &eviction_list); |
188 | continue; | ||
184 | } | 189 | } |
190 | list_del(&obj_priv->evict_list); | ||
191 | drm_gem_object_unreference(&obj_priv->base); | ||
185 | } | 192 | } |
186 | 193 | ||
187 | /* Unbinding will emit any required flushes */ | 194 | /* Unbinding will emit any required flushes */ |
188 | list_for_each_entry_safe(obj_priv, tmp_obj_priv, | 195 | while (!list_empty(&eviction_list)) { |
189 | &eviction_list, evict_list) { | 196 | obj_priv = list_first_entry(&eviction_list, |
190 | #if WATCH_LRU | 197 | struct drm_i915_gem_object, |
191 | DRM_INFO("%s: evicting %p\n", __func__, obj); | 198 | evict_list); |
192 | #endif | 199 | if (ret == 0) |
193 | ret = i915_gem_object_unbind(&obj_priv->base); | 200 | ret = i915_gem_object_unbind(&obj_priv->base); |
194 | if (ret) | 201 | list_del(&obj_priv->evict_list); |
195 | return ret; | 202 | drm_gem_object_unreference(&obj_priv->base); |
196 | } | 203 | } |
197 | 204 | ||
198 | /* The just created free hole should be on the top of the free stack | 205 | return ret; |
199 | * maintained by drm_mm, so this BUG_ON actually executes in O(1). | ||
200 | * Furthermore all accessed data has just recently been used, so it | ||
201 | * should be really fast, too. */ | ||
202 | BUG_ON(!drm_mm_search_free(&dev_priv->mm.gtt_space, min_size, | ||
203 | alignment, 0)); | ||
204 | |||
205 | return 0; | ||
206 | } | 206 | } |
207 | 207 | ||
208 | int | 208 | int |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 16861b800fe..744225ebb4b 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -887,6 +887,49 @@ static void i915_handle_error(struct drm_device *dev, bool wedged) | |||
887 | queue_work(dev_priv->wq, &dev_priv->error_work); | 887 | queue_work(dev_priv->wq, &dev_priv->error_work); |
888 | } | 888 | } |
889 | 889 | ||
890 | static void i915_pageflip_stall_check(struct drm_device *dev, int pipe) | ||
891 | { | ||
892 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
893 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; | ||
894 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
895 | struct drm_i915_gem_object *obj_priv; | ||
896 | struct intel_unpin_work *work; | ||
897 | unsigned long flags; | ||
898 | bool stall_detected; | ||
899 | |||
900 | /* Ignore early vblank irqs */ | ||
901 | if (intel_crtc == NULL) | ||
902 | return; | ||
903 | |||
904 | spin_lock_irqsave(&dev->event_lock, flags); | ||
905 | work = intel_crtc->unpin_work; | ||
906 | |||
907 | if (work == NULL || work->pending || !work->enable_stall_check) { | ||
908 | /* Either the pending flip IRQ arrived, or we're too early. Don't check */ | ||
909 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
910 | return; | ||
911 | } | ||
912 | |||
913 | /* Potential stall - if we see that the flip has happened, assume a missed interrupt */ | ||
914 | obj_priv = to_intel_bo(work->pending_flip_obj); | ||
915 | if(IS_I965G(dev)) { | ||
916 | int dspsurf = intel_crtc->plane == 0 ? DSPASURF : DSPBSURF; | ||
917 | stall_detected = I915_READ(dspsurf) == obj_priv->gtt_offset; | ||
918 | } else { | ||
919 | int dspaddr = intel_crtc->plane == 0 ? DSPAADDR : DSPBADDR; | ||
920 | stall_detected = I915_READ(dspaddr) == (obj_priv->gtt_offset + | ||
921 | crtc->y * crtc->fb->pitch + | ||
922 | crtc->x * crtc->fb->bits_per_pixel/8); | ||
923 | } | ||
924 | |||
925 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
926 | |||
927 | if (stall_detected) { | ||
928 | DRM_DEBUG_DRIVER("Pageflip stall detected\n"); | ||
929 | intel_prepare_page_flip(dev, intel_crtc->plane); | ||
930 | } | ||
931 | } | ||
932 | |||
890 | irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | 933 | irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) |
891 | { | 934 | { |
892 | struct drm_device *dev = (struct drm_device *) arg; | 935 | struct drm_device *dev = (struct drm_device *) arg; |
@@ -1004,15 +1047,19 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | |||
1004 | if (pipea_stats & vblank_status) { | 1047 | if (pipea_stats & vblank_status) { |
1005 | vblank++; | 1048 | vblank++; |
1006 | drm_handle_vblank(dev, 0); | 1049 | drm_handle_vblank(dev, 0); |
1007 | if (!dev_priv->flip_pending_is_done) | 1050 | if (!dev_priv->flip_pending_is_done) { |
1051 | i915_pageflip_stall_check(dev, 0); | ||
1008 | intel_finish_page_flip(dev, 0); | 1052 | intel_finish_page_flip(dev, 0); |
1053 | } | ||
1009 | } | 1054 | } |
1010 | 1055 | ||
1011 | if (pipeb_stats & vblank_status) { | 1056 | if (pipeb_stats & vblank_status) { |
1012 | vblank++; | 1057 | vblank++; |
1013 | drm_handle_vblank(dev, 1); | 1058 | drm_handle_vblank(dev, 1); |
1014 | if (!dev_priv->flip_pending_is_done) | 1059 | if (!dev_priv->flip_pending_is_done) { |
1060 | i915_pageflip_stall_check(dev, 1); | ||
1015 | intel_finish_page_flip(dev, 1); | 1061 | intel_finish_page_flip(dev, 1); |
1062 | } | ||
1016 | } | 1063 | } |
1017 | 1064 | ||
1018 | if ((pipea_stats & PIPE_LEGACY_BLC_EVENT_STATUS) || | 1065 | if ((pipea_stats & PIPE_LEGACY_BLC_EVENT_STATUS) || |
@@ -1303,17 +1350,25 @@ void i915_hangcheck_elapsed(unsigned long data) | |||
1303 | i915_seqno_passed(i915_get_gem_seqno(dev, | 1350 | i915_seqno_passed(i915_get_gem_seqno(dev, |
1304 | &dev_priv->render_ring), | 1351 | &dev_priv->render_ring), |
1305 | i915_get_tail_request(dev)->seqno)) { | 1352 | i915_get_tail_request(dev)->seqno)) { |
1353 | bool missed_wakeup = false; | ||
1354 | |||
1306 | dev_priv->hangcheck_count = 0; | 1355 | dev_priv->hangcheck_count = 0; |
1307 | 1356 | ||
1308 | /* Issue a wake-up to catch stuck h/w. */ | 1357 | /* Issue a wake-up to catch stuck h/w. */ |
1309 | if (dev_priv->render_ring.waiting_gem_seqno | | 1358 | if (dev_priv->render_ring.waiting_gem_seqno && |
1310 | dev_priv->bsd_ring.waiting_gem_seqno) { | 1359 | waitqueue_active(&dev_priv->render_ring.irq_queue)) { |
1311 | DRM_ERROR("Hangcheck timer elapsed... GPU idle, missed IRQ.\n"); | 1360 | DRM_WAKEUP(&dev_priv->render_ring.irq_queue); |
1312 | if (dev_priv->render_ring.waiting_gem_seqno) | 1361 | missed_wakeup = true; |
1313 | DRM_WAKEUP(&dev_priv->render_ring.irq_queue); | ||
1314 | if (dev_priv->bsd_ring.waiting_gem_seqno) | ||
1315 | DRM_WAKEUP(&dev_priv->bsd_ring.irq_queue); | ||
1316 | } | 1362 | } |
1363 | |||
1364 | if (dev_priv->bsd_ring.waiting_gem_seqno && | ||
1365 | waitqueue_active(&dev_priv->bsd_ring.irq_queue)) { | ||
1366 | DRM_WAKEUP(&dev_priv->bsd_ring.irq_queue); | ||
1367 | missed_wakeup = true; | ||
1368 | } | ||
1369 | |||
1370 | if (missed_wakeup) | ||
1371 | DRM_ERROR("Hangcheck timer elapsed... GPU idle, missed IRQ.\n"); | ||
1317 | return; | 1372 | return; |
1318 | } | 1373 | } |
1319 | 1374 | ||
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 67e3ec1a6af..4f5e15577e8 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -319,6 +319,7 @@ | |||
319 | 319 | ||
320 | #define MI_MODE 0x0209c | 320 | #define MI_MODE 0x0209c |
321 | # define VS_TIMER_DISPATCH (1 << 6) | 321 | # define VS_TIMER_DISPATCH (1 << 6) |
322 | # define MI_FLUSH_ENABLE (1 << 11) | ||
322 | 323 | ||
323 | #define SCPD0 0x0209c /* 915+ only */ | 324 | #define SCPD0 0x0209c /* 915+ only */ |
324 | #define IER 0x020a0 | 325 | #define IER 0x020a0 |
@@ -2205,9 +2206,17 @@ | |||
2205 | #define WM1_LP_SR_EN (1<<31) | 2206 | #define WM1_LP_SR_EN (1<<31) |
2206 | #define WM1_LP_LATENCY_SHIFT 24 | 2207 | #define WM1_LP_LATENCY_SHIFT 24 |
2207 | #define WM1_LP_LATENCY_MASK (0x7f<<24) | 2208 | #define WM1_LP_LATENCY_MASK (0x7f<<24) |
2209 | #define WM1_LP_FBC_LP1_MASK (0xf<<20) | ||
2210 | #define WM1_LP_FBC_LP1_SHIFT 20 | ||
2208 | #define WM1_LP_SR_MASK (0x1ff<<8) | 2211 | #define WM1_LP_SR_MASK (0x1ff<<8) |
2209 | #define WM1_LP_SR_SHIFT 8 | 2212 | #define WM1_LP_SR_SHIFT 8 |
2210 | #define WM1_LP_CURSOR_MASK (0x3f) | 2213 | #define WM1_LP_CURSOR_MASK (0x3f) |
2214 | #define WM2_LP_ILK 0x4510c | ||
2215 | #define WM2_LP_EN (1<<31) | ||
2216 | #define WM3_LP_ILK 0x45110 | ||
2217 | #define WM3_LP_EN (1<<31) | ||
2218 | #define WM1S_LP_ILK 0x45120 | ||
2219 | #define WM1S_LP_EN (1<<31) | ||
2211 | 2220 | ||
2212 | /* Memory latency timer register */ | 2221 | /* Memory latency timer register */ |
2213 | #define MLTR_ILK 0x11222 | 2222 | #define MLTR_ILK 0x11222 |
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 2c6b98f2440..31f08581e93 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
@@ -789,16 +789,25 @@ int i915_save_state(struct drm_device *dev) | |||
789 | dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2)); | 789 | dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2)); |
790 | 790 | ||
791 | /* Fences */ | 791 | /* Fences */ |
792 | if (IS_I965G(dev)) { | 792 | switch (INTEL_INFO(dev)->gen) { |
793 | case 6: | ||
794 | for (i = 0; i < 16; i++) | ||
795 | dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); | ||
796 | break; | ||
797 | case 5: | ||
798 | case 4: | ||
793 | for (i = 0; i < 16; i++) | 799 | for (i = 0; i < 16; i++) |
794 | dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_965_0 + (i * 8)); | 800 | dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_965_0 + (i * 8)); |
795 | } else { | 801 | break; |
796 | for (i = 0; i < 8; i++) | 802 | case 3: |
797 | dev_priv->saveFENCE[i] = I915_READ(FENCE_REG_830_0 + (i * 4)); | ||
798 | |||
799 | if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) | 803 | if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) |
800 | for (i = 0; i < 8; i++) | 804 | for (i = 0; i < 8; i++) |
801 | dev_priv->saveFENCE[i+8] = I915_READ(FENCE_REG_945_8 + (i * 4)); | 805 | dev_priv->saveFENCE[i+8] = I915_READ(FENCE_REG_945_8 + (i * 4)); |
806 | case 2: | ||
807 | for (i = 0; i < 8; i++) | ||
808 | dev_priv->saveFENCE[i] = I915_READ(FENCE_REG_830_0 + (i * 4)); | ||
809 | break; | ||
810 | |||
802 | } | 811 | } |
803 | 812 | ||
804 | return 0; | 813 | return 0; |
@@ -815,15 +824,24 @@ int i915_restore_state(struct drm_device *dev) | |||
815 | I915_WRITE(HWS_PGA, dev_priv->saveHWS); | 824 | I915_WRITE(HWS_PGA, dev_priv->saveHWS); |
816 | 825 | ||
817 | /* Fences */ | 826 | /* Fences */ |
818 | if (IS_I965G(dev)) { | 827 | switch (INTEL_INFO(dev)->gen) { |
828 | case 6: | ||
829 | for (i = 0; i < 16; i++) | ||
830 | I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (i * 8), dev_priv->saveFENCE[i]); | ||
831 | break; | ||
832 | case 5: | ||
833 | case 4: | ||
819 | for (i = 0; i < 16; i++) | 834 | for (i = 0; i < 16; i++) |
820 | I915_WRITE64(FENCE_REG_965_0 + (i * 8), dev_priv->saveFENCE[i]); | 835 | I915_WRITE64(FENCE_REG_965_0 + (i * 8), dev_priv->saveFENCE[i]); |
821 | } else { | 836 | break; |
822 | for (i = 0; i < 8; i++) | 837 | case 3: |
823 | I915_WRITE(FENCE_REG_830_0 + (i * 4), dev_priv->saveFENCE[i]); | 838 | case 2: |
824 | if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) | 839 | if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) |
825 | for (i = 0; i < 8; i++) | 840 | for (i = 0; i < 8; i++) |
826 | I915_WRITE(FENCE_REG_945_8 + (i * 4), dev_priv->saveFENCE[i+8]); | 841 | I915_WRITE(FENCE_REG_945_8 + (i * 4), dev_priv->saveFENCE[i+8]); |
842 | for (i = 0; i < 8; i++) | ||
843 | I915_WRITE(FENCE_REG_830_0 + (i * 4), dev_priv->saveFENCE[i]); | ||
844 | break; | ||
827 | } | 845 | } |
828 | 846 | ||
829 | i915_restore_display(dev); | 847 | i915_restore_display(dev); |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 4b7735196cd..197d4f32585 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -188,7 +188,7 @@ static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector) | |||
188 | 188 | ||
189 | if (wait_for((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0, | 189 | if (wait_for((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0, |
190 | 1000, 1)) | 190 | 1000, 1)) |
191 | DRM_ERROR("timed out waiting for FORCE_TRIGGER"); | 191 | DRM_DEBUG_KMS("timed out waiting for FORCE_TRIGGER"); |
192 | 192 | ||
193 | if (turn_off_dac) { | 193 | if (turn_off_dac) { |
194 | I915_WRITE(PCH_ADPA, temp); | 194 | I915_WRITE(PCH_ADPA, temp); |
@@ -245,7 +245,7 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) | |||
245 | if (wait_for((I915_READ(PORT_HOTPLUG_EN) & | 245 | if (wait_for((I915_READ(PORT_HOTPLUG_EN) & |
246 | CRT_HOTPLUG_FORCE_DETECT) == 0, | 246 | CRT_HOTPLUG_FORCE_DETECT) == 0, |
247 | 1000, 1)) | 247 | 1000, 1)) |
248 | DRM_ERROR("timed out waiting for FORCE_DETECT to go off"); | 248 | DRM_DEBUG_KMS("timed out waiting for FORCE_DETECT to go off"); |
249 | } | 249 | } |
250 | 250 | ||
251 | stat = I915_READ(PORT_HOTPLUG_STAT); | 251 | stat = I915_READ(PORT_HOTPLUG_STAT); |
@@ -400,7 +400,8 @@ intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder | |||
400 | return status; | 400 | return status; |
401 | } | 401 | } |
402 | 402 | ||
403 | static enum drm_connector_status intel_crt_detect(struct drm_connector *connector) | 403 | static enum drm_connector_status |
404 | intel_crt_detect(struct drm_connector *connector, bool force) | ||
404 | { | 405 | { |
405 | struct drm_device *dev = connector->dev; | 406 | struct drm_device *dev = connector->dev; |
406 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 407 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
@@ -419,6 +420,9 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connecto | |||
419 | if (intel_crt_detect_ddc(encoder)) | 420 | if (intel_crt_detect_ddc(encoder)) |
420 | return connector_status_connected; | 421 | return connector_status_connected; |
421 | 422 | ||
423 | if (!force) | ||
424 | return connector->status; | ||
425 | |||
422 | /* for pre-945g platforms use load detect */ | 426 | /* for pre-945g platforms use load detect */ |
423 | if (encoder->crtc && encoder->crtc->enabled) { | 427 | if (encoder->crtc && encoder->crtc->enabled) { |
424 | status = intel_crt_load_detect(encoder->crtc, intel_encoder); | 428 | status = intel_crt_load_detect(encoder->crtc, intel_encoder); |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 23157e1de3b..97922859459 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -990,15 +990,31 @@ void intel_wait_for_vblank(struct drm_device *dev, int pipe) | |||
990 | struct drm_i915_private *dev_priv = dev->dev_private; | 990 | struct drm_i915_private *dev_priv = dev->dev_private; |
991 | int pipestat_reg = (pipe == 0 ? PIPEASTAT : PIPEBSTAT); | 991 | int pipestat_reg = (pipe == 0 ? PIPEASTAT : PIPEBSTAT); |
992 | 992 | ||
993 | /* Clear existing vblank status. Note this will clear any other | ||
994 | * sticky status fields as well. | ||
995 | * | ||
996 | * This races with i915_driver_irq_handler() with the result | ||
997 | * that either function could miss a vblank event. Here it is not | ||
998 | * fatal, as we will either wait upon the next vblank interrupt or | ||
999 | * timeout. Generally speaking intel_wait_for_vblank() is only | ||
1000 | * called during modeset at which time the GPU should be idle and | ||
1001 | * should *not* be performing page flips and thus not waiting on | ||
1002 | * vblanks... | ||
1003 | * Currently, the result of us stealing a vblank from the irq | ||
1004 | * handler is that a single frame will be skipped during swapbuffers. | ||
1005 | */ | ||
1006 | I915_WRITE(pipestat_reg, | ||
1007 | I915_READ(pipestat_reg) | PIPE_VBLANK_INTERRUPT_STATUS); | ||
1008 | |||
993 | /* Wait for vblank interrupt bit to set */ | 1009 | /* Wait for vblank interrupt bit to set */ |
994 | if (wait_for((I915_READ(pipestat_reg) & | 1010 | if (wait_for((I915_READ(pipestat_reg) & |
995 | PIPE_VBLANK_INTERRUPT_STATUS) == 0, | 1011 | PIPE_VBLANK_INTERRUPT_STATUS), |
996 | 50, 0)) | 1012 | 50, 0)) |
997 | DRM_DEBUG_KMS("vblank wait timed out\n"); | 1013 | DRM_DEBUG_KMS("vblank wait timed out\n"); |
998 | } | 1014 | } |
999 | 1015 | ||
1000 | /** | 1016 | /* |
1001 | * intel_wait_for_vblank_off - wait for vblank after disabling a pipe | 1017 | * intel_wait_for_pipe_off - wait for pipe to turn off |
1002 | * @dev: drm device | 1018 | * @dev: drm device |
1003 | * @pipe: pipe to wait for | 1019 | * @pipe: pipe to wait for |
1004 | * | 1020 | * |
@@ -1006,25 +1022,39 @@ void intel_wait_for_vblank(struct drm_device *dev, int pipe) | |||
1006 | * spinning on the vblank interrupt status bit, since we won't actually | 1022 | * spinning on the vblank interrupt status bit, since we won't actually |
1007 | * see an interrupt when the pipe is disabled. | 1023 | * see an interrupt when the pipe is disabled. |
1008 | * | 1024 | * |
1009 | * So this function waits for the display line value to settle (it | 1025 | * On Gen4 and above: |
1010 | * usually ends up stopping at the start of the next frame). | 1026 | * wait for the pipe register state bit to turn off |
1027 | * | ||
1028 | * Otherwise: | ||
1029 | * wait for the display line value to settle (it usually | ||
1030 | * ends up stopping at the start of the next frame). | ||
1031 | * | ||
1011 | */ | 1032 | */ |
1012 | void intel_wait_for_vblank_off(struct drm_device *dev, int pipe) | 1033 | static void intel_wait_for_pipe_off(struct drm_device *dev, int pipe) |
1013 | { | 1034 | { |
1014 | struct drm_i915_private *dev_priv = dev->dev_private; | 1035 | struct drm_i915_private *dev_priv = dev->dev_private; |
1015 | int pipedsl_reg = (pipe == 0 ? PIPEADSL : PIPEBDSL); | 1036 | |
1016 | unsigned long timeout = jiffies + msecs_to_jiffies(100); | 1037 | if (INTEL_INFO(dev)->gen >= 4) { |
1017 | u32 last_line; | 1038 | int pipeconf_reg = (pipe == 0 ? PIPEACONF : PIPEBCONF); |
1018 | 1039 | ||
1019 | /* Wait for the display line to settle */ | 1040 | /* Wait for the Pipe State to go off */ |
1020 | do { | 1041 | if (wait_for((I915_READ(pipeconf_reg) & I965_PIPECONF_ACTIVE) == 0, |
1021 | last_line = I915_READ(pipedsl_reg) & DSL_LINEMASK; | 1042 | 100, 0)) |
1022 | mdelay(5); | 1043 | DRM_DEBUG_KMS("pipe_off wait timed out\n"); |
1023 | } while (((I915_READ(pipedsl_reg) & DSL_LINEMASK) != last_line) && | 1044 | } else { |
1024 | time_after(timeout, jiffies)); | 1045 | u32 last_line; |
1025 | 1046 | int pipedsl_reg = (pipe == 0 ? PIPEADSL : PIPEBDSL); | |
1026 | if (time_after(jiffies, timeout)) | 1047 | unsigned long timeout = jiffies + msecs_to_jiffies(100); |
1027 | DRM_DEBUG_KMS("vblank wait timed out\n"); | 1048 | |
1049 | /* Wait for the display line to settle */ | ||
1050 | do { | ||
1051 | last_line = I915_READ(pipedsl_reg) & DSL_LINEMASK; | ||
1052 | mdelay(5); | ||
1053 | } while (((I915_READ(pipedsl_reg) & DSL_LINEMASK) != last_line) && | ||
1054 | time_after(timeout, jiffies)); | ||
1055 | if (time_after(jiffies, timeout)) | ||
1056 | DRM_DEBUG_KMS("pipe_off wait timed out\n"); | ||
1057 | } | ||
1028 | } | 1058 | } |
1029 | 1059 | ||
1030 | /* Parameters have changed, update FBC info */ | 1060 | /* Parameters have changed, update FBC info */ |
@@ -1486,7 +1516,7 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, | |||
1486 | dspcntr &= ~DISPPLANE_TILED; | 1516 | dspcntr &= ~DISPPLANE_TILED; |
1487 | } | 1517 | } |
1488 | 1518 | ||
1489 | if (IS_IRONLAKE(dev)) | 1519 | if (HAS_PCH_SPLIT(dev)) |
1490 | /* must disable */ | 1520 | /* must disable */ |
1491 | dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE; | 1521 | dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE; |
1492 | 1522 | ||
@@ -1495,20 +1525,19 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, | |||
1495 | Start = obj_priv->gtt_offset; | 1525 | Start = obj_priv->gtt_offset; |
1496 | Offset = y * fb->pitch + x * (fb->bits_per_pixel / 8); | 1526 | Offset = y * fb->pitch + x * (fb->bits_per_pixel / 8); |
1497 | 1527 | ||
1498 | DRM_DEBUG("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y); | 1528 | DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n", |
1529 | Start, Offset, x, y, fb->pitch); | ||
1499 | I915_WRITE(dspstride, fb->pitch); | 1530 | I915_WRITE(dspstride, fb->pitch); |
1500 | if (IS_I965G(dev)) { | 1531 | if (IS_I965G(dev)) { |
1501 | I915_WRITE(dspbase, Offset); | ||
1502 | I915_READ(dspbase); | ||
1503 | I915_WRITE(dspsurf, Start); | 1532 | I915_WRITE(dspsurf, Start); |
1504 | I915_READ(dspsurf); | ||
1505 | I915_WRITE(dsptileoff, (y << 16) | x); | 1533 | I915_WRITE(dsptileoff, (y << 16) | x); |
1534 | I915_WRITE(dspbase, Offset); | ||
1506 | } else { | 1535 | } else { |
1507 | I915_WRITE(dspbase, Start + Offset); | 1536 | I915_WRITE(dspbase, Start + Offset); |
1508 | I915_READ(dspbase); | ||
1509 | } | 1537 | } |
1538 | POSTING_READ(dspbase); | ||
1510 | 1539 | ||
1511 | if ((IS_I965G(dev) || plane == 0)) | 1540 | if (IS_I965G(dev) || plane == 0) |
1512 | intel_update_fbc(crtc, &crtc->mode); | 1541 | intel_update_fbc(crtc, &crtc->mode); |
1513 | 1542 | ||
1514 | intel_wait_for_vblank(dev, intel_crtc->pipe); | 1543 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
@@ -1522,7 +1551,6 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
1522 | struct drm_framebuffer *old_fb) | 1551 | struct drm_framebuffer *old_fb) |
1523 | { | 1552 | { |
1524 | struct drm_device *dev = crtc->dev; | 1553 | struct drm_device *dev = crtc->dev; |
1525 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1526 | struct drm_i915_master_private *master_priv; | 1554 | struct drm_i915_master_private *master_priv; |
1527 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 1555 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1528 | struct intel_framebuffer *intel_fb; | 1556 | struct intel_framebuffer *intel_fb; |
@@ -1530,13 +1558,6 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
1530 | struct drm_gem_object *obj; | 1558 | struct drm_gem_object *obj; |
1531 | int pipe = intel_crtc->pipe; | 1559 | int pipe = intel_crtc->pipe; |
1532 | int plane = intel_crtc->plane; | 1560 | int plane = intel_crtc->plane; |
1533 | unsigned long Start, Offset; | ||
1534 | int dspbase = (plane == 0 ? DSPAADDR : DSPBADDR); | ||
1535 | int dspsurf = (plane == 0 ? DSPASURF : DSPBSURF); | ||
1536 | int dspstride = (plane == 0) ? DSPASTRIDE : DSPBSTRIDE; | ||
1537 | int dsptileoff = (plane == 0 ? DSPATILEOFF : DSPBTILEOFF); | ||
1538 | int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR; | ||
1539 | u32 dspcntr; | ||
1540 | int ret; | 1561 | int ret; |
1541 | 1562 | ||
1542 | /* no fb bound */ | 1563 | /* no fb bound */ |
@@ -1572,71 +1593,18 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
1572 | return ret; | 1593 | return ret; |
1573 | } | 1594 | } |
1574 | 1595 | ||
1575 | dspcntr = I915_READ(dspcntr_reg); | 1596 | ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y); |
1576 | /* Mask out pixel format bits in case we change it */ | 1597 | if (ret) { |
1577 | dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; | ||
1578 | switch (crtc->fb->bits_per_pixel) { | ||
1579 | case 8: | ||
1580 | dspcntr |= DISPPLANE_8BPP; | ||
1581 | break; | ||
1582 | case 16: | ||
1583 | if (crtc->fb->depth == 15) | ||
1584 | dspcntr |= DISPPLANE_15_16BPP; | ||
1585 | else | ||
1586 | dspcntr |= DISPPLANE_16BPP; | ||
1587 | break; | ||
1588 | case 24: | ||
1589 | case 32: | ||
1590 | if (crtc->fb->depth == 30) | ||
1591 | dspcntr |= DISPPLANE_32BPP_30BIT_NO_ALPHA; | ||
1592 | else | ||
1593 | dspcntr |= DISPPLANE_32BPP_NO_ALPHA; | ||
1594 | break; | ||
1595 | default: | ||
1596 | DRM_ERROR("Unknown color depth\n"); | ||
1597 | i915_gem_object_unpin(obj); | 1598 | i915_gem_object_unpin(obj); |
1598 | mutex_unlock(&dev->struct_mutex); | 1599 | mutex_unlock(&dev->struct_mutex); |
1599 | return -EINVAL; | 1600 | return ret; |
1600 | } | ||
1601 | if (IS_I965G(dev)) { | ||
1602 | if (obj_priv->tiling_mode != I915_TILING_NONE) | ||
1603 | dspcntr |= DISPPLANE_TILED; | ||
1604 | else | ||
1605 | dspcntr &= ~DISPPLANE_TILED; | ||
1606 | } | ||
1607 | |||
1608 | if (HAS_PCH_SPLIT(dev)) | ||
1609 | /* must disable */ | ||
1610 | dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE; | ||
1611 | |||
1612 | I915_WRITE(dspcntr_reg, dspcntr); | ||
1613 | |||
1614 | Start = obj_priv->gtt_offset; | ||
1615 | Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8); | ||
1616 | |||
1617 | DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n", | ||
1618 | Start, Offset, x, y, crtc->fb->pitch); | ||
1619 | I915_WRITE(dspstride, crtc->fb->pitch); | ||
1620 | if (IS_I965G(dev)) { | ||
1621 | I915_WRITE(dspsurf, Start); | ||
1622 | I915_WRITE(dsptileoff, (y << 16) | x); | ||
1623 | I915_WRITE(dspbase, Offset); | ||
1624 | } else { | ||
1625 | I915_WRITE(dspbase, Start + Offset); | ||
1626 | } | 1601 | } |
1627 | POSTING_READ(dspbase); | ||
1628 | |||
1629 | if ((IS_I965G(dev) || plane == 0)) | ||
1630 | intel_update_fbc(crtc, &crtc->mode); | ||
1631 | |||
1632 | intel_wait_for_vblank(dev, pipe); | ||
1633 | 1602 | ||
1634 | if (old_fb) { | 1603 | if (old_fb) { |
1635 | intel_fb = to_intel_framebuffer(old_fb); | 1604 | intel_fb = to_intel_framebuffer(old_fb); |
1636 | obj_priv = to_intel_bo(intel_fb->obj); | 1605 | obj_priv = to_intel_bo(intel_fb->obj); |
1637 | i915_gem_object_unpin(intel_fb->obj); | 1606 | i915_gem_object_unpin(intel_fb->obj); |
1638 | } | 1607 | } |
1639 | intel_increase_pllclock(crtc, true); | ||
1640 | 1608 | ||
1641 | mutex_unlock(&dev->struct_mutex); | 1609 | mutex_unlock(&dev->struct_mutex); |
1642 | 1610 | ||
@@ -1911,9 +1879,6 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1911 | int fdi_tx_reg = (pipe == 0) ? FDI_TXA_CTL : FDI_TXB_CTL; | 1879 | int fdi_tx_reg = (pipe == 0) ? FDI_TXA_CTL : FDI_TXB_CTL; |
1912 | int fdi_rx_reg = (pipe == 0) ? FDI_RXA_CTL : FDI_RXB_CTL; | 1880 | int fdi_rx_reg = (pipe == 0) ? FDI_RXA_CTL : FDI_RXB_CTL; |
1913 | int transconf_reg = (pipe == 0) ? TRANSACONF : TRANSBCONF; | 1881 | int transconf_reg = (pipe == 0) ? TRANSACONF : TRANSBCONF; |
1914 | int pf_ctl_reg = (pipe == 0) ? PFA_CTL_1 : PFB_CTL_1; | ||
1915 | int pf_win_size = (pipe == 0) ? PFA_WIN_SZ : PFB_WIN_SZ; | ||
1916 | int pf_win_pos = (pipe == 0) ? PFA_WIN_POS : PFB_WIN_POS; | ||
1917 | int cpu_htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B; | 1882 | int cpu_htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B; |
1918 | int cpu_hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B; | 1883 | int cpu_hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B; |
1919 | int cpu_hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B; | 1884 | int cpu_hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B; |
@@ -1982,15 +1947,19 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1982 | } | 1947 | } |
1983 | 1948 | ||
1984 | /* Enable panel fitting for LVDS */ | 1949 | /* Enable panel fitting for LVDS */ |
1985 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) | 1950 | if (dev_priv->pch_pf_size && |
1986 | || HAS_eDP || intel_pch_has_edp(crtc)) { | 1951 | (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) |
1987 | if (dev_priv->pch_pf_size) { | 1952 | || HAS_eDP || intel_pch_has_edp(crtc))) { |
1988 | temp = I915_READ(pf_ctl_reg); | 1953 | /* Force use of hard-coded filter coefficients |
1989 | I915_WRITE(pf_ctl_reg, temp | PF_ENABLE | PF_FILTER_MED_3x3); | 1954 | * as some pre-programmed values are broken, |
1990 | I915_WRITE(pf_win_pos, dev_priv->pch_pf_pos); | 1955 | * e.g. x201. |
1991 | I915_WRITE(pf_win_size, dev_priv->pch_pf_size); | 1956 | */ |
1992 | } else | 1957 | I915_WRITE(pipe ? PFB_CTL_1 : PFA_CTL_1, |
1993 | I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE); | 1958 | PF_ENABLE | PF_FILTER_MED_3x3); |
1959 | I915_WRITE(pipe ? PFB_WIN_POS : PFA_WIN_POS, | ||
1960 | dev_priv->pch_pf_pos); | ||
1961 | I915_WRITE(pipe ? PFB_WIN_SZ : PFA_WIN_SZ, | ||
1962 | dev_priv->pch_pf_size); | ||
1994 | } | 1963 | } |
1995 | 1964 | ||
1996 | /* Enable CPU pipe */ | 1965 | /* Enable CPU pipe */ |
@@ -2115,7 +2084,7 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2115 | I915_WRITE(transconf_reg, temp | TRANS_ENABLE); | 2084 | I915_WRITE(transconf_reg, temp | TRANS_ENABLE); |
2116 | I915_READ(transconf_reg); | 2085 | I915_READ(transconf_reg); |
2117 | 2086 | ||
2118 | if (wait_for(I915_READ(transconf_reg) & TRANS_STATE_ENABLE, 10, 0)) | 2087 | if (wait_for(I915_READ(transconf_reg) & TRANS_STATE_ENABLE, 100, 1)) |
2119 | DRM_ERROR("failed to enable transcoder\n"); | 2088 | DRM_ERROR("failed to enable transcoder\n"); |
2120 | } | 2089 | } |
2121 | 2090 | ||
@@ -2155,14 +2124,8 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2155 | udelay(100); | 2124 | udelay(100); |
2156 | 2125 | ||
2157 | /* Disable PF */ | 2126 | /* Disable PF */ |
2158 | temp = I915_READ(pf_ctl_reg); | 2127 | I915_WRITE(pipe ? PFB_CTL_1 : PFA_CTL_1, 0); |
2159 | if ((temp & PF_ENABLE) != 0) { | 2128 | I915_WRITE(pipe ? PFB_WIN_SZ : PFA_WIN_SZ, 0); |
2160 | I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE); | ||
2161 | I915_READ(pf_ctl_reg); | ||
2162 | } | ||
2163 | I915_WRITE(pf_win_size, 0); | ||
2164 | POSTING_READ(pf_win_size); | ||
2165 | |||
2166 | 2129 | ||
2167 | /* disable CPU FDI tx and PCH FDI rx */ | 2130 | /* disable CPU FDI tx and PCH FDI rx */ |
2168 | temp = I915_READ(fdi_tx_reg); | 2131 | temp = I915_READ(fdi_tx_reg); |
@@ -2379,13 +2342,13 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2379 | I915_READ(dspbase_reg); | 2342 | I915_READ(dspbase_reg); |
2380 | } | 2343 | } |
2381 | 2344 | ||
2382 | /* Wait for vblank for the disable to take effect */ | ||
2383 | intel_wait_for_vblank_off(dev, pipe); | ||
2384 | |||
2385 | /* Don't disable pipe A or pipe A PLLs if needed */ | 2345 | /* Don't disable pipe A or pipe A PLLs if needed */ |
2386 | if (pipeconf_reg == PIPEACONF && | 2346 | if (pipeconf_reg == PIPEACONF && |
2387 | (dev_priv->quirks & QUIRK_PIPEA_FORCE)) | 2347 | (dev_priv->quirks & QUIRK_PIPEA_FORCE)) { |
2348 | /* Wait for vblank for the disable to take effect */ | ||
2349 | intel_wait_for_vblank(dev, pipe); | ||
2388 | goto skip_pipe_off; | 2350 | goto skip_pipe_off; |
2351 | } | ||
2389 | 2352 | ||
2390 | /* Next, disable display pipes */ | 2353 | /* Next, disable display pipes */ |
2391 | temp = I915_READ(pipeconf_reg); | 2354 | temp = I915_READ(pipeconf_reg); |
@@ -2394,8 +2357,8 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2394 | I915_READ(pipeconf_reg); | 2357 | I915_READ(pipeconf_reg); |
2395 | } | 2358 | } |
2396 | 2359 | ||
2397 | /* Wait for vblank for the disable to take effect. */ | 2360 | /* Wait for the pipe to turn off */ |
2398 | intel_wait_for_vblank_off(dev, pipe); | 2361 | intel_wait_for_pipe_off(dev, pipe); |
2399 | 2362 | ||
2400 | temp = I915_READ(dpll_reg); | 2363 | temp = I915_READ(dpll_reg); |
2401 | if ((temp & DPLL_VCO_ENABLE) != 0) { | 2364 | if ((temp & DPLL_VCO_ENABLE) != 0) { |
@@ -2421,6 +2384,9 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2421 | int pipe = intel_crtc->pipe; | 2384 | int pipe = intel_crtc->pipe; |
2422 | bool enabled; | 2385 | bool enabled; |
2423 | 2386 | ||
2387 | if (intel_crtc->dpms_mode == mode) | ||
2388 | return; | ||
2389 | |||
2424 | intel_crtc->dpms_mode = mode; | 2390 | intel_crtc->dpms_mode = mode; |
2425 | intel_crtc->cursor_on = mode == DRM_MODE_DPMS_ON; | 2391 | intel_crtc->cursor_on = mode == DRM_MODE_DPMS_ON; |
2426 | 2392 | ||
@@ -2511,11 +2477,19 @@ static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, | |||
2511 | struct drm_display_mode *adjusted_mode) | 2477 | struct drm_display_mode *adjusted_mode) |
2512 | { | 2478 | { |
2513 | struct drm_device *dev = crtc->dev; | 2479 | struct drm_device *dev = crtc->dev; |
2480 | |||
2514 | if (HAS_PCH_SPLIT(dev)) { | 2481 | if (HAS_PCH_SPLIT(dev)) { |
2515 | /* FDI link clock is fixed at 2.7G */ | 2482 | /* FDI link clock is fixed at 2.7G */ |
2516 | if (mode->clock * 3 > IRONLAKE_FDI_FREQ * 4) | 2483 | if (mode->clock * 3 > IRONLAKE_FDI_FREQ * 4) |
2517 | return false; | 2484 | return false; |
2518 | } | 2485 | } |
2486 | |||
2487 | /* XXX some encoders set the crtcinfo, others don't. | ||
2488 | * Obviously we need some form of conflict resolution here... | ||
2489 | */ | ||
2490 | if (adjusted_mode->crtc_htotal == 0) | ||
2491 | drm_mode_set_crtcinfo(adjusted_mode, 0); | ||
2492 | |||
2519 | return true; | 2493 | return true; |
2520 | } | 2494 | } |
2521 | 2495 | ||
@@ -2815,14 +2789,8 @@ static unsigned long intel_calculate_wm(unsigned long clock_in_khz, | |||
2815 | /* Don't promote wm_size to unsigned... */ | 2789 | /* Don't promote wm_size to unsigned... */ |
2816 | if (wm_size > (long)wm->max_wm) | 2790 | if (wm_size > (long)wm->max_wm) |
2817 | wm_size = wm->max_wm; | 2791 | wm_size = wm->max_wm; |
2818 | if (wm_size <= 0) { | 2792 | if (wm_size <= 0) |
2819 | wm_size = wm->default_wm; | 2793 | wm_size = wm->default_wm; |
2820 | DRM_ERROR("Insufficient FIFO for plane, expect flickering:" | ||
2821 | " entries required = %ld, available = %lu.\n", | ||
2822 | entries_required + wm->guard_size, | ||
2823 | wm->fifo_size); | ||
2824 | } | ||
2825 | |||
2826 | return wm_size; | 2794 | return wm_size; |
2827 | } | 2795 | } |
2828 | 2796 | ||
@@ -3436,8 +3404,7 @@ static void ironlake_update_wm(struct drm_device *dev, int planea_clock, | |||
3436 | reg_value = I915_READ(WM1_LP_ILK); | 3404 | reg_value = I915_READ(WM1_LP_ILK); |
3437 | reg_value &= ~(WM1_LP_LATENCY_MASK | WM1_LP_SR_MASK | | 3405 | reg_value &= ~(WM1_LP_LATENCY_MASK | WM1_LP_SR_MASK | |
3438 | WM1_LP_CURSOR_MASK); | 3406 | WM1_LP_CURSOR_MASK); |
3439 | reg_value |= WM1_LP_SR_EN | | 3407 | reg_value |= (ilk_sr_latency << WM1_LP_LATENCY_SHIFT) | |
3440 | (ilk_sr_latency << WM1_LP_LATENCY_SHIFT) | | ||
3441 | (sr_wm << WM1_LP_SR_SHIFT) | cursor_wm; | 3408 | (sr_wm << WM1_LP_SR_SHIFT) | cursor_wm; |
3442 | 3409 | ||
3443 | I915_WRITE(WM1_LP_ILK, reg_value); | 3410 | I915_WRITE(WM1_LP_ILK, reg_value); |
@@ -3554,10 +3521,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3554 | u32 dpll = 0, fp = 0, fp2 = 0, dspcntr, pipeconf; | 3521 | u32 dpll = 0, fp = 0, fp2 = 0, dspcntr, pipeconf; |
3555 | bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false; | 3522 | bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false; |
3556 | bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; | 3523 | bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; |
3557 | bool is_edp = false; | 3524 | struct intel_encoder *has_edp_encoder = NULL; |
3558 | struct drm_mode_config *mode_config = &dev->mode_config; | 3525 | struct drm_mode_config *mode_config = &dev->mode_config; |
3559 | struct drm_encoder *encoder; | 3526 | struct drm_encoder *encoder; |
3560 | struct intel_encoder *intel_encoder = NULL; | ||
3561 | const intel_limit_t *limit; | 3527 | const intel_limit_t *limit; |
3562 | int ret; | 3528 | int ret; |
3563 | struct fdi_m_n m_n = {0}; | 3529 | struct fdi_m_n m_n = {0}; |
@@ -3578,12 +3544,12 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3578 | drm_vblank_pre_modeset(dev, pipe); | 3544 | drm_vblank_pre_modeset(dev, pipe); |
3579 | 3545 | ||
3580 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { | 3546 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { |
3547 | struct intel_encoder *intel_encoder; | ||
3581 | 3548 | ||
3582 | if (!encoder || encoder->crtc != crtc) | 3549 | if (encoder->crtc != crtc) |
3583 | continue; | 3550 | continue; |
3584 | 3551 | ||
3585 | intel_encoder = enc_to_intel_encoder(encoder); | 3552 | intel_encoder = enc_to_intel_encoder(encoder); |
3586 | |||
3587 | switch (intel_encoder->type) { | 3553 | switch (intel_encoder->type) { |
3588 | case INTEL_OUTPUT_LVDS: | 3554 | case INTEL_OUTPUT_LVDS: |
3589 | is_lvds = true; | 3555 | is_lvds = true; |
@@ -3607,7 +3573,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3607 | is_dp = true; | 3573 | is_dp = true; |
3608 | break; | 3574 | break; |
3609 | case INTEL_OUTPUT_EDP: | 3575 | case INTEL_OUTPUT_EDP: |
3610 | is_edp = true; | 3576 | has_edp_encoder = intel_encoder; |
3611 | break; | 3577 | break; |
3612 | } | 3578 | } |
3613 | 3579 | ||
@@ -3685,10 +3651,10 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3685 | int lane = 0, link_bw, bpp; | 3651 | int lane = 0, link_bw, bpp; |
3686 | /* eDP doesn't require FDI link, so just set DP M/N | 3652 | /* eDP doesn't require FDI link, so just set DP M/N |
3687 | according to current link config */ | 3653 | according to current link config */ |
3688 | if (is_edp) { | 3654 | if (has_edp_encoder) { |
3689 | target_clock = mode->clock; | 3655 | target_clock = mode->clock; |
3690 | intel_edp_link_config(intel_encoder, | 3656 | intel_edp_link_config(has_edp_encoder, |
3691 | &lane, &link_bw); | 3657 | &lane, &link_bw); |
3692 | } else { | 3658 | } else { |
3693 | /* DP over FDI requires target mode clock | 3659 | /* DP over FDI requires target mode clock |
3694 | instead of link clock */ | 3660 | instead of link clock */ |
@@ -3709,7 +3675,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3709 | temp |= PIPE_8BPC; | 3675 | temp |= PIPE_8BPC; |
3710 | else | 3676 | else |
3711 | temp |= PIPE_6BPC; | 3677 | temp |= PIPE_6BPC; |
3712 | } else if (is_edp || (is_dp && intel_pch_has_edp(crtc))) { | 3678 | } else if (has_edp_encoder || (is_dp && intel_pch_has_edp(crtc))) { |
3713 | switch (dev_priv->edp_bpp/3) { | 3679 | switch (dev_priv->edp_bpp/3) { |
3714 | case 8: | 3680 | case 8: |
3715 | temp |= PIPE_8BPC; | 3681 | temp |= PIPE_8BPC; |
@@ -3782,7 +3748,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3782 | 3748 | ||
3783 | udelay(200); | 3749 | udelay(200); |
3784 | 3750 | ||
3785 | if (is_edp) { | 3751 | if (has_edp_encoder) { |
3786 | if (dev_priv->lvds_use_ssc) { | 3752 | if (dev_priv->lvds_use_ssc) { |
3787 | temp |= DREF_SSC1_ENABLE; | 3753 | temp |= DREF_SSC1_ENABLE; |
3788 | I915_WRITE(PCH_DREF_CONTROL, temp); | 3754 | I915_WRITE(PCH_DREF_CONTROL, temp); |
@@ -3931,7 +3897,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3931 | dpll_reg = pch_dpll_reg; | 3897 | dpll_reg = pch_dpll_reg; |
3932 | } | 3898 | } |
3933 | 3899 | ||
3934 | if (!is_edp) { | 3900 | if (!has_edp_encoder) { |
3935 | I915_WRITE(fp_reg, fp); | 3901 | I915_WRITE(fp_reg, fp); |
3936 | I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE); | 3902 | I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE); |
3937 | I915_READ(dpll_reg); | 3903 | I915_READ(dpll_reg); |
@@ -4026,7 +3992,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
4026 | } | 3992 | } |
4027 | } | 3993 | } |
4028 | 3994 | ||
4029 | if (!is_edp) { | 3995 | if (!has_edp_encoder) { |
4030 | I915_WRITE(fp_reg, fp); | 3996 | I915_WRITE(fp_reg, fp); |
4031 | I915_WRITE(dpll_reg, dpll); | 3997 | I915_WRITE(dpll_reg, dpll); |
4032 | I915_READ(dpll_reg); | 3998 | I915_READ(dpll_reg); |
@@ -4105,7 +4071,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
4105 | I915_WRITE(link_m1_reg, m_n.link_m); | 4071 | I915_WRITE(link_m1_reg, m_n.link_m); |
4106 | I915_WRITE(link_n1_reg, m_n.link_n); | 4072 | I915_WRITE(link_n1_reg, m_n.link_n); |
4107 | 4073 | ||
4108 | if (is_edp) { | 4074 | if (has_edp_encoder) { |
4109 | ironlake_set_pll_edp(crtc, adjusted_mode->clock); | 4075 | ironlake_set_pll_edp(crtc, adjusted_mode->clock); |
4110 | } else { | 4076 | } else { |
4111 | /* enable FDI RX PLL too */ | 4077 | /* enable FDI RX PLL too */ |
@@ -4911,15 +4877,6 @@ static void intel_crtc_destroy(struct drm_crtc *crtc) | |||
4911 | kfree(intel_crtc); | 4877 | kfree(intel_crtc); |
4912 | } | 4878 | } |
4913 | 4879 | ||
4914 | struct intel_unpin_work { | ||
4915 | struct work_struct work; | ||
4916 | struct drm_device *dev; | ||
4917 | struct drm_gem_object *old_fb_obj; | ||
4918 | struct drm_gem_object *pending_flip_obj; | ||
4919 | struct drm_pending_vblank_event *event; | ||
4920 | int pending; | ||
4921 | }; | ||
4922 | |||
4923 | static void intel_unpin_work_fn(struct work_struct *__work) | 4880 | static void intel_unpin_work_fn(struct work_struct *__work) |
4924 | { | 4881 | { |
4925 | struct intel_unpin_work *work = | 4882 | struct intel_unpin_work *work = |
@@ -5007,7 +4964,8 @@ void intel_prepare_page_flip(struct drm_device *dev, int plane) | |||
5007 | 4964 | ||
5008 | spin_lock_irqsave(&dev->event_lock, flags); | 4965 | spin_lock_irqsave(&dev->event_lock, flags); |
5009 | if (intel_crtc->unpin_work) { | 4966 | if (intel_crtc->unpin_work) { |
5010 | intel_crtc->unpin_work->pending = 1; | 4967 | if ((++intel_crtc->unpin_work->pending) > 1) |
4968 | DRM_ERROR("Prepared flip multiple times\n"); | ||
5011 | } else { | 4969 | } else { |
5012 | DRM_DEBUG_DRIVER("preparing flip with no unpin work?\n"); | 4970 | DRM_DEBUG_DRIVER("preparing flip with no unpin work?\n"); |
5013 | } | 4971 | } |
@@ -5026,9 +4984,9 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
5026 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 4984 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
5027 | struct intel_unpin_work *work; | 4985 | struct intel_unpin_work *work; |
5028 | unsigned long flags, offset; | 4986 | unsigned long flags, offset; |
5029 | int pipesrc_reg = (intel_crtc->pipe == 0) ? PIPEASRC : PIPEBSRC; | 4987 | int pipe = intel_crtc->pipe; |
5030 | int ret, pipesrc; | 4988 | u32 pf, pipesrc; |
5031 | u32 flip_mask; | 4989 | int ret; |
5032 | 4990 | ||
5033 | work = kzalloc(sizeof *work, GFP_KERNEL); | 4991 | work = kzalloc(sizeof *work, GFP_KERNEL); |
5034 | if (work == NULL) | 4992 | if (work == NULL) |
@@ -5077,42 +5035,73 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
5077 | atomic_inc(&obj_priv->pending_flip); | 5035 | atomic_inc(&obj_priv->pending_flip); |
5078 | work->pending_flip_obj = obj; | 5036 | work->pending_flip_obj = obj; |
5079 | 5037 | ||
5080 | if (intel_crtc->plane) | ||
5081 | flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; | ||
5082 | else | ||
5083 | flip_mask = MI_WAIT_FOR_PLANE_A_FLIP; | ||
5084 | |||
5085 | if (IS_GEN3(dev) || IS_GEN2(dev)) { | 5038 | if (IS_GEN3(dev) || IS_GEN2(dev)) { |
5039 | u32 flip_mask; | ||
5040 | |||
5041 | if (intel_crtc->plane) | ||
5042 | flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; | ||
5043 | else | ||
5044 | flip_mask = MI_WAIT_FOR_PLANE_A_FLIP; | ||
5045 | |||
5086 | BEGIN_LP_RING(2); | 5046 | BEGIN_LP_RING(2); |
5087 | OUT_RING(MI_WAIT_FOR_EVENT | flip_mask); | 5047 | OUT_RING(MI_WAIT_FOR_EVENT | flip_mask); |
5088 | OUT_RING(0); | 5048 | OUT_RING(0); |
5089 | ADVANCE_LP_RING(); | 5049 | ADVANCE_LP_RING(); |
5090 | } | 5050 | } |
5091 | 5051 | ||
5052 | work->enable_stall_check = true; | ||
5053 | |||
5092 | /* Offset into the new buffer for cases of shared fbs between CRTCs */ | 5054 | /* Offset into the new buffer for cases of shared fbs between CRTCs */ |
5093 | offset = obj_priv->gtt_offset; | 5055 | offset = crtc->y * fb->pitch + crtc->x * fb->bits_per_pixel/8; |
5094 | offset += (crtc->y * fb->pitch) + (crtc->x * (fb->bits_per_pixel) / 8); | ||
5095 | 5056 | ||
5096 | BEGIN_LP_RING(4); | 5057 | BEGIN_LP_RING(4); |
5097 | if (IS_I965G(dev)) { | 5058 | switch(INTEL_INFO(dev)->gen) { |
5059 | case 2: | ||
5098 | OUT_RING(MI_DISPLAY_FLIP | | 5060 | OUT_RING(MI_DISPLAY_FLIP | |
5099 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | 5061 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); |
5100 | OUT_RING(fb->pitch); | 5062 | OUT_RING(fb->pitch); |
5101 | OUT_RING(offset | obj_priv->tiling_mode); | 5063 | OUT_RING(obj_priv->gtt_offset + offset); |
5102 | pipesrc = I915_READ(pipesrc_reg); | 5064 | OUT_RING(MI_NOOP); |
5103 | OUT_RING(pipesrc & 0x0fff0fff); | 5065 | break; |
5104 | } else if (IS_GEN3(dev)) { | 5066 | |
5067 | case 3: | ||
5105 | OUT_RING(MI_DISPLAY_FLIP_I915 | | 5068 | OUT_RING(MI_DISPLAY_FLIP_I915 | |
5106 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | 5069 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); |
5107 | OUT_RING(fb->pitch); | 5070 | OUT_RING(fb->pitch); |
5108 | OUT_RING(offset); | 5071 | OUT_RING(obj_priv->gtt_offset + offset); |
5109 | OUT_RING(MI_NOOP); | 5072 | OUT_RING(MI_NOOP); |
5110 | } else { | 5073 | break; |
5074 | |||
5075 | case 4: | ||
5076 | case 5: | ||
5077 | /* i965+ uses the linear or tiled offsets from the | ||
5078 | * Display Registers (which do not change across a page-flip) | ||
5079 | * so we need only reprogram the base address. | ||
5080 | */ | ||
5111 | OUT_RING(MI_DISPLAY_FLIP | | 5081 | OUT_RING(MI_DISPLAY_FLIP | |
5112 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | 5082 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); |
5113 | OUT_RING(fb->pitch); | 5083 | OUT_RING(fb->pitch); |
5114 | OUT_RING(offset); | 5084 | OUT_RING(obj_priv->gtt_offset | obj_priv->tiling_mode); |
5115 | OUT_RING(MI_NOOP); | 5085 | |
5086 | /* XXX Enabling the panel-fitter across page-flip is so far | ||
5087 | * untested on non-native modes, so ignore it for now. | ||
5088 | * pf = I915_READ(pipe == 0 ? PFA_CTL_1 : PFB_CTL_1) & PF_ENABLE; | ||
5089 | */ | ||
5090 | pf = 0; | ||
5091 | pipesrc = I915_READ(pipe == 0 ? PIPEASRC : PIPEBSRC) & 0x0fff0fff; | ||
5092 | OUT_RING(pf | pipesrc); | ||
5093 | break; | ||
5094 | |||
5095 | case 6: | ||
5096 | OUT_RING(MI_DISPLAY_FLIP | | ||
5097 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | ||
5098 | OUT_RING(fb->pitch | obj_priv->tiling_mode); | ||
5099 | OUT_RING(obj_priv->gtt_offset); | ||
5100 | |||
5101 | pf = I915_READ(pipe == 0 ? PFA_CTL_1 : PFB_CTL_1) & PF_ENABLE; | ||
5102 | pipesrc = I915_READ(pipe == 0 ? PIPEASRC : PIPEBSRC) & 0x0fff0fff; | ||
5103 | OUT_RING(pf | pipesrc); | ||
5104 | break; | ||
5116 | } | 5105 | } |
5117 | ADVANCE_LP_RING(); | 5106 | ADVANCE_LP_RING(); |
5118 | 5107 | ||
@@ -5193,7 +5182,7 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) | |||
5193 | dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base; | 5182 | dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base; |
5194 | 5183 | ||
5195 | intel_crtc->cursor_addr = 0; | 5184 | intel_crtc->cursor_addr = 0; |
5196 | intel_crtc->dpms_mode = DRM_MODE_DPMS_OFF; | 5185 | intel_crtc->dpms_mode = -1; |
5197 | drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs); | 5186 | drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs); |
5198 | 5187 | ||
5199 | intel_crtc->busy = false; | 5188 | intel_crtc->busy = false; |
@@ -5701,6 +5690,9 @@ void intel_init_clock_gating(struct drm_device *dev) | |||
5701 | I915_WRITE(DISP_ARB_CTL, | 5690 | I915_WRITE(DISP_ARB_CTL, |
5702 | (I915_READ(DISP_ARB_CTL) | | 5691 | (I915_READ(DISP_ARB_CTL) | |
5703 | DISP_FBC_WM_DIS)); | 5692 | DISP_FBC_WM_DIS)); |
5693 | I915_WRITE(WM3_LP_ILK, 0); | ||
5694 | I915_WRITE(WM2_LP_ILK, 0); | ||
5695 | I915_WRITE(WM1_LP_ILK, 0); | ||
5704 | } | 5696 | } |
5705 | /* | 5697 | /* |
5706 | * Based on the document from hardware guys the following bits | 5698 | * Based on the document from hardware guys the following bits |
@@ -5722,8 +5714,7 @@ void intel_init_clock_gating(struct drm_device *dev) | |||
5722 | ILK_DPFC_DIS2 | | 5714 | ILK_DPFC_DIS2 | |
5723 | ILK_CLK_FBC); | 5715 | ILK_CLK_FBC); |
5724 | } | 5716 | } |
5725 | if (IS_GEN6(dev)) | 5717 | return; |
5726 | return; | ||
5727 | } else if (IS_G4X(dev)) { | 5718 | } else if (IS_G4X(dev)) { |
5728 | uint32_t dspclk_gate; | 5719 | uint32_t dspclk_gate; |
5729 | I915_WRITE(RENCLK_GATE_D1, 0); | 5720 | I915_WRITE(RENCLK_GATE_D1, 0); |
@@ -5784,11 +5775,9 @@ void intel_init_clock_gating(struct drm_device *dev) | |||
5784 | OUT_RING(MI_FLUSH); | 5775 | OUT_RING(MI_FLUSH); |
5785 | ADVANCE_LP_RING(); | 5776 | ADVANCE_LP_RING(); |
5786 | } | 5777 | } |
5787 | } else { | 5778 | } else |
5788 | DRM_DEBUG_KMS("Failed to allocate render context." | 5779 | DRM_DEBUG_KMS("Failed to allocate render context." |
5789 | "Disable RC6\n"); | 5780 | "Disable RC6\n"); |
5790 | return; | ||
5791 | } | ||
5792 | } | 5781 | } |
5793 | 5782 | ||
5794 | if (I915_HAS_RC6(dev) && drm_core_check_feature(dev, DRIVER_MODESET)) { | 5783 | if (I915_HAS_RC6(dev) && drm_core_check_feature(dev, DRIVER_MODESET)) { |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 9caccd03dcc..9ab8708ac6b 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -239,7 +239,6 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, | |||
239 | uint32_t ch_data = ch_ctl + 4; | 239 | uint32_t ch_data = ch_ctl + 4; |
240 | int i; | 240 | int i; |
241 | int recv_bytes; | 241 | int recv_bytes; |
242 | uint32_t ctl; | ||
243 | uint32_t status; | 242 | uint32_t status; |
244 | uint32_t aux_clock_divider; | 243 | uint32_t aux_clock_divider; |
245 | int try, precharge; | 244 | int try, precharge; |
@@ -263,41 +262,43 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, | |||
263 | else | 262 | else |
264 | precharge = 5; | 263 | precharge = 5; |
265 | 264 | ||
265 | if (I915_READ(ch_ctl) & DP_AUX_CH_CTL_SEND_BUSY) { | ||
266 | DRM_ERROR("dp_aux_ch not started status 0x%08x\n", | ||
267 | I915_READ(ch_ctl)); | ||
268 | return -EBUSY; | ||
269 | } | ||
270 | |||
266 | /* Must try at least 3 times according to DP spec */ | 271 | /* Must try at least 3 times according to DP spec */ |
267 | for (try = 0; try < 5; try++) { | 272 | for (try = 0; try < 5; try++) { |
268 | /* Load the send data into the aux channel data registers */ | 273 | /* Load the send data into the aux channel data registers */ |
269 | for (i = 0; i < send_bytes; i += 4) { | 274 | for (i = 0; i < send_bytes; i += 4) |
270 | uint32_t d = pack_aux(send + i, send_bytes - i); | 275 | I915_WRITE(ch_data + i, |
271 | 276 | pack_aux(send + i, send_bytes - i)); | |
272 | I915_WRITE(ch_data + i, d); | ||
273 | } | ||
274 | |||
275 | ctl = (DP_AUX_CH_CTL_SEND_BUSY | | ||
276 | DP_AUX_CH_CTL_TIME_OUT_400us | | ||
277 | (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | | ||
278 | (precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) | | ||
279 | (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT) | | ||
280 | DP_AUX_CH_CTL_DONE | | ||
281 | DP_AUX_CH_CTL_TIME_OUT_ERROR | | ||
282 | DP_AUX_CH_CTL_RECEIVE_ERROR); | ||
283 | 277 | ||
284 | /* Send the command and wait for it to complete */ | 278 | /* Send the command and wait for it to complete */ |
285 | I915_WRITE(ch_ctl, ctl); | 279 | I915_WRITE(ch_ctl, |
286 | (void) I915_READ(ch_ctl); | 280 | DP_AUX_CH_CTL_SEND_BUSY | |
281 | DP_AUX_CH_CTL_TIME_OUT_400us | | ||
282 | (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | | ||
283 | (precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) | | ||
284 | (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT) | | ||
285 | DP_AUX_CH_CTL_DONE | | ||
286 | DP_AUX_CH_CTL_TIME_OUT_ERROR | | ||
287 | DP_AUX_CH_CTL_RECEIVE_ERROR); | ||
287 | for (;;) { | 288 | for (;;) { |
288 | udelay(100); | ||
289 | status = I915_READ(ch_ctl); | 289 | status = I915_READ(ch_ctl); |
290 | if ((status & DP_AUX_CH_CTL_SEND_BUSY) == 0) | 290 | if ((status & DP_AUX_CH_CTL_SEND_BUSY) == 0) |
291 | break; | 291 | break; |
292 | udelay(100); | ||
292 | } | 293 | } |
293 | 294 | ||
294 | /* Clear done status and any errors */ | 295 | /* Clear done status and any errors */ |
295 | I915_WRITE(ch_ctl, (status | | 296 | I915_WRITE(ch_ctl, |
296 | DP_AUX_CH_CTL_DONE | | 297 | status | |
297 | DP_AUX_CH_CTL_TIME_OUT_ERROR | | 298 | DP_AUX_CH_CTL_DONE | |
298 | DP_AUX_CH_CTL_RECEIVE_ERROR)); | 299 | DP_AUX_CH_CTL_TIME_OUT_ERROR | |
299 | (void) I915_READ(ch_ctl); | 300 | DP_AUX_CH_CTL_RECEIVE_ERROR); |
300 | if ((status & DP_AUX_CH_CTL_TIME_OUT_ERROR) == 0) | 301 | if (status & DP_AUX_CH_CTL_DONE) |
301 | break; | 302 | break; |
302 | } | 303 | } |
303 | 304 | ||
@@ -324,15 +325,12 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, | |||
324 | /* Unload any bytes sent back from the other side */ | 325 | /* Unload any bytes sent back from the other side */ |
325 | recv_bytes = ((status & DP_AUX_CH_CTL_MESSAGE_SIZE_MASK) >> | 326 | recv_bytes = ((status & DP_AUX_CH_CTL_MESSAGE_SIZE_MASK) >> |
326 | DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT); | 327 | DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT); |
327 | |||
328 | if (recv_bytes > recv_size) | 328 | if (recv_bytes > recv_size) |
329 | recv_bytes = recv_size; | 329 | recv_bytes = recv_size; |
330 | 330 | ||
331 | for (i = 0; i < recv_bytes; i += 4) { | 331 | for (i = 0; i < recv_bytes; i += 4) |
332 | uint32_t d = I915_READ(ch_data + i); | 332 | unpack_aux(I915_READ(ch_data + i), |
333 | 333 | recv + i, recv_bytes - i); | |
334 | unpack_aux(d, recv + i, recv_bytes - i); | ||
335 | } | ||
336 | 334 | ||
337 | return recv_bytes; | 335 | return recv_bytes; |
338 | } | 336 | } |
@@ -1140,18 +1138,14 @@ static bool | |||
1140 | intel_dp_set_link_train(struct intel_dp *intel_dp, | 1138 | intel_dp_set_link_train(struct intel_dp *intel_dp, |
1141 | uint32_t dp_reg_value, | 1139 | uint32_t dp_reg_value, |
1142 | uint8_t dp_train_pat, | 1140 | uint8_t dp_train_pat, |
1143 | uint8_t train_set[4], | 1141 | uint8_t train_set[4]) |
1144 | bool first) | ||
1145 | { | 1142 | { |
1146 | struct drm_device *dev = intel_dp->base.enc.dev; | 1143 | struct drm_device *dev = intel_dp->base.enc.dev; |
1147 | struct drm_i915_private *dev_priv = dev->dev_private; | 1144 | struct drm_i915_private *dev_priv = dev->dev_private; |
1148 | struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.enc.crtc); | ||
1149 | int ret; | 1145 | int ret; |
1150 | 1146 | ||
1151 | I915_WRITE(intel_dp->output_reg, dp_reg_value); | 1147 | I915_WRITE(intel_dp->output_reg, dp_reg_value); |
1152 | POSTING_READ(intel_dp->output_reg); | 1148 | POSTING_READ(intel_dp->output_reg); |
1153 | if (first) | ||
1154 | intel_wait_for_vblank(dev, intel_crtc->pipe); | ||
1155 | 1149 | ||
1156 | intel_dp_aux_native_write_1(intel_dp, | 1150 | intel_dp_aux_native_write_1(intel_dp, |
1157 | DP_TRAINING_PATTERN_SET, | 1151 | DP_TRAINING_PATTERN_SET, |
@@ -1176,10 +1170,15 @@ intel_dp_link_train(struct intel_dp *intel_dp) | |||
1176 | uint8_t voltage; | 1170 | uint8_t voltage; |
1177 | bool clock_recovery = false; | 1171 | bool clock_recovery = false; |
1178 | bool channel_eq = false; | 1172 | bool channel_eq = false; |
1179 | bool first = true; | ||
1180 | int tries; | 1173 | int tries; |
1181 | u32 reg; | 1174 | u32 reg; |
1182 | uint32_t DP = intel_dp->DP; | 1175 | uint32_t DP = intel_dp->DP; |
1176 | struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.enc.crtc); | ||
1177 | |||
1178 | /* Enable output, wait for it to become active */ | ||
1179 | I915_WRITE(intel_dp->output_reg, intel_dp->DP); | ||
1180 | POSTING_READ(intel_dp->output_reg); | ||
1181 | intel_wait_for_vblank(dev, intel_crtc->pipe); | ||
1183 | 1182 | ||
1184 | /* Write the link configuration data */ | 1183 | /* Write the link configuration data */ |
1185 | intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET, | 1184 | intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET, |
@@ -1212,9 +1211,8 @@ intel_dp_link_train(struct intel_dp *intel_dp) | |||
1212 | reg = DP | DP_LINK_TRAIN_PAT_1; | 1211 | reg = DP | DP_LINK_TRAIN_PAT_1; |
1213 | 1212 | ||
1214 | if (!intel_dp_set_link_train(intel_dp, reg, | 1213 | if (!intel_dp_set_link_train(intel_dp, reg, |
1215 | DP_TRAINING_PATTERN_1, train_set, first)) | 1214 | DP_TRAINING_PATTERN_1, train_set)) |
1216 | break; | 1215 | break; |
1217 | first = false; | ||
1218 | /* Set training pattern 1 */ | 1216 | /* Set training pattern 1 */ |
1219 | 1217 | ||
1220 | udelay(100); | 1218 | udelay(100); |
@@ -1268,8 +1266,7 @@ intel_dp_link_train(struct intel_dp *intel_dp) | |||
1268 | 1266 | ||
1269 | /* channel eq pattern */ | 1267 | /* channel eq pattern */ |
1270 | if (!intel_dp_set_link_train(intel_dp, reg, | 1268 | if (!intel_dp_set_link_train(intel_dp, reg, |
1271 | DP_TRAINING_PATTERN_2, train_set, | 1269 | DP_TRAINING_PATTERN_2, train_set)) |
1272 | false)) | ||
1273 | break; | 1270 | break; |
1274 | 1271 | ||
1275 | udelay(400); | 1272 | udelay(400); |
@@ -1388,7 +1385,7 @@ ironlake_dp_detect(struct drm_connector *connector) | |||
1388 | * \return false if DP port is disconnected. | 1385 | * \return false if DP port is disconnected. |
1389 | */ | 1386 | */ |
1390 | static enum drm_connector_status | 1387 | static enum drm_connector_status |
1391 | intel_dp_detect(struct drm_connector *connector) | 1388 | intel_dp_detect(struct drm_connector *connector, bool force) |
1392 | { | 1389 | { |
1393 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1390 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1394 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | 1391 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 0e92aa07b38..8828b3ac641 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -176,6 +176,16 @@ struct intel_crtc { | |||
176 | #define enc_to_intel_encoder(x) container_of(x, struct intel_encoder, enc) | 176 | #define enc_to_intel_encoder(x) container_of(x, struct intel_encoder, enc) |
177 | #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base) | 177 | #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base) |
178 | 178 | ||
179 | struct intel_unpin_work { | ||
180 | struct work_struct work; | ||
181 | struct drm_device *dev; | ||
182 | struct drm_gem_object *old_fb_obj; | ||
183 | struct drm_gem_object *pending_flip_obj; | ||
184 | struct drm_pending_vblank_event *event; | ||
185 | int pending; | ||
186 | bool enable_stall_check; | ||
187 | }; | ||
188 | |||
179 | struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg, | 189 | struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg, |
180 | const char *name); | 190 | const char *name); |
181 | void intel_i2c_destroy(struct i2c_adapter *adapter); | 191 | void intel_i2c_destroy(struct i2c_adapter *adapter); |
@@ -219,7 +229,6 @@ extern struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, | |||
219 | struct drm_crtc *crtc); | 229 | struct drm_crtc *crtc); |
220 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, | 230 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, |
221 | struct drm_file *file_priv); | 231 | struct drm_file *file_priv); |
222 | extern void intel_wait_for_vblank_off(struct drm_device *dev, int pipe); | ||
223 | extern void intel_wait_for_vblank(struct drm_device *dev, int pipe); | 232 | extern void intel_wait_for_vblank(struct drm_device *dev, int pipe); |
224 | extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe); | 233 | extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe); |
225 | extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, | 234 | extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, |
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index a399f4b2c1c..7c9ec1472d4 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c | |||
@@ -221,7 +221,8 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder, | |||
221 | * | 221 | * |
222 | * Unimplemented. | 222 | * Unimplemented. |
223 | */ | 223 | */ |
224 | static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector) | 224 | static enum drm_connector_status |
225 | intel_dvo_detect(struct drm_connector *connector, bool force) | ||
225 | { | 226 | { |
226 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 227 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
227 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); | 228 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 7bdc96256bf..b61966c126d 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c | |||
@@ -237,8 +237,10 @@ int intel_fbdev_destroy(struct drm_device *dev, | |||
237 | drm_fb_helper_fini(&ifbdev->helper); | 237 | drm_fb_helper_fini(&ifbdev->helper); |
238 | 238 | ||
239 | drm_framebuffer_cleanup(&ifb->base); | 239 | drm_framebuffer_cleanup(&ifb->base); |
240 | if (ifb->obj) | 240 | if (ifb->obj) { |
241 | drm_gem_object_unreference(ifb->obj); | 241 | drm_gem_object_unreference(ifb->obj); |
242 | ifb->obj = NULL; | ||
243 | } | ||
242 | 244 | ||
243 | return 0; | 245 | return 0; |
244 | } | 246 | } |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index ccd4c97e652..926934a482e 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -139,7 +139,7 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder, | |||
139 | } | 139 | } |
140 | 140 | ||
141 | static enum drm_connector_status | 141 | static enum drm_connector_status |
142 | intel_hdmi_detect(struct drm_connector *connector) | 142 | intel_hdmi_detect(struct drm_connector *connector, bool force) |
143 | { | 143 | { |
144 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 144 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
145 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); | 145 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index b819c108114..6ec39a86ed0 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -445,7 +445,8 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder, | |||
445 | * connected and closed means disconnected. We also send hotplug events as | 445 | * connected and closed means disconnected. We also send hotplug events as |
446 | * needed, using lid status notification from the input layer. | 446 | * needed, using lid status notification from the input layer. |
447 | */ | 447 | */ |
448 | static enum drm_connector_status intel_lvds_detect(struct drm_connector *connector) | 448 | static enum drm_connector_status |
449 | intel_lvds_detect(struct drm_connector *connector, bool force) | ||
449 | { | 450 | { |
450 | struct drm_device *dev = connector->dev; | 451 | struct drm_device *dev = connector->dev; |
451 | enum drm_connector_status status = connector_status_connected; | 452 | enum drm_connector_status status = connector_status_connected; |
@@ -540,7 +541,9 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val, | |||
540 | * the LID nofication event. | 541 | * the LID nofication event. |
541 | */ | 542 | */ |
542 | if (connector) | 543 | if (connector) |
543 | connector->status = connector->funcs->detect(connector); | 544 | connector->status = connector->funcs->detect(connector, |
545 | false); | ||
546 | |||
544 | /* Don't force modeset on machines where it causes a GPU lockup */ | 547 | /* Don't force modeset on machines where it causes a GPU lockup */ |
545 | if (dmi_check_system(intel_no_modeset_on_lid)) | 548 | if (dmi_check_system(intel_no_modeset_on_lid)) |
546 | return NOTIFY_OK; | 549 | return NOTIFY_OK; |
@@ -875,8 +878,6 @@ void intel_lvds_init(struct drm_device *dev) | |||
875 | 878 | ||
876 | intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT); | 879 | intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT); |
877 | intel_encoder->crtc_mask = (1 << 1); | 880 | intel_encoder->crtc_mask = (1 << 1); |
878 | if (IS_I965G(dev)) | ||
879 | intel_encoder->crtc_mask |= (1 << 0); | ||
880 | drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs); | 881 | drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs); |
881 | drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs); | 882 | drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs); |
882 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; | 883 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; |
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 4f00390d7c6..1d306a458be 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c | |||
@@ -25,6 +25,8 @@ | |||
25 | * | 25 | * |
26 | * Derived from Xorg ddx, xf86-video-intel, src/i830_video.c | 26 | * Derived from Xorg ddx, xf86-video-intel, src/i830_video.c |
27 | */ | 27 | */ |
28 | |||
29 | #include <linux/seq_file.h> | ||
28 | #include "drmP.h" | 30 | #include "drmP.h" |
29 | #include "drm.h" | 31 | #include "drm.h" |
30 | #include "i915_drm.h" | 32 | #include "i915_drm.h" |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 51e9c9e718c..cb3508f78bc 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -220,9 +220,13 @@ static int init_render_ring(struct drm_device *dev, | |||
220 | { | 220 | { |
221 | drm_i915_private_t *dev_priv = dev->dev_private; | 221 | drm_i915_private_t *dev_priv = dev->dev_private; |
222 | int ret = init_ring_common(dev, ring); | 222 | int ret = init_ring_common(dev, ring); |
223 | int mode; | ||
224 | |||
223 | if (IS_I9XX(dev) && !IS_GEN3(dev)) { | 225 | if (IS_I9XX(dev) && !IS_GEN3(dev)) { |
224 | I915_WRITE(MI_MODE, | 226 | mode = VS_TIMER_DISPATCH << 16 | VS_TIMER_DISPATCH; |
225 | (VS_TIMER_DISPATCH) << 16 | VS_TIMER_DISPATCH); | 227 | if (IS_GEN6(dev)) |
228 | mode |= MI_FLUSH_ENABLE << 16 | MI_FLUSH_ENABLE; | ||
229 | I915_WRITE(MI_MODE, mode); | ||
226 | } | 230 | } |
227 | return ret; | 231 | return ret; |
228 | } | 232 | } |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 093e914e8a4..ee73e428a84 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -1061,8 +1061,9 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
1061 | if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, mode)) | 1061 | if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, mode)) |
1062 | return false; | 1062 | return false; |
1063 | 1063 | ||
1064 | if (!intel_sdvo_set_input_timings_for_mode(intel_sdvo, mode, adjusted_mode)) | 1064 | (void) intel_sdvo_set_input_timings_for_mode(intel_sdvo, |
1065 | return false; | 1065 | mode, |
1066 | adjusted_mode); | ||
1066 | } else if (intel_sdvo->is_lvds) { | 1067 | } else if (intel_sdvo->is_lvds) { |
1067 | drm_mode_set_crtcinfo(intel_sdvo->sdvo_lvds_fixed_mode, 0); | 1068 | drm_mode_set_crtcinfo(intel_sdvo->sdvo_lvds_fixed_mode, 0); |
1068 | 1069 | ||
@@ -1070,8 +1071,9 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
1070 | intel_sdvo->sdvo_lvds_fixed_mode)) | 1071 | intel_sdvo->sdvo_lvds_fixed_mode)) |
1071 | return false; | 1072 | return false; |
1072 | 1073 | ||
1073 | if (!intel_sdvo_set_input_timings_for_mode(intel_sdvo, mode, adjusted_mode)) | 1074 | (void) intel_sdvo_set_input_timings_for_mode(intel_sdvo, |
1074 | return false; | 1075 | mode, |
1076 | adjusted_mode); | ||
1075 | } | 1077 | } |
1076 | 1078 | ||
1077 | /* Make the CRTC code factor in the SDVO pixel multiplier. The | 1079 | /* Make the CRTC code factor in the SDVO pixel multiplier. The |
@@ -1108,10 +1110,9 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1108 | in_out.in0 = intel_sdvo->attached_output; | 1110 | in_out.in0 = intel_sdvo->attached_output; |
1109 | in_out.in1 = 0; | 1111 | in_out.in1 = 0; |
1110 | 1112 | ||
1111 | if (!intel_sdvo_set_value(intel_sdvo, | 1113 | intel_sdvo_set_value(intel_sdvo, |
1112 | SDVO_CMD_SET_IN_OUT_MAP, | 1114 | SDVO_CMD_SET_IN_OUT_MAP, |
1113 | &in_out, sizeof(in_out))) | 1115 | &in_out, sizeof(in_out)); |
1114 | return; | ||
1115 | 1116 | ||
1116 | if (intel_sdvo->is_hdmi) { | 1117 | if (intel_sdvo->is_hdmi) { |
1117 | if (!intel_sdvo_set_avi_infoframe(intel_sdvo, mode)) | 1118 | if (!intel_sdvo_set_avi_infoframe(intel_sdvo, mode)) |
@@ -1122,11 +1123,9 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1122 | 1123 | ||
1123 | /* We have tried to get input timing in mode_fixup, and filled into | 1124 | /* We have tried to get input timing in mode_fixup, and filled into |
1124 | adjusted_mode */ | 1125 | adjusted_mode */ |
1125 | if (intel_sdvo->is_tv || intel_sdvo->is_lvds) { | 1126 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); |
1126 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); | 1127 | if (intel_sdvo->is_tv || intel_sdvo->is_lvds) |
1127 | input_dtd.part2.sdvo_flags = intel_sdvo->sdvo_flags; | 1128 | input_dtd.part2.sdvo_flags = intel_sdvo->sdvo_flags; |
1128 | } else | ||
1129 | intel_sdvo_get_dtd_from_mode(&input_dtd, mode); | ||
1130 | 1129 | ||
1131 | /* If it's a TV, we already set the output timing in mode_fixup. | 1130 | /* If it's a TV, we already set the output timing in mode_fixup. |
1132 | * Otherwise, the output timing is equal to the input timing. | 1131 | * Otherwise, the output timing is equal to the input timing. |
@@ -1137,8 +1136,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1137 | intel_sdvo->attached_output)) | 1136 | intel_sdvo->attached_output)) |
1138 | return; | 1137 | return; |
1139 | 1138 | ||
1140 | if (!intel_sdvo_set_output_timing(intel_sdvo, &input_dtd)) | 1139 | (void) intel_sdvo_set_output_timing(intel_sdvo, &input_dtd); |
1141 | return; | ||
1142 | } | 1140 | } |
1143 | 1141 | ||
1144 | /* Set the input timing to the screen. Assume always input 0. */ | 1142 | /* Set the input timing to the screen. Assume always input 0. */ |
@@ -1165,8 +1163,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1165 | intel_sdvo_set_input_timing(encoder, &input_dtd); | 1163 | intel_sdvo_set_input_timing(encoder, &input_dtd); |
1166 | } | 1164 | } |
1167 | #else | 1165 | #else |
1168 | if (!intel_sdvo_set_input_timing(intel_sdvo, &input_dtd)) | 1166 | (void) intel_sdvo_set_input_timing(intel_sdvo, &input_dtd); |
1169 | return; | ||
1170 | #endif | 1167 | #endif |
1171 | 1168 | ||
1172 | sdvo_pixel_multiply = intel_sdvo_get_pixel_multiplier(mode); | 1169 | sdvo_pixel_multiply = intel_sdvo_get_pixel_multiplier(mode); |
@@ -1420,7 +1417,7 @@ intel_analog_is_connected(struct drm_device *dev) | |||
1420 | if (!analog_connector) | 1417 | if (!analog_connector) |
1421 | return false; | 1418 | return false; |
1422 | 1419 | ||
1423 | if (analog_connector->funcs->detect(analog_connector) == | 1420 | if (analog_connector->funcs->detect(analog_connector, false) == |
1424 | connector_status_disconnected) | 1421 | connector_status_disconnected) |
1425 | return false; | 1422 | return false; |
1426 | 1423 | ||
@@ -1489,7 +1486,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) | |||
1489 | return status; | 1486 | return status; |
1490 | } | 1487 | } |
1491 | 1488 | ||
1492 | static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector) | 1489 | static enum drm_connector_status |
1490 | intel_sdvo_detect(struct drm_connector *connector, bool force) | ||
1493 | { | 1491 | { |
1494 | uint16_t response; | 1492 | uint16_t response; |
1495 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1493 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
@@ -1932,6 +1930,41 @@ static const struct drm_encoder_funcs intel_sdvo_enc_funcs = { | |||
1932 | .destroy = intel_sdvo_enc_destroy, | 1930 | .destroy = intel_sdvo_enc_destroy, |
1933 | }; | 1931 | }; |
1934 | 1932 | ||
1933 | static void | ||
1934 | intel_sdvo_guess_ddc_bus(struct intel_sdvo *sdvo) | ||
1935 | { | ||
1936 | uint16_t mask = 0; | ||
1937 | unsigned int num_bits; | ||
1938 | |||
1939 | /* Make a mask of outputs less than or equal to our own priority in the | ||
1940 | * list. | ||
1941 | */ | ||
1942 | switch (sdvo->controlled_output) { | ||
1943 | case SDVO_OUTPUT_LVDS1: | ||
1944 | mask |= SDVO_OUTPUT_LVDS1; | ||
1945 | case SDVO_OUTPUT_LVDS0: | ||
1946 | mask |= SDVO_OUTPUT_LVDS0; | ||
1947 | case SDVO_OUTPUT_TMDS1: | ||
1948 | mask |= SDVO_OUTPUT_TMDS1; | ||
1949 | case SDVO_OUTPUT_TMDS0: | ||
1950 | mask |= SDVO_OUTPUT_TMDS0; | ||
1951 | case SDVO_OUTPUT_RGB1: | ||
1952 | mask |= SDVO_OUTPUT_RGB1; | ||
1953 | case SDVO_OUTPUT_RGB0: | ||
1954 | mask |= SDVO_OUTPUT_RGB0; | ||
1955 | break; | ||
1956 | } | ||
1957 | |||
1958 | /* Count bits to find what number we are in the priority list. */ | ||
1959 | mask &= sdvo->caps.output_flags; | ||
1960 | num_bits = hweight16(mask); | ||
1961 | /* If more than 3 outputs, default to DDC bus 3 for now. */ | ||
1962 | if (num_bits > 3) | ||
1963 | num_bits = 3; | ||
1964 | |||
1965 | /* Corresponds to SDVO_CONTROL_BUS_DDCx */ | ||
1966 | sdvo->ddc_bus = 1 << num_bits; | ||
1967 | } | ||
1935 | 1968 | ||
1936 | /** | 1969 | /** |
1937 | * Choose the appropriate DDC bus for control bus switch command for this | 1970 | * Choose the appropriate DDC bus for control bus switch command for this |
@@ -1951,7 +1984,10 @@ intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv, | |||
1951 | else | 1984 | else |
1952 | mapping = &(dev_priv->sdvo_mappings[1]); | 1985 | mapping = &(dev_priv->sdvo_mappings[1]); |
1953 | 1986 | ||
1954 | sdvo->ddc_bus = 1 << ((mapping->ddc_pin & 0xf0) >> 4); | 1987 | if (mapping->initialized) |
1988 | sdvo->ddc_bus = 1 << ((mapping->ddc_pin & 0xf0) >> 4); | ||
1989 | else | ||
1990 | intel_sdvo_guess_ddc_bus(sdvo); | ||
1955 | } | 1991 | } |
1956 | 1992 | ||
1957 | static bool | 1993 | static bool |
@@ -2134,8 +2170,7 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type) | |||
2134 | return true; | 2170 | return true; |
2135 | 2171 | ||
2136 | err: | 2172 | err: |
2137 | intel_sdvo_destroy_enhance_property(connector); | 2173 | intel_sdvo_destroy(connector); |
2138 | kfree(intel_sdvo_connector); | ||
2139 | return false; | 2174 | return false; |
2140 | } | 2175 | } |
2141 | 2176 | ||
@@ -2207,8 +2242,7 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device) | |||
2207 | return true; | 2242 | return true; |
2208 | 2243 | ||
2209 | err: | 2244 | err: |
2210 | intel_sdvo_destroy_enhance_property(connector); | 2245 | intel_sdvo_destroy(connector); |
2211 | kfree(intel_sdvo_connector); | ||
2212 | return false; | 2246 | return false; |
2213 | } | 2247 | } |
2214 | 2248 | ||
@@ -2486,11 +2520,10 @@ static bool intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo, | |||
2486 | uint16_t response; | 2520 | uint16_t response; |
2487 | } enhancements; | 2521 | } enhancements; |
2488 | 2522 | ||
2489 | if (!intel_sdvo_get_value(intel_sdvo, | 2523 | enhancements.response = 0; |
2490 | SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS, | 2524 | intel_sdvo_get_value(intel_sdvo, |
2491 | &enhancements, sizeof(enhancements))) | 2525 | SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS, |
2492 | return false; | 2526 | &enhancements, sizeof(enhancements)); |
2493 | |||
2494 | if (enhancements.response == 0) { | 2527 | if (enhancements.response == 0) { |
2495 | DRM_DEBUG_KMS("No enhancement is supported\n"); | 2528 | DRM_DEBUG_KMS("No enhancement is supported\n"); |
2496 | return true; | 2529 | return true; |
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index d2029efee98..4a117e318a7 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
@@ -1231,7 +1231,6 @@ intel_tv_detect_type (struct intel_tv *intel_tv) | |||
1231 | struct drm_encoder *encoder = &intel_tv->base.enc; | 1231 | struct drm_encoder *encoder = &intel_tv->base.enc; |
1232 | struct drm_device *dev = encoder->dev; | 1232 | struct drm_device *dev = encoder->dev; |
1233 | struct drm_i915_private *dev_priv = dev->dev_private; | 1233 | struct drm_i915_private *dev_priv = dev->dev_private; |
1234 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | ||
1235 | unsigned long irqflags; | 1234 | unsigned long irqflags; |
1236 | u32 tv_ctl, save_tv_ctl; | 1235 | u32 tv_ctl, save_tv_ctl; |
1237 | u32 tv_dac, save_tv_dac; | 1236 | u32 tv_dac, save_tv_dac; |
@@ -1268,11 +1267,15 @@ intel_tv_detect_type (struct intel_tv *intel_tv) | |||
1268 | DAC_C_0_7_V); | 1267 | DAC_C_0_7_V); |
1269 | I915_WRITE(TV_CTL, tv_ctl); | 1268 | I915_WRITE(TV_CTL, tv_ctl); |
1270 | I915_WRITE(TV_DAC, tv_dac); | 1269 | I915_WRITE(TV_DAC, tv_dac); |
1271 | intel_wait_for_vblank(dev, intel_crtc->pipe); | 1270 | POSTING_READ(TV_DAC); |
1271 | msleep(20); | ||
1272 | |||
1272 | tv_dac = I915_READ(TV_DAC); | 1273 | tv_dac = I915_READ(TV_DAC); |
1273 | I915_WRITE(TV_DAC, save_tv_dac); | 1274 | I915_WRITE(TV_DAC, save_tv_dac); |
1274 | I915_WRITE(TV_CTL, save_tv_ctl); | 1275 | I915_WRITE(TV_CTL, save_tv_ctl); |
1275 | intel_wait_for_vblank(dev, intel_crtc->pipe); | 1276 | POSTING_READ(TV_CTL); |
1277 | msleep(20); | ||
1278 | |||
1276 | /* | 1279 | /* |
1277 | * A B C | 1280 | * A B C |
1278 | * 0 1 1 Composite | 1281 | * 0 1 1 Composite |
@@ -1338,7 +1341,7 @@ static void intel_tv_find_better_format(struct drm_connector *connector) | |||
1338 | * we have a pipe programmed in order to probe the TV. | 1341 | * we have a pipe programmed in order to probe the TV. |
1339 | */ | 1342 | */ |
1340 | static enum drm_connector_status | 1343 | static enum drm_connector_status |
1341 | intel_tv_detect(struct drm_connector *connector) | 1344 | intel_tv_detect(struct drm_connector *connector, bool force) |
1342 | { | 1345 | { |
1343 | struct drm_display_mode mode; | 1346 | struct drm_display_mode mode; |
1344 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1347 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
@@ -1350,7 +1353,7 @@ intel_tv_detect(struct drm_connector *connector) | |||
1350 | 1353 | ||
1351 | if (encoder->crtc && encoder->crtc->enabled) { | 1354 | if (encoder->crtc && encoder->crtc->enabled) { |
1352 | type = intel_tv_detect_type(intel_tv); | 1355 | type = intel_tv_detect_type(intel_tv); |
1353 | } else { | 1356 | } else if (force) { |
1354 | struct drm_crtc *crtc; | 1357 | struct drm_crtc *crtc; |
1355 | int dpms_mode; | 1358 | int dpms_mode; |
1356 | 1359 | ||
@@ -1361,10 +1364,9 @@ intel_tv_detect(struct drm_connector *connector) | |||
1361 | intel_release_load_detect_pipe(&intel_tv->base, connector, | 1364 | intel_release_load_detect_pipe(&intel_tv->base, connector, |
1362 | dpms_mode); | 1365 | dpms_mode); |
1363 | } else | 1366 | } else |
1364 | type = -1; | 1367 | return connector_status_unknown; |
1365 | } | 1368 | } else |
1366 | 1369 | return connector->status; | |
1367 | intel_tv->type = type; | ||
1368 | 1370 | ||
1369 | if (type < 0) | 1371 | if (type < 0) |
1370 | return connector_status_disconnected; | 1372 | return connector_status_disconnected; |
diff --git a/drivers/gpu/drm/mga/mga_state.c b/drivers/gpu/drm/mga/mga_state.c index fff82045c42..9ce2827f8c0 100644 --- a/drivers/gpu/drm/mga/mga_state.c +++ b/drivers/gpu/drm/mga/mga_state.c | |||
@@ -1085,19 +1085,19 @@ file_priv) | |||
1085 | } | 1085 | } |
1086 | 1086 | ||
1087 | struct drm_ioctl_desc mga_ioctls[] = { | 1087 | struct drm_ioctl_desc mga_ioctls[] = { |
1088 | DRM_IOCTL_DEF(DRM_MGA_INIT, mga_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1088 | DRM_IOCTL_DEF_DRV(MGA_INIT, mga_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
1089 | DRM_IOCTL_DEF(DRM_MGA_FLUSH, mga_dma_flush, DRM_AUTH), | 1089 | DRM_IOCTL_DEF_DRV(MGA_FLUSH, mga_dma_flush, DRM_AUTH), |
1090 | DRM_IOCTL_DEF(DRM_MGA_RESET, mga_dma_reset, DRM_AUTH), | 1090 | DRM_IOCTL_DEF_DRV(MGA_RESET, mga_dma_reset, DRM_AUTH), |
1091 | DRM_IOCTL_DEF(DRM_MGA_SWAP, mga_dma_swap, DRM_AUTH), | 1091 | DRM_IOCTL_DEF_DRV(MGA_SWAP, mga_dma_swap, DRM_AUTH), |
1092 | DRM_IOCTL_DEF(DRM_MGA_CLEAR, mga_dma_clear, DRM_AUTH), | 1092 | DRM_IOCTL_DEF_DRV(MGA_CLEAR, mga_dma_clear, DRM_AUTH), |
1093 | DRM_IOCTL_DEF(DRM_MGA_VERTEX, mga_dma_vertex, DRM_AUTH), | 1093 | DRM_IOCTL_DEF_DRV(MGA_VERTEX, mga_dma_vertex, DRM_AUTH), |
1094 | DRM_IOCTL_DEF(DRM_MGA_INDICES, mga_dma_indices, DRM_AUTH), | 1094 | DRM_IOCTL_DEF_DRV(MGA_INDICES, mga_dma_indices, DRM_AUTH), |
1095 | DRM_IOCTL_DEF(DRM_MGA_ILOAD, mga_dma_iload, DRM_AUTH), | 1095 | DRM_IOCTL_DEF_DRV(MGA_ILOAD, mga_dma_iload, DRM_AUTH), |
1096 | DRM_IOCTL_DEF(DRM_MGA_BLIT, mga_dma_blit, DRM_AUTH), | 1096 | DRM_IOCTL_DEF_DRV(MGA_BLIT, mga_dma_blit, DRM_AUTH), |
1097 | DRM_IOCTL_DEF(DRM_MGA_GETPARAM, mga_getparam, DRM_AUTH), | 1097 | DRM_IOCTL_DEF_DRV(MGA_GETPARAM, mga_getparam, DRM_AUTH), |
1098 | DRM_IOCTL_DEF(DRM_MGA_SET_FENCE, mga_set_fence, DRM_AUTH), | 1098 | DRM_IOCTL_DEF_DRV(MGA_SET_FENCE, mga_set_fence, DRM_AUTH), |
1099 | DRM_IOCTL_DEF(DRM_MGA_WAIT_FENCE, mga_wait_fence, DRM_AUTH), | 1099 | DRM_IOCTL_DEF_DRV(MGA_WAIT_FENCE, mga_wait_fence, DRM_AUTH), |
1100 | DRM_IOCTL_DEF(DRM_MGA_DMA_BOOTSTRAP, mga_dma_bootstrap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1100 | DRM_IOCTL_DEF_DRV(MGA_DMA_BOOTSTRAP, mga_dma_bootstrap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
1101 | }; | 1101 | }; |
1102 | 1102 | ||
1103 | int mga_max_ioctl = DRM_ARRAY_SIZE(mga_ioctls); | 1103 | int mga_max_ioctl = DRM_ARRAY_SIZE(mga_ioctls); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 0b69a9628c9..974b0f8ae04 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c | |||
@@ -2166,7 +2166,7 @@ peek_fb(struct drm_device *dev, struct io_mapping *fb, | |||
2166 | uint32_t val = 0; | 2166 | uint32_t val = 0; |
2167 | 2167 | ||
2168 | if (off < pci_resource_len(dev->pdev, 1)) { | 2168 | if (off < pci_resource_len(dev->pdev, 1)) { |
2169 | uint32_t __iomem *p = | 2169 | uint8_t __iomem *p = |
2170 | io_mapping_map_atomic_wc(fb, off & PAGE_MASK, KM_USER0); | 2170 | io_mapping_map_atomic_wc(fb, off & PAGE_MASK, KM_USER0); |
2171 | 2171 | ||
2172 | val = ioread32(p + (off & ~PAGE_MASK)); | 2172 | val = ioread32(p + (off & ~PAGE_MASK)); |
@@ -2182,7 +2182,7 @@ poke_fb(struct drm_device *dev, struct io_mapping *fb, | |||
2182 | uint32_t off, uint32_t val) | 2182 | uint32_t off, uint32_t val) |
2183 | { | 2183 | { |
2184 | if (off < pci_resource_len(dev->pdev, 1)) { | 2184 | if (off < pci_resource_len(dev->pdev, 1)) { |
2185 | uint32_t __iomem *p = | 2185 | uint8_t __iomem *p = |
2186 | io_mapping_map_atomic_wc(fb, off & PAGE_MASK, KM_USER0); | 2186 | io_mapping_map_atomic_wc(fb, off & PAGE_MASK, KM_USER0); |
2187 | 2187 | ||
2188 | iowrite32(val, p + (off & ~PAGE_MASK)); | 2188 | iowrite32(val, p + (off & ~PAGE_MASK)); |
@@ -3869,27 +3869,10 @@ static int call_lvds_manufacturer_script(struct drm_device *dev, struct dcb_entr | |||
3869 | } | 3869 | } |
3870 | #ifdef __powerpc__ | 3870 | #ifdef __powerpc__ |
3871 | /* Powerbook specific quirks */ | 3871 | /* Powerbook specific quirks */ |
3872 | if ((dev->pci_device & 0xffff) == 0x0179 || | 3872 | if (script == LVDS_RESET && |
3873 | (dev->pci_device & 0xffff) == 0x0189 || | 3873 | (dev->pci_device == 0x0179 || dev->pci_device == 0x0189 || |
3874 | (dev->pci_device & 0xffff) == 0x0329) { | 3874 | dev->pci_device == 0x0329)) |
3875 | if (script == LVDS_RESET) { | 3875 | nv_write_tmds(dev, dcbent->or, 0, 0x02, 0x72); |
3876 | nv_write_tmds(dev, dcbent->or, 0, 0x02, 0x72); | ||
3877 | |||
3878 | } else if (script == LVDS_PANEL_ON) { | ||
3879 | bios_wr32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL, | ||
3880 | bios_rd32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL) | ||
3881 | | (1 << 31)); | ||
3882 | bios_wr32(bios, NV_PCRTC_GPIO_EXT, | ||
3883 | bios_rd32(bios, NV_PCRTC_GPIO_EXT) | 1); | ||
3884 | |||
3885 | } else if (script == LVDS_PANEL_OFF) { | ||
3886 | bios_wr32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL, | ||
3887 | bios_rd32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL) | ||
3888 | & ~(1 << 31)); | ||
3889 | bios_wr32(bios, NV_PCRTC_GPIO_EXT, | ||
3890 | bios_rd32(bios, NV_PCRTC_GPIO_EXT) & ~3); | ||
3891 | } | ||
3892 | } | ||
3893 | #endif | 3876 | #endif |
3894 | 3877 | ||
3895 | return 0; | 3878 | return 0; |
@@ -4381,11 +4364,8 @@ int nouveau_bios_parse_lvds_table(struct drm_device *dev, int pxclk, bool *dl, b | |||
4381 | * | 4364 | * |
4382 | * For the moment, a quirk will do :) | 4365 | * For the moment, a quirk will do :) |
4383 | */ | 4366 | */ |
4384 | if ((dev->pdev->device == 0x01d7) && | 4367 | if (nv_match_device(dev, 0x01d7, 0x1028, 0x01c2)) |
4385 | (dev->pdev->subsystem_vendor == 0x1028) && | ||
4386 | (dev->pdev->subsystem_device == 0x01c2)) { | ||
4387 | bios->fp.duallink_transition_clk = 80000; | 4368 | bios->fp.duallink_transition_clk = 80000; |
4388 | } | ||
4389 | 4369 | ||
4390 | /* set dual_link flag for EDID case */ | 4370 | /* set dual_link flag for EDID case */ |
4391 | if (pxclk && (chip_version < 0x25 || chip_version > 0x28)) | 4371 | if (pxclk && (chip_version < 0x25 || chip_version > 0x28)) |
@@ -4587,7 +4567,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
4587 | return 1; | 4567 | return 1; |
4588 | } | 4568 | } |
4589 | 4569 | ||
4590 | NV_TRACE(dev, "0x%04X: parsing output script 0\n", script); | 4570 | NV_DEBUG_KMS(dev, "0x%04X: parsing output script 0\n", script); |
4591 | nouveau_bios_run_init_table(dev, script, dcbent); | 4571 | nouveau_bios_run_init_table(dev, script, dcbent); |
4592 | } else | 4572 | } else |
4593 | if (pxclk == -1) { | 4573 | if (pxclk == -1) { |
@@ -4597,7 +4577,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
4597 | return 1; | 4577 | return 1; |
4598 | } | 4578 | } |
4599 | 4579 | ||
4600 | NV_TRACE(dev, "0x%04X: parsing output script 1\n", script); | 4580 | NV_DEBUG_KMS(dev, "0x%04X: parsing output script 1\n", script); |
4601 | nouveau_bios_run_init_table(dev, script, dcbent); | 4581 | nouveau_bios_run_init_table(dev, script, dcbent); |
4602 | } else | 4582 | } else |
4603 | if (pxclk == -2) { | 4583 | if (pxclk == -2) { |
@@ -4610,7 +4590,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
4610 | return 1; | 4590 | return 1; |
4611 | } | 4591 | } |
4612 | 4592 | ||
4613 | NV_TRACE(dev, "0x%04X: parsing output script 2\n", script); | 4593 | NV_DEBUG_KMS(dev, "0x%04X: parsing output script 2\n", script); |
4614 | nouveau_bios_run_init_table(dev, script, dcbent); | 4594 | nouveau_bios_run_init_table(dev, script, dcbent); |
4615 | } else | 4595 | } else |
4616 | if (pxclk > 0) { | 4596 | if (pxclk > 0) { |
@@ -4622,7 +4602,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
4622 | return 1; | 4602 | return 1; |
4623 | } | 4603 | } |
4624 | 4604 | ||
4625 | NV_TRACE(dev, "0x%04X: parsing clock script 0\n", script); | 4605 | NV_DEBUG_KMS(dev, "0x%04X: parsing clock script 0\n", script); |
4626 | nouveau_bios_run_init_table(dev, script, dcbent); | 4606 | nouveau_bios_run_init_table(dev, script, dcbent); |
4627 | } else | 4607 | } else |
4628 | if (pxclk < 0) { | 4608 | if (pxclk < 0) { |
@@ -4634,7 +4614,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
4634 | return 1; | 4614 | return 1; |
4635 | } | 4615 | } |
4636 | 4616 | ||
4637 | NV_TRACE(dev, "0x%04X: parsing clock script 1\n", script); | 4617 | NV_DEBUG_KMS(dev, "0x%04X: parsing clock script 1\n", script); |
4638 | nouveau_bios_run_init_table(dev, script, dcbent); | 4618 | nouveau_bios_run_init_table(dev, script, dcbent); |
4639 | } | 4619 | } |
4640 | 4620 | ||
@@ -5357,19 +5337,17 @@ static int parse_bit_tmds_tbl_entry(struct drm_device *dev, struct nvbios *bios, | |||
5357 | } | 5337 | } |
5358 | 5338 | ||
5359 | tmdstableptr = ROM16(bios->data[bitentry->offset]); | 5339 | tmdstableptr = ROM16(bios->data[bitentry->offset]); |
5360 | 5340 | if (!tmdstableptr) { | |
5361 | if (tmdstableptr == 0x0) { | ||
5362 | NV_ERROR(dev, "Pointer to TMDS table invalid\n"); | 5341 | NV_ERROR(dev, "Pointer to TMDS table invalid\n"); |
5363 | return -EINVAL; | 5342 | return -EINVAL; |
5364 | } | 5343 | } |
5365 | 5344 | ||
5345 | NV_INFO(dev, "TMDS table version %d.%d\n", | ||
5346 | bios->data[tmdstableptr] >> 4, bios->data[tmdstableptr] & 0xf); | ||
5347 | |||
5366 | /* nv50+ has v2.0, but we don't parse it atm */ | 5348 | /* nv50+ has v2.0, but we don't parse it atm */ |
5367 | if (bios->data[tmdstableptr] != 0x11) { | 5349 | if (bios->data[tmdstableptr] != 0x11) |
5368 | NV_WARN(dev, | ||
5369 | "TMDS table revision %d.%d not currently supported\n", | ||
5370 | bios->data[tmdstableptr] >> 4, bios->data[tmdstableptr] & 0xf); | ||
5371 | return -ENOSYS; | 5350 | return -ENOSYS; |
5372 | } | ||
5373 | 5351 | ||
5374 | /* | 5352 | /* |
5375 | * These two scripts are odd: they don't seem to get run even when | 5353 | * These two scripts are odd: they don't seem to get run even when |
@@ -5809,6 +5787,20 @@ parse_dcb_gpio_table(struct nvbios *bios) | |||
5809 | gpio->line = tvdac_gpio[1] >> 4; | 5787 | gpio->line = tvdac_gpio[1] >> 4; |
5810 | gpio->invert = tvdac_gpio[0] & 2; | 5788 | gpio->invert = tvdac_gpio[0] & 2; |
5811 | } | 5789 | } |
5790 | } else { | ||
5791 | /* | ||
5792 | * No systematic way to store GPIO info on pre-v2.2 | ||
5793 | * DCBs, try to match the PCI device IDs. | ||
5794 | */ | ||
5795 | |||
5796 | /* Apple iMac G4 NV18 */ | ||
5797 | if (nv_match_device(dev, 0x0189, 0x10de, 0x0010)) { | ||
5798 | struct dcb_gpio_entry *gpio = new_gpio_entry(bios); | ||
5799 | |||
5800 | gpio->tag = DCB_GPIO_TVDAC0; | ||
5801 | gpio->line = 4; | ||
5802 | } | ||
5803 | |||
5812 | } | 5804 | } |
5813 | 5805 | ||
5814 | if (!gpio_table_ptr) | 5806 | if (!gpio_table_ptr) |
@@ -5884,9 +5876,7 @@ apply_dcb_connector_quirks(struct nvbios *bios, int idx) | |||
5884 | struct drm_device *dev = bios->dev; | 5876 | struct drm_device *dev = bios->dev; |
5885 | 5877 | ||
5886 | /* Gigabyte NX85T */ | 5878 | /* Gigabyte NX85T */ |
5887 | if ((dev->pdev->device == 0x0421) && | 5879 | if (nv_match_device(dev, 0x0421, 0x1458, 0x344c)) { |
5888 | (dev->pdev->subsystem_vendor == 0x1458) && | ||
5889 | (dev->pdev->subsystem_device == 0x344c)) { | ||
5890 | if (cte->type == DCB_CONNECTOR_HDMI_1) | 5880 | if (cte->type == DCB_CONNECTOR_HDMI_1) |
5891 | cte->type = DCB_CONNECTOR_DVI_I; | 5881 | cte->type = DCB_CONNECTOR_DVI_I; |
5892 | } | 5882 | } |
@@ -6139,7 +6129,7 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb, | |||
6139 | entry->tmdsconf.slave_addr = (conf & 0x00000070) >> 4; | 6129 | entry->tmdsconf.slave_addr = (conf & 0x00000070) >> 4; |
6140 | 6130 | ||
6141 | break; | 6131 | break; |
6142 | case 0xe: | 6132 | case OUTPUT_EOL: |
6143 | /* weird g80 mobile type that "nv" treats as a terminator */ | 6133 | /* weird g80 mobile type that "nv" treats as a terminator */ |
6144 | dcb->entries--; | 6134 | dcb->entries--; |
6145 | return false; | 6135 | return false; |
@@ -6176,22 +6166,14 @@ parse_dcb15_entry(struct drm_device *dev, struct dcb_table *dcb, | |||
6176 | entry->type = OUTPUT_TV; | 6166 | entry->type = OUTPUT_TV; |
6177 | break; | 6167 | break; |
6178 | case 2: | 6168 | case 2: |
6179 | case 3: | ||
6180 | entry->type = OUTPUT_LVDS; | ||
6181 | break; | ||
6182 | case 4: | 6169 | case 4: |
6183 | switch ((conn & 0x000000f0) >> 4) { | 6170 | if (conn & 0x10) |
6184 | case 0: | ||
6185 | entry->type = OUTPUT_TMDS; | ||
6186 | break; | ||
6187 | case 1: | ||
6188 | entry->type = OUTPUT_LVDS; | 6171 | entry->type = OUTPUT_LVDS; |
6189 | break; | 6172 | else |
6190 | default: | 6173 | entry->type = OUTPUT_TMDS; |
6191 | NV_ERROR(dev, "Unknown DCB subtype 4/%d\n", | 6174 | break; |
6192 | (conn & 0x000000f0) >> 4); | 6175 | case 3: |
6193 | return false; | 6176 | entry->type = OUTPUT_LVDS; |
6194 | } | ||
6195 | break; | 6177 | break; |
6196 | default: | 6178 | default: |
6197 | NV_ERROR(dev, "Unknown DCB type %d\n", conn & 0x0000000f); | 6179 | NV_ERROR(dev, "Unknown DCB type %d\n", conn & 0x0000000f); |
@@ -6307,9 +6289,7 @@ apply_dcb_encoder_quirks(struct drm_device *dev, int idx, u32 *conn, u32 *conf) | |||
6307 | * nasty problems until this is sorted (assuming it's not a | 6289 | * nasty problems until this is sorted (assuming it's not a |
6308 | * VBIOS bug). | 6290 | * VBIOS bug). |
6309 | */ | 6291 | */ |
6310 | if ((dev->pdev->device == 0x040d) && | 6292 | if (nv_match_device(dev, 0x040d, 0x1028, 0x019b)) { |
6311 | (dev->pdev->subsystem_vendor == 0x1028) && | ||
6312 | (dev->pdev->subsystem_device == 0x019b)) { | ||
6313 | if (*conn == 0x02026312 && *conf == 0x00000020) | 6293 | if (*conn == 0x02026312 && *conf == 0x00000020) |
6314 | return false; | 6294 | return false; |
6315 | } | 6295 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h index fd14dfd3d78..c1de2f3fcb0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.h +++ b/drivers/gpu/drm/nouveau/nouveau_bios.h | |||
@@ -95,6 +95,7 @@ enum dcb_type { | |||
95 | OUTPUT_TMDS = 2, | 95 | OUTPUT_TMDS = 2, |
96 | OUTPUT_LVDS = 3, | 96 | OUTPUT_LVDS = 3, |
97 | OUTPUT_DP = 6, | 97 | OUTPUT_DP = 6, |
98 | OUTPUT_EOL = 14, /* DCB 4.0+, appears to be end-of-list */ | ||
98 | OUTPUT_ANY = -1 | 99 | OUTPUT_ANY = -1 |
99 | }; | 100 | }; |
100 | 101 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 84f85183d04..f6f44779d82 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c | |||
@@ -36,6 +36,21 @@ | |||
36 | #include <linux/log2.h> | 36 | #include <linux/log2.h> |
37 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
38 | 38 | ||
39 | int | ||
40 | nouveau_bo_sync_gpu(struct nouveau_bo *nvbo, struct nouveau_channel *chan) | ||
41 | { | ||
42 | struct nouveau_fence *prev_fence = nvbo->bo.sync_obj; | ||
43 | int ret; | ||
44 | |||
45 | if (!prev_fence || nouveau_fence_channel(prev_fence) == chan) | ||
46 | return 0; | ||
47 | |||
48 | spin_lock(&nvbo->bo.lock); | ||
49 | ret = ttm_bo_wait(&nvbo->bo, false, false, false); | ||
50 | spin_unlock(&nvbo->bo.lock); | ||
51 | return ret; | ||
52 | } | ||
53 | |||
39 | static void | 54 | static void |
40 | nouveau_bo_del_ttm(struct ttm_buffer_object *bo) | 55 | nouveau_bo_del_ttm(struct ttm_buffer_object *bo) |
41 | { | 56 | { |
diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index 90fdcda332b..0480f064f2c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c | |||
@@ -426,18 +426,18 @@ nouveau_ioctl_fifo_free(struct drm_device *dev, void *data, | |||
426 | ***********************************/ | 426 | ***********************************/ |
427 | 427 | ||
428 | struct drm_ioctl_desc nouveau_ioctls[] = { | 428 | struct drm_ioctl_desc nouveau_ioctls[] = { |
429 | DRM_IOCTL_DEF(DRM_NOUVEAU_GETPARAM, nouveau_ioctl_getparam, DRM_AUTH), | 429 | DRM_IOCTL_DEF_DRV(NOUVEAU_GETPARAM, nouveau_ioctl_getparam, DRM_AUTH), |
430 | DRM_IOCTL_DEF(DRM_NOUVEAU_SETPARAM, nouveau_ioctl_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 430 | DRM_IOCTL_DEF_DRV(NOUVEAU_SETPARAM, nouveau_ioctl_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
431 | DRM_IOCTL_DEF(DRM_NOUVEAU_CHANNEL_ALLOC, nouveau_ioctl_fifo_alloc, DRM_AUTH), | 431 | DRM_IOCTL_DEF_DRV(NOUVEAU_CHANNEL_ALLOC, nouveau_ioctl_fifo_alloc, DRM_AUTH), |
432 | DRM_IOCTL_DEF(DRM_NOUVEAU_CHANNEL_FREE, nouveau_ioctl_fifo_free, DRM_AUTH), | 432 | DRM_IOCTL_DEF_DRV(NOUVEAU_CHANNEL_FREE, nouveau_ioctl_fifo_free, DRM_AUTH), |
433 | DRM_IOCTL_DEF(DRM_NOUVEAU_GROBJ_ALLOC, nouveau_ioctl_grobj_alloc, DRM_AUTH), | 433 | DRM_IOCTL_DEF_DRV(NOUVEAU_GROBJ_ALLOC, nouveau_ioctl_grobj_alloc, DRM_AUTH), |
434 | DRM_IOCTL_DEF(DRM_NOUVEAU_NOTIFIEROBJ_ALLOC, nouveau_ioctl_notifier_alloc, DRM_AUTH), | 434 | DRM_IOCTL_DEF_DRV(NOUVEAU_NOTIFIEROBJ_ALLOC, nouveau_ioctl_notifier_alloc, DRM_AUTH), |
435 | DRM_IOCTL_DEF(DRM_NOUVEAU_GPUOBJ_FREE, nouveau_ioctl_gpuobj_free, DRM_AUTH), | 435 | DRM_IOCTL_DEF_DRV(NOUVEAU_GPUOBJ_FREE, nouveau_ioctl_gpuobj_free, DRM_AUTH), |
436 | DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_NEW, nouveau_gem_ioctl_new, DRM_AUTH), | 436 | DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_NEW, nouveau_gem_ioctl_new, DRM_AUTH), |
437 | DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PUSHBUF, nouveau_gem_ioctl_pushbuf, DRM_AUTH), | 437 | DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_PUSHBUF, nouveau_gem_ioctl_pushbuf, DRM_AUTH), |
438 | DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, DRM_AUTH), | 438 | DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, DRM_AUTH), |
439 | DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, DRM_AUTH), | 439 | DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, DRM_AUTH), |
440 | DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, DRM_AUTH), | 440 | DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, DRM_AUTH), |
441 | }; | 441 | }; |
442 | 442 | ||
443 | int nouveau_max_ioctl = DRM_ARRAY_SIZE(nouveau_ioctls); | 443 | int nouveau_max_ioctl = DRM_ARRAY_SIZE(nouveau_ioctls); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index b1b22baf142..fc737037f75 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c | |||
@@ -104,7 +104,7 @@ nouveau_connector_ddc_detect(struct drm_connector *connector, | |||
104 | int i; | 104 | int i; |
105 | 105 | ||
106 | for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { | 106 | for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { |
107 | struct nouveau_i2c_chan *i2c; | 107 | struct nouveau_i2c_chan *i2c = NULL; |
108 | struct nouveau_encoder *nv_encoder; | 108 | struct nouveau_encoder *nv_encoder; |
109 | struct drm_mode_object *obj; | 109 | struct drm_mode_object *obj; |
110 | int id; | 110 | int id; |
@@ -117,7 +117,9 @@ nouveau_connector_ddc_detect(struct drm_connector *connector, | |||
117 | if (!obj) | 117 | if (!obj) |
118 | continue; | 118 | continue; |
119 | nv_encoder = nouveau_encoder(obj_to_encoder(obj)); | 119 | nv_encoder = nouveau_encoder(obj_to_encoder(obj)); |
120 | i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index); | 120 | |
121 | if (nv_encoder->dcb->i2c_index < 0xf) | ||
122 | i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index); | ||
121 | 123 | ||
122 | if (i2c && nouveau_probe_i2c_addr(i2c, 0x50)) { | 124 | if (i2c && nouveau_probe_i2c_addr(i2c, 0x50)) { |
123 | *pnv_encoder = nv_encoder; | 125 | *pnv_encoder = nv_encoder; |
@@ -166,7 +168,7 @@ nouveau_connector_set_encoder(struct drm_connector *connector, | |||
166 | } | 168 | } |
167 | 169 | ||
168 | static enum drm_connector_status | 170 | static enum drm_connector_status |
169 | nouveau_connector_detect(struct drm_connector *connector) | 171 | nouveau_connector_detect(struct drm_connector *connector, bool force) |
170 | { | 172 | { |
171 | struct drm_device *dev = connector->dev; | 173 | struct drm_device *dev = connector->dev; |
172 | struct nouveau_connector *nv_connector = nouveau_connector(connector); | 174 | struct nouveau_connector *nv_connector = nouveau_connector(connector); |
@@ -244,7 +246,7 @@ detect_analog: | |||
244 | } | 246 | } |
245 | 247 | ||
246 | static enum drm_connector_status | 248 | static enum drm_connector_status |
247 | nouveau_connector_detect_lvds(struct drm_connector *connector) | 249 | nouveau_connector_detect_lvds(struct drm_connector *connector, bool force) |
248 | { | 250 | { |
249 | struct drm_device *dev = connector->dev; | 251 | struct drm_device *dev = connector->dev; |
250 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 252 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
@@ -265,7 +267,7 @@ nouveau_connector_detect_lvds(struct drm_connector *connector) | |||
265 | 267 | ||
266 | /* Try retrieving EDID via DDC */ | 268 | /* Try retrieving EDID via DDC */ |
267 | if (!dev_priv->vbios.fp_no_ddc) { | 269 | if (!dev_priv->vbios.fp_no_ddc) { |
268 | status = nouveau_connector_detect(connector); | 270 | status = nouveau_connector_detect(connector, force); |
269 | if (status == connector_status_connected) | 271 | if (status == connector_status_connected) |
270 | goto out; | 272 | goto out; |
271 | } | 273 | } |
@@ -556,8 +558,10 @@ nouveau_connector_get_modes(struct drm_connector *connector) | |||
556 | if (nv_encoder->dcb->type == OUTPUT_LVDS && | 558 | if (nv_encoder->dcb->type == OUTPUT_LVDS && |
557 | (nv_encoder->dcb->lvdsconf.use_straps_for_mode || | 559 | (nv_encoder->dcb->lvdsconf.use_straps_for_mode || |
558 | dev_priv->vbios.fp_no_ddc) && nouveau_bios_fp_mode(dev, NULL)) { | 560 | dev_priv->vbios.fp_no_ddc) && nouveau_bios_fp_mode(dev, NULL)) { |
559 | nv_connector->native_mode = drm_mode_create(dev); | 561 | struct drm_display_mode mode; |
560 | nouveau_bios_fp_mode(dev, nv_connector->native_mode); | 562 | |
563 | nouveau_bios_fp_mode(dev, &mode); | ||
564 | nv_connector->native_mode = drm_mode_duplicate(dev, &mode); | ||
561 | } | 565 | } |
562 | 566 | ||
563 | /* Find the native mode if this is a digital panel, if we didn't | 567 | /* Find the native mode if this is a digital panel, if we didn't |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index e424bf74d70..b1be617373b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
@@ -1165,6 +1165,7 @@ extern u16 nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index); | |||
1165 | extern void nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val); | 1165 | extern void nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val); |
1166 | extern u32 nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index); | 1166 | extern u32 nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index); |
1167 | extern void nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, u32 val); | 1167 | extern void nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, u32 val); |
1168 | extern int nouveau_bo_sync_gpu(struct nouveau_bo *, struct nouveau_channel *); | ||
1168 | 1169 | ||
1169 | /* nouveau_fence.c */ | 1170 | /* nouveau_fence.c */ |
1170 | struct nouveau_fence; | 1171 | struct nouveau_fence; |
@@ -1388,6 +1389,15 @@ nv_two_reg_pll(struct drm_device *dev) | |||
1388 | return false; | 1389 | return false; |
1389 | } | 1390 | } |
1390 | 1391 | ||
1392 | static inline bool | ||
1393 | nv_match_device(struct drm_device *dev, unsigned device, | ||
1394 | unsigned sub_vendor, unsigned sub_device) | ||
1395 | { | ||
1396 | return dev->pdev->device == device && | ||
1397 | dev->pdev->subsystem_vendor == sub_vendor && | ||
1398 | dev->pdev->subsystem_device == sub_device; | ||
1399 | } | ||
1400 | |||
1391 | #define NV_SW 0x0000506e | 1401 | #define NV_SW 0x0000506e |
1392 | #define NV_SW_DMA_SEMAPHORE 0x00000060 | 1402 | #define NV_SW_DMA_SEMAPHORE 0x00000060 |
1393 | #define NV_SW_SEMAPHORE_OFFSET 0x00000064 | 1403 | #define NV_SW_SEMAPHORE_OFFSET 0x00000064 |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 6b208ffafa8..87ac21ec23d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c | |||
@@ -64,16 +64,17 @@ nouveau_fence_update(struct nouveau_channel *chan) | |||
64 | struct nouveau_fence *fence; | 64 | struct nouveau_fence *fence; |
65 | uint32_t sequence; | 65 | uint32_t sequence; |
66 | 66 | ||
67 | spin_lock(&chan->fence.lock); | ||
68 | |||
67 | if (USE_REFCNT) | 69 | if (USE_REFCNT) |
68 | sequence = nvchan_rd32(chan, 0x48); | 70 | sequence = nvchan_rd32(chan, 0x48); |
69 | else | 71 | else |
70 | sequence = atomic_read(&chan->fence.last_sequence_irq); | 72 | sequence = atomic_read(&chan->fence.last_sequence_irq); |
71 | 73 | ||
72 | if (chan->fence.sequence_ack == sequence) | 74 | if (chan->fence.sequence_ack == sequence) |
73 | return; | 75 | goto out; |
74 | chan->fence.sequence_ack = sequence; | 76 | chan->fence.sequence_ack = sequence; |
75 | 77 | ||
76 | spin_lock(&chan->fence.lock); | ||
77 | list_for_each_safe(entry, tmp, &chan->fence.pending) { | 78 | list_for_each_safe(entry, tmp, &chan->fence.pending) { |
78 | fence = list_entry(entry, struct nouveau_fence, entry); | 79 | fence = list_entry(entry, struct nouveau_fence, entry); |
79 | 80 | ||
@@ -85,6 +86,7 @@ nouveau_fence_update(struct nouveau_channel *chan) | |||
85 | if (sequence == chan->fence.sequence_ack) | 86 | if (sequence == chan->fence.sequence_ack) |
86 | break; | 87 | break; |
87 | } | 88 | } |
89 | out: | ||
88 | spin_unlock(&chan->fence.lock); | 90 | spin_unlock(&chan->fence.lock); |
89 | } | 91 | } |
90 | 92 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 0f417ac1b69..19620a6709f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c | |||
@@ -167,11 +167,9 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data, | |||
167 | goto out; | 167 | goto out; |
168 | 168 | ||
169 | ret = drm_gem_handle_create(file_priv, nvbo->gem, &req->info.handle); | 169 | ret = drm_gem_handle_create(file_priv, nvbo->gem, &req->info.handle); |
170 | /* drop reference from allocate - handle holds it now */ | ||
171 | drm_gem_object_unreference_unlocked(nvbo->gem); | ||
170 | out: | 172 | out: |
171 | drm_gem_object_handle_unreference_unlocked(nvbo->gem); | ||
172 | |||
173 | if (ret) | ||
174 | drm_gem_object_unreference_unlocked(nvbo->gem); | ||
175 | return ret; | 173 | return ret; |
176 | } | 174 | } |
177 | 175 | ||
@@ -245,7 +243,7 @@ validate_fini_list(struct list_head *list, struct nouveau_fence *fence) | |||
245 | list_del(&nvbo->entry); | 243 | list_del(&nvbo->entry); |
246 | nvbo->reserved_by = NULL; | 244 | nvbo->reserved_by = NULL; |
247 | ttm_bo_unreserve(&nvbo->bo); | 245 | ttm_bo_unreserve(&nvbo->bo); |
248 | drm_gem_object_unreference(nvbo->gem); | 246 | drm_gem_object_unreference_unlocked(nvbo->gem); |
249 | } | 247 | } |
250 | } | 248 | } |
251 | 249 | ||
@@ -300,7 +298,7 @@ retry: | |||
300 | validate_fini(op, NULL); | 298 | validate_fini(op, NULL); |
301 | if (ret == -EAGAIN) | 299 | if (ret == -EAGAIN) |
302 | ret = ttm_bo_wait_unreserved(&nvbo->bo, false); | 300 | ret = ttm_bo_wait_unreserved(&nvbo->bo, false); |
303 | drm_gem_object_unreference(gem); | 301 | drm_gem_object_unreference_unlocked(gem); |
304 | if (ret) { | 302 | if (ret) { |
305 | NV_ERROR(dev, "fail reserve\n"); | 303 | NV_ERROR(dev, "fail reserve\n"); |
306 | return ret; | 304 | return ret; |
@@ -337,7 +335,9 @@ retry: | |||
337 | return -EINVAL; | 335 | return -EINVAL; |
338 | } | 336 | } |
339 | 337 | ||
338 | mutex_unlock(&drm_global_mutex); | ||
340 | ret = ttm_bo_wait_cpu(&nvbo->bo, false); | 339 | ret = ttm_bo_wait_cpu(&nvbo->bo, false); |
340 | mutex_lock(&drm_global_mutex); | ||
341 | if (ret) { | 341 | if (ret) { |
342 | NV_ERROR(dev, "fail wait_cpu\n"); | 342 | NV_ERROR(dev, "fail wait_cpu\n"); |
343 | return ret; | 343 | return ret; |
@@ -361,16 +361,11 @@ validate_list(struct nouveau_channel *chan, struct list_head *list, | |||
361 | 361 | ||
362 | list_for_each_entry(nvbo, list, entry) { | 362 | list_for_each_entry(nvbo, list, entry) { |
363 | struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[nvbo->pbbo_index]; | 363 | struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[nvbo->pbbo_index]; |
364 | struct nouveau_fence *prev_fence = nvbo->bo.sync_obj; | ||
365 | 364 | ||
366 | if (prev_fence && nouveau_fence_channel(prev_fence) != chan) { | 365 | ret = nouveau_bo_sync_gpu(nvbo, chan); |
367 | spin_lock(&nvbo->bo.lock); | 366 | if (unlikely(ret)) { |
368 | ret = ttm_bo_wait(&nvbo->bo, false, false, false); | 367 | NV_ERROR(dev, "fail pre-validate sync\n"); |
369 | spin_unlock(&nvbo->bo.lock); | 368 | return ret; |
370 | if (unlikely(ret)) { | ||
371 | NV_ERROR(dev, "fail wait other chan\n"); | ||
372 | return ret; | ||
373 | } | ||
374 | } | 369 | } |
375 | 370 | ||
376 | ret = nouveau_gem_set_domain(nvbo->gem, b->read_domains, | 371 | ret = nouveau_gem_set_domain(nvbo->gem, b->read_domains, |
@@ -381,7 +376,7 @@ validate_list(struct nouveau_channel *chan, struct list_head *list, | |||
381 | return ret; | 376 | return ret; |
382 | } | 377 | } |
383 | 378 | ||
384 | nvbo->channel = chan; | 379 | nvbo->channel = (b->read_domains & (1 << 31)) ? NULL : chan; |
385 | ret = ttm_bo_validate(&nvbo->bo, &nvbo->placement, | 380 | ret = ttm_bo_validate(&nvbo->bo, &nvbo->placement, |
386 | false, false, false); | 381 | false, false, false); |
387 | nvbo->channel = NULL; | 382 | nvbo->channel = NULL; |
@@ -390,6 +385,12 @@ validate_list(struct nouveau_channel *chan, struct list_head *list, | |||
390 | return ret; | 385 | return ret; |
391 | } | 386 | } |
392 | 387 | ||
388 | ret = nouveau_bo_sync_gpu(nvbo, chan); | ||
389 | if (unlikely(ret)) { | ||
390 | NV_ERROR(dev, "fail post-validate sync\n"); | ||
391 | return ret; | ||
392 | } | ||
393 | |||
393 | if (nvbo->bo.offset == b->presumed.offset && | 394 | if (nvbo->bo.offset == b->presumed.offset && |
394 | ((nvbo->bo.mem.mem_type == TTM_PL_VRAM && | 395 | ((nvbo->bo.mem.mem_type == TTM_PL_VRAM && |
395 | b->presumed.domain & NOUVEAU_GEM_DOMAIN_VRAM) || | 396 | b->presumed.domain & NOUVEAU_GEM_DOMAIN_VRAM) || |
@@ -613,7 +614,20 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, | |||
613 | return PTR_ERR(bo); | 614 | return PTR_ERR(bo); |
614 | } | 615 | } |
615 | 616 | ||
616 | mutex_lock(&dev->struct_mutex); | 617 | /* Mark push buffers as being used on PFIFO, the validation code |
618 | * will then make sure that if the pushbuf bo moves, that they | ||
619 | * happen on the kernel channel, which will in turn cause a sync | ||
620 | * to happen before we try and submit the push buffer. | ||
621 | */ | ||
622 | for (i = 0; i < req->nr_push; i++) { | ||
623 | if (push[i].bo_index >= req->nr_buffers) { | ||
624 | NV_ERROR(dev, "push %d buffer not in list\n", i); | ||
625 | ret = -EINVAL; | ||
626 | goto out; | ||
627 | } | ||
628 | |||
629 | bo[push[i].bo_index].read_domains |= (1 << 31); | ||
630 | } | ||
617 | 631 | ||
618 | /* Validate buffer list */ | 632 | /* Validate buffer list */ |
619 | ret = nouveau_gem_pushbuf_validate(chan, file_priv, bo, req->buffers, | 633 | ret = nouveau_gem_pushbuf_validate(chan, file_priv, bo, req->buffers, |
@@ -647,7 +661,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, | |||
647 | push[i].length); | 661 | push[i].length); |
648 | } | 662 | } |
649 | } else | 663 | } else |
650 | if (dev_priv->card_type >= NV_20) { | 664 | if (dev_priv->chipset >= 0x25) { |
651 | ret = RING_SPACE(chan, req->nr_push * 2); | 665 | ret = RING_SPACE(chan, req->nr_push * 2); |
652 | if (ret) { | 666 | if (ret) { |
653 | NV_ERROR(dev, "cal_space: %d\n", ret); | 667 | NV_ERROR(dev, "cal_space: %d\n", ret); |
@@ -713,7 +727,6 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, | |||
713 | out: | 727 | out: |
714 | validate_fini(&op, fence); | 728 | validate_fini(&op, fence); |
715 | nouveau_fence_unref((void**)&fence); | 729 | nouveau_fence_unref((void**)&fence); |
716 | mutex_unlock(&dev->struct_mutex); | ||
717 | kfree(bo); | 730 | kfree(bo); |
718 | kfree(push); | 731 | kfree(push); |
719 | 732 | ||
@@ -722,7 +735,7 @@ out_next: | |||
722 | req->suffix0 = 0x00000000; | 735 | req->suffix0 = 0x00000000; |
723 | req->suffix1 = 0x00000000; | 736 | req->suffix1 = 0x00000000; |
724 | } else | 737 | } else |
725 | if (dev_priv->card_type >= NV_20) { | 738 | if (dev_priv->chipset >= 0x25) { |
726 | req->suffix0 = 0x00020000; | 739 | req->suffix0 = 0x00020000; |
727 | req->suffix1 = 0x00000000; | 740 | req->suffix1 = 0x00000000; |
728 | } else { | 741 | } else { |
diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c index 0bd407ca3d4..84614858728 100644 --- a/drivers/gpu/drm/nouveau/nouveau_i2c.c +++ b/drivers/gpu/drm/nouveau/nouveau_i2c.c | |||
@@ -163,7 +163,7 @@ nouveau_i2c_init(struct drm_device *dev, struct dcb_i2c_entry *entry, int index) | |||
163 | if (entry->chan) | 163 | if (entry->chan) |
164 | return -EEXIST; | 164 | return -EEXIST; |
165 | 165 | ||
166 | if (dev_priv->card_type == NV_C0 && entry->read >= NV50_I2C_PORTS) { | 166 | if (dev_priv->card_type >= NV_50 && entry->read >= NV50_I2C_PORTS) { |
167 | NV_ERROR(dev, "unknown i2c port %d\n", entry->read); | 167 | NV_ERROR(dev, "unknown i2c port %d\n", entry->read); |
168 | return -EINVAL; | 168 | return -EINVAL; |
169 | } | 169 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c index 491767fe4fc..6b9187d7f67 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c | |||
@@ -214,6 +214,7 @@ int | |||
214 | nouveau_sgdma_init(struct drm_device *dev) | 214 | nouveau_sgdma_init(struct drm_device *dev) |
215 | { | 215 | { |
216 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 216 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
217 | struct pci_dev *pdev = dev->pdev; | ||
217 | struct nouveau_gpuobj *gpuobj = NULL; | 218 | struct nouveau_gpuobj *gpuobj = NULL; |
218 | uint32_t aper_size, obj_size; | 219 | uint32_t aper_size, obj_size; |
219 | int i, ret; | 220 | int i, ret; |
@@ -239,10 +240,19 @@ nouveau_sgdma_init(struct drm_device *dev) | |||
239 | 240 | ||
240 | dev_priv->gart_info.sg_dummy_page = | 241 | dev_priv->gart_info.sg_dummy_page = |
241 | alloc_page(GFP_KERNEL|__GFP_DMA32); | 242 | alloc_page(GFP_KERNEL|__GFP_DMA32); |
243 | if (!dev_priv->gart_info.sg_dummy_page) { | ||
244 | nouveau_gpuobj_del(dev, &gpuobj); | ||
245 | return -ENOMEM; | ||
246 | } | ||
247 | |||
242 | set_bit(PG_locked, &dev_priv->gart_info.sg_dummy_page->flags); | 248 | set_bit(PG_locked, &dev_priv->gart_info.sg_dummy_page->flags); |
243 | dev_priv->gart_info.sg_dummy_bus = | 249 | dev_priv->gart_info.sg_dummy_bus = |
244 | pci_map_page(dev->pdev, dev_priv->gart_info.sg_dummy_page, 0, | 250 | pci_map_page(pdev, dev_priv->gart_info.sg_dummy_page, 0, |
245 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); | 251 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); |
252 | if (pci_dma_mapping_error(pdev, dev_priv->gart_info.sg_dummy_bus)) { | ||
253 | nouveau_gpuobj_del(dev, &gpuobj); | ||
254 | return -EFAULT; | ||
255 | } | ||
246 | 256 | ||
247 | if (dev_priv->card_type < NV_50) { | 257 | if (dev_priv->card_type < NV_50) { |
248 | /* Maybe use NV_DMA_TARGET_AGP for PCIE? NVIDIA do this, and | 258 | /* Maybe use NV_DMA_TARGET_AGP for PCIE? NVIDIA do this, and |
diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c index a5dcf768580..0d3206a7046 100644 --- a/drivers/gpu/drm/nouveau/nv04_dfp.c +++ b/drivers/gpu/drm/nouveau/nv04_dfp.c | |||
@@ -444,6 +444,7 @@ static void nv04_dfp_commit(struct drm_encoder *encoder) | |||
444 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 444 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
445 | struct dcb_entry *dcbe = nv_encoder->dcb; | 445 | struct dcb_entry *dcbe = nv_encoder->dcb; |
446 | int head = nouveau_crtc(encoder->crtc)->index; | 446 | int head = nouveau_crtc(encoder->crtc)->index; |
447 | struct drm_encoder *slave_encoder; | ||
447 | 448 | ||
448 | if (dcbe->type == OUTPUT_TMDS) | 449 | if (dcbe->type == OUTPUT_TMDS) |
449 | run_tmds_table(dev, dcbe, head, nv_encoder->mode.clock); | 450 | run_tmds_table(dev, dcbe, head, nv_encoder->mode.clock); |
@@ -462,9 +463,10 @@ static void nv04_dfp_commit(struct drm_encoder *encoder) | |||
462 | NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0x00100000); | 463 | NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0x00100000); |
463 | 464 | ||
464 | /* Init external transmitters */ | 465 | /* Init external transmitters */ |
465 | if (get_tmds_slave(encoder)) | 466 | slave_encoder = get_tmds_slave(encoder); |
466 | get_slave_funcs(get_tmds_slave(encoder))->mode_set( | 467 | if (slave_encoder) |
467 | encoder, &nv_encoder->mode, &nv_encoder->mode); | 468 | get_slave_funcs(slave_encoder)->mode_set( |
469 | slave_encoder, &nv_encoder->mode, &nv_encoder->mode); | ||
468 | 470 | ||
469 | helper->dpms(encoder, DRM_MODE_DPMS_ON); | 471 | helper->dpms(encoder, DRM_MODE_DPMS_ON); |
470 | 472 | ||
@@ -473,6 +475,27 @@ static void nv04_dfp_commit(struct drm_encoder *encoder) | |||
473 | nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); | 475 | nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); |
474 | } | 476 | } |
475 | 477 | ||
478 | static void nv04_dfp_update_backlight(struct drm_encoder *encoder, int mode) | ||
479 | { | ||
480 | #ifdef __powerpc__ | ||
481 | struct drm_device *dev = encoder->dev; | ||
482 | |||
483 | /* BIOS scripts usually take care of the backlight, thanks | ||
484 | * Apple for your consistency. | ||
485 | */ | ||
486 | if (dev->pci_device == 0x0179 || dev->pci_device == 0x0189 || | ||
487 | dev->pci_device == 0x0329) { | ||
488 | if (mode == DRM_MODE_DPMS_ON) { | ||
489 | nv_mask(dev, NV_PBUS_DEBUG_DUALHEAD_CTL, 0, 1 << 31); | ||
490 | nv_mask(dev, NV_PCRTC_GPIO_EXT, 3, 1); | ||
491 | } else { | ||
492 | nv_mask(dev, NV_PBUS_DEBUG_DUALHEAD_CTL, 1 << 31, 0); | ||
493 | nv_mask(dev, NV_PCRTC_GPIO_EXT, 3, 0); | ||
494 | } | ||
495 | } | ||
496 | #endif | ||
497 | } | ||
498 | |||
476 | static inline bool is_powersaving_dpms(int mode) | 499 | static inline bool is_powersaving_dpms(int mode) |
477 | { | 500 | { |
478 | return (mode != DRM_MODE_DPMS_ON); | 501 | return (mode != DRM_MODE_DPMS_ON); |
@@ -520,6 +543,7 @@ static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode) | |||
520 | LVDS_PANEL_OFF, 0); | 543 | LVDS_PANEL_OFF, 0); |
521 | } | 544 | } |
522 | 545 | ||
546 | nv04_dfp_update_backlight(encoder, mode); | ||
523 | nv04_dfp_update_fp_control(encoder, mode); | 547 | nv04_dfp_update_fp_control(encoder, mode); |
524 | 548 | ||
525 | if (mode == DRM_MODE_DPMS_ON) | 549 | if (mode == DRM_MODE_DPMS_ON) |
@@ -543,6 +567,7 @@ static void nv04_tmds_dpms(struct drm_encoder *encoder, int mode) | |||
543 | NV_INFO(dev, "Setting dpms mode %d on tmds encoder (output %d)\n", | 567 | NV_INFO(dev, "Setting dpms mode %d on tmds encoder (output %d)\n", |
544 | mode, nv_encoder->dcb->index); | 568 | mode, nv_encoder->dcb->index); |
545 | 569 | ||
570 | nv04_dfp_update_backlight(encoder, mode); | ||
546 | nv04_dfp_update_fp_control(encoder, mode); | 571 | nv04_dfp_update_fp_control(encoder, mode); |
547 | } | 572 | } |
548 | 573 | ||
diff --git a/drivers/gpu/drm/nouveau/nv17_tv.c b/drivers/gpu/drm/nouveau/nv17_tv.c index 44fefb0c708..13cdc05b7c2 100644 --- a/drivers/gpu/drm/nouveau/nv17_tv.c +++ b/drivers/gpu/drm/nouveau/nv17_tv.c | |||
@@ -121,10 +121,14 @@ static bool | |||
121 | get_tv_detect_quirks(struct drm_device *dev, uint32_t *pin_mask) | 121 | get_tv_detect_quirks(struct drm_device *dev, uint32_t *pin_mask) |
122 | { | 122 | { |
123 | /* Zotac FX5200 */ | 123 | /* Zotac FX5200 */ |
124 | if (dev->pdev->device == 0x0322 && | 124 | if (nv_match_device(dev, 0x0322, 0x19da, 0x1035) || |
125 | dev->pdev->subsystem_vendor == 0x19da && | 125 | nv_match_device(dev, 0x0322, 0x19da, 0x2035)) { |
126 | (dev->pdev->subsystem_device == 0x1035 || | 126 | *pin_mask = 0xc; |
127 | dev->pdev->subsystem_device == 0x2035)) { | 127 | return false; |
128 | } | ||
129 | |||
130 | /* MSI nForce2 IGP */ | ||
131 | if (nv_match_device(dev, 0x01f0, 0x1462, 0x5710)) { | ||
128 | *pin_mask = 0xc; | 132 | *pin_mask = 0xc; |
129 | return false; | 133 | return false; |
130 | } | 134 | } |
diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index 37c7b48ab24..91ef93cf1f3 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c | |||
@@ -139,6 +139,8 @@ nv50_instmem_init(struct drm_device *dev) | |||
139 | chan->file_priv = (struct drm_file *)-2; | 139 | chan->file_priv = (struct drm_file *)-2; |
140 | dev_priv->fifos[0] = dev_priv->fifos[127] = chan; | 140 | dev_priv->fifos[0] = dev_priv->fifos[127] = chan; |
141 | 141 | ||
142 | INIT_LIST_HEAD(&chan->ramht_refs); | ||
143 | |||
142 | /* Channel's PRAMIN object + heap */ | 144 | /* Channel's PRAMIN object + heap */ |
143 | ret = nouveau_gpuobj_new_fake(dev, 0, c_offset, c_size, 0, | 145 | ret = nouveau_gpuobj_new_fake(dev, 0, c_offset, c_size, 0, |
144 | NULL, &chan->ramin); | 146 | NULL, &chan->ramin); |
@@ -278,7 +280,7 @@ nv50_instmem_init(struct drm_device *dev) | |||
278 | /*XXX: incorrect, but needed to make hash func "work" */ | 280 | /*XXX: incorrect, but needed to make hash func "work" */ |
279 | dev_priv->ramht_offset = 0x10000; | 281 | dev_priv->ramht_offset = 0x10000; |
280 | dev_priv->ramht_bits = 9; | 282 | dev_priv->ramht_bits = 9; |
281 | dev_priv->ramht_size = (1 << dev_priv->ramht_bits); | 283 | dev_priv->ramht_size = (1 << dev_priv->ramht_bits) * 8; |
282 | return 0; | 284 | return 0; |
283 | } | 285 | } |
284 | 286 | ||
diff --git a/drivers/gpu/drm/nouveau/nvc0_instmem.c b/drivers/gpu/drm/nouveau/nvc0_instmem.c index 3ab3cdc4217..6b451f86478 100644 --- a/drivers/gpu/drm/nouveau/nvc0_instmem.c +++ b/drivers/gpu/drm/nouveau/nvc0_instmem.c | |||
@@ -142,14 +142,16 @@ int | |||
142 | nvc0_instmem_suspend(struct drm_device *dev) | 142 | nvc0_instmem_suspend(struct drm_device *dev) |
143 | { | 143 | { |
144 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 144 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
145 | u32 *buf; | ||
145 | int i; | 146 | int i; |
146 | 147 | ||
147 | dev_priv->susres.ramin_copy = vmalloc(65536); | 148 | dev_priv->susres.ramin_copy = vmalloc(65536); |
148 | if (!dev_priv->susres.ramin_copy) | 149 | if (!dev_priv->susres.ramin_copy) |
149 | return -ENOMEM; | 150 | return -ENOMEM; |
151 | buf = dev_priv->susres.ramin_copy; | ||
150 | 152 | ||
151 | for (i = 0x700000; i < 0x710000; i += 4) | 153 | for (i = 0; i < 65536; i += 4) |
152 | dev_priv->susres.ramin_copy[i/4] = nv_rd32(dev, i); | 154 | buf[i/4] = nv_rd32(dev, NV04_PRAMIN + i); |
153 | return 0; | 155 | return 0; |
154 | } | 156 | } |
155 | 157 | ||
@@ -157,14 +159,15 @@ void | |||
157 | nvc0_instmem_resume(struct drm_device *dev) | 159 | nvc0_instmem_resume(struct drm_device *dev) |
158 | { | 160 | { |
159 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 161 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
162 | u32 *buf = dev_priv->susres.ramin_copy; | ||
160 | u64 chan; | 163 | u64 chan; |
161 | int i; | 164 | int i; |
162 | 165 | ||
163 | chan = dev_priv->vram_size - dev_priv->ramin_rsvd_vram; | 166 | chan = dev_priv->vram_size - dev_priv->ramin_rsvd_vram; |
164 | nv_wr32(dev, 0x001700, chan >> 16); | 167 | nv_wr32(dev, 0x001700, chan >> 16); |
165 | 168 | ||
166 | for (i = 0x700000; i < 0x710000; i += 4) | 169 | for (i = 0; i < 65536; i += 4) |
167 | nv_wr32(dev, i, dev_priv->susres.ramin_copy[i/4]); | 170 | nv_wr32(dev, NV04_PRAMIN + i, buf[i/4]); |
168 | vfree(dev_priv->susres.ramin_copy); | 171 | vfree(dev_priv->susres.ramin_copy); |
169 | dev_priv->susres.ramin_copy = NULL; | 172 | dev_priv->susres.ramin_copy = NULL; |
170 | 173 | ||
@@ -221,7 +224,7 @@ nvc0_instmem_init(struct drm_device *dev) | |||
221 | /*XXX: incorrect, but needed to make hash func "work" */ | 224 | /*XXX: incorrect, but needed to make hash func "work" */ |
222 | dev_priv->ramht_offset = 0x10000; | 225 | dev_priv->ramht_offset = 0x10000; |
223 | dev_priv->ramht_bits = 9; | 226 | dev_priv->ramht_bits = 9; |
224 | dev_priv->ramht_size = (1 << dev_priv->ramht_bits); | 227 | dev_priv->ramht_size = (1 << dev_priv->ramht_bits) * 8; |
225 | return 0; | 228 | return 0; |
226 | } | 229 | } |
227 | 230 | ||
diff --git a/drivers/gpu/drm/r128/r128_state.c b/drivers/gpu/drm/r128/r128_state.c index 077af1f2f9b..a9e33ce6591 100644 --- a/drivers/gpu/drm/r128/r128_state.c +++ b/drivers/gpu/drm/r128/r128_state.c | |||
@@ -1639,30 +1639,29 @@ void r128_driver_preclose(struct drm_device *dev, struct drm_file *file_priv) | |||
1639 | r128_do_cleanup_pageflip(dev); | 1639 | r128_do_cleanup_pageflip(dev); |
1640 | } | 1640 | } |
1641 | } | 1641 | } |
1642 | |||
1643 | void r128_driver_lastclose(struct drm_device *dev) | 1642 | void r128_driver_lastclose(struct drm_device *dev) |
1644 | { | 1643 | { |
1645 | r128_do_cleanup_cce(dev); | 1644 | r128_do_cleanup_cce(dev); |
1646 | } | 1645 | } |
1647 | 1646 | ||
1648 | struct drm_ioctl_desc r128_ioctls[] = { | 1647 | struct drm_ioctl_desc r128_ioctls[] = { |
1649 | DRM_IOCTL_DEF(DRM_R128_INIT, r128_cce_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1648 | DRM_IOCTL_DEF_DRV(R128_INIT, r128_cce_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
1650 | DRM_IOCTL_DEF(DRM_R128_CCE_START, r128_cce_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1649 | DRM_IOCTL_DEF_DRV(R128_CCE_START, r128_cce_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
1651 | DRM_IOCTL_DEF(DRM_R128_CCE_STOP, r128_cce_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1650 | DRM_IOCTL_DEF_DRV(R128_CCE_STOP, r128_cce_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
1652 | DRM_IOCTL_DEF(DRM_R128_CCE_RESET, r128_cce_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1651 | DRM_IOCTL_DEF_DRV(R128_CCE_RESET, r128_cce_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
1653 | DRM_IOCTL_DEF(DRM_R128_CCE_IDLE, r128_cce_idle, DRM_AUTH), | 1652 | DRM_IOCTL_DEF_DRV(R128_CCE_IDLE, r128_cce_idle, DRM_AUTH), |
1654 | DRM_IOCTL_DEF(DRM_R128_RESET, r128_engine_reset, DRM_AUTH), | 1653 | DRM_IOCTL_DEF_DRV(R128_RESET, r128_engine_reset, DRM_AUTH), |
1655 | DRM_IOCTL_DEF(DRM_R128_FULLSCREEN, r128_fullscreen, DRM_AUTH), | 1654 | DRM_IOCTL_DEF_DRV(R128_FULLSCREEN, r128_fullscreen, DRM_AUTH), |
1656 | DRM_IOCTL_DEF(DRM_R128_SWAP, r128_cce_swap, DRM_AUTH), | 1655 | DRM_IOCTL_DEF_DRV(R128_SWAP, r128_cce_swap, DRM_AUTH), |
1657 | DRM_IOCTL_DEF(DRM_R128_FLIP, r128_cce_flip, DRM_AUTH), | 1656 | DRM_IOCTL_DEF_DRV(R128_FLIP, r128_cce_flip, DRM_AUTH), |
1658 | DRM_IOCTL_DEF(DRM_R128_CLEAR, r128_cce_clear, DRM_AUTH), | 1657 | DRM_IOCTL_DEF_DRV(R128_CLEAR, r128_cce_clear, DRM_AUTH), |
1659 | DRM_IOCTL_DEF(DRM_R128_VERTEX, r128_cce_vertex, DRM_AUTH), | 1658 | DRM_IOCTL_DEF_DRV(R128_VERTEX, r128_cce_vertex, DRM_AUTH), |
1660 | DRM_IOCTL_DEF(DRM_R128_INDICES, r128_cce_indices, DRM_AUTH), | 1659 | DRM_IOCTL_DEF_DRV(R128_INDICES, r128_cce_indices, DRM_AUTH), |
1661 | DRM_IOCTL_DEF(DRM_R128_BLIT, r128_cce_blit, DRM_AUTH), | 1660 | DRM_IOCTL_DEF_DRV(R128_BLIT, r128_cce_blit, DRM_AUTH), |
1662 | DRM_IOCTL_DEF(DRM_R128_DEPTH, r128_cce_depth, DRM_AUTH), | 1661 | DRM_IOCTL_DEF_DRV(R128_DEPTH, r128_cce_depth, DRM_AUTH), |
1663 | DRM_IOCTL_DEF(DRM_R128_STIPPLE, r128_cce_stipple, DRM_AUTH), | 1662 | DRM_IOCTL_DEF_DRV(R128_STIPPLE, r128_cce_stipple, DRM_AUTH), |
1664 | DRM_IOCTL_DEF(DRM_R128_INDIRECT, r128_cce_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1663 | DRM_IOCTL_DEF_DRV(R128_INDIRECT, r128_cce_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
1665 | DRM_IOCTL_DEF(DRM_R128_GETPARAM, r128_getparam, DRM_AUTH), | 1664 | DRM_IOCTL_DEF_DRV(R128_GETPARAM, r128_getparam, DRM_AUTH), |
1666 | }; | 1665 | }; |
1667 | 1666 | ||
1668 | int r128_max_ioctl = DRM_ARRAY_SIZE(r128_ioctls); | 1667 | int r128_max_ioctl = DRM_ARRAY_SIZE(r128_ioctls); |
diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h index 1bc72c3190a..fe359a239df 100644 --- a/drivers/gpu/drm/radeon/atombios.h +++ b/drivers/gpu/drm/radeon/atombios.h | |||
@@ -4999,7 +4999,7 @@ typedef struct _SW_I2C_IO_DATA_PARAMETERS | |||
4999 | #define SW_I2C_CNTL_WRITE1BIT 6 | 4999 | #define SW_I2C_CNTL_WRITE1BIT 6 |
5000 | 5000 | ||
5001 | //==============================VESA definition Portion=============================== | 5001 | //==============================VESA definition Portion=============================== |
5002 | #define VESA_OEM_PRODUCT_REV '01.00' | 5002 | #define VESA_OEM_PRODUCT_REV "01.00" |
5003 | #define VESA_MODE_ATTRIBUTE_MODE_SUPPORT 0xBB //refer to VBE spec p.32, no TTY support | 5003 | #define VESA_MODE_ATTRIBUTE_MODE_SUPPORT 0xBB //refer to VBE spec p.32, no TTY support |
5004 | #define VESA_MODE_WIN_ATTRIBUTE 7 | 5004 | #define VESA_MODE_WIN_ATTRIBUTE 7 |
5005 | #define VESA_WIN_SIZE 64 | 5005 | #define VESA_WIN_SIZE 64 |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 12ad512bd3d..cd0290f946c 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -332,6 +332,11 @@ static void atombios_crtc_set_timing(struct drm_crtc *crtc, | |||
332 | args.usV_SyncWidth = | 332 | args.usV_SyncWidth = |
333 | cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start); | 333 | cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start); |
334 | 334 | ||
335 | args.ucOverscanRight = radeon_crtc->h_border; | ||
336 | args.ucOverscanLeft = radeon_crtc->h_border; | ||
337 | args.ucOverscanBottom = radeon_crtc->v_border; | ||
338 | args.ucOverscanTop = radeon_crtc->v_border; | ||
339 | |||
335 | if (mode->flags & DRM_MODE_FLAG_NVSYNC) | 340 | if (mode->flags & DRM_MODE_FLAG_NVSYNC) |
336 | misc |= ATOM_VSYNC_POLARITY; | 341 | misc |= ATOM_VSYNC_POLARITY; |
337 | if (mode->flags & DRM_MODE_FLAG_NHSYNC) | 342 | if (mode->flags & DRM_MODE_FLAG_NHSYNC) |
@@ -471,6 +476,8 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
471 | struct radeon_encoder *radeon_encoder = NULL; | 476 | struct radeon_encoder *radeon_encoder = NULL; |
472 | u32 adjusted_clock = mode->clock; | 477 | u32 adjusted_clock = mode->clock; |
473 | int encoder_mode = 0; | 478 | int encoder_mode = 0; |
479 | u32 dp_clock = mode->clock; | ||
480 | int bpc = 8; | ||
474 | 481 | ||
475 | /* reset the pll flags */ | 482 | /* reset the pll flags */ |
476 | pll->flags = 0; | 483 | pll->flags = 0; |
@@ -513,6 +520,17 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
513 | if (encoder->crtc == crtc) { | 520 | if (encoder->crtc == crtc) { |
514 | radeon_encoder = to_radeon_encoder(encoder); | 521 | radeon_encoder = to_radeon_encoder(encoder); |
515 | encoder_mode = atombios_get_encoder_mode(encoder); | 522 | encoder_mode = atombios_get_encoder_mode(encoder); |
523 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) { | ||
524 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
525 | if (connector) { | ||
526 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
527 | struct radeon_connector_atom_dig *dig_connector = | ||
528 | radeon_connector->con_priv; | ||
529 | |||
530 | dp_clock = dig_connector->dp_clock; | ||
531 | } | ||
532 | } | ||
533 | |||
516 | if (ASIC_IS_AVIVO(rdev)) { | 534 | if (ASIC_IS_AVIVO(rdev)) { |
517 | /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ | 535 | /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ |
518 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) | 536 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) |
@@ -521,6 +539,21 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
521 | pll->algo = PLL_ALGO_LEGACY; | 539 | pll->algo = PLL_ALGO_LEGACY; |
522 | pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER; | 540 | pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER; |
523 | } | 541 | } |
542 | /* There is some evidence (often anecdotal) that RV515/RV620 LVDS | ||
543 | * (on some boards at least) prefers the legacy algo. I'm not | ||
544 | * sure whether this should handled generically or on a | ||
545 | * case-by-case quirk basis. Both algos should work fine in the | ||
546 | * majority of cases. | ||
547 | */ | ||
548 | if ((radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) && | ||
549 | ((rdev->family == CHIP_RV515) || | ||
550 | (rdev->family == CHIP_RV620))) { | ||
551 | /* allow the user to overrride just in case */ | ||
552 | if (radeon_new_pll == 1) | ||
553 | pll->algo = PLL_ALGO_NEW; | ||
554 | else | ||
555 | pll->algo = PLL_ALGO_LEGACY; | ||
556 | } | ||
524 | } else { | 557 | } else { |
525 | if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) | 558 | if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) |
526 | pll->flags |= RADEON_PLL_NO_ODD_POST_DIV; | 559 | pll->flags |= RADEON_PLL_NO_ODD_POST_DIV; |
@@ -555,6 +588,14 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
555 | args.v1.usPixelClock = cpu_to_le16(mode->clock / 10); | 588 | args.v1.usPixelClock = cpu_to_le16(mode->clock / 10); |
556 | args.v1.ucTransmitterID = radeon_encoder->encoder_id; | 589 | args.v1.ucTransmitterID = radeon_encoder->encoder_id; |
557 | args.v1.ucEncodeMode = encoder_mode; | 590 | args.v1.ucEncodeMode = encoder_mode; |
591 | if (encoder_mode == ATOM_ENCODER_MODE_DP) { | ||
592 | /* may want to enable SS on DP eventually */ | ||
593 | /* args.v1.ucConfig |= | ||
594 | ADJUST_DISPLAY_CONFIG_SS_ENABLE;*/ | ||
595 | } else if (encoder_mode == ATOM_ENCODER_MODE_LVDS) { | ||
596 | args.v1.ucConfig |= | ||
597 | ADJUST_DISPLAY_CONFIG_SS_ENABLE; | ||
598 | } | ||
558 | 599 | ||
559 | atom_execute_table(rdev->mode_info.atom_context, | 600 | atom_execute_table(rdev->mode_info.atom_context, |
560 | index, (uint32_t *)&args); | 601 | index, (uint32_t *)&args); |
@@ -568,10 +609,20 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
568 | if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | 609 | if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { |
569 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 610 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
570 | 611 | ||
571 | if (encoder_mode == ATOM_ENCODER_MODE_DP) | 612 | if (encoder_mode == ATOM_ENCODER_MODE_DP) { |
613 | /* may want to enable SS on DP/eDP eventually */ | ||
614 | /*args.v3.sInput.ucDispPllConfig |= | ||
615 | DISPPLL_CONFIG_SS_ENABLE;*/ | ||
572 | args.v3.sInput.ucDispPllConfig |= | 616 | args.v3.sInput.ucDispPllConfig |= |
573 | DISPPLL_CONFIG_COHERENT_MODE; | 617 | DISPPLL_CONFIG_COHERENT_MODE; |
574 | else { | 618 | /* 16200 or 27000 */ |
619 | args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10); | ||
620 | } else { | ||
621 | if (encoder_mode == ATOM_ENCODER_MODE_HDMI) { | ||
622 | /* deep color support */ | ||
623 | args.v3.sInput.usPixelClock = | ||
624 | cpu_to_le16((mode->clock * bpc / 8) / 10); | ||
625 | } | ||
575 | if (dig->coherent_mode) | 626 | if (dig->coherent_mode) |
576 | args.v3.sInput.ucDispPllConfig |= | 627 | args.v3.sInput.ucDispPllConfig |= |
577 | DISPPLL_CONFIG_COHERENT_MODE; | 628 | DISPPLL_CONFIG_COHERENT_MODE; |
@@ -580,13 +631,19 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
580 | DISPPLL_CONFIG_DUAL_LINK; | 631 | DISPPLL_CONFIG_DUAL_LINK; |
581 | } | 632 | } |
582 | } else if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | 633 | } else if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { |
583 | /* may want to enable SS on DP/eDP eventually */ | 634 | if (encoder_mode == ATOM_ENCODER_MODE_DP) { |
584 | /*args.v3.sInput.ucDispPllConfig |= | 635 | /* may want to enable SS on DP/eDP eventually */ |
585 | DISPPLL_CONFIG_SS_ENABLE;*/ | 636 | /*args.v3.sInput.ucDispPllConfig |= |
586 | if (encoder_mode == ATOM_ENCODER_MODE_DP) | 637 | DISPPLL_CONFIG_SS_ENABLE;*/ |
587 | args.v3.sInput.ucDispPllConfig |= | 638 | args.v3.sInput.ucDispPllConfig |= |
588 | DISPPLL_CONFIG_COHERENT_MODE; | 639 | DISPPLL_CONFIG_COHERENT_MODE; |
589 | else { | 640 | /* 16200 or 27000 */ |
641 | args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10); | ||
642 | } else if (encoder_mode == ATOM_ENCODER_MODE_LVDS) { | ||
643 | /* want to enable SS on LVDS eventually */ | ||
644 | /*args.v3.sInput.ucDispPllConfig |= | ||
645 | DISPPLL_CONFIG_SS_ENABLE;*/ | ||
646 | } else { | ||
590 | if (mode->clock > 165000) | 647 | if (mode->clock > 165000) |
591 | args.v3.sInput.ucDispPllConfig |= | 648 | args.v3.sInput.ucDispPllConfig |= |
592 | DISPPLL_CONFIG_DUAL_LINK; | 649 | DISPPLL_CONFIG_DUAL_LINK; |
@@ -1019,11 +1076,11 @@ static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
1019 | 1076 | ||
1020 | if (rdev->family >= CHIP_RV770) { | 1077 | if (rdev->family >= CHIP_RV770) { |
1021 | if (radeon_crtc->crtc_id) { | 1078 | if (radeon_crtc->crtc_id) { |
1022 | WREG32(R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 0); | 1079 | WREG32(R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location)); |
1023 | WREG32(R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 0); | 1080 | WREG32(R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location)); |
1024 | } else { | 1081 | } else { |
1025 | WREG32(R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 0); | 1082 | WREG32(R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location)); |
1026 | WREG32(R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 0); | 1083 | WREG32(R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(fb_location)); |
1027 | } | 1084 | } |
1028 | } | 1085 | } |
1029 | WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, | 1086 | WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, |
@@ -1160,8 +1217,18 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc, | |||
1160 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 1217 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
1161 | struct drm_device *dev = crtc->dev; | 1218 | struct drm_device *dev = crtc->dev; |
1162 | struct radeon_device *rdev = dev->dev_private; | 1219 | struct radeon_device *rdev = dev->dev_private; |
1220 | struct drm_encoder *encoder; | ||
1221 | bool is_tvcv = false; | ||
1163 | 1222 | ||
1164 | /* TODO color tiling */ | 1223 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
1224 | /* find tv std */ | ||
1225 | if (encoder->crtc == crtc) { | ||
1226 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
1227 | if (radeon_encoder->active_device & | ||
1228 | (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) | ||
1229 | is_tvcv = true; | ||
1230 | } | ||
1231 | } | ||
1165 | 1232 | ||
1166 | atombios_disable_ss(crtc); | 1233 | atombios_disable_ss(crtc); |
1167 | /* always set DCPLL */ | 1234 | /* always set DCPLL */ |
@@ -1170,9 +1237,14 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc, | |||
1170 | atombios_crtc_set_pll(crtc, adjusted_mode); | 1237 | atombios_crtc_set_pll(crtc, adjusted_mode); |
1171 | atombios_enable_ss(crtc); | 1238 | atombios_enable_ss(crtc); |
1172 | 1239 | ||
1173 | if (ASIC_IS_AVIVO(rdev)) | 1240 | if (ASIC_IS_DCE4(rdev)) |
1174 | atombios_set_crtc_dtd_timing(crtc, adjusted_mode); | 1241 | atombios_set_crtc_dtd_timing(crtc, adjusted_mode); |
1175 | else { | 1242 | else if (ASIC_IS_AVIVO(rdev)) { |
1243 | if (is_tvcv) | ||
1244 | atombios_crtc_set_timing(crtc, adjusted_mode); | ||
1245 | else | ||
1246 | atombios_set_crtc_dtd_timing(crtc, adjusted_mode); | ||
1247 | } else { | ||
1176 | atombios_crtc_set_timing(crtc, adjusted_mode); | 1248 | atombios_crtc_set_timing(crtc, adjusted_mode); |
1177 | if (radeon_crtc->crtc_id == 0) | 1249 | if (radeon_crtc->crtc_id == 0) |
1178 | atombios_set_crtc_dtd_timing(crtc, adjusted_mode); | 1250 | atombios_set_crtc_dtd_timing(crtc, adjusted_mode); |
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 36e0d4b545e..4e7778d44b8 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c | |||
@@ -610,7 +610,7 @@ void dp_link_train(struct drm_encoder *encoder, | |||
610 | enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER; | 610 | enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER; |
611 | else | 611 | else |
612 | enc_id |= ATOM_DP_CONFIG_DIG1_ENCODER; | 612 | enc_id |= ATOM_DP_CONFIG_DIG1_ENCODER; |
613 | if (dig_connector->linkb) | 613 | if (dig->linkb) |
614 | enc_id |= ATOM_DP_CONFIG_LINK_B; | 614 | enc_id |= ATOM_DP_CONFIG_LINK_B; |
615 | else | 615 | else |
616 | enc_id |= ATOM_DP_CONFIG_LINK_A; | 616 | enc_id |= ATOM_DP_CONFIG_LINK_A; |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 957d5067ad9..2f93d46ae69 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -675,6 +675,43 @@ static int evergreen_cp_load_microcode(struct radeon_device *rdev) | |||
675 | return 0; | 675 | return 0; |
676 | } | 676 | } |
677 | 677 | ||
678 | static int evergreen_cp_start(struct radeon_device *rdev) | ||
679 | { | ||
680 | int r; | ||
681 | uint32_t cp_me; | ||
682 | |||
683 | r = radeon_ring_lock(rdev, 7); | ||
684 | if (r) { | ||
685 | DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); | ||
686 | return r; | ||
687 | } | ||
688 | radeon_ring_write(rdev, PACKET3(PACKET3_ME_INITIALIZE, 5)); | ||
689 | radeon_ring_write(rdev, 0x1); | ||
690 | radeon_ring_write(rdev, 0x0); | ||
691 | radeon_ring_write(rdev, rdev->config.evergreen.max_hw_contexts - 1); | ||
692 | radeon_ring_write(rdev, PACKET3_ME_INITIALIZE_DEVICE_ID(1)); | ||
693 | radeon_ring_write(rdev, 0); | ||
694 | radeon_ring_write(rdev, 0); | ||
695 | radeon_ring_unlock_commit(rdev); | ||
696 | |||
697 | cp_me = 0xff; | ||
698 | WREG32(CP_ME_CNTL, cp_me); | ||
699 | |||
700 | r = radeon_ring_lock(rdev, 4); | ||
701 | if (r) { | ||
702 | DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); | ||
703 | return r; | ||
704 | } | ||
705 | /* init some VGT regs */ | ||
706 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); | ||
707 | radeon_ring_write(rdev, (VGT_VERTEX_REUSE_BLOCK_CNTL - PACKET3_SET_CONTEXT_REG_START) >> 2); | ||
708 | radeon_ring_write(rdev, 0xe); | ||
709 | radeon_ring_write(rdev, 0x10); | ||
710 | radeon_ring_unlock_commit(rdev); | ||
711 | |||
712 | return 0; | ||
713 | } | ||
714 | |||
678 | int evergreen_cp_resume(struct radeon_device *rdev) | 715 | int evergreen_cp_resume(struct radeon_device *rdev) |
679 | { | 716 | { |
680 | u32 tmp; | 717 | u32 tmp; |
@@ -719,7 +756,7 @@ int evergreen_cp_resume(struct radeon_device *rdev) | |||
719 | rdev->cp.rptr = RREG32(CP_RB_RPTR); | 756 | rdev->cp.rptr = RREG32(CP_RB_RPTR); |
720 | rdev->cp.wptr = RREG32(CP_RB_WPTR); | 757 | rdev->cp.wptr = RREG32(CP_RB_WPTR); |
721 | 758 | ||
722 | r600_cp_start(rdev); | 759 | evergreen_cp_start(rdev); |
723 | rdev->cp.ready = true; | 760 | rdev->cp.ready = true; |
724 | r = radeon_ring_test(rdev); | 761 | r = radeon_ring_test(rdev); |
725 | if (r) { | 762 | if (r) { |
@@ -1100,7 +1137,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
1100 | 1137 | ||
1101 | WREG32(RCU_IND_INDEX, 0x203); | 1138 | WREG32(RCU_IND_INDEX, 0x203); |
1102 | efuse_straps_3 = RREG32(RCU_IND_DATA); | 1139 | efuse_straps_3 = RREG32(RCU_IND_DATA); |
1103 | efuse_box_bit_127_124 = (u8)(efuse_straps_3 & 0xF0000000) >> 28; | 1140 | efuse_box_bit_127_124 = (u8)((efuse_straps_3 & 0xF0000000) >> 28); |
1104 | 1141 | ||
1105 | switch(efuse_box_bit_127_124) { | 1142 | switch(efuse_box_bit_127_124) { |
1106 | case 0x0: | 1143 | case 0x0: |
@@ -1123,14 +1160,25 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
1123 | EVERGREEN_MAX_BACKENDS_MASK)); | 1160 | EVERGREEN_MAX_BACKENDS_MASK)); |
1124 | break; | 1161 | break; |
1125 | } | 1162 | } |
1126 | } else | 1163 | } else { |
1127 | gb_backend_map = | 1164 | switch (rdev->family) { |
1128 | evergreen_get_tile_pipe_to_backend_map(rdev, | 1165 | case CHIP_CYPRESS: |
1129 | rdev->config.evergreen.max_tile_pipes, | 1166 | case CHIP_HEMLOCK: |
1130 | rdev->config.evergreen.max_backends, | 1167 | gb_backend_map = 0x66442200; |
1131 | ((EVERGREEN_MAX_BACKENDS_MASK << | 1168 | break; |
1132 | rdev->config.evergreen.max_backends) & | 1169 | case CHIP_JUNIPER: |
1133 | EVERGREEN_MAX_BACKENDS_MASK)); | 1170 | gb_backend_map = 0x00006420; |
1171 | break; | ||
1172 | default: | ||
1173 | gb_backend_map = | ||
1174 | evergreen_get_tile_pipe_to_backend_map(rdev, | ||
1175 | rdev->config.evergreen.max_tile_pipes, | ||
1176 | rdev->config.evergreen.max_backends, | ||
1177 | ((EVERGREEN_MAX_BACKENDS_MASK << | ||
1178 | rdev->config.evergreen.max_backends) & | ||
1179 | EVERGREEN_MAX_BACKENDS_MASK)); | ||
1180 | } | ||
1181 | } | ||
1134 | 1182 | ||
1135 | rdev->config.evergreen.tile_config = gb_addr_config; | 1183 | rdev->config.evergreen.tile_config = gb_addr_config; |
1136 | WREG32(GB_BACKEND_MAP, gb_backend_map); | 1184 | WREG32(GB_BACKEND_MAP, gb_backend_map); |
@@ -1359,6 +1407,7 @@ int evergreen_mc_init(struct radeon_device *rdev) | |||
1359 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; | 1407 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; |
1360 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; | 1408 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; |
1361 | rdev->mc.visible_vram_size = rdev->mc.aper_size; | 1409 | rdev->mc.visible_vram_size = rdev->mc.aper_size; |
1410 | rdev->mc.active_vram_size = rdev->mc.visible_vram_size; | ||
1362 | r600_vram_gtt_location(rdev, &rdev->mc); | 1411 | r600_vram_gtt_location(rdev, &rdev->mc); |
1363 | radeon_update_bandwidth_info(rdev); | 1412 | radeon_update_bandwidth_info(rdev); |
1364 | 1413 | ||
@@ -1472,7 +1521,7 @@ void evergreen_disable_interrupt_state(struct radeon_device *rdev) | |||
1472 | { | 1521 | { |
1473 | u32 tmp; | 1522 | u32 tmp; |
1474 | 1523 | ||
1475 | WREG32(CP_INT_CNTL, 0); | 1524 | WREG32(CP_INT_CNTL, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); |
1476 | WREG32(GRBM_INT_CNTL, 0); | 1525 | WREG32(GRBM_INT_CNTL, 0); |
1477 | WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); | 1526 | WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); |
1478 | WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); | 1527 | WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); |
@@ -2054,11 +2103,6 @@ int evergreen_resume(struct radeon_device *rdev) | |||
2054 | */ | 2103 | */ |
2055 | /* post card */ | 2104 | /* post card */ |
2056 | atom_asic_init(rdev->mode_info.atom_context); | 2105 | atom_asic_init(rdev->mode_info.atom_context); |
2057 | /* Initialize clocks */ | ||
2058 | r = radeon_clocks_init(rdev); | ||
2059 | if (r) { | ||
2060 | return r; | ||
2061 | } | ||
2062 | 2106 | ||
2063 | r = evergreen_startup(rdev); | 2107 | r = evergreen_startup(rdev); |
2064 | if (r) { | 2108 | if (r) { |
@@ -2164,9 +2208,6 @@ int evergreen_init(struct radeon_device *rdev) | |||
2164 | radeon_surface_init(rdev); | 2208 | radeon_surface_init(rdev); |
2165 | /* Initialize clocks */ | 2209 | /* Initialize clocks */ |
2166 | radeon_get_clock_info(rdev->ddev); | 2210 | radeon_get_clock_info(rdev->ddev); |
2167 | r = radeon_clocks_init(rdev); | ||
2168 | if (r) | ||
2169 | return r; | ||
2170 | /* Fence driver */ | 2211 | /* Fence driver */ |
2171 | r = radeon_fence_driver_init(rdev); | 2212 | r = radeon_fence_driver_init(rdev); |
2172 | if (r) | 2213 | if (r) |
@@ -2236,7 +2277,6 @@ void evergreen_fini(struct radeon_device *rdev) | |||
2236 | evergreen_pcie_gart_fini(rdev); | 2277 | evergreen_pcie_gart_fini(rdev); |
2237 | radeon_gem_fini(rdev); | 2278 | radeon_gem_fini(rdev); |
2238 | radeon_fence_driver_fini(rdev); | 2279 | radeon_fence_driver_fini(rdev); |
2239 | radeon_clocks_fini(rdev); | ||
2240 | radeon_agp_fini(rdev); | 2280 | radeon_agp_fini(rdev); |
2241 | radeon_bo_fini(rdev); | 2281 | radeon_bo_fini(rdev); |
2242 | radeon_atombios_fini(rdev); | 2282 | radeon_atombios_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index e817a0bb5eb..e59422320bb 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -1030,6 +1030,7 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) | |||
1030 | return r; | 1030 | return r; |
1031 | } | 1031 | } |
1032 | rdev->cp.ready = true; | 1032 | rdev->cp.ready = true; |
1033 | rdev->mc.active_vram_size = rdev->mc.real_vram_size; | ||
1033 | return 0; | 1034 | return 0; |
1034 | } | 1035 | } |
1035 | 1036 | ||
@@ -1047,6 +1048,7 @@ void r100_cp_fini(struct radeon_device *rdev) | |||
1047 | void r100_cp_disable(struct radeon_device *rdev) | 1048 | void r100_cp_disable(struct radeon_device *rdev) |
1048 | { | 1049 | { |
1049 | /* Disable ring */ | 1050 | /* Disable ring */ |
1051 | rdev->mc.active_vram_size = rdev->mc.visible_vram_size; | ||
1050 | rdev->cp.ready = false; | 1052 | rdev->cp.ready = false; |
1051 | WREG32(RADEON_CP_CSQ_MODE, 0); | 1053 | WREG32(RADEON_CP_CSQ_MODE, 0); |
1052 | WREG32(RADEON_CP_CSQ_CNTL, 0); | 1054 | WREG32(RADEON_CP_CSQ_CNTL, 0); |
@@ -2020,18 +2022,7 @@ bool r100_gpu_cp_is_lockup(struct radeon_device *rdev, struct r100_gpu_lockup *l | |||
2020 | return false; | 2022 | return false; |
2021 | } | 2023 | } |
2022 | elapsed = jiffies_to_msecs(cjiffies - lockup->last_jiffies); | 2024 | elapsed = jiffies_to_msecs(cjiffies - lockup->last_jiffies); |
2023 | if (elapsed >= 3000) { | 2025 | if (elapsed >= 10000) { |
2024 | /* very likely the improbable case where current | ||
2025 | * rptr is equal to last recorded, a while ago, rptr | ||
2026 | * this is more likely a false positive update tracking | ||
2027 | * information which should force us to be recall at | ||
2028 | * latter point | ||
2029 | */ | ||
2030 | lockup->last_cp_rptr = cp->rptr; | ||
2031 | lockup->last_jiffies = jiffies; | ||
2032 | return false; | ||
2033 | } | ||
2034 | if (elapsed >= 1000) { | ||
2035 | dev_err(rdev->dev, "GPU lockup CP stall for more than %lumsec\n", elapsed); | 2026 | dev_err(rdev->dev, "GPU lockup CP stall for more than %lumsec\n", elapsed); |
2036 | return true; | 2027 | return true; |
2037 | } | 2028 | } |
@@ -2306,6 +2297,7 @@ void r100_vram_init_sizes(struct radeon_device *rdev) | |||
2306 | /* FIXME we don't use the second aperture yet when we could use it */ | 2297 | /* FIXME we don't use the second aperture yet when we could use it */ |
2307 | if (rdev->mc.visible_vram_size > rdev->mc.aper_size) | 2298 | if (rdev->mc.visible_vram_size > rdev->mc.aper_size) |
2308 | rdev->mc.visible_vram_size = rdev->mc.aper_size; | 2299 | rdev->mc.visible_vram_size = rdev->mc.aper_size; |
2300 | rdev->mc.active_vram_size = rdev->mc.visible_vram_size; | ||
2309 | config_aper_size = RREG32(RADEON_CONFIG_APER_SIZE); | 2301 | config_aper_size = RREG32(RADEON_CONFIG_APER_SIZE); |
2310 | if (rdev->flags & RADEON_IS_IGP) { | 2302 | if (rdev->flags & RADEON_IS_IGP) { |
2311 | uint32_t tom; | 2303 | uint32_t tom; |
@@ -3308,13 +3300,14 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) | |||
3308 | unsigned long size; | 3300 | unsigned long size; |
3309 | unsigned prim_walk; | 3301 | unsigned prim_walk; |
3310 | unsigned nverts; | 3302 | unsigned nverts; |
3303 | unsigned num_cb = track->num_cb; | ||
3311 | 3304 | ||
3312 | for (i = 0; i < track->num_cb; i++) { | 3305 | if (!track->zb_cb_clear && !track->color_channel_mask && |
3306 | !track->blend_read_enable) | ||
3307 | num_cb = 0; | ||
3308 | |||
3309 | for (i = 0; i < num_cb; i++) { | ||
3313 | if (track->cb[i].robj == NULL) { | 3310 | if (track->cb[i].robj == NULL) { |
3314 | if (!(track->zb_cb_clear || track->color_channel_mask || | ||
3315 | track->blend_read_enable)) { | ||
3316 | continue; | ||
3317 | } | ||
3318 | DRM_ERROR("[drm] No buffer for color buffer %d !\n", i); | 3311 | DRM_ERROR("[drm] No buffer for color buffer %d !\n", i); |
3319 | return -EINVAL; | 3312 | return -EINVAL; |
3320 | } | 3313 | } |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index d0ebae9dde2..7b65e4efe8a 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -1248,6 +1248,7 @@ int r600_mc_init(struct radeon_device *rdev) | |||
1248 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); | 1248 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); |
1249 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); | 1249 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); |
1250 | rdev->mc.visible_vram_size = rdev->mc.aper_size; | 1250 | rdev->mc.visible_vram_size = rdev->mc.aper_size; |
1251 | rdev->mc.active_vram_size = rdev->mc.visible_vram_size; | ||
1251 | r600_vram_gtt_location(rdev, &rdev->mc); | 1252 | r600_vram_gtt_location(rdev, &rdev->mc); |
1252 | 1253 | ||
1253 | if (rdev->flags & RADEON_IS_IGP) { | 1254 | if (rdev->flags & RADEON_IS_IGP) { |
@@ -1917,6 +1918,7 @@ void r600_pciep_wreg(struct radeon_device *rdev, u32 reg, u32 v) | |||
1917 | */ | 1918 | */ |
1918 | void r600_cp_stop(struct radeon_device *rdev) | 1919 | void r600_cp_stop(struct radeon_device *rdev) |
1919 | { | 1920 | { |
1921 | rdev->mc.active_vram_size = rdev->mc.visible_vram_size; | ||
1920 | WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1)); | 1922 | WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1)); |
1921 | } | 1923 | } |
1922 | 1924 | ||
@@ -2119,10 +2121,7 @@ int r600_cp_start(struct radeon_device *rdev) | |||
2119 | } | 2121 | } |
2120 | radeon_ring_write(rdev, PACKET3(PACKET3_ME_INITIALIZE, 5)); | 2122 | radeon_ring_write(rdev, PACKET3(PACKET3_ME_INITIALIZE, 5)); |
2121 | radeon_ring_write(rdev, 0x1); | 2123 | radeon_ring_write(rdev, 0x1); |
2122 | if (rdev->family >= CHIP_CEDAR) { | 2124 | if (rdev->family >= CHIP_RV770) { |
2123 | radeon_ring_write(rdev, 0x0); | ||
2124 | radeon_ring_write(rdev, rdev->config.evergreen.max_hw_contexts - 1); | ||
2125 | } else if (rdev->family >= CHIP_RV770) { | ||
2126 | radeon_ring_write(rdev, 0x0); | 2125 | radeon_ring_write(rdev, 0x0); |
2127 | radeon_ring_write(rdev, rdev->config.rv770.max_hw_contexts - 1); | 2126 | radeon_ring_write(rdev, rdev->config.rv770.max_hw_contexts - 1); |
2128 | } else { | 2127 | } else { |
@@ -2489,11 +2488,6 @@ int r600_resume(struct radeon_device *rdev) | |||
2489 | */ | 2488 | */ |
2490 | /* post card */ | 2489 | /* post card */ |
2491 | atom_asic_init(rdev->mode_info.atom_context); | 2490 | atom_asic_init(rdev->mode_info.atom_context); |
2492 | /* Initialize clocks */ | ||
2493 | r = radeon_clocks_init(rdev); | ||
2494 | if (r) { | ||
2495 | return r; | ||
2496 | } | ||
2497 | 2491 | ||
2498 | r = r600_startup(rdev); | 2492 | r = r600_startup(rdev); |
2499 | if (r) { | 2493 | if (r) { |
@@ -2586,9 +2580,6 @@ int r600_init(struct radeon_device *rdev) | |||
2586 | radeon_surface_init(rdev); | 2580 | radeon_surface_init(rdev); |
2587 | /* Initialize clocks */ | 2581 | /* Initialize clocks */ |
2588 | radeon_get_clock_info(rdev->ddev); | 2582 | radeon_get_clock_info(rdev->ddev); |
2589 | r = radeon_clocks_init(rdev); | ||
2590 | if (r) | ||
2591 | return r; | ||
2592 | /* Fence driver */ | 2583 | /* Fence driver */ |
2593 | r = radeon_fence_driver_init(rdev); | 2584 | r = radeon_fence_driver_init(rdev); |
2594 | if (r) | 2585 | if (r) |
@@ -2663,7 +2654,6 @@ void r600_fini(struct radeon_device *rdev) | |||
2663 | radeon_agp_fini(rdev); | 2654 | radeon_agp_fini(rdev); |
2664 | radeon_gem_fini(rdev); | 2655 | radeon_gem_fini(rdev); |
2665 | radeon_fence_driver_fini(rdev); | 2656 | radeon_fence_driver_fini(rdev); |
2666 | radeon_clocks_fini(rdev); | ||
2667 | radeon_bo_fini(rdev); | 2657 | radeon_bo_fini(rdev); |
2668 | radeon_atombios_fini(rdev); | 2658 | radeon_atombios_fini(rdev); |
2669 | kfree(rdev->bios); | 2659 | kfree(rdev->bios); |
@@ -2741,7 +2731,7 @@ int r600_ib_test(struct radeon_device *rdev) | |||
2741 | if (i < rdev->usec_timeout) { | 2731 | if (i < rdev->usec_timeout) { |
2742 | DRM_INFO("ib test succeeded in %u usecs\n", i); | 2732 | DRM_INFO("ib test succeeded in %u usecs\n", i); |
2743 | } else { | 2733 | } else { |
2744 | DRM_ERROR("radeon: ib test failed (sracth(0x%04X)=0x%08X)\n", | 2734 | DRM_ERROR("radeon: ib test failed (scratch(0x%04X)=0x%08X)\n", |
2745 | scratch, tmp); | 2735 | scratch, tmp); |
2746 | r = -EINVAL; | 2736 | r = -EINVAL; |
2747 | } | 2737 | } |
@@ -2922,7 +2912,7 @@ static void r600_disable_interrupt_state(struct radeon_device *rdev) | |||
2922 | { | 2912 | { |
2923 | u32 tmp; | 2913 | u32 tmp; |
2924 | 2914 | ||
2925 | WREG32(CP_INT_CNTL, 0); | 2915 | WREG32(CP_INT_CNTL, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); |
2926 | WREG32(GRBM_INT_CNTL, 0); | 2916 | WREG32(GRBM_INT_CNTL, 0); |
2927 | WREG32(DxMODE_INT_MASK, 0); | 2917 | WREG32(DxMODE_INT_MASK, 0); |
2928 | if (ASIC_IS_DCE3(rdev)) { | 2918 | if (ASIC_IS_DCE3(rdev)) { |
@@ -3540,8 +3530,9 @@ void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo) | |||
3540 | /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read | 3530 | /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read |
3541 | * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL | 3531 | * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL |
3542 | */ | 3532 | */ |
3543 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) { | 3533 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) && |
3544 | void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; | 3534 | rdev->vram_scratch.ptr) { |
3535 | void __iomem *ptr = (void *)rdev->vram_scratch.ptr; | ||
3545 | u32 tmp; | 3536 | u32 tmp; |
3546 | 3537 | ||
3547 | WREG32(HDP_DEBUG1, 0); | 3538 | WREG32(HDP_DEBUG1, 0); |
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c index d13622ae74e..3473c00781f 100644 --- a/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c | |||
@@ -1,3 +1,28 @@ | |||
1 | /* | ||
2 | * Copyright 2009 Advanced Micro Devices, Inc. | ||
3 | * Copyright 2009 Red Hat Inc. | ||
4 | * | ||
5 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
6 | * copy of this software and associated documentation files (the "Software"), | ||
7 | * to deal in the Software without restriction, including without limitation | ||
8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
9 | * and/or sell copies of the Software, and to permit persons to whom the | ||
10 | * Software is furnished to do so, subject to the following conditions: | ||
11 | * | ||
12 | * The above copyright notice and this permission notice (including the next | ||
13 | * paragraph) shall be included in all copies or substantial portions of the | ||
14 | * Software. | ||
15 | * | ||
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
19 | * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
20 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
21 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
22 | * DEALINGS IN THE SOFTWARE. | ||
23 | * | ||
24 | */ | ||
25 | |||
1 | #include "drmP.h" | 26 | #include "drmP.h" |
2 | #include "drm.h" | 27 | #include "drm.h" |
3 | #include "radeon_drm.h" | 28 | #include "radeon_drm.h" |
@@ -507,6 +532,7 @@ int r600_blit_init(struct radeon_device *rdev) | |||
507 | memcpy(ptr + rdev->r600_blit.ps_offset, r6xx_ps, r6xx_ps_size * 4); | 532 | memcpy(ptr + rdev->r600_blit.ps_offset, r6xx_ps, r6xx_ps_size * 4); |
508 | radeon_bo_kunmap(rdev->r600_blit.shader_obj); | 533 | radeon_bo_kunmap(rdev->r600_blit.shader_obj); |
509 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); | 534 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); |
535 | rdev->mc.active_vram_size = rdev->mc.real_vram_size; | ||
510 | return 0; | 536 | return 0; |
511 | } | 537 | } |
512 | 538 | ||
@@ -514,6 +540,7 @@ void r600_blit_fini(struct radeon_device *rdev) | |||
514 | { | 540 | { |
515 | int r; | 541 | int r; |
516 | 542 | ||
543 | rdev->mc.active_vram_size = rdev->mc.visible_vram_size; | ||
517 | if (rdev->r600_blit.shader_obj == NULL) | 544 | if (rdev->r600_blit.shader_obj == NULL) |
518 | return; | 545 | return; |
519 | /* If we can't reserve the bo, unref should be enough to destroy | 546 | /* If we can't reserve the bo, unref should be enough to destroy |
diff --git a/drivers/gpu/drm/radeon/r600_blit_shaders.h b/drivers/gpu/drm/radeon/r600_blit_shaders.h index fdc3b378cbb..f437d36dd98 100644 --- a/drivers/gpu/drm/radeon/r600_blit_shaders.h +++ b/drivers/gpu/drm/radeon/r600_blit_shaders.h | |||
@@ -1,3 +1,27 @@ | |||
1 | /* | ||
2 | * Copyright 2009 Advanced Micro Devices, Inc. | ||
3 | * Copyright 2009 Red Hat Inc. | ||
4 | * | ||
5 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
6 | * copy of this software and associated documentation files (the "Software"), | ||
7 | * to deal in the Software without restriction, including without limitation | ||
8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
9 | * and/or sell copies of the Software, and to permit persons to whom the | ||
10 | * Software is furnished to do so, subject to the following conditions: | ||
11 | * | ||
12 | * The above copyright notice and this permission notice (including the next | ||
13 | * paragraph) shall be included in all copies or substantial portions of the | ||
14 | * Software. | ||
15 | * | ||
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
19 | * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
20 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
21 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
22 | * DEALINGS IN THE SOFTWARE. | ||
23 | * | ||
24 | */ | ||
1 | 25 | ||
2 | #ifndef R600_BLIT_SHADERS_H | 26 | #ifndef R600_BLIT_SHADERS_H |
3 | #define R600_BLIT_SHADERS_H | 27 | #define R600_BLIT_SHADERS_H |
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index d8864949e38..250a3a91819 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
@@ -1170,9 +1170,8 @@ static inline int r600_check_texture_resource(struct radeon_cs_parser *p, u32 i | |||
1170 | /* using get ib will give us the offset into the mipmap bo */ | 1170 | /* using get ib will give us the offset into the mipmap bo */ |
1171 | word0 = radeon_get_ib_value(p, idx + 3) << 8; | 1171 | word0 = radeon_get_ib_value(p, idx + 3) << 8; |
1172 | if ((mipmap_size + word0) > radeon_bo_size(mipmap)) { | 1172 | if ((mipmap_size + word0) > radeon_bo_size(mipmap)) { |
1173 | dev_warn(p->dev, "mipmap bo too small (%d %d %d %d %d %d -> %d have %ld)\n", | 1173 | /*dev_warn(p->dev, "mipmap bo too small (%d %d %d %d %d %d -> %d have %ld)\n", |
1174 | w0, h0, bpe, blevel, nlevels, word0, mipmap_size, radeon_bo_size(texture)); | 1174 | w0, h0, bpe, blevel, nlevels, word0, mipmap_size, radeon_bo_size(texture));*/ |
1175 | return -EINVAL; | ||
1176 | } | 1175 | } |
1177 | return 0; | 1176 | return 0; |
1178 | } | 1177 | } |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 3dfcfa3ca42..9ff38c99a6e 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -344,6 +344,7 @@ struct radeon_mc { | |||
344 | * about vram size near mc fb location */ | 344 | * about vram size near mc fb location */ |
345 | u64 mc_vram_size; | 345 | u64 mc_vram_size; |
346 | u64 visible_vram_size; | 346 | u64 visible_vram_size; |
347 | u64 active_vram_size; | ||
347 | u64 gtt_size; | 348 | u64 gtt_size; |
348 | u64 gtt_start; | 349 | u64 gtt_start; |
349 | u64 gtt_end; | 350 | u64 gtt_end; |
@@ -1013,6 +1014,11 @@ int radeon_gem_set_tiling_ioctl(struct drm_device *dev, void *data, | |||
1013 | int radeon_gem_get_tiling_ioctl(struct drm_device *dev, void *data, | 1014 | int radeon_gem_get_tiling_ioctl(struct drm_device *dev, void *data, |
1014 | struct drm_file *filp); | 1015 | struct drm_file *filp); |
1015 | 1016 | ||
1017 | /* VRAM scratch page for HDP bug */ | ||
1018 | struct r700_vram_scratch { | ||
1019 | struct radeon_bo *robj; | ||
1020 | volatile uint32_t *ptr; | ||
1021 | }; | ||
1016 | 1022 | ||
1017 | /* | 1023 | /* |
1018 | * Core structure, functions and helpers. | 1024 | * Core structure, functions and helpers. |
@@ -1079,6 +1085,7 @@ struct radeon_device { | |||
1079 | const struct firmware *pfp_fw; /* r6/700 PFP firmware */ | 1085 | const struct firmware *pfp_fw; /* r6/700 PFP firmware */ |
1080 | const struct firmware *rlc_fw; /* r6/700 RLC firmware */ | 1086 | const struct firmware *rlc_fw; /* r6/700 RLC firmware */ |
1081 | struct r600_blit r600_blit; | 1087 | struct r600_blit r600_blit; |
1088 | struct r700_vram_scratch vram_scratch; | ||
1082 | int msi_enabled; /* msi enabled */ | 1089 | int msi_enabled; /* msi enabled */ |
1083 | struct r600_ih ih; /* r6/700 interrupt ring */ | 1090 | struct r600_ih ih; /* r6/700 interrupt ring */ |
1084 | struct workqueue_struct *wq; | 1091 | struct workqueue_struct *wq; |
@@ -1333,8 +1340,6 @@ extern bool radeon_card_posted(struct radeon_device *rdev); | |||
1333 | extern void radeon_update_bandwidth_info(struct radeon_device *rdev); | 1340 | extern void radeon_update_bandwidth_info(struct radeon_device *rdev); |
1334 | extern void radeon_update_display_priority(struct radeon_device *rdev); | 1341 | extern void radeon_update_display_priority(struct radeon_device *rdev); |
1335 | extern bool radeon_boot_test_post_card(struct radeon_device *rdev); | 1342 | extern bool radeon_boot_test_post_card(struct radeon_device *rdev); |
1336 | extern int radeon_clocks_init(struct radeon_device *rdev); | ||
1337 | extern void radeon_clocks_fini(struct radeon_device *rdev); | ||
1338 | extern void radeon_scratch_init(struct radeon_device *rdev); | 1343 | extern void radeon_scratch_init(struct radeon_device *rdev); |
1339 | extern void radeon_surface_init(struct radeon_device *rdev); | 1344 | extern void radeon_surface_init(struct radeon_device *rdev); |
1340 | extern int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data); | 1345 | extern int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data); |
diff --git a/drivers/gpu/drm/radeon/radeon_agp.c b/drivers/gpu/drm/radeon/radeon_agp.c index f40dfb77f9b..bd2f33e5c91 100644 --- a/drivers/gpu/drm/radeon/radeon_agp.c +++ b/drivers/gpu/drm/radeon/radeon_agp.c | |||
@@ -156,7 +156,13 @@ int radeon_agp_init(struct radeon_device *rdev) | |||
156 | } | 156 | } |
157 | 157 | ||
158 | mode.mode = info.mode; | 158 | mode.mode = info.mode; |
159 | agp_status = (RREG32(RADEON_AGP_STATUS) | RADEON_AGPv3_MODE) & mode.mode; | 159 | /* chips with the agp to pcie bridge don't have the AGP_STATUS register |
160 | * Just use the whatever mode the host sets up. | ||
161 | */ | ||
162 | if (rdev->family <= CHIP_RV350) | ||
163 | agp_status = (RREG32(RADEON_AGP_STATUS) | RADEON_AGPv3_MODE) & mode.mode; | ||
164 | else | ||
165 | agp_status = mode.mode; | ||
160 | is_v3 = !!(agp_status & RADEON_AGPv3_MODE); | 166 | is_v3 = !!(agp_status & RADEON_AGPv3_MODE); |
161 | 167 | ||
162 | if (is_v3) { | 168 | if (is_v3) { |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 646f96f97c7..25e1dd19779 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c | |||
@@ -733,6 +733,7 @@ static struct radeon_asic evergreen_asic = { | |||
733 | .set_engine_clock = &radeon_atom_set_engine_clock, | 733 | .set_engine_clock = &radeon_atom_set_engine_clock, |
734 | .get_memory_clock = &radeon_atom_get_memory_clock, | 734 | .get_memory_clock = &radeon_atom_get_memory_clock, |
735 | .set_memory_clock = &radeon_atom_set_memory_clock, | 735 | .set_memory_clock = &radeon_atom_set_memory_clock, |
736 | .get_pcie_lanes = NULL, | ||
736 | .set_pcie_lanes = NULL, | 737 | .set_pcie_lanes = NULL, |
737 | .set_clock_gating = NULL, | 738 | .set_clock_gating = NULL, |
738 | .set_surface_reg = r600_set_surface_reg, | 739 | .set_surface_reg = r600_set_surface_reg, |
@@ -857,21 +858,3 @@ int radeon_asic_init(struct radeon_device *rdev) | |||
857 | return 0; | 858 | return 0; |
858 | } | 859 | } |
859 | 860 | ||
860 | /* | ||
861 | * Wrapper around modesetting bits. Move to radeon_clocks.c? | ||
862 | */ | ||
863 | int radeon_clocks_init(struct radeon_device *rdev) | ||
864 | { | ||
865 | int r; | ||
866 | |||
867 | r = radeon_static_clocks_init(rdev->ddev); | ||
868 | if (r) { | ||
869 | return r; | ||
870 | } | ||
871 | DRM_INFO("Clocks initialized !\n"); | ||
872 | return 0; | ||
873 | } | ||
874 | |||
875 | void radeon_clocks_fini(struct radeon_device *rdev) | ||
876 | { | ||
877 | } | ||
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 6d30868744e..8e43ddae70c 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -32,11 +32,11 @@ | |||
32 | 32 | ||
33 | /* from radeon_encoder.c */ | 33 | /* from radeon_encoder.c */ |
34 | extern uint32_t | 34 | extern uint32_t |
35 | radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, | 35 | radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, |
36 | uint8_t dac); | 36 | uint8_t dac); |
37 | extern void radeon_link_encoder_connector(struct drm_device *dev); | 37 | extern void radeon_link_encoder_connector(struct drm_device *dev); |
38 | extern void | 38 | extern void |
39 | radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, | 39 | radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, |
40 | uint32_t supported_device); | 40 | uint32_t supported_device); |
41 | 41 | ||
42 | /* from radeon_connector.c */ | 42 | /* from radeon_connector.c */ |
@@ -46,14 +46,14 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
46 | uint32_t supported_device, | 46 | uint32_t supported_device, |
47 | int connector_type, | 47 | int connector_type, |
48 | struct radeon_i2c_bus_rec *i2c_bus, | 48 | struct radeon_i2c_bus_rec *i2c_bus, |
49 | bool linkb, uint32_t igp_lane_info, | 49 | uint32_t igp_lane_info, |
50 | uint16_t connector_object_id, | 50 | uint16_t connector_object_id, |
51 | struct radeon_hpd *hpd, | 51 | struct radeon_hpd *hpd, |
52 | struct radeon_router *router); | 52 | struct radeon_router *router); |
53 | 53 | ||
54 | /* from radeon_legacy_encoder.c */ | 54 | /* from radeon_legacy_encoder.c */ |
55 | extern void | 55 | extern void |
56 | radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, | 56 | radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum, |
57 | uint32_t supported_device); | 57 | uint32_t supported_device); |
58 | 58 | ||
59 | union atom_supported_devices { | 59 | union atom_supported_devices { |
@@ -85,6 +85,19 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_dev | |||
85 | for (i = 0; i < num_indices; i++) { | 85 | for (i = 0; i < num_indices; i++) { |
86 | gpio = &i2c_info->asGPIO_Info[i]; | 86 | gpio = &i2c_info->asGPIO_Info[i]; |
87 | 87 | ||
88 | /* some evergreen boards have bad data for this entry */ | ||
89 | if (ASIC_IS_DCE4(rdev)) { | ||
90 | if ((i == 7) && | ||
91 | (gpio->usClkMaskRegisterIndex == 0x1936) && | ||
92 | (gpio->sucI2cId.ucAccess == 0)) { | ||
93 | gpio->sucI2cId.ucAccess = 0x97; | ||
94 | gpio->ucDataMaskShift = 8; | ||
95 | gpio->ucDataEnShift = 8; | ||
96 | gpio->ucDataY_Shift = 8; | ||
97 | gpio->ucDataA_Shift = 8; | ||
98 | } | ||
99 | } | ||
100 | |||
88 | if (gpio->sucI2cId.ucAccess == id) { | 101 | if (gpio->sucI2cId.ucAccess == id) { |
89 | i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; | 102 | i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; |
90 | i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; | 103 | i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; |
@@ -147,6 +160,20 @@ void radeon_atombios_i2c_init(struct radeon_device *rdev) | |||
147 | for (i = 0; i < num_indices; i++) { | 160 | for (i = 0; i < num_indices; i++) { |
148 | gpio = &i2c_info->asGPIO_Info[i]; | 161 | gpio = &i2c_info->asGPIO_Info[i]; |
149 | i2c.valid = false; | 162 | i2c.valid = false; |
163 | |||
164 | /* some evergreen boards have bad data for this entry */ | ||
165 | if (ASIC_IS_DCE4(rdev)) { | ||
166 | if ((i == 7) && | ||
167 | (gpio->usClkMaskRegisterIndex == 0x1936) && | ||
168 | (gpio->sucI2cId.ucAccess == 0)) { | ||
169 | gpio->sucI2cId.ucAccess = 0x97; | ||
170 | gpio->ucDataMaskShift = 8; | ||
171 | gpio->ucDataEnShift = 8; | ||
172 | gpio->ucDataY_Shift = 8; | ||
173 | gpio->ucDataA_Shift = 8; | ||
174 | } | ||
175 | } | ||
176 | |||
150 | i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; | 177 | i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; |
151 | i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; | 178 | i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; |
152 | i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4; | 179 | i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4; |
@@ -226,6 +253,8 @@ static struct radeon_hpd radeon_atom_get_hpd_info_from_gpio(struct radeon_device | |||
226 | struct radeon_hpd hpd; | 253 | struct radeon_hpd hpd; |
227 | u32 reg; | 254 | u32 reg; |
228 | 255 | ||
256 | memset(&hpd, 0, sizeof(struct radeon_hpd)); | ||
257 | |||
229 | if (ASIC_IS_DCE4(rdev)) | 258 | if (ASIC_IS_DCE4(rdev)) |
230 | reg = EVERGREEN_DC_GPIO_HPD_A; | 259 | reg = EVERGREEN_DC_GPIO_HPD_A; |
231 | else | 260 | else |
@@ -288,6 +317,15 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, | |||
288 | *connector_type = DRM_MODE_CONNECTOR_DVID; | 317 | *connector_type = DRM_MODE_CONNECTOR_DVID; |
289 | } | 318 | } |
290 | 319 | ||
320 | /* MSI K9A2GM V2/V3 board has no HDMI or DVI */ | ||
321 | if ((dev->pdev->device == 0x796e) && | ||
322 | (dev->pdev->subsystem_vendor == 0x1462) && | ||
323 | (dev->pdev->subsystem_device == 0x7302)) { | ||
324 | if ((supported_device == ATOM_DEVICE_DFP2_SUPPORT) || | ||
325 | (supported_device == ATOM_DEVICE_DFP3_SUPPORT)) | ||
326 | return false; | ||
327 | } | ||
328 | |||
291 | /* a-bit f-i90hd - ciaranm on #radeonhd - this board has no DVI */ | 329 | /* a-bit f-i90hd - ciaranm on #radeonhd - this board has no DVI */ |
292 | if ((dev->pdev->device == 0x7941) && | 330 | if ((dev->pdev->device == 0x7941) && |
293 | (dev->pdev->subsystem_vendor == 0x147b) && | 331 | (dev->pdev->subsystem_vendor == 0x147b) && |
@@ -477,7 +515,6 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
477 | int i, j, k, path_size, device_support; | 515 | int i, j, k, path_size, device_support; |
478 | int connector_type; | 516 | int connector_type; |
479 | u16 igp_lane_info, conn_id, connector_object_id; | 517 | u16 igp_lane_info, conn_id, connector_object_id; |
480 | bool linkb; | ||
481 | struct radeon_i2c_bus_rec ddc_bus; | 518 | struct radeon_i2c_bus_rec ddc_bus; |
482 | struct radeon_router router; | 519 | struct radeon_router router; |
483 | struct radeon_gpio_rec gpio; | 520 | struct radeon_gpio_rec gpio; |
@@ -510,7 +547,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
510 | addr += path_size; | 547 | addr += path_size; |
511 | path = (ATOM_DISPLAY_OBJECT_PATH *) addr; | 548 | path = (ATOM_DISPLAY_OBJECT_PATH *) addr; |
512 | path_size += le16_to_cpu(path->usSize); | 549 | path_size += le16_to_cpu(path->usSize); |
513 | linkb = false; | 550 | |
514 | if (device_support & le16_to_cpu(path->usDeviceTag)) { | 551 | if (device_support & le16_to_cpu(path->usDeviceTag)) { |
515 | uint8_t con_obj_id, con_obj_num, con_obj_type; | 552 | uint8_t con_obj_id, con_obj_num, con_obj_type; |
516 | 553 | ||
@@ -601,13 +638,10 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
601 | OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; | 638 | OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; |
602 | 639 | ||
603 | if (grph_obj_type == GRAPH_OBJECT_TYPE_ENCODER) { | 640 | if (grph_obj_type == GRAPH_OBJECT_TYPE_ENCODER) { |
604 | if (grph_obj_num == 2) | 641 | u16 encoder_obj = le16_to_cpu(path->usGraphicObjIds[j]); |
605 | linkb = true; | ||
606 | else | ||
607 | linkb = false; | ||
608 | 642 | ||
609 | radeon_add_atom_encoder(dev, | 643 | radeon_add_atom_encoder(dev, |
610 | grph_obj_id, | 644 | encoder_obj, |
611 | le16_to_cpu | 645 | le16_to_cpu |
612 | (path-> | 646 | (path-> |
613 | usDeviceTag)); | 647 | usDeviceTag)); |
@@ -744,7 +778,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
744 | le16_to_cpu(path-> | 778 | le16_to_cpu(path-> |
745 | usDeviceTag), | 779 | usDeviceTag), |
746 | connector_type, &ddc_bus, | 780 | connector_type, &ddc_bus, |
747 | linkb, igp_lane_info, | 781 | igp_lane_info, |
748 | connector_object_id, | 782 | connector_object_id, |
749 | &hpd, | 783 | &hpd, |
750 | &router); | 784 | &router); |
@@ -933,13 +967,13 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
933 | 967 | ||
934 | if (ASIC_IS_AVIVO(rdev) || radeon_r4xx_atom) | 968 | if (ASIC_IS_AVIVO(rdev) || radeon_r4xx_atom) |
935 | radeon_add_atom_encoder(dev, | 969 | radeon_add_atom_encoder(dev, |
936 | radeon_get_encoder_id(dev, | 970 | radeon_get_encoder_enum(dev, |
937 | (1 << i), | 971 | (1 << i), |
938 | dac), | 972 | dac), |
939 | (1 << i)); | 973 | (1 << i)); |
940 | else | 974 | else |
941 | radeon_add_legacy_encoder(dev, | 975 | radeon_add_legacy_encoder(dev, |
942 | radeon_get_encoder_id(dev, | 976 | radeon_get_encoder_enum(dev, |
943 | (1 << i), | 977 | (1 << i), |
944 | dac), | 978 | dac), |
945 | (1 << i)); | 979 | (1 << i)); |
@@ -996,7 +1030,7 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
996 | bios_connectors[i]. | 1030 | bios_connectors[i]. |
997 | connector_type, | 1031 | connector_type, |
998 | &bios_connectors[i].ddc_bus, | 1032 | &bios_connectors[i].ddc_bus, |
999 | false, 0, | 1033 | 0, |
1000 | connector_object_id, | 1034 | connector_object_id, |
1001 | &bios_connectors[i].hpd, | 1035 | &bios_connectors[i].hpd, |
1002 | &router); | 1036 | &router); |
@@ -1183,7 +1217,7 @@ bool radeon_atombios_sideport_present(struct radeon_device *rdev) | |||
1183 | return true; | 1217 | return true; |
1184 | break; | 1218 | break; |
1185 | case 2: | 1219 | case 2: |
1186 | if (igp_info->info_2.ucMemoryType & 0x0f) | 1220 | if (igp_info->info_2.ulBootUpSidePortClock) |
1187 | return true; | 1221 | return true; |
1188 | break; | 1222 | break; |
1189 | default: | 1223 | default: |
@@ -1305,6 +1339,7 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct | |||
1305 | union lvds_info *lvds_info; | 1339 | union lvds_info *lvds_info; |
1306 | uint8_t frev, crev; | 1340 | uint8_t frev, crev; |
1307 | struct radeon_encoder_atom_dig *lvds = NULL; | 1341 | struct radeon_encoder_atom_dig *lvds = NULL; |
1342 | int encoder_enum = (encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT; | ||
1308 | 1343 | ||
1309 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, | 1344 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, |
1310 | &frev, &crev, &data_offset)) { | 1345 | &frev, &crev, &data_offset)) { |
@@ -1368,6 +1403,12 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct | |||
1368 | } | 1403 | } |
1369 | 1404 | ||
1370 | encoder->native_mode = lvds->native_mode; | 1405 | encoder->native_mode = lvds->native_mode; |
1406 | |||
1407 | if (encoder_enum == 2) | ||
1408 | lvds->linkb = true; | ||
1409 | else | ||
1410 | lvds->linkb = false; | ||
1411 | |||
1371 | } | 1412 | } |
1372 | return lvds; | 1413 | return lvds; |
1373 | } | 1414 | } |
@@ -1517,39 +1558,39 @@ radeon_atombios_get_tv_info(struct radeon_device *rdev) | |||
1517 | switch (tv_info->ucTV_BootUpDefaultStandard) { | 1558 | switch (tv_info->ucTV_BootUpDefaultStandard) { |
1518 | case ATOM_TV_NTSC: | 1559 | case ATOM_TV_NTSC: |
1519 | tv_std = TV_STD_NTSC; | 1560 | tv_std = TV_STD_NTSC; |
1520 | DRM_INFO("Default TV standard: NTSC\n"); | 1561 | DRM_DEBUG_KMS("Default TV standard: NTSC\n"); |
1521 | break; | 1562 | break; |
1522 | case ATOM_TV_NTSCJ: | 1563 | case ATOM_TV_NTSCJ: |
1523 | tv_std = TV_STD_NTSC_J; | 1564 | tv_std = TV_STD_NTSC_J; |
1524 | DRM_INFO("Default TV standard: NTSC-J\n"); | 1565 | DRM_DEBUG_KMS("Default TV standard: NTSC-J\n"); |
1525 | break; | 1566 | break; |
1526 | case ATOM_TV_PAL: | 1567 | case ATOM_TV_PAL: |
1527 | tv_std = TV_STD_PAL; | 1568 | tv_std = TV_STD_PAL; |
1528 | DRM_INFO("Default TV standard: PAL\n"); | 1569 | DRM_DEBUG_KMS("Default TV standard: PAL\n"); |
1529 | break; | 1570 | break; |
1530 | case ATOM_TV_PALM: | 1571 | case ATOM_TV_PALM: |
1531 | tv_std = TV_STD_PAL_M; | 1572 | tv_std = TV_STD_PAL_M; |
1532 | DRM_INFO("Default TV standard: PAL-M\n"); | 1573 | DRM_DEBUG_KMS("Default TV standard: PAL-M\n"); |
1533 | break; | 1574 | break; |
1534 | case ATOM_TV_PALN: | 1575 | case ATOM_TV_PALN: |
1535 | tv_std = TV_STD_PAL_N; | 1576 | tv_std = TV_STD_PAL_N; |
1536 | DRM_INFO("Default TV standard: PAL-N\n"); | 1577 | DRM_DEBUG_KMS("Default TV standard: PAL-N\n"); |
1537 | break; | 1578 | break; |
1538 | case ATOM_TV_PALCN: | 1579 | case ATOM_TV_PALCN: |
1539 | tv_std = TV_STD_PAL_CN; | 1580 | tv_std = TV_STD_PAL_CN; |
1540 | DRM_INFO("Default TV standard: PAL-CN\n"); | 1581 | DRM_DEBUG_KMS("Default TV standard: PAL-CN\n"); |
1541 | break; | 1582 | break; |
1542 | case ATOM_TV_PAL60: | 1583 | case ATOM_TV_PAL60: |
1543 | tv_std = TV_STD_PAL_60; | 1584 | tv_std = TV_STD_PAL_60; |
1544 | DRM_INFO("Default TV standard: PAL-60\n"); | 1585 | DRM_DEBUG_KMS("Default TV standard: PAL-60\n"); |
1545 | break; | 1586 | break; |
1546 | case ATOM_TV_SECAM: | 1587 | case ATOM_TV_SECAM: |
1547 | tv_std = TV_STD_SECAM; | 1588 | tv_std = TV_STD_SECAM; |
1548 | DRM_INFO("Default TV standard: SECAM\n"); | 1589 | DRM_DEBUG_KMS("Default TV standard: SECAM\n"); |
1549 | break; | 1590 | break; |
1550 | default: | 1591 | default: |
1551 | tv_std = TV_STD_NTSC; | 1592 | tv_std = TV_STD_NTSC; |
1552 | DRM_INFO("Unknown TV standard; defaulting to NTSC\n"); | 1593 | DRM_DEBUG_KMS("Unknown TV standard; defaulting to NTSC\n"); |
1553 | break; | 1594 | break; |
1554 | } | 1595 | } |
1555 | } | 1596 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_clocks.c b/drivers/gpu/drm/radeon/radeon_clocks.c index 14448a740ba..5249af8931e 100644 --- a/drivers/gpu/drm/radeon/radeon_clocks.c +++ b/drivers/gpu/drm/radeon/radeon_clocks.c | |||
@@ -327,6 +327,14 @@ void radeon_get_clock_info(struct drm_device *dev) | |||
327 | mpll->max_feedback_div = 0xff; | 327 | mpll->max_feedback_div = 0xff; |
328 | mpll->best_vco = 0; | 328 | mpll->best_vco = 0; |
329 | 329 | ||
330 | if (!rdev->clock.default_sclk) | ||
331 | rdev->clock.default_sclk = radeon_get_engine_clock(rdev); | ||
332 | if ((!rdev->clock.default_mclk) && rdev->asic->get_memory_clock) | ||
333 | rdev->clock.default_mclk = radeon_get_memory_clock(rdev); | ||
334 | |||
335 | rdev->pm.current_sclk = rdev->clock.default_sclk; | ||
336 | rdev->pm.current_mclk = rdev->clock.default_mclk; | ||
337 | |||
330 | } | 338 | } |
331 | 339 | ||
332 | /* 10 khz */ | 340 | /* 10 khz */ |
@@ -897,53 +905,3 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) | |||
897 | } | 905 | } |
898 | } | 906 | } |
899 | 907 | ||
900 | static void radeon_apply_clock_quirks(struct radeon_device *rdev) | ||
901 | { | ||
902 | uint32_t tmp; | ||
903 | |||
904 | /* XXX make sure engine is idle */ | ||
905 | |||
906 | if (rdev->family < CHIP_RS600) { | ||
907 | tmp = RREG32_PLL(RADEON_SCLK_CNTL); | ||
908 | if (ASIC_IS_R300(rdev) || ASIC_IS_RV100(rdev)) | ||
909 | tmp |= RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_VIP; | ||
910 | if ((rdev->family == CHIP_RV250) | ||
911 | || (rdev->family == CHIP_RV280)) | ||
912 | tmp |= | ||
913 | RADEON_SCLK_FORCE_DISP1 | RADEON_SCLK_FORCE_DISP2; | ||
914 | if ((rdev->family == CHIP_RV350) | ||
915 | || (rdev->family == CHIP_RV380)) | ||
916 | tmp |= R300_SCLK_FORCE_VAP; | ||
917 | if (rdev->family == CHIP_R420) | ||
918 | tmp |= R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX; | ||
919 | WREG32_PLL(RADEON_SCLK_CNTL, tmp); | ||
920 | } else if (rdev->family < CHIP_R600) { | ||
921 | tmp = RREG32_PLL(AVIVO_CP_DYN_CNTL); | ||
922 | tmp |= AVIVO_CP_FORCEON; | ||
923 | WREG32_PLL(AVIVO_CP_DYN_CNTL, tmp); | ||
924 | |||
925 | tmp = RREG32_PLL(AVIVO_E2_DYN_CNTL); | ||
926 | tmp |= AVIVO_E2_FORCEON; | ||
927 | WREG32_PLL(AVIVO_E2_DYN_CNTL, tmp); | ||
928 | |||
929 | tmp = RREG32_PLL(AVIVO_IDCT_DYN_CNTL); | ||
930 | tmp |= AVIVO_IDCT_FORCEON; | ||
931 | WREG32_PLL(AVIVO_IDCT_DYN_CNTL, tmp); | ||
932 | } | ||
933 | } | ||
934 | |||
935 | int radeon_static_clocks_init(struct drm_device *dev) | ||
936 | { | ||
937 | struct radeon_device *rdev = dev->dev_private; | ||
938 | |||
939 | /* XXX make sure engine is idle */ | ||
940 | |||
941 | if (radeon_dynclks != -1) { | ||
942 | if (radeon_dynclks) { | ||
943 | if (rdev->asic->set_clock_gating) | ||
944 | radeon_set_clock_gating(rdev, 1); | ||
945 | } | ||
946 | } | ||
947 | radeon_apply_clock_quirks(rdev); | ||
948 | return 0; | ||
949 | } | ||
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 885dcfac183..7b7ea269549 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
@@ -39,8 +39,8 @@ | |||
39 | 39 | ||
40 | /* from radeon_encoder.c */ | 40 | /* from radeon_encoder.c */ |
41 | extern uint32_t | 41 | extern uint32_t |
42 | radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, | 42 | radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, |
43 | uint8_t dac); | 43 | uint8_t dac); |
44 | extern void radeon_link_encoder_connector(struct drm_device *dev); | 44 | extern void radeon_link_encoder_connector(struct drm_device *dev); |
45 | 45 | ||
46 | /* from radeon_connector.c */ | 46 | /* from radeon_connector.c */ |
@@ -55,7 +55,7 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
55 | 55 | ||
56 | /* from radeon_legacy_encoder.c */ | 56 | /* from radeon_legacy_encoder.c */ |
57 | extern void | 57 | extern void |
58 | radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, | 58 | radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum, |
59 | uint32_t supported_device); | 59 | uint32_t supported_device); |
60 | 60 | ||
61 | /* old legacy ATI BIOS routines */ | 61 | /* old legacy ATI BIOS routines */ |
@@ -913,47 +913,47 @@ radeon_combios_get_tv_info(struct radeon_device *rdev) | |||
913 | switch (RBIOS8(tv_info + 7) & 0xf) { | 913 | switch (RBIOS8(tv_info + 7) & 0xf) { |
914 | case 1: | 914 | case 1: |
915 | tv_std = TV_STD_NTSC; | 915 | tv_std = TV_STD_NTSC; |
916 | DRM_INFO("Default TV standard: NTSC\n"); | 916 | DRM_DEBUG_KMS("Default TV standard: NTSC\n"); |
917 | break; | 917 | break; |
918 | case 2: | 918 | case 2: |
919 | tv_std = TV_STD_PAL; | 919 | tv_std = TV_STD_PAL; |
920 | DRM_INFO("Default TV standard: PAL\n"); | 920 | DRM_DEBUG_KMS("Default TV standard: PAL\n"); |
921 | break; | 921 | break; |
922 | case 3: | 922 | case 3: |
923 | tv_std = TV_STD_PAL_M; | 923 | tv_std = TV_STD_PAL_M; |
924 | DRM_INFO("Default TV standard: PAL-M\n"); | 924 | DRM_DEBUG_KMS("Default TV standard: PAL-M\n"); |
925 | break; | 925 | break; |
926 | case 4: | 926 | case 4: |
927 | tv_std = TV_STD_PAL_60; | 927 | tv_std = TV_STD_PAL_60; |
928 | DRM_INFO("Default TV standard: PAL-60\n"); | 928 | DRM_DEBUG_KMS("Default TV standard: PAL-60\n"); |
929 | break; | 929 | break; |
930 | case 5: | 930 | case 5: |
931 | tv_std = TV_STD_NTSC_J; | 931 | tv_std = TV_STD_NTSC_J; |
932 | DRM_INFO("Default TV standard: NTSC-J\n"); | 932 | DRM_DEBUG_KMS("Default TV standard: NTSC-J\n"); |
933 | break; | 933 | break; |
934 | case 6: | 934 | case 6: |
935 | tv_std = TV_STD_SCART_PAL; | 935 | tv_std = TV_STD_SCART_PAL; |
936 | DRM_INFO("Default TV standard: SCART-PAL\n"); | 936 | DRM_DEBUG_KMS("Default TV standard: SCART-PAL\n"); |
937 | break; | 937 | break; |
938 | default: | 938 | default: |
939 | tv_std = TV_STD_NTSC; | 939 | tv_std = TV_STD_NTSC; |
940 | DRM_INFO | 940 | DRM_DEBUG_KMS |
941 | ("Unknown TV standard; defaulting to NTSC\n"); | 941 | ("Unknown TV standard; defaulting to NTSC\n"); |
942 | break; | 942 | break; |
943 | } | 943 | } |
944 | 944 | ||
945 | switch ((RBIOS8(tv_info + 9) >> 2) & 0x3) { | 945 | switch ((RBIOS8(tv_info + 9) >> 2) & 0x3) { |
946 | case 0: | 946 | case 0: |
947 | DRM_INFO("29.498928713 MHz TV ref clk\n"); | 947 | DRM_DEBUG_KMS("29.498928713 MHz TV ref clk\n"); |
948 | break; | 948 | break; |
949 | case 1: | 949 | case 1: |
950 | DRM_INFO("28.636360000 MHz TV ref clk\n"); | 950 | DRM_DEBUG_KMS("28.636360000 MHz TV ref clk\n"); |
951 | break; | 951 | break; |
952 | case 2: | 952 | case 2: |
953 | DRM_INFO("14.318180000 MHz TV ref clk\n"); | 953 | DRM_DEBUG_KMS("14.318180000 MHz TV ref clk\n"); |
954 | break; | 954 | break; |
955 | case 3: | 955 | case 3: |
956 | DRM_INFO("27.000000000 MHz TV ref clk\n"); | 956 | DRM_DEBUG_KMS("27.000000000 MHz TV ref clk\n"); |
957 | break; | 957 | break; |
958 | default: | 958 | default: |
959 | break; | 959 | break; |
@@ -1324,7 +1324,7 @@ bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder, | |||
1324 | 1324 | ||
1325 | if (tmds_info) { | 1325 | if (tmds_info) { |
1326 | ver = RBIOS8(tmds_info); | 1326 | ver = RBIOS8(tmds_info); |
1327 | DRM_INFO("DFP table revision: %d\n", ver); | 1327 | DRM_DEBUG_KMS("DFP table revision: %d\n", ver); |
1328 | if (ver == 3) { | 1328 | if (ver == 3) { |
1329 | n = RBIOS8(tmds_info + 5) + 1; | 1329 | n = RBIOS8(tmds_info + 5) + 1; |
1330 | if (n > 4) | 1330 | if (n > 4) |
@@ -1408,7 +1408,7 @@ bool radeon_legacy_get_ext_tmds_info_from_combios(struct radeon_encoder *encoder | |||
1408 | offset = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE); | 1408 | offset = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE); |
1409 | if (offset) { | 1409 | if (offset) { |
1410 | ver = RBIOS8(offset); | 1410 | ver = RBIOS8(offset); |
1411 | DRM_INFO("External TMDS Table revision: %d\n", ver); | 1411 | DRM_DEBUG_KMS("External TMDS Table revision: %d\n", ver); |
1412 | tmds->slave_addr = RBIOS8(offset + 4 + 2); | 1412 | tmds->slave_addr = RBIOS8(offset + 4 + 2); |
1413 | tmds->slave_addr >>= 1; /* 7 bit addressing */ | 1413 | tmds->slave_addr >>= 1; /* 7 bit addressing */ |
1414 | gpio = RBIOS8(offset + 4 + 3); | 1414 | gpio = RBIOS8(offset + 4 + 3); |
@@ -1485,6 +1485,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1485 | /* PowerMac8,1 ? */ | 1485 | /* PowerMac8,1 ? */ |
1486 | /* imac g5 isight */ | 1486 | /* imac g5 isight */ |
1487 | rdev->mode_info.connector_table = CT_IMAC_G5_ISIGHT; | 1487 | rdev->mode_info.connector_table = CT_IMAC_G5_ISIGHT; |
1488 | } else if ((rdev->pdev->device == 0x4a48) && | ||
1489 | (rdev->pdev->subsystem_vendor == 0x1002) && | ||
1490 | (rdev->pdev->subsystem_device == 0x4a48)) { | ||
1491 | /* Mac X800 */ | ||
1492 | rdev->mode_info.connector_table = CT_MAC_X800; | ||
1488 | } else | 1493 | } else |
1489 | #endif /* CONFIG_PPC_PMAC */ | 1494 | #endif /* CONFIG_PPC_PMAC */ |
1490 | #ifdef CONFIG_PPC64 | 1495 | #ifdef CONFIG_PPC64 |
@@ -1505,7 +1510,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1505 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | 1510 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); |
1506 | hpd.hpd = RADEON_HPD_NONE; | 1511 | hpd.hpd = RADEON_HPD_NONE; |
1507 | radeon_add_legacy_encoder(dev, | 1512 | radeon_add_legacy_encoder(dev, |
1508 | radeon_get_encoder_id(dev, | 1513 | radeon_get_encoder_enum(dev, |
1509 | ATOM_DEVICE_CRT1_SUPPORT, | 1514 | ATOM_DEVICE_CRT1_SUPPORT, |
1510 | 1), | 1515 | 1), |
1511 | ATOM_DEVICE_CRT1_SUPPORT); | 1516 | ATOM_DEVICE_CRT1_SUPPORT); |
@@ -1520,7 +1525,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1520 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_NONE_DETECTED, 0, 0); | 1525 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_NONE_DETECTED, 0, 0); |
1521 | hpd.hpd = RADEON_HPD_NONE; | 1526 | hpd.hpd = RADEON_HPD_NONE; |
1522 | radeon_add_legacy_encoder(dev, | 1527 | radeon_add_legacy_encoder(dev, |
1523 | radeon_get_encoder_id(dev, | 1528 | radeon_get_encoder_enum(dev, |
1524 | ATOM_DEVICE_LCD1_SUPPORT, | 1529 | ATOM_DEVICE_LCD1_SUPPORT, |
1525 | 0), | 1530 | 0), |
1526 | ATOM_DEVICE_LCD1_SUPPORT); | 1531 | ATOM_DEVICE_LCD1_SUPPORT); |
@@ -1535,7 +1540,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1535 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | 1540 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); |
1536 | hpd.hpd = RADEON_HPD_NONE; | 1541 | hpd.hpd = RADEON_HPD_NONE; |
1537 | radeon_add_legacy_encoder(dev, | 1542 | radeon_add_legacy_encoder(dev, |
1538 | radeon_get_encoder_id(dev, | 1543 | radeon_get_encoder_enum(dev, |
1539 | ATOM_DEVICE_CRT1_SUPPORT, | 1544 | ATOM_DEVICE_CRT1_SUPPORT, |
1540 | 1), | 1545 | 1), |
1541 | ATOM_DEVICE_CRT1_SUPPORT); | 1546 | ATOM_DEVICE_CRT1_SUPPORT); |
@@ -1550,12 +1555,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1550 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); | 1555 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); |
1551 | hpd.hpd = RADEON_HPD_1; | 1556 | hpd.hpd = RADEON_HPD_1; |
1552 | radeon_add_legacy_encoder(dev, | 1557 | radeon_add_legacy_encoder(dev, |
1553 | radeon_get_encoder_id(dev, | 1558 | radeon_get_encoder_enum(dev, |
1554 | ATOM_DEVICE_DFP1_SUPPORT, | 1559 | ATOM_DEVICE_DFP1_SUPPORT, |
1555 | 0), | 1560 | 0), |
1556 | ATOM_DEVICE_DFP1_SUPPORT); | 1561 | ATOM_DEVICE_DFP1_SUPPORT); |
1557 | radeon_add_legacy_encoder(dev, | 1562 | radeon_add_legacy_encoder(dev, |
1558 | radeon_get_encoder_id(dev, | 1563 | radeon_get_encoder_enum(dev, |
1559 | ATOM_DEVICE_CRT2_SUPPORT, | 1564 | ATOM_DEVICE_CRT2_SUPPORT, |
1560 | 2), | 1565 | 2), |
1561 | ATOM_DEVICE_CRT2_SUPPORT); | 1566 | ATOM_DEVICE_CRT2_SUPPORT); |
@@ -1571,7 +1576,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1571 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | 1576 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); |
1572 | hpd.hpd = RADEON_HPD_NONE; | 1577 | hpd.hpd = RADEON_HPD_NONE; |
1573 | radeon_add_legacy_encoder(dev, | 1578 | radeon_add_legacy_encoder(dev, |
1574 | radeon_get_encoder_id(dev, | 1579 | radeon_get_encoder_enum(dev, |
1575 | ATOM_DEVICE_CRT1_SUPPORT, | 1580 | ATOM_DEVICE_CRT1_SUPPORT, |
1576 | 1), | 1581 | 1), |
1577 | ATOM_DEVICE_CRT1_SUPPORT); | 1582 | ATOM_DEVICE_CRT1_SUPPORT); |
@@ -1588,7 +1593,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1588 | ddc_i2c.valid = false; | 1593 | ddc_i2c.valid = false; |
1589 | hpd.hpd = RADEON_HPD_NONE; | 1594 | hpd.hpd = RADEON_HPD_NONE; |
1590 | radeon_add_legacy_encoder(dev, | 1595 | radeon_add_legacy_encoder(dev, |
1591 | radeon_get_encoder_id(dev, | 1596 | radeon_get_encoder_enum(dev, |
1592 | ATOM_DEVICE_TV1_SUPPORT, | 1597 | ATOM_DEVICE_TV1_SUPPORT, |
1593 | 2), | 1598 | 2), |
1594 | ATOM_DEVICE_TV1_SUPPORT); | 1599 | ATOM_DEVICE_TV1_SUPPORT); |
@@ -1607,7 +1612,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1607 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); | 1612 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); |
1608 | hpd.hpd = RADEON_HPD_NONE; | 1613 | hpd.hpd = RADEON_HPD_NONE; |
1609 | radeon_add_legacy_encoder(dev, | 1614 | radeon_add_legacy_encoder(dev, |
1610 | radeon_get_encoder_id(dev, | 1615 | radeon_get_encoder_enum(dev, |
1611 | ATOM_DEVICE_LCD1_SUPPORT, | 1616 | ATOM_DEVICE_LCD1_SUPPORT, |
1612 | 0), | 1617 | 0), |
1613 | ATOM_DEVICE_LCD1_SUPPORT); | 1618 | ATOM_DEVICE_LCD1_SUPPORT); |
@@ -1619,7 +1624,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1619 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | 1624 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); |
1620 | hpd.hpd = RADEON_HPD_NONE; | 1625 | hpd.hpd = RADEON_HPD_NONE; |
1621 | radeon_add_legacy_encoder(dev, | 1626 | radeon_add_legacy_encoder(dev, |
1622 | radeon_get_encoder_id(dev, | 1627 | radeon_get_encoder_enum(dev, |
1623 | ATOM_DEVICE_CRT2_SUPPORT, | 1628 | ATOM_DEVICE_CRT2_SUPPORT, |
1624 | 2), | 1629 | 2), |
1625 | ATOM_DEVICE_CRT2_SUPPORT); | 1630 | ATOM_DEVICE_CRT2_SUPPORT); |
@@ -1631,7 +1636,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1631 | ddc_i2c.valid = false; | 1636 | ddc_i2c.valid = false; |
1632 | hpd.hpd = RADEON_HPD_NONE; | 1637 | hpd.hpd = RADEON_HPD_NONE; |
1633 | radeon_add_legacy_encoder(dev, | 1638 | radeon_add_legacy_encoder(dev, |
1634 | radeon_get_encoder_id(dev, | 1639 | radeon_get_encoder_enum(dev, |
1635 | ATOM_DEVICE_TV1_SUPPORT, | 1640 | ATOM_DEVICE_TV1_SUPPORT, |
1636 | 2), | 1641 | 2), |
1637 | ATOM_DEVICE_TV1_SUPPORT); | 1642 | ATOM_DEVICE_TV1_SUPPORT); |
@@ -1648,7 +1653,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1648 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); | 1653 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); |
1649 | hpd.hpd = RADEON_HPD_NONE; | 1654 | hpd.hpd = RADEON_HPD_NONE; |
1650 | radeon_add_legacy_encoder(dev, | 1655 | radeon_add_legacy_encoder(dev, |
1651 | radeon_get_encoder_id(dev, | 1656 | radeon_get_encoder_enum(dev, |
1652 | ATOM_DEVICE_LCD1_SUPPORT, | 1657 | ATOM_DEVICE_LCD1_SUPPORT, |
1653 | 0), | 1658 | 0), |
1654 | ATOM_DEVICE_LCD1_SUPPORT); | 1659 | ATOM_DEVICE_LCD1_SUPPORT); |
@@ -1660,12 +1665,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1660 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | 1665 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); |
1661 | hpd.hpd = RADEON_HPD_2; /* ??? */ | 1666 | hpd.hpd = RADEON_HPD_2; /* ??? */ |
1662 | radeon_add_legacy_encoder(dev, | 1667 | radeon_add_legacy_encoder(dev, |
1663 | radeon_get_encoder_id(dev, | 1668 | radeon_get_encoder_enum(dev, |
1664 | ATOM_DEVICE_DFP2_SUPPORT, | 1669 | ATOM_DEVICE_DFP2_SUPPORT, |
1665 | 0), | 1670 | 0), |
1666 | ATOM_DEVICE_DFP2_SUPPORT); | 1671 | ATOM_DEVICE_DFP2_SUPPORT); |
1667 | radeon_add_legacy_encoder(dev, | 1672 | radeon_add_legacy_encoder(dev, |
1668 | radeon_get_encoder_id(dev, | 1673 | radeon_get_encoder_enum(dev, |
1669 | ATOM_DEVICE_CRT1_SUPPORT, | 1674 | ATOM_DEVICE_CRT1_SUPPORT, |
1670 | 1), | 1675 | 1), |
1671 | ATOM_DEVICE_CRT1_SUPPORT); | 1676 | ATOM_DEVICE_CRT1_SUPPORT); |
@@ -1680,7 +1685,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1680 | ddc_i2c.valid = false; | 1685 | ddc_i2c.valid = false; |
1681 | hpd.hpd = RADEON_HPD_NONE; | 1686 | hpd.hpd = RADEON_HPD_NONE; |
1682 | radeon_add_legacy_encoder(dev, | 1687 | radeon_add_legacy_encoder(dev, |
1683 | radeon_get_encoder_id(dev, | 1688 | radeon_get_encoder_enum(dev, |
1684 | ATOM_DEVICE_TV1_SUPPORT, | 1689 | ATOM_DEVICE_TV1_SUPPORT, |
1685 | 2), | 1690 | 2), |
1686 | ATOM_DEVICE_TV1_SUPPORT); | 1691 | ATOM_DEVICE_TV1_SUPPORT); |
@@ -1697,7 +1702,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1697 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); | 1702 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); |
1698 | hpd.hpd = RADEON_HPD_NONE; | 1703 | hpd.hpd = RADEON_HPD_NONE; |
1699 | radeon_add_legacy_encoder(dev, | 1704 | radeon_add_legacy_encoder(dev, |
1700 | radeon_get_encoder_id(dev, | 1705 | radeon_get_encoder_enum(dev, |
1701 | ATOM_DEVICE_LCD1_SUPPORT, | 1706 | ATOM_DEVICE_LCD1_SUPPORT, |
1702 | 0), | 1707 | 0), |
1703 | ATOM_DEVICE_LCD1_SUPPORT); | 1708 | ATOM_DEVICE_LCD1_SUPPORT); |
@@ -1709,12 +1714,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1709 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | 1714 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); |
1710 | hpd.hpd = RADEON_HPD_1; /* ??? */ | 1715 | hpd.hpd = RADEON_HPD_1; /* ??? */ |
1711 | radeon_add_legacy_encoder(dev, | 1716 | radeon_add_legacy_encoder(dev, |
1712 | radeon_get_encoder_id(dev, | 1717 | radeon_get_encoder_enum(dev, |
1713 | ATOM_DEVICE_DFP1_SUPPORT, | 1718 | ATOM_DEVICE_DFP1_SUPPORT, |
1714 | 0), | 1719 | 0), |
1715 | ATOM_DEVICE_DFP1_SUPPORT); | 1720 | ATOM_DEVICE_DFP1_SUPPORT); |
1716 | radeon_add_legacy_encoder(dev, | 1721 | radeon_add_legacy_encoder(dev, |
1717 | radeon_get_encoder_id(dev, | 1722 | radeon_get_encoder_enum(dev, |
1718 | ATOM_DEVICE_CRT1_SUPPORT, | 1723 | ATOM_DEVICE_CRT1_SUPPORT, |
1719 | 1), | 1724 | 1), |
1720 | ATOM_DEVICE_CRT1_SUPPORT); | 1725 | ATOM_DEVICE_CRT1_SUPPORT); |
@@ -1728,7 +1733,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1728 | ddc_i2c.valid = false; | 1733 | ddc_i2c.valid = false; |
1729 | hpd.hpd = RADEON_HPD_NONE; | 1734 | hpd.hpd = RADEON_HPD_NONE; |
1730 | radeon_add_legacy_encoder(dev, | 1735 | radeon_add_legacy_encoder(dev, |
1731 | radeon_get_encoder_id(dev, | 1736 | radeon_get_encoder_enum(dev, |
1732 | ATOM_DEVICE_TV1_SUPPORT, | 1737 | ATOM_DEVICE_TV1_SUPPORT, |
1733 | 2), | 1738 | 2), |
1734 | ATOM_DEVICE_TV1_SUPPORT); | 1739 | ATOM_DEVICE_TV1_SUPPORT); |
@@ -1745,7 +1750,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1745 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); | 1750 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); |
1746 | hpd.hpd = RADEON_HPD_NONE; | 1751 | hpd.hpd = RADEON_HPD_NONE; |
1747 | radeon_add_legacy_encoder(dev, | 1752 | radeon_add_legacy_encoder(dev, |
1748 | radeon_get_encoder_id(dev, | 1753 | radeon_get_encoder_enum(dev, |
1749 | ATOM_DEVICE_LCD1_SUPPORT, | 1754 | ATOM_DEVICE_LCD1_SUPPORT, |
1750 | 0), | 1755 | 0), |
1751 | ATOM_DEVICE_LCD1_SUPPORT); | 1756 | ATOM_DEVICE_LCD1_SUPPORT); |
@@ -1757,7 +1762,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1757 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | 1762 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); |
1758 | hpd.hpd = RADEON_HPD_NONE; | 1763 | hpd.hpd = RADEON_HPD_NONE; |
1759 | radeon_add_legacy_encoder(dev, | 1764 | radeon_add_legacy_encoder(dev, |
1760 | radeon_get_encoder_id(dev, | 1765 | radeon_get_encoder_enum(dev, |
1761 | ATOM_DEVICE_CRT1_SUPPORT, | 1766 | ATOM_DEVICE_CRT1_SUPPORT, |
1762 | 1), | 1767 | 1), |
1763 | ATOM_DEVICE_CRT1_SUPPORT); | 1768 | ATOM_DEVICE_CRT1_SUPPORT); |
@@ -1769,7 +1774,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1769 | ddc_i2c.valid = false; | 1774 | ddc_i2c.valid = false; |
1770 | hpd.hpd = RADEON_HPD_NONE; | 1775 | hpd.hpd = RADEON_HPD_NONE; |
1771 | radeon_add_legacy_encoder(dev, | 1776 | radeon_add_legacy_encoder(dev, |
1772 | radeon_get_encoder_id(dev, | 1777 | radeon_get_encoder_enum(dev, |
1773 | ATOM_DEVICE_TV1_SUPPORT, | 1778 | ATOM_DEVICE_TV1_SUPPORT, |
1774 | 2), | 1779 | 2), |
1775 | ATOM_DEVICE_TV1_SUPPORT); | 1780 | ATOM_DEVICE_TV1_SUPPORT); |
@@ -1786,12 +1791,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1786 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); | 1791 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); |
1787 | hpd.hpd = RADEON_HPD_2; /* ??? */ | 1792 | hpd.hpd = RADEON_HPD_2; /* ??? */ |
1788 | radeon_add_legacy_encoder(dev, | 1793 | radeon_add_legacy_encoder(dev, |
1789 | radeon_get_encoder_id(dev, | 1794 | radeon_get_encoder_enum(dev, |
1790 | ATOM_DEVICE_DFP2_SUPPORT, | 1795 | ATOM_DEVICE_DFP2_SUPPORT, |
1791 | 0), | 1796 | 0), |
1792 | ATOM_DEVICE_DFP2_SUPPORT); | 1797 | ATOM_DEVICE_DFP2_SUPPORT); |
1793 | radeon_add_legacy_encoder(dev, | 1798 | radeon_add_legacy_encoder(dev, |
1794 | radeon_get_encoder_id(dev, | 1799 | radeon_get_encoder_enum(dev, |
1795 | ATOM_DEVICE_CRT2_SUPPORT, | 1800 | ATOM_DEVICE_CRT2_SUPPORT, |
1796 | 2), | 1801 | 2), |
1797 | ATOM_DEVICE_CRT2_SUPPORT); | 1802 | ATOM_DEVICE_CRT2_SUPPORT); |
@@ -1806,7 +1811,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1806 | ddc_i2c.valid = false; | 1811 | ddc_i2c.valid = false; |
1807 | hpd.hpd = RADEON_HPD_NONE; | 1812 | hpd.hpd = RADEON_HPD_NONE; |
1808 | radeon_add_legacy_encoder(dev, | 1813 | radeon_add_legacy_encoder(dev, |
1809 | radeon_get_encoder_id(dev, | 1814 | radeon_get_encoder_enum(dev, |
1810 | ATOM_DEVICE_TV1_SUPPORT, | 1815 | ATOM_DEVICE_TV1_SUPPORT, |
1811 | 2), | 1816 | 2), |
1812 | ATOM_DEVICE_TV1_SUPPORT); | 1817 | ATOM_DEVICE_TV1_SUPPORT); |
@@ -1823,12 +1828,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1823 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); | 1828 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); |
1824 | hpd.hpd = RADEON_HPD_1; /* ??? */ | 1829 | hpd.hpd = RADEON_HPD_1; /* ??? */ |
1825 | radeon_add_legacy_encoder(dev, | 1830 | radeon_add_legacy_encoder(dev, |
1826 | radeon_get_encoder_id(dev, | 1831 | radeon_get_encoder_enum(dev, |
1827 | ATOM_DEVICE_DFP1_SUPPORT, | 1832 | ATOM_DEVICE_DFP1_SUPPORT, |
1828 | 0), | 1833 | 0), |
1829 | ATOM_DEVICE_DFP1_SUPPORT); | 1834 | ATOM_DEVICE_DFP1_SUPPORT); |
1830 | radeon_add_legacy_encoder(dev, | 1835 | radeon_add_legacy_encoder(dev, |
1831 | radeon_get_encoder_id(dev, | 1836 | radeon_get_encoder_enum(dev, |
1832 | ATOM_DEVICE_CRT2_SUPPORT, | 1837 | ATOM_DEVICE_CRT2_SUPPORT, |
1833 | 2), | 1838 | 2), |
1834 | ATOM_DEVICE_CRT2_SUPPORT); | 1839 | ATOM_DEVICE_CRT2_SUPPORT); |
@@ -1842,7 +1847,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1842 | ddc_i2c.valid = false; | 1847 | ddc_i2c.valid = false; |
1843 | hpd.hpd = RADEON_HPD_NONE; | 1848 | hpd.hpd = RADEON_HPD_NONE; |
1844 | radeon_add_legacy_encoder(dev, | 1849 | radeon_add_legacy_encoder(dev, |
1845 | radeon_get_encoder_id(dev, | 1850 | radeon_get_encoder_enum(dev, |
1846 | ATOM_DEVICE_TV1_SUPPORT, | 1851 | ATOM_DEVICE_TV1_SUPPORT, |
1847 | 2), | 1852 | 2), |
1848 | ATOM_DEVICE_TV1_SUPPORT); | 1853 | ATOM_DEVICE_TV1_SUPPORT); |
@@ -1859,7 +1864,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1859 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0); | 1864 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0); |
1860 | hpd.hpd = RADEON_HPD_1; /* ??? */ | 1865 | hpd.hpd = RADEON_HPD_1; /* ??? */ |
1861 | radeon_add_legacy_encoder(dev, | 1866 | radeon_add_legacy_encoder(dev, |
1862 | radeon_get_encoder_id(dev, | 1867 | radeon_get_encoder_enum(dev, |
1863 | ATOM_DEVICE_DFP1_SUPPORT, | 1868 | ATOM_DEVICE_DFP1_SUPPORT, |
1864 | 0), | 1869 | 0), |
1865 | ATOM_DEVICE_DFP1_SUPPORT); | 1870 | ATOM_DEVICE_DFP1_SUPPORT); |
@@ -1871,7 +1876,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1871 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); | 1876 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); |
1872 | hpd.hpd = RADEON_HPD_NONE; | 1877 | hpd.hpd = RADEON_HPD_NONE; |
1873 | radeon_add_legacy_encoder(dev, | 1878 | radeon_add_legacy_encoder(dev, |
1874 | radeon_get_encoder_id(dev, | 1879 | radeon_get_encoder_enum(dev, |
1875 | ATOM_DEVICE_CRT2_SUPPORT, | 1880 | ATOM_DEVICE_CRT2_SUPPORT, |
1876 | 2), | 1881 | 2), |
1877 | ATOM_DEVICE_CRT2_SUPPORT); | 1882 | ATOM_DEVICE_CRT2_SUPPORT); |
@@ -1883,7 +1888,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1883 | ddc_i2c.valid = false; | 1888 | ddc_i2c.valid = false; |
1884 | hpd.hpd = RADEON_HPD_NONE; | 1889 | hpd.hpd = RADEON_HPD_NONE; |
1885 | radeon_add_legacy_encoder(dev, | 1890 | radeon_add_legacy_encoder(dev, |
1886 | radeon_get_encoder_id(dev, | 1891 | radeon_get_encoder_enum(dev, |
1887 | ATOM_DEVICE_TV1_SUPPORT, | 1892 | ATOM_DEVICE_TV1_SUPPORT, |
1888 | 2), | 1893 | 2), |
1889 | ATOM_DEVICE_TV1_SUPPORT); | 1894 | ATOM_DEVICE_TV1_SUPPORT); |
@@ -1900,7 +1905,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1900 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | 1905 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); |
1901 | hpd.hpd = RADEON_HPD_NONE; | 1906 | hpd.hpd = RADEON_HPD_NONE; |
1902 | radeon_add_legacy_encoder(dev, | 1907 | radeon_add_legacy_encoder(dev, |
1903 | radeon_get_encoder_id(dev, | 1908 | radeon_get_encoder_enum(dev, |
1904 | ATOM_DEVICE_CRT1_SUPPORT, | 1909 | ATOM_DEVICE_CRT1_SUPPORT, |
1905 | 1), | 1910 | 1), |
1906 | ATOM_DEVICE_CRT1_SUPPORT); | 1911 | ATOM_DEVICE_CRT1_SUPPORT); |
@@ -1912,7 +1917,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1912 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); | 1917 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); |
1913 | hpd.hpd = RADEON_HPD_NONE; | 1918 | hpd.hpd = RADEON_HPD_NONE; |
1914 | radeon_add_legacy_encoder(dev, | 1919 | radeon_add_legacy_encoder(dev, |
1915 | radeon_get_encoder_id(dev, | 1920 | radeon_get_encoder_enum(dev, |
1916 | ATOM_DEVICE_CRT2_SUPPORT, | 1921 | ATOM_DEVICE_CRT2_SUPPORT, |
1917 | 2), | 1922 | 2), |
1918 | ATOM_DEVICE_CRT2_SUPPORT); | 1923 | ATOM_DEVICE_CRT2_SUPPORT); |
@@ -1924,7 +1929,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1924 | ddc_i2c.valid = false; | 1929 | ddc_i2c.valid = false; |
1925 | hpd.hpd = RADEON_HPD_NONE; | 1930 | hpd.hpd = RADEON_HPD_NONE; |
1926 | radeon_add_legacy_encoder(dev, | 1931 | radeon_add_legacy_encoder(dev, |
1927 | radeon_get_encoder_id(dev, | 1932 | radeon_get_encoder_enum(dev, |
1928 | ATOM_DEVICE_TV1_SUPPORT, | 1933 | ATOM_DEVICE_TV1_SUPPORT, |
1929 | 2), | 1934 | 2), |
1930 | ATOM_DEVICE_TV1_SUPPORT); | 1935 | ATOM_DEVICE_TV1_SUPPORT); |
@@ -1941,7 +1946,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1941 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | 1946 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); |
1942 | hpd.hpd = RADEON_HPD_NONE; | 1947 | hpd.hpd = RADEON_HPD_NONE; |
1943 | radeon_add_legacy_encoder(dev, | 1948 | radeon_add_legacy_encoder(dev, |
1944 | radeon_get_encoder_id(dev, | 1949 | radeon_get_encoder_enum(dev, |
1945 | ATOM_DEVICE_CRT1_SUPPORT, | 1950 | ATOM_DEVICE_CRT1_SUPPORT, |
1946 | 1), | 1951 | 1), |
1947 | ATOM_DEVICE_CRT1_SUPPORT); | 1952 | ATOM_DEVICE_CRT1_SUPPORT); |
@@ -1952,7 +1957,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1952 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); | 1957 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); |
1953 | hpd.hpd = RADEON_HPD_NONE; | 1958 | hpd.hpd = RADEON_HPD_NONE; |
1954 | radeon_add_legacy_encoder(dev, | 1959 | radeon_add_legacy_encoder(dev, |
1955 | radeon_get_encoder_id(dev, | 1960 | radeon_get_encoder_enum(dev, |
1956 | ATOM_DEVICE_CRT2_SUPPORT, | 1961 | ATOM_DEVICE_CRT2_SUPPORT, |
1957 | 2), | 1962 | 2), |
1958 | ATOM_DEVICE_CRT2_SUPPORT); | 1963 | ATOM_DEVICE_CRT2_SUPPORT); |
@@ -1961,6 +1966,48 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1961 | CONNECTOR_OBJECT_ID_VGA, | 1966 | CONNECTOR_OBJECT_ID_VGA, |
1962 | &hpd); | 1967 | &hpd); |
1963 | break; | 1968 | break; |
1969 | case CT_MAC_X800: | ||
1970 | DRM_INFO("Connector Table: %d (mac x800)\n", | ||
1971 | rdev->mode_info.connector_table); | ||
1972 | /* DVI - primary dac, internal tmds */ | ||
1973 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); | ||
1974 | hpd.hpd = RADEON_HPD_1; /* ??? */ | ||
1975 | radeon_add_legacy_encoder(dev, | ||
1976 | radeon_get_encoder_enum(dev, | ||
1977 | ATOM_DEVICE_DFP1_SUPPORT, | ||
1978 | 0), | ||
1979 | ATOM_DEVICE_DFP1_SUPPORT); | ||
1980 | radeon_add_legacy_encoder(dev, | ||
1981 | radeon_get_encoder_enum(dev, | ||
1982 | ATOM_DEVICE_CRT1_SUPPORT, | ||
1983 | 1), | ||
1984 | ATOM_DEVICE_CRT1_SUPPORT); | ||
1985 | radeon_add_legacy_connector(dev, 0, | ||
1986 | ATOM_DEVICE_DFP1_SUPPORT | | ||
1987 | ATOM_DEVICE_CRT1_SUPPORT, | ||
1988 | DRM_MODE_CONNECTOR_DVII, &ddc_i2c, | ||
1989 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, | ||
1990 | &hpd); | ||
1991 | /* DVI - tv dac, dvo */ | ||
1992 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0); | ||
1993 | hpd.hpd = RADEON_HPD_2; /* ??? */ | ||
1994 | radeon_add_legacy_encoder(dev, | ||
1995 | radeon_get_encoder_enum(dev, | ||
1996 | ATOM_DEVICE_DFP2_SUPPORT, | ||
1997 | 0), | ||
1998 | ATOM_DEVICE_DFP2_SUPPORT); | ||
1999 | radeon_add_legacy_encoder(dev, | ||
2000 | radeon_get_encoder_enum(dev, | ||
2001 | ATOM_DEVICE_CRT2_SUPPORT, | ||
2002 | 2), | ||
2003 | ATOM_DEVICE_CRT2_SUPPORT); | ||
2004 | radeon_add_legacy_connector(dev, 1, | ||
2005 | ATOM_DEVICE_DFP2_SUPPORT | | ||
2006 | ATOM_DEVICE_CRT2_SUPPORT, | ||
2007 | DRM_MODE_CONNECTOR_DVII, &ddc_i2c, | ||
2008 | CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I, | ||
2009 | &hpd); | ||
2010 | break; | ||
1964 | default: | 2011 | default: |
1965 | DRM_INFO("Connector table: %d (invalid)\n", | 2012 | DRM_INFO("Connector table: %d (invalid)\n", |
1966 | rdev->mode_info.connector_table); | 2013 | rdev->mode_info.connector_table); |
@@ -2109,7 +2156,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2109 | else | 2156 | else |
2110 | devices = ATOM_DEVICE_DFP1_SUPPORT; | 2157 | devices = ATOM_DEVICE_DFP1_SUPPORT; |
2111 | radeon_add_legacy_encoder(dev, | 2158 | radeon_add_legacy_encoder(dev, |
2112 | radeon_get_encoder_id | 2159 | radeon_get_encoder_enum |
2113 | (dev, devices, 0), | 2160 | (dev, devices, 0), |
2114 | devices); | 2161 | devices); |
2115 | radeon_add_legacy_connector(dev, i, devices, | 2162 | radeon_add_legacy_connector(dev, i, devices, |
@@ -2123,7 +2170,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2123 | if (tmp & 0x1) { | 2170 | if (tmp & 0x1) { |
2124 | devices = ATOM_DEVICE_CRT2_SUPPORT; | 2171 | devices = ATOM_DEVICE_CRT2_SUPPORT; |
2125 | radeon_add_legacy_encoder(dev, | 2172 | radeon_add_legacy_encoder(dev, |
2126 | radeon_get_encoder_id | 2173 | radeon_get_encoder_enum |
2127 | (dev, | 2174 | (dev, |
2128 | ATOM_DEVICE_CRT2_SUPPORT, | 2175 | ATOM_DEVICE_CRT2_SUPPORT, |
2129 | 2), | 2176 | 2), |
@@ -2131,7 +2178,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2131 | } else { | 2178 | } else { |
2132 | devices = ATOM_DEVICE_CRT1_SUPPORT; | 2179 | devices = ATOM_DEVICE_CRT1_SUPPORT; |
2133 | radeon_add_legacy_encoder(dev, | 2180 | radeon_add_legacy_encoder(dev, |
2134 | radeon_get_encoder_id | 2181 | radeon_get_encoder_enum |
2135 | (dev, | 2182 | (dev, |
2136 | ATOM_DEVICE_CRT1_SUPPORT, | 2183 | ATOM_DEVICE_CRT1_SUPPORT, |
2137 | 1), | 2184 | 1), |
@@ -2151,7 +2198,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2151 | if (tmp & 0x1) { | 2198 | if (tmp & 0x1) { |
2152 | devices |= ATOM_DEVICE_CRT2_SUPPORT; | 2199 | devices |= ATOM_DEVICE_CRT2_SUPPORT; |
2153 | radeon_add_legacy_encoder(dev, | 2200 | radeon_add_legacy_encoder(dev, |
2154 | radeon_get_encoder_id | 2201 | radeon_get_encoder_enum |
2155 | (dev, | 2202 | (dev, |
2156 | ATOM_DEVICE_CRT2_SUPPORT, | 2203 | ATOM_DEVICE_CRT2_SUPPORT, |
2157 | 2), | 2204 | 2), |
@@ -2159,7 +2206,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2159 | } else { | 2206 | } else { |
2160 | devices |= ATOM_DEVICE_CRT1_SUPPORT; | 2207 | devices |= ATOM_DEVICE_CRT1_SUPPORT; |
2161 | radeon_add_legacy_encoder(dev, | 2208 | radeon_add_legacy_encoder(dev, |
2162 | radeon_get_encoder_id | 2209 | radeon_get_encoder_enum |
2163 | (dev, | 2210 | (dev, |
2164 | ATOM_DEVICE_CRT1_SUPPORT, | 2211 | ATOM_DEVICE_CRT1_SUPPORT, |
2165 | 1), | 2212 | 1), |
@@ -2168,7 +2215,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2168 | if ((tmp >> 4) & 0x1) { | 2215 | if ((tmp >> 4) & 0x1) { |
2169 | devices |= ATOM_DEVICE_DFP2_SUPPORT; | 2216 | devices |= ATOM_DEVICE_DFP2_SUPPORT; |
2170 | radeon_add_legacy_encoder(dev, | 2217 | radeon_add_legacy_encoder(dev, |
2171 | radeon_get_encoder_id | 2218 | radeon_get_encoder_enum |
2172 | (dev, | 2219 | (dev, |
2173 | ATOM_DEVICE_DFP2_SUPPORT, | 2220 | ATOM_DEVICE_DFP2_SUPPORT, |
2174 | 0), | 2221 | 0), |
@@ -2177,7 +2224,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2177 | } else { | 2224 | } else { |
2178 | devices |= ATOM_DEVICE_DFP1_SUPPORT; | 2225 | devices |= ATOM_DEVICE_DFP1_SUPPORT; |
2179 | radeon_add_legacy_encoder(dev, | 2226 | radeon_add_legacy_encoder(dev, |
2180 | radeon_get_encoder_id | 2227 | radeon_get_encoder_enum |
2181 | (dev, | 2228 | (dev, |
2182 | ATOM_DEVICE_DFP1_SUPPORT, | 2229 | ATOM_DEVICE_DFP1_SUPPORT, |
2183 | 0), | 2230 | 0), |
@@ -2202,7 +2249,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2202 | connector_object_id = CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; | 2249 | connector_object_id = CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; |
2203 | } | 2250 | } |
2204 | radeon_add_legacy_encoder(dev, | 2251 | radeon_add_legacy_encoder(dev, |
2205 | radeon_get_encoder_id | 2252 | radeon_get_encoder_enum |
2206 | (dev, devices, 0), | 2253 | (dev, devices, 0), |
2207 | devices); | 2254 | devices); |
2208 | radeon_add_legacy_connector(dev, i, devices, | 2255 | radeon_add_legacy_connector(dev, i, devices, |
@@ -2215,7 +2262,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2215 | case CONNECTOR_CTV_LEGACY: | 2262 | case CONNECTOR_CTV_LEGACY: |
2216 | case CONNECTOR_STV_LEGACY: | 2263 | case CONNECTOR_STV_LEGACY: |
2217 | radeon_add_legacy_encoder(dev, | 2264 | radeon_add_legacy_encoder(dev, |
2218 | radeon_get_encoder_id | 2265 | radeon_get_encoder_enum |
2219 | (dev, | 2266 | (dev, |
2220 | ATOM_DEVICE_TV1_SUPPORT, | 2267 | ATOM_DEVICE_TV1_SUPPORT, |
2221 | 2), | 2268 | 2), |
@@ -2242,12 +2289,12 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2242 | DRM_DEBUG_KMS("Found DFP table, assuming DVI connector\n"); | 2289 | DRM_DEBUG_KMS("Found DFP table, assuming DVI connector\n"); |
2243 | 2290 | ||
2244 | radeon_add_legacy_encoder(dev, | 2291 | radeon_add_legacy_encoder(dev, |
2245 | radeon_get_encoder_id(dev, | 2292 | radeon_get_encoder_enum(dev, |
2246 | ATOM_DEVICE_CRT1_SUPPORT, | 2293 | ATOM_DEVICE_CRT1_SUPPORT, |
2247 | 1), | 2294 | 1), |
2248 | ATOM_DEVICE_CRT1_SUPPORT); | 2295 | ATOM_DEVICE_CRT1_SUPPORT); |
2249 | radeon_add_legacy_encoder(dev, | 2296 | radeon_add_legacy_encoder(dev, |
2250 | radeon_get_encoder_id(dev, | 2297 | radeon_get_encoder_enum(dev, |
2251 | ATOM_DEVICE_DFP1_SUPPORT, | 2298 | ATOM_DEVICE_DFP1_SUPPORT, |
2252 | 0), | 2299 | 0), |
2253 | ATOM_DEVICE_DFP1_SUPPORT); | 2300 | ATOM_DEVICE_DFP1_SUPPORT); |
@@ -2268,7 +2315,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2268 | DRM_DEBUG_KMS("Found CRT table, assuming VGA connector\n"); | 2315 | DRM_DEBUG_KMS("Found CRT table, assuming VGA connector\n"); |
2269 | if (crt_info) { | 2316 | if (crt_info) { |
2270 | radeon_add_legacy_encoder(dev, | 2317 | radeon_add_legacy_encoder(dev, |
2271 | radeon_get_encoder_id(dev, | 2318 | radeon_get_encoder_enum(dev, |
2272 | ATOM_DEVICE_CRT1_SUPPORT, | 2319 | ATOM_DEVICE_CRT1_SUPPORT, |
2273 | 1), | 2320 | 1), |
2274 | ATOM_DEVICE_CRT1_SUPPORT); | 2321 | ATOM_DEVICE_CRT1_SUPPORT); |
@@ -2297,7 +2344,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2297 | COMBIOS_LCD_DDC_INFO_TABLE); | 2344 | COMBIOS_LCD_DDC_INFO_TABLE); |
2298 | 2345 | ||
2299 | radeon_add_legacy_encoder(dev, | 2346 | radeon_add_legacy_encoder(dev, |
2300 | radeon_get_encoder_id(dev, | 2347 | radeon_get_encoder_enum(dev, |
2301 | ATOM_DEVICE_LCD1_SUPPORT, | 2348 | ATOM_DEVICE_LCD1_SUPPORT, |
2302 | 0), | 2349 | 0), |
2303 | ATOM_DEVICE_LCD1_SUPPORT); | 2350 | ATOM_DEVICE_LCD1_SUPPORT); |
@@ -2351,7 +2398,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2351 | hpd.hpd = RADEON_HPD_NONE; | 2398 | hpd.hpd = RADEON_HPD_NONE; |
2352 | ddc_i2c.valid = false; | 2399 | ddc_i2c.valid = false; |
2353 | radeon_add_legacy_encoder(dev, | 2400 | radeon_add_legacy_encoder(dev, |
2354 | radeon_get_encoder_id | 2401 | radeon_get_encoder_enum |
2355 | (dev, | 2402 | (dev, |
2356 | ATOM_DEVICE_TV1_SUPPORT, | 2403 | ATOM_DEVICE_TV1_SUPPORT, |
2357 | 2), | 2404 | 2), |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 47c4b276d30..ecc1a8fafbf 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -481,7 +481,8 @@ static int radeon_lvds_mode_valid(struct drm_connector *connector, | |||
481 | return MODE_OK; | 481 | return MODE_OK; |
482 | } | 482 | } |
483 | 483 | ||
484 | static enum drm_connector_status radeon_lvds_detect(struct drm_connector *connector) | 484 | static enum drm_connector_status |
485 | radeon_lvds_detect(struct drm_connector *connector, bool force) | ||
485 | { | 486 | { |
486 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 487 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
487 | struct drm_encoder *encoder = radeon_best_single_encoder(connector); | 488 | struct drm_encoder *encoder = radeon_best_single_encoder(connector); |
@@ -594,7 +595,8 @@ static int radeon_vga_mode_valid(struct drm_connector *connector, | |||
594 | return MODE_OK; | 595 | return MODE_OK; |
595 | } | 596 | } |
596 | 597 | ||
597 | static enum drm_connector_status radeon_vga_detect(struct drm_connector *connector) | 598 | static enum drm_connector_status |
599 | radeon_vga_detect(struct drm_connector *connector, bool force) | ||
598 | { | 600 | { |
599 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 601 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
600 | struct drm_encoder *encoder; | 602 | struct drm_encoder *encoder; |
@@ -691,7 +693,8 @@ static int radeon_tv_mode_valid(struct drm_connector *connector, | |||
691 | return MODE_OK; | 693 | return MODE_OK; |
692 | } | 694 | } |
693 | 695 | ||
694 | static enum drm_connector_status radeon_tv_detect(struct drm_connector *connector) | 696 | static enum drm_connector_status |
697 | radeon_tv_detect(struct drm_connector *connector, bool force) | ||
695 | { | 698 | { |
696 | struct drm_encoder *encoder; | 699 | struct drm_encoder *encoder; |
697 | struct drm_encoder_helper_funcs *encoder_funcs; | 700 | struct drm_encoder_helper_funcs *encoder_funcs; |
@@ -748,7 +751,8 @@ static int radeon_dvi_get_modes(struct drm_connector *connector) | |||
748 | * we have to check if this analog encoder is shared with anyone else (TV) | 751 | * we have to check if this analog encoder is shared with anyone else (TV) |
749 | * if its shared we have to set the other connector to disconnected. | 752 | * if its shared we have to set the other connector to disconnected. |
750 | */ | 753 | */ |
751 | static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connector) | 754 | static enum drm_connector_status |
755 | radeon_dvi_detect(struct drm_connector *connector, bool force) | ||
752 | { | 756 | { |
753 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 757 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
754 | struct drm_encoder *encoder = NULL; | 758 | struct drm_encoder *encoder = NULL; |
@@ -972,32 +976,35 @@ static int radeon_dp_get_modes(struct drm_connector *connector) | |||
972 | return ret; | 976 | return ret; |
973 | } | 977 | } |
974 | 978 | ||
975 | static enum drm_connector_status radeon_dp_detect(struct drm_connector *connector) | 979 | static enum drm_connector_status |
980 | radeon_dp_detect(struct drm_connector *connector, bool force) | ||
976 | { | 981 | { |
977 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 982 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
978 | enum drm_connector_status ret = connector_status_disconnected; | 983 | enum drm_connector_status ret = connector_status_disconnected; |
979 | struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; | 984 | struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; |
980 | u8 sink_type; | ||
981 | 985 | ||
982 | if (radeon_connector->edid) { | 986 | if (radeon_connector->edid) { |
983 | kfree(radeon_connector->edid); | 987 | kfree(radeon_connector->edid); |
984 | radeon_connector->edid = NULL; | 988 | radeon_connector->edid = NULL; |
985 | } | 989 | } |
986 | 990 | ||
987 | sink_type = radeon_dp_getsinktype(radeon_connector); | 991 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { |
988 | if ((sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || | 992 | /* eDP is always DP */ |
989 | (sink_type == CONNECTOR_OBJECT_ID_eDP)) { | 993 | radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT; |
990 | if (radeon_dp_getdpcd(radeon_connector)) { | 994 | if (radeon_dp_getdpcd(radeon_connector)) |
991 | radeon_dig_connector->dp_sink_type = sink_type; | ||
992 | ret = connector_status_connected; | 995 | ret = connector_status_connected; |
993 | } | ||
994 | } else { | 996 | } else { |
995 | if (radeon_ddc_probe(radeon_connector)) { | 997 | radeon_dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector); |
996 | radeon_dig_connector->dp_sink_type = sink_type; | 998 | if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) { |
997 | ret = connector_status_connected; | 999 | if (radeon_dp_getdpcd(radeon_connector)) |
1000 | ret = connector_status_connected; | ||
1001 | } else { | ||
1002 | if (radeon_ddc_probe(radeon_connector)) | ||
1003 | ret = connector_status_connected; | ||
998 | } | 1004 | } |
999 | } | 1005 | } |
1000 | 1006 | ||
1007 | radeon_connector_update_scratch_regs(connector, ret); | ||
1001 | return ret; | 1008 | return ret; |
1002 | } | 1009 | } |
1003 | 1010 | ||
@@ -1037,7 +1044,6 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1037 | uint32_t supported_device, | 1044 | uint32_t supported_device, |
1038 | int connector_type, | 1045 | int connector_type, |
1039 | struct radeon_i2c_bus_rec *i2c_bus, | 1046 | struct radeon_i2c_bus_rec *i2c_bus, |
1040 | bool linkb, | ||
1041 | uint32_t igp_lane_info, | 1047 | uint32_t igp_lane_info, |
1042 | uint16_t connector_object_id, | 1048 | uint16_t connector_object_id, |
1043 | struct radeon_hpd *hpd, | 1049 | struct radeon_hpd *hpd, |
@@ -1050,10 +1056,16 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1050 | uint32_t subpixel_order = SubPixelNone; | 1056 | uint32_t subpixel_order = SubPixelNone; |
1051 | bool shared_ddc = false; | 1057 | bool shared_ddc = false; |
1052 | 1058 | ||
1053 | /* fixme - tv/cv/din */ | ||
1054 | if (connector_type == DRM_MODE_CONNECTOR_Unknown) | 1059 | if (connector_type == DRM_MODE_CONNECTOR_Unknown) |
1055 | return; | 1060 | return; |
1056 | 1061 | ||
1062 | /* if the user selected tv=0 don't try and add the connector */ | ||
1063 | if (((connector_type == DRM_MODE_CONNECTOR_SVIDEO) || | ||
1064 | (connector_type == DRM_MODE_CONNECTOR_Composite) || | ||
1065 | (connector_type == DRM_MODE_CONNECTOR_9PinDIN)) && | ||
1066 | (radeon_tv == 0)) | ||
1067 | return; | ||
1068 | |||
1057 | /* see if we already added it */ | 1069 | /* see if we already added it */ |
1058 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 1070 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
1059 | radeon_connector = to_radeon_connector(connector); | 1071 | radeon_connector = to_radeon_connector(connector); |
@@ -1128,7 +1140,6 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1128 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); | 1140 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); |
1129 | if (!radeon_dig_connector) | 1141 | if (!radeon_dig_connector) |
1130 | goto failed; | 1142 | goto failed; |
1131 | radeon_dig_connector->linkb = linkb; | ||
1132 | radeon_dig_connector->igp_lane_info = igp_lane_info; | 1143 | radeon_dig_connector->igp_lane_info = igp_lane_info; |
1133 | radeon_connector->con_priv = radeon_dig_connector; | 1144 | radeon_connector->con_priv = radeon_dig_connector; |
1134 | drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); | 1145 | drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); |
@@ -1158,7 +1169,6 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1158 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); | 1169 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); |
1159 | if (!radeon_dig_connector) | 1170 | if (!radeon_dig_connector) |
1160 | goto failed; | 1171 | goto failed; |
1161 | radeon_dig_connector->linkb = linkb; | ||
1162 | radeon_dig_connector->igp_lane_info = igp_lane_info; | 1172 | radeon_dig_connector->igp_lane_info = igp_lane_info; |
1163 | radeon_connector->con_priv = radeon_dig_connector; | 1173 | radeon_connector->con_priv = radeon_dig_connector; |
1164 | drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); | 1174 | drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); |
@@ -1182,7 +1192,6 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1182 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); | 1192 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); |
1183 | if (!radeon_dig_connector) | 1193 | if (!radeon_dig_connector) |
1184 | goto failed; | 1194 | goto failed; |
1185 | radeon_dig_connector->linkb = linkb; | ||
1186 | radeon_dig_connector->igp_lane_info = igp_lane_info; | 1195 | radeon_dig_connector->igp_lane_info = igp_lane_info; |
1187 | radeon_connector->con_priv = radeon_dig_connector; | 1196 | radeon_connector->con_priv = radeon_dig_connector; |
1188 | drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type); | 1197 | drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type); |
@@ -1211,25 +1220,22 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1211 | case DRM_MODE_CONNECTOR_SVIDEO: | 1220 | case DRM_MODE_CONNECTOR_SVIDEO: |
1212 | case DRM_MODE_CONNECTOR_Composite: | 1221 | case DRM_MODE_CONNECTOR_Composite: |
1213 | case DRM_MODE_CONNECTOR_9PinDIN: | 1222 | case DRM_MODE_CONNECTOR_9PinDIN: |
1214 | if (radeon_tv == 1) { | 1223 | drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type); |
1215 | drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type); | 1224 | drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs); |
1216 | drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs); | 1225 | radeon_connector->dac_load_detect = true; |
1217 | radeon_connector->dac_load_detect = true; | 1226 | drm_connector_attach_property(&radeon_connector->base, |
1218 | drm_connector_attach_property(&radeon_connector->base, | 1227 | rdev->mode_info.load_detect_property, |
1219 | rdev->mode_info.load_detect_property, | 1228 | 1); |
1220 | 1); | 1229 | drm_connector_attach_property(&radeon_connector->base, |
1221 | drm_connector_attach_property(&radeon_connector->base, | 1230 | rdev->mode_info.tv_std_property, |
1222 | rdev->mode_info.tv_std_property, | 1231 | radeon_atombios_get_tv_info(rdev)); |
1223 | radeon_atombios_get_tv_info(rdev)); | 1232 | /* no HPD on analog connectors */ |
1224 | /* no HPD on analog connectors */ | 1233 | radeon_connector->hpd.hpd = RADEON_HPD_NONE; |
1225 | radeon_connector->hpd.hpd = RADEON_HPD_NONE; | ||
1226 | } | ||
1227 | break; | 1234 | break; |
1228 | case DRM_MODE_CONNECTOR_LVDS: | 1235 | case DRM_MODE_CONNECTOR_LVDS: |
1229 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); | 1236 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); |
1230 | if (!radeon_dig_connector) | 1237 | if (!radeon_dig_connector) |
1231 | goto failed; | 1238 | goto failed; |
1232 | radeon_dig_connector->linkb = linkb; | ||
1233 | radeon_dig_connector->igp_lane_info = igp_lane_info; | 1239 | radeon_dig_connector->igp_lane_info = igp_lane_info; |
1234 | radeon_connector->con_priv = radeon_dig_connector; | 1240 | radeon_connector->con_priv = radeon_dig_connector; |
1235 | drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); | 1241 | drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); |
@@ -1275,10 +1281,16 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
1275 | struct radeon_connector *radeon_connector; | 1281 | struct radeon_connector *radeon_connector; |
1276 | uint32_t subpixel_order = SubPixelNone; | 1282 | uint32_t subpixel_order = SubPixelNone; |
1277 | 1283 | ||
1278 | /* fixme - tv/cv/din */ | ||
1279 | if (connector_type == DRM_MODE_CONNECTOR_Unknown) | 1284 | if (connector_type == DRM_MODE_CONNECTOR_Unknown) |
1280 | return; | 1285 | return; |
1281 | 1286 | ||
1287 | /* if the user selected tv=0 don't try and add the connector */ | ||
1288 | if (((connector_type == DRM_MODE_CONNECTOR_SVIDEO) || | ||
1289 | (connector_type == DRM_MODE_CONNECTOR_Composite) || | ||
1290 | (connector_type == DRM_MODE_CONNECTOR_9PinDIN)) && | ||
1291 | (radeon_tv == 0)) | ||
1292 | return; | ||
1293 | |||
1282 | /* see if we already added it */ | 1294 | /* see if we already added it */ |
1283 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 1295 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
1284 | radeon_connector = to_radeon_connector(connector); | 1296 | radeon_connector = to_radeon_connector(connector); |
@@ -1350,26 +1362,24 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
1350 | case DRM_MODE_CONNECTOR_SVIDEO: | 1362 | case DRM_MODE_CONNECTOR_SVIDEO: |
1351 | case DRM_MODE_CONNECTOR_Composite: | 1363 | case DRM_MODE_CONNECTOR_Composite: |
1352 | case DRM_MODE_CONNECTOR_9PinDIN: | 1364 | case DRM_MODE_CONNECTOR_9PinDIN: |
1353 | if (radeon_tv == 1) { | 1365 | drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type); |
1354 | drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type); | 1366 | drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs); |
1355 | drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs); | 1367 | radeon_connector->dac_load_detect = true; |
1356 | radeon_connector->dac_load_detect = true; | 1368 | /* RS400,RC410,RS480 chipset seems to report a lot |
1357 | /* RS400,RC410,RS480 chipset seems to report a lot | 1369 | * of false positive on load detect, we haven't yet |
1358 | * of false positive on load detect, we haven't yet | 1370 | * found a way to make load detect reliable on those |
1359 | * found a way to make load detect reliable on those | 1371 | * chipset, thus just disable it for TV. |
1360 | * chipset, thus just disable it for TV. | 1372 | */ |
1361 | */ | 1373 | if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480) |
1362 | if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480) | 1374 | radeon_connector->dac_load_detect = false; |
1363 | radeon_connector->dac_load_detect = false; | 1375 | drm_connector_attach_property(&radeon_connector->base, |
1364 | drm_connector_attach_property(&radeon_connector->base, | 1376 | rdev->mode_info.load_detect_property, |
1365 | rdev->mode_info.load_detect_property, | 1377 | radeon_connector->dac_load_detect); |
1366 | radeon_connector->dac_load_detect); | 1378 | drm_connector_attach_property(&radeon_connector->base, |
1367 | drm_connector_attach_property(&radeon_connector->base, | 1379 | rdev->mode_info.tv_std_property, |
1368 | rdev->mode_info.tv_std_property, | 1380 | radeon_combios_get_tv_info(rdev)); |
1369 | radeon_combios_get_tv_info(rdev)); | 1381 | /* no HPD on analog connectors */ |
1370 | /* no HPD on analog connectors */ | 1382 | radeon_connector->hpd.hpd = RADEON_HPD_NONE; |
1371 | radeon_connector->hpd.hpd = RADEON_HPD_NONE; | ||
1372 | } | ||
1373 | break; | 1383 | break; |
1374 | case DRM_MODE_CONNECTOR_LVDS: | 1384 | case DRM_MODE_CONNECTOR_LVDS: |
1375 | drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); | 1385 | drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 4f7a170d156..256d204a6d2 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -199,7 +199,7 @@ void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 | |||
199 | mc->mc_vram_size = mc->aper_size; | 199 | mc->mc_vram_size = mc->aper_size; |
200 | } | 200 | } |
201 | mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; | 201 | mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; |
202 | if (rdev->flags & RADEON_IS_AGP && mc->vram_end > mc->gtt_start && mc->vram_end <= mc->gtt_end) { | 202 | if (rdev->flags & RADEON_IS_AGP && mc->vram_end > mc->gtt_start && mc->vram_start <= mc->gtt_end) { |
203 | dev_warn(rdev->dev, "limiting VRAM to PCI aperture size\n"); | 203 | dev_warn(rdev->dev, "limiting VRAM to PCI aperture size\n"); |
204 | mc->real_vram_size = mc->aper_size; | 204 | mc->real_vram_size = mc->aper_size; |
205 | mc->mc_vram_size = mc->aper_size; | 205 | mc->mc_vram_size = mc->aper_size; |
@@ -293,30 +293,20 @@ bool radeon_card_posted(struct radeon_device *rdev) | |||
293 | void radeon_update_bandwidth_info(struct radeon_device *rdev) | 293 | void radeon_update_bandwidth_info(struct radeon_device *rdev) |
294 | { | 294 | { |
295 | fixed20_12 a; | 295 | fixed20_12 a; |
296 | u32 sclk, mclk; | 296 | u32 sclk = rdev->pm.current_sclk; |
297 | u32 mclk = rdev->pm.current_mclk; | ||
297 | 298 | ||
298 | if (rdev->flags & RADEON_IS_IGP) { | 299 | /* sclk/mclk in Mhz */ |
299 | sclk = radeon_get_engine_clock(rdev); | 300 | a.full = dfixed_const(100); |
300 | mclk = rdev->clock.default_mclk; | 301 | rdev->pm.sclk.full = dfixed_const(sclk); |
301 | 302 | rdev->pm.sclk.full = dfixed_div(rdev->pm.sclk, a); | |
302 | a.full = dfixed_const(100); | 303 | rdev->pm.mclk.full = dfixed_const(mclk); |
303 | rdev->pm.sclk.full = dfixed_const(sclk); | 304 | rdev->pm.mclk.full = dfixed_div(rdev->pm.mclk, a); |
304 | rdev->pm.sclk.full = dfixed_div(rdev->pm.sclk, a); | ||
305 | rdev->pm.mclk.full = dfixed_const(mclk); | ||
306 | rdev->pm.mclk.full = dfixed_div(rdev->pm.mclk, a); | ||
307 | 305 | ||
306 | if (rdev->flags & RADEON_IS_IGP) { | ||
308 | a.full = dfixed_const(16); | 307 | a.full = dfixed_const(16); |
309 | /* core_bandwidth = sclk(Mhz) * 16 */ | 308 | /* core_bandwidth = sclk(Mhz) * 16 */ |
310 | rdev->pm.core_bandwidth.full = dfixed_div(rdev->pm.sclk, a); | 309 | rdev->pm.core_bandwidth.full = dfixed_div(rdev->pm.sclk, a); |
311 | } else { | ||
312 | sclk = radeon_get_engine_clock(rdev); | ||
313 | mclk = radeon_get_memory_clock(rdev); | ||
314 | |||
315 | a.full = dfixed_const(100); | ||
316 | rdev->pm.sclk.full = dfixed_const(sclk); | ||
317 | rdev->pm.sclk.full = dfixed_div(rdev->pm.sclk, a); | ||
318 | rdev->pm.mclk.full = dfixed_const(mclk); | ||
319 | rdev->pm.mclk.full = dfixed_div(rdev->pm.mclk, a); | ||
320 | } | 310 | } |
321 | } | 311 | } |
322 | 312 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 5764f4d3b4f..b92d2f2fcbe 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -349,6 +349,8 @@ static void radeon_print_display_setup(struct drm_device *dev) | |||
349 | DRM_INFO(" DFP4: %s\n", encoder_names[radeon_encoder->encoder_id]); | 349 | DRM_INFO(" DFP4: %s\n", encoder_names[radeon_encoder->encoder_id]); |
350 | if (devices & ATOM_DEVICE_DFP5_SUPPORT) | 350 | if (devices & ATOM_DEVICE_DFP5_SUPPORT) |
351 | DRM_INFO(" DFP5: %s\n", encoder_names[radeon_encoder->encoder_id]); | 351 | DRM_INFO(" DFP5: %s\n", encoder_names[radeon_encoder->encoder_id]); |
352 | if (devices & ATOM_DEVICE_DFP6_SUPPORT) | ||
353 | DRM_INFO(" DFP6: %s\n", encoder_names[radeon_encoder->encoder_id]); | ||
352 | if (devices & ATOM_DEVICE_TV1_SUPPORT) | 354 | if (devices & ATOM_DEVICE_TV1_SUPPORT) |
353 | DRM_INFO(" TV1: %s\n", encoder_names[radeon_encoder->encoder_id]); | 355 | DRM_INFO(" TV1: %s\n", encoder_names[radeon_encoder->encoder_id]); |
354 | if (devices & ATOM_DEVICE_CV_SUPPORT) | 356 | if (devices & ATOM_DEVICE_CV_SUPPORT) |
@@ -841,8 +843,9 @@ static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb) | |||
841 | { | 843 | { |
842 | struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb); | 844 | struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb); |
843 | 845 | ||
844 | if (radeon_fb->obj) | 846 | if (radeon_fb->obj) { |
845 | drm_gem_object_unreference_unlocked(radeon_fb->obj); | 847 | drm_gem_object_unreference_unlocked(radeon_fb->obj); |
848 | } | ||
846 | drm_framebuffer_cleanup(fb); | 849 | drm_framebuffer_cleanup(fb); |
847 | kfree(radeon_fb); | 850 | kfree(radeon_fb); |
848 | } | 851 | } |
@@ -1094,6 +1097,18 @@ void radeon_modeset_fini(struct radeon_device *rdev) | |||
1094 | radeon_i2c_fini(rdev); | 1097 | radeon_i2c_fini(rdev); |
1095 | } | 1098 | } |
1096 | 1099 | ||
1100 | static bool is_hdtv_mode(struct drm_display_mode *mode) | ||
1101 | { | ||
1102 | /* try and guess if this is a tv or a monitor */ | ||
1103 | if ((mode->vdisplay == 480 && mode->hdisplay == 720) || /* 480p */ | ||
1104 | (mode->vdisplay == 576) || /* 576p */ | ||
1105 | (mode->vdisplay == 720) || /* 720p */ | ||
1106 | (mode->vdisplay == 1080)) /* 1080p */ | ||
1107 | return true; | ||
1108 | else | ||
1109 | return false; | ||
1110 | } | ||
1111 | |||
1097 | bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, | 1112 | bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, |
1098 | struct drm_display_mode *mode, | 1113 | struct drm_display_mode *mode, |
1099 | struct drm_display_mode *adjusted_mode) | 1114 | struct drm_display_mode *adjusted_mode) |
@@ -1128,20 +1143,22 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, | |||
1128 | radeon_crtc->rmx_type = radeon_encoder->rmx_type; | 1143 | radeon_crtc->rmx_type = radeon_encoder->rmx_type; |
1129 | else | 1144 | else |
1130 | radeon_crtc->rmx_type = RMX_OFF; | 1145 | radeon_crtc->rmx_type = RMX_OFF; |
1131 | src_v = crtc->mode.vdisplay; | ||
1132 | dst_v = radeon_crtc->native_mode.vdisplay; | ||
1133 | src_h = crtc->mode.hdisplay; | ||
1134 | dst_h = radeon_crtc->native_mode.vdisplay; | ||
1135 | /* copy native mode */ | 1146 | /* copy native mode */ |
1136 | memcpy(&radeon_crtc->native_mode, | 1147 | memcpy(&radeon_crtc->native_mode, |
1137 | &radeon_encoder->native_mode, | 1148 | &radeon_encoder->native_mode, |
1138 | sizeof(struct drm_display_mode)); | 1149 | sizeof(struct drm_display_mode)); |
1150 | src_v = crtc->mode.vdisplay; | ||
1151 | dst_v = radeon_crtc->native_mode.vdisplay; | ||
1152 | src_h = crtc->mode.hdisplay; | ||
1153 | dst_h = radeon_crtc->native_mode.hdisplay; | ||
1139 | 1154 | ||
1140 | /* fix up for overscan on hdmi */ | 1155 | /* fix up for overscan on hdmi */ |
1141 | if (ASIC_IS_AVIVO(rdev) && | 1156 | if (ASIC_IS_AVIVO(rdev) && |
1157 | (!(mode->flags & DRM_MODE_FLAG_INTERLACE)) && | ||
1142 | ((radeon_encoder->underscan_type == UNDERSCAN_ON) || | 1158 | ((radeon_encoder->underscan_type == UNDERSCAN_ON) || |
1143 | ((radeon_encoder->underscan_type == UNDERSCAN_AUTO) && | 1159 | ((radeon_encoder->underscan_type == UNDERSCAN_AUTO) && |
1144 | drm_detect_hdmi_monitor(radeon_connector->edid)))) { | 1160 | drm_detect_hdmi_monitor(radeon_connector->edid) && |
1161 | is_hdtv_mode(mode)))) { | ||
1145 | radeon_crtc->h_border = (mode->hdisplay >> 5) + 16; | 1162 | radeon_crtc->h_border = (mode->hdisplay >> 5) + 16; |
1146 | radeon_crtc->v_border = (mode->vdisplay >> 5) + 16; | 1163 | radeon_crtc->v_border = (mode->vdisplay >> 5) + 16; |
1147 | radeon_crtc->rmx_type = RMX_FULL; | 1164 | radeon_crtc->rmx_type = RMX_FULL; |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 263c8098d7d..2c293e8304d 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
@@ -81,7 +81,7 @@ void radeon_setup_encoder_clones(struct drm_device *dev) | |||
81 | } | 81 | } |
82 | 82 | ||
83 | uint32_t | 83 | uint32_t |
84 | radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, uint8_t dac) | 84 | radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, uint8_t dac) |
85 | { | 85 | { |
86 | struct radeon_device *rdev = dev->dev_private; | 86 | struct radeon_device *rdev = dev->dev_private; |
87 | uint32_t ret = 0; | 87 | uint32_t ret = 0; |
@@ -97,59 +97,59 @@ radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, uint8_t | |||
97 | if ((rdev->family == CHIP_RS300) || | 97 | if ((rdev->family == CHIP_RS300) || |
98 | (rdev->family == CHIP_RS400) || | 98 | (rdev->family == CHIP_RS400) || |
99 | (rdev->family == CHIP_RS480)) | 99 | (rdev->family == CHIP_RS480)) |
100 | ret = ENCODER_OBJECT_ID_INTERNAL_DAC2; | 100 | ret = ENCODER_INTERNAL_DAC2_ENUM_ID1; |
101 | else if (ASIC_IS_AVIVO(rdev)) | 101 | else if (ASIC_IS_AVIVO(rdev)) |
102 | ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1; | 102 | ret = ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1; |
103 | else | 103 | else |
104 | ret = ENCODER_OBJECT_ID_INTERNAL_DAC1; | 104 | ret = ENCODER_INTERNAL_DAC1_ENUM_ID1; |
105 | break; | 105 | break; |
106 | case 2: /* dac b */ | 106 | case 2: /* dac b */ |
107 | if (ASIC_IS_AVIVO(rdev)) | 107 | if (ASIC_IS_AVIVO(rdev)) |
108 | ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2; | 108 | ret = ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1; |
109 | else { | 109 | else { |
110 | /*if (rdev->family == CHIP_R200) | 110 | /*if (rdev->family == CHIP_R200) |
111 | ret = ENCODER_OBJECT_ID_INTERNAL_DVO1; | 111 | ret = ENCODER_INTERNAL_DVO1_ENUM_ID1; |
112 | else*/ | 112 | else*/ |
113 | ret = ENCODER_OBJECT_ID_INTERNAL_DAC2; | 113 | ret = ENCODER_INTERNAL_DAC2_ENUM_ID1; |
114 | } | 114 | } |
115 | break; | 115 | break; |
116 | case 3: /* external dac */ | 116 | case 3: /* external dac */ |
117 | if (ASIC_IS_AVIVO(rdev)) | 117 | if (ASIC_IS_AVIVO(rdev)) |
118 | ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1; | 118 | ret = ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1; |
119 | else | 119 | else |
120 | ret = ENCODER_OBJECT_ID_INTERNAL_DVO1; | 120 | ret = ENCODER_INTERNAL_DVO1_ENUM_ID1; |
121 | break; | 121 | break; |
122 | } | 122 | } |
123 | break; | 123 | break; |
124 | case ATOM_DEVICE_LCD1_SUPPORT: | 124 | case ATOM_DEVICE_LCD1_SUPPORT: |
125 | if (ASIC_IS_AVIVO(rdev)) | 125 | if (ASIC_IS_AVIVO(rdev)) |
126 | ret = ENCODER_OBJECT_ID_INTERNAL_LVTM1; | 126 | ret = ENCODER_INTERNAL_LVTM1_ENUM_ID1; |
127 | else | 127 | else |
128 | ret = ENCODER_OBJECT_ID_INTERNAL_LVDS; | 128 | ret = ENCODER_INTERNAL_LVDS_ENUM_ID1; |
129 | break; | 129 | break; |
130 | case ATOM_DEVICE_DFP1_SUPPORT: | 130 | case ATOM_DEVICE_DFP1_SUPPORT: |
131 | if ((rdev->family == CHIP_RS300) || | 131 | if ((rdev->family == CHIP_RS300) || |
132 | (rdev->family == CHIP_RS400) || | 132 | (rdev->family == CHIP_RS400) || |
133 | (rdev->family == CHIP_RS480)) | 133 | (rdev->family == CHIP_RS480)) |
134 | ret = ENCODER_OBJECT_ID_INTERNAL_DVO1; | 134 | ret = ENCODER_INTERNAL_DVO1_ENUM_ID1; |
135 | else if (ASIC_IS_AVIVO(rdev)) | 135 | else if (ASIC_IS_AVIVO(rdev)) |
136 | ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1; | 136 | ret = ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1; |
137 | else | 137 | else |
138 | ret = ENCODER_OBJECT_ID_INTERNAL_TMDS1; | 138 | ret = ENCODER_INTERNAL_TMDS1_ENUM_ID1; |
139 | break; | 139 | break; |
140 | case ATOM_DEVICE_LCD2_SUPPORT: | 140 | case ATOM_DEVICE_LCD2_SUPPORT: |
141 | case ATOM_DEVICE_DFP2_SUPPORT: | 141 | case ATOM_DEVICE_DFP2_SUPPORT: |
142 | if ((rdev->family == CHIP_RS600) || | 142 | if ((rdev->family == CHIP_RS600) || |
143 | (rdev->family == CHIP_RS690) || | 143 | (rdev->family == CHIP_RS690) || |
144 | (rdev->family == CHIP_RS740)) | 144 | (rdev->family == CHIP_RS740)) |
145 | ret = ENCODER_OBJECT_ID_INTERNAL_DDI; | 145 | ret = ENCODER_INTERNAL_DDI_ENUM_ID1; |
146 | else if (ASIC_IS_AVIVO(rdev)) | 146 | else if (ASIC_IS_AVIVO(rdev)) |
147 | ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1; | 147 | ret = ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1; |
148 | else | 148 | else |
149 | ret = ENCODER_OBJECT_ID_INTERNAL_DVO1; | 149 | ret = ENCODER_INTERNAL_DVO1_ENUM_ID1; |
150 | break; | 150 | break; |
151 | case ATOM_DEVICE_DFP3_SUPPORT: | 151 | case ATOM_DEVICE_DFP3_SUPPORT: |
152 | ret = ENCODER_OBJECT_ID_INTERNAL_LVTM1; | 152 | ret = ENCODER_INTERNAL_LVTM1_ENUM_ID1; |
153 | break; | 153 | break; |
154 | } | 154 | } |
155 | 155 | ||
@@ -228,32 +228,6 @@ radeon_get_connector_for_encoder(struct drm_encoder *encoder) | |||
228 | return NULL; | 228 | return NULL; |
229 | } | 229 | } |
230 | 230 | ||
231 | static struct radeon_connector_atom_dig * | ||
232 | radeon_get_atom_connector_priv_from_encoder(struct drm_encoder *encoder) | ||
233 | { | ||
234 | struct drm_device *dev = encoder->dev; | ||
235 | struct radeon_device *rdev = dev->dev_private; | ||
236 | struct drm_connector *connector; | ||
237 | struct radeon_connector *radeon_connector; | ||
238 | struct radeon_connector_atom_dig *dig_connector; | ||
239 | |||
240 | if (!rdev->is_atom_bios) | ||
241 | return NULL; | ||
242 | |||
243 | connector = radeon_get_connector_for_encoder(encoder); | ||
244 | if (!connector) | ||
245 | return NULL; | ||
246 | |||
247 | radeon_connector = to_radeon_connector(connector); | ||
248 | |||
249 | if (!radeon_connector->con_priv) | ||
250 | return NULL; | ||
251 | |||
252 | dig_connector = radeon_connector->con_priv; | ||
253 | |||
254 | return dig_connector; | ||
255 | } | ||
256 | |||
257 | void radeon_panel_mode_fixup(struct drm_encoder *encoder, | 231 | void radeon_panel_mode_fixup(struct drm_encoder *encoder, |
258 | struct drm_display_mode *adjusted_mode) | 232 | struct drm_display_mode *adjusted_mode) |
259 | { | 233 | { |
@@ -512,14 +486,12 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) | |||
512 | struct radeon_device *rdev = dev->dev_private; | 486 | struct radeon_device *rdev = dev->dev_private; |
513 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 487 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
514 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 488 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
515 | struct radeon_connector_atom_dig *dig_connector = | ||
516 | radeon_get_atom_connector_priv_from_encoder(encoder); | ||
517 | union lvds_encoder_control args; | 489 | union lvds_encoder_control args; |
518 | int index = 0; | 490 | int index = 0; |
519 | int hdmi_detected = 0; | 491 | int hdmi_detected = 0; |
520 | uint8_t frev, crev; | 492 | uint8_t frev, crev; |
521 | 493 | ||
522 | if (!dig || !dig_connector) | 494 | if (!dig) |
523 | return; | 495 | return; |
524 | 496 | ||
525 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) | 497 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) |
@@ -562,7 +534,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) | |||
562 | if (dig->lvds_misc & ATOM_PANEL_MISC_888RGB) | 534 | if (dig->lvds_misc & ATOM_PANEL_MISC_888RGB) |
563 | args.v1.ucMisc |= (1 << 1); | 535 | args.v1.ucMisc |= (1 << 1); |
564 | } else { | 536 | } else { |
565 | if (dig_connector->linkb) | 537 | if (dig->linkb) |
566 | args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; | 538 | args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; |
567 | if (radeon_encoder->pixel_clock > 165000) | 539 | if (radeon_encoder->pixel_clock > 165000) |
568 | args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; | 540 | args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; |
@@ -601,7 +573,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) | |||
601 | args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_LEVEL_4; | 573 | args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_LEVEL_4; |
602 | } | 574 | } |
603 | } else { | 575 | } else { |
604 | if (dig_connector->linkb) | 576 | if (dig->linkb) |
605 | args.v2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; | 577 | args.v2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; |
606 | if (radeon_encoder->pixel_clock > 165000) | 578 | if (radeon_encoder->pixel_clock > 165000) |
607 | args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL; | 579 | args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL; |
@@ -623,6 +595,8 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) | |||
623 | int | 595 | int |
624 | atombios_get_encoder_mode(struct drm_encoder *encoder) | 596 | atombios_get_encoder_mode(struct drm_encoder *encoder) |
625 | { | 597 | { |
598 | struct drm_device *dev = encoder->dev; | ||
599 | struct radeon_device *rdev = dev->dev_private; | ||
626 | struct drm_connector *connector; | 600 | struct drm_connector *connector; |
627 | struct radeon_connector *radeon_connector; | 601 | struct radeon_connector *radeon_connector; |
628 | struct radeon_connector_atom_dig *dig_connector; | 602 | struct radeon_connector_atom_dig *dig_connector; |
@@ -636,9 +610,13 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
636 | switch (connector->connector_type) { | 610 | switch (connector->connector_type) { |
637 | case DRM_MODE_CONNECTOR_DVII: | 611 | case DRM_MODE_CONNECTOR_DVII: |
638 | case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */ | 612 | case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */ |
639 | if (drm_detect_hdmi_monitor(radeon_connector->edid)) | 613 | if (drm_detect_hdmi_monitor(radeon_connector->edid)) { |
640 | return ATOM_ENCODER_MODE_HDMI; | 614 | /* fix me */ |
641 | else if (radeon_connector->use_digital) | 615 | if (ASIC_IS_DCE4(rdev)) |
616 | return ATOM_ENCODER_MODE_DVI; | ||
617 | else | ||
618 | return ATOM_ENCODER_MODE_HDMI; | ||
619 | } else if (radeon_connector->use_digital) | ||
642 | return ATOM_ENCODER_MODE_DVI; | 620 | return ATOM_ENCODER_MODE_DVI; |
643 | else | 621 | else |
644 | return ATOM_ENCODER_MODE_CRT; | 622 | return ATOM_ENCODER_MODE_CRT; |
@@ -646,9 +624,13 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
646 | case DRM_MODE_CONNECTOR_DVID: | 624 | case DRM_MODE_CONNECTOR_DVID: |
647 | case DRM_MODE_CONNECTOR_HDMIA: | 625 | case DRM_MODE_CONNECTOR_HDMIA: |
648 | default: | 626 | default: |
649 | if (drm_detect_hdmi_monitor(radeon_connector->edid)) | 627 | if (drm_detect_hdmi_monitor(radeon_connector->edid)) { |
650 | return ATOM_ENCODER_MODE_HDMI; | 628 | /* fix me */ |
651 | else | 629 | if (ASIC_IS_DCE4(rdev)) |
630 | return ATOM_ENCODER_MODE_DVI; | ||
631 | else | ||
632 | return ATOM_ENCODER_MODE_HDMI; | ||
633 | } else | ||
652 | return ATOM_ENCODER_MODE_DVI; | 634 | return ATOM_ENCODER_MODE_DVI; |
653 | break; | 635 | break; |
654 | case DRM_MODE_CONNECTOR_LVDS: | 636 | case DRM_MODE_CONNECTOR_LVDS: |
@@ -660,9 +642,13 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
660 | if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || | 642 | if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || |
661 | (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) | 643 | (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) |
662 | return ATOM_ENCODER_MODE_DP; | 644 | return ATOM_ENCODER_MODE_DP; |
663 | else if (drm_detect_hdmi_monitor(radeon_connector->edid)) | 645 | else if (drm_detect_hdmi_monitor(radeon_connector->edid)) { |
664 | return ATOM_ENCODER_MODE_HDMI; | 646 | /* fix me */ |
665 | else | 647 | if (ASIC_IS_DCE4(rdev)) |
648 | return ATOM_ENCODER_MODE_DVI; | ||
649 | else | ||
650 | return ATOM_ENCODER_MODE_HDMI; | ||
651 | } else | ||
666 | return ATOM_ENCODER_MODE_DVI; | 652 | return ATOM_ENCODER_MODE_DVI; |
667 | break; | 653 | break; |
668 | case DRM_MODE_CONNECTOR_DVIA: | 654 | case DRM_MODE_CONNECTOR_DVIA: |
@@ -729,13 +715,24 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | |||
729 | struct radeon_device *rdev = dev->dev_private; | 715 | struct radeon_device *rdev = dev->dev_private; |
730 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 716 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
731 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 717 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
732 | struct radeon_connector_atom_dig *dig_connector = | 718 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); |
733 | radeon_get_atom_connector_priv_from_encoder(encoder); | ||
734 | union dig_encoder_control args; | 719 | union dig_encoder_control args; |
735 | int index = 0; | 720 | int index = 0; |
736 | uint8_t frev, crev; | 721 | uint8_t frev, crev; |
722 | int dp_clock = 0; | ||
723 | int dp_lane_count = 0; | ||
724 | |||
725 | if (connector) { | ||
726 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
727 | struct radeon_connector_atom_dig *dig_connector = | ||
728 | radeon_connector->con_priv; | ||
737 | 729 | ||
738 | if (!dig || !dig_connector) | 730 | dp_clock = dig_connector->dp_clock; |
731 | dp_lane_count = dig_connector->dp_lane_count; | ||
732 | } | ||
733 | |||
734 | /* no dig encoder assigned */ | ||
735 | if (dig->dig_encoder == -1) | ||
739 | return; | 736 | return; |
740 | 737 | ||
741 | memset(&args, 0, sizeof(args)); | 738 | memset(&args, 0, sizeof(args)); |
@@ -757,9 +754,9 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | |||
757 | args.v1.ucEncoderMode = atombios_get_encoder_mode(encoder); | 754 | args.v1.ucEncoderMode = atombios_get_encoder_mode(encoder); |
758 | 755 | ||
759 | if (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) { | 756 | if (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) { |
760 | if (dig_connector->dp_clock == 270000) | 757 | if (dp_clock == 270000) |
761 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; | 758 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; |
762 | args.v1.ucLaneNum = dig_connector->dp_lane_count; | 759 | args.v1.ucLaneNum = dp_lane_count; |
763 | } else if (radeon_encoder->pixel_clock > 165000) | 760 | } else if (radeon_encoder->pixel_clock > 165000) |
764 | args.v1.ucLaneNum = 8; | 761 | args.v1.ucLaneNum = 8; |
765 | else | 762 | else |
@@ -781,7 +778,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | |||
781 | args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3; | 778 | args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3; |
782 | break; | 779 | break; |
783 | } | 780 | } |
784 | if (dig_connector->linkb) | 781 | if (dig->linkb) |
785 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKB; | 782 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKB; |
786 | else | 783 | else |
787 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKA; | 784 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKA; |
@@ -804,38 +801,47 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
804 | struct radeon_device *rdev = dev->dev_private; | 801 | struct radeon_device *rdev = dev->dev_private; |
805 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 802 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
806 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 803 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
807 | struct radeon_connector_atom_dig *dig_connector = | 804 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); |
808 | radeon_get_atom_connector_priv_from_encoder(encoder); | ||
809 | struct drm_connector *connector; | ||
810 | struct radeon_connector *radeon_connector; | ||
811 | union dig_transmitter_control args; | 805 | union dig_transmitter_control args; |
812 | int index = 0; | 806 | int index = 0; |
813 | uint8_t frev, crev; | 807 | uint8_t frev, crev; |
814 | bool is_dp = false; | 808 | bool is_dp = false; |
815 | int pll_id = 0; | 809 | int pll_id = 0; |
810 | int dp_clock = 0; | ||
811 | int dp_lane_count = 0; | ||
812 | int connector_object_id = 0; | ||
813 | int igp_lane_info = 0; | ||
816 | 814 | ||
817 | if (!dig || !dig_connector) | 815 | if (connector) { |
818 | return; | 816 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
817 | struct radeon_connector_atom_dig *dig_connector = | ||
818 | radeon_connector->con_priv; | ||
819 | 819 | ||
820 | connector = radeon_get_connector_for_encoder(encoder); | 820 | dp_clock = dig_connector->dp_clock; |
821 | radeon_connector = to_radeon_connector(connector); | 821 | dp_lane_count = dig_connector->dp_lane_count; |
822 | connector_object_id = | ||
823 | (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; | ||
824 | igp_lane_info = dig_connector->igp_lane_info; | ||
825 | } | ||
826 | |||
827 | /* no dig encoder assigned */ | ||
828 | if (dig->dig_encoder == -1) | ||
829 | return; | ||
822 | 830 | ||
823 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) | 831 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) |
824 | is_dp = true; | 832 | is_dp = true; |
825 | 833 | ||
826 | memset(&args, 0, sizeof(args)); | 834 | memset(&args, 0, sizeof(args)); |
827 | 835 | ||
828 | if (ASIC_IS_DCE32(rdev) || ASIC_IS_DCE4(rdev)) | 836 | switch (radeon_encoder->encoder_id) { |
837 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
838 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
839 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
829 | index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl); | 840 | index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl); |
830 | else { | 841 | break; |
831 | switch (radeon_encoder->encoder_id) { | 842 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
832 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | 843 | index = GetIndexIntoMasterTable(COMMAND, LVTMATransmitterControl); |
833 | index = GetIndexIntoMasterTable(COMMAND, DIG1TransmitterControl); | 844 | break; |
834 | break; | ||
835 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
836 | index = GetIndexIntoMasterTable(COMMAND, DIG2TransmitterControl); | ||
837 | break; | ||
838 | } | ||
839 | } | 845 | } |
840 | 846 | ||
841 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | 847 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) |
@@ -843,14 +849,14 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
843 | 849 | ||
844 | args.v1.ucAction = action; | 850 | args.v1.ucAction = action; |
845 | if (action == ATOM_TRANSMITTER_ACTION_INIT) { | 851 | if (action == ATOM_TRANSMITTER_ACTION_INIT) { |
846 | args.v1.usInitInfo = radeon_connector->connector_object_id; | 852 | args.v1.usInitInfo = connector_object_id; |
847 | } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) { | 853 | } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) { |
848 | args.v1.asMode.ucLaneSel = lane_num; | 854 | args.v1.asMode.ucLaneSel = lane_num; |
849 | args.v1.asMode.ucLaneSet = lane_set; | 855 | args.v1.asMode.ucLaneSet = lane_set; |
850 | } else { | 856 | } else { |
851 | if (is_dp) | 857 | if (is_dp) |
852 | args.v1.usPixelClock = | 858 | args.v1.usPixelClock = |
853 | cpu_to_le16(dig_connector->dp_clock / 10); | 859 | cpu_to_le16(dp_clock / 10); |
854 | else if (radeon_encoder->pixel_clock > 165000) | 860 | else if (radeon_encoder->pixel_clock > 165000) |
855 | args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | 861 | args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); |
856 | else | 862 | else |
@@ -858,13 +864,13 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
858 | } | 864 | } |
859 | if (ASIC_IS_DCE4(rdev)) { | 865 | if (ASIC_IS_DCE4(rdev)) { |
860 | if (is_dp) | 866 | if (is_dp) |
861 | args.v3.ucLaneNum = dig_connector->dp_lane_count; | 867 | args.v3.ucLaneNum = dp_lane_count; |
862 | else if (radeon_encoder->pixel_clock > 165000) | 868 | else if (radeon_encoder->pixel_clock > 165000) |
863 | args.v3.ucLaneNum = 8; | 869 | args.v3.ucLaneNum = 8; |
864 | else | 870 | else |
865 | args.v3.ucLaneNum = 4; | 871 | args.v3.ucLaneNum = 4; |
866 | 872 | ||
867 | if (dig_connector->linkb) { | 873 | if (dig->linkb) { |
868 | args.v3.acConfig.ucLinkSel = 1; | 874 | args.v3.acConfig.ucLinkSel = 1; |
869 | args.v3.acConfig.ucEncoderSel = 1; | 875 | args.v3.acConfig.ucEncoderSel = 1; |
870 | } | 876 | } |
@@ -904,7 +910,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
904 | } | 910 | } |
905 | } else if (ASIC_IS_DCE32(rdev)) { | 911 | } else if (ASIC_IS_DCE32(rdev)) { |
906 | args.v2.acConfig.ucEncoderSel = dig->dig_encoder; | 912 | args.v2.acConfig.ucEncoderSel = dig->dig_encoder; |
907 | if (dig_connector->linkb) | 913 | if (dig->linkb) |
908 | args.v2.acConfig.ucLinkSel = 1; | 914 | args.v2.acConfig.ucLinkSel = 1; |
909 | 915 | ||
910 | switch (radeon_encoder->encoder_id) { | 916 | switch (radeon_encoder->encoder_id) { |
@@ -938,23 +944,23 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
938 | if ((rdev->flags & RADEON_IS_IGP) && | 944 | if ((rdev->flags & RADEON_IS_IGP) && |
939 | (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY)) { | 945 | (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY)) { |
940 | if (is_dp || (radeon_encoder->pixel_clock <= 165000)) { | 946 | if (is_dp || (radeon_encoder->pixel_clock <= 165000)) { |
941 | if (dig_connector->igp_lane_info & 0x1) | 947 | if (igp_lane_info & 0x1) |
942 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3; | 948 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3; |
943 | else if (dig_connector->igp_lane_info & 0x2) | 949 | else if (igp_lane_info & 0x2) |
944 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7; | 950 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7; |
945 | else if (dig_connector->igp_lane_info & 0x4) | 951 | else if (igp_lane_info & 0x4) |
946 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11; | 952 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11; |
947 | else if (dig_connector->igp_lane_info & 0x8) | 953 | else if (igp_lane_info & 0x8) |
948 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15; | 954 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15; |
949 | } else { | 955 | } else { |
950 | if (dig_connector->igp_lane_info & 0x3) | 956 | if (igp_lane_info & 0x3) |
951 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7; | 957 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7; |
952 | else if (dig_connector->igp_lane_info & 0xc) | 958 | else if (igp_lane_info & 0xc) |
953 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15; | 959 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15; |
954 | } | 960 | } |
955 | } | 961 | } |
956 | 962 | ||
957 | if (dig_connector->linkb) | 963 | if (dig->linkb) |
958 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB; | 964 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB; |
959 | else | 965 | else |
960 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA; | 966 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA; |
@@ -1072,8 +1078,7 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
1072 | if (is_dig) { | 1078 | if (is_dig) { |
1073 | switch (mode) { | 1079 | switch (mode) { |
1074 | case DRM_MODE_DPMS_ON: | 1080 | case DRM_MODE_DPMS_ON: |
1075 | if (!ASIC_IS_DCE4(rdev)) | 1081 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); |
1076 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); | ||
1077 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { | 1082 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { |
1078 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | 1083 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); |
1079 | 1084 | ||
@@ -1085,8 +1090,7 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
1085 | case DRM_MODE_DPMS_STANDBY: | 1090 | case DRM_MODE_DPMS_STANDBY: |
1086 | case DRM_MODE_DPMS_SUSPEND: | 1091 | case DRM_MODE_DPMS_SUSPEND: |
1087 | case DRM_MODE_DPMS_OFF: | 1092 | case DRM_MODE_DPMS_OFF: |
1088 | if (!ASIC_IS_DCE4(rdev)) | 1093 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); |
1089 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); | ||
1090 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { | 1094 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { |
1091 | if (ASIC_IS_DCE4(rdev)) | 1095 | if (ASIC_IS_DCE4(rdev)) |
1092 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF); | 1096 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF); |
@@ -1290,24 +1294,22 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder) | |||
1290 | uint32_t dig_enc_in_use = 0; | 1294 | uint32_t dig_enc_in_use = 0; |
1291 | 1295 | ||
1292 | if (ASIC_IS_DCE4(rdev)) { | 1296 | if (ASIC_IS_DCE4(rdev)) { |
1293 | struct radeon_connector_atom_dig *dig_connector = | 1297 | dig = radeon_encoder->enc_priv; |
1294 | radeon_get_atom_connector_priv_from_encoder(encoder); | ||
1295 | |||
1296 | switch (radeon_encoder->encoder_id) { | 1298 | switch (radeon_encoder->encoder_id) { |
1297 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | 1299 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: |
1298 | if (dig_connector->linkb) | 1300 | if (dig->linkb) |
1299 | return 1; | 1301 | return 1; |
1300 | else | 1302 | else |
1301 | return 0; | 1303 | return 0; |
1302 | break; | 1304 | break; |
1303 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | 1305 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: |
1304 | if (dig_connector->linkb) | 1306 | if (dig->linkb) |
1305 | return 3; | 1307 | return 3; |
1306 | else | 1308 | else |
1307 | return 2; | 1309 | return 2; |
1308 | break; | 1310 | break; |
1309 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | 1311 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
1310 | if (dig_connector->linkb) | 1312 | if (dig->linkb) |
1311 | return 5; | 1313 | return 5; |
1312 | else | 1314 | else |
1313 | return 4; | 1315 | return 4; |
@@ -1641,6 +1643,7 @@ radeon_atombios_set_dac_info(struct radeon_encoder *radeon_encoder) | |||
1641 | struct radeon_encoder_atom_dig * | 1643 | struct radeon_encoder_atom_dig * |
1642 | radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder) | 1644 | radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder) |
1643 | { | 1645 | { |
1646 | int encoder_enum = (radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT; | ||
1644 | struct radeon_encoder_atom_dig *dig = kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL); | 1647 | struct radeon_encoder_atom_dig *dig = kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL); |
1645 | 1648 | ||
1646 | if (!dig) | 1649 | if (!dig) |
@@ -1650,11 +1653,16 @@ radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder) | |||
1650 | dig->coherent_mode = true; | 1653 | dig->coherent_mode = true; |
1651 | dig->dig_encoder = -1; | 1654 | dig->dig_encoder = -1; |
1652 | 1655 | ||
1656 | if (encoder_enum == 2) | ||
1657 | dig->linkb = true; | ||
1658 | else | ||
1659 | dig->linkb = false; | ||
1660 | |||
1653 | return dig; | 1661 | return dig; |
1654 | } | 1662 | } |
1655 | 1663 | ||
1656 | void | 1664 | void |
1657 | radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device) | 1665 | radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t supported_device) |
1658 | { | 1666 | { |
1659 | struct radeon_device *rdev = dev->dev_private; | 1667 | struct radeon_device *rdev = dev->dev_private; |
1660 | struct drm_encoder *encoder; | 1668 | struct drm_encoder *encoder; |
@@ -1663,7 +1671,7 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su | |||
1663 | /* see if we already added it */ | 1671 | /* see if we already added it */ |
1664 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 1672 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
1665 | radeon_encoder = to_radeon_encoder(encoder); | 1673 | radeon_encoder = to_radeon_encoder(encoder); |
1666 | if (radeon_encoder->encoder_id == encoder_id) { | 1674 | if (radeon_encoder->encoder_enum == encoder_enum) { |
1667 | radeon_encoder->devices |= supported_device; | 1675 | radeon_encoder->devices |= supported_device; |
1668 | return; | 1676 | return; |
1669 | } | 1677 | } |
@@ -1691,7 +1699,8 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su | |||
1691 | 1699 | ||
1692 | radeon_encoder->enc_priv = NULL; | 1700 | radeon_encoder->enc_priv = NULL; |
1693 | 1701 | ||
1694 | radeon_encoder->encoder_id = encoder_id; | 1702 | radeon_encoder->encoder_enum = encoder_enum; |
1703 | radeon_encoder->encoder_id = (encoder_enum & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; | ||
1695 | radeon_encoder->devices = supported_device; | 1704 | radeon_encoder->devices = supported_device; |
1696 | radeon_encoder->rmx_type = RMX_OFF; | 1705 | radeon_encoder->rmx_type = RMX_OFF; |
1697 | radeon_encoder->underscan_type = UNDERSCAN_OFF; | 1706 | radeon_encoder->underscan_type = UNDERSCAN_OFF; |
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index dbf86962bdd..40b0c087b59 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c | |||
@@ -94,6 +94,7 @@ static void radeonfb_destroy_pinned_object(struct drm_gem_object *gobj) | |||
94 | ret = radeon_bo_reserve(rbo, false); | 94 | ret = radeon_bo_reserve(rbo, false); |
95 | if (likely(ret == 0)) { | 95 | if (likely(ret == 0)) { |
96 | radeon_bo_kunmap(rbo); | 96 | radeon_bo_kunmap(rbo); |
97 | radeon_bo_unpin(rbo); | ||
97 | radeon_bo_unreserve(rbo); | 98 | radeon_bo_unreserve(rbo); |
98 | } | 99 | } |
99 | drm_gem_object_unreference_unlocked(gobj); | 100 | drm_gem_object_unreference_unlocked(gobj); |
@@ -118,7 +119,7 @@ static int radeonfb_create_pinned_object(struct radeon_fbdev *rfbdev, | |||
118 | aligned_size = ALIGN(size, PAGE_SIZE); | 119 | aligned_size = ALIGN(size, PAGE_SIZE); |
119 | ret = radeon_gem_object_create(rdev, aligned_size, 0, | 120 | ret = radeon_gem_object_create(rdev, aligned_size, 0, |
120 | RADEON_GEM_DOMAIN_VRAM, | 121 | RADEON_GEM_DOMAIN_VRAM, |
121 | false, ttm_bo_type_kernel, | 122 | false, true, |
122 | &gobj); | 123 | &gobj); |
123 | if (ret) { | 124 | if (ret) { |
124 | printk(KERN_ERR "failed to allocate framebuffer (%d)\n", | 125 | printk(KERN_ERR "failed to allocate framebuffer (%d)\n", |
@@ -325,8 +326,6 @@ static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfb | |||
325 | { | 326 | { |
326 | struct fb_info *info; | 327 | struct fb_info *info; |
327 | struct radeon_framebuffer *rfb = &rfbdev->rfb; | 328 | struct radeon_framebuffer *rfb = &rfbdev->rfb; |
328 | struct radeon_bo *rbo; | ||
329 | int r; | ||
330 | 329 | ||
331 | if (rfbdev->helper.fbdev) { | 330 | if (rfbdev->helper.fbdev) { |
332 | info = rfbdev->helper.fbdev; | 331 | info = rfbdev->helper.fbdev; |
@@ -338,14 +337,8 @@ static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfb | |||
338 | } | 337 | } |
339 | 338 | ||
340 | if (rfb->obj) { | 339 | if (rfb->obj) { |
341 | rbo = rfb->obj->driver_private; | 340 | radeonfb_destroy_pinned_object(rfb->obj); |
342 | r = radeon_bo_reserve(rbo, false); | 341 | rfb->obj = NULL; |
343 | if (likely(r == 0)) { | ||
344 | radeon_bo_kunmap(rbo); | ||
345 | radeon_bo_unpin(rbo); | ||
346 | radeon_bo_unreserve(rbo); | ||
347 | } | ||
348 | drm_gem_object_unreference_unlocked(rfb->obj); | ||
349 | } | 342 | } |
350 | drm_fb_helper_fini(&rfbdev->helper); | 343 | drm_fb_helper_fini(&rfbdev->helper); |
351 | drm_framebuffer_cleanup(&rfb->base); | 344 | drm_framebuffer_cleanup(&rfb->base); |
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index c578f265b24..d1e595d9172 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c | |||
@@ -201,11 +201,11 @@ int radeon_gem_create_ioctl(struct drm_device *dev, void *data, | |||
201 | return r; | 201 | return r; |
202 | } | 202 | } |
203 | r = drm_gem_handle_create(filp, gobj, &handle); | 203 | r = drm_gem_handle_create(filp, gobj, &handle); |
204 | /* drop reference from allocate - handle holds it now */ | ||
205 | drm_gem_object_unreference_unlocked(gobj); | ||
204 | if (r) { | 206 | if (r) { |
205 | drm_gem_object_unreference_unlocked(gobj); | ||
206 | return r; | 207 | return r; |
207 | } | 208 | } |
208 | drm_gem_object_handle_unreference_unlocked(gobj); | ||
209 | args->handle = handle; | 209 | args->handle = handle; |
210 | return 0; | 210 | return 0; |
211 | } | 211 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index bfd2ce5f537..6a13ee38a5b 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c | |||
@@ -99,6 +99,13 @@ static void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state) | |||
99 | } | 99 | } |
100 | } | 100 | } |
101 | 101 | ||
102 | /* switch the pads to ddc mode */ | ||
103 | if (ASIC_IS_DCE3(rdev) && rec->hw_capable) { | ||
104 | temp = RREG32(rec->mask_clk_reg); | ||
105 | temp &= ~(1 << 16); | ||
106 | WREG32(rec->mask_clk_reg, temp); | ||
107 | } | ||
108 | |||
102 | /* clear the output pin values */ | 109 | /* clear the output pin values */ |
103 | temp = RREG32(rec->a_clk_reg) & ~rec->a_clk_mask; | 110 | temp = RREG32(rec->a_clk_reg) & ~rec->a_clk_mask; |
104 | WREG32(rec->a_clk_reg, temp); | 111 | WREG32(rec->a_clk_reg, temp); |
@@ -206,7 +213,7 @@ static void post_xfer(struct i2c_adapter *i2c_adap) | |||
206 | 213 | ||
207 | static u32 radeon_get_i2c_prescale(struct radeon_device *rdev) | 214 | static u32 radeon_get_i2c_prescale(struct radeon_device *rdev) |
208 | { | 215 | { |
209 | u32 sclk = radeon_get_engine_clock(rdev); | 216 | u32 sclk = rdev->pm.current_sclk; |
210 | u32 prescale = 0; | 217 | u32 prescale = 0; |
211 | u32 nm; | 218 | u32 nm; |
212 | u8 n, m, loop; | 219 | u8 n, m, loop; |
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index 059bfa4098d..a108c7ed14f 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c | |||
@@ -121,11 +121,12 @@ int radeon_irq_kms_init(struct radeon_device *rdev) | |||
121 | * chips. Disable MSI on them for now. | 121 | * chips. Disable MSI on them for now. |
122 | */ | 122 | */ |
123 | if ((rdev->family >= CHIP_RV380) && | 123 | if ((rdev->family >= CHIP_RV380) && |
124 | (!(rdev->flags & RADEON_IS_IGP))) { | 124 | (!(rdev->flags & RADEON_IS_IGP)) && |
125 | (!(rdev->flags & RADEON_IS_AGP))) { | ||
125 | int ret = pci_enable_msi(rdev->pdev); | 126 | int ret = pci_enable_msi(rdev->pdev); |
126 | if (!ret) { | 127 | if (!ret) { |
127 | rdev->msi_enabled = 1; | 128 | rdev->msi_enabled = 1; |
128 | DRM_INFO("radeon: using MSI.\n"); | 129 | dev_info(rdev->dev, "radeon: using MSI.\n"); |
129 | } | 130 | } |
130 | } | 131 | } |
131 | rdev->irq.installed = true; | 132 | rdev->irq.installed = true; |
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index b1c8ace5f08..8fbbe1c6ebb 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
@@ -161,6 +161,7 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
161 | DRM_DEBUG_KMS("tiling config is r6xx+ only!\n"); | 161 | DRM_DEBUG_KMS("tiling config is r6xx+ only!\n"); |
162 | return -EINVAL; | 162 | return -EINVAL; |
163 | } | 163 | } |
164 | break; | ||
164 | case RADEON_INFO_WANT_HYPERZ: | 165 | case RADEON_INFO_WANT_HYPERZ: |
165 | /* The "value" here is both an input and output parameter. | 166 | /* The "value" here is both an input and output parameter. |
166 | * If the input value is 1, filp requests hyper-z access. | 167 | * If the input value is 1, filp requests hyper-z access. |
@@ -202,6 +203,10 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
202 | */ | 203 | */ |
203 | int radeon_driver_firstopen_kms(struct drm_device *dev) | 204 | int radeon_driver_firstopen_kms(struct drm_device *dev) |
204 | { | 205 | { |
206 | struct radeon_device *rdev = dev->dev_private; | ||
207 | |||
208 | if (rdev->powered_down) | ||
209 | return -EINVAL; | ||
205 | return 0; | 210 | return 0; |
206 | } | 211 | } |
207 | 212 | ||
@@ -323,45 +328,45 @@ KMS_INVALID_IOCTL(radeon_surface_free_kms) | |||
323 | 328 | ||
324 | 329 | ||
325 | struct drm_ioctl_desc radeon_ioctls_kms[] = { | 330 | struct drm_ioctl_desc radeon_ioctls_kms[] = { |
326 | DRM_IOCTL_DEF(DRM_RADEON_CP_INIT, radeon_cp_init_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 331 | DRM_IOCTL_DEF_DRV(RADEON_CP_INIT, radeon_cp_init_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
327 | DRM_IOCTL_DEF(DRM_RADEON_CP_START, radeon_cp_start_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 332 | DRM_IOCTL_DEF_DRV(RADEON_CP_START, radeon_cp_start_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
328 | DRM_IOCTL_DEF(DRM_RADEON_CP_STOP, radeon_cp_stop_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 333 | DRM_IOCTL_DEF_DRV(RADEON_CP_STOP, radeon_cp_stop_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
329 | DRM_IOCTL_DEF(DRM_RADEON_CP_RESET, radeon_cp_reset_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 334 | DRM_IOCTL_DEF_DRV(RADEON_CP_RESET, radeon_cp_reset_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
330 | DRM_IOCTL_DEF(DRM_RADEON_CP_IDLE, radeon_cp_idle_kms, DRM_AUTH), | 335 | DRM_IOCTL_DEF_DRV(RADEON_CP_IDLE, radeon_cp_idle_kms, DRM_AUTH), |
331 | DRM_IOCTL_DEF(DRM_RADEON_CP_RESUME, radeon_cp_resume_kms, DRM_AUTH), | 336 | DRM_IOCTL_DEF_DRV(RADEON_CP_RESUME, radeon_cp_resume_kms, DRM_AUTH), |
332 | DRM_IOCTL_DEF(DRM_RADEON_RESET, radeon_engine_reset_kms, DRM_AUTH), | 337 | DRM_IOCTL_DEF_DRV(RADEON_RESET, radeon_engine_reset_kms, DRM_AUTH), |
333 | DRM_IOCTL_DEF(DRM_RADEON_FULLSCREEN, radeon_fullscreen_kms, DRM_AUTH), | 338 | DRM_IOCTL_DEF_DRV(RADEON_FULLSCREEN, radeon_fullscreen_kms, DRM_AUTH), |
334 | DRM_IOCTL_DEF(DRM_RADEON_SWAP, radeon_cp_swap_kms, DRM_AUTH), | 339 | DRM_IOCTL_DEF_DRV(RADEON_SWAP, radeon_cp_swap_kms, DRM_AUTH), |
335 | DRM_IOCTL_DEF(DRM_RADEON_CLEAR, radeon_cp_clear_kms, DRM_AUTH), | 340 | DRM_IOCTL_DEF_DRV(RADEON_CLEAR, radeon_cp_clear_kms, DRM_AUTH), |
336 | DRM_IOCTL_DEF(DRM_RADEON_VERTEX, radeon_cp_vertex_kms, DRM_AUTH), | 341 | DRM_IOCTL_DEF_DRV(RADEON_VERTEX, radeon_cp_vertex_kms, DRM_AUTH), |
337 | DRM_IOCTL_DEF(DRM_RADEON_INDICES, radeon_cp_indices_kms, DRM_AUTH), | 342 | DRM_IOCTL_DEF_DRV(RADEON_INDICES, radeon_cp_indices_kms, DRM_AUTH), |
338 | DRM_IOCTL_DEF(DRM_RADEON_TEXTURE, radeon_cp_texture_kms, DRM_AUTH), | 343 | DRM_IOCTL_DEF_DRV(RADEON_TEXTURE, radeon_cp_texture_kms, DRM_AUTH), |
339 | DRM_IOCTL_DEF(DRM_RADEON_STIPPLE, radeon_cp_stipple_kms, DRM_AUTH), | 344 | DRM_IOCTL_DEF_DRV(RADEON_STIPPLE, radeon_cp_stipple_kms, DRM_AUTH), |
340 | DRM_IOCTL_DEF(DRM_RADEON_INDIRECT, radeon_cp_indirect_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 345 | DRM_IOCTL_DEF_DRV(RADEON_INDIRECT, radeon_cp_indirect_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
341 | DRM_IOCTL_DEF(DRM_RADEON_VERTEX2, radeon_cp_vertex2_kms, DRM_AUTH), | 346 | DRM_IOCTL_DEF_DRV(RADEON_VERTEX2, radeon_cp_vertex2_kms, DRM_AUTH), |
342 | DRM_IOCTL_DEF(DRM_RADEON_CMDBUF, radeon_cp_cmdbuf_kms, DRM_AUTH), | 347 | DRM_IOCTL_DEF_DRV(RADEON_CMDBUF, radeon_cp_cmdbuf_kms, DRM_AUTH), |
343 | DRM_IOCTL_DEF(DRM_RADEON_GETPARAM, radeon_cp_getparam_kms, DRM_AUTH), | 348 | DRM_IOCTL_DEF_DRV(RADEON_GETPARAM, radeon_cp_getparam_kms, DRM_AUTH), |
344 | DRM_IOCTL_DEF(DRM_RADEON_FLIP, radeon_cp_flip_kms, DRM_AUTH), | 349 | DRM_IOCTL_DEF_DRV(RADEON_FLIP, radeon_cp_flip_kms, DRM_AUTH), |
345 | DRM_IOCTL_DEF(DRM_RADEON_ALLOC, radeon_mem_alloc_kms, DRM_AUTH), | 350 | DRM_IOCTL_DEF_DRV(RADEON_ALLOC, radeon_mem_alloc_kms, DRM_AUTH), |
346 | DRM_IOCTL_DEF(DRM_RADEON_FREE, radeon_mem_free_kms, DRM_AUTH), | 351 | DRM_IOCTL_DEF_DRV(RADEON_FREE, radeon_mem_free_kms, DRM_AUTH), |
347 | DRM_IOCTL_DEF(DRM_RADEON_INIT_HEAP, radeon_mem_init_heap_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 352 | DRM_IOCTL_DEF_DRV(RADEON_INIT_HEAP, radeon_mem_init_heap_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
348 | DRM_IOCTL_DEF(DRM_RADEON_IRQ_EMIT, radeon_irq_emit_kms, DRM_AUTH), | 353 | DRM_IOCTL_DEF_DRV(RADEON_IRQ_EMIT, radeon_irq_emit_kms, DRM_AUTH), |
349 | DRM_IOCTL_DEF(DRM_RADEON_IRQ_WAIT, radeon_irq_wait_kms, DRM_AUTH), | 354 | DRM_IOCTL_DEF_DRV(RADEON_IRQ_WAIT, radeon_irq_wait_kms, DRM_AUTH), |
350 | DRM_IOCTL_DEF(DRM_RADEON_SETPARAM, radeon_cp_setparam_kms, DRM_AUTH), | 355 | DRM_IOCTL_DEF_DRV(RADEON_SETPARAM, radeon_cp_setparam_kms, DRM_AUTH), |
351 | DRM_IOCTL_DEF(DRM_RADEON_SURF_ALLOC, radeon_surface_alloc_kms, DRM_AUTH), | 356 | DRM_IOCTL_DEF_DRV(RADEON_SURF_ALLOC, radeon_surface_alloc_kms, DRM_AUTH), |
352 | DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free_kms, DRM_AUTH), | 357 | DRM_IOCTL_DEF_DRV(RADEON_SURF_FREE, radeon_surface_free_kms, DRM_AUTH), |
353 | /* KMS */ | 358 | /* KMS */ |
354 | DRM_IOCTL_DEF(DRM_RADEON_GEM_INFO, radeon_gem_info_ioctl, DRM_AUTH|DRM_UNLOCKED), | 359 | DRM_IOCTL_DEF_DRV(RADEON_GEM_INFO, radeon_gem_info_ioctl, DRM_AUTH|DRM_UNLOCKED), |
355 | DRM_IOCTL_DEF(DRM_RADEON_GEM_CREATE, radeon_gem_create_ioctl, DRM_AUTH|DRM_UNLOCKED), | 360 | DRM_IOCTL_DEF_DRV(RADEON_GEM_CREATE, radeon_gem_create_ioctl, DRM_AUTH|DRM_UNLOCKED), |
356 | DRM_IOCTL_DEF(DRM_RADEON_GEM_MMAP, radeon_gem_mmap_ioctl, DRM_AUTH|DRM_UNLOCKED), | 361 | DRM_IOCTL_DEF_DRV(RADEON_GEM_MMAP, radeon_gem_mmap_ioctl, DRM_AUTH|DRM_UNLOCKED), |
357 | DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_DOMAIN, radeon_gem_set_domain_ioctl, DRM_AUTH|DRM_UNLOCKED), | 362 | DRM_IOCTL_DEF_DRV(RADEON_GEM_SET_DOMAIN, radeon_gem_set_domain_ioctl, DRM_AUTH|DRM_UNLOCKED), |
358 | DRM_IOCTL_DEF(DRM_RADEON_GEM_PREAD, radeon_gem_pread_ioctl, DRM_AUTH|DRM_UNLOCKED), | 363 | DRM_IOCTL_DEF_DRV(RADEON_GEM_PREAD, radeon_gem_pread_ioctl, DRM_AUTH|DRM_UNLOCKED), |
359 | DRM_IOCTL_DEF(DRM_RADEON_GEM_PWRITE, radeon_gem_pwrite_ioctl, DRM_AUTH|DRM_UNLOCKED), | 364 | DRM_IOCTL_DEF_DRV(RADEON_GEM_PWRITE, radeon_gem_pwrite_ioctl, DRM_AUTH|DRM_UNLOCKED), |
360 | DRM_IOCTL_DEF(DRM_RADEON_GEM_WAIT_IDLE, radeon_gem_wait_idle_ioctl, DRM_AUTH|DRM_UNLOCKED), | 365 | DRM_IOCTL_DEF_DRV(RADEON_GEM_WAIT_IDLE, radeon_gem_wait_idle_ioctl, DRM_AUTH|DRM_UNLOCKED), |
361 | DRM_IOCTL_DEF(DRM_RADEON_CS, radeon_cs_ioctl, DRM_AUTH|DRM_UNLOCKED), | 366 | DRM_IOCTL_DEF_DRV(RADEON_CS, radeon_cs_ioctl, DRM_AUTH|DRM_UNLOCKED), |
362 | DRM_IOCTL_DEF(DRM_RADEON_INFO, radeon_info_ioctl, DRM_AUTH|DRM_UNLOCKED), | 367 | DRM_IOCTL_DEF_DRV(RADEON_INFO, radeon_info_ioctl, DRM_AUTH|DRM_UNLOCKED), |
363 | DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_TILING, radeon_gem_set_tiling_ioctl, DRM_AUTH|DRM_UNLOCKED), | 368 | DRM_IOCTL_DEF_DRV(RADEON_GEM_SET_TILING, radeon_gem_set_tiling_ioctl, DRM_AUTH|DRM_UNLOCKED), |
364 | DRM_IOCTL_DEF(DRM_RADEON_GEM_GET_TILING, radeon_gem_get_tiling_ioctl, DRM_AUTH|DRM_UNLOCKED), | 369 | DRM_IOCTL_DEF_DRV(RADEON_GEM_GET_TILING, radeon_gem_get_tiling_ioctl, DRM_AUTH|DRM_UNLOCKED), |
365 | DRM_IOCTL_DEF(DRM_RADEON_GEM_BUSY, radeon_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED), | 370 | DRM_IOCTL_DEF_DRV(RADEON_GEM_BUSY, radeon_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED), |
366 | }; | 371 | }; |
367 | int radeon_max_kms_ioctl = DRM_ARRAY_SIZE(radeon_ioctls_kms); | 372 | int radeon_max_kms_ioctl = DRM_ARRAY_SIZE(radeon_ioctls_kms); |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index 989df519a1e..305049afde1 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c | |||
@@ -272,7 +272,7 @@ static uint8_t radeon_compute_pll_gain(uint16_t ref_freq, uint16_t ref_div, | |||
272 | if (!ref_div) | 272 | if (!ref_div) |
273 | return 1; | 273 | return 1; |
274 | 274 | ||
275 | vcoFreq = ((unsigned)ref_freq & fb_div) / ref_div; | 275 | vcoFreq = ((unsigned)ref_freq * fb_div) / ref_div; |
276 | 276 | ||
277 | /* | 277 | /* |
278 | * This is horribly crude: the VCO frequency range is divided into | 278 | * This is horribly crude: the VCO frequency range is divided into |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index b8149cbc0c7..0b8397000f4 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c | |||
@@ -1345,7 +1345,7 @@ static struct radeon_encoder_ext_tmds *radeon_legacy_get_ext_tmds_info(struct ra | |||
1345 | } | 1345 | } |
1346 | 1346 | ||
1347 | void | 1347 | void |
1348 | radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device) | 1348 | radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t supported_device) |
1349 | { | 1349 | { |
1350 | struct radeon_device *rdev = dev->dev_private; | 1350 | struct radeon_device *rdev = dev->dev_private; |
1351 | struct drm_encoder *encoder; | 1351 | struct drm_encoder *encoder; |
@@ -1354,7 +1354,7 @@ radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t | |||
1354 | /* see if we already added it */ | 1354 | /* see if we already added it */ |
1355 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 1355 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
1356 | radeon_encoder = to_radeon_encoder(encoder); | 1356 | radeon_encoder = to_radeon_encoder(encoder); |
1357 | if (radeon_encoder->encoder_id == encoder_id) { | 1357 | if (radeon_encoder->encoder_enum == encoder_enum) { |
1358 | radeon_encoder->devices |= supported_device; | 1358 | radeon_encoder->devices |= supported_device; |
1359 | return; | 1359 | return; |
1360 | } | 1360 | } |
@@ -1374,7 +1374,8 @@ radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t | |||
1374 | 1374 | ||
1375 | radeon_encoder->enc_priv = NULL; | 1375 | radeon_encoder->enc_priv = NULL; |
1376 | 1376 | ||
1377 | radeon_encoder->encoder_id = encoder_id; | 1377 | radeon_encoder->encoder_enum = encoder_enum; |
1378 | radeon_encoder->encoder_id = (encoder_enum & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; | ||
1378 | radeon_encoder->devices = supported_device; | 1379 | radeon_encoder->devices = supported_device; |
1379 | radeon_encoder->rmx_type = RMX_OFF; | 1380 | radeon_encoder->rmx_type = RMX_OFF; |
1380 | 1381 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 5bbc086b926..17a6602b588 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
@@ -204,7 +204,7 @@ struct radeon_i2c_chan { | |||
204 | 204 | ||
205 | /* mostly for macs, but really any system without connector tables */ | 205 | /* mostly for macs, but really any system without connector tables */ |
206 | enum radeon_connector_table { | 206 | enum radeon_connector_table { |
207 | CT_NONE, | 207 | CT_NONE = 0, |
208 | CT_GENERIC, | 208 | CT_GENERIC, |
209 | CT_IBOOK, | 209 | CT_IBOOK, |
210 | CT_POWERBOOK_EXTERNAL, | 210 | CT_POWERBOOK_EXTERNAL, |
@@ -215,6 +215,7 @@ enum radeon_connector_table { | |||
215 | CT_IMAC_G5_ISIGHT, | 215 | CT_IMAC_G5_ISIGHT, |
216 | CT_EMAC, | 216 | CT_EMAC, |
217 | CT_RN50_POWER, | 217 | CT_RN50_POWER, |
218 | CT_MAC_X800, | ||
218 | }; | 219 | }; |
219 | 220 | ||
220 | enum radeon_dvo_chip { | 221 | enum radeon_dvo_chip { |
@@ -342,6 +343,7 @@ struct radeon_atom_ss { | |||
342 | }; | 343 | }; |
343 | 344 | ||
344 | struct radeon_encoder_atom_dig { | 345 | struct radeon_encoder_atom_dig { |
346 | bool linkb; | ||
345 | /* atom dig */ | 347 | /* atom dig */ |
346 | bool coherent_mode; | 348 | bool coherent_mode; |
347 | int dig_encoder; /* -1 disabled, 0 DIGA, 1 DIGB */ | 349 | int dig_encoder; /* -1 disabled, 0 DIGA, 1 DIGB */ |
@@ -360,6 +362,7 @@ struct radeon_encoder_atom_dac { | |||
360 | 362 | ||
361 | struct radeon_encoder { | 363 | struct radeon_encoder { |
362 | struct drm_encoder base; | 364 | struct drm_encoder base; |
365 | uint32_t encoder_enum; | ||
363 | uint32_t encoder_id; | 366 | uint32_t encoder_id; |
364 | uint32_t devices; | 367 | uint32_t devices; |
365 | uint32_t active_device; | 368 | uint32_t active_device; |
@@ -378,7 +381,6 @@ struct radeon_encoder { | |||
378 | 381 | ||
379 | struct radeon_connector_atom_dig { | 382 | struct radeon_connector_atom_dig { |
380 | uint32_t igp_lane_info; | 383 | uint32_t igp_lane_info; |
381 | bool linkb; | ||
382 | /* displayport */ | 384 | /* displayport */ |
383 | struct radeon_i2c_chan *dp_i2c_bus; | 385 | struct radeon_i2c_chan *dp_i2c_bus; |
384 | u8 dpcd[8]; | 386 | u8 dpcd[8]; |
@@ -599,7 +601,6 @@ extern bool radeon_get_atom_connector_info_from_supported_devices_table(struct d | |||
599 | void radeon_enc_destroy(struct drm_encoder *encoder); | 601 | void radeon_enc_destroy(struct drm_encoder *encoder); |
600 | void radeon_copy_fb(struct drm_device *dev, struct drm_gem_object *dst_obj); | 602 | void radeon_copy_fb(struct drm_device *dev, struct drm_gem_object *dst_obj); |
601 | void radeon_combios_asic_init(struct drm_device *dev); | 603 | void radeon_combios_asic_init(struct drm_device *dev); |
602 | extern int radeon_static_clocks_init(struct drm_device *dev); | ||
603 | bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, | 604 | bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, |
604 | struct drm_display_mode *mode, | 605 | struct drm_display_mode *mode, |
605 | struct drm_display_mode *adjusted_mode); | 606 | struct drm_display_mode *adjusted_mode); |
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 0afd1e62347..b3b5306bb57 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
@@ -69,7 +69,7 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain) | |||
69 | u32 c = 0; | 69 | u32 c = 0; |
70 | 70 | ||
71 | rbo->placement.fpfn = 0; | 71 | rbo->placement.fpfn = 0; |
72 | rbo->placement.lpfn = 0; | 72 | rbo->placement.lpfn = rbo->rdev->mc.active_vram_size >> PAGE_SHIFT; |
73 | rbo->placement.placement = rbo->placements; | 73 | rbo->placement.placement = rbo->placements; |
74 | rbo->placement.busy_placement = rbo->placements; | 74 | rbo->placement.busy_placement = rbo->placements; |
75 | if (domain & RADEON_GEM_DOMAIN_VRAM) | 75 | if (domain & RADEON_GEM_DOMAIN_VRAM) |
diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h index 353998dc2c0..3481bc7f6f5 100644 --- a/drivers/gpu/drm/radeon/radeon_object.h +++ b/drivers/gpu/drm/radeon/radeon_object.h | |||
@@ -124,11 +124,8 @@ static inline int radeon_bo_wait(struct radeon_bo *bo, u32 *mem_type, | |||
124 | int r; | 124 | int r; |
125 | 125 | ||
126 | r = ttm_bo_reserve(&bo->tbo, true, no_wait, false, 0); | 126 | r = ttm_bo_reserve(&bo->tbo, true, no_wait, false, 0); |
127 | if (unlikely(r != 0)) { | 127 | if (unlikely(r != 0)) |
128 | if (r != -ERESTARTSYS) | ||
129 | dev_err(bo->rdev->dev, "%p reserve failed for wait\n", bo); | ||
130 | return r; | 128 | return r; |
131 | } | ||
132 | spin_lock(&bo->tbo.lock); | 129 | spin_lock(&bo->tbo.lock); |
133 | if (mem_type) | 130 | if (mem_type) |
134 | *mem_type = bo->tbo.mem.mem_type; | 131 | *mem_type = bo->tbo.mem.mem_type; |
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 58038f5cab3..f87efec7623 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
@@ -226,6 +226,11 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev) | |||
226 | { | 226 | { |
227 | int i; | 227 | int i; |
228 | 228 | ||
229 | /* no need to take locks, etc. if nothing's going to change */ | ||
230 | if ((rdev->pm.requested_clock_mode_index == rdev->pm.current_clock_mode_index) && | ||
231 | (rdev->pm.requested_power_state_index == rdev->pm.current_power_state_index)) | ||
232 | return; | ||
233 | |||
229 | mutex_lock(&rdev->ddev->struct_mutex); | 234 | mutex_lock(&rdev->ddev->struct_mutex); |
230 | mutex_lock(&rdev->vram_mutex); | 235 | mutex_lock(&rdev->vram_mutex); |
231 | mutex_lock(&rdev->cp.mutex); | 236 | mutex_lock(&rdev->cp.mutex); |
@@ -632,8 +637,6 @@ void radeon_pm_fini(struct radeon_device *rdev) | |||
632 | } | 637 | } |
633 | 638 | ||
634 | radeon_hwmon_fini(rdev); | 639 | radeon_hwmon_fini(rdev); |
635 | if (rdev->pm.i2c_bus) | ||
636 | radeon_i2c_destroy(rdev->pm.i2c_bus); | ||
637 | } | 640 | } |
638 | 641 | ||
639 | void radeon_pm_compute_clocks(struct radeon_device *rdev) | 642 | void radeon_pm_compute_clocks(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c index b3ba44c0a81..4ae5a3d1074 100644 --- a/drivers/gpu/drm/radeon/radeon_state.c +++ b/drivers/gpu/drm/radeon/radeon_state.c | |||
@@ -3228,34 +3228,34 @@ void radeon_driver_postclose(struct drm_device *dev, struct drm_file *file_priv) | |||
3228 | } | 3228 | } |
3229 | 3229 | ||
3230 | struct drm_ioctl_desc radeon_ioctls[] = { | 3230 | struct drm_ioctl_desc radeon_ioctls[] = { |
3231 | DRM_IOCTL_DEF(DRM_RADEON_CP_INIT, radeon_cp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 3231 | DRM_IOCTL_DEF_DRV(RADEON_CP_INIT, radeon_cp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
3232 | DRM_IOCTL_DEF(DRM_RADEON_CP_START, radeon_cp_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 3232 | DRM_IOCTL_DEF_DRV(RADEON_CP_START, radeon_cp_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
3233 | DRM_IOCTL_DEF(DRM_RADEON_CP_STOP, radeon_cp_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 3233 | DRM_IOCTL_DEF_DRV(RADEON_CP_STOP, radeon_cp_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
3234 | DRM_IOCTL_DEF(DRM_RADEON_CP_RESET, radeon_cp_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 3234 | DRM_IOCTL_DEF_DRV(RADEON_CP_RESET, radeon_cp_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
3235 | DRM_IOCTL_DEF(DRM_RADEON_CP_IDLE, radeon_cp_idle, DRM_AUTH), | 3235 | DRM_IOCTL_DEF_DRV(RADEON_CP_IDLE, radeon_cp_idle, DRM_AUTH), |
3236 | DRM_IOCTL_DEF(DRM_RADEON_CP_RESUME, radeon_cp_resume, DRM_AUTH), | 3236 | DRM_IOCTL_DEF_DRV(RADEON_CP_RESUME, radeon_cp_resume, DRM_AUTH), |
3237 | DRM_IOCTL_DEF(DRM_RADEON_RESET, radeon_engine_reset, DRM_AUTH), | 3237 | DRM_IOCTL_DEF_DRV(RADEON_RESET, radeon_engine_reset, DRM_AUTH), |
3238 | DRM_IOCTL_DEF(DRM_RADEON_FULLSCREEN, radeon_fullscreen, DRM_AUTH), | 3238 | DRM_IOCTL_DEF_DRV(RADEON_FULLSCREEN, radeon_fullscreen, DRM_AUTH), |
3239 | DRM_IOCTL_DEF(DRM_RADEON_SWAP, radeon_cp_swap, DRM_AUTH), | 3239 | DRM_IOCTL_DEF_DRV(RADEON_SWAP, radeon_cp_swap, DRM_AUTH), |
3240 | DRM_IOCTL_DEF(DRM_RADEON_CLEAR, radeon_cp_clear, DRM_AUTH), | 3240 | DRM_IOCTL_DEF_DRV(RADEON_CLEAR, radeon_cp_clear, DRM_AUTH), |
3241 | DRM_IOCTL_DEF(DRM_RADEON_VERTEX, radeon_cp_vertex, DRM_AUTH), | 3241 | DRM_IOCTL_DEF_DRV(RADEON_VERTEX, radeon_cp_vertex, DRM_AUTH), |
3242 | DRM_IOCTL_DEF(DRM_RADEON_INDICES, radeon_cp_indices, DRM_AUTH), | 3242 | DRM_IOCTL_DEF_DRV(RADEON_INDICES, radeon_cp_indices, DRM_AUTH), |
3243 | DRM_IOCTL_DEF(DRM_RADEON_TEXTURE, radeon_cp_texture, DRM_AUTH), | 3243 | DRM_IOCTL_DEF_DRV(RADEON_TEXTURE, radeon_cp_texture, DRM_AUTH), |
3244 | DRM_IOCTL_DEF(DRM_RADEON_STIPPLE, radeon_cp_stipple, DRM_AUTH), | 3244 | DRM_IOCTL_DEF_DRV(RADEON_STIPPLE, radeon_cp_stipple, DRM_AUTH), |
3245 | DRM_IOCTL_DEF(DRM_RADEON_INDIRECT, radeon_cp_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 3245 | DRM_IOCTL_DEF_DRV(RADEON_INDIRECT, radeon_cp_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
3246 | DRM_IOCTL_DEF(DRM_RADEON_VERTEX2, radeon_cp_vertex2, DRM_AUTH), | 3246 | DRM_IOCTL_DEF_DRV(RADEON_VERTEX2, radeon_cp_vertex2, DRM_AUTH), |
3247 | DRM_IOCTL_DEF(DRM_RADEON_CMDBUF, radeon_cp_cmdbuf, DRM_AUTH), | 3247 | DRM_IOCTL_DEF_DRV(RADEON_CMDBUF, radeon_cp_cmdbuf, DRM_AUTH), |
3248 | DRM_IOCTL_DEF(DRM_RADEON_GETPARAM, radeon_cp_getparam, DRM_AUTH), | 3248 | DRM_IOCTL_DEF_DRV(RADEON_GETPARAM, radeon_cp_getparam, DRM_AUTH), |
3249 | DRM_IOCTL_DEF(DRM_RADEON_FLIP, radeon_cp_flip, DRM_AUTH), | 3249 | DRM_IOCTL_DEF_DRV(RADEON_FLIP, radeon_cp_flip, DRM_AUTH), |
3250 | DRM_IOCTL_DEF(DRM_RADEON_ALLOC, radeon_mem_alloc, DRM_AUTH), | 3250 | DRM_IOCTL_DEF_DRV(RADEON_ALLOC, radeon_mem_alloc, DRM_AUTH), |
3251 | DRM_IOCTL_DEF(DRM_RADEON_FREE, radeon_mem_free, DRM_AUTH), | 3251 | DRM_IOCTL_DEF_DRV(RADEON_FREE, radeon_mem_free, DRM_AUTH), |
3252 | DRM_IOCTL_DEF(DRM_RADEON_INIT_HEAP, radeon_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 3252 | DRM_IOCTL_DEF_DRV(RADEON_INIT_HEAP, radeon_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
3253 | DRM_IOCTL_DEF(DRM_RADEON_IRQ_EMIT, radeon_irq_emit, DRM_AUTH), | 3253 | DRM_IOCTL_DEF_DRV(RADEON_IRQ_EMIT, radeon_irq_emit, DRM_AUTH), |
3254 | DRM_IOCTL_DEF(DRM_RADEON_IRQ_WAIT, radeon_irq_wait, DRM_AUTH), | 3254 | DRM_IOCTL_DEF_DRV(RADEON_IRQ_WAIT, radeon_irq_wait, DRM_AUTH), |
3255 | DRM_IOCTL_DEF(DRM_RADEON_SETPARAM, radeon_cp_setparam, DRM_AUTH), | 3255 | DRM_IOCTL_DEF_DRV(RADEON_SETPARAM, radeon_cp_setparam, DRM_AUTH), |
3256 | DRM_IOCTL_DEF(DRM_RADEON_SURF_ALLOC, radeon_surface_alloc, DRM_AUTH), | 3256 | DRM_IOCTL_DEF_DRV(RADEON_SURF_ALLOC, radeon_surface_alloc, DRM_AUTH), |
3257 | DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH), | 3257 | DRM_IOCTL_DEF_DRV(RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH), |
3258 | DRM_IOCTL_DEF(DRM_RADEON_CS, r600_cs_legacy_ioctl, DRM_AUTH) | 3258 | DRM_IOCTL_DEF_DRV(RADEON_CS, r600_cs_legacy_ioctl, DRM_AUTH) |
3259 | }; | 3259 | }; |
3260 | 3260 | ||
3261 | int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls); | 3261 | int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls); |
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index cc05b230d7e..51d5f7b5ab2 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
@@ -693,6 +693,7 @@ void rs600_mc_init(struct radeon_device *rdev) | |||
693 | rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE); | 693 | rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE); |
694 | rdev->mc.mc_vram_size = rdev->mc.real_vram_size; | 694 | rdev->mc.mc_vram_size = rdev->mc.real_vram_size; |
695 | rdev->mc.visible_vram_size = rdev->mc.aper_size; | 695 | rdev->mc.visible_vram_size = rdev->mc.aper_size; |
696 | rdev->mc.active_vram_size = rdev->mc.visible_vram_size; | ||
696 | rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); | 697 | rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); |
697 | base = RREG32_MC(R_000004_MC_FB_LOCATION); | 698 | base = RREG32_MC(R_000004_MC_FB_LOCATION); |
698 | base = G_000004_MC_FB_START(base) << 16; | 699 | base = G_000004_MC_FB_START(base) << 16; |
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 3e3f75718be..4dc2a87ea68 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c | |||
@@ -157,6 +157,7 @@ void rs690_mc_init(struct radeon_device *rdev) | |||
157 | rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); | 157 | rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); |
158 | rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); | 158 | rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); |
159 | rdev->mc.visible_vram_size = rdev->mc.aper_size; | 159 | rdev->mc.visible_vram_size = rdev->mc.aper_size; |
160 | rdev->mc.active_vram_size = rdev->mc.visible_vram_size; | ||
160 | base = RREG32_MC(R_000100_MCCFG_FB_LOCATION); | 161 | base = RREG32_MC(R_000100_MCCFG_FB_LOCATION); |
161 | base = G_000100_MC_FB_START(base) << 16; | 162 | base = G_000100_MC_FB_START(base) << 16; |
162 | rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); | 163 | rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index f1c79681011..9490da70074 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
@@ -267,6 +267,7 @@ static void rv770_mc_program(struct radeon_device *rdev) | |||
267 | */ | 267 | */ |
268 | void r700_cp_stop(struct radeon_device *rdev) | 268 | void r700_cp_stop(struct radeon_device *rdev) |
269 | { | 269 | { |
270 | rdev->mc.active_vram_size = rdev->mc.visible_vram_size; | ||
270 | WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT)); | 271 | WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT)); |
271 | } | 272 | } |
272 | 273 | ||
@@ -905,6 +906,54 @@ static void rv770_gpu_init(struct radeon_device *rdev) | |||
905 | 906 | ||
906 | } | 907 | } |
907 | 908 | ||
909 | static int rv770_vram_scratch_init(struct radeon_device *rdev) | ||
910 | { | ||
911 | int r; | ||
912 | u64 gpu_addr; | ||
913 | |||
914 | if (rdev->vram_scratch.robj == NULL) { | ||
915 | r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, | ||
916 | true, RADEON_GEM_DOMAIN_VRAM, | ||
917 | &rdev->vram_scratch.robj); | ||
918 | if (r) { | ||
919 | return r; | ||
920 | } | ||
921 | } | ||
922 | |||
923 | r = radeon_bo_reserve(rdev->vram_scratch.robj, false); | ||
924 | if (unlikely(r != 0)) | ||
925 | return r; | ||
926 | r = radeon_bo_pin(rdev->vram_scratch.robj, | ||
927 | RADEON_GEM_DOMAIN_VRAM, &gpu_addr); | ||
928 | if (r) { | ||
929 | radeon_bo_unreserve(rdev->vram_scratch.robj); | ||
930 | return r; | ||
931 | } | ||
932 | r = radeon_bo_kmap(rdev->vram_scratch.robj, | ||
933 | (void **)&rdev->vram_scratch.ptr); | ||
934 | if (r) | ||
935 | radeon_bo_unpin(rdev->vram_scratch.robj); | ||
936 | radeon_bo_unreserve(rdev->vram_scratch.robj); | ||
937 | |||
938 | return r; | ||
939 | } | ||
940 | |||
941 | static void rv770_vram_scratch_fini(struct radeon_device *rdev) | ||
942 | { | ||
943 | int r; | ||
944 | |||
945 | if (rdev->vram_scratch.robj == NULL) { | ||
946 | return; | ||
947 | } | ||
948 | r = radeon_bo_reserve(rdev->vram_scratch.robj, false); | ||
949 | if (likely(r == 0)) { | ||
950 | radeon_bo_kunmap(rdev->vram_scratch.robj); | ||
951 | radeon_bo_unpin(rdev->vram_scratch.robj); | ||
952 | radeon_bo_unreserve(rdev->vram_scratch.robj); | ||
953 | } | ||
954 | radeon_bo_unref(&rdev->vram_scratch.robj); | ||
955 | } | ||
956 | |||
908 | int rv770_mc_init(struct radeon_device *rdev) | 957 | int rv770_mc_init(struct radeon_device *rdev) |
909 | { | 958 | { |
910 | u32 tmp; | 959 | u32 tmp; |
@@ -944,6 +993,7 @@ int rv770_mc_init(struct radeon_device *rdev) | |||
944 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); | 993 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); |
945 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); | 994 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); |
946 | rdev->mc.visible_vram_size = rdev->mc.aper_size; | 995 | rdev->mc.visible_vram_size = rdev->mc.aper_size; |
996 | rdev->mc.active_vram_size = rdev->mc.visible_vram_size; | ||
947 | r600_vram_gtt_location(rdev, &rdev->mc); | 997 | r600_vram_gtt_location(rdev, &rdev->mc); |
948 | radeon_update_bandwidth_info(rdev); | 998 | radeon_update_bandwidth_info(rdev); |
949 | 999 | ||
@@ -970,6 +1020,9 @@ static int rv770_startup(struct radeon_device *rdev) | |||
970 | if (r) | 1020 | if (r) |
971 | return r; | 1021 | return r; |
972 | } | 1022 | } |
1023 | r = rv770_vram_scratch_init(rdev); | ||
1024 | if (r) | ||
1025 | return r; | ||
973 | rv770_gpu_init(rdev); | 1026 | rv770_gpu_init(rdev); |
974 | r = r600_blit_init(rdev); | 1027 | r = r600_blit_init(rdev); |
975 | if (r) { | 1028 | if (r) { |
@@ -1023,11 +1076,6 @@ int rv770_resume(struct radeon_device *rdev) | |||
1023 | */ | 1076 | */ |
1024 | /* post card */ | 1077 | /* post card */ |
1025 | atom_asic_init(rdev->mode_info.atom_context); | 1078 | atom_asic_init(rdev->mode_info.atom_context); |
1026 | /* Initialize clocks */ | ||
1027 | r = radeon_clocks_init(rdev); | ||
1028 | if (r) { | ||
1029 | return r; | ||
1030 | } | ||
1031 | 1079 | ||
1032 | r = rv770_startup(rdev); | 1080 | r = rv770_startup(rdev); |
1033 | if (r) { | 1081 | if (r) { |
@@ -1118,9 +1166,6 @@ int rv770_init(struct radeon_device *rdev) | |||
1118 | radeon_surface_init(rdev); | 1166 | radeon_surface_init(rdev); |
1119 | /* Initialize clocks */ | 1167 | /* Initialize clocks */ |
1120 | radeon_get_clock_info(rdev->ddev); | 1168 | radeon_get_clock_info(rdev->ddev); |
1121 | r = radeon_clocks_init(rdev); | ||
1122 | if (r) | ||
1123 | return r; | ||
1124 | /* Fence driver */ | 1169 | /* Fence driver */ |
1125 | r = radeon_fence_driver_init(rdev); | 1170 | r = radeon_fence_driver_init(rdev); |
1126 | if (r) | 1171 | if (r) |
@@ -1195,9 +1240,9 @@ void rv770_fini(struct radeon_device *rdev) | |||
1195 | r600_irq_fini(rdev); | 1240 | r600_irq_fini(rdev); |
1196 | radeon_irq_kms_fini(rdev); | 1241 | radeon_irq_kms_fini(rdev); |
1197 | rv770_pcie_gart_fini(rdev); | 1242 | rv770_pcie_gart_fini(rdev); |
1243 | rv770_vram_scratch_fini(rdev); | ||
1198 | radeon_gem_fini(rdev); | 1244 | radeon_gem_fini(rdev); |
1199 | radeon_fence_driver_fini(rdev); | 1245 | radeon_fence_driver_fini(rdev); |
1200 | radeon_clocks_fini(rdev); | ||
1201 | radeon_agp_fini(rdev); | 1246 | radeon_agp_fini(rdev); |
1202 | radeon_bo_fini(rdev); | 1247 | radeon_bo_fini(rdev); |
1203 | radeon_atombios_fini(rdev); | 1248 | radeon_atombios_fini(rdev); |
diff --git a/drivers/gpu/drm/savage/savage_bci.c b/drivers/gpu/drm/savage/savage_bci.c index 976dc8d2528..bf5f83ea14f 100644 --- a/drivers/gpu/drm/savage/savage_bci.c +++ b/drivers/gpu/drm/savage/savage_bci.c | |||
@@ -1082,10 +1082,10 @@ void savage_reclaim_buffers(struct drm_device *dev, struct drm_file *file_priv) | |||
1082 | } | 1082 | } |
1083 | 1083 | ||
1084 | struct drm_ioctl_desc savage_ioctls[] = { | 1084 | struct drm_ioctl_desc savage_ioctls[] = { |
1085 | DRM_IOCTL_DEF(DRM_SAVAGE_BCI_INIT, savage_bci_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1085 | DRM_IOCTL_DEF_DRV(SAVAGE_BCI_INIT, savage_bci_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
1086 | DRM_IOCTL_DEF(DRM_SAVAGE_BCI_CMDBUF, savage_bci_cmdbuf, DRM_AUTH), | 1086 | DRM_IOCTL_DEF_DRV(SAVAGE_BCI_CMDBUF, savage_bci_cmdbuf, DRM_AUTH), |
1087 | DRM_IOCTL_DEF(DRM_SAVAGE_BCI_EVENT_EMIT, savage_bci_event_emit, DRM_AUTH), | 1087 | DRM_IOCTL_DEF_DRV(SAVAGE_BCI_EVENT_EMIT, savage_bci_event_emit, DRM_AUTH), |
1088 | DRM_IOCTL_DEF(DRM_SAVAGE_BCI_EVENT_WAIT, savage_bci_event_wait, DRM_AUTH), | 1088 | DRM_IOCTL_DEF_DRV(SAVAGE_BCI_EVENT_WAIT, savage_bci_event_wait, DRM_AUTH), |
1089 | }; | 1089 | }; |
1090 | 1090 | ||
1091 | int savage_max_ioctl = DRM_ARRAY_SIZE(savage_ioctls); | 1091 | int savage_max_ioctl = DRM_ARRAY_SIZE(savage_ioctls); |
diff --git a/drivers/gpu/drm/sis/sis_mm.c b/drivers/gpu/drm/sis/sis_mm.c index 07d0f2979ca..7fe2b63412c 100644 --- a/drivers/gpu/drm/sis/sis_mm.c +++ b/drivers/gpu/drm/sis/sis_mm.c | |||
@@ -320,12 +320,12 @@ void sis_reclaim_buffers_locked(struct drm_device *dev, | |||
320 | } | 320 | } |
321 | 321 | ||
322 | struct drm_ioctl_desc sis_ioctls[] = { | 322 | struct drm_ioctl_desc sis_ioctls[] = { |
323 | DRM_IOCTL_DEF(DRM_SIS_FB_ALLOC, sis_fb_alloc, DRM_AUTH), | 323 | DRM_IOCTL_DEF_DRV(SIS_FB_ALLOC, sis_fb_alloc, DRM_AUTH), |
324 | DRM_IOCTL_DEF(DRM_SIS_FB_FREE, sis_drm_free, DRM_AUTH), | 324 | DRM_IOCTL_DEF_DRV(SIS_FB_FREE, sis_drm_free, DRM_AUTH), |
325 | DRM_IOCTL_DEF(DRM_SIS_AGP_INIT, sis_ioctl_agp_init, DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY), | 325 | DRM_IOCTL_DEF_DRV(SIS_AGP_INIT, sis_ioctl_agp_init, DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY), |
326 | DRM_IOCTL_DEF(DRM_SIS_AGP_ALLOC, sis_ioctl_agp_alloc, DRM_AUTH), | 326 | DRM_IOCTL_DEF_DRV(SIS_AGP_ALLOC, sis_ioctl_agp_alloc, DRM_AUTH), |
327 | DRM_IOCTL_DEF(DRM_SIS_AGP_FREE, sis_drm_free, DRM_AUTH), | 327 | DRM_IOCTL_DEF_DRV(SIS_AGP_FREE, sis_drm_free, DRM_AUTH), |
328 | DRM_IOCTL_DEF(DRM_SIS_FB_INIT, sis_fb_init, DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY), | 328 | DRM_IOCTL_DEF_DRV(SIS_FB_INIT, sis_fb_init, DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY), |
329 | }; | 329 | }; |
330 | 330 | ||
331 | int sis_max_ioctl = DRM_ARRAY_SIZE(sis_ioctls); | 331 | int sis_max_ioctl = DRM_ARRAY_SIZE(sis_ioctls); |
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index cb4cf7ef4d1..db809e034cc 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c | |||
@@ -442,6 +442,43 @@ out_err: | |||
442 | } | 442 | } |
443 | 443 | ||
444 | /** | 444 | /** |
445 | * Call bo::reserved and with the lru lock held. | ||
446 | * Will release GPU memory type usage on destruction. | ||
447 | * This is the place to put in driver specific hooks. | ||
448 | * Will release the bo::reserved lock and the | ||
449 | * lru lock on exit. | ||
450 | */ | ||
451 | |||
452 | static void ttm_bo_cleanup_memtype_use(struct ttm_buffer_object *bo) | ||
453 | { | ||
454 | struct ttm_bo_global *glob = bo->glob; | ||
455 | |||
456 | if (bo->ttm) { | ||
457 | |||
458 | /** | ||
459 | * Release the lru_lock, since we don't want to have | ||
460 | * an atomic requirement on ttm_tt[unbind|destroy]. | ||
461 | */ | ||
462 | |||
463 | spin_unlock(&glob->lru_lock); | ||
464 | ttm_tt_unbind(bo->ttm); | ||
465 | ttm_tt_destroy(bo->ttm); | ||
466 | bo->ttm = NULL; | ||
467 | spin_lock(&glob->lru_lock); | ||
468 | } | ||
469 | |||
470 | if (bo->mem.mm_node) { | ||
471 | drm_mm_put_block(bo->mem.mm_node); | ||
472 | bo->mem.mm_node = NULL; | ||
473 | } | ||
474 | |||
475 | atomic_set(&bo->reserved, 0); | ||
476 | wake_up_all(&bo->event_queue); | ||
477 | spin_unlock(&glob->lru_lock); | ||
478 | } | ||
479 | |||
480 | |||
481 | /** | ||
445 | * If bo idle, remove from delayed- and lru lists, and unref. | 482 | * If bo idle, remove from delayed- and lru lists, and unref. |
446 | * If not idle, and already on delayed list, do nothing. | 483 | * If not idle, and already on delayed list, do nothing. |
447 | * If not idle, and not on delayed list, put on delayed list, | 484 | * If not idle, and not on delayed list, put on delayed list, |
@@ -456,6 +493,7 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all) | |||
456 | int ret; | 493 | int ret; |
457 | 494 | ||
458 | spin_lock(&bo->lock); | 495 | spin_lock(&bo->lock); |
496 | retry: | ||
459 | (void) ttm_bo_wait(bo, false, false, !remove_all); | 497 | (void) ttm_bo_wait(bo, false, false, !remove_all); |
460 | 498 | ||
461 | if (!bo->sync_obj) { | 499 | if (!bo->sync_obj) { |
@@ -464,31 +502,52 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all) | |||
464 | spin_unlock(&bo->lock); | 502 | spin_unlock(&bo->lock); |
465 | 503 | ||
466 | spin_lock(&glob->lru_lock); | 504 | spin_lock(&glob->lru_lock); |
467 | put_count = ttm_bo_del_from_lru(bo); | 505 | ret = ttm_bo_reserve_locked(bo, false, !remove_all, false, 0); |
506 | |||
507 | /** | ||
508 | * Someone else has the object reserved. Bail and retry. | ||
509 | */ | ||
468 | 510 | ||
469 | ret = ttm_bo_reserve_locked(bo, false, false, false, 0); | 511 | if (unlikely(ret == -EBUSY)) { |
470 | BUG_ON(ret); | 512 | spin_unlock(&glob->lru_lock); |
471 | if (bo->ttm) | 513 | spin_lock(&bo->lock); |
472 | ttm_tt_unbind(bo->ttm); | 514 | goto requeue; |
515 | } | ||
516 | |||
517 | /** | ||
518 | * We can re-check for sync object without taking | ||
519 | * the bo::lock since setting the sync object requires | ||
520 | * also bo::reserved. A busy object at this point may | ||
521 | * be caused by another thread starting an accelerated | ||
522 | * eviction. | ||
523 | */ | ||
524 | |||
525 | if (unlikely(bo->sync_obj)) { | ||
526 | atomic_set(&bo->reserved, 0); | ||
527 | wake_up_all(&bo->event_queue); | ||
528 | spin_unlock(&glob->lru_lock); | ||
529 | spin_lock(&bo->lock); | ||
530 | if (remove_all) | ||
531 | goto retry; | ||
532 | else | ||
533 | goto requeue; | ||
534 | } | ||
535 | |||
536 | put_count = ttm_bo_del_from_lru(bo); | ||
473 | 537 | ||
474 | if (!list_empty(&bo->ddestroy)) { | 538 | if (!list_empty(&bo->ddestroy)) { |
475 | list_del_init(&bo->ddestroy); | 539 | list_del_init(&bo->ddestroy); |
476 | ++put_count; | 540 | ++put_count; |
477 | } | 541 | } |
478 | if (bo->mem.mm_node) { | ||
479 | drm_mm_put_block(bo->mem.mm_node); | ||
480 | bo->mem.mm_node = NULL; | ||
481 | } | ||
482 | spin_unlock(&glob->lru_lock); | ||
483 | 542 | ||
484 | atomic_set(&bo->reserved, 0); | 543 | ttm_bo_cleanup_memtype_use(bo); |
485 | 544 | ||
486 | while (put_count--) | 545 | while (put_count--) |
487 | kref_put(&bo->list_kref, ttm_bo_ref_bug); | 546 | kref_put(&bo->list_kref, ttm_bo_ref_bug); |
488 | 547 | ||
489 | return 0; | 548 | return 0; |
490 | } | 549 | } |
491 | 550 | requeue: | |
492 | spin_lock(&glob->lru_lock); | 551 | spin_lock(&glob->lru_lock); |
493 | if (list_empty(&bo->ddestroy)) { | 552 | if (list_empty(&bo->ddestroy)) { |
494 | void *sync_obj = bo->sync_obj; | 553 | void *sync_obj = bo->sync_obj; |
diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index 7cffb3e0423..3451a82adba 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c | |||
@@ -351,6 +351,7 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo, | |||
351 | INIT_LIST_HEAD(&fbo->lru); | 351 | INIT_LIST_HEAD(&fbo->lru); |
352 | INIT_LIST_HEAD(&fbo->swap); | 352 | INIT_LIST_HEAD(&fbo->swap); |
353 | fbo->vm_node = NULL; | 353 | fbo->vm_node = NULL; |
354 | atomic_set(&fbo->cpu_writers, 0); | ||
354 | 355 | ||
355 | fbo->sync_obj = driver->sync_obj_ref(bo->sync_obj); | 356 | fbo->sync_obj = driver->sync_obj_ref(bo->sync_obj); |
356 | kref_init(&fbo->list_kref); | 357 | kref_init(&fbo->list_kref); |
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c index ca904799f01..b1e02fffd3c 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c | |||
@@ -69,7 +69,7 @@ struct ttm_page_pool { | |||
69 | spinlock_t lock; | 69 | spinlock_t lock; |
70 | bool fill_lock; | 70 | bool fill_lock; |
71 | struct list_head list; | 71 | struct list_head list; |
72 | int gfp_flags; | 72 | gfp_t gfp_flags; |
73 | unsigned npages; | 73 | unsigned npages; |
74 | char *name; | 74 | char *name; |
75 | unsigned long nfrees; | 75 | unsigned long nfrees; |
@@ -475,7 +475,7 @@ static void ttm_handle_caching_state_failure(struct list_head *pages, | |||
475 | * This function is reentrant if caller updates count depending on number of | 475 | * This function is reentrant if caller updates count depending on number of |
476 | * pages returned in pages array. | 476 | * pages returned in pages array. |
477 | */ | 477 | */ |
478 | static int ttm_alloc_new_pages(struct list_head *pages, int gfp_flags, | 478 | static int ttm_alloc_new_pages(struct list_head *pages, gfp_t gfp_flags, |
479 | int ttm_flags, enum ttm_caching_state cstate, unsigned count) | 479 | int ttm_flags, enum ttm_caching_state cstate, unsigned count) |
480 | { | 480 | { |
481 | struct page **caching_array; | 481 | struct page **caching_array; |
@@ -666,7 +666,7 @@ int ttm_get_pages(struct list_head *pages, int flags, | |||
666 | { | 666 | { |
667 | struct ttm_page_pool *pool = ttm_get_pool(flags, cstate); | 667 | struct ttm_page_pool *pool = ttm_get_pool(flags, cstate); |
668 | struct page *p = NULL; | 668 | struct page *p = NULL; |
669 | int gfp_flags = GFP_USER; | 669 | gfp_t gfp_flags = GFP_USER; |
670 | int r; | 670 | int r; |
671 | 671 | ||
672 | /* set zero flag for page allocation if required */ | 672 | /* set zero flag for page allocation if required */ |
@@ -818,7 +818,7 @@ int ttm_page_alloc_init(struct ttm_mem_global *glob, unsigned max_pages) | |||
818 | return 0; | 818 | return 0; |
819 | } | 819 | } |
820 | 820 | ||
821 | void ttm_page_alloc_fini() | 821 | void ttm_page_alloc_fini(void) |
822 | { | 822 | { |
823 | int i; | 823 | int i; |
824 | 824 | ||
diff --git a/drivers/gpu/drm/via/via_dma.c b/drivers/gpu/drm/via/via_dma.c index 68dda74a50a..cc0ffa9abd0 100644 --- a/drivers/gpu/drm/via/via_dma.c +++ b/drivers/gpu/drm/via/via_dma.c | |||
@@ -722,20 +722,20 @@ static int via_cmdbuf_size(struct drm_device *dev, void *data, struct drm_file * | |||
722 | } | 722 | } |
723 | 723 | ||
724 | struct drm_ioctl_desc via_ioctls[] = { | 724 | struct drm_ioctl_desc via_ioctls[] = { |
725 | DRM_IOCTL_DEF(DRM_VIA_ALLOCMEM, via_mem_alloc, DRM_AUTH), | 725 | DRM_IOCTL_DEF_DRV(VIA_ALLOCMEM, via_mem_alloc, DRM_AUTH), |
726 | DRM_IOCTL_DEF(DRM_VIA_FREEMEM, via_mem_free, DRM_AUTH), | 726 | DRM_IOCTL_DEF_DRV(VIA_FREEMEM, via_mem_free, DRM_AUTH), |
727 | DRM_IOCTL_DEF(DRM_VIA_AGP_INIT, via_agp_init, DRM_AUTH|DRM_MASTER), | 727 | DRM_IOCTL_DEF_DRV(VIA_AGP_INIT, via_agp_init, DRM_AUTH|DRM_MASTER), |
728 | DRM_IOCTL_DEF(DRM_VIA_FB_INIT, via_fb_init, DRM_AUTH|DRM_MASTER), | 728 | DRM_IOCTL_DEF_DRV(VIA_FB_INIT, via_fb_init, DRM_AUTH|DRM_MASTER), |
729 | DRM_IOCTL_DEF(DRM_VIA_MAP_INIT, via_map_init, DRM_AUTH|DRM_MASTER), | 729 | DRM_IOCTL_DEF_DRV(VIA_MAP_INIT, via_map_init, DRM_AUTH|DRM_MASTER), |
730 | DRM_IOCTL_DEF(DRM_VIA_DEC_FUTEX, via_decoder_futex, DRM_AUTH), | 730 | DRM_IOCTL_DEF_DRV(VIA_DEC_FUTEX, via_decoder_futex, DRM_AUTH), |
731 | DRM_IOCTL_DEF(DRM_VIA_DMA_INIT, via_dma_init, DRM_AUTH), | 731 | DRM_IOCTL_DEF_DRV(VIA_DMA_INIT, via_dma_init, DRM_AUTH), |
732 | DRM_IOCTL_DEF(DRM_VIA_CMDBUFFER, via_cmdbuffer, DRM_AUTH), | 732 | DRM_IOCTL_DEF_DRV(VIA_CMDBUFFER, via_cmdbuffer, DRM_AUTH), |
733 | DRM_IOCTL_DEF(DRM_VIA_FLUSH, via_flush_ioctl, DRM_AUTH), | 733 | DRM_IOCTL_DEF_DRV(VIA_FLUSH, via_flush_ioctl, DRM_AUTH), |
734 | DRM_IOCTL_DEF(DRM_VIA_PCICMD, via_pci_cmdbuffer, DRM_AUTH), | 734 | DRM_IOCTL_DEF_DRV(VIA_PCICMD, via_pci_cmdbuffer, DRM_AUTH), |
735 | DRM_IOCTL_DEF(DRM_VIA_CMDBUF_SIZE, via_cmdbuf_size, DRM_AUTH), | 735 | DRM_IOCTL_DEF_DRV(VIA_CMDBUF_SIZE, via_cmdbuf_size, DRM_AUTH), |
736 | DRM_IOCTL_DEF(DRM_VIA_WAIT_IRQ, via_wait_irq, DRM_AUTH), | 736 | DRM_IOCTL_DEF_DRV(VIA_WAIT_IRQ, via_wait_irq, DRM_AUTH), |
737 | DRM_IOCTL_DEF(DRM_VIA_DMA_BLIT, via_dma_blit, DRM_AUTH), | 737 | DRM_IOCTL_DEF_DRV(VIA_DMA_BLIT, via_dma_blit, DRM_AUTH), |
738 | DRM_IOCTL_DEF(DRM_VIA_BLIT_SYNC, via_dma_blit_sync, DRM_AUTH) | 738 | DRM_IOCTL_DEF_DRV(VIA_BLIT_SYNC, via_dma_blit_sync, DRM_AUTH) |
739 | }; | 739 | }; |
740 | 740 | ||
741 | int via_max_ioctl = DRM_ARRAY_SIZE(via_ioctls); | 741 | int via_max_ioctl = DRM_ARRAY_SIZE(via_ioctls); |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 9dd395b9021..a96ed6d9d01 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | |||
@@ -99,47 +99,47 @@ | |||
99 | */ | 99 | */ |
100 | 100 | ||
101 | #define VMW_IOCTL_DEF(ioctl, func, flags) \ | 101 | #define VMW_IOCTL_DEF(ioctl, func, flags) \ |
102 | [DRM_IOCTL_NR(ioctl) - DRM_COMMAND_BASE] = {ioctl, flags, func} | 102 | [DRM_IOCTL_NR(DRM_IOCTL_##ioctl) - DRM_COMMAND_BASE] = {DRM_##ioctl, flags, func, DRM_IOCTL_##ioctl} |
103 | 103 | ||
104 | /** | 104 | /** |
105 | * Ioctl definitions. | 105 | * Ioctl definitions. |
106 | */ | 106 | */ |
107 | 107 | ||
108 | static struct drm_ioctl_desc vmw_ioctls[] = { | 108 | static struct drm_ioctl_desc vmw_ioctls[] = { |
109 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_GET_PARAM, vmw_getparam_ioctl, | 109 | VMW_IOCTL_DEF(VMW_GET_PARAM, vmw_getparam_ioctl, |
110 | DRM_AUTH | DRM_UNLOCKED), | 110 | DRM_AUTH | DRM_UNLOCKED), |
111 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_ALLOC_DMABUF, vmw_dmabuf_alloc_ioctl, | 111 | VMW_IOCTL_DEF(VMW_ALLOC_DMABUF, vmw_dmabuf_alloc_ioctl, |
112 | DRM_AUTH | DRM_UNLOCKED), | 112 | DRM_AUTH | DRM_UNLOCKED), |
113 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_DMABUF, vmw_dmabuf_unref_ioctl, | 113 | VMW_IOCTL_DEF(VMW_UNREF_DMABUF, vmw_dmabuf_unref_ioctl, |
114 | DRM_AUTH | DRM_UNLOCKED), | 114 | DRM_AUTH | DRM_UNLOCKED), |
115 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_CURSOR_BYPASS, | 115 | VMW_IOCTL_DEF(VMW_CURSOR_BYPASS, |
116 | vmw_kms_cursor_bypass_ioctl, | 116 | vmw_kms_cursor_bypass_ioctl, |
117 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), | 117 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), |
118 | 118 | ||
119 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_CONTROL_STREAM, vmw_overlay_ioctl, | 119 | VMW_IOCTL_DEF(VMW_CONTROL_STREAM, vmw_overlay_ioctl, |
120 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), | 120 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), |
121 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_CLAIM_STREAM, vmw_stream_claim_ioctl, | 121 | VMW_IOCTL_DEF(VMW_CLAIM_STREAM, vmw_stream_claim_ioctl, |
122 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), | 122 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), |
123 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_STREAM, vmw_stream_unref_ioctl, | 123 | VMW_IOCTL_DEF(VMW_UNREF_STREAM, vmw_stream_unref_ioctl, |
124 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), | 124 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), |
125 | 125 | ||
126 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_CREATE_CONTEXT, vmw_context_define_ioctl, | 126 | VMW_IOCTL_DEF(VMW_CREATE_CONTEXT, vmw_context_define_ioctl, |
127 | DRM_AUTH | DRM_UNLOCKED), | 127 | DRM_AUTH | DRM_UNLOCKED), |
128 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_CONTEXT, vmw_context_destroy_ioctl, | 128 | VMW_IOCTL_DEF(VMW_UNREF_CONTEXT, vmw_context_destroy_ioctl, |
129 | DRM_AUTH | DRM_UNLOCKED), | 129 | DRM_AUTH | DRM_UNLOCKED), |
130 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_CREATE_SURFACE, vmw_surface_define_ioctl, | 130 | VMW_IOCTL_DEF(VMW_CREATE_SURFACE, vmw_surface_define_ioctl, |
131 | DRM_AUTH | DRM_UNLOCKED), | 131 | DRM_AUTH | DRM_UNLOCKED), |
132 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_SURFACE, vmw_surface_destroy_ioctl, | 132 | VMW_IOCTL_DEF(VMW_UNREF_SURFACE, vmw_surface_destroy_ioctl, |
133 | DRM_AUTH | DRM_UNLOCKED), | 133 | DRM_AUTH | DRM_UNLOCKED), |
134 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_REF_SURFACE, vmw_surface_reference_ioctl, | 134 | VMW_IOCTL_DEF(VMW_REF_SURFACE, vmw_surface_reference_ioctl, |
135 | DRM_AUTH | DRM_UNLOCKED), | 135 | DRM_AUTH | DRM_UNLOCKED), |
136 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_EXECBUF, vmw_execbuf_ioctl, | 136 | VMW_IOCTL_DEF(VMW_EXECBUF, vmw_execbuf_ioctl, |
137 | DRM_AUTH | DRM_UNLOCKED), | 137 | DRM_AUTH | DRM_UNLOCKED), |
138 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_FIFO_DEBUG, vmw_fifo_debug_ioctl, | 138 | VMW_IOCTL_DEF(VMW_FIFO_DEBUG, vmw_fifo_debug_ioctl, |
139 | DRM_AUTH | DRM_ROOT_ONLY | DRM_MASTER | DRM_UNLOCKED), | 139 | DRM_AUTH | DRM_ROOT_ONLY | DRM_MASTER | DRM_UNLOCKED), |
140 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_FENCE_WAIT, vmw_fence_wait_ioctl, | 140 | VMW_IOCTL_DEF(VMW_FENCE_WAIT, vmw_fence_wait_ioctl, |
141 | DRM_AUTH | DRM_UNLOCKED), | 141 | DRM_AUTH | DRM_UNLOCKED), |
142 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_UPDATE_LAYOUT, vmw_kms_update_layout_ioctl, | 142 | VMW_IOCTL_DEF(VMW_UPDATE_LAYOUT, vmw_kms_update_layout_ioctl, |
143 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED) | 143 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED) |
144 | }; | 144 | }; |
145 | 145 | ||
@@ -148,13 +148,16 @@ static struct pci_device_id vmw_pci_id_list[] = { | |||
148 | {0, 0, 0} | 148 | {0, 0, 0} |
149 | }; | 149 | }; |
150 | 150 | ||
151 | static char *vmw_devname = "vmwgfx"; | 151 | static int enable_fbdev; |
152 | 152 | ||
153 | static int vmw_probe(struct pci_dev *, const struct pci_device_id *); | 153 | static int vmw_probe(struct pci_dev *, const struct pci_device_id *); |
154 | static void vmw_master_init(struct vmw_master *); | 154 | static void vmw_master_init(struct vmw_master *); |
155 | static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val, | 155 | static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val, |
156 | void *ptr); | 156 | void *ptr); |
157 | 157 | ||
158 | MODULE_PARM_DESC(enable_fbdev, "Enable vmwgfx fbdev"); | ||
159 | module_param_named(enable_fbdev, enable_fbdev, int, 0600); | ||
160 | |||
158 | static void vmw_print_capabilities(uint32_t capabilities) | 161 | static void vmw_print_capabilities(uint32_t capabilities) |
159 | { | 162 | { |
160 | DRM_INFO("Capabilities:\n"); | 163 | DRM_INFO("Capabilities:\n"); |
@@ -192,8 +195,6 @@ static int vmw_request_device(struct vmw_private *dev_priv) | |||
192 | { | 195 | { |
193 | int ret; | 196 | int ret; |
194 | 197 | ||
195 | vmw_kms_save_vga(dev_priv); | ||
196 | |||
197 | ret = vmw_fifo_init(dev_priv, &dev_priv->fifo); | 198 | ret = vmw_fifo_init(dev_priv, &dev_priv->fifo); |
198 | if (unlikely(ret != 0)) { | 199 | if (unlikely(ret != 0)) { |
199 | DRM_ERROR("Unable to initialize FIFO.\n"); | 200 | DRM_ERROR("Unable to initialize FIFO.\n"); |
@@ -206,9 +207,35 @@ static int vmw_request_device(struct vmw_private *dev_priv) | |||
206 | static void vmw_release_device(struct vmw_private *dev_priv) | 207 | static void vmw_release_device(struct vmw_private *dev_priv) |
207 | { | 208 | { |
208 | vmw_fifo_release(dev_priv, &dev_priv->fifo); | 209 | vmw_fifo_release(dev_priv, &dev_priv->fifo); |
209 | vmw_kms_restore_vga(dev_priv); | ||
210 | } | 210 | } |
211 | 211 | ||
212 | int vmw_3d_resource_inc(struct vmw_private *dev_priv) | ||
213 | { | ||
214 | int ret = 0; | ||
215 | |||
216 | mutex_lock(&dev_priv->release_mutex); | ||
217 | if (unlikely(dev_priv->num_3d_resources++ == 0)) { | ||
218 | ret = vmw_request_device(dev_priv); | ||
219 | if (unlikely(ret != 0)) | ||
220 | --dev_priv->num_3d_resources; | ||
221 | } | ||
222 | mutex_unlock(&dev_priv->release_mutex); | ||
223 | return ret; | ||
224 | } | ||
225 | |||
226 | |||
227 | void vmw_3d_resource_dec(struct vmw_private *dev_priv) | ||
228 | { | ||
229 | int32_t n3d; | ||
230 | |||
231 | mutex_lock(&dev_priv->release_mutex); | ||
232 | if (unlikely(--dev_priv->num_3d_resources == 0)) | ||
233 | vmw_release_device(dev_priv); | ||
234 | n3d = (int32_t) dev_priv->num_3d_resources; | ||
235 | mutex_unlock(&dev_priv->release_mutex); | ||
236 | |||
237 | BUG_ON(n3d < 0); | ||
238 | } | ||
212 | 239 | ||
213 | static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | 240 | static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) |
214 | { | 241 | { |
@@ -228,6 +255,7 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
228 | dev_priv->last_read_sequence = (uint32_t) -100; | 255 | dev_priv->last_read_sequence = (uint32_t) -100; |
229 | mutex_init(&dev_priv->hw_mutex); | 256 | mutex_init(&dev_priv->hw_mutex); |
230 | mutex_init(&dev_priv->cmdbuf_mutex); | 257 | mutex_init(&dev_priv->cmdbuf_mutex); |
258 | mutex_init(&dev_priv->release_mutex); | ||
231 | rwlock_init(&dev_priv->resource_lock); | 259 | rwlock_init(&dev_priv->resource_lock); |
232 | idr_init(&dev_priv->context_idr); | 260 | idr_init(&dev_priv->context_idr); |
233 | idr_init(&dev_priv->surface_idr); | 261 | idr_init(&dev_priv->surface_idr); |
@@ -244,6 +272,8 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
244 | dev_priv->vram_start = pci_resource_start(dev->pdev, 1); | 272 | dev_priv->vram_start = pci_resource_start(dev->pdev, 1); |
245 | dev_priv->mmio_start = pci_resource_start(dev->pdev, 2); | 273 | dev_priv->mmio_start = pci_resource_start(dev->pdev, 2); |
246 | 274 | ||
275 | dev_priv->enable_fb = enable_fbdev; | ||
276 | |||
247 | mutex_lock(&dev_priv->hw_mutex); | 277 | mutex_lock(&dev_priv->hw_mutex); |
248 | 278 | ||
249 | vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2); | 279 | vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2); |
@@ -343,17 +373,6 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
343 | 373 | ||
344 | dev->dev_private = dev_priv; | 374 | dev->dev_private = dev_priv; |
345 | 375 | ||
346 | if (!dev->devname) | ||
347 | dev->devname = vmw_devname; | ||
348 | |||
349 | if (dev_priv->capabilities & SVGA_CAP_IRQMASK) { | ||
350 | ret = drm_irq_install(dev); | ||
351 | if (unlikely(ret != 0)) { | ||
352 | DRM_ERROR("Failed installing irq: %d\n", ret); | ||
353 | goto out_no_irq; | ||
354 | } | ||
355 | } | ||
356 | |||
357 | ret = pci_request_regions(dev->pdev, "vmwgfx probe"); | 376 | ret = pci_request_regions(dev->pdev, "vmwgfx probe"); |
358 | dev_priv->stealth = (ret != 0); | 377 | dev_priv->stealth = (ret != 0); |
359 | if (dev_priv->stealth) { | 378 | if (dev_priv->stealth) { |
@@ -369,26 +388,52 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
369 | goto out_no_device; | 388 | goto out_no_device; |
370 | } | 389 | } |
371 | } | 390 | } |
372 | ret = vmw_request_device(dev_priv); | 391 | ret = vmw_kms_init(dev_priv); |
373 | if (unlikely(ret != 0)) | 392 | if (unlikely(ret != 0)) |
374 | goto out_no_device; | 393 | goto out_no_kms; |
375 | vmw_kms_init(dev_priv); | ||
376 | vmw_overlay_init(dev_priv); | 394 | vmw_overlay_init(dev_priv); |
377 | vmw_fb_init(dev_priv); | 395 | if (dev_priv->enable_fb) { |
396 | ret = vmw_3d_resource_inc(dev_priv); | ||
397 | if (unlikely(ret != 0)) | ||
398 | goto out_no_fifo; | ||
399 | vmw_kms_save_vga(dev_priv); | ||
400 | vmw_fb_init(dev_priv); | ||
401 | DRM_INFO("%s", vmw_fifo_have_3d(dev_priv) ? | ||
402 | "Detected device 3D availability.\n" : | ||
403 | "Detected no device 3D availability.\n"); | ||
404 | } else { | ||
405 | DRM_INFO("Delayed 3D detection since we're not " | ||
406 | "running the device in SVGA mode yet.\n"); | ||
407 | } | ||
408 | |||
409 | if (dev_priv->capabilities & SVGA_CAP_IRQMASK) { | ||
410 | ret = drm_irq_install(dev); | ||
411 | if (unlikely(ret != 0)) { | ||
412 | DRM_ERROR("Failed installing irq: %d\n", ret); | ||
413 | goto out_no_irq; | ||
414 | } | ||
415 | } | ||
378 | 416 | ||
379 | dev_priv->pm_nb.notifier_call = vmwgfx_pm_notifier; | 417 | dev_priv->pm_nb.notifier_call = vmwgfx_pm_notifier; |
380 | register_pm_notifier(&dev_priv->pm_nb); | 418 | register_pm_notifier(&dev_priv->pm_nb); |
381 | 419 | ||
382 | DRM_INFO("%s", vmw_fifo_have_3d(dev_priv) ? "Have 3D\n" : "No 3D\n"); | ||
383 | |||
384 | return 0; | 420 | return 0; |
385 | 421 | ||
386 | out_no_device: | ||
387 | if (dev_priv->capabilities & SVGA_CAP_IRQMASK) | ||
388 | drm_irq_uninstall(dev_priv->dev); | ||
389 | if (dev->devname == vmw_devname) | ||
390 | dev->devname = NULL; | ||
391 | out_no_irq: | 422 | out_no_irq: |
423 | if (dev_priv->enable_fb) { | ||
424 | vmw_fb_close(dev_priv); | ||
425 | vmw_kms_restore_vga(dev_priv); | ||
426 | vmw_3d_resource_dec(dev_priv); | ||
427 | } | ||
428 | out_no_fifo: | ||
429 | vmw_overlay_close(dev_priv); | ||
430 | vmw_kms_close(dev_priv); | ||
431 | out_no_kms: | ||
432 | if (dev_priv->stealth) | ||
433 | pci_release_region(dev->pdev, 2); | ||
434 | else | ||
435 | pci_release_regions(dev->pdev); | ||
436 | out_no_device: | ||
392 | ttm_object_device_release(&dev_priv->tdev); | 437 | ttm_object_device_release(&dev_priv->tdev); |
393 | out_err4: | 438 | out_err4: |
394 | iounmap(dev_priv->mmio_virt); | 439 | iounmap(dev_priv->mmio_virt); |
@@ -415,19 +460,20 @@ static int vmw_driver_unload(struct drm_device *dev) | |||
415 | 460 | ||
416 | unregister_pm_notifier(&dev_priv->pm_nb); | 461 | unregister_pm_notifier(&dev_priv->pm_nb); |
417 | 462 | ||
418 | vmw_fb_close(dev_priv); | 463 | if (dev_priv->capabilities & SVGA_CAP_IRQMASK) |
464 | drm_irq_uninstall(dev_priv->dev); | ||
465 | if (dev_priv->enable_fb) { | ||
466 | vmw_fb_close(dev_priv); | ||
467 | vmw_kms_restore_vga(dev_priv); | ||
468 | vmw_3d_resource_dec(dev_priv); | ||
469 | } | ||
419 | vmw_kms_close(dev_priv); | 470 | vmw_kms_close(dev_priv); |
420 | vmw_overlay_close(dev_priv); | 471 | vmw_overlay_close(dev_priv); |
421 | vmw_release_device(dev_priv); | ||
422 | if (dev_priv->stealth) | 472 | if (dev_priv->stealth) |
423 | pci_release_region(dev->pdev, 2); | 473 | pci_release_region(dev->pdev, 2); |
424 | else | 474 | else |
425 | pci_release_regions(dev->pdev); | 475 | pci_release_regions(dev->pdev); |
426 | 476 | ||
427 | if (dev_priv->capabilities & SVGA_CAP_IRQMASK) | ||
428 | drm_irq_uninstall(dev_priv->dev); | ||
429 | if (dev->devname == vmw_devname) | ||
430 | dev->devname = NULL; | ||
431 | ttm_object_device_release(&dev_priv->tdev); | 477 | ttm_object_device_release(&dev_priv->tdev); |
432 | iounmap(dev_priv->mmio_virt); | 478 | iounmap(dev_priv->mmio_virt); |
433 | drm_mtrr_del(dev_priv->mmio_mtrr, dev_priv->mmio_start, | 479 | drm_mtrr_del(dev_priv->mmio_mtrr, dev_priv->mmio_start, |
@@ -500,7 +546,7 @@ static long vmw_unlocked_ioctl(struct file *filp, unsigned int cmd, | |||
500 | struct drm_ioctl_desc *ioctl = | 546 | struct drm_ioctl_desc *ioctl = |
501 | &vmw_ioctls[nr - DRM_COMMAND_BASE]; | 547 | &vmw_ioctls[nr - DRM_COMMAND_BASE]; |
502 | 548 | ||
503 | if (unlikely(ioctl->cmd != cmd)) { | 549 | if (unlikely(ioctl->cmd_drv != cmd)) { |
504 | DRM_ERROR("Invalid command format, ioctl %d\n", | 550 | DRM_ERROR("Invalid command format, ioctl %d\n", |
505 | nr - DRM_COMMAND_BASE); | 551 | nr - DRM_COMMAND_BASE); |
506 | return -EINVAL; | 552 | return -EINVAL; |
@@ -589,6 +635,16 @@ static int vmw_master_set(struct drm_device *dev, | |||
589 | struct vmw_master *vmaster = vmw_master(file_priv->master); | 635 | struct vmw_master *vmaster = vmw_master(file_priv->master); |
590 | int ret = 0; | 636 | int ret = 0; |
591 | 637 | ||
638 | if (!dev_priv->enable_fb) { | ||
639 | ret = vmw_3d_resource_inc(dev_priv); | ||
640 | if (unlikely(ret != 0)) | ||
641 | return ret; | ||
642 | vmw_kms_save_vga(dev_priv); | ||
643 | mutex_lock(&dev_priv->hw_mutex); | ||
644 | vmw_write(dev_priv, SVGA_REG_TRACES, 0); | ||
645 | mutex_unlock(&dev_priv->hw_mutex); | ||
646 | } | ||
647 | |||
592 | if (active) { | 648 | if (active) { |
593 | BUG_ON(active != &dev_priv->fbdev_master); | 649 | BUG_ON(active != &dev_priv->fbdev_master); |
594 | ret = ttm_vt_lock(&active->lock, false, vmw_fp->tfile); | 650 | ret = ttm_vt_lock(&active->lock, false, vmw_fp->tfile); |
@@ -617,7 +673,13 @@ static int vmw_master_set(struct drm_device *dev, | |||
617 | return 0; | 673 | return 0; |
618 | 674 | ||
619 | out_no_active_lock: | 675 | out_no_active_lock: |
620 | vmw_release_device(dev_priv); | 676 | if (!dev_priv->enable_fb) { |
677 | mutex_lock(&dev_priv->hw_mutex); | ||
678 | vmw_write(dev_priv, SVGA_REG_TRACES, 1); | ||
679 | mutex_unlock(&dev_priv->hw_mutex); | ||
680 | vmw_kms_restore_vga(dev_priv); | ||
681 | vmw_3d_resource_dec(dev_priv); | ||
682 | } | ||
621 | return ret; | 683 | return ret; |
622 | } | 684 | } |
623 | 685 | ||
@@ -645,11 +707,23 @@ static void vmw_master_drop(struct drm_device *dev, | |||
645 | 707 | ||
646 | ttm_lock_set_kill(&vmaster->lock, true, SIGTERM); | 708 | ttm_lock_set_kill(&vmaster->lock, true, SIGTERM); |
647 | 709 | ||
710 | if (!dev_priv->enable_fb) { | ||
711 | ret = ttm_bo_evict_mm(&dev_priv->bdev, TTM_PL_VRAM); | ||
712 | if (unlikely(ret != 0)) | ||
713 | DRM_ERROR("Unable to clean VRAM on master drop.\n"); | ||
714 | mutex_lock(&dev_priv->hw_mutex); | ||
715 | vmw_write(dev_priv, SVGA_REG_TRACES, 1); | ||
716 | mutex_unlock(&dev_priv->hw_mutex); | ||
717 | vmw_kms_restore_vga(dev_priv); | ||
718 | vmw_3d_resource_dec(dev_priv); | ||
719 | } | ||
720 | |||
648 | dev_priv->active_master = &dev_priv->fbdev_master; | 721 | dev_priv->active_master = &dev_priv->fbdev_master; |
649 | ttm_lock_set_kill(&dev_priv->fbdev_master.lock, false, SIGTERM); | 722 | ttm_lock_set_kill(&dev_priv->fbdev_master.lock, false, SIGTERM); |
650 | ttm_vt_unlock(&dev_priv->fbdev_master.lock); | 723 | ttm_vt_unlock(&dev_priv->fbdev_master.lock); |
651 | 724 | ||
652 | vmw_fb_on(dev_priv); | 725 | if (dev_priv->enable_fb) |
726 | vmw_fb_on(dev_priv); | ||
653 | } | 727 | } |
654 | 728 | ||
655 | 729 | ||
@@ -722,6 +796,7 @@ static struct drm_driver driver = { | |||
722 | .irq_postinstall = vmw_irq_postinstall, | 796 | .irq_postinstall = vmw_irq_postinstall, |
723 | .irq_uninstall = vmw_irq_uninstall, | 797 | .irq_uninstall = vmw_irq_uninstall, |
724 | .irq_handler = vmw_irq_handler, | 798 | .irq_handler = vmw_irq_handler, |
799 | .get_vblank_counter = vmw_get_vblank_counter, | ||
725 | .reclaim_buffers_locked = NULL, | 800 | .reclaim_buffers_locked = NULL, |
726 | .get_map_ofs = drm_core_get_map_ofs, | 801 | .get_map_ofs = drm_core_get_map_ofs, |
727 | .get_reg_ofs = drm_core_get_reg_ofs, | 802 | .get_reg_ofs = drm_core_get_reg_ofs, |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 429f917b60b..58de6393f61 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | |||
@@ -277,6 +277,7 @@ struct vmw_private { | |||
277 | 277 | ||
278 | bool stealth; | 278 | bool stealth; |
279 | bool is_opened; | 279 | bool is_opened; |
280 | bool enable_fb; | ||
280 | 281 | ||
281 | /** | 282 | /** |
282 | * Master management. | 283 | * Master management. |
@@ -285,6 +286,9 @@ struct vmw_private { | |||
285 | struct vmw_master *active_master; | 286 | struct vmw_master *active_master; |
286 | struct vmw_master fbdev_master; | 287 | struct vmw_master fbdev_master; |
287 | struct notifier_block pm_nb; | 288 | struct notifier_block pm_nb; |
289 | |||
290 | struct mutex release_mutex; | ||
291 | uint32_t num_3d_resources; | ||
288 | }; | 292 | }; |
289 | 293 | ||
290 | static inline struct vmw_private *vmw_priv(struct drm_device *dev) | 294 | static inline struct vmw_private *vmw_priv(struct drm_device *dev) |
@@ -319,6 +323,9 @@ static inline uint32_t vmw_read(struct vmw_private *dev_priv, | |||
319 | return val; | 323 | return val; |
320 | } | 324 | } |
321 | 325 | ||
326 | int vmw_3d_resource_inc(struct vmw_private *dev_priv); | ||
327 | void vmw_3d_resource_dec(struct vmw_private *dev_priv); | ||
328 | |||
322 | /** | 329 | /** |
323 | * GMR utilities - vmwgfx_gmr.c | 330 | * GMR utilities - vmwgfx_gmr.c |
324 | */ | 331 | */ |
@@ -511,6 +518,7 @@ void vmw_kms_write_svga(struct vmw_private *vmw_priv, | |||
511 | unsigned bbp, unsigned depth); | 518 | unsigned bbp, unsigned depth); |
512 | int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, | 519 | int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, |
513 | struct drm_file *file_priv); | 520 | struct drm_file *file_priv); |
521 | u32 vmw_get_vblank_counter(struct drm_device *dev, int crtc); | ||
514 | 522 | ||
515 | /** | 523 | /** |
516 | * Overlay control - vmwgfx_overlay.c | 524 | * Overlay control - vmwgfx_overlay.c |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c index 870967a97c1..409e172f4ab 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | |||
@@ -615,6 +615,11 @@ int vmw_dmabuf_to_start_of_vram(struct vmw_private *vmw_priv, | |||
615 | if (unlikely(ret != 0)) | 615 | if (unlikely(ret != 0)) |
616 | goto err_unlock; | 616 | goto err_unlock; |
617 | 617 | ||
618 | if (bo->mem.mem_type == TTM_PL_VRAM && | ||
619 | bo->mem.mm_node->start < bo->num_pages) | ||
620 | (void) ttm_bo_validate(bo, &vmw_sys_placement, false, | ||
621 | false, false); | ||
622 | |||
618 | ret = ttm_bo_validate(bo, &ne_placement, false, false, false); | 623 | ret = ttm_bo_validate(bo, &ne_placement, false, false, false); |
619 | 624 | ||
620 | /* Could probably bug on */ | 625 | /* Could probably bug on */ |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c index e6a1eb7ea95..0fe31766e4c 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c | |||
@@ -106,6 +106,7 @@ int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) | |||
106 | mutex_lock(&dev_priv->hw_mutex); | 106 | mutex_lock(&dev_priv->hw_mutex); |
107 | dev_priv->enable_state = vmw_read(dev_priv, SVGA_REG_ENABLE); | 107 | dev_priv->enable_state = vmw_read(dev_priv, SVGA_REG_ENABLE); |
108 | dev_priv->config_done_state = vmw_read(dev_priv, SVGA_REG_CONFIG_DONE); | 108 | dev_priv->config_done_state = vmw_read(dev_priv, SVGA_REG_CONFIG_DONE); |
109 | dev_priv->traces_state = vmw_read(dev_priv, SVGA_REG_TRACES); | ||
109 | vmw_write(dev_priv, SVGA_REG_ENABLE, 1); | 110 | vmw_write(dev_priv, SVGA_REG_ENABLE, 1); |
110 | 111 | ||
111 | min = 4; | 112 | min = 4; |
@@ -175,6 +176,8 @@ void vmw_fifo_release(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) | |||
175 | dev_priv->config_done_state); | 176 | dev_priv->config_done_state); |
176 | vmw_write(dev_priv, SVGA_REG_ENABLE, | 177 | vmw_write(dev_priv, SVGA_REG_ENABLE, |
177 | dev_priv->enable_state); | 178 | dev_priv->enable_state); |
179 | vmw_write(dev_priv, SVGA_REG_TRACES, | ||
180 | dev_priv->traces_state); | ||
178 | 181 | ||
179 | mutex_unlock(&dev_priv->hw_mutex); | 182 | mutex_unlock(&dev_priv->hw_mutex); |
180 | vmw_fence_queue_takedown(&fifo->fence_queue); | 183 | vmw_fence_queue_takedown(&fifo->fence_queue); |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 64d7f47df86..e882ba099f0 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |||
@@ -898,7 +898,19 @@ int vmw_kms_save_vga(struct vmw_private *vmw_priv) | |||
898 | save->width = vmw_read(vmw_priv, SVGA_REG_DISPLAY_WIDTH); | 898 | save->width = vmw_read(vmw_priv, SVGA_REG_DISPLAY_WIDTH); |
899 | save->height = vmw_read(vmw_priv, SVGA_REG_DISPLAY_HEIGHT); | 899 | save->height = vmw_read(vmw_priv, SVGA_REG_DISPLAY_HEIGHT); |
900 | vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); | 900 | vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); |
901 | if (i == 0 && vmw_priv->num_displays == 1 && | ||
902 | save->width == 0 && save->height == 0) { | ||
903 | |||
904 | /* | ||
905 | * It should be fairly safe to assume that these | ||
906 | * values are uninitialized. | ||
907 | */ | ||
908 | |||
909 | save->width = vmw_priv->vga_width - save->pos_x; | ||
910 | save->height = vmw_priv->vga_height - save->pos_y; | ||
911 | } | ||
901 | } | 912 | } |
913 | |||
902 | return 0; | 914 | return 0; |
903 | } | 915 | } |
904 | 916 | ||
@@ -984,3 +996,8 @@ out_unlock: | |||
984 | ttm_read_unlock(&vmaster->lock); | 996 | ttm_read_unlock(&vmaster->lock); |
985 | return ret; | 997 | return ret; |
986 | } | 998 | } |
999 | |||
1000 | u32 vmw_get_vblank_counter(struct drm_device *dev, int crtc) | ||
1001 | { | ||
1002 | return 0; | ||
1003 | } | ||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index 2ff5cf78235..11cb39e3acc 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | |||
@@ -27,6 +27,8 @@ | |||
27 | 27 | ||
28 | #include "vmwgfx_kms.h" | 28 | #include "vmwgfx_kms.h" |
29 | 29 | ||
30 | #define VMWGFX_LDU_NUM_DU 8 | ||
31 | |||
30 | #define vmw_crtc_to_ldu(x) \ | 32 | #define vmw_crtc_to_ldu(x) \ |
31 | container_of(x, struct vmw_legacy_display_unit, base.crtc) | 33 | container_of(x, struct vmw_legacy_display_unit, base.crtc) |
32 | #define vmw_encoder_to_ldu(x) \ | 34 | #define vmw_encoder_to_ldu(x) \ |
@@ -335,7 +337,8 @@ static void vmw_ldu_connector_restore(struct drm_connector *connector) | |||
335 | } | 337 | } |
336 | 338 | ||
337 | static enum drm_connector_status | 339 | static enum drm_connector_status |
338 | vmw_ldu_connector_detect(struct drm_connector *connector) | 340 | vmw_ldu_connector_detect(struct drm_connector *connector, |
341 | bool force) | ||
339 | { | 342 | { |
340 | if (vmw_connector_to_ldu(connector)->pref_active) | 343 | if (vmw_connector_to_ldu(connector)->pref_active) |
341 | return connector_status_connected; | 344 | return connector_status_connected; |
@@ -516,7 +519,7 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit) | |||
516 | 519 | ||
517 | drm_connector_init(dev, connector, &vmw_legacy_connector_funcs, | 520 | drm_connector_init(dev, connector, &vmw_legacy_connector_funcs, |
518 | DRM_MODE_CONNECTOR_LVDS); | 521 | DRM_MODE_CONNECTOR_LVDS); |
519 | connector->status = vmw_ldu_connector_detect(connector); | 522 | connector->status = vmw_ldu_connector_detect(connector, true); |
520 | 523 | ||
521 | drm_encoder_init(dev, encoder, &vmw_legacy_encoder_funcs, | 524 | drm_encoder_init(dev, encoder, &vmw_legacy_encoder_funcs, |
522 | DRM_MODE_ENCODER_LVDS); | 525 | DRM_MODE_ENCODER_LVDS); |
@@ -535,6 +538,10 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit) | |||
535 | 538 | ||
536 | int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv) | 539 | int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv) |
537 | { | 540 | { |
541 | struct drm_device *dev = dev_priv->dev; | ||
542 | int i; | ||
543 | int ret; | ||
544 | |||
538 | if (dev_priv->ldu_priv) { | 545 | if (dev_priv->ldu_priv) { |
539 | DRM_INFO("ldu system already on\n"); | 546 | DRM_INFO("ldu system already on\n"); |
540 | return -EINVAL; | 547 | return -EINVAL; |
@@ -552,23 +559,24 @@ int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv) | |||
552 | 559 | ||
553 | drm_mode_create_dirty_info_property(dev_priv->dev); | 560 | drm_mode_create_dirty_info_property(dev_priv->dev); |
554 | 561 | ||
555 | vmw_ldu_init(dev_priv, 0); | ||
556 | /* for old hardware without multimon only enable one display */ | ||
557 | if (dev_priv->capabilities & SVGA_CAP_MULTIMON) { | 562 | if (dev_priv->capabilities & SVGA_CAP_MULTIMON) { |
558 | vmw_ldu_init(dev_priv, 1); | 563 | for (i = 0; i < VMWGFX_LDU_NUM_DU; ++i) |
559 | vmw_ldu_init(dev_priv, 2); | 564 | vmw_ldu_init(dev_priv, i); |
560 | vmw_ldu_init(dev_priv, 3); | 565 | ret = drm_vblank_init(dev, VMWGFX_LDU_NUM_DU); |
561 | vmw_ldu_init(dev_priv, 4); | 566 | } else { |
562 | vmw_ldu_init(dev_priv, 5); | 567 | /* for old hardware without multimon only enable one display */ |
563 | vmw_ldu_init(dev_priv, 6); | 568 | vmw_ldu_init(dev_priv, 0); |
564 | vmw_ldu_init(dev_priv, 7); | 569 | ret = drm_vblank_init(dev, 1); |
565 | } | 570 | } |
566 | 571 | ||
567 | return 0; | 572 | return ret; |
568 | } | 573 | } |
569 | 574 | ||
570 | int vmw_kms_close_legacy_display_system(struct vmw_private *dev_priv) | 575 | int vmw_kms_close_legacy_display_system(struct vmw_private *dev_priv) |
571 | { | 576 | { |
577 | struct drm_device *dev = dev_priv->dev; | ||
578 | |||
579 | drm_vblank_cleanup(dev); | ||
572 | if (!dev_priv->ldu_priv) | 580 | if (!dev_priv->ldu_priv) |
573 | return -ENOSYS; | 581 | return -ENOSYS; |
574 | 582 | ||
@@ -610,7 +618,7 @@ int vmw_kms_ldu_update_layout(struct vmw_private *dev_priv, unsigned num, | |||
610 | ldu->pref_height = 600; | 618 | ldu->pref_height = 600; |
611 | ldu->pref_active = false; | 619 | ldu->pref_active = false; |
612 | } | 620 | } |
613 | con->status = vmw_ldu_connector_detect(con); | 621 | con->status = vmw_ldu_connector_detect(con, true); |
614 | } | 622 | } |
615 | 623 | ||
616 | mutex_unlock(&dev->mode_config.mutex); | 624 | mutex_unlock(&dev->mode_config.mutex); |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index 5f2d5df01e5..c8c40e9979d 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | |||
@@ -211,6 +211,7 @@ static void vmw_hw_context_destroy(struct vmw_resource *res) | |||
211 | cmd->body.cid = cpu_to_le32(res->id); | 211 | cmd->body.cid = cpu_to_le32(res->id); |
212 | 212 | ||
213 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); | 213 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); |
214 | vmw_3d_resource_dec(dev_priv); | ||
214 | } | 215 | } |
215 | 216 | ||
216 | static int vmw_context_init(struct vmw_private *dev_priv, | 217 | static int vmw_context_init(struct vmw_private *dev_priv, |
@@ -247,6 +248,7 @@ static int vmw_context_init(struct vmw_private *dev_priv, | |||
247 | cmd->body.cid = cpu_to_le32(res->id); | 248 | cmd->body.cid = cpu_to_le32(res->id); |
248 | 249 | ||
249 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); | 250 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); |
251 | (void) vmw_3d_resource_inc(dev_priv); | ||
250 | vmw_resource_activate(res, vmw_hw_context_destroy); | 252 | vmw_resource_activate(res, vmw_hw_context_destroy); |
251 | return 0; | 253 | return 0; |
252 | } | 254 | } |
@@ -406,6 +408,7 @@ static void vmw_hw_surface_destroy(struct vmw_resource *res) | |||
406 | cmd->body.sid = cpu_to_le32(res->id); | 408 | cmd->body.sid = cpu_to_le32(res->id); |
407 | 409 | ||
408 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); | 410 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); |
411 | vmw_3d_resource_dec(dev_priv); | ||
409 | } | 412 | } |
410 | 413 | ||
411 | void vmw_surface_res_free(struct vmw_resource *res) | 414 | void vmw_surface_res_free(struct vmw_resource *res) |
@@ -473,6 +476,7 @@ int vmw_surface_init(struct vmw_private *dev_priv, | |||
473 | } | 476 | } |
474 | 477 | ||
475 | vmw_fifo_commit(dev_priv, submit_size); | 478 | vmw_fifo_commit(dev_priv, submit_size); |
479 | (void) vmw_3d_resource_inc(dev_priv); | ||
476 | vmw_resource_activate(res, vmw_hw_surface_destroy); | 480 | vmw_resource_activate(res, vmw_hw_surface_destroy); |
477 | return 0; | 481 | return 0; |
478 | } | 482 | } |
diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c index b87569e96b1..f366f968155 100644 --- a/drivers/gpu/vga/vgaarb.c +++ b/drivers/gpu/vga/vgaarb.c | |||
@@ -598,7 +598,7 @@ static inline void vga_update_device_decodes(struct vga_device *vgadev, | |||
598 | pr_debug("vgaarb: decoding count now is: %d\n", vga_decode_count); | 598 | pr_debug("vgaarb: decoding count now is: %d\n", vga_decode_count); |
599 | } | 599 | } |
600 | 600 | ||
601 | void __vga_set_legacy_decoding(struct pci_dev *pdev, unsigned int decodes, bool userspace) | 601 | static void __vga_set_legacy_decoding(struct pci_dev *pdev, unsigned int decodes, bool userspace) |
602 | { | 602 | { |
603 | struct vga_device *vgadev; | 603 | struct vga_device *vgadev; |
604 | unsigned long flags; | 604 | unsigned long flags; |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 0c52899be96..3f729248602 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -1285,8 +1285,11 @@ static const struct hid_device_id hid_blacklist[] = { | |||
1285 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, | 1285 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, |
1286 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, | 1286 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, |
1287 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, | 1287 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, |
1288 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_T91MT) }, | ||
1289 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) }, | ||
1288 | { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, | 1290 | { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, |
1289 | { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) }, | 1291 | { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) }, |
1292 | { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE_2) }, | ||
1290 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH) }, | 1293 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH) }, |
1291 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) }, | 1294 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) }, |
1292 | { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, | 1295 | { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, |
@@ -1578,7 +1581,6 @@ static const struct hid_device_id hid_ignore_list[] = { | |||
1578 | { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24) }, | 1581 | { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24) }, |
1579 | { HID_USB_DEVICE(USB_VENDOR_ID_AIRCABLE, USB_DEVICE_ID_AIRCABLE1) }, | 1582 | { HID_USB_DEVICE(USB_VENDOR_ID_AIRCABLE, USB_DEVICE_ID_AIRCABLE1) }, |
1580 | { HID_USB_DEVICE(USB_VENDOR_ID_ALCOR, USB_DEVICE_ID_ALCOR_USBRS232) }, | 1583 | { HID_USB_DEVICE(USB_VENDOR_ID_ALCOR, USB_DEVICE_ID_ALCOR_USBRS232) }, |
1581 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_T91MT)}, | ||
1582 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_LCM)}, | 1584 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_LCM)}, |
1583 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_LCM2)}, | 1585 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_LCM2)}, |
1584 | { HID_USB_DEVICE(USB_VENDOR_ID_AVERMEDIA, USB_DEVICE_ID_AVER_FM_MR800) }, | 1586 | { HID_USB_DEVICE(USB_VENDOR_ID_AVERMEDIA, USB_DEVICE_ID_AVER_FM_MR800) }, |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 85c6d13c9ff..765a4f53eb5 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
@@ -105,6 +105,7 @@ | |||
105 | 105 | ||
106 | #define USB_VENDOR_ID_ASUS 0x0486 | 106 | #define USB_VENDOR_ID_ASUS 0x0486 |
107 | #define USB_DEVICE_ID_ASUS_T91MT 0x0185 | 107 | #define USB_DEVICE_ID_ASUS_T91MT 0x0185 |
108 | #define USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO 0x0186 | ||
108 | 109 | ||
109 | #define USB_VENDOR_ID_ASUSTEK 0x0b05 | 110 | #define USB_VENDOR_ID_ASUSTEK 0x0b05 |
110 | #define USB_DEVICE_ID_ASUSTEK_LCM 0x1726 | 111 | #define USB_DEVICE_ID_ASUSTEK_LCM 0x1726 |
@@ -128,6 +129,7 @@ | |||
128 | 129 | ||
129 | #define USB_VENDOR_ID_BTC 0x046e | 130 | #define USB_VENDOR_ID_BTC 0x046e |
130 | #define USB_DEVICE_ID_BTC_EMPREX_REMOTE 0x5578 | 131 | #define USB_DEVICE_ID_BTC_EMPREX_REMOTE 0x5578 |
132 | #define USB_DEVICE_ID_BTC_EMPREX_REMOTE_2 0x5577 | ||
131 | 133 | ||
132 | #define USB_VENDOR_ID_CANDO 0x2087 | 134 | #define USB_VENDOR_ID_CANDO 0x2087 |
133 | #define USB_DEVICE_ID_CANDO_MULTI_TOUCH 0x0a01 | 135 | #define USB_DEVICE_ID_CANDO_MULTI_TOUCH 0x0a01 |
@@ -149,6 +151,7 @@ | |||
149 | 151 | ||
150 | #define USB_VENDOR_ID_CHICONY 0x04f2 | 152 | #define USB_VENDOR_ID_CHICONY 0x04f2 |
151 | #define USB_DEVICE_ID_CHICONY_TACTICAL_PAD 0x0418 | 153 | #define USB_DEVICE_ID_CHICONY_TACTICAL_PAD 0x0418 |
154 | #define USB_DEVICE_ID_CHICONY_MULTI_TOUCH 0xb19d | ||
152 | 155 | ||
153 | #define USB_VENDOR_ID_CIDC 0x1677 | 156 | #define USB_VENDOR_ID_CIDC 0x1677 |
154 | 157 | ||
@@ -507,6 +510,7 @@ | |||
507 | #define USB_VENDOR_ID_UCLOGIC 0x5543 | 510 | #define USB_VENDOR_ID_UCLOGIC 0x5543 |
508 | #define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209 0x0042 | 511 | #define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209 0x0042 |
509 | #define USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U 0x0003 | 512 | #define USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U 0x0003 |
513 | #define USB_DEVICE_ID_UCLOGIC_TABLET_KNA5 0x6001 | ||
510 | 514 | ||
511 | #define USB_VENDOR_ID_VERNIER 0x08f7 | 515 | #define USB_VENDOR_ID_VERNIER 0x08f7 |
512 | #define USB_DEVICE_ID_VERNIER_LABPRO 0x0001 | 516 | #define USB_DEVICE_ID_VERNIER_LABPRO 0x0001 |
diff --git a/drivers/hid/hid-mosart.c b/drivers/hid/hid-mosart.c index e91437c1890..ac5421d568f 100644 --- a/drivers/hid/hid-mosart.c +++ b/drivers/hid/hid-mosart.c | |||
@@ -239,6 +239,7 @@ static void mosart_remove(struct hid_device *hdev) | |||
239 | 239 | ||
240 | static const struct hid_device_id mosart_devices[] = { | 240 | static const struct hid_device_id mosart_devices[] = { |
241 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_T91MT) }, | 241 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_T91MT) }, |
242 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) }, | ||
242 | { } | 243 | { } |
243 | }; | 244 | }; |
244 | MODULE_DEVICE_TABLE(hid, mosart_devices); | 245 | MODULE_DEVICE_TABLE(hid, mosart_devices); |
diff --git a/drivers/hid/hid-topseed.c b/drivers/hid/hid-topseed.c index 5771f851f85..956ed9ac19d 100644 --- a/drivers/hid/hid-topseed.c +++ b/drivers/hid/hid-topseed.c | |||
@@ -64,6 +64,7 @@ static int ts_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
64 | static const struct hid_device_id ts_devices[] = { | 64 | static const struct hid_device_id ts_devices[] = { |
65 | { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) }, | 65 | { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) }, |
66 | { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) }, | 66 | { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) }, |
67 | { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE_2) }, | ||
67 | { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) }, | 68 | { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) }, |
68 | { } | 69 | { } |
69 | }; | 70 | }; |
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index b729c028667..599041a7f67 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c | |||
@@ -828,6 +828,7 @@ static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t co | |||
828 | } | 828 | } |
829 | } else { | 829 | } else { |
830 | int skipped_report_id = 0; | 830 | int skipped_report_id = 0; |
831 | int report_id = buf[0]; | ||
831 | if (buf[0] == 0x0) { | 832 | if (buf[0] == 0x0) { |
832 | /* Don't send the Report ID */ | 833 | /* Don't send the Report ID */ |
833 | buf++; | 834 | buf++; |
@@ -837,7 +838,7 @@ static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t co | |||
837 | ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | 838 | ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
838 | HID_REQ_SET_REPORT, | 839 | HID_REQ_SET_REPORT, |
839 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | 840 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, |
840 | ((report_type + 1) << 8) | *buf, | 841 | ((report_type + 1) << 8) | report_id, |
841 | interface->desc.bInterfaceNumber, buf, count, | 842 | interface->desc.bInterfaceNumber, buf, count, |
842 | USB_CTRL_SET_TIMEOUT); | 843 | USB_CTRL_SET_TIMEOUT); |
843 | /* count also the report id, if this was a numbered report. */ | 844 | /* count also the report id, if this was a numbered report. */ |
@@ -1445,6 +1446,11 @@ static const struct hid_device_id hid_usb_table[] = { | |||
1445 | { } | 1446 | { } |
1446 | }; | 1447 | }; |
1447 | 1448 | ||
1449 | struct usb_interface *usbhid_find_interface(int minor) | ||
1450 | { | ||
1451 | return usb_find_interface(&hid_driver, minor); | ||
1452 | } | ||
1453 | |||
1448 | static struct hid_driver hid_usb_driver = { | 1454 | static struct hid_driver hid_usb_driver = { |
1449 | .name = "generic-usb", | 1455 | .name = "generic-usb", |
1450 | .id_table = hid_usb_table, | 1456 | .id_table = hid_usb_table, |
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 2643d314762..70da3181c8a 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
@@ -33,6 +33,7 @@ static const struct hid_blacklist { | |||
33 | { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR, HID_QUIRK_BADPAD }, | 33 | { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR, HID_QUIRK_BADPAD }, |
34 | { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD }, | 34 | { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD }, |
35 | { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD }, | 35 | { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD }, |
36 | { USB_VENDOR_ID_DWAV, USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER, HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET }, | ||
36 | { USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH, HID_QUIRK_MULTI_INPUT }, | 37 | { USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH, HID_QUIRK_MULTI_INPUT }, |
37 | { USB_VENDOR_ID_MOJO, USB_DEVICE_ID_RETRO_ADAPTER, HID_QUIRK_MULTI_INPUT }, | 38 | { USB_VENDOR_ID_MOJO, USB_DEVICE_ID_RETRO_ADAPTER, HID_QUIRK_MULTI_INPUT }, |
38 | { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, | 39 | { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, |
@@ -69,6 +70,7 @@ static const struct hid_blacklist { | |||
69 | { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET }, | 70 | { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET }, |
70 | { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209, HID_QUIRK_MULTI_INPUT }, | 71 | { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209, HID_QUIRK_MULTI_INPUT }, |
71 | { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U, HID_QUIRK_MULTI_INPUT }, | 72 | { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U, HID_QUIRK_MULTI_INPUT }, |
73 | { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_KNA5, HID_QUIRK_MULTI_INPUT }, | ||
72 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, | 74 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, |
73 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, | 75 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, |
74 | 76 | ||
@@ -77,6 +79,8 @@ static const struct hid_blacklist { | |||
77 | 79 | ||
78 | { USB_VENDOR_ID_PI_ENGINEERING, USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL, HID_QUIRK_HIDINPUT_FORCE }, | 80 | { USB_VENDOR_ID_PI_ENGINEERING, USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL, HID_QUIRK_HIDINPUT_FORCE }, |
79 | 81 | ||
82 | { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_MULTI_TOUCH, HID_QUIRK_MULTI_INPUT }, | ||
83 | |||
80 | { 0, 0 } | 84 | { 0, 0 } |
81 | }; | 85 | }; |
82 | 86 | ||
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index 0a29c51114a..681e620eb95 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c | |||
@@ -270,7 +270,7 @@ static int hiddev_open(struct inode *inode, struct file *file) | |||
270 | struct hiddev *hiddev; | 270 | struct hiddev *hiddev; |
271 | int res; | 271 | int res; |
272 | 272 | ||
273 | intf = usb_find_interface(&hiddev_driver, iminor(inode)); | 273 | intf = usbhid_find_interface(iminor(inode)); |
274 | if (!intf) | 274 | if (!intf) |
275 | return -ENODEV; | 275 | return -ENODEV; |
276 | hid = usb_get_intfdata(intf); | 276 | hid = usb_get_intfdata(intf); |
diff --git a/drivers/hid/usbhid/usbhid.h b/drivers/hid/usbhid/usbhid.h index 693fd3e720d..89d2e847dcc 100644 --- a/drivers/hid/usbhid/usbhid.h +++ b/drivers/hid/usbhid/usbhid.h | |||
@@ -42,6 +42,7 @@ void usbhid_submit_report | |||
42 | (struct hid_device *hid, struct hid_report *report, unsigned char dir); | 42 | (struct hid_device *hid, struct hid_report *report, unsigned char dir); |
43 | int usbhid_get_power(struct hid_device *hid); | 43 | int usbhid_get_power(struct hid_device *hid); |
44 | void usbhid_put_power(struct hid_device *hid); | 44 | void usbhid_put_power(struct hid_device *hid); |
45 | struct usb_interface *usbhid_find_interface(int minor); | ||
45 | 46 | ||
46 | /* iofl flags */ | 47 | /* iofl flags */ |
47 | #define HID_CTRL_RUNNING 1 | 48 | #define HID_CTRL_RUNNING 1 |
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 4d4d09bdec0..97499d00615 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -409,7 +409,7 @@ config SENSORS_CORETEMP | |||
409 | 409 | ||
410 | config SENSORS_PKGTEMP | 410 | config SENSORS_PKGTEMP |
411 | tristate "Intel processor package temperature sensor" | 411 | tristate "Intel processor package temperature sensor" |
412 | depends on X86 && PCI && EXPERIMENTAL | 412 | depends on X86 && EXPERIMENTAL |
413 | help | 413 | help |
414 | If you say yes here you get support for the package level temperature | 414 | If you say yes here you get support for the package level temperature |
415 | sensor inside your CPU. Check documentation/driver for details. | 415 | sensor inside your CPU. Check documentation/driver for details. |
diff --git a/drivers/hwmon/adm1031.c b/drivers/hwmon/adm1031.c index 15c1a9616af..0683e6be662 100644 --- a/drivers/hwmon/adm1031.c +++ b/drivers/hwmon/adm1031.c | |||
@@ -79,7 +79,7 @@ struct adm1031_data { | |||
79 | int chip_type; | 79 | int chip_type; |
80 | char valid; /* !=0 if following fields are valid */ | 80 | char valid; /* !=0 if following fields are valid */ |
81 | unsigned long last_updated; /* In jiffies */ | 81 | unsigned long last_updated; /* In jiffies */ |
82 | unsigned int update_rate; /* In milliseconds */ | 82 | unsigned int update_interval; /* In milliseconds */ |
83 | /* The chan_select_table contains the possible configurations for | 83 | /* The chan_select_table contains the possible configurations for |
84 | * auto fan control. | 84 | * auto fan control. |
85 | */ | 85 | */ |
@@ -743,23 +743,23 @@ static SENSOR_DEVICE_ATTR(temp3_crit_alarm, S_IRUGO, show_alarm, NULL, 12); | |||
743 | static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, 13); | 743 | static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, 13); |
744 | static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 14); | 744 | static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 14); |
745 | 745 | ||
746 | /* Update Rate */ | 746 | /* Update Interval */ |
747 | static const unsigned int update_rates[] = { | 747 | static const unsigned int update_intervals[] = { |
748 | 16000, 8000, 4000, 2000, 1000, 500, 250, 125, | 748 | 16000, 8000, 4000, 2000, 1000, 500, 250, 125, |
749 | }; | 749 | }; |
750 | 750 | ||
751 | static ssize_t show_update_rate(struct device *dev, | 751 | static ssize_t show_update_interval(struct device *dev, |
752 | struct device_attribute *attr, char *buf) | 752 | struct device_attribute *attr, char *buf) |
753 | { | 753 | { |
754 | struct i2c_client *client = to_i2c_client(dev); | 754 | struct i2c_client *client = to_i2c_client(dev); |
755 | struct adm1031_data *data = i2c_get_clientdata(client); | 755 | struct adm1031_data *data = i2c_get_clientdata(client); |
756 | 756 | ||
757 | return sprintf(buf, "%u\n", data->update_rate); | 757 | return sprintf(buf, "%u\n", data->update_interval); |
758 | } | 758 | } |
759 | 759 | ||
760 | static ssize_t set_update_rate(struct device *dev, | 760 | static ssize_t set_update_interval(struct device *dev, |
761 | struct device_attribute *attr, | 761 | struct device_attribute *attr, |
762 | const char *buf, size_t count) | 762 | const char *buf, size_t count) |
763 | { | 763 | { |
764 | struct i2c_client *client = to_i2c_client(dev); | 764 | struct i2c_client *client = to_i2c_client(dev); |
765 | struct adm1031_data *data = i2c_get_clientdata(client); | 765 | struct adm1031_data *data = i2c_get_clientdata(client); |
@@ -771,12 +771,15 @@ static ssize_t set_update_rate(struct device *dev, | |||
771 | if (err) | 771 | if (err) |
772 | return err; | 772 | return err; |
773 | 773 | ||
774 | /* find the nearest update rate from the table */ | 774 | /* |
775 | for (i = 0; i < ARRAY_SIZE(update_rates) - 1; i++) { | 775 | * Find the nearest update interval from the table. |
776 | if (val >= update_rates[i]) | 776 | * Use it to determine the matching update rate. |
777 | */ | ||
778 | for (i = 0; i < ARRAY_SIZE(update_intervals) - 1; i++) { | ||
779 | if (val >= update_intervals[i]) | ||
777 | break; | 780 | break; |
778 | } | 781 | } |
779 | /* if not found, we point to the last entry (lowest update rate) */ | 782 | /* if not found, we point to the last entry (lowest update interval) */ |
780 | 783 | ||
781 | /* set the new update rate while preserving other settings */ | 784 | /* set the new update rate while preserving other settings */ |
782 | reg = adm1031_read_value(client, ADM1031_REG_FAN_FILTER); | 785 | reg = adm1031_read_value(client, ADM1031_REG_FAN_FILTER); |
@@ -785,14 +788,14 @@ static ssize_t set_update_rate(struct device *dev, | |||
785 | adm1031_write_value(client, ADM1031_REG_FAN_FILTER, reg); | 788 | adm1031_write_value(client, ADM1031_REG_FAN_FILTER, reg); |
786 | 789 | ||
787 | mutex_lock(&data->update_lock); | 790 | mutex_lock(&data->update_lock); |
788 | data->update_rate = update_rates[i]; | 791 | data->update_interval = update_intervals[i]; |
789 | mutex_unlock(&data->update_lock); | 792 | mutex_unlock(&data->update_lock); |
790 | 793 | ||
791 | return count; | 794 | return count; |
792 | } | 795 | } |
793 | 796 | ||
794 | static DEVICE_ATTR(update_rate, S_IRUGO | S_IWUSR, show_update_rate, | 797 | static DEVICE_ATTR(update_interval, S_IRUGO | S_IWUSR, show_update_interval, |
795 | set_update_rate); | 798 | set_update_interval); |
796 | 799 | ||
797 | static struct attribute *adm1031_attributes[] = { | 800 | static struct attribute *adm1031_attributes[] = { |
798 | &sensor_dev_attr_fan1_input.dev_attr.attr, | 801 | &sensor_dev_attr_fan1_input.dev_attr.attr, |
@@ -830,7 +833,7 @@ static struct attribute *adm1031_attributes[] = { | |||
830 | 833 | ||
831 | &sensor_dev_attr_auto_fan1_min_pwm.dev_attr.attr, | 834 | &sensor_dev_attr_auto_fan1_min_pwm.dev_attr.attr, |
832 | 835 | ||
833 | &dev_attr_update_rate.attr, | 836 | &dev_attr_update_interval.attr, |
834 | &dev_attr_alarms.attr, | 837 | &dev_attr_alarms.attr, |
835 | 838 | ||
836 | NULL | 839 | NULL |
@@ -981,7 +984,8 @@ static void adm1031_init_client(struct i2c_client *client) | |||
981 | mask = ADM1031_UPDATE_RATE_MASK; | 984 | mask = ADM1031_UPDATE_RATE_MASK; |
982 | read_val = adm1031_read_value(client, ADM1031_REG_FAN_FILTER); | 985 | read_val = adm1031_read_value(client, ADM1031_REG_FAN_FILTER); |
983 | i = (read_val & mask) >> ADM1031_UPDATE_RATE_SHIFT; | 986 | i = (read_val & mask) >> ADM1031_UPDATE_RATE_SHIFT; |
984 | data->update_rate = update_rates[i]; | 987 | /* Save it as update interval */ |
988 | data->update_interval = update_intervals[i]; | ||
985 | } | 989 | } |
986 | 990 | ||
987 | static struct adm1031_data *adm1031_update_device(struct device *dev) | 991 | static struct adm1031_data *adm1031_update_device(struct device *dev) |
@@ -993,7 +997,8 @@ static struct adm1031_data *adm1031_update_device(struct device *dev) | |||
993 | 997 | ||
994 | mutex_lock(&data->update_lock); | 998 | mutex_lock(&data->update_lock); |
995 | 999 | ||
996 | next_update = data->last_updated + msecs_to_jiffies(data->update_rate); | 1000 | next_update = data->last_updated |
1001 | + msecs_to_jiffies(data->update_interval); | ||
997 | if (time_after(jiffies, next_update) || !data->valid) { | 1002 | if (time_after(jiffies, next_update) || !data->valid) { |
998 | 1003 | ||
999 | dev_dbg(&client->dev, "Starting adm1031 update\n"); | 1004 | dev_dbg(&client->dev, "Starting adm1031 update\n"); |
diff --git a/drivers/hwmon/ads7871.c b/drivers/hwmon/ads7871.c index b300a2048af..52319340e18 100644 --- a/drivers/hwmon/ads7871.c +++ b/drivers/hwmon/ads7871.c | |||
@@ -160,30 +160,12 @@ static const struct attribute_group ads7871_group = { | |||
160 | 160 | ||
161 | static int __devinit ads7871_probe(struct spi_device *spi) | 161 | static int __devinit ads7871_probe(struct spi_device *spi) |
162 | { | 162 | { |
163 | int status, ret, err = 0; | 163 | int ret, err; |
164 | uint8_t val; | 164 | uint8_t val; |
165 | struct ads7871_data *pdata; | 165 | struct ads7871_data *pdata; |
166 | 166 | ||
167 | dev_dbg(&spi->dev, "probe\n"); | 167 | dev_dbg(&spi->dev, "probe\n"); |
168 | 168 | ||
169 | pdata = kzalloc(sizeof(struct ads7871_data), GFP_KERNEL); | ||
170 | if (!pdata) { | ||
171 | err = -ENOMEM; | ||
172 | goto exit; | ||
173 | } | ||
174 | |||
175 | status = sysfs_create_group(&spi->dev.kobj, &ads7871_group); | ||
176 | if (status < 0) | ||
177 | goto error_free; | ||
178 | |||
179 | pdata->hwmon_dev = hwmon_device_register(&spi->dev); | ||
180 | if (IS_ERR(pdata->hwmon_dev)) { | ||
181 | err = PTR_ERR(pdata->hwmon_dev); | ||
182 | goto error_remove; | ||
183 | } | ||
184 | |||
185 | spi_set_drvdata(spi, pdata); | ||
186 | |||
187 | /* Configure the SPI bus */ | 169 | /* Configure the SPI bus */ |
188 | spi->mode = (SPI_MODE_0); | 170 | spi->mode = (SPI_MODE_0); |
189 | spi->bits_per_word = 8; | 171 | spi->bits_per_word = 8; |
@@ -201,6 +183,24 @@ static int __devinit ads7871_probe(struct spi_device *spi) | |||
201 | we need to make sure we really have a chip*/ | 183 | we need to make sure we really have a chip*/ |
202 | if (val != ret) { | 184 | if (val != ret) { |
203 | err = -ENODEV; | 185 | err = -ENODEV; |
186 | goto exit; | ||
187 | } | ||
188 | |||
189 | pdata = kzalloc(sizeof(struct ads7871_data), GFP_KERNEL); | ||
190 | if (!pdata) { | ||
191 | err = -ENOMEM; | ||
192 | goto exit; | ||
193 | } | ||
194 | |||
195 | err = sysfs_create_group(&spi->dev.kobj, &ads7871_group); | ||
196 | if (err < 0) | ||
197 | goto error_free; | ||
198 | |||
199 | spi_set_drvdata(spi, pdata); | ||
200 | |||
201 | pdata->hwmon_dev = hwmon_device_register(&spi->dev); | ||
202 | if (IS_ERR(pdata->hwmon_dev)) { | ||
203 | err = PTR_ERR(pdata->hwmon_dev); | ||
204 | goto error_remove; | 204 | goto error_remove; |
205 | } | 205 | } |
206 | 206 | ||
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index c070c9714cb..a23b17a78ac 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/pci.h> | 36 | #include <linux/pci.h> |
37 | #include <asm/msr.h> | 37 | #include <asm/msr.h> |
38 | #include <asm/processor.h> | 38 | #include <asm/processor.h> |
39 | #include <asm/smp.h> | ||
39 | 40 | ||
40 | #define DRVNAME "coretemp" | 41 | #define DRVNAME "coretemp" |
41 | 42 | ||
@@ -423,9 +424,18 @@ static int __cpuinit coretemp_device_add(unsigned int cpu) | |||
423 | int err; | 424 | int err; |
424 | struct platform_device *pdev; | 425 | struct platform_device *pdev; |
425 | struct pdev_entry *pdev_entry; | 426 | struct pdev_entry *pdev_entry; |
426 | #ifdef CONFIG_SMP | ||
427 | struct cpuinfo_x86 *c = &cpu_data(cpu); | 427 | struct cpuinfo_x86 *c = &cpu_data(cpu); |
428 | #endif | 428 | |
429 | /* | ||
430 | * CPUID.06H.EAX[0] indicates whether the CPU has thermal | ||
431 | * sensors. We check this bit only, all the early CPUs | ||
432 | * without thermal sensors will be filtered out. | ||
433 | */ | ||
434 | if (!cpu_has(c, X86_FEATURE_DTS)) { | ||
435 | printk(KERN_INFO DRVNAME ": CPU (model=0x%x)" | ||
436 | " has no thermal sensor.\n", c->x86_model); | ||
437 | return 0; | ||
438 | } | ||
429 | 439 | ||
430 | mutex_lock(&pdev_list_mutex); | 440 | mutex_lock(&pdev_list_mutex); |
431 | 441 | ||
@@ -482,14 +492,22 @@ exit: | |||
482 | 492 | ||
483 | static void coretemp_device_remove(unsigned int cpu) | 493 | static void coretemp_device_remove(unsigned int cpu) |
484 | { | 494 | { |
485 | struct pdev_entry *p, *n; | 495 | struct pdev_entry *p; |
496 | unsigned int i; | ||
497 | |||
486 | mutex_lock(&pdev_list_mutex); | 498 | mutex_lock(&pdev_list_mutex); |
487 | list_for_each_entry_safe(p, n, &pdev_list, list) { | 499 | list_for_each_entry(p, &pdev_list, list) { |
488 | if (p->cpu == cpu) { | 500 | if (p->cpu != cpu) |
489 | platform_device_unregister(p->pdev); | 501 | continue; |
490 | list_del(&p->list); | 502 | |
491 | kfree(p); | 503 | platform_device_unregister(p->pdev); |
492 | } | 504 | list_del(&p->list); |
505 | mutex_unlock(&pdev_list_mutex); | ||
506 | kfree(p); | ||
507 | for_each_cpu(i, cpu_sibling_mask(cpu)) | ||
508 | if (i != cpu && !coretemp_device_add(i)) | ||
509 | break; | ||
510 | return; | ||
493 | } | 511 | } |
494 | mutex_unlock(&pdev_list_mutex); | 512 | mutex_unlock(&pdev_list_mutex); |
495 | } | 513 | } |
@@ -518,7 +536,6 @@ static struct notifier_block coretemp_cpu_notifier __refdata = { | |||
518 | static int __init coretemp_init(void) | 536 | static int __init coretemp_init(void) |
519 | { | 537 | { |
520 | int i, err = -ENODEV; | 538 | int i, err = -ENODEV; |
521 | struct pdev_entry *p, *n; | ||
522 | 539 | ||
523 | /* quick check if we run Intel */ | 540 | /* quick check if we run Intel */ |
524 | if (cpu_data(0).x86_vendor != X86_VENDOR_INTEL) | 541 | if (cpu_data(0).x86_vendor != X86_VENDOR_INTEL) |
@@ -528,30 +545,21 @@ static int __init coretemp_init(void) | |||
528 | if (err) | 545 | if (err) |
529 | goto exit; | 546 | goto exit; |
530 | 547 | ||
531 | for_each_online_cpu(i) { | 548 | for_each_online_cpu(i) |
532 | struct cpuinfo_x86 *c = &cpu_data(i); | 549 | coretemp_device_add(i); |
533 | /* | 550 | |
534 | * CPUID.06H.EAX[0] indicates whether the CPU has thermal | 551 | #ifndef CONFIG_HOTPLUG_CPU |
535 | * sensors. We check this bit only, all the early CPUs | ||
536 | * without thermal sensors will be filtered out. | ||
537 | */ | ||
538 | if (c->cpuid_level >= 6 && (cpuid_eax(0x06) & 0x01)) | ||
539 | coretemp_device_add(i); | ||
540 | else { | ||
541 | printk(KERN_INFO DRVNAME ": CPU (model=0x%x)" | ||
542 | " has no thermal sensor.\n", c->x86_model); | ||
543 | } | ||
544 | } | ||
545 | if (list_empty(&pdev_list)) { | 552 | if (list_empty(&pdev_list)) { |
546 | err = -ENODEV; | 553 | err = -ENODEV; |
547 | goto exit_driver_unreg; | 554 | goto exit_driver_unreg; |
548 | } | 555 | } |
556 | #endif | ||
549 | 557 | ||
550 | register_hotcpu_notifier(&coretemp_cpu_notifier); | 558 | register_hotcpu_notifier(&coretemp_cpu_notifier); |
551 | return 0; | 559 | return 0; |
552 | 560 | ||
553 | exit_driver_unreg: | ||
554 | #ifndef CONFIG_HOTPLUG_CPU | 561 | #ifndef CONFIG_HOTPLUG_CPU |
562 | exit_driver_unreg: | ||
555 | platform_driver_unregister(&coretemp_driver); | 563 | platform_driver_unregister(&coretemp_driver); |
556 | #endif | 564 | #endif |
557 | exit: | 565 | exit: |
diff --git a/drivers/hwmon/emc1403.c b/drivers/hwmon/emc1403.c index 5b58b20dead..8dee3f38fdf 100644 --- a/drivers/hwmon/emc1403.c +++ b/drivers/hwmon/emc1403.c | |||
@@ -308,7 +308,6 @@ static int emc1403_probe(struct i2c_client *client, | |||
308 | res = sysfs_create_group(&client->dev.kobj, &m_thermal_gr); | 308 | res = sysfs_create_group(&client->dev.kobj, &m_thermal_gr); |
309 | if (res) { | 309 | if (res) { |
310 | dev_warn(&client->dev, "create group failed\n"); | 310 | dev_warn(&client->dev, "create group failed\n"); |
311 | hwmon_device_unregister(data->hwmon_dev); | ||
312 | goto thermal_error1; | 311 | goto thermal_error1; |
313 | } | 312 | } |
314 | data->hwmon_dev = hwmon_device_register(&client->dev); | 313 | data->hwmon_dev = hwmon_device_register(&client->dev); |
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c index 537841ef44b..75afb3b0e07 100644 --- a/drivers/hwmon/f71882fg.c +++ b/drivers/hwmon/f71882fg.c | |||
@@ -111,7 +111,7 @@ static struct platform_device *f71882fg_pdev; | |||
111 | /* Super-I/O Function prototypes */ | 111 | /* Super-I/O Function prototypes */ |
112 | static inline int superio_inb(int base, int reg); | 112 | static inline int superio_inb(int base, int reg); |
113 | static inline int superio_inw(int base, int reg); | 113 | static inline int superio_inw(int base, int reg); |
114 | static inline void superio_enter(int base); | 114 | static inline int superio_enter(int base); |
115 | static inline void superio_select(int base, int ld); | 115 | static inline void superio_select(int base, int ld); |
116 | static inline void superio_exit(int base); | 116 | static inline void superio_exit(int base); |
117 | 117 | ||
@@ -861,11 +861,20 @@ static int superio_inw(int base, int reg) | |||
861 | return val; | 861 | return val; |
862 | } | 862 | } |
863 | 863 | ||
864 | static inline void superio_enter(int base) | 864 | static inline int superio_enter(int base) |
865 | { | 865 | { |
866 | /* Don't step on other drivers' I/O space by accident */ | ||
867 | if (!request_muxed_region(base, 2, DRVNAME)) { | ||
868 | printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n", | ||
869 | base); | ||
870 | return -EBUSY; | ||
871 | } | ||
872 | |||
866 | /* according to the datasheet the key must be send twice! */ | 873 | /* according to the datasheet the key must be send twice! */ |
867 | outb(SIO_UNLOCK_KEY, base); | 874 | outb(SIO_UNLOCK_KEY, base); |
868 | outb(SIO_UNLOCK_KEY, base); | 875 | outb(SIO_UNLOCK_KEY, base); |
876 | |||
877 | return 0; | ||
869 | } | 878 | } |
870 | 879 | ||
871 | static inline void superio_select(int base, int ld) | 880 | static inline void superio_select(int base, int ld) |
@@ -877,6 +886,7 @@ static inline void superio_select(int base, int ld) | |||
877 | static inline void superio_exit(int base) | 886 | static inline void superio_exit(int base) |
878 | { | 887 | { |
879 | outb(SIO_LOCK_KEY, base); | 888 | outb(SIO_LOCK_KEY, base); |
889 | release_region(base, 2); | ||
880 | } | 890 | } |
881 | 891 | ||
882 | static inline int fan_from_reg(u16 reg) | 892 | static inline int fan_from_reg(u16 reg) |
@@ -2175,21 +2185,15 @@ static int f71882fg_remove(struct platform_device *pdev) | |||
2175 | static int __init f71882fg_find(int sioaddr, unsigned short *address, | 2185 | static int __init f71882fg_find(int sioaddr, unsigned short *address, |
2176 | struct f71882fg_sio_data *sio_data) | 2186 | struct f71882fg_sio_data *sio_data) |
2177 | { | 2187 | { |
2178 | int err = -ENODEV; | ||
2179 | u16 devid; | 2188 | u16 devid; |
2180 | 2189 | int err = superio_enter(sioaddr); | |
2181 | /* Don't step on other drivers' I/O space by accident */ | 2190 | if (err) |
2182 | if (!request_region(sioaddr, 2, DRVNAME)) { | 2191 | return err; |
2183 | printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n", | ||
2184 | (int)sioaddr); | ||
2185 | return -EBUSY; | ||
2186 | } | ||
2187 | |||
2188 | superio_enter(sioaddr); | ||
2189 | 2192 | ||
2190 | devid = superio_inw(sioaddr, SIO_REG_MANID); | 2193 | devid = superio_inw(sioaddr, SIO_REG_MANID); |
2191 | if (devid != SIO_FINTEK_ID) { | 2194 | if (devid != SIO_FINTEK_ID) { |
2192 | pr_debug(DRVNAME ": Not a Fintek device\n"); | 2195 | pr_debug(DRVNAME ": Not a Fintek device\n"); |
2196 | err = -ENODEV; | ||
2193 | goto exit; | 2197 | goto exit; |
2194 | } | 2198 | } |
2195 | 2199 | ||
@@ -2213,6 +2217,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, | |||
2213 | default: | 2217 | default: |
2214 | printk(KERN_INFO DRVNAME ": Unsupported Fintek device: %04x\n", | 2218 | printk(KERN_INFO DRVNAME ": Unsupported Fintek device: %04x\n", |
2215 | (unsigned int)devid); | 2219 | (unsigned int)devid); |
2220 | err = -ENODEV; | ||
2216 | goto exit; | 2221 | goto exit; |
2217 | } | 2222 | } |
2218 | 2223 | ||
@@ -2223,12 +2228,14 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, | |||
2223 | 2228 | ||
2224 | if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) { | 2229 | if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) { |
2225 | printk(KERN_WARNING DRVNAME ": Device not activated\n"); | 2230 | printk(KERN_WARNING DRVNAME ": Device not activated\n"); |
2231 | err = -ENODEV; | ||
2226 | goto exit; | 2232 | goto exit; |
2227 | } | 2233 | } |
2228 | 2234 | ||
2229 | *address = superio_inw(sioaddr, SIO_REG_ADDR); | 2235 | *address = superio_inw(sioaddr, SIO_REG_ADDR); |
2230 | if (*address == 0) { | 2236 | if (*address == 0) { |
2231 | printk(KERN_WARNING DRVNAME ": Base address not set\n"); | 2237 | printk(KERN_WARNING DRVNAME ": Base address not set\n"); |
2238 | err = -ENODEV; | ||
2232 | goto exit; | 2239 | goto exit; |
2233 | } | 2240 | } |
2234 | *address &= ~(REGION_LENGTH - 1); /* Ignore 3 LSB */ | 2241 | *address &= ~(REGION_LENGTH - 1); /* Ignore 3 LSB */ |
@@ -2239,7 +2246,6 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, | |||
2239 | (int)superio_inb(sioaddr, SIO_REG_DEVREV)); | 2246 | (int)superio_inb(sioaddr, SIO_REG_DEVREV)); |
2240 | exit: | 2247 | exit: |
2241 | superio_exit(sioaddr); | 2248 | superio_exit(sioaddr); |
2242 | release_region(sioaddr, 2); | ||
2243 | return err; | 2249 | return err; |
2244 | } | 2250 | } |
2245 | 2251 | ||
diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c index 0f58ecc5334..9638d58f99f 100644 --- a/drivers/hwmon/f75375s.c +++ b/drivers/hwmon/f75375s.c | |||
@@ -79,7 +79,7 @@ enum chips { f75373, f75375 }; | |||
79 | #define F75375_REG_PWM2_DROP_DUTY 0x6C | 79 | #define F75375_REG_PWM2_DROP_DUTY 0x6C |
80 | 80 | ||
81 | #define FAN_CTRL_LINEAR(nr) (4 + nr) | 81 | #define FAN_CTRL_LINEAR(nr) (4 + nr) |
82 | #define FAN_CTRL_MODE(nr) (5 + ((nr) * 2)) | 82 | #define FAN_CTRL_MODE(nr) (4 + ((nr) * 2)) |
83 | 83 | ||
84 | /* | 84 | /* |
85 | * Data structures and manipulation thereof | 85 | * Data structures and manipulation thereof |
@@ -298,7 +298,7 @@ static int set_pwm_enable_direct(struct i2c_client *client, int nr, int val) | |||
298 | return -EINVAL; | 298 | return -EINVAL; |
299 | 299 | ||
300 | fanmode = f75375_read8(client, F75375_REG_FAN_TIMER); | 300 | fanmode = f75375_read8(client, F75375_REG_FAN_TIMER); |
301 | fanmode = ~(3 << FAN_CTRL_MODE(nr)); | 301 | fanmode &= ~(3 << FAN_CTRL_MODE(nr)); |
302 | 302 | ||
303 | switch (val) { | 303 | switch (val) { |
304 | case 0: /* Full speed */ | 304 | case 0: /* Full speed */ |
@@ -350,7 +350,7 @@ static ssize_t set_pwm_mode(struct device *dev, struct device_attribute *attr, | |||
350 | 350 | ||
351 | mutex_lock(&data->update_lock); | 351 | mutex_lock(&data->update_lock); |
352 | conf = f75375_read8(client, F75375_REG_CONFIG1); | 352 | conf = f75375_read8(client, F75375_REG_CONFIG1); |
353 | conf = ~(1 << FAN_CTRL_LINEAR(nr)); | 353 | conf &= ~(1 << FAN_CTRL_LINEAR(nr)); |
354 | 354 | ||
355 | if (val == 0) | 355 | if (val == 0) |
356 | conf |= (1 << FAN_CTRL_LINEAR(nr)) ; | 356 | conf |= (1 << FAN_CTRL_LINEAR(nr)) ; |
diff --git a/drivers/hwmon/hp_accel.c b/drivers/hwmon/hp_accel.c index 7580f55e67e..36e95753223 100644 --- a/drivers/hwmon/hp_accel.c +++ b/drivers/hwmon/hp_accel.c | |||
@@ -221,6 +221,8 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = { | |||
221 | AXIS_DMI_MATCH("HPB442x", "HP ProBook 442", xy_rotated_left), | 221 | AXIS_DMI_MATCH("HPB442x", "HP ProBook 442", xy_rotated_left), |
222 | AXIS_DMI_MATCH("HPB452x", "HP ProBook 452", y_inverted), | 222 | AXIS_DMI_MATCH("HPB452x", "HP ProBook 452", y_inverted), |
223 | AXIS_DMI_MATCH("HPB522x", "HP ProBook 522", xy_swap), | 223 | AXIS_DMI_MATCH("HPB522x", "HP ProBook 522", xy_swap), |
224 | AXIS_DMI_MATCH("HPB532x", "HP ProBook 532", y_inverted), | ||
225 | AXIS_DMI_MATCH("Mini5102", "HP Mini 5102", xy_rotated_left_usd), | ||
224 | { NULL, } | 226 | { NULL, } |
225 | /* Laptop models without axis info (yet): | 227 | /* Laptop models without axis info (yet): |
226 | * "NC6910" "HP Compaq 6910" | 228 | * "NC6910" "HP Compaq 6910" |
diff --git a/drivers/hwmon/k8temp.c b/drivers/hwmon/k8temp.c index b9bb3e0ca53..39ead2a4d3c 100644 --- a/drivers/hwmon/k8temp.c +++ b/drivers/hwmon/k8temp.c | |||
@@ -143,6 +143,37 @@ static const struct pci_device_id k8temp_ids[] = { | |||
143 | 143 | ||
144 | MODULE_DEVICE_TABLE(pci, k8temp_ids); | 144 | MODULE_DEVICE_TABLE(pci, k8temp_ids); |
145 | 145 | ||
146 | static int __devinit is_rev_g_desktop(u8 model) | ||
147 | { | ||
148 | u32 brandidx; | ||
149 | |||
150 | if (model < 0x69) | ||
151 | return 0; | ||
152 | |||
153 | if (model == 0xc1 || model == 0x6c || model == 0x7c) | ||
154 | return 0; | ||
155 | |||
156 | /* | ||
157 | * Differentiate between AM2 and ASB1. | ||
158 | * See "Constructing the processor Name String" in "Revision | ||
159 | * Guide for AMD NPT Family 0Fh Processors" (33610). | ||
160 | */ | ||
161 | brandidx = cpuid_ebx(0x80000001); | ||
162 | brandidx = (brandidx >> 9) & 0x1f; | ||
163 | |||
164 | /* Single core */ | ||
165 | if ((model == 0x6f || model == 0x7f) && | ||
166 | (brandidx == 0x7 || brandidx == 0x9 || brandidx == 0xc)) | ||
167 | return 0; | ||
168 | |||
169 | /* Dual core */ | ||
170 | if (model == 0x6b && | ||
171 | (brandidx == 0xb || brandidx == 0xc)) | ||
172 | return 0; | ||
173 | |||
174 | return 1; | ||
175 | } | ||
176 | |||
146 | static int __devinit k8temp_probe(struct pci_dev *pdev, | 177 | static int __devinit k8temp_probe(struct pci_dev *pdev, |
147 | const struct pci_device_id *id) | 178 | const struct pci_device_id *id) |
148 | { | 179 | { |
@@ -179,9 +210,7 @@ static int __devinit k8temp_probe(struct pci_dev *pdev, | |||
179 | "wrong - check erratum #141\n"); | 210 | "wrong - check erratum #141\n"); |
180 | } | 211 | } |
181 | 212 | ||
182 | if ((model >= 0x69) && | 213 | if (is_rev_g_desktop(model)) { |
183 | !(model == 0xc1 || model == 0x6c || model == 0x7c || | ||
184 | model == 0x6b || model == 0x6f || model == 0x7f)) { | ||
185 | /* | 214 | /* |
186 | * RevG desktop CPUs (i.e. no socket S1G1 or | 215 | * RevG desktop CPUs (i.e. no socket S1G1 or |
187 | * ASB1 parts) need additional offset, | 216 | * ASB1 parts) need additional offset, |
diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c index 6138f036b15..fc591ae5310 100644 --- a/drivers/hwmon/lis3lv02d.c +++ b/drivers/hwmon/lis3lv02d.c | |||
@@ -277,7 +277,7 @@ static irqreturn_t lis302dl_interrupt(int irq, void *dummy) | |||
277 | wake_up_interruptible(&lis3_dev.misc_wait); | 277 | wake_up_interruptible(&lis3_dev.misc_wait); |
278 | kill_fasync(&lis3_dev.async_queue, SIGIO, POLL_IN); | 278 | kill_fasync(&lis3_dev.async_queue, SIGIO, POLL_IN); |
279 | out: | 279 | out: |
280 | if (lis3_dev.whoami == WAI_8B && lis3_dev.idev && | 280 | if (lis3_dev.pdata && lis3_dev.whoami == WAI_8B && lis3_dev.idev && |
281 | lis3_dev.idev->input->users) | 281 | lis3_dev.idev->input->users) |
282 | return IRQ_WAKE_THREAD; | 282 | return IRQ_WAKE_THREAD; |
283 | return IRQ_HANDLED; | 283 | return IRQ_HANDLED; |
@@ -718,7 +718,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev) | |||
718 | * io-apic is not configurable (and generates a warning) but I keep it | 718 | * io-apic is not configurable (and generates a warning) but I keep it |
719 | * in case of support for other hardware. | 719 | * in case of support for other hardware. |
720 | */ | 720 | */ |
721 | if (dev->whoami == WAI_8B) | 721 | if (dev->pdata && dev->whoami == WAI_8B) |
722 | thread_fn = lis302dl_interrupt_thread1_8b; | 722 | thread_fn = lis302dl_interrupt_thread1_8b; |
723 | else | 723 | else |
724 | thread_fn = NULL; | 724 | thread_fn = NULL; |
diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c index dc1f5402c1d..8e5933b72d1 100644 --- a/drivers/hwmon/lis3lv02d_i2c.c +++ b/drivers/hwmon/lis3lv02d_i2c.c | |||
@@ -121,7 +121,7 @@ static int lis3lv02d_i2c_suspend(struct i2c_client *client, pm_message_t mesg) | |||
121 | { | 121 | { |
122 | struct lis3lv02d *lis3 = i2c_get_clientdata(client); | 122 | struct lis3lv02d *lis3 = i2c_get_clientdata(client); |
123 | 123 | ||
124 | if (!lis3->pdata->wakeup_flags) | 124 | if (!lis3->pdata || !lis3->pdata->wakeup_flags) |
125 | lis3lv02d_poweroff(lis3); | 125 | lis3lv02d_poweroff(lis3); |
126 | return 0; | 126 | return 0; |
127 | } | 127 | } |
@@ -130,7 +130,7 @@ static int lis3lv02d_i2c_resume(struct i2c_client *client) | |||
130 | { | 130 | { |
131 | struct lis3lv02d *lis3 = i2c_get_clientdata(client); | 131 | struct lis3lv02d *lis3 = i2c_get_clientdata(client); |
132 | 132 | ||
133 | if (!lis3->pdata->wakeup_flags) | 133 | if (!lis3->pdata || !lis3->pdata->wakeup_flags) |
134 | lis3lv02d_poweron(lis3); | 134 | lis3lv02d_poweron(lis3); |
135 | return 0; | 135 | return 0; |
136 | } | 136 | } |
diff --git a/drivers/hwmon/lis3lv02d_spi.c b/drivers/hwmon/lis3lv02d_spi.c index 82b16808a27..b9be5e3a22b 100644 --- a/drivers/hwmon/lis3lv02d_spi.c +++ b/drivers/hwmon/lis3lv02d_spi.c | |||
@@ -92,7 +92,7 @@ static int lis3lv02d_spi_suspend(struct spi_device *spi, pm_message_t mesg) | |||
92 | { | 92 | { |
93 | struct lis3lv02d *lis3 = spi_get_drvdata(spi); | 93 | struct lis3lv02d *lis3 = spi_get_drvdata(spi); |
94 | 94 | ||
95 | if (!lis3->pdata->wakeup_flags) | 95 | if (!lis3->pdata || !lis3->pdata->wakeup_flags) |
96 | lis3lv02d_poweroff(&lis3_dev); | 96 | lis3lv02d_poweroff(&lis3_dev); |
97 | 97 | ||
98 | return 0; | 98 | return 0; |
@@ -102,7 +102,7 @@ static int lis3lv02d_spi_resume(struct spi_device *spi) | |||
102 | { | 102 | { |
103 | struct lis3lv02d *lis3 = spi_get_drvdata(spi); | 103 | struct lis3lv02d *lis3 = spi_get_drvdata(spi); |
104 | 104 | ||
105 | if (!lis3->pdata->wakeup_flags) | 105 | if (!lis3->pdata || !lis3->pdata->wakeup_flags) |
106 | lis3lv02d_poweron(lis3); | 106 | lis3lv02d_poweron(lis3); |
107 | 107 | ||
108 | return 0; | 108 | return 0; |
diff --git a/drivers/hwmon/lm95241.c b/drivers/hwmon/lm95241.c index 94741d42112..464340f2549 100644 --- a/drivers/hwmon/lm95241.c +++ b/drivers/hwmon/lm95241.c | |||
@@ -91,7 +91,7 @@ static struct lm95241_data *lm95241_update_device(struct device *dev); | |||
91 | struct lm95241_data { | 91 | struct lm95241_data { |
92 | struct device *hwmon_dev; | 92 | struct device *hwmon_dev; |
93 | struct mutex update_lock; | 93 | struct mutex update_lock; |
94 | unsigned long last_updated, rate; /* in jiffies */ | 94 | unsigned long last_updated, interval; /* in jiffies */ |
95 | char valid; /* zero until following fields are valid */ | 95 | char valid; /* zero until following fields are valid */ |
96 | /* registers values */ | 96 | /* registers values */ |
97 | u8 local_h, local_l; /* local */ | 97 | u8 local_h, local_l; /* local */ |
@@ -114,23 +114,23 @@ show_temp(local); | |||
114 | show_temp(remote1); | 114 | show_temp(remote1); |
115 | show_temp(remote2); | 115 | show_temp(remote2); |
116 | 116 | ||
117 | static ssize_t show_rate(struct device *dev, struct device_attribute *attr, | 117 | static ssize_t show_interval(struct device *dev, struct device_attribute *attr, |
118 | char *buf) | 118 | char *buf) |
119 | { | 119 | { |
120 | struct lm95241_data *data = lm95241_update_device(dev); | 120 | struct lm95241_data *data = lm95241_update_device(dev); |
121 | 121 | ||
122 | snprintf(buf, PAGE_SIZE - 1, "%lu\n", 1000 * data->rate / HZ); | 122 | snprintf(buf, PAGE_SIZE - 1, "%lu\n", 1000 * data->interval / HZ); |
123 | return strlen(buf); | 123 | return strlen(buf); |
124 | } | 124 | } |
125 | 125 | ||
126 | static ssize_t set_rate(struct device *dev, struct device_attribute *attr, | 126 | static ssize_t set_interval(struct device *dev, struct device_attribute *attr, |
127 | const char *buf, size_t count) | 127 | const char *buf, size_t count) |
128 | { | 128 | { |
129 | struct i2c_client *client = to_i2c_client(dev); | 129 | struct i2c_client *client = to_i2c_client(dev); |
130 | struct lm95241_data *data = i2c_get_clientdata(client); | 130 | struct lm95241_data *data = i2c_get_clientdata(client); |
131 | 131 | ||
132 | strict_strtol(buf, 10, &data->rate); | 132 | strict_strtol(buf, 10, &data->interval); |
133 | data->rate = data->rate * HZ / 1000; | 133 | data->interval = data->interval * HZ / 1000; |
134 | 134 | ||
135 | return count; | 135 | return count; |
136 | } | 136 | } |
@@ -286,7 +286,8 @@ static DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_min1, set_min1); | |||
286 | static DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, show_min2, set_min2); | 286 | static DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, show_min2, set_min2); |
287 | static DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_max1, set_max1); | 287 | static DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_max1, set_max1); |
288 | static DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_max2, set_max2); | 288 | static DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_max2, set_max2); |
289 | static DEVICE_ATTR(rate, S_IWUSR | S_IRUGO, show_rate, set_rate); | 289 | static DEVICE_ATTR(update_interval, S_IWUSR | S_IRUGO, show_interval, |
290 | set_interval); | ||
290 | 291 | ||
291 | static struct attribute *lm95241_attributes[] = { | 292 | static struct attribute *lm95241_attributes[] = { |
292 | &dev_attr_temp1_input.attr, | 293 | &dev_attr_temp1_input.attr, |
@@ -298,7 +299,7 @@ static struct attribute *lm95241_attributes[] = { | |||
298 | &dev_attr_temp3_min.attr, | 299 | &dev_attr_temp3_min.attr, |
299 | &dev_attr_temp2_max.attr, | 300 | &dev_attr_temp2_max.attr, |
300 | &dev_attr_temp3_max.attr, | 301 | &dev_attr_temp3_max.attr, |
301 | &dev_attr_rate.attr, | 302 | &dev_attr_update_interval.attr, |
302 | NULL | 303 | NULL |
303 | }; | 304 | }; |
304 | 305 | ||
@@ -376,7 +377,7 @@ static void lm95241_init_client(struct i2c_client *client) | |||
376 | { | 377 | { |
377 | struct lm95241_data *data = i2c_get_clientdata(client); | 378 | struct lm95241_data *data = i2c_get_clientdata(client); |
378 | 379 | ||
379 | data->rate = HZ; /* 1 sec default */ | 380 | data->interval = HZ; /* 1 sec default */ |
380 | data->valid = 0; | 381 | data->valid = 0; |
381 | data->config = CFG_CR0076; | 382 | data->config = CFG_CR0076; |
382 | data->model = 0; | 383 | data->model = 0; |
@@ -410,7 +411,7 @@ static struct lm95241_data *lm95241_update_device(struct device *dev) | |||
410 | 411 | ||
411 | mutex_lock(&data->update_lock); | 412 | mutex_lock(&data->update_lock); |
412 | 413 | ||
413 | if (time_after(jiffies, data->last_updated + data->rate) || | 414 | if (time_after(jiffies, data->last_updated + data->interval) || |
414 | !data->valid) { | 415 | !data->valid) { |
415 | dev_dbg(&client->dev, "Updating lm95241 data.\n"); | 416 | dev_dbg(&client->dev, "Updating lm95241 data.\n"); |
416 | data->local_h = | 417 | data->local_h = |
diff --git a/drivers/hwmon/pkgtemp.c b/drivers/hwmon/pkgtemp.c index 74157fcda6e..f11903936c8 100644 --- a/drivers/hwmon/pkgtemp.c +++ b/drivers/hwmon/pkgtemp.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include <linux/list.h> | 33 | #include <linux/list.h> |
34 | #include <linux/platform_device.h> | 34 | #include <linux/platform_device.h> |
35 | #include <linux/cpu.h> | 35 | #include <linux/cpu.h> |
36 | #include <linux/pci.h> | ||
37 | #include <asm/msr.h> | 36 | #include <asm/msr.h> |
38 | #include <asm/processor.h> | 37 | #include <asm/processor.h> |
39 | 38 | ||
@@ -224,7 +223,7 @@ static int __devinit pkgtemp_probe(struct platform_device *pdev) | |||
224 | 223 | ||
225 | err = sysfs_create_group(&pdev->dev.kobj, &pkgtemp_group); | 224 | err = sysfs_create_group(&pdev->dev.kobj, &pkgtemp_group); |
226 | if (err) | 225 | if (err) |
227 | goto exit_free; | 226 | goto exit_dev; |
228 | 227 | ||
229 | data->hwmon_dev = hwmon_device_register(&pdev->dev); | 228 | data->hwmon_dev = hwmon_device_register(&pdev->dev); |
230 | if (IS_ERR(data->hwmon_dev)) { | 229 | if (IS_ERR(data->hwmon_dev)) { |
@@ -238,6 +237,8 @@ static int __devinit pkgtemp_probe(struct platform_device *pdev) | |||
238 | 237 | ||
239 | exit_class: | 238 | exit_class: |
240 | sysfs_remove_group(&pdev->dev.kobj, &pkgtemp_group); | 239 | sysfs_remove_group(&pdev->dev.kobj, &pkgtemp_group); |
240 | exit_dev: | ||
241 | device_remove_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr); | ||
241 | exit_free: | 242 | exit_free: |
242 | kfree(data); | 243 | kfree(data); |
243 | exit: | 244 | exit: |
@@ -250,6 +251,7 @@ static int __devexit pkgtemp_remove(struct platform_device *pdev) | |||
250 | 251 | ||
251 | hwmon_device_unregister(data->hwmon_dev); | 252 | hwmon_device_unregister(data->hwmon_dev); |
252 | sysfs_remove_group(&pdev->dev.kobj, &pkgtemp_group); | 253 | sysfs_remove_group(&pdev->dev.kobj, &pkgtemp_group); |
254 | device_remove_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr); | ||
253 | platform_set_drvdata(pdev, NULL); | 255 | platform_set_drvdata(pdev, NULL); |
254 | kfree(data); | 256 | kfree(data); |
255 | return 0; | 257 | return 0; |
@@ -281,9 +283,10 @@ static int __cpuinit pkgtemp_device_add(unsigned int cpu) | |||
281 | int err; | 283 | int err; |
282 | struct platform_device *pdev; | 284 | struct platform_device *pdev; |
283 | struct pdev_entry *pdev_entry; | 285 | struct pdev_entry *pdev_entry; |
284 | #ifdef CONFIG_SMP | ||
285 | struct cpuinfo_x86 *c = &cpu_data(cpu); | 286 | struct cpuinfo_x86 *c = &cpu_data(cpu); |
286 | #endif | 287 | |
288 | if (!cpu_has(c, X86_FEATURE_PTS)) | ||
289 | return 0; | ||
287 | 290 | ||
288 | mutex_lock(&pdev_list_mutex); | 291 | mutex_lock(&pdev_list_mutex); |
289 | 292 | ||
@@ -339,17 +342,18 @@ exit: | |||
339 | #ifdef CONFIG_HOTPLUG_CPU | 342 | #ifdef CONFIG_HOTPLUG_CPU |
340 | static void pkgtemp_device_remove(unsigned int cpu) | 343 | static void pkgtemp_device_remove(unsigned int cpu) |
341 | { | 344 | { |
342 | struct pdev_entry *p, *n; | 345 | struct pdev_entry *p; |
343 | unsigned int i; | 346 | unsigned int i; |
344 | int err; | 347 | int err; |
345 | 348 | ||
346 | mutex_lock(&pdev_list_mutex); | 349 | mutex_lock(&pdev_list_mutex); |
347 | list_for_each_entry_safe(p, n, &pdev_list, list) { | 350 | list_for_each_entry(p, &pdev_list, list) { |
348 | if (p->cpu != cpu) | 351 | if (p->cpu != cpu) |
349 | continue; | 352 | continue; |
350 | 353 | ||
351 | platform_device_unregister(p->pdev); | 354 | platform_device_unregister(p->pdev); |
352 | list_del(&p->list); | 355 | list_del(&p->list); |
356 | mutex_unlock(&pdev_list_mutex); | ||
353 | kfree(p); | 357 | kfree(p); |
354 | for_each_cpu(i, cpu_core_mask(cpu)) { | 358 | for_each_cpu(i, cpu_core_mask(cpu)) { |
355 | if (i != cpu) { | 359 | if (i != cpu) { |
@@ -358,7 +362,7 @@ static void pkgtemp_device_remove(unsigned int cpu) | |||
358 | break; | 362 | break; |
359 | } | 363 | } |
360 | } | 364 | } |
361 | break; | 365 | return; |
362 | } | 366 | } |
363 | mutex_unlock(&pdev_list_mutex); | 367 | mutex_unlock(&pdev_list_mutex); |
364 | } | 368 | } |
@@ -399,11 +403,6 @@ static int __init pkgtemp_init(void) | |||
399 | goto exit; | 403 | goto exit; |
400 | 404 | ||
401 | for_each_online_cpu(i) { | 405 | for_each_online_cpu(i) { |
402 | struct cpuinfo_x86 *c = &cpu_data(i); | ||
403 | |||
404 | if (!cpu_has(c, X86_FEATURE_PTS)) | ||
405 | continue; | ||
406 | |||
407 | err = pkgtemp_device_add(i); | 406 | err = pkgtemp_device_add(i); |
408 | if (err) | 407 | if (err) |
409 | goto exit_devices_unreg; | 408 | goto exit_devices_unreg; |
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index e96e69dd36f..072c58008a6 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c | |||
@@ -127,6 +127,7 @@ superio_enter(int ioreg) | |||
127 | static inline void | 127 | static inline void |
128 | superio_exit(int ioreg) | 128 | superio_exit(int ioreg) |
129 | { | 129 | { |
130 | outb(0xaa, ioreg); | ||
130 | outb(0x02, ioreg); | 131 | outb(0x02, ioreg); |
131 | outb(0x02, ioreg + 1); | 132 | outb(0x02, ioreg + 1); |
132 | } | 133 | } |
diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c index f7bd2613cec..f2de3be35df 100644 --- a/drivers/i2c/busses/i2c-cpm.c +++ b/drivers/i2c/busses/i2c-cpm.c | |||
@@ -677,6 +677,11 @@ static int __devinit cpm_i2c_probe(struct platform_device *ofdev, | |||
677 | dev_dbg(&ofdev->dev, "hw routines for %s registered.\n", | 677 | dev_dbg(&ofdev->dev, "hw routines for %s registered.\n", |
678 | cpm->adap.name); | 678 | cpm->adap.name); |
679 | 679 | ||
680 | /* | ||
681 | * register OF I2C devices | ||
682 | */ | ||
683 | of_i2c_register_devices(&cpm->adap); | ||
684 | |||
680 | return 0; | 685 | return 0; |
681 | out_shut: | 686 | out_shut: |
682 | cpm_i2c_shutdown(cpm); | 687 | cpm_i2c_shutdown(cpm); |
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index 2222c87876b..b8feac5f2ef 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c | |||
@@ -357,9 +357,6 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) | |||
357 | 357 | ||
358 | dev->terminate = 0; | 358 | dev->terminate = 0; |
359 | 359 | ||
360 | /* write the data into mode register */ | ||
361 | davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); | ||
362 | |||
363 | /* | 360 | /* |
364 | * First byte should be set here, not after interrupt, | 361 | * First byte should be set here, not after interrupt, |
365 | * because transmit-data-ready interrupt can come before | 362 | * because transmit-data-ready interrupt can come before |
@@ -371,6 +368,9 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) | |||
371 | dev->buf_len--; | 368 | dev->buf_len--; |
372 | } | 369 | } |
373 | 370 | ||
371 | /* write the data into mode register; start transmitting */ | ||
372 | davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); | ||
373 | |||
374 | r = wait_for_completion_interruptible_timeout(&dev->cmd_complete, | 374 | r = wait_for_completion_interruptible_timeout(&dev->cmd_complete, |
375 | dev->adapter.timeout); | 375 | dev->adapter.timeout); |
376 | if (r == 0) { | 376 | if (r == 0) { |
diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index 43ca32fddde..89eedf45d30 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c | |||
@@ -761,6 +761,9 @@ static int __devinit iic_probe(struct platform_device *ofdev, | |||
761 | dev_info(&ofdev->dev, "using %s mode\n", | 761 | dev_info(&ofdev->dev, "using %s mode\n", |
762 | dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)"); | 762 | dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)"); |
763 | 763 | ||
764 | /* Now register all the child nodes */ | ||
765 | of_i2c_register_devices(adap); | ||
766 | |||
764 | return 0; | 767 | return 0; |
765 | 768 | ||
766 | error_cleanup: | 769 | error_cleanup: |
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index a1c419a716a..b74e6dc6886 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c | |||
@@ -632,6 +632,7 @@ static int __devinit fsl_i2c_probe(struct platform_device *op, | |||
632 | dev_err(i2c->dev, "failed to add adapter\n"); | 632 | dev_err(i2c->dev, "failed to add adapter\n"); |
633 | goto fail_add; | 633 | goto fail_add; |
634 | } | 634 | } |
635 | of_i2c_register_devices(&i2c->adap); | ||
635 | 636 | ||
636 | return result; | 637 | return result; |
637 | 638 | ||
diff --git a/drivers/i2c/busses/i2c-octeon.c b/drivers/i2c/busses/i2c-octeon.c index 0e9f85d0a83..56dbe54e881 100644 --- a/drivers/i2c/busses/i2c-octeon.c +++ b/drivers/i2c/busses/i2c-octeon.c | |||
@@ -218,7 +218,7 @@ static int octeon_i2c_wait(struct octeon_i2c *i2c) | |||
218 | return result; | 218 | return result; |
219 | } else if (result == 0) { | 219 | } else if (result == 0) { |
220 | dev_dbg(i2c->dev, "%s: timeout\n", __func__); | 220 | dev_dbg(i2c->dev, "%s: timeout\n", __func__); |
221 | result = -ETIMEDOUT; | 221 | return -ETIMEDOUT; |
222 | } | 222 | } |
223 | 223 | ||
224 | return 0; | 224 | return 0; |
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 7674efb5537..b33c78586bf 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c | |||
@@ -680,6 +680,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) | |||
680 | 680 | ||
681 | if (r == 0) | 681 | if (r == 0) |
682 | r = num; | 682 | r = num; |
683 | |||
684 | omap_i2c_wait_for_bb(dev); | ||
683 | out: | 685 | out: |
684 | omap_i2c_idle(dev); | 686 | omap_i2c_idle(dev); |
685 | return r; | 687 | return r; |
diff --git a/drivers/i2c/busses/i2c-pca-isa.c b/drivers/i2c/busses/i2c-pca-isa.c index bbd77603a41..29933f87d8f 100644 --- a/drivers/i2c/busses/i2c-pca-isa.c +++ b/drivers/i2c/busses/i2c-pca-isa.c | |||
@@ -71,8 +71,8 @@ static int pca_isa_readbyte(void *pd, int reg) | |||
71 | 71 | ||
72 | static int pca_isa_waitforcompletion(void *pd) | 72 | static int pca_isa_waitforcompletion(void *pd) |
73 | { | 73 | { |
74 | long ret = ~0; | ||
75 | unsigned long timeout; | 74 | unsigned long timeout; |
75 | long ret; | ||
76 | 76 | ||
77 | if (irq > -1) { | 77 | if (irq > -1) { |
78 | ret = wait_event_timeout(pca_wait, | 78 | ret = wait_event_timeout(pca_wait, |
@@ -81,11 +81,15 @@ static int pca_isa_waitforcompletion(void *pd) | |||
81 | } else { | 81 | } else { |
82 | /* Do polling */ | 82 | /* Do polling */ |
83 | timeout = jiffies + pca_isa_ops.timeout; | 83 | timeout = jiffies + pca_isa_ops.timeout; |
84 | while (((pca_isa_readbyte(pd, I2C_PCA_CON) | 84 | do { |
85 | & I2C_PCA_CON_SI) == 0) | 85 | ret = time_before(jiffies, timeout); |
86 | && (ret = time_before(jiffies, timeout))) | 86 | if (pca_isa_readbyte(pd, I2C_PCA_CON) |
87 | & I2C_PCA_CON_SI) | ||
88 | break; | ||
87 | udelay(100); | 89 | udelay(100); |
90 | } while (ret); | ||
88 | } | 91 | } |
92 | |||
89 | return ret > 0; | 93 | return ret > 0; |
90 | } | 94 | } |
91 | 95 | ||
diff --git a/drivers/i2c/busses/i2c-pca-platform.c b/drivers/i2c/busses/i2c-pca-platform.c index ef5c78487eb..5f6d7f89e22 100644 --- a/drivers/i2c/busses/i2c-pca-platform.c +++ b/drivers/i2c/busses/i2c-pca-platform.c | |||
@@ -80,8 +80,8 @@ static void i2c_pca_pf_writebyte32(void *pd, int reg, int val) | |||
80 | static int i2c_pca_pf_waitforcompletion(void *pd) | 80 | static int i2c_pca_pf_waitforcompletion(void *pd) |
81 | { | 81 | { |
82 | struct i2c_pca_pf_data *i2c = pd; | 82 | struct i2c_pca_pf_data *i2c = pd; |
83 | long ret = ~0; | ||
84 | unsigned long timeout; | 83 | unsigned long timeout; |
84 | long ret; | ||
85 | 85 | ||
86 | if (i2c->irq) { | 86 | if (i2c->irq) { |
87 | ret = wait_event_timeout(i2c->wait, | 87 | ret = wait_event_timeout(i2c->wait, |
@@ -90,10 +90,13 @@ static int i2c_pca_pf_waitforcompletion(void *pd) | |||
90 | } else { | 90 | } else { |
91 | /* Do polling */ | 91 | /* Do polling */ |
92 | timeout = jiffies + i2c->adap.timeout; | 92 | timeout = jiffies + i2c->adap.timeout; |
93 | while (((i2c->algo_data.read_byte(i2c, I2C_PCA_CON) | 93 | do { |
94 | & I2C_PCA_CON_SI) == 0) | 94 | ret = time_before(jiffies, timeout); |
95 | && (ret = time_before(jiffies, timeout))) | 95 | if (i2c->algo_data.read_byte(i2c, I2C_PCA_CON) |
96 | & I2C_PCA_CON_SI) | ||
97 | break; | ||
96 | udelay(100); | 98 | udelay(100); |
99 | } while (ret); | ||
97 | } | 100 | } |
98 | 101 | ||
99 | return ret > 0; | 102 | return ret > 0; |
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 72902e0bbfa..bf831bf8158 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c | |||
@@ -662,8 +662,8 @@ static int s3c24xx_i2c_clockrate(struct s3c24xx_i2c *i2c, unsigned int *got) | |||
662 | unsigned long sda_delay; | 662 | unsigned long sda_delay; |
663 | 663 | ||
664 | if (pdata->sda_delay) { | 664 | if (pdata->sda_delay) { |
665 | sda_delay = (freq / 1000) * pdata->sda_delay; | 665 | sda_delay = clkin * pdata->sda_delay; |
666 | sda_delay /= 1000000; | 666 | sda_delay = DIV_ROUND_UP(sda_delay, 1000000); |
667 | sda_delay = DIV_ROUND_UP(sda_delay, 5); | 667 | sda_delay = DIV_ROUND_UP(sda_delay, 5); |
668 | if (sda_delay > 3) | 668 | if (sda_delay > 3) |
669 | sda_delay = 3; | 669 | sda_delay = 3; |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 6649176de94..bea4c5021d2 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include <linux/init.h> | 32 | #include <linux/init.h> |
33 | #include <linux/idr.h> | 33 | #include <linux/idr.h> |
34 | #include <linux/mutex.h> | 34 | #include <linux/mutex.h> |
35 | #include <linux/of_i2c.h> | ||
36 | #include <linux/of_device.h> | 35 | #include <linux/of_device.h> |
37 | #include <linux/completion.h> | 36 | #include <linux/completion.h> |
38 | #include <linux/hardirq.h> | 37 | #include <linux/hardirq.h> |
@@ -197,11 +196,12 @@ static int i2c_device_pm_suspend(struct device *dev) | |||
197 | { | 196 | { |
198 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; | 197 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; |
199 | 198 | ||
200 | if (pm_runtime_suspended(dev)) | 199 | if (pm) { |
201 | return 0; | 200 | if (pm_runtime_suspended(dev)) |
202 | 201 | return 0; | |
203 | if (pm) | 202 | else |
204 | return pm->suspend ? pm->suspend(dev) : 0; | 203 | return pm->suspend ? pm->suspend(dev) : 0; |
204 | } | ||
205 | 205 | ||
206 | return i2c_legacy_suspend(dev, PMSG_SUSPEND); | 206 | return i2c_legacy_suspend(dev, PMSG_SUSPEND); |
207 | } | 207 | } |
@@ -216,12 +216,6 @@ static int i2c_device_pm_resume(struct device *dev) | |||
216 | else | 216 | else |
217 | ret = i2c_legacy_resume(dev); | 217 | ret = i2c_legacy_resume(dev); |
218 | 218 | ||
219 | if (!ret) { | ||
220 | pm_runtime_disable(dev); | ||
221 | pm_runtime_set_active(dev); | ||
222 | pm_runtime_enable(dev); | ||
223 | } | ||
224 | |||
225 | return ret; | 219 | return ret; |
226 | } | 220 | } |
227 | 221 | ||
@@ -229,11 +223,12 @@ static int i2c_device_pm_freeze(struct device *dev) | |||
229 | { | 223 | { |
230 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; | 224 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; |
231 | 225 | ||
232 | if (pm_runtime_suspended(dev)) | 226 | if (pm) { |
233 | return 0; | 227 | if (pm_runtime_suspended(dev)) |
234 | 228 | return 0; | |
235 | if (pm) | 229 | else |
236 | return pm->freeze ? pm->freeze(dev) : 0; | 230 | return pm->freeze ? pm->freeze(dev) : 0; |
231 | } | ||
237 | 232 | ||
238 | return i2c_legacy_suspend(dev, PMSG_FREEZE); | 233 | return i2c_legacy_suspend(dev, PMSG_FREEZE); |
239 | } | 234 | } |
@@ -242,11 +237,12 @@ static int i2c_device_pm_thaw(struct device *dev) | |||
242 | { | 237 | { |
243 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; | 238 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; |
244 | 239 | ||
245 | if (pm_runtime_suspended(dev)) | 240 | if (pm) { |
246 | return 0; | 241 | if (pm_runtime_suspended(dev)) |
247 | 242 | return 0; | |
248 | if (pm) | 243 | else |
249 | return pm->thaw ? pm->thaw(dev) : 0; | 244 | return pm->thaw ? pm->thaw(dev) : 0; |
245 | } | ||
250 | 246 | ||
251 | return i2c_legacy_resume(dev); | 247 | return i2c_legacy_resume(dev); |
252 | } | 248 | } |
@@ -255,11 +251,12 @@ static int i2c_device_pm_poweroff(struct device *dev) | |||
255 | { | 251 | { |
256 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; | 252 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; |
257 | 253 | ||
258 | if (pm_runtime_suspended(dev)) | 254 | if (pm) { |
259 | return 0; | 255 | if (pm_runtime_suspended(dev)) |
260 | 256 | return 0; | |
261 | if (pm) | 257 | else |
262 | return pm->poweroff ? pm->poweroff(dev) : 0; | 258 | return pm->poweroff ? pm->poweroff(dev) : 0; |
259 | } | ||
263 | 260 | ||
264 | return i2c_legacy_suspend(dev, PMSG_HIBERNATE); | 261 | return i2c_legacy_suspend(dev, PMSG_HIBERNATE); |
265 | } | 262 | } |
@@ -876,9 +873,6 @@ static int i2c_register_adapter(struct i2c_adapter *adap) | |||
876 | if (adap->nr < __i2c_first_dynamic_bus_num) | 873 | if (adap->nr < __i2c_first_dynamic_bus_num) |
877 | i2c_scan_static_board_info(adap); | 874 | i2c_scan_static_board_info(adap); |
878 | 875 | ||
879 | /* Register devices from the device tree */ | ||
880 | of_i2c_register_devices(adap); | ||
881 | |||
882 | /* Notify drivers */ | 876 | /* Notify drivers */ |
883 | mutex_lock(&core_lock); | 877 | mutex_lock(&core_lock); |
884 | bus_for_each_drv(&i2c_bus_type, NULL, adap, __process_new_adapter); | 878 | bus_for_each_drv(&i2c_bus_type, NULL, adap, __process_new_adapter); |
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 4c3d1bfec0c..068cef0a987 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
@@ -1448,19 +1448,13 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, | |||
1448 | if (hwif == NULL) | 1448 | if (hwif == NULL) |
1449 | continue; | 1449 | continue; |
1450 | 1450 | ||
1451 | if (hwif->present) | ||
1452 | hwif_register_devices(hwif); | ||
1453 | } | ||
1454 | |||
1455 | ide_host_for_each_port(i, hwif, host) { | ||
1456 | if (hwif == NULL) | ||
1457 | continue; | ||
1458 | |||
1459 | ide_sysfs_register_port(hwif); | 1451 | ide_sysfs_register_port(hwif); |
1460 | ide_proc_register_port(hwif); | 1452 | ide_proc_register_port(hwif); |
1461 | 1453 | ||
1462 | if (hwif->present) | 1454 | if (hwif->present) { |
1463 | ide_proc_port_register_devices(hwif); | 1455 | ide_proc_port_register_devices(hwif); |
1456 | hwif_register_devices(hwif); | ||
1457 | } | ||
1464 | } | 1458 | } |
1465 | 1459 | ||
1466 | return j ? 0 : -1; | 1460 | return j ? 0 : -1; |
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index a10152bb142..c37ef64d146 100755..100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c | |||
@@ -83,7 +83,7 @@ static unsigned int mwait_substates; | |||
83 | /* Reliable LAPIC Timer States, bit 1 for C1 etc. */ | 83 | /* Reliable LAPIC Timer States, bit 1 for C1 etc. */ |
84 | static unsigned int lapic_timer_reliable_states; | 84 | static unsigned int lapic_timer_reliable_states; |
85 | 85 | ||
86 | static struct cpuidle_device *intel_idle_cpuidle_devices; | 86 | static struct cpuidle_device __percpu *intel_idle_cpuidle_devices; |
87 | static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state); | 87 | static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state); |
88 | 88 | ||
89 | static struct cpuidle_state *cpuidle_state_table; | 89 | static struct cpuidle_state *cpuidle_state_table; |
@@ -108,7 +108,7 @@ static struct cpuidle_state nehalem_cstates[MWAIT_MAX_NUM_CSTATES] = { | |||
108 | .name = "NHM-C3", | 108 | .name = "NHM-C3", |
109 | .desc = "MWAIT 0x10", | 109 | .desc = "MWAIT 0x10", |
110 | .driver_data = (void *) 0x10, | 110 | .driver_data = (void *) 0x10, |
111 | .flags = CPUIDLE_FLAG_TIME_VALID, | 111 | .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, |
112 | .exit_latency = 20, | 112 | .exit_latency = 20, |
113 | .power_usage = 500, | 113 | .power_usage = 500, |
114 | .target_residency = 80, | 114 | .target_residency = 80, |
@@ -117,7 +117,7 @@ static struct cpuidle_state nehalem_cstates[MWAIT_MAX_NUM_CSTATES] = { | |||
117 | .name = "NHM-C6", | 117 | .name = "NHM-C6", |
118 | .desc = "MWAIT 0x20", | 118 | .desc = "MWAIT 0x20", |
119 | .driver_data = (void *) 0x20, | 119 | .driver_data = (void *) 0x20, |
120 | .flags = CPUIDLE_FLAG_TIME_VALID, | 120 | .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, |
121 | .exit_latency = 200, | 121 | .exit_latency = 200, |
122 | .power_usage = 350, | 122 | .power_usage = 350, |
123 | .target_residency = 800, | 123 | .target_residency = 800, |
@@ -149,7 +149,7 @@ static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = { | |||
149 | .name = "ATM-C4", | 149 | .name = "ATM-C4", |
150 | .desc = "MWAIT 0x30", | 150 | .desc = "MWAIT 0x30", |
151 | .driver_data = (void *) 0x30, | 151 | .driver_data = (void *) 0x30, |
152 | .flags = CPUIDLE_FLAG_TIME_VALID, | 152 | .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, |
153 | .exit_latency = 100, | 153 | .exit_latency = 100, |
154 | .power_usage = 250, | 154 | .power_usage = 250, |
155 | .target_residency = 400, | 155 | .target_residency = 400, |
@@ -157,13 +157,13 @@ static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = { | |||
157 | { /* MWAIT C5 */ }, | 157 | { /* MWAIT C5 */ }, |
158 | { /* MWAIT C6 */ | 158 | { /* MWAIT C6 */ |
159 | .name = "ATM-C6", | 159 | .name = "ATM-C6", |
160 | .desc = "MWAIT 0x40", | 160 | .desc = "MWAIT 0x52", |
161 | .driver_data = (void *) 0x40, | 161 | .driver_data = (void *) 0x52, |
162 | .flags = CPUIDLE_FLAG_TIME_VALID, | 162 | .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, |
163 | .exit_latency = 200, | 163 | .exit_latency = 140, |
164 | .power_usage = 150, | 164 | .power_usage = 150, |
165 | .target_residency = 800, | 165 | .target_residency = 560, |
166 | .enter = NULL }, /* disabled */ | 166 | .enter = &intel_idle }, |
167 | }; | 167 | }; |
168 | 168 | ||
169 | /** | 169 | /** |
@@ -185,6 +185,16 @@ static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state) | |||
185 | 185 | ||
186 | local_irq_disable(); | 186 | local_irq_disable(); |
187 | 187 | ||
188 | /* | ||
189 | * If the state flag indicates that the TLB will be flushed or if this | ||
190 | * is the deepest c-state supported, do a voluntary leave mm to avoid | ||
191 | * costly and mostly unnecessary wakeups for flushing the user TLB's | ||
192 | * associated with the active mm. | ||
193 | */ | ||
194 | if (state->flags & CPUIDLE_FLAG_TLB_FLUSHED || | ||
195 | (&dev->states[dev->state_count - 1] == state)) | ||
196 | leave_mm(cpu); | ||
197 | |||
188 | if (!(lapic_timer_reliable_states & (1 << (cstate)))) | 198 | if (!(lapic_timer_reliable_states & (1 << (cstate)))) |
189 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu); | 199 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu); |
190 | 200 | ||
diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c index d0dc1db80b2..50815022cff 100644 --- a/drivers/ieee1394/ohci1394.c +++ b/drivers/ieee1394/ohci1394.c | |||
@@ -1106,7 +1106,7 @@ static int ohci_iso_recv_init(struct hpsb_iso *iso) | |||
1106 | if (recv->block_irq_interval * 4 > iso->buf_packets) | 1106 | if (recv->block_irq_interval * 4 > iso->buf_packets) |
1107 | recv->block_irq_interval = iso->buf_packets / 4; | 1107 | recv->block_irq_interval = iso->buf_packets / 4; |
1108 | if (recv->block_irq_interval < 1) | 1108 | if (recv->block_irq_interval < 1) |
1109 | recv->block_irq_interval = 1; | 1109 | recv->block_irq_interval = 1; |
1110 | 1110 | ||
1111 | /* choose a buffer stride */ | 1111 | /* choose a buffer stride */ |
1112 | /* must be a power of 2, and <= PAGE_SIZE */ | 1112 | /* must be a power of 2, and <= PAGE_SIZE */ |
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.h b/drivers/infiniband/hw/cxgb3/cxio_hal.h index 8f0caf7d448..78fbe9ffe7f 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_hal.h +++ b/drivers/infiniband/hw/cxgb3/cxio_hal.h | |||
@@ -53,7 +53,7 @@ | |||
53 | #define T3_MAX_PBL_SIZE 256 | 53 | #define T3_MAX_PBL_SIZE 256 |
54 | #define T3_MAX_RQ_SIZE 1024 | 54 | #define T3_MAX_RQ_SIZE 1024 |
55 | #define T3_MAX_QP_DEPTH (T3_MAX_RQ_SIZE-1) | 55 | #define T3_MAX_QP_DEPTH (T3_MAX_RQ_SIZE-1) |
56 | #define T3_MAX_CQ_DEPTH 262144 | 56 | #define T3_MAX_CQ_DEPTH 65536 |
57 | #define T3_MAX_NUM_STAG (1<<15) | 57 | #define T3_MAX_NUM_STAG (1<<15) |
58 | #define T3_MAX_MR_SIZE 0x100000000ULL | 58 | #define T3_MAX_MR_SIZE 0x100000000ULL |
59 | #define T3_PAGESIZE_MASK 0xffff000 /* 4KB-128MB */ | 59 | #define T3_PAGESIZE_MASK 0xffff000 /* 4KB-128MB */ |
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c index d88077a2199..13c88871dc3 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_cm.c +++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c | |||
@@ -463,7 +463,8 @@ static int send_connect(struct iwch_ep *ep) | |||
463 | V_MSS_IDX(mtu_idx) | | 463 | V_MSS_IDX(mtu_idx) | |
464 | V_L2T_IDX(ep->l2t->idx) | V_TX_CHANNEL(ep->l2t->smt_idx); | 464 | V_L2T_IDX(ep->l2t->idx) | V_TX_CHANNEL(ep->l2t->smt_idx); |
465 | opt0l = V_TOS((ep->tos >> 2) & M_TOS) | V_RCV_BUFSIZ(rcv_win>>10); | 465 | opt0l = V_TOS((ep->tos >> 2) & M_TOS) | V_RCV_BUFSIZ(rcv_win>>10); |
466 | opt2 = V_FLAVORS_VALID(1) | V_CONG_CONTROL_FLAVOR(cong_flavor); | 466 | opt2 = F_RX_COALESCE_VALID | V_RX_COALESCE(0) | V_FLAVORS_VALID(1) | |
467 | V_CONG_CONTROL_FLAVOR(cong_flavor); | ||
467 | skb->priority = CPL_PRIORITY_SETUP; | 468 | skb->priority = CPL_PRIORITY_SETUP; |
468 | set_arp_failure_handler(skb, act_open_req_arp_failure); | 469 | set_arp_failure_handler(skb, act_open_req_arp_failure); |
469 | 470 | ||
@@ -1280,7 +1281,8 @@ static void accept_cr(struct iwch_ep *ep, __be32 peer_ip, struct sk_buff *skb) | |||
1280 | V_MSS_IDX(mtu_idx) | | 1281 | V_MSS_IDX(mtu_idx) | |
1281 | V_L2T_IDX(ep->l2t->idx) | V_TX_CHANNEL(ep->l2t->smt_idx); | 1282 | V_L2T_IDX(ep->l2t->idx) | V_TX_CHANNEL(ep->l2t->smt_idx); |
1282 | opt0l = V_TOS((ep->tos >> 2) & M_TOS) | V_RCV_BUFSIZ(rcv_win>>10); | 1283 | opt0l = V_TOS((ep->tos >> 2) & M_TOS) | V_RCV_BUFSIZ(rcv_win>>10); |
1283 | opt2 = V_FLAVORS_VALID(1) | V_CONG_CONTROL_FLAVOR(cong_flavor); | 1284 | opt2 = F_RX_COALESCE_VALID | V_RX_COALESCE(0) | V_FLAVORS_VALID(1) | |
1285 | V_CONG_CONTROL_FLAVOR(cong_flavor); | ||
1284 | 1286 | ||
1285 | rpl = cplhdr(skb); | 1287 | rpl = cplhdr(skb); |
1286 | rpl->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); | 1288 | rpl->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); |
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index 443cea55daa..61e0efd4ccf 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c | |||
@@ -502,7 +502,9 @@ int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
502 | static void nes_retrans_expired(struct nes_cm_node *cm_node) | 502 | static void nes_retrans_expired(struct nes_cm_node *cm_node) |
503 | { | 503 | { |
504 | struct iw_cm_id *cm_id = cm_node->cm_id; | 504 | struct iw_cm_id *cm_id = cm_node->cm_id; |
505 | switch (cm_node->state) { | 505 | enum nes_cm_node_state state = cm_node->state; |
506 | cm_node->state = NES_CM_STATE_CLOSED; | ||
507 | switch (state) { | ||
506 | case NES_CM_STATE_SYN_RCVD: | 508 | case NES_CM_STATE_SYN_RCVD: |
507 | case NES_CM_STATE_CLOSING: | 509 | case NES_CM_STATE_CLOSING: |
508 | rem_ref_cm_node(cm_node->cm_core, cm_node); | 510 | rem_ref_cm_node(cm_node->cm_core, cm_node); |
@@ -511,7 +513,6 @@ static void nes_retrans_expired(struct nes_cm_node *cm_node) | |||
511 | case NES_CM_STATE_FIN_WAIT1: | 513 | case NES_CM_STATE_FIN_WAIT1: |
512 | if (cm_node->cm_id) | 514 | if (cm_node->cm_id) |
513 | cm_id->rem_ref(cm_id); | 515 | cm_id->rem_ref(cm_id); |
514 | cm_node->state = NES_CM_STATE_CLOSED; | ||
515 | send_reset(cm_node, NULL); | 516 | send_reset(cm_node, NULL); |
516 | break; | 517 | break; |
517 | default: | 518 | default: |
@@ -1439,9 +1440,6 @@ static void handle_rst_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1439 | break; | 1440 | break; |
1440 | case NES_CM_STATE_MPAREQ_RCVD: | 1441 | case NES_CM_STATE_MPAREQ_RCVD: |
1441 | passive_state = atomic_add_return(1, &cm_node->passive_state); | 1442 | passive_state = atomic_add_return(1, &cm_node->passive_state); |
1442 | if (passive_state == NES_SEND_RESET_EVENT) | ||
1443 | create_event(cm_node, NES_CM_EVENT_RESET); | ||
1444 | cm_node->state = NES_CM_STATE_CLOSED; | ||
1445 | dev_kfree_skb_any(skb); | 1443 | dev_kfree_skb_any(skb); |
1446 | break; | 1444 | break; |
1447 | case NES_CM_STATE_ESTABLISHED: | 1445 | case NES_CM_STATE_ESTABLISHED: |
@@ -1456,6 +1454,7 @@ static void handle_rst_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1456 | case NES_CM_STATE_CLOSED: | 1454 | case NES_CM_STATE_CLOSED: |
1457 | drop_packet(skb); | 1455 | drop_packet(skb); |
1458 | break; | 1456 | break; |
1457 | case NES_CM_STATE_FIN_WAIT2: | ||
1459 | case NES_CM_STATE_FIN_WAIT1: | 1458 | case NES_CM_STATE_FIN_WAIT1: |
1460 | case NES_CM_STATE_LAST_ACK: | 1459 | case NES_CM_STATE_LAST_ACK: |
1461 | cm_node->cm_id->rem_ref(cm_node->cm_id); | 1460 | cm_node->cm_id->rem_ref(cm_node->cm_id); |
@@ -2777,6 +2776,12 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
2777 | return -EINVAL; | 2776 | return -EINVAL; |
2778 | } | 2777 | } |
2779 | 2778 | ||
2779 | passive_state = atomic_add_return(1, &cm_node->passive_state); | ||
2780 | if (passive_state == NES_SEND_RESET_EVENT) { | ||
2781 | rem_ref_cm_node(cm_node->cm_core, cm_node); | ||
2782 | return -ECONNRESET; | ||
2783 | } | ||
2784 | |||
2780 | /* associate the node with the QP */ | 2785 | /* associate the node with the QP */ |
2781 | nesqp->cm_node = (void *)cm_node; | 2786 | nesqp->cm_node = (void *)cm_node; |
2782 | cm_node->nesqp = nesqp; | 2787 | cm_node->nesqp = nesqp; |
@@ -2979,9 +2984,6 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
2979 | printk(KERN_ERR "%s[%u] OFA CM event_handler returned, " | 2984 | printk(KERN_ERR "%s[%u] OFA CM event_handler returned, " |
2980 | "ret=%d\n", __func__, __LINE__, ret); | 2985 | "ret=%d\n", __func__, __LINE__, ret); |
2981 | 2986 | ||
2982 | passive_state = atomic_add_return(1, &cm_node->passive_state); | ||
2983 | if (passive_state == NES_SEND_RESET_EVENT) | ||
2984 | create_event(cm_node, NES_CM_EVENT_RESET); | ||
2985 | return 0; | 2987 | return 0; |
2986 | } | 2988 | } |
2987 | 2989 | ||
diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c index f8233c851c6..1980a461c49 100644 --- a/drivers/infiniband/hw/nes/nes_hw.c +++ b/drivers/infiniband/hw/nes/nes_hw.c | |||
@@ -3468,6 +3468,19 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev, | |||
3468 | return; /* Ignore it, wait for close complete */ | 3468 | return; /* Ignore it, wait for close complete */ |
3469 | 3469 | ||
3470 | if (atomic_inc_return(&nesqp->close_timer_started) == 1) { | 3470 | if (atomic_inc_return(&nesqp->close_timer_started) == 1) { |
3471 | if ((tcp_state == NES_AEQE_TCP_STATE_CLOSE_WAIT) && | ||
3472 | (nesqp->ibqp_state == IB_QPS_RTS) && | ||
3473 | ((nesadapter->eeprom_version >> 16) != NES_A0)) { | ||
3474 | spin_lock_irqsave(&nesqp->lock, flags); | ||
3475 | nesqp->hw_iwarp_state = iwarp_state; | ||
3476 | nesqp->hw_tcp_state = tcp_state; | ||
3477 | nesqp->last_aeq = async_event_id; | ||
3478 | next_iwarp_state = NES_CQP_QP_IWARP_STATE_CLOSING; | ||
3479 | nesqp->hw_iwarp_state = NES_AEQE_IWARP_STATE_CLOSING; | ||
3480 | spin_unlock_irqrestore(&nesqp->lock, flags); | ||
3481 | nes_hw_modify_qp(nesdev, nesqp, next_iwarp_state, 0, 0); | ||
3482 | nes_cm_disconn(nesqp); | ||
3483 | } | ||
3471 | nesqp->cm_id->add_ref(nesqp->cm_id); | 3484 | nesqp->cm_id->add_ref(nesqp->cm_id); |
3472 | schedule_nes_timer(nesqp->cm_node, (struct sk_buff *)nesqp, | 3485 | schedule_nes_timer(nesqp->cm_node, (struct sk_buff *)nesqp, |
3473 | NES_TIMER_TYPE_CLOSE, 1, 0); | 3486 | NES_TIMER_TYPE_CLOSE, 1, 0); |
@@ -3477,7 +3490,6 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev, | |||
3477 | nesqp->hwqp.qp_id, atomic_read(&nesqp->refcount), | 3490 | nesqp->hwqp.qp_id, atomic_read(&nesqp->refcount), |
3478 | async_event_id, nesqp->last_aeq, tcp_state); | 3491 | async_event_id, nesqp->last_aeq, tcp_state); |
3479 | } | 3492 | } |
3480 | |||
3481 | break; | 3493 | break; |
3482 | case NES_AEQE_AEID_LLP_CLOSE_COMPLETE: | 3494 | case NES_AEQE_AEID_LLP_CLOSE_COMPLETE: |
3483 | if (nesqp->term_flags) { | 3495 | if (nesqp->term_flags) { |
diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h index aa9183db32b..1204c3432b6 100644 --- a/drivers/infiniband/hw/nes/nes_hw.h +++ b/drivers/infiniband/hw/nes/nes_hw.h | |||
@@ -45,6 +45,7 @@ | |||
45 | #define NES_PHY_TYPE_KR 9 | 45 | #define NES_PHY_TYPE_KR 9 |
46 | 46 | ||
47 | #define NES_MULTICAST_PF_MAX 8 | 47 | #define NES_MULTICAST_PF_MAX 8 |
48 | #define NES_A0 3 | ||
48 | 49 | ||
49 | enum pci_regs { | 50 | enum pci_regs { |
50 | NES_INT_STAT = 0x0000, | 51 | NES_INT_STAT = 0x0000, |
diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c index 6dfdd49cdbc..10560c796fd 100644 --- a/drivers/infiniband/hw/nes/nes_nic.c +++ b/drivers/infiniband/hw/nes/nes_nic.c | |||
@@ -1446,14 +1446,14 @@ static int nes_netdev_set_pauseparam(struct net_device *netdev, | |||
1446 | NES_IDX_MAC_TX_CONFIG + (nesdev->mac_index*0x200)); | 1446 | NES_IDX_MAC_TX_CONFIG + (nesdev->mac_index*0x200)); |
1447 | u32temp |= NES_IDX_MAC_TX_CONFIG_ENABLE_PAUSE; | 1447 | u32temp |= NES_IDX_MAC_TX_CONFIG_ENABLE_PAUSE; |
1448 | nes_write_indexed(nesdev, | 1448 | nes_write_indexed(nesdev, |
1449 | NES_IDX_MAC_TX_CONFIG_ENABLE_PAUSE + (nesdev->mac_index*0x200), u32temp); | 1449 | NES_IDX_MAC_TX_CONFIG + (nesdev->mac_index*0x200), u32temp); |
1450 | nesdev->disable_tx_flow_control = 0; | 1450 | nesdev->disable_tx_flow_control = 0; |
1451 | } else if ((et_pauseparam->tx_pause == 0) && (nesdev->disable_tx_flow_control == 0)) { | 1451 | } else if ((et_pauseparam->tx_pause == 0) && (nesdev->disable_tx_flow_control == 0)) { |
1452 | u32temp = nes_read_indexed(nesdev, | 1452 | u32temp = nes_read_indexed(nesdev, |
1453 | NES_IDX_MAC_TX_CONFIG + (nesdev->mac_index*0x200)); | 1453 | NES_IDX_MAC_TX_CONFIG + (nesdev->mac_index*0x200)); |
1454 | u32temp &= ~NES_IDX_MAC_TX_CONFIG_ENABLE_PAUSE; | 1454 | u32temp &= ~NES_IDX_MAC_TX_CONFIG_ENABLE_PAUSE; |
1455 | nes_write_indexed(nesdev, | 1455 | nes_write_indexed(nesdev, |
1456 | NES_IDX_MAC_TX_CONFIG_ENABLE_PAUSE + (nesdev->mac_index*0x200), u32temp); | 1456 | NES_IDX_MAC_TX_CONFIG + (nesdev->mac_index*0x200), u32temp); |
1457 | nesdev->disable_tx_flow_control = 1; | 1457 | nesdev->disable_tx_flow_control = 1; |
1458 | } | 1458 | } |
1459 | if ((et_pauseparam->rx_pause == 1) && (nesdev->disable_rx_flow_control == 1)) { | 1459 | if ((et_pauseparam->rx_pause == 1) && (nesdev->disable_rx_flow_control == 1)) { |
diff --git a/drivers/input/input.c b/drivers/input/input.c index a9b025f4147..ab698205651 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -1599,11 +1599,14 @@ EXPORT_SYMBOL(input_free_device); | |||
1599 | * @dev: input device supporting MT events and finger tracking | 1599 | * @dev: input device supporting MT events and finger tracking |
1600 | * @num_slots: number of slots used by the device | 1600 | * @num_slots: number of slots used by the device |
1601 | * | 1601 | * |
1602 | * This function allocates all necessary memory for MT slot handling | 1602 | * This function allocates all necessary memory for MT slot handling in the |
1603 | * in the input device, and adds ABS_MT_SLOT to the device capabilities. | 1603 | * input device, and adds ABS_MT_SLOT to the device capabilities. All slots |
1604 | * are initially marked as unused iby setting ABS_MT_TRACKING_ID to -1. | ||
1604 | */ | 1605 | */ |
1605 | int input_mt_create_slots(struct input_dev *dev, unsigned int num_slots) | 1606 | int input_mt_create_slots(struct input_dev *dev, unsigned int num_slots) |
1606 | { | 1607 | { |
1608 | int i; | ||
1609 | |||
1607 | if (!num_slots) | 1610 | if (!num_slots) |
1608 | return 0; | 1611 | return 0; |
1609 | 1612 | ||
@@ -1614,6 +1617,10 @@ int input_mt_create_slots(struct input_dev *dev, unsigned int num_slots) | |||
1614 | dev->mtsize = num_slots; | 1617 | dev->mtsize = num_slots; |
1615 | input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0); | 1618 | input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0); |
1616 | 1619 | ||
1620 | /* Mark slots as 'unused' */ | ||
1621 | for (i = 0; i < num_slots; i++) | ||
1622 | dev->mt[i].abs[ABS_MT_TRACKING_ID - ABS_MT_FIRST] = -1; | ||
1623 | |||
1617 | return 0; | 1624 | return 0; |
1618 | } | 1625 | } |
1619 | EXPORT_SYMBOL(input_mt_create_slots); | 1626 | EXPORT_SYMBOL(input_mt_create_slots); |
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index d85bd8a7967..22239e98849 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c | |||
@@ -483,6 +483,9 @@ static int joydev_handle_JSIOCSAXMAP(struct joydev *joydev, | |||
483 | 483 | ||
484 | memcpy(joydev->abspam, abspam, len); | 484 | memcpy(joydev->abspam, abspam, len); |
485 | 485 | ||
486 | for (i = 0; i < joydev->nabs; i++) | ||
487 | joydev->absmap[joydev->abspam[i]] = i; | ||
488 | |||
486 | out: | 489 | out: |
487 | kfree(abspam); | 490 | kfree(abspam); |
488 | return retval; | 491 | return retval; |
diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c index dcc86b97a15..19fa94af207 100644 --- a/drivers/input/keyboard/hil_kbd.c +++ b/drivers/input/keyboard/hil_kbd.c | |||
@@ -232,13 +232,13 @@ static void hil_dev_handle_ptr_events(struct hil_dev *ptr) | |||
232 | if (absdev) { | 232 | if (absdev) { |
233 | val = lo + (hi << 8); | 233 | val = lo + (hi << 8); |
234 | #ifdef TABLET_AUTOADJUST | 234 | #ifdef TABLET_AUTOADJUST |
235 | if (val < input_abs_min(dev, ABS_X + i)) | 235 | if (val < input_abs_get_min(dev, ABS_X + i)) |
236 | input_abs_set_min(dev, ABS_X + i, val); | 236 | input_abs_set_min(dev, ABS_X + i, val); |
237 | if (val > input_abs_max(dev, ABS_X + i)) | 237 | if (val > input_abs_get_max(dev, ABS_X + i)) |
238 | input_abs_set_max(dev, ABS_X + i, val); | 238 | input_abs_set_max(dev, ABS_X + i, val); |
239 | #endif | 239 | #endif |
240 | if (i % 3) | 240 | if (i % 3) |
241 | val = input_abs_max(dev, ABS_X + i) - val; | 241 | val = input_abs_get_max(dev, ABS_X + i) - val; |
242 | input_report_abs(dev, ABS_X + i, val); | 242 | input_report_abs(dev, ABS_X + i, val); |
243 | } else { | 243 | } else { |
244 | val = (int) (((int8_t) lo) | ((int8_t) hi << 8)); | 244 | val = (int) (((int8_t) lo) | ((int8_t) hi << 8)); |
@@ -388,11 +388,11 @@ static void hil_dev_pointer_setup(struct hil_dev *ptr) | |||
388 | 388 | ||
389 | #ifdef TABLET_AUTOADJUST | 389 | #ifdef TABLET_AUTOADJUST |
390 | for (i = 0; i < ABS_MAX; i++) { | 390 | for (i = 0; i < ABS_MAX; i++) { |
391 | int diff = input_abs_max(input_dev, ABS_X + i) / 10; | 391 | int diff = input_abs_get_max(input_dev, ABS_X + i) / 10; |
392 | input_abs_set_min(input_dev, ABS_X + i, | 392 | input_abs_set_min(input_dev, ABS_X + i, |
393 | input_abs_min(input_dev, ABS_X + i) + diff) | 393 | input_abs_get_min(input_dev, ABS_X + i) + diff); |
394 | input_abs_set_max(input_dev, ABS_X + i, | 394 | input_abs_set_max(input_dev, ABS_X + i, |
395 | input_abs_max(input_dev, ABS_X + i) - diff) | 395 | input_abs_get_max(input_dev, ABS_X + i) - diff); |
396 | } | 396 | } |
397 | #endif | 397 | #endif |
398 | 398 | ||
diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c index 0e53b3bc39a..f32404f9918 100644 --- a/drivers/input/keyboard/pxa27x_keypad.c +++ b/drivers/input/keyboard/pxa27x_keypad.c | |||
@@ -567,8 +567,6 @@ static int __devexit pxa27x_keypad_remove(struct platform_device *pdev) | |||
567 | clk_put(keypad->clk); | 567 | clk_put(keypad->clk); |
568 | 568 | ||
569 | input_unregister_device(keypad->input_dev); | 569 | input_unregister_device(keypad->input_dev); |
570 | input_free_device(keypad->input_dev); | ||
571 | |||
572 | iounmap(keypad->mmio_base); | 570 | iounmap(keypad->mmio_base); |
573 | 571 | ||
574 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 572 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index bb53fd33cd1..360698553eb 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c | |||
@@ -404,6 +404,13 @@ static int uinput_setup_device(struct uinput_device *udev, const char __user *bu | |||
404 | retval = uinput_validate_absbits(dev); | 404 | retval = uinput_validate_absbits(dev); |
405 | if (retval < 0) | 405 | if (retval < 0) |
406 | goto exit; | 406 | goto exit; |
407 | if (test_bit(ABS_MT_SLOT, dev->absbit)) { | ||
408 | int nslot = input_abs_get_max(dev, ABS_MT_SLOT) + 1; | ||
409 | input_mt_create_slots(dev, nslot); | ||
410 | input_set_events_per_packet(dev, 6 * nslot); | ||
411 | } else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) { | ||
412 | input_set_events_per_packet(dev, 60); | ||
413 | } | ||
407 | } | 414 | } |
408 | 415 | ||
409 | udev->state = UIST_SETUP_COMPLETE; | 416 | udev->state = UIST_SETUP_COMPLETE; |
@@ -811,6 +818,8 @@ static struct miscdevice uinput_misc = { | |||
811 | .minor = UINPUT_MINOR, | 818 | .minor = UINPUT_MINOR, |
812 | .name = UINPUT_NAME, | 819 | .name = UINPUT_NAME, |
813 | }; | 820 | }; |
821 | MODULE_ALIAS_MISCDEV(UINPUT_MINOR); | ||
822 | MODULE_ALIAS("devname:" UINPUT_NAME); | ||
814 | 823 | ||
815 | static int __init uinput_init(void) | 824 | static int __init uinput_init(void) |
816 | { | 825 | { |
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index ea67c49146a..b9523176391 100644 --- a/drivers/input/mouse/bcm5974.c +++ b/drivers/input/mouse/bcm5974.c | |||
@@ -337,10 +337,14 @@ static void report_finger_data(struct input_dev *input, | |||
337 | const struct bcm5974_config *cfg, | 337 | const struct bcm5974_config *cfg, |
338 | const struct tp_finger *f) | 338 | const struct tp_finger *f) |
339 | { | 339 | { |
340 | input_report_abs(input, ABS_MT_TOUCH_MAJOR, raw2int(f->force_major)); | 340 | input_report_abs(input, ABS_MT_TOUCH_MAJOR, |
341 | input_report_abs(input, ABS_MT_TOUCH_MINOR, raw2int(f->force_minor)); | 341 | raw2int(f->force_major) << 1); |
342 | input_report_abs(input, ABS_MT_WIDTH_MAJOR, raw2int(f->size_major)); | 342 | input_report_abs(input, ABS_MT_TOUCH_MINOR, |
343 | input_report_abs(input, ABS_MT_WIDTH_MINOR, raw2int(f->size_minor)); | 343 | raw2int(f->force_minor) << 1); |
344 | input_report_abs(input, ABS_MT_WIDTH_MAJOR, | ||
345 | raw2int(f->size_major) << 1); | ||
346 | input_report_abs(input, ABS_MT_WIDTH_MINOR, | ||
347 | raw2int(f->size_minor) << 1); | ||
344 | input_report_abs(input, ABS_MT_ORIENTATION, | 348 | input_report_abs(input, ABS_MT_ORIENTATION, |
345 | MAX_FINGER_ORIENTATION - raw2int(f->orientation)); | 349 | MAX_FINGER_ORIENTATION - raw2int(f->orientation)); |
346 | input_report_abs(input, ABS_MT_POSITION_X, raw2int(f->abs_x)); | 350 | input_report_abs(input, ABS_MT_POSITION_X, raw2int(f->abs_x)); |
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 83c24cca234..d528a2dba06 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c | |||
@@ -138,8 +138,8 @@ static void mousedev_touchpad_event(struct input_dev *dev, | |||
138 | 138 | ||
139 | fx(0) = value; | 139 | fx(0) = value; |
140 | if (mousedev->touch && mousedev->pkt_count >= 2) { | 140 | if (mousedev->touch && mousedev->pkt_count >= 2) { |
141 | size = input_abs_get_min(dev, ABS_X) - | 141 | size = input_abs_get_max(dev, ABS_X) - |
142 | input_abs_get_max(dev, ABS_X); | 142 | input_abs_get_min(dev, ABS_X); |
143 | if (size == 0) | 143 | if (size == 0) |
144 | size = 256 * 2; | 144 | size = 256 * 2; |
145 | 145 | ||
@@ -155,8 +155,8 @@ static void mousedev_touchpad_event(struct input_dev *dev, | |||
155 | fy(0) = value; | 155 | fy(0) = value; |
156 | if (mousedev->touch && mousedev->pkt_count >= 2) { | 156 | if (mousedev->touch && mousedev->pkt_count >= 2) { |
157 | /* use X size for ABS_Y to keep the same scale */ | 157 | /* use X size for ABS_Y to keep the same scale */ |
158 | size = input_abs_get_min(dev, ABS_X) - | 158 | size = input_abs_get_max(dev, ABS_X) - |
159 | input_abs_get_max(dev, ABS_X); | 159 | input_abs_get_min(dev, ABS_X); |
160 | if (size == 0) | 160 | if (size == 0) |
161 | size = 256 * 2; | 161 | size = 256 * 2; |
162 | 162 | ||
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 46e4ba0b924..f5851316048 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
@@ -1485,8 +1485,8 @@ static int __init i8042_init(void) | |||
1485 | 1485 | ||
1486 | static void __exit i8042_exit(void) | 1486 | static void __exit i8042_exit(void) |
1487 | { | 1487 | { |
1488 | platform_driver_unregister(&i8042_driver); | ||
1489 | platform_device_unregister(i8042_platform_device); | 1488 | platform_device_unregister(i8042_platform_device); |
1489 | platform_driver_unregister(&i8042_driver); | ||
1490 | i8042_platform_exit(); | 1490 | i8042_platform_exit(); |
1491 | 1491 | ||
1492 | panic_blink = NULL; | 1492 | panic_blink = NULL; |
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index 42ba3691d90..b35876ee690 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c | |||
@@ -103,27 +103,26 @@ static void wacom_sys_irq(struct urb *urb) | |||
103 | static int wacom_open(struct input_dev *dev) | 103 | static int wacom_open(struct input_dev *dev) |
104 | { | 104 | { |
105 | struct wacom *wacom = input_get_drvdata(dev); | 105 | struct wacom *wacom = input_get_drvdata(dev); |
106 | int retval = 0; | ||
106 | 107 | ||
107 | mutex_lock(&wacom->lock); | 108 | if (usb_autopm_get_interface(wacom->intf) < 0) |
108 | |||
109 | wacom->irq->dev = wacom->usbdev; | ||
110 | |||
111 | if (usb_autopm_get_interface(wacom->intf) < 0) { | ||
112 | mutex_unlock(&wacom->lock); | ||
113 | return -EIO; | 109 | return -EIO; |
114 | } | 110 | |
111 | mutex_lock(&wacom->lock); | ||
115 | 112 | ||
116 | if (usb_submit_urb(wacom->irq, GFP_KERNEL)) { | 113 | if (usb_submit_urb(wacom->irq, GFP_KERNEL)) { |
117 | usb_autopm_put_interface(wacom->intf); | 114 | retval = -EIO; |
118 | mutex_unlock(&wacom->lock); | 115 | goto out; |
119 | return -EIO; | ||
120 | } | 116 | } |
121 | 117 | ||
122 | wacom->open = true; | 118 | wacom->open = true; |
123 | wacom->intf->needs_remote_wakeup = 1; | 119 | wacom->intf->needs_remote_wakeup = 1; |
124 | 120 | ||
121 | out: | ||
125 | mutex_unlock(&wacom->lock); | 122 | mutex_unlock(&wacom->lock); |
126 | return 0; | 123 | if (retval) |
124 | usb_autopm_put_interface(wacom->intf); | ||
125 | return retval; | ||
127 | } | 126 | } |
128 | 127 | ||
129 | static void wacom_close(struct input_dev *dev) | 128 | static void wacom_close(struct input_dev *dev) |
@@ -135,6 +134,8 @@ static void wacom_close(struct input_dev *dev) | |||
135 | wacom->open = false; | 134 | wacom->open = false; |
136 | wacom->intf->needs_remote_wakeup = 0; | 135 | wacom->intf->needs_remote_wakeup = 0; |
137 | mutex_unlock(&wacom->lock); | 136 | mutex_unlock(&wacom->lock); |
137 | |||
138 | usb_autopm_put_interface(wacom->intf); | ||
138 | } | 139 | } |
139 | 140 | ||
140 | static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, | 141 | static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, |
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 40d77ba8fdc..47fd7a041c5 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
@@ -243,10 +243,10 @@ static int wacom_graphire_irq(struct wacom_wac *wacom) | |||
243 | if (features->type == WACOM_G4 || | 243 | if (features->type == WACOM_G4 || |
244 | features->type == WACOM_MO) { | 244 | features->type == WACOM_MO) { |
245 | input_report_abs(input, ABS_DISTANCE, data[6] & 0x3f); | 245 | input_report_abs(input, ABS_DISTANCE, data[6] & 0x3f); |
246 | rw = (signed)(data[7] & 0x04) - (data[7] & 0x03); | 246 | rw = (data[7] & 0x04) - (data[7] & 0x03); |
247 | } else { | 247 | } else { |
248 | input_report_abs(input, ABS_DISTANCE, data[7] & 0x3f); | 248 | input_report_abs(input, ABS_DISTANCE, data[7] & 0x3f); |
249 | rw = -(signed)data[6]; | 249 | rw = -(signed char)data[6]; |
250 | } | 250 | } |
251 | input_report_rel(input, REL_WHEEL, rw); | 251 | input_report_rel(input, REL_WHEEL, rw); |
252 | } | 252 | } |
@@ -442,8 +442,10 @@ static void wacom_intuos_general(struct wacom_wac *wacom) | |||
442 | /* general pen packet */ | 442 | /* general pen packet */ |
443 | if ((data[1] & 0xb8) == 0xa0) { | 443 | if ((data[1] & 0xb8) == 0xa0) { |
444 | t = (data[6] << 2) | ((data[7] >> 6) & 3); | 444 | t = (data[6] << 2) | ((data[7] >> 6) & 3); |
445 | if (features->type >= INTUOS4S && features->type <= INTUOS4L) | 445 | if ((features->type >= INTUOS4S && features->type <= INTUOS4L) || |
446 | features->type == WACOM_21UX2) { | ||
446 | t = (t << 1) | (data[1] & 1); | 447 | t = (t << 1) | (data[1] & 1); |
448 | } | ||
447 | input_report_abs(input, ABS_PRESSURE, t); | 449 | input_report_abs(input, ABS_PRESSURE, t); |
448 | input_report_abs(input, ABS_TILT_X, | 450 | input_report_abs(input, ABS_TILT_X, |
449 | ((data[7] << 1) & 0x7e) | (data[8] >> 7)); | 451 | ((data[7] << 1) & 0x7e) | (data[8] >> 7)); |
diff --git a/drivers/isdn/hardware/avm/Kconfig b/drivers/isdn/hardware/avm/Kconfig index 5dbcbe3a54a..b99b906ea9b 100644 --- a/drivers/isdn/hardware/avm/Kconfig +++ b/drivers/isdn/hardware/avm/Kconfig | |||
@@ -36,12 +36,13 @@ config ISDN_DRV_AVMB1_T1ISA | |||
36 | 36 | ||
37 | config ISDN_DRV_AVMB1_B1PCMCIA | 37 | config ISDN_DRV_AVMB1_B1PCMCIA |
38 | tristate "AVM B1/M1/M2 PCMCIA support" | 38 | tristate "AVM B1/M1/M2 PCMCIA support" |
39 | depends on PCMCIA | ||
39 | help | 40 | help |
40 | Enable support for the PCMCIA version of the AVM B1 card. | 41 | Enable support for the PCMCIA version of the AVM B1 card. |
41 | 42 | ||
42 | config ISDN_DRV_AVMB1_AVM_CS | 43 | config ISDN_DRV_AVMB1_AVM_CS |
43 | tristate "AVM B1/M1/M2 PCMCIA cs module" | 44 | tristate "AVM B1/M1/M2 PCMCIA cs module" |
44 | depends on ISDN_DRV_AVMB1_B1PCMCIA && PCMCIA | 45 | depends on ISDN_DRV_AVMB1_B1PCMCIA |
45 | help | 46 | help |
46 | Enable the PCMCIA client driver for the AVM B1/M1/M2 | 47 | Enable the PCMCIA client driver for the AVM B1/M1/M2 |
47 | PCMCIA cards. | 48 | PCMCIA cards. |
diff --git a/drivers/isdn/sc/interrupt.c b/drivers/isdn/sc/interrupt.c index 485be8b1e1b..f0225bc0f26 100644 --- a/drivers/isdn/sc/interrupt.c +++ b/drivers/isdn/sc/interrupt.c | |||
@@ -112,11 +112,19 @@ irqreturn_t interrupt_handler(int dummy, void *card_inst) | |||
112 | } | 112 | } |
113 | else if(callid>=0x0000 && callid<=0x7FFF) | 113 | else if(callid>=0x0000 && callid<=0x7FFF) |
114 | { | 114 | { |
115 | int len; | ||
116 | |||
115 | pr_debug("%s: Got Incoming Call\n", | 117 | pr_debug("%s: Got Incoming Call\n", |
116 | sc_adapter[card]->devicename); | 118 | sc_adapter[card]->devicename); |
117 | strcpy(setup.phone,&(rcvmsg.msg_data.byte_array[4])); | 119 | len = strlcpy(setup.phone, &(rcvmsg.msg_data.byte_array[4]), |
118 | strcpy(setup.eazmsn, | 120 | sizeof(setup.phone)); |
119 | sc_adapter[card]->channel[rcvmsg.phy_link_no-1].dn); | 121 | if (len >= sizeof(setup.phone)) |
122 | continue; | ||
123 | len = strlcpy(setup.eazmsn, | ||
124 | sc_adapter[card]->channel[rcvmsg.phy_link_no - 1].dn, | ||
125 | sizeof(setup.eazmsn)); | ||
126 | if (len >= sizeof(setup.eazmsn)) | ||
127 | continue; | ||
120 | setup.si1 = 7; | 128 | setup.si1 = 7; |
121 | setup.si2 = 0; | 129 | setup.si2 = 0; |
122 | setup.plan = 0; | 130 | setup.plan = 0; |
@@ -176,7 +184,9 @@ irqreturn_t interrupt_handler(int dummy, void *card_inst) | |||
176 | * Handle a GetMyNumber Rsp | 184 | * Handle a GetMyNumber Rsp |
177 | */ | 185 | */ |
178 | if (IS_CE_MESSAGE(rcvmsg,Call,0,GetMyNumber)){ | 186 | if (IS_CE_MESSAGE(rcvmsg,Call,0,GetMyNumber)){ |
179 | strcpy(sc_adapter[card]->channel[rcvmsg.phy_link_no-1].dn,rcvmsg.msg_data.byte_array); | 187 | strlcpy(sc_adapter[card]->channel[rcvmsg.phy_link_no - 1].dn, |
188 | rcvmsg.msg_data.byte_array, | ||
189 | sizeof(rcvmsg.msg_data.byte_array)); | ||
180 | continue; | 190 | continue; |
181 | } | 191 | } |
182 | 192 | ||
diff --git a/drivers/leds/leds-ns2.c b/drivers/leds/leds-ns2.c index 74dce4ba026..350eb34f049 100644 --- a/drivers/leds/leds-ns2.c +++ b/drivers/leds/leds-ns2.c | |||
@@ -81,7 +81,7 @@ static int ns2_led_get_mode(struct ns2_led_data *led_dat, | |||
81 | int cmd_level; | 81 | int cmd_level; |
82 | int slow_level; | 82 | int slow_level; |
83 | 83 | ||
84 | read_lock(&led_dat->rw_lock); | 84 | read_lock_irq(&led_dat->rw_lock); |
85 | 85 | ||
86 | cmd_level = gpio_get_value(led_dat->cmd); | 86 | cmd_level = gpio_get_value(led_dat->cmd); |
87 | slow_level = gpio_get_value(led_dat->slow); | 87 | slow_level = gpio_get_value(led_dat->slow); |
@@ -95,7 +95,7 @@ static int ns2_led_get_mode(struct ns2_led_data *led_dat, | |||
95 | } | 95 | } |
96 | } | 96 | } |
97 | 97 | ||
98 | read_unlock(&led_dat->rw_lock); | 98 | read_unlock_irq(&led_dat->rw_lock); |
99 | 99 | ||
100 | return ret; | 100 | return ret; |
101 | } | 101 | } |
@@ -104,8 +104,9 @@ static void ns2_led_set_mode(struct ns2_led_data *led_dat, | |||
104 | enum ns2_led_modes mode) | 104 | enum ns2_led_modes mode) |
105 | { | 105 | { |
106 | int i; | 106 | int i; |
107 | unsigned long flags; | ||
107 | 108 | ||
108 | write_lock(&led_dat->rw_lock); | 109 | write_lock_irqsave(&led_dat->rw_lock, flags); |
109 | 110 | ||
110 | for (i = 0; i < ARRAY_SIZE(ns2_led_modval); i++) { | 111 | for (i = 0; i < ARRAY_SIZE(ns2_led_modval); i++) { |
111 | if (mode == ns2_led_modval[i].mode) { | 112 | if (mode == ns2_led_modval[i].mode) { |
@@ -116,7 +117,7 @@ static void ns2_led_set_mode(struct ns2_led_data *led_dat, | |||
116 | } | 117 | } |
117 | } | 118 | } |
118 | 119 | ||
119 | write_unlock(&led_dat->rw_lock); | 120 | write_unlock_irqrestore(&led_dat->rw_lock, flags); |
120 | } | 121 | } |
121 | 122 | ||
122 | static void ns2_led_set(struct led_classdev *led_cdev, | 123 | static void ns2_led_set(struct led_classdev *led_cdev, |
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index 35bc2737412..2d17e76066b 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <linux/syscalls.h> | 45 | #include <linux/syscalls.h> |
46 | #include <linux/suspend.h> | 46 | #include <linux/suspend.h> |
47 | #include <linux/cpu.h> | 47 | #include <linux/cpu.h> |
48 | #include <linux/compat.h> | ||
48 | #include <asm/prom.h> | 49 | #include <asm/prom.h> |
49 | #include <asm/machdep.h> | 50 | #include <asm/machdep.h> |
50 | #include <asm/io.h> | 51 | #include <asm/io.h> |
@@ -2349,11 +2350,52 @@ static long pmu_unlocked_ioctl(struct file *filp, | |||
2349 | return ret; | 2350 | return ret; |
2350 | } | 2351 | } |
2351 | 2352 | ||
2353 | #ifdef CONFIG_COMPAT | ||
2354 | #define PMU_IOC_GET_BACKLIGHT32 _IOR('B', 1, compat_size_t) | ||
2355 | #define PMU_IOC_SET_BACKLIGHT32 _IOW('B', 2, compat_size_t) | ||
2356 | #define PMU_IOC_GET_MODEL32 _IOR('B', 3, compat_size_t) | ||
2357 | #define PMU_IOC_HAS_ADB32 _IOR('B', 4, compat_size_t) | ||
2358 | #define PMU_IOC_CAN_SLEEP32 _IOR('B', 5, compat_size_t) | ||
2359 | #define PMU_IOC_GRAB_BACKLIGHT32 _IOR('B', 6, compat_size_t) | ||
2360 | |||
2361 | static long compat_pmu_ioctl (struct file *filp, u_int cmd, u_long arg) | ||
2362 | { | ||
2363 | switch (cmd) { | ||
2364 | case PMU_IOC_SLEEP: | ||
2365 | break; | ||
2366 | case PMU_IOC_GET_BACKLIGHT32: | ||
2367 | cmd = PMU_IOC_GET_BACKLIGHT; | ||
2368 | break; | ||
2369 | case PMU_IOC_SET_BACKLIGHT32: | ||
2370 | cmd = PMU_IOC_SET_BACKLIGHT; | ||
2371 | break; | ||
2372 | case PMU_IOC_GET_MODEL32: | ||
2373 | cmd = PMU_IOC_GET_MODEL; | ||
2374 | break; | ||
2375 | case PMU_IOC_HAS_ADB32: | ||
2376 | cmd = PMU_IOC_HAS_ADB; | ||
2377 | break; | ||
2378 | case PMU_IOC_CAN_SLEEP32: | ||
2379 | cmd = PMU_IOC_CAN_SLEEP; | ||
2380 | break; | ||
2381 | case PMU_IOC_GRAB_BACKLIGHT32: | ||
2382 | cmd = PMU_IOC_GRAB_BACKLIGHT; | ||
2383 | break; | ||
2384 | default: | ||
2385 | return -ENOIOCTLCMD; | ||
2386 | } | ||
2387 | return pmu_unlocked_ioctl(filp, cmd, (unsigned long)compat_ptr(arg)); | ||
2388 | } | ||
2389 | #endif | ||
2390 | |||
2352 | static const struct file_operations pmu_device_fops = { | 2391 | static const struct file_operations pmu_device_fops = { |
2353 | .read = pmu_read, | 2392 | .read = pmu_read, |
2354 | .write = pmu_write, | 2393 | .write = pmu_write, |
2355 | .poll = pmu_fpoll, | 2394 | .poll = pmu_fpoll, |
2356 | .unlocked_ioctl = pmu_unlocked_ioctl, | 2395 | .unlocked_ioctl = pmu_unlocked_ioctl, |
2396 | #ifdef CONFIG_COMPAT | ||
2397 | .compat_ioctl = compat_pmu_ioctl, | ||
2398 | #endif | ||
2357 | .open = pmu_open, | 2399 | .open = pmu_open, |
2358 | .release = pmu_release, | 2400 | .release = pmu_release, |
2359 | }; | 2401 | }; |
diff --git a/drivers/md/.gitignore b/drivers/md/.gitignore deleted file mode 100644 index a7afec6b19c..00000000000 --- a/drivers/md/.gitignore +++ /dev/null | |||
@@ -1,4 +0,0 @@ | |||
1 | mktables | ||
2 | raid6altivec*.c | ||
3 | raid6int*.c | ||
4 | raid6tables.c | ||
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 1ba1e122e94..e4fb58db545 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -1000,10 +1000,11 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start) | |||
1000 | page = bitmap->sb_page; | 1000 | page = bitmap->sb_page; |
1001 | offset = sizeof(bitmap_super_t); | 1001 | offset = sizeof(bitmap_super_t); |
1002 | if (!file) | 1002 | if (!file) |
1003 | read_sb_page(bitmap->mddev, | 1003 | page = read_sb_page( |
1004 | bitmap->mddev->bitmap_info.offset, | 1004 | bitmap->mddev, |
1005 | page, | 1005 | bitmap->mddev->bitmap_info.offset, |
1006 | index, count); | 1006 | page, |
1007 | index, count); | ||
1007 | } else if (file) { | 1008 | } else if (file) { |
1008 | page = read_page(file, index, bitmap, count); | 1009 | page = read_page(file, index, bitmap, count); |
1009 | offset = 0; | 1010 | offset = 0; |
@@ -1542,8 +1543,7 @@ void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector) | |||
1542 | atomic_read(&bitmap->mddev->recovery_active) == 0); | 1543 | atomic_read(&bitmap->mddev->recovery_active) == 0); |
1543 | 1544 | ||
1544 | bitmap->mddev->curr_resync_completed = bitmap->mddev->curr_resync; | 1545 | bitmap->mddev->curr_resync_completed = bitmap->mddev->curr_resync; |
1545 | if (bitmap->mddev->persistent) | 1546 | set_bit(MD_CHANGE_CLEAN, &bitmap->mddev->flags); |
1546 | set_bit(MD_CHANGE_CLEAN, &bitmap->mddev->flags); | ||
1547 | sector &= ~((1ULL << CHUNK_BLOCK_SHIFT(bitmap)) - 1); | 1547 | sector &= ~((1ULL << CHUNK_BLOCK_SHIFT(bitmap)) - 1); |
1548 | s = 0; | 1548 | s = 0; |
1549 | while (s < sector && s < bitmap->mddev->resync_max_sectors) { | 1549 | while (s < sector && s < bitmap->mddev->resync_max_sectors) { |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 3640f025cb7..ed075d19db3 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -1578,7 +1578,9 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1578 | bmask = queue_logical_block_size(rdev->bdev->bd_disk->queue)-1; | 1578 | bmask = queue_logical_block_size(rdev->bdev->bd_disk->queue)-1; |
1579 | if (rdev->sb_size & bmask) | 1579 | if (rdev->sb_size & bmask) |
1580 | rdev->sb_size = (rdev->sb_size | bmask) + 1; | 1580 | rdev->sb_size = (rdev->sb_size | bmask) + 1; |
1581 | } | 1581 | } else |
1582 | max_dev = le32_to_cpu(sb->max_dev); | ||
1583 | |||
1582 | for (i=0; i<max_dev;i++) | 1584 | for (i=0; i<max_dev;i++) |
1583 | sb->dev_roles[i] = cpu_to_le16(0xfffe); | 1585 | sb->dev_roles[i] = cpu_to_le16(0xfffe); |
1584 | 1586 | ||
@@ -2102,9 +2104,9 @@ repeat: | |||
2102 | rdev->recovery_offset = mddev->curr_resync_completed; | 2104 | rdev->recovery_offset = mddev->curr_resync_completed; |
2103 | 2105 | ||
2104 | } | 2106 | } |
2105 | if (mddev->external || !mddev->persistent) { | 2107 | if (!mddev->persistent) { |
2106 | clear_bit(MD_CHANGE_DEVS, &mddev->flags); | ||
2107 | clear_bit(MD_CHANGE_CLEAN, &mddev->flags); | 2108 | clear_bit(MD_CHANGE_CLEAN, &mddev->flags); |
2109 | clear_bit(MD_CHANGE_DEVS, &mddev->flags); | ||
2108 | wake_up(&mddev->sb_wait); | 2110 | wake_up(&mddev->sb_wait); |
2109 | return; | 2111 | return; |
2110 | } | 2112 | } |
@@ -2113,7 +2115,6 @@ repeat: | |||
2113 | 2115 | ||
2114 | mddev->utime = get_seconds(); | 2116 | mddev->utime = get_seconds(); |
2115 | 2117 | ||
2116 | set_bit(MD_CHANGE_PENDING, &mddev->flags); | ||
2117 | if (test_and_clear_bit(MD_CHANGE_DEVS, &mddev->flags)) | 2118 | if (test_and_clear_bit(MD_CHANGE_DEVS, &mddev->flags)) |
2118 | force_change = 1; | 2119 | force_change = 1; |
2119 | if (test_and_clear_bit(MD_CHANGE_CLEAN, &mddev->flags)) | 2120 | if (test_and_clear_bit(MD_CHANGE_CLEAN, &mddev->flags)) |
@@ -3306,7 +3307,7 @@ array_state_show(mddev_t *mddev, char *page) | |||
3306 | case 0: | 3307 | case 0: |
3307 | if (mddev->in_sync) | 3308 | if (mddev->in_sync) |
3308 | st = clean; | 3309 | st = clean; |
3309 | else if (test_bit(MD_CHANGE_CLEAN, &mddev->flags)) | 3310 | else if (test_bit(MD_CHANGE_PENDING, &mddev->flags)) |
3310 | st = write_pending; | 3311 | st = write_pending; |
3311 | else if (mddev->safemode) | 3312 | else if (mddev->safemode) |
3312 | st = active_idle; | 3313 | st = active_idle; |
@@ -3387,9 +3388,7 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len) | |||
3387 | mddev->in_sync = 1; | 3388 | mddev->in_sync = 1; |
3388 | if (mddev->safemode == 1) | 3389 | if (mddev->safemode == 1) |
3389 | mddev->safemode = 0; | 3390 | mddev->safemode = 0; |
3390 | if (mddev->persistent) | 3391 | set_bit(MD_CHANGE_CLEAN, &mddev->flags); |
3391 | set_bit(MD_CHANGE_CLEAN, | ||
3392 | &mddev->flags); | ||
3393 | } | 3392 | } |
3394 | err = 0; | 3393 | err = 0; |
3395 | } else | 3394 | } else |
@@ -3401,8 +3400,7 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len) | |||
3401 | case active: | 3400 | case active: |
3402 | if (mddev->pers) { | 3401 | if (mddev->pers) { |
3403 | restart_array(mddev); | 3402 | restart_array(mddev); |
3404 | if (mddev->external) | 3403 | clear_bit(MD_CHANGE_PENDING, &mddev->flags); |
3405 | clear_bit(MD_CHANGE_CLEAN, &mddev->flags); | ||
3406 | wake_up(&mddev->sb_wait); | 3404 | wake_up(&mddev->sb_wait); |
3407 | err = 0; | 3405 | err = 0; |
3408 | } else { | 3406 | } else { |
@@ -6505,6 +6503,7 @@ void md_write_start(mddev_t *mddev, struct bio *bi) | |||
6505 | if (mddev->in_sync) { | 6503 | if (mddev->in_sync) { |
6506 | mddev->in_sync = 0; | 6504 | mddev->in_sync = 0; |
6507 | set_bit(MD_CHANGE_CLEAN, &mddev->flags); | 6505 | set_bit(MD_CHANGE_CLEAN, &mddev->flags); |
6506 | set_bit(MD_CHANGE_PENDING, &mddev->flags); | ||
6508 | md_wakeup_thread(mddev->thread); | 6507 | md_wakeup_thread(mddev->thread); |
6509 | did_change = 1; | 6508 | did_change = 1; |
6510 | } | 6509 | } |
@@ -6513,7 +6512,6 @@ void md_write_start(mddev_t *mddev, struct bio *bi) | |||
6513 | if (did_change) | 6512 | if (did_change) |
6514 | sysfs_notify_dirent_safe(mddev->sysfs_state); | 6513 | sysfs_notify_dirent_safe(mddev->sysfs_state); |
6515 | wait_event(mddev->sb_wait, | 6514 | wait_event(mddev->sb_wait, |
6516 | !test_bit(MD_CHANGE_CLEAN, &mddev->flags) && | ||
6517 | !test_bit(MD_CHANGE_PENDING, &mddev->flags)); | 6515 | !test_bit(MD_CHANGE_PENDING, &mddev->flags)); |
6518 | } | 6516 | } |
6519 | 6517 | ||
@@ -6549,6 +6547,7 @@ int md_allow_write(mddev_t *mddev) | |||
6549 | if (mddev->in_sync) { | 6547 | if (mddev->in_sync) { |
6550 | mddev->in_sync = 0; | 6548 | mddev->in_sync = 0; |
6551 | set_bit(MD_CHANGE_CLEAN, &mddev->flags); | 6549 | set_bit(MD_CHANGE_CLEAN, &mddev->flags); |
6550 | set_bit(MD_CHANGE_PENDING, &mddev->flags); | ||
6552 | if (mddev->safemode_delay && | 6551 | if (mddev->safemode_delay && |
6553 | mddev->safemode == 0) | 6552 | mddev->safemode == 0) |
6554 | mddev->safemode = 1; | 6553 | mddev->safemode = 1; |
@@ -6558,7 +6557,7 @@ int md_allow_write(mddev_t *mddev) | |||
6558 | } else | 6557 | } else |
6559 | spin_unlock_irq(&mddev->write_lock); | 6558 | spin_unlock_irq(&mddev->write_lock); |
6560 | 6559 | ||
6561 | if (test_bit(MD_CHANGE_CLEAN, &mddev->flags)) | 6560 | if (test_bit(MD_CHANGE_PENDING, &mddev->flags)) |
6562 | return -EAGAIN; | 6561 | return -EAGAIN; |
6563 | else | 6562 | else |
6564 | return 0; | 6563 | return 0; |
@@ -6756,8 +6755,7 @@ void md_do_sync(mddev_t *mddev) | |||
6756 | atomic_read(&mddev->recovery_active) == 0); | 6755 | atomic_read(&mddev->recovery_active) == 0); |
6757 | mddev->curr_resync_completed = | 6756 | mddev->curr_resync_completed = |
6758 | mddev->curr_resync; | 6757 | mddev->curr_resync; |
6759 | if (mddev->persistent) | 6758 | set_bit(MD_CHANGE_CLEAN, &mddev->flags); |
6760 | set_bit(MD_CHANGE_CLEAN, &mddev->flags); | ||
6761 | sysfs_notify(&mddev->kobj, NULL, "sync_completed"); | 6759 | sysfs_notify(&mddev->kobj, NULL, "sync_completed"); |
6762 | } | 6760 | } |
6763 | 6761 | ||
@@ -7006,7 +7004,7 @@ void md_check_recovery(mddev_t *mddev) | |||
7006 | if (mddev->ro && !test_bit(MD_RECOVERY_NEEDED, &mddev->recovery)) | 7004 | if (mddev->ro && !test_bit(MD_RECOVERY_NEEDED, &mddev->recovery)) |
7007 | return; | 7005 | return; |
7008 | if ( ! ( | 7006 | if ( ! ( |
7009 | (mddev->flags && !mddev->external) || | 7007 | (mddev->flags & ~ (1<<MD_CHANGE_PENDING)) || |
7010 | test_bit(MD_RECOVERY_NEEDED, &mddev->recovery) || | 7008 | test_bit(MD_RECOVERY_NEEDED, &mddev->recovery) || |
7011 | test_bit(MD_RECOVERY_DONE, &mddev->recovery) || | 7009 | test_bit(MD_RECOVERY_DONE, &mddev->recovery) || |
7012 | (mddev->external == 0 && mddev->safemode == 1) || | 7010 | (mddev->external == 0 && mddev->safemode == 1) || |
@@ -7036,8 +7034,7 @@ void md_check_recovery(mddev_t *mddev) | |||
7036 | mddev->recovery_cp == MaxSector) { | 7034 | mddev->recovery_cp == MaxSector) { |
7037 | mddev->in_sync = 1; | 7035 | mddev->in_sync = 1; |
7038 | did_change = 1; | 7036 | did_change = 1; |
7039 | if (mddev->persistent) | 7037 | set_bit(MD_CHANGE_CLEAN, &mddev->flags); |
7040 | set_bit(MD_CHANGE_CLEAN, &mddev->flags); | ||
7041 | } | 7038 | } |
7042 | if (mddev->safemode == 1) | 7039 | if (mddev->safemode == 1) |
7043 | mddev->safemode = 0; | 7040 | mddev->safemode = 0; |
diff --git a/drivers/md/md.h b/drivers/md/md.h index d8e2ab25103..112a2c32db0 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h | |||
@@ -139,7 +139,7 @@ struct mddev_s | |||
139 | unsigned long flags; | 139 | unsigned long flags; |
140 | #define MD_CHANGE_DEVS 0 /* Some device status has changed */ | 140 | #define MD_CHANGE_DEVS 0 /* Some device status has changed */ |
141 | #define MD_CHANGE_CLEAN 1 /* transition to or from 'clean' */ | 141 | #define MD_CHANGE_CLEAN 1 /* transition to or from 'clean' */ |
142 | #define MD_CHANGE_PENDING 2 /* superblock update in progress */ | 142 | #define MD_CHANGE_PENDING 2 /* switch from 'clean' to 'active' in progress */ |
143 | 143 | ||
144 | int suspended; | 144 | int suspended; |
145 | atomic_t active_io; | 145 | atomic_t active_io; |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 886a9d86548..378a25894c5 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -1781,7 +1781,9 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
1781 | 1781 | ||
1782 | /* take from bio_init */ | 1782 | /* take from bio_init */ |
1783 | bio->bi_next = NULL; | 1783 | bio->bi_next = NULL; |
1784 | bio->bi_flags &= ~(BIO_POOL_MASK-1); | ||
1784 | bio->bi_flags |= 1 << BIO_UPTODATE; | 1785 | bio->bi_flags |= 1 << BIO_UPTODATE; |
1786 | bio->bi_comp_cpu = -1; | ||
1785 | bio->bi_rw = READ; | 1787 | bio->bi_rw = READ; |
1786 | bio->bi_vcnt = 0; | 1788 | bio->bi_vcnt = 0; |
1787 | bio->bi_idx = 0; | 1789 | bio->bi_idx = 0; |
@@ -1854,7 +1856,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
1854 | !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) | 1856 | !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) |
1855 | break; | 1857 | break; |
1856 | BUG_ON(sync_blocks < (PAGE_SIZE>>9)); | 1858 | BUG_ON(sync_blocks < (PAGE_SIZE>>9)); |
1857 | if (len > (sync_blocks<<9)) | 1859 | if ((len >> 9) > sync_blocks) |
1858 | len = sync_blocks<<9; | 1860 | len = sync_blocks<<9; |
1859 | } | 1861 | } |
1860 | 1862 | ||
diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c index 7e82a9df726..7961d59f5ca 100644 --- a/drivers/media/IR/ir-keytable.c +++ b/drivers/media/IR/ir-keytable.c | |||
@@ -319,7 +319,7 @@ static void ir_timer_keyup(unsigned long cookie) | |||
319 | * a keyup event might follow immediately after the keydown. | 319 | * a keyup event might follow immediately after the keydown. |
320 | */ | 320 | */ |
321 | spin_lock_irqsave(&ir->keylock, flags); | 321 | spin_lock_irqsave(&ir->keylock, flags); |
322 | if (time_is_after_eq_jiffies(ir->keyup_jiffies)) | 322 | if (time_is_before_eq_jiffies(ir->keyup_jiffies)) |
323 | ir_keyup(ir); | 323 | ir_keyup(ir); |
324 | spin_unlock_irqrestore(&ir->keylock, flags); | 324 | spin_unlock_irqrestore(&ir->keylock, flags); |
325 | } | 325 | } |
@@ -510,6 +510,13 @@ int __ir_input_register(struct input_dev *input_dev, | |||
510 | (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_IR_RAW) ? | 510 | (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_IR_RAW) ? |
511 | " in raw mode" : ""); | 511 | " in raw mode" : ""); |
512 | 512 | ||
513 | /* | ||
514 | * Default delay of 250ms is too short for some protocols, expecially | ||
515 | * since the timeout is currently set to 250ms. Increase it to 500ms, | ||
516 | * to avoid wrong repetition of the keycodes. | ||
517 | */ | ||
518 | input_dev->rep[REP_DELAY] = 500; | ||
519 | |||
513 | return 0; | 520 | return 0; |
514 | 521 | ||
515 | out_event: | 522 | out_event: |
diff --git a/drivers/media/IR/ir-lirc-codec.c b/drivers/media/IR/ir-lirc-codec.c index 77b5946413c..e63f757d5d7 100644 --- a/drivers/media/IR/ir-lirc-codec.c +++ b/drivers/media/IR/ir-lirc-codec.c | |||
@@ -267,7 +267,7 @@ static int ir_lirc_register(struct input_dev *input_dev) | |||
267 | features |= LIRC_CAN_SET_SEND_CARRIER; | 267 | features |= LIRC_CAN_SET_SEND_CARRIER; |
268 | 268 | ||
269 | if (ir_dev->props->s_tx_duty_cycle) | 269 | if (ir_dev->props->s_tx_duty_cycle) |
270 | features |= LIRC_CAN_SET_REC_DUTY_CYCLE; | 270 | features |= LIRC_CAN_SET_SEND_DUTY_CYCLE; |
271 | } | 271 | } |
272 | 272 | ||
273 | if (ir_dev->props->s_rx_carrier_range) | 273 | if (ir_dev->props->s_rx_carrier_range) |
diff --git a/drivers/media/IR/ir-raw-event.c b/drivers/media/IR/ir-raw-event.c index 43094e7eccf..8e0e1b1f8c8 100644 --- a/drivers/media/IR/ir-raw-event.c +++ b/drivers/media/IR/ir-raw-event.c | |||
@@ -279,9 +279,11 @@ int ir_raw_event_register(struct input_dev *input_dev) | |||
279 | "rc%u", (unsigned int)ir->devno); | 279 | "rc%u", (unsigned int)ir->devno); |
280 | 280 | ||
281 | if (IS_ERR(ir->raw->thread)) { | 281 | if (IS_ERR(ir->raw->thread)) { |
282 | int ret = PTR_ERR(ir->raw->thread); | ||
283 | |||
282 | kfree(ir->raw); | 284 | kfree(ir->raw); |
283 | ir->raw = NULL; | 285 | ir->raw = NULL; |
284 | return PTR_ERR(ir->raw->thread); | 286 | return ret; |
285 | } | 287 | } |
286 | 288 | ||
287 | mutex_lock(&ir_raw_handler_lock); | 289 | mutex_lock(&ir_raw_handler_lock); |
diff --git a/drivers/media/IR/ir-sysfs.c b/drivers/media/IR/ir-sysfs.c index 96dafc425c8..46d42467f9b 100644 --- a/drivers/media/IR/ir-sysfs.c +++ b/drivers/media/IR/ir-sysfs.c | |||
@@ -67,13 +67,14 @@ static ssize_t show_protocols(struct device *d, | |||
67 | char *tmp = buf; | 67 | char *tmp = buf; |
68 | int i; | 68 | int i; |
69 | 69 | ||
70 | if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) { | 70 | if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) { |
71 | enabled = ir_dev->rc_tab.ir_type; | 71 | enabled = ir_dev->rc_tab.ir_type; |
72 | allowed = ir_dev->props->allowed_protos; | 72 | allowed = ir_dev->props->allowed_protos; |
73 | } else { | 73 | } else if (ir_dev->raw) { |
74 | enabled = ir_dev->raw->enabled_protocols; | 74 | enabled = ir_dev->raw->enabled_protocols; |
75 | allowed = ir_raw_get_allowed_protocols(); | 75 | allowed = ir_raw_get_allowed_protocols(); |
76 | } | 76 | } else |
77 | return sprintf(tmp, "[builtin]\n"); | ||
77 | 78 | ||
78 | IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n", | 79 | IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n", |
79 | (long long)allowed, | 80 | (long long)allowed, |
@@ -121,10 +122,14 @@ static ssize_t store_protocols(struct device *d, | |||
121 | int rc, i, count = 0; | 122 | int rc, i, count = 0; |
122 | unsigned long flags; | 123 | unsigned long flags; |
123 | 124 | ||
124 | if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) | 125 | if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) |
125 | type = ir_dev->rc_tab.ir_type; | 126 | type = ir_dev->rc_tab.ir_type; |
126 | else | 127 | else if (ir_dev->raw) |
127 | type = ir_dev->raw->enabled_protocols; | 128 | type = ir_dev->raw->enabled_protocols; |
129 | else { | ||
130 | IR_dprintk(1, "Protocol switching not supported\n"); | ||
131 | return -EINVAL; | ||
132 | } | ||
128 | 133 | ||
129 | while ((tmp = strsep((char **) &data, " \n")) != NULL) { | 134 | while ((tmp = strsep((char **) &data, " \n")) != NULL) { |
130 | if (!*tmp) | 135 | if (!*tmp) |
@@ -185,7 +190,7 @@ static ssize_t store_protocols(struct device *d, | |||
185 | } | 190 | } |
186 | } | 191 | } |
187 | 192 | ||
188 | if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) { | 193 | if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) { |
189 | spin_lock_irqsave(&ir_dev->rc_tab.lock, flags); | 194 | spin_lock_irqsave(&ir_dev->rc_tab.lock, flags); |
190 | ir_dev->rc_tab.ir_type = type; | 195 | ir_dev->rc_tab.ir_type = type; |
191 | spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags); | 196 | spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags); |
diff --git a/drivers/media/IR/keymaps/rc-rc6-mce.c b/drivers/media/IR/keymaps/rc-rc6-mce.c index 64264f7f838..39557ad401b 100644 --- a/drivers/media/IR/keymaps/rc-rc6-mce.c +++ b/drivers/media/IR/keymaps/rc-rc6-mce.c | |||
@@ -19,6 +19,7 @@ static struct ir_scancode rc6_mce[] = { | |||
19 | 19 | ||
20 | { 0x800f0416, KEY_PLAY }, | 20 | { 0x800f0416, KEY_PLAY }, |
21 | { 0x800f0418, KEY_PAUSE }, | 21 | { 0x800f0418, KEY_PAUSE }, |
22 | { 0x800f046e, KEY_PLAYPAUSE }, | ||
22 | { 0x800f0419, KEY_STOP }, | 23 | { 0x800f0419, KEY_STOP }, |
23 | { 0x800f0417, KEY_RECORD }, | 24 | { 0x800f0417, KEY_RECORD }, |
24 | 25 | ||
@@ -37,6 +38,8 @@ static struct ir_scancode rc6_mce[] = { | |||
37 | { 0x800f0411, KEY_VOLUMEDOWN }, | 38 | { 0x800f0411, KEY_VOLUMEDOWN }, |
38 | { 0x800f0412, KEY_CHANNELUP }, | 39 | { 0x800f0412, KEY_CHANNELUP }, |
39 | { 0x800f0413, KEY_CHANNELDOWN }, | 40 | { 0x800f0413, KEY_CHANNELDOWN }, |
41 | { 0x800f043a, KEY_BRIGHTNESSUP }, | ||
42 | { 0x800f0480, KEY_BRIGHTNESSDOWN }, | ||
40 | 43 | ||
41 | { 0x800f0401, KEY_NUMERIC_1 }, | 44 | { 0x800f0401, KEY_NUMERIC_1 }, |
42 | { 0x800f0402, KEY_NUMERIC_2 }, | 45 | { 0x800f0402, KEY_NUMERIC_2 }, |
diff --git a/drivers/media/IR/mceusb.c b/drivers/media/IR/mceusb.c index ac6bb2c01a4..bc620e10ef7 100644 --- a/drivers/media/IR/mceusb.c +++ b/drivers/media/IR/mceusb.c | |||
@@ -120,6 +120,10 @@ static struct usb_device_id mceusb_dev_table[] = { | |||
120 | { USB_DEVICE(VENDOR_PHILIPS, 0x0613) }, | 120 | { USB_DEVICE(VENDOR_PHILIPS, 0x0613) }, |
121 | /* Philips eHome Infrared Transceiver */ | 121 | /* Philips eHome Infrared Transceiver */ |
122 | { USB_DEVICE(VENDOR_PHILIPS, 0x0815) }, | 122 | { USB_DEVICE(VENDOR_PHILIPS, 0x0815) }, |
123 | /* Philips/Spinel plus IR transceiver for ASUS */ | ||
124 | { USB_DEVICE(VENDOR_PHILIPS, 0x206c) }, | ||
125 | /* Philips/Spinel plus IR transceiver for ASUS */ | ||
126 | { USB_DEVICE(VENDOR_PHILIPS, 0x2088) }, | ||
123 | /* Realtek MCE IR Receiver */ | 127 | /* Realtek MCE IR Receiver */ |
124 | { USB_DEVICE(VENDOR_REALTEK, 0x0161) }, | 128 | { USB_DEVICE(VENDOR_REALTEK, 0x0161) }, |
125 | /* SMK/Toshiba G83C0004D410 */ | 129 | /* SMK/Toshiba G83C0004D410 */ |
diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c index fe818348b8a..48397f103d3 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_core.c +++ b/drivers/media/dvb/dvb-usb/dib0700_core.c | |||
@@ -673,9 +673,6 @@ static int dib0700_probe(struct usb_interface *intf, | |||
673 | else | 673 | else |
674 | dev->props.rc.core.bulk_mode = false; | 674 | dev->props.rc.core.bulk_mode = false; |
675 | 675 | ||
676 | /* Need a higher delay, to avoid wrong repeat */ | ||
677 | dev->rc_input_dev->rep[REP_DELAY] = 500; | ||
678 | |||
679 | dib0700_rc_setup(dev); | 676 | dib0700_rc_setup(dev); |
680 | 677 | ||
681 | return 0; | 678 | return 0; |
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index f634d2e784b..e06acd1fecb 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c | |||
@@ -940,6 +940,58 @@ static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap) | |||
940 | return adap->fe == NULL ? -ENODEV : 0; | 940 | return adap->fe == NULL ? -ENODEV : 0; |
941 | } | 941 | } |
942 | 942 | ||
943 | /* STK7770P */ | ||
944 | static struct dib7000p_config dib7770p_dib7000p_config = { | ||
945 | .output_mpeg2_in_188_bytes = 1, | ||
946 | |||
947 | .agc_config_count = 1, | ||
948 | .agc = &dib7070_agc_config, | ||
949 | .bw = &dib7070_bw_config_12_mhz, | ||
950 | .tuner_is_baseband = 1, | ||
951 | .spur_protect = 1, | ||
952 | |||
953 | .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS, | ||
954 | .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES, | ||
955 | .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, | ||
956 | |||
957 | .hostbus_diversity = 1, | ||
958 | .enable_current_mirror = 1, | ||
959 | .disable_sample_and_hold = 0, | ||
960 | }; | ||
961 | |||
962 | static int stk7770p_frontend_attach(struct dvb_usb_adapter *adap) | ||
963 | { | ||
964 | struct usb_device_descriptor *p = &adap->dev->udev->descriptor; | ||
965 | if (p->idVendor == cpu_to_le16(USB_VID_PINNACLE) && | ||
966 | p->idProduct == cpu_to_le16(USB_PID_PINNACLE_PCTV72E)) | ||
967 | dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); | ||
968 | else | ||
969 | dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); | ||
970 | msleep(10); | ||
971 | dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); | ||
972 | dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); | ||
973 | dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); | ||
974 | dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); | ||
975 | |||
976 | dib0700_ctrl_clock(adap->dev, 72, 1); | ||
977 | |||
978 | msleep(10); | ||
979 | dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); | ||
980 | msleep(10); | ||
981 | dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); | ||
982 | |||
983 | if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, | ||
984 | &dib7770p_dib7000p_config) != 0) { | ||
985 | err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", | ||
986 | __func__); | ||
987 | return -ENODEV; | ||
988 | } | ||
989 | |||
990 | adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, | ||
991 | &dib7770p_dib7000p_config); | ||
992 | return adap->fe == NULL ? -ENODEV : 0; | ||
993 | } | ||
994 | |||
943 | /* DIB807x generic */ | 995 | /* DIB807x generic */ |
944 | static struct dibx000_agc_config dib807x_agc_config[2] = { | 996 | static struct dibx000_agc_config dib807x_agc_config[2] = { |
945 | { | 997 | { |
@@ -1781,7 +1833,7 @@ struct usb_device_id dib0700_usb_id_table[] = { | |||
1781 | /* 60 */{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS_2) }, | 1833 | /* 60 */{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS_2) }, |
1782 | { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XPVR) }, | 1834 | { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XPVR) }, |
1783 | { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XP) }, | 1835 | { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XP) }, |
1784 | { USB_DEVICE(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD) }, | 1836 | { USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x000, 0x3f00) }, |
1785 | { USB_DEVICE(USB_VID_EVOLUTEPC, USB_PID_TVWAY_PLUS) }, | 1837 | { USB_DEVICE(USB_VID_EVOLUTEPC, USB_PID_TVWAY_PLUS) }, |
1786 | /* 65 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73ESE) }, | 1838 | /* 65 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73ESE) }, |
1787 | { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV282E) }, | 1839 | { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV282E) }, |
@@ -2406,7 +2458,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { | |||
2406 | .pid_filter_count = 32, | 2458 | .pid_filter_count = 32, |
2407 | .pid_filter = stk70x0p_pid_filter, | 2459 | .pid_filter = stk70x0p_pid_filter, |
2408 | .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, | 2460 | .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, |
2409 | .frontend_attach = stk7070p_frontend_attach, | 2461 | .frontend_attach = stk7770p_frontend_attach, |
2410 | .tuner_attach = dib7770p_tuner_attach, | 2462 | .tuner_attach = dib7770p_tuner_attach, |
2411 | 2463 | ||
2412 | DIB0700_DEFAULT_STREAMING_CONFIG(0x02), | 2464 | DIB0700_DEFAULT_STREAMING_CONFIG(0x02), |
diff --git a/drivers/media/dvb/dvb-usb/opera1.c b/drivers/media/dvb/dvb-usb/opera1.c index 6b22ec64ab0..f896337b453 100644 --- a/drivers/media/dvb/dvb-usb/opera1.c +++ b/drivers/media/dvb/dvb-usb/opera1.c | |||
@@ -483,9 +483,7 @@ static int opera1_xilinx_load_firmware(struct usb_device *dev, | |||
483 | } | 483 | } |
484 | } | 484 | } |
485 | kfree(p); | 485 | kfree(p); |
486 | if (fw) { | 486 | release_firmware(fw); |
487 | release_firmware(fw); | ||
488 | } | ||
489 | return ret; | 487 | return ret; |
490 | } | 488 | } |
491 | 489 | ||
diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c index 2e28b973dfd..3aed0d43392 100644 --- a/drivers/media/dvb/frontends/dib7000p.c +++ b/drivers/media/dvb/frontends/dib7000p.c | |||
@@ -260,6 +260,9 @@ static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_ad | |||
260 | 260 | ||
261 | // dprintk( "908: %x, 909: %x\n", reg_908, reg_909); | 261 | // dprintk( "908: %x, 909: %x\n", reg_908, reg_909); |
262 | 262 | ||
263 | reg_909 |= (state->cfg.disable_sample_and_hold & 1) << 4; | ||
264 | reg_908 |= (state->cfg.enable_current_mirror & 1) << 7; | ||
265 | |||
263 | dib7000p_write_word(state, 908, reg_908); | 266 | dib7000p_write_word(state, 908, reg_908); |
264 | dib7000p_write_word(state, 909, reg_909); | 267 | dib7000p_write_word(state, 909, reg_909); |
265 | } | 268 | } |
@@ -778,7 +781,10 @@ static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_fronte | |||
778 | default: | 781 | default: |
779 | case GUARD_INTERVAL_1_32: value *= 1; break; | 782 | case GUARD_INTERVAL_1_32: value *= 1; break; |
780 | } | 783 | } |
781 | state->div_sync_wait = (value * 3) / 2 + 32; // add 50% SFN margin + compensate for one DVSY-fifo TODO | 784 | if (state->cfg.diversity_delay == 0) |
785 | state->div_sync_wait = (value * 3) / 2 + 48; // add 50% SFN margin + compensate for one DVSY-fifo | ||
786 | else | ||
787 | state->div_sync_wait = (value * 3) / 2 + state->cfg.diversity_delay; // add 50% SFN margin + compensate for one DVSY-fifo | ||
782 | 788 | ||
783 | /* deactive the possibility of diversity reception if extended interleaver */ | 789 | /* deactive the possibility of diversity reception if extended interleaver */ |
784 | state->div_force_off = !1 && ch->u.ofdm.transmission_mode != TRANSMISSION_MODE_8K; | 790 | state->div_force_off = !1 && ch->u.ofdm.transmission_mode != TRANSMISSION_MODE_8K; |
diff --git a/drivers/media/dvb/frontends/dib7000p.h b/drivers/media/dvb/frontends/dib7000p.h index 805dd13a97e..da17345bf5b 100644 --- a/drivers/media/dvb/frontends/dib7000p.h +++ b/drivers/media/dvb/frontends/dib7000p.h | |||
@@ -33,6 +33,11 @@ struct dib7000p_config { | |||
33 | int (*agc_control) (struct dvb_frontend *, u8 before); | 33 | int (*agc_control) (struct dvb_frontend *, u8 before); |
34 | 34 | ||
35 | u8 output_mode; | 35 | u8 output_mode; |
36 | u8 disable_sample_and_hold : 1; | ||
37 | |||
38 | u8 enable_current_mirror : 1; | ||
39 | u8 diversity_delay; | ||
40 | |||
36 | }; | 41 | }; |
37 | 42 | ||
38 | #define DEFAULT_DIB7000P_I2C_ADDRESS 18 | 43 | #define DEFAULT_DIB7000P_I2C_ADDRESS 18 |
diff --git a/drivers/media/dvb/mantis/Kconfig b/drivers/media/dvb/mantis/Kconfig index decdeda840d..fd0830ed10d 100644 --- a/drivers/media/dvb/mantis/Kconfig +++ b/drivers/media/dvb/mantis/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config MANTIS_CORE | 1 | config MANTIS_CORE |
2 | tristate "Mantis/Hopper PCI bridge based devices" | 2 | tristate "Mantis/Hopper PCI bridge based devices" |
3 | depends on PCI && I2C && INPUT | 3 | depends on PCI && I2C && INPUT && IR_CORE |
4 | 4 | ||
5 | help | 5 | help |
6 | Support for PCI cards based on the Mantis and Hopper PCi bridge. | 6 | Support for PCI cards based on the Mantis and Hopper PCi bridge. |
diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index d93468cd3a8..ff3b0fa901b 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c | |||
@@ -1098,33 +1098,26 @@ EXPORT_SYMBOL_GPL(smscore_onresponse); | |||
1098 | * | 1098 | * |
1099 | * @return pointer to descriptor on success, NULL on error. | 1099 | * @return pointer to descriptor on success, NULL on error. |
1100 | */ | 1100 | */ |
1101 | struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev) | 1101 | |
1102 | struct smscore_buffer_t *get_entry(struct smscore_device_t *coredev) | ||
1102 | { | 1103 | { |
1103 | struct smscore_buffer_t *cb = NULL; | 1104 | struct smscore_buffer_t *cb = NULL; |
1104 | unsigned long flags; | 1105 | unsigned long flags; |
1105 | 1106 | ||
1106 | DEFINE_WAIT(wait); | ||
1107 | |||
1108 | spin_lock_irqsave(&coredev->bufferslock, flags); | 1107 | spin_lock_irqsave(&coredev->bufferslock, flags); |
1109 | 1108 | if (!list_empty(&coredev->buffers)) { | |
1110 | /* This function must return a valid buffer, since the buffer list is | 1109 | cb = (struct smscore_buffer_t *) coredev->buffers.next; |
1111 | * finite, we check that there is an available buffer, if not, we wait | 1110 | list_del(&cb->entry); |
1112 | * until such buffer become available. | ||
1113 | */ | ||
1114 | |||
1115 | prepare_to_wait(&coredev->buffer_mng_waitq, &wait, TASK_INTERRUPTIBLE); | ||
1116 | if (list_empty(&coredev->buffers)) { | ||
1117 | spin_unlock_irqrestore(&coredev->bufferslock, flags); | ||
1118 | schedule(); | ||
1119 | spin_lock_irqsave(&coredev->bufferslock, flags); | ||
1120 | } | 1111 | } |
1112 | spin_unlock_irqrestore(&coredev->bufferslock, flags); | ||
1113 | return cb; | ||
1114 | } | ||
1121 | 1115 | ||
1122 | finish_wait(&coredev->buffer_mng_waitq, &wait); | 1116 | struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev) |
1123 | 1117 | { | |
1124 | cb = (struct smscore_buffer_t *) coredev->buffers.next; | 1118 | struct smscore_buffer_t *cb = NULL; |
1125 | list_del(&cb->entry); | ||
1126 | 1119 | ||
1127 | spin_unlock_irqrestore(&coredev->bufferslock, flags); | 1120 | wait_event(coredev->buffer_mng_waitq, (cb = get_entry(coredev))); |
1128 | 1121 | ||
1129 | return cb; | 1122 | return cb; |
1130 | } | 1123 | } |
diff --git a/drivers/media/radio/si470x/radio-si470x-i2c.c b/drivers/media/radio/si470x/radio-si470x-i2c.c index 67a4ec8768a..4ce541a5eb4 100644 --- a/drivers/media/radio/si470x/radio-si470x-i2c.c +++ b/drivers/media/radio/si470x/radio-si470x-i2c.c | |||
@@ -395,7 +395,7 @@ static int __devinit si470x_i2c_probe(struct i2c_client *client, | |||
395 | radio->registers[POWERCFG] = POWERCFG_ENABLE; | 395 | radio->registers[POWERCFG] = POWERCFG_ENABLE; |
396 | if (si470x_set_register(radio, POWERCFG) < 0) { | 396 | if (si470x_set_register(radio, POWERCFG) < 0) { |
397 | retval = -EIO; | 397 | retval = -EIO; |
398 | goto err_all; | 398 | goto err_video; |
399 | } | 399 | } |
400 | msleep(110); | 400 | msleep(110); |
401 | 401 | ||
diff --git a/drivers/media/video/cx231xx/Makefile b/drivers/media/video/cx231xx/Makefile index 755dd0ce65f..6f2b5738448 100644 --- a/drivers/media/video/cx231xx/Makefile +++ b/drivers/media/video/cx231xx/Makefile | |||
@@ -11,4 +11,5 @@ EXTRA_CFLAGS += -Idrivers/media/video | |||
11 | EXTRA_CFLAGS += -Idrivers/media/common/tuners | 11 | EXTRA_CFLAGS += -Idrivers/media/common/tuners |
12 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core | 12 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core |
13 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends | 13 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends |
14 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-usb | ||
14 | 15 | ||
diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c index 6bdc0ef1811..f2a4900014b 100644 --- a/drivers/media/video/cx231xx/cx231xx-cards.c +++ b/drivers/media/video/cx231xx/cx231xx-cards.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <media/v4l2-chip-ident.h> | 32 | #include <media/v4l2-chip-ident.h> |
33 | 33 | ||
34 | #include <media/cx25840.h> | 34 | #include <media/cx25840.h> |
35 | #include "dvb-usb-ids.h" | ||
35 | #include "xc5000.h" | 36 | #include "xc5000.h" |
36 | 37 | ||
37 | #include "cx231xx.h" | 38 | #include "cx231xx.h" |
@@ -175,6 +176,8 @@ struct usb_device_id cx231xx_id_table[] = { | |||
175 | .driver_info = CX231XX_BOARD_CNXT_RDE_250}, | 176 | .driver_info = CX231XX_BOARD_CNXT_RDE_250}, |
176 | {USB_DEVICE(0x0572, 0x58A1), | 177 | {USB_DEVICE(0x0572, 0x58A1), |
177 | .driver_info = CX231XX_BOARD_CNXT_RDU_250}, | 178 | .driver_info = CX231XX_BOARD_CNXT_RDU_250}, |
179 | {USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x4000,0x4fff), | ||
180 | .driver_info = CX231XX_BOARD_UNKNOWN}, | ||
178 | {}, | 181 | {}, |
179 | }; | 182 | }; |
180 | 183 | ||
@@ -226,14 +229,16 @@ void cx231xx_pre_card_setup(struct cx231xx *dev) | |||
226 | dev->board.name, dev->model); | 229 | dev->board.name, dev->model); |
227 | 230 | ||
228 | /* set the direction for GPIO pins */ | 231 | /* set the direction for GPIO pins */ |
229 | cx231xx_set_gpio_direction(dev, dev->board.tuner_gpio->bit, 1); | 232 | if (dev->board.tuner_gpio) { |
230 | cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit, 1); | 233 | cx231xx_set_gpio_direction(dev, dev->board.tuner_gpio->bit, 1); |
231 | cx231xx_set_gpio_direction(dev, dev->board.tuner_sif_gpio, 1); | 234 | cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit, 1); |
235 | cx231xx_set_gpio_direction(dev, dev->board.tuner_sif_gpio, 1); | ||
232 | 236 | ||
233 | /* request some modules if any required */ | 237 | /* request some modules if any required */ |
234 | 238 | ||
235 | /* reset the Tuner */ | 239 | /* reset the Tuner */ |
236 | cx231xx_gpio_set(dev, dev->board.tuner_gpio); | 240 | cx231xx_gpio_set(dev, dev->board.tuner_gpio); |
241 | } | ||
237 | 242 | ||
238 | /* set the mode to Analog mode initially */ | 243 | /* set the mode to Analog mode initially */ |
239 | cx231xx_set_mode(dev, CX231XX_ANALOG_MODE); | 244 | cx231xx_set_mode(dev, CX231XX_ANALOG_MODE); |
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index 86ca8c2359d..f5a3e74c3c7 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c | |||
@@ -1996,7 +1996,7 @@ static int cx25840_probe(struct i2c_client *client, | |||
1996 | 1996 | ||
1997 | state->volume = v4l2_ctrl_new_std(&state->hdl, | 1997 | state->volume = v4l2_ctrl_new_std(&state->hdl, |
1998 | &cx25840_audio_ctrl_ops, V4L2_CID_AUDIO_VOLUME, | 1998 | &cx25840_audio_ctrl_ops, V4L2_CID_AUDIO_VOLUME, |
1999 | 0, 65335, 65535 / 100, default_volume); | 1999 | 0, 65535, 65535 / 100, default_volume); |
2000 | state->mute = v4l2_ctrl_new_std(&state->hdl, | 2000 | state->mute = v4l2_ctrl_new_std(&state->hdl, |
2001 | &cx25840_audio_ctrl_ops, V4L2_CID_AUDIO_MUTE, | 2001 | &cx25840_audio_ctrl_ops, V4L2_CID_AUDIO_MUTE, |
2002 | 0, 1, 1, 0); | 2002 | 0, 1, 1, 0); |
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig index 99dbae11759..0fa85cbefbb 100644 --- a/drivers/media/video/cx88/Kconfig +++ b/drivers/media/video/cx88/Kconfig | |||
@@ -17,7 +17,7 @@ config VIDEO_CX88 | |||
17 | 17 | ||
18 | config VIDEO_CX88_ALSA | 18 | config VIDEO_CX88_ALSA |
19 | tristate "Conexant 2388x DMA audio support" | 19 | tristate "Conexant 2388x DMA audio support" |
20 | depends on VIDEO_CX88 && SND && EXPERIMENTAL | 20 | depends on VIDEO_CX88 && SND |
21 | select SND_PCM | 21 | select SND_PCM |
22 | ---help--- | 22 | ---help--- |
23 | This is a video4linux driver for direct (DMA) audio on | 23 | This is a video4linux driver for direct (DMA) audio on |
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index b9846106913..78abc1c1f9d 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c | |||
@@ -223,6 +223,7 @@ static int alloc_and_submit_int_urb(struct gspca_dev *gspca_dev, | |||
223 | usb_rcvintpipe(dev, ep->bEndpointAddress), | 223 | usb_rcvintpipe(dev, ep->bEndpointAddress), |
224 | buffer, buffer_len, | 224 | buffer, buffer_len, |
225 | int_irq, (void *)gspca_dev, interval); | 225 | int_irq, (void *)gspca_dev, interval); |
226 | urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
226 | gspca_dev->int_urb = urb; | 227 | gspca_dev->int_urb = urb; |
227 | ret = usb_submit_urb(urb, GFP_KERNEL); | 228 | ret = usb_submit_urb(urb, GFP_KERNEL); |
228 | if (ret < 0) { | 229 | if (ret < 0) { |
diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c index 83a718f0f3f..9052d570255 100644 --- a/drivers/media/video/gspca/sn9c20x.c +++ b/drivers/media/video/gspca/sn9c20x.c | |||
@@ -2357,8 +2357,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
2357 | (data[33] << 10); | 2357 | (data[33] << 10); |
2358 | avg_lum >>= 9; | 2358 | avg_lum >>= 9; |
2359 | atomic_set(&sd->avg_lum, avg_lum); | 2359 | atomic_set(&sd->avg_lum, avg_lum); |
2360 | gspca_frame_add(gspca_dev, LAST_PACKET, | 2360 | gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); |
2361 | data, len); | ||
2362 | return; | 2361 | return; |
2363 | } | 2362 | } |
2364 | if (gspca_dev->last_packet_type == LAST_PACKET) { | 2363 | if (gspca_dev->last_packet_type == LAST_PACKET) { |
diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c index be03a712731..f0316d02f09 100644 --- a/drivers/media/video/ivtv/ivtvfb.c +++ b/drivers/media/video/ivtv/ivtvfb.c | |||
@@ -466,6 +466,8 @@ static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar | |||
466 | struct fb_vblank vblank; | 466 | struct fb_vblank vblank; |
467 | u32 trace; | 467 | u32 trace; |
468 | 468 | ||
469 | memset(&vblank, 0, sizeof(struct fb_vblank)); | ||
470 | |||
469 | vblank.flags = FB_VBLANK_HAVE_COUNT |FB_VBLANK_HAVE_VCOUNT | | 471 | vblank.flags = FB_VBLANK_HAVE_COUNT |FB_VBLANK_HAVE_VCOUNT | |
470 | FB_VBLANK_HAVE_VSYNC; | 472 | FB_VBLANK_HAVE_VSYNC; |
471 | trace = read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16; | 473 | trace = read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16; |
diff --git a/drivers/media/video/mem2mem_testdev.c b/drivers/media/video/mem2mem_testdev.c index 4525335f9bd..a7210d98138 100644 --- a/drivers/media/video/mem2mem_testdev.c +++ b/drivers/media/video/mem2mem_testdev.c | |||
@@ -239,7 +239,7 @@ static int device_process(struct m2mtest_ctx *ctx, | |||
239 | return -EFAULT; | 239 | return -EFAULT; |
240 | } | 240 | } |
241 | 241 | ||
242 | if (in_buf->vb.size < out_buf->vb.size) { | 242 | if (in_buf->vb.size > out_buf->vb.size) { |
243 | v4l2_err(&dev->v4l2_dev, "Output buffer is too small\n"); | 243 | v4l2_err(&dev->v4l2_dev, "Output buffer is too small\n"); |
244 | return -EINVAL; | 244 | return -EINVAL; |
245 | } | 245 | } |
@@ -1014,6 +1014,7 @@ static int m2mtest_remove(struct platform_device *pdev) | |||
1014 | v4l2_m2m_release(dev->m2m_dev); | 1014 | v4l2_m2m_release(dev->m2m_dev); |
1015 | del_timer_sync(&dev->timer); | 1015 | del_timer_sync(&dev->timer); |
1016 | video_unregister_device(dev->vfd); | 1016 | video_unregister_device(dev->vfd); |
1017 | video_device_release(dev->vfd); | ||
1017 | v4l2_device_unregister(&dev->v4l2_dev); | 1018 | v4l2_device_unregister(&dev->v4l2_dev); |
1018 | kfree(dev); | 1019 | kfree(dev); |
1019 | 1020 | ||
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c index 758a4db27d6..c71af4e0e51 100644 --- a/drivers/media/video/mt9m111.c +++ b/drivers/media/video/mt9m111.c | |||
@@ -447,6 +447,9 @@ static int mt9m111_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | |||
447 | dev_dbg(&client->dev, "%s left=%d, top=%d, width=%d, height=%d\n", | 447 | dev_dbg(&client->dev, "%s left=%d, top=%d, width=%d, height=%d\n", |
448 | __func__, rect.left, rect.top, rect.width, rect.height); | 448 | __func__, rect.left, rect.top, rect.width, rect.height); |
449 | 449 | ||
450 | if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
451 | return -EINVAL; | ||
452 | |||
450 | ret = mt9m111_make_rect(client, &rect); | 453 | ret = mt9m111_make_rect(client, &rect); |
451 | if (!ret) | 454 | if (!ret) |
452 | mt9m111->rect = rect; | 455 | mt9m111->rect = rect; |
@@ -466,12 +469,14 @@ static int mt9m111_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | |||
466 | 469 | ||
467 | static int mt9m111_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) | 470 | static int mt9m111_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) |
468 | { | 471 | { |
472 | if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
473 | return -EINVAL; | ||
474 | |||
469 | a->bounds.left = MT9M111_MIN_DARK_COLS; | 475 | a->bounds.left = MT9M111_MIN_DARK_COLS; |
470 | a->bounds.top = MT9M111_MIN_DARK_ROWS; | 476 | a->bounds.top = MT9M111_MIN_DARK_ROWS; |
471 | a->bounds.width = MT9M111_MAX_WIDTH; | 477 | a->bounds.width = MT9M111_MAX_WIDTH; |
472 | a->bounds.height = MT9M111_MAX_HEIGHT; | 478 | a->bounds.height = MT9M111_MAX_HEIGHT; |
473 | a->defrect = a->bounds; | 479 | a->defrect = a->bounds; |
474 | a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
475 | a->pixelaspect.numerator = 1; | 480 | a->pixelaspect.numerator = 1; |
476 | a->pixelaspect.denominator = 1; | 481 | a->pixelaspect.denominator = 1; |
477 | 482 | ||
@@ -487,6 +492,7 @@ static int mt9m111_g_fmt(struct v4l2_subdev *sd, | |||
487 | mf->width = mt9m111->rect.width; | 492 | mf->width = mt9m111->rect.width; |
488 | mf->height = mt9m111->rect.height; | 493 | mf->height = mt9m111->rect.height; |
489 | mf->code = mt9m111->fmt->code; | 494 | mf->code = mt9m111->fmt->code; |
495 | mf->colorspace = mt9m111->fmt->colorspace; | ||
490 | mf->field = V4L2_FIELD_NONE; | 496 | mf->field = V4L2_FIELD_NONE; |
491 | 497 | ||
492 | return 0; | 498 | return 0; |
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c index e7cd23cd639..b48473c7896 100644 --- a/drivers/media/video/mt9v022.c +++ b/drivers/media/video/mt9v022.c | |||
@@ -402,9 +402,6 @@ static int mt9v022_s_fmt(struct v4l2_subdev *sd, | |||
402 | if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATC) | 402 | if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATC) |
403 | return -EINVAL; | 403 | return -EINVAL; |
404 | break; | 404 | break; |
405 | case 0: | ||
406 | /* No format change, only geometry */ | ||
407 | break; | ||
408 | default: | 405 | default: |
409 | return -EINVAL; | 406 | return -EINVAL; |
410 | } | 407 | } |
diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c index 66ff174151b..b6ea67221d1 100644 --- a/drivers/media/video/mx2_camera.c +++ b/drivers/media/video/mx2_camera.c | |||
@@ -378,6 +378,9 @@ static void mx25_camera_frame_done(struct mx2_camera_dev *pcdev, int fb, | |||
378 | 378 | ||
379 | spin_lock_irqsave(&pcdev->lock, flags); | 379 | spin_lock_irqsave(&pcdev->lock, flags); |
380 | 380 | ||
381 | if (*fb_active == NULL) | ||
382 | goto out; | ||
383 | |||
381 | vb = &(*fb_active)->vb; | 384 | vb = &(*fb_active)->vb; |
382 | dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, | 385 | dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, |
383 | vb, vb->baddr, vb->bsize); | 386 | vb, vb->baddr, vb->bsize); |
@@ -402,6 +405,7 @@ static void mx25_camera_frame_done(struct mx2_camera_dev *pcdev, int fb, | |||
402 | 405 | ||
403 | *fb_active = buf; | 406 | *fb_active = buf; |
404 | 407 | ||
408 | out: | ||
405 | spin_unlock_irqrestore(&pcdev->lock, flags); | 409 | spin_unlock_irqrestore(&pcdev->lock, flags); |
406 | } | 410 | } |
407 | 411 | ||
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c index 1b992b84719..55ea914c7fc 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c +++ b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c | |||
@@ -513,7 +513,7 @@ int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr, | |||
513 | if (ret >= 0) { | 513 | if (ret >= 0) { |
514 | ret = pvr2_ctrl_range_check(cptr,*valptr); | 514 | ret = pvr2_ctrl_range_check(cptr,*valptr); |
515 | } | 515 | } |
516 | if (maskptr) *maskptr = ~0; | 516 | *maskptr = ~0; |
517 | } else if (cptr->info->type == pvr2_ctl_bool) { | 517 | } else if (cptr->info->type == pvr2_ctl_bool) { |
518 | ret = parse_token(ptr,len,valptr,boolNames, | 518 | ret = parse_token(ptr,len,valptr,boolNames, |
519 | ARRAY_SIZE(boolNames)); | 519 | ARRAY_SIZE(boolNames)); |
@@ -522,7 +522,7 @@ int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr, | |||
522 | } else if (ret == 0) { | 522 | } else if (ret == 0) { |
523 | *valptr = (*valptr & 1) ? !0 : 0; | 523 | *valptr = (*valptr & 1) ? !0 : 0; |
524 | } | 524 | } |
525 | if (maskptr) *maskptr = 1; | 525 | *maskptr = 1; |
526 | } else if (cptr->info->type == pvr2_ctl_enum) { | 526 | } else if (cptr->info->type == pvr2_ctl_enum) { |
527 | ret = parse_token( | 527 | ret = parse_token( |
528 | ptr,len,valptr, | 528 | ptr,len,valptr, |
@@ -531,7 +531,7 @@ int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr, | |||
531 | if (ret >= 0) { | 531 | if (ret >= 0) { |
532 | ret = pvr2_ctrl_range_check(cptr,*valptr); | 532 | ret = pvr2_ctrl_range_check(cptr,*valptr); |
533 | } | 533 | } |
534 | if (maskptr) *maskptr = ~0; | 534 | *maskptr = ~0; |
535 | } else if (cptr->info->type == pvr2_ctl_bitmask) { | 535 | } else if (cptr->info->type == pvr2_ctl_bitmask) { |
536 | ret = parse_tlist( | 536 | ret = parse_tlist( |
537 | ptr,len,maskptr,valptr, | 537 | ptr,len,maskptr,valptr, |
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index b151c7be8a5..6961c55baf9 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c | |||
@@ -393,6 +393,37 @@ static void fimc_set_yuv_order(struct fimc_ctx *ctx) | |||
393 | dbg("ctx->out_order_1p= %d", ctx->out_order_1p); | 393 | dbg("ctx->out_order_1p= %d", ctx->out_order_1p); |
394 | } | 394 | } |
395 | 395 | ||
396 | static void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f) | ||
397 | { | ||
398 | struct samsung_fimc_variant *variant = ctx->fimc_dev->variant; | ||
399 | |||
400 | f->dma_offset.y_h = f->offs_h; | ||
401 | if (!variant->pix_hoff) | ||
402 | f->dma_offset.y_h *= (f->fmt->depth >> 3); | ||
403 | |||
404 | f->dma_offset.y_v = f->offs_v; | ||
405 | |||
406 | f->dma_offset.cb_h = f->offs_h; | ||
407 | f->dma_offset.cb_v = f->offs_v; | ||
408 | |||
409 | f->dma_offset.cr_h = f->offs_h; | ||
410 | f->dma_offset.cr_v = f->offs_v; | ||
411 | |||
412 | if (!variant->pix_hoff) { | ||
413 | if (f->fmt->planes_cnt == 3) { | ||
414 | f->dma_offset.cb_h >>= 1; | ||
415 | f->dma_offset.cr_h >>= 1; | ||
416 | } | ||
417 | if (f->fmt->color == S5P_FIMC_YCBCR420) { | ||
418 | f->dma_offset.cb_v >>= 1; | ||
419 | f->dma_offset.cr_v >>= 1; | ||
420 | } | ||
421 | } | ||
422 | |||
423 | dbg("in_offset: color= %d, y_h= %d, y_v= %d", | ||
424 | f->fmt->color, f->dma_offset.y_h, f->dma_offset.y_v); | ||
425 | } | ||
426 | |||
396 | /** | 427 | /** |
397 | * fimc_prepare_config - check dimensions, operation and color mode | 428 | * fimc_prepare_config - check dimensions, operation and color mode |
398 | * and pre-calculate offset and the scaling coefficients. | 429 | * and pre-calculate offset and the scaling coefficients. |
@@ -406,7 +437,6 @@ static int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags) | |||
406 | { | 437 | { |
407 | struct fimc_frame *s_frame, *d_frame; | 438 | struct fimc_frame *s_frame, *d_frame; |
408 | struct fimc_vid_buffer *buf = NULL; | 439 | struct fimc_vid_buffer *buf = NULL; |
409 | struct samsung_fimc_variant *variant = ctx->fimc_dev->variant; | ||
410 | int ret = 0; | 440 | int ret = 0; |
411 | 441 | ||
412 | s_frame = &ctx->s_frame; | 442 | s_frame = &ctx->s_frame; |
@@ -419,61 +449,16 @@ static int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags) | |||
419 | swap(d_frame->width, d_frame->height); | 449 | swap(d_frame->width, d_frame->height); |
420 | } | 450 | } |
421 | 451 | ||
422 | /* Prepare the output offset ratios for scaler. */ | 452 | /* Prepare the DMA offset ratios for scaler. */ |
423 | d_frame->dma_offset.y_h = d_frame->offs_h; | 453 | fimc_prepare_dma_offset(ctx, &ctx->s_frame); |
424 | if (!variant->pix_hoff) | 454 | fimc_prepare_dma_offset(ctx, &ctx->d_frame); |
425 | d_frame->dma_offset.y_h *= (d_frame->fmt->depth >> 3); | ||
426 | |||
427 | d_frame->dma_offset.y_v = d_frame->offs_v; | ||
428 | |||
429 | d_frame->dma_offset.cb_h = d_frame->offs_h; | ||
430 | d_frame->dma_offset.cb_v = d_frame->offs_v; | ||
431 | |||
432 | d_frame->dma_offset.cr_h = d_frame->offs_h; | ||
433 | d_frame->dma_offset.cr_v = d_frame->offs_v; | ||
434 | 455 | ||
435 | if (!variant->pix_hoff && d_frame->fmt->planes_cnt == 3) { | ||
436 | d_frame->dma_offset.cb_h >>= 1; | ||
437 | d_frame->dma_offset.cb_v >>= 1; | ||
438 | d_frame->dma_offset.cr_h >>= 1; | ||
439 | d_frame->dma_offset.cr_v >>= 1; | ||
440 | } | ||
441 | |||
442 | dbg("out offset: color= %d, y_h= %d, y_v= %d", | ||
443 | d_frame->fmt->color, | ||
444 | d_frame->dma_offset.y_h, d_frame->dma_offset.y_v); | ||
445 | |||
446 | /* Prepare the input offset ratios for scaler. */ | ||
447 | s_frame->dma_offset.y_h = s_frame->offs_h; | ||
448 | if (!variant->pix_hoff) | ||
449 | s_frame->dma_offset.y_h *= (s_frame->fmt->depth >> 3); | ||
450 | s_frame->dma_offset.y_v = s_frame->offs_v; | ||
451 | |||
452 | s_frame->dma_offset.cb_h = s_frame->offs_h; | ||
453 | s_frame->dma_offset.cb_v = s_frame->offs_v; | ||
454 | |||
455 | s_frame->dma_offset.cr_h = s_frame->offs_h; | ||
456 | s_frame->dma_offset.cr_v = s_frame->offs_v; | ||
457 | |||
458 | if (!variant->pix_hoff && s_frame->fmt->planes_cnt == 3) { | ||
459 | s_frame->dma_offset.cb_h >>= 1; | ||
460 | s_frame->dma_offset.cb_v >>= 1; | ||
461 | s_frame->dma_offset.cr_h >>= 1; | ||
462 | s_frame->dma_offset.cr_v >>= 1; | ||
463 | } | ||
464 | |||
465 | dbg("in offset: color= %d, y_h= %d, y_v= %d", | ||
466 | s_frame->fmt->color, s_frame->dma_offset.y_h, | ||
467 | s_frame->dma_offset.y_v); | ||
468 | |||
469 | fimc_set_yuv_order(ctx); | ||
470 | |||
471 | /* Check against the scaler ratio. */ | ||
472 | if (s_frame->height > (SCALER_MAX_VRATIO * d_frame->height) || | 456 | if (s_frame->height > (SCALER_MAX_VRATIO * d_frame->height) || |
473 | s_frame->width > (SCALER_MAX_HRATIO * d_frame->width)) { | 457 | s_frame->width > (SCALER_MAX_HRATIO * d_frame->width)) { |
474 | err("out of scaler range"); | 458 | err("out of scaler range"); |
475 | return -EINVAL; | 459 | return -EINVAL; |
476 | } | 460 | } |
461 | fimc_set_yuv_order(ctx); | ||
477 | } | 462 | } |
478 | 463 | ||
479 | /* Input DMA mode is not allowed when the scaler is disabled. */ | 464 | /* Input DMA mode is not allowed when the scaler is disabled. */ |
@@ -822,7 +807,8 @@ static int fimc_m2m_s_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
822 | } else { | 807 | } else { |
823 | v4l2_err(&ctx->fimc_dev->m2m.v4l2_dev, | 808 | v4l2_err(&ctx->fimc_dev->m2m.v4l2_dev, |
824 | "Wrong buffer/video queue type (%d)\n", f->type); | 809 | "Wrong buffer/video queue type (%d)\n", f->type); |
825 | return -EINVAL; | 810 | ret = -EINVAL; |
811 | goto s_fmt_out; | ||
826 | } | 812 | } |
827 | 813 | ||
828 | pix = &f->fmt.pix; | 814 | pix = &f->fmt.pix; |
@@ -1414,8 +1400,10 @@ static int fimc_probe(struct platform_device *pdev) | |||
1414 | } | 1400 | } |
1415 | 1401 | ||
1416 | fimc->work_queue = create_workqueue(dev_name(&fimc->pdev->dev)); | 1402 | fimc->work_queue = create_workqueue(dev_name(&fimc->pdev->dev)); |
1417 | if (!fimc->work_queue) | 1403 | if (!fimc->work_queue) { |
1404 | ret = -ENOMEM; | ||
1418 | goto err_irq; | 1405 | goto err_irq; |
1406 | } | ||
1419 | 1407 | ||
1420 | ret = fimc_register_m2m_device(fimc); | 1408 | ret = fimc_register_m2m_device(fimc); |
1421 | if (ret) | 1409 | if (ret) |
@@ -1492,6 +1480,7 @@ static struct samsung_fimc_variant fimc2_variant_s5p = { | |||
1492 | }; | 1480 | }; |
1493 | 1481 | ||
1494 | static struct samsung_fimc_variant fimc01_variant_s5pv210 = { | 1482 | static struct samsung_fimc_variant fimc01_variant_s5pv210 = { |
1483 | .pix_hoff = 1, | ||
1495 | .has_inp_rot = 1, | 1484 | .has_inp_rot = 1, |
1496 | .has_out_rot = 1, | 1485 | .has_out_rot = 1, |
1497 | .min_inp_pixsize = 16, | 1486 | .min_inp_pixsize = 16, |
@@ -1506,6 +1495,7 @@ static struct samsung_fimc_variant fimc01_variant_s5pv210 = { | |||
1506 | }; | 1495 | }; |
1507 | 1496 | ||
1508 | static struct samsung_fimc_variant fimc2_variant_s5pv210 = { | 1497 | static struct samsung_fimc_variant fimc2_variant_s5pv210 = { |
1498 | .pix_hoff = 1, | ||
1509 | .min_inp_pixsize = 16, | 1499 | .min_inp_pixsize = 16, |
1510 | .min_out_pixsize = 32, | 1500 | .min_out_pixsize = 32, |
1511 | 1501 | ||
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index ec697fcd406..bb8d83d8dda 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c | |||
@@ -4323,13 +4323,13 @@ struct saa7134_board saa7134_boards[] = { | |||
4323 | }, | 4323 | }, |
4324 | [SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM] = { | 4324 | [SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM] = { |
4325 | /* Beholder Intl. Ltd. 2008 */ | 4325 | /* Beholder Intl. Ltd. 2008 */ |
4326 | /*Dmitry Belimov <d.belimov@gmail.com> */ | 4326 | /* Dmitry Belimov <d.belimov@gmail.com> */ |
4327 | .name = "Beholder BeholdTV Columbus TVFM", | 4327 | .name = "Beholder BeholdTV Columbus TV/FM", |
4328 | .audio_clock = 0x00187de7, | 4328 | .audio_clock = 0x00187de7, |
4329 | .tuner_type = TUNER_ALPS_TSBE5_PAL, | 4329 | .tuner_type = TUNER_ALPS_TSBE5_PAL, |
4330 | .radio_type = UNSET, | 4330 | .radio_type = TUNER_TEA5767, |
4331 | .tuner_addr = ADDR_UNSET, | 4331 | .tuner_addr = 0xc2 >> 1, |
4332 | .radio_addr = ADDR_UNSET, | 4332 | .radio_addr = 0xc0 >> 1, |
4333 | .tda9887_conf = TDA9887_PRESENT, | 4333 | .tda9887_conf = TDA9887_PRESENT, |
4334 | .gpiomask = 0x000A8004, | 4334 | .gpiomask = 0x000A8004, |
4335 | .inputs = {{ | 4335 | .inputs = {{ |
diff --git a/drivers/media/video/saa7164/saa7164-buffer.c b/drivers/media/video/saa7164/saa7164-buffer.c index 5713f3a4b76..ddd25d32723 100644 --- a/drivers/media/video/saa7164/saa7164-buffer.c +++ b/drivers/media/video/saa7164/saa7164-buffer.c | |||
@@ -136,10 +136,11 @@ ret: | |||
136 | int saa7164_buffer_dealloc(struct saa7164_tsport *port, | 136 | int saa7164_buffer_dealloc(struct saa7164_tsport *port, |
137 | struct saa7164_buffer *buf) | 137 | struct saa7164_buffer *buf) |
138 | { | 138 | { |
139 | struct saa7164_dev *dev = port->dev; | 139 | struct saa7164_dev *dev; |
140 | 140 | ||
141 | if ((buf == 0) || (port == 0)) | 141 | if (!buf || !port) |
142 | return SAA_ERR_BAD_PARAMETER; | 142 | return SAA_ERR_BAD_PARAMETER; |
143 | dev = port->dev; | ||
143 | 144 | ||
144 | dprintk(DBGLVL_BUF, "%s() deallocating buffer @ 0x%p\n", __func__, buf); | 145 | dprintk(DBGLVL_BUF, "%s() deallocating buffer @ 0x%p\n", __func__, buf); |
145 | 146 | ||
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index 8bdd940f32e..2ac85d8984f 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c | |||
@@ -486,6 +486,12 @@ static int uvc_parse_format(struct uvc_device *dev, | |||
486 | max(frame->dwFrameInterval[0], | 486 | max(frame->dwFrameInterval[0], |
487 | frame->dwDefaultFrameInterval)); | 487 | frame->dwDefaultFrameInterval)); |
488 | 488 | ||
489 | if (dev->quirks & UVC_QUIRK_RESTRICT_FRAME_RATE) { | ||
490 | frame->bFrameIntervalType = 1; | ||
491 | frame->dwFrameInterval[0] = | ||
492 | frame->dwDefaultFrameInterval; | ||
493 | } | ||
494 | |||
489 | uvc_trace(UVC_TRACE_DESCR, "- %ux%u (%u.%u fps)\n", | 495 | uvc_trace(UVC_TRACE_DESCR, "- %ux%u (%u.%u fps)\n", |
490 | frame->wWidth, frame->wHeight, | 496 | frame->wWidth, frame->wHeight, |
491 | 10000000/frame->dwDefaultFrameInterval, | 497 | 10000000/frame->dwDefaultFrameInterval, |
@@ -2026,6 +2032,15 @@ static struct usb_device_id uvc_ids[] = { | |||
2026 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC, | 2032 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC, |
2027 | .bInterfaceSubClass = 1, | 2033 | .bInterfaceSubClass = 1, |
2028 | .bInterfaceProtocol = 0 }, | 2034 | .bInterfaceProtocol = 0 }, |
2035 | /* Chicony CNF7129 (Asus EEE 100HE) */ | ||
2036 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | ||
2037 | | USB_DEVICE_ID_MATCH_INT_INFO, | ||
2038 | .idVendor = 0x04f2, | ||
2039 | .idProduct = 0xb071, | ||
2040 | .bInterfaceClass = USB_CLASS_VIDEO, | ||
2041 | .bInterfaceSubClass = 1, | ||
2042 | .bInterfaceProtocol = 0, | ||
2043 | .driver_info = UVC_QUIRK_RESTRICT_FRAME_RATE }, | ||
2029 | /* Alcor Micro AU3820 (Future Boy PC USB Webcam) */ | 2044 | /* Alcor Micro AU3820 (Future Boy PC USB Webcam) */ |
2030 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | 2045 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
2031 | | USB_DEVICE_ID_MATCH_INT_INFO, | 2046 | | USB_DEVICE_ID_MATCH_INT_INFO, |
@@ -2091,6 +2106,15 @@ static struct usb_device_id uvc_ids[] = { | |||
2091 | .bInterfaceProtocol = 0, | 2106 | .bInterfaceProtocol = 0, |
2092 | .driver_info = UVC_QUIRK_PROBE_MINMAX | 2107 | .driver_info = UVC_QUIRK_PROBE_MINMAX |
2093 | | UVC_QUIRK_PROBE_DEF }, | 2108 | | UVC_QUIRK_PROBE_DEF }, |
2109 | /* IMC Networks (Medion Akoya) */ | ||
2110 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | ||
2111 | | USB_DEVICE_ID_MATCH_INT_INFO, | ||
2112 | .idVendor = 0x13d3, | ||
2113 | .idProduct = 0x5103, | ||
2114 | .bInterfaceClass = USB_CLASS_VIDEO, | ||
2115 | .bInterfaceSubClass = 1, | ||
2116 | .bInterfaceProtocol = 0, | ||
2117 | .driver_info = UVC_QUIRK_STREAM_NO_FID }, | ||
2094 | /* Syntek (HP Spartan) */ | 2118 | /* Syntek (HP Spartan) */ |
2095 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | 2119 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
2096 | | USB_DEVICE_ID_MATCH_INT_INFO, | 2120 | | USB_DEVICE_ID_MATCH_INT_INFO, |
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index bdacf3beabf..892e0e51916 100644 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h | |||
@@ -182,6 +182,7 @@ struct uvc_xu_control { | |||
182 | #define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020 | 182 | #define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020 |
183 | #define UVC_QUIRK_FIX_BANDWIDTH 0x00000080 | 183 | #define UVC_QUIRK_FIX_BANDWIDTH 0x00000080 |
184 | #define UVC_QUIRK_PROBE_DEF 0x00000100 | 184 | #define UVC_QUIRK_PROBE_DEF 0x00000100 |
185 | #define UVC_QUIRK_RESTRICT_FRAME_RATE 0x00000200 | ||
185 | 186 | ||
186 | /* Format flags */ | 187 | /* Format flags */ |
187 | #define UVC_FMT_FLAG_COMPRESSED 0x00000001 | 188 | #define UVC_FMT_FLAG_COMPRESSED 0x00000001 |
diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c index 372b87efcd0..6ff9e4bac3e 100644 --- a/drivers/media/video/videobuf-dma-contig.c +++ b/drivers/media/video/videobuf-dma-contig.c | |||
@@ -393,8 +393,10 @@ void videobuf_dma_contig_free(struct videobuf_queue *q, | |||
393 | } | 393 | } |
394 | 394 | ||
395 | /* read() method */ | 395 | /* read() method */ |
396 | dma_free_coherent(q->dev, mem->size, mem->vaddr, mem->dma_handle); | 396 | if (mem->vaddr) { |
397 | mem->vaddr = NULL; | 397 | dma_free_coherent(q->dev, mem->size, mem->vaddr, mem->dma_handle); |
398 | mem->vaddr = NULL; | ||
399 | } | ||
398 | } | 400 | } |
399 | EXPORT_SYMBOL_GPL(videobuf_dma_contig_free); | 401 | EXPORT_SYMBOL_GPL(videobuf_dma_contig_free); |
400 | 402 | ||
diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c index 06f9a9c2a39..2ad0bc252b0 100644 --- a/drivers/media/video/videobuf-dma-sg.c +++ b/drivers/media/video/videobuf-dma-sg.c | |||
@@ -94,7 +94,7 @@ err: | |||
94 | * must free the memory. | 94 | * must free the memory. |
95 | */ | 95 | */ |
96 | static struct scatterlist *videobuf_pages_to_sg(struct page **pages, | 96 | static struct scatterlist *videobuf_pages_to_sg(struct page **pages, |
97 | int nr_pages, int offset) | 97 | int nr_pages, int offset, size_t size) |
98 | { | 98 | { |
99 | struct scatterlist *sglist; | 99 | struct scatterlist *sglist; |
100 | int i; | 100 | int i; |
@@ -110,12 +110,14 @@ static struct scatterlist *videobuf_pages_to_sg(struct page **pages, | |||
110 | /* DMA to highmem pages might not work */ | 110 | /* DMA to highmem pages might not work */ |
111 | goto highmem; | 111 | goto highmem; |
112 | sg_set_page(&sglist[0], pages[0], PAGE_SIZE - offset, offset); | 112 | sg_set_page(&sglist[0], pages[0], PAGE_SIZE - offset, offset); |
113 | size -= PAGE_SIZE - offset; | ||
113 | for (i = 1; i < nr_pages; i++) { | 114 | for (i = 1; i < nr_pages; i++) { |
114 | if (NULL == pages[i]) | 115 | if (NULL == pages[i]) |
115 | goto nopage; | 116 | goto nopage; |
116 | if (PageHighMem(pages[i])) | 117 | if (PageHighMem(pages[i])) |
117 | goto highmem; | 118 | goto highmem; |
118 | sg_set_page(&sglist[i], pages[i], PAGE_SIZE, 0); | 119 | sg_set_page(&sglist[i], pages[i], min(PAGE_SIZE, size), 0); |
120 | size -= min(PAGE_SIZE, size); | ||
119 | } | 121 | } |
120 | return sglist; | 122 | return sglist; |
121 | 123 | ||
@@ -170,7 +172,8 @@ static int videobuf_dma_init_user_locked(struct videobuf_dmabuf *dma, | |||
170 | 172 | ||
171 | first = (data & PAGE_MASK) >> PAGE_SHIFT; | 173 | first = (data & PAGE_MASK) >> PAGE_SHIFT; |
172 | last = ((data+size-1) & PAGE_MASK) >> PAGE_SHIFT; | 174 | last = ((data+size-1) & PAGE_MASK) >> PAGE_SHIFT; |
173 | dma->offset = data & ~PAGE_MASK; | 175 | dma->offset = data & ~PAGE_MASK; |
176 | dma->size = size; | ||
174 | dma->nr_pages = last-first+1; | 177 | dma->nr_pages = last-first+1; |
175 | dma->pages = kmalloc(dma->nr_pages * sizeof(struct page *), GFP_KERNEL); | 178 | dma->pages = kmalloc(dma->nr_pages * sizeof(struct page *), GFP_KERNEL); |
176 | if (NULL == dma->pages) | 179 | if (NULL == dma->pages) |
@@ -252,7 +255,7 @@ int videobuf_dma_map(struct device *dev, struct videobuf_dmabuf *dma) | |||
252 | 255 | ||
253 | if (dma->pages) { | 256 | if (dma->pages) { |
254 | dma->sglist = videobuf_pages_to_sg(dma->pages, dma->nr_pages, | 257 | dma->sglist = videobuf_pages_to_sg(dma->pages, dma->nr_pages, |
255 | dma->offset); | 258 | dma->offset, dma->size); |
256 | } | 259 | } |
257 | if (dma->vaddr) { | 260 | if (dma->vaddr) { |
258 | dma->sglist = videobuf_vmalloc_to_sg(dma->vaddr, | 261 | dma->sglist = videobuf_vmalloc_to_sg(dma->vaddr, |
diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c index 04028a9ee08..428377a5a6f 100644 --- a/drivers/mfd/max8925-core.c +++ b/drivers/mfd/max8925-core.c | |||
@@ -429,24 +429,25 @@ static void max8925_irq_sync_unlock(unsigned int irq) | |||
429 | irq_tsc = cache_tsc; | 429 | irq_tsc = cache_tsc; |
430 | for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) { | 430 | for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) { |
431 | irq_data = &max8925_irqs[i]; | 431 | irq_data = &max8925_irqs[i]; |
432 | /* 1 -- disable, 0 -- enable */ | ||
432 | switch (irq_data->mask_reg) { | 433 | switch (irq_data->mask_reg) { |
433 | case MAX8925_CHG_IRQ1_MASK: | 434 | case MAX8925_CHG_IRQ1_MASK: |
434 | irq_chg[0] &= irq_data->enable; | 435 | irq_chg[0] &= ~irq_data->enable; |
435 | break; | 436 | break; |
436 | case MAX8925_CHG_IRQ2_MASK: | 437 | case MAX8925_CHG_IRQ2_MASK: |
437 | irq_chg[1] &= irq_data->enable; | 438 | irq_chg[1] &= ~irq_data->enable; |
438 | break; | 439 | break; |
439 | case MAX8925_ON_OFF_IRQ1_MASK: | 440 | case MAX8925_ON_OFF_IRQ1_MASK: |
440 | irq_on[0] &= irq_data->enable; | 441 | irq_on[0] &= ~irq_data->enable; |
441 | break; | 442 | break; |
442 | case MAX8925_ON_OFF_IRQ2_MASK: | 443 | case MAX8925_ON_OFF_IRQ2_MASK: |
443 | irq_on[1] &= irq_data->enable; | 444 | irq_on[1] &= ~irq_data->enable; |
444 | break; | 445 | break; |
445 | case MAX8925_RTC_IRQ_MASK: | 446 | case MAX8925_RTC_IRQ_MASK: |
446 | irq_rtc &= irq_data->enable; | 447 | irq_rtc &= ~irq_data->enable; |
447 | break; | 448 | break; |
448 | case MAX8925_TSC_IRQ_MASK: | 449 | case MAX8925_TSC_IRQ_MASK: |
449 | irq_tsc &= irq_data->enable; | 450 | irq_tsc &= ~irq_data->enable; |
450 | break; | 451 | break; |
451 | default: | 452 | default: |
452 | dev_err(chip->dev, "wrong IRQ\n"); | 453 | dev_err(chip->dev, "wrong IRQ\n"); |
diff --git a/drivers/mfd/wm831x-irq.c b/drivers/mfd/wm831x-irq.c index 7dabe4dbd37..294183b6260 100644 --- a/drivers/mfd/wm831x-irq.c +++ b/drivers/mfd/wm831x-irq.c | |||
@@ -394,8 +394,13 @@ static int wm831x_irq_set_type(unsigned int irq, unsigned int type) | |||
394 | 394 | ||
395 | irq = irq - wm831x->irq_base; | 395 | irq = irq - wm831x->irq_base; |
396 | 396 | ||
397 | if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_11) | 397 | if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_11) { |
398 | return -EINVAL; | 398 | /* Ignore internal-only IRQs */ |
399 | if (irq >= 0 && irq < WM831X_NUM_IRQS) | ||
400 | return 0; | ||
401 | else | ||
402 | return -EINVAL; | ||
403 | } | ||
399 | 404 | ||
400 | switch (type) { | 405 | switch (type) { |
401 | case IRQ_TYPE_EDGE_BOTH: | 406 | case IRQ_TYPE_EDGE_BOTH: |
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 0b591b65824..b7433126074 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig | |||
@@ -368,7 +368,7 @@ config VMWARE_BALLOON | |||
368 | If unsure, say N. | 368 | If unsure, say N. |
369 | 369 | ||
370 | To compile this driver as a module, choose M here: the | 370 | To compile this driver as a module, choose M here: the |
371 | module will be called vmware_balloon. | 371 | module will be called vmw_balloon. |
372 | 372 | ||
373 | config ARM_CHARLCD | 373 | config ARM_CHARLCD |
374 | bool "ARM Ltd. Character LCD Driver" | 374 | bool "ARM Ltd. Character LCD Driver" |
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 255a80dc9d7..42eab95cde2 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile | |||
@@ -33,5 +33,5 @@ obj-$(CONFIG_IWMC3200TOP) += iwmc3200top/ | |||
33 | obj-$(CONFIG_HMC6352) += hmc6352.o | 33 | obj-$(CONFIG_HMC6352) += hmc6352.o |
34 | obj-y += eeprom/ | 34 | obj-y += eeprom/ |
35 | obj-y += cb710/ | 35 | obj-y += cb710/ |
36 | obj-$(CONFIG_VMWARE_BALLOON) += vmware_balloon.o | 36 | obj-$(CONFIG_VMWARE_BALLOON) += vmw_balloon.o |
37 | obj-$(CONFIG_ARM_CHARLCD) += arm-charlcd.o | 37 | obj-$(CONFIG_ARM_CHARLCD) += arm-charlcd.o |
diff --git a/drivers/misc/bh1780gli.c b/drivers/misc/bh1780gli.c index 714c6b48731..d5f3a3fd231 100644 --- a/drivers/misc/bh1780gli.c +++ b/drivers/misc/bh1780gli.c | |||
@@ -190,7 +190,6 @@ static int __devexit bh1780_remove(struct i2c_client *client) | |||
190 | 190 | ||
191 | ddata = i2c_get_clientdata(client); | 191 | ddata = i2c_get_clientdata(client); |
192 | sysfs_remove_group(&client->dev.kobj, &bh1780_attr_group); | 192 | sysfs_remove_group(&client->dev.kobj, &bh1780_attr_group); |
193 | i2c_set_clientdata(client, NULL); | ||
194 | kfree(ddata); | 193 | kfree(ddata); |
195 | 194 | ||
196 | return 0; | 195 | return 0; |
diff --git a/drivers/misc/vmware_balloon.c b/drivers/misc/vmw_balloon.c index 2a1e804a71a..2a1e804a71a 100644 --- a/drivers/misc/vmware_balloon.c +++ b/drivers/misc/vmw_balloon.c | |||
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index bd2755e8d9a..f332c52968b 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c | |||
@@ -362,9 +362,8 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, | |||
362 | goto err; | 362 | goto err; |
363 | } | 363 | } |
364 | 364 | ||
365 | err = mmc_sd_get_cid(host, host->ocr & ocr, card->raw_cid); | 365 | if (ocr & R4_MEMORY_PRESENT |
366 | 366 | && mmc_sd_get_cid(host, host->ocr & ocr, card->raw_cid) == 0) { | |
367 | if (!err) { | ||
368 | card->type = MMC_TYPE_SD_COMBO; | 367 | card->type = MMC_TYPE_SD_COMBO; |
369 | 368 | ||
370 | if (oldcard && (oldcard->type != MMC_TYPE_SD_COMBO || | 369 | if (oldcard && (oldcard->type != MMC_TYPE_SD_COMBO || |
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index 5f3a599ead0..87226cd202a 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c | |||
@@ -66,6 +66,7 @@ | |||
66 | #include <linux/clk.h> | 66 | #include <linux/clk.h> |
67 | #include <linux/atmel_pdc.h> | 67 | #include <linux/atmel_pdc.h> |
68 | #include <linux/gfp.h> | 68 | #include <linux/gfp.h> |
69 | #include <linux/highmem.h> | ||
69 | 70 | ||
70 | #include <linux/mmc/host.h> | 71 | #include <linux/mmc/host.h> |
71 | 72 | ||
diff --git a/drivers/mmc/host/imxmmc.c b/drivers/mmc/host/imxmmc.c index 9a68ff4353a..5a950b16d9e 100644 --- a/drivers/mmc/host/imxmmc.c +++ b/drivers/mmc/host/imxmmc.c | |||
@@ -148,11 +148,12 @@ static int imxmci_start_clock(struct imxmci_host *host) | |||
148 | 148 | ||
149 | while (delay--) { | 149 | while (delay--) { |
150 | reg = readw(host->base + MMC_REG_STATUS); | 150 | reg = readw(host->base + MMC_REG_STATUS); |
151 | if (reg & STATUS_CARD_BUS_CLK_RUN) | 151 | if (reg & STATUS_CARD_BUS_CLK_RUN) { |
152 | /* Check twice before cut */ | 152 | /* Check twice before cut */ |
153 | reg = readw(host->base + MMC_REG_STATUS); | 153 | reg = readw(host->base + MMC_REG_STATUS); |
154 | if (reg & STATUS_CARD_BUS_CLK_RUN) | 154 | if (reg & STATUS_CARD_BUS_CLK_RUN) |
155 | return 0; | 155 | return 0; |
156 | } | ||
156 | 157 | ||
157 | if (test_bit(IMXMCI_PEND_STARTED_b, &host->pending_events)) | 158 | if (test_bit(IMXMCI_PEND_STARTED_b, &host->pending_events)) |
158 | return 0; | 159 | return 0; |
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 4a8776f8afd..4526d2791f2 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c | |||
@@ -2305,7 +2305,6 @@ static int omap_hsmmc_suspend(struct device *dev) | |||
2305 | int ret = 0; | 2305 | int ret = 0; |
2306 | struct platform_device *pdev = to_platform_device(dev); | 2306 | struct platform_device *pdev = to_platform_device(dev); |
2307 | struct omap_hsmmc_host *host = platform_get_drvdata(pdev); | 2307 | struct omap_hsmmc_host *host = platform_get_drvdata(pdev); |
2308 | pm_message_t state = PMSG_SUSPEND; /* unused by MMC core */ | ||
2309 | 2308 | ||
2310 | if (host && host->suspended) | 2309 | if (host && host->suspended) |
2311 | return 0; | 2310 | return 0; |
@@ -2324,8 +2323,8 @@ static int omap_hsmmc_suspend(struct device *dev) | |||
2324 | } | 2323 | } |
2325 | } | 2324 | } |
2326 | cancel_work_sync(&host->mmc_carddetect_work); | 2325 | cancel_work_sync(&host->mmc_carddetect_work); |
2327 | mmc_host_enable(host->mmc); | ||
2328 | ret = mmc_suspend_host(host->mmc); | 2326 | ret = mmc_suspend_host(host->mmc); |
2327 | mmc_host_enable(host->mmc); | ||
2329 | if (ret == 0) { | 2328 | if (ret == 0) { |
2330 | omap_hsmmc_disable_irq(host); | 2329 | omap_hsmmc_disable_irq(host); |
2331 | OMAP_HSMMC_WRITE(host->base, HCTL, | 2330 | OMAP_HSMMC_WRITE(host->base, HCTL, |
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 2e16e0a90a5..976330de379 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c | |||
@@ -1600,7 +1600,7 @@ static int __devinit s3cmci_probe(struct platform_device *pdev) | |||
1600 | host->pio_active = XFER_NONE; | 1600 | host->pio_active = XFER_NONE; |
1601 | 1601 | ||
1602 | #ifdef CONFIG_MMC_S3C_PIODMA | 1602 | #ifdef CONFIG_MMC_S3C_PIODMA |
1603 | host->dodma = host->pdata->dma; | 1603 | host->dodma = host->pdata->use_dma; |
1604 | #endif | 1604 | #endif |
1605 | 1605 | ||
1606 | host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1606 | host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index 71ad4163b95..aacb862ecc8 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c | |||
@@ -241,8 +241,10 @@ static struct sdhci_ops sdhci_s3c_ops = { | |||
241 | static void sdhci_s3c_notify_change(struct platform_device *dev, int state) | 241 | static void sdhci_s3c_notify_change(struct platform_device *dev, int state) |
242 | { | 242 | { |
243 | struct sdhci_host *host = platform_get_drvdata(dev); | 243 | struct sdhci_host *host = platform_get_drvdata(dev); |
244 | unsigned long flags; | ||
245 | |||
244 | if (host) { | 246 | if (host) { |
245 | spin_lock(&host->lock); | 247 | spin_lock_irqsave(&host->lock, flags); |
246 | if (state) { | 248 | if (state) { |
247 | dev_dbg(&dev->dev, "card inserted.\n"); | 249 | dev_dbg(&dev->dev, "card inserted.\n"); |
248 | host->flags &= ~SDHCI_DEVICE_DEAD; | 250 | host->flags &= ~SDHCI_DEVICE_DEAD; |
@@ -253,7 +255,7 @@ static void sdhci_s3c_notify_change(struct platform_device *dev, int state) | |||
253 | host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION; | 255 | host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION; |
254 | } | 256 | } |
255 | tasklet_schedule(&host->card_tasklet); | 257 | tasklet_schedule(&host->card_tasklet); |
256 | spin_unlock(&host->lock); | 258 | spin_unlock_irqrestore(&host->lock, flags); |
257 | } | 259 | } |
258 | } | 260 | } |
259 | 261 | ||
@@ -481,8 +483,10 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev) | |||
481 | sdhci_remove_host(host, 1); | 483 | sdhci_remove_host(host, 1); |
482 | 484 | ||
483 | for (ptr = 0; ptr < 3; ptr++) { | 485 | for (ptr = 0; ptr < 3; ptr++) { |
484 | clk_disable(sc->clk_bus[ptr]); | 486 | if (sc->clk_bus[ptr]) { |
485 | clk_put(sc->clk_bus[ptr]); | 487 | clk_disable(sc->clk_bus[ptr]); |
488 | clk_put(sc->clk_bus[ptr]); | ||
489 | } | ||
486 | } | 490 | } |
487 | clk_disable(sc->clk_io); | 491 | clk_disable(sc->clk_io); |
488 | clk_put(sc->clk_io); | 492 | clk_put(sc->clk_io); |
diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c index ee7d0a5a51c..69d98e3bf6a 100644 --- a/drivers/mmc/host/tmio_mmc.c +++ b/drivers/mmc/host/tmio_mmc.c | |||
@@ -164,6 +164,7 @@ tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command *cmd) | |||
164 | static void tmio_mmc_pio_irq(struct tmio_mmc_host *host) | 164 | static void tmio_mmc_pio_irq(struct tmio_mmc_host *host) |
165 | { | 165 | { |
166 | struct mmc_data *data = host->data; | 166 | struct mmc_data *data = host->data; |
167 | void *sg_virt; | ||
167 | unsigned short *buf; | 168 | unsigned short *buf; |
168 | unsigned int count; | 169 | unsigned int count; |
169 | unsigned long flags; | 170 | unsigned long flags; |
@@ -173,8 +174,8 @@ static void tmio_mmc_pio_irq(struct tmio_mmc_host *host) | |||
173 | return; | 174 | return; |
174 | } | 175 | } |
175 | 176 | ||
176 | buf = (unsigned short *)(tmio_mmc_kmap_atomic(host, &flags) + | 177 | sg_virt = tmio_mmc_kmap_atomic(host->sg_ptr, &flags); |
177 | host->sg_off); | 178 | buf = (unsigned short *)(sg_virt + host->sg_off); |
178 | 179 | ||
179 | count = host->sg_ptr->length - host->sg_off; | 180 | count = host->sg_ptr->length - host->sg_off; |
180 | if (count > data->blksz) | 181 | if (count > data->blksz) |
@@ -191,7 +192,7 @@ static void tmio_mmc_pio_irq(struct tmio_mmc_host *host) | |||
191 | 192 | ||
192 | host->sg_off += count; | 193 | host->sg_off += count; |
193 | 194 | ||
194 | tmio_mmc_kunmap_atomic(host, &flags); | 195 | tmio_mmc_kunmap_atomic(sg_virt, &flags); |
195 | 196 | ||
196 | if (host->sg_off == host->sg_ptr->length) | 197 | if (host->sg_off == host->sg_ptr->length) |
197 | tmio_mmc_next_sg(host); | 198 | tmio_mmc_next_sg(host); |
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h index 64f7d5dfc10..0fedc78e3ea 100644 --- a/drivers/mmc/host/tmio_mmc.h +++ b/drivers/mmc/host/tmio_mmc.h | |||
@@ -82,10 +82,7 @@ | |||
82 | 82 | ||
83 | #define ack_mmc_irqs(host, i) \ | 83 | #define ack_mmc_irqs(host, i) \ |
84 | do { \ | 84 | do { \ |
85 | u32 mask;\ | 85 | sd_ctrl_write32((host), CTL_STATUS, ~(i)); \ |
86 | mask = sd_ctrl_read32((host), CTL_STATUS); \ | ||
87 | mask &= ~((i) & TMIO_MASK_IRQ); \ | ||
88 | sd_ctrl_write32((host), CTL_STATUS, mask); \ | ||
89 | } while (0) | 86 | } while (0) |
90 | 87 | ||
91 | 88 | ||
@@ -177,19 +174,17 @@ static inline int tmio_mmc_next_sg(struct tmio_mmc_host *host) | |||
177 | return --host->sg_len; | 174 | return --host->sg_len; |
178 | } | 175 | } |
179 | 176 | ||
180 | static inline char *tmio_mmc_kmap_atomic(struct tmio_mmc_host *host, | 177 | static inline char *tmio_mmc_kmap_atomic(struct scatterlist *sg, |
181 | unsigned long *flags) | 178 | unsigned long *flags) |
182 | { | 179 | { |
183 | struct scatterlist *sg = host->sg_ptr; | ||
184 | |||
185 | local_irq_save(*flags); | 180 | local_irq_save(*flags); |
186 | return kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset; | 181 | return kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset; |
187 | } | 182 | } |
188 | 183 | ||
189 | static inline void tmio_mmc_kunmap_atomic(struct tmio_mmc_host *host, | 184 | static inline void tmio_mmc_kunmap_atomic(void *virt, |
190 | unsigned long *flags) | 185 | unsigned long *flags) |
191 | { | 186 | { |
192 | kunmap_atomic(sg_page(host->sg_ptr), KM_BIO_SRC_IRQ); | 187 | kunmap_atomic(virt, KM_BIO_SRC_IRQ); |
193 | local_irq_restore(*flags); | 188 | local_irq_restore(*flags); |
194 | } | 189 | } |
195 | 190 | ||
diff --git a/drivers/mtd/nand/bf5xx_nand.c b/drivers/mtd/nand/bf5xx_nand.c index a382e3dd0a5..6fbeefa3a76 100644 --- a/drivers/mtd/nand/bf5xx_nand.c +++ b/drivers/mtd/nand/bf5xx_nand.c | |||
@@ -682,7 +682,6 @@ static int __devinit bf5xx_nand_add_partition(struct bf5xx_nand_info *info) | |||
682 | static int __devexit bf5xx_nand_remove(struct platform_device *pdev) | 682 | static int __devexit bf5xx_nand_remove(struct platform_device *pdev) |
683 | { | 683 | { |
684 | struct bf5xx_nand_info *info = to_nand_info(pdev); | 684 | struct bf5xx_nand_info *info = to_nand_info(pdev); |
685 | struct mtd_info *mtd = NULL; | ||
686 | 685 | ||
687 | platform_set_drvdata(pdev, NULL); | 686 | platform_set_drvdata(pdev, NULL); |
688 | 687 | ||
@@ -690,11 +689,7 @@ static int __devexit bf5xx_nand_remove(struct platform_device *pdev) | |||
690 | * and their partitions, then go through freeing the | 689 | * and their partitions, then go through freeing the |
691 | * resources used | 690 | * resources used |
692 | */ | 691 | */ |
693 | mtd = &info->mtd; | 692 | nand_release(&info->mtd); |
694 | if (mtd) { | ||
695 | nand_release(mtd); | ||
696 | kfree(mtd); | ||
697 | } | ||
698 | 693 | ||
699 | peripheral_free_list(bfin_nfc_pin_req); | 694 | peripheral_free_list(bfin_nfc_pin_req); |
700 | bf5xx_nand_dma_remove(info); | 695 | bf5xx_nand_dma_remove(info); |
@@ -710,7 +705,7 @@ static int bf5xx_nand_scan(struct mtd_info *mtd) | |||
710 | struct nand_chip *chip = mtd->priv; | 705 | struct nand_chip *chip = mtd->priv; |
711 | int ret; | 706 | int ret; |
712 | 707 | ||
713 | ret = nand_scan_ident(mtd, 1); | 708 | ret = nand_scan_ident(mtd, 1, NULL); |
714 | if (ret) | 709 | if (ret) |
715 | return ret; | 710 | return ret; |
716 | 711 | ||
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index fcf8ceb277d..b2828e84d24 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c | |||
@@ -67,7 +67,9 @@ | |||
67 | #define NFC_V1_V2_CONFIG1_BIG (1 << 5) | 67 | #define NFC_V1_V2_CONFIG1_BIG (1 << 5) |
68 | #define NFC_V1_V2_CONFIG1_RST (1 << 6) | 68 | #define NFC_V1_V2_CONFIG1_RST (1 << 6) |
69 | #define NFC_V1_V2_CONFIG1_CE (1 << 7) | 69 | #define NFC_V1_V2_CONFIG1_CE (1 << 7) |
70 | #define NFC_V1_V2_CONFIG1_ONE_CYCLE (1 << 8) | 70 | #define NFC_V2_CONFIG1_ONE_CYCLE (1 << 8) |
71 | #define NFC_V2_CONFIG1_PPB(x) (((x) & 0x3) << 9) | ||
72 | #define NFC_V2_CONFIG1_FP_INT (1 << 11) | ||
71 | 73 | ||
72 | #define NFC_V1_V2_CONFIG2_INT (1 << 15) | 74 | #define NFC_V1_V2_CONFIG2_INT (1 << 15) |
73 | 75 | ||
@@ -402,16 +404,16 @@ static void send_read_id_v1_v2(struct mxc_nand_host *host) | |||
402 | /* Wait for operation to complete */ | 404 | /* Wait for operation to complete */ |
403 | wait_op_done(host, true); | 405 | wait_op_done(host, true); |
404 | 406 | ||
407 | memcpy(host->data_buf, host->main_area0, 16); | ||
408 | |||
405 | if (this->options & NAND_BUSWIDTH_16) { | 409 | if (this->options & NAND_BUSWIDTH_16) { |
406 | void __iomem *main_buf = host->main_area0; | ||
407 | /* compress the ID info */ | 410 | /* compress the ID info */ |
408 | writeb(readb(main_buf + 2), main_buf + 1); | 411 | host->data_buf[1] = host->data_buf[2]; |
409 | writeb(readb(main_buf + 4), main_buf + 2); | 412 | host->data_buf[2] = host->data_buf[4]; |
410 | writeb(readb(main_buf + 6), main_buf + 3); | 413 | host->data_buf[3] = host->data_buf[6]; |
411 | writeb(readb(main_buf + 8), main_buf + 4); | 414 | host->data_buf[4] = host->data_buf[8]; |
412 | writeb(readb(main_buf + 10), main_buf + 5); | 415 | host->data_buf[5] = host->data_buf[10]; |
413 | } | 416 | } |
414 | memcpy(host->data_buf, host->main_area0, 16); | ||
415 | } | 417 | } |
416 | 418 | ||
417 | static uint16_t get_dev_status_v3(struct mxc_nand_host *host) | 419 | static uint16_t get_dev_status_v3(struct mxc_nand_host *host) |
@@ -729,27 +731,30 @@ static void preset_v1_v2(struct mtd_info *mtd) | |||
729 | { | 731 | { |
730 | struct nand_chip *nand_chip = mtd->priv; | 732 | struct nand_chip *nand_chip = mtd->priv; |
731 | struct mxc_nand_host *host = nand_chip->priv; | 733 | struct mxc_nand_host *host = nand_chip->priv; |
732 | uint16_t tmp; | 734 | uint16_t config1 = 0; |
733 | 735 | ||
734 | /* enable interrupt, disable spare enable */ | 736 | if (nand_chip->ecc.mode == NAND_ECC_HW) |
735 | tmp = readw(NFC_V1_V2_CONFIG1); | 737 | config1 |= NFC_V1_V2_CONFIG1_ECC_EN; |
736 | tmp &= ~NFC_V1_V2_CONFIG1_INT_MSK; | 738 | |
737 | tmp &= ~NFC_V1_V2_CONFIG1_SP_EN; | 739 | if (nfc_is_v21()) |
738 | if (nand_chip->ecc.mode == NAND_ECC_HW) { | 740 | config1 |= NFC_V2_CONFIG1_FP_INT; |
739 | tmp |= NFC_V1_V2_CONFIG1_ECC_EN; | 741 | |
740 | } else { | 742 | if (!cpu_is_mx21()) |
741 | tmp &= ~NFC_V1_V2_CONFIG1_ECC_EN; | 743 | config1 |= NFC_V1_V2_CONFIG1_INT_MSK; |
742 | } | ||
743 | 744 | ||
744 | if (nfc_is_v21() && mtd->writesize) { | 745 | if (nfc_is_v21() && mtd->writesize) { |
746 | uint16_t pages_per_block = mtd->erasesize / mtd->writesize; | ||
747 | |||
745 | host->eccsize = get_eccsize(mtd); | 748 | host->eccsize = get_eccsize(mtd); |
746 | if (host->eccsize == 4) | 749 | if (host->eccsize == 4) |
747 | tmp |= NFC_V2_CONFIG1_ECC_MODE_4; | 750 | config1 |= NFC_V2_CONFIG1_ECC_MODE_4; |
751 | |||
752 | config1 |= NFC_V2_CONFIG1_PPB(ffs(pages_per_block) - 6); | ||
748 | } else { | 753 | } else { |
749 | host->eccsize = 1; | 754 | host->eccsize = 1; |
750 | } | 755 | } |
751 | 756 | ||
752 | writew(tmp, NFC_V1_V2_CONFIG1); | 757 | writew(config1, NFC_V1_V2_CONFIG1); |
753 | /* preset operation */ | 758 | /* preset operation */ |
754 | 759 | ||
755 | /* Unlock the internal RAM Buffer */ | 760 | /* Unlock the internal RAM Buffer */ |
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 133d51528f8..513e0a76a4a 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c | |||
@@ -413,7 +413,7 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, | |||
413 | prefetch_status = gpmc_read_status(GPMC_PREFETCH_COUNT); | 413 | prefetch_status = gpmc_read_status(GPMC_PREFETCH_COUNT); |
414 | } while (prefetch_status); | 414 | } while (prefetch_status); |
415 | /* disable and stop the PFPW engine */ | 415 | /* disable and stop the PFPW engine */ |
416 | gpmc_prefetch_reset(); | 416 | gpmc_prefetch_reset(info->gpmc_cs); |
417 | 417 | ||
418 | dma_unmap_single(&info->pdev->dev, dma_addr, len, dir); | 418 | dma_unmap_single(&info->pdev->dev, dma_addr, len, dir); |
419 | return 0; | 419 | return 0; |
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index 4d89f378020..4d01cda6884 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c | |||
@@ -1320,6 +1320,7 @@ static int pxa3xx_nand_probe(struct platform_device *pdev) | |||
1320 | goto fail_free_irq; | 1320 | goto fail_free_irq; |
1321 | } | 1321 | } |
1322 | 1322 | ||
1323 | #ifdef CONFIG_MTD_PARTITIONS | ||
1323 | if (mtd_has_cmdlinepart()) { | 1324 | if (mtd_has_cmdlinepart()) { |
1324 | static const char *probes[] = { "cmdlinepart", NULL }; | 1325 | static const char *probes[] = { "cmdlinepart", NULL }; |
1325 | struct mtd_partition *parts; | 1326 | struct mtd_partition *parts; |
@@ -1332,6 +1333,9 @@ static int pxa3xx_nand_probe(struct platform_device *pdev) | |||
1332 | } | 1333 | } |
1333 | 1334 | ||
1334 | return add_mtd_partitions(mtd, pdata->parts, pdata->nr_parts); | 1335 | return add_mtd_partitions(mtd, pdata->parts, pdata->nr_parts); |
1336 | #else | ||
1337 | return 0; | ||
1338 | #endif | ||
1335 | 1339 | ||
1336 | fail_free_irq: | 1340 | fail_free_irq: |
1337 | free_irq(irq, info); | 1341 | free_irq(irq, info); |
@@ -1364,7 +1368,9 @@ static int pxa3xx_nand_remove(struct platform_device *pdev) | |||
1364 | platform_set_drvdata(pdev, NULL); | 1368 | platform_set_drvdata(pdev, NULL); |
1365 | 1369 | ||
1366 | del_mtd_device(mtd); | 1370 | del_mtd_device(mtd); |
1371 | #ifdef CONFIG_MTD_PARTITIONS | ||
1367 | del_mtd_partitions(mtd); | 1372 | del_mtd_partitions(mtd); |
1373 | #endif | ||
1368 | irq = platform_get_irq(pdev, 0); | 1374 | irq = platform_get_irq(pdev, 0); |
1369 | if (irq >= 0) | 1375 | if (irq >= 0) |
1370 | free_irq(irq, info); | 1376 | free_irq(irq, info); |
diff --git a/drivers/mtd/onenand/samsung.c b/drivers/mtd/onenand/samsung.c index cb443af3d45..a460f1b748c 100644 --- a/drivers/mtd/onenand/samsung.c +++ b/drivers/mtd/onenand/samsung.c | |||
@@ -554,14 +554,13 @@ static int s5pc110_dma_ops(void *dst, void *src, size_t count, int direction) | |||
554 | 554 | ||
555 | do { | 555 | do { |
556 | status = readl(base + S5PC110_DMA_TRANS_STATUS); | 556 | status = readl(base + S5PC110_DMA_TRANS_STATUS); |
557 | if (status & S5PC110_DMA_TRANS_STATUS_TE) { | ||
558 | writel(S5PC110_DMA_TRANS_CMD_TEC, | ||
559 | base + S5PC110_DMA_TRANS_CMD); | ||
560 | return -EIO; | ||
561 | } | ||
557 | } while (!(status & S5PC110_DMA_TRANS_STATUS_TD)); | 562 | } while (!(status & S5PC110_DMA_TRANS_STATUS_TD)); |
558 | 563 | ||
559 | if (status & S5PC110_DMA_TRANS_STATUS_TE) { | ||
560 | writel(S5PC110_DMA_TRANS_CMD_TEC, base + S5PC110_DMA_TRANS_CMD); | ||
561 | writel(S5PC110_DMA_TRANS_CMD_TDC, base + S5PC110_DMA_TRANS_CMD); | ||
562 | return -EIO; | ||
563 | } | ||
564 | |||
565 | writel(S5PC110_DMA_TRANS_CMD_TDC, base + S5PC110_DMA_TRANS_CMD); | 564 | writel(S5PC110_DMA_TRANS_CMD_TDC, base + S5PC110_DMA_TRANS_CMD); |
566 | 565 | ||
567 | return 0; | 566 | return 0; |
@@ -571,13 +570,12 @@ static int s5pc110_read_bufferram(struct mtd_info *mtd, int area, | |||
571 | unsigned char *buffer, int offset, size_t count) | 570 | unsigned char *buffer, int offset, size_t count) |
572 | { | 571 | { |
573 | struct onenand_chip *this = mtd->priv; | 572 | struct onenand_chip *this = mtd->priv; |
574 | void __iomem *bufferram; | ||
575 | void __iomem *p; | 573 | void __iomem *p; |
576 | void *buf = (void *) buffer; | 574 | void *buf = (void *) buffer; |
577 | dma_addr_t dma_src, dma_dst; | 575 | dma_addr_t dma_src, dma_dst; |
578 | int err; | 576 | int err; |
579 | 577 | ||
580 | p = bufferram = this->base + area; | 578 | p = this->base + area; |
581 | if (ONENAND_CURRENT_BUFFERRAM(this)) { | 579 | if (ONENAND_CURRENT_BUFFERRAM(this)) { |
582 | if (area == ONENAND_DATARAM) | 580 | if (area == ONENAND_DATARAM) |
583 | p += this->writesize; | 581 | p += this->writesize; |
@@ -621,7 +619,7 @@ static int s5pc110_read_bufferram(struct mtd_info *mtd, int area, | |||
621 | normal: | 619 | normal: |
622 | if (count != mtd->writesize) { | 620 | if (count != mtd->writesize) { |
623 | /* Copy the bufferram to memory to prevent unaligned access */ | 621 | /* Copy the bufferram to memory to prevent unaligned access */ |
624 | memcpy(this->page_buf, bufferram, mtd->writesize); | 622 | memcpy(this->page_buf, p, mtd->writesize); |
625 | p = this->page_buf + offset; | 623 | p = this->page_buf + offset; |
626 | } | 624 | } |
627 | 625 | ||
diff --git a/drivers/mtd/ubi/Kconfig.debug b/drivers/mtd/ubi/Kconfig.debug index 2246f154e2f..61f6e5e4045 100644 --- a/drivers/mtd/ubi/Kconfig.debug +++ b/drivers/mtd/ubi/Kconfig.debug | |||
@@ -6,7 +6,7 @@ config MTD_UBI_DEBUG | |||
6 | depends on SYSFS | 6 | depends on SYSFS |
7 | depends on MTD_UBI | 7 | depends on MTD_UBI |
8 | select DEBUG_FS | 8 | select DEBUG_FS |
9 | select KALLSYMS_ALL | 9 | select KALLSYMS_ALL if KALLSYMS && DEBUG_KERNEL |
10 | help | 10 | help |
11 | This option enables UBI debugging. | 11 | This option enables UBI debugging. |
12 | 12 | ||
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index 4dfa6b90c21..3d2d1a69e9a 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c | |||
@@ -798,18 +798,18 @@ static int rename_volumes(struct ubi_device *ubi, | |||
798 | goto out_free; | 798 | goto out_free; |
799 | } | 799 | } |
800 | 800 | ||
801 | re = kzalloc(sizeof(struct ubi_rename_entry), GFP_KERNEL); | 801 | re1 = kzalloc(sizeof(struct ubi_rename_entry), GFP_KERNEL); |
802 | if (!re) { | 802 | if (!re1) { |
803 | err = -ENOMEM; | 803 | err = -ENOMEM; |
804 | ubi_close_volume(desc); | 804 | ubi_close_volume(desc); |
805 | goto out_free; | 805 | goto out_free; |
806 | } | 806 | } |
807 | 807 | ||
808 | re->remove = 1; | 808 | re1->remove = 1; |
809 | re->desc = desc; | 809 | re1->desc = desc; |
810 | list_add(&re->list, &rename_list); | 810 | list_add(&re1->list, &rename_list); |
811 | dbg_msg("will remove volume %d, name \"%s\"", | 811 | dbg_msg("will remove volume %d, name \"%s\"", |
812 | re->desc->vol->vol_id, re->desc->vol->name); | 812 | re1->desc->vol->vol_id, re1->desc->vol->name); |
813 | } | 813 | } |
814 | 814 | ||
815 | mutex_lock(&ubi->device_mutex); | 815 | mutex_lock(&ubi->device_mutex); |
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index 372a15ac999..69b52e9c948 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c | |||
@@ -843,7 +843,7 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, | |||
843 | case UBI_COMPAT_DELETE: | 843 | case UBI_COMPAT_DELETE: |
844 | ubi_msg("\"delete\" compatible internal volume %d:%d" | 844 | ubi_msg("\"delete\" compatible internal volume %d:%d" |
845 | " found, will remove it", vol_id, lnum); | 845 | " found, will remove it", vol_id, lnum); |
846 | err = add_to_list(si, pnum, ec, &si->corr); | 846 | err = add_to_list(si, pnum, ec, &si->erase); |
847 | if (err) | 847 | if (err) |
848 | return err; | 848 | return err; |
849 | return 0; | 849 | return 0; |
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index ee7b1d8fbb9..97a435672ea 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c | |||
@@ -1212,7 +1212,8 @@ int ubi_wl_scrub_peb(struct ubi_device *ubi, int pnum) | |||
1212 | retry: | 1212 | retry: |
1213 | spin_lock(&ubi->wl_lock); | 1213 | spin_lock(&ubi->wl_lock); |
1214 | e = ubi->lookuptbl[pnum]; | 1214 | e = ubi->lookuptbl[pnum]; |
1215 | if (e == ubi->move_from || in_wl_tree(e, &ubi->scrub)) { | 1215 | if (e == ubi->move_from || in_wl_tree(e, &ubi->scrub) || |
1216 | in_wl_tree(e, &ubi->erroneous)) { | ||
1216 | spin_unlock(&ubi->wl_lock); | 1217 | spin_unlock(&ubi->wl_lock); |
1217 | return 0; | 1218 | return 0; |
1218 | } | 1219 | } |
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index c754d88e5ec..179871d9e71 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c | |||
@@ -633,7 +633,11 @@ struct vortex_private { | |||
633 | open:1, | 633 | open:1, |
634 | medialock:1, | 634 | medialock:1, |
635 | must_free_region:1, /* Flag: if zero, Cardbus owns the I/O region */ | 635 | must_free_region:1, /* Flag: if zero, Cardbus owns the I/O region */ |
636 | large_frames:1; /* accept large frames */ | 636 | large_frames:1, /* accept large frames */ |
637 | handling_irq:1; /* private in_irq indicator */ | ||
638 | /* {get|set}_wol operations are already serialized by rtnl. | ||
639 | * no additional locking is required for the enable_wol and acpi_set_WOL() | ||
640 | */ | ||
637 | int drv_flags; | 641 | int drv_flags; |
638 | u16 status_enable; | 642 | u16 status_enable; |
639 | u16 intr_enable; | 643 | u16 intr_enable; |
@@ -646,7 +650,7 @@ struct vortex_private { | |||
646 | u16 io_size; /* Size of PCI region (for release_region) */ | 650 | u16 io_size; /* Size of PCI region (for release_region) */ |
647 | 651 | ||
648 | /* Serialises access to hardware other than MII and variables below. | 652 | /* Serialises access to hardware other than MII and variables below. |
649 | * The lock hierarchy is rtnl_lock > lock > mii_lock > window_lock. */ | 653 | * The lock hierarchy is rtnl_lock > {lock, mii_lock} > window_lock. */ |
650 | spinlock_t lock; | 654 | spinlock_t lock; |
651 | 655 | ||
652 | spinlock_t mii_lock; /* Serialises access to MII */ | 656 | spinlock_t mii_lock; /* Serialises access to MII */ |
@@ -1993,10 +1997,9 @@ vortex_error(struct net_device *dev, int status) | |||
1993 | } | 1997 | } |
1994 | } | 1998 | } |
1995 | 1999 | ||
1996 | if (status & RxEarly) { /* Rx early is unused. */ | 2000 | if (status & RxEarly) /* Rx early is unused. */ |
1997 | vortex_rx(dev); | ||
1998 | iowrite16(AckIntr | RxEarly, ioaddr + EL3_CMD); | 2001 | iowrite16(AckIntr | RxEarly, ioaddr + EL3_CMD); |
1999 | } | 2002 | |
2000 | if (status & StatsFull) { /* Empty statistics. */ | 2003 | if (status & StatsFull) { /* Empty statistics. */ |
2001 | static int DoneDidThat; | 2004 | static int DoneDidThat; |
2002 | if (vortex_debug > 4) | 2005 | if (vortex_debug > 4) |
@@ -2133,6 +2136,15 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2133 | dev->name, vp->cur_tx); | 2136 | dev->name, vp->cur_tx); |
2134 | } | 2137 | } |
2135 | 2138 | ||
2139 | /* | ||
2140 | * We can't allow a recursion from our interrupt handler back into the | ||
2141 | * tx routine, as they take the same spin lock, and that causes | ||
2142 | * deadlock. Just return NETDEV_TX_BUSY and let the stack try again in | ||
2143 | * a bit | ||
2144 | */ | ||
2145 | if (vp->handling_irq) | ||
2146 | return NETDEV_TX_BUSY; | ||
2147 | |||
2136 | if (vp->cur_tx - vp->dirty_tx >= TX_RING_SIZE) { | 2148 | if (vp->cur_tx - vp->dirty_tx >= TX_RING_SIZE) { |
2137 | if (vortex_debug > 0) | 2149 | if (vortex_debug > 0) |
2138 | pr_warning("%s: BUG! Tx Ring full, refusing to send buffer.\n", | 2150 | pr_warning("%s: BUG! Tx Ring full, refusing to send buffer.\n", |
@@ -2288,7 +2300,12 @@ vortex_interrupt(int irq, void *dev_id) | |||
2288 | if (status & (HostError | RxEarly | StatsFull | TxComplete | IntReq)) { | 2300 | if (status & (HostError | RxEarly | StatsFull | TxComplete | IntReq)) { |
2289 | if (status == 0xffff) | 2301 | if (status == 0xffff) |
2290 | break; | 2302 | break; |
2303 | if (status & RxEarly) | ||
2304 | vortex_rx(dev); | ||
2305 | spin_unlock(&vp->window_lock); | ||
2291 | vortex_error(dev, status); | 2306 | vortex_error(dev, status); |
2307 | spin_lock(&vp->window_lock); | ||
2308 | window_set(vp, 7); | ||
2292 | } | 2309 | } |
2293 | 2310 | ||
2294 | if (--work_done < 0) { | 2311 | if (--work_done < 0) { |
@@ -2335,11 +2352,13 @@ boomerang_interrupt(int irq, void *dev_id) | |||
2335 | 2352 | ||
2336 | ioaddr = vp->ioaddr; | 2353 | ioaddr = vp->ioaddr; |
2337 | 2354 | ||
2355 | |||
2338 | /* | 2356 | /* |
2339 | * It seems dopey to put the spinlock this early, but we could race against vortex_tx_timeout | 2357 | * It seems dopey to put the spinlock this early, but we could race against vortex_tx_timeout |
2340 | * and boomerang_start_xmit | 2358 | * and boomerang_start_xmit |
2341 | */ | 2359 | */ |
2342 | spin_lock(&vp->lock); | 2360 | spin_lock(&vp->lock); |
2361 | vp->handling_irq = 1; | ||
2343 | 2362 | ||
2344 | status = ioread16(ioaddr + EL3_STATUS); | 2363 | status = ioread16(ioaddr + EL3_STATUS); |
2345 | 2364 | ||
@@ -2447,6 +2466,7 @@ boomerang_interrupt(int irq, void *dev_id) | |||
2447 | pr_debug("%s: exiting interrupt, status %4.4x.\n", | 2466 | pr_debug("%s: exiting interrupt, status %4.4x.\n", |
2448 | dev->name, status); | 2467 | dev->name, status); |
2449 | handler_exit: | 2468 | handler_exit: |
2469 | vp->handling_irq = 0; | ||
2450 | spin_unlock(&vp->lock); | 2470 | spin_unlock(&vp->lock); |
2451 | return IRQ_HANDLED; | 2471 | return IRQ_HANDLED; |
2452 | } | 2472 | } |
@@ -2922,28 +2942,31 @@ static void vortex_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | |||
2922 | { | 2942 | { |
2923 | struct vortex_private *vp = netdev_priv(dev); | 2943 | struct vortex_private *vp = netdev_priv(dev); |
2924 | 2944 | ||
2925 | spin_lock_irq(&vp->lock); | 2945 | if (!VORTEX_PCI(vp)) |
2946 | return; | ||
2947 | |||
2926 | wol->supported = WAKE_MAGIC; | 2948 | wol->supported = WAKE_MAGIC; |
2927 | 2949 | ||
2928 | wol->wolopts = 0; | 2950 | wol->wolopts = 0; |
2929 | if (vp->enable_wol) | 2951 | if (vp->enable_wol) |
2930 | wol->wolopts |= WAKE_MAGIC; | 2952 | wol->wolopts |= WAKE_MAGIC; |
2931 | spin_unlock_irq(&vp->lock); | ||
2932 | } | 2953 | } |
2933 | 2954 | ||
2934 | static int vortex_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | 2955 | static int vortex_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) |
2935 | { | 2956 | { |
2936 | struct vortex_private *vp = netdev_priv(dev); | 2957 | struct vortex_private *vp = netdev_priv(dev); |
2958 | |||
2959 | if (!VORTEX_PCI(vp)) | ||
2960 | return -EOPNOTSUPP; | ||
2961 | |||
2937 | if (wol->wolopts & ~WAKE_MAGIC) | 2962 | if (wol->wolopts & ~WAKE_MAGIC) |
2938 | return -EINVAL; | 2963 | return -EINVAL; |
2939 | 2964 | ||
2940 | spin_lock_irq(&vp->lock); | ||
2941 | if (wol->wolopts & WAKE_MAGIC) | 2965 | if (wol->wolopts & WAKE_MAGIC) |
2942 | vp->enable_wol = 1; | 2966 | vp->enable_wol = 1; |
2943 | else | 2967 | else |
2944 | vp->enable_wol = 0; | 2968 | vp->enable_wol = 0; |
2945 | acpi_set_WOL(dev); | 2969 | acpi_set_WOL(dev); |
2946 | spin_unlock_irq(&vp->lock); | ||
2947 | 2970 | ||
2948 | return 0; | 2971 | return 0; |
2949 | } | 2972 | } |
@@ -2971,7 +2994,6 @@ static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
2971 | { | 2994 | { |
2972 | int err; | 2995 | int err; |
2973 | struct vortex_private *vp = netdev_priv(dev); | 2996 | struct vortex_private *vp = netdev_priv(dev); |
2974 | unsigned long flags; | ||
2975 | pci_power_t state = 0; | 2997 | pci_power_t state = 0; |
2976 | 2998 | ||
2977 | if(VORTEX_PCI(vp)) | 2999 | if(VORTEX_PCI(vp)) |
@@ -2981,9 +3003,7 @@ static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
2981 | 3003 | ||
2982 | if(state != 0) | 3004 | if(state != 0) |
2983 | pci_set_power_state(VORTEX_PCI(vp), PCI_D0); | 3005 | pci_set_power_state(VORTEX_PCI(vp), PCI_D0); |
2984 | spin_lock_irqsave(&vp->lock, flags); | ||
2985 | err = generic_mii_ioctl(&vp->mii, if_mii(rq), cmd, NULL); | 3006 | err = generic_mii_ioctl(&vp->mii, if_mii(rq), cmd, NULL); |
2986 | spin_unlock_irqrestore(&vp->lock, flags); | ||
2987 | if(state != 0) | 3007 | if(state != 0) |
2988 | pci_set_power_state(VORTEX_PCI(vp), state); | 3008 | pci_set_power_state(VORTEX_PCI(vp), state); |
2989 | 3009 | ||
@@ -3188,6 +3208,9 @@ static void acpi_set_WOL(struct net_device *dev) | |||
3188 | return; | 3208 | return; |
3189 | } | 3209 | } |
3190 | 3210 | ||
3211 | if (VORTEX_PCI(vp)->current_state < PCI_D3hot) | ||
3212 | return; | ||
3213 | |||
3191 | /* Change the power state to D3; RxEnable doesn't take effect. */ | 3214 | /* Change the power state to D3; RxEnable doesn't take effect. */ |
3192 | pci_set_power_state(VORTEX_PCI(vp), PCI_D3hot); | 3215 | pci_set_power_state(VORTEX_PCI(vp), PCI_D3hot); |
3193 | } | 3216 | } |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 5a6895320b4..5db667c0b37 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -928,6 +928,16 @@ config SMC91X | |||
928 | The module will be called smc91x. If you want to compile it as a | 928 | The module will be called smc91x. If you want to compile it as a |
929 | module, say M here and read <file:Documentation/kbuild/modules.txt>. | 929 | module, say M here and read <file:Documentation/kbuild/modules.txt>. |
930 | 930 | ||
931 | config PXA168_ETH | ||
932 | tristate "Marvell pxa168 ethernet support" | ||
933 | depends on CPU_PXA168 | ||
934 | select PHYLIB | ||
935 | help | ||
936 | This driver supports the pxa168 Ethernet ports. | ||
937 | |||
938 | To compile this driver as a module, choose M here. The module | ||
939 | will be called pxa168_eth. | ||
940 | |||
931 | config NET_NETX | 941 | config NET_NETX |
932 | tristate "NetX Ethernet support" | 942 | tristate "NetX Ethernet support" |
933 | select MII | 943 | select MII |
@@ -2418,7 +2428,7 @@ config UGETH_TX_ON_DEMAND | |||
2418 | 2428 | ||
2419 | config MV643XX_ETH | 2429 | config MV643XX_ETH |
2420 | tristate "Marvell Discovery (643XX) and Orion ethernet support" | 2430 | tristate "Marvell Discovery (643XX) and Orion ethernet support" |
2421 | depends on MV64X60 || PPC32 || PLAT_ORION | 2431 | depends on (MV64X60 || PPC32 || PLAT_ORION) && INET |
2422 | select INET_LRO | 2432 | select INET_LRO |
2423 | select PHYLIB | 2433 | select PHYLIB |
2424 | help | 2434 | help |
@@ -2793,7 +2803,7 @@ config NIU | |||
2793 | 2803 | ||
2794 | config PASEMI_MAC | 2804 | config PASEMI_MAC |
2795 | tristate "PA Semi 1/10Gbit MAC" | 2805 | tristate "PA Semi 1/10Gbit MAC" |
2796 | depends on PPC_PASEMI && PCI | 2806 | depends on PPC_PASEMI && PCI && INET |
2797 | select PHYLIB | 2807 | select PHYLIB |
2798 | select INET_LRO | 2808 | select INET_LRO |
2799 | help | 2809 | help |
diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 56e8c27f77c..3e8f150c4b1 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile | |||
@@ -244,6 +244,7 @@ obj-$(CONFIG_MYRI10GE) += myri10ge/ | |||
244 | obj-$(CONFIG_SMC91X) += smc91x.o | 244 | obj-$(CONFIG_SMC91X) += smc91x.o |
245 | obj-$(CONFIG_SMC911X) += smc911x.o | 245 | obj-$(CONFIG_SMC911X) += smc911x.o |
246 | obj-$(CONFIG_SMSC911X) += smsc911x.o | 246 | obj-$(CONFIG_SMSC911X) += smsc911x.o |
247 | obj-$(CONFIG_PXA168_ETH) += pxa168_eth.o | ||
247 | obj-$(CONFIG_BFIN_MAC) += bfin_mac.o | 248 | obj-$(CONFIG_BFIN_MAC) += bfin_mac.o |
248 | obj-$(CONFIG_DM9000) += dm9000.o | 249 | obj-$(CONFIG_DM9000) += dm9000.o |
249 | obj-$(CONFIG_PASEMI_MAC) += pasemi_mac_driver.o | 250 | obj-$(CONFIG_PASEMI_MAC) += pasemi_mac_driver.o |
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index 63b9ba0cc67..c73be284831 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c | |||
@@ -1251,6 +1251,12 @@ static void atl1_free_ring_resources(struct atl1_adapter *adapter) | |||
1251 | 1251 | ||
1252 | rrd_ring->desc = NULL; | 1252 | rrd_ring->desc = NULL; |
1253 | rrd_ring->dma = 0; | 1253 | rrd_ring->dma = 0; |
1254 | |||
1255 | adapter->cmb.dma = 0; | ||
1256 | adapter->cmb.cmb = NULL; | ||
1257 | |||
1258 | adapter->smb.dma = 0; | ||
1259 | adapter->smb.smb = NULL; | ||
1254 | } | 1260 | } |
1255 | 1261 | ||
1256 | static void atl1_setup_mac_ctrl(struct atl1_adapter *adapter) | 1262 | static void atl1_setup_mac_ctrl(struct atl1_adapter *adapter) |
@@ -2847,10 +2853,11 @@ static int atl1_resume(struct pci_dev *pdev) | |||
2847 | pci_enable_wake(pdev, PCI_D3cold, 0); | 2853 | pci_enable_wake(pdev, PCI_D3cold, 0); |
2848 | 2854 | ||
2849 | atl1_reset_hw(&adapter->hw); | 2855 | atl1_reset_hw(&adapter->hw); |
2850 | adapter->cmb.cmb->int_stats = 0; | ||
2851 | 2856 | ||
2852 | if (netif_running(netdev)) | 2857 | if (netif_running(netdev)) { |
2858 | adapter->cmb.cmb->int_stats = 0; | ||
2853 | atl1_up(adapter); | 2859 | atl1_up(adapter); |
2860 | } | ||
2854 | netif_device_attach(netdev); | 2861 | netif_device_attach(netdev); |
2855 | 2862 | ||
2856 | return 0; | 2863 | return 0; |
diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 37617abc164..efeffdf9e5f 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c | |||
@@ -848,6 +848,15 @@ static int b44_poll(struct napi_struct *napi, int budget) | |||
848 | b44_tx(bp); | 848 | b44_tx(bp); |
849 | /* spin_unlock(&bp->tx_lock); */ | 849 | /* spin_unlock(&bp->tx_lock); */ |
850 | } | 850 | } |
851 | if (bp->istat & ISTAT_RFO) { /* fast recovery, in ~20msec */ | ||
852 | bp->istat &= ~ISTAT_RFO; | ||
853 | b44_disable_ints(bp); | ||
854 | ssb_device_enable(bp->sdev, 0); /* resets ISTAT_RFO */ | ||
855 | b44_init_rings(bp); | ||
856 | b44_init_hw(bp, B44_FULL_RESET_SKIP_PHY); | ||
857 | netif_wake_queue(bp->dev); | ||
858 | } | ||
859 | |||
851 | spin_unlock_irqrestore(&bp->lock, flags); | 860 | spin_unlock_irqrestore(&bp->lock, flags); |
852 | 861 | ||
853 | work_done = 0; | 862 | work_done = 0; |
@@ -2161,8 +2170,6 @@ static int __devinit b44_init_one(struct ssb_device *sdev, | |||
2161 | dev->irq = sdev->irq; | 2170 | dev->irq = sdev->irq; |
2162 | SET_ETHTOOL_OPS(dev, &b44_ethtool_ops); | 2171 | SET_ETHTOOL_OPS(dev, &b44_ethtool_ops); |
2163 | 2172 | ||
2164 | netif_carrier_off(dev); | ||
2165 | |||
2166 | err = ssb_bus_powerup(sdev->bus, 0); | 2173 | err = ssb_bus_powerup(sdev->bus, 0); |
2167 | if (err) { | 2174 | if (err) { |
2168 | dev_err(sdev->dev, | 2175 | dev_err(sdev->dev, |
@@ -2204,6 +2211,8 @@ static int __devinit b44_init_one(struct ssb_device *sdev, | |||
2204 | goto err_out_powerdown; | 2211 | goto err_out_powerdown; |
2205 | } | 2212 | } |
2206 | 2213 | ||
2214 | netif_carrier_off(dev); | ||
2215 | |||
2207 | ssb_set_drvdata(sdev, dev); | 2216 | ssb_set_drvdata(sdev, dev); |
2208 | 2217 | ||
2209 | /* Chip reset provides power to the b44 MAC & PCI cores, which | 2218 | /* Chip reset provides power to the b44 MAC & PCI cores, which |
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 99197bd54da..53306bf3f40 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h | |||
@@ -181,6 +181,7 @@ struct be_drvr_stats { | |||
181 | u64 be_rx_bytes_prev; | 181 | u64 be_rx_bytes_prev; |
182 | u64 be_rx_pkts; | 182 | u64 be_rx_pkts; |
183 | u32 be_rx_rate; | 183 | u32 be_rx_rate; |
184 | u32 be_rx_mcast_pkt; | ||
184 | /* number of non ether type II frames dropped where | 185 | /* number of non ether type II frames dropped where |
185 | * frame len > length field of Mac Hdr */ | 186 | * frame len > length field of Mac Hdr */ |
186 | u32 be_802_3_dropped_frames; | 187 | u32 be_802_3_dropped_frames; |
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 3d305494a60..34abcc9403d 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c | |||
@@ -140,10 +140,8 @@ int be_process_mcc(struct be_adapter *adapter, int *status) | |||
140 | while ((compl = be_mcc_compl_get(adapter))) { | 140 | while ((compl = be_mcc_compl_get(adapter))) { |
141 | if (compl->flags & CQE_FLAGS_ASYNC_MASK) { | 141 | if (compl->flags & CQE_FLAGS_ASYNC_MASK) { |
142 | /* Interpret flags as an async trailer */ | 142 | /* Interpret flags as an async trailer */ |
143 | BUG_ON(!is_link_state_evt(compl->flags)); | 143 | if (is_link_state_evt(compl->flags)) |
144 | 144 | be_async_link_state_process(adapter, | |
145 | /* Interpret compl as a async link evt */ | ||
146 | be_async_link_state_process(adapter, | ||
147 | (struct be_async_event_link_state *) compl); | 145 | (struct be_async_event_link_state *) compl); |
148 | } else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) { | 146 | } else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) { |
149 | *status = be_mcc_compl_process(adapter, compl); | 147 | *status = be_mcc_compl_process(adapter, compl); |
@@ -207,7 +205,7 @@ static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db) | |||
207 | 205 | ||
208 | if (msecs > 4000) { | 206 | if (msecs > 4000) { |
209 | dev_err(&adapter->pdev->dev, "mbox poll timed out\n"); | 207 | dev_err(&adapter->pdev->dev, "mbox poll timed out\n"); |
210 | be_dump_ue(adapter); | 208 | be_detect_dump_ue(adapter); |
211 | return -1; | 209 | return -1; |
212 | } | 210 | } |
213 | 211 | ||
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index bdc10a28cfd..ad1e6fac60c 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h | |||
@@ -992,5 +992,5 @@ extern int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num, | |||
992 | extern int be_cmd_get_phy_info(struct be_adapter *adapter, | 992 | extern int be_cmd_get_phy_info(struct be_adapter *adapter, |
993 | struct be_dma_mem *cmd); | 993 | struct be_dma_mem *cmd); |
994 | extern int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain); | 994 | extern int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain); |
995 | extern void be_dump_ue(struct be_adapter *adapter); | 995 | extern void be_detect_dump_ue(struct be_adapter *adapter); |
996 | 996 | ||
diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index cd16243c7c3..13f0abbc520 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c | |||
@@ -60,6 +60,7 @@ static const struct be_ethtool_stat et_stats[] = { | |||
60 | {DRVSTAT_INFO(be_rx_events)}, | 60 | {DRVSTAT_INFO(be_rx_events)}, |
61 | {DRVSTAT_INFO(be_tx_compl)}, | 61 | {DRVSTAT_INFO(be_tx_compl)}, |
62 | {DRVSTAT_INFO(be_rx_compl)}, | 62 | {DRVSTAT_INFO(be_rx_compl)}, |
63 | {DRVSTAT_INFO(be_rx_mcast_pkt)}, | ||
63 | {DRVSTAT_INFO(be_ethrx_post_fail)}, | 64 | {DRVSTAT_INFO(be_ethrx_post_fail)}, |
64 | {DRVSTAT_INFO(be_802_3_dropped_frames)}, | 65 | {DRVSTAT_INFO(be_802_3_dropped_frames)}, |
65 | {DRVSTAT_INFO(be_802_3_malformed_frames)}, | 66 | {DRVSTAT_INFO(be_802_3_malformed_frames)}, |
diff --git a/drivers/net/benet/be_hw.h b/drivers/net/benet/be_hw.h index 5d38046402b..a2ec5df0d73 100644 --- a/drivers/net/benet/be_hw.h +++ b/drivers/net/benet/be_hw.h | |||
@@ -167,8 +167,11 @@ | |||
167 | #define FLASH_FCoE_BIOS_START_g3 (13631488) | 167 | #define FLASH_FCoE_BIOS_START_g3 (13631488) |
168 | #define FLASH_REDBOOT_START_g3 (262144) | 168 | #define FLASH_REDBOOT_START_g3 (262144) |
169 | 169 | ||
170 | 170 | /************* Rx Packet Type Encoding **************/ | |
171 | 171 | #define BE_UNICAST_PACKET 0 | |
172 | #define BE_MULTICAST_PACKET 1 | ||
173 | #define BE_BROADCAST_PACKET 2 | ||
174 | #define BE_RSVD_PACKET 3 | ||
172 | 175 | ||
173 | /* | 176 | /* |
174 | * BE descriptors: host memory data structures whose formats | 177 | * BE descriptors: host memory data structures whose formats |
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 74e146f470c..6eda7a02225 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c | |||
@@ -247,6 +247,7 @@ void netdev_stats_update(struct be_adapter *adapter) | |||
247 | dev_stats->tx_packets = drvr_stats(adapter)->be_tx_pkts; | 247 | dev_stats->tx_packets = drvr_stats(adapter)->be_tx_pkts; |
248 | dev_stats->rx_bytes = drvr_stats(adapter)->be_rx_bytes; | 248 | dev_stats->rx_bytes = drvr_stats(adapter)->be_rx_bytes; |
249 | dev_stats->tx_bytes = drvr_stats(adapter)->be_tx_bytes; | 249 | dev_stats->tx_bytes = drvr_stats(adapter)->be_tx_bytes; |
250 | dev_stats->multicast = drvr_stats(adapter)->be_rx_mcast_pkt; | ||
250 | 251 | ||
251 | /* bad pkts received */ | 252 | /* bad pkts received */ |
252 | dev_stats->rx_errors = port_stats->rx_crc_errors + | 253 | dev_stats->rx_errors = port_stats->rx_crc_errors + |
@@ -294,7 +295,6 @@ void netdev_stats_update(struct be_adapter *adapter) | |||
294 | /* no space available in linux */ | 295 | /* no space available in linux */ |
295 | dev_stats->tx_dropped = 0; | 296 | dev_stats->tx_dropped = 0; |
296 | 297 | ||
297 | dev_stats->multicast = port_stats->rx_multicast_frames; | ||
298 | dev_stats->collisions = 0; | 298 | dev_stats->collisions = 0; |
299 | 299 | ||
300 | /* detailed tx_errors */ | 300 | /* detailed tx_errors */ |
@@ -848,7 +848,7 @@ static void be_rx_rate_update(struct be_adapter *adapter) | |||
848 | } | 848 | } |
849 | 849 | ||
850 | static void be_rx_stats_update(struct be_adapter *adapter, | 850 | static void be_rx_stats_update(struct be_adapter *adapter, |
851 | u32 pktsize, u16 numfrags) | 851 | u32 pktsize, u16 numfrags, u8 pkt_type) |
852 | { | 852 | { |
853 | struct be_drvr_stats *stats = drvr_stats(adapter); | 853 | struct be_drvr_stats *stats = drvr_stats(adapter); |
854 | 854 | ||
@@ -856,6 +856,9 @@ static void be_rx_stats_update(struct be_adapter *adapter, | |||
856 | stats->be_rx_frags += numfrags; | 856 | stats->be_rx_frags += numfrags; |
857 | stats->be_rx_bytes += pktsize; | 857 | stats->be_rx_bytes += pktsize; |
858 | stats->be_rx_pkts++; | 858 | stats->be_rx_pkts++; |
859 | |||
860 | if (pkt_type == BE_MULTICAST_PACKET) | ||
861 | stats->be_rx_mcast_pkt++; | ||
859 | } | 862 | } |
860 | 863 | ||
861 | static inline bool do_pkt_csum(struct be_eth_rx_compl *rxcp, bool cso) | 864 | static inline bool do_pkt_csum(struct be_eth_rx_compl *rxcp, bool cso) |
@@ -925,9 +928,11 @@ static void skb_fill_rx_data(struct be_adapter *adapter, | |||
925 | u16 rxq_idx, i, j; | 928 | u16 rxq_idx, i, j; |
926 | u32 pktsize, hdr_len, curr_frag_len, size; | 929 | u32 pktsize, hdr_len, curr_frag_len, size; |
927 | u8 *start; | 930 | u8 *start; |
931 | u8 pkt_type; | ||
928 | 932 | ||
929 | rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); | 933 | rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); |
930 | pktsize = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp); | 934 | pktsize = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp); |
935 | pkt_type = AMAP_GET_BITS(struct amap_eth_rx_compl, cast_enc, rxcp); | ||
931 | 936 | ||
932 | page_info = get_rx_page_info(adapter, rxq_idx); | 937 | page_info = get_rx_page_info(adapter, rxq_idx); |
933 | 938 | ||
@@ -993,7 +998,7 @@ static void skb_fill_rx_data(struct be_adapter *adapter, | |||
993 | BUG_ON(j > MAX_SKB_FRAGS); | 998 | BUG_ON(j > MAX_SKB_FRAGS); |
994 | 999 | ||
995 | done: | 1000 | done: |
996 | be_rx_stats_update(adapter, pktsize, num_rcvd); | 1001 | be_rx_stats_update(adapter, pktsize, num_rcvd, pkt_type); |
997 | } | 1002 | } |
998 | 1003 | ||
999 | /* Process the RX completion indicated by rxcp when GRO is disabled */ | 1004 | /* Process the RX completion indicated by rxcp when GRO is disabled */ |
@@ -1060,6 +1065,7 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter, | |||
1060 | u32 num_rcvd, pkt_size, remaining, vlanf, curr_frag_len; | 1065 | u32 num_rcvd, pkt_size, remaining, vlanf, curr_frag_len; |
1061 | u16 i, rxq_idx = 0, vid, j; | 1066 | u16 i, rxq_idx = 0, vid, j; |
1062 | u8 vtm; | 1067 | u8 vtm; |
1068 | u8 pkt_type; | ||
1063 | 1069 | ||
1064 | num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp); | 1070 | num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp); |
1065 | /* Is it a flush compl that has no data */ | 1071 | /* Is it a flush compl that has no data */ |
@@ -1070,6 +1076,7 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter, | |||
1070 | vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp); | 1076 | vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp); |
1071 | rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); | 1077 | rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); |
1072 | vtm = AMAP_GET_BITS(struct amap_eth_rx_compl, vtm, rxcp); | 1078 | vtm = AMAP_GET_BITS(struct amap_eth_rx_compl, vtm, rxcp); |
1079 | pkt_type = AMAP_GET_BITS(struct amap_eth_rx_compl, cast_enc, rxcp); | ||
1073 | 1080 | ||
1074 | /* vlanf could be wrongly set in some cards. | 1081 | /* vlanf could be wrongly set in some cards. |
1075 | * ignore if vtm is not set */ | 1082 | * ignore if vtm is not set */ |
@@ -1125,7 +1132,7 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter, | |||
1125 | vlan_gro_frags(&eq_obj->napi, adapter->vlan_grp, vid); | 1132 | vlan_gro_frags(&eq_obj->napi, adapter->vlan_grp, vid); |
1126 | } | 1133 | } |
1127 | 1134 | ||
1128 | be_rx_stats_update(adapter, pkt_size, num_rcvd); | 1135 | be_rx_stats_update(adapter, pkt_size, num_rcvd, pkt_type); |
1129 | } | 1136 | } |
1130 | 1137 | ||
1131 | static struct be_eth_rx_compl *be_rx_compl_get(struct be_adapter *adapter) | 1138 | static struct be_eth_rx_compl *be_rx_compl_get(struct be_adapter *adapter) |
@@ -1743,26 +1750,7 @@ static int be_poll_tx_mcc(struct napi_struct *napi, int budget) | |||
1743 | return 1; | 1750 | return 1; |
1744 | } | 1751 | } |
1745 | 1752 | ||
1746 | static inline bool be_detect_ue(struct be_adapter *adapter) | 1753 | void be_detect_dump_ue(struct be_adapter *adapter) |
1747 | { | ||
1748 | u32 online0 = 0, online1 = 0; | ||
1749 | |||
1750 | pci_read_config_dword(adapter->pdev, PCICFG_ONLINE0, &online0); | ||
1751 | |||
1752 | pci_read_config_dword(adapter->pdev, PCICFG_ONLINE1, &online1); | ||
1753 | |||
1754 | if (!online0 || !online1) { | ||
1755 | adapter->ue_detected = true; | ||
1756 | dev_err(&adapter->pdev->dev, | ||
1757 | "UE Detected!! online0=%d online1=%d\n", | ||
1758 | online0, online1); | ||
1759 | return true; | ||
1760 | } | ||
1761 | |||
1762 | return false; | ||
1763 | } | ||
1764 | |||
1765 | void be_dump_ue(struct be_adapter *adapter) | ||
1766 | { | 1754 | { |
1767 | u32 ue_status_lo, ue_status_hi, ue_status_lo_mask, ue_status_hi_mask; | 1755 | u32 ue_status_lo, ue_status_hi, ue_status_lo_mask, ue_status_hi_mask; |
1768 | u32 i; | 1756 | u32 i; |
@@ -1779,6 +1767,11 @@ void be_dump_ue(struct be_adapter *adapter) | |||
1779 | ue_status_lo = (ue_status_lo & (~ue_status_lo_mask)); | 1767 | ue_status_lo = (ue_status_lo & (~ue_status_lo_mask)); |
1780 | ue_status_hi = (ue_status_hi & (~ue_status_hi_mask)); | 1768 | ue_status_hi = (ue_status_hi & (~ue_status_hi_mask)); |
1781 | 1769 | ||
1770 | if (ue_status_lo || ue_status_hi) { | ||
1771 | adapter->ue_detected = true; | ||
1772 | dev_err(&adapter->pdev->dev, "UE Detected!!\n"); | ||
1773 | } | ||
1774 | |||
1782 | if (ue_status_lo) { | 1775 | if (ue_status_lo) { |
1783 | for (i = 0; ue_status_lo; ue_status_lo >>= 1, i++) { | 1776 | for (i = 0; ue_status_lo; ue_status_lo >>= 1, i++) { |
1784 | if (ue_status_lo & 1) | 1777 | if (ue_status_lo & 1) |
@@ -1814,10 +1807,8 @@ static void be_worker(struct work_struct *work) | |||
1814 | adapter->rx_post_starved = false; | 1807 | adapter->rx_post_starved = false; |
1815 | be_post_rx_frags(adapter); | 1808 | be_post_rx_frags(adapter); |
1816 | } | 1809 | } |
1817 | if (!adapter->ue_detected) { | 1810 | if (!adapter->ue_detected) |
1818 | if (be_detect_ue(adapter)) | 1811 | be_detect_dump_ue(adapter); |
1819 | be_dump_ue(adapter); | ||
1820 | } | ||
1821 | 1812 | ||
1822 | schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000)); | 1813 | schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000)); |
1823 | } | 1814 | } |
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 53af9c93e75..0c2d96ed561 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h | |||
@@ -20,8 +20,8 @@ | |||
20 | * (you will need to reboot afterwards) */ | 20 | * (you will need to reboot afterwards) */ |
21 | /* #define BNX2X_STOP_ON_ERROR */ | 21 | /* #define BNX2X_STOP_ON_ERROR */ |
22 | 22 | ||
23 | #define DRV_MODULE_VERSION "1.52.53-3" | 23 | #define DRV_MODULE_VERSION "1.52.53-4" |
24 | #define DRV_MODULE_RELDATE "2010/18/04" | 24 | #define DRV_MODULE_RELDATE "2010/16/08" |
25 | #define BNX2X_BC_VER 0x040200 | 25 | #define BNX2X_BC_VER 0x040200 |
26 | 26 | ||
27 | #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) | 27 | #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) |
diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index b4ec2b02a46..f8c3f08e4ce 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c | |||
@@ -4328,10 +4328,12 @@ static int bnx2x_init_port(struct bnx2x *bp) | |||
4328 | val |= aeu_gpio_mask; | 4328 | val |= aeu_gpio_mask; |
4329 | REG_WR(bp, offset, val); | 4329 | REG_WR(bp, offset, val); |
4330 | } | 4330 | } |
4331 | bp->port.need_hw_lock = 1; | ||
4331 | break; | 4332 | break; |
4332 | 4333 | ||
4333 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: | ||
4334 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: | 4334 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: |
4335 | bp->port.need_hw_lock = 1; | ||
4336 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: | ||
4335 | /* add SPIO 5 to group 0 */ | 4337 | /* add SPIO 5 to group 0 */ |
4336 | { | 4338 | { |
4337 | u32 reg_addr = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 : | 4339 | u32 reg_addr = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 : |
@@ -4341,7 +4343,10 @@ static int bnx2x_init_port(struct bnx2x *bp) | |||
4341 | REG_WR(bp, reg_addr, val); | 4343 | REG_WR(bp, reg_addr, val); |
4342 | } | 4344 | } |
4343 | break; | 4345 | break; |
4344 | 4346 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: | |
4347 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: | ||
4348 | bp->port.need_hw_lock = 1; | ||
4349 | break; | ||
4345 | default: | 4350 | default: |
4346 | break; | 4351 | break; |
4347 | } | 4352 | } |
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 822f586d72a..0ddf4c66afe 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c | |||
@@ -2466,6 +2466,9 @@ int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct pac | |||
2466 | if (!(dev->flags & IFF_MASTER)) | 2466 | if (!(dev->flags & IFF_MASTER)) |
2467 | goto out; | 2467 | goto out; |
2468 | 2468 | ||
2469 | if (!pskb_may_pull(skb, sizeof(struct lacpdu))) | ||
2470 | goto out; | ||
2471 | |||
2469 | read_lock(&bond->lock); | 2472 | read_lock(&bond->lock); |
2470 | slave = bond_get_slave_by_dev((struct bonding *)netdev_priv(dev), | 2473 | slave = bond_get_slave_by_dev((struct bonding *)netdev_priv(dev), |
2471 | orig_dev); | 2474 | orig_dev); |
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index c746b331771..26bb118c453 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c | |||
@@ -362,6 +362,9 @@ static int rlb_arp_recv(struct sk_buff *skb, struct net_device *bond_dev, struct | |||
362 | goto out; | 362 | goto out; |
363 | } | 363 | } |
364 | 364 | ||
365 | if (!pskb_may_pull(skb, arp_hdr_len(bond_dev))) | ||
366 | goto out; | ||
367 | |||
365 | if (skb->len < sizeof(struct arp_pkt)) { | 368 | if (skb->len < sizeof(struct arp_pkt)) { |
366 | pr_debug("Packet is too small to be an ARP\n"); | 369 | pr_debug("Packet is too small to be an ARP\n"); |
367 | goto out; | 370 | goto out; |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 2cc4cfc3189..e953c6ad6e6 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -2797,9 +2797,15 @@ void bond_loadbalance_arp_mon(struct work_struct *work) | |||
2797 | * so it can wait | 2797 | * so it can wait |
2798 | */ | 2798 | */ |
2799 | bond_for_each_slave(bond, slave, i) { | 2799 | bond_for_each_slave(bond, slave, i) { |
2800 | unsigned long trans_start = dev_trans_start(slave->dev); | ||
2801 | |||
2800 | if (slave->link != BOND_LINK_UP) { | 2802 | if (slave->link != BOND_LINK_UP) { |
2801 | if (time_before_eq(jiffies, dev_trans_start(slave->dev) + delta_in_ticks) && | 2803 | if (time_in_range(jiffies, |
2802 | time_before_eq(jiffies, slave->dev->last_rx + delta_in_ticks)) { | 2804 | trans_start - delta_in_ticks, |
2805 | trans_start + delta_in_ticks) && | ||
2806 | time_in_range(jiffies, | ||
2807 | slave->dev->last_rx - delta_in_ticks, | ||
2808 | slave->dev->last_rx + delta_in_ticks)) { | ||
2803 | 2809 | ||
2804 | slave->link = BOND_LINK_UP; | 2810 | slave->link = BOND_LINK_UP; |
2805 | slave->state = BOND_STATE_ACTIVE; | 2811 | slave->state = BOND_STATE_ACTIVE; |
@@ -2827,8 +2833,12 @@ void bond_loadbalance_arp_mon(struct work_struct *work) | |||
2827 | * when the source ip is 0, so don't take the link down | 2833 | * when the source ip is 0, so don't take the link down |
2828 | * if we don't know our ip yet | 2834 | * if we don't know our ip yet |
2829 | */ | 2835 | */ |
2830 | if (time_after_eq(jiffies, dev_trans_start(slave->dev) + 2*delta_in_ticks) || | 2836 | if (!time_in_range(jiffies, |
2831 | (time_after_eq(jiffies, slave->dev->last_rx + 2*delta_in_ticks))) { | 2837 | trans_start - delta_in_ticks, |
2838 | trans_start + 2 * delta_in_ticks) || | ||
2839 | !time_in_range(jiffies, | ||
2840 | slave->dev->last_rx - delta_in_ticks, | ||
2841 | slave->dev->last_rx + 2 * delta_in_ticks)) { | ||
2832 | 2842 | ||
2833 | slave->link = BOND_LINK_DOWN; | 2843 | slave->link = BOND_LINK_DOWN; |
2834 | slave->state = BOND_STATE_BACKUP; | 2844 | slave->state = BOND_STATE_BACKUP; |
@@ -2883,13 +2893,16 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks) | |||
2883 | { | 2893 | { |
2884 | struct slave *slave; | 2894 | struct slave *slave; |
2885 | int i, commit = 0; | 2895 | int i, commit = 0; |
2896 | unsigned long trans_start; | ||
2886 | 2897 | ||
2887 | bond_for_each_slave(bond, slave, i) { | 2898 | bond_for_each_slave(bond, slave, i) { |
2888 | slave->new_link = BOND_LINK_NOCHANGE; | 2899 | slave->new_link = BOND_LINK_NOCHANGE; |
2889 | 2900 | ||
2890 | if (slave->link != BOND_LINK_UP) { | 2901 | if (slave->link != BOND_LINK_UP) { |
2891 | if (time_before_eq(jiffies, slave_last_rx(bond, slave) + | 2902 | if (time_in_range(jiffies, |
2892 | delta_in_ticks)) { | 2903 | slave_last_rx(bond, slave) - delta_in_ticks, |
2904 | slave_last_rx(bond, slave) + delta_in_ticks)) { | ||
2905 | |||
2893 | slave->new_link = BOND_LINK_UP; | 2906 | slave->new_link = BOND_LINK_UP; |
2894 | commit++; | 2907 | commit++; |
2895 | } | 2908 | } |
@@ -2902,8 +2915,9 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks) | |||
2902 | * active. This avoids bouncing, as the last receive | 2915 | * active. This avoids bouncing, as the last receive |
2903 | * times need a full ARP monitor cycle to be updated. | 2916 | * times need a full ARP monitor cycle to be updated. |
2904 | */ | 2917 | */ |
2905 | if (!time_after_eq(jiffies, slave->jiffies + | 2918 | if (time_in_range(jiffies, |
2906 | 2 * delta_in_ticks)) | 2919 | slave->jiffies - delta_in_ticks, |
2920 | slave->jiffies + 2 * delta_in_ticks)) | ||
2907 | continue; | 2921 | continue; |
2908 | 2922 | ||
2909 | /* | 2923 | /* |
@@ -2921,8 +2935,10 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks) | |||
2921 | */ | 2935 | */ |
2922 | if (slave->state == BOND_STATE_BACKUP && | 2936 | if (slave->state == BOND_STATE_BACKUP && |
2923 | !bond->current_arp_slave && | 2937 | !bond->current_arp_slave && |
2924 | time_after(jiffies, slave_last_rx(bond, slave) + | 2938 | !time_in_range(jiffies, |
2925 | 3 * delta_in_ticks)) { | 2939 | slave_last_rx(bond, slave) - delta_in_ticks, |
2940 | slave_last_rx(bond, slave) + 3 * delta_in_ticks)) { | ||
2941 | |||
2926 | slave->new_link = BOND_LINK_DOWN; | 2942 | slave->new_link = BOND_LINK_DOWN; |
2927 | commit++; | 2943 | commit++; |
2928 | } | 2944 | } |
@@ -2933,11 +2949,15 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks) | |||
2933 | * - (more than 2*delta since receive AND | 2949 | * - (more than 2*delta since receive AND |
2934 | * the bond has an IP address) | 2950 | * the bond has an IP address) |
2935 | */ | 2951 | */ |
2952 | trans_start = dev_trans_start(slave->dev); | ||
2936 | if ((slave->state == BOND_STATE_ACTIVE) && | 2953 | if ((slave->state == BOND_STATE_ACTIVE) && |
2937 | (time_after_eq(jiffies, dev_trans_start(slave->dev) + | 2954 | (!time_in_range(jiffies, |
2938 | 2 * delta_in_ticks) || | 2955 | trans_start - delta_in_ticks, |
2939 | (time_after_eq(jiffies, slave_last_rx(bond, slave) | 2956 | trans_start + 2 * delta_in_ticks) || |
2940 | + 2 * delta_in_ticks)))) { | 2957 | !time_in_range(jiffies, |
2958 | slave_last_rx(bond, slave) - delta_in_ticks, | ||
2959 | slave_last_rx(bond, slave) + 2 * delta_in_ticks))) { | ||
2960 | |||
2941 | slave->new_link = BOND_LINK_DOWN; | 2961 | slave->new_link = BOND_LINK_DOWN; |
2942 | commit++; | 2962 | commit++; |
2943 | } | 2963 | } |
@@ -2956,6 +2976,7 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks) | |||
2956 | { | 2976 | { |
2957 | struct slave *slave; | 2977 | struct slave *slave; |
2958 | int i; | 2978 | int i; |
2979 | unsigned long trans_start; | ||
2959 | 2980 | ||
2960 | bond_for_each_slave(bond, slave, i) { | 2981 | bond_for_each_slave(bond, slave, i) { |
2961 | switch (slave->new_link) { | 2982 | switch (slave->new_link) { |
@@ -2963,10 +2984,11 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks) | |||
2963 | continue; | 2984 | continue; |
2964 | 2985 | ||
2965 | case BOND_LINK_UP: | 2986 | case BOND_LINK_UP: |
2987 | trans_start = dev_trans_start(slave->dev); | ||
2966 | if ((!bond->curr_active_slave && | 2988 | if ((!bond->curr_active_slave && |
2967 | time_before_eq(jiffies, | 2989 | time_in_range(jiffies, |
2968 | dev_trans_start(slave->dev) + | 2990 | trans_start - delta_in_ticks, |
2969 | delta_in_ticks)) || | 2991 | trans_start + delta_in_ticks)) || |
2970 | bond->curr_active_slave != slave) { | 2992 | bond->curr_active_slave != slave) { |
2971 | slave->link = BOND_LINK_UP; | 2993 | slave->link = BOND_LINK_UP; |
2972 | bond->current_arp_slave = NULL; | 2994 | bond->current_arp_slave = NULL; |
@@ -5142,6 +5164,15 @@ int bond_create(struct net *net, const char *name) | |||
5142 | res = dev_alloc_name(bond_dev, "bond%d"); | 5164 | res = dev_alloc_name(bond_dev, "bond%d"); |
5143 | if (res < 0) | 5165 | if (res < 0) |
5144 | goto out; | 5166 | goto out; |
5167 | } else { | ||
5168 | /* | ||
5169 | * If we're given a name to register | ||
5170 | * we need to ensure that its not already | ||
5171 | * registered | ||
5172 | */ | ||
5173 | res = -EEXIST; | ||
5174 | if (__dev_get_by_name(net, name) != NULL) | ||
5175 | goto out; | ||
5145 | } | 5176 | } |
5146 | 5177 | ||
5147 | res = register_netdevice(bond_dev); | 5178 | res = register_netdevice(bond_dev); |
diff --git a/drivers/net/caif/Kconfig b/drivers/net/caif/Kconfig index 631a6242b01..75bfc3a9d95 100644 --- a/drivers/net/caif/Kconfig +++ b/drivers/net/caif/Kconfig | |||
@@ -15,7 +15,7 @@ config CAIF_TTY | |||
15 | 15 | ||
16 | config CAIF_SPI_SLAVE | 16 | config CAIF_SPI_SLAVE |
17 | tristate "CAIF SPI transport driver for slave interface" | 17 | tristate "CAIF SPI transport driver for slave interface" |
18 | depends on CAIF | 18 | depends on CAIF && HAS_DMA |
19 | default n | 19 | default n |
20 | ---help--- | 20 | ---help--- |
21 | The CAIF Link layer SPI Protocol driver for Slave SPI interface. | 21 | The CAIF Link layer SPI Protocol driver for Slave SPI interface. |
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index ad19585d960..f208712c0b9 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c | |||
@@ -2296,6 +2296,8 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr) | |||
2296 | case CHELSIO_GET_QSET_NUM:{ | 2296 | case CHELSIO_GET_QSET_NUM:{ |
2297 | struct ch_reg edata; | 2297 | struct ch_reg edata; |
2298 | 2298 | ||
2299 | memset(&edata, 0, sizeof(struct ch_reg)); | ||
2300 | |||
2299 | edata.cmd = CHELSIO_GET_QSET_NUM; | 2301 | edata.cmd = CHELSIO_GET_QSET_NUM; |
2300 | edata.val = pi->nqsets; | 2302 | edata.val = pi->nqsets; |
2301 | if (copy_to_user(useraddr, &edata, sizeof(edata))) | 2303 | if (copy_to_user(useraddr, &edata, sizeof(edata))) |
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index a4a0d2b6eb1..d3d4a57e245 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c | |||
@@ -936,12 +936,14 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw) | |||
936 | ew32(IMC, 0xffffffff); | 936 | ew32(IMC, 0xffffffff); |
937 | icr = er32(ICR); | 937 | icr = er32(ICR); |
938 | 938 | ||
939 | /* Install any alternate MAC address into RAR0 */ | 939 | if (hw->mac.type == e1000_82571) { |
940 | ret_val = e1000_check_alt_mac_addr_generic(hw); | 940 | /* Install any alternate MAC address into RAR0 */ |
941 | if (ret_val) | 941 | ret_val = e1000_check_alt_mac_addr_generic(hw); |
942 | return ret_val; | 942 | if (ret_val) |
943 | return ret_val; | ||
943 | 944 | ||
944 | e1000e_set_laa_state_82571(hw, true); | 945 | e1000e_set_laa_state_82571(hw, true); |
946 | } | ||
945 | 947 | ||
946 | /* Reinitialize the 82571 serdes link state machine */ | 948 | /* Reinitialize the 82571 serdes link state machine */ |
947 | if (hw->phy.media_type == e1000_media_type_internal_serdes) | 949 | if (hw->phy.media_type == e1000_media_type_internal_serdes) |
@@ -1618,14 +1620,16 @@ static s32 e1000_read_mac_addr_82571(struct e1000_hw *hw) | |||
1618 | { | 1620 | { |
1619 | s32 ret_val = 0; | 1621 | s32 ret_val = 0; |
1620 | 1622 | ||
1621 | /* | 1623 | if (hw->mac.type == e1000_82571) { |
1622 | * If there's an alternate MAC address place it in RAR0 | 1624 | /* |
1623 | * so that it will override the Si installed default perm | 1625 | * If there's an alternate MAC address place it in RAR0 |
1624 | * address. | 1626 | * so that it will override the Si installed default perm |
1625 | */ | 1627 | * address. |
1626 | ret_val = e1000_check_alt_mac_addr_generic(hw); | 1628 | */ |
1627 | if (ret_val) | 1629 | ret_val = e1000_check_alt_mac_addr_generic(hw); |
1628 | goto out; | 1630 | if (ret_val) |
1631 | goto out; | ||
1632 | } | ||
1629 | 1633 | ||
1630 | ret_val = e1000_read_mac_addr_generic(hw); | 1634 | ret_val = e1000_read_mac_addr_generic(hw); |
1631 | 1635 | ||
@@ -1833,6 +1837,7 @@ struct e1000_info e1000_82573_info = { | |||
1833 | | FLAG_HAS_SMART_POWER_DOWN | 1837 | | FLAG_HAS_SMART_POWER_DOWN |
1834 | | FLAG_HAS_AMT | 1838 | | FLAG_HAS_AMT |
1835 | | FLAG_HAS_SWSM_ON_LOAD, | 1839 | | FLAG_HAS_SWSM_ON_LOAD, |
1840 | .flags2 = FLAG2_DISABLE_ASPM_L1, | ||
1836 | .pba = 20, | 1841 | .pba = 20, |
1837 | .max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN, | 1842 | .max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN, |
1838 | .get_variants = e1000_get_variants_82571, | 1843 | .get_variants = e1000_get_variants_82571, |
diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h index 307a72f483e..93b3bedae8d 100644 --- a/drivers/net/e1000e/defines.h +++ b/drivers/net/e1000e/defines.h | |||
@@ -621,6 +621,7 @@ | |||
621 | #define E1000_FLASH_UPDATES 2000 | 621 | #define E1000_FLASH_UPDATES 2000 |
622 | 622 | ||
623 | /* NVM Word Offsets */ | 623 | /* NVM Word Offsets */ |
624 | #define NVM_COMPAT 0x0003 | ||
624 | #define NVM_ID_LED_SETTINGS 0x0004 | 625 | #define NVM_ID_LED_SETTINGS 0x0004 |
625 | #define NVM_INIT_CONTROL2_REG 0x000F | 626 | #define NVM_INIT_CONTROL2_REG 0x000F |
626 | #define NVM_INIT_CONTROL3_PORT_B 0x0014 | 627 | #define NVM_INIT_CONTROL3_PORT_B 0x0014 |
@@ -643,6 +644,9 @@ | |||
643 | /* Mask bits for fields in Word 0x1a of the NVM */ | 644 | /* Mask bits for fields in Word 0x1a of the NVM */ |
644 | #define NVM_WORD1A_ASPM_MASK 0x000C | 645 | #define NVM_WORD1A_ASPM_MASK 0x000C |
645 | 646 | ||
647 | /* Mask bits for fields in Word 0x03 of the EEPROM */ | ||
648 | #define NVM_COMPAT_LOM 0x0800 | ||
649 | |||
646 | /* For checksumming, the sum of all words in the NVM should equal 0xBABA. */ | 650 | /* For checksumming, the sum of all words in the NVM should equal 0xBABA. */ |
647 | #define NVM_SUM 0xBABA | 651 | #define NVM_SUM 0xBABA |
648 | 652 | ||
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h index 66ed08f726f..ba302a5c2c3 100644 --- a/drivers/net/e1000e/hw.h +++ b/drivers/net/e1000e/hw.h | |||
@@ -57,6 +57,7 @@ enum e1e_registers { | |||
57 | E1000_SCTL = 0x00024, /* SerDes Control - RW */ | 57 | E1000_SCTL = 0x00024, /* SerDes Control - RW */ |
58 | E1000_FCAL = 0x00028, /* Flow Control Address Low - RW */ | 58 | E1000_FCAL = 0x00028, /* Flow Control Address Low - RW */ |
59 | E1000_FCAH = 0x0002C, /* Flow Control Address High -RW */ | 59 | E1000_FCAH = 0x0002C, /* Flow Control Address High -RW */ |
60 | E1000_FEXTNVM4 = 0x00024, /* Future Extended NVM 4 - RW */ | ||
60 | E1000_FEXTNVM = 0x00028, /* Future Extended NVM - RW */ | 61 | E1000_FEXTNVM = 0x00028, /* Future Extended NVM - RW */ |
61 | E1000_FCT = 0x00030, /* Flow Control Type - RW */ | 62 | E1000_FCT = 0x00030, /* Flow Control Type - RW */ |
62 | E1000_VET = 0x00038, /* VLAN Ether Type - RW */ | 63 | E1000_VET = 0x00038, /* VLAN Ether Type - RW */ |
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 63930d12711..57b5435599a 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c | |||
@@ -105,6 +105,10 @@ | |||
105 | #define E1000_FEXTNVM_SW_CONFIG 1 | 105 | #define E1000_FEXTNVM_SW_CONFIG 1 |
106 | #define E1000_FEXTNVM_SW_CONFIG_ICH8M (1 << 27) /* Bit redefined for ICH8M :/ */ | 106 | #define E1000_FEXTNVM_SW_CONFIG_ICH8M (1 << 27) /* Bit redefined for ICH8M :/ */ |
107 | 107 | ||
108 | #define E1000_FEXTNVM4_BEACON_DURATION_MASK 0x7 | ||
109 | #define E1000_FEXTNVM4_BEACON_DURATION_8USEC 0x7 | ||
110 | #define E1000_FEXTNVM4_BEACON_DURATION_16USEC 0x3 | ||
111 | |||
108 | #define PCIE_ICH8_SNOOP_ALL PCIE_NO_SNOOP_ALL | 112 | #define PCIE_ICH8_SNOOP_ALL PCIE_NO_SNOOP_ALL |
109 | 113 | ||
110 | #define E1000_ICH_RAR_ENTRIES 7 | 114 | #define E1000_ICH_RAR_ENTRIES 7 |
@@ -125,6 +129,7 @@ | |||
125 | 129 | ||
126 | /* SMBus Address Phy Register */ | 130 | /* SMBus Address Phy Register */ |
127 | #define HV_SMB_ADDR PHY_REG(768, 26) | 131 | #define HV_SMB_ADDR PHY_REG(768, 26) |
132 | #define HV_SMB_ADDR_MASK 0x007F | ||
128 | #define HV_SMB_ADDR_PEC_EN 0x0200 | 133 | #define HV_SMB_ADDR_PEC_EN 0x0200 |
129 | #define HV_SMB_ADDR_VALID 0x0080 | 134 | #define HV_SMB_ADDR_VALID 0x0080 |
130 | 135 | ||
@@ -237,6 +242,8 @@ static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link); | |||
237 | static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw); | 242 | static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw); |
238 | static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw); | 243 | static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw); |
239 | static bool e1000_check_mng_mode_pchlan(struct e1000_hw *hw); | 244 | static bool e1000_check_mng_mode_pchlan(struct e1000_hw *hw); |
245 | static s32 e1000_k1_workaround_lv(struct e1000_hw *hw); | ||
246 | static void e1000_gate_hw_phy_config_ich8lan(struct e1000_hw *hw, bool gate); | ||
240 | 247 | ||
241 | static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg) | 248 | static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg) |
242 | { | 249 | { |
@@ -272,7 +279,7 @@ static inline void __ew32flash(struct e1000_hw *hw, unsigned long reg, u32 val) | |||
272 | static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) | 279 | static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) |
273 | { | 280 | { |
274 | struct e1000_phy_info *phy = &hw->phy; | 281 | struct e1000_phy_info *phy = &hw->phy; |
275 | u32 ctrl; | 282 | u32 ctrl, fwsm; |
276 | s32 ret_val = 0; | 283 | s32 ret_val = 0; |
277 | 284 | ||
278 | phy->addr = 1; | 285 | phy->addr = 1; |
@@ -294,7 +301,8 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) | |||
294 | * disabled, then toggle the LANPHYPC Value bit to force | 301 | * disabled, then toggle the LANPHYPC Value bit to force |
295 | * the interconnect to PCIe mode. | 302 | * the interconnect to PCIe mode. |
296 | */ | 303 | */ |
297 | if (!(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) { | 304 | fwsm = er32(FWSM); |
305 | if (!(fwsm & E1000_ICH_FWSM_FW_VALID)) { | ||
298 | ctrl = er32(CTRL); | 306 | ctrl = er32(CTRL); |
299 | ctrl |= E1000_CTRL_LANPHYPC_OVERRIDE; | 307 | ctrl |= E1000_CTRL_LANPHYPC_OVERRIDE; |
300 | ctrl &= ~E1000_CTRL_LANPHYPC_VALUE; | 308 | ctrl &= ~E1000_CTRL_LANPHYPC_VALUE; |
@@ -303,6 +311,13 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) | |||
303 | ctrl &= ~E1000_CTRL_LANPHYPC_OVERRIDE; | 311 | ctrl &= ~E1000_CTRL_LANPHYPC_OVERRIDE; |
304 | ew32(CTRL, ctrl); | 312 | ew32(CTRL, ctrl); |
305 | msleep(50); | 313 | msleep(50); |
314 | |||
315 | /* | ||
316 | * Gate automatic PHY configuration by hardware on | ||
317 | * non-managed 82579 | ||
318 | */ | ||
319 | if (hw->mac.type == e1000_pch2lan) | ||
320 | e1000_gate_hw_phy_config_ich8lan(hw, true); | ||
306 | } | 321 | } |
307 | 322 | ||
308 | /* | 323 | /* |
@@ -315,6 +330,13 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) | |||
315 | if (ret_val) | 330 | if (ret_val) |
316 | goto out; | 331 | goto out; |
317 | 332 | ||
333 | /* Ungate automatic PHY configuration on non-managed 82579 */ | ||
334 | if ((hw->mac.type == e1000_pch2lan) && | ||
335 | !(fwsm & E1000_ICH_FWSM_FW_VALID)) { | ||
336 | msleep(10); | ||
337 | e1000_gate_hw_phy_config_ich8lan(hw, false); | ||
338 | } | ||
339 | |||
318 | phy->id = e1000_phy_unknown; | 340 | phy->id = e1000_phy_unknown; |
319 | ret_val = e1000e_get_phy_id(hw); | 341 | ret_val = e1000e_get_phy_id(hw); |
320 | if (ret_val) | 342 | if (ret_val) |
@@ -561,13 +583,10 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_adapter *adapter) | |||
561 | if (mac->type == e1000_ich8lan) | 583 | if (mac->type == e1000_ich8lan) |
562 | e1000e_set_kmrn_lock_loss_workaround_ich8lan(hw, true); | 584 | e1000e_set_kmrn_lock_loss_workaround_ich8lan(hw, true); |
563 | 585 | ||
564 | /* Disable PHY configuration by hardware, config by software */ | 586 | /* Gate automatic PHY configuration by hardware on managed 82579 */ |
565 | if (mac->type == e1000_pch2lan) { | 587 | if ((mac->type == e1000_pch2lan) && |
566 | u32 extcnf_ctrl = er32(EXTCNF_CTRL); | 588 | (er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) |
567 | 589 | e1000_gate_hw_phy_config_ich8lan(hw, true); | |
568 | extcnf_ctrl |= E1000_EXTCNF_CTRL_GATE_PHY_CFG; | ||
569 | ew32(EXTCNF_CTRL, extcnf_ctrl); | ||
570 | } | ||
571 | 590 | ||
572 | return 0; | 591 | return 0; |
573 | } | 592 | } |
@@ -652,6 +671,12 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) | |||
652 | goto out; | 671 | goto out; |
653 | } | 672 | } |
654 | 673 | ||
674 | if (hw->mac.type == e1000_pch2lan) { | ||
675 | ret_val = e1000_k1_workaround_lv(hw); | ||
676 | if (ret_val) | ||
677 | goto out; | ||
678 | } | ||
679 | |||
655 | /* | 680 | /* |
656 | * Check if there was DownShift, must be checked | 681 | * Check if there was DownShift, must be checked |
657 | * immediately after link-up | 682 | * immediately after link-up |
@@ -895,6 +920,34 @@ static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw) | |||
895 | } | 920 | } |
896 | 921 | ||
897 | /** | 922 | /** |
923 | * e1000_write_smbus_addr - Write SMBus address to PHY needed during Sx states | ||
924 | * @hw: pointer to the HW structure | ||
925 | * | ||
926 | * Assumes semaphore already acquired. | ||
927 | * | ||
928 | **/ | ||
929 | static s32 e1000_write_smbus_addr(struct e1000_hw *hw) | ||
930 | { | ||
931 | u16 phy_data; | ||
932 | u32 strap = er32(STRAP); | ||
933 | s32 ret_val = 0; | ||
934 | |||
935 | strap &= E1000_STRAP_SMBUS_ADDRESS_MASK; | ||
936 | |||
937 | ret_val = e1000_read_phy_reg_hv_locked(hw, HV_SMB_ADDR, &phy_data); | ||
938 | if (ret_val) | ||
939 | goto out; | ||
940 | |||
941 | phy_data &= ~HV_SMB_ADDR_MASK; | ||
942 | phy_data |= (strap >> E1000_STRAP_SMBUS_ADDRESS_SHIFT); | ||
943 | phy_data |= HV_SMB_ADDR_PEC_EN | HV_SMB_ADDR_VALID; | ||
944 | ret_val = e1000_write_phy_reg_hv_locked(hw, HV_SMB_ADDR, phy_data); | ||
945 | |||
946 | out: | ||
947 | return ret_val; | ||
948 | } | ||
949 | |||
950 | /** | ||
898 | * e1000_sw_lcd_config_ich8lan - SW-based LCD Configuration | 951 | * e1000_sw_lcd_config_ich8lan - SW-based LCD Configuration |
899 | * @hw: pointer to the HW structure | 952 | * @hw: pointer to the HW structure |
900 | * | 953 | * |
@@ -903,7 +956,6 @@ static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw) | |||
903 | **/ | 956 | **/ |
904 | static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw) | 957 | static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw) |
905 | { | 958 | { |
906 | struct e1000_adapter *adapter = hw->adapter; | ||
907 | struct e1000_phy_info *phy = &hw->phy; | 959 | struct e1000_phy_info *phy = &hw->phy; |
908 | u32 i, data, cnf_size, cnf_base_addr, sw_cfg_mask; | 960 | u32 i, data, cnf_size, cnf_base_addr, sw_cfg_mask; |
909 | s32 ret_val = 0; | 961 | s32 ret_val = 0; |
@@ -921,7 +973,8 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw) | |||
921 | if (phy->type != e1000_phy_igp_3) | 973 | if (phy->type != e1000_phy_igp_3) |
922 | return ret_val; | 974 | return ret_val; |
923 | 975 | ||
924 | if (adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_AMT) { | 976 | if ((hw->adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_AMT) || |
977 | (hw->adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_C)) { | ||
925 | sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG; | 978 | sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG; |
926 | break; | 979 | break; |
927 | } | 980 | } |
@@ -961,21 +1014,16 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw) | |||
961 | cnf_base_addr = data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK; | 1014 | cnf_base_addr = data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK; |
962 | cnf_base_addr >>= E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT; | 1015 | cnf_base_addr >>= E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT; |
963 | 1016 | ||
964 | if (!(data & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE) && | 1017 | if ((!(data & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE) && |
965 | ((hw->mac.type == e1000_pchlan) || | 1018 | (hw->mac.type == e1000_pchlan)) || |
966 | (hw->mac.type == e1000_pch2lan))) { | 1019 | (hw->mac.type == e1000_pch2lan)) { |
967 | /* | 1020 | /* |
968 | * HW configures the SMBus address and LEDs when the | 1021 | * HW configures the SMBus address and LEDs when the |
969 | * OEM and LCD Write Enable bits are set in the NVM. | 1022 | * OEM and LCD Write Enable bits are set in the NVM. |
970 | * When both NVM bits are cleared, SW will configure | 1023 | * When both NVM bits are cleared, SW will configure |
971 | * them instead. | 1024 | * them instead. |
972 | */ | 1025 | */ |
973 | data = er32(STRAP); | 1026 | ret_val = e1000_write_smbus_addr(hw); |
974 | data &= E1000_STRAP_SMBUS_ADDRESS_MASK; | ||
975 | reg_data = data >> E1000_STRAP_SMBUS_ADDRESS_SHIFT; | ||
976 | reg_data |= HV_SMB_ADDR_PEC_EN | HV_SMB_ADDR_VALID; | ||
977 | ret_val = e1000_write_phy_reg_hv_locked(hw, HV_SMB_ADDR, | ||
978 | reg_data); | ||
979 | if (ret_val) | 1027 | if (ret_val) |
980 | goto out; | 1028 | goto out; |
981 | 1029 | ||
@@ -1440,10 +1488,6 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable) | |||
1440 | goto out; | 1488 | goto out; |
1441 | 1489 | ||
1442 | /* Enable jumbo frame workaround in the PHY */ | 1490 | /* Enable jumbo frame workaround in the PHY */ |
1443 | e1e_rphy(hw, PHY_REG(769, 20), &data); | ||
1444 | ret_val = e1e_wphy(hw, PHY_REG(769, 20), data & ~(1 << 14)); | ||
1445 | if (ret_val) | ||
1446 | goto out; | ||
1447 | e1e_rphy(hw, PHY_REG(769, 23), &data); | 1491 | e1e_rphy(hw, PHY_REG(769, 23), &data); |
1448 | data &= ~(0x7F << 5); | 1492 | data &= ~(0x7F << 5); |
1449 | data |= (0x37 << 5); | 1493 | data |= (0x37 << 5); |
@@ -1452,7 +1496,6 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable) | |||
1452 | goto out; | 1496 | goto out; |
1453 | e1e_rphy(hw, PHY_REG(769, 16), &data); | 1497 | e1e_rphy(hw, PHY_REG(769, 16), &data); |
1454 | data &= ~(1 << 13); | 1498 | data &= ~(1 << 13); |
1455 | data |= (1 << 12); | ||
1456 | ret_val = e1e_wphy(hw, PHY_REG(769, 16), data); | 1499 | ret_val = e1e_wphy(hw, PHY_REG(769, 16), data); |
1457 | if (ret_val) | 1500 | if (ret_val) |
1458 | goto out; | 1501 | goto out; |
@@ -1477,7 +1520,7 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable) | |||
1477 | 1520 | ||
1478 | mac_reg = er32(RCTL); | 1521 | mac_reg = er32(RCTL); |
1479 | mac_reg &= ~E1000_RCTL_SECRC; | 1522 | mac_reg &= ~E1000_RCTL_SECRC; |
1480 | ew32(FFLT_DBG, mac_reg); | 1523 | ew32(RCTL, mac_reg); |
1481 | 1524 | ||
1482 | ret_val = e1000e_read_kmrn_reg(hw, | 1525 | ret_val = e1000e_read_kmrn_reg(hw, |
1483 | E1000_KMRNCTRLSTA_CTRL_OFFSET, | 1526 | E1000_KMRNCTRLSTA_CTRL_OFFSET, |
@@ -1503,17 +1546,12 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable) | |||
1503 | goto out; | 1546 | goto out; |
1504 | 1547 | ||
1505 | /* Write PHY register values back to h/w defaults */ | 1548 | /* Write PHY register values back to h/w defaults */ |
1506 | e1e_rphy(hw, PHY_REG(769, 20), &data); | ||
1507 | ret_val = e1e_wphy(hw, PHY_REG(769, 20), data & ~(1 << 14)); | ||
1508 | if (ret_val) | ||
1509 | goto out; | ||
1510 | e1e_rphy(hw, PHY_REG(769, 23), &data); | 1549 | e1e_rphy(hw, PHY_REG(769, 23), &data); |
1511 | data &= ~(0x7F << 5); | 1550 | data &= ~(0x7F << 5); |
1512 | ret_val = e1e_wphy(hw, PHY_REG(769, 23), data); | 1551 | ret_val = e1e_wphy(hw, PHY_REG(769, 23), data); |
1513 | if (ret_val) | 1552 | if (ret_val) |
1514 | goto out; | 1553 | goto out; |
1515 | e1e_rphy(hw, PHY_REG(769, 16), &data); | 1554 | e1e_rphy(hw, PHY_REG(769, 16), &data); |
1516 | data &= ~(1 << 12); | ||
1517 | data |= (1 << 13); | 1555 | data |= (1 << 13); |
1518 | ret_val = e1e_wphy(hw, PHY_REG(769, 16), data); | 1556 | ret_val = e1e_wphy(hw, PHY_REG(769, 16), data); |
1519 | if (ret_val) | 1557 | if (ret_val) |
@@ -1559,6 +1597,69 @@ out: | |||
1559 | } | 1597 | } |
1560 | 1598 | ||
1561 | /** | 1599 | /** |
1600 | * e1000_k1_gig_workaround_lv - K1 Si workaround | ||
1601 | * @hw: pointer to the HW structure | ||
1602 | * | ||
1603 | * Workaround to set the K1 beacon duration for 82579 parts | ||
1604 | **/ | ||
1605 | static s32 e1000_k1_workaround_lv(struct e1000_hw *hw) | ||
1606 | { | ||
1607 | s32 ret_val = 0; | ||
1608 | u16 status_reg = 0; | ||
1609 | u32 mac_reg; | ||
1610 | |||
1611 | if (hw->mac.type != e1000_pch2lan) | ||
1612 | goto out; | ||
1613 | |||
1614 | /* Set K1 beacon duration based on 1Gbps speed or otherwise */ | ||
1615 | ret_val = e1e_rphy(hw, HV_M_STATUS, &status_reg); | ||
1616 | if (ret_val) | ||
1617 | goto out; | ||
1618 | |||
1619 | if ((status_reg & (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE)) | ||
1620 | == (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE)) { | ||
1621 | mac_reg = er32(FEXTNVM4); | ||
1622 | mac_reg &= ~E1000_FEXTNVM4_BEACON_DURATION_MASK; | ||
1623 | |||
1624 | if (status_reg & HV_M_STATUS_SPEED_1000) | ||
1625 | mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_8USEC; | ||
1626 | else | ||
1627 | mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_16USEC; | ||
1628 | |||
1629 | ew32(FEXTNVM4, mac_reg); | ||
1630 | } | ||
1631 | |||
1632 | out: | ||
1633 | return ret_val; | ||
1634 | } | ||
1635 | |||
1636 | /** | ||
1637 | * e1000_gate_hw_phy_config_ich8lan - disable PHY config via hardware | ||
1638 | * @hw: pointer to the HW structure | ||
1639 | * @gate: boolean set to true to gate, false to ungate | ||
1640 | * | ||
1641 | * Gate/ungate the automatic PHY configuration via hardware; perform | ||
1642 | * the configuration via software instead. | ||
1643 | **/ | ||
1644 | static void e1000_gate_hw_phy_config_ich8lan(struct e1000_hw *hw, bool gate) | ||
1645 | { | ||
1646 | u32 extcnf_ctrl; | ||
1647 | |||
1648 | if (hw->mac.type != e1000_pch2lan) | ||
1649 | return; | ||
1650 | |||
1651 | extcnf_ctrl = er32(EXTCNF_CTRL); | ||
1652 | |||
1653 | if (gate) | ||
1654 | extcnf_ctrl |= E1000_EXTCNF_CTRL_GATE_PHY_CFG; | ||
1655 | else | ||
1656 | extcnf_ctrl &= ~E1000_EXTCNF_CTRL_GATE_PHY_CFG; | ||
1657 | |||
1658 | ew32(EXTCNF_CTRL, extcnf_ctrl); | ||
1659 | return; | ||
1660 | } | ||
1661 | |||
1662 | /** | ||
1562 | * e1000_lan_init_done_ich8lan - Check for PHY config completion | 1663 | * e1000_lan_init_done_ich8lan - Check for PHY config completion |
1563 | * @hw: pointer to the HW structure | 1664 | * @hw: pointer to the HW structure |
1564 | * | 1665 | * |
@@ -1602,6 +1703,9 @@ static s32 e1000_post_phy_reset_ich8lan(struct e1000_hw *hw) | |||
1602 | if (e1000_check_reset_block(hw)) | 1703 | if (e1000_check_reset_block(hw)) |
1603 | goto out; | 1704 | goto out; |
1604 | 1705 | ||
1706 | /* Allow time for h/w to get to quiescent state after reset */ | ||
1707 | msleep(10); | ||
1708 | |||
1605 | /* Perform any necessary post-reset workarounds */ | 1709 | /* Perform any necessary post-reset workarounds */ |
1606 | switch (hw->mac.type) { | 1710 | switch (hw->mac.type) { |
1607 | case e1000_pchlan: | 1711 | case e1000_pchlan: |
@@ -1630,6 +1734,13 @@ static s32 e1000_post_phy_reset_ich8lan(struct e1000_hw *hw) | |||
1630 | /* Configure the LCD with the OEM bits in NVM */ | 1734 | /* Configure the LCD with the OEM bits in NVM */ |
1631 | ret_val = e1000_oem_bits_config_ich8lan(hw, true); | 1735 | ret_val = e1000_oem_bits_config_ich8lan(hw, true); |
1632 | 1736 | ||
1737 | /* Ungate automatic PHY configuration on non-managed 82579 */ | ||
1738 | if ((hw->mac.type == e1000_pch2lan) && | ||
1739 | !(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) { | ||
1740 | msleep(10); | ||
1741 | e1000_gate_hw_phy_config_ich8lan(hw, false); | ||
1742 | } | ||
1743 | |||
1633 | out: | 1744 | out: |
1634 | return ret_val; | 1745 | return ret_val; |
1635 | } | 1746 | } |
@@ -1646,6 +1757,11 @@ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) | |||
1646 | { | 1757 | { |
1647 | s32 ret_val = 0; | 1758 | s32 ret_val = 0; |
1648 | 1759 | ||
1760 | /* Gate automatic PHY configuration by hardware on non-managed 82579 */ | ||
1761 | if ((hw->mac.type == e1000_pch2lan) && | ||
1762 | !(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) | ||
1763 | e1000_gate_hw_phy_config_ich8lan(hw, true); | ||
1764 | |||
1649 | ret_val = e1000e_phy_hw_reset_generic(hw); | 1765 | ret_val = e1000e_phy_hw_reset_generic(hw); |
1650 | if (ret_val) | 1766 | if (ret_val) |
1651 | goto out; | 1767 | goto out; |
@@ -2910,6 +3026,14 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) | |||
2910 | * external PHY is reset. | 3026 | * external PHY is reset. |
2911 | */ | 3027 | */ |
2912 | ctrl |= E1000_CTRL_PHY_RST; | 3028 | ctrl |= E1000_CTRL_PHY_RST; |
3029 | |||
3030 | /* | ||
3031 | * Gate automatic PHY configuration by hardware on | ||
3032 | * non-managed 82579 | ||
3033 | */ | ||
3034 | if ((hw->mac.type == e1000_pch2lan) && | ||
3035 | !(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) | ||
3036 | e1000_gate_hw_phy_config_ich8lan(hw, true); | ||
2913 | } | 3037 | } |
2914 | ret_val = e1000_acquire_swflag_ich8lan(hw); | 3038 | ret_val = e1000_acquire_swflag_ich8lan(hw); |
2915 | e_dbg("Issuing a global reset to ich8lan\n"); | 3039 | e_dbg("Issuing a global reset to ich8lan\n"); |
@@ -3460,13 +3584,20 @@ void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw) | |||
3460 | void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw) | 3584 | void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw) |
3461 | { | 3585 | { |
3462 | u32 phy_ctrl; | 3586 | u32 phy_ctrl; |
3587 | s32 ret_val; | ||
3463 | 3588 | ||
3464 | phy_ctrl = er32(PHY_CTRL); | 3589 | phy_ctrl = er32(PHY_CTRL); |
3465 | phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU | E1000_PHY_CTRL_GBE_DISABLE; | 3590 | phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU | E1000_PHY_CTRL_GBE_DISABLE; |
3466 | ew32(PHY_CTRL, phy_ctrl); | 3591 | ew32(PHY_CTRL, phy_ctrl); |
3467 | 3592 | ||
3468 | if (hw->mac.type >= e1000_pchlan) | 3593 | if (hw->mac.type >= e1000_pchlan) { |
3469 | e1000_phy_hw_reset_ich8lan(hw); | 3594 | e1000_oem_bits_config_ich8lan(hw, true); |
3595 | ret_val = hw->phy.ops.acquire(hw); | ||
3596 | if (ret_val) | ||
3597 | return; | ||
3598 | e1000_write_smbus_addr(hw); | ||
3599 | hw->phy.ops.release(hw); | ||
3600 | } | ||
3470 | } | 3601 | } |
3471 | 3602 | ||
3472 | /** | 3603 | /** |
diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c index df4a2792293..0fd4eb5ac5f 100644 --- a/drivers/net/e1000e/lib.c +++ b/drivers/net/e1000e/lib.c | |||
@@ -183,6 +183,16 @@ s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw) | |||
183 | u16 offset, nvm_alt_mac_addr_offset, nvm_data; | 183 | u16 offset, nvm_alt_mac_addr_offset, nvm_data; |
184 | u8 alt_mac_addr[ETH_ALEN]; | 184 | u8 alt_mac_addr[ETH_ALEN]; |
185 | 185 | ||
186 | ret_val = e1000_read_nvm(hw, NVM_COMPAT, 1, &nvm_data); | ||
187 | if (ret_val) | ||
188 | goto out; | ||
189 | |||
190 | /* Check for LOM (vs. NIC) or one of two valid mezzanine cards */ | ||
191 | if (!((nvm_data & NVM_COMPAT_LOM) || | ||
192 | (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES_DUAL) || | ||
193 | (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES_QUAD))) | ||
194 | goto out; | ||
195 | |||
186 | ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1, | 196 | ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1, |
187 | &nvm_alt_mac_addr_offset); | 197 | &nvm_alt_mac_addr_offset); |
188 | if (ret_val) { | 198 | if (ret_val) { |
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 2b8ef44bd2b..e561d15c3eb 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c | |||
@@ -2704,6 +2704,16 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter) | |||
2704 | u32 psrctl = 0; | 2704 | u32 psrctl = 0; |
2705 | u32 pages = 0; | 2705 | u32 pages = 0; |
2706 | 2706 | ||
2707 | /* Workaround Si errata on 82579 - configure jumbo frame flow */ | ||
2708 | if (hw->mac.type == e1000_pch2lan) { | ||
2709 | s32 ret_val; | ||
2710 | |||
2711 | if (adapter->netdev->mtu > ETH_DATA_LEN) | ||
2712 | ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, true); | ||
2713 | else | ||
2714 | ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, false); | ||
2715 | } | ||
2716 | |||
2707 | /* Program MC offset vector base */ | 2717 | /* Program MC offset vector base */ |
2708 | rctl = er32(RCTL); | 2718 | rctl = er32(RCTL); |
2709 | rctl &= ~(3 << E1000_RCTL_MO_SHIFT); | 2719 | rctl &= ~(3 << E1000_RCTL_MO_SHIFT); |
@@ -2744,16 +2754,6 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter) | |||
2744 | e1e_wphy(hw, 22, phy_data); | 2754 | e1e_wphy(hw, 22, phy_data); |
2745 | } | 2755 | } |
2746 | 2756 | ||
2747 | /* Workaround Si errata on 82579 - configure jumbo frame flow */ | ||
2748 | if (hw->mac.type == e1000_pch2lan) { | ||
2749 | s32 ret_val; | ||
2750 | |||
2751 | if (rctl & E1000_RCTL_LPE) | ||
2752 | ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, true); | ||
2753 | else | ||
2754 | ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, false); | ||
2755 | } | ||
2756 | |||
2757 | /* Setup buffer sizes */ | 2757 | /* Setup buffer sizes */ |
2758 | rctl &= ~E1000_RCTL_SZ_4096; | 2758 | rctl &= ~E1000_RCTL_SZ_4096; |
2759 | rctl |= E1000_RCTL_BSEX; | 2759 | rctl |= E1000_RCTL_BSEX; |
@@ -4833,6 +4833,15 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) | |||
4833 | return -EINVAL; | 4833 | return -EINVAL; |
4834 | } | 4834 | } |
4835 | 4835 | ||
4836 | /* Jumbo frame workaround on 82579 requires CRC be stripped */ | ||
4837 | if ((adapter->hw.mac.type == e1000_pch2lan) && | ||
4838 | !(adapter->flags2 & FLAG2_CRC_STRIPPING) && | ||
4839 | (new_mtu > ETH_DATA_LEN)) { | ||
4840 | e_err("Jumbo Frames not supported on 82579 when CRC " | ||
4841 | "stripping is disabled.\n"); | ||
4842 | return -EINVAL; | ||
4843 | } | ||
4844 | |||
4836 | /* 82573 Errata 17 */ | 4845 | /* 82573 Errata 17 */ |
4837 | if (((adapter->hw.mac.type == e1000_82573) || | 4846 | if (((adapter->hw.mac.type == e1000_82573) || |
4838 | (adapter->hw.mac.type == e1000_82574)) && | 4847 | (adapter->hw.mac.type == e1000_82574)) && |
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index 99a929964e3..1846623c6ae 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h | |||
@@ -40,7 +40,7 @@ | |||
40 | #include <asm/io.h> | 40 | #include <asm/io.h> |
41 | 41 | ||
42 | #define DRV_NAME "ehea" | 42 | #define DRV_NAME "ehea" |
43 | #define DRV_VERSION "EHEA_0105" | 43 | #define DRV_VERSION "EHEA_0106" |
44 | 44 | ||
45 | /* eHEA capability flags */ | 45 | /* eHEA capability flags */ |
46 | #define DLPAR_PORT_ADD_REM 1 | 46 | #define DLPAR_PORT_ADD_REM 1 |
@@ -400,6 +400,7 @@ struct ehea_port_res { | |||
400 | u32 poll_counter; | 400 | u32 poll_counter; |
401 | struct net_lro_mgr lro_mgr; | 401 | struct net_lro_mgr lro_mgr; |
402 | struct net_lro_desc lro_desc[MAX_LRO_DESCRIPTORS]; | 402 | struct net_lro_desc lro_desc[MAX_LRO_DESCRIPTORS]; |
403 | int sq_restart_flag; | ||
403 | }; | 404 | }; |
404 | 405 | ||
405 | 406 | ||
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 897719b49f9..6372610ed24 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c | |||
@@ -533,8 +533,15 @@ static inline void ehea_fill_skb(struct net_device *dev, | |||
533 | int length = cqe->num_bytes_transfered - 4; /*remove CRC */ | 533 | int length = cqe->num_bytes_transfered - 4; /*remove CRC */ |
534 | 534 | ||
535 | skb_put(skb, length); | 535 | skb_put(skb, length); |
536 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
537 | skb->protocol = eth_type_trans(skb, dev); | 536 | skb->protocol = eth_type_trans(skb, dev); |
537 | |||
538 | /* The packet was not an IPV4 packet so a complemented checksum was | ||
539 | calculated. The value is found in the Internet Checksum field. */ | ||
540 | if (cqe->status & EHEA_CQE_BLIND_CKSUM) { | ||
541 | skb->ip_summed = CHECKSUM_COMPLETE; | ||
542 | skb->csum = csum_unfold(~cqe->inet_checksum_value); | ||
543 | } else | ||
544 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
538 | } | 545 | } |
539 | 546 | ||
540 | static inline struct sk_buff *get_skb_by_index(struct sk_buff **skb_array, | 547 | static inline struct sk_buff *get_skb_by_index(struct sk_buff **skb_array, |
@@ -776,6 +783,53 @@ static int ehea_proc_rwqes(struct net_device *dev, | |||
776 | return processed; | 783 | return processed; |
777 | } | 784 | } |
778 | 785 | ||
786 | #define SWQE_RESTART_CHECK 0xdeadbeaff00d0000ull | ||
787 | |||
788 | static void reset_sq_restart_flag(struct ehea_port *port) | ||
789 | { | ||
790 | int i; | ||
791 | |||
792 | for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) { | ||
793 | struct ehea_port_res *pr = &port->port_res[i]; | ||
794 | pr->sq_restart_flag = 0; | ||
795 | } | ||
796 | } | ||
797 | |||
798 | static void check_sqs(struct ehea_port *port) | ||
799 | { | ||
800 | struct ehea_swqe *swqe; | ||
801 | int swqe_index; | ||
802 | int i, k; | ||
803 | |||
804 | for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) { | ||
805 | struct ehea_port_res *pr = &port->port_res[i]; | ||
806 | k = 0; | ||
807 | swqe = ehea_get_swqe(pr->qp, &swqe_index); | ||
808 | memset(swqe, 0, SWQE_HEADER_SIZE); | ||
809 | atomic_dec(&pr->swqe_avail); | ||
810 | |||
811 | swqe->tx_control |= EHEA_SWQE_PURGE; | ||
812 | swqe->wr_id = SWQE_RESTART_CHECK; | ||
813 | swqe->tx_control |= EHEA_SWQE_SIGNALLED_COMPLETION; | ||
814 | swqe->tx_control |= EHEA_SWQE_IMM_DATA_PRESENT; | ||
815 | swqe->immediate_data_length = 80; | ||
816 | |||
817 | ehea_post_swqe(pr->qp, swqe); | ||
818 | |||
819 | while (pr->sq_restart_flag == 0) { | ||
820 | msleep(5); | ||
821 | if (++k == 100) { | ||
822 | ehea_error("HW/SW queues out of sync"); | ||
823 | ehea_schedule_port_reset(pr->port); | ||
824 | return; | ||
825 | } | ||
826 | } | ||
827 | } | ||
828 | |||
829 | return; | ||
830 | } | ||
831 | |||
832 | |||
779 | static struct ehea_cqe *ehea_proc_cqes(struct ehea_port_res *pr, int my_quota) | 833 | static struct ehea_cqe *ehea_proc_cqes(struct ehea_port_res *pr, int my_quota) |
780 | { | 834 | { |
781 | struct sk_buff *skb; | 835 | struct sk_buff *skb; |
@@ -793,6 +847,13 @@ static struct ehea_cqe *ehea_proc_cqes(struct ehea_port_res *pr, int my_quota) | |||
793 | 847 | ||
794 | cqe_counter++; | 848 | cqe_counter++; |
795 | rmb(); | 849 | rmb(); |
850 | |||
851 | if (cqe->wr_id == SWQE_RESTART_CHECK) { | ||
852 | pr->sq_restart_flag = 1; | ||
853 | swqe_av++; | ||
854 | break; | ||
855 | } | ||
856 | |||
796 | if (cqe->status & EHEA_CQE_STAT_ERR_MASK) { | 857 | if (cqe->status & EHEA_CQE_STAT_ERR_MASK) { |
797 | ehea_error("Bad send completion status=0x%04X", | 858 | ehea_error("Bad send completion status=0x%04X", |
798 | cqe->status); | 859 | cqe->status); |
@@ -2675,8 +2736,10 @@ static void ehea_flush_sq(struct ehea_port *port) | |||
2675 | int k = 0; | 2736 | int k = 0; |
2676 | while (atomic_read(&pr->swqe_avail) < swqe_max) { | 2737 | while (atomic_read(&pr->swqe_avail) < swqe_max) { |
2677 | msleep(5); | 2738 | msleep(5); |
2678 | if (++k == 20) | 2739 | if (++k == 20) { |
2740 | ehea_error("WARNING: sq not flushed completely"); | ||
2679 | break; | 2741 | break; |
2742 | } | ||
2680 | } | 2743 | } |
2681 | } | 2744 | } |
2682 | } | 2745 | } |
@@ -2917,6 +2980,7 @@ static void ehea_rereg_mrs(struct work_struct *work) | |||
2917 | port_napi_disable(port); | 2980 | port_napi_disable(port); |
2918 | mutex_unlock(&port->port_lock); | 2981 | mutex_unlock(&port->port_lock); |
2919 | } | 2982 | } |
2983 | reset_sq_restart_flag(port); | ||
2920 | } | 2984 | } |
2921 | 2985 | ||
2922 | /* Unregister old memory region */ | 2986 | /* Unregister old memory region */ |
@@ -2951,6 +3015,7 @@ static void ehea_rereg_mrs(struct work_struct *work) | |||
2951 | mutex_lock(&port->port_lock); | 3015 | mutex_lock(&port->port_lock); |
2952 | port_napi_enable(port); | 3016 | port_napi_enable(port); |
2953 | ret = ehea_restart_qps(dev); | 3017 | ret = ehea_restart_qps(dev); |
3018 | check_sqs(port); | ||
2954 | if (!ret) | 3019 | if (!ret) |
2955 | netif_wake_queue(dev); | 3020 | netif_wake_queue(dev); |
2956 | mutex_unlock(&port->port_lock); | 3021 | mutex_unlock(&port->port_lock); |
diff --git a/drivers/net/ehea/ehea_qmr.h b/drivers/net/ehea/ehea_qmr.h index f608a6c54af..38104734a3b 100644 --- a/drivers/net/ehea/ehea_qmr.h +++ b/drivers/net/ehea/ehea_qmr.h | |||
@@ -150,6 +150,7 @@ struct ehea_rwqe { | |||
150 | #define EHEA_CQE_TYPE_RQ 0x60 | 150 | #define EHEA_CQE_TYPE_RQ 0x60 |
151 | #define EHEA_CQE_STAT_ERR_MASK 0x700F | 151 | #define EHEA_CQE_STAT_ERR_MASK 0x700F |
152 | #define EHEA_CQE_STAT_FAT_ERR_MASK 0xF | 152 | #define EHEA_CQE_STAT_FAT_ERR_MASK 0xF |
153 | #define EHEA_CQE_BLIND_CKSUM 0x8000 | ||
153 | #define EHEA_CQE_STAT_ERR_TCP 0x4000 | 154 | #define EHEA_CQE_STAT_ERR_TCP 0x4000 |
154 | #define EHEA_CQE_STAT_ERR_IP 0x2000 | 155 | #define EHEA_CQE_STAT_ERR_IP 0x2000 |
155 | #define EHEA_CQE_STAT_ERR_CRC 0x1000 | 156 | #define EHEA_CQE_STAT_ERR_CRC 0x1000 |
diff --git a/drivers/net/eql.c b/drivers/net/eql.c index dda2c7944da..0cb1cf9cf4b 100644 --- a/drivers/net/eql.c +++ b/drivers/net/eql.c | |||
@@ -555,6 +555,8 @@ static int eql_g_master_cfg(struct net_device *dev, master_config_t __user *mcp) | |||
555 | equalizer_t *eql; | 555 | equalizer_t *eql; |
556 | master_config_t mc; | 556 | master_config_t mc; |
557 | 557 | ||
558 | memset(&mc, 0, sizeof(master_config_t)); | ||
559 | |||
558 | if (eql_is_master(dev)) { | 560 | if (eql_is_master(dev)) { |
559 | eql = netdev_priv(dev); | 561 | eql = netdev_priv(dev); |
560 | mc.max_slaves = eql->max_slaves; | 562 | mc.max_slaves = eql->max_slaves; |
diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 768b840aeb6..cce32d43175 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c | |||
@@ -678,24 +678,37 @@ static int fec_enet_mii_probe(struct net_device *dev) | |||
678 | { | 678 | { |
679 | struct fec_enet_private *fep = netdev_priv(dev); | 679 | struct fec_enet_private *fep = netdev_priv(dev); |
680 | struct phy_device *phy_dev = NULL; | 680 | struct phy_device *phy_dev = NULL; |
681 | int ret; | 681 | char mdio_bus_id[MII_BUS_ID_SIZE]; |
682 | char phy_name[MII_BUS_ID_SIZE + 3]; | ||
683 | int phy_id; | ||
682 | 684 | ||
683 | fep->phy_dev = NULL; | 685 | fep->phy_dev = NULL; |
684 | 686 | ||
685 | /* find the first phy */ | 687 | /* check for attached phy */ |
686 | phy_dev = phy_find_first(fep->mii_bus); | 688 | for (phy_id = 0; (phy_id < PHY_MAX_ADDR); phy_id++) { |
687 | if (!phy_dev) { | 689 | if ((fep->mii_bus->phy_mask & (1 << phy_id))) |
688 | printk(KERN_ERR "%s: no PHY found\n", dev->name); | 690 | continue; |
689 | return -ENODEV; | 691 | if (fep->mii_bus->phy_map[phy_id] == NULL) |
692 | continue; | ||
693 | if (fep->mii_bus->phy_map[phy_id]->phy_id == 0) | ||
694 | continue; | ||
695 | strncpy(mdio_bus_id, fep->mii_bus->id, MII_BUS_ID_SIZE); | ||
696 | break; | ||
690 | } | 697 | } |
691 | 698 | ||
692 | /* attach the mac to the phy */ | 699 | if (phy_id >= PHY_MAX_ADDR) { |
693 | ret = phy_connect_direct(dev, phy_dev, | 700 | printk(KERN_INFO "%s: no PHY, assuming direct connection " |
694 | &fec_enet_adjust_link, 0, | 701 | "to switch\n", dev->name); |
695 | PHY_INTERFACE_MODE_MII); | 702 | strncpy(mdio_bus_id, "0", MII_BUS_ID_SIZE); |
696 | if (ret) { | 703 | phy_id = 0; |
697 | printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); | 704 | } |
698 | return ret; | 705 | |
706 | snprintf(phy_name, MII_BUS_ID_SIZE, PHY_ID_FMT, mdio_bus_id, phy_id); | ||
707 | phy_dev = phy_connect(dev, phy_name, &fec_enet_adjust_link, 0, | ||
708 | PHY_INTERFACE_MODE_MII); | ||
709 | if (IS_ERR(phy_dev)) { | ||
710 | printk(KERN_ERR "%s: could not attach to PHY\n", dev->name); | ||
711 | return PTR_ERR(phy_dev); | ||
699 | } | 712 | } |
700 | 713 | ||
701 | /* mask with MAC supported features */ | 714 | /* mask with MAC supported features */ |
@@ -738,7 +751,7 @@ static int fec_enet_mii_init(struct platform_device *pdev) | |||
738 | fep->mii_bus->read = fec_enet_mdio_read; | 751 | fep->mii_bus->read = fec_enet_mdio_read; |
739 | fep->mii_bus->write = fec_enet_mdio_write; | 752 | fep->mii_bus->write = fec_enet_mdio_write; |
740 | fep->mii_bus->reset = fec_enet_mdio_reset; | 753 | fep->mii_bus->reset = fec_enet_mdio_reset; |
741 | snprintf(fep->mii_bus->id, MII_BUS_ID_SIZE, "%x", pdev->id); | 754 | snprintf(fep->mii_bus->id, MII_BUS_ID_SIZE, "%x", pdev->id + 1); |
742 | fep->mii_bus->priv = fep; | 755 | fep->mii_bus->priv = fep; |
743 | fep->mii_bus->parent = &pdev->dev; | 756 | fep->mii_bus->parent = &pdev->dev; |
744 | 757 | ||
@@ -1311,6 +1324,9 @@ fec_probe(struct platform_device *pdev) | |||
1311 | if (ret) | 1324 | if (ret) |
1312 | goto failed_mii_init; | 1325 | goto failed_mii_init; |
1313 | 1326 | ||
1327 | /* Carrier starts down, phylib will bring it up */ | ||
1328 | netif_carrier_off(ndev); | ||
1329 | |||
1314 | ret = register_netdev(ndev); | 1330 | ret = register_netdev(ndev); |
1315 | if (ret) | 1331 | if (ret) |
1316 | goto failed_register; | 1332 | goto failed_register; |
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index 3506fd6ad72..519e19e2395 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c | |||
@@ -2928,7 +2928,7 @@ static int __devinit emac_probe(struct platform_device *ofdev, | |||
2928 | if (dev->emac_irq != NO_IRQ) | 2928 | if (dev->emac_irq != NO_IRQ) |
2929 | irq_dispose_mapping(dev->emac_irq); | 2929 | irq_dispose_mapping(dev->emac_irq); |
2930 | err_free: | 2930 | err_free: |
2931 | kfree(ndev); | 2931 | free_netdev(ndev); |
2932 | err_gone: | 2932 | err_gone: |
2933 | /* if we were on the bootlist, remove us as we won't show up and | 2933 | /* if we were on the bootlist, remove us as we won't show up and |
2934 | * wake up all waiters to notify them in case they were waiting | 2934 | * wake up all waiters to notify them in case they were waiting |
@@ -2971,7 +2971,7 @@ static int __devexit emac_remove(struct platform_device *ofdev) | |||
2971 | if (dev->emac_irq != NO_IRQ) | 2971 | if (dev->emac_irq != NO_IRQ) |
2972 | irq_dispose_mapping(dev->emac_irq); | 2972 | irq_dispose_mapping(dev->emac_irq); |
2973 | 2973 | ||
2974 | kfree(dev->ndev); | 2974 | free_netdev(dev->ndev); |
2975 | 2975 | ||
2976 | return 0; | 2976 | return 0; |
2977 | } | 2977 | } |
diff --git a/drivers/net/ibm_newemac/debug.c b/drivers/net/ibm_newemac/debug.c index 3995fafc1e0..8c6c1e2a875 100644 --- a/drivers/net/ibm_newemac/debug.c +++ b/drivers/net/ibm_newemac/debug.c | |||
@@ -238,7 +238,7 @@ void emac_dbg_dump_all(void) | |||
238 | } | 238 | } |
239 | 239 | ||
240 | #if defined(CONFIG_MAGIC_SYSRQ) | 240 | #if defined(CONFIG_MAGIC_SYSRQ) |
241 | static void emac_sysrq_handler(int key, struct tty_struct *tty) | 241 | static void emac_sysrq_handler(int key) |
242 | { | 242 | { |
243 | emac_dbg_dump_all(); | 243 | emac_dbg_dump_all(); |
244 | } | 244 | } |
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 2602852cc55..4734c939ad0 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c | |||
@@ -1113,7 +1113,8 @@ static int ibmveth_change_mtu(struct net_device *dev, int new_mtu) | |||
1113 | struct ibmveth_adapter *adapter = netdev_priv(dev); | 1113 | struct ibmveth_adapter *adapter = netdev_priv(dev); |
1114 | struct vio_dev *viodev = adapter->vdev; | 1114 | struct vio_dev *viodev = adapter->vdev; |
1115 | int new_mtu_oh = new_mtu + IBMVETH_BUFF_OH; | 1115 | int new_mtu_oh = new_mtu + IBMVETH_BUFF_OH; |
1116 | int i; | 1116 | int i, rc; |
1117 | int need_restart = 0; | ||
1117 | 1118 | ||
1118 | if (new_mtu < IBMVETH_MAX_MTU) | 1119 | if (new_mtu < IBMVETH_MAX_MTU) |
1119 | return -EINVAL; | 1120 | return -EINVAL; |
@@ -1127,35 +1128,32 @@ static int ibmveth_change_mtu(struct net_device *dev, int new_mtu) | |||
1127 | 1128 | ||
1128 | /* Deactivate all the buffer pools so that the next loop can activate | 1129 | /* Deactivate all the buffer pools so that the next loop can activate |
1129 | only the buffer pools necessary to hold the new MTU */ | 1130 | only the buffer pools necessary to hold the new MTU */ |
1130 | for (i = 0; i < IbmVethNumBufferPools; i++) | 1131 | if (netif_running(adapter->netdev)) { |
1131 | if (adapter->rx_buff_pool[i].active) { | 1132 | need_restart = 1; |
1132 | ibmveth_free_buffer_pool(adapter, | 1133 | adapter->pool_config = 1; |
1133 | &adapter->rx_buff_pool[i]); | 1134 | ibmveth_close(adapter->netdev); |
1134 | adapter->rx_buff_pool[i].active = 0; | 1135 | adapter->pool_config = 0; |
1135 | } | 1136 | } |
1136 | 1137 | ||
1137 | /* Look for an active buffer pool that can hold the new MTU */ | 1138 | /* Look for an active buffer pool that can hold the new MTU */ |
1138 | for(i = 0; i<IbmVethNumBufferPools; i++) { | 1139 | for(i = 0; i<IbmVethNumBufferPools; i++) { |
1139 | adapter->rx_buff_pool[i].active = 1; | 1140 | adapter->rx_buff_pool[i].active = 1; |
1140 | 1141 | ||
1141 | if (new_mtu_oh < adapter->rx_buff_pool[i].buff_size) { | 1142 | if (new_mtu_oh < adapter->rx_buff_pool[i].buff_size) { |
1142 | if (netif_running(adapter->netdev)) { | ||
1143 | adapter->pool_config = 1; | ||
1144 | ibmveth_close(adapter->netdev); | ||
1145 | adapter->pool_config = 0; | ||
1146 | dev->mtu = new_mtu; | ||
1147 | vio_cmo_set_dev_desired(viodev, | ||
1148 | ibmveth_get_desired_dma | ||
1149 | (viodev)); | ||
1150 | return ibmveth_open(adapter->netdev); | ||
1151 | } | ||
1152 | dev->mtu = new_mtu; | 1143 | dev->mtu = new_mtu; |
1153 | vio_cmo_set_dev_desired(viodev, | 1144 | vio_cmo_set_dev_desired(viodev, |
1154 | ibmveth_get_desired_dma | 1145 | ibmveth_get_desired_dma |
1155 | (viodev)); | 1146 | (viodev)); |
1147 | if (need_restart) { | ||
1148 | return ibmveth_open(adapter->netdev); | ||
1149 | } | ||
1156 | return 0; | 1150 | return 0; |
1157 | } | 1151 | } |
1158 | } | 1152 | } |
1153 | |||
1154 | if (need_restart && (rc = ibmveth_open(adapter->netdev))) | ||
1155 | return rc; | ||
1156 | |||
1159 | return -EINVAL; | 1157 | return -EINVAL; |
1160 | } | 1158 | } |
1161 | 1159 | ||
diff --git a/drivers/net/ks8851.c b/drivers/net/ks8851.c index b4fb07a6f13..51919fcd50c 100644 --- a/drivers/net/ks8851.c +++ b/drivers/net/ks8851.c | |||
@@ -503,30 +503,33 @@ static void ks8851_rx_pkts(struct ks8851_net *ks) | |||
503 | ks8851_wrreg16(ks, KS_RXQCR, | 503 | ks8851_wrreg16(ks, KS_RXQCR, |
504 | ks->rc_rxqcr | RXQCR_SDA | RXQCR_ADRFE); | 504 | ks->rc_rxqcr | RXQCR_SDA | RXQCR_ADRFE); |
505 | 505 | ||
506 | if (rxlen > 0) { | 506 | if (rxlen > 4) { |
507 | skb = netdev_alloc_skb(ks->netdev, rxlen + 2 + 8); | 507 | unsigned int rxalign; |
508 | if (!skb) { | 508 | |
509 | /* todo - dump frame and move on */ | 509 | rxlen -= 4; |
510 | } | 510 | rxalign = ALIGN(rxlen, 4); |
511 | skb = netdev_alloc_skb_ip_align(ks->netdev, rxalign); | ||
512 | if (skb) { | ||
511 | 513 | ||
512 | /* two bytes to ensure ip is aligned, and four bytes | 514 | /* 4 bytes of status header + 4 bytes of |
513 | * for the status header and 4 bytes of garbage */ | 515 | * garbage: we put them before ethernet |
514 | skb_reserve(skb, 2 + 4 + 4); | 516 | * header, so that they are copied, |
517 | * but ignored. | ||
518 | */ | ||
515 | 519 | ||
516 | rxpkt = skb_put(skb, rxlen - 4) - 8; | 520 | rxpkt = skb_put(skb, rxlen) - 8; |
517 | 521 | ||
518 | /* align the packet length to 4 bytes, and add 4 bytes | 522 | ks8851_rdfifo(ks, rxpkt, rxalign + 8); |
519 | * as we're getting the rx status header as well */ | ||
520 | ks8851_rdfifo(ks, rxpkt, ALIGN(rxlen, 4) + 8); | ||
521 | 523 | ||
522 | if (netif_msg_pktdata(ks)) | 524 | if (netif_msg_pktdata(ks)) |
523 | ks8851_dbg_dumpkkt(ks, rxpkt); | 525 | ks8851_dbg_dumpkkt(ks, rxpkt); |
524 | 526 | ||
525 | skb->protocol = eth_type_trans(skb, ks->netdev); | 527 | skb->protocol = eth_type_trans(skb, ks->netdev); |
526 | netif_rx(skb); | 528 | netif_rx(skb); |
527 | 529 | ||
528 | ks->netdev->stats.rx_packets++; | 530 | ks->netdev->stats.rx_packets++; |
529 | ks->netdev->stats.rx_bytes += rxlen - 4; | 531 | ks->netdev->stats.rx_bytes += rxlen; |
532 | } | ||
530 | } | 533 | } |
531 | 534 | ||
532 | ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr); | 535 | ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr); |
diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c index c7b624711f5..87f0a93b165 100644 --- a/drivers/net/ll_temac_main.c +++ b/drivers/net/ll_temac_main.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/of_device.h> | 38 | #include <linux/of_device.h> |
39 | #include <linux/of_mdio.h> | 39 | #include <linux/of_mdio.h> |
40 | #include <linux/of_platform.h> | 40 | #include <linux/of_platform.h> |
41 | #include <linux/of_address.h> | ||
41 | #include <linux/skbuff.h> | 42 | #include <linux/skbuff.h> |
42 | #include <linux/spinlock.h> | 43 | #include <linux/spinlock.h> |
43 | #include <linux/tcp.h> /* needed for sizeof(tcphdr) */ | 44 | #include <linux/tcp.h> /* needed for sizeof(tcphdr) */ |
@@ -902,8 +903,8 @@ temac_poll_controller(struct net_device *ndev) | |||
902 | disable_irq(lp->tx_irq); | 903 | disable_irq(lp->tx_irq); |
903 | disable_irq(lp->rx_irq); | 904 | disable_irq(lp->rx_irq); |
904 | 905 | ||
905 | ll_temac_rx_irq(lp->tx_irq, lp); | 906 | ll_temac_rx_irq(lp->tx_irq, ndev); |
906 | ll_temac_tx_irq(lp->rx_irq, lp); | 907 | ll_temac_tx_irq(lp->rx_irq, ndev); |
907 | 908 | ||
908 | enable_irq(lp->tx_irq); | 909 | enable_irq(lp->tx_irq); |
909 | enable_irq(lp->rx_irq); | 910 | enable_irq(lp->rx_irq); |
diff --git a/drivers/net/ll_temac_mdio.c b/drivers/net/ll_temac_mdio.c index 5ae28c975b3..8cf9d4f56bb 100644 --- a/drivers/net/ll_temac_mdio.c +++ b/drivers/net/ll_temac_mdio.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/phy.h> | 10 | #include <linux/phy.h> |
11 | #include <linux/of.h> | 11 | #include <linux/of.h> |
12 | #include <linux/of_device.h> | 12 | #include <linux/of_device.h> |
13 | #include <linux/of_address.h> | ||
13 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
14 | #include <linux/of_mdio.h> | 15 | #include <linux/of_mdio.h> |
15 | 16 | ||
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index ffa1b9ce1cc..6dca3574e35 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h | |||
@@ -53,8 +53,8 @@ | |||
53 | 53 | ||
54 | #define _NETXEN_NIC_LINUX_MAJOR 4 | 54 | #define _NETXEN_NIC_LINUX_MAJOR 4 |
55 | #define _NETXEN_NIC_LINUX_MINOR 0 | 55 | #define _NETXEN_NIC_LINUX_MINOR 0 |
56 | #define _NETXEN_NIC_LINUX_SUBVERSION 73 | 56 | #define _NETXEN_NIC_LINUX_SUBVERSION 74 |
57 | #define NETXEN_NIC_LINUX_VERSIONID "4.0.73" | 57 | #define NETXEN_NIC_LINUX_VERSIONID "4.0.74" |
58 | 58 | ||
59 | #define NETXEN_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c)) | 59 | #define NETXEN_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c)) |
60 | #define _major(v) (((v) >> 24) & 0xff) | 60 | #define _major(v) (((v) >> 24) & 0xff) |
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index c865dda2adf..b075a35b85d 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c | |||
@@ -1540,7 +1540,6 @@ netxen_process_rcv(struct netxen_adapter *adapter, | |||
1540 | if (pkt_offset) | 1540 | if (pkt_offset) |
1541 | skb_pull(skb, pkt_offset); | 1541 | skb_pull(skb, pkt_offset); |
1542 | 1542 | ||
1543 | skb->truesize = skb->len + sizeof(struct sk_buff); | ||
1544 | skb->protocol = eth_type_trans(skb, netdev); | 1543 | skb->protocol = eth_type_trans(skb, netdev); |
1545 | 1544 | ||
1546 | napi_gro_receive(&sds_ring->napi, skb); | 1545 | napi_gro_receive(&sds_ring->napi, skb); |
@@ -1602,8 +1601,6 @@ netxen_process_lro(struct netxen_adapter *adapter, | |||
1602 | 1601 | ||
1603 | skb_put(skb, lro_length + data_offset); | 1602 | skb_put(skb, lro_length + data_offset); |
1604 | 1603 | ||
1605 | skb->truesize = skb->len + sizeof(struct sk_buff) + skb_headroom(skb); | ||
1606 | |||
1607 | skb_pull(skb, l2_hdr_offset); | 1604 | skb_pull(skb, l2_hdr_offset); |
1608 | skb->protocol = eth_type_trans(skb, netdev); | 1605 | skb->protocol = eth_type_trans(skb, netdev); |
1609 | 1606 | ||
@@ -1805,8 +1802,6 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid, | |||
1805 | netxen_ctx_msg msg = 0; | 1802 | netxen_ctx_msg msg = 0; |
1806 | struct list_head *head; | 1803 | struct list_head *head; |
1807 | 1804 | ||
1808 | spin_lock(&rds_ring->lock); | ||
1809 | |||
1810 | producer = rds_ring->producer; | 1805 | producer = rds_ring->producer; |
1811 | 1806 | ||
1812 | head = &rds_ring->free_list; | 1807 | head = &rds_ring->free_list; |
@@ -1853,8 +1848,6 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid, | |||
1853 | NETXEN_RCV_PRODUCER_OFFSET), msg); | 1848 | NETXEN_RCV_PRODUCER_OFFSET), msg); |
1854 | } | 1849 | } |
1855 | } | 1850 | } |
1856 | |||
1857 | spin_unlock(&rds_ring->lock); | ||
1858 | } | 1851 | } |
1859 | 1852 | ||
1860 | static void | 1853 | static void |
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index fd86e18604e..73d31459223 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -2032,8 +2032,6 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev) | |||
2032 | struct netxen_adapter *adapter = netdev_priv(netdev); | 2032 | struct netxen_adapter *adapter = netdev_priv(netdev); |
2033 | struct net_device_stats *stats = &netdev->stats; | 2033 | struct net_device_stats *stats = &netdev->stats; |
2034 | 2034 | ||
2035 | memset(stats, 0, sizeof(*stats)); | ||
2036 | |||
2037 | stats->rx_packets = adapter->stats.rx_pkts + adapter->stats.lro_pkts; | 2035 | stats->rx_packets = adapter->stats.rx_pkts + adapter->stats.lro_pkts; |
2038 | stats->tx_packets = adapter->stats.xmitfinished; | 2036 | stats->tx_packets = adapter->stats.xmitfinished; |
2039 | stats->rx_bytes = adapter->stats.rxbytes; | 2037 | stats->rx_bytes = adapter->stats.rxbytes; |
@@ -2133,9 +2131,16 @@ static int netxen_nic_poll(struct napi_struct *napi, int budget) | |||
2133 | #ifdef CONFIG_NET_POLL_CONTROLLER | 2131 | #ifdef CONFIG_NET_POLL_CONTROLLER |
2134 | static void netxen_nic_poll_controller(struct net_device *netdev) | 2132 | static void netxen_nic_poll_controller(struct net_device *netdev) |
2135 | { | 2133 | { |
2134 | int ring; | ||
2135 | struct nx_host_sds_ring *sds_ring; | ||
2136 | struct netxen_adapter *adapter = netdev_priv(netdev); | 2136 | struct netxen_adapter *adapter = netdev_priv(netdev); |
2137 | struct netxen_recv_context *recv_ctx = &adapter->recv_ctx; | ||
2138 | |||
2137 | disable_irq(adapter->irq); | 2139 | disable_irq(adapter->irq); |
2138 | netxen_intr(adapter->irq, adapter); | 2140 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { |
2141 | sds_ring = &recv_ctx->sds_rings[ring]; | ||
2142 | netxen_intr(adapter->irq, sds_ring); | ||
2143 | } | ||
2139 | enable_irq(adapter->irq); | 2144 | enable_irq(adapter->irq); |
2140 | } | 2145 | } |
2141 | #endif | 2146 | #endif |
diff --git a/drivers/net/niu.c b/drivers/net/niu.c index bc695d53cdc..fe6983af691 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c | |||
@@ -7269,32 +7269,28 @@ static int niu_get_ethtool_tcam_all(struct niu *np, | |||
7269 | struct niu_parent *parent = np->parent; | 7269 | struct niu_parent *parent = np->parent; |
7270 | struct niu_tcam_entry *tp; | 7270 | struct niu_tcam_entry *tp; |
7271 | int i, idx, cnt; | 7271 | int i, idx, cnt; |
7272 | u16 n_entries; | ||
7273 | unsigned long flags; | 7272 | unsigned long flags; |
7274 | 7273 | int ret = 0; | |
7275 | 7274 | ||
7276 | /* put the tcam size here */ | 7275 | /* put the tcam size here */ |
7277 | nfc->data = tcam_get_size(np); | 7276 | nfc->data = tcam_get_size(np); |
7278 | 7277 | ||
7279 | niu_lock_parent(np, flags); | 7278 | niu_lock_parent(np, flags); |
7280 | n_entries = nfc->rule_cnt; | ||
7281 | for (cnt = 0, i = 0; i < nfc->data; i++) { | 7279 | for (cnt = 0, i = 0; i < nfc->data; i++) { |
7282 | idx = tcam_get_index(np, i); | 7280 | idx = tcam_get_index(np, i); |
7283 | tp = &parent->tcam[idx]; | 7281 | tp = &parent->tcam[idx]; |
7284 | if (!tp->valid) | 7282 | if (!tp->valid) |
7285 | continue; | 7283 | continue; |
7284 | if (cnt == nfc->rule_cnt) { | ||
7285 | ret = -EMSGSIZE; | ||
7286 | break; | ||
7287 | } | ||
7286 | rule_locs[cnt] = i; | 7288 | rule_locs[cnt] = i; |
7287 | cnt++; | 7289 | cnt++; |
7288 | } | 7290 | } |
7289 | niu_unlock_parent(np, flags); | 7291 | niu_unlock_parent(np, flags); |
7290 | 7292 | ||
7291 | if (n_entries != cnt) { | 7293 | return ret; |
7292 | /* print warning, this should not happen */ | ||
7293 | netdev_info(np->dev, "niu%d: In %s(): n_entries[%d] != cnt[%d]!!!\n", | ||
7294 | np->parent->index, __func__, n_entries, cnt); | ||
7295 | } | ||
7296 | |||
7297 | return 0; | ||
7298 | } | 7294 | } |
7299 | 7295 | ||
7300 | static int niu_get_nfc(struct net_device *dev, struct ethtool_rxnfc *cmd, | 7296 | static int niu_get_nfc(struct net_device *dev, struct ethtool_rxnfc *cmd, |
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index c3edfe4c265..f9b509a6b09 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c | |||
@@ -508,7 +508,8 @@ static int pcnet_confcheck(struct pcmcia_device *p_dev, | |||
508 | unsigned int vcc, | 508 | unsigned int vcc, |
509 | void *priv_data) | 509 | void *priv_data) |
510 | { | 510 | { |
511 | int *has_shmem = priv_data; | 511 | int *priv = priv_data; |
512 | int try = (*priv & 0x1); | ||
512 | int i; | 513 | int i; |
513 | cistpl_io_t *io = &cfg->io; | 514 | cistpl_io_t *io = &cfg->io; |
514 | 515 | ||
@@ -525,77 +526,103 @@ static int pcnet_confcheck(struct pcmcia_device *p_dev, | |||
525 | i = p_dev->resource[1]->end = 0; | 526 | i = p_dev->resource[1]->end = 0; |
526 | } | 527 | } |
527 | 528 | ||
528 | *has_shmem = ((cfg->mem.nwin == 1) && | 529 | *priv &= ((cfg->mem.nwin == 1) && |
529 | (cfg->mem.win[0].len >= 0x4000)); | 530 | (cfg->mem.win[0].len >= 0x4000)) ? 0x10 : ~0x10; |
531 | |||
530 | p_dev->resource[0]->start = io->win[i].base; | 532 | p_dev->resource[0]->start = io->win[i].base; |
531 | p_dev->resource[0]->end = io->win[i].len; | 533 | p_dev->resource[0]->end = io->win[i].len; |
532 | p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK; | 534 | if (!try) |
535 | p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK; | ||
536 | else | ||
537 | p_dev->io_lines = 16; | ||
533 | if (p_dev->resource[0]->end + p_dev->resource[1]->end >= 32) | 538 | if (p_dev->resource[0]->end + p_dev->resource[1]->end >= 32) |
534 | return try_io_port(p_dev); | 539 | return try_io_port(p_dev); |
535 | 540 | ||
536 | return 0; | 541 | return -EINVAL; |
542 | } | ||
543 | |||
544 | static hw_info_t *pcnet_try_config(struct pcmcia_device *link, | ||
545 | int *has_shmem, int try) | ||
546 | { | ||
547 | struct net_device *dev = link->priv; | ||
548 | hw_info_t *local_hw_info; | ||
549 | pcnet_dev_t *info = PRIV(dev); | ||
550 | int priv = try; | ||
551 | int ret; | ||
552 | |||
553 | ret = pcmcia_loop_config(link, pcnet_confcheck, &priv); | ||
554 | if (ret) { | ||
555 | dev_warn(&link->dev, "no useable port range found\n"); | ||
556 | return NULL; | ||
557 | } | ||
558 | *has_shmem = (priv & 0x10); | ||
559 | |||
560 | if (!link->irq) | ||
561 | return NULL; | ||
562 | |||
563 | if (resource_size(link->resource[1]) == 8) { | ||
564 | link->conf.Attributes |= CONF_ENABLE_SPKR; | ||
565 | link->conf.Status = CCSR_AUDIO_ENA; | ||
566 | } | ||
567 | if ((link->manf_id == MANFID_IBM) && | ||
568 | (link->card_id == PRODID_IBM_HOME_AND_AWAY)) | ||
569 | link->conf.ConfigIndex |= 0x10; | ||
570 | |||
571 | ret = pcmcia_request_configuration(link, &link->conf); | ||
572 | if (ret) | ||
573 | return NULL; | ||
574 | |||
575 | dev->irq = link->irq; | ||
576 | dev->base_addr = link->resource[0]->start; | ||
577 | |||
578 | if (info->flags & HAS_MISC_REG) { | ||
579 | if ((if_port == 1) || (if_port == 2)) | ||
580 | dev->if_port = if_port; | ||
581 | else | ||
582 | dev_notice(&link->dev, "invalid if_port requested\n"); | ||
583 | } else | ||
584 | dev->if_port = 0; | ||
585 | |||
586 | if ((link->conf.ConfigBase == 0x03c0) && | ||
587 | (link->manf_id == 0x149) && (link->card_id == 0xc1ab)) { | ||
588 | dev_info(&link->dev, | ||
589 | "this is an AX88190 card - use axnet_cs instead.\n"); | ||
590 | return NULL; | ||
591 | } | ||
592 | |||
593 | local_hw_info = get_hwinfo(link); | ||
594 | if (!local_hw_info) | ||
595 | local_hw_info = get_prom(link); | ||
596 | if (!local_hw_info) | ||
597 | local_hw_info = get_dl10019(link); | ||
598 | if (!local_hw_info) | ||
599 | local_hw_info = get_ax88190(link); | ||
600 | if (!local_hw_info) | ||
601 | local_hw_info = get_hwired(link); | ||
602 | |||
603 | return local_hw_info; | ||
537 | } | 604 | } |
538 | 605 | ||
539 | static int pcnet_config(struct pcmcia_device *link) | 606 | static int pcnet_config(struct pcmcia_device *link) |
540 | { | 607 | { |
541 | struct net_device *dev = link->priv; | 608 | struct net_device *dev = link->priv; |
542 | pcnet_dev_t *info = PRIV(dev); | 609 | pcnet_dev_t *info = PRIV(dev); |
543 | int ret, start_pg, stop_pg, cm_offset; | 610 | int start_pg, stop_pg, cm_offset; |
544 | int has_shmem = 0; | 611 | int has_shmem = 0; |
545 | hw_info_t *local_hw_info; | 612 | hw_info_t *local_hw_info; |
546 | 613 | ||
547 | dev_dbg(&link->dev, "pcnet_config\n"); | 614 | dev_dbg(&link->dev, "pcnet_config\n"); |
548 | 615 | ||
549 | ret = pcmcia_loop_config(link, pcnet_confcheck, &has_shmem); | 616 | local_hw_info = pcnet_try_config(link, &has_shmem, 0); |
550 | if (ret) | 617 | if (!local_hw_info) { |
551 | goto failed; | 618 | /* check whether forcing io_lines to 16 helps... */ |
552 | 619 | pcmcia_disable_device(link); | |
553 | if (!link->irq) | 620 | local_hw_info = pcnet_try_config(link, &has_shmem, 1); |
554 | goto failed; | 621 | if (local_hw_info == NULL) { |
555 | 622 | dev_notice(&link->dev, "unable to read hardware net" | |
556 | if (resource_size(link->resource[1]) == 8) { | 623 | " address for io base %#3lx\n", dev->base_addr); |
557 | link->conf.Attributes |= CONF_ENABLE_SPKR; | 624 | goto failed; |
558 | link->conf.Status = CCSR_AUDIO_ENA; | 625 | } |
559 | } | ||
560 | if ((link->manf_id == MANFID_IBM) && | ||
561 | (link->card_id == PRODID_IBM_HOME_AND_AWAY)) | ||
562 | link->conf.ConfigIndex |= 0x10; | ||
563 | |||
564 | ret = pcmcia_request_configuration(link, &link->conf); | ||
565 | if (ret) | ||
566 | goto failed; | ||
567 | dev->irq = link->irq; | ||
568 | dev->base_addr = link->resource[0]->start; | ||
569 | if (info->flags & HAS_MISC_REG) { | ||
570 | if ((if_port == 1) || (if_port == 2)) | ||
571 | dev->if_port = if_port; | ||
572 | else | ||
573 | printk(KERN_NOTICE "pcnet_cs: invalid if_port requested\n"); | ||
574 | } else { | ||
575 | dev->if_port = 0; | ||
576 | } | ||
577 | |||
578 | if ((link->conf.ConfigBase == 0x03c0) && | ||
579 | (link->manf_id == 0x149) && (link->card_id == 0xc1ab)) { | ||
580 | printk(KERN_INFO "pcnet_cs: this is an AX88190 card!\n"); | ||
581 | printk(KERN_INFO "pcnet_cs: use axnet_cs instead.\n"); | ||
582 | goto failed; | ||
583 | } | ||
584 | |||
585 | local_hw_info = get_hwinfo(link); | ||
586 | if (local_hw_info == NULL) | ||
587 | local_hw_info = get_prom(link); | ||
588 | if (local_hw_info == NULL) | ||
589 | local_hw_info = get_dl10019(link); | ||
590 | if (local_hw_info == NULL) | ||
591 | local_hw_info = get_ax88190(link); | ||
592 | if (local_hw_info == NULL) | ||
593 | local_hw_info = get_hwired(link); | ||
594 | |||
595 | if (local_hw_info == NULL) { | ||
596 | printk(KERN_NOTICE "pcnet_cs: unable to read hardware net" | ||
597 | " address for io base %#3lx\n", dev->base_addr); | ||
598 | goto failed; | ||
599 | } | 626 | } |
600 | 627 | ||
601 | info->flags = local_hw_info->flags; | 628 | info->flags = local_hw_info->flags; |
@@ -1637,6 +1664,7 @@ static struct pcmcia_device_id pcnet_ids[] = { | |||
1637 | PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCETTX", 0x547e66dc, 0x6fc5459b), | 1664 | PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCETTX", 0x547e66dc, 0x6fc5459b), |
1638 | PCMCIA_DEVICE_PROD_ID12("iPort", "10/100 Ethernet Card", 0x56c538d2, 0x11b0ffc0), | 1665 | PCMCIA_DEVICE_PROD_ID12("iPort", "10/100 Ethernet Card", 0x56c538d2, 0x11b0ffc0), |
1639 | PCMCIA_DEVICE_PROD_ID12("KANSAI ELECTRIC CO.,LTD", "KLA-PCM/T", 0xb18dc3b4, 0xcc51a956), | 1666 | PCMCIA_DEVICE_PROD_ID12("KANSAI ELECTRIC CO.,LTD", "KLA-PCM/T", 0xb18dc3b4, 0xcc51a956), |
1667 | PCMCIA_DEVICE_PROD_ID12("KENTRONICS", "KEP-230", 0xaf8144c9, 0x868f6616), | ||
1640 | PCMCIA_DEVICE_PROD_ID12("KCI", "PE520 PCMCIA Ethernet Adapter", 0xa89b87d3, 0x1eb88e64), | 1668 | PCMCIA_DEVICE_PROD_ID12("KCI", "PE520 PCMCIA Ethernet Adapter", 0xa89b87d3, 0x1eb88e64), |
1641 | PCMCIA_DEVICE_PROD_ID12("KINGMAX", "EN10T2T", 0x7bcb459a, 0xa5c81fa5), | 1669 | PCMCIA_DEVICE_PROD_ID12("KINGMAX", "EN10T2T", 0x7bcb459a, 0xa5c81fa5), |
1642 | PCMCIA_DEVICE_PROD_ID12("Kingston", "KNE-PC2", 0x1128e633, 0xce2a89b3), | 1670 | PCMCIA_DEVICE_PROD_ID12("Kingston", "KNE-PC2", 0x1128e633, 0xce2a89b3), |
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 6a6b8199a0d..6c58da2b882 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c | |||
@@ -308,7 +308,7 @@ static int mdio_bus_suspend(struct device *dev) | |||
308 | * may call phy routines that try to grab the same lock, and that may | 308 | * may call phy routines that try to grab the same lock, and that may |
309 | * lead to a deadlock. | 309 | * lead to a deadlock. |
310 | */ | 310 | */ |
311 | if (phydev->attached_dev) | 311 | if (phydev->attached_dev && phydev->adjust_link) |
312 | phy_stop_machine(phydev); | 312 | phy_stop_machine(phydev); |
313 | 313 | ||
314 | if (!mdio_bus_phy_may_suspend(phydev)) | 314 | if (!mdio_bus_phy_may_suspend(phydev)) |
@@ -331,7 +331,7 @@ static int mdio_bus_resume(struct device *dev) | |||
331 | return ret; | 331 | return ret; |
332 | 332 | ||
333 | no_resume: | 333 | no_resume: |
334 | if (phydev->attached_dev) | 334 | if (phydev->attached_dev && phydev->adjust_link) |
335 | phy_start_machine(phydev, NULL); | 335 | phy_start_machine(phydev, NULL); |
336 | 336 | ||
337 | return 0; | 337 | return 0; |
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index c0761197c07..16ddc77313c 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c | |||
@@ -466,6 +466,8 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, | |||
466 | 466 | ||
467 | phydev->interface = interface; | 467 | phydev->interface = interface; |
468 | 468 | ||
469 | phydev->state = PHY_READY; | ||
470 | |||
469 | /* Do initial configuration here, now that | 471 | /* Do initial configuration here, now that |
470 | * we have certain key parameters | 472 | * we have certain key parameters |
471 | * (dev_flags and interface) */ | 473 | * (dev_flags and interface) */ |
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 6695a51e09e..736b91703b3 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c | |||
@@ -1314,8 +1314,13 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb) | |||
1314 | hdrlen = (ppp->flags & SC_MP_XSHORTSEQ)? MPHDRLEN_SSN: MPHDRLEN; | 1314 | hdrlen = (ppp->flags & SC_MP_XSHORTSEQ)? MPHDRLEN_SSN: MPHDRLEN; |
1315 | i = 0; | 1315 | i = 0; |
1316 | list_for_each_entry(pch, &ppp->channels, clist) { | 1316 | list_for_each_entry(pch, &ppp->channels, clist) { |
1317 | navail += pch->avail = (pch->chan != NULL); | 1317 | if (pch->chan) { |
1318 | pch->speed = pch->chan->speed; | 1318 | pch->avail = 1; |
1319 | navail++; | ||
1320 | pch->speed = pch->chan->speed; | ||
1321 | } else { | ||
1322 | pch->avail = 0; | ||
1323 | } | ||
1319 | if (pch->avail) { | 1324 | if (pch->avail) { |
1320 | if (skb_queue_empty(&pch->file.xq) || | 1325 | if (skb_queue_empty(&pch->file.xq) || |
1321 | !pch->had_frag) { | 1326 | !pch->had_frag) { |
diff --git a/drivers/net/pxa168_eth.c b/drivers/net/pxa168_eth.c new file mode 100644 index 00000000000..85eddda276b --- /dev/null +++ b/drivers/net/pxa168_eth.c | |||
@@ -0,0 +1,1666 @@ | |||
1 | /* | ||
2 | * PXA168 ethernet driver. | ||
3 | * Most of the code is derived from mv643xx ethernet driver. | ||
4 | * | ||
5 | * Copyright (C) 2010 Marvell International Ltd. | ||
6 | * Sachin Sanap <ssanap@marvell.com> | ||
7 | * Philip Rakity <prakity@marvell.com> | ||
8 | * Mark Brown <markb@marvell.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or | ||
11 | * modify it under the terms of the GNU General Public License | ||
12 | * as published by the Free Software Foundation; either version 2 | ||
13 | * of the License, or (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
23 | */ | ||
24 | |||
25 | #include <linux/init.h> | ||
26 | #include <linux/dma-mapping.h> | ||
27 | #include <linux/in.h> | ||
28 | #include <linux/ip.h> | ||
29 | #include <linux/tcp.h> | ||
30 | #include <linux/udp.h> | ||
31 | #include <linux/etherdevice.h> | ||
32 | #include <linux/bitops.h> | ||
33 | #include <linux/delay.h> | ||
34 | #include <linux/ethtool.h> | ||
35 | #include <linux/platform_device.h> | ||
36 | #include <linux/module.h> | ||
37 | #include <linux/kernel.h> | ||
38 | #include <linux/workqueue.h> | ||
39 | #include <linux/clk.h> | ||
40 | #include <linux/phy.h> | ||
41 | #include <linux/io.h> | ||
42 | #include <linux/types.h> | ||
43 | #include <asm/pgtable.h> | ||
44 | #include <asm/system.h> | ||
45 | #include <linux/delay.h> | ||
46 | #include <linux/dma-mapping.h> | ||
47 | #include <asm/cacheflush.h> | ||
48 | #include <linux/pxa168_eth.h> | ||
49 | |||
50 | #define DRIVER_NAME "pxa168-eth" | ||
51 | #define DRIVER_VERSION "0.3" | ||
52 | |||
53 | /* | ||
54 | * Registers | ||
55 | */ | ||
56 | |||
57 | #define PHY_ADDRESS 0x0000 | ||
58 | #define SMI 0x0010 | ||
59 | #define PORT_CONFIG 0x0400 | ||
60 | #define PORT_CONFIG_EXT 0x0408 | ||
61 | #define PORT_COMMAND 0x0410 | ||
62 | #define PORT_STATUS 0x0418 | ||
63 | #define HTPR 0x0428 | ||
64 | #define SDMA_CONFIG 0x0440 | ||
65 | #define SDMA_CMD 0x0448 | ||
66 | #define INT_CAUSE 0x0450 | ||
67 | #define INT_W_CLEAR 0x0454 | ||
68 | #define INT_MASK 0x0458 | ||
69 | #define ETH_F_RX_DESC_0 0x0480 | ||
70 | #define ETH_C_RX_DESC_0 0x04A0 | ||
71 | #define ETH_C_TX_DESC_1 0x04E4 | ||
72 | |||
73 | /* smi register */ | ||
74 | #define SMI_BUSY (1 << 28) /* 0 - Write, 1 - Read */ | ||
75 | #define SMI_R_VALID (1 << 27) /* 0 - Write, 1 - Read */ | ||
76 | #define SMI_OP_W (0 << 26) /* Write operation */ | ||
77 | #define SMI_OP_R (1 << 26) /* Read operation */ | ||
78 | |||
79 | #define PHY_WAIT_ITERATIONS 10 | ||
80 | |||
81 | #define PXA168_ETH_PHY_ADDR_DEFAULT 0 | ||
82 | /* RX & TX descriptor command */ | ||
83 | #define BUF_OWNED_BY_DMA (1 << 31) | ||
84 | |||
85 | /* RX descriptor status */ | ||
86 | #define RX_EN_INT (1 << 23) | ||
87 | #define RX_FIRST_DESC (1 << 17) | ||
88 | #define RX_LAST_DESC (1 << 16) | ||
89 | #define RX_ERROR (1 << 15) | ||
90 | |||
91 | /* TX descriptor command */ | ||
92 | #define TX_EN_INT (1 << 23) | ||
93 | #define TX_GEN_CRC (1 << 22) | ||
94 | #define TX_ZERO_PADDING (1 << 18) | ||
95 | #define TX_FIRST_DESC (1 << 17) | ||
96 | #define TX_LAST_DESC (1 << 16) | ||
97 | #define TX_ERROR (1 << 15) | ||
98 | |||
99 | /* SDMA_CMD */ | ||
100 | #define SDMA_CMD_AT (1 << 31) | ||
101 | #define SDMA_CMD_TXDL (1 << 24) | ||
102 | #define SDMA_CMD_TXDH (1 << 23) | ||
103 | #define SDMA_CMD_AR (1 << 15) | ||
104 | #define SDMA_CMD_ERD (1 << 7) | ||
105 | |||
106 | /* Bit definitions of the Port Config Reg */ | ||
107 | #define PCR_HS (1 << 12) | ||
108 | #define PCR_EN (1 << 7) | ||
109 | #define PCR_PM (1 << 0) | ||
110 | |||
111 | /* Bit definitions of the Port Config Extend Reg */ | ||
112 | #define PCXR_2BSM (1 << 28) | ||
113 | #define PCXR_DSCP_EN (1 << 21) | ||
114 | #define PCXR_MFL_1518 (0 << 14) | ||
115 | #define PCXR_MFL_1536 (1 << 14) | ||
116 | #define PCXR_MFL_2048 (2 << 14) | ||
117 | #define PCXR_MFL_64K (3 << 14) | ||
118 | #define PCXR_FLP (1 << 11) | ||
119 | #define PCXR_PRIO_TX_OFF 3 | ||
120 | #define PCXR_TX_HIGH_PRI (7 << PCXR_PRIO_TX_OFF) | ||
121 | |||
122 | /* Bit definitions of the SDMA Config Reg */ | ||
123 | #define SDCR_BSZ_OFF 12 | ||
124 | #define SDCR_BSZ8 (3 << SDCR_BSZ_OFF) | ||
125 | #define SDCR_BSZ4 (2 << SDCR_BSZ_OFF) | ||
126 | #define SDCR_BSZ2 (1 << SDCR_BSZ_OFF) | ||
127 | #define SDCR_BSZ1 (0 << SDCR_BSZ_OFF) | ||
128 | #define SDCR_BLMR (1 << 6) | ||
129 | #define SDCR_BLMT (1 << 7) | ||
130 | #define SDCR_RIFB (1 << 9) | ||
131 | #define SDCR_RC_OFF 2 | ||
132 | #define SDCR_RC_MAX_RETRANS (0xf << SDCR_RC_OFF) | ||
133 | |||
134 | /* | ||
135 | * Bit definitions of the Interrupt Cause Reg | ||
136 | * and Interrupt MASK Reg is the same | ||
137 | */ | ||
138 | #define ICR_RXBUF (1 << 0) | ||
139 | #define ICR_TXBUF_H (1 << 2) | ||
140 | #define ICR_TXBUF_L (1 << 3) | ||
141 | #define ICR_TXEND_H (1 << 6) | ||
142 | #define ICR_TXEND_L (1 << 7) | ||
143 | #define ICR_RXERR (1 << 8) | ||
144 | #define ICR_TXERR_H (1 << 10) | ||
145 | #define ICR_TXERR_L (1 << 11) | ||
146 | #define ICR_TX_UDR (1 << 13) | ||
147 | #define ICR_MII_CH (1 << 28) | ||
148 | |||
149 | #define ALL_INTS (ICR_TXBUF_H | ICR_TXBUF_L | ICR_TX_UDR |\ | ||
150 | ICR_TXERR_H | ICR_TXERR_L |\ | ||
151 | ICR_TXEND_H | ICR_TXEND_L |\ | ||
152 | ICR_RXBUF | ICR_RXERR | ICR_MII_CH) | ||
153 | |||
154 | #define ETH_HW_IP_ALIGN 2 /* hw aligns IP header */ | ||
155 | |||
156 | #define NUM_RX_DESCS 64 | ||
157 | #define NUM_TX_DESCS 64 | ||
158 | |||
159 | #define HASH_ADD 0 | ||
160 | #define HASH_DELETE 1 | ||
161 | #define HASH_ADDR_TABLE_SIZE 0x4000 /* 16K (1/2K address - PCR_HS == 1) */ | ||
162 | #define HOP_NUMBER 12 | ||
163 | |||
164 | /* Bit definitions for Port status */ | ||
165 | #define PORT_SPEED_100 (1 << 0) | ||
166 | #define FULL_DUPLEX (1 << 1) | ||
167 | #define FLOW_CONTROL_ENABLED (1 << 2) | ||
168 | #define LINK_UP (1 << 3) | ||
169 | |||
170 | /* Bit definitions for work to be done */ | ||
171 | #define WORK_LINK (1 << 0) | ||
172 | #define WORK_TX_DONE (1 << 1) | ||
173 | |||
174 | /* | ||
175 | * Misc definitions. | ||
176 | */ | ||
177 | #define SKB_DMA_REALIGN ((PAGE_SIZE - NET_SKB_PAD) % SMP_CACHE_BYTES) | ||
178 | |||
179 | struct rx_desc { | ||
180 | u32 cmd_sts; /* Descriptor command status */ | ||
181 | u16 byte_cnt; /* Descriptor buffer byte count */ | ||
182 | u16 buf_size; /* Buffer size */ | ||
183 | u32 buf_ptr; /* Descriptor buffer pointer */ | ||
184 | u32 next_desc_ptr; /* Next descriptor pointer */ | ||
185 | }; | ||
186 | |||
187 | struct tx_desc { | ||
188 | u32 cmd_sts; /* Command/status field */ | ||
189 | u16 reserved; | ||
190 | u16 byte_cnt; /* buffer byte count */ | ||
191 | u32 buf_ptr; /* pointer to buffer for this descriptor */ | ||
192 | u32 next_desc_ptr; /* Pointer to next descriptor */ | ||
193 | }; | ||
194 | |||
195 | struct pxa168_eth_private { | ||
196 | int port_num; /* User Ethernet port number */ | ||
197 | |||
198 | int rx_resource_err; /* Rx ring resource error flag */ | ||
199 | |||
200 | /* Next available and first returning Rx resource */ | ||
201 | int rx_curr_desc_q, rx_used_desc_q; | ||
202 | |||
203 | /* Next available and first returning Tx resource */ | ||
204 | int tx_curr_desc_q, tx_used_desc_q; | ||
205 | |||
206 | struct rx_desc *p_rx_desc_area; | ||
207 | dma_addr_t rx_desc_dma; | ||
208 | int rx_desc_area_size; | ||
209 | struct sk_buff **rx_skb; | ||
210 | |||
211 | struct tx_desc *p_tx_desc_area; | ||
212 | dma_addr_t tx_desc_dma; | ||
213 | int tx_desc_area_size; | ||
214 | struct sk_buff **tx_skb; | ||
215 | |||
216 | struct work_struct tx_timeout_task; | ||
217 | |||
218 | struct net_device *dev; | ||
219 | struct napi_struct napi; | ||
220 | u8 work_todo; | ||
221 | int skb_size; | ||
222 | |||
223 | struct net_device_stats stats; | ||
224 | /* Size of Tx Ring per queue */ | ||
225 | int tx_ring_size; | ||
226 | /* Number of tx descriptors in use */ | ||
227 | int tx_desc_count; | ||
228 | /* Size of Rx Ring per queue */ | ||
229 | int rx_ring_size; | ||
230 | /* Number of rx descriptors in use */ | ||
231 | int rx_desc_count; | ||
232 | |||
233 | /* | ||
234 | * Used in case RX Ring is empty, which can occur when | ||
235 | * system does not have resources (skb's) | ||
236 | */ | ||
237 | struct timer_list timeout; | ||
238 | struct mii_bus *smi_bus; | ||
239 | struct phy_device *phy; | ||
240 | |||
241 | /* clock */ | ||
242 | struct clk *clk; | ||
243 | struct pxa168_eth_platform_data *pd; | ||
244 | /* | ||
245 | * Ethernet controller base address. | ||
246 | */ | ||
247 | void __iomem *base; | ||
248 | |||
249 | /* Pointer to the hardware address filter table */ | ||
250 | void *htpr; | ||
251 | dma_addr_t htpr_dma; | ||
252 | }; | ||
253 | |||
254 | struct addr_table_entry { | ||
255 | __le32 lo; | ||
256 | __le32 hi; | ||
257 | }; | ||
258 | |||
259 | /* Bit fields of a Hash Table Entry */ | ||
260 | enum hash_table_entry { | ||
261 | HASH_ENTRY_VALID = 1, | ||
262 | SKIP = 2, | ||
263 | HASH_ENTRY_RECEIVE_DISCARD = 4, | ||
264 | HASH_ENTRY_RECEIVE_DISCARD_BIT = 2 | ||
265 | }; | ||
266 | |||
267 | static int pxa168_get_settings(struct net_device *dev, struct ethtool_cmd *cmd); | ||
268 | static int pxa168_set_settings(struct net_device *dev, struct ethtool_cmd *cmd); | ||
269 | static int pxa168_init_hw(struct pxa168_eth_private *pep); | ||
270 | static void eth_port_reset(struct net_device *dev); | ||
271 | static void eth_port_start(struct net_device *dev); | ||
272 | static int pxa168_eth_open(struct net_device *dev); | ||
273 | static int pxa168_eth_stop(struct net_device *dev); | ||
274 | static int ethernet_phy_setup(struct net_device *dev); | ||
275 | |||
276 | static inline u32 rdl(struct pxa168_eth_private *pep, int offset) | ||
277 | { | ||
278 | return readl(pep->base + offset); | ||
279 | } | ||
280 | |||
281 | static inline void wrl(struct pxa168_eth_private *pep, int offset, u32 data) | ||
282 | { | ||
283 | writel(data, pep->base + offset); | ||
284 | } | ||
285 | |||
286 | static void abort_dma(struct pxa168_eth_private *pep) | ||
287 | { | ||
288 | int delay; | ||
289 | int max_retries = 40; | ||
290 | |||
291 | do { | ||
292 | wrl(pep, SDMA_CMD, SDMA_CMD_AR | SDMA_CMD_AT); | ||
293 | udelay(100); | ||
294 | |||
295 | delay = 10; | ||
296 | while ((rdl(pep, SDMA_CMD) & (SDMA_CMD_AR | SDMA_CMD_AT)) | ||
297 | && delay-- > 0) { | ||
298 | udelay(10); | ||
299 | } | ||
300 | } while (max_retries-- > 0 && delay <= 0); | ||
301 | |||
302 | if (max_retries <= 0) | ||
303 | printk(KERN_ERR "%s : DMA Stuck\n", __func__); | ||
304 | } | ||
305 | |||
306 | static int ethernet_phy_get(struct pxa168_eth_private *pep) | ||
307 | { | ||
308 | unsigned int reg_data; | ||
309 | |||
310 | reg_data = rdl(pep, PHY_ADDRESS); | ||
311 | |||
312 | return (reg_data >> (5 * pep->port_num)) & 0x1f; | ||
313 | } | ||
314 | |||
315 | static void ethernet_phy_set_addr(struct pxa168_eth_private *pep, int phy_addr) | ||
316 | { | ||
317 | u32 reg_data; | ||
318 | int addr_shift = 5 * pep->port_num; | ||
319 | |||
320 | reg_data = rdl(pep, PHY_ADDRESS); | ||
321 | reg_data &= ~(0x1f << addr_shift); | ||
322 | reg_data |= (phy_addr & 0x1f) << addr_shift; | ||
323 | wrl(pep, PHY_ADDRESS, reg_data); | ||
324 | } | ||
325 | |||
326 | static void ethernet_phy_reset(struct pxa168_eth_private *pep) | ||
327 | { | ||
328 | int data; | ||
329 | |||
330 | data = phy_read(pep->phy, MII_BMCR); | ||
331 | if (data < 0) | ||
332 | return; | ||
333 | |||
334 | data |= BMCR_RESET; | ||
335 | if (phy_write(pep->phy, MII_BMCR, data) < 0) | ||
336 | return; | ||
337 | |||
338 | do { | ||
339 | data = phy_read(pep->phy, MII_BMCR); | ||
340 | } while (data >= 0 && data & BMCR_RESET); | ||
341 | } | ||
342 | |||
343 | static void rxq_refill(struct net_device *dev) | ||
344 | { | ||
345 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
346 | struct sk_buff *skb; | ||
347 | struct rx_desc *p_used_rx_desc; | ||
348 | int used_rx_desc; | ||
349 | |||
350 | while (pep->rx_desc_count < pep->rx_ring_size) { | ||
351 | int size; | ||
352 | |||
353 | skb = dev_alloc_skb(pep->skb_size); | ||
354 | if (!skb) | ||
355 | break; | ||
356 | if (SKB_DMA_REALIGN) | ||
357 | skb_reserve(skb, SKB_DMA_REALIGN); | ||
358 | pep->rx_desc_count++; | ||
359 | /* Get 'used' Rx descriptor */ | ||
360 | used_rx_desc = pep->rx_used_desc_q; | ||
361 | p_used_rx_desc = &pep->p_rx_desc_area[used_rx_desc]; | ||
362 | size = skb->end - skb->data; | ||
363 | p_used_rx_desc->buf_ptr = dma_map_single(NULL, | ||
364 | skb->data, | ||
365 | size, | ||
366 | DMA_FROM_DEVICE); | ||
367 | p_used_rx_desc->buf_size = size; | ||
368 | pep->rx_skb[used_rx_desc] = skb; | ||
369 | |||
370 | /* Return the descriptor to DMA ownership */ | ||
371 | wmb(); | ||
372 | p_used_rx_desc->cmd_sts = BUF_OWNED_BY_DMA | RX_EN_INT; | ||
373 | wmb(); | ||
374 | |||
375 | /* Move the used descriptor pointer to the next descriptor */ | ||
376 | pep->rx_used_desc_q = (used_rx_desc + 1) % pep->rx_ring_size; | ||
377 | |||
378 | /* Any Rx return cancels the Rx resource error status */ | ||
379 | pep->rx_resource_err = 0; | ||
380 | |||
381 | skb_reserve(skb, ETH_HW_IP_ALIGN); | ||
382 | } | ||
383 | |||
384 | /* | ||
385 | * If RX ring is empty of SKB, set a timer to try allocating | ||
386 | * again at a later time. | ||
387 | */ | ||
388 | if (pep->rx_desc_count == 0) { | ||
389 | pep->timeout.expires = jiffies + (HZ / 10); | ||
390 | add_timer(&pep->timeout); | ||
391 | } | ||
392 | } | ||
393 | |||
394 | static inline void rxq_refill_timer_wrapper(unsigned long data) | ||
395 | { | ||
396 | struct pxa168_eth_private *pep = (void *)data; | ||
397 | napi_schedule(&pep->napi); | ||
398 | } | ||
399 | |||
400 | static inline u8 flip_8_bits(u8 x) | ||
401 | { | ||
402 | return (((x) & 0x01) << 3) | (((x) & 0x02) << 1) | ||
403 | | (((x) & 0x04) >> 1) | (((x) & 0x08) >> 3) | ||
404 | | (((x) & 0x10) << 3) | (((x) & 0x20) << 1) | ||
405 | | (((x) & 0x40) >> 1) | (((x) & 0x80) >> 3); | ||
406 | } | ||
407 | |||
408 | static void nibble_swap_every_byte(unsigned char *mac_addr) | ||
409 | { | ||
410 | int i; | ||
411 | for (i = 0; i < ETH_ALEN; i++) { | ||
412 | mac_addr[i] = ((mac_addr[i] & 0x0f) << 4) | | ||
413 | ((mac_addr[i] & 0xf0) >> 4); | ||
414 | } | ||
415 | } | ||
416 | |||
417 | static void inverse_every_nibble(unsigned char *mac_addr) | ||
418 | { | ||
419 | int i; | ||
420 | for (i = 0; i < ETH_ALEN; i++) | ||
421 | mac_addr[i] = flip_8_bits(mac_addr[i]); | ||
422 | } | ||
423 | |||
424 | /* | ||
425 | * ---------------------------------------------------------------------------- | ||
426 | * This function will calculate the hash function of the address. | ||
427 | * Inputs | ||
428 | * mac_addr_orig - MAC address. | ||
429 | * Outputs | ||
430 | * return the calculated entry. | ||
431 | */ | ||
432 | static u32 hash_function(unsigned char *mac_addr_orig) | ||
433 | { | ||
434 | u32 hash_result; | ||
435 | u32 addr0; | ||
436 | u32 addr1; | ||
437 | u32 addr2; | ||
438 | u32 addr3; | ||
439 | unsigned char mac_addr[ETH_ALEN]; | ||
440 | |||
441 | /* Make a copy of MAC address since we are going to performe bit | ||
442 | * operations on it | ||
443 | */ | ||
444 | memcpy(mac_addr, mac_addr_orig, ETH_ALEN); | ||
445 | |||
446 | nibble_swap_every_byte(mac_addr); | ||
447 | inverse_every_nibble(mac_addr); | ||
448 | |||
449 | addr0 = (mac_addr[5] >> 2) & 0x3f; | ||
450 | addr1 = (mac_addr[5] & 0x03) | (((mac_addr[4] & 0x7f)) << 2); | ||
451 | addr2 = ((mac_addr[4] & 0x80) >> 7) | mac_addr[3] << 1; | ||
452 | addr3 = (mac_addr[2] & 0xff) | ((mac_addr[1] & 1) << 8); | ||
453 | |||
454 | hash_result = (addr0 << 9) | (addr1 ^ addr2 ^ addr3); | ||
455 | hash_result = hash_result & 0x07ff; | ||
456 | return hash_result; | ||
457 | } | ||
458 | |||
459 | /* | ||
460 | * ---------------------------------------------------------------------------- | ||
461 | * This function will add/del an entry to the address table. | ||
462 | * Inputs | ||
463 | * pep - ETHERNET . | ||
464 | * mac_addr - MAC address. | ||
465 | * skip - if 1, skip this address.Used in case of deleting an entry which is a | ||
466 | * part of chain in the hash table.We cant just delete the entry since | ||
467 | * that will break the chain.We need to defragment the tables time to | ||
468 | * time. | ||
469 | * rd - 0 Discard packet upon match. | ||
470 | * - 1 Receive packet upon match. | ||
471 | * Outputs | ||
472 | * address table entry is added/deleted. | ||
473 | * 0 if success. | ||
474 | * -ENOSPC if table full | ||
475 | */ | ||
476 | static int add_del_hash_entry(struct pxa168_eth_private *pep, | ||
477 | unsigned char *mac_addr, | ||
478 | u32 rd, u32 skip, int del) | ||
479 | { | ||
480 | struct addr_table_entry *entry, *start; | ||
481 | u32 new_high; | ||
482 | u32 new_low; | ||
483 | u32 i; | ||
484 | |||
485 | new_low = (((mac_addr[1] >> 4) & 0xf) << 15) | ||
486 | | (((mac_addr[1] >> 0) & 0xf) << 11) | ||
487 | | (((mac_addr[0] >> 4) & 0xf) << 7) | ||
488 | | (((mac_addr[0] >> 0) & 0xf) << 3) | ||
489 | | (((mac_addr[3] >> 4) & 0x1) << 31) | ||
490 | | (((mac_addr[3] >> 0) & 0xf) << 27) | ||
491 | | (((mac_addr[2] >> 4) & 0xf) << 23) | ||
492 | | (((mac_addr[2] >> 0) & 0xf) << 19) | ||
493 | | (skip << SKIP) | (rd << HASH_ENTRY_RECEIVE_DISCARD_BIT) | ||
494 | | HASH_ENTRY_VALID; | ||
495 | |||
496 | new_high = (((mac_addr[5] >> 4) & 0xf) << 15) | ||
497 | | (((mac_addr[5] >> 0) & 0xf) << 11) | ||
498 | | (((mac_addr[4] >> 4) & 0xf) << 7) | ||
499 | | (((mac_addr[4] >> 0) & 0xf) << 3) | ||
500 | | (((mac_addr[3] >> 5) & 0x7) << 0); | ||
501 | |||
502 | /* | ||
503 | * Pick the appropriate table, start scanning for free/reusable | ||
504 | * entries at the index obtained by hashing the specified MAC address | ||
505 | */ | ||
506 | start = (struct addr_table_entry *)(pep->htpr); | ||
507 | entry = start + hash_function(mac_addr); | ||
508 | for (i = 0; i < HOP_NUMBER; i++) { | ||
509 | if (!(le32_to_cpu(entry->lo) & HASH_ENTRY_VALID)) { | ||
510 | break; | ||
511 | } else { | ||
512 | /* if same address put in same position */ | ||
513 | if (((le32_to_cpu(entry->lo) & 0xfffffff8) == | ||
514 | (new_low & 0xfffffff8)) && | ||
515 | (le32_to_cpu(entry->hi) == new_high)) { | ||
516 | break; | ||
517 | } | ||
518 | } | ||
519 | if (entry == start + 0x7ff) | ||
520 | entry = start; | ||
521 | else | ||
522 | entry++; | ||
523 | } | ||
524 | |||
525 | if (((le32_to_cpu(entry->lo) & 0xfffffff8) != (new_low & 0xfffffff8)) && | ||
526 | (le32_to_cpu(entry->hi) != new_high) && del) | ||
527 | return 0; | ||
528 | |||
529 | if (i == HOP_NUMBER) { | ||
530 | if (!del) { | ||
531 | printk(KERN_INFO "%s: table section is full, need to " | ||
532 | "move to 16kB implementation?\n", | ||
533 | __FILE__); | ||
534 | return -ENOSPC; | ||
535 | } else | ||
536 | return 0; | ||
537 | } | ||
538 | |||
539 | /* | ||
540 | * Update the selected entry | ||
541 | */ | ||
542 | if (del) { | ||
543 | entry->hi = 0; | ||
544 | entry->lo = 0; | ||
545 | } else { | ||
546 | entry->hi = cpu_to_le32(new_high); | ||
547 | entry->lo = cpu_to_le32(new_low); | ||
548 | } | ||
549 | |||
550 | return 0; | ||
551 | } | ||
552 | |||
553 | /* | ||
554 | * ---------------------------------------------------------------------------- | ||
555 | * Create an addressTable entry from MAC address info | ||
556 | * found in the specifed net_device struct | ||
557 | * | ||
558 | * Input : pointer to ethernet interface network device structure | ||
559 | * Output : N/A | ||
560 | */ | ||
561 | static void update_hash_table_mac_address(struct pxa168_eth_private *pep, | ||
562 | unsigned char *oaddr, | ||
563 | unsigned char *addr) | ||
564 | { | ||
565 | /* Delete old entry */ | ||
566 | if (oaddr) | ||
567 | add_del_hash_entry(pep, oaddr, 1, 0, HASH_DELETE); | ||
568 | /* Add new entry */ | ||
569 | add_del_hash_entry(pep, addr, 1, 0, HASH_ADD); | ||
570 | } | ||
571 | |||
572 | static int init_hash_table(struct pxa168_eth_private *pep) | ||
573 | { | ||
574 | /* | ||
575 | * Hardware expects CPU to build a hash table based on a predefined | ||
576 | * hash function and populate it based on hardware address. The | ||
577 | * location of the hash table is identified by 32-bit pointer stored | ||
578 | * in HTPR internal register. Two possible sizes exists for the hash | ||
579 | * table 8kB (256kB of DRAM required (4 x 64 kB banks)) and 1/2kB | ||
580 | * (16kB of DRAM required (4 x 4 kB banks)).We currently only support | ||
581 | * 1/2kB. | ||
582 | */ | ||
583 | /* TODO: Add support for 8kB hash table and alternative hash | ||
584 | * function.Driver can dynamically switch to them if the 1/2kB hash | ||
585 | * table is full. | ||
586 | */ | ||
587 | if (pep->htpr == NULL) { | ||
588 | pep->htpr = dma_alloc_coherent(pep->dev->dev.parent, | ||
589 | HASH_ADDR_TABLE_SIZE, | ||
590 | &pep->htpr_dma, GFP_KERNEL); | ||
591 | if (pep->htpr == NULL) | ||
592 | return -ENOMEM; | ||
593 | } | ||
594 | memset(pep->htpr, 0, HASH_ADDR_TABLE_SIZE); | ||
595 | wrl(pep, HTPR, pep->htpr_dma); | ||
596 | return 0; | ||
597 | } | ||
598 | |||
599 | static void pxa168_eth_set_rx_mode(struct net_device *dev) | ||
600 | { | ||
601 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
602 | struct netdev_hw_addr *ha; | ||
603 | u32 val; | ||
604 | |||
605 | val = rdl(pep, PORT_CONFIG); | ||
606 | if (dev->flags & IFF_PROMISC) | ||
607 | val |= PCR_PM; | ||
608 | else | ||
609 | val &= ~PCR_PM; | ||
610 | wrl(pep, PORT_CONFIG, val); | ||
611 | |||
612 | /* | ||
613 | * Remove the old list of MAC address and add dev->addr | ||
614 | * and multicast address. | ||
615 | */ | ||
616 | memset(pep->htpr, 0, HASH_ADDR_TABLE_SIZE); | ||
617 | update_hash_table_mac_address(pep, NULL, dev->dev_addr); | ||
618 | |||
619 | netdev_for_each_mc_addr(ha, dev) | ||
620 | update_hash_table_mac_address(pep, NULL, ha->addr); | ||
621 | } | ||
622 | |||
623 | static int pxa168_eth_set_mac_address(struct net_device *dev, void *addr) | ||
624 | { | ||
625 | struct sockaddr *sa = addr; | ||
626 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
627 | unsigned char oldMac[ETH_ALEN]; | ||
628 | |||
629 | if (!is_valid_ether_addr(sa->sa_data)) | ||
630 | return -EINVAL; | ||
631 | memcpy(oldMac, dev->dev_addr, ETH_ALEN); | ||
632 | memcpy(dev->dev_addr, sa->sa_data, ETH_ALEN); | ||
633 | netif_addr_lock_bh(dev); | ||
634 | update_hash_table_mac_address(pep, oldMac, dev->dev_addr); | ||
635 | netif_addr_unlock_bh(dev); | ||
636 | return 0; | ||
637 | } | ||
638 | |||
639 | static void eth_port_start(struct net_device *dev) | ||
640 | { | ||
641 | unsigned int val = 0; | ||
642 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
643 | int tx_curr_desc, rx_curr_desc; | ||
644 | |||
645 | /* Perform PHY reset, if there is a PHY. */ | ||
646 | if (pep->phy != NULL) { | ||
647 | struct ethtool_cmd cmd; | ||
648 | |||
649 | pxa168_get_settings(pep->dev, &cmd); | ||
650 | ethernet_phy_reset(pep); | ||
651 | pxa168_set_settings(pep->dev, &cmd); | ||
652 | } | ||
653 | |||
654 | /* Assignment of Tx CTRP of given queue */ | ||
655 | tx_curr_desc = pep->tx_curr_desc_q; | ||
656 | wrl(pep, ETH_C_TX_DESC_1, | ||
657 | (u32) (pep->tx_desc_dma + tx_curr_desc * sizeof(struct tx_desc))); | ||
658 | |||
659 | /* Assignment of Rx CRDP of given queue */ | ||
660 | rx_curr_desc = pep->rx_curr_desc_q; | ||
661 | wrl(pep, ETH_C_RX_DESC_0, | ||
662 | (u32) (pep->rx_desc_dma + rx_curr_desc * sizeof(struct rx_desc))); | ||
663 | |||
664 | wrl(pep, ETH_F_RX_DESC_0, | ||
665 | (u32) (pep->rx_desc_dma + rx_curr_desc * sizeof(struct rx_desc))); | ||
666 | |||
667 | /* Clear all interrupts */ | ||
668 | wrl(pep, INT_CAUSE, 0); | ||
669 | |||
670 | /* Enable all interrupts for receive, transmit and error. */ | ||
671 | wrl(pep, INT_MASK, ALL_INTS); | ||
672 | |||
673 | val = rdl(pep, PORT_CONFIG); | ||
674 | val |= PCR_EN; | ||
675 | wrl(pep, PORT_CONFIG, val); | ||
676 | |||
677 | /* Start RX DMA engine */ | ||
678 | val = rdl(pep, SDMA_CMD); | ||
679 | val |= SDMA_CMD_ERD; | ||
680 | wrl(pep, SDMA_CMD, val); | ||
681 | } | ||
682 | |||
683 | static void eth_port_reset(struct net_device *dev) | ||
684 | { | ||
685 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
686 | unsigned int val = 0; | ||
687 | |||
688 | /* Stop all interrupts for receive, transmit and error. */ | ||
689 | wrl(pep, INT_MASK, 0); | ||
690 | |||
691 | /* Clear all interrupts */ | ||
692 | wrl(pep, INT_CAUSE, 0); | ||
693 | |||
694 | /* Stop RX DMA */ | ||
695 | val = rdl(pep, SDMA_CMD); | ||
696 | val &= ~SDMA_CMD_ERD; /* abort dma command */ | ||
697 | |||
698 | /* Abort any transmit and receive operations and put DMA | ||
699 | * in idle state. | ||
700 | */ | ||
701 | abort_dma(pep); | ||
702 | |||
703 | /* Disable port */ | ||
704 | val = rdl(pep, PORT_CONFIG); | ||
705 | val &= ~PCR_EN; | ||
706 | wrl(pep, PORT_CONFIG, val); | ||
707 | } | ||
708 | |||
709 | /* | ||
710 | * txq_reclaim - Free the tx desc data for completed descriptors | ||
711 | * If force is non-zero, frees uncompleted descriptors as well | ||
712 | */ | ||
713 | static int txq_reclaim(struct net_device *dev, int force) | ||
714 | { | ||
715 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
716 | struct tx_desc *desc; | ||
717 | u32 cmd_sts; | ||
718 | struct sk_buff *skb; | ||
719 | int tx_index; | ||
720 | dma_addr_t addr; | ||
721 | int count; | ||
722 | int released = 0; | ||
723 | |||
724 | netif_tx_lock(dev); | ||
725 | |||
726 | pep->work_todo &= ~WORK_TX_DONE; | ||
727 | while (pep->tx_desc_count > 0) { | ||
728 | tx_index = pep->tx_used_desc_q; | ||
729 | desc = &pep->p_tx_desc_area[tx_index]; | ||
730 | cmd_sts = desc->cmd_sts; | ||
731 | if (!force && (cmd_sts & BUF_OWNED_BY_DMA)) { | ||
732 | if (released > 0) { | ||
733 | goto txq_reclaim_end; | ||
734 | } else { | ||
735 | released = -1; | ||
736 | goto txq_reclaim_end; | ||
737 | } | ||
738 | } | ||
739 | pep->tx_used_desc_q = (tx_index + 1) % pep->tx_ring_size; | ||
740 | pep->tx_desc_count--; | ||
741 | addr = desc->buf_ptr; | ||
742 | count = desc->byte_cnt; | ||
743 | skb = pep->tx_skb[tx_index]; | ||
744 | if (skb) | ||
745 | pep->tx_skb[tx_index] = NULL; | ||
746 | |||
747 | if (cmd_sts & TX_ERROR) { | ||
748 | if (net_ratelimit()) | ||
749 | printk(KERN_ERR "%s: Error in TX\n", dev->name); | ||
750 | dev->stats.tx_errors++; | ||
751 | } | ||
752 | dma_unmap_single(NULL, addr, count, DMA_TO_DEVICE); | ||
753 | if (skb) | ||
754 | dev_kfree_skb_irq(skb); | ||
755 | released++; | ||
756 | } | ||
757 | txq_reclaim_end: | ||
758 | netif_tx_unlock(dev); | ||
759 | return released; | ||
760 | } | ||
761 | |||
762 | static void pxa168_eth_tx_timeout(struct net_device *dev) | ||
763 | { | ||
764 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
765 | |||
766 | printk(KERN_INFO "%s: TX timeout desc_count %d\n", | ||
767 | dev->name, pep->tx_desc_count); | ||
768 | |||
769 | schedule_work(&pep->tx_timeout_task); | ||
770 | } | ||
771 | |||
772 | static void pxa168_eth_tx_timeout_task(struct work_struct *work) | ||
773 | { | ||
774 | struct pxa168_eth_private *pep = container_of(work, | ||
775 | struct pxa168_eth_private, | ||
776 | tx_timeout_task); | ||
777 | struct net_device *dev = pep->dev; | ||
778 | pxa168_eth_stop(dev); | ||
779 | pxa168_eth_open(dev); | ||
780 | } | ||
781 | |||
782 | static int rxq_process(struct net_device *dev, int budget) | ||
783 | { | ||
784 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
785 | struct net_device_stats *stats = &dev->stats; | ||
786 | unsigned int received_packets = 0; | ||
787 | struct sk_buff *skb; | ||
788 | |||
789 | while (budget-- > 0) { | ||
790 | int rx_next_curr_desc, rx_curr_desc, rx_used_desc; | ||
791 | struct rx_desc *rx_desc; | ||
792 | unsigned int cmd_sts; | ||
793 | |||
794 | /* Do not process Rx ring in case of Rx ring resource error */ | ||
795 | if (pep->rx_resource_err) | ||
796 | break; | ||
797 | rx_curr_desc = pep->rx_curr_desc_q; | ||
798 | rx_used_desc = pep->rx_used_desc_q; | ||
799 | rx_desc = &pep->p_rx_desc_area[rx_curr_desc]; | ||
800 | cmd_sts = rx_desc->cmd_sts; | ||
801 | rmb(); | ||
802 | if (cmd_sts & (BUF_OWNED_BY_DMA)) | ||
803 | break; | ||
804 | skb = pep->rx_skb[rx_curr_desc]; | ||
805 | pep->rx_skb[rx_curr_desc] = NULL; | ||
806 | |||
807 | rx_next_curr_desc = (rx_curr_desc + 1) % pep->rx_ring_size; | ||
808 | pep->rx_curr_desc_q = rx_next_curr_desc; | ||
809 | |||
810 | /* Rx descriptors exhausted. */ | ||
811 | /* Set the Rx ring resource error flag */ | ||
812 | if (rx_next_curr_desc == rx_used_desc) | ||
813 | pep->rx_resource_err = 1; | ||
814 | pep->rx_desc_count--; | ||
815 | dma_unmap_single(NULL, rx_desc->buf_ptr, | ||
816 | rx_desc->buf_size, | ||
817 | DMA_FROM_DEVICE); | ||
818 | received_packets++; | ||
819 | /* | ||
820 | * Update statistics. | ||
821 | * Note byte count includes 4 byte CRC count | ||
822 | */ | ||
823 | stats->rx_packets++; | ||
824 | stats->rx_bytes += rx_desc->byte_cnt; | ||
825 | /* | ||
826 | * In case received a packet without first / last bits on OR | ||
827 | * the error summary bit is on, the packets needs to be droped. | ||
828 | */ | ||
829 | if (((cmd_sts & (RX_FIRST_DESC | RX_LAST_DESC)) != | ||
830 | (RX_FIRST_DESC | RX_LAST_DESC)) | ||
831 | || (cmd_sts & RX_ERROR)) { | ||
832 | |||
833 | stats->rx_dropped++; | ||
834 | if ((cmd_sts & (RX_FIRST_DESC | RX_LAST_DESC)) != | ||
835 | (RX_FIRST_DESC | RX_LAST_DESC)) { | ||
836 | if (net_ratelimit()) | ||
837 | printk(KERN_ERR | ||
838 | "%s: Rx pkt on multiple desc\n", | ||
839 | dev->name); | ||
840 | } | ||
841 | if (cmd_sts & RX_ERROR) | ||
842 | stats->rx_errors++; | ||
843 | dev_kfree_skb_irq(skb); | ||
844 | } else { | ||
845 | /* | ||
846 | * The -4 is for the CRC in the trailer of the | ||
847 | * received packet | ||
848 | */ | ||
849 | skb_put(skb, rx_desc->byte_cnt - 4); | ||
850 | skb->protocol = eth_type_trans(skb, dev); | ||
851 | netif_receive_skb(skb); | ||
852 | } | ||
853 | dev->last_rx = jiffies; | ||
854 | } | ||
855 | /* Fill RX ring with skb's */ | ||
856 | rxq_refill(dev); | ||
857 | return received_packets; | ||
858 | } | ||
859 | |||
860 | static int pxa168_eth_collect_events(struct pxa168_eth_private *pep, | ||
861 | struct net_device *dev) | ||
862 | { | ||
863 | u32 icr; | ||
864 | int ret = 0; | ||
865 | |||
866 | icr = rdl(pep, INT_CAUSE); | ||
867 | if (icr == 0) | ||
868 | return IRQ_NONE; | ||
869 | |||
870 | wrl(pep, INT_CAUSE, ~icr); | ||
871 | if (icr & (ICR_TXBUF_H | ICR_TXBUF_L)) { | ||
872 | pep->work_todo |= WORK_TX_DONE; | ||
873 | ret = 1; | ||
874 | } | ||
875 | if (icr & ICR_RXBUF) | ||
876 | ret = 1; | ||
877 | if (icr & ICR_MII_CH) { | ||
878 | pep->work_todo |= WORK_LINK; | ||
879 | ret = 1; | ||
880 | } | ||
881 | return ret; | ||
882 | } | ||
883 | |||
884 | static void handle_link_event(struct pxa168_eth_private *pep) | ||
885 | { | ||
886 | struct net_device *dev = pep->dev; | ||
887 | u32 port_status; | ||
888 | int speed; | ||
889 | int duplex; | ||
890 | int fc; | ||
891 | |||
892 | port_status = rdl(pep, PORT_STATUS); | ||
893 | if (!(port_status & LINK_UP)) { | ||
894 | if (netif_carrier_ok(dev)) { | ||
895 | printk(KERN_INFO "%s: link down\n", dev->name); | ||
896 | netif_carrier_off(dev); | ||
897 | txq_reclaim(dev, 1); | ||
898 | } | ||
899 | return; | ||
900 | } | ||
901 | if (port_status & PORT_SPEED_100) | ||
902 | speed = 100; | ||
903 | else | ||
904 | speed = 10; | ||
905 | |||
906 | duplex = (port_status & FULL_DUPLEX) ? 1 : 0; | ||
907 | fc = (port_status & FLOW_CONTROL_ENABLED) ? 1 : 0; | ||
908 | printk(KERN_INFO "%s: link up, %d Mb/s, %s duplex, " | ||
909 | "flow control %sabled\n", dev->name, | ||
910 | speed, duplex ? "full" : "half", fc ? "en" : "dis"); | ||
911 | if (!netif_carrier_ok(dev)) | ||
912 | netif_carrier_on(dev); | ||
913 | } | ||
914 | |||
915 | static irqreturn_t pxa168_eth_int_handler(int irq, void *dev_id) | ||
916 | { | ||
917 | struct net_device *dev = (struct net_device *)dev_id; | ||
918 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
919 | |||
920 | if (unlikely(!pxa168_eth_collect_events(pep, dev))) | ||
921 | return IRQ_NONE; | ||
922 | /* Disable interrupts */ | ||
923 | wrl(pep, INT_MASK, 0); | ||
924 | napi_schedule(&pep->napi); | ||
925 | return IRQ_HANDLED; | ||
926 | } | ||
927 | |||
928 | static void pxa168_eth_recalc_skb_size(struct pxa168_eth_private *pep) | ||
929 | { | ||
930 | int skb_size; | ||
931 | |||
932 | /* | ||
933 | * Reserve 2+14 bytes for an ethernet header (the hardware | ||
934 | * automatically prepends 2 bytes of dummy data to each | ||
935 | * received packet), 16 bytes for up to four VLAN tags, and | ||
936 | * 4 bytes for the trailing FCS -- 36 bytes total. | ||
937 | */ | ||
938 | skb_size = pep->dev->mtu + 36; | ||
939 | |||
940 | /* | ||
941 | * Make sure that the skb size is a multiple of 8 bytes, as | ||
942 | * the lower three bits of the receive descriptor's buffer | ||
943 | * size field are ignored by the hardware. | ||
944 | */ | ||
945 | pep->skb_size = (skb_size + 7) & ~7; | ||
946 | |||
947 | /* | ||
948 | * If NET_SKB_PAD is smaller than a cache line, | ||
949 | * netdev_alloc_skb() will cause skb->data to be misaligned | ||
950 | * to a cache line boundary. If this is the case, include | ||
951 | * some extra space to allow re-aligning the data area. | ||
952 | */ | ||
953 | pep->skb_size += SKB_DMA_REALIGN; | ||
954 | |||
955 | } | ||
956 | |||
957 | static int set_port_config_ext(struct pxa168_eth_private *pep) | ||
958 | { | ||
959 | int skb_size; | ||
960 | |||
961 | pxa168_eth_recalc_skb_size(pep); | ||
962 | if (pep->skb_size <= 1518) | ||
963 | skb_size = PCXR_MFL_1518; | ||
964 | else if (pep->skb_size <= 1536) | ||
965 | skb_size = PCXR_MFL_1536; | ||
966 | else if (pep->skb_size <= 2048) | ||
967 | skb_size = PCXR_MFL_2048; | ||
968 | else | ||
969 | skb_size = PCXR_MFL_64K; | ||
970 | |||
971 | /* Extended Port Configuration */ | ||
972 | wrl(pep, | ||
973 | PORT_CONFIG_EXT, PCXR_2BSM | /* Two byte prefix aligns IP hdr */ | ||
974 | PCXR_DSCP_EN | /* Enable DSCP in IP */ | ||
975 | skb_size | PCXR_FLP | /* do not force link pass */ | ||
976 | PCXR_TX_HIGH_PRI); /* Transmit - high priority queue */ | ||
977 | |||
978 | return 0; | ||
979 | } | ||
980 | |||
981 | static int pxa168_init_hw(struct pxa168_eth_private *pep) | ||
982 | { | ||
983 | int err = 0; | ||
984 | |||
985 | /* Disable interrupts */ | ||
986 | wrl(pep, INT_MASK, 0); | ||
987 | wrl(pep, INT_CAUSE, 0); | ||
988 | /* Write to ICR to clear interrupts. */ | ||
989 | wrl(pep, INT_W_CLEAR, 0); | ||
990 | /* Abort any transmit and receive operations and put DMA | ||
991 | * in idle state. | ||
992 | */ | ||
993 | abort_dma(pep); | ||
994 | /* Initialize address hash table */ | ||
995 | err = init_hash_table(pep); | ||
996 | if (err) | ||
997 | return err; | ||
998 | /* SDMA configuration */ | ||
999 | wrl(pep, SDMA_CONFIG, SDCR_BSZ8 | /* Burst size = 32 bytes */ | ||
1000 | SDCR_RIFB | /* Rx interrupt on frame */ | ||
1001 | SDCR_BLMT | /* Little endian transmit */ | ||
1002 | SDCR_BLMR | /* Little endian receive */ | ||
1003 | SDCR_RC_MAX_RETRANS); /* Max retransmit count */ | ||
1004 | /* Port Configuration */ | ||
1005 | wrl(pep, PORT_CONFIG, PCR_HS); /* Hash size is 1/2kb */ | ||
1006 | set_port_config_ext(pep); | ||
1007 | |||
1008 | return err; | ||
1009 | } | ||
1010 | |||
1011 | static int rxq_init(struct net_device *dev) | ||
1012 | { | ||
1013 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
1014 | struct rx_desc *p_rx_desc; | ||
1015 | int size = 0, i = 0; | ||
1016 | int rx_desc_num = pep->rx_ring_size; | ||
1017 | |||
1018 | /* Allocate RX skb rings */ | ||
1019 | pep->rx_skb = kmalloc(sizeof(*pep->rx_skb) * pep->rx_ring_size, | ||
1020 | GFP_KERNEL); | ||
1021 | if (!pep->rx_skb) { | ||
1022 | printk(KERN_ERR "%s: Cannot alloc RX skb ring\n", dev->name); | ||
1023 | return -ENOMEM; | ||
1024 | } | ||
1025 | /* Allocate RX ring */ | ||
1026 | pep->rx_desc_count = 0; | ||
1027 | size = pep->rx_ring_size * sizeof(struct rx_desc); | ||
1028 | pep->rx_desc_area_size = size; | ||
1029 | pep->p_rx_desc_area = dma_alloc_coherent(pep->dev->dev.parent, size, | ||
1030 | &pep->rx_desc_dma, GFP_KERNEL); | ||
1031 | if (!pep->p_rx_desc_area) { | ||
1032 | printk(KERN_ERR "%s: Cannot alloc RX ring (size %d bytes)\n", | ||
1033 | dev->name, size); | ||
1034 | goto out; | ||
1035 | } | ||
1036 | memset((void *)pep->p_rx_desc_area, 0, size); | ||
1037 | /* initialize the next_desc_ptr links in the Rx descriptors ring */ | ||
1038 | p_rx_desc = (struct rx_desc *)pep->p_rx_desc_area; | ||
1039 | for (i = 0; i < rx_desc_num; i++) { | ||
1040 | p_rx_desc[i].next_desc_ptr = pep->rx_desc_dma + | ||
1041 | ((i + 1) % rx_desc_num) * sizeof(struct rx_desc); | ||
1042 | } | ||
1043 | /* Save Rx desc pointer to driver struct. */ | ||
1044 | pep->rx_curr_desc_q = 0; | ||
1045 | pep->rx_used_desc_q = 0; | ||
1046 | pep->rx_desc_area_size = rx_desc_num * sizeof(struct rx_desc); | ||
1047 | return 0; | ||
1048 | out: | ||
1049 | kfree(pep->rx_skb); | ||
1050 | return -ENOMEM; | ||
1051 | } | ||
1052 | |||
1053 | static void rxq_deinit(struct net_device *dev) | ||
1054 | { | ||
1055 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
1056 | int curr; | ||
1057 | |||
1058 | /* Free preallocated skb's on RX rings */ | ||
1059 | for (curr = 0; pep->rx_desc_count && curr < pep->rx_ring_size; curr++) { | ||
1060 | if (pep->rx_skb[curr]) { | ||
1061 | dev_kfree_skb(pep->rx_skb[curr]); | ||
1062 | pep->rx_desc_count--; | ||
1063 | } | ||
1064 | } | ||
1065 | if (pep->rx_desc_count) | ||
1066 | printk(KERN_ERR | ||
1067 | "Error in freeing Rx Ring. %d skb's still\n", | ||
1068 | pep->rx_desc_count); | ||
1069 | /* Free RX ring */ | ||
1070 | if (pep->p_rx_desc_area) | ||
1071 | dma_free_coherent(pep->dev->dev.parent, pep->rx_desc_area_size, | ||
1072 | pep->p_rx_desc_area, pep->rx_desc_dma); | ||
1073 | kfree(pep->rx_skb); | ||
1074 | } | ||
1075 | |||
1076 | static int txq_init(struct net_device *dev) | ||
1077 | { | ||
1078 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
1079 | struct tx_desc *p_tx_desc; | ||
1080 | int size = 0, i = 0; | ||
1081 | int tx_desc_num = pep->tx_ring_size; | ||
1082 | |||
1083 | pep->tx_skb = kmalloc(sizeof(*pep->tx_skb) * pep->tx_ring_size, | ||
1084 | GFP_KERNEL); | ||
1085 | if (!pep->tx_skb) { | ||
1086 | printk(KERN_ERR "%s: Cannot alloc TX skb ring\n", dev->name); | ||
1087 | return -ENOMEM; | ||
1088 | } | ||
1089 | /* Allocate TX ring */ | ||
1090 | pep->tx_desc_count = 0; | ||
1091 | size = pep->tx_ring_size * sizeof(struct tx_desc); | ||
1092 | pep->tx_desc_area_size = size; | ||
1093 | pep->p_tx_desc_area = dma_alloc_coherent(pep->dev->dev.parent, size, | ||
1094 | &pep->tx_desc_dma, GFP_KERNEL); | ||
1095 | if (!pep->p_tx_desc_area) { | ||
1096 | printk(KERN_ERR "%s: Cannot allocate Tx Ring (size %d bytes)\n", | ||
1097 | dev->name, size); | ||
1098 | goto out; | ||
1099 | } | ||
1100 | memset((void *)pep->p_tx_desc_area, 0, pep->tx_desc_area_size); | ||
1101 | /* Initialize the next_desc_ptr links in the Tx descriptors ring */ | ||
1102 | p_tx_desc = (struct tx_desc *)pep->p_tx_desc_area; | ||
1103 | for (i = 0; i < tx_desc_num; i++) { | ||
1104 | p_tx_desc[i].next_desc_ptr = pep->tx_desc_dma + | ||
1105 | ((i + 1) % tx_desc_num) * sizeof(struct tx_desc); | ||
1106 | } | ||
1107 | pep->tx_curr_desc_q = 0; | ||
1108 | pep->tx_used_desc_q = 0; | ||
1109 | pep->tx_desc_area_size = tx_desc_num * sizeof(struct tx_desc); | ||
1110 | return 0; | ||
1111 | out: | ||
1112 | kfree(pep->tx_skb); | ||
1113 | return -ENOMEM; | ||
1114 | } | ||
1115 | |||
1116 | static void txq_deinit(struct net_device *dev) | ||
1117 | { | ||
1118 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
1119 | |||
1120 | /* Free outstanding skb's on TX ring */ | ||
1121 | txq_reclaim(dev, 1); | ||
1122 | BUG_ON(pep->tx_used_desc_q != pep->tx_curr_desc_q); | ||
1123 | /* Free TX ring */ | ||
1124 | if (pep->p_tx_desc_area) | ||
1125 | dma_free_coherent(pep->dev->dev.parent, pep->tx_desc_area_size, | ||
1126 | pep->p_tx_desc_area, pep->tx_desc_dma); | ||
1127 | kfree(pep->tx_skb); | ||
1128 | } | ||
1129 | |||
1130 | static int pxa168_eth_open(struct net_device *dev) | ||
1131 | { | ||
1132 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
1133 | int err; | ||
1134 | |||
1135 | err = request_irq(dev->irq, pxa168_eth_int_handler, | ||
1136 | IRQF_DISABLED, dev->name, dev); | ||
1137 | if (err) { | ||
1138 | dev_printk(KERN_ERR, &dev->dev, "can't assign irq\n"); | ||
1139 | return -EAGAIN; | ||
1140 | } | ||
1141 | pep->rx_resource_err = 0; | ||
1142 | err = rxq_init(dev); | ||
1143 | if (err != 0) | ||
1144 | goto out_free_irq; | ||
1145 | err = txq_init(dev); | ||
1146 | if (err != 0) | ||
1147 | goto out_free_rx_skb; | ||
1148 | pep->rx_used_desc_q = 0; | ||
1149 | pep->rx_curr_desc_q = 0; | ||
1150 | |||
1151 | /* Fill RX ring with skb's */ | ||
1152 | rxq_refill(dev); | ||
1153 | pep->rx_used_desc_q = 0; | ||
1154 | pep->rx_curr_desc_q = 0; | ||
1155 | netif_carrier_off(dev); | ||
1156 | eth_port_start(dev); | ||
1157 | napi_enable(&pep->napi); | ||
1158 | return 0; | ||
1159 | out_free_rx_skb: | ||
1160 | rxq_deinit(dev); | ||
1161 | out_free_irq: | ||
1162 | free_irq(dev->irq, dev); | ||
1163 | return err; | ||
1164 | } | ||
1165 | |||
1166 | static int pxa168_eth_stop(struct net_device *dev) | ||
1167 | { | ||
1168 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
1169 | eth_port_reset(dev); | ||
1170 | |||
1171 | /* Disable interrupts */ | ||
1172 | wrl(pep, INT_MASK, 0); | ||
1173 | wrl(pep, INT_CAUSE, 0); | ||
1174 | /* Write to ICR to clear interrupts. */ | ||
1175 | wrl(pep, INT_W_CLEAR, 0); | ||
1176 | napi_disable(&pep->napi); | ||
1177 | del_timer_sync(&pep->timeout); | ||
1178 | netif_carrier_off(dev); | ||
1179 | free_irq(dev->irq, dev); | ||
1180 | rxq_deinit(dev); | ||
1181 | txq_deinit(dev); | ||
1182 | |||
1183 | return 0; | ||
1184 | } | ||
1185 | |||
1186 | static int pxa168_eth_change_mtu(struct net_device *dev, int mtu) | ||
1187 | { | ||
1188 | int retval; | ||
1189 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
1190 | |||
1191 | if ((mtu > 9500) || (mtu < 68)) | ||
1192 | return -EINVAL; | ||
1193 | |||
1194 | dev->mtu = mtu; | ||
1195 | retval = set_port_config_ext(pep); | ||
1196 | |||
1197 | if (!netif_running(dev)) | ||
1198 | return 0; | ||
1199 | |||
1200 | /* | ||
1201 | * Stop and then re-open the interface. This will allocate RX | ||
1202 | * skbs of the new MTU. | ||
1203 | * There is a possible danger that the open will not succeed, | ||
1204 | * due to memory being full. | ||
1205 | */ | ||
1206 | pxa168_eth_stop(dev); | ||
1207 | if (pxa168_eth_open(dev)) { | ||
1208 | dev_printk(KERN_ERR, &dev->dev, | ||
1209 | "fatal error on re-opening device after " | ||
1210 | "MTU change\n"); | ||
1211 | } | ||
1212 | |||
1213 | return 0; | ||
1214 | } | ||
1215 | |||
1216 | static int eth_alloc_tx_desc_index(struct pxa168_eth_private *pep) | ||
1217 | { | ||
1218 | int tx_desc_curr; | ||
1219 | |||
1220 | tx_desc_curr = pep->tx_curr_desc_q; | ||
1221 | pep->tx_curr_desc_q = (tx_desc_curr + 1) % pep->tx_ring_size; | ||
1222 | BUG_ON(pep->tx_curr_desc_q == pep->tx_used_desc_q); | ||
1223 | pep->tx_desc_count++; | ||
1224 | |||
1225 | return tx_desc_curr; | ||
1226 | } | ||
1227 | |||
1228 | static int pxa168_rx_poll(struct napi_struct *napi, int budget) | ||
1229 | { | ||
1230 | struct pxa168_eth_private *pep = | ||
1231 | container_of(napi, struct pxa168_eth_private, napi); | ||
1232 | struct net_device *dev = pep->dev; | ||
1233 | int work_done = 0; | ||
1234 | |||
1235 | if (unlikely(pep->work_todo & WORK_LINK)) { | ||
1236 | pep->work_todo &= ~(WORK_LINK); | ||
1237 | handle_link_event(pep); | ||
1238 | } | ||
1239 | /* | ||
1240 | * We call txq_reclaim every time since in NAPI interupts are disabled | ||
1241 | * and due to this we miss the TX_DONE interrupt,which is not updated in | ||
1242 | * interrupt status register. | ||
1243 | */ | ||
1244 | txq_reclaim(dev, 0); | ||
1245 | if (netif_queue_stopped(dev) | ||
1246 | && pep->tx_ring_size - pep->tx_desc_count > 1) { | ||
1247 | netif_wake_queue(dev); | ||
1248 | } | ||
1249 | work_done = rxq_process(dev, budget); | ||
1250 | if (work_done < budget) { | ||
1251 | napi_complete(napi); | ||
1252 | wrl(pep, INT_MASK, ALL_INTS); | ||
1253 | } | ||
1254 | |||
1255 | return work_done; | ||
1256 | } | ||
1257 | |||
1258 | static int pxa168_eth_start_xmit(struct sk_buff *skb, struct net_device *dev) | ||
1259 | { | ||
1260 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
1261 | struct net_device_stats *stats = &dev->stats; | ||
1262 | struct tx_desc *desc; | ||
1263 | int tx_index; | ||
1264 | int length; | ||
1265 | |||
1266 | tx_index = eth_alloc_tx_desc_index(pep); | ||
1267 | desc = &pep->p_tx_desc_area[tx_index]; | ||
1268 | length = skb->len; | ||
1269 | pep->tx_skb[tx_index] = skb; | ||
1270 | desc->byte_cnt = length; | ||
1271 | desc->buf_ptr = dma_map_single(NULL, skb->data, length, DMA_TO_DEVICE); | ||
1272 | wmb(); | ||
1273 | desc->cmd_sts = BUF_OWNED_BY_DMA | TX_GEN_CRC | TX_FIRST_DESC | | ||
1274 | TX_ZERO_PADDING | TX_LAST_DESC | TX_EN_INT; | ||
1275 | wmb(); | ||
1276 | wrl(pep, SDMA_CMD, SDMA_CMD_TXDH | SDMA_CMD_ERD); | ||
1277 | |||
1278 | stats->tx_bytes += skb->len; | ||
1279 | stats->tx_packets++; | ||
1280 | dev->trans_start = jiffies; | ||
1281 | if (pep->tx_ring_size - pep->tx_desc_count <= 1) { | ||
1282 | /* We handled the current skb, but now we are out of space.*/ | ||
1283 | netif_stop_queue(dev); | ||
1284 | } | ||
1285 | |||
1286 | return NETDEV_TX_OK; | ||
1287 | } | ||
1288 | |||
1289 | static int smi_wait_ready(struct pxa168_eth_private *pep) | ||
1290 | { | ||
1291 | int i = 0; | ||
1292 | |||
1293 | /* wait for the SMI register to become available */ | ||
1294 | for (i = 0; rdl(pep, SMI) & SMI_BUSY; i++) { | ||
1295 | if (i == PHY_WAIT_ITERATIONS) | ||
1296 | return -ETIMEDOUT; | ||
1297 | msleep(10); | ||
1298 | } | ||
1299 | |||
1300 | return 0; | ||
1301 | } | ||
1302 | |||
1303 | static int pxa168_smi_read(struct mii_bus *bus, int phy_addr, int regnum) | ||
1304 | { | ||
1305 | struct pxa168_eth_private *pep = bus->priv; | ||
1306 | int i = 0; | ||
1307 | int val; | ||
1308 | |||
1309 | if (smi_wait_ready(pep)) { | ||
1310 | printk(KERN_WARNING "pxa168_eth: SMI bus busy timeout\n"); | ||
1311 | return -ETIMEDOUT; | ||
1312 | } | ||
1313 | wrl(pep, SMI, (phy_addr << 16) | (regnum << 21) | SMI_OP_R); | ||
1314 | /* now wait for the data to be valid */ | ||
1315 | for (i = 0; !((val = rdl(pep, SMI)) & SMI_R_VALID); i++) { | ||
1316 | if (i == PHY_WAIT_ITERATIONS) { | ||
1317 | printk(KERN_WARNING | ||
1318 | "pxa168_eth: SMI bus read not valid\n"); | ||
1319 | return -ENODEV; | ||
1320 | } | ||
1321 | msleep(10); | ||
1322 | } | ||
1323 | |||
1324 | return val & 0xffff; | ||
1325 | } | ||
1326 | |||
1327 | static int pxa168_smi_write(struct mii_bus *bus, int phy_addr, int regnum, | ||
1328 | u16 value) | ||
1329 | { | ||
1330 | struct pxa168_eth_private *pep = bus->priv; | ||
1331 | |||
1332 | if (smi_wait_ready(pep)) { | ||
1333 | printk(KERN_WARNING "pxa168_eth: SMI bus busy timeout\n"); | ||
1334 | return -ETIMEDOUT; | ||
1335 | } | ||
1336 | |||
1337 | wrl(pep, SMI, (phy_addr << 16) | (regnum << 21) | | ||
1338 | SMI_OP_W | (value & 0xffff)); | ||
1339 | |||
1340 | if (smi_wait_ready(pep)) { | ||
1341 | printk(KERN_ERR "pxa168_eth: SMI bus busy timeout\n"); | ||
1342 | return -ETIMEDOUT; | ||
1343 | } | ||
1344 | |||
1345 | return 0; | ||
1346 | } | ||
1347 | |||
1348 | static int pxa168_eth_do_ioctl(struct net_device *dev, struct ifreq *ifr, | ||
1349 | int cmd) | ||
1350 | { | ||
1351 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
1352 | if (pep->phy != NULL) | ||
1353 | return phy_mii_ioctl(pep->phy, ifr, cmd); | ||
1354 | |||
1355 | return -EOPNOTSUPP; | ||
1356 | } | ||
1357 | |||
1358 | static struct phy_device *phy_scan(struct pxa168_eth_private *pep, int phy_addr) | ||
1359 | { | ||
1360 | struct mii_bus *bus = pep->smi_bus; | ||
1361 | struct phy_device *phydev; | ||
1362 | int start; | ||
1363 | int num; | ||
1364 | int i; | ||
1365 | |||
1366 | if (phy_addr == PXA168_ETH_PHY_ADDR_DEFAULT) { | ||
1367 | /* Scan entire range */ | ||
1368 | start = ethernet_phy_get(pep); | ||
1369 | num = 32; | ||
1370 | } else { | ||
1371 | /* Use phy addr specific to platform */ | ||
1372 | start = phy_addr & 0x1f; | ||
1373 | num = 1; | ||
1374 | } | ||
1375 | phydev = NULL; | ||
1376 | for (i = 0; i < num; i++) { | ||
1377 | int addr = (start + i) & 0x1f; | ||
1378 | if (bus->phy_map[addr] == NULL) | ||
1379 | mdiobus_scan(bus, addr); | ||
1380 | |||
1381 | if (phydev == NULL) { | ||
1382 | phydev = bus->phy_map[addr]; | ||
1383 | if (phydev != NULL) | ||
1384 | ethernet_phy_set_addr(pep, addr); | ||
1385 | } | ||
1386 | } | ||
1387 | |||
1388 | return phydev; | ||
1389 | } | ||
1390 | |||
1391 | static void phy_init(struct pxa168_eth_private *pep, int speed, int duplex) | ||
1392 | { | ||
1393 | struct phy_device *phy = pep->phy; | ||
1394 | ethernet_phy_reset(pep); | ||
1395 | |||
1396 | phy_attach(pep->dev, dev_name(&phy->dev), 0, PHY_INTERFACE_MODE_MII); | ||
1397 | |||
1398 | if (speed == 0) { | ||
1399 | phy->autoneg = AUTONEG_ENABLE; | ||
1400 | phy->speed = 0; | ||
1401 | phy->duplex = 0; | ||
1402 | phy->supported &= PHY_BASIC_FEATURES; | ||
1403 | phy->advertising = phy->supported | ADVERTISED_Autoneg; | ||
1404 | } else { | ||
1405 | phy->autoneg = AUTONEG_DISABLE; | ||
1406 | phy->advertising = 0; | ||
1407 | phy->speed = speed; | ||
1408 | phy->duplex = duplex; | ||
1409 | } | ||
1410 | phy_start_aneg(phy); | ||
1411 | } | ||
1412 | |||
1413 | static int ethernet_phy_setup(struct net_device *dev) | ||
1414 | { | ||
1415 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
1416 | |||
1417 | if (pep->pd->init) | ||
1418 | pep->pd->init(); | ||
1419 | pep->phy = phy_scan(pep, pep->pd->phy_addr & 0x1f); | ||
1420 | if (pep->phy != NULL) | ||
1421 | phy_init(pep, pep->pd->speed, pep->pd->duplex); | ||
1422 | update_hash_table_mac_address(pep, NULL, dev->dev_addr); | ||
1423 | |||
1424 | return 0; | ||
1425 | } | ||
1426 | |||
1427 | static int pxa168_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
1428 | { | ||
1429 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
1430 | int err; | ||
1431 | |||
1432 | err = phy_read_status(pep->phy); | ||
1433 | if (err == 0) | ||
1434 | err = phy_ethtool_gset(pep->phy, cmd); | ||
1435 | |||
1436 | return err; | ||
1437 | } | ||
1438 | |||
1439 | static int pxa168_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
1440 | { | ||
1441 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
1442 | |||
1443 | return phy_ethtool_sset(pep->phy, cmd); | ||
1444 | } | ||
1445 | |||
1446 | static void pxa168_get_drvinfo(struct net_device *dev, | ||
1447 | struct ethtool_drvinfo *info) | ||
1448 | { | ||
1449 | strncpy(info->driver, DRIVER_NAME, 32); | ||
1450 | strncpy(info->version, DRIVER_VERSION, 32); | ||
1451 | strncpy(info->fw_version, "N/A", 32); | ||
1452 | strncpy(info->bus_info, "N/A", 32); | ||
1453 | } | ||
1454 | |||
1455 | static u32 pxa168_get_link(struct net_device *dev) | ||
1456 | { | ||
1457 | return !!netif_carrier_ok(dev); | ||
1458 | } | ||
1459 | |||
1460 | static const struct ethtool_ops pxa168_ethtool_ops = { | ||
1461 | .get_settings = pxa168_get_settings, | ||
1462 | .set_settings = pxa168_set_settings, | ||
1463 | .get_drvinfo = pxa168_get_drvinfo, | ||
1464 | .get_link = pxa168_get_link, | ||
1465 | }; | ||
1466 | |||
1467 | static const struct net_device_ops pxa168_eth_netdev_ops = { | ||
1468 | .ndo_open = pxa168_eth_open, | ||
1469 | .ndo_stop = pxa168_eth_stop, | ||
1470 | .ndo_start_xmit = pxa168_eth_start_xmit, | ||
1471 | .ndo_set_rx_mode = pxa168_eth_set_rx_mode, | ||
1472 | .ndo_set_mac_address = pxa168_eth_set_mac_address, | ||
1473 | .ndo_validate_addr = eth_validate_addr, | ||
1474 | .ndo_do_ioctl = pxa168_eth_do_ioctl, | ||
1475 | .ndo_change_mtu = pxa168_eth_change_mtu, | ||
1476 | .ndo_tx_timeout = pxa168_eth_tx_timeout, | ||
1477 | }; | ||
1478 | |||
1479 | static int pxa168_eth_probe(struct platform_device *pdev) | ||
1480 | { | ||
1481 | struct pxa168_eth_private *pep = NULL; | ||
1482 | struct net_device *dev = NULL; | ||
1483 | struct resource *res; | ||
1484 | struct clk *clk; | ||
1485 | int err; | ||
1486 | |||
1487 | printk(KERN_NOTICE "PXA168 10/100 Ethernet Driver\n"); | ||
1488 | |||
1489 | clk = clk_get(&pdev->dev, "MFUCLK"); | ||
1490 | if (IS_ERR(clk)) { | ||
1491 | printk(KERN_ERR "%s: Fast Ethernet failed to get clock\n", | ||
1492 | DRIVER_NAME); | ||
1493 | return -ENODEV; | ||
1494 | } | ||
1495 | clk_enable(clk); | ||
1496 | |||
1497 | dev = alloc_etherdev(sizeof(struct pxa168_eth_private)); | ||
1498 | if (!dev) { | ||
1499 | err = -ENOMEM; | ||
1500 | goto err_clk; | ||
1501 | } | ||
1502 | |||
1503 | platform_set_drvdata(pdev, dev); | ||
1504 | pep = netdev_priv(dev); | ||
1505 | pep->dev = dev; | ||
1506 | pep->clk = clk; | ||
1507 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1508 | if (res == NULL) { | ||
1509 | err = -ENODEV; | ||
1510 | goto err_netdev; | ||
1511 | } | ||
1512 | pep->base = ioremap(res->start, res->end - res->start + 1); | ||
1513 | if (pep->base == NULL) { | ||
1514 | err = -ENOMEM; | ||
1515 | goto err_netdev; | ||
1516 | } | ||
1517 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
1518 | BUG_ON(!res); | ||
1519 | dev->irq = res->start; | ||
1520 | dev->netdev_ops = &pxa168_eth_netdev_ops; | ||
1521 | dev->watchdog_timeo = 2 * HZ; | ||
1522 | dev->base_addr = 0; | ||
1523 | SET_ETHTOOL_OPS(dev, &pxa168_ethtool_ops); | ||
1524 | |||
1525 | INIT_WORK(&pep->tx_timeout_task, pxa168_eth_tx_timeout_task); | ||
1526 | |||
1527 | printk(KERN_INFO "%s:Using random mac address\n", DRIVER_NAME); | ||
1528 | random_ether_addr(dev->dev_addr); | ||
1529 | |||
1530 | pep->pd = pdev->dev.platform_data; | ||
1531 | pep->rx_ring_size = NUM_RX_DESCS; | ||
1532 | if (pep->pd->rx_queue_size) | ||
1533 | pep->rx_ring_size = pep->pd->rx_queue_size; | ||
1534 | |||
1535 | pep->tx_ring_size = NUM_TX_DESCS; | ||
1536 | if (pep->pd->tx_queue_size) | ||
1537 | pep->tx_ring_size = pep->pd->tx_queue_size; | ||
1538 | |||
1539 | pep->port_num = pep->pd->port_number; | ||
1540 | /* Hardware supports only 3 ports */ | ||
1541 | BUG_ON(pep->port_num > 2); | ||
1542 | netif_napi_add(dev, &pep->napi, pxa168_rx_poll, pep->rx_ring_size); | ||
1543 | |||
1544 | memset(&pep->timeout, 0, sizeof(struct timer_list)); | ||
1545 | init_timer(&pep->timeout); | ||
1546 | pep->timeout.function = rxq_refill_timer_wrapper; | ||
1547 | pep->timeout.data = (unsigned long)pep; | ||
1548 | |||
1549 | pep->smi_bus = mdiobus_alloc(); | ||
1550 | if (pep->smi_bus == NULL) { | ||
1551 | err = -ENOMEM; | ||
1552 | goto err_base; | ||
1553 | } | ||
1554 | pep->smi_bus->priv = pep; | ||
1555 | pep->smi_bus->name = "pxa168_eth smi"; | ||
1556 | pep->smi_bus->read = pxa168_smi_read; | ||
1557 | pep->smi_bus->write = pxa168_smi_write; | ||
1558 | snprintf(pep->smi_bus->id, MII_BUS_ID_SIZE, "%d", pdev->id); | ||
1559 | pep->smi_bus->parent = &pdev->dev; | ||
1560 | pep->smi_bus->phy_mask = 0xffffffff; | ||
1561 | err = mdiobus_register(pep->smi_bus); | ||
1562 | if (err) | ||
1563 | goto err_free_mdio; | ||
1564 | |||
1565 | pxa168_init_hw(pep); | ||
1566 | err = ethernet_phy_setup(dev); | ||
1567 | if (err) | ||
1568 | goto err_mdiobus; | ||
1569 | SET_NETDEV_DEV(dev, &pdev->dev); | ||
1570 | err = register_netdev(dev); | ||
1571 | if (err) | ||
1572 | goto err_mdiobus; | ||
1573 | return 0; | ||
1574 | |||
1575 | err_mdiobus: | ||
1576 | mdiobus_unregister(pep->smi_bus); | ||
1577 | err_free_mdio: | ||
1578 | mdiobus_free(pep->smi_bus); | ||
1579 | err_base: | ||
1580 | iounmap(pep->base); | ||
1581 | err_netdev: | ||
1582 | free_netdev(dev); | ||
1583 | err_clk: | ||
1584 | clk_disable(clk); | ||
1585 | clk_put(clk); | ||
1586 | return err; | ||
1587 | } | ||
1588 | |||
1589 | static int pxa168_eth_remove(struct platform_device *pdev) | ||
1590 | { | ||
1591 | struct net_device *dev = platform_get_drvdata(pdev); | ||
1592 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
1593 | |||
1594 | if (pep->htpr) { | ||
1595 | dma_free_coherent(pep->dev->dev.parent, HASH_ADDR_TABLE_SIZE, | ||
1596 | pep->htpr, pep->htpr_dma); | ||
1597 | pep->htpr = NULL; | ||
1598 | } | ||
1599 | if (pep->clk) { | ||
1600 | clk_disable(pep->clk); | ||
1601 | clk_put(pep->clk); | ||
1602 | pep->clk = NULL; | ||
1603 | } | ||
1604 | if (pep->phy != NULL) | ||
1605 | phy_detach(pep->phy); | ||
1606 | |||
1607 | iounmap(pep->base); | ||
1608 | pep->base = NULL; | ||
1609 | mdiobus_unregister(pep->smi_bus); | ||
1610 | mdiobus_free(pep->smi_bus); | ||
1611 | unregister_netdev(dev); | ||
1612 | flush_scheduled_work(); | ||
1613 | free_netdev(dev); | ||
1614 | platform_set_drvdata(pdev, NULL); | ||
1615 | return 0; | ||
1616 | } | ||
1617 | |||
1618 | static void pxa168_eth_shutdown(struct platform_device *pdev) | ||
1619 | { | ||
1620 | struct net_device *dev = platform_get_drvdata(pdev); | ||
1621 | eth_port_reset(dev); | ||
1622 | } | ||
1623 | |||
1624 | #ifdef CONFIG_PM | ||
1625 | static int pxa168_eth_resume(struct platform_device *pdev) | ||
1626 | { | ||
1627 | return -ENOSYS; | ||
1628 | } | ||
1629 | |||
1630 | static int pxa168_eth_suspend(struct platform_device *pdev, pm_message_t state) | ||
1631 | { | ||
1632 | return -ENOSYS; | ||
1633 | } | ||
1634 | |||
1635 | #else | ||
1636 | #define pxa168_eth_resume NULL | ||
1637 | #define pxa168_eth_suspend NULL | ||
1638 | #endif | ||
1639 | |||
1640 | static struct platform_driver pxa168_eth_driver = { | ||
1641 | .probe = pxa168_eth_probe, | ||
1642 | .remove = pxa168_eth_remove, | ||
1643 | .shutdown = pxa168_eth_shutdown, | ||
1644 | .resume = pxa168_eth_resume, | ||
1645 | .suspend = pxa168_eth_suspend, | ||
1646 | .driver = { | ||
1647 | .name = DRIVER_NAME, | ||
1648 | }, | ||
1649 | }; | ||
1650 | |||
1651 | static int __init pxa168_init_module(void) | ||
1652 | { | ||
1653 | return platform_driver_register(&pxa168_eth_driver); | ||
1654 | } | ||
1655 | |||
1656 | static void __exit pxa168_cleanup_module(void) | ||
1657 | { | ||
1658 | platform_driver_unregister(&pxa168_eth_driver); | ||
1659 | } | ||
1660 | |||
1661 | module_init(pxa168_init_module); | ||
1662 | module_exit(pxa168_cleanup_module); | ||
1663 | |||
1664 | MODULE_LICENSE("GPL"); | ||
1665 | MODULE_DESCRIPTION("Ethernet driver for Marvell PXA168"); | ||
1666 | MODULE_ALIAS("platform:pxa168_eth"); | ||
diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index 75ba744b173..2c7cf0b6481 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c | |||
@@ -1316,7 +1316,7 @@ qlcnic_alloc_rx_skb(struct qlcnic_adapter *adapter, | |||
1316 | return -ENOMEM; | 1316 | return -ENOMEM; |
1317 | } | 1317 | } |
1318 | 1318 | ||
1319 | skb_reserve(skb, 2); | 1319 | skb_reserve(skb, NET_IP_ALIGN); |
1320 | 1320 | ||
1321 | dma = pci_map_single(pdev, skb->data, | 1321 | dma = pci_map_single(pdev, skb->data, |
1322 | rds_ring->dma_size, PCI_DMA_FROMDEVICE); | 1322 | rds_ring->dma_size, PCI_DMA_FROMDEVICE); |
@@ -1404,7 +1404,6 @@ qlcnic_process_rcv(struct qlcnic_adapter *adapter, | |||
1404 | if (pkt_offset) | 1404 | if (pkt_offset) |
1405 | skb_pull(skb, pkt_offset); | 1405 | skb_pull(skb, pkt_offset); |
1406 | 1406 | ||
1407 | skb->truesize = skb->len + sizeof(struct sk_buff); | ||
1408 | skb->protocol = eth_type_trans(skb, netdev); | 1407 | skb->protocol = eth_type_trans(skb, netdev); |
1409 | 1408 | ||
1410 | napi_gro_receive(&sds_ring->napi, skb); | 1409 | napi_gro_receive(&sds_ring->napi, skb); |
@@ -1466,8 +1465,6 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter, | |||
1466 | 1465 | ||
1467 | skb_put(skb, lro_length + data_offset); | 1466 | skb_put(skb, lro_length + data_offset); |
1468 | 1467 | ||
1469 | skb->truesize = skb->len + sizeof(struct sk_buff) + skb_headroom(skb); | ||
1470 | |||
1471 | skb_pull(skb, l2_hdr_offset); | 1468 | skb_pull(skb, l2_hdr_offset); |
1472 | skb->protocol = eth_type_trans(skb, netdev); | 1469 | skb->protocol = eth_type_trans(skb, netdev); |
1473 | 1470 | ||
@@ -1700,8 +1697,6 @@ qlcnic_process_rcv_diag(struct qlcnic_adapter *adapter, | |||
1700 | if (pkt_offset) | 1697 | if (pkt_offset) |
1701 | skb_pull(skb, pkt_offset); | 1698 | skb_pull(skb, pkt_offset); |
1702 | 1699 | ||
1703 | skb->truesize = skb->len + sizeof(struct sk_buff); | ||
1704 | |||
1705 | if (!qlcnic_check_loopback_buff(skb->data)) | 1700 | if (!qlcnic_check_loopback_buff(skb->data)) |
1706 | adapter->diag_cnt++; | 1701 | adapter->diag_cnt++; |
1707 | 1702 | ||
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index bf6d87adda4..66eea597202 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c | |||
@@ -1983,8 +1983,6 @@ static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev) | |||
1983 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | 1983 | struct qlcnic_adapter *adapter = netdev_priv(netdev); |
1984 | struct net_device_stats *stats = &netdev->stats; | 1984 | struct net_device_stats *stats = &netdev->stats; |
1985 | 1985 | ||
1986 | memset(stats, 0, sizeof(*stats)); | ||
1987 | |||
1988 | stats->rx_packets = adapter->stats.rx_pkts + adapter->stats.lro_pkts; | 1986 | stats->rx_packets = adapter->stats.rx_pkts + adapter->stats.lro_pkts; |
1989 | stats->tx_packets = adapter->stats.xmitfinished; | 1987 | stats->tx_packets = adapter->stats.xmitfinished; |
1990 | stats->rx_bytes = adapter->stats.rxbytes + adapter->stats.lrobytes; | 1988 | stats->rx_bytes = adapter->stats.rxbytes + adapter->stats.lrobytes; |
@@ -2190,9 +2188,16 @@ static int qlcnic_rx_poll(struct napi_struct *napi, int budget) | |||
2190 | #ifdef CONFIG_NET_POLL_CONTROLLER | 2188 | #ifdef CONFIG_NET_POLL_CONTROLLER |
2191 | static void qlcnic_poll_controller(struct net_device *netdev) | 2189 | static void qlcnic_poll_controller(struct net_device *netdev) |
2192 | { | 2190 | { |
2191 | int ring; | ||
2192 | struct qlcnic_host_sds_ring *sds_ring; | ||
2193 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | 2193 | struct qlcnic_adapter *adapter = netdev_priv(netdev); |
2194 | struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; | ||
2195 | |||
2194 | disable_irq(adapter->irq); | 2196 | disable_irq(adapter->irq); |
2195 | qlcnic_intr(adapter->irq, adapter); | 2197 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { |
2198 | sds_ring = &recv_ctx->sds_rings[ring]; | ||
2199 | qlcnic_intr(adapter->irq, sds_ring); | ||
2200 | } | ||
2196 | enable_irq(adapter->irq); | 2201 | enable_irq(adapter->irq); |
2197 | } | 2202 | } |
2198 | #endif | 2203 | #endif |
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 8d63f69b27d..5f89e83501f 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c | |||
@@ -3919,12 +3919,12 @@ static int ql_adapter_down(struct ql_adapter *qdev) | |||
3919 | for (i = 0; i < qdev->rss_ring_count; i++) | 3919 | for (i = 0; i < qdev->rss_ring_count; i++) |
3920 | netif_napi_del(&qdev->rx_ring[i].napi); | 3920 | netif_napi_del(&qdev->rx_ring[i].napi); |
3921 | 3921 | ||
3922 | ql_free_rx_buffers(qdev); | ||
3923 | |||
3924 | status = ql_adapter_reset(qdev); | 3922 | status = ql_adapter_reset(qdev); |
3925 | if (status) | 3923 | if (status) |
3926 | netif_err(qdev, ifdown, qdev->ndev, "reset(func #%d) FAILED!\n", | 3924 | netif_err(qdev, ifdown, qdev->ndev, "reset(func #%d) FAILED!\n", |
3927 | qdev->func); | 3925 | qdev->func); |
3926 | ql_free_rx_buffers(qdev); | ||
3927 | |||
3928 | return status; | 3928 | return status; |
3929 | } | 3929 | } |
3930 | 3930 | ||
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 078bbf4e6f1..992db2fa136 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
@@ -1212,7 +1212,8 @@ static void rtl8169_update_counters(struct net_device *dev) | |||
1212 | if ((RTL_R8(ChipCmd) & CmdRxEnb) == 0) | 1212 | if ((RTL_R8(ChipCmd) & CmdRxEnb) == 0) |
1213 | return; | 1213 | return; |
1214 | 1214 | ||
1215 | counters = pci_alloc_consistent(tp->pci_dev, sizeof(*counters), &paddr); | 1215 | counters = dma_alloc_coherent(&tp->pci_dev->dev, sizeof(*counters), |
1216 | &paddr, GFP_KERNEL); | ||
1216 | if (!counters) | 1217 | if (!counters) |
1217 | return; | 1218 | return; |
1218 | 1219 | ||
@@ -1233,7 +1234,8 @@ static void rtl8169_update_counters(struct net_device *dev) | |||
1233 | RTL_W32(CounterAddrLow, 0); | 1234 | RTL_W32(CounterAddrLow, 0); |
1234 | RTL_W32(CounterAddrHigh, 0); | 1235 | RTL_W32(CounterAddrHigh, 0); |
1235 | 1236 | ||
1236 | pci_free_consistent(tp->pci_dev, sizeof(*counters), counters, paddr); | 1237 | dma_free_coherent(&tp->pci_dev->dev, sizeof(*counters), counters, |
1238 | paddr); | ||
1237 | } | 1239 | } |
1238 | 1240 | ||
1239 | static void rtl8169_get_ethtool_stats(struct net_device *dev, | 1241 | static void rtl8169_get_ethtool_stats(struct net_device *dev, |
@@ -2934,7 +2936,7 @@ static const struct rtl_cfg_info { | |||
2934 | .hw_start = rtl_hw_start_8168, | 2936 | .hw_start = rtl_hw_start_8168, |
2935 | .region = 2, | 2937 | .region = 2, |
2936 | .align = 8, | 2938 | .align = 8, |
2937 | .intr_event = SYSErr | LinkChg | RxOverflow | | 2939 | .intr_event = SYSErr | RxFIFOOver | LinkChg | RxOverflow | |
2938 | TxErr | TxOK | RxOK | RxErr, | 2940 | TxErr | TxOK | RxOK | RxErr, |
2939 | .napi_event = TxErr | TxOK | RxOK | RxOverflow, | 2941 | .napi_event = TxErr | TxOK | RxOK | RxOverflow, |
2940 | .features = RTL_FEATURE_GMII | RTL_FEATURE_MSI, | 2942 | .features = RTL_FEATURE_GMII | RTL_FEATURE_MSI, |
@@ -3292,15 +3294,15 @@ static int rtl8169_open(struct net_device *dev) | |||
3292 | 3294 | ||
3293 | /* | 3295 | /* |
3294 | * Rx and Tx desscriptors needs 256 bytes alignment. | 3296 | * Rx and Tx desscriptors needs 256 bytes alignment. |
3295 | * pci_alloc_consistent provides more. | 3297 | * dma_alloc_coherent provides more. |
3296 | */ | 3298 | */ |
3297 | tp->TxDescArray = pci_alloc_consistent(pdev, R8169_TX_RING_BYTES, | 3299 | tp->TxDescArray = dma_alloc_coherent(&pdev->dev, R8169_TX_RING_BYTES, |
3298 | &tp->TxPhyAddr); | 3300 | &tp->TxPhyAddr, GFP_KERNEL); |
3299 | if (!tp->TxDescArray) | 3301 | if (!tp->TxDescArray) |
3300 | goto err_pm_runtime_put; | 3302 | goto err_pm_runtime_put; |
3301 | 3303 | ||
3302 | tp->RxDescArray = pci_alloc_consistent(pdev, R8169_RX_RING_BYTES, | 3304 | tp->RxDescArray = dma_alloc_coherent(&pdev->dev, R8169_RX_RING_BYTES, |
3303 | &tp->RxPhyAddr); | 3305 | &tp->RxPhyAddr, GFP_KERNEL); |
3304 | if (!tp->RxDescArray) | 3306 | if (!tp->RxDescArray) |
3305 | goto err_free_tx_0; | 3307 | goto err_free_tx_0; |
3306 | 3308 | ||
@@ -3334,12 +3336,12 @@ out: | |||
3334 | err_release_ring_2: | 3336 | err_release_ring_2: |
3335 | rtl8169_rx_clear(tp); | 3337 | rtl8169_rx_clear(tp); |
3336 | err_free_rx_1: | 3338 | err_free_rx_1: |
3337 | pci_free_consistent(pdev, R8169_RX_RING_BYTES, tp->RxDescArray, | 3339 | dma_free_coherent(&pdev->dev, R8169_RX_RING_BYTES, tp->RxDescArray, |
3338 | tp->RxPhyAddr); | 3340 | tp->RxPhyAddr); |
3339 | tp->RxDescArray = NULL; | 3341 | tp->RxDescArray = NULL; |
3340 | err_free_tx_0: | 3342 | err_free_tx_0: |
3341 | pci_free_consistent(pdev, R8169_TX_RING_BYTES, tp->TxDescArray, | 3343 | dma_free_coherent(&pdev->dev, R8169_TX_RING_BYTES, tp->TxDescArray, |
3342 | tp->TxPhyAddr); | 3344 | tp->TxPhyAddr); |
3343 | tp->TxDescArray = NULL; | 3345 | tp->TxDescArray = NULL; |
3344 | err_pm_runtime_put: | 3346 | err_pm_runtime_put: |
3345 | pm_runtime_put_noidle(&pdev->dev); | 3347 | pm_runtime_put_noidle(&pdev->dev); |
@@ -3975,7 +3977,7 @@ static void rtl8169_free_rx_skb(struct rtl8169_private *tp, | |||
3975 | { | 3977 | { |
3976 | struct pci_dev *pdev = tp->pci_dev; | 3978 | struct pci_dev *pdev = tp->pci_dev; |
3977 | 3979 | ||
3978 | pci_unmap_single(pdev, le64_to_cpu(desc->addr), tp->rx_buf_sz, | 3980 | dma_unmap_single(&pdev->dev, le64_to_cpu(desc->addr), tp->rx_buf_sz, |
3979 | PCI_DMA_FROMDEVICE); | 3981 | PCI_DMA_FROMDEVICE); |
3980 | dev_kfree_skb(*sk_buff); | 3982 | dev_kfree_skb(*sk_buff); |
3981 | *sk_buff = NULL; | 3983 | *sk_buff = NULL; |
@@ -4000,7 +4002,7 @@ static inline void rtl8169_map_to_asic(struct RxDesc *desc, dma_addr_t mapping, | |||
4000 | static struct sk_buff *rtl8169_alloc_rx_skb(struct pci_dev *pdev, | 4002 | static struct sk_buff *rtl8169_alloc_rx_skb(struct pci_dev *pdev, |
4001 | struct net_device *dev, | 4003 | struct net_device *dev, |
4002 | struct RxDesc *desc, int rx_buf_sz, | 4004 | struct RxDesc *desc, int rx_buf_sz, |
4003 | unsigned int align) | 4005 | unsigned int align, gfp_t gfp) |
4004 | { | 4006 | { |
4005 | struct sk_buff *skb; | 4007 | struct sk_buff *skb; |
4006 | dma_addr_t mapping; | 4008 | dma_addr_t mapping; |
@@ -4008,13 +4010,13 @@ static struct sk_buff *rtl8169_alloc_rx_skb(struct pci_dev *pdev, | |||
4008 | 4010 | ||
4009 | pad = align ? align : NET_IP_ALIGN; | 4011 | pad = align ? align : NET_IP_ALIGN; |
4010 | 4012 | ||
4011 | skb = netdev_alloc_skb(dev, rx_buf_sz + pad); | 4013 | skb = __netdev_alloc_skb(dev, rx_buf_sz + pad, gfp); |
4012 | if (!skb) | 4014 | if (!skb) |
4013 | goto err_out; | 4015 | goto err_out; |
4014 | 4016 | ||
4015 | skb_reserve(skb, align ? ((pad - 1) & (unsigned long)skb->data) : pad); | 4017 | skb_reserve(skb, align ? ((pad - 1) & (unsigned long)skb->data) : pad); |
4016 | 4018 | ||
4017 | mapping = pci_map_single(pdev, skb->data, rx_buf_sz, | 4019 | mapping = dma_map_single(&pdev->dev, skb->data, rx_buf_sz, |
4018 | PCI_DMA_FROMDEVICE); | 4020 | PCI_DMA_FROMDEVICE); |
4019 | 4021 | ||
4020 | rtl8169_map_to_asic(desc, mapping, rx_buf_sz); | 4022 | rtl8169_map_to_asic(desc, mapping, rx_buf_sz); |
@@ -4039,7 +4041,7 @@ static void rtl8169_rx_clear(struct rtl8169_private *tp) | |||
4039 | } | 4041 | } |
4040 | 4042 | ||
4041 | static u32 rtl8169_rx_fill(struct rtl8169_private *tp, struct net_device *dev, | 4043 | static u32 rtl8169_rx_fill(struct rtl8169_private *tp, struct net_device *dev, |
4042 | u32 start, u32 end) | 4044 | u32 start, u32 end, gfp_t gfp) |
4043 | { | 4045 | { |
4044 | u32 cur; | 4046 | u32 cur; |
4045 | 4047 | ||
@@ -4054,7 +4056,7 @@ static u32 rtl8169_rx_fill(struct rtl8169_private *tp, struct net_device *dev, | |||
4054 | 4056 | ||
4055 | skb = rtl8169_alloc_rx_skb(tp->pci_dev, dev, | 4057 | skb = rtl8169_alloc_rx_skb(tp->pci_dev, dev, |
4056 | tp->RxDescArray + i, | 4058 | tp->RxDescArray + i, |
4057 | tp->rx_buf_sz, tp->align); | 4059 | tp->rx_buf_sz, tp->align, gfp); |
4058 | if (!skb) | 4060 | if (!skb) |
4059 | break; | 4061 | break; |
4060 | 4062 | ||
@@ -4082,7 +4084,7 @@ static int rtl8169_init_ring(struct net_device *dev) | |||
4082 | memset(tp->tx_skb, 0x0, NUM_TX_DESC * sizeof(struct ring_info)); | 4084 | memset(tp->tx_skb, 0x0, NUM_TX_DESC * sizeof(struct ring_info)); |
4083 | memset(tp->Rx_skbuff, 0x0, NUM_RX_DESC * sizeof(struct sk_buff *)); | 4085 | memset(tp->Rx_skbuff, 0x0, NUM_RX_DESC * sizeof(struct sk_buff *)); |
4084 | 4086 | ||
4085 | if (rtl8169_rx_fill(tp, dev, 0, NUM_RX_DESC) != NUM_RX_DESC) | 4087 | if (rtl8169_rx_fill(tp, dev, 0, NUM_RX_DESC, GFP_KERNEL) != NUM_RX_DESC) |
4086 | goto err_out; | 4088 | goto err_out; |
4087 | 4089 | ||
4088 | rtl8169_mark_as_last_descriptor(tp->RxDescArray + NUM_RX_DESC - 1); | 4090 | rtl8169_mark_as_last_descriptor(tp->RxDescArray + NUM_RX_DESC - 1); |
@@ -4099,7 +4101,8 @@ static void rtl8169_unmap_tx_skb(struct pci_dev *pdev, struct ring_info *tx_skb, | |||
4099 | { | 4101 | { |
4100 | unsigned int len = tx_skb->len; | 4102 | unsigned int len = tx_skb->len; |
4101 | 4103 | ||
4102 | pci_unmap_single(pdev, le64_to_cpu(desc->addr), len, PCI_DMA_TODEVICE); | 4104 | dma_unmap_single(&pdev->dev, le64_to_cpu(desc->addr), len, |
4105 | PCI_DMA_TODEVICE); | ||
4103 | desc->opts1 = 0x00; | 4106 | desc->opts1 = 0x00; |
4104 | desc->opts2 = 0x00; | 4107 | desc->opts2 = 0x00; |
4105 | desc->addr = 0x00; | 4108 | desc->addr = 0x00; |
@@ -4243,7 +4246,8 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, | |||
4243 | txd = tp->TxDescArray + entry; | 4246 | txd = tp->TxDescArray + entry; |
4244 | len = frag->size; | 4247 | len = frag->size; |
4245 | addr = ((void *) page_address(frag->page)) + frag->page_offset; | 4248 | addr = ((void *) page_address(frag->page)) + frag->page_offset; |
4246 | mapping = pci_map_single(tp->pci_dev, addr, len, PCI_DMA_TODEVICE); | 4249 | mapping = dma_map_single(&tp->pci_dev->dev, addr, len, |
4250 | PCI_DMA_TODEVICE); | ||
4247 | 4251 | ||
4248 | /* anti gcc 2.95.3 bugware (sic) */ | 4252 | /* anti gcc 2.95.3 bugware (sic) */ |
4249 | status = opts1 | len | (RingEnd * !((entry + 1) % NUM_TX_DESC)); | 4253 | status = opts1 | len | (RingEnd * !((entry + 1) % NUM_TX_DESC)); |
@@ -4313,7 +4317,8 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, | |||
4313 | tp->tx_skb[entry].skb = skb; | 4317 | tp->tx_skb[entry].skb = skb; |
4314 | } | 4318 | } |
4315 | 4319 | ||
4316 | mapping = pci_map_single(tp->pci_dev, skb->data, len, PCI_DMA_TODEVICE); | 4320 | mapping = dma_map_single(&tp->pci_dev->dev, skb->data, len, |
4321 | PCI_DMA_TODEVICE); | ||
4317 | 4322 | ||
4318 | tp->tx_skb[entry].len = len; | 4323 | tp->tx_skb[entry].len = len; |
4319 | txd->addr = cpu_to_le64(mapping); | 4324 | txd->addr = cpu_to_le64(mapping); |
@@ -4477,8 +4482,8 @@ static inline bool rtl8169_try_rx_copy(struct sk_buff **sk_buff, | |||
4477 | if (!skb) | 4482 | if (!skb) |
4478 | goto out; | 4483 | goto out; |
4479 | 4484 | ||
4480 | pci_dma_sync_single_for_cpu(tp->pci_dev, addr, pkt_size, | 4485 | dma_sync_single_for_cpu(&tp->pci_dev->dev, addr, pkt_size, |
4481 | PCI_DMA_FROMDEVICE); | 4486 | PCI_DMA_FROMDEVICE); |
4482 | skb_copy_from_linear_data(*sk_buff, skb->data, pkt_size); | 4487 | skb_copy_from_linear_data(*sk_buff, skb->data, pkt_size); |
4483 | *sk_buff = skb; | 4488 | *sk_buff = skb; |
4484 | done = true; | 4489 | done = true; |
@@ -4549,11 +4554,11 @@ static int rtl8169_rx_interrupt(struct net_device *dev, | |||
4549 | rtl8169_rx_csum(skb, desc); | 4554 | rtl8169_rx_csum(skb, desc); |
4550 | 4555 | ||
4551 | if (rtl8169_try_rx_copy(&skb, tp, pkt_size, addr)) { | 4556 | if (rtl8169_try_rx_copy(&skb, tp, pkt_size, addr)) { |
4552 | pci_dma_sync_single_for_device(pdev, addr, | 4557 | dma_sync_single_for_device(&pdev->dev, addr, |
4553 | pkt_size, PCI_DMA_FROMDEVICE); | 4558 | pkt_size, PCI_DMA_FROMDEVICE); |
4554 | rtl8169_mark_to_asic(desc, tp->rx_buf_sz); | 4559 | rtl8169_mark_to_asic(desc, tp->rx_buf_sz); |
4555 | } else { | 4560 | } else { |
4556 | pci_unmap_single(pdev, addr, tp->rx_buf_sz, | 4561 | dma_unmap_single(&pdev->dev, addr, tp->rx_buf_sz, |
4557 | PCI_DMA_FROMDEVICE); | 4562 | PCI_DMA_FROMDEVICE); |
4558 | tp->Rx_skbuff[entry] = NULL; | 4563 | tp->Rx_skbuff[entry] = NULL; |
4559 | } | 4564 | } |
@@ -4583,7 +4588,7 @@ static int rtl8169_rx_interrupt(struct net_device *dev, | |||
4583 | count = cur_rx - tp->cur_rx; | 4588 | count = cur_rx - tp->cur_rx; |
4584 | tp->cur_rx = cur_rx; | 4589 | tp->cur_rx = cur_rx; |
4585 | 4590 | ||
4586 | delta = rtl8169_rx_fill(tp, dev, tp->dirty_rx, tp->cur_rx); | 4591 | delta = rtl8169_rx_fill(tp, dev, tp->dirty_rx, tp->cur_rx, GFP_ATOMIC); |
4587 | if (!delta && count) | 4592 | if (!delta && count) |
4588 | netif_info(tp, intr, dev, "no Rx buffer allocated\n"); | 4593 | netif_info(tp, intr, dev, "no Rx buffer allocated\n"); |
4589 | tp->dirty_rx += delta; | 4594 | tp->dirty_rx += delta; |
@@ -4625,8 +4630,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) | |||
4625 | } | 4630 | } |
4626 | 4631 | ||
4627 | /* Work around for rx fifo overflow */ | 4632 | /* Work around for rx fifo overflow */ |
4628 | if (unlikely(status & RxFIFOOver) && | 4633 | if (unlikely(status & RxFIFOOver)) { |
4629 | (tp->mac_version == RTL_GIGA_MAC_VER_11)) { | ||
4630 | netif_stop_queue(dev); | 4634 | netif_stop_queue(dev); |
4631 | rtl8169_tx_timeout(dev); | 4635 | rtl8169_tx_timeout(dev); |
4632 | break; | 4636 | break; |
@@ -4770,10 +4774,10 @@ static int rtl8169_close(struct net_device *dev) | |||
4770 | 4774 | ||
4771 | free_irq(dev->irq, dev); | 4775 | free_irq(dev->irq, dev); |
4772 | 4776 | ||
4773 | pci_free_consistent(pdev, R8169_RX_RING_BYTES, tp->RxDescArray, | 4777 | dma_free_coherent(&pdev->dev, R8169_RX_RING_BYTES, tp->RxDescArray, |
4774 | tp->RxPhyAddr); | 4778 | tp->RxPhyAddr); |
4775 | pci_free_consistent(pdev, R8169_TX_RING_BYTES, tp->TxDescArray, | 4779 | dma_free_coherent(&pdev->dev, R8169_TX_RING_BYTES, tp->TxDescArray, |
4776 | tp->TxPhyAddr); | 4780 | tp->TxPhyAddr); |
4777 | tp->TxDescArray = NULL; | 4781 | tp->TxDescArray = NULL; |
4778 | tp->RxDescArray = NULL; | 4782 | tp->RxDescArray = NULL; |
4779 | 4783 | ||
diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c index 07eb884ff98..44150f2f7bf 100644 --- a/drivers/net/rionet.c +++ b/drivers/net/rionet.c | |||
@@ -384,7 +384,7 @@ static void rionet_remove(struct rio_dev *rdev) | |||
384 | free_pages((unsigned long)rionet_active, rdev->net->hport->sys_size ? | 384 | free_pages((unsigned long)rionet_active, rdev->net->hport->sys_size ? |
385 | __ilog2(sizeof(void *)) + 4 : 0); | 385 | __ilog2(sizeof(void *)) + 4 : 0); |
386 | unregister_netdev(ndev); | 386 | unregister_netdev(ndev); |
387 | kfree(ndev); | 387 | free_netdev(ndev); |
388 | 388 | ||
389 | list_for_each_entry_safe(peer, tmp, &rionet_peers, node) { | 389 | list_for_each_entry_safe(peer, tmp, &rionet_peers, node) { |
390 | list_del(&peer->node); | 390 | list_del(&peer->node); |
diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c index cc4bd8c65f8..9265315baa0 100644 --- a/drivers/net/sgiseeq.c +++ b/drivers/net/sgiseeq.c | |||
@@ -804,7 +804,7 @@ static int __devinit sgiseeq_probe(struct platform_device *pdev) | |||
804 | err_out_free_page: | 804 | err_out_free_page: |
805 | free_page((unsigned long) sp->srings); | 805 | free_page((unsigned long) sp->srings); |
806 | err_out_free_dev: | 806 | err_out_free_dev: |
807 | kfree(dev); | 807 | free_netdev(dev); |
808 | 808 | ||
809 | err_out: | 809 | err_out: |
810 | return err; | 810 | return err; |
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index f5a9eb1df59..79fd02bc69f 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c | |||
@@ -1437,7 +1437,7 @@ static const struct net_device_ops sh_eth_netdev_ops = { | |||
1437 | 1437 | ||
1438 | static int sh_eth_drv_probe(struct platform_device *pdev) | 1438 | static int sh_eth_drv_probe(struct platform_device *pdev) |
1439 | { | 1439 | { |
1440 | int ret, i, devno = 0; | 1440 | int ret, devno = 0; |
1441 | struct resource *res; | 1441 | struct resource *res; |
1442 | struct net_device *ndev = NULL; | 1442 | struct net_device *ndev = NULL; |
1443 | struct sh_eth_private *mdp; | 1443 | struct sh_eth_private *mdp; |
diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 40e5c46e757..465ae7e8450 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <linux/seq_file.h> | 43 | #include <linux/seq_file.h> |
44 | #include <linux/mii.h> | 44 | #include <linux/mii.h> |
45 | #include <linux/slab.h> | 45 | #include <linux/slab.h> |
46 | #include <linux/dmi.h> | ||
46 | #include <asm/irq.h> | 47 | #include <asm/irq.h> |
47 | 48 | ||
48 | #include "skge.h" | 49 | #include "skge.h" |
@@ -3868,6 +3869,8 @@ static void __devinit skge_show_addr(struct net_device *dev) | |||
3868 | netif_info(skge, probe, skge->netdev, "addr %pM\n", dev->dev_addr); | 3869 | netif_info(skge, probe, skge->netdev, "addr %pM\n", dev->dev_addr); |
3869 | } | 3870 | } |
3870 | 3871 | ||
3872 | static int only_32bit_dma; | ||
3873 | |||
3871 | static int __devinit skge_probe(struct pci_dev *pdev, | 3874 | static int __devinit skge_probe(struct pci_dev *pdev, |
3872 | const struct pci_device_id *ent) | 3875 | const struct pci_device_id *ent) |
3873 | { | 3876 | { |
@@ -3889,7 +3892,7 @@ static int __devinit skge_probe(struct pci_dev *pdev, | |||
3889 | 3892 | ||
3890 | pci_set_master(pdev); | 3893 | pci_set_master(pdev); |
3891 | 3894 | ||
3892 | if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { | 3895 | if (!only_32bit_dma && !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { |
3893 | using_dac = 1; | 3896 | using_dac = 1; |
3894 | err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); | 3897 | err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); |
3895 | } else if (!(err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))) { | 3898 | } else if (!(err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))) { |
@@ -4147,8 +4150,21 @@ static struct pci_driver skge_driver = { | |||
4147 | .shutdown = skge_shutdown, | 4150 | .shutdown = skge_shutdown, |
4148 | }; | 4151 | }; |
4149 | 4152 | ||
4153 | static struct dmi_system_id skge_32bit_dma_boards[] = { | ||
4154 | { | ||
4155 | .ident = "Gigabyte nForce boards", | ||
4156 | .matches = { | ||
4157 | DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co"), | ||
4158 | DMI_MATCH(DMI_BOARD_NAME, "nForce"), | ||
4159 | }, | ||
4160 | }, | ||
4161 | {} | ||
4162 | }; | ||
4163 | |||
4150 | static int __init skge_init_module(void) | 4164 | static int __init skge_init_module(void) |
4151 | { | 4165 | { |
4166 | if (dmi_check_system(skge_32bit_dma_boards)) | ||
4167 | only_32bit_dma = 1; | ||
4152 | skge_debug_init(); | 4168 | skge_debug_init(); |
4153 | return pci_register_driver(&skge_driver); | 4169 | return pci_register_driver(&skge_driver); |
4154 | } | 4170 | } |
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index 0909ae934ad..8150ba15411 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c | |||
@@ -58,6 +58,7 @@ | |||
58 | 58 | ||
59 | MODULE_LICENSE("GPL"); | 59 | MODULE_LICENSE("GPL"); |
60 | MODULE_VERSION(SMSC_DRV_VERSION); | 60 | MODULE_VERSION(SMSC_DRV_VERSION); |
61 | MODULE_ALIAS("platform:smsc911x"); | ||
61 | 62 | ||
62 | #if USE_DEBUG > 0 | 63 | #if USE_DEBUG > 0 |
63 | static int debug = 16; | 64 | static int debug = 16; |
diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index bbb7951b9c4..ea0461eb2db 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c | |||
@@ -1865,15 +1865,15 @@ static int stmmac_resume(struct platform_device *pdev) | |||
1865 | if (!netif_running(dev)) | 1865 | if (!netif_running(dev)) |
1866 | return 0; | 1866 | return 0; |
1867 | 1867 | ||
1868 | spin_lock(&priv->lock); | ||
1869 | |||
1870 | if (priv->shutdown) { | 1868 | if (priv->shutdown) { |
1871 | /* Re-open the interface and re-init the MAC/DMA | 1869 | /* Re-open the interface and re-init the MAC/DMA |
1872 | and the rings. */ | 1870 | and the rings (i.e. on hibernation stage) */ |
1873 | stmmac_open(dev); | 1871 | stmmac_open(dev); |
1874 | goto out_resume; | 1872 | return 0; |
1875 | } | 1873 | } |
1876 | 1874 | ||
1875 | spin_lock(&priv->lock); | ||
1876 | |||
1877 | /* Power Down bit, into the PM register, is cleared | 1877 | /* Power Down bit, into the PM register, is cleared |
1878 | * automatically as soon as a magic packet or a Wake-up frame | 1878 | * automatically as soon as a magic packet or a Wake-up frame |
1879 | * is received. Anyway, it's better to manually clear | 1879 | * is received. Anyway, it's better to manually clear |
@@ -1901,7 +1901,6 @@ static int stmmac_resume(struct platform_device *pdev) | |||
1901 | 1901 | ||
1902 | netif_start_queue(dev); | 1902 | netif_start_queue(dev); |
1903 | 1903 | ||
1904 | out_resume: | ||
1905 | spin_unlock(&priv->lock); | 1904 | spin_unlock(&priv->lock); |
1906 | return 0; | 1905 | return 0; |
1907 | } | 1906 | } |
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index bc3af78a869..1ec4b9e0239 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -4666,7 +4666,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) | |||
4666 | desc_idx, *post_ptr); | 4666 | desc_idx, *post_ptr); |
4667 | drop_it_no_recycle: | 4667 | drop_it_no_recycle: |
4668 | /* Other statistics kept track of by card. */ | 4668 | /* Other statistics kept track of by card. */ |
4669 | tp->net_stats.rx_dropped++; | 4669 | tp->rx_dropped++; |
4670 | goto next_pkt; | 4670 | goto next_pkt; |
4671 | } | 4671 | } |
4672 | 4672 | ||
@@ -4726,7 +4726,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) | |||
4726 | if (len > (tp->dev->mtu + ETH_HLEN) && | 4726 | if (len > (tp->dev->mtu + ETH_HLEN) && |
4727 | skb->protocol != htons(ETH_P_8021Q)) { | 4727 | skb->protocol != htons(ETH_P_8021Q)) { |
4728 | dev_kfree_skb(skb); | 4728 | dev_kfree_skb(skb); |
4729 | goto next_pkt; | 4729 | goto drop_it_no_recycle; |
4730 | } | 4730 | } |
4731 | 4731 | ||
4732 | if (desc->type_flags & RXD_FLAG_VLAN && | 4732 | if (desc->type_flags & RXD_FLAG_VLAN && |
@@ -9240,6 +9240,8 @@ static struct rtnl_link_stats64 *tg3_get_stats64(struct net_device *dev, | |||
9240 | stats->rx_missed_errors = old_stats->rx_missed_errors + | 9240 | stats->rx_missed_errors = old_stats->rx_missed_errors + |
9241 | get_stat64(&hw_stats->rx_discards); | 9241 | get_stat64(&hw_stats->rx_discards); |
9242 | 9242 | ||
9243 | stats->rx_dropped = tp->rx_dropped; | ||
9244 | |||
9243 | return stats; | 9245 | return stats; |
9244 | } | 9246 | } |
9245 | 9247 | ||
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 4937bd19096..be7ff138a7f 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h | |||
@@ -2759,7 +2759,7 @@ struct tg3 { | |||
2759 | 2759 | ||
2760 | 2760 | ||
2761 | /* begin "everything else" cacheline(s) section */ | 2761 | /* begin "everything else" cacheline(s) section */ |
2762 | struct rtnl_link_stats64 net_stats; | 2762 | unsigned long rx_dropped; |
2763 | struct rtnl_link_stats64 net_stats_prev; | 2763 | struct rtnl_link_stats64 net_stats_prev; |
2764 | struct tg3_ethtool_stats estats; | 2764 | struct tg3_ethtool_stats estats; |
2765 | struct tg3_ethtool_stats estats_prev; | 2765 | struct tg3_ethtool_stats estats_prev; |
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index 5efa57757a2..6888e3d4146 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c | |||
@@ -243,6 +243,7 @@ enum { | |||
243 | NWayState = (1 << 14) | (1 << 13) | (1 << 12), | 243 | NWayState = (1 << 14) | (1 << 13) | (1 << 12), |
244 | NWayRestart = (1 << 12), | 244 | NWayRestart = (1 << 12), |
245 | NonselPortActive = (1 << 9), | 245 | NonselPortActive = (1 << 9), |
246 | SelPortActive = (1 << 8), | ||
246 | LinkFailStatus = (1 << 2), | 247 | LinkFailStatus = (1 << 2), |
247 | NetCxnErr = (1 << 1), | 248 | NetCxnErr = (1 << 1), |
248 | }; | 249 | }; |
@@ -363,7 +364,9 @@ static u16 t21040_csr15[] = { 0, 0, 0x0006, 0x0000, 0x0000, }; | |||
363 | 364 | ||
364 | /* 21041 transceiver register settings: TP AUTO, BNC, AUI, TP, TP FD*/ | 365 | /* 21041 transceiver register settings: TP AUTO, BNC, AUI, TP, TP FD*/ |
365 | static u16 t21041_csr13[] = { 0xEF01, 0xEF09, 0xEF09, 0xEF01, 0xEF09, }; | 366 | static u16 t21041_csr13[] = { 0xEF01, 0xEF09, 0xEF09, 0xEF01, 0xEF09, }; |
366 | static u16 t21041_csr14[] = { 0xFFFF, 0xF7FD, 0xF7FD, 0x6F3F, 0x6F3D, }; | 367 | static u16 t21041_csr14[] = { 0xFFFF, 0xF7FD, 0xF7FD, 0x7F3F, 0x7F3D, }; |
368 | /* If on-chip autonegotiation is broken, use half-duplex (FF3F) instead */ | ||
369 | static u16 t21041_csr14_brk[] = { 0xFF3F, 0xF7FD, 0xF7FD, 0x7F3F, 0x7F3D, }; | ||
367 | static u16 t21041_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, }; | 370 | static u16 t21041_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, }; |
368 | 371 | ||
369 | 372 | ||
@@ -1064,6 +1067,9 @@ static void de21041_media_timer (unsigned long data) | |||
1064 | unsigned int carrier; | 1067 | unsigned int carrier; |
1065 | unsigned long flags; | 1068 | unsigned long flags; |
1066 | 1069 | ||
1070 | /* clear port active bits */ | ||
1071 | dw32(SIAStatus, NonselPortActive | SelPortActive); | ||
1072 | |||
1067 | carrier = (status & NetCxnErr) ? 0 : 1; | 1073 | carrier = (status & NetCxnErr) ? 0 : 1; |
1068 | 1074 | ||
1069 | if (carrier) { | 1075 | if (carrier) { |
@@ -1158,14 +1164,29 @@ no_link_yet: | |||
1158 | static void de_media_interrupt (struct de_private *de, u32 status) | 1164 | static void de_media_interrupt (struct de_private *de, u32 status) |
1159 | { | 1165 | { |
1160 | if (status & LinkPass) { | 1166 | if (status & LinkPass) { |
1167 | /* Ignore if current media is AUI or BNC and we can't use TP */ | ||
1168 | if ((de->media_type == DE_MEDIA_AUI || | ||
1169 | de->media_type == DE_MEDIA_BNC) && | ||
1170 | (de->media_lock || | ||
1171 | !de_ok_to_advertise(de, DE_MEDIA_TP_AUTO))) | ||
1172 | return; | ||
1173 | /* If current media is not TP, change it to TP */ | ||
1174 | if ((de->media_type == DE_MEDIA_AUI || | ||
1175 | de->media_type == DE_MEDIA_BNC)) { | ||
1176 | de->media_type = DE_MEDIA_TP_AUTO; | ||
1177 | de_stop_rxtx(de); | ||
1178 | de_set_media(de); | ||
1179 | de_start_rxtx(de); | ||
1180 | } | ||
1161 | de_link_up(de); | 1181 | de_link_up(de); |
1162 | mod_timer(&de->media_timer, jiffies + DE_TIMER_LINK); | 1182 | mod_timer(&de->media_timer, jiffies + DE_TIMER_LINK); |
1163 | return; | 1183 | return; |
1164 | } | 1184 | } |
1165 | 1185 | ||
1166 | BUG_ON(!(status & LinkFail)); | 1186 | BUG_ON(!(status & LinkFail)); |
1167 | 1187 | /* Mark the link as down only if current media is TP */ | |
1168 | if (netif_carrier_ok(de->dev)) { | 1188 | if (netif_carrier_ok(de->dev) && de->media_type != DE_MEDIA_AUI && |
1189 | de->media_type != DE_MEDIA_BNC) { | ||
1169 | de_link_down(de); | 1190 | de_link_down(de); |
1170 | mod_timer(&de->media_timer, jiffies + DE_TIMER_NO_LINK); | 1191 | mod_timer(&de->media_timer, jiffies + DE_TIMER_NO_LINK); |
1171 | } | 1192 | } |
@@ -1229,6 +1250,7 @@ static void de_adapter_sleep (struct de_private *de) | |||
1229 | if (de->de21040) | 1250 | if (de->de21040) |
1230 | return; | 1251 | return; |
1231 | 1252 | ||
1253 | dw32(CSR13, 0); /* Reset phy */ | ||
1232 | pci_read_config_dword(de->pdev, PCIPM, &pmctl); | 1254 | pci_read_config_dword(de->pdev, PCIPM, &pmctl); |
1233 | pmctl |= PM_Sleep; | 1255 | pmctl |= PM_Sleep; |
1234 | pci_write_config_dword(de->pdev, PCIPM, pmctl); | 1256 | pci_write_config_dword(de->pdev, PCIPM, pmctl); |
@@ -1574,12 +1596,15 @@ static int __de_set_settings(struct de_private *de, struct ethtool_cmd *ecmd) | |||
1574 | return 0; /* nothing to change */ | 1596 | return 0; /* nothing to change */ |
1575 | 1597 | ||
1576 | de_link_down(de); | 1598 | de_link_down(de); |
1599 | mod_timer(&de->media_timer, jiffies + DE_TIMER_NO_LINK); | ||
1577 | de_stop_rxtx(de); | 1600 | de_stop_rxtx(de); |
1578 | 1601 | ||
1579 | de->media_type = new_media; | 1602 | de->media_type = new_media; |
1580 | de->media_lock = media_lock; | 1603 | de->media_lock = media_lock; |
1581 | de->media_advertise = ecmd->advertising; | 1604 | de->media_advertise = ecmd->advertising; |
1582 | de_set_media(de); | 1605 | de_set_media(de); |
1606 | if (netif_running(de->dev)) | ||
1607 | de_start_rxtx(de); | ||
1583 | 1608 | ||
1584 | return 0; | 1609 | return 0; |
1585 | } | 1610 | } |
@@ -1911,8 +1936,14 @@ fill_defaults: | |||
1911 | for (i = 0; i < DE_MAX_MEDIA; i++) { | 1936 | for (i = 0; i < DE_MAX_MEDIA; i++) { |
1912 | if (de->media[i].csr13 == 0xffff) | 1937 | if (de->media[i].csr13 == 0xffff) |
1913 | de->media[i].csr13 = t21041_csr13[i]; | 1938 | de->media[i].csr13 = t21041_csr13[i]; |
1914 | if (de->media[i].csr14 == 0xffff) | 1939 | if (de->media[i].csr14 == 0xffff) { |
1915 | de->media[i].csr14 = t21041_csr14[i]; | 1940 | /* autonegotiation is broken at least on some chip |
1941 | revisions - rev. 0x21 works, 0x11 does not */ | ||
1942 | if (de->pdev->revision < 0x20) | ||
1943 | de->media[i].csr14 = t21041_csr14_brk[i]; | ||
1944 | else | ||
1945 | de->media[i].csr14 = t21041_csr14[i]; | ||
1946 | } | ||
1916 | if (de->media[i].csr15 == 0xffff) | 1947 | if (de->media[i].csr15 == 0xffff) |
1917 | de->media[i].csr15 = t21041_csr15[i]; | 1948 | de->media[i].csr15 = t21041_csr15[i]; |
1918 | } | 1949 | } |
@@ -2158,6 +2189,8 @@ static int de_resume (struct pci_dev *pdev) | |||
2158 | dev_err(&dev->dev, "pci_enable_device failed in resume\n"); | 2189 | dev_err(&dev->dev, "pci_enable_device failed in resume\n"); |
2159 | goto out; | 2190 | goto out; |
2160 | } | 2191 | } |
2192 | pci_set_master(pdev); | ||
2193 | de_init_rings(de); | ||
2161 | de_init_hw(de); | 2194 | de_init_hw(de); |
2162 | out_attach: | 2195 | out_attach: |
2163 | netif_device_attach(dev); | 2196 | netif_device_attach(dev); |
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 6efca66b876..1cd752f9a6e 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c | |||
@@ -1652,6 +1652,8 @@ static int hso_get_count(struct hso_serial *serial, | |||
1652 | struct uart_icount cnow; | 1652 | struct uart_icount cnow; |
1653 | struct hso_tiocmget *tiocmget = serial->tiocmget; | 1653 | struct hso_tiocmget *tiocmget = serial->tiocmget; |
1654 | 1654 | ||
1655 | memset(&icount, 0, sizeof(struct serial_icounter_struct)); | ||
1656 | |||
1655 | if (!tiocmget) | 1657 | if (!tiocmget) |
1656 | return -ENOENT; | 1658 | return -ENOENT; |
1657 | spin_lock_irq(&serial->serial_lock); | 1659 | spin_lock_irq(&serial->serial_lock); |
diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c index 08e7b6abacd..b2bcf99e6f0 100644 --- a/drivers/net/usb/ipheth.c +++ b/drivers/net/usb/ipheth.c | |||
@@ -58,6 +58,7 @@ | |||
58 | #define USB_PRODUCT_IPHONE 0x1290 | 58 | #define USB_PRODUCT_IPHONE 0x1290 |
59 | #define USB_PRODUCT_IPHONE_3G 0x1292 | 59 | #define USB_PRODUCT_IPHONE_3G 0x1292 |
60 | #define USB_PRODUCT_IPHONE_3GS 0x1294 | 60 | #define USB_PRODUCT_IPHONE_3GS 0x1294 |
61 | #define USB_PRODUCT_IPHONE_4 0x1297 | ||
61 | 62 | ||
62 | #define IPHETH_USBINTF_CLASS 255 | 63 | #define IPHETH_USBINTF_CLASS 255 |
63 | #define IPHETH_USBINTF_SUBCLASS 253 | 64 | #define IPHETH_USBINTF_SUBCLASS 253 |
@@ -92,6 +93,10 @@ static struct usb_device_id ipheth_table[] = { | |||
92 | USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_3GS, | 93 | USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_3GS, |
93 | IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, | 94 | IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, |
94 | IPHETH_USBINTF_PROTO) }, | 95 | IPHETH_USBINTF_PROTO) }, |
96 | { USB_DEVICE_AND_INTERFACE_INFO( | ||
97 | USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4, | ||
98 | IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, | ||
99 | IPHETH_USBINTF_PROTO) }, | ||
95 | { } | 100 | { } |
96 | }; | 101 | }; |
97 | MODULE_DEVICE_TABLE(usb, ipheth_table); | 102 | MODULE_DEVICE_TABLE(usb, ipheth_table); |
@@ -424,10 +429,6 @@ static const struct net_device_ops ipheth_netdev_ops = { | |||
424 | .ndo_get_stats = &ipheth_stats, | 429 | .ndo_get_stats = &ipheth_stats, |
425 | }; | 430 | }; |
426 | 431 | ||
427 | static struct device_type ipheth_type = { | ||
428 | .name = "wwan", | ||
429 | }; | ||
430 | |||
431 | static int ipheth_probe(struct usb_interface *intf, | 432 | static int ipheth_probe(struct usb_interface *intf, |
432 | const struct usb_device_id *id) | 433 | const struct usb_device_id *id) |
433 | { | 434 | { |
@@ -445,7 +446,7 @@ static int ipheth_probe(struct usb_interface *intf, | |||
445 | 446 | ||
446 | netdev->netdev_ops = &ipheth_netdev_ops; | 447 | netdev->netdev_ops = &ipheth_netdev_ops; |
447 | netdev->watchdog_timeo = IPHETH_TX_TIMEOUT; | 448 | netdev->watchdog_timeo = IPHETH_TX_TIMEOUT; |
448 | strcpy(netdev->name, "wwan%d"); | 449 | strcpy(netdev->name, "eth%d"); |
449 | 450 | ||
450 | dev = netdev_priv(netdev); | 451 | dev = netdev_priv(netdev); |
451 | dev->udev = udev; | 452 | dev->udev = udev; |
@@ -495,7 +496,6 @@ static int ipheth_probe(struct usb_interface *intf, | |||
495 | 496 | ||
496 | SET_NETDEV_DEV(netdev, &intf->dev); | 497 | SET_NETDEV_DEV(netdev, &intf->dev); |
497 | SET_ETHTOOL_OPS(netdev, &ops); | 498 | SET_ETHTOOL_OPS(netdev, &ops); |
498 | SET_NETDEV_DEVTYPE(netdev, &ipheth_type); | ||
499 | 499 | ||
500 | retval = register_netdev(netdev); | 500 | retval = register_netdev(netdev); |
501 | if (retval) { | 501 | if (retval) { |
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index fd69095ef6e..f53412368ce 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c | |||
@@ -2824,7 +2824,7 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi | |||
2824 | netif_napi_add(dev, &vptr->napi, velocity_poll, VELOCITY_NAPI_WEIGHT); | 2824 | netif_napi_add(dev, &vptr->napi, velocity_poll, VELOCITY_NAPI_WEIGHT); |
2825 | 2825 | ||
2826 | dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER | | 2826 | dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER | |
2827 | NETIF_F_HW_VLAN_RX | NETIF_F_IP_CSUM | NETIF_F_SG; | 2827 | NETIF_F_HW_VLAN_RX | NETIF_F_IP_CSUM; |
2828 | 2828 | ||
2829 | ret = register_netdev(dev); | 2829 | ret = register_netdev(dev); |
2830 | if (ret < 0) | 2830 | if (ret < 0) |
diff --git a/drivers/net/wimax/i2400m/rx.c b/drivers/net/wimax/i2400m/rx.c index 8cc9e319f43..1737d1488b3 100644 --- a/drivers/net/wimax/i2400m/rx.c +++ b/drivers/net/wimax/i2400m/rx.c | |||
@@ -1244,16 +1244,16 @@ int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb) | |||
1244 | int i, result; | 1244 | int i, result; |
1245 | struct device *dev = i2400m_dev(i2400m); | 1245 | struct device *dev = i2400m_dev(i2400m); |
1246 | const struct i2400m_msg_hdr *msg_hdr; | 1246 | const struct i2400m_msg_hdr *msg_hdr; |
1247 | size_t pl_itr, pl_size, skb_len; | 1247 | size_t pl_itr, pl_size; |
1248 | unsigned long flags; | 1248 | unsigned long flags; |
1249 | unsigned num_pls, single_last; | 1249 | unsigned num_pls, single_last, skb_len; |
1250 | 1250 | ||
1251 | skb_len = skb->len; | 1251 | skb_len = skb->len; |
1252 | d_fnstart(4, dev, "(i2400m %p skb %p [size %zu])\n", | 1252 | d_fnstart(4, dev, "(i2400m %p skb %p [size %u])\n", |
1253 | i2400m, skb, skb_len); | 1253 | i2400m, skb, skb_len); |
1254 | result = -EIO; | 1254 | result = -EIO; |
1255 | msg_hdr = (void *) skb->data; | 1255 | msg_hdr = (void *) skb->data; |
1256 | result = i2400m_rx_msg_hdr_check(i2400m, msg_hdr, skb->len); | 1256 | result = i2400m_rx_msg_hdr_check(i2400m, msg_hdr, skb_len); |
1257 | if (result < 0) | 1257 | if (result < 0) |
1258 | goto error_msg_hdr_check; | 1258 | goto error_msg_hdr_check; |
1259 | result = -EIO; | 1259 | result = -EIO; |
@@ -1261,10 +1261,10 @@ int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb) | |||
1261 | pl_itr = sizeof(*msg_hdr) + /* Check payload descriptor(s) */ | 1261 | pl_itr = sizeof(*msg_hdr) + /* Check payload descriptor(s) */ |
1262 | num_pls * sizeof(msg_hdr->pld[0]); | 1262 | num_pls * sizeof(msg_hdr->pld[0]); |
1263 | pl_itr = ALIGN(pl_itr, I2400M_PL_ALIGN); | 1263 | pl_itr = ALIGN(pl_itr, I2400M_PL_ALIGN); |
1264 | if (pl_itr > skb->len) { /* got all the payload descriptors? */ | 1264 | if (pl_itr > skb_len) { /* got all the payload descriptors? */ |
1265 | dev_err(dev, "RX: HW BUG? message too short (%u bytes) for " | 1265 | dev_err(dev, "RX: HW BUG? message too short (%u bytes) for " |
1266 | "%u payload descriptors (%zu each, total %zu)\n", | 1266 | "%u payload descriptors (%zu each, total %zu)\n", |
1267 | skb->len, num_pls, sizeof(msg_hdr->pld[0]), pl_itr); | 1267 | skb_len, num_pls, sizeof(msg_hdr->pld[0]), pl_itr); |
1268 | goto error_pl_descr_short; | 1268 | goto error_pl_descr_short; |
1269 | } | 1269 | } |
1270 | /* Walk each payload payload--check we really got it */ | 1270 | /* Walk each payload payload--check we really got it */ |
@@ -1272,7 +1272,7 @@ int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb) | |||
1272 | /* work around old gcc warnings */ | 1272 | /* work around old gcc warnings */ |
1273 | pl_size = i2400m_pld_size(&msg_hdr->pld[i]); | 1273 | pl_size = i2400m_pld_size(&msg_hdr->pld[i]); |
1274 | result = i2400m_rx_pl_descr_check(i2400m, &msg_hdr->pld[i], | 1274 | result = i2400m_rx_pl_descr_check(i2400m, &msg_hdr->pld[i], |
1275 | pl_itr, skb->len); | 1275 | pl_itr, skb_len); |
1276 | if (result < 0) | 1276 | if (result < 0) |
1277 | goto error_pl_descr_check; | 1277 | goto error_pl_descr_check; |
1278 | single_last = num_pls == 1 || i == num_pls - 1; | 1278 | single_last = num_pls == 1 || i == num_pls - 1; |
@@ -1290,16 +1290,16 @@ int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb) | |||
1290 | if (i < i2400m->rx_pl_min) | 1290 | if (i < i2400m->rx_pl_min) |
1291 | i2400m->rx_pl_min = i; | 1291 | i2400m->rx_pl_min = i; |
1292 | i2400m->rx_num++; | 1292 | i2400m->rx_num++; |
1293 | i2400m->rx_size_acc += skb->len; | 1293 | i2400m->rx_size_acc += skb_len; |
1294 | if (skb->len < i2400m->rx_size_min) | 1294 | if (skb_len < i2400m->rx_size_min) |
1295 | i2400m->rx_size_min = skb->len; | 1295 | i2400m->rx_size_min = skb_len; |
1296 | if (skb->len > i2400m->rx_size_max) | 1296 | if (skb_len > i2400m->rx_size_max) |
1297 | i2400m->rx_size_max = skb->len; | 1297 | i2400m->rx_size_max = skb_len; |
1298 | spin_unlock_irqrestore(&i2400m->rx_lock, flags); | 1298 | spin_unlock_irqrestore(&i2400m->rx_lock, flags); |
1299 | error_pl_descr_check: | 1299 | error_pl_descr_check: |
1300 | error_pl_descr_short: | 1300 | error_pl_descr_short: |
1301 | error_msg_hdr_check: | 1301 | error_msg_hdr_check: |
1302 | d_fnend(4, dev, "(i2400m %p skb %p [size %zu]) = %d\n", | 1302 | d_fnend(4, dev, "(i2400m %p skb %p [size %u]) = %d\n", |
1303 | i2400m, skb, skb_len, result); | 1303 | i2400m, skb, skb_len, result); |
1304 | return result; | 1304 | return result; |
1305 | } | 1305 | } |
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c index a105087af96..f9aa1bc0a94 100644 --- a/drivers/net/wireless/adm8211.c +++ b/drivers/net/wireless/adm8211.c | |||
@@ -732,7 +732,7 @@ static int adm8211_rf_set_channel(struct ieee80211_hw *dev, unsigned int chan) | |||
732 | 732 | ||
733 | /* Nothing to do for ADMtek BBP */ | 733 | /* Nothing to do for ADMtek BBP */ |
734 | } else if (priv->bbp_type != ADM8211_TYPE_ADMTEK) | 734 | } else if (priv->bbp_type != ADM8211_TYPE_ADMTEK) |
735 | wiphy_debug(dev->wiphy, "unsupported bbp type %d\n", | 735 | wiphy_debug(dev->wiphy, "unsupported BBP type %d\n", |
736 | priv->bbp_type); | 736 | priv->bbp_type); |
737 | 737 | ||
738 | ADM8211_RESTORE(); | 738 | ADM8211_RESTORE(); |
@@ -1032,7 +1032,7 @@ static int adm8211_hw_init_bbp(struct ieee80211_hw *dev) | |||
1032 | break; | 1032 | break; |
1033 | } | 1033 | } |
1034 | } else | 1034 | } else |
1035 | wiphy_debug(dev->wiphy, "unsupported bbp %d\n", priv->bbp_type); | 1035 | wiphy_debug(dev->wiphy, "unsupported BBP %d\n", priv->bbp_type); |
1036 | 1036 | ||
1037 | ADM8211_CSR_WRITE(SYNRF, 0); | 1037 | ADM8211_CSR_WRITE(SYNRF, 0); |
1038 | 1038 | ||
@@ -1525,7 +1525,7 @@ static int adm8211_start(struct ieee80211_hw *dev) | |||
1525 | retval = request_irq(priv->pdev->irq, adm8211_interrupt, | 1525 | retval = request_irq(priv->pdev->irq, adm8211_interrupt, |
1526 | IRQF_SHARED, "adm8211", dev); | 1526 | IRQF_SHARED, "adm8211", dev); |
1527 | if (retval) { | 1527 | if (retval) { |
1528 | wiphy_err(dev->wiphy, "failed to register irq handler\n"); | 1528 | wiphy_err(dev->wiphy, "failed to register IRQ handler\n"); |
1529 | goto fail; | 1529 | goto fail; |
1530 | } | 1530 | } |
1531 | 1531 | ||
@@ -1902,7 +1902,7 @@ static int __devinit adm8211_probe(struct pci_dev *pdev, | |||
1902 | goto err_free_eeprom; | 1902 | goto err_free_eeprom; |
1903 | } | 1903 | } |
1904 | 1904 | ||
1905 | wiphy_info(dev->wiphy, "hwaddr %pm, rev 0x%02x\n", | 1905 | wiphy_info(dev->wiphy, "hwaddr %pM, Rev 0x%02x\n", |
1906 | dev->wiphy->perm_addr, pdev->revision); | 1906 | dev->wiphy->perm_addr, pdev->revision); |
1907 | 1907 | ||
1908 | return 0; | 1908 | return 0; |
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c index d5140a87f07..1128fa8c9ed 100644 --- a/drivers/net/wireless/at76c50x-usb.c +++ b/drivers/net/wireless/at76c50x-usb.c | |||
@@ -655,7 +655,7 @@ static int at76_get_hw_config(struct at76_priv *priv) | |||
655 | exit: | 655 | exit: |
656 | kfree(hwcfg); | 656 | kfree(hwcfg); |
657 | if (ret < 0) | 657 | if (ret < 0) |
658 | wiphy_err(priv->hw->wiphy, "cannot get hw config (error %d)\n", | 658 | wiphy_err(priv->hw->wiphy, "cannot get HW Config (error %d)\n", |
659 | ret); | 659 | ret); |
660 | 660 | ||
661 | return ret; | 661 | return ret; |
@@ -960,7 +960,7 @@ static void at76_dump_mib_mac_addr(struct at76_priv *priv) | |||
960 | sizeof(struct mib_mac_addr)); | 960 | sizeof(struct mib_mac_addr)); |
961 | if (ret < 0) { | 961 | if (ret < 0) { |
962 | wiphy_err(priv->hw->wiphy, | 962 | wiphy_err(priv->hw->wiphy, |
963 | "at76_get_mib (mac_addr) failed: %d\n", ret); | 963 | "at76_get_mib (MAC_ADDR) failed: %d\n", ret); |
964 | goto exit; | 964 | goto exit; |
965 | } | 965 | } |
966 | 966 | ||
@@ -989,7 +989,7 @@ static void at76_dump_mib_mac_wep(struct at76_priv *priv) | |||
989 | sizeof(struct mib_mac_wep)); | 989 | sizeof(struct mib_mac_wep)); |
990 | if (ret < 0) { | 990 | if (ret < 0) { |
991 | wiphy_err(priv->hw->wiphy, | 991 | wiphy_err(priv->hw->wiphy, |
992 | "at76_get_mib (mac_wep) failed: %d\n", ret); | 992 | "at76_get_mib (MAC_WEP) failed: %d\n", ret); |
993 | goto exit; | 993 | goto exit; |
994 | } | 994 | } |
995 | 995 | ||
@@ -1026,7 +1026,7 @@ static void at76_dump_mib_mac_mgmt(struct at76_priv *priv) | |||
1026 | sizeof(struct mib_mac_mgmt)); | 1026 | sizeof(struct mib_mac_mgmt)); |
1027 | if (ret < 0) { | 1027 | if (ret < 0) { |
1028 | wiphy_err(priv->hw->wiphy, | 1028 | wiphy_err(priv->hw->wiphy, |
1029 | "at76_get_mib (mac_mgmt) failed: %d\n", ret); | 1029 | "at76_get_mib (MAC_MGMT) failed: %d\n", ret); |
1030 | goto exit; | 1030 | goto exit; |
1031 | } | 1031 | } |
1032 | 1032 | ||
@@ -1062,7 +1062,7 @@ static void at76_dump_mib_mac(struct at76_priv *priv) | |||
1062 | ret = at76_get_mib(priv->udev, MIB_MAC, m, sizeof(struct mib_mac)); | 1062 | ret = at76_get_mib(priv->udev, MIB_MAC, m, sizeof(struct mib_mac)); |
1063 | if (ret < 0) { | 1063 | if (ret < 0) { |
1064 | wiphy_err(priv->hw->wiphy, | 1064 | wiphy_err(priv->hw->wiphy, |
1065 | "at76_get_mib (mac) failed: %d\n", ret); | 1065 | "at76_get_mib (MAC) failed: %d\n", ret); |
1066 | goto exit; | 1066 | goto exit; |
1067 | } | 1067 | } |
1068 | 1068 | ||
@@ -1099,7 +1099,7 @@ static void at76_dump_mib_phy(struct at76_priv *priv) | |||
1099 | ret = at76_get_mib(priv->udev, MIB_PHY, m, sizeof(struct mib_phy)); | 1099 | ret = at76_get_mib(priv->udev, MIB_PHY, m, sizeof(struct mib_phy)); |
1100 | if (ret < 0) { | 1100 | if (ret < 0) { |
1101 | wiphy_err(priv->hw->wiphy, | 1101 | wiphy_err(priv->hw->wiphy, |
1102 | "at76_get_mib (phy) failed: %d\n", ret); | 1102 | "at76_get_mib (PHY) failed: %d\n", ret); |
1103 | goto exit; | 1103 | goto exit; |
1104 | } | 1104 | } |
1105 | 1105 | ||
@@ -1132,7 +1132,7 @@ static void at76_dump_mib_local(struct at76_priv *priv) | |||
1132 | ret = at76_get_mib(priv->udev, MIB_LOCAL, m, sizeof(struct mib_local)); | 1132 | ret = at76_get_mib(priv->udev, MIB_LOCAL, m, sizeof(struct mib_local)); |
1133 | if (ret < 0) { | 1133 | if (ret < 0) { |
1134 | wiphy_err(priv->hw->wiphy, | 1134 | wiphy_err(priv->hw->wiphy, |
1135 | "at76_get_mib (local) failed: %d\n", ret); | 1135 | "at76_get_mib (LOCAL) failed: %d\n", ret); |
1136 | goto exit; | 1136 | goto exit; |
1137 | } | 1137 | } |
1138 | 1138 | ||
@@ -1158,7 +1158,7 @@ static void at76_dump_mib_mdomain(struct at76_priv *priv) | |||
1158 | sizeof(struct mib_mdomain)); | 1158 | sizeof(struct mib_mdomain)); |
1159 | if (ret < 0) { | 1159 | if (ret < 0) { |
1160 | wiphy_err(priv->hw->wiphy, | 1160 | wiphy_err(priv->hw->wiphy, |
1161 | "at76_get_mib (mdomain) failed: %d\n", ret); | 1161 | "at76_get_mib (MDOMAIN) failed: %d\n", ret); |
1162 | goto exit; | 1162 | goto exit; |
1163 | } | 1163 | } |
1164 | 1164 | ||
@@ -1229,7 +1229,7 @@ static int at76_submit_rx_urb(struct at76_priv *priv) | |||
1229 | struct sk_buff *skb = priv->rx_skb; | 1229 | struct sk_buff *skb = priv->rx_skb; |
1230 | 1230 | ||
1231 | if (!priv->rx_urb) { | 1231 | if (!priv->rx_urb) { |
1232 | wiphy_err(priv->hw->wiphy, "%s: priv->rx_urb is null\n", | 1232 | wiphy_err(priv->hw->wiphy, "%s: priv->rx_urb is NULL\n", |
1233 | __func__); | 1233 | __func__); |
1234 | return -EFAULT; | 1234 | return -EFAULT; |
1235 | } | 1235 | } |
@@ -1792,7 +1792,7 @@ static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1792 | wiphy_err(priv->hw->wiphy, "error in tx submit urb: %d\n", ret); | 1792 | wiphy_err(priv->hw->wiphy, "error in tx submit urb: %d\n", ret); |
1793 | if (ret == -EINVAL) | 1793 | if (ret == -EINVAL) |
1794 | wiphy_err(priv->hw->wiphy, | 1794 | wiphy_err(priv->hw->wiphy, |
1795 | "-einval: tx urb %p hcpriv %p complete %p\n", | 1795 | "-EINVAL: tx urb %p hcpriv %p complete %p\n", |
1796 | priv->tx_urb, | 1796 | priv->tx_urb, |
1797 | priv->tx_urb->hcpriv, priv->tx_urb->complete); | 1797 | priv->tx_urb->hcpriv, priv->tx_urb->complete); |
1798 | } | 1798 | } |
@@ -2310,7 +2310,7 @@ static int at76_init_new_device(struct at76_priv *priv, | |||
2310 | 2310 | ||
2311 | priv->mac80211_registered = 1; | 2311 | priv->mac80211_registered = 1; |
2312 | 2312 | ||
2313 | wiphy_info(priv->hw->wiphy, "usb %s, mac %pm, firmware %d.%d.%d-%d\n", | 2313 | wiphy_info(priv->hw->wiphy, "USB %s, MAC %pM, firmware %d.%d.%d-%d\n", |
2314 | dev_name(&interface->dev), priv->mac_addr, | 2314 | dev_name(&interface->dev), priv->mac_addr, |
2315 | priv->fw_version.major, priv->fw_version.minor, | 2315 | priv->fw_version.major, priv->fw_version.minor, |
2316 | priv->fw_version.patch, priv->fw_version.build); | 2316 | priv->fw_version.patch, priv->fw_version.build); |
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c index c67b05f3bcb..debfb0fbc7c 100644 --- a/drivers/net/wireless/ath/ar9170/main.c +++ b/drivers/net/wireless/ath/ar9170/main.c | |||
@@ -245,7 +245,7 @@ static void __ar9170_dump_txstats(struct ar9170 *ar) | |||
245 | { | 245 | { |
246 | int i; | 246 | int i; |
247 | 247 | ||
248 | wiphy_debug(ar->hw->wiphy, "qos queue stats\n"); | 248 | wiphy_debug(ar->hw->wiphy, "QoS queue stats\n"); |
249 | 249 | ||
250 | for (i = 0; i < __AR9170_NUM_TXQ; i++) | 250 | for (i = 0; i < __AR9170_NUM_TXQ; i++) |
251 | wiphy_debug(ar->hw->wiphy, | 251 | wiphy_debug(ar->hw->wiphy, |
@@ -387,7 +387,7 @@ static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar, | |||
387 | if (mac && compare_ether_addr(ieee80211_get_DA(hdr), mac)) { | 387 | if (mac && compare_ether_addr(ieee80211_get_DA(hdr), mac)) { |
388 | #ifdef AR9170_QUEUE_DEBUG | 388 | #ifdef AR9170_QUEUE_DEBUG |
389 | wiphy_debug(ar->hw->wiphy, | 389 | wiphy_debug(ar->hw->wiphy, |
390 | "skip frame => da %pm != %pm\n", | 390 | "skip frame => DA %pM != %pM\n", |
391 | mac, ieee80211_get_DA(hdr)); | 391 | mac, ieee80211_get_DA(hdr)); |
392 | ar9170_print_txheader(ar, skb); | 392 | ar9170_print_txheader(ar, skb); |
393 | #endif /* AR9170_QUEUE_DEBUG */ | 393 | #endif /* AR9170_QUEUE_DEBUG */ |
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 373dcfec689..d77ce9906b6 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -1327,6 +1327,10 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, | |||
1327 | PCI_DMA_TODEVICE); | 1327 | PCI_DMA_TODEVICE); |
1328 | 1328 | ||
1329 | rate = ieee80211_get_tx_rate(sc->hw, info); | 1329 | rate = ieee80211_get_tx_rate(sc->hw, info); |
1330 | if (!rate) { | ||
1331 | ret = -EINVAL; | ||
1332 | goto err_unmap; | ||
1333 | } | ||
1330 | 1334 | ||
1331 | if (info->flags & IEEE80211_TX_CTL_NO_ACK) | 1335 | if (info->flags & IEEE80211_TX_CTL_NO_ACK) |
1332 | flags |= AR5K_TXDESC_NOACK; | 1336 | flags |= AR5K_TXDESC_NOACK; |
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index cc648b6ae31..a3d95cca8f0 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c | |||
@@ -543,7 +543,7 @@ static u8 ath9k_hw_chan_2_clockrate_mhz(struct ath_hw *ah) | |||
543 | if (conf_is_ht40(conf)) | 543 | if (conf_is_ht40(conf)) |
544 | return clockrate * 2; | 544 | return clockrate * 2; |
545 | 545 | ||
546 | return clockrate * 2; | 546 | return clockrate; |
547 | } | 547 | } |
548 | 548 | ||
549 | static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah) | 549 | static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah) |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index b883b174385..057fb69ddf7 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | |||
@@ -797,7 +797,7 @@ static bool ar9300_uncompress_block(struct ath_hw *ah, | |||
797 | length = block[it+1]; | 797 | length = block[it+1]; |
798 | length &= 0xff; | 798 | length &= 0xff; |
799 | 799 | ||
800 | if (length > 0 && spot >= 0 && spot+length < mdataSize) { | 800 | if (length > 0 && spot >= 0 && spot+length <= mdataSize) { |
801 | ath_print(common, ATH_DBG_EEPROM, | 801 | ath_print(common, ATH_DBG_EEPROM, |
802 | "Restore at %d: spot=%d " | 802 | "Restore at %d: spot=%d " |
803 | "offset=%d length=%d\n", | 803 | "offset=%d length=%d\n", |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index 7f48df1e290..0b09db0f8e7 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h | |||
@@ -62,7 +62,7 @@ | |||
62 | 62 | ||
63 | #define SD_NO_CTL 0xE0 | 63 | #define SD_NO_CTL 0xE0 |
64 | #define NO_CTL 0xff | 64 | #define NO_CTL 0xff |
65 | #define CTL_MODE_M 7 | 65 | #define CTL_MODE_M 0xf |
66 | #define CTL_11A 0 | 66 | #define CTL_11A 0 |
67 | #define CTL_11B 1 | 67 | #define CTL_11B 1 |
68 | #define CTL_11G 2 | 68 | #define CTL_11G 2 |
diff --git a/drivers/net/wireless/ath/regd.h b/drivers/net/wireless/ath/regd.h index a1c39526161..345dd9721b4 100644 --- a/drivers/net/wireless/ath/regd.h +++ b/drivers/net/wireless/ath/regd.h | |||
@@ -31,7 +31,6 @@ enum ctl_group { | |||
31 | #define NO_CTL 0xff | 31 | #define NO_CTL 0xff |
32 | #define SD_NO_CTL 0xE0 | 32 | #define SD_NO_CTL 0xE0 |
33 | #define NO_CTL 0xff | 33 | #define NO_CTL 0xff |
34 | #define CTL_MODE_M 7 | ||
35 | #define CTL_11A 0 | 34 | #define CTL_11A 0 |
36 | #define CTL_11B 1 | 35 | #define CTL_11B 1 |
37 | #define CTL_11G 2 | 36 | #define CTL_11G 2 |
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index 1189dbb6e2a..996e9d7d758 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c | |||
@@ -2723,14 +2723,6 @@ static void __ipw2100_rx_process(struct ipw2100_priv *priv) | |||
2723 | 2723 | ||
2724 | packet = &priv->rx_buffers[i]; | 2724 | packet = &priv->rx_buffers[i]; |
2725 | 2725 | ||
2726 | /* Sync the DMA for the STATUS buffer so CPU is sure to get | ||
2727 | * the correct values */ | ||
2728 | pci_dma_sync_single_for_cpu(priv->pci_dev, | ||
2729 | sq->nic + | ||
2730 | sizeof(struct ipw2100_status) * i, | ||
2731 | sizeof(struct ipw2100_status), | ||
2732 | PCI_DMA_FROMDEVICE); | ||
2733 | |||
2734 | /* Sync the DMA for the RX buffer so CPU is sure to get | 2726 | /* Sync the DMA for the RX buffer so CPU is sure to get |
2735 | * the correct values */ | 2727 | * the correct values */ |
2736 | pci_dma_sync_single_for_cpu(priv->pci_dev, packet->dma_addr, | 2728 | pci_dma_sync_single_for_cpu(priv->pci_dev, packet->dma_addr, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index fec02621232..0b779a41a14 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c | |||
@@ -265,7 +265,7 @@ struct iwl_cfg iwl1000_bgn_cfg = { | |||
265 | .support_ct_kill_exit = true, | 265 | .support_ct_kill_exit = true, |
266 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, | 266 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, |
267 | .chain_noise_scale = 1000, | 267 | .chain_noise_scale = 1000, |
268 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 268 | .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, |
269 | .max_event_log_size = 128, | 269 | .max_event_log_size = 128, |
270 | .ucode_tracing = true, | 270 | .ucode_tracing = true, |
271 | .sensitivity_calib_by_driver = true, | 271 | .sensitivity_calib_by_driver = true, |
@@ -297,7 +297,7 @@ struct iwl_cfg iwl1000_bg_cfg = { | |||
297 | .support_ct_kill_exit = true, | 297 | .support_ct_kill_exit = true, |
298 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, | 298 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, |
299 | .chain_noise_scale = 1000, | 299 | .chain_noise_scale = 1000, |
300 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 300 | .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, |
301 | .max_event_log_size = 128, | 301 | .max_event_log_size = 128, |
302 | .ucode_tracing = true, | 302 | .ucode_tracing = true, |
303 | .sensitivity_calib_by_driver = true, | 303 | .sensitivity_calib_by_driver = true, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 6950a783913..8ccfcd08218 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
@@ -2731,7 +2731,7 @@ static struct iwl_cfg iwl3945_bg_cfg = { | |||
2731 | .led_compensation = 64, | 2731 | .led_compensation = 64, |
2732 | .broken_powersave = true, | 2732 | .broken_powersave = true, |
2733 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, | 2733 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, |
2734 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 2734 | .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, |
2735 | .max_event_log_size = 512, | 2735 | .max_event_log_size = 512, |
2736 | .tx_power_by_driver = true, | 2736 | .tx_power_by_driver = true, |
2737 | }; | 2737 | }; |
@@ -2752,7 +2752,7 @@ static struct iwl_cfg iwl3945_abg_cfg = { | |||
2752 | .led_compensation = 64, | 2752 | .led_compensation = 64, |
2753 | .broken_powersave = true, | 2753 | .broken_powersave = true, |
2754 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, | 2754 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, |
2755 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 2755 | .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, |
2756 | .max_event_log_size = 512, | 2756 | .max_event_log_size = 512, |
2757 | .tx_power_by_driver = true, | 2757 | .tx_power_by_driver = true, |
2758 | }; | 2758 | }; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index d6da356608f..d92b7290923 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -2322,7 +2322,7 @@ struct iwl_cfg iwl4965_agn_cfg = { | |||
2322 | .led_compensation = 61, | 2322 | .led_compensation = 61, |
2323 | .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS, | 2323 | .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS, |
2324 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 2324 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
2325 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 2325 | .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, |
2326 | .temperature_kelvin = true, | 2326 | .temperature_kelvin = true, |
2327 | .max_event_log_size = 512, | 2327 | .max_event_log_size = 512, |
2328 | .tx_power_by_driver = true, | 2328 | .tx_power_by_driver = true, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index aacf3770f07..48bdcd8d2e9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -510,7 +510,7 @@ struct iwl_cfg iwl5300_agn_cfg = { | |||
510 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 510 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
511 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, | 511 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, |
512 | .chain_noise_scale = 1000, | 512 | .chain_noise_scale = 1000, |
513 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 513 | .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, |
514 | .max_event_log_size = 512, | 514 | .max_event_log_size = 512, |
515 | .ucode_tracing = true, | 515 | .ucode_tracing = true, |
516 | .sensitivity_calib_by_driver = true, | 516 | .sensitivity_calib_by_driver = true, |
@@ -541,7 +541,7 @@ struct iwl_cfg iwl5100_bgn_cfg = { | |||
541 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 541 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
542 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, | 542 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, |
543 | .chain_noise_scale = 1000, | 543 | .chain_noise_scale = 1000, |
544 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 544 | .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, |
545 | .max_event_log_size = 512, | 545 | .max_event_log_size = 512, |
546 | .ucode_tracing = true, | 546 | .ucode_tracing = true, |
547 | .sensitivity_calib_by_driver = true, | 547 | .sensitivity_calib_by_driver = true, |
@@ -570,7 +570,7 @@ struct iwl_cfg iwl5100_abg_cfg = { | |||
570 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 570 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
571 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, | 571 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, |
572 | .chain_noise_scale = 1000, | 572 | .chain_noise_scale = 1000, |
573 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 573 | .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, |
574 | .max_event_log_size = 512, | 574 | .max_event_log_size = 512, |
575 | .ucode_tracing = true, | 575 | .ucode_tracing = true, |
576 | .sensitivity_calib_by_driver = true, | 576 | .sensitivity_calib_by_driver = true, |
@@ -601,7 +601,7 @@ struct iwl_cfg iwl5100_agn_cfg = { | |||
601 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 601 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
602 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, | 602 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, |
603 | .chain_noise_scale = 1000, | 603 | .chain_noise_scale = 1000, |
604 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 604 | .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, |
605 | .max_event_log_size = 512, | 605 | .max_event_log_size = 512, |
606 | .ucode_tracing = true, | 606 | .ucode_tracing = true, |
607 | .sensitivity_calib_by_driver = true, | 607 | .sensitivity_calib_by_driver = true, |
@@ -632,7 +632,7 @@ struct iwl_cfg iwl5350_agn_cfg = { | |||
632 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 632 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
633 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, | 633 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, |
634 | .chain_noise_scale = 1000, | 634 | .chain_noise_scale = 1000, |
635 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 635 | .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, |
636 | .max_event_log_size = 512, | 636 | .max_event_log_size = 512, |
637 | .ucode_tracing = true, | 637 | .ucode_tracing = true, |
638 | .sensitivity_calib_by_driver = true, | 638 | .sensitivity_calib_by_driver = true, |
@@ -663,7 +663,7 @@ struct iwl_cfg iwl5150_agn_cfg = { | |||
663 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 663 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
664 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, | 664 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, |
665 | .chain_noise_scale = 1000, | 665 | .chain_noise_scale = 1000, |
666 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 666 | .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, |
667 | .max_event_log_size = 512, | 667 | .max_event_log_size = 512, |
668 | .ucode_tracing = true, | 668 | .ucode_tracing = true, |
669 | .sensitivity_calib_by_driver = true, | 669 | .sensitivity_calib_by_driver = true, |
@@ -693,7 +693,7 @@ struct iwl_cfg iwl5150_abg_cfg = { | |||
693 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 693 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
694 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, | 694 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, |
695 | .chain_noise_scale = 1000, | 695 | .chain_noise_scale = 1000, |
696 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 696 | .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, |
697 | .max_event_log_size = 512, | 697 | .max_event_log_size = 512, |
698 | .ucode_tracing = true, | 698 | .ucode_tracing = true, |
699 | .sensitivity_calib_by_driver = true, | 699 | .sensitivity_calib_by_driver = true, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index af4fd50f340..cee06b968de 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c | |||
@@ -388,7 +388,7 @@ struct iwl_cfg iwl6000g2a_2agn_cfg = { | |||
388 | .support_ct_kill_exit = true, | 388 | .support_ct_kill_exit = true, |
389 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 389 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
390 | .chain_noise_scale = 1000, | 390 | .chain_noise_scale = 1000, |
391 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 391 | .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, |
392 | .max_event_log_size = 512, | 392 | .max_event_log_size = 512, |
393 | .ucode_tracing = true, | 393 | .ucode_tracing = true, |
394 | .sensitivity_calib_by_driver = true, | 394 | .sensitivity_calib_by_driver = true, |
@@ -424,7 +424,7 @@ struct iwl_cfg iwl6000g2a_2abg_cfg = { | |||
424 | .support_ct_kill_exit = true, | 424 | .support_ct_kill_exit = true, |
425 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 425 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
426 | .chain_noise_scale = 1000, | 426 | .chain_noise_scale = 1000, |
427 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 427 | .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, |
428 | .max_event_log_size = 512, | 428 | .max_event_log_size = 512, |
429 | .sensitivity_calib_by_driver = true, | 429 | .sensitivity_calib_by_driver = true, |
430 | .chain_noise_calib_by_driver = true, | 430 | .chain_noise_calib_by_driver = true, |
@@ -459,7 +459,7 @@ struct iwl_cfg iwl6000g2a_2bg_cfg = { | |||
459 | .support_ct_kill_exit = true, | 459 | .support_ct_kill_exit = true, |
460 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 460 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
461 | .chain_noise_scale = 1000, | 461 | .chain_noise_scale = 1000, |
462 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 462 | .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, |
463 | .max_event_log_size = 512, | 463 | .max_event_log_size = 512, |
464 | .sensitivity_calib_by_driver = true, | 464 | .sensitivity_calib_by_driver = true, |
465 | .chain_noise_calib_by_driver = true, | 465 | .chain_noise_calib_by_driver = true, |
@@ -496,7 +496,7 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = { | |||
496 | .support_ct_kill_exit = true, | 496 | .support_ct_kill_exit = true, |
497 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 497 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
498 | .chain_noise_scale = 1000, | 498 | .chain_noise_scale = 1000, |
499 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 499 | .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, |
500 | .max_event_log_size = 512, | 500 | .max_event_log_size = 512, |
501 | .sensitivity_calib_by_driver = true, | 501 | .sensitivity_calib_by_driver = true, |
502 | .chain_noise_calib_by_driver = true, | 502 | .chain_noise_calib_by_driver = true, |
@@ -532,7 +532,7 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = { | |||
532 | .support_ct_kill_exit = true, | 532 | .support_ct_kill_exit = true, |
533 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 533 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
534 | .chain_noise_scale = 1000, | 534 | .chain_noise_scale = 1000, |
535 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 535 | .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, |
536 | .max_event_log_size = 512, | 536 | .max_event_log_size = 512, |
537 | .sensitivity_calib_by_driver = true, | 537 | .sensitivity_calib_by_driver = true, |
538 | .chain_noise_calib_by_driver = true, | 538 | .chain_noise_calib_by_driver = true, |
@@ -570,7 +570,7 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = { | |||
570 | .support_ct_kill_exit = true, | 570 | .support_ct_kill_exit = true, |
571 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 571 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
572 | .chain_noise_scale = 1000, | 572 | .chain_noise_scale = 1000, |
573 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 573 | .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, |
574 | .max_event_log_size = 512, | 574 | .max_event_log_size = 512, |
575 | .sensitivity_calib_by_driver = true, | 575 | .sensitivity_calib_by_driver = true, |
576 | .chain_noise_calib_by_driver = true, | 576 | .chain_noise_calib_by_driver = true, |
@@ -606,7 +606,7 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = { | |||
606 | .support_ct_kill_exit = true, | 606 | .support_ct_kill_exit = true, |
607 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 607 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
608 | .chain_noise_scale = 1000, | 608 | .chain_noise_scale = 1000, |
609 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 609 | .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, |
610 | .max_event_log_size = 512, | 610 | .max_event_log_size = 512, |
611 | .sensitivity_calib_by_driver = true, | 611 | .sensitivity_calib_by_driver = true, |
612 | .chain_noise_calib_by_driver = true, | 612 | .chain_noise_calib_by_driver = true, |
@@ -644,7 +644,7 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = { | |||
644 | .support_ct_kill_exit = true, | 644 | .support_ct_kill_exit = true, |
645 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 645 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
646 | .chain_noise_scale = 1000, | 646 | .chain_noise_scale = 1000, |
647 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 647 | .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, |
648 | .max_event_log_size = 512, | 648 | .max_event_log_size = 512, |
649 | .sensitivity_calib_by_driver = true, | 649 | .sensitivity_calib_by_driver = true, |
650 | .chain_noise_calib_by_driver = true, | 650 | .chain_noise_calib_by_driver = true, |
@@ -680,7 +680,7 @@ struct iwl_cfg iwl6000g2b_bg_cfg = { | |||
680 | .support_ct_kill_exit = true, | 680 | .support_ct_kill_exit = true, |
681 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 681 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
682 | .chain_noise_scale = 1000, | 682 | .chain_noise_scale = 1000, |
683 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 683 | .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, |
684 | .max_event_log_size = 512, | 684 | .max_event_log_size = 512, |
685 | .sensitivity_calib_by_driver = true, | 685 | .sensitivity_calib_by_driver = true, |
686 | .chain_noise_calib_by_driver = true, | 686 | .chain_noise_calib_by_driver = true, |
@@ -721,7 +721,7 @@ struct iwl_cfg iwl6000i_2agn_cfg = { | |||
721 | .support_ct_kill_exit = true, | 721 | .support_ct_kill_exit = true, |
722 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 722 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
723 | .chain_noise_scale = 1000, | 723 | .chain_noise_scale = 1000, |
724 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 724 | .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, |
725 | .max_event_log_size = 1024, | 725 | .max_event_log_size = 1024, |
726 | .ucode_tracing = true, | 726 | .ucode_tracing = true, |
727 | .sensitivity_calib_by_driver = true, | 727 | .sensitivity_calib_by_driver = true, |
@@ -756,7 +756,7 @@ struct iwl_cfg iwl6000i_2abg_cfg = { | |||
756 | .support_ct_kill_exit = true, | 756 | .support_ct_kill_exit = true, |
757 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 757 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
758 | .chain_noise_scale = 1000, | 758 | .chain_noise_scale = 1000, |
759 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 759 | .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, |
760 | .max_event_log_size = 1024, | 760 | .max_event_log_size = 1024, |
761 | .ucode_tracing = true, | 761 | .ucode_tracing = true, |
762 | .sensitivity_calib_by_driver = true, | 762 | .sensitivity_calib_by_driver = true, |
@@ -791,7 +791,7 @@ struct iwl_cfg iwl6000i_2bg_cfg = { | |||
791 | .support_ct_kill_exit = true, | 791 | .support_ct_kill_exit = true, |
792 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 792 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
793 | .chain_noise_scale = 1000, | 793 | .chain_noise_scale = 1000, |
794 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 794 | .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, |
795 | .max_event_log_size = 1024, | 795 | .max_event_log_size = 1024, |
796 | .ucode_tracing = true, | 796 | .ucode_tracing = true, |
797 | .sensitivity_calib_by_driver = true, | 797 | .sensitivity_calib_by_driver = true, |
@@ -828,7 +828,7 @@ struct iwl_cfg iwl6050_2agn_cfg = { | |||
828 | .support_ct_kill_exit = true, | 828 | .support_ct_kill_exit = true, |
829 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 829 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
830 | .chain_noise_scale = 1500, | 830 | .chain_noise_scale = 1500, |
831 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 831 | .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, |
832 | .max_event_log_size = 1024, | 832 | .max_event_log_size = 1024, |
833 | .ucode_tracing = true, | 833 | .ucode_tracing = true, |
834 | .sensitivity_calib_by_driver = true, | 834 | .sensitivity_calib_by_driver = true, |
@@ -866,7 +866,7 @@ struct iwl_cfg iwl6050g2_bgn_cfg = { | |||
866 | .support_ct_kill_exit = true, | 866 | .support_ct_kill_exit = true, |
867 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 867 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
868 | .chain_noise_scale = 1500, | 868 | .chain_noise_scale = 1500, |
869 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 869 | .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, |
870 | .max_event_log_size = 1024, | 870 | .max_event_log_size = 1024, |
871 | .ucode_tracing = true, | 871 | .ucode_tracing = true, |
872 | .sensitivity_calib_by_driver = true, | 872 | .sensitivity_calib_by_driver = true, |
@@ -902,7 +902,7 @@ struct iwl_cfg iwl6050_2abg_cfg = { | |||
902 | .support_ct_kill_exit = true, | 902 | .support_ct_kill_exit = true, |
903 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 903 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
904 | .chain_noise_scale = 1500, | 904 | .chain_noise_scale = 1500, |
905 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 905 | .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, |
906 | .max_event_log_size = 1024, | 906 | .max_event_log_size = 1024, |
907 | .ucode_tracing = true, | 907 | .ucode_tracing = true, |
908 | .sensitivity_calib_by_driver = true, | 908 | .sensitivity_calib_by_driver = true, |
@@ -940,7 +940,7 @@ struct iwl_cfg iwl6000_3agn_cfg = { | |||
940 | .support_ct_kill_exit = true, | 940 | .support_ct_kill_exit = true, |
941 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 941 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
942 | .chain_noise_scale = 1000, | 942 | .chain_noise_scale = 1000, |
943 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 943 | .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, |
944 | .max_event_log_size = 1024, | 944 | .max_event_log_size = 1024, |
945 | .ucode_tracing = true, | 945 | .ucode_tracing = true, |
946 | .sensitivity_calib_by_driver = true, | 946 | .sensitivity_calib_by_driver = true, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 9dd9e64c2b0..8fd00a6e512 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c | |||
@@ -1411,7 +1411,7 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
1411 | clear_bit(STATUS_SCAN_HW, &priv->status); | 1411 | clear_bit(STATUS_SCAN_HW, &priv->status); |
1412 | clear_bit(STATUS_SCANNING, &priv->status); | 1412 | clear_bit(STATUS_SCANNING, &priv->status); |
1413 | /* inform mac80211 scan aborted */ | 1413 | /* inform mac80211 scan aborted */ |
1414 | queue_work(priv->workqueue, &priv->scan_completed); | 1414 | queue_work(priv->workqueue, &priv->abort_scan); |
1415 | } | 1415 | } |
1416 | 1416 | ||
1417 | int iwlagn_manage_ibss_station(struct iwl_priv *priv, | 1417 | int iwlagn_manage_ibss_station(struct iwl_priv *priv, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index c1882fd8345..10d7b9b7f06 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -3667,6 +3667,49 @@ out_exit: | |||
3667 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 3667 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
3668 | } | 3668 | } |
3669 | 3669 | ||
3670 | static void iwlagn_configure_filter(struct ieee80211_hw *hw, | ||
3671 | unsigned int changed_flags, | ||
3672 | unsigned int *total_flags, | ||
3673 | u64 multicast) | ||
3674 | { | ||
3675 | struct iwl_priv *priv = hw->priv; | ||
3676 | __le32 filter_or = 0, filter_nand = 0; | ||
3677 | |||
3678 | #define CHK(test, flag) do { \ | ||
3679 | if (*total_flags & (test)) \ | ||
3680 | filter_or |= (flag); \ | ||
3681 | else \ | ||
3682 | filter_nand |= (flag); \ | ||
3683 | } while (0) | ||
3684 | |||
3685 | IWL_DEBUG_MAC80211(priv, "Enter: changed: 0x%x, total: 0x%x\n", | ||
3686 | changed_flags, *total_flags); | ||
3687 | |||
3688 | CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK); | ||
3689 | CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK); | ||
3690 | CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK); | ||
3691 | |||
3692 | #undef CHK | ||
3693 | |||
3694 | mutex_lock(&priv->mutex); | ||
3695 | |||
3696 | priv->staging_rxon.filter_flags &= ~filter_nand; | ||
3697 | priv->staging_rxon.filter_flags |= filter_or; | ||
3698 | |||
3699 | iwlcore_commit_rxon(priv); | ||
3700 | |||
3701 | mutex_unlock(&priv->mutex); | ||
3702 | |||
3703 | /* | ||
3704 | * Receiving all multicast frames is always enabled by the | ||
3705 | * default flags setup in iwl_connection_init_rx_config() | ||
3706 | * since we currently do not support programming multicast | ||
3707 | * filters into the device. | ||
3708 | */ | ||
3709 | *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS | | ||
3710 | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; | ||
3711 | } | ||
3712 | |||
3670 | static void iwl_mac_flush(struct ieee80211_hw *hw, bool drop) | 3713 | static void iwl_mac_flush(struct ieee80211_hw *hw, bool drop) |
3671 | { | 3714 | { |
3672 | struct iwl_priv *priv = hw->priv; | 3715 | struct iwl_priv *priv = hw->priv; |
@@ -3867,7 +3910,7 @@ static struct ieee80211_ops iwl_hw_ops = { | |||
3867 | .add_interface = iwl_mac_add_interface, | 3910 | .add_interface = iwl_mac_add_interface, |
3868 | .remove_interface = iwl_mac_remove_interface, | 3911 | .remove_interface = iwl_mac_remove_interface, |
3869 | .config = iwl_mac_config, | 3912 | .config = iwl_mac_config, |
3870 | .configure_filter = iwl_configure_filter, | 3913 | .configure_filter = iwlagn_configure_filter, |
3871 | .set_key = iwl_mac_set_key, | 3914 | .set_key = iwl_mac_set_key, |
3872 | .update_tkip_key = iwl_mac_update_tkip_key, | 3915 | .update_tkip_key = iwl_mac_update_tkip_key, |
3873 | .conf_tx = iwl_mac_conf_tx, | 3916 | .conf_tx = iwl_mac_conf_tx, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 2c03c6e20a7..e23c4060a0f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -1328,51 +1328,6 @@ out: | |||
1328 | EXPORT_SYMBOL(iwl_apm_init); | 1328 | EXPORT_SYMBOL(iwl_apm_init); |
1329 | 1329 | ||
1330 | 1330 | ||
1331 | |||
1332 | void iwl_configure_filter(struct ieee80211_hw *hw, | ||
1333 | unsigned int changed_flags, | ||
1334 | unsigned int *total_flags, | ||
1335 | u64 multicast) | ||
1336 | { | ||
1337 | struct iwl_priv *priv = hw->priv; | ||
1338 | __le32 filter_or = 0, filter_nand = 0; | ||
1339 | |||
1340 | #define CHK(test, flag) do { \ | ||
1341 | if (*total_flags & (test)) \ | ||
1342 | filter_or |= (flag); \ | ||
1343 | else \ | ||
1344 | filter_nand |= (flag); \ | ||
1345 | } while (0) | ||
1346 | |||
1347 | IWL_DEBUG_MAC80211(priv, "Enter: changed: 0x%x, total: 0x%x\n", | ||
1348 | changed_flags, *total_flags); | ||
1349 | |||
1350 | CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK); | ||
1351 | CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK); | ||
1352 | CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK); | ||
1353 | |||
1354 | #undef CHK | ||
1355 | |||
1356 | mutex_lock(&priv->mutex); | ||
1357 | |||
1358 | priv->staging_rxon.filter_flags &= ~filter_nand; | ||
1359 | priv->staging_rxon.filter_flags |= filter_or; | ||
1360 | |||
1361 | iwlcore_commit_rxon(priv); | ||
1362 | |||
1363 | mutex_unlock(&priv->mutex); | ||
1364 | |||
1365 | /* | ||
1366 | * Receiving all multicast frames is always enabled by the | ||
1367 | * default flags setup in iwl_connection_init_rx_config() | ||
1368 | * since we currently do not support programming multicast | ||
1369 | * filters into the device. | ||
1370 | */ | ||
1371 | *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS | | ||
1372 | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; | ||
1373 | } | ||
1374 | EXPORT_SYMBOL(iwl_configure_filter); | ||
1375 | |||
1376 | int iwl_set_hw_params(struct iwl_priv *priv) | 1331 | int iwl_set_hw_params(struct iwl_priv *priv) |
1377 | { | 1332 | { |
1378 | priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; | 1333 | priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; |
@@ -2658,6 +2613,11 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external) | |||
2658 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 2613 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
2659 | return -EINVAL; | 2614 | return -EINVAL; |
2660 | 2615 | ||
2616 | if (test_bit(STATUS_SCANNING, &priv->status)) { | ||
2617 | IWL_DEBUG_INFO(priv, "scan in progress.\n"); | ||
2618 | return -EINVAL; | ||
2619 | } | ||
2620 | |||
2661 | if (mode >= IWL_MAX_FORCE_RESET) { | 2621 | if (mode >= IWL_MAX_FORCE_RESET) { |
2662 | IWL_DEBUG_INFO(priv, "invalid reset request.\n"); | 2622 | IWL_DEBUG_INFO(priv, "invalid reset request.\n"); |
2663 | return -EINVAL; | 2623 | return -EINVAL; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 4a71dfb10a1..5e6ee3da6bb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -372,9 +372,6 @@ int iwl_set_decrypted_flag(struct iwl_priv *priv, | |||
372 | u32 decrypt_res, | 372 | u32 decrypt_res, |
373 | struct ieee80211_rx_status *stats); | 373 | struct ieee80211_rx_status *stats); |
374 | void iwl_irq_handle_error(struct iwl_priv *priv); | 374 | void iwl_irq_handle_error(struct iwl_priv *priv); |
375 | void iwl_configure_filter(struct ieee80211_hw *hw, | ||
376 | unsigned int changed_flags, | ||
377 | unsigned int *total_flags, u64 multicast); | ||
378 | int iwl_set_hw_params(struct iwl_priv *priv); | 375 | int iwl_set_hw_params(struct iwl_priv *priv); |
379 | void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif); | 376 | void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif); |
380 | void iwl_bss_info_changed(struct ieee80211_hw *hw, | 377 | void iwl_bss_info_changed(struct ieee80211_hw *hw, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index f35bcad56e3..2e97cd2fa98 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -1049,7 +1049,8 @@ struct iwl_event_log { | |||
1049 | #define IWL_DELAY_NEXT_FORCE_FW_RELOAD (HZ*5) | 1049 | #define IWL_DELAY_NEXT_FORCE_FW_RELOAD (HZ*5) |
1050 | 1050 | ||
1051 | /* timer constants use to monitor and recover stuck tx queues in mSecs */ | 1051 | /* timer constants use to monitor and recover stuck tx queues in mSecs */ |
1052 | #define IWL_MONITORING_PERIOD (1000) | 1052 | #define IWL_DEF_MONITORING_PERIOD (1000) |
1053 | #define IWL_LONG_MONITORING_PERIOD (5000) | ||
1053 | #define IWL_ONE_HUNDRED_MSECS (100) | 1054 | #define IWL_ONE_HUNDRED_MSECS (100) |
1054 | #define IWL_SIXTY_SECS (60000) | 1055 | #define IWL_SIXTY_SECS (60000) |
1055 | 1056 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 70c4b8fba0e..d31661c1ce7 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -3018,7 +3018,7 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
3018 | clear_bit(STATUS_SCANNING, &priv->status); | 3018 | clear_bit(STATUS_SCANNING, &priv->status); |
3019 | 3019 | ||
3020 | /* inform mac80211 scan aborted */ | 3020 | /* inform mac80211 scan aborted */ |
3021 | queue_work(priv->workqueue, &priv->scan_completed); | 3021 | queue_work(priv->workqueue, &priv->abort_scan); |
3022 | } | 3022 | } |
3023 | 3023 | ||
3024 | static void iwl3945_bg_restart(struct work_struct *data) | 3024 | static void iwl3945_bg_restart(struct work_struct *data) |
@@ -3391,6 +3391,55 @@ static int iwl3945_mac_sta_add(struct ieee80211_hw *hw, | |||
3391 | 3391 | ||
3392 | return 0; | 3392 | return 0; |
3393 | } | 3393 | } |
3394 | |||
3395 | static void iwl3945_configure_filter(struct ieee80211_hw *hw, | ||
3396 | unsigned int changed_flags, | ||
3397 | unsigned int *total_flags, | ||
3398 | u64 multicast) | ||
3399 | { | ||
3400 | struct iwl_priv *priv = hw->priv; | ||
3401 | __le32 filter_or = 0, filter_nand = 0; | ||
3402 | |||
3403 | #define CHK(test, flag) do { \ | ||
3404 | if (*total_flags & (test)) \ | ||
3405 | filter_or |= (flag); \ | ||
3406 | else \ | ||
3407 | filter_nand |= (flag); \ | ||
3408 | } while (0) | ||
3409 | |||
3410 | IWL_DEBUG_MAC80211(priv, "Enter: changed: 0x%x, total: 0x%x\n", | ||
3411 | changed_flags, *total_flags); | ||
3412 | |||
3413 | CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK); | ||
3414 | CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK); | ||
3415 | CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK); | ||
3416 | |||
3417 | #undef CHK | ||
3418 | |||
3419 | mutex_lock(&priv->mutex); | ||
3420 | |||
3421 | priv->staging_rxon.filter_flags &= ~filter_nand; | ||
3422 | priv->staging_rxon.filter_flags |= filter_or; | ||
3423 | |||
3424 | /* | ||
3425 | * Committing directly here breaks for some reason, | ||
3426 | * but we'll eventually commit the filter flags | ||
3427 | * change anyway. | ||
3428 | */ | ||
3429 | |||
3430 | mutex_unlock(&priv->mutex); | ||
3431 | |||
3432 | /* | ||
3433 | * Receiving all multicast frames is always enabled by the | ||
3434 | * default flags setup in iwl_connection_init_rx_config() | ||
3435 | * since we currently do not support programming multicast | ||
3436 | * filters into the device. | ||
3437 | */ | ||
3438 | *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS | | ||
3439 | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; | ||
3440 | } | ||
3441 | |||
3442 | |||
3394 | /***************************************************************************** | 3443 | /***************************************************************************** |
3395 | * | 3444 | * |
3396 | * sysfs attributes | 3445 | * sysfs attributes |
@@ -3796,7 +3845,7 @@ static struct ieee80211_ops iwl3945_hw_ops = { | |||
3796 | .add_interface = iwl_mac_add_interface, | 3845 | .add_interface = iwl_mac_add_interface, |
3797 | .remove_interface = iwl_mac_remove_interface, | 3846 | .remove_interface = iwl_mac_remove_interface, |
3798 | .config = iwl_mac_config, | 3847 | .config = iwl_mac_config, |
3799 | .configure_filter = iwl_configure_filter, | 3848 | .configure_filter = iwl3945_configure_filter, |
3800 | .set_key = iwl3945_mac_set_key, | 3849 | .set_key = iwl3945_mac_set_key, |
3801 | .conf_tx = iwl_mac_conf_tx, | 3850 | .conf_tx = iwl_mac_conf_tx, |
3802 | .reset_tsf = iwl_mac_reset_tsf, | 3851 | .reset_tsf = iwl_mac_reset_tsf, |
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index ba854c70ab9..87b634978b3 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c | |||
@@ -128,7 +128,7 @@ struct if_sdio_card { | |||
128 | bool helper_allocated; | 128 | bool helper_allocated; |
129 | bool firmware_allocated; | 129 | bool firmware_allocated; |
130 | 130 | ||
131 | u8 buffer[65536]; | 131 | u8 buffer[65536] __attribute__((aligned(4))); |
132 | 132 | ||
133 | spinlock_t lock; | 133 | spinlock_t lock; |
134 | struct if_sdio_packet *packets; | 134 | struct if_sdio_packet *packets; |
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 01ad7f77383..86fa8abdd66 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
@@ -486,7 +486,7 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, | |||
486 | struct ieee80211_rx_status rx_status; | 486 | struct ieee80211_rx_status rx_status; |
487 | 487 | ||
488 | if (data->idle) { | 488 | if (data->idle) { |
489 | wiphy_debug(hw->wiphy, "trying to tx when idle - reject\n"); | 489 | wiphy_debug(hw->wiphy, "Trying to TX when idle - reject\n"); |
490 | return false; | 490 | return false; |
491 | } | 491 | } |
492 | 492 | ||
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index d761ed2d8af..f152a25be59 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c | |||
@@ -910,14 +910,14 @@ static int mwl8k_rxq_init(struct ieee80211_hw *hw, int index) | |||
910 | 910 | ||
911 | rxq->rxd = pci_alloc_consistent(priv->pdev, size, &rxq->rxd_dma); | 911 | rxq->rxd = pci_alloc_consistent(priv->pdev, size, &rxq->rxd_dma); |
912 | if (rxq->rxd == NULL) { | 912 | if (rxq->rxd == NULL) { |
913 | wiphy_err(hw->wiphy, "failed to alloc rx descriptors\n"); | 913 | wiphy_err(hw->wiphy, "failed to alloc RX descriptors\n"); |
914 | return -ENOMEM; | 914 | return -ENOMEM; |
915 | } | 915 | } |
916 | memset(rxq->rxd, 0, size); | 916 | memset(rxq->rxd, 0, size); |
917 | 917 | ||
918 | rxq->buf = kmalloc(MWL8K_RX_DESCS * sizeof(*rxq->buf), GFP_KERNEL); | 918 | rxq->buf = kmalloc(MWL8K_RX_DESCS * sizeof(*rxq->buf), GFP_KERNEL); |
919 | if (rxq->buf == NULL) { | 919 | if (rxq->buf == NULL) { |
920 | wiphy_err(hw->wiphy, "failed to alloc rx skbuff list\n"); | 920 | wiphy_err(hw->wiphy, "failed to alloc RX skbuff list\n"); |
921 | pci_free_consistent(priv->pdev, size, rxq->rxd, rxq->rxd_dma); | 921 | pci_free_consistent(priv->pdev, size, rxq->rxd, rxq->rxd_dma); |
922 | return -ENOMEM; | 922 | return -ENOMEM; |
923 | } | 923 | } |
@@ -1145,14 +1145,14 @@ static int mwl8k_txq_init(struct ieee80211_hw *hw, int index) | |||
1145 | 1145 | ||
1146 | txq->txd = pci_alloc_consistent(priv->pdev, size, &txq->txd_dma); | 1146 | txq->txd = pci_alloc_consistent(priv->pdev, size, &txq->txd_dma); |
1147 | if (txq->txd == NULL) { | 1147 | if (txq->txd == NULL) { |
1148 | wiphy_err(hw->wiphy, "failed to alloc tx descriptors\n"); | 1148 | wiphy_err(hw->wiphy, "failed to alloc TX descriptors\n"); |
1149 | return -ENOMEM; | 1149 | return -ENOMEM; |
1150 | } | 1150 | } |
1151 | memset(txq->txd, 0, size); | 1151 | memset(txq->txd, 0, size); |
1152 | 1152 | ||
1153 | txq->skb = kmalloc(MWL8K_TX_DESCS * sizeof(*txq->skb), GFP_KERNEL); | 1153 | txq->skb = kmalloc(MWL8K_TX_DESCS * sizeof(*txq->skb), GFP_KERNEL); |
1154 | if (txq->skb == NULL) { | 1154 | if (txq->skb == NULL) { |
1155 | wiphy_err(hw->wiphy, "failed to alloc tx skbuff list\n"); | 1155 | wiphy_err(hw->wiphy, "failed to alloc TX skbuff list\n"); |
1156 | pci_free_consistent(priv->pdev, size, txq->txd, txq->txd_dma); | 1156 | pci_free_consistent(priv->pdev, size, txq->txd, txq->txd_dma); |
1157 | return -ENOMEM; | 1157 | return -ENOMEM; |
1158 | } | 1158 | } |
@@ -1573,7 +1573,7 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd) | |||
1573 | PCI_DMA_BIDIRECTIONAL); | 1573 | PCI_DMA_BIDIRECTIONAL); |
1574 | 1574 | ||
1575 | if (!timeout) { | 1575 | if (!timeout) { |
1576 | wiphy_err(hw->wiphy, "command %s timeout after %u ms\n", | 1576 | wiphy_err(hw->wiphy, "Command %s timeout after %u ms\n", |
1577 | mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), | 1577 | mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), |
1578 | MWL8K_CMD_TIMEOUT_MS); | 1578 | MWL8K_CMD_TIMEOUT_MS); |
1579 | rc = -ETIMEDOUT; | 1579 | rc = -ETIMEDOUT; |
@@ -1584,11 +1584,11 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd) | |||
1584 | 1584 | ||
1585 | rc = cmd->result ? -EINVAL : 0; | 1585 | rc = cmd->result ? -EINVAL : 0; |
1586 | if (rc) | 1586 | if (rc) |
1587 | wiphy_err(hw->wiphy, "command %s error 0x%x\n", | 1587 | wiphy_err(hw->wiphy, "Command %s error 0x%x\n", |
1588 | mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), | 1588 | mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), |
1589 | le16_to_cpu(cmd->result)); | 1589 | le16_to_cpu(cmd->result)); |
1590 | else if (ms > 2000) | 1590 | else if (ms > 2000) |
1591 | wiphy_notice(hw->wiphy, "command %s took %d ms\n", | 1591 | wiphy_notice(hw->wiphy, "Command %s took %d ms\n", |
1592 | mwl8k_cmd_name(cmd->code, | 1592 | mwl8k_cmd_name(cmd->code, |
1593 | buf, sizeof(buf)), | 1593 | buf, sizeof(buf)), |
1594 | ms); | 1594 | ms); |
@@ -3210,7 +3210,7 @@ static int mwl8k_start(struct ieee80211_hw *hw) | |||
3210 | rc = request_irq(priv->pdev->irq, mwl8k_interrupt, | 3210 | rc = request_irq(priv->pdev->irq, mwl8k_interrupt, |
3211 | IRQF_SHARED, MWL8K_NAME, hw); | 3211 | IRQF_SHARED, MWL8K_NAME, hw); |
3212 | if (rc) { | 3212 | if (rc) { |
3213 | wiphy_err(hw->wiphy, "failed to register irq handler\n"); | 3213 | wiphy_err(hw->wiphy, "failed to register IRQ handler\n"); |
3214 | return -EIO; | 3214 | return -EIO; |
3215 | } | 3215 | } |
3216 | 3216 | ||
@@ -3926,7 +3926,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, | |||
3926 | 3926 | ||
3927 | priv->sram = pci_iomap(pdev, 0, 0x10000); | 3927 | priv->sram = pci_iomap(pdev, 0, 0x10000); |
3928 | if (priv->sram == NULL) { | 3928 | if (priv->sram == NULL) { |
3929 | wiphy_err(hw->wiphy, "cannot map device sram\n"); | 3929 | wiphy_err(hw->wiphy, "Cannot map device SRAM\n"); |
3930 | goto err_iounmap; | 3930 | goto err_iounmap; |
3931 | } | 3931 | } |
3932 | 3932 | ||
@@ -3938,7 +3938,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, | |||
3938 | if (priv->regs == NULL) { | 3938 | if (priv->regs == NULL) { |
3939 | priv->regs = pci_iomap(pdev, 2, 0x10000); | 3939 | priv->regs = pci_iomap(pdev, 2, 0x10000); |
3940 | if (priv->regs == NULL) { | 3940 | if (priv->regs == NULL) { |
3941 | wiphy_err(hw->wiphy, "cannot map device registers\n"); | 3941 | wiphy_err(hw->wiphy, "Cannot map device registers\n"); |
3942 | goto err_iounmap; | 3942 | goto err_iounmap; |
3943 | } | 3943 | } |
3944 | } | 3944 | } |
@@ -3950,14 +3950,14 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, | |||
3950 | /* Ask userland hotplug daemon for the device firmware */ | 3950 | /* Ask userland hotplug daemon for the device firmware */ |
3951 | rc = mwl8k_request_firmware(priv); | 3951 | rc = mwl8k_request_firmware(priv); |
3952 | if (rc) { | 3952 | if (rc) { |
3953 | wiphy_err(hw->wiphy, "firmware files not found\n"); | 3953 | wiphy_err(hw->wiphy, "Firmware files not found\n"); |
3954 | goto err_stop_firmware; | 3954 | goto err_stop_firmware; |
3955 | } | 3955 | } |
3956 | 3956 | ||
3957 | /* Load firmware into hardware */ | 3957 | /* Load firmware into hardware */ |
3958 | rc = mwl8k_load_firmware(hw); | 3958 | rc = mwl8k_load_firmware(hw); |
3959 | if (rc) { | 3959 | if (rc) { |
3960 | wiphy_err(hw->wiphy, "cannot start firmware\n"); | 3960 | wiphy_err(hw->wiphy, "Cannot start firmware\n"); |
3961 | goto err_stop_firmware; | 3961 | goto err_stop_firmware; |
3962 | } | 3962 | } |
3963 | 3963 | ||
@@ -4047,7 +4047,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, | |||
4047 | rc = request_irq(priv->pdev->irq, mwl8k_interrupt, | 4047 | rc = request_irq(priv->pdev->irq, mwl8k_interrupt, |
4048 | IRQF_SHARED, MWL8K_NAME, hw); | 4048 | IRQF_SHARED, MWL8K_NAME, hw); |
4049 | if (rc) { | 4049 | if (rc) { |
4050 | wiphy_err(hw->wiphy, "failed to register irq handler\n"); | 4050 | wiphy_err(hw->wiphy, "failed to register IRQ handler\n"); |
4051 | goto err_free_queues; | 4051 | goto err_free_queues; |
4052 | } | 4052 | } |
4053 | 4053 | ||
@@ -4067,7 +4067,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, | |||
4067 | rc = mwl8k_cmd_get_hw_spec_sta(hw); | 4067 | rc = mwl8k_cmd_get_hw_spec_sta(hw); |
4068 | } | 4068 | } |
4069 | if (rc) { | 4069 | if (rc) { |
4070 | wiphy_err(hw->wiphy, "cannot initialise firmware\n"); | 4070 | wiphy_err(hw->wiphy, "Cannot initialise firmware\n"); |
4071 | goto err_free_irq; | 4071 | goto err_free_irq; |
4072 | } | 4072 | } |
4073 | 4073 | ||
@@ -4081,14 +4081,14 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, | |||
4081 | /* Turn radio off */ | 4081 | /* Turn radio off */ |
4082 | rc = mwl8k_cmd_radio_disable(hw); | 4082 | rc = mwl8k_cmd_radio_disable(hw); |
4083 | if (rc) { | 4083 | if (rc) { |
4084 | wiphy_err(hw->wiphy, "cannot disable\n"); | 4084 | wiphy_err(hw->wiphy, "Cannot disable\n"); |
4085 | goto err_free_irq; | 4085 | goto err_free_irq; |
4086 | } | 4086 | } |
4087 | 4087 | ||
4088 | /* Clear MAC address */ | 4088 | /* Clear MAC address */ |
4089 | rc = mwl8k_cmd_set_mac_addr(hw, NULL, "\x00\x00\x00\x00\x00\x00"); | 4089 | rc = mwl8k_cmd_set_mac_addr(hw, NULL, "\x00\x00\x00\x00\x00\x00"); |
4090 | if (rc) { | 4090 | if (rc) { |
4091 | wiphy_err(hw->wiphy, "cannot clear mac address\n"); | 4091 | wiphy_err(hw->wiphy, "Cannot clear MAC address\n"); |
4092 | goto err_free_irq; | 4092 | goto err_free_irq; |
4093 | } | 4093 | } |
4094 | 4094 | ||
@@ -4098,7 +4098,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, | |||
4098 | 4098 | ||
4099 | rc = ieee80211_register_hw(hw); | 4099 | rc = ieee80211_register_hw(hw); |
4100 | if (rc) { | 4100 | if (rc) { |
4101 | wiphy_err(hw->wiphy, "cannot register device\n"); | 4101 | wiphy_err(hw->wiphy, "Cannot register device\n"); |
4102 | goto err_free_queues; | 4102 | goto err_free_queues; |
4103 | } | 4103 | } |
4104 | 4104 | ||
diff --git a/drivers/net/wireless/p54/eeprom.c b/drivers/net/wireless/p54/eeprom.c index d687cb7f2a5..78347041ec4 100644 --- a/drivers/net/wireless/p54/eeprom.c +++ b/drivers/net/wireless/p54/eeprom.c | |||
@@ -167,7 +167,7 @@ static int p54_generate_band(struct ieee80211_hw *dev, | |||
167 | } | 167 | } |
168 | 168 | ||
169 | if (j == 0) { | 169 | if (j == 0) { |
170 | wiphy_err(dev->wiphy, "disabling totally damaged %d GHz band\n", | 170 | wiphy_err(dev->wiphy, "Disabling totally damaged %d GHz band\n", |
171 | (band == IEEE80211_BAND_2GHZ) ? 2 : 5); | 171 | (band == IEEE80211_BAND_2GHZ) ? 2 : 5); |
172 | 172 | ||
173 | ret = -ENODATA; | 173 | ret = -ENODATA; |
@@ -695,12 +695,12 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) | |||
695 | u8 perm_addr[ETH_ALEN]; | 695 | u8 perm_addr[ETH_ALEN]; |
696 | 696 | ||
697 | wiphy_warn(dev->wiphy, | 697 | wiphy_warn(dev->wiphy, |
698 | "invalid hwaddr! using randomly generated mac addr\n"); | 698 | "Invalid hwaddr! Using randomly generated MAC addr\n"); |
699 | random_ether_addr(perm_addr); | 699 | random_ether_addr(perm_addr); |
700 | SET_IEEE80211_PERM_ADDR(dev, perm_addr); | 700 | SET_IEEE80211_PERM_ADDR(dev, perm_addr); |
701 | } | 701 | } |
702 | 702 | ||
703 | wiphy_info(dev->wiphy, "hwaddr %pm, mac:isl38%02x rf:%s\n", | 703 | wiphy_info(dev->wiphy, "hwaddr %pM, MAC:isl38%02x RF:%s\n", |
704 | dev->wiphy->perm_addr, priv->version, | 704 | dev->wiphy->perm_addr, priv->version, |
705 | p54_rf_chips[priv->rxhw]); | 705 | p54_rf_chips[priv->rxhw]); |
706 | 706 | ||
diff --git a/drivers/net/wireless/p54/fwio.c b/drivers/net/wireless/p54/fwio.c index 47006bca485..15b20c29a60 100644 --- a/drivers/net/wireless/p54/fwio.c +++ b/drivers/net/wireless/p54/fwio.c | |||
@@ -125,7 +125,7 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) | |||
125 | 125 | ||
126 | if (fw_version) | 126 | if (fw_version) |
127 | wiphy_info(priv->hw->wiphy, | 127 | wiphy_info(priv->hw->wiphy, |
128 | "fw rev %s - softmac protocol %x.%x\n", | 128 | "FW rev %s - Softmac protocol %x.%x\n", |
129 | fw_version, priv->fw_var >> 8, priv->fw_var & 0xff); | 129 | fw_version, priv->fw_var >> 8, priv->fw_var & 0xff); |
130 | 130 | ||
131 | if (priv->fw_var < 0x500) | 131 | if (priv->fw_var < 0x500) |
diff --git a/drivers/net/wireless/p54/led.c b/drivers/net/wireless/p54/led.c index ea91f5cce6b..3837e1eec5f 100644 --- a/drivers/net/wireless/p54/led.c +++ b/drivers/net/wireless/p54/led.c | |||
@@ -58,7 +58,7 @@ static void p54_update_leds(struct work_struct *work) | |||
58 | err = p54_set_leds(priv); | 58 | err = p54_set_leds(priv); |
59 | if (err && net_ratelimit()) | 59 | if (err && net_ratelimit()) |
60 | wiphy_err(priv->hw->wiphy, | 60 | wiphy_err(priv->hw->wiphy, |
61 | "failed to update leds (%d).\n", err); | 61 | "failed to update LEDs (%d).\n", err); |
62 | 62 | ||
63 | if (rerun) | 63 | if (rerun) |
64 | ieee80211_queue_delayed_work(priv->hw, &priv->led_work, | 64 | ieee80211_queue_delayed_work(priv->hw, &priv->led_work, |
@@ -103,7 +103,7 @@ static int p54_register_led(struct p54_common *priv, | |||
103 | err = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_dev); | 103 | err = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_dev); |
104 | if (err) | 104 | if (err) |
105 | wiphy_err(priv->hw->wiphy, | 105 | wiphy_err(priv->hw->wiphy, |
106 | "failed to register %s led.\n", name); | 106 | "Failed to register %s LED.\n", name); |
107 | else | 107 | else |
108 | led->registered = 1; | 108 | led->registered = 1; |
109 | 109 | ||
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c index 822f8dc26e9..1eacba4daa5 100644 --- a/drivers/net/wireless/p54/p54pci.c +++ b/drivers/net/wireless/p54/p54pci.c | |||
@@ -466,7 +466,7 @@ static int p54p_open(struct ieee80211_hw *dev) | |||
466 | P54P_READ(dev_int); | 466 | P54P_READ(dev_int); |
467 | 467 | ||
468 | if (!wait_for_completion_interruptible_timeout(&priv->boot_comp, HZ)) { | 468 | if (!wait_for_completion_interruptible_timeout(&priv->boot_comp, HZ)) { |
469 | wiphy_err(dev->wiphy, "cannot boot firmware!\n"); | 469 | wiphy_err(dev->wiphy, "Cannot boot firmware!\n"); |
470 | p54p_stop(dev); | 470 | p54p_stop(dev); |
471 | return -ETIMEDOUT; | 471 | return -ETIMEDOUT; |
472 | } | 472 | } |
diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c index 427b46f558e..0e937dc0c9c 100644 --- a/drivers/net/wireless/p54/txrx.c +++ b/drivers/net/wireless/p54/txrx.c | |||
@@ -446,7 +446,7 @@ static void p54_rx_frame_sent(struct p54_common *priv, struct sk_buff *skb) | |||
446 | } | 446 | } |
447 | 447 | ||
448 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && | 448 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && |
449 | (!payload->status)) | 449 | !(payload->status & P54_TX_FAILED)) |
450 | info->flags |= IEEE80211_TX_STAT_ACK; | 450 | info->flags |= IEEE80211_TX_STAT_ACK; |
451 | if (payload->status & P54_TX_PSM_CANCELLED) | 451 | if (payload->status & P54_TX_PSM_CANCELLED) |
452 | info->flags |= IEEE80211_TX_STAT_TX_FILTERED; | 452 | info->flags |= IEEE80211_TX_STAT_TX_FILTERED; |
@@ -540,7 +540,7 @@ static void p54_rx_trap(struct p54_common *priv, struct sk_buff *skb) | |||
540 | case P54_TRAP_BEACON_TX: | 540 | case P54_TRAP_BEACON_TX: |
541 | break; | 541 | break; |
542 | case P54_TRAP_RADAR: | 542 | case P54_TRAP_RADAR: |
543 | wiphy_info(priv->hw->wiphy, "radar (freq:%d mhz)\n", freq); | 543 | wiphy_info(priv->hw->wiphy, "radar (freq:%d MHz)\n", freq); |
544 | break; | 544 | break; |
545 | case P54_TRAP_NO_BEACON: | 545 | case P54_TRAP_NO_BEACON: |
546 | if (priv->vif) | 546 | if (priv->vif) |
diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c index b50c39aaec0..30107ce78df 100644 --- a/drivers/net/wireless/rtl818x/rtl8180_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c | |||
@@ -445,7 +445,7 @@ static int rtl8180_init_rx_ring(struct ieee80211_hw *dev) | |||
445 | &priv->rx_ring_dma); | 445 | &priv->rx_ring_dma); |
446 | 446 | ||
447 | if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) { | 447 | if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) { |
448 | wiphy_err(dev->wiphy, "cannot allocate rx ring\n"); | 448 | wiphy_err(dev->wiphy, "Cannot allocate RX ring\n"); |
449 | return -ENOMEM; | 449 | return -ENOMEM; |
450 | } | 450 | } |
451 | 451 | ||
@@ -502,7 +502,7 @@ static int rtl8180_init_tx_ring(struct ieee80211_hw *dev, | |||
502 | 502 | ||
503 | ring = pci_alloc_consistent(priv->pdev, sizeof(*ring) * entries, &dma); | 503 | ring = pci_alloc_consistent(priv->pdev, sizeof(*ring) * entries, &dma); |
504 | if (!ring || (unsigned long)ring & 0xFF) { | 504 | if (!ring || (unsigned long)ring & 0xFF) { |
505 | wiphy_err(dev->wiphy, "cannot allocate tx ring (prio = %d)\n", | 505 | wiphy_err(dev->wiphy, "Cannot allocate TX ring (prio = %d)\n", |
506 | prio); | 506 | prio); |
507 | return -ENOMEM; | 507 | return -ENOMEM; |
508 | } | 508 | } |
@@ -568,7 +568,7 @@ static int rtl8180_start(struct ieee80211_hw *dev) | |||
568 | ret = request_irq(priv->pdev->irq, rtl8180_interrupt, | 568 | ret = request_irq(priv->pdev->irq, rtl8180_interrupt, |
569 | IRQF_SHARED, KBUILD_MODNAME, dev); | 569 | IRQF_SHARED, KBUILD_MODNAME, dev); |
570 | if (ret) { | 570 | if (ret) { |
571 | wiphy_err(dev->wiphy, "failed to register irq handler\n"); | 571 | wiphy_err(dev->wiphy, "failed to register IRQ handler\n"); |
572 | goto err_free_rings; | 572 | goto err_free_rings; |
573 | } | 573 | } |
574 | 574 | ||
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c index 5738a55c1b0..98e0351c1dd 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c | |||
@@ -573,7 +573,7 @@ static int rtl8187_cmd_reset(struct ieee80211_hw *dev) | |||
573 | } while (--i); | 573 | } while (--i); |
574 | 574 | ||
575 | if (!i) { | 575 | if (!i) { |
576 | wiphy_err(dev->wiphy, "reset timeout!\n"); | 576 | wiphy_err(dev->wiphy, "Reset timeout!\n"); |
577 | return -ETIMEDOUT; | 577 | return -ETIMEDOUT; |
578 | } | 578 | } |
579 | 579 | ||
@@ -1526,7 +1526,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, | |||
1526 | mutex_init(&priv->conf_mutex); | 1526 | mutex_init(&priv->conf_mutex); |
1527 | skb_queue_head_init(&priv->b_tx_status.queue); | 1527 | skb_queue_head_init(&priv->b_tx_status.queue); |
1528 | 1528 | ||
1529 | wiphy_info(dev->wiphy, "hwaddr %pm, %s v%d + %s, rfkill mask %d\n", | 1529 | wiphy_info(dev->wiphy, "hwaddr %pM, %s V%d + %s, rfkill mask %d\n", |
1530 | mac_addr, chip_name, priv->asic_rev, priv->rf->name, | 1530 | mac_addr, chip_name, priv->asic_rev, priv->rf->name, |
1531 | priv->rfkill_mask); | 1531 | priv->rfkill_mask); |
1532 | 1532 | ||
diff --git a/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c b/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c index fd96f911232..97eebdcf7eb 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c +++ b/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c | |||
@@ -366,7 +366,7 @@ static void rtl8225_rf_init(struct ieee80211_hw *dev) | |||
366 | rtl8225_write(dev, 0x02, 0x044d); | 366 | rtl8225_write(dev, 0x02, 0x044d); |
367 | msleep(100); | 367 | msleep(100); |
368 | if (!(rtl8225_read(dev, 6) & (1 << 7))) | 368 | if (!(rtl8225_read(dev, 6) & (1 << 7))) |
369 | wiphy_warn(dev->wiphy, "rf calibration failed! %x\n", | 369 | wiphy_warn(dev->wiphy, "RF Calibration Failed! %x\n", |
370 | rtl8225_read(dev, 6)); | 370 | rtl8225_read(dev, 6)); |
371 | } | 371 | } |
372 | 372 | ||
@@ -735,7 +735,7 @@ static void rtl8225z2_rf_init(struct ieee80211_hw *dev) | |||
735 | rtl8225_write(dev, 0x02, 0x044D); | 735 | rtl8225_write(dev, 0x02, 0x044D); |
736 | msleep(100); | 736 | msleep(100); |
737 | if (!(rtl8225_read(dev, 6) & (1 << 7))) | 737 | if (!(rtl8225_read(dev, 6) & (1 << 7))) |
738 | wiphy_warn(dev->wiphy, "rf calibration failed! %x\n", | 738 | wiphy_warn(dev->wiphy, "RF Calibration Failed! %x\n", |
739 | rtl8225_read(dev, 6)); | 739 | rtl8225_read(dev, 6)); |
740 | } | 740 | } |
741 | 741 | ||
diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c index a9352b2c7ac..b7e755f4178 100644 --- a/drivers/oprofile/buffer_sync.c +++ b/drivers/oprofile/buffer_sync.c | |||
@@ -141,16 +141,6 @@ static struct notifier_block module_load_nb = { | |||
141 | .notifier_call = module_load_notify, | 141 | .notifier_call = module_load_notify, |
142 | }; | 142 | }; |
143 | 143 | ||
144 | |||
145 | static void end_sync(void) | ||
146 | { | ||
147 | end_cpu_work(); | ||
148 | /* make sure we don't leak task structs */ | ||
149 | process_task_mortuary(); | ||
150 | process_task_mortuary(); | ||
151 | } | ||
152 | |||
153 | |||
154 | int sync_start(void) | 144 | int sync_start(void) |
155 | { | 145 | { |
156 | int err; | 146 | int err; |
@@ -158,7 +148,7 @@ int sync_start(void) | |||
158 | if (!zalloc_cpumask_var(&marked_cpus, GFP_KERNEL)) | 148 | if (!zalloc_cpumask_var(&marked_cpus, GFP_KERNEL)) |
159 | return -ENOMEM; | 149 | return -ENOMEM; |
160 | 150 | ||
161 | start_cpu_work(); | 151 | mutex_lock(&buffer_mutex); |
162 | 152 | ||
163 | err = task_handoff_register(&task_free_nb); | 153 | err = task_handoff_register(&task_free_nb); |
164 | if (err) | 154 | if (err) |
@@ -173,7 +163,10 @@ int sync_start(void) | |||
173 | if (err) | 163 | if (err) |
174 | goto out4; | 164 | goto out4; |
175 | 165 | ||
166 | start_cpu_work(); | ||
167 | |||
176 | out: | 168 | out: |
169 | mutex_unlock(&buffer_mutex); | ||
177 | return err; | 170 | return err; |
178 | out4: | 171 | out4: |
179 | profile_event_unregister(PROFILE_MUNMAP, &munmap_nb); | 172 | profile_event_unregister(PROFILE_MUNMAP, &munmap_nb); |
@@ -182,7 +175,6 @@ out3: | |||
182 | out2: | 175 | out2: |
183 | task_handoff_unregister(&task_free_nb); | 176 | task_handoff_unregister(&task_free_nb); |
184 | out1: | 177 | out1: |
185 | end_sync(); | ||
186 | free_cpumask_var(marked_cpus); | 178 | free_cpumask_var(marked_cpus); |
187 | goto out; | 179 | goto out; |
188 | } | 180 | } |
@@ -190,11 +182,20 @@ out1: | |||
190 | 182 | ||
191 | void sync_stop(void) | 183 | void sync_stop(void) |
192 | { | 184 | { |
185 | /* flush buffers */ | ||
186 | mutex_lock(&buffer_mutex); | ||
187 | end_cpu_work(); | ||
193 | unregister_module_notifier(&module_load_nb); | 188 | unregister_module_notifier(&module_load_nb); |
194 | profile_event_unregister(PROFILE_MUNMAP, &munmap_nb); | 189 | profile_event_unregister(PROFILE_MUNMAP, &munmap_nb); |
195 | profile_event_unregister(PROFILE_TASK_EXIT, &task_exit_nb); | 190 | profile_event_unregister(PROFILE_TASK_EXIT, &task_exit_nb); |
196 | task_handoff_unregister(&task_free_nb); | 191 | task_handoff_unregister(&task_free_nb); |
197 | end_sync(); | 192 | mutex_unlock(&buffer_mutex); |
193 | flush_scheduled_work(); | ||
194 | |||
195 | /* make sure we don't leak task structs */ | ||
196 | process_task_mortuary(); | ||
197 | process_task_mortuary(); | ||
198 | |||
198 | free_cpumask_var(marked_cpus); | 199 | free_cpumask_var(marked_cpus); |
199 | } | 200 | } |
200 | 201 | ||
diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c index 219f79e2210..f179ac2ea80 100644 --- a/drivers/oprofile/cpu_buffer.c +++ b/drivers/oprofile/cpu_buffer.c | |||
@@ -120,8 +120,6 @@ void end_cpu_work(void) | |||
120 | 120 | ||
121 | cancel_delayed_work(&b->work); | 121 | cancel_delayed_work(&b->work); |
122 | } | 122 | } |
123 | |||
124 | flush_scheduled_work(); | ||
125 | } | 123 | } |
126 | 124 | ||
127 | /* | 125 | /* |
diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c index 45fcc1e96df..3bc72d18b12 100644 --- a/drivers/pci/hotplug/acpi_pcihp.c +++ b/drivers/pci/hotplug/acpi_pcihp.c | |||
@@ -338,9 +338,7 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags) | |||
338 | acpi_handle chandle, handle; | 338 | acpi_handle chandle, handle; |
339 | struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL }; | 339 | struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL }; |
340 | 340 | ||
341 | flags &= (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | | 341 | flags &= OSC_SHPC_NATIVE_HP_CONTROL; |
342 | OSC_SHPC_NATIVE_HP_CONTROL | | ||
343 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); | ||
344 | if (!flags) { | 342 | if (!flags) { |
345 | err("Invalid flags %u specified!\n", flags); | 343 | err("Invalid flags %u specified!\n", flags); |
346 | return -EINVAL; | 344 | return -EINVAL; |
@@ -360,7 +358,7 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags) | |||
360 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &string); | 358 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &string); |
361 | dbg("Trying to get hotplug control for %s\n", | 359 | dbg("Trying to get hotplug control for %s\n", |
362 | (char *)string.pointer); | 360 | (char *)string.pointer); |
363 | status = acpi_pci_osc_control_set(handle, flags); | 361 | status = acpi_pci_osc_control_set(handle, &flags, flags); |
364 | if (ACPI_SUCCESS(status)) | 362 | if (ACPI_SUCCESS(status)) |
365 | goto got_one; | 363 | goto got_one; |
366 | if (status == AE_SUPPORT) | 364 | if (status == AE_SUPPORT) |
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index 4ed76b47b6d..73d51398926 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h | |||
@@ -176,19 +176,11 @@ static inline void pciehp_firmware_init(void) | |||
176 | { | 176 | { |
177 | pciehp_acpi_slot_detection_init(); | 177 | pciehp_acpi_slot_detection_init(); |
178 | } | 178 | } |
179 | |||
180 | static inline int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev) | ||
181 | { | ||
182 | int retval; | ||
183 | u32 flags = (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | | ||
184 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); | ||
185 | retval = acpi_get_hp_hw_control_from_firmware(dev, flags); | ||
186 | if (retval) | ||
187 | return retval; | ||
188 | return pciehp_acpi_slot_detection_check(dev); | ||
189 | } | ||
190 | #else | 179 | #else |
191 | #define pciehp_firmware_init() do {} while (0) | 180 | #define pciehp_firmware_init() do {} while (0) |
192 | #define pciehp_get_hp_hw_control_from_firmware(dev) 0 | 181 | static inline int pciehp_acpi_slot_detection_check(struct pci_dev *dev) |
182 | { | ||
183 | return 0; | ||
184 | } | ||
193 | #endif /* CONFIG_ACPI */ | 185 | #endif /* CONFIG_ACPI */ |
194 | #endif /* _PCIEHP_H */ | 186 | #endif /* _PCIEHP_H */ |
diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c index 1f4000a5a10..2574700db46 100644 --- a/drivers/pci/hotplug/pciehp_acpi.c +++ b/drivers/pci/hotplug/pciehp_acpi.c | |||
@@ -85,9 +85,7 @@ static int __init dummy_probe(struct pcie_device *dev) | |||
85 | acpi_handle handle; | 85 | acpi_handle handle; |
86 | struct dummy_slot *slot, *tmp; | 86 | struct dummy_slot *slot, *tmp; |
87 | struct pci_dev *pdev = dev->port; | 87 | struct pci_dev *pdev = dev->port; |
88 | /* Note: pciehp_detect_mode != PCIEHP_DETECT_ACPI here */ | 88 | |
89 | if (pciehp_get_hp_hw_control_from_firmware(pdev)) | ||
90 | return -ENODEV; | ||
91 | pos = pci_pcie_cap(pdev); | 89 | pos = pci_pcie_cap(pdev); |
92 | if (!pos) | 90 | if (!pos) |
93 | return -ENODEV; | 91 | return -ENODEV; |
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 3588ea61b0d..aa5f3ff629f 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c | |||
@@ -59,7 +59,7 @@ module_param(pciehp_force, bool, 0644); | |||
59 | MODULE_PARM_DESC(pciehp_debug, "Debugging mode enabled or not"); | 59 | MODULE_PARM_DESC(pciehp_debug, "Debugging mode enabled or not"); |
60 | MODULE_PARM_DESC(pciehp_poll_mode, "Using polling mechanism for hot-plug events or not"); | 60 | MODULE_PARM_DESC(pciehp_poll_mode, "Using polling mechanism for hot-plug events or not"); |
61 | MODULE_PARM_DESC(pciehp_poll_time, "Polling mechanism frequency, in seconds"); | 61 | MODULE_PARM_DESC(pciehp_poll_time, "Polling mechanism frequency, in seconds"); |
62 | MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if _OSC and OSHP are missing"); | 62 | MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if OSHP is missing"); |
63 | 63 | ||
64 | #define PCIE_MODULE_NAME "pciehp" | 64 | #define PCIE_MODULE_NAME "pciehp" |
65 | 65 | ||
@@ -235,7 +235,7 @@ static int pciehp_probe(struct pcie_device *dev) | |||
235 | dev_info(&dev->device, | 235 | dev_info(&dev->device, |
236 | "Bypassing BIOS check for pciehp use on %s\n", | 236 | "Bypassing BIOS check for pciehp use on %s\n", |
237 | pci_name(dev->port)); | 237 | pci_name(dev->port)); |
238 | else if (pciehp_get_hp_hw_control_from_firmware(dev->port)) | 238 | else if (pciehp_acpi_slot_detection_check(dev->port)) |
239 | goto err_out_none; | 239 | goto err_out_none; |
240 | 240 | ||
241 | ctrl = pcie_init(dev); | 241 | ctrl = pcie_init(dev); |
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index c3ceebb5be8..4789f8e8bf7 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c | |||
@@ -71,6 +71,49 @@ | |||
71 | #define DMA_32BIT_PFN IOVA_PFN(DMA_BIT_MASK(32)) | 71 | #define DMA_32BIT_PFN IOVA_PFN(DMA_BIT_MASK(32)) |
72 | #define DMA_64BIT_PFN IOVA_PFN(DMA_BIT_MASK(64)) | 72 | #define DMA_64BIT_PFN IOVA_PFN(DMA_BIT_MASK(64)) |
73 | 73 | ||
74 | /* page table handling */ | ||
75 | #define LEVEL_STRIDE (9) | ||
76 | #define LEVEL_MASK (((u64)1 << LEVEL_STRIDE) - 1) | ||
77 | |||
78 | static inline int agaw_to_level(int agaw) | ||
79 | { | ||
80 | return agaw + 2; | ||
81 | } | ||
82 | |||
83 | static inline int agaw_to_width(int agaw) | ||
84 | { | ||
85 | return 30 + agaw * LEVEL_STRIDE; | ||
86 | } | ||
87 | |||
88 | static inline int width_to_agaw(int width) | ||
89 | { | ||
90 | return (width - 30) / LEVEL_STRIDE; | ||
91 | } | ||
92 | |||
93 | static inline unsigned int level_to_offset_bits(int level) | ||
94 | { | ||
95 | return (level - 1) * LEVEL_STRIDE; | ||
96 | } | ||
97 | |||
98 | static inline int pfn_level_offset(unsigned long pfn, int level) | ||
99 | { | ||
100 | return (pfn >> level_to_offset_bits(level)) & LEVEL_MASK; | ||
101 | } | ||
102 | |||
103 | static inline unsigned long level_mask(int level) | ||
104 | { | ||
105 | return -1UL << level_to_offset_bits(level); | ||
106 | } | ||
107 | |||
108 | static inline unsigned long level_size(int level) | ||
109 | { | ||
110 | return 1UL << level_to_offset_bits(level); | ||
111 | } | ||
112 | |||
113 | static inline unsigned long align_to_level(unsigned long pfn, int level) | ||
114 | { | ||
115 | return (pfn + level_size(level) - 1) & level_mask(level); | ||
116 | } | ||
74 | 117 | ||
75 | /* VT-d pages must always be _smaller_ than MM pages. Otherwise things | 118 | /* VT-d pages must always be _smaller_ than MM pages. Otherwise things |
76 | are never going to work. */ | 119 | are never going to work. */ |
@@ -434,8 +477,6 @@ void free_iova_mem(struct iova *iova) | |||
434 | } | 477 | } |
435 | 478 | ||
436 | 479 | ||
437 | static inline int width_to_agaw(int width); | ||
438 | |||
439 | static int __iommu_calculate_agaw(struct intel_iommu *iommu, int max_gaw) | 480 | static int __iommu_calculate_agaw(struct intel_iommu *iommu, int max_gaw) |
440 | { | 481 | { |
441 | unsigned long sagaw; | 482 | unsigned long sagaw; |
@@ -646,51 +687,6 @@ out: | |||
646 | spin_unlock_irqrestore(&iommu->lock, flags); | 687 | spin_unlock_irqrestore(&iommu->lock, flags); |
647 | } | 688 | } |
648 | 689 | ||
649 | /* page table handling */ | ||
650 | #define LEVEL_STRIDE (9) | ||
651 | #define LEVEL_MASK (((u64)1 << LEVEL_STRIDE) - 1) | ||
652 | |||
653 | static inline int agaw_to_level(int agaw) | ||
654 | { | ||
655 | return agaw + 2; | ||
656 | } | ||
657 | |||
658 | static inline int agaw_to_width(int agaw) | ||
659 | { | ||
660 | return 30 + agaw * LEVEL_STRIDE; | ||
661 | |||
662 | } | ||
663 | |||
664 | static inline int width_to_agaw(int width) | ||
665 | { | ||
666 | return (width - 30) / LEVEL_STRIDE; | ||
667 | } | ||
668 | |||
669 | static inline unsigned int level_to_offset_bits(int level) | ||
670 | { | ||
671 | return (level - 1) * LEVEL_STRIDE; | ||
672 | } | ||
673 | |||
674 | static inline int pfn_level_offset(unsigned long pfn, int level) | ||
675 | { | ||
676 | return (pfn >> level_to_offset_bits(level)) & LEVEL_MASK; | ||
677 | } | ||
678 | |||
679 | static inline unsigned long level_mask(int level) | ||
680 | { | ||
681 | return -1UL << level_to_offset_bits(level); | ||
682 | } | ||
683 | |||
684 | static inline unsigned long level_size(int level) | ||
685 | { | ||
686 | return 1UL << level_to_offset_bits(level); | ||
687 | } | ||
688 | |||
689 | static inline unsigned long align_to_level(unsigned long pfn, int level) | ||
690 | { | ||
691 | return (pfn + level_size(level) - 1) & level_mask(level); | ||
692 | } | ||
693 | |||
694 | static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain, | 690 | static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain, |
695 | unsigned long pfn) | 691 | unsigned long pfn) |
696 | { | 692 | { |
@@ -3761,6 +3757,33 @@ static void __devinit quirk_iommu_rwbf(struct pci_dev *dev) | |||
3761 | 3757 | ||
3762 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf); | 3758 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf); |
3763 | 3759 | ||
3760 | #define GGC 0x52 | ||
3761 | #define GGC_MEMORY_SIZE_MASK (0xf << 8) | ||
3762 | #define GGC_MEMORY_SIZE_NONE (0x0 << 8) | ||
3763 | #define GGC_MEMORY_SIZE_1M (0x1 << 8) | ||
3764 | #define GGC_MEMORY_SIZE_2M (0x3 << 8) | ||
3765 | #define GGC_MEMORY_VT_ENABLED (0x8 << 8) | ||
3766 | #define GGC_MEMORY_SIZE_2M_VT (0x9 << 8) | ||
3767 | #define GGC_MEMORY_SIZE_3M_VT (0xa << 8) | ||
3768 | #define GGC_MEMORY_SIZE_4M_VT (0xb << 8) | ||
3769 | |||
3770 | static void __devinit quirk_calpella_no_shadow_gtt(struct pci_dev *dev) | ||
3771 | { | ||
3772 | unsigned short ggc; | ||
3773 | |||
3774 | if (pci_read_config_word(dev, GGC, &ggc)) | ||
3775 | return; | ||
3776 | |||
3777 | if (!(ggc & GGC_MEMORY_VT_ENABLED)) { | ||
3778 | printk(KERN_INFO "DMAR: BIOS has allocated no shadow GTT; disabling IOMMU for graphics\n"); | ||
3779 | dmar_map_gfx = 0; | ||
3780 | } | ||
3781 | } | ||
3782 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0040, quirk_calpella_no_shadow_gtt); | ||
3783 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0044, quirk_calpella_no_shadow_gtt); | ||
3784 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0062, quirk_calpella_no_shadow_gtt); | ||
3785 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x006a, quirk_calpella_no_shadow_gtt); | ||
3786 | |||
3764 | /* On Tylersburg chipsets, some BIOSes have been known to enable the | 3787 | /* On Tylersburg chipsets, some BIOSes have been known to enable the |
3765 | ISOCH DMAR unit for the Azalia sound device, but not give it any | 3788 | ISOCH DMAR unit for the Azalia sound device, but not give it any |
3766 | TLB entries, which causes it to deadlock. Check for that. We do | 3789 | TLB entries, which causes it to deadlock. Check for that. We do |
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index ce6a3666b3d..553d8ee55c1 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c | |||
@@ -608,7 +608,7 @@ int pci_iov_resource_bar(struct pci_dev *dev, int resno, | |||
608 | * the VF BAR size multiplied by the number of VFs. The alignment | 608 | * the VF BAR size multiplied by the number of VFs. The alignment |
609 | * is just the VF BAR size. | 609 | * is just the VF BAR size. |
610 | */ | 610 | */ |
611 | int pci_sriov_resource_alignment(struct pci_dev *dev, int resno) | 611 | resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno) |
612 | { | 612 | { |
613 | struct resource tmp; | 613 | struct resource tmp; |
614 | enum pci_bar_type type; | 614 | enum pci_bar_type type; |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 679c39de6a8..6beb11b617a 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -140,8 +140,10 @@ static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } | |||
140 | 140 | ||
141 | #ifdef CONFIG_PCIEAER | 141 | #ifdef CONFIG_PCIEAER |
142 | void pci_no_aer(void); | 142 | void pci_no_aer(void); |
143 | bool pci_aer_available(void); | ||
143 | #else | 144 | #else |
144 | static inline void pci_no_aer(void) { } | 145 | static inline void pci_no_aer(void) { } |
146 | static inline bool pci_aer_available(void) { return false; } | ||
145 | #endif | 147 | #endif |
146 | 148 | ||
147 | static inline int pci_no_d1d2(struct pci_dev *dev) | 149 | static inline int pci_no_d1d2(struct pci_dev *dev) |
@@ -262,7 +264,8 @@ extern int pci_iov_init(struct pci_dev *dev); | |||
262 | extern void pci_iov_release(struct pci_dev *dev); | 264 | extern void pci_iov_release(struct pci_dev *dev); |
263 | extern int pci_iov_resource_bar(struct pci_dev *dev, int resno, | 265 | extern int pci_iov_resource_bar(struct pci_dev *dev, int resno, |
264 | enum pci_bar_type *type); | 266 | enum pci_bar_type *type); |
265 | extern int pci_sriov_resource_alignment(struct pci_dev *dev, int resno); | 267 | extern resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, |
268 | int resno); | ||
266 | extern void pci_restore_iov_state(struct pci_dev *dev); | 269 | extern void pci_restore_iov_state(struct pci_dev *dev); |
267 | extern int pci_iov_bus_range(struct pci_bus *bus); | 270 | extern int pci_iov_bus_range(struct pci_bus *bus); |
268 | 271 | ||
@@ -318,7 +321,7 @@ static inline int pci_ats_enabled(struct pci_dev *dev) | |||
318 | } | 321 | } |
319 | #endif /* CONFIG_PCI_IOV */ | 322 | #endif /* CONFIG_PCI_IOV */ |
320 | 323 | ||
321 | static inline int pci_resource_alignment(struct pci_dev *dev, | 324 | static inline resource_size_t pci_resource_alignment(struct pci_dev *dev, |
322 | struct resource *res) | 325 | struct resource *res) |
323 | { | 326 | { |
324 | #ifdef CONFIG_PCI_IOV | 327 | #ifdef CONFIG_PCI_IOV |
diff --git a/drivers/pci/pcie/Makefile b/drivers/pci/pcie/Makefile index ea654545e7c..00c62df5a9f 100644 --- a/drivers/pci/pcie/Makefile +++ b/drivers/pci/pcie/Makefile | |||
@@ -6,10 +6,11 @@ | |||
6 | obj-$(CONFIG_PCIEASPM) += aspm.o | 6 | obj-$(CONFIG_PCIEASPM) += aspm.o |
7 | 7 | ||
8 | pcieportdrv-y := portdrv_core.o portdrv_pci.o portdrv_bus.o | 8 | pcieportdrv-y := portdrv_core.o portdrv_pci.o portdrv_bus.o |
9 | pcieportdrv-$(CONFIG_ACPI) += portdrv_acpi.o | ||
9 | 10 | ||
10 | obj-$(CONFIG_PCIEPORTBUS) += pcieportdrv.o | 11 | obj-$(CONFIG_PCIEPORTBUS) += pcieportdrv.o |
11 | 12 | ||
12 | # Build PCI Express AER if needed | 13 | # Build PCI Express AER if needed |
13 | obj-$(CONFIG_PCIEAER) += aer/ | 14 | obj-$(CONFIG_PCIEAER) += aer/ |
14 | 15 | ||
15 | obj-$(CONFIG_PCIE_PME) += pme/ | 16 | obj-$(CONFIG_PCIE_PME) += pme.o |
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c index 484cc55194b..f409948e1a9 100644 --- a/drivers/pci/pcie/aer/aerdrv.c +++ b/drivers/pci/pcie/aer/aerdrv.c | |||
@@ -72,6 +72,11 @@ void pci_no_aer(void) | |||
72 | pcie_aer_disable = 1; /* has priority over 'forceload' */ | 72 | pcie_aer_disable = 1; /* has priority over 'forceload' */ |
73 | } | 73 | } |
74 | 74 | ||
75 | bool pci_aer_available(void) | ||
76 | { | ||
77 | return !pcie_aer_disable && pci_msi_enabled(); | ||
78 | } | ||
79 | |||
75 | static int set_device_error_reporting(struct pci_dev *dev, void *data) | 80 | static int set_device_error_reporting(struct pci_dev *dev, void *data) |
76 | { | 81 | { |
77 | bool enable = *((bool *)data); | 82 | bool enable = *((bool *)data); |
@@ -411,9 +416,7 @@ static void aer_error_resume(struct pci_dev *dev) | |||
411 | */ | 416 | */ |
412 | static int __init aer_service_init(void) | 417 | static int __init aer_service_init(void) |
413 | { | 418 | { |
414 | if (pcie_aer_disable) | 419 | if (!pci_aer_available()) |
415 | return -ENXIO; | ||
416 | if (!pci_msi_enabled()) | ||
417 | return -ENXIO; | 420 | return -ENXIO; |
418 | return pcie_port_service_register(&aerdriver); | 421 | return pcie_port_service_register(&aerdriver); |
419 | } | 422 | } |
diff --git a/drivers/pci/pcie/aer/aerdrv_acpi.c b/drivers/pci/pcie/aer/aerdrv_acpi.c index f278d7b0d95..2bb9b897221 100644 --- a/drivers/pci/pcie/aer/aerdrv_acpi.c +++ b/drivers/pci/pcie/aer/aerdrv_acpi.c | |||
@@ -19,42 +19,6 @@ | |||
19 | #include <acpi/apei.h> | 19 | #include <acpi/apei.h> |
20 | #include "aerdrv.h" | 20 | #include "aerdrv.h" |
21 | 21 | ||
22 | /** | ||
23 | * aer_osc_setup - run ACPI _OSC method | ||
24 | * @pciedev: pcie_device which AER is being enabled on | ||
25 | * | ||
26 | * @return: Zero on success. Nonzero otherwise. | ||
27 | * | ||
28 | * Invoked when PCIe bus loads AER service driver. To avoid conflict with | ||
29 | * BIOS AER support requires BIOS to yield AER control to OS native driver. | ||
30 | **/ | ||
31 | int aer_osc_setup(struct pcie_device *pciedev) | ||
32 | { | ||
33 | acpi_status status = AE_NOT_FOUND; | ||
34 | struct pci_dev *pdev = pciedev->port; | ||
35 | acpi_handle handle = NULL; | ||
36 | |||
37 | if (acpi_pci_disabled) | ||
38 | return -1; | ||
39 | |||
40 | handle = acpi_find_root_bridge_handle(pdev); | ||
41 | if (handle) { | ||
42 | status = acpi_pci_osc_control_set(handle, | ||
43 | OSC_PCI_EXPRESS_AER_CONTROL | | ||
44 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); | ||
45 | } | ||
46 | |||
47 | if (ACPI_FAILURE(status)) { | ||
48 | dev_printk(KERN_DEBUG, &pciedev->device, "AER service couldn't " | ||
49 | "init device: %s\n", | ||
50 | (status == AE_SUPPORT || status == AE_NOT_FOUND) ? | ||
51 | "no _OSC support" : "_OSC failed"); | ||
52 | return -1; | ||
53 | } | ||
54 | |||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | #ifdef CONFIG_ACPI_APEI | 22 | #ifdef CONFIG_ACPI_APEI |
59 | static inline int hest_match_pci(struct acpi_hest_aer_common *p, | 23 | static inline int hest_match_pci(struct acpi_hest_aer_common *p, |
60 | struct pci_dev *pci) | 24 | struct pci_dev *pci) |
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index fc0b5a93e1d..29e268fadf1 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c | |||
@@ -772,22 +772,10 @@ void aer_isr(struct work_struct *work) | |||
772 | */ | 772 | */ |
773 | int aer_init(struct pcie_device *dev) | 773 | int aer_init(struct pcie_device *dev) |
774 | { | 774 | { |
775 | if (pcie_aer_get_firmware_first(dev->port)) { | ||
776 | dev_printk(KERN_DEBUG, &dev->device, | ||
777 | "PCIe errors handled by platform firmware.\n"); | ||
778 | goto out; | ||
779 | } | ||
780 | |||
781 | if (aer_osc_setup(dev)) | ||
782 | goto out; | ||
783 | |||
784 | return 0; | ||
785 | out: | ||
786 | if (forceload) { | 775 | if (forceload) { |
787 | dev_printk(KERN_DEBUG, &dev->device, | 776 | dev_printk(KERN_DEBUG, &dev->device, |
788 | "aerdrv forceload requested.\n"); | 777 | "aerdrv forceload requested.\n"); |
789 | pcie_aer_force_firmware_first(dev->port, 0); | 778 | pcie_aer_force_firmware_first(dev->port, 0); |
790 | return 0; | ||
791 | } | 779 | } |
792 | return -ENXIO; | 780 | return 0; |
793 | } | 781 | } |
diff --git a/drivers/pci/pcie/pme/pcie_pme.c b/drivers/pci/pcie/pme.c index bbdea18693d..2f3c9040722 100644 --- a/drivers/pci/pcie/pme/pcie_pme.c +++ b/drivers/pci/pcie/pme.c | |||
@@ -23,38 +23,13 @@ | |||
23 | #include <linux/pci-acpi.h> | 23 | #include <linux/pci-acpi.h> |
24 | #include <linux/pm_runtime.h> | 24 | #include <linux/pm_runtime.h> |
25 | 25 | ||
26 | #include "../../pci.h" | 26 | #include "../pci.h" |
27 | #include "pcie_pme.h" | 27 | #include "portdrv.h" |
28 | 28 | ||
29 | #define PCI_EXP_RTSTA_PME 0x10000 /* PME status */ | 29 | #define PCI_EXP_RTSTA_PME 0x10000 /* PME status */ |
30 | #define PCI_EXP_RTSTA_PENDING 0x20000 /* PME pending */ | 30 | #define PCI_EXP_RTSTA_PENDING 0x20000 /* PME pending */ |
31 | 31 | ||
32 | /* | 32 | /* |
33 | * If set, this switch will prevent the PCIe root port PME service driver from | ||
34 | * being registered. Consequently, the interrupt-based PCIe PME signaling will | ||
35 | * not be used by any PCIe root ports in that case. | ||
36 | */ | ||
37 | static bool pcie_pme_disabled = true; | ||
38 | |||
39 | /* | ||
40 | * The PCI Express Base Specification 2.0, Section 6.1.8, states the following: | ||
41 | * "In order to maintain compatibility with non-PCI Express-aware system | ||
42 | * software, system power management logic must be configured by firmware to use | ||
43 | * the legacy mechanism of signaling PME by default. PCI Express-aware system | ||
44 | * software must notify the firmware prior to enabling native, interrupt-based | ||
45 | * PME signaling." However, if the platform doesn't provide us with a suitable | ||
46 | * notification mechanism or the notification fails, it is not clear whether or | ||
47 | * not we are supposed to use the interrupt-based PCIe PME signaling. The | ||
48 | * switch below can be used to indicate the desired behaviour. When set, it | ||
49 | * will make the kernel use the interrupt-based PCIe PME signaling regardless of | ||
50 | * the platform notification status, although the kernel will attempt to notify | ||
51 | * the platform anyway. When unset, it will prevent the kernel from using the | ||
52 | * the interrupt-based PCIe PME signaling if the platform notification fails, | ||
53 | * which is the default. | ||
54 | */ | ||
55 | static bool pcie_pme_force_enable; | ||
56 | |||
57 | /* | ||
58 | * If this switch is set, MSI will not be used for PCIe PME signaling. This | 33 | * If this switch is set, MSI will not be used for PCIe PME signaling. This |
59 | * causes the PCIe port driver to use INTx interrupts only, but it turns out | 34 | * causes the PCIe port driver to use INTx interrupts only, but it turns out |
60 | * that using MSI for PCIe PME signaling doesn't play well with PCIe PME-based | 35 | * that using MSI for PCIe PME signaling doesn't play well with PCIe PME-based |
@@ -64,38 +39,13 @@ bool pcie_pme_msi_disabled; | |||
64 | 39 | ||
65 | static int __init pcie_pme_setup(char *str) | 40 | static int __init pcie_pme_setup(char *str) |
66 | { | 41 | { |
67 | if (!strncmp(str, "auto", 4)) | 42 | if (!strncmp(str, "nomsi", 5)) |
68 | pcie_pme_disabled = false; | 43 | pcie_pme_msi_disabled = true; |
69 | else if (!strncmp(str, "force", 5)) | ||
70 | pcie_pme_force_enable = true; | ||
71 | |||
72 | str = strchr(str, ','); | ||
73 | if (str) { | ||
74 | str++; | ||
75 | str += strspn(str, " \t"); | ||
76 | if (*str && !strcmp(str, "nomsi")) | ||
77 | pcie_pme_msi_disabled = true; | ||
78 | } | ||
79 | 44 | ||
80 | return 1; | 45 | return 1; |
81 | } | 46 | } |
82 | __setup("pcie_pme=", pcie_pme_setup); | 47 | __setup("pcie_pme=", pcie_pme_setup); |
83 | 48 | ||
84 | /** | ||
85 | * pcie_pme_platform_setup - Ensure that the kernel controls the PCIe PME. | ||
86 | * @srv: PCIe PME root port service to use for carrying out the check. | ||
87 | * | ||
88 | * Notify the platform that the native PCIe PME is going to be used and return | ||
89 | * 'true' if the control of the PCIe PME registers has been acquired from the | ||
90 | * platform. | ||
91 | */ | ||
92 | static bool pcie_pme_platform_setup(struct pcie_device *srv) | ||
93 | { | ||
94 | if (!pcie_pme_platform_notify(srv)) | ||
95 | return true; | ||
96 | return pcie_pme_force_enable; | ||
97 | } | ||
98 | |||
99 | struct pcie_pme_service_data { | 49 | struct pcie_pme_service_data { |
100 | spinlock_t lock; | 50 | spinlock_t lock; |
101 | struct pcie_device *srv; | 51 | struct pcie_device *srv; |
@@ -108,7 +58,7 @@ struct pcie_pme_service_data { | |||
108 | * @dev: PCIe root port or event collector. | 58 | * @dev: PCIe root port or event collector. |
109 | * @enable: Enable or disable the interrupt. | 59 | * @enable: Enable or disable the interrupt. |
110 | */ | 60 | */ |
111 | static void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable) | 61 | void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable) |
112 | { | 62 | { |
113 | int rtctl_pos; | 63 | int rtctl_pos; |
114 | u16 rtctl; | 64 | u16 rtctl; |
@@ -417,9 +367,6 @@ static int pcie_pme_probe(struct pcie_device *srv) | |||
417 | struct pcie_pme_service_data *data; | 367 | struct pcie_pme_service_data *data; |
418 | int ret; | 368 | int ret; |
419 | 369 | ||
420 | if (!pcie_pme_platform_setup(srv)) | ||
421 | return -EACCES; | ||
422 | |||
423 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 370 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
424 | if (!data) | 371 | if (!data) |
425 | return -ENOMEM; | 372 | return -ENOMEM; |
@@ -509,8 +456,7 @@ static struct pcie_port_service_driver pcie_pme_driver = { | |||
509 | */ | 456 | */ |
510 | static int __init pcie_pme_service_init(void) | 457 | static int __init pcie_pme_service_init(void) |
511 | { | 458 | { |
512 | return pcie_pme_disabled ? | 459 | return pcie_port_service_register(&pcie_pme_driver); |
513 | -ENODEV : pcie_port_service_register(&pcie_pme_driver); | ||
514 | } | 460 | } |
515 | 461 | ||
516 | module_init(pcie_pme_service_init); | 462 | module_init(pcie_pme_service_init); |
diff --git a/drivers/pci/pcie/pme/Makefile b/drivers/pci/pcie/pme/Makefile deleted file mode 100644 index 8b923805308..00000000000 --- a/drivers/pci/pcie/pme/Makefile +++ /dev/null | |||
@@ -1,8 +0,0 @@ | |||
1 | # | ||
2 | # Makefile for PCI-Express Root Port PME signaling driver | ||
3 | # | ||
4 | |||
5 | obj-$(CONFIG_PCIE_PME) += pmedriver.o | ||
6 | |||
7 | pmedriver-objs := pcie_pme.o | ||
8 | pmedriver-$(CONFIG_ACPI) += pcie_pme_acpi.o | ||
diff --git a/drivers/pci/pcie/pme/pcie_pme.h b/drivers/pci/pcie/pme/pcie_pme.h deleted file mode 100644 index b30d2b7c977..00000000000 --- a/drivers/pci/pcie/pme/pcie_pme.h +++ /dev/null | |||
@@ -1,28 +0,0 @@ | |||
1 | /* | ||
2 | * drivers/pci/pcie/pme/pcie_pme.h | ||
3 | * | ||
4 | * PCI Express Root Port PME signaling support | ||
5 | * | ||
6 | * Copyright (C) 2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc. | ||
7 | */ | ||
8 | |||
9 | #ifndef _PCIE_PME_H_ | ||
10 | #define _PCIE_PME_H_ | ||
11 | |||
12 | struct pcie_device; | ||
13 | |||
14 | #ifdef CONFIG_ACPI | ||
15 | extern int pcie_pme_acpi_setup(struct pcie_device *srv); | ||
16 | |||
17 | static inline int pcie_pme_platform_notify(struct pcie_device *srv) | ||
18 | { | ||
19 | return pcie_pme_acpi_setup(srv); | ||
20 | } | ||
21 | #else /* !CONFIG_ACPI */ | ||
22 | static inline int pcie_pme_platform_notify(struct pcie_device *srv) | ||
23 | { | ||
24 | return 0; | ||
25 | } | ||
26 | #endif /* !CONFIG_ACPI */ | ||
27 | |||
28 | #endif | ||
diff --git a/drivers/pci/pcie/pme/pcie_pme_acpi.c b/drivers/pci/pcie/pme/pcie_pme_acpi.c deleted file mode 100644 index 83ab2287ae3..00000000000 --- a/drivers/pci/pcie/pme/pcie_pme_acpi.c +++ /dev/null | |||
@@ -1,54 +0,0 @@ | |||
1 | /* | ||
2 | * PCIe Native PME support, ACPI-related part | ||
3 | * | ||
4 | * Copyright (C) 2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc. | ||
5 | * | ||
6 | * This file is subject to the terms and conditions of the GNU General Public | ||
7 | * License V2. See the file "COPYING" in the main directory of this archive | ||
8 | * for more details. | ||
9 | */ | ||
10 | |||
11 | #include <linux/pci.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/errno.h> | ||
14 | #include <linux/acpi.h> | ||
15 | #include <linux/pci-acpi.h> | ||
16 | #include <linux/pcieport_if.h> | ||
17 | |||
18 | /** | ||
19 | * pcie_pme_acpi_setup - Request the ACPI BIOS to release control over PCIe PME. | ||
20 | * @srv - PCIe PME service for a root port or event collector. | ||
21 | * | ||
22 | * Invoked when the PCIe bus type loads PCIe PME service driver. To avoid | ||
23 | * conflict with the BIOS PCIe support requires the BIOS to yield PCIe PME | ||
24 | * control to the kernel. | ||
25 | */ | ||
26 | int pcie_pme_acpi_setup(struct pcie_device *srv) | ||
27 | { | ||
28 | acpi_status status = AE_NOT_FOUND; | ||
29 | struct pci_dev *port = srv->port; | ||
30 | acpi_handle handle; | ||
31 | int error = 0; | ||
32 | |||
33 | if (acpi_pci_disabled) | ||
34 | return -ENOSYS; | ||
35 | |||
36 | dev_info(&port->dev, "Requesting control of PCIe PME from ACPI BIOS\n"); | ||
37 | |||
38 | handle = acpi_find_root_bridge_handle(port); | ||
39 | if (!handle) | ||
40 | return -EINVAL; | ||
41 | |||
42 | status = acpi_pci_osc_control_set(handle, | ||
43 | OSC_PCI_EXPRESS_PME_CONTROL | | ||
44 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); | ||
45 | if (ACPI_FAILURE(status)) { | ||
46 | dev_info(&port->dev, | ||
47 | "Failed to receive control of PCIe PME service: %s\n", | ||
48 | (status == AE_SUPPORT || status == AE_NOT_FOUND) ? | ||
49 | "no _OSC support" : "ACPI _OSC failed"); | ||
50 | error = -ENODEV; | ||
51 | } | ||
52 | |||
53 | return error; | ||
54 | } | ||
diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h index 813a5c3427b..7b5aba0a329 100644 --- a/drivers/pci/pcie/portdrv.h +++ b/drivers/pci/pcie/portdrv.h | |||
@@ -20,6 +20,9 @@ | |||
20 | 20 | ||
21 | #define get_descriptor_id(type, service) (((type - 4) << 4) | service) | 21 | #define get_descriptor_id(type, service) (((type - 4) << 4) | service) |
22 | 22 | ||
23 | extern bool pcie_ports_disabled; | ||
24 | extern bool pcie_ports_auto; | ||
25 | |||
23 | extern struct bus_type pcie_port_bus_type; | 26 | extern struct bus_type pcie_port_bus_type; |
24 | extern int pcie_port_device_register(struct pci_dev *dev); | 27 | extern int pcie_port_device_register(struct pci_dev *dev); |
25 | #ifdef CONFIG_PM | 28 | #ifdef CONFIG_PM |
@@ -30,6 +33,8 @@ extern void pcie_port_device_remove(struct pci_dev *dev); | |||
30 | extern int __must_check pcie_port_bus_register(void); | 33 | extern int __must_check pcie_port_bus_register(void); |
31 | extern void pcie_port_bus_unregister(void); | 34 | extern void pcie_port_bus_unregister(void); |
32 | 35 | ||
36 | struct pci_dev; | ||
37 | |||
33 | #ifdef CONFIG_PCIE_PME | 38 | #ifdef CONFIG_PCIE_PME |
34 | extern bool pcie_pme_msi_disabled; | 39 | extern bool pcie_pme_msi_disabled; |
35 | 40 | ||
@@ -42,9 +47,26 @@ static inline bool pcie_pme_no_msi(void) | |||
42 | { | 47 | { |
43 | return pcie_pme_msi_disabled; | 48 | return pcie_pme_msi_disabled; |
44 | } | 49 | } |
50 | |||
51 | extern void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable); | ||
45 | #else /* !CONFIG_PCIE_PME */ | 52 | #else /* !CONFIG_PCIE_PME */ |
46 | static inline void pcie_pme_disable_msi(void) {} | 53 | static inline void pcie_pme_disable_msi(void) {} |
47 | static inline bool pcie_pme_no_msi(void) { return false; } | 54 | static inline bool pcie_pme_no_msi(void) { return false; } |
55 | static inline void pcie_pme_interrupt_enable(struct pci_dev *dev, bool en) {} | ||
48 | #endif /* !CONFIG_PCIE_PME */ | 56 | #endif /* !CONFIG_PCIE_PME */ |
49 | 57 | ||
58 | #ifdef CONFIG_ACPI | ||
59 | extern int pcie_port_acpi_setup(struct pci_dev *port, int *mask); | ||
60 | |||
61 | static inline int pcie_port_platform_notify(struct pci_dev *port, int *mask) | ||
62 | { | ||
63 | return pcie_port_acpi_setup(port, mask); | ||
64 | } | ||
65 | #else /* !CONFIG_ACPI */ | ||
66 | static inline int pcie_port_platform_notify(struct pci_dev *port, int *mask) | ||
67 | { | ||
68 | return 0; | ||
69 | } | ||
70 | #endif /* !CONFIG_ACPI */ | ||
71 | |||
50 | #endif /* _PORTDRV_H_ */ | 72 | #endif /* _PORTDRV_H_ */ |
diff --git a/drivers/pci/pcie/portdrv_acpi.c b/drivers/pci/pcie/portdrv_acpi.c new file mode 100644 index 00000000000..b7c4cb1ccb2 --- /dev/null +++ b/drivers/pci/pcie/portdrv_acpi.c | |||
@@ -0,0 +1,77 @@ | |||
1 | /* | ||
2 | * PCIe Port Native Services Support, ACPI-Related Part | ||
3 | * | ||
4 | * Copyright (C) 2010 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc. | ||
5 | * | ||
6 | * This file is subject to the terms and conditions of the GNU General Public | ||
7 | * License V2. See the file "COPYING" in the main directory of this archive | ||
8 | * for more details. | ||
9 | */ | ||
10 | |||
11 | #include <linux/pci.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/errno.h> | ||
14 | #include <linux/acpi.h> | ||
15 | #include <linux/pci-acpi.h> | ||
16 | #include <linux/pcieport_if.h> | ||
17 | |||
18 | #include "aer/aerdrv.h" | ||
19 | #include "../pci.h" | ||
20 | |||
21 | /** | ||
22 | * pcie_port_acpi_setup - Request the BIOS to release control of PCIe services. | ||
23 | * @port: PCIe Port service for a root port or event collector. | ||
24 | * @srv_mask: Bit mask of services that can be enabled for @port. | ||
25 | * | ||
26 | * Invoked when @port is identified as a PCIe port device. To avoid conflicts | ||
27 | * with the BIOS PCIe port native services support requires the BIOS to yield | ||
28 | * control of these services to the kernel. The mask of services that the BIOS | ||
29 | * allows to be enabled for @port is written to @srv_mask. | ||
30 | * | ||
31 | * NOTE: It turns out that we cannot do that for individual port services | ||
32 | * separately, because that would make some systems work incorrectly. | ||
33 | */ | ||
34 | int pcie_port_acpi_setup(struct pci_dev *port, int *srv_mask) | ||
35 | { | ||
36 | acpi_status status; | ||
37 | acpi_handle handle; | ||
38 | u32 flags; | ||
39 | |||
40 | if (acpi_pci_disabled) | ||
41 | return 0; | ||
42 | |||
43 | handle = acpi_find_root_bridge_handle(port); | ||
44 | if (!handle) | ||
45 | return -EINVAL; | ||
46 | |||
47 | flags = OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL | ||
48 | | OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | ||
49 | | OSC_PCI_EXPRESS_PME_CONTROL; | ||
50 | |||
51 | if (pci_aer_available()) { | ||
52 | if (pcie_aer_get_firmware_first(port)) | ||
53 | dev_dbg(&port->dev, "PCIe errors handled by BIOS.\n"); | ||
54 | else | ||
55 | flags |= OSC_PCI_EXPRESS_AER_CONTROL; | ||
56 | } | ||
57 | |||
58 | status = acpi_pci_osc_control_set(handle, &flags, | ||
59 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); | ||
60 | if (ACPI_FAILURE(status)) { | ||
61 | dev_dbg(&port->dev, "ACPI _OSC request failed (code %d)\n", | ||
62 | status); | ||
63 | return -ENODEV; | ||
64 | } | ||
65 | |||
66 | dev_info(&port->dev, "ACPI _OSC control granted for 0x%02x\n", flags); | ||
67 | |||
68 | *srv_mask = PCIE_PORT_SERVICE_VC; | ||
69 | if (flags & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL) | ||
70 | *srv_mask |= PCIE_PORT_SERVICE_HP; | ||
71 | if (flags & OSC_PCI_EXPRESS_PME_CONTROL) | ||
72 | *srv_mask |= PCIE_PORT_SERVICE_PME; | ||
73 | if (flags & OSC_PCI_EXPRESS_AER_CONTROL) | ||
74 | *srv_mask |= PCIE_PORT_SERVICE_AER; | ||
75 | |||
76 | return 0; | ||
77 | } | ||
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index e73effbe402..a9c222d79eb 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c | |||
@@ -14,6 +14,8 @@ | |||
14 | #include <linux/string.h> | 14 | #include <linux/string.h> |
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/pcieport_if.h> | 16 | #include <linux/pcieport_if.h> |
17 | #include <linux/aer.h> | ||
18 | #include <linux/pci-aspm.h> | ||
17 | 19 | ||
18 | #include "../pci.h" | 20 | #include "../pci.h" |
19 | #include "portdrv.h" | 21 | #include "portdrv.h" |
@@ -236,24 +238,64 @@ static int get_port_device_capability(struct pci_dev *dev) | |||
236 | int services = 0, pos; | 238 | int services = 0, pos; |
237 | u16 reg16; | 239 | u16 reg16; |
238 | u32 reg32; | 240 | u32 reg32; |
241 | int cap_mask; | ||
242 | int err; | ||
243 | |||
244 | err = pcie_port_platform_notify(dev, &cap_mask); | ||
245 | if (pcie_ports_auto) { | ||
246 | if (err) { | ||
247 | pcie_no_aspm(); | ||
248 | return 0; | ||
249 | } | ||
250 | } else { | ||
251 | cap_mask = PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP | ||
252 | | PCIE_PORT_SERVICE_VC; | ||
253 | if (pci_aer_available()) | ||
254 | cap_mask |= PCIE_PORT_SERVICE_AER; | ||
255 | } | ||
239 | 256 | ||
240 | pos = pci_pcie_cap(dev); | 257 | pos = pci_pcie_cap(dev); |
241 | pci_read_config_word(dev, pos + PCI_EXP_FLAGS, ®16); | 258 | pci_read_config_word(dev, pos + PCI_EXP_FLAGS, ®16); |
242 | /* Hot-Plug Capable */ | 259 | /* Hot-Plug Capable */ |
243 | if (reg16 & PCI_EXP_FLAGS_SLOT) { | 260 | if ((cap_mask & PCIE_PORT_SERVICE_HP) && (reg16 & PCI_EXP_FLAGS_SLOT)) { |
244 | pci_read_config_dword(dev, pos + PCI_EXP_SLTCAP, ®32); | 261 | pci_read_config_dword(dev, pos + PCI_EXP_SLTCAP, ®32); |
245 | if (reg32 & PCI_EXP_SLTCAP_HPC) | 262 | if (reg32 & PCI_EXP_SLTCAP_HPC) { |
246 | services |= PCIE_PORT_SERVICE_HP; | 263 | services |= PCIE_PORT_SERVICE_HP; |
264 | /* | ||
265 | * Disable hot-plug interrupts in case they have been | ||
266 | * enabled by the BIOS and the hot-plug service driver | ||
267 | * is not loaded. | ||
268 | */ | ||
269 | pos += PCI_EXP_SLTCTL; | ||
270 | pci_read_config_word(dev, pos, ®16); | ||
271 | reg16 &= ~(PCI_EXP_SLTCTL_CCIE | PCI_EXP_SLTCTL_HPIE); | ||
272 | pci_write_config_word(dev, pos, reg16); | ||
273 | } | ||
247 | } | 274 | } |
248 | /* AER capable */ | 275 | /* AER capable */ |
249 | if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR)) | 276 | if ((cap_mask & PCIE_PORT_SERVICE_AER) |
277 | && pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR)) { | ||
250 | services |= PCIE_PORT_SERVICE_AER; | 278 | services |= PCIE_PORT_SERVICE_AER; |
279 | /* | ||
280 | * Disable AER on this port in case it's been enabled by the | ||
281 | * BIOS (the AER service driver will enable it when necessary). | ||
282 | */ | ||
283 | pci_disable_pcie_error_reporting(dev); | ||
284 | } | ||
251 | /* VC support */ | 285 | /* VC support */ |
252 | if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_VC)) | 286 | if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_VC)) |
253 | services |= PCIE_PORT_SERVICE_VC; | 287 | services |= PCIE_PORT_SERVICE_VC; |
254 | /* Root ports are capable of generating PME too */ | 288 | /* Root ports are capable of generating PME too */ |
255 | if (dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) | 289 | if ((cap_mask & PCIE_PORT_SERVICE_PME) |
290 | && dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) { | ||
256 | services |= PCIE_PORT_SERVICE_PME; | 291 | services |= PCIE_PORT_SERVICE_PME; |
292 | /* | ||
293 | * Disable PME interrupt on this port in case it's been enabled | ||
294 | * by the BIOS (the PME service driver will enable it when | ||
295 | * necessary). | ||
296 | */ | ||
297 | pcie_pme_interrupt_enable(dev, false); | ||
298 | } | ||
257 | 299 | ||
258 | return services; | 300 | return services; |
259 | } | 301 | } |
@@ -494,6 +536,9 @@ static void pcie_port_shutdown_service(struct device *dev) {} | |||
494 | */ | 536 | */ |
495 | int pcie_port_service_register(struct pcie_port_service_driver *new) | 537 | int pcie_port_service_register(struct pcie_port_service_driver *new) |
496 | { | 538 | { |
539 | if (pcie_ports_disabled) | ||
540 | return -ENODEV; | ||
541 | |||
497 | new->driver.name = (char *)new->name; | 542 | new->driver.name = (char *)new->name; |
498 | new->driver.bus = &pcie_port_bus_type; | 543 | new->driver.bus = &pcie_port_bus_type; |
499 | new->driver.probe = pcie_port_probe_service; | 544 | new->driver.probe = pcie_port_probe_service; |
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index 3debed25e46..f9033e190fb 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/pcieport_if.h> | 15 | #include <linux/pcieport_if.h> |
16 | #include <linux/aer.h> | 16 | #include <linux/aer.h> |
17 | #include <linux/dmi.h> | 17 | #include <linux/dmi.h> |
18 | #include <linux/pci-aspm.h> | ||
18 | 19 | ||
19 | #include "portdrv.h" | 20 | #include "portdrv.h" |
20 | #include "aer/aerdrv.h" | 21 | #include "aer/aerdrv.h" |
@@ -29,6 +30,31 @@ MODULE_AUTHOR(DRIVER_AUTHOR); | |||
29 | MODULE_DESCRIPTION(DRIVER_DESC); | 30 | MODULE_DESCRIPTION(DRIVER_DESC); |
30 | MODULE_LICENSE("GPL"); | 31 | MODULE_LICENSE("GPL"); |
31 | 32 | ||
33 | /* If this switch is set, PCIe port native services should not be enabled. */ | ||
34 | bool pcie_ports_disabled; | ||
35 | |||
36 | /* | ||
37 | * If this switch is set, ACPI _OSC will be used to determine whether or not to | ||
38 | * enable PCIe port native services. | ||
39 | */ | ||
40 | bool pcie_ports_auto = true; | ||
41 | |||
42 | static int __init pcie_port_setup(char *str) | ||
43 | { | ||
44 | if (!strncmp(str, "compat", 6)) { | ||
45 | pcie_ports_disabled = true; | ||
46 | } else if (!strncmp(str, "native", 6)) { | ||
47 | pcie_ports_disabled = false; | ||
48 | pcie_ports_auto = false; | ||
49 | } else if (!strncmp(str, "auto", 4)) { | ||
50 | pcie_ports_disabled = false; | ||
51 | pcie_ports_auto = true; | ||
52 | } | ||
53 | |||
54 | return 1; | ||
55 | } | ||
56 | __setup("pcie_ports=", pcie_port_setup); | ||
57 | |||
32 | /* global data */ | 58 | /* global data */ |
33 | 59 | ||
34 | static int pcie_portdrv_restore_config(struct pci_dev *dev) | 60 | static int pcie_portdrv_restore_config(struct pci_dev *dev) |
@@ -301,6 +327,11 @@ static int __init pcie_portdrv_init(void) | |||
301 | { | 327 | { |
302 | int retval; | 328 | int retval; |
303 | 329 | ||
330 | if (pcie_ports_disabled) { | ||
331 | pcie_no_aspm(); | ||
332 | return -EACCES; | ||
333 | } | ||
334 | |||
304 | dmi_check_system(pcie_portdrv_dmi_table); | 335 | dmi_check_system(pcie_portdrv_dmi_table); |
305 | 336 | ||
306 | retval = pcie_port_bus_register(); | 337 | retval = pcie_port_bus_register(); |
@@ -315,11 +346,4 @@ static int __init pcie_portdrv_init(void) | |||
315 | return retval; | 346 | return retval; |
316 | } | 347 | } |
317 | 348 | ||
318 | static void __exit pcie_portdrv_exit(void) | ||
319 | { | ||
320 | pci_unregister_driver(&pcie_portdriver); | ||
321 | pcie_port_bus_unregister(); | ||
322 | } | ||
323 | |||
324 | module_init(pcie_portdrv_init); | 349 | module_init(pcie_portdrv_init); |
325 | module_exit(pcie_portdrv_exit); | ||
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 89ed181cd90..857ae01734a 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -163,6 +163,26 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_2, quirk_isa_d | |||
163 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_3, quirk_isa_dma_hangs); | 163 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_3, quirk_isa_dma_hangs); |
164 | 164 | ||
165 | /* | 165 | /* |
166 | * Intel NM10 "TigerPoint" LPC PM1a_STS.BM_STS must be clear | ||
167 | * for some HT machines to use C4 w/o hanging. | ||
168 | */ | ||
169 | static void __devinit quirk_tigerpoint_bm_sts(struct pci_dev *dev) | ||
170 | { | ||
171 | u32 pmbase; | ||
172 | u16 pm1a; | ||
173 | |||
174 | pci_read_config_dword(dev, 0x40, &pmbase); | ||
175 | pmbase = pmbase & 0xff80; | ||
176 | pm1a = inw(pmbase); | ||
177 | |||
178 | if (pm1a & 0x10) { | ||
179 | dev_info(&dev->dev, FW_BUG "TigerPoint LPC.BM_STS cleared\n"); | ||
180 | outw(0x10, pmbase); | ||
181 | } | ||
182 | } | ||
183 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TGP_LPC, quirk_tigerpoint_bm_sts); | ||
184 | |||
185 | /* | ||
166 | * Chipsets where PCI->PCI transfers vanish or hang | 186 | * Chipsets where PCI->PCI transfers vanish or hang |
167 | */ | 187 | */ |
168 | static void __devinit quirk_nopcipci(struct pci_dev *dev) | 188 | static void __devinit quirk_nopcipci(struct pci_dev *dev) |
diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c index 659eaa0fc48..968cfea04f7 100644 --- a/drivers/pci/slot.c +++ b/drivers/pci/slot.c | |||
@@ -49,7 +49,7 @@ static ssize_t address_read_file(struct pci_slot *slot, char *buf) | |||
49 | } | 49 | } |
50 | 50 | ||
51 | /* these strings match up with the values in pci_bus_speed */ | 51 | /* these strings match up with the values in pci_bus_speed */ |
52 | static char *pci_bus_speed_strings[] = { | 52 | static const char *pci_bus_speed_strings[] = { |
53 | "33 MHz PCI", /* 0x00 */ | 53 | "33 MHz PCI", /* 0x00 */ |
54 | "66 MHz PCI", /* 0x01 */ | 54 | "66 MHz PCI", /* 0x01 */ |
55 | "66 MHz PCI-X", /* 0x02 */ | 55 | "66 MHz PCI-X", /* 0x02 */ |
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index 54aa1c238cb..9ba4dade69a 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c | |||
@@ -163,7 +163,7 @@ static int pcmcia_access_config(struct pcmcia_device *p_dev, | |||
163 | c = p_dev->function_config; | 163 | c = p_dev->function_config; |
164 | 164 | ||
165 | if (!(c->state & CONFIG_LOCKED)) { | 165 | if (!(c->state & CONFIG_LOCKED)) { |
166 | dev_dbg(&s->dev, "Configuration isnt't locked\n"); | 166 | dev_dbg(&p_dev->dev, "Configuration isnt't locked\n"); |
167 | mutex_unlock(&s->ops_mutex); | 167 | mutex_unlock(&s->ops_mutex); |
168 | return -EACCES; | 168 | return -EACCES; |
169 | } | 169 | } |
@@ -220,7 +220,7 @@ int pcmcia_map_mem_page(struct pcmcia_device *p_dev, window_handle_t wh, | |||
220 | s->win[w].card_start = offset; | 220 | s->win[w].card_start = offset; |
221 | ret = s->ops->set_mem_map(s, &s->win[w]); | 221 | ret = s->ops->set_mem_map(s, &s->win[w]); |
222 | if (ret) | 222 | if (ret) |
223 | dev_warn(&s->dev, "failed to set_mem_map\n"); | 223 | dev_warn(&p_dev->dev, "failed to set_mem_map\n"); |
224 | mutex_unlock(&s->ops_mutex); | 224 | mutex_unlock(&s->ops_mutex); |
225 | return ret; | 225 | return ret; |
226 | } /* pcmcia_map_mem_page */ | 226 | } /* pcmcia_map_mem_page */ |
@@ -244,18 +244,18 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev, | |||
244 | c = p_dev->function_config; | 244 | c = p_dev->function_config; |
245 | 245 | ||
246 | if (!(s->state & SOCKET_PRESENT)) { | 246 | if (!(s->state & SOCKET_PRESENT)) { |
247 | dev_dbg(&s->dev, "No card present\n"); | 247 | dev_dbg(&p_dev->dev, "No card present\n"); |
248 | ret = -ENODEV; | 248 | ret = -ENODEV; |
249 | goto unlock; | 249 | goto unlock; |
250 | } | 250 | } |
251 | if (!(c->state & CONFIG_LOCKED)) { | 251 | if (!(c->state & CONFIG_LOCKED)) { |
252 | dev_dbg(&s->dev, "Configuration isnt't locked\n"); | 252 | dev_dbg(&p_dev->dev, "Configuration isnt't locked\n"); |
253 | ret = -EACCES; | 253 | ret = -EACCES; |
254 | goto unlock; | 254 | goto unlock; |
255 | } | 255 | } |
256 | 256 | ||
257 | if (mod->Attributes & (CONF_IRQ_CHANGE_VALID | CONF_VCC_CHANGE_VALID)) { | 257 | if (mod->Attributes & (CONF_IRQ_CHANGE_VALID | CONF_VCC_CHANGE_VALID)) { |
258 | dev_dbg(&s->dev, | 258 | dev_dbg(&p_dev->dev, |
259 | "changing Vcc or IRQ is not allowed at this time\n"); | 259 | "changing Vcc or IRQ is not allowed at this time\n"); |
260 | ret = -EINVAL; | 260 | ret = -EINVAL; |
261 | goto unlock; | 261 | goto unlock; |
@@ -265,20 +265,22 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev, | |||
265 | if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) && | 265 | if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) && |
266 | (mod->Attributes & CONF_VPP2_CHANGE_VALID)) { | 266 | (mod->Attributes & CONF_VPP2_CHANGE_VALID)) { |
267 | if (mod->Vpp1 != mod->Vpp2) { | 267 | if (mod->Vpp1 != mod->Vpp2) { |
268 | dev_dbg(&s->dev, "Vpp1 and Vpp2 must be the same\n"); | 268 | dev_dbg(&p_dev->dev, |
269 | "Vpp1 and Vpp2 must be the same\n"); | ||
269 | ret = -EINVAL; | 270 | ret = -EINVAL; |
270 | goto unlock; | 271 | goto unlock; |
271 | } | 272 | } |
272 | s->socket.Vpp = mod->Vpp1; | 273 | s->socket.Vpp = mod->Vpp1; |
273 | if (s->ops->set_socket(s, &s->socket)) { | 274 | if (s->ops->set_socket(s, &s->socket)) { |
274 | dev_printk(KERN_WARNING, &s->dev, | 275 | dev_printk(KERN_WARNING, &p_dev->dev, |
275 | "Unable to set VPP\n"); | 276 | "Unable to set VPP\n"); |
276 | ret = -EIO; | 277 | ret = -EIO; |
277 | goto unlock; | 278 | goto unlock; |
278 | } | 279 | } |
279 | } else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) || | 280 | } else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) || |
280 | (mod->Attributes & CONF_VPP2_CHANGE_VALID)) { | 281 | (mod->Attributes & CONF_VPP2_CHANGE_VALID)) { |
281 | dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n"); | 282 | dev_dbg(&p_dev->dev, |
283 | "changing Vcc is not allowed at this time\n"); | ||
282 | ret = -EINVAL; | 284 | ret = -EINVAL; |
283 | goto unlock; | 285 | goto unlock; |
284 | } | 286 | } |
@@ -401,7 +403,7 @@ int pcmcia_release_window(struct pcmcia_device *p_dev, struct resource *res) | |||
401 | win = &s->win[w]; | 403 | win = &s->win[w]; |
402 | 404 | ||
403 | if (!(p_dev->_win & CLIENT_WIN_REQ(w))) { | 405 | if (!(p_dev->_win & CLIENT_WIN_REQ(w))) { |
404 | dev_dbg(&s->dev, "not releasing unknown window\n"); | 406 | dev_dbg(&p_dev->dev, "not releasing unknown window\n"); |
405 | mutex_unlock(&s->ops_mutex); | 407 | mutex_unlock(&s->ops_mutex); |
406 | return -EINVAL; | 408 | return -EINVAL; |
407 | } | 409 | } |
@@ -439,7 +441,7 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, | |||
439 | return -ENODEV; | 441 | return -ENODEV; |
440 | 442 | ||
441 | if (req->IntType & INT_CARDBUS) { | 443 | if (req->IntType & INT_CARDBUS) { |
442 | dev_dbg(&s->dev, "IntType may not be INT_CARDBUS\n"); | 444 | dev_dbg(&p_dev->dev, "IntType may not be INT_CARDBUS\n"); |
443 | return -EINVAL; | 445 | return -EINVAL; |
444 | } | 446 | } |
445 | 447 | ||
@@ -447,7 +449,7 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, | |||
447 | c = p_dev->function_config; | 449 | c = p_dev->function_config; |
448 | if (c->state & CONFIG_LOCKED) { | 450 | if (c->state & CONFIG_LOCKED) { |
449 | mutex_unlock(&s->ops_mutex); | 451 | mutex_unlock(&s->ops_mutex); |
450 | dev_dbg(&s->dev, "Configuration is locked\n"); | 452 | dev_dbg(&p_dev->dev, "Configuration is locked\n"); |
451 | return -EACCES; | 453 | return -EACCES; |
452 | } | 454 | } |
453 | 455 | ||
@@ -455,7 +457,7 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, | |||
455 | s->socket.Vpp = req->Vpp; | 457 | s->socket.Vpp = req->Vpp; |
456 | if (s->ops->set_socket(s, &s->socket)) { | 458 | if (s->ops->set_socket(s, &s->socket)) { |
457 | mutex_unlock(&s->ops_mutex); | 459 | mutex_unlock(&s->ops_mutex); |
458 | dev_printk(KERN_WARNING, &s->dev, | 460 | dev_printk(KERN_WARNING, &p_dev->dev, |
459 | "Unable to set socket state\n"); | 461 | "Unable to set socket state\n"); |
460 | return -EINVAL; | 462 | return -EINVAL; |
461 | } | 463 | } |
@@ -569,19 +571,20 @@ int pcmcia_request_io(struct pcmcia_device *p_dev) | |||
569 | int ret = -EINVAL; | 571 | int ret = -EINVAL; |
570 | 572 | ||
571 | mutex_lock(&s->ops_mutex); | 573 | mutex_lock(&s->ops_mutex); |
572 | dev_dbg(&s->dev, "pcmcia_request_io: %pR , %pR", &c->io[0], &c->io[1]); | 574 | dev_dbg(&p_dev->dev, "pcmcia_request_io: %pR , %pR", |
575 | &c->io[0], &c->io[1]); | ||
573 | 576 | ||
574 | if (!(s->state & SOCKET_PRESENT)) { | 577 | if (!(s->state & SOCKET_PRESENT)) { |
575 | dev_dbg(&s->dev, "pcmcia_request_io: No card present\n"); | 578 | dev_dbg(&p_dev->dev, "pcmcia_request_io: No card present\n"); |
576 | goto out; | 579 | goto out; |
577 | } | 580 | } |
578 | 581 | ||
579 | if (c->state & CONFIG_LOCKED) { | 582 | if (c->state & CONFIG_LOCKED) { |
580 | dev_dbg(&s->dev, "Configuration is locked\n"); | 583 | dev_dbg(&p_dev->dev, "Configuration is locked\n"); |
581 | goto out; | 584 | goto out; |
582 | } | 585 | } |
583 | if (c->state & CONFIG_IO_REQ) { | 586 | if (c->state & CONFIG_IO_REQ) { |
584 | dev_dbg(&s->dev, "IO already configured\n"); | 587 | dev_dbg(&p_dev->dev, "IO already configured\n"); |
585 | goto out; | 588 | goto out; |
586 | } | 589 | } |
587 | 590 | ||
@@ -592,7 +595,13 @@ int pcmcia_request_io(struct pcmcia_device *p_dev) | |||
592 | if (c->io[1].end) { | 595 | if (c->io[1].end) { |
593 | ret = alloc_io_space(s, &c->io[1], p_dev->io_lines); | 596 | ret = alloc_io_space(s, &c->io[1], p_dev->io_lines); |
594 | if (ret) { | 597 | if (ret) { |
598 | struct resource tmp = c->io[0]; | ||
599 | /* release the previously allocated resource */ | ||
595 | release_io_space(s, &c->io[0]); | 600 | release_io_space(s, &c->io[0]); |
601 | /* but preserve the settings, for they worked... */ | ||
602 | c->io[0].end = resource_size(&tmp); | ||
603 | c->io[0].start = tmp.start; | ||
604 | c->io[0].flags = tmp.flags; | ||
596 | goto out; | 605 | goto out; |
597 | } | 606 | } |
598 | } else | 607 | } else |
@@ -601,7 +610,7 @@ int pcmcia_request_io(struct pcmcia_device *p_dev) | |||
601 | c->state |= CONFIG_IO_REQ; | 610 | c->state |= CONFIG_IO_REQ; |
602 | p_dev->_io = 1; | 611 | p_dev->_io = 1; |
603 | 612 | ||
604 | dev_dbg(&s->dev, "pcmcia_request_io succeeded: %pR , %pR", | 613 | dev_dbg(&p_dev->dev, "pcmcia_request_io succeeded: %pR , %pR", |
605 | &c->io[0], &c->io[1]); | 614 | &c->io[0], &c->io[1]); |
606 | out: | 615 | out: |
607 | mutex_unlock(&s->ops_mutex); | 616 | mutex_unlock(&s->ops_mutex); |
@@ -800,7 +809,7 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha | |||
800 | int w; | 809 | int w; |
801 | 810 | ||
802 | if (!(s->state & SOCKET_PRESENT)) { | 811 | if (!(s->state & SOCKET_PRESENT)) { |
803 | dev_dbg(&s->dev, "No card present\n"); | 812 | dev_dbg(&p_dev->dev, "No card present\n"); |
804 | return -ENODEV; | 813 | return -ENODEV; |
805 | } | 814 | } |
806 | 815 | ||
@@ -809,12 +818,12 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha | |||
809 | req->Size = s->map_size; | 818 | req->Size = s->map_size; |
810 | align = (s->features & SS_CAP_MEM_ALIGN) ? req->Size : s->map_size; | 819 | align = (s->features & SS_CAP_MEM_ALIGN) ? req->Size : s->map_size; |
811 | if (req->Size & (s->map_size-1)) { | 820 | if (req->Size & (s->map_size-1)) { |
812 | dev_dbg(&s->dev, "invalid map size\n"); | 821 | dev_dbg(&p_dev->dev, "invalid map size\n"); |
813 | return -EINVAL; | 822 | return -EINVAL; |
814 | } | 823 | } |
815 | if ((req->Base && (s->features & SS_CAP_STATIC_MAP)) || | 824 | if ((req->Base && (s->features & SS_CAP_STATIC_MAP)) || |
816 | (req->Base & (align-1))) { | 825 | (req->Base & (align-1))) { |
817 | dev_dbg(&s->dev, "invalid base address\n"); | 826 | dev_dbg(&p_dev->dev, "invalid base address\n"); |
818 | return -EINVAL; | 827 | return -EINVAL; |
819 | } | 828 | } |
820 | if (req->Base) | 829 | if (req->Base) |
@@ -826,7 +835,7 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha | |||
826 | if (!(s->state & SOCKET_WIN_REQ(w))) | 835 | if (!(s->state & SOCKET_WIN_REQ(w))) |
827 | break; | 836 | break; |
828 | if (w == MAX_WIN) { | 837 | if (w == MAX_WIN) { |
829 | dev_dbg(&s->dev, "all windows are used already\n"); | 838 | dev_dbg(&p_dev->dev, "all windows are used already\n"); |
830 | mutex_unlock(&s->ops_mutex); | 839 | mutex_unlock(&s->ops_mutex); |
831 | return -EINVAL; | 840 | return -EINVAL; |
832 | } | 841 | } |
@@ -837,7 +846,7 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha | |||
837 | win->res = pcmcia_find_mem_region(req->Base, req->Size, align, | 846 | win->res = pcmcia_find_mem_region(req->Base, req->Size, align, |
838 | 0, s); | 847 | 0, s); |
839 | if (!win->res) { | 848 | if (!win->res) { |
840 | dev_dbg(&s->dev, "allocating mem region failed\n"); | 849 | dev_dbg(&p_dev->dev, "allocating mem region failed\n"); |
841 | mutex_unlock(&s->ops_mutex); | 850 | mutex_unlock(&s->ops_mutex); |
842 | return -EINVAL; | 851 | return -EINVAL; |
843 | } | 852 | } |
@@ -851,7 +860,7 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha | |||
851 | win->card_start = 0; | 860 | win->card_start = 0; |
852 | 861 | ||
853 | if (s->ops->set_mem_map(s, win) != 0) { | 862 | if (s->ops->set_mem_map(s, win) != 0) { |
854 | dev_dbg(&s->dev, "failed to set memory mapping\n"); | 863 | dev_dbg(&p_dev->dev, "failed to set memory mapping\n"); |
855 | mutex_unlock(&s->ops_mutex); | 864 | mutex_unlock(&s->ops_mutex); |
856 | return -EIO; | 865 | return -EIO; |
857 | } | 866 | } |
@@ -874,7 +883,7 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha | |||
874 | if (win->res) | 883 | if (win->res) |
875 | request_resource(&iomem_resource, res); | 884 | request_resource(&iomem_resource, res); |
876 | 885 | ||
877 | dev_dbg(&s->dev, "request_window results in %pR\n", res); | 886 | dev_dbg(&p_dev->dev, "request_window results in %pR\n", res); |
878 | 887 | ||
879 | mutex_unlock(&s->ops_mutex); | 888 | mutex_unlock(&s->ops_mutex); |
880 | *wh = res; | 889 | *wh = res; |
diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c index b8a869af0f4..deef6656ab7 100644 --- a/drivers/pcmcia/pd6729.c +++ b/drivers/pcmcia/pd6729.c | |||
@@ -646,7 +646,7 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev, | |||
646 | if (!pci_resource_start(dev, 0)) { | 646 | if (!pci_resource_start(dev, 0)) { |
647 | dev_warn(&dev->dev, "refusing to load the driver as the " | 647 | dev_warn(&dev->dev, "refusing to load the driver as the " |
648 | "io_base is NULL.\n"); | 648 | "io_base is NULL.\n"); |
649 | goto err_out_free_mem; | 649 | goto err_out_disable; |
650 | } | 650 | } |
651 | 651 | ||
652 | dev_info(&dev->dev, "Cirrus PD6729 PCI to PCMCIA Bridge at 0x%llx " | 652 | dev_info(&dev->dev, "Cirrus PD6729 PCI to PCMCIA Bridge at 0x%llx " |
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 044f430f3b4..cff7cc2c1f0 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig | |||
@@ -486,10 +486,12 @@ config TOPSTAR_LAPTOP | |||
486 | config ACPI_TOSHIBA | 486 | config ACPI_TOSHIBA |
487 | tristate "Toshiba Laptop Extras" | 487 | tristate "Toshiba Laptop Extras" |
488 | depends on ACPI | 488 | depends on ACPI |
489 | depends on LEDS_CLASS | ||
490 | depends on NEW_LEDS | ||
491 | depends on BACKLIGHT_CLASS_DEVICE | ||
489 | depends on INPUT | 492 | depends on INPUT |
490 | depends on RFKILL || RFKILL = n | 493 | depends on RFKILL || RFKILL = n |
491 | select INPUT_POLLDEV | 494 | select INPUT_POLLDEV |
492 | select BACKLIGHT_CLASS_DEVICE | ||
493 | ---help--- | 495 | ---help--- |
494 | This driver adds support for access to certain system settings | 496 | This driver adds support for access to certain system settings |
495 | on "legacy free" Toshiba laptops. These laptops can be recognized by | 497 | on "legacy free" Toshiba laptops. These laptops can be recognized by |
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index f1551637498..c1741142a4c 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c | |||
@@ -79,12 +79,13 @@ struct bios_args { | |||
79 | u32 command; | 79 | u32 command; |
80 | u32 commandtype; | 80 | u32 commandtype; |
81 | u32 datasize; | 81 | u32 datasize; |
82 | char *data; | 82 | u32 data; |
83 | }; | 83 | }; |
84 | 84 | ||
85 | struct bios_return { | 85 | struct bios_return { |
86 | u32 sigpass; | 86 | u32 sigpass; |
87 | u32 return_code; | 87 | u32 return_code; |
88 | u32 value; | ||
88 | }; | 89 | }; |
89 | 90 | ||
90 | struct key_entry { | 91 | struct key_entry { |
@@ -148,7 +149,7 @@ static struct platform_driver hp_wmi_driver = { | |||
148 | * buffer = kzalloc(128, GFP_KERNEL); | 149 | * buffer = kzalloc(128, GFP_KERNEL); |
149 | * ret = hp_wmi_perform_query(0x7, 0, buffer, 128) | 150 | * ret = hp_wmi_perform_query(0x7, 0, buffer, 128) |
150 | */ | 151 | */ |
151 | static int hp_wmi_perform_query(int query, int write, char *buffer, | 152 | static int hp_wmi_perform_query(int query, int write, u32 *buffer, |
152 | int buffersize) | 153 | int buffersize) |
153 | { | 154 | { |
154 | struct bios_return bios_return; | 155 | struct bios_return bios_return; |
@@ -159,7 +160,7 @@ static int hp_wmi_perform_query(int query, int write, char *buffer, | |||
159 | .command = write ? 0x2 : 0x1, | 160 | .command = write ? 0x2 : 0x1, |
160 | .commandtype = query, | 161 | .commandtype = query, |
161 | .datasize = buffersize, | 162 | .datasize = buffersize, |
162 | .data = buffer, | 163 | .data = *buffer, |
163 | }; | 164 | }; |
164 | struct acpi_buffer input = { sizeof(struct bios_args), &args }; | 165 | struct acpi_buffer input = { sizeof(struct bios_args), &args }; |
165 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; | 166 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; |
@@ -177,29 +178,14 @@ static int hp_wmi_perform_query(int query, int write, char *buffer, | |||
177 | 178 | ||
178 | bios_return = *((struct bios_return *)obj->buffer.pointer); | 179 | bios_return = *((struct bios_return *)obj->buffer.pointer); |
179 | 180 | ||
180 | if (bios_return.return_code) { | 181 | memcpy(buffer, &bios_return.value, sizeof(bios_return.value)); |
181 | printk(KERN_WARNING PREFIX "Query %d returned %d\n", query, | ||
182 | bios_return.return_code); | ||
183 | kfree(obj); | ||
184 | return bios_return.return_code; | ||
185 | } | ||
186 | if (obj->buffer.length - sizeof(bios_return) > buffersize) { | ||
187 | kfree(obj); | ||
188 | return -EINVAL; | ||
189 | } | ||
190 | |||
191 | memset(buffer, 0, buffersize); | ||
192 | memcpy(buffer, | ||
193 | ((char *)obj->buffer.pointer) + sizeof(struct bios_return), | ||
194 | obj->buffer.length - sizeof(bios_return)); | ||
195 | kfree(obj); | ||
196 | return 0; | 182 | return 0; |
197 | } | 183 | } |
198 | 184 | ||
199 | static int hp_wmi_display_state(void) | 185 | static int hp_wmi_display_state(void) |
200 | { | 186 | { |
201 | int state; | 187 | int state = 0; |
202 | int ret = hp_wmi_perform_query(HPWMI_DISPLAY_QUERY, 0, (char *)&state, | 188 | int ret = hp_wmi_perform_query(HPWMI_DISPLAY_QUERY, 0, &state, |
203 | sizeof(state)); | 189 | sizeof(state)); |
204 | if (ret) | 190 | if (ret) |
205 | return -EINVAL; | 191 | return -EINVAL; |
@@ -208,8 +194,8 @@ static int hp_wmi_display_state(void) | |||
208 | 194 | ||
209 | static int hp_wmi_hddtemp_state(void) | 195 | static int hp_wmi_hddtemp_state(void) |
210 | { | 196 | { |
211 | int state; | 197 | int state = 0; |
212 | int ret = hp_wmi_perform_query(HPWMI_HDDTEMP_QUERY, 0, (char *)&state, | 198 | int ret = hp_wmi_perform_query(HPWMI_HDDTEMP_QUERY, 0, &state, |
213 | sizeof(state)); | 199 | sizeof(state)); |
214 | if (ret) | 200 | if (ret) |
215 | return -EINVAL; | 201 | return -EINVAL; |
@@ -218,8 +204,8 @@ static int hp_wmi_hddtemp_state(void) | |||
218 | 204 | ||
219 | static int hp_wmi_als_state(void) | 205 | static int hp_wmi_als_state(void) |
220 | { | 206 | { |
221 | int state; | 207 | int state = 0; |
222 | int ret = hp_wmi_perform_query(HPWMI_ALS_QUERY, 0, (char *)&state, | 208 | int ret = hp_wmi_perform_query(HPWMI_ALS_QUERY, 0, &state, |
223 | sizeof(state)); | 209 | sizeof(state)); |
224 | if (ret) | 210 | if (ret) |
225 | return -EINVAL; | 211 | return -EINVAL; |
@@ -228,8 +214,8 @@ static int hp_wmi_als_state(void) | |||
228 | 214 | ||
229 | static int hp_wmi_dock_state(void) | 215 | static int hp_wmi_dock_state(void) |
230 | { | 216 | { |
231 | int state; | 217 | int state = 0; |
232 | int ret = hp_wmi_perform_query(HPWMI_HARDWARE_QUERY, 0, (char *)&state, | 218 | int ret = hp_wmi_perform_query(HPWMI_HARDWARE_QUERY, 0, &state, |
233 | sizeof(state)); | 219 | sizeof(state)); |
234 | 220 | ||
235 | if (ret) | 221 | if (ret) |
@@ -240,8 +226,8 @@ static int hp_wmi_dock_state(void) | |||
240 | 226 | ||
241 | static int hp_wmi_tablet_state(void) | 227 | static int hp_wmi_tablet_state(void) |
242 | { | 228 | { |
243 | int state; | 229 | int state = 0; |
244 | int ret = hp_wmi_perform_query(HPWMI_HARDWARE_QUERY, 0, (char *)&state, | 230 | int ret = hp_wmi_perform_query(HPWMI_HARDWARE_QUERY, 0, &state, |
245 | sizeof(state)); | 231 | sizeof(state)); |
246 | if (ret) | 232 | if (ret) |
247 | return ret; | 233 | return ret; |
@@ -256,7 +242,7 @@ static int hp_wmi_set_block(void *data, bool blocked) | |||
256 | int ret; | 242 | int ret; |
257 | 243 | ||
258 | ret = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, | 244 | ret = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, |
259 | (char *)&query, sizeof(query)); | 245 | &query, sizeof(query)); |
260 | if (ret) | 246 | if (ret) |
261 | return -EINVAL; | 247 | return -EINVAL; |
262 | return 0; | 248 | return 0; |
@@ -268,10 +254,10 @@ static const struct rfkill_ops hp_wmi_rfkill_ops = { | |||
268 | 254 | ||
269 | static bool hp_wmi_get_sw_state(enum hp_wmi_radio r) | 255 | static bool hp_wmi_get_sw_state(enum hp_wmi_radio r) |
270 | { | 256 | { |
271 | int wireless; | 257 | int wireless = 0; |
272 | int mask; | 258 | int mask; |
273 | hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, | 259 | hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, |
274 | (char *)&wireless, sizeof(wireless)); | 260 | &wireless, sizeof(wireless)); |
275 | /* TBD: Pass error */ | 261 | /* TBD: Pass error */ |
276 | 262 | ||
277 | mask = 0x200 << (r * 8); | 263 | mask = 0x200 << (r * 8); |
@@ -284,10 +270,10 @@ static bool hp_wmi_get_sw_state(enum hp_wmi_radio r) | |||
284 | 270 | ||
285 | static bool hp_wmi_get_hw_state(enum hp_wmi_radio r) | 271 | static bool hp_wmi_get_hw_state(enum hp_wmi_radio r) |
286 | { | 272 | { |
287 | int wireless; | 273 | int wireless = 0; |
288 | int mask; | 274 | int mask; |
289 | hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, | 275 | hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, |
290 | (char *)&wireless, sizeof(wireless)); | 276 | &wireless, sizeof(wireless)); |
291 | /* TBD: Pass error */ | 277 | /* TBD: Pass error */ |
292 | 278 | ||
293 | mask = 0x800 << (r * 8); | 279 | mask = 0x800 << (r * 8); |
@@ -347,7 +333,7 @@ static ssize_t set_als(struct device *dev, struct device_attribute *attr, | |||
347 | const char *buf, size_t count) | 333 | const char *buf, size_t count) |
348 | { | 334 | { |
349 | u32 tmp = simple_strtoul(buf, NULL, 10); | 335 | u32 tmp = simple_strtoul(buf, NULL, 10); |
350 | int ret = hp_wmi_perform_query(HPWMI_ALS_QUERY, 1, (char *)&tmp, | 336 | int ret = hp_wmi_perform_query(HPWMI_ALS_QUERY, 1, &tmp, |
351 | sizeof(tmp)); | 337 | sizeof(tmp)); |
352 | if (ret) | 338 | if (ret) |
353 | return -EINVAL; | 339 | return -EINVAL; |
@@ -421,7 +407,7 @@ static void hp_wmi_notify(u32 value, void *context) | |||
421 | static struct key_entry *key; | 407 | static struct key_entry *key; |
422 | union acpi_object *obj; | 408 | union acpi_object *obj; |
423 | u32 event_id, event_data; | 409 | u32 event_id, event_data; |
424 | int key_code, ret; | 410 | int key_code = 0, ret; |
425 | u32 *location; | 411 | u32 *location; |
426 | acpi_status status; | 412 | acpi_status status; |
427 | 413 | ||
@@ -475,7 +461,7 @@ static void hp_wmi_notify(u32 value, void *context) | |||
475 | break; | 461 | break; |
476 | case HPWMI_BEZEL_BUTTON: | 462 | case HPWMI_BEZEL_BUTTON: |
477 | ret = hp_wmi_perform_query(HPWMI_HOTKEY_QUERY, 0, | 463 | ret = hp_wmi_perform_query(HPWMI_HOTKEY_QUERY, 0, |
478 | (char *)&key_code, | 464 | &key_code, |
479 | sizeof(key_code)); | 465 | sizeof(key_code)); |
480 | if (ret) | 466 | if (ret) |
481 | break; | 467 | break; |
@@ -578,9 +564,9 @@ static void cleanup_sysfs(struct platform_device *device) | |||
578 | static int __devinit hp_wmi_bios_setup(struct platform_device *device) | 564 | static int __devinit hp_wmi_bios_setup(struct platform_device *device) |
579 | { | 565 | { |
580 | int err; | 566 | int err; |
581 | int wireless; | 567 | int wireless = 0; |
582 | 568 | ||
583 | err = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, (char *)&wireless, | 569 | err = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, &wireless, |
584 | sizeof(wireless)); | 570 | sizeof(wireless)); |
585 | if (err) | 571 | if (err) |
586 | return err; | 572 | return err; |
diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c index 9024480a822..c44a5e8b8b8 100644 --- a/drivers/platform/x86/intel_ips.c +++ b/drivers/platform/x86/intel_ips.c | |||
@@ -51,7 +51,6 @@ | |||
51 | * TODO: | 51 | * TODO: |
52 | * - handle CPU hotplug | 52 | * - handle CPU hotplug |
53 | * - provide turbo enable/disable api | 53 | * - provide turbo enable/disable api |
54 | * - make sure we can write turbo enable/disable reg based on MISC_EN | ||
55 | * | 54 | * |
56 | * Related documents: | 55 | * Related documents: |
57 | * - CDI 403777, 403778 - Auburndale EDS vol 1 & 2 | 56 | * - CDI 403777, 403778 - Auburndale EDS vol 1 & 2 |
@@ -230,7 +229,7 @@ | |||
230 | #define THM_TC2 0xac | 229 | #define THM_TC2 0xac |
231 | #define THM_DTV 0xb0 | 230 | #define THM_DTV 0xb0 |
232 | #define THM_ITV 0xd8 | 231 | #define THM_ITV 0xd8 |
233 | #define ITV_ME_SEQNO_MASK 0x000f0000 /* ME should update every ~200ms */ | 232 | #define ITV_ME_SEQNO_MASK 0x00ff0000 /* ME should update every ~200ms */ |
234 | #define ITV_ME_SEQNO_SHIFT (16) | 233 | #define ITV_ME_SEQNO_SHIFT (16) |
235 | #define ITV_MCH_TEMP_MASK 0x0000ff00 | 234 | #define ITV_MCH_TEMP_MASK 0x0000ff00 |
236 | #define ITV_MCH_TEMP_SHIFT (8) | 235 | #define ITV_MCH_TEMP_SHIFT (8) |
@@ -325,6 +324,7 @@ struct ips_driver { | |||
325 | bool gpu_preferred; | 324 | bool gpu_preferred; |
326 | bool poll_turbo_status; | 325 | bool poll_turbo_status; |
327 | bool second_cpu; | 326 | bool second_cpu; |
327 | bool turbo_toggle_allowed; | ||
328 | struct ips_mcp_limits *limits; | 328 | struct ips_mcp_limits *limits; |
329 | 329 | ||
330 | /* Optional MCH interfaces for if i915 is in use */ | 330 | /* Optional MCH interfaces for if i915 is in use */ |
@@ -415,7 +415,7 @@ static void ips_cpu_lower(struct ips_driver *ips) | |||
415 | new_limit = cur_limit - 8; /* 1W decrease */ | 415 | new_limit = cur_limit - 8; /* 1W decrease */ |
416 | 416 | ||
417 | /* Clamp to SKU TDP limit */ | 417 | /* Clamp to SKU TDP limit */ |
418 | if (((new_limit * 10) / 8) < (ips->orig_turbo_limit & TURBO_TDP_MASK)) | 418 | if (new_limit < (ips->orig_turbo_limit & TURBO_TDP_MASK)) |
419 | new_limit = ips->orig_turbo_limit & TURBO_TDP_MASK; | 419 | new_limit = ips->orig_turbo_limit & TURBO_TDP_MASK; |
420 | 420 | ||
421 | thm_writew(THM_MPCPC, (new_limit * 10) / 8); | 421 | thm_writew(THM_MPCPC, (new_limit * 10) / 8); |
@@ -461,7 +461,8 @@ static void ips_enable_cpu_turbo(struct ips_driver *ips) | |||
461 | if (ips->__cpu_turbo_on) | 461 | if (ips->__cpu_turbo_on) |
462 | return; | 462 | return; |
463 | 463 | ||
464 | on_each_cpu(do_enable_cpu_turbo, ips, 1); | 464 | if (ips->turbo_toggle_allowed) |
465 | on_each_cpu(do_enable_cpu_turbo, ips, 1); | ||
465 | 466 | ||
466 | ips->__cpu_turbo_on = true; | 467 | ips->__cpu_turbo_on = true; |
467 | } | 468 | } |
@@ -498,7 +499,8 @@ static void ips_disable_cpu_turbo(struct ips_driver *ips) | |||
498 | if (!ips->__cpu_turbo_on) | 499 | if (!ips->__cpu_turbo_on) |
499 | return; | 500 | return; |
500 | 501 | ||
501 | on_each_cpu(do_disable_cpu_turbo, ips, 1); | 502 | if (ips->turbo_toggle_allowed) |
503 | on_each_cpu(do_disable_cpu_turbo, ips, 1); | ||
502 | 504 | ||
503 | ips->__cpu_turbo_on = false; | 505 | ips->__cpu_turbo_on = false; |
504 | } | 506 | } |
@@ -598,17 +600,29 @@ static bool mcp_exceeded(struct ips_driver *ips) | |||
598 | { | 600 | { |
599 | unsigned long flags; | 601 | unsigned long flags; |
600 | bool ret = false; | 602 | bool ret = false; |
603 | u32 temp_limit; | ||
604 | u32 avg_power; | ||
605 | const char *msg = "MCP limit exceeded: "; | ||
601 | 606 | ||
602 | spin_lock_irqsave(&ips->turbo_status_lock, flags); | 607 | spin_lock_irqsave(&ips->turbo_status_lock, flags); |
603 | if (ips->mcp_avg_temp > (ips->mcp_temp_limit * 100)) | 608 | |
604 | ret = true; | 609 | temp_limit = ips->mcp_temp_limit * 100; |
605 | if (ips->cpu_avg_power + ips->mch_avg_power > ips->mcp_power_limit) | 610 | if (ips->mcp_avg_temp > temp_limit) { |
611 | dev_info(&ips->dev->dev, | ||
612 | "%sAvg temp %u, limit %u\n", msg, ips->mcp_avg_temp, | ||
613 | temp_limit); | ||
606 | ret = true; | 614 | ret = true; |
607 | spin_unlock_irqrestore(&ips->turbo_status_lock, flags); | 615 | } |
608 | 616 | ||
609 | if (ret) | 617 | avg_power = ips->cpu_avg_power + ips->mch_avg_power; |
618 | if (avg_power > ips->mcp_power_limit) { | ||
610 | dev_info(&ips->dev->dev, | 619 | dev_info(&ips->dev->dev, |
611 | "MCP power or thermal limit exceeded\n"); | 620 | "%sAvg power %u, limit %u\n", msg, avg_power, |
621 | ips->mcp_power_limit); | ||
622 | ret = true; | ||
623 | } | ||
624 | |||
625 | spin_unlock_irqrestore(&ips->turbo_status_lock, flags); | ||
612 | 626 | ||
613 | return ret; | 627 | return ret; |
614 | } | 628 | } |
@@ -663,6 +677,27 @@ static bool mch_exceeded(struct ips_driver *ips) | |||
663 | } | 677 | } |
664 | 678 | ||
665 | /** | 679 | /** |
680 | * verify_limits - verify BIOS provided limits | ||
681 | * @ips: IPS structure | ||
682 | * | ||
683 | * BIOS can optionally provide non-default limits for power and temp. Check | ||
684 | * them here and use the defaults if the BIOS values are not provided or | ||
685 | * are otherwise unusable. | ||
686 | */ | ||
687 | static void verify_limits(struct ips_driver *ips) | ||
688 | { | ||
689 | if (ips->mcp_power_limit < ips->limits->mcp_power_limit || | ||
690 | ips->mcp_power_limit > 35000) | ||
691 | ips->mcp_power_limit = ips->limits->mcp_power_limit; | ||
692 | |||
693 | if (ips->mcp_temp_limit < ips->limits->core_temp_limit || | ||
694 | ips->mcp_temp_limit < ips->limits->mch_temp_limit || | ||
695 | ips->mcp_temp_limit > 150) | ||
696 | ips->mcp_temp_limit = min(ips->limits->core_temp_limit, | ||
697 | ips->limits->mch_temp_limit); | ||
698 | } | ||
699 | |||
700 | /** | ||
666 | * update_turbo_limits - get various limits & settings from regs | 701 | * update_turbo_limits - get various limits & settings from regs |
667 | * @ips: IPS driver struct | 702 | * @ips: IPS driver struct |
668 | * | 703 | * |
@@ -680,12 +715,21 @@ static void update_turbo_limits(struct ips_driver *ips) | |||
680 | u32 hts = thm_readl(THM_HTS); | 715 | u32 hts = thm_readl(THM_HTS); |
681 | 716 | ||
682 | ips->cpu_turbo_enabled = !(hts & HTS_PCTD_DIS); | 717 | ips->cpu_turbo_enabled = !(hts & HTS_PCTD_DIS); |
683 | ips->gpu_turbo_enabled = !(hts & HTS_GTD_DIS); | 718 | /* |
719 | * Disable turbo for now, until we can figure out why the power figures | ||
720 | * are wrong | ||
721 | */ | ||
722 | ips->cpu_turbo_enabled = false; | ||
723 | |||
724 | if (ips->gpu_busy) | ||
725 | ips->gpu_turbo_enabled = !(hts & HTS_GTD_DIS); | ||
726 | |||
684 | ips->core_power_limit = thm_readw(THM_MPCPC); | 727 | ips->core_power_limit = thm_readw(THM_MPCPC); |
685 | ips->mch_power_limit = thm_readw(THM_MMGPC); | 728 | ips->mch_power_limit = thm_readw(THM_MMGPC); |
686 | ips->mcp_temp_limit = thm_readw(THM_PTL); | 729 | ips->mcp_temp_limit = thm_readw(THM_PTL); |
687 | ips->mcp_power_limit = thm_readw(THM_MPPC); | 730 | ips->mcp_power_limit = thm_readw(THM_MPPC); |
688 | 731 | ||
732 | verify_limits(ips); | ||
689 | /* Ignore BIOS CPU vs GPU pref */ | 733 | /* Ignore BIOS CPU vs GPU pref */ |
690 | } | 734 | } |
691 | 735 | ||
@@ -858,7 +902,7 @@ static u32 get_cpu_power(struct ips_driver *ips, u32 *last, int period) | |||
858 | ret = (ret * 1000) / 65535; | 902 | ret = (ret * 1000) / 65535; |
859 | *last = val; | 903 | *last = val; |
860 | 904 | ||
861 | return ret; | 905 | return 0; |
862 | } | 906 | } |
863 | 907 | ||
864 | static const u16 temp_decay_factor = 2; | 908 | static const u16 temp_decay_factor = 2; |
@@ -940,7 +984,6 @@ static int ips_monitor(void *data) | |||
940 | kfree(mch_samples); | 984 | kfree(mch_samples); |
941 | kfree(cpu_samples); | 985 | kfree(cpu_samples); |
942 | kfree(mchp_samples); | 986 | kfree(mchp_samples); |
943 | kthread_stop(ips->adjust); | ||
944 | return -ENOMEM; | 987 | return -ENOMEM; |
945 | } | 988 | } |
946 | 989 | ||
@@ -948,7 +991,7 @@ static int ips_monitor(void *data) | |||
948 | ITV_ME_SEQNO_SHIFT; | 991 | ITV_ME_SEQNO_SHIFT; |
949 | seqno_timestamp = get_jiffies_64(); | 992 | seqno_timestamp = get_jiffies_64(); |
950 | 993 | ||
951 | old_cpu_power = thm_readl(THM_CEC) / 65535; | 994 | old_cpu_power = thm_readl(THM_CEC); |
952 | schedule_timeout_interruptible(msecs_to_jiffies(IPS_SAMPLE_PERIOD)); | 995 | schedule_timeout_interruptible(msecs_to_jiffies(IPS_SAMPLE_PERIOD)); |
953 | 996 | ||
954 | /* Collect an initial average */ | 997 | /* Collect an initial average */ |
@@ -1150,11 +1193,18 @@ static irqreturn_t ips_irq_handler(int irq, void *arg) | |||
1150 | STS_GPL_SHIFT; | 1193 | STS_GPL_SHIFT; |
1151 | /* ignore EC CPU vs GPU pref */ | 1194 | /* ignore EC CPU vs GPU pref */ |
1152 | ips->cpu_turbo_enabled = !(sts & STS_PCTD_DIS); | 1195 | ips->cpu_turbo_enabled = !(sts & STS_PCTD_DIS); |
1153 | ips->gpu_turbo_enabled = !(sts & STS_GTD_DIS); | 1196 | /* |
1197 | * Disable turbo for now, until we can figure | ||
1198 | * out why the power figures are wrong | ||
1199 | */ | ||
1200 | ips->cpu_turbo_enabled = false; | ||
1201 | if (ips->gpu_busy) | ||
1202 | ips->gpu_turbo_enabled = !(sts & STS_GTD_DIS); | ||
1154 | ips->mcp_temp_limit = (sts & STS_PTL_MASK) >> | 1203 | ips->mcp_temp_limit = (sts & STS_PTL_MASK) >> |
1155 | STS_PTL_SHIFT; | 1204 | STS_PTL_SHIFT; |
1156 | ips->mcp_power_limit = (tc1 & STS_PPL_MASK) >> | 1205 | ips->mcp_power_limit = (tc1 & STS_PPL_MASK) >> |
1157 | STS_PPL_SHIFT; | 1206 | STS_PPL_SHIFT; |
1207 | verify_limits(ips); | ||
1158 | spin_unlock(&ips->turbo_status_lock); | 1208 | spin_unlock(&ips->turbo_status_lock); |
1159 | 1209 | ||
1160 | thm_writeb(THM_SEC, SEC_ACK); | 1210 | thm_writeb(THM_SEC, SEC_ACK); |
@@ -1333,8 +1383,10 @@ static struct ips_mcp_limits *ips_detect_cpu(struct ips_driver *ips) | |||
1333 | * turbo manually or we'll get an illegal MSR access, even though | 1383 | * turbo manually or we'll get an illegal MSR access, even though |
1334 | * turbo will still be available. | 1384 | * turbo will still be available. |
1335 | */ | 1385 | */ |
1336 | if (!(misc_en & IA32_MISC_TURBO_EN)) | 1386 | if (misc_en & IA32_MISC_TURBO_EN) |
1337 | ; /* add turbo MSR write allowed flag if necessary */ | 1387 | ips->turbo_toggle_allowed = true; |
1388 | else | ||
1389 | ips->turbo_toggle_allowed = false; | ||
1338 | 1390 | ||
1339 | if (strstr(boot_cpu_data.x86_model_id, "CPU M")) | 1391 | if (strstr(boot_cpu_data.x86_model_id, "CPU M")) |
1340 | limits = &ips_sv_limits; | 1392 | limits = &ips_sv_limits; |
@@ -1351,9 +1403,10 @@ static struct ips_mcp_limits *ips_detect_cpu(struct ips_driver *ips) | |||
1351 | tdp = turbo_power & TURBO_TDP_MASK; | 1403 | tdp = turbo_power & TURBO_TDP_MASK; |
1352 | 1404 | ||
1353 | /* Sanity check TDP against CPU */ | 1405 | /* Sanity check TDP against CPU */ |
1354 | if (limits->mcp_power_limit != (tdp / 8) * 1000) { | 1406 | if (limits->core_power_limit != (tdp / 8) * 1000) { |
1355 | dev_warn(&ips->dev->dev, "Warning: CPU TDP doesn't match expected value (found %d, expected %d)\n", | 1407 | dev_info(&ips->dev->dev, "CPU TDP doesn't match expected value (found %d, expected %d)\n", |
1356 | tdp / 8, limits->mcp_power_limit / 1000); | 1408 | tdp / 8, limits->core_power_limit / 1000); |
1409 | limits->core_power_limit = (tdp / 8) * 1000; | ||
1357 | } | 1410 | } |
1358 | 1411 | ||
1359 | out: | 1412 | out: |
@@ -1390,7 +1443,7 @@ static bool ips_get_i915_syms(struct ips_driver *ips) | |||
1390 | return true; | 1443 | return true; |
1391 | 1444 | ||
1392 | out_put_busy: | 1445 | out_put_busy: |
1393 | symbol_put(i915_gpu_turbo_disable); | 1446 | symbol_put(i915_gpu_busy); |
1394 | out_put_lower: | 1447 | out_put_lower: |
1395 | symbol_put(i915_gpu_lower); | 1448 | symbol_put(i915_gpu_lower); |
1396 | out_put_raise: | 1449 | out_put_raise: |
@@ -1532,22 +1585,27 @@ static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
1532 | /* Save turbo limits & ratios */ | 1585 | /* Save turbo limits & ratios */ |
1533 | rdmsrl(TURBO_POWER_CURRENT_LIMIT, ips->orig_turbo_limit); | 1586 | rdmsrl(TURBO_POWER_CURRENT_LIMIT, ips->orig_turbo_limit); |
1534 | 1587 | ||
1535 | ips_enable_cpu_turbo(ips); | 1588 | ips_disable_cpu_turbo(ips); |
1536 | ips->cpu_turbo_enabled = true; | 1589 | ips->cpu_turbo_enabled = false; |
1537 | 1590 | ||
1538 | /* Set up the work queue and monitor/adjust threads */ | 1591 | /* Create thermal adjust thread */ |
1539 | ips->monitor = kthread_run(ips_monitor, ips, "ips-monitor"); | 1592 | ips->adjust = kthread_create(ips_adjust, ips, "ips-adjust"); |
1540 | if (IS_ERR(ips->monitor)) { | 1593 | if (IS_ERR(ips->adjust)) { |
1541 | dev_err(&dev->dev, | 1594 | dev_err(&dev->dev, |
1542 | "failed to create thermal monitor thread, aborting\n"); | 1595 | "failed to create thermal adjust thread, aborting\n"); |
1543 | ret = -ENOMEM; | 1596 | ret = -ENOMEM; |
1544 | goto error_free_irq; | 1597 | goto error_free_irq; |
1598 | |||
1545 | } | 1599 | } |
1546 | 1600 | ||
1547 | ips->adjust = kthread_create(ips_adjust, ips, "ips-adjust"); | 1601 | /* |
1548 | if (IS_ERR(ips->adjust)) { | 1602 | * Set up the work queue and monitor thread. The monitor thread |
1603 | * will wake up ips_adjust thread. | ||
1604 | */ | ||
1605 | ips->monitor = kthread_run(ips_monitor, ips, "ips-monitor"); | ||
1606 | if (IS_ERR(ips->monitor)) { | ||
1549 | dev_err(&dev->dev, | 1607 | dev_err(&dev->dev, |
1550 | "failed to create thermal adjust thread, aborting\n"); | 1608 | "failed to create thermal monitor thread, aborting\n"); |
1551 | ret = -ENOMEM; | 1609 | ret = -ENOMEM; |
1552 | goto error_thread_cleanup; | 1610 | goto error_thread_cleanup; |
1553 | } | 1611 | } |
@@ -1566,7 +1624,7 @@ static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
1566 | return ret; | 1624 | return ret; |
1567 | 1625 | ||
1568 | error_thread_cleanup: | 1626 | error_thread_cleanup: |
1569 | kthread_stop(ips->monitor); | 1627 | kthread_stop(ips->adjust); |
1570 | error_free_irq: | 1628 | error_free_irq: |
1571 | free_irq(ips->dev->irq, ips); | 1629 | free_irq(ips->dev->irq, ips); |
1572 | error_unmap: | 1630 | error_unmap: |
diff --git a/drivers/platform/x86/intel_rar_register.c b/drivers/platform/x86/intel_rar_register.c index 73f8e6d7266..2b11a33325e 100644 --- a/drivers/platform/x86/intel_rar_register.c +++ b/drivers/platform/x86/intel_rar_register.c | |||
@@ -145,7 +145,7 @@ static void free_rar_device(struct rar_device *rar) | |||
145 | */ | 145 | */ |
146 | static struct rar_device *_rar_to_device(int rar, int *off) | 146 | static struct rar_device *_rar_to_device(int rar, int *off) |
147 | { | 147 | { |
148 | if (rar >= 0 && rar <= 3) { | 148 | if (rar >= 0 && rar < MRST_NUM_RAR) { |
149 | *off = rar; | 149 | *off = rar; |
150 | return &my_rar_device; | 150 | return &my_rar_device; |
151 | } | 151 | } |
diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c index 943f9084dcb..6abe18e638e 100644 --- a/drivers/platform/x86/intel_scu_ipc.c +++ b/drivers/platform/x86/intel_scu_ipc.c | |||
@@ -487,7 +487,7 @@ int intel_scu_ipc_i2c_cntrl(u32 addr, u32 *data) | |||
487 | mdelay(1); | 487 | mdelay(1); |
488 | *data = readl(ipcdev.i2c_base + I2C_DATA_ADDR); | 488 | *data = readl(ipcdev.i2c_base + I2C_DATA_ADDR); |
489 | } else if (cmd == IPC_I2C_WRITE) { | 489 | } else if (cmd == IPC_I2C_WRITE) { |
490 | writel(addr, ipcdev.i2c_base + I2C_DATA_ADDR); | 490 | writel(*data, ipcdev.i2c_base + I2C_DATA_ADDR); |
491 | mdelay(1); | 491 | mdelay(1); |
492 | writel(addr, ipcdev.i2c_base + IPC_I2C_CNTRL_ADDR); | 492 | writel(addr, ipcdev.i2c_base + IPC_I2C_CNTRL_ADDR); |
493 | } else { | 493 | } else { |
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index e35ed128bde..2d61186ad5a 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
@@ -3093,7 +3093,8 @@ static const struct tpacpi_quirk tpacpi_hotkey_qtable[] __initconst = { | |||
3093 | TPACPI_Q_IBM('1', 'D', TPACPI_HK_Q_INIMASK), /* X22, X23, X24 */ | 3093 | TPACPI_Q_IBM('1', 'D', TPACPI_HK_Q_INIMASK), /* X22, X23, X24 */ |
3094 | }; | 3094 | }; |
3095 | 3095 | ||
3096 | typedef u16 tpacpi_keymap_t[TPACPI_HOTKEY_MAP_LEN]; | 3096 | typedef u16 tpacpi_keymap_entry_t; |
3097 | typedef tpacpi_keymap_entry_t tpacpi_keymap_t[TPACPI_HOTKEY_MAP_LEN]; | ||
3097 | 3098 | ||
3098 | static int __init hotkey_init(struct ibm_init_struct *iibm) | 3099 | static int __init hotkey_init(struct ibm_init_struct *iibm) |
3099 | { | 3100 | { |
@@ -3230,7 +3231,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
3230 | }; | 3231 | }; |
3231 | 3232 | ||
3232 | #define TPACPI_HOTKEY_MAP_SIZE sizeof(tpacpi_keymap_t) | 3233 | #define TPACPI_HOTKEY_MAP_SIZE sizeof(tpacpi_keymap_t) |
3233 | #define TPACPI_HOTKEY_MAP_TYPESIZE sizeof(tpacpi_keymap_t[0]) | 3234 | #define TPACPI_HOTKEY_MAP_TYPESIZE sizeof(tpacpi_keymap_entry_t) |
3234 | 3235 | ||
3235 | int res, i; | 3236 | int res, i; |
3236 | int status; | 3237 | int status; |
diff --git a/drivers/power/apm_power.c b/drivers/power/apm_power.c index 936bae560fa..dc628cb2e76 100644 --- a/drivers/power/apm_power.c +++ b/drivers/power/apm_power.c | |||
@@ -233,6 +233,7 @@ static int calculate_capacity(enum apm_source source) | |||
233 | empty_design_prop = POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN; | 233 | empty_design_prop = POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN; |
234 | now_prop = POWER_SUPPLY_PROP_ENERGY_NOW; | 234 | now_prop = POWER_SUPPLY_PROP_ENERGY_NOW; |
235 | avg_prop = POWER_SUPPLY_PROP_ENERGY_AVG; | 235 | avg_prop = POWER_SUPPLY_PROP_ENERGY_AVG; |
236 | break; | ||
236 | case SOURCE_VOLTAGE: | 237 | case SOURCE_VOLTAGE: |
237 | full_prop = POWER_SUPPLY_PROP_VOLTAGE_MAX; | 238 | full_prop = POWER_SUPPLY_PROP_VOLTAGE_MAX; |
238 | empty_prop = POWER_SUPPLY_PROP_VOLTAGE_MIN; | 239 | empty_prop = POWER_SUPPLY_PROP_VOLTAGE_MIN; |
diff --git a/drivers/power/intel_mid_battery.c b/drivers/power/intel_mid_battery.c index c61ffec2ff1..2a10cd36118 100644 --- a/drivers/power/intel_mid_battery.c +++ b/drivers/power/intel_mid_battery.c | |||
@@ -185,8 +185,8 @@ static int pmic_scu_ipc_battery_property_get(struct battery_property *prop) | |||
185 | { | 185 | { |
186 | u32 data[3]; | 186 | u32 data[3]; |
187 | u8 *p = (u8 *)&data[1]; | 187 | u8 *p = (u8 *)&data[1]; |
188 | int err = intel_scu_ipc_command(IPC_CMD_BATTERY_PROPERTY, | 188 | int err = intel_scu_ipc_command(IPCMSG_BATTERY, |
189 | IPCMSG_BATTERY, NULL, 0, data, 3); | 189 | IPC_CMD_BATTERY_PROPERTY, NULL, 0, data, 3); |
190 | 190 | ||
191 | prop->capacity = data[0]; | 191 | prop->capacity = data[0]; |
192 | prop->crnt = *p++; | 192 | prop->crnt = *p++; |
@@ -207,7 +207,7 @@ static int pmic_scu_ipc_battery_property_get(struct battery_property *prop) | |||
207 | 207 | ||
208 | static int pmic_scu_ipc_set_charger(int charger) | 208 | static int pmic_scu_ipc_set_charger(int charger) |
209 | { | 209 | { |
210 | return intel_scu_ipc_simple_command(charger, IPCMSG_BATTERY); | 210 | return intel_scu_ipc_simple_command(IPCMSG_BATTERY, charger); |
211 | } | 211 | } |
212 | 212 | ||
213 | /** | 213 | /** |
diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c index 7d149a8d8d9..2ce2eb71d0f 100644 --- a/drivers/regulator/88pm8607.c +++ b/drivers/regulator/88pm8607.c | |||
@@ -215,7 +215,7 @@ static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index) | |||
215 | struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); | 215 | struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); |
216 | int ret = -EINVAL; | 216 | int ret = -EINVAL; |
217 | 217 | ||
218 | if (info->vol_table && (index < (2 << info->vol_nbits))) { | 218 | if (info->vol_table && (index < (1 << info->vol_nbits))) { |
219 | ret = info->vol_table[index]; | 219 | ret = info->vol_table[index]; |
220 | if (info->slope_double) | 220 | if (info->slope_double) |
221 | ret <<= 1; | 221 | ret <<= 1; |
@@ -233,7 +233,7 @@ static int choose_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) | |||
233 | max_uV = max_uV >> 1; | 233 | max_uV = max_uV >> 1; |
234 | } | 234 | } |
235 | if (info->vol_table) { | 235 | if (info->vol_table) { |
236 | for (i = 0; i < (2 << info->vol_nbits); i++) { | 236 | for (i = 0; i < (1 << info->vol_nbits); i++) { |
237 | if (!info->vol_table[i]) | 237 | if (!info->vol_table[i]) |
238 | break; | 238 | break; |
239 | if ((min_uV <= info->vol_table[i]) | 239 | if ((min_uV <= info->vol_table[i]) |
diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c index 11790990277..b349266a43d 100644 --- a/drivers/regulator/ab3100.c +++ b/drivers/regulator/ab3100.c | |||
@@ -634,12 +634,9 @@ static int __devinit ab3100_regulators_probe(struct platform_device *pdev) | |||
634 | "%s: failed to register regulator %s err %d\n", | 634 | "%s: failed to register regulator %s err %d\n", |
635 | __func__, ab3100_regulator_desc[i].name, | 635 | __func__, ab3100_regulator_desc[i].name, |
636 | err); | 636 | err); |
637 | i--; | ||
638 | /* remove the already registered regulators */ | 637 | /* remove the already registered regulators */ |
639 | while (i > 0) { | 638 | while (--i >= 0) |
640 | regulator_unregister(ab3100_regulators[i].rdev); | 639 | regulator_unregister(ab3100_regulators[i].rdev); |
641 | i--; | ||
642 | } | ||
643 | return err; | 640 | return err; |
644 | } | 641 | } |
645 | 642 | ||
diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index dc3f1a49167..28c7ae67cec 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c | |||
@@ -157,7 +157,7 @@ static int ab8500_list_voltage(struct regulator_dev *rdev, unsigned selector) | |||
157 | if (info->fixed_uV) | 157 | if (info->fixed_uV) |
158 | return info->fixed_uV; | 158 | return info->fixed_uV; |
159 | 159 | ||
160 | if (selector > info->voltages_len) | 160 | if (selector >= info->voltages_len) |
161 | return -EINVAL; | 161 | return -EINVAL; |
162 | 162 | ||
163 | return info->supported_voltages[selector]; | 163 | return info->supported_voltages[selector]; |
@@ -344,13 +344,14 @@ static inline struct ab8500_regulator_info *find_regulator_info(int id) | |||
344 | static __devinit int ab8500_regulator_probe(struct platform_device *pdev) | 344 | static __devinit int ab8500_regulator_probe(struct platform_device *pdev) |
345 | { | 345 | { |
346 | struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); | 346 | struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); |
347 | struct ab8500_platform_data *pdata = dev_get_platdata(ab8500->dev); | 347 | struct ab8500_platform_data *pdata; |
348 | int i, err; | 348 | int i, err; |
349 | 349 | ||
350 | if (!ab8500) { | 350 | if (!ab8500) { |
351 | dev_err(&pdev->dev, "null mfd parent\n"); | 351 | dev_err(&pdev->dev, "null mfd parent\n"); |
352 | return -EINVAL; | 352 | return -EINVAL; |
353 | } | 353 | } |
354 | pdata = dev_get_platdata(ab8500->dev); | ||
354 | 355 | ||
355 | /* register all regulators */ | 356 | /* register all regulators */ |
356 | for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) { | 357 | for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) { |
@@ -368,11 +369,9 @@ static __devinit int ab8500_regulator_probe(struct platform_device *pdev) | |||
368 | dev_err(&pdev->dev, "failed to register regulator %s\n", | 369 | dev_err(&pdev->dev, "failed to register regulator %s\n", |
369 | info->desc.name); | 370 | info->desc.name); |
370 | /* when we fail, un-register all earlier regulators */ | 371 | /* when we fail, un-register all earlier regulators */ |
371 | i--; | 372 | while (--i >= 0) { |
372 | while (i > 0) { | ||
373 | info = &ab8500_regulator_info[i]; | 373 | info = &ab8500_regulator_info[i]; |
374 | regulator_unregister(info->regulator); | 374 | regulator_unregister(info->regulator); |
375 | i--; | ||
376 | } | 375 | } |
377 | return err; | 376 | return err; |
378 | } | 377 | } |
diff --git a/drivers/regulator/ad5398.c b/drivers/regulator/ad5398.c index d59d2f2314a..a4be41614ee 100644 --- a/drivers/regulator/ad5398.c +++ b/drivers/regulator/ad5398.c | |||
@@ -25,7 +25,7 @@ struct ad5398_chip_info { | |||
25 | unsigned int current_level; | 25 | unsigned int current_level; |
26 | unsigned int current_mask; | 26 | unsigned int current_mask; |
27 | unsigned int current_offset; | 27 | unsigned int current_offset; |
28 | struct regulator_dev rdev; | 28 | struct regulator_dev *rdev; |
29 | }; | 29 | }; |
30 | 30 | ||
31 | static int ad5398_calc_current(struct ad5398_chip_info *chip, | 31 | static int ad5398_calc_current(struct ad5398_chip_info *chip, |
@@ -211,7 +211,6 @@ MODULE_DEVICE_TABLE(i2c, ad5398_id); | |||
211 | static int __devinit ad5398_probe(struct i2c_client *client, | 211 | static int __devinit ad5398_probe(struct i2c_client *client, |
212 | const struct i2c_device_id *id) | 212 | const struct i2c_device_id *id) |
213 | { | 213 | { |
214 | struct regulator_dev *rdev; | ||
215 | struct regulator_init_data *init_data = client->dev.platform_data; | 214 | struct regulator_init_data *init_data = client->dev.platform_data; |
216 | struct ad5398_chip_info *chip; | 215 | struct ad5398_chip_info *chip; |
217 | const struct ad5398_current_data_format *df = | 216 | const struct ad5398_current_data_format *df = |
@@ -233,9 +232,10 @@ static int __devinit ad5398_probe(struct i2c_client *client, | |||
233 | chip->current_offset = df->current_offset; | 232 | chip->current_offset = df->current_offset; |
234 | chip->current_mask = (chip->current_level - 1) << chip->current_offset; | 233 | chip->current_mask = (chip->current_level - 1) << chip->current_offset; |
235 | 234 | ||
236 | rdev = regulator_register(&ad5398_reg, &client->dev, init_data, chip); | 235 | chip->rdev = regulator_register(&ad5398_reg, &client->dev, |
237 | if (IS_ERR(rdev)) { | 236 | init_data, chip); |
238 | ret = PTR_ERR(rdev); | 237 | if (IS_ERR(chip->rdev)) { |
238 | ret = PTR_ERR(chip->rdev); | ||
239 | dev_err(&client->dev, "failed to register %s %s\n", | 239 | dev_err(&client->dev, "failed to register %s %s\n", |
240 | id->name, ad5398_reg.name); | 240 | id->name, ad5398_reg.name); |
241 | goto err; | 241 | goto err; |
@@ -254,9 +254,8 @@ static int __devexit ad5398_remove(struct i2c_client *client) | |||
254 | { | 254 | { |
255 | struct ad5398_chip_info *chip = i2c_get_clientdata(client); | 255 | struct ad5398_chip_info *chip = i2c_get_clientdata(client); |
256 | 256 | ||
257 | regulator_unregister(&chip->rdev); | 257 | regulator_unregister(chip->rdev); |
258 | kfree(chip); | 258 | kfree(chip); |
259 | i2c_set_clientdata(client, NULL); | ||
260 | 259 | ||
261 | return 0; | 260 | return 0; |
262 | } | 261 | } |
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 422a709d271..cc8b337b911 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
@@ -700,7 +700,7 @@ static void print_constraints(struct regulator_dev *rdev) | |||
700 | constraints->min_uA != constraints->max_uA) { | 700 | constraints->min_uA != constraints->max_uA) { |
701 | ret = _regulator_get_current_limit(rdev); | 701 | ret = _regulator_get_current_limit(rdev); |
702 | if (ret > 0) | 702 | if (ret > 0) |
703 | count += sprintf(buf + count, "at %d uA ", ret / 1000); | 703 | count += sprintf(buf + count, "at %d mA ", ret / 1000); |
704 | } | 704 | } |
705 | 705 | ||
706 | if (constraints->valid_modes_mask & REGULATOR_MODE_FAST) | 706 | if (constraints->valid_modes_mask & REGULATOR_MODE_FAST) |
@@ -2302,8 +2302,10 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, | |||
2302 | dev_set_name(&rdev->dev, "regulator.%d", | 2302 | dev_set_name(&rdev->dev, "regulator.%d", |
2303 | atomic_inc_return(®ulator_no) - 1); | 2303 | atomic_inc_return(®ulator_no) - 1); |
2304 | ret = device_register(&rdev->dev); | 2304 | ret = device_register(&rdev->dev); |
2305 | if (ret != 0) | 2305 | if (ret != 0) { |
2306 | put_device(&rdev->dev); | ||
2306 | goto clean; | 2307 | goto clean; |
2308 | } | ||
2307 | 2309 | ||
2308 | dev_set_drvdata(&rdev->dev, rdev); | 2310 | dev_set_drvdata(&rdev->dev, rdev); |
2309 | 2311 | ||
diff --git a/drivers/regulator/isl6271a-regulator.c b/drivers/regulator/isl6271a-regulator.c index e49d2bd393f..b8cc6389a54 100644 --- a/drivers/regulator/isl6271a-regulator.c +++ b/drivers/regulator/isl6271a-regulator.c | |||
@@ -165,7 +165,7 @@ static int __devinit isl6271a_probe(struct i2c_client *i2c, | |||
165 | mutex_init(&pmic->mtx); | 165 | mutex_init(&pmic->mtx); |
166 | 166 | ||
167 | for (i = 0; i < 3; i++) { | 167 | for (i = 0; i < 3; i++) { |
168 | pmic->rdev[i] = regulator_register(&isl_rd[0], &i2c->dev, | 168 | pmic->rdev[i] = regulator_register(&isl_rd[i], &i2c->dev, |
169 | init_data, pmic); | 169 | init_data, pmic); |
170 | if (IS_ERR(pmic->rdev[i])) { | 170 | if (IS_ERR(pmic->rdev[i])) { |
171 | dev_err(&i2c->dev, "failed to register %s\n", id->name); | 171 | dev_err(&i2c->dev, "failed to register %s\n", id->name); |
@@ -191,8 +191,6 @@ static int __devexit isl6271a_remove(struct i2c_client *i2c) | |||
191 | struct isl_pmic *pmic = i2c_get_clientdata(i2c); | 191 | struct isl_pmic *pmic = i2c_get_clientdata(i2c); |
192 | int i; | 192 | int i; |
193 | 193 | ||
194 | i2c_set_clientdata(i2c, NULL); | ||
195 | |||
196 | for (i = 0; i < 3; i++) | 194 | for (i = 0; i < 3; i++) |
197 | regulator_unregister(pmic->rdev[i]); | 195 | regulator_unregister(pmic->rdev[i]); |
198 | 196 | ||
diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c index 8867c2710a6..559cfa271a4 100644 --- a/drivers/regulator/max1586.c +++ b/drivers/regulator/max1586.c | |||
@@ -121,14 +121,14 @@ static int max1586_v6_set(struct regulator_dev *rdev, int min_uV, int max_uV) | |||
121 | if (max_uV < MAX1586_V6_MIN_UV || max_uV > MAX1586_V6_MAX_UV) | 121 | if (max_uV < MAX1586_V6_MIN_UV || max_uV > MAX1586_V6_MAX_UV) |
122 | return -EINVAL; | 122 | return -EINVAL; |
123 | 123 | ||
124 | if (min_uV >= 3000000) | ||
125 | selector = 3; | ||
126 | if (min_uV < 3000000) | ||
127 | selector = 2; | ||
128 | if (min_uV < 2500000) | ||
129 | selector = 1; | ||
130 | if (min_uV < 1800000) | 124 | if (min_uV < 1800000) |
131 | selector = 0; | 125 | selector = 0; |
126 | else if (min_uV < 2500000) | ||
127 | selector = 1; | ||
128 | else if (min_uV < 3000000) | ||
129 | selector = 2; | ||
130 | else if (min_uV >= 3000000) | ||
131 | selector = 3; | ||
132 | 132 | ||
133 | if (max1586_v6_calc_voltage(selector) > max_uV) | 133 | if (max1586_v6_calc_voltage(selector) > max_uV) |
134 | return -EINVAL; | 134 | return -EINVAL; |
diff --git a/drivers/regulator/max8649.c b/drivers/regulator/max8649.c index 4520ace3f7e..6b60a9c0366 100644 --- a/drivers/regulator/max8649.c +++ b/drivers/regulator/max8649.c | |||
@@ -330,7 +330,7 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client, | |||
330 | /* set external clock frequency */ | 330 | /* set external clock frequency */ |
331 | info->extclk_freq = pdata->extclk_freq; | 331 | info->extclk_freq = pdata->extclk_freq; |
332 | max8649_set_bits(info->i2c, MAX8649_SYNC, MAX8649_EXT_MASK, | 332 | max8649_set_bits(info->i2c, MAX8649_SYNC, MAX8649_EXT_MASK, |
333 | info->extclk_freq); | 333 | info->extclk_freq << 6); |
334 | } | 334 | } |
335 | 335 | ||
336 | if (pdata->ramp_timing) { | 336 | if (pdata->ramp_timing) { |
diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c index ab67298799f..a1baf1fbe00 100644 --- a/drivers/regulator/max8998.c +++ b/drivers/regulator/max8998.c | |||
@@ -549,7 +549,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) | |||
549 | if (!max8998) | 549 | if (!max8998) |
550 | return -ENOMEM; | 550 | return -ENOMEM; |
551 | 551 | ||
552 | size = sizeof(struct regulator_dev *) * (pdata->num_regulators + 1); | 552 | size = sizeof(struct regulator_dev *) * pdata->num_regulators; |
553 | max8998->rdev = kzalloc(size, GFP_KERNEL); | 553 | max8998->rdev = kzalloc(size, GFP_KERNEL); |
554 | if (!max8998->rdev) { | 554 | if (!max8998->rdev) { |
555 | kfree(max8998); | 555 | kfree(max8998); |
@@ -557,7 +557,9 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) | |||
557 | } | 557 | } |
558 | 558 | ||
559 | rdev = max8998->rdev; | 559 | rdev = max8998->rdev; |
560 | max8998->dev = &pdev->dev; | ||
560 | max8998->iodev = iodev; | 561 | max8998->iodev = iodev; |
562 | max8998->num_regulators = pdata->num_regulators; | ||
561 | platform_set_drvdata(pdev, max8998); | 563 | platform_set_drvdata(pdev, max8998); |
562 | 564 | ||
563 | for (i = 0; i < pdata->num_regulators; i++) { | 565 | for (i = 0; i < pdata->num_regulators; i++) { |
@@ -583,7 +585,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) | |||
583 | 585 | ||
584 | return 0; | 586 | return 0; |
585 | err: | 587 | err: |
586 | for (i = 0; i <= max8998->num_regulators; i++) | 588 | for (i = 0; i < max8998->num_regulators; i++) |
587 | if (rdev[i]) | 589 | if (rdev[i]) |
588 | regulator_unregister(rdev[i]); | 590 | regulator_unregister(rdev[i]); |
589 | 591 | ||
@@ -599,7 +601,7 @@ static int __devexit max8998_pmic_remove(struct platform_device *pdev) | |||
599 | struct regulator_dev **rdev = max8998->rdev; | 601 | struct regulator_dev **rdev = max8998->rdev; |
600 | int i; | 602 | int i; |
601 | 603 | ||
602 | for (i = 0; i <= max8998->num_regulators; i++) | 604 | for (i = 0; i < max8998->num_regulators; i++) |
603 | if (rdev[i]) | 605 | if (rdev[i]) |
604 | regulator_unregister(rdev[i]); | 606 | regulator_unregister(rdev[i]); |
605 | 607 | ||
diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c index c239f42aa4a..020f5878d7f 100644 --- a/drivers/regulator/tps6507x-regulator.c +++ b/drivers/regulator/tps6507x-regulator.c | |||
@@ -626,12 +626,6 @@ fail: | |||
626 | return error; | 626 | return error; |
627 | } | 627 | } |
628 | 628 | ||
629 | /** | ||
630 | * tps6507x_remove - TPS6507x driver i2c remove handler | ||
631 | * @client: i2c driver client device structure | ||
632 | * | ||
633 | * Unregister TPS driver as an i2c client device driver | ||
634 | */ | ||
635 | static int __devexit tps6507x_pmic_remove(struct platform_device *pdev) | 629 | static int __devexit tps6507x_pmic_remove(struct platform_device *pdev) |
636 | { | 630 | { |
637 | struct tps6507x_dev *tps6507x_dev = platform_get_drvdata(pdev); | 631 | struct tps6507x_dev *tps6507x_dev = platform_get_drvdata(pdev); |
diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c index 8cff1413a14..51237fbb1bb 100644 --- a/drivers/regulator/tps6586x-regulator.c +++ b/drivers/regulator/tps6586x-regulator.c | |||
@@ -133,7 +133,7 @@ static int tps6586x_ldo_get_voltage(struct regulator_dev *rdev) | |||
133 | mask = ((1 << ri->volt_nbits) - 1) << ri->volt_shift; | 133 | mask = ((1 << ri->volt_nbits) - 1) << ri->volt_shift; |
134 | val = (val & mask) >> ri->volt_shift; | 134 | val = (val & mask) >> ri->volt_shift; |
135 | 135 | ||
136 | if (val > ri->desc.n_voltages) | 136 | if (val >= ri->desc.n_voltages) |
137 | BUG(); | 137 | BUG(); |
138 | 138 | ||
139 | return ri->voltages[val] * 1000; | 139 | return ri->voltages[val] * 1000; |
@@ -150,7 +150,7 @@ static int tps6586x_dvm_set_voltage(struct regulator_dev *rdev, | |||
150 | if (ret) | 150 | if (ret) |
151 | return ret; | 151 | return ret; |
152 | 152 | ||
153 | return tps6586x_set_bits(parent, ri->go_reg, ri->go_bit); | 153 | return tps6586x_set_bits(parent, ri->go_reg, 1 << ri->go_bit); |
154 | } | 154 | } |
155 | 155 | ||
156 | static int tps6586x_regulator_enable(struct regulator_dev *rdev) | 156 | static int tps6586x_regulator_enable(struct regulator_dev *rdev) |
diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c index e686cdb61b9..9edf8f69234 100644 --- a/drivers/regulator/wm831x-ldo.c +++ b/drivers/regulator/wm831x-ldo.c | |||
@@ -215,8 +215,7 @@ static int wm831x_gp_ldo_set_mode(struct regulator_dev *rdev, | |||
215 | 215 | ||
216 | case REGULATOR_MODE_IDLE: | 216 | case REGULATOR_MODE_IDLE: |
217 | ret = wm831x_set_bits(wm831x, ctrl_reg, | 217 | ret = wm831x_set_bits(wm831x, ctrl_reg, |
218 | WM831X_LDO1_LP_MODE, | 218 | WM831X_LDO1_LP_MODE, 0); |
219 | WM831X_LDO1_LP_MODE); | ||
220 | if (ret < 0) | 219 | if (ret < 0) |
221 | return ret; | 220 | return ret; |
222 | 221 | ||
@@ -225,10 +224,12 @@ static int wm831x_gp_ldo_set_mode(struct regulator_dev *rdev, | |||
225 | WM831X_LDO1_ON_MODE); | 224 | WM831X_LDO1_ON_MODE); |
226 | if (ret < 0) | 225 | if (ret < 0) |
227 | return ret; | 226 | return ret; |
227 | break; | ||
228 | 228 | ||
229 | case REGULATOR_MODE_STANDBY: | 229 | case REGULATOR_MODE_STANDBY: |
230 | ret = wm831x_set_bits(wm831x, ctrl_reg, | 230 | ret = wm831x_set_bits(wm831x, ctrl_reg, |
231 | WM831X_LDO1_LP_MODE, 0); | 231 | WM831X_LDO1_LP_MODE, |
232 | WM831X_LDO1_LP_MODE); | ||
232 | if (ret < 0) | 233 | if (ret < 0) |
233 | return ret; | 234 | return ret; |
234 | 235 | ||
diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c index 0e6ed7db936..fe4b8a8a9df 100644 --- a/drivers/regulator/wm8350-regulator.c +++ b/drivers/regulator/wm8350-regulator.c | |||
@@ -1129,7 +1129,7 @@ static unsigned int wm8350_dcdc_get_mode(struct regulator_dev *rdev) | |||
1129 | mode = REGULATOR_MODE_NORMAL; | 1129 | mode = REGULATOR_MODE_NORMAL; |
1130 | } else if (!active && !sleep) | 1130 | } else if (!active && !sleep) |
1131 | mode = REGULATOR_MODE_IDLE; | 1131 | mode = REGULATOR_MODE_IDLE; |
1132 | else if (!sleep) | 1132 | else if (sleep) |
1133 | mode = REGULATOR_MODE_STANDBY; | 1133 | mode = REGULATOR_MODE_STANDBY; |
1134 | 1134 | ||
1135 | return mode; | 1135 | return mode; |
diff --git a/drivers/rtc/rtc-ab3100.c b/drivers/rtc/rtc-ab3100.c index d26780ea254..261a07e0fb2 100644 --- a/drivers/rtc/rtc-ab3100.c +++ b/drivers/rtc/rtc-ab3100.c | |||
@@ -235,6 +235,7 @@ static int __init ab3100_rtc_probe(struct platform_device *pdev) | |||
235 | err = PTR_ERR(rtc); | 235 | err = PTR_ERR(rtc); |
236 | return err; | 236 | return err; |
237 | } | 237 | } |
238 | platform_set_drvdata(pdev, rtc); | ||
238 | 239 | ||
239 | return 0; | 240 | return 0; |
240 | } | 241 | } |
@@ -244,6 +245,7 @@ static int __exit ab3100_rtc_remove(struct platform_device *pdev) | |||
244 | struct rtc_device *rtc = platform_get_drvdata(pdev); | 245 | struct rtc_device *rtc = platform_get_drvdata(pdev); |
245 | 246 | ||
246 | rtc_device_unregister(rtc); | 247 | rtc_device_unregister(rtc); |
248 | platform_set_drvdata(pdev, NULL); | ||
247 | return 0; | 249 | return 0; |
248 | } | 250 | } |
249 | 251 | ||
diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c index 72b2bcc2c22..d4fb82d85e9 100644 --- a/drivers/rtc/rtc-bfin.c +++ b/drivers/rtc/rtc-bfin.c | |||
@@ -426,7 +426,7 @@ static int bfin_rtc_suspend(struct platform_device *pdev, pm_message_t state) | |||
426 | enable_irq_wake(IRQ_RTC); | 426 | enable_irq_wake(IRQ_RTC); |
427 | bfin_rtc_sync_pending(&pdev->dev); | 427 | bfin_rtc_sync_pending(&pdev->dev); |
428 | } else | 428 | } else |
429 | bfin_rtc_int_clear(-1); | 429 | bfin_rtc_int_clear(0); |
430 | 430 | ||
431 | return 0; | 431 | return 0; |
432 | } | 432 | } |
@@ -435,8 +435,17 @@ static int bfin_rtc_resume(struct platform_device *pdev) | |||
435 | { | 435 | { |
436 | if (device_may_wakeup(&pdev->dev)) | 436 | if (device_may_wakeup(&pdev->dev)) |
437 | disable_irq_wake(IRQ_RTC); | 437 | disable_irq_wake(IRQ_RTC); |
438 | else | 438 | |
439 | bfin_write_RTC_ISTAT(-1); | 439 | /* |
440 | * Since only some of the RTC bits are maintained externally in the | ||
441 | * Vbat domain, we need to wait for the RTC MMRs to be synced into | ||
442 | * the core after waking up. This happens every RTC 1HZ. Once that | ||
443 | * has happened, we can go ahead and re-enable the important write | ||
444 | * complete interrupt event. | ||
445 | */ | ||
446 | while (!(bfin_read_RTC_ISTAT() & RTC_ISTAT_SEC)) | ||
447 | continue; | ||
448 | bfin_rtc_int_set(RTC_ISTAT_WRITE_COMPLETE); | ||
440 | 449 | ||
441 | return 0; | 450 | return 0; |
442 | } | 451 | } |
diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c index 9daed8db83d..9de8516e353 100644 --- a/drivers/rtc/rtc-ds3232.c +++ b/drivers/rtc/rtc-ds3232.c | |||
@@ -268,7 +268,6 @@ out_irq: | |||
268 | free_irq(client->irq, client); | 268 | free_irq(client->irq, client); |
269 | 269 | ||
270 | out_free: | 270 | out_free: |
271 | i2c_set_clientdata(client, NULL); | ||
272 | kfree(ds3232); | 271 | kfree(ds3232); |
273 | return ret; | 272 | return ret; |
274 | } | 273 | } |
@@ -287,7 +286,6 @@ static int __devexit ds3232_remove(struct i2c_client *client) | |||
287 | } | 286 | } |
288 | 287 | ||
289 | rtc_device_unregister(ds3232->rtc); | 288 | rtc_device_unregister(ds3232->rtc); |
290 | i2c_set_clientdata(client, NULL); | ||
291 | kfree(ds3232); | 289 | kfree(ds3232); |
292 | return 0; | 290 | return 0; |
293 | } | 291 | } |
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index 66377f3e28b..d60557cae8e 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c | |||
@@ -364,7 +364,7 @@ static int m41t80_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
364 | t->time.tm_isdst = -1; | 364 | t->time.tm_isdst = -1; |
365 | t->enabled = !!(reg[M41T80_REG_ALARM_MON] & M41T80_ALMON_AFE); | 365 | t->enabled = !!(reg[M41T80_REG_ALARM_MON] & M41T80_ALMON_AFE); |
366 | t->pending = !!(reg[M41T80_REG_FLAGS] & M41T80_FLAGS_AF); | 366 | t->pending = !!(reg[M41T80_REG_FLAGS] & M41T80_FLAGS_AF); |
367 | return rtc_valid_tm(t); | 367 | return 0; |
368 | } | 368 | } |
369 | 369 | ||
370 | static struct rtc_class_ops m41t80_rtc_ops = { | 370 | static struct rtc_class_ops m41t80_rtc_ops = { |
diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c index 6c418fe7f28..b7a6690e5b3 100644 --- a/drivers/rtc/rtc-pl031.c +++ b/drivers/rtc/rtc-pl031.c | |||
@@ -403,7 +403,7 @@ static int pl031_probe(struct amba_device *adev, struct amba_id *id) | |||
403 | } | 403 | } |
404 | 404 | ||
405 | if (request_irq(adev->irq[0], pl031_interrupt, | 405 | if (request_irq(adev->irq[0], pl031_interrupt, |
406 | IRQF_DISABLED | IRQF_SHARED, "rtc-pl031", ldata)) { | 406 | IRQF_DISABLED, "rtc-pl031", ldata)) { |
407 | ret = -EIO; | 407 | ret = -EIO; |
408 | goto out_no_irq; | 408 | goto out_no_irq; |
409 | } | 409 | } |
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index a0d3ec89d41..f57a87f4ae9 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c | |||
@@ -310,11 +310,6 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
310 | 310 | ||
311 | s3c_rtc_setaie(alrm->enabled); | 311 | s3c_rtc_setaie(alrm->enabled); |
312 | 312 | ||
313 | if (alrm->enabled) | ||
314 | enable_irq_wake(s3c_rtc_alarmno); | ||
315 | else | ||
316 | disable_irq_wake(s3c_rtc_alarmno); | ||
317 | |||
318 | return 0; | 313 | return 0; |
319 | } | 314 | } |
320 | 315 | ||
@@ -587,6 +582,10 @@ static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state) | |||
587 | ticnt_en_save &= S3C64XX_RTCCON_TICEN; | 582 | ticnt_en_save &= S3C64XX_RTCCON_TICEN; |
588 | } | 583 | } |
589 | s3c_rtc_enable(pdev, 0); | 584 | s3c_rtc_enable(pdev, 0); |
585 | |||
586 | if (device_may_wakeup(&pdev->dev)) | ||
587 | enable_irq_wake(s3c_rtc_alarmno); | ||
588 | |||
590 | return 0; | 589 | return 0; |
591 | } | 590 | } |
592 | 591 | ||
@@ -600,6 +599,10 @@ static int s3c_rtc_resume(struct platform_device *pdev) | |||
600 | tmp = readb(s3c_rtc_base + S3C2410_RTCCON); | 599 | tmp = readb(s3c_rtc_base + S3C2410_RTCCON); |
601 | writeb(tmp | ticnt_en_save, s3c_rtc_base + S3C2410_RTCCON); | 600 | writeb(tmp | ticnt_en_save, s3c_rtc_base + S3C2410_RTCCON); |
602 | } | 601 | } |
602 | |||
603 | if (device_may_wakeup(&pdev->dev)) | ||
604 | disable_irq_wake(s3c_rtc_alarmno); | ||
605 | |||
603 | return 0; | 606 | return 0; |
604 | } | 607 | } |
605 | #else | 608 | #else |
diff --git a/drivers/s390/char/ctrlchar.c b/drivers/s390/char/ctrlchar.c index c6cbcb3f925..0e9a309b966 100644 --- a/drivers/s390/char/ctrlchar.c +++ b/drivers/s390/char/ctrlchar.c | |||
@@ -16,12 +16,11 @@ | |||
16 | 16 | ||
17 | #ifdef CONFIG_MAGIC_SYSRQ | 17 | #ifdef CONFIG_MAGIC_SYSRQ |
18 | static int ctrlchar_sysrq_key; | 18 | static int ctrlchar_sysrq_key; |
19 | static struct tty_struct *sysrq_tty; | ||
20 | 19 | ||
21 | static void | 20 | static void |
22 | ctrlchar_handle_sysrq(struct work_struct *work) | 21 | ctrlchar_handle_sysrq(struct work_struct *work) |
23 | { | 22 | { |
24 | handle_sysrq(ctrlchar_sysrq_key, sysrq_tty); | 23 | handle_sysrq(ctrlchar_sysrq_key); |
25 | } | 24 | } |
26 | 25 | ||
27 | static DECLARE_WORK(ctrlchar_work, ctrlchar_handle_sysrq); | 26 | static DECLARE_WORK(ctrlchar_work, ctrlchar_handle_sysrq); |
@@ -54,7 +53,6 @@ ctrlchar_handle(const unsigned char *buf, int len, struct tty_struct *tty) | |||
54 | /* racy */ | 53 | /* racy */ |
55 | if (len == 3 && buf[1] == '-') { | 54 | if (len == 3 && buf[1] == '-') { |
56 | ctrlchar_sysrq_key = buf[2]; | 55 | ctrlchar_sysrq_key = buf[2]; |
57 | sysrq_tty = tty; | ||
58 | schedule_work(&ctrlchar_work); | 56 | schedule_work(&ctrlchar_work); |
59 | return CTRLCHAR_SYSRQ; | 57 | return CTRLCHAR_SYSRQ; |
60 | } | 58 | } |
diff --git a/drivers/s390/char/keyboard.c b/drivers/s390/char/keyboard.c index 18d9a497863..8cd58e412b5 100644 --- a/drivers/s390/char/keyboard.c +++ b/drivers/s390/char/keyboard.c | |||
@@ -305,7 +305,7 @@ kbd_keycode(struct kbd_data *kbd, unsigned int keycode) | |||
305 | if (kbd->sysrq) { | 305 | if (kbd->sysrq) { |
306 | if (kbd->sysrq == K(KT_LATIN, '-')) { | 306 | if (kbd->sysrq == K(KT_LATIN, '-')) { |
307 | kbd->sysrq = 0; | 307 | kbd->sysrq = 0; |
308 | handle_sysrq(value, kbd->tty); | 308 | handle_sysrq(value); |
309 | return; | 309 | return; |
310 | } | 310 | } |
311 | if (value == '-') { | 311 | if (value == '-') { |
diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c index b7de02525ec..85cf607fc78 100644 --- a/drivers/s390/char/tape_block.c +++ b/drivers/s390/char/tape_block.c | |||
@@ -217,8 +217,7 @@ tapeblock_setup_device(struct tape_device * device) | |||
217 | if (!blkdat->request_queue) | 217 | if (!blkdat->request_queue) |
218 | return -ENOMEM; | 218 | return -ENOMEM; |
219 | 219 | ||
220 | elevator_exit(blkdat->request_queue->elevator); | 220 | rc = elevator_change(blkdat->request_queue, "noop"); |
221 | rc = elevator_init(blkdat->request_queue, "noop"); | ||
222 | if (rc) | 221 | if (rc) |
223 | goto cleanup_queue; | 222 | goto cleanup_queue; |
224 | 223 | ||
diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c index 6edf20b62de..2c7d2d9be4d 100644 --- a/drivers/s390/net/ctcm_main.c +++ b/drivers/s390/net/ctcm_main.c | |||
@@ -1154,7 +1154,7 @@ static struct net_device *ctcm_init_netdevice(struct ctcm_priv *priv) | |||
1154 | dev_fsm, dev_fsm_len, GFP_KERNEL); | 1154 | dev_fsm, dev_fsm_len, GFP_KERNEL); |
1155 | if (priv->fsm == NULL) { | 1155 | if (priv->fsm == NULL) { |
1156 | CTCMY_DBF_DEV(SETUP, dev, "init_fsm error"); | 1156 | CTCMY_DBF_DEV(SETUP, dev, "init_fsm error"); |
1157 | kfree(dev); | 1157 | free_netdev(dev); |
1158 | return NULL; | 1158 | return NULL; |
1159 | } | 1159 | } |
1160 | fsm_newstate(priv->fsm, DEV_STATE_STOPPED); | 1160 | fsm_newstate(priv->fsm, DEV_STATE_STOPPED); |
@@ -1165,7 +1165,7 @@ static struct net_device *ctcm_init_netdevice(struct ctcm_priv *priv) | |||
1165 | grp = ctcmpc_init_mpc_group(priv); | 1165 | grp = ctcmpc_init_mpc_group(priv); |
1166 | if (grp == NULL) { | 1166 | if (grp == NULL) { |
1167 | MPC_DBF_DEV(SETUP, dev, "init_mpc_group error"); | 1167 | MPC_DBF_DEV(SETUP, dev, "init_mpc_group error"); |
1168 | kfree(dev); | 1168 | free_netdev(dev); |
1169 | return NULL; | 1169 | return NULL; |
1170 | } | 1170 | } |
1171 | tasklet_init(&grp->mpc_tasklet2, | 1171 | tasklet_init(&grp->mpc_tasklet2, |
diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c index 7d4d2275573..7f11f3e48e1 100644 --- a/drivers/scsi/be2iscsi/be_iscsi.c +++ b/drivers/scsi/be2iscsi/be_iscsi.c | |||
@@ -300,8 +300,7 @@ int beiscsi_get_host_param(struct Scsi_Host *shost, | |||
300 | enum iscsi_host_param param, char *buf) | 300 | enum iscsi_host_param param, char *buf) |
301 | { | 301 | { |
302 | struct beiscsi_hba *phba = (struct beiscsi_hba *)iscsi_host_priv(shost); | 302 | struct beiscsi_hba *phba = (struct beiscsi_hba *)iscsi_host_priv(shost); |
303 | int len = 0; | 303 | int status = 0; |
304 | int status; | ||
305 | 304 | ||
306 | SE_DEBUG(DBG_LVL_8, "In beiscsi_get_host_param, param= %d\n", param); | 305 | SE_DEBUG(DBG_LVL_8, "In beiscsi_get_host_param, param= %d\n", param); |
307 | switch (param) { | 306 | switch (param) { |
@@ -315,7 +314,7 @@ int beiscsi_get_host_param(struct Scsi_Host *shost, | |||
315 | default: | 314 | default: |
316 | return iscsi_host_get_param(shost, param, buf); | 315 | return iscsi_host_get_param(shost, param, buf); |
317 | } | 316 | } |
318 | return len; | 317 | return status; |
319 | } | 318 | } |
320 | 319 | ||
321 | int beiscsi_get_macaddr(char *buf, struct beiscsi_hba *phba) | 320 | int beiscsi_get_macaddr(char *buf, struct beiscsi_hba *phba) |
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c index 26350e470bc..877324fc594 100644 --- a/drivers/scsi/be2iscsi/be_mgmt.c +++ b/drivers/scsi/be2iscsi/be_mgmt.c | |||
@@ -368,7 +368,7 @@ int mgmt_open_connection(struct beiscsi_hba *phba, | |||
368 | memset(req, 0, sizeof(*req)); | 368 | memset(req, 0, sizeof(*req)); |
369 | wrb->tag0 |= tag; | 369 | wrb->tag0 |= tag; |
370 | 370 | ||
371 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 1); | 371 | be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1); |
372 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, | 372 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, |
373 | OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD, | 373 | OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD, |
374 | sizeof(*req)); | 374 | sizeof(*req)); |
diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c index cd05e049d5f..d0c82340f0e 100644 --- a/drivers/scsi/constants.c +++ b/drivers/scsi/constants.c | |||
@@ -1404,13 +1404,13 @@ void scsi_print_sense(char *name, struct scsi_cmnd *cmd) | |||
1404 | { | 1404 | { |
1405 | struct scsi_sense_hdr sshdr; | 1405 | struct scsi_sense_hdr sshdr; |
1406 | 1406 | ||
1407 | scmd_printk(KERN_INFO, cmd, ""); | 1407 | scmd_printk(KERN_INFO, cmd, " "); |
1408 | scsi_decode_sense_buffer(cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE, | 1408 | scsi_decode_sense_buffer(cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE, |
1409 | &sshdr); | 1409 | &sshdr); |
1410 | scsi_show_sense_hdr(&sshdr); | 1410 | scsi_show_sense_hdr(&sshdr); |
1411 | scsi_decode_sense_extras(cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE, | 1411 | scsi_decode_sense_extras(cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE, |
1412 | &sshdr); | 1412 | &sshdr); |
1413 | scmd_printk(KERN_INFO, cmd, ""); | 1413 | scmd_printk(KERN_INFO, cmd, " "); |
1414 | scsi_show_extd_sense(sshdr.asc, sshdr.ascq); | 1414 | scsi_show_extd_sense(sshdr.asc, sshdr.ascq); |
1415 | } | 1415 | } |
1416 | EXPORT_SYMBOL(scsi_print_sense); | 1416 | EXPORT_SYMBOL(scsi_print_sense); |
@@ -1453,7 +1453,7 @@ EXPORT_SYMBOL(scsi_show_result); | |||
1453 | 1453 | ||
1454 | void scsi_print_result(struct scsi_cmnd *cmd) | 1454 | void scsi_print_result(struct scsi_cmnd *cmd) |
1455 | { | 1455 | { |
1456 | scmd_printk(KERN_INFO, cmd, ""); | 1456 | scmd_printk(KERN_INFO, cmd, " "); |
1457 | scsi_show_result(cmd->result); | 1457 | scsi_show_result(cmd->result); |
1458 | } | 1458 | } |
1459 | EXPORT_SYMBOL(scsi_print_result); | 1459 | EXPORT_SYMBOL(scsi_print_result); |
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 4f5551b5fe5..c5d0606ad09 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c | |||
@@ -3231,6 +3231,12 @@ static __devinit int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev) | |||
3231 | misc_fw_support = readl(&cfgtable->misc_fw_support); | 3231 | misc_fw_support = readl(&cfgtable->misc_fw_support); |
3232 | use_doorbell = misc_fw_support & MISC_FW_DOORBELL_RESET; | 3232 | use_doorbell = misc_fw_support & MISC_FW_DOORBELL_RESET; |
3233 | 3233 | ||
3234 | /* The doorbell reset seems to cause lockups on some Smart | ||
3235 | * Arrays (e.g. P410, P410i, maybe others). Until this is | ||
3236 | * fixed or at least isolated, avoid the doorbell reset. | ||
3237 | */ | ||
3238 | use_doorbell = 0; | ||
3239 | |||
3234 | rc = hpsa_controller_hard_reset(pdev, vaddr, use_doorbell); | 3240 | rc = hpsa_controller_hard_reset(pdev, vaddr, use_doorbell); |
3235 | if (rc) | 3241 | if (rc) |
3236 | goto unmap_cfgtable; | 3242 | goto unmap_cfgtable; |
diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c index fda4de3440c..e88bbdde49c 100644 --- a/drivers/scsi/osd/osd_initiator.c +++ b/drivers/scsi/osd/osd_initiator.c | |||
@@ -865,7 +865,7 @@ void osd_req_read(struct osd_request *or, | |||
865 | { | 865 | { |
866 | _osd_req_encode_common(or, OSD_ACT_READ, obj, offset, len); | 866 | _osd_req_encode_common(or, OSD_ACT_READ, obj, offset, len); |
867 | WARN_ON(or->in.bio || or->in.total_bytes); | 867 | WARN_ON(or->in.bio || or->in.total_bytes); |
868 | WARN_ON(1 == (bio->bi_rw & REQ_WRITE)); | 868 | WARN_ON(bio->bi_rw & REQ_WRITE); |
869 | or->in.bio = bio; | 869 | or->in.bio = bio; |
870 | or->in.total_bytes = len; | 870 | or->in.total_bytes = len; |
871 | } | 871 | } |
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 420238cc794..114bc5a8117 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -1838,26 +1838,33 @@ qla24xx_vport_delete(struct fc_vport *fc_vport) | |||
1838 | 1838 | ||
1839 | qla24xx_disable_vp(vha); | 1839 | qla24xx_disable_vp(vha); |
1840 | 1840 | ||
1841 | vha->flags.delete_progress = 1; | ||
1842 | |||
1841 | fc_remove_host(vha->host); | 1843 | fc_remove_host(vha->host); |
1842 | 1844 | ||
1843 | scsi_remove_host(vha->host); | 1845 | scsi_remove_host(vha->host); |
1844 | 1846 | ||
1845 | qla2x00_free_fcports(vha); | 1847 | if (vha->timer_active) { |
1848 | qla2x00_vp_stop_timer(vha); | ||
1849 | DEBUG15(printk(KERN_INFO "scsi(%ld): timer for the vport[%d]" | ||
1850 | " = %p has stopped\n", vha->host_no, vha->vp_idx, vha)); | ||
1851 | } | ||
1846 | 1852 | ||
1847 | qla24xx_deallocate_vp_id(vha); | 1853 | qla24xx_deallocate_vp_id(vha); |
1848 | 1854 | ||
1855 | /* No pending activities shall be there on the vha now */ | ||
1856 | DEBUG(msleep(random32()%10)); /* Just to see if something falls on | ||
1857 | * the net we have placed below */ | ||
1858 | |||
1859 | BUG_ON(atomic_read(&vha->vref_count)); | ||
1860 | |||
1861 | qla2x00_free_fcports(vha); | ||
1862 | |||
1849 | mutex_lock(&ha->vport_lock); | 1863 | mutex_lock(&ha->vport_lock); |
1850 | ha->cur_vport_count--; | 1864 | ha->cur_vport_count--; |
1851 | clear_bit(vha->vp_idx, ha->vp_idx_map); | 1865 | clear_bit(vha->vp_idx, ha->vp_idx_map); |
1852 | mutex_unlock(&ha->vport_lock); | 1866 | mutex_unlock(&ha->vport_lock); |
1853 | 1867 | ||
1854 | if (vha->timer_active) { | ||
1855 | qla2x00_vp_stop_timer(vha); | ||
1856 | DEBUG15(printk ("scsi(%ld): timer for the vport[%d] = %p " | ||
1857 | "has stopped\n", | ||
1858 | vha->host_no, vha->vp_idx, vha)); | ||
1859 | } | ||
1860 | |||
1861 | if (vha->req->id && !ha->flags.cpu_affinity_enabled) { | 1868 | if (vha->req->id && !ha->flags.cpu_affinity_enabled) { |
1862 | if (qla25xx_delete_req_que(vha, vha->req) != QLA_SUCCESS) | 1869 | if (qla25xx_delete_req_que(vha, vha->req) != QLA_SUCCESS) |
1863 | qla_printk(KERN_WARNING, ha, | 1870 | qla_printk(KERN_WARNING, ha, |
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h index 6cfc28a25eb..b74e6b5743d 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.h +++ b/drivers/scsi/qla2xxx/qla_dbg.h | |||
@@ -29,8 +29,6 @@ | |||
29 | /* #define QL_DEBUG_LEVEL_17 */ /* Output EEH trace messages */ | 29 | /* #define QL_DEBUG_LEVEL_17 */ /* Output EEH trace messages */ |
30 | /* #define QL_DEBUG_LEVEL_18 */ /* Output T10 CRC trace messages */ | 30 | /* #define QL_DEBUG_LEVEL_18 */ /* Output T10 CRC trace messages */ |
31 | 31 | ||
32 | /* #define QL_PRINTK_BUF */ /* Captures printk to buffer */ | ||
33 | |||
34 | /* | 32 | /* |
35 | * Macros use for debugging the driver. | 33 | * Macros use for debugging the driver. |
36 | */ | 34 | */ |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 3a432ea0c7a..d2a4e153070 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -2641,6 +2641,7 @@ struct qla_hw_data { | |||
2641 | #define MBX_UPDATE_FLASH_ACTIVE 3 | 2641 | #define MBX_UPDATE_FLASH_ACTIVE 3 |
2642 | 2642 | ||
2643 | struct mutex vport_lock; /* Virtual port synchronization */ | 2643 | struct mutex vport_lock; /* Virtual port synchronization */ |
2644 | spinlock_t vport_slock; /* order is hardware_lock, then vport_slock */ | ||
2644 | struct completion mbx_cmd_comp; /* Serialize mbx access */ | 2645 | struct completion mbx_cmd_comp; /* Serialize mbx access */ |
2645 | struct completion mbx_intr_comp; /* Used for completion notification */ | 2646 | struct completion mbx_intr_comp; /* Used for completion notification */ |
2646 | struct completion dcbx_comp; /* For set port config notification */ | 2647 | struct completion dcbx_comp; /* For set port config notification */ |
@@ -2828,6 +2829,7 @@ typedef struct scsi_qla_host { | |||
2828 | uint32_t management_server_logged_in :1; | 2829 | uint32_t management_server_logged_in :1; |
2829 | uint32_t process_response_queue :1; | 2830 | uint32_t process_response_queue :1; |
2830 | uint32_t difdix_supported:1; | 2831 | uint32_t difdix_supported:1; |
2832 | uint32_t delete_progress:1; | ||
2831 | } flags; | 2833 | } flags; |
2832 | 2834 | ||
2833 | atomic_t loop_state; | 2835 | atomic_t loop_state; |
@@ -2922,6 +2924,8 @@ typedef struct scsi_qla_host { | |||
2922 | struct req_que *req; | 2924 | struct req_que *req; |
2923 | int fw_heartbeat_counter; | 2925 | int fw_heartbeat_counter; |
2924 | int seconds_since_last_heartbeat; | 2926 | int seconds_since_last_heartbeat; |
2927 | |||
2928 | atomic_t vref_count; | ||
2925 | } scsi_qla_host_t; | 2929 | } scsi_qla_host_t; |
2926 | 2930 | ||
2927 | /* | 2931 | /* |
@@ -2932,6 +2936,22 @@ typedef struct scsi_qla_host { | |||
2932 | test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || \ | 2936 | test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || \ |
2933 | atomic_read(&ha->loop_state) == LOOP_DOWN) | 2937 | atomic_read(&ha->loop_state) == LOOP_DOWN) |
2934 | 2938 | ||
2939 | #define QLA_VHA_MARK_BUSY(__vha, __bail) do { \ | ||
2940 | atomic_inc(&__vha->vref_count); \ | ||
2941 | mb(); \ | ||
2942 | if (__vha->flags.delete_progress) { \ | ||
2943 | atomic_dec(&__vha->vref_count); \ | ||
2944 | __bail = 1; \ | ||
2945 | } else { \ | ||
2946 | __bail = 0; \ | ||
2947 | } \ | ||
2948 | } while (0) | ||
2949 | |||
2950 | #define QLA_VHA_MARK_NOT_BUSY(__vha) do { \ | ||
2951 | atomic_dec(&__vha->vref_count); \ | ||
2952 | } while (0) | ||
2953 | |||
2954 | |||
2935 | #define qla_printk(level, ha, format, arg...) \ | 2955 | #define qla_printk(level, ha, format, arg...) \ |
2936 | dev_printk(level , &((ha)->pdev->dev) , format , ## arg) | 2956 | dev_printk(level , &((ha)->pdev->dev) , format , ## arg) |
2937 | 2957 | ||
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index d863ed2619b..9c383baebe2 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -69,21 +69,29 @@ qla2x00_ctx_sp_free(srb_t *sp) | |||
69 | { | 69 | { |
70 | struct srb_ctx *ctx = sp->ctx; | 70 | struct srb_ctx *ctx = sp->ctx; |
71 | struct srb_iocb *iocb = ctx->u.iocb_cmd; | 71 | struct srb_iocb *iocb = ctx->u.iocb_cmd; |
72 | struct scsi_qla_host *vha = sp->fcport->vha; | ||
72 | 73 | ||
73 | del_timer_sync(&iocb->timer); | 74 | del_timer_sync(&iocb->timer); |
74 | kfree(iocb); | 75 | kfree(iocb); |
75 | kfree(ctx); | 76 | kfree(ctx); |
76 | mempool_free(sp, sp->fcport->vha->hw->srb_mempool); | 77 | mempool_free(sp, sp->fcport->vha->hw->srb_mempool); |
78 | |||
79 | QLA_VHA_MARK_NOT_BUSY(vha); | ||
77 | } | 80 | } |
78 | 81 | ||
79 | inline srb_t * | 82 | inline srb_t * |
80 | qla2x00_get_ctx_sp(scsi_qla_host_t *vha, fc_port_t *fcport, size_t size, | 83 | qla2x00_get_ctx_sp(scsi_qla_host_t *vha, fc_port_t *fcport, size_t size, |
81 | unsigned long tmo) | 84 | unsigned long tmo) |
82 | { | 85 | { |
83 | srb_t *sp; | 86 | srb_t *sp = NULL; |
84 | struct qla_hw_data *ha = vha->hw; | 87 | struct qla_hw_data *ha = vha->hw; |
85 | struct srb_ctx *ctx; | 88 | struct srb_ctx *ctx; |
86 | struct srb_iocb *iocb; | 89 | struct srb_iocb *iocb; |
90 | uint8_t bail; | ||
91 | |||
92 | QLA_VHA_MARK_BUSY(vha, bail); | ||
93 | if (bail) | ||
94 | return NULL; | ||
87 | 95 | ||
88 | sp = mempool_alloc(ha->srb_mempool, GFP_KERNEL); | 96 | sp = mempool_alloc(ha->srb_mempool, GFP_KERNEL); |
89 | if (!sp) | 97 | if (!sp) |
@@ -116,6 +124,8 @@ qla2x00_get_ctx_sp(scsi_qla_host_t *vha, fc_port_t *fcport, size_t size, | |||
116 | iocb->timer.function = qla2x00_ctx_sp_timeout; | 124 | iocb->timer.function = qla2x00_ctx_sp_timeout; |
117 | add_timer(&iocb->timer); | 125 | add_timer(&iocb->timer); |
118 | done: | 126 | done: |
127 | if (!sp) | ||
128 | QLA_VHA_MARK_NOT_BUSY(vha); | ||
119 | return sp; | 129 | return sp; |
120 | } | 130 | } |
121 | 131 | ||
@@ -1777,11 +1787,15 @@ qla2x00_init_rings(scsi_qla_host_t *vha) | |||
1777 | qla2x00_init_response_q_entries(rsp); | 1787 | qla2x00_init_response_q_entries(rsp); |
1778 | } | 1788 | } |
1779 | 1789 | ||
1790 | spin_lock_irqsave(&ha->vport_slock, flags); | ||
1780 | /* Clear RSCN queue. */ | 1791 | /* Clear RSCN queue. */ |
1781 | list_for_each_entry(vp, &ha->vp_list, list) { | 1792 | list_for_each_entry(vp, &ha->vp_list, list) { |
1782 | vp->rscn_in_ptr = 0; | 1793 | vp->rscn_in_ptr = 0; |
1783 | vp->rscn_out_ptr = 0; | 1794 | vp->rscn_out_ptr = 0; |
1784 | } | 1795 | } |
1796 | |||
1797 | spin_unlock_irqrestore(&ha->vport_slock, flags); | ||
1798 | |||
1785 | ha->isp_ops->config_rings(vha); | 1799 | ha->isp_ops->config_rings(vha); |
1786 | 1800 | ||
1787 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 1801 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
@@ -3218,12 +3232,17 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha, | |||
3218 | /* Bypass virtual ports of the same host. */ | 3232 | /* Bypass virtual ports of the same host. */ |
3219 | found = 0; | 3233 | found = 0; |
3220 | if (ha->num_vhosts) { | 3234 | if (ha->num_vhosts) { |
3235 | unsigned long flags; | ||
3236 | |||
3237 | spin_lock_irqsave(&ha->vport_slock, flags); | ||
3221 | list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) { | 3238 | list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) { |
3222 | if (new_fcport->d_id.b24 == vp->d_id.b24) { | 3239 | if (new_fcport->d_id.b24 == vp->d_id.b24) { |
3223 | found = 1; | 3240 | found = 1; |
3224 | break; | 3241 | break; |
3225 | } | 3242 | } |
3226 | } | 3243 | } |
3244 | spin_unlock_irqrestore(&ha->vport_slock, flags); | ||
3245 | |||
3227 | if (found) | 3246 | if (found) |
3228 | continue; | 3247 | continue; |
3229 | } | 3248 | } |
@@ -3343,6 +3362,7 @@ qla2x00_find_new_loop_id(scsi_qla_host_t *vha, fc_port_t *dev) | |||
3343 | struct qla_hw_data *ha = vha->hw; | 3362 | struct qla_hw_data *ha = vha->hw; |
3344 | struct scsi_qla_host *vp; | 3363 | struct scsi_qla_host *vp; |
3345 | struct scsi_qla_host *tvp; | 3364 | struct scsi_qla_host *tvp; |
3365 | unsigned long flags = 0; | ||
3346 | 3366 | ||
3347 | rval = QLA_SUCCESS; | 3367 | rval = QLA_SUCCESS; |
3348 | 3368 | ||
@@ -3367,6 +3387,8 @@ qla2x00_find_new_loop_id(scsi_qla_host_t *vha, fc_port_t *dev) | |||
3367 | /* Check for loop ID being already in use. */ | 3387 | /* Check for loop ID being already in use. */ |
3368 | found = 0; | 3388 | found = 0; |
3369 | fcport = NULL; | 3389 | fcport = NULL; |
3390 | |||
3391 | spin_lock_irqsave(&ha->vport_slock, flags); | ||
3370 | list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) { | 3392 | list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) { |
3371 | list_for_each_entry(fcport, &vp->vp_fcports, list) { | 3393 | list_for_each_entry(fcport, &vp->vp_fcports, list) { |
3372 | if (fcport->loop_id == dev->loop_id && | 3394 | if (fcport->loop_id == dev->loop_id && |
@@ -3379,6 +3401,7 @@ qla2x00_find_new_loop_id(scsi_qla_host_t *vha, fc_port_t *dev) | |||
3379 | if (found) | 3401 | if (found) |
3380 | break; | 3402 | break; |
3381 | } | 3403 | } |
3404 | spin_unlock_irqrestore(&ha->vport_slock, flags); | ||
3382 | 3405 | ||
3383 | /* If not in use then it is free to use. */ | 3406 | /* If not in use then it is free to use. */ |
3384 | if (!found) { | 3407 | if (!found) { |
@@ -3791,14 +3814,27 @@ void | |||
3791 | qla2x00_update_fcports(scsi_qla_host_t *base_vha) | 3814 | qla2x00_update_fcports(scsi_qla_host_t *base_vha) |
3792 | { | 3815 | { |
3793 | fc_port_t *fcport; | 3816 | fc_port_t *fcport; |
3794 | struct scsi_qla_host *tvp, *vha; | 3817 | struct scsi_qla_host *vha; |
3818 | struct qla_hw_data *ha = base_vha->hw; | ||
3819 | unsigned long flags; | ||
3795 | 3820 | ||
3821 | spin_lock_irqsave(&ha->vport_slock, flags); | ||
3796 | /* Go with deferred removal of rport references. */ | 3822 | /* Go with deferred removal of rport references. */ |
3797 | list_for_each_entry_safe(vha, tvp, &base_vha->hw->vp_list, list) | 3823 | list_for_each_entry(vha, &base_vha->hw->vp_list, list) { |
3798 | list_for_each_entry(fcport, &vha->vp_fcports, list) | 3824 | atomic_inc(&vha->vref_count); |
3825 | list_for_each_entry(fcport, &vha->vp_fcports, list) { | ||
3799 | if (fcport && fcport->drport && | 3826 | if (fcport && fcport->drport && |
3800 | atomic_read(&fcport->state) != FCS_UNCONFIGURED) | 3827 | atomic_read(&fcport->state) != FCS_UNCONFIGURED) { |
3828 | spin_unlock_irqrestore(&ha->vport_slock, flags); | ||
3829 | |||
3801 | qla2x00_rport_del(fcport); | 3830 | qla2x00_rport_del(fcport); |
3831 | |||
3832 | spin_lock_irqsave(&ha->vport_slock, flags); | ||
3833 | } | ||
3834 | } | ||
3835 | atomic_dec(&vha->vref_count); | ||
3836 | } | ||
3837 | spin_unlock_irqrestore(&ha->vport_slock, flags); | ||
3802 | } | 3838 | } |
3803 | 3839 | ||
3804 | void | 3840 | void |
@@ -3806,7 +3842,7 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha) | |||
3806 | { | 3842 | { |
3807 | struct qla_hw_data *ha = vha->hw; | 3843 | struct qla_hw_data *ha = vha->hw; |
3808 | struct scsi_qla_host *vp, *base_vha = pci_get_drvdata(ha->pdev); | 3844 | struct scsi_qla_host *vp, *base_vha = pci_get_drvdata(ha->pdev); |
3809 | struct scsi_qla_host *tvp; | 3845 | unsigned long flags; |
3810 | 3846 | ||
3811 | vha->flags.online = 0; | 3847 | vha->flags.online = 0; |
3812 | ha->flags.chip_reset_done = 0; | 3848 | ha->flags.chip_reset_done = 0; |
@@ -3824,8 +3860,18 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha) | |||
3824 | if (atomic_read(&vha->loop_state) != LOOP_DOWN) { | 3860 | if (atomic_read(&vha->loop_state) != LOOP_DOWN) { |
3825 | atomic_set(&vha->loop_state, LOOP_DOWN); | 3861 | atomic_set(&vha->loop_state, LOOP_DOWN); |
3826 | qla2x00_mark_all_devices_lost(vha, 0); | 3862 | qla2x00_mark_all_devices_lost(vha, 0); |
3827 | list_for_each_entry_safe(vp, tvp, &base_vha->hw->vp_list, list) | 3863 | |
3864 | spin_lock_irqsave(&ha->vport_slock, flags); | ||
3865 | list_for_each_entry(vp, &base_vha->hw->vp_list, list) { | ||
3866 | atomic_inc(&vp->vref_count); | ||
3867 | spin_unlock_irqrestore(&ha->vport_slock, flags); | ||
3868 | |||
3828 | qla2x00_mark_all_devices_lost(vp, 0); | 3869 | qla2x00_mark_all_devices_lost(vp, 0); |
3870 | |||
3871 | spin_lock_irqsave(&ha->vport_slock, flags); | ||
3872 | atomic_dec(&vp->vref_count); | ||
3873 | } | ||
3874 | spin_unlock_irqrestore(&ha->vport_slock, flags); | ||
3829 | } else { | 3875 | } else { |
3830 | if (!atomic_read(&vha->loop_down_timer)) | 3876 | if (!atomic_read(&vha->loop_down_timer)) |
3831 | atomic_set(&vha->loop_down_timer, | 3877 | atomic_set(&vha->loop_down_timer, |
@@ -3862,8 +3908,8 @@ qla2x00_abort_isp(scsi_qla_host_t *vha) | |||
3862 | uint8_t status = 0; | 3908 | uint8_t status = 0; |
3863 | struct qla_hw_data *ha = vha->hw; | 3909 | struct qla_hw_data *ha = vha->hw; |
3864 | struct scsi_qla_host *vp; | 3910 | struct scsi_qla_host *vp; |
3865 | struct scsi_qla_host *tvp; | ||
3866 | struct req_que *req = ha->req_q_map[0]; | 3911 | struct req_que *req = ha->req_q_map[0]; |
3912 | unsigned long flags; | ||
3867 | 3913 | ||
3868 | if (vha->flags.online) { | 3914 | if (vha->flags.online) { |
3869 | qla2x00_abort_isp_cleanup(vha); | 3915 | qla2x00_abort_isp_cleanup(vha); |
@@ -3970,10 +4016,21 @@ qla2x00_abort_isp(scsi_qla_host_t *vha) | |||
3970 | DEBUG(printk(KERN_INFO | 4016 | DEBUG(printk(KERN_INFO |
3971 | "qla2x00_abort_isp(%ld): succeeded.\n", | 4017 | "qla2x00_abort_isp(%ld): succeeded.\n", |
3972 | vha->host_no)); | 4018 | vha->host_no)); |
3973 | list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) { | 4019 | |
3974 | if (vp->vp_idx) | 4020 | spin_lock_irqsave(&ha->vport_slock, flags); |
4021 | list_for_each_entry(vp, &ha->vp_list, list) { | ||
4022 | if (vp->vp_idx) { | ||
4023 | atomic_inc(&vp->vref_count); | ||
4024 | spin_unlock_irqrestore(&ha->vport_slock, flags); | ||
4025 | |||
3975 | qla2x00_vp_abort_isp(vp); | 4026 | qla2x00_vp_abort_isp(vp); |
4027 | |||
4028 | spin_lock_irqsave(&ha->vport_slock, flags); | ||
4029 | atomic_dec(&vp->vref_count); | ||
4030 | } | ||
3976 | } | 4031 | } |
4032 | spin_unlock_irqrestore(&ha->vport_slock, flags); | ||
4033 | |||
3977 | } else { | 4034 | } else { |
3978 | qla_printk(KERN_INFO, ha, | 4035 | qla_printk(KERN_INFO, ha, |
3979 | "qla2x00_abort_isp: **** FAILED ****\n"); | 4036 | "qla2x00_abort_isp: **** FAILED ****\n"); |
@@ -5185,7 +5242,7 @@ qla82xx_restart_isp(scsi_qla_host_t *vha) | |||
5185 | struct req_que *req = ha->req_q_map[0]; | 5242 | struct req_que *req = ha->req_q_map[0]; |
5186 | struct rsp_que *rsp = ha->rsp_q_map[0]; | 5243 | struct rsp_que *rsp = ha->rsp_q_map[0]; |
5187 | struct scsi_qla_host *vp; | 5244 | struct scsi_qla_host *vp; |
5188 | struct scsi_qla_host *tvp; | 5245 | unsigned long flags; |
5189 | 5246 | ||
5190 | status = qla2x00_init_rings(vha); | 5247 | status = qla2x00_init_rings(vha); |
5191 | if (!status) { | 5248 | if (!status) { |
@@ -5272,10 +5329,21 @@ qla82xx_restart_isp(scsi_qla_host_t *vha) | |||
5272 | DEBUG(printk(KERN_INFO | 5329 | DEBUG(printk(KERN_INFO |
5273 | "qla82xx_restart_isp(%ld): succeeded.\n", | 5330 | "qla82xx_restart_isp(%ld): succeeded.\n", |
5274 | vha->host_no)); | 5331 | vha->host_no)); |
5275 | list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) { | 5332 | |
5276 | if (vp->vp_idx) | 5333 | spin_lock_irqsave(&ha->vport_slock, flags); |
5334 | list_for_each_entry(vp, &ha->vp_list, list) { | ||
5335 | if (vp->vp_idx) { | ||
5336 | atomic_inc(&vp->vref_count); | ||
5337 | spin_unlock_irqrestore(&ha->vport_slock, flags); | ||
5338 | |||
5277 | qla2x00_vp_abort_isp(vp); | 5339 | qla2x00_vp_abort_isp(vp); |
5340 | |||
5341 | spin_lock_irqsave(&ha->vport_slock, flags); | ||
5342 | atomic_dec(&vp->vref_count); | ||
5343 | } | ||
5278 | } | 5344 | } |
5345 | spin_unlock_irqrestore(&ha->vport_slock, flags); | ||
5346 | |||
5279 | } else { | 5347 | } else { |
5280 | qla_printk(KERN_INFO, ha, | 5348 | qla_printk(KERN_INFO, ha, |
5281 | "qla82xx_restart_isp: **** FAILED ****\n"); | 5349 | "qla82xx_restart_isp: **** FAILED ****\n"); |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 6982ba70e12..28f65be19da 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -1706,19 +1706,20 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) | |||
1706 | cp->result = DID_ERROR << 16; | 1706 | cp->result = DID_ERROR << 16; |
1707 | break; | 1707 | break; |
1708 | } | 1708 | } |
1709 | } else if (!lscsi_status) { | 1709 | } else { |
1710 | DEBUG2(qla_printk(KERN_INFO, ha, | 1710 | DEBUG2(qla_printk(KERN_INFO, ha, |
1711 | "scsi(%ld:%d:%d) Dropped frame(s) detected (0x%x " | 1711 | "scsi(%ld:%d:%d) Dropped frame(s) detected (0x%x " |
1712 | "of 0x%x bytes).\n", vha->host_no, cp->device->id, | 1712 | "of 0x%x bytes).\n", vha->host_no, cp->device->id, |
1713 | cp->device->lun, resid, scsi_bufflen(cp))); | 1713 | cp->device->lun, resid, scsi_bufflen(cp))); |
1714 | 1714 | ||
1715 | cp->result = DID_ERROR << 16; | 1715 | cp->result = DID_ERROR << 16 | lscsi_status; |
1716 | break; | 1716 | goto check_scsi_status; |
1717 | } | 1717 | } |
1718 | 1718 | ||
1719 | cp->result = DID_OK << 16 | lscsi_status; | 1719 | cp->result = DID_OK << 16 | lscsi_status; |
1720 | logit = 0; | 1720 | logit = 0; |
1721 | 1721 | ||
1722 | check_scsi_status: | ||
1722 | /* | 1723 | /* |
1723 | * Check to see if SCSI Status is non zero. If so report SCSI | 1724 | * Check to see if SCSI Status is non zero. If so report SCSI |
1724 | * Status. | 1725 | * Status. |
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 6009b0c6948..a595ec8264f 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -2913,7 +2913,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha, | |||
2913 | uint16_t stat = le16_to_cpu(rptid_entry->vp_idx); | 2913 | uint16_t stat = le16_to_cpu(rptid_entry->vp_idx); |
2914 | struct qla_hw_data *ha = vha->hw; | 2914 | struct qla_hw_data *ha = vha->hw; |
2915 | scsi_qla_host_t *vp; | 2915 | scsi_qla_host_t *vp; |
2916 | scsi_qla_host_t *tvp; | 2916 | unsigned long flags; |
2917 | 2917 | ||
2918 | if (rptid_entry->entry_status != 0) | 2918 | if (rptid_entry->entry_status != 0) |
2919 | return; | 2919 | return; |
@@ -2945,9 +2945,12 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha, | |||
2945 | return; | 2945 | return; |
2946 | } | 2946 | } |
2947 | 2947 | ||
2948 | list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) | 2948 | spin_lock_irqsave(&ha->vport_slock, flags); |
2949 | list_for_each_entry(vp, &ha->vp_list, list) | ||
2949 | if (vp_idx == vp->vp_idx) | 2950 | if (vp_idx == vp->vp_idx) |
2950 | break; | 2951 | break; |
2952 | spin_unlock_irqrestore(&ha->vport_slock, flags); | ||
2953 | |||
2951 | if (!vp) | 2954 | if (!vp) |
2952 | return; | 2955 | return; |
2953 | 2956 | ||
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index 987c5b0ca78..2b69392a71a 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c | |||
@@ -30,6 +30,7 @@ qla24xx_allocate_vp_id(scsi_qla_host_t *vha) | |||
30 | { | 30 | { |
31 | uint32_t vp_id; | 31 | uint32_t vp_id; |
32 | struct qla_hw_data *ha = vha->hw; | 32 | struct qla_hw_data *ha = vha->hw; |
33 | unsigned long flags; | ||
33 | 34 | ||
34 | /* Find an empty slot and assign an vp_id */ | 35 | /* Find an empty slot and assign an vp_id */ |
35 | mutex_lock(&ha->vport_lock); | 36 | mutex_lock(&ha->vport_lock); |
@@ -44,7 +45,11 @@ qla24xx_allocate_vp_id(scsi_qla_host_t *vha) | |||
44 | set_bit(vp_id, ha->vp_idx_map); | 45 | set_bit(vp_id, ha->vp_idx_map); |
45 | ha->num_vhosts++; | 46 | ha->num_vhosts++; |
46 | vha->vp_idx = vp_id; | 47 | vha->vp_idx = vp_id; |
48 | |||
49 | spin_lock_irqsave(&ha->vport_slock, flags); | ||
47 | list_add_tail(&vha->list, &ha->vp_list); | 50 | list_add_tail(&vha->list, &ha->vp_list); |
51 | spin_unlock_irqrestore(&ha->vport_slock, flags); | ||
52 | |||
48 | mutex_unlock(&ha->vport_lock); | 53 | mutex_unlock(&ha->vport_lock); |
49 | return vp_id; | 54 | return vp_id; |
50 | } | 55 | } |
@@ -54,12 +59,31 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t *vha) | |||
54 | { | 59 | { |
55 | uint16_t vp_id; | 60 | uint16_t vp_id; |
56 | struct qla_hw_data *ha = vha->hw; | 61 | struct qla_hw_data *ha = vha->hw; |
62 | unsigned long flags = 0; | ||
57 | 63 | ||
58 | mutex_lock(&ha->vport_lock); | 64 | mutex_lock(&ha->vport_lock); |
65 | /* | ||
66 | * Wait for all pending activities to finish before removing vport from | ||
67 | * the list. | ||
68 | * Lock needs to be held for safe removal from the list (it | ||
69 | * ensures no active vp_list traversal while the vport is removed | ||
70 | * from the queue) | ||
71 | */ | ||
72 | spin_lock_irqsave(&ha->vport_slock, flags); | ||
73 | while (atomic_read(&vha->vref_count)) { | ||
74 | spin_unlock_irqrestore(&ha->vport_slock, flags); | ||
75 | |||
76 | msleep(500); | ||
77 | |||
78 | spin_lock_irqsave(&ha->vport_slock, flags); | ||
79 | } | ||
80 | list_del(&vha->list); | ||
81 | spin_unlock_irqrestore(&ha->vport_slock, flags); | ||
82 | |||
59 | vp_id = vha->vp_idx; | 83 | vp_id = vha->vp_idx; |
60 | ha->num_vhosts--; | 84 | ha->num_vhosts--; |
61 | clear_bit(vp_id, ha->vp_idx_map); | 85 | clear_bit(vp_id, ha->vp_idx_map); |
62 | list_del(&vha->list); | 86 | |
63 | mutex_unlock(&ha->vport_lock); | 87 | mutex_unlock(&ha->vport_lock); |
64 | } | 88 | } |
65 | 89 | ||
@@ -68,12 +92,17 @@ qla24xx_find_vhost_by_name(struct qla_hw_data *ha, uint8_t *port_name) | |||
68 | { | 92 | { |
69 | scsi_qla_host_t *vha; | 93 | scsi_qla_host_t *vha; |
70 | struct scsi_qla_host *tvha; | 94 | struct scsi_qla_host *tvha; |
95 | unsigned long flags; | ||
71 | 96 | ||
97 | spin_lock_irqsave(&ha->vport_slock, flags); | ||
72 | /* Locate matching device in database. */ | 98 | /* Locate matching device in database. */ |
73 | list_for_each_entry_safe(vha, tvha, &ha->vp_list, list) { | 99 | list_for_each_entry_safe(vha, tvha, &ha->vp_list, list) { |
74 | if (!memcmp(port_name, vha->port_name, WWN_SIZE)) | 100 | if (!memcmp(port_name, vha->port_name, WWN_SIZE)) { |
101 | spin_unlock_irqrestore(&ha->vport_slock, flags); | ||
75 | return vha; | 102 | return vha; |
103 | } | ||
76 | } | 104 | } |
105 | spin_unlock_irqrestore(&ha->vport_slock, flags); | ||
77 | return NULL; | 106 | return NULL; |
78 | } | 107 | } |
79 | 108 | ||
@@ -93,6 +122,12 @@ qla24xx_find_vhost_by_name(struct qla_hw_data *ha, uint8_t *port_name) | |||
93 | static void | 122 | static void |
94 | qla2x00_mark_vp_devices_dead(scsi_qla_host_t *vha) | 123 | qla2x00_mark_vp_devices_dead(scsi_qla_host_t *vha) |
95 | { | 124 | { |
125 | /* | ||
126 | * !!! NOTE !!! | ||
127 | * This function, if called in contexts other than vp create, disable | ||
128 | * or delete, please make sure this is synchronized with the | ||
129 | * delete thread. | ||
130 | */ | ||
96 | fc_port_t *fcport; | 131 | fc_port_t *fcport; |
97 | 132 | ||
98 | list_for_each_entry(fcport, &vha->vp_fcports, list) { | 133 | list_for_each_entry(fcport, &vha->vp_fcports, list) { |
@@ -100,7 +135,6 @@ qla2x00_mark_vp_devices_dead(scsi_qla_host_t *vha) | |||
100 | "loop_id=0x%04x :%x\n", | 135 | "loop_id=0x%04x :%x\n", |
101 | vha->host_no, fcport->loop_id, fcport->vp_idx)); | 136 | vha->host_no, fcport->loop_id, fcport->vp_idx)); |
102 | 137 | ||
103 | atomic_set(&fcport->state, FCS_DEVICE_DEAD); | ||
104 | qla2x00_mark_device_lost(vha, fcport, 0, 0); | 138 | qla2x00_mark_device_lost(vha, fcport, 0, 0); |
105 | atomic_set(&fcport->state, FCS_UNCONFIGURED); | 139 | atomic_set(&fcport->state, FCS_UNCONFIGURED); |
106 | } | 140 | } |
@@ -194,12 +228,17 @@ qla24xx_configure_vp(scsi_qla_host_t *vha) | |||
194 | void | 228 | void |
195 | qla2x00_alert_all_vps(struct rsp_que *rsp, uint16_t *mb) | 229 | qla2x00_alert_all_vps(struct rsp_que *rsp, uint16_t *mb) |
196 | { | 230 | { |
197 | scsi_qla_host_t *vha, *tvha; | 231 | scsi_qla_host_t *vha; |
198 | struct qla_hw_data *ha = rsp->hw; | 232 | struct qla_hw_data *ha = rsp->hw; |
199 | int i = 0; | 233 | int i = 0; |
234 | unsigned long flags; | ||
200 | 235 | ||
201 | list_for_each_entry_safe(vha, tvha, &ha->vp_list, list) { | 236 | spin_lock_irqsave(&ha->vport_slock, flags); |
237 | list_for_each_entry(vha, &ha->vp_list, list) { | ||
202 | if (vha->vp_idx) { | 238 | if (vha->vp_idx) { |
239 | atomic_inc(&vha->vref_count); | ||
240 | spin_unlock_irqrestore(&ha->vport_slock, flags); | ||
241 | |||
203 | switch (mb[0]) { | 242 | switch (mb[0]) { |
204 | case MBA_LIP_OCCURRED: | 243 | case MBA_LIP_OCCURRED: |
205 | case MBA_LOOP_UP: | 244 | case MBA_LOOP_UP: |
@@ -215,9 +254,13 @@ qla2x00_alert_all_vps(struct rsp_que *rsp, uint16_t *mb) | |||
215 | qla2x00_async_event(vha, rsp, mb); | 254 | qla2x00_async_event(vha, rsp, mb); |
216 | break; | 255 | break; |
217 | } | 256 | } |
257 | |||
258 | spin_lock_irqsave(&ha->vport_slock, flags); | ||
259 | atomic_dec(&vha->vref_count); | ||
218 | } | 260 | } |
219 | i++; | 261 | i++; |
220 | } | 262 | } |
263 | spin_unlock_irqrestore(&ha->vport_slock, flags); | ||
221 | } | 264 | } |
222 | 265 | ||
223 | int | 266 | int |
@@ -297,7 +340,7 @@ qla2x00_do_dpc_all_vps(scsi_qla_host_t *vha) | |||
297 | int ret; | 340 | int ret; |
298 | struct qla_hw_data *ha = vha->hw; | 341 | struct qla_hw_data *ha = vha->hw; |
299 | scsi_qla_host_t *vp; | 342 | scsi_qla_host_t *vp; |
300 | struct scsi_qla_host *tvp; | 343 | unsigned long flags = 0; |
301 | 344 | ||
302 | if (vha->vp_idx) | 345 | if (vha->vp_idx) |
303 | return; | 346 | return; |
@@ -309,10 +352,19 @@ qla2x00_do_dpc_all_vps(scsi_qla_host_t *vha) | |||
309 | if (!(ha->current_topology & ISP_CFG_F)) | 352 | if (!(ha->current_topology & ISP_CFG_F)) |
310 | return; | 353 | return; |
311 | 354 | ||
312 | list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) { | 355 | spin_lock_irqsave(&ha->vport_slock, flags); |
313 | if (vp->vp_idx) | 356 | list_for_each_entry(vp, &ha->vp_list, list) { |
357 | if (vp->vp_idx) { | ||
358 | atomic_inc(&vp->vref_count); | ||
359 | spin_unlock_irqrestore(&ha->vport_slock, flags); | ||
360 | |||
314 | ret = qla2x00_do_dpc_vp(vp); | 361 | ret = qla2x00_do_dpc_vp(vp); |
362 | |||
363 | spin_lock_irqsave(&ha->vport_slock, flags); | ||
364 | atomic_dec(&vp->vref_count); | ||
365 | } | ||
315 | } | 366 | } |
367 | spin_unlock_irqrestore(&ha->vport_slock, flags); | ||
316 | } | 368 | } |
317 | 369 | ||
318 | int | 370 | int |
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index 915b77a6e19..0a71cc71eab 100644 --- a/drivers/scsi/qla2xxx/qla_nx.c +++ b/drivers/scsi/qla2xxx/qla_nx.c | |||
@@ -2672,6 +2672,19 @@ qla82xx_start_scsi(srb_t *sp) | |||
2672 | sufficient_dsds: | 2672 | sufficient_dsds: |
2673 | req_cnt = 1; | 2673 | req_cnt = 1; |
2674 | 2674 | ||
2675 | if (req->cnt < (req_cnt + 2)) { | ||
2676 | cnt = (uint16_t)RD_REG_DWORD_RELAXED( | ||
2677 | ®->req_q_out[0]); | ||
2678 | if (req->ring_index < cnt) | ||
2679 | req->cnt = cnt - req->ring_index; | ||
2680 | else | ||
2681 | req->cnt = req->length - | ||
2682 | (req->ring_index - cnt); | ||
2683 | } | ||
2684 | |||
2685 | if (req->cnt < (req_cnt + 2)) | ||
2686 | goto queuing_error; | ||
2687 | |||
2675 | ctx = sp->ctx = mempool_alloc(ha->ctx_mempool, GFP_ATOMIC); | 2688 | ctx = sp->ctx = mempool_alloc(ha->ctx_mempool, GFP_ATOMIC); |
2676 | if (!sp->ctx) { | 2689 | if (!sp->ctx) { |
2677 | DEBUG(printk(KERN_INFO | 2690 | DEBUG(printk(KERN_INFO |
@@ -3307,16 +3320,19 @@ qla82xx_check_fw_alive(scsi_qla_host_t *vha) | |||
3307 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); | 3320 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); |
3308 | } | 3321 | } |
3309 | qla2xxx_wake_dpc(vha); | 3322 | qla2xxx_wake_dpc(vha); |
3323 | ha->flags.fw_hung = 1; | ||
3310 | if (ha->flags.mbox_busy) { | 3324 | if (ha->flags.mbox_busy) { |
3311 | ha->flags.fw_hung = 1; | ||
3312 | ha->flags.mbox_int = 1; | 3325 | ha->flags.mbox_int = 1; |
3313 | DEBUG2(qla_printk(KERN_ERR, ha, | 3326 | DEBUG2(qla_printk(KERN_ERR, ha, |
3314 | "Due to fw hung, doing premature " | 3327 | "Due to fw hung, doing premature " |
3315 | "completion of mbx command\n")); | 3328 | "completion of mbx command\n")); |
3316 | complete(&ha->mbx_intr_comp); | 3329 | if (test_bit(MBX_INTR_WAIT, |
3330 | &ha->mbx_cmd_flags)) | ||
3331 | complete(&ha->mbx_intr_comp); | ||
3317 | } | 3332 | } |
3318 | } | 3333 | } |
3319 | } | 3334 | } else |
3335 | vha->seconds_since_last_heartbeat = 0; | ||
3320 | vha->fw_heartbeat_counter = fw_heartbeat_counter; | 3336 | vha->fw_heartbeat_counter = fw_heartbeat_counter; |
3321 | } | 3337 | } |
3322 | 3338 | ||
@@ -3418,13 +3434,15 @@ void qla82xx_watchdog(scsi_qla_host_t *vha) | |||
3418 | "%s(): Adapter reset needed!\n", __func__); | 3434 | "%s(): Adapter reset needed!\n", __func__); |
3419 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); | 3435 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); |
3420 | qla2xxx_wake_dpc(vha); | 3436 | qla2xxx_wake_dpc(vha); |
3437 | ha->flags.fw_hung = 1; | ||
3421 | if (ha->flags.mbox_busy) { | 3438 | if (ha->flags.mbox_busy) { |
3422 | ha->flags.fw_hung = 1; | ||
3423 | ha->flags.mbox_int = 1; | 3439 | ha->flags.mbox_int = 1; |
3424 | DEBUG2(qla_printk(KERN_ERR, ha, | 3440 | DEBUG2(qla_printk(KERN_ERR, ha, |
3425 | "Need reset, doing premature " | 3441 | "Need reset, doing premature " |
3426 | "completion of mbx command\n")); | 3442 | "completion of mbx command\n")); |
3427 | complete(&ha->mbx_intr_comp); | 3443 | if (test_bit(MBX_INTR_WAIT, |
3444 | &ha->mbx_cmd_flags)) | ||
3445 | complete(&ha->mbx_intr_comp); | ||
3428 | } | 3446 | } |
3429 | } else { | 3447 | } else { |
3430 | qla82xx_check_fw_alive(vha); | 3448 | qla82xx_check_fw_alive(vha); |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 8c80b49ac1c..1e4bff69525 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -2341,16 +2341,28 @@ probe_out: | |||
2341 | static void | 2341 | static void |
2342 | qla2x00_remove_one(struct pci_dev *pdev) | 2342 | qla2x00_remove_one(struct pci_dev *pdev) |
2343 | { | 2343 | { |
2344 | scsi_qla_host_t *base_vha, *vha, *temp; | 2344 | scsi_qla_host_t *base_vha, *vha; |
2345 | struct qla_hw_data *ha; | 2345 | struct qla_hw_data *ha; |
2346 | unsigned long flags; | ||
2346 | 2347 | ||
2347 | base_vha = pci_get_drvdata(pdev); | 2348 | base_vha = pci_get_drvdata(pdev); |
2348 | ha = base_vha->hw; | 2349 | ha = base_vha->hw; |
2349 | 2350 | ||
2350 | list_for_each_entry_safe(vha, temp, &ha->vp_list, list) { | 2351 | spin_lock_irqsave(&ha->vport_slock, flags); |
2351 | if (vha && vha->fc_vport) | 2352 | list_for_each_entry(vha, &ha->vp_list, list) { |
2353 | atomic_inc(&vha->vref_count); | ||
2354 | |||
2355 | if (vha && vha->fc_vport) { | ||
2356 | spin_unlock_irqrestore(&ha->vport_slock, flags); | ||
2357 | |||
2352 | fc_vport_terminate(vha->fc_vport); | 2358 | fc_vport_terminate(vha->fc_vport); |
2359 | |||
2360 | spin_lock_irqsave(&ha->vport_slock, flags); | ||
2361 | } | ||
2362 | |||
2363 | atomic_dec(&vha->vref_count); | ||
2353 | } | 2364 | } |
2365 | spin_unlock_irqrestore(&ha->vport_slock, flags); | ||
2354 | 2366 | ||
2355 | set_bit(UNLOADING, &base_vha->dpc_flags); | 2367 | set_bit(UNLOADING, &base_vha->dpc_flags); |
2356 | 2368 | ||
@@ -2975,10 +2987,17 @@ static struct qla_work_evt * | |||
2975 | qla2x00_alloc_work(struct scsi_qla_host *vha, enum qla_work_type type) | 2987 | qla2x00_alloc_work(struct scsi_qla_host *vha, enum qla_work_type type) |
2976 | { | 2988 | { |
2977 | struct qla_work_evt *e; | 2989 | struct qla_work_evt *e; |
2990 | uint8_t bail; | ||
2991 | |||
2992 | QLA_VHA_MARK_BUSY(vha, bail); | ||
2993 | if (bail) | ||
2994 | return NULL; | ||
2978 | 2995 | ||
2979 | e = kzalloc(sizeof(struct qla_work_evt), GFP_ATOMIC); | 2996 | e = kzalloc(sizeof(struct qla_work_evt), GFP_ATOMIC); |
2980 | if (!e) | 2997 | if (!e) { |
2998 | QLA_VHA_MARK_NOT_BUSY(vha); | ||
2981 | return NULL; | 2999 | return NULL; |
3000 | } | ||
2982 | 3001 | ||
2983 | INIT_LIST_HEAD(&e->list); | 3002 | INIT_LIST_HEAD(&e->list); |
2984 | e->type = type; | 3003 | e->type = type; |
@@ -3135,6 +3154,9 @@ qla2x00_do_work(struct scsi_qla_host *vha) | |||
3135 | } | 3154 | } |
3136 | if (e->flags & QLA_EVT_FLAG_FREE) | 3155 | if (e->flags & QLA_EVT_FLAG_FREE) |
3137 | kfree(e); | 3156 | kfree(e); |
3157 | |||
3158 | /* For each work completed decrement vha ref count */ | ||
3159 | QLA_VHA_MARK_NOT_BUSY(vha); | ||
3138 | } | 3160 | } |
3139 | } | 3161 | } |
3140 | 3162 | ||
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index e75ccb91317..8edbccb3232 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h | |||
@@ -7,9 +7,9 @@ | |||
7 | /* | 7 | /* |
8 | * Driver version | 8 | * Driver version |
9 | */ | 9 | */ |
10 | #define QLA2XXX_VERSION "8.03.03-k0" | 10 | #define QLA2XXX_VERSION "8.03.04-k0" |
11 | 11 | ||
12 | #define QLA_DRIVER_MAJOR_VER 8 | 12 | #define QLA_DRIVER_MAJOR_VER 8 |
13 | #define QLA_DRIVER_MINOR_VER 3 | 13 | #define QLA_DRIVER_MINOR_VER 3 |
14 | #define QLA_DRIVER_PATCH_VER 3 | 14 | #define QLA_DRIVER_PATCH_VER 4 |
15 | #define QLA_DRIVER_BETA_VER 0 | 15 | #define QLA_DRIVER_BETA_VER 0 |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 9ade720422c..ee02d3838a0 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -1011,8 +1011,8 @@ int scsi_init_io(struct scsi_cmnd *cmd, gfp_t gfp_mask) | |||
1011 | 1011 | ||
1012 | err_exit: | 1012 | err_exit: |
1013 | scsi_release_buffers(cmd); | 1013 | scsi_release_buffers(cmd); |
1014 | scsi_put_command(cmd); | ||
1015 | cmd->request->special = NULL; | 1014 | cmd->request->special = NULL; |
1015 | scsi_put_command(cmd); | ||
1016 | return error; | 1016 | return error; |
1017 | } | 1017 | } |
1018 | EXPORT_SYMBOL(scsi_init_io); | 1018 | EXPORT_SYMBOL(scsi_init_io); |
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 63bd01ae534..20514c47a5a 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -870,7 +870,7 @@ static int sd_release(struct gendisk *disk, fmode_t mode) | |||
870 | 870 | ||
871 | SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_release\n")); | 871 | SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_release\n")); |
872 | 872 | ||
873 | if (atomic_dec_return(&sdkp->openers) && sdev->removable) { | 873 | if (atomic_dec_return(&sdkp->openers) == 0 && sdev->removable) { |
874 | if (scsi_block_when_processing_errors(sdev)) | 874 | if (scsi_block_when_processing_errors(sdev)) |
875 | scsi_set_medium_removal(sdev, SCSI_REMOVAL_ALLOW); | 875 | scsi_set_medium_removal(sdev, SCSI_REMOVAL_ALLOW); |
876 | } | 876 | } |
@@ -2623,15 +2623,15 @@ module_exit(exit_sd); | |||
2623 | static void sd_print_sense_hdr(struct scsi_disk *sdkp, | 2623 | static void sd_print_sense_hdr(struct scsi_disk *sdkp, |
2624 | struct scsi_sense_hdr *sshdr) | 2624 | struct scsi_sense_hdr *sshdr) |
2625 | { | 2625 | { |
2626 | sd_printk(KERN_INFO, sdkp, ""); | 2626 | sd_printk(KERN_INFO, sdkp, " "); |
2627 | scsi_show_sense_hdr(sshdr); | 2627 | scsi_show_sense_hdr(sshdr); |
2628 | sd_printk(KERN_INFO, sdkp, ""); | 2628 | sd_printk(KERN_INFO, sdkp, " "); |
2629 | scsi_show_extd_sense(sshdr->asc, sshdr->ascq); | 2629 | scsi_show_extd_sense(sshdr->asc, sshdr->ascq); |
2630 | } | 2630 | } |
2631 | 2631 | ||
2632 | static void sd_print_result(struct scsi_disk *sdkp, int result) | 2632 | static void sd_print_result(struct scsi_disk *sdkp, int result) |
2633 | { | 2633 | { |
2634 | sd_printk(KERN_INFO, sdkp, ""); | 2634 | sd_printk(KERN_INFO, sdkp, " "); |
2635 | scsi_show_result(result); | 2635 | scsi_show_result(result); |
2636 | } | 2636 | } |
2637 | 2637 | ||
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c index a7bc8b7b09a..2c3e89ddf06 100644 --- a/drivers/scsi/sym53c8xx_2/sym_hipd.c +++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c | |||
@@ -72,10 +72,7 @@ static void sym_printl_hex(u_char *p, int n) | |||
72 | 72 | ||
73 | static void sym_print_msg(struct sym_ccb *cp, char *label, u_char *msg) | 73 | static void sym_print_msg(struct sym_ccb *cp, char *label, u_char *msg) |
74 | { | 74 | { |
75 | if (label) | 75 | sym_print_addr(cp->cmd, "%s: ", label); |
76 | sym_print_addr(cp->cmd, "%s: ", label); | ||
77 | else | ||
78 | sym_print_addr(cp->cmd, ""); | ||
79 | 76 | ||
80 | spi_print_msg(msg); | 77 | spi_print_msg(msg); |
81 | printf("\n"); | 78 | printf("\n"); |
@@ -4558,7 +4555,8 @@ static void sym_int_sir(struct sym_hcb *np) | |||
4558 | switch (np->msgin [2]) { | 4555 | switch (np->msgin [2]) { |
4559 | case M_X_MODIFY_DP: | 4556 | case M_X_MODIFY_DP: |
4560 | if (DEBUG_FLAGS & DEBUG_POINTER) | 4557 | if (DEBUG_FLAGS & DEBUG_POINTER) |
4561 | sym_print_msg(cp, NULL, np->msgin); | 4558 | sym_print_msg(cp, "extended msg ", |
4559 | np->msgin); | ||
4562 | tmp = (np->msgin[3]<<24) + (np->msgin[4]<<16) + | 4560 | tmp = (np->msgin[3]<<24) + (np->msgin[4]<<16) + |
4563 | (np->msgin[5]<<8) + (np->msgin[6]); | 4561 | (np->msgin[5]<<8) + (np->msgin[6]); |
4564 | sym_modify_dp(np, tp, cp, tmp); | 4562 | sym_modify_dp(np, tp, cp, tmp); |
@@ -4585,7 +4583,7 @@ static void sym_int_sir(struct sym_hcb *np) | |||
4585 | */ | 4583 | */ |
4586 | case M_IGN_RESIDUE: | 4584 | case M_IGN_RESIDUE: |
4587 | if (DEBUG_FLAGS & DEBUG_POINTER) | 4585 | if (DEBUG_FLAGS & DEBUG_POINTER) |
4588 | sym_print_msg(cp, NULL, np->msgin); | 4586 | sym_print_msg(cp, "1 or 2 byte ", np->msgin); |
4589 | if (cp->host_flags & HF_SENSE) | 4587 | if (cp->host_flags & HF_SENSE) |
4590 | OUTL_DSP(np, SCRIPTA_BA(np, clrack)); | 4588 | OUTL_DSP(np, SCRIPTA_BA(np, clrack)); |
4591 | else | 4589 | else |
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c index 7356a56ac45..be0ebce36e5 100644 --- a/drivers/serial/68328serial.c +++ b/drivers/serial/68328serial.c | |||
@@ -869,7 +869,9 @@ static int get_serial_info(struct m68k_serial * info, | |||
869 | tmp.close_delay = info->close_delay; | 869 | tmp.close_delay = info->close_delay; |
870 | tmp.closing_wait = info->closing_wait; | 870 | tmp.closing_wait = info->closing_wait; |
871 | tmp.custom_divisor = info->custom_divisor; | 871 | tmp.custom_divisor = info->custom_divisor; |
872 | copy_to_user(retinfo,&tmp,sizeof(*retinfo)); | 872 | if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) |
873 | return -EFAULT; | ||
874 | |||
873 | return 0; | 875 | return 0; |
874 | } | 876 | } |
875 | 877 | ||
@@ -882,7 +884,8 @@ static int set_serial_info(struct m68k_serial * info, | |||
882 | 884 | ||
883 | if (!new_info) | 885 | if (!new_info) |
884 | return -EFAULT; | 886 | return -EFAULT; |
885 | copy_from_user(&new_serial,new_info,sizeof(new_serial)); | 887 | if (copy_from_user(&new_serial, new_info, sizeof(new_serial))) |
888 | return -EFAULT; | ||
886 | old_info = *info; | 889 | old_info = *info; |
887 | 890 | ||
888 | if (!capable(CAP_SYS_ADMIN)) { | 891 | if (!capable(CAP_SYS_ADMIN)) { |
@@ -943,8 +946,7 @@ static int get_lsr_info(struct m68k_serial * info, unsigned int *value) | |||
943 | status = 0; | 946 | status = 0; |
944 | #endif | 947 | #endif |
945 | local_irq_restore(flags); | 948 | local_irq_restore(flags); |
946 | put_user(status,value); | 949 | return put_user(status, value); |
947 | return 0; | ||
948 | } | 950 | } |
949 | 951 | ||
950 | /* | 952 | /* |
@@ -999,27 +1001,18 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file, | |||
999 | send_break(info, arg ? arg*(100) : 250); | 1001 | send_break(info, arg ? arg*(100) : 250); |
1000 | return 0; | 1002 | return 0; |
1001 | case TIOCGSERIAL: | 1003 | case TIOCGSERIAL: |
1002 | if (access_ok(VERIFY_WRITE, (void *) arg, | 1004 | return get_serial_info(info, |
1003 | sizeof(struct serial_struct))) | 1005 | (struct serial_struct *) arg); |
1004 | return get_serial_info(info, | ||
1005 | (struct serial_struct *) arg); | ||
1006 | return -EFAULT; | ||
1007 | case TIOCSSERIAL: | 1006 | case TIOCSSERIAL: |
1008 | return set_serial_info(info, | 1007 | return set_serial_info(info, |
1009 | (struct serial_struct *) arg); | 1008 | (struct serial_struct *) arg); |
1010 | case TIOCSERGETLSR: /* Get line status register */ | 1009 | case TIOCSERGETLSR: /* Get line status register */ |
1011 | if (access_ok(VERIFY_WRITE, (void *) arg, | 1010 | return get_lsr_info(info, (unsigned int *) arg); |
1012 | sizeof(unsigned int))) | ||
1013 | return get_lsr_info(info, (unsigned int *) arg); | ||
1014 | return -EFAULT; | ||
1015 | case TIOCSERGSTRUCT: | 1011 | case TIOCSERGSTRUCT: |
1016 | if (!access_ok(VERIFY_WRITE, (void *) arg, | 1012 | if (copy_to_user((struct m68k_serial *) arg, |
1017 | sizeof(struct m68k_serial))) | 1013 | info, sizeof(struct m68k_serial))) |
1018 | return -EFAULT; | 1014 | return -EFAULT; |
1019 | copy_to_user((struct m68k_serial *) arg, | ||
1020 | info, sizeof(struct m68k_serial)); | ||
1021 | return 0; | 1015 | return 0; |
1022 | |||
1023 | default: | 1016 | default: |
1024 | return -ENOIOCTLCMD; | 1017 | return -ENOIOCTLCMD; |
1025 | } | 1018 | } |
diff --git a/drivers/serial/8250_early.c b/drivers/serial/8250_early.c index b745792ec25..eaafb98debe 100644 --- a/drivers/serial/8250_early.c +++ b/drivers/serial/8250_early.c | |||
@@ -203,13 +203,13 @@ static int __init parse_options(struct early_serial8250_device *device, | |||
203 | 203 | ||
204 | if (mmio || mmio32) | 204 | if (mmio || mmio32) |
205 | printk(KERN_INFO | 205 | printk(KERN_INFO |
206 | "Early serial console at MMIO%s 0x%llu (options '%s')\n", | 206 | "Early serial console at MMIO%s 0x%llx (options '%s')\n", |
207 | mmio32 ? "32" : "", | 207 | mmio32 ? "32" : "", |
208 | (unsigned long long)port->mapbase, | 208 | (unsigned long long)port->mapbase, |
209 | device->options); | 209 | device->options); |
210 | else | 210 | else |
211 | printk(KERN_INFO | 211 | printk(KERN_INFO |
212 | "Early serial console at I/O port 0x%lu (options '%s')\n", | 212 | "Early serial console at I/O port 0x%lx (options '%s')\n", |
213 | port->iobase, | 213 | port->iobase, |
214 | device->options); | 214 | device->options); |
215 | 215 | ||
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c index 50441ffe8e3..2904aa04412 100644 --- a/drivers/serial/amba-pl010.c +++ b/drivers/serial/amba-pl010.c | |||
@@ -472,14 +472,9 @@ pl010_set_termios(struct uart_port *port, struct ktermios *termios, | |||
472 | spin_unlock_irqrestore(&uap->port.lock, flags); | 472 | spin_unlock_irqrestore(&uap->port.lock, flags); |
473 | } | 473 | } |
474 | 474 | ||
475 | static void pl010_set_ldisc(struct uart_port *port) | 475 | static void pl010_set_ldisc(struct uart_port *port, int new) |
476 | { | 476 | { |
477 | int line = port->line; | 477 | if (new == N_PPS) { |
478 | |||
479 | if (line >= port->state->port.tty->driver->num) | ||
480 | return; | ||
481 | |||
482 | if (port->state->port.tty->ldisc->ops->num == N_PPS) { | ||
483 | port->flags |= UPF_HARDPPS_CD; | 478 | port->flags |= UPF_HARDPPS_CD; |
484 | pl010_enable_ms(port); | 479 | pl010_enable_ms(port); |
485 | } else | 480 | } else |
diff --git a/drivers/serial/bfin_sport_uart.c b/drivers/serial/bfin_sport_uart.c index e57fb3d228e..5318dd3774a 100644 --- a/drivers/serial/bfin_sport_uart.c +++ b/drivers/serial/bfin_sport_uart.c | |||
@@ -121,7 +121,7 @@ static int sport_uart_setup(struct sport_uart_port *up, int size, int baud_rate) | |||
121 | unsigned int sclk = get_sclk(); | 121 | unsigned int sclk = get_sclk(); |
122 | 122 | ||
123 | /* Set TCR1 and TCR2, TFSR is not enabled for uart */ | 123 | /* Set TCR1 and TCR2, TFSR is not enabled for uart */ |
124 | SPORT_PUT_TCR1(up, (ITFS | TLSBIT | ITCLK)); | 124 | SPORT_PUT_TCR1(up, (LATFS | ITFS | TFSR | TLSBIT | ITCLK)); |
125 | SPORT_PUT_TCR2(up, size + 1); | 125 | SPORT_PUT_TCR2(up, size + 1); |
126 | pr_debug("%s TCR1:%x, TCR2:%x\n", __func__, SPORT_GET_TCR1(up), SPORT_GET_TCR2(up)); | 126 | pr_debug("%s TCR1:%x, TCR2:%x\n", __func__, SPORT_GET_TCR1(up), SPORT_GET_TCR2(up)); |
127 | 127 | ||
diff --git a/drivers/serial/mfd.c b/drivers/serial/mfd.c index bc9af503907..5dff45c76d3 100644 --- a/drivers/serial/mfd.c +++ b/drivers/serial/mfd.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/console.h> | 28 | #include <linux/console.h> |
29 | #include <linux/sysrq.h> | 29 | #include <linux/sysrq.h> |
30 | #include <linux/slab.h> | ||
30 | #include <linux/serial_reg.h> | 31 | #include <linux/serial_reg.h> |
31 | #include <linux/circ_buf.h> | 32 | #include <linux/circ_buf.h> |
32 | #include <linux/delay.h> | 33 | #include <linux/delay.h> |
@@ -1423,7 +1424,6 @@ static void hsu_global_init(void) | |||
1423 | } | 1424 | } |
1424 | 1425 | ||
1425 | phsu = hsu; | 1426 | phsu = hsu; |
1426 | |||
1427 | hsu_debugfs_init(hsu); | 1427 | hsu_debugfs_init(hsu); |
1428 | return; | 1428 | return; |
1429 | 1429 | ||
@@ -1435,18 +1435,20 @@ err_free_region: | |||
1435 | 1435 | ||
1436 | static void serial_hsu_remove(struct pci_dev *pdev) | 1436 | static void serial_hsu_remove(struct pci_dev *pdev) |
1437 | { | 1437 | { |
1438 | struct hsu_port *hsu; | 1438 | void *priv = pci_get_drvdata(pdev); |
1439 | int i; | 1439 | struct uart_hsu_port *up; |
1440 | 1440 | ||
1441 | hsu = pci_get_drvdata(pdev); | 1441 | if (!priv) |
1442 | if (!hsu) | ||
1443 | return; | 1442 | return; |
1444 | 1443 | ||
1445 | for (i = 0; i < 3; i++) | 1444 | /* For port 0/1/2, priv is the address of uart_hsu_port */ |
1446 | uart_remove_one_port(&serial_hsu_reg, &hsu->port[i].port); | 1445 | if (pdev->device != 0x081E) { |
1446 | up = priv; | ||
1447 | uart_remove_one_port(&serial_hsu_reg, &up->port); | ||
1448 | } | ||
1447 | 1449 | ||
1448 | pci_set_drvdata(pdev, NULL); | 1450 | pci_set_drvdata(pdev, NULL); |
1449 | free_irq(hsu->irq, hsu); | 1451 | free_irq(pdev->irq, priv); |
1450 | pci_disable_device(pdev); | 1452 | pci_disable_device(pdev); |
1451 | } | 1453 | } |
1452 | 1454 | ||
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index 8dedb266f14..c4399e23565 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c | |||
@@ -500,6 +500,7 @@ static int __init mpc512x_psc_fifoc_init(void) | |||
500 | psc_fifoc = of_iomap(np, 0); | 500 | psc_fifoc = of_iomap(np, 0); |
501 | if (!psc_fifoc) { | 501 | if (!psc_fifoc) { |
502 | pr_err("%s: Can't map FIFOC\n", __func__); | 502 | pr_err("%s: Can't map FIFOC\n", __func__); |
503 | of_node_put(np); | ||
503 | return -ENODEV; | 504 | return -ENODEV; |
504 | } | 505 | } |
505 | 506 | ||
diff --git a/drivers/serial/mrst_max3110.c b/drivers/serial/mrst_max3110.c index f6ad1ecbff7..51c15f58e01 100644 --- a/drivers/serial/mrst_max3110.c +++ b/drivers/serial/mrst_max3110.c | |||
@@ -29,6 +29,7 @@ | |||
29 | 29 | ||
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/ioport.h> | 31 | #include <linux/ioport.h> |
32 | #include <linux/irq.h> | ||
32 | #include <linux/init.h> | 33 | #include <linux/init.h> |
33 | #include <linux/console.h> | 34 | #include <linux/console.h> |
34 | #include <linux/sysrq.h> | 35 | #include <linux/sysrq.h> |
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index 141c69554bd..7d475b2a79e 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c | |||
@@ -335,8 +335,6 @@ static int serial_probe(struct pcmcia_device *link) | |||
335 | info->p_dev = link; | 335 | info->p_dev = link; |
336 | link->priv = info; | 336 | link->priv = info; |
337 | 337 | ||
338 | link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; | ||
339 | link->resource[0]->end = 8; | ||
340 | link->conf.Attributes = CONF_ENABLE_IRQ; | 338 | link->conf.Attributes = CONF_ENABLE_IRQ; |
341 | if (do_sound) { | 339 | if (do_sound) { |
342 | link->conf.Attributes |= CONF_ENABLE_SPKR; | 340 | link->conf.Attributes |= CONF_ENABLE_SPKR; |
@@ -411,6 +409,27 @@ static int setup_serial(struct pcmcia_device *handle, struct serial_info * info, | |||
411 | 409 | ||
412 | /*====================================================================*/ | 410 | /*====================================================================*/ |
413 | 411 | ||
412 | static int pfc_config(struct pcmcia_device *p_dev) | ||
413 | { | ||
414 | unsigned int port = 0; | ||
415 | struct serial_info *info = p_dev->priv; | ||
416 | |||
417 | if ((p_dev->resource[1]->end != 0) && | ||
418 | (resource_size(p_dev->resource[1]) == 8)) { | ||
419 | port = p_dev->resource[1]->start; | ||
420 | info->slave = 1; | ||
421 | } else if ((info->manfid == MANFID_OSITECH) && | ||
422 | (resource_size(p_dev->resource[0]) == 0x40)) { | ||
423 | port = p_dev->resource[0]->start + 0x28; | ||
424 | info->slave = 1; | ||
425 | } | ||
426 | if (info->slave) | ||
427 | return setup_serial(p_dev, info, port, p_dev->irq); | ||
428 | |||
429 | dev_warn(&p_dev->dev, "no usable port range found, giving up\n"); | ||
430 | return -ENODEV; | ||
431 | } | ||
432 | |||
414 | static int simple_config_check(struct pcmcia_device *p_dev, | 433 | static int simple_config_check(struct pcmcia_device *p_dev, |
415 | cistpl_cftable_entry_t *cf, | 434 | cistpl_cftable_entry_t *cf, |
416 | cistpl_cftable_entry_t *dflt, | 435 | cistpl_cftable_entry_t *dflt, |
@@ -461,23 +480,8 @@ static int simple_config(struct pcmcia_device *link) | |||
461 | struct serial_info *info = link->priv; | 480 | struct serial_info *info = link->priv; |
462 | int i = -ENODEV, try; | 481 | int i = -ENODEV, try; |
463 | 482 | ||
464 | /* If the card is already configured, look up the port and irq */ | 483 | link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; |
465 | if (link->function_config) { | 484 | link->resource[0]->end = 8; |
466 | unsigned int port = 0; | ||
467 | if ((link->resource[1]->end != 0) && | ||
468 | (resource_size(link->resource[1]) == 8)) { | ||
469 | port = link->resource[1]->end; | ||
470 | info->slave = 1; | ||
471 | } else if ((info->manfid == MANFID_OSITECH) && | ||
472 | (resource_size(link->resource[0]) == 0x40)) { | ||
473 | port = link->resource[0]->start + 0x28; | ||
474 | info->slave = 1; | ||
475 | } | ||
476 | if (info->slave) { | ||
477 | return setup_serial(link, info, port, | ||
478 | link->irq); | ||
479 | } | ||
480 | } | ||
481 | 485 | ||
482 | /* First pass: look for a config entry that looks normal. | 486 | /* First pass: look for a config entry that looks normal. |
483 | * Two tries: without IO aliases, then with aliases */ | 487 | * Two tries: without IO aliases, then with aliases */ |
@@ -491,8 +495,7 @@ static int simple_config(struct pcmcia_device *link) | |||
491 | if (!pcmcia_loop_config(link, simple_config_check_notpicky, NULL)) | 495 | if (!pcmcia_loop_config(link, simple_config_check_notpicky, NULL)) |
492 | goto found_port; | 496 | goto found_port; |
493 | 497 | ||
494 | printk(KERN_NOTICE | 498 | dev_warn(&link->dev, "no usable port range found, giving up\n"); |
495 | "serial_cs: no usable port range found, giving up\n"); | ||
496 | return -1; | 499 | return -1; |
497 | 500 | ||
498 | found_port: | 501 | found_port: |
@@ -558,6 +561,7 @@ static int multi_config(struct pcmcia_device *link) | |||
558 | int i, base2 = 0; | 561 | int i, base2 = 0; |
559 | 562 | ||
560 | /* First, look for a generic full-sized window */ | 563 | /* First, look for a generic full-sized window */ |
564 | link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; | ||
561 | link->resource[0]->end = info->multi * 8; | 565 | link->resource[0]->end = info->multi * 8; |
562 | if (pcmcia_loop_config(link, multi_config_check, &base2)) { | 566 | if (pcmcia_loop_config(link, multi_config_check, &base2)) { |
563 | /* If that didn't work, look for two windows */ | 567 | /* If that didn't work, look for two windows */ |
@@ -565,15 +569,14 @@ static int multi_config(struct pcmcia_device *link) | |||
565 | info->multi = 2; | 569 | info->multi = 2; |
566 | if (pcmcia_loop_config(link, multi_config_check_notpicky, | 570 | if (pcmcia_loop_config(link, multi_config_check_notpicky, |
567 | &base2)) { | 571 | &base2)) { |
568 | printk(KERN_NOTICE "serial_cs: no usable port range" | 572 | dev_warn(&link->dev, "no usable port range " |
569 | "found, giving up\n"); | 573 | "found, giving up\n"); |
570 | return -ENODEV; | 574 | return -ENODEV; |
571 | } | 575 | } |
572 | } | 576 | } |
573 | 577 | ||
574 | if (!link->irq) | 578 | if (!link->irq) |
575 | dev_warn(&link->dev, | 579 | dev_warn(&link->dev, "no usable IRQ found, continuing...\n"); |
576 | "serial_cs: no usable IRQ found, continuing...\n"); | ||
577 | 580 | ||
578 | /* | 581 | /* |
579 | * Apply any configuration quirks. | 582 | * Apply any configuration quirks. |
@@ -675,6 +678,7 @@ static int serial_config(struct pcmcia_device * link) | |||
675 | multifunction cards that ask for appropriate IO port ranges */ | 678 | multifunction cards that ask for appropriate IO port ranges */ |
676 | if ((info->multi == 0) && | 679 | if ((info->multi == 0) && |
677 | (link->has_func_id) && | 680 | (link->has_func_id) && |
681 | (link->socket->pcmcia_pfc == 0) && | ||
678 | ((link->func_id == CISTPL_FUNCID_MULTI) || | 682 | ((link->func_id == CISTPL_FUNCID_MULTI) || |
679 | (link->func_id == CISTPL_FUNCID_SERIAL))) | 683 | (link->func_id == CISTPL_FUNCID_SERIAL))) |
680 | pcmcia_loop_config(link, serial_check_for_multi, info); | 684 | pcmcia_loop_config(link, serial_check_for_multi, info); |
@@ -685,7 +689,13 @@ static int serial_config(struct pcmcia_device * link) | |||
685 | if (info->quirk && info->quirk->multi != -1) | 689 | if (info->quirk && info->quirk->multi != -1) |
686 | info->multi = info->quirk->multi; | 690 | info->multi = info->quirk->multi; |
687 | 691 | ||
688 | if (info->multi > 1) | 692 | dev_info(&link->dev, |
693 | "trying to set up [0x%04x:0x%04x] (pfc: %d, multi: %d, quirk: %p)\n", | ||
694 | link->manf_id, link->card_id, | ||
695 | link->socket->pcmcia_pfc, info->multi, info->quirk); | ||
696 | if (link->socket->pcmcia_pfc) | ||
697 | i = pfc_config(link); | ||
698 | else if (info->multi > 1) | ||
689 | i = multi_config(link); | 699 | i = multi_config(link); |
690 | else | 700 | else |
691 | i = simple_config(link); | 701 | i = simple_config(link); |
@@ -704,7 +714,7 @@ static int serial_config(struct pcmcia_device * link) | |||
704 | return 0; | 714 | return 0; |
705 | 715 | ||
706 | failed: | 716 | failed: |
707 | dev_warn(&link->dev, "serial_cs: failed to initialize\n"); | 717 | dev_warn(&link->dev, "failed to initialize\n"); |
708 | serial_remove(link); | 718 | serial_remove(link); |
709 | return -ENODEV; | 719 | return -ENODEV; |
710 | } | 720 | } |
diff --git a/drivers/serial/sn_console.c b/drivers/serial/sn_console.c index 7e5e5efea4e..cff9a306660 100644 --- a/drivers/serial/sn_console.c +++ b/drivers/serial/sn_console.c | |||
@@ -492,7 +492,7 @@ sn_receive_chars(struct sn_cons_port *port, unsigned long flags) | |||
492 | sysrq_requested = 0; | 492 | sysrq_requested = 0; |
493 | if (ch && time_before(jiffies, sysrq_timeout)) { | 493 | if (ch && time_before(jiffies, sysrq_timeout)) { |
494 | spin_unlock_irqrestore(&port->sc_port.lock, flags); | 494 | spin_unlock_irqrestore(&port->sc_port.lock, flags); |
495 | handle_sysrq(ch, NULL); | 495 | handle_sysrq(ch); |
496 | spin_lock_irqsave(&port->sc_port.lock, flags); | 496 | spin_lock_irqsave(&port->sc_port.lock, flags); |
497 | /* ignore actual sysrq command char */ | 497 | /* ignore actual sysrq command char */ |
498 | continue; | 498 | continue; |
diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c index acd35d1ebd1..4c37c4e2864 100644 --- a/drivers/spi/amba-pl022.c +++ b/drivers/spi/amba-pl022.c | |||
@@ -503,8 +503,9 @@ static void giveback(struct pl022 *pl022) | |||
503 | msg->state = NULL; | 503 | msg->state = NULL; |
504 | if (msg->complete) | 504 | if (msg->complete) |
505 | msg->complete(msg->context); | 505 | msg->complete(msg->context); |
506 | /* This message is completed, so let's turn off the clock! */ | 506 | /* This message is completed, so let's turn off the clocks! */ |
507 | clk_disable(pl022->clk); | 507 | clk_disable(pl022->clk); |
508 | amba_pclk_disable(pl022->adev); | ||
508 | } | 509 | } |
509 | 510 | ||
510 | /** | 511 | /** |
@@ -1139,9 +1140,10 @@ static void pump_messages(struct work_struct *work) | |||
1139 | /* Setup the SPI using the per chip configuration */ | 1140 | /* Setup the SPI using the per chip configuration */ |
1140 | pl022->cur_chip = spi_get_ctldata(pl022->cur_msg->spi); | 1141 | pl022->cur_chip = spi_get_ctldata(pl022->cur_msg->spi); |
1141 | /* | 1142 | /* |
1142 | * We enable the clock here, then the clock will be disabled when | 1143 | * We enable the clocks here, then the clocks will be disabled when |
1143 | * giveback() is called in each method (poll/interrupt/DMA) | 1144 | * giveback() is called in each method (poll/interrupt/DMA) |
1144 | */ | 1145 | */ |
1146 | amba_pclk_enable(pl022->adev); | ||
1145 | clk_enable(pl022->clk); | 1147 | clk_enable(pl022->clk); |
1146 | restore_state(pl022); | 1148 | restore_state(pl022); |
1147 | flush(pl022); | 1149 | flush(pl022); |
@@ -1786,11 +1788,9 @@ pl022_probe(struct amba_device *adev, struct amba_id *id) | |||
1786 | } | 1788 | } |
1787 | 1789 | ||
1788 | /* Disable SSP */ | 1790 | /* Disable SSP */ |
1789 | clk_enable(pl022->clk); | ||
1790 | writew((readw(SSP_CR1(pl022->virtbase)) & (~SSP_CR1_MASK_SSE)), | 1791 | writew((readw(SSP_CR1(pl022->virtbase)) & (~SSP_CR1_MASK_SSE)), |
1791 | SSP_CR1(pl022->virtbase)); | 1792 | SSP_CR1(pl022->virtbase)); |
1792 | load_ssp_default_config(pl022); | 1793 | load_ssp_default_config(pl022); |
1793 | clk_disable(pl022->clk); | ||
1794 | 1794 | ||
1795 | status = request_irq(adev->irq[0], pl022_interrupt_handler, 0, "pl022", | 1795 | status = request_irq(adev->irq[0], pl022_interrupt_handler, 0, "pl022", |
1796 | pl022); | 1796 | pl022); |
@@ -1818,6 +1818,8 @@ pl022_probe(struct amba_device *adev, struct amba_id *id) | |||
1818 | goto err_spi_register; | 1818 | goto err_spi_register; |
1819 | } | 1819 | } |
1820 | dev_dbg(dev, "probe succeded\n"); | 1820 | dev_dbg(dev, "probe succeded\n"); |
1821 | /* Disable the silicon block pclk and clock it when needed */ | ||
1822 | amba_pclk_disable(adev); | ||
1821 | return 0; | 1823 | return 0; |
1822 | 1824 | ||
1823 | err_spi_register: | 1825 | err_spi_register: |
@@ -1879,9 +1881,9 @@ static int pl022_suspend(struct amba_device *adev, pm_message_t state) | |||
1879 | return status; | 1881 | return status; |
1880 | } | 1882 | } |
1881 | 1883 | ||
1882 | clk_enable(pl022->clk); | 1884 | amba_pclk_enable(adev); |
1883 | load_ssp_default_config(pl022); | 1885 | load_ssp_default_config(pl022); |
1884 | clk_disable(pl022->clk); | 1886 | amba_pclk_disable(adev); |
1885 | dev_dbg(&adev->dev, "suspended\n"); | 1887 | dev_dbg(&adev->dev, "suspended\n"); |
1886 | return 0; | 1888 | return 0; |
1887 | } | 1889 | } |
@@ -1981,7 +1983,7 @@ static int __init pl022_init(void) | |||
1981 | return amba_driver_register(&pl022_driver); | 1983 | return amba_driver_register(&pl022_driver); |
1982 | } | 1984 | } |
1983 | 1985 | ||
1984 | module_init(pl022_init); | 1986 | subsys_initcall(pl022_init); |
1985 | 1987 | ||
1986 | static void __exit pl022_exit(void) | 1988 | static void __exit pl022_exit(void) |
1987 | { | 1989 | { |
diff --git a/drivers/spi/dw_spi.c b/drivers/spi/dw_spi.c index d256cb00604..56247853c29 100644 --- a/drivers/spi/dw_spi.c +++ b/drivers/spi/dw_spi.c | |||
@@ -181,10 +181,6 @@ static void flush(struct dw_spi *dws) | |||
181 | wait_till_not_busy(dws); | 181 | wait_till_not_busy(dws); |
182 | } | 182 | } |
183 | 183 | ||
184 | static void null_cs_control(u32 command) | ||
185 | { | ||
186 | } | ||
187 | |||
188 | static int null_writer(struct dw_spi *dws) | 184 | static int null_writer(struct dw_spi *dws) |
189 | { | 185 | { |
190 | u8 n_bytes = dws->n_bytes; | 186 | u8 n_bytes = dws->n_bytes; |
@@ -322,7 +318,7 @@ static void giveback(struct dw_spi *dws) | |||
322 | struct spi_transfer, | 318 | struct spi_transfer, |
323 | transfer_list); | 319 | transfer_list); |
324 | 320 | ||
325 | if (!last_transfer->cs_change) | 321 | if (!last_transfer->cs_change && dws->cs_control) |
326 | dws->cs_control(MRST_SPI_DEASSERT); | 322 | dws->cs_control(MRST_SPI_DEASSERT); |
327 | 323 | ||
328 | msg->state = NULL; | 324 | msg->state = NULL; |
@@ -396,6 +392,11 @@ static irqreturn_t interrupt_transfer(struct dw_spi *dws) | |||
396 | static irqreturn_t dw_spi_irq(int irq, void *dev_id) | 392 | static irqreturn_t dw_spi_irq(int irq, void *dev_id) |
397 | { | 393 | { |
398 | struct dw_spi *dws = dev_id; | 394 | struct dw_spi *dws = dev_id; |
395 | u16 irq_status, irq_mask = 0x3f; | ||
396 | |||
397 | irq_status = dw_readw(dws, isr) & irq_mask; | ||
398 | if (!irq_status) | ||
399 | return IRQ_NONE; | ||
399 | 400 | ||
400 | if (!dws->cur_msg) { | 401 | if (!dws->cur_msg) { |
401 | spi_mask_intr(dws, SPI_INT_TXEI); | 402 | spi_mask_intr(dws, SPI_INT_TXEI); |
@@ -544,13 +545,13 @@ static void pump_transfers(unsigned long data) | |||
544 | */ | 545 | */ |
545 | if (dws->cs_control) { | 546 | if (dws->cs_control) { |
546 | if (dws->rx && dws->tx) | 547 | if (dws->rx && dws->tx) |
547 | chip->tmode = 0x00; | 548 | chip->tmode = SPI_TMOD_TR; |
548 | else if (dws->rx) | 549 | else if (dws->rx) |
549 | chip->tmode = 0x02; | 550 | chip->tmode = SPI_TMOD_RO; |
550 | else | 551 | else |
551 | chip->tmode = 0x01; | 552 | chip->tmode = SPI_TMOD_TO; |
552 | 553 | ||
553 | cr0 &= ~(0x3 << SPI_MODE_OFFSET); | 554 | cr0 &= ~SPI_TMOD_MASK; |
554 | cr0 |= (chip->tmode << SPI_TMOD_OFFSET); | 555 | cr0 |= (chip->tmode << SPI_TMOD_OFFSET); |
555 | } | 556 | } |
556 | 557 | ||
@@ -699,9 +700,6 @@ static int dw_spi_setup(struct spi_device *spi) | |||
699 | chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL); | 700 | chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL); |
700 | if (!chip) | 701 | if (!chip) |
701 | return -ENOMEM; | 702 | return -ENOMEM; |
702 | |||
703 | chip->cs_control = null_cs_control; | ||
704 | chip->enable_dma = 0; | ||
705 | } | 703 | } |
706 | 704 | ||
707 | /* | 705 | /* |
@@ -883,7 +881,7 @@ int __devinit dw_spi_add_host(struct dw_spi *dws) | |||
883 | dws->dma_inited = 0; | 881 | dws->dma_inited = 0; |
884 | dws->dma_addr = (dma_addr_t)(dws->paddr + 0x60); | 882 | dws->dma_addr = (dma_addr_t)(dws->paddr + 0x60); |
885 | 883 | ||
886 | ret = request_irq(dws->irq, dw_spi_irq, 0, | 884 | ret = request_irq(dws->irq, dw_spi_irq, IRQF_SHARED, |
887 | "dw_spi", dws); | 885 | "dw_spi", dws); |
888 | if (ret < 0) { | 886 | if (ret < 0) { |
889 | dev_err(&master->dev, "can not get IRQ\n"); | 887 | dev_err(&master->dev, "can not get IRQ\n"); |
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index a9e5c79ae52..b5a78a1f442 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/cache.h> | 24 | #include <linux/cache.h> |
25 | #include <linux/mutex.h> | 25 | #include <linux/mutex.h> |
26 | #include <linux/of_device.h> | ||
26 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
27 | #include <linux/mod_devicetable.h> | 28 | #include <linux/mod_devicetable.h> |
28 | #include <linux/spi/spi.h> | 29 | #include <linux/spi/spi.h> |
@@ -86,6 +87,10 @@ static int spi_match_device(struct device *dev, struct device_driver *drv) | |||
86 | const struct spi_device *spi = to_spi_device(dev); | 87 | const struct spi_device *spi = to_spi_device(dev); |
87 | const struct spi_driver *sdrv = to_spi_driver(drv); | 88 | const struct spi_driver *sdrv = to_spi_driver(drv); |
88 | 89 | ||
90 | /* Attempt an OF style match */ | ||
91 | if (of_driver_match_device(dev, drv)) | ||
92 | return 1; | ||
93 | |||
89 | if (sdrv->id_table) | 94 | if (sdrv->id_table) |
90 | return !!spi_match_id(sdrv->id_table, spi); | 95 | return !!spi_match_id(sdrv->id_table, spi); |
91 | 96 | ||
@@ -554,11 +559,9 @@ done: | |||
554 | EXPORT_SYMBOL_GPL(spi_register_master); | 559 | EXPORT_SYMBOL_GPL(spi_register_master); |
555 | 560 | ||
556 | 561 | ||
557 | static int __unregister(struct device *dev, void *master_dev) | 562 | static int __unregister(struct device *dev, void *null) |
558 | { | 563 | { |
559 | /* note: before about 2.6.14-rc1 this would corrupt memory: */ | 564 | spi_unregister_device(to_spi_device(dev)); |
560 | if (dev != master_dev) | ||
561 | spi_unregister_device(to_spi_device(dev)); | ||
562 | return 0; | 565 | return 0; |
563 | } | 566 | } |
564 | 567 | ||
@@ -576,8 +579,7 @@ void spi_unregister_master(struct spi_master *master) | |||
576 | { | 579 | { |
577 | int dummy; | 580 | int dummy; |
578 | 581 | ||
579 | dummy = device_for_each_child(master->dev.parent, &master->dev, | 582 | dummy = device_for_each_child(&master->dev, NULL, __unregister); |
580 | __unregister); | ||
581 | device_unregister(&master->dev); | 583 | device_unregister(&master->dev); |
582 | } | 584 | } |
583 | EXPORT_SYMBOL_GPL(spi_unregister_master); | 585 | EXPORT_SYMBOL_GPL(spi_unregister_master); |
diff --git a/drivers/spi/spi_gpio.c b/drivers/spi/spi_gpio.c index e24a63498ac..63e51b011d5 100644 --- a/drivers/spi/spi_gpio.c +++ b/drivers/spi/spi_gpio.c | |||
@@ -350,7 +350,7 @@ static int __init spi_gpio_probe(struct platform_device *pdev) | |||
350 | spi_gpio->bitbang.master = spi_master_get(master); | 350 | spi_gpio->bitbang.master = spi_master_get(master); |
351 | spi_gpio->bitbang.chipselect = spi_gpio_chipselect; | 351 | spi_gpio->bitbang.chipselect = spi_gpio_chipselect; |
352 | 352 | ||
353 | if ((master_flags & (SPI_MASTER_NO_RX | SPI_MASTER_NO_RX)) == 0) { | 353 | if ((master_flags & (SPI_MASTER_NO_TX | SPI_MASTER_NO_RX)) == 0) { |
354 | spi_gpio->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_txrx_word_mode0; | 354 | spi_gpio->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_txrx_word_mode0; |
355 | spi_gpio->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_txrx_word_mode1; | 355 | spi_gpio->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_txrx_word_mode1; |
356 | spi_gpio->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_txrx_word_mode2; | 356 | spi_gpio->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_txrx_word_mode2; |
diff --git a/drivers/spi/spi_mpc8xxx.c b/drivers/spi/spi_mpc8xxx.c index d31b57f7baa..1dd86b835cd 100644 --- a/drivers/spi/spi_mpc8xxx.c +++ b/drivers/spi/spi_mpc8xxx.c | |||
@@ -408,11 +408,17 @@ static void mpc8xxx_spi_cpm_bufs_start(struct mpc8xxx_spi *mspi) | |||
408 | 408 | ||
409 | xfer_ofs = mspi->xfer_in_progress->len - mspi->count; | 409 | xfer_ofs = mspi->xfer_in_progress->len - mspi->count; |
410 | 410 | ||
411 | out_be32(&rx_bd->cbd_bufaddr, mspi->rx_dma + xfer_ofs); | 411 | if (mspi->rx_dma == mspi->dma_dummy_rx) |
412 | out_be32(&rx_bd->cbd_bufaddr, mspi->rx_dma); | ||
413 | else | ||
414 | out_be32(&rx_bd->cbd_bufaddr, mspi->rx_dma + xfer_ofs); | ||
412 | out_be16(&rx_bd->cbd_datlen, 0); | 415 | out_be16(&rx_bd->cbd_datlen, 0); |
413 | out_be16(&rx_bd->cbd_sc, BD_SC_EMPTY | BD_SC_INTRPT | BD_SC_WRAP); | 416 | out_be16(&rx_bd->cbd_sc, BD_SC_EMPTY | BD_SC_INTRPT | BD_SC_WRAP); |
414 | 417 | ||
415 | out_be32(&tx_bd->cbd_bufaddr, mspi->tx_dma + xfer_ofs); | 418 | if (mspi->tx_dma == mspi->dma_dummy_tx) |
419 | out_be32(&tx_bd->cbd_bufaddr, mspi->tx_dma); | ||
420 | else | ||
421 | out_be32(&tx_bd->cbd_bufaddr, mspi->tx_dma + xfer_ofs); | ||
416 | out_be16(&tx_bd->cbd_datlen, xfer_len); | 422 | out_be16(&tx_bd->cbd_datlen, xfer_len); |
417 | out_be16(&tx_bd->cbd_sc, BD_SC_READY | BD_SC_INTRPT | BD_SC_WRAP | | 423 | out_be16(&tx_bd->cbd_sc, BD_SC_READY | BD_SC_INTRPT | BD_SC_WRAP | |
418 | BD_SC_LAST); | 424 | BD_SC_LAST); |
diff --git a/drivers/spi/spi_s3c64xx.c b/drivers/spi/spi_s3c64xx.c index 97365815a72..c3038da2648 100644 --- a/drivers/spi/spi_s3c64xx.c +++ b/drivers/spi/spi_s3c64xx.c | |||
@@ -200,6 +200,9 @@ static void flush_fifo(struct s3c64xx_spi_driver_data *sdd) | |||
200 | val = readl(regs + S3C64XX_SPI_STATUS); | 200 | val = readl(regs + S3C64XX_SPI_STATUS); |
201 | } while (TX_FIFO_LVL(val, sci) && loops--); | 201 | } while (TX_FIFO_LVL(val, sci) && loops--); |
202 | 202 | ||
203 | if (loops == 0) | ||
204 | dev_warn(&sdd->pdev->dev, "Timed out flushing TX FIFO\n"); | ||
205 | |||
203 | /* Flush RxFIFO*/ | 206 | /* Flush RxFIFO*/ |
204 | loops = msecs_to_loops(1); | 207 | loops = msecs_to_loops(1); |
205 | do { | 208 | do { |
@@ -210,6 +213,9 @@ static void flush_fifo(struct s3c64xx_spi_driver_data *sdd) | |||
210 | break; | 213 | break; |
211 | } while (loops--); | 214 | } while (loops--); |
212 | 215 | ||
216 | if (loops == 0) | ||
217 | dev_warn(&sdd->pdev->dev, "Timed out flushing RX FIFO\n"); | ||
218 | |||
213 | val = readl(regs + S3C64XX_SPI_CH_CFG); | 219 | val = readl(regs + S3C64XX_SPI_CH_CFG); |
214 | val &= ~S3C64XX_SPI_CH_SW_RST; | 220 | val &= ~S3C64XX_SPI_CH_SW_RST; |
215 | writel(val, regs + S3C64XX_SPI_CH_CFG); | 221 | writel(val, regs + S3C64XX_SPI_CH_CFG); |
@@ -320,16 +326,17 @@ static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd, | |||
320 | 326 | ||
321 | /* millisecs to xfer 'len' bytes @ 'cur_speed' */ | 327 | /* millisecs to xfer 'len' bytes @ 'cur_speed' */ |
322 | ms = xfer->len * 8 * 1000 / sdd->cur_speed; | 328 | ms = xfer->len * 8 * 1000 / sdd->cur_speed; |
323 | ms += 5; /* some tolerance */ | 329 | ms += 10; /* some tolerance */ |
324 | 330 | ||
325 | if (dma_mode) { | 331 | if (dma_mode) { |
326 | val = msecs_to_jiffies(ms) + 10; | 332 | val = msecs_to_jiffies(ms) + 10; |
327 | val = wait_for_completion_timeout(&sdd->xfer_completion, val); | 333 | val = wait_for_completion_timeout(&sdd->xfer_completion, val); |
328 | } else { | 334 | } else { |
335 | u32 status; | ||
329 | val = msecs_to_loops(ms); | 336 | val = msecs_to_loops(ms); |
330 | do { | 337 | do { |
331 | val = readl(regs + S3C64XX_SPI_STATUS); | 338 | status = readl(regs + S3C64XX_SPI_STATUS); |
332 | } while (RX_FIFO_LVL(val, sci) < xfer->len && --val); | 339 | } while (RX_FIFO_LVL(status, sci) < xfer->len && --val); |
333 | } | 340 | } |
334 | 341 | ||
335 | if (!val) | 342 | if (!val) |
@@ -447,8 +454,8 @@ static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd) | |||
447 | writel(val, regs + S3C64XX_SPI_CLK_CFG); | 454 | writel(val, regs + S3C64XX_SPI_CLK_CFG); |
448 | } | 455 | } |
449 | 456 | ||
450 | void s3c64xx_spi_dma_rxcb(struct s3c2410_dma_chan *chan, void *buf_id, | 457 | static void s3c64xx_spi_dma_rxcb(struct s3c2410_dma_chan *chan, void *buf_id, |
451 | int size, enum s3c2410_dma_buffresult res) | 458 | int size, enum s3c2410_dma_buffresult res) |
452 | { | 459 | { |
453 | struct s3c64xx_spi_driver_data *sdd = buf_id; | 460 | struct s3c64xx_spi_driver_data *sdd = buf_id; |
454 | unsigned long flags; | 461 | unsigned long flags; |
@@ -467,8 +474,8 @@ void s3c64xx_spi_dma_rxcb(struct s3c2410_dma_chan *chan, void *buf_id, | |||
467 | spin_unlock_irqrestore(&sdd->lock, flags); | 474 | spin_unlock_irqrestore(&sdd->lock, flags); |
468 | } | 475 | } |
469 | 476 | ||
470 | void s3c64xx_spi_dma_txcb(struct s3c2410_dma_chan *chan, void *buf_id, | 477 | static void s3c64xx_spi_dma_txcb(struct s3c2410_dma_chan *chan, void *buf_id, |
471 | int size, enum s3c2410_dma_buffresult res) | 478 | int size, enum s3c2410_dma_buffresult res) |
472 | { | 479 | { |
473 | struct s3c64xx_spi_driver_data *sdd = buf_id; | 480 | struct s3c64xx_spi_driver_data *sdd = buf_id; |
474 | unsigned long flags; | 481 | unsigned long flags; |
@@ -508,8 +515,9 @@ static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd, | |||
508 | list_for_each_entry(xfer, &msg->transfers, transfer_list) { | 515 | list_for_each_entry(xfer, &msg->transfers, transfer_list) { |
509 | 516 | ||
510 | if (xfer->tx_buf != NULL) { | 517 | if (xfer->tx_buf != NULL) { |
511 | xfer->tx_dma = dma_map_single(dev, xfer->tx_buf, | 518 | xfer->tx_dma = dma_map_single(dev, |
512 | xfer->len, DMA_TO_DEVICE); | 519 | (void *)xfer->tx_buf, xfer->len, |
520 | DMA_TO_DEVICE); | ||
513 | if (dma_mapping_error(dev, xfer->tx_dma)) { | 521 | if (dma_mapping_error(dev, xfer->tx_dma)) { |
514 | dev_err(dev, "dma_map_single Tx failed\n"); | 522 | dev_err(dev, "dma_map_single Tx failed\n"); |
515 | xfer->tx_dma = XFER_DMAADDR_INVALID; | 523 | xfer->tx_dma = XFER_DMAADDR_INVALID; |
@@ -919,6 +927,13 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev) | |||
919 | return -ENODEV; | 927 | return -ENODEV; |
920 | } | 928 | } |
921 | 929 | ||
930 | sci = pdev->dev.platform_data; | ||
931 | if (!sci->src_clk_name) { | ||
932 | dev_err(&pdev->dev, | ||
933 | "Board init must call s3c64xx_spi_set_info()\n"); | ||
934 | return -EINVAL; | ||
935 | } | ||
936 | |||
922 | /* Check for availability of necessary resource */ | 937 | /* Check for availability of necessary resource */ |
923 | 938 | ||
924 | dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0); | 939 | dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0); |
@@ -946,8 +961,6 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev) | |||
946 | return -ENOMEM; | 961 | return -ENOMEM; |
947 | } | 962 | } |
948 | 963 | ||
949 | sci = pdev->dev.platform_data; | ||
950 | |||
951 | platform_set_drvdata(pdev, master); | 964 | platform_set_drvdata(pdev, master); |
952 | 965 | ||
953 | sdd = spi_master_get_devdata(master); | 966 | sdd = spi_master_get_devdata(master); |
@@ -1170,7 +1183,7 @@ static int __init s3c64xx_spi_init(void) | |||
1170 | { | 1183 | { |
1171 | return platform_driver_probe(&s3c64xx_spi_driver, s3c64xx_spi_probe); | 1184 | return platform_driver_probe(&s3c64xx_spi_driver, s3c64xx_spi_probe); |
1172 | } | 1185 | } |
1173 | module_init(s3c64xx_spi_init); | 1186 | subsys_initcall(s3c64xx_spi_init); |
1174 | 1187 | ||
1175 | static void __exit s3c64xx_spi_exit(void) | 1188 | static void __exit s3c64xx_spi_exit(void) |
1176 | { | 1189 | { |
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 4a7a7a7f11b..335311a98fd 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig | |||
@@ -113,8 +113,6 @@ source "drivers/staging/vme/Kconfig" | |||
113 | 113 | ||
114 | source "drivers/staging/memrar/Kconfig" | 114 | source "drivers/staging/memrar/Kconfig" |
115 | 115 | ||
116 | source "drivers/staging/sep/Kconfig" | ||
117 | |||
118 | source "drivers/staging/iio/Kconfig" | 116 | source "drivers/staging/iio/Kconfig" |
119 | 117 | ||
120 | source "drivers/staging/zram/Kconfig" | 118 | source "drivers/staging/zram/Kconfig" |
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index ca5c03eb3ce..e3f1e1b6095 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile | |||
@@ -38,7 +38,6 @@ obj-$(CONFIG_FB_UDL) += udlfb/ | |||
38 | obj-$(CONFIG_HYPERV) += hv/ | 38 | obj-$(CONFIG_HYPERV) += hv/ |
39 | obj-$(CONFIG_VME_BUS) += vme/ | 39 | obj-$(CONFIG_VME_BUS) += vme/ |
40 | obj-$(CONFIG_MRST_RAR_HANDLER) += memrar/ | 40 | obj-$(CONFIG_MRST_RAR_HANDLER) += memrar/ |
41 | obj-$(CONFIG_DX_SEP) += sep/ | ||
42 | obj-$(CONFIG_IIO) += iio/ | 41 | obj-$(CONFIG_IIO) += iio/ |
43 | obj-$(CONFIG_ZRAM) += zram/ | 42 | obj-$(CONFIG_ZRAM) += zram/ |
44 | obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/ | 43 | obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/ |
diff --git a/drivers/staging/batman-adv/bat_sysfs.c b/drivers/staging/batman-adv/bat_sysfs.c index b4a8d5eb64f..05ca15a6c9f 100644 --- a/drivers/staging/batman-adv/bat_sysfs.c +++ b/drivers/staging/batman-adv/bat_sysfs.c | |||
@@ -267,6 +267,10 @@ static ssize_t store_log_level(struct kobject *kobj, struct attribute *attr, | |||
267 | if (atomic_read(&bat_priv->log_level) == log_level_tmp) | 267 | if (atomic_read(&bat_priv->log_level) == log_level_tmp) |
268 | return count; | 268 | return count; |
269 | 269 | ||
270 | bat_info(net_dev, "Changing log level from: %i to: %li\n", | ||
271 | atomic_read(&bat_priv->log_level), | ||
272 | log_level_tmp); | ||
273 | |||
270 | atomic_set(&bat_priv->log_level, (unsigned)log_level_tmp); | 274 | atomic_set(&bat_priv->log_level, (unsigned)log_level_tmp); |
271 | return count; | 275 | return count; |
272 | } | 276 | } |
diff --git a/drivers/staging/batman-adv/hard-interface.c b/drivers/staging/batman-adv/hard-interface.c index 92c216a5688..6e973a79aa2 100644 --- a/drivers/staging/batman-adv/hard-interface.c +++ b/drivers/staging/batman-adv/hard-interface.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include "hash.h" | 30 | #include "hash.h" |
31 | 31 | ||
32 | #include <linux/if_arp.h> | 32 | #include <linux/if_arp.h> |
33 | #include <linux/netfilter_bridge.h> | ||
34 | 33 | ||
35 | #define MIN(x, y) ((x) < (y) ? (x) : (y)) | 34 | #define MIN(x, y) ((x) < (y) ? (x) : (y)) |
36 | 35 | ||
@@ -129,6 +128,9 @@ static bool hardif_is_iface_up(struct batman_if *batman_if) | |||
129 | 128 | ||
130 | static void update_mac_addresses(struct batman_if *batman_if) | 129 | static void update_mac_addresses(struct batman_if *batman_if) |
131 | { | 130 | { |
131 | if (!batman_if || !batman_if->packet_buff) | ||
132 | return; | ||
133 | |||
132 | addr_to_string(batman_if->addr_str, batman_if->net_dev->dev_addr); | 134 | addr_to_string(batman_if->addr_str, batman_if->net_dev->dev_addr); |
133 | 135 | ||
134 | memcpy(((struct batman_packet *)(batman_if->packet_buff))->orig, | 136 | memcpy(((struct batman_packet *)(batman_if->packet_buff))->orig, |
@@ -194,8 +196,6 @@ static void hardif_activate_interface(struct net_device *net_dev, | |||
194 | if (batman_if->if_status != IF_INACTIVE) | 196 | if (batman_if->if_status != IF_INACTIVE) |
195 | return; | 197 | return; |
196 | 198 | ||
197 | dev_hold(batman_if->net_dev); | ||
198 | |||
199 | update_mac_addresses(batman_if); | 199 | update_mac_addresses(batman_if); |
200 | batman_if->if_status = IF_TO_BE_ACTIVATED; | 200 | batman_if->if_status = IF_TO_BE_ACTIVATED; |
201 | 201 | ||
@@ -222,8 +222,6 @@ static void hardif_deactivate_interface(struct net_device *net_dev, | |||
222 | (batman_if->if_status != IF_TO_BE_ACTIVATED)) | 222 | (batman_if->if_status != IF_TO_BE_ACTIVATED)) |
223 | return; | 223 | return; |
224 | 224 | ||
225 | dev_put(batman_if->net_dev); | ||
226 | |||
227 | batman_if->if_status = IF_INACTIVE; | 225 | batman_if->if_status = IF_INACTIVE; |
228 | 226 | ||
229 | bat_info(net_dev, "Interface deactivated: %s\n", batman_if->dev); | 227 | bat_info(net_dev, "Interface deactivated: %s\n", batman_if->dev); |
@@ -318,11 +316,13 @@ static struct batman_if *hardif_add_interface(struct net_device *net_dev) | |||
318 | if (ret != 1) | 316 | if (ret != 1) |
319 | goto out; | 317 | goto out; |
320 | 318 | ||
319 | dev_hold(net_dev); | ||
320 | |||
321 | batman_if = kmalloc(sizeof(struct batman_if), GFP_ATOMIC); | 321 | batman_if = kmalloc(sizeof(struct batman_if), GFP_ATOMIC); |
322 | if (!batman_if) { | 322 | if (!batman_if) { |
323 | pr_err("Can't add interface (%s): out of memory\n", | 323 | pr_err("Can't add interface (%s): out of memory\n", |
324 | net_dev->name); | 324 | net_dev->name); |
325 | goto out; | 325 | goto release_dev; |
326 | } | 326 | } |
327 | 327 | ||
328 | batman_if->dev = kstrdup(net_dev->name, GFP_ATOMIC); | 328 | batman_if->dev = kstrdup(net_dev->name, GFP_ATOMIC); |
@@ -336,6 +336,7 @@ static struct batman_if *hardif_add_interface(struct net_device *net_dev) | |||
336 | batman_if->if_num = -1; | 336 | batman_if->if_num = -1; |
337 | batman_if->net_dev = net_dev; | 337 | batman_if->net_dev = net_dev; |
338 | batman_if->if_status = IF_NOT_IN_USE; | 338 | batman_if->if_status = IF_NOT_IN_USE; |
339 | batman_if->packet_buff = NULL; | ||
339 | INIT_LIST_HEAD(&batman_if->list); | 340 | INIT_LIST_HEAD(&batman_if->list); |
340 | 341 | ||
341 | check_known_mac_addr(batman_if->net_dev->dev_addr); | 342 | check_known_mac_addr(batman_if->net_dev->dev_addr); |
@@ -346,6 +347,8 @@ free_dev: | |||
346 | kfree(batman_if->dev); | 347 | kfree(batman_if->dev); |
347 | free_if: | 348 | free_if: |
348 | kfree(batman_if); | 349 | kfree(batman_if); |
350 | release_dev: | ||
351 | dev_put(net_dev); | ||
349 | out: | 352 | out: |
350 | return NULL; | 353 | return NULL; |
351 | } | 354 | } |
@@ -374,6 +377,7 @@ static void hardif_remove_interface(struct batman_if *batman_if) | |||
374 | batman_if->if_status = IF_TO_BE_REMOVED; | 377 | batman_if->if_status = IF_TO_BE_REMOVED; |
375 | list_del_rcu(&batman_if->list); | 378 | list_del_rcu(&batman_if->list); |
376 | sysfs_del_hardif(&batman_if->hardif_obj); | 379 | sysfs_del_hardif(&batman_if->hardif_obj); |
380 | dev_put(batman_if->net_dev); | ||
377 | call_rcu(&batman_if->rcu, hardif_free_interface); | 381 | call_rcu(&batman_if->rcu, hardif_free_interface); |
378 | } | 382 | } |
379 | 383 | ||
@@ -393,15 +397,13 @@ static int hard_if_event(struct notifier_block *this, | |||
393 | /* FIXME: each batman_if will be attached to a softif */ | 397 | /* FIXME: each batman_if will be attached to a softif */ |
394 | struct bat_priv *bat_priv = netdev_priv(soft_device); | 398 | struct bat_priv *bat_priv = netdev_priv(soft_device); |
395 | 399 | ||
396 | if (!batman_if) | 400 | if (!batman_if && event == NETDEV_REGISTER) |
397 | batman_if = hardif_add_interface(net_dev); | 401 | batman_if = hardif_add_interface(net_dev); |
398 | 402 | ||
399 | if (!batman_if) | 403 | if (!batman_if) |
400 | goto out; | 404 | goto out; |
401 | 405 | ||
402 | switch (event) { | 406 | switch (event) { |
403 | case NETDEV_REGISTER: | ||
404 | break; | ||
405 | case NETDEV_UP: | 407 | case NETDEV_UP: |
406 | hardif_activate_interface(soft_device, bat_priv, batman_if); | 408 | hardif_activate_interface(soft_device, bat_priv, batman_if); |
407 | break; | 409 | break; |
@@ -428,11 +430,6 @@ out: | |||
428 | return NOTIFY_DONE; | 430 | return NOTIFY_DONE; |
429 | } | 431 | } |
430 | 432 | ||
431 | static int batman_skb_recv_finish(struct sk_buff *skb) | ||
432 | { | ||
433 | return NF_ACCEPT; | ||
434 | } | ||
435 | |||
436 | /* receive a packet with the batman ethertype coming on a hard | 433 | /* receive a packet with the batman ethertype coming on a hard |
437 | * interface */ | 434 | * interface */ |
438 | int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, | 435 | int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, |
@@ -442,8 +439,6 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, | |||
442 | struct bat_priv *bat_priv = netdev_priv(soft_device); | 439 | struct bat_priv *bat_priv = netdev_priv(soft_device); |
443 | struct batman_packet *batman_packet; | 440 | struct batman_packet *batman_packet; |
444 | struct batman_if *batman_if; | 441 | struct batman_if *batman_if; |
445 | struct net_device_stats *stats; | ||
446 | struct rtnl_link_stats64 temp; | ||
447 | int ret; | 442 | int ret; |
448 | 443 | ||
449 | skb = skb_share_check(skb, GFP_ATOMIC); | 444 | skb = skb_share_check(skb, GFP_ATOMIC); |
@@ -455,13 +450,6 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, | |||
455 | if (atomic_read(&module_state) != MODULE_ACTIVE) | 450 | if (atomic_read(&module_state) != MODULE_ACTIVE) |
456 | goto err_free; | 451 | goto err_free; |
457 | 452 | ||
458 | /* if netfilter/ebtables wants to block incoming batman | ||
459 | * packets then give them a chance to do so here */ | ||
460 | ret = NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, dev, NULL, | ||
461 | batman_skb_recv_finish); | ||
462 | if (ret != 1) | ||
463 | goto err_out; | ||
464 | |||
465 | /* packet should hold at least type and version */ | 453 | /* packet should hold at least type and version */ |
466 | if (unlikely(skb_headlen(skb) < 2)) | 454 | if (unlikely(skb_headlen(skb) < 2)) |
467 | goto err_free; | 455 | goto err_free; |
@@ -479,12 +467,6 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, | |||
479 | if (batman_if->if_status != IF_ACTIVE) | 467 | if (batman_if->if_status != IF_ACTIVE) |
480 | goto err_free; | 468 | goto err_free; |
481 | 469 | ||
482 | stats = (struct net_device_stats *)dev_get_stats(skb->dev, &temp); | ||
483 | if (stats) { | ||
484 | stats->rx_packets++; | ||
485 | stats->rx_bytes += skb->len; | ||
486 | } | ||
487 | |||
488 | batman_packet = (struct batman_packet *)skb->data; | 470 | batman_packet = (struct batman_packet *)skb->data; |
489 | 471 | ||
490 | if (batman_packet->version != COMPAT_VERSION) { | 472 | if (batman_packet->version != COMPAT_VERSION) { |
diff --git a/drivers/staging/batman-adv/icmp_socket.c b/drivers/staging/batman-adv/icmp_socket.c index fc3d32c1272..3ae7dd2d2d4 100644 --- a/drivers/staging/batman-adv/icmp_socket.c +++ b/drivers/staging/batman-adv/icmp_socket.c | |||
@@ -67,6 +67,7 @@ static int bat_socket_open(struct inode *inode, struct file *file) | |||
67 | INIT_LIST_HEAD(&socket_client->queue_list); | 67 | INIT_LIST_HEAD(&socket_client->queue_list); |
68 | socket_client->queue_len = 0; | 68 | socket_client->queue_len = 0; |
69 | socket_client->index = i; | 69 | socket_client->index = i; |
70 | socket_client->bat_priv = inode->i_private; | ||
70 | spin_lock_init(&socket_client->lock); | 71 | spin_lock_init(&socket_client->lock); |
71 | init_waitqueue_head(&socket_client->queue_wait); | 72 | init_waitqueue_head(&socket_client->queue_wait); |
72 | 73 | ||
@@ -151,9 +152,8 @@ static ssize_t bat_socket_read(struct file *file, char __user *buf, | |||
151 | static ssize_t bat_socket_write(struct file *file, const char __user *buff, | 152 | static ssize_t bat_socket_write(struct file *file, const char __user *buff, |
152 | size_t len, loff_t *off) | 153 | size_t len, loff_t *off) |
153 | { | 154 | { |
154 | /* FIXME: each orig_node->batman_if will be attached to a softif */ | ||
155 | struct bat_priv *bat_priv = netdev_priv(soft_device); | ||
156 | struct socket_client *socket_client = file->private_data; | 155 | struct socket_client *socket_client = file->private_data; |
156 | struct bat_priv *bat_priv = socket_client->bat_priv; | ||
157 | struct icmp_packet_rr icmp_packet; | 157 | struct icmp_packet_rr icmp_packet; |
158 | struct orig_node *orig_node; | 158 | struct orig_node *orig_node; |
159 | struct batman_if *batman_if; | 159 | struct batman_if *batman_if; |
@@ -168,6 +168,9 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff, | |||
168 | return -EINVAL; | 168 | return -EINVAL; |
169 | } | 169 | } |
170 | 170 | ||
171 | if (!bat_priv->primary_if) | ||
172 | return -EFAULT; | ||
173 | |||
171 | if (len >= sizeof(struct icmp_packet_rr)) | 174 | if (len >= sizeof(struct icmp_packet_rr)) |
172 | packet_len = sizeof(struct icmp_packet_rr); | 175 | packet_len = sizeof(struct icmp_packet_rr); |
173 | 176 | ||
@@ -223,7 +226,8 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff, | |||
223 | if (batman_if->if_status != IF_ACTIVE) | 226 | if (batman_if->if_status != IF_ACTIVE) |
224 | goto dst_unreach; | 227 | goto dst_unreach; |
225 | 228 | ||
226 | memcpy(icmp_packet.orig, batman_if->net_dev->dev_addr, ETH_ALEN); | 229 | memcpy(icmp_packet.orig, |
230 | bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); | ||
227 | 231 | ||
228 | if (packet_len == sizeof(struct icmp_packet_rr)) | 232 | if (packet_len == sizeof(struct icmp_packet_rr)) |
229 | memcpy(icmp_packet.rr, batman_if->net_dev->dev_addr, ETH_ALEN); | 233 | memcpy(icmp_packet.rr, batman_if->net_dev->dev_addr, ETH_ALEN); |
@@ -271,7 +275,7 @@ int bat_socket_setup(struct bat_priv *bat_priv) | |||
271 | goto err; | 275 | goto err; |
272 | 276 | ||
273 | d = debugfs_create_file(ICMP_SOCKET, S_IFREG | S_IWUSR | S_IRUSR, | 277 | d = debugfs_create_file(ICMP_SOCKET, S_IFREG | S_IWUSR | S_IRUSR, |
274 | bat_priv->debug_dir, NULL, &fops); | 278 | bat_priv->debug_dir, bat_priv, &fops); |
275 | if (d) | 279 | if (d) |
276 | goto err; | 280 | goto err; |
277 | 281 | ||
diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c index 2686019fe4e..ef7c20ae797 100644 --- a/drivers/staging/batman-adv/main.c +++ b/drivers/staging/batman-adv/main.c | |||
@@ -250,10 +250,13 @@ int choose_orig(void *data, int32_t size) | |||
250 | int is_my_mac(uint8_t *addr) | 250 | int is_my_mac(uint8_t *addr) |
251 | { | 251 | { |
252 | struct batman_if *batman_if; | 252 | struct batman_if *batman_if; |
253 | |||
253 | rcu_read_lock(); | 254 | rcu_read_lock(); |
254 | list_for_each_entry_rcu(batman_if, &if_list, list) { | 255 | list_for_each_entry_rcu(batman_if, &if_list, list) { |
255 | if ((batman_if->net_dev) && | 256 | if (batman_if->if_status != IF_ACTIVE) |
256 | (compare_orig(batman_if->net_dev->dev_addr, addr))) { | 257 | continue; |
258 | |||
259 | if (compare_orig(batman_if->net_dev->dev_addr, addr)) { | ||
257 | rcu_read_unlock(); | 260 | rcu_read_unlock(); |
258 | return 1; | 261 | return 1; |
259 | } | 262 | } |
diff --git a/drivers/staging/batman-adv/originator.c b/drivers/staging/batman-adv/originator.c index 28bb627ffa1..de5a8c1a810 100644 --- a/drivers/staging/batman-adv/originator.c +++ b/drivers/staging/batman-adv/originator.c | |||
@@ -391,11 +391,12 @@ static int orig_node_add_if(struct orig_node *orig_node, int max_if_num) | |||
391 | int orig_hash_add_if(struct batman_if *batman_if, int max_if_num) | 391 | int orig_hash_add_if(struct batman_if *batman_if, int max_if_num) |
392 | { | 392 | { |
393 | struct orig_node *orig_node; | 393 | struct orig_node *orig_node; |
394 | unsigned long flags; | ||
394 | HASHIT(hashit); | 395 | HASHIT(hashit); |
395 | 396 | ||
396 | /* resize all orig nodes because orig_node->bcast_own(_sum) depend on | 397 | /* resize all orig nodes because orig_node->bcast_own(_sum) depend on |
397 | * if_num */ | 398 | * if_num */ |
398 | spin_lock(&orig_hash_lock); | 399 | spin_lock_irqsave(&orig_hash_lock, flags); |
399 | 400 | ||
400 | while (hash_iterate(orig_hash, &hashit)) { | 401 | while (hash_iterate(orig_hash, &hashit)) { |
401 | orig_node = hashit.bucket->data; | 402 | orig_node = hashit.bucket->data; |
@@ -404,11 +405,11 @@ int orig_hash_add_if(struct batman_if *batman_if, int max_if_num) | |||
404 | goto err; | 405 | goto err; |
405 | } | 406 | } |
406 | 407 | ||
407 | spin_unlock(&orig_hash_lock); | 408 | spin_unlock_irqrestore(&orig_hash_lock, flags); |
408 | return 0; | 409 | return 0; |
409 | 410 | ||
410 | err: | 411 | err: |
411 | spin_unlock(&orig_hash_lock); | 412 | spin_unlock_irqrestore(&orig_hash_lock, flags); |
412 | return -ENOMEM; | 413 | return -ENOMEM; |
413 | } | 414 | } |
414 | 415 | ||
@@ -468,12 +469,13 @@ int orig_hash_del_if(struct batman_if *batman_if, int max_if_num) | |||
468 | { | 469 | { |
469 | struct batman_if *batman_if_tmp; | 470 | struct batman_if *batman_if_tmp; |
470 | struct orig_node *orig_node; | 471 | struct orig_node *orig_node; |
472 | unsigned long flags; | ||
471 | HASHIT(hashit); | 473 | HASHIT(hashit); |
472 | int ret; | 474 | int ret; |
473 | 475 | ||
474 | /* resize all orig nodes because orig_node->bcast_own(_sum) depend on | 476 | /* resize all orig nodes because orig_node->bcast_own(_sum) depend on |
475 | * if_num */ | 477 | * if_num */ |
476 | spin_lock(&orig_hash_lock); | 478 | spin_lock_irqsave(&orig_hash_lock, flags); |
477 | 479 | ||
478 | while (hash_iterate(orig_hash, &hashit)) { | 480 | while (hash_iterate(orig_hash, &hashit)) { |
479 | orig_node = hashit.bucket->data; | 481 | orig_node = hashit.bucket->data; |
@@ -500,10 +502,10 @@ int orig_hash_del_if(struct batman_if *batman_if, int max_if_num) | |||
500 | rcu_read_unlock(); | 502 | rcu_read_unlock(); |
501 | 503 | ||
502 | batman_if->if_num = -1; | 504 | batman_if->if_num = -1; |
503 | spin_unlock(&orig_hash_lock); | 505 | spin_unlock_irqrestore(&orig_hash_lock, flags); |
504 | return 0; | 506 | return 0; |
505 | 507 | ||
506 | err: | 508 | err: |
507 | spin_unlock(&orig_hash_lock); | 509 | spin_unlock_irqrestore(&orig_hash_lock, flags); |
508 | return -ENOMEM; | 510 | return -ENOMEM; |
509 | } | 511 | } |
diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index 066cc9149bf..032195e6de9 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c | |||
@@ -783,6 +783,8 @@ int recv_bat_packet(struct sk_buff *skb, | |||
783 | 783 | ||
784 | static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len) | 784 | static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len) |
785 | { | 785 | { |
786 | /* FIXME: each batman_if will be attached to a softif */ | ||
787 | struct bat_priv *bat_priv = netdev_priv(soft_device); | ||
786 | struct orig_node *orig_node; | 788 | struct orig_node *orig_node; |
787 | struct icmp_packet_rr *icmp_packet; | 789 | struct icmp_packet_rr *icmp_packet; |
788 | struct ethhdr *ethhdr; | 790 | struct ethhdr *ethhdr; |
@@ -801,6 +803,9 @@ static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len) | |||
801 | return NET_RX_DROP; | 803 | return NET_RX_DROP; |
802 | } | 804 | } |
803 | 805 | ||
806 | if (!bat_priv->primary_if) | ||
807 | return NET_RX_DROP; | ||
808 | |||
804 | /* answer echo request (ping) */ | 809 | /* answer echo request (ping) */ |
805 | /* get routing information */ | 810 | /* get routing information */ |
806 | spin_lock_irqsave(&orig_hash_lock, flags); | 811 | spin_lock_irqsave(&orig_hash_lock, flags); |
@@ -830,7 +835,8 @@ static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len) | |||
830 | } | 835 | } |
831 | 836 | ||
832 | memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); | 837 | memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); |
833 | memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN); | 838 | memcpy(icmp_packet->orig, |
839 | bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); | ||
834 | icmp_packet->msg_type = ECHO_REPLY; | 840 | icmp_packet->msg_type = ECHO_REPLY; |
835 | icmp_packet->ttl = TTL; | 841 | icmp_packet->ttl = TTL; |
836 | 842 | ||
@@ -845,6 +851,8 @@ static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len) | |||
845 | 851 | ||
846 | static int recv_icmp_ttl_exceeded(struct sk_buff *skb, size_t icmp_len) | 852 | static int recv_icmp_ttl_exceeded(struct sk_buff *skb, size_t icmp_len) |
847 | { | 853 | { |
854 | /* FIXME: each batman_if will be attached to a softif */ | ||
855 | struct bat_priv *bat_priv = netdev_priv(soft_device); | ||
848 | struct orig_node *orig_node; | 856 | struct orig_node *orig_node; |
849 | struct icmp_packet *icmp_packet; | 857 | struct icmp_packet *icmp_packet; |
850 | struct ethhdr *ethhdr; | 858 | struct ethhdr *ethhdr; |
@@ -865,6 +873,9 @@ static int recv_icmp_ttl_exceeded(struct sk_buff *skb, size_t icmp_len) | |||
865 | return NET_RX_DROP; | 873 | return NET_RX_DROP; |
866 | } | 874 | } |
867 | 875 | ||
876 | if (!bat_priv->primary_if) | ||
877 | return NET_RX_DROP; | ||
878 | |||
868 | /* get routing information */ | 879 | /* get routing information */ |
869 | spin_lock_irqsave(&orig_hash_lock, flags); | 880 | spin_lock_irqsave(&orig_hash_lock, flags); |
870 | orig_node = ((struct orig_node *) | 881 | orig_node = ((struct orig_node *) |
@@ -892,7 +903,8 @@ static int recv_icmp_ttl_exceeded(struct sk_buff *skb, size_t icmp_len) | |||
892 | } | 903 | } |
893 | 904 | ||
894 | memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); | 905 | memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); |
895 | memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN); | 906 | memcpy(icmp_packet->orig, |
907 | bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); | ||
896 | icmp_packet->msg_type = TTL_EXCEEDED; | 908 | icmp_packet->msg_type = TTL_EXCEEDED; |
897 | icmp_packet->ttl = TTL; | 909 | icmp_packet->ttl = TTL; |
898 | 910 | ||
diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c index 055edee7b4e..da3c82e47bb 100644 --- a/drivers/staging/batman-adv/send.c +++ b/drivers/staging/batman-adv/send.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include "vis.h" | 29 | #include "vis.h" |
30 | #include "aggregation.h" | 30 | #include "aggregation.h" |
31 | 31 | ||
32 | #include <linux/netfilter_bridge.h> | ||
33 | 32 | ||
34 | static void send_outstanding_bcast_packet(struct work_struct *work); | 33 | static void send_outstanding_bcast_packet(struct work_struct *work); |
35 | 34 | ||
@@ -92,12 +91,9 @@ int send_skb_packet(struct sk_buff *skb, | |||
92 | 91 | ||
93 | /* dev_queue_xmit() returns a negative result on error. However on | 92 | /* dev_queue_xmit() returns a negative result on error. However on |
94 | * congestion and traffic shaping, it drops and returns NET_XMIT_DROP | 93 | * congestion and traffic shaping, it drops and returns NET_XMIT_DROP |
95 | * (which is > 0). This will not be treated as an error. | 94 | * (which is > 0). This will not be treated as an error. */ |
96 | * Also, if netfilter/ebtables wants to block outgoing batman | ||
97 | * packets then giving them a chance to do so here */ | ||
98 | 95 | ||
99 | return NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev, | 96 | return dev_queue_xmit(skb); |
100 | dev_queue_xmit); | ||
101 | send_skb_err: | 97 | send_skb_err: |
102 | kfree_skb(skb); | 98 | kfree_skb(skb); |
103 | return NET_XMIT_DROP; | 99 | return NET_XMIT_DROP; |
diff --git a/drivers/staging/batman-adv/types.h b/drivers/staging/batman-adv/types.h index 21d0717afb0..9aa9d369c75 100644 --- a/drivers/staging/batman-adv/types.h +++ b/drivers/staging/batman-adv/types.h | |||
@@ -126,6 +126,7 @@ struct socket_client { | |||
126 | unsigned char index; | 126 | unsigned char index; |
127 | spinlock_t lock; | 127 | spinlock_t lock; |
128 | wait_queue_head_t queue_wait; | 128 | wait_queue_head_t queue_wait; |
129 | struct bat_priv *bat_priv; | ||
129 | }; | 130 | }; |
130 | 131 | ||
131 | struct socket_packet { | 132 | struct socket_packet { |
diff --git a/drivers/staging/comedi/drivers/das08_cs.c b/drivers/staging/comedi/drivers/das08_cs.c index c6aa52f8dce..48d9fb1227d 100644 --- a/drivers/staging/comedi/drivers/das08_cs.c +++ b/drivers/staging/comedi/drivers/das08_cs.c | |||
@@ -222,7 +222,6 @@ static int das08_pcmcia_config_loop(struct pcmcia_device *p_dev, | |||
222 | p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; | 222 | p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; |
223 | p_dev->resource[0]->flags |= | 223 | p_dev->resource[0]->flags |= |
224 | pcmcia_io_cfg_data_width(io->flags); | 224 | pcmcia_io_cfg_data_width(io->flags); |
225 | p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; | ||
226 | p_dev->resource[0]->start = io->win[0].base; | 225 | p_dev->resource[0]->start = io->win[0].base; |
227 | p_dev->resource[0]->end = io->win[0].len; | 226 | p_dev->resource[0]->end = io->win[0].len; |
228 | if (io->nwin > 1) { | 227 | if (io->nwin > 1) { |
diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index 56e11575c97..64a01147eca 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c | |||
@@ -327,6 +327,9 @@ static const struct net_device_ops device_ops = { | |||
327 | .ndo_stop = netvsc_close, | 327 | .ndo_stop = netvsc_close, |
328 | .ndo_start_xmit = netvsc_start_xmit, | 328 | .ndo_start_xmit = netvsc_start_xmit, |
329 | .ndo_set_multicast_list = netvsc_set_multicast_list, | 329 | .ndo_set_multicast_list = netvsc_set_multicast_list, |
330 | .ndo_change_mtu = eth_change_mtu, | ||
331 | .ndo_validate_addr = eth_validate_addr, | ||
332 | .ndo_set_mac_address = eth_mac_addr, | ||
330 | }; | 333 | }; |
331 | 334 | ||
332 | static int netvsc_probe(struct device *device) | 335 | static int netvsc_probe(struct device *device) |
diff --git a/drivers/staging/hv/ring_buffer.c b/drivers/staging/hv/ring_buffer.c index 17bc7626f70..d78c569ac94 100644 --- a/drivers/staging/hv/ring_buffer.c +++ b/drivers/staging/hv/ring_buffer.c | |||
@@ -193,8 +193,7 @@ Description: | |||
193 | static inline u64 | 193 | static inline u64 |
194 | GetRingBufferIndices(struct hv_ring_buffer_info *RingInfo) | 194 | GetRingBufferIndices(struct hv_ring_buffer_info *RingInfo) |
195 | { | 195 | { |
196 | return ((u64)RingInfo->RingBuffer->WriteIndex << 32) | 196 | return (u64)RingInfo->RingBuffer->WriteIndex << 32; |
197 | || RingInfo->RingBuffer->ReadIndex; | ||
198 | } | 197 | } |
199 | 198 | ||
200 | 199 | ||
diff --git a/drivers/staging/hv/storvsc_api.h b/drivers/staging/hv/storvsc_api.h index 0063bde9a4b..8505a1c5f9e 100644 --- a/drivers/staging/hv/storvsc_api.h +++ b/drivers/staging/hv/storvsc_api.h | |||
@@ -28,10 +28,10 @@ | |||
28 | #include "vmbus_api.h" | 28 | #include "vmbus_api.h" |
29 | 29 | ||
30 | /* Defines */ | 30 | /* Defines */ |
31 | #define STORVSC_RING_BUFFER_SIZE (10*PAGE_SIZE) | 31 | #define STORVSC_RING_BUFFER_SIZE (20*PAGE_SIZE) |
32 | #define BLKVSC_RING_BUFFER_SIZE (20*PAGE_SIZE) | 32 | #define BLKVSC_RING_BUFFER_SIZE (20*PAGE_SIZE) |
33 | 33 | ||
34 | #define STORVSC_MAX_IO_REQUESTS 64 | 34 | #define STORVSC_MAX_IO_REQUESTS 128 |
35 | 35 | ||
36 | /* | 36 | /* |
37 | * In Hyper-V, each port/path/target maps to 1 scsi host adapter. In | 37 | * In Hyper-V, each port/path/target maps to 1 scsi host adapter. In |
diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 075b61bd492..62882a437aa 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c | |||
@@ -495,7 +495,7 @@ static unsigned int copy_to_bounce_buffer(struct scatterlist *orig_sgl, | |||
495 | 495 | ||
496 | /* ASSERT(orig_sgl[i].offset + orig_sgl[i].length <= PAGE_SIZE); */ | 496 | /* ASSERT(orig_sgl[i].offset + orig_sgl[i].length <= PAGE_SIZE); */ |
497 | 497 | ||
498 | if (j == 0) | 498 | if (bounce_addr == 0) |
499 | bounce_addr = (unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])), KM_IRQ0); | 499 | bounce_addr = (unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])), KM_IRQ0); |
500 | 500 | ||
501 | while (srclen) { | 501 | while (srclen) { |
@@ -556,7 +556,7 @@ static unsigned int copy_from_bounce_buffer(struct scatterlist *orig_sgl, | |||
556 | destlen = orig_sgl[i].length; | 556 | destlen = orig_sgl[i].length; |
557 | /* ASSERT(orig_sgl[i].offset + orig_sgl[i].length <= PAGE_SIZE); */ | 557 | /* ASSERT(orig_sgl[i].offset + orig_sgl[i].length <= PAGE_SIZE); */ |
558 | 558 | ||
559 | if (j == 0) | 559 | if (bounce_addr == 0) |
560 | bounce_addr = (unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])), KM_IRQ0); | 560 | bounce_addr = (unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])), KM_IRQ0); |
561 | 561 | ||
562 | while (destlen) { | 562 | while (destlen) { |
@@ -615,6 +615,7 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd, | |||
615 | unsigned int request_size = 0; | 615 | unsigned int request_size = 0; |
616 | int i; | 616 | int i; |
617 | struct scatterlist *sgl; | 617 | struct scatterlist *sgl; |
618 | unsigned int sg_count = 0; | ||
618 | 619 | ||
619 | DPRINT_DBG(STORVSC_DRV, "scmnd %p dir %d, use_sg %d buf %p len %d " | 620 | DPRINT_DBG(STORVSC_DRV, "scmnd %p dir %d, use_sg %d buf %p len %d " |
620 | "queue depth %d tagged %d", scmnd, scmnd->sc_data_direction, | 621 | "queue depth %d tagged %d", scmnd, scmnd->sc_data_direction, |
@@ -697,6 +698,7 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd, | |||
697 | request->DataBuffer.Length = scsi_bufflen(scmnd); | 698 | request->DataBuffer.Length = scsi_bufflen(scmnd); |
698 | if (scsi_sg_count(scmnd)) { | 699 | if (scsi_sg_count(scmnd)) { |
699 | sgl = (struct scatterlist *)scsi_sglist(scmnd); | 700 | sgl = (struct scatterlist *)scsi_sglist(scmnd); |
701 | sg_count = scsi_sg_count(scmnd); | ||
700 | 702 | ||
701 | /* check if we need to bounce the sgl */ | 703 | /* check if we need to bounce the sgl */ |
702 | if (do_bounce_buffer(sgl, scsi_sg_count(scmnd)) != -1) { | 704 | if (do_bounce_buffer(sgl, scsi_sg_count(scmnd)) != -1) { |
@@ -731,15 +733,16 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd, | |||
731 | scsi_sg_count(scmnd)); | 733 | scsi_sg_count(scmnd)); |
732 | 734 | ||
733 | sgl = cmd_request->bounce_sgl; | 735 | sgl = cmd_request->bounce_sgl; |
736 | sg_count = cmd_request->bounce_sgl_count; | ||
734 | } | 737 | } |
735 | 738 | ||
736 | request->DataBuffer.Offset = sgl[0].offset; | 739 | request->DataBuffer.Offset = sgl[0].offset; |
737 | 740 | ||
738 | for (i = 0; i < scsi_sg_count(scmnd); i++) { | 741 | for (i = 0; i < sg_count; i++) { |
739 | DPRINT_DBG(STORVSC_DRV, "sgl[%d] len %d offset %d\n", | 742 | DPRINT_DBG(STORVSC_DRV, "sgl[%d] len %d offset %d\n", |
740 | i, sgl[i].length, sgl[i].offset); | 743 | i, sgl[i].length, sgl[i].offset); |
741 | request->DataBuffer.PfnArray[i] = | 744 | request->DataBuffer.PfnArray[i] = |
742 | page_to_pfn(sg_page((&sgl[i]))); | 745 | page_to_pfn(sg_page((&sgl[i]))); |
743 | } | 746 | } |
744 | } else if (scsi_sglist(scmnd)) { | 747 | } else if (scsi_sglist(scmnd)) { |
745 | /* ASSERT(scsi_bufflen(scmnd) <= PAGE_SIZE); */ | 748 | /* ASSERT(scsi_bufflen(scmnd) <= PAGE_SIZE); */ |
diff --git a/drivers/staging/octeon/Kconfig b/drivers/staging/octeon/Kconfig index 638ad6b3589..9493128e5fd 100644 --- a/drivers/staging/octeon/Kconfig +++ b/drivers/staging/octeon/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config OCTEON_ETHERNET | 1 | config OCTEON_ETHERNET |
2 | tristate "Cavium Networks Octeon Ethernet support" | 2 | tristate "Cavium Networks Octeon Ethernet support" |
3 | depends on CPU_CAVIUM_OCTEON | 3 | depends on CPU_CAVIUM_OCTEON && NETDEVICES |
4 | select PHYLIB | 4 | select PHYLIB |
5 | select MDIO_OCTEON | 5 | select MDIO_OCTEON |
6 | help | 6 | help |
diff --git a/drivers/staging/rt2860/usb_main_dev.c b/drivers/staging/rt2860/usb_main_dev.c index a0fe31de0a6..ebf9074a908 100644 --- a/drivers/staging/rt2860/usb_main_dev.c +++ b/drivers/staging/rt2860/usb_main_dev.c | |||
@@ -44,6 +44,7 @@ struct usb_device_id rtusb_usb_id[] = { | |||
44 | {USB_DEVICE(0x07B8, 0x2870)}, /* AboCom */ | 44 | {USB_DEVICE(0x07B8, 0x2870)}, /* AboCom */ |
45 | {USB_DEVICE(0x07B8, 0x2770)}, /* AboCom */ | 45 | {USB_DEVICE(0x07B8, 0x2770)}, /* AboCom */ |
46 | {USB_DEVICE(0x0DF6, 0x0039)}, /* Sitecom 2770 */ | 46 | {USB_DEVICE(0x0DF6, 0x0039)}, /* Sitecom 2770 */ |
47 | {USB_DEVICE(0x0DF6, 0x003F)}, /* Sitecom 2770 */ | ||
47 | {USB_DEVICE(0x083A, 0x7512)}, /* Arcadyan 2770 */ | 48 | {USB_DEVICE(0x083A, 0x7512)}, /* Arcadyan 2770 */ |
48 | {USB_DEVICE(0x0789, 0x0162)}, /* Logitec 2870 */ | 49 | {USB_DEVICE(0x0789, 0x0162)}, /* Logitec 2870 */ |
49 | {USB_DEVICE(0x0789, 0x0163)}, /* Logitec 2870 */ | 50 | {USB_DEVICE(0x0789, 0x0163)}, /* Logitec 2870 */ |
@@ -95,7 +96,8 @@ struct usb_device_id rtusb_usb_id[] = { | |||
95 | {USB_DEVICE(0x050d, 0x815c)}, | 96 | {USB_DEVICE(0x050d, 0x815c)}, |
96 | {USB_DEVICE(0x1482, 0x3C09)}, /* Abocom */ | 97 | {USB_DEVICE(0x1482, 0x3C09)}, /* Abocom */ |
97 | {USB_DEVICE(0x14B2, 0x3C09)}, /* Alpha */ | 98 | {USB_DEVICE(0x14B2, 0x3C09)}, /* Alpha */ |
98 | {USB_DEVICE(0x04E8, 0x2018)}, /* samsung */ | 99 | {USB_DEVICE(0x04E8, 0x2018)}, /* samsung linkstick2 */ |
100 | {USB_DEVICE(0x1690, 0x0740)}, /* Askey */ | ||
99 | {USB_DEVICE(0x5A57, 0x0280)}, /* Zinwell */ | 101 | {USB_DEVICE(0x5A57, 0x0280)}, /* Zinwell */ |
100 | {USB_DEVICE(0x5A57, 0x0282)}, /* Zinwell */ | 102 | {USB_DEVICE(0x5A57, 0x0282)}, /* Zinwell */ |
101 | {USB_DEVICE(0x7392, 0x7718)}, | 103 | {USB_DEVICE(0x7392, 0x7718)}, |
@@ -105,21 +107,34 @@ struct usb_device_id rtusb_usb_id[] = { | |||
105 | {USB_DEVICE(0x1737, 0x0071)}, /* Linksys WUSB600N */ | 107 | {USB_DEVICE(0x1737, 0x0071)}, /* Linksys WUSB600N */ |
106 | {USB_DEVICE(0x0411, 0x00e8)}, /* Buffalo WLI-UC-G300N */ | 108 | {USB_DEVICE(0x0411, 0x00e8)}, /* Buffalo WLI-UC-G300N */ |
107 | {USB_DEVICE(0x050d, 0x815c)}, /* Belkin F5D8053 */ | 109 | {USB_DEVICE(0x050d, 0x815c)}, /* Belkin F5D8053 */ |
110 | {USB_DEVICE(0x100D, 0x9031)}, /* Motorola 2770 */ | ||
108 | #endif /* RT2870 // */ | 111 | #endif /* RT2870 // */ |
109 | #ifdef RT3070 | 112 | #ifdef RT3070 |
110 | {USB_DEVICE(0x148F, 0x3070)}, /* Ralink 3070 */ | 113 | {USB_DEVICE(0x148F, 0x3070)}, /* Ralink 3070 */ |
111 | {USB_DEVICE(0x148F, 0x3071)}, /* Ralink 3071 */ | 114 | {USB_DEVICE(0x148F, 0x3071)}, /* Ralink 3071 */ |
112 | {USB_DEVICE(0x148F, 0x3072)}, /* Ralink 3072 */ | 115 | {USB_DEVICE(0x148F, 0x3072)}, /* Ralink 3072 */ |
113 | {USB_DEVICE(0x0DB0, 0x3820)}, /* Ralink 3070 */ | 116 | {USB_DEVICE(0x0DB0, 0x3820)}, /* Ralink 3070 */ |
117 | {USB_DEVICE(0x0DB0, 0x871C)}, /* Ralink 3070 */ | ||
118 | {USB_DEVICE(0x0DB0, 0x822C)}, /* Ralink 3070 */ | ||
119 | {USB_DEVICE(0x0DB0, 0x871B)}, /* Ralink 3070 */ | ||
120 | {USB_DEVICE(0x0DB0, 0x822B)}, /* Ralink 3070 */ | ||
114 | {USB_DEVICE(0x0DF6, 0x003E)}, /* Sitecom 3070 */ | 121 | {USB_DEVICE(0x0DF6, 0x003E)}, /* Sitecom 3070 */ |
115 | {USB_DEVICE(0x0DF6, 0x0042)}, /* Sitecom 3072 */ | 122 | {USB_DEVICE(0x0DF6, 0x0042)}, /* Sitecom 3072 */ |
123 | {USB_DEVICE(0x0DF6, 0x0048)}, /* Sitecom 3070 */ | ||
124 | {USB_DEVICE(0x0DF6, 0x0047)}, /* Sitecom 3071 */ | ||
116 | {USB_DEVICE(0x14B2, 0x3C12)}, /* AL 3070 */ | 125 | {USB_DEVICE(0x14B2, 0x3C12)}, /* AL 3070 */ |
117 | {USB_DEVICE(0x18C5, 0x0012)}, /* Corega 3070 */ | 126 | {USB_DEVICE(0x18C5, 0x0012)}, /* Corega 3070 */ |
118 | {USB_DEVICE(0x083A, 0x7511)}, /* Arcadyan 3070 */ | 127 | {USB_DEVICE(0x083A, 0x7511)}, /* Arcadyan 3070 */ |
128 | {USB_DEVICE(0x083A, 0xA701)}, /* SMC 3070 */ | ||
129 | {USB_DEVICE(0x083A, 0xA702)}, /* SMC 3072 */ | ||
119 | {USB_DEVICE(0x1740, 0x9703)}, /* EnGenius 3070 */ | 130 | {USB_DEVICE(0x1740, 0x9703)}, /* EnGenius 3070 */ |
120 | {USB_DEVICE(0x1740, 0x9705)}, /* EnGenius 3071 */ | 131 | {USB_DEVICE(0x1740, 0x9705)}, /* EnGenius 3071 */ |
121 | {USB_DEVICE(0x1740, 0x9706)}, /* EnGenius 3072 */ | 132 | {USB_DEVICE(0x1740, 0x9706)}, /* EnGenius 3072 */ |
133 | {USB_DEVICE(0x1740, 0x9707)}, /* EnGenius 3070 */ | ||
134 | {USB_DEVICE(0x1740, 0x9708)}, /* EnGenius 3071 */ | ||
135 | {USB_DEVICE(0x1740, 0x9709)}, /* EnGenius 3072 */ | ||
122 | {USB_DEVICE(0x13D3, 0x3273)}, /* AzureWave 3070 */ | 136 | {USB_DEVICE(0x13D3, 0x3273)}, /* AzureWave 3070 */ |
137 | {USB_DEVICE(0x13D3, 0x3305)}, /* AzureWave 3070*/ | ||
123 | {USB_DEVICE(0x1044, 0x800D)}, /* Gigabyte GN-WB32L 3070 */ | 138 | {USB_DEVICE(0x1044, 0x800D)}, /* Gigabyte GN-WB32L 3070 */ |
124 | {USB_DEVICE(0x2019, 0xAB25)}, /* Planex Communications, Inc. RT3070 */ | 139 | {USB_DEVICE(0x2019, 0xAB25)}, /* Planex Communications, Inc. RT3070 */ |
125 | {USB_DEVICE(0x07B8, 0x3070)}, /* AboCom 3070 */ | 140 | {USB_DEVICE(0x07B8, 0x3070)}, /* AboCom 3070 */ |
@@ -132,14 +147,36 @@ struct usb_device_id rtusb_usb_id[] = { | |||
132 | {USB_DEVICE(0x07D1, 0x3C0D)}, /* D-Link 3070 */ | 147 | {USB_DEVICE(0x07D1, 0x3C0D)}, /* D-Link 3070 */ |
133 | {USB_DEVICE(0x07D1, 0x3C0E)}, /* D-Link 3070 */ | 148 | {USB_DEVICE(0x07D1, 0x3C0E)}, /* D-Link 3070 */ |
134 | {USB_DEVICE(0x07D1, 0x3C0F)}, /* D-Link 3070 */ | 149 | {USB_DEVICE(0x07D1, 0x3C0F)}, /* D-Link 3070 */ |
150 | {USB_DEVICE(0x07D1, 0x3C16)}, /* D-Link 3070 */ | ||
151 | {USB_DEVICE(0x07D1, 0x3C17)}, /* D-Link 8070 */ | ||
135 | {USB_DEVICE(0x1D4D, 0x000C)}, /* Pegatron Corporation 3070 */ | 152 | {USB_DEVICE(0x1D4D, 0x000C)}, /* Pegatron Corporation 3070 */ |
136 | {USB_DEVICE(0x1D4D, 0x000E)}, /* Pegatron Corporation 3070 */ | 153 | {USB_DEVICE(0x1D4D, 0x000E)}, /* Pegatron Corporation 3070 */ |
137 | {USB_DEVICE(0x5A57, 0x5257)}, /* Zinwell 3070 */ | 154 | {USB_DEVICE(0x5A57, 0x5257)}, /* Zinwell 3070 */ |
138 | {USB_DEVICE(0x5A57, 0x0283)}, /* Zinwell 3072 */ | 155 | {USB_DEVICE(0x5A57, 0x0283)}, /* Zinwell 3072 */ |
139 | {USB_DEVICE(0x04BB, 0x0945)}, /* I-O DATA 3072 */ | 156 | {USB_DEVICE(0x04BB, 0x0945)}, /* I-O DATA 3072 */ |
157 | {USB_DEVICE(0x04BB, 0x0947)}, /* I-O DATA 3070 */ | ||
158 | {USB_DEVICE(0x04BB, 0x0948)}, /* I-O DATA 3072 */ | ||
140 | {USB_DEVICE(0x203D, 0x1480)}, /* Encore 3070 */ | 159 | {USB_DEVICE(0x203D, 0x1480)}, /* Encore 3070 */ |
160 | {USB_DEVICE(0x20B8, 0x8888)}, /* PARA INDUSTRIAL 3070 */ | ||
161 | {USB_DEVICE(0x0B05, 0x1784)}, /* Asus 3072 */ | ||
162 | {USB_DEVICE(0x203D, 0x14A9)}, /* Encore 3070*/ | ||
163 | {USB_DEVICE(0x0DB0, 0x899A)}, /* MSI 3070*/ | ||
164 | {USB_DEVICE(0x0DB0, 0x3870)}, /* MSI 3070*/ | ||
165 | {USB_DEVICE(0x0DB0, 0x870A)}, /* MSI 3070*/ | ||
166 | {USB_DEVICE(0x0DB0, 0x6899)}, /* MSI 3070 */ | ||
167 | {USB_DEVICE(0x0DB0, 0x3822)}, /* MSI 3070 */ | ||
168 | {USB_DEVICE(0x0DB0, 0x3871)}, /* MSI 3070 */ | ||
169 | {USB_DEVICE(0x0DB0, 0x871A)}, /* MSI 3070 */ | ||
170 | {USB_DEVICE(0x0DB0, 0x822A)}, /* MSI 3070 */ | ||
171 | {USB_DEVICE(0x0DB0, 0x3821)}, /* Ralink 3070 */ | ||
172 | {USB_DEVICE(0x0DB0, 0x821A)}, /* Ralink 3070 */ | ||
173 | {USB_DEVICE(0x083A, 0xA703)}, /* IO-MAGIC */ | ||
174 | {USB_DEVICE(0x13D3, 0x3307)}, /* Azurewave */ | ||
175 | {USB_DEVICE(0x13D3, 0x3321)}, /* Azurewave */ | ||
176 | {USB_DEVICE(0x07FA, 0x7712)}, /* Edimax */ | ||
177 | {USB_DEVICE(0x0789, 0x0166)}, /* Edimax */ | ||
178 | {USB_DEVICE(0x148F, 0x2070)}, /* Edimax */ | ||
141 | #endif /* RT3070 // */ | 179 | #endif /* RT3070 // */ |
142 | {USB_DEVICE(0x0DF6, 0x003F)}, /* Sitecom WL-608 */ | ||
143 | {USB_DEVICE(0x1737, 0x0077)}, /* Linksys WUSB54GC-EU v3 */ | 180 | {USB_DEVICE(0x1737, 0x0077)}, /* Linksys WUSB54GC-EU v3 */ |
144 | {USB_DEVICE(0x2001, 0x3C09)}, /* D-Link */ | 181 | {USB_DEVICE(0x2001, 0x3C09)}, /* D-Link */ |
145 | {USB_DEVICE(0x2001, 0x3C0A)}, /* D-Link 3072 */ | 182 | {USB_DEVICE(0x2001, 0x3C0A)}, /* D-Link 3072 */ |
diff --git a/drivers/staging/sep/Kconfig b/drivers/staging/sep/Kconfig deleted file mode 100644 index 0a9c39c7f2b..00000000000 --- a/drivers/staging/sep/Kconfig +++ /dev/null | |||
@@ -1,10 +0,0 @@ | |||
1 | config DX_SEP | ||
2 | tristate "Discretix SEP driver" | ||
3 | # depends on MRST | ||
4 | depends on RAR_REGISTER && PCI | ||
5 | default y | ||
6 | help | ||
7 | Discretix SEP driver | ||
8 | |||
9 | If unsure say M. The compiled module will be | ||
10 | called sep_driver.ko | ||
diff --git a/drivers/staging/sep/Makefile b/drivers/staging/sep/Makefile deleted file mode 100644 index 628d5f91941..00000000000 --- a/drivers/staging/sep/Makefile +++ /dev/null | |||
@@ -1,2 +0,0 @@ | |||
1 | obj-$(CONFIG_DX_SEP) := sep_driver.o | ||
2 | |||
diff --git a/drivers/staging/sep/TODO b/drivers/staging/sep/TODO deleted file mode 100644 index ff0e931dab6..00000000000 --- a/drivers/staging/sep/TODO +++ /dev/null | |||
@@ -1,8 +0,0 @@ | |||
1 | Todo's so far (from Alan Cox) | ||
2 | - Fix firmware loading | ||
3 | - Get firmware into firmware git tree | ||
4 | - Review and tidy each algorithm function | ||
5 | - Check whether it can be plugged into any of the kernel crypto API | ||
6 | interfaces | ||
7 | - Do something about the magic shared memory interface and replace it | ||
8 | with something saner (in Linux terms) | ||
diff --git a/drivers/staging/sep/sep_dev.h b/drivers/staging/sep/sep_dev.h deleted file mode 100644 index 9200524bb64..00000000000 --- a/drivers/staging/sep/sep_dev.h +++ /dev/null | |||
@@ -1,110 +0,0 @@ | |||
1 | #ifndef __SEP_DEV_H__ | ||
2 | #define __SEP_DEV_H__ | ||
3 | |||
4 | /* | ||
5 | * | ||
6 | * sep_dev.h - Security Processor Device Structures | ||
7 | * | ||
8 | * Copyright(c) 2009 Intel Corporation. All rights reserved. | ||
9 | * Copyright(c) 2009 Discretix. All rights reserved. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify it | ||
12 | * under the terms of the GNU General Public License as published by the Free | ||
13 | * Software Foundation; either version 2 of the License, or (at your option) | ||
14 | * any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
17 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
18 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
19 | * more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License along with | ||
22 | * this program; if not, write to the Free Software Foundation, Inc., 59 | ||
23 | * Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
24 | * | ||
25 | * CONTACTS: | ||
26 | * | ||
27 | * Alan Cox alan@linux.intel.com | ||
28 | * | ||
29 | */ | ||
30 | |||
31 | struct sep_device { | ||
32 | /* pointer to pci dev */ | ||
33 | struct pci_dev *pdev; | ||
34 | |||
35 | unsigned long in_use; | ||
36 | |||
37 | /* address of the shared memory allocated during init for SEP driver | ||
38 | (coherent alloc) */ | ||
39 | void *shared_addr; | ||
40 | /* the physical address of the shared area */ | ||
41 | dma_addr_t shared_bus; | ||
42 | |||
43 | /* restricted access region (coherent alloc) */ | ||
44 | dma_addr_t rar_bus; | ||
45 | void *rar_addr; | ||
46 | /* firmware regions: cache is at rar_addr */ | ||
47 | unsigned long cache_size; | ||
48 | |||
49 | /* follows the cache */ | ||
50 | dma_addr_t resident_bus; | ||
51 | unsigned long resident_size; | ||
52 | void *resident_addr; | ||
53 | |||
54 | /* start address of the access to the SEP registers from driver */ | ||
55 | void __iomem *reg_addr; | ||
56 | /* transaction counter that coordinates the transactions between SEP and HOST */ | ||
57 | unsigned long send_ct; | ||
58 | /* counter for the messages from sep */ | ||
59 | unsigned long reply_ct; | ||
60 | /* counter for the number of bytes allocated in the pool for the current | ||
61 | transaction */ | ||
62 | unsigned long data_pool_bytes_allocated; | ||
63 | |||
64 | /* array of pointers to the pages that represent input data for the synchronic | ||
65 | DMA action */ | ||
66 | struct page **in_page_array; | ||
67 | |||
68 | /* array of pointers to the pages that represent out data for the synchronic | ||
69 | DMA action */ | ||
70 | struct page **out_page_array; | ||
71 | |||
72 | /* number of pages in the sep_in_page_array */ | ||
73 | unsigned long in_num_pages; | ||
74 | |||
75 | /* number of pages in the sep_out_page_array */ | ||
76 | unsigned long out_num_pages; | ||
77 | |||
78 | /* global data for every flow */ | ||
79 | struct sep_flow_context_t flows[SEP_DRIVER_NUM_FLOWS]; | ||
80 | |||
81 | /* pointer to the workqueue that handles the flow done interrupts */ | ||
82 | struct workqueue_struct *flow_wq; | ||
83 | |||
84 | }; | ||
85 | |||
86 | static struct sep_device *sep_dev; | ||
87 | |||
88 | static inline void sep_write_reg(struct sep_device *dev, int reg, u32 value) | ||
89 | { | ||
90 | void __iomem *addr = dev->reg_addr + reg; | ||
91 | writel(value, addr); | ||
92 | } | ||
93 | |||
94 | static inline u32 sep_read_reg(struct sep_device *dev, int reg) | ||
95 | { | ||
96 | void __iomem *addr = dev->reg_addr + reg; | ||
97 | return readl(addr); | ||
98 | } | ||
99 | |||
100 | /* wait for SRAM write complete(indirect write */ | ||
101 | static inline void sep_wait_sram_write(struct sep_device *dev) | ||
102 | { | ||
103 | u32 reg_val; | ||
104 | do | ||
105 | reg_val = sep_read_reg(dev, HW_SRAM_DATA_READY_REG_ADDR); | ||
106 | while (!(reg_val & 1)); | ||
107 | } | ||
108 | |||
109 | |||
110 | #endif | ||
diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c deleted file mode 100644 index ecbde3467b1..00000000000 --- a/drivers/staging/sep/sep_driver.c +++ /dev/null | |||
@@ -1,2742 +0,0 @@ | |||
1 | /* | ||
2 | * | ||
3 | * sep_driver.c - Security Processor Driver main group of functions | ||
4 | * | ||
5 | * Copyright(c) 2009 Intel Corporation. All rights reserved. | ||
6 | * Copyright(c) 2009 Discretix. All rights reserved. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the Free | ||
10 | * Software Foundation; either version 2 of the License, or (at your option) | ||
11 | * any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
16 | * more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License along with | ||
19 | * this program; if not, write to the Free Software Foundation, Inc., 59 | ||
20 | * Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
21 | * | ||
22 | * CONTACTS: | ||
23 | * | ||
24 | * Mark Allyn mark.a.allyn@intel.com | ||
25 | * | ||
26 | * CHANGES: | ||
27 | * | ||
28 | * 2009.06.26 Initial publish | ||
29 | * | ||
30 | */ | ||
31 | |||
32 | #include <linux/init.h> | ||
33 | #include <linux/module.h> | ||
34 | #include <linux/fs.h> | ||
35 | #include <linux/cdev.h> | ||
36 | #include <linux/kdev_t.h> | ||
37 | #include <linux/mutex.h> | ||
38 | #include <linux/sched.h> | ||
39 | #include <linux/mm.h> | ||
40 | #include <linux/poll.h> | ||
41 | #include <linux/wait.h> | ||
42 | #include <linux/pci.h> | ||
43 | #include <linux/firmware.h> | ||
44 | #include <linux/slab.h> | ||
45 | #include <asm/ioctl.h> | ||
46 | #include <linux/ioport.h> | ||
47 | #include <asm/io.h> | ||
48 | #include <linux/interrupt.h> | ||
49 | #include <linux/pagemap.h> | ||
50 | #include <asm/cacheflush.h> | ||
51 | #include "sep_driver_hw_defs.h" | ||
52 | #include "sep_driver_config.h" | ||
53 | #include "sep_driver_api.h" | ||
54 | #include "sep_dev.h" | ||
55 | |||
56 | #if SEP_DRIVER_ARM_DEBUG_MODE | ||
57 | |||
58 | #define CRYS_SEP_ROM_length 0x4000 | ||
59 | #define CRYS_SEP_ROM_start_address 0x8000C000UL | ||
60 | #define CRYS_SEP_ROM_start_address_offset 0xC000UL | ||
61 | #define SEP_ROM_BANK_register 0x80008420UL | ||
62 | #define SEP_ROM_BANK_register_offset 0x8420UL | ||
63 | #define SEP_RAR_IO_MEM_REGION_START_ADDRESS 0x82000000 | ||
64 | |||
65 | /* | ||
66 | * THESE 2 definitions are specific to the board - must be | ||
67 | * defined during integration | ||
68 | */ | ||
69 | #define SEP_RAR_IO_MEM_REGION_START_ADDRESS 0xFF0D0000 | ||
70 | |||
71 | /* 2M size */ | ||
72 | |||
73 | static void sep_load_rom_code(struct sep_device *sep) | ||
74 | { | ||
75 | /* Index variables */ | ||
76 | unsigned long i, k, j; | ||
77 | u32 reg; | ||
78 | u32 error; | ||
79 | u32 warning; | ||
80 | |||
81 | /* Loading ROM from SEP_ROM_image.h file */ | ||
82 | k = sizeof(CRYS_SEP_ROM); | ||
83 | |||
84 | edbg("SEP Driver: DX_CC_TST_SepRomLoader start\n"); | ||
85 | |||
86 | edbg("SEP Driver: k is %lu\n", k); | ||
87 | edbg("SEP Driver: sep->reg_addr is %p\n", sep->reg_addr); | ||
88 | edbg("SEP Driver: CRYS_SEP_ROM_start_address_offset is %p\n", CRYS_SEP_ROM_start_address_offset); | ||
89 | |||
90 | for (i = 0; i < 4; i++) { | ||
91 | /* write bank */ | ||
92 | sep_write_reg(sep, SEP_ROM_BANK_register_offset, i); | ||
93 | |||
94 | for (j = 0; j < CRYS_SEP_ROM_length / 4; j++) { | ||
95 | sep_write_reg(sep, CRYS_SEP_ROM_start_address_offset + 4 * j, CRYS_SEP_ROM[i * 0x1000 + j]); | ||
96 | |||
97 | k = k - 4; | ||
98 | |||
99 | if (k == 0) { | ||
100 | j = CRYS_SEP_ROM_length; | ||
101 | i = 4; | ||
102 | } | ||
103 | } | ||
104 | } | ||
105 | |||
106 | /* reset the SEP */ | ||
107 | sep_write_reg(sep, HW_HOST_SEP_SW_RST_REG_ADDR, 0x1); | ||
108 | |||
109 | /* poll for SEP ROM boot finish */ | ||
110 | do | ||
111 | reg = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); | ||
112 | while (!reg); | ||
113 | |||
114 | edbg("SEP Driver: ROM polling ended\n"); | ||
115 | |||
116 | switch (reg) { | ||
117 | case 0x1: | ||
118 | /* fatal error - read erro status from GPRO */ | ||
119 | error = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR); | ||
120 | edbg("SEP Driver: ROM polling case 1\n"); | ||
121 | break; | ||
122 | case 0x4: | ||
123 | /* Cold boot ended successfully */ | ||
124 | case 0x8: | ||
125 | /* Warmboot ended successfully */ | ||
126 | case 0x10: | ||
127 | /* ColdWarm boot ended successfully */ | ||
128 | error = 0; | ||
129 | case 0x2: | ||
130 | /* Boot First Phase ended */ | ||
131 | warning = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR); | ||
132 | case 0x20: | ||
133 | edbg("SEP Driver: ROM polling case %d\n", reg); | ||
134 | break; | ||
135 | } | ||
136 | |||
137 | } | ||
138 | |||
139 | #else | ||
140 | static void sep_load_rom_code(struct sep_device *sep) { } | ||
141 | #endif /* SEP_DRIVER_ARM_DEBUG_MODE */ | ||
142 | |||
143 | |||
144 | |||
145 | /*---------------------------------------- | ||
146 | DEFINES | ||
147 | -----------------------------------------*/ | ||
148 | |||
149 | #define BASE_ADDRESS_FOR_SYSTEM 0xfffc0000 | ||
150 | #define SEP_RAR_IO_MEM_REGION_SIZE 0x40000 | ||
151 | |||
152 | /*-------------------------------------------- | ||
153 | GLOBAL variables | ||
154 | --------------------------------------------*/ | ||
155 | |||
156 | /* debug messages level */ | ||
157 | static int debug; | ||
158 | module_param(debug, int , 0); | ||
159 | MODULE_PARM_DESC(debug, "Flag to enable SEP debug messages"); | ||
160 | |||
161 | /* Keep this a single static object for now to keep the conversion easy */ | ||
162 | |||
163 | static struct sep_device sep_instance; | ||
164 | static struct sep_device *sep_dev = &sep_instance; | ||
165 | |||
166 | /* | ||
167 | mutex for the access to the internals of the sep driver | ||
168 | */ | ||
169 | static DEFINE_MUTEX(sep_mutex); | ||
170 | |||
171 | |||
172 | /* wait queue head (event) of the driver */ | ||
173 | static DECLARE_WAIT_QUEUE_HEAD(sep_event); | ||
174 | |||
175 | /** | ||
176 | * sep_load_firmware - copy firmware cache/resident | ||
177 | * @sep: device we are loading | ||
178 | * | ||
179 | * This functions copies the cache and resident from their source | ||
180 | * location into destination shared memory. | ||
181 | */ | ||
182 | |||
183 | static int sep_load_firmware(struct sep_device *sep) | ||
184 | { | ||
185 | const struct firmware *fw; | ||
186 | char *cache_name = "sep/cache.image.bin"; | ||
187 | char *res_name = "sep/resident.image.bin"; | ||
188 | int error; | ||
189 | |||
190 | edbg("SEP Driver:rar_virtual is %p\n", sep->rar_addr); | ||
191 | edbg("SEP Driver:rar_bus is %08llx\n", (unsigned long long)sep->rar_bus); | ||
192 | |||
193 | /* load cache */ | ||
194 | error = request_firmware(&fw, cache_name, &sep->pdev->dev); | ||
195 | if (error) { | ||
196 | edbg("SEP Driver:cant request cache fw\n"); | ||
197 | return error; | ||
198 | } | ||
199 | edbg("SEP Driver:cache %08Zx@%p\n", fw->size, (void *) fw->data); | ||
200 | |||
201 | memcpy(sep->rar_addr, (void *)fw->data, fw->size); | ||
202 | sep->cache_size = fw->size; | ||
203 | release_firmware(fw); | ||
204 | |||
205 | sep->resident_bus = sep->rar_bus + sep->cache_size; | ||
206 | sep->resident_addr = sep->rar_addr + sep->cache_size; | ||
207 | |||
208 | /* load resident */ | ||
209 | error = request_firmware(&fw, res_name, &sep->pdev->dev); | ||
210 | if (error) { | ||
211 | edbg("SEP Driver:cant request res fw\n"); | ||
212 | return error; | ||
213 | } | ||
214 | edbg("sep: res %08Zx@%p\n", fw->size, (void *)fw->data); | ||
215 | |||
216 | memcpy(sep->resident_addr, (void *) fw->data, fw->size); | ||
217 | sep->resident_size = fw->size; | ||
218 | release_firmware(fw); | ||
219 | |||
220 | edbg("sep: resident v %p b %08llx cache v %p b %08llx\n", | ||
221 | sep->resident_addr, (unsigned long long)sep->resident_bus, | ||
222 | sep->rar_addr, (unsigned long long)sep->rar_bus); | ||
223 | return 0; | ||
224 | } | ||
225 | |||
226 | MODULE_FIRMWARE("sep/cache.image.bin"); | ||
227 | MODULE_FIRMWARE("sep/resident.image.bin"); | ||
228 | |||
229 | /** | ||
230 | * sep_map_and_alloc_shared_area - allocate shared block | ||
231 | * @sep: security processor | ||
232 | * @size: size of shared area | ||
233 | * | ||
234 | * Allocate a shared buffer in host memory that can be used by both the | ||
235 | * kernel and also the hardware interface via DMA. | ||
236 | */ | ||
237 | |||
238 | static int sep_map_and_alloc_shared_area(struct sep_device *sep, | ||
239 | unsigned long size) | ||
240 | { | ||
241 | /* shared_addr = ioremap_nocache(0xda00000,shared_area_size); */ | ||
242 | sep->shared_addr = dma_alloc_coherent(&sep->pdev->dev, size, | ||
243 | &sep->shared_bus, GFP_KERNEL); | ||
244 | |||
245 | if (!sep->shared_addr) { | ||
246 | edbg("sep_driver :shared memory dma_alloc_coherent failed\n"); | ||
247 | return -ENOMEM; | ||
248 | } | ||
249 | /* set the bus address of the shared area */ | ||
250 | edbg("sep: shared_addr %ld bytes @%p (bus %08llx)\n", | ||
251 | size, sep->shared_addr, (unsigned long long)sep->shared_bus); | ||
252 | return 0; | ||
253 | } | ||
254 | |||
255 | /** | ||
256 | * sep_unmap_and_free_shared_area - free shared block | ||
257 | * @sep: security processor | ||
258 | * | ||
259 | * Free the shared area allocated to the security processor. The | ||
260 | * processor must have finished with this and any final posted | ||
261 | * writes cleared before we do so. | ||
262 | */ | ||
263 | static void sep_unmap_and_free_shared_area(struct sep_device *sep, int size) | ||
264 | { | ||
265 | dma_free_coherent(&sep->pdev->dev, size, | ||
266 | sep->shared_addr, sep->shared_bus); | ||
267 | } | ||
268 | |||
269 | /** | ||
270 | * sep_shared_virt_to_bus - convert bus/virt addresses | ||
271 | * | ||
272 | * Returns the bus address inside the shared area according | ||
273 | * to the virtual address. | ||
274 | */ | ||
275 | |||
276 | static dma_addr_t sep_shared_virt_to_bus(struct sep_device *sep, | ||
277 | void *virt_address) | ||
278 | { | ||
279 | dma_addr_t pa = sep->shared_bus + (virt_address - sep->shared_addr); | ||
280 | edbg("sep: virt to bus b %08llx v %p\n", (unsigned long long) pa, | ||
281 | virt_address); | ||
282 | return pa; | ||
283 | } | ||
284 | |||
285 | /** | ||
286 | * sep_shared_bus_to_virt - convert bus/virt addresses | ||
287 | * | ||
288 | * Returns virtual address inside the shared area according | ||
289 | * to the bus address. | ||
290 | */ | ||
291 | |||
292 | static void *sep_shared_bus_to_virt(struct sep_device *sep, | ||
293 | dma_addr_t bus_address) | ||
294 | { | ||
295 | return sep->shared_addr + (bus_address - sep->shared_bus); | ||
296 | } | ||
297 | |||
298 | |||
299 | /** | ||
300 | * sep_try_open - attempt to open a SEP device | ||
301 | * @sep: device to attempt to open | ||
302 | * | ||
303 | * Atomically attempt to get ownership of a SEP device. | ||
304 | * Returns 1 if the device was opened, 0 on failure. | ||
305 | */ | ||
306 | |||
307 | static int sep_try_open(struct sep_device *sep) | ||
308 | { | ||
309 | if (!test_and_set_bit(0, &sep->in_use)) | ||
310 | return 1; | ||
311 | return 0; | ||
312 | } | ||
313 | |||
314 | /** | ||
315 | * sep_open - device open method | ||
316 | * @inode: inode of sep device | ||
317 | * @filp: file handle to sep device | ||
318 | * | ||
319 | * Open method for the SEP device. Called when userspace opens | ||
320 | * the SEP device node. Must also release the memory data pool | ||
321 | * allocations. | ||
322 | * | ||
323 | * Returns zero on success otherwise an error code. | ||
324 | */ | ||
325 | |||
326 | static int sep_open(struct inode *inode, struct file *filp) | ||
327 | { | ||
328 | if (sep_dev == NULL) | ||
329 | return -ENODEV; | ||
330 | |||
331 | /* check the blocking mode */ | ||
332 | if (filp->f_flags & O_NDELAY) { | ||
333 | if (sep_try_open(sep_dev) == 0) | ||
334 | return -EAGAIN; | ||
335 | } else | ||
336 | if (wait_event_interruptible(sep_event, sep_try_open(sep_dev)) < 0) | ||
337 | return -EINTR; | ||
338 | |||
339 | /* Bind to the device, we only have one which makes it easy */ | ||
340 | filp->private_data = sep_dev; | ||
341 | /* release data pool allocations */ | ||
342 | sep_dev->data_pool_bytes_allocated = 0; | ||
343 | return 0; | ||
344 | } | ||
345 | |||
346 | |||
347 | /** | ||
348 | * sep_release - close a SEP device | ||
349 | * @inode: inode of SEP device | ||
350 | * @filp: file handle being closed | ||
351 | * | ||
352 | * Called on the final close of a SEP device. As the open protects against | ||
353 | * multiple simultaenous opens that means this method is called when the | ||
354 | * final reference to the open handle is dropped. | ||
355 | */ | ||
356 | |||
357 | static int sep_release(struct inode *inode, struct file *filp) | ||
358 | { | ||
359 | struct sep_device *sep = filp->private_data; | ||
360 | #if 0 /*!SEP_DRIVER_POLLING_MODE */ | ||
361 | /* close IMR */ | ||
362 | sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, 0x7FFF); | ||
363 | /* release IRQ line */ | ||
364 | free_irq(SEP_DIRVER_IRQ_NUM, sep); | ||
365 | |||
366 | #endif | ||
367 | /* Ensure any blocked open progresses */ | ||
368 | clear_bit(0, &sep->in_use); | ||
369 | wake_up(&sep_event); | ||
370 | return 0; | ||
371 | } | ||
372 | |||
373 | /*--------------------------------------------------------------- | ||
374 | map function - this functions maps the message shared area | ||
375 | -----------------------------------------------------------------*/ | ||
376 | static int sep_mmap(struct file *filp, struct vm_area_struct *vma) | ||
377 | { | ||
378 | dma_addr_t bus_addr; | ||
379 | struct sep_device *sep = filp->private_data; | ||
380 | |||
381 | dbg("-------->SEP Driver: mmap start\n"); | ||
382 | |||
383 | /* check that the size of the mapped range is as the size of the message | ||
384 | shared area */ | ||
385 | if ((vma->vm_end - vma->vm_start) > SEP_DRIVER_MMMAP_AREA_SIZE) { | ||
386 | edbg("SEP Driver mmap requested size is more than allowed\n"); | ||
387 | printk(KERN_WARNING "SEP Driver mmap requested size is more than allowed\n"); | ||
388 | printk(KERN_WARNING "SEP Driver vma->vm_end is %08lx\n", vma->vm_end); | ||
389 | printk(KERN_WARNING "SEP Driver vma->vm_end is %08lx\n", vma->vm_start); | ||
390 | return -EAGAIN; | ||
391 | } | ||
392 | |||
393 | edbg("SEP Driver:sep->shared_addr is %p\n", sep->shared_addr); | ||
394 | |||
395 | /* get bus address */ | ||
396 | bus_addr = sep->shared_bus; | ||
397 | |||
398 | edbg("SEP Driver: phys_addr is %08llx\n", (unsigned long long)bus_addr); | ||
399 | |||
400 | if (remap_pfn_range(vma, vma->vm_start, bus_addr >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot)) { | ||
401 | edbg("SEP Driver remap_page_range failed\n"); | ||
402 | printk(KERN_WARNING "SEP Driver remap_page_range failed\n"); | ||
403 | return -EAGAIN; | ||
404 | } | ||
405 | |||
406 | dbg("SEP Driver:<-------- mmap end\n"); | ||
407 | |||
408 | return 0; | ||
409 | } | ||
410 | |||
411 | |||
412 | /*----------------------------------------------- | ||
413 | poll function | ||
414 | *----------------------------------------------*/ | ||
415 | static unsigned int sep_poll(struct file *filp, poll_table * wait) | ||
416 | { | ||
417 | unsigned long count; | ||
418 | unsigned int mask = 0; | ||
419 | unsigned long retval = 0; /* flow id */ | ||
420 | struct sep_device *sep = filp->private_data; | ||
421 | |||
422 | dbg("---------->SEP Driver poll: start\n"); | ||
423 | |||
424 | |||
425 | #if SEP_DRIVER_POLLING_MODE | ||
426 | |||
427 | while (sep->send_ct != (retval & 0x7FFFFFFF)) { | ||
428 | retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR); | ||
429 | |||
430 | for (count = 0; count < 10 * 4; count += 4) | ||
431 | edbg("Poll Debug Word %lu of the message is %lu\n", count, *((unsigned long *) (sep->shared_addr + SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES + count))); | ||
432 | } | ||
433 | |||
434 | sep->reply_ct++; | ||
435 | #else | ||
436 | /* add the event to the polling wait table */ | ||
437 | poll_wait(filp, &sep_event, wait); | ||
438 | |||
439 | #endif | ||
440 | |||
441 | edbg("sep->send_ct is %lu\n", sep->send_ct); | ||
442 | edbg("sep->reply_ct is %lu\n", sep->reply_ct); | ||
443 | |||
444 | /* check if the data is ready */ | ||
445 | if (sep->send_ct == sep->reply_ct) { | ||
446 | for (count = 0; count < 12 * 4; count += 4) | ||
447 | edbg("Sep Mesg Word %lu of the message is %lu\n", count, *((unsigned long *) (sep->shared_addr + count))); | ||
448 | |||
449 | for (count = 0; count < 10 * 4; count += 4) | ||
450 | edbg("Debug Data Word %lu of the message is %lu\n", count, *((unsigned long *) (sep->shared_addr + 0x1800 + count))); | ||
451 | |||
452 | retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR); | ||
453 | edbg("retval is %lu\n", retval); | ||
454 | /* check if the this is sep reply or request */ | ||
455 | if (retval >> 31) { | ||
456 | edbg("SEP Driver: sep request in\n"); | ||
457 | /* request */ | ||
458 | mask |= POLLOUT | POLLWRNORM; | ||
459 | } else { | ||
460 | edbg("SEP Driver: sep reply in\n"); | ||
461 | mask |= POLLIN | POLLRDNORM; | ||
462 | } | ||
463 | } | ||
464 | dbg("SEP Driver:<-------- poll exit\n"); | ||
465 | return mask; | ||
466 | } | ||
467 | |||
468 | /** | ||
469 | * sep_time_address - address in SEP memory of time | ||
470 | * @sep: SEP device we want the address from | ||
471 | * | ||
472 | * Return the address of the two dwords in memory used for time | ||
473 | * setting. | ||
474 | */ | ||
475 | |||
476 | static u32 *sep_time_address(struct sep_device *sep) | ||
477 | { | ||
478 | return sep->shared_addr + SEP_DRIVER_SYSTEM_TIME_MEMORY_OFFSET_IN_BYTES; | ||
479 | } | ||
480 | |||
481 | /** | ||
482 | * sep_set_time - set the SEP time | ||
483 | * @sep: the SEP we are setting the time for | ||
484 | * | ||
485 | * Calculates time and sets it at the predefined address. | ||
486 | * Called with the sep mutex held. | ||
487 | */ | ||
488 | static unsigned long sep_set_time(struct sep_device *sep) | ||
489 | { | ||
490 | struct timeval time; | ||
491 | u32 *time_addr; /* address of time as seen by the kernel */ | ||
492 | |||
493 | |||
494 | dbg("sep:sep_set_time start\n"); | ||
495 | |||
496 | do_gettimeofday(&time); | ||
497 | |||
498 | /* set value in the SYSTEM MEMORY offset */ | ||
499 | time_addr = sep_time_address(sep); | ||
500 | |||
501 | time_addr[0] = SEP_TIME_VAL_TOKEN; | ||
502 | time_addr[1] = time.tv_sec; | ||
503 | |||
504 | edbg("SEP Driver:time.tv_sec is %lu\n", time.tv_sec); | ||
505 | edbg("SEP Driver:time_addr is %p\n", time_addr); | ||
506 | edbg("SEP Driver:sep->shared_addr is %p\n", sep->shared_addr); | ||
507 | |||
508 | return time.tv_sec; | ||
509 | } | ||
510 | |||
511 | /** | ||
512 | * sep_dump_message - dump the message that is pending | ||
513 | * @sep: sep device | ||
514 | * | ||
515 | * Dump out the message pending in the shared message area | ||
516 | */ | ||
517 | |||
518 | static void sep_dump_message(struct sep_device *sep) | ||
519 | { | ||
520 | int count; | ||
521 | for (count = 0; count < 12 * 4; count += 4) | ||
522 | edbg("Word %d of the message is %u\n", count, *((u32 *) (sep->shared_addr + count))); | ||
523 | } | ||
524 | |||
525 | /** | ||
526 | * sep_send_command_handler - kick off a command | ||
527 | * @sep: sep being signalled | ||
528 | * | ||
529 | * This function raises interrupt to SEP that signals that is has a new | ||
530 | * command from the host | ||
531 | */ | ||
532 | |||
533 | static void sep_send_command_handler(struct sep_device *sep) | ||
534 | { | ||
535 | dbg("sep:sep_send_command_handler start\n"); | ||
536 | |||
537 | mutex_lock(&sep_mutex); | ||
538 | sep_set_time(sep); | ||
539 | |||
540 | /* FIXME: flush cache */ | ||
541 | flush_cache_all(); | ||
542 | |||
543 | sep_dump_message(sep); | ||
544 | /* update counter */ | ||
545 | sep->send_ct++; | ||
546 | /* send interrupt to SEP */ | ||
547 | sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x2); | ||
548 | dbg("SEP Driver:<-------- sep_send_command_handler end\n"); | ||
549 | mutex_unlock(&sep_mutex); | ||
550 | return; | ||
551 | } | ||
552 | |||
553 | /** | ||
554 | * sep_send_reply_command_handler - kick off a command reply | ||
555 | * @sep: sep being signalled | ||
556 | * | ||
557 | * This function raises interrupt to SEP that signals that is has a new | ||
558 | * command from the host | ||
559 | */ | ||
560 | |||
561 | static void sep_send_reply_command_handler(struct sep_device *sep) | ||
562 | { | ||
563 | dbg("sep:sep_send_reply_command_handler start\n"); | ||
564 | |||
565 | /* flash cache */ | ||
566 | flush_cache_all(); | ||
567 | |||
568 | sep_dump_message(sep); | ||
569 | |||
570 | mutex_lock(&sep_mutex); | ||
571 | sep->send_ct++; /* update counter */ | ||
572 | /* send the interrupt to SEP */ | ||
573 | sep_write_reg(sep, HW_HOST_HOST_SEP_GPR2_REG_ADDR, sep->send_ct); | ||
574 | /* update both counters */ | ||
575 | sep->send_ct++; | ||
576 | sep->reply_ct++; | ||
577 | mutex_unlock(&sep_mutex); | ||
578 | dbg("sep: sep_send_reply_command_handler end\n"); | ||
579 | } | ||
580 | |||
581 | /* | ||
582 | This function handles the allocate data pool memory request | ||
583 | This function returns calculates the bus address of the | ||
584 | allocated memory, and the offset of this area from the mapped address. | ||
585 | Therefore, the FVOs in user space can calculate the exact virtual | ||
586 | address of this allocated memory | ||
587 | */ | ||
588 | static int sep_allocate_data_pool_memory_handler(struct sep_device *sep, | ||
589 | unsigned long arg) | ||
590 | { | ||
591 | int error; | ||
592 | struct sep_driver_alloc_t command_args; | ||
593 | |||
594 | dbg("SEP Driver:--------> sep_allocate_data_pool_memory_handler start\n"); | ||
595 | |||
596 | error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_alloc_t)); | ||
597 | if (error) { | ||
598 | error = -EFAULT; | ||
599 | goto end_function; | ||
600 | } | ||
601 | |||
602 | /* allocate memory */ | ||
603 | if ((sep->data_pool_bytes_allocated + command_args.num_bytes) > SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES) { | ||
604 | error = -ENOMEM; | ||
605 | goto end_function; | ||
606 | } | ||
607 | |||
608 | /* set the virtual and bus address */ | ||
609 | command_args.offset = SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + sep->data_pool_bytes_allocated; | ||
610 | command_args.phys_address = sep->shared_bus + SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + sep->data_pool_bytes_allocated; | ||
611 | |||
612 | /* write the memory back to the user space */ | ||
613 | error = copy_to_user((void *) arg, (void *) &command_args, sizeof(struct sep_driver_alloc_t)); | ||
614 | if (error) { | ||
615 | error = -EFAULT; | ||
616 | goto end_function; | ||
617 | } | ||
618 | |||
619 | /* set the allocation */ | ||
620 | sep->data_pool_bytes_allocated += command_args.num_bytes; | ||
621 | |||
622 | end_function: | ||
623 | dbg("SEP Driver:<-------- sep_allocate_data_pool_memory_handler end\n"); | ||
624 | return error; | ||
625 | } | ||
626 | |||
627 | /* | ||
628 | This function handles write into allocated data pool command | ||
629 | */ | ||
630 | static int sep_write_into_data_pool_handler(struct sep_device *sep, unsigned long arg) | ||
631 | { | ||
632 | int error; | ||
633 | void *virt_address; | ||
634 | unsigned long va; | ||
635 | unsigned long app_in_address; | ||
636 | unsigned long num_bytes; | ||
637 | void *data_pool_area_addr; | ||
638 | |||
639 | dbg("SEP Driver:--------> sep_write_into_data_pool_handler start\n"); | ||
640 | |||
641 | /* get the application address */ | ||
642 | error = get_user(app_in_address, &(((struct sep_driver_write_t *) arg)->app_address)); | ||
643 | if (error) | ||
644 | goto end_function; | ||
645 | |||
646 | /* get the virtual kernel address address */ | ||
647 | error = get_user(va, &(((struct sep_driver_write_t *) arg)->datapool_address)); | ||
648 | if (error) | ||
649 | goto end_function; | ||
650 | virt_address = (void *)va; | ||
651 | |||
652 | /* get the number of bytes */ | ||
653 | error = get_user(num_bytes, &(((struct sep_driver_write_t *) arg)->num_bytes)); | ||
654 | if (error) | ||
655 | goto end_function; | ||
656 | |||
657 | /* calculate the start of the data pool */ | ||
658 | data_pool_area_addr = sep->shared_addr + SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES; | ||
659 | |||
660 | |||
661 | /* check that the range of the virtual kernel address is correct */ | ||
662 | if (virt_address < data_pool_area_addr || virt_address > (data_pool_area_addr + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES)) { | ||
663 | error = -EINVAL; | ||
664 | goto end_function; | ||
665 | } | ||
666 | /* copy the application data */ | ||
667 | error = copy_from_user(virt_address, (void *) app_in_address, num_bytes); | ||
668 | if (error) | ||
669 | error = -EFAULT; | ||
670 | end_function: | ||
671 | dbg("SEP Driver:<-------- sep_write_into_data_pool_handler end\n"); | ||
672 | return error; | ||
673 | } | ||
674 | |||
675 | /* | ||
676 | this function handles the read from data pool command | ||
677 | */ | ||
678 | static int sep_read_from_data_pool_handler(struct sep_device *sep, unsigned long arg) | ||
679 | { | ||
680 | int error; | ||
681 | /* virtual address of dest application buffer */ | ||
682 | unsigned long app_out_address; | ||
683 | /* virtual address of the data pool */ | ||
684 | unsigned long va; | ||
685 | void *virt_address; | ||
686 | unsigned long num_bytes; | ||
687 | void *data_pool_area_addr; | ||
688 | |||
689 | dbg("SEP Driver:--------> sep_read_from_data_pool_handler start\n"); | ||
690 | |||
691 | /* get the application address */ | ||
692 | error = get_user(app_out_address, &(((struct sep_driver_write_t *) arg)->app_address)); | ||
693 | if (error) | ||
694 | goto end_function; | ||
695 | |||
696 | /* get the virtual kernel address address */ | ||
697 | error = get_user(va, &(((struct sep_driver_write_t *) arg)->datapool_address)); | ||
698 | if (error) | ||
699 | goto end_function; | ||
700 | virt_address = (void *)va; | ||
701 | |||
702 | /* get the number of bytes */ | ||
703 | error = get_user(num_bytes, &(((struct sep_driver_write_t *) arg)->num_bytes)); | ||
704 | if (error) | ||
705 | goto end_function; | ||
706 | |||
707 | /* calculate the start of the data pool */ | ||
708 | data_pool_area_addr = sep->shared_addr + SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES; | ||
709 | |||
710 | /* FIXME: These are incomplete all over the driver: what about + len | ||
711 | and when doing that also overflows */ | ||
712 | /* check that the range of the virtual kernel address is correct */ | ||
713 | if (virt_address < data_pool_area_addr || virt_address > data_pool_area_addr + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES) { | ||
714 | error = -EINVAL; | ||
715 | goto end_function; | ||
716 | } | ||
717 | |||
718 | /* copy the application data */ | ||
719 | error = copy_to_user((void *) app_out_address, virt_address, num_bytes); | ||
720 | if (error) | ||
721 | error = -EFAULT; | ||
722 | end_function: | ||
723 | dbg("SEP Driver:<-------- sep_read_from_data_pool_handler end\n"); | ||
724 | return error; | ||
725 | } | ||
726 | |||
727 | /* | ||
728 | This function releases all the application virtual buffer physical pages, | ||
729 | that were previously locked | ||
730 | */ | ||
731 | static int sep_free_dma_pages(struct page **page_array_ptr, unsigned long num_pages, unsigned long dirtyFlag) | ||
732 | { | ||
733 | unsigned long count; | ||
734 | |||
735 | if (dirtyFlag) { | ||
736 | for (count = 0; count < num_pages; count++) { | ||
737 | /* the out array was written, therefore the data was changed */ | ||
738 | if (!PageReserved(page_array_ptr[count])) | ||
739 | SetPageDirty(page_array_ptr[count]); | ||
740 | page_cache_release(page_array_ptr[count]); | ||
741 | } | ||
742 | } else { | ||
743 | /* free in pages - the data was only read, therefore no update was done | ||
744 | on those pages */ | ||
745 | for (count = 0; count < num_pages; count++) | ||
746 | page_cache_release(page_array_ptr[count]); | ||
747 | } | ||
748 | |||
749 | if (page_array_ptr) | ||
750 | /* free the array */ | ||
751 | kfree(page_array_ptr); | ||
752 | |||
753 | return 0; | ||
754 | } | ||
755 | |||
756 | /* | ||
757 | This function locks all the physical pages of the kernel virtual buffer | ||
758 | and construct a basic lli array, where each entry holds the physical | ||
759 | page address and the size that application data holds in this physical pages | ||
760 | */ | ||
761 | static int sep_lock_kernel_pages(struct sep_device *sep, | ||
762 | unsigned long kernel_virt_addr, | ||
763 | unsigned long data_size, | ||
764 | unsigned long *num_pages_ptr, | ||
765 | struct sep_lli_entry_t **lli_array_ptr, | ||
766 | struct page ***page_array_ptr) | ||
767 | { | ||
768 | int error = 0; | ||
769 | /* the the page of the end address of the user space buffer */ | ||
770 | unsigned long end_page; | ||
771 | /* the page of the start address of the user space buffer */ | ||
772 | unsigned long start_page; | ||
773 | /* the range in pages */ | ||
774 | unsigned long num_pages; | ||
775 | struct sep_lli_entry_t *lli_array; | ||
776 | /* next kernel address to map */ | ||
777 | unsigned long next_kernel_address; | ||
778 | unsigned long count; | ||
779 | |||
780 | dbg("SEP Driver:--------> sep_lock_kernel_pages start\n"); | ||
781 | |||
782 | /* set start and end pages and num pages */ | ||
783 | end_page = (kernel_virt_addr + data_size - 1) >> PAGE_SHIFT; | ||
784 | start_page = kernel_virt_addr >> PAGE_SHIFT; | ||
785 | num_pages = end_page - start_page + 1; | ||
786 | |||
787 | edbg("SEP Driver: kernel_virt_addr is %08lx\n", kernel_virt_addr); | ||
788 | edbg("SEP Driver: data_size is %lu\n", data_size); | ||
789 | edbg("SEP Driver: start_page is %lx\n", start_page); | ||
790 | edbg("SEP Driver: end_page is %lx\n", end_page); | ||
791 | edbg("SEP Driver: num_pages is %lu\n", num_pages); | ||
792 | |||
793 | lli_array = kmalloc(sizeof(struct sep_lli_entry_t) * num_pages, GFP_ATOMIC); | ||
794 | if (!lli_array) { | ||
795 | edbg("SEP Driver: kmalloc for lli_array failed\n"); | ||
796 | error = -ENOMEM; | ||
797 | goto end_function; | ||
798 | } | ||
799 | |||
800 | /* set the start address of the first page - app data may start not at | ||
801 | the beginning of the page */ | ||
802 | lli_array[0].physical_address = (unsigned long) virt_to_phys((unsigned long *) kernel_virt_addr); | ||
803 | |||
804 | /* check that not all the data is in the first page only */ | ||
805 | if ((PAGE_SIZE - (kernel_virt_addr & (~PAGE_MASK))) >= data_size) | ||
806 | lli_array[0].block_size = data_size; | ||
807 | else | ||
808 | lli_array[0].block_size = PAGE_SIZE - (kernel_virt_addr & (~PAGE_MASK)); | ||
809 | |||
810 | /* debug print */ | ||
811 | dbg("lli_array[0].physical_address is %08lx, lli_array[0].block_size is %lu\n", lli_array[0].physical_address, lli_array[0].block_size); | ||
812 | |||
813 | /* advance the address to the start of the next page */ | ||
814 | next_kernel_address = (kernel_virt_addr & PAGE_MASK) + PAGE_SIZE; | ||
815 | |||
816 | /* go from the second page to the prev before last */ | ||
817 | for (count = 1; count < (num_pages - 1); count++) { | ||
818 | lli_array[count].physical_address = (unsigned long) virt_to_phys((unsigned long *) next_kernel_address); | ||
819 | lli_array[count].block_size = PAGE_SIZE; | ||
820 | |||
821 | edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n", count, lli_array[count].physical_address, count, lli_array[count].block_size); | ||
822 | next_kernel_address += PAGE_SIZE; | ||
823 | } | ||
824 | |||
825 | /* if more then 1 pages locked - then update for the last page size needed */ | ||
826 | if (num_pages > 1) { | ||
827 | /* update the address of the last page */ | ||
828 | lli_array[count].physical_address = (unsigned long) virt_to_phys((unsigned long *) next_kernel_address); | ||
829 | |||
830 | /* set the size of the last page */ | ||
831 | lli_array[count].block_size = (kernel_virt_addr + data_size) & (~PAGE_MASK); | ||
832 | |||
833 | if (lli_array[count].block_size == 0) { | ||
834 | dbg("app_virt_addr is %08lx\n", kernel_virt_addr); | ||
835 | dbg("data_size is %lu\n", data_size); | ||
836 | while (1); | ||
837 | } | ||
838 | |||
839 | edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n", count, lli_array[count].physical_address, count, lli_array[count].block_size); | ||
840 | } | ||
841 | /* set output params */ | ||
842 | *lli_array_ptr = lli_array; | ||
843 | *num_pages_ptr = num_pages; | ||
844 | *page_array_ptr = 0; | ||
845 | end_function: | ||
846 | dbg("SEP Driver:<-------- sep_lock_kernel_pages end\n"); | ||
847 | return 0; | ||
848 | } | ||
849 | |||
850 | /* | ||
851 | This function locks all the physical pages of the application virtual buffer | ||
852 | and construct a basic lli array, where each entry holds the physical page | ||
853 | address and the size that application data holds in this physical pages | ||
854 | */ | ||
855 | static int sep_lock_user_pages(struct sep_device *sep, | ||
856 | unsigned long app_virt_addr, | ||
857 | unsigned long data_size, | ||
858 | unsigned long *num_pages_ptr, | ||
859 | struct sep_lli_entry_t **lli_array_ptr, | ||
860 | struct page ***page_array_ptr) | ||
861 | { | ||
862 | int error = 0; | ||
863 | /* the the page of the end address of the user space buffer */ | ||
864 | unsigned long end_page; | ||
865 | /* the page of the start address of the user space buffer */ | ||
866 | unsigned long start_page; | ||
867 | /* the range in pages */ | ||
868 | unsigned long num_pages; | ||
869 | struct page **page_array; | ||
870 | struct sep_lli_entry_t *lli_array; | ||
871 | unsigned long count; | ||
872 | int result; | ||
873 | |||
874 | dbg("SEP Driver:--------> sep_lock_user_pages start\n"); | ||
875 | |||
876 | /* set start and end pages and num pages */ | ||
877 | end_page = (app_virt_addr + data_size - 1) >> PAGE_SHIFT; | ||
878 | start_page = app_virt_addr >> PAGE_SHIFT; | ||
879 | num_pages = end_page - start_page + 1; | ||
880 | |||
881 | edbg("SEP Driver: app_virt_addr is %08lx\n", app_virt_addr); | ||
882 | edbg("SEP Driver: data_size is %lu\n", data_size); | ||
883 | edbg("SEP Driver: start_page is %lu\n", start_page); | ||
884 | edbg("SEP Driver: end_page is %lu\n", end_page); | ||
885 | edbg("SEP Driver: num_pages is %lu\n", num_pages); | ||
886 | |||
887 | /* allocate array of pages structure pointers */ | ||
888 | page_array = kmalloc(sizeof(struct page *) * num_pages, GFP_ATOMIC); | ||
889 | if (!page_array) { | ||
890 | edbg("SEP Driver: kmalloc for page_array failed\n"); | ||
891 | |||
892 | error = -ENOMEM; | ||
893 | goto end_function; | ||
894 | } | ||
895 | |||
896 | lli_array = kmalloc(sizeof(struct sep_lli_entry_t) * num_pages, GFP_ATOMIC); | ||
897 | if (!lli_array) { | ||
898 | edbg("SEP Driver: kmalloc for lli_array failed\n"); | ||
899 | |||
900 | error = -ENOMEM; | ||
901 | goto end_function_with_error1; | ||
902 | } | ||
903 | |||
904 | /* convert the application virtual address into a set of physical */ | ||
905 | down_read(¤t->mm->mmap_sem); | ||
906 | result = get_user_pages(current, current->mm, app_virt_addr, num_pages, 1, 0, page_array, 0); | ||
907 | up_read(¤t->mm->mmap_sem); | ||
908 | |||
909 | /* check the number of pages locked - if not all then exit with error */ | ||
910 | if (result != num_pages) { | ||
911 | dbg("SEP Driver: not all pages locked by get_user_pages\n"); | ||
912 | |||
913 | error = -ENOMEM; | ||
914 | goto end_function_with_error2; | ||
915 | } | ||
916 | |||
917 | /* flush the cache */ | ||
918 | for (count = 0; count < num_pages; count++) | ||
919 | flush_dcache_page(page_array[count]); | ||
920 | |||
921 | /* set the start address of the first page - app data may start not at | ||
922 | the beginning of the page */ | ||
923 | lli_array[0].physical_address = ((unsigned long) page_to_phys(page_array[0])) + (app_virt_addr & (~PAGE_MASK)); | ||
924 | |||
925 | /* check that not all the data is in the first page only */ | ||
926 | if ((PAGE_SIZE - (app_virt_addr & (~PAGE_MASK))) >= data_size) | ||
927 | lli_array[0].block_size = data_size; | ||
928 | else | ||
929 | lli_array[0].block_size = PAGE_SIZE - (app_virt_addr & (~PAGE_MASK)); | ||
930 | |||
931 | /* debug print */ | ||
932 | dbg("lli_array[0].physical_address is %08lx, lli_array[0].block_size is %lu\n", lli_array[0].physical_address, lli_array[0].block_size); | ||
933 | |||
934 | /* go from the second page to the prev before last */ | ||
935 | for (count = 1; count < (num_pages - 1); count++) { | ||
936 | lli_array[count].physical_address = (unsigned long) page_to_phys(page_array[count]); | ||
937 | lli_array[count].block_size = PAGE_SIZE; | ||
938 | |||
939 | edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n", count, lli_array[count].physical_address, count, lli_array[count].block_size); | ||
940 | } | ||
941 | |||
942 | /* if more then 1 pages locked - then update for the last page size needed */ | ||
943 | if (num_pages > 1) { | ||
944 | /* update the address of the last page */ | ||
945 | lli_array[count].physical_address = (unsigned long) page_to_phys(page_array[count]); | ||
946 | |||
947 | /* set the size of the last page */ | ||
948 | lli_array[count].block_size = (app_virt_addr + data_size) & (~PAGE_MASK); | ||
949 | |||
950 | if (lli_array[count].block_size == 0) { | ||
951 | dbg("app_virt_addr is %08lx\n", app_virt_addr); | ||
952 | dbg("data_size is %lu\n", data_size); | ||
953 | while (1); | ||
954 | } | ||
955 | edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n", | ||
956 | count, lli_array[count].physical_address, | ||
957 | count, lli_array[count].block_size); | ||
958 | } | ||
959 | |||
960 | /* set output params */ | ||
961 | *lli_array_ptr = lli_array; | ||
962 | *num_pages_ptr = num_pages; | ||
963 | *page_array_ptr = page_array; | ||
964 | goto end_function; | ||
965 | |||
966 | end_function_with_error2: | ||
967 | /* release the cache */ | ||
968 | for (count = 0; count < num_pages; count++) | ||
969 | page_cache_release(page_array[count]); | ||
970 | kfree(lli_array); | ||
971 | end_function_with_error1: | ||
972 | kfree(page_array); | ||
973 | end_function: | ||
974 | dbg("SEP Driver:<-------- sep_lock_user_pages end\n"); | ||
975 | return 0; | ||
976 | } | ||
977 | |||
978 | |||
979 | /* | ||
980 | this function calculates the size of data that can be inserted into the lli | ||
981 | table from this array the condition is that either the table is full | ||
982 | (all etnries are entered), or there are no more entries in the lli array | ||
983 | */ | ||
984 | static unsigned long sep_calculate_lli_table_max_size(struct sep_lli_entry_t *lli_in_array_ptr, unsigned long num_array_entries) | ||
985 | { | ||
986 | unsigned long table_data_size = 0; | ||
987 | unsigned long counter; | ||
988 | |||
989 | /* calculate the data in the out lli table if till we fill the whole | ||
990 | table or till the data has ended */ | ||
991 | for (counter = 0; (counter < (SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP - 1)) && (counter < num_array_entries); counter++) | ||
992 | table_data_size += lli_in_array_ptr[counter].block_size; | ||
993 | return table_data_size; | ||
994 | } | ||
995 | |||
996 | /* | ||
997 | this functions builds ont lli table from the lli_array according to | ||
998 | the given size of data | ||
999 | */ | ||
1000 | static void sep_build_lli_table(struct sep_lli_entry_t *lli_array_ptr, struct sep_lli_entry_t *lli_table_ptr, unsigned long *num_processed_entries_ptr, unsigned long *num_table_entries_ptr, unsigned long table_data_size) | ||
1001 | { | ||
1002 | unsigned long curr_table_data_size; | ||
1003 | /* counter of lli array entry */ | ||
1004 | unsigned long array_counter; | ||
1005 | |||
1006 | dbg("SEP Driver:--------> sep_build_lli_table start\n"); | ||
1007 | |||
1008 | /* init currrent table data size and lli array entry counter */ | ||
1009 | curr_table_data_size = 0; | ||
1010 | array_counter = 0; | ||
1011 | *num_table_entries_ptr = 1; | ||
1012 | |||
1013 | edbg("SEP Driver:table_data_size is %lu\n", table_data_size); | ||
1014 | |||
1015 | /* fill the table till table size reaches the needed amount */ | ||
1016 | while (curr_table_data_size < table_data_size) { | ||
1017 | /* update the number of entries in table */ | ||
1018 | (*num_table_entries_ptr)++; | ||
1019 | |||
1020 | lli_table_ptr->physical_address = lli_array_ptr[array_counter].physical_address; | ||
1021 | lli_table_ptr->block_size = lli_array_ptr[array_counter].block_size; | ||
1022 | curr_table_data_size += lli_table_ptr->block_size; | ||
1023 | |||
1024 | edbg("SEP Driver:lli_table_ptr is %08lx\n", (unsigned long) lli_table_ptr); | ||
1025 | edbg("SEP Driver:lli_table_ptr->physical_address is %08lx\n", lli_table_ptr->physical_address); | ||
1026 | edbg("SEP Driver:lli_table_ptr->block_size is %lu\n", lli_table_ptr->block_size); | ||
1027 | |||
1028 | /* check for overflow of the table data */ | ||
1029 | if (curr_table_data_size > table_data_size) { | ||
1030 | edbg("SEP Driver:curr_table_data_size > table_data_size\n"); | ||
1031 | |||
1032 | /* update the size of block in the table */ | ||
1033 | lli_table_ptr->block_size -= (curr_table_data_size - table_data_size); | ||
1034 | |||
1035 | /* update the physical address in the lli array */ | ||
1036 | lli_array_ptr[array_counter].physical_address += lli_table_ptr->block_size; | ||
1037 | |||
1038 | /* update the block size left in the lli array */ | ||
1039 | lli_array_ptr[array_counter].block_size = (curr_table_data_size - table_data_size); | ||
1040 | } else | ||
1041 | /* advance to the next entry in the lli_array */ | ||
1042 | array_counter++; | ||
1043 | |||
1044 | edbg("SEP Driver:lli_table_ptr->physical_address is %08lx\n", lli_table_ptr->physical_address); | ||
1045 | edbg("SEP Driver:lli_table_ptr->block_size is %lu\n", lli_table_ptr->block_size); | ||
1046 | |||
1047 | /* move to the next entry in table */ | ||
1048 | lli_table_ptr++; | ||
1049 | } | ||
1050 | |||
1051 | /* set the info entry to default */ | ||
1052 | lli_table_ptr->physical_address = 0xffffffff; | ||
1053 | lli_table_ptr->block_size = 0; | ||
1054 | |||
1055 | edbg("SEP Driver:lli_table_ptr is %08lx\n", (unsigned long) lli_table_ptr); | ||
1056 | edbg("SEP Driver:lli_table_ptr->physical_address is %08lx\n", lli_table_ptr->physical_address); | ||
1057 | edbg("SEP Driver:lli_table_ptr->block_size is %lu\n", lli_table_ptr->block_size); | ||
1058 | |||
1059 | /* set the output parameter */ | ||
1060 | *num_processed_entries_ptr += array_counter; | ||
1061 | |||
1062 | edbg("SEP Driver:*num_processed_entries_ptr is %lu\n", *num_processed_entries_ptr); | ||
1063 | dbg("SEP Driver:<-------- sep_build_lli_table end\n"); | ||
1064 | return; | ||
1065 | } | ||
1066 | |||
1067 | /* | ||
1068 | this function goes over the list of the print created tables and | ||
1069 | prints all the data | ||
1070 | */ | ||
1071 | static void sep_debug_print_lli_tables(struct sep_device *sep, struct sep_lli_entry_t *lli_table_ptr, unsigned long num_table_entries, unsigned long table_data_size) | ||
1072 | { | ||
1073 | unsigned long table_count; | ||
1074 | unsigned long entries_count; | ||
1075 | |||
1076 | dbg("SEP Driver:--------> sep_debug_print_lli_tables start\n"); | ||
1077 | |||
1078 | table_count = 1; | ||
1079 | while ((unsigned long) lli_table_ptr != 0xffffffff) { | ||
1080 | edbg("SEP Driver: lli table %08lx, table_data_size is %lu\n", table_count, table_data_size); | ||
1081 | edbg("SEP Driver: num_table_entries is %lu\n", num_table_entries); | ||
1082 | |||
1083 | /* print entries of the table (without info entry) */ | ||
1084 | for (entries_count = 0; entries_count < num_table_entries; entries_count++, lli_table_ptr++) { | ||
1085 | edbg("SEP Driver:lli_table_ptr address is %08lx\n", (unsigned long) lli_table_ptr); | ||
1086 | edbg("SEP Driver:phys address is %08lx block size is %lu\n", lli_table_ptr->physical_address, lli_table_ptr->block_size); | ||
1087 | } | ||
1088 | |||
1089 | /* point to the info entry */ | ||
1090 | lli_table_ptr--; | ||
1091 | |||
1092 | edbg("SEP Driver:phys lli_table_ptr->block_size is %lu\n", lli_table_ptr->block_size); | ||
1093 | edbg("SEP Driver:phys lli_table_ptr->physical_address is %08lx\n", lli_table_ptr->physical_address); | ||
1094 | |||
1095 | |||
1096 | table_data_size = lli_table_ptr->block_size & 0xffffff; | ||
1097 | num_table_entries = (lli_table_ptr->block_size >> 24) & 0xff; | ||
1098 | lli_table_ptr = (struct sep_lli_entry_t *) | ||
1099 | (lli_table_ptr->physical_address); | ||
1100 | |||
1101 | edbg("SEP Driver:phys table_data_size is %lu num_table_entries is %lu lli_table_ptr is%lu\n", table_data_size, num_table_entries, (unsigned long) lli_table_ptr); | ||
1102 | |||
1103 | if ((unsigned long) lli_table_ptr != 0xffffffff) | ||
1104 | lli_table_ptr = (struct sep_lli_entry_t *) sep_shared_bus_to_virt(sep, (unsigned long) lli_table_ptr); | ||
1105 | |||
1106 | table_count++; | ||
1107 | } | ||
1108 | dbg("SEP Driver:<-------- sep_debug_print_lli_tables end\n"); | ||
1109 | } | ||
1110 | |||
1111 | |||
1112 | /* | ||
1113 | This function prepares only input DMA table for synhronic symmetric | ||
1114 | operations (HASH) | ||
1115 | */ | ||
1116 | static int sep_prepare_input_dma_table(struct sep_device *sep, | ||
1117 | unsigned long app_virt_addr, | ||
1118 | unsigned long data_size, | ||
1119 | unsigned long block_size, | ||
1120 | unsigned long *lli_table_ptr, | ||
1121 | unsigned long *num_entries_ptr, | ||
1122 | unsigned long *table_data_size_ptr, | ||
1123 | bool isKernelVirtualAddress) | ||
1124 | { | ||
1125 | /* pointer to the info entry of the table - the last entry */ | ||
1126 | struct sep_lli_entry_t *info_entry_ptr; | ||
1127 | /* array of pointers ot page */ | ||
1128 | struct sep_lli_entry_t *lli_array_ptr; | ||
1129 | /* points to the first entry to be processed in the lli_in_array */ | ||
1130 | unsigned long current_entry; | ||
1131 | /* num entries in the virtual buffer */ | ||
1132 | unsigned long sep_lli_entries; | ||
1133 | /* lli table pointer */ | ||
1134 | struct sep_lli_entry_t *in_lli_table_ptr; | ||
1135 | /* the total data in one table */ | ||
1136 | unsigned long table_data_size; | ||
1137 | /* number of entries in lli table */ | ||
1138 | unsigned long num_entries_in_table; | ||
1139 | /* next table address */ | ||
1140 | void *lli_table_alloc_addr; | ||
1141 | unsigned long result; | ||
1142 | |||
1143 | dbg("SEP Driver:--------> sep_prepare_input_dma_table start\n"); | ||
1144 | |||
1145 | edbg("SEP Driver:data_size is %lu\n", data_size); | ||
1146 | edbg("SEP Driver:block_size is %lu\n", block_size); | ||
1147 | |||
1148 | /* initialize the pages pointers */ | ||
1149 | sep->in_page_array = 0; | ||
1150 | sep->in_num_pages = 0; | ||
1151 | |||
1152 | if (data_size == 0) { | ||
1153 | /* special case - created 2 entries table with zero data */ | ||
1154 | in_lli_table_ptr = (struct sep_lli_entry_t *) (sep->shared_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES); | ||
1155 | /* FIXME: Should the entry below not be for _bus */ | ||
1156 | in_lli_table_ptr->physical_address = (unsigned long)sep->shared_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES; | ||
1157 | in_lli_table_ptr->block_size = 0; | ||
1158 | |||
1159 | in_lli_table_ptr++; | ||
1160 | in_lli_table_ptr->physical_address = 0xFFFFFFFF; | ||
1161 | in_lli_table_ptr->block_size = 0; | ||
1162 | |||
1163 | *lli_table_ptr = sep->shared_bus + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES; | ||
1164 | *num_entries_ptr = 2; | ||
1165 | *table_data_size_ptr = 0; | ||
1166 | |||
1167 | goto end_function; | ||
1168 | } | ||
1169 | |||
1170 | /* check if the pages are in Kernel Virtual Address layout */ | ||
1171 | if (isKernelVirtualAddress == true) | ||
1172 | /* lock the pages of the kernel buffer and translate them to pages */ | ||
1173 | result = sep_lock_kernel_pages(sep, app_virt_addr, data_size, &sep->in_num_pages, &lli_array_ptr, &sep->in_page_array); | ||
1174 | else | ||
1175 | /* lock the pages of the user buffer and translate them to pages */ | ||
1176 | result = sep_lock_user_pages(sep, app_virt_addr, data_size, &sep->in_num_pages, &lli_array_ptr, &sep->in_page_array); | ||
1177 | |||
1178 | if (result) | ||
1179 | return result; | ||
1180 | |||
1181 | edbg("SEP Driver:output sep->in_num_pages is %lu\n", sep->in_num_pages); | ||
1182 | |||
1183 | current_entry = 0; | ||
1184 | info_entry_ptr = 0; | ||
1185 | sep_lli_entries = sep->in_num_pages; | ||
1186 | |||
1187 | /* initiate to point after the message area */ | ||
1188 | lli_table_alloc_addr = sep->shared_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES; | ||
1189 | |||
1190 | /* loop till all the entries in in array are not processed */ | ||
1191 | while (current_entry < sep_lli_entries) { | ||
1192 | /* set the new input and output tables */ | ||
1193 | in_lli_table_ptr = (struct sep_lli_entry_t *) lli_table_alloc_addr; | ||
1194 | |||
1195 | lli_table_alloc_addr += sizeof(struct sep_lli_entry_t) * SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; | ||
1196 | |||
1197 | /* calculate the maximum size of data for input table */ | ||
1198 | table_data_size = sep_calculate_lli_table_max_size(&lli_array_ptr[current_entry], (sep_lli_entries - current_entry)); | ||
1199 | |||
1200 | /* now calculate the table size so that it will be module block size */ | ||
1201 | table_data_size = (table_data_size / block_size) * block_size; | ||
1202 | |||
1203 | edbg("SEP Driver:output table_data_size is %lu\n", table_data_size); | ||
1204 | |||
1205 | /* construct input lli table */ | ||
1206 | sep_build_lli_table(&lli_array_ptr[current_entry], in_lli_table_ptr, ¤t_entry, &num_entries_in_table, table_data_size); | ||
1207 | |||
1208 | if (info_entry_ptr == 0) { | ||
1209 | /* set the output parameters to physical addresses */ | ||
1210 | *lli_table_ptr = sep_shared_virt_to_bus(sep, in_lli_table_ptr); | ||
1211 | *num_entries_ptr = num_entries_in_table; | ||
1212 | *table_data_size_ptr = table_data_size; | ||
1213 | |||
1214 | edbg("SEP Driver:output lli_table_in_ptr is %08lx\n", *lli_table_ptr); | ||
1215 | } else { | ||
1216 | /* update the info entry of the previous in table */ | ||
1217 | info_entry_ptr->physical_address = sep_shared_virt_to_bus(sep, in_lli_table_ptr); | ||
1218 | info_entry_ptr->block_size = ((num_entries_in_table) << 24) | (table_data_size); | ||
1219 | } | ||
1220 | |||
1221 | /* save the pointer to the info entry of the current tables */ | ||
1222 | info_entry_ptr = in_lli_table_ptr + num_entries_in_table - 1; | ||
1223 | } | ||
1224 | |||
1225 | /* print input tables */ | ||
1226 | sep_debug_print_lli_tables(sep, (struct sep_lli_entry_t *) | ||
1227 | sep_shared_bus_to_virt(sep, *lli_table_ptr), *num_entries_ptr, *table_data_size_ptr); | ||
1228 | |||
1229 | /* the array of the pages */ | ||
1230 | kfree(lli_array_ptr); | ||
1231 | end_function: | ||
1232 | dbg("SEP Driver:<-------- sep_prepare_input_dma_table end\n"); | ||
1233 | return 0; | ||
1234 | |||
1235 | } | ||
1236 | |||
1237 | /* | ||
1238 | This function creates the input and output dma tables for | ||
1239 | symmetric operations (AES/DES) according to the block size from LLI arays | ||
1240 | */ | ||
1241 | static int sep_construct_dma_tables_from_lli(struct sep_device *sep, | ||
1242 | struct sep_lli_entry_t *lli_in_array, | ||
1243 | unsigned long sep_in_lli_entries, | ||
1244 | struct sep_lli_entry_t *lli_out_array, | ||
1245 | unsigned long sep_out_lli_entries, | ||
1246 | unsigned long block_size, unsigned long *lli_table_in_ptr, unsigned long *lli_table_out_ptr, unsigned long *in_num_entries_ptr, unsigned long *out_num_entries_ptr, unsigned long *table_data_size_ptr) | ||
1247 | { | ||
1248 | /* points to the area where next lli table can be allocated: keep void * | ||
1249 | as there is pointer scaling to fix otherwise */ | ||
1250 | void *lli_table_alloc_addr; | ||
1251 | /* input lli table */ | ||
1252 | struct sep_lli_entry_t *in_lli_table_ptr; | ||
1253 | /* output lli table */ | ||
1254 | struct sep_lli_entry_t *out_lli_table_ptr; | ||
1255 | /* pointer to the info entry of the table - the last entry */ | ||
1256 | struct sep_lli_entry_t *info_in_entry_ptr; | ||
1257 | /* pointer to the info entry of the table - the last entry */ | ||
1258 | struct sep_lli_entry_t *info_out_entry_ptr; | ||
1259 | /* points to the first entry to be processed in the lli_in_array */ | ||
1260 | unsigned long current_in_entry; | ||
1261 | /* points to the first entry to be processed in the lli_out_array */ | ||
1262 | unsigned long current_out_entry; | ||
1263 | /* max size of the input table */ | ||
1264 | unsigned long in_table_data_size; | ||
1265 | /* max size of the output table */ | ||
1266 | unsigned long out_table_data_size; | ||
1267 | /* flag te signifies if this is the first tables build from the arrays */ | ||
1268 | unsigned long first_table_flag; | ||
1269 | /* the data size that should be in table */ | ||
1270 | unsigned long table_data_size; | ||
1271 | /* number of etnries in the input table */ | ||
1272 | unsigned long num_entries_in_table; | ||
1273 | /* number of etnries in the output table */ | ||
1274 | unsigned long num_entries_out_table; | ||
1275 | |||
1276 | dbg("SEP Driver:--------> sep_construct_dma_tables_from_lli start\n"); | ||
1277 | |||
1278 | /* initiate to pint after the message area */ | ||
1279 | lli_table_alloc_addr = sep->shared_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES; | ||
1280 | |||
1281 | current_in_entry = 0; | ||
1282 | current_out_entry = 0; | ||
1283 | first_table_flag = 1; | ||
1284 | info_in_entry_ptr = 0; | ||
1285 | info_out_entry_ptr = 0; | ||
1286 | |||
1287 | /* loop till all the entries in in array are not processed */ | ||
1288 | while (current_in_entry < sep_in_lli_entries) { | ||
1289 | /* set the new input and output tables */ | ||
1290 | in_lli_table_ptr = (struct sep_lli_entry_t *) lli_table_alloc_addr; | ||
1291 | |||
1292 | lli_table_alloc_addr += sizeof(struct sep_lli_entry_t) * SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; | ||
1293 | |||
1294 | /* set the first output tables */ | ||
1295 | out_lli_table_ptr = (struct sep_lli_entry_t *) lli_table_alloc_addr; | ||
1296 | |||
1297 | lli_table_alloc_addr += sizeof(struct sep_lli_entry_t) * SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; | ||
1298 | |||
1299 | /* calculate the maximum size of data for input table */ | ||
1300 | in_table_data_size = sep_calculate_lli_table_max_size(&lli_in_array[current_in_entry], (sep_in_lli_entries - current_in_entry)); | ||
1301 | |||
1302 | /* calculate the maximum size of data for output table */ | ||
1303 | out_table_data_size = sep_calculate_lli_table_max_size(&lli_out_array[current_out_entry], (sep_out_lli_entries - current_out_entry)); | ||
1304 | |||
1305 | edbg("SEP Driver:in_table_data_size is %lu\n", in_table_data_size); | ||
1306 | edbg("SEP Driver:out_table_data_size is %lu\n", out_table_data_size); | ||
1307 | |||
1308 | /* check where the data is smallest */ | ||
1309 | table_data_size = in_table_data_size; | ||
1310 | if (table_data_size > out_table_data_size) | ||
1311 | table_data_size = out_table_data_size; | ||
1312 | |||
1313 | /* now calculate the table size so that it will be module block size */ | ||
1314 | table_data_size = (table_data_size / block_size) * block_size; | ||
1315 | |||
1316 | dbg("SEP Driver:table_data_size is %lu\n", table_data_size); | ||
1317 | |||
1318 | /* construct input lli table */ | ||
1319 | sep_build_lli_table(&lli_in_array[current_in_entry], in_lli_table_ptr, ¤t_in_entry, &num_entries_in_table, table_data_size); | ||
1320 | |||
1321 | /* construct output lli table */ | ||
1322 | sep_build_lli_table(&lli_out_array[current_out_entry], out_lli_table_ptr, ¤t_out_entry, &num_entries_out_table, table_data_size); | ||
1323 | |||
1324 | /* if info entry is null - this is the first table built */ | ||
1325 | if (info_in_entry_ptr == 0) { | ||
1326 | /* set the output parameters to physical addresses */ | ||
1327 | *lli_table_in_ptr = sep_shared_virt_to_bus(sep, in_lli_table_ptr); | ||
1328 | *in_num_entries_ptr = num_entries_in_table; | ||
1329 | *lli_table_out_ptr = sep_shared_virt_to_bus(sep, out_lli_table_ptr); | ||
1330 | *out_num_entries_ptr = num_entries_out_table; | ||
1331 | *table_data_size_ptr = table_data_size; | ||
1332 | |||
1333 | edbg("SEP Driver:output lli_table_in_ptr is %08lx\n", *lli_table_in_ptr); | ||
1334 | edbg("SEP Driver:output lli_table_out_ptr is %08lx\n", *lli_table_out_ptr); | ||
1335 | } else { | ||
1336 | /* update the info entry of the previous in table */ | ||
1337 | info_in_entry_ptr->physical_address = sep_shared_virt_to_bus(sep, in_lli_table_ptr); | ||
1338 | info_in_entry_ptr->block_size = ((num_entries_in_table) << 24) | (table_data_size); | ||
1339 | |||
1340 | /* update the info entry of the previous in table */ | ||
1341 | info_out_entry_ptr->physical_address = sep_shared_virt_to_bus(sep, out_lli_table_ptr); | ||
1342 | info_out_entry_ptr->block_size = ((num_entries_out_table) << 24) | (table_data_size); | ||
1343 | } | ||
1344 | |||
1345 | /* save the pointer to the info entry of the current tables */ | ||
1346 | info_in_entry_ptr = in_lli_table_ptr + num_entries_in_table - 1; | ||
1347 | info_out_entry_ptr = out_lli_table_ptr + num_entries_out_table - 1; | ||
1348 | |||
1349 | edbg("SEP Driver:output num_entries_out_table is %lu\n", (unsigned long) num_entries_out_table); | ||
1350 | edbg("SEP Driver:output info_in_entry_ptr is %lu\n", (unsigned long) info_in_entry_ptr); | ||
1351 | edbg("SEP Driver:output info_out_entry_ptr is %lu\n", (unsigned long) info_out_entry_ptr); | ||
1352 | } | ||
1353 | |||
1354 | /* print input tables */ | ||
1355 | sep_debug_print_lli_tables(sep, (struct sep_lli_entry_t *) | ||
1356 | sep_shared_bus_to_virt(sep, *lli_table_in_ptr), *in_num_entries_ptr, *table_data_size_ptr); | ||
1357 | /* print output tables */ | ||
1358 | sep_debug_print_lli_tables(sep, (struct sep_lli_entry_t *) | ||
1359 | sep_shared_bus_to_virt(sep, *lli_table_out_ptr), *out_num_entries_ptr, *table_data_size_ptr); | ||
1360 | dbg("SEP Driver:<-------- sep_construct_dma_tables_from_lli end\n"); | ||
1361 | return 0; | ||
1362 | } | ||
1363 | |||
1364 | |||
1365 | /* | ||
1366 | This function builds input and output DMA tables for synhronic | ||
1367 | symmetric operations (AES, DES). It also checks that each table | ||
1368 | is of the modular block size | ||
1369 | */ | ||
1370 | static int sep_prepare_input_output_dma_table(struct sep_device *sep, | ||
1371 | unsigned long app_virt_in_addr, | ||
1372 | unsigned long app_virt_out_addr, | ||
1373 | unsigned long data_size, | ||
1374 | unsigned long block_size, | ||
1375 | unsigned long *lli_table_in_ptr, unsigned long *lli_table_out_ptr, unsigned long *in_num_entries_ptr, unsigned long *out_num_entries_ptr, unsigned long *table_data_size_ptr, bool isKernelVirtualAddress) | ||
1376 | { | ||
1377 | /* array of pointers of page */ | ||
1378 | struct sep_lli_entry_t *lli_in_array; | ||
1379 | /* array of pointers of page */ | ||
1380 | struct sep_lli_entry_t *lli_out_array; | ||
1381 | int result = 0; | ||
1382 | |||
1383 | dbg("SEP Driver:--------> sep_prepare_input_output_dma_table start\n"); | ||
1384 | |||
1385 | /* initialize the pages pointers */ | ||
1386 | sep->in_page_array = 0; | ||
1387 | sep->out_page_array = 0; | ||
1388 | |||
1389 | /* check if the pages are in Kernel Virtual Address layout */ | ||
1390 | if (isKernelVirtualAddress == true) { | ||
1391 | /* lock the pages of the kernel buffer and translate them to pages */ | ||
1392 | result = sep_lock_kernel_pages(sep, app_virt_in_addr, data_size, &sep->in_num_pages, &lli_in_array, &sep->in_page_array); | ||
1393 | if (result) { | ||
1394 | edbg("SEP Driver: sep_lock_kernel_pages for input virtual buffer failed\n"); | ||
1395 | goto end_function; | ||
1396 | } | ||
1397 | } else { | ||
1398 | /* lock the pages of the user buffer and translate them to pages */ | ||
1399 | result = sep_lock_user_pages(sep, app_virt_in_addr, data_size, &sep->in_num_pages, &lli_in_array, &sep->in_page_array); | ||
1400 | if (result) { | ||
1401 | edbg("SEP Driver: sep_lock_user_pages for input virtual buffer failed\n"); | ||
1402 | goto end_function; | ||
1403 | } | ||
1404 | } | ||
1405 | |||
1406 | if (isKernelVirtualAddress == true) { | ||
1407 | result = sep_lock_kernel_pages(sep, app_virt_out_addr, data_size, &sep->out_num_pages, &lli_out_array, &sep->out_page_array); | ||
1408 | if (result) { | ||
1409 | edbg("SEP Driver: sep_lock_kernel_pages for output virtual buffer failed\n"); | ||
1410 | goto end_function_with_error1; | ||
1411 | } | ||
1412 | } else { | ||
1413 | result = sep_lock_user_pages(sep, app_virt_out_addr, data_size, &sep->out_num_pages, &lli_out_array, &sep->out_page_array); | ||
1414 | if (result) { | ||
1415 | edbg("SEP Driver: sep_lock_user_pages for output virtual buffer failed\n"); | ||
1416 | goto end_function_with_error1; | ||
1417 | } | ||
1418 | } | ||
1419 | edbg("sep->in_num_pages is %lu\n", sep->in_num_pages); | ||
1420 | edbg("sep->out_num_pages is %lu\n", sep->out_num_pages); | ||
1421 | edbg("SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP is %x\n", SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP); | ||
1422 | |||
1423 | |||
1424 | /* call the fucntion that creates table from the lli arrays */ | ||
1425 | result = sep_construct_dma_tables_from_lli(sep, lli_in_array, sep->in_num_pages, lli_out_array, sep->out_num_pages, block_size, lli_table_in_ptr, lli_table_out_ptr, in_num_entries_ptr, out_num_entries_ptr, table_data_size_ptr); | ||
1426 | if (result) { | ||
1427 | edbg("SEP Driver: sep_construct_dma_tables_from_lli failed\n"); | ||
1428 | goto end_function_with_error2; | ||
1429 | } | ||
1430 | |||
1431 | /* fall through - free the lli entry arrays */ | ||
1432 | dbg("in_num_entries_ptr is %08lx\n", *in_num_entries_ptr); | ||
1433 | dbg("out_num_entries_ptr is %08lx\n", *out_num_entries_ptr); | ||
1434 | dbg("table_data_size_ptr is %08lx\n", *table_data_size_ptr); | ||
1435 | end_function_with_error2: | ||
1436 | kfree(lli_out_array); | ||
1437 | end_function_with_error1: | ||
1438 | kfree(lli_in_array); | ||
1439 | end_function: | ||
1440 | dbg("SEP Driver:<-------- sep_prepare_input_output_dma_table end result = %d\n", (int) result); | ||
1441 | return result; | ||
1442 | |||
1443 | } | ||
1444 | |||
1445 | /* | ||
1446 | this function handles tha request for creation of the DMA table | ||
1447 | for the synchronic symmetric operations (AES,DES) | ||
1448 | */ | ||
1449 | static int sep_create_sync_dma_tables_handler(struct sep_device *sep, | ||
1450 | unsigned long arg) | ||
1451 | { | ||
1452 | int error; | ||
1453 | /* command arguments */ | ||
1454 | struct sep_driver_build_sync_table_t command_args; | ||
1455 | |||
1456 | dbg("SEP Driver:--------> sep_create_sync_dma_tables_handler start\n"); | ||
1457 | |||
1458 | error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_build_sync_table_t)); | ||
1459 | if (error) { | ||
1460 | error = -EFAULT; | ||
1461 | goto end_function; | ||
1462 | } | ||
1463 | |||
1464 | edbg("app_in_address is %08lx\n", command_args.app_in_address); | ||
1465 | edbg("app_out_address is %08lx\n", command_args.app_out_address); | ||
1466 | edbg("data_size is %lu\n", command_args.data_in_size); | ||
1467 | edbg("block_size is %lu\n", command_args.block_size); | ||
1468 | |||
1469 | /* check if we need to build only input table or input/output */ | ||
1470 | if (command_args.app_out_address) | ||
1471 | /* prepare input and output tables */ | ||
1472 | error = sep_prepare_input_output_dma_table(sep, | ||
1473 | command_args.app_in_address, | ||
1474 | command_args.app_out_address, | ||
1475 | command_args.data_in_size, | ||
1476 | command_args.block_size, | ||
1477 | &command_args.in_table_address, | ||
1478 | &command_args.out_table_address, &command_args.in_table_num_entries, &command_args.out_table_num_entries, &command_args.table_data_size, command_args.isKernelVirtualAddress); | ||
1479 | else | ||
1480 | /* prepare input tables */ | ||
1481 | error = sep_prepare_input_dma_table(sep, | ||
1482 | command_args.app_in_address, | ||
1483 | command_args.data_in_size, command_args.block_size, &command_args.in_table_address, &command_args.in_table_num_entries, &command_args.table_data_size, command_args.isKernelVirtualAddress); | ||
1484 | |||
1485 | if (error) | ||
1486 | goto end_function; | ||
1487 | /* copy to user */ | ||
1488 | if (copy_to_user((void *) arg, (void *) &command_args, sizeof(struct sep_driver_build_sync_table_t))) | ||
1489 | error = -EFAULT; | ||
1490 | end_function: | ||
1491 | dbg("SEP Driver:<-------- sep_create_sync_dma_tables_handler end\n"); | ||
1492 | return error; | ||
1493 | } | ||
1494 | |||
1495 | /* | ||
1496 | this function handles the request for freeing dma table for synhronic actions | ||
1497 | */ | ||
1498 | static int sep_free_dma_table_data_handler(struct sep_device *sep) | ||
1499 | { | ||
1500 | dbg("SEP Driver:--------> sep_free_dma_table_data_handler start\n"); | ||
1501 | |||
1502 | /* free input pages array */ | ||
1503 | sep_free_dma_pages(sep->in_page_array, sep->in_num_pages, 0); | ||
1504 | |||
1505 | /* free output pages array if needed */ | ||
1506 | if (sep->out_page_array) | ||
1507 | sep_free_dma_pages(sep->out_page_array, sep->out_num_pages, 1); | ||
1508 | |||
1509 | /* reset all the values */ | ||
1510 | sep->in_page_array = 0; | ||
1511 | sep->out_page_array = 0; | ||
1512 | sep->in_num_pages = 0; | ||
1513 | sep->out_num_pages = 0; | ||
1514 | dbg("SEP Driver:<-------- sep_free_dma_table_data_handler end\n"); | ||
1515 | return 0; | ||
1516 | } | ||
1517 | |||
1518 | /* | ||
1519 | this function find a space for the new flow dma table | ||
1520 | */ | ||
1521 | static int sep_find_free_flow_dma_table_space(struct sep_device *sep, | ||
1522 | unsigned long **table_address_ptr) | ||
1523 | { | ||
1524 | int error = 0; | ||
1525 | /* pointer to the id field of the flow dma table */ | ||
1526 | unsigned long *start_table_ptr; | ||
1527 | /* Do not make start_addr unsigned long * unless fixing the offset | ||
1528 | computations ! */ | ||
1529 | void *flow_dma_area_start_addr; | ||
1530 | unsigned long *flow_dma_area_end_addr; | ||
1531 | /* maximum table size in words */ | ||
1532 | unsigned long table_size_in_words; | ||
1533 | |||
1534 | /* find the start address of the flow DMA table area */ | ||
1535 | flow_dma_area_start_addr = sep->shared_addr + SEP_DRIVER_FLOW_DMA_TABLES_AREA_OFFSET_IN_BYTES; | ||
1536 | |||
1537 | /* set end address of the flow table area */ | ||
1538 | flow_dma_area_end_addr = flow_dma_area_start_addr + SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES; | ||
1539 | |||
1540 | /* set table size in words */ | ||
1541 | table_size_in_words = SEP_DRIVER_MAX_FLOW_NUM_ENTRIES_IN_TABLE * (sizeof(struct sep_lli_entry_t) / sizeof(long)) + 2; | ||
1542 | |||
1543 | /* set the pointer to the start address of DMA area */ | ||
1544 | start_table_ptr = flow_dma_area_start_addr; | ||
1545 | |||
1546 | /* find the space for the next table */ | ||
1547 | while (((*start_table_ptr & 0x7FFFFFFF) != 0) && start_table_ptr < flow_dma_area_end_addr) | ||
1548 | start_table_ptr += table_size_in_words; | ||
1549 | |||
1550 | /* check if we reached the end of floa tables area */ | ||
1551 | if (start_table_ptr >= flow_dma_area_end_addr) | ||
1552 | error = -1; | ||
1553 | else | ||
1554 | *table_address_ptr = start_table_ptr; | ||
1555 | |||
1556 | return error; | ||
1557 | } | ||
1558 | |||
1559 | /* | ||
1560 | This function creates one DMA table for flow and returns its data, | ||
1561 | and pointer to its info entry | ||
1562 | */ | ||
1563 | static int sep_prepare_one_flow_dma_table(struct sep_device *sep, | ||
1564 | unsigned long virt_buff_addr, | ||
1565 | unsigned long virt_buff_size, | ||
1566 | struct sep_lli_entry_t *table_data, | ||
1567 | struct sep_lli_entry_t **info_entry_ptr, | ||
1568 | struct sep_flow_context_t *flow_data_ptr, | ||
1569 | bool isKernelVirtualAddress) | ||
1570 | { | ||
1571 | int error; | ||
1572 | /* the range in pages */ | ||
1573 | unsigned long lli_array_size; | ||
1574 | struct sep_lli_entry_t *lli_array; | ||
1575 | struct sep_lli_entry_t *flow_dma_table_entry_ptr; | ||
1576 | unsigned long *start_dma_table_ptr; | ||
1577 | /* total table data counter */ | ||
1578 | unsigned long dma_table_data_count; | ||
1579 | /* pointer that will keep the pointer to the pages of the virtual buffer */ | ||
1580 | struct page **page_array_ptr; | ||
1581 | unsigned long entry_count; | ||
1582 | |||
1583 | /* find the space for the new table */ | ||
1584 | error = sep_find_free_flow_dma_table_space(sep, &start_dma_table_ptr); | ||
1585 | if (error) | ||
1586 | goto end_function; | ||
1587 | |||
1588 | /* check if the pages are in Kernel Virtual Address layout */ | ||
1589 | if (isKernelVirtualAddress == true) | ||
1590 | /* lock kernel buffer in the memory */ | ||
1591 | error = sep_lock_kernel_pages(sep, virt_buff_addr, virt_buff_size, &lli_array_size, &lli_array, &page_array_ptr); | ||
1592 | else | ||
1593 | /* lock user buffer in the memory */ | ||
1594 | error = sep_lock_user_pages(sep, virt_buff_addr, virt_buff_size, &lli_array_size, &lli_array, &page_array_ptr); | ||
1595 | |||
1596 | if (error) | ||
1597 | goto end_function; | ||
1598 | |||
1599 | /* set the pointer to page array at the beginning of table - this table is | ||
1600 | now considered taken */ | ||
1601 | *start_dma_table_ptr = lli_array_size; | ||
1602 | |||
1603 | /* point to the place of the pages pointers of the table */ | ||
1604 | start_dma_table_ptr++; | ||
1605 | |||
1606 | /* set the pages pointer */ | ||
1607 | *start_dma_table_ptr = (unsigned long) page_array_ptr; | ||
1608 | |||
1609 | /* set the pointer to the first entry */ | ||
1610 | flow_dma_table_entry_ptr = (struct sep_lli_entry_t *) (++start_dma_table_ptr); | ||
1611 | |||
1612 | /* now create the entries for table */ | ||
1613 | for (dma_table_data_count = entry_count = 0; entry_count < lli_array_size; entry_count++) { | ||
1614 | flow_dma_table_entry_ptr->physical_address = lli_array[entry_count].physical_address; | ||
1615 | |||
1616 | flow_dma_table_entry_ptr->block_size = lli_array[entry_count].block_size; | ||
1617 | |||
1618 | /* set the total data of a table */ | ||
1619 | dma_table_data_count += lli_array[entry_count].block_size; | ||
1620 | |||
1621 | flow_dma_table_entry_ptr++; | ||
1622 | } | ||
1623 | |||
1624 | /* set the physical address */ | ||
1625 | table_data->physical_address = virt_to_phys(start_dma_table_ptr); | ||
1626 | |||
1627 | /* set the num_entries and total data size */ | ||
1628 | table_data->block_size = ((lli_array_size + 1) << SEP_NUM_ENTRIES_OFFSET_IN_BITS) | (dma_table_data_count); | ||
1629 | |||
1630 | /* set the info entry */ | ||
1631 | flow_dma_table_entry_ptr->physical_address = 0xffffffff; | ||
1632 | flow_dma_table_entry_ptr->block_size = 0; | ||
1633 | |||
1634 | /* set the pointer to info entry */ | ||
1635 | *info_entry_ptr = flow_dma_table_entry_ptr; | ||
1636 | |||
1637 | /* the array of the lli entries */ | ||
1638 | kfree(lli_array); | ||
1639 | end_function: | ||
1640 | return error; | ||
1641 | } | ||
1642 | |||
1643 | |||
1644 | |||
1645 | /* | ||
1646 | This function creates a list of tables for flow and returns the data for | ||
1647 | the first and last tables of the list | ||
1648 | */ | ||
1649 | static int sep_prepare_flow_dma_tables(struct sep_device *sep, | ||
1650 | unsigned long num_virtual_buffers, | ||
1651 | unsigned long first_buff_addr, struct sep_flow_context_t *flow_data_ptr, struct sep_lli_entry_t *first_table_data_ptr, struct sep_lli_entry_t *last_table_data_ptr, bool isKernelVirtualAddress) | ||
1652 | { | ||
1653 | int error; | ||
1654 | unsigned long virt_buff_addr; | ||
1655 | unsigned long virt_buff_size; | ||
1656 | struct sep_lli_entry_t table_data; | ||
1657 | struct sep_lli_entry_t *info_entry_ptr; | ||
1658 | struct sep_lli_entry_t *prev_info_entry_ptr; | ||
1659 | unsigned long i; | ||
1660 | |||
1661 | /* init vars */ | ||
1662 | error = 0; | ||
1663 | prev_info_entry_ptr = 0; | ||
1664 | |||
1665 | /* init the first table to default */ | ||
1666 | table_data.physical_address = 0xffffffff; | ||
1667 | first_table_data_ptr->physical_address = 0xffffffff; | ||
1668 | table_data.block_size = 0; | ||
1669 | |||
1670 | for (i = 0; i < num_virtual_buffers; i++) { | ||
1671 | /* get the virtual buffer address */ | ||
1672 | error = get_user(virt_buff_addr, &first_buff_addr); | ||
1673 | if (error) | ||
1674 | goto end_function; | ||
1675 | |||
1676 | /* get the virtual buffer size */ | ||
1677 | first_buff_addr++; | ||
1678 | error = get_user(virt_buff_size, &first_buff_addr); | ||
1679 | if (error) | ||
1680 | goto end_function; | ||
1681 | |||
1682 | /* advance the address to point to the next pair of address|size */ | ||
1683 | first_buff_addr++; | ||
1684 | |||
1685 | /* now prepare the one flow LLI table from the data */ | ||
1686 | error = sep_prepare_one_flow_dma_table(sep, virt_buff_addr, virt_buff_size, &table_data, &info_entry_ptr, flow_data_ptr, isKernelVirtualAddress); | ||
1687 | if (error) | ||
1688 | goto end_function; | ||
1689 | |||
1690 | if (i == 0) { | ||
1691 | /* if this is the first table - save it to return to the user | ||
1692 | application */ | ||
1693 | *first_table_data_ptr = table_data; | ||
1694 | |||
1695 | /* set the pointer to info entry */ | ||
1696 | prev_info_entry_ptr = info_entry_ptr; | ||
1697 | } else { | ||
1698 | /* not first table - the previous table info entry should | ||
1699 | be updated */ | ||
1700 | prev_info_entry_ptr->block_size = (0x1 << SEP_INT_FLAG_OFFSET_IN_BITS) | (table_data.block_size); | ||
1701 | |||
1702 | /* set the pointer to info entry */ | ||
1703 | prev_info_entry_ptr = info_entry_ptr; | ||
1704 | } | ||
1705 | } | ||
1706 | |||
1707 | /* set the last table data */ | ||
1708 | *last_table_data_ptr = table_data; | ||
1709 | end_function: | ||
1710 | return error; | ||
1711 | } | ||
1712 | |||
1713 | /* | ||
1714 | this function goes over all the flow tables connected to the given | ||
1715 | table and deallocate them | ||
1716 | */ | ||
1717 | static void sep_deallocated_flow_tables(struct sep_lli_entry_t *first_table_ptr) | ||
1718 | { | ||
1719 | /* id pointer */ | ||
1720 | unsigned long *table_ptr; | ||
1721 | /* end address of the flow dma area */ | ||
1722 | unsigned long num_entries; | ||
1723 | unsigned long num_pages; | ||
1724 | struct page **pages_ptr; | ||
1725 | /* maximum table size in words */ | ||
1726 | struct sep_lli_entry_t *info_entry_ptr; | ||
1727 | |||
1728 | /* set the pointer to the first table */ | ||
1729 | table_ptr = (unsigned long *) first_table_ptr->physical_address; | ||
1730 | |||
1731 | /* set the num of entries */ | ||
1732 | num_entries = (first_table_ptr->block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) | ||
1733 | & SEP_NUM_ENTRIES_MASK; | ||
1734 | |||
1735 | /* go over all the connected tables */ | ||
1736 | while (*table_ptr != 0xffffffff) { | ||
1737 | /* get number of pages */ | ||
1738 | num_pages = *(table_ptr - 2); | ||
1739 | |||
1740 | /* get the pointer to the pages */ | ||
1741 | pages_ptr = (struct page **) (*(table_ptr - 1)); | ||
1742 | |||
1743 | /* free the pages */ | ||
1744 | sep_free_dma_pages(pages_ptr, num_pages, 1); | ||
1745 | |||
1746 | /* goto to the info entry */ | ||
1747 | info_entry_ptr = ((struct sep_lli_entry_t *) table_ptr) + (num_entries - 1); | ||
1748 | |||
1749 | table_ptr = (unsigned long *) info_entry_ptr->physical_address; | ||
1750 | num_entries = (info_entry_ptr->block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK; | ||
1751 | } | ||
1752 | |||
1753 | return; | ||
1754 | } | ||
1755 | |||
1756 | /** | ||
1757 | * sep_find_flow_context - find a flow | ||
1758 | * @sep: the SEP we are working with | ||
1759 | * @flow_id: flow identifier | ||
1760 | * | ||
1761 | * Returns a pointer the matching flow, or NULL if the flow does not | ||
1762 | * exist. | ||
1763 | */ | ||
1764 | |||
1765 | static struct sep_flow_context_t *sep_find_flow_context(struct sep_device *sep, | ||
1766 | unsigned long flow_id) | ||
1767 | { | ||
1768 | int count; | ||
1769 | /* | ||
1770 | * always search for flow with id default first - in case we | ||
1771 | * already started working on the flow there can be no situation | ||
1772 | * when 2 flows are with default flag | ||
1773 | */ | ||
1774 | for (count = 0; count < SEP_DRIVER_NUM_FLOWS; count++) { | ||
1775 | if (sep->flows[count].flow_id == flow_id) | ||
1776 | return &sep->flows[count]; | ||
1777 | } | ||
1778 | return NULL; | ||
1779 | } | ||
1780 | |||
1781 | |||
1782 | /* | ||
1783 | this function handles the request to create the DMA tables for flow | ||
1784 | */ | ||
1785 | static int sep_create_flow_dma_tables_handler(struct sep_device *sep, | ||
1786 | unsigned long arg) | ||
1787 | { | ||
1788 | int error = -ENOENT; | ||
1789 | struct sep_driver_build_flow_table_t command_args; | ||
1790 | /* first table - output */ | ||
1791 | struct sep_lli_entry_t first_table_data; | ||
1792 | /* dma table data */ | ||
1793 | struct sep_lli_entry_t last_table_data; | ||
1794 | /* pointer to the info entry of the previuos DMA table */ | ||
1795 | struct sep_lli_entry_t *prev_info_entry_ptr; | ||
1796 | /* pointer to the flow data strucutre */ | ||
1797 | struct sep_flow_context_t *flow_context_ptr; | ||
1798 | |||
1799 | dbg("SEP Driver:--------> sep_create_flow_dma_tables_handler start\n"); | ||
1800 | |||
1801 | /* init variables */ | ||
1802 | prev_info_entry_ptr = 0; | ||
1803 | first_table_data.physical_address = 0xffffffff; | ||
1804 | |||
1805 | /* find the free structure for flow data */ | ||
1806 | error = -EINVAL; | ||
1807 | flow_context_ptr = sep_find_flow_context(sep, SEP_FREE_FLOW_ID); | ||
1808 | if (flow_context_ptr == NULL) | ||
1809 | goto end_function; | ||
1810 | |||
1811 | error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_build_flow_table_t)); | ||
1812 | if (error) { | ||
1813 | error = -EFAULT; | ||
1814 | goto end_function; | ||
1815 | } | ||
1816 | |||
1817 | /* create flow tables */ | ||
1818 | error = sep_prepare_flow_dma_tables(sep, command_args.num_virtual_buffers, command_args.virt_buff_data_addr, flow_context_ptr, &first_table_data, &last_table_data, command_args.isKernelVirtualAddress); | ||
1819 | if (error) | ||
1820 | goto end_function_with_error; | ||
1821 | |||
1822 | /* check if flow is static */ | ||
1823 | if (!command_args.flow_type) | ||
1824 | /* point the info entry of the last to the info entry of the first */ | ||
1825 | last_table_data = first_table_data; | ||
1826 | |||
1827 | /* set output params */ | ||
1828 | command_args.first_table_addr = first_table_data.physical_address; | ||
1829 | command_args.first_table_num_entries = ((first_table_data.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK); | ||
1830 | command_args.first_table_data_size = (first_table_data.block_size & SEP_TABLE_DATA_SIZE_MASK); | ||
1831 | |||
1832 | /* send the parameters to user application */ | ||
1833 | error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_build_flow_table_t)); | ||
1834 | if (error) { | ||
1835 | error = -EFAULT; | ||
1836 | goto end_function_with_error; | ||
1837 | } | ||
1838 | |||
1839 | /* all the flow created - update the flow entry with temp id */ | ||
1840 | flow_context_ptr->flow_id = SEP_TEMP_FLOW_ID; | ||
1841 | |||
1842 | /* set the processing tables data in the context */ | ||
1843 | if (command_args.input_output_flag == SEP_DRIVER_IN_FLAG) | ||
1844 | flow_context_ptr->input_tables_in_process = first_table_data; | ||
1845 | else | ||
1846 | flow_context_ptr->output_tables_in_process = first_table_data; | ||
1847 | |||
1848 | goto end_function; | ||
1849 | |||
1850 | end_function_with_error: | ||
1851 | /* free the allocated tables */ | ||
1852 | sep_deallocated_flow_tables(&first_table_data); | ||
1853 | end_function: | ||
1854 | dbg("SEP Driver:<-------- sep_create_flow_dma_tables_handler end\n"); | ||
1855 | return error; | ||
1856 | } | ||
1857 | |||
1858 | /* | ||
1859 | this function handles add tables to flow | ||
1860 | */ | ||
1861 | static int sep_add_flow_tables_handler(struct sep_device *sep, unsigned long arg) | ||
1862 | { | ||
1863 | int error; | ||
1864 | unsigned long num_entries; | ||
1865 | struct sep_driver_add_flow_table_t command_args; | ||
1866 | struct sep_flow_context_t *flow_context_ptr; | ||
1867 | /* first dma table data */ | ||
1868 | struct sep_lli_entry_t first_table_data; | ||
1869 | /* last dma table data */ | ||
1870 | struct sep_lli_entry_t last_table_data; | ||
1871 | /* pointer to the info entry of the current DMA table */ | ||
1872 | struct sep_lli_entry_t *info_entry_ptr; | ||
1873 | |||
1874 | dbg("SEP Driver:--------> sep_add_flow_tables_handler start\n"); | ||
1875 | |||
1876 | /* get input parameters */ | ||
1877 | error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_add_flow_table_t)); | ||
1878 | if (error) { | ||
1879 | error = -EFAULT; | ||
1880 | goto end_function; | ||
1881 | } | ||
1882 | |||
1883 | /* find the flow structure for the flow id */ | ||
1884 | flow_context_ptr = sep_find_flow_context(sep, command_args.flow_id); | ||
1885 | if (flow_context_ptr == NULL) | ||
1886 | goto end_function; | ||
1887 | |||
1888 | /* prepare the flow dma tables */ | ||
1889 | error = sep_prepare_flow_dma_tables(sep, command_args.num_virtual_buffers, command_args.virt_buff_data_addr, flow_context_ptr, &first_table_data, &last_table_data, command_args.isKernelVirtualAddress); | ||
1890 | if (error) | ||
1891 | goto end_function_with_error; | ||
1892 | |||
1893 | /* now check if there is already an existing add table for this flow */ | ||
1894 | if (command_args.inputOutputFlag == SEP_DRIVER_IN_FLAG) { | ||
1895 | /* this buffer was for input buffers */ | ||
1896 | if (flow_context_ptr->input_tables_flag) { | ||
1897 | /* add table already exists - add the new tables to the end | ||
1898 | of the previous */ | ||
1899 | num_entries = (flow_context_ptr->last_input_table.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK; | ||
1900 | |||
1901 | info_entry_ptr = (struct sep_lli_entry_t *) | ||
1902 | (flow_context_ptr->last_input_table.physical_address + (sizeof(struct sep_lli_entry_t) * (num_entries - 1))); | ||
1903 | |||
1904 | /* connect to list of tables */ | ||
1905 | *info_entry_ptr = first_table_data; | ||
1906 | |||
1907 | /* set the first table data */ | ||
1908 | first_table_data = flow_context_ptr->first_input_table; | ||
1909 | } else { | ||
1910 | /* set the input flag */ | ||
1911 | flow_context_ptr->input_tables_flag = 1; | ||
1912 | |||
1913 | /* set the first table data */ | ||
1914 | flow_context_ptr->first_input_table = first_table_data; | ||
1915 | } | ||
1916 | /* set the last table data */ | ||
1917 | flow_context_ptr->last_input_table = last_table_data; | ||
1918 | } else { /* this is output tables */ | ||
1919 | |||
1920 | /* this buffer was for input buffers */ | ||
1921 | if (flow_context_ptr->output_tables_flag) { | ||
1922 | /* add table already exists - add the new tables to | ||
1923 | the end of the previous */ | ||
1924 | num_entries = (flow_context_ptr->last_output_table.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK; | ||
1925 | |||
1926 | info_entry_ptr = (struct sep_lli_entry_t *) | ||
1927 | (flow_context_ptr->last_output_table.physical_address + (sizeof(struct sep_lli_entry_t) * (num_entries - 1))); | ||
1928 | |||
1929 | /* connect to list of tables */ | ||
1930 | *info_entry_ptr = first_table_data; | ||
1931 | |||
1932 | /* set the first table data */ | ||
1933 | first_table_data = flow_context_ptr->first_output_table; | ||
1934 | } else { | ||
1935 | /* set the input flag */ | ||
1936 | flow_context_ptr->output_tables_flag = 1; | ||
1937 | |||
1938 | /* set the first table data */ | ||
1939 | flow_context_ptr->first_output_table = first_table_data; | ||
1940 | } | ||
1941 | /* set the last table data */ | ||
1942 | flow_context_ptr->last_output_table = last_table_data; | ||
1943 | } | ||
1944 | |||
1945 | /* set output params */ | ||
1946 | command_args.first_table_addr = first_table_data.physical_address; | ||
1947 | command_args.first_table_num_entries = ((first_table_data.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK); | ||
1948 | command_args.first_table_data_size = (first_table_data.block_size & SEP_TABLE_DATA_SIZE_MASK); | ||
1949 | |||
1950 | /* send the parameters to user application */ | ||
1951 | error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_add_flow_table_t)); | ||
1952 | if (error) | ||
1953 | error = -EFAULT; | ||
1954 | end_function_with_error: | ||
1955 | /* free the allocated tables */ | ||
1956 | sep_deallocated_flow_tables(&first_table_data); | ||
1957 | end_function: | ||
1958 | dbg("SEP Driver:<-------- sep_add_flow_tables_handler end\n"); | ||
1959 | return error; | ||
1960 | } | ||
1961 | |||
1962 | /* | ||
1963 | this function add the flow add message to the specific flow | ||
1964 | */ | ||
1965 | static int sep_add_flow_tables_message_handler(struct sep_device *sep, unsigned long arg) | ||
1966 | { | ||
1967 | int error; | ||
1968 | struct sep_driver_add_message_t command_args; | ||
1969 | struct sep_flow_context_t *flow_context_ptr; | ||
1970 | |||
1971 | dbg("SEP Driver:--------> sep_add_flow_tables_message_handler start\n"); | ||
1972 | |||
1973 | error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_add_message_t)); | ||
1974 | if (error) { | ||
1975 | error = -EFAULT; | ||
1976 | goto end_function; | ||
1977 | } | ||
1978 | |||
1979 | /* check input */ | ||
1980 | if (command_args.message_size_in_bytes > SEP_MAX_ADD_MESSAGE_LENGTH_IN_BYTES) { | ||
1981 | error = -ENOMEM; | ||
1982 | goto end_function; | ||
1983 | } | ||
1984 | |||
1985 | /* find the flow context */ | ||
1986 | flow_context_ptr = sep_find_flow_context(sep, command_args.flow_id); | ||
1987 | if (flow_context_ptr == NULL) | ||
1988 | goto end_function; | ||
1989 | |||
1990 | /* copy the message into context */ | ||
1991 | flow_context_ptr->message_size_in_bytes = command_args.message_size_in_bytes; | ||
1992 | error = copy_from_user(flow_context_ptr->message, (void *) command_args.message_address, command_args.message_size_in_bytes); | ||
1993 | if (error) | ||
1994 | error = -EFAULT; | ||
1995 | end_function: | ||
1996 | dbg("SEP Driver:<-------- sep_add_flow_tables_message_handler end\n"); | ||
1997 | return error; | ||
1998 | } | ||
1999 | |||
2000 | |||
2001 | /* | ||
2002 | this function returns the bus and virtual addresses of the static pool | ||
2003 | */ | ||
2004 | static int sep_get_static_pool_addr_handler(struct sep_device *sep, unsigned long arg) | ||
2005 | { | ||
2006 | int error; | ||
2007 | struct sep_driver_static_pool_addr_t command_args; | ||
2008 | |||
2009 | dbg("SEP Driver:--------> sep_get_static_pool_addr_handler start\n"); | ||
2010 | |||
2011 | /*prepare the output parameters in the struct */ | ||
2012 | command_args.physical_static_address = sep->shared_bus + SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES; | ||
2013 | command_args.virtual_static_address = (unsigned long)sep->shared_addr + SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES; | ||
2014 | |||
2015 | edbg("SEP Driver:bus_static_address is %08lx, virtual_static_address %08lx\n", command_args.physical_static_address, command_args.virtual_static_address); | ||
2016 | |||
2017 | /* send the parameters to user application */ | ||
2018 | error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_static_pool_addr_t)); | ||
2019 | if (error) | ||
2020 | error = -EFAULT; | ||
2021 | dbg("SEP Driver:<-------- sep_get_static_pool_addr_handler end\n"); | ||
2022 | return error; | ||
2023 | } | ||
2024 | |||
2025 | /* | ||
2026 | this address gets the offset of the physical address from the start | ||
2027 | of the mapped area | ||
2028 | */ | ||
2029 | static int sep_get_physical_mapped_offset_handler(struct sep_device *sep, unsigned long arg) | ||
2030 | { | ||
2031 | int error; | ||
2032 | struct sep_driver_get_mapped_offset_t command_args; | ||
2033 | |||
2034 | dbg("SEP Driver:--------> sep_get_physical_mapped_offset_handler start\n"); | ||
2035 | |||
2036 | error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_get_mapped_offset_t)); | ||
2037 | if (error) { | ||
2038 | error = -EFAULT; | ||
2039 | goto end_function; | ||
2040 | } | ||
2041 | |||
2042 | if (command_args.physical_address < sep->shared_bus) { | ||
2043 | error = -EINVAL; | ||
2044 | goto end_function; | ||
2045 | } | ||
2046 | |||
2047 | /*prepare the output parameters in the struct */ | ||
2048 | command_args.offset = command_args.physical_address - sep->shared_bus; | ||
2049 | |||
2050 | edbg("SEP Driver:bus_address is %08lx, offset is %lu\n", command_args.physical_address, command_args.offset); | ||
2051 | |||
2052 | /* send the parameters to user application */ | ||
2053 | error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_get_mapped_offset_t)); | ||
2054 | if (error) | ||
2055 | error = -EFAULT; | ||
2056 | end_function: | ||
2057 | dbg("SEP Driver:<-------- sep_get_physical_mapped_offset_handler end\n"); | ||
2058 | return error; | ||
2059 | } | ||
2060 | |||
2061 | |||
2062 | /* | ||
2063 | ? | ||
2064 | */ | ||
2065 | static int sep_start_handler(struct sep_device *sep) | ||
2066 | { | ||
2067 | unsigned long reg_val; | ||
2068 | unsigned long error = 0; | ||
2069 | |||
2070 | dbg("SEP Driver:--------> sep_start_handler start\n"); | ||
2071 | |||
2072 | /* wait in polling for message from SEP */ | ||
2073 | do | ||
2074 | reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); | ||
2075 | while (!reg_val); | ||
2076 | |||
2077 | /* check the value */ | ||
2078 | if (reg_val == 0x1) | ||
2079 | /* fatal error - read error status from GPRO */ | ||
2080 | error = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR); | ||
2081 | dbg("SEP Driver:<-------- sep_start_handler end\n"); | ||
2082 | return error; | ||
2083 | } | ||
2084 | |||
2085 | /* | ||
2086 | this function handles the request for SEP initialization | ||
2087 | */ | ||
2088 | static int sep_init_handler(struct sep_device *sep, unsigned long arg) | ||
2089 | { | ||
2090 | unsigned long message_word; | ||
2091 | unsigned long *message_ptr; | ||
2092 | struct sep_driver_init_t command_args; | ||
2093 | unsigned long counter; | ||
2094 | unsigned long error; | ||
2095 | unsigned long reg_val; | ||
2096 | |||
2097 | dbg("SEP Driver:--------> sep_init_handler start\n"); | ||
2098 | error = 0; | ||
2099 | |||
2100 | error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_init_t)); | ||
2101 | if (error) { | ||
2102 | error = -EFAULT; | ||
2103 | goto end_function; | ||
2104 | } | ||
2105 | dbg("SEP Driver:--------> sep_init_handler - finished copy_from_user\n"); | ||
2106 | |||
2107 | /* PATCH - configure the DMA to single -burst instead of multi-burst */ | ||
2108 | /*sep_configure_dma_burst(); */ | ||
2109 | |||
2110 | dbg("SEP Driver:--------> sep_init_handler - finished sep_configure_dma_burst \n"); | ||
2111 | |||
2112 | message_ptr = (unsigned long *) command_args.message_addr; | ||
2113 | |||
2114 | /* set the base address of the SRAM */ | ||
2115 | sep_write_reg(sep, HW_SRAM_ADDR_REG_ADDR, HW_CC_SRAM_BASE_ADDRESS); | ||
2116 | |||
2117 | for (counter = 0; counter < command_args.message_size_in_words; counter++, message_ptr++) { | ||
2118 | get_user(message_word, message_ptr); | ||
2119 | /* write data to SRAM */ | ||
2120 | sep_write_reg(sep, HW_SRAM_DATA_REG_ADDR, message_word); | ||
2121 | edbg("SEP Driver:message_word is %lu\n", message_word); | ||
2122 | /* wait for write complete */ | ||
2123 | sep_wait_sram_write(sep); | ||
2124 | } | ||
2125 | dbg("SEP Driver:--------> sep_init_handler - finished getting messages from user space\n"); | ||
2126 | /* signal SEP */ | ||
2127 | sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x1); | ||
2128 | |||
2129 | do | ||
2130 | reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); | ||
2131 | while (!(reg_val & 0xFFFFFFFD)); | ||
2132 | |||
2133 | dbg("SEP Driver:--------> sep_init_handler - finished waiting for reg_val & 0xFFFFFFFD \n"); | ||
2134 | |||
2135 | /* check the value */ | ||
2136 | if (reg_val == 0x1) { | ||
2137 | edbg("SEP Driver:init failed\n"); | ||
2138 | |||
2139 | error = sep_read_reg(sep, 0x8060); | ||
2140 | edbg("SEP Driver:sw monitor is %lu\n", error); | ||
2141 | |||
2142 | /* fatal error - read erro status from GPRO */ | ||
2143 | error = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR); | ||
2144 | edbg("SEP Driver:error is %lu\n", error); | ||
2145 | } | ||
2146 | end_function: | ||
2147 | dbg("SEP Driver:<-------- sep_init_handler end\n"); | ||
2148 | return error; | ||
2149 | |||
2150 | } | ||
2151 | |||
2152 | /* | ||
2153 | this function handles the request cache and resident reallocation | ||
2154 | */ | ||
2155 | static int sep_realloc_cache_resident_handler(struct sep_device *sep, | ||
2156 | unsigned long arg) | ||
2157 | { | ||
2158 | struct sep_driver_realloc_cache_resident_t command_args; | ||
2159 | int error; | ||
2160 | |||
2161 | /* copy cache and resident to the their intended locations */ | ||
2162 | error = sep_load_firmware(sep); | ||
2163 | if (error) | ||
2164 | return error; | ||
2165 | |||
2166 | command_args.new_base_addr = sep->shared_bus; | ||
2167 | |||
2168 | /* find the new base address according to the lowest address between | ||
2169 | cache, resident and shared area */ | ||
2170 | if (sep->resident_bus < command_args.new_base_addr) | ||
2171 | command_args.new_base_addr = sep->resident_bus; | ||
2172 | if (sep->rar_bus < command_args.new_base_addr) | ||
2173 | command_args.new_base_addr = sep->rar_bus; | ||
2174 | |||
2175 | /* set the return parameters */ | ||
2176 | command_args.new_cache_addr = sep->rar_bus; | ||
2177 | command_args.new_resident_addr = sep->resident_bus; | ||
2178 | |||
2179 | /* set the new shared area */ | ||
2180 | command_args.new_shared_area_addr = sep->shared_bus; | ||
2181 | |||
2182 | edbg("SEP Driver:command_args.new_shared_addr is %08llx\n", command_args.new_shared_area_addr); | ||
2183 | edbg("SEP Driver:command_args.new_base_addr is %08llx\n", command_args.new_base_addr); | ||
2184 | edbg("SEP Driver:command_args.new_resident_addr is %08llx\n", command_args.new_resident_addr); | ||
2185 | edbg("SEP Driver:command_args.new_rar_addr is %08llx\n", command_args.new_cache_addr); | ||
2186 | |||
2187 | /* return to user */ | ||
2188 | if (copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_realloc_cache_resident_t))) | ||
2189 | return -EFAULT; | ||
2190 | return 0; | ||
2191 | } | ||
2192 | |||
2193 | /** | ||
2194 | * sep_get_time_handler - time request from user space | ||
2195 | * @sep: sep we are to set the time for | ||
2196 | * @arg: pointer to user space arg buffer | ||
2197 | * | ||
2198 | * This function reports back the time and the address in the SEP | ||
2199 | * shared buffer at which it has been placed. (Do we really need this!!!) | ||
2200 | */ | ||
2201 | |||
2202 | static int sep_get_time_handler(struct sep_device *sep, unsigned long arg) | ||
2203 | { | ||
2204 | struct sep_driver_get_time_t command_args; | ||
2205 | |||
2206 | mutex_lock(&sep_mutex); | ||
2207 | command_args.time_value = sep_set_time(sep); | ||
2208 | command_args.time_physical_address = (unsigned long)sep_time_address(sep); | ||
2209 | mutex_unlock(&sep_mutex); | ||
2210 | if (copy_to_user((void __user *)arg, | ||
2211 | &command_args, sizeof(struct sep_driver_get_time_t))) | ||
2212 | return -EFAULT; | ||
2213 | return 0; | ||
2214 | |||
2215 | } | ||
2216 | |||
2217 | /* | ||
2218 | This API handles the end transaction request | ||
2219 | */ | ||
2220 | static int sep_end_transaction_handler(struct sep_device *sep, unsigned long arg) | ||
2221 | { | ||
2222 | dbg("SEP Driver:--------> sep_end_transaction_handler start\n"); | ||
2223 | |||
2224 | #if 0 /*!SEP_DRIVER_POLLING_MODE */ | ||
2225 | /* close IMR */ | ||
2226 | sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, 0x7FFF); | ||
2227 | |||
2228 | /* release IRQ line */ | ||
2229 | free_irq(SEP_DIRVER_IRQ_NUM, sep); | ||
2230 | |||
2231 | /* lock the sep mutex */ | ||
2232 | mutex_unlock(&sep_mutex); | ||
2233 | #endif | ||
2234 | |||
2235 | dbg("SEP Driver:<-------- sep_end_transaction_handler end\n"); | ||
2236 | |||
2237 | return 0; | ||
2238 | } | ||
2239 | |||
2240 | |||
2241 | /** | ||
2242 | * sep_set_flow_id_handler - handle flow setting | ||
2243 | * @sep: the SEP we are configuring | ||
2244 | * @flow_id: the flow we are setting | ||
2245 | * | ||
2246 | * This function handler the set flow id command | ||
2247 | */ | ||
2248 | static int sep_set_flow_id_handler(struct sep_device *sep, | ||
2249 | unsigned long flow_id) | ||
2250 | { | ||
2251 | int error = 0; | ||
2252 | struct sep_flow_context_t *flow_data_ptr; | ||
2253 | |||
2254 | /* find the flow data structure that was just used for creating new flow | ||
2255 | - its id should be default */ | ||
2256 | |||
2257 | mutex_lock(&sep_mutex); | ||
2258 | flow_data_ptr = sep_find_flow_context(sep, SEP_TEMP_FLOW_ID); | ||
2259 | if (flow_data_ptr) | ||
2260 | flow_data_ptr->flow_id = flow_id; /* set flow id */ | ||
2261 | else | ||
2262 | error = -EINVAL; | ||
2263 | mutex_unlock(&sep_mutex); | ||
2264 | return error; | ||
2265 | } | ||
2266 | |||
2267 | static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | ||
2268 | { | ||
2269 | int error = 0; | ||
2270 | struct sep_device *sep = filp->private_data; | ||
2271 | |||
2272 | dbg("------------>SEP Driver: ioctl start\n"); | ||
2273 | |||
2274 | edbg("SEP Driver: cmd is %x\n", cmd); | ||
2275 | |||
2276 | switch (cmd) { | ||
2277 | case SEP_IOCSENDSEPCOMMAND: | ||
2278 | /* send command to SEP */ | ||
2279 | sep_send_command_handler(sep); | ||
2280 | edbg("SEP Driver: after sep_send_command_handler\n"); | ||
2281 | break; | ||
2282 | case SEP_IOCSENDSEPRPLYCOMMAND: | ||
2283 | /* send reply command to SEP */ | ||
2284 | sep_send_reply_command_handler(sep); | ||
2285 | break; | ||
2286 | case SEP_IOCALLOCDATAPOLL: | ||
2287 | /* allocate data pool */ | ||
2288 | error = sep_allocate_data_pool_memory_handler(sep, arg); | ||
2289 | break; | ||
2290 | case SEP_IOCWRITEDATAPOLL: | ||
2291 | /* write data into memory pool */ | ||
2292 | error = sep_write_into_data_pool_handler(sep, arg); | ||
2293 | break; | ||
2294 | case SEP_IOCREADDATAPOLL: | ||
2295 | /* read data from data pool into application memory */ | ||
2296 | error = sep_read_from_data_pool_handler(sep, arg); | ||
2297 | break; | ||
2298 | case SEP_IOCCREATESYMDMATABLE: | ||
2299 | /* create dma table for synhronic operation */ | ||
2300 | error = sep_create_sync_dma_tables_handler(sep, arg); | ||
2301 | break; | ||
2302 | case SEP_IOCCREATEFLOWDMATABLE: | ||
2303 | /* create flow dma tables */ | ||
2304 | error = sep_create_flow_dma_tables_handler(sep, arg); | ||
2305 | break; | ||
2306 | case SEP_IOCFREEDMATABLEDATA: | ||
2307 | /* free the pages */ | ||
2308 | error = sep_free_dma_table_data_handler(sep); | ||
2309 | break; | ||
2310 | case SEP_IOCSETFLOWID: | ||
2311 | /* set flow id */ | ||
2312 | error = sep_set_flow_id_handler(sep, (unsigned long)arg); | ||
2313 | break; | ||
2314 | case SEP_IOCADDFLOWTABLE: | ||
2315 | /* add tables to the dynamic flow */ | ||
2316 | error = sep_add_flow_tables_handler(sep, arg); | ||
2317 | break; | ||
2318 | case SEP_IOCADDFLOWMESSAGE: | ||
2319 | /* add message of add tables to flow */ | ||
2320 | error = sep_add_flow_tables_message_handler(sep, arg); | ||
2321 | break; | ||
2322 | case SEP_IOCSEPSTART: | ||
2323 | /* start command to sep */ | ||
2324 | error = sep_start_handler(sep); | ||
2325 | break; | ||
2326 | case SEP_IOCSEPINIT: | ||
2327 | /* init command to sep */ | ||
2328 | error = sep_init_handler(sep, arg); | ||
2329 | break; | ||
2330 | case SEP_IOCGETSTATICPOOLADDR: | ||
2331 | /* get the physical and virtual addresses of the static pool */ | ||
2332 | error = sep_get_static_pool_addr_handler(sep, arg); | ||
2333 | break; | ||
2334 | case SEP_IOCENDTRANSACTION: | ||
2335 | error = sep_end_transaction_handler(sep, arg); | ||
2336 | break; | ||
2337 | case SEP_IOCREALLOCCACHERES: | ||
2338 | error = sep_realloc_cache_resident_handler(sep, arg); | ||
2339 | break; | ||
2340 | case SEP_IOCGETMAPPEDADDROFFSET: | ||
2341 | error = sep_get_physical_mapped_offset_handler(sep, arg); | ||
2342 | break; | ||
2343 | case SEP_IOCGETIME: | ||
2344 | error = sep_get_time_handler(sep, arg); | ||
2345 | break; | ||
2346 | default: | ||
2347 | error = -ENOTTY; | ||
2348 | break; | ||
2349 | } | ||
2350 | dbg("SEP Driver:<-------- ioctl end\n"); | ||
2351 | return error; | ||
2352 | } | ||
2353 | |||
2354 | |||
2355 | |||
2356 | #if !SEP_DRIVER_POLLING_MODE | ||
2357 | |||
2358 | /* handler for flow done interrupt */ | ||
2359 | |||
2360 | static void sep_flow_done_handler(struct work_struct *work) | ||
2361 | { | ||
2362 | struct sep_flow_context_t *flow_data_ptr; | ||
2363 | |||
2364 | /* obtain the mutex */ | ||
2365 | mutex_lock(&sep_mutex); | ||
2366 | |||
2367 | /* get the pointer to context */ | ||
2368 | flow_data_ptr = (struct sep_flow_context_t *) work; | ||
2369 | |||
2370 | /* free all the current input tables in sep */ | ||
2371 | sep_deallocated_flow_tables(&flow_data_ptr->input_tables_in_process); | ||
2372 | |||
2373 | /* free all the current tables output tables in SEP (if needed) */ | ||
2374 | if (flow_data_ptr->output_tables_in_process.physical_address != 0xffffffff) | ||
2375 | sep_deallocated_flow_tables(&flow_data_ptr->output_tables_in_process); | ||
2376 | |||
2377 | /* check if we have additional tables to be sent to SEP only input | ||
2378 | flag may be checked */ | ||
2379 | if (flow_data_ptr->input_tables_flag) { | ||
2380 | /* copy the message to the shared RAM and signal SEP */ | ||
2381 | memcpy((void *) flow_data_ptr->message, (void *) sep->shared_addr, flow_data_ptr->message_size_in_bytes); | ||
2382 | |||
2383 | sep_write_reg(sep, HW_HOST_HOST_SEP_GPR2_REG_ADDR, 0x2); | ||
2384 | } | ||
2385 | mutex_unlock(&sep_mutex); | ||
2386 | } | ||
2387 | /* | ||
2388 | interrupt handler function | ||
2389 | */ | ||
2390 | static irqreturn_t sep_inthandler(int irq, void *dev_id) | ||
2391 | { | ||
2392 | irqreturn_t int_error; | ||
2393 | unsigned long reg_val; | ||
2394 | unsigned long flow_id; | ||
2395 | struct sep_flow_context_t *flow_context_ptr; | ||
2396 | struct sep_device *sep = dev_id; | ||
2397 | |||
2398 | int_error = IRQ_HANDLED; | ||
2399 | |||
2400 | /* read the IRR register to check if this is SEP interrupt */ | ||
2401 | reg_val = sep_read_reg(sep, HW_HOST_IRR_REG_ADDR); | ||
2402 | edbg("SEP Interrupt - reg is %08lx\n", reg_val); | ||
2403 | |||
2404 | /* check if this is the flow interrupt */ | ||
2405 | if (0 /*reg_val & (0x1 << 11) */ ) { | ||
2406 | /* read GPRO to find out the which flow is done */ | ||
2407 | flow_id = sep_read_reg(sep, HW_HOST_IRR_REG_ADDR); | ||
2408 | |||
2409 | /* find the contex of the flow */ | ||
2410 | flow_context_ptr = sep_find_flow_context(sep, flow_id >> 28); | ||
2411 | if (flow_context_ptr == NULL) | ||
2412 | goto end_function_with_error; | ||
2413 | |||
2414 | /* queue the work */ | ||
2415 | INIT_WORK(&flow_context_ptr->flow_wq, sep_flow_done_handler); | ||
2416 | queue_work(sep->flow_wq, &flow_context_ptr->flow_wq); | ||
2417 | |||
2418 | } else { | ||
2419 | /* check if this is reply interrupt from SEP */ | ||
2420 | if (reg_val & (0x1 << 13)) { | ||
2421 | /* update the counter of reply messages */ | ||
2422 | sep->reply_ct++; | ||
2423 | /* wake up the waiting process */ | ||
2424 | wake_up(&sep_event); | ||
2425 | } else { | ||
2426 | int_error = IRQ_NONE; | ||
2427 | goto end_function; | ||
2428 | } | ||
2429 | } | ||
2430 | end_function_with_error: | ||
2431 | /* clear the interrupt */ | ||
2432 | sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, reg_val); | ||
2433 | end_function: | ||
2434 | return int_error; | ||
2435 | } | ||
2436 | |||
2437 | #endif | ||
2438 | |||
2439 | |||
2440 | |||
2441 | #if 0 | ||
2442 | |||
2443 | static void sep_wait_busy(struct sep_device *sep) | ||
2444 | { | ||
2445 | u32 reg; | ||
2446 | |||
2447 | do { | ||
2448 | reg = sep_read_reg(sep, HW_HOST_SEP_BUSY_REG_ADDR); | ||
2449 | } while (reg); | ||
2450 | } | ||
2451 | |||
2452 | /* | ||
2453 | PATCH for configuring the DMA to single burst instead of multi-burst | ||
2454 | */ | ||
2455 | static void sep_configure_dma_burst(struct sep_device *sep) | ||
2456 | { | ||
2457 | #define HW_AHB_RD_WR_BURSTS_REG_ADDR 0x0E10UL | ||
2458 | |||
2459 | dbg("SEP Driver:<-------- sep_configure_dma_burst start \n"); | ||
2460 | |||
2461 | /* request access to registers from SEP */ | ||
2462 | sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x2); | ||
2463 | |||
2464 | dbg("SEP Driver:<-------- sep_configure_dma_burst finished request access to registers from SEP (write reg) \n"); | ||
2465 | |||
2466 | sep_wait_busy(sep); | ||
2467 | |||
2468 | dbg("SEP Driver:<-------- sep_configure_dma_burst finished request access to registers from SEP (while(revVal) wait loop) \n"); | ||
2469 | |||
2470 | /* set the DMA burst register to single burst */ | ||
2471 | sep_write_reg(sep, HW_AHB_RD_WR_BURSTS_REG_ADDR, 0x0UL); | ||
2472 | |||
2473 | /* release the sep busy */ | ||
2474 | sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x0UL); | ||
2475 | sep_wait_busy(sep); | ||
2476 | |||
2477 | dbg("SEP Driver:<-------- sep_configure_dma_burst done \n"); | ||
2478 | |||
2479 | } | ||
2480 | |||
2481 | #endif | ||
2482 | |||
2483 | /* | ||
2484 | Function that is activated on the successful probe of the SEP device | ||
2485 | */ | ||
2486 | static int __devinit sep_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | ||
2487 | { | ||
2488 | int error = 0; | ||
2489 | struct sep_device *sep; | ||
2490 | int counter; | ||
2491 | int size; /* size of memory for allocation */ | ||
2492 | |||
2493 | edbg("Sep pci probe starting\n"); | ||
2494 | if (sep_dev != NULL) { | ||
2495 | dev_warn(&pdev->dev, "only one SEP supported.\n"); | ||
2496 | return -EBUSY; | ||
2497 | } | ||
2498 | |||
2499 | /* enable the device */ | ||
2500 | error = pci_enable_device(pdev); | ||
2501 | if (error) { | ||
2502 | edbg("error enabling pci device\n"); | ||
2503 | goto end_function; | ||
2504 | } | ||
2505 | |||
2506 | /* set the pci dev pointer */ | ||
2507 | sep_dev = &sep_instance; | ||
2508 | sep = &sep_instance; | ||
2509 | |||
2510 | edbg("sep->shared_addr = %p\n", sep->shared_addr); | ||
2511 | /* transaction counter that coordinates the transactions between SEP | ||
2512 | and HOST */ | ||
2513 | sep->send_ct = 0; | ||
2514 | /* counter for the messages from sep */ | ||
2515 | sep->reply_ct = 0; | ||
2516 | /* counter for the number of bytes allocated in the pool | ||
2517 | for the current transaction */ | ||
2518 | sep->data_pool_bytes_allocated = 0; | ||
2519 | |||
2520 | /* calculate the total size for allocation */ | ||
2521 | size = SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES + | ||
2522 | SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES + SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES + SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES + SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES; | ||
2523 | |||
2524 | /* allocate the shared area */ | ||
2525 | if (sep_map_and_alloc_shared_area(sep, size)) { | ||
2526 | error = -ENOMEM; | ||
2527 | /* allocation failed */ | ||
2528 | goto end_function_error; | ||
2529 | } | ||
2530 | /* now set the memory regions */ | ||
2531 | #if (SEP_DRIVER_RECONFIG_MESSAGE_AREA == 1) | ||
2532 | /* Note: this test section will need moving before it could ever | ||
2533 | work as the registers are not yet mapped ! */ | ||
2534 | /* send the new SHARED MESSAGE AREA to the SEP */ | ||
2535 | sep_write_reg(sep, HW_HOST_HOST_SEP_GPR1_REG_ADDR, sep->shared_bus); | ||
2536 | |||
2537 | /* poll for SEP response */ | ||
2538 | retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR); | ||
2539 | while (retval != 0xffffffff && retval != sep->shared_bus) | ||
2540 | retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR); | ||
2541 | |||
2542 | /* check the return value (register) */ | ||
2543 | if (retval != sep->shared_bus) { | ||
2544 | error = -ENOMEM; | ||
2545 | goto end_function_deallocate_sep_shared_area; | ||
2546 | } | ||
2547 | #endif | ||
2548 | /* init the flow contextes */ | ||
2549 | for (counter = 0; counter < SEP_DRIVER_NUM_FLOWS; counter++) | ||
2550 | sep->flows[counter].flow_id = SEP_FREE_FLOW_ID; | ||
2551 | |||
2552 | sep->flow_wq = create_singlethread_workqueue("sepflowwq"); | ||
2553 | if (sep->flow_wq == NULL) { | ||
2554 | error = -ENOMEM; | ||
2555 | edbg("sep_driver:flow queue creation failed\n"); | ||
2556 | goto end_function_deallocate_sep_shared_area; | ||
2557 | } | ||
2558 | edbg("SEP Driver: create flow workqueue \n"); | ||
2559 | sep->pdev = pci_dev_get(pdev); | ||
2560 | |||
2561 | sep->reg_addr = pci_ioremap_bar(pdev, 0); | ||
2562 | if (!sep->reg_addr) { | ||
2563 | edbg("sep: ioremap of registers failed.\n"); | ||
2564 | goto end_function_deallocate_sep_shared_area; | ||
2565 | } | ||
2566 | edbg("SEP Driver:reg_addr is %p\n", sep->reg_addr); | ||
2567 | |||
2568 | /* load the rom code */ | ||
2569 | sep_load_rom_code(sep); | ||
2570 | |||
2571 | /* set up system base address and shared memory location */ | ||
2572 | sep->rar_addr = dma_alloc_coherent(&sep->pdev->dev, | ||
2573 | 2 * SEP_RAR_IO_MEM_REGION_SIZE, | ||
2574 | &sep->rar_bus, GFP_KERNEL); | ||
2575 | |||
2576 | if (!sep->rar_addr) { | ||
2577 | edbg("SEP Driver:can't allocate rar\n"); | ||
2578 | goto end_function_uniomap; | ||
2579 | } | ||
2580 | |||
2581 | |||
2582 | edbg("SEP Driver:rar_bus is %08llx\n", (unsigned long long)sep->rar_bus); | ||
2583 | edbg("SEP Driver:rar_virtual is %p\n", sep->rar_addr); | ||
2584 | |||
2585 | #if !SEP_DRIVER_POLLING_MODE | ||
2586 | |||
2587 | edbg("SEP Driver: about to write IMR and ICR REG_ADDR\n"); | ||
2588 | |||
2589 | /* clear ICR register */ | ||
2590 | sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF); | ||
2591 | |||
2592 | /* set the IMR register - open only GPR 2 */ | ||
2593 | sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13))); | ||
2594 | |||
2595 | edbg("SEP Driver: about to call request_irq\n"); | ||
2596 | /* get the interrupt line */ | ||
2597 | error = request_irq(pdev->irq, sep_inthandler, IRQF_SHARED, "sep_driver", sep); | ||
2598 | if (error) | ||
2599 | goto end_function_free_res; | ||
2600 | return 0; | ||
2601 | edbg("SEP Driver: about to write IMR REG_ADDR"); | ||
2602 | |||
2603 | /* set the IMR register - open only GPR 2 */ | ||
2604 | sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13))); | ||
2605 | |||
2606 | end_function_free_res: | ||
2607 | dma_free_coherent(&sep->pdev->dev, 2 * SEP_RAR_IO_MEM_REGION_SIZE, | ||
2608 | sep->rar_addr, sep->rar_bus); | ||
2609 | #endif /* SEP_DRIVER_POLLING_MODE */ | ||
2610 | end_function_uniomap: | ||
2611 | iounmap(sep->reg_addr); | ||
2612 | end_function_deallocate_sep_shared_area: | ||
2613 | /* de-allocate shared area */ | ||
2614 | sep_unmap_and_free_shared_area(sep, size); | ||
2615 | end_function_error: | ||
2616 | sep_dev = NULL; | ||
2617 | end_function: | ||
2618 | return error; | ||
2619 | } | ||
2620 | |||
2621 | static const struct pci_device_id sep_pci_id_tbl[] = { | ||
2622 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080c)}, | ||
2623 | {0} | ||
2624 | }; | ||
2625 | |||
2626 | MODULE_DEVICE_TABLE(pci, sep_pci_id_tbl); | ||
2627 | |||
2628 | /* field for registering driver to PCI device */ | ||
2629 | static struct pci_driver sep_pci_driver = { | ||
2630 | .name = "sep_sec_driver", | ||
2631 | .id_table = sep_pci_id_tbl, | ||
2632 | .probe = sep_probe | ||
2633 | /* FIXME: remove handler */ | ||
2634 | }; | ||
2635 | |||
2636 | /* major and minor device numbers */ | ||
2637 | static dev_t sep_devno; | ||
2638 | |||
2639 | /* the files operations structure of the driver */ | ||
2640 | static struct file_operations sep_file_operations = { | ||
2641 | .owner = THIS_MODULE, | ||
2642 | .unlocked_ioctl = sep_ioctl, | ||
2643 | .poll = sep_poll, | ||
2644 | .open = sep_open, | ||
2645 | .release = sep_release, | ||
2646 | .mmap = sep_mmap, | ||
2647 | }; | ||
2648 | |||
2649 | |||
2650 | /* cdev struct of the driver */ | ||
2651 | static struct cdev sep_cdev; | ||
2652 | |||
2653 | /* | ||
2654 | this function registers the driver to the file system | ||
2655 | */ | ||
2656 | static int sep_register_driver_to_fs(void) | ||
2657 | { | ||
2658 | int ret_val = alloc_chrdev_region(&sep_devno, 0, 1, "sep_sec_driver"); | ||
2659 | if (ret_val) { | ||
2660 | edbg("sep: major number allocation failed, retval is %d\n", | ||
2661 | ret_val); | ||
2662 | return ret_val; | ||
2663 | } | ||
2664 | /* init cdev */ | ||
2665 | cdev_init(&sep_cdev, &sep_file_operations); | ||
2666 | sep_cdev.owner = THIS_MODULE; | ||
2667 | |||
2668 | /* register the driver with the kernel */ | ||
2669 | ret_val = cdev_add(&sep_cdev, sep_devno, 1); | ||
2670 | if (ret_val) { | ||
2671 | edbg("sep_driver:cdev_add failed, retval is %d\n", ret_val); | ||
2672 | /* unregister dev numbers */ | ||
2673 | unregister_chrdev_region(sep_devno, 1); | ||
2674 | } | ||
2675 | return ret_val; | ||
2676 | } | ||
2677 | |||
2678 | |||
2679 | /*-------------------------------------------------------------- | ||
2680 | init function | ||
2681 | ----------------------------------------------------------------*/ | ||
2682 | static int __init sep_init(void) | ||
2683 | { | ||
2684 | int ret_val = 0; | ||
2685 | dbg("SEP Driver:-------->Init start\n"); | ||
2686 | /* FIXME: Probe can occur before we are ready to survive a probe */ | ||
2687 | ret_val = pci_register_driver(&sep_pci_driver); | ||
2688 | if (ret_val) { | ||
2689 | edbg("sep_driver:sep_driver_to_device failed, ret_val is %d\n", ret_val); | ||
2690 | goto end_function_unregister_from_fs; | ||
2691 | } | ||
2692 | /* register driver to fs */ | ||
2693 | ret_val = sep_register_driver_to_fs(); | ||
2694 | if (ret_val) | ||
2695 | goto end_function_unregister_pci; | ||
2696 | goto end_function; | ||
2697 | end_function_unregister_pci: | ||
2698 | pci_unregister_driver(&sep_pci_driver); | ||
2699 | end_function_unregister_from_fs: | ||
2700 | /* unregister from fs */ | ||
2701 | cdev_del(&sep_cdev); | ||
2702 | /* unregister dev numbers */ | ||
2703 | unregister_chrdev_region(sep_devno, 1); | ||
2704 | end_function: | ||
2705 | dbg("SEP Driver:<-------- Init end\n"); | ||
2706 | return ret_val; | ||
2707 | } | ||
2708 | |||
2709 | |||
2710 | /*------------------------------------------------------------- | ||
2711 | exit function | ||
2712 | --------------------------------------------------------------*/ | ||
2713 | static void __exit sep_exit(void) | ||
2714 | { | ||
2715 | int size; | ||
2716 | |||
2717 | dbg("SEP Driver:--------> Exit start\n"); | ||
2718 | |||
2719 | /* unregister from fs */ | ||
2720 | cdev_del(&sep_cdev); | ||
2721 | /* unregister dev numbers */ | ||
2722 | unregister_chrdev_region(sep_devno, 1); | ||
2723 | /* calculate the total size for de-allocation */ | ||
2724 | size = SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES + | ||
2725 | SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES + SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES + SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES + SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES; | ||
2726 | /* FIXME: We need to do this in the unload for the device */ | ||
2727 | /* free shared area */ | ||
2728 | if (sep_dev) { | ||
2729 | sep_unmap_and_free_shared_area(sep_dev, size); | ||
2730 | edbg("SEP Driver: free pages SEP SHARED AREA \n"); | ||
2731 | iounmap((void *) sep_dev->reg_addr); | ||
2732 | edbg("SEP Driver: iounmap \n"); | ||
2733 | } | ||
2734 | edbg("SEP Driver: release_mem_region \n"); | ||
2735 | dbg("SEP Driver:<-------- Exit end\n"); | ||
2736 | } | ||
2737 | |||
2738 | |||
2739 | module_init(sep_init); | ||
2740 | module_exit(sep_exit); | ||
2741 | |||
2742 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/staging/sep/sep_driver_api.h b/drivers/staging/sep/sep_driver_api.h deleted file mode 100644 index 7ef16da7c4e..00000000000 --- a/drivers/staging/sep/sep_driver_api.h +++ /dev/null | |||
@@ -1,425 +0,0 @@ | |||
1 | /* | ||
2 | * | ||
3 | * sep_driver_api.h - Security Processor Driver api definitions | ||
4 | * | ||
5 | * Copyright(c) 2009 Intel Corporation. All rights reserved. | ||
6 | * Copyright(c) 2009 Discretix. All rights reserved. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the Free | ||
10 | * Software Foundation; either version 2 of the License, or (at your option) | ||
11 | * any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
16 | * more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License along with | ||
19 | * this program; if not, write to the Free Software Foundation, Inc., 59 | ||
20 | * Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
21 | * | ||
22 | * CONTACTS: | ||
23 | * | ||
24 | * Mark Allyn mark.a.allyn@intel.com | ||
25 | * | ||
26 | * CHANGES: | ||
27 | * | ||
28 | * 2009.06.26 Initial publish | ||
29 | * | ||
30 | */ | ||
31 | |||
32 | #ifndef __SEP_DRIVER_API_H__ | ||
33 | #define __SEP_DRIVER_API_H__ | ||
34 | |||
35 | |||
36 | |||
37 | /*---------------------------------------------------------------- | ||
38 | IOCTL command defines | ||
39 | -----------------------------------------------------------------*/ | ||
40 | |||
41 | /* magic number 1 of the sep IOCTL command */ | ||
42 | #define SEP_IOC_MAGIC_NUMBER 's' | ||
43 | |||
44 | /* sends interrupt to sep that message is ready */ | ||
45 | #define SEP_IOCSENDSEPCOMMAND _IO(SEP_IOC_MAGIC_NUMBER , 0) | ||
46 | |||
47 | /* sends interrupt to sep that message is ready */ | ||
48 | #define SEP_IOCSENDSEPRPLYCOMMAND _IO(SEP_IOC_MAGIC_NUMBER , 1) | ||
49 | |||
50 | /* allocate memory in data pool */ | ||
51 | #define SEP_IOCALLOCDATAPOLL _IO(SEP_IOC_MAGIC_NUMBER , 2) | ||
52 | |||
53 | /* write to pre-allocated memory in data pool */ | ||
54 | #define SEP_IOCWRITEDATAPOLL _IO(SEP_IOC_MAGIC_NUMBER , 3) | ||
55 | |||
56 | /* read from pre-allocated memory in data pool */ | ||
57 | #define SEP_IOCREADDATAPOLL _IO(SEP_IOC_MAGIC_NUMBER , 4) | ||
58 | |||
59 | /* create sym dma lli tables */ | ||
60 | #define SEP_IOCCREATESYMDMATABLE _IO(SEP_IOC_MAGIC_NUMBER , 5) | ||
61 | |||
62 | /* create flow dma lli tables */ | ||
63 | #define SEP_IOCCREATEFLOWDMATABLE _IO(SEP_IOC_MAGIC_NUMBER , 6) | ||
64 | |||
65 | /* free dynamic data aalocated during table creation */ | ||
66 | #define SEP_IOCFREEDMATABLEDATA _IO(SEP_IOC_MAGIC_NUMBER , 7) | ||
67 | |||
68 | /* get the static pool area addresses (physical and virtual) */ | ||
69 | #define SEP_IOCGETSTATICPOOLADDR _IO(SEP_IOC_MAGIC_NUMBER , 8) | ||
70 | |||
71 | /* set flow id command */ | ||
72 | #define SEP_IOCSETFLOWID _IO(SEP_IOC_MAGIC_NUMBER , 9) | ||
73 | |||
74 | /* add tables to the dynamic flow */ | ||
75 | #define SEP_IOCADDFLOWTABLE _IO(SEP_IOC_MAGIC_NUMBER , 10) | ||
76 | |||
77 | /* add flow add tables message */ | ||
78 | #define SEP_IOCADDFLOWMESSAGE _IO(SEP_IOC_MAGIC_NUMBER , 11) | ||
79 | |||
80 | /* start sep command */ | ||
81 | #define SEP_IOCSEPSTART _IO(SEP_IOC_MAGIC_NUMBER , 12) | ||
82 | |||
83 | /* init sep command */ | ||
84 | #define SEP_IOCSEPINIT _IO(SEP_IOC_MAGIC_NUMBER , 13) | ||
85 | |||
86 | /* end transaction command */ | ||
87 | #define SEP_IOCENDTRANSACTION _IO(SEP_IOC_MAGIC_NUMBER , 15) | ||
88 | |||
89 | /* reallocate cache and resident */ | ||
90 | #define SEP_IOCREALLOCCACHERES _IO(SEP_IOC_MAGIC_NUMBER , 16) | ||
91 | |||
92 | /* get the offset of the address starting from the beginnnig of the map area */ | ||
93 | #define SEP_IOCGETMAPPEDADDROFFSET _IO(SEP_IOC_MAGIC_NUMBER , 17) | ||
94 | |||
95 | /* get time address and value */ | ||
96 | #define SEP_IOCGETIME _IO(SEP_IOC_MAGIC_NUMBER , 19) | ||
97 | |||
98 | /*------------------------------------------- | ||
99 | TYPEDEFS | ||
100 | ----------------------------------------------*/ | ||
101 | |||
102 | /* | ||
103 | init command struct | ||
104 | */ | ||
105 | struct sep_driver_init_t { | ||
106 | /* start of the 1G of the host memory address that SEP can access */ | ||
107 | unsigned long message_addr; | ||
108 | |||
109 | /* start address of resident */ | ||
110 | unsigned long message_size_in_words; | ||
111 | |||
112 | }; | ||
113 | |||
114 | |||
115 | /* | ||
116 | realloc cache resident command | ||
117 | */ | ||
118 | struct sep_driver_realloc_cache_resident_t { | ||
119 | /* new cache address */ | ||
120 | u64 new_cache_addr; | ||
121 | /* new resident address */ | ||
122 | u64 new_resident_addr; | ||
123 | /* new resident address */ | ||
124 | u64 new_shared_area_addr; | ||
125 | /* new base address */ | ||
126 | u64 new_base_addr; | ||
127 | }; | ||
128 | |||
129 | struct sep_driver_alloc_t { | ||
130 | /* virtual address of allocated space */ | ||
131 | unsigned long offset; | ||
132 | |||
133 | /* physical address of allocated space */ | ||
134 | unsigned long phys_address; | ||
135 | |||
136 | /* number of bytes to allocate */ | ||
137 | unsigned long num_bytes; | ||
138 | }; | ||
139 | |||
140 | /* | ||
141 | */ | ||
142 | struct sep_driver_write_t { | ||
143 | /* application space address */ | ||
144 | unsigned long app_address; | ||
145 | |||
146 | /* address of the data pool */ | ||
147 | unsigned long datapool_address; | ||
148 | |||
149 | /* number of bytes to write */ | ||
150 | unsigned long num_bytes; | ||
151 | }; | ||
152 | |||
153 | /* | ||
154 | */ | ||
155 | struct sep_driver_read_t { | ||
156 | /* application space address */ | ||
157 | unsigned long app_address; | ||
158 | |||
159 | /* address of the data pool */ | ||
160 | unsigned long datapool_address; | ||
161 | |||
162 | /* number of bytes to read */ | ||
163 | unsigned long num_bytes; | ||
164 | }; | ||
165 | |||
166 | /* | ||
167 | */ | ||
168 | struct sep_driver_build_sync_table_t { | ||
169 | /* address value of the data in */ | ||
170 | unsigned long app_in_address; | ||
171 | |||
172 | /* size of data in */ | ||
173 | unsigned long data_in_size; | ||
174 | |||
175 | /* address of the data out */ | ||
176 | unsigned long app_out_address; | ||
177 | |||
178 | /* the size of the block of the operation - if needed, | ||
179 | every table will be modulo this parameter */ | ||
180 | unsigned long block_size; | ||
181 | |||
182 | /* the physical address of the first input DMA table */ | ||
183 | unsigned long in_table_address; | ||
184 | |||
185 | /* number of entries in the first input DMA table */ | ||
186 | unsigned long in_table_num_entries; | ||
187 | |||
188 | /* the physical address of the first output DMA table */ | ||
189 | unsigned long out_table_address; | ||
190 | |||
191 | /* number of entries in the first output DMA table */ | ||
192 | unsigned long out_table_num_entries; | ||
193 | |||
194 | /* data in the first input table */ | ||
195 | unsigned long table_data_size; | ||
196 | |||
197 | /* distinct user/kernel layout */ | ||
198 | bool isKernelVirtualAddress; | ||
199 | |||
200 | }; | ||
201 | |||
202 | /* | ||
203 | */ | ||
204 | struct sep_driver_build_flow_table_t { | ||
205 | /* flow type */ | ||
206 | unsigned long flow_type; | ||
207 | |||
208 | /* flag for input output */ | ||
209 | unsigned long input_output_flag; | ||
210 | |||
211 | /* address value of the data in */ | ||
212 | unsigned long virt_buff_data_addr; | ||
213 | |||
214 | /* size of data in */ | ||
215 | unsigned long num_virtual_buffers; | ||
216 | |||
217 | /* the physical address of the first input DMA table */ | ||
218 | unsigned long first_table_addr; | ||
219 | |||
220 | /* number of entries in the first input DMA table */ | ||
221 | unsigned long first_table_num_entries; | ||
222 | |||
223 | /* data in the first input table */ | ||
224 | unsigned long first_table_data_size; | ||
225 | |||
226 | /* distinct user/kernel layout */ | ||
227 | bool isKernelVirtualAddress; | ||
228 | }; | ||
229 | |||
230 | |||
231 | struct sep_driver_add_flow_table_t { | ||
232 | /* flow id */ | ||
233 | unsigned long flow_id; | ||
234 | |||
235 | /* flag for input output */ | ||
236 | unsigned long inputOutputFlag; | ||
237 | |||
238 | /* address value of the data in */ | ||
239 | unsigned long virt_buff_data_addr; | ||
240 | |||
241 | /* size of data in */ | ||
242 | unsigned long num_virtual_buffers; | ||
243 | |||
244 | /* address of the first table */ | ||
245 | unsigned long first_table_addr; | ||
246 | |||
247 | /* number of entries in the first table */ | ||
248 | unsigned long first_table_num_entries; | ||
249 | |||
250 | /* data size of the first table */ | ||
251 | unsigned long first_table_data_size; | ||
252 | |||
253 | /* distinct user/kernel layout */ | ||
254 | bool isKernelVirtualAddress; | ||
255 | |||
256 | }; | ||
257 | |||
258 | /* | ||
259 | command struct for set flow id | ||
260 | */ | ||
261 | struct sep_driver_set_flow_id_t { | ||
262 | /* flow id to set */ | ||
263 | unsigned long flow_id; | ||
264 | }; | ||
265 | |||
266 | |||
267 | /* command struct for add tables message */ | ||
268 | struct sep_driver_add_message_t { | ||
269 | /* flow id to set */ | ||
270 | unsigned long flow_id; | ||
271 | |||
272 | /* message size in bytes */ | ||
273 | unsigned long message_size_in_bytes; | ||
274 | |||
275 | /* address of the message */ | ||
276 | unsigned long message_address; | ||
277 | }; | ||
278 | |||
279 | /* command struct for static pool addresses */ | ||
280 | struct sep_driver_static_pool_addr_t { | ||
281 | /* physical address of the static pool */ | ||
282 | unsigned long physical_static_address; | ||
283 | |||
284 | /* virtual address of the static pool */ | ||
285 | unsigned long virtual_static_address; | ||
286 | }; | ||
287 | |||
288 | /* command struct for getiing offset of the physical address from | ||
289 | the start of the mapped area */ | ||
290 | struct sep_driver_get_mapped_offset_t { | ||
291 | /* physical address of the static pool */ | ||
292 | unsigned long physical_address; | ||
293 | |||
294 | /* virtual address of the static pool */ | ||
295 | unsigned long offset; | ||
296 | }; | ||
297 | |||
298 | /* command struct for getting time value and address */ | ||
299 | struct sep_driver_get_time_t { | ||
300 | /* physical address of stored time */ | ||
301 | unsigned long time_physical_address; | ||
302 | |||
303 | /* value of the stored time */ | ||
304 | unsigned long time_value; | ||
305 | }; | ||
306 | |||
307 | |||
308 | /* | ||
309 | structure that represent one entry in the DMA LLI table | ||
310 | */ | ||
311 | struct sep_lli_entry_t { | ||
312 | /* physical address */ | ||
313 | unsigned long physical_address; | ||
314 | |||
315 | /* block size */ | ||
316 | unsigned long block_size; | ||
317 | }; | ||
318 | |||
319 | /* | ||
320 | structure that reperesents data needed for lli table construction | ||
321 | */ | ||
322 | struct sep_lli_prepare_table_data_t { | ||
323 | /* pointer to the memory where the first lli entry to be built */ | ||
324 | struct sep_lli_entry_t *lli_entry_ptr; | ||
325 | |||
326 | /* pointer to the array of lli entries from which the table is to be built */ | ||
327 | struct sep_lli_entry_t *lli_array_ptr; | ||
328 | |||
329 | /* number of elements in lli array */ | ||
330 | int lli_array_size; | ||
331 | |||
332 | /* number of entries in the created table */ | ||
333 | int num_table_entries; | ||
334 | |||
335 | /* number of array entries processed during table creation */ | ||
336 | int num_array_entries_processed; | ||
337 | |||
338 | /* the totatl data size in the created table */ | ||
339 | int lli_table_total_data_size; | ||
340 | }; | ||
341 | |||
342 | /* | ||
343 | structure that represent tone table - it is not used in code, jkust | ||
344 | to show what table looks like | ||
345 | */ | ||
346 | struct sep_lli_table_t { | ||
347 | /* number of pages mapped in this tables. If 0 - means that the table | ||
348 | is not defined (used as a valid flag) */ | ||
349 | unsigned long num_pages; | ||
350 | /* | ||
351 | pointer to array of page pointers that represent the mapping of the | ||
352 | virtual buffer defined by the table to the physical memory. If this | ||
353 | pointer is NULL, it means that the table is not defined | ||
354 | (used as a valid flag) | ||
355 | */ | ||
356 | struct page **table_page_array_ptr; | ||
357 | |||
358 | /* maximum flow entries in table */ | ||
359 | struct sep_lli_entry_t lli_entries[SEP_DRIVER_MAX_FLOW_NUM_ENTRIES_IN_TABLE]; | ||
360 | }; | ||
361 | |||
362 | |||
363 | /* | ||
364 | structure for keeping the mapping of the virtual buffer into physical pages | ||
365 | */ | ||
366 | struct sep_flow_buffer_data { | ||
367 | /* pointer to the array of page structs pointers to the pages of the | ||
368 | virtual buffer */ | ||
369 | struct page **page_array_ptr; | ||
370 | |||
371 | /* number of pages taken by the virtual buffer */ | ||
372 | unsigned long num_pages; | ||
373 | |||
374 | /* this flag signals if this page_array is the last one among many that were | ||
375 | sent in one setting to SEP */ | ||
376 | unsigned long last_page_array_flag; | ||
377 | }; | ||
378 | |||
379 | /* | ||
380 | struct that keeps all the data for one flow | ||
381 | */ | ||
382 | struct sep_flow_context_t { | ||
383 | /* | ||
384 | work struct for handling the flow done interrupt in the workqueue | ||
385 | this structure must be in the first place, since it will be used | ||
386 | forcasting to the containing flow context | ||
387 | */ | ||
388 | struct work_struct flow_wq; | ||
389 | |||
390 | /* flow id */ | ||
391 | unsigned long flow_id; | ||
392 | |||
393 | /* additional input tables exists */ | ||
394 | unsigned long input_tables_flag; | ||
395 | |||
396 | /* additional output tables exists */ | ||
397 | unsigned long output_tables_flag; | ||
398 | |||
399 | /* data of the first input file */ | ||
400 | struct sep_lli_entry_t first_input_table; | ||
401 | |||
402 | /* data of the first output table */ | ||
403 | struct sep_lli_entry_t first_output_table; | ||
404 | |||
405 | /* last input table data */ | ||
406 | struct sep_lli_entry_t last_input_table; | ||
407 | |||
408 | /* last output table data */ | ||
409 | struct sep_lli_entry_t last_output_table; | ||
410 | |||
411 | /* first list of table */ | ||
412 | struct sep_lli_entry_t input_tables_in_process; | ||
413 | |||
414 | /* output table in process (in sep) */ | ||
415 | struct sep_lli_entry_t output_tables_in_process; | ||
416 | |||
417 | /* size of messages in bytes */ | ||
418 | unsigned long message_size_in_bytes; | ||
419 | |||
420 | /* message */ | ||
421 | unsigned char message[SEP_MAX_ADD_MESSAGE_LENGTH_IN_BYTES]; | ||
422 | }; | ||
423 | |||
424 | |||
425 | #endif | ||
diff --git a/drivers/staging/sep/sep_driver_config.h b/drivers/staging/sep/sep_driver_config.h deleted file mode 100644 index 6008fe5eca0..00000000000 --- a/drivers/staging/sep/sep_driver_config.h +++ /dev/null | |||
@@ -1,225 +0,0 @@ | |||
1 | /* | ||
2 | * | ||
3 | * sep_driver_config.h - Security Processor Driver configuration | ||
4 | * | ||
5 | * Copyright(c) 2009 Intel Corporation. All rights reserved. | ||
6 | * Copyright(c) 2009 Discretix. All rights reserved. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the Free | ||
10 | * Software Foundation; either version 2 of the License, or (at your option) | ||
11 | * any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
16 | * more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License along with | ||
19 | * this program; if not, write to the Free Software Foundation, Inc., 59 | ||
20 | * Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
21 | * | ||
22 | * CONTACTS: | ||
23 | * | ||
24 | * Mark Allyn mark.a.allyn@intel.com | ||
25 | * | ||
26 | * CHANGES: | ||
27 | * | ||
28 | * 2009.06.26 Initial publish | ||
29 | * | ||
30 | */ | ||
31 | |||
32 | #ifndef __SEP_DRIVER_CONFIG_H__ | ||
33 | #define __SEP_DRIVER_CONFIG_H__ | ||
34 | |||
35 | |||
36 | /*-------------------------------------- | ||
37 | DRIVER CONFIGURATION FLAGS | ||
38 | -------------------------------------*/ | ||
39 | |||
40 | /* if flag is on , then the driver is running in polling and | ||
41 | not interrupt mode */ | ||
42 | #define SEP_DRIVER_POLLING_MODE 1 | ||
43 | |||
44 | /* flag which defines if the shared area address should be | ||
45 | reconfiged (send to SEP anew) during init of the driver */ | ||
46 | #define SEP_DRIVER_RECONFIG_MESSAGE_AREA 0 | ||
47 | |||
48 | /* the mode for running on the ARM1172 Evaluation platform (flag is 1) */ | ||
49 | #define SEP_DRIVER_ARM_DEBUG_MODE 0 | ||
50 | |||
51 | /*------------------------------------------- | ||
52 | INTERNAL DATA CONFIGURATION | ||
53 | -------------------------------------------*/ | ||
54 | |||
55 | /* flag for the input array */ | ||
56 | #define SEP_DRIVER_IN_FLAG 0 | ||
57 | |||
58 | /* flag for output array */ | ||
59 | #define SEP_DRIVER_OUT_FLAG 1 | ||
60 | |||
61 | /* maximum number of entries in one LLI tables */ | ||
62 | #define SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP 8 | ||
63 | |||
64 | |||
65 | /*-------------------------------------------------------- | ||
66 | SHARED AREA memory total size is 36K | ||
67 | it is divided is following: | ||
68 | |||
69 | SHARED_MESSAGE_AREA 8K } | ||
70 | } | ||
71 | STATIC_POOL_AREA 4K } MAPPED AREA ( 24 K) | ||
72 | } | ||
73 | DATA_POOL_AREA 12K } | ||
74 | |||
75 | SYNCHRONIC_DMA_TABLES_AREA 5K | ||
76 | |||
77 | FLOW_DMA_TABLES_AREA 4K | ||
78 | |||
79 | SYSTEM_MEMORY_AREA 3k | ||
80 | |||
81 | SYSTEM_MEMORY total size is 3k | ||
82 | it is divided as following: | ||
83 | |||
84 | TIME_MEMORY_AREA 8B | ||
85 | -----------------------------------------------------------*/ | ||
86 | |||
87 | |||
88 | |||
89 | /* | ||
90 | the maximum length of the message - the rest of the message shared | ||
91 | area will be dedicated to the dma lli tables | ||
92 | */ | ||
93 | #define SEP_DRIVER_MAX_MESSAGE_SIZE_IN_BYTES (8 * 1024) | ||
94 | |||
95 | /* the size of the message shared area in pages */ | ||
96 | #define SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES (8 * 1024) | ||
97 | |||
98 | /* the size of the data pool static area in pages */ | ||
99 | #define SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES (4 * 1024) | ||
100 | |||
101 | /* the size of the data pool shared area size in pages */ | ||
102 | #define SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES (12 * 1024) | ||
103 | |||
104 | /* the size of the message shared area in pages */ | ||
105 | #define SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES (1024 * 5) | ||
106 | |||
107 | |||
108 | /* the size of the data pool shared area size in pages */ | ||
109 | #define SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES (1024 * 4) | ||
110 | |||
111 | /* system data (time, caller id etc') pool */ | ||
112 | #define SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES 100 | ||
113 | |||
114 | |||
115 | /* area size that is mapped - we map the MESSAGE AREA, STATIC POOL and | ||
116 | DATA POOL areas. area must be module 4k */ | ||
117 | #define SEP_DRIVER_MMMAP_AREA_SIZE (1024 * 24) | ||
118 | |||
119 | |||
120 | /*----------------------------------------------- | ||
121 | offsets of the areas starting from the shared area start address | ||
122 | */ | ||
123 | |||
124 | /* message area offset */ | ||
125 | #define SEP_DRIVER_MESSAGE_AREA_OFFSET_IN_BYTES 0 | ||
126 | |||
127 | /* static pool area offset */ | ||
128 | #define SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES \ | ||
129 | (SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES) | ||
130 | |||
131 | /* data pool area offset */ | ||
132 | #define SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES \ | ||
133 | (SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES + \ | ||
134 | SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES) | ||
135 | |||
136 | /* synhronic dma tables area offset */ | ||
137 | #define SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES \ | ||
138 | (SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + \ | ||
139 | SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES) | ||
140 | |||
141 | /* sep driver flow dma tables area offset */ | ||
142 | #define SEP_DRIVER_FLOW_DMA_TABLES_AREA_OFFSET_IN_BYTES \ | ||
143 | (SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES + \ | ||
144 | SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES) | ||
145 | |||
146 | /* system memory offset in bytes */ | ||
147 | #define SEP_DRIVER_SYSTEM_DATA_MEMORY_OFFSET_IN_BYTES \ | ||
148 | (SEP_DRIVER_FLOW_DMA_TABLES_AREA_OFFSET_IN_BYTES + \ | ||
149 | SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES) | ||
150 | |||
151 | /* offset of the time area */ | ||
152 | #define SEP_DRIVER_SYSTEM_TIME_MEMORY_OFFSET_IN_BYTES \ | ||
153 | (SEP_DRIVER_SYSTEM_DATA_MEMORY_OFFSET_IN_BYTES) | ||
154 | |||
155 | |||
156 | |||
157 | /* start physical address of the SEP registers memory in HOST */ | ||
158 | #define SEP_IO_MEM_REGION_START_ADDRESS 0x80000000 | ||
159 | |||
160 | /* size of the SEP registers memory region in HOST (for now 100 registers) */ | ||
161 | #define SEP_IO_MEM_REGION_SIZE (2 * 0x100000) | ||
162 | |||
163 | /* define the number of IRQ for SEP interrupts */ | ||
164 | #define SEP_DIRVER_IRQ_NUM 1 | ||
165 | |||
166 | /* maximum number of add buffers */ | ||
167 | #define SEP_MAX_NUM_ADD_BUFFERS 100 | ||
168 | |||
169 | /* number of flows */ | ||
170 | #define SEP_DRIVER_NUM_FLOWS 4 | ||
171 | |||
172 | /* maximum number of entries in flow table */ | ||
173 | #define SEP_DRIVER_MAX_FLOW_NUM_ENTRIES_IN_TABLE 25 | ||
174 | |||
175 | /* offset of the num entries in the block length entry of the LLI */ | ||
176 | #define SEP_NUM_ENTRIES_OFFSET_IN_BITS 24 | ||
177 | |||
178 | /* offset of the interrupt flag in the block length entry of the LLI */ | ||
179 | #define SEP_INT_FLAG_OFFSET_IN_BITS 31 | ||
180 | |||
181 | /* mask for extracting data size from LLI */ | ||
182 | #define SEP_TABLE_DATA_SIZE_MASK 0xFFFFFF | ||
183 | |||
184 | /* mask for entries after being shifted left */ | ||
185 | #define SEP_NUM_ENTRIES_MASK 0x7F | ||
186 | |||
187 | /* default flow id */ | ||
188 | #define SEP_FREE_FLOW_ID 0xFFFFFFFF | ||
189 | |||
190 | /* temp flow id used during cretiong of new flow until receiving | ||
191 | real flow id from sep */ | ||
192 | #define SEP_TEMP_FLOW_ID (SEP_DRIVER_NUM_FLOWS + 1) | ||
193 | |||
194 | /* maximum add buffers message length in bytes */ | ||
195 | #define SEP_MAX_ADD_MESSAGE_LENGTH_IN_BYTES (7 * 4) | ||
196 | |||
197 | /* maximum number of concurrent virtual buffers */ | ||
198 | #define SEP_MAX_VIRT_BUFFERS_CONCURRENT 100 | ||
199 | |||
200 | /* the token that defines the start of time address */ | ||
201 | #define SEP_TIME_VAL_TOKEN 0x12345678 | ||
202 | |||
203 | /* DEBUG LEVEL MASKS */ | ||
204 | #define SEP_DEBUG_LEVEL_BASIC 0x1 | ||
205 | |||
206 | #define SEP_DEBUG_LEVEL_EXTENDED 0x4 | ||
207 | |||
208 | |||
209 | /* Debug helpers */ | ||
210 | |||
211 | #define dbg(fmt, args...) \ | ||
212 | do {\ | ||
213 | if (debug & SEP_DEBUG_LEVEL_BASIC) \ | ||
214 | printk(KERN_DEBUG fmt, ##args); \ | ||
215 | } while(0); | ||
216 | |||
217 | #define edbg(fmt, args...) \ | ||
218 | do { \ | ||
219 | if (debug & SEP_DEBUG_LEVEL_EXTENDED) \ | ||
220 | printk(KERN_DEBUG fmt, ##args); \ | ||
221 | } while(0); | ||
222 | |||
223 | |||
224 | |||
225 | #endif | ||
diff --git a/drivers/staging/sep/sep_driver_hw_defs.h b/drivers/staging/sep/sep_driver_hw_defs.h deleted file mode 100644 index ea6abd8a14b..00000000000 --- a/drivers/staging/sep/sep_driver_hw_defs.h +++ /dev/null | |||
@@ -1,232 +0,0 @@ | |||
1 | /* | ||
2 | * | ||
3 | * sep_driver_hw_defs.h - Security Processor Driver hardware definitions | ||
4 | * | ||
5 | * Copyright(c) 2009 Intel Corporation. All rights reserved. | ||
6 | * Copyright(c) 2009 Discretix. All rights reserved. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the Free | ||
10 | * Software Foundation; either version 2 of the License, or (at your option) | ||
11 | * any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
16 | * more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License along with | ||
19 | * this program; if not, write to the Free Software Foundation, Inc., 59 | ||
20 | * Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
21 | * | ||
22 | * CONTACTS: | ||
23 | * | ||
24 | * Mark Allyn mark.a.allyn@intel.com | ||
25 | * | ||
26 | * CHANGES: | ||
27 | * | ||
28 | * 2009.06.26 Initial publish | ||
29 | * | ||
30 | */ | ||
31 | |||
32 | #ifndef SEP_DRIVER_HW_DEFS__H | ||
33 | #define SEP_DRIVER_HW_DEFS__H | ||
34 | |||
35 | /*--------------------------------------------------------------------------*/ | ||
36 | /* Abstract: HW Registers Defines. */ | ||
37 | /* */ | ||
38 | /* Note: This file was automatically created !!! */ | ||
39 | /* DO NOT EDIT THIS FILE !!! */ | ||
40 | /*--------------------------------------------------------------------------*/ | ||
41 | |||
42 | |||
43 | /* cf registers */ | ||
44 | #define HW_R0B_ADDR_0_REG_ADDR 0x0000UL | ||
45 | #define HW_R0B_ADDR_1_REG_ADDR 0x0004UL | ||
46 | #define HW_R0B_ADDR_2_REG_ADDR 0x0008UL | ||
47 | #define HW_R0B_ADDR_3_REG_ADDR 0x000cUL | ||
48 | #define HW_R0B_ADDR_4_REG_ADDR 0x0010UL | ||
49 | #define HW_R0B_ADDR_5_REG_ADDR 0x0014UL | ||
50 | #define HW_R0B_ADDR_6_REG_ADDR 0x0018UL | ||
51 | #define HW_R0B_ADDR_7_REG_ADDR 0x001cUL | ||
52 | #define HW_R0B_ADDR_8_REG_ADDR 0x0020UL | ||
53 | #define HW_R2B_ADDR_0_REG_ADDR 0x0080UL | ||
54 | #define HW_R2B_ADDR_1_REG_ADDR 0x0084UL | ||
55 | #define HW_R2B_ADDR_2_REG_ADDR 0x0088UL | ||
56 | #define HW_R2B_ADDR_3_REG_ADDR 0x008cUL | ||
57 | #define HW_R2B_ADDR_4_REG_ADDR 0x0090UL | ||
58 | #define HW_R2B_ADDR_5_REG_ADDR 0x0094UL | ||
59 | #define HW_R2B_ADDR_6_REG_ADDR 0x0098UL | ||
60 | #define HW_R2B_ADDR_7_REG_ADDR 0x009cUL | ||
61 | #define HW_R2B_ADDR_8_REG_ADDR 0x00a0UL | ||
62 | #define HW_R3B_REG_ADDR 0x00C0UL | ||
63 | #define HW_R4B_REG_ADDR 0x0100UL | ||
64 | #define HW_CSA_ADDR_0_REG_ADDR 0x0140UL | ||
65 | #define HW_CSA_ADDR_1_REG_ADDR 0x0144UL | ||
66 | #define HW_CSA_ADDR_2_REG_ADDR 0x0148UL | ||
67 | #define HW_CSA_ADDR_3_REG_ADDR 0x014cUL | ||
68 | #define HW_CSA_ADDR_4_REG_ADDR 0x0150UL | ||
69 | #define HW_CSA_ADDR_5_REG_ADDR 0x0154UL | ||
70 | #define HW_CSA_ADDR_6_REG_ADDR 0x0158UL | ||
71 | #define HW_CSA_ADDR_7_REG_ADDR 0x015cUL | ||
72 | #define HW_CSA_ADDR_8_REG_ADDR 0x0160UL | ||
73 | #define HW_CSA_REG_ADDR 0x0140UL | ||
74 | #define HW_SINB_REG_ADDR 0x0180UL | ||
75 | #define HW_SOUTB_REG_ADDR 0x0184UL | ||
76 | #define HW_PKI_CONTROL_REG_ADDR 0x01C0UL | ||
77 | #define HW_PKI_STATUS_REG_ADDR 0x01C4UL | ||
78 | #define HW_PKI_BUSY_REG_ADDR 0x01C8UL | ||
79 | #define HW_PKI_A_1025_REG_ADDR 0x01CCUL | ||
80 | #define HW_PKI_SDMA_CTL_REG_ADDR 0x01D0UL | ||
81 | #define HW_PKI_SDMA_OFFSET_REG_ADDR 0x01D4UL | ||
82 | #define HW_PKI_SDMA_POINTERS_REG_ADDR 0x01D8UL | ||
83 | #define HW_PKI_SDMA_DLENG_REG_ADDR 0x01DCUL | ||
84 | #define HW_PKI_SDMA_EXP_POINTERS_REG_ADDR 0x01E0UL | ||
85 | #define HW_PKI_SDMA_RES_POINTERS_REG_ADDR 0x01E4UL | ||
86 | #define HW_PKI_CLR_REG_ADDR 0x01E8UL | ||
87 | #define HW_PKI_SDMA_BUSY_REG_ADDR 0x01E8UL | ||
88 | #define HW_PKI_SDMA_FIRST_EXP_N_REG_ADDR 0x01ECUL | ||
89 | #define HW_PKI_SDMA_MUL_BY1_REG_ADDR 0x01F0UL | ||
90 | #define HW_PKI_SDMA_RMUL_SEL_REG_ADDR 0x01F4UL | ||
91 | #define HW_DES_KEY_0_REG_ADDR 0x0208UL | ||
92 | #define HW_DES_KEY_1_REG_ADDR 0x020CUL | ||
93 | #define HW_DES_KEY_2_REG_ADDR 0x0210UL | ||
94 | #define HW_DES_KEY_3_REG_ADDR 0x0214UL | ||
95 | #define HW_DES_KEY_4_REG_ADDR 0x0218UL | ||
96 | #define HW_DES_KEY_5_REG_ADDR 0x021CUL | ||
97 | #define HW_DES_CONTROL_0_REG_ADDR 0x0220UL | ||
98 | #define HW_DES_CONTROL_1_REG_ADDR 0x0224UL | ||
99 | #define HW_DES_IV_0_REG_ADDR 0x0228UL | ||
100 | #define HW_DES_IV_1_REG_ADDR 0x022CUL | ||
101 | #define HW_AES_KEY_0_ADDR_0_REG_ADDR 0x0400UL | ||
102 | #define HW_AES_KEY_0_ADDR_1_REG_ADDR 0x0404UL | ||
103 | #define HW_AES_KEY_0_ADDR_2_REG_ADDR 0x0408UL | ||
104 | #define HW_AES_KEY_0_ADDR_3_REG_ADDR 0x040cUL | ||
105 | #define HW_AES_KEY_0_ADDR_4_REG_ADDR 0x0410UL | ||
106 | #define HW_AES_KEY_0_ADDR_5_REG_ADDR 0x0414UL | ||
107 | #define HW_AES_KEY_0_ADDR_6_REG_ADDR 0x0418UL | ||
108 | #define HW_AES_KEY_0_ADDR_7_REG_ADDR 0x041cUL | ||
109 | #define HW_AES_KEY_0_REG_ADDR 0x0400UL | ||
110 | #define HW_AES_IV_0_ADDR_0_REG_ADDR 0x0440UL | ||
111 | #define HW_AES_IV_0_ADDR_1_REG_ADDR 0x0444UL | ||
112 | #define HW_AES_IV_0_ADDR_2_REG_ADDR 0x0448UL | ||
113 | #define HW_AES_IV_0_ADDR_3_REG_ADDR 0x044cUL | ||
114 | #define HW_AES_IV_0_REG_ADDR 0x0440UL | ||
115 | #define HW_AES_CTR1_ADDR_0_REG_ADDR 0x0460UL | ||
116 | #define HW_AES_CTR1_ADDR_1_REG_ADDR 0x0464UL | ||
117 | #define HW_AES_CTR1_ADDR_2_REG_ADDR 0x0468UL | ||
118 | #define HW_AES_CTR1_ADDR_3_REG_ADDR 0x046cUL | ||
119 | #define HW_AES_CTR1_REG_ADDR 0x0460UL | ||
120 | #define HW_AES_SK_REG_ADDR 0x0478UL | ||
121 | #define HW_AES_MAC_OK_REG_ADDR 0x0480UL | ||
122 | #define HW_AES_PREV_IV_0_ADDR_0_REG_ADDR 0x0490UL | ||
123 | #define HW_AES_PREV_IV_0_ADDR_1_REG_ADDR 0x0494UL | ||
124 | #define HW_AES_PREV_IV_0_ADDR_2_REG_ADDR 0x0498UL | ||
125 | #define HW_AES_PREV_IV_0_ADDR_3_REG_ADDR 0x049cUL | ||
126 | #define HW_AES_PREV_IV_0_REG_ADDR 0x0490UL | ||
127 | #define HW_AES_CONTROL_REG_ADDR 0x04C0UL | ||
128 | #define HW_HASH_H0_REG_ADDR 0x0640UL | ||
129 | #define HW_HASH_H1_REG_ADDR 0x0644UL | ||
130 | #define HW_HASH_H2_REG_ADDR 0x0648UL | ||
131 | #define HW_HASH_H3_REG_ADDR 0x064CUL | ||
132 | #define HW_HASH_H4_REG_ADDR 0x0650UL | ||
133 | #define HW_HASH_H5_REG_ADDR 0x0654UL | ||
134 | #define HW_HASH_H6_REG_ADDR 0x0658UL | ||
135 | #define HW_HASH_H7_REG_ADDR 0x065CUL | ||
136 | #define HW_HASH_H8_REG_ADDR 0x0660UL | ||
137 | #define HW_HASH_H9_REG_ADDR 0x0664UL | ||
138 | #define HW_HASH_H10_REG_ADDR 0x0668UL | ||
139 | #define HW_HASH_H11_REG_ADDR 0x066CUL | ||
140 | #define HW_HASH_H12_REG_ADDR 0x0670UL | ||
141 | #define HW_HASH_H13_REG_ADDR 0x0674UL | ||
142 | #define HW_HASH_H14_REG_ADDR 0x0678UL | ||
143 | #define HW_HASH_H15_REG_ADDR 0x067CUL | ||
144 | #define HW_HASH_CONTROL_REG_ADDR 0x07C0UL | ||
145 | #define HW_HASH_PAD_EN_REG_ADDR 0x07C4UL | ||
146 | #define HW_HASH_PAD_CFG_REG_ADDR 0x07C8UL | ||
147 | #define HW_HASH_CUR_LEN_0_REG_ADDR 0x07CCUL | ||
148 | #define HW_HASH_CUR_LEN_1_REG_ADDR 0x07D0UL | ||
149 | #define HW_HASH_CUR_LEN_2_REG_ADDR 0x07D4UL | ||
150 | #define HW_HASH_CUR_LEN_3_REG_ADDR 0x07D8UL | ||
151 | #define HW_HASH_PARAM_REG_ADDR 0x07DCUL | ||
152 | #define HW_HASH_INT_BUSY_REG_ADDR 0x07E0UL | ||
153 | #define HW_HASH_SW_RESET_REG_ADDR 0x07E4UL | ||
154 | #define HW_HASH_ENDIANESS_REG_ADDR 0x07E8UL | ||
155 | #define HW_HASH_DATA_REG_ADDR 0x07ECUL | ||
156 | #define HW_DRNG_CONTROL_REG_ADDR 0x0800UL | ||
157 | #define HW_DRNG_VALID_REG_ADDR 0x0804UL | ||
158 | #define HW_DRNG_DATA_REG_ADDR 0x0808UL | ||
159 | #define HW_RND_SRC_EN_REG_ADDR 0x080CUL | ||
160 | #define HW_AES_CLK_ENABLE_REG_ADDR 0x0810UL | ||
161 | #define HW_DES_CLK_ENABLE_REG_ADDR 0x0814UL | ||
162 | #define HW_HASH_CLK_ENABLE_REG_ADDR 0x0818UL | ||
163 | #define HW_PKI_CLK_ENABLE_REG_ADDR 0x081CUL | ||
164 | #define HW_CLK_STATUS_REG_ADDR 0x0824UL | ||
165 | #define HW_CLK_ENABLE_REG_ADDR 0x0828UL | ||
166 | #define HW_DRNG_SAMPLE_REG_ADDR 0x0850UL | ||
167 | #define HW_RND_SRC_CTL_REG_ADDR 0x0858UL | ||
168 | #define HW_CRYPTO_CTL_REG_ADDR 0x0900UL | ||
169 | #define HW_CRYPTO_STATUS_REG_ADDR 0x090CUL | ||
170 | #define HW_CRYPTO_BUSY_REG_ADDR 0x0910UL | ||
171 | #define HW_AES_BUSY_REG_ADDR 0x0914UL | ||
172 | #define HW_DES_BUSY_REG_ADDR 0x0918UL | ||
173 | #define HW_HASH_BUSY_REG_ADDR 0x091CUL | ||
174 | #define HW_CONTENT_REG_ADDR 0x0924UL | ||
175 | #define HW_VERSION_REG_ADDR 0x0928UL | ||
176 | #define HW_CONTEXT_ID_REG_ADDR 0x0930UL | ||
177 | #define HW_DIN_BUFFER_REG_ADDR 0x0C00UL | ||
178 | #define HW_DIN_MEM_DMA_BUSY_REG_ADDR 0x0c20UL | ||
179 | #define HW_SRC_LLI_MEM_ADDR_REG_ADDR 0x0c24UL | ||
180 | #define HW_SRC_LLI_WORD0_REG_ADDR 0x0C28UL | ||
181 | #define HW_SRC_LLI_WORD1_REG_ADDR 0x0C2CUL | ||
182 | #define HW_SRAM_SRC_ADDR_REG_ADDR 0x0c30UL | ||
183 | #define HW_DIN_SRAM_BYTES_LEN_REG_ADDR 0x0c34UL | ||
184 | #define HW_DIN_SRAM_DMA_BUSY_REG_ADDR 0x0C38UL | ||
185 | #define HW_WRITE_ALIGN_REG_ADDR 0x0C3CUL | ||
186 | #define HW_OLD_DATA_REG_ADDR 0x0C48UL | ||
187 | #define HW_WRITE_ALIGN_LAST_REG_ADDR 0x0C4CUL | ||
188 | #define HW_DOUT_BUFFER_REG_ADDR 0x0C00UL | ||
189 | #define HW_DST_LLI_WORD0_REG_ADDR 0x0D28UL | ||
190 | #define HW_DST_LLI_WORD1_REG_ADDR 0x0D2CUL | ||
191 | #define HW_DST_LLI_MEM_ADDR_REG_ADDR 0x0D24UL | ||
192 | #define HW_DOUT_MEM_DMA_BUSY_REG_ADDR 0x0D20UL | ||
193 | #define HW_SRAM_DEST_ADDR_REG_ADDR 0x0D30UL | ||
194 | #define HW_DOUT_SRAM_BYTES_LEN_REG_ADDR 0x0D34UL | ||
195 | #define HW_DOUT_SRAM_DMA_BUSY_REG_ADDR 0x0D38UL | ||
196 | #define HW_READ_ALIGN_REG_ADDR 0x0D3CUL | ||
197 | #define HW_READ_LAST_DATA_REG_ADDR 0x0D44UL | ||
198 | #define HW_RC4_THRU_CPU_REG_ADDR 0x0D4CUL | ||
199 | #define HW_AHB_SINGLE_REG_ADDR 0x0E00UL | ||
200 | #define HW_SRAM_DATA_REG_ADDR 0x0F00UL | ||
201 | #define HW_SRAM_ADDR_REG_ADDR 0x0F04UL | ||
202 | #define HW_SRAM_DATA_READY_REG_ADDR 0x0F08UL | ||
203 | #define HW_HOST_IRR_REG_ADDR 0x0A00UL | ||
204 | #define HW_HOST_IMR_REG_ADDR 0x0A04UL | ||
205 | #define HW_HOST_ICR_REG_ADDR 0x0A08UL | ||
206 | #define HW_HOST_SEP_SRAM_THRESHOLD_REG_ADDR 0x0A10UL | ||
207 | #define HW_HOST_SEP_BUSY_REG_ADDR 0x0A14UL | ||
208 | #define HW_HOST_SEP_LCS_REG_ADDR 0x0A18UL | ||
209 | #define HW_HOST_CC_SW_RST_REG_ADDR 0x0A40UL | ||
210 | #define HW_HOST_SEP_SW_RST_REG_ADDR 0x0A44UL | ||
211 | #define HW_HOST_FLOW_DMA_SW_INT0_REG_ADDR 0x0A80UL | ||
212 | #define HW_HOST_FLOW_DMA_SW_INT1_REG_ADDR 0x0A84UL | ||
213 | #define HW_HOST_FLOW_DMA_SW_INT2_REG_ADDR 0x0A88UL | ||
214 | #define HW_HOST_FLOW_DMA_SW_INT3_REG_ADDR 0x0A8cUL | ||
215 | #define HW_HOST_FLOW_DMA_SW_INT4_REG_ADDR 0x0A90UL | ||
216 | #define HW_HOST_FLOW_DMA_SW_INT5_REG_ADDR 0x0A94UL | ||
217 | #define HW_HOST_FLOW_DMA_SW_INT6_REG_ADDR 0x0A98UL | ||
218 | #define HW_HOST_FLOW_DMA_SW_INT7_REG_ADDR 0x0A9cUL | ||
219 | #define HW_HOST_SEP_HOST_GPR0_REG_ADDR 0x0B00UL | ||
220 | #define HW_HOST_SEP_HOST_GPR1_REG_ADDR 0x0B04UL | ||
221 | #define HW_HOST_SEP_HOST_GPR2_REG_ADDR 0x0B08UL | ||
222 | #define HW_HOST_SEP_HOST_GPR3_REG_ADDR 0x0B0CUL | ||
223 | #define HW_HOST_HOST_SEP_GPR0_REG_ADDR 0x0B80UL | ||
224 | #define HW_HOST_HOST_SEP_GPR1_REG_ADDR 0x0B84UL | ||
225 | #define HW_HOST_HOST_SEP_GPR2_REG_ADDR 0x0B88UL | ||
226 | #define HW_HOST_HOST_SEP_GPR3_REG_ADDR 0x0B8CUL | ||
227 | #define HW_HOST_HOST_ENDIAN_REG_ADDR 0x0B90UL | ||
228 | #define HW_HOST_HOST_COMM_CLK_EN_REG_ADDR 0x0B94UL | ||
229 | #define HW_CLR_SRAM_BUSY_REG_REG_ADDR 0x0F0CUL | ||
230 | #define HW_CC_SRAM_BASE_ADDRESS 0x5800UL | ||
231 | |||
232 | #endif /* ifndef HW_DEFS */ | ||
diff --git a/drivers/staging/spectra/Kconfig b/drivers/staging/spectra/Kconfig index 5e2ffefb60a..d231ae27299 100644 --- a/drivers/staging/spectra/Kconfig +++ b/drivers/staging/spectra/Kconfig | |||
@@ -2,6 +2,7 @@ | |||
2 | menuconfig SPECTRA | 2 | menuconfig SPECTRA |
3 | tristate "Denali Spectra Flash Translation Layer" | 3 | tristate "Denali Spectra Flash Translation Layer" |
4 | depends on BLOCK | 4 | depends on BLOCK |
5 | depends on X86_MRST | ||
5 | default n | 6 | default n |
6 | ---help--- | 7 | ---help--- |
7 | Enable the FTL pseudo-filesystem used with the NAND Flash | 8 | Enable the FTL pseudo-filesystem used with the NAND Flash |
diff --git a/drivers/staging/spectra/ffsport.c b/drivers/staging/spectra/ffsport.c index d0c5c97eda3..fa21a0fd8e8 100644 --- a/drivers/staging/spectra/ffsport.c +++ b/drivers/staging/spectra/ffsport.c | |||
@@ -27,6 +27,8 @@ | |||
27 | #include <linux/kthread.h> | 27 | #include <linux/kthread.h> |
28 | #include <linux/log2.h> | 28 | #include <linux/log2.h> |
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/smp_lock.h> | ||
31 | #include <linux/slab.h> | ||
30 | 32 | ||
31 | /**** Helper functions used for Div, Remainder operation on u64 ****/ | 33 | /**** Helper functions used for Div, Remainder operation on u64 ****/ |
32 | 34 | ||
@@ -113,7 +115,6 @@ u64 GLOB_u64_Remainder(u64 addr, u32 divisor_type) | |||
113 | 115 | ||
114 | #define GLOB_SBD_NAME "nd" | 116 | #define GLOB_SBD_NAME "nd" |
115 | #define GLOB_SBD_IRQ_NUM (29) | 117 | #define GLOB_SBD_IRQ_NUM (29) |
116 | #define GLOB_VERSION "driver version 20091110" | ||
117 | 118 | ||
118 | #define GLOB_SBD_IOCTL_GC (0x7701) | 119 | #define GLOB_SBD_IOCTL_GC (0x7701) |
119 | #define GLOB_SBD_IOCTL_WL (0x7702) | 120 | #define GLOB_SBD_IOCTL_WL (0x7702) |
@@ -272,13 +273,6 @@ static int get_res_blk_num_os(void) | |||
272 | return res_blks; | 273 | return res_blks; |
273 | } | 274 | } |
274 | 275 | ||
275 | static void SBD_prepare_flush(struct request_queue *q, struct request *rq) | ||
276 | { | ||
277 | rq->cmd_type = REQ_TYPE_LINUX_BLOCK; | ||
278 | /* rq->timeout = 5 * HZ; */ | ||
279 | rq->cmd[0] = REQ_LB_OP_FLUSH; | ||
280 | } | ||
281 | |||
282 | /* Transfer a full request. */ | 276 | /* Transfer a full request. */ |
283 | static int do_transfer(struct spectra_nand_dev *tr, struct request *req) | 277 | static int do_transfer(struct spectra_nand_dev *tr, struct request *req) |
284 | { | 278 | { |
@@ -296,8 +290,7 @@ static int do_transfer(struct spectra_nand_dev *tr, struct request *req) | |||
296 | IdentifyDeviceData.PagesPerBlock * | 290 | IdentifyDeviceData.PagesPerBlock * |
297 | res_blks_os; | 291 | res_blks_os; |
298 | 292 | ||
299 | if (req->cmd_type == REQ_TYPE_LINUX_BLOCK && | 293 | if (req->cmd_type & REQ_FLUSH) { |
300 | req->cmd[0] == REQ_LB_OP_FLUSH) { | ||
301 | if (force_flush_cache()) /* Fail to flush cache */ | 294 | if (force_flush_cache()) /* Fail to flush cache */ |
302 | return -EIO; | 295 | return -EIO; |
303 | else | 296 | else |
@@ -597,11 +590,23 @@ int GLOB_SBD_ioctl(struct block_device *bdev, fmode_t mode, | |||
597 | return -ENOTTY; | 590 | return -ENOTTY; |
598 | } | 591 | } |
599 | 592 | ||
593 | int GLOB_SBD_unlocked_ioctl(struct block_device *bdev, fmode_t mode, | ||
594 | unsigned int cmd, unsigned long arg) | ||
595 | { | ||
596 | int ret; | ||
597 | |||
598 | lock_kernel(); | ||
599 | ret = GLOB_SBD_ioctl(bdev, mode, cmd, arg); | ||
600 | unlock_kernel(); | ||
601 | |||
602 | return ret; | ||
603 | } | ||
604 | |||
600 | static struct block_device_operations GLOB_SBD_ops = { | 605 | static struct block_device_operations GLOB_SBD_ops = { |
601 | .owner = THIS_MODULE, | 606 | .owner = THIS_MODULE, |
602 | .open = GLOB_SBD_open, | 607 | .open = GLOB_SBD_open, |
603 | .release = GLOB_SBD_release, | 608 | .release = GLOB_SBD_release, |
604 | .locked_ioctl = GLOB_SBD_ioctl, | 609 | .ioctl = GLOB_SBD_unlocked_ioctl, |
605 | .getgeo = GLOB_SBD_getgeo, | 610 | .getgeo = GLOB_SBD_getgeo, |
606 | }; | 611 | }; |
607 | 612 | ||
@@ -650,8 +655,7 @@ static int SBD_setup_device(struct spectra_nand_dev *dev, int which) | |||
650 | /* Here we force report 512 byte hardware sector size to Kernel */ | 655 | /* Here we force report 512 byte hardware sector size to Kernel */ |
651 | blk_queue_logical_block_size(dev->queue, 512); | 656 | blk_queue_logical_block_size(dev->queue, 512); |
652 | 657 | ||
653 | blk_queue_ordered(dev->queue, QUEUE_ORDERED_DRAIN_FLUSH, | 658 | blk_queue_ordered(dev->queue, QUEUE_ORDERED_DRAIN_FLUSH); |
654 | SBD_prepare_flush); | ||
655 | 659 | ||
656 | dev->thread = kthread_run(spectra_trans_thread, dev, "nand_thd"); | 660 | dev->thread = kthread_run(spectra_trans_thread, dev, "nand_thd"); |
657 | if (IS_ERR(dev->thread)) { | 661 | if (IS_ERR(dev->thread)) { |
diff --git a/drivers/staging/spectra/flash.c b/drivers/staging/spectra/flash.c index 134aa5166a8..9b5218b6ada 100644 --- a/drivers/staging/spectra/flash.c +++ b/drivers/staging/spectra/flash.c | |||
@@ -61,7 +61,6 @@ static void FTL_Cache_Read_Page(u8 *pData, u64 dwPageAddr, | |||
61 | static void FTL_Cache_Write_Page(u8 *pData, u64 dwPageAddr, | 61 | static void FTL_Cache_Write_Page(u8 *pData, u64 dwPageAddr, |
62 | u8 cache_blk, u16 flag); | 62 | u8 cache_blk, u16 flag); |
63 | static int FTL_Cache_Write(void); | 63 | static int FTL_Cache_Write(void); |
64 | static int FTL_Cache_Write_Back(u8 *pData, u64 blk_addr); | ||
65 | static void FTL_Calculate_LRU(void); | 64 | static void FTL_Calculate_LRU(void); |
66 | static u32 FTL_Get_Block_Index(u32 wBlockNum); | 65 | static u32 FTL_Get_Block_Index(u32 wBlockNum); |
67 | 66 | ||
@@ -86,8 +85,6 @@ static u32 FTL_Replace_MWBlock(void); | |||
86 | static int FTL_Replace_Block(u64 blk_addr); | 85 | static int FTL_Replace_Block(u64 blk_addr); |
87 | static int FTL_Adjust_Relative_Erase_Count(u32 Index_of_MAX); | 86 | static int FTL_Adjust_Relative_Erase_Count(u32 Index_of_MAX); |
88 | 87 | ||
89 | static int FTL_Flash_Error_Handle(u8 *pData, u64 old_page_addr, u64 blk_addr); | ||
90 | |||
91 | struct device_info_tag DeviceInfo; | 88 | struct device_info_tag DeviceInfo; |
92 | struct flash_cache_tag Cache; | 89 | struct flash_cache_tag Cache; |
93 | static struct spectra_l2_cache_info cache_l2; | 90 | static struct spectra_l2_cache_info cache_l2; |
@@ -775,7 +772,7 @@ static void dump_cache_l2_table(void) | |||
775 | { | 772 | { |
776 | struct list_head *p; | 773 | struct list_head *p; |
777 | struct spectra_l2_cache_list *pnd; | 774 | struct spectra_l2_cache_list *pnd; |
778 | int n, i; | 775 | int n; |
779 | 776 | ||
780 | n = 0; | 777 | n = 0; |
781 | list_for_each(p, &cache_l2.table.list) { | 778 | list_for_each(p, &cache_l2.table.list) { |
@@ -1538,79 +1535,6 @@ static int FTL_Cache_Write_All(u8 *pData, u64 blk_addr) | |||
1538 | } | 1535 | } |
1539 | 1536 | ||
1540 | /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& | 1537 | /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& |
1541 | * Function: FTL_Cache_Update_Block | ||
1542 | * Inputs: pointer to buffer,page address,block address | ||
1543 | * Outputs: PASS=0 / FAIL=1 | ||
1544 | * Description: It updates the cache | ||
1545 | *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/ | ||
1546 | static int FTL_Cache_Update_Block(u8 *pData, | ||
1547 | u64 old_page_addr, u64 blk_addr) | ||
1548 | { | ||
1549 | int i, j; | ||
1550 | u8 *buf = pData; | ||
1551 | int wResult = PASS; | ||
1552 | int wFoundInCache; | ||
1553 | u64 page_addr; | ||
1554 | u64 addr; | ||
1555 | u64 old_blk_addr; | ||
1556 | u16 page_offset; | ||
1557 | |||
1558 | nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n", | ||
1559 | __FILE__, __LINE__, __func__); | ||
1560 | |||
1561 | old_blk_addr = (u64)(old_page_addr >> | ||
1562 | DeviceInfo.nBitsInBlockDataSize) * DeviceInfo.wBlockDataSize; | ||
1563 | page_offset = (u16)(GLOB_u64_Remainder(old_page_addr, 2) >> | ||
1564 | DeviceInfo.nBitsInPageDataSize); | ||
1565 | |||
1566 | for (i = 0; i < DeviceInfo.wPagesPerBlock; i += Cache.pages_per_item) { | ||
1567 | page_addr = old_blk_addr + i * DeviceInfo.wPageDataSize; | ||
1568 | if (i != page_offset) { | ||
1569 | wFoundInCache = FAIL; | ||
1570 | for (j = 0; j < CACHE_ITEM_NUM; j++) { | ||
1571 | addr = Cache.array[j].address; | ||
1572 | addr = FTL_Get_Physical_Block_Addr(addr) + | ||
1573 | GLOB_u64_Remainder(addr, 2); | ||
1574 | if ((addr >= page_addr) && addr < | ||
1575 | (page_addr + Cache.cache_item_size)) { | ||
1576 | wFoundInCache = PASS; | ||
1577 | buf = Cache.array[j].buf; | ||
1578 | Cache.array[j].changed = SET; | ||
1579 | #if CMD_DMA | ||
1580 | #if RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE | ||
1581 | int_cache[ftl_cmd_cnt].item = j; | ||
1582 | int_cache[ftl_cmd_cnt].cache.address = | ||
1583 | Cache.array[j].address; | ||
1584 | int_cache[ftl_cmd_cnt].cache.changed = | ||
1585 | Cache.array[j].changed; | ||
1586 | #endif | ||
1587 | #endif | ||
1588 | break; | ||
1589 | } | ||
1590 | } | ||
1591 | if (FAIL == wFoundInCache) { | ||
1592 | if (ERR == FTL_Cache_Read_All(g_pTempBuf, | ||
1593 | page_addr)) { | ||
1594 | wResult = FAIL; | ||
1595 | break; | ||
1596 | } | ||
1597 | buf = g_pTempBuf; | ||
1598 | } | ||
1599 | } else { | ||
1600 | buf = pData; | ||
1601 | } | ||
1602 | |||
1603 | if (FAIL == FTL_Cache_Write_All(buf, | ||
1604 | blk_addr + (page_addr - old_blk_addr))) { | ||
1605 | wResult = FAIL; | ||
1606 | break; | ||
1607 | } | ||
1608 | } | ||
1609 | |||
1610 | return wResult; | ||
1611 | } | ||
1612 | |||
1613 | /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& | ||
1614 | * Function: FTL_Copy_Block | 1538 | * Function: FTL_Copy_Block |
1615 | * Inputs: source block address | 1539 | * Inputs: source block address |
1616 | * Destination block address | 1540 | * Destination block address |
@@ -1698,7 +1622,7 @@ static int get_l2_cache_blks(void) | |||
1698 | static int erase_l2_cache_blocks(void) | 1622 | static int erase_l2_cache_blocks(void) |
1699 | { | 1623 | { |
1700 | int i, ret = PASS; | 1624 | int i, ret = PASS; |
1701 | u32 pblk, lblk; | 1625 | u32 pblk, lblk = BAD_BLOCK; |
1702 | u64 addr; | 1626 | u64 addr; |
1703 | u32 *pbt = (u32 *)g_pBlockTable; | 1627 | u32 *pbt = (u32 *)g_pBlockTable; |
1704 | 1628 | ||
@@ -2004,87 +1928,6 @@ static int search_l2_cache(u8 *buf, u64 logical_addr) | |||
2004 | return ret; | 1928 | return ret; |
2005 | } | 1929 | } |
2006 | 1930 | ||
2007 | /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& | ||
2008 | * Function: FTL_Cache_Write_Back | ||
2009 | * Inputs: pointer to data cached in sys memory | ||
2010 | * address of free block in flash | ||
2011 | * Outputs: PASS=0 / FAIL=1 | ||
2012 | * Description: writes all the pages of Cache Block to flash | ||
2013 | * | ||
2014 | *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/ | ||
2015 | static int FTL_Cache_Write_Back(u8 *pData, u64 blk_addr) | ||
2016 | { | ||
2017 | int i, j, iErase; | ||
2018 | u64 old_page_addr, addr, phy_addr; | ||
2019 | u32 *pbt = (u32 *)g_pBlockTable; | ||
2020 | u32 lba; | ||
2021 | |||
2022 | nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n", | ||
2023 | __FILE__, __LINE__, __func__); | ||
2024 | |||
2025 | old_page_addr = FTL_Get_Physical_Block_Addr(blk_addr) + | ||
2026 | GLOB_u64_Remainder(blk_addr, 2); | ||
2027 | |||
2028 | iErase = (FAIL == FTL_Replace_Block(blk_addr)) ? PASS : FAIL; | ||
2029 | |||
2030 | pbt[BLK_FROM_ADDR(blk_addr)] &= (~SPARE_BLOCK); | ||
2031 | |||
2032 | #if CMD_DMA | ||
2033 | p_BTableChangesDelta = (struct BTableChangesDelta *)g_pBTDelta_Free; | ||
2034 | g_pBTDelta_Free += sizeof(struct BTableChangesDelta); | ||
2035 | |||
2036 | p_BTableChangesDelta->ftl_cmd_cnt = ftl_cmd_cnt; | ||
2037 | p_BTableChangesDelta->BT_Index = (u32)(blk_addr >> | ||
2038 | DeviceInfo.nBitsInBlockDataSize); | ||
2039 | p_BTableChangesDelta->BT_Entry_Value = | ||
2040 | pbt[(u32)(blk_addr >> DeviceInfo.nBitsInBlockDataSize)]; | ||
2041 | p_BTableChangesDelta->ValidFields = 0x0C; | ||
2042 | #endif | ||
2043 | |||
2044 | if (IN_PROGRESS_BLOCK_TABLE != g_cBlockTableStatus) { | ||
2045 | g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE; | ||
2046 | FTL_Write_IN_Progress_Block_Table_Page(); | ||
2047 | } | ||
2048 | |||
2049 | for (i = 0; i < RETRY_TIMES; i++) { | ||
2050 | if (PASS == iErase) { | ||
2051 | phy_addr = FTL_Get_Physical_Block_Addr(blk_addr); | ||
2052 | if (FAIL == GLOB_FTL_Block_Erase(phy_addr)) { | ||
2053 | lba = BLK_FROM_ADDR(blk_addr); | ||
2054 | MARK_BLOCK_AS_BAD(pbt[lba]); | ||
2055 | i = RETRY_TIMES; | ||
2056 | break; | ||
2057 | } | ||
2058 | } | ||
2059 | |||
2060 | for (j = 0; j < CACHE_ITEM_NUM; j++) { | ||
2061 | addr = Cache.array[j].address; | ||
2062 | if ((addr <= blk_addr) && | ||
2063 | ((addr + Cache.cache_item_size) > blk_addr)) | ||
2064 | cache_block_to_write = j; | ||
2065 | } | ||
2066 | |||
2067 | phy_addr = FTL_Get_Physical_Block_Addr(blk_addr); | ||
2068 | if (PASS == FTL_Cache_Update_Block(pData, | ||
2069 | old_page_addr, phy_addr)) { | ||
2070 | cache_block_to_write = UNHIT_CACHE_ITEM; | ||
2071 | break; | ||
2072 | } else { | ||
2073 | iErase = PASS; | ||
2074 | } | ||
2075 | } | ||
2076 | |||
2077 | if (i >= RETRY_TIMES) { | ||
2078 | if (ERR == FTL_Flash_Error_Handle(pData, | ||
2079 | old_page_addr, blk_addr)) | ||
2080 | return ERR; | ||
2081 | else | ||
2082 | return FAIL; | ||
2083 | } | ||
2084 | |||
2085 | return PASS; | ||
2086 | } | ||
2087 | |||
2088 | /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& | 1931 | /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& |
2089 | * Function: FTL_Cache_Write_Page | 1932 | * Function: FTL_Cache_Write_Page |
2090 | * Inputs: Pointer to buffer, page address, cache block number | 1933 | * Inputs: Pointer to buffer, page address, cache block number |
@@ -2370,159 +2213,6 @@ static int FTL_Write_Block_Table(int wForce) | |||
2370 | return 1; | 2213 | return 1; |
2371 | } | 2214 | } |
2372 | 2215 | ||
2373 | /****************************************************************** | ||
2374 | * Function: GLOB_FTL_Flash_Format | ||
2375 | * Inputs: none | ||
2376 | * Outputs: PASS | ||
2377 | * Description: The block table stores bad block info, including MDF+ | ||
2378 | * blocks gone bad over the ages. Therefore, if we have a | ||
2379 | * block table in place, then use it to scan for bad blocks | ||
2380 | * If not, then scan for MDF. | ||
2381 | * Now, a block table will only be found if spectra was already | ||
2382 | * being used. For a fresh flash, we'll go thru scanning for | ||
2383 | * MDF. If spectra was being used, then there is a chance that | ||
2384 | * the MDF has been corrupted. Spectra avoids writing to the | ||
2385 | * first 2 bytes of the spare area to all pages in a block. This | ||
2386 | * covers all known flash devices. However, since flash | ||
2387 | * manufacturers have no standard of where the MDF is stored, | ||
2388 | * this cannot guarantee that the MDF is protected for future | ||
2389 | * devices too. The initial scanning for the block table assures | ||
2390 | * this. It is ok even if the block table is outdated, as all | ||
2391 | * we're looking for are bad block markers. | ||
2392 | * Use this when mounting a file system or starting a | ||
2393 | * new flash. | ||
2394 | * | ||
2395 | *********************************************************************/ | ||
2396 | static int FTL_Format_Flash(u8 valid_block_table) | ||
2397 | { | ||
2398 | u32 i, j; | ||
2399 | u32 *pbt = (u32 *)g_pBlockTable; | ||
2400 | u32 tempNode; | ||
2401 | int ret; | ||
2402 | |||
2403 | #if CMD_DMA | ||
2404 | u32 *pbtStartingCopy = (u32 *)g_pBTStartingCopy; | ||
2405 | if (ftl_cmd_cnt) | ||
2406 | return FAIL; | ||
2407 | #endif | ||
2408 | |||
2409 | if (FAIL == FTL_Check_Block_Table(FAIL)) | ||
2410 | valid_block_table = 0; | ||
2411 | |||
2412 | if (valid_block_table) { | ||
2413 | u8 switched = 1; | ||
2414 | u32 block, k; | ||
2415 | |||
2416 | k = DeviceInfo.wSpectraStartBlock; | ||
2417 | while (switched && (k < DeviceInfo.wSpectraEndBlock)) { | ||
2418 | switched = 0; | ||
2419 | k++; | ||
2420 | for (j = DeviceInfo.wSpectraStartBlock, i = 0; | ||
2421 | j <= DeviceInfo.wSpectraEndBlock; | ||
2422 | j++, i++) { | ||
2423 | block = (pbt[i] & ~BAD_BLOCK) - | ||
2424 | DeviceInfo.wSpectraStartBlock; | ||
2425 | if (block != i) { | ||
2426 | switched = 1; | ||
2427 | tempNode = pbt[i]; | ||
2428 | pbt[i] = pbt[block]; | ||
2429 | pbt[block] = tempNode; | ||
2430 | } | ||
2431 | } | ||
2432 | } | ||
2433 | if ((k == DeviceInfo.wSpectraEndBlock) && switched) | ||
2434 | valid_block_table = 0; | ||
2435 | } | ||
2436 | |||
2437 | if (!valid_block_table) { | ||
2438 | memset(g_pBlockTable, 0, | ||
2439 | DeviceInfo.wDataBlockNum * sizeof(u32)); | ||
2440 | memset(g_pWearCounter, 0, | ||
2441 | DeviceInfo.wDataBlockNum * sizeof(u8)); | ||
2442 | if (DeviceInfo.MLCDevice) | ||
2443 | memset(g_pReadCounter, 0, | ||
2444 | DeviceInfo.wDataBlockNum * sizeof(u16)); | ||
2445 | #if CMD_DMA | ||
2446 | memset(g_pBTStartingCopy, 0, | ||
2447 | DeviceInfo.wDataBlockNum * sizeof(u32)); | ||
2448 | memset(g_pWearCounterCopy, 0, | ||
2449 | DeviceInfo.wDataBlockNum * sizeof(u8)); | ||
2450 | if (DeviceInfo.MLCDevice) | ||
2451 | memset(g_pReadCounterCopy, 0, | ||
2452 | DeviceInfo.wDataBlockNum * sizeof(u16)); | ||
2453 | #endif | ||
2454 | for (j = DeviceInfo.wSpectraStartBlock, i = 0; | ||
2455 | j <= DeviceInfo.wSpectraEndBlock; | ||
2456 | j++, i++) { | ||
2457 | if (GLOB_LLD_Get_Bad_Block((u32)j)) | ||
2458 | pbt[i] = (u32)(BAD_BLOCK | j); | ||
2459 | } | ||
2460 | } | ||
2461 | |||
2462 | nand_dbg_print(NAND_DBG_WARN, "Erasing all blocks in the NAND\n"); | ||
2463 | |||
2464 | for (j = DeviceInfo.wSpectraStartBlock, i = 0; | ||
2465 | j <= DeviceInfo.wSpectraEndBlock; | ||
2466 | j++, i++) { | ||
2467 | if ((pbt[i] & BAD_BLOCK) != BAD_BLOCK) { | ||
2468 | ret = GLOB_LLD_Erase_Block(j); | ||
2469 | if (FAIL == ret) { | ||
2470 | pbt[i] = (u32)(j); | ||
2471 | MARK_BLOCK_AS_BAD(pbt[i]); | ||
2472 | nand_dbg_print(NAND_DBG_WARN, | ||
2473 | "NAND Program fail in %s, Line %d, " | ||
2474 | "Function: %s, new Bad Block %d generated!\n", | ||
2475 | __FILE__, __LINE__, __func__, (int)j); | ||
2476 | } else { | ||
2477 | pbt[i] = (u32)(SPARE_BLOCK | j); | ||
2478 | } | ||
2479 | } | ||
2480 | #if CMD_DMA | ||
2481 | pbtStartingCopy[i] = pbt[i]; | ||
2482 | #endif | ||
2483 | } | ||
2484 | |||
2485 | g_wBlockTableOffset = 0; | ||
2486 | for (i = 0; (i <= (DeviceInfo.wSpectraEndBlock - | ||
2487 | DeviceInfo.wSpectraStartBlock)) | ||
2488 | && ((pbt[i] & BAD_BLOCK) == BAD_BLOCK); i++) | ||
2489 | ; | ||
2490 | if (i > (DeviceInfo.wSpectraEndBlock - DeviceInfo.wSpectraStartBlock)) { | ||
2491 | printk(KERN_ERR "All blocks bad!\n"); | ||
2492 | return FAIL; | ||
2493 | } else { | ||
2494 | g_wBlockTableIndex = pbt[i] & ~BAD_BLOCK; | ||
2495 | if (i != BLOCK_TABLE_INDEX) { | ||
2496 | tempNode = pbt[i]; | ||
2497 | pbt[i] = pbt[BLOCK_TABLE_INDEX]; | ||
2498 | pbt[BLOCK_TABLE_INDEX] = tempNode; | ||
2499 | } | ||
2500 | } | ||
2501 | pbt[BLOCK_TABLE_INDEX] &= (~SPARE_BLOCK); | ||
2502 | |||
2503 | #if CMD_DMA | ||
2504 | pbtStartingCopy[BLOCK_TABLE_INDEX] &= (~SPARE_BLOCK); | ||
2505 | #endif | ||
2506 | |||
2507 | g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE; | ||
2508 | memset(g_pBTBlocks, 0xFF, | ||
2509 | (1 + LAST_BT_ID - FIRST_BT_ID) * sizeof(u32)); | ||
2510 | g_pBTBlocks[FIRST_BT_ID-FIRST_BT_ID] = g_wBlockTableIndex; | ||
2511 | FTL_Write_Block_Table(FAIL); | ||
2512 | |||
2513 | for (i = 0; i < CACHE_ITEM_NUM; i++) { | ||
2514 | Cache.array[i].address = NAND_CACHE_INIT_ADDR; | ||
2515 | Cache.array[i].use_cnt = 0; | ||
2516 | Cache.array[i].changed = CLEAR; | ||
2517 | } | ||
2518 | |||
2519 | #if (RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE && CMD_DMA) | ||
2520 | memcpy((void *)&cache_start_copy, (void *)&Cache, | ||
2521 | sizeof(struct flash_cache_tag)); | ||
2522 | #endif | ||
2523 | return PASS; | ||
2524 | } | ||
2525 | |||
2526 | static int force_format_nand(void) | 2216 | static int force_format_nand(void) |
2527 | { | 2217 | { |
2528 | u32 i; | 2218 | u32 i; |
@@ -3031,112 +2721,6 @@ static int FTL_Read_Block_Table(void) | |||
3031 | return wResult; | 2721 | return wResult; |
3032 | } | 2722 | } |
3033 | 2723 | ||
3034 | |||
3035 | /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& | ||
3036 | * Function: FTL_Flash_Error_Handle | ||
3037 | * Inputs: Pointer to data | ||
3038 | * Page address | ||
3039 | * Block address | ||
3040 | * Outputs: PASS=0 / FAIL=1 | ||
3041 | * Description: It handles any error occured during Spectra operation | ||
3042 | *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/ | ||
3043 | static int FTL_Flash_Error_Handle(u8 *pData, u64 old_page_addr, | ||
3044 | u64 blk_addr) | ||
3045 | { | ||
3046 | u32 i; | ||
3047 | int j; | ||
3048 | u32 tmp_node, blk_node = BLK_FROM_ADDR(blk_addr); | ||
3049 | u64 phy_addr; | ||
3050 | int wErase = FAIL; | ||
3051 | int wResult = FAIL; | ||
3052 | u32 *pbt = (u32 *)g_pBlockTable; | ||
3053 | |||
3054 | nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n", | ||
3055 | __FILE__, __LINE__, __func__); | ||
3056 | |||
3057 | if (ERR == GLOB_FTL_Garbage_Collection()) | ||
3058 | return ERR; | ||
3059 | |||
3060 | do { | ||
3061 | for (i = DeviceInfo.wSpectraEndBlock - | ||
3062 | DeviceInfo.wSpectraStartBlock; | ||
3063 | i > 0; i--) { | ||
3064 | if (IS_SPARE_BLOCK(i)) { | ||
3065 | tmp_node = (u32)(BAD_BLOCK | | ||
3066 | pbt[blk_node]); | ||
3067 | pbt[blk_node] = (u32)(pbt[i] & | ||
3068 | (~SPARE_BLOCK)); | ||
3069 | pbt[i] = tmp_node; | ||
3070 | #if CMD_DMA | ||
3071 | p_BTableChangesDelta = | ||
3072 | (struct BTableChangesDelta *) | ||
3073 | g_pBTDelta_Free; | ||
3074 | g_pBTDelta_Free += | ||
3075 | sizeof(struct BTableChangesDelta); | ||
3076 | |||
3077 | p_BTableChangesDelta->ftl_cmd_cnt = | ||
3078 | ftl_cmd_cnt; | ||
3079 | p_BTableChangesDelta->BT_Index = | ||
3080 | blk_node; | ||
3081 | p_BTableChangesDelta->BT_Entry_Value = | ||
3082 | pbt[blk_node]; | ||
3083 | p_BTableChangesDelta->ValidFields = 0x0C; | ||
3084 | |||
3085 | p_BTableChangesDelta = | ||
3086 | (struct BTableChangesDelta *) | ||
3087 | g_pBTDelta_Free; | ||
3088 | g_pBTDelta_Free += | ||
3089 | sizeof(struct BTableChangesDelta); | ||
3090 | |||
3091 | p_BTableChangesDelta->ftl_cmd_cnt = | ||
3092 | ftl_cmd_cnt; | ||
3093 | p_BTableChangesDelta->BT_Index = i; | ||
3094 | p_BTableChangesDelta->BT_Entry_Value = pbt[i]; | ||
3095 | p_BTableChangesDelta->ValidFields = 0x0C; | ||
3096 | #endif | ||
3097 | wResult = PASS; | ||
3098 | break; | ||
3099 | } | ||
3100 | } | ||
3101 | |||
3102 | if (FAIL == wResult) { | ||
3103 | if (FAIL == GLOB_FTL_Garbage_Collection()) | ||
3104 | break; | ||
3105 | else | ||
3106 | continue; | ||
3107 | } | ||
3108 | |||
3109 | if (IN_PROGRESS_BLOCK_TABLE != g_cBlockTableStatus) { | ||
3110 | g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE; | ||
3111 | FTL_Write_IN_Progress_Block_Table_Page(); | ||
3112 | } | ||
3113 | |||
3114 | phy_addr = FTL_Get_Physical_Block_Addr(blk_addr); | ||
3115 | |||
3116 | for (j = 0; j < RETRY_TIMES; j++) { | ||
3117 | if (PASS == wErase) { | ||
3118 | if (FAIL == GLOB_FTL_Block_Erase(phy_addr)) { | ||
3119 | MARK_BLOCK_AS_BAD(pbt[blk_node]); | ||
3120 | break; | ||
3121 | } | ||
3122 | } | ||
3123 | if (PASS == FTL_Cache_Update_Block(pData, | ||
3124 | old_page_addr, | ||
3125 | phy_addr)) { | ||
3126 | wResult = PASS; | ||
3127 | break; | ||
3128 | } else { | ||
3129 | wResult = FAIL; | ||
3130 | wErase = PASS; | ||
3131 | } | ||
3132 | } | ||
3133 | } while (FAIL == wResult); | ||
3134 | |||
3135 | FTL_Write_Block_Table(FAIL); | ||
3136 | |||
3137 | return wResult; | ||
3138 | } | ||
3139 | |||
3140 | /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& | 2724 | /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& |
3141 | * Function: FTL_Get_Page_Num | 2725 | * Function: FTL_Get_Page_Num |
3142 | * Inputs: Size in bytes | 2726 | * Inputs: Size in bytes |
diff --git a/drivers/staging/ti-st/st.h b/drivers/staging/ti-st/st.h index 9952579425b..1b3060eb292 100644 --- a/drivers/staging/ti-st/st.h +++ b/drivers/staging/ti-st/st.h | |||
@@ -80,5 +80,4 @@ struct st_proto_s { | |||
80 | extern long st_register(struct st_proto_s *); | 80 | extern long st_register(struct st_proto_s *); |
81 | extern long st_unregister(enum proto_type); | 81 | extern long st_unregister(enum proto_type); |
82 | 82 | ||
83 | extern struct platform_device *st_get_plat_device(void); | ||
84 | #endif /* ST_H */ | 83 | #endif /* ST_H */ |
diff --git a/drivers/staging/ti-st/st_core.c b/drivers/staging/ti-st/st_core.c index 063c9b1db1a..b85d8bfdf60 100644 --- a/drivers/staging/ti-st/st_core.c +++ b/drivers/staging/ti-st/st_core.c | |||
@@ -38,7 +38,6 @@ | |||
38 | #include "st_ll.h" | 38 | #include "st_ll.h" |
39 | #include "st.h" | 39 | #include "st.h" |
40 | 40 | ||
41 | #define VERBOSE | ||
42 | /* strings to be used for rfkill entries and by | 41 | /* strings to be used for rfkill entries and by |
43 | * ST Core to be used for sysfs debug entry | 42 | * ST Core to be used for sysfs debug entry |
44 | */ | 43 | */ |
@@ -581,7 +580,7 @@ long st_register(struct st_proto_s *new_proto) | |||
581 | long err = 0; | 580 | long err = 0; |
582 | unsigned long flags = 0; | 581 | unsigned long flags = 0; |
583 | 582 | ||
584 | st_kim_ref(&st_gdata); | 583 | st_kim_ref(&st_gdata, 0); |
585 | pr_info("%s(%d) ", __func__, new_proto->type); | 584 | pr_info("%s(%d) ", __func__, new_proto->type); |
586 | if (st_gdata == NULL || new_proto == NULL || new_proto->recv == NULL | 585 | if (st_gdata == NULL || new_proto == NULL || new_proto->recv == NULL |
587 | || new_proto->reg_complete_cb == NULL) { | 586 | || new_proto->reg_complete_cb == NULL) { |
@@ -713,7 +712,7 @@ long st_unregister(enum proto_type type) | |||
713 | 712 | ||
714 | pr_debug("%s: %d ", __func__, type); | 713 | pr_debug("%s: %d ", __func__, type); |
715 | 714 | ||
716 | st_kim_ref(&st_gdata); | 715 | st_kim_ref(&st_gdata, 0); |
717 | if (type < ST_BT || type >= ST_MAX) { | 716 | if (type < ST_BT || type >= ST_MAX) { |
718 | pr_err(" protocol %d not supported", type); | 717 | pr_err(" protocol %d not supported", type); |
719 | return -EPROTONOSUPPORT; | 718 | return -EPROTONOSUPPORT; |
@@ -767,7 +766,7 @@ long st_write(struct sk_buff *skb) | |||
767 | #endif | 766 | #endif |
768 | long len; | 767 | long len; |
769 | 768 | ||
770 | st_kim_ref(&st_gdata); | 769 | st_kim_ref(&st_gdata, 0); |
771 | if (unlikely(skb == NULL || st_gdata == NULL | 770 | if (unlikely(skb == NULL || st_gdata == NULL |
772 | || st_gdata->tty == NULL)) { | 771 | || st_gdata->tty == NULL)) { |
773 | pr_err("data/tty unavailable to perform write"); | 772 | pr_err("data/tty unavailable to perform write"); |
@@ -818,7 +817,7 @@ static int st_tty_open(struct tty_struct *tty) | |||
818 | struct st_data_s *st_gdata; | 817 | struct st_data_s *st_gdata; |
819 | pr_info("%s ", __func__); | 818 | pr_info("%s ", __func__); |
820 | 819 | ||
821 | st_kim_ref(&st_gdata); | 820 | st_kim_ref(&st_gdata, 0); |
822 | st_gdata->tty = tty; | 821 | st_gdata->tty = tty; |
823 | tty->disc_data = st_gdata; | 822 | tty->disc_data = st_gdata; |
824 | 823 | ||
diff --git a/drivers/staging/ti-st/st_core.h b/drivers/staging/ti-st/st_core.h index e0c32d149f5..8601320a679 100644 --- a/drivers/staging/ti-st/st_core.h +++ b/drivers/staging/ti-st/st_core.h | |||
@@ -117,7 +117,7 @@ int st_core_init(struct st_data_s **); | |||
117 | void st_core_exit(struct st_data_s *); | 117 | void st_core_exit(struct st_data_s *); |
118 | 118 | ||
119 | /* ask for reference from KIM */ | 119 | /* ask for reference from KIM */ |
120 | void st_kim_ref(struct st_data_s **); | 120 | void st_kim_ref(struct st_data_s **, int); |
121 | 121 | ||
122 | #define GPS_STUB_TEST | 122 | #define GPS_STUB_TEST |
123 | #ifdef GPS_STUB_TEST | 123 | #ifdef GPS_STUB_TEST |
diff --git a/drivers/staging/ti-st/st_kim.c b/drivers/staging/ti-st/st_kim.c index b4a6c7fdc4e..9e99463f76e 100644 --- a/drivers/staging/ti-st/st_kim.c +++ b/drivers/staging/ti-st/st_kim.c | |||
@@ -72,11 +72,26 @@ const unsigned char *protocol_names[] = { | |||
72 | PROTO_ENTRY(ST_GPS, "GPS"), | 72 | PROTO_ENTRY(ST_GPS, "GPS"), |
73 | }; | 73 | }; |
74 | 74 | ||
75 | #define MAX_ST_DEVICES 3 /* Imagine 1 on each UART for now */ | ||
76 | struct platform_device *st_kim_devices[MAX_ST_DEVICES]; | ||
75 | 77 | ||
76 | /**********************************************************************/ | 78 | /**********************************************************************/ |
77 | /* internal functions */ | 79 | /* internal functions */ |
78 | 80 | ||
79 | /** | 81 | /** |
82 | * st_get_plat_device - | ||
83 | * function which returns the reference to the platform device | ||
84 | * requested by id. As of now only 1 such device exists (id=0) | ||
85 | * the context requesting for reference can get the id to be | ||
86 | * requested by a. The protocol driver which is registering or | ||
87 | * b. the tty device which is opened. | ||
88 | */ | ||
89 | static struct platform_device *st_get_plat_device(int id) | ||
90 | { | ||
91 | return st_kim_devices[id]; | ||
92 | } | ||
93 | |||
94 | /** | ||
80 | * validate_firmware_response - | 95 | * validate_firmware_response - |
81 | * function to return whether the firmware response was proper | 96 | * function to return whether the firmware response was proper |
82 | * in case of error don't complete so that waiting for proper | 97 | * in case of error don't complete so that waiting for proper |
@@ -353,7 +368,7 @@ void st_kim_chip_toggle(enum proto_type type, enum kim_gpio_state state) | |||
353 | struct kim_data_s *kim_gdata; | 368 | struct kim_data_s *kim_gdata; |
354 | pr_info(" %s ", __func__); | 369 | pr_info(" %s ", __func__); |
355 | 370 | ||
356 | kim_pdev = st_get_plat_device(); | 371 | kim_pdev = st_get_plat_device(0); |
357 | kim_gdata = dev_get_drvdata(&kim_pdev->dev); | 372 | kim_gdata = dev_get_drvdata(&kim_pdev->dev); |
358 | 373 | ||
359 | if (kim_gdata->gpios[type] == -1) { | 374 | if (kim_gdata->gpios[type] == -1) { |
@@ -574,12 +589,12 @@ static int kim_toggle_radio(void *data, bool blocked) | |||
574 | * This would enable multiple such platform devices to exist | 589 | * This would enable multiple such platform devices to exist |
575 | * on a given platform | 590 | * on a given platform |
576 | */ | 591 | */ |
577 | void st_kim_ref(struct st_data_s **core_data) | 592 | void st_kim_ref(struct st_data_s **core_data, int id) |
578 | { | 593 | { |
579 | struct platform_device *pdev; | 594 | struct platform_device *pdev; |
580 | struct kim_data_s *kim_gdata; | 595 | struct kim_data_s *kim_gdata; |
581 | /* get kim_gdata reference from platform device */ | 596 | /* get kim_gdata reference from platform device */ |
582 | pdev = st_get_plat_device(); | 597 | pdev = st_get_plat_device(id); |
583 | kim_gdata = dev_get_drvdata(&pdev->dev); | 598 | kim_gdata = dev_get_drvdata(&pdev->dev); |
584 | *core_data = kim_gdata->core_data; | 599 | *core_data = kim_gdata->core_data; |
585 | } | 600 | } |
@@ -623,6 +638,7 @@ static int kim_probe(struct platform_device *pdev) | |||
623 | long *gpios = pdev->dev.platform_data; | 638 | long *gpios = pdev->dev.platform_data; |
624 | struct kim_data_s *kim_gdata; | 639 | struct kim_data_s *kim_gdata; |
625 | 640 | ||
641 | st_kim_devices[pdev->id] = pdev; | ||
626 | kim_gdata = kzalloc(sizeof(struct kim_data_s), GFP_ATOMIC); | 642 | kim_gdata = kzalloc(sizeof(struct kim_data_s), GFP_ATOMIC); |
627 | if (!kim_gdata) { | 643 | if (!kim_gdata) { |
628 | pr_err("no mem to allocate"); | 644 | pr_err("no mem to allocate"); |
diff --git a/drivers/staging/tm6000/Kconfig b/drivers/staging/tm6000/Kconfig index c725356cc34..de7ebb99d8f 100644 --- a/drivers/staging/tm6000/Kconfig +++ b/drivers/staging/tm6000/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config VIDEO_TM6000 | 1 | config VIDEO_TM6000 |
2 | tristate "TV Master TM5600/6000/6010 driver" | 2 | tristate "TV Master TM5600/6000/6010 driver" |
3 | depends on VIDEO_DEV && I2C && INPUT && USB && EXPERIMENTAL | 3 | depends on VIDEO_DEV && I2C && INPUT && IR_CORE && USB && EXPERIMENTAL |
4 | select VIDEO_TUNER | 4 | select VIDEO_TUNER |
5 | select MEDIA_TUNER_XC2028 | 5 | select MEDIA_TUNER_XC2028 |
6 | select MEDIA_TUNER_XC5000 | 6 | select MEDIA_TUNER_XC5000 |
diff --git a/drivers/staging/tm6000/tm6000-input.c b/drivers/staging/tm6000/tm6000-input.c index 32f7a0af693..54f7667cc70 100644 --- a/drivers/staging/tm6000/tm6000-input.c +++ b/drivers/staging/tm6000/tm6000-input.c | |||
@@ -46,7 +46,7 @@ MODULE_PARM_DESC(enable_ir, "enable ir (default is enable"); | |||
46 | } | 46 | } |
47 | 47 | ||
48 | struct tm6000_ir_poll_result { | 48 | struct tm6000_ir_poll_result { |
49 | u8 rc_data[4]; | 49 | u16 rc_data; |
50 | }; | 50 | }; |
51 | 51 | ||
52 | struct tm6000_IR { | 52 | struct tm6000_IR { |
@@ -60,9 +60,9 @@ struct tm6000_IR { | |||
60 | int polling; | 60 | int polling; |
61 | struct delayed_work work; | 61 | struct delayed_work work; |
62 | u8 wait:1; | 62 | u8 wait:1; |
63 | u8 key:1; | ||
63 | struct urb *int_urb; | 64 | struct urb *int_urb; |
64 | u8 *urb_data; | 65 | u8 *urb_data; |
65 | u8 key:1; | ||
66 | 66 | ||
67 | int (*get_key) (struct tm6000_IR *, struct tm6000_ir_poll_result *); | 67 | int (*get_key) (struct tm6000_IR *, struct tm6000_ir_poll_result *); |
68 | 68 | ||
@@ -122,13 +122,14 @@ static void tm6000_ir_urb_received(struct urb *urb) | |||
122 | 122 | ||
123 | if (urb->status != 0) | 123 | if (urb->status != 0) |
124 | printk(KERN_INFO "not ready\n"); | 124 | printk(KERN_INFO "not ready\n"); |
125 | else if (urb->actual_length > 0) | 125 | else if (urb->actual_length > 0) { |
126 | memcpy(ir->urb_data, urb->transfer_buffer, urb->actual_length); | 126 | memcpy(ir->urb_data, urb->transfer_buffer, urb->actual_length); |
127 | 127 | ||
128 | dprintk("data %02x %02x %02x %02x\n", ir->urb_data[0], | 128 | dprintk("data %02x %02x %02x %02x\n", ir->urb_data[0], |
129 | ir->urb_data[1], ir->urb_data[2], ir->urb_data[3]); | 129 | ir->urb_data[1], ir->urb_data[2], ir->urb_data[3]); |
130 | 130 | ||
131 | ir->key = 1; | 131 | ir->key = 1; |
132 | } | ||
132 | 133 | ||
133 | rc = usb_submit_urb(urb, GFP_ATOMIC); | 134 | rc = usb_submit_urb(urb, GFP_ATOMIC); |
134 | } | 135 | } |
@@ -140,30 +141,47 @@ static int default_polling_getkey(struct tm6000_IR *ir, | |||
140 | int rc; | 141 | int rc; |
141 | u8 buf[2]; | 142 | u8 buf[2]; |
142 | 143 | ||
143 | if (ir->wait && !&dev->int_in) { | 144 | if (ir->wait && !&dev->int_in) |
144 | poll_result->rc_data[0] = 0xff; | ||
145 | return 0; | 145 | return 0; |
146 | } | ||
147 | 146 | ||
148 | if (&dev->int_in) { | 147 | if (&dev->int_in) { |
149 | poll_result->rc_data[0] = ir->urb_data[0]; | 148 | if (ir->ir.ir_type == IR_TYPE_RC5) |
150 | poll_result->rc_data[1] = ir->urb_data[1]; | 149 | poll_result->rc_data = ir->urb_data[0]; |
150 | else | ||
151 | poll_result->rc_data = ir->urb_data[0] | ir->urb_data[1] << 8; | ||
151 | } else { | 152 | } else { |
152 | tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 0); | 153 | tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 0); |
153 | msleep(10); | 154 | msleep(10); |
154 | tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 1); | 155 | tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 1); |
155 | msleep(10); | 156 | msleep(10); |
156 | 157 | ||
157 | rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | | 158 | if (ir->ir.ir_type == IR_TYPE_RC5) { |
158 | USB_RECIP_DEVICE, REQ_02_GET_IR_CODE, 0, 0, buf, 1); | 159 | rc = tm6000_read_write_usb(dev, USB_DIR_IN | |
160 | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
161 | REQ_02_GET_IR_CODE, 0, 0, buf, 1); | ||
159 | 162 | ||
160 | msleep(10); | 163 | msleep(10); |
161 | 164 | ||
162 | dprintk("read data=%02x\n", buf[0]); | 165 | dprintk("read data=%02x\n", buf[0]); |
163 | if (rc < 0) | 166 | if (rc < 0) |
164 | return rc; | 167 | return rc; |
165 | 168 | ||
166 | poll_result->rc_data[0] = buf[0]; | 169 | poll_result->rc_data = buf[0]; |
170 | } else { | ||
171 | rc = tm6000_read_write_usb(dev, USB_DIR_IN | | ||
172 | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
173 | REQ_02_GET_IR_CODE, 0, 0, buf, 2); | ||
174 | |||
175 | msleep(10); | ||
176 | |||
177 | dprintk("read data=%04x\n", buf[0] | buf[1] << 8); | ||
178 | if (rc < 0) | ||
179 | return rc; | ||
180 | |||
181 | poll_result->rc_data = buf[0] | buf[1] << 8; | ||
182 | } | ||
183 | if ((poll_result->rc_data & 0x00ff) != 0xff) | ||
184 | ir->key = 1; | ||
167 | } | 185 | } |
168 | return 0; | 186 | return 0; |
169 | } | 187 | } |
@@ -180,12 +198,11 @@ static void tm6000_ir_handle_key(struct tm6000_IR *ir) | |||
180 | return; | 198 | return; |
181 | } | 199 | } |
182 | 200 | ||
183 | dprintk("ir->get_key result data=%02x %02x\n", | 201 | dprintk("ir->get_key result data=%04x\n", poll_result.rc_data); |
184 | poll_result.rc_data[0], poll_result.rc_data[1]); | ||
185 | 202 | ||
186 | if (poll_result.rc_data[0] != 0xff && ir->key == 1) { | 203 | if (ir->key) { |
187 | ir_input_keydown(ir->input->input_dev, &ir->ir, | 204 | ir_input_keydown(ir->input->input_dev, &ir->ir, |
188 | poll_result.rc_data[0] | poll_result.rc_data[1] << 8); | 205 | (u32)poll_result.rc_data); |
189 | 206 | ||
190 | ir_input_nokey(ir->input->input_dev, &ir->ir); | 207 | ir_input_nokey(ir->input->input_dev, &ir->ir); |
191 | ir->key = 0; | 208 | ir->key = 0; |
diff --git a/drivers/staging/vt6655/wpactl.c b/drivers/staging/vt6655/wpactl.c index 0142338bcaf..4bdb8362de8 100644 --- a/drivers/staging/vt6655/wpactl.c +++ b/drivers/staging/vt6655/wpactl.c | |||
@@ -766,9 +766,14 @@ static int wpa_set_associate(PSDevice pDevice, | |||
766 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ie_len = %d\n", param->u.wpa_associate.wpa_ie_len); | 766 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ie_len = %d\n", param->u.wpa_associate.wpa_ie_len); |
767 | 767 | ||
768 | 768 | ||
769 | if (param->u.wpa_associate.wpa_ie && | 769 | if (param->u.wpa_associate.wpa_ie_len) { |
770 | copy_from_user(&abyWPAIE[0], param->u.wpa_associate.wpa_ie, param->u.wpa_associate.wpa_ie_len)) | 770 | if (!param->u.wpa_associate.wpa_ie) |
771 | return -EINVAL; | 771 | return -EINVAL; |
772 | if (param->u.wpa_associate.wpa_ie_len > sizeof(abyWPAIE)) | ||
773 | return -EINVAL; | ||
774 | if (copy_from_user(&abyWPAIE[0], param->u.wpa_associate.wpa_ie, param->u.wpa_associate.wpa_ie_len)) | ||
775 | return -EFAULT; | ||
776 | } | ||
772 | 777 | ||
773 | if (param->u.wpa_associate.mode == 1) | 778 | if (param->u.wpa_associate.mode == 1) |
774 | pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA; | 779 | pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA; |
diff --git a/drivers/staging/wlan-ng/cfg80211.c b/drivers/staging/wlan-ng/cfg80211.c index 368c30a9d5f..4af83d5318f 100644 --- a/drivers/staging/wlan-ng/cfg80211.c +++ b/drivers/staging/wlan-ng/cfg80211.c | |||
@@ -219,6 +219,7 @@ int prism2_get_key(struct wiphy *wiphy, struct net_device *dev, | |||
219 | return -ENOENT; | 219 | return -ENOENT; |
220 | params.key_len = len; | 220 | params.key_len = len; |
221 | params.key = wlandev->wep_keys[key_index]; | 221 | params.key = wlandev->wep_keys[key_index]; |
222 | params.seq_len = 0; | ||
222 | 223 | ||
223 | callback(cookie, ¶ms); | 224 | callback(cookie, ¶ms); |
224 | 225 | ||
@@ -735,6 +736,8 @@ struct wiphy *wlan_create_wiphy(struct device *dev, wlandevice_t *wlandev) | |||
735 | priv->band.n_channels = ARRAY_SIZE(prism2_channels); | 736 | priv->band.n_channels = ARRAY_SIZE(prism2_channels); |
736 | priv->band.bitrates = priv->rates; | 737 | priv->band.bitrates = priv->rates; |
737 | priv->band.n_bitrates = ARRAY_SIZE(prism2_rates); | 738 | priv->band.n_bitrates = ARRAY_SIZE(prism2_rates); |
739 | priv->band.band = IEEE80211_BAND_2GHZ; | ||
740 | priv->band.ht_cap.ht_supported = false; | ||
738 | wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band; | 741 | wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band; |
739 | 742 | ||
740 | set_wiphy_dev(wiphy, dev); | 743 | set_wiphy_dev(wiphy, dev); |
diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c index 77d4d715a78..722c840ac63 100644 --- a/drivers/staging/zram/zram_drv.c +++ b/drivers/staging/zram/zram_drv.c | |||
@@ -769,6 +769,7 @@ static int __init zram_init(void) | |||
769 | free_devices: | 769 | free_devices: |
770 | while (dev_id) | 770 | while (dev_id) |
771 | destroy_device(&devices[--dev_id]); | 771 | destroy_device(&devices[--dev_id]); |
772 | kfree(devices); | ||
772 | unregister: | 773 | unregister: |
773 | unregister_blkdev(zram_major, "zram"); | 774 | unregister_blkdev(zram_major, "zram"); |
774 | out: | 775 | out: |
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index 593fc5e2d2e..5af23cc5ea9 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c | |||
@@ -1127,6 +1127,7 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance, | |||
1127 | { | 1127 | { |
1128 | struct cxacru_data *instance; | 1128 | struct cxacru_data *instance; |
1129 | struct usb_device *usb_dev = interface_to_usbdev(intf); | 1129 | struct usb_device *usb_dev = interface_to_usbdev(intf); |
1130 | struct usb_host_endpoint *cmd_ep = usb_dev->ep_in[CXACRU_EP_CMD]; | ||
1130 | int ret; | 1131 | int ret; |
1131 | 1132 | ||
1132 | /* instance init */ | 1133 | /* instance init */ |
@@ -1171,15 +1172,34 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance, | |||
1171 | goto fail; | 1172 | goto fail; |
1172 | } | 1173 | } |
1173 | 1174 | ||
1174 | usb_fill_int_urb(instance->rcv_urb, | 1175 | if (!cmd_ep) { |
1176 | dbg("cxacru_bind: no command endpoint"); | ||
1177 | ret = -ENODEV; | ||
1178 | goto fail; | ||
1179 | } | ||
1180 | |||
1181 | if ((cmd_ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | ||
1182 | == USB_ENDPOINT_XFER_INT) { | ||
1183 | usb_fill_int_urb(instance->rcv_urb, | ||
1175 | usb_dev, usb_rcvintpipe(usb_dev, CXACRU_EP_CMD), | 1184 | usb_dev, usb_rcvintpipe(usb_dev, CXACRU_EP_CMD), |
1176 | instance->rcv_buf, PAGE_SIZE, | 1185 | instance->rcv_buf, PAGE_SIZE, |
1177 | cxacru_blocking_completion, &instance->rcv_done, 1); | 1186 | cxacru_blocking_completion, &instance->rcv_done, 1); |
1178 | 1187 | ||
1179 | usb_fill_int_urb(instance->snd_urb, | 1188 | usb_fill_int_urb(instance->snd_urb, |
1180 | usb_dev, usb_sndintpipe(usb_dev, CXACRU_EP_CMD), | 1189 | usb_dev, usb_sndintpipe(usb_dev, CXACRU_EP_CMD), |
1181 | instance->snd_buf, PAGE_SIZE, | 1190 | instance->snd_buf, PAGE_SIZE, |
1182 | cxacru_blocking_completion, &instance->snd_done, 4); | 1191 | cxacru_blocking_completion, &instance->snd_done, 4); |
1192 | } else { | ||
1193 | usb_fill_bulk_urb(instance->rcv_urb, | ||
1194 | usb_dev, usb_rcvbulkpipe(usb_dev, CXACRU_EP_CMD), | ||
1195 | instance->rcv_buf, PAGE_SIZE, | ||
1196 | cxacru_blocking_completion, &instance->rcv_done); | ||
1197 | |||
1198 | usb_fill_bulk_urb(instance->snd_urb, | ||
1199 | usb_dev, usb_sndbulkpipe(usb_dev, CXACRU_EP_CMD), | ||
1200 | instance->snd_buf, PAGE_SIZE, | ||
1201 | cxacru_blocking_completion, &instance->snd_done); | ||
1202 | } | ||
1183 | 1203 | ||
1184 | mutex_init(&instance->cm_serialize); | 1204 | mutex_init(&instance->cm_serialize); |
1185 | 1205 | ||
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 1833b3a7151..bc62fae0680 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -965,7 +965,8 @@ static int acm_probe(struct usb_interface *intf, | |||
965 | } | 965 | } |
966 | 966 | ||
967 | if (!buflen) { | 967 | if (!buflen) { |
968 | if (intf->cur_altsetting->endpoint->extralen && | 968 | if (intf->cur_altsetting->endpoint && |
969 | intf->cur_altsetting->endpoint->extralen && | ||
969 | intf->cur_altsetting->endpoint->extra) { | 970 | intf->cur_altsetting->endpoint->extra) { |
970 | dev_dbg(&intf->dev, | 971 | dev_dbg(&intf->dev, |
971 | "Seeking extra descriptors on endpoint\n"); | 972 | "Seeking extra descriptors on endpoint\n"); |
@@ -1481,6 +1482,11 @@ static int acm_reset_resume(struct usb_interface *intf) | |||
1481 | USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, \ | 1482 | USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, \ |
1482 | USB_CDC_ACM_PROTO_VENDOR) | 1483 | USB_CDC_ACM_PROTO_VENDOR) |
1483 | 1484 | ||
1485 | #define SAMSUNG_PCSUITE_ACM_INFO(x) \ | ||
1486 | USB_DEVICE_AND_INTERFACE_INFO(0x04e7, x, \ | ||
1487 | USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, \ | ||
1488 | USB_CDC_ACM_PROTO_VENDOR) | ||
1489 | |||
1484 | /* | 1490 | /* |
1485 | * USB driver structure. | 1491 | * USB driver structure. |
1486 | */ | 1492 | */ |
@@ -1591,6 +1597,17 @@ static const struct usb_device_id acm_ids[] = { | |||
1591 | { NOKIA_PCSUITE_ACM_INFO(0x0108), }, /* Nokia 5320 XpressMusic 2G */ | 1597 | { NOKIA_PCSUITE_ACM_INFO(0x0108), }, /* Nokia 5320 XpressMusic 2G */ |
1592 | { NOKIA_PCSUITE_ACM_INFO(0x01f5), }, /* Nokia N97, RM-505 */ | 1598 | { NOKIA_PCSUITE_ACM_INFO(0x01f5), }, /* Nokia N97, RM-505 */ |
1593 | { NOKIA_PCSUITE_ACM_INFO(0x02e3), }, /* Nokia 5230, RM-588 */ | 1599 | { NOKIA_PCSUITE_ACM_INFO(0x02e3), }, /* Nokia 5230, RM-588 */ |
1600 | { NOKIA_PCSUITE_ACM_INFO(0x0178), }, /* Nokia E63 */ | ||
1601 | { NOKIA_PCSUITE_ACM_INFO(0x010e), }, /* Nokia E75 */ | ||
1602 | { NOKIA_PCSUITE_ACM_INFO(0x02d9), }, /* Nokia 6760 Slide */ | ||
1603 | { NOKIA_PCSUITE_ACM_INFO(0x01d0), }, /* Nokia E52 */ | ||
1604 | { NOKIA_PCSUITE_ACM_INFO(0x0223), }, /* Nokia E72 */ | ||
1605 | { NOKIA_PCSUITE_ACM_INFO(0x0275), }, /* Nokia X6 */ | ||
1606 | { NOKIA_PCSUITE_ACM_INFO(0x026c), }, /* Nokia N97 Mini */ | ||
1607 | { NOKIA_PCSUITE_ACM_INFO(0x0154), }, /* Nokia 5800 XpressMusic */ | ||
1608 | { NOKIA_PCSUITE_ACM_INFO(0x04ce), }, /* Nokia E90 */ | ||
1609 | { NOKIA_PCSUITE_ACM_INFO(0x01d4), }, /* Nokia E55 */ | ||
1610 | { SAMSUNG_PCSUITE_ACM_INFO(0x6651), }, /* Samsung GTi8510 (INNOV8) */ | ||
1594 | 1611 | ||
1595 | /* NOTE: non-Nokia COMM/ACM/0xff is likely MSFT RNDIS... NOT a modem! */ | 1612 | /* NOTE: non-Nokia COMM/ACM/0xff is likely MSFT RNDIS... NOT a modem! */ |
1596 | 1613 | ||
@@ -1599,6 +1616,10 @@ static const struct usb_device_id acm_ids[] = { | |||
1599 | .driver_info = NOT_A_MODEM, | 1616 | .driver_info = NOT_A_MODEM, |
1600 | }, | 1617 | }, |
1601 | 1618 | ||
1619 | /* control interfaces without any protocol set */ | ||
1620 | { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, | ||
1621 | USB_CDC_PROTO_NONE) }, | ||
1622 | |||
1602 | /* control interfaces with various AT-command sets */ | 1623 | /* control interfaces with various AT-command sets */ |
1603 | { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, | 1624 | { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, |
1604 | USB_CDC_ACM_PROTO_AT_V25TER) }, | 1625 | USB_CDC_ACM_PROTO_AT_V25TER) }, |
diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index 7e594449600..9eed5b52d9d 100644 --- a/drivers/usb/core/Kconfig +++ b/drivers/usb/core/Kconfig | |||
@@ -91,12 +91,12 @@ config USB_DYNAMIC_MINORS | |||
91 | If you are unsure about this, say N here. | 91 | If you are unsure about this, say N here. |
92 | 92 | ||
93 | config USB_SUSPEND | 93 | config USB_SUSPEND |
94 | bool "USB runtime power management (suspend/resume and wakeup)" | 94 | bool "USB runtime power management (autosuspend) and wakeup" |
95 | depends on USB && PM_RUNTIME | 95 | depends on USB && PM_RUNTIME |
96 | help | 96 | help |
97 | If you say Y here, you can use driver calls or the sysfs | 97 | If you say Y here, you can use driver calls or the sysfs |
98 | "power/level" file to suspend or resume individual USB | 98 | "power/control" file to enable or disable autosuspend for |
99 | peripherals and to enable or disable autosuspend (see | 99 | individual USB peripherals (see |
100 | Documentation/usb/power-management.txt for more details). | 100 | Documentation/usb/power-management.txt for more details). |
101 | 101 | ||
102 | Also, USB "remote wakeup" signaling is supported, whereby some | 102 | Also, USB "remote wakeup" signaling is supported, whereby some |
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c index f06f5dbc8cd..1e6ccef2cf0 100644 --- a/drivers/usb/core/file.c +++ b/drivers/usb/core/file.c | |||
@@ -159,9 +159,9 @@ void usb_major_cleanup(void) | |||
159 | int usb_register_dev(struct usb_interface *intf, | 159 | int usb_register_dev(struct usb_interface *intf, |
160 | struct usb_class_driver *class_driver) | 160 | struct usb_class_driver *class_driver) |
161 | { | 161 | { |
162 | int retval = -EINVAL; | 162 | int retval; |
163 | int minor_base = class_driver->minor_base; | 163 | int minor_base = class_driver->minor_base; |
164 | int minor = 0; | 164 | int minor; |
165 | char name[20]; | 165 | char name[20]; |
166 | char *temp; | 166 | char *temp; |
167 | 167 | ||
@@ -173,12 +173,17 @@ int usb_register_dev(struct usb_interface *intf, | |||
173 | */ | 173 | */ |
174 | minor_base = 0; | 174 | minor_base = 0; |
175 | #endif | 175 | #endif |
176 | intf->minor = -1; | ||
177 | |||
178 | dbg ("looking for a minor, starting at %d", minor_base); | ||
179 | 176 | ||
180 | if (class_driver->fops == NULL) | 177 | if (class_driver->fops == NULL) |
181 | goto exit; | 178 | return -EINVAL; |
179 | if (intf->minor >= 0) | ||
180 | return -EADDRINUSE; | ||
181 | |||
182 | retval = init_usb_class(); | ||
183 | if (retval) | ||
184 | return retval; | ||
185 | |||
186 | dev_dbg(&intf->dev, "looking for a minor, starting at %d", minor_base); | ||
182 | 187 | ||
183 | down_write(&minor_rwsem); | 188 | down_write(&minor_rwsem); |
184 | for (minor = minor_base; minor < MAX_USB_MINORS; ++minor) { | 189 | for (minor = minor_base; minor < MAX_USB_MINORS; ++minor) { |
@@ -186,20 +191,12 @@ int usb_register_dev(struct usb_interface *intf, | |||
186 | continue; | 191 | continue; |
187 | 192 | ||
188 | usb_minors[minor] = class_driver->fops; | 193 | usb_minors[minor] = class_driver->fops; |
189 | 194 | intf->minor = minor; | |
190 | retval = 0; | ||
191 | break; | 195 | break; |
192 | } | 196 | } |
193 | up_write(&minor_rwsem); | 197 | up_write(&minor_rwsem); |
194 | 198 | if (intf->minor < 0) | |
195 | if (retval) | 199 | return -EXFULL; |
196 | goto exit; | ||
197 | |||
198 | retval = init_usb_class(); | ||
199 | if (retval) | ||
200 | goto exit; | ||
201 | |||
202 | intf->minor = minor; | ||
203 | 200 | ||
204 | /* create a usb class device for this usb interface */ | 201 | /* create a usb class device for this usb interface */ |
205 | snprintf(name, sizeof(name), class_driver->name, minor - minor_base); | 202 | snprintf(name, sizeof(name), class_driver->name, minor - minor_base); |
@@ -213,11 +210,11 @@ int usb_register_dev(struct usb_interface *intf, | |||
213 | "%s", temp); | 210 | "%s", temp); |
214 | if (IS_ERR(intf->usb_dev)) { | 211 | if (IS_ERR(intf->usb_dev)) { |
215 | down_write(&minor_rwsem); | 212 | down_write(&minor_rwsem); |
216 | usb_minors[intf->minor] = NULL; | 213 | usb_minors[minor] = NULL; |
214 | intf->minor = -1; | ||
217 | up_write(&minor_rwsem); | 215 | up_write(&minor_rwsem); |
218 | retval = PTR_ERR(intf->usb_dev); | 216 | retval = PTR_ERR(intf->usb_dev); |
219 | } | 217 | } |
220 | exit: | ||
221 | return retval; | 218 | return retval; |
222 | } | 219 | } |
223 | EXPORT_SYMBOL_GPL(usb_register_dev); | 220 | EXPORT_SYMBOL_GPL(usb_register_dev); |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index fd4c36ea5e4..9f0ce7de0e3 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -1724,6 +1724,15 @@ free_interfaces: | |||
1724 | if (ret) | 1724 | if (ret) |
1725 | goto free_interfaces; | 1725 | goto free_interfaces; |
1726 | 1726 | ||
1727 | /* if it's already configured, clear out old state first. | ||
1728 | * getting rid of old interfaces means unbinding their drivers. | ||
1729 | */ | ||
1730 | if (dev->state != USB_STATE_ADDRESS) | ||
1731 | usb_disable_device(dev, 1); /* Skip ep0 */ | ||
1732 | |||
1733 | /* Get rid of pending async Set-Config requests for this device */ | ||
1734 | cancel_async_set_config(dev); | ||
1735 | |||
1727 | /* Make sure we have bandwidth (and available HCD resources) for this | 1736 | /* Make sure we have bandwidth (and available HCD resources) for this |
1728 | * configuration. Remove endpoints from the schedule if we're dropping | 1737 | * configuration. Remove endpoints from the schedule if we're dropping |
1729 | * this configuration to set configuration 0. After this point, the | 1738 | * this configuration to set configuration 0. After this point, the |
@@ -1733,20 +1742,11 @@ free_interfaces: | |||
1733 | mutex_lock(&hcd->bandwidth_mutex); | 1742 | mutex_lock(&hcd->bandwidth_mutex); |
1734 | ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL); | 1743 | ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL); |
1735 | if (ret < 0) { | 1744 | if (ret < 0) { |
1736 | usb_autosuspend_device(dev); | ||
1737 | mutex_unlock(&hcd->bandwidth_mutex); | 1745 | mutex_unlock(&hcd->bandwidth_mutex); |
1746 | usb_autosuspend_device(dev); | ||
1738 | goto free_interfaces; | 1747 | goto free_interfaces; |
1739 | } | 1748 | } |
1740 | 1749 | ||
1741 | /* if it's already configured, clear out old state first. | ||
1742 | * getting rid of old interfaces means unbinding their drivers. | ||
1743 | */ | ||
1744 | if (dev->state != USB_STATE_ADDRESS) | ||
1745 | usb_disable_device(dev, 1); /* Skip ep0 */ | ||
1746 | |||
1747 | /* Get rid of pending async Set-Config requests for this device */ | ||
1748 | cancel_async_set_config(dev); | ||
1749 | |||
1750 | ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | 1750 | ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
1751 | USB_REQ_SET_CONFIGURATION, 0, configuration, 0, | 1751 | USB_REQ_SET_CONFIGURATION, 0, configuration, 0, |
1752 | NULL, 0, USB_CTRL_SET_TIMEOUT); | 1752 | NULL, 0, USB_CTRL_SET_TIMEOUT); |
@@ -1761,8 +1761,8 @@ free_interfaces: | |||
1761 | if (!cp) { | 1761 | if (!cp) { |
1762 | usb_set_device_state(dev, USB_STATE_ADDRESS); | 1762 | usb_set_device_state(dev, USB_STATE_ADDRESS); |
1763 | usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); | 1763 | usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); |
1764 | usb_autosuspend_device(dev); | ||
1765 | mutex_unlock(&hcd->bandwidth_mutex); | 1764 | mutex_unlock(&hcd->bandwidth_mutex); |
1765 | usb_autosuspend_device(dev); | ||
1766 | goto free_interfaces; | 1766 | goto free_interfaces; |
1767 | } | 1767 | } |
1768 | mutex_unlock(&hcd->bandwidth_mutex); | 1768 | mutex_unlock(&hcd->bandwidth_mutex); |
@@ -1802,6 +1802,7 @@ free_interfaces: | |||
1802 | intf->dev.groups = usb_interface_groups; | 1802 | intf->dev.groups = usb_interface_groups; |
1803 | intf->dev.dma_mask = dev->dev.dma_mask; | 1803 | intf->dev.dma_mask = dev->dev.dma_mask; |
1804 | INIT_WORK(&intf->reset_ws, __usb_queue_reset_device); | 1804 | INIT_WORK(&intf->reset_ws, __usb_queue_reset_device); |
1805 | intf->minor = -1; | ||
1805 | device_initialize(&intf->dev); | 1806 | device_initialize(&intf->dev); |
1806 | dev_set_name(&intf->dev, "%d-%s:%d.%d", | 1807 | dev_set_name(&intf->dev, "%d-%s:%d.%d", |
1807 | dev->bus->busnum, dev->devpath, | 1808 | dev->bus->busnum, dev->devpath, |
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index e483f80822d..1160c55de7f 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c | |||
@@ -723,12 +723,12 @@ int usb_string_ids_tab(struct usb_composite_dev *cdev, struct usb_string *str) | |||
723 | 723 | ||
724 | /** | 724 | /** |
725 | * usb_string_ids_n() - allocate unused string IDs in batch | 725 | * usb_string_ids_n() - allocate unused string IDs in batch |
726 | * @cdev: the device whose string descriptor IDs are being allocated | 726 | * @c: the device whose string descriptor IDs are being allocated |
727 | * @n: number of string IDs to allocate | 727 | * @n: number of string IDs to allocate |
728 | * Context: single threaded during gadget setup | 728 | * Context: single threaded during gadget setup |
729 | * | 729 | * |
730 | * Returns the first requested ID. This ID and next @n-1 IDs are now | 730 | * Returns the first requested ID. This ID and next @n-1 IDs are now |
731 | * valid IDs. At least providind that @n is non zore because if it | 731 | * valid IDs. At least provided that @n is non-zero because if it |
732 | * is, returns last requested ID which is now very useful information. | 732 | * is, returns last requested ID which is now very useful information. |
733 | * | 733 | * |
734 | * @usb_string_ids_n() is called from bind() callbacks to allocate | 734 | * @usb_string_ids_n() is called from bind() callbacks to allocate |
diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c index 166bf71fd34..e03058fe23c 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/m66592-udc.c | |||
@@ -1609,6 +1609,7 @@ static int __init m66592_probe(struct platform_device *pdev) | |||
1609 | /* initialize ucd */ | 1609 | /* initialize ucd */ |
1610 | m66592 = kzalloc(sizeof(struct m66592), GFP_KERNEL); | 1610 | m66592 = kzalloc(sizeof(struct m66592), GFP_KERNEL); |
1611 | if (m66592 == NULL) { | 1611 | if (m66592 == NULL) { |
1612 | ret = -ENOMEM; | ||
1612 | pr_err("kzalloc error\n"); | 1613 | pr_err("kzalloc error\n"); |
1613 | goto clean_up; | 1614 | goto clean_up; |
1614 | } | 1615 | } |
diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c index 70a81784275..2456ccd9965 100644 --- a/drivers/usb/gadget/r8a66597-udc.c +++ b/drivers/usb/gadget/r8a66597-udc.c | |||
@@ -1557,6 +1557,7 @@ static int __init r8a66597_probe(struct platform_device *pdev) | |||
1557 | /* initialize ucd */ | 1557 | /* initialize ucd */ |
1558 | r8a66597 = kzalloc(sizeof(struct r8a66597), GFP_KERNEL); | 1558 | r8a66597 = kzalloc(sizeof(struct r8a66597), GFP_KERNEL); |
1559 | if (r8a66597 == NULL) { | 1559 | if (r8a66597 == NULL) { |
1560 | ret = -ENOMEM; | ||
1560 | printk(KERN_ERR "kzalloc error\n"); | 1561 | printk(KERN_ERR "kzalloc error\n"); |
1561 | goto clean_up; | 1562 | goto clean_up; |
1562 | } | 1563 | } |
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c index 020fa5a25fd..972d5ddd1e1 100644 --- a/drivers/usb/gadget/rndis.c +++ b/drivers/usb/gadget/rndis.c | |||
@@ -293,9 +293,13 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
293 | /* mandatory */ | 293 | /* mandatory */ |
294 | case OID_GEN_VENDOR_DESCRIPTION: | 294 | case OID_GEN_VENDOR_DESCRIPTION: |
295 | pr_debug("%s: OID_GEN_VENDOR_DESCRIPTION\n", __func__); | 295 | pr_debug("%s: OID_GEN_VENDOR_DESCRIPTION\n", __func__); |
296 | length = strlen (rndis_per_dev_params [configNr].vendorDescr); | 296 | if ( rndis_per_dev_params [configNr].vendorDescr ) { |
297 | memcpy (outbuf, | 297 | length = strlen (rndis_per_dev_params [configNr].vendorDescr); |
298 | rndis_per_dev_params [configNr].vendorDescr, length); | 298 | memcpy (outbuf, |
299 | rndis_per_dev_params [configNr].vendorDescr, length); | ||
300 | } else { | ||
301 | outbuf[0] = 0; | ||
302 | } | ||
299 | retval = 0; | 303 | retval = 0; |
300 | break; | 304 | break; |
301 | 305 | ||
@@ -1148,7 +1152,7 @@ static struct proc_dir_entry *rndis_connect_state [RNDIS_MAX_CONFIGS]; | |||
1148 | #endif /* CONFIG_USB_GADGET_DEBUG_FILES */ | 1152 | #endif /* CONFIG_USB_GADGET_DEBUG_FILES */ |
1149 | 1153 | ||
1150 | 1154 | ||
1151 | int __init rndis_init (void) | 1155 | int rndis_init(void) |
1152 | { | 1156 | { |
1153 | u8 i; | 1157 | u8 i; |
1154 | 1158 | ||
diff --git a/drivers/usb/gadget/rndis.h b/drivers/usb/gadget/rndis.h index c236aaa9dcd..907c3300811 100644 --- a/drivers/usb/gadget/rndis.h +++ b/drivers/usb/gadget/rndis.h | |||
@@ -262,7 +262,7 @@ int rndis_signal_disconnect (int configNr); | |||
262 | int rndis_state (int configNr); | 262 | int rndis_state (int configNr); |
263 | extern void rndis_set_host_mac (int configNr, const u8 *addr); | 263 | extern void rndis_set_host_mac (int configNr, const u8 *addr); |
264 | 264 | ||
265 | int __devinit rndis_init (void); | 265 | int rndis_init(void); |
266 | void rndis_exit (void); | 266 | void rndis_exit (void); |
267 | 267 | ||
268 | #endif /* _LINUX_RNDIS_H */ | 268 | #endif /* _LINUX_RNDIS_H */ |
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index 521ebed0118..a229744a8c7 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c | |||
@@ -12,8 +12,6 @@ | |||
12 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #define DEBUG | ||
16 | |||
17 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
18 | #include <linux/module.h> | 16 | #include <linux/module.h> |
19 | #include <linux/spinlock.h> | 17 | #include <linux/spinlock.h> |
diff --git a/drivers/usb/gadget/uvc_v4l2.c b/drivers/usb/gadget/uvc_v4l2.c index 2dcffdac86d..5e807f083bc 100644 --- a/drivers/usb/gadget/uvc_v4l2.c +++ b/drivers/usb/gadget/uvc_v4l2.c | |||
@@ -94,7 +94,7 @@ uvc_v4l2_set_format(struct uvc_video *video, struct v4l2_format *fmt) | |||
94 | break; | 94 | break; |
95 | } | 95 | } |
96 | 96 | ||
97 | if (format == NULL || format->fcc != fmt->fmt.pix.pixelformat) { | 97 | if (i == ARRAY_SIZE(uvc_formats)) { |
98 | printk(KERN_INFO "Unsupported format 0x%08x.\n", | 98 | printk(KERN_INFO "Unsupported format 0x%08x.\n", |
99 | fmt->fmt.pix.pixelformat); | 99 | fmt->fmt.pix.pixelformat); |
100 | return -EINVAL; | 100 | return -EINVAL; |
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 58b72d741d9..a1e8d273103 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c | |||
@@ -119,6 +119,11 @@ static int ehci_pci_setup(struct usb_hcd *hcd) | |||
119 | ehci->broken_periodic = 1; | 119 | ehci->broken_periodic = 1; |
120 | ehci_info(ehci, "using broken periodic workaround\n"); | 120 | ehci_info(ehci, "using broken periodic workaround\n"); |
121 | } | 121 | } |
122 | if (pdev->device == 0x0806 || pdev->device == 0x0811 | ||
123 | || pdev->device == 0x0829) { | ||
124 | ehci_info(ehci, "disable lpm for langwell/penwell\n"); | ||
125 | ehci->has_lpm = 0; | ||
126 | } | ||
122 | break; | 127 | break; |
123 | case PCI_VENDOR_ID_TDI: | 128 | case PCI_VENDOR_ID_TDI: |
124 | if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) { | 129 | if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) { |
diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c index 335ee699fd8..ba52be47302 100644 --- a/drivers/usb/host/ehci-ppc-of.c +++ b/drivers/usb/host/ehci-ppc-of.c | |||
@@ -192,17 +192,19 @@ ehci_hcd_ppc_of_probe(struct platform_device *op, const struct of_device_id *mat | |||
192 | } | 192 | } |
193 | 193 | ||
194 | rv = usb_add_hcd(hcd, irq, 0); | 194 | rv = usb_add_hcd(hcd, irq, 0); |
195 | if (rv == 0) | 195 | if (rv) |
196 | return 0; | 196 | goto err_ehci; |
197 | |||
198 | return 0; | ||
197 | 199 | ||
200 | err_ehci: | ||
201 | if (ehci->has_amcc_usb23) | ||
202 | iounmap(ehci->ohci_hcctrl_reg); | ||
198 | iounmap(hcd->regs); | 203 | iounmap(hcd->regs); |
199 | err_ioremap: | 204 | err_ioremap: |
200 | irq_dispose_mapping(irq); | 205 | irq_dispose_mapping(irq); |
201 | err_irq: | 206 | err_irq: |
202 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 207 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
203 | |||
204 | if (ehci->has_amcc_usb23) | ||
205 | iounmap(ehci->ohci_hcctrl_reg); | ||
206 | err_rmr: | 208 | err_rmr: |
207 | usb_put_hcd(hcd); | 209 | usb_put_hcd(hcd); |
208 | 210 | ||
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index d1a3dfc9a40..bdba8c5d844 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c | |||
@@ -829,6 +829,7 @@ static void enqueue_an_ATL_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, | |||
829 | * almost immediately. With ISP1761, this register requires a delay of | 829 | * almost immediately. With ISP1761, this register requires a delay of |
830 | * 195ns between a write and subsequent read (see section 15.1.1.3). | 830 | * 195ns between a write and subsequent read (see section 15.1.1.3). |
831 | */ | 831 | */ |
832 | mmiowb(); | ||
832 | ndelay(195); | 833 | ndelay(195); |
833 | skip_map = isp1760_readl(hcd->regs + HC_ATL_PTD_SKIPMAP_REG); | 834 | skip_map = isp1760_readl(hcd->regs + HC_ATL_PTD_SKIPMAP_REG); |
834 | 835 | ||
@@ -870,6 +871,7 @@ static void enqueue_an_INT_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, | |||
870 | * almost immediately. With ISP1761, this register requires a delay of | 871 | * almost immediately. With ISP1761, this register requires a delay of |
871 | * 195ns between a write and subsequent read (see section 15.1.1.3). | 872 | * 195ns between a write and subsequent read (see section 15.1.1.3). |
872 | */ | 873 | */ |
874 | mmiowb(); | ||
873 | ndelay(195); | 875 | ndelay(195); |
874 | skip_map = isp1760_readl(hcd->regs + HC_INT_PTD_SKIPMAP_REG); | 876 | skip_map = isp1760_readl(hcd->regs + HC_INT_PTD_SKIPMAP_REG); |
875 | 877 | ||
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index bc3f4f42706..48e60d166ff 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -131,7 +131,7 @@ static void next_trb(struct xhci_hcd *xhci, | |||
131 | *seg = (*seg)->next; | 131 | *seg = (*seg)->next; |
132 | *trb = ((*seg)->trbs); | 132 | *trb = ((*seg)->trbs); |
133 | } else { | 133 | } else { |
134 | *trb = (*trb)++; | 134 | (*trb)++; |
135 | } | 135 | } |
136 | } | 136 | } |
137 | 137 | ||
@@ -1551,6 +1551,10 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, | |||
1551 | /* calc actual length */ | 1551 | /* calc actual length */ |
1552 | if (ep->skip) { | 1552 | if (ep->skip) { |
1553 | td->urb->iso_frame_desc[idx].actual_length = 0; | 1553 | td->urb->iso_frame_desc[idx].actual_length = 0; |
1554 | /* Update ring dequeue pointer */ | ||
1555 | while (ep_ring->dequeue != td->last_trb) | ||
1556 | inc_deq(xhci, ep_ring, false); | ||
1557 | inc_deq(xhci, ep_ring, false); | ||
1554 | return finish_td(xhci, td, event_trb, event, ep, status, true); | 1558 | return finish_td(xhci, td, event_trb, event, ep, status, true); |
1555 | } | 1559 | } |
1556 | 1560 | ||
diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c index d240de097c6..801324af947 100644 --- a/drivers/usb/misc/adutux.c +++ b/drivers/usb/misc/adutux.c | |||
@@ -439,7 +439,7 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count, | |||
439 | /* drain secondary buffer */ | 439 | /* drain secondary buffer */ |
440 | int amount = bytes_to_read < data_in_secondary ? bytes_to_read : data_in_secondary; | 440 | int amount = bytes_to_read < data_in_secondary ? bytes_to_read : data_in_secondary; |
441 | i = copy_to_user(buffer, dev->read_buffer_secondary+dev->secondary_head, amount); | 441 | i = copy_to_user(buffer, dev->read_buffer_secondary+dev->secondary_head, amount); |
442 | if (i < 0) { | 442 | if (i) { |
443 | retval = -EFAULT; | 443 | retval = -EFAULT; |
444 | goto exit; | 444 | goto exit; |
445 | } | 445 | } |
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c index 2de49c8887c..bc88c79875a 100644 --- a/drivers/usb/misc/iowarrior.c +++ b/drivers/usb/misc/iowarrior.c | |||
@@ -542,7 +542,7 @@ static long iowarrior_ioctl(struct file *file, unsigned int cmd, | |||
542 | retval = io_res; | 542 | retval = io_res; |
543 | else { | 543 | else { |
544 | io_res = copy_to_user(user_buffer, buffer, dev->report_size); | 544 | io_res = copy_to_user(user_buffer, buffer, dev->report_size); |
545 | if (io_res < 0) | 545 | if (io_res) |
546 | retval = -EFAULT; | 546 | retval = -EFAULT; |
547 | } | 547 | } |
548 | break; | 548 | break; |
@@ -574,7 +574,7 @@ static long iowarrior_ioctl(struct file *file, unsigned int cmd, | |||
574 | } | 574 | } |
575 | io_res = copy_to_user((struct iowarrior_info __user *)arg, &info, | 575 | io_res = copy_to_user((struct iowarrior_info __user *)arg, &info, |
576 | sizeof(struct iowarrior_info)); | 576 | sizeof(struct iowarrior_info)); |
577 | if (io_res < 0) | 577 | if (io_res) |
578 | retval = -EFAULT; | 578 | retval = -EFAULT; |
579 | break; | 579 | break; |
580 | } | 580 | } |
diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c index 59dc3d351b6..5ab5bb89bae 100644 --- a/drivers/usb/musb/cppi_dma.c +++ b/drivers/usb/musb/cppi_dma.c | |||
@@ -322,6 +322,7 @@ cppi_channel_allocate(struct dma_controller *c, | |||
322 | index, transmit ? 'T' : 'R', cppi_ch); | 322 | index, transmit ? 'T' : 'R', cppi_ch); |
323 | cppi_ch->hw_ep = ep; | 323 | cppi_ch->hw_ep = ep; |
324 | cppi_ch->channel.status = MUSB_DMA_STATUS_FREE; | 324 | cppi_ch->channel.status = MUSB_DMA_STATUS_FREE; |
325 | cppi_ch->channel.max_len = 0x7fffffff; | ||
325 | 326 | ||
326 | DBG(4, "Allocate CPPI%d %cX\n", index, transmit ? 'T' : 'R'); | 327 | DBG(4, "Allocate CPPI%d %cX\n", index, transmit ? 'T' : 'R'); |
327 | return &cppi_ch->channel; | 328 | return &cppi_ch->channel; |
diff --git a/drivers/usb/musb/musb_debugfs.c b/drivers/usb/musb/musb_debugfs.c index c79a5e30d43..9e8639d4e86 100644 --- a/drivers/usb/musb/musb_debugfs.c +++ b/drivers/usb/musb/musb_debugfs.c | |||
@@ -195,15 +195,14 @@ static const struct file_operations musb_regdump_fops = { | |||
195 | 195 | ||
196 | static int musb_test_mode_open(struct inode *inode, struct file *file) | 196 | static int musb_test_mode_open(struct inode *inode, struct file *file) |
197 | { | 197 | { |
198 | file->private_data = inode->i_private; | ||
199 | |||
200 | return single_open(file, musb_test_mode_show, inode->i_private); | 198 | return single_open(file, musb_test_mode_show, inode->i_private); |
201 | } | 199 | } |
202 | 200 | ||
203 | static ssize_t musb_test_mode_write(struct file *file, | 201 | static ssize_t musb_test_mode_write(struct file *file, |
204 | const char __user *ubuf, size_t count, loff_t *ppos) | 202 | const char __user *ubuf, size_t count, loff_t *ppos) |
205 | { | 203 | { |
206 | struct musb *musb = file->private_data; | 204 | struct seq_file *s = file->private_data; |
205 | struct musb *musb = s->private; | ||
207 | u8 test = 0; | 206 | u8 test = 0; |
208 | char buf[18]; | 207 | char buf[18]; |
209 | 208 | ||
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 6fca870e957..d065e23f123 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c | |||
@@ -300,6 +300,11 @@ static void txstate(struct musb *musb, struct musb_request *req) | |||
300 | #ifndef CONFIG_MUSB_PIO_ONLY | 300 | #ifndef CONFIG_MUSB_PIO_ONLY |
301 | if (is_dma_capable() && musb_ep->dma) { | 301 | if (is_dma_capable() && musb_ep->dma) { |
302 | struct dma_controller *c = musb->dma_controller; | 302 | struct dma_controller *c = musb->dma_controller; |
303 | size_t request_size; | ||
304 | |||
305 | /* setup DMA, then program endpoint CSR */ | ||
306 | request_size = min_t(size_t, request->length - request->actual, | ||
307 | musb_ep->dma->max_len); | ||
303 | 308 | ||
304 | use_dma = (request->dma != DMA_ADDR_INVALID); | 309 | use_dma = (request->dma != DMA_ADDR_INVALID); |
305 | 310 | ||
@@ -307,11 +312,6 @@ static void txstate(struct musb *musb, struct musb_request *req) | |||
307 | 312 | ||
308 | #ifdef CONFIG_USB_INVENTRA_DMA | 313 | #ifdef CONFIG_USB_INVENTRA_DMA |
309 | { | 314 | { |
310 | size_t request_size; | ||
311 | |||
312 | /* setup DMA, then program endpoint CSR */ | ||
313 | request_size = min_t(size_t, request->length, | ||
314 | musb_ep->dma->max_len); | ||
315 | if (request_size < musb_ep->packet_sz) | 315 | if (request_size < musb_ep->packet_sz) |
316 | musb_ep->dma->desired_mode = 0; | 316 | musb_ep->dma->desired_mode = 0; |
317 | else | 317 | else |
@@ -373,8 +373,8 @@ static void txstate(struct musb *musb, struct musb_request *req) | |||
373 | use_dma = use_dma && c->channel_program( | 373 | use_dma = use_dma && c->channel_program( |
374 | musb_ep->dma, musb_ep->packet_sz, | 374 | musb_ep->dma, musb_ep->packet_sz, |
375 | 0, | 375 | 0, |
376 | request->dma, | 376 | request->dma + request->actual, |
377 | request->length); | 377 | request_size); |
378 | if (!use_dma) { | 378 | if (!use_dma) { |
379 | c->channel_release(musb_ep->dma); | 379 | c->channel_release(musb_ep->dma); |
380 | musb_ep->dma = NULL; | 380 | musb_ep->dma = NULL; |
@@ -386,8 +386,8 @@ static void txstate(struct musb *musb, struct musb_request *req) | |||
386 | use_dma = use_dma && c->channel_program( | 386 | use_dma = use_dma && c->channel_program( |
387 | musb_ep->dma, musb_ep->packet_sz, | 387 | musb_ep->dma, musb_ep->packet_sz, |
388 | request->zero, | 388 | request->zero, |
389 | request->dma, | 389 | request->dma + request->actual, |
390 | request->length); | 390 | request_size); |
391 | #endif | 391 | #endif |
392 | } | 392 | } |
393 | #endif | 393 | #endif |
@@ -501,26 +501,14 @@ void musb_g_tx(struct musb *musb, u8 epnum) | |||
501 | request->zero = 0; | 501 | request->zero = 0; |
502 | } | 502 | } |
503 | 503 | ||
504 | /* ... or if not, then complete it. */ | 504 | if (request->actual == request->length) { |
505 | musb_g_giveback(musb_ep, request, 0); | 505 | musb_g_giveback(musb_ep, request, 0); |
506 | 506 | request = musb_ep->desc ? next_request(musb_ep) : NULL; | |
507 | /* | 507 | if (!request) { |
508 | * Kickstart next transfer if appropriate; | 508 | DBG(4, "%s idle now\n", |
509 | * the packet that just completed might not | 509 | musb_ep->end_point.name); |
510 | * be transmitted for hours or days. | 510 | return; |
511 | * REVISIT for double buffering... | 511 | } |
512 | * FIXME revisit for stalls too... | ||
513 | */ | ||
514 | musb_ep_select(mbase, epnum); | ||
515 | csr = musb_readw(epio, MUSB_TXCSR); | ||
516 | if (csr & MUSB_TXCSR_FIFONOTEMPTY) | ||
517 | return; | ||
518 | |||
519 | request = musb_ep->desc ? next_request(musb_ep) : NULL; | ||
520 | if (!request) { | ||
521 | DBG(4, "%s idle now\n", | ||
522 | musb_ep->end_point.name); | ||
523 | return; | ||
524 | } | 512 | } |
525 | } | 513 | } |
526 | 514 | ||
@@ -568,11 +556,19 @@ static void rxstate(struct musb *musb, struct musb_request *req) | |||
568 | { | 556 | { |
569 | const u8 epnum = req->epnum; | 557 | const u8 epnum = req->epnum; |
570 | struct usb_request *request = &req->request; | 558 | struct usb_request *request = &req->request; |
571 | struct musb_ep *musb_ep = &musb->endpoints[epnum].ep_out; | 559 | struct musb_ep *musb_ep; |
572 | void __iomem *epio = musb->endpoints[epnum].regs; | 560 | void __iomem *epio = musb->endpoints[epnum].regs; |
573 | unsigned fifo_count = 0; | 561 | unsigned fifo_count = 0; |
574 | u16 len = musb_ep->packet_sz; | 562 | u16 len; |
575 | u16 csr = musb_readw(epio, MUSB_RXCSR); | 563 | u16 csr = musb_readw(epio, MUSB_RXCSR); |
564 | struct musb_hw_ep *hw_ep = &musb->endpoints[epnum]; | ||
565 | |||
566 | if (hw_ep->is_shared_fifo) | ||
567 | musb_ep = &hw_ep->ep_in; | ||
568 | else | ||
569 | musb_ep = &hw_ep->ep_out; | ||
570 | |||
571 | len = musb_ep->packet_sz; | ||
576 | 572 | ||
577 | /* We shouldn't get here while DMA is active, but we do... */ | 573 | /* We shouldn't get here while DMA is active, but we do... */ |
578 | if (dma_channel_status(musb_ep->dma) == MUSB_DMA_STATUS_BUSY) { | 574 | if (dma_channel_status(musb_ep->dma) == MUSB_DMA_STATUS_BUSY) { |
@@ -647,8 +643,8 @@ static void rxstate(struct musb *musb, struct musb_request *req) | |||
647 | */ | 643 | */ |
648 | 644 | ||
649 | csr |= MUSB_RXCSR_DMAENAB; | 645 | csr |= MUSB_RXCSR_DMAENAB; |
650 | #ifdef USE_MODE1 | ||
651 | csr |= MUSB_RXCSR_AUTOCLEAR; | 646 | csr |= MUSB_RXCSR_AUTOCLEAR; |
647 | #ifdef USE_MODE1 | ||
652 | /* csr |= MUSB_RXCSR_DMAMODE; */ | 648 | /* csr |= MUSB_RXCSR_DMAMODE; */ |
653 | 649 | ||
654 | /* this special sequence (enabling and then | 650 | /* this special sequence (enabling and then |
@@ -663,10 +659,11 @@ static void rxstate(struct musb *musb, struct musb_request *req) | |||
663 | if (request->actual < request->length) { | 659 | if (request->actual < request->length) { |
664 | int transfer_size = 0; | 660 | int transfer_size = 0; |
665 | #ifdef USE_MODE1 | 661 | #ifdef USE_MODE1 |
666 | transfer_size = min(request->length, | 662 | transfer_size = min(request->length - request->actual, |
667 | channel->max_len); | 663 | channel->max_len); |
668 | #else | 664 | #else |
669 | transfer_size = len; | 665 | transfer_size = min(request->length - request->actual, |
666 | (unsigned)len); | ||
670 | #endif | 667 | #endif |
671 | if (transfer_size <= musb_ep->packet_sz) | 668 | if (transfer_size <= musb_ep->packet_sz) |
672 | musb_ep->dma->desired_mode = 0; | 669 | musb_ep->dma->desired_mode = 0; |
@@ -740,9 +737,15 @@ void musb_g_rx(struct musb *musb, u8 epnum) | |||
740 | u16 csr; | 737 | u16 csr; |
741 | struct usb_request *request; | 738 | struct usb_request *request; |
742 | void __iomem *mbase = musb->mregs; | 739 | void __iomem *mbase = musb->mregs; |
743 | struct musb_ep *musb_ep = &musb->endpoints[epnum].ep_out; | 740 | struct musb_ep *musb_ep; |
744 | void __iomem *epio = musb->endpoints[epnum].regs; | 741 | void __iomem *epio = musb->endpoints[epnum].regs; |
745 | struct dma_channel *dma; | 742 | struct dma_channel *dma; |
743 | struct musb_hw_ep *hw_ep = &musb->endpoints[epnum]; | ||
744 | |||
745 | if (hw_ep->is_shared_fifo) | ||
746 | musb_ep = &hw_ep->ep_in; | ||
747 | else | ||
748 | musb_ep = &hw_ep->ep_out; | ||
746 | 749 | ||
747 | musb_ep_select(mbase, epnum); | 750 | musb_ep_select(mbase, epnum); |
748 | 751 | ||
@@ -1081,7 +1084,7 @@ struct free_record { | |||
1081 | /* | 1084 | /* |
1082 | * Context: controller locked, IRQs blocked. | 1085 | * Context: controller locked, IRQs blocked. |
1083 | */ | 1086 | */ |
1084 | static void musb_ep_restart(struct musb *musb, struct musb_request *req) | 1087 | void musb_ep_restart(struct musb *musb, struct musb_request *req) |
1085 | { | 1088 | { |
1086 | DBG(3, "<== %s request %p len %u on hw_ep%d\n", | 1089 | DBG(3, "<== %s request %p len %u on hw_ep%d\n", |
1087 | req->tx ? "TX/IN" : "RX/OUT", | 1090 | req->tx ? "TX/IN" : "RX/OUT", |
diff --git a/drivers/usb/musb/musb_gadget.h b/drivers/usb/musb/musb_gadget.h index c8b140325d8..572b1da7f2d 100644 --- a/drivers/usb/musb/musb_gadget.h +++ b/drivers/usb/musb/musb_gadget.h | |||
@@ -105,4 +105,6 @@ extern void musb_gadget_cleanup(struct musb *); | |||
105 | 105 | ||
106 | extern void musb_g_giveback(struct musb_ep *, struct usb_request *, int); | 106 | extern void musb_g_giveback(struct musb_ep *, struct usb_request *, int); |
107 | 107 | ||
108 | extern void musb_ep_restart(struct musb *, struct musb_request *); | ||
109 | |||
108 | #endif /* __MUSB_GADGET_H */ | 110 | #endif /* __MUSB_GADGET_H */ |
diff --git a/drivers/usb/musb/musb_gadget_ep0.c b/drivers/usb/musb/musb_gadget_ep0.c index 59bef8f3a35..6dd03f4c5f4 100644 --- a/drivers/usb/musb/musb_gadget_ep0.c +++ b/drivers/usb/musb/musb_gadget_ep0.c | |||
@@ -261,6 +261,7 @@ __acquires(musb->lock) | |||
261 | ctrlrequest->wIndex & 0x0f; | 261 | ctrlrequest->wIndex & 0x0f; |
262 | struct musb_ep *musb_ep; | 262 | struct musb_ep *musb_ep; |
263 | struct musb_hw_ep *ep; | 263 | struct musb_hw_ep *ep; |
264 | struct musb_request *request; | ||
264 | void __iomem *regs; | 265 | void __iomem *regs; |
265 | int is_in; | 266 | int is_in; |
266 | u16 csr; | 267 | u16 csr; |
@@ -302,6 +303,14 @@ __acquires(musb->lock) | |||
302 | musb_writew(regs, MUSB_RXCSR, csr); | 303 | musb_writew(regs, MUSB_RXCSR, csr); |
303 | } | 304 | } |
304 | 305 | ||
306 | /* Maybe start the first request in the queue */ | ||
307 | request = to_musb_request( | ||
308 | next_request(musb_ep)); | ||
309 | if (!musb_ep->busy && request) { | ||
310 | DBG(3, "restarting the request\n"); | ||
311 | musb_ep_restart(musb, request); | ||
312 | } | ||
313 | |||
305 | /* select ep0 again */ | 314 | /* select ep0 again */ |
306 | musb_ep_select(mbase, 0); | 315 | musb_ep_select(mbase, 0); |
307 | } break; | 316 | } break; |
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 877d20b1dff..9e65c47cc98 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c | |||
@@ -660,6 +660,12 @@ static bool musb_tx_dma_program(struct dma_controller *dma, | |||
660 | 660 | ||
661 | qh->segsize = length; | 661 | qh->segsize = length; |
662 | 662 | ||
663 | /* | ||
664 | * Ensure the data reaches to main memory before starting | ||
665 | * DMA transfer | ||
666 | */ | ||
667 | wmb(); | ||
668 | |||
663 | if (!dma->channel_program(channel, pkt_size, mode, | 669 | if (!dma->channel_program(channel, pkt_size, mode, |
664 | urb->transfer_dma + offset, length)) { | 670 | urb->transfer_dma + offset, length)) { |
665 | dma->channel_release(channel); | 671 | dma->channel_release(channel); |
diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c index 0e8888588d4..0bc97698af1 100644 --- a/drivers/usb/otg/twl4030-usb.c +++ b/drivers/usb/otg/twl4030-usb.c | |||
@@ -347,11 +347,20 @@ static void twl4030_i2c_access(struct twl4030_usb *twl, int on) | |||
347 | } | 347 | } |
348 | } | 348 | } |
349 | 349 | ||
350 | static void twl4030_phy_power(struct twl4030_usb *twl, int on) | 350 | static void __twl4030_phy_power(struct twl4030_usb *twl, int on) |
351 | { | 351 | { |
352 | u8 pwr; | 352 | u8 pwr = twl4030_usb_read(twl, PHY_PWR_CTRL); |
353 | |||
354 | if (on) | ||
355 | pwr &= ~PHY_PWR_PHYPWD; | ||
356 | else | ||
357 | pwr |= PHY_PWR_PHYPWD; | ||
353 | 358 | ||
354 | pwr = twl4030_usb_read(twl, PHY_PWR_CTRL); | 359 | WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0); |
360 | } | ||
361 | |||
362 | static void twl4030_phy_power(struct twl4030_usb *twl, int on) | ||
363 | { | ||
355 | if (on) { | 364 | if (on) { |
356 | regulator_enable(twl->usb3v1); | 365 | regulator_enable(twl->usb3v1); |
357 | regulator_enable(twl->usb1v8); | 366 | regulator_enable(twl->usb1v8); |
@@ -365,15 +374,13 @@ static void twl4030_phy_power(struct twl4030_usb *twl, int on) | |||
365 | twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, | 374 | twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, |
366 | VUSB_DEDICATED2); | 375 | VUSB_DEDICATED2); |
367 | regulator_enable(twl->usb1v5); | 376 | regulator_enable(twl->usb1v5); |
368 | pwr &= ~PHY_PWR_PHYPWD; | 377 | __twl4030_phy_power(twl, 1); |
369 | WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0); | ||
370 | twl4030_usb_write(twl, PHY_CLK_CTRL, | 378 | twl4030_usb_write(twl, PHY_CLK_CTRL, |
371 | twl4030_usb_read(twl, PHY_CLK_CTRL) | | 379 | twl4030_usb_read(twl, PHY_CLK_CTRL) | |
372 | (PHY_CLK_CTRL_CLOCKGATING_EN | | 380 | (PHY_CLK_CTRL_CLOCKGATING_EN | |
373 | PHY_CLK_CTRL_CLK32K_EN)); | 381 | PHY_CLK_CTRL_CLK32K_EN)); |
374 | } else { | 382 | } else { |
375 | pwr |= PHY_PWR_PHYPWD; | 383 | __twl4030_phy_power(twl, 0); |
376 | WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0); | ||
377 | regulator_disable(twl->usb1v5); | 384 | regulator_disable(twl->usb1v5); |
378 | regulator_disable(twl->usb1v8); | 385 | regulator_disable(twl->usb1v8); |
379 | regulator_disable(twl->usb3v1); | 386 | regulator_disable(twl->usb3v1); |
@@ -387,19 +394,25 @@ static void twl4030_phy_suspend(struct twl4030_usb *twl, int controller_off) | |||
387 | 394 | ||
388 | twl4030_phy_power(twl, 0); | 395 | twl4030_phy_power(twl, 0); |
389 | twl->asleep = 1; | 396 | twl->asleep = 1; |
397 | dev_dbg(twl->dev, "%s\n", __func__); | ||
390 | } | 398 | } |
391 | 399 | ||
392 | static void twl4030_phy_resume(struct twl4030_usb *twl) | 400 | static void __twl4030_phy_resume(struct twl4030_usb *twl) |
393 | { | 401 | { |
394 | if (!twl->asleep) | ||
395 | return; | ||
396 | |||
397 | twl4030_phy_power(twl, 1); | 402 | twl4030_phy_power(twl, 1); |
398 | twl4030_i2c_access(twl, 1); | 403 | twl4030_i2c_access(twl, 1); |
399 | twl4030_usb_set_mode(twl, twl->usb_mode); | 404 | twl4030_usb_set_mode(twl, twl->usb_mode); |
400 | if (twl->usb_mode == T2_USB_MODE_ULPI) | 405 | if (twl->usb_mode == T2_USB_MODE_ULPI) |
401 | twl4030_i2c_access(twl, 0); | 406 | twl4030_i2c_access(twl, 0); |
407 | } | ||
408 | |||
409 | static void twl4030_phy_resume(struct twl4030_usb *twl) | ||
410 | { | ||
411 | if (!twl->asleep) | ||
412 | return; | ||
413 | __twl4030_phy_resume(twl); | ||
402 | twl->asleep = 0; | 414 | twl->asleep = 0; |
415 | dev_dbg(twl->dev, "%s\n", __func__); | ||
403 | } | 416 | } |
404 | 417 | ||
405 | static int twl4030_usb_ldo_init(struct twl4030_usb *twl) | 418 | static int twl4030_usb_ldo_init(struct twl4030_usb *twl) |
@@ -408,8 +421,8 @@ static int twl4030_usb_ldo_init(struct twl4030_usb *twl) | |||
408 | twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0xC0, PROTECT_KEY); | 421 | twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0xC0, PROTECT_KEY); |
409 | twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0x0C, PROTECT_KEY); | 422 | twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0x0C, PROTECT_KEY); |
410 | 423 | ||
411 | /* put VUSB3V1 LDO in active state */ | 424 | /* Keep VUSB3V1 LDO in sleep state until VBUS/ID change detected*/ |
412 | twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2); | 425 | /*twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2);*/ |
413 | 426 | ||
414 | /* input to VUSB3V1 LDO is from VBAT, not VBUS */ | 427 | /* input to VUSB3V1 LDO is from VBAT, not VBUS */ |
415 | twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x14, VUSB_DEDICATED1); | 428 | twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x14, VUSB_DEDICATED1); |
@@ -502,6 +515,26 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl) | |||
502 | return IRQ_HANDLED; | 515 | return IRQ_HANDLED; |
503 | } | 516 | } |
504 | 517 | ||
518 | static void twl4030_usb_phy_init(struct twl4030_usb *twl) | ||
519 | { | ||
520 | int status; | ||
521 | |||
522 | status = twl4030_usb_linkstat(twl); | ||
523 | if (status >= 0) { | ||
524 | if (status == USB_EVENT_NONE) { | ||
525 | __twl4030_phy_power(twl, 0); | ||
526 | twl->asleep = 1; | ||
527 | } else { | ||
528 | __twl4030_phy_resume(twl); | ||
529 | twl->asleep = 0; | ||
530 | } | ||
531 | |||
532 | blocking_notifier_call_chain(&twl->otg.notifier, status, | ||
533 | twl->otg.gadget); | ||
534 | } | ||
535 | sysfs_notify(&twl->dev->kobj, NULL, "vbus"); | ||
536 | } | ||
537 | |||
505 | static int twl4030_set_suspend(struct otg_transceiver *x, int suspend) | 538 | static int twl4030_set_suspend(struct otg_transceiver *x, int suspend) |
506 | { | 539 | { |
507 | struct twl4030_usb *twl = xceiv_to_twl(x); | 540 | struct twl4030_usb *twl = xceiv_to_twl(x); |
@@ -568,7 +601,7 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev) | |||
568 | twl->otg.set_peripheral = twl4030_set_peripheral; | 601 | twl->otg.set_peripheral = twl4030_set_peripheral; |
569 | twl->otg.set_suspend = twl4030_set_suspend; | 602 | twl->otg.set_suspend = twl4030_set_suspend; |
570 | twl->usb_mode = pdata->usb_mode; | 603 | twl->usb_mode = pdata->usb_mode; |
571 | twl->asleep = 1; | 604 | twl->asleep = 1; |
572 | 605 | ||
573 | /* init spinlock for workqueue */ | 606 | /* init spinlock for workqueue */ |
574 | spin_lock_init(&twl->lock); | 607 | spin_lock_init(&twl->lock); |
@@ -606,15 +639,10 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev) | |||
606 | return status; | 639 | return status; |
607 | } | 640 | } |
608 | 641 | ||
609 | /* The IRQ handler just handles changes from the previous states | 642 | /* Power down phy or make it work according to |
610 | * of the ID and VBUS pins ... in probe() we must initialize that | 643 | * current link state. |
611 | * previous state. The easy way: fake an IRQ. | ||
612 | * | ||
613 | * REVISIT: a real IRQ might have happened already, if PREEMPT is | ||
614 | * enabled. Else the IRQ may not yet be configured or enabled, | ||
615 | * because of scheduling delays. | ||
616 | */ | 644 | */ |
617 | twl4030_usb_irq(twl->irq, twl); | 645 | twl4030_usb_phy_init(twl); |
618 | 646 | ||
619 | dev_info(&pdev->dev, "Initialized TWL4030 USB module\n"); | 647 | dev_info(&pdev->dev, "Initialized TWL4030 USB module\n"); |
620 | return 0; | 648 | return 0; |
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 2bef4415c19..4f1744c5871 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c | |||
@@ -56,6 +56,7 @@ static int debug; | |||
56 | static const struct usb_device_id id_table[] = { | 56 | static const struct usb_device_id id_table[] = { |
57 | { USB_DEVICE(0x0471, 0x066A) }, /* AKTAKOM ACE-1001 cable */ | 57 | { USB_DEVICE(0x0471, 0x066A) }, /* AKTAKOM ACE-1001 cable */ |
58 | { USB_DEVICE(0x0489, 0xE000) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */ | 58 | { USB_DEVICE(0x0489, 0xE000) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */ |
59 | { USB_DEVICE(0x0489, 0xE003) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */ | ||
59 | { USB_DEVICE(0x0745, 0x1000) }, /* CipherLab USB CCD Barcode Scanner 1000 */ | 60 | { USB_DEVICE(0x0745, 0x1000) }, /* CipherLab USB CCD Barcode Scanner 1000 */ |
60 | { USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */ | 61 | { USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */ |
61 | { USB_DEVICE(0x08FD, 0x000A) }, /* Digianswer A/S , ZigBee/802.15.4 MAC Device */ | 62 | { USB_DEVICE(0x08FD, 0x000A) }, /* Digianswer A/S , ZigBee/802.15.4 MAC Device */ |
@@ -88,6 +89,7 @@ static const struct usb_device_id id_table[] = { | |||
88 | { USB_DEVICE(0x10C4, 0x8149) }, /* West Mountain Radio Computerized Battery Analyzer */ | 89 | { USB_DEVICE(0x10C4, 0x8149) }, /* West Mountain Radio Computerized Battery Analyzer */ |
89 | { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */ | 90 | { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */ |
90 | { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */ | 91 | { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */ |
92 | { USB_DEVICE(0x10C4, 0x8156) }, /* B&G H3000 link cable */ | ||
91 | { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ | 93 | { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ |
92 | { USB_DEVICE(0x10C4, 0x818B) }, /* AVIT Research USB to TTL */ | 94 | { USB_DEVICE(0x10C4, 0x818B) }, /* AVIT Research USB to TTL */ |
93 | { USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */ | 95 | { USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */ |
@@ -109,6 +111,7 @@ static const struct usb_device_id id_table[] = { | |||
109 | { USB_DEVICE(0x10C4, 0x83A8) }, /* Amber Wireless AMB2560 */ | 111 | { USB_DEVICE(0x10C4, 0x83A8) }, /* Amber Wireless AMB2560 */ |
110 | { USB_DEVICE(0x10C4, 0x8411) }, /* Kyocera GPS Module */ | 112 | { USB_DEVICE(0x10C4, 0x8411) }, /* Kyocera GPS Module */ |
111 | { USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */ | 113 | { USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */ |
114 | { USB_DEVICE(0x10C4, 0x8477) }, /* Balluff RFID */ | ||
112 | { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ | 115 | { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ |
113 | { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ | 116 | { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ |
114 | { USB_DEVICE(0x10C4, 0xEA71) }, /* Infinity GPS-MIC-1 Radio Monophone */ | 117 | { USB_DEVICE(0x10C4, 0xEA71) }, /* Infinity GPS-MIC-1 Radio Monophone */ |
@@ -122,14 +125,14 @@ static const struct usb_device_id id_table[] = { | |||
122 | { USB_DEVICE(0x1555, 0x0004) }, /* Owen AC4 USB-RS485 Converter */ | 125 | { USB_DEVICE(0x1555, 0x0004) }, /* Owen AC4 USB-RS485 Converter */ |
123 | { USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */ | 126 | { USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */ |
124 | { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */ | 127 | { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */ |
125 | { USB_DEVICE(0x17F4, 0xAAAA) }, /* Wavesense Jazz blood glucose meter */ | ||
126 | { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */ | ||
127 | { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ | ||
128 | { USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */ | ||
129 | { USB_DEVICE(0x16DC, 0x0010) }, /* W-IE-NE-R Plein & Baus GmbH PL512 Power Supply */ | 128 | { USB_DEVICE(0x16DC, 0x0010) }, /* W-IE-NE-R Plein & Baus GmbH PL512 Power Supply */ |
130 | { USB_DEVICE(0x16DC, 0x0011) }, /* W-IE-NE-R Plein & Baus GmbH RCM Remote Control for MARATON Power Supply */ | 129 | { USB_DEVICE(0x16DC, 0x0011) }, /* W-IE-NE-R Plein & Baus GmbH RCM Remote Control for MARATON Power Supply */ |
131 | { USB_DEVICE(0x16DC, 0x0012) }, /* W-IE-NE-R Plein & Baus GmbH MPOD Multi Channel Power Supply */ | 130 | { USB_DEVICE(0x16DC, 0x0012) }, /* W-IE-NE-R Plein & Baus GmbH MPOD Multi Channel Power Supply */ |
132 | { USB_DEVICE(0x16DC, 0x0015) }, /* W-IE-NE-R Plein & Baus GmbH CML Control, Monitoring and Data Logger */ | 131 | { USB_DEVICE(0x16DC, 0x0015) }, /* W-IE-NE-R Plein & Baus GmbH CML Control, Monitoring and Data Logger */ |
132 | { USB_DEVICE(0x17F4, 0xAAAA) }, /* Wavesense Jazz blood glucose meter */ | ||
133 | { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */ | ||
134 | { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ | ||
135 | { USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */ | ||
133 | { } /* Terminating Entry */ | 136 | { } /* Terminating Entry */ |
134 | }; | 137 | }; |
135 | 138 | ||
@@ -222,8 +225,8 @@ static struct usb_serial_driver cp210x_device = { | |||
222 | #define BITS_STOP_2 0x0002 | 225 | #define BITS_STOP_2 0x0002 |
223 | 226 | ||
224 | /* CP210X_SET_BREAK */ | 227 | /* CP210X_SET_BREAK */ |
225 | #define BREAK_ON 0x0000 | 228 | #define BREAK_ON 0x0001 |
226 | #define BREAK_OFF 0x0001 | 229 | #define BREAK_OFF 0x0000 |
227 | 230 | ||
228 | /* CP210X_(SET_MHS|GET_MDMSTS) */ | 231 | /* CP210X_(SET_MHS|GET_MDMSTS) */ |
229 | #define CONTROL_DTR 0x0001 | 232 | #define CONTROL_DTR 0x0001 |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index eb12d9b096b..97cc87d654c 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -180,6 +180,7 @@ static struct usb_device_id id_table_combined [] = { | |||
180 | { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) }, | 180 | { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) }, |
181 | { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) }, | 181 | { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) }, |
182 | { USB_DEVICE(FTDI_VID, FTDI_SPROG_II) }, | 182 | { USB_DEVICE(FTDI_VID, FTDI_SPROG_II) }, |
183 | { USB_DEVICE(FTDI_VID, FTDI_LENZ_LIUSB_PID) }, | ||
183 | { USB_DEVICE(FTDI_VID, FTDI_XF_632_PID) }, | 184 | { USB_DEVICE(FTDI_VID, FTDI_XF_632_PID) }, |
184 | { USB_DEVICE(FTDI_VID, FTDI_XF_634_PID) }, | 185 | { USB_DEVICE(FTDI_VID, FTDI_XF_634_PID) }, |
185 | { USB_DEVICE(FTDI_VID, FTDI_XF_547_PID) }, | 186 | { USB_DEVICE(FTDI_VID, FTDI_XF_547_PID) }, |
@@ -750,6 +751,16 @@ static struct usb_device_id id_table_combined [] = { | |||
750 | { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_SH4_PID), | 751 | { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_SH4_PID), |
751 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 752 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
752 | { USB_DEVICE(FTDI_VID, SEGWAY_RMP200_PID) }, | 753 | { USB_DEVICE(FTDI_VID, SEGWAY_RMP200_PID) }, |
754 | { USB_DEVICE(IONICS_VID, IONICS_PLUGCOMPUTER_PID), | ||
755 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | ||
756 | { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_24_MASTER_WING_PID) }, | ||
757 | { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_PC_WING_PID) }, | ||
758 | { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_USB_DMX_PID) }, | ||
759 | { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_MIDI_TIMECODE_PID) }, | ||
760 | { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_MINI_WING_PID) }, | ||
761 | { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_MAXI_WING_PID) }, | ||
762 | { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_MEDIA_WING_PID) }, | ||
763 | { USB_DEVICE(FTDI_VID, FTDI_CHAMSYS_WING_PID) }, | ||
753 | { }, /* Optional parameter entry */ | 764 | { }, /* Optional parameter entry */ |
754 | { } /* Terminating entry */ | 765 | { } /* Terminating entry */ |
755 | }; | 766 | }; |
@@ -1376,7 +1387,7 @@ static void ftdi_set_max_packet_size(struct usb_serial_port *port) | |||
1376 | } | 1387 | } |
1377 | 1388 | ||
1378 | /* set max packet size based on descriptor */ | 1389 | /* set max packet size based on descriptor */ |
1379 | priv->max_packet_size = ep_desc->wMaxPacketSize; | 1390 | priv->max_packet_size = le16_to_cpu(ep_desc->wMaxPacketSize); |
1380 | 1391 | ||
1381 | dev_info(&udev->dev, "Setting MaxPacketSize %d\n", priv->max_packet_size); | 1392 | dev_info(&udev->dev, "Setting MaxPacketSize %d\n", priv->max_packet_size); |
1382 | } | 1393 | } |
@@ -1831,7 +1842,7 @@ static int ftdi_process_packet(struct tty_struct *tty, | |||
1831 | 1842 | ||
1832 | if (port->port.console && port->sysrq) { | 1843 | if (port->port.console && port->sysrq) { |
1833 | for (i = 0; i < len; i++, ch++) { | 1844 | for (i = 0; i < len; i++, ch++) { |
1834 | if (!usb_serial_handle_sysrq_char(tty, port, *ch)) | 1845 | if (!usb_serial_handle_sysrq_char(port, *ch)) |
1835 | tty_insert_flip_char(tty, *ch, flag); | 1846 | tty_insert_flip_char(tty, *ch, flag); |
1836 | } | 1847 | } |
1837 | } else { | 1848 | } else { |
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 6e612c52e76..15a4583775a 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h | |||
@@ -110,6 +110,9 @@ | |||
110 | /* Propox devices */ | 110 | /* Propox devices */ |
111 | #define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 | 111 | #define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 |
112 | 112 | ||
113 | /* Lenz LI-USB Computer Interface. */ | ||
114 | #define FTDI_LENZ_LIUSB_PID 0xD780 | ||
115 | |||
113 | /* | 116 | /* |
114 | * Xsens Technologies BV products (http://www.xsens.com). | 117 | * Xsens Technologies BV products (http://www.xsens.com). |
115 | */ | 118 | */ |
@@ -132,6 +135,18 @@ | |||
132 | #define FTDI_NDI_AURORA_SCU_PID 0xDA74 /* NDI Aurora SCU */ | 135 | #define FTDI_NDI_AURORA_SCU_PID 0xDA74 /* NDI Aurora SCU */ |
133 | 136 | ||
134 | /* | 137 | /* |
138 | * ChamSys Limited (www.chamsys.co.uk) USB wing/interface product IDs | ||
139 | */ | ||
140 | #define FTDI_CHAMSYS_24_MASTER_WING_PID 0xDAF8 | ||
141 | #define FTDI_CHAMSYS_PC_WING_PID 0xDAF9 | ||
142 | #define FTDI_CHAMSYS_USB_DMX_PID 0xDAFA | ||
143 | #define FTDI_CHAMSYS_MIDI_TIMECODE_PID 0xDAFB | ||
144 | #define FTDI_CHAMSYS_MINI_WING_PID 0xDAFC | ||
145 | #define FTDI_CHAMSYS_MAXI_WING_PID 0xDAFD | ||
146 | #define FTDI_CHAMSYS_MEDIA_WING_PID 0xDAFE | ||
147 | #define FTDI_CHAMSYS_WING_PID 0xDAFF | ||
148 | |||
149 | /* | ||
135 | * Westrex International devices submitted by Cory Lee | 150 | * Westrex International devices submitted by Cory Lee |
136 | */ | 151 | */ |
137 | #define FTDI_WESTREX_MODEL_777_PID 0xDC00 /* Model 777 */ | 152 | #define FTDI_WESTREX_MODEL_777_PID 0xDC00 /* Model 777 */ |
@@ -989,6 +1004,12 @@ | |||
989 | #define ALTI2_N3_PID 0x6001 /* Neptune 3 */ | 1004 | #define ALTI2_N3_PID 0x6001 /* Neptune 3 */ |
990 | 1005 | ||
991 | /* | 1006 | /* |
1007 | * Ionics PlugComputer | ||
1008 | */ | ||
1009 | #define IONICS_VID 0x1c0c | ||
1010 | #define IONICS_PLUGCOMPUTER_PID 0x0102 | ||
1011 | |||
1012 | /* | ||
992 | * Dresden Elektronik Sensor Terminal Board | 1013 | * Dresden Elektronik Sensor Terminal Board |
993 | */ | 1014 | */ |
994 | #define DE_VID 0x1cf1 /* Vendor ID */ | 1015 | #define DE_VID 0x1cf1 /* Vendor ID */ |
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index ca92f67747c..e6833e216fc 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
@@ -343,7 +343,7 @@ void usb_serial_generic_process_read_urb(struct urb *urb) | |||
343 | tty_insert_flip_string(tty, ch, urb->actual_length); | 343 | tty_insert_flip_string(tty, ch, urb->actual_length); |
344 | else { | 344 | else { |
345 | for (i = 0; i < urb->actual_length; i++, ch++) { | 345 | for (i = 0; i < urb->actual_length; i++, ch++) { |
346 | if (!usb_serial_handle_sysrq_char(tty, port, *ch)) | 346 | if (!usb_serial_handle_sysrq_char(port, *ch)) |
347 | tty_insert_flip_char(tty, *ch, TTY_NORMAL); | 347 | tty_insert_flip_char(tty, *ch, TTY_NORMAL); |
348 | } | 348 | } |
349 | } | 349 | } |
@@ -448,12 +448,11 @@ void usb_serial_generic_unthrottle(struct tty_struct *tty) | |||
448 | EXPORT_SYMBOL_GPL(usb_serial_generic_unthrottle); | 448 | EXPORT_SYMBOL_GPL(usb_serial_generic_unthrottle); |
449 | 449 | ||
450 | #ifdef CONFIG_MAGIC_SYSRQ | 450 | #ifdef CONFIG_MAGIC_SYSRQ |
451 | int usb_serial_handle_sysrq_char(struct tty_struct *tty, | 451 | int usb_serial_handle_sysrq_char(struct usb_serial_port *port, unsigned int ch) |
452 | struct usb_serial_port *port, unsigned int ch) | ||
453 | { | 452 | { |
454 | if (port->sysrq && port->port.console) { | 453 | if (port->sysrq && port->port.console) { |
455 | if (ch && time_before(jiffies, port->sysrq)) { | 454 | if (ch && time_before(jiffies, port->sysrq)) { |
456 | handle_sysrq(ch, tty); | 455 | handle_sysrq(ch); |
457 | port->sysrq = 0; | 456 | port->sysrq = 0; |
458 | return 1; | 457 | return 1; |
459 | } | 458 | } |
@@ -462,8 +461,7 @@ int usb_serial_handle_sysrq_char(struct tty_struct *tty, | |||
462 | return 0; | 461 | return 0; |
463 | } | 462 | } |
464 | #else | 463 | #else |
465 | int usb_serial_handle_sysrq_char(struct tty_struct *tty, | 464 | int usb_serial_handle_sysrq_char(struct usb_serial_port *port, unsigned int ch) |
466 | struct usb_serial_port *port, unsigned int ch) | ||
467 | { | 465 | { |
468 | return 0; | 466 | return 0; |
469 | } | 467 | } |
@@ -518,6 +516,7 @@ void usb_serial_generic_disconnect(struct usb_serial *serial) | |||
518 | for (i = 0; i < serial->num_ports; ++i) | 516 | for (i = 0; i < serial->num_ports; ++i) |
519 | generic_cleanup(serial->port[i]); | 517 | generic_cleanup(serial->port[i]); |
520 | } | 518 | } |
519 | EXPORT_SYMBOL_GPL(usb_serial_generic_disconnect); | ||
521 | 520 | ||
522 | void usb_serial_generic_release(struct usb_serial *serial) | 521 | void usb_serial_generic_release(struct usb_serial *serial) |
523 | { | 522 | { |
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index dc47f986df5..a7cfc595293 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c | |||
@@ -1151,7 +1151,7 @@ static int download_fw(struct edgeport_serial *serial) | |||
1151 | 1151 | ||
1152 | /* Check if we have an old version in the I2C and | 1152 | /* Check if we have an old version in the I2C and |
1153 | update if necessary */ | 1153 | update if necessary */ |
1154 | if (download_cur_ver != download_new_ver) { | 1154 | if (download_cur_ver < download_new_ver) { |
1155 | dbg("%s - Update I2C dld from %d.%d to %d.%d", | 1155 | dbg("%s - Update I2C dld from %d.%d to %d.%d", |
1156 | __func__, | 1156 | __func__, |
1157 | firmware_version->Ver_Major, | 1157 | firmware_version->Ver_Major, |
@@ -1284,7 +1284,7 @@ static int download_fw(struct edgeport_serial *serial) | |||
1284 | kfree(header); | 1284 | kfree(header); |
1285 | kfree(rom_desc); | 1285 | kfree(rom_desc); |
1286 | kfree(ti_manuf_desc); | 1286 | kfree(ti_manuf_desc); |
1287 | return status; | 1287 | return -EINVAL; |
1288 | } | 1288 | } |
1289 | 1289 | ||
1290 | /* Update I2C with type 0xf2 record with correct | 1290 | /* Update I2C with type 0xf2 record with correct |
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 30922a7e334..aa665817a27 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c | |||
@@ -2024,6 +2024,9 @@ static int mos7720_ioctl(struct tty_struct *tty, struct file *file, | |||
2024 | 2024 | ||
2025 | case TIOCGICOUNT: | 2025 | case TIOCGICOUNT: |
2026 | cnow = mos7720_port->icount; | 2026 | cnow = mos7720_port->icount; |
2027 | |||
2028 | memset(&icount, 0, sizeof(struct serial_icounter_struct)); | ||
2029 | |||
2027 | icount.cts = cnow.cts; | 2030 | icount.cts = cnow.cts; |
2028 | icount.dsr = cnow.dsr; | 2031 | icount.dsr = cnow.dsr; |
2029 | icount.rng = cnow.rng; | 2032 | icount.rng = cnow.rng; |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 585b7e66374..1a42bc21379 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
@@ -119,16 +119,20 @@ | |||
119 | * by making a change here, in moschip_port_id_table, and in | 119 | * by making a change here, in moschip_port_id_table, and in |
120 | * moschip_id_table_combined | 120 | * moschip_id_table_combined |
121 | */ | 121 | */ |
122 | #define USB_VENDOR_ID_BANDB 0x0856 | 122 | #define USB_VENDOR_ID_BANDB 0x0856 |
123 | #define BANDB_DEVICE_ID_USO9ML2_2 0xAC22 | 123 | #define BANDB_DEVICE_ID_USO9ML2_2 0xAC22 |
124 | #define BANDB_DEVICE_ID_USO9ML2_4 0xAC24 | 124 | #define BANDB_DEVICE_ID_USO9ML2_2P 0xBC00 |
125 | #define BANDB_DEVICE_ID_US9ML2_2 0xAC29 | 125 | #define BANDB_DEVICE_ID_USO9ML2_4 0xAC24 |
126 | #define BANDB_DEVICE_ID_US9ML2_4 0xAC30 | 126 | #define BANDB_DEVICE_ID_USO9ML2_4P 0xBC01 |
127 | #define BANDB_DEVICE_ID_USPTL4_2 0xAC31 | 127 | #define BANDB_DEVICE_ID_US9ML2_2 0xAC29 |
128 | #define BANDB_DEVICE_ID_USPTL4_4 0xAC32 | 128 | #define BANDB_DEVICE_ID_US9ML2_4 0xAC30 |
129 | #define BANDB_DEVICE_ID_USOPTL4_2 0xAC42 | 129 | #define BANDB_DEVICE_ID_USPTL4_2 0xAC31 |
130 | #define BANDB_DEVICE_ID_USOPTL4_4 0xAC44 | 130 | #define BANDB_DEVICE_ID_USPTL4_4 0xAC32 |
131 | #define BANDB_DEVICE_ID_USOPTL2_4 0xAC24 | 131 | #define BANDB_DEVICE_ID_USOPTL4_2 0xAC42 |
132 | #define BANDB_DEVICE_ID_USOPTL4_2P 0xBC02 | ||
133 | #define BANDB_DEVICE_ID_USOPTL4_4 0xAC44 | ||
134 | #define BANDB_DEVICE_ID_USOPTL4_4P 0xBC03 | ||
135 | #define BANDB_DEVICE_ID_USOPTL2_4 0xAC24 | ||
132 | 136 | ||
133 | /* This driver also supports | 137 | /* This driver also supports |
134 | * ATEN UC2324 device using Moschip MCS7840 | 138 | * ATEN UC2324 device using Moschip MCS7840 |
@@ -184,13 +188,17 @@ static const struct usb_device_id moschip_port_id_table[] = { | |||
184 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)}, | 188 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)}, |
185 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, | 189 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, |
186 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)}, | 190 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)}, |
191 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2P)}, | ||
187 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4)}, | 192 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4)}, |
193 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4P)}, | ||
188 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_2)}, | 194 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_2)}, |
189 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_4)}, | 195 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_4)}, |
190 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_2)}, | 196 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_2)}, |
191 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_4)}, | 197 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_4)}, |
192 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)}, | 198 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)}, |
199 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2P)}, | ||
193 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, | 200 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, |
201 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4P)}, | ||
194 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL2_4)}, | 202 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL2_4)}, |
195 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)}, | 203 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)}, |
196 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)}, | 204 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)}, |
@@ -201,13 +209,17 @@ static const struct usb_device_id moschip_id_table_combined[] __devinitconst = { | |||
201 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)}, | 209 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)}, |
202 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, | 210 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, |
203 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)}, | 211 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)}, |
212 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2P)}, | ||
204 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4)}, | 213 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4)}, |
214 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4P)}, | ||
205 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_2)}, | 215 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_2)}, |
206 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_4)}, | 216 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_4)}, |
207 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_2)}, | 217 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_2)}, |
208 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_4)}, | 218 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_4)}, |
209 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)}, | 219 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)}, |
220 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2P)}, | ||
210 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, | 221 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, |
222 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4P)}, | ||
211 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL2_4)}, | 223 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL2_4)}, |
212 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)}, | 224 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)}, |
213 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)}, | 225 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)}, |
@@ -2273,6 +2285,9 @@ static int mos7840_ioctl(struct tty_struct *tty, struct file *file, | |||
2273 | case TIOCGICOUNT: | 2285 | case TIOCGICOUNT: |
2274 | cnow = mos7840_port->icount; | 2286 | cnow = mos7840_port->icount; |
2275 | smp_rmb(); | 2287 | smp_rmb(); |
2288 | |||
2289 | memset(&icount, 0, sizeof(struct serial_icounter_struct)); | ||
2290 | |||
2276 | icount.cts = cnow.cts; | 2291 | icount.cts = cnow.cts; |
2277 | icount.dsr = cnow.dsr; | 2292 | icount.dsr = cnow.dsr; |
2278 | icount.rng = cnow.rng; | 2293 | icount.rng = cnow.rng; |
diff --git a/drivers/usb/serial/navman.c b/drivers/usb/serial/navman.c index a6b207c8491..1f00f243c26 100644 --- a/drivers/usb/serial/navman.c +++ b/drivers/usb/serial/navman.c | |||
@@ -25,6 +25,7 @@ static int debug; | |||
25 | 25 | ||
26 | static const struct usb_device_id id_table[] = { | 26 | static const struct usb_device_id id_table[] = { |
27 | { USB_DEVICE(0x0a99, 0x0001) }, /* Talon Technology device */ | 27 | { USB_DEVICE(0x0a99, 0x0001) }, /* Talon Technology device */ |
28 | { USB_DEVICE(0x0df7, 0x0900) }, /* Mobile Action i-gotU */ | ||
28 | { }, | 29 | { }, |
29 | }; | 30 | }; |
30 | MODULE_DEVICE_TABLE(usb, id_table); | 31 | MODULE_DEVICE_TABLE(usb, id_table); |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 9fc6ea2c681..c46911af282 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -164,6 +164,14 @@ static void option_instat_callback(struct urb *urb); | |||
164 | #define YISO_VENDOR_ID 0x0EAB | 164 | #define YISO_VENDOR_ID 0x0EAB |
165 | #define YISO_PRODUCT_U893 0xC893 | 165 | #define YISO_PRODUCT_U893 0xC893 |
166 | 166 | ||
167 | /* | ||
168 | * NOVATEL WIRELESS PRODUCTS | ||
169 | * | ||
170 | * Note from Novatel Wireless: | ||
171 | * If your Novatel modem does not work on linux, don't | ||
172 | * change the option module, but check our website. If | ||
173 | * that does not help, contact ddeschepper@nvtl.com | ||
174 | */ | ||
167 | /* MERLIN EVDO PRODUCTS */ | 175 | /* MERLIN EVDO PRODUCTS */ |
168 | #define NOVATELWIRELESS_PRODUCT_V640 0x1100 | 176 | #define NOVATELWIRELESS_PRODUCT_V640 0x1100 |
169 | #define NOVATELWIRELESS_PRODUCT_V620 0x1110 | 177 | #define NOVATELWIRELESS_PRODUCT_V620 0x1110 |
@@ -185,24 +193,39 @@ static void option_instat_callback(struct urb *urb); | |||
185 | #define NOVATELWIRELESS_PRODUCT_EU730 0x2400 | 193 | #define NOVATELWIRELESS_PRODUCT_EU730 0x2400 |
186 | #define NOVATELWIRELESS_PRODUCT_EU740 0x2410 | 194 | #define NOVATELWIRELESS_PRODUCT_EU740 0x2410 |
187 | #define NOVATELWIRELESS_PRODUCT_EU870D 0x2420 | 195 | #define NOVATELWIRELESS_PRODUCT_EU870D 0x2420 |
188 | |||
189 | /* OVATION PRODUCTS */ | 196 | /* OVATION PRODUCTS */ |
190 | #define NOVATELWIRELESS_PRODUCT_MC727 0x4100 | 197 | #define NOVATELWIRELESS_PRODUCT_MC727 0x4100 |
191 | #define NOVATELWIRELESS_PRODUCT_MC950D 0x4400 | 198 | #define NOVATELWIRELESS_PRODUCT_MC950D 0x4400 |
192 | #define NOVATELWIRELESS_PRODUCT_U727 0x5010 | 199 | /* |
193 | #define NOVATELWIRELESS_PRODUCT_MC727_NEW 0x5100 | 200 | * Note from Novatel Wireless: |
194 | #define NOVATELWIRELESS_PRODUCT_MC760 0x6000 | 201 | * All PID in the 5xxx range are currently reserved for |
202 | * auto-install CDROMs, and should not be added to this | ||
203 | * module. | ||
204 | * | ||
205 | * #define NOVATELWIRELESS_PRODUCT_U727 0x5010 | ||
206 | * #define NOVATELWIRELESS_PRODUCT_MC727_NEW 0x5100 | ||
207 | */ | ||
195 | #define NOVATELWIRELESS_PRODUCT_OVMC760 0x6002 | 208 | #define NOVATELWIRELESS_PRODUCT_OVMC760 0x6002 |
196 | 209 | #define NOVATELWIRELESS_PRODUCT_MC780 0x6010 | |
197 | /* FUTURE NOVATEL PRODUCTS */ | 210 | #define NOVATELWIRELESS_PRODUCT_EVDO_FULLSPEED 0x6000 |
198 | #define NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED 0X6001 | 211 | #define NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED 0x6001 |
199 | #define NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED 0X7000 | 212 | #define NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED 0x7000 |
200 | #define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED 0X7001 | 213 | #define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED 0x7001 |
201 | #define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED 0X8000 | 214 | #define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED3 0x7003 |
202 | #define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED 0X8001 | 215 | #define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED4 0x7004 |
203 | #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED 0X9000 | 216 | #define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED5 0x7005 |
204 | #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0X9001 | 217 | #define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED6 0x7006 |
205 | #define NOVATELWIRELESS_PRODUCT_GLOBAL 0XA001 | 218 | #define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED7 0x7007 |
219 | #define NOVATELWIRELESS_PRODUCT_MC996D 0x7030 | ||
220 | #define NOVATELWIRELESS_PRODUCT_MF3470 0x7041 | ||
221 | #define NOVATELWIRELESS_PRODUCT_MC547 0x7042 | ||
222 | #define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED 0x8000 | ||
223 | #define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED 0x8001 | ||
224 | #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED 0x9000 | ||
225 | #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0x9001 | ||
226 | #define NOVATELWIRELESS_PRODUCT_G1 0xA001 | ||
227 | #define NOVATELWIRELESS_PRODUCT_G1_M 0xA002 | ||
228 | #define NOVATELWIRELESS_PRODUCT_G2 0xA010 | ||
206 | 229 | ||
207 | /* AMOI PRODUCTS */ | 230 | /* AMOI PRODUCTS */ |
208 | #define AMOI_VENDOR_ID 0x1614 | 231 | #define AMOI_VENDOR_ID 0x1614 |
@@ -365,6 +388,10 @@ static void option_instat_callback(struct urb *urb); | |||
365 | #define OLIVETTI_VENDOR_ID 0x0b3c | 388 | #define OLIVETTI_VENDOR_ID 0x0b3c |
366 | #define OLIVETTI_PRODUCT_OLICARD100 0xc000 | 389 | #define OLIVETTI_PRODUCT_OLICARD100 0xc000 |
367 | 390 | ||
391 | /* Celot products */ | ||
392 | #define CELOT_VENDOR_ID 0x211f | ||
393 | #define CELOT_PRODUCT_CT680M 0x6801 | ||
394 | |||
368 | /* some devices interfaces need special handling due to a number of reasons */ | 395 | /* some devices interfaces need special handling due to a number of reasons */ |
369 | enum option_blacklist_reason { | 396 | enum option_blacklist_reason { |
370 | OPTION_BLACKLIST_NONE = 0, | 397 | OPTION_BLACKLIST_NONE = 0, |
@@ -486,36 +513,44 @@ static const struct usb_device_id option_ids[] = { | |||
486 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff) }, | 513 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff) }, |
487 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ETS1220, 0xff, 0xff, 0xff) }, | 514 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ETS1220, 0xff, 0xff, 0xff) }, |
488 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC) }, | 515 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC) }, |
489 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, /* Novatel Merlin V640/XV620 */ | 516 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, |
490 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, /* Novatel Merlin V620/S620 */ | 517 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, |
491 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) }, /* Novatel Merlin EX720/V740/X720 */ | 518 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) }, |
492 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V720) }, /* Novatel Merlin V720/S720/PC720 */ | 519 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V720) }, |
493 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U730) }, /* Novatel U730/U740 (VF version) */ | 520 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U730) }, |
494 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U740) }, /* Novatel U740 */ | 521 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U740) }, |
495 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U870) }, /* Novatel U870 */ | 522 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U870) }, |
496 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_XU870) }, /* Novatel Merlin XU870 HSDPA/3G */ | 523 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_XU870) }, |
497 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_X950D) }, /* Novatel X950D */ | 524 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_X950D) }, |
498 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EV620) }, /* Novatel EV620/ES620 CDMA/EV-DO */ | 525 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EV620) }, |
499 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_ES720) }, /* Novatel ES620/ES720/U720/USB720 */ | 526 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_ES720) }, |
500 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E725) }, /* Novatel E725/E726 */ | 527 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E725) }, |
501 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_ES620) }, /* Novatel Merlin ES620 SM Bus */ | 528 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_ES620) }, |
502 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU730) }, /* Novatel EU730 and Vodafone EU740 */ | 529 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU730) }, |
503 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU740) }, /* Novatel non-Vodafone EU740 */ | 530 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU740) }, |
504 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU870D) }, /* Novatel EU850D/EU860D/EU870D */ | 531 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU870D) }, |
505 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC950D) }, /* Novatel MC930D/MC950D */ | 532 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC950D) }, |
506 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, /* Novatel MC727/U727/USB727 */ | 533 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, |
507 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727_NEW) }, /* Novatel MC727/U727/USB727 refresh */ | 534 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_OVMC760) }, |
508 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U727) }, /* Novatel MC727/U727/USB727 */ | 535 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC780) }, |
509 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC760) }, /* Novatel MC760/U760/USB760 */ | 536 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_FULLSPEED) }, |
510 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_OVMC760) }, /* Novatel Ovation MC760 */ | 537 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED) }, |
511 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED) }, /* Novatel HSPA product */ | 538 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) }, |
512 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) }, /* Novatel EVDO Embedded product */ | 539 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) }, |
513 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) }, /* Novatel HSPA Embedded product */ | 540 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED) }, |
514 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED) }, /* Novatel EVDO product */ | 541 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED3) }, |
515 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED) }, /* Novatel HSPA product */ | 542 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED4) }, |
516 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED) }, /* Novatel EVDO Embedded product */ | 543 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED5) }, |
517 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED) }, /* Novatel HSPA Embedded product */ | 544 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED6) }, |
518 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_GLOBAL) }, /* Novatel Global product */ | 545 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED7) }, |
546 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC996D) }, | ||
547 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MF3470) }, | ||
548 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC547) }, | ||
549 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED) }, | ||
550 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED) }, | ||
551 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G1) }, | ||
552 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G1_M) }, | ||
553 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G2) }, | ||
519 | 554 | ||
520 | { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) }, | 555 | { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) }, |
521 | { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) }, | 556 | { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) }, |
@@ -887,10 +922,9 @@ static const struct usb_device_id option_ids[] = { | |||
887 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100F) }, | 922 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100F) }, |
888 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1011)}, | 923 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1011)}, |
889 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1012)}, | 924 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1012)}, |
890 | |||
891 | { USB_DEVICE(CINTERION_VENDOR_ID, 0x0047) }, | 925 | { USB_DEVICE(CINTERION_VENDOR_ID, 0x0047) }, |
892 | |||
893 | { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) }, | 926 | { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) }, |
927 | { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */ | ||
894 | { } /* Terminating entry */ | 928 | { } /* Terminating entry */ |
895 | }; | 929 | }; |
896 | MODULE_DEVICE_TABLE(usb, option_ids); | 930 | MODULE_DEVICE_TABLE(usb, option_ids); |
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 6b600182227..8ae4c6cbc38 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
@@ -86,6 +86,7 @@ static const struct usb_device_id id_table[] = { | |||
86 | { USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) }, | 86 | { USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) }, |
87 | { USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) }, | 87 | { USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) }, |
88 | { USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) }, | 88 | { USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) }, |
89 | { USB_DEVICE(ZEAGLE_VENDOR_ID, ZEAGLE_N2ITION3_PRODUCT_ID) }, | ||
89 | { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) }, | 90 | { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) }, |
90 | { USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) }, | 91 | { USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) }, |
91 | { USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) }, | 92 | { USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) }, |
@@ -788,7 +789,7 @@ static void pl2303_process_read_urb(struct urb *urb) | |||
788 | 789 | ||
789 | if (port->port.console && port->sysrq) { | 790 | if (port->port.console && port->sysrq) { |
790 | for (i = 0; i < urb->actual_length; ++i) | 791 | for (i = 0; i < urb->actual_length; ++i) |
791 | if (!usb_serial_handle_sysrq_char(tty, port, data[i])) | 792 | if (!usb_serial_handle_sysrq_char(port, data[i])) |
792 | tty_insert_flip_char(tty, data[i], tty_flag); | 793 | tty_insert_flip_char(tty, data[i], tty_flag); |
793 | } else { | 794 | } else { |
794 | tty_insert_flip_string_fixed_flag(tty, data, tty_flag, | 795 | tty_insert_flip_string_fixed_flag(tty, data, tty_flag, |
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index a871645389d..43eb9bdad42 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h | |||
@@ -128,6 +128,10 @@ | |||
128 | #define CRESSI_VENDOR_ID 0x04b8 | 128 | #define CRESSI_VENDOR_ID 0x04b8 |
129 | #define CRESSI_EDY_PRODUCT_ID 0x0521 | 129 | #define CRESSI_EDY_PRODUCT_ID 0x0521 |
130 | 130 | ||
131 | /* Zeagle dive computer interface */ | ||
132 | #define ZEAGLE_VENDOR_ID 0x04b8 | ||
133 | #define ZEAGLE_N2ITION3_PRODUCT_ID 0x0522 | ||
134 | |||
131 | /* Sony, USB data cable for CMD-Jxx mobile phones */ | 135 | /* Sony, USB data cable for CMD-Jxx mobile phones */ |
132 | #define SONY_VENDOR_ID 0x054c | 136 | #define SONY_VENDOR_ID 0x054c |
133 | #define SONY_QN3USB_PRODUCT_ID 0x0437 | 137 | #define SONY_QN3USB_PRODUCT_ID 0x0437 |
diff --git a/drivers/usb/serial/ssu100.c b/drivers/usb/serial/ssu100.c index 6e82d4f54bc..e986002b384 100644 --- a/drivers/usb/serial/ssu100.c +++ b/drivers/usb/serial/ssu100.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/serial.h> | 15 | #include <linux/serial.h> |
16 | #include <linux/usb.h> | 16 | #include <linux/usb.h> |
17 | #include <linux/usb/serial.h> | 17 | #include <linux/usb/serial.h> |
18 | #include <linux/serial_reg.h> | ||
18 | #include <linux/uaccess.h> | 19 | #include <linux/uaccess.h> |
19 | 20 | ||
20 | #define QT_OPEN_CLOSE_CHANNEL 0xca | 21 | #define QT_OPEN_CLOSE_CHANNEL 0xca |
@@ -27,36 +28,11 @@ | |||
27 | #define QT_HW_FLOW_CONTROL_MASK 0xc5 | 28 | #define QT_HW_FLOW_CONTROL_MASK 0xc5 |
28 | #define QT_SW_FLOW_CONTROL_MASK 0xc6 | 29 | #define QT_SW_FLOW_CONTROL_MASK 0xc6 |
29 | 30 | ||
30 | #define MODEM_CTL_REGISTER 0x04 | ||
31 | #define MODEM_STATUS_REGISTER 0x06 | ||
32 | |||
33 | |||
34 | #define SERIAL_LSR_OE 0x02 | ||
35 | #define SERIAL_LSR_PE 0x04 | ||
36 | #define SERIAL_LSR_FE 0x08 | ||
37 | #define SERIAL_LSR_BI 0x10 | ||
38 | |||
39 | #define SERIAL_LSR_TEMT 0x40 | ||
40 | |||
41 | #define SERIAL_MCR_DTR 0x01 | ||
42 | #define SERIAL_MCR_RTS 0x02 | ||
43 | #define SERIAL_MCR_LOOP 0x10 | ||
44 | |||
45 | #define SERIAL_MSR_CTS 0x10 | ||
46 | #define SERIAL_MSR_CD 0x80 | ||
47 | #define SERIAL_MSR_RI 0x40 | ||
48 | #define SERIAL_MSR_DSR 0x20 | ||
49 | #define SERIAL_MSR_MASK 0xf0 | 31 | #define SERIAL_MSR_MASK 0xf0 |
50 | 32 | ||
51 | #define SERIAL_CRTSCTS ((SERIAL_MCR_RTS << 8) | SERIAL_MSR_CTS) | 33 | #define SERIAL_CRTSCTS ((UART_MCR_RTS << 8) | UART_MSR_CTS) |
52 | 34 | ||
53 | #define SERIAL_8_DATA 0x03 | 35 | #define SERIAL_EVEN_PARITY (UART_LCR_PARITY | UART_LCR_EPAR) |
54 | #define SERIAL_7_DATA 0x02 | ||
55 | #define SERIAL_6_DATA 0x01 | ||
56 | #define SERIAL_5_DATA 0x00 | ||
57 | |||
58 | #define SERIAL_ODD_PARITY 0X08 | ||
59 | #define SERIAL_EVEN_PARITY 0X18 | ||
60 | 36 | ||
61 | #define MAX_BAUD_RATE 460800 | 37 | #define MAX_BAUD_RATE 460800 |
62 | 38 | ||
@@ -70,7 +46,7 @@ | |||
70 | #define FULLPWRBIT 0x00000080 | 46 | #define FULLPWRBIT 0x00000080 |
71 | #define NEXT_BOARD_POWER_BIT 0x00000004 | 47 | #define NEXT_BOARD_POWER_BIT 0x00000004 |
72 | 48 | ||
73 | static int debug = 1; | 49 | static int debug; |
74 | 50 | ||
75 | /* Version Information */ | 51 | /* Version Information */ |
76 | #define DRIVER_VERSION "v0.1" | 52 | #define DRIVER_VERSION "v0.1" |
@@ -99,10 +75,12 @@ static struct usb_driver ssu100_driver = { | |||
99 | }; | 75 | }; |
100 | 76 | ||
101 | struct ssu100_port_private { | 77 | struct ssu100_port_private { |
78 | spinlock_t status_lock; | ||
102 | u8 shadowLSR; | 79 | u8 shadowLSR; |
103 | u8 shadowMSR; | 80 | u8 shadowMSR; |
104 | wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ | 81 | wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ |
105 | unsigned short max_packet_size; | 82 | unsigned short max_packet_size; |
83 | struct async_icount icount; | ||
106 | }; | 84 | }; |
107 | 85 | ||
108 | static void ssu100_release(struct usb_serial *serial) | 86 | static void ssu100_release(struct usb_serial *serial) |
@@ -150,9 +128,10 @@ static inline int ssu100_getregister(struct usb_device *dev, | |||
150 | 128 | ||
151 | static inline int ssu100_setregister(struct usb_device *dev, | 129 | static inline int ssu100_setregister(struct usb_device *dev, |
152 | unsigned short uart, | 130 | unsigned short uart, |
131 | unsigned short reg, | ||
153 | u16 data) | 132 | u16 data) |
154 | { | 133 | { |
155 | u16 value = (data << 8) | MODEM_CTL_REGISTER; | 134 | u16 value = (data << 8) | reg; |
156 | 135 | ||
157 | return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | 136 | return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
158 | QT_SET_GET_REGISTER, 0x40, value, uart, | 137 | QT_SET_GET_REGISTER, 0x40, value, uart, |
@@ -178,11 +157,11 @@ static inline int update_mctrl(struct usb_device *dev, unsigned int set, | |||
178 | clear &= ~set; /* 'set' takes precedence over 'clear' */ | 157 | clear &= ~set; /* 'set' takes precedence over 'clear' */ |
179 | urb_value = 0; | 158 | urb_value = 0; |
180 | if (set & TIOCM_DTR) | 159 | if (set & TIOCM_DTR) |
181 | urb_value |= SERIAL_MCR_DTR; | 160 | urb_value |= UART_MCR_DTR; |
182 | if (set & TIOCM_RTS) | 161 | if (set & TIOCM_RTS) |
183 | urb_value |= SERIAL_MCR_RTS; | 162 | urb_value |= UART_MCR_RTS; |
184 | 163 | ||
185 | result = ssu100_setregister(dev, 0, urb_value); | 164 | result = ssu100_setregister(dev, 0, UART_MCR, urb_value); |
186 | if (result < 0) | 165 | if (result < 0) |
187 | dbg("%s Error from MODEM_CTRL urb", __func__); | 166 | dbg("%s Error from MODEM_CTRL urb", __func__); |
188 | 167 | ||
@@ -264,24 +243,24 @@ static void ssu100_set_termios(struct tty_struct *tty, | |||
264 | 243 | ||
265 | if (cflag & PARENB) { | 244 | if (cflag & PARENB) { |
266 | if (cflag & PARODD) | 245 | if (cflag & PARODD) |
267 | urb_value |= SERIAL_ODD_PARITY; | 246 | urb_value |= UART_LCR_PARITY; |
268 | else | 247 | else |
269 | urb_value |= SERIAL_EVEN_PARITY; | 248 | urb_value |= SERIAL_EVEN_PARITY; |
270 | } | 249 | } |
271 | 250 | ||
272 | switch (cflag & CSIZE) { | 251 | switch (cflag & CSIZE) { |
273 | case CS5: | 252 | case CS5: |
274 | urb_value |= SERIAL_5_DATA; | 253 | urb_value |= UART_LCR_WLEN5; |
275 | break; | 254 | break; |
276 | case CS6: | 255 | case CS6: |
277 | urb_value |= SERIAL_6_DATA; | 256 | urb_value |= UART_LCR_WLEN6; |
278 | break; | 257 | break; |
279 | case CS7: | 258 | case CS7: |
280 | urb_value |= SERIAL_7_DATA; | 259 | urb_value |= UART_LCR_WLEN7; |
281 | break; | 260 | break; |
282 | default: | 261 | default: |
283 | case CS8: | 262 | case CS8: |
284 | urb_value |= SERIAL_8_DATA; | 263 | urb_value |= UART_LCR_WLEN8; |
285 | break; | 264 | break; |
286 | } | 265 | } |
287 | 266 | ||
@@ -333,6 +312,7 @@ static int ssu100_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
333 | struct ssu100_port_private *priv = usb_get_serial_port_data(port); | 312 | struct ssu100_port_private *priv = usb_get_serial_port_data(port); |
334 | u8 *data; | 313 | u8 *data; |
335 | int result; | 314 | int result; |
315 | unsigned long flags; | ||
336 | 316 | ||
337 | dbg("%s - port %d", __func__, port->number); | 317 | dbg("%s - port %d", __func__, port->number); |
338 | 318 | ||
@@ -350,11 +330,10 @@ static int ssu100_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
350 | return result; | 330 | return result; |
351 | } | 331 | } |
352 | 332 | ||
353 | priv->shadowLSR = data[0] & (SERIAL_LSR_OE | SERIAL_LSR_PE | | 333 | spin_lock_irqsave(&priv->status_lock, flags); |
354 | SERIAL_LSR_FE | SERIAL_LSR_BI); | 334 | priv->shadowLSR = data[0]; |
355 | 335 | priv->shadowMSR = data[1]; | |
356 | priv->shadowMSR = data[1] & (SERIAL_MSR_CTS | SERIAL_MSR_DSR | | 336 | spin_unlock_irqrestore(&priv->status_lock, flags); |
357 | SERIAL_MSR_RI | SERIAL_MSR_CD); | ||
358 | 337 | ||
359 | kfree(data); | 338 | kfree(data); |
360 | 339 | ||
@@ -398,11 +377,51 @@ static int get_serial_info(struct usb_serial_port *port, | |||
398 | return 0; | 377 | return 0; |
399 | } | 378 | } |
400 | 379 | ||
380 | static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) | ||
381 | { | ||
382 | struct ssu100_port_private *priv = usb_get_serial_port_data(port); | ||
383 | struct async_icount prev, cur; | ||
384 | unsigned long flags; | ||
385 | |||
386 | spin_lock_irqsave(&priv->status_lock, flags); | ||
387 | prev = priv->icount; | ||
388 | spin_unlock_irqrestore(&priv->status_lock, flags); | ||
389 | |||
390 | while (1) { | ||
391 | wait_event_interruptible(priv->delta_msr_wait, | ||
392 | ((priv->icount.rng != prev.rng) || | ||
393 | (priv->icount.dsr != prev.dsr) || | ||
394 | (priv->icount.dcd != prev.dcd) || | ||
395 | (priv->icount.cts != prev.cts))); | ||
396 | |||
397 | if (signal_pending(current)) | ||
398 | return -ERESTARTSYS; | ||
399 | |||
400 | spin_lock_irqsave(&priv->status_lock, flags); | ||
401 | cur = priv->icount; | ||
402 | spin_unlock_irqrestore(&priv->status_lock, flags); | ||
403 | |||
404 | if ((prev.rng == cur.rng) && | ||
405 | (prev.dsr == cur.dsr) && | ||
406 | (prev.dcd == cur.dcd) && | ||
407 | (prev.cts == cur.cts)) | ||
408 | return -EIO; | ||
409 | |||
410 | if ((arg & TIOCM_RNG && (prev.rng != cur.rng)) || | ||
411 | (arg & TIOCM_DSR && (prev.dsr != cur.dsr)) || | ||
412 | (arg & TIOCM_CD && (prev.dcd != cur.dcd)) || | ||
413 | (arg & TIOCM_CTS && (prev.cts != cur.cts))) | ||
414 | return 0; | ||
415 | } | ||
416 | return 0; | ||
417 | } | ||
418 | |||
401 | static int ssu100_ioctl(struct tty_struct *tty, struct file *file, | 419 | static int ssu100_ioctl(struct tty_struct *tty, struct file *file, |
402 | unsigned int cmd, unsigned long arg) | 420 | unsigned int cmd, unsigned long arg) |
403 | { | 421 | { |
404 | struct usb_serial_port *port = tty->driver_data; | 422 | struct usb_serial_port *port = tty->driver_data; |
405 | struct ssu100_port_private *priv = usb_get_serial_port_data(port); | 423 | struct ssu100_port_private *priv = usb_get_serial_port_data(port); |
424 | void __user *user_arg = (void __user *)arg; | ||
406 | 425 | ||
407 | dbg("%s cmd 0x%04x", __func__, cmd); | 426 | dbg("%s cmd 0x%04x", __func__, cmd); |
408 | 427 | ||
@@ -412,28 +431,28 @@ static int ssu100_ioctl(struct tty_struct *tty, struct file *file, | |||
412 | (struct serial_struct __user *) arg); | 431 | (struct serial_struct __user *) arg); |
413 | 432 | ||
414 | case TIOCMIWAIT: | 433 | case TIOCMIWAIT: |
415 | while (priv != NULL) { | 434 | return wait_modem_info(port, arg); |
416 | u8 prevMSR = priv->shadowMSR & SERIAL_MSR_MASK; | 435 | |
417 | interruptible_sleep_on(&priv->delta_msr_wait); | 436 | case TIOCGICOUNT: |
418 | /* see if a signal did it */ | 437 | { |
419 | if (signal_pending(current)) | 438 | struct serial_icounter_struct icount; |
420 | return -ERESTARTSYS; | 439 | struct async_icount cnow = priv->icount; |
421 | else { | 440 | memset(&icount, 0, sizeof(icount)); |
422 | u8 diff = (priv->shadowMSR & SERIAL_MSR_MASK) ^ prevMSR; | 441 | icount.cts = cnow.cts; |
423 | if (!diff) | 442 | icount.dsr = cnow.dsr; |
424 | return -EIO; /* no change => error */ | 443 | icount.rng = cnow.rng; |
425 | 444 | icount.dcd = cnow.dcd; | |
426 | /* Return 0 if caller wanted to know about | 445 | icount.rx = cnow.rx; |
427 | these bits */ | 446 | icount.tx = cnow.tx; |
428 | 447 | icount.frame = cnow.frame; | |
429 | if (((arg & TIOCM_RNG) && (diff & SERIAL_MSR_RI)) || | 448 | icount.overrun = cnow.overrun; |
430 | ((arg & TIOCM_DSR) && (diff & SERIAL_MSR_DSR)) || | 449 | icount.parity = cnow.parity; |
431 | ((arg & TIOCM_CD) && (diff & SERIAL_MSR_CD)) || | 450 | icount.brk = cnow.brk; |
432 | ((arg & TIOCM_CTS) && (diff & SERIAL_MSR_CTS))) | 451 | icount.buf_overrun = cnow.buf_overrun; |
433 | return 0; | 452 | if (copy_to_user(user_arg, &icount, sizeof(icount))) |
434 | } | 453 | return -EFAULT; |
435 | } | ||
436 | return 0; | 454 | return 0; |
455 | } | ||
437 | 456 | ||
438 | default: | 457 | default: |
439 | break; | 458 | break; |
@@ -455,6 +474,7 @@ static void ssu100_set_max_packet_size(struct usb_serial_port *port) | |||
455 | 474 | ||
456 | unsigned num_endpoints; | 475 | unsigned num_endpoints; |
457 | int i; | 476 | int i; |
477 | unsigned long flags; | ||
458 | 478 | ||
459 | num_endpoints = interface->cur_altsetting->desc.bNumEndpoints; | 479 | num_endpoints = interface->cur_altsetting->desc.bNumEndpoints; |
460 | dev_info(&udev->dev, "Number of endpoints %d\n", num_endpoints); | 480 | dev_info(&udev->dev, "Number of endpoints %d\n", num_endpoints); |
@@ -466,7 +486,9 @@ static void ssu100_set_max_packet_size(struct usb_serial_port *port) | |||
466 | } | 486 | } |
467 | 487 | ||
468 | /* set max packet size based on descriptor */ | 488 | /* set max packet size based on descriptor */ |
489 | spin_lock_irqsave(&priv->status_lock, flags); | ||
469 | priv->max_packet_size = ep_desc->wMaxPacketSize; | 490 | priv->max_packet_size = ep_desc->wMaxPacketSize; |
491 | spin_unlock_irqrestore(&priv->status_lock, flags); | ||
470 | 492 | ||
471 | dev_info(&udev->dev, "Setting MaxPacketSize %d\n", priv->max_packet_size); | 493 | dev_info(&udev->dev, "Setting MaxPacketSize %d\n", priv->max_packet_size); |
472 | } | 494 | } |
@@ -485,9 +507,9 @@ static int ssu100_attach(struct usb_serial *serial) | |||
485 | return -ENOMEM; | 507 | return -ENOMEM; |
486 | } | 508 | } |
487 | 509 | ||
510 | spin_lock_init(&priv->status_lock); | ||
488 | init_waitqueue_head(&priv->delta_msr_wait); | 511 | init_waitqueue_head(&priv->delta_msr_wait); |
489 | usb_set_serial_port_data(port, priv); | 512 | usb_set_serial_port_data(port, priv); |
490 | |||
491 | ssu100_set_max_packet_size(port); | 513 | ssu100_set_max_packet_size(port); |
492 | 514 | ||
493 | return ssu100_initdevice(serial->dev); | 515 | return ssu100_initdevice(serial->dev); |
@@ -506,20 +528,20 @@ static int ssu100_tiocmget(struct tty_struct *tty, struct file *file) | |||
506 | if (!d) | 528 | if (!d) |
507 | return -ENOMEM; | 529 | return -ENOMEM; |
508 | 530 | ||
509 | r = ssu100_getregister(dev, 0, MODEM_CTL_REGISTER, d); | 531 | r = ssu100_getregister(dev, 0, UART_MCR, d); |
510 | if (r < 0) | 532 | if (r < 0) |
511 | goto mget_out; | 533 | goto mget_out; |
512 | 534 | ||
513 | r = ssu100_getregister(dev, 0, MODEM_STATUS_REGISTER, d+1); | 535 | r = ssu100_getregister(dev, 0, UART_MSR, d+1); |
514 | if (r < 0) | 536 | if (r < 0) |
515 | goto mget_out; | 537 | goto mget_out; |
516 | 538 | ||
517 | r = (d[0] & SERIAL_MCR_DTR ? TIOCM_DTR : 0) | | 539 | r = (d[0] & UART_MCR_DTR ? TIOCM_DTR : 0) | |
518 | (d[0] & SERIAL_MCR_RTS ? TIOCM_RTS : 0) | | 540 | (d[0] & UART_MCR_RTS ? TIOCM_RTS : 0) | |
519 | (d[1] & SERIAL_MSR_CTS ? TIOCM_CTS : 0) | | 541 | (d[1] & UART_MSR_CTS ? TIOCM_CTS : 0) | |
520 | (d[1] & SERIAL_MSR_CD ? TIOCM_CAR : 0) | | 542 | (d[1] & UART_MSR_DCD ? TIOCM_CAR : 0) | |
521 | (d[1] & SERIAL_MSR_RI ? TIOCM_RI : 0) | | 543 | (d[1] & UART_MSR_RI ? TIOCM_RI : 0) | |
522 | (d[1] & SERIAL_MSR_DSR ? TIOCM_DSR : 0); | 544 | (d[1] & UART_MSR_DSR ? TIOCM_DSR : 0); |
523 | 545 | ||
524 | mget_out: | 546 | mget_out: |
525 | kfree(d); | 547 | kfree(d); |
@@ -546,7 +568,7 @@ static void ssu100_dtr_rts(struct usb_serial_port *port, int on) | |||
546 | if (!port->serial->disconnected) { | 568 | if (!port->serial->disconnected) { |
547 | /* Disable flow control */ | 569 | /* Disable flow control */ |
548 | if (!on && | 570 | if (!on && |
549 | ssu100_setregister(dev, 0, 0) < 0) | 571 | ssu100_setregister(dev, 0, UART_MCR, 0) < 0) |
550 | dev_err(&port->dev, "error from flowcontrol urb\n"); | 572 | dev_err(&port->dev, "error from flowcontrol urb\n"); |
551 | /* drop RTS and DTR */ | 573 | /* drop RTS and DTR */ |
552 | if (on) | 574 | if (on) |
@@ -557,34 +579,88 @@ static void ssu100_dtr_rts(struct usb_serial_port *port, int on) | |||
557 | mutex_unlock(&port->serial->disc_mutex); | 579 | mutex_unlock(&port->serial->disc_mutex); |
558 | } | 580 | } |
559 | 581 | ||
582 | static void ssu100_update_msr(struct usb_serial_port *port, u8 msr) | ||
583 | { | ||
584 | struct ssu100_port_private *priv = usb_get_serial_port_data(port); | ||
585 | unsigned long flags; | ||
586 | |||
587 | spin_lock_irqsave(&priv->status_lock, flags); | ||
588 | priv->shadowMSR = msr; | ||
589 | spin_unlock_irqrestore(&priv->status_lock, flags); | ||
590 | |||
591 | if (msr & UART_MSR_ANY_DELTA) { | ||
592 | /* update input line counters */ | ||
593 | if (msr & UART_MSR_DCTS) | ||
594 | priv->icount.cts++; | ||
595 | if (msr & UART_MSR_DDSR) | ||
596 | priv->icount.dsr++; | ||
597 | if (msr & UART_MSR_DDCD) | ||
598 | priv->icount.dcd++; | ||
599 | if (msr & UART_MSR_TERI) | ||
600 | priv->icount.rng++; | ||
601 | wake_up_interruptible(&priv->delta_msr_wait); | ||
602 | } | ||
603 | } | ||
604 | |||
605 | static void ssu100_update_lsr(struct usb_serial_port *port, u8 lsr, | ||
606 | char *tty_flag) | ||
607 | { | ||
608 | struct ssu100_port_private *priv = usb_get_serial_port_data(port); | ||
609 | unsigned long flags; | ||
610 | |||
611 | spin_lock_irqsave(&priv->status_lock, flags); | ||
612 | priv->shadowLSR = lsr; | ||
613 | spin_unlock_irqrestore(&priv->status_lock, flags); | ||
614 | |||
615 | *tty_flag = TTY_NORMAL; | ||
616 | if (lsr & UART_LSR_BRK_ERROR_BITS) { | ||
617 | /* we always want to update icount, but we only want to | ||
618 | * update tty_flag for one case */ | ||
619 | if (lsr & UART_LSR_BI) { | ||
620 | priv->icount.brk++; | ||
621 | *tty_flag = TTY_BREAK; | ||
622 | usb_serial_handle_break(port); | ||
623 | } | ||
624 | if (lsr & UART_LSR_PE) { | ||
625 | priv->icount.parity++; | ||
626 | if (*tty_flag == TTY_NORMAL) | ||
627 | *tty_flag = TTY_PARITY; | ||
628 | } | ||
629 | if (lsr & UART_LSR_FE) { | ||
630 | priv->icount.frame++; | ||
631 | if (*tty_flag == TTY_NORMAL) | ||
632 | *tty_flag = TTY_FRAME; | ||
633 | } | ||
634 | if (lsr & UART_LSR_OE){ | ||
635 | priv->icount.overrun++; | ||
636 | if (*tty_flag == TTY_NORMAL) | ||
637 | *tty_flag = TTY_OVERRUN; | ||
638 | } | ||
639 | } | ||
640 | |||
641 | } | ||
642 | |||
560 | static int ssu100_process_packet(struct tty_struct *tty, | 643 | static int ssu100_process_packet(struct tty_struct *tty, |
561 | struct usb_serial_port *port, | 644 | struct usb_serial_port *port, |
562 | struct ssu100_port_private *priv, | 645 | struct ssu100_port_private *priv, |
563 | char *packet, int len) | 646 | char *packet, int len) |
564 | { | 647 | { |
565 | int i; | 648 | int i; |
566 | char flag; | 649 | char flag = TTY_NORMAL; |
567 | char *ch; | 650 | char *ch; |
568 | 651 | ||
569 | dbg("%s - port %d", __func__, port->number); | 652 | dbg("%s - port %d", __func__, port->number); |
570 | 653 | ||
571 | if (len < 4) { | 654 | if ((len >= 4) && |
572 | dbg("%s - malformed packet", __func__); | 655 | (packet[0] == 0x1b) && (packet[1] == 0x1b) && |
573 | return 0; | ||
574 | } | ||
575 | |||
576 | if ((packet[0] == 0x1b) && (packet[1] == 0x1b) && | ||
577 | ((packet[2] == 0x00) || (packet[2] == 0x01))) { | 656 | ((packet[2] == 0x00) || (packet[2] == 0x01))) { |
578 | if (packet[2] == 0x00) | 657 | if (packet[2] == 0x00) { |
579 | priv->shadowLSR = packet[3] & (SERIAL_LSR_OE | | 658 | ssu100_update_lsr(port, packet[3], &flag); |
580 | SERIAL_LSR_PE | | 659 | if (flag == TTY_OVERRUN) |
581 | SERIAL_LSR_FE | | 660 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
582 | SERIAL_LSR_BI); | ||
583 | |||
584 | if (packet[2] == 0x01) { | ||
585 | priv->shadowMSR = packet[3]; | ||
586 | wake_up_interruptible(&priv->delta_msr_wait); | ||
587 | } | 661 | } |
662 | if (packet[2] == 0x01) | ||
663 | ssu100_update_msr(port, packet[3]); | ||
588 | 664 | ||
589 | len -= 4; | 665 | len -= 4; |
590 | ch = packet + 4; | 666 | ch = packet + 4; |
@@ -596,7 +672,7 @@ static int ssu100_process_packet(struct tty_struct *tty, | |||
596 | 672 | ||
597 | if (port->port.console && port->sysrq) { | 673 | if (port->port.console && port->sysrq) { |
598 | for (i = 0; i < len; i++, ch++) { | 674 | for (i = 0; i < len; i++, ch++) { |
599 | if (!usb_serial_handle_sysrq_char(tty, port, *ch)) | 675 | if (!usb_serial_handle_sysrq_char(port, *ch)) |
600 | tty_insert_flip_char(tty, *ch, flag); | 676 | tty_insert_flip_char(tty, *ch, flag); |
601 | } | 677 | } |
602 | } else | 678 | } else |
@@ -631,7 +707,6 @@ static void ssu100_process_read_urb(struct urb *urb) | |||
631 | tty_kref_put(tty); | 707 | tty_kref_put(tty); |
632 | } | 708 | } |
633 | 709 | ||
634 | |||
635 | static struct usb_serial_driver ssu100_device = { | 710 | static struct usb_serial_driver ssu100_device = { |
636 | .driver = { | 711 | .driver = { |
637 | .owner = THIS_MODULE, | 712 | .owner = THIS_MODULE, |
@@ -653,6 +728,7 @@ static struct usb_serial_driver ssu100_device = { | |||
653 | .tiocmset = ssu100_tiocmset, | 728 | .tiocmset = ssu100_tiocmset, |
654 | .ioctl = ssu100_ioctl, | 729 | .ioctl = ssu100_ioctl, |
655 | .set_termios = ssu100_set_termios, | 730 | .set_termios = ssu100_set_termios, |
731 | .disconnect = usb_serial_generic_disconnect, | ||
656 | }; | 732 | }; |
657 | 733 | ||
658 | static int __init ssu100_init(void) | 734 | static int __init ssu100_init(void) |
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 2a982e62963..7a2177c79bd 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -736,6 +736,7 @@ int usb_serial_probe(struct usb_interface *interface, | |||
736 | 736 | ||
737 | serial = create_serial(dev, interface, type); | 737 | serial = create_serial(dev, interface, type); |
738 | if (!serial) { | 738 | if (!serial) { |
739 | module_put(type->driver.owner); | ||
739 | dev_err(&interface->dev, "%s - out of memory\n", __func__); | 740 | dev_err(&interface->dev, "%s - out of memory\n", __func__); |
740 | return -ENOMEM; | 741 | return -ENOMEM; |
741 | } | 742 | } |
@@ -746,11 +747,11 @@ int usb_serial_probe(struct usb_interface *interface, | |||
746 | 747 | ||
747 | id = get_iface_id(type, interface); | 748 | id = get_iface_id(type, interface); |
748 | retval = type->probe(serial, id); | 749 | retval = type->probe(serial, id); |
749 | module_put(type->driver.owner); | ||
750 | 750 | ||
751 | if (retval) { | 751 | if (retval) { |
752 | dbg("sub driver rejected device"); | 752 | dbg("sub driver rejected device"); |
753 | kfree(serial); | 753 | kfree(serial); |
754 | module_put(type->driver.owner); | ||
754 | return retval; | 755 | return retval; |
755 | } | 756 | } |
756 | } | 757 | } |
@@ -822,6 +823,7 @@ int usb_serial_probe(struct usb_interface *interface, | |||
822 | if (num_bulk_in == 0 || num_bulk_out == 0) { | 823 | if (num_bulk_in == 0 || num_bulk_out == 0) { |
823 | dev_info(&interface->dev, "PL-2303 hack: descriptors matched but endpoints did not\n"); | 824 | dev_info(&interface->dev, "PL-2303 hack: descriptors matched but endpoints did not\n"); |
824 | kfree(serial); | 825 | kfree(serial); |
826 | module_put(type->driver.owner); | ||
825 | return -ENODEV; | 827 | return -ENODEV; |
826 | } | 828 | } |
827 | } | 829 | } |
@@ -835,22 +837,15 @@ int usb_serial_probe(struct usb_interface *interface, | |||
835 | dev_err(&interface->dev, | 837 | dev_err(&interface->dev, |
836 | "Generic device with no bulk out, not allowed.\n"); | 838 | "Generic device with no bulk out, not allowed.\n"); |
837 | kfree(serial); | 839 | kfree(serial); |
840 | module_put(type->driver.owner); | ||
838 | return -EIO; | 841 | return -EIO; |
839 | } | 842 | } |
840 | } | 843 | } |
841 | #endif | 844 | #endif |
842 | if (!num_ports) { | 845 | if (!num_ports) { |
843 | /* if this device type has a calc_num_ports function, call it */ | 846 | /* if this device type has a calc_num_ports function, call it */ |
844 | if (type->calc_num_ports) { | 847 | if (type->calc_num_ports) |
845 | if (!try_module_get(type->driver.owner)) { | ||
846 | dev_err(&interface->dev, | ||
847 | "module get failed, exiting\n"); | ||
848 | kfree(serial); | ||
849 | return -EIO; | ||
850 | } | ||
851 | num_ports = type->calc_num_ports(serial); | 848 | num_ports = type->calc_num_ports(serial); |
852 | module_put(type->driver.owner); | ||
853 | } | ||
854 | if (!num_ports) | 849 | if (!num_ports) |
855 | num_ports = type->num_ports; | 850 | num_ports = type->num_ports; |
856 | } | 851 | } |
@@ -1039,13 +1034,7 @@ int usb_serial_probe(struct usb_interface *interface, | |||
1039 | 1034 | ||
1040 | /* if this device type has an attach function, call it */ | 1035 | /* if this device type has an attach function, call it */ |
1041 | if (type->attach) { | 1036 | if (type->attach) { |
1042 | if (!try_module_get(type->driver.owner)) { | ||
1043 | dev_err(&interface->dev, | ||
1044 | "module get failed, exiting\n"); | ||
1045 | goto probe_error; | ||
1046 | } | ||
1047 | retval = type->attach(serial); | 1037 | retval = type->attach(serial); |
1048 | module_put(type->driver.owner); | ||
1049 | if (retval < 0) | 1038 | if (retval < 0) |
1050 | goto probe_error; | 1039 | goto probe_error; |
1051 | serial->attached = 1; | 1040 | serial->attached = 1; |
@@ -1088,10 +1077,12 @@ int usb_serial_probe(struct usb_interface *interface, | |||
1088 | exit: | 1077 | exit: |
1089 | /* success */ | 1078 | /* success */ |
1090 | usb_set_intfdata(interface, serial); | 1079 | usb_set_intfdata(interface, serial); |
1080 | module_put(type->driver.owner); | ||
1091 | return 0; | 1081 | return 0; |
1092 | 1082 | ||
1093 | probe_error: | 1083 | probe_error: |
1094 | usb_serial_put(serial); | 1084 | usb_serial_put(serial); |
1085 | module_put(type->driver.owner); | ||
1095 | return -EIO; | 1086 | return -EIO; |
1096 | } | 1087 | } |
1097 | EXPORT_SYMBOL_GPL(usb_serial_probe); | 1088 | EXPORT_SYMBOL_GPL(usb_serial_probe); |
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 29e850a7a2f..7c8008225ee 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c | |||
@@ -243,7 +243,7 @@ static int get_rx_bufs(struct vhost_virtqueue *vq, | |||
243 | int r, nlogs = 0; | 243 | int r, nlogs = 0; |
244 | 244 | ||
245 | while (datalen > 0) { | 245 | while (datalen > 0) { |
246 | if (unlikely(headcount >= VHOST_NET_MAX_SG)) { | 246 | if (unlikely(seg >= VHOST_NET_MAX_SG)) { |
247 | r = -ENOBUFS; | 247 | r = -ENOBUFS; |
248 | goto err; | 248 | goto err; |
249 | } | 249 | } |
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index e05557d5299..dd3d6f7406f 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c | |||
@@ -60,22 +60,25 @@ static int vhost_poll_wakeup(wait_queue_t *wait, unsigned mode, int sync, | |||
60 | return 0; | 60 | return 0; |
61 | } | 61 | } |
62 | 62 | ||
63 | static void vhost_work_init(struct vhost_work *work, vhost_work_fn_t fn) | ||
64 | { | ||
65 | INIT_LIST_HEAD(&work->node); | ||
66 | work->fn = fn; | ||
67 | init_waitqueue_head(&work->done); | ||
68 | work->flushing = 0; | ||
69 | work->queue_seq = work->done_seq = 0; | ||
70 | } | ||
71 | |||
63 | /* Init poll structure */ | 72 | /* Init poll structure */ |
64 | void vhost_poll_init(struct vhost_poll *poll, vhost_work_fn_t fn, | 73 | void vhost_poll_init(struct vhost_poll *poll, vhost_work_fn_t fn, |
65 | unsigned long mask, struct vhost_dev *dev) | 74 | unsigned long mask, struct vhost_dev *dev) |
66 | { | 75 | { |
67 | struct vhost_work *work = &poll->work; | ||
68 | |||
69 | init_waitqueue_func_entry(&poll->wait, vhost_poll_wakeup); | 76 | init_waitqueue_func_entry(&poll->wait, vhost_poll_wakeup); |
70 | init_poll_funcptr(&poll->table, vhost_poll_func); | 77 | init_poll_funcptr(&poll->table, vhost_poll_func); |
71 | poll->mask = mask; | 78 | poll->mask = mask; |
72 | poll->dev = dev; | 79 | poll->dev = dev; |
73 | 80 | ||
74 | INIT_LIST_HEAD(&work->node); | 81 | vhost_work_init(&poll->work, fn); |
75 | work->fn = fn; | ||
76 | init_waitqueue_head(&work->done); | ||
77 | work->flushing = 0; | ||
78 | work->queue_seq = work->done_seq = 0; | ||
79 | } | 82 | } |
80 | 83 | ||
81 | /* Start polling a file. We add ourselves to file's wait queue. The caller must | 84 | /* Start polling a file. We add ourselves to file's wait queue. The caller must |
@@ -95,35 +98,38 @@ void vhost_poll_stop(struct vhost_poll *poll) | |||
95 | remove_wait_queue(poll->wqh, &poll->wait); | 98 | remove_wait_queue(poll->wqh, &poll->wait); |
96 | } | 99 | } |
97 | 100 | ||
98 | /* Flush any work that has been scheduled. When calling this, don't hold any | 101 | static void vhost_work_flush(struct vhost_dev *dev, struct vhost_work *work) |
99 | * locks that are also used by the callback. */ | ||
100 | void vhost_poll_flush(struct vhost_poll *poll) | ||
101 | { | 102 | { |
102 | struct vhost_work *work = &poll->work; | ||
103 | unsigned seq; | 103 | unsigned seq; |
104 | int left; | 104 | int left; |
105 | int flushing; | 105 | int flushing; |
106 | 106 | ||
107 | spin_lock_irq(&poll->dev->work_lock); | 107 | spin_lock_irq(&dev->work_lock); |
108 | seq = work->queue_seq; | 108 | seq = work->queue_seq; |
109 | work->flushing++; | 109 | work->flushing++; |
110 | spin_unlock_irq(&poll->dev->work_lock); | 110 | spin_unlock_irq(&dev->work_lock); |
111 | wait_event(work->done, ({ | 111 | wait_event(work->done, ({ |
112 | spin_lock_irq(&poll->dev->work_lock); | 112 | spin_lock_irq(&dev->work_lock); |
113 | left = seq - work->done_seq <= 0; | 113 | left = seq - work->done_seq <= 0; |
114 | spin_unlock_irq(&poll->dev->work_lock); | 114 | spin_unlock_irq(&dev->work_lock); |
115 | left; | 115 | left; |
116 | })); | 116 | })); |
117 | spin_lock_irq(&poll->dev->work_lock); | 117 | spin_lock_irq(&dev->work_lock); |
118 | flushing = --work->flushing; | 118 | flushing = --work->flushing; |
119 | spin_unlock_irq(&poll->dev->work_lock); | 119 | spin_unlock_irq(&dev->work_lock); |
120 | BUG_ON(flushing < 0); | 120 | BUG_ON(flushing < 0); |
121 | } | 121 | } |
122 | 122 | ||
123 | void vhost_poll_queue(struct vhost_poll *poll) | 123 | /* Flush any work that has been scheduled. When calling this, don't hold any |
124 | * locks that are also used by the callback. */ | ||
125 | void vhost_poll_flush(struct vhost_poll *poll) | ||
126 | { | ||
127 | vhost_work_flush(poll->dev, &poll->work); | ||
128 | } | ||
129 | |||
130 | static inline void vhost_work_queue(struct vhost_dev *dev, | ||
131 | struct vhost_work *work) | ||
124 | { | 132 | { |
125 | struct vhost_dev *dev = poll->dev; | ||
126 | struct vhost_work *work = &poll->work; | ||
127 | unsigned long flags; | 133 | unsigned long flags; |
128 | 134 | ||
129 | spin_lock_irqsave(&dev->work_lock, flags); | 135 | spin_lock_irqsave(&dev->work_lock, flags); |
@@ -135,6 +141,11 @@ void vhost_poll_queue(struct vhost_poll *poll) | |||
135 | spin_unlock_irqrestore(&dev->work_lock, flags); | 141 | spin_unlock_irqrestore(&dev->work_lock, flags); |
136 | } | 142 | } |
137 | 143 | ||
144 | void vhost_poll_queue(struct vhost_poll *poll) | ||
145 | { | ||
146 | vhost_work_queue(poll->dev, &poll->work); | ||
147 | } | ||
148 | |||
138 | static void vhost_vq_reset(struct vhost_dev *dev, | 149 | static void vhost_vq_reset(struct vhost_dev *dev, |
139 | struct vhost_virtqueue *vq) | 150 | struct vhost_virtqueue *vq) |
140 | { | 151 | { |
@@ -236,6 +247,29 @@ long vhost_dev_check_owner(struct vhost_dev *dev) | |||
236 | return dev->mm == current->mm ? 0 : -EPERM; | 247 | return dev->mm == current->mm ? 0 : -EPERM; |
237 | } | 248 | } |
238 | 249 | ||
250 | struct vhost_attach_cgroups_struct { | ||
251 | struct vhost_work work; | ||
252 | struct task_struct *owner; | ||
253 | int ret; | ||
254 | }; | ||
255 | |||
256 | static void vhost_attach_cgroups_work(struct vhost_work *work) | ||
257 | { | ||
258 | struct vhost_attach_cgroups_struct *s; | ||
259 | s = container_of(work, struct vhost_attach_cgroups_struct, work); | ||
260 | s->ret = cgroup_attach_task_all(s->owner, current); | ||
261 | } | ||
262 | |||
263 | static int vhost_attach_cgroups(struct vhost_dev *dev) | ||
264 | { | ||
265 | struct vhost_attach_cgroups_struct attach; | ||
266 | attach.owner = current; | ||
267 | vhost_work_init(&attach.work, vhost_attach_cgroups_work); | ||
268 | vhost_work_queue(dev, &attach.work); | ||
269 | vhost_work_flush(dev, &attach.work); | ||
270 | return attach.ret; | ||
271 | } | ||
272 | |||
239 | /* Caller should have device mutex */ | 273 | /* Caller should have device mutex */ |
240 | static long vhost_dev_set_owner(struct vhost_dev *dev) | 274 | static long vhost_dev_set_owner(struct vhost_dev *dev) |
241 | { | 275 | { |
@@ -255,14 +289,16 @@ static long vhost_dev_set_owner(struct vhost_dev *dev) | |||
255 | } | 289 | } |
256 | 290 | ||
257 | dev->worker = worker; | 291 | dev->worker = worker; |
258 | err = cgroup_attach_task_current_cg(worker); | 292 | wake_up_process(worker); /* avoid contributing to loadavg */ |
293 | |||
294 | err = vhost_attach_cgroups(dev); | ||
259 | if (err) | 295 | if (err) |
260 | goto err_cgroup; | 296 | goto err_cgroup; |
261 | wake_up_process(worker); /* avoid contributing to loadavg */ | ||
262 | 297 | ||
263 | return 0; | 298 | return 0; |
264 | err_cgroup: | 299 | err_cgroup: |
265 | kthread_stop(worker); | 300 | kthread_stop(worker); |
301 | dev->worker = NULL; | ||
266 | err_worker: | 302 | err_worker: |
267 | if (dev->mm) | 303 | if (dev->mm) |
268 | mmput(dev->mm); | 304 | mmput(dev->mm); |
@@ -323,7 +359,10 @@ void vhost_dev_cleanup(struct vhost_dev *dev) | |||
323 | dev->mm = NULL; | 359 | dev->mm = NULL; |
324 | 360 | ||
325 | WARN_ON(!list_empty(&dev->work_list)); | 361 | WARN_ON(!list_empty(&dev->work_list)); |
326 | kthread_stop(dev->worker); | 362 | if (dev->worker) { |
363 | kthread_stop(dev->worker); | ||
364 | dev->worker = NULL; | ||
365 | } | ||
327 | } | 366 | } |
328 | 367 | ||
329 | static int log_access_ok(void __user *log_base, u64 addr, unsigned long sz) | 368 | static int log_access_ok(void __user *log_base, u64 addr, unsigned long sz) |
@@ -819,11 +858,12 @@ int vhost_log_write(struct vhost_virtqueue *vq, struct vhost_log *log, | |||
819 | if (r < 0) | 858 | if (r < 0) |
820 | return r; | 859 | return r; |
821 | len -= l; | 860 | len -= l; |
822 | if (!len) | 861 | if (!len) { |
862 | if (vq->log_ctx) | ||
863 | eventfd_signal(vq->log_ctx, 1); | ||
823 | return 0; | 864 | return 0; |
865 | } | ||
824 | } | 866 | } |
825 | if (vq->log_ctx) | ||
826 | eventfd_signal(vq->log_ctx, 1); | ||
827 | /* Length written exceeds what we have stored. This is a bug. */ | 867 | /* Length written exceeds what we have stored. This is a bug. */ |
828 | BUG(); | 868 | BUG(); |
829 | return 0; | 869 | return 0; |
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 84f842331df..7ccc967831f 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c | |||
@@ -3508,7 +3508,7 @@ static void fbcon_exit(void) | |||
3508 | softback_buf = 0UL; | 3508 | softback_buf = 0UL; |
3509 | 3509 | ||
3510 | for (i = 0; i < FB_MAX; i++) { | 3510 | for (i = 0; i < FB_MAX; i++) { |
3511 | int pending; | 3511 | int pending = 0; |
3512 | 3512 | ||
3513 | mapped = 0; | 3513 | mapped = 0; |
3514 | info = registered_fb[i]; | 3514 | info = registered_fb[i]; |
@@ -3516,7 +3516,8 @@ static void fbcon_exit(void) | |||
3516 | if (info == NULL) | 3516 | if (info == NULL) |
3517 | continue; | 3517 | continue; |
3518 | 3518 | ||
3519 | pending = cancel_work_sync(&info->queue); | 3519 | if (info->queue.func) |
3520 | pending = cancel_work_sync(&info->queue); | ||
3520 | DPRINTK("fbcon: %s pending work\n", (pending ? "canceled" : | 3521 | DPRINTK("fbcon: %s pending work\n", (pending ? "canceled" : |
3521 | "no")); | 3522 | "no")); |
3522 | 3523 | ||
diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c index 815f84b0793..70477c2e4b6 100644 --- a/drivers/video/efifb.c +++ b/drivers/video/efifb.c | |||
@@ -13,7 +13,7 @@ | |||
13 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
14 | #include <linux/screen_info.h> | 14 | #include <linux/screen_info.h> |
15 | #include <linux/dmi.h> | 15 | #include <linux/dmi.h> |
16 | 16 | #include <linux/pci.h> | |
17 | #include <video/vga.h> | 17 | #include <video/vga.h> |
18 | 18 | ||
19 | static struct fb_var_screeninfo efifb_defined __devinitdata = { | 19 | static struct fb_var_screeninfo efifb_defined __devinitdata = { |
@@ -39,17 +39,31 @@ enum { | |||
39 | M_I20, /* 20-Inch iMac */ | 39 | M_I20, /* 20-Inch iMac */ |
40 | M_I20_SR, /* 20-Inch iMac (Santa Rosa) */ | 40 | M_I20_SR, /* 20-Inch iMac (Santa Rosa) */ |
41 | M_I24, /* 24-Inch iMac */ | 41 | M_I24, /* 24-Inch iMac */ |
42 | M_I24_8_1, /* 24-Inch iMac, 8,1th gen */ | ||
43 | M_I24_10_1, /* 24-Inch iMac, 10,1th gen */ | ||
44 | M_I27_11_1, /* 27-Inch iMac, 11,1th gen */ | ||
42 | M_MINI, /* Mac Mini */ | 45 | M_MINI, /* Mac Mini */ |
46 | M_MINI_3_1, /* Mac Mini, 3,1th gen */ | ||
47 | M_MINI_4_1, /* Mac Mini, 4,1th gen */ | ||
43 | M_MB, /* MacBook */ | 48 | M_MB, /* MacBook */ |
44 | M_MB_2, /* MacBook, 2nd rev. */ | 49 | M_MB_2, /* MacBook, 2nd rev. */ |
45 | M_MB_3, /* MacBook, 3rd rev. */ | 50 | M_MB_3, /* MacBook, 3rd rev. */ |
51 | M_MB_5_1, /* MacBook, 5th rev. */ | ||
52 | M_MB_6_1, /* MacBook, 6th rev. */ | ||
53 | M_MB_7_1, /* MacBook, 7th rev. */ | ||
46 | M_MB_SR, /* MacBook, 2nd gen, (Santa Rosa) */ | 54 | M_MB_SR, /* MacBook, 2nd gen, (Santa Rosa) */ |
47 | M_MBA, /* MacBook Air */ | 55 | M_MBA, /* MacBook Air */ |
48 | M_MBP, /* MacBook Pro */ | 56 | M_MBP, /* MacBook Pro */ |
49 | M_MBP_2, /* MacBook Pro 2nd gen */ | 57 | M_MBP_2, /* MacBook Pro 2nd gen */ |
58 | M_MBP_2_2, /* MacBook Pro 2,2nd gen */ | ||
50 | M_MBP_SR, /* MacBook Pro (Santa Rosa) */ | 59 | M_MBP_SR, /* MacBook Pro (Santa Rosa) */ |
51 | M_MBP_4, /* MacBook Pro, 4th gen */ | 60 | M_MBP_4, /* MacBook Pro, 4th gen */ |
52 | M_MBP_5_1, /* MacBook Pro, 5,1th gen */ | 61 | M_MBP_5_1, /* MacBook Pro, 5,1th gen */ |
62 | M_MBP_5_2, /* MacBook Pro, 5,2th gen */ | ||
63 | M_MBP_5_3, /* MacBook Pro, 5,3rd gen */ | ||
64 | M_MBP_6_1, /* MacBook Pro, 6,1th gen */ | ||
65 | M_MBP_6_2, /* MacBook Pro, 6,2th gen */ | ||
66 | M_MBP_7_1, /* MacBook Pro, 7,1th gen */ | ||
53 | M_UNKNOWN /* placeholder */ | 67 | M_UNKNOWN /* placeholder */ |
54 | }; | 68 | }; |
55 | 69 | ||
@@ -64,14 +78,28 @@ static struct efifb_dmi_info { | |||
64 | [M_I20] = { "i20", 0x80010000, 1728 * 4, 1680, 1050 }, /* guess */ | 78 | [M_I20] = { "i20", 0x80010000, 1728 * 4, 1680, 1050 }, /* guess */ |
65 | [M_I20_SR] = { "imac7", 0x40010000, 1728 * 4, 1680, 1050 }, | 79 | [M_I20_SR] = { "imac7", 0x40010000, 1728 * 4, 1680, 1050 }, |
66 | [M_I24] = { "i24", 0x80010000, 2048 * 4, 1920, 1200 }, /* guess */ | 80 | [M_I24] = { "i24", 0x80010000, 2048 * 4, 1920, 1200 }, /* guess */ |
81 | [M_I24_8_1] = { "imac8", 0xc0060000, 2048 * 4, 1920, 1200 }, | ||
82 | [M_I24_10_1] = { "imac10", 0xc0010000, 2048 * 4, 1920, 1080 }, | ||
83 | [M_I27_11_1] = { "imac11", 0xc0010000, 2560 * 4, 2560, 1440 }, | ||
67 | [M_MINI]= { "mini", 0x80000000, 2048 * 4, 1024, 768 }, | 84 | [M_MINI]= { "mini", 0x80000000, 2048 * 4, 1024, 768 }, |
85 | [M_MINI_3_1] = { "mini31", 0x40010000, 1024 * 4, 1024, 768 }, | ||
86 | [M_MINI_4_1] = { "mini41", 0xc0010000, 2048 * 4, 1920, 1200 }, | ||
68 | [M_MB] = { "macbook", 0x80000000, 2048 * 4, 1280, 800 }, | 87 | [M_MB] = { "macbook", 0x80000000, 2048 * 4, 1280, 800 }, |
88 | [M_MB_5_1] = { "macbook51", 0x80010000, 2048 * 4, 1280, 800 }, | ||
89 | [M_MB_6_1] = { "macbook61", 0x80010000, 2048 * 4, 1280, 800 }, | ||
90 | [M_MB_7_1] = { "macbook71", 0x80010000, 2048 * 4, 1280, 800 }, | ||
69 | [M_MBA] = { "mba", 0x80000000, 2048 * 4, 1280, 800 }, | 91 | [M_MBA] = { "mba", 0x80000000, 2048 * 4, 1280, 800 }, |
70 | [M_MBP] = { "mbp", 0x80010000, 1472 * 4, 1440, 900 }, | 92 | [M_MBP] = { "mbp", 0x80010000, 1472 * 4, 1440, 900 }, |
71 | [M_MBP_2] = { "mbp2", 0, 0, 0, 0 }, /* placeholder */ | 93 | [M_MBP_2] = { "mbp2", 0, 0, 0, 0 }, /* placeholder */ |
94 | [M_MBP_2_2] = { "mbp22", 0x80010000, 1472 * 4, 1440, 900 }, | ||
72 | [M_MBP_SR] = { "mbp3", 0x80030000, 2048 * 4, 1440, 900 }, | 95 | [M_MBP_SR] = { "mbp3", 0x80030000, 2048 * 4, 1440, 900 }, |
73 | [M_MBP_4] = { "mbp4", 0xc0060000, 2048 * 4, 1920, 1200 }, | 96 | [M_MBP_4] = { "mbp4", 0xc0060000, 2048 * 4, 1920, 1200 }, |
74 | [M_MBP_5_1] = { "mbp51", 0xc0010000, 2048 * 4, 1440, 900 }, | 97 | [M_MBP_5_1] = { "mbp51", 0xc0010000, 2048 * 4, 1440, 900 }, |
98 | [M_MBP_5_2] = { "mbp52", 0xc0010000, 2048 * 4, 1920, 1200 }, | ||
99 | [M_MBP_5_3] = { "mbp53", 0xd0010000, 2048 * 4, 1440, 900 }, | ||
100 | [M_MBP_6_1] = { "mbp61", 0x90030000, 2048 * 4, 1920, 1200 }, | ||
101 | [M_MBP_6_2] = { "mbp62", 0x90030000, 2048 * 4, 1680, 1050 }, | ||
102 | [M_MBP_7_1] = { "mbp71", 0xc0010000, 2048 * 4, 1280, 800 }, | ||
75 | [M_UNKNOWN] = { NULL, 0, 0, 0, 0 } | 103 | [M_UNKNOWN] = { NULL, 0, 0, 0, 0 } |
76 | }; | 104 | }; |
77 | 105 | ||
@@ -92,7 +120,12 @@ static const struct dmi_system_id dmi_system_table[] __initconst = { | |||
92 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac6,1", M_I24), | 120 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac6,1", M_I24), |
93 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac6,1", M_I24), | 121 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac6,1", M_I24), |
94 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac7,1", M_I20_SR), | 122 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac7,1", M_I20_SR), |
123 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac8,1", M_I24_8_1), | ||
124 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac10,1", M_I24_10_1), | ||
125 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac11,1", M_I27_11_1), | ||
95 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "Macmini1,1", M_MINI), | 126 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "Macmini1,1", M_MINI), |
127 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "Macmini3,1", M_MINI_3_1), | ||
128 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "Macmini4,1", M_MINI_4_1), | ||
96 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook1,1", M_MB), | 129 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook1,1", M_MB), |
97 | /* At least one of these two will be right; maybe both? */ | 130 | /* At least one of these two will be right; maybe both? */ |
98 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook2,1", M_MB), | 131 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook2,1", M_MB), |
@@ -101,14 +134,23 @@ static const struct dmi_system_id dmi_system_table[] __initconst = { | |||
101 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook3,1", M_MB), | 134 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook3,1", M_MB), |
102 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook3,1", M_MB), | 135 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook3,1", M_MB), |
103 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook4,1", M_MB), | 136 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook4,1", M_MB), |
137 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook5,1", M_MB_5_1), | ||
138 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook6,1", M_MB_6_1), | ||
139 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook7,1", M_MB_7_1), | ||
104 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir1,1", M_MBA), | 140 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir1,1", M_MBA), |
105 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro1,1", M_MBP), | 141 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro1,1", M_MBP), |
106 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,1", M_MBP_2), | 142 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,1", M_MBP_2), |
143 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,2", M_MBP_2_2), | ||
107 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro2,1", M_MBP_2), | 144 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro2,1", M_MBP_2), |
108 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro3,1", M_MBP_SR), | 145 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro3,1", M_MBP_SR), |
109 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro3,1", M_MBP_SR), | 146 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro3,1", M_MBP_SR), |
110 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro4,1", M_MBP_4), | 147 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro4,1", M_MBP_4), |
111 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,1", M_MBP_5_1), | 148 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,1", M_MBP_5_1), |
149 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,2", M_MBP_5_2), | ||
150 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,3", M_MBP_5_3), | ||
151 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,1", M_MBP_6_1), | ||
152 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,2", M_MBP_6_2), | ||
153 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro7,1", M_MBP_7_1), | ||
112 | {}, | 154 | {}, |
113 | }; | 155 | }; |
114 | 156 | ||
@@ -116,7 +158,7 @@ static int set_system(const struct dmi_system_id *id) | |||
116 | { | 158 | { |
117 | struct efifb_dmi_info *info = id->driver_data; | 159 | struct efifb_dmi_info *info = id->driver_data; |
118 | if (info->base == 0) | 160 | if (info->base == 0) |
119 | return -ENODEV; | 161 | return 0; |
120 | 162 | ||
121 | printk(KERN_INFO "efifb: dmi detected %s - framebuffer at %p " | 163 | printk(KERN_INFO "efifb: dmi detected %s - framebuffer at %p " |
122 | "(%dx%d, stride %d)\n", id->ident, | 164 | "(%dx%d, stride %d)\n", id->ident, |
@@ -124,18 +166,55 @@ static int set_system(const struct dmi_system_id *id) | |||
124 | info->stride); | 166 | info->stride); |
125 | 167 | ||
126 | /* Trust the bootloader over the DMI tables */ | 168 | /* Trust the bootloader over the DMI tables */ |
127 | if (screen_info.lfb_base == 0) | 169 | if (screen_info.lfb_base == 0) { |
170 | #if defined(CONFIG_PCI) | ||
171 | struct pci_dev *dev = NULL; | ||
172 | int found_bar = 0; | ||
173 | #endif | ||
128 | screen_info.lfb_base = info->base; | 174 | screen_info.lfb_base = info->base; |
129 | if (screen_info.lfb_linelength == 0) | ||
130 | screen_info.lfb_linelength = info->stride; | ||
131 | if (screen_info.lfb_width == 0) | ||
132 | screen_info.lfb_width = info->width; | ||
133 | if (screen_info.lfb_height == 0) | ||
134 | screen_info.lfb_height = info->height; | ||
135 | if (screen_info.orig_video_isVGA == 0) | ||
136 | screen_info.orig_video_isVGA = VIDEO_TYPE_EFI; | ||
137 | 175 | ||
138 | return 0; | 176 | #if defined(CONFIG_PCI) |
177 | /* make sure that the address in the table is actually on a | ||
178 | * VGA device's PCI BAR */ | ||
179 | |||
180 | for_each_pci_dev(dev) { | ||
181 | int i; | ||
182 | if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) | ||
183 | continue; | ||
184 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { | ||
185 | resource_size_t start, end; | ||
186 | |||
187 | start = pci_resource_start(dev, i); | ||
188 | if (start == 0) | ||
189 | break; | ||
190 | end = pci_resource_end(dev, i); | ||
191 | if (screen_info.lfb_base >= start && | ||
192 | screen_info.lfb_base < end) { | ||
193 | found_bar = 1; | ||
194 | } | ||
195 | } | ||
196 | } | ||
197 | if (!found_bar) | ||
198 | screen_info.lfb_base = 0; | ||
199 | #endif | ||
200 | } | ||
201 | if (screen_info.lfb_base) { | ||
202 | if (screen_info.lfb_linelength == 0) | ||
203 | screen_info.lfb_linelength = info->stride; | ||
204 | if (screen_info.lfb_width == 0) | ||
205 | screen_info.lfb_width = info->width; | ||
206 | if (screen_info.lfb_height == 0) | ||
207 | screen_info.lfb_height = info->height; | ||
208 | if (screen_info.orig_video_isVGA == 0) | ||
209 | screen_info.orig_video_isVGA = VIDEO_TYPE_EFI; | ||
210 | } else { | ||
211 | screen_info.lfb_linelength = 0; | ||
212 | screen_info.lfb_width = 0; | ||
213 | screen_info.lfb_height = 0; | ||
214 | screen_info.orig_video_isVGA = 0; | ||
215 | return 0; | ||
216 | } | ||
217 | return 1; | ||
139 | } | 218 | } |
140 | 219 | ||
141 | static int efifb_setcolreg(unsigned regno, unsigned red, unsigned green, | 220 | static int efifb_setcolreg(unsigned regno, unsigned red, unsigned green, |
diff --git a/drivers/video/pxa168fb.c b/drivers/video/pxa168fb.c index c91a7f70f7b..a31a77ff6f3 100644 --- a/drivers/video/pxa168fb.c +++ b/drivers/video/pxa168fb.c | |||
@@ -298,8 +298,8 @@ static void set_dma_control0(struct pxa168fb_info *fbi) | |||
298 | * Set bit to enable graphics DMA. | 298 | * Set bit to enable graphics DMA. |
299 | */ | 299 | */ |
300 | x = readl(fbi->reg_base + LCD_SPU_DMA_CTRL0); | 300 | x = readl(fbi->reg_base + LCD_SPU_DMA_CTRL0); |
301 | x |= fbi->active ? 0x00000100 : 0; | 301 | x &= ~CFG_GRA_ENA_MASK; |
302 | fbi->active = 0; | 302 | x |= fbi->active ? CFG_GRA_ENA(1) : CFG_GRA_ENA(0); |
303 | 303 | ||
304 | /* | 304 | /* |
305 | * If we are in a pseudo-color mode, we need to enable | 305 | * If we are in a pseudo-color mode, we need to enable |
@@ -559,7 +559,7 @@ static struct fb_ops pxa168fb_ops = { | |||
559 | .fb_imageblit = cfb_imageblit, | 559 | .fb_imageblit = cfb_imageblit, |
560 | }; | 560 | }; |
561 | 561 | ||
562 | static int __init pxa168fb_init_mode(struct fb_info *info, | 562 | static int __devinit pxa168fb_init_mode(struct fb_info *info, |
563 | struct pxa168fb_mach_info *mi) | 563 | struct pxa168fb_mach_info *mi) |
564 | { | 564 | { |
565 | struct pxa168fb_info *fbi = info->par; | 565 | struct pxa168fb_info *fbi = info->par; |
@@ -599,7 +599,7 @@ static int __init pxa168fb_init_mode(struct fb_info *info, | |||
599 | return ret; | 599 | return ret; |
600 | } | 600 | } |
601 | 601 | ||
602 | static int __init pxa168fb_probe(struct platform_device *pdev) | 602 | static int __devinit pxa168fb_probe(struct platform_device *pdev) |
603 | { | 603 | { |
604 | struct pxa168fb_mach_info *mi; | 604 | struct pxa168fb_mach_info *mi; |
605 | struct fb_info *info = 0; | 605 | struct fb_info *info = 0; |
@@ -792,7 +792,7 @@ static struct platform_driver pxa168fb_driver = { | |||
792 | .probe = pxa168fb_probe, | 792 | .probe = pxa168fb_probe, |
793 | }; | 793 | }; |
794 | 794 | ||
795 | static int __devinit pxa168fb_init(void) | 795 | static int __init pxa168fb_init(void) |
796 | { | 796 | { |
797 | return platform_driver_register(&pxa168fb_driver); | 797 | return platform_driver_register(&pxa168fb_driver); |
798 | } | 798 | } |
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c index 559bf1727a2..b52f8e4ef1f 100644 --- a/drivers/video/sis/sis_main.c +++ b/drivers/video/sis/sis_main.c | |||
@@ -1701,6 +1701,9 @@ static int sisfb_ioctl(struct fb_info *info, unsigned int cmd, | |||
1701 | break; | 1701 | break; |
1702 | 1702 | ||
1703 | case FBIOGET_VBLANK: | 1703 | case FBIOGET_VBLANK: |
1704 | |||
1705 | memset(&sisvbblank, 0, sizeof(struct fb_vblank)); | ||
1706 | |||
1704 | sisvbblank.count = 0; | 1707 | sisvbblank.count = 0; |
1705 | sisvbblank.flags = sisfb_setupvbblankflags(ivideo, &sisvbblank.vcount, &sisvbblank.hcount); | 1708 | sisvbblank.flags = sisfb_setupvbblankflags(ivideo, &sisvbblank.vcount, &sisvbblank.hcount); |
1706 | 1709 | ||
diff --git a/drivers/video/via/ioctl.c b/drivers/video/via/ioctl.c index da03c074e32..4d553d0b8d7 100644 --- a/drivers/video/via/ioctl.c +++ b/drivers/video/via/ioctl.c | |||
@@ -25,6 +25,8 @@ int viafb_ioctl_get_viafb_info(u_long arg) | |||
25 | { | 25 | { |
26 | struct viafb_ioctl_info viainfo; | 26 | struct viafb_ioctl_info viainfo; |
27 | 27 | ||
28 | memset(&viainfo, 0, sizeof(struct viafb_ioctl_info)); | ||
29 | |||
28 | viainfo.viafb_id = VIAID; | 30 | viainfo.viafb_id = VIAID; |
29 | viainfo.vendor_id = PCI_VIA_VENDOR_ID; | 31 | viainfo.vendor_id = PCI_VIA_VENDOR_ID; |
30 | 32 | ||
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index b036677df8c..24efd8ea41b 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig | |||
@@ -213,11 +213,11 @@ config OMAP_WATCHDOG | |||
213 | here to enable the OMAP1610/OMAP1710/OMAP2420/OMAP3430/OMAP4430 watchdog timer. | 213 | here to enable the OMAP1610/OMAP1710/OMAP2420/OMAP3430/OMAP4430 watchdog timer. |
214 | 214 | ||
215 | config PNX4008_WATCHDOG | 215 | config PNX4008_WATCHDOG |
216 | tristate "PNX4008 Watchdog" | 216 | tristate "PNX4008 and LPC32XX Watchdog" |
217 | depends on ARCH_PNX4008 | 217 | depends on ARCH_PNX4008 || ARCH_LPC32XX |
218 | help | 218 | help |
219 | Say Y here if to include support for the watchdog timer | 219 | Say Y here if to include support for the watchdog timer |
220 | in the PNX4008 processor. | 220 | in the PNX4008 or LPC32XX processor. |
221 | This driver can be built as a module by choosing M. The module | 221 | This driver can be built as a module by choosing M. The module |
222 | will be called pnx4008_wdt. | 222 | will be called pnx4008_wdt. |
223 | 223 | ||
diff --git a/drivers/watchdog/sb_wdog.c b/drivers/watchdog/sb_wdog.c index 88c83aa5730..f31493e65b3 100644 --- a/drivers/watchdog/sb_wdog.c +++ b/drivers/watchdog/sb_wdog.c | |||
@@ -305,7 +305,7 @@ static int __init sbwdog_init(void) | |||
305 | if (ret) { | 305 | if (ret) { |
306 | printk(KERN_ERR "%s: failed to request irq 1 - %d\n", | 306 | printk(KERN_ERR "%s: failed to request irq 1 - %d\n", |
307 | ident.identity, ret); | 307 | ident.identity, ret); |
308 | return ret; | 308 | goto out; |
309 | } | 309 | } |
310 | 310 | ||
311 | ret = misc_register(&sbwdog_miscdev); | 311 | ret = misc_register(&sbwdog_miscdev); |
@@ -313,14 +313,20 @@ static int __init sbwdog_init(void) | |||
313 | printk(KERN_INFO "%s: timeout is %ld.%ld secs\n", | 313 | printk(KERN_INFO "%s: timeout is %ld.%ld secs\n", |
314 | ident.identity, | 314 | ident.identity, |
315 | timeout / 1000000, (timeout / 100000) % 10); | 315 | timeout / 1000000, (timeout / 100000) % 10); |
316 | } else | 316 | return 0; |
317 | free_irq(1, (void *)user_dog); | 317 | } |
318 | free_irq(1, (void *)user_dog); | ||
319 | out: | ||
320 | unregister_reboot_notifier(&sbwdog_notifier); | ||
321 | |||
318 | return ret; | 322 | return ret; |
319 | } | 323 | } |
320 | 324 | ||
321 | static void __exit sbwdog_exit(void) | 325 | static void __exit sbwdog_exit(void) |
322 | { | 326 | { |
323 | misc_deregister(&sbwdog_miscdev); | 327 | misc_deregister(&sbwdog_miscdev); |
328 | free_irq(1, (void *)user_dog); | ||
329 | unregister_reboot_notifier(&sbwdog_notifier); | ||
324 | } | 330 | } |
325 | 331 | ||
326 | module_init(sbwdog_init); | 332 | module_init(sbwdog_init); |
diff --git a/drivers/watchdog/ts72xx_wdt.c b/drivers/watchdog/ts72xx_wdt.c index 458c499c122..18cdeb4c425 100644 --- a/drivers/watchdog/ts72xx_wdt.c +++ b/drivers/watchdog/ts72xx_wdt.c | |||
@@ -449,6 +449,9 @@ static __devinit int ts72xx_wdt_probe(struct platform_device *pdev) | |||
449 | wdt->pdev = pdev; | 449 | wdt->pdev = pdev; |
450 | mutex_init(&wdt->lock); | 450 | mutex_init(&wdt->lock); |
451 | 451 | ||
452 | /* make sure that the watchdog is disabled */ | ||
453 | ts72xx_wdt_stop(wdt); | ||
454 | |||
452 | error = misc_register(&ts72xx_wdt_miscdev); | 455 | error = misc_register(&ts72xx_wdt_miscdev); |
453 | if (error) { | 456 | if (error) { |
454 | dev_err(&pdev->dev, "failed to register miscdev\n"); | 457 | dev_err(&pdev->dev, "failed to register miscdev\n"); |
diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 72f91bff29c..13365ba3521 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c | |||
@@ -112,6 +112,7 @@ static inline unsigned long *cpu_evtchn_mask(int cpu) | |||
112 | #define VALID_EVTCHN(chn) ((chn) != 0) | 112 | #define VALID_EVTCHN(chn) ((chn) != 0) |
113 | 113 | ||
114 | static struct irq_chip xen_dynamic_chip; | 114 | static struct irq_chip xen_dynamic_chip; |
115 | static struct irq_chip xen_percpu_chip; | ||
115 | 116 | ||
116 | /* Constructor for packed IRQ information. */ | 117 | /* Constructor for packed IRQ information. */ |
117 | static struct irq_info mk_unbound_info(void) | 118 | static struct irq_info mk_unbound_info(void) |
@@ -377,7 +378,7 @@ int bind_evtchn_to_irq(unsigned int evtchn) | |||
377 | irq = find_unbound_irq(); | 378 | irq = find_unbound_irq(); |
378 | 379 | ||
379 | set_irq_chip_and_handler_name(irq, &xen_dynamic_chip, | 380 | set_irq_chip_and_handler_name(irq, &xen_dynamic_chip, |
380 | handle_level_irq, "event"); | 381 | handle_edge_irq, "event"); |
381 | 382 | ||
382 | evtchn_to_irq[evtchn] = irq; | 383 | evtchn_to_irq[evtchn] = irq; |
383 | irq_info[irq] = mk_evtchn_info(evtchn); | 384 | irq_info[irq] = mk_evtchn_info(evtchn); |
@@ -403,8 +404,8 @@ static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu) | |||
403 | if (irq < 0) | 404 | if (irq < 0) |
404 | goto out; | 405 | goto out; |
405 | 406 | ||
406 | set_irq_chip_and_handler_name(irq, &xen_dynamic_chip, | 407 | set_irq_chip_and_handler_name(irq, &xen_percpu_chip, |
407 | handle_level_irq, "ipi"); | 408 | handle_percpu_irq, "ipi"); |
408 | 409 | ||
409 | bind_ipi.vcpu = cpu; | 410 | bind_ipi.vcpu = cpu; |
410 | if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_ipi, | 411 | if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_ipi, |
@@ -444,8 +445,8 @@ static int bind_virq_to_irq(unsigned int virq, unsigned int cpu) | |||
444 | 445 | ||
445 | irq = find_unbound_irq(); | 446 | irq = find_unbound_irq(); |
446 | 447 | ||
447 | set_irq_chip_and_handler_name(irq, &xen_dynamic_chip, | 448 | set_irq_chip_and_handler_name(irq, &xen_percpu_chip, |
448 | handle_level_irq, "virq"); | 449 | handle_percpu_irq, "virq"); |
449 | 450 | ||
450 | evtchn_to_irq[evtchn] = irq; | 451 | evtchn_to_irq[evtchn] = irq; |
451 | irq_info[irq] = mk_virq_info(evtchn, virq); | 452 | irq_info[irq] = mk_virq_info(evtchn, virq); |
@@ -964,6 +965,16 @@ static struct irq_chip xen_dynamic_chip __read_mostly = { | |||
964 | .retrigger = retrigger_dynirq, | 965 | .retrigger = retrigger_dynirq, |
965 | }; | 966 | }; |
966 | 967 | ||
968 | static struct irq_chip xen_percpu_chip __read_mostly = { | ||
969 | .name = "xen-percpu", | ||
970 | |||
971 | .disable = disable_dynirq, | ||
972 | .mask = disable_dynirq, | ||
973 | .unmask = enable_dynirq, | ||
974 | |||
975 | .ack = ack_dynirq, | ||
976 | }; | ||
977 | |||
967 | int xen_set_callback_via(uint64_t via) | 978 | int xen_set_callback_via(uint64_t via) |
968 | { | 979 | { |
969 | struct xen_hvm_param a; | 980 | struct xen_hvm_param a; |
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index 1799bd89031..ef9c7db5207 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c | |||
@@ -237,7 +237,7 @@ static void sysrq_handler(struct xenbus_watch *watch, const char **vec, | |||
237 | goto again; | 237 | goto again; |
238 | 238 | ||
239 | if (sysrq_key != '\0') | 239 | if (sysrq_key != '\0') |
240 | handle_sysrq(sysrq_key, NULL); | 240 | handle_sysrq(sysrq_key); |
241 | } | 241 | } |
242 | 242 | ||
243 | static struct xenbus_watch sysrq_watch = { | 243 | static struct xenbus_watch sysrq_watch = { |
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c index 29bac511887..d409495876f 100644 --- a/drivers/xen/xenbus/xenbus_probe.c +++ b/drivers/xen/xenbus/xenbus_probe.c | |||
@@ -755,7 +755,10 @@ int register_xenstore_notifier(struct notifier_block *nb) | |||
755 | { | 755 | { |
756 | int ret = 0; | 756 | int ret = 0; |
757 | 757 | ||
758 | blocking_notifier_chain_register(&xenstore_chain, nb); | 758 | if (xenstored_ready > 0) |
759 | ret = nb->notifier_call(nb, 0, NULL); | ||
760 | else | ||
761 | blocking_notifier_chain_register(&xenstore_chain, nb); | ||
759 | 762 | ||
760 | return ret; | 763 | return ret; |
761 | } | 764 | } |
@@ -769,7 +772,7 @@ EXPORT_SYMBOL_GPL(unregister_xenstore_notifier); | |||
769 | 772 | ||
770 | void xenbus_probe(struct work_struct *unused) | 773 | void xenbus_probe(struct work_struct *unused) |
771 | { | 774 | { |
772 | BUG_ON((xenstored_ready <= 0)); | 775 | xenstored_ready = 1; |
773 | 776 | ||
774 | /* Enumerate devices in xenstore and watch for changes. */ | 777 | /* Enumerate devices in xenstore and watch for changes. */ |
775 | xenbus_probe_devices(&xenbus_frontend); | 778 | xenbus_probe_devices(&xenbus_frontend); |
@@ -835,8 +838,8 @@ static int __init xenbus_init(void) | |||
835 | xen_store_evtchn = xen_start_info->store_evtchn; | 838 | xen_store_evtchn = xen_start_info->store_evtchn; |
836 | xen_store_mfn = xen_start_info->store_mfn; | 839 | xen_store_mfn = xen_start_info->store_mfn; |
837 | xen_store_interface = mfn_to_virt(xen_store_mfn); | 840 | xen_store_interface = mfn_to_virt(xen_store_mfn); |
841 | xenstored_ready = 1; | ||
838 | } | 842 | } |
839 | xenstored_ready = 1; | ||
840 | } | 843 | } |
841 | 844 | ||
842 | /* Initialize the interface to xenstore. */ | 845 | /* Initialize the interface to xenstore. */ |
diff --git a/firmware/Makefile b/firmware/Makefile index b27f09f05d1..9c2d19452d0 100644 --- a/firmware/Makefile +++ b/firmware/Makefile | |||
@@ -142,7 +142,7 @@ fw-shipped-$(CONFIG_YAM) += yam/1200.bin yam/9600.bin | |||
142 | fw-shipped-all := $(fw-shipped-y) $(fw-shipped-m) $(fw-shipped-) | 142 | fw-shipped-all := $(fw-shipped-y) $(fw-shipped-m) $(fw-shipped-) |
143 | 143 | ||
144 | # Directories which we _might_ need to create, so we have a rule for them. | 144 | # Directories which we _might_ need to create, so we have a rule for them. |
145 | firmware-dirs := $(sort $(patsubst %,$(objtree)/$(obj)/%/,$(dir $(fw-external-y) $(fw-shipped-all)))) | 145 | firmware-dirs := $(sort $(addprefix $(objtree)/$(obj)/,$(dir $(fw-external-y) $(fw-shipped-all)))) |
146 | 146 | ||
147 | quiet_cmd_mkdir = MKDIR $(patsubst $(objtree)/%,%,$@) | 147 | quiet_cmd_mkdir = MKDIR $(patsubst $(objtree)/%,%,$@) |
148 | cmd_mkdir = mkdir -p $@ | 148 | cmd_mkdir = mkdir -p $@ |
diff --git a/fs/9p/fid.c b/fs/9p/fid.c index 35856368906..6406f896bf9 100644 --- a/fs/9p/fid.c +++ b/fs/9p/fid.c | |||
@@ -242,7 +242,8 @@ struct p9_fid *v9fs_fid_lookup(struct dentry *dentry) | |||
242 | } | 242 | } |
243 | kfree(wnames); | 243 | kfree(wnames); |
244 | fid_out: | 244 | fid_out: |
245 | v9fs_fid_add(dentry, fid); | 245 | if (!IS_ERR(fid)) |
246 | v9fs_fid_add(dentry, fid); | ||
246 | err_out: | 247 | err_out: |
247 | up_read(&v9ses->rename_sem); | 248 | up_read(&v9ses->rename_sem); |
248 | return fid; | 249 | return fid; |
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c index 16c8a2a98c1..899f168fd19 100644 --- a/fs/9p/vfs_dir.c +++ b/fs/9p/vfs_dir.c | |||
@@ -292,9 +292,11 @@ int v9fs_dir_release(struct inode *inode, struct file *filp) | |||
292 | 292 | ||
293 | fid = filp->private_data; | 293 | fid = filp->private_data; |
294 | P9_DPRINTK(P9_DEBUG_VFS, | 294 | P9_DPRINTK(P9_DEBUG_VFS, |
295 | "inode: %p filp: %p fid: %d\n", inode, filp, fid->fid); | 295 | "v9fs_dir_release: inode: %p filp: %p fid: %d\n", |
296 | inode, filp, fid ? fid->fid : -1); | ||
296 | filemap_write_and_wait(inode->i_mapping); | 297 | filemap_write_and_wait(inode->i_mapping); |
297 | p9_client_clunk(fid); | 298 | if (fid) |
299 | p9_client_clunk(fid); | ||
298 | return 0; | 300 | return 0; |
299 | } | 301 | } |
300 | 302 | ||
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index c7c23eab944..9e670d52764 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -730,7 +730,10 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int mode, | |||
730 | P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err); | 730 | P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err); |
731 | goto error; | 731 | goto error; |
732 | } | 732 | } |
733 | dentry->d_op = &v9fs_cached_dentry_operations; | 733 | if (v9ses->cache) |
734 | dentry->d_op = &v9fs_cached_dentry_operations; | ||
735 | else | ||
736 | dentry->d_op = &v9fs_dentry_operations; | ||
734 | d_instantiate(dentry, inode); | 737 | d_instantiate(dentry, inode); |
735 | err = v9fs_fid_add(dentry, fid); | 738 | err = v9fs_fid_add(dentry, fid); |
736 | if (err < 0) | 739 | if (err < 0) |
@@ -1128,6 +1131,7 @@ v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, | |||
1128 | v9fs_stat2inode(st, dentry->d_inode, dentry->d_inode->i_sb); | 1131 | v9fs_stat2inode(st, dentry->d_inode, dentry->d_inode->i_sb); |
1129 | generic_fillattr(dentry->d_inode, stat); | 1132 | generic_fillattr(dentry->d_inode, stat); |
1130 | 1133 | ||
1134 | p9stat_free(st); | ||
1131 | kfree(st); | 1135 | kfree(st); |
1132 | return 0; | 1136 | return 0; |
1133 | } | 1137 | } |
@@ -1489,6 +1493,7 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen) | |||
1489 | 1493 | ||
1490 | retval = strnlen(buffer, buflen); | 1494 | retval = strnlen(buffer, buflen); |
1491 | done: | 1495 | done: |
1496 | p9stat_free(st); | ||
1492 | kfree(st); | 1497 | kfree(st); |
1493 | return retval; | 1498 | return retval; |
1494 | } | 1499 | } |
@@ -1942,7 +1947,7 @@ static const struct inode_operations v9fs_dir_inode_operations_dotu = { | |||
1942 | .unlink = v9fs_vfs_unlink, | 1947 | .unlink = v9fs_vfs_unlink, |
1943 | .mkdir = v9fs_vfs_mkdir, | 1948 | .mkdir = v9fs_vfs_mkdir, |
1944 | .rmdir = v9fs_vfs_rmdir, | 1949 | .rmdir = v9fs_vfs_rmdir, |
1945 | .mknod = v9fs_vfs_mknod_dotl, | 1950 | .mknod = v9fs_vfs_mknod, |
1946 | .rename = v9fs_vfs_rename, | 1951 | .rename = v9fs_vfs_rename, |
1947 | .getattr = v9fs_vfs_getattr, | 1952 | .getattr = v9fs_vfs_getattr, |
1948 | .setattr = v9fs_vfs_setattr, | 1953 | .setattr = v9fs_vfs_setattr, |
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index f9311077de6..1d12ba0ed3d 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c | |||
@@ -122,6 +122,10 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags, | |||
122 | fid = v9fs_session_init(v9ses, dev_name, data); | 122 | fid = v9fs_session_init(v9ses, dev_name, data); |
123 | if (IS_ERR(fid)) { | 123 | if (IS_ERR(fid)) { |
124 | retval = PTR_ERR(fid); | 124 | retval = PTR_ERR(fid); |
125 | /* | ||
126 | * we need to call session_close to tear down some | ||
127 | * of the data structure setup by session_init | ||
128 | */ | ||
125 | goto close_session; | 129 | goto close_session; |
126 | } | 130 | } |
127 | 131 | ||
@@ -144,7 +148,6 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags, | |||
144 | retval = -ENOMEM; | 148 | retval = -ENOMEM; |
145 | goto release_sb; | 149 | goto release_sb; |
146 | } | 150 | } |
147 | |||
148 | sb->s_root = root; | 151 | sb->s_root = root; |
149 | 152 | ||
150 | if (v9fs_proto_dotl(v9ses)) { | 153 | if (v9fs_proto_dotl(v9ses)) { |
@@ -152,7 +155,7 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags, | |||
152 | st = p9_client_getattr_dotl(fid, P9_STATS_BASIC); | 155 | st = p9_client_getattr_dotl(fid, P9_STATS_BASIC); |
153 | if (IS_ERR(st)) { | 156 | if (IS_ERR(st)) { |
154 | retval = PTR_ERR(st); | 157 | retval = PTR_ERR(st); |
155 | goto clunk_fid; | 158 | goto release_sb; |
156 | } | 159 | } |
157 | 160 | ||
158 | v9fs_stat2inode_dotl(st, root->d_inode); | 161 | v9fs_stat2inode_dotl(st, root->d_inode); |
@@ -162,7 +165,7 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags, | |||
162 | st = p9_client_stat(fid); | 165 | st = p9_client_stat(fid); |
163 | if (IS_ERR(st)) { | 166 | if (IS_ERR(st)) { |
164 | retval = PTR_ERR(st); | 167 | retval = PTR_ERR(st); |
165 | goto clunk_fid; | 168 | goto release_sb; |
166 | } | 169 | } |
167 | 170 | ||
168 | root->d_inode->i_ino = v9fs_qid2ino(&st->qid); | 171 | root->d_inode->i_ino = v9fs_qid2ino(&st->qid); |
@@ -174,19 +177,24 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags, | |||
174 | 177 | ||
175 | v9fs_fid_add(root, fid); | 178 | v9fs_fid_add(root, fid); |
176 | 179 | ||
177 | P9_DPRINTK(P9_DEBUG_VFS, " simple set mount, return 0\n"); | 180 | P9_DPRINTK(P9_DEBUG_VFS, " simple set mount, return 0\n"); |
178 | simple_set_mnt(mnt, sb); | 181 | simple_set_mnt(mnt, sb); |
179 | return 0; | 182 | return 0; |
180 | 183 | ||
181 | clunk_fid: | 184 | clunk_fid: |
182 | p9_client_clunk(fid); | 185 | p9_client_clunk(fid); |
183 | |||
184 | close_session: | 186 | close_session: |
185 | v9fs_session_close(v9ses); | 187 | v9fs_session_close(v9ses); |
186 | kfree(v9ses); | 188 | kfree(v9ses); |
187 | return retval; | 189 | return retval; |
188 | |||
189 | release_sb: | 190 | release_sb: |
191 | /* | ||
192 | * we will do the session_close and root dentry release | ||
193 | * in the below call. But we need to clunk fid, because we haven't | ||
194 | * attached the fid to dentry so it won't get clunked | ||
195 | * automatically. | ||
196 | */ | ||
197 | p9_client_clunk(fid); | ||
190 | deactivate_locked_super(sb); | 198 | deactivate_locked_super(sb); |
191 | return retval; | 199 | return retval; |
192 | } | 200 | } |
@@ -712,8 +712,16 @@ static ssize_t aio_run_iocb(struct kiocb *iocb) | |||
712 | */ | 712 | */ |
713 | ret = retry(iocb); | 713 | ret = retry(iocb); |
714 | 714 | ||
715 | if (ret != -EIOCBRETRY && ret != -EIOCBQUEUED) | 715 | if (ret != -EIOCBRETRY && ret != -EIOCBQUEUED) { |
716 | /* | ||
717 | * There's no easy way to restart the syscall since other AIO's | ||
718 | * may be already running. Just fail this IO with EINTR. | ||
719 | */ | ||
720 | if (unlikely(ret == -ERESTARTSYS || ret == -ERESTARTNOINTR || | ||
721 | ret == -ERESTARTNOHAND || ret == -ERESTART_RESTARTBLOCK)) | ||
722 | ret = -EINTR; | ||
716 | aio_complete(iocb, ret, 0); | 723 | aio_complete(iocb, ret, 0); |
724 | } | ||
717 | out: | 725 | out: |
718 | spin_lock_irq(&ctx->ctx_lock); | 726 | spin_lock_irq(&ctx->ctx_lock); |
719 | 727 | ||
@@ -1659,6 +1667,9 @@ long do_io_submit(aio_context_t ctx_id, long nr, | |||
1659 | if (unlikely(nr < 0)) | 1667 | if (unlikely(nr < 0)) |
1660 | return -EINVAL; | 1668 | return -EINVAL; |
1661 | 1669 | ||
1670 | if (unlikely(nr > LONG_MAX/sizeof(*iocbpp))) | ||
1671 | nr = LONG_MAX/sizeof(*iocbpp); | ||
1672 | |||
1662 | if (unlikely(!access_ok(VERIFY_READ, iocbpp, (nr*sizeof(*iocbpp))))) | 1673 | if (unlikely(!access_ok(VERIFY_READ, iocbpp, (nr*sizeof(*iocbpp))))) |
1663 | return -EFAULT; | 1674 | return -EFAULT; |
1664 | 1675 | ||
diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c index f96eff04e11..a6395bdb26a 100644 --- a/fs/binfmt_aout.c +++ b/fs/binfmt_aout.c | |||
@@ -134,10 +134,6 @@ static int aout_core_dump(struct coredump_params *cprm) | |||
134 | if (!dump_write(file, dump_start, dump_size)) | 134 | if (!dump_write(file, dump_start, dump_size)) |
135 | goto end_coredump; | 135 | goto end_coredump; |
136 | } | 136 | } |
137 | /* Finally dump the task struct. Not be used by gdb, but could be useful */ | ||
138 | set_fs(KERNEL_DS); | ||
139 | if (!dump_write(file, current, sizeof(*current))) | ||
140 | goto end_coredump; | ||
141 | end_coredump: | 137 | end_coredump: |
142 | set_fs(fs); | 138 | set_fs(fs); |
143 | return has_dumped; | 139 | return has_dumped; |
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c index a7528b91393..fd0cc0bf9a4 100644 --- a/fs/binfmt_misc.c +++ b/fs/binfmt_misc.c | |||
@@ -724,7 +724,7 @@ static int __init init_misc_binfmt(void) | |||
724 | { | 724 | { |
725 | int err = register_filesystem(&bm_fs_type); | 725 | int err = register_filesystem(&bm_fs_type); |
726 | if (!err) { | 726 | if (!err) { |
727 | err = register_binfmt(&misc_format); | 727 | err = insert_binfmt(&misc_format); |
728 | if (err) | 728 | if (err) |
729 | unregister_filesystem(&bm_fs_type); | 729 | unregister_filesystem(&bm_fs_type); |
730 | } | 730 | } |
diff --git a/fs/bio-integrity.c b/fs/bio-integrity.c index 612a5c38d3c..4d0ff5ee27b 100644 --- a/fs/bio-integrity.c +++ b/fs/bio-integrity.c | |||
@@ -413,10 +413,10 @@ int bio_integrity_prep(struct bio *bio) | |||
413 | 413 | ||
414 | /* Allocate kernel buffer for protection data */ | 414 | /* Allocate kernel buffer for protection data */ |
415 | len = sectors * blk_integrity_tuple_size(bi); | 415 | len = sectors * blk_integrity_tuple_size(bi); |
416 | buf = kmalloc(len, GFP_NOIO | __GFP_NOFAIL | q->bounce_gfp); | 416 | buf = kmalloc(len, GFP_NOIO | q->bounce_gfp); |
417 | if (unlikely(buf == NULL)) { | 417 | if (unlikely(buf == NULL)) { |
418 | printk(KERN_ERR "could not allocate integrity buffer\n"); | 418 | printk(KERN_ERR "could not allocate integrity buffer\n"); |
419 | return -EIO; | 419 | return -ENOMEM; |
420 | } | 420 | } |
421 | 421 | ||
422 | end = (((unsigned long) buf) + len + PAGE_SIZE - 1) >> PAGE_SHIFT; | 422 | end = (((unsigned long) buf) + len + PAGE_SIZE - 1) >> PAGE_SHIFT; |
diff --git a/fs/ceph/Kconfig b/fs/ceph/Kconfig index bc87b9c1d27..0fcd2640c23 100644 --- a/fs/ceph/Kconfig +++ b/fs/ceph/Kconfig | |||
@@ -3,6 +3,7 @@ config CEPH_FS | |||
3 | depends on INET && EXPERIMENTAL | 3 | depends on INET && EXPERIMENTAL |
4 | select LIBCRC32C | 4 | select LIBCRC32C |
5 | select CRYPTO_AES | 5 | select CRYPTO_AES |
6 | select CRYPTO | ||
6 | help | 7 | help |
7 | Choose Y or M here to include support for mounting the | 8 | Choose Y or M here to include support for mounting the |
8 | experimental Ceph distributed file system. Ceph is an extremely | 9 | experimental Ceph distributed file system. Ceph is an extremely |
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index 5598a0d0229..efbc604001c 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c | |||
@@ -87,7 +87,7 @@ static int ceph_set_page_dirty(struct page *page) | |||
87 | 87 | ||
88 | /* dirty the head */ | 88 | /* dirty the head */ |
89 | spin_lock(&inode->i_lock); | 89 | spin_lock(&inode->i_lock); |
90 | if (ci->i_wrbuffer_ref_head == 0) | 90 | if (ci->i_head_snapc == NULL) |
91 | ci->i_head_snapc = ceph_get_snap_context(snapc); | 91 | ci->i_head_snapc = ceph_get_snap_context(snapc); |
92 | ++ci->i_wrbuffer_ref_head; | 92 | ++ci->i_wrbuffer_ref_head; |
93 | if (ci->i_wrbuffer_ref == 0) | 93 | if (ci->i_wrbuffer_ref == 0) |
@@ -105,13 +105,7 @@ static int ceph_set_page_dirty(struct page *page) | |||
105 | spin_lock_irq(&mapping->tree_lock); | 105 | spin_lock_irq(&mapping->tree_lock); |
106 | if (page->mapping) { /* Race with truncate? */ | 106 | if (page->mapping) { /* Race with truncate? */ |
107 | WARN_ON_ONCE(!PageUptodate(page)); | 107 | WARN_ON_ONCE(!PageUptodate(page)); |
108 | 108 | account_page_dirtied(page, page->mapping); | |
109 | if (mapping_cap_account_dirty(mapping)) { | ||
110 | __inc_zone_page_state(page, NR_FILE_DIRTY); | ||
111 | __inc_bdi_stat(mapping->backing_dev_info, | ||
112 | BDI_RECLAIMABLE); | ||
113 | task_io_account_write(PAGE_CACHE_SIZE); | ||
114 | } | ||
115 | radix_tree_tag_set(&mapping->page_tree, | 109 | radix_tree_tag_set(&mapping->page_tree, |
116 | page_index(page), PAGECACHE_TAG_DIRTY); | 110 | page_index(page), PAGECACHE_TAG_DIRTY); |
117 | 111 | ||
@@ -352,7 +346,7 @@ static struct ceph_snap_context *get_oldest_context(struct inode *inode, | |||
352 | break; | 346 | break; |
353 | } | 347 | } |
354 | } | 348 | } |
355 | if (!snapc && ci->i_head_snapc) { | 349 | if (!snapc && ci->i_wrbuffer_ref_head) { |
356 | snapc = ceph_get_snap_context(ci->i_head_snapc); | 350 | snapc = ceph_get_snap_context(ci->i_head_snapc); |
357 | dout(" head snapc %p has %d dirty pages\n", | 351 | dout(" head snapc %p has %d dirty pages\n", |
358 | snapc, ci->i_wrbuffer_ref_head); | 352 | snapc, ci->i_wrbuffer_ref_head); |
@@ -417,8 +411,8 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc) | |||
417 | if (i_size < page_off + len) | 411 | if (i_size < page_off + len) |
418 | len = i_size - page_off; | 412 | len = i_size - page_off; |
419 | 413 | ||
420 | dout("writepage %p page %p index %lu on %llu~%u\n", | 414 | dout("writepage %p page %p index %lu on %llu~%u snapc %p\n", |
421 | inode, page, page->index, page_off, len); | 415 | inode, page, page->index, page_off, len, snapc); |
422 | 416 | ||
423 | writeback_stat = atomic_long_inc_return(&client->writeback_count); | 417 | writeback_stat = atomic_long_inc_return(&client->writeback_count); |
424 | if (writeback_stat > | 418 | if (writeback_stat > |
@@ -772,7 +766,8 @@ get_more_pages: | |||
772 | /* ok */ | 766 | /* ok */ |
773 | if (locked_pages == 0) { | 767 | if (locked_pages == 0) { |
774 | /* prepare async write request */ | 768 | /* prepare async write request */ |
775 | offset = page->index << PAGE_CACHE_SHIFT; | 769 | offset = (unsigned long long)page->index |
770 | << PAGE_CACHE_SHIFT; | ||
776 | len = wsize; | 771 | len = wsize; |
777 | req = ceph_osdc_new_request(&client->osdc, | 772 | req = ceph_osdc_new_request(&client->osdc, |
778 | &ci->i_layout, | 773 | &ci->i_layout, |
diff --git a/fs/ceph/auth_x.c b/fs/ceph/auth_x.c index 582e0b2caf8..a2d002cbdec 100644 --- a/fs/ceph/auth_x.c +++ b/fs/ceph/auth_x.c | |||
@@ -376,7 +376,7 @@ static void ceph_x_validate_tickets(struct ceph_auth_client *ac, int *pneed) | |||
376 | 376 | ||
377 | th = get_ticket_handler(ac, service); | 377 | th = get_ticket_handler(ac, service); |
378 | 378 | ||
379 | if (!th) { | 379 | if (IS_ERR(th)) { |
380 | *pneed |= service; | 380 | *pneed |= service; |
381 | continue; | 381 | continue; |
382 | } | 382 | } |
@@ -399,6 +399,9 @@ static int ceph_x_build_request(struct ceph_auth_client *ac, | |||
399 | struct ceph_x_ticket_handler *th = | 399 | struct ceph_x_ticket_handler *th = |
400 | get_ticket_handler(ac, CEPH_ENTITY_TYPE_AUTH); | 400 | get_ticket_handler(ac, CEPH_ENTITY_TYPE_AUTH); |
401 | 401 | ||
402 | if (IS_ERR(th)) | ||
403 | return PTR_ERR(th); | ||
404 | |||
402 | ceph_x_validate_tickets(ac, &need); | 405 | ceph_x_validate_tickets(ac, &need); |
403 | 406 | ||
404 | dout("build_request want %x have %x need %x\n", | 407 | dout("build_request want %x have %x need %x\n", |
@@ -450,7 +453,6 @@ static int ceph_x_build_request(struct ceph_auth_client *ac, | |||
450 | return -ERANGE; | 453 | return -ERANGE; |
451 | head->op = cpu_to_le16(CEPHX_GET_PRINCIPAL_SESSION_KEY); | 454 | head->op = cpu_to_le16(CEPHX_GET_PRINCIPAL_SESSION_KEY); |
452 | 455 | ||
453 | BUG_ON(!th); | ||
454 | ret = ceph_x_build_authorizer(ac, th, &xi->auth_authorizer); | 456 | ret = ceph_x_build_authorizer(ac, th, &xi->auth_authorizer); |
455 | if (ret) | 457 | if (ret) |
456 | return ret; | 458 | return ret; |
@@ -505,7 +507,8 @@ static int ceph_x_handle_reply(struct ceph_auth_client *ac, int result, | |||
505 | 507 | ||
506 | case CEPHX_GET_PRINCIPAL_SESSION_KEY: | 508 | case CEPHX_GET_PRINCIPAL_SESSION_KEY: |
507 | th = get_ticket_handler(ac, CEPH_ENTITY_TYPE_AUTH); | 509 | th = get_ticket_handler(ac, CEPH_ENTITY_TYPE_AUTH); |
508 | BUG_ON(!th); | 510 | if (IS_ERR(th)) |
511 | return PTR_ERR(th); | ||
509 | ret = ceph_x_proc_ticket_reply(ac, &th->session_key, | 512 | ret = ceph_x_proc_ticket_reply(ac, &th->session_key, |
510 | buf + sizeof(*head), end); | 513 | buf + sizeof(*head), end); |
511 | break; | 514 | break; |
@@ -563,8 +566,8 @@ static int ceph_x_verify_authorizer_reply(struct ceph_auth_client *ac, | |||
563 | void *end = p + sizeof(au->reply_buf); | 566 | void *end = p + sizeof(au->reply_buf); |
564 | 567 | ||
565 | th = get_ticket_handler(ac, au->service); | 568 | th = get_ticket_handler(ac, au->service); |
566 | if (!th) | 569 | if (IS_ERR(th)) |
567 | return -EIO; /* hrm! */ | 570 | return PTR_ERR(th); |
568 | ret = ceph_x_decrypt(&th->session_key, &p, end, &reply, sizeof(reply)); | 571 | ret = ceph_x_decrypt(&th->session_key, &p, end, &reply, sizeof(reply)); |
569 | if (ret < 0) | 572 | if (ret < 0) |
570 | return ret; | 573 | return ret; |
@@ -626,7 +629,7 @@ static void ceph_x_invalidate_authorizer(struct ceph_auth_client *ac, | |||
626 | struct ceph_x_ticket_handler *th; | 629 | struct ceph_x_ticket_handler *th; |
627 | 630 | ||
628 | th = get_ticket_handler(ac, peer_type); | 631 | th = get_ticket_handler(ac, peer_type); |
629 | if (th && !IS_ERR(th)) | 632 | if (!IS_ERR(th)) |
630 | remove_ticket_handler(ac, th); | 633 | remove_ticket_handler(ac, th); |
631 | } | 634 | } |
632 | 635 | ||
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 7bf182b0397..5e9da996a15 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c | |||
@@ -814,7 +814,7 @@ int __ceph_caps_used(struct ceph_inode_info *ci) | |||
814 | used |= CEPH_CAP_PIN; | 814 | used |= CEPH_CAP_PIN; |
815 | if (ci->i_rd_ref) | 815 | if (ci->i_rd_ref) |
816 | used |= CEPH_CAP_FILE_RD; | 816 | used |= CEPH_CAP_FILE_RD; |
817 | if (ci->i_rdcache_ref || ci->i_rdcache_gen) | 817 | if (ci->i_rdcache_ref || ci->vfs_inode.i_data.nrpages) |
818 | used |= CEPH_CAP_FILE_CACHE; | 818 | used |= CEPH_CAP_FILE_CACHE; |
819 | if (ci->i_wr_ref) | 819 | if (ci->i_wr_ref) |
820 | used |= CEPH_CAP_FILE_WR; | 820 | used |= CEPH_CAP_FILE_WR; |
@@ -1082,6 +1082,7 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap, | |||
1082 | gid_t gid; | 1082 | gid_t gid; |
1083 | struct ceph_mds_session *session; | 1083 | struct ceph_mds_session *session; |
1084 | u64 xattr_version = 0; | 1084 | u64 xattr_version = 0; |
1085 | struct ceph_buffer *xattr_blob = NULL; | ||
1085 | int delayed = 0; | 1086 | int delayed = 0; |
1086 | u64 flush_tid = 0; | 1087 | u64 flush_tid = 0; |
1087 | int i; | 1088 | int i; |
@@ -1142,6 +1143,10 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap, | |||
1142 | for (i = 0; i < CEPH_CAP_BITS; i++) | 1143 | for (i = 0; i < CEPH_CAP_BITS; i++) |
1143 | if (flushing & (1 << i)) | 1144 | if (flushing & (1 << i)) |
1144 | ci->i_cap_flush_tid[i] = flush_tid; | 1145 | ci->i_cap_flush_tid[i] = flush_tid; |
1146 | |||
1147 | follows = ci->i_head_snapc->seq; | ||
1148 | } else { | ||
1149 | follows = 0; | ||
1145 | } | 1150 | } |
1146 | 1151 | ||
1147 | keep = cap->implemented; | 1152 | keep = cap->implemented; |
@@ -1155,14 +1160,14 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap, | |||
1155 | mtime = inode->i_mtime; | 1160 | mtime = inode->i_mtime; |
1156 | atime = inode->i_atime; | 1161 | atime = inode->i_atime; |
1157 | time_warp_seq = ci->i_time_warp_seq; | 1162 | time_warp_seq = ci->i_time_warp_seq; |
1158 | follows = ci->i_snap_realm->cached_context->seq; | ||
1159 | uid = inode->i_uid; | 1163 | uid = inode->i_uid; |
1160 | gid = inode->i_gid; | 1164 | gid = inode->i_gid; |
1161 | mode = inode->i_mode; | 1165 | mode = inode->i_mode; |
1162 | 1166 | ||
1163 | if (dropping & CEPH_CAP_XATTR_EXCL) { | 1167 | if (flushing & CEPH_CAP_XATTR_EXCL) { |
1164 | __ceph_build_xattrs_blob(ci); | 1168 | __ceph_build_xattrs_blob(ci); |
1165 | xattr_version = ci->i_xattrs.version + 1; | 1169 | xattr_blob = ci->i_xattrs.blob; |
1170 | xattr_version = ci->i_xattrs.version; | ||
1166 | } | 1171 | } |
1167 | 1172 | ||
1168 | spin_unlock(&inode->i_lock); | 1173 | spin_unlock(&inode->i_lock); |
@@ -1170,9 +1175,7 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap, | |||
1170 | ret = send_cap_msg(session, ceph_vino(inode).ino, cap_id, | 1175 | ret = send_cap_msg(session, ceph_vino(inode).ino, cap_id, |
1171 | op, keep, want, flushing, seq, flush_tid, issue_seq, mseq, | 1176 | op, keep, want, flushing, seq, flush_tid, issue_seq, mseq, |
1172 | size, max_size, &mtime, &atime, time_warp_seq, | 1177 | size, max_size, &mtime, &atime, time_warp_seq, |
1173 | uid, gid, mode, | 1178 | uid, gid, mode, xattr_version, xattr_blob, |
1174 | xattr_version, | ||
1175 | (flushing & CEPH_CAP_XATTR_EXCL) ? ci->i_xattrs.blob : NULL, | ||
1176 | follows); | 1179 | follows); |
1177 | if (ret < 0) { | 1180 | if (ret < 0) { |
1178 | dout("error sending cap msg, must requeue %p\n", inode); | 1181 | dout("error sending cap msg, must requeue %p\n", inode); |
@@ -1192,10 +1195,14 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap, | |||
1192 | * asynchronously back to the MDS once sync writes complete and dirty | 1195 | * asynchronously back to the MDS once sync writes complete and dirty |
1193 | * data is written out. | 1196 | * data is written out. |
1194 | * | 1197 | * |
1198 | * Unless @again is true, skip cap_snaps that were already sent to | ||
1199 | * the MDS (i.e., during this session). | ||
1200 | * | ||
1195 | * Called under i_lock. Takes s_mutex as needed. | 1201 | * Called under i_lock. Takes s_mutex as needed. |
1196 | */ | 1202 | */ |
1197 | void __ceph_flush_snaps(struct ceph_inode_info *ci, | 1203 | void __ceph_flush_snaps(struct ceph_inode_info *ci, |
1198 | struct ceph_mds_session **psession) | 1204 | struct ceph_mds_session **psession, |
1205 | int again) | ||
1199 | __releases(ci->vfs_inode->i_lock) | 1206 | __releases(ci->vfs_inode->i_lock) |
1200 | __acquires(ci->vfs_inode->i_lock) | 1207 | __acquires(ci->vfs_inode->i_lock) |
1201 | { | 1208 | { |
@@ -1224,7 +1231,7 @@ retry: | |||
1224 | * pages to be written out. | 1231 | * pages to be written out. |
1225 | */ | 1232 | */ |
1226 | if (capsnap->dirty_pages || capsnap->writing) | 1233 | if (capsnap->dirty_pages || capsnap->writing) |
1227 | continue; | 1234 | break; |
1228 | 1235 | ||
1229 | /* | 1236 | /* |
1230 | * if cap writeback already occurred, we should have dropped | 1237 | * if cap writeback already occurred, we should have dropped |
@@ -1237,6 +1244,13 @@ retry: | |||
1237 | dout("no auth cap (migrating?), doing nothing\n"); | 1244 | dout("no auth cap (migrating?), doing nothing\n"); |
1238 | goto out; | 1245 | goto out; |
1239 | } | 1246 | } |
1247 | |||
1248 | /* only flush each capsnap once */ | ||
1249 | if (!again && !list_empty(&capsnap->flushing_item)) { | ||
1250 | dout("already flushed %p, skipping\n", capsnap); | ||
1251 | continue; | ||
1252 | } | ||
1253 | |||
1240 | mds = ci->i_auth_cap->session->s_mds; | 1254 | mds = ci->i_auth_cap->session->s_mds; |
1241 | mseq = ci->i_auth_cap->mseq; | 1255 | mseq = ci->i_auth_cap->mseq; |
1242 | 1256 | ||
@@ -1273,8 +1287,8 @@ retry: | |||
1273 | &session->s_cap_snaps_flushing); | 1287 | &session->s_cap_snaps_flushing); |
1274 | spin_unlock(&inode->i_lock); | 1288 | spin_unlock(&inode->i_lock); |
1275 | 1289 | ||
1276 | dout("flush_snaps %p cap_snap %p follows %lld size %llu\n", | 1290 | dout("flush_snaps %p cap_snap %p follows %lld tid %llu\n", |
1277 | inode, capsnap, next_follows, capsnap->size); | 1291 | inode, capsnap, capsnap->follows, capsnap->flush_tid); |
1278 | send_cap_msg(session, ceph_vino(inode).ino, 0, | 1292 | send_cap_msg(session, ceph_vino(inode).ino, 0, |
1279 | CEPH_CAP_OP_FLUSHSNAP, capsnap->issued, 0, | 1293 | CEPH_CAP_OP_FLUSHSNAP, capsnap->issued, 0, |
1280 | capsnap->dirty, 0, capsnap->flush_tid, 0, mseq, | 1294 | capsnap->dirty, 0, capsnap->flush_tid, 0, mseq, |
@@ -1282,7 +1296,7 @@ retry: | |||
1282 | &capsnap->mtime, &capsnap->atime, | 1296 | &capsnap->mtime, &capsnap->atime, |
1283 | capsnap->time_warp_seq, | 1297 | capsnap->time_warp_seq, |
1284 | capsnap->uid, capsnap->gid, capsnap->mode, | 1298 | capsnap->uid, capsnap->gid, capsnap->mode, |
1285 | 0, NULL, | 1299 | capsnap->xattr_version, capsnap->xattr_blob, |
1286 | capsnap->follows); | 1300 | capsnap->follows); |
1287 | 1301 | ||
1288 | next_follows = capsnap->follows + 1; | 1302 | next_follows = capsnap->follows + 1; |
@@ -1311,7 +1325,7 @@ static void ceph_flush_snaps(struct ceph_inode_info *ci) | |||
1311 | struct inode *inode = &ci->vfs_inode; | 1325 | struct inode *inode = &ci->vfs_inode; |
1312 | 1326 | ||
1313 | spin_lock(&inode->i_lock); | 1327 | spin_lock(&inode->i_lock); |
1314 | __ceph_flush_snaps(ci, NULL); | 1328 | __ceph_flush_snaps(ci, NULL, 0); |
1315 | spin_unlock(&inode->i_lock); | 1329 | spin_unlock(&inode->i_lock); |
1316 | } | 1330 | } |
1317 | 1331 | ||
@@ -1332,7 +1346,11 @@ void __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask) | |||
1332 | ceph_cap_string(was | mask)); | 1346 | ceph_cap_string(was | mask)); |
1333 | ci->i_dirty_caps |= mask; | 1347 | ci->i_dirty_caps |= mask; |
1334 | if (was == 0) { | 1348 | if (was == 0) { |
1335 | dout(" inode %p now dirty\n", &ci->vfs_inode); | 1349 | if (!ci->i_head_snapc) |
1350 | ci->i_head_snapc = ceph_get_snap_context( | ||
1351 | ci->i_snap_realm->cached_context); | ||
1352 | dout(" inode %p now dirty snapc %p\n", &ci->vfs_inode, | ||
1353 | ci->i_head_snapc); | ||
1336 | BUG_ON(!list_empty(&ci->i_dirty_item)); | 1354 | BUG_ON(!list_empty(&ci->i_dirty_item)); |
1337 | spin_lock(&mdsc->cap_dirty_lock); | 1355 | spin_lock(&mdsc->cap_dirty_lock); |
1338 | list_add(&ci->i_dirty_item, &mdsc->cap_dirty); | 1356 | list_add(&ci->i_dirty_item, &mdsc->cap_dirty); |
@@ -1470,7 +1488,7 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags, | |||
1470 | 1488 | ||
1471 | /* flush snaps first time around only */ | 1489 | /* flush snaps first time around only */ |
1472 | if (!list_empty(&ci->i_cap_snaps)) | 1490 | if (!list_empty(&ci->i_cap_snaps)) |
1473 | __ceph_flush_snaps(ci, &session); | 1491 | __ceph_flush_snaps(ci, &session, 0); |
1474 | goto retry_locked; | 1492 | goto retry_locked; |
1475 | retry: | 1493 | retry: |
1476 | spin_lock(&inode->i_lock); | 1494 | spin_lock(&inode->i_lock); |
@@ -1887,7 +1905,7 @@ static void kick_flushing_capsnaps(struct ceph_mds_client *mdsc, | |||
1887 | if (cap && cap->session == session) { | 1905 | if (cap && cap->session == session) { |
1888 | dout("kick_flushing_caps %p cap %p capsnap %p\n", inode, | 1906 | dout("kick_flushing_caps %p cap %p capsnap %p\n", inode, |
1889 | cap, capsnap); | 1907 | cap, capsnap); |
1890 | __ceph_flush_snaps(ci, &session); | 1908 | __ceph_flush_snaps(ci, &session, 1); |
1891 | } else { | 1909 | } else { |
1892 | pr_err("%p auth cap %p not mds%d ???\n", inode, | 1910 | pr_err("%p auth cap %p not mds%d ???\n", inode, |
1893 | cap, session->s_mds); | 1911 | cap, session->s_mds); |
@@ -2190,7 +2208,9 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr, | |||
2190 | 2208 | ||
2191 | if (ci->i_head_snapc == snapc) { | 2209 | if (ci->i_head_snapc == snapc) { |
2192 | ci->i_wrbuffer_ref_head -= nr; | 2210 | ci->i_wrbuffer_ref_head -= nr; |
2193 | if (!ci->i_wrbuffer_ref_head) { | 2211 | if (ci->i_wrbuffer_ref_head == 0 && |
2212 | ci->i_dirty_caps == 0 && ci->i_flushing_caps == 0) { | ||
2213 | BUG_ON(!ci->i_head_snapc); | ||
2194 | ceph_put_snap_context(ci->i_head_snapc); | 2214 | ceph_put_snap_context(ci->i_head_snapc); |
2195 | ci->i_head_snapc = NULL; | 2215 | ci->i_head_snapc = NULL; |
2196 | } | 2216 | } |
@@ -2263,7 +2283,8 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant, | |||
2263 | { | 2283 | { |
2264 | struct ceph_inode_info *ci = ceph_inode(inode); | 2284 | struct ceph_inode_info *ci = ceph_inode(inode); |
2265 | int mds = session->s_mds; | 2285 | int mds = session->s_mds; |
2266 | int seq = le32_to_cpu(grant->seq); | 2286 | unsigned seq = le32_to_cpu(grant->seq); |
2287 | unsigned issue_seq = le32_to_cpu(grant->issue_seq); | ||
2267 | int newcaps = le32_to_cpu(grant->caps); | 2288 | int newcaps = le32_to_cpu(grant->caps); |
2268 | int issued, implemented, used, wanted, dirty; | 2289 | int issued, implemented, used, wanted, dirty; |
2269 | u64 size = le64_to_cpu(grant->size); | 2290 | u64 size = le64_to_cpu(grant->size); |
@@ -2275,8 +2296,8 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant, | |||
2275 | int revoked_rdcache = 0; | 2296 | int revoked_rdcache = 0; |
2276 | int queue_invalidate = 0; | 2297 | int queue_invalidate = 0; |
2277 | 2298 | ||
2278 | dout("handle_cap_grant inode %p cap %p mds%d seq %d %s\n", | 2299 | dout("handle_cap_grant inode %p cap %p mds%d seq %u/%u %s\n", |
2279 | inode, cap, mds, seq, ceph_cap_string(newcaps)); | 2300 | inode, cap, mds, seq, issue_seq, ceph_cap_string(newcaps)); |
2280 | dout(" size %llu max_size %llu, i_size %llu\n", size, max_size, | 2301 | dout(" size %llu max_size %llu, i_size %llu\n", size, max_size, |
2281 | inode->i_size); | 2302 | inode->i_size); |
2282 | 2303 | ||
@@ -2372,6 +2393,7 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant, | |||
2372 | } | 2393 | } |
2373 | 2394 | ||
2374 | cap->seq = seq; | 2395 | cap->seq = seq; |
2396 | cap->issue_seq = issue_seq; | ||
2375 | 2397 | ||
2376 | /* file layout may have changed */ | 2398 | /* file layout may have changed */ |
2377 | ci->i_layout = grant->layout; | 2399 | ci->i_layout = grant->layout; |
@@ -2483,6 +2505,11 @@ static void handle_cap_flush_ack(struct inode *inode, u64 flush_tid, | |||
2483 | dout(" inode %p now clean\n", inode); | 2505 | dout(" inode %p now clean\n", inode); |
2484 | BUG_ON(!list_empty(&ci->i_dirty_item)); | 2506 | BUG_ON(!list_empty(&ci->i_dirty_item)); |
2485 | drop = 1; | 2507 | drop = 1; |
2508 | if (ci->i_wrbuffer_ref_head == 0) { | ||
2509 | BUG_ON(!ci->i_head_snapc); | ||
2510 | ceph_put_snap_context(ci->i_head_snapc); | ||
2511 | ci->i_head_snapc = NULL; | ||
2512 | } | ||
2486 | } else { | 2513 | } else { |
2487 | BUG_ON(list_empty(&ci->i_dirty_item)); | 2514 | BUG_ON(list_empty(&ci->i_dirty_item)); |
2488 | } | 2515 | } |
@@ -2749,15 +2776,7 @@ void ceph_handle_caps(struct ceph_mds_session *session, | |||
2749 | if (op == CEPH_CAP_OP_IMPORT) | 2776 | if (op == CEPH_CAP_OP_IMPORT) |
2750 | __queue_cap_release(session, vino.ino, cap_id, | 2777 | __queue_cap_release(session, vino.ino, cap_id, |
2751 | mseq, seq); | 2778 | mseq, seq); |
2752 | 2779 | goto flush_cap_releases; | |
2753 | /* | ||
2754 | * send any full release message to try to move things | ||
2755 | * along for the mds (who clearly thinks we still have this | ||
2756 | * cap). | ||
2757 | */ | ||
2758 | ceph_add_cap_releases(mdsc, session); | ||
2759 | ceph_send_cap_releases(mdsc, session); | ||
2760 | goto done; | ||
2761 | } | 2780 | } |
2762 | 2781 | ||
2763 | /* these will work even if we don't have a cap yet */ | 2782 | /* these will work even if we don't have a cap yet */ |
@@ -2785,7 +2804,7 @@ void ceph_handle_caps(struct ceph_mds_session *session, | |||
2785 | dout(" no cap on %p ino %llx.%llx from mds%d\n", | 2804 | dout(" no cap on %p ino %llx.%llx from mds%d\n", |
2786 | inode, ceph_ino(inode), ceph_snap(inode), mds); | 2805 | inode, ceph_ino(inode), ceph_snap(inode), mds); |
2787 | spin_unlock(&inode->i_lock); | 2806 | spin_unlock(&inode->i_lock); |
2788 | goto done; | 2807 | goto flush_cap_releases; |
2789 | } | 2808 | } |
2790 | 2809 | ||
2791 | /* note that each of these drops i_lock for us */ | 2810 | /* note that each of these drops i_lock for us */ |
@@ -2809,6 +2828,17 @@ void ceph_handle_caps(struct ceph_mds_session *session, | |||
2809 | ceph_cap_op_name(op)); | 2828 | ceph_cap_op_name(op)); |
2810 | } | 2829 | } |
2811 | 2830 | ||
2831 | goto done; | ||
2832 | |||
2833 | flush_cap_releases: | ||
2834 | /* | ||
2835 | * send any full release message to try to move things | ||
2836 | * along for the mds (who clearly thinks we still have this | ||
2837 | * cap). | ||
2838 | */ | ||
2839 | ceph_add_cap_releases(mdsc, session); | ||
2840 | ceph_send_cap_releases(mdsc, session); | ||
2841 | |||
2812 | done: | 2842 | done: |
2813 | mutex_unlock(&session->s_mutex); | 2843 | mutex_unlock(&session->s_mutex); |
2814 | done_unlocked: | 2844 | done_unlocked: |
diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c index 360c4f22718..6fd8b20a861 100644 --- a/fs/ceph/debugfs.c +++ b/fs/ceph/debugfs.c | |||
@@ -171,6 +171,8 @@ static int mdsc_show(struct seq_file *s, void *p) | |||
171 | } else if (req->r_dentry) { | 171 | } else if (req->r_dentry) { |
172 | path = ceph_mdsc_build_path(req->r_dentry, &pathlen, | 172 | path = ceph_mdsc_build_path(req->r_dentry, &pathlen, |
173 | &pathbase, 0); | 173 | &pathbase, 0); |
174 | if (IS_ERR(path)) | ||
175 | path = NULL; | ||
174 | spin_lock(&req->r_dentry->d_lock); | 176 | spin_lock(&req->r_dentry->d_lock); |
175 | seq_printf(s, " #%llx/%.*s (%s)", | 177 | seq_printf(s, " #%llx/%.*s (%s)", |
176 | ceph_ino(req->r_dentry->d_parent->d_inode), | 178 | ceph_ino(req->r_dentry->d_parent->d_inode), |
@@ -187,6 +189,8 @@ static int mdsc_show(struct seq_file *s, void *p) | |||
187 | if (req->r_old_dentry) { | 189 | if (req->r_old_dentry) { |
188 | path = ceph_mdsc_build_path(req->r_old_dentry, &pathlen, | 190 | path = ceph_mdsc_build_path(req->r_old_dentry, &pathlen, |
189 | &pathbase, 0); | 191 | &pathbase, 0); |
192 | if (IS_ERR(path)) | ||
193 | path = NULL; | ||
190 | spin_lock(&req->r_old_dentry->d_lock); | 194 | spin_lock(&req->r_old_dentry->d_lock); |
191 | seq_printf(s, " #%llx/%.*s (%s)", | 195 | seq_printf(s, " #%llx/%.*s (%s)", |
192 | ceph_ino(req->r_old_dentry->d_parent->d_inode), | 196 | ceph_ino(req->r_old_dentry->d_parent->d_inode), |
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 67bbb41d552..a1986eb5204 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
@@ -46,7 +46,7 @@ int ceph_init_dentry(struct dentry *dentry) | |||
46 | else | 46 | else |
47 | dentry->d_op = &ceph_snap_dentry_ops; | 47 | dentry->d_op = &ceph_snap_dentry_ops; |
48 | 48 | ||
49 | di = kmem_cache_alloc(ceph_dentry_cachep, GFP_NOFS); | 49 | di = kmem_cache_alloc(ceph_dentry_cachep, GFP_NOFS | __GFP_ZERO); |
50 | if (!di) | 50 | if (!di) |
51 | return -ENOMEM; /* oh well */ | 51 | return -ENOMEM; /* oh well */ |
52 | 52 | ||
@@ -1021,11 +1021,15 @@ out_touch: | |||
1021 | static void ceph_dentry_release(struct dentry *dentry) | 1021 | static void ceph_dentry_release(struct dentry *dentry) |
1022 | { | 1022 | { |
1023 | struct ceph_dentry_info *di = ceph_dentry(dentry); | 1023 | struct ceph_dentry_info *di = ceph_dentry(dentry); |
1024 | struct inode *parent_inode = dentry->d_parent->d_inode; | 1024 | struct inode *parent_inode = NULL; |
1025 | u64 snapid = ceph_snap(parent_inode); | 1025 | u64 snapid = CEPH_NOSNAP; |
1026 | 1026 | ||
1027 | if (!IS_ROOT(dentry)) { | ||
1028 | parent_inode = dentry->d_parent->d_inode; | ||
1029 | if (parent_inode) | ||
1030 | snapid = ceph_snap(parent_inode); | ||
1031 | } | ||
1027 | dout("dentry_release %p parent %p\n", dentry, parent_inode); | 1032 | dout("dentry_release %p parent %p\n", dentry, parent_inode); |
1028 | |||
1029 | if (parent_inode && snapid != CEPH_SNAPDIR) { | 1033 | if (parent_inode && snapid != CEPH_SNAPDIR) { |
1030 | struct ceph_inode_info *ci = ceph_inode(parent_inode); | 1034 | struct ceph_inode_info *ci = ceph_inode(parent_inode); |
1031 | 1035 | ||
diff --git a/fs/ceph/export.c b/fs/ceph/export.c index 4480cb1c63e..e38423e82f2 100644 --- a/fs/ceph/export.c +++ b/fs/ceph/export.c | |||
@@ -42,32 +42,37 @@ struct ceph_nfs_confh { | |||
42 | static int ceph_encode_fh(struct dentry *dentry, u32 *rawfh, int *max_len, | 42 | static int ceph_encode_fh(struct dentry *dentry, u32 *rawfh, int *max_len, |
43 | int connectable) | 43 | int connectable) |
44 | { | 44 | { |
45 | int type; | ||
45 | struct ceph_nfs_fh *fh = (void *)rawfh; | 46 | struct ceph_nfs_fh *fh = (void *)rawfh; |
46 | struct ceph_nfs_confh *cfh = (void *)rawfh; | 47 | struct ceph_nfs_confh *cfh = (void *)rawfh; |
47 | struct dentry *parent = dentry->d_parent; | 48 | struct dentry *parent = dentry->d_parent; |
48 | struct inode *inode = dentry->d_inode; | 49 | struct inode *inode = dentry->d_inode; |
49 | int type; | 50 | int connected_handle_length = sizeof(*cfh)/4; |
51 | int handle_length = sizeof(*fh)/4; | ||
50 | 52 | ||
51 | /* don't re-export snaps */ | 53 | /* don't re-export snaps */ |
52 | if (ceph_snap(inode) != CEPH_NOSNAP) | 54 | if (ceph_snap(inode) != CEPH_NOSNAP) |
53 | return -EINVAL; | 55 | return -EINVAL; |
54 | 56 | ||
55 | if (*max_len >= sizeof(*cfh)) { | 57 | if (*max_len >= connected_handle_length) { |
56 | dout("encode_fh %p connectable\n", dentry); | 58 | dout("encode_fh %p connectable\n", dentry); |
57 | cfh->ino = ceph_ino(dentry->d_inode); | 59 | cfh->ino = ceph_ino(dentry->d_inode); |
58 | cfh->parent_ino = ceph_ino(parent->d_inode); | 60 | cfh->parent_ino = ceph_ino(parent->d_inode); |
59 | cfh->parent_name_hash = parent->d_name.hash; | 61 | cfh->parent_name_hash = parent->d_name.hash; |
60 | *max_len = sizeof(*cfh); | 62 | *max_len = connected_handle_length; |
61 | type = 2; | 63 | type = 2; |
62 | } else if (*max_len > sizeof(*fh)) { | 64 | } else if (*max_len >= handle_length) { |
63 | if (connectable) | 65 | if (connectable) { |
64 | return -ENOSPC; | 66 | *max_len = connected_handle_length; |
67 | return 255; | ||
68 | } | ||
65 | dout("encode_fh %p\n", dentry); | 69 | dout("encode_fh %p\n", dentry); |
66 | fh->ino = ceph_ino(dentry->d_inode); | 70 | fh->ino = ceph_ino(dentry->d_inode); |
67 | *max_len = sizeof(*fh); | 71 | *max_len = handle_length; |
68 | type = 1; | 72 | type = 1; |
69 | } else { | 73 | } else { |
70 | return -ENOSPC; | 74 | *max_len = handle_length; |
75 | return 255; | ||
71 | } | 76 | } |
72 | return type; | 77 | return type; |
73 | } | 78 | } |
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 8c044a4f045..66e4da6dba2 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c | |||
@@ -697,7 +697,7 @@ more: | |||
697 | * start_request so that a tid has been assigned. | 697 | * start_request so that a tid has been assigned. |
698 | */ | 698 | */ |
699 | spin_lock(&ci->i_unsafe_lock); | 699 | spin_lock(&ci->i_unsafe_lock); |
700 | list_add(&ci->i_unsafe_writes, &req->r_unsafe_item); | 700 | list_add(&req->r_unsafe_item, &ci->i_unsafe_writes); |
701 | spin_unlock(&ci->i_unsafe_lock); | 701 | spin_unlock(&ci->i_unsafe_lock); |
702 | ceph_get_cap_refs(ci, CEPH_CAP_FILE_WR); | 702 | ceph_get_cap_refs(ci, CEPH_CAP_FILE_WR); |
703 | } | 703 | } |
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 5d893d31e39..62377ec37ed 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c | |||
@@ -677,6 +677,7 @@ static int fill_inode(struct inode *inode, | |||
677 | if (ci->i_files == 0 && ci->i_subdirs == 0 && | 677 | if (ci->i_files == 0 && ci->i_subdirs == 0 && |
678 | ceph_snap(inode) == CEPH_NOSNAP && | 678 | ceph_snap(inode) == CEPH_NOSNAP && |
679 | (le32_to_cpu(info->cap.caps) & CEPH_CAP_FILE_SHARED) && | 679 | (le32_to_cpu(info->cap.caps) & CEPH_CAP_FILE_SHARED) && |
680 | (issued & CEPH_CAP_FILE_EXCL) == 0 && | ||
680 | (ci->i_ceph_flags & CEPH_I_COMPLETE) == 0) { | 681 | (ci->i_ceph_flags & CEPH_I_COMPLETE) == 0) { |
681 | dout(" marking %p complete (empty)\n", inode); | 682 | dout(" marking %p complete (empty)\n", inode); |
682 | ci->i_ceph_flags |= CEPH_I_COMPLETE; | 683 | ci->i_ceph_flags |= CEPH_I_COMPLETE; |
@@ -844,7 +845,7 @@ static void ceph_set_dentry_offset(struct dentry *dn) | |||
844 | * the caller) if we fail. | 845 | * the caller) if we fail. |
845 | */ | 846 | */ |
846 | static struct dentry *splice_dentry(struct dentry *dn, struct inode *in, | 847 | static struct dentry *splice_dentry(struct dentry *dn, struct inode *in, |
847 | bool *prehash) | 848 | bool *prehash, bool set_offset) |
848 | { | 849 | { |
849 | struct dentry *realdn; | 850 | struct dentry *realdn; |
850 | 851 | ||
@@ -876,7 +877,8 @@ static struct dentry *splice_dentry(struct dentry *dn, struct inode *in, | |||
876 | } | 877 | } |
877 | if ((!prehash || *prehash) && d_unhashed(dn)) | 878 | if ((!prehash || *prehash) && d_unhashed(dn)) |
878 | d_rehash(dn); | 879 | d_rehash(dn); |
879 | ceph_set_dentry_offset(dn); | 880 | if (set_offset) |
881 | ceph_set_dentry_offset(dn); | ||
880 | out: | 882 | out: |
881 | return dn; | 883 | return dn; |
882 | } | 884 | } |
@@ -1061,7 +1063,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, | |||
1061 | d_delete(dn); | 1063 | d_delete(dn); |
1062 | goto done; | 1064 | goto done; |
1063 | } | 1065 | } |
1064 | dn = splice_dentry(dn, in, &have_lease); | 1066 | dn = splice_dentry(dn, in, &have_lease, true); |
1065 | if (IS_ERR(dn)) { | 1067 | if (IS_ERR(dn)) { |
1066 | err = PTR_ERR(dn); | 1068 | err = PTR_ERR(dn); |
1067 | goto done; | 1069 | goto done; |
@@ -1104,7 +1106,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, | |||
1104 | goto done; | 1106 | goto done; |
1105 | } | 1107 | } |
1106 | dout(" linking snapped dir %p to dn %p\n", in, dn); | 1108 | dout(" linking snapped dir %p to dn %p\n", in, dn); |
1107 | dn = splice_dentry(dn, in, NULL); | 1109 | dn = splice_dentry(dn, in, NULL, true); |
1108 | if (IS_ERR(dn)) { | 1110 | if (IS_ERR(dn)) { |
1109 | err = PTR_ERR(dn); | 1111 | err = PTR_ERR(dn); |
1110 | goto done; | 1112 | goto done; |
@@ -1229,14 +1231,14 @@ retry_lookup: | |||
1229 | in = dn->d_inode; | 1231 | in = dn->d_inode; |
1230 | } else { | 1232 | } else { |
1231 | in = ceph_get_inode(parent->d_sb, vino); | 1233 | in = ceph_get_inode(parent->d_sb, vino); |
1232 | if (in == NULL) { | 1234 | if (IS_ERR(in)) { |
1233 | dout("new_inode badness\n"); | 1235 | dout("new_inode badness\n"); |
1234 | d_delete(dn); | 1236 | d_delete(dn); |
1235 | dput(dn); | 1237 | dput(dn); |
1236 | err = -ENOMEM; | 1238 | err = PTR_ERR(in); |
1237 | goto out; | 1239 | goto out; |
1238 | } | 1240 | } |
1239 | dn = splice_dentry(dn, in, NULL); | 1241 | dn = splice_dentry(dn, in, NULL, false); |
1240 | if (IS_ERR(dn)) | 1242 | if (IS_ERR(dn)) |
1241 | dn = NULL; | 1243 | dn = NULL; |
1242 | } | 1244 | } |
diff --git a/fs/ceph/locks.c b/fs/ceph/locks.c index ae85af06454..ff4e753aae9 100644 --- a/fs/ceph/locks.c +++ b/fs/ceph/locks.c | |||
@@ -82,7 +82,8 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl) | |||
82 | length = fl->fl_end - fl->fl_start + 1; | 82 | length = fl->fl_end - fl->fl_start + 1; |
83 | 83 | ||
84 | err = ceph_lock_message(CEPH_LOCK_FCNTL, op, file, | 84 | err = ceph_lock_message(CEPH_LOCK_FCNTL, op, file, |
85 | (u64)fl->fl_pid, (u64)fl->fl_nspid, | 85 | (u64)fl->fl_pid, |
86 | (u64)(unsigned long)fl->fl_nspid, | ||
86 | lock_cmd, fl->fl_start, | 87 | lock_cmd, fl->fl_start, |
87 | length, wait); | 88 | length, wait); |
88 | if (!err) { | 89 | if (!err) { |
@@ -92,7 +93,8 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl) | |||
92 | /* undo! This should only happen if the kernel detects | 93 | /* undo! This should only happen if the kernel detects |
93 | * local deadlock. */ | 94 | * local deadlock. */ |
94 | ceph_lock_message(CEPH_LOCK_FCNTL, op, file, | 95 | ceph_lock_message(CEPH_LOCK_FCNTL, op, file, |
95 | (u64)fl->fl_pid, (u64)fl->fl_nspid, | 96 | (u64)fl->fl_pid, |
97 | (u64)(unsigned long)fl->fl_nspid, | ||
96 | CEPH_LOCK_UNLOCK, fl->fl_start, | 98 | CEPH_LOCK_UNLOCK, fl->fl_start, |
97 | length, 0); | 99 | length, 0); |
98 | dout("got %d on posix_lock_file, undid lock", err); | 100 | dout("got %d on posix_lock_file, undid lock", err); |
@@ -132,7 +134,8 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl) | |||
132 | length = fl->fl_end - fl->fl_start + 1; | 134 | length = fl->fl_end - fl->fl_start + 1; |
133 | 135 | ||
134 | err = ceph_lock_message(CEPH_LOCK_FLOCK, CEPH_MDS_OP_SETFILELOCK, | 136 | err = ceph_lock_message(CEPH_LOCK_FLOCK, CEPH_MDS_OP_SETFILELOCK, |
135 | file, (u64)fl->fl_pid, (u64)fl->fl_nspid, | 137 | file, (u64)fl->fl_pid, |
138 | (u64)(unsigned long)fl->fl_nspid, | ||
136 | lock_cmd, fl->fl_start, | 139 | lock_cmd, fl->fl_start, |
137 | length, wait); | 140 | length, wait); |
138 | if (!err) { | 141 | if (!err) { |
@@ -141,7 +144,7 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl) | |||
141 | ceph_lock_message(CEPH_LOCK_FLOCK, | 144 | ceph_lock_message(CEPH_LOCK_FLOCK, |
142 | CEPH_MDS_OP_SETFILELOCK, | 145 | CEPH_MDS_OP_SETFILELOCK, |
143 | file, (u64)fl->fl_pid, | 146 | file, (u64)fl->fl_pid, |
144 | (u64)fl->fl_nspid, | 147 | (u64)(unsigned long)fl->fl_nspid, |
145 | CEPH_LOCK_UNLOCK, fl->fl_start, | 148 | CEPH_LOCK_UNLOCK, fl->fl_start, |
146 | length, 0); | 149 | length, 0); |
147 | dout("got %d on flock_lock_file_wait, undid lock", err); | 150 | dout("got %d on flock_lock_file_wait, undid lock", err); |
@@ -235,7 +238,8 @@ int lock_to_ceph_filelock(struct file_lock *lock, | |||
235 | cephlock->length = cpu_to_le64(lock->fl_end - lock->fl_start + 1); | 238 | cephlock->length = cpu_to_le64(lock->fl_end - lock->fl_start + 1); |
236 | cephlock->client = cpu_to_le64(0); | 239 | cephlock->client = cpu_to_le64(0); |
237 | cephlock->pid = cpu_to_le64(lock->fl_pid); | 240 | cephlock->pid = cpu_to_le64(lock->fl_pid); |
238 | cephlock->pid_namespace = cpu_to_le64((u64)lock->fl_nspid); | 241 | cephlock->pid_namespace = |
242 | cpu_to_le64((u64)(unsigned long)lock->fl_nspid); | ||
239 | 243 | ||
240 | switch (lock->fl_type) { | 244 | switch (lock->fl_type) { |
241 | case F_RDLCK: | 245 | case F_RDLCK: |
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index a75ddbf9fe3..fad95f8f260 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c | |||
@@ -560,6 +560,13 @@ static void __unregister_request(struct ceph_mds_client *mdsc, | |||
560 | * | 560 | * |
561 | * Called under mdsc->mutex. | 561 | * Called under mdsc->mutex. |
562 | */ | 562 | */ |
563 | struct dentry *get_nonsnap_parent(struct dentry *dentry) | ||
564 | { | ||
565 | while (!IS_ROOT(dentry) && ceph_snap(dentry->d_inode) != CEPH_NOSNAP) | ||
566 | dentry = dentry->d_parent; | ||
567 | return dentry; | ||
568 | } | ||
569 | |||
563 | static int __choose_mds(struct ceph_mds_client *mdsc, | 570 | static int __choose_mds(struct ceph_mds_client *mdsc, |
564 | struct ceph_mds_request *req) | 571 | struct ceph_mds_request *req) |
565 | { | 572 | { |
@@ -590,14 +597,29 @@ static int __choose_mds(struct ceph_mds_client *mdsc, | |||
590 | if (req->r_inode) { | 597 | if (req->r_inode) { |
591 | inode = req->r_inode; | 598 | inode = req->r_inode; |
592 | } else if (req->r_dentry) { | 599 | } else if (req->r_dentry) { |
593 | if (req->r_dentry->d_inode) { | 600 | struct inode *dir = req->r_dentry->d_parent->d_inode; |
601 | |||
602 | if (dir->i_sb != mdsc->client->sb) { | ||
603 | /* not this fs! */ | ||
604 | inode = req->r_dentry->d_inode; | ||
605 | } else if (ceph_snap(dir) != CEPH_NOSNAP) { | ||
606 | /* direct snapped/virtual snapdir requests | ||
607 | * based on parent dir inode */ | ||
608 | struct dentry *dn = | ||
609 | get_nonsnap_parent(req->r_dentry->d_parent); | ||
610 | inode = dn->d_inode; | ||
611 | dout("__choose_mds using nonsnap parent %p\n", inode); | ||
612 | } else if (req->r_dentry->d_inode) { | ||
613 | /* dentry target */ | ||
594 | inode = req->r_dentry->d_inode; | 614 | inode = req->r_dentry->d_inode; |
595 | } else { | 615 | } else { |
596 | inode = req->r_dentry->d_parent->d_inode; | 616 | /* dir + name */ |
617 | inode = dir; | ||
597 | hash = req->r_dentry->d_name.hash; | 618 | hash = req->r_dentry->d_name.hash; |
598 | is_hash = true; | 619 | is_hash = true; |
599 | } | 620 | } |
600 | } | 621 | } |
622 | |||
601 | dout("__choose_mds %p is_hash=%d (%d) mode %d\n", inode, (int)is_hash, | 623 | dout("__choose_mds %p is_hash=%d (%d) mode %d\n", inode, (int)is_hash, |
602 | (int)hash, mode); | 624 | (int)hash, mode); |
603 | if (!inode) | 625 | if (!inode) |
@@ -2208,7 +2230,7 @@ static void handle_session(struct ceph_mds_session *session, | |||
2208 | pr_info("mds%d reconnect denied\n", session->s_mds); | 2230 | pr_info("mds%d reconnect denied\n", session->s_mds); |
2209 | remove_session_caps(session); | 2231 | remove_session_caps(session); |
2210 | wake = 1; /* for good measure */ | 2232 | wake = 1; /* for good measure */ |
2211 | complete_all(&mdsc->session_close_waiters); | 2233 | wake_up_all(&mdsc->session_close_wq); |
2212 | kick_requests(mdsc, mds); | 2234 | kick_requests(mdsc, mds); |
2213 | break; | 2235 | break; |
2214 | 2236 | ||
@@ -2302,7 +2324,7 @@ static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap, | |||
2302 | path = ceph_mdsc_build_path(dentry, &pathlen, &pathbase, 0); | 2324 | path = ceph_mdsc_build_path(dentry, &pathlen, &pathbase, 0); |
2303 | if (IS_ERR(path)) { | 2325 | if (IS_ERR(path)) { |
2304 | err = PTR_ERR(path); | 2326 | err = PTR_ERR(path); |
2305 | BUG_ON(err); | 2327 | goto out_dput; |
2306 | } | 2328 | } |
2307 | } else { | 2329 | } else { |
2308 | path = NULL; | 2330 | path = NULL; |
@@ -2310,7 +2332,7 @@ static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap, | |||
2310 | } | 2332 | } |
2311 | err = ceph_pagelist_encode_string(pagelist, path, pathlen); | 2333 | err = ceph_pagelist_encode_string(pagelist, path, pathlen); |
2312 | if (err) | 2334 | if (err) |
2313 | goto out; | 2335 | goto out_free; |
2314 | 2336 | ||
2315 | spin_lock(&inode->i_lock); | 2337 | spin_lock(&inode->i_lock); |
2316 | cap->seq = 0; /* reset cap seq */ | 2338 | cap->seq = 0; /* reset cap seq */ |
@@ -2352,10 +2374,13 @@ static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap, | |||
2352 | num_fcntl_locks, | 2374 | num_fcntl_locks, |
2353 | num_flock_locks); | 2375 | num_flock_locks); |
2354 | unlock_kernel(); | 2376 | unlock_kernel(); |
2377 | } else { | ||
2378 | err = ceph_pagelist_append(pagelist, &rec, reclen); | ||
2355 | } | 2379 | } |
2356 | 2380 | ||
2357 | out: | 2381 | out_free: |
2358 | kfree(path); | 2382 | kfree(path); |
2383 | out_dput: | ||
2359 | dput(dentry); | 2384 | dput(dentry); |
2360 | return err; | 2385 | return err; |
2361 | } | 2386 | } |
@@ -2876,7 +2901,7 @@ int ceph_mdsc_init(struct ceph_mds_client *mdsc, struct ceph_client *client) | |||
2876 | return -ENOMEM; | 2901 | return -ENOMEM; |
2877 | 2902 | ||
2878 | init_completion(&mdsc->safe_umount_waiters); | 2903 | init_completion(&mdsc->safe_umount_waiters); |
2879 | init_completion(&mdsc->session_close_waiters); | 2904 | init_waitqueue_head(&mdsc->session_close_wq); |
2880 | INIT_LIST_HEAD(&mdsc->waiting_for_map); | 2905 | INIT_LIST_HEAD(&mdsc->waiting_for_map); |
2881 | mdsc->sessions = NULL; | 2906 | mdsc->sessions = NULL; |
2882 | mdsc->max_sessions = 0; | 2907 | mdsc->max_sessions = 0; |
@@ -3021,6 +3046,23 @@ void ceph_mdsc_sync(struct ceph_mds_client *mdsc) | |||
3021 | wait_event(mdsc->cap_flushing_wq, check_cap_flush(mdsc, want_flush)); | 3046 | wait_event(mdsc->cap_flushing_wq, check_cap_flush(mdsc, want_flush)); |
3022 | } | 3047 | } |
3023 | 3048 | ||
3049 | /* | ||
3050 | * true if all sessions are closed, or we force unmount | ||
3051 | */ | ||
3052 | bool done_closing_sessions(struct ceph_mds_client *mdsc) | ||
3053 | { | ||
3054 | int i, n = 0; | ||
3055 | |||
3056 | if (mdsc->client->mount_state == CEPH_MOUNT_SHUTDOWN) | ||
3057 | return true; | ||
3058 | |||
3059 | mutex_lock(&mdsc->mutex); | ||
3060 | for (i = 0; i < mdsc->max_sessions; i++) | ||
3061 | if (mdsc->sessions[i]) | ||
3062 | n++; | ||
3063 | mutex_unlock(&mdsc->mutex); | ||
3064 | return n == 0; | ||
3065 | } | ||
3024 | 3066 | ||
3025 | /* | 3067 | /* |
3026 | * called after sb is ro. | 3068 | * called after sb is ro. |
@@ -3029,45 +3071,32 @@ void ceph_mdsc_close_sessions(struct ceph_mds_client *mdsc) | |||
3029 | { | 3071 | { |
3030 | struct ceph_mds_session *session; | 3072 | struct ceph_mds_session *session; |
3031 | int i; | 3073 | int i; |
3032 | int n; | ||
3033 | struct ceph_client *client = mdsc->client; | 3074 | struct ceph_client *client = mdsc->client; |
3034 | unsigned long started, timeout = client->mount_args->mount_timeout * HZ; | 3075 | unsigned long timeout = client->mount_args->mount_timeout * HZ; |
3035 | 3076 | ||
3036 | dout("close_sessions\n"); | 3077 | dout("close_sessions\n"); |
3037 | 3078 | ||
3038 | mutex_lock(&mdsc->mutex); | ||
3039 | |||
3040 | /* close sessions */ | 3079 | /* close sessions */ |
3041 | started = jiffies; | 3080 | mutex_lock(&mdsc->mutex); |
3042 | while (time_before(jiffies, started + timeout)) { | 3081 | for (i = 0; i < mdsc->max_sessions; i++) { |
3043 | dout("closing sessions\n"); | 3082 | session = __ceph_lookup_mds_session(mdsc, i); |
3044 | n = 0; | 3083 | if (!session) |
3045 | for (i = 0; i < mdsc->max_sessions; i++) { | 3084 | continue; |
3046 | session = __ceph_lookup_mds_session(mdsc, i); | ||
3047 | if (!session) | ||
3048 | continue; | ||
3049 | mutex_unlock(&mdsc->mutex); | ||
3050 | mutex_lock(&session->s_mutex); | ||
3051 | __close_session(mdsc, session); | ||
3052 | mutex_unlock(&session->s_mutex); | ||
3053 | ceph_put_mds_session(session); | ||
3054 | mutex_lock(&mdsc->mutex); | ||
3055 | n++; | ||
3056 | } | ||
3057 | if (n == 0) | ||
3058 | break; | ||
3059 | |||
3060 | if (client->mount_state == CEPH_MOUNT_SHUTDOWN) | ||
3061 | break; | ||
3062 | |||
3063 | dout("waiting for sessions to close\n"); | ||
3064 | mutex_unlock(&mdsc->mutex); | 3085 | mutex_unlock(&mdsc->mutex); |
3065 | wait_for_completion_timeout(&mdsc->session_close_waiters, | 3086 | mutex_lock(&session->s_mutex); |
3066 | timeout); | 3087 | __close_session(mdsc, session); |
3088 | mutex_unlock(&session->s_mutex); | ||
3089 | ceph_put_mds_session(session); | ||
3067 | mutex_lock(&mdsc->mutex); | 3090 | mutex_lock(&mdsc->mutex); |
3068 | } | 3091 | } |
3092 | mutex_unlock(&mdsc->mutex); | ||
3093 | |||
3094 | dout("waiting for sessions to close\n"); | ||
3095 | wait_event_timeout(mdsc->session_close_wq, done_closing_sessions(mdsc), | ||
3096 | timeout); | ||
3069 | 3097 | ||
3070 | /* tear down remaining sessions */ | 3098 | /* tear down remaining sessions */ |
3099 | mutex_lock(&mdsc->mutex); | ||
3071 | for (i = 0; i < mdsc->max_sessions; i++) { | 3100 | for (i = 0; i < mdsc->max_sessions; i++) { |
3072 | if (mdsc->sessions[i]) { | 3101 | if (mdsc->sessions[i]) { |
3073 | session = get_session(mdsc->sessions[i]); | 3102 | session = get_session(mdsc->sessions[i]); |
@@ -3080,9 +3109,7 @@ void ceph_mdsc_close_sessions(struct ceph_mds_client *mdsc) | |||
3080 | mutex_lock(&mdsc->mutex); | 3109 | mutex_lock(&mdsc->mutex); |
3081 | } | 3110 | } |
3082 | } | 3111 | } |
3083 | |||
3084 | WARN_ON(!list_empty(&mdsc->cap_delay_list)); | 3112 | WARN_ON(!list_empty(&mdsc->cap_delay_list)); |
3085 | |||
3086 | mutex_unlock(&mdsc->mutex); | 3113 | mutex_unlock(&mdsc->mutex); |
3087 | 3114 | ||
3088 | ceph_cleanup_empty_realms(mdsc); | 3115 | ceph_cleanup_empty_realms(mdsc); |
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index ab7e89f5e34..c98267ce6d2 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h | |||
@@ -234,7 +234,8 @@ struct ceph_mds_client { | |||
234 | struct mutex mutex; /* all nested structures */ | 234 | struct mutex mutex; /* all nested structures */ |
235 | 235 | ||
236 | struct ceph_mdsmap *mdsmap; | 236 | struct ceph_mdsmap *mdsmap; |
237 | struct completion safe_umount_waiters, session_close_waiters; | 237 | struct completion safe_umount_waiters; |
238 | wait_queue_head_t session_close_wq; | ||
238 | struct list_head waiting_for_map; | 239 | struct list_head waiting_for_map; |
239 | 240 | ||
240 | struct ceph_mds_session **sessions; /* NULL for mds if no session */ | 241 | struct ceph_mds_session **sessions; /* NULL for mds if no session */ |
diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index bed6391e52c..3b5571b8ce2 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c | |||
@@ -549,7 +549,7 @@ static void __unregister_request(struct ceph_osd_client *osdc, | |||
549 | */ | 549 | */ |
550 | static void __cancel_request(struct ceph_osd_request *req) | 550 | static void __cancel_request(struct ceph_osd_request *req) |
551 | { | 551 | { |
552 | if (req->r_sent) { | 552 | if (req->r_sent && req->r_osd) { |
553 | ceph_con_revoke(&req->r_osd->o_con, req->r_request); | 553 | ceph_con_revoke(&req->r_osd->o_con, req->r_request); |
554 | req->r_sent = 0; | 554 | req->r_sent = 0; |
555 | } | 555 | } |
@@ -661,7 +661,7 @@ static int __send_request(struct ceph_osd_client *osdc, | |||
661 | reqhead->reassert_version = req->r_reassert_version; | 661 | reqhead->reassert_version = req->r_reassert_version; |
662 | 662 | ||
663 | req->r_stamp = jiffies; | 663 | req->r_stamp = jiffies; |
664 | list_move_tail(&osdc->req_lru, &req->r_req_lru_item); | 664 | list_move_tail(&req->r_req_lru_item, &osdc->req_lru); |
665 | 665 | ||
666 | ceph_msg_get(req->r_request); /* send consumes a ref */ | 666 | ceph_msg_get(req->r_request); /* send consumes a ref */ |
667 | ceph_con_send(&req->r_osd->o_con, req->r_request); | 667 | ceph_con_send(&req->r_osd->o_con, req->r_request); |
diff --git a/fs/ceph/pagelist.c b/fs/ceph/pagelist.c index b6859f47d36..46a368b6dce 100644 --- a/fs/ceph/pagelist.c +++ b/fs/ceph/pagelist.c | |||
@@ -5,10 +5,18 @@ | |||
5 | 5 | ||
6 | #include "pagelist.h" | 6 | #include "pagelist.h" |
7 | 7 | ||
8 | static void ceph_pagelist_unmap_tail(struct ceph_pagelist *pl) | ||
9 | { | ||
10 | struct page *page = list_entry(pl->head.prev, struct page, | ||
11 | lru); | ||
12 | kunmap(page); | ||
13 | } | ||
14 | |||
8 | int ceph_pagelist_release(struct ceph_pagelist *pl) | 15 | int ceph_pagelist_release(struct ceph_pagelist *pl) |
9 | { | 16 | { |
10 | if (pl->mapped_tail) | 17 | if (pl->mapped_tail) |
11 | kunmap(pl->mapped_tail); | 18 | ceph_pagelist_unmap_tail(pl); |
19 | |||
12 | while (!list_empty(&pl->head)) { | 20 | while (!list_empty(&pl->head)) { |
13 | struct page *page = list_first_entry(&pl->head, struct page, | 21 | struct page *page = list_first_entry(&pl->head, struct page, |
14 | lru); | 22 | lru); |
@@ -26,7 +34,7 @@ static int ceph_pagelist_addpage(struct ceph_pagelist *pl) | |||
26 | pl->room += PAGE_SIZE; | 34 | pl->room += PAGE_SIZE; |
27 | list_add_tail(&page->lru, &pl->head); | 35 | list_add_tail(&page->lru, &pl->head); |
28 | if (pl->mapped_tail) | 36 | if (pl->mapped_tail) |
29 | kunmap(pl->mapped_tail); | 37 | ceph_pagelist_unmap_tail(pl); |
30 | pl->mapped_tail = kmap(page); | 38 | pl->mapped_tail = kmap(page); |
31 | return 0; | 39 | return 0; |
32 | } | 40 | } |
diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c index c0b26b6badb..190b6c4a6f2 100644 --- a/fs/ceph/snap.c +++ b/fs/ceph/snap.c | |||
@@ -119,6 +119,7 @@ static struct ceph_snap_realm *ceph_create_snap_realm( | |||
119 | INIT_LIST_HEAD(&realm->children); | 119 | INIT_LIST_HEAD(&realm->children); |
120 | INIT_LIST_HEAD(&realm->child_item); | 120 | INIT_LIST_HEAD(&realm->child_item); |
121 | INIT_LIST_HEAD(&realm->empty_item); | 121 | INIT_LIST_HEAD(&realm->empty_item); |
122 | INIT_LIST_HEAD(&realm->dirty_item); | ||
122 | INIT_LIST_HEAD(&realm->inodes_with_caps); | 123 | INIT_LIST_HEAD(&realm->inodes_with_caps); |
123 | spin_lock_init(&realm->inodes_with_caps_lock); | 124 | spin_lock_init(&realm->inodes_with_caps_lock); |
124 | __insert_snap_realm(&mdsc->snap_realms, realm); | 125 | __insert_snap_realm(&mdsc->snap_realms, realm); |
@@ -435,7 +436,7 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci) | |||
435 | { | 436 | { |
436 | struct inode *inode = &ci->vfs_inode; | 437 | struct inode *inode = &ci->vfs_inode; |
437 | struct ceph_cap_snap *capsnap; | 438 | struct ceph_cap_snap *capsnap; |
438 | int used; | 439 | int used, dirty; |
439 | 440 | ||
440 | capsnap = kzalloc(sizeof(*capsnap), GFP_NOFS); | 441 | capsnap = kzalloc(sizeof(*capsnap), GFP_NOFS); |
441 | if (!capsnap) { | 442 | if (!capsnap) { |
@@ -445,6 +446,7 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci) | |||
445 | 446 | ||
446 | spin_lock(&inode->i_lock); | 447 | spin_lock(&inode->i_lock); |
447 | used = __ceph_caps_used(ci); | 448 | used = __ceph_caps_used(ci); |
449 | dirty = __ceph_caps_dirty(ci); | ||
448 | if (__ceph_have_pending_cap_snap(ci)) { | 450 | if (__ceph_have_pending_cap_snap(ci)) { |
449 | /* there is no point in queuing multiple "pending" cap_snaps, | 451 | /* there is no point in queuing multiple "pending" cap_snaps, |
450 | as no new writes are allowed to start when pending, so any | 452 | as no new writes are allowed to start when pending, so any |
@@ -452,27 +454,37 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci) | |||
452 | cap_snap. lucky us. */ | 454 | cap_snap. lucky us. */ |
453 | dout("queue_cap_snap %p already pending\n", inode); | 455 | dout("queue_cap_snap %p already pending\n", inode); |
454 | kfree(capsnap); | 456 | kfree(capsnap); |
455 | } else if (ci->i_wrbuffer_ref_head || (used & CEPH_CAP_FILE_WR)) { | 457 | } else if (ci->i_wrbuffer_ref_head || (used & CEPH_CAP_FILE_WR) || |
458 | (dirty & (CEPH_CAP_AUTH_EXCL|CEPH_CAP_XATTR_EXCL| | ||
459 | CEPH_CAP_FILE_EXCL|CEPH_CAP_FILE_WR))) { | ||
456 | struct ceph_snap_context *snapc = ci->i_head_snapc; | 460 | struct ceph_snap_context *snapc = ci->i_head_snapc; |
457 | 461 | ||
462 | dout("queue_cap_snap %p cap_snap %p queuing under %p\n", inode, | ||
463 | capsnap, snapc); | ||
458 | igrab(inode); | 464 | igrab(inode); |
459 | 465 | ||
460 | atomic_set(&capsnap->nref, 1); | 466 | atomic_set(&capsnap->nref, 1); |
461 | capsnap->ci = ci; | 467 | capsnap->ci = ci; |
462 | INIT_LIST_HEAD(&capsnap->ci_item); | 468 | INIT_LIST_HEAD(&capsnap->ci_item); |
463 | INIT_LIST_HEAD(&capsnap->flushing_item); | 469 | INIT_LIST_HEAD(&capsnap->flushing_item); |
464 | 470 | ||
465 | capsnap->follows = snapc->seq - 1; | 471 | capsnap->follows = snapc->seq; |
466 | capsnap->issued = __ceph_caps_issued(ci, NULL); | 472 | capsnap->issued = __ceph_caps_issued(ci, NULL); |
467 | capsnap->dirty = __ceph_caps_dirty(ci); | 473 | capsnap->dirty = dirty; |
468 | 474 | ||
469 | capsnap->mode = inode->i_mode; | 475 | capsnap->mode = inode->i_mode; |
470 | capsnap->uid = inode->i_uid; | 476 | capsnap->uid = inode->i_uid; |
471 | capsnap->gid = inode->i_gid; | 477 | capsnap->gid = inode->i_gid; |
472 | 478 | ||
473 | /* fixme? */ | 479 | if (dirty & CEPH_CAP_XATTR_EXCL) { |
474 | capsnap->xattr_blob = NULL; | 480 | __ceph_build_xattrs_blob(ci); |
475 | capsnap->xattr_len = 0; | 481 | capsnap->xattr_blob = |
482 | ceph_buffer_get(ci->i_xattrs.blob); | ||
483 | capsnap->xattr_version = ci->i_xattrs.version; | ||
484 | } else { | ||
485 | capsnap->xattr_blob = NULL; | ||
486 | capsnap->xattr_version = 0; | ||
487 | } | ||
476 | 488 | ||
477 | /* dirty page count moved from _head to this cap_snap; | 489 | /* dirty page count moved from _head to this cap_snap; |
478 | all subsequent writes page dirties occur _after_ this | 490 | all subsequent writes page dirties occur _after_ this |
@@ -480,7 +492,9 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci) | |||
480 | capsnap->dirty_pages = ci->i_wrbuffer_ref_head; | 492 | capsnap->dirty_pages = ci->i_wrbuffer_ref_head; |
481 | ci->i_wrbuffer_ref_head = 0; | 493 | ci->i_wrbuffer_ref_head = 0; |
482 | capsnap->context = snapc; | 494 | capsnap->context = snapc; |
483 | ci->i_head_snapc = NULL; | 495 | ci->i_head_snapc = |
496 | ceph_get_snap_context(ci->i_snap_realm->cached_context); | ||
497 | dout(" new snapc is %p\n", ci->i_head_snapc); | ||
484 | list_add_tail(&capsnap->ci_item, &ci->i_cap_snaps); | 498 | list_add_tail(&capsnap->ci_item, &ci->i_cap_snaps); |
485 | 499 | ||
486 | if (used & CEPH_CAP_FILE_WR) { | 500 | if (used & CEPH_CAP_FILE_WR) { |
@@ -539,6 +553,41 @@ int __ceph_finish_cap_snap(struct ceph_inode_info *ci, | |||
539 | return 1; /* caller may want to ceph_flush_snaps */ | 553 | return 1; /* caller may want to ceph_flush_snaps */ |
540 | } | 554 | } |
541 | 555 | ||
556 | /* | ||
557 | * Queue cap_snaps for snap writeback for this realm and its children. | ||
558 | * Called under snap_rwsem, so realm topology won't change. | ||
559 | */ | ||
560 | static void queue_realm_cap_snaps(struct ceph_snap_realm *realm) | ||
561 | { | ||
562 | struct ceph_inode_info *ci; | ||
563 | struct inode *lastinode = NULL; | ||
564 | struct ceph_snap_realm *child; | ||
565 | |||
566 | dout("queue_realm_cap_snaps %p %llx inodes\n", realm, realm->ino); | ||
567 | |||
568 | spin_lock(&realm->inodes_with_caps_lock); | ||
569 | list_for_each_entry(ci, &realm->inodes_with_caps, | ||
570 | i_snap_realm_item) { | ||
571 | struct inode *inode = igrab(&ci->vfs_inode); | ||
572 | if (!inode) | ||
573 | continue; | ||
574 | spin_unlock(&realm->inodes_with_caps_lock); | ||
575 | if (lastinode) | ||
576 | iput(lastinode); | ||
577 | lastinode = inode; | ||
578 | ceph_queue_cap_snap(ci); | ||
579 | spin_lock(&realm->inodes_with_caps_lock); | ||
580 | } | ||
581 | spin_unlock(&realm->inodes_with_caps_lock); | ||
582 | if (lastinode) | ||
583 | iput(lastinode); | ||
584 | |||
585 | dout("queue_realm_cap_snaps %p %llx children\n", realm, realm->ino); | ||
586 | list_for_each_entry(child, &realm->children, child_item) | ||
587 | queue_realm_cap_snaps(child); | ||
588 | |||
589 | dout("queue_realm_cap_snaps %p %llx done\n", realm, realm->ino); | ||
590 | } | ||
542 | 591 | ||
543 | /* | 592 | /* |
544 | * Parse and apply a snapblob "snap trace" from the MDS. This specifies | 593 | * Parse and apply a snapblob "snap trace" from the MDS. This specifies |
@@ -556,6 +605,7 @@ int ceph_update_snap_trace(struct ceph_mds_client *mdsc, | |||
556 | struct ceph_snap_realm *realm; | 605 | struct ceph_snap_realm *realm; |
557 | int invalidate = 0; | 606 | int invalidate = 0; |
558 | int err = -ENOMEM; | 607 | int err = -ENOMEM; |
608 | LIST_HEAD(dirty_realms); | ||
559 | 609 | ||
560 | dout("update_snap_trace deletion=%d\n", deletion); | 610 | dout("update_snap_trace deletion=%d\n", deletion); |
561 | more: | 611 | more: |
@@ -578,45 +628,6 @@ more: | |||
578 | } | 628 | } |
579 | } | 629 | } |
580 | 630 | ||
581 | if (le64_to_cpu(ri->seq) > realm->seq) { | ||
582 | dout("update_snap_trace updating %llx %p %lld -> %lld\n", | ||
583 | realm->ino, realm, realm->seq, le64_to_cpu(ri->seq)); | ||
584 | /* | ||
585 | * if the realm seq has changed, queue a cap_snap for every | ||
586 | * inode with open caps. we do this _before_ we update | ||
587 | * the realm info so that we prepare for writeback under the | ||
588 | * _previous_ snap context. | ||
589 | * | ||
590 | * ...unless it's a snap deletion! | ||
591 | */ | ||
592 | if (!deletion) { | ||
593 | struct ceph_inode_info *ci; | ||
594 | struct inode *lastinode = NULL; | ||
595 | |||
596 | spin_lock(&realm->inodes_with_caps_lock); | ||
597 | list_for_each_entry(ci, &realm->inodes_with_caps, | ||
598 | i_snap_realm_item) { | ||
599 | struct inode *inode = igrab(&ci->vfs_inode); | ||
600 | if (!inode) | ||
601 | continue; | ||
602 | spin_unlock(&realm->inodes_with_caps_lock); | ||
603 | if (lastinode) | ||
604 | iput(lastinode); | ||
605 | lastinode = inode; | ||
606 | ceph_queue_cap_snap(ci); | ||
607 | spin_lock(&realm->inodes_with_caps_lock); | ||
608 | } | ||
609 | spin_unlock(&realm->inodes_with_caps_lock); | ||
610 | if (lastinode) | ||
611 | iput(lastinode); | ||
612 | dout("update_snap_trace cap_snaps queued\n"); | ||
613 | } | ||
614 | |||
615 | } else { | ||
616 | dout("update_snap_trace %llx %p seq %lld unchanged\n", | ||
617 | realm->ino, realm, realm->seq); | ||
618 | } | ||
619 | |||
620 | /* ensure the parent is correct */ | 631 | /* ensure the parent is correct */ |
621 | err = adjust_snap_realm_parent(mdsc, realm, le64_to_cpu(ri->parent)); | 632 | err = adjust_snap_realm_parent(mdsc, realm, le64_to_cpu(ri->parent)); |
622 | if (err < 0) | 633 | if (err < 0) |
@@ -624,6 +635,8 @@ more: | |||
624 | invalidate += err; | 635 | invalidate += err; |
625 | 636 | ||
626 | if (le64_to_cpu(ri->seq) > realm->seq) { | 637 | if (le64_to_cpu(ri->seq) > realm->seq) { |
638 | dout("update_snap_trace updating %llx %p %lld -> %lld\n", | ||
639 | realm->ino, realm, realm->seq, le64_to_cpu(ri->seq)); | ||
627 | /* update realm parameters, snap lists */ | 640 | /* update realm parameters, snap lists */ |
628 | realm->seq = le64_to_cpu(ri->seq); | 641 | realm->seq = le64_to_cpu(ri->seq); |
629 | realm->created = le64_to_cpu(ri->created); | 642 | realm->created = le64_to_cpu(ri->created); |
@@ -641,9 +654,17 @@ more: | |||
641 | if (err < 0) | 654 | if (err < 0) |
642 | goto fail; | 655 | goto fail; |
643 | 656 | ||
657 | /* queue realm for cap_snap creation */ | ||
658 | list_add(&realm->dirty_item, &dirty_realms); | ||
659 | |||
644 | invalidate = 1; | 660 | invalidate = 1; |
645 | } else if (!realm->cached_context) { | 661 | } else if (!realm->cached_context) { |
662 | dout("update_snap_trace %llx %p seq %lld new\n", | ||
663 | realm->ino, realm, realm->seq); | ||
646 | invalidate = 1; | 664 | invalidate = 1; |
665 | } else { | ||
666 | dout("update_snap_trace %llx %p seq %lld unchanged\n", | ||
667 | realm->ino, realm, realm->seq); | ||
647 | } | 668 | } |
648 | 669 | ||
649 | dout("done with %llx %p, invalidated=%d, %p %p\n", realm->ino, | 670 | dout("done with %llx %p, invalidated=%d, %p %p\n", realm->ino, |
@@ -656,6 +677,14 @@ more: | |||
656 | if (invalidate) | 677 | if (invalidate) |
657 | rebuild_snap_realms(realm); | 678 | rebuild_snap_realms(realm); |
658 | 679 | ||
680 | /* | ||
681 | * queue cap snaps _after_ we've built the new snap contexts, | ||
682 | * so that i_head_snapc can be set appropriately. | ||
683 | */ | ||
684 | list_for_each_entry(realm, &dirty_realms, dirty_item) { | ||
685 | queue_realm_cap_snaps(realm); | ||
686 | } | ||
687 | |||
659 | __cleanup_empty_realms(mdsc); | 688 | __cleanup_empty_realms(mdsc); |
660 | return 0; | 689 | return 0; |
661 | 690 | ||
@@ -688,7 +717,7 @@ static void flush_snaps(struct ceph_mds_client *mdsc) | |||
688 | igrab(inode); | 717 | igrab(inode); |
689 | spin_unlock(&mdsc->snap_flush_lock); | 718 | spin_unlock(&mdsc->snap_flush_lock); |
690 | spin_lock(&inode->i_lock); | 719 | spin_lock(&inode->i_lock); |
691 | __ceph_flush_snaps(ci, &session); | 720 | __ceph_flush_snaps(ci, &session, 0); |
692 | spin_unlock(&inode->i_lock); | 721 | spin_unlock(&inode->i_lock); |
693 | iput(inode); | 722 | iput(inode); |
694 | spin_lock(&mdsc->snap_flush_lock); | 723 | spin_lock(&mdsc->snap_flush_lock); |
@@ -789,6 +818,7 @@ void ceph_handle_snap(struct ceph_mds_client *mdsc, | |||
789 | }; | 818 | }; |
790 | struct inode *inode = ceph_find_inode(sb, vino); | 819 | struct inode *inode = ceph_find_inode(sb, vino); |
791 | struct ceph_inode_info *ci; | 820 | struct ceph_inode_info *ci; |
821 | struct ceph_snap_realm *oldrealm; | ||
792 | 822 | ||
793 | if (!inode) | 823 | if (!inode) |
794 | continue; | 824 | continue; |
@@ -814,18 +844,19 @@ void ceph_handle_snap(struct ceph_mds_client *mdsc, | |||
814 | dout(" will move %p to split realm %llx %p\n", | 844 | dout(" will move %p to split realm %llx %p\n", |
815 | inode, realm->ino, realm); | 845 | inode, realm->ino, realm); |
816 | /* | 846 | /* |
817 | * Remove the inode from the realm's inode | 847 | * Move the inode to the new realm |
818 | * list, but don't add it to the new realm | ||
819 | * yet. We don't want the cap_snap to be | ||
820 | * queued (again) by ceph_update_snap_trace() | ||
821 | * below. Queue it _now_, under the old context. | ||
822 | */ | 848 | */ |
823 | spin_lock(&realm->inodes_with_caps_lock); | 849 | spin_lock(&realm->inodes_with_caps_lock); |
824 | list_del_init(&ci->i_snap_realm_item); | 850 | list_del_init(&ci->i_snap_realm_item); |
851 | list_add(&ci->i_snap_realm_item, | ||
852 | &realm->inodes_with_caps); | ||
853 | oldrealm = ci->i_snap_realm; | ||
854 | ci->i_snap_realm = realm; | ||
825 | spin_unlock(&realm->inodes_with_caps_lock); | 855 | spin_unlock(&realm->inodes_with_caps_lock); |
826 | spin_unlock(&inode->i_lock); | 856 | spin_unlock(&inode->i_lock); |
827 | 857 | ||
828 | ceph_queue_cap_snap(ci); | 858 | ceph_get_snap_realm(mdsc, realm); |
859 | ceph_put_snap_realm(mdsc, oldrealm); | ||
829 | 860 | ||
830 | iput(inode); | 861 | iput(inode); |
831 | continue; | 862 | continue; |
@@ -853,43 +884,9 @@ skip_inode: | |||
853 | ceph_update_snap_trace(mdsc, p, e, | 884 | ceph_update_snap_trace(mdsc, p, e, |
854 | op == CEPH_SNAP_OP_DESTROY); | 885 | op == CEPH_SNAP_OP_DESTROY); |
855 | 886 | ||
856 | if (op == CEPH_SNAP_OP_SPLIT) { | 887 | if (op == CEPH_SNAP_OP_SPLIT) |
857 | /* | ||
858 | * ok, _now_ add the inodes into the new realm. | ||
859 | */ | ||
860 | for (i = 0; i < num_split_inos; i++) { | ||
861 | struct ceph_vino vino = { | ||
862 | .ino = le64_to_cpu(split_inos[i]), | ||
863 | .snap = CEPH_NOSNAP, | ||
864 | }; | ||
865 | struct inode *inode = ceph_find_inode(sb, vino); | ||
866 | struct ceph_inode_info *ci; | ||
867 | |||
868 | if (!inode) | ||
869 | continue; | ||
870 | ci = ceph_inode(inode); | ||
871 | spin_lock(&inode->i_lock); | ||
872 | if (list_empty(&ci->i_snap_realm_item)) { | ||
873 | struct ceph_snap_realm *oldrealm = | ||
874 | ci->i_snap_realm; | ||
875 | |||
876 | dout(" moving %p to split realm %llx %p\n", | ||
877 | inode, realm->ino, realm); | ||
878 | spin_lock(&realm->inodes_with_caps_lock); | ||
879 | list_add(&ci->i_snap_realm_item, | ||
880 | &realm->inodes_with_caps); | ||
881 | ci->i_snap_realm = realm; | ||
882 | spin_unlock(&realm->inodes_with_caps_lock); | ||
883 | ceph_get_snap_realm(mdsc, realm); | ||
884 | ceph_put_snap_realm(mdsc, oldrealm); | ||
885 | } | ||
886 | spin_unlock(&inode->i_lock); | ||
887 | iput(inode); | ||
888 | } | ||
889 | |||
890 | /* we took a reference when we created the realm, above */ | 888 | /* we took a reference when we created the realm, above */ |
891 | ceph_put_snap_realm(mdsc, realm); | 889 | ceph_put_snap_realm(mdsc, realm); |
892 | } | ||
893 | 890 | ||
894 | __cleanup_empty_realms(mdsc); | 891 | __cleanup_empty_realms(mdsc); |
895 | 892 | ||
diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 2482d696f0d..b87638e84c4 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h | |||
@@ -216,8 +216,7 @@ struct ceph_cap_snap { | |||
216 | uid_t uid; | 216 | uid_t uid; |
217 | gid_t gid; | 217 | gid_t gid; |
218 | 218 | ||
219 | void *xattr_blob; | 219 | struct ceph_buffer *xattr_blob; |
220 | int xattr_len; | ||
221 | u64 xattr_version; | 220 | u64 xattr_version; |
222 | 221 | ||
223 | u64 size; | 222 | u64 size; |
@@ -229,8 +228,11 @@ struct ceph_cap_snap { | |||
229 | 228 | ||
230 | static inline void ceph_put_cap_snap(struct ceph_cap_snap *capsnap) | 229 | static inline void ceph_put_cap_snap(struct ceph_cap_snap *capsnap) |
231 | { | 230 | { |
232 | if (atomic_dec_and_test(&capsnap->nref)) | 231 | if (atomic_dec_and_test(&capsnap->nref)) { |
232 | if (capsnap->xattr_blob) | ||
233 | ceph_buffer_put(capsnap->xattr_blob); | ||
233 | kfree(capsnap); | 234 | kfree(capsnap); |
235 | } | ||
234 | } | 236 | } |
235 | 237 | ||
236 | /* | 238 | /* |
@@ -342,7 +344,8 @@ struct ceph_inode_info { | |||
342 | unsigned i_cap_exporting_issued; | 344 | unsigned i_cap_exporting_issued; |
343 | struct ceph_cap_reservation i_cap_migration_resv; | 345 | struct ceph_cap_reservation i_cap_migration_resv; |
344 | struct list_head i_cap_snaps; /* snapped state pending flush to mds */ | 346 | struct list_head i_cap_snaps; /* snapped state pending flush to mds */ |
345 | struct ceph_snap_context *i_head_snapc; /* set if wr_buffer_head > 0 */ | 347 | struct ceph_snap_context *i_head_snapc; /* set if wr_buffer_head > 0 or |
348 | dirty|flushing caps */ | ||
346 | unsigned i_snap_caps; /* cap bits for snapped files */ | 349 | unsigned i_snap_caps; /* cap bits for snapped files */ |
347 | 350 | ||
348 | int i_nr_by_mode[CEPH_FILE_MODE_NUM]; /* open file counts */ | 351 | int i_nr_by_mode[CEPH_FILE_MODE_NUM]; /* open file counts */ |
@@ -687,6 +690,8 @@ struct ceph_snap_realm { | |||
687 | 690 | ||
688 | struct list_head empty_item; /* if i have ref==0 */ | 691 | struct list_head empty_item; /* if i have ref==0 */ |
689 | 692 | ||
693 | struct list_head dirty_item; /* if realm needs new context */ | ||
694 | |||
690 | /* the current set of snaps for this realm */ | 695 | /* the current set of snaps for this realm */ |
691 | struct ceph_snap_context *cached_context; | 696 | struct ceph_snap_context *cached_context; |
692 | 697 | ||
@@ -823,7 +828,8 @@ extern void ceph_put_cap_refs(struct ceph_inode_info *ci, int had); | |||
823 | extern void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr, | 828 | extern void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr, |
824 | struct ceph_snap_context *snapc); | 829 | struct ceph_snap_context *snapc); |
825 | extern void __ceph_flush_snaps(struct ceph_inode_info *ci, | 830 | extern void __ceph_flush_snaps(struct ceph_inode_info *ci, |
826 | struct ceph_mds_session **psession); | 831 | struct ceph_mds_session **psession, |
832 | int again); | ||
827 | extern void ceph_check_caps(struct ceph_inode_info *ci, int flags, | 833 | extern void ceph_check_caps(struct ceph_inode_info *ci, int flags, |
828 | struct ceph_mds_session *session); | 834 | struct ceph_mds_session *session); |
829 | extern void ceph_check_delayed_caps(struct ceph_mds_client *mdsc); | 835 | extern void ceph_check_delayed_caps(struct ceph_mds_client *mdsc); |
diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index 097a2654c00..9578af610b7 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c | |||
@@ -485,6 +485,7 @@ void __ceph_build_xattrs_blob(struct ceph_inode_info *ci) | |||
485 | ci->i_xattrs.blob = ci->i_xattrs.prealloc_blob; | 485 | ci->i_xattrs.blob = ci->i_xattrs.prealloc_blob; |
486 | ci->i_xattrs.prealloc_blob = NULL; | 486 | ci->i_xattrs.prealloc_blob = NULL; |
487 | ci->i_xattrs.dirty = false; | 487 | ci->i_xattrs.dirty = false; |
488 | ci->i_xattrs.version++; | ||
488 | } | 489 | } |
489 | } | 490 | } |
490 | 491 | ||
diff --git a/fs/char_dev.c b/fs/char_dev.c index f80a4f25123..143d393881c 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c | |||
@@ -40,7 +40,9 @@ struct backing_dev_info directly_mappable_cdev_bdi = { | |||
40 | #endif | 40 | #endif |
41 | /* permit direct mmap, for read, write or exec */ | 41 | /* permit direct mmap, for read, write or exec */ |
42 | BDI_CAP_MAP_DIRECT | | 42 | BDI_CAP_MAP_DIRECT | |
43 | BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP), | 43 | BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP | |
44 | /* no writeback happens */ | ||
45 | BDI_CAP_NO_ACCT_AND_WRITEBACK), | ||
44 | }; | 46 | }; |
45 | 47 | ||
46 | static struct kobj_map *cdev_map; | 48 | static struct kobj_map *cdev_map; |
diff --git a/fs/cifs/cifs_unicode.h b/fs/cifs/cifs_unicode.h index 650638275a6..7fe6b52df50 100644 --- a/fs/cifs/cifs_unicode.h +++ b/fs/cifs/cifs_unicode.h | |||
@@ -30,6 +30,8 @@ | |||
30 | * This is a compressed table of upper and lower case conversion. | 30 | * This is a compressed table of upper and lower case conversion. |
31 | * | 31 | * |
32 | */ | 32 | */ |
33 | #ifndef _CIFS_UNICODE_H | ||
34 | #define _CIFS_UNICODE_H | ||
33 | 35 | ||
34 | #include <asm/byteorder.h> | 36 | #include <asm/byteorder.h> |
35 | #include <linux/types.h> | 37 | #include <linux/types.h> |
@@ -67,8 +69,8 @@ extern const struct UniCaseRange CifsUniUpperRange[]; | |||
67 | #endif /* UNIUPR_NOUPPER */ | 69 | #endif /* UNIUPR_NOUPPER */ |
68 | 70 | ||
69 | #ifndef UNIUPR_NOLOWER | 71 | #ifndef UNIUPR_NOLOWER |
70 | extern signed char UniLowerTable[512]; | 72 | extern signed char CifsUniLowerTable[512]; |
71 | extern struct UniCaseRange UniLowerRange[]; | 73 | extern const struct UniCaseRange CifsUniLowerRange[]; |
72 | #endif /* UNIUPR_NOLOWER */ | 74 | #endif /* UNIUPR_NOLOWER */ |
73 | 75 | ||
74 | #ifdef __KERNEL__ | 76 | #ifdef __KERNEL__ |
@@ -337,15 +339,15 @@ UniStrupr(register wchar_t *upin) | |||
337 | * UniTolower: Convert a unicode character to lower case | 339 | * UniTolower: Convert a unicode character to lower case |
338 | */ | 340 | */ |
339 | static inline wchar_t | 341 | static inline wchar_t |
340 | UniTolower(wchar_t uc) | 342 | UniTolower(register wchar_t uc) |
341 | { | 343 | { |
342 | register struct UniCaseRange *rp; | 344 | register const struct UniCaseRange *rp; |
343 | 345 | ||
344 | if (uc < sizeof(UniLowerTable)) { | 346 | if (uc < sizeof(CifsUniLowerTable)) { |
345 | /* Latin characters */ | 347 | /* Latin characters */ |
346 | return uc + UniLowerTable[uc]; /* Use base tables */ | 348 | return uc + CifsUniLowerTable[uc]; /* Use base tables */ |
347 | } else { | 349 | } else { |
348 | rp = UniLowerRange; /* Use range tables */ | 350 | rp = CifsUniLowerRange; /* Use range tables */ |
349 | while (rp->start) { | 351 | while (rp->start) { |
350 | if (uc < rp->start) /* Before start of range */ | 352 | if (uc < rp->start) /* Before start of range */ |
351 | return uc; /* Uppercase = input */ | 353 | return uc; /* Uppercase = input */ |
@@ -374,3 +376,5 @@ UniStrlwr(register wchar_t *upin) | |||
374 | } | 376 | } |
375 | 377 | ||
376 | #endif | 378 | #endif |
379 | |||
380 | #endif /* _CIFS_UNICODE_H */ | ||
diff --git a/fs/cifs/cifs_uniupr.h b/fs/cifs/cifs_uniupr.h index 18a9d978e51..0ac7c5a8633 100644 --- a/fs/cifs/cifs_uniupr.h +++ b/fs/cifs/cifs_uniupr.h | |||
@@ -140,7 +140,7 @@ const struct UniCaseRange CifsUniUpperRange[] = { | |||
140 | /* | 140 | /* |
141 | * Latin lower case | 141 | * Latin lower case |
142 | */ | 142 | */ |
143 | static signed char CifsUniLowerTable[512] = { | 143 | signed char CifsUniLowerTable[512] = { |
144 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 000-00f */ | 144 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 000-00f */ |
145 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 010-01f */ | 145 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 010-01f */ |
146 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 020-02f */ | 146 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 020-02f */ |
@@ -242,12 +242,12 @@ static signed char UniCaseRangeLff20[27] = { | |||
242 | /* | 242 | /* |
243 | * Lower Case Range | 243 | * Lower Case Range |
244 | */ | 244 | */ |
245 | static const struct UniCaseRange CifsUniLowerRange[] = { | 245 | const struct UniCaseRange CifsUniLowerRange[] = { |
246 | 0x0380, 0x03ab, UniCaseRangeL0380, | 246 | {0x0380, 0x03ab, UniCaseRangeL0380}, |
247 | 0x0400, 0x042f, UniCaseRangeL0400, | 247 | {0x0400, 0x042f, UniCaseRangeL0400}, |
248 | 0x0490, 0x04cb, UniCaseRangeL0490, | 248 | {0x0490, 0x04cb, UniCaseRangeL0490}, |
249 | 0x1e00, 0x1ff7, UniCaseRangeL1e00, | 249 | {0x1e00, 0x1ff7, UniCaseRangeL1e00}, |
250 | 0xff20, 0xff3a, UniCaseRangeLff20, | 250 | {0xff20, 0xff3a, UniCaseRangeLff20}, |
251 | 0, 0, 0 | 251 | {0} |
252 | }; | 252 | }; |
253 | #endif | 253 | #endif |
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c index 847628dfdc4..35042d8f733 100644 --- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c | |||
@@ -223,63 +223,6 @@ int cifs_calculate_mac_key(struct mac_key *key, const char *rn, | |||
223 | return 0; | 223 | return 0; |
224 | } | 224 | } |
225 | 225 | ||
226 | int CalcNTLMv2_partial_mac_key(struct cifsSesInfo *ses, | ||
227 | const struct nls_table *nls_info) | ||
228 | { | ||
229 | char temp_hash[16]; | ||
230 | struct HMACMD5Context ctx; | ||
231 | char *ucase_buf; | ||
232 | __le16 *unicode_buf; | ||
233 | unsigned int i, user_name_len, dom_name_len; | ||
234 | |||
235 | if (ses == NULL) | ||
236 | return -EINVAL; | ||
237 | |||
238 | E_md4hash(ses->password, temp_hash); | ||
239 | |||
240 | hmac_md5_init_limK_to_64(temp_hash, 16, &ctx); | ||
241 | user_name_len = strlen(ses->userName); | ||
242 | if (user_name_len > MAX_USERNAME_SIZE) | ||
243 | return -EINVAL; | ||
244 | if (ses->domainName == NULL) | ||
245 | return -EINVAL; /* BB should we use CIFS_LINUX_DOM */ | ||
246 | dom_name_len = strlen(ses->domainName); | ||
247 | if (dom_name_len > MAX_USERNAME_SIZE) | ||
248 | return -EINVAL; | ||
249 | |||
250 | ucase_buf = kmalloc((MAX_USERNAME_SIZE+1), GFP_KERNEL); | ||
251 | if (ucase_buf == NULL) | ||
252 | return -ENOMEM; | ||
253 | unicode_buf = kmalloc((MAX_USERNAME_SIZE+1)*4, GFP_KERNEL); | ||
254 | if (unicode_buf == NULL) { | ||
255 | kfree(ucase_buf); | ||
256 | return -ENOMEM; | ||
257 | } | ||
258 | |||
259 | for (i = 0; i < user_name_len; i++) | ||
260 | ucase_buf[i] = nls_info->charset2upper[(int)ses->userName[i]]; | ||
261 | ucase_buf[i] = 0; | ||
262 | user_name_len = cifs_strtoUCS(unicode_buf, ucase_buf, | ||
263 | MAX_USERNAME_SIZE*2, nls_info); | ||
264 | unicode_buf[user_name_len] = 0; | ||
265 | user_name_len++; | ||
266 | |||
267 | for (i = 0; i < dom_name_len; i++) | ||
268 | ucase_buf[i] = nls_info->charset2upper[(int)ses->domainName[i]]; | ||
269 | ucase_buf[i] = 0; | ||
270 | dom_name_len = cifs_strtoUCS(unicode_buf+user_name_len, ucase_buf, | ||
271 | MAX_USERNAME_SIZE*2, nls_info); | ||
272 | |||
273 | unicode_buf[user_name_len + dom_name_len] = 0; | ||
274 | hmac_md5_update((const unsigned char *) unicode_buf, | ||
275 | (user_name_len+dom_name_len)*2, &ctx); | ||
276 | |||
277 | hmac_md5_final(ses->server->ntlmv2_hash, &ctx); | ||
278 | kfree(ucase_buf); | ||
279 | kfree(unicode_buf); | ||
280 | return 0; | ||
281 | } | ||
282 | |||
283 | #ifdef CONFIG_CIFS_WEAK_PW_HASH | 226 | #ifdef CONFIG_CIFS_WEAK_PW_HASH |
284 | void calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt, | 227 | void calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt, |
285 | char *lnm_session_key) | 228 | char *lnm_session_key) |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 1f545081408..1d60c655e3e 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -87,8 +87,9 @@ extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr); | |||
87 | extern int decode_negTokenInit(unsigned char *security_blob, int length, | 87 | extern int decode_negTokenInit(unsigned char *security_blob, int length, |
88 | struct TCP_Server_Info *server); | 88 | struct TCP_Server_Info *server); |
89 | extern int cifs_convert_address(struct sockaddr *dst, const char *src, int len); | 89 | extern int cifs_convert_address(struct sockaddr *dst, const char *src, int len); |
90 | extern int cifs_set_port(struct sockaddr *addr, const unsigned short int port); | ||
90 | extern int cifs_fill_sockaddr(struct sockaddr *dst, const char *src, int len, | 91 | extern int cifs_fill_sockaddr(struct sockaddr *dst, const char *src, int len, |
91 | unsigned short int port); | 92 | const unsigned short int port); |
92 | extern int map_smb_to_linux_error(struct smb_hdr *smb, int logErr); | 93 | extern int map_smb_to_linux_error(struct smb_hdr *smb, int logErr); |
93 | extern void header_assemble(struct smb_hdr *, char /* command */ , | 94 | extern void header_assemble(struct smb_hdr *, char /* command */ , |
94 | const struct cifsTconInfo *, int /* length of | 95 | const struct cifsTconInfo *, int /* length of |
@@ -365,8 +366,6 @@ extern int cifs_verify_signature(struct smb_hdr *, | |||
365 | __u32 expected_sequence_number); | 366 | __u32 expected_sequence_number); |
366 | extern int cifs_calculate_mac_key(struct mac_key *key, const char *rn, | 367 | extern int cifs_calculate_mac_key(struct mac_key *key, const char *rn, |
367 | const char *pass); | 368 | const char *pass); |
368 | extern int CalcNTLMv2_partial_mac_key(struct cifsSesInfo *, | ||
369 | const struct nls_table *); | ||
370 | extern void CalcNTLMv2_response(const struct cifsSesInfo *, char *); | 369 | extern void CalcNTLMv2_response(const struct cifsSesInfo *, char *); |
371 | extern void setup_ntlmv2_rsp(struct cifsSesInfo *, char *, | 370 | extern void setup_ntlmv2_rsp(struct cifsSesInfo *, char *, |
372 | const struct nls_table *); | 371 | const struct nls_table *); |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index c65c3419dd3..7e83b356cc9 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -232,7 +232,7 @@ static int | |||
232 | small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, | 232 | small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, |
233 | void **request_buf) | 233 | void **request_buf) |
234 | { | 234 | { |
235 | int rc = 0; | 235 | int rc; |
236 | 236 | ||
237 | rc = cifs_reconnect_tcon(tcon, smb_command); | 237 | rc = cifs_reconnect_tcon(tcon, smb_command); |
238 | if (rc) | 238 | if (rc) |
@@ -250,7 +250,7 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, | |||
250 | if (tcon != NULL) | 250 | if (tcon != NULL) |
251 | cifs_stats_inc(&tcon->num_smbs_sent); | 251 | cifs_stats_inc(&tcon->num_smbs_sent); |
252 | 252 | ||
253 | return rc; | 253 | return 0; |
254 | } | 254 | } |
255 | 255 | ||
256 | int | 256 | int |
@@ -281,16 +281,9 @@ small_smb_init_no_tc(const int smb_command, const int wct, | |||
281 | 281 | ||
282 | /* If the return code is zero, this function must fill in request_buf pointer */ | 282 | /* If the return code is zero, this function must fill in request_buf pointer */ |
283 | static int | 283 | static int |
284 | smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, | 284 | __smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, |
285 | void **request_buf /* returned */ , | 285 | void **request_buf, void **response_buf) |
286 | void **response_buf /* returned */ ) | ||
287 | { | 286 | { |
288 | int rc = 0; | ||
289 | |||
290 | rc = cifs_reconnect_tcon(tcon, smb_command); | ||
291 | if (rc) | ||
292 | return rc; | ||
293 | |||
294 | *request_buf = cifs_buf_get(); | 287 | *request_buf = cifs_buf_get(); |
295 | if (*request_buf == NULL) { | 288 | if (*request_buf == NULL) { |
296 | /* BB should we add a retry in here if not a writepage? */ | 289 | /* BB should we add a retry in here if not a writepage? */ |
@@ -309,7 +302,31 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, | |||
309 | if (tcon != NULL) | 302 | if (tcon != NULL) |
310 | cifs_stats_inc(&tcon->num_smbs_sent); | 303 | cifs_stats_inc(&tcon->num_smbs_sent); |
311 | 304 | ||
312 | return rc; | 305 | return 0; |
306 | } | ||
307 | |||
308 | /* If the return code is zero, this function must fill in request_buf pointer */ | ||
309 | static int | ||
310 | smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, | ||
311 | void **request_buf, void **response_buf) | ||
312 | { | ||
313 | int rc; | ||
314 | |||
315 | rc = cifs_reconnect_tcon(tcon, smb_command); | ||
316 | if (rc) | ||
317 | return rc; | ||
318 | |||
319 | return __smb_init(smb_command, wct, tcon, request_buf, response_buf); | ||
320 | } | ||
321 | |||
322 | static int | ||
323 | smb_init_no_reconnect(int smb_command, int wct, struct cifsTconInfo *tcon, | ||
324 | void **request_buf, void **response_buf) | ||
325 | { | ||
326 | if (tcon->ses->need_reconnect || tcon->need_reconnect) | ||
327 | return -EHOSTDOWN; | ||
328 | |||
329 | return __smb_init(smb_command, wct, tcon, request_buf, response_buf); | ||
313 | } | 330 | } |
314 | 331 | ||
315 | static int validate_t2(struct smb_t2_rsp *pSMB) | 332 | static int validate_t2(struct smb_t2_rsp *pSMB) |
@@ -4534,8 +4551,8 @@ CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon) | |||
4534 | 4551 | ||
4535 | cFYI(1, "In QFSUnixInfo"); | 4552 | cFYI(1, "In QFSUnixInfo"); |
4536 | QFSUnixRetry: | 4553 | QFSUnixRetry: |
4537 | rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, | 4554 | rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon, |
4538 | (void **) &pSMBr); | 4555 | (void **) &pSMB, (void **) &pSMBr); |
4539 | if (rc) | 4556 | if (rc) |
4540 | return rc; | 4557 | return rc; |
4541 | 4558 | ||
@@ -4604,8 +4621,8 @@ CIFSSMBSetFSUnixInfo(const int xid, struct cifsTconInfo *tcon, __u64 cap) | |||
4604 | cFYI(1, "In SETFSUnixInfo"); | 4621 | cFYI(1, "In SETFSUnixInfo"); |
4605 | SETFSUnixRetry: | 4622 | SETFSUnixRetry: |
4606 | /* BB switch to small buf init to save memory */ | 4623 | /* BB switch to small buf init to save memory */ |
4607 | rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, | 4624 | rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon, |
4608 | (void **) &pSMBr); | 4625 | (void **) &pSMB, (void **) &pSMBr); |
4609 | if (rc) | 4626 | if (rc) |
4610 | return rc; | 4627 | return rc; |
4611 | 4628 | ||
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 95c2ea67edf..88c84a38bcc 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -400,7 +400,9 @@ incomplete_rcv: | |||
400 | cFYI(1, "call to reconnect done"); | 400 | cFYI(1, "call to reconnect done"); |
401 | csocket = server->ssocket; | 401 | csocket = server->ssocket; |
402 | continue; | 402 | continue; |
403 | } else if ((length == -ERESTARTSYS) || (length == -EAGAIN)) { | 403 | } else if (length == -ERESTARTSYS || |
404 | length == -EAGAIN || | ||
405 | length == -EINTR) { | ||
404 | msleep(1); /* minimum sleep to prevent looping | 406 | msleep(1); /* minimum sleep to prevent looping |
405 | allowing socket to clear and app threads to set | 407 | allowing socket to clear and app threads to set |
406 | tcpStatus CifsNeedReconnect if server hung */ | 408 | tcpStatus CifsNeedReconnect if server hung */ |
@@ -414,18 +416,6 @@ incomplete_rcv: | |||
414 | } else | 416 | } else |
415 | continue; | 417 | continue; |
416 | } else if (length <= 0) { | 418 | } else if (length <= 0) { |
417 | if (server->tcpStatus == CifsNew) { | ||
418 | cFYI(1, "tcp session abend after SMBnegprot"); | ||
419 | /* some servers kill the TCP session rather than | ||
420 | returning an SMB negprot error, in which | ||
421 | case reconnecting here is not going to help, | ||
422 | and so simply return error to mount */ | ||
423 | break; | ||
424 | } | ||
425 | if (!try_to_freeze() && (length == -EINTR)) { | ||
426 | cFYI(1, "cifsd thread killed"); | ||
427 | break; | ||
428 | } | ||
429 | cFYI(1, "Reconnect after unexpected peek error %d", | 419 | cFYI(1, "Reconnect after unexpected peek error %d", |
430 | length); | 420 | length); |
431 | cifs_reconnect(server); | 421 | cifs_reconnect(server); |
@@ -466,27 +456,19 @@ incomplete_rcv: | |||
466 | an error on SMB negprot response */ | 456 | an error on SMB negprot response */ |
467 | cFYI(1, "Negative RFC1002 Session Response Error 0x%x)", | 457 | cFYI(1, "Negative RFC1002 Session Response Error 0x%x)", |
468 | pdu_length); | 458 | pdu_length); |
469 | if (server->tcpStatus == CifsNew) { | 459 | /* give server a second to clean up */ |
470 | /* if nack on negprot (rather than | 460 | msleep(1000); |
471 | ret of smb negprot error) reconnecting | 461 | /* always try 445 first on reconnect since we get NACK |
472 | not going to help, ret error to mount */ | 462 | * on some if we ever connected to port 139 (the NACK |
473 | break; | 463 | * is since we do not begin with RFC1001 session |
474 | } else { | 464 | * initialize frame) |
475 | /* give server a second to | 465 | */ |
476 | clean up before reconnect attempt */ | 466 | cifs_set_port((struct sockaddr *) |
477 | msleep(1000); | 467 | &server->addr.sockAddr, CIFS_PORT); |
478 | /* always try 445 first on reconnect | 468 | cifs_reconnect(server); |
479 | since we get NACK on some if we ever | 469 | csocket = server->ssocket; |
480 | connected to port 139 (the NACK is | 470 | wake_up(&server->response_q); |
481 | since we do not begin with RFC1001 | 471 | continue; |
482 | session initialize frame) */ | ||
483 | server->addr.sockAddr.sin_port = | ||
484 | htons(CIFS_PORT); | ||
485 | cifs_reconnect(server); | ||
486 | csocket = server->ssocket; | ||
487 | wake_up(&server->response_q); | ||
488 | continue; | ||
489 | } | ||
490 | } else if (temp != (char) 0) { | 472 | } else if (temp != (char) 0) { |
491 | cERROR(1, "Unknown RFC 1002 frame"); | 473 | cERROR(1, "Unknown RFC 1002 frame"); |
492 | cifs_dump_mem(" Received Data: ", (char *)smb_buffer, | 474 | cifs_dump_mem(" Received Data: ", (char *)smb_buffer, |
@@ -522,8 +504,7 @@ incomplete_rcv: | |||
522 | total_read += length) { | 504 | total_read += length) { |
523 | length = kernel_recvmsg(csocket, &smb_msg, &iov, 1, | 505 | length = kernel_recvmsg(csocket, &smb_msg, &iov, 1, |
524 | pdu_length - total_read, 0); | 506 | pdu_length - total_read, 0); |
525 | if ((server->tcpStatus == CifsExiting) || | 507 | if (server->tcpStatus == CifsExiting) { |
526 | (length == -EINTR)) { | ||
527 | /* then will exit */ | 508 | /* then will exit */ |
528 | reconnect = 2; | 509 | reconnect = 2; |
529 | break; | 510 | break; |
@@ -534,8 +515,9 @@ incomplete_rcv: | |||
534 | /* Now we will reread sock */ | 515 | /* Now we will reread sock */ |
535 | reconnect = 1; | 516 | reconnect = 1; |
536 | break; | 517 | break; |
537 | } else if ((length == -ERESTARTSYS) || | 518 | } else if (length == -ERESTARTSYS || |
538 | (length == -EAGAIN)) { | 519 | length == -EAGAIN || |
520 | length == -EINTR) { | ||
539 | msleep(1); /* minimum sleep to prevent looping, | 521 | msleep(1); /* minimum sleep to prevent looping, |
540 | allowing socket to clear and app | 522 | allowing socket to clear and app |
541 | threads to set tcpStatus | 523 | threads to set tcpStatus |
@@ -1673,7 +1655,9 @@ cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol) | |||
1673 | MAX_USERNAME_SIZE)) | 1655 | MAX_USERNAME_SIZE)) |
1674 | continue; | 1656 | continue; |
1675 | if (strlen(vol->username) != 0 && | 1657 | if (strlen(vol->username) != 0 && |
1676 | strncmp(ses->password, vol->password, | 1658 | ses->password != NULL && |
1659 | strncmp(ses->password, | ||
1660 | vol->password ? vol->password : "", | ||
1677 | MAX_PASSWORD_SIZE)) | 1661 | MAX_PASSWORD_SIZE)) |
1678 | continue; | 1662 | continue; |
1679 | } | 1663 | } |
@@ -1722,9 +1706,6 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) | |||
1722 | if (ses) { | 1706 | if (ses) { |
1723 | cFYI(1, "Existing smb sess found (status=%d)", ses->status); | 1707 | cFYI(1, "Existing smb sess found (status=%d)", ses->status); |
1724 | 1708 | ||
1725 | /* existing SMB ses has a server reference already */ | ||
1726 | cifs_put_tcp_session(server); | ||
1727 | |||
1728 | mutex_lock(&ses->session_mutex); | 1709 | mutex_lock(&ses->session_mutex); |
1729 | rc = cifs_negotiate_protocol(xid, ses); | 1710 | rc = cifs_negotiate_protocol(xid, ses); |
1730 | if (rc) { | 1711 | if (rc) { |
@@ -1747,6 +1728,9 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) | |||
1747 | } | 1728 | } |
1748 | } | 1729 | } |
1749 | mutex_unlock(&ses->session_mutex); | 1730 | mutex_unlock(&ses->session_mutex); |
1731 | |||
1732 | /* existing SMB ses has a server reference already */ | ||
1733 | cifs_put_tcp_session(server); | ||
1750 | FreeXid(xid); | 1734 | FreeXid(xid); |
1751 | return ses; | 1735 | return ses; |
1752 | } | 1736 | } |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 578d88c5b46..f9ed0751cc1 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -305,8 +305,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
305 | full_path = build_path_from_dentry(direntry); | 305 | full_path = build_path_from_dentry(direntry); |
306 | if (full_path == NULL) { | 306 | if (full_path == NULL) { |
307 | rc = -ENOMEM; | 307 | rc = -ENOMEM; |
308 | FreeXid(xid); | 308 | goto cifs_create_out; |
309 | return rc; | ||
310 | } | 309 | } |
311 | 310 | ||
312 | if (oplockEnabled) | 311 | if (oplockEnabled) |
@@ -365,9 +364,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
365 | 364 | ||
366 | buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); | 365 | buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); |
367 | if (buf == NULL) { | 366 | if (buf == NULL) { |
368 | kfree(full_path); | 367 | rc = -ENOMEM; |
369 | FreeXid(xid); | 368 | goto cifs_create_out; |
370 | return -ENOMEM; | ||
371 | } | 369 | } |
372 | 370 | ||
373 | /* | 371 | /* |
@@ -496,6 +494,11 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, | |||
496 | struct cifsTconInfo *pTcon; | 494 | struct cifsTconInfo *pTcon; |
497 | char *full_path = NULL; | 495 | char *full_path = NULL; |
498 | struct inode *newinode = NULL; | 496 | struct inode *newinode = NULL; |
497 | int oplock = 0; | ||
498 | u16 fileHandle; | ||
499 | FILE_ALL_INFO *buf = NULL; | ||
500 | unsigned int bytes_written; | ||
501 | struct win_dev *pdev; | ||
499 | 502 | ||
500 | if (!old_valid_dev(device_number)) | 503 | if (!old_valid_dev(device_number)) |
501 | return -EINVAL; | 504 | return -EINVAL; |
@@ -506,9 +509,12 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, | |||
506 | pTcon = cifs_sb->tcon; | 509 | pTcon = cifs_sb->tcon; |
507 | 510 | ||
508 | full_path = build_path_from_dentry(direntry); | 511 | full_path = build_path_from_dentry(direntry); |
509 | if (full_path == NULL) | 512 | if (full_path == NULL) { |
510 | rc = -ENOMEM; | 513 | rc = -ENOMEM; |
511 | else if (pTcon->unix_ext) { | 514 | goto mknod_out; |
515 | } | ||
516 | |||
517 | if (pTcon->unix_ext) { | ||
512 | struct cifs_unix_set_info_args args = { | 518 | struct cifs_unix_set_info_args args = { |
513 | .mode = mode & ~current_umask(), | 519 | .mode = mode & ~current_umask(), |
514 | .ctime = NO_CHANGE_64, | 520 | .ctime = NO_CHANGE_64, |
@@ -527,87 +533,78 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, | |||
527 | cifs_sb->local_nls, | 533 | cifs_sb->local_nls, |
528 | cifs_sb->mnt_cifs_flags & | 534 | cifs_sb->mnt_cifs_flags & |
529 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 535 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
536 | if (rc) | ||
537 | goto mknod_out; | ||
530 | 538 | ||
531 | if (!rc) { | 539 | rc = cifs_get_inode_info_unix(&newinode, full_path, |
532 | rc = cifs_get_inode_info_unix(&newinode, full_path, | ||
533 | inode->i_sb, xid); | 540 | inode->i_sb, xid); |
534 | if (pTcon->nocase) | 541 | if (pTcon->nocase) |
535 | direntry->d_op = &cifs_ci_dentry_ops; | 542 | direntry->d_op = &cifs_ci_dentry_ops; |
536 | else | 543 | else |
537 | direntry->d_op = &cifs_dentry_ops; | 544 | direntry->d_op = &cifs_dentry_ops; |
538 | if (rc == 0) | ||
539 | d_instantiate(direntry, newinode); | ||
540 | } | ||
541 | } else { | ||
542 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { | ||
543 | int oplock = 0; | ||
544 | u16 fileHandle; | ||
545 | FILE_ALL_INFO *buf; | ||
546 | 545 | ||
547 | cFYI(1, "sfu compat create special file"); | 546 | if (rc == 0) |
547 | d_instantiate(direntry, newinode); | ||
548 | goto mknod_out; | ||
549 | } | ||
548 | 550 | ||
549 | buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); | 551 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)) |
550 | if (buf == NULL) { | 552 | goto mknod_out; |
551 | kfree(full_path); | ||
552 | rc = -ENOMEM; | ||
553 | FreeXid(xid); | ||
554 | return rc; | ||
555 | } | ||
556 | 553 | ||
557 | rc = CIFSSMBOpen(xid, pTcon, full_path, | 554 | |
558 | FILE_CREATE, /* fail if exists */ | 555 | cFYI(1, "sfu compat create special file"); |
559 | GENERIC_WRITE /* BB would | 556 | |
560 | WRITE_OWNER | WRITE_DAC be better? */, | 557 | buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); |
561 | /* Create a file and set the | 558 | if (buf == NULL) { |
562 | file attribute to SYSTEM */ | 559 | kfree(full_path); |
563 | CREATE_NOT_DIR | CREATE_OPTION_SPECIAL, | 560 | rc = -ENOMEM; |
564 | &fileHandle, &oplock, buf, | 561 | FreeXid(xid); |
565 | cifs_sb->local_nls, | 562 | return rc; |
566 | cifs_sb->mnt_cifs_flags & | ||
567 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
568 | |||
569 | /* BB FIXME - add handling for backlevel servers | ||
570 | which need legacy open and check for all | ||
571 | calls to SMBOpen for fallback to SMBLeagcyOpen */ | ||
572 | if (!rc) { | ||
573 | /* BB Do not bother to decode buf since no | ||
574 | local inode yet to put timestamps in, | ||
575 | but we can reuse it safely */ | ||
576 | unsigned int bytes_written; | ||
577 | struct win_dev *pdev; | ||
578 | pdev = (struct win_dev *)buf; | ||
579 | if (S_ISCHR(mode)) { | ||
580 | memcpy(pdev->type, "IntxCHR", 8); | ||
581 | pdev->major = | ||
582 | cpu_to_le64(MAJOR(device_number)); | ||
583 | pdev->minor = | ||
584 | cpu_to_le64(MINOR(device_number)); | ||
585 | rc = CIFSSMBWrite(xid, pTcon, | ||
586 | fileHandle, | ||
587 | sizeof(struct win_dev), | ||
588 | 0, &bytes_written, (char *)pdev, | ||
589 | NULL, 0); | ||
590 | } else if (S_ISBLK(mode)) { | ||
591 | memcpy(pdev->type, "IntxBLK", 8); | ||
592 | pdev->major = | ||
593 | cpu_to_le64(MAJOR(device_number)); | ||
594 | pdev->minor = | ||
595 | cpu_to_le64(MINOR(device_number)); | ||
596 | rc = CIFSSMBWrite(xid, pTcon, | ||
597 | fileHandle, | ||
598 | sizeof(struct win_dev), | ||
599 | 0, &bytes_written, (char *)pdev, | ||
600 | NULL, 0); | ||
601 | } /* else if(S_ISFIFO */ | ||
602 | CIFSSMBClose(xid, pTcon, fileHandle); | ||
603 | d_drop(direntry); | ||
604 | } | ||
605 | kfree(buf); | ||
606 | /* add code here to set EAs */ | ||
607 | } | ||
608 | } | 563 | } |
609 | 564 | ||
565 | /* FIXME: would WRITE_OWNER | WRITE_DAC be better? */ | ||
566 | rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_CREATE, | ||
567 | GENERIC_WRITE, CREATE_NOT_DIR | CREATE_OPTION_SPECIAL, | ||
568 | &fileHandle, &oplock, buf, cifs_sb->local_nls, | ||
569 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
570 | if (rc) | ||
571 | goto mknod_out; | ||
572 | |||
573 | /* BB Do not bother to decode buf since no local inode yet to put | ||
574 | * timestamps in, but we can reuse it safely */ | ||
575 | |||
576 | pdev = (struct win_dev *)buf; | ||
577 | if (S_ISCHR(mode)) { | ||
578 | memcpy(pdev->type, "IntxCHR", 8); | ||
579 | pdev->major = | ||
580 | cpu_to_le64(MAJOR(device_number)); | ||
581 | pdev->minor = | ||
582 | cpu_to_le64(MINOR(device_number)); | ||
583 | rc = CIFSSMBWrite(xid, pTcon, | ||
584 | fileHandle, | ||
585 | sizeof(struct win_dev), | ||
586 | 0, &bytes_written, (char *)pdev, | ||
587 | NULL, 0); | ||
588 | } else if (S_ISBLK(mode)) { | ||
589 | memcpy(pdev->type, "IntxBLK", 8); | ||
590 | pdev->major = | ||
591 | cpu_to_le64(MAJOR(device_number)); | ||
592 | pdev->minor = | ||
593 | cpu_to_le64(MINOR(device_number)); | ||
594 | rc = CIFSSMBWrite(xid, pTcon, | ||
595 | fileHandle, | ||
596 | sizeof(struct win_dev), | ||
597 | 0, &bytes_written, (char *)pdev, | ||
598 | NULL, 0); | ||
599 | } /* else if (S_ISFIFO) */ | ||
600 | CIFSSMBClose(xid, pTcon, fileHandle); | ||
601 | d_drop(direntry); | ||
602 | |||
603 | /* FIXME: add code here to set EAs */ | ||
604 | |||
605 | mknod_out: | ||
610 | kfree(full_path); | 606 | kfree(full_path); |
607 | kfree(buf); | ||
611 | FreeXid(xid); | 608 | FreeXid(xid); |
612 | return rc; | 609 | return rc; |
613 | } | 610 | } |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index db11fdef0e9..de748c652d1 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -242,8 +242,7 @@ int cifs_open(struct inode *inode, struct file *file) | |||
242 | full_path = build_path_from_dentry(file->f_path.dentry); | 242 | full_path = build_path_from_dentry(file->f_path.dentry); |
243 | if (full_path == NULL) { | 243 | if (full_path == NULL) { |
244 | rc = -ENOMEM; | 244 | rc = -ENOMEM; |
245 | FreeXid(xid); | 245 | goto out; |
246 | return rc; | ||
247 | } | 246 | } |
248 | 247 | ||
249 | cFYI(1, "inode = 0x%p file flags are 0x%x for %s", | 248 | cFYI(1, "inode = 0x%p file flags are 0x%x for %s", |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 4bc47e5b5f2..53cce8cc222 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -801,6 +801,8 @@ retry_iget5_locked: | |||
801 | inode->i_flags |= S_NOATIME | S_NOCMTIME; | 801 | inode->i_flags |= S_NOATIME | S_NOCMTIME; |
802 | if (inode->i_state & I_NEW) { | 802 | if (inode->i_state & I_NEW) { |
803 | inode->i_ino = hash; | 803 | inode->i_ino = hash; |
804 | if (S_ISREG(inode->i_mode)) | ||
805 | inode->i_data.backing_dev_info = sb->s_bdi; | ||
804 | #ifdef CONFIG_CIFS_FSCACHE | 806 | #ifdef CONFIG_CIFS_FSCACHE |
805 | /* initialize per-inode cache cookie pointer */ | 807 | /* initialize per-inode cache cookie pointer */ |
806 | CIFS_I(inode)->fscache = NULL; | 808 | CIFS_I(inode)->fscache = NULL; |
@@ -834,7 +836,7 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino) | |||
834 | xid, NULL); | 836 | xid, NULL); |
835 | 837 | ||
836 | if (!inode) | 838 | if (!inode) |
837 | return ERR_PTR(-ENOMEM); | 839 | return ERR_PTR(rc); |
838 | 840 | ||
839 | #ifdef CONFIG_CIFS_FSCACHE | 841 | #ifdef CONFIG_CIFS_FSCACHE |
840 | /* populate tcon->resource_id */ | 842 | /* populate tcon->resource_id */ |
@@ -1462,29 +1464,18 @@ int cifs_rename(struct inode *source_dir, struct dentry *source_dentry, | |||
1462 | { | 1464 | { |
1463 | char *fromName = NULL; | 1465 | char *fromName = NULL; |
1464 | char *toName = NULL; | 1466 | char *toName = NULL; |
1465 | struct cifs_sb_info *cifs_sb_source; | 1467 | struct cifs_sb_info *cifs_sb; |
1466 | struct cifs_sb_info *cifs_sb_target; | ||
1467 | struct cifsTconInfo *tcon; | 1468 | struct cifsTconInfo *tcon; |
1468 | FILE_UNIX_BASIC_INFO *info_buf_source = NULL; | 1469 | FILE_UNIX_BASIC_INFO *info_buf_source = NULL; |
1469 | FILE_UNIX_BASIC_INFO *info_buf_target; | 1470 | FILE_UNIX_BASIC_INFO *info_buf_target; |
1470 | int xid, rc, tmprc; | 1471 | int xid, rc, tmprc; |
1471 | 1472 | ||
1472 | cifs_sb_target = CIFS_SB(target_dir->i_sb); | 1473 | cifs_sb = CIFS_SB(source_dir->i_sb); |
1473 | cifs_sb_source = CIFS_SB(source_dir->i_sb); | 1474 | tcon = cifs_sb->tcon; |
1474 | tcon = cifs_sb_source->tcon; | ||
1475 | 1475 | ||
1476 | xid = GetXid(); | 1476 | xid = GetXid(); |
1477 | 1477 | ||
1478 | /* | 1478 | /* |
1479 | * BB: this might be allowed if same server, but different share. | ||
1480 | * Consider adding support for this | ||
1481 | */ | ||
1482 | if (tcon != cifs_sb_target->tcon) { | ||
1483 | rc = -EXDEV; | ||
1484 | goto cifs_rename_exit; | ||
1485 | } | ||
1486 | |||
1487 | /* | ||
1488 | * we already have the rename sem so we do not need to | 1479 | * we already have the rename sem so we do not need to |
1489 | * grab it again here to protect the path integrity | 1480 | * grab it again here to protect the path integrity |
1490 | */ | 1481 | */ |
@@ -1519,17 +1510,16 @@ int cifs_rename(struct inode *source_dir, struct dentry *source_dentry, | |||
1519 | info_buf_target = info_buf_source + 1; | 1510 | info_buf_target = info_buf_source + 1; |
1520 | tmprc = CIFSSMBUnixQPathInfo(xid, tcon, fromName, | 1511 | tmprc = CIFSSMBUnixQPathInfo(xid, tcon, fromName, |
1521 | info_buf_source, | 1512 | info_buf_source, |
1522 | cifs_sb_source->local_nls, | 1513 | cifs_sb->local_nls, |
1523 | cifs_sb_source->mnt_cifs_flags & | 1514 | cifs_sb->mnt_cifs_flags & |
1524 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 1515 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
1525 | if (tmprc != 0) | 1516 | if (tmprc != 0) |
1526 | goto unlink_target; | 1517 | goto unlink_target; |
1527 | 1518 | ||
1528 | tmprc = CIFSSMBUnixQPathInfo(xid, tcon, | 1519 | tmprc = CIFSSMBUnixQPathInfo(xid, tcon, toName, |
1529 | toName, info_buf_target, | 1520 | info_buf_target, |
1530 | cifs_sb_target->local_nls, | 1521 | cifs_sb->local_nls, |
1531 | /* remap based on source sb */ | 1522 | cifs_sb->mnt_cifs_flags & |
1532 | cifs_sb_source->mnt_cifs_flags & | ||
1533 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 1523 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
1534 | 1524 | ||
1535 | if (tmprc == 0 && (info_buf_source->UniqueId == | 1525 | if (tmprc == 0 && (info_buf_source->UniqueId == |
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c index f97851119e6..9aad47a2d62 100644 --- a/fs/cifs/netmisc.c +++ b/fs/cifs/netmisc.c | |||
@@ -206,26 +206,30 @@ cifs_convert_address(struct sockaddr *dst, const char *src, int len) | |||
206 | } | 206 | } |
207 | 207 | ||
208 | int | 208 | int |
209 | cifs_fill_sockaddr(struct sockaddr *dst, const char *src, int len, | 209 | cifs_set_port(struct sockaddr *addr, const unsigned short int port) |
210 | const unsigned short int port) | ||
211 | { | 210 | { |
212 | if (!cifs_convert_address(dst, src, len)) | 211 | switch (addr->sa_family) { |
213 | return 0; | ||
214 | |||
215 | switch (dst->sa_family) { | ||
216 | case AF_INET: | 212 | case AF_INET: |
217 | ((struct sockaddr_in *)dst)->sin_port = htons(port); | 213 | ((struct sockaddr_in *)addr)->sin_port = htons(port); |
218 | break; | 214 | break; |
219 | case AF_INET6: | 215 | case AF_INET6: |
220 | ((struct sockaddr_in6 *)dst)->sin6_port = htons(port); | 216 | ((struct sockaddr_in6 *)addr)->sin6_port = htons(port); |
221 | break; | 217 | break; |
222 | default: | 218 | default: |
223 | return 0; | 219 | return 0; |
224 | } | 220 | } |
225 | |||
226 | return 1; | 221 | return 1; |
227 | } | 222 | } |
228 | 223 | ||
224 | int | ||
225 | cifs_fill_sockaddr(struct sockaddr *dst, const char *src, int len, | ||
226 | const unsigned short int port) | ||
227 | { | ||
228 | if (!cifs_convert_address(dst, src, len)) | ||
229 | return 0; | ||
230 | return cifs_set_port(dst, port); | ||
231 | } | ||
232 | |||
229 | /***************************************************************************** | 233 | /***************************************************************************** |
230 | convert a NT status code to a dos class/code | 234 | convert a NT status code to a dos class/code |
231 | *****************************************************************************/ | 235 | *****************************************************************************/ |
diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c index de89645777c..116af7546cf 100644 --- a/fs/coda/psdev.c +++ b/fs/coda/psdev.c | |||
@@ -184,8 +184,8 @@ static ssize_t coda_psdev_write(struct file *file, const char __user *buf, | |||
184 | } | 184 | } |
185 | 185 | ||
186 | /* adjust outsize. is this useful ?? */ | 186 | /* adjust outsize. is this useful ?? */ |
187 | req->uc_outSize = nbytes; | 187 | req->uc_outSize = nbytes; |
188 | req->uc_flags |= REQ_WRITE; | 188 | req->uc_flags |= CODA_REQ_WRITE; |
189 | count = nbytes; | 189 | count = nbytes; |
190 | 190 | ||
191 | /* Convert filedescriptor into a file handle */ | 191 | /* Convert filedescriptor into a file handle */ |
diff --git a/fs/compat.c b/fs/compat.c index 718c7062aec..0644a154672 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -1153,7 +1153,7 @@ static ssize_t compat_do_readv_writev(int type, struct file *file, | |||
1153 | { | 1153 | { |
1154 | compat_ssize_t tot_len; | 1154 | compat_ssize_t tot_len; |
1155 | struct iovec iovstack[UIO_FASTIOV]; | 1155 | struct iovec iovstack[UIO_FASTIOV]; |
1156 | struct iovec *iov; | 1156 | struct iovec *iov = iovstack; |
1157 | ssize_t ret; | 1157 | ssize_t ret; |
1158 | io_fn_t fn; | 1158 | io_fn_t fn; |
1159 | iov_fn_t fnv; | 1159 | iov_fn_t fnv; |
diff --git a/fs/direct-io.c b/fs/direct-io.c index 51f270b479b..48d74c7391d 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c | |||
@@ -634,7 +634,7 @@ static int dio_send_cur_page(struct dio *dio) | |||
634 | int ret = 0; | 634 | int ret = 0; |
635 | 635 | ||
636 | if (dio->bio) { | 636 | if (dio->bio) { |
637 | loff_t cur_offset = dio->block_in_file << dio->blkbits; | 637 | loff_t cur_offset = dio->cur_page_fs_offset; |
638 | loff_t bio_next_offset = dio->logical_offset_in_bio + | 638 | loff_t bio_next_offset = dio->logical_offset_in_bio + |
639 | dio->bio->bi_size; | 639 | dio->bio->bi_size; |
640 | 640 | ||
@@ -659,7 +659,7 @@ static int dio_send_cur_page(struct dio *dio) | |||
659 | * Submit now if the underlying fs is about to perform a | 659 | * Submit now if the underlying fs is about to perform a |
660 | * metadata read | 660 | * metadata read |
661 | */ | 661 | */ |
662 | if (dio->boundary) | 662 | else if (dio->boundary) |
663 | dio_bio_submit(dio); | 663 | dio_bio_submit(dio); |
664 | } | 664 | } |
665 | 665 | ||
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index a2e3b562e65..cbadc1bee6e 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c | |||
@@ -1793,7 +1793,7 @@ struct kmem_cache *ecryptfs_key_tfm_cache; | |||
1793 | static struct list_head key_tfm_list; | 1793 | static struct list_head key_tfm_list; |
1794 | struct mutex key_tfm_list_mutex; | 1794 | struct mutex key_tfm_list_mutex; |
1795 | 1795 | ||
1796 | int ecryptfs_init_crypto(void) | 1796 | int __init ecryptfs_init_crypto(void) |
1797 | { | 1797 | { |
1798 | mutex_init(&key_tfm_list_mutex); | 1798 | mutex_init(&key_tfm_list_mutex); |
1799 | INIT_LIST_HEAD(&key_tfm_list); | 1799 | INIT_LIST_HEAD(&key_tfm_list); |
@@ -2169,7 +2169,6 @@ int ecryptfs_encrypt_and_encode_filename( | |||
2169 | (ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE | 2169 | (ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE |
2170 | + encoded_name_no_prefix_size); | 2170 | + encoded_name_no_prefix_size); |
2171 | (*encoded_name)[(*encoded_name_size)] = '\0'; | 2171 | (*encoded_name)[(*encoded_name_size)] = '\0'; |
2172 | (*encoded_name_size)++; | ||
2173 | } else { | 2172 | } else { |
2174 | rc = -EOPNOTSUPP; | 2173 | rc = -EOPNOTSUPP; |
2175 | } | 2174 | } |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 6c55113e722..3fbc9420338 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -349,7 +349,7 @@ out: | |||
349 | 349 | ||
350 | /** | 350 | /** |
351 | * ecryptfs_new_lower_dentry | 351 | * ecryptfs_new_lower_dentry |
352 | * @ename: The name of the new dentry. | 352 | * @name: The name of the new dentry. |
353 | * @lower_dir_dentry: Parent directory of the new dentry. | 353 | * @lower_dir_dentry: Parent directory of the new dentry. |
354 | * @nd: nameidata from last lookup. | 354 | * @nd: nameidata from last lookup. |
355 | * | 355 | * |
@@ -386,20 +386,19 @@ ecryptfs_new_lower_dentry(struct qstr *name, struct dentry *lower_dir_dentry, | |||
386 | * ecryptfs_lookup_one_lower | 386 | * ecryptfs_lookup_one_lower |
387 | * @ecryptfs_dentry: The eCryptfs dentry that we are looking up | 387 | * @ecryptfs_dentry: The eCryptfs dentry that we are looking up |
388 | * @lower_dir_dentry: lower parent directory | 388 | * @lower_dir_dentry: lower parent directory |
389 | * @name: lower file name | ||
389 | * | 390 | * |
390 | * Get the lower dentry from vfs. If lower dentry does not exist yet, | 391 | * Get the lower dentry from vfs. If lower dentry does not exist yet, |
391 | * create it. | 392 | * create it. |
392 | */ | 393 | */ |
393 | static struct dentry * | 394 | static struct dentry * |
394 | ecryptfs_lookup_one_lower(struct dentry *ecryptfs_dentry, | 395 | ecryptfs_lookup_one_lower(struct dentry *ecryptfs_dentry, |
395 | struct dentry *lower_dir_dentry) | 396 | struct dentry *lower_dir_dentry, struct qstr *name) |
396 | { | 397 | { |
397 | struct nameidata nd; | 398 | struct nameidata nd; |
398 | struct vfsmount *lower_mnt; | 399 | struct vfsmount *lower_mnt; |
399 | struct qstr *name; | ||
400 | int err; | 400 | int err; |
401 | 401 | ||
402 | name = &ecryptfs_dentry->d_name; | ||
403 | lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt( | 402 | lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt( |
404 | ecryptfs_dentry->d_parent)); | 403 | ecryptfs_dentry->d_parent)); |
405 | err = vfs_path_lookup(lower_dir_dentry, lower_mnt, name->name , 0, &nd); | 404 | err = vfs_path_lookup(lower_dir_dentry, lower_mnt, name->name , 0, &nd); |
@@ -434,6 +433,7 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | |||
434 | size_t encrypted_and_encoded_name_size; | 433 | size_t encrypted_and_encoded_name_size; |
435 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = NULL; | 434 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = NULL; |
436 | struct dentry *lower_dir_dentry, *lower_dentry; | 435 | struct dentry *lower_dir_dentry, *lower_dentry; |
436 | struct qstr lower_name; | ||
437 | int rc = 0; | 437 | int rc = 0; |
438 | 438 | ||
439 | ecryptfs_dentry->d_op = &ecryptfs_dops; | 439 | ecryptfs_dentry->d_op = &ecryptfs_dops; |
@@ -444,9 +444,17 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | |||
444 | goto out_d_drop; | 444 | goto out_d_drop; |
445 | } | 445 | } |
446 | lower_dir_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry->d_parent); | 446 | lower_dir_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry->d_parent); |
447 | 447 | lower_name.name = ecryptfs_dentry->d_name.name; | |
448 | lower_name.len = ecryptfs_dentry->d_name.len; | ||
449 | lower_name.hash = ecryptfs_dentry->d_name.hash; | ||
450 | if (lower_dir_dentry->d_op && lower_dir_dentry->d_op->d_hash) { | ||
451 | rc = lower_dir_dentry->d_op->d_hash(lower_dir_dentry, | ||
452 | &lower_name); | ||
453 | if (rc < 0) | ||
454 | goto out_d_drop; | ||
455 | } | ||
448 | lower_dentry = ecryptfs_lookup_one_lower(ecryptfs_dentry, | 456 | lower_dentry = ecryptfs_lookup_one_lower(ecryptfs_dentry, |
449 | lower_dir_dentry); | 457 | lower_dir_dentry, &lower_name); |
450 | if (IS_ERR(lower_dentry)) { | 458 | if (IS_ERR(lower_dentry)) { |
451 | rc = PTR_ERR(lower_dentry); | 459 | rc = PTR_ERR(lower_dentry); |
452 | ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_lower() returned " | 460 | ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_lower() returned " |
@@ -471,8 +479,17 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | |||
471 | "filename; rc = [%d]\n", __func__, rc); | 479 | "filename; rc = [%d]\n", __func__, rc); |
472 | goto out_d_drop; | 480 | goto out_d_drop; |
473 | } | 481 | } |
482 | lower_name.name = encrypted_and_encoded_name; | ||
483 | lower_name.len = encrypted_and_encoded_name_size; | ||
484 | lower_name.hash = full_name_hash(lower_name.name, lower_name.len); | ||
485 | if (lower_dir_dentry->d_op && lower_dir_dentry->d_op->d_hash) { | ||
486 | rc = lower_dir_dentry->d_op->d_hash(lower_dir_dentry, | ||
487 | &lower_name); | ||
488 | if (rc < 0) | ||
489 | goto out_d_drop; | ||
490 | } | ||
474 | lower_dentry = ecryptfs_lookup_one_lower(ecryptfs_dentry, | 491 | lower_dentry = ecryptfs_lookup_one_lower(ecryptfs_dentry, |
475 | lower_dir_dentry); | 492 | lower_dir_dentry, &lower_name); |
476 | if (IS_ERR(lower_dentry)) { | 493 | if (IS_ERR(lower_dentry)) { |
477 | rc = PTR_ERR(lower_dentry); | 494 | rc = PTR_ERR(lower_dentry); |
478 | ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_lower() returned " | 495 | ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_lower() returned " |
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c index 89c5476506e..73811cfa2ea 100644 --- a/fs/ecryptfs/keystore.c +++ b/fs/ecryptfs/keystore.c | |||
@@ -515,6 +515,7 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, | |||
515 | if (!s) { | 515 | if (!s) { |
516 | printk(KERN_ERR "%s: Out of memory whilst trying to kmalloc " | 516 | printk(KERN_ERR "%s: Out of memory whilst trying to kmalloc " |
517 | "[%zd] bytes of kernel memory\n", __func__, sizeof(*s)); | 517 | "[%zd] bytes of kernel memory\n", __func__, sizeof(*s)); |
518 | rc = -ENOMEM; | ||
518 | goto out; | 519 | goto out; |
519 | } | 520 | } |
520 | s->desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; | 521 | s->desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; |
@@ -806,6 +807,7 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size, | |||
806 | if (!s) { | 807 | if (!s) { |
807 | printk(KERN_ERR "%s: Out of memory whilst trying to kmalloc " | 808 | printk(KERN_ERR "%s: Out of memory whilst trying to kmalloc " |
808 | "[%zd] bytes of kernel memory\n", __func__, sizeof(*s)); | 809 | "[%zd] bytes of kernel memory\n", __func__, sizeof(*s)); |
810 | rc = -ENOMEM; | ||
809 | goto out; | 811 | goto out; |
810 | } | 812 | } |
811 | s->desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; | 813 | s->desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; |
diff --git a/fs/ecryptfs/kthread.c b/fs/ecryptfs/kthread.c index d8c3a373aaf..0851ab6980f 100644 --- a/fs/ecryptfs/kthread.c +++ b/fs/ecryptfs/kthread.c | |||
@@ -86,7 +86,7 @@ out: | |||
86 | return 0; | 86 | return 0; |
87 | } | 87 | } |
88 | 88 | ||
89 | int ecryptfs_init_kthread(void) | 89 | int __init ecryptfs_init_kthread(void) |
90 | { | 90 | { |
91 | int rc = 0; | 91 | int rc = 0; |
92 | 92 | ||
diff --git a/fs/ecryptfs/messaging.c b/fs/ecryptfs/messaging.c index bcb68c0cb1f..ab224809051 100644 --- a/fs/ecryptfs/messaging.c +++ b/fs/ecryptfs/messaging.c | |||
@@ -473,7 +473,7 @@ sleep: | |||
473 | return rc; | 473 | return rc; |
474 | } | 474 | } |
475 | 475 | ||
476 | int ecryptfs_init_messaging(void) | 476 | int __init ecryptfs_init_messaging(void) |
477 | { | 477 | { |
478 | int i; | 478 | int i; |
479 | int rc = 0; | 479 | int rc = 0; |
diff --git a/fs/ecryptfs/miscdev.c b/fs/ecryptfs/miscdev.c index 3745f612bcd..00208c3d7e9 100644 --- a/fs/ecryptfs/miscdev.c +++ b/fs/ecryptfs/miscdev.c | |||
@@ -500,7 +500,7 @@ static struct miscdevice ecryptfs_miscdev = { | |||
500 | * | 500 | * |
501 | * Returns zero on success; non-zero otherwise | 501 | * Returns zero on success; non-zero otherwise |
502 | */ | 502 | */ |
503 | int ecryptfs_init_ecryptfs_miscdev(void) | 503 | int __init ecryptfs_init_ecryptfs_miscdev(void) |
504 | { | 504 | { |
505 | int rc; | 505 | int rc; |
506 | 506 | ||
@@ -376,6 +376,9 @@ static int count(const char __user * const __user * argv, int max) | |||
376 | argv++; | 376 | argv++; |
377 | if (i++ >= max) | 377 | if (i++ >= max) |
378 | return -E2BIG; | 378 | return -E2BIG; |
379 | |||
380 | if (fatal_signal_pending(current)) | ||
381 | return -ERESTARTNOHAND; | ||
379 | cond_resched(); | 382 | cond_resched(); |
380 | } | 383 | } |
381 | } | 384 | } |
@@ -419,6 +422,12 @@ static int copy_strings(int argc, const char __user *const __user *argv, | |||
419 | while (len > 0) { | 422 | while (len > 0) { |
420 | int offset, bytes_to_copy; | 423 | int offset, bytes_to_copy; |
421 | 424 | ||
425 | if (fatal_signal_pending(current)) { | ||
426 | ret = -ERESTARTNOHAND; | ||
427 | goto out; | ||
428 | } | ||
429 | cond_resched(); | ||
430 | |||
422 | offset = pos % PAGE_SIZE; | 431 | offset = pos % PAGE_SIZE; |
423 | if (offset == 0) | 432 | if (offset == 0) |
424 | offset = PAGE_SIZE; | 433 | offset = PAGE_SIZE; |
@@ -594,6 +603,11 @@ int setup_arg_pages(struct linux_binprm *bprm, | |||
594 | #else | 603 | #else |
595 | stack_top = arch_align_stack(stack_top); | 604 | stack_top = arch_align_stack(stack_top); |
596 | stack_top = PAGE_ALIGN(stack_top); | 605 | stack_top = PAGE_ALIGN(stack_top); |
606 | |||
607 | if (unlikely(stack_top < mmap_min_addr) || | ||
608 | unlikely(vma->vm_end - vma->vm_start >= stack_top - mmap_min_addr)) | ||
609 | return -ENOMEM; | ||
610 | |||
597 | stack_shift = vma->vm_end - stack_top; | 611 | stack_shift = vma->vm_end - stack_top; |
598 | 612 | ||
599 | bprm->p -= stack_shift; | 613 | bprm->p -= stack_shift; |
@@ -2000,3 +2014,41 @@ fail_creds: | |||
2000 | fail: | 2014 | fail: |
2001 | return; | 2015 | return; |
2002 | } | 2016 | } |
2017 | |||
2018 | /* | ||
2019 | * Core dumping helper functions. These are the only things you should | ||
2020 | * do on a core-file: use only these functions to write out all the | ||
2021 | * necessary info. | ||
2022 | */ | ||
2023 | int dump_write(struct file *file, const void *addr, int nr) | ||
2024 | { | ||
2025 | return access_ok(VERIFY_READ, addr, nr) && file->f_op->write(file, addr, nr, &file->f_pos) == nr; | ||
2026 | } | ||
2027 | |||
2028 | int dump_seek(struct file *file, loff_t off) | ||
2029 | { | ||
2030 | int ret = 1; | ||
2031 | |||
2032 | if (file->f_op->llseek && file->f_op->llseek != no_llseek) { | ||
2033 | if (file->f_op->llseek(file, off, SEEK_CUR) < 0) | ||
2034 | return 0; | ||
2035 | } else { | ||
2036 | char *buf = (char *)get_zeroed_page(GFP_KERNEL); | ||
2037 | |||
2038 | if (!buf) | ||
2039 | return 0; | ||
2040 | while (off > 0) { | ||
2041 | unsigned long n = off; | ||
2042 | |||
2043 | if (n > PAGE_SIZE) | ||
2044 | n = PAGE_SIZE; | ||
2045 | if (!dump_write(file, buf, n)) { | ||
2046 | ret = 0; | ||
2047 | break; | ||
2048 | } | ||
2049 | off -= n; | ||
2050 | } | ||
2051 | free_page((unsigned long)buf); | ||
2052 | } | ||
2053 | return ret; | ||
2054 | } | ||
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c index eb7368ebd8c..3eadd97324b 100644 --- a/fs/exofs/inode.c +++ b/fs/exofs/inode.c | |||
@@ -54,6 +54,9 @@ struct page_collect { | |||
54 | unsigned nr_pages; | 54 | unsigned nr_pages; |
55 | unsigned long length; | 55 | unsigned long length; |
56 | loff_t pg_first; /* keep 64bit also in 32-arches */ | 56 | loff_t pg_first; /* keep 64bit also in 32-arches */ |
57 | bool read_4_write; /* This means two things: that the read is sync | ||
58 | * And the pages should not be unlocked. | ||
59 | */ | ||
57 | }; | 60 | }; |
58 | 61 | ||
59 | static void _pcol_init(struct page_collect *pcol, unsigned expected_pages, | 62 | static void _pcol_init(struct page_collect *pcol, unsigned expected_pages, |
@@ -71,6 +74,7 @@ static void _pcol_init(struct page_collect *pcol, unsigned expected_pages, | |||
71 | pcol->nr_pages = 0; | 74 | pcol->nr_pages = 0; |
72 | pcol->length = 0; | 75 | pcol->length = 0; |
73 | pcol->pg_first = -1; | 76 | pcol->pg_first = -1; |
77 | pcol->read_4_write = false; | ||
74 | } | 78 | } |
75 | 79 | ||
76 | static void _pcol_reset(struct page_collect *pcol) | 80 | static void _pcol_reset(struct page_collect *pcol) |
@@ -347,7 +351,8 @@ static int readpage_strip(void *data, struct page *page) | |||
347 | if (PageError(page)) | 351 | if (PageError(page)) |
348 | ClearPageError(page); | 352 | ClearPageError(page); |
349 | 353 | ||
350 | unlock_page(page); | 354 | if (!pcol->read_4_write) |
355 | unlock_page(page); | ||
351 | EXOFS_DBGMSG("readpage_strip(0x%lx, 0x%lx) empty page," | 356 | EXOFS_DBGMSG("readpage_strip(0x%lx, 0x%lx) empty page," |
352 | " splitting\n", inode->i_ino, page->index); | 357 | " splitting\n", inode->i_ino, page->index); |
353 | 358 | ||
@@ -428,6 +433,7 @@ static int _readpage(struct page *page, bool is_sync) | |||
428 | /* readpage_strip might call read_exec(,is_sync==false) at several | 433 | /* readpage_strip might call read_exec(,is_sync==false) at several |
429 | * places but not if we have a single page. | 434 | * places but not if we have a single page. |
430 | */ | 435 | */ |
436 | pcol.read_4_write = is_sync; | ||
431 | ret = readpage_strip(&pcol, page); | 437 | ret = readpage_strip(&pcol, page); |
432 | if (ret) { | 438 | if (ret) { |
433 | EXOFS_ERR("_readpage => %d\n", ret); | 439 | EXOFS_ERR("_readpage => %d\n", ret); |
diff --git a/fs/fcntl.c b/fs/fcntl.c index 6769fd0f35b..f8cc34f542c 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c | |||
@@ -769,11 +769,15 @@ EXPORT_SYMBOL(kill_fasync); | |||
769 | 769 | ||
770 | static int __init fcntl_init(void) | 770 | static int __init fcntl_init(void) |
771 | { | 771 | { |
772 | /* please add new bits here to ensure allocation uniqueness */ | 772 | /* |
773 | BUILD_BUG_ON(19 - 1 /* for O_RDONLY being 0 */ != HWEIGHT32( | 773 | * Please add new bits here to ensure allocation uniqueness. |
774 | * Exceptions: O_NONBLOCK is a two bit define on parisc; O_NDELAY | ||
775 | * is defined as O_NONBLOCK on some platforms and not on others. | ||
776 | */ | ||
777 | BUILD_BUG_ON(18 - 1 /* for O_RDONLY being 0 */ != HWEIGHT32( | ||
774 | O_RDONLY | O_WRONLY | O_RDWR | | 778 | O_RDONLY | O_WRONLY | O_RDWR | |
775 | O_CREAT | O_EXCL | O_NOCTTY | | 779 | O_CREAT | O_EXCL | O_NOCTTY | |
776 | O_TRUNC | O_APPEND | O_NONBLOCK | | 780 | O_TRUNC | O_APPEND | /* O_NONBLOCK | */ |
777 | __O_SYNC | O_DSYNC | FASYNC | | 781 | __O_SYNC | O_DSYNC | FASYNC | |
778 | O_DIRECT | O_LARGEFILE | O_DIRECTORY | | 782 | O_DIRECT | O_LARGEFILE | O_DIRECTORY | |
779 | O_NOFOLLOW | O_NOATIME | O_CLOEXEC | | 783 | O_NOFOLLOW | O_NOATIME | O_CLOEXEC | |
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 7d9d06ba184..ab38fef1c9a 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
@@ -52,8 +52,6 @@ struct wb_writeback_work { | |||
52 | #define CREATE_TRACE_POINTS | 52 | #define CREATE_TRACE_POINTS |
53 | #include <trace/events/writeback.h> | 53 | #include <trace/events/writeback.h> |
54 | 54 | ||
55 | #define inode_to_bdi(inode) ((inode)->i_mapping->backing_dev_info) | ||
56 | |||
57 | /* | 55 | /* |
58 | * We don't actually have pdflush, but this one is exported though /proc... | 56 | * We don't actually have pdflush, but this one is exported though /proc... |
59 | */ | 57 | */ |
@@ -71,6 +69,16 @@ int writeback_in_progress(struct backing_dev_info *bdi) | |||
71 | return test_bit(BDI_writeback_running, &bdi->state); | 69 | return test_bit(BDI_writeback_running, &bdi->state); |
72 | } | 70 | } |
73 | 71 | ||
72 | static inline struct backing_dev_info *inode_to_bdi(struct inode *inode) | ||
73 | { | ||
74 | struct super_block *sb = inode->i_sb; | ||
75 | |||
76 | if (strcmp(sb->s_type->name, "bdev") == 0) | ||
77 | return inode->i_mapping->backing_dev_info; | ||
78 | |||
79 | return sb->s_bdi; | ||
80 | } | ||
81 | |||
74 | static void bdi_queue_work(struct backing_dev_info *bdi, | 82 | static void bdi_queue_work(struct backing_dev_info *bdi, |
75 | struct wb_writeback_work *work) | 83 | struct wb_writeback_work *work) |
76 | { | 84 | { |
@@ -808,7 +816,7 @@ int bdi_writeback_thread(void *data) | |||
808 | wb->last_active = jiffies; | 816 | wb->last_active = jiffies; |
809 | 817 | ||
810 | set_current_state(TASK_INTERRUPTIBLE); | 818 | set_current_state(TASK_INTERRUPTIBLE); |
811 | if (!list_empty(&bdi->work_list)) { | 819 | if (!list_empty(&bdi->work_list) || kthread_should_stop()) { |
812 | __set_current_state(TASK_RUNNING); | 820 | __set_current_state(TASK_RUNNING); |
813 | continue; | 821 | continue; |
814 | } | 822 | } |
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 69ad053ffd7..cde755cca56 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c | |||
@@ -276,7 +276,7 @@ static void flush_bg_queue(struct fuse_conn *fc) | |||
276 | * Called with fc->lock, unlocks it | 276 | * Called with fc->lock, unlocks it |
277 | */ | 277 | */ |
278 | static void request_end(struct fuse_conn *fc, struct fuse_req *req) | 278 | static void request_end(struct fuse_conn *fc, struct fuse_req *req) |
279 | __releases(&fc->lock) | 279 | __releases(fc->lock) |
280 | { | 280 | { |
281 | void (*end) (struct fuse_conn *, struct fuse_req *) = req->end; | 281 | void (*end) (struct fuse_conn *, struct fuse_req *) = req->end; |
282 | req->end = NULL; | 282 | req->end = NULL; |
@@ -306,8 +306,8 @@ __releases(&fc->lock) | |||
306 | 306 | ||
307 | static void wait_answer_interruptible(struct fuse_conn *fc, | 307 | static void wait_answer_interruptible(struct fuse_conn *fc, |
308 | struct fuse_req *req) | 308 | struct fuse_req *req) |
309 | __releases(&fc->lock) | 309 | __releases(fc->lock) |
310 | __acquires(&fc->lock) | 310 | __acquires(fc->lock) |
311 | { | 311 | { |
312 | if (signal_pending(current)) | 312 | if (signal_pending(current)) |
313 | return; | 313 | return; |
@@ -325,8 +325,8 @@ static void queue_interrupt(struct fuse_conn *fc, struct fuse_req *req) | |||
325 | } | 325 | } |
326 | 326 | ||
327 | static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req) | 327 | static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req) |
328 | __releases(&fc->lock) | 328 | __releases(fc->lock) |
329 | __acquires(&fc->lock) | 329 | __acquires(fc->lock) |
330 | { | 330 | { |
331 | if (!fc->no_interrupt) { | 331 | if (!fc->no_interrupt) { |
332 | /* Any signal may interrupt this */ | 332 | /* Any signal may interrupt this */ |
@@ -905,8 +905,8 @@ static int request_pending(struct fuse_conn *fc) | |||
905 | 905 | ||
906 | /* Wait until a request is available on the pending list */ | 906 | /* Wait until a request is available on the pending list */ |
907 | static void request_wait(struct fuse_conn *fc) | 907 | static void request_wait(struct fuse_conn *fc) |
908 | __releases(&fc->lock) | 908 | __releases(fc->lock) |
909 | __acquires(&fc->lock) | 909 | __acquires(fc->lock) |
910 | { | 910 | { |
911 | DECLARE_WAITQUEUE(wait, current); | 911 | DECLARE_WAITQUEUE(wait, current); |
912 | 912 | ||
@@ -934,7 +934,7 @@ __acquires(&fc->lock) | |||
934 | */ | 934 | */ |
935 | static int fuse_read_interrupt(struct fuse_conn *fc, struct fuse_copy_state *cs, | 935 | static int fuse_read_interrupt(struct fuse_conn *fc, struct fuse_copy_state *cs, |
936 | size_t nbytes, struct fuse_req *req) | 936 | size_t nbytes, struct fuse_req *req) |
937 | __releases(&fc->lock) | 937 | __releases(fc->lock) |
938 | { | 938 | { |
939 | struct fuse_in_header ih; | 939 | struct fuse_in_header ih; |
940 | struct fuse_interrupt_in arg; | 940 | struct fuse_interrupt_in arg; |
@@ -1354,7 +1354,7 @@ static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode, | |||
1354 | loff_t file_size; | 1354 | loff_t file_size; |
1355 | unsigned int num; | 1355 | unsigned int num; |
1356 | unsigned int offset; | 1356 | unsigned int offset; |
1357 | size_t total_len; | 1357 | size_t total_len = 0; |
1358 | 1358 | ||
1359 | req = fuse_get_req(fc); | 1359 | req = fuse_get_req(fc); |
1360 | if (IS_ERR(req)) | 1360 | if (IS_ERR(req)) |
@@ -1720,8 +1720,8 @@ static unsigned fuse_dev_poll(struct file *file, poll_table *wait) | |||
1720 | * This function releases and reacquires fc->lock | 1720 | * This function releases and reacquires fc->lock |
1721 | */ | 1721 | */ |
1722 | static void end_requests(struct fuse_conn *fc, struct list_head *head) | 1722 | static void end_requests(struct fuse_conn *fc, struct list_head *head) |
1723 | __releases(&fc->lock) | 1723 | __releases(fc->lock) |
1724 | __acquires(&fc->lock) | 1724 | __acquires(fc->lock) |
1725 | { | 1725 | { |
1726 | while (!list_empty(head)) { | 1726 | while (!list_empty(head)) { |
1727 | struct fuse_req *req; | 1727 | struct fuse_req *req; |
@@ -1744,8 +1744,8 @@ __acquires(&fc->lock) | |||
1744 | * locked). | 1744 | * locked). |
1745 | */ | 1745 | */ |
1746 | static void end_io_requests(struct fuse_conn *fc) | 1746 | static void end_io_requests(struct fuse_conn *fc) |
1747 | __releases(&fc->lock) | 1747 | __releases(fc->lock) |
1748 | __acquires(&fc->lock) | 1748 | __acquires(fc->lock) |
1749 | { | 1749 | { |
1750 | while (!list_empty(&fc->io)) { | 1750 | while (!list_empty(&fc->io)) { |
1751 | struct fuse_req *req = | 1751 | struct fuse_req *req = |
@@ -1769,6 +1769,16 @@ __acquires(&fc->lock) | |||
1769 | } | 1769 | } |
1770 | } | 1770 | } |
1771 | 1771 | ||
1772 | static void end_queued_requests(struct fuse_conn *fc) | ||
1773 | __releases(fc->lock) | ||
1774 | __acquires(fc->lock) | ||
1775 | { | ||
1776 | fc->max_background = UINT_MAX; | ||
1777 | flush_bg_queue(fc); | ||
1778 | end_requests(fc, &fc->pending); | ||
1779 | end_requests(fc, &fc->processing); | ||
1780 | } | ||
1781 | |||
1772 | /* | 1782 | /* |
1773 | * Abort all requests. | 1783 | * Abort all requests. |
1774 | * | 1784 | * |
@@ -1795,8 +1805,7 @@ void fuse_abort_conn(struct fuse_conn *fc) | |||
1795 | fc->connected = 0; | 1805 | fc->connected = 0; |
1796 | fc->blocked = 0; | 1806 | fc->blocked = 0; |
1797 | end_io_requests(fc); | 1807 | end_io_requests(fc); |
1798 | end_requests(fc, &fc->pending); | 1808 | end_queued_requests(fc); |
1799 | end_requests(fc, &fc->processing); | ||
1800 | wake_up_all(&fc->waitq); | 1809 | wake_up_all(&fc->waitq); |
1801 | wake_up_all(&fc->blocked_waitq); | 1810 | wake_up_all(&fc->blocked_waitq); |
1802 | kill_fasync(&fc->fasync, SIGIO, POLL_IN); | 1811 | kill_fasync(&fc->fasync, SIGIO, POLL_IN); |
@@ -1811,8 +1820,9 @@ int fuse_dev_release(struct inode *inode, struct file *file) | |||
1811 | if (fc) { | 1820 | if (fc) { |
1812 | spin_lock(&fc->lock); | 1821 | spin_lock(&fc->lock); |
1813 | fc->connected = 0; | 1822 | fc->connected = 0; |
1814 | end_requests(fc, &fc->pending); | 1823 | fc->blocked = 0; |
1815 | end_requests(fc, &fc->processing); | 1824 | end_queued_requests(fc); |
1825 | wake_up_all(&fc->blocked_waitq); | ||
1816 | spin_unlock(&fc->lock); | 1826 | spin_unlock(&fc->lock); |
1817 | fuse_conn_put(fc); | 1827 | fuse_conn_put(fc); |
1818 | } | 1828 | } |
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 147c1f71bdb..c8224587123 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
@@ -1144,8 +1144,8 @@ static void fuse_writepage_finish(struct fuse_conn *fc, struct fuse_req *req) | |||
1144 | 1144 | ||
1145 | /* Called under fc->lock, may release and reacquire it */ | 1145 | /* Called under fc->lock, may release and reacquire it */ |
1146 | static void fuse_send_writepage(struct fuse_conn *fc, struct fuse_req *req) | 1146 | static void fuse_send_writepage(struct fuse_conn *fc, struct fuse_req *req) |
1147 | __releases(&fc->lock) | 1147 | __releases(fc->lock) |
1148 | __acquires(&fc->lock) | 1148 | __acquires(fc->lock) |
1149 | { | 1149 | { |
1150 | struct fuse_inode *fi = get_fuse_inode(req->inode); | 1150 | struct fuse_inode *fi = get_fuse_inode(req->inode); |
1151 | loff_t size = i_size_read(req->inode); | 1151 | loff_t size = i_size_read(req->inode); |
@@ -1183,8 +1183,8 @@ __acquires(&fc->lock) | |||
1183 | * Called with fc->lock | 1183 | * Called with fc->lock |
1184 | */ | 1184 | */ |
1185 | void fuse_flush_writepages(struct inode *inode) | 1185 | void fuse_flush_writepages(struct inode *inode) |
1186 | __releases(&fc->lock) | 1186 | __releases(fc->lock) |
1187 | __acquires(&fc->lock) | 1187 | __acquires(fc->lock) |
1188 | { | 1188 | { |
1189 | struct fuse_conn *fc = get_fuse_conn(inode); | 1189 | struct fuse_conn *fc = get_fuse_conn(inode); |
1190 | struct fuse_inode *fi = get_fuse_inode(inode); | 1190 | struct fuse_inode *fi = get_fuse_inode(inode); |
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 9c65170e932..eb01f3575e1 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c | |||
@@ -923,7 +923,7 @@ int gfs2_logd(void *data) | |||
923 | 923 | ||
924 | do { | 924 | do { |
925 | prepare_to_wait(&sdp->sd_logd_waitq, &wait, | 925 | prepare_to_wait(&sdp->sd_logd_waitq, &wait, |
926 | TASK_UNINTERRUPTIBLE); | 926 | TASK_INTERRUPTIBLE); |
927 | if (!gfs2_ail_flush_reqd(sdp) && | 927 | if (!gfs2_ail_flush_reqd(sdp) && |
928 | !gfs2_jrnl_flush_reqd(sdp) && | 928 | !gfs2_jrnl_flush_reqd(sdp) && |
929 | !kthread_should_stop()) | 929 | !kthread_should_stop()) |
diff --git a/fs/minix/namei.c b/fs/minix/namei.c index e20ee85955d..f3f3578393a 100644 --- a/fs/minix/namei.c +++ b/fs/minix/namei.c | |||
@@ -115,7 +115,7 @@ static int minix_mkdir(struct inode * dir, struct dentry *dentry, int mode) | |||
115 | 115 | ||
116 | inode_inc_link_count(dir); | 116 | inode_inc_link_count(dir); |
117 | 117 | ||
118 | inode = minix_new_inode(dir, mode, &err); | 118 | inode = minix_new_inode(dir, S_IFDIR | mode, &err); |
119 | if (!inode) | 119 | if (!inode) |
120 | goto out_dir; | 120 | goto out_dir; |
121 | 121 | ||
diff --git a/fs/namespace.c b/fs/namespace.c index de402eb6eaf..a72eaabfe8f 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -1484,13 +1484,30 @@ out_unlock: | |||
1484 | } | 1484 | } |
1485 | 1485 | ||
1486 | /* | 1486 | /* |
1487 | * Sanity check the flags to change_mnt_propagation. | ||
1488 | */ | ||
1489 | |||
1490 | static int flags_to_propagation_type(int flags) | ||
1491 | { | ||
1492 | int type = flags & ~MS_REC; | ||
1493 | |||
1494 | /* Fail if any non-propagation flags are set */ | ||
1495 | if (type & ~(MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE)) | ||
1496 | return 0; | ||
1497 | /* Only one propagation flag should be set */ | ||
1498 | if (!is_power_of_2(type)) | ||
1499 | return 0; | ||
1500 | return type; | ||
1501 | } | ||
1502 | |||
1503 | /* | ||
1487 | * recursively change the type of the mountpoint. | 1504 | * recursively change the type of the mountpoint. |
1488 | */ | 1505 | */ |
1489 | static int do_change_type(struct path *path, int flag) | 1506 | static int do_change_type(struct path *path, int flag) |
1490 | { | 1507 | { |
1491 | struct vfsmount *m, *mnt = path->mnt; | 1508 | struct vfsmount *m, *mnt = path->mnt; |
1492 | int recurse = flag & MS_REC; | 1509 | int recurse = flag & MS_REC; |
1493 | int type = flag & ~MS_REC; | 1510 | int type; |
1494 | int err = 0; | 1511 | int err = 0; |
1495 | 1512 | ||
1496 | if (!capable(CAP_SYS_ADMIN)) | 1513 | if (!capable(CAP_SYS_ADMIN)) |
@@ -1499,6 +1516,10 @@ static int do_change_type(struct path *path, int flag) | |||
1499 | if (path->dentry != path->mnt->mnt_root) | 1516 | if (path->dentry != path->mnt->mnt_root) |
1500 | return -EINVAL; | 1517 | return -EINVAL; |
1501 | 1518 | ||
1519 | type = flags_to_propagation_type(flag); | ||
1520 | if (!type) | ||
1521 | return -EINVAL; | ||
1522 | |||
1502 | down_write(&namespace_sem); | 1523 | down_write(&namespace_sem); |
1503 | if (type == MS_SHARED) { | 1524 | if (type == MS_SHARED) { |
1504 | err = invent_group_ids(mnt, recurse); | 1525 | err = invent_group_ids(mnt, recurse); |
diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig index 6c2aad49d73..f7e13db613c 100644 --- a/fs/nfs/Kconfig +++ b/fs/nfs/Kconfig | |||
@@ -63,6 +63,7 @@ config NFS_V3_ACL | |||
63 | config NFS_V4 | 63 | config NFS_V4 |
64 | bool "NFS client support for NFS version 4" | 64 | bool "NFS client support for NFS version 4" |
65 | depends on NFS_FS | 65 | depends on NFS_FS |
66 | select SUNRPC_GSS | ||
66 | help | 67 | help |
67 | This option enables support for version 4 of the NFS protocol | 68 | This option enables support for version 4 of the NFS protocol |
68 | (RFC 3530) in the kernel's NFS client. | 69 | (RFC 3530) in the kernel's NFS client. |
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 4e7df2adb21..e7340729af8 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
@@ -275,7 +275,7 @@ static int nfs_sockaddr_match_ipaddr6(const struct sockaddr *sa1, | |||
275 | sin1->sin6_scope_id != sin2->sin6_scope_id) | 275 | sin1->sin6_scope_id != sin2->sin6_scope_id) |
276 | return 0; | 276 | return 0; |
277 | 277 | ||
278 | return ipv6_addr_equal(&sin1->sin6_addr, &sin1->sin6_addr); | 278 | return ipv6_addr_equal(&sin1->sin6_addr, &sin2->sin6_addr); |
279 | } | 279 | } |
280 | #else /* !defined(CONFIG_IPV6) && !defined(CONFIG_IPV6_MODULE) */ | 280 | #else /* !defined(CONFIG_IPV6) && !defined(CONFIG_IPV6_MODULE) */ |
281 | static int nfs_sockaddr_match_ipaddr6(const struct sockaddr *sa1, | 281 | static int nfs_sockaddr_match_ipaddr6(const struct sockaddr *sa1, |
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index eb51bd6201d..05bf3c0dc75 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c | |||
@@ -723,10 +723,6 @@ static int do_vfs_lock(struct file *file, struct file_lock *fl) | |||
723 | default: | 723 | default: |
724 | BUG(); | 724 | BUG(); |
725 | } | 725 | } |
726 | if (res < 0) | ||
727 | dprintk(KERN_WARNING "%s: VFS is out of sync with lock manager" | ||
728 | " - error %d!\n", | ||
729 | __func__, res); | ||
730 | return res; | 726 | return res; |
731 | } | 727 | } |
732 | 728 | ||
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index ec3966e4706..f4cbf0c306c 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -431,7 +431,15 @@ static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
431 | goto out_err; | 431 | goto out_err; |
432 | 432 | ||
433 | error = server->nfs_client->rpc_ops->statfs(server, fh, &res); | 433 | error = server->nfs_client->rpc_ops->statfs(server, fh, &res); |
434 | if (unlikely(error == -ESTALE)) { | ||
435 | struct dentry *pd_dentry; | ||
434 | 436 | ||
437 | pd_dentry = dget_parent(dentry); | ||
438 | if (pd_dentry != NULL) { | ||
439 | nfs_zap_caches(pd_dentry->d_inode); | ||
440 | dput(pd_dentry); | ||
441 | } | ||
442 | } | ||
435 | nfs_free_fattr(res.fattr); | 443 | nfs_free_fattr(res.fattr); |
436 | if (error < 0) | 444 | if (error < 0) |
437 | goto out_err; | 445 | goto out_err; |
diff --git a/fs/nfsd/Kconfig b/fs/nfsd/Kconfig index 95932f523ae..4264377552e 100644 --- a/fs/nfsd/Kconfig +++ b/fs/nfsd/Kconfig | |||
@@ -69,6 +69,7 @@ config NFSD_V4 | |||
69 | depends on NFSD && PROC_FS && EXPERIMENTAL | 69 | depends on NFSD && PROC_FS && EXPERIMENTAL |
70 | select NFSD_V3 | 70 | select NFSD_V3 |
71 | select FS_POSIX_ACL | 71 | select FS_POSIX_ACL |
72 | select SUNRPC_GSS | ||
72 | help | 73 | help |
73 | This option enables support in your system's NFS server for | 74 | This option enables support in your system's NFS server for |
74 | version 4 of the NFS protocol (RFC 3530). | 75 | version 4 of the NFS protocol (RFC 3530). |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 2e7357104cf..cf0d2ffb3c8 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -440,7 +440,7 @@ test_share(struct nfs4_stateid *stp, struct nfsd4_open *open) { | |||
440 | 440 | ||
441 | static int nfs4_access_to_omode(u32 access) | 441 | static int nfs4_access_to_omode(u32 access) |
442 | { | 442 | { |
443 | switch (access) { | 443 | switch (access & NFS4_SHARE_ACCESS_BOTH) { |
444 | case NFS4_SHARE_ACCESS_READ: | 444 | case NFS4_SHARE_ACCESS_READ: |
445 | return O_RDONLY; | 445 | return O_RDONLY; |
446 | case NFS4_SHARE_ACCESS_WRITE: | 446 | case NFS4_SHARE_ACCESS_WRITE: |
@@ -2450,14 +2450,13 @@ nfsd4_truncate(struct svc_rqst *rqstp, struct svc_fh *fh, | |||
2450 | static __be32 | 2450 | static __be32 |
2451 | nfs4_upgrade_open(struct svc_rqst *rqstp, struct nfs4_file *fp, struct svc_fh *cur_fh, struct nfs4_stateid *stp, struct nfsd4_open *open) | 2451 | nfs4_upgrade_open(struct svc_rqst *rqstp, struct nfs4_file *fp, struct svc_fh *cur_fh, struct nfs4_stateid *stp, struct nfsd4_open *open) |
2452 | { | 2452 | { |
2453 | u32 op_share_access, new_access; | 2453 | u32 op_share_access = open->op_share_access & ~NFS4_SHARE_WANT_MASK; |
2454 | bool new_access; | ||
2454 | __be32 status; | 2455 | __be32 status; |
2455 | 2456 | ||
2456 | set_access(&new_access, stp->st_access_bmap); | 2457 | new_access = !test_bit(op_share_access, &stp->st_access_bmap); |
2457 | new_access = (~new_access) & open->op_share_access & ~NFS4_SHARE_WANT_MASK; | ||
2458 | |||
2459 | if (new_access) { | 2458 | if (new_access) { |
2460 | status = nfs4_get_vfs_file(rqstp, fp, cur_fh, new_access); | 2459 | status = nfs4_get_vfs_file(rqstp, fp, cur_fh, op_share_access); |
2461 | if (status) | 2460 | if (status) |
2462 | return status; | 2461 | return status; |
2463 | } | 2462 | } |
@@ -2470,7 +2469,6 @@ nfs4_upgrade_open(struct svc_rqst *rqstp, struct nfs4_file *fp, struct svc_fh *c | |||
2470 | return status; | 2469 | return status; |
2471 | } | 2470 | } |
2472 | /* remember the open */ | 2471 | /* remember the open */ |
2473 | op_share_access = open->op_share_access & ~NFS4_SHARE_WANT_MASK; | ||
2474 | __set_bit(op_share_access, &stp->st_access_bmap); | 2472 | __set_bit(op_share_access, &stp->st_access_bmap); |
2475 | __set_bit(open->op_share_deny, &stp->st_deny_bmap); | 2473 | __set_bit(open->op_share_deny, &stp->st_deny_bmap); |
2476 | 2474 | ||
@@ -2983,7 +2981,6 @@ nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate, | |||
2983 | *filpp = find_readable_file(stp->st_file); | 2981 | *filpp = find_readable_file(stp->st_file); |
2984 | else | 2982 | else |
2985 | *filpp = find_writeable_file(stp->st_file); | 2983 | *filpp = find_writeable_file(stp->st_file); |
2986 | BUG_ON(!*filpp); /* assured by check_openmode */ | ||
2987 | } | 2984 | } |
2988 | } | 2985 | } |
2989 | status = nfs_ok; | 2986 | status = nfs_ok; |
@@ -3561,7 +3558,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
3561 | struct nfs4_stateowner *open_sop = NULL; | 3558 | struct nfs4_stateowner *open_sop = NULL; |
3562 | struct nfs4_stateowner *lock_sop = NULL; | 3559 | struct nfs4_stateowner *lock_sop = NULL; |
3563 | struct nfs4_stateid *lock_stp; | 3560 | struct nfs4_stateid *lock_stp; |
3564 | struct file *filp; | 3561 | struct nfs4_file *fp; |
3562 | struct file *filp = NULL; | ||
3565 | struct file_lock file_lock; | 3563 | struct file_lock file_lock; |
3566 | struct file_lock conflock; | 3564 | struct file_lock conflock; |
3567 | __be32 status = 0; | 3565 | __be32 status = 0; |
@@ -3591,7 +3589,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
3591 | * lock stateid. | 3589 | * lock stateid. |
3592 | */ | 3590 | */ |
3593 | struct nfs4_stateid *open_stp = NULL; | 3591 | struct nfs4_stateid *open_stp = NULL; |
3594 | struct nfs4_file *fp; | ||
3595 | 3592 | ||
3596 | status = nfserr_stale_clientid; | 3593 | status = nfserr_stale_clientid; |
3597 | if (!nfsd4_has_session(cstate) && | 3594 | if (!nfsd4_has_session(cstate) && |
@@ -3634,6 +3631,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
3634 | if (status) | 3631 | if (status) |
3635 | goto out; | 3632 | goto out; |
3636 | lock_sop = lock->lk_replay_owner; | 3633 | lock_sop = lock->lk_replay_owner; |
3634 | fp = lock_stp->st_file; | ||
3637 | } | 3635 | } |
3638 | /* lock->lk_replay_owner and lock_stp have been created or found */ | 3636 | /* lock->lk_replay_owner and lock_stp have been created or found */ |
3639 | 3637 | ||
@@ -3648,13 +3646,19 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
3648 | switch (lock->lk_type) { | 3646 | switch (lock->lk_type) { |
3649 | case NFS4_READ_LT: | 3647 | case NFS4_READ_LT: |
3650 | case NFS4_READW_LT: | 3648 | case NFS4_READW_LT: |
3651 | filp = find_readable_file(lock_stp->st_file); | 3649 | if (find_readable_file(lock_stp->st_file)) { |
3650 | nfs4_get_vfs_file(rqstp, fp, &cstate->current_fh, NFS4_SHARE_ACCESS_READ); | ||
3651 | filp = find_readable_file(lock_stp->st_file); | ||
3652 | } | ||
3652 | file_lock.fl_type = F_RDLCK; | 3653 | file_lock.fl_type = F_RDLCK; |
3653 | cmd = F_SETLK; | 3654 | cmd = F_SETLK; |
3654 | break; | 3655 | break; |
3655 | case NFS4_WRITE_LT: | 3656 | case NFS4_WRITE_LT: |
3656 | case NFS4_WRITEW_LT: | 3657 | case NFS4_WRITEW_LT: |
3657 | filp = find_writeable_file(lock_stp->st_file); | 3658 | if (find_writeable_file(lock_stp->st_file)) { |
3659 | nfs4_get_vfs_file(rqstp, fp, &cstate->current_fh, NFS4_SHARE_ACCESS_WRITE); | ||
3660 | filp = find_writeable_file(lock_stp->st_file); | ||
3661 | } | ||
3658 | file_lock.fl_type = F_WRLCK; | 3662 | file_lock.fl_type = F_WRLCK; |
3659 | cmd = F_SETLK; | 3663 | cmd = F_SETLK; |
3660 | break; | 3664 | break; |
diff --git a/fs/nfsd/nfsfh.h b/fs/nfsd/nfsfh.h index cdfb8c6a420..c16f8d8331b 100644 --- a/fs/nfsd/nfsfh.h +++ b/fs/nfsd/nfsfh.h | |||
@@ -196,8 +196,6 @@ fh_lock(struct svc_fh *fhp) | |||
196 | static inline void | 196 | static inline void |
197 | fh_unlock(struct svc_fh *fhp) | 197 | fh_unlock(struct svc_fh *fhp) |
198 | { | 198 | { |
199 | BUG_ON(!fhp->fh_dentry); | ||
200 | |||
201 | if (fhp->fh_locked) { | 199 | if (fhp->fh_locked) { |
202 | fill_post_wcc(fhp); | 200 | fill_post_wcc(fhp); |
203 | mutex_unlock(&fhp->fh_dentry->d_inode->i_mutex); | 201 | mutex_unlock(&fhp->fh_dentry->d_inode->i_mutex); |
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 7731a75971d..322518c88e4 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h | |||
@@ -363,23 +363,23 @@ struct nfs4_file { | |||
363 | * at all? */ | 363 | * at all? */ |
364 | static inline struct file *find_writeable_file(struct nfs4_file *f) | 364 | static inline struct file *find_writeable_file(struct nfs4_file *f) |
365 | { | 365 | { |
366 | if (f->fi_fds[O_RDWR]) | 366 | if (f->fi_fds[O_WRONLY]) |
367 | return f->fi_fds[O_RDWR]; | 367 | return f->fi_fds[O_WRONLY]; |
368 | return f->fi_fds[O_WRONLY]; | 368 | return f->fi_fds[O_RDWR]; |
369 | } | 369 | } |
370 | 370 | ||
371 | static inline struct file *find_readable_file(struct nfs4_file *f) | 371 | static inline struct file *find_readable_file(struct nfs4_file *f) |
372 | { | 372 | { |
373 | if (f->fi_fds[O_RDWR]) | 373 | if (f->fi_fds[O_RDONLY]) |
374 | return f->fi_fds[O_RDWR]; | 374 | return f->fi_fds[O_RDONLY]; |
375 | return f->fi_fds[O_RDONLY]; | 375 | return f->fi_fds[O_RDWR]; |
376 | } | 376 | } |
377 | 377 | ||
378 | static inline struct file *find_any_file(struct nfs4_file *f) | 378 | static inline struct file *find_any_file(struct nfs4_file *f) |
379 | { | 379 | { |
380 | if (f->fi_fds[O_RDWR]) | 380 | if (f->fi_fds[O_RDWR]) |
381 | return f->fi_fds[O_RDWR]; | 381 | return f->fi_fds[O_RDWR]; |
382 | else if (f->fi_fds[O_RDWR]) | 382 | else if (f->fi_fds[O_WRONLY]) |
383 | return f->fi_fds[O_WRONLY]; | 383 | return f->fi_fds[O_WRONLY]; |
384 | else | 384 | else |
385 | return f->fi_fds[O_RDONLY]; | 385 | return f->fi_fds[O_RDONLY]; |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 96360a83cb9..661a6cf8e82 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -2033,15 +2033,17 @@ out: | |||
2033 | __be32 | 2033 | __be32 |
2034 | nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat, int access) | 2034 | nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat, int access) |
2035 | { | 2035 | { |
2036 | struct path path = { | ||
2037 | .mnt = fhp->fh_export->ex_path.mnt, | ||
2038 | .dentry = fhp->fh_dentry, | ||
2039 | }; | ||
2040 | __be32 err; | 2036 | __be32 err; |
2041 | 2037 | ||
2042 | err = fh_verify(rqstp, fhp, 0, NFSD_MAY_NOP | access); | 2038 | err = fh_verify(rqstp, fhp, 0, NFSD_MAY_NOP | access); |
2043 | if (!err && vfs_statfs(&path, stat)) | 2039 | if (!err) { |
2044 | err = nfserr_io; | 2040 | struct path path = { |
2041 | .mnt = fhp->fh_export->ex_path.mnt, | ||
2042 | .dentry = fhp->fh_dentry, | ||
2043 | }; | ||
2044 | if (vfs_statfs(&path, stat)) | ||
2045 | err = nfserr_io; | ||
2046 | } | ||
2045 | return err; | 2047 | return err; |
2046 | } | 2048 | } |
2047 | 2049 | ||
diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c index d97310f07be..d2771510337 100644 --- a/fs/nilfs2/the_nilfs.c +++ b/fs/nilfs2/the_nilfs.c | |||
@@ -446,6 +446,7 @@ int load_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi) | |||
446 | nilfs_mdt_destroy(nilfs->ns_cpfile); | 446 | nilfs_mdt_destroy(nilfs->ns_cpfile); |
447 | nilfs_mdt_destroy(nilfs->ns_sufile); | 447 | nilfs_mdt_destroy(nilfs->ns_sufile); |
448 | nilfs_mdt_destroy(nilfs->ns_dat); | 448 | nilfs_mdt_destroy(nilfs->ns_dat); |
449 | nilfs_mdt_destroy(nilfs->ns_gc_dat); | ||
449 | 450 | ||
450 | failed: | 451 | failed: |
451 | nilfs_clear_recovery_info(&ri); | 452 | nilfs_clear_recovery_info(&ri); |
diff --git a/fs/notify/Kconfig b/fs/notify/Kconfig index 22c629eedd8..b388443c3a0 100644 --- a/fs/notify/Kconfig +++ b/fs/notify/Kconfig | |||
@@ -3,4 +3,4 @@ config FSNOTIFY | |||
3 | 3 | ||
4 | source "fs/notify/dnotify/Kconfig" | 4 | source "fs/notify/dnotify/Kconfig" |
5 | source "fs/notify/inotify/Kconfig" | 5 | source "fs/notify/inotify/Kconfig" |
6 | source "fs/notify/fanotify/Kconfig" | 6 | #source "fs/notify/fanotify/Kconfig" |
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 756566fe844..85366c78cc3 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c | |||
@@ -165,9 +165,6 @@ static bool fanotify_should_send_event(struct fsnotify_group *group, | |||
165 | "mask=%x data=%p data_type=%d\n", __func__, group, to_tell, | 165 | "mask=%x data=%p data_type=%d\n", __func__, group, to_tell, |
166 | inode_mark, vfsmnt_mark, event_mask, data, data_type); | 166 | inode_mark, vfsmnt_mark, event_mask, data, data_type); |
167 | 167 | ||
168 | pr_debug("%s: group=%p vfsmount_mark=%p inode_mark=%p mask=%x\n", | ||
169 | __func__, group, vfsmnt_mark, inode_mark, event_mask); | ||
170 | |||
171 | /* sorry, fanotify only gives a damn about files and dirs */ | 168 | /* sorry, fanotify only gives a damn about files and dirs */ |
172 | if (!S_ISREG(to_tell->i_mode) && | 169 | if (!S_ISREG(to_tell->i_mode) && |
173 | !S_ISDIR(to_tell->i_mode)) | 170 | !S_ISDIR(to_tell->i_mode)) |
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 032b837fcd1..5ed8e58d7bf 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c | |||
@@ -195,6 +195,14 @@ static int prepare_for_access_response(struct fsnotify_group *group, | |||
195 | re->fd = fd; | 195 | re->fd = fd; |
196 | 196 | ||
197 | mutex_lock(&group->fanotify_data.access_mutex); | 197 | mutex_lock(&group->fanotify_data.access_mutex); |
198 | |||
199 | if (group->fanotify_data.bypass_perm) { | ||
200 | mutex_unlock(&group->fanotify_data.access_mutex); | ||
201 | kmem_cache_free(fanotify_response_event_cache, re); | ||
202 | event->response = FAN_ALLOW; | ||
203 | return 0; | ||
204 | } | ||
205 | |||
198 | list_add_tail(&re->list, &group->fanotify_data.access_list); | 206 | list_add_tail(&re->list, &group->fanotify_data.access_list); |
199 | mutex_unlock(&group->fanotify_data.access_mutex); | 207 | mutex_unlock(&group->fanotify_data.access_mutex); |
200 | 208 | ||
@@ -364,9 +372,28 @@ static ssize_t fanotify_write(struct file *file, const char __user *buf, size_t | |||
364 | static int fanotify_release(struct inode *ignored, struct file *file) | 372 | static int fanotify_release(struct inode *ignored, struct file *file) |
365 | { | 373 | { |
366 | struct fsnotify_group *group = file->private_data; | 374 | struct fsnotify_group *group = file->private_data; |
375 | struct fanotify_response_event *re, *lre; | ||
367 | 376 | ||
368 | pr_debug("%s: file=%p group=%p\n", __func__, file, group); | 377 | pr_debug("%s: file=%p group=%p\n", __func__, file, group); |
369 | 378 | ||
379 | #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS | ||
380 | mutex_lock(&group->fanotify_data.access_mutex); | ||
381 | |||
382 | group->fanotify_data.bypass_perm = true; | ||
383 | |||
384 | list_for_each_entry_safe(re, lre, &group->fanotify_data.access_list, list) { | ||
385 | pr_debug("%s: found group=%p re=%p event=%p\n", __func__, group, | ||
386 | re, re->event); | ||
387 | |||
388 | list_del_init(&re->list); | ||
389 | re->event->response = FAN_ALLOW; | ||
390 | |||
391 | kmem_cache_free(fanotify_response_event_cache, re); | ||
392 | } | ||
393 | mutex_unlock(&group->fanotify_data.access_mutex); | ||
394 | |||
395 | wake_up(&group->fanotify_data.access_waitq); | ||
396 | #endif | ||
370 | /* matches the fanotify_init->fsnotify_alloc_group */ | 397 | /* matches the fanotify_init->fsnotify_alloc_group */ |
371 | fsnotify_put_group(group); | 398 | fsnotify_put_group(group); |
372 | 399 | ||
@@ -614,7 +641,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) | |||
614 | __func__, flags, event_f_flags); | 641 | __func__, flags, event_f_flags); |
615 | 642 | ||
616 | if (!capable(CAP_SYS_ADMIN)) | 643 | if (!capable(CAP_SYS_ADMIN)) |
617 | return -EACCES; | 644 | return -EPERM; |
618 | 645 | ||
619 | if (flags & ~FAN_ALL_INIT_FLAGS) | 646 | if (flags & ~FAN_ALL_INIT_FLAGS) |
620 | return -EINVAL; | 647 | return -EINVAL; |
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index 3970392b272..36802420d69 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c | |||
@@ -148,13 +148,14 @@ static int send_to_group(struct inode *to_tell, struct vfsmount *mnt, | |||
148 | const unsigned char *file_name, | 148 | const unsigned char *file_name, |
149 | struct fsnotify_event **event) | 149 | struct fsnotify_event **event) |
150 | { | 150 | { |
151 | struct fsnotify_group *group = inode_mark->group; | 151 | struct fsnotify_group *group = NULL; |
152 | __u32 inode_test_mask = (mask & ~FS_EVENT_ON_CHILD); | 152 | __u32 inode_test_mask = 0; |
153 | __u32 vfsmount_test_mask = (mask & ~FS_EVENT_ON_CHILD); | 153 | __u32 vfsmount_test_mask = 0; |
154 | 154 | ||
155 | pr_debug("%s: group=%p to_tell=%p mnt=%p mark=%p mask=%x data=%p" | 155 | if (unlikely(!inode_mark && !vfsmount_mark)) { |
156 | " data_is=%d cookie=%d event=%p\n", __func__, group, to_tell, | 156 | BUG(); |
157 | mnt, inode_mark, mask, data, data_is, cookie, *event); | 157 | return 0; |
158 | } | ||
158 | 159 | ||
159 | /* clear ignored on inode modification */ | 160 | /* clear ignored on inode modification */ |
160 | if (mask & FS_MODIFY) { | 161 | if (mask & FS_MODIFY) { |
@@ -168,18 +169,29 @@ static int send_to_group(struct inode *to_tell, struct vfsmount *mnt, | |||
168 | 169 | ||
169 | /* does the inode mark tell us to do something? */ | 170 | /* does the inode mark tell us to do something? */ |
170 | if (inode_mark) { | 171 | if (inode_mark) { |
172 | group = inode_mark->group; | ||
173 | inode_test_mask = (mask & ~FS_EVENT_ON_CHILD); | ||
171 | inode_test_mask &= inode_mark->mask; | 174 | inode_test_mask &= inode_mark->mask; |
172 | inode_test_mask &= ~inode_mark->ignored_mask; | 175 | inode_test_mask &= ~inode_mark->ignored_mask; |
173 | } | 176 | } |
174 | 177 | ||
175 | /* does the vfsmount_mark tell us to do something? */ | 178 | /* does the vfsmount_mark tell us to do something? */ |
176 | if (vfsmount_mark) { | 179 | if (vfsmount_mark) { |
180 | vfsmount_test_mask = (mask & ~FS_EVENT_ON_CHILD); | ||
181 | group = vfsmount_mark->group; | ||
177 | vfsmount_test_mask &= vfsmount_mark->mask; | 182 | vfsmount_test_mask &= vfsmount_mark->mask; |
178 | vfsmount_test_mask &= ~vfsmount_mark->ignored_mask; | 183 | vfsmount_test_mask &= ~vfsmount_mark->ignored_mask; |
179 | if (inode_mark) | 184 | if (inode_mark) |
180 | vfsmount_test_mask &= ~inode_mark->ignored_mask; | 185 | vfsmount_test_mask &= ~inode_mark->ignored_mask; |
181 | } | 186 | } |
182 | 187 | ||
188 | pr_debug("%s: group=%p to_tell=%p mnt=%p mask=%x inode_mark=%p" | ||
189 | " inode_test_mask=%x vfsmount_mark=%p vfsmount_test_mask=%x" | ||
190 | " data=%p data_is=%d cookie=%d event=%p\n", | ||
191 | __func__, group, to_tell, mnt, mask, inode_mark, | ||
192 | inode_test_mask, vfsmount_mark, vfsmount_test_mask, data, | ||
193 | data_is, cookie, *event); | ||
194 | |||
183 | if (!inode_test_mask && !vfsmount_test_mask) | 195 | if (!inode_test_mask && !vfsmount_test_mask) |
184 | return 0; | 196 | return 0; |
185 | 197 | ||
@@ -207,13 +219,12 @@ static int send_to_group(struct inode *to_tell, struct vfsmount *mnt, | |||
207 | int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, | 219 | int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, |
208 | const unsigned char *file_name, u32 cookie) | 220 | const unsigned char *file_name, u32 cookie) |
209 | { | 221 | { |
210 | struct hlist_node *inode_node, *vfsmount_node; | 222 | struct hlist_node *inode_node = NULL, *vfsmount_node = NULL; |
211 | struct fsnotify_mark *inode_mark = NULL, *vfsmount_mark = NULL; | 223 | struct fsnotify_mark *inode_mark = NULL, *vfsmount_mark = NULL; |
212 | struct fsnotify_group *inode_group, *vfsmount_group; | 224 | struct fsnotify_group *inode_group, *vfsmount_group; |
213 | struct fsnotify_event *event = NULL; | 225 | struct fsnotify_event *event = NULL; |
214 | struct vfsmount *mnt; | 226 | struct vfsmount *mnt; |
215 | int idx, ret = 0; | 227 | int idx, ret = 0; |
216 | bool used_inode = false, used_vfsmount = false; | ||
217 | /* global tests shouldn't care about events on child only the specific event */ | 228 | /* global tests shouldn't care about events on child only the specific event */ |
218 | __u32 test_mask = (mask & ~FS_EVENT_ON_CHILD); | 229 | __u32 test_mask = (mask & ~FS_EVENT_ON_CHILD); |
219 | 230 | ||
@@ -238,57 +249,50 @@ int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, | |||
238 | (test_mask & to_tell->i_fsnotify_mask)) | 249 | (test_mask & to_tell->i_fsnotify_mask)) |
239 | inode_node = srcu_dereference(to_tell->i_fsnotify_marks.first, | 250 | inode_node = srcu_dereference(to_tell->i_fsnotify_marks.first, |
240 | &fsnotify_mark_srcu); | 251 | &fsnotify_mark_srcu); |
241 | else | ||
242 | inode_node = NULL; | ||
243 | 252 | ||
244 | if (mnt) { | 253 | if (mnt && ((mask & FS_MODIFY) || |
245 | if ((mask & FS_MODIFY) || | 254 | (test_mask & mnt->mnt_fsnotify_mask))) { |
246 | (test_mask & mnt->mnt_fsnotify_mask)) | 255 | vfsmount_node = srcu_dereference(mnt->mnt_fsnotify_marks.first, |
247 | vfsmount_node = srcu_dereference(mnt->mnt_fsnotify_marks.first, | 256 | &fsnotify_mark_srcu); |
248 | &fsnotify_mark_srcu); | 257 | inode_node = srcu_dereference(to_tell->i_fsnotify_marks.first, |
249 | else | 258 | &fsnotify_mark_srcu); |
250 | vfsmount_node = NULL; | ||
251 | } else { | ||
252 | mnt = NULL; | ||
253 | vfsmount_node = NULL; | ||
254 | } | 259 | } |
255 | 260 | ||
256 | while (inode_node || vfsmount_node) { | 261 | while (inode_node || vfsmount_node) { |
262 | inode_group = vfsmount_group = NULL; | ||
263 | |||
257 | if (inode_node) { | 264 | if (inode_node) { |
258 | inode_mark = hlist_entry(srcu_dereference(inode_node, &fsnotify_mark_srcu), | 265 | inode_mark = hlist_entry(srcu_dereference(inode_node, &fsnotify_mark_srcu), |
259 | struct fsnotify_mark, i.i_list); | 266 | struct fsnotify_mark, i.i_list); |
260 | inode_group = inode_mark->group; | 267 | inode_group = inode_mark->group; |
261 | } else | 268 | } |
262 | inode_group = (void *)-1; | ||
263 | 269 | ||
264 | if (vfsmount_node) { | 270 | if (vfsmount_node) { |
265 | vfsmount_mark = hlist_entry(srcu_dereference(vfsmount_node, &fsnotify_mark_srcu), | 271 | vfsmount_mark = hlist_entry(srcu_dereference(vfsmount_node, &fsnotify_mark_srcu), |
266 | struct fsnotify_mark, m.m_list); | 272 | struct fsnotify_mark, m.m_list); |
267 | vfsmount_group = vfsmount_mark->group; | 273 | vfsmount_group = vfsmount_mark->group; |
268 | } else | 274 | } |
269 | vfsmount_group = (void *)-1; | ||
270 | 275 | ||
271 | if (inode_group < vfsmount_group) { | 276 | if (inode_group > vfsmount_group) { |
272 | /* handle inode */ | 277 | /* handle inode */ |
273 | send_to_group(to_tell, NULL, inode_mark, NULL, mask, data, | 278 | send_to_group(to_tell, NULL, inode_mark, NULL, mask, data, |
274 | data_is, cookie, file_name, &event); | 279 | data_is, cookie, file_name, &event); |
275 | used_inode = true; | 280 | /* we didn't use the vfsmount_mark */ |
276 | } else if (vfsmount_group < inode_group) { | 281 | vfsmount_group = NULL; |
282 | } else if (vfsmount_group > inode_group) { | ||
277 | send_to_group(to_tell, mnt, NULL, vfsmount_mark, mask, data, | 283 | send_to_group(to_tell, mnt, NULL, vfsmount_mark, mask, data, |
278 | data_is, cookie, file_name, &event); | 284 | data_is, cookie, file_name, &event); |
279 | used_vfsmount = true; | 285 | inode_group = NULL; |
280 | } else { | 286 | } else { |
281 | send_to_group(to_tell, mnt, inode_mark, vfsmount_mark, | 287 | send_to_group(to_tell, mnt, inode_mark, vfsmount_mark, |
282 | mask, data, data_is, cookie, file_name, | 288 | mask, data, data_is, cookie, file_name, |
283 | &event); | 289 | &event); |
284 | used_vfsmount = true; | ||
285 | used_inode = true; | ||
286 | } | 290 | } |
287 | 291 | ||
288 | if (used_inode) | 292 | if (inode_group) |
289 | inode_node = srcu_dereference(inode_node->next, | 293 | inode_node = srcu_dereference(inode_node->next, |
290 | &fsnotify_mark_srcu); | 294 | &fsnotify_mark_srcu); |
291 | if (used_vfsmount) | 295 | if (vfsmount_group) |
292 | vfsmount_node = srcu_dereference(vfsmount_node->next, | 296 | vfsmount_node = srcu_dereference(vfsmount_node->next, |
293 | &fsnotify_mark_srcu); | 297 | &fsnotify_mark_srcu); |
294 | } | 298 | } |
diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c index a76e0aa5cd3..391915093fe 100644 --- a/fs/ocfs2/acl.c +++ b/fs/ocfs2/acl.c | |||
@@ -209,7 +209,10 @@ static int ocfs2_acl_set_mode(struct inode *inode, struct buffer_head *di_bh, | |||
209 | } | 209 | } |
210 | 210 | ||
211 | inode->i_mode = new_mode; | 211 | inode->i_mode = new_mode; |
212 | inode->i_ctime = CURRENT_TIME; | ||
212 | di->i_mode = cpu_to_le16(inode->i_mode); | 213 | di->i_mode = cpu_to_le16(inode->i_mode); |
214 | di->i_ctime = cpu_to_le64(inode->i_ctime.tv_sec); | ||
215 | di->i_ctime_nsec = cpu_to_le32(inode->i_ctime.tv_nsec); | ||
213 | 216 | ||
214 | ocfs2_journal_dirty(handle, di_bh); | 217 | ocfs2_journal_dirty(handle, di_bh); |
215 | 218 | ||
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index 215e12ce1d8..592fae5007d 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
@@ -6672,7 +6672,7 @@ int ocfs2_grab_pages(struct inode *inode, loff_t start, loff_t end, | |||
6672 | last_page_bytes = PAGE_ALIGN(end); | 6672 | last_page_bytes = PAGE_ALIGN(end); |
6673 | index = start >> PAGE_CACHE_SHIFT; | 6673 | index = start >> PAGE_CACHE_SHIFT; |
6674 | do { | 6674 | do { |
6675 | pages[numpages] = grab_cache_page(mapping, index); | 6675 | pages[numpages] = find_or_create_page(mapping, index, GFP_NOFS); |
6676 | if (!pages[numpages]) { | 6676 | if (!pages[numpages]) { |
6677 | ret = -ENOMEM; | 6677 | ret = -ENOMEM; |
6678 | mlog_errno(ret); | 6678 | mlog_errno(ret); |
diff --git a/fs/ocfs2/blockcheck.c b/fs/ocfs2/blockcheck.c index ec6d1233959..c7ee03c2222 100644 --- a/fs/ocfs2/blockcheck.c +++ b/fs/ocfs2/blockcheck.c | |||
@@ -439,7 +439,7 @@ int ocfs2_block_check_validate(void *data, size_t blocksize, | |||
439 | 439 | ||
440 | ocfs2_blockcheck_inc_failure(stats); | 440 | ocfs2_blockcheck_inc_failure(stats); |
441 | mlog(ML_ERROR, | 441 | mlog(ML_ERROR, |
442 | "CRC32 failed: stored: %u, computed %u. Applying ECC.\n", | 442 | "CRC32 failed: stored: 0x%x, computed 0x%x. Applying ECC.\n", |
443 | (unsigned int)check.bc_crc32e, (unsigned int)crc); | 443 | (unsigned int)check.bc_crc32e, (unsigned int)crc); |
444 | 444 | ||
445 | /* Ok, try ECC fixups */ | 445 | /* Ok, try ECC fixups */ |
@@ -453,7 +453,7 @@ int ocfs2_block_check_validate(void *data, size_t blocksize, | |||
453 | goto out; | 453 | goto out; |
454 | } | 454 | } |
455 | 455 | ||
456 | mlog(ML_ERROR, "Fixed CRC32 failed: stored: %u, computed %u\n", | 456 | mlog(ML_ERROR, "Fixed CRC32 failed: stored: 0x%x, computed 0x%x\n", |
457 | (unsigned int)check.bc_crc32e, (unsigned int)crc); | 457 | (unsigned int)check.bc_crc32e, (unsigned int)crc); |
458 | 458 | ||
459 | rc = -EIO; | 459 | rc = -EIO; |
diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c index 1361997cf20..cbe2f057cc2 100644 --- a/fs/ocfs2/cluster/tcp.c +++ b/fs/ocfs2/cluster/tcp.c | |||
@@ -977,7 +977,7 @@ static int o2net_tx_can_proceed(struct o2net_node *nn, | |||
977 | int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec, | 977 | int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec, |
978 | size_t caller_veclen, u8 target_node, int *status) | 978 | size_t caller_veclen, u8 target_node, int *status) |
979 | { | 979 | { |
980 | int ret; | 980 | int ret = 0; |
981 | struct o2net_msg *msg = NULL; | 981 | struct o2net_msg *msg = NULL; |
982 | size_t veclen, caller_bytes = 0; | 982 | size_t veclen, caller_bytes = 0; |
983 | struct kvec *vec = NULL; | 983 | struct kvec *vec = NULL; |
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c index f04ebcfffc4..c49f6de0e7a 100644 --- a/fs/ocfs2/dir.c +++ b/fs/ocfs2/dir.c | |||
@@ -3931,6 +3931,15 @@ static int ocfs2_dx_dir_rebalance(struct ocfs2_super *osb, struct inode *dir, | |||
3931 | goto out_commit; | 3931 | goto out_commit; |
3932 | } | 3932 | } |
3933 | 3933 | ||
3934 | cpos = split_hash; | ||
3935 | ret = ocfs2_dx_dir_new_cluster(dir, &et, cpos, handle, | ||
3936 | data_ac, meta_ac, new_dx_leaves, | ||
3937 | num_dx_leaves); | ||
3938 | if (ret) { | ||
3939 | mlog_errno(ret); | ||
3940 | goto out_commit; | ||
3941 | } | ||
3942 | |||
3934 | for (i = 0; i < num_dx_leaves; i++) { | 3943 | for (i = 0; i < num_dx_leaves; i++) { |
3935 | ret = ocfs2_journal_access_dl(handle, INODE_CACHE(dir), | 3944 | ret = ocfs2_journal_access_dl(handle, INODE_CACHE(dir), |
3936 | orig_dx_leaves[i], | 3945 | orig_dx_leaves[i], |
@@ -3939,15 +3948,14 @@ static int ocfs2_dx_dir_rebalance(struct ocfs2_super *osb, struct inode *dir, | |||
3939 | mlog_errno(ret); | 3948 | mlog_errno(ret); |
3940 | goto out_commit; | 3949 | goto out_commit; |
3941 | } | 3950 | } |
3942 | } | ||
3943 | 3951 | ||
3944 | cpos = split_hash; | 3952 | ret = ocfs2_journal_access_dl(handle, INODE_CACHE(dir), |
3945 | ret = ocfs2_dx_dir_new_cluster(dir, &et, cpos, handle, | 3953 | new_dx_leaves[i], |
3946 | data_ac, meta_ac, new_dx_leaves, | 3954 | OCFS2_JOURNAL_ACCESS_WRITE); |
3947 | num_dx_leaves); | 3955 | if (ret) { |
3948 | if (ret) { | 3956 | mlog_errno(ret); |
3949 | mlog_errno(ret); | 3957 | goto out_commit; |
3950 | goto out_commit; | 3958 | } |
3951 | } | 3959 | } |
3952 | 3960 | ||
3953 | ocfs2_dx_dir_transfer_leaf(dir, split_hash, handle, tmp_dx_leaf, | 3961 | ocfs2_dx_dir_transfer_leaf(dir, split_hash, handle, tmp_dx_leaf, |
diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h index 4b6ae2c13b4..765298908f1 100644 --- a/fs/ocfs2/dlm/dlmcommon.h +++ b/fs/ocfs2/dlm/dlmcommon.h | |||
@@ -1030,6 +1030,7 @@ int dlm_drop_lockres_ref(struct dlm_ctxt *dlm, | |||
1030 | struct dlm_lock_resource *res); | 1030 | struct dlm_lock_resource *res); |
1031 | void dlm_clean_master_list(struct dlm_ctxt *dlm, | 1031 | void dlm_clean_master_list(struct dlm_ctxt *dlm, |
1032 | u8 dead_node); | 1032 | u8 dead_node); |
1033 | void dlm_force_free_mles(struct dlm_ctxt *dlm); | ||
1033 | int dlm_lock_basts_flushed(struct dlm_ctxt *dlm, struct dlm_lock *lock); | 1034 | int dlm_lock_basts_flushed(struct dlm_ctxt *dlm, struct dlm_lock *lock); |
1034 | int __dlm_lockres_has_locks(struct dlm_lock_resource *res); | 1035 | int __dlm_lockres_has_locks(struct dlm_lock_resource *res); |
1035 | int __dlm_lockres_unused(struct dlm_lock_resource *res); | 1036 | int __dlm_lockres_unused(struct dlm_lock_resource *res); |
diff --git a/fs/ocfs2/dlm/dlmdebug.c b/fs/ocfs2/dlm/dlmdebug.c index 5efdd37dfe4..901ca52bf86 100644 --- a/fs/ocfs2/dlm/dlmdebug.c +++ b/fs/ocfs2/dlm/dlmdebug.c | |||
@@ -636,8 +636,14 @@ static void *lockres_seq_start(struct seq_file *m, loff_t *pos) | |||
636 | spin_lock(&dlm->track_lock); | 636 | spin_lock(&dlm->track_lock); |
637 | if (oldres) | 637 | if (oldres) |
638 | track_list = &oldres->tracking; | 638 | track_list = &oldres->tracking; |
639 | else | 639 | else { |
640 | track_list = &dlm->tracking_list; | 640 | track_list = &dlm->tracking_list; |
641 | if (list_empty(track_list)) { | ||
642 | dl = NULL; | ||
643 | spin_unlock(&dlm->track_lock); | ||
644 | goto bail; | ||
645 | } | ||
646 | } | ||
641 | 647 | ||
642 | list_for_each_entry(res, track_list, tracking) { | 648 | list_for_each_entry(res, track_list, tracking) { |
643 | if (&res->tracking == &dlm->tracking_list) | 649 | if (&res->tracking == &dlm->tracking_list) |
@@ -660,6 +666,7 @@ static void *lockres_seq_start(struct seq_file *m, loff_t *pos) | |||
660 | } else | 666 | } else |
661 | dl = NULL; | 667 | dl = NULL; |
662 | 668 | ||
669 | bail: | ||
663 | /* passed to seq_show */ | 670 | /* passed to seq_show */ |
664 | return dl; | 671 | return dl; |
665 | } | 672 | } |
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c index 153abb5abef..11a5c87fd7f 100644 --- a/fs/ocfs2/dlm/dlmdomain.c +++ b/fs/ocfs2/dlm/dlmdomain.c | |||
@@ -693,6 +693,7 @@ void dlm_unregister_domain(struct dlm_ctxt *dlm) | |||
693 | 693 | ||
694 | dlm_mark_domain_leaving(dlm); | 694 | dlm_mark_domain_leaving(dlm); |
695 | dlm_leave_domain(dlm); | 695 | dlm_leave_domain(dlm); |
696 | dlm_force_free_mles(dlm); | ||
696 | dlm_complete_dlm_shutdown(dlm); | 697 | dlm_complete_dlm_shutdown(dlm); |
697 | } | 698 | } |
698 | dlm_put(dlm); | 699 | dlm_put(dlm); |
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index ffb4c68dafa..f564b0e5f80 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c | |||
@@ -3433,3 +3433,43 @@ void dlm_lockres_release_ast(struct dlm_ctxt *dlm, | |||
3433 | wake_up(&res->wq); | 3433 | wake_up(&res->wq); |
3434 | wake_up(&dlm->migration_wq); | 3434 | wake_up(&dlm->migration_wq); |
3435 | } | 3435 | } |
3436 | |||
3437 | void dlm_force_free_mles(struct dlm_ctxt *dlm) | ||
3438 | { | ||
3439 | int i; | ||
3440 | struct hlist_head *bucket; | ||
3441 | struct dlm_master_list_entry *mle; | ||
3442 | struct hlist_node *tmp, *list; | ||
3443 | |||
3444 | /* | ||
3445 | * We notified all other nodes that we are exiting the domain and | ||
3446 | * marked the dlm state to DLM_CTXT_LEAVING. If any mles are still | ||
3447 | * around we force free them and wake any processes that are waiting | ||
3448 | * on the mles | ||
3449 | */ | ||
3450 | spin_lock(&dlm->spinlock); | ||
3451 | spin_lock(&dlm->master_lock); | ||
3452 | |||
3453 | BUG_ON(dlm->dlm_state != DLM_CTXT_LEAVING); | ||
3454 | BUG_ON((find_next_bit(dlm->domain_map, O2NM_MAX_NODES, 0) < O2NM_MAX_NODES)); | ||
3455 | |||
3456 | for (i = 0; i < DLM_HASH_BUCKETS; i++) { | ||
3457 | bucket = dlm_master_hash(dlm, i); | ||
3458 | hlist_for_each_safe(list, tmp, bucket) { | ||
3459 | mle = hlist_entry(list, struct dlm_master_list_entry, | ||
3460 | master_hash_node); | ||
3461 | if (mle->type != DLM_MLE_BLOCK) { | ||
3462 | mlog(ML_ERROR, "bad mle: %p\n", mle); | ||
3463 | dlm_print_one_mle(mle); | ||
3464 | } | ||
3465 | atomic_set(&mle->woken, 1); | ||
3466 | wake_up(&mle->wq); | ||
3467 | |||
3468 | __dlm_unlink_mle(dlm, mle); | ||
3469 | __dlm_mle_detach_hb_events(dlm, mle); | ||
3470 | __dlm_put_mle(mle); | ||
3471 | } | ||
3472 | } | ||
3473 | spin_unlock(&dlm->master_lock); | ||
3474 | spin_unlock(&dlm->spinlock); | ||
3475 | } | ||
diff --git a/fs/ocfs2/dlmglue.h b/fs/ocfs2/dlmglue.h index d1ce48e1b3d..1d596d8c4a4 100644 --- a/fs/ocfs2/dlmglue.h +++ b/fs/ocfs2/dlmglue.h | |||
@@ -84,6 +84,7 @@ enum { | |||
84 | OI_LS_PARENT, | 84 | OI_LS_PARENT, |
85 | OI_LS_RENAME1, | 85 | OI_LS_RENAME1, |
86 | OI_LS_RENAME2, | 86 | OI_LS_RENAME2, |
87 | OI_LS_REFLINK_TARGET, | ||
87 | }; | 88 | }; |
88 | 89 | ||
89 | int ocfs2_dlm_init(struct ocfs2_super *osb); | 90 | int ocfs2_dlm_init(struct ocfs2_super *osb); |
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 81296b4e364..9a03c151b5c 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/writeback.h> | 36 | #include <linux/writeback.h> |
37 | #include <linux/falloc.h> | 37 | #include <linux/falloc.h> |
38 | #include <linux/quotaops.h> | 38 | #include <linux/quotaops.h> |
39 | #include <linux/blkdev.h> | ||
39 | 40 | ||
40 | #define MLOG_MASK_PREFIX ML_INODE | 41 | #define MLOG_MASK_PREFIX ML_INODE |
41 | #include <cluster/masklog.h> | 42 | #include <cluster/masklog.h> |
@@ -190,8 +191,16 @@ static int ocfs2_sync_file(struct file *file, int datasync) | |||
190 | if (err) | 191 | if (err) |
191 | goto bail; | 192 | goto bail; |
192 | 193 | ||
193 | if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) | 194 | if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) { |
195 | /* | ||
196 | * We still have to flush drive's caches to get data to the | ||
197 | * platter | ||
198 | */ | ||
199 | if (osb->s_mount_opt & OCFS2_MOUNT_BARRIER) | ||
200 | blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, | ||
201 | NULL, BLKDEV_IFL_WAIT); | ||
194 | goto bail; | 202 | goto bail; |
203 | } | ||
195 | 204 | ||
196 | journal = osb->journal->j_journal; | 205 | journal = osb->journal->j_journal; |
197 | err = jbd2_journal_force_commit(journal); | 206 | err = jbd2_journal_force_commit(journal); |
@@ -774,7 +783,7 @@ static int ocfs2_write_zero_page(struct inode *inode, u64 abs_from, | |||
774 | BUG_ON(abs_to > (((u64)index + 1) << PAGE_CACHE_SHIFT)); | 783 | BUG_ON(abs_to > (((u64)index + 1) << PAGE_CACHE_SHIFT)); |
775 | BUG_ON(abs_from & (inode->i_blkbits - 1)); | 784 | BUG_ON(abs_from & (inode->i_blkbits - 1)); |
776 | 785 | ||
777 | page = grab_cache_page(mapping, index); | 786 | page = find_or_create_page(mapping, index, GFP_NOFS); |
778 | if (!page) { | 787 | if (!page) { |
779 | ret = -ENOMEM; | 788 | ret = -ENOMEM; |
780 | mlog_errno(ret); | 789 | mlog_errno(ret); |
@@ -2329,7 +2338,7 @@ out_dio: | |||
2329 | BUG_ON(ret == -EIOCBQUEUED && !(file->f_flags & O_DIRECT)); | 2338 | BUG_ON(ret == -EIOCBQUEUED && !(file->f_flags & O_DIRECT)); |
2330 | 2339 | ||
2331 | if (((file->f_flags & O_DSYNC) && !direct_io) || IS_SYNC(inode) || | 2340 | if (((file->f_flags & O_DSYNC) && !direct_io) || IS_SYNC(inode) || |
2332 | ((file->f_flags & O_DIRECT) && has_refcount)) { | 2341 | ((file->f_flags & O_DIRECT) && !direct_io)) { |
2333 | ret = filemap_fdatawrite_range(file->f_mapping, pos, | 2342 | ret = filemap_fdatawrite_range(file->f_mapping, pos, |
2334 | pos + count - 1); | 2343 | pos + count - 1); |
2335 | if (ret < 0) | 2344 | if (ret < 0) |
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index 0492464916b..eece3e05d9d 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c | |||
@@ -488,7 +488,11 @@ static int ocfs2_read_locked_inode(struct inode *inode, | |||
488 | OCFS2_BH_IGNORE_CACHE); | 488 | OCFS2_BH_IGNORE_CACHE); |
489 | } else { | 489 | } else { |
490 | status = ocfs2_read_blocks_sync(osb, args->fi_blkno, 1, &bh); | 490 | status = ocfs2_read_blocks_sync(osb, args->fi_blkno, 1, &bh); |
491 | if (!status) | 491 | /* |
492 | * If buffer is in jbd, then its checksum may not have been | ||
493 | * computed as yet. | ||
494 | */ | ||
495 | if (!status && !buffer_jbd(bh)) | ||
492 | status = ocfs2_validate_inode_block(osb->sb, bh); | 496 | status = ocfs2_validate_inode_block(osb->sb, bh); |
493 | } | 497 | } |
494 | if (status < 0) { | 498 | if (status < 0) { |
diff --git a/fs/ocfs2/mmap.c b/fs/ocfs2/mmap.c index af2b8fe1f13..4c18f4ad93b 100644 --- a/fs/ocfs2/mmap.c +++ b/fs/ocfs2/mmap.c | |||
@@ -74,9 +74,11 @@ static int __ocfs2_page_mkwrite(struct inode *inode, struct buffer_head *di_bh, | |||
74 | /* | 74 | /* |
75 | * Another node might have truncated while we were waiting on | 75 | * Another node might have truncated while we were waiting on |
76 | * cluster locks. | 76 | * cluster locks. |
77 | * We don't check size == 0 before the shift. This is borrowed | ||
78 | * from do_generic_file_read. | ||
77 | */ | 79 | */ |
78 | last_index = size >> PAGE_CACHE_SHIFT; | 80 | last_index = (size - 1) >> PAGE_CACHE_SHIFT; |
79 | if (page->index > last_index) { | 81 | if (unlikely(!size || page->index > last_index)) { |
80 | ret = -EINVAL; | 82 | ret = -EINVAL; |
81 | goto out; | 83 | goto out; |
82 | } | 84 | } |
@@ -107,7 +109,7 @@ static int __ocfs2_page_mkwrite(struct inode *inode, struct buffer_head *di_bh, | |||
107 | * because the "write" would invalidate their data. | 109 | * because the "write" would invalidate their data. |
108 | */ | 110 | */ |
109 | if (page->index == last_index) | 111 | if (page->index == last_index) |
110 | len = size & ~PAGE_CACHE_MASK; | 112 | len = ((size - 1) & ~PAGE_CACHE_MASK) + 1; |
111 | 113 | ||
112 | ret = ocfs2_write_begin_nolock(mapping, pos, len, 0, &locked_page, | 114 | ret = ocfs2_write_begin_nolock(mapping, pos, len, 0, &locked_page, |
113 | &fsdata, di_bh, page); | 115 | &fsdata, di_bh, page); |
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index f171b51a74f..a00dda2e4f1 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
@@ -472,32 +472,23 @@ leave: | |||
472 | return status; | 472 | return status; |
473 | } | 473 | } |
474 | 474 | ||
475 | static int ocfs2_mknod_locked(struct ocfs2_super *osb, | 475 | static int __ocfs2_mknod_locked(struct inode *dir, |
476 | struct inode *dir, | 476 | struct inode *inode, |
477 | struct inode *inode, | 477 | dev_t dev, |
478 | dev_t dev, | 478 | struct buffer_head **new_fe_bh, |
479 | struct buffer_head **new_fe_bh, | 479 | struct buffer_head *parent_fe_bh, |
480 | struct buffer_head *parent_fe_bh, | 480 | handle_t *handle, |
481 | handle_t *handle, | 481 | struct ocfs2_alloc_context *inode_ac, |
482 | struct ocfs2_alloc_context *inode_ac) | 482 | u64 fe_blkno, u64 suballoc_loc, u16 suballoc_bit) |
483 | { | 483 | { |
484 | int status = 0; | 484 | int status = 0; |
485 | struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); | ||
485 | struct ocfs2_dinode *fe = NULL; | 486 | struct ocfs2_dinode *fe = NULL; |
486 | struct ocfs2_extent_list *fel; | 487 | struct ocfs2_extent_list *fel; |
487 | u64 suballoc_loc, fe_blkno = 0; | ||
488 | u16 suballoc_bit; | ||
489 | u16 feat; | 488 | u16 feat; |
490 | 489 | ||
491 | *new_fe_bh = NULL; | 490 | *new_fe_bh = NULL; |
492 | 491 | ||
493 | status = ocfs2_claim_new_inode(handle, dir, parent_fe_bh, | ||
494 | inode_ac, &suballoc_loc, | ||
495 | &suballoc_bit, &fe_blkno); | ||
496 | if (status < 0) { | ||
497 | mlog_errno(status); | ||
498 | goto leave; | ||
499 | } | ||
500 | |||
501 | /* populate as many fields early on as possible - many of | 492 | /* populate as many fields early on as possible - many of |
502 | * these are used by the support functions here and in | 493 | * these are used by the support functions here and in |
503 | * callers. */ | 494 | * callers. */ |
@@ -591,6 +582,34 @@ leave: | |||
591 | return status; | 582 | return status; |
592 | } | 583 | } |
593 | 584 | ||
585 | static int ocfs2_mknod_locked(struct ocfs2_super *osb, | ||
586 | struct inode *dir, | ||
587 | struct inode *inode, | ||
588 | dev_t dev, | ||
589 | struct buffer_head **new_fe_bh, | ||
590 | struct buffer_head *parent_fe_bh, | ||
591 | handle_t *handle, | ||
592 | struct ocfs2_alloc_context *inode_ac) | ||
593 | { | ||
594 | int status = 0; | ||
595 | u64 suballoc_loc, fe_blkno = 0; | ||
596 | u16 suballoc_bit; | ||
597 | |||
598 | *new_fe_bh = NULL; | ||
599 | |||
600 | status = ocfs2_claim_new_inode(handle, dir, parent_fe_bh, | ||
601 | inode_ac, &suballoc_loc, | ||
602 | &suballoc_bit, &fe_blkno); | ||
603 | if (status < 0) { | ||
604 | mlog_errno(status); | ||
605 | return status; | ||
606 | } | ||
607 | |||
608 | return __ocfs2_mknod_locked(dir, inode, dev, new_fe_bh, | ||
609 | parent_fe_bh, handle, inode_ac, | ||
610 | fe_blkno, suballoc_loc, suballoc_bit); | ||
611 | } | ||
612 | |||
594 | static int ocfs2_mkdir(struct inode *dir, | 613 | static int ocfs2_mkdir(struct inode *dir, |
595 | struct dentry *dentry, | 614 | struct dentry *dentry, |
596 | int mode) | 615 | int mode) |
@@ -1852,61 +1871,117 @@ bail: | |||
1852 | return status; | 1871 | return status; |
1853 | } | 1872 | } |
1854 | 1873 | ||
1855 | static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, | 1874 | static int ocfs2_lookup_lock_orphan_dir(struct ocfs2_super *osb, |
1856 | struct inode **ret_orphan_dir, | 1875 | struct inode **ret_orphan_dir, |
1857 | u64 blkno, | 1876 | struct buffer_head **ret_orphan_dir_bh) |
1858 | char *name, | ||
1859 | struct ocfs2_dir_lookup_result *lookup) | ||
1860 | { | 1877 | { |
1861 | struct inode *orphan_dir_inode; | 1878 | struct inode *orphan_dir_inode; |
1862 | struct buffer_head *orphan_dir_bh = NULL; | 1879 | struct buffer_head *orphan_dir_bh = NULL; |
1863 | int status = 0; | 1880 | int ret = 0; |
1864 | |||
1865 | status = ocfs2_blkno_stringify(blkno, name); | ||
1866 | if (status < 0) { | ||
1867 | mlog_errno(status); | ||
1868 | return status; | ||
1869 | } | ||
1870 | 1881 | ||
1871 | orphan_dir_inode = ocfs2_get_system_file_inode(osb, | 1882 | orphan_dir_inode = ocfs2_get_system_file_inode(osb, |
1872 | ORPHAN_DIR_SYSTEM_INODE, | 1883 | ORPHAN_DIR_SYSTEM_INODE, |
1873 | osb->slot_num); | 1884 | osb->slot_num); |
1874 | if (!orphan_dir_inode) { | 1885 | if (!orphan_dir_inode) { |
1875 | status = -ENOENT; | 1886 | ret = -ENOENT; |
1876 | mlog_errno(status); | 1887 | mlog_errno(ret); |
1877 | return status; | 1888 | return ret; |
1878 | } | 1889 | } |
1879 | 1890 | ||
1880 | mutex_lock(&orphan_dir_inode->i_mutex); | 1891 | mutex_lock(&orphan_dir_inode->i_mutex); |
1881 | 1892 | ||
1882 | status = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1); | 1893 | ret = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1); |
1883 | if (status < 0) { | 1894 | if (ret < 0) { |
1884 | mlog_errno(status); | 1895 | mutex_unlock(&orphan_dir_inode->i_mutex); |
1885 | goto leave; | 1896 | iput(orphan_dir_inode); |
1897 | |||
1898 | mlog_errno(ret); | ||
1899 | return ret; | ||
1886 | } | 1900 | } |
1887 | 1901 | ||
1888 | status = ocfs2_prepare_dir_for_insert(osb, orphan_dir_inode, | 1902 | *ret_orphan_dir = orphan_dir_inode; |
1889 | orphan_dir_bh, name, | 1903 | *ret_orphan_dir_bh = orphan_dir_bh; |
1890 | OCFS2_ORPHAN_NAMELEN, lookup); | ||
1891 | if (status < 0) { | ||
1892 | ocfs2_inode_unlock(orphan_dir_inode, 1); | ||
1893 | 1904 | ||
1894 | mlog_errno(status); | 1905 | return 0; |
1895 | goto leave; | 1906 | } |
1907 | |||
1908 | static int __ocfs2_prepare_orphan_dir(struct inode *orphan_dir_inode, | ||
1909 | struct buffer_head *orphan_dir_bh, | ||
1910 | u64 blkno, | ||
1911 | char *name, | ||
1912 | struct ocfs2_dir_lookup_result *lookup) | ||
1913 | { | ||
1914 | int ret; | ||
1915 | struct ocfs2_super *osb = OCFS2_SB(orphan_dir_inode->i_sb); | ||
1916 | |||
1917 | ret = ocfs2_blkno_stringify(blkno, name); | ||
1918 | if (ret < 0) { | ||
1919 | mlog_errno(ret); | ||
1920 | return ret; | ||
1921 | } | ||
1922 | |||
1923 | ret = ocfs2_prepare_dir_for_insert(osb, orphan_dir_inode, | ||
1924 | orphan_dir_bh, name, | ||
1925 | OCFS2_ORPHAN_NAMELEN, lookup); | ||
1926 | if (ret < 0) { | ||
1927 | mlog_errno(ret); | ||
1928 | return ret; | ||
1929 | } | ||
1930 | |||
1931 | return 0; | ||
1932 | } | ||
1933 | |||
1934 | /** | ||
1935 | * ocfs2_prepare_orphan_dir() - Prepare an orphan directory for | ||
1936 | * insertion of an orphan. | ||
1937 | * @osb: ocfs2 file system | ||
1938 | * @ret_orphan_dir: Orphan dir inode - returned locked! | ||
1939 | * @blkno: Actual block number of the inode to be inserted into orphan dir. | ||
1940 | * @lookup: dir lookup result, to be passed back into functions like | ||
1941 | * ocfs2_orphan_add | ||
1942 | * | ||
1943 | * Returns zero on success and the ret_orphan_dir, name and lookup | ||
1944 | * fields will be populated. | ||
1945 | * | ||
1946 | * Returns non-zero on failure. | ||
1947 | */ | ||
1948 | static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, | ||
1949 | struct inode **ret_orphan_dir, | ||
1950 | u64 blkno, | ||
1951 | char *name, | ||
1952 | struct ocfs2_dir_lookup_result *lookup) | ||
1953 | { | ||
1954 | struct inode *orphan_dir_inode = NULL; | ||
1955 | struct buffer_head *orphan_dir_bh = NULL; | ||
1956 | int ret = 0; | ||
1957 | |||
1958 | ret = ocfs2_lookup_lock_orphan_dir(osb, &orphan_dir_inode, | ||
1959 | &orphan_dir_bh); | ||
1960 | if (ret < 0) { | ||
1961 | mlog_errno(ret); | ||
1962 | return ret; | ||
1963 | } | ||
1964 | |||
1965 | ret = __ocfs2_prepare_orphan_dir(orphan_dir_inode, orphan_dir_bh, | ||
1966 | blkno, name, lookup); | ||
1967 | if (ret < 0) { | ||
1968 | mlog_errno(ret); | ||
1969 | goto out; | ||
1896 | } | 1970 | } |
1897 | 1971 | ||
1898 | *ret_orphan_dir = orphan_dir_inode; | 1972 | *ret_orphan_dir = orphan_dir_inode; |
1899 | 1973 | ||
1900 | leave: | 1974 | out: |
1901 | if (status) { | 1975 | brelse(orphan_dir_bh); |
1976 | |||
1977 | if (ret) { | ||
1978 | ocfs2_inode_unlock(orphan_dir_inode, 1); | ||
1902 | mutex_unlock(&orphan_dir_inode->i_mutex); | 1979 | mutex_unlock(&orphan_dir_inode->i_mutex); |
1903 | iput(orphan_dir_inode); | 1980 | iput(orphan_dir_inode); |
1904 | } | 1981 | } |
1905 | 1982 | ||
1906 | brelse(orphan_dir_bh); | 1983 | mlog_exit(ret); |
1907 | 1984 | return ret; | |
1908 | mlog_exit(status); | ||
1909 | return status; | ||
1910 | } | 1985 | } |
1911 | 1986 | ||
1912 | static int ocfs2_orphan_add(struct ocfs2_super *osb, | 1987 | static int ocfs2_orphan_add(struct ocfs2_super *osb, |
@@ -2053,6 +2128,99 @@ leave: | |||
2053 | return status; | 2128 | return status; |
2054 | } | 2129 | } |
2055 | 2130 | ||
2131 | /** | ||
2132 | * ocfs2_prep_new_orphaned_file() - Prepare the orphan dir to recieve a newly | ||
2133 | * allocated file. This is different from the typical 'add to orphan dir' | ||
2134 | * operation in that the inode does not yet exist. This is a problem because | ||
2135 | * the orphan dir stringifies the inode block number to come up with it's | ||
2136 | * dirent. Obviously if the inode does not yet exist we have a chicken and egg | ||
2137 | * problem. This function works around it by calling deeper into the orphan | ||
2138 | * and suballoc code than other callers. Use this only by necessity. | ||
2139 | * @dir: The directory which this inode will ultimately wind up under - not the | ||
2140 | * orphan dir! | ||
2141 | * @dir_bh: buffer_head the @dir inode block | ||
2142 | * @orphan_name: string of length (CFS2_ORPHAN_NAMELEN + 1). Will be filled | ||
2143 | * with the string to be used for orphan dirent. Pass back to the orphan dir | ||
2144 | * code. | ||
2145 | * @ret_orphan_dir: orphan dir inode returned to be passed back into orphan | ||
2146 | * dir code. | ||
2147 | * @ret_di_blkno: block number where the new inode will be allocated. | ||
2148 | * @orphan_insert: Dir insert context to be passed back into orphan dir code. | ||
2149 | * @ret_inode_ac: Inode alloc context to be passed back to the allocator. | ||
2150 | * | ||
2151 | * Returns zero on success and the ret_orphan_dir, name and lookup | ||
2152 | * fields will be populated. | ||
2153 | * | ||
2154 | * Returns non-zero on failure. | ||
2155 | */ | ||
2156 | static int ocfs2_prep_new_orphaned_file(struct inode *dir, | ||
2157 | struct buffer_head *dir_bh, | ||
2158 | char *orphan_name, | ||
2159 | struct inode **ret_orphan_dir, | ||
2160 | u64 *ret_di_blkno, | ||
2161 | struct ocfs2_dir_lookup_result *orphan_insert, | ||
2162 | struct ocfs2_alloc_context **ret_inode_ac) | ||
2163 | { | ||
2164 | int ret; | ||
2165 | u64 di_blkno; | ||
2166 | struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); | ||
2167 | struct inode *orphan_dir = NULL; | ||
2168 | struct buffer_head *orphan_dir_bh = NULL; | ||
2169 | struct ocfs2_alloc_context *inode_ac = NULL; | ||
2170 | |||
2171 | ret = ocfs2_lookup_lock_orphan_dir(osb, &orphan_dir, &orphan_dir_bh); | ||
2172 | if (ret < 0) { | ||
2173 | mlog_errno(ret); | ||
2174 | return ret; | ||
2175 | } | ||
2176 | |||
2177 | /* reserve an inode spot */ | ||
2178 | ret = ocfs2_reserve_new_inode(osb, &inode_ac); | ||
2179 | if (ret < 0) { | ||
2180 | if (ret != -ENOSPC) | ||
2181 | mlog_errno(ret); | ||
2182 | goto out; | ||
2183 | } | ||
2184 | |||
2185 | ret = ocfs2_find_new_inode_loc(dir, dir_bh, inode_ac, | ||
2186 | &di_blkno); | ||
2187 | if (ret) { | ||
2188 | mlog_errno(ret); | ||
2189 | goto out; | ||
2190 | } | ||
2191 | |||
2192 | ret = __ocfs2_prepare_orphan_dir(orphan_dir, orphan_dir_bh, | ||
2193 | di_blkno, orphan_name, orphan_insert); | ||
2194 | if (ret < 0) { | ||
2195 | mlog_errno(ret); | ||
2196 | goto out; | ||
2197 | } | ||
2198 | |||
2199 | out: | ||
2200 | if (ret == 0) { | ||
2201 | *ret_orphan_dir = orphan_dir; | ||
2202 | *ret_di_blkno = di_blkno; | ||
2203 | *ret_inode_ac = inode_ac; | ||
2204 | /* | ||
2205 | * orphan_name and orphan_insert are already up to | ||
2206 | * date via prepare_orphan_dir | ||
2207 | */ | ||
2208 | } else { | ||
2209 | /* Unroll reserve_new_inode* */ | ||
2210 | if (inode_ac) | ||
2211 | ocfs2_free_alloc_context(inode_ac); | ||
2212 | |||
2213 | /* Unroll orphan dir locking */ | ||
2214 | mutex_unlock(&orphan_dir->i_mutex); | ||
2215 | ocfs2_inode_unlock(orphan_dir, 1); | ||
2216 | iput(orphan_dir); | ||
2217 | } | ||
2218 | |||
2219 | brelse(orphan_dir_bh); | ||
2220 | |||
2221 | return 0; | ||
2222 | } | ||
2223 | |||
2056 | int ocfs2_create_inode_in_orphan(struct inode *dir, | 2224 | int ocfs2_create_inode_in_orphan(struct inode *dir, |
2057 | int mode, | 2225 | int mode, |
2058 | struct inode **new_inode) | 2226 | struct inode **new_inode) |
@@ -2068,6 +2236,8 @@ int ocfs2_create_inode_in_orphan(struct inode *dir, | |||
2068 | struct buffer_head *new_di_bh = NULL; | 2236 | struct buffer_head *new_di_bh = NULL; |
2069 | struct ocfs2_alloc_context *inode_ac = NULL; | 2237 | struct ocfs2_alloc_context *inode_ac = NULL; |
2070 | struct ocfs2_dir_lookup_result orphan_insert = { NULL, }; | 2238 | struct ocfs2_dir_lookup_result orphan_insert = { NULL, }; |
2239 | u64 uninitialized_var(di_blkno), suballoc_loc; | ||
2240 | u16 suballoc_bit; | ||
2071 | 2241 | ||
2072 | status = ocfs2_inode_lock(dir, &parent_di_bh, 1); | 2242 | status = ocfs2_inode_lock(dir, &parent_di_bh, 1); |
2073 | if (status < 0) { | 2243 | if (status < 0) { |
@@ -2076,20 +2246,9 @@ int ocfs2_create_inode_in_orphan(struct inode *dir, | |||
2076 | return status; | 2246 | return status; |
2077 | } | 2247 | } |
2078 | 2248 | ||
2079 | /* | 2249 | status = ocfs2_prep_new_orphaned_file(dir, parent_di_bh, |
2080 | * We give the orphan dir the root blkno to fake an orphan name, | 2250 | orphan_name, &orphan_dir, |
2081 | * and allocate enough space for our insertion. | 2251 | &di_blkno, &orphan_insert, &inode_ac); |
2082 | */ | ||
2083 | status = ocfs2_prepare_orphan_dir(osb, &orphan_dir, | ||
2084 | osb->root_blkno, | ||
2085 | orphan_name, &orphan_insert); | ||
2086 | if (status < 0) { | ||
2087 | mlog_errno(status); | ||
2088 | goto leave; | ||
2089 | } | ||
2090 | |||
2091 | /* reserve an inode spot */ | ||
2092 | status = ocfs2_reserve_new_inode(osb, &inode_ac); | ||
2093 | if (status < 0) { | 2252 | if (status < 0) { |
2094 | if (status != -ENOSPC) | 2253 | if (status != -ENOSPC) |
2095 | mlog_errno(status); | 2254 | mlog_errno(status); |
@@ -2116,17 +2275,20 @@ int ocfs2_create_inode_in_orphan(struct inode *dir, | |||
2116 | goto leave; | 2275 | goto leave; |
2117 | did_quota_inode = 1; | 2276 | did_quota_inode = 1; |
2118 | 2277 | ||
2119 | inode->i_nlink = 0; | 2278 | status = ocfs2_claim_new_inode_at_loc(handle, dir, inode_ac, |
2120 | /* do the real work now. */ | 2279 | &suballoc_loc, |
2121 | status = ocfs2_mknod_locked(osb, dir, inode, | 2280 | &suballoc_bit, di_blkno); |
2122 | 0, &new_di_bh, parent_di_bh, handle, | ||
2123 | inode_ac); | ||
2124 | if (status < 0) { | 2281 | if (status < 0) { |
2125 | mlog_errno(status); | 2282 | mlog_errno(status); |
2126 | goto leave; | 2283 | goto leave; |
2127 | } | 2284 | } |
2128 | 2285 | ||
2129 | status = ocfs2_blkno_stringify(OCFS2_I(inode)->ip_blkno, orphan_name); | 2286 | inode->i_nlink = 0; |
2287 | /* do the real work now. */ | ||
2288 | status = __ocfs2_mknod_locked(dir, inode, | ||
2289 | 0, &new_di_bh, parent_di_bh, handle, | ||
2290 | inode_ac, di_blkno, suballoc_loc, | ||
2291 | suballoc_bit); | ||
2130 | if (status < 0) { | 2292 | if (status < 0) { |
2131 | mlog_errno(status); | 2293 | mlog_errno(status); |
2132 | goto leave; | 2294 | goto leave; |
diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h index 33f1c9a8258..fa31d05e41b 100644 --- a/fs/ocfs2/ocfs2_fs.h +++ b/fs/ocfs2/ocfs2_fs.h | |||
@@ -235,18 +235,31 @@ | |||
235 | #define OCFS2_HAS_REFCOUNT_FL (0x0010) | 235 | #define OCFS2_HAS_REFCOUNT_FL (0x0010) |
236 | 236 | ||
237 | /* Inode attributes, keep in sync with EXT2 */ | 237 | /* Inode attributes, keep in sync with EXT2 */ |
238 | #define OCFS2_SECRM_FL (0x00000001) /* Secure deletion */ | 238 | #define OCFS2_SECRM_FL FS_SECRM_FL /* Secure deletion */ |
239 | #define OCFS2_UNRM_FL (0x00000002) /* Undelete */ | 239 | #define OCFS2_UNRM_FL FS_UNRM_FL /* Undelete */ |
240 | #define OCFS2_COMPR_FL (0x00000004) /* Compress file */ | 240 | #define OCFS2_COMPR_FL FS_COMPR_FL /* Compress file */ |
241 | #define OCFS2_SYNC_FL (0x00000008) /* Synchronous updates */ | 241 | #define OCFS2_SYNC_FL FS_SYNC_FL /* Synchronous updates */ |
242 | #define OCFS2_IMMUTABLE_FL (0x00000010) /* Immutable file */ | 242 | #define OCFS2_IMMUTABLE_FL FS_IMMUTABLE_FL /* Immutable file */ |
243 | #define OCFS2_APPEND_FL (0x00000020) /* writes to file may only append */ | 243 | #define OCFS2_APPEND_FL FS_APPEND_FL /* writes to file may only append */ |
244 | #define OCFS2_NODUMP_FL (0x00000040) /* do not dump file */ | 244 | #define OCFS2_NODUMP_FL FS_NODUMP_FL /* do not dump file */ |
245 | #define OCFS2_NOATIME_FL (0x00000080) /* do not update atime */ | 245 | #define OCFS2_NOATIME_FL FS_NOATIME_FL /* do not update atime */ |
246 | #define OCFS2_DIRSYNC_FL (0x00010000) /* dirsync behaviour (directories only) */ | 246 | /* Reserved for compression usage... */ |
247 | 247 | #define OCFS2_DIRTY_FL FS_DIRTY_FL | |
248 | #define OCFS2_FL_VISIBLE (0x000100FF) /* User visible flags */ | 248 | #define OCFS2_COMPRBLK_FL FS_COMPRBLK_FL /* One or more compressed clusters */ |
249 | #define OCFS2_FL_MODIFIABLE (0x000100FF) /* User modifiable flags */ | 249 | #define OCFS2_NOCOMP_FL FS_NOCOMP_FL /* Don't compress */ |
250 | #define OCFS2_ECOMPR_FL FS_ECOMPR_FL /* Compression error */ | ||
251 | /* End compression flags --- maybe not all used */ | ||
252 | #define OCFS2_BTREE_FL FS_BTREE_FL /* btree format dir */ | ||
253 | #define OCFS2_INDEX_FL FS_INDEX_FL /* hash-indexed directory */ | ||
254 | #define OCFS2_IMAGIC_FL FS_IMAGIC_FL /* AFS directory */ | ||
255 | #define OCFS2_JOURNAL_DATA_FL FS_JOURNAL_DATA_FL /* Reserved for ext3 */ | ||
256 | #define OCFS2_NOTAIL_FL FS_NOTAIL_FL /* file tail should not be merged */ | ||
257 | #define OCFS2_DIRSYNC_FL FS_DIRSYNC_FL /* dirsync behaviour (directories only) */ | ||
258 | #define OCFS2_TOPDIR_FL FS_TOPDIR_FL /* Top of directory hierarchies*/ | ||
259 | #define OCFS2_RESERVED_FL FS_RESERVED_FL /* reserved for ext2 lib */ | ||
260 | |||
261 | #define OCFS2_FL_VISIBLE FS_FL_USER_VISIBLE /* User visible flags */ | ||
262 | #define OCFS2_FL_MODIFIABLE FS_FL_USER_MODIFIABLE /* User modifiable flags */ | ||
250 | 263 | ||
251 | /* | 264 | /* |
252 | * Extent record flags (e_node.leaf.flags) | 265 | * Extent record flags (e_node.leaf.flags) |
diff --git a/fs/ocfs2/ocfs2_ioctl.h b/fs/ocfs2/ocfs2_ioctl.h index 2d3420af1a8..5d241505690 100644 --- a/fs/ocfs2/ocfs2_ioctl.h +++ b/fs/ocfs2/ocfs2_ioctl.h | |||
@@ -23,10 +23,10 @@ | |||
23 | /* | 23 | /* |
24 | * ioctl commands | 24 | * ioctl commands |
25 | */ | 25 | */ |
26 | #define OCFS2_IOC_GETFLAGS _IOR('f', 1, long) | 26 | #define OCFS2_IOC_GETFLAGS FS_IOC_GETFLAGS |
27 | #define OCFS2_IOC_SETFLAGS _IOW('f', 2, long) | 27 | #define OCFS2_IOC_SETFLAGS FS_IOC_SETFLAGS |
28 | #define OCFS2_IOC32_GETFLAGS _IOR('f', 1, int) | 28 | #define OCFS2_IOC32_GETFLAGS FS_IOC32_GETFLAGS |
29 | #define OCFS2_IOC32_SETFLAGS _IOW('f', 2, int) | 29 | #define OCFS2_IOC32_SETFLAGS FS_IOC32_SETFLAGS |
30 | 30 | ||
31 | /* | 31 | /* |
32 | * Space reservation / allocation / free ioctls and argument structure | 32 | * Space reservation / allocation / free ioctls and argument structure |
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c index 73a11ccfd4c..efdd7560740 100644 --- a/fs/ocfs2/refcounttree.c +++ b/fs/ocfs2/refcounttree.c | |||
@@ -2960,7 +2960,7 @@ static int ocfs2_duplicate_clusters_by_page(handle_t *handle, | |||
2960 | if (map_end & (PAGE_CACHE_SIZE - 1)) | 2960 | if (map_end & (PAGE_CACHE_SIZE - 1)) |
2961 | to = map_end & (PAGE_CACHE_SIZE - 1); | 2961 | to = map_end & (PAGE_CACHE_SIZE - 1); |
2962 | 2962 | ||
2963 | page = grab_cache_page(mapping, page_index); | 2963 | page = find_or_create_page(mapping, page_index, GFP_NOFS); |
2964 | 2964 | ||
2965 | /* | 2965 | /* |
2966 | * In case PAGE_CACHE_SIZE <= CLUSTER_SIZE, This page | 2966 | * In case PAGE_CACHE_SIZE <= CLUSTER_SIZE, This page |
@@ -3179,7 +3179,8 @@ static int ocfs2_cow_sync_writeback(struct super_block *sb, | |||
3179 | if (map_end > end) | 3179 | if (map_end > end) |
3180 | map_end = end; | 3180 | map_end = end; |
3181 | 3181 | ||
3182 | page = grab_cache_page(context->inode->i_mapping, page_index); | 3182 | page = find_or_create_page(context->inode->i_mapping, |
3183 | page_index, GFP_NOFS); | ||
3183 | BUG_ON(!page); | 3184 | BUG_ON(!page); |
3184 | 3185 | ||
3185 | wait_on_page_writeback(page); | 3186 | wait_on_page_writeback(page); |
@@ -4200,8 +4201,9 @@ static int __ocfs2_reflink(struct dentry *old_dentry, | |||
4200 | goto out; | 4201 | goto out; |
4201 | } | 4202 | } |
4202 | 4203 | ||
4203 | mutex_lock(&new_inode->i_mutex); | 4204 | mutex_lock_nested(&new_inode->i_mutex, I_MUTEX_CHILD); |
4204 | ret = ocfs2_inode_lock(new_inode, &new_bh, 1); | 4205 | ret = ocfs2_inode_lock_nested(new_inode, &new_bh, 1, |
4206 | OI_LS_REFLINK_TARGET); | ||
4205 | if (ret) { | 4207 | if (ret) { |
4206 | mlog_errno(ret); | 4208 | mlog_errno(ret); |
4207 | goto out_unlock; | 4209 | goto out_unlock; |
diff --git a/fs/ocfs2/reservations.c b/fs/ocfs2/reservations.c index d8b6e4259b8..3e78db361bc 100644 --- a/fs/ocfs2/reservations.c +++ b/fs/ocfs2/reservations.c | |||
@@ -732,25 +732,23 @@ int ocfs2_resmap_resv_bits(struct ocfs2_reservation_map *resmap, | |||
732 | struct ocfs2_alloc_reservation *resv, | 732 | struct ocfs2_alloc_reservation *resv, |
733 | int *cstart, int *clen) | 733 | int *cstart, int *clen) |
734 | { | 734 | { |
735 | unsigned int wanted = *clen; | ||
736 | |||
737 | if (resv == NULL || ocfs2_resmap_disabled(resmap)) | 735 | if (resv == NULL || ocfs2_resmap_disabled(resmap)) |
738 | return -ENOSPC; | 736 | return -ENOSPC; |
739 | 737 | ||
740 | spin_lock(&resv_lock); | 738 | spin_lock(&resv_lock); |
741 | 739 | ||
742 | /* | ||
743 | * We don't want to over-allocate for temporary | ||
744 | * windows. Otherwise, we run the risk of fragmenting the | ||
745 | * allocation space. | ||
746 | */ | ||
747 | wanted = ocfs2_resv_window_bits(resmap, resv); | ||
748 | if ((resv->r_flags & OCFS2_RESV_FLAG_TMP) || wanted < *clen) | ||
749 | wanted = *clen; | ||
750 | |||
751 | if (ocfs2_resv_empty(resv)) { | 740 | if (ocfs2_resv_empty(resv)) { |
752 | mlog(0, "empty reservation, find new window\n"); | 741 | /* |
742 | * We don't want to over-allocate for temporary | ||
743 | * windows. Otherwise, we run the risk of fragmenting the | ||
744 | * allocation space. | ||
745 | */ | ||
746 | unsigned int wanted = ocfs2_resv_window_bits(resmap, resv); | ||
753 | 747 | ||
748 | if ((resv->r_flags & OCFS2_RESV_FLAG_TMP) || wanted < *clen) | ||
749 | wanted = *clen; | ||
750 | |||
751 | mlog(0, "empty reservation, find new window\n"); | ||
754 | /* | 752 | /* |
755 | * Try to get a window here. If it works, we must fall | 753 | * Try to get a window here. If it works, we must fall |
756 | * through and test the bitmap . This avoids some | 754 | * through and test the bitmap . This avoids some |
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c index a8e6a95a353..849c2f0e0a0 100644 --- a/fs/ocfs2/suballoc.c +++ b/fs/ocfs2/suballoc.c | |||
@@ -57,11 +57,28 @@ struct ocfs2_suballoc_result { | |||
57 | u64 sr_bg_blkno; /* The bg we allocated from. Set | 57 | u64 sr_bg_blkno; /* The bg we allocated from. Set |
58 | to 0 when a block group is | 58 | to 0 when a block group is |
59 | contiguous. */ | 59 | contiguous. */ |
60 | u64 sr_bg_stable_blkno; /* | ||
61 | * Doesn't change, always | ||
62 | * set to target block | ||
63 | * group descriptor | ||
64 | * block. | ||
65 | */ | ||
60 | u64 sr_blkno; /* The first allocated block */ | 66 | u64 sr_blkno; /* The first allocated block */ |
61 | unsigned int sr_bit_offset; /* The bit in the bg */ | 67 | unsigned int sr_bit_offset; /* The bit in the bg */ |
62 | unsigned int sr_bits; /* How many bits we claimed */ | 68 | unsigned int sr_bits; /* How many bits we claimed */ |
63 | }; | 69 | }; |
64 | 70 | ||
71 | static u64 ocfs2_group_from_res(struct ocfs2_suballoc_result *res) | ||
72 | { | ||
73 | if (res->sr_blkno == 0) | ||
74 | return 0; | ||
75 | |||
76 | if (res->sr_bg_blkno) | ||
77 | return res->sr_bg_blkno; | ||
78 | |||
79 | return ocfs2_which_suballoc_group(res->sr_blkno, res->sr_bit_offset); | ||
80 | } | ||
81 | |||
65 | static inline void ocfs2_debug_bg(struct ocfs2_group_desc *bg); | 82 | static inline void ocfs2_debug_bg(struct ocfs2_group_desc *bg); |
66 | static inline void ocfs2_debug_suballoc_inode(struct ocfs2_dinode *fe); | 83 | static inline void ocfs2_debug_suballoc_inode(struct ocfs2_dinode *fe); |
67 | static inline u16 ocfs2_find_victim_chain(struct ocfs2_chain_list *cl); | 84 | static inline u16 ocfs2_find_victim_chain(struct ocfs2_chain_list *cl); |
@@ -138,6 +155,10 @@ void ocfs2_free_ac_resource(struct ocfs2_alloc_context *ac) | |||
138 | brelse(ac->ac_bh); | 155 | brelse(ac->ac_bh); |
139 | ac->ac_bh = NULL; | 156 | ac->ac_bh = NULL; |
140 | ac->ac_resv = NULL; | 157 | ac->ac_resv = NULL; |
158 | if (ac->ac_find_loc_priv) { | ||
159 | kfree(ac->ac_find_loc_priv); | ||
160 | ac->ac_find_loc_priv = NULL; | ||
161 | } | ||
141 | } | 162 | } |
142 | 163 | ||
143 | void ocfs2_free_alloc_context(struct ocfs2_alloc_context *ac) | 164 | void ocfs2_free_alloc_context(struct ocfs2_alloc_context *ac) |
@@ -336,7 +357,7 @@ out: | |||
336 | static void ocfs2_bg_discontig_add_extent(struct ocfs2_super *osb, | 357 | static void ocfs2_bg_discontig_add_extent(struct ocfs2_super *osb, |
337 | struct ocfs2_group_desc *bg, | 358 | struct ocfs2_group_desc *bg, |
338 | struct ocfs2_chain_list *cl, | 359 | struct ocfs2_chain_list *cl, |
339 | u64 p_blkno, u32 clusters) | 360 | u64 p_blkno, unsigned int clusters) |
340 | { | 361 | { |
341 | struct ocfs2_extent_list *el = &bg->bg_list; | 362 | struct ocfs2_extent_list *el = &bg->bg_list; |
342 | struct ocfs2_extent_rec *rec; | 363 | struct ocfs2_extent_rec *rec; |
@@ -348,7 +369,7 @@ static void ocfs2_bg_discontig_add_extent(struct ocfs2_super *osb, | |||
348 | rec->e_blkno = cpu_to_le64(p_blkno); | 369 | rec->e_blkno = cpu_to_le64(p_blkno); |
349 | rec->e_cpos = cpu_to_le32(le16_to_cpu(bg->bg_bits) / | 370 | rec->e_cpos = cpu_to_le32(le16_to_cpu(bg->bg_bits) / |
350 | le16_to_cpu(cl->cl_bpc)); | 371 | le16_to_cpu(cl->cl_bpc)); |
351 | rec->e_leaf_clusters = cpu_to_le32(clusters); | 372 | rec->e_leaf_clusters = cpu_to_le16(clusters); |
352 | le16_add_cpu(&bg->bg_bits, clusters * le16_to_cpu(cl->cl_bpc)); | 373 | le16_add_cpu(&bg->bg_bits, clusters * le16_to_cpu(cl->cl_bpc)); |
353 | le16_add_cpu(&bg->bg_free_bits_count, | 374 | le16_add_cpu(&bg->bg_free_bits_count, |
354 | clusters * le16_to_cpu(cl->cl_bpc)); | 375 | clusters * le16_to_cpu(cl->cl_bpc)); |
@@ -1678,6 +1699,15 @@ static int ocfs2_search_one_group(struct ocfs2_alloc_context *ac, | |||
1678 | if (!ret) | 1699 | if (!ret) |
1679 | ocfs2_bg_discontig_fix_result(ac, gd, res); | 1700 | ocfs2_bg_discontig_fix_result(ac, gd, res); |
1680 | 1701 | ||
1702 | /* | ||
1703 | * sr_bg_blkno might have been changed by | ||
1704 | * ocfs2_bg_discontig_fix_result | ||
1705 | */ | ||
1706 | res->sr_bg_stable_blkno = group_bh->b_blocknr; | ||
1707 | |||
1708 | if (ac->ac_find_loc_only) | ||
1709 | goto out_loc_only; | ||
1710 | |||
1681 | ret = ocfs2_alloc_dinode_update_counts(alloc_inode, handle, ac->ac_bh, | 1711 | ret = ocfs2_alloc_dinode_update_counts(alloc_inode, handle, ac->ac_bh, |
1682 | res->sr_bits, | 1712 | res->sr_bits, |
1683 | le16_to_cpu(gd->bg_chain)); | 1713 | le16_to_cpu(gd->bg_chain)); |
@@ -1691,6 +1721,7 @@ static int ocfs2_search_one_group(struct ocfs2_alloc_context *ac, | |||
1691 | if (ret < 0) | 1721 | if (ret < 0) |
1692 | mlog_errno(ret); | 1722 | mlog_errno(ret); |
1693 | 1723 | ||
1724 | out_loc_only: | ||
1694 | *bits_left = le16_to_cpu(gd->bg_free_bits_count); | 1725 | *bits_left = le16_to_cpu(gd->bg_free_bits_count); |
1695 | 1726 | ||
1696 | out: | 1727 | out: |
@@ -1708,7 +1739,6 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, | |||
1708 | { | 1739 | { |
1709 | int status; | 1740 | int status; |
1710 | u16 chain; | 1741 | u16 chain; |
1711 | u32 tmp_used; | ||
1712 | u64 next_group; | 1742 | u64 next_group; |
1713 | struct inode *alloc_inode = ac->ac_inode; | 1743 | struct inode *alloc_inode = ac->ac_inode; |
1714 | struct buffer_head *group_bh = NULL; | 1744 | struct buffer_head *group_bh = NULL; |
@@ -1770,6 +1800,11 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, | |||
1770 | if (!status) | 1800 | if (!status) |
1771 | ocfs2_bg_discontig_fix_result(ac, bg, res); | 1801 | ocfs2_bg_discontig_fix_result(ac, bg, res); |
1772 | 1802 | ||
1803 | /* | ||
1804 | * sr_bg_blkno might have been changed by | ||
1805 | * ocfs2_bg_discontig_fix_result | ||
1806 | */ | ||
1807 | res->sr_bg_stable_blkno = group_bh->b_blocknr; | ||
1773 | 1808 | ||
1774 | /* | 1809 | /* |
1775 | * Keep track of previous block descriptor read. When | 1810 | * Keep track of previous block descriptor read. When |
@@ -1796,22 +1831,17 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, | |||
1796 | } | 1831 | } |
1797 | } | 1832 | } |
1798 | 1833 | ||
1799 | /* Ok, claim our bits now: set the info on dinode, chainlist | 1834 | if (ac->ac_find_loc_only) |
1800 | * and then the group */ | 1835 | goto out_loc_only; |
1801 | status = ocfs2_journal_access_di(handle, | 1836 | |
1802 | INODE_CACHE(alloc_inode), | 1837 | status = ocfs2_alloc_dinode_update_counts(alloc_inode, handle, |
1803 | ac->ac_bh, | 1838 | ac->ac_bh, res->sr_bits, |
1804 | OCFS2_JOURNAL_ACCESS_WRITE); | 1839 | chain); |
1805 | if (status < 0) { | 1840 | if (status) { |
1806 | mlog_errno(status); | 1841 | mlog_errno(status); |
1807 | goto bail; | 1842 | goto bail; |
1808 | } | 1843 | } |
1809 | 1844 | ||
1810 | tmp_used = le32_to_cpu(fe->id1.bitmap1.i_used); | ||
1811 | fe->id1.bitmap1.i_used = cpu_to_le32(res->sr_bits + tmp_used); | ||
1812 | le32_add_cpu(&cl->cl_recs[chain].c_free, -res->sr_bits); | ||
1813 | ocfs2_journal_dirty(handle, ac->ac_bh); | ||
1814 | |||
1815 | status = ocfs2_block_group_set_bits(handle, | 1845 | status = ocfs2_block_group_set_bits(handle, |
1816 | alloc_inode, | 1846 | alloc_inode, |
1817 | bg, | 1847 | bg, |
@@ -1826,6 +1856,7 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, | |||
1826 | mlog(0, "Allocated %u bits from suballocator %llu\n", res->sr_bits, | 1856 | mlog(0, "Allocated %u bits from suballocator %llu\n", res->sr_bits, |
1827 | (unsigned long long)le64_to_cpu(fe->i_blkno)); | 1857 | (unsigned long long)le64_to_cpu(fe->i_blkno)); |
1828 | 1858 | ||
1859 | out_loc_only: | ||
1829 | *bits_left = le16_to_cpu(bg->bg_free_bits_count); | 1860 | *bits_left = le16_to_cpu(bg->bg_free_bits_count); |
1830 | bail: | 1861 | bail: |
1831 | brelse(group_bh); | 1862 | brelse(group_bh); |
@@ -1845,6 +1876,7 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_alloc_context *ac, | |||
1845 | int status; | 1876 | int status; |
1846 | u16 victim, i; | 1877 | u16 victim, i; |
1847 | u16 bits_left = 0; | 1878 | u16 bits_left = 0; |
1879 | u64 hint = ac->ac_last_group; | ||
1848 | struct ocfs2_chain_list *cl; | 1880 | struct ocfs2_chain_list *cl; |
1849 | struct ocfs2_dinode *fe; | 1881 | struct ocfs2_dinode *fe; |
1850 | 1882 | ||
@@ -1872,7 +1904,7 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_alloc_context *ac, | |||
1872 | goto bail; | 1904 | goto bail; |
1873 | } | 1905 | } |
1874 | 1906 | ||
1875 | res->sr_bg_blkno = ac->ac_last_group; | 1907 | res->sr_bg_blkno = hint; |
1876 | if (res->sr_bg_blkno) { | 1908 | if (res->sr_bg_blkno) { |
1877 | /* Attempt to short-circuit the usual search mechanism | 1909 | /* Attempt to short-circuit the usual search mechanism |
1878 | * by jumping straight to the most recently used | 1910 | * by jumping straight to the most recently used |
@@ -1896,8 +1928,10 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_alloc_context *ac, | |||
1896 | 1928 | ||
1897 | status = ocfs2_search_chain(ac, handle, bits_wanted, min_bits, | 1929 | status = ocfs2_search_chain(ac, handle, bits_wanted, min_bits, |
1898 | res, &bits_left); | 1930 | res, &bits_left); |
1899 | if (!status) | 1931 | if (!status) { |
1932 | hint = ocfs2_group_from_res(res); | ||
1900 | goto set_hint; | 1933 | goto set_hint; |
1934 | } | ||
1901 | if (status < 0 && status != -ENOSPC) { | 1935 | if (status < 0 && status != -ENOSPC) { |
1902 | mlog_errno(status); | 1936 | mlog_errno(status); |
1903 | goto bail; | 1937 | goto bail; |
@@ -1920,8 +1954,10 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_alloc_context *ac, | |||
1920 | ac->ac_chain = i; | 1954 | ac->ac_chain = i; |
1921 | status = ocfs2_search_chain(ac, handle, bits_wanted, min_bits, | 1955 | status = ocfs2_search_chain(ac, handle, bits_wanted, min_bits, |
1922 | res, &bits_left); | 1956 | res, &bits_left); |
1923 | if (!status) | 1957 | if (!status) { |
1958 | hint = ocfs2_group_from_res(res); | ||
1924 | break; | 1959 | break; |
1960 | } | ||
1925 | if (status < 0 && status != -ENOSPC) { | 1961 | if (status < 0 && status != -ENOSPC) { |
1926 | mlog_errno(status); | 1962 | mlog_errno(status); |
1927 | goto bail; | 1963 | goto bail; |
@@ -1936,7 +1972,7 @@ set_hint: | |||
1936 | if (bits_left < min_bits) | 1972 | if (bits_left < min_bits) |
1937 | ac->ac_last_group = 0; | 1973 | ac->ac_last_group = 0; |
1938 | else | 1974 | else |
1939 | ac->ac_last_group = res->sr_bg_blkno; | 1975 | ac->ac_last_group = hint; |
1940 | } | 1976 | } |
1941 | 1977 | ||
1942 | bail: | 1978 | bail: |
@@ -2016,6 +2052,136 @@ static inline void ocfs2_save_inode_ac_group(struct inode *dir, | |||
2016 | OCFS2_I(dir)->ip_last_used_slot = ac->ac_alloc_slot; | 2052 | OCFS2_I(dir)->ip_last_used_slot = ac->ac_alloc_slot; |
2017 | } | 2053 | } |
2018 | 2054 | ||
2055 | int ocfs2_find_new_inode_loc(struct inode *dir, | ||
2056 | struct buffer_head *parent_fe_bh, | ||
2057 | struct ocfs2_alloc_context *ac, | ||
2058 | u64 *fe_blkno) | ||
2059 | { | ||
2060 | int ret; | ||
2061 | handle_t *handle = NULL; | ||
2062 | struct ocfs2_suballoc_result *res; | ||
2063 | |||
2064 | BUG_ON(!ac); | ||
2065 | BUG_ON(ac->ac_bits_given != 0); | ||
2066 | BUG_ON(ac->ac_bits_wanted != 1); | ||
2067 | BUG_ON(ac->ac_which != OCFS2_AC_USE_INODE); | ||
2068 | |||
2069 | res = kzalloc(sizeof(*res), GFP_NOFS); | ||
2070 | if (res == NULL) { | ||
2071 | ret = -ENOMEM; | ||
2072 | mlog_errno(ret); | ||
2073 | goto out; | ||
2074 | } | ||
2075 | |||
2076 | ocfs2_init_inode_ac_group(dir, parent_fe_bh, ac); | ||
2077 | |||
2078 | /* | ||
2079 | * The handle started here is for chain relink. Alternatively, | ||
2080 | * we could just disable relink for these calls. | ||
2081 | */ | ||
2082 | handle = ocfs2_start_trans(OCFS2_SB(dir->i_sb), OCFS2_SUBALLOC_ALLOC); | ||
2083 | if (IS_ERR(handle)) { | ||
2084 | ret = PTR_ERR(handle); | ||
2085 | handle = NULL; | ||
2086 | mlog_errno(ret); | ||
2087 | goto out; | ||
2088 | } | ||
2089 | |||
2090 | /* | ||
2091 | * This will instruct ocfs2_claim_suballoc_bits and | ||
2092 | * ocfs2_search_one_group to search but save actual allocation | ||
2093 | * for later. | ||
2094 | */ | ||
2095 | ac->ac_find_loc_only = 1; | ||
2096 | |||
2097 | ret = ocfs2_claim_suballoc_bits(ac, handle, 1, 1, res); | ||
2098 | if (ret < 0) { | ||
2099 | mlog_errno(ret); | ||
2100 | goto out; | ||
2101 | } | ||
2102 | |||
2103 | ac->ac_find_loc_priv = res; | ||
2104 | *fe_blkno = res->sr_blkno; | ||
2105 | |||
2106 | out: | ||
2107 | if (handle) | ||
2108 | ocfs2_commit_trans(OCFS2_SB(dir->i_sb), handle); | ||
2109 | |||
2110 | if (ret) | ||
2111 | kfree(res); | ||
2112 | |||
2113 | return ret; | ||
2114 | } | ||
2115 | |||
2116 | int ocfs2_claim_new_inode_at_loc(handle_t *handle, | ||
2117 | struct inode *dir, | ||
2118 | struct ocfs2_alloc_context *ac, | ||
2119 | u64 *suballoc_loc, | ||
2120 | u16 *suballoc_bit, | ||
2121 | u64 di_blkno) | ||
2122 | { | ||
2123 | int ret; | ||
2124 | u16 chain; | ||
2125 | struct ocfs2_suballoc_result *res = ac->ac_find_loc_priv; | ||
2126 | struct buffer_head *bg_bh = NULL; | ||
2127 | struct ocfs2_group_desc *bg; | ||
2128 | struct ocfs2_dinode *di = (struct ocfs2_dinode *) ac->ac_bh->b_data; | ||
2129 | |||
2130 | /* | ||
2131 | * Since di_blkno is being passed back in, we check for any | ||
2132 | * inconsistencies which may have happened between | ||
2133 | * calls. These are code bugs as di_blkno is not expected to | ||
2134 | * change once returned from ocfs2_find_new_inode_loc() | ||
2135 | */ | ||
2136 | BUG_ON(res->sr_blkno != di_blkno); | ||
2137 | |||
2138 | ret = ocfs2_read_group_descriptor(ac->ac_inode, di, | ||
2139 | res->sr_bg_stable_blkno, &bg_bh); | ||
2140 | if (ret) { | ||
2141 | mlog_errno(ret); | ||
2142 | goto out; | ||
2143 | } | ||
2144 | |||
2145 | bg = (struct ocfs2_group_desc *) bg_bh->b_data; | ||
2146 | chain = le16_to_cpu(bg->bg_chain); | ||
2147 | |||
2148 | ret = ocfs2_alloc_dinode_update_counts(ac->ac_inode, handle, | ||
2149 | ac->ac_bh, res->sr_bits, | ||
2150 | chain); | ||
2151 | if (ret) { | ||
2152 | mlog_errno(ret); | ||
2153 | goto out; | ||
2154 | } | ||
2155 | |||
2156 | ret = ocfs2_block_group_set_bits(handle, | ||
2157 | ac->ac_inode, | ||
2158 | bg, | ||
2159 | bg_bh, | ||
2160 | res->sr_bit_offset, | ||
2161 | res->sr_bits); | ||
2162 | if (ret < 0) { | ||
2163 | mlog_errno(ret); | ||
2164 | goto out; | ||
2165 | } | ||
2166 | |||
2167 | mlog(0, "Allocated %u bits from suballocator %llu\n", res->sr_bits, | ||
2168 | (unsigned long long)di_blkno); | ||
2169 | |||
2170 | atomic_inc(&OCFS2_SB(ac->ac_inode->i_sb)->alloc_stats.bg_allocs); | ||
2171 | |||
2172 | BUG_ON(res->sr_bits != 1); | ||
2173 | |||
2174 | *suballoc_loc = res->sr_bg_blkno; | ||
2175 | *suballoc_bit = res->sr_bit_offset; | ||
2176 | ac->ac_bits_given++; | ||
2177 | ocfs2_save_inode_ac_group(dir, ac); | ||
2178 | |||
2179 | out: | ||
2180 | brelse(bg_bh); | ||
2181 | |||
2182 | return ret; | ||
2183 | } | ||
2184 | |||
2019 | int ocfs2_claim_new_inode(handle_t *handle, | 2185 | int ocfs2_claim_new_inode(handle_t *handle, |
2020 | struct inode *dir, | 2186 | struct inode *dir, |
2021 | struct buffer_head *parent_fe_bh, | 2187 | struct buffer_head *parent_fe_bh, |
@@ -2567,7 +2733,8 @@ out: | |||
2567 | * suballoc_bit. | 2733 | * suballoc_bit. |
2568 | */ | 2734 | */ |
2569 | static int ocfs2_get_suballoc_slot_bit(struct ocfs2_super *osb, u64 blkno, | 2735 | static int ocfs2_get_suballoc_slot_bit(struct ocfs2_super *osb, u64 blkno, |
2570 | u16 *suballoc_slot, u16 *suballoc_bit) | 2736 | u16 *suballoc_slot, u64 *group_blkno, |
2737 | u16 *suballoc_bit) | ||
2571 | { | 2738 | { |
2572 | int status; | 2739 | int status; |
2573 | struct buffer_head *inode_bh = NULL; | 2740 | struct buffer_head *inode_bh = NULL; |
@@ -2604,6 +2771,8 @@ static int ocfs2_get_suballoc_slot_bit(struct ocfs2_super *osb, u64 blkno, | |||
2604 | *suballoc_slot = le16_to_cpu(inode_fe->i_suballoc_slot); | 2771 | *suballoc_slot = le16_to_cpu(inode_fe->i_suballoc_slot); |
2605 | if (suballoc_bit) | 2772 | if (suballoc_bit) |
2606 | *suballoc_bit = le16_to_cpu(inode_fe->i_suballoc_bit); | 2773 | *suballoc_bit = le16_to_cpu(inode_fe->i_suballoc_bit); |
2774 | if (group_blkno) | ||
2775 | *group_blkno = le64_to_cpu(inode_fe->i_suballoc_loc); | ||
2607 | 2776 | ||
2608 | bail: | 2777 | bail: |
2609 | brelse(inode_bh); | 2778 | brelse(inode_bh); |
@@ -2621,7 +2790,8 @@ bail: | |||
2621 | */ | 2790 | */ |
2622 | static int ocfs2_test_suballoc_bit(struct ocfs2_super *osb, | 2791 | static int ocfs2_test_suballoc_bit(struct ocfs2_super *osb, |
2623 | struct inode *suballoc, | 2792 | struct inode *suballoc, |
2624 | struct buffer_head *alloc_bh, u64 blkno, | 2793 | struct buffer_head *alloc_bh, |
2794 | u64 group_blkno, u64 blkno, | ||
2625 | u16 bit, int *res) | 2795 | u16 bit, int *res) |
2626 | { | 2796 | { |
2627 | struct ocfs2_dinode *alloc_di; | 2797 | struct ocfs2_dinode *alloc_di; |
@@ -2642,10 +2812,8 @@ static int ocfs2_test_suballoc_bit(struct ocfs2_super *osb, | |||
2642 | goto bail; | 2812 | goto bail; |
2643 | } | 2813 | } |
2644 | 2814 | ||
2645 | if (alloc_di->i_suballoc_loc) | 2815 | bg_blkno = group_blkno ? group_blkno : |
2646 | bg_blkno = le64_to_cpu(alloc_di->i_suballoc_loc); | 2816 | ocfs2_which_suballoc_group(blkno, bit); |
2647 | else | ||
2648 | bg_blkno = ocfs2_which_suballoc_group(blkno, bit); | ||
2649 | status = ocfs2_read_group_descriptor(suballoc, alloc_di, bg_blkno, | 2817 | status = ocfs2_read_group_descriptor(suballoc, alloc_di, bg_blkno, |
2650 | &group_bh); | 2818 | &group_bh); |
2651 | if (status < 0) { | 2819 | if (status < 0) { |
@@ -2680,6 +2848,7 @@ bail: | |||
2680 | int ocfs2_test_inode_bit(struct ocfs2_super *osb, u64 blkno, int *res) | 2848 | int ocfs2_test_inode_bit(struct ocfs2_super *osb, u64 blkno, int *res) |
2681 | { | 2849 | { |
2682 | int status; | 2850 | int status; |
2851 | u64 group_blkno = 0; | ||
2683 | u16 suballoc_bit = 0, suballoc_slot = 0; | 2852 | u16 suballoc_bit = 0, suballoc_slot = 0; |
2684 | struct inode *inode_alloc_inode; | 2853 | struct inode *inode_alloc_inode; |
2685 | struct buffer_head *alloc_bh = NULL; | 2854 | struct buffer_head *alloc_bh = NULL; |
@@ -2687,7 +2856,7 @@ int ocfs2_test_inode_bit(struct ocfs2_super *osb, u64 blkno, int *res) | |||
2687 | mlog_entry("blkno: %llu", (unsigned long long)blkno); | 2856 | mlog_entry("blkno: %llu", (unsigned long long)blkno); |
2688 | 2857 | ||
2689 | status = ocfs2_get_suballoc_slot_bit(osb, blkno, &suballoc_slot, | 2858 | status = ocfs2_get_suballoc_slot_bit(osb, blkno, &suballoc_slot, |
2690 | &suballoc_bit); | 2859 | &group_blkno, &suballoc_bit); |
2691 | if (status < 0) { | 2860 | if (status < 0) { |
2692 | mlog(ML_ERROR, "get alloc slot and bit failed %d\n", status); | 2861 | mlog(ML_ERROR, "get alloc slot and bit failed %d\n", status); |
2693 | goto bail; | 2862 | goto bail; |
@@ -2715,7 +2884,7 @@ int ocfs2_test_inode_bit(struct ocfs2_super *osb, u64 blkno, int *res) | |||
2715 | } | 2884 | } |
2716 | 2885 | ||
2717 | status = ocfs2_test_suballoc_bit(osb, inode_alloc_inode, alloc_bh, | 2886 | status = ocfs2_test_suballoc_bit(osb, inode_alloc_inode, alloc_bh, |
2718 | blkno, suballoc_bit, res); | 2887 | group_blkno, blkno, suballoc_bit, res); |
2719 | if (status < 0) | 2888 | if (status < 0) |
2720 | mlog(ML_ERROR, "test suballoc bit failed %d\n", status); | 2889 | mlog(ML_ERROR, "test suballoc bit failed %d\n", status); |
2721 | 2890 | ||
diff --git a/fs/ocfs2/suballoc.h b/fs/ocfs2/suballoc.h index a017dd3ee7d..b8afabfeede 100644 --- a/fs/ocfs2/suballoc.h +++ b/fs/ocfs2/suballoc.h | |||
@@ -56,6 +56,9 @@ struct ocfs2_alloc_context { | |||
56 | u64 ac_max_block; /* Highest block number to allocate. 0 is | 56 | u64 ac_max_block; /* Highest block number to allocate. 0 is |
57 | is the same as ~0 - unlimited */ | 57 | is the same as ~0 - unlimited */ |
58 | 58 | ||
59 | int ac_find_loc_only; /* hack for reflink operation ordering */ | ||
60 | struct ocfs2_suballoc_result *ac_find_loc_priv; /* */ | ||
61 | |||
59 | struct ocfs2_alloc_reservation *ac_resv; | 62 | struct ocfs2_alloc_reservation *ac_resv; |
60 | }; | 63 | }; |
61 | 64 | ||
@@ -197,4 +200,22 @@ int ocfs2_lock_allocators(struct inode *inode, struct ocfs2_extent_tree *et, | |||
197 | struct ocfs2_alloc_context **meta_ac); | 200 | struct ocfs2_alloc_context **meta_ac); |
198 | 201 | ||
199 | int ocfs2_test_inode_bit(struct ocfs2_super *osb, u64 blkno, int *res); | 202 | int ocfs2_test_inode_bit(struct ocfs2_super *osb, u64 blkno, int *res); |
203 | |||
204 | |||
205 | |||
206 | /* | ||
207 | * The following two interfaces are for ocfs2_create_inode_in_orphan(). | ||
208 | */ | ||
209 | int ocfs2_find_new_inode_loc(struct inode *dir, | ||
210 | struct buffer_head *parent_fe_bh, | ||
211 | struct ocfs2_alloc_context *ac, | ||
212 | u64 *fe_blkno); | ||
213 | |||
214 | int ocfs2_claim_new_inode_at_loc(handle_t *handle, | ||
215 | struct inode *dir, | ||
216 | struct ocfs2_alloc_context *ac, | ||
217 | u64 *suballoc_loc, | ||
218 | u16 *suballoc_bit, | ||
219 | u64 di_blkno); | ||
220 | |||
200 | #endif /* _CHAINALLOC_H_ */ | 221 | #endif /* _CHAINALLOC_H_ */ |
diff --git a/fs/ocfs2/symlink.c b/fs/ocfs2/symlink.c index 32499d213fc..9975457c981 100644 --- a/fs/ocfs2/symlink.c +++ b/fs/ocfs2/symlink.c | |||
@@ -128,7 +128,7 @@ static void *ocfs2_fast_follow_link(struct dentry *dentry, | |||
128 | } | 128 | } |
129 | 129 | ||
130 | /* Fast symlinks can't be large */ | 130 | /* Fast symlinks can't be large */ |
131 | len = strlen(target); | 131 | len = strnlen(target, ocfs2_fast_symlink_chars(inode->i_sb)); |
132 | link = kzalloc(len + 1, GFP_NOFS); | 132 | link = kzalloc(len + 1, GFP_NOFS); |
133 | if (!link) { | 133 | if (!link) { |
134 | status = -ENOMEM; | 134 | status = -ENOMEM; |
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index d03469f6180..06fa5e77c40 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c | |||
@@ -1286,13 +1286,11 @@ int ocfs2_xattr_get_nolock(struct inode *inode, | |||
1286 | xis.inode_bh = xbs.inode_bh = di_bh; | 1286 | xis.inode_bh = xbs.inode_bh = di_bh; |
1287 | di = (struct ocfs2_dinode *)di_bh->b_data; | 1287 | di = (struct ocfs2_dinode *)di_bh->b_data; |
1288 | 1288 | ||
1289 | down_read(&oi->ip_xattr_sem); | ||
1290 | ret = ocfs2_xattr_ibody_get(inode, name_index, name, buffer, | 1289 | ret = ocfs2_xattr_ibody_get(inode, name_index, name, buffer, |
1291 | buffer_size, &xis); | 1290 | buffer_size, &xis); |
1292 | if (ret == -ENODATA && di->i_xattr_loc) | 1291 | if (ret == -ENODATA && di->i_xattr_loc) |
1293 | ret = ocfs2_xattr_block_get(inode, name_index, name, buffer, | 1292 | ret = ocfs2_xattr_block_get(inode, name_index, name, buffer, |
1294 | buffer_size, &xbs); | 1293 | buffer_size, &xbs); |
1295 | up_read(&oi->ip_xattr_sem); | ||
1296 | 1294 | ||
1297 | return ret; | 1295 | return ret; |
1298 | } | 1296 | } |
@@ -1316,8 +1314,10 @@ static int ocfs2_xattr_get(struct inode *inode, | |||
1316 | mlog_errno(ret); | 1314 | mlog_errno(ret); |
1317 | return ret; | 1315 | return ret; |
1318 | } | 1316 | } |
1317 | down_read(&OCFS2_I(inode)->ip_xattr_sem); | ||
1319 | ret = ocfs2_xattr_get_nolock(inode, di_bh, name_index, | 1318 | ret = ocfs2_xattr_get_nolock(inode, di_bh, name_index, |
1320 | name, buffer, buffer_size); | 1319 | name, buffer, buffer_size); |
1320 | up_read(&OCFS2_I(inode)->ip_xattr_sem); | ||
1321 | 1321 | ||
1322 | ocfs2_inode_unlock(inode, 0); | 1322 | ocfs2_inode_unlock(inode, 0); |
1323 | 1323 | ||
diff --git a/fs/proc/base.c b/fs/proc/base.c index a1c43e7c8a7..8e4addaa542 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -2675,7 +2675,7 @@ static const struct pid_entry tgid_base_stuff[] = { | |||
2675 | INF("auxv", S_IRUSR, proc_pid_auxv), | 2675 | INF("auxv", S_IRUSR, proc_pid_auxv), |
2676 | ONE("status", S_IRUGO, proc_pid_status), | 2676 | ONE("status", S_IRUGO, proc_pid_status), |
2677 | ONE("personality", S_IRUSR, proc_pid_personality), | 2677 | ONE("personality", S_IRUSR, proc_pid_personality), |
2678 | INF("limits", S_IRUSR, proc_pid_limits), | 2678 | INF("limits", S_IRUGO, proc_pid_limits), |
2679 | #ifdef CONFIG_SCHED_DEBUG | 2679 | #ifdef CONFIG_SCHED_DEBUG |
2680 | REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), | 2680 | REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), |
2681 | #endif | 2681 | #endif |
@@ -3011,7 +3011,7 @@ static const struct pid_entry tid_base_stuff[] = { | |||
3011 | INF("auxv", S_IRUSR, proc_pid_auxv), | 3011 | INF("auxv", S_IRUSR, proc_pid_auxv), |
3012 | ONE("status", S_IRUGO, proc_pid_status), | 3012 | ONE("status", S_IRUGO, proc_pid_status), |
3013 | ONE("personality", S_IRUSR, proc_pid_personality), | 3013 | ONE("personality", S_IRUSR, proc_pid_personality), |
3014 | INF("limits", S_IRUSR, proc_pid_limits), | 3014 | INF("limits", S_IRUGO, proc_pid_limits), |
3015 | #ifdef CONFIG_SCHED_DEBUG | 3015 | #ifdef CONFIG_SCHED_DEBUG |
3016 | REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), | 3016 | REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), |
3017 | #endif | 3017 | #endif |
diff --git a/fs/proc/page.c b/fs/proc/page.c index 180cf5a0bd6..3b8b4566033 100644 --- a/fs/proc/page.c +++ b/fs/proc/page.c | |||
@@ -146,7 +146,7 @@ u64 stable_page_flags(struct page *page) | |||
146 | u |= kpf_copy_bit(k, KPF_HWPOISON, PG_hwpoison); | 146 | u |= kpf_copy_bit(k, KPF_HWPOISON, PG_hwpoison); |
147 | #endif | 147 | #endif |
148 | 148 | ||
149 | #ifdef CONFIG_IA64_UNCACHED_ALLOCATOR | 149 | #ifdef CONFIG_ARCH_USES_PG_UNCACHED |
150 | u |= kpf_copy_bit(k, KPF_UNCACHED, PG_uncached); | 150 | u |= kpf_copy_bit(k, KPF_UNCACHED, PG_uncached); |
151 | #endif | 151 | #endif |
152 | 152 | ||
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 439fc1f1c1c..1dbca4e8cc1 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
@@ -224,7 +224,8 @@ static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma) | |||
224 | /* We don't show the stack guard page in /proc/maps */ | 224 | /* We don't show the stack guard page in /proc/maps */ |
225 | start = vma->vm_start; | 225 | start = vma->vm_start; |
226 | if (vma->vm_flags & VM_GROWSDOWN) | 226 | if (vma->vm_flags & VM_GROWSDOWN) |
227 | start += PAGE_SIZE; | 227 | if (!vma_stack_continue(vma->vm_prev, vma->vm_start)) |
228 | start += PAGE_SIZE; | ||
228 | 229 | ||
229 | seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu %n", | 230 | seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu %n", |
230 | start, | 231 | start, |
@@ -362,13 +363,13 @@ static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, | |||
362 | mss->referenced += PAGE_SIZE; | 363 | mss->referenced += PAGE_SIZE; |
363 | mapcount = page_mapcount(page); | 364 | mapcount = page_mapcount(page); |
364 | if (mapcount >= 2) { | 365 | if (mapcount >= 2) { |
365 | if (pte_dirty(ptent)) | 366 | if (pte_dirty(ptent) || PageDirty(page)) |
366 | mss->shared_dirty += PAGE_SIZE; | 367 | mss->shared_dirty += PAGE_SIZE; |
367 | else | 368 | else |
368 | mss->shared_clean += PAGE_SIZE; | 369 | mss->shared_clean += PAGE_SIZE; |
369 | mss->pss += (PAGE_SIZE << PSS_SHIFT) / mapcount; | 370 | mss->pss += (PAGE_SIZE << PSS_SHIFT) / mapcount; |
370 | } else { | 371 | } else { |
371 | if (pte_dirty(ptent)) | 372 | if (pte_dirty(ptent) || PageDirty(page)) |
372 | mss->private_dirty += PAGE_SIZE; | 373 | mss->private_dirty += PAGE_SIZE; |
373 | else | 374 | else |
374 | mss->private_clean += PAGE_SIZE; | 375 | mss->private_clean += PAGE_SIZE; |
diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c index 91c817ff02c..2367fb3f70b 100644 --- a/fs/proc/vmcore.c +++ b/fs/proc/vmcore.c | |||
@@ -163,7 +163,7 @@ static ssize_t read_vmcore(struct file *file, char __user *buffer, | |||
163 | 163 | ||
164 | static const struct file_operations proc_vmcore_operations = { | 164 | static const struct file_operations proc_vmcore_operations = { |
165 | .read = read_vmcore, | 165 | .read = read_vmcore, |
166 | .llseek = generic_file_llseek, | 166 | .llseek = default_llseek, |
167 | }; | 167 | }; |
168 | 168 | ||
169 | static struct vmcore* __init get_new_element(void) | 169 | static struct vmcore* __init get_new_element(void) |
diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c index f53505de071..5cbb81e134a 100644 --- a/fs/reiserfs/ioctl.c +++ b/fs/reiserfs/ioctl.c | |||
@@ -170,6 +170,7 @@ int reiserfs_prepare_write(struct file *f, struct page *page, | |||
170 | int reiserfs_unpack(struct inode *inode, struct file *filp) | 170 | int reiserfs_unpack(struct inode *inode, struct file *filp) |
171 | { | 171 | { |
172 | int retval = 0; | 172 | int retval = 0; |
173 | int depth; | ||
173 | int index; | 174 | int index; |
174 | struct page *page; | 175 | struct page *page; |
175 | struct address_space *mapping; | 176 | struct address_space *mapping; |
@@ -188,8 +189,8 @@ int reiserfs_unpack(struct inode *inode, struct file *filp) | |||
188 | /* we need to make sure nobody is changing the file size beneath | 189 | /* we need to make sure nobody is changing the file size beneath |
189 | ** us | 190 | ** us |
190 | */ | 191 | */ |
191 | mutex_lock(&inode->i_mutex); | 192 | reiserfs_mutex_lock_safe(&inode->i_mutex, inode->i_sb); |
192 | reiserfs_write_lock(inode->i_sb); | 193 | depth = reiserfs_write_lock_once(inode->i_sb); |
193 | 194 | ||
194 | write_from = inode->i_size & (blocksize - 1); | 195 | write_from = inode->i_size & (blocksize - 1); |
195 | /* if we are on a block boundary, we are already unpacked. */ | 196 | /* if we are on a block boundary, we are already unpacked. */ |
@@ -224,6 +225,6 @@ int reiserfs_unpack(struct inode *inode, struct file *filp) | |||
224 | 225 | ||
225 | out: | 226 | out: |
226 | mutex_unlock(&inode->i_mutex); | 227 | mutex_unlock(&inode->i_mutex); |
227 | reiserfs_write_unlock(inode->i_sb); | 228 | reiserfs_write_unlock_once(inode->i_sb, depth); |
228 | return retval; | 229 | return retval; |
229 | } | 230 | } |
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 1b27b5688f6..da3fefe91a8 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c | |||
@@ -340,7 +340,7 @@ static int sysfs_open_file(struct inode *inode, struct file *file) | |||
340 | char *p; | 340 | char *p; |
341 | 341 | ||
342 | p = d_path(&file->f_path, last_sysfs_file, sizeof(last_sysfs_file)); | 342 | p = d_path(&file->f_path, last_sysfs_file, sizeof(last_sysfs_file)); |
343 | if (p) | 343 | if (!IS_ERR(p)) |
344 | memmove(last_sysfs_file, p, strlen(p) + 1); | 344 | memmove(last_sysfs_file, p, strlen(p) + 1); |
345 | 345 | ||
346 | /* need attr_sd for attr and ops, its parent for kobj */ | 346 | /* need attr_sd for attr and ops, its parent for kobj */ |
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 15412fe15c3..b552f816de1 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c | |||
@@ -852,8 +852,8 @@ xfs_convert_page( | |||
852 | SetPageUptodate(page); | 852 | SetPageUptodate(page); |
853 | 853 | ||
854 | if (count) { | 854 | if (count) { |
855 | wbc->nr_to_write--; | 855 | if (--wbc->nr_to_write <= 0 && |
856 | if (wbc->nr_to_write <= 0) | 856 | wbc->sync_mode == WB_SYNC_NONE) |
857 | done = 1; | 857 | done = 1; |
858 | } | 858 | } |
859 | xfs_start_page_writeback(page, !page_dirty, count); | 859 | xfs_start_page_writeback(page, !page_dirty, count); |
@@ -1068,7 +1068,7 @@ xfs_vm_writepage( | |||
1068 | * by themselves. | 1068 | * by themselves. |
1069 | */ | 1069 | */ |
1070 | if ((current->flags & (PF_MEMALLOC|PF_KSWAPD)) == PF_MEMALLOC) | 1070 | if ((current->flags & (PF_MEMALLOC|PF_KSWAPD)) == PF_MEMALLOC) |
1071 | goto out_fail; | 1071 | goto redirty; |
1072 | 1072 | ||
1073 | /* | 1073 | /* |
1074 | * We need a transaction if there are delalloc or unwritten buffers | 1074 | * We need a transaction if there are delalloc or unwritten buffers |
@@ -1080,7 +1080,7 @@ xfs_vm_writepage( | |||
1080 | */ | 1080 | */ |
1081 | xfs_count_page_state(page, &delalloc, &unwritten); | 1081 | xfs_count_page_state(page, &delalloc, &unwritten); |
1082 | if ((current->flags & PF_FSTRANS) && (delalloc || unwritten)) | 1082 | if ((current->flags & PF_FSTRANS) && (delalloc || unwritten)) |
1083 | goto out_fail; | 1083 | goto redirty; |
1084 | 1084 | ||
1085 | /* Is this page beyond the end of the file? */ | 1085 | /* Is this page beyond the end of the file? */ |
1086 | offset = i_size_read(inode); | 1086 | offset = i_size_read(inode); |
@@ -1245,12 +1245,15 @@ error: | |||
1245 | if (iohead) | 1245 | if (iohead) |
1246 | xfs_cancel_ioend(iohead); | 1246 | xfs_cancel_ioend(iohead); |
1247 | 1247 | ||
1248 | if (err == -EAGAIN) | ||
1249 | goto redirty; | ||
1250 | |||
1248 | xfs_aops_discard_page(page); | 1251 | xfs_aops_discard_page(page); |
1249 | ClearPageUptodate(page); | 1252 | ClearPageUptodate(page); |
1250 | unlock_page(page); | 1253 | unlock_page(page); |
1251 | return err; | 1254 | return err; |
1252 | 1255 | ||
1253 | out_fail: | 1256 | redirty: |
1254 | redirty_page_for_writepage(wbc, page); | 1257 | redirty_page_for_writepage(wbc, page); |
1255 | unlock_page(page); | 1258 | unlock_page(page); |
1256 | return 0; | 1259 | return 0; |
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index b93ea334228..1846a0dd703 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c | |||
@@ -440,12 +440,7 @@ _xfs_buf_find( | |||
440 | ASSERT(btp == bp->b_target); | 440 | ASSERT(btp == bp->b_target); |
441 | if (bp->b_file_offset == range_base && | 441 | if (bp->b_file_offset == range_base && |
442 | bp->b_buffer_length == range_length) { | 442 | bp->b_buffer_length == range_length) { |
443 | /* | ||
444 | * If we look at something, bring it to the | ||
445 | * front of the list for next time. | ||
446 | */ | ||
447 | atomic_inc(&bp->b_hold); | 443 | atomic_inc(&bp->b_hold); |
448 | list_move(&bp->b_hash_list, &hash->bh_list); | ||
449 | goto found; | 444 | goto found; |
450 | } | 445 | } |
451 | } | 446 | } |
@@ -1431,8 +1426,7 @@ xfs_alloc_bufhash( | |||
1431 | { | 1426 | { |
1432 | unsigned int i; | 1427 | unsigned int i; |
1433 | 1428 | ||
1434 | btp->bt_hashshift = external ? 3 : 8; /* 8 or 256 buckets */ | 1429 | btp->bt_hashshift = external ? 3 : 12; /* 8 or 4096 buckets */ |
1435 | btp->bt_hashmask = (1 << btp->bt_hashshift) - 1; | ||
1436 | btp->bt_hash = kmem_zalloc_large((1 << btp->bt_hashshift) * | 1430 | btp->bt_hash = kmem_zalloc_large((1 << btp->bt_hashshift) * |
1437 | sizeof(xfs_bufhash_t)); | 1431 | sizeof(xfs_bufhash_t)); |
1438 | for (i = 0; i < (1 << btp->bt_hashshift); i++) { | 1432 | for (i = 0; i < (1 << btp->bt_hashshift); i++) { |
@@ -1926,7 +1920,8 @@ xfs_buf_init(void) | |||
1926 | if (!xfs_buf_zone) | 1920 | if (!xfs_buf_zone) |
1927 | goto out; | 1921 | goto out; |
1928 | 1922 | ||
1929 | xfslogd_workqueue = create_workqueue("xfslogd"); | 1923 | xfslogd_workqueue = alloc_workqueue("xfslogd", |
1924 | WQ_RESCUER | WQ_HIGHPRI, 1); | ||
1930 | if (!xfslogd_workqueue) | 1925 | if (!xfslogd_workqueue) |
1931 | goto out_free_buf_zone; | 1926 | goto out_free_buf_zone; |
1932 | 1927 | ||
diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h index d533d64e2c3..9d021c73ea5 100644 --- a/fs/xfs/linux-2.6/xfs_buf.h +++ b/fs/xfs/linux-2.6/xfs_buf.h | |||
@@ -128,7 +128,6 @@ typedef struct xfs_buftarg { | |||
128 | size_t bt_smask; | 128 | size_t bt_smask; |
129 | 129 | ||
130 | /* per device buffer hash table */ | 130 | /* per device buffer hash table */ |
131 | uint bt_hashmask; | ||
132 | uint bt_hashshift; | 131 | uint bt_hashshift; |
133 | xfs_bufhash_t *bt_hash; | 132 | xfs_bufhash_t *bt_hash; |
134 | 133 | ||
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c index 237f5ffb2ee..3b9e626f7cd 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/fs/xfs/linux-2.6/xfs_ioctl.c | |||
@@ -785,6 +785,8 @@ xfs_ioc_fsgetxattr( | |||
785 | { | 785 | { |
786 | struct fsxattr fa; | 786 | struct fsxattr fa; |
787 | 787 | ||
788 | memset(&fa, 0, sizeof(struct fsxattr)); | ||
789 | |||
788 | xfs_ilock(ip, XFS_ILOCK_SHARED); | 790 | xfs_ilock(ip, XFS_ILOCK_SHARED); |
789 | fa.fsx_xflags = xfs_ip2xflags(ip); | 791 | fa.fsx_xflags = xfs_ip2xflags(ip); |
790 | fa.fsx_extsize = ip->i_d.di_extsize << ip->i_mount->m_sb.sb_blocklog; | 792 | fa.fsx_extsize = ip->i_d.di_extsize << ip->i_mount->m_sb.sb_blocklog; |
@@ -907,6 +909,13 @@ xfs_ioctl_setattr( | |||
907 | return XFS_ERROR(EIO); | 909 | return XFS_ERROR(EIO); |
908 | 910 | ||
909 | /* | 911 | /* |
912 | * Disallow 32bit project ids because on-disk structure | ||
913 | * is 16bit only. | ||
914 | */ | ||
915 | if ((mask & FSX_PROJID) && (fa->fsx_projid > (__uint16_t)-1)) | ||
916 | return XFS_ERROR(EINVAL); | ||
917 | |||
918 | /* | ||
910 | * If disk quotas is on, we make sure that the dquots do exist on disk, | 919 | * If disk quotas is on, we make sure that the dquots do exist on disk, |
911 | * before we start any other transactions. Trying to do this later | 920 | * before we start any other transactions. Trying to do this later |
912 | * is messy. We don't care to take a readlock to look at the ids | 921 | * is messy. We don't care to take a readlock to look at the ids |
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 68be25dcd30..b1fc2a6bfe8 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c | |||
@@ -664,7 +664,7 @@ xfs_vn_fiemap( | |||
664 | fieinfo->fi_extents_max + 1; | 664 | fieinfo->fi_extents_max + 1; |
665 | bm.bmv_count = min_t(__s32, bm.bmv_count, | 665 | bm.bmv_count = min_t(__s32, bm.bmv_count, |
666 | (PAGE_SIZE * 16 / sizeof(struct getbmapx))); | 666 | (PAGE_SIZE * 16 / sizeof(struct getbmapx))); |
667 | bm.bmv_iflags = BMV_IF_PREALLOC; | 667 | bm.bmv_iflags = BMV_IF_PREALLOC | BMV_IF_NO_HOLES; |
668 | if (fieinfo->fi_flags & FIEMAP_FLAG_XATTR) | 668 | if (fieinfo->fi_flags & FIEMAP_FLAG_XATTR) |
669 | bm.bmv_iflags |= BMV_IF_ATTRFORK; | 669 | bm.bmv_iflags |= BMV_IF_ATTRFORK; |
670 | if (!(fieinfo->fi_flags & FIEMAP_FLAG_SYNC)) | 670 | if (!(fieinfo->fi_flags & FIEMAP_FLAG_SYNC)) |
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 5fa7a30cc3f..08fd3102128 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
@@ -1225,6 +1225,7 @@ xfs_fs_statfs( | |||
1225 | struct xfs_inode *ip = XFS_I(dentry->d_inode); | 1225 | struct xfs_inode *ip = XFS_I(dentry->d_inode); |
1226 | __uint64_t fakeinos, id; | 1226 | __uint64_t fakeinos, id; |
1227 | xfs_extlen_t lsize; | 1227 | xfs_extlen_t lsize; |
1228 | __int64_t ffree; | ||
1228 | 1229 | ||
1229 | statp->f_type = XFS_SB_MAGIC; | 1230 | statp->f_type = XFS_SB_MAGIC; |
1230 | statp->f_namelen = MAXNAMELEN - 1; | 1231 | statp->f_namelen = MAXNAMELEN - 1; |
@@ -1248,7 +1249,11 @@ xfs_fs_statfs( | |||
1248 | statp->f_files = min_t(typeof(statp->f_files), | 1249 | statp->f_files = min_t(typeof(statp->f_files), |
1249 | statp->f_files, | 1250 | statp->f_files, |
1250 | mp->m_maxicount); | 1251 | mp->m_maxicount); |
1251 | statp->f_ffree = statp->f_files - (sbp->sb_icount - sbp->sb_ifree); | 1252 | |
1253 | /* make sure statp->f_ffree does not underflow */ | ||
1254 | ffree = statp->f_files - (sbp->sb_icount - sbp->sb_ifree); | ||
1255 | statp->f_ffree = max_t(__int64_t, ffree, 0); | ||
1256 | |||
1252 | spin_unlock(&mp->m_sb_lock); | 1257 | spin_unlock(&mp->m_sb_lock); |
1253 | 1258 | ||
1254 | if ((ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) || | 1259 | if ((ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) || |
@@ -1401,7 +1406,7 @@ xfs_fs_freeze( | |||
1401 | 1406 | ||
1402 | xfs_save_resvblks(mp); | 1407 | xfs_save_resvblks(mp); |
1403 | xfs_quiesce_attr(mp); | 1408 | xfs_quiesce_attr(mp); |
1404 | return -xfs_fs_log_dummy(mp); | 1409 | return -xfs_fs_log_dummy(mp, SYNC_WAIT); |
1405 | } | 1410 | } |
1406 | 1411 | ||
1407 | STATIC int | 1412 | STATIC int |
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c index dfcbd98d159..81976ffed7d 100644 --- a/fs/xfs/linux-2.6/xfs_sync.c +++ b/fs/xfs/linux-2.6/xfs_sync.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include "xfs_inode_item.h" | 34 | #include "xfs_inode_item.h" |
35 | #include "xfs_quota.h" | 35 | #include "xfs_quota.h" |
36 | #include "xfs_trace.h" | 36 | #include "xfs_trace.h" |
37 | #include "xfs_fsops.h" | ||
37 | 38 | ||
38 | #include <linux/kthread.h> | 39 | #include <linux/kthread.h> |
39 | #include <linux/freezer.h> | 40 | #include <linux/freezer.h> |
@@ -341,38 +342,6 @@ xfs_sync_attr( | |||
341 | } | 342 | } |
342 | 343 | ||
343 | STATIC int | 344 | STATIC int |
344 | xfs_commit_dummy_trans( | ||
345 | struct xfs_mount *mp, | ||
346 | uint flags) | ||
347 | { | ||
348 | struct xfs_inode *ip = mp->m_rootip; | ||
349 | struct xfs_trans *tp; | ||
350 | int error; | ||
351 | |||
352 | /* | ||
353 | * Put a dummy transaction in the log to tell recovery | ||
354 | * that all others are OK. | ||
355 | */ | ||
356 | tp = xfs_trans_alloc(mp, XFS_TRANS_DUMMY1); | ||
357 | error = xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), 0, 0, 0); | ||
358 | if (error) { | ||
359 | xfs_trans_cancel(tp, 0); | ||
360 | return error; | ||
361 | } | ||
362 | |||
363 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
364 | |||
365 | xfs_trans_ijoin(tp, ip); | ||
366 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | ||
367 | error = xfs_trans_commit(tp, 0); | ||
368 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
369 | |||
370 | /* the log force ensures this transaction is pushed to disk */ | ||
371 | xfs_log_force(mp, (flags & SYNC_WAIT) ? XFS_LOG_SYNC : 0); | ||
372 | return error; | ||
373 | } | ||
374 | |||
375 | STATIC int | ||
376 | xfs_sync_fsdata( | 345 | xfs_sync_fsdata( |
377 | struct xfs_mount *mp) | 346 | struct xfs_mount *mp) |
378 | { | 347 | { |
@@ -432,7 +401,7 @@ xfs_quiesce_data( | |||
432 | 401 | ||
433 | /* mark the log as covered if needed */ | 402 | /* mark the log as covered if needed */ |
434 | if (xfs_log_need_covered(mp)) | 403 | if (xfs_log_need_covered(mp)) |
435 | error2 = xfs_commit_dummy_trans(mp, SYNC_WAIT); | 404 | error2 = xfs_fs_log_dummy(mp, SYNC_WAIT); |
436 | 405 | ||
437 | /* flush data-only devices */ | 406 | /* flush data-only devices */ |
438 | if (mp->m_rtdev_targp) | 407 | if (mp->m_rtdev_targp) |
@@ -563,7 +532,7 @@ xfs_flush_inodes( | |||
563 | /* | 532 | /* |
564 | * Every sync period we need to unpin all items, reclaim inodes and sync | 533 | * Every sync period we need to unpin all items, reclaim inodes and sync |
565 | * disk quotas. We might need to cover the log to indicate that the | 534 | * disk quotas. We might need to cover the log to indicate that the |
566 | * filesystem is idle. | 535 | * filesystem is idle and not frozen. |
567 | */ | 536 | */ |
568 | STATIC void | 537 | STATIC void |
569 | xfs_sync_worker( | 538 | xfs_sync_worker( |
@@ -577,8 +546,9 @@ xfs_sync_worker( | |||
577 | xfs_reclaim_inodes(mp, 0); | 546 | xfs_reclaim_inodes(mp, 0); |
578 | /* dgc: errors ignored here */ | 547 | /* dgc: errors ignored here */ |
579 | error = xfs_qm_sync(mp, SYNC_TRYLOCK); | 548 | error = xfs_qm_sync(mp, SYNC_TRYLOCK); |
580 | if (xfs_log_need_covered(mp)) | 549 | if (mp->m_super->s_frozen == SB_UNFROZEN && |
581 | error = xfs_commit_dummy_trans(mp, 0); | 550 | xfs_log_need_covered(mp)) |
551 | error = xfs_fs_log_dummy(mp, 0); | ||
582 | } | 552 | } |
583 | mp->m_sync_seq++; | 553 | mp->m_sync_seq++; |
584 | wake_up(&mp->m_wait_single_sync_task); | 554 | wake_up(&mp->m_wait_single_sync_task); |
@@ -698,14 +668,11 @@ xfs_inode_set_reclaim_tag( | |||
698 | xfs_perag_put(pag); | 668 | xfs_perag_put(pag); |
699 | } | 669 | } |
700 | 670 | ||
701 | void | 671 | STATIC void |
702 | __xfs_inode_clear_reclaim_tag( | 672 | __xfs_inode_clear_reclaim( |
703 | xfs_mount_t *mp, | ||
704 | xfs_perag_t *pag, | 673 | xfs_perag_t *pag, |
705 | xfs_inode_t *ip) | 674 | xfs_inode_t *ip) |
706 | { | 675 | { |
707 | radix_tree_tag_clear(&pag->pag_ici_root, | ||
708 | XFS_INO_TO_AGINO(mp, ip->i_ino), XFS_ICI_RECLAIM_TAG); | ||
709 | pag->pag_ici_reclaimable--; | 676 | pag->pag_ici_reclaimable--; |
710 | if (!pag->pag_ici_reclaimable) { | 677 | if (!pag->pag_ici_reclaimable) { |
711 | /* clear the reclaim tag from the perag radix tree */ | 678 | /* clear the reclaim tag from the perag radix tree */ |
@@ -719,6 +686,17 @@ __xfs_inode_clear_reclaim_tag( | |||
719 | } | 686 | } |
720 | } | 687 | } |
721 | 688 | ||
689 | void | ||
690 | __xfs_inode_clear_reclaim_tag( | ||
691 | xfs_mount_t *mp, | ||
692 | xfs_perag_t *pag, | ||
693 | xfs_inode_t *ip) | ||
694 | { | ||
695 | radix_tree_tag_clear(&pag->pag_ici_root, | ||
696 | XFS_INO_TO_AGINO(mp, ip->i_ino), XFS_ICI_RECLAIM_TAG); | ||
697 | __xfs_inode_clear_reclaim(pag, ip); | ||
698 | } | ||
699 | |||
722 | /* | 700 | /* |
723 | * Inodes in different states need to be treated differently, and the return | 701 | * Inodes in different states need to be treated differently, and the return |
724 | * value of xfs_iflush is not sufficient to get this right. The following table | 702 | * value of xfs_iflush is not sufficient to get this right. The following table |
@@ -868,6 +846,7 @@ reclaim: | |||
868 | if (!radix_tree_delete(&pag->pag_ici_root, | 846 | if (!radix_tree_delete(&pag->pag_ici_root, |
869 | XFS_INO_TO_AGINO(ip->i_mount, ip->i_ino))) | 847 | XFS_INO_TO_AGINO(ip->i_mount, ip->i_ino))) |
870 | ASSERT(0); | 848 | ASSERT(0); |
849 | __xfs_inode_clear_reclaim(pag, ip); | ||
871 | write_unlock(&pag->pag_ici_lock); | 850 | write_unlock(&pag->pag_ici_lock); |
872 | 851 | ||
873 | /* | 852 | /* |
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index 23f14e595c1..f90dadd5a96 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c | |||
@@ -5533,12 +5533,24 @@ xfs_getbmap( | |||
5533 | map[i].br_startblock)) | 5533 | map[i].br_startblock)) |
5534 | goto out_free_map; | 5534 | goto out_free_map; |
5535 | 5535 | ||
5536 | nexleft--; | ||
5537 | bmv->bmv_offset = | 5536 | bmv->bmv_offset = |
5538 | out[cur_ext].bmv_offset + | 5537 | out[cur_ext].bmv_offset + |
5539 | out[cur_ext].bmv_length; | 5538 | out[cur_ext].bmv_length; |
5540 | bmv->bmv_length = | 5539 | bmv->bmv_length = |
5541 | max_t(__int64_t, 0, bmvend - bmv->bmv_offset); | 5540 | max_t(__int64_t, 0, bmvend - bmv->bmv_offset); |
5541 | |||
5542 | /* | ||
5543 | * In case we don't want to return the hole, | ||
5544 | * don't increase cur_ext so that we can reuse | ||
5545 | * it in the next loop. | ||
5546 | */ | ||
5547 | if ((iflags & BMV_IF_NO_HOLES) && | ||
5548 | map[i].br_startblock == HOLESTARTBLOCK) { | ||
5549 | memset(&out[cur_ext], 0, sizeof(out[cur_ext])); | ||
5550 | continue; | ||
5551 | } | ||
5552 | |||
5553 | nexleft--; | ||
5542 | bmv->bmv_entries++; | 5554 | bmv->bmv_entries++; |
5543 | cur_ext++; | 5555 | cur_ext++; |
5544 | } | 5556 | } |
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h index 7cf7220e7d5..87c2e9d0228 100644 --- a/fs/xfs/xfs_fs.h +++ b/fs/xfs/xfs_fs.h | |||
@@ -114,8 +114,10 @@ struct getbmapx { | |||
114 | #define BMV_IF_NO_DMAPI_READ 0x2 /* Do not generate DMAPI read event */ | 114 | #define BMV_IF_NO_DMAPI_READ 0x2 /* Do not generate DMAPI read event */ |
115 | #define BMV_IF_PREALLOC 0x4 /* rtn status BMV_OF_PREALLOC if req */ | 115 | #define BMV_IF_PREALLOC 0x4 /* rtn status BMV_OF_PREALLOC if req */ |
116 | #define BMV_IF_DELALLOC 0x8 /* rtn status BMV_OF_DELALLOC if req */ | 116 | #define BMV_IF_DELALLOC 0x8 /* rtn status BMV_OF_DELALLOC if req */ |
117 | #define BMV_IF_NO_HOLES 0x10 /* Do not return holes */ | ||
117 | #define BMV_IF_VALID \ | 118 | #define BMV_IF_VALID \ |
118 | (BMV_IF_ATTRFORK|BMV_IF_NO_DMAPI_READ|BMV_IF_PREALLOC|BMV_IF_DELALLOC) | 119 | (BMV_IF_ATTRFORK|BMV_IF_NO_DMAPI_READ|BMV_IF_PREALLOC| \ |
120 | BMV_IF_DELALLOC|BMV_IF_NO_HOLES) | ||
119 | 121 | ||
120 | /* bmv_oflags values - returned for each non-header segment */ | 122 | /* bmv_oflags values - returned for each non-header segment */ |
121 | #define BMV_OF_PREALLOC 0x1 /* segment = unwritten pre-allocation */ | 123 | #define BMV_OF_PREALLOC 0x1 /* segment = unwritten pre-allocation */ |
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index dbca5f5c37b..43b1d569933 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c | |||
@@ -604,31 +604,36 @@ out: | |||
604 | return 0; | 604 | return 0; |
605 | } | 605 | } |
606 | 606 | ||
607 | /* | ||
608 | * Dump a transaction into the log that contains no real change. This is needed | ||
609 | * to be able to make the log dirty or stamp the current tail LSN into the log | ||
610 | * during the covering operation. | ||
611 | * | ||
612 | * We cannot use an inode here for this - that will push dirty state back up | ||
613 | * into the VFS and then periodic inode flushing will prevent log covering from | ||
614 | * making progress. Hence we log a field in the superblock instead. | ||
615 | */ | ||
607 | int | 616 | int |
608 | xfs_fs_log_dummy( | 617 | xfs_fs_log_dummy( |
609 | xfs_mount_t *mp) | 618 | xfs_mount_t *mp, |
619 | int flags) | ||
610 | { | 620 | { |
611 | xfs_trans_t *tp; | 621 | xfs_trans_t *tp; |
612 | xfs_inode_t *ip; | ||
613 | int error; | 622 | int error; |
614 | 623 | ||
615 | tp = _xfs_trans_alloc(mp, XFS_TRANS_DUMMY1, KM_SLEEP); | 624 | tp = _xfs_trans_alloc(mp, XFS_TRANS_DUMMY1, KM_SLEEP); |
616 | error = xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), 0, 0, 0); | 625 | error = xfs_trans_reserve(tp, 0, mp->m_sb.sb_sectsize + 128, 0, 0, |
626 | XFS_DEFAULT_LOG_COUNT); | ||
617 | if (error) { | 627 | if (error) { |
618 | xfs_trans_cancel(tp, 0); | 628 | xfs_trans_cancel(tp, 0); |
619 | return error; | 629 | return error; |
620 | } | 630 | } |
621 | 631 | ||
622 | ip = mp->m_rootip; | 632 | /* log the UUID because it is an unchanging field */ |
623 | xfs_ilock(ip, XFS_ILOCK_EXCL); | 633 | xfs_mod_sb(tp, XFS_SB_UUID); |
624 | 634 | if (flags & SYNC_WAIT) | |
625 | xfs_trans_ijoin(tp, ip); | 635 | xfs_trans_set_sync(tp); |
626 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | 636 | return xfs_trans_commit(tp, 0); |
627 | xfs_trans_set_sync(tp); | ||
628 | error = xfs_trans_commit(tp, 0); | ||
629 | |||
630 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
631 | return error; | ||
632 | } | 637 | } |
633 | 638 | ||
634 | int | 639 | int |
diff --git a/fs/xfs/xfs_fsops.h b/fs/xfs/xfs_fsops.h index 88435e0a77c..a786c5212c1 100644 --- a/fs/xfs/xfs_fsops.h +++ b/fs/xfs/xfs_fsops.h | |||
@@ -25,6 +25,6 @@ extern int xfs_fs_counts(xfs_mount_t *mp, xfs_fsop_counts_t *cnt); | |||
25 | extern int xfs_reserve_blocks(xfs_mount_t *mp, __uint64_t *inval, | 25 | extern int xfs_reserve_blocks(xfs_mount_t *mp, __uint64_t *inval, |
26 | xfs_fsop_resblks_t *outval); | 26 | xfs_fsop_resblks_t *outval); |
27 | extern int xfs_fs_goingdown(xfs_mount_t *mp, __uint32_t inflags); | 27 | extern int xfs_fs_goingdown(xfs_mount_t *mp, __uint32_t inflags); |
28 | extern int xfs_fs_log_dummy(xfs_mount_t *mp); | 28 | extern int xfs_fs_log_dummy(xfs_mount_t *mp, int flags); |
29 | 29 | ||
30 | #endif /* __XFS_FSOPS_H__ */ | 30 | #endif /* __XFS_FSOPS_H__ */ |
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c index abf80ae1e95..5371d2dc360 100644 --- a/fs/xfs/xfs_ialloc.c +++ b/fs/xfs/xfs_ialloc.c | |||
@@ -1213,7 +1213,6 @@ xfs_imap_lookup( | |||
1213 | struct xfs_inobt_rec_incore rec; | 1213 | struct xfs_inobt_rec_incore rec; |
1214 | struct xfs_btree_cur *cur; | 1214 | struct xfs_btree_cur *cur; |
1215 | struct xfs_buf *agbp; | 1215 | struct xfs_buf *agbp; |
1216 | xfs_agino_t startino; | ||
1217 | int error; | 1216 | int error; |
1218 | int i; | 1217 | int i; |
1219 | 1218 | ||
@@ -1227,13 +1226,13 @@ xfs_imap_lookup( | |||
1227 | } | 1226 | } |
1228 | 1227 | ||
1229 | /* | 1228 | /* |
1230 | * derive and lookup the exact inode record for the given agino. If the | 1229 | * Lookup the inode record for the given agino. If the record cannot be |
1231 | * record cannot be found, then it's an invalid inode number and we | 1230 | * found, then it's an invalid inode number and we should abort. Once |
1232 | * should abort. | 1231 | * we have a record, we need to ensure it contains the inode number |
1232 | * we are looking up. | ||
1233 | */ | 1233 | */ |
1234 | cur = xfs_inobt_init_cursor(mp, tp, agbp, agno); | 1234 | cur = xfs_inobt_init_cursor(mp, tp, agbp, agno); |
1235 | startino = agino & ~(XFS_IALLOC_INODES(mp) - 1); | 1235 | error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &i); |
1236 | error = xfs_inobt_lookup(cur, startino, XFS_LOOKUP_EQ, &i); | ||
1237 | if (!error) { | 1236 | if (!error) { |
1238 | if (i) | 1237 | if (i) |
1239 | error = xfs_inobt_get_rec(cur, &rec, &i); | 1238 | error = xfs_inobt_get_rec(cur, &rec, &i); |
@@ -1246,6 +1245,11 @@ xfs_imap_lookup( | |||
1246 | if (error) | 1245 | if (error) |
1247 | return error; | 1246 | return error; |
1248 | 1247 | ||
1248 | /* check that the returned record contains the required inode */ | ||
1249 | if (rec.ir_startino > agino || | ||
1250 | rec.ir_startino + XFS_IALLOC_INODES(mp) <= agino) | ||
1251 | return EINVAL; | ||
1252 | |||
1249 | /* for untrusted inodes check it is allocated first */ | 1253 | /* for untrusted inodes check it is allocated first */ |
1250 | if ((flags & XFS_IGET_UNTRUSTED) && | 1254 | if ((flags & XFS_IGET_UNTRUSTED) && |
1251 | (rec.ir_free & XFS_INOBT_MASK(agino - rec.ir_startino))) | 1255 | (rec.ir_free & XFS_INOBT_MASK(agino - rec.ir_startino))) |
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 68415cb4f23..34798f391c4 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -1914,6 +1914,11 @@ xfs_iunlink_remove( | |||
1914 | return 0; | 1914 | return 0; |
1915 | } | 1915 | } |
1916 | 1916 | ||
1917 | /* | ||
1918 | * A big issue when freeing the inode cluster is is that we _cannot_ skip any | ||
1919 | * inodes that are in memory - they all must be marked stale and attached to | ||
1920 | * the cluster buffer. | ||
1921 | */ | ||
1917 | STATIC void | 1922 | STATIC void |
1918 | xfs_ifree_cluster( | 1923 | xfs_ifree_cluster( |
1919 | xfs_inode_t *free_ip, | 1924 | xfs_inode_t *free_ip, |
@@ -1945,8 +1950,6 @@ xfs_ifree_cluster( | |||
1945 | } | 1950 | } |
1946 | 1951 | ||
1947 | for (j = 0; j < nbufs; j++, inum += ninodes) { | 1952 | for (j = 0; j < nbufs; j++, inum += ninodes) { |
1948 | int found = 0; | ||
1949 | |||
1950 | blkno = XFS_AGB_TO_DADDR(mp, XFS_INO_TO_AGNO(mp, inum), | 1953 | blkno = XFS_AGB_TO_DADDR(mp, XFS_INO_TO_AGNO(mp, inum), |
1951 | XFS_INO_TO_AGBNO(mp, inum)); | 1954 | XFS_INO_TO_AGBNO(mp, inum)); |
1952 | 1955 | ||
@@ -1965,7 +1968,9 @@ xfs_ifree_cluster( | |||
1965 | /* | 1968 | /* |
1966 | * Walk the inodes already attached to the buffer and mark them | 1969 | * Walk the inodes already attached to the buffer and mark them |
1967 | * stale. These will all have the flush locks held, so an | 1970 | * stale. These will all have the flush locks held, so an |
1968 | * in-memory inode walk can't lock them. | 1971 | * in-memory inode walk can't lock them. By marking them all |
1972 | * stale first, we will not attempt to lock them in the loop | ||
1973 | * below as the XFS_ISTALE flag will be set. | ||
1969 | */ | 1974 | */ |
1970 | lip = XFS_BUF_FSPRIVATE(bp, xfs_log_item_t *); | 1975 | lip = XFS_BUF_FSPRIVATE(bp, xfs_log_item_t *); |
1971 | while (lip) { | 1976 | while (lip) { |
@@ -1977,11 +1982,11 @@ xfs_ifree_cluster( | |||
1977 | &iip->ili_flush_lsn, | 1982 | &iip->ili_flush_lsn, |
1978 | &iip->ili_item.li_lsn); | 1983 | &iip->ili_item.li_lsn); |
1979 | xfs_iflags_set(iip->ili_inode, XFS_ISTALE); | 1984 | xfs_iflags_set(iip->ili_inode, XFS_ISTALE); |
1980 | found++; | ||
1981 | } | 1985 | } |
1982 | lip = lip->li_bio_list; | 1986 | lip = lip->li_bio_list; |
1983 | } | 1987 | } |
1984 | 1988 | ||
1989 | |||
1985 | /* | 1990 | /* |
1986 | * For each inode in memory attempt to add it to the inode | 1991 | * For each inode in memory attempt to add it to the inode |
1987 | * buffer and set it up for being staled on buffer IO | 1992 | * buffer and set it up for being staled on buffer IO |
@@ -1993,6 +1998,7 @@ xfs_ifree_cluster( | |||
1993 | * even trying to lock them. | 1998 | * even trying to lock them. |
1994 | */ | 1999 | */ |
1995 | for (i = 0; i < ninodes; i++) { | 2000 | for (i = 0; i < ninodes; i++) { |
2001 | retry: | ||
1996 | read_lock(&pag->pag_ici_lock); | 2002 | read_lock(&pag->pag_ici_lock); |
1997 | ip = radix_tree_lookup(&pag->pag_ici_root, | 2003 | ip = radix_tree_lookup(&pag->pag_ici_root, |
1998 | XFS_INO_TO_AGINO(mp, (inum + i))); | 2004 | XFS_INO_TO_AGINO(mp, (inum + i))); |
@@ -2003,38 +2009,36 @@ xfs_ifree_cluster( | |||
2003 | continue; | 2009 | continue; |
2004 | } | 2010 | } |
2005 | 2011 | ||
2006 | /* don't try to lock/unlock the current inode */ | 2012 | /* |
2013 | * Don't try to lock/unlock the current inode, but we | ||
2014 | * _cannot_ skip the other inodes that we did not find | ||
2015 | * in the list attached to the buffer and are not | ||
2016 | * already marked stale. If we can't lock it, back off | ||
2017 | * and retry. | ||
2018 | */ | ||
2007 | if (ip != free_ip && | 2019 | if (ip != free_ip && |
2008 | !xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) { | 2020 | !xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) { |
2009 | read_unlock(&pag->pag_ici_lock); | 2021 | read_unlock(&pag->pag_ici_lock); |
2010 | continue; | 2022 | delay(1); |
2023 | goto retry; | ||
2011 | } | 2024 | } |
2012 | read_unlock(&pag->pag_ici_lock); | 2025 | read_unlock(&pag->pag_ici_lock); |
2013 | 2026 | ||
2014 | if (!xfs_iflock_nowait(ip)) { | 2027 | xfs_iflock(ip); |
2015 | if (ip != free_ip) | ||
2016 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
2017 | continue; | ||
2018 | } | ||
2019 | |||
2020 | xfs_iflags_set(ip, XFS_ISTALE); | 2028 | xfs_iflags_set(ip, XFS_ISTALE); |
2021 | if (xfs_inode_clean(ip)) { | ||
2022 | ASSERT(ip != free_ip); | ||
2023 | xfs_ifunlock(ip); | ||
2024 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
2025 | continue; | ||
2026 | } | ||
2027 | 2029 | ||
2030 | /* | ||
2031 | * we don't need to attach clean inodes or those only | ||
2032 | * with unlogged changes (which we throw away, anyway). | ||
2033 | */ | ||
2028 | iip = ip->i_itemp; | 2034 | iip = ip->i_itemp; |
2029 | if (!iip) { | 2035 | if (!iip || xfs_inode_clean(ip)) { |
2030 | /* inode with unlogged changes only */ | ||
2031 | ASSERT(ip != free_ip); | 2036 | ASSERT(ip != free_ip); |
2032 | ip->i_update_core = 0; | 2037 | ip->i_update_core = 0; |
2033 | xfs_ifunlock(ip); | 2038 | xfs_ifunlock(ip); |
2034 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 2039 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
2035 | continue; | 2040 | continue; |
2036 | } | 2041 | } |
2037 | found++; | ||
2038 | 2042 | ||
2039 | iip->ili_last_fields = iip->ili_format.ilf_fields; | 2043 | iip->ili_last_fields = iip->ili_format.ilf_fields; |
2040 | iip->ili_format.ilf_fields = 0; | 2044 | iip->ili_format.ilf_fields = 0; |
@@ -2049,8 +2053,7 @@ xfs_ifree_cluster( | |||
2049 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 2053 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
2050 | } | 2054 | } |
2051 | 2055 | ||
2052 | if (found) | 2056 | xfs_trans_stale_inode_buf(tp, bp); |
2053 | xfs_trans_stale_inode_buf(tp, bp); | ||
2054 | xfs_trans_binval(tp, bp); | 2057 | xfs_trans_binval(tp, bp); |
2055 | } | 2058 | } |
2056 | 2059 | ||
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 430a8fc02c1..ba8e36e0b4e 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
@@ -3002,7 +3002,8 @@ _xfs_log_force( | |||
3002 | 3002 | ||
3003 | XFS_STATS_INC(xs_log_force); | 3003 | XFS_STATS_INC(xs_log_force); |
3004 | 3004 | ||
3005 | xlog_cil_push(log, 1); | 3005 | if (log->l_cilp) |
3006 | xlog_cil_force(log); | ||
3006 | 3007 | ||
3007 | spin_lock(&log->l_icloglock); | 3008 | spin_lock(&log->l_icloglock); |
3008 | 3009 | ||
@@ -3154,7 +3155,7 @@ _xfs_log_force_lsn( | |||
3154 | XFS_STATS_INC(xs_log_force); | 3155 | XFS_STATS_INC(xs_log_force); |
3155 | 3156 | ||
3156 | if (log->l_cilp) { | 3157 | if (log->l_cilp) { |
3157 | lsn = xlog_cil_push_lsn(log, lsn); | 3158 | lsn = xlog_cil_force_lsn(log, lsn); |
3158 | if (lsn == NULLCOMMITLSN) | 3159 | if (lsn == NULLCOMMITLSN) |
3159 | return 0; | 3160 | return 0; |
3160 | } | 3161 | } |
@@ -3711,7 +3712,7 @@ xfs_log_force_umount( | |||
3711 | * call below. | 3712 | * call below. |
3712 | */ | 3713 | */ |
3713 | if (!logerror && (mp->m_flags & XFS_MOUNT_DELAYLOG)) | 3714 | if (!logerror && (mp->m_flags & XFS_MOUNT_DELAYLOG)) |
3714 | xlog_cil_push(log, 1); | 3715 | xlog_cil_force(log); |
3715 | 3716 | ||
3716 | /* | 3717 | /* |
3717 | * We must hold both the GRANT lock and the LOG lock, | 3718 | * We must hold both the GRANT lock and the LOG lock, |
diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c index 31e4ea2d19a..7e206fc1fa3 100644 --- a/fs/xfs/xfs_log_cil.c +++ b/fs/xfs/xfs_log_cil.c | |||
@@ -68,6 +68,7 @@ xlog_cil_init( | |||
68 | ctx->sequence = 1; | 68 | ctx->sequence = 1; |
69 | ctx->cil = cil; | 69 | ctx->cil = cil; |
70 | cil->xc_ctx = ctx; | 70 | cil->xc_ctx = ctx; |
71 | cil->xc_current_sequence = ctx->sequence; | ||
71 | 72 | ||
72 | cil->xc_log = log; | 73 | cil->xc_log = log; |
73 | log->l_cilp = cil; | 74 | log->l_cilp = cil; |
@@ -269,15 +270,10 @@ xlog_cil_insert( | |||
269 | static void | 270 | static void |
270 | xlog_cil_format_items( | 271 | xlog_cil_format_items( |
271 | struct log *log, | 272 | struct log *log, |
272 | struct xfs_log_vec *log_vector, | 273 | struct xfs_log_vec *log_vector) |
273 | struct xlog_ticket *ticket, | ||
274 | xfs_lsn_t *start_lsn) | ||
275 | { | 274 | { |
276 | struct xfs_log_vec *lv; | 275 | struct xfs_log_vec *lv; |
277 | 276 | ||
278 | if (start_lsn) | ||
279 | *start_lsn = log->l_cilp->xc_ctx->sequence; | ||
280 | |||
281 | ASSERT(log_vector); | 277 | ASSERT(log_vector); |
282 | for (lv = log_vector; lv; lv = lv->lv_next) { | 278 | for (lv = log_vector; lv; lv = lv->lv_next) { |
283 | void *ptr; | 279 | void *ptr; |
@@ -301,9 +297,24 @@ xlog_cil_format_items( | |||
301 | ptr += vec->i_len; | 297 | ptr += vec->i_len; |
302 | } | 298 | } |
303 | ASSERT(ptr == lv->lv_buf + lv->lv_buf_len); | 299 | ASSERT(ptr == lv->lv_buf + lv->lv_buf_len); |
300 | } | ||
301 | } | ||
304 | 302 | ||
303 | static void | ||
304 | xlog_cil_insert_items( | ||
305 | struct log *log, | ||
306 | struct xfs_log_vec *log_vector, | ||
307 | struct xlog_ticket *ticket, | ||
308 | xfs_lsn_t *start_lsn) | ||
309 | { | ||
310 | struct xfs_log_vec *lv; | ||
311 | |||
312 | if (start_lsn) | ||
313 | *start_lsn = log->l_cilp->xc_ctx->sequence; | ||
314 | |||
315 | ASSERT(log_vector); | ||
316 | for (lv = log_vector; lv; lv = lv->lv_next) | ||
305 | xlog_cil_insert(log, ticket, lv->lv_item, lv); | 317 | xlog_cil_insert(log, ticket, lv->lv_item, lv); |
306 | } | ||
307 | } | 318 | } |
308 | 319 | ||
309 | static void | 320 | static void |
@@ -321,80 +332,6 @@ xlog_cil_free_logvec( | |||
321 | } | 332 | } |
322 | 333 | ||
323 | /* | 334 | /* |
324 | * Commit a transaction with the given vector to the Committed Item List. | ||
325 | * | ||
326 | * To do this, we need to format the item, pin it in memory if required and | ||
327 | * account for the space used by the transaction. Once we have done that we | ||
328 | * need to release the unused reservation for the transaction, attach the | ||
329 | * transaction to the checkpoint context so we carry the busy extents through | ||
330 | * to checkpoint completion, and then unlock all the items in the transaction. | ||
331 | * | ||
332 | * For more specific information about the order of operations in | ||
333 | * xfs_log_commit_cil() please refer to the comments in | ||
334 | * xfs_trans_commit_iclog(). | ||
335 | * | ||
336 | * Called with the context lock already held in read mode to lock out | ||
337 | * background commit, returns without it held once background commits are | ||
338 | * allowed again. | ||
339 | */ | ||
340 | int | ||
341 | xfs_log_commit_cil( | ||
342 | struct xfs_mount *mp, | ||
343 | struct xfs_trans *tp, | ||
344 | struct xfs_log_vec *log_vector, | ||
345 | xfs_lsn_t *commit_lsn, | ||
346 | int flags) | ||
347 | { | ||
348 | struct log *log = mp->m_log; | ||
349 | int log_flags = 0; | ||
350 | int push = 0; | ||
351 | |||
352 | if (flags & XFS_TRANS_RELEASE_LOG_RES) | ||
353 | log_flags = XFS_LOG_REL_PERM_RESERV; | ||
354 | |||
355 | if (XLOG_FORCED_SHUTDOWN(log)) { | ||
356 | xlog_cil_free_logvec(log_vector); | ||
357 | return XFS_ERROR(EIO); | ||
358 | } | ||
359 | |||
360 | /* lock out background commit */ | ||
361 | down_read(&log->l_cilp->xc_ctx_lock); | ||
362 | xlog_cil_format_items(log, log_vector, tp->t_ticket, commit_lsn); | ||
363 | |||
364 | /* check we didn't blow the reservation */ | ||
365 | if (tp->t_ticket->t_curr_res < 0) | ||
366 | xlog_print_tic_res(log->l_mp, tp->t_ticket); | ||
367 | |||
368 | /* attach the transaction to the CIL if it has any busy extents */ | ||
369 | if (!list_empty(&tp->t_busy)) { | ||
370 | spin_lock(&log->l_cilp->xc_cil_lock); | ||
371 | list_splice_init(&tp->t_busy, | ||
372 | &log->l_cilp->xc_ctx->busy_extents); | ||
373 | spin_unlock(&log->l_cilp->xc_cil_lock); | ||
374 | } | ||
375 | |||
376 | tp->t_commit_lsn = *commit_lsn; | ||
377 | xfs_log_done(mp, tp->t_ticket, NULL, log_flags); | ||
378 | xfs_trans_unreserve_and_mod_sb(tp); | ||
379 | |||
380 | /* check for background commit before unlock */ | ||
381 | if (log->l_cilp->xc_ctx->space_used > XLOG_CIL_SPACE_LIMIT(log)) | ||
382 | push = 1; | ||
383 | up_read(&log->l_cilp->xc_ctx_lock); | ||
384 | |||
385 | /* | ||
386 | * We need to push CIL every so often so we don't cache more than we | ||
387 | * can fit in the log. The limit really is that a checkpoint can't be | ||
388 | * more than half the log (the current checkpoint is not allowed to | ||
389 | * overwrite the previous checkpoint), but commit latency and memory | ||
390 | * usage limit this to a smaller size in most cases. | ||
391 | */ | ||
392 | if (push) | ||
393 | xlog_cil_push(log, 0); | ||
394 | return 0; | ||
395 | } | ||
396 | |||
397 | /* | ||
398 | * Mark all items committed and clear busy extents. We free the log vector | 335 | * Mark all items committed and clear busy extents. We free the log vector |
399 | * chains in a separate pass so that we unpin the log items as quickly as | 336 | * chains in a separate pass so that we unpin the log items as quickly as |
400 | * possible. | 337 | * possible. |
@@ -427,13 +364,23 @@ xlog_cil_committed( | |||
427 | } | 364 | } |
428 | 365 | ||
429 | /* | 366 | /* |
430 | * Push the Committed Item List to the log. If the push_now flag is not set, | 367 | * Push the Committed Item List to the log. If @push_seq flag is zero, then it |
431 | * then it is a background flush and so we can chose to ignore it. | 368 | * is a background flush and so we can chose to ignore it. Otherwise, if the |
369 | * current sequence is the same as @push_seq we need to do a flush. If | ||
370 | * @push_seq is less than the current sequence, then it has already been | ||
371 | * flushed and we don't need to do anything - the caller will wait for it to | ||
372 | * complete if necessary. | ||
373 | * | ||
374 | * @push_seq is a value rather than a flag because that allows us to do an | ||
375 | * unlocked check of the sequence number for a match. Hence we can allows log | ||
376 | * forces to run racily and not issue pushes for the same sequence twice. If we | ||
377 | * get a race between multiple pushes for the same sequence they will block on | ||
378 | * the first one and then abort, hence avoiding needless pushes. | ||
432 | */ | 379 | */ |
433 | int | 380 | STATIC int |
434 | xlog_cil_push( | 381 | xlog_cil_push( |
435 | struct log *log, | 382 | struct log *log, |
436 | int push_now) | 383 | xfs_lsn_t push_seq) |
437 | { | 384 | { |
438 | struct xfs_cil *cil = log->l_cilp; | 385 | struct xfs_cil *cil = log->l_cilp; |
439 | struct xfs_log_vec *lv; | 386 | struct xfs_log_vec *lv; |
@@ -453,12 +400,20 @@ xlog_cil_push( | |||
453 | if (!cil) | 400 | if (!cil) |
454 | return 0; | 401 | return 0; |
455 | 402 | ||
403 | ASSERT(!push_seq || push_seq <= cil->xc_ctx->sequence); | ||
404 | |||
456 | new_ctx = kmem_zalloc(sizeof(*new_ctx), KM_SLEEP|KM_NOFS); | 405 | new_ctx = kmem_zalloc(sizeof(*new_ctx), KM_SLEEP|KM_NOFS); |
457 | new_ctx->ticket = xlog_cil_ticket_alloc(log); | 406 | new_ctx->ticket = xlog_cil_ticket_alloc(log); |
458 | 407 | ||
459 | /* lock out transaction commit, but don't block on background push */ | 408 | /* |
409 | * Lock out transaction commit, but don't block for background pushes | ||
410 | * unless we are well over the CIL space limit. See the definition of | ||
411 | * XLOG_CIL_HARD_SPACE_LIMIT() for the full explanation of the logic | ||
412 | * used here. | ||
413 | */ | ||
460 | if (!down_write_trylock(&cil->xc_ctx_lock)) { | 414 | if (!down_write_trylock(&cil->xc_ctx_lock)) { |
461 | if (!push_now) | 415 | if (!push_seq && |
416 | cil->xc_ctx->space_used < XLOG_CIL_HARD_SPACE_LIMIT(log)) | ||
462 | goto out_free_ticket; | 417 | goto out_free_ticket; |
463 | down_write(&cil->xc_ctx_lock); | 418 | down_write(&cil->xc_ctx_lock); |
464 | } | 419 | } |
@@ -469,7 +424,11 @@ xlog_cil_push( | |||
469 | goto out_skip; | 424 | goto out_skip; |
470 | 425 | ||
471 | /* check for spurious background flush */ | 426 | /* check for spurious background flush */ |
472 | if (!push_now && cil->xc_ctx->space_used < XLOG_CIL_SPACE_LIMIT(log)) | 427 | if (!push_seq && cil->xc_ctx->space_used < XLOG_CIL_SPACE_LIMIT(log)) |
428 | goto out_skip; | ||
429 | |||
430 | /* check for a previously pushed seqeunce */ | ||
431 | if (push_seq && push_seq < cil->xc_ctx->sequence) | ||
473 | goto out_skip; | 432 | goto out_skip; |
474 | 433 | ||
475 | /* | 434 | /* |
@@ -515,6 +474,13 @@ xlog_cil_push( | |||
515 | cil->xc_ctx = new_ctx; | 474 | cil->xc_ctx = new_ctx; |
516 | 475 | ||
517 | /* | 476 | /* |
477 | * mirror the new sequence into the cil structure so that we can do | ||
478 | * unlocked checks against the current sequence in log forces without | ||
479 | * risking deferencing a freed context pointer. | ||
480 | */ | ||
481 | cil->xc_current_sequence = new_ctx->sequence; | ||
482 | |||
483 | /* | ||
518 | * The switch is now done, so we can drop the context lock and move out | 484 | * The switch is now done, so we can drop the context lock and move out |
519 | * of a shared context. We can't just go straight to the commit record, | 485 | * of a shared context. We can't just go straight to the commit record, |
520 | * though - we need to synchronise with previous and future commits so | 486 | * though - we need to synchronise with previous and future commits so |
@@ -626,6 +592,102 @@ out_abort: | |||
626 | } | 592 | } |
627 | 593 | ||
628 | /* | 594 | /* |
595 | * Commit a transaction with the given vector to the Committed Item List. | ||
596 | * | ||
597 | * To do this, we need to format the item, pin it in memory if required and | ||
598 | * account for the space used by the transaction. Once we have done that we | ||
599 | * need to release the unused reservation for the transaction, attach the | ||
600 | * transaction to the checkpoint context so we carry the busy extents through | ||
601 | * to checkpoint completion, and then unlock all the items in the transaction. | ||
602 | * | ||
603 | * For more specific information about the order of operations in | ||
604 | * xfs_log_commit_cil() please refer to the comments in | ||
605 | * xfs_trans_commit_iclog(). | ||
606 | * | ||
607 | * Called with the context lock already held in read mode to lock out | ||
608 | * background commit, returns without it held once background commits are | ||
609 | * allowed again. | ||
610 | */ | ||
611 | int | ||
612 | xfs_log_commit_cil( | ||
613 | struct xfs_mount *mp, | ||
614 | struct xfs_trans *tp, | ||
615 | struct xfs_log_vec *log_vector, | ||
616 | xfs_lsn_t *commit_lsn, | ||
617 | int flags) | ||
618 | { | ||
619 | struct log *log = mp->m_log; | ||
620 | int log_flags = 0; | ||
621 | int push = 0; | ||
622 | |||
623 | if (flags & XFS_TRANS_RELEASE_LOG_RES) | ||
624 | log_flags = XFS_LOG_REL_PERM_RESERV; | ||
625 | |||
626 | if (XLOG_FORCED_SHUTDOWN(log)) { | ||
627 | xlog_cil_free_logvec(log_vector); | ||
628 | return XFS_ERROR(EIO); | ||
629 | } | ||
630 | |||
631 | /* | ||
632 | * do all the hard work of formatting items (including memory | ||
633 | * allocation) outside the CIL context lock. This prevents stalling CIL | ||
634 | * pushes when we are low on memory and a transaction commit spends a | ||
635 | * lot of time in memory reclaim. | ||
636 | */ | ||
637 | xlog_cil_format_items(log, log_vector); | ||
638 | |||
639 | /* lock out background commit */ | ||
640 | down_read(&log->l_cilp->xc_ctx_lock); | ||
641 | xlog_cil_insert_items(log, log_vector, tp->t_ticket, commit_lsn); | ||
642 | |||
643 | /* check we didn't blow the reservation */ | ||
644 | if (tp->t_ticket->t_curr_res < 0) | ||
645 | xlog_print_tic_res(log->l_mp, tp->t_ticket); | ||
646 | |||
647 | /* attach the transaction to the CIL if it has any busy extents */ | ||
648 | if (!list_empty(&tp->t_busy)) { | ||
649 | spin_lock(&log->l_cilp->xc_cil_lock); | ||
650 | list_splice_init(&tp->t_busy, | ||
651 | &log->l_cilp->xc_ctx->busy_extents); | ||
652 | spin_unlock(&log->l_cilp->xc_cil_lock); | ||
653 | } | ||
654 | |||
655 | tp->t_commit_lsn = *commit_lsn; | ||
656 | xfs_log_done(mp, tp->t_ticket, NULL, log_flags); | ||
657 | xfs_trans_unreserve_and_mod_sb(tp); | ||
658 | |||
659 | /* | ||
660 | * Once all the items of the transaction have been copied to the CIL, | ||
661 | * the items can be unlocked and freed. | ||
662 | * | ||
663 | * This needs to be done before we drop the CIL context lock because we | ||
664 | * have to update state in the log items and unlock them before they go | ||
665 | * to disk. If we don't, then the CIL checkpoint can race with us and | ||
666 | * we can run checkpoint completion before we've updated and unlocked | ||
667 | * the log items. This affects (at least) processing of stale buffers, | ||
668 | * inodes and EFIs. | ||
669 | */ | ||
670 | xfs_trans_free_items(tp, *commit_lsn, 0); | ||
671 | |||
672 | /* check for background commit before unlock */ | ||
673 | if (log->l_cilp->xc_ctx->space_used > XLOG_CIL_SPACE_LIMIT(log)) | ||
674 | push = 1; | ||
675 | |||
676 | up_read(&log->l_cilp->xc_ctx_lock); | ||
677 | |||
678 | /* | ||
679 | * We need to push CIL every so often so we don't cache more than we | ||
680 | * can fit in the log. The limit really is that a checkpoint can't be | ||
681 | * more than half the log (the current checkpoint is not allowed to | ||
682 | * overwrite the previous checkpoint), but commit latency and memory | ||
683 | * usage limit this to a smaller size in most cases. | ||
684 | */ | ||
685 | if (push) | ||
686 | xlog_cil_push(log, 0); | ||
687 | return 0; | ||
688 | } | ||
689 | |||
690 | /* | ||
629 | * Conditionally push the CIL based on the sequence passed in. | 691 | * Conditionally push the CIL based on the sequence passed in. |
630 | * | 692 | * |
631 | * We only need to push if we haven't already pushed the sequence | 693 | * We only need to push if we haven't already pushed the sequence |
@@ -639,39 +701,34 @@ out_abort: | |||
639 | * commit lsn is there. It'll be empty, so this is broken for now. | 701 | * commit lsn is there. It'll be empty, so this is broken for now. |
640 | */ | 702 | */ |
641 | xfs_lsn_t | 703 | xfs_lsn_t |
642 | xlog_cil_push_lsn( | 704 | xlog_cil_force_lsn( |
643 | struct log *log, | 705 | struct log *log, |
644 | xfs_lsn_t push_seq) | 706 | xfs_lsn_t sequence) |
645 | { | 707 | { |
646 | struct xfs_cil *cil = log->l_cilp; | 708 | struct xfs_cil *cil = log->l_cilp; |
647 | struct xfs_cil_ctx *ctx; | 709 | struct xfs_cil_ctx *ctx; |
648 | xfs_lsn_t commit_lsn = NULLCOMMITLSN; | 710 | xfs_lsn_t commit_lsn = NULLCOMMITLSN; |
649 | 711 | ||
650 | restart: | 712 | ASSERT(sequence <= cil->xc_current_sequence); |
651 | down_write(&cil->xc_ctx_lock); | 713 | |
652 | ASSERT(push_seq <= cil->xc_ctx->sequence); | 714 | /* |
653 | 715 | * check to see if we need to force out the current context. | |
654 | /* check to see if we need to force out the current context */ | 716 | * xlog_cil_push() handles racing pushes for the same sequence, |
655 | if (push_seq == cil->xc_ctx->sequence) { | 717 | * so no need to deal with it here. |
656 | up_write(&cil->xc_ctx_lock); | 718 | */ |
657 | xlog_cil_push(log, 1); | 719 | if (sequence == cil->xc_current_sequence) |
658 | goto restart; | 720 | xlog_cil_push(log, sequence); |
659 | } | ||
660 | 721 | ||
661 | /* | 722 | /* |
662 | * See if we can find a previous sequence still committing. | 723 | * See if we can find a previous sequence still committing. |
663 | * We can drop the flush lock as soon as we have the cil lock | ||
664 | * because we are now only comparing contexts protected by | ||
665 | * the cil lock. | ||
666 | * | ||
667 | * We need to wait for all previous sequence commits to complete | 724 | * We need to wait for all previous sequence commits to complete |
668 | * before allowing the force of push_seq to go ahead. Hence block | 725 | * before allowing the force of push_seq to go ahead. Hence block |
669 | * on commits for those as well. | 726 | * on commits for those as well. |
670 | */ | 727 | */ |
728 | restart: | ||
671 | spin_lock(&cil->xc_cil_lock); | 729 | spin_lock(&cil->xc_cil_lock); |
672 | up_write(&cil->xc_ctx_lock); | ||
673 | list_for_each_entry(ctx, &cil->xc_committing, committing) { | 730 | list_for_each_entry(ctx, &cil->xc_committing, committing) { |
674 | if (ctx->sequence > push_seq) | 731 | if (ctx->sequence > sequence) |
675 | continue; | 732 | continue; |
676 | if (!ctx->commit_lsn) { | 733 | if (!ctx->commit_lsn) { |
677 | /* | 734 | /* |
@@ -681,7 +738,7 @@ restart: | |||
681 | sv_wait(&cil->xc_commit_wait, 0, &cil->xc_cil_lock, 0); | 738 | sv_wait(&cil->xc_commit_wait, 0, &cil->xc_cil_lock, 0); |
682 | goto restart; | 739 | goto restart; |
683 | } | 740 | } |
684 | if (ctx->sequence != push_seq) | 741 | if (ctx->sequence != sequence) |
685 | continue; | 742 | continue; |
686 | /* found it! */ | 743 | /* found it! */ |
687 | commit_lsn = ctx->commit_lsn; | 744 | commit_lsn = ctx->commit_lsn; |
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index 8c072618965..edcdfe01617 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h | |||
@@ -422,16 +422,17 @@ struct xfs_cil { | |||
422 | struct rw_semaphore xc_ctx_lock; | 422 | struct rw_semaphore xc_ctx_lock; |
423 | struct list_head xc_committing; | 423 | struct list_head xc_committing; |
424 | sv_t xc_commit_wait; | 424 | sv_t xc_commit_wait; |
425 | xfs_lsn_t xc_current_sequence; | ||
425 | }; | 426 | }; |
426 | 427 | ||
427 | /* | 428 | /* |
428 | * The amount of log space we should the CIL to aggregate is difficult to size. | 429 | * The amount of log space we allow the CIL to aggregate is difficult to size. |
429 | * Whatever we chose we have to make we can get a reservation for the log space | 430 | * Whatever we choose, we have to make sure we can get a reservation for the |
430 | * effectively, that it is large enough to capture sufficient relogging to | 431 | * log space effectively, that it is large enough to capture sufficient |
431 | * reduce log buffer IO significantly, but it is not too large for the log or | 432 | * relogging to reduce log buffer IO significantly, but it is not too large for |
432 | * induces too much latency when writing out through the iclogs. We track both | 433 | * the log or induces too much latency when writing out through the iclogs. We |
433 | * space consumed and the number of vectors in the checkpoint context, so we | 434 | * track both space consumed and the number of vectors in the checkpoint |
434 | * need to decide which to use for limiting. | 435 | * context, so we need to decide which to use for limiting. |
435 | * | 436 | * |
436 | * Every log buffer we write out during a push needs a header reserved, which | 437 | * Every log buffer we write out during a push needs a header reserved, which |
437 | * is at least one sector and more for v2 logs. Hence we need a reservation of | 438 | * is at least one sector and more for v2 logs. Hence we need a reservation of |
@@ -458,16 +459,21 @@ struct xfs_cil { | |||
458 | * checkpoint transaction ticket is specific to the checkpoint context, rather | 459 | * checkpoint transaction ticket is specific to the checkpoint context, rather |
459 | * than the CIL itself. | 460 | * than the CIL itself. |
460 | * | 461 | * |
461 | * With dynamic reservations, we can basically make up arbitrary limits for the | 462 | * With dynamic reservations, we can effectively make up arbitrary limits for |
462 | * checkpoint size so long as they don't violate any other size rules. Hence | 463 | * the checkpoint size so long as they don't violate any other size rules. |
463 | * the initial maximum size for the checkpoint transaction will be set to a | 464 | * Recovery imposes a rule that no transaction exceed half the log, so we are |
464 | * quarter of the log or 8MB, which ever is smaller. 8MB is an arbitrary limit | 465 | * limited by that. Furthermore, the log transaction reservation subsystem |
465 | * right now based on the latency of writing out a large amount of data through | 466 | * tries to keep 25% of the log free, so we need to keep below that limit or we |
466 | * the circular iclog buffers. | 467 | * risk running out of free log space to start any new transactions. |
468 | * | ||
469 | * In order to keep background CIL push efficient, we will set a lower | ||
470 | * threshold at which background pushing is attempted without blocking current | ||
471 | * transaction commits. A separate, higher bound defines when CIL pushes are | ||
472 | * enforced to ensure we stay within our maximum checkpoint size bounds. | ||
473 | * threshold, yet give us plenty of space for aggregation on large logs. | ||
467 | */ | 474 | */ |
468 | 475 | #define XLOG_CIL_SPACE_LIMIT(log) (log->l_logsize >> 3) | |
469 | #define XLOG_CIL_SPACE_LIMIT(log) \ | 476 | #define XLOG_CIL_HARD_SPACE_LIMIT(log) (3 * (log->l_logsize >> 4)) |
470 | (min((log->l_logsize >> 2), (8 * 1024 * 1024))) | ||
471 | 477 | ||
472 | /* | 478 | /* |
473 | * The reservation head lsn is not made up of a cycle number and block number. | 479 | * The reservation head lsn is not made up of a cycle number and block number. |
@@ -562,8 +568,16 @@ int xlog_cil_init(struct log *log); | |||
562 | void xlog_cil_init_post_recovery(struct log *log); | 568 | void xlog_cil_init_post_recovery(struct log *log); |
563 | void xlog_cil_destroy(struct log *log); | 569 | void xlog_cil_destroy(struct log *log); |
564 | 570 | ||
565 | int xlog_cil_push(struct log *log, int push_now); | 571 | /* |
566 | xfs_lsn_t xlog_cil_push_lsn(struct log *log, xfs_lsn_t push_sequence); | 572 | * CIL force routines |
573 | */ | ||
574 | xfs_lsn_t xlog_cil_force_lsn(struct log *log, xfs_lsn_t sequence); | ||
575 | |||
576 | static inline void | ||
577 | xlog_cil_force(struct log *log) | ||
578 | { | ||
579 | xlog_cil_force_lsn(log, log->l_cilp->xc_current_sequence); | ||
580 | } | ||
567 | 581 | ||
568 | /* | 582 | /* |
569 | * Unmount record type is used as a pseudo transaction type for the ticket. | 583 | * Unmount record type is used as a pseudo transaction type for the ticket. |
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index fdca7416c75..1c47edaea0d 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c | |||
@@ -1167,7 +1167,7 @@ xfs_trans_del_item( | |||
1167 | * Unlock all of the items of a transaction and free all the descriptors | 1167 | * Unlock all of the items of a transaction and free all the descriptors |
1168 | * of that transaction. | 1168 | * of that transaction. |
1169 | */ | 1169 | */ |
1170 | STATIC void | 1170 | void |
1171 | xfs_trans_free_items( | 1171 | xfs_trans_free_items( |
1172 | struct xfs_trans *tp, | 1172 | struct xfs_trans *tp, |
1173 | xfs_lsn_t commit_lsn, | 1173 | xfs_lsn_t commit_lsn, |
@@ -1653,9 +1653,6 @@ xfs_trans_commit_cil( | |||
1653 | return error; | 1653 | return error; |
1654 | 1654 | ||
1655 | current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS); | 1655 | current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS); |
1656 | |||
1657 | /* xfs_trans_free_items() unlocks them first */ | ||
1658 | xfs_trans_free_items(tp, *commit_lsn, 0); | ||
1659 | xfs_trans_free(tp); | 1656 | xfs_trans_free(tp); |
1660 | return 0; | 1657 | return 0; |
1661 | } | 1658 | } |
diff --git a/fs/xfs/xfs_trans_priv.h b/fs/xfs/xfs_trans_priv.h index e2d93d8ead7..62da86c90de 100644 --- a/fs/xfs/xfs_trans_priv.h +++ b/fs/xfs/xfs_trans_priv.h | |||
@@ -25,7 +25,8 @@ struct xfs_trans; | |||
25 | 25 | ||
26 | void xfs_trans_add_item(struct xfs_trans *, struct xfs_log_item *); | 26 | void xfs_trans_add_item(struct xfs_trans *, struct xfs_log_item *); |
27 | void xfs_trans_del_item(struct xfs_log_item *); | 27 | void xfs_trans_del_item(struct xfs_log_item *); |
28 | 28 | void xfs_trans_free_items(struct xfs_trans *tp, xfs_lsn_t commit_lsn, | |
29 | int flags); | ||
29 | void xfs_trans_item_committed(struct xfs_log_item *lip, | 30 | void xfs_trans_item_committed(struct xfs_log_item *lip, |
30 | xfs_lsn_t commit_lsn, int aborted); | 31 | xfs_lsn_t commit_lsn, int aborted); |
31 | void xfs_trans_unreserve_and_mod_sb(struct xfs_trans *tp); | 32 | void xfs_trans_unreserve_and_mod_sb(struct xfs_trans *tp); |
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 66d585c6917..4c7c7bfb2b2 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
@@ -2299,15 +2299,22 @@ xfs_alloc_file_space( | |||
2299 | e = allocatesize_fsb; | 2299 | e = allocatesize_fsb; |
2300 | } | 2300 | } |
2301 | 2301 | ||
2302 | /* | ||
2303 | * The transaction reservation is limited to a 32-bit block | ||
2304 | * count, hence we need to limit the number of blocks we are | ||
2305 | * trying to reserve to avoid an overflow. We can't allocate | ||
2306 | * more than @nimaps extents, and an extent is limited on disk | ||
2307 | * to MAXEXTLEN (21 bits), so use that to enforce the limit. | ||
2308 | */ | ||
2309 | resblks = min_t(xfs_fileoff_t, (e - s), (MAXEXTLEN * nimaps)); | ||
2302 | if (unlikely(rt)) { | 2310 | if (unlikely(rt)) { |
2303 | resrtextents = qblocks = (uint)(e - s); | 2311 | resrtextents = qblocks = resblks; |
2304 | resrtextents /= mp->m_sb.sb_rextsize; | 2312 | resrtextents /= mp->m_sb.sb_rextsize; |
2305 | resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0); | 2313 | resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0); |
2306 | quota_flag = XFS_QMOPT_RES_RTBLKS; | 2314 | quota_flag = XFS_QMOPT_RES_RTBLKS; |
2307 | } else { | 2315 | } else { |
2308 | resrtextents = 0; | 2316 | resrtextents = 0; |
2309 | resblks = qblocks = \ | 2317 | resblks = qblocks = XFS_DIOSTRAT_SPACE_RES(mp, resblks); |
2310 | XFS_DIOSTRAT_SPACE_RES(mp, (uint)(e - s)); | ||
2311 | quota_flag = XFS_QMOPT_RES_REGBLKS; | 2318 | quota_flag = XFS_QMOPT_RES_REGBLKS; |
2312 | } | 2319 | } |
2313 | 2320 | ||
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index baacd98e7cc..4de84ce3a92 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h | |||
@@ -377,9 +377,6 @@ struct acpi_pci_root { | |||
377 | 377 | ||
378 | u32 osc_support_set; /* _OSC state of support bits */ | 378 | u32 osc_support_set; /* _OSC state of support bits */ |
379 | u32 osc_control_set; /* _OSC state of control bits */ | 379 | u32 osc_control_set; /* _OSC state of control bits */ |
380 | u32 osc_control_qry; /* the latest _OSC query result */ | ||
381 | |||
382 | u32 osc_queried:1; /* has _OSC control been queried? */ | ||
383 | }; | 380 | }; |
384 | 381 | ||
385 | /* helper */ | 382 | /* helper */ |
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index c0786d446a0..984cdc62e30 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h | |||
@@ -55,7 +55,7 @@ | |||
55 | extern u8 acpi_gbl_permanent_mmap; | 55 | extern u8 acpi_gbl_permanent_mmap; |
56 | 56 | ||
57 | /* | 57 | /* |
58 | * Globals that are publically available, allowing for | 58 | * Globals that are publicly available, allowing for |
59 | * run time configuration | 59 | * run time configuration |
60 | */ | 60 | */ |
61 | extern u32 acpi_dbg_level; | 61 | extern u32 acpi_dbg_level; |
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index c7376bf80b0..8ca18e26d7e 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h | |||
@@ -16,15 +16,27 @@ | |||
16 | * While the GPIO programming interface defines valid GPIO numbers | 16 | * While the GPIO programming interface defines valid GPIO numbers |
17 | * to be in the range 0..MAX_INT, this library restricts them to the | 17 | * to be in the range 0..MAX_INT, this library restricts them to the |
18 | * smaller range 0..ARCH_NR_GPIOS-1. | 18 | * smaller range 0..ARCH_NR_GPIOS-1. |
19 | * | ||
20 | * ARCH_NR_GPIOS is somewhat arbitrary; it usually reflects the sum of | ||
21 | * builtin/SoC GPIOs plus a number of GPIOs on expanders; the latter is | ||
22 | * actually an estimate of a board-specific value. | ||
19 | */ | 23 | */ |
20 | 24 | ||
21 | #ifndef ARCH_NR_GPIOS | 25 | #ifndef ARCH_NR_GPIOS |
22 | #define ARCH_NR_GPIOS 256 | 26 | #define ARCH_NR_GPIOS 256 |
23 | #endif | 27 | #endif |
24 | 28 | ||
29 | /* | ||
30 | * "valid" GPIO numbers are nonnegative and may be passed to | ||
31 | * setup routines like gpio_request(). only some valid numbers | ||
32 | * can successfully be requested and used. | ||
33 | * | ||
34 | * Invalid GPIO numbers are useful for indicating no-such-GPIO in | ||
35 | * platform data and other tables. | ||
36 | */ | ||
37 | |||
25 | static inline int gpio_is_valid(int number) | 38 | static inline int gpio_is_valid(int number) |
26 | { | 39 | { |
27 | /* only some non-negative numbers are valid */ | ||
28 | return ((unsigned)number) < ARCH_NR_GPIOS; | 40 | return ((unsigned)number) < ARCH_NR_GPIOS; |
29 | } | 41 | } |
30 | 42 | ||
diff --git a/include/asm-generic/percpu.h b/include/asm-generic/percpu.h index b5043a9890d..08923b68476 100644 --- a/include/asm-generic/percpu.h +++ b/include/asm-generic/percpu.h | |||
@@ -70,11 +70,16 @@ extern void setup_per_cpu_areas(void); | |||
70 | 70 | ||
71 | #else /* ! SMP */ | 71 | #else /* ! SMP */ |
72 | 72 | ||
73 | #define per_cpu(var, cpu) (*((void)(cpu), &(var))) | 73 | #define VERIFY_PERCPU_PTR(__p) ({ \ |
74 | #define __get_cpu_var(var) (var) | 74 | __verify_pcpu_ptr((__p)); \ |
75 | #define __raw_get_cpu_var(var) (var) | 75 | (typeof(*(__p)) __kernel __force *)(__p); \ |
76 | #define this_cpu_ptr(ptr) per_cpu_ptr(ptr, 0) | 76 | }) |
77 | #define __this_cpu_ptr(ptr) this_cpu_ptr(ptr) | 77 | |
78 | #define per_cpu(var, cpu) (*((void)(cpu), VERIFY_PERCPU_PTR(&(var)))) | ||
79 | #define __get_cpu_var(var) (*VERIFY_PERCPU_PTR(&(var))) | ||
80 | #define __raw_get_cpu_var(var) (*VERIFY_PERCPU_PTR(&(var))) | ||
81 | #define this_cpu_ptr(ptr) per_cpu_ptr(ptr, 0) | ||
82 | #define __this_cpu_ptr(ptr) this_cpu_ptr(ptr) | ||
78 | 83 | ||
79 | #endif /* SMP */ | 84 | #endif /* SMP */ |
80 | 85 | ||
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 2a512bc0d4a..4c9461a4f9e 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h | |||
@@ -305,14 +305,16 @@ struct drm_ioctl_desc { | |||
305 | unsigned int cmd; | 305 | unsigned int cmd; |
306 | int flags; | 306 | int flags; |
307 | drm_ioctl_t *func; | 307 | drm_ioctl_t *func; |
308 | unsigned int cmd_drv; | ||
308 | }; | 309 | }; |
309 | 310 | ||
310 | /** | 311 | /** |
311 | * Creates a driver or general drm_ioctl_desc array entry for the given | 312 | * Creates a driver or general drm_ioctl_desc array entry for the given |
312 | * ioctl, for use by drm_ioctl(). | 313 | * ioctl, for use by drm_ioctl(). |
313 | */ | 314 | */ |
314 | #define DRM_IOCTL_DEF(ioctl, _func, _flags) \ | 315 | |
315 | [DRM_IOCTL_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags} | 316 | #define DRM_IOCTL_DEF_DRV(ioctl, _func, _flags) \ |
317 | [DRM_IOCTL_NR(DRM_##ioctl)] = {.cmd = DRM_##ioctl, .func = _func, .flags = _flags, .cmd_drv = DRM_IOCTL_##ioctl} | ||
316 | 318 | ||
317 | struct drm_magic_entry { | 319 | struct drm_magic_entry { |
318 | struct list_head head; | 320 | struct list_head head; |
@@ -610,7 +612,7 @@ struct drm_gem_object { | |||
610 | struct kref refcount; | 612 | struct kref refcount; |
611 | 613 | ||
612 | /** Handle count of this object. Each handle also holds a reference */ | 614 | /** Handle count of this object. Each handle also holds a reference */ |
613 | struct kref handlecount; | 615 | atomic_t handle_count; /* number of handles on this object */ |
614 | 616 | ||
615 | /** Related drm device */ | 617 | /** Related drm device */ |
616 | struct drm_device *dev; | 618 | struct drm_device *dev; |
@@ -806,7 +808,6 @@ struct drm_driver { | |||
806 | */ | 808 | */ |
807 | int (*gem_init_object) (struct drm_gem_object *obj); | 809 | int (*gem_init_object) (struct drm_gem_object *obj); |
808 | void (*gem_free_object) (struct drm_gem_object *obj); | 810 | void (*gem_free_object) (struct drm_gem_object *obj); |
809 | void (*gem_free_object_unlocked) (struct drm_gem_object *obj); | ||
810 | 811 | ||
811 | /* vga arb irq handler */ | 812 | /* vga arb irq handler */ |
812 | void (*vgaarb_irq)(struct drm_device *dev, bool state); | 813 | void (*vgaarb_irq)(struct drm_device *dev, bool state); |
@@ -1173,6 +1174,7 @@ extern int drm_release(struct inode *inode, struct file *filp); | |||
1173 | extern int drm_mmap(struct file *filp, struct vm_area_struct *vma); | 1174 | extern int drm_mmap(struct file *filp, struct vm_area_struct *vma); |
1174 | extern int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma); | 1175 | extern int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma); |
1175 | extern void drm_vm_open_locked(struct vm_area_struct *vma); | 1176 | extern void drm_vm_open_locked(struct vm_area_struct *vma); |
1177 | extern void drm_vm_close_locked(struct vm_area_struct *vma); | ||
1176 | extern resource_size_t drm_core_get_map_ofs(struct drm_local_map * map); | 1178 | extern resource_size_t drm_core_get_map_ofs(struct drm_local_map * map); |
1177 | extern resource_size_t drm_core_get_reg_ofs(struct drm_device *dev); | 1179 | extern resource_size_t drm_core_get_reg_ofs(struct drm_device *dev); |
1178 | extern unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait); | 1180 | extern unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait); |
@@ -1453,12 +1455,11 @@ int drm_gem_init(struct drm_device *dev); | |||
1453 | void drm_gem_destroy(struct drm_device *dev); | 1455 | void drm_gem_destroy(struct drm_device *dev); |
1454 | void drm_gem_object_release(struct drm_gem_object *obj); | 1456 | void drm_gem_object_release(struct drm_gem_object *obj); |
1455 | void drm_gem_object_free(struct kref *kref); | 1457 | void drm_gem_object_free(struct kref *kref); |
1456 | void drm_gem_object_free_unlocked(struct kref *kref); | ||
1457 | struct drm_gem_object *drm_gem_object_alloc(struct drm_device *dev, | 1458 | struct drm_gem_object *drm_gem_object_alloc(struct drm_device *dev, |
1458 | size_t size); | 1459 | size_t size); |
1459 | int drm_gem_object_init(struct drm_device *dev, | 1460 | int drm_gem_object_init(struct drm_device *dev, |
1460 | struct drm_gem_object *obj, size_t size); | 1461 | struct drm_gem_object *obj, size_t size); |
1461 | void drm_gem_object_handle_free(struct kref *kref); | 1462 | void drm_gem_object_handle_free(struct drm_gem_object *obj); |
1462 | void drm_gem_vm_open(struct vm_area_struct *vma); | 1463 | void drm_gem_vm_open(struct vm_area_struct *vma); |
1463 | void drm_gem_vm_close(struct vm_area_struct *vma); | 1464 | void drm_gem_vm_close(struct vm_area_struct *vma); |
1464 | int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma); | 1465 | int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma); |
@@ -1481,8 +1482,12 @@ drm_gem_object_unreference(struct drm_gem_object *obj) | |||
1481 | static inline void | 1482 | static inline void |
1482 | drm_gem_object_unreference_unlocked(struct drm_gem_object *obj) | 1483 | drm_gem_object_unreference_unlocked(struct drm_gem_object *obj) |
1483 | { | 1484 | { |
1484 | if (obj != NULL) | 1485 | if (obj != NULL) { |
1485 | kref_put(&obj->refcount, drm_gem_object_free_unlocked); | 1486 | struct drm_device *dev = obj->dev; |
1487 | mutex_lock(&dev->struct_mutex); | ||
1488 | kref_put(&obj->refcount, drm_gem_object_free); | ||
1489 | mutex_unlock(&dev->struct_mutex); | ||
1490 | } | ||
1486 | } | 1491 | } |
1487 | 1492 | ||
1488 | int drm_gem_handle_create(struct drm_file *file_priv, | 1493 | int drm_gem_handle_create(struct drm_file *file_priv, |
@@ -1493,7 +1498,7 @@ static inline void | |||
1493 | drm_gem_object_handle_reference(struct drm_gem_object *obj) | 1498 | drm_gem_object_handle_reference(struct drm_gem_object *obj) |
1494 | { | 1499 | { |
1495 | drm_gem_object_reference(obj); | 1500 | drm_gem_object_reference(obj); |
1496 | kref_get(&obj->handlecount); | 1501 | atomic_inc(&obj->handle_count); |
1497 | } | 1502 | } |
1498 | 1503 | ||
1499 | static inline void | 1504 | static inline void |
@@ -1502,12 +1507,15 @@ drm_gem_object_handle_unreference(struct drm_gem_object *obj) | |||
1502 | if (obj == NULL) | 1507 | if (obj == NULL) |
1503 | return; | 1508 | return; |
1504 | 1509 | ||
1510 | if (atomic_read(&obj->handle_count) == 0) | ||
1511 | return; | ||
1505 | /* | 1512 | /* |
1506 | * Must bump handle count first as this may be the last | 1513 | * Must bump handle count first as this may be the last |
1507 | * ref, in which case the object would disappear before we | 1514 | * ref, in which case the object would disappear before we |
1508 | * checked for a name | 1515 | * checked for a name |
1509 | */ | 1516 | */ |
1510 | kref_put(&obj->handlecount, drm_gem_object_handle_free); | 1517 | if (atomic_dec_and_test(&obj->handle_count)) |
1518 | drm_gem_object_handle_free(obj); | ||
1511 | drm_gem_object_unreference(obj); | 1519 | drm_gem_object_unreference(obj); |
1512 | } | 1520 | } |
1513 | 1521 | ||
@@ -1517,12 +1525,17 @@ drm_gem_object_handle_unreference_unlocked(struct drm_gem_object *obj) | |||
1517 | if (obj == NULL) | 1525 | if (obj == NULL) |
1518 | return; | 1526 | return; |
1519 | 1527 | ||
1528 | if (atomic_read(&obj->handle_count) == 0) | ||
1529 | return; | ||
1530 | |||
1520 | /* | 1531 | /* |
1521 | * Must bump handle count first as this may be the last | 1532 | * Must bump handle count first as this may be the last |
1522 | * ref, in which case the object would disappear before we | 1533 | * ref, in which case the object would disappear before we |
1523 | * checked for a name | 1534 | * checked for a name |
1524 | */ | 1535 | */ |
1525 | kref_put(&obj->handlecount, drm_gem_object_handle_free); | 1536 | |
1537 | if (atomic_dec_and_test(&obj->handle_count)) | ||
1538 | drm_gem_object_handle_free(obj); | ||
1526 | drm_gem_object_unreference_unlocked(obj); | 1539 | drm_gem_object_unreference_unlocked(obj); |
1527 | } | 1540 | } |
1528 | 1541 | ||
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index c9f3cc5949a..3e5a51af757 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h | |||
@@ -386,7 +386,15 @@ struct drm_connector_funcs { | |||
386 | void (*dpms)(struct drm_connector *connector, int mode); | 386 | void (*dpms)(struct drm_connector *connector, int mode); |
387 | void (*save)(struct drm_connector *connector); | 387 | void (*save)(struct drm_connector *connector); |
388 | void (*restore)(struct drm_connector *connector); | 388 | void (*restore)(struct drm_connector *connector); |
389 | enum drm_connector_status (*detect)(struct drm_connector *connector); | 389 | |
390 | /* Check to see if anything is attached to the connector. | ||
391 | * @force is set to false whilst polling, true when checking the | ||
392 | * connector due to user request. @force can be used by the driver | ||
393 | * to avoid expensive, destructive operations during automated | ||
394 | * probing. | ||
395 | */ | ||
396 | enum drm_connector_status (*detect)(struct drm_connector *connector, | ||
397 | bool force); | ||
390 | int (*fill_modes)(struct drm_connector *connector, uint32_t max_width, uint32_t max_height); | 398 | int (*fill_modes)(struct drm_connector *connector, uint32_t max_width, uint32_t max_height); |
391 | int (*set_property)(struct drm_connector *connector, struct drm_property *property, | 399 | int (*set_property)(struct drm_connector *connector, struct drm_property *property, |
392 | uint64_t val); | 400 | uint64_t val); |
diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h index 3a9940ef728..883c1d43989 100644 --- a/include/drm/drm_pciids.h +++ b/include/drm/drm_pciids.h | |||
@@ -85,7 +85,6 @@ | |||
85 | {0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ | 85 | {0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ |
86 | {0x1002, 0x5462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ | 86 | {0x1002, 0x5462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ |
87 | {0x1002, 0x5464, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ | 87 | {0x1002, 0x5464, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ |
88 | {0x1002, 0x5657, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ | ||
89 | {0x1002, 0x5548, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ | 88 | {0x1002, 0x5548, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ |
90 | {0x1002, 0x5549, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ | 89 | {0x1002, 0x5549, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ |
91 | {0x1002, 0x554A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ | 90 | {0x1002, 0x554A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ |
@@ -103,6 +102,7 @@ | |||
103 | {0x1002, 0x564F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 102 | {0x1002, 0x564F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
104 | {0x1002, 0x5652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 103 | {0x1002, 0x5652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
105 | {0x1002, 0x5653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 104 | {0x1002, 0x5653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
105 | {0x1002, 0x5657, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ | ||
106 | {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP}, \ | 106 | {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP}, \ |
107 | {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \ | 107 | {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \ |
108 | {0x1002, 0x5954, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \ | 108 | {0x1002, 0x5954, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \ |
diff --git a/include/drm/i830_drm.h b/include/drm/i830_drm.h index 4b00d2dd4f6..61315c29b8f 100644 --- a/include/drm/i830_drm.h +++ b/include/drm/i830_drm.h | |||
@@ -264,20 +264,20 @@ typedef struct _drm_i830_sarea { | |||
264 | #define DRM_I830_GETPARAM 0x0c | 264 | #define DRM_I830_GETPARAM 0x0c |
265 | #define DRM_I830_SETPARAM 0x0d | 265 | #define DRM_I830_SETPARAM 0x0d |
266 | 266 | ||
267 | #define DRM_IOCTL_I830_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_IOCTL_I830_INIT, drm_i830_init_t) | 267 | #define DRM_IOCTL_I830_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I830_INIT, drm_i830_init_t) |
268 | #define DRM_IOCTL_I830_VERTEX DRM_IOW( DRM_COMMAND_BASE + DRM_IOCTL_I830_VERTEX, drm_i830_vertex_t) | 268 | #define DRM_IOCTL_I830_VERTEX DRM_IOW( DRM_COMMAND_BASE + DRM_I830_VERTEX, drm_i830_vertex_t) |
269 | #define DRM_IOCTL_I830_CLEAR DRM_IOW( DRM_COMMAND_BASE + DRM_IOCTL_I830_CLEAR, drm_i830_clear_t) | 269 | #define DRM_IOCTL_I830_CLEAR DRM_IOW( DRM_COMMAND_BASE + DRM_I830_CLEAR, drm_i830_clear_t) |
270 | #define DRM_IOCTL_I830_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_IOCTL_I830_FLUSH) | 270 | #define DRM_IOCTL_I830_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I830_FLUSH) |
271 | #define DRM_IOCTL_I830_GETAGE DRM_IO ( DRM_COMMAND_BASE + DRM_IOCTL_I830_GETAGE) | 271 | #define DRM_IOCTL_I830_GETAGE DRM_IO ( DRM_COMMAND_BASE + DRM_I830_GETAGE) |
272 | #define DRM_IOCTL_I830_GETBUF DRM_IOWR(DRM_COMMAND_BASE + DRM_IOCTL_I830_GETBUF, drm_i830_dma_t) | 272 | #define DRM_IOCTL_I830_GETBUF DRM_IOWR(DRM_COMMAND_BASE + DRM_I830_GETBUF, drm_i830_dma_t) |
273 | #define DRM_IOCTL_I830_SWAP DRM_IO ( DRM_COMMAND_BASE + DRM_IOCTL_I830_SWAP) | 273 | #define DRM_IOCTL_I830_SWAP DRM_IO ( DRM_COMMAND_BASE + DRM_I830_SWAP) |
274 | #define DRM_IOCTL_I830_COPY DRM_IOW( DRM_COMMAND_BASE + DRM_IOCTL_I830_COPY, drm_i830_copy_t) | 274 | #define DRM_IOCTL_I830_COPY DRM_IOW( DRM_COMMAND_BASE + DRM_I830_COPY, drm_i830_copy_t) |
275 | #define DRM_IOCTL_I830_DOCOPY DRM_IO ( DRM_COMMAND_BASE + DRM_IOCTL_I830_DOCOPY) | 275 | #define DRM_IOCTL_I830_DOCOPY DRM_IO ( DRM_COMMAND_BASE + DRM_I830_DOCOPY) |
276 | #define DRM_IOCTL_I830_FLIP DRM_IO ( DRM_COMMAND_BASE + DRM_IOCTL_I830_FLIP) | 276 | #define DRM_IOCTL_I830_FLIP DRM_IO ( DRM_COMMAND_BASE + DRM_I830_FLIP) |
277 | #define DRM_IOCTL_I830_IRQ_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_IOCTL_I830_IRQ_EMIT, drm_i830_irq_emit_t) | 277 | #define DRM_IOCTL_I830_IRQ_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_I830_IRQ_EMIT, drm_i830_irq_emit_t) |
278 | #define DRM_IOCTL_I830_IRQ_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_IOCTL_I830_IRQ_WAIT, drm_i830_irq_wait_t) | 278 | #define DRM_IOCTL_I830_IRQ_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_I830_IRQ_WAIT, drm_i830_irq_wait_t) |
279 | #define DRM_IOCTL_I830_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_IOCTL_I830_GETPARAM, drm_i830_getparam_t) | 279 | #define DRM_IOCTL_I830_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_I830_GETPARAM, drm_i830_getparam_t) |
280 | #define DRM_IOCTL_I830_SETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_IOCTL_I830_SETPARAM, drm_i830_setparam_t) | 280 | #define DRM_IOCTL_I830_SETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_I830_SETPARAM, drm_i830_setparam_t) |
281 | 281 | ||
282 | typedef struct _drm_i830_clear { | 282 | typedef struct _drm_i830_clear { |
283 | int clear_color; | 283 | int clear_color; |
diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h index 8f8b072c4c7..e41c74facb6 100644 --- a/include/drm/i915_drm.h +++ b/include/drm/i915_drm.h | |||
@@ -215,6 +215,7 @@ typedef struct _drm_i915_sarea { | |||
215 | #define DRM_IOCTL_I915_SET_VBLANK_PIPE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t) | 215 | #define DRM_IOCTL_I915_SET_VBLANK_PIPE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t) |
216 | #define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t) | 216 | #define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t) |
217 | #define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t) | 217 | #define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t) |
218 | #define DRM_IOCTL_I915_HWS_ADDR DRM_IOW(DRM_COMMAND_BASE + DRM_I915_HWS_ADDR, struct drm_i915_gem_init) | ||
218 | #define DRM_IOCTL_I915_GEM_INIT DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_INIT, struct drm_i915_gem_init) | 219 | #define DRM_IOCTL_I915_GEM_INIT DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_INIT, struct drm_i915_gem_init) |
219 | #define DRM_IOCTL_I915_GEM_EXECBUFFER DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER, struct drm_i915_gem_execbuffer) | 220 | #define DRM_IOCTL_I915_GEM_EXECBUFFER DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER, struct drm_i915_gem_execbuffer) |
220 | #define DRM_IOCTL_I915_GEM_EXECBUFFER2 DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER2, struct drm_i915_gem_execbuffer2) | 221 | #define DRM_IOCTL_I915_GEM_EXECBUFFER2 DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER2, struct drm_i915_gem_execbuffer2) |
diff --git a/include/drm/mga_drm.h b/include/drm/mga_drm.h index 3ffbc4798af..c16097f99be 100644 --- a/include/drm/mga_drm.h +++ b/include/drm/mga_drm.h | |||
@@ -248,7 +248,7 @@ typedef struct _drm_mga_sarea { | |||
248 | #define DRM_MGA_DMA_BOOTSTRAP 0x0c | 248 | #define DRM_MGA_DMA_BOOTSTRAP 0x0c |
249 | 249 | ||
250 | #define DRM_IOCTL_MGA_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_INIT, drm_mga_init_t) | 250 | #define DRM_IOCTL_MGA_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_INIT, drm_mga_init_t) |
251 | #define DRM_IOCTL_MGA_FLUSH DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_FLUSH, drm_lock_t) | 251 | #define DRM_IOCTL_MGA_FLUSH DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_FLUSH, struct drm_lock) |
252 | #define DRM_IOCTL_MGA_RESET DRM_IO( DRM_COMMAND_BASE + DRM_MGA_RESET) | 252 | #define DRM_IOCTL_MGA_RESET DRM_IO( DRM_COMMAND_BASE + DRM_MGA_RESET) |
253 | #define DRM_IOCTL_MGA_SWAP DRM_IO( DRM_COMMAND_BASE + DRM_MGA_SWAP) | 253 | #define DRM_IOCTL_MGA_SWAP DRM_IO( DRM_COMMAND_BASE + DRM_MGA_SWAP) |
254 | #define DRM_IOCTL_MGA_CLEAR DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_CLEAR, drm_mga_clear_t) | 254 | #define DRM_IOCTL_MGA_CLEAR DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_CLEAR, drm_mga_clear_t) |
diff --git a/include/drm/nouveau_drm.h b/include/drm/nouveau_drm.h index fe917dee723..01a71411950 100644 --- a/include/drm/nouveau_drm.h +++ b/include/drm/nouveau_drm.h | |||
@@ -197,4 +197,17 @@ struct drm_nouveau_sarea { | |||
197 | #define DRM_NOUVEAU_GEM_CPU_FINI 0x43 | 197 | #define DRM_NOUVEAU_GEM_CPU_FINI 0x43 |
198 | #define DRM_NOUVEAU_GEM_INFO 0x44 | 198 | #define DRM_NOUVEAU_GEM_INFO 0x44 |
199 | 199 | ||
200 | #define DRM_IOCTL_NOUVEAU_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GETPARAM, struct drm_nouveau_getparam) | ||
201 | #define DRM_IOCTL_NOUVEAU_SETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_SETPARAM, struct drm_nouveau_setparam) | ||
202 | #define DRM_IOCTL_NOUVEAU_CHANNEL_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_CHANNEL_ALLOC, struct drm_nouveau_channel_alloc) | ||
203 | #define DRM_IOCTL_NOUVEAU_CHANNEL_FREE DRM_IOW (DRM_COMMAND_BASE + DRM_NOUVEAU_CHANNEL_FREE, struct drm_nouveau_channel_free) | ||
204 | #define DRM_IOCTL_NOUVEAU_GROBJ_ALLOC DRM_IOW (DRM_COMMAND_BASE + DRM_NOUVEAU_GROBJ_ALLOC, struct drm_nouveau_grobj_alloc) | ||
205 | #define DRM_IOCTL_NOUVEAU_NOTIFIEROBJ_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_NOTIFIEROBJ_ALLOC, struct drm_nouveau_notifierobj_alloc) | ||
206 | #define DRM_IOCTL_NOUVEAU_GPUOBJ_FREE DRM_IOW (DRM_COMMAND_BASE + DRM_NOUVEAU_GPUOBJ_FREE, struct drm_nouveau_gpuobj_free) | ||
207 | #define DRM_IOCTL_NOUVEAU_GEM_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_NEW, struct drm_nouveau_gem_new) | ||
208 | #define DRM_IOCTL_NOUVEAU_GEM_PUSHBUF DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_PUSHBUF, struct drm_nouveau_gem_pushbuf) | ||
209 | #define DRM_IOCTL_NOUVEAU_GEM_CPU_PREP DRM_IOW (DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_CPU_PREP, struct drm_nouveau_gem_cpu_prep) | ||
210 | #define DRM_IOCTL_NOUVEAU_GEM_CPU_FINI DRM_IOW (DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_CPU_FINI, struct drm_nouveau_gem_cpu_fini) | ||
211 | #define DRM_IOCTL_NOUVEAU_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_INFO, struct drm_nouveau_gem_info) | ||
212 | |||
200 | #endif /* __NOUVEAU_DRM_H__ */ | 213 | #endif /* __NOUVEAU_DRM_H__ */ |
diff --git a/include/drm/radeon_drm.h b/include/drm/radeon_drm.h index 0acaf8f9143..10f8b53bdd4 100644 --- a/include/drm/radeon_drm.h +++ b/include/drm/radeon_drm.h | |||
@@ -547,8 +547,8 @@ typedef struct { | |||
547 | #define DRM_IOCTL_RADEON_GEM_WAIT_IDLE DRM_IOW(DRM_COMMAND_BASE + DRM_RADEON_GEM_WAIT_IDLE, struct drm_radeon_gem_wait_idle) | 547 | #define DRM_IOCTL_RADEON_GEM_WAIT_IDLE DRM_IOW(DRM_COMMAND_BASE + DRM_RADEON_GEM_WAIT_IDLE, struct drm_radeon_gem_wait_idle) |
548 | #define DRM_IOCTL_RADEON_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_CS, struct drm_radeon_cs) | 548 | #define DRM_IOCTL_RADEON_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_CS, struct drm_radeon_cs) |
549 | #define DRM_IOCTL_RADEON_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_INFO, struct drm_radeon_info) | 549 | #define DRM_IOCTL_RADEON_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_INFO, struct drm_radeon_info) |
550 | #define DRM_IOCTL_RADEON_SET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_SET_TILING, struct drm_radeon_gem_set_tiling) | 550 | #define DRM_IOCTL_RADEON_GEM_SET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_SET_TILING, struct drm_radeon_gem_set_tiling) |
551 | #define DRM_IOCTL_RADEON_GET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_GET_TILING, struct drm_radeon_gem_get_tiling) | 551 | #define DRM_IOCTL_RADEON_GEM_GET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_GET_TILING, struct drm_radeon_gem_get_tiling) |
552 | #define DRM_IOCTL_RADEON_GEM_BUSY DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_BUSY, struct drm_radeon_gem_busy) | 552 | #define DRM_IOCTL_RADEON_GEM_BUSY DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_BUSY, struct drm_radeon_gem_busy) |
553 | 553 | ||
554 | typedef struct drm_radeon_init { | 554 | typedef struct drm_radeon_init { |
diff --git a/include/drm/savage_drm.h b/include/drm/savage_drm.h index 8a576ef0182..4863cf6bf96 100644 --- a/include/drm/savage_drm.h +++ b/include/drm/savage_drm.h | |||
@@ -63,10 +63,10 @@ typedef struct _drm_savage_sarea { | |||
63 | #define DRM_SAVAGE_BCI_EVENT_EMIT 0x02 | 63 | #define DRM_SAVAGE_BCI_EVENT_EMIT 0x02 |
64 | #define DRM_SAVAGE_BCI_EVENT_WAIT 0x03 | 64 | #define DRM_SAVAGE_BCI_EVENT_WAIT 0x03 |
65 | 65 | ||
66 | #define DRM_IOCTL_SAVAGE_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_INIT, drm_savage_init_t) | 66 | #define DRM_IOCTL_SAVAGE_BCI_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_INIT, drm_savage_init_t) |
67 | #define DRM_IOCTL_SAVAGE_CMDBUF DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_CMDBUF, drm_savage_cmdbuf_t) | 67 | #define DRM_IOCTL_SAVAGE_BCI_CMDBUF DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_CMDBUF, drm_savage_cmdbuf_t) |
68 | #define DRM_IOCTL_SAVAGE_EVENT_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_SAVAGE_BCI_EVENT_EMIT, drm_savage_event_emit_t) | 68 | #define DRM_IOCTL_SAVAGE_BCI_EVENT_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_SAVAGE_BCI_EVENT_EMIT, drm_savage_event_emit_t) |
69 | #define DRM_IOCTL_SAVAGE_EVENT_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_EVENT_WAIT, drm_savage_event_wait_t) | 69 | #define DRM_IOCTL_SAVAGE_BCI_EVENT_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_EVENT_WAIT, drm_savage_event_wait_t) |
70 | 70 | ||
71 | #define SAVAGE_DMA_PCI 1 | 71 | #define SAVAGE_DMA_PCI 1 |
72 | #define SAVAGE_DMA_AGP 3 | 72 | #define SAVAGE_DMA_AGP 3 |
diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index 267a86c74e2..2040e6c4f17 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h | |||
@@ -246,9 +246,11 @@ struct ttm_buffer_object { | |||
246 | 246 | ||
247 | atomic_t reserved; | 247 | atomic_t reserved; |
248 | 248 | ||
249 | |||
250 | /** | 249 | /** |
251 | * Members protected by the bo::lock | 250 | * Members protected by the bo::lock |
251 | * In addition, setting sync_obj to anything else | ||
252 | * than NULL requires bo::reserved to be held. This allows for | ||
253 | * checking NULL while reserved but not holding bo::lock. | ||
252 | */ | 254 | */ |
253 | 255 | ||
254 | void *sync_obj_arg; | 256 | void *sync_obj_arg; |
diff --git a/include/linux/Kbuild b/include/linux/Kbuild index 626b629429f..4e8ea8c8ec1 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild | |||
@@ -118,7 +118,6 @@ header-y += eventpoll.h | |||
118 | header-y += ext2_fs.h | 118 | header-y += ext2_fs.h |
119 | header-y += fadvise.h | 119 | header-y += fadvise.h |
120 | header-y += falloc.h | 120 | header-y += falloc.h |
121 | header-y += fanotify.h | ||
122 | header-y += fb.h | 121 | header-y += fb.h |
123 | header-y += fcntl.h | 122 | header-y += fcntl.h |
124 | header-y += fd.h | 123 | header-y += fd.h |
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index ccf94dc5acd..c227757feb0 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -304,8 +304,8 @@ acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context); | |||
304 | OSC_PCI_EXPRESS_PME_CONTROL | \ | 304 | OSC_PCI_EXPRESS_PME_CONTROL | \ |
305 | OSC_PCI_EXPRESS_AER_CONTROL | \ | 305 | OSC_PCI_EXPRESS_AER_CONTROL | \ |
306 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL) | 306 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL) |
307 | 307 | extern acpi_status acpi_pci_osc_control_set(acpi_handle handle, | |
308 | extern acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 flags); | 308 | u32 *mask, u32 req); |
309 | extern void acpi_early_init(void); | 309 | extern void acpi_early_init(void); |
310 | 310 | ||
311 | #else /* !CONFIG_ACPI */ | 311 | #else /* !CONFIG_ACPI */ |
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index ed3e92e41c6..0c991023ee4 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h | |||
@@ -578,7 +578,12 @@ struct task_struct *cgroup_iter_next(struct cgroup *cgrp, | |||
578 | void cgroup_iter_end(struct cgroup *cgrp, struct cgroup_iter *it); | 578 | void cgroup_iter_end(struct cgroup *cgrp, struct cgroup_iter *it); |
579 | int cgroup_scan_tasks(struct cgroup_scanner *scan); | 579 | int cgroup_scan_tasks(struct cgroup_scanner *scan); |
580 | int cgroup_attach_task(struct cgroup *, struct task_struct *); | 580 | int cgroup_attach_task(struct cgroup *, struct task_struct *); |
581 | int cgroup_attach_task_current_cg(struct task_struct *); | 581 | int cgroup_attach_task_all(struct task_struct *from, struct task_struct *); |
582 | |||
583 | static inline int cgroup_attach_task_current_cg(struct task_struct *tsk) | ||
584 | { | ||
585 | return cgroup_attach_task_all(current, tsk); | ||
586 | } | ||
582 | 587 | ||
583 | /* | 588 | /* |
584 | * CSS ID is ID for cgroup_subsys_state structs under subsys. This only works | 589 | * CSS ID is ID for cgroup_subsys_state structs under subsys. This only works |
@@ -636,6 +641,11 @@ static inline int cgroupstats_build(struct cgroupstats *stats, | |||
636 | } | 641 | } |
637 | 642 | ||
638 | /* No cgroups - nothing to do */ | 643 | /* No cgroups - nothing to do */ |
644 | static inline int cgroup_attach_task_all(struct task_struct *from, | ||
645 | struct task_struct *t) | ||
646 | { | ||
647 | return 0; | ||
648 | } | ||
639 | static inline int cgroup_attach_task_current_cg(struct task_struct *t) | 649 | static inline int cgroup_attach_task_current_cg(struct task_struct *t) |
640 | { | 650 | { |
641 | return 0; | 651 | return 0; |
diff --git a/include/linux/compat.h b/include/linux/compat.h index 9ddc8780e8d..5778b559d59 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h | |||
@@ -360,5 +360,8 @@ extern ssize_t compat_rw_copy_check_uvector(int type, | |||
360 | const struct compat_iovec __user *uvector, unsigned long nr_segs, | 360 | const struct compat_iovec __user *uvector, unsigned long nr_segs, |
361 | unsigned long fast_segs, struct iovec *fast_pointer, | 361 | unsigned long fast_segs, struct iovec *fast_pointer, |
362 | struct iovec **ret_pointer); | 362 | struct iovec **ret_pointer); |
363 | |||
364 | extern void __user *compat_alloc_user_space(unsigned long len); | ||
365 | |||
363 | #endif /* CONFIG_COMPAT */ | 366 | #endif /* CONFIG_COMPAT */ |
364 | #endif /* _LINUX_COMPAT_H */ | 367 | #endif /* _LINUX_COMPAT_H */ |
diff --git a/include/linux/coredump.h b/include/linux/coredump.h index 8ba66a9d902..ba4b85a6d9b 100644 --- a/include/linux/coredump.h +++ b/include/linux/coredump.h | |||
@@ -9,37 +9,7 @@ | |||
9 | * These are the only things you should do on a core-file: use only these | 9 | * These are the only things you should do on a core-file: use only these |
10 | * functions to write out all the necessary info. | 10 | * functions to write out all the necessary info. |
11 | */ | 11 | */ |
12 | static inline int dump_write(struct file *file, const void *addr, int nr) | 12 | extern int dump_write(struct file *file, const void *addr, int nr); |
13 | { | 13 | extern int dump_seek(struct file *file, loff_t off); |
14 | return file->f_op->write(file, addr, nr, &file->f_pos) == nr; | ||
15 | } | ||
16 | |||
17 | static inline int dump_seek(struct file *file, loff_t off) | ||
18 | { | ||
19 | int ret = 1; | ||
20 | |||
21 | if (file->f_op->llseek && file->f_op->llseek != no_llseek) { | ||
22 | if (file->f_op->llseek(file, off, SEEK_CUR) < 0) | ||
23 | return 0; | ||
24 | } else { | ||
25 | char *buf = (char *)get_zeroed_page(GFP_KERNEL); | ||
26 | |||
27 | if (!buf) | ||
28 | return 0; | ||
29 | while (off > 0) { | ||
30 | unsigned long n = off; | ||
31 | |||
32 | if (n > PAGE_SIZE) | ||
33 | n = PAGE_SIZE; | ||
34 | if (!dump_write(file, buf, n)) { | ||
35 | ret = 0; | ||
36 | break; | ||
37 | } | ||
38 | off -= n; | ||
39 | } | ||
40 | free_page((unsigned long)buf); | ||
41 | } | ||
42 | return ret; | ||
43 | } | ||
44 | 14 | ||
45 | #endif /* _LINUX_COREDUMP_H */ | 15 | #endif /* _LINUX_COREDUMP_H */ |
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index 36ca9721a0c..1be416bbbb8 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h | |||
@@ -53,6 +53,7 @@ struct cpuidle_state { | |||
53 | #define CPUIDLE_FLAG_BALANCED (0x40) /* medium latency, moderate savings */ | 53 | #define CPUIDLE_FLAG_BALANCED (0x40) /* medium latency, moderate savings */ |
54 | #define CPUIDLE_FLAG_DEEP (0x80) /* high latency, large savings */ | 54 | #define CPUIDLE_FLAG_DEEP (0x80) /* high latency, large savings */ |
55 | #define CPUIDLE_FLAG_IGNORE (0x100) /* ignore during this idle period */ | 55 | #define CPUIDLE_FLAG_IGNORE (0x100) /* ignore during this idle period */ |
56 | #define CPUIDLE_FLAG_TLB_FLUSHED (0x200) /* tlb will be flushed */ | ||
56 | 57 | ||
57 | #define CPUIDLE_DRIVER_FLAGS_MASK (0xFFFF0000) | 58 | #define CPUIDLE_DRIVER_FLAGS_MASK (0xFFFF0000) |
58 | 59 | ||
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index ce29b815119..ba8319ae5fc 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h | |||
@@ -102,6 +102,9 @@ static inline u64 dma_get_mask(struct device *dev) | |||
102 | return DMA_BIT_MASK(32); | 102 | return DMA_BIT_MASK(32); |
103 | } | 103 | } |
104 | 104 | ||
105 | #ifdef ARCH_HAS_DMA_SET_COHERENT_MASK | ||
106 | int dma_set_coherent_mask(struct device *dev, u64 mask); | ||
107 | #else | ||
105 | static inline int dma_set_coherent_mask(struct device *dev, u64 mask) | 108 | static inline int dma_set_coherent_mask(struct device *dev, u64 mask) |
106 | { | 109 | { |
107 | if (!dma_supported(dev, mask)) | 110 | if (!dma_supported(dev, mask)) |
@@ -109,6 +112,7 @@ static inline int dma_set_coherent_mask(struct device *dev, u64 mask) | |||
109 | dev->coherent_dma_mask = mask; | 112 | dev->coherent_dma_mask = mask; |
110 | return 0; | 113 | return 0; |
111 | } | 114 | } |
115 | #endif | ||
112 | 116 | ||
113 | extern u64 dma_get_required_mask(struct device *dev); | 117 | extern u64 dma_get_required_mask(struct device *dev); |
114 | 118 | ||
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index c61d4ca27bc..e2106495cc1 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h | |||
@@ -548,7 +548,7 @@ static inline bool dma_dev_has_pq_continue(struct dma_device *dma) | |||
548 | return (dma->max_pq & DMA_HAS_PQ_CONTINUE) == DMA_HAS_PQ_CONTINUE; | 548 | return (dma->max_pq & DMA_HAS_PQ_CONTINUE) == DMA_HAS_PQ_CONTINUE; |
549 | } | 549 | } |
550 | 550 | ||
551 | static unsigned short dma_dev_to_maxpq(struct dma_device *dma) | 551 | static inline unsigned short dma_dev_to_maxpq(struct dma_device *dma) |
552 | { | 552 | { |
553 | return dma->max_pq & ~DMA_HAS_PQ_CONTINUE; | 553 | return dma->max_pq & ~DMA_HAS_PQ_CONTINUE; |
554 | } | 554 | } |
diff --git a/include/linux/elevator.h b/include/linux/elevator.h index 2c958f4fce1..4fd978e7eb8 100644 --- a/include/linux/elevator.h +++ b/include/linux/elevator.h | |||
@@ -93,6 +93,7 @@ struct elevator_queue | |||
93 | struct elevator_type *elevator_type; | 93 | struct elevator_type *elevator_type; |
94 | struct mutex sysfs_lock; | 94 | struct mutex sysfs_lock; |
95 | struct hlist_head *hash; | 95 | struct hlist_head *hash; |
96 | unsigned int registered:1; | ||
96 | }; | 97 | }; |
97 | 98 | ||
98 | /* | 99 | /* |
@@ -136,6 +137,7 @@ extern ssize_t elv_iosched_store(struct request_queue *, const char *, size_t); | |||
136 | 137 | ||
137 | extern int elevator_init(struct request_queue *, char *); | 138 | extern int elevator_init(struct request_queue *, char *); |
138 | extern void elevator_exit(struct elevator_queue *); | 139 | extern void elevator_exit(struct elevator_queue *); |
140 | extern int elevator_change(struct request_queue *, const char *); | ||
139 | extern int elv_rq_merge_ok(struct request *, struct bio *); | 141 | extern int elv_rq_merge_ok(struct request *, struct bio *); |
140 | 142 | ||
141 | /* | 143 | /* |
diff --git a/include/linux/fanotify.h b/include/linux/fanotify.h index f0949a57ca9..63531a6b4d2 100644 --- a/include/linux/fanotify.h +++ b/include/linux/fanotify.h | |||
@@ -65,14 +65,14 @@ | |||
65 | FAN_ALL_PERM_EVENTS |\ | 65 | FAN_ALL_PERM_EVENTS |\ |
66 | FAN_Q_OVERFLOW) | 66 | FAN_Q_OVERFLOW) |
67 | 67 | ||
68 | #define FANOTIFY_METADATA_VERSION 1 | 68 | #define FANOTIFY_METADATA_VERSION 2 |
69 | 69 | ||
70 | struct fanotify_event_metadata { | 70 | struct fanotify_event_metadata { |
71 | __u32 event_len; | 71 | __u32 event_len; |
72 | __u32 vers; | 72 | __u32 vers; |
73 | __s32 fd; | ||
74 | __u64 mask; | 73 | __u64 mask; |
75 | __s64 pid; | 74 | __s32 fd; |
75 | __s32 pid; | ||
76 | } __attribute__ ((packed)); | 76 | } __attribute__ ((packed)); |
77 | 77 | ||
78 | struct fanotify_response { | 78 | struct fanotify_response { |
@@ -95,11 +95,4 @@ struct fanotify_response { | |||
95 | (long)(meta)->event_len >= (long)FAN_EVENT_METADATA_LEN && \ | 95 | (long)(meta)->event_len >= (long)FAN_EVENT_METADATA_LEN && \ |
96 | (long)(meta)->event_len <= (long)(len)) | 96 | (long)(meta)->event_len <= (long)(len)) |
97 | 97 | ||
98 | #ifdef __KERNEL__ | ||
99 | |||
100 | struct fanotify_wait { | ||
101 | struct fsnotify_event *event; | ||
102 | __s32 fd; | ||
103 | }; | ||
104 | #endif /* __KERNEL__ */ | ||
105 | #endif /* _LINUX_FANOTIFY_H */ | 98 | #endif /* _LINUX_FANOTIFY_H */ |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 6b0f6e9993a..34a1cbcb561 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -1089,6 +1089,10 @@ struct file_lock { | |||
1089 | 1089 | ||
1090 | #include <linux/fcntl.h> | 1090 | #include <linux/fcntl.h> |
1091 | 1091 | ||
1092 | /* temporary stubs for BKL removal */ | ||
1093 | #define lock_flocks() lock_kernel() | ||
1094 | #define unlock_flocks() unlock_kernel() | ||
1095 | |||
1092 | extern void send_sigio(struct fown_struct *fown, int fd, int band); | 1096 | extern void send_sigio(struct fown_struct *fown, int fd, int band); |
1093 | 1097 | ||
1094 | #ifdef CONFIG_FILE_LOCKING | 1098 | #ifdef CONFIG_FILE_LOCKING |
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index ed36fb57c42..e40190d1687 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h | |||
@@ -156,6 +156,7 @@ struct fsnotify_group { | |||
156 | struct mutex access_mutex; | 156 | struct mutex access_mutex; |
157 | struct list_head access_list; | 157 | struct list_head access_list; |
158 | wait_queue_head_t access_waitq; | 158 | wait_queue_head_t access_waitq; |
159 | bool bypass_perm; /* protected by access_mutex */ | ||
159 | #endif /* CONFIG_FANOTIFY_ACCESS_PERMISSIONS */ | 160 | #endif /* CONFIG_FANOTIFY_ACCESS_PERMISSIONS */ |
160 | int f_flags; | 161 | int f_flags; |
161 | } fanotify_data; | 162 | } fanotify_data; |
diff --git a/include/linux/gpio.h b/include/linux/gpio.h index 03f616b78cf..e41f7dd1ae6 100644 --- a/include/linux/gpio.h +++ b/include/linux/gpio.h | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/errno.h> | 13 | #include <linux/errno.h> |
14 | 14 | ||
15 | struct device; | 15 | struct device; |
16 | struct gpio_chip; | ||
16 | 17 | ||
17 | /* | 18 | /* |
18 | * Some platforms don't support the GPIO programming interface. | 19 | * Some platforms don't support the GPIO programming interface. |
diff --git a/include/linux/i2c/sx150x.h b/include/linux/i2c/sx150x.h index ee3049cb9ba..52baa79d69a 100644 --- a/include/linux/i2c/sx150x.h +++ b/include/linux/i2c/sx150x.h | |||
@@ -63,6 +63,9 @@ | |||
63 | * IRQ lines will appear. Similarly to gpio_base, the expander | 63 | * IRQ lines will appear. Similarly to gpio_base, the expander |
64 | * will create a block of irqs beginning at this number. | 64 | * will create a block of irqs beginning at this number. |
65 | * This value is ignored if irq_summary is < 0. | 65 | * This value is ignored if irq_summary is < 0. |
66 | * @reset_during_probe: If set to true, the driver will trigger a full | ||
67 | * reset of the chip at the beginning of the probe | ||
68 | * in order to place it in a known state. | ||
66 | */ | 69 | */ |
67 | struct sx150x_platform_data { | 70 | struct sx150x_platform_data { |
68 | unsigned gpio_base; | 71 | unsigned gpio_base; |
@@ -73,6 +76,7 @@ struct sx150x_platform_data { | |||
73 | u16 io_polarity; | 76 | u16 io_polarity; |
74 | int irq_summary; | 77 | int irq_summary; |
75 | unsigned irq_base; | 78 | unsigned irq_base; |
79 | bool reset_during_probe; | ||
76 | }; | 80 | }; |
77 | 81 | ||
78 | #endif /* __LINUX_I2C_SX150X_H */ | 82 | #endif /* __LINUX_I2C_SX150X_H */ |
diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h index c831467774d..bed7a4682b9 100644 --- a/include/linux/if_ether.h +++ b/include/linux/if_ether.h | |||
@@ -119,7 +119,7 @@ struct ethhdr { | |||
119 | unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ | 119 | unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ |
120 | unsigned char h_source[ETH_ALEN]; /* source ether addr */ | 120 | unsigned char h_source[ETH_ALEN]; /* source ether addr */ |
121 | __be16 h_proto; /* packet type ID field */ | 121 | __be16 h_proto; /* packet type ID field */ |
122 | } __packed; | 122 | } __attribute__((packed)); |
123 | 123 | ||
124 | #ifdef __KERNEL__ | 124 | #ifdef __KERNEL__ |
125 | #include <linux/skbuff.h> | 125 | #include <linux/skbuff.h> |
diff --git a/include/linux/if_fddi.h b/include/linux/if_fddi.h index 9947c39e62f..e6dc11e7f9a 100644 --- a/include/linux/if_fddi.h +++ b/include/linux/if_fddi.h | |||
@@ -67,7 +67,7 @@ struct fddi_8022_1_hdr { | |||
67 | __u8 dsap; /* destination service access point */ | 67 | __u8 dsap; /* destination service access point */ |
68 | __u8 ssap; /* source service access point */ | 68 | __u8 ssap; /* source service access point */ |
69 | __u8 ctrl; /* control byte #1 */ | 69 | __u8 ctrl; /* control byte #1 */ |
70 | } __packed; | 70 | } __attribute__((packed)); |
71 | 71 | ||
72 | /* Define 802.2 Type 2 header */ | 72 | /* Define 802.2 Type 2 header */ |
73 | struct fddi_8022_2_hdr { | 73 | struct fddi_8022_2_hdr { |
@@ -75,7 +75,7 @@ struct fddi_8022_2_hdr { | |||
75 | __u8 ssap; /* source service access point */ | 75 | __u8 ssap; /* source service access point */ |
76 | __u8 ctrl_1; /* control byte #1 */ | 76 | __u8 ctrl_1; /* control byte #1 */ |
77 | __u8 ctrl_2; /* control byte #2 */ | 77 | __u8 ctrl_2; /* control byte #2 */ |
78 | } __packed; | 78 | } __attribute__((packed)); |
79 | 79 | ||
80 | /* Define 802.2 SNAP header */ | 80 | /* Define 802.2 SNAP header */ |
81 | #define FDDI_K_OUI_LEN 3 | 81 | #define FDDI_K_OUI_LEN 3 |
@@ -85,7 +85,7 @@ struct fddi_snap_hdr { | |||
85 | __u8 ctrl; /* always 0x03 */ | 85 | __u8 ctrl; /* always 0x03 */ |
86 | __u8 oui[FDDI_K_OUI_LEN]; /* organizational universal id */ | 86 | __u8 oui[FDDI_K_OUI_LEN]; /* organizational universal id */ |
87 | __be16 ethertype; /* packet type ID field */ | 87 | __be16 ethertype; /* packet type ID field */ |
88 | } __packed; | 88 | } __attribute__((packed)); |
89 | 89 | ||
90 | /* Define FDDI LLC frame header */ | 90 | /* Define FDDI LLC frame header */ |
91 | struct fddihdr { | 91 | struct fddihdr { |
@@ -98,7 +98,7 @@ struct fddihdr { | |||
98 | struct fddi_8022_2_hdr llc_8022_2; | 98 | struct fddi_8022_2_hdr llc_8022_2; |
99 | struct fddi_snap_hdr llc_snap; | 99 | struct fddi_snap_hdr llc_snap; |
100 | } hdr; | 100 | } hdr; |
101 | } __packed; | 101 | } __attribute__((packed)); |
102 | 102 | ||
103 | #ifdef __KERNEL__ | 103 | #ifdef __KERNEL__ |
104 | #include <linux/netdevice.h> | 104 | #include <linux/netdevice.h> |
diff --git a/include/linux/if_hippi.h b/include/linux/if_hippi.h index 5fe5f307c6f..cdc049f1829 100644 --- a/include/linux/if_hippi.h +++ b/include/linux/if_hippi.h | |||
@@ -104,7 +104,7 @@ struct hippi_fp_hdr { | |||
104 | __be32 fixed; | 104 | __be32 fixed; |
105 | #endif | 105 | #endif |
106 | __be32 d2_size; | 106 | __be32 d2_size; |
107 | } __packed; | 107 | } __attribute__((packed)); |
108 | 108 | ||
109 | struct hippi_le_hdr { | 109 | struct hippi_le_hdr { |
110 | #if defined (__BIG_ENDIAN_BITFIELD) | 110 | #if defined (__BIG_ENDIAN_BITFIELD) |
@@ -129,7 +129,7 @@ struct hippi_le_hdr { | |||
129 | __u8 daddr[HIPPI_ALEN]; | 129 | __u8 daddr[HIPPI_ALEN]; |
130 | __u16 locally_administered; | 130 | __u16 locally_administered; |
131 | __u8 saddr[HIPPI_ALEN]; | 131 | __u8 saddr[HIPPI_ALEN]; |
132 | } __packed; | 132 | } __attribute__((packed)); |
133 | 133 | ||
134 | #define HIPPI_OUI_LEN 3 | 134 | #define HIPPI_OUI_LEN 3 |
135 | /* | 135 | /* |
@@ -142,12 +142,12 @@ struct hippi_snap_hdr { | |||
142 | __u8 ctrl; /* always 0x03 */ | 142 | __u8 ctrl; /* always 0x03 */ |
143 | __u8 oui[HIPPI_OUI_LEN]; /* organizational universal id (zero)*/ | 143 | __u8 oui[HIPPI_OUI_LEN]; /* organizational universal id (zero)*/ |
144 | __be16 ethertype; /* packet type ID field */ | 144 | __be16 ethertype; /* packet type ID field */ |
145 | } __packed; | 145 | } __attribute__((packed)); |
146 | 146 | ||
147 | struct hippi_hdr { | 147 | struct hippi_hdr { |
148 | struct hippi_fp_hdr fp; | 148 | struct hippi_fp_hdr fp; |
149 | struct hippi_le_hdr le; | 149 | struct hippi_le_hdr le; |
150 | struct hippi_snap_hdr snap; | 150 | struct hippi_snap_hdr snap; |
151 | } __packed; | 151 | } __attribute__((packed)); |
152 | 152 | ||
153 | #endif /* _LINUX_IF_HIPPI_H */ | 153 | #endif /* _LINUX_IF_HIPPI_H */ |
diff --git a/include/linux/if_pppox.h b/include/linux/if_pppox.h index 1925e0c3f16..27741e05446 100644 --- a/include/linux/if_pppox.h +++ b/include/linux/if_pppox.h | |||
@@ -59,7 +59,7 @@ struct sockaddr_pppox { | |||
59 | union{ | 59 | union{ |
60 | struct pppoe_addr pppoe; | 60 | struct pppoe_addr pppoe; |
61 | }sa_addr; | 61 | }sa_addr; |
62 | } __packed; | 62 | } __attribute__((packed)); |
63 | 63 | ||
64 | /* The use of the above union isn't viable because the size of this | 64 | /* The use of the above union isn't viable because the size of this |
65 | * struct must stay fixed over time -- applications use sizeof(struct | 65 | * struct must stay fixed over time -- applications use sizeof(struct |
@@ -70,7 +70,7 @@ struct sockaddr_pppol2tp { | |||
70 | sa_family_t sa_family; /* address family, AF_PPPOX */ | 70 | sa_family_t sa_family; /* address family, AF_PPPOX */ |
71 | unsigned int sa_protocol; /* protocol identifier */ | 71 | unsigned int sa_protocol; /* protocol identifier */ |
72 | struct pppol2tp_addr pppol2tp; | 72 | struct pppol2tp_addr pppol2tp; |
73 | } __packed; | 73 | } __attribute__((packed)); |
74 | 74 | ||
75 | /* The L2TPv3 protocol changes tunnel and session ids from 16 to 32 | 75 | /* The L2TPv3 protocol changes tunnel and session ids from 16 to 32 |
76 | * bits. So we need a different sockaddr structure. | 76 | * bits. So we need a different sockaddr structure. |
@@ -79,7 +79,7 @@ struct sockaddr_pppol2tpv3 { | |||
79 | sa_family_t sa_family; /* address family, AF_PPPOX */ | 79 | sa_family_t sa_family; /* address family, AF_PPPOX */ |
80 | unsigned int sa_protocol; /* protocol identifier */ | 80 | unsigned int sa_protocol; /* protocol identifier */ |
81 | struct pppol2tpv3_addr pppol2tp; | 81 | struct pppol2tpv3_addr pppol2tp; |
82 | } __packed; | 82 | } __attribute__((packed)); |
83 | 83 | ||
84 | /********************************************************************* | 84 | /********************************************************************* |
85 | * | 85 | * |
@@ -101,7 +101,7 @@ struct pppoe_tag { | |||
101 | __be16 tag_type; | 101 | __be16 tag_type; |
102 | __be16 tag_len; | 102 | __be16 tag_len; |
103 | char tag_data[0]; | 103 | char tag_data[0]; |
104 | } __attribute ((packed)); | 104 | } __attribute__ ((packed)); |
105 | 105 | ||
106 | /* Tag identifiers */ | 106 | /* Tag identifiers */ |
107 | #define PTT_EOL __cpu_to_be16(0x0000) | 107 | #define PTT_EOL __cpu_to_be16(0x0000) |
@@ -129,7 +129,7 @@ struct pppoe_hdr { | |||
129 | __be16 sid; | 129 | __be16 sid; |
130 | __be16 length; | 130 | __be16 length; |
131 | struct pppoe_tag tag[0]; | 131 | struct pppoe_tag tag[0]; |
132 | } __packed; | 132 | } __attribute__((packed)); |
133 | 133 | ||
134 | /* Length of entire PPPoE + PPP header */ | 134 | /* Length of entire PPPoE + PPP header */ |
135 | #define PPPOE_SES_HLEN 8 | 135 | #define PPPOE_SES_HLEN 8 |
diff --git a/include/linux/intel-gtt.h b/include/linux/intel-gtt.h new file mode 100644 index 00000000000..1d19ab2afa3 --- /dev/null +++ b/include/linux/intel-gtt.h | |||
@@ -0,0 +1,20 @@ | |||
1 | /* | ||
2 | * Common Intel AGPGART and GTT definitions. | ||
3 | */ | ||
4 | #ifndef _INTEL_GTT_H | ||
5 | #define _INTEL_GTT_H | ||
6 | |||
7 | #include <linux/agp_backend.h> | ||
8 | |||
9 | /* This is for Intel only GTT controls. | ||
10 | * | ||
11 | * Sandybridge: AGP_USER_CACHED_MEMORY default to LLC only | ||
12 | */ | ||
13 | |||
14 | #define AGP_USER_CACHED_MEMORY_LLC_MLC (AGP_USER_TYPES + 2) | ||
15 | #define AGP_USER_UNCACHED_MEMORY (AGP_USER_TYPES + 4) | ||
16 | |||
17 | /* flag for GFDT type */ | ||
18 | #define AGP_USER_CACHED_MEMORY_GFDT (1 << 3) | ||
19 | |||
20 | #endif | ||
diff --git a/include/linux/io-mapping.h b/include/linux/io-mapping.h index 0a6b3d5c490..7fb59279373 100644 --- a/include/linux/io-mapping.h +++ b/include/linux/io-mapping.h | |||
@@ -79,7 +79,7 @@ io_mapping_free(struct io_mapping *mapping) | |||
79 | } | 79 | } |
80 | 80 | ||
81 | /* Atomic map/unmap */ | 81 | /* Atomic map/unmap */ |
82 | static inline void * | 82 | static inline void __iomem * |
83 | io_mapping_map_atomic_wc(struct io_mapping *mapping, | 83 | io_mapping_map_atomic_wc(struct io_mapping *mapping, |
84 | unsigned long offset, | 84 | unsigned long offset, |
85 | int slot) | 85 | int slot) |
@@ -94,12 +94,12 @@ io_mapping_map_atomic_wc(struct io_mapping *mapping, | |||
94 | } | 94 | } |
95 | 95 | ||
96 | static inline void | 96 | static inline void |
97 | io_mapping_unmap_atomic(void *vaddr, int slot) | 97 | io_mapping_unmap_atomic(void __iomem *vaddr, int slot) |
98 | { | 98 | { |
99 | iounmap_atomic(vaddr, slot); | 99 | iounmap_atomic(vaddr, slot); |
100 | } | 100 | } |
101 | 101 | ||
102 | static inline void * | 102 | static inline void __iomem * |
103 | io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset) | 103 | io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset) |
104 | { | 104 | { |
105 | resource_size_t phys_addr; | 105 | resource_size_t phys_addr; |
@@ -111,7 +111,7 @@ io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset) | |||
111 | } | 111 | } |
112 | 112 | ||
113 | static inline void | 113 | static inline void |
114 | io_mapping_unmap(void *vaddr) | 114 | io_mapping_unmap(void __iomem *vaddr) |
115 | { | 115 | { |
116 | iounmap(vaddr); | 116 | iounmap(vaddr); |
117 | } | 117 | } |
@@ -125,38 +125,38 @@ struct io_mapping; | |||
125 | static inline struct io_mapping * | 125 | static inline struct io_mapping * |
126 | io_mapping_create_wc(resource_size_t base, unsigned long size) | 126 | io_mapping_create_wc(resource_size_t base, unsigned long size) |
127 | { | 127 | { |
128 | return (struct io_mapping *) ioremap_wc(base, size); | 128 | return (struct io_mapping __force *) ioremap_wc(base, size); |
129 | } | 129 | } |
130 | 130 | ||
131 | static inline void | 131 | static inline void |
132 | io_mapping_free(struct io_mapping *mapping) | 132 | io_mapping_free(struct io_mapping *mapping) |
133 | { | 133 | { |
134 | iounmap(mapping); | 134 | iounmap((void __force __iomem *) mapping); |
135 | } | 135 | } |
136 | 136 | ||
137 | /* Atomic map/unmap */ | 137 | /* Atomic map/unmap */ |
138 | static inline void * | 138 | static inline void __iomem * |
139 | io_mapping_map_atomic_wc(struct io_mapping *mapping, | 139 | io_mapping_map_atomic_wc(struct io_mapping *mapping, |
140 | unsigned long offset, | 140 | unsigned long offset, |
141 | int slot) | 141 | int slot) |
142 | { | 142 | { |
143 | return ((char *) mapping) + offset; | 143 | return ((char __force __iomem *) mapping) + offset; |
144 | } | 144 | } |
145 | 145 | ||
146 | static inline void | 146 | static inline void |
147 | io_mapping_unmap_atomic(void *vaddr, int slot) | 147 | io_mapping_unmap_atomic(void __iomem *vaddr, int slot) |
148 | { | 148 | { |
149 | } | 149 | } |
150 | 150 | ||
151 | /* Non-atomic map/unmap */ | 151 | /* Non-atomic map/unmap */ |
152 | static inline void * | 152 | static inline void __iomem * |
153 | io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset) | 153 | io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset) |
154 | { | 154 | { |
155 | return ((char *) mapping) + offset; | 155 | return ((char __force __iomem *) mapping) + offset; |
156 | } | 156 | } |
157 | 157 | ||
158 | static inline void | 158 | static inline void |
159 | io_mapping_unmap(void *vaddr) | 159 | io_mapping_unmap(void __iomem *vaddr) |
160 | { | 160 | { |
161 | } | 161 | } |
162 | 162 | ||
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index ab9e9e89e40..e62683ba88e 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h | |||
@@ -58,7 +58,7 @@ struct ipv6_opt_hdr { | |||
58 | /* | 58 | /* |
59 | * TLV encoded option data follows. | 59 | * TLV encoded option data follows. |
60 | */ | 60 | */ |
61 | } __packed; /* required for some archs */ | 61 | } __attribute__((packed)); /* required for some archs */ |
62 | 62 | ||
63 | #define ipv6_destopt_hdr ipv6_opt_hdr | 63 | #define ipv6_destopt_hdr ipv6_opt_hdr |
64 | #define ipv6_hopopt_hdr ipv6_opt_hdr | 64 | #define ipv6_hopopt_hdr ipv6_opt_hdr |
@@ -99,7 +99,7 @@ struct ipv6_destopt_hao { | |||
99 | __u8 type; | 99 | __u8 type; |
100 | __u8 length; | 100 | __u8 length; |
101 | struct in6_addr addr; | 101 | struct in6_addr addr; |
102 | } __packed; | 102 | } __attribute__((packed)); |
103 | 103 | ||
104 | /* | 104 | /* |
105 | * IPv6 fixed header | 105 | * IPv6 fixed header |
diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h index 4aa95f203f3..62dbee554f6 100644 --- a/include/linux/kfifo.h +++ b/include/linux/kfifo.h | |||
@@ -214,7 +214,7 @@ __kfifo_must_check_helper(unsigned int val) | |||
214 | */ | 214 | */ |
215 | #define kfifo_reset(fifo) \ | 215 | #define kfifo_reset(fifo) \ |
216 | (void)({ \ | 216 | (void)({ \ |
217 | typeof(fifo + 1) __tmp = (fifo); \ | 217 | typeof((fifo) + 1) __tmp = (fifo); \ |
218 | __tmp->kfifo.in = __tmp->kfifo.out = 0; \ | 218 | __tmp->kfifo.in = __tmp->kfifo.out = 0; \ |
219 | }) | 219 | }) |
220 | 220 | ||
@@ -228,7 +228,7 @@ __kfifo_must_check_helper(unsigned int val) | |||
228 | */ | 228 | */ |
229 | #define kfifo_reset_out(fifo) \ | 229 | #define kfifo_reset_out(fifo) \ |
230 | (void)({ \ | 230 | (void)({ \ |
231 | typeof(fifo + 1) __tmp = (fifo); \ | 231 | typeof((fifo) + 1) __tmp = (fifo); \ |
232 | __tmp->kfifo.out = __tmp->kfifo.in; \ | 232 | __tmp->kfifo.out = __tmp->kfifo.in; \ |
233 | }) | 233 | }) |
234 | 234 | ||
@@ -238,7 +238,7 @@ __kfifo_must_check_helper(unsigned int val) | |||
238 | */ | 238 | */ |
239 | #define kfifo_len(fifo) \ | 239 | #define kfifo_len(fifo) \ |
240 | ({ \ | 240 | ({ \ |
241 | typeof(fifo + 1) __tmpl = (fifo); \ | 241 | typeof((fifo) + 1) __tmpl = (fifo); \ |
242 | __tmpl->kfifo.in - __tmpl->kfifo.out; \ | 242 | __tmpl->kfifo.in - __tmpl->kfifo.out; \ |
243 | }) | 243 | }) |
244 | 244 | ||
@@ -248,7 +248,7 @@ __kfifo_must_check_helper(unsigned int val) | |||
248 | */ | 248 | */ |
249 | #define kfifo_is_empty(fifo) \ | 249 | #define kfifo_is_empty(fifo) \ |
250 | ({ \ | 250 | ({ \ |
251 | typeof(fifo + 1) __tmpq = (fifo); \ | 251 | typeof((fifo) + 1) __tmpq = (fifo); \ |
252 | __tmpq->kfifo.in == __tmpq->kfifo.out; \ | 252 | __tmpq->kfifo.in == __tmpq->kfifo.out; \ |
253 | }) | 253 | }) |
254 | 254 | ||
@@ -258,7 +258,7 @@ __kfifo_must_check_helper(unsigned int val) | |||
258 | */ | 258 | */ |
259 | #define kfifo_is_full(fifo) \ | 259 | #define kfifo_is_full(fifo) \ |
260 | ({ \ | 260 | ({ \ |
261 | typeof(fifo + 1) __tmpq = (fifo); \ | 261 | typeof((fifo) + 1) __tmpq = (fifo); \ |
262 | kfifo_len(__tmpq) > __tmpq->kfifo.mask; \ | 262 | kfifo_len(__tmpq) > __tmpq->kfifo.mask; \ |
263 | }) | 263 | }) |
264 | 264 | ||
@@ -269,7 +269,7 @@ __kfifo_must_check_helper(unsigned int val) | |||
269 | #define kfifo_avail(fifo) \ | 269 | #define kfifo_avail(fifo) \ |
270 | __kfifo_must_check_helper( \ | 270 | __kfifo_must_check_helper( \ |
271 | ({ \ | 271 | ({ \ |
272 | typeof(fifo + 1) __tmpq = (fifo); \ | 272 | typeof((fifo) + 1) __tmpq = (fifo); \ |
273 | const size_t __recsize = sizeof(*__tmpq->rectype); \ | 273 | const size_t __recsize = sizeof(*__tmpq->rectype); \ |
274 | unsigned int __avail = kfifo_size(__tmpq) - kfifo_len(__tmpq); \ | 274 | unsigned int __avail = kfifo_size(__tmpq) - kfifo_len(__tmpq); \ |
275 | (__recsize) ? ((__avail <= __recsize) ? 0 : \ | 275 | (__recsize) ? ((__avail <= __recsize) ? 0 : \ |
@@ -284,7 +284,7 @@ __kfifo_must_check_helper( \ | |||
284 | */ | 284 | */ |
285 | #define kfifo_skip(fifo) \ | 285 | #define kfifo_skip(fifo) \ |
286 | (void)({ \ | 286 | (void)({ \ |
287 | typeof(fifo + 1) __tmp = (fifo); \ | 287 | typeof((fifo) + 1) __tmp = (fifo); \ |
288 | const size_t __recsize = sizeof(*__tmp->rectype); \ | 288 | const size_t __recsize = sizeof(*__tmp->rectype); \ |
289 | struct __kfifo *__kfifo = &__tmp->kfifo; \ | 289 | struct __kfifo *__kfifo = &__tmp->kfifo; \ |
290 | if (__recsize) \ | 290 | if (__recsize) \ |
@@ -302,7 +302,7 @@ __kfifo_must_check_helper( \ | |||
302 | #define kfifo_peek_len(fifo) \ | 302 | #define kfifo_peek_len(fifo) \ |
303 | __kfifo_must_check_helper( \ | 303 | __kfifo_must_check_helper( \ |
304 | ({ \ | 304 | ({ \ |
305 | typeof(fifo + 1) __tmp = (fifo); \ | 305 | typeof((fifo) + 1) __tmp = (fifo); \ |
306 | const size_t __recsize = sizeof(*__tmp->rectype); \ | 306 | const size_t __recsize = sizeof(*__tmp->rectype); \ |
307 | struct __kfifo *__kfifo = &__tmp->kfifo; \ | 307 | struct __kfifo *__kfifo = &__tmp->kfifo; \ |
308 | (!__recsize) ? kfifo_len(__tmp) * sizeof(*__tmp->type) : \ | 308 | (!__recsize) ? kfifo_len(__tmp) * sizeof(*__tmp->type) : \ |
@@ -325,7 +325,7 @@ __kfifo_must_check_helper( \ | |||
325 | #define kfifo_alloc(fifo, size, gfp_mask) \ | 325 | #define kfifo_alloc(fifo, size, gfp_mask) \ |
326 | __kfifo_must_check_helper( \ | 326 | __kfifo_must_check_helper( \ |
327 | ({ \ | 327 | ({ \ |
328 | typeof(fifo + 1) __tmp = (fifo); \ | 328 | typeof((fifo) + 1) __tmp = (fifo); \ |
329 | struct __kfifo *__kfifo = &__tmp->kfifo; \ | 329 | struct __kfifo *__kfifo = &__tmp->kfifo; \ |
330 | __is_kfifo_ptr(__tmp) ? \ | 330 | __is_kfifo_ptr(__tmp) ? \ |
331 | __kfifo_alloc(__kfifo, size, sizeof(*__tmp->type), gfp_mask) : \ | 331 | __kfifo_alloc(__kfifo, size, sizeof(*__tmp->type), gfp_mask) : \ |
@@ -339,7 +339,7 @@ __kfifo_must_check_helper( \ | |||
339 | */ | 339 | */ |
340 | #define kfifo_free(fifo) \ | 340 | #define kfifo_free(fifo) \ |
341 | ({ \ | 341 | ({ \ |
342 | typeof(fifo + 1) __tmp = (fifo); \ | 342 | typeof((fifo) + 1) __tmp = (fifo); \ |
343 | struct __kfifo *__kfifo = &__tmp->kfifo; \ | 343 | struct __kfifo *__kfifo = &__tmp->kfifo; \ |
344 | if (__is_kfifo_ptr(__tmp)) \ | 344 | if (__is_kfifo_ptr(__tmp)) \ |
345 | __kfifo_free(__kfifo); \ | 345 | __kfifo_free(__kfifo); \ |
@@ -358,7 +358,7 @@ __kfifo_must_check_helper( \ | |||
358 | */ | 358 | */ |
359 | #define kfifo_init(fifo, buffer, size) \ | 359 | #define kfifo_init(fifo, buffer, size) \ |
360 | ({ \ | 360 | ({ \ |
361 | typeof(fifo + 1) __tmp = (fifo); \ | 361 | typeof((fifo) + 1) __tmp = (fifo); \ |
362 | struct __kfifo *__kfifo = &__tmp->kfifo; \ | 362 | struct __kfifo *__kfifo = &__tmp->kfifo; \ |
363 | __is_kfifo_ptr(__tmp) ? \ | 363 | __is_kfifo_ptr(__tmp) ? \ |
364 | __kfifo_init(__kfifo, buffer, size, sizeof(*__tmp->type)) : \ | 364 | __kfifo_init(__kfifo, buffer, size, sizeof(*__tmp->type)) : \ |
@@ -379,8 +379,8 @@ __kfifo_must_check_helper( \ | |||
379 | */ | 379 | */ |
380 | #define kfifo_put(fifo, val) \ | 380 | #define kfifo_put(fifo, val) \ |
381 | ({ \ | 381 | ({ \ |
382 | typeof(fifo + 1) __tmp = (fifo); \ | 382 | typeof((fifo) + 1) __tmp = (fifo); \ |
383 | typeof(val + 1) __val = (val); \ | 383 | typeof((val) + 1) __val = (val); \ |
384 | unsigned int __ret; \ | 384 | unsigned int __ret; \ |
385 | const size_t __recsize = sizeof(*__tmp->rectype); \ | 385 | const size_t __recsize = sizeof(*__tmp->rectype); \ |
386 | struct __kfifo *__kfifo = &__tmp->kfifo; \ | 386 | struct __kfifo *__kfifo = &__tmp->kfifo; \ |
@@ -421,8 +421,8 @@ __kfifo_must_check_helper( \ | |||
421 | #define kfifo_get(fifo, val) \ | 421 | #define kfifo_get(fifo, val) \ |
422 | __kfifo_must_check_helper( \ | 422 | __kfifo_must_check_helper( \ |
423 | ({ \ | 423 | ({ \ |
424 | typeof(fifo + 1) __tmp = (fifo); \ | 424 | typeof((fifo) + 1) __tmp = (fifo); \ |
425 | typeof(val + 1) __val = (val); \ | 425 | typeof((val) + 1) __val = (val); \ |
426 | unsigned int __ret; \ | 426 | unsigned int __ret; \ |
427 | const size_t __recsize = sizeof(*__tmp->rectype); \ | 427 | const size_t __recsize = sizeof(*__tmp->rectype); \ |
428 | struct __kfifo *__kfifo = &__tmp->kfifo; \ | 428 | struct __kfifo *__kfifo = &__tmp->kfifo; \ |
@@ -462,8 +462,8 @@ __kfifo_must_check_helper( \ | |||
462 | #define kfifo_peek(fifo, val) \ | 462 | #define kfifo_peek(fifo, val) \ |
463 | __kfifo_must_check_helper( \ | 463 | __kfifo_must_check_helper( \ |
464 | ({ \ | 464 | ({ \ |
465 | typeof(fifo + 1) __tmp = (fifo); \ | 465 | typeof((fifo) + 1) __tmp = (fifo); \ |
466 | typeof(val + 1) __val = (val); \ | 466 | typeof((val) + 1) __val = (val); \ |
467 | unsigned int __ret; \ | 467 | unsigned int __ret; \ |
468 | const size_t __recsize = sizeof(*__tmp->rectype); \ | 468 | const size_t __recsize = sizeof(*__tmp->rectype); \ |
469 | struct __kfifo *__kfifo = &__tmp->kfifo; \ | 469 | struct __kfifo *__kfifo = &__tmp->kfifo; \ |
@@ -501,8 +501,8 @@ __kfifo_must_check_helper( \ | |||
501 | */ | 501 | */ |
502 | #define kfifo_in(fifo, buf, n) \ | 502 | #define kfifo_in(fifo, buf, n) \ |
503 | ({ \ | 503 | ({ \ |
504 | typeof(fifo + 1) __tmp = (fifo); \ | 504 | typeof((fifo) + 1) __tmp = (fifo); \ |
505 | typeof(buf + 1) __buf = (buf); \ | 505 | typeof((buf) + 1) __buf = (buf); \ |
506 | unsigned long __n = (n); \ | 506 | unsigned long __n = (n); \ |
507 | const size_t __recsize = sizeof(*__tmp->rectype); \ | 507 | const size_t __recsize = sizeof(*__tmp->rectype); \ |
508 | struct __kfifo *__kfifo = &__tmp->kfifo; \ | 508 | struct __kfifo *__kfifo = &__tmp->kfifo; \ |
@@ -554,8 +554,8 @@ __kfifo_must_check_helper( \ | |||
554 | #define kfifo_out(fifo, buf, n) \ | 554 | #define kfifo_out(fifo, buf, n) \ |
555 | __kfifo_must_check_helper( \ | 555 | __kfifo_must_check_helper( \ |
556 | ({ \ | 556 | ({ \ |
557 | typeof(fifo + 1) __tmp = (fifo); \ | 557 | typeof((fifo) + 1) __tmp = (fifo); \ |
558 | typeof(buf + 1) __buf = (buf); \ | 558 | typeof((buf) + 1) __buf = (buf); \ |
559 | unsigned long __n = (n); \ | 559 | unsigned long __n = (n); \ |
560 | const size_t __recsize = sizeof(*__tmp->rectype); \ | 560 | const size_t __recsize = sizeof(*__tmp->rectype); \ |
561 | struct __kfifo *__kfifo = &__tmp->kfifo; \ | 561 | struct __kfifo *__kfifo = &__tmp->kfifo; \ |
@@ -611,7 +611,7 @@ __kfifo_must_check_helper( \ | |||
611 | #define kfifo_from_user(fifo, from, len, copied) \ | 611 | #define kfifo_from_user(fifo, from, len, copied) \ |
612 | __kfifo_must_check_helper( \ | 612 | __kfifo_must_check_helper( \ |
613 | ({ \ | 613 | ({ \ |
614 | typeof(fifo + 1) __tmp = (fifo); \ | 614 | typeof((fifo) + 1) __tmp = (fifo); \ |
615 | const void __user *__from = (from); \ | 615 | const void __user *__from = (from); \ |
616 | unsigned int __len = (len); \ | 616 | unsigned int __len = (len); \ |
617 | unsigned int *__copied = (copied); \ | 617 | unsigned int *__copied = (copied); \ |
@@ -639,7 +639,7 @@ __kfifo_must_check_helper( \ | |||
639 | #define kfifo_to_user(fifo, to, len, copied) \ | 639 | #define kfifo_to_user(fifo, to, len, copied) \ |
640 | __kfifo_must_check_helper( \ | 640 | __kfifo_must_check_helper( \ |
641 | ({ \ | 641 | ({ \ |
642 | typeof(fifo + 1) __tmp = (fifo); \ | 642 | typeof((fifo) + 1) __tmp = (fifo); \ |
643 | void __user *__to = (to); \ | 643 | void __user *__to = (to); \ |
644 | unsigned int __len = (len); \ | 644 | unsigned int __len = (len); \ |
645 | unsigned int *__copied = (copied); \ | 645 | unsigned int *__copied = (copied); \ |
@@ -666,7 +666,7 @@ __kfifo_must_check_helper( \ | |||
666 | */ | 666 | */ |
667 | #define kfifo_dma_in_prepare(fifo, sgl, nents, len) \ | 667 | #define kfifo_dma_in_prepare(fifo, sgl, nents, len) \ |
668 | ({ \ | 668 | ({ \ |
669 | typeof(fifo + 1) __tmp = (fifo); \ | 669 | typeof((fifo) + 1) __tmp = (fifo); \ |
670 | struct scatterlist *__sgl = (sgl); \ | 670 | struct scatterlist *__sgl = (sgl); \ |
671 | int __nents = (nents); \ | 671 | int __nents = (nents); \ |
672 | unsigned int __len = (len); \ | 672 | unsigned int __len = (len); \ |
@@ -690,7 +690,7 @@ __kfifo_must_check_helper( \ | |||
690 | */ | 690 | */ |
691 | #define kfifo_dma_in_finish(fifo, len) \ | 691 | #define kfifo_dma_in_finish(fifo, len) \ |
692 | (void)({ \ | 692 | (void)({ \ |
693 | typeof(fifo + 1) __tmp = (fifo); \ | 693 | typeof((fifo) + 1) __tmp = (fifo); \ |
694 | unsigned int __len = (len); \ | 694 | unsigned int __len = (len); \ |
695 | const size_t __recsize = sizeof(*__tmp->rectype); \ | 695 | const size_t __recsize = sizeof(*__tmp->rectype); \ |
696 | struct __kfifo *__kfifo = &__tmp->kfifo; \ | 696 | struct __kfifo *__kfifo = &__tmp->kfifo; \ |
@@ -717,7 +717,7 @@ __kfifo_must_check_helper( \ | |||
717 | */ | 717 | */ |
718 | #define kfifo_dma_out_prepare(fifo, sgl, nents, len) \ | 718 | #define kfifo_dma_out_prepare(fifo, sgl, nents, len) \ |
719 | ({ \ | 719 | ({ \ |
720 | typeof(fifo + 1) __tmp = (fifo); \ | 720 | typeof((fifo) + 1) __tmp = (fifo); \ |
721 | struct scatterlist *__sgl = (sgl); \ | 721 | struct scatterlist *__sgl = (sgl); \ |
722 | int __nents = (nents); \ | 722 | int __nents = (nents); \ |
723 | unsigned int __len = (len); \ | 723 | unsigned int __len = (len); \ |
@@ -741,7 +741,7 @@ __kfifo_must_check_helper( \ | |||
741 | */ | 741 | */ |
742 | #define kfifo_dma_out_finish(fifo, len) \ | 742 | #define kfifo_dma_out_finish(fifo, len) \ |
743 | (void)({ \ | 743 | (void)({ \ |
744 | typeof(fifo + 1) __tmp = (fifo); \ | 744 | typeof((fifo) + 1) __tmp = (fifo); \ |
745 | unsigned int __len = (len); \ | 745 | unsigned int __len = (len); \ |
746 | const size_t __recsize = sizeof(*__tmp->rectype); \ | 746 | const size_t __recsize = sizeof(*__tmp->rectype); \ |
747 | struct __kfifo *__kfifo = &__tmp->kfifo; \ | 747 | struct __kfifo *__kfifo = &__tmp->kfifo; \ |
@@ -766,8 +766,8 @@ __kfifo_must_check_helper( \ | |||
766 | #define kfifo_out_peek(fifo, buf, n) \ | 766 | #define kfifo_out_peek(fifo, buf, n) \ |
767 | __kfifo_must_check_helper( \ | 767 | __kfifo_must_check_helper( \ |
768 | ({ \ | 768 | ({ \ |
769 | typeof(fifo + 1) __tmp = (fifo); \ | 769 | typeof((fifo) + 1) __tmp = (fifo); \ |
770 | typeof(buf + 1) __buf = (buf); \ | 770 | typeof((buf) + 1) __buf = (buf); \ |
771 | unsigned long __n = (n); \ | 771 | unsigned long __n = (n); \ |
772 | const size_t __recsize = sizeof(*__tmp->rectype); \ | 772 | const size_t __recsize = sizeof(*__tmp->rectype); \ |
773 | struct __kfifo *__kfifo = &__tmp->kfifo; \ | 773 | struct __kfifo *__kfifo = &__tmp->kfifo; \ |
diff --git a/include/linux/kobject.h b/include/linux/kobject.h index cf343a85253..7950a37a714 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/compiler.h> | 22 | #include <linux/compiler.h> |
23 | #include <linux/spinlock.h> | 23 | #include <linux/spinlock.h> |
24 | #include <linux/kref.h> | 24 | #include <linux/kref.h> |
25 | #include <linux/kobject_ns.h> | ||
25 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
26 | #include <linux/wait.h> | 27 | #include <linux/wait.h> |
27 | #include <asm/atomic.h> | 28 | #include <asm/atomic.h> |
@@ -136,42 +137,8 @@ struct kobj_attribute { | |||
136 | 137 | ||
137 | extern const struct sysfs_ops kobj_sysfs_ops; | 138 | extern const struct sysfs_ops kobj_sysfs_ops; |
138 | 139 | ||
139 | /* | ||
140 | * Namespace types which are used to tag kobjects and sysfs entries. | ||
141 | * Network namespace will likely be the first. | ||
142 | */ | ||
143 | enum kobj_ns_type { | ||
144 | KOBJ_NS_TYPE_NONE = 0, | ||
145 | KOBJ_NS_TYPE_NET, | ||
146 | KOBJ_NS_TYPES | ||
147 | }; | ||
148 | |||
149 | struct sock; | 140 | struct sock; |
150 | 141 | ||
151 | /* | ||
152 | * Callbacks so sysfs can determine namespaces | ||
153 | * @current_ns: return calling task's namespace | ||
154 | * @netlink_ns: return namespace to which a sock belongs (right?) | ||
155 | * @initial_ns: return the initial namespace (i.e. init_net_ns) | ||
156 | */ | ||
157 | struct kobj_ns_type_operations { | ||
158 | enum kobj_ns_type type; | ||
159 | const void *(*current_ns)(void); | ||
160 | const void *(*netlink_ns)(struct sock *sk); | ||
161 | const void *(*initial_ns)(void); | ||
162 | }; | ||
163 | |||
164 | int kobj_ns_type_register(const struct kobj_ns_type_operations *ops); | ||
165 | int kobj_ns_type_registered(enum kobj_ns_type type); | ||
166 | const struct kobj_ns_type_operations *kobj_child_ns_ops(struct kobject *parent); | ||
167 | const struct kobj_ns_type_operations *kobj_ns_ops(struct kobject *kobj); | ||
168 | |||
169 | const void *kobj_ns_current(enum kobj_ns_type type); | ||
170 | const void *kobj_ns_netlink(enum kobj_ns_type type, struct sock *sk); | ||
171 | const void *kobj_ns_initial(enum kobj_ns_type type); | ||
172 | void kobj_ns_exit(enum kobj_ns_type type, const void *ns); | ||
173 | |||
174 | |||
175 | /** | 142 | /** |
176 | * struct kset - a set of kobjects of a specific type, belonging to a specific subsystem. | 143 | * struct kset - a set of kobjects of a specific type, belonging to a specific subsystem. |
177 | * | 144 | * |
diff --git a/include/linux/kobject_ns.h b/include/linux/kobject_ns.h new file mode 100644 index 00000000000..82cb5bf461f --- /dev/null +++ b/include/linux/kobject_ns.h | |||
@@ -0,0 +1,56 @@ | |||
1 | /* Kernel object name space definitions | ||
2 | * | ||
3 | * Copyright (c) 2002-2003 Patrick Mochel | ||
4 | * Copyright (c) 2002-2003 Open Source Development Labs | ||
5 | * Copyright (c) 2006-2008 Greg Kroah-Hartman <greg@kroah.com> | ||
6 | * Copyright (c) 2006-2008 Novell Inc. | ||
7 | * | ||
8 | * Split from kobject.h by David Howells (dhowells@redhat.com) | ||
9 | * | ||
10 | * This file is released under the GPLv2. | ||
11 | * | ||
12 | * Please read Documentation/kobject.txt before using the kobject | ||
13 | * interface, ESPECIALLY the parts about reference counts and object | ||
14 | * destructors. | ||
15 | */ | ||
16 | |||
17 | #ifndef _LINUX_KOBJECT_NS_H | ||
18 | #define _LINUX_KOBJECT_NS_H | ||
19 | |||
20 | struct sock; | ||
21 | struct kobject; | ||
22 | |||
23 | /* | ||
24 | * Namespace types which are used to tag kobjects and sysfs entries. | ||
25 | * Network namespace will likely be the first. | ||
26 | */ | ||
27 | enum kobj_ns_type { | ||
28 | KOBJ_NS_TYPE_NONE = 0, | ||
29 | KOBJ_NS_TYPE_NET, | ||
30 | KOBJ_NS_TYPES | ||
31 | }; | ||
32 | |||
33 | /* | ||
34 | * Callbacks so sysfs can determine namespaces | ||
35 | * @current_ns: return calling task's namespace | ||
36 | * @netlink_ns: return namespace to which a sock belongs (right?) | ||
37 | * @initial_ns: return the initial namespace (i.e. init_net_ns) | ||
38 | */ | ||
39 | struct kobj_ns_type_operations { | ||
40 | enum kobj_ns_type type; | ||
41 | const void *(*current_ns)(void); | ||
42 | const void *(*netlink_ns)(struct sock *sk); | ||
43 | const void *(*initial_ns)(void); | ||
44 | }; | ||
45 | |||
46 | int kobj_ns_type_register(const struct kobj_ns_type_operations *ops); | ||
47 | int kobj_ns_type_registered(enum kobj_ns_type type); | ||
48 | const struct kobj_ns_type_operations *kobj_child_ns_ops(struct kobject *parent); | ||
49 | const struct kobj_ns_type_operations *kobj_ns_ops(struct kobject *kobj); | ||
50 | |||
51 | const void *kobj_ns_current(enum kobj_ns_type type); | ||
52 | const void *kobj_ns_netlink(enum kobj_ns_type type, struct sock *sk); | ||
53 | const void *kobj_ns_initial(enum kobj_ns_type type); | ||
54 | void kobj_ns_exit(enum kobj_ns_type type, const void *ns); | ||
55 | |||
56 | #endif /* _LINUX_KOBJECT_NS_H */ | ||
diff --git a/include/linux/ksm.h b/include/linux/ksm.h index 74d691ee912..3319a696762 100644 --- a/include/linux/ksm.h +++ b/include/linux/ksm.h | |||
@@ -16,6 +16,9 @@ | |||
16 | struct stable_node; | 16 | struct stable_node; |
17 | struct mem_cgroup; | 17 | struct mem_cgroup; |
18 | 18 | ||
19 | struct page *ksm_does_need_to_copy(struct page *page, | ||
20 | struct vm_area_struct *vma, unsigned long address); | ||
21 | |||
19 | #ifdef CONFIG_KSM | 22 | #ifdef CONFIG_KSM |
20 | int ksm_madvise(struct vm_area_struct *vma, unsigned long start, | 23 | int ksm_madvise(struct vm_area_struct *vma, unsigned long start, |
21 | unsigned long end, int advice, unsigned long *vm_flags); | 24 | unsigned long end, int advice, unsigned long *vm_flags); |
@@ -70,19 +73,14 @@ static inline void set_page_stable_node(struct page *page, | |||
70 | * We'd like to make this conditional on vma->vm_flags & VM_MERGEABLE, | 73 | * We'd like to make this conditional on vma->vm_flags & VM_MERGEABLE, |
71 | * but what if the vma was unmerged while the page was swapped out? | 74 | * but what if the vma was unmerged while the page was swapped out? |
72 | */ | 75 | */ |
73 | struct page *ksm_does_need_to_copy(struct page *page, | 76 | static inline int ksm_might_need_to_copy(struct page *page, |
74 | struct vm_area_struct *vma, unsigned long address); | ||
75 | static inline struct page *ksm_might_need_to_copy(struct page *page, | ||
76 | struct vm_area_struct *vma, unsigned long address) | 77 | struct vm_area_struct *vma, unsigned long address) |
77 | { | 78 | { |
78 | struct anon_vma *anon_vma = page_anon_vma(page); | 79 | struct anon_vma *anon_vma = page_anon_vma(page); |
79 | 80 | ||
80 | if (!anon_vma || | 81 | return anon_vma && |
81 | (anon_vma->root == vma->anon_vma->root && | 82 | (anon_vma->root != vma->anon_vma->root || |
82 | page->index == linear_page_index(vma, address))) | 83 | page->index != linear_page_index(vma, address)); |
83 | return page; | ||
84 | |||
85 | return ksm_does_need_to_copy(page, vma, address); | ||
86 | } | 84 | } |
87 | 85 | ||
88 | int page_referenced_ksm(struct page *page, | 86 | int page_referenced_ksm(struct page *page, |
@@ -115,10 +113,10 @@ static inline int ksm_madvise(struct vm_area_struct *vma, unsigned long start, | |||
115 | return 0; | 113 | return 0; |
116 | } | 114 | } |
117 | 115 | ||
118 | static inline struct page *ksm_might_need_to_copy(struct page *page, | 116 | static inline int ksm_might_need_to_copy(struct page *page, |
119 | struct vm_area_struct *vma, unsigned long address) | 117 | struct vm_area_struct *vma, unsigned long address) |
120 | { | 118 | { |
121 | return page; | 119 | return 0; |
122 | } | 120 | } |
123 | 121 | ||
124 | static inline int page_referenced_ksm(struct page *page, | 122 | static inline int page_referenced_ksm(struct page *page, |
diff --git a/include/linux/lglock.h b/include/linux/lglock.h index b288cb713b9..f549056fb20 100644 --- a/include/linux/lglock.h +++ b/include/linux/lglock.h | |||
@@ -150,7 +150,7 @@ | |||
150 | int i; \ | 150 | int i; \ |
151 | preempt_disable(); \ | 151 | preempt_disable(); \ |
152 | rwlock_acquire(&name##_lock_dep_map, 0, 0, _RET_IP_); \ | 152 | rwlock_acquire(&name##_lock_dep_map, 0, 0, _RET_IP_); \ |
153 | for_each_online_cpu(i) { \ | 153 | for_each_possible_cpu(i) { \ |
154 | arch_spinlock_t *lock; \ | 154 | arch_spinlock_t *lock; \ |
155 | lock = &per_cpu(name##_lock, i); \ | 155 | lock = &per_cpu(name##_lock, i); \ |
156 | arch_spin_lock(lock); \ | 156 | arch_spin_lock(lock); \ |
@@ -161,7 +161,7 @@ | |||
161 | void name##_global_unlock(void) { \ | 161 | void name##_global_unlock(void) { \ |
162 | int i; \ | 162 | int i; \ |
163 | rwlock_release(&name##_lock_dep_map, 1, _RET_IP_); \ | 163 | rwlock_release(&name##_lock_dep_map, 1, _RET_IP_); \ |
164 | for_each_online_cpu(i) { \ | 164 | for_each_possible_cpu(i) { \ |
165 | arch_spinlock_t *lock; \ | 165 | arch_spinlock_t *lock; \ |
166 | lock = &per_cpu(name##_lock, i); \ | 166 | lock = &per_cpu(name##_lock, i); \ |
167 | arch_spin_unlock(lock); \ | 167 | arch_spin_unlock(lock); \ |
diff --git a/include/linux/libata.h b/include/linux/libata.h index f010f18a0f8..45fb2967b66 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -335,6 +335,7 @@ enum { | |||
335 | ATA_EHI_HOTPLUGGED = (1 << 0), /* could have been hotplugged */ | 335 | ATA_EHI_HOTPLUGGED = (1 << 0), /* could have been hotplugged */ |
336 | ATA_EHI_NO_AUTOPSY = (1 << 2), /* no autopsy */ | 336 | ATA_EHI_NO_AUTOPSY = (1 << 2), /* no autopsy */ |
337 | ATA_EHI_QUIET = (1 << 3), /* be quiet */ | 337 | ATA_EHI_QUIET = (1 << 3), /* be quiet */ |
338 | ATA_EHI_NO_RECOVERY = (1 << 4), /* no recovery */ | ||
338 | 339 | ||
339 | ATA_EHI_DID_SOFTRESET = (1 << 16), /* already soft-reset this port */ | 340 | ATA_EHI_DID_SOFTRESET = (1 << 16), /* already soft-reset this port */ |
340 | ATA_EHI_DID_HARDRESET = (1 << 17), /* already soft-reset this port */ | 341 | ATA_EHI_DID_HARDRESET = (1 << 17), /* already soft-reset this port */ |
@@ -723,6 +724,7 @@ struct ata_port { | |||
723 | struct ata_ioports ioaddr; /* ATA cmd/ctl/dma register blocks */ | 724 | struct ata_ioports ioaddr; /* ATA cmd/ctl/dma register blocks */ |
724 | u8 ctl; /* cache of ATA control register */ | 725 | u8 ctl; /* cache of ATA control register */ |
725 | u8 last_ctl; /* Cache last written value */ | 726 | u8 last_ctl; /* Cache last written value */ |
727 | struct ata_link* sff_pio_task_link; /* link currently used */ | ||
726 | struct delayed_work sff_pio_task; | 728 | struct delayed_work sff_pio_task; |
727 | #ifdef CONFIG_ATA_BMDMA | 729 | #ifdef CONFIG_ATA_BMDMA |
728 | struct ata_bmdma_prd *bmdma_prd; /* BMDMA SG list */ | 730 | struct ata_bmdma_prd *bmdma_prd; /* BMDMA SG list */ |
@@ -1594,7 +1596,7 @@ extern void ata_sff_irq_on(struct ata_port *ap); | |||
1594 | extern void ata_sff_irq_clear(struct ata_port *ap); | 1596 | extern void ata_sff_irq_clear(struct ata_port *ap); |
1595 | extern int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc, | 1597 | extern int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc, |
1596 | u8 status, int in_wq); | 1598 | u8 status, int in_wq); |
1597 | extern void ata_sff_queue_pio_task(struct ata_port *ap, unsigned long delay); | 1599 | extern void ata_sff_queue_pio_task(struct ata_link *link, unsigned long delay); |
1598 | extern unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc); | 1600 | extern unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc); |
1599 | extern bool ata_sff_qc_fill_rtf(struct ata_queued_cmd *qc); | 1601 | extern bool ata_sff_qc_fill_rtf(struct ata_queued_cmd *qc); |
1600 | extern unsigned int ata_sff_port_intr(struct ata_port *ap, | 1602 | extern unsigned int ata_sff_port_intr(struct ata_port *ap, |
diff --git a/include/linux/miscdevice.h b/include/linux/miscdevice.h index bafffc73790..18fd13028ba 100644 --- a/include/linux/miscdevice.h +++ b/include/linux/miscdevice.h | |||
@@ -33,6 +33,7 @@ | |||
33 | #define MWAVE_MINOR 219 /* ACP/Mwave Modem */ | 33 | #define MWAVE_MINOR 219 /* ACP/Mwave Modem */ |
34 | #define MPT_MINOR 220 | 34 | #define MPT_MINOR 220 |
35 | #define MPT2SAS_MINOR 221 | 35 | #define MPT2SAS_MINOR 221 |
36 | #define UINPUT_MINOR 223 | ||
36 | #define HPET_MINOR 228 | 37 | #define HPET_MINOR 228 |
37 | #define FUSE_MINOR 229 | 38 | #define FUSE_MINOR 229 |
38 | #define KVM_MINOR 232 | 39 | #define KVM_MINOR 232 |
diff --git a/include/linux/mm.h b/include/linux/mm.h index 709f6728fc9..74949fbef8c 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -78,7 +78,11 @@ extern unsigned int kobjsize(const void *objp); | |||
78 | #define VM_MAYSHARE 0x00000080 | 78 | #define VM_MAYSHARE 0x00000080 |
79 | 79 | ||
80 | #define VM_GROWSDOWN 0x00000100 /* general info on the segment */ | 80 | #define VM_GROWSDOWN 0x00000100 /* general info on the segment */ |
81 | #if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64) | ||
81 | #define VM_GROWSUP 0x00000200 | 82 | #define VM_GROWSUP 0x00000200 |
83 | #else | ||
84 | #define VM_GROWSUP 0x00000000 | ||
85 | #endif | ||
82 | #define VM_PFNMAP 0x00000400 /* Page-ranges managed without "struct page", just pure PFN */ | 86 | #define VM_PFNMAP 0x00000400 /* Page-ranges managed without "struct page", just pure PFN */ |
83 | #define VM_DENYWRITE 0x00000800 /* ETXTBSY on write attempts.. */ | 87 | #define VM_DENYWRITE 0x00000800 /* ETXTBSY on write attempts.. */ |
84 | 88 | ||
@@ -860,6 +864,12 @@ int set_page_dirty(struct page *page); | |||
860 | int set_page_dirty_lock(struct page *page); | 864 | int set_page_dirty_lock(struct page *page); |
861 | int clear_page_dirty_for_io(struct page *page); | 865 | int clear_page_dirty_for_io(struct page *page); |
862 | 866 | ||
867 | /* Is the vma a continuation of the stack vma above it? */ | ||
868 | static inline int vma_stack_continue(struct vm_area_struct *vma, unsigned long addr) | ||
869 | { | ||
870 | return vma && (vma->vm_end == addr) && (vma->vm_flags & VM_GROWSDOWN); | ||
871 | } | ||
872 | |||
863 | extern unsigned long move_page_tables(struct vm_area_struct *vma, | 873 | extern unsigned long move_page_tables(struct vm_area_struct *vma, |
864 | unsigned long old_addr, struct vm_area_struct *new_vma, | 874 | unsigned long old_addr, struct vm_area_struct *new_vma, |
865 | unsigned long new_addr, unsigned long len); | 875 | unsigned long new_addr, unsigned long len); |
@@ -1330,8 +1340,10 @@ unsigned long ra_submit(struct file_ra_state *ra, | |||
1330 | 1340 | ||
1331 | /* Do stack extension */ | 1341 | /* Do stack extension */ |
1332 | extern int expand_stack(struct vm_area_struct *vma, unsigned long address); | 1342 | extern int expand_stack(struct vm_area_struct *vma, unsigned long address); |
1333 | #ifdef CONFIG_IA64 | 1343 | #if VM_GROWSUP |
1334 | extern int expand_upwards(struct vm_area_struct *vma, unsigned long address); | 1344 | extern int expand_upwards(struct vm_area_struct *vma, unsigned long address); |
1345 | #else | ||
1346 | #define expand_upwards(vma, address) do { } while (0) | ||
1335 | #endif | 1347 | #endif |
1336 | extern int expand_stack_downwards(struct vm_area_struct *vma, | 1348 | extern int expand_stack_downwards(struct vm_area_struct *vma, |
1337 | unsigned long address); | 1349 | unsigned long address); |
@@ -1357,7 +1369,15 @@ static inline unsigned long vma_pages(struct vm_area_struct *vma) | |||
1357 | return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; | 1369 | return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; |
1358 | } | 1370 | } |
1359 | 1371 | ||
1372 | #ifdef CONFIG_MMU | ||
1360 | pgprot_t vm_get_page_prot(unsigned long vm_flags); | 1373 | pgprot_t vm_get_page_prot(unsigned long vm_flags); |
1374 | #else | ||
1375 | static inline pgprot_t vm_get_page_prot(unsigned long vm_flags) | ||
1376 | { | ||
1377 | return __pgprot(0); | ||
1378 | } | ||
1379 | #endif | ||
1380 | |||
1361 | struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr); | 1381 | struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr); |
1362 | int remap_pfn_range(struct vm_area_struct *, unsigned long addr, | 1382 | int remap_pfn_range(struct vm_area_struct *, unsigned long addr, |
1363 | unsigned long pfn, unsigned long size, pgprot_t); | 1383 | unsigned long pfn, unsigned long size, pgprot_t); |
diff --git a/include/linux/mmc/sdio.h b/include/linux/mmc/sdio.h index 329a8faa6e3..245cdacee54 100644 --- a/include/linux/mmc/sdio.h +++ b/include/linux/mmc/sdio.h | |||
@@ -38,6 +38,8 @@ | |||
38 | * [8:0] Byte/block count | 38 | * [8:0] Byte/block count |
39 | */ | 39 | */ |
40 | 40 | ||
41 | #define R4_MEMORY_PRESENT (1 << 27) | ||
42 | |||
41 | /* | 43 | /* |
42 | SDIO status in R5 | 44 | SDIO status in R5 |
43 | Type | 45 | Type |
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 6e6e62648a4..3984c4eb41f 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h | |||
@@ -284,6 +284,13 @@ struct zone { | |||
284 | unsigned long watermark[NR_WMARK]; | 284 | unsigned long watermark[NR_WMARK]; |
285 | 285 | ||
286 | /* | 286 | /* |
287 | * When free pages are below this point, additional steps are taken | ||
288 | * when reading the number of free pages to avoid per-cpu counter | ||
289 | * drift allowing watermarks to be breached | ||
290 | */ | ||
291 | unsigned long percpu_drift_mark; | ||
292 | |||
293 | /* | ||
287 | * We don't know if the memory that we're going to allocate will be freeable | 294 | * We don't know if the memory that we're going to allocate will be freeable |
288 | * or/and it will be released eventually, so to avoid totally wasting several | 295 | * or/and it will be released eventually, so to avoid totally wasting several |
289 | * GB of ram we must reserve some of the lower zone memory (otherwise we risk | 296 | * GB of ram we must reserve some of the lower zone memory (otherwise we risk |
@@ -441,6 +448,12 @@ static inline int zone_is_oom_locked(const struct zone *zone) | |||
441 | return test_bit(ZONE_OOM_LOCKED, &zone->flags); | 448 | return test_bit(ZONE_OOM_LOCKED, &zone->flags); |
442 | } | 449 | } |
443 | 450 | ||
451 | #ifdef CONFIG_SMP | ||
452 | unsigned long zone_nr_free_pages(struct zone *zone); | ||
453 | #else | ||
454 | #define zone_nr_free_pages(zone) zone_page_state(zone, NR_FREE_PAGES) | ||
455 | #endif /* CONFIG_SMP */ | ||
456 | |||
444 | /* | 457 | /* |
445 | * The "priority" of VM scanning is how much of the queues we will scan in one | 458 | * The "priority" of VM scanning is how much of the queues we will scan in one |
446 | * go. A value of 12 for DEF_PRIORITY implies that we will scan 1/4096th of the | 459 | * go. A value of 12 for DEF_PRIORITY implies that we will scan 1/4096th of the |
diff --git a/include/linux/module.h b/include/linux/module.h index 8a6b9fdc7ff..aace066bad8 100644 --- a/include/linux/module.h +++ b/include/linux/module.h | |||
@@ -686,17 +686,16 @@ extern int module_sysfs_initialized; | |||
686 | 686 | ||
687 | 687 | ||
688 | #ifdef CONFIG_GENERIC_BUG | 688 | #ifdef CONFIG_GENERIC_BUG |
689 | int module_bug_finalize(const Elf_Ehdr *, const Elf_Shdr *, | 689 | void module_bug_finalize(const Elf_Ehdr *, const Elf_Shdr *, |
690 | struct module *); | 690 | struct module *); |
691 | void module_bug_cleanup(struct module *); | 691 | void module_bug_cleanup(struct module *); |
692 | 692 | ||
693 | #else /* !CONFIG_GENERIC_BUG */ | 693 | #else /* !CONFIG_GENERIC_BUG */ |
694 | 694 | ||
695 | static inline int module_bug_finalize(const Elf_Ehdr *hdr, | 695 | static inline void module_bug_finalize(const Elf_Ehdr *hdr, |
696 | const Elf_Shdr *sechdrs, | 696 | const Elf_Shdr *sechdrs, |
697 | struct module *mod) | 697 | struct module *mod) |
698 | { | 698 | { |
699 | return 0; | ||
700 | } | 699 | } |
701 | static inline void module_bug_cleanup(struct module *mod) {} | 700 | static inline void module_bug_cleanup(struct module *mod) {} |
702 | #endif /* CONFIG_GENERIC_BUG */ | 701 | #endif /* CONFIG_GENERIC_BUG */ |
diff --git a/include/linux/mutex.h b/include/linux/mutex.h index 878cab4f5fc..f363bc8fdc7 100644 --- a/include/linux/mutex.h +++ b/include/linux/mutex.h | |||
@@ -78,6 +78,14 @@ struct mutex_waiter { | |||
78 | # include <linux/mutex-debug.h> | 78 | # include <linux/mutex-debug.h> |
79 | #else | 79 | #else |
80 | # define __DEBUG_MUTEX_INITIALIZER(lockname) | 80 | # define __DEBUG_MUTEX_INITIALIZER(lockname) |
81 | /** | ||
82 | * mutex_init - initialize the mutex | ||
83 | * @mutex: the mutex to be initialized | ||
84 | * | ||
85 | * Initialize the mutex to unlocked state. | ||
86 | * | ||
87 | * It is not allowed to initialize an already locked mutex. | ||
88 | */ | ||
81 | # define mutex_init(mutex) \ | 89 | # define mutex_init(mutex) \ |
82 | do { \ | 90 | do { \ |
83 | static struct lock_class_key __key; \ | 91 | static struct lock_class_key __key; \ |
diff --git a/include/linux/nbd.h b/include/linux/nbd.h index bb58854a806..d146ca10c0f 100644 --- a/include/linux/nbd.h +++ b/include/linux/nbd.h | |||
@@ -88,7 +88,7 @@ struct nbd_request { | |||
88 | char handle[8]; | 88 | char handle[8]; |
89 | __be64 from; | 89 | __be64 from; |
90 | __be32 len; | 90 | __be32 len; |
91 | } __packed; | 91 | } __attribute__((packed)); |
92 | 92 | ||
93 | /* | 93 | /* |
94 | * This is the reply packet that nbd-server sends back to the client after | 94 | * This is the reply packet that nbd-server sends back to the client after |
diff --git a/include/linux/ncp.h b/include/linux/ncp.h index 3ace8370e61..99f0adeeb3f 100644 --- a/include/linux/ncp.h +++ b/include/linux/ncp.h | |||
@@ -27,7 +27,7 @@ struct ncp_request_header { | |||
27 | __u8 conn_high; | 27 | __u8 conn_high; |
28 | __u8 function; | 28 | __u8 function; |
29 | __u8 data[0]; | 29 | __u8 data[0]; |
30 | } __packed; | 30 | } __attribute__((packed)); |
31 | 31 | ||
32 | #define NCP_REPLY (0x3333) | 32 | #define NCP_REPLY (0x3333) |
33 | #define NCP_WATCHDOG (0x3E3E) | 33 | #define NCP_WATCHDOG (0x3E3E) |
@@ -42,7 +42,7 @@ struct ncp_reply_header { | |||
42 | __u8 completion_code; | 42 | __u8 completion_code; |
43 | __u8 connection_state; | 43 | __u8 connection_state; |
44 | __u8 data[0]; | 44 | __u8 data[0]; |
45 | } __packed; | 45 | } __attribute__((packed)); |
46 | 46 | ||
47 | #define NCP_VOLNAME_LEN (16) | 47 | #define NCP_VOLNAME_LEN (16) |
48 | #define NCP_NUMBER_OF_VOLUMES (256) | 48 | #define NCP_NUMBER_OF_VOLUMES (256) |
@@ -158,7 +158,7 @@ struct nw_info_struct { | |||
158 | #ifdef __KERNEL__ | 158 | #ifdef __KERNEL__ |
159 | struct nw_nfs_info nfs; | 159 | struct nw_nfs_info nfs; |
160 | #endif | 160 | #endif |
161 | } __packed; | 161 | } __attribute__((packed)); |
162 | 162 | ||
163 | /* modify mask - use with MODIFY_DOS_INFO structure */ | 163 | /* modify mask - use with MODIFY_DOS_INFO structure */ |
164 | #define DM_ATTRIBUTES (cpu_to_le32(0x02)) | 164 | #define DM_ATTRIBUTES (cpu_to_le32(0x02)) |
@@ -190,12 +190,12 @@ struct nw_modify_dos_info { | |||
190 | __u16 inheritanceGrantMask; | 190 | __u16 inheritanceGrantMask; |
191 | __u16 inheritanceRevokeMask; | 191 | __u16 inheritanceRevokeMask; |
192 | __u32 maximumSpace; | 192 | __u32 maximumSpace; |
193 | } __packed; | 193 | } __attribute__((packed)); |
194 | 194 | ||
195 | struct nw_search_sequence { | 195 | struct nw_search_sequence { |
196 | __u8 volNumber; | 196 | __u8 volNumber; |
197 | __u32 dirBase; | 197 | __u32 dirBase; |
198 | __u32 sequence; | 198 | __u32 sequence; |
199 | } __packed; | 199 | } __attribute__((packed)); |
200 | 200 | ||
201 | #endif /* _LINUX_NCP_H */ | 201 | #endif /* _LINUX_NCP_H */ |
diff --git a/include/linux/netfilter/xt_IDLETIMER.h b/include/linux/netfilter/xt_IDLETIMER.h index 3e1aa1be942..208ae938733 100644 --- a/include/linux/netfilter/xt_IDLETIMER.h +++ b/include/linux/netfilter/xt_IDLETIMER.h | |||
@@ -39,7 +39,7 @@ struct idletimer_tg_info { | |||
39 | char label[MAX_IDLETIMER_LABEL_SIZE]; | 39 | char label[MAX_IDLETIMER_LABEL_SIZE]; |
40 | 40 | ||
41 | /* for kernel module internal use only */ | 41 | /* for kernel module internal use only */ |
42 | struct idletimer_tg *timer __attribute((aligned(8))); | 42 | struct idletimer_tg *timer __attribute__((aligned(8))); |
43 | }; | 43 | }; |
44 | 44 | ||
45 | #endif | 45 | #endif |
diff --git a/include/linux/netfilter/xt_ipvs.h b/include/linux/netfilter/xt_ipvs.h index 1167aeb7a34..eff34ac1880 100644 --- a/include/linux/netfilter/xt_ipvs.h +++ b/include/linux/netfilter/xt_ipvs.h | |||
@@ -1,6 +1,8 @@ | |||
1 | #ifndef _XT_IPVS_H | 1 | #ifndef _XT_IPVS_H |
2 | #define _XT_IPVS_H | 2 | #define _XT_IPVS_H |
3 | 3 | ||
4 | #include <linux/types.h> | ||
5 | |||
4 | enum { | 6 | enum { |
5 | XT_IPVS_IPVS_PROPERTY = 1 << 0, /* all other options imply this one */ | 7 | XT_IPVS_IPVS_PROPERTY = 1 << 0, /* all other options imply this one */ |
6 | XT_IPVS_PROTO = 1 << 1, | 8 | XT_IPVS_PROTO = 1 << 1, |
diff --git a/include/linux/netlink.h b/include/linux/netlink.h index 59d066936ab..123566912d7 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h | |||
@@ -27,8 +27,6 @@ | |||
27 | 27 | ||
28 | #define MAX_LINKS 32 | 28 | #define MAX_LINKS 32 |
29 | 29 | ||
30 | struct net; | ||
31 | |||
32 | struct sockaddr_nl { | 30 | struct sockaddr_nl { |
33 | sa_family_t nl_family; /* AF_NETLINK */ | 31 | sa_family_t nl_family; /* AF_NETLINK */ |
34 | unsigned short nl_pad; /* zero */ | 32 | unsigned short nl_pad; /* zero */ |
@@ -151,6 +149,8 @@ struct nlattr { | |||
151 | #include <linux/capability.h> | 149 | #include <linux/capability.h> |
152 | #include <linux/skbuff.h> | 150 | #include <linux/skbuff.h> |
153 | 151 | ||
152 | struct net; | ||
153 | |||
154 | static inline struct nlmsghdr *nlmsg_hdr(const struct sk_buff *skb) | 154 | static inline struct nlmsghdr *nlmsg_hdr(const struct sk_buff *skb) |
155 | { | 155 | { |
156 | return (struct nlmsghdr *)skb->data; | 156 | return (struct nlmsghdr *)skb->data; |
diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h index 791d5109f34..50d8009be86 100644 --- a/include/linux/netpoll.h +++ b/include/linux/netpoll.h | |||
@@ -63,20 +63,20 @@ static inline bool netpoll_rx(struct sk_buff *skb) | |||
63 | unsigned long flags; | 63 | unsigned long flags; |
64 | bool ret = false; | 64 | bool ret = false; |
65 | 65 | ||
66 | rcu_read_lock_bh(); | 66 | local_irq_save(flags); |
67 | npinfo = rcu_dereference_bh(skb->dev->npinfo); | 67 | npinfo = rcu_dereference_bh(skb->dev->npinfo); |
68 | 68 | ||
69 | if (!npinfo || (list_empty(&npinfo->rx_np) && !npinfo->rx_flags)) | 69 | if (!npinfo || (list_empty(&npinfo->rx_np) && !npinfo->rx_flags)) |
70 | goto out; | 70 | goto out; |
71 | 71 | ||
72 | spin_lock_irqsave(&npinfo->rx_lock, flags); | 72 | spin_lock(&npinfo->rx_lock); |
73 | /* check rx_flags again with the lock held */ | 73 | /* check rx_flags again with the lock held */ |
74 | if (npinfo->rx_flags && __netpoll_rx(skb)) | 74 | if (npinfo->rx_flags && __netpoll_rx(skb)) |
75 | ret = true; | 75 | ret = true; |
76 | spin_unlock_irqrestore(&npinfo->rx_lock, flags); | 76 | spin_unlock(&npinfo->rx_lock); |
77 | 77 | ||
78 | out: | 78 | out: |
79 | rcu_read_unlock_bh(); | 79 | local_irq_restore(flags); |
80 | return ret; | 80 | return ret; |
81 | } | 81 | } |
82 | 82 | ||
diff --git a/include/linux/pci.h b/include/linux/pci.h index b1d17956a15..c8d95e369ff 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -1214,6 +1214,9 @@ static inline struct pci_dev *pci_get_bus_and_slot(unsigned int bus, | |||
1214 | unsigned int devfn) | 1214 | unsigned int devfn) |
1215 | { return NULL; } | 1215 | { return NULL; } |
1216 | 1216 | ||
1217 | static inline int pci_domain_nr(struct pci_bus *bus) | ||
1218 | { return 0; } | ||
1219 | |||
1217 | #define dev_is_pci(d) (false) | 1220 | #define dev_is_pci(d) (false) |
1218 | #define dev_is_pf(d) (false) | 1221 | #define dev_is_pf(d) (false) |
1219 | #define dev_num_vf(d) (0) | 1222 | #define dev_num_vf(d) (0) |
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index f6a3b2d36ca..570fddeb038 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
@@ -393,6 +393,9 @@ | |||
393 | #define PCI_DEVICE_ID_VLSI_82C147 0x0105 | 393 | #define PCI_DEVICE_ID_VLSI_82C147 0x0105 |
394 | #define PCI_DEVICE_ID_VLSI_VAS96011 0x0702 | 394 | #define PCI_DEVICE_ID_VLSI_VAS96011 0x0702 |
395 | 395 | ||
396 | /* AMD RD890 Chipset */ | ||
397 | #define PCI_DEVICE_ID_RD890_IOMMU 0x5a23 | ||
398 | |||
396 | #define PCI_VENDOR_ID_ADL 0x1005 | 399 | #define PCI_VENDOR_ID_ADL 0x1005 |
397 | #define PCI_DEVICE_ID_ADL_2301 0x2301 | 400 | #define PCI_DEVICE_ID_ADL_2301 0x2301 |
398 | 401 | ||
@@ -2300,6 +2303,8 @@ | |||
2300 | #define PCI_DEVICE_ID_P2010 0x0079 | 2303 | #define PCI_DEVICE_ID_P2010 0x0079 |
2301 | #define PCI_DEVICE_ID_P1020E 0x0100 | 2304 | #define PCI_DEVICE_ID_P1020E 0x0100 |
2302 | #define PCI_DEVICE_ID_P1020 0x0101 | 2305 | #define PCI_DEVICE_ID_P1020 0x0101 |
2306 | #define PCI_DEVICE_ID_P1021E 0x0102 | ||
2307 | #define PCI_DEVICE_ID_P1021 0x0103 | ||
2303 | #define PCI_DEVICE_ID_P1011E 0x0108 | 2308 | #define PCI_DEVICE_ID_P1011E 0x0108 |
2304 | #define PCI_DEVICE_ID_P1011 0x0109 | 2309 | #define PCI_DEVICE_ID_P1011 0x0109 |
2305 | #define PCI_DEVICE_ID_P1022E 0x0110 | 2310 | #define PCI_DEVICE_ID_P1022E 0x0110 |
diff --git a/include/linux/percpu.h b/include/linux/percpu.h index b8b9084527b..49466b13c5c 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h | |||
@@ -149,7 +149,7 @@ extern void __init percpu_init_late(void); | |||
149 | 149 | ||
150 | #else /* CONFIG_SMP */ | 150 | #else /* CONFIG_SMP */ |
151 | 151 | ||
152 | #define per_cpu_ptr(ptr, cpu) ({ (void)(cpu); (ptr); }) | 152 | #define per_cpu_ptr(ptr, cpu) ({ (void)(cpu); VERIFY_PERCPU_PTR((ptr)); }) |
153 | 153 | ||
154 | /* can't distinguish from other static vars, always false */ | 154 | /* can't distinguish from other static vars, always false */ |
155 | static inline bool is_kernel_percpu_address(unsigned long addr) | 155 | static inline bool is_kernel_percpu_address(unsigned long addr) |
diff --git a/include/linux/phonet.h b/include/linux/phonet.h index 24426c3d6b5..76edadf046d 100644 --- a/include/linux/phonet.h +++ b/include/linux/phonet.h | |||
@@ -56,7 +56,7 @@ struct phonethdr { | |||
56 | __be16 pn_length; | 56 | __be16 pn_length; |
57 | __u8 pn_robj; | 57 | __u8 pn_robj; |
58 | __u8 pn_sobj; | 58 | __u8 pn_sobj; |
59 | } __packed; | 59 | } __attribute__((packed)); |
60 | 60 | ||
61 | /* Common Phonet payload header */ | 61 | /* Common Phonet payload header */ |
62 | struct phonetmsg { | 62 | struct phonetmsg { |
@@ -98,7 +98,7 @@ struct sockaddr_pn { | |||
98 | __u8 spn_dev; | 98 | __u8 spn_dev; |
99 | __u8 spn_resource; | 99 | __u8 spn_resource; |
100 | __u8 spn_zero[sizeof(struct sockaddr) - sizeof(sa_family_t) - 3]; | 100 | __u8 spn_zero[sizeof(struct sockaddr) - sizeof(sa_family_t) - 3]; |
101 | } __packed; | 101 | } __attribute__((packed)); |
102 | 102 | ||
103 | /* Well known address */ | 103 | /* Well known address */ |
104 | #define PN_DEV_PC 0x10 | 104 | #define PN_DEV_PC 0x10 |
diff --git a/include/linux/pxa168_eth.h b/include/linux/pxa168_eth.h new file mode 100644 index 00000000000..18d75e79560 --- /dev/null +++ b/include/linux/pxa168_eth.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | *pxa168 ethernet platform device data definition file. | ||
3 | */ | ||
4 | #ifndef __LINUX_PXA168_ETH_H | ||
5 | #define __LINUX_PXA168_ETH_H | ||
6 | |||
7 | struct pxa168_eth_platform_data { | ||
8 | int port_number; | ||
9 | int phy_addr; | ||
10 | |||
11 | /* | ||
12 | * If speed is 0, then speed and duplex are autonegotiated. | ||
13 | */ | ||
14 | int speed; /* 0, SPEED_10, SPEED_100 */ | ||
15 | int duplex; /* DUPLEX_HALF or DUPLEX_FULL */ | ||
16 | |||
17 | /* | ||
18 | * Override default RX/TX queue sizes if nonzero. | ||
19 | */ | ||
20 | int rx_queue_size; | ||
21 | int tx_queue_size; | ||
22 | |||
23 | /* | ||
24 | * init callback is used for board specific initialization | ||
25 | * e.g on Aspenite its used to initialize the PHY transceiver. | ||
26 | */ | ||
27 | int (*init)(void); | ||
28 | }; | ||
29 | |||
30 | #endif /* __LINUX_PXA168_ETH_H */ | ||
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index d50ba858cfe..d1a9193960f 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h | |||
@@ -274,8 +274,14 @@ static inline int dquot_alloc_space(struct inode *inode, qsize_t nr) | |||
274 | int ret; | 274 | int ret; |
275 | 275 | ||
276 | ret = dquot_alloc_space_nodirty(inode, nr); | 276 | ret = dquot_alloc_space_nodirty(inode, nr); |
277 | if (!ret) | 277 | if (!ret) { |
278 | mark_inode_dirty_sync(inode); | 278 | /* |
279 | * Mark inode fully dirty. Since we are allocating blocks, inode | ||
280 | * would become fully dirty soon anyway and it reportedly | ||
281 | * reduces inode_lock contention. | ||
282 | */ | ||
283 | mark_inode_dirty(inode); | ||
284 | } | ||
279 | return ret; | 285 | return ret; |
280 | } | 286 | } |
281 | 287 | ||
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 9fbc54a2585..83af1f8d8b7 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h | |||
@@ -454,7 +454,7 @@ static inline notrace void rcu_read_unlock_sched_notrace(void) | |||
454 | * Makes rcu_dereference_check() do the dirty work. | 454 | * Makes rcu_dereference_check() do the dirty work. |
455 | */ | 455 | */ |
456 | #define rcu_dereference_bh(p) \ | 456 | #define rcu_dereference_bh(p) \ |
457 | rcu_dereference_check(p, rcu_read_lock_bh_held()) | 457 | rcu_dereference_check(p, rcu_read_lock_bh_held() || irqs_disabled()) |
458 | 458 | ||
459 | /** | 459 | /** |
460 | * rcu_dereference_sched - fetch RCU-protected pointer, checking for RCU-sched | 460 | * rcu_dereference_sched - fetch RCU-protected pointer, checking for RCU-sched |
diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h index 4f82326eb29..08c32e4f261 100644 --- a/include/linux/rfkill.h +++ b/include/linux/rfkill.h | |||
@@ -81,7 +81,7 @@ struct rfkill_event { | |||
81 | __u8 type; | 81 | __u8 type; |
82 | __u8 op; | 82 | __u8 op; |
83 | __u8 soft, hard; | 83 | __u8 soft, hard; |
84 | } __packed; | 84 | } __attribute__((packed)); |
85 | 85 | ||
86 | /* | 86 | /* |
87 | * We are planning to be backward and forward compatible with changes | 87 | * We are planning to be backward and forward compatible with changes |
diff --git a/include/linux/semaphore.h b/include/linux/semaphore.h index 7415839ac89..5310d27abd2 100644 --- a/include/linux/semaphore.h +++ b/include/linux/semaphore.h | |||
@@ -26,6 +26,9 @@ struct semaphore { | |||
26 | .wait_list = LIST_HEAD_INIT((name).wait_list), \ | 26 | .wait_list = LIST_HEAD_INIT((name).wait_list), \ |
27 | } | 27 | } |
28 | 28 | ||
29 | #define DEFINE_SEMAPHORE(name) \ | ||
30 | struct semaphore name = __SEMAPHORE_INITIALIZER(name, 1) | ||
31 | |||
29 | #define DECLARE_MUTEX(name) \ | 32 | #define DECLARE_MUTEX(name) \ |
30 | struct semaphore name = __SEMAPHORE_INITIALIZER(name, 1) | 33 | struct semaphore name = __SEMAPHORE_INITIALIZER(name, 1) |
31 | 34 | ||
diff --git a/include/linux/serial.h b/include/linux/serial.h index 1ebc694a6d5..ef914061511 100644 --- a/include/linux/serial.h +++ b/include/linux/serial.h | |||
@@ -77,8 +77,7 @@ struct serial_struct { | |||
77 | #define PORT_16654 11 | 77 | #define PORT_16654 11 |
78 | #define PORT_16850 12 | 78 | #define PORT_16850 12 |
79 | #define PORT_RSA 13 /* RSA-DV II/S card */ | 79 | #define PORT_RSA 13 /* RSA-DV II/S card */ |
80 | #define PORT_U6_16550A 14 | 80 | #define PORT_MAX 13 |
81 | #define PORT_MAX 14 | ||
82 | 81 | ||
83 | #define SERIAL_IO_PORT 0 | 82 | #define SERIAL_IO_PORT 0 |
84 | #define SERIAL_IO_HUB6 1 | 83 | #define SERIAL_IO_HUB6 1 |
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 3c2ad99fed3..563e2340091 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h | |||
@@ -44,7 +44,8 @@ | |||
44 | #define PORT_RM9000 16 /* PMC-Sierra RM9xxx internal UART */ | 44 | #define PORT_RM9000 16 /* PMC-Sierra RM9xxx internal UART */ |
45 | #define PORT_OCTEON 17 /* Cavium OCTEON internal UART */ | 45 | #define PORT_OCTEON 17 /* Cavium OCTEON internal UART */ |
46 | #define PORT_AR7 18 /* Texas Instruments AR7 internal UART */ | 46 | #define PORT_AR7 18 /* Texas Instruments AR7 internal UART */ |
47 | #define PORT_MAX_8250 18 /* max port ID */ | 47 | #define PORT_U6_16550A 19 /* ST-Ericsson U6xxx internal UART */ |
48 | #define PORT_MAX_8250 19 /* max port ID */ | ||
48 | 49 | ||
49 | /* | 50 | /* |
50 | * ARM specific type numbers. These are not currently guaranteed | 51 | * ARM specific type numbers. These are not currently guaranteed |
@@ -465,7 +466,7 @@ uart_handle_sysrq_char(struct uart_port *port, unsigned int ch) | |||
465 | #ifdef SUPPORT_SYSRQ | 466 | #ifdef SUPPORT_SYSRQ |
466 | if (port->sysrq) { | 467 | if (port->sysrq) { |
467 | if (ch && time_before(jiffies, port->sysrq)) { | 468 | if (ch && time_before(jiffies, port->sysrq)) { |
468 | handle_sysrq(ch, port->state->port.tty); | 469 | handle_sysrq(ch); |
469 | port->sysrq = 0; | 470 | port->sysrq = 0; |
470 | return 1; | 471 | return 1; |
471 | } | 472 | } |
diff --git a/include/linux/socket.h b/include/linux/socket.h index a2fada9becb..a8f56e1ec76 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h | |||
@@ -322,7 +322,7 @@ extern int csum_partial_copy_fromiovecend(unsigned char *kdata, | |||
322 | int offset, | 322 | int offset, |
323 | unsigned int len, __wsum *csump); | 323 | unsigned int len, __wsum *csump); |
324 | 324 | ||
325 | extern int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode); | 325 | extern long verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode); |
326 | extern int memcpy_toiovec(struct iovec *v, unsigned char *kdata, int len); | 326 | extern int memcpy_toiovec(struct iovec *v, unsigned char *kdata, int len); |
327 | extern int memcpy_toiovecend(const struct iovec *v, unsigned char *kdata, | 327 | extern int memcpy_toiovecend(const struct iovec *v, unsigned char *kdata, |
328 | int offset, int len); | 328 | int offset, int len); |
diff --git a/include/linux/spi/dw_spi.h b/include/linux/spi/dw_spi.h index cc813f95a2f..c91302f3a25 100644 --- a/include/linux/spi/dw_spi.h +++ b/include/linux/spi/dw_spi.h | |||
@@ -14,7 +14,9 @@ | |||
14 | #define SPI_MODE_OFFSET 6 | 14 | #define SPI_MODE_OFFSET 6 |
15 | #define SPI_SCPH_OFFSET 6 | 15 | #define SPI_SCPH_OFFSET 6 |
16 | #define SPI_SCOL_OFFSET 7 | 16 | #define SPI_SCOL_OFFSET 7 |
17 | |||
17 | #define SPI_TMOD_OFFSET 8 | 18 | #define SPI_TMOD_OFFSET 8 |
19 | #define SPI_TMOD_MASK (0x3 << SPI_TMOD_OFFSET) | ||
18 | #define SPI_TMOD_TR 0x0 /* xmit & recv */ | 20 | #define SPI_TMOD_TR 0x0 /* xmit & recv */ |
19 | #define SPI_TMOD_TO 0x1 /* xmit only */ | 21 | #define SPI_TMOD_TO 0x1 /* xmit only */ |
20 | #define SPI_TMOD_RO 0x2 /* recv only */ | 22 | #define SPI_TMOD_RO 0x2 /* recv only */ |
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index 569dc722a60..85f38a63f09 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h | |||
@@ -30,7 +30,7 @@ struct rpc_inode; | |||
30 | * The high-level client handle | 30 | * The high-level client handle |
31 | */ | 31 | */ |
32 | struct rpc_clnt { | 32 | struct rpc_clnt { |
33 | struct kref cl_kref; /* Number of references */ | 33 | atomic_t cl_count; /* Number of references */ |
34 | struct list_head cl_clients; /* Global list of clients */ | 34 | struct list_head cl_clients; /* Global list of clients */ |
35 | struct list_head cl_tasks; /* List of tasks */ | 35 | struct list_head cl_tasks; /* List of tasks */ |
36 | spinlock_t cl_lock; /* spinlock */ | 36 | spinlock_t cl_lock; /* spinlock */ |
diff --git a/include/linux/swap.h b/include/linux/swap.h index 2fee51a11b7..7cdd63366f8 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h | |||
@@ -19,6 +19,7 @@ struct bio; | |||
19 | #define SWAP_FLAG_PREFER 0x8000 /* set if swap priority specified */ | 19 | #define SWAP_FLAG_PREFER 0x8000 /* set if swap priority specified */ |
20 | #define SWAP_FLAG_PRIO_MASK 0x7fff | 20 | #define SWAP_FLAG_PRIO_MASK 0x7fff |
21 | #define SWAP_FLAG_PRIO_SHIFT 0 | 21 | #define SWAP_FLAG_PRIO_SHIFT 0 |
22 | #define SWAP_FLAG_DISCARD 0x10000 /* discard swap cluster after use */ | ||
22 | 23 | ||
23 | static inline int current_is_kswapd(void) | 24 | static inline int current_is_kswapd(void) |
24 | { | 25 | { |
@@ -142,7 +143,7 @@ struct swap_extent { | |||
142 | enum { | 143 | enum { |
143 | SWP_USED = (1 << 0), /* is slot in swap_info[] used? */ | 144 | SWP_USED = (1 << 0), /* is slot in swap_info[] used? */ |
144 | SWP_WRITEOK = (1 << 1), /* ok to write to this swap? */ | 145 | SWP_WRITEOK = (1 << 1), /* ok to write to this swap? */ |
145 | SWP_DISCARDABLE = (1 << 2), /* blkdev supports discard */ | 146 | SWP_DISCARDABLE = (1 << 2), /* swapon+blkdev support discard */ |
146 | SWP_DISCARDING = (1 << 3), /* now discarding a free cluster */ | 147 | SWP_DISCARDING = (1 << 3), /* now discarding a free cluster */ |
147 | SWP_SOLIDSTATE = (1 << 4), /* blkdev seeks are cheap */ | 148 | SWP_SOLIDSTATE = (1 << 4), /* blkdev seeks are cheap */ |
148 | SWP_CONTINUED = (1 << 5), /* swap_map has count continuation */ | 149 | SWP_CONTINUED = (1 << 5), /* swap_map has count continuation */ |
@@ -315,6 +316,7 @@ extern long nr_swap_pages; | |||
315 | extern long total_swap_pages; | 316 | extern long total_swap_pages; |
316 | extern void si_swapinfo(struct sysinfo *); | 317 | extern void si_swapinfo(struct sysinfo *); |
317 | extern swp_entry_t get_swap_page(void); | 318 | extern swp_entry_t get_swap_page(void); |
319 | extern swp_entry_t get_swap_page_of_type(int); | ||
318 | extern int valid_swaphandles(swp_entry_t, unsigned long *); | 320 | extern int valid_swaphandles(swp_entry_t, unsigned long *); |
319 | extern int add_swap_count_continuation(swp_entry_t, gfp_t); | 321 | extern int add_swap_count_continuation(swp_entry_t, gfp_t); |
320 | extern void swap_shmem_alloc(swp_entry_t); | 322 | extern void swap_shmem_alloc(swp_entry_t); |
@@ -331,13 +333,6 @@ extern int reuse_swap_page(struct page *); | |||
331 | extern int try_to_free_swap(struct page *); | 333 | extern int try_to_free_swap(struct page *); |
332 | struct backing_dev_info; | 334 | struct backing_dev_info; |
333 | 335 | ||
334 | #ifdef CONFIG_HIBERNATION | ||
335 | void hibernation_freeze_swap(void); | ||
336 | void hibernation_thaw_swap(void); | ||
337 | swp_entry_t get_swap_for_hibernation(int type); | ||
338 | void swap_free_for_hibernation(swp_entry_t val); | ||
339 | #endif | ||
340 | |||
341 | /* linux/mm/thrash.c */ | 336 | /* linux/mm/thrash.c */ |
342 | extern struct mm_struct *swap_token_mm; | 337 | extern struct mm_struct *swap_token_mm; |
343 | extern void grab_swap_token(struct mm_struct *); | 338 | extern void grab_swap_token(struct mm_struct *); |
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index 3c92121ba9a..96eb576d82f 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/errno.h> | 16 | #include <linux/errno.h> |
17 | #include <linux/list.h> | 17 | #include <linux/list.h> |
18 | #include <linux/lockdep.h> | 18 | #include <linux/lockdep.h> |
19 | #include <linux/kobject_ns.h> | ||
19 | #include <asm/atomic.h> | 20 | #include <asm/atomic.h> |
20 | 21 | ||
21 | struct kobject; | 22 | struct kobject; |
diff --git a/include/linux/sysrq.h b/include/linux/sysrq.h index 609e8ca5f53..387fa7d05c9 100644 --- a/include/linux/sysrq.h +++ b/include/linux/sysrq.h | |||
@@ -15,9 +15,7 @@ | |||
15 | #define _LINUX_SYSRQ_H | 15 | #define _LINUX_SYSRQ_H |
16 | 16 | ||
17 | #include <linux/errno.h> | 17 | #include <linux/errno.h> |
18 | 18 | #include <linux/types.h> | |
19 | struct pt_regs; | ||
20 | struct tty_struct; | ||
21 | 19 | ||
22 | /* Possible values of bitmask for enabling sysrq functions */ | 20 | /* Possible values of bitmask for enabling sysrq functions */ |
23 | /* 0x0001 is reserved for enable everything */ | 21 | /* 0x0001 is reserved for enable everything */ |
@@ -31,7 +29,7 @@ struct tty_struct; | |||
31 | #define SYSRQ_ENABLE_RTNICE 0x0100 | 29 | #define SYSRQ_ENABLE_RTNICE 0x0100 |
32 | 30 | ||
33 | struct sysrq_key_op { | 31 | struct sysrq_key_op { |
34 | void (*handler)(int, struct tty_struct *); | 32 | void (*handler)(int); |
35 | char *help_msg; | 33 | char *help_msg; |
36 | char *action_msg; | 34 | char *action_msg; |
37 | int enable_mask; | 35 | int enable_mask; |
@@ -44,8 +42,8 @@ struct sysrq_key_op { | |||
44 | * are available -- else NULL's). | 42 | * are available -- else NULL's). |
45 | */ | 43 | */ |
46 | 44 | ||
47 | void handle_sysrq(int key, struct tty_struct *tty); | 45 | void handle_sysrq(int key); |
48 | void __handle_sysrq(int key, struct tty_struct *tty, int check_mask); | 46 | void __handle_sysrq(int key, bool check_mask); |
49 | int register_sysrq_key(int key, struct sysrq_key_op *op); | 47 | int register_sysrq_key(int key, struct sysrq_key_op *op); |
50 | int unregister_sysrq_key(int key, struct sysrq_key_op *op); | 48 | int unregister_sysrq_key(int key, struct sysrq_key_op *op); |
51 | struct sysrq_key_op *__sysrq_get_key_op(int key); | 49 | struct sysrq_key_op *__sysrq_get_key_op(int key); |
@@ -54,7 +52,11 @@ int sysrq_toggle_support(int enable_mask); | |||
54 | 52 | ||
55 | #else | 53 | #else |
56 | 54 | ||
57 | static inline void handle_sysrq(int key, struct tty_struct *tty) | 55 | static inline void handle_sysrq(int key) |
56 | { | ||
57 | } | ||
58 | |||
59 | static inline void __handle_sysrq(int key, bool check_mask) | ||
58 | { | 60 | { |
59 | } | 61 | } |
60 | 62 | ||
diff --git a/include/linux/uinput.h b/include/linux/uinput.h index 60c81da77f0..05f7fed2b17 100644 --- a/include/linux/uinput.h +++ b/include/linux/uinput.h | |||
@@ -37,7 +37,6 @@ | |||
37 | #define UINPUT_VERSION 3 | 37 | #define UINPUT_VERSION 3 |
38 | 38 | ||
39 | #ifdef __KERNEL__ | 39 | #ifdef __KERNEL__ |
40 | #define UINPUT_MINOR 223 | ||
41 | #define UINPUT_NAME "uinput" | 40 | #define UINPUT_NAME "uinput" |
42 | #define UINPUT_BUFFER_SIZE 16 | 41 | #define UINPUT_BUFFER_SIZE 16 |
43 | #define UINPUT_NUM_REQUESTS 16 | 42 | #define UINPUT_NUM_REQUESTS 16 |
diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 890bc147219..617068134ae 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h | |||
@@ -247,6 +247,7 @@ int usb_add_config(struct usb_composite_dev *, | |||
247 | * value; it should return zero on successful initialization. | 247 | * value; it should return zero on successful initialization. |
248 | * @unbind: Reverses @bind(); called as a side effect of unregistering | 248 | * @unbind: Reverses @bind(); called as a side effect of unregistering |
249 | * this driver. | 249 | * this driver. |
250 | * @disconnect: optional driver disconnect method | ||
250 | * @suspend: Notifies when the host stops sending USB traffic, | 251 | * @suspend: Notifies when the host stops sending USB traffic, |
251 | * after function notifications | 252 | * after function notifications |
252 | * @resume: Notifies configuration when the host restarts USB traffic, | 253 | * @resume: Notifies configuration when the host restarts USB traffic, |
diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index 84a4c44c208..55675b1efb2 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h | |||
@@ -342,8 +342,7 @@ extern int usb_serial_generic_submit_read_urb(struct usb_serial_port *port, | |||
342 | extern void usb_serial_generic_process_read_urb(struct urb *urb); | 342 | extern void usb_serial_generic_process_read_urb(struct urb *urb); |
343 | extern int usb_serial_generic_prepare_write_buffer(struct usb_serial_port *port, | 343 | extern int usb_serial_generic_prepare_write_buffer(struct usb_serial_port *port, |
344 | void *dest, size_t size); | 344 | void *dest, size_t size); |
345 | extern int usb_serial_handle_sysrq_char(struct tty_struct *tty, | 345 | extern int usb_serial_handle_sysrq_char(struct usb_serial_port *port, |
346 | struct usb_serial_port *port, | ||
347 | unsigned int ch); | 346 | unsigned int ch); |
348 | extern int usb_serial_handle_break(struct usb_serial_port *port); | 347 | extern int usb_serial_handle_break(struct usb_serial_port *port); |
349 | 348 | ||
diff --git a/include/linux/vgaarb.h b/include/linux/vgaarb.h index 6228b5b77d3..e9e1524b582 100644 --- a/include/linux/vgaarb.h +++ b/include/linux/vgaarb.h | |||
@@ -93,8 +93,11 @@ extern void vga_set_legacy_decoding(struct pci_dev *pdev, | |||
93 | * Nested calls are supported (a per-resource counter is maintained) | 93 | * Nested calls are supported (a per-resource counter is maintained) |
94 | */ | 94 | */ |
95 | 95 | ||
96 | extern int vga_get(struct pci_dev *pdev, unsigned int rsrc, | 96 | #if defined(CONFIG_VGA_ARB) |
97 | int interruptible); | 97 | extern int vga_get(struct pci_dev *pdev, unsigned int rsrc, int interruptible); |
98 | #else | ||
99 | static inline int vga_get(struct pci_dev *pdev, unsigned int rsrc, int interruptible) { return 0; } | ||
100 | #endif | ||
98 | 101 | ||
99 | /** | 102 | /** |
100 | * vga_get_interruptible | 103 | * vga_get_interruptible |
@@ -131,7 +134,11 @@ static inline int vga_get_uninterruptible(struct pci_dev *pdev, | |||
131 | * are already locked by another card. It can be called in any context | 134 | * are already locked by another card. It can be called in any context |
132 | */ | 135 | */ |
133 | 136 | ||
137 | #if defined(CONFIG_VGA_ARB) | ||
134 | extern int vga_tryget(struct pci_dev *pdev, unsigned int rsrc); | 138 | extern int vga_tryget(struct pci_dev *pdev, unsigned int rsrc); |
139 | #else | ||
140 | static inline int vga_tryget(struct pci_dev *pdev, unsigned int rsrc) { return 0; } | ||
141 | #endif | ||
135 | 142 | ||
136 | /** | 143 | /** |
137 | * vga_put - release lock on legacy VGA resources | 144 | * vga_put - release lock on legacy VGA resources |
@@ -146,7 +153,11 @@ extern int vga_tryget(struct pci_dev *pdev, unsigned int rsrc); | |||
146 | * released if the counter reaches 0. | 153 | * released if the counter reaches 0. |
147 | */ | 154 | */ |
148 | 155 | ||
156 | #if defined(CONFIG_VGA_ARB) | ||
149 | extern void vga_put(struct pci_dev *pdev, unsigned int rsrc); | 157 | extern void vga_put(struct pci_dev *pdev, unsigned int rsrc); |
158 | #else | ||
159 | #define vga_put(pdev, rsrc) | ||
160 | #endif | ||
150 | 161 | ||
151 | 162 | ||
152 | /** | 163 | /** |
diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h index 7f43ccdc1d3..eaaea37b3b7 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h | |||
@@ -170,6 +170,28 @@ static inline unsigned long zone_page_state(struct zone *zone, | |||
170 | return x; | 170 | return x; |
171 | } | 171 | } |
172 | 172 | ||
173 | /* | ||
174 | * More accurate version that also considers the currently pending | ||
175 | * deltas. For that we need to loop over all cpus to find the current | ||
176 | * deltas. There is no synchronization so the result cannot be | ||
177 | * exactly accurate either. | ||
178 | */ | ||
179 | static inline unsigned long zone_page_state_snapshot(struct zone *zone, | ||
180 | enum zone_stat_item item) | ||
181 | { | ||
182 | long x = atomic_long_read(&zone->vm_stat[item]); | ||
183 | |||
184 | #ifdef CONFIG_SMP | ||
185 | int cpu; | ||
186 | for_each_online_cpu(cpu) | ||
187 | x += per_cpu_ptr(zone->pageset, cpu)->vm_stat_diff[item]; | ||
188 | |||
189 | if (x < 0) | ||
190 | x = 0; | ||
191 | #endif | ||
192 | return x; | ||
193 | } | ||
194 | |||
173 | extern unsigned long global_reclaimable_pages(void); | 195 | extern unsigned long global_reclaimable_pages(void); |
174 | extern unsigned long zone_reclaimable_pages(struct zone *zone); | 196 | extern unsigned long zone_reclaimable_pages(struct zone *zone); |
175 | 197 | ||
diff --git a/include/linux/wait.h b/include/linux/wait.h index 0836ccc5712..3efc9f3f43a 100644 --- a/include/linux/wait.h +++ b/include/linux/wait.h | |||
@@ -614,6 +614,7 @@ int wake_bit_function(wait_queue_t *wait, unsigned mode, int sync, void *key); | |||
614 | (wait)->private = current; \ | 614 | (wait)->private = current; \ |
615 | (wait)->func = autoremove_wake_function; \ | 615 | (wait)->func = autoremove_wake_function; \ |
616 | INIT_LIST_HEAD(&(wait)->task_list); \ | 616 | INIT_LIST_HEAD(&(wait)->task_list); \ |
617 | (wait)->flags = 0; \ | ||
617 | } while (0) | 618 | } while (0) |
618 | 619 | ||
619 | /** | 620 | /** |
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index 4f9d277bcd9..25e02c941ba 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h | |||
@@ -25,18 +25,20 @@ typedef void (*work_func_t)(struct work_struct *work); | |||
25 | 25 | ||
26 | enum { | 26 | enum { |
27 | WORK_STRUCT_PENDING_BIT = 0, /* work item is pending execution */ | 27 | WORK_STRUCT_PENDING_BIT = 0, /* work item is pending execution */ |
28 | WORK_STRUCT_CWQ_BIT = 1, /* data points to cwq */ | 28 | WORK_STRUCT_DELAYED_BIT = 1, /* work item is delayed */ |
29 | WORK_STRUCT_LINKED_BIT = 2, /* next work is linked to this one */ | 29 | WORK_STRUCT_CWQ_BIT = 2, /* data points to cwq */ |
30 | WORK_STRUCT_LINKED_BIT = 3, /* next work is linked to this one */ | ||
30 | #ifdef CONFIG_DEBUG_OBJECTS_WORK | 31 | #ifdef CONFIG_DEBUG_OBJECTS_WORK |
31 | WORK_STRUCT_STATIC_BIT = 3, /* static initializer (debugobjects) */ | 32 | WORK_STRUCT_STATIC_BIT = 4, /* static initializer (debugobjects) */ |
32 | WORK_STRUCT_COLOR_SHIFT = 4, /* color for workqueue flushing */ | 33 | WORK_STRUCT_COLOR_SHIFT = 5, /* color for workqueue flushing */ |
33 | #else | 34 | #else |
34 | WORK_STRUCT_COLOR_SHIFT = 3, /* color for workqueue flushing */ | 35 | WORK_STRUCT_COLOR_SHIFT = 4, /* color for workqueue flushing */ |
35 | #endif | 36 | #endif |
36 | 37 | ||
37 | WORK_STRUCT_COLOR_BITS = 4, | 38 | WORK_STRUCT_COLOR_BITS = 4, |
38 | 39 | ||
39 | WORK_STRUCT_PENDING = 1 << WORK_STRUCT_PENDING_BIT, | 40 | WORK_STRUCT_PENDING = 1 << WORK_STRUCT_PENDING_BIT, |
41 | WORK_STRUCT_DELAYED = 1 << WORK_STRUCT_DELAYED_BIT, | ||
40 | WORK_STRUCT_CWQ = 1 << WORK_STRUCT_CWQ_BIT, | 42 | WORK_STRUCT_CWQ = 1 << WORK_STRUCT_CWQ_BIT, |
41 | WORK_STRUCT_LINKED = 1 << WORK_STRUCT_LINKED_BIT, | 43 | WORK_STRUCT_LINKED = 1 << WORK_STRUCT_LINKED_BIT, |
42 | #ifdef CONFIG_DEBUG_OBJECTS_WORK | 44 | #ifdef CONFIG_DEBUG_OBJECTS_WORK |
@@ -59,8 +61,8 @@ enum { | |||
59 | 61 | ||
60 | /* | 62 | /* |
61 | * Reserve 7 bits off of cwq pointer w/ debugobjects turned | 63 | * Reserve 7 bits off of cwq pointer w/ debugobjects turned |
62 | * off. This makes cwqs aligned to 128 bytes which isn't too | 64 | * off. This makes cwqs aligned to 256 bytes and allows 15 |
63 | * excessive while allowing 15 workqueue flush colors. | 65 | * workqueue flush colors. |
64 | */ | 66 | */ |
65 | WORK_STRUCT_FLAG_BITS = WORK_STRUCT_COLOR_SHIFT + | 67 | WORK_STRUCT_FLAG_BITS = WORK_STRUCT_COLOR_SHIFT + |
66 | WORK_STRUCT_COLOR_BITS, | 68 | WORK_STRUCT_COLOR_BITS, |
@@ -233,6 +235,10 @@ static inline unsigned int work_static(struct work_struct *work) { return 0; } | |||
233 | #define work_clear_pending(work) \ | 235 | #define work_clear_pending(work) \ |
234 | clear_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(work)) | 236 | clear_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(work)) |
235 | 237 | ||
238 | /* | ||
239 | * Workqueue flags and constants. For details, please refer to | ||
240 | * Documentation/workqueue.txt. | ||
241 | */ | ||
236 | enum { | 242 | enum { |
237 | WQ_NON_REENTRANT = 1 << 0, /* guarantee non-reentrance */ | 243 | WQ_NON_REENTRANT = 1 << 0, /* guarantee non-reentrance */ |
238 | WQ_UNBOUND = 1 << 1, /* not bound to any cpu */ | 244 | WQ_UNBOUND = 1 << 1, /* not bound to any cpu */ |
@@ -241,6 +247,8 @@ enum { | |||
241 | WQ_HIGHPRI = 1 << 4, /* high priority */ | 247 | WQ_HIGHPRI = 1 << 4, /* high priority */ |
242 | WQ_CPU_INTENSIVE = 1 << 5, /* cpu instensive workqueue */ | 248 | WQ_CPU_INTENSIVE = 1 << 5, /* cpu instensive workqueue */ |
243 | 249 | ||
250 | WQ_DYING = 1 << 6, /* internal: workqueue is dying */ | ||
251 | |||
244 | WQ_MAX_ACTIVE = 512, /* I like 512, better ideas? */ | 252 | WQ_MAX_ACTIVE = 512, /* I like 512, better ideas? */ |
245 | WQ_MAX_UNBOUND_PER_CPU = 4, /* 4 * #cpus for unbound wq */ | 253 | WQ_MAX_UNBOUND_PER_CPU = 4, /* 4 * #cpus for unbound wq */ |
246 | WQ_DFL_ACTIVE = WQ_MAX_ACTIVE / 2, | 254 | WQ_DFL_ACTIVE = WQ_MAX_ACTIVE / 2, |
diff --git a/include/media/videobuf-dma-sg.h b/include/media/videobuf-dma-sg.h index 97e07f46a0f..aa4ebb42a56 100644 --- a/include/media/videobuf-dma-sg.h +++ b/include/media/videobuf-dma-sg.h | |||
@@ -48,6 +48,7 @@ struct videobuf_dmabuf { | |||
48 | 48 | ||
49 | /* for userland buffer */ | 49 | /* for userland buffer */ |
50 | int offset; | 50 | int offset; |
51 | size_t size; | ||
51 | struct page **pages; | 52 | struct page **pages; |
52 | 53 | ||
53 | /* for kernel buffers */ | 54 | /* for kernel buffers */ |
diff --git a/include/net/addrconf.h b/include/net/addrconf.h index 45375b41a2a..4d40c4d0230 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h | |||
@@ -121,6 +121,7 @@ static inline int addrconf_finite_timeout(unsigned long timeout) | |||
121 | * IPv6 Address Label subsystem (addrlabel.c) | 121 | * IPv6 Address Label subsystem (addrlabel.c) |
122 | */ | 122 | */ |
123 | extern int ipv6_addr_label_init(void); | 123 | extern int ipv6_addr_label_init(void); |
124 | extern void ipv6_addr_label_cleanup(void); | ||
124 | extern void ipv6_addr_label_rtnl_register(void); | 125 | extern void ipv6_addr_label_rtnl_register(void); |
125 | extern u32 ipv6_addr_label(struct net *net, | 126 | extern u32 ipv6_addr_label(struct net *net, |
126 | const struct in6_addr *addr, | 127 | const struct in6_addr *addr, |
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 27a902d9b3a..30fce0128dd 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h | |||
@@ -161,12 +161,30 @@ static inline struct sk_buff *bt_skb_send_alloc(struct sock *sk, unsigned long l | |||
161 | { | 161 | { |
162 | struct sk_buff *skb; | 162 | struct sk_buff *skb; |
163 | 163 | ||
164 | release_sock(sk); | ||
164 | if ((skb = sock_alloc_send_skb(sk, len + BT_SKB_RESERVE, nb, err))) { | 165 | if ((skb = sock_alloc_send_skb(sk, len + BT_SKB_RESERVE, nb, err))) { |
165 | skb_reserve(skb, BT_SKB_RESERVE); | 166 | skb_reserve(skb, BT_SKB_RESERVE); |
166 | bt_cb(skb)->incoming = 0; | 167 | bt_cb(skb)->incoming = 0; |
167 | } | 168 | } |
169 | lock_sock(sk); | ||
170 | |||
171 | if (!skb && *err) | ||
172 | return NULL; | ||
173 | |||
174 | *err = sock_error(sk); | ||
175 | if (*err) | ||
176 | goto out; | ||
177 | |||
178 | if (sk->sk_shutdown) { | ||
179 | *err = -ECONNRESET; | ||
180 | goto out; | ||
181 | } | ||
168 | 182 | ||
169 | return skb; | 183 | return skb; |
184 | |||
185 | out: | ||
186 | kfree_skb(skb); | ||
187 | return NULL; | ||
170 | } | 188 | } |
171 | 189 | ||
172 | int bt_err(__u16 code); | 190 | int bt_err(__u16 code); |
diff --git a/include/net/cls_cgroup.h b/include/net/cls_cgroup.h index 726cc353640..ef6c24a529e 100644 --- a/include/net/cls_cgroup.h +++ b/include/net/cls_cgroup.h | |||
@@ -27,11 +27,17 @@ struct cgroup_cls_state | |||
27 | #ifdef CONFIG_NET_CLS_CGROUP | 27 | #ifdef CONFIG_NET_CLS_CGROUP |
28 | static inline u32 task_cls_classid(struct task_struct *p) | 28 | static inline u32 task_cls_classid(struct task_struct *p) |
29 | { | 29 | { |
30 | int classid; | ||
31 | |||
30 | if (in_interrupt()) | 32 | if (in_interrupt()) |
31 | return 0; | 33 | return 0; |
32 | 34 | ||
33 | return container_of(task_subsys_state(p, net_cls_subsys_id), | 35 | rcu_read_lock(); |
34 | struct cgroup_cls_state, css)->classid; | 36 | classid = container_of(task_subsys_state(p, net_cls_subsys_id), |
37 | struct cgroup_cls_state, css)->classid; | ||
38 | rcu_read_unlock(); | ||
39 | |||
40 | return classid; | ||
35 | } | 41 | } |
36 | #else | 42 | #else |
37 | extern int net_cls_subsys_id; | 43 | extern int net_cls_subsys_id; |
diff --git a/include/net/dst.h b/include/net/dst.h index 81d1413a870..02386505033 100644 --- a/include/net/dst.h +++ b/include/net/dst.h | |||
@@ -242,6 +242,7 @@ static inline void skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev) | |||
242 | dev->stats.rx_packets++; | 242 | dev->stats.rx_packets++; |
243 | dev->stats.rx_bytes += skb->len; | 243 | dev->stats.rx_bytes += skb->len; |
244 | skb->rxhash = 0; | 244 | skb->rxhash = 0; |
245 | skb_set_queue_mapping(skb, 0); | ||
245 | skb_dst_drop(skb); | 246 | skb_dst_drop(skb); |
246 | nf_reset(skb); | 247 | nf_reset(skb); |
247 | } | 248 | } |
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index a4747a0f730..f976885f686 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h | |||
@@ -955,6 +955,9 @@ static inline __wsum ip_vs_check_diff2(__be16 old, __be16 new, __wsum oldsum) | |||
955 | return csum_partial(diff, sizeof(diff), oldsum); | 955 | return csum_partial(diff, sizeof(diff), oldsum); |
956 | } | 956 | } |
957 | 957 | ||
958 | extern void ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp, | ||
959 | int outin); | ||
960 | |||
958 | #endif /* __KERNEL__ */ | 961 | #endif /* __KERNEL__ */ |
959 | 962 | ||
960 | #endif /* _NET_IP_VS_H */ | 963 | #endif /* _NET_IP_VS_H */ |
diff --git a/include/net/route.h b/include/net/route.h index bd732d62e1c..7e5e73bfa4d 100644 --- a/include/net/route.h +++ b/include/net/route.h | |||
@@ -199,6 +199,8 @@ static inline int ip_route_newports(struct rtable **rp, u8 protocol, | |||
199 | fl.fl_ip_sport = sport; | 199 | fl.fl_ip_sport = sport; |
200 | fl.fl_ip_dport = dport; | 200 | fl.fl_ip_dport = dport; |
201 | fl.proto = protocol; | 201 | fl.proto = protocol; |
202 | if (inet_sk(sk)->transparent) | ||
203 | fl.flags |= FLOWI_FLAG_ANYSRC; | ||
202 | ip_rt_put(*rp); | 204 | ip_rt_put(*rp); |
203 | *rp = NULL; | 205 | *rp = NULL; |
204 | security_sk_classify_flow(sk, &fl); | 206 | security_sk_classify_flow(sk, &fl); |
diff --git a/include/net/sock.h b/include/net/sock.h index ac53bfbdfe1..adab9dc5818 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
@@ -752,6 +752,7 @@ struct proto { | |||
752 | /* Keeping track of sk's, looking them up, and port selection methods. */ | 752 | /* Keeping track of sk's, looking them up, and port selection methods. */ |
753 | void (*hash)(struct sock *sk); | 753 | void (*hash)(struct sock *sk); |
754 | void (*unhash)(struct sock *sk); | 754 | void (*unhash)(struct sock *sk); |
755 | void (*rehash)(struct sock *sk); | ||
755 | int (*get_port)(struct sock *sk, unsigned short snum); | 756 | int (*get_port)(struct sock *sk, unsigned short snum); |
756 | 757 | ||
757 | /* Keeping track of sockets in use */ | 758 | /* Keeping track of sockets in use */ |
diff --git a/include/net/tcp.h b/include/net/tcp.h index df6a2eb2019..3e4b33e3660 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h | |||
@@ -268,11 +268,21 @@ static inline int between(__u32 seq1, __u32 seq2, __u32 seq3) | |||
268 | return seq3 - seq2 >= seq1 - seq2; | 268 | return seq3 - seq2 >= seq1 - seq2; |
269 | } | 269 | } |
270 | 270 | ||
271 | static inline int tcp_too_many_orphans(struct sock *sk, int num) | 271 | static inline bool tcp_too_many_orphans(struct sock *sk, int shift) |
272 | { | 272 | { |
273 | return (num > sysctl_tcp_max_orphans) || | 273 | struct percpu_counter *ocp = sk->sk_prot->orphan_count; |
274 | (sk->sk_wmem_queued > SOCK_MIN_SNDBUF && | 274 | int orphans = percpu_counter_read_positive(ocp); |
275 | atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2]); | 275 | |
276 | if (orphans << shift > sysctl_tcp_max_orphans) { | ||
277 | orphans = percpu_counter_sum_positive(ocp); | ||
278 | if (orphans << shift > sysctl_tcp_max_orphans) | ||
279 | return true; | ||
280 | } | ||
281 | |||
282 | if (sk->sk_wmem_queued > SOCK_MIN_SNDBUF && | ||
283 | atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2]) | ||
284 | return true; | ||
285 | return false; | ||
276 | } | 286 | } |
277 | 287 | ||
278 | /* syncookies: remember time of last synqueue overflow */ | 288 | /* syncookies: remember time of last synqueue overflow */ |
@@ -465,8 +475,22 @@ extern unsigned int tcp_current_mss(struct sock *sk); | |||
465 | /* Bound MSS / TSO packet size with the half of the window */ | 475 | /* Bound MSS / TSO packet size with the half of the window */ |
466 | static inline int tcp_bound_to_half_wnd(struct tcp_sock *tp, int pktsize) | 476 | static inline int tcp_bound_to_half_wnd(struct tcp_sock *tp, int pktsize) |
467 | { | 477 | { |
468 | if (tp->max_window && pktsize > (tp->max_window >> 1)) | 478 | int cutoff; |
469 | return max(tp->max_window >> 1, 68U - tp->tcp_header_len); | 479 | |
480 | /* When peer uses tiny windows, there is no use in packetizing | ||
481 | * to sub-MSS pieces for the sake of SWS or making sure there | ||
482 | * are enough packets in the pipe for fast recovery. | ||
483 | * | ||
484 | * On the other hand, for extremely large MSS devices, handling | ||
485 | * smaller than MSS windows in this way does make sense. | ||
486 | */ | ||
487 | if (tp->max_window >= 512) | ||
488 | cutoff = (tp->max_window >> 1); | ||
489 | else | ||
490 | cutoff = tp->max_window; | ||
491 | |||
492 | if (cutoff && pktsize > cutoff) | ||
493 | return max_t(int, cutoff, 68U - tp->tcp_header_len); | ||
470 | else | 494 | else |
471 | return pktsize; | 495 | return pktsize; |
472 | } | 496 | } |
diff --git a/include/net/udp.h b/include/net/udp.h index 7abdf305da5..a184d3496b1 100644 --- a/include/net/udp.h +++ b/include/net/udp.h | |||
@@ -151,6 +151,7 @@ static inline void udp_lib_hash(struct sock *sk) | |||
151 | } | 151 | } |
152 | 152 | ||
153 | extern void udp_lib_unhash(struct sock *sk); | 153 | extern void udp_lib_unhash(struct sock *sk); |
154 | extern void udp_lib_rehash(struct sock *sk, u16 new_hash); | ||
154 | 155 | ||
155 | static inline void udp_lib_close(struct sock *sk, long timeout) | 156 | static inline void udp_lib_close(struct sock *sk, long timeout) |
156 | { | 157 | { |
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index fc8f36dd0f5..4f53532d4c2 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
@@ -298,8 +298,8 @@ struct xfrm_state_afinfo { | |||
298 | const struct xfrm_type *type_map[IPPROTO_MAX]; | 298 | const struct xfrm_type *type_map[IPPROTO_MAX]; |
299 | struct xfrm_mode *mode_map[XFRM_MODE_MAX]; | 299 | struct xfrm_mode *mode_map[XFRM_MODE_MAX]; |
300 | int (*init_flags)(struct xfrm_state *x); | 300 | int (*init_flags)(struct xfrm_state *x); |
301 | void (*init_tempsel)(struct xfrm_state *x, struct flowi *fl, | 301 | void (*init_tempsel)(struct xfrm_selector *sel, struct flowi *fl); |
302 | struct xfrm_tmpl *tmpl, | 302 | void (*init_temprop)(struct xfrm_state *x, struct xfrm_tmpl *tmpl, |
303 | xfrm_address_t *daddr, xfrm_address_t *saddr); | 303 | xfrm_address_t *daddr, xfrm_address_t *saddr); |
304 | int (*tmpl_sort)(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n); | 304 | int (*tmpl_sort)(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n); |
305 | int (*state_sort)(struct xfrm_state **dst, struct xfrm_state **src, int n); | 305 | int (*state_sort)(struct xfrm_state **dst, struct xfrm_state **src, int n); |
diff --git a/include/trace/events/timer.h b/include/trace/events/timer.h index c624126a9c8..425bcfe56c6 100644 --- a/include/trace/events/timer.h +++ b/include/trace/events/timer.h | |||
@@ -81,14 +81,16 @@ TRACE_EVENT(timer_expire_entry, | |||
81 | TP_STRUCT__entry( | 81 | TP_STRUCT__entry( |
82 | __field( void *, timer ) | 82 | __field( void *, timer ) |
83 | __field( unsigned long, now ) | 83 | __field( unsigned long, now ) |
84 | __field( void *, function) | ||
84 | ), | 85 | ), |
85 | 86 | ||
86 | TP_fast_assign( | 87 | TP_fast_assign( |
87 | __entry->timer = timer; | 88 | __entry->timer = timer; |
88 | __entry->now = jiffies; | 89 | __entry->now = jiffies; |
90 | __entry->function = timer->function; | ||
89 | ), | 91 | ), |
90 | 92 | ||
91 | TP_printk("timer=%p now=%lu", __entry->timer, __entry->now) | 93 | TP_printk("timer=%p function=%pf now=%lu", __entry->timer, __entry->function,__entry->now) |
92 | ); | 94 | ); |
93 | 95 | ||
94 | /** | 96 | /** |
@@ -200,14 +202,16 @@ TRACE_EVENT(hrtimer_expire_entry, | |||
200 | TP_STRUCT__entry( | 202 | TP_STRUCT__entry( |
201 | __field( void *, hrtimer ) | 203 | __field( void *, hrtimer ) |
202 | __field( s64, now ) | 204 | __field( s64, now ) |
205 | __field( void *, function) | ||
203 | ), | 206 | ), |
204 | 207 | ||
205 | TP_fast_assign( | 208 | TP_fast_assign( |
206 | __entry->hrtimer = hrtimer; | 209 | __entry->hrtimer = hrtimer; |
207 | __entry->now = now->tv64; | 210 | __entry->now = now->tv64; |
211 | __entry->function = hrtimer->function; | ||
208 | ), | 212 | ), |
209 | 213 | ||
210 | TP_printk("hrtimer=%p now=%llu", __entry->hrtimer, | 214 | TP_printk("hrtimer=%p function=%pf now=%llu", __entry->hrtimer, __entry->function, |
211 | (unsigned long long)ktime_to_ns((ktime_t) { .tv64 = __entry->now })) | 215 | (unsigned long long)ktime_to_ns((ktime_t) { .tv64 = __entry->now })) |
212 | ); | 216 | ); |
213 | 217 | ||
diff --git a/include/xen/platform_pci.h b/include/xen/platform_pci.h index ce9d671c636..a785a3b0c8c 100644 --- a/include/xen/platform_pci.h +++ b/include/xen/platform_pci.h | |||
@@ -16,11 +16,15 @@ | |||
16 | #define XEN_IOPORT_PROTOVER (XEN_IOPORT_BASE + 2) /* 1 byte access (R) */ | 16 | #define XEN_IOPORT_PROTOVER (XEN_IOPORT_BASE + 2) /* 1 byte access (R) */ |
17 | #define XEN_IOPORT_PRODNUM (XEN_IOPORT_BASE + 2) /* 2 byte access (W) */ | 17 | #define XEN_IOPORT_PRODNUM (XEN_IOPORT_BASE + 2) /* 2 byte access (W) */ |
18 | 18 | ||
19 | #define XEN_UNPLUG_ALL_IDE_DISKS 1 | 19 | #define XEN_UNPLUG_ALL_IDE_DISKS (1<<0) |
20 | #define XEN_UNPLUG_ALL_NICS 2 | 20 | #define XEN_UNPLUG_ALL_NICS (1<<1) |
21 | #define XEN_UNPLUG_AUX_IDE_DISKS 4 | 21 | #define XEN_UNPLUG_AUX_IDE_DISKS (1<<2) |
22 | #define XEN_UNPLUG_ALL 7 | 22 | #define XEN_UNPLUG_ALL (XEN_UNPLUG_ALL_IDE_DISKS|\ |
23 | #define XEN_UNPLUG_IGNORE 8 | 23 | XEN_UNPLUG_ALL_NICS|\ |
24 | XEN_UNPLUG_AUX_IDE_DISKS) | ||
25 | |||
26 | #define XEN_UNPLUG_UNNECESSARY (1<<16) | ||
27 | #define XEN_UNPLUG_NEVER (1<<17) | ||
24 | 28 | ||
25 | static inline int xen_must_unplug_nics(void) { | 29 | static inline int xen_must_unplug_nics(void) { |
26 | #if (defined(CONFIG_XEN_NETDEV_FRONTEND) || \ | 30 | #if (defined(CONFIG_XEN_NETDEV_FRONTEND) || \ |
@@ -743,6 +743,8 @@ static unsigned long copy_semid_to_user(void __user *buf, struct semid64_ds *in, | |||
743 | { | 743 | { |
744 | struct semid_ds out; | 744 | struct semid_ds out; |
745 | 745 | ||
746 | memset(&out, 0, sizeof(out)); | ||
747 | |||
746 | ipc64_perm_to_ipc_perm(&in->sem_perm, &out.sem_perm); | 748 | ipc64_perm_to_ipc_perm(&in->sem_perm, &out.sem_perm); |
747 | 749 | ||
748 | out.sem_otime = in->sem_otime; | 750 | out.sem_otime = in->sem_otime; |
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 192f88c5b0f..c9483d8f614 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -1791,19 +1791,20 @@ out: | |||
1791 | } | 1791 | } |
1792 | 1792 | ||
1793 | /** | 1793 | /** |
1794 | * cgroup_attach_task_current_cg - attach task 'tsk' to current task's cgroup | 1794 | * cgroup_attach_task_all - attach task 'tsk' to all cgroups of task 'from' |
1795 | * @from: attach to all cgroups of a given task | ||
1795 | * @tsk: the task to be attached | 1796 | * @tsk: the task to be attached |
1796 | */ | 1797 | */ |
1797 | int cgroup_attach_task_current_cg(struct task_struct *tsk) | 1798 | int cgroup_attach_task_all(struct task_struct *from, struct task_struct *tsk) |
1798 | { | 1799 | { |
1799 | struct cgroupfs_root *root; | 1800 | struct cgroupfs_root *root; |
1800 | struct cgroup *cur_cg; | ||
1801 | int retval = 0; | 1801 | int retval = 0; |
1802 | 1802 | ||
1803 | cgroup_lock(); | 1803 | cgroup_lock(); |
1804 | for_each_active_root(root) { | 1804 | for_each_active_root(root) { |
1805 | cur_cg = task_cgroup_from_root(current, root); | 1805 | struct cgroup *from_cg = task_cgroup_from_root(from, root); |
1806 | retval = cgroup_attach_task(cur_cg, tsk); | 1806 | |
1807 | retval = cgroup_attach_task(from_cg, tsk); | ||
1807 | if (retval) | 1808 | if (retval) |
1808 | break; | 1809 | break; |
1809 | } | 1810 | } |
@@ -1811,7 +1812,7 @@ int cgroup_attach_task_current_cg(struct task_struct *tsk) | |||
1811 | 1812 | ||
1812 | return retval; | 1813 | return retval; |
1813 | } | 1814 | } |
1814 | EXPORT_SYMBOL_GPL(cgroup_attach_task_current_cg); | 1815 | EXPORT_SYMBOL_GPL(cgroup_attach_task_all); |
1815 | 1816 | ||
1816 | /* | 1817 | /* |
1817 | * Attach task with pid 'pid' to cgroup 'cgrp'. Call with cgroup_mutex | 1818 | * Attach task with pid 'pid' to cgroup 'cgrp'. Call with cgroup_mutex |
diff --git a/kernel/compat.c b/kernel/compat.c index e167efce842..c9e2ec0b34a 100644 --- a/kernel/compat.c +++ b/kernel/compat.c | |||
@@ -1126,3 +1126,24 @@ compat_sys_sysinfo(struct compat_sysinfo __user *info) | |||
1126 | 1126 | ||
1127 | return 0; | 1127 | return 0; |
1128 | } | 1128 | } |
1129 | |||
1130 | /* | ||
1131 | * Allocate user-space memory for the duration of a single system call, | ||
1132 | * in order to marshall parameters inside a compat thunk. | ||
1133 | */ | ||
1134 | void __user *compat_alloc_user_space(unsigned long len) | ||
1135 | { | ||
1136 | void __user *ptr; | ||
1137 | |||
1138 | /* If len would occupy more than half of the entire compat space... */ | ||
1139 | if (unlikely(len > (((compat_uptr_t)~0) >> 1))) | ||
1140 | return NULL; | ||
1141 | |||
1142 | ptr = arch_compat_alloc_user_space(len); | ||
1143 | |||
1144 | if (unlikely(!access_ok(VERIFY_WRITE, ptr, len))) | ||
1145 | return NULL; | ||
1146 | |||
1147 | return ptr; | ||
1148 | } | ||
1149 | EXPORT_SYMBOL_GPL(compat_alloc_user_space); | ||
diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c index 3c2d4972d23..de407c78178 100644 --- a/kernel/debug/debug_core.c +++ b/kernel/debug/debug_core.c | |||
@@ -741,7 +741,7 @@ static struct console kgdbcons = { | |||
741 | }; | 741 | }; |
742 | 742 | ||
743 | #ifdef CONFIG_MAGIC_SYSRQ | 743 | #ifdef CONFIG_MAGIC_SYSRQ |
744 | static void sysrq_handle_dbg(int key, struct tty_struct *tty) | 744 | static void sysrq_handle_dbg(int key) |
745 | { | 745 | { |
746 | if (!dbg_io_ops) { | 746 | if (!dbg_io_ops) { |
747 | printk(KERN_CRIT "ERROR: No KGDB I/O module available\n"); | 747 | printk(KERN_CRIT "ERROR: No KGDB I/O module available\n"); |
diff --git a/kernel/debug/kdb/kdb_bp.c b/kernel/debug/kdb/kdb_bp.c index 75bd9b3ebbb..20059ef4459 100644 --- a/kernel/debug/kdb/kdb_bp.c +++ b/kernel/debug/kdb/kdb_bp.c | |||
@@ -274,7 +274,6 @@ static int kdb_bp(int argc, const char **argv) | |||
274 | int i, bpno; | 274 | int i, bpno; |
275 | kdb_bp_t *bp, *bp_check; | 275 | kdb_bp_t *bp, *bp_check; |
276 | int diag; | 276 | int diag; |
277 | int free; | ||
278 | char *symname = NULL; | 277 | char *symname = NULL; |
279 | long offset = 0ul; | 278 | long offset = 0ul; |
280 | int nextarg; | 279 | int nextarg; |
@@ -305,7 +304,6 @@ static int kdb_bp(int argc, const char **argv) | |||
305 | /* | 304 | /* |
306 | * Find an empty bp structure to allocate | 305 | * Find an empty bp structure to allocate |
307 | */ | 306 | */ |
308 | free = KDB_MAXBPT; | ||
309 | for (bpno = 0, bp = kdb_breakpoints; bpno < KDB_MAXBPT; bpno++, bp++) { | 307 | for (bpno = 0, bp = kdb_breakpoints; bpno < KDB_MAXBPT; bpno++, bp++) { |
310 | if (bp->bp_free) | 308 | if (bp->bp_free) |
311 | break; | 309 | break; |
diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c index 28b844118bb..caf057a3de0 100644 --- a/kernel/debug/kdb/kdb_main.c +++ b/kernel/debug/kdb/kdb_main.c | |||
@@ -1929,7 +1929,7 @@ static int kdb_sr(int argc, const char **argv) | |||
1929 | if (argc != 1) | 1929 | if (argc != 1) |
1930 | return KDB_ARGCOUNT; | 1930 | return KDB_ARGCOUNT; |
1931 | kdb_trap_printk++; | 1931 | kdb_trap_printk++; |
1932 | __handle_sysrq(*argv[1], NULL, 0); | 1932 | __handle_sysrq(*argv[1], false); |
1933 | kdb_trap_printk--; | 1933 | kdb_trap_printk--; |
1934 | 1934 | ||
1935 | return 0; | 1935 | return 0; |
diff --git a/kernel/fork.c b/kernel/fork.c index b7e9d60a675..c445f8cc408 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -356,10 +356,10 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) | |||
356 | if (IS_ERR(pol)) | 356 | if (IS_ERR(pol)) |
357 | goto fail_nomem_policy; | 357 | goto fail_nomem_policy; |
358 | vma_set_policy(tmp, pol); | 358 | vma_set_policy(tmp, pol); |
359 | tmp->vm_mm = mm; | ||
359 | if (anon_vma_fork(tmp, mpnt)) | 360 | if (anon_vma_fork(tmp, mpnt)) |
360 | goto fail_nomem_anon_vma_fork; | 361 | goto fail_nomem_anon_vma_fork; |
361 | tmp->vm_flags &= ~VM_LOCKED; | 362 | tmp->vm_flags &= ~VM_LOCKED; |
362 | tmp->vm_mm = mm; | ||
363 | tmp->vm_next = tmp->vm_prev = NULL; | 363 | tmp->vm_next = tmp->vm_prev = NULL; |
364 | file = tmp->vm_file; | 364 | file = tmp->vm_file; |
365 | if (file) { | 365 | if (file) { |
diff --git a/kernel/gcov/fs.c b/kernel/gcov/fs.c index ef3c3f88a7a..f83972b1656 100644 --- a/kernel/gcov/fs.c +++ b/kernel/gcov/fs.c | |||
@@ -33,10 +33,11 @@ | |||
33 | * @children: child nodes | 33 | * @children: child nodes |
34 | * @all: list head for list of all nodes | 34 | * @all: list head for list of all nodes |
35 | * @parent: parent node | 35 | * @parent: parent node |
36 | * @info: associated profiling data structure if not a directory | 36 | * @loaded_info: array of pointers to profiling data sets for loaded object |
37 | * @ghost: when an object file containing profiling data is unloaded we keep a | 37 | * files. |
38 | * copy of the profiling data here to allow collecting coverage data | 38 | * @num_loaded: number of profiling data sets for loaded object files. |
39 | * for cleanup code. Such a node is called a "ghost". | 39 | * @unloaded_info: accumulated copy of profiling data sets for unloaded |
40 | * object files. Used only when gcov_persist=1. | ||
40 | * @dentry: main debugfs entry, either a directory or data file | 41 | * @dentry: main debugfs entry, either a directory or data file |
41 | * @links: associated symbolic links | 42 | * @links: associated symbolic links |
42 | * @name: data file basename | 43 | * @name: data file basename |
@@ -51,10 +52,11 @@ struct gcov_node { | |||
51 | struct list_head children; | 52 | struct list_head children; |
52 | struct list_head all; | 53 | struct list_head all; |
53 | struct gcov_node *parent; | 54 | struct gcov_node *parent; |
54 | struct gcov_info *info; | 55 | struct gcov_info **loaded_info; |
55 | struct gcov_info *ghost; | 56 | struct gcov_info *unloaded_info; |
56 | struct dentry *dentry; | 57 | struct dentry *dentry; |
57 | struct dentry **links; | 58 | struct dentry **links; |
59 | int num_loaded; | ||
58 | char name[0]; | 60 | char name[0]; |
59 | }; | 61 | }; |
60 | 62 | ||
@@ -136,16 +138,37 @@ static const struct seq_operations gcov_seq_ops = { | |||
136 | }; | 138 | }; |
137 | 139 | ||
138 | /* | 140 | /* |
139 | * Return the profiling data set for a given node. This can either be the | 141 | * Return a profiling data set associated with the given node. This is |
140 | * original profiling data structure or a duplicate (also called "ghost") | 142 | * either a data set for a loaded object file or a data set copy in case |
141 | * in case the associated object file has been unloaded. | 143 | * all associated object files have been unloaded. |
142 | */ | 144 | */ |
143 | static struct gcov_info *get_node_info(struct gcov_node *node) | 145 | static struct gcov_info *get_node_info(struct gcov_node *node) |
144 | { | 146 | { |
145 | if (node->info) | 147 | if (node->num_loaded > 0) |
146 | return node->info; | 148 | return node->loaded_info[0]; |
147 | 149 | ||
148 | return node->ghost; | 150 | return node->unloaded_info; |
151 | } | ||
152 | |||
153 | /* | ||
154 | * Return a newly allocated profiling data set which contains the sum of | ||
155 | * all profiling data associated with the given node. | ||
156 | */ | ||
157 | static struct gcov_info *get_accumulated_info(struct gcov_node *node) | ||
158 | { | ||
159 | struct gcov_info *info; | ||
160 | int i = 0; | ||
161 | |||
162 | if (node->unloaded_info) | ||
163 | info = gcov_info_dup(node->unloaded_info); | ||
164 | else | ||
165 | info = gcov_info_dup(node->loaded_info[i++]); | ||
166 | if (!info) | ||
167 | return NULL; | ||
168 | for (; i < node->num_loaded; i++) | ||
169 | gcov_info_add(info, node->loaded_info[i]); | ||
170 | |||
171 | return info; | ||
149 | } | 172 | } |
150 | 173 | ||
151 | /* | 174 | /* |
@@ -163,9 +186,10 @@ static int gcov_seq_open(struct inode *inode, struct file *file) | |||
163 | mutex_lock(&node_lock); | 186 | mutex_lock(&node_lock); |
164 | /* | 187 | /* |
165 | * Read from a profiling data copy to minimize reference tracking | 188 | * Read from a profiling data copy to minimize reference tracking |
166 | * complexity and concurrent access. | 189 | * complexity and concurrent access and to keep accumulating multiple |
190 | * profiling data sets associated with one node simple. | ||
167 | */ | 191 | */ |
168 | info = gcov_info_dup(get_node_info(node)); | 192 | info = get_accumulated_info(node); |
169 | if (!info) | 193 | if (!info) |
170 | goto out_unlock; | 194 | goto out_unlock; |
171 | iter = gcov_iter_new(info); | 195 | iter = gcov_iter_new(info); |
@@ -225,12 +249,25 @@ static struct gcov_node *get_node_by_name(const char *name) | |||
225 | return NULL; | 249 | return NULL; |
226 | } | 250 | } |
227 | 251 | ||
252 | /* | ||
253 | * Reset all profiling data associated with the specified node. | ||
254 | */ | ||
255 | static void reset_node(struct gcov_node *node) | ||
256 | { | ||
257 | int i; | ||
258 | |||
259 | if (node->unloaded_info) | ||
260 | gcov_info_reset(node->unloaded_info); | ||
261 | for (i = 0; i < node->num_loaded; i++) | ||
262 | gcov_info_reset(node->loaded_info[i]); | ||
263 | } | ||
264 | |||
228 | static void remove_node(struct gcov_node *node); | 265 | static void remove_node(struct gcov_node *node); |
229 | 266 | ||
230 | /* | 267 | /* |
231 | * write() implementation for gcov data files. Reset profiling data for the | 268 | * write() implementation for gcov data files. Reset profiling data for the |
232 | * associated file. If the object file has been unloaded (i.e. this is | 269 | * corresponding file. If all associated object files have been unloaded, |
233 | * a "ghost" node), remove the debug fs node as well. | 270 | * remove the debug fs node as well. |
234 | */ | 271 | */ |
235 | static ssize_t gcov_seq_write(struct file *file, const char __user *addr, | 272 | static ssize_t gcov_seq_write(struct file *file, const char __user *addr, |
236 | size_t len, loff_t *pos) | 273 | size_t len, loff_t *pos) |
@@ -245,10 +282,10 @@ static ssize_t gcov_seq_write(struct file *file, const char __user *addr, | |||
245 | node = get_node_by_name(info->filename); | 282 | node = get_node_by_name(info->filename); |
246 | if (node) { | 283 | if (node) { |
247 | /* Reset counts or remove node for unloaded modules. */ | 284 | /* Reset counts or remove node for unloaded modules. */ |
248 | if (node->ghost) | 285 | if (node->num_loaded == 0) |
249 | remove_node(node); | 286 | remove_node(node); |
250 | else | 287 | else |
251 | gcov_info_reset(node->info); | 288 | reset_node(node); |
252 | } | 289 | } |
253 | /* Reset counts for open file. */ | 290 | /* Reset counts for open file. */ |
254 | gcov_info_reset(info); | 291 | gcov_info_reset(info); |
@@ -378,7 +415,10 @@ static void init_node(struct gcov_node *node, struct gcov_info *info, | |||
378 | INIT_LIST_HEAD(&node->list); | 415 | INIT_LIST_HEAD(&node->list); |
379 | INIT_LIST_HEAD(&node->children); | 416 | INIT_LIST_HEAD(&node->children); |
380 | INIT_LIST_HEAD(&node->all); | 417 | INIT_LIST_HEAD(&node->all); |
381 | node->info = info; | 418 | if (node->loaded_info) { |
419 | node->loaded_info[0] = info; | ||
420 | node->num_loaded = 1; | ||
421 | } | ||
382 | node->parent = parent; | 422 | node->parent = parent; |
383 | if (name) | 423 | if (name) |
384 | strcpy(node->name, name); | 424 | strcpy(node->name, name); |
@@ -394,9 +434,13 @@ static struct gcov_node *new_node(struct gcov_node *parent, | |||
394 | struct gcov_node *node; | 434 | struct gcov_node *node; |
395 | 435 | ||
396 | node = kzalloc(sizeof(struct gcov_node) + strlen(name) + 1, GFP_KERNEL); | 436 | node = kzalloc(sizeof(struct gcov_node) + strlen(name) + 1, GFP_KERNEL); |
397 | if (!node) { | 437 | if (!node) |
398 | pr_warning("out of memory\n"); | 438 | goto err_nomem; |
399 | return NULL; | 439 | if (info) { |
440 | node->loaded_info = kcalloc(1, sizeof(struct gcov_info *), | ||
441 | GFP_KERNEL); | ||
442 | if (!node->loaded_info) | ||
443 | goto err_nomem; | ||
400 | } | 444 | } |
401 | init_node(node, info, name, parent); | 445 | init_node(node, info, name, parent); |
402 | /* Differentiate between gcov data file nodes and directory nodes. */ | 446 | /* Differentiate between gcov data file nodes and directory nodes. */ |
@@ -416,6 +460,11 @@ static struct gcov_node *new_node(struct gcov_node *parent, | |||
416 | list_add(&node->all, &all_head); | 460 | list_add(&node->all, &all_head); |
417 | 461 | ||
418 | return node; | 462 | return node; |
463 | |||
464 | err_nomem: | ||
465 | kfree(node); | ||
466 | pr_warning("out of memory\n"); | ||
467 | return NULL; | ||
419 | } | 468 | } |
420 | 469 | ||
421 | /* Remove symbolic links associated with node. */ | 470 | /* Remove symbolic links associated with node. */ |
@@ -441,8 +490,9 @@ static void release_node(struct gcov_node *node) | |||
441 | list_del(&node->all); | 490 | list_del(&node->all); |
442 | debugfs_remove(node->dentry); | 491 | debugfs_remove(node->dentry); |
443 | remove_links(node); | 492 | remove_links(node); |
444 | if (node->ghost) | 493 | kfree(node->loaded_info); |
445 | gcov_info_free(node->ghost); | 494 | if (node->unloaded_info) |
495 | gcov_info_free(node->unloaded_info); | ||
446 | kfree(node); | 496 | kfree(node); |
447 | } | 497 | } |
448 | 498 | ||
@@ -477,7 +527,7 @@ static struct gcov_node *get_child_by_name(struct gcov_node *parent, | |||
477 | 527 | ||
478 | /* | 528 | /* |
479 | * write() implementation for reset file. Reset all profiling data to zero | 529 | * write() implementation for reset file. Reset all profiling data to zero |
480 | * and remove ghost nodes. | 530 | * and remove nodes for which all associated object files are unloaded. |
481 | */ | 531 | */ |
482 | static ssize_t reset_write(struct file *file, const char __user *addr, | 532 | static ssize_t reset_write(struct file *file, const char __user *addr, |
483 | size_t len, loff_t *pos) | 533 | size_t len, loff_t *pos) |
@@ -487,8 +537,8 @@ static ssize_t reset_write(struct file *file, const char __user *addr, | |||
487 | mutex_lock(&node_lock); | 537 | mutex_lock(&node_lock); |
488 | restart: | 538 | restart: |
489 | list_for_each_entry(node, &all_head, all) { | 539 | list_for_each_entry(node, &all_head, all) { |
490 | if (node->info) | 540 | if (node->num_loaded > 0) |
491 | gcov_info_reset(node->info); | 541 | reset_node(node); |
492 | else if (list_empty(&node->children)) { | 542 | else if (list_empty(&node->children)) { |
493 | remove_node(node); | 543 | remove_node(node); |
494 | /* Several nodes may have gone - restart loop. */ | 544 | /* Several nodes may have gone - restart loop. */ |
@@ -564,37 +614,115 @@ err_remove: | |||
564 | } | 614 | } |
565 | 615 | ||
566 | /* | 616 | /* |
567 | * The profiling data set associated with this node is being unloaded. Store a | 617 | * Associate a profiling data set with an existing node. Needs to be called |
568 | * copy of the profiling data and turn this node into a "ghost". | 618 | * with node_lock held. |
569 | */ | 619 | */ |
570 | static int ghost_node(struct gcov_node *node) | 620 | static void add_info(struct gcov_node *node, struct gcov_info *info) |
571 | { | 621 | { |
572 | node->ghost = gcov_info_dup(node->info); | 622 | struct gcov_info **loaded_info; |
573 | if (!node->ghost) { | 623 | int num = node->num_loaded; |
574 | pr_warning("could not save data for '%s' (out of memory)\n", | 624 | |
575 | node->info->filename); | 625 | /* |
576 | return -ENOMEM; | 626 | * Prepare new array. This is done first to simplify cleanup in |
627 | * case the new data set is incompatible, the node only contains | ||
628 | * unloaded data sets and there's not enough memory for the array. | ||
629 | */ | ||
630 | loaded_info = kcalloc(num + 1, sizeof(struct gcov_info *), GFP_KERNEL); | ||
631 | if (!loaded_info) { | ||
632 | pr_warning("could not add '%s' (out of memory)\n", | ||
633 | info->filename); | ||
634 | return; | ||
635 | } | ||
636 | memcpy(loaded_info, node->loaded_info, | ||
637 | num * sizeof(struct gcov_info *)); | ||
638 | loaded_info[num] = info; | ||
639 | /* Check if the new data set is compatible. */ | ||
640 | if (num == 0) { | ||
641 | /* | ||
642 | * A module was unloaded, modified and reloaded. The new | ||
643 | * data set replaces the copy of the last one. | ||
644 | */ | ||
645 | if (!gcov_info_is_compatible(node->unloaded_info, info)) { | ||
646 | pr_warning("discarding saved data for %s " | ||
647 | "(incompatible version)\n", info->filename); | ||
648 | gcov_info_free(node->unloaded_info); | ||
649 | node->unloaded_info = NULL; | ||
650 | } | ||
651 | } else { | ||
652 | /* | ||
653 | * Two different versions of the same object file are loaded. | ||
654 | * The initial one takes precedence. | ||
655 | */ | ||
656 | if (!gcov_info_is_compatible(node->loaded_info[0], info)) { | ||
657 | pr_warning("could not add '%s' (incompatible " | ||
658 | "version)\n", info->filename); | ||
659 | kfree(loaded_info); | ||
660 | return; | ||
661 | } | ||
577 | } | 662 | } |
578 | node->info = NULL; | 663 | /* Overwrite previous array. */ |
664 | kfree(node->loaded_info); | ||
665 | node->loaded_info = loaded_info; | ||
666 | node->num_loaded = num + 1; | ||
667 | } | ||
579 | 668 | ||
580 | return 0; | 669 | /* |
670 | * Return the index of a profiling data set associated with a node. | ||
671 | */ | ||
672 | static int get_info_index(struct gcov_node *node, struct gcov_info *info) | ||
673 | { | ||
674 | int i; | ||
675 | |||
676 | for (i = 0; i < node->num_loaded; i++) { | ||
677 | if (node->loaded_info[i] == info) | ||
678 | return i; | ||
679 | } | ||
680 | return -ENOENT; | ||
581 | } | 681 | } |
582 | 682 | ||
583 | /* | 683 | /* |
584 | * Profiling data for this node has been loaded again. Add profiling data | 684 | * Save the data of a profiling data set which is being unloaded. |
585 | * from previous instantiation and turn this node into a regular node. | ||
586 | */ | 685 | */ |
587 | static void revive_node(struct gcov_node *node, struct gcov_info *info) | 686 | static void save_info(struct gcov_node *node, struct gcov_info *info) |
588 | { | 687 | { |
589 | if (gcov_info_is_compatible(node->ghost, info)) | 688 | if (node->unloaded_info) |
590 | gcov_info_add(info, node->ghost); | 689 | gcov_info_add(node->unloaded_info, info); |
591 | else { | 690 | else { |
592 | pr_warning("discarding saved data for '%s' (version changed)\n", | 691 | node->unloaded_info = gcov_info_dup(info); |
692 | if (!node->unloaded_info) { | ||
693 | pr_warning("could not save data for '%s' " | ||
694 | "(out of memory)\n", info->filename); | ||
695 | } | ||
696 | } | ||
697 | } | ||
698 | |||
699 | /* | ||
700 | * Disassociate a profiling data set from a node. Needs to be called with | ||
701 | * node_lock held. | ||
702 | */ | ||
703 | static void remove_info(struct gcov_node *node, struct gcov_info *info) | ||
704 | { | ||
705 | int i; | ||
706 | |||
707 | i = get_info_index(node, info); | ||
708 | if (i < 0) { | ||
709 | pr_warning("could not remove '%s' (not found)\n", | ||
593 | info->filename); | 710 | info->filename); |
711 | return; | ||
594 | } | 712 | } |
595 | gcov_info_free(node->ghost); | 713 | if (gcov_persist) |
596 | node->ghost = NULL; | 714 | save_info(node, info); |
597 | node->info = info; | 715 | /* Shrink array. */ |
716 | node->loaded_info[i] = node->loaded_info[node->num_loaded - 1]; | ||
717 | node->num_loaded--; | ||
718 | if (node->num_loaded > 0) | ||
719 | return; | ||
720 | /* Last loaded data set was removed. */ | ||
721 | kfree(node->loaded_info); | ||
722 | node->loaded_info = NULL; | ||
723 | node->num_loaded = 0; | ||
724 | if (!node->unloaded_info) | ||
725 | remove_node(node); | ||
598 | } | 726 | } |
599 | 727 | ||
600 | /* | 728 | /* |
@@ -609,30 +737,18 @@ void gcov_event(enum gcov_action action, struct gcov_info *info) | |||
609 | node = get_node_by_name(info->filename); | 737 | node = get_node_by_name(info->filename); |
610 | switch (action) { | 738 | switch (action) { |
611 | case GCOV_ADD: | 739 | case GCOV_ADD: |
612 | /* Add new node or revive ghost. */ | 740 | if (node) |
613 | if (!node) { | 741 | add_info(node, info); |
742 | else | ||
614 | add_node(info); | 743 | add_node(info); |
615 | break; | ||
616 | } | ||
617 | if (gcov_persist) | ||
618 | revive_node(node, info); | ||
619 | else { | ||
620 | pr_warning("could not add '%s' (already exists)\n", | ||
621 | info->filename); | ||
622 | } | ||
623 | break; | 744 | break; |
624 | case GCOV_REMOVE: | 745 | case GCOV_REMOVE: |
625 | /* Remove node or turn into ghost. */ | 746 | if (node) |
626 | if (!node) { | 747 | remove_info(node, info); |
748 | else { | ||
627 | pr_warning("could not remove '%s' (not found)\n", | 749 | pr_warning("could not remove '%s' (not found)\n", |
628 | info->filename); | 750 | info->filename); |
629 | break; | ||
630 | } | 751 | } |
631 | if (gcov_persist) { | ||
632 | if (!ghost_node(node)) | ||
633 | break; | ||
634 | } | ||
635 | remove_node(node); | ||
636 | break; | 752 | break; |
637 | } | 753 | } |
638 | mutex_unlock(&node_lock); | 754 | mutex_unlock(&node_lock); |
diff --git a/kernel/groups.c b/kernel/groups.c index 53b1916c949..253dc0f35cf 100644 --- a/kernel/groups.c +++ b/kernel/groups.c | |||
@@ -143,10 +143,9 @@ int groups_search(const struct group_info *group_info, gid_t grp) | |||
143 | right = group_info->ngroups; | 143 | right = group_info->ngroups; |
144 | while (left < right) { | 144 | while (left < right) { |
145 | unsigned int mid = (left+right)/2; | 145 | unsigned int mid = (left+right)/2; |
146 | int cmp = grp - GROUP_AT(group_info, mid); | 146 | if (grp > GROUP_AT(group_info, mid)) |
147 | if (cmp > 0) | ||
148 | left = mid + 1; | 147 | left = mid + 1; |
149 | else if (cmp < 0) | 148 | else if (grp < GROUP_AT(group_info, mid)) |
150 | right = mid; | 149 | right = mid; |
151 | else | 150 | else |
152 | return 1; | 151 | return 1; |
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index ce669174f35..1decafbb6b1 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c | |||
@@ -1091,11 +1091,10 @@ EXPORT_SYMBOL_GPL(hrtimer_cancel); | |||
1091 | */ | 1091 | */ |
1092 | ktime_t hrtimer_get_remaining(const struct hrtimer *timer) | 1092 | ktime_t hrtimer_get_remaining(const struct hrtimer *timer) |
1093 | { | 1093 | { |
1094 | struct hrtimer_clock_base *base; | ||
1095 | unsigned long flags; | 1094 | unsigned long flags; |
1096 | ktime_t rem; | 1095 | ktime_t rem; |
1097 | 1096 | ||
1098 | base = lock_hrtimer_base(timer, &flags); | 1097 | lock_hrtimer_base(timer, &flags); |
1099 | rem = hrtimer_expires_remaining(timer); | 1098 | rem = hrtimer_expires_remaining(timer); |
1100 | unlock_hrtimer_base(timer, &flags); | 1099 | unlock_hrtimer_base(timer, &flags); |
1101 | 1100 | ||
diff --git a/kernel/hw_breakpoint.c b/kernel/hw_breakpoint.c index d71a987fd2b..c7c2aed9e2d 100644 --- a/kernel/hw_breakpoint.c +++ b/kernel/hw_breakpoint.c | |||
@@ -433,7 +433,8 @@ register_user_hw_breakpoint(struct perf_event_attr *attr, | |||
433 | perf_overflow_handler_t triggered, | 433 | perf_overflow_handler_t triggered, |
434 | struct task_struct *tsk) | 434 | struct task_struct *tsk) |
435 | { | 435 | { |
436 | return perf_event_create_kernel_counter(attr, -1, tsk->pid, triggered); | 436 | return perf_event_create_kernel_counter(attr, -1, task_pid_vnr(tsk), |
437 | triggered); | ||
437 | } | 438 | } |
438 | EXPORT_SYMBOL_GPL(register_user_hw_breakpoint); | 439 | EXPORT_SYMBOL_GPL(register_user_hw_breakpoint); |
439 | 440 | ||
diff --git a/kernel/kfifo.c b/kernel/kfifo.c index 6b5580c5764..01a0700e873 100644 --- a/kernel/kfifo.c +++ b/kernel/kfifo.c | |||
@@ -365,8 +365,6 @@ static unsigned int setup_sgl(struct __kfifo *fifo, struct scatterlist *sgl, | |||
365 | n = setup_sgl_buf(sgl, fifo->data + off, nents, l); | 365 | n = setup_sgl_buf(sgl, fifo->data + off, nents, l); |
366 | n += setup_sgl_buf(sgl + n, fifo->data, nents - n, len - l); | 366 | n += setup_sgl_buf(sgl + n, fifo->data, nents - n, len - l); |
367 | 367 | ||
368 | if (n) | ||
369 | sg_mark_end(sgl + n - 1); | ||
370 | return n; | 368 | return n; |
371 | } | 369 | } |
372 | 370 | ||
diff --git a/kernel/module.c b/kernel/module.c index d0b5f8db11b..ccd64199184 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -1537,6 +1537,7 @@ static int __unlink_module(void *_mod) | |||
1537 | { | 1537 | { |
1538 | struct module *mod = _mod; | 1538 | struct module *mod = _mod; |
1539 | list_del(&mod->list); | 1539 | list_del(&mod->list); |
1540 | module_bug_cleanup(mod); | ||
1540 | return 0; | 1541 | return 0; |
1541 | } | 1542 | } |
1542 | 1543 | ||
@@ -2625,6 +2626,7 @@ static struct module *load_module(void __user *umod, | |||
2625 | if (err < 0) | 2626 | if (err < 0) |
2626 | goto ddebug; | 2627 | goto ddebug; |
2627 | 2628 | ||
2629 | module_bug_finalize(info.hdr, info.sechdrs, mod); | ||
2628 | list_add_rcu(&mod->list, &modules); | 2630 | list_add_rcu(&mod->list, &modules); |
2629 | mutex_unlock(&module_mutex); | 2631 | mutex_unlock(&module_mutex); |
2630 | 2632 | ||
@@ -2650,6 +2652,8 @@ static struct module *load_module(void __user *umod, | |||
2650 | mutex_lock(&module_mutex); | 2652 | mutex_lock(&module_mutex); |
2651 | /* Unlink carefully: kallsyms could be walking list. */ | 2653 | /* Unlink carefully: kallsyms could be walking list. */ |
2652 | list_del_rcu(&mod->list); | 2654 | list_del_rcu(&mod->list); |
2655 | module_bug_cleanup(mod); | ||
2656 | |||
2653 | ddebug: | 2657 | ddebug: |
2654 | if (!mod->taints) | 2658 | if (!mod->taints) |
2655 | dynamic_debug_remove(info.debug); | 2659 | dynamic_debug_remove(info.debug); |
diff --git a/kernel/mutex.c b/kernel/mutex.c index 4c0b7b3e6d2..200407c1502 100644 --- a/kernel/mutex.c +++ b/kernel/mutex.c | |||
@@ -36,15 +36,6 @@ | |||
36 | # include <asm/mutex.h> | 36 | # include <asm/mutex.h> |
37 | #endif | 37 | #endif |
38 | 38 | ||
39 | /*** | ||
40 | * mutex_init - initialize the mutex | ||
41 | * @lock: the mutex to be initialized | ||
42 | * @key: the lock_class_key for the class; used by mutex lock debugging | ||
43 | * | ||
44 | * Initialize the mutex to unlocked state. | ||
45 | * | ||
46 | * It is not allowed to initialize an already locked mutex. | ||
47 | */ | ||
48 | void | 39 | void |
49 | __mutex_init(struct mutex *lock, const char *name, struct lock_class_key *key) | 40 | __mutex_init(struct mutex *lock, const char *name, struct lock_class_key *key) |
50 | { | 41 | { |
@@ -68,7 +59,7 @@ EXPORT_SYMBOL(__mutex_init); | |||
68 | static __used noinline void __sched | 59 | static __used noinline void __sched |
69 | __mutex_lock_slowpath(atomic_t *lock_count); | 60 | __mutex_lock_slowpath(atomic_t *lock_count); |
70 | 61 | ||
71 | /*** | 62 | /** |
72 | * mutex_lock - acquire the mutex | 63 | * mutex_lock - acquire the mutex |
73 | * @lock: the mutex to be acquired | 64 | * @lock: the mutex to be acquired |
74 | * | 65 | * |
@@ -105,7 +96,7 @@ EXPORT_SYMBOL(mutex_lock); | |||
105 | 96 | ||
106 | static __used noinline void __sched __mutex_unlock_slowpath(atomic_t *lock_count); | 97 | static __used noinline void __sched __mutex_unlock_slowpath(atomic_t *lock_count); |
107 | 98 | ||
108 | /*** | 99 | /** |
109 | * mutex_unlock - release the mutex | 100 | * mutex_unlock - release the mutex |
110 | * @lock: the mutex to be released | 101 | * @lock: the mutex to be released |
111 | * | 102 | * |
@@ -364,8 +355,8 @@ __mutex_lock_killable_slowpath(atomic_t *lock_count); | |||
364 | static noinline int __sched | 355 | static noinline int __sched |
365 | __mutex_lock_interruptible_slowpath(atomic_t *lock_count); | 356 | __mutex_lock_interruptible_slowpath(atomic_t *lock_count); |
366 | 357 | ||
367 | /*** | 358 | /** |
368 | * mutex_lock_interruptible - acquire the mutex, interruptable | 359 | * mutex_lock_interruptible - acquire the mutex, interruptible |
369 | * @lock: the mutex to be acquired | 360 | * @lock: the mutex to be acquired |
370 | * | 361 | * |
371 | * Lock the mutex like mutex_lock(), and return 0 if the mutex has | 362 | * Lock the mutex like mutex_lock(), and return 0 if the mutex has |
@@ -456,15 +447,15 @@ static inline int __mutex_trylock_slowpath(atomic_t *lock_count) | |||
456 | return prev == 1; | 447 | return prev == 1; |
457 | } | 448 | } |
458 | 449 | ||
459 | /*** | 450 | /** |
460 | * mutex_trylock - try acquire the mutex, without waiting | 451 | * mutex_trylock - try to acquire the mutex, without waiting |
461 | * @lock: the mutex to be acquired | 452 | * @lock: the mutex to be acquired |
462 | * | 453 | * |
463 | * Try to acquire the mutex atomically. Returns 1 if the mutex | 454 | * Try to acquire the mutex atomically. Returns 1 if the mutex |
464 | * has been acquired successfully, and 0 on contention. | 455 | * has been acquired successfully, and 0 on contention. |
465 | * | 456 | * |
466 | * NOTE: this function follows the spin_trylock() convention, so | 457 | * NOTE: this function follows the spin_trylock() convention, so |
467 | * it is negated to the down_trylock() return values! Be careful | 458 | * it is negated from the down_trylock() return values! Be careful |
468 | * about this when converting semaphore users to mutexes. | 459 | * about this when converting semaphore users to mutexes. |
469 | * | 460 | * |
470 | * This function must not be used in interrupt context. The | 461 | * This function must not be used in interrupt context. The |
diff --git a/kernel/perf_event.c b/kernel/perf_event.c index 403d1804b19..b98bed3d818 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c | |||
@@ -402,11 +402,31 @@ static void perf_group_detach(struct perf_event *event) | |||
402 | } | 402 | } |
403 | } | 403 | } |
404 | 404 | ||
405 | static inline int | ||
406 | event_filter_match(struct perf_event *event) | ||
407 | { | ||
408 | return event->cpu == -1 || event->cpu == smp_processor_id(); | ||
409 | } | ||
410 | |||
405 | static void | 411 | static void |
406 | event_sched_out(struct perf_event *event, | 412 | event_sched_out(struct perf_event *event, |
407 | struct perf_cpu_context *cpuctx, | 413 | struct perf_cpu_context *cpuctx, |
408 | struct perf_event_context *ctx) | 414 | struct perf_event_context *ctx) |
409 | { | 415 | { |
416 | u64 delta; | ||
417 | /* | ||
418 | * An event which could not be activated because of | ||
419 | * filter mismatch still needs to have its timings | ||
420 | * maintained, otherwise bogus information is return | ||
421 | * via read() for time_enabled, time_running: | ||
422 | */ | ||
423 | if (event->state == PERF_EVENT_STATE_INACTIVE | ||
424 | && !event_filter_match(event)) { | ||
425 | delta = ctx->time - event->tstamp_stopped; | ||
426 | event->tstamp_running += delta; | ||
427 | event->tstamp_stopped = ctx->time; | ||
428 | } | ||
429 | |||
410 | if (event->state != PERF_EVENT_STATE_ACTIVE) | 430 | if (event->state != PERF_EVENT_STATE_ACTIVE) |
411 | return; | 431 | return; |
412 | 432 | ||
@@ -432,9 +452,7 @@ group_sched_out(struct perf_event *group_event, | |||
432 | struct perf_event_context *ctx) | 452 | struct perf_event_context *ctx) |
433 | { | 453 | { |
434 | struct perf_event *event; | 454 | struct perf_event *event; |
435 | 455 | int state = group_event->state; | |
436 | if (group_event->state != PERF_EVENT_STATE_ACTIVE) | ||
437 | return; | ||
438 | 456 | ||
439 | event_sched_out(group_event, cpuctx, ctx); | 457 | event_sched_out(group_event, cpuctx, ctx); |
440 | 458 | ||
@@ -444,7 +462,7 @@ group_sched_out(struct perf_event *group_event, | |||
444 | list_for_each_entry(event, &group_event->sibling_list, group_entry) | 462 | list_for_each_entry(event, &group_event->sibling_list, group_entry) |
445 | event_sched_out(event, cpuctx, ctx); | 463 | event_sched_out(event, cpuctx, ctx); |
446 | 464 | ||
447 | if (group_event->attr.exclusive) | 465 | if (state == PERF_EVENT_STATE_ACTIVE && group_event->attr.exclusive) |
448 | cpuctx->exclusive = 0; | 466 | cpuctx->exclusive = 0; |
449 | } | 467 | } |
450 | 468 | ||
@@ -2184,15 +2202,13 @@ static void perf_event_for_each(struct perf_event *event, | |||
2184 | static int perf_event_period(struct perf_event *event, u64 __user *arg) | 2202 | static int perf_event_period(struct perf_event *event, u64 __user *arg) |
2185 | { | 2203 | { |
2186 | struct perf_event_context *ctx = event->ctx; | 2204 | struct perf_event_context *ctx = event->ctx; |
2187 | unsigned long size; | ||
2188 | int ret = 0; | 2205 | int ret = 0; |
2189 | u64 value; | 2206 | u64 value; |
2190 | 2207 | ||
2191 | if (!event->attr.sample_period) | 2208 | if (!event->attr.sample_period) |
2192 | return -EINVAL; | 2209 | return -EINVAL; |
2193 | 2210 | ||
2194 | size = copy_from_user(&value, arg, sizeof(value)); | 2211 | if (copy_from_user(&value, arg, sizeof(value))) |
2195 | if (size != sizeof(value)) | ||
2196 | return -EFAULT; | 2212 | return -EFAULT; |
2197 | 2213 | ||
2198 | if (!value) | 2214 | if (!value) |
@@ -5743,15 +5759,15 @@ perf_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) | |||
5743 | { | 5759 | { |
5744 | unsigned int cpu = (long)hcpu; | 5760 | unsigned int cpu = (long)hcpu; |
5745 | 5761 | ||
5746 | switch (action) { | 5762 | switch (action & ~CPU_TASKS_FROZEN) { |
5747 | 5763 | ||
5748 | case CPU_UP_PREPARE: | 5764 | case CPU_UP_PREPARE: |
5749 | case CPU_UP_PREPARE_FROZEN: | 5765 | case CPU_DOWN_FAILED: |
5750 | perf_event_init_cpu(cpu); | 5766 | perf_event_init_cpu(cpu); |
5751 | break; | 5767 | break; |
5752 | 5768 | ||
5769 | case CPU_UP_CANCELED: | ||
5753 | case CPU_DOWN_PREPARE: | 5770 | case CPU_DOWN_PREPARE: |
5754 | case CPU_DOWN_PREPARE_FROZEN: | ||
5755 | perf_event_exit_cpu(cpu); | 5771 | perf_event_exit_cpu(cpu); |
5756 | break; | 5772 | break; |
5757 | 5773 | ||
diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c index 996a4dec5f9..645e541a45f 100644 --- a/kernel/pm_qos_params.c +++ b/kernel/pm_qos_params.c | |||
@@ -212,15 +212,17 @@ EXPORT_SYMBOL_GPL(pm_qos_request_active); | |||
212 | 212 | ||
213 | /** | 213 | /** |
214 | * pm_qos_add_request - inserts new qos request into the list | 214 | * pm_qos_add_request - inserts new qos request into the list |
215 | * @pm_qos_class: identifies which list of qos request to us | 215 | * @dep: pointer to a preallocated handle |
216 | * @pm_qos_class: identifies which list of qos request to use | ||
216 | * @value: defines the qos request | 217 | * @value: defines the qos request |
217 | * | 218 | * |
218 | * This function inserts a new entry in the pm_qos_class list of requested qos | 219 | * This function inserts a new entry in the pm_qos_class list of requested qos |
219 | * performance characteristics. It recomputes the aggregate QoS expectations | 220 | * performance characteristics. It recomputes the aggregate QoS expectations |
220 | * for the pm_qos_class of parameters, and returns the pm_qos_request list | 221 | * for the pm_qos_class of parameters and initializes the pm_qos_request_list |
221 | * element as a handle for use in updating and removal. Call needs to save | 222 | * handle. Caller needs to save this handle for later use in updates and |
222 | * this handle for later use. | 223 | * removal. |
223 | */ | 224 | */ |
225 | |||
224 | void pm_qos_add_request(struct pm_qos_request_list *dep, | 226 | void pm_qos_add_request(struct pm_qos_request_list *dep, |
225 | int pm_qos_class, s32 value) | 227 | int pm_qos_class, s32 value) |
226 | { | 228 | { |
@@ -348,7 +350,7 @@ static int pm_qos_power_open(struct inode *inode, struct file *filp) | |||
348 | 350 | ||
349 | pm_qos_class = find_pm_qos_object_by_minor(iminor(inode)); | 351 | pm_qos_class = find_pm_qos_object_by_minor(iminor(inode)); |
350 | if (pm_qos_class >= 0) { | 352 | if (pm_qos_class >= 0) { |
351 | struct pm_qos_request_list *req = kzalloc(GFP_KERNEL, sizeof(*req)); | 353 | struct pm_qos_request_list *req = kzalloc(sizeof(*req), GFP_KERNEL); |
352 | if (!req) | 354 | if (!req) |
353 | return -ENOMEM; | 355 | return -ENOMEM; |
354 | 356 | ||
@@ -387,10 +389,12 @@ static ssize_t pm_qos_power_write(struct file *filp, const char __user *buf, | |||
387 | } else if (count == 11) { /* len('0x12345678/0') */ | 389 | } else if (count == 11) { /* len('0x12345678/0') */ |
388 | if (copy_from_user(ascii_value, buf, 11)) | 390 | if (copy_from_user(ascii_value, buf, 11)) |
389 | return -EFAULT; | 391 | return -EFAULT; |
392 | if (strlen(ascii_value) != 10) | ||
393 | return -EINVAL; | ||
390 | x = sscanf(ascii_value, "%x", &value); | 394 | x = sscanf(ascii_value, "%x", &value); |
391 | if (x != 1) | 395 | if (x != 1) |
392 | return -EINVAL; | 396 | return -EINVAL; |
393 | pr_debug(KERN_ERR "%s, %d, 0x%x\n", ascii_value, x, value); | 397 | pr_debug("%s, %d, 0x%x\n", ascii_value, x, value); |
394 | } else | 398 | } else |
395 | return -EINVAL; | 399 | return -EINVAL; |
396 | 400 | ||
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index c77963938bc..8dc31e02ae1 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c | |||
@@ -338,7 +338,6 @@ int hibernation_snapshot(int platform_mode) | |||
338 | goto Close; | 338 | goto Close; |
339 | 339 | ||
340 | suspend_console(); | 340 | suspend_console(); |
341 | hibernation_freeze_swap(); | ||
342 | saved_mask = clear_gfp_allowed_mask(GFP_IOFS); | 341 | saved_mask = clear_gfp_allowed_mask(GFP_IOFS); |
343 | error = dpm_suspend_start(PMSG_FREEZE); | 342 | error = dpm_suspend_start(PMSG_FREEZE); |
344 | if (error) | 343 | if (error) |
diff --git a/kernel/power/poweroff.c b/kernel/power/poweroff.c index e8b33700627..d52359374e8 100644 --- a/kernel/power/poweroff.c +++ b/kernel/power/poweroff.c | |||
@@ -24,7 +24,7 @@ static void do_poweroff(struct work_struct *dummy) | |||
24 | 24 | ||
25 | static DECLARE_WORK(poweroff_work, do_poweroff); | 25 | static DECLARE_WORK(poweroff_work, do_poweroff); |
26 | 26 | ||
27 | static void handle_poweroff(int key, struct tty_struct *tty) | 27 | static void handle_poweroff(int key) |
28 | { | 28 | { |
29 | /* run sysrq poweroff on boot cpu */ | 29 | /* run sysrq poweroff on boot cpu */ |
30 | schedule_work_on(cpumask_first(cpu_online_mask), &poweroff_work); | 30 | schedule_work_on(cpumask_first(cpu_online_mask), &poweroff_work); |
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c index 5e7edfb05e6..d3f795f01bb 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c | |||
@@ -1086,7 +1086,6 @@ void swsusp_free(void) | |||
1086 | buffer = NULL; | 1086 | buffer = NULL; |
1087 | alloc_normal = 0; | 1087 | alloc_normal = 0; |
1088 | alloc_highmem = 0; | 1088 | alloc_highmem = 0; |
1089 | hibernation_thaw_swap(); | ||
1090 | } | 1089 | } |
1091 | 1090 | ||
1092 | /* Helper functions used for the shrinking of memory. */ | 1091 | /* Helper functions used for the shrinking of memory. */ |
@@ -1122,9 +1121,19 @@ static unsigned long preallocate_image_pages(unsigned long nr_pages, gfp_t mask) | |||
1122 | return nr_alloc; | 1121 | return nr_alloc; |
1123 | } | 1122 | } |
1124 | 1123 | ||
1125 | static unsigned long preallocate_image_memory(unsigned long nr_pages) | 1124 | static unsigned long preallocate_image_memory(unsigned long nr_pages, |
1125 | unsigned long avail_normal) | ||
1126 | { | 1126 | { |
1127 | return preallocate_image_pages(nr_pages, GFP_IMAGE); | 1127 | unsigned long alloc; |
1128 | |||
1129 | if (avail_normal <= alloc_normal) | ||
1130 | return 0; | ||
1131 | |||
1132 | alloc = avail_normal - alloc_normal; | ||
1133 | if (nr_pages < alloc) | ||
1134 | alloc = nr_pages; | ||
1135 | |||
1136 | return preallocate_image_pages(alloc, GFP_IMAGE); | ||
1128 | } | 1137 | } |
1129 | 1138 | ||
1130 | #ifdef CONFIG_HIGHMEM | 1139 | #ifdef CONFIG_HIGHMEM |
@@ -1170,15 +1179,22 @@ static inline unsigned long preallocate_highmem_fraction(unsigned long nr_pages, | |||
1170 | */ | 1179 | */ |
1171 | static void free_unnecessary_pages(void) | 1180 | static void free_unnecessary_pages(void) |
1172 | { | 1181 | { |
1173 | unsigned long save_highmem, to_free_normal, to_free_highmem; | 1182 | unsigned long save, to_free_normal, to_free_highmem; |
1174 | 1183 | ||
1175 | to_free_normal = alloc_normal - count_data_pages(); | 1184 | save = count_data_pages(); |
1176 | save_highmem = count_highmem_pages(); | 1185 | if (alloc_normal >= save) { |
1177 | if (alloc_highmem > save_highmem) { | 1186 | to_free_normal = alloc_normal - save; |
1178 | to_free_highmem = alloc_highmem - save_highmem; | 1187 | save = 0; |
1188 | } else { | ||
1189 | to_free_normal = 0; | ||
1190 | save -= alloc_normal; | ||
1191 | } | ||
1192 | save += count_highmem_pages(); | ||
1193 | if (alloc_highmem >= save) { | ||
1194 | to_free_highmem = alloc_highmem - save; | ||
1179 | } else { | 1195 | } else { |
1180 | to_free_highmem = 0; | 1196 | to_free_highmem = 0; |
1181 | to_free_normal -= save_highmem - alloc_highmem; | 1197 | to_free_normal -= save - alloc_highmem; |
1182 | } | 1198 | } |
1183 | 1199 | ||
1184 | memory_bm_position_reset(©_bm); | 1200 | memory_bm_position_reset(©_bm); |
@@ -1259,7 +1275,7 @@ int hibernate_preallocate_memory(void) | |||
1259 | { | 1275 | { |
1260 | struct zone *zone; | 1276 | struct zone *zone; |
1261 | unsigned long saveable, size, max_size, count, highmem, pages = 0; | 1277 | unsigned long saveable, size, max_size, count, highmem, pages = 0; |
1262 | unsigned long alloc, save_highmem, pages_highmem; | 1278 | unsigned long alloc, save_highmem, pages_highmem, avail_normal; |
1263 | struct timeval start, stop; | 1279 | struct timeval start, stop; |
1264 | int error; | 1280 | int error; |
1265 | 1281 | ||
@@ -1296,6 +1312,7 @@ int hibernate_preallocate_memory(void) | |||
1296 | else | 1312 | else |
1297 | count += zone_page_state(zone, NR_FREE_PAGES); | 1313 | count += zone_page_state(zone, NR_FREE_PAGES); |
1298 | } | 1314 | } |
1315 | avail_normal = count; | ||
1299 | count += highmem; | 1316 | count += highmem; |
1300 | count -= totalreserve_pages; | 1317 | count -= totalreserve_pages; |
1301 | 1318 | ||
@@ -1310,12 +1327,21 @@ int hibernate_preallocate_memory(void) | |||
1310 | */ | 1327 | */ |
1311 | if (size >= saveable) { | 1328 | if (size >= saveable) { |
1312 | pages = preallocate_image_highmem(save_highmem); | 1329 | pages = preallocate_image_highmem(save_highmem); |
1313 | pages += preallocate_image_memory(saveable - pages); | 1330 | pages += preallocate_image_memory(saveable - pages, avail_normal); |
1314 | goto out; | 1331 | goto out; |
1315 | } | 1332 | } |
1316 | 1333 | ||
1317 | /* Estimate the minimum size of the image. */ | 1334 | /* Estimate the minimum size of the image. */ |
1318 | pages = minimum_image_size(saveable); | 1335 | pages = minimum_image_size(saveable); |
1336 | /* | ||
1337 | * To avoid excessive pressure on the normal zone, leave room in it to | ||
1338 | * accommodate an image of the minimum size (unless it's already too | ||
1339 | * small, in which case don't preallocate pages from it at all). | ||
1340 | */ | ||
1341 | if (avail_normal > pages) | ||
1342 | avail_normal -= pages; | ||
1343 | else | ||
1344 | avail_normal = 0; | ||
1319 | if (size < pages) | 1345 | if (size < pages) |
1320 | size = min_t(unsigned long, pages, max_size); | 1346 | size = min_t(unsigned long, pages, max_size); |
1321 | 1347 | ||
@@ -1336,16 +1362,34 @@ int hibernate_preallocate_memory(void) | |||
1336 | */ | 1362 | */ |
1337 | pages_highmem = preallocate_image_highmem(highmem / 2); | 1363 | pages_highmem = preallocate_image_highmem(highmem / 2); |
1338 | alloc = (count - max_size) - pages_highmem; | 1364 | alloc = (count - max_size) - pages_highmem; |
1339 | pages = preallocate_image_memory(alloc); | 1365 | pages = preallocate_image_memory(alloc, avail_normal); |
1340 | if (pages < alloc) | 1366 | if (pages < alloc) { |
1341 | goto err_out; | 1367 | /* We have exhausted non-highmem pages, try highmem. */ |
1342 | size = max_size - size; | 1368 | alloc -= pages; |
1343 | alloc = size; | 1369 | pages += pages_highmem; |
1344 | size = preallocate_highmem_fraction(size, highmem, count); | 1370 | pages_highmem = preallocate_image_highmem(alloc); |
1345 | pages_highmem += size; | 1371 | if (pages_highmem < alloc) |
1346 | alloc -= size; | 1372 | goto err_out; |
1347 | pages += preallocate_image_memory(alloc); | 1373 | pages += pages_highmem; |
1348 | pages += pages_highmem; | 1374 | /* |
1375 | * size is the desired number of saveable pages to leave in | ||
1376 | * memory, so try to preallocate (all memory - size) pages. | ||
1377 | */ | ||
1378 | alloc = (count - pages) - size; | ||
1379 | pages += preallocate_image_highmem(alloc); | ||
1380 | } else { | ||
1381 | /* | ||
1382 | * There are approximately max_size saveable pages at this point | ||
1383 | * and we want to reduce this number down to size. | ||
1384 | */ | ||
1385 | alloc = max_size - size; | ||
1386 | size = preallocate_highmem_fraction(alloc, highmem, count); | ||
1387 | pages_highmem += size; | ||
1388 | alloc -= size; | ||
1389 | size = preallocate_image_memory(alloc, avail_normal); | ||
1390 | pages_highmem += preallocate_image_highmem(alloc - size); | ||
1391 | pages += pages_highmem + size; | ||
1392 | } | ||
1349 | 1393 | ||
1350 | /* | 1394 | /* |
1351 | * We only need as many page frames for the image as there are saveable | 1395 | * We only need as many page frames for the image as there are saveable |
diff --git a/kernel/power/swap.c b/kernel/power/swap.c index 5d0059eed3e..e6a5bdf61a3 100644 --- a/kernel/power/swap.c +++ b/kernel/power/swap.c | |||
@@ -136,10 +136,10 @@ sector_t alloc_swapdev_block(int swap) | |||
136 | { | 136 | { |
137 | unsigned long offset; | 137 | unsigned long offset; |
138 | 138 | ||
139 | offset = swp_offset(get_swap_for_hibernation(swap)); | 139 | offset = swp_offset(get_swap_page_of_type(swap)); |
140 | if (offset) { | 140 | if (offset) { |
141 | if (swsusp_extents_insert(offset)) | 141 | if (swsusp_extents_insert(offset)) |
142 | swap_free_for_hibernation(swp_entry(swap, offset)); | 142 | swap_free(swp_entry(swap, offset)); |
143 | else | 143 | else |
144 | return swapdev_block(swap, offset); | 144 | return swapdev_block(swap, offset); |
145 | } | 145 | } |
@@ -163,7 +163,7 @@ void free_all_swap_pages(int swap) | |||
163 | ext = container_of(node, struct swsusp_extent, node); | 163 | ext = container_of(node, struct swsusp_extent, node); |
164 | rb_erase(node, &swsusp_extents); | 164 | rb_erase(node, &swsusp_extents); |
165 | for (offset = ext->start; offset <= ext->end; offset++) | 165 | for (offset = ext->start; offset <= ext->end; offset++) |
166 | swap_free_for_hibernation(swp_entry(swap, offset)); | 166 | swap_free(swp_entry(swap, offset)); |
167 | 167 | ||
168 | kfree(ext); | 168 | kfree(ext); |
169 | } | 169 | } |
diff --git a/kernel/sched.c b/kernel/sched.c index 41541d79e3c..dc85ceb9083 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -1294,6 +1294,10 @@ static void resched_task(struct task_struct *p) | |||
1294 | static void sched_rt_avg_update(struct rq *rq, u64 rt_delta) | 1294 | static void sched_rt_avg_update(struct rq *rq, u64 rt_delta) |
1295 | { | 1295 | { |
1296 | } | 1296 | } |
1297 | |||
1298 | static void sched_avg_update(struct rq *rq) | ||
1299 | { | ||
1300 | } | ||
1297 | #endif /* CONFIG_SMP */ | 1301 | #endif /* CONFIG_SMP */ |
1298 | 1302 | ||
1299 | #if BITS_PER_LONG == 32 | 1303 | #if BITS_PER_LONG == 32 |
@@ -3182,6 +3186,8 @@ static void update_cpu_load(struct rq *this_rq) | |||
3182 | 3186 | ||
3183 | this_rq->cpu_load[i] = (old_load * (scale - 1) + new_load) >> i; | 3187 | this_rq->cpu_load[i] = (old_load * (scale - 1) + new_load) >> i; |
3184 | } | 3188 | } |
3189 | |||
3190 | sched_avg_update(this_rq); | ||
3185 | } | 3191 | } |
3186 | 3192 | ||
3187 | static void update_cpu_load_active(struct rq *this_rq) | 3193 | static void update_cpu_load_active(struct rq *this_rq) |
@@ -3507,9 +3513,9 @@ void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st) | |||
3507 | rtime = nsecs_to_cputime(p->se.sum_exec_runtime); | 3513 | rtime = nsecs_to_cputime(p->se.sum_exec_runtime); |
3508 | 3514 | ||
3509 | if (total) { | 3515 | if (total) { |
3510 | u64 temp; | 3516 | u64 temp = rtime; |
3511 | 3517 | ||
3512 | temp = (u64)(rtime * utime); | 3518 | temp *= utime; |
3513 | do_div(temp, total); | 3519 | do_div(temp, total); |
3514 | utime = (cputime_t)temp; | 3520 | utime = (cputime_t)temp; |
3515 | } else | 3521 | } else |
@@ -3540,9 +3546,9 @@ void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *st) | |||
3540 | rtime = nsecs_to_cputime(cputime.sum_exec_runtime); | 3546 | rtime = nsecs_to_cputime(cputime.sum_exec_runtime); |
3541 | 3547 | ||
3542 | if (total) { | 3548 | if (total) { |
3543 | u64 temp; | 3549 | u64 temp = rtime; |
3544 | 3550 | ||
3545 | temp = (u64)(rtime * cputime.utime); | 3551 | temp *= cputime.utime; |
3546 | do_div(temp, total); | 3552 | do_div(temp, total); |
3547 | utime = (cputime_t)temp; | 3553 | utime = (cputime_t)temp; |
3548 | } else | 3554 | } else |
@@ -3865,8 +3871,16 @@ int mutex_spin_on_owner(struct mutex *lock, struct thread_info *owner) | |||
3865 | /* | 3871 | /* |
3866 | * Owner changed, break to re-assess state. | 3872 | * Owner changed, break to re-assess state. |
3867 | */ | 3873 | */ |
3868 | if (lock->owner != owner) | 3874 | if (lock->owner != owner) { |
3875 | /* | ||
3876 | * If the lock has switched to a different owner, | ||
3877 | * we likely have heavy contention. Return 0 to quit | ||
3878 | * optimistic spinning and not contend further: | ||
3879 | */ | ||
3880 | if (lock->owner) | ||
3881 | return 0; | ||
3869 | break; | 3882 | break; |
3883 | } | ||
3870 | 3884 | ||
3871 | /* | 3885 | /* |
3872 | * Is that owner really running on that cpu? | 3886 | * Is that owner really running on that cpu? |
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 806d1b227a2..db3f674ca49 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c | |||
@@ -54,13 +54,13 @@ enum sched_tunable_scaling sysctl_sched_tunable_scaling | |||
54 | * Minimal preemption granularity for CPU-bound tasks: | 54 | * Minimal preemption granularity for CPU-bound tasks: |
55 | * (default: 2 msec * (1 + ilog(ncpus)), units: nanoseconds) | 55 | * (default: 2 msec * (1 + ilog(ncpus)), units: nanoseconds) |
56 | */ | 56 | */ |
57 | unsigned int sysctl_sched_min_granularity = 2000000ULL; | 57 | unsigned int sysctl_sched_min_granularity = 750000ULL; |
58 | unsigned int normalized_sysctl_sched_min_granularity = 2000000ULL; | 58 | unsigned int normalized_sysctl_sched_min_granularity = 750000ULL; |
59 | 59 | ||
60 | /* | 60 | /* |
61 | * is kept at sysctl_sched_latency / sysctl_sched_min_granularity | 61 | * is kept at sysctl_sched_latency / sysctl_sched_min_granularity |
62 | */ | 62 | */ |
63 | static unsigned int sched_nr_latency = 3; | 63 | static unsigned int sched_nr_latency = 8; |
64 | 64 | ||
65 | /* | 65 | /* |
66 | * After fork, child runs first. If set to 0 (default) then | 66 | * After fork, child runs first. If set to 0 (default) then |
@@ -1313,7 +1313,7 @@ static struct sched_group * | |||
1313 | find_idlest_group(struct sched_domain *sd, struct task_struct *p, | 1313 | find_idlest_group(struct sched_domain *sd, struct task_struct *p, |
1314 | int this_cpu, int load_idx) | 1314 | int this_cpu, int load_idx) |
1315 | { | 1315 | { |
1316 | struct sched_group *idlest = NULL, *this = NULL, *group = sd->groups; | 1316 | struct sched_group *idlest = NULL, *group = sd->groups; |
1317 | unsigned long min_load = ULONG_MAX, this_load = 0; | 1317 | unsigned long min_load = ULONG_MAX, this_load = 0; |
1318 | int imbalance = 100 + (sd->imbalance_pct-100)/2; | 1318 | int imbalance = 100 + (sd->imbalance_pct-100)/2; |
1319 | 1319 | ||
@@ -1348,7 +1348,6 @@ find_idlest_group(struct sched_domain *sd, struct task_struct *p, | |||
1348 | 1348 | ||
1349 | if (local_group) { | 1349 | if (local_group) { |
1350 | this_load = avg_load; | 1350 | this_load = avg_load; |
1351 | this = group; | ||
1352 | } else if (avg_load < min_load) { | 1351 | } else if (avg_load < min_load) { |
1353 | min_load = avg_load; | 1352 | min_load = avg_load; |
1354 | idlest = group; | 1353 | idlest = group; |
@@ -2268,8 +2267,6 @@ unsigned long scale_rt_power(int cpu) | |||
2268 | struct rq *rq = cpu_rq(cpu); | 2267 | struct rq *rq = cpu_rq(cpu); |
2269 | u64 total, available; | 2268 | u64 total, available; |
2270 | 2269 | ||
2271 | sched_avg_update(rq); | ||
2272 | |||
2273 | total = sched_avg_period() + (rq->clock - rq->age_stamp); | 2270 | total = sched_avg_period() + (rq->clock - rq->age_stamp); |
2274 | available = total - rq->rt_avg; | 2271 | available = total - rq->rt_avg; |
2275 | 2272 | ||
@@ -3633,7 +3630,7 @@ static inline int nohz_kick_needed(struct rq *rq, int cpu) | |||
3633 | if (time_before(now, nohz.next_balance)) | 3630 | if (time_before(now, nohz.next_balance)) |
3634 | return 0; | 3631 | return 0; |
3635 | 3632 | ||
3636 | if (!rq->nr_running) | 3633 | if (rq->idle_at_tick) |
3637 | return 0; | 3634 | return 0; |
3638 | 3635 | ||
3639 | first_pick_cpu = atomic_read(&nohz.first_pick_cpu); | 3636 | first_pick_cpu = atomic_read(&nohz.first_pick_cpu); |
@@ -3752,6 +3749,8 @@ static void task_fork_fair(struct task_struct *p) | |||
3752 | 3749 | ||
3753 | raw_spin_lock_irqsave(&rq->lock, flags); | 3750 | raw_spin_lock_irqsave(&rq->lock, flags); |
3754 | 3751 | ||
3752 | update_rq_clock(rq); | ||
3753 | |||
3755 | if (unlikely(task_cpu(p) != this_cpu)) | 3754 | if (unlikely(task_cpu(p) != this_cpu)) |
3756 | __set_task_cpu(p, this_cpu); | 3755 | __set_task_cpu(p, this_cpu); |
3757 | 3756 | ||
diff --git a/kernel/signal.c b/kernel/signal.c index bded6518778..919562c3d6b 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -2215,6 +2215,14 @@ int copy_siginfo_to_user(siginfo_t __user *to, siginfo_t *from) | |||
2215 | #ifdef __ARCH_SI_TRAPNO | 2215 | #ifdef __ARCH_SI_TRAPNO |
2216 | err |= __put_user(from->si_trapno, &to->si_trapno); | 2216 | err |= __put_user(from->si_trapno, &to->si_trapno); |
2217 | #endif | 2217 | #endif |
2218 | #ifdef BUS_MCEERR_AO | ||
2219 | /* | ||
2220 | * Other callers might not initialize the si_lsb field, | ||
2221 | * so check explicitely for the right codes here. | ||
2222 | */ | ||
2223 | if (from->si_code == BUS_MCEERR_AR || from->si_code == BUS_MCEERR_AO) | ||
2224 | err |= __put_user(from->si_addr_lsb, &to->si_addr_lsb); | ||
2225 | #endif | ||
2218 | break; | 2226 | break; |
2219 | case __SI_CHLD: | 2227 | case __SI_CHLD: |
2220 | err |= __put_user(from->si_pid, &to->si_pid); | 2228 | err |= __put_user(from->si_pid, &to->si_pid); |
diff --git a/kernel/smp.c b/kernel/smp.c index 75c970c715d..ed6aacfcb7e 100644 --- a/kernel/smp.c +++ b/kernel/smp.c | |||
@@ -365,9 +365,10 @@ call: | |||
365 | EXPORT_SYMBOL_GPL(smp_call_function_any); | 365 | EXPORT_SYMBOL_GPL(smp_call_function_any); |
366 | 366 | ||
367 | /** | 367 | /** |
368 | * __smp_call_function_single(): Run a function on another CPU | 368 | * __smp_call_function_single(): Run a function on a specific CPU |
369 | * @cpu: The CPU to run on. | 369 | * @cpu: The CPU to run on. |
370 | * @data: Pre-allocated and setup data structure | 370 | * @data: Pre-allocated and setup data structure |
371 | * @wait: If true, wait until function has completed on specified CPU. | ||
371 | * | 372 | * |
372 | * Like smp_call_function_single(), but allow caller to pass in a | 373 | * Like smp_call_function_single(), but allow caller to pass in a |
373 | * pre-allocated data structure. Useful for embedding @data inside | 374 | * pre-allocated data structure. Useful for embedding @data inside |
@@ -376,8 +377,10 @@ EXPORT_SYMBOL_GPL(smp_call_function_any); | |||
376 | void __smp_call_function_single(int cpu, struct call_single_data *data, | 377 | void __smp_call_function_single(int cpu, struct call_single_data *data, |
377 | int wait) | 378 | int wait) |
378 | { | 379 | { |
379 | csd_lock(data); | 380 | unsigned int this_cpu; |
381 | unsigned long flags; | ||
380 | 382 | ||
383 | this_cpu = get_cpu(); | ||
381 | /* | 384 | /* |
382 | * Can deadlock when called with interrupts disabled. | 385 | * Can deadlock when called with interrupts disabled. |
383 | * We allow cpu's that are not yet online though, as no one else can | 386 | * We allow cpu's that are not yet online though, as no one else can |
@@ -387,7 +390,15 @@ void __smp_call_function_single(int cpu, struct call_single_data *data, | |||
387 | WARN_ON_ONCE(cpu_online(smp_processor_id()) && wait && irqs_disabled() | 390 | WARN_ON_ONCE(cpu_online(smp_processor_id()) && wait && irqs_disabled() |
388 | && !oops_in_progress); | 391 | && !oops_in_progress); |
389 | 392 | ||
390 | generic_exec_single(cpu, data, wait); | 393 | if (cpu == this_cpu) { |
394 | local_irq_save(flags); | ||
395 | data->func(data->info); | ||
396 | local_irq_restore(flags); | ||
397 | } else { | ||
398 | csd_lock(data); | ||
399 | generic_exec_single(cpu, data, wait); | ||
400 | } | ||
401 | put_cpu(); | ||
391 | } | 402 | } |
392 | 403 | ||
393 | /** | 404 | /** |
diff --git a/kernel/sys.c b/kernel/sys.c index e9ad4448982..7f5a0cd296a 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -931,6 +931,7 @@ SYSCALL_DEFINE2(setpgid, pid_t, pid, pid_t, pgid) | |||
931 | pgid = pid; | 931 | pgid = pid; |
932 | if (pgid < 0) | 932 | if (pgid < 0) |
933 | return -EINVAL; | 933 | return -EINVAL; |
934 | rcu_read_lock(); | ||
934 | 935 | ||
935 | /* From this point forward we keep holding onto the tasklist lock | 936 | /* From this point forward we keep holding onto the tasklist lock |
936 | * so that our parent does not change from under us. -DaveM | 937 | * so that our parent does not change from under us. -DaveM |
@@ -984,6 +985,7 @@ SYSCALL_DEFINE2(setpgid, pid_t, pid, pid_t, pgid) | |||
984 | out: | 985 | out: |
985 | /* All paths lead to here, thus we are safe. -DaveM */ | 986 | /* All paths lead to here, thus we are safe. -DaveM */ |
986 | write_unlock_irq(&tasklist_lock); | 987 | write_unlock_irq(&tasklist_lock); |
988 | rcu_read_unlock(); | ||
987 | return err; | 989 | return err; |
988 | } | 990 | } |
989 | 991 | ||
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index ca38e8e3e90..3a45c224770 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -1713,10 +1713,7 @@ static __init int sysctl_init(void) | |||
1713 | { | 1713 | { |
1714 | sysctl_set_parent(NULL, root_table); | 1714 | sysctl_set_parent(NULL, root_table); |
1715 | #ifdef CONFIG_SYSCTL_SYSCALL_CHECK | 1715 | #ifdef CONFIG_SYSCTL_SYSCALL_CHECK |
1716 | { | 1716 | sysctl_check_table(current->nsproxy, root_table); |
1717 | int err; | ||
1718 | err = sysctl_check_table(current->nsproxy, root_table); | ||
1719 | } | ||
1720 | #endif | 1717 | #endif |
1721 | return 0; | 1718 | return 0; |
1722 | } | 1719 | } |
@@ -2488,7 +2485,7 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int | |||
2488 | kbuf[left] = 0; | 2485 | kbuf[left] = 0; |
2489 | } | 2486 | } |
2490 | 2487 | ||
2491 | for (; left && vleft--; i++, min++, max++, first=0) { | 2488 | for (; left && vleft--; i++, first = 0) { |
2492 | unsigned long val; | 2489 | unsigned long val; |
2493 | 2490 | ||
2494 | if (write) { | 2491 | if (write) { |
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 0d88ce9b9fb..fa7ece649fe 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
@@ -381,12 +381,19 @@ static int function_stat_show(struct seq_file *m, void *v) | |||
381 | { | 381 | { |
382 | struct ftrace_profile *rec = v; | 382 | struct ftrace_profile *rec = v; |
383 | char str[KSYM_SYMBOL_LEN]; | 383 | char str[KSYM_SYMBOL_LEN]; |
384 | int ret = 0; | ||
384 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 385 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
385 | static DEFINE_MUTEX(mutex); | ||
386 | static struct trace_seq s; | 386 | static struct trace_seq s; |
387 | unsigned long long avg; | 387 | unsigned long long avg; |
388 | unsigned long long stddev; | 388 | unsigned long long stddev; |
389 | #endif | 389 | #endif |
390 | mutex_lock(&ftrace_profile_lock); | ||
391 | |||
392 | /* we raced with function_profile_reset() */ | ||
393 | if (unlikely(rec->counter == 0)) { | ||
394 | ret = -EBUSY; | ||
395 | goto out; | ||
396 | } | ||
390 | 397 | ||
391 | kallsyms_lookup(rec->ip, NULL, NULL, NULL, str); | 398 | kallsyms_lookup(rec->ip, NULL, NULL, NULL, str); |
392 | seq_printf(m, " %-30.30s %10lu", str, rec->counter); | 399 | seq_printf(m, " %-30.30s %10lu", str, rec->counter); |
@@ -408,7 +415,6 @@ static int function_stat_show(struct seq_file *m, void *v) | |||
408 | do_div(stddev, (rec->counter - 1) * 1000); | 415 | do_div(stddev, (rec->counter - 1) * 1000); |
409 | } | 416 | } |
410 | 417 | ||
411 | mutex_lock(&mutex); | ||
412 | trace_seq_init(&s); | 418 | trace_seq_init(&s); |
413 | trace_print_graph_duration(rec->time, &s); | 419 | trace_print_graph_duration(rec->time, &s); |
414 | trace_seq_puts(&s, " "); | 420 | trace_seq_puts(&s, " "); |
@@ -416,11 +422,12 @@ static int function_stat_show(struct seq_file *m, void *v) | |||
416 | trace_seq_puts(&s, " "); | 422 | trace_seq_puts(&s, " "); |
417 | trace_print_graph_duration(stddev, &s); | 423 | trace_print_graph_duration(stddev, &s); |
418 | trace_print_seq(m, &s); | 424 | trace_print_seq(m, &s); |
419 | mutex_unlock(&mutex); | ||
420 | #endif | 425 | #endif |
421 | seq_putc(m, '\n'); | 426 | seq_putc(m, '\n'); |
427 | out: | ||
428 | mutex_unlock(&ftrace_profile_lock); | ||
422 | 429 | ||
423 | return 0; | 430 | return ret; |
424 | } | 431 | } |
425 | 432 | ||
426 | static void ftrace_profile_reset(struct ftrace_profile_stat *stat) | 433 | static void ftrace_profile_reset(struct ftrace_profile_stat *stat) |
@@ -1503,6 +1510,8 @@ static void *t_start(struct seq_file *m, loff_t *pos) | |||
1503 | if (*pos > 0) | 1510 | if (*pos > 0) |
1504 | return t_hash_start(m, pos); | 1511 | return t_hash_start(m, pos); |
1505 | iter->flags |= FTRACE_ITER_PRINTALL; | 1512 | iter->flags |= FTRACE_ITER_PRINTALL; |
1513 | /* reset in case of seek/pread */ | ||
1514 | iter->flags &= ~FTRACE_ITER_HASH; | ||
1506 | return iter; | 1515 | return iter; |
1507 | } | 1516 | } |
1508 | 1517 | ||
@@ -2409,7 +2418,7 @@ static const struct file_operations ftrace_filter_fops = { | |||
2409 | .open = ftrace_filter_open, | 2418 | .open = ftrace_filter_open, |
2410 | .read = seq_read, | 2419 | .read = seq_read, |
2411 | .write = ftrace_filter_write, | 2420 | .write = ftrace_filter_write, |
2412 | .llseek = ftrace_regex_lseek, | 2421 | .llseek = no_llseek, |
2413 | .release = ftrace_filter_release, | 2422 | .release = ftrace_filter_release, |
2414 | }; | 2423 | }; |
2415 | 2424 | ||
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 19cccc3c302..bca96377fd4 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c | |||
@@ -405,7 +405,7 @@ static inline int test_time_stamp(u64 delta) | |||
405 | #define BUF_MAX_DATA_SIZE (BUF_PAGE_SIZE - (sizeof(u32) * 2)) | 405 | #define BUF_MAX_DATA_SIZE (BUF_PAGE_SIZE - (sizeof(u32) * 2)) |
406 | 406 | ||
407 | /* Max number of timestamps that can fit on a page */ | 407 | /* Max number of timestamps that can fit on a page */ |
408 | #define RB_TIMESTAMPS_PER_PAGE (BUF_PAGE_SIZE / RB_LEN_TIME_STAMP) | 408 | #define RB_TIMESTAMPS_PER_PAGE (BUF_PAGE_SIZE / RB_LEN_TIME_EXTEND) |
409 | 409 | ||
410 | int ring_buffer_print_page_header(struct trace_seq *s) | 410 | int ring_buffer_print_page_header(struct trace_seq *s) |
411 | { | 411 | { |
@@ -2985,13 +2985,11 @@ static void rb_advance_reader(struct ring_buffer_per_cpu *cpu_buffer) | |||
2985 | 2985 | ||
2986 | static void rb_advance_iter(struct ring_buffer_iter *iter) | 2986 | static void rb_advance_iter(struct ring_buffer_iter *iter) |
2987 | { | 2987 | { |
2988 | struct ring_buffer *buffer; | ||
2989 | struct ring_buffer_per_cpu *cpu_buffer; | 2988 | struct ring_buffer_per_cpu *cpu_buffer; |
2990 | struct ring_buffer_event *event; | 2989 | struct ring_buffer_event *event; |
2991 | unsigned length; | 2990 | unsigned length; |
2992 | 2991 | ||
2993 | cpu_buffer = iter->cpu_buffer; | 2992 | cpu_buffer = iter->cpu_buffer; |
2994 | buffer = cpu_buffer->buffer; | ||
2995 | 2993 | ||
2996 | /* | 2994 | /* |
2997 | * Check if we are at the end of the buffer. | 2995 | * Check if we are at the end of the buffer. |
diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c index 000e6e85b44..31cc4cb0dbf 100644 --- a/kernel/trace/trace_event_perf.c +++ b/kernel/trace/trace_event_perf.c | |||
@@ -91,6 +91,8 @@ int perf_trace_init(struct perf_event *p_event) | |||
91 | tp_event->class && tp_event->class->reg && | 91 | tp_event->class && tp_event->class->reg && |
92 | try_module_get(tp_event->mod)) { | 92 | try_module_get(tp_event->mod)) { |
93 | ret = perf_trace_event_init(tp_event, p_event); | 93 | ret = perf_trace_event_init(tp_event, p_event); |
94 | if (ret) | ||
95 | module_put(tp_event->mod); | ||
94 | break; | 96 | break; |
95 | } | 97 | } |
96 | } | 98 | } |
@@ -146,6 +148,7 @@ void perf_trace_destroy(struct perf_event *p_event) | |||
146 | } | 148 | } |
147 | } | 149 | } |
148 | out: | 150 | out: |
151 | module_put(tp_event->mod); | ||
149 | mutex_unlock(&event_mutex); | 152 | mutex_unlock(&event_mutex); |
150 | } | 153 | } |
151 | 154 | ||
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 8b27c9849b4..544301d29de 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c | |||
@@ -514,8 +514,8 @@ static int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs); | |||
514 | static int kretprobe_dispatcher(struct kretprobe_instance *ri, | 514 | static int kretprobe_dispatcher(struct kretprobe_instance *ri, |
515 | struct pt_regs *regs); | 515 | struct pt_regs *regs); |
516 | 516 | ||
517 | /* Check the name is good for event/group */ | 517 | /* Check the name is good for event/group/fields */ |
518 | static int check_event_name(const char *name) | 518 | static int is_good_name(const char *name) |
519 | { | 519 | { |
520 | if (!isalpha(*name) && *name != '_') | 520 | if (!isalpha(*name) && *name != '_') |
521 | return 0; | 521 | return 0; |
@@ -557,7 +557,7 @@ static struct trace_probe *alloc_trace_probe(const char *group, | |||
557 | else | 557 | else |
558 | tp->rp.kp.pre_handler = kprobe_dispatcher; | 558 | tp->rp.kp.pre_handler = kprobe_dispatcher; |
559 | 559 | ||
560 | if (!event || !check_event_name(event)) { | 560 | if (!event || !is_good_name(event)) { |
561 | ret = -EINVAL; | 561 | ret = -EINVAL; |
562 | goto error; | 562 | goto error; |
563 | } | 563 | } |
@@ -567,7 +567,7 @@ static struct trace_probe *alloc_trace_probe(const char *group, | |||
567 | if (!tp->call.name) | 567 | if (!tp->call.name) |
568 | goto error; | 568 | goto error; |
569 | 569 | ||
570 | if (!group || !check_event_name(group)) { | 570 | if (!group || !is_good_name(group)) { |
571 | ret = -EINVAL; | 571 | ret = -EINVAL; |
572 | goto error; | 572 | goto error; |
573 | } | 573 | } |
@@ -883,7 +883,7 @@ static int create_trace_probe(int argc, char **argv) | |||
883 | int i, ret = 0; | 883 | int i, ret = 0; |
884 | int is_return = 0, is_delete = 0; | 884 | int is_return = 0, is_delete = 0; |
885 | char *symbol = NULL, *event = NULL, *group = NULL; | 885 | char *symbol = NULL, *event = NULL, *group = NULL; |
886 | char *arg, *tmp; | 886 | char *arg; |
887 | unsigned long offset = 0; | 887 | unsigned long offset = 0; |
888 | void *addr = NULL; | 888 | void *addr = NULL; |
889 | char buf[MAX_EVENT_NAME_LEN]; | 889 | char buf[MAX_EVENT_NAME_LEN]; |
@@ -992,26 +992,36 @@ static int create_trace_probe(int argc, char **argv) | |||
992 | /* parse arguments */ | 992 | /* parse arguments */ |
993 | ret = 0; | 993 | ret = 0; |
994 | for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) { | 994 | for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) { |
995 | /* Increment count for freeing args in error case */ | ||
996 | tp->nr_args++; | ||
997 | |||
995 | /* Parse argument name */ | 998 | /* Parse argument name */ |
996 | arg = strchr(argv[i], '='); | 999 | arg = strchr(argv[i], '='); |
997 | if (arg) | 1000 | if (arg) { |
998 | *arg++ = '\0'; | 1001 | *arg++ = '\0'; |
999 | else | 1002 | tp->args[i].name = kstrdup(argv[i], GFP_KERNEL); |
1003 | } else { | ||
1000 | arg = argv[i]; | 1004 | arg = argv[i]; |
1005 | /* If argument name is omitted, set "argN" */ | ||
1006 | snprintf(buf, MAX_EVENT_NAME_LEN, "arg%d", i + 1); | ||
1007 | tp->args[i].name = kstrdup(buf, GFP_KERNEL); | ||
1008 | } | ||
1001 | 1009 | ||
1002 | tp->args[i].name = kstrdup(argv[i], GFP_KERNEL); | ||
1003 | if (!tp->args[i].name) { | 1010 | if (!tp->args[i].name) { |
1004 | pr_info("Failed to allocate argument%d name '%s'.\n", | 1011 | pr_info("Failed to allocate argument[%d] name.\n", i); |
1005 | i, argv[i]); | ||
1006 | ret = -ENOMEM; | 1012 | ret = -ENOMEM; |
1007 | goto error; | 1013 | goto error; |
1008 | } | 1014 | } |
1009 | tmp = strchr(tp->args[i].name, ':'); | 1015 | |
1010 | if (tmp) | 1016 | if (!is_good_name(tp->args[i].name)) { |
1011 | *tmp = '_'; /* convert : to _ */ | 1017 | pr_info("Invalid argument[%d] name: %s\n", |
1018 | i, tp->args[i].name); | ||
1019 | ret = -EINVAL; | ||
1020 | goto error; | ||
1021 | } | ||
1012 | 1022 | ||
1013 | if (conflict_field_name(tp->args[i].name, tp->args, i)) { | 1023 | if (conflict_field_name(tp->args[i].name, tp->args, i)) { |
1014 | pr_info("Argument%d name '%s' conflicts with " | 1024 | pr_info("Argument[%d] name '%s' conflicts with " |
1015 | "another field.\n", i, argv[i]); | 1025 | "another field.\n", i, argv[i]); |
1016 | ret = -EINVAL; | 1026 | ret = -EINVAL; |
1017 | goto error; | 1027 | goto error; |
@@ -1020,12 +1030,9 @@ static int create_trace_probe(int argc, char **argv) | |||
1020 | /* Parse fetch argument */ | 1030 | /* Parse fetch argument */ |
1021 | ret = parse_probe_arg(arg, tp, &tp->args[i], is_return); | 1031 | ret = parse_probe_arg(arg, tp, &tp->args[i], is_return); |
1022 | if (ret) { | 1032 | if (ret) { |
1023 | pr_info("Parse error at argument%d. (%d)\n", i, ret); | 1033 | pr_info("Parse error at argument[%d]. (%d)\n", i, ret); |
1024 | kfree(tp->args[i].name); | ||
1025 | goto error; | 1034 | goto error; |
1026 | } | 1035 | } |
1027 | |||
1028 | tp->nr_args++; | ||
1029 | } | 1036 | } |
1030 | 1037 | ||
1031 | ret = register_trace_probe(tp); | 1038 | ret = register_trace_probe(tp); |
diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c index 056468eae7c..a6b7e0e0f3e 100644 --- a/kernel/trace/trace_stack.c +++ b/kernel/trace/trace_stack.c | |||
@@ -249,7 +249,7 @@ static int trace_lookup_stack(struct seq_file *m, long i) | |||
249 | { | 249 | { |
250 | unsigned long addr = stack_dump_trace[i]; | 250 | unsigned long addr = stack_dump_trace[i]; |
251 | 251 | ||
252 | return seq_printf(m, "%pF\n", (void *)addr); | 252 | return seq_printf(m, "%pS\n", (void *)addr); |
253 | } | 253 | } |
254 | 254 | ||
255 | static void print_disabled(struct seq_file *m) | 255 | static void print_disabled(struct seq_file *m) |
diff --git a/kernel/watchdog.c b/kernel/watchdog.c index 613bc1f0461..7f9c3c52ecc 100644 --- a/kernel/watchdog.c +++ b/kernel/watchdog.c | |||
@@ -122,7 +122,7 @@ static void __touch_watchdog(void) | |||
122 | 122 | ||
123 | void touch_softlockup_watchdog(void) | 123 | void touch_softlockup_watchdog(void) |
124 | { | 124 | { |
125 | __get_cpu_var(watchdog_touch_ts) = 0; | 125 | __raw_get_cpu_var(watchdog_touch_ts) = 0; |
126 | } | 126 | } |
127 | EXPORT_SYMBOL(touch_softlockup_watchdog); | 127 | EXPORT_SYMBOL(touch_softlockup_watchdog); |
128 | 128 | ||
@@ -142,7 +142,14 @@ void touch_all_softlockup_watchdogs(void) | |||
142 | #ifdef CONFIG_HARDLOCKUP_DETECTOR | 142 | #ifdef CONFIG_HARDLOCKUP_DETECTOR |
143 | void touch_nmi_watchdog(void) | 143 | void touch_nmi_watchdog(void) |
144 | { | 144 | { |
145 | __get_cpu_var(watchdog_nmi_touch) = true; | 145 | if (watchdog_enabled) { |
146 | unsigned cpu; | ||
147 | |||
148 | for_each_present_cpu(cpu) { | ||
149 | if (per_cpu(watchdog_nmi_touch, cpu) != true) | ||
150 | per_cpu(watchdog_nmi_touch, cpu) = true; | ||
151 | } | ||
152 | } | ||
146 | touch_softlockup_watchdog(); | 153 | touch_softlockup_watchdog(); |
147 | } | 154 | } |
148 | EXPORT_SYMBOL(touch_nmi_watchdog); | 155 | EXPORT_SYMBOL(touch_nmi_watchdog); |
@@ -206,6 +213,9 @@ void watchdog_overflow_callback(struct perf_event *event, int nmi, | |||
206 | struct perf_sample_data *data, | 213 | struct perf_sample_data *data, |
207 | struct pt_regs *regs) | 214 | struct pt_regs *regs) |
208 | { | 215 | { |
216 | /* Ensure the watchdog never gets throttled */ | ||
217 | event->hw.interrupts = 0; | ||
218 | |||
209 | if (__get_cpu_var(watchdog_nmi_touch) == true) { | 219 | if (__get_cpu_var(watchdog_nmi_touch) == true) { |
210 | __get_cpu_var(watchdog_nmi_touch) = false; | 220 | __get_cpu_var(watchdog_nmi_touch) = false; |
211 | return; | 221 | return; |
@@ -430,6 +440,9 @@ static int watchdog_enable(int cpu) | |||
430 | wake_up_process(p); | 440 | wake_up_process(p); |
431 | } | 441 | } |
432 | 442 | ||
443 | /* if any cpu succeeds, watchdog is considered enabled for the system */ | ||
444 | watchdog_enabled = 1; | ||
445 | |||
433 | return 0; | 446 | return 0; |
434 | } | 447 | } |
435 | 448 | ||
@@ -452,9 +465,6 @@ static void watchdog_disable(int cpu) | |||
452 | per_cpu(softlockup_watchdog, cpu) = NULL; | 465 | per_cpu(softlockup_watchdog, cpu) = NULL; |
453 | kthread_stop(p); | 466 | kthread_stop(p); |
454 | } | 467 | } |
455 | |||
456 | /* if any cpu succeeds, watchdog is considered enabled for the system */ | ||
457 | watchdog_enabled = 1; | ||
458 | } | 468 | } |
459 | 469 | ||
460 | static void watchdog_enable_all_cpus(void) | 470 | static void watchdog_enable_all_cpus(void) |
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 8bd600c020e..f77afd93922 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
@@ -1,19 +1,26 @@ | |||
1 | /* | 1 | /* |
2 | * linux/kernel/workqueue.c | 2 | * kernel/workqueue.c - generic async execution with shared worker pool |
3 | * | 3 | * |
4 | * Generic mechanism for defining kernel helper threads for running | 4 | * Copyright (C) 2002 Ingo Molnar |
5 | * arbitrary tasks in process context. | ||
6 | * | 5 | * |
7 | * Started by Ingo Molnar, Copyright (C) 2002 | 6 | * Derived from the taskqueue/keventd code by: |
7 | * David Woodhouse <dwmw2@infradead.org> | ||
8 | * Andrew Morton | ||
9 | * Kai Petzke <wpp@marie.physik.tu-berlin.de> | ||
10 | * Theodore Ts'o <tytso@mit.edu> | ||
8 | * | 11 | * |
9 | * Derived from the taskqueue/keventd code by: | 12 | * Made to use alloc_percpu by Christoph Lameter. |
10 | * | 13 | * |
11 | * David Woodhouse <dwmw2@infradead.org> | 14 | * Copyright (C) 2010 SUSE Linux Products GmbH |
12 | * Andrew Morton | 15 | * Copyright (C) 2010 Tejun Heo <tj@kernel.org> |
13 | * Kai Petzke <wpp@marie.physik.tu-berlin.de> | ||
14 | * Theodore Ts'o <tytso@mit.edu> | ||
15 | * | 16 | * |
16 | * Made to use alloc_percpu by Christoph Lameter. | 17 | * This is the generic async execution mechanism. Work items as are |
18 | * executed in process context. The worker pool is shared and | ||
19 | * automatically managed. There is one worker pool for each CPU and | ||
20 | * one extra for works which are better served by workers which are | ||
21 | * not bound to any specific CPU. | ||
22 | * | ||
23 | * Please read Documentation/workqueue.txt for details. | ||
17 | */ | 24 | */ |
18 | 25 | ||
19 | #include <linux/module.h> | 26 | #include <linux/module.h> |
@@ -90,7 +97,8 @@ enum { | |||
90 | /* | 97 | /* |
91 | * Structure fields follow one of the following exclusion rules. | 98 | * Structure fields follow one of the following exclusion rules. |
92 | * | 99 | * |
93 | * I: Set during initialization and read-only afterwards. | 100 | * I: Modifiable by initialization/destruction paths and read-only for |
101 | * everyone else. | ||
94 | * | 102 | * |
95 | * P: Preemption protected. Disabling preemption is enough and should | 103 | * P: Preemption protected. Disabling preemption is enough and should |
96 | * only be modified and accessed from the local cpu. | 104 | * only be modified and accessed from the local cpu. |
@@ -198,7 +206,7 @@ typedef cpumask_var_t mayday_mask_t; | |||
198 | cpumask_test_and_set_cpu((cpu), (mask)) | 206 | cpumask_test_and_set_cpu((cpu), (mask)) |
199 | #define mayday_clear_cpu(cpu, mask) cpumask_clear_cpu((cpu), (mask)) | 207 | #define mayday_clear_cpu(cpu, mask) cpumask_clear_cpu((cpu), (mask)) |
200 | #define for_each_mayday_cpu(cpu, mask) for_each_cpu((cpu), (mask)) | 208 | #define for_each_mayday_cpu(cpu, mask) for_each_cpu((cpu), (mask)) |
201 | #define alloc_mayday_mask(maskp, gfp) alloc_cpumask_var((maskp), (gfp)) | 209 | #define alloc_mayday_mask(maskp, gfp) zalloc_cpumask_var((maskp), (gfp)) |
202 | #define free_mayday_mask(mask) free_cpumask_var((mask)) | 210 | #define free_mayday_mask(mask) free_cpumask_var((mask)) |
203 | #else | 211 | #else |
204 | typedef unsigned long mayday_mask_t; | 212 | typedef unsigned long mayday_mask_t; |
@@ -943,10 +951,14 @@ static void __queue_work(unsigned int cpu, struct workqueue_struct *wq, | |||
943 | struct global_cwq *gcwq; | 951 | struct global_cwq *gcwq; |
944 | struct cpu_workqueue_struct *cwq; | 952 | struct cpu_workqueue_struct *cwq; |
945 | struct list_head *worklist; | 953 | struct list_head *worklist; |
954 | unsigned int work_flags; | ||
946 | unsigned long flags; | 955 | unsigned long flags; |
947 | 956 | ||
948 | debug_work_activate(work); | 957 | debug_work_activate(work); |
949 | 958 | ||
959 | if (WARN_ON_ONCE(wq->flags & WQ_DYING)) | ||
960 | return; | ||
961 | |||
950 | /* determine gcwq to use */ | 962 | /* determine gcwq to use */ |
951 | if (!(wq->flags & WQ_UNBOUND)) { | 963 | if (!(wq->flags & WQ_UNBOUND)) { |
952 | struct global_cwq *last_gcwq; | 964 | struct global_cwq *last_gcwq; |
@@ -989,14 +1001,17 @@ static void __queue_work(unsigned int cpu, struct workqueue_struct *wq, | |||
989 | BUG_ON(!list_empty(&work->entry)); | 1001 | BUG_ON(!list_empty(&work->entry)); |
990 | 1002 | ||
991 | cwq->nr_in_flight[cwq->work_color]++; | 1003 | cwq->nr_in_flight[cwq->work_color]++; |
1004 | work_flags = work_color_to_flags(cwq->work_color); | ||
992 | 1005 | ||
993 | if (likely(cwq->nr_active < cwq->max_active)) { | 1006 | if (likely(cwq->nr_active < cwq->max_active)) { |
994 | cwq->nr_active++; | 1007 | cwq->nr_active++; |
995 | worklist = gcwq_determine_ins_pos(gcwq, cwq); | 1008 | worklist = gcwq_determine_ins_pos(gcwq, cwq); |
996 | } else | 1009 | } else { |
1010 | work_flags |= WORK_STRUCT_DELAYED; | ||
997 | worklist = &cwq->delayed_works; | 1011 | worklist = &cwq->delayed_works; |
1012 | } | ||
998 | 1013 | ||
999 | insert_work(cwq, work, worklist, work_color_to_flags(cwq->work_color)); | 1014 | insert_work(cwq, work, worklist, work_flags); |
1000 | 1015 | ||
1001 | spin_unlock_irqrestore(&gcwq->lock, flags); | 1016 | spin_unlock_irqrestore(&gcwq->lock, flags); |
1002 | } | 1017 | } |
@@ -1215,6 +1230,7 @@ static void worker_leave_idle(struct worker *worker) | |||
1215 | * bound), %false if offline. | 1230 | * bound), %false if offline. |
1216 | */ | 1231 | */ |
1217 | static bool worker_maybe_bind_and_lock(struct worker *worker) | 1232 | static bool worker_maybe_bind_and_lock(struct worker *worker) |
1233 | __acquires(&gcwq->lock) | ||
1218 | { | 1234 | { |
1219 | struct global_cwq *gcwq = worker->gcwq; | 1235 | struct global_cwq *gcwq = worker->gcwq; |
1220 | struct task_struct *task = worker->task; | 1236 | struct task_struct *task = worker->task; |
@@ -1488,6 +1504,8 @@ static void gcwq_mayday_timeout(unsigned long __gcwq) | |||
1488 | * otherwise. | 1504 | * otherwise. |
1489 | */ | 1505 | */ |
1490 | static bool maybe_create_worker(struct global_cwq *gcwq) | 1506 | static bool maybe_create_worker(struct global_cwq *gcwq) |
1507 | __releases(&gcwq->lock) | ||
1508 | __acquires(&gcwq->lock) | ||
1491 | { | 1509 | { |
1492 | if (!need_to_create_worker(gcwq)) | 1510 | if (!need_to_create_worker(gcwq)) |
1493 | return false; | 1511 | return false; |
@@ -1662,6 +1680,7 @@ static void cwq_activate_first_delayed(struct cpu_workqueue_struct *cwq) | |||
1662 | struct list_head *pos = gcwq_determine_ins_pos(cwq->gcwq, cwq); | 1680 | struct list_head *pos = gcwq_determine_ins_pos(cwq->gcwq, cwq); |
1663 | 1681 | ||
1664 | move_linked_works(work, pos, NULL); | 1682 | move_linked_works(work, pos, NULL); |
1683 | __clear_bit(WORK_STRUCT_DELAYED_BIT, work_data_bits(work)); | ||
1665 | cwq->nr_active++; | 1684 | cwq->nr_active++; |
1666 | } | 1685 | } |
1667 | 1686 | ||
@@ -1669,6 +1688,7 @@ static void cwq_activate_first_delayed(struct cpu_workqueue_struct *cwq) | |||
1669 | * cwq_dec_nr_in_flight - decrement cwq's nr_in_flight | 1688 | * cwq_dec_nr_in_flight - decrement cwq's nr_in_flight |
1670 | * @cwq: cwq of interest | 1689 | * @cwq: cwq of interest |
1671 | * @color: color of work which left the queue | 1690 | * @color: color of work which left the queue |
1691 | * @delayed: for a delayed work | ||
1672 | * | 1692 | * |
1673 | * A work either has completed or is removed from pending queue, | 1693 | * A work either has completed or is removed from pending queue, |
1674 | * decrement nr_in_flight of its cwq and handle workqueue flushing. | 1694 | * decrement nr_in_flight of its cwq and handle workqueue flushing. |
@@ -1676,19 +1696,22 @@ static void cwq_activate_first_delayed(struct cpu_workqueue_struct *cwq) | |||
1676 | * CONTEXT: | 1696 | * CONTEXT: |
1677 | * spin_lock_irq(gcwq->lock). | 1697 | * spin_lock_irq(gcwq->lock). |
1678 | */ | 1698 | */ |
1679 | static void cwq_dec_nr_in_flight(struct cpu_workqueue_struct *cwq, int color) | 1699 | static void cwq_dec_nr_in_flight(struct cpu_workqueue_struct *cwq, int color, |
1700 | bool delayed) | ||
1680 | { | 1701 | { |
1681 | /* ignore uncolored works */ | 1702 | /* ignore uncolored works */ |
1682 | if (color == WORK_NO_COLOR) | 1703 | if (color == WORK_NO_COLOR) |
1683 | return; | 1704 | return; |
1684 | 1705 | ||
1685 | cwq->nr_in_flight[color]--; | 1706 | cwq->nr_in_flight[color]--; |
1686 | cwq->nr_active--; | ||
1687 | 1707 | ||
1688 | if (!list_empty(&cwq->delayed_works)) { | 1708 | if (!delayed) { |
1689 | /* one down, submit a delayed one */ | 1709 | cwq->nr_active--; |
1690 | if (cwq->nr_active < cwq->max_active) | 1710 | if (!list_empty(&cwq->delayed_works)) { |
1691 | cwq_activate_first_delayed(cwq); | 1711 | /* one down, submit a delayed one */ |
1712 | if (cwq->nr_active < cwq->max_active) | ||
1713 | cwq_activate_first_delayed(cwq); | ||
1714 | } | ||
1692 | } | 1715 | } |
1693 | 1716 | ||
1694 | /* is flush in progress and are we at the flushing tip? */ | 1717 | /* is flush in progress and are we at the flushing tip? */ |
@@ -1725,6 +1748,8 @@ static void cwq_dec_nr_in_flight(struct cpu_workqueue_struct *cwq, int color) | |||
1725 | * spin_lock_irq(gcwq->lock) which is released and regrabbed. | 1748 | * spin_lock_irq(gcwq->lock) which is released and regrabbed. |
1726 | */ | 1749 | */ |
1727 | static void process_one_work(struct worker *worker, struct work_struct *work) | 1750 | static void process_one_work(struct worker *worker, struct work_struct *work) |
1751 | __releases(&gcwq->lock) | ||
1752 | __acquires(&gcwq->lock) | ||
1728 | { | 1753 | { |
1729 | struct cpu_workqueue_struct *cwq = get_work_cwq(work); | 1754 | struct cpu_workqueue_struct *cwq = get_work_cwq(work); |
1730 | struct global_cwq *gcwq = cwq->gcwq; | 1755 | struct global_cwq *gcwq = cwq->gcwq; |
@@ -1823,7 +1848,7 @@ static void process_one_work(struct worker *worker, struct work_struct *work) | |||
1823 | hlist_del_init(&worker->hentry); | 1848 | hlist_del_init(&worker->hentry); |
1824 | worker->current_work = NULL; | 1849 | worker->current_work = NULL; |
1825 | worker->current_cwq = NULL; | 1850 | worker->current_cwq = NULL; |
1826 | cwq_dec_nr_in_flight(cwq, work_color); | 1851 | cwq_dec_nr_in_flight(cwq, work_color, false); |
1827 | } | 1852 | } |
1828 | 1853 | ||
1829 | /** | 1854 | /** |
@@ -2388,7 +2413,8 @@ static int try_to_grab_pending(struct work_struct *work) | |||
2388 | debug_work_deactivate(work); | 2413 | debug_work_deactivate(work); |
2389 | list_del_init(&work->entry); | 2414 | list_del_init(&work->entry); |
2390 | cwq_dec_nr_in_flight(get_work_cwq(work), | 2415 | cwq_dec_nr_in_flight(get_work_cwq(work), |
2391 | get_work_color(work)); | 2416 | get_work_color(work), |
2417 | *work_data_bits(work) & WORK_STRUCT_DELAYED); | ||
2392 | ret = 1; | 2418 | ret = 1; |
2393 | } | 2419 | } |
2394 | } | 2420 | } |
@@ -2791,7 +2817,6 @@ struct workqueue_struct *__alloc_workqueue_key(const char *name, | |||
2791 | if (IS_ERR(rescuer->task)) | 2817 | if (IS_ERR(rescuer->task)) |
2792 | goto err; | 2818 | goto err; |
2793 | 2819 | ||
2794 | wq->rescuer = rescuer; | ||
2795 | rescuer->task->flags |= PF_THREAD_BOUND; | 2820 | rescuer->task->flags |= PF_THREAD_BOUND; |
2796 | wake_up_process(rescuer->task); | 2821 | wake_up_process(rescuer->task); |
2797 | } | 2822 | } |
@@ -2833,6 +2858,7 @@ void destroy_workqueue(struct workqueue_struct *wq) | |||
2833 | { | 2858 | { |
2834 | unsigned int cpu; | 2859 | unsigned int cpu; |
2835 | 2860 | ||
2861 | wq->flags |= WQ_DYING; | ||
2836 | flush_workqueue(wq); | 2862 | flush_workqueue(wq); |
2837 | 2863 | ||
2838 | /* | 2864 | /* |
@@ -2857,6 +2883,7 @@ void destroy_workqueue(struct workqueue_struct *wq) | |||
2857 | if (wq->flags & WQ_RESCUER) { | 2883 | if (wq->flags & WQ_RESCUER) { |
2858 | kthread_stop(wq->rescuer->task); | 2884 | kthread_stop(wq->rescuer->task); |
2859 | free_mayday_mask(wq->mayday_mask); | 2885 | free_mayday_mask(wq->mayday_mask); |
2886 | kfree(wq->rescuer); | ||
2860 | } | 2887 | } |
2861 | 2888 | ||
2862 | free_cwqs(wq); | 2889 | free_cwqs(wq); |
@@ -3239,6 +3266,8 @@ static int __cpuinit trustee_thread(void *__gcwq) | |||
3239 | * multiple times. To be used by cpu_callback. | 3266 | * multiple times. To be used by cpu_callback. |
3240 | */ | 3267 | */ |
3241 | static void __cpuinit wait_trustee_state(struct global_cwq *gcwq, int state) | 3268 | static void __cpuinit wait_trustee_state(struct global_cwq *gcwq, int state) |
3269 | __releases(&gcwq->lock) | ||
3270 | __acquires(&gcwq->lock) | ||
3242 | { | 3271 | { |
3243 | if (!(gcwq->trustee_state == state || | 3272 | if (!(gcwq->trustee_state == state || |
3244 | gcwq->trustee_state == TRUSTEE_DONE)) { | 3273 | gcwq->trustee_state == TRUSTEE_DONE)) { |
@@ -3545,8 +3574,7 @@ static int __init init_workqueues(void) | |||
3545 | spin_lock_init(&gcwq->lock); | 3574 | spin_lock_init(&gcwq->lock); |
3546 | INIT_LIST_HEAD(&gcwq->worklist); | 3575 | INIT_LIST_HEAD(&gcwq->worklist); |
3547 | gcwq->cpu = cpu; | 3576 | gcwq->cpu = cpu; |
3548 | if (cpu == WORK_CPU_UNBOUND) | 3577 | gcwq->flags |= GCWQ_DISASSOCIATED; |
3549 | gcwq->flags |= GCWQ_DISASSOCIATED; | ||
3550 | 3578 | ||
3551 | INIT_LIST_HEAD(&gcwq->idle_list); | 3579 | INIT_LIST_HEAD(&gcwq->idle_list); |
3552 | for (i = 0; i < BUSY_WORKER_HASH_SIZE; i++) | 3580 | for (i = 0; i < BUSY_WORKER_HASH_SIZE; i++) |
@@ -3570,6 +3598,8 @@ static int __init init_workqueues(void) | |||
3570 | struct global_cwq *gcwq = get_gcwq(cpu); | 3598 | struct global_cwq *gcwq = get_gcwq(cpu); |
3571 | struct worker *worker; | 3599 | struct worker *worker; |
3572 | 3600 | ||
3601 | if (cpu != WORK_CPU_UNBOUND) | ||
3602 | gcwq->flags &= ~GCWQ_DISASSOCIATED; | ||
3573 | worker = create_worker(gcwq, true); | 3603 | worker = create_worker(gcwq, true); |
3574 | BUG_ON(!worker); | 3604 | BUG_ON(!worker); |
3575 | spin_lock_irq(&gcwq->lock); | 3605 | spin_lock_irq(&gcwq->lock); |
@@ -72,8 +72,8 @@ static const struct bug_entry *module_find_bug(unsigned long bugaddr) | |||
72 | return NULL; | 72 | return NULL; |
73 | } | 73 | } |
74 | 74 | ||
75 | int module_bug_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, | 75 | void module_bug_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, |
76 | struct module *mod) | 76 | struct module *mod) |
77 | { | 77 | { |
78 | char *secstrings; | 78 | char *secstrings; |
79 | unsigned int i; | 79 | unsigned int i; |
@@ -97,8 +97,6 @@ int module_bug_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, | |||
97 | * could potentially lead to deadlock and thus be counter-productive. | 97 | * could potentially lead to deadlock and thus be counter-productive. |
98 | */ | 98 | */ |
99 | list_add(&mod->bug_list, &module_bug_list); | 99 | list_add(&mod->bug_list, &module_bug_list); |
100 | |||
101 | return 0; | ||
102 | } | 100 | } |
103 | 101 | ||
104 | void module_bug_cleanup(struct module *mod) | 102 | void module_bug_cleanup(struct module *mod) |
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c index b93579504df..70af0a7f97c 100644 --- a/lib/kobject_uevent.c +++ b/lib/kobject_uevent.c | |||
@@ -123,7 +123,7 @@ static int kobj_usermode_filter(struct kobject *kobj) | |||
123 | * @kobj: struct kobject that the action is happening to | 123 | * @kobj: struct kobject that the action is happening to |
124 | * @envp_ext: pointer to environmental data | 124 | * @envp_ext: pointer to environmental data |
125 | * | 125 | * |
126 | * Returns 0 if kobject_uevent() is completed with success or the | 126 | * Returns 0 if kobject_uevent_env() is completed with success or the |
127 | * corresponding error when it fails. | 127 | * corresponding error when it fails. |
128 | */ | 128 | */ |
129 | int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, | 129 | int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, |
@@ -317,7 +317,7 @@ exit: | |||
317 | EXPORT_SYMBOL_GPL(kobject_uevent_env); | 317 | EXPORT_SYMBOL_GPL(kobject_uevent_env); |
318 | 318 | ||
319 | /** | 319 | /** |
320 | * kobject_uevent - notify userspace by ending an uevent | 320 | * kobject_uevent - notify userspace by sending an uevent |
321 | * | 321 | * |
322 | * @action: action that is happening | 322 | * @action: action that is happening |
323 | * @kobj: struct kobject that the action is happening to | 323 | * @kobj: struct kobject that the action is happening to |
diff --git a/lib/list_sort.c b/lib/list_sort.c index 4b5cb794c38..a7616fa3162 100644 --- a/lib/list_sort.c +++ b/lib/list_sort.c | |||
@@ -70,7 +70,7 @@ static void merge_and_restore_back_links(void *priv, | |||
70 | * element comparison is needed, so the client's cmp() | 70 | * element comparison is needed, so the client's cmp() |
71 | * routine can invoke cond_resched() periodically. | 71 | * routine can invoke cond_resched() periodically. |
72 | */ | 72 | */ |
73 | (*cmp)(priv, tail, tail); | 73 | (*cmp)(priv, tail->next, tail->next); |
74 | 74 | ||
75 | tail->next->prev = tail; | 75 | tail->next->prev = tail; |
76 | tail = tail->next; | 76 | tail = tail->next; |
diff --git a/lib/radix-tree.c b/lib/radix-tree.c index 5b7d4623f0b..efd16fa80b1 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c | |||
@@ -174,14 +174,16 @@ static void radix_tree_node_rcu_free(struct rcu_head *head) | |||
174 | { | 174 | { |
175 | struct radix_tree_node *node = | 175 | struct radix_tree_node *node = |
176 | container_of(head, struct radix_tree_node, rcu_head); | 176 | container_of(head, struct radix_tree_node, rcu_head); |
177 | int i; | ||
177 | 178 | ||
178 | /* | 179 | /* |
179 | * must only free zeroed nodes into the slab. radix_tree_shrink | 180 | * must only free zeroed nodes into the slab. radix_tree_shrink |
180 | * can leave us with a non-NULL entry in the first slot, so clear | 181 | * can leave us with a non-NULL entry in the first slot, so clear |
181 | * that here to make sure. | 182 | * that here to make sure. |
182 | */ | 183 | */ |
183 | tag_clear(node, 0, 0); | 184 | for (i = 0; i < RADIX_TREE_MAX_TAGS; i++) |
184 | tag_clear(node, 1, 0); | 185 | tag_clear(node, i, 0); |
186 | |||
185 | node->slots[0] = NULL; | 187 | node->slots[0] = NULL; |
186 | node->count = 0; | 188 | node->count = 0; |
187 | 189 | ||
@@ -623,6 +625,13 @@ EXPORT_SYMBOL(radix_tree_tag_get); | |||
623 | * also settag. The function stops either after tagging nr_to_tag items or | 625 | * also settag. The function stops either after tagging nr_to_tag items or |
624 | * after reaching last_index. | 626 | * after reaching last_index. |
625 | * | 627 | * |
628 | * The tags must be set from the leaf level only and propagated back up the | ||
629 | * path to the root. We must do this so that we resolve the full path before | ||
630 | * setting any tags on intermediate nodes. If we set tags as we descend, then | ||
631 | * we can get to the leaf node and find that the index that has the iftag | ||
632 | * set is outside the range we are scanning. This reults in dangling tags and | ||
633 | * can lead to problems with later tag operations (e.g. livelocks on lookups). | ||
634 | * | ||
626 | * The function returns number of leaves where the tag was set and sets | 635 | * The function returns number of leaves where the tag was set and sets |
627 | * *first_indexp to the first unscanned index. | 636 | * *first_indexp to the first unscanned index. |
628 | * WARNING! *first_indexp can wrap if last_index is ULONG_MAX. Caller must | 637 | * WARNING! *first_indexp can wrap if last_index is ULONG_MAX. Caller must |
@@ -633,9 +642,13 @@ unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root, | |||
633 | unsigned long nr_to_tag, | 642 | unsigned long nr_to_tag, |
634 | unsigned int iftag, unsigned int settag) | 643 | unsigned int iftag, unsigned int settag) |
635 | { | 644 | { |
636 | unsigned int height = root->height, shift; | 645 | unsigned int height = root->height; |
637 | unsigned long tagged = 0, index = *first_indexp; | 646 | struct radix_tree_path path[height]; |
638 | struct radix_tree_node *open_slots[height], *slot; | 647 | struct radix_tree_path *pathp = path; |
648 | struct radix_tree_node *slot; | ||
649 | unsigned int shift; | ||
650 | unsigned long tagged = 0; | ||
651 | unsigned long index = *first_indexp; | ||
639 | 652 | ||
640 | last_index = min(last_index, radix_tree_maxindex(height)); | 653 | last_index = min(last_index, radix_tree_maxindex(height)); |
641 | if (index > last_index) | 654 | if (index > last_index) |
@@ -655,6 +668,13 @@ unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root, | |||
655 | shift = (height - 1) * RADIX_TREE_MAP_SHIFT; | 668 | shift = (height - 1) * RADIX_TREE_MAP_SHIFT; |
656 | slot = radix_tree_indirect_to_ptr(root->rnode); | 669 | slot = radix_tree_indirect_to_ptr(root->rnode); |
657 | 670 | ||
671 | /* | ||
672 | * we fill the path from (root->height - 2) to 0, leaving the index at | ||
673 | * (root->height - 1) as a terminator. Zero the node in the terminator | ||
674 | * so that we can use this to end walk loops back up the path. | ||
675 | */ | ||
676 | path[height - 1].node = NULL; | ||
677 | |||
658 | for (;;) { | 678 | for (;;) { |
659 | int offset; | 679 | int offset; |
660 | 680 | ||
@@ -663,17 +683,30 @@ unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root, | |||
663 | goto next; | 683 | goto next; |
664 | if (!tag_get(slot, iftag, offset)) | 684 | if (!tag_get(slot, iftag, offset)) |
665 | goto next; | 685 | goto next; |
686 | if (height > 1) { | ||
687 | /* Go down one level */ | ||
688 | height--; | ||
689 | shift -= RADIX_TREE_MAP_SHIFT; | ||
690 | path[height - 1].node = slot; | ||
691 | path[height - 1].offset = offset; | ||
692 | slot = slot->slots[offset]; | ||
693 | continue; | ||
694 | } | ||
695 | |||
696 | /* tag the leaf */ | ||
697 | tagged++; | ||
666 | tag_set(slot, settag, offset); | 698 | tag_set(slot, settag, offset); |
667 | if (height == 1) { | 699 | |
668 | tagged++; | 700 | /* walk back up the path tagging interior nodes */ |
669 | goto next; | 701 | pathp = &path[0]; |
702 | while (pathp->node) { | ||
703 | /* stop if we find a node with the tag already set */ | ||
704 | if (tag_get(pathp->node, settag, pathp->offset)) | ||
705 | break; | ||
706 | tag_set(pathp->node, settag, pathp->offset); | ||
707 | pathp++; | ||
670 | } | 708 | } |
671 | /* Go down one level */ | 709 | |
672 | height--; | ||
673 | shift -= RADIX_TREE_MAP_SHIFT; | ||
674 | open_slots[height] = slot; | ||
675 | slot = slot->slots[offset]; | ||
676 | continue; | ||
677 | next: | 710 | next: |
678 | /* Go to next item at level determined by 'shift' */ | 711 | /* Go to next item at level determined by 'shift' */ |
679 | index = ((index >> shift) + 1) << shift; | 712 | index = ((index >> shift) + 1) << shift; |
@@ -688,7 +721,7 @@ next: | |||
688 | * last_index is guaranteed to be in the tree, what | 721 | * last_index is guaranteed to be in the tree, what |
689 | * we do below cannot wander astray. | 722 | * we do below cannot wander astray. |
690 | */ | 723 | */ |
691 | slot = open_slots[height]; | 724 | slot = path[height - 1].node; |
692 | height++; | 725 | height++; |
693 | shift += RADIX_TREE_MAP_SHIFT; | 726 | shift += RADIX_TREE_MAP_SHIFT; |
694 | } | 727 | } |
diff --git a/lib/raid6/.gitignore b/lib/raid6/.gitignore new file mode 100644 index 00000000000..162becacf97 --- /dev/null +++ b/lib/raid6/.gitignore | |||
@@ -0,0 +1,4 @@ | |||
1 | mktables | ||
2 | altivec*.c | ||
3 | int*.c | ||
4 | tables.c | ||
diff --git a/lib/scatterlist.c b/lib/scatterlist.c index a5ec42868f9..4ceb05d772a 100644 --- a/lib/scatterlist.c +++ b/lib/scatterlist.c | |||
@@ -248,8 +248,18 @@ int __sg_alloc_table(struct sg_table *table, unsigned int nents, | |||
248 | left -= sg_size; | 248 | left -= sg_size; |
249 | 249 | ||
250 | sg = alloc_fn(alloc_size, gfp_mask); | 250 | sg = alloc_fn(alloc_size, gfp_mask); |
251 | if (unlikely(!sg)) | 251 | if (unlikely(!sg)) { |
252 | return -ENOMEM; | 252 | /* |
253 | * Adjust entry count to reflect that the last | ||
254 | * entry of the previous table won't be used for | ||
255 | * linkage. Without this, sg_kfree() may get | ||
256 | * confused. | ||
257 | */ | ||
258 | if (prv) | ||
259 | table->nents = ++table->orig_nents; | ||
260 | |||
261 | return -ENOMEM; | ||
262 | } | ||
253 | 263 | ||
254 | sg_init_table(sg, alloc_size); | 264 | sg_init_table(sg, alloc_size); |
255 | table->nents = table->orig_nents += sg_size; | 265 | table->nents = table->orig_nents += sg_size; |
diff --git a/mm/Kconfig b/mm/Kconfig index f4e516e9c37..f0fb9124e41 100644 --- a/mm/Kconfig +++ b/mm/Kconfig | |||
@@ -189,7 +189,7 @@ config COMPACTION | |||
189 | config MIGRATION | 189 | config MIGRATION |
190 | bool "Page migration" | 190 | bool "Page migration" |
191 | def_bool y | 191 | def_bool y |
192 | depends on NUMA || ARCH_ENABLE_MEMORY_HOTREMOVE | 192 | depends on NUMA || ARCH_ENABLE_MEMORY_HOTREMOVE || COMPACTION |
193 | help | 193 | help |
194 | Allows the migration of the physical location of pages of processes | 194 | Allows the migration of the physical location of pages of processes |
195 | while the virtual addresses are not changed. This is useful in | 195 | while the virtual addresses are not changed. This is useful in |
diff --git a/mm/backing-dev.c b/mm/backing-dev.c index eaa4a5bbe06..65d420499a6 100644 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c | |||
@@ -30,6 +30,7 @@ EXPORT_SYMBOL_GPL(default_backing_dev_info); | |||
30 | 30 | ||
31 | struct backing_dev_info noop_backing_dev_info = { | 31 | struct backing_dev_info noop_backing_dev_info = { |
32 | .name = "noop", | 32 | .name = "noop", |
33 | .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK, | ||
33 | }; | 34 | }; |
34 | EXPORT_SYMBOL_GPL(noop_backing_dev_info); | 35 | EXPORT_SYMBOL_GPL(noop_backing_dev_info); |
35 | 36 | ||
@@ -243,6 +244,7 @@ static int __init default_bdi_init(void) | |||
243 | err = bdi_init(&default_backing_dev_info); | 244 | err = bdi_init(&default_backing_dev_info); |
244 | if (!err) | 245 | if (!err) |
245 | bdi_register(&default_backing_dev_info, NULL, "default"); | 246 | bdi_register(&default_backing_dev_info, NULL, "default"); |
247 | err = bdi_init(&noop_backing_dev_info); | ||
246 | 248 | ||
247 | return err; | 249 | return err; |
248 | } | 250 | } |
@@ -445,8 +447,8 @@ static int bdi_forker_thread(void *ptr) | |||
445 | switch (action) { | 447 | switch (action) { |
446 | case FORK_THREAD: | 448 | case FORK_THREAD: |
447 | __set_current_state(TASK_RUNNING); | 449 | __set_current_state(TASK_RUNNING); |
448 | task = kthread_run(bdi_writeback_thread, &bdi->wb, "flush-%s", | 450 | task = kthread_create(bdi_writeback_thread, &bdi->wb, |
449 | dev_name(bdi->dev)); | 451 | "flush-%s", dev_name(bdi->dev)); |
450 | if (IS_ERR(task)) { | 452 | if (IS_ERR(task)) { |
451 | /* | 453 | /* |
452 | * If thread creation fails, force writeout of | 454 | * If thread creation fails, force writeout of |
@@ -457,10 +459,13 @@ static int bdi_forker_thread(void *ptr) | |||
457 | /* | 459 | /* |
458 | * The spinlock makes sure we do not lose | 460 | * The spinlock makes sure we do not lose |
459 | * wake-ups when racing with 'bdi_queue_work()'. | 461 | * wake-ups when racing with 'bdi_queue_work()'. |
462 | * And as soon as the bdi thread is visible, we | ||
463 | * can start it. | ||
460 | */ | 464 | */ |
461 | spin_lock_bh(&bdi->wb_lock); | 465 | spin_lock_bh(&bdi->wb_lock); |
462 | bdi->wb.task = task; | 466 | bdi->wb.task = task; |
463 | spin_unlock_bh(&bdi->wb_lock); | 467 | spin_unlock_bh(&bdi->wb_lock); |
468 | wake_up_process(task); | ||
464 | } | 469 | } |
465 | break; | 470 | break; |
466 | 471 | ||
diff --git a/mm/bounce.c b/mm/bounce.c index 13b6dad1eed..1481de68184 100644 --- a/mm/bounce.c +++ b/mm/bounce.c | |||
@@ -116,8 +116,8 @@ static void copy_to_high_bio_irq(struct bio *to, struct bio *from) | |||
116 | */ | 116 | */ |
117 | vfrom = page_address(fromvec->bv_page) + tovec->bv_offset; | 117 | vfrom = page_address(fromvec->bv_page) + tovec->bv_offset; |
118 | 118 | ||
119 | flush_dcache_page(tovec->bv_page); | ||
120 | bounce_copy_vec(tovec, vfrom); | 119 | bounce_copy_vec(tovec, vfrom); |
120 | flush_dcache_page(tovec->bv_page); | ||
121 | } | 121 | } |
122 | } | 122 | } |
123 | 123 | ||
diff --git a/mm/compaction.c b/mm/compaction.c index 94cce51b0b3..4d709ee5901 100644 --- a/mm/compaction.c +++ b/mm/compaction.c | |||
@@ -214,15 +214,16 @@ static void acct_isolated(struct zone *zone, struct compact_control *cc) | |||
214 | /* Similar to reclaim, but different enough that they don't share logic */ | 214 | /* Similar to reclaim, but different enough that they don't share logic */ |
215 | static bool too_many_isolated(struct zone *zone) | 215 | static bool too_many_isolated(struct zone *zone) |
216 | { | 216 | { |
217 | 217 | unsigned long active, inactive, isolated; | |
218 | unsigned long inactive, isolated; | ||
219 | 218 | ||
220 | inactive = zone_page_state(zone, NR_INACTIVE_FILE) + | 219 | inactive = zone_page_state(zone, NR_INACTIVE_FILE) + |
221 | zone_page_state(zone, NR_INACTIVE_ANON); | 220 | zone_page_state(zone, NR_INACTIVE_ANON); |
221 | active = zone_page_state(zone, NR_ACTIVE_FILE) + | ||
222 | zone_page_state(zone, NR_ACTIVE_ANON); | ||
222 | isolated = zone_page_state(zone, NR_ISOLATED_FILE) + | 223 | isolated = zone_page_state(zone, NR_ISOLATED_FILE) + |
223 | zone_page_state(zone, NR_ISOLATED_ANON); | 224 | zone_page_state(zone, NR_ISOLATED_ANON); |
224 | 225 | ||
225 | return isolated > inactive; | 226 | return isolated > (inactive + active) / 2; |
226 | } | 227 | } |
227 | 228 | ||
228 | /* | 229 | /* |
diff --git a/mm/fremap.c b/mm/fremap.c index 46f5dacf90a..ec520c7b28d 100644 --- a/mm/fremap.c +++ b/mm/fremap.c | |||
@@ -125,7 +125,6 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, | |||
125 | { | 125 | { |
126 | struct mm_struct *mm = current->mm; | 126 | struct mm_struct *mm = current->mm; |
127 | struct address_space *mapping; | 127 | struct address_space *mapping; |
128 | unsigned long end = start + size; | ||
129 | struct vm_area_struct *vma; | 128 | struct vm_area_struct *vma; |
130 | int err = -EINVAL; | 129 | int err = -EINVAL; |
131 | int has_write_lock = 0; | 130 | int has_write_lock = 0; |
@@ -142,6 +141,10 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, | |||
142 | if (start + size <= start) | 141 | if (start + size <= start) |
143 | return err; | 142 | return err; |
144 | 143 | ||
144 | /* Does pgoff wrap? */ | ||
145 | if (pgoff + (size >> PAGE_SHIFT) < pgoff) | ||
146 | return err; | ||
147 | |||
145 | /* Can we represent this offset inside this architecture's pte's? */ | 148 | /* Can we represent this offset inside this architecture's pte's? */ |
146 | #if PTE_FILE_MAX_BITS < BITS_PER_LONG | 149 | #if PTE_FILE_MAX_BITS < BITS_PER_LONG |
147 | if (pgoff + (size >> PAGE_SHIFT) >= (1UL << PTE_FILE_MAX_BITS)) | 150 | if (pgoff + (size >> PAGE_SHIFT) >= (1UL << PTE_FILE_MAX_BITS)) |
@@ -168,7 +171,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, | |||
168 | if (!(vma->vm_flags & VM_CAN_NONLINEAR)) | 171 | if (!(vma->vm_flags & VM_CAN_NONLINEAR)) |
169 | goto out; | 172 | goto out; |
170 | 173 | ||
171 | if (end <= start || start < vma->vm_start || end > vma->vm_end) | 174 | if (start < vma->vm_start || start + size > vma->vm_end) |
172 | goto out; | 175 | goto out; |
173 | 176 | ||
174 | /* Must set VM_NONLINEAR before any pages are populated. */ | 177 | /* Must set VM_NONLINEAR before any pages are populated. */ |
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index cc5be788a39..c0327380718 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
@@ -2324,11 +2324,8 @@ retry_avoidcopy: | |||
2324 | * and just make the page writable */ | 2324 | * and just make the page writable */ |
2325 | avoidcopy = (page_mapcount(old_page) == 1); | 2325 | avoidcopy = (page_mapcount(old_page) == 1); |
2326 | if (avoidcopy) { | 2326 | if (avoidcopy) { |
2327 | if (!trylock_page(old_page)) { | 2327 | if (PageAnon(old_page)) |
2328 | if (PageAnon(old_page)) | 2328 | page_move_anon_rmap(old_page, vma, address); |
2329 | page_move_anon_rmap(old_page, vma, address); | ||
2330 | } else | ||
2331 | unlock_page(old_page); | ||
2332 | set_huge_ptep_writable(vma, address, ptep); | 2329 | set_huge_ptep_writable(vma, address, ptep); |
2333 | return 0; | 2330 | return 0; |
2334 | } | 2331 | } |
@@ -2404,7 +2401,7 @@ retry_avoidcopy: | |||
2404 | set_huge_pte_at(mm, address, ptep, | 2401 | set_huge_pte_at(mm, address, ptep, |
2405 | make_huge_pte(vma, new_page, 1)); | 2402 | make_huge_pte(vma, new_page, 1)); |
2406 | page_remove_rmap(old_page); | 2403 | page_remove_rmap(old_page); |
2407 | hugepage_add_anon_rmap(new_page, vma, address); | 2404 | hugepage_add_new_anon_rmap(new_page, vma, address); |
2408 | /* Make the old page be freed below */ | 2405 | /* Make the old page be freed below */ |
2409 | new_page = old_page; | 2406 | new_page = old_page; |
2410 | mmu_notifier_invalidate_range_end(mm, | 2407 | mmu_notifier_invalidate_range_end(mm, |
@@ -2631,10 +2628,16 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2631 | vma, address); | 2628 | vma, address); |
2632 | } | 2629 | } |
2633 | 2630 | ||
2634 | if (!pagecache_page) { | 2631 | /* |
2635 | page = pte_page(entry); | 2632 | * hugetlb_cow() requires page locks of pte_page(entry) and |
2633 | * pagecache_page, so here we need take the former one | ||
2634 | * when page != pagecache_page or !pagecache_page. | ||
2635 | * Note that locking order is always pagecache_page -> page, | ||
2636 | * so no worry about deadlock. | ||
2637 | */ | ||
2638 | page = pte_page(entry); | ||
2639 | if (page != pagecache_page) | ||
2636 | lock_page(page); | 2640 | lock_page(page); |
2637 | } | ||
2638 | 2641 | ||
2639 | spin_lock(&mm->page_table_lock); | 2642 | spin_lock(&mm->page_table_lock); |
2640 | /* Check for a racing update before calling hugetlb_cow */ | 2643 | /* Check for a racing update before calling hugetlb_cow */ |
@@ -2661,9 +2664,8 @@ out_page_table_lock: | |||
2661 | if (pagecache_page) { | 2664 | if (pagecache_page) { |
2662 | unlock_page(pagecache_page); | 2665 | unlock_page(pagecache_page); |
2663 | put_page(pagecache_page); | 2666 | put_page(pagecache_page); |
2664 | } else { | ||
2665 | unlock_page(page); | ||
2666 | } | 2667 | } |
2668 | unlock_page(page); | ||
2667 | 2669 | ||
2668 | out_mutex: | 2670 | out_mutex: |
2669 | mutex_unlock(&hugetlb_instantiation_mutex); | 2671 | mutex_unlock(&hugetlb_instantiation_mutex); |
@@ -712,7 +712,7 @@ static int write_protect_page(struct vm_area_struct *vma, struct page *page, | |||
712 | if (!ptep) | 712 | if (!ptep) |
713 | goto out; | 713 | goto out; |
714 | 714 | ||
715 | if (pte_write(*ptep)) { | 715 | if (pte_write(*ptep) || pte_dirty(*ptep)) { |
716 | pte_t entry; | 716 | pte_t entry; |
717 | 717 | ||
718 | swapped = PageSwapCache(page); | 718 | swapped = PageSwapCache(page); |
@@ -735,7 +735,9 @@ static int write_protect_page(struct vm_area_struct *vma, struct page *page, | |||
735 | set_pte_at(mm, addr, ptep, entry); | 735 | set_pte_at(mm, addr, ptep, entry); |
736 | goto out_unlock; | 736 | goto out_unlock; |
737 | } | 737 | } |
738 | entry = pte_wrprotect(entry); | 738 | if (pte_dirty(entry)) |
739 | set_page_dirty(page); | ||
740 | entry = pte_mkclean(pte_wrprotect(entry)); | ||
739 | set_pte_at_notify(mm, addr, ptep, entry); | 741 | set_pte_at_notify(mm, addr, ptep, entry); |
740 | } | 742 | } |
741 | *orig_pte = *ptep; | 743 | *orig_pte = *ptep; |
@@ -1504,8 +1506,6 @@ struct page *ksm_does_need_to_copy(struct page *page, | |||
1504 | { | 1506 | { |
1505 | struct page *new_page; | 1507 | struct page *new_page; |
1506 | 1508 | ||
1507 | unlock_page(page); /* any racers will COW it, not modify it */ | ||
1508 | |||
1509 | new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, address); | 1509 | new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, address); |
1510 | if (new_page) { | 1510 | if (new_page) { |
1511 | copy_user_highpage(new_page, page, address, vma); | 1511 | copy_user_highpage(new_page, page, address, vma); |
@@ -1521,7 +1521,6 @@ struct page *ksm_does_need_to_copy(struct page *page, | |||
1521 | add_page_to_unevictable_list(new_page); | 1521 | add_page_to_unevictable_list(new_page); |
1522 | } | 1522 | } |
1523 | 1523 | ||
1524 | page_cache_release(page); | ||
1525 | return new_page; | 1524 | return new_page; |
1526 | } | 1525 | } |
1527 | 1526 | ||
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 3eed583895a..9be3cf8a5da 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -3587,9 +3587,13 @@ unlock: | |||
3587 | 3587 | ||
3588 | static void mem_cgroup_threshold(struct mem_cgroup *memcg) | 3588 | static void mem_cgroup_threshold(struct mem_cgroup *memcg) |
3589 | { | 3589 | { |
3590 | __mem_cgroup_threshold(memcg, false); | 3590 | while (memcg) { |
3591 | if (do_swap_account) | 3591 | __mem_cgroup_threshold(memcg, false); |
3592 | __mem_cgroup_threshold(memcg, true); | 3592 | if (do_swap_account) |
3593 | __mem_cgroup_threshold(memcg, true); | ||
3594 | |||
3595 | memcg = parent_mem_cgroup(memcg); | ||
3596 | } | ||
3593 | } | 3597 | } |
3594 | 3598 | ||
3595 | static int compare_thresholds(const void *a, const void *b) | 3599 | static int compare_thresholds(const void *a, const void *b) |
diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 9c26eeca134..757f6b0accf 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c | |||
@@ -183,7 +183,7 @@ EXPORT_SYMBOL_GPL(hwpoison_filter); | |||
183 | * signal. | 183 | * signal. |
184 | */ | 184 | */ |
185 | static int kill_proc_ao(struct task_struct *t, unsigned long addr, int trapno, | 185 | static int kill_proc_ao(struct task_struct *t, unsigned long addr, int trapno, |
186 | unsigned long pfn) | 186 | unsigned long pfn, struct page *page) |
187 | { | 187 | { |
188 | struct siginfo si; | 188 | struct siginfo si; |
189 | int ret; | 189 | int ret; |
@@ -198,7 +198,7 @@ static int kill_proc_ao(struct task_struct *t, unsigned long addr, int trapno, | |||
198 | #ifdef __ARCH_SI_TRAPNO | 198 | #ifdef __ARCH_SI_TRAPNO |
199 | si.si_trapno = trapno; | 199 | si.si_trapno = trapno; |
200 | #endif | 200 | #endif |
201 | si.si_addr_lsb = PAGE_SHIFT; | 201 | si.si_addr_lsb = compound_order(compound_head(page)) + PAGE_SHIFT; |
202 | /* | 202 | /* |
203 | * Don't use force here, it's convenient if the signal | 203 | * Don't use force here, it's convenient if the signal |
204 | * can be temporarily blocked. | 204 | * can be temporarily blocked. |
@@ -235,7 +235,7 @@ void shake_page(struct page *p, int access) | |||
235 | int nr; | 235 | int nr; |
236 | do { | 236 | do { |
237 | nr = shrink_slab(1000, GFP_KERNEL, 1000); | 237 | nr = shrink_slab(1000, GFP_KERNEL, 1000); |
238 | if (page_count(p) == 0) | 238 | if (page_count(p) == 1) |
239 | break; | 239 | break; |
240 | } while (nr > 10); | 240 | } while (nr > 10); |
241 | } | 241 | } |
@@ -327,7 +327,7 @@ static void add_to_kill(struct task_struct *tsk, struct page *p, | |||
327 | * wrong earlier. | 327 | * wrong earlier. |
328 | */ | 328 | */ |
329 | static void kill_procs_ao(struct list_head *to_kill, int doit, int trapno, | 329 | static void kill_procs_ao(struct list_head *to_kill, int doit, int trapno, |
330 | int fail, unsigned long pfn) | 330 | int fail, struct page *page, unsigned long pfn) |
331 | { | 331 | { |
332 | struct to_kill *tk, *next; | 332 | struct to_kill *tk, *next; |
333 | 333 | ||
@@ -352,7 +352,7 @@ static void kill_procs_ao(struct list_head *to_kill, int doit, int trapno, | |||
352 | * process anyways. | 352 | * process anyways. |
353 | */ | 353 | */ |
354 | else if (kill_proc_ao(tk->tsk, tk->addr, trapno, | 354 | else if (kill_proc_ao(tk->tsk, tk->addr, trapno, |
355 | pfn) < 0) | 355 | pfn, page) < 0) |
356 | printk(KERN_ERR | 356 | printk(KERN_ERR |
357 | "MCE %#lx: Cannot send advisory machine check signal to %s:%d\n", | 357 | "MCE %#lx: Cannot send advisory machine check signal to %s:%d\n", |
358 | pfn, tk->tsk->comm, tk->tsk->pid); | 358 | pfn, tk->tsk->comm, tk->tsk->pid); |
@@ -928,7 +928,7 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn, | |||
928 | * any accesses to the poisoned memory. | 928 | * any accesses to the poisoned memory. |
929 | */ | 929 | */ |
930 | kill_procs_ao(&tokill, !!PageDirty(hpage), trapno, | 930 | kill_procs_ao(&tokill, !!PageDirty(hpage), trapno, |
931 | ret != SWAP_SUCCESS, pfn); | 931 | ret != SWAP_SUCCESS, p, pfn); |
932 | 932 | ||
933 | return ret; | 933 | return ret; |
934 | } | 934 | } |
diff --git a/mm/memory.c b/mm/memory.c index 2ed2267439d..0e18b4d649e 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -2623,7 +2623,7 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2623 | unsigned int flags, pte_t orig_pte) | 2623 | unsigned int flags, pte_t orig_pte) |
2624 | { | 2624 | { |
2625 | spinlock_t *ptl; | 2625 | spinlock_t *ptl; |
2626 | struct page *page; | 2626 | struct page *page, *swapcache = NULL; |
2627 | swp_entry_t entry; | 2627 | swp_entry_t entry; |
2628 | pte_t pte; | 2628 | pte_t pte; |
2629 | struct mem_cgroup *ptr = NULL; | 2629 | struct mem_cgroup *ptr = NULL; |
@@ -2679,10 +2679,25 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2679 | lock_page(page); | 2679 | lock_page(page); |
2680 | delayacct_clear_flag(DELAYACCT_PF_SWAPIN); | 2680 | delayacct_clear_flag(DELAYACCT_PF_SWAPIN); |
2681 | 2681 | ||
2682 | page = ksm_might_need_to_copy(page, vma, address); | 2682 | /* |
2683 | if (!page) { | 2683 | * Make sure try_to_free_swap or reuse_swap_page or swapoff did not |
2684 | ret = VM_FAULT_OOM; | 2684 | * release the swapcache from under us. The page pin, and pte_same |
2685 | goto out; | 2685 | * test below, are not enough to exclude that. Even if it is still |
2686 | * swapcache, we need to check that the page's swap has not changed. | ||
2687 | */ | ||
2688 | if (unlikely(!PageSwapCache(page) || page_private(page) != entry.val)) | ||
2689 | goto out_page; | ||
2690 | |||
2691 | if (ksm_might_need_to_copy(page, vma, address)) { | ||
2692 | swapcache = page; | ||
2693 | page = ksm_does_need_to_copy(page, vma, address); | ||
2694 | |||
2695 | if (unlikely(!page)) { | ||
2696 | ret = VM_FAULT_OOM; | ||
2697 | page = swapcache; | ||
2698 | swapcache = NULL; | ||
2699 | goto out_page; | ||
2700 | } | ||
2686 | } | 2701 | } |
2687 | 2702 | ||
2688 | if (mem_cgroup_try_charge_swapin(mm, page, GFP_KERNEL, &ptr)) { | 2703 | if (mem_cgroup_try_charge_swapin(mm, page, GFP_KERNEL, &ptr)) { |
@@ -2735,6 +2750,18 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2735 | if (vm_swap_full() || (vma->vm_flags & VM_LOCKED) || PageMlocked(page)) | 2750 | if (vm_swap_full() || (vma->vm_flags & VM_LOCKED) || PageMlocked(page)) |
2736 | try_to_free_swap(page); | 2751 | try_to_free_swap(page); |
2737 | unlock_page(page); | 2752 | unlock_page(page); |
2753 | if (swapcache) { | ||
2754 | /* | ||
2755 | * Hold the lock to avoid the swap entry to be reused | ||
2756 | * until we take the PT lock for the pte_same() check | ||
2757 | * (to avoid false positives from pte_same). For | ||
2758 | * further safety release the lock after the swap_free | ||
2759 | * so that the swap count won't change under a | ||
2760 | * parallel locked swapcache. | ||
2761 | */ | ||
2762 | unlock_page(swapcache); | ||
2763 | page_cache_release(swapcache); | ||
2764 | } | ||
2738 | 2765 | ||
2739 | if (flags & FAULT_FLAG_WRITE) { | 2766 | if (flags & FAULT_FLAG_WRITE) { |
2740 | ret |= do_wp_page(mm, vma, address, page_table, pmd, ptl, pte); | 2767 | ret |= do_wp_page(mm, vma, address, page_table, pmd, ptl, pte); |
@@ -2756,15 +2783,17 @@ out_page: | |||
2756 | unlock_page(page); | 2783 | unlock_page(page); |
2757 | out_release: | 2784 | out_release: |
2758 | page_cache_release(page); | 2785 | page_cache_release(page); |
2786 | if (swapcache) { | ||
2787 | unlock_page(swapcache); | ||
2788 | page_cache_release(swapcache); | ||
2789 | } | ||
2759 | return ret; | 2790 | return ret; |
2760 | } | 2791 | } |
2761 | 2792 | ||
2762 | /* | 2793 | /* |
2763 | * This is like a special single-page "expand_downwards()", | 2794 | * This is like a special single-page "expand_{down|up}wards()", |
2764 | * except we must first make sure that 'address-PAGE_SIZE' | 2795 | * except we must first make sure that 'address{-|+}PAGE_SIZE' |
2765 | * doesn't hit another vma. | 2796 | * doesn't hit another vma. |
2766 | * | ||
2767 | * The "find_vma()" will do the right thing even if we wrap | ||
2768 | */ | 2797 | */ |
2769 | static inline int check_stack_guard_page(struct vm_area_struct *vma, unsigned long address) | 2798 | static inline int check_stack_guard_page(struct vm_area_struct *vma, unsigned long address) |
2770 | { | 2799 | { |
@@ -2783,6 +2812,15 @@ static inline int check_stack_guard_page(struct vm_area_struct *vma, unsigned lo | |||
2783 | 2812 | ||
2784 | expand_stack(vma, address - PAGE_SIZE); | 2813 | expand_stack(vma, address - PAGE_SIZE); |
2785 | } | 2814 | } |
2815 | if ((vma->vm_flags & VM_GROWSUP) && address + PAGE_SIZE == vma->vm_end) { | ||
2816 | struct vm_area_struct *next = vma->vm_next; | ||
2817 | |||
2818 | /* As VM_GROWSDOWN but s/below/above/ */ | ||
2819 | if (next && next->vm_start == address + PAGE_SIZE) | ||
2820 | return next->vm_flags & VM_GROWSUP ? 0 : -ENOMEM; | ||
2821 | |||
2822 | expand_upwards(vma, address + PAGE_SIZE); | ||
2823 | } | ||
2786 | return 0; | 2824 | return 0; |
2787 | } | 2825 | } |
2788 | 2826 | ||
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index a4cfcdc0045..dd186c1a5d5 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c | |||
@@ -584,19 +584,19 @@ static inline int pageblock_free(struct page *page) | |||
584 | /* Return the start of the next active pageblock after a given page */ | 584 | /* Return the start of the next active pageblock after a given page */ |
585 | static struct page *next_active_pageblock(struct page *page) | 585 | static struct page *next_active_pageblock(struct page *page) |
586 | { | 586 | { |
587 | int pageblocks_stride; | ||
588 | |||
589 | /* Ensure the starting page is pageblock-aligned */ | 587 | /* Ensure the starting page is pageblock-aligned */ |
590 | BUG_ON(page_to_pfn(page) & (pageblock_nr_pages - 1)); | 588 | BUG_ON(page_to_pfn(page) & (pageblock_nr_pages - 1)); |
591 | 589 | ||
592 | /* Move forward by at least 1 * pageblock_nr_pages */ | ||
593 | pageblocks_stride = 1; | ||
594 | |||
595 | /* If the entire pageblock is free, move to the end of free page */ | 590 | /* If the entire pageblock is free, move to the end of free page */ |
596 | if (pageblock_free(page)) | 591 | if (pageblock_free(page)) { |
597 | pageblocks_stride += page_order(page) - pageblock_order; | 592 | int order; |
593 | /* be careful. we don't have locks, page_order can be changed.*/ | ||
594 | order = page_order(page); | ||
595 | if ((order < MAX_ORDER) && (order >= pageblock_order)) | ||
596 | return page + (1 << order); | ||
597 | } | ||
598 | 598 | ||
599 | return page + (pageblocks_stride * pageblock_nr_pages); | 599 | return page + pageblock_nr_pages; |
600 | } | 600 | } |
601 | 601 | ||
602 | /* Checks if this range of memory is likely to be hot-removable. */ | 602 | /* Checks if this range of memory is likely to be hot-removable. */ |
diff --git a/mm/mlock.c b/mm/mlock.c index cbae7c5b956..b70919ce4f7 100644 --- a/mm/mlock.c +++ b/mm/mlock.c | |||
@@ -135,12 +135,6 @@ void munlock_vma_page(struct page *page) | |||
135 | } | 135 | } |
136 | } | 136 | } |
137 | 137 | ||
138 | /* Is the vma a continuation of the stack vma above it? */ | ||
139 | static inline int vma_stack_continue(struct vm_area_struct *vma, unsigned long addr) | ||
140 | { | ||
141 | return vma && (vma->vm_end == addr) && (vma->vm_flags & VM_GROWSDOWN); | ||
142 | } | ||
143 | |||
144 | static inline int stack_guard_page(struct vm_area_struct *vma, unsigned long addr) | 138 | static inline int stack_guard_page(struct vm_area_struct *vma, unsigned long addr) |
145 | { | 139 | { |
146 | return (vma->vm_flags & VM_GROWSDOWN) && | 140 | return (vma->vm_flags & VM_GROWSDOWN) && |
@@ -1716,9 +1716,6 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns | |||
1716 | * PA-RISC uses this for its stack; IA64 for its Register Backing Store. | 1716 | * PA-RISC uses this for its stack; IA64 for its Register Backing Store. |
1717 | * vma is the last one with address > vma->vm_end. Have to extend vma. | 1717 | * vma is the last one with address > vma->vm_end. Have to extend vma. |
1718 | */ | 1718 | */ |
1719 | #ifndef CONFIG_IA64 | ||
1720 | static | ||
1721 | #endif | ||
1722 | int expand_upwards(struct vm_area_struct *vma, unsigned long address) | 1719 | int expand_upwards(struct vm_area_struct *vma, unsigned long address) |
1723 | { | 1720 | { |
1724 | int error; | 1721 | int error; |
@@ -2012,6 +2009,7 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, | |||
2012 | removed_exe_file_vma(mm); | 2009 | removed_exe_file_vma(mm); |
2013 | fput(new->vm_file); | 2010 | fput(new->vm_file); |
2014 | } | 2011 | } |
2012 | unlink_anon_vmas(new); | ||
2015 | out_free_mpol: | 2013 | out_free_mpol: |
2016 | mpol_put(pol); | 2014 | mpol_put(pol); |
2017 | out_free_vma: | 2015 | out_free_vma: |
diff --git a/mm/mmzone.c b/mm/mmzone.c index f5b7d176021..e35bfb82c85 100644 --- a/mm/mmzone.c +++ b/mm/mmzone.c | |||
@@ -87,3 +87,24 @@ int memmap_valid_within(unsigned long pfn, | |||
87 | return 1; | 87 | return 1; |
88 | } | 88 | } |
89 | #endif /* CONFIG_ARCH_HAS_HOLES_MEMORYMODEL */ | 89 | #endif /* CONFIG_ARCH_HAS_HOLES_MEMORYMODEL */ |
90 | |||
91 | #ifdef CONFIG_SMP | ||
92 | /* Called when a more accurate view of NR_FREE_PAGES is needed */ | ||
93 | unsigned long zone_nr_free_pages(struct zone *zone) | ||
94 | { | ||
95 | unsigned long nr_free_pages = zone_page_state(zone, NR_FREE_PAGES); | ||
96 | |||
97 | /* | ||
98 | * While kswapd is awake, it is considered the zone is under some | ||
99 | * memory pressure. Under pressure, there is a risk that | ||
100 | * per-cpu-counter-drift will allow the min watermark to be breached | ||
101 | * potentially causing a live-lock. While kswapd is awake and | ||
102 | * free pages are low, get a better estimate for free pages | ||
103 | */ | ||
104 | if (nr_free_pages < zone->percpu_drift_mark && | ||
105 | !waitqueue_active(&zone->zone_pgdat->kswapd_wait)) | ||
106 | return zone_page_state_snapshot(zone, NR_FREE_PAGES); | ||
107 | |||
108 | return nr_free_pages; | ||
109 | } | ||
110 | #endif /* CONFIG_SMP */ | ||
diff --git a/mm/oom_kill.c b/mm/oom_kill.c index fc81cb22869..4029583a102 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c | |||
@@ -121,8 +121,8 @@ struct task_struct *find_lock_task_mm(struct task_struct *p) | |||
121 | } | 121 | } |
122 | 122 | ||
123 | /* return true if the task is not adequate as candidate victim task. */ | 123 | /* return true if the task is not adequate as candidate victim task. */ |
124 | static bool oom_unkillable_task(struct task_struct *p, struct mem_cgroup *mem, | 124 | static bool oom_unkillable_task(struct task_struct *p, |
125 | const nodemask_t *nodemask) | 125 | const struct mem_cgroup *mem, const nodemask_t *nodemask) |
126 | { | 126 | { |
127 | if (is_global_init(p)) | 127 | if (is_global_init(p)) |
128 | return true; | 128 | return true; |
@@ -208,8 +208,13 @@ unsigned int oom_badness(struct task_struct *p, struct mem_cgroup *mem, | |||
208 | */ | 208 | */ |
209 | points += p->signal->oom_score_adj; | 209 | points += p->signal->oom_score_adj; |
210 | 210 | ||
211 | if (points < 0) | 211 | /* |
212 | return 0; | 212 | * Never return 0 for an eligible task that may be killed since it's |
213 | * possible that no single user task uses more than 0.1% of memory and | ||
214 | * no single admin tasks uses more than 3.0%. | ||
215 | */ | ||
216 | if (points <= 0) | ||
217 | return 1; | ||
213 | return (points < 1000) ? points : 1000; | 218 | return (points < 1000) ? points : 1000; |
214 | } | 219 | } |
215 | 220 | ||
@@ -339,26 +344,24 @@ static struct task_struct *select_bad_process(unsigned int *ppoints, | |||
339 | /** | 344 | /** |
340 | * dump_tasks - dump current memory state of all system tasks | 345 | * dump_tasks - dump current memory state of all system tasks |
341 | * @mem: current's memory controller, if constrained | 346 | * @mem: current's memory controller, if constrained |
347 | * @nodemask: nodemask passed to page allocator for mempolicy ooms | ||
342 | * | 348 | * |
343 | * Dumps the current memory state of all system tasks, excluding kernel threads. | 349 | * Dumps the current memory state of all eligible tasks. Tasks not in the same |
350 | * memcg, not in the same cpuset, or bound to a disjoint set of mempolicy nodes | ||
351 | * are not shown. | ||
344 | * State information includes task's pid, uid, tgid, vm size, rss, cpu, oom_adj | 352 | * State information includes task's pid, uid, tgid, vm size, rss, cpu, oom_adj |
345 | * value, oom_score_adj value, and name. | 353 | * value, oom_score_adj value, and name. |
346 | * | 354 | * |
347 | * If the actual is non-NULL, only tasks that are a member of the mem_cgroup are | ||
348 | * shown. | ||
349 | * | ||
350 | * Call with tasklist_lock read-locked. | 355 | * Call with tasklist_lock read-locked. |
351 | */ | 356 | */ |
352 | static void dump_tasks(const struct mem_cgroup *mem) | 357 | static void dump_tasks(const struct mem_cgroup *mem, const nodemask_t *nodemask) |
353 | { | 358 | { |
354 | struct task_struct *p; | 359 | struct task_struct *p; |
355 | struct task_struct *task; | 360 | struct task_struct *task; |
356 | 361 | ||
357 | pr_info("[ pid ] uid tgid total_vm rss cpu oom_adj oom_score_adj name\n"); | 362 | pr_info("[ pid ] uid tgid total_vm rss cpu oom_adj oom_score_adj name\n"); |
358 | for_each_process(p) { | 363 | for_each_process(p) { |
359 | if (p->flags & PF_KTHREAD) | 364 | if (oom_unkillable_task(p, mem, nodemask)) |
360 | continue; | ||
361 | if (mem && !task_in_mem_cgroup(p, mem)) | ||
362 | continue; | 365 | continue; |
363 | 366 | ||
364 | task = find_lock_task_mm(p); | 367 | task = find_lock_task_mm(p); |
@@ -381,7 +384,7 @@ static void dump_tasks(const struct mem_cgroup *mem) | |||
381 | } | 384 | } |
382 | 385 | ||
383 | static void dump_header(struct task_struct *p, gfp_t gfp_mask, int order, | 386 | static void dump_header(struct task_struct *p, gfp_t gfp_mask, int order, |
384 | struct mem_cgroup *mem) | 387 | struct mem_cgroup *mem, const nodemask_t *nodemask) |
385 | { | 388 | { |
386 | task_lock(current); | 389 | task_lock(current); |
387 | pr_warning("%s invoked oom-killer: gfp_mask=0x%x, order=%d, " | 390 | pr_warning("%s invoked oom-killer: gfp_mask=0x%x, order=%d, " |
@@ -394,7 +397,7 @@ static void dump_header(struct task_struct *p, gfp_t gfp_mask, int order, | |||
394 | mem_cgroup_print_oom_info(mem, p); | 397 | mem_cgroup_print_oom_info(mem, p); |
395 | show_mem(); | 398 | show_mem(); |
396 | if (sysctl_oom_dump_tasks) | 399 | if (sysctl_oom_dump_tasks) |
397 | dump_tasks(mem); | 400 | dump_tasks(mem, nodemask); |
398 | } | 401 | } |
399 | 402 | ||
400 | #define K(x) ((x) << (PAGE_SHIFT-10)) | 403 | #define K(x) ((x) << (PAGE_SHIFT-10)) |
@@ -436,7 +439,7 @@ static int oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order, | |||
436 | unsigned int victim_points = 0; | 439 | unsigned int victim_points = 0; |
437 | 440 | ||
438 | if (printk_ratelimit()) | 441 | if (printk_ratelimit()) |
439 | dump_header(p, gfp_mask, order, mem); | 442 | dump_header(p, gfp_mask, order, mem, nodemask); |
440 | 443 | ||
441 | /* | 444 | /* |
442 | * If the task is already exiting, don't alarm the sysadmin or kill | 445 | * If the task is already exiting, don't alarm the sysadmin or kill |
@@ -482,7 +485,7 @@ static int oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order, | |||
482 | * Determines whether the kernel must panic because of the panic_on_oom sysctl. | 485 | * Determines whether the kernel must panic because of the panic_on_oom sysctl. |
483 | */ | 486 | */ |
484 | static void check_panic_on_oom(enum oom_constraint constraint, gfp_t gfp_mask, | 487 | static void check_panic_on_oom(enum oom_constraint constraint, gfp_t gfp_mask, |
485 | int order) | 488 | int order, const nodemask_t *nodemask) |
486 | { | 489 | { |
487 | if (likely(!sysctl_panic_on_oom)) | 490 | if (likely(!sysctl_panic_on_oom)) |
488 | return; | 491 | return; |
@@ -496,7 +499,7 @@ static void check_panic_on_oom(enum oom_constraint constraint, gfp_t gfp_mask, | |||
496 | return; | 499 | return; |
497 | } | 500 | } |
498 | read_lock(&tasklist_lock); | 501 | read_lock(&tasklist_lock); |
499 | dump_header(NULL, gfp_mask, order, NULL); | 502 | dump_header(NULL, gfp_mask, order, NULL, nodemask); |
500 | read_unlock(&tasklist_lock); | 503 | read_unlock(&tasklist_lock); |
501 | panic("Out of memory: %s panic_on_oom is enabled\n", | 504 | panic("Out of memory: %s panic_on_oom is enabled\n", |
502 | sysctl_panic_on_oom == 2 ? "compulsory" : "system-wide"); | 505 | sysctl_panic_on_oom == 2 ? "compulsory" : "system-wide"); |
@@ -509,7 +512,7 @@ void mem_cgroup_out_of_memory(struct mem_cgroup *mem, gfp_t gfp_mask) | |||
509 | unsigned int points = 0; | 512 | unsigned int points = 0; |
510 | struct task_struct *p; | 513 | struct task_struct *p; |
511 | 514 | ||
512 | check_panic_on_oom(CONSTRAINT_MEMCG, gfp_mask, 0); | 515 | check_panic_on_oom(CONSTRAINT_MEMCG, gfp_mask, 0, NULL); |
513 | limit = mem_cgroup_get_limit(mem) >> PAGE_SHIFT; | 516 | limit = mem_cgroup_get_limit(mem) >> PAGE_SHIFT; |
514 | read_lock(&tasklist_lock); | 517 | read_lock(&tasklist_lock); |
515 | retry: | 518 | retry: |
@@ -641,6 +644,7 @@ static void clear_system_oom(void) | |||
641 | void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, | 644 | void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, |
642 | int order, nodemask_t *nodemask) | 645 | int order, nodemask_t *nodemask) |
643 | { | 646 | { |
647 | const nodemask_t *mpol_mask; | ||
644 | struct task_struct *p; | 648 | struct task_struct *p; |
645 | unsigned long totalpages; | 649 | unsigned long totalpages; |
646 | unsigned long freed = 0; | 650 | unsigned long freed = 0; |
@@ -670,7 +674,8 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, | |||
670 | */ | 674 | */ |
671 | constraint = constrained_alloc(zonelist, gfp_mask, nodemask, | 675 | constraint = constrained_alloc(zonelist, gfp_mask, nodemask, |
672 | &totalpages); | 676 | &totalpages); |
673 | check_panic_on_oom(constraint, gfp_mask, order); | 677 | mpol_mask = (constraint == CONSTRAINT_MEMORY_POLICY) ? nodemask : NULL; |
678 | check_panic_on_oom(constraint, gfp_mask, order, mpol_mask); | ||
674 | 679 | ||
675 | read_lock(&tasklist_lock); | 680 | read_lock(&tasklist_lock); |
676 | if (sysctl_oom_kill_allocating_task && | 681 | if (sysctl_oom_kill_allocating_task && |
@@ -688,15 +693,13 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, | |||
688 | } | 693 | } |
689 | 694 | ||
690 | retry: | 695 | retry: |
691 | p = select_bad_process(&points, totalpages, NULL, | 696 | p = select_bad_process(&points, totalpages, NULL, mpol_mask); |
692 | constraint == CONSTRAINT_MEMORY_POLICY ? nodemask : | ||
693 | NULL); | ||
694 | if (PTR_ERR(p) == -1UL) | 697 | if (PTR_ERR(p) == -1UL) |
695 | goto out; | 698 | goto out; |
696 | 699 | ||
697 | /* Found nothing?!?! Either we hang forever, or we panic. */ | 700 | /* Found nothing?!?! Either we hang forever, or we panic. */ |
698 | if (!p) { | 701 | if (!p) { |
699 | dump_header(NULL, gfp_mask, order, NULL); | 702 | dump_header(NULL, gfp_mask, order, NULL, mpol_mask); |
700 | read_unlock(&tasklist_lock); | 703 | read_unlock(&tasklist_lock); |
701 | panic("Out of memory and no killable processes...\n"); | 704 | panic("Out of memory and no killable processes...\n"); |
702 | } | 705 | } |
diff --git a/mm/page-writeback.c b/mm/page-writeback.c index c09ef5219cb..e3bccac1f02 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c | |||
@@ -985,22 +985,16 @@ continue_unlock: | |||
985 | } | 985 | } |
986 | } | 986 | } |
987 | 987 | ||
988 | if (wbc->nr_to_write > 0) { | 988 | /* |
989 | if (--wbc->nr_to_write == 0 && | 989 | * We stop writing back only if we are not doing |
990 | wbc->sync_mode == WB_SYNC_NONE) { | 990 | * integrity sync. In case of integrity sync we have to |
991 | /* | 991 | * keep going until we have written all the pages |
992 | * We stop writing back only if we are | 992 | * we tagged for writeback prior to entering this loop. |
993 | * not doing integrity sync. In case of | 993 | */ |
994 | * integrity sync we have to keep going | 994 | if (--wbc->nr_to_write <= 0 && |
995 | * because someone may be concurrently | 995 | wbc->sync_mode == WB_SYNC_NONE) { |
996 | * dirtying pages, and we might have | 996 | done = 1; |
997 | * synced a lot of newly appeared dirty | 997 | break; |
998 | * pages, but have not synced all of the | ||
999 | * old dirty pages. | ||
1000 | */ | ||
1001 | done = 1; | ||
1002 | break; | ||
1003 | } | ||
1004 | } | 998 | } |
1005 | } | 999 | } |
1006 | pagevec_release(&pvec); | 1000 | pagevec_release(&pvec); |
@@ -1132,6 +1126,7 @@ void account_page_dirtied(struct page *page, struct address_space *mapping) | |||
1132 | task_io_account_write(PAGE_CACHE_SIZE); | 1126 | task_io_account_write(PAGE_CACHE_SIZE); |
1133 | } | 1127 | } |
1134 | } | 1128 | } |
1129 | EXPORT_SYMBOL(account_page_dirtied); | ||
1135 | 1130 | ||
1136 | /* | 1131 | /* |
1137 | * For address_spaces which do not use buffers. Just tag the page as dirty in | 1132 | * For address_spaces which do not use buffers. Just tag the page as dirty in |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index a9649f4b261..f12ad1836ab 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -588,13 +588,13 @@ static void free_pcppages_bulk(struct zone *zone, int count, | |||
588 | { | 588 | { |
589 | int migratetype = 0; | 589 | int migratetype = 0; |
590 | int batch_free = 0; | 590 | int batch_free = 0; |
591 | int to_free = count; | ||
591 | 592 | ||
592 | spin_lock(&zone->lock); | 593 | spin_lock(&zone->lock); |
593 | zone->all_unreclaimable = 0; | 594 | zone->all_unreclaimable = 0; |
594 | zone->pages_scanned = 0; | 595 | zone->pages_scanned = 0; |
595 | 596 | ||
596 | __mod_zone_page_state(zone, NR_FREE_PAGES, count); | 597 | while (to_free) { |
597 | while (count) { | ||
598 | struct page *page; | 598 | struct page *page; |
599 | struct list_head *list; | 599 | struct list_head *list; |
600 | 600 | ||
@@ -619,8 +619,9 @@ static void free_pcppages_bulk(struct zone *zone, int count, | |||
619 | /* MIGRATE_MOVABLE list may include MIGRATE_RESERVEs */ | 619 | /* MIGRATE_MOVABLE list may include MIGRATE_RESERVEs */ |
620 | __free_one_page(page, zone, 0, page_private(page)); | 620 | __free_one_page(page, zone, 0, page_private(page)); |
621 | trace_mm_page_pcpu_drain(page, 0, page_private(page)); | 621 | trace_mm_page_pcpu_drain(page, 0, page_private(page)); |
622 | } while (--count && --batch_free && !list_empty(list)); | 622 | } while (--to_free && --batch_free && !list_empty(list)); |
623 | } | 623 | } |
624 | __mod_zone_page_state(zone, NR_FREE_PAGES, count); | ||
624 | spin_unlock(&zone->lock); | 625 | spin_unlock(&zone->lock); |
625 | } | 626 | } |
626 | 627 | ||
@@ -631,8 +632,8 @@ static void free_one_page(struct zone *zone, struct page *page, int order, | |||
631 | zone->all_unreclaimable = 0; | 632 | zone->all_unreclaimable = 0; |
632 | zone->pages_scanned = 0; | 633 | zone->pages_scanned = 0; |
633 | 634 | ||
634 | __mod_zone_page_state(zone, NR_FREE_PAGES, 1 << order); | ||
635 | __free_one_page(page, zone, order, migratetype); | 635 | __free_one_page(page, zone, order, migratetype); |
636 | __mod_zone_page_state(zone, NR_FREE_PAGES, 1 << order); | ||
636 | spin_unlock(&zone->lock); | 637 | spin_unlock(&zone->lock); |
637 | } | 638 | } |
638 | 639 | ||
@@ -1461,7 +1462,7 @@ int zone_watermark_ok(struct zone *z, int order, unsigned long mark, | |||
1461 | { | 1462 | { |
1462 | /* free_pages my go negative - that's OK */ | 1463 | /* free_pages my go negative - that's OK */ |
1463 | long min = mark; | 1464 | long min = mark; |
1464 | long free_pages = zone_page_state(z, NR_FREE_PAGES) - (1 << order) + 1; | 1465 | long free_pages = zone_nr_free_pages(z) - (1 << order) + 1; |
1465 | int o; | 1466 | int o; |
1466 | 1467 | ||
1467 | if (alloc_flags & ALLOC_HIGH) | 1468 | if (alloc_flags & ALLOC_HIGH) |
@@ -1846,6 +1847,7 @@ __alloc_pages_direct_reclaim(gfp_t gfp_mask, unsigned int order, | |||
1846 | struct page *page = NULL; | 1847 | struct page *page = NULL; |
1847 | struct reclaim_state reclaim_state; | 1848 | struct reclaim_state reclaim_state; |
1848 | struct task_struct *p = current; | 1849 | struct task_struct *p = current; |
1850 | bool drained = false; | ||
1849 | 1851 | ||
1850 | cond_resched(); | 1852 | cond_resched(); |
1851 | 1853 | ||
@@ -1864,14 +1866,25 @@ __alloc_pages_direct_reclaim(gfp_t gfp_mask, unsigned int order, | |||
1864 | 1866 | ||
1865 | cond_resched(); | 1867 | cond_resched(); |
1866 | 1868 | ||
1867 | if (order != 0) | 1869 | if (unlikely(!(*did_some_progress))) |
1868 | drain_all_pages(); | 1870 | return NULL; |
1869 | 1871 | ||
1870 | if (likely(*did_some_progress)) | 1872 | retry: |
1871 | page = get_page_from_freelist(gfp_mask, nodemask, order, | 1873 | page = get_page_from_freelist(gfp_mask, nodemask, order, |
1872 | zonelist, high_zoneidx, | 1874 | zonelist, high_zoneidx, |
1873 | alloc_flags, preferred_zone, | 1875 | alloc_flags, preferred_zone, |
1874 | migratetype); | 1876 | migratetype); |
1877 | |||
1878 | /* | ||
1879 | * If an allocation failed after direct reclaim, it could be because | ||
1880 | * pages are pinned on the per-cpu lists. Drain them and try again | ||
1881 | */ | ||
1882 | if (!page && !drained) { | ||
1883 | drain_all_pages(); | ||
1884 | drained = true; | ||
1885 | goto retry; | ||
1886 | } | ||
1887 | |||
1875 | return page; | 1888 | return page; |
1876 | } | 1889 | } |
1877 | 1890 | ||
@@ -2423,7 +2436,7 @@ void show_free_areas(void) | |||
2423 | " all_unreclaimable? %s" | 2436 | " all_unreclaimable? %s" |
2424 | "\n", | 2437 | "\n", |
2425 | zone->name, | 2438 | zone->name, |
2426 | K(zone_page_state(zone, NR_FREE_PAGES)), | 2439 | K(zone_nr_free_pages(zone)), |
2427 | K(min_wmark_pages(zone)), | 2440 | K(min_wmark_pages(zone)), |
2428 | K(low_wmark_pages(zone)), | 2441 | K(low_wmark_pages(zone)), |
2429 | K(high_wmark_pages(zone)), | 2442 | K(high_wmark_pages(zone)), |
@@ -5169,9 +5182,9 @@ void *__init alloc_large_system_hash(const char *tablename, | |||
5169 | if (!table) | 5182 | if (!table) |
5170 | panic("Failed to allocate %s hash table\n", tablename); | 5183 | panic("Failed to allocate %s hash table\n", tablename); |
5171 | 5184 | ||
5172 | printk(KERN_INFO "%s hash table entries: %d (order: %d, %lu bytes)\n", | 5185 | printk(KERN_INFO "%s hash table entries: %ld (order: %d, %lu bytes)\n", |
5173 | tablename, | 5186 | tablename, |
5174 | (1U << log2qty), | 5187 | (1UL << log2qty), |
5175 | ilog2(size) - PAGE_SHIFT, | 5188 | ilog2(size) - PAGE_SHIFT, |
5176 | size); | 5189 | size); |
5177 | 5190 | ||
diff --git a/mm/percpu.c b/mm/percpu.c index e61dc2cc587..c76ef3891e0 100644 --- a/mm/percpu.c +++ b/mm/percpu.c | |||
@@ -393,7 +393,9 @@ static int pcpu_extend_area_map(struct pcpu_chunk *chunk, int new_alloc) | |||
393 | goto out_unlock; | 393 | goto out_unlock; |
394 | 394 | ||
395 | old_size = chunk->map_alloc * sizeof(chunk->map[0]); | 395 | old_size = chunk->map_alloc * sizeof(chunk->map[0]); |
396 | memcpy(new, chunk->map, old_size); | 396 | old = chunk->map; |
397 | |||
398 | memcpy(new, old, old_size); | ||
397 | 399 | ||
398 | chunk->map_alloc = new_alloc; | 400 | chunk->map_alloc = new_alloc; |
399 | chunk->map = new; | 401 | chunk->map = new; |
@@ -1162,7 +1164,7 @@ static struct pcpu_alloc_info * __init pcpu_build_alloc_info( | |||
1162 | } | 1164 | } |
1163 | 1165 | ||
1164 | /* | 1166 | /* |
1165 | * Don't accept if wastage is over 25%. The | 1167 | * Don't accept if wastage is over 1/3. The |
1166 | * greater-than comparison ensures upa==1 always | 1168 | * greater-than comparison ensures upa==1 always |
1167 | * passes the following check. | 1169 | * passes the following check. |
1168 | */ | 1170 | */ |
@@ -1399,9 +1401,9 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai, | |||
1399 | 1401 | ||
1400 | if (pcpu_first_unit_cpu == NR_CPUS) | 1402 | if (pcpu_first_unit_cpu == NR_CPUS) |
1401 | pcpu_first_unit_cpu = cpu; | 1403 | pcpu_first_unit_cpu = cpu; |
1404 | pcpu_last_unit_cpu = cpu; | ||
1402 | } | 1405 | } |
1403 | } | 1406 | } |
1404 | pcpu_last_unit_cpu = cpu; | ||
1405 | pcpu_nr_units = unit; | 1407 | pcpu_nr_units = unit; |
1406 | 1408 | ||
1407 | for_each_possible_cpu(cpu) | 1409 | for_each_possible_cpu(cpu) |
diff --git a/mm/percpu_up.c b/mm/percpu_up.c index c4351c7f57d..db884fae572 100644 --- a/mm/percpu_up.c +++ b/mm/percpu_up.c | |||
@@ -14,13 +14,13 @@ void __percpu *__alloc_percpu(size_t size, size_t align) | |||
14 | * percpu sections on SMP for which this path isn't used. | 14 | * percpu sections on SMP for which this path isn't used. |
15 | */ | 15 | */ |
16 | WARN_ON_ONCE(align > SMP_CACHE_BYTES); | 16 | WARN_ON_ONCE(align > SMP_CACHE_BYTES); |
17 | return kzalloc(size, GFP_KERNEL); | 17 | return (void __percpu __force *)kzalloc(size, GFP_KERNEL); |
18 | } | 18 | } |
19 | EXPORT_SYMBOL_GPL(__alloc_percpu); | 19 | EXPORT_SYMBOL_GPL(__alloc_percpu); |
20 | 20 | ||
21 | void free_percpu(void __percpu *p) | 21 | void free_percpu(void __percpu *p) |
22 | { | 22 | { |
23 | kfree(p); | 23 | kfree(this_cpu_ptr(p)); |
24 | } | 24 | } |
25 | EXPORT_SYMBOL_GPL(free_percpu); | 25 | EXPORT_SYMBOL_GPL(free_percpu); |
26 | 26 | ||
@@ -316,7 +316,7 @@ void __init anon_vma_init(void) | |||
316 | */ | 316 | */ |
317 | struct anon_vma *page_lock_anon_vma(struct page *page) | 317 | struct anon_vma *page_lock_anon_vma(struct page *page) |
318 | { | 318 | { |
319 | struct anon_vma *anon_vma; | 319 | struct anon_vma *anon_vma, *root_anon_vma; |
320 | unsigned long anon_mapping; | 320 | unsigned long anon_mapping; |
321 | 321 | ||
322 | rcu_read_lock(); | 322 | rcu_read_lock(); |
@@ -327,8 +327,21 @@ struct anon_vma *page_lock_anon_vma(struct page *page) | |||
327 | goto out; | 327 | goto out; |
328 | 328 | ||
329 | anon_vma = (struct anon_vma *) (anon_mapping - PAGE_MAPPING_ANON); | 329 | anon_vma = (struct anon_vma *) (anon_mapping - PAGE_MAPPING_ANON); |
330 | anon_vma_lock(anon_vma); | 330 | root_anon_vma = ACCESS_ONCE(anon_vma->root); |
331 | return anon_vma; | 331 | spin_lock(&root_anon_vma->lock); |
332 | |||
333 | /* | ||
334 | * If this page is still mapped, then its anon_vma cannot have been | ||
335 | * freed. But if it has been unmapped, we have no security against | ||
336 | * the anon_vma structure being freed and reused (for another anon_vma: | ||
337 | * SLAB_DESTROY_BY_RCU guarantees that - so the spin_lock above cannot | ||
338 | * corrupt): with anon_vma_prepare() or anon_vma_fork() redirecting | ||
339 | * anon_vma->root before page_unlock_anon_vma() is called to unlock. | ||
340 | */ | ||
341 | if (page_mapped(page)) | ||
342 | return anon_vma; | ||
343 | |||
344 | spin_unlock(&root_anon_vma->lock); | ||
332 | out: | 345 | out: |
333 | rcu_read_unlock(); | 346 | rcu_read_unlock(); |
334 | return NULL; | 347 | return NULL; |
@@ -368,7 +381,13 @@ vma_address(struct page *page, struct vm_area_struct *vma) | |||
368 | unsigned long page_address_in_vma(struct page *page, struct vm_area_struct *vma) | 381 | unsigned long page_address_in_vma(struct page *page, struct vm_area_struct *vma) |
369 | { | 382 | { |
370 | if (PageAnon(page)) { | 383 | if (PageAnon(page)) { |
371 | if (vma->anon_vma->root != page_anon_vma(page)->root) | 384 | struct anon_vma *page__anon_vma = page_anon_vma(page); |
385 | /* | ||
386 | * Note: swapoff's unuse_vma() is more efficient with this | ||
387 | * check, and needs it to match anon_vma when KSM is active. | ||
388 | */ | ||
389 | if (!vma->anon_vma || !page__anon_vma || | ||
390 | vma->anon_vma->root != page__anon_vma->root) | ||
372 | return -EFAULT; | 391 | return -EFAULT; |
373 | } else if (page->mapping && !(vma->vm_flags & VM_NONLINEAR)) { | 392 | } else if (page->mapping && !(vma->vm_flags & VM_NONLINEAR)) { |
374 | if (!vma->vm_file || | 393 | if (!vma->vm_file || |
@@ -1551,13 +1570,14 @@ static void __hugepage_set_anon_rmap(struct page *page, | |||
1551 | struct vm_area_struct *vma, unsigned long address, int exclusive) | 1570 | struct vm_area_struct *vma, unsigned long address, int exclusive) |
1552 | { | 1571 | { |
1553 | struct anon_vma *anon_vma = vma->anon_vma; | 1572 | struct anon_vma *anon_vma = vma->anon_vma; |
1573 | |||
1554 | BUG_ON(!anon_vma); | 1574 | BUG_ON(!anon_vma); |
1555 | if (!exclusive) { | 1575 | |
1556 | struct anon_vma_chain *avc; | 1576 | if (PageAnon(page)) |
1557 | avc = list_entry(vma->anon_vma_chain.prev, | 1577 | return; |
1558 | struct anon_vma_chain, same_vma); | 1578 | if (!exclusive) |
1559 | anon_vma = avc->anon_vma; | 1579 | anon_vma = anon_vma->root; |
1560 | } | 1580 | |
1561 | anon_vma = (void *) anon_vma + PAGE_MAPPING_ANON; | 1581 | anon_vma = (void *) anon_vma + PAGE_MAPPING_ANON; |
1562 | page->mapping = (struct address_space *) anon_vma; | 1582 | page->mapping = (struct address_space *) anon_vma; |
1563 | page->index = linear_page_index(vma, address); | 1583 | page->index = linear_page_index(vma, address); |
@@ -1568,6 +1588,8 @@ void hugepage_add_anon_rmap(struct page *page, | |||
1568 | { | 1588 | { |
1569 | struct anon_vma *anon_vma = vma->anon_vma; | 1589 | struct anon_vma *anon_vma = vma->anon_vma; |
1570 | int first; | 1590 | int first; |
1591 | |||
1592 | BUG_ON(!PageLocked(page)); | ||
1571 | BUG_ON(!anon_vma); | 1593 | BUG_ON(!anon_vma); |
1572 | BUG_ON(address < vma->vm_start || address >= vma->vm_end); | 1594 | BUG_ON(address < vma->vm_start || address >= vma->vm_end); |
1573 | first = atomic_inc_and_test(&page->_mapcount); | 1595 | first = atomic_inc_and_test(&page->_mapcount); |
diff --git a/mm/swapfile.c b/mm/swapfile.c index e132e1708ac..9fc7bac7db0 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c | |||
@@ -47,8 +47,6 @@ long nr_swap_pages; | |||
47 | long total_swap_pages; | 47 | long total_swap_pages; |
48 | static int least_priority; | 48 | static int least_priority; |
49 | 49 | ||
50 | static bool swap_for_hibernation; | ||
51 | |||
52 | static const char Bad_file[] = "Bad swap file entry "; | 50 | static const char Bad_file[] = "Bad swap file entry "; |
53 | static const char Unused_file[] = "Unused swap file entry "; | 51 | static const char Unused_file[] = "Unused swap file entry "; |
54 | static const char Bad_offset[] = "Bad swap offset entry "; | 52 | static const char Bad_offset[] = "Bad swap offset entry "; |
@@ -317,10 +315,8 @@ checks: | |||
317 | if (offset > si->highest_bit) | 315 | if (offset > si->highest_bit) |
318 | scan_base = offset = si->lowest_bit; | 316 | scan_base = offset = si->lowest_bit; |
319 | 317 | ||
320 | /* reuse swap entry of cache-only swap if not hibernation. */ | 318 | /* reuse swap entry of cache-only swap if not busy. */ |
321 | if (vm_swap_full() | 319 | if (vm_swap_full() && si->swap_map[offset] == SWAP_HAS_CACHE) { |
322 | && usage == SWAP_HAS_CACHE | ||
323 | && si->swap_map[offset] == SWAP_HAS_CACHE) { | ||
324 | int swap_was_freed; | 320 | int swap_was_freed; |
325 | spin_unlock(&swap_lock); | 321 | spin_unlock(&swap_lock); |
326 | swap_was_freed = __try_to_reclaim_swap(si, offset); | 322 | swap_was_freed = __try_to_reclaim_swap(si, offset); |
@@ -450,8 +446,6 @@ swp_entry_t get_swap_page(void) | |||
450 | spin_lock(&swap_lock); | 446 | spin_lock(&swap_lock); |
451 | if (nr_swap_pages <= 0) | 447 | if (nr_swap_pages <= 0) |
452 | goto noswap; | 448 | goto noswap; |
453 | if (swap_for_hibernation) | ||
454 | goto noswap; | ||
455 | nr_swap_pages--; | 449 | nr_swap_pages--; |
456 | 450 | ||
457 | for (type = swap_list.next; type >= 0 && wrapped < 2; type = next) { | 451 | for (type = swap_list.next; type >= 0 && wrapped < 2; type = next) { |
@@ -484,6 +478,28 @@ noswap: | |||
484 | return (swp_entry_t) {0}; | 478 | return (swp_entry_t) {0}; |
485 | } | 479 | } |
486 | 480 | ||
481 | /* The only caller of this function is now susupend routine */ | ||
482 | swp_entry_t get_swap_page_of_type(int type) | ||
483 | { | ||
484 | struct swap_info_struct *si; | ||
485 | pgoff_t offset; | ||
486 | |||
487 | spin_lock(&swap_lock); | ||
488 | si = swap_info[type]; | ||
489 | if (si && (si->flags & SWP_WRITEOK)) { | ||
490 | nr_swap_pages--; | ||
491 | /* This is called for allocating swap entry, not cache */ | ||
492 | offset = scan_swap_map(si, 1); | ||
493 | if (offset) { | ||
494 | spin_unlock(&swap_lock); | ||
495 | return swp_entry(type, offset); | ||
496 | } | ||
497 | nr_swap_pages++; | ||
498 | } | ||
499 | spin_unlock(&swap_lock); | ||
500 | return (swp_entry_t) {0}; | ||
501 | } | ||
502 | |||
487 | static struct swap_info_struct *swap_info_get(swp_entry_t entry) | 503 | static struct swap_info_struct *swap_info_get(swp_entry_t entry) |
488 | { | 504 | { |
489 | struct swap_info_struct *p; | 505 | struct swap_info_struct *p; |
@@ -667,6 +683,24 @@ int try_to_free_swap(struct page *page) | |||
667 | if (page_swapcount(page)) | 683 | if (page_swapcount(page)) |
668 | return 0; | 684 | return 0; |
669 | 685 | ||
686 | /* | ||
687 | * Once hibernation has begun to create its image of memory, | ||
688 | * there's a danger that one of the calls to try_to_free_swap() | ||
689 | * - most probably a call from __try_to_reclaim_swap() while | ||
690 | * hibernation is allocating its own swap pages for the image, | ||
691 | * but conceivably even a call from memory reclaim - will free | ||
692 | * the swap from a page which has already been recorded in the | ||
693 | * image as a clean swapcache page, and then reuse its swap for | ||
694 | * another page of the image. On waking from hibernation, the | ||
695 | * original page might be freed under memory pressure, then | ||
696 | * later read back in from swap, now with the wrong data. | ||
697 | * | ||
698 | * Hibernation clears bits from gfp_allowed_mask to prevent | ||
699 | * memory reclaim from writing to disk, so check that here. | ||
700 | */ | ||
701 | if (!(gfp_allowed_mask & __GFP_IO)) | ||
702 | return 0; | ||
703 | |||
670 | delete_from_swap_cache(page); | 704 | delete_from_swap_cache(page); |
671 | SetPageDirty(page); | 705 | SetPageDirty(page); |
672 | return 1; | 706 | return 1; |
@@ -743,74 +777,6 @@ int mem_cgroup_count_swap_user(swp_entry_t ent, struct page **pagep) | |||
743 | #endif | 777 | #endif |
744 | 778 | ||
745 | #ifdef CONFIG_HIBERNATION | 779 | #ifdef CONFIG_HIBERNATION |
746 | |||
747 | static pgoff_t hibernation_offset[MAX_SWAPFILES]; | ||
748 | /* | ||
749 | * Once hibernation starts to use swap, we freeze swap_map[]. Otherwise, | ||
750 | * saved swap_map[] image to the disk will be an incomplete because it's | ||
751 | * changing without synchronization with hibernation snap shot. | ||
752 | * At resume, we just make swap_for_hibernation=false. We can forget | ||
753 | * used maps easily. | ||
754 | */ | ||
755 | void hibernation_freeze_swap(void) | ||
756 | { | ||
757 | int i; | ||
758 | |||
759 | spin_lock(&swap_lock); | ||
760 | |||
761 | printk(KERN_INFO "PM: Freeze Swap\n"); | ||
762 | swap_for_hibernation = true; | ||
763 | for (i = 0; i < MAX_SWAPFILES; i++) | ||
764 | hibernation_offset[i] = 1; | ||
765 | spin_unlock(&swap_lock); | ||
766 | } | ||
767 | |||
768 | void hibernation_thaw_swap(void) | ||
769 | { | ||
770 | spin_lock(&swap_lock); | ||
771 | if (swap_for_hibernation) { | ||
772 | printk(KERN_INFO "PM: Thaw Swap\n"); | ||
773 | swap_for_hibernation = false; | ||
774 | } | ||
775 | spin_unlock(&swap_lock); | ||
776 | } | ||
777 | |||
778 | /* | ||
779 | * Because updateing swap_map[] can make not-saved-status-change, | ||
780 | * we use our own easy allocator. | ||
781 | * Please see kernel/power/swap.c, Used swaps are recorded into | ||
782 | * RB-tree. | ||
783 | */ | ||
784 | swp_entry_t get_swap_for_hibernation(int type) | ||
785 | { | ||
786 | pgoff_t off; | ||
787 | swp_entry_t val = {0}; | ||
788 | struct swap_info_struct *si; | ||
789 | |||
790 | spin_lock(&swap_lock); | ||
791 | |||
792 | si = swap_info[type]; | ||
793 | if (!si || !(si->flags & SWP_WRITEOK)) | ||
794 | goto done; | ||
795 | |||
796 | for (off = hibernation_offset[type]; off < si->max; ++off) { | ||
797 | if (!si->swap_map[off]) | ||
798 | break; | ||
799 | } | ||
800 | if (off < si->max) { | ||
801 | val = swp_entry(type, off); | ||
802 | hibernation_offset[type] = off + 1; | ||
803 | } | ||
804 | done: | ||
805 | spin_unlock(&swap_lock); | ||
806 | return val; | ||
807 | } | ||
808 | |||
809 | void swap_free_for_hibernation(swp_entry_t ent) | ||
810 | { | ||
811 | /* Nothing to do */ | ||
812 | } | ||
813 | |||
814 | /* | 780 | /* |
815 | * Find the swap type that corresponds to given device (if any). | 781 | * Find the swap type that corresponds to given device (if any). |
816 | * | 782 | * |
@@ -2081,7 +2047,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) | |||
2081 | p->flags |= SWP_SOLIDSTATE; | 2047 | p->flags |= SWP_SOLIDSTATE; |
2082 | p->cluster_next = 1 + (random32() % p->highest_bit); | 2048 | p->cluster_next = 1 + (random32() % p->highest_bit); |
2083 | } | 2049 | } |
2084 | if (discard_swap(p) == 0) | 2050 | if (discard_swap(p) == 0 && (swap_flags & SWAP_FLAG_DISCARD)) |
2085 | p->flags |= SWP_DISCARDABLE; | 2051 | p->flags |= SWP_DISCARDABLE; |
2086 | } | 2052 | } |
2087 | 2053 | ||
diff --git a/mm/vmscan.c b/mm/vmscan.c index c391c320dba..c5dfabf25f1 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -1804,12 +1804,11 @@ static void shrink_zone(int priority, struct zone *zone, | |||
1804 | * If a zone is deemed to be full of pinned pages then just give it a light | 1804 | * If a zone is deemed to be full of pinned pages then just give it a light |
1805 | * scan then give up on it. | 1805 | * scan then give up on it. |
1806 | */ | 1806 | */ |
1807 | static bool shrink_zones(int priority, struct zonelist *zonelist, | 1807 | static void shrink_zones(int priority, struct zonelist *zonelist, |
1808 | struct scan_control *sc) | 1808 | struct scan_control *sc) |
1809 | { | 1809 | { |
1810 | struct zoneref *z; | 1810 | struct zoneref *z; |
1811 | struct zone *zone; | 1811 | struct zone *zone; |
1812 | bool all_unreclaimable = true; | ||
1813 | 1812 | ||
1814 | for_each_zone_zonelist_nodemask(zone, z, zonelist, | 1813 | for_each_zone_zonelist_nodemask(zone, z, zonelist, |
1815 | gfp_zone(sc->gfp_mask), sc->nodemask) { | 1814 | gfp_zone(sc->gfp_mask), sc->nodemask) { |
@@ -1827,8 +1826,38 @@ static bool shrink_zones(int priority, struct zonelist *zonelist, | |||
1827 | } | 1826 | } |
1828 | 1827 | ||
1829 | shrink_zone(priority, zone, sc); | 1828 | shrink_zone(priority, zone, sc); |
1830 | all_unreclaimable = false; | ||
1831 | } | 1829 | } |
1830 | } | ||
1831 | |||
1832 | static bool zone_reclaimable(struct zone *zone) | ||
1833 | { | ||
1834 | return zone->pages_scanned < zone_reclaimable_pages(zone) * 6; | ||
1835 | } | ||
1836 | |||
1837 | /* | ||
1838 | * As hibernation is going on, kswapd is freezed so that it can't mark | ||
1839 | * the zone into all_unreclaimable. It can't handle OOM during hibernation. | ||
1840 | * So let's check zone's unreclaimable in direct reclaim as well as kswapd. | ||
1841 | */ | ||
1842 | static bool all_unreclaimable(struct zonelist *zonelist, | ||
1843 | struct scan_control *sc) | ||
1844 | { | ||
1845 | struct zoneref *z; | ||
1846 | struct zone *zone; | ||
1847 | bool all_unreclaimable = true; | ||
1848 | |||
1849 | for_each_zone_zonelist_nodemask(zone, z, zonelist, | ||
1850 | gfp_zone(sc->gfp_mask), sc->nodemask) { | ||
1851 | if (!populated_zone(zone)) | ||
1852 | continue; | ||
1853 | if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL)) | ||
1854 | continue; | ||
1855 | if (zone_reclaimable(zone)) { | ||
1856 | all_unreclaimable = false; | ||
1857 | break; | ||
1858 | } | ||
1859 | } | ||
1860 | |||
1832 | return all_unreclaimable; | 1861 | return all_unreclaimable; |
1833 | } | 1862 | } |
1834 | 1863 | ||
@@ -1852,7 +1881,6 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist, | |||
1852 | struct scan_control *sc) | 1881 | struct scan_control *sc) |
1853 | { | 1882 | { |
1854 | int priority; | 1883 | int priority; |
1855 | bool all_unreclaimable; | ||
1856 | unsigned long total_scanned = 0; | 1884 | unsigned long total_scanned = 0; |
1857 | struct reclaim_state *reclaim_state = current->reclaim_state; | 1885 | struct reclaim_state *reclaim_state = current->reclaim_state; |
1858 | struct zoneref *z; | 1886 | struct zoneref *z; |
@@ -1869,7 +1897,7 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist, | |||
1869 | sc->nr_scanned = 0; | 1897 | sc->nr_scanned = 0; |
1870 | if (!priority) | 1898 | if (!priority) |
1871 | disable_swap_token(); | 1899 | disable_swap_token(); |
1872 | all_unreclaimable = shrink_zones(priority, zonelist, sc); | 1900 | shrink_zones(priority, zonelist, sc); |
1873 | /* | 1901 | /* |
1874 | * Don't shrink slabs when reclaiming memory from | 1902 | * Don't shrink slabs when reclaiming memory from |
1875 | * over limit cgroups | 1903 | * over limit cgroups |
@@ -1931,7 +1959,7 @@ out: | |||
1931 | return sc->nr_reclaimed; | 1959 | return sc->nr_reclaimed; |
1932 | 1960 | ||
1933 | /* top priority shrink_zones still had more to do? don't OOM, then */ | 1961 | /* top priority shrink_zones still had more to do? don't OOM, then */ |
1934 | if (scanning_global_lru(sc) && !all_unreclaimable) | 1962 | if (scanning_global_lru(sc) && !all_unreclaimable(zonelist, sc)) |
1935 | return 1; | 1963 | return 1; |
1936 | 1964 | ||
1937 | return 0; | 1965 | return 0; |
@@ -2197,8 +2225,7 @@ loop_again: | |||
2197 | total_scanned += sc.nr_scanned; | 2225 | total_scanned += sc.nr_scanned; |
2198 | if (zone->all_unreclaimable) | 2226 | if (zone->all_unreclaimable) |
2199 | continue; | 2227 | continue; |
2200 | if (nr_slab == 0 && | 2228 | if (nr_slab == 0 && !zone_reclaimable(zone)) |
2201 | zone->pages_scanned >= (zone_reclaimable_pages(zone) * 6)) | ||
2202 | zone->all_unreclaimable = 1; | 2229 | zone->all_unreclaimable = 1; |
2203 | /* | 2230 | /* |
2204 | * If we've done a decent amount of scanning and | 2231 | * If we've done a decent amount of scanning and |
diff --git a/mm/vmstat.c b/mm/vmstat.c index f389168f9a8..355a9e669aa 100644 --- a/mm/vmstat.c +++ b/mm/vmstat.c | |||
@@ -138,11 +138,24 @@ static void refresh_zone_stat_thresholds(void) | |||
138 | int threshold; | 138 | int threshold; |
139 | 139 | ||
140 | for_each_populated_zone(zone) { | 140 | for_each_populated_zone(zone) { |
141 | unsigned long max_drift, tolerate_drift; | ||
142 | |||
141 | threshold = calculate_threshold(zone); | 143 | threshold = calculate_threshold(zone); |
142 | 144 | ||
143 | for_each_online_cpu(cpu) | 145 | for_each_online_cpu(cpu) |
144 | per_cpu_ptr(zone->pageset, cpu)->stat_threshold | 146 | per_cpu_ptr(zone->pageset, cpu)->stat_threshold |
145 | = threshold; | 147 | = threshold; |
148 | |||
149 | /* | ||
150 | * Only set percpu_drift_mark if there is a danger that | ||
151 | * NR_FREE_PAGES reports the low watermark is ok when in fact | ||
152 | * the min watermark could be breached by an allocation | ||
153 | */ | ||
154 | tolerate_drift = low_wmark_pages(zone) - min_wmark_pages(zone); | ||
155 | max_drift = num_online_cpus() * threshold; | ||
156 | if (max_drift > tolerate_drift) | ||
157 | zone->percpu_drift_mark = high_wmark_pages(zone) + | ||
158 | max_drift; | ||
146 | } | 159 | } |
147 | } | 160 | } |
148 | 161 | ||
@@ -813,7 +826,7 @@ static void zoneinfo_show_print(struct seq_file *m, pg_data_t *pgdat, | |||
813 | "\n scanned %lu" | 826 | "\n scanned %lu" |
814 | "\n spanned %lu" | 827 | "\n spanned %lu" |
815 | "\n present %lu", | 828 | "\n present %lu", |
816 | zone_page_state(zone, NR_FREE_PAGES), | 829 | zone_nr_free_pages(zone), |
817 | min_wmark_pages(zone), | 830 | min_wmark_pages(zone), |
818 | low_wmark_pages(zone), | 831 | low_wmark_pages(zone), |
819 | high_wmark_pages(zone), | 832 | high_wmark_pages(zone), |
@@ -998,6 +1011,7 @@ static int __cpuinit vmstat_cpuup_callback(struct notifier_block *nfb, | |||
998 | switch (action) { | 1011 | switch (action) { |
999 | case CPU_ONLINE: | 1012 | case CPU_ONLINE: |
1000 | case CPU_ONLINE_FROZEN: | 1013 | case CPU_ONLINE_FROZEN: |
1014 | refresh_zone_stat_thresholds(); | ||
1001 | start_cpu_timer(cpu); | 1015 | start_cpu_timer(cpu); |
1002 | node_set_state(cpu_to_node(cpu), N_CPU); | 1016 | node_set_state(cpu_to_node(cpu), N_CPU); |
1003 | break; | 1017 | break; |
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index 01ddb0472f8..0eb96f7e44b 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c | |||
@@ -24,8 +24,11 @@ int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, | |||
24 | 24 | ||
25 | if (vlan_dev) | 25 | if (vlan_dev) |
26 | skb->dev = vlan_dev; | 26 | skb->dev = vlan_dev; |
27 | else if (vlan_id) | 27 | else if (vlan_id) { |
28 | goto drop; | 28 | if (!(skb->dev->flags & IFF_PROMISC)) |
29 | goto drop; | ||
30 | skb->pkt_type = PACKET_OTHERHOST; | ||
31 | } | ||
29 | 32 | ||
30 | return (polling ? netif_receive_skb(skb) : netif_rx(skb)); | 33 | return (polling ? netif_receive_skb(skb) : netif_rx(skb)); |
31 | 34 | ||
@@ -102,8 +105,11 @@ vlan_gro_common(struct napi_struct *napi, struct vlan_group *grp, | |||
102 | 105 | ||
103 | if (vlan_dev) | 106 | if (vlan_dev) |
104 | skb->dev = vlan_dev; | 107 | skb->dev = vlan_dev; |
105 | else if (vlan_id) | 108 | else if (vlan_id) { |
106 | goto drop; | 109 | if (!(skb->dev->flags & IFF_PROMISC)) |
110 | goto drop; | ||
111 | skb->pkt_type = PACKET_OTHERHOST; | ||
112 | } | ||
107 | 113 | ||
108 | for (p = napi->gro_list; p; p = p->next) { | 114 | for (p = napi->gro_list; p; p = p->next) { |
109 | NAPI_GRO_CB(p)->same_flow = | 115 | NAPI_GRO_CB(p)->same_flow = |
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 3d59c9bf8fe..3bccdd12a26 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
@@ -510,7 +510,8 @@ static int vlan_dev_open(struct net_device *dev) | |||
510 | if (vlan->flags & VLAN_FLAG_GVRP) | 510 | if (vlan->flags & VLAN_FLAG_GVRP) |
511 | vlan_gvrp_request_join(dev); | 511 | vlan_gvrp_request_join(dev); |
512 | 512 | ||
513 | netif_carrier_on(dev); | 513 | if (netif_carrier_ok(real_dev)) |
514 | netif_carrier_on(dev); | ||
514 | return 0; | 515 | return 0; |
515 | 516 | ||
516 | clear_allmulti: | 517 | clear_allmulti: |
diff --git a/net/9p/client.c b/net/9p/client.c index dc6f2f26d02..9eb72505308 100644 --- a/net/9p/client.c +++ b/net/9p/client.c | |||
@@ -331,8 +331,10 @@ static void p9_tag_cleanup(struct p9_client *c) | |||
331 | } | 331 | } |
332 | } | 332 | } |
333 | 333 | ||
334 | if (c->tagpool) | 334 | if (c->tagpool) { |
335 | p9_idpool_put(0, c->tagpool); /* free reserved tag 0 */ | ||
335 | p9_idpool_destroy(c->tagpool); | 336 | p9_idpool_destroy(c->tagpool); |
337 | } | ||
336 | 338 | ||
337 | /* free requests associated with tags */ | 339 | /* free requests associated with tags */ |
338 | for (row = 0; row < (c->max_tag/P9_ROW_MAXTAG); row++) { | 340 | for (row = 0; row < (c->max_tag/P9_ROW_MAXTAG); row++) { |
@@ -944,6 +946,7 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames, | |||
944 | int16_t nwqids, count; | 946 | int16_t nwqids, count; |
945 | 947 | ||
946 | err = 0; | 948 | err = 0; |
949 | wqids = NULL; | ||
947 | clnt = oldfid->clnt; | 950 | clnt = oldfid->clnt; |
948 | if (clone) { | 951 | if (clone) { |
949 | fid = p9_fid_create(clnt); | 952 | fid = p9_fid_create(clnt); |
@@ -994,9 +997,11 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames, | |||
994 | else | 997 | else |
995 | fid->qid = oldfid->qid; | 998 | fid->qid = oldfid->qid; |
996 | 999 | ||
1000 | kfree(wqids); | ||
997 | return fid; | 1001 | return fid; |
998 | 1002 | ||
999 | clunk_fid: | 1003 | clunk_fid: |
1004 | kfree(wqids); | ||
1000 | p9_client_clunk(fid); | 1005 | p9_client_clunk(fid); |
1001 | fid = NULL; | 1006 | fid = NULL; |
1002 | 1007 | ||
diff --git a/net/9p/trans_rdma.c b/net/9p/trans_rdma.c index 0ea20c30466..17c5ba7551a 100644 --- a/net/9p/trans_rdma.c +++ b/net/9p/trans_rdma.c | |||
@@ -426,8 +426,10 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req) | |||
426 | 426 | ||
427 | /* Allocate an fcall for the reply */ | 427 | /* Allocate an fcall for the reply */ |
428 | rpl_context = kmalloc(sizeof *rpl_context, GFP_KERNEL); | 428 | rpl_context = kmalloc(sizeof *rpl_context, GFP_KERNEL); |
429 | if (!rpl_context) | 429 | if (!rpl_context) { |
430 | err = -ENOMEM; | ||
430 | goto err_close; | 431 | goto err_close; |
432 | } | ||
431 | 433 | ||
432 | /* | 434 | /* |
433 | * If the request has a buffer, steal it, otherwise | 435 | * If the request has a buffer, steal it, otherwise |
@@ -445,8 +447,8 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req) | |||
445 | } | 447 | } |
446 | rpl_context->rc = req->rc; | 448 | rpl_context->rc = req->rc; |
447 | if (!rpl_context->rc) { | 449 | if (!rpl_context->rc) { |
448 | kfree(rpl_context); | 450 | err = -ENOMEM; |
449 | goto err_close; | 451 | goto err_free2; |
450 | } | 452 | } |
451 | 453 | ||
452 | /* | 454 | /* |
@@ -458,11 +460,8 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req) | |||
458 | */ | 460 | */ |
459 | if (atomic_inc_return(&rdma->rq_count) <= rdma->rq_depth) { | 461 | if (atomic_inc_return(&rdma->rq_count) <= rdma->rq_depth) { |
460 | err = post_recv(client, rpl_context); | 462 | err = post_recv(client, rpl_context); |
461 | if (err) { | 463 | if (err) |
462 | kfree(rpl_context->rc); | 464 | goto err_free1; |
463 | kfree(rpl_context); | ||
464 | goto err_close; | ||
465 | } | ||
466 | } else | 465 | } else |
467 | atomic_dec(&rdma->rq_count); | 466 | atomic_dec(&rdma->rq_count); |
468 | 467 | ||
@@ -471,8 +470,10 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req) | |||
471 | 470 | ||
472 | /* Post the request */ | 471 | /* Post the request */ |
473 | c = kmalloc(sizeof *c, GFP_KERNEL); | 472 | c = kmalloc(sizeof *c, GFP_KERNEL); |
474 | if (!c) | 473 | if (!c) { |
475 | goto err_close; | 474 | err = -ENOMEM; |
475 | goto err_free1; | ||
476 | } | ||
476 | c->req = req; | 477 | c->req = req; |
477 | 478 | ||
478 | c->busa = ib_dma_map_single(rdma->cm_id->device, | 479 | c->busa = ib_dma_map_single(rdma->cm_id->device, |
@@ -499,9 +500,15 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req) | |||
499 | return ib_post_send(rdma->qp, &wr, &bad_wr); | 500 | return ib_post_send(rdma->qp, &wr, &bad_wr); |
500 | 501 | ||
501 | error: | 502 | error: |
503 | kfree(c); | ||
504 | kfree(rpl_context->rc); | ||
505 | kfree(rpl_context); | ||
502 | P9_DPRINTK(P9_DEBUG_ERROR, "EIO\n"); | 506 | P9_DPRINTK(P9_DEBUG_ERROR, "EIO\n"); |
503 | return -EIO; | 507 | return -EIO; |
504 | 508 | err_free1: | |
509 | kfree(rpl_context->rc); | ||
510 | err_free2: | ||
511 | kfree(rpl_context); | ||
505 | err_close: | 512 | err_close: |
506 | spin_lock_irqsave(&rdma->req_lock, flags); | 513 | spin_lock_irqsave(&rdma->req_lock, flags); |
507 | if (rdma->state < P9_RDMA_CLOSING) { | 514 | if (rdma->state < P9_RDMA_CLOSING) { |
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index dcfbe99ff81..b88515936e4 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c | |||
@@ -329,7 +329,8 @@ p9_virtio_create(struct p9_client *client, const char *devname, char *args) | |||
329 | 329 | ||
330 | mutex_lock(&virtio_9p_lock); | 330 | mutex_lock(&virtio_9p_lock); |
331 | list_for_each_entry(chan, &virtio_chan_list, chan_list) { | 331 | list_for_each_entry(chan, &virtio_chan_list, chan_list) { |
332 | if (!strncmp(devname, chan->tag, chan->tag_len)) { | 332 | if (!strncmp(devname, chan->tag, chan->tag_len) && |
333 | strlen(devname) == chan->tag_len) { | ||
333 | if (!chan->inuse) { | 334 | if (!chan->inuse) { |
334 | chan->inuse = true; | 335 | chan->inuse = true; |
335 | found = 1; | 336 | found = 1; |
diff --git a/net/Kconfig b/net/Kconfig index e330594d370..e926884c167 100644 --- a/net/Kconfig +++ b/net/Kconfig | |||
@@ -217,7 +217,7 @@ source "net/dns_resolver/Kconfig" | |||
217 | 217 | ||
218 | config RPS | 218 | config RPS |
219 | boolean | 219 | boolean |
220 | depends on SMP && SYSFS | 220 | depends on SMP && SYSFS && USE_GENERIC_SMP_HELPERS |
221 | default y | 221 | default y |
222 | 222 | ||
223 | menu "Network testing" | 223 | menu "Network testing" |
diff --git a/net/atm/br2684.c b/net/atm/br2684.c index 651babdfab3..ad2b232a205 100644 --- a/net/atm/br2684.c +++ b/net/atm/br2684.c | |||
@@ -399,12 +399,6 @@ static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb) | |||
399 | unregister_netdev(net_dev); | 399 | unregister_netdev(net_dev); |
400 | free_netdev(net_dev); | 400 | free_netdev(net_dev); |
401 | } | 401 | } |
402 | read_lock_irq(&devs_lock); | ||
403 | if (list_empty(&br2684_devs)) { | ||
404 | /* last br2684 device */ | ||
405 | unregister_atmdevice_notifier(&atm_dev_notifier); | ||
406 | } | ||
407 | read_unlock_irq(&devs_lock); | ||
408 | return; | 402 | return; |
409 | } | 403 | } |
410 | 404 | ||
@@ -675,7 +669,6 @@ static int br2684_create(void __user *arg) | |||
675 | 669 | ||
676 | if (list_empty(&br2684_devs)) { | 670 | if (list_empty(&br2684_devs)) { |
677 | /* 1st br2684 device */ | 671 | /* 1st br2684 device */ |
678 | register_atmdevice_notifier(&atm_dev_notifier); | ||
679 | brdev->number = 1; | 672 | brdev->number = 1; |
680 | } else | 673 | } else |
681 | brdev->number = BRPRIV(list_entry_brdev(br2684_devs.prev))->number + 1; | 674 | brdev->number = BRPRIV(list_entry_brdev(br2684_devs.prev))->number + 1; |
@@ -815,6 +808,7 @@ static int __init br2684_init(void) | |||
815 | return -ENOMEM; | 808 | return -ENOMEM; |
816 | #endif | 809 | #endif |
817 | register_atm_ioctl(&br2684_ioctl_ops); | 810 | register_atm_ioctl(&br2684_ioctl_ops); |
811 | register_atmdevice_notifier(&atm_dev_notifier); | ||
818 | return 0; | 812 | return 0; |
819 | } | 813 | } |
820 | 814 | ||
@@ -830,9 +824,7 @@ static void __exit br2684_exit(void) | |||
830 | #endif | 824 | #endif |
831 | 825 | ||
832 | 826 | ||
833 | /* if not already empty */ | 827 | unregister_atmdevice_notifier(&atm_dev_notifier); |
834 | if (!list_empty(&br2684_devs)) | ||
835 | unregister_atmdevice_notifier(&atm_dev_notifier); | ||
836 | 828 | ||
837 | while (!list_empty(&br2684_devs)) { | 829 | while (!list_empty(&br2684_devs)) { |
838 | net_dev = list_entry_brdev(br2684_devs.next); | 830 | net_dev = list_entry_brdev(br2684_devs.next); |
diff --git a/net/atm/mpc.c b/net/atm/mpc.c index 622b471e14e..74bcc662c3d 100644 --- a/net/atm/mpc.c +++ b/net/atm/mpc.c | |||
@@ -778,7 +778,7 @@ static void mpc_push(struct atm_vcc *vcc, struct sk_buff *skb) | |||
778 | eg->packets_rcvd++; | 778 | eg->packets_rcvd++; |
779 | mpc->eg_ops->put(eg); | 779 | mpc->eg_ops->put(eg); |
780 | 780 | ||
781 | memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data)); | 781 | memset(ATM_SKB(new_skb), 0, sizeof(struct atm_skb_data)); |
782 | netif_rx(new_skb); | 782 | netif_rx(new_skb); |
783 | } | 783 | } |
784 | 784 | ||
diff --git a/net/ax25/ax25_ds_timer.c b/net/ax25/ax25_ds_timer.c index 2ce79df0068..c7d81436213 100644 --- a/net/ax25/ax25_ds_timer.c +++ b/net/ax25/ax25_ds_timer.c | |||
@@ -112,8 +112,8 @@ void ax25_ds_heartbeat_expiry(ax25_cb *ax25) | |||
112 | if (sk) { | 112 | if (sk) { |
113 | sock_hold(sk); | 113 | sock_hold(sk); |
114 | ax25_destroy_socket(ax25); | 114 | ax25_destroy_socket(ax25); |
115 | sock_put(sk); | ||
116 | bh_unlock_sock(sk); | 115 | bh_unlock_sock(sk); |
116 | sock_put(sk); | ||
117 | } else | 117 | } else |
118 | ax25_destroy_socket(ax25); | 118 | ax25_destroy_socket(ax25); |
119 | return; | 119 | return; |
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index fadf26b4ed7..0b54b7dd840 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -1441,33 +1441,23 @@ static inline void l2cap_do_send(struct sock *sk, struct sk_buff *skb) | |||
1441 | 1441 | ||
1442 | static void l2cap_streaming_send(struct sock *sk) | 1442 | static void l2cap_streaming_send(struct sock *sk) |
1443 | { | 1443 | { |
1444 | struct sk_buff *skb, *tx_skb; | 1444 | struct sk_buff *skb; |
1445 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 1445 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
1446 | u16 control, fcs; | 1446 | u16 control, fcs; |
1447 | 1447 | ||
1448 | while ((skb = sk->sk_send_head)) { | 1448 | while ((skb = skb_dequeue(TX_QUEUE(sk)))) { |
1449 | tx_skb = skb_clone(skb, GFP_ATOMIC); | 1449 | control = get_unaligned_le16(skb->data + L2CAP_HDR_SIZE); |
1450 | |||
1451 | control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); | ||
1452 | control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT; | 1450 | control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT; |
1453 | put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); | 1451 | put_unaligned_le16(control, skb->data + L2CAP_HDR_SIZE); |
1454 | 1452 | ||
1455 | if (pi->fcs == L2CAP_FCS_CRC16) { | 1453 | if (pi->fcs == L2CAP_FCS_CRC16) { |
1456 | fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2); | 1454 | fcs = crc16(0, (u8 *)skb->data, skb->len - 2); |
1457 | put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2); | 1455 | put_unaligned_le16(fcs, skb->data + skb->len - 2); |
1458 | } | 1456 | } |
1459 | 1457 | ||
1460 | l2cap_do_send(sk, tx_skb); | 1458 | l2cap_do_send(sk, skb); |
1461 | 1459 | ||
1462 | pi->next_tx_seq = (pi->next_tx_seq + 1) % 64; | 1460 | pi->next_tx_seq = (pi->next_tx_seq + 1) % 64; |
1463 | |||
1464 | if (skb_queue_is_last(TX_QUEUE(sk), skb)) | ||
1465 | sk->sk_send_head = NULL; | ||
1466 | else | ||
1467 | sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb); | ||
1468 | |||
1469 | skb = skb_dequeue(TX_QUEUE(sk)); | ||
1470 | kfree_skb(skb); | ||
1471 | } | 1461 | } |
1472 | } | 1462 | } |
1473 | 1463 | ||
@@ -1960,6 +1950,11 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us | |||
1960 | 1950 | ||
1961 | switch (optname) { | 1951 | switch (optname) { |
1962 | case L2CAP_OPTIONS: | 1952 | case L2CAP_OPTIONS: |
1953 | if (sk->sk_state == BT_CONNECTED) { | ||
1954 | err = -EINVAL; | ||
1955 | break; | ||
1956 | } | ||
1957 | |||
1963 | opts.imtu = l2cap_pi(sk)->imtu; | 1958 | opts.imtu = l2cap_pi(sk)->imtu; |
1964 | opts.omtu = l2cap_pi(sk)->omtu; | 1959 | opts.omtu = l2cap_pi(sk)->omtu; |
1965 | opts.flush_to = l2cap_pi(sk)->flush_to; | 1960 | opts.flush_to = l2cap_pi(sk)->flush_to; |
@@ -2771,10 +2766,10 @@ static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, | |||
2771 | case L2CAP_CONF_MTU: | 2766 | case L2CAP_CONF_MTU: |
2772 | if (val < L2CAP_DEFAULT_MIN_MTU) { | 2767 | if (val < L2CAP_DEFAULT_MIN_MTU) { |
2773 | *result = L2CAP_CONF_UNACCEPT; | 2768 | *result = L2CAP_CONF_UNACCEPT; |
2774 | pi->omtu = L2CAP_DEFAULT_MIN_MTU; | 2769 | pi->imtu = L2CAP_DEFAULT_MIN_MTU; |
2775 | } else | 2770 | } else |
2776 | pi->omtu = val; | 2771 | pi->imtu = val; |
2777 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu); | 2772 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu); |
2778 | break; | 2773 | break; |
2779 | 2774 | ||
2780 | case L2CAP_CONF_FLUSH_TO: | 2775 | case L2CAP_CONF_FLUSH_TO: |
@@ -3071,6 +3066,17 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
3071 | return 0; | 3066 | return 0; |
3072 | } | 3067 | } |
3073 | 3068 | ||
3069 | static inline void set_default_fcs(struct l2cap_pinfo *pi) | ||
3070 | { | ||
3071 | /* FCS is enabled only in ERTM or streaming mode, if one or both | ||
3072 | * sides request it. | ||
3073 | */ | ||
3074 | if (pi->mode != L2CAP_MODE_ERTM && pi->mode != L2CAP_MODE_STREAMING) | ||
3075 | pi->fcs = L2CAP_FCS_NONE; | ||
3076 | else if (!(pi->conf_state & L2CAP_CONF_NO_FCS_RECV)) | ||
3077 | pi->fcs = L2CAP_FCS_CRC16; | ||
3078 | } | ||
3079 | |||
3074 | static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data) | 3080 | static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data) |
3075 | { | 3081 | { |
3076 | struct l2cap_conf_req *req = (struct l2cap_conf_req *) data; | 3082 | struct l2cap_conf_req *req = (struct l2cap_conf_req *) data; |
@@ -3088,14 +3094,8 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
3088 | if (!sk) | 3094 | if (!sk) |
3089 | return -ENOENT; | 3095 | return -ENOENT; |
3090 | 3096 | ||
3091 | if (sk->sk_state != BT_CONFIG) { | 3097 | if (sk->sk_state == BT_DISCONN) |
3092 | struct l2cap_cmd_rej rej; | ||
3093 | |||
3094 | rej.reason = cpu_to_le16(0x0002); | ||
3095 | l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ, | ||
3096 | sizeof(rej), &rej); | ||
3097 | goto unlock; | 3098 | goto unlock; |
3098 | } | ||
3099 | 3099 | ||
3100 | /* Reject if config buffer is too small. */ | 3100 | /* Reject if config buffer is too small. */ |
3101 | len = cmd_len - sizeof(*req); | 3101 | len = cmd_len - sizeof(*req); |
@@ -3135,9 +3135,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
3135 | goto unlock; | 3135 | goto unlock; |
3136 | 3136 | ||
3137 | if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) { | 3137 | if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) { |
3138 | if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) || | 3138 | set_default_fcs(l2cap_pi(sk)); |
3139 | l2cap_pi(sk)->fcs != L2CAP_FCS_NONE) | ||
3140 | l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16; | ||
3141 | 3139 | ||
3142 | sk->sk_state = BT_CONNECTED; | 3140 | sk->sk_state = BT_CONNECTED; |
3143 | 3141 | ||
@@ -3225,9 +3223,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
3225 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE; | 3223 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE; |
3226 | 3224 | ||
3227 | if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) { | 3225 | if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) { |
3228 | if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) || | 3226 | set_default_fcs(l2cap_pi(sk)); |
3229 | l2cap_pi(sk)->fcs != L2CAP_FCS_NONE) | ||
3230 | l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16; | ||
3231 | 3227 | ||
3232 | sk->sk_state = BT_CONNECTED; | 3228 | sk->sk_state = BT_CONNECTED; |
3233 | l2cap_pi(sk)->next_tx_seq = 0; | 3229 | l2cap_pi(sk)->next_tx_seq = 0; |
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 44a62327595..194b3a04cfd 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
@@ -82,11 +82,14 @@ static void rfcomm_sk_data_ready(struct rfcomm_dlc *d, struct sk_buff *skb) | |||
82 | static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err) | 82 | static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err) |
83 | { | 83 | { |
84 | struct sock *sk = d->owner, *parent; | 84 | struct sock *sk = d->owner, *parent; |
85 | unsigned long flags; | ||
86 | |||
85 | if (!sk) | 87 | if (!sk) |
86 | return; | 88 | return; |
87 | 89 | ||
88 | BT_DBG("dlc %p state %ld err %d", d, d->state, err); | 90 | BT_DBG("dlc %p state %ld err %d", d, d->state, err); |
89 | 91 | ||
92 | local_irq_save(flags); | ||
90 | bh_lock_sock(sk); | 93 | bh_lock_sock(sk); |
91 | 94 | ||
92 | if (err) | 95 | if (err) |
@@ -108,6 +111,7 @@ static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err) | |||
108 | } | 111 | } |
109 | 112 | ||
110 | bh_unlock_sock(sk); | 113 | bh_unlock_sock(sk); |
114 | local_irq_restore(flags); | ||
111 | 115 | ||
112 | if (parent && sock_flag(sk, SOCK_ZAPPED)) { | 116 | if (parent && sock_flag(sk, SOCK_ZAPPED)) { |
113 | /* We have to drop DLC lock here, otherwise | 117 | /* We have to drop DLC lock here, otherwise |
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 2c911c0759c..137f23259a9 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c | |||
@@ -162,8 +162,8 @@ static inline struct nf_bridge_info *nf_bridge_unshare(struct sk_buff *skb) | |||
162 | if (tmp) { | 162 | if (tmp) { |
163 | memcpy(tmp, nf_bridge, sizeof(struct nf_bridge_info)); | 163 | memcpy(tmp, nf_bridge, sizeof(struct nf_bridge_info)); |
164 | atomic_set(&tmp->use, 1); | 164 | atomic_set(&tmp->use, 1); |
165 | nf_bridge_put(nf_bridge); | ||
166 | } | 165 | } |
166 | nf_bridge_put(nf_bridge); | ||
167 | nf_bridge = tmp; | 167 | nf_bridge = tmp; |
168 | } | 168 | } |
169 | return nf_bridge; | 169 | return nf_bridge; |
@@ -761,9 +761,11 @@ static int br_nf_dev_queue_xmit(struct sk_buff *skb) | |||
761 | { | 761 | { |
762 | if (skb->nfct != NULL && skb->protocol == htons(ETH_P_IP) && | 762 | if (skb->nfct != NULL && skb->protocol == htons(ETH_P_IP) && |
763 | skb->len + nf_bridge_mtu_reduction(skb) > skb->dev->mtu && | 763 | skb->len + nf_bridge_mtu_reduction(skb) > skb->dev->mtu && |
764 | !skb_is_gso(skb)) | 764 | !skb_is_gso(skb)) { |
765 | /* BUG: Should really parse the IP options here. */ | ||
766 | memset(IPCB(skb), 0, sizeof(struct inet_skb_parm)); | ||
765 | return ip_fragment(skb, br_dev_queue_push_xmit); | 767 | return ip_fragment(skb, br_dev_queue_push_xmit); |
766 | else | 768 | } else |
767 | return br_dev_queue_push_xmit(skb); | 769 | return br_dev_queue_push_xmit(skb); |
768 | } | 770 | } |
769 | #else | 771 | #else |
diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c index 8ce90478611..4bf28f25f36 100644 --- a/net/caif/caif_socket.c +++ b/net/caif/caif_socket.c | |||
@@ -827,6 +827,7 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr, | |||
827 | long timeo; | 827 | long timeo; |
828 | int err; | 828 | int err; |
829 | int ifindex, headroom, tailroom; | 829 | int ifindex, headroom, tailroom; |
830 | unsigned int mtu; | ||
830 | struct net_device *dev; | 831 | struct net_device *dev; |
831 | 832 | ||
832 | lock_sock(sk); | 833 | lock_sock(sk); |
@@ -896,15 +897,23 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr, | |||
896 | cf_sk->sk.sk_state = CAIF_DISCONNECTED; | 897 | cf_sk->sk.sk_state = CAIF_DISCONNECTED; |
897 | goto out; | 898 | goto out; |
898 | } | 899 | } |
899 | dev = dev_get_by_index(sock_net(sk), ifindex); | 900 | |
901 | err = -ENODEV; | ||
902 | rcu_read_lock(); | ||
903 | dev = dev_get_by_index_rcu(sock_net(sk), ifindex); | ||
904 | if (!dev) { | ||
905 | rcu_read_unlock(); | ||
906 | goto out; | ||
907 | } | ||
900 | cf_sk->headroom = LL_RESERVED_SPACE_EXTRA(dev, headroom); | 908 | cf_sk->headroom = LL_RESERVED_SPACE_EXTRA(dev, headroom); |
909 | mtu = dev->mtu; | ||
910 | rcu_read_unlock(); | ||
911 | |||
901 | cf_sk->tailroom = tailroom; | 912 | cf_sk->tailroom = tailroom; |
902 | cf_sk->maxframe = dev->mtu - (headroom + tailroom); | 913 | cf_sk->maxframe = mtu - (headroom + tailroom); |
903 | dev_put(dev); | ||
904 | if (cf_sk->maxframe < 1) { | 914 | if (cf_sk->maxframe < 1) { |
905 | pr_warning("CAIF: %s(): CAIF Interface MTU too small (%d)\n", | 915 | pr_warning("CAIF: %s(): CAIF Interface MTU too small (%u)\n", |
906 | __func__, dev->mtu); | 916 | __func__, mtu); |
907 | err = -ENODEV; | ||
908 | goto out; | 917 | goto out; |
909 | } | 918 | } |
910 | 919 | ||
diff --git a/net/caif/cfrfml.c b/net/caif/cfrfml.c index eb1602022ac..9a699242d10 100644 --- a/net/caif/cfrfml.c +++ b/net/caif/cfrfml.c | |||
@@ -7,7 +7,7 @@ | |||
7 | #include <linux/stddef.h> | 7 | #include <linux/stddef.h> |
8 | #include <linux/spinlock.h> | 8 | #include <linux/spinlock.h> |
9 | #include <linux/slab.h> | 9 | #include <linux/slab.h> |
10 | #include <linux/unaligned/le_byteshift.h> | 10 | #include <asm/unaligned.h> |
11 | #include <net/caif/caif_layer.h> | 11 | #include <net/caif/caif_layer.h> |
12 | #include <net/caif/cfsrvl.h> | 12 | #include <net/caif/cfsrvl.h> |
13 | #include <net/caif/cfpkt.h> | 13 | #include <net/caif/cfpkt.h> |
diff --git a/net/core/dev.c b/net/core/dev.c index 3721fbb9a83..660dd41aaaa 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2058,16 +2058,16 @@ static struct netdev_queue *dev_pick_tx(struct net_device *dev, | |||
2058 | struct sk_buff *skb) | 2058 | struct sk_buff *skb) |
2059 | { | 2059 | { |
2060 | int queue_index; | 2060 | int queue_index; |
2061 | struct sock *sk = skb->sk; | 2061 | const struct net_device_ops *ops = dev->netdev_ops; |
2062 | 2062 | ||
2063 | queue_index = sk_tx_queue_get(sk); | 2063 | if (ops->ndo_select_queue) { |
2064 | if (queue_index < 0) { | 2064 | queue_index = ops->ndo_select_queue(dev, skb); |
2065 | const struct net_device_ops *ops = dev->netdev_ops; | 2065 | queue_index = dev_cap_txqueue(dev, queue_index); |
2066 | } else { | ||
2067 | struct sock *sk = skb->sk; | ||
2068 | queue_index = sk_tx_queue_get(sk); | ||
2069 | if (queue_index < 0) { | ||
2066 | 2070 | ||
2067 | if (ops->ndo_select_queue) { | ||
2068 | queue_index = ops->ndo_select_queue(dev, skb); | ||
2069 | queue_index = dev_cap_txqueue(dev, queue_index); | ||
2070 | } else { | ||
2071 | queue_index = 0; | 2071 | queue_index = 0; |
2072 | if (dev->real_num_tx_queues > 1) | 2072 | if (dev->real_num_tx_queues > 1) |
2073 | queue_index = skb_tx_hash(dev, skb); | 2073 | queue_index = skb_tx_hash(dev, skb); |
@@ -4845,7 +4845,7 @@ static void rollback_registered_many(struct list_head *head) | |||
4845 | dev = list_first_entry(head, struct net_device, unreg_list); | 4845 | dev = list_first_entry(head, struct net_device, unreg_list); |
4846 | call_netdevice_notifiers(NETDEV_UNREGISTER_BATCH, dev); | 4846 | call_netdevice_notifiers(NETDEV_UNREGISTER_BATCH, dev); |
4847 | 4847 | ||
4848 | synchronize_net(); | 4848 | rcu_barrier(); |
4849 | 4849 | ||
4850 | list_for_each_entry(dev, head, unreg_list) | 4850 | list_for_each_entry(dev, head, unreg_list) |
4851 | dev_put(dev); | 4851 | dev_put(dev); |
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 7a85367b3c2..8451ab48109 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c | |||
@@ -348,7 +348,7 @@ static noinline_for_stack int ethtool_get_rxnfc(struct net_device *dev, | |||
348 | if (info.cmd == ETHTOOL_GRXCLSRLALL) { | 348 | if (info.cmd == ETHTOOL_GRXCLSRLALL) { |
349 | if (info.rule_cnt > 0) { | 349 | if (info.rule_cnt > 0) { |
350 | if (info.rule_cnt <= KMALLOC_MAX_SIZE / sizeof(u32)) | 350 | if (info.rule_cnt <= KMALLOC_MAX_SIZE / sizeof(u32)) |
351 | rule_buf = kmalloc(info.rule_cnt * sizeof(u32), | 351 | rule_buf = kzalloc(info.rule_cnt * sizeof(u32), |
352 | GFP_USER); | 352 | GFP_USER); |
353 | if (!rule_buf) | 353 | if (!rule_buf) |
354 | return -ENOMEM; | 354 | return -ENOMEM; |
@@ -397,7 +397,7 @@ static noinline_for_stack int ethtool_get_rxfh_indir(struct net_device *dev, | |||
397 | (KMALLOC_MAX_SIZE - sizeof(*indir)) / sizeof(*indir->ring_index)) | 397 | (KMALLOC_MAX_SIZE - sizeof(*indir)) / sizeof(*indir->ring_index)) |
398 | return -ENOMEM; | 398 | return -ENOMEM; |
399 | full_size = sizeof(*indir) + sizeof(*indir->ring_index) * table_size; | 399 | full_size = sizeof(*indir) + sizeof(*indir->ring_index) * table_size; |
400 | indir = kmalloc(full_size, GFP_USER); | 400 | indir = kzalloc(full_size, GFP_USER); |
401 | if (!indir) | 401 | if (!indir) |
402 | return -ENOMEM; | 402 | return -ENOMEM; |
403 | 403 | ||
@@ -538,7 +538,7 @@ static int ethtool_get_rx_ntuple(struct net_device *dev, void __user *useraddr) | |||
538 | 538 | ||
539 | gstrings.len = ret; | 539 | gstrings.len = ret; |
540 | 540 | ||
541 | data = kmalloc(gstrings.len * ETH_GSTRING_LEN, GFP_USER); | 541 | data = kzalloc(gstrings.len * ETH_GSTRING_LEN, GFP_USER); |
542 | if (!data) | 542 | if (!data) |
543 | return -ENOMEM; | 543 | return -ENOMEM; |
544 | 544 | ||
@@ -775,7 +775,7 @@ static int ethtool_get_regs(struct net_device *dev, char __user *useraddr) | |||
775 | if (regs.len > reglen) | 775 | if (regs.len > reglen) |
776 | regs.len = reglen; | 776 | regs.len = reglen; |
777 | 777 | ||
778 | regbuf = kmalloc(reglen, GFP_USER); | 778 | regbuf = kzalloc(reglen, GFP_USER); |
779 | if (!regbuf) | 779 | if (!regbuf) |
780 | return -ENOMEM; | 780 | return -ENOMEM; |
781 | 781 | ||
diff --git a/net/core/gen_estimator.c b/net/core/gen_estimator.c index 9fbe7f7429b..6743146e4d6 100644 --- a/net/core/gen_estimator.c +++ b/net/core/gen_estimator.c | |||
@@ -232,7 +232,7 @@ int gen_new_estimator(struct gnet_stats_basic_packed *bstats, | |||
232 | est->last_packets = bstats->packets; | 232 | est->last_packets = bstats->packets; |
233 | est->avpps = rate_est->pps<<10; | 233 | est->avpps = rate_est->pps<<10; |
234 | 234 | ||
235 | spin_lock(&est_tree_lock); | 235 | spin_lock_bh(&est_tree_lock); |
236 | if (!elist[idx].timer.function) { | 236 | if (!elist[idx].timer.function) { |
237 | INIT_LIST_HEAD(&elist[idx].list); | 237 | INIT_LIST_HEAD(&elist[idx].list); |
238 | setup_timer(&elist[idx].timer, est_timer, idx); | 238 | setup_timer(&elist[idx].timer, est_timer, idx); |
@@ -243,7 +243,7 @@ int gen_new_estimator(struct gnet_stats_basic_packed *bstats, | |||
243 | 243 | ||
244 | list_add_rcu(&est->list, &elist[idx].list); | 244 | list_add_rcu(&est->list, &elist[idx].list); |
245 | gen_add_node(est); | 245 | gen_add_node(est); |
246 | spin_unlock(&est_tree_lock); | 246 | spin_unlock_bh(&est_tree_lock); |
247 | 247 | ||
248 | return 0; | 248 | return 0; |
249 | } | 249 | } |
@@ -270,7 +270,7 @@ void gen_kill_estimator(struct gnet_stats_basic_packed *bstats, | |||
270 | { | 270 | { |
271 | struct gen_estimator *e; | 271 | struct gen_estimator *e; |
272 | 272 | ||
273 | spin_lock(&est_tree_lock); | 273 | spin_lock_bh(&est_tree_lock); |
274 | while ((e = gen_find_node(bstats, rate_est))) { | 274 | while ((e = gen_find_node(bstats, rate_est))) { |
275 | rb_erase(&e->node, &est_root); | 275 | rb_erase(&e->node, &est_root); |
276 | 276 | ||
@@ -281,7 +281,7 @@ void gen_kill_estimator(struct gnet_stats_basic_packed *bstats, | |||
281 | list_del_rcu(&e->list); | 281 | list_del_rcu(&e->list); |
282 | call_rcu(&e->e_rcu, __gen_kill_estimator); | 282 | call_rcu(&e->e_rcu, __gen_kill_estimator); |
283 | } | 283 | } |
284 | spin_unlock(&est_tree_lock); | 284 | spin_unlock_bh(&est_tree_lock); |
285 | } | 285 | } |
286 | EXPORT_SYMBOL(gen_kill_estimator); | 286 | EXPORT_SYMBOL(gen_kill_estimator); |
287 | 287 | ||
@@ -320,9 +320,9 @@ bool gen_estimator_active(const struct gnet_stats_basic_packed *bstats, | |||
320 | 320 | ||
321 | ASSERT_RTNL(); | 321 | ASSERT_RTNL(); |
322 | 322 | ||
323 | spin_lock(&est_tree_lock); | 323 | spin_lock_bh(&est_tree_lock); |
324 | res = gen_find_node(bstats, rate_est) != NULL; | 324 | res = gen_find_node(bstats, rate_est) != NULL; |
325 | spin_unlock(&est_tree_lock); | 325 | spin_unlock_bh(&est_tree_lock); |
326 | 326 | ||
327 | return res; | 327 | return res; |
328 | } | 328 | } |
diff --git a/net/core/iovec.c b/net/core/iovec.c index 1cd98df412d..e6b133b77cc 100644 --- a/net/core/iovec.c +++ b/net/core/iovec.c | |||
@@ -35,9 +35,10 @@ | |||
35 | * in any case. | 35 | * in any case. |
36 | */ | 36 | */ |
37 | 37 | ||
38 | int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode) | 38 | long verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode) |
39 | { | 39 | { |
40 | int size, err, ct; | 40 | int size, ct; |
41 | long err; | ||
41 | 42 | ||
42 | if (m->msg_namelen) { | 43 | if (m->msg_namelen) { |
43 | if (mode == VERIFY_READ) { | 44 | if (mode == VERIFY_READ) { |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 3a2513f0d0c..c83b421341c 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -2573,6 +2573,10 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features) | |||
2573 | __copy_skb_header(nskb, skb); | 2573 | __copy_skb_header(nskb, skb); |
2574 | nskb->mac_len = skb->mac_len; | 2574 | nskb->mac_len = skb->mac_len; |
2575 | 2575 | ||
2576 | /* nskb and skb might have different headroom */ | ||
2577 | if (nskb->ip_summed == CHECKSUM_PARTIAL) | ||
2578 | nskb->csum_start += skb_headroom(nskb) - headroom; | ||
2579 | |||
2576 | skb_reset_mac_header(nskb); | 2580 | skb_reset_mac_header(nskb); |
2577 | skb_set_network_header(nskb, skb->mac_len); | 2581 | skb_set_network_header(nskb, skb->mac_len); |
2578 | nskb->transport_header = (nskb->network_header + | 2582 | nskb->transport_header = (nskb->network_header + |
@@ -2703,7 +2707,7 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb) | |||
2703 | return -E2BIG; | 2707 | return -E2BIG; |
2704 | 2708 | ||
2705 | headroom = skb_headroom(p); | 2709 | headroom = skb_headroom(p); |
2706 | nskb = netdev_alloc_skb(p->dev, headroom + skb_gro_offset(p)); | 2710 | nskb = alloc_skb(headroom + skb_gro_offset(p), GFP_ATOMIC); |
2707 | if (unlikely(!nskb)) | 2711 | if (unlikely(!nskb)) |
2708 | return -ENOMEM; | 2712 | return -ENOMEM; |
2709 | 2713 | ||
diff --git a/net/core/sock.c b/net/core/sock.c index b05b9b6ddb8..ef30e9d286e 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -1351,9 +1351,9 @@ int sock_i_uid(struct sock *sk) | |||
1351 | { | 1351 | { |
1352 | int uid; | 1352 | int uid; |
1353 | 1353 | ||
1354 | read_lock(&sk->sk_callback_lock); | 1354 | read_lock_bh(&sk->sk_callback_lock); |
1355 | uid = sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_uid : 0; | 1355 | uid = sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_uid : 0; |
1356 | read_unlock(&sk->sk_callback_lock); | 1356 | read_unlock_bh(&sk->sk_callback_lock); |
1357 | return uid; | 1357 | return uid; |
1358 | } | 1358 | } |
1359 | EXPORT_SYMBOL(sock_i_uid); | 1359 | EXPORT_SYMBOL(sock_i_uid); |
@@ -1362,9 +1362,9 @@ unsigned long sock_i_ino(struct sock *sk) | |||
1362 | { | 1362 | { |
1363 | unsigned long ino; | 1363 | unsigned long ino; |
1364 | 1364 | ||
1365 | read_lock(&sk->sk_callback_lock); | 1365 | read_lock_bh(&sk->sk_callback_lock); |
1366 | ino = sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_ino : 0; | 1366 | ino = sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_ino : 0; |
1367 | read_unlock(&sk->sk_callback_lock); | 1367 | read_unlock_bh(&sk->sk_callback_lock); |
1368 | return ino; | 1368 | return ino; |
1369 | } | 1369 | } |
1370 | EXPORT_SYMBOL(sock_i_ino); | 1370 | EXPORT_SYMBOL(sock_i_ino); |
diff --git a/net/core/stream.c b/net/core/stream.c index d959e0f4152..f5df85dcd20 100644 --- a/net/core/stream.c +++ b/net/core/stream.c | |||
@@ -141,10 +141,10 @@ int sk_stream_wait_memory(struct sock *sk, long *timeo_p) | |||
141 | 141 | ||
142 | set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); | 142 | set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); |
143 | sk->sk_write_pending++; | 143 | sk->sk_write_pending++; |
144 | sk_wait_event(sk, ¤t_timeo, !sk->sk_err && | 144 | sk_wait_event(sk, ¤t_timeo, sk->sk_err || |
145 | !(sk->sk_shutdown & SEND_SHUTDOWN) && | 145 | (sk->sk_shutdown & SEND_SHUTDOWN) || |
146 | sk_stream_memory_free(sk) && | 146 | (sk_stream_memory_free(sk) && |
147 | vm_wait); | 147 | !vm_wait)); |
148 | sk->sk_write_pending--; | 148 | sk->sk_write_pending--; |
149 | 149 | ||
150 | if (vm_wait) { | 150 | if (vm_wait) { |
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index 7c3a7d19124..7cd7760144f 100644 --- a/net/ipv4/Kconfig +++ b/net/ipv4/Kconfig | |||
@@ -46,7 +46,7 @@ config IP_ADVANCED_ROUTER | |||
46 | rp_filter on use: | 46 | rp_filter on use: |
47 | 47 | ||
48 | echo 1 > /proc/sys/net/ipv4/conf/<device>/rp_filter | 48 | echo 1 > /proc/sys/net/ipv4/conf/<device>/rp_filter |
49 | and | 49 | or |
50 | echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter | 50 | echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter |
51 | 51 | ||
52 | Note that some distributions enable it in startup scripts. | 52 | Note that some distributions enable it in startup scripts. |
@@ -217,6 +217,7 @@ config NET_IPIP | |||
217 | 217 | ||
218 | config NET_IPGRE | 218 | config NET_IPGRE |
219 | tristate "IP: GRE tunnels over IP" | 219 | tristate "IP: GRE tunnels over IP" |
220 | depends on IPV6 || IPV6=n | ||
220 | help | 221 | help |
221 | Tunneling means encapsulating data of one protocol type within | 222 | Tunneling means encapsulating data of one protocol type within |
222 | another protocol and sending it over a channel that understands the | 223 | another protocol and sending it over a channel that understands the |
@@ -412,7 +413,7 @@ config INET_XFRM_MODE_BEET | |||
412 | If unsure, say Y. | 413 | If unsure, say Y. |
413 | 414 | ||
414 | config INET_LRO | 415 | config INET_LRO |
415 | bool "Large Receive Offload (ipv4/tcp)" | 416 | tristate "Large Receive Offload (ipv4/tcp)" |
416 | default y | 417 | default y |
417 | ---help--- | 418 | ---help--- |
418 | Support for Large Receive Offload (ipv4/tcp). | 419 | Support for Large Receive Offload (ipv4/tcp). |
diff --git a/net/ipv4/datagram.c b/net/ipv4/datagram.c index f0550941df7..721a8a37b45 100644 --- a/net/ipv4/datagram.c +++ b/net/ipv4/datagram.c | |||
@@ -62,8 +62,11 @@ int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
62 | } | 62 | } |
63 | if (!inet->inet_saddr) | 63 | if (!inet->inet_saddr) |
64 | inet->inet_saddr = rt->rt_src; /* Update source address */ | 64 | inet->inet_saddr = rt->rt_src; /* Update source address */ |
65 | if (!inet->inet_rcv_saddr) | 65 | if (!inet->inet_rcv_saddr) { |
66 | inet->inet_rcv_saddr = rt->rt_src; | 66 | inet->inet_rcv_saddr = rt->rt_src; |
67 | if (sk->sk_prot->rehash) | ||
68 | sk->sk_prot->rehash(sk); | ||
69 | } | ||
67 | inet->inet_daddr = rt->rt_dst; | 70 | inet->inet_daddr = rt->rt_dst; |
68 | inet->inet_dport = usin->sin_port; | 71 | inet->inet_dport = usin->sin_port; |
69 | sk->sk_state = TCP_ESTABLISHED; | 72 | sk->sk_state = TCP_ESTABLISHED; |
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index a4396891835..7d02a9f999f 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
@@ -246,6 +246,7 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, | |||
246 | 246 | ||
247 | struct fib_result res; | 247 | struct fib_result res; |
248 | int no_addr, rpf, accept_local; | 248 | int no_addr, rpf, accept_local; |
249 | bool dev_match; | ||
249 | int ret; | 250 | int ret; |
250 | struct net *net; | 251 | struct net *net; |
251 | 252 | ||
@@ -273,12 +274,22 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, | |||
273 | } | 274 | } |
274 | *spec_dst = FIB_RES_PREFSRC(res); | 275 | *spec_dst = FIB_RES_PREFSRC(res); |
275 | fib_combine_itag(itag, &res); | 276 | fib_combine_itag(itag, &res); |
277 | dev_match = false; | ||
278 | |||
276 | #ifdef CONFIG_IP_ROUTE_MULTIPATH | 279 | #ifdef CONFIG_IP_ROUTE_MULTIPATH |
277 | if (FIB_RES_DEV(res) == dev || res.fi->fib_nhs > 1) | 280 | for (ret = 0; ret < res.fi->fib_nhs; ret++) { |
281 | struct fib_nh *nh = &res.fi->fib_nh[ret]; | ||
282 | |||
283 | if (nh->nh_dev == dev) { | ||
284 | dev_match = true; | ||
285 | break; | ||
286 | } | ||
287 | } | ||
278 | #else | 288 | #else |
279 | if (FIB_RES_DEV(res) == dev) | 289 | if (FIB_RES_DEV(res) == dev) |
290 | dev_match = true; | ||
280 | #endif | 291 | #endif |
281 | { | 292 | if (dev_match) { |
282 | ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST; | 293 | ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST; |
283 | fib_res_put(&res); | 294 | fib_res_put(&res); |
284 | return ret; | 295 | return ret; |
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 79d057a939b..4a8e370862b 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -186,7 +186,9 @@ static inline struct tnode *node_parent_rcu(struct node *node) | |||
186 | { | 186 | { |
187 | struct tnode *ret = node_parent(node); | 187 | struct tnode *ret = node_parent(node); |
188 | 188 | ||
189 | return rcu_dereference(ret); | 189 | return rcu_dereference_check(ret, |
190 | rcu_read_lock_held() || | ||
191 | lockdep_rtnl_is_held()); | ||
190 | } | 192 | } |
191 | 193 | ||
192 | /* Same as rcu_assign_pointer | 194 | /* Same as rcu_assign_pointer |
@@ -1753,7 +1755,9 @@ static struct leaf *leaf_walk_rcu(struct tnode *p, struct node *c) | |||
1753 | 1755 | ||
1754 | static struct leaf *trie_firstleaf(struct trie *t) | 1756 | static struct leaf *trie_firstleaf(struct trie *t) |
1755 | { | 1757 | { |
1756 | struct tnode *n = (struct tnode *) rcu_dereference(t->trie); | 1758 | struct tnode *n = (struct tnode *) rcu_dereference_check(t->trie, |
1759 | rcu_read_lock_held() || | ||
1760 | lockdep_rtnl_is_held()); | ||
1757 | 1761 | ||
1758 | if (!n) | 1762 | if (!n) |
1759 | return NULL; | 1763 | return NULL; |
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index a1ad0e7180d..2a4bb76f213 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
@@ -856,6 +856,18 @@ static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb, | |||
856 | igmpv3_clear_delrec(in_dev); | 856 | igmpv3_clear_delrec(in_dev); |
857 | } else if (len < 12) { | 857 | } else if (len < 12) { |
858 | return; /* ignore bogus packet; freed by caller */ | 858 | return; /* ignore bogus packet; freed by caller */ |
859 | } else if (IGMP_V1_SEEN(in_dev)) { | ||
860 | /* This is a v3 query with v1 queriers present */ | ||
861 | max_delay = IGMP_Query_Response_Interval; | ||
862 | group = 0; | ||
863 | } else if (IGMP_V2_SEEN(in_dev)) { | ||
864 | /* this is a v3 query with v2 queriers present; | ||
865 | * Interpretation of the max_delay code is problematic here. | ||
866 | * A real v2 host would use ih_code directly, while v3 has a | ||
867 | * different encoding. We use the v3 encoding as more likely | ||
868 | * to be intended in a v3 query. | ||
869 | */ | ||
870 | max_delay = IGMPV3_MRC(ih3->code)*(HZ/IGMP_TIMER_SCALE); | ||
859 | } else { /* v3 */ | 871 | } else { /* v3 */ |
860 | if (!pskb_may_pull(skb, sizeof(struct igmpv3_query))) | 872 | if (!pskb_may_pull(skb, sizeof(struct igmpv3_query))) |
861 | return; | 873 | return; |
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 945b20a5ad5..35c93e8b6a4 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
@@ -45,7 +45,7 @@ | |||
45 | #include <net/netns/generic.h> | 45 | #include <net/netns/generic.h> |
46 | #include <net/rtnetlink.h> | 46 | #include <net/rtnetlink.h> |
47 | 47 | ||
48 | #ifdef CONFIG_IPV6 | 48 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
49 | #include <net/ipv6.h> | 49 | #include <net/ipv6.h> |
50 | #include <net/ip6_fib.h> | 50 | #include <net/ip6_fib.h> |
51 | #include <net/ip6_route.h> | 51 | #include <net/ip6_route.h> |
@@ -699,7 +699,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev | |||
699 | if ((dst = rt->rt_gateway) == 0) | 699 | if ((dst = rt->rt_gateway) == 0) |
700 | goto tx_error_icmp; | 700 | goto tx_error_icmp; |
701 | } | 701 | } |
702 | #ifdef CONFIG_IPV6 | 702 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
703 | else if (skb->protocol == htons(ETH_P_IPV6)) { | 703 | else if (skb->protocol == htons(ETH_P_IPV6)) { |
704 | struct in6_addr *addr6; | 704 | struct in6_addr *addr6; |
705 | int addr_type; | 705 | int addr_type; |
@@ -774,7 +774,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev | |||
774 | goto tx_error; | 774 | goto tx_error; |
775 | } | 775 | } |
776 | } | 776 | } |
777 | #ifdef CONFIG_IPV6 | 777 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
778 | else if (skb->protocol == htons(ETH_P_IPV6)) { | 778 | else if (skb->protocol == htons(ETH_P_IPV6)) { |
779 | struct rt6_info *rt6 = (struct rt6_info *)skb_dst(skb); | 779 | struct rt6_info *rt6 = (struct rt6_info *)skb_dst(skb); |
780 | 780 | ||
@@ -850,7 +850,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev | |||
850 | if ((iph->ttl = tiph->ttl) == 0) { | 850 | if ((iph->ttl = tiph->ttl) == 0) { |
851 | if (skb->protocol == htons(ETH_P_IP)) | 851 | if (skb->protocol == htons(ETH_P_IP)) |
852 | iph->ttl = old_iph->ttl; | 852 | iph->ttl = old_iph->ttl; |
853 | #ifdef CONFIG_IPV6 | 853 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
854 | else if (skb->protocol == htons(ETH_P_IPV6)) | 854 | else if (skb->protocol == htons(ETH_P_IPV6)) |
855 | iph->ttl = ((struct ipv6hdr *)old_iph)->hop_limit; | 855 | iph->ttl = ((struct ipv6hdr *)old_iph)->hop_limit; |
856 | #endif | 856 | #endif |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 04b69896df5..7649d775007 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -488,9 +488,8 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
488 | * we can switch to copy when see the first bad fragment. | 488 | * we can switch to copy when see the first bad fragment. |
489 | */ | 489 | */ |
490 | if (skb_has_frags(skb)) { | 490 | if (skb_has_frags(skb)) { |
491 | struct sk_buff *frag; | 491 | struct sk_buff *frag, *frag2; |
492 | int first_len = skb_pagelen(skb); | 492 | int first_len = skb_pagelen(skb); |
493 | int truesizes = 0; | ||
494 | 493 | ||
495 | if (first_len - hlen > mtu || | 494 | if (first_len - hlen > mtu || |
496 | ((first_len - hlen) & 7) || | 495 | ((first_len - hlen) & 7) || |
@@ -503,18 +502,18 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
503 | if (frag->len > mtu || | 502 | if (frag->len > mtu || |
504 | ((frag->len & 7) && frag->next) || | 503 | ((frag->len & 7) && frag->next) || |
505 | skb_headroom(frag) < hlen) | 504 | skb_headroom(frag) < hlen) |
506 | goto slow_path; | 505 | goto slow_path_clean; |
507 | 506 | ||
508 | /* Partially cloned skb? */ | 507 | /* Partially cloned skb? */ |
509 | if (skb_shared(frag)) | 508 | if (skb_shared(frag)) |
510 | goto slow_path; | 509 | goto slow_path_clean; |
511 | 510 | ||
512 | BUG_ON(frag->sk); | 511 | BUG_ON(frag->sk); |
513 | if (skb->sk) { | 512 | if (skb->sk) { |
514 | frag->sk = skb->sk; | 513 | frag->sk = skb->sk; |
515 | frag->destructor = sock_wfree; | 514 | frag->destructor = sock_wfree; |
516 | } | 515 | } |
517 | truesizes += frag->truesize; | 516 | skb->truesize -= frag->truesize; |
518 | } | 517 | } |
519 | 518 | ||
520 | /* Everything is OK. Generate! */ | 519 | /* Everything is OK. Generate! */ |
@@ -524,7 +523,6 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
524 | frag = skb_shinfo(skb)->frag_list; | 523 | frag = skb_shinfo(skb)->frag_list; |
525 | skb_frag_list_init(skb); | 524 | skb_frag_list_init(skb); |
526 | skb->data_len = first_len - skb_headlen(skb); | 525 | skb->data_len = first_len - skb_headlen(skb); |
527 | skb->truesize -= truesizes; | ||
528 | skb->len = first_len; | 526 | skb->len = first_len; |
529 | iph->tot_len = htons(first_len); | 527 | iph->tot_len = htons(first_len); |
530 | iph->frag_off = htons(IP_MF); | 528 | iph->frag_off = htons(IP_MF); |
@@ -576,6 +574,15 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
576 | } | 574 | } |
577 | IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGFAILS); | 575 | IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGFAILS); |
578 | return err; | 576 | return err; |
577 | |||
578 | slow_path_clean: | ||
579 | skb_walk_frags(skb, frag2) { | ||
580 | if (frag2 == frag) | ||
581 | break; | ||
582 | frag2->sk = NULL; | ||
583 | frag2->destructor = NULL; | ||
584 | skb->truesize += frag2->truesize; | ||
585 | } | ||
579 | } | 586 | } |
580 | 587 | ||
581 | slow_path: | 588 | slow_path: |
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 6c40a8c46e7..64b70ad162e 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c | |||
@@ -1129,6 +1129,9 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname, | |||
1129 | case IP_HDRINCL: | 1129 | case IP_HDRINCL: |
1130 | val = inet->hdrincl; | 1130 | val = inet->hdrincl; |
1131 | break; | 1131 | break; |
1132 | case IP_NODEFRAG: | ||
1133 | val = inet->nodefrag; | ||
1134 | break; | ||
1132 | case IP_MTU_DISCOVER: | 1135 | case IP_MTU_DISCOVER: |
1133 | val = inet->pmtudisc; | 1136 | val = inet->pmtudisc; |
1134 | break; | 1137 | break; |
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 51d6c316797..e8f4f9a57f1 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
@@ -1420,6 +1420,9 @@ static int translate_compat_table(const char *name, | |||
1420 | if (ret != 0) | 1420 | if (ret != 0) |
1421 | break; | 1421 | break; |
1422 | ++i; | 1422 | ++i; |
1423 | if (strcmp(arpt_get_target(iter1)->u.user.name, | ||
1424 | XT_ERROR_TARGET) == 0) | ||
1425 | ++newinfo->stacksize; | ||
1423 | } | 1426 | } |
1424 | if (ret) { | 1427 | if (ret) { |
1425 | /* | 1428 | /* |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 97b64b22c41..d163f2e3b2e 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -1751,6 +1751,9 @@ translate_compat_table(struct net *net, | |||
1751 | if (ret != 0) | 1751 | if (ret != 0) |
1752 | break; | 1752 | break; |
1753 | ++i; | 1753 | ++i; |
1754 | if (strcmp(ipt_get_target(iter1)->u.user.name, | ||
1755 | XT_ERROR_TARGET) == 0) | ||
1756 | ++newinfo->stacksize; | ||
1754 | } | 1757 | } |
1755 | if (ret) { | 1758 | if (ret) { |
1756 | /* | 1759 | /* |
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c index b254dafaf42..43eec80c0e7 100644 --- a/net/ipv4/netfilter/ipt_REJECT.c +++ b/net/ipv4/netfilter/ipt_REJECT.c | |||
@@ -112,6 +112,7 @@ static void send_reset(struct sk_buff *oldskb, int hook) | |||
112 | /* ip_route_me_harder expects skb->dst to be set */ | 112 | /* ip_route_me_harder expects skb->dst to be set */ |
113 | skb_dst_set_noref(nskb, skb_dst(oldskb)); | 113 | skb_dst_set_noref(nskb, skb_dst(oldskb)); |
114 | 114 | ||
115 | nskb->protocol = htons(ETH_P_IP); | ||
115 | if (ip_route_me_harder(nskb, addr_type)) | 116 | if (ip_route_me_harder(nskb, addr_type)) |
116 | goto free_nskb; | 117 | goto free_nskb; |
117 | 118 | ||
diff --git a/net/ipv4/netfilter/nf_defrag_ipv4.c b/net/ipv4/netfilter/nf_defrag_ipv4.c index eab8de32f20..f3a9b42b16c 100644 --- a/net/ipv4/netfilter/nf_defrag_ipv4.c +++ b/net/ipv4/netfilter/nf_defrag_ipv4.c | |||
@@ -66,9 +66,11 @@ static unsigned int ipv4_conntrack_defrag(unsigned int hooknum, | |||
66 | const struct net_device *out, | 66 | const struct net_device *out, |
67 | int (*okfn)(struct sk_buff *)) | 67 | int (*okfn)(struct sk_buff *)) |
68 | { | 68 | { |
69 | struct sock *sk = skb->sk; | ||
69 | struct inet_sock *inet = inet_sk(skb->sk); | 70 | struct inet_sock *inet = inet_sk(skb->sk); |
70 | 71 | ||
71 | if (inet && inet->nodefrag) | 72 | if (sk && (sk->sk_family == PF_INET) && |
73 | inet->nodefrag) | ||
72 | return NF_ACCEPT; | 74 | return NF_ACCEPT; |
73 | 75 | ||
74 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) | 76 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) |
diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic.c b/net/ipv4/netfilter/nf_nat_snmp_basic.c index 1679e2c0963..ee5f419d0a5 100644 --- a/net/ipv4/netfilter/nf_nat_snmp_basic.c +++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c | |||
@@ -893,13 +893,15 @@ static void fast_csum(__sum16 *csum, | |||
893 | unsigned char s[4]; | 893 | unsigned char s[4]; |
894 | 894 | ||
895 | if (offset & 1) { | 895 | if (offset & 1) { |
896 | s[0] = s[2] = 0; | 896 | s[0] = ~0; |
897 | s[1] = ~*optr; | 897 | s[1] = ~*optr; |
898 | s[2] = 0; | ||
898 | s[3] = *nptr; | 899 | s[3] = *nptr; |
899 | } else { | 900 | } else { |
900 | s[1] = s[3] = 0; | ||
901 | s[0] = ~*optr; | 901 | s[0] = ~*optr; |
902 | s[1] = ~0; | ||
902 | s[2] = *nptr; | 903 | s[2] = *nptr; |
904 | s[3] = 0; | ||
903 | } | 905 | } |
904 | 906 | ||
905 | *csum = csum_fold(csum_partial(s, 4, ~csum_unfold(*csum))); | 907 | *csum = csum_fold(csum_partial(s, 4, ~csum_unfold(*csum))); |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 3f56b6e6c6a..ac6559cb54f 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -1231,7 +1231,7 @@ restart: | |||
1231 | } | 1231 | } |
1232 | 1232 | ||
1233 | if (net_ratelimit()) | 1233 | if (net_ratelimit()) |
1234 | printk(KERN_WARNING "Neighbour table overflow.\n"); | 1234 | printk(KERN_WARNING "ipv4: Neighbour table overflow.\n"); |
1235 | rt_drop(rt); | 1235 | rt_drop(rt); |
1236 | return -ENOBUFS; | 1236 | return -ENOBUFS; |
1237 | } | 1237 | } |
@@ -2738,6 +2738,11 @@ slow_output: | |||
2738 | } | 2738 | } |
2739 | EXPORT_SYMBOL_GPL(__ip_route_output_key); | 2739 | EXPORT_SYMBOL_GPL(__ip_route_output_key); |
2740 | 2740 | ||
2741 | static struct dst_entry *ipv4_blackhole_dst_check(struct dst_entry *dst, u32 cookie) | ||
2742 | { | ||
2743 | return NULL; | ||
2744 | } | ||
2745 | |||
2741 | static void ipv4_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) | 2746 | static void ipv4_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) |
2742 | { | 2747 | { |
2743 | } | 2748 | } |
@@ -2746,7 +2751,7 @@ static struct dst_ops ipv4_dst_blackhole_ops = { | |||
2746 | .family = AF_INET, | 2751 | .family = AF_INET, |
2747 | .protocol = cpu_to_be16(ETH_P_IP), | 2752 | .protocol = cpu_to_be16(ETH_P_IP), |
2748 | .destroy = ipv4_dst_destroy, | 2753 | .destroy = ipv4_dst_destroy, |
2749 | .check = ipv4_dst_check, | 2754 | .check = ipv4_blackhole_dst_check, |
2750 | .update_pmtu = ipv4_rt_blackhole_update_pmtu, | 2755 | .update_pmtu = ipv4_rt_blackhole_update_pmtu, |
2751 | .entries = ATOMIC_INIT(0), | 2756 | .entries = ATOMIC_INIT(0), |
2752 | }; | 2757 | }; |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 176e11aaea7..f115ea68a4e 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -386,8 +386,6 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
386 | */ | 386 | */ |
387 | 387 | ||
388 | mask = 0; | 388 | mask = 0; |
389 | if (sk->sk_err) | ||
390 | mask = POLLERR; | ||
391 | 389 | ||
392 | /* | 390 | /* |
393 | * POLLHUP is certainly not done right. But poll() doesn't | 391 | * POLLHUP is certainly not done right. But poll() doesn't |
@@ -451,11 +449,17 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
451 | if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk)) | 449 | if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk)) |
452 | mask |= POLLOUT | POLLWRNORM; | 450 | mask |= POLLOUT | POLLWRNORM; |
453 | } | 451 | } |
454 | } | 452 | } else |
453 | mask |= POLLOUT | POLLWRNORM; | ||
455 | 454 | ||
456 | if (tp->urg_data & TCP_URG_VALID) | 455 | if (tp->urg_data & TCP_URG_VALID) |
457 | mask |= POLLPRI; | 456 | mask |= POLLPRI; |
458 | } | 457 | } |
458 | /* This barrier is coupled with smp_wmb() in tcp_reset() */ | ||
459 | smp_rmb(); | ||
460 | if (sk->sk_err) | ||
461 | mask |= POLLERR; | ||
462 | |||
459 | return mask; | 463 | return mask; |
460 | } | 464 | } |
461 | EXPORT_SYMBOL(tcp_poll); | 465 | EXPORT_SYMBOL(tcp_poll); |
@@ -939,7 +943,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
939 | sg = sk->sk_route_caps & NETIF_F_SG; | 943 | sg = sk->sk_route_caps & NETIF_F_SG; |
940 | 944 | ||
941 | while (--iovlen >= 0) { | 945 | while (--iovlen >= 0) { |
942 | int seglen = iov->iov_len; | 946 | size_t seglen = iov->iov_len; |
943 | unsigned char __user *from = iov->iov_base; | 947 | unsigned char __user *from = iov->iov_base; |
944 | 948 | ||
945 | iov++; | 949 | iov++; |
@@ -2011,11 +2015,8 @@ adjudge_to_death: | |||
2011 | } | 2015 | } |
2012 | } | 2016 | } |
2013 | if (sk->sk_state != TCP_CLOSE) { | 2017 | if (sk->sk_state != TCP_CLOSE) { |
2014 | int orphan_count = percpu_counter_read_positive( | ||
2015 | sk->sk_prot->orphan_count); | ||
2016 | |||
2017 | sk_mem_reclaim(sk); | 2018 | sk_mem_reclaim(sk); |
2018 | if (tcp_too_many_orphans(sk, orphan_count)) { | 2019 | if (tcp_too_many_orphans(sk, 0)) { |
2019 | if (net_ratelimit()) | 2020 | if (net_ratelimit()) |
2020 | printk(KERN_INFO "TCP: too many of orphaned " | 2021 | printk(KERN_INFO "TCP: too many of orphaned " |
2021 | "sockets\n"); | 2022 | "sockets\n"); |
@@ -3212,7 +3213,7 @@ void __init tcp_init(void) | |||
3212 | { | 3213 | { |
3213 | struct sk_buff *skb = NULL; | 3214 | struct sk_buff *skb = NULL; |
3214 | unsigned long nr_pages, limit; | 3215 | unsigned long nr_pages, limit; |
3215 | int order, i, max_share; | 3216 | int i, max_share, cnt; |
3216 | unsigned long jiffy = jiffies; | 3217 | unsigned long jiffy = jiffies; |
3217 | 3218 | ||
3218 | BUILD_BUG_ON(sizeof(struct tcp_skb_cb) > sizeof(skb->cb)); | 3219 | BUILD_BUG_ON(sizeof(struct tcp_skb_cb) > sizeof(skb->cb)); |
@@ -3261,22 +3262,12 @@ void __init tcp_init(void) | |||
3261 | INIT_HLIST_HEAD(&tcp_hashinfo.bhash[i].chain); | 3262 | INIT_HLIST_HEAD(&tcp_hashinfo.bhash[i].chain); |
3262 | } | 3263 | } |
3263 | 3264 | ||
3264 | /* Try to be a bit smarter and adjust defaults depending | 3265 | |
3265 | * on available memory. | 3266 | cnt = tcp_hashinfo.ehash_mask + 1; |
3266 | */ | 3267 | |
3267 | for (order = 0; ((1 << order) << PAGE_SHIFT) < | 3268 | tcp_death_row.sysctl_max_tw_buckets = cnt / 2; |
3268 | (tcp_hashinfo.bhash_size * sizeof(struct inet_bind_hashbucket)); | 3269 | sysctl_tcp_max_orphans = cnt / 2; |
3269 | order++) | 3270 | sysctl_max_syn_backlog = max(128, cnt / 256); |
3270 | ; | ||
3271 | if (order >= 4) { | ||
3272 | tcp_death_row.sysctl_max_tw_buckets = 180000; | ||
3273 | sysctl_tcp_max_orphans = 4096 << (order - 4); | ||
3274 | sysctl_max_syn_backlog = 1024; | ||
3275 | } else if (order < 3) { | ||
3276 | tcp_death_row.sysctl_max_tw_buckets >>= (3 - order); | ||
3277 | sysctl_tcp_max_orphans >>= (3 - order); | ||
3278 | sysctl_max_syn_backlog = 128; | ||
3279 | } | ||
3280 | 3271 | ||
3281 | /* Set the pressure threshold to be a fraction of global memory that | 3272 | /* Set the pressure threshold to be a fraction of global memory that |
3282 | * is up to 1/2 at 256 MB, decreasing toward zero with the amount of | 3273 | * is up to 1/2 at 256 MB, decreasing toward zero with the amount of |
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c index 0ec9bd0ae94..850c737e08e 100644 --- a/net/ipv4/tcp_cong.c +++ b/net/ipv4/tcp_cong.c | |||
@@ -196,10 +196,10 @@ void tcp_get_allowed_congestion_control(char *buf, size_t maxlen) | |||
196 | int tcp_set_allowed_congestion_control(char *val) | 196 | int tcp_set_allowed_congestion_control(char *val) |
197 | { | 197 | { |
198 | struct tcp_congestion_ops *ca; | 198 | struct tcp_congestion_ops *ca; |
199 | char *clone, *name; | 199 | char *saved_clone, *clone, *name; |
200 | int ret = 0; | 200 | int ret = 0; |
201 | 201 | ||
202 | clone = kstrdup(val, GFP_USER); | 202 | saved_clone = clone = kstrdup(val, GFP_USER); |
203 | if (!clone) | 203 | if (!clone) |
204 | return -ENOMEM; | 204 | return -ENOMEM; |
205 | 205 | ||
@@ -226,6 +226,7 @@ int tcp_set_allowed_congestion_control(char *val) | |||
226 | } | 226 | } |
227 | out: | 227 | out: |
228 | spin_unlock(&tcp_cong_list_lock); | 228 | spin_unlock(&tcp_cong_list_lock); |
229 | kfree(saved_clone); | ||
229 | 230 | ||
230 | return ret; | 231 | return ret; |
231 | } | 232 | } |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index e663b78a2ef..b55f60f6fcb 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -2545,7 +2545,8 @@ static void tcp_mark_head_lost(struct sock *sk, int packets) | |||
2545 | cnt += tcp_skb_pcount(skb); | 2545 | cnt += tcp_skb_pcount(skb); |
2546 | 2546 | ||
2547 | if (cnt > packets) { | 2547 | if (cnt > packets) { |
2548 | if (tcp_is_sack(tp) || (oldcnt >= packets)) | 2548 | if ((tcp_is_sack(tp) && !tcp_is_fack(tp)) || |
2549 | (oldcnt >= packets)) | ||
2549 | break; | 2550 | break; |
2550 | 2551 | ||
2551 | mss = skb_shinfo(skb)->gso_size; | 2552 | mss = skb_shinfo(skb)->gso_size; |
@@ -4048,6 +4049,8 @@ static void tcp_reset(struct sock *sk) | |||
4048 | default: | 4049 | default: |
4049 | sk->sk_err = ECONNRESET; | 4050 | sk->sk_err = ECONNRESET; |
4050 | } | 4051 | } |
4052 | /* This barrier is coupled with smp_rmb() in tcp_poll() */ | ||
4053 | smp_wmb(); | ||
4051 | 4054 | ||
4052 | if (!sock_flag(sk, SOCK_DEAD)) | 4055 | if (!sock_flag(sk, SOCK_DEAD)) |
4053 | sk->sk_error_report(sk); | 4056 | sk->sk_error_report(sk); |
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 808bb920c9f..74c54b30600 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c | |||
@@ -66,18 +66,18 @@ static void tcp_write_err(struct sock *sk) | |||
66 | static int tcp_out_of_resources(struct sock *sk, int do_reset) | 66 | static int tcp_out_of_resources(struct sock *sk, int do_reset) |
67 | { | 67 | { |
68 | struct tcp_sock *tp = tcp_sk(sk); | 68 | struct tcp_sock *tp = tcp_sk(sk); |
69 | int orphans = percpu_counter_read_positive(&tcp_orphan_count); | 69 | int shift = 0; |
70 | 70 | ||
71 | /* If peer does not open window for long time, or did not transmit | 71 | /* If peer does not open window for long time, or did not transmit |
72 | * anything for long time, penalize it. */ | 72 | * anything for long time, penalize it. */ |
73 | if ((s32)(tcp_time_stamp - tp->lsndtime) > 2*TCP_RTO_MAX || !do_reset) | 73 | if ((s32)(tcp_time_stamp - tp->lsndtime) > 2*TCP_RTO_MAX || !do_reset) |
74 | orphans <<= 1; | 74 | shift++; |
75 | 75 | ||
76 | /* If some dubious ICMP arrived, penalize even more. */ | 76 | /* If some dubious ICMP arrived, penalize even more. */ |
77 | if (sk->sk_err_soft) | 77 | if (sk->sk_err_soft) |
78 | orphans <<= 1; | 78 | shift++; |
79 | 79 | ||
80 | if (tcp_too_many_orphans(sk, orphans)) { | 80 | if (tcp_too_many_orphans(sk, shift)) { |
81 | if (net_ratelimit()) | 81 | if (net_ratelimit()) |
82 | printk(KERN_INFO "Out of socket memory\n"); | 82 | printk(KERN_INFO "Out of socket memory\n"); |
83 | 83 | ||
@@ -135,13 +135,16 @@ static void tcp_mtu_probing(struct inet_connection_sock *icsk, struct sock *sk) | |||
135 | 135 | ||
136 | /* This function calculates a "timeout" which is equivalent to the timeout of a | 136 | /* This function calculates a "timeout" which is equivalent to the timeout of a |
137 | * TCP connection after "boundary" unsuccessful, exponentially backed-off | 137 | * TCP connection after "boundary" unsuccessful, exponentially backed-off |
138 | * retransmissions with an initial RTO of TCP_RTO_MIN. | 138 | * retransmissions with an initial RTO of TCP_RTO_MIN or TCP_TIMEOUT_INIT if |
139 | * syn_set flag is set. | ||
139 | */ | 140 | */ |
140 | static bool retransmits_timed_out(struct sock *sk, | 141 | static bool retransmits_timed_out(struct sock *sk, |
141 | unsigned int boundary) | 142 | unsigned int boundary, |
143 | bool syn_set) | ||
142 | { | 144 | { |
143 | unsigned int timeout, linear_backoff_thresh; | 145 | unsigned int timeout, linear_backoff_thresh; |
144 | unsigned int start_ts; | 146 | unsigned int start_ts; |
147 | unsigned int rto_base = syn_set ? TCP_TIMEOUT_INIT : TCP_RTO_MIN; | ||
145 | 148 | ||
146 | if (!inet_csk(sk)->icsk_retransmits) | 149 | if (!inet_csk(sk)->icsk_retransmits) |
147 | return false; | 150 | return false; |
@@ -151,12 +154,12 @@ static bool retransmits_timed_out(struct sock *sk, | |||
151 | else | 154 | else |
152 | start_ts = tcp_sk(sk)->retrans_stamp; | 155 | start_ts = tcp_sk(sk)->retrans_stamp; |
153 | 156 | ||
154 | linear_backoff_thresh = ilog2(TCP_RTO_MAX/TCP_RTO_MIN); | 157 | linear_backoff_thresh = ilog2(TCP_RTO_MAX/rto_base); |
155 | 158 | ||
156 | if (boundary <= linear_backoff_thresh) | 159 | if (boundary <= linear_backoff_thresh) |
157 | timeout = ((2 << boundary) - 1) * TCP_RTO_MIN; | 160 | timeout = ((2 << boundary) - 1) * rto_base; |
158 | else | 161 | else |
159 | timeout = ((2 << linear_backoff_thresh) - 1) * TCP_RTO_MIN + | 162 | timeout = ((2 << linear_backoff_thresh) - 1) * rto_base + |
160 | (boundary - linear_backoff_thresh) * TCP_RTO_MAX; | 163 | (boundary - linear_backoff_thresh) * TCP_RTO_MAX; |
161 | 164 | ||
162 | return (tcp_time_stamp - start_ts) >= timeout; | 165 | return (tcp_time_stamp - start_ts) >= timeout; |
@@ -167,14 +170,15 @@ static int tcp_write_timeout(struct sock *sk) | |||
167 | { | 170 | { |
168 | struct inet_connection_sock *icsk = inet_csk(sk); | 171 | struct inet_connection_sock *icsk = inet_csk(sk); |
169 | int retry_until; | 172 | int retry_until; |
170 | bool do_reset; | 173 | bool do_reset, syn_set = 0; |
171 | 174 | ||
172 | if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) { | 175 | if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) { |
173 | if (icsk->icsk_retransmits) | 176 | if (icsk->icsk_retransmits) |
174 | dst_negative_advice(sk); | 177 | dst_negative_advice(sk); |
175 | retry_until = icsk->icsk_syn_retries ? : sysctl_tcp_syn_retries; | 178 | retry_until = icsk->icsk_syn_retries ? : sysctl_tcp_syn_retries; |
179 | syn_set = 1; | ||
176 | } else { | 180 | } else { |
177 | if (retransmits_timed_out(sk, sysctl_tcp_retries1)) { | 181 | if (retransmits_timed_out(sk, sysctl_tcp_retries1, 0)) { |
178 | /* Black hole detection */ | 182 | /* Black hole detection */ |
179 | tcp_mtu_probing(icsk, sk); | 183 | tcp_mtu_probing(icsk, sk); |
180 | 184 | ||
@@ -187,14 +191,14 @@ static int tcp_write_timeout(struct sock *sk) | |||
187 | 191 | ||
188 | retry_until = tcp_orphan_retries(sk, alive); | 192 | retry_until = tcp_orphan_retries(sk, alive); |
189 | do_reset = alive || | 193 | do_reset = alive || |
190 | !retransmits_timed_out(sk, retry_until); | 194 | !retransmits_timed_out(sk, retry_until, 0); |
191 | 195 | ||
192 | if (tcp_out_of_resources(sk, do_reset)) | 196 | if (tcp_out_of_resources(sk, do_reset)) |
193 | return 1; | 197 | return 1; |
194 | } | 198 | } |
195 | } | 199 | } |
196 | 200 | ||
197 | if (retransmits_timed_out(sk, retry_until)) { | 201 | if (retransmits_timed_out(sk, retry_until, syn_set)) { |
198 | /* Has it gone just too far? */ | 202 | /* Has it gone just too far? */ |
199 | tcp_write_err(sk); | 203 | tcp_write_err(sk); |
200 | return 1; | 204 | return 1; |
@@ -436,7 +440,7 @@ out_reset_timer: | |||
436 | icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX); | 440 | icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX); |
437 | } | 441 | } |
438 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto, TCP_RTO_MAX); | 442 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto, TCP_RTO_MAX); |
439 | if (retransmits_timed_out(sk, sysctl_tcp_retries1 + 1)) | 443 | if (retransmits_timed_out(sk, sysctl_tcp_retries1 + 1, 0)) |
440 | __sk_dst_reset(sk); | 444 | __sk_dst_reset(sk); |
441 | 445 | ||
442 | out:; | 446 | out:; |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 32e0bef60d0..fb23c2e63b5 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -1260,6 +1260,49 @@ void udp_lib_unhash(struct sock *sk) | |||
1260 | } | 1260 | } |
1261 | EXPORT_SYMBOL(udp_lib_unhash); | 1261 | EXPORT_SYMBOL(udp_lib_unhash); |
1262 | 1262 | ||
1263 | /* | ||
1264 | * inet_rcv_saddr was changed, we must rehash secondary hash | ||
1265 | */ | ||
1266 | void udp_lib_rehash(struct sock *sk, u16 newhash) | ||
1267 | { | ||
1268 | if (sk_hashed(sk)) { | ||
1269 | struct udp_table *udptable = sk->sk_prot->h.udp_table; | ||
1270 | struct udp_hslot *hslot, *hslot2, *nhslot2; | ||
1271 | |||
1272 | hslot2 = udp_hashslot2(udptable, udp_sk(sk)->udp_portaddr_hash); | ||
1273 | nhslot2 = udp_hashslot2(udptable, newhash); | ||
1274 | udp_sk(sk)->udp_portaddr_hash = newhash; | ||
1275 | if (hslot2 != nhslot2) { | ||
1276 | hslot = udp_hashslot(udptable, sock_net(sk), | ||
1277 | udp_sk(sk)->udp_port_hash); | ||
1278 | /* we must lock primary chain too */ | ||
1279 | spin_lock_bh(&hslot->lock); | ||
1280 | |||
1281 | spin_lock(&hslot2->lock); | ||
1282 | hlist_nulls_del_init_rcu(&udp_sk(sk)->udp_portaddr_node); | ||
1283 | hslot2->count--; | ||
1284 | spin_unlock(&hslot2->lock); | ||
1285 | |||
1286 | spin_lock(&nhslot2->lock); | ||
1287 | hlist_nulls_add_head_rcu(&udp_sk(sk)->udp_portaddr_node, | ||
1288 | &nhslot2->head); | ||
1289 | nhslot2->count++; | ||
1290 | spin_unlock(&nhslot2->lock); | ||
1291 | |||
1292 | spin_unlock_bh(&hslot->lock); | ||
1293 | } | ||
1294 | } | ||
1295 | } | ||
1296 | EXPORT_SYMBOL(udp_lib_rehash); | ||
1297 | |||
1298 | static void udp_v4_rehash(struct sock *sk) | ||
1299 | { | ||
1300 | u16 new_hash = udp4_portaddr_hash(sock_net(sk), | ||
1301 | inet_sk(sk)->inet_rcv_saddr, | ||
1302 | inet_sk(sk)->inet_num); | ||
1303 | udp_lib_rehash(sk, new_hash); | ||
1304 | } | ||
1305 | |||
1263 | static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) | 1306 | static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) |
1264 | { | 1307 | { |
1265 | int rc; | 1308 | int rc; |
@@ -1843,6 +1886,7 @@ struct proto udp_prot = { | |||
1843 | .backlog_rcv = __udp_queue_rcv_skb, | 1886 | .backlog_rcv = __udp_queue_rcv_skb, |
1844 | .hash = udp_lib_hash, | 1887 | .hash = udp_lib_hash, |
1845 | .unhash = udp_lib_unhash, | 1888 | .unhash = udp_lib_unhash, |
1889 | .rehash = udp_v4_rehash, | ||
1846 | .get_port = udp_v4_get_port, | 1890 | .get_port = udp_v4_get_port, |
1847 | .memory_allocated = &udp_memory_allocated, | 1891 | .memory_allocated = &udp_memory_allocated, |
1848 | .sysctl_mem = sysctl_udp_mem, | 1892 | .sysctl_mem = sysctl_udp_mem, |
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 869078d4eeb..a580349f0b8 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c | |||
@@ -61,7 +61,7 @@ static int xfrm4_get_saddr(struct net *net, | |||
61 | 61 | ||
62 | static int xfrm4_get_tos(struct flowi *fl) | 62 | static int xfrm4_get_tos(struct flowi *fl) |
63 | { | 63 | { |
64 | return fl->fl4_tos; | 64 | return IPTOS_RT_MASK & fl->fl4_tos; /* Strip ECN bits */ |
65 | } | 65 | } |
66 | 66 | ||
67 | static int xfrm4_init_path(struct xfrm_dst *path, struct dst_entry *dst, | 67 | static int xfrm4_init_path(struct xfrm_dst *path, struct dst_entry *dst, |
diff --git a/net/ipv4/xfrm4_state.c b/net/ipv4/xfrm4_state.c index 1ef1366a0a0..47947624ecc 100644 --- a/net/ipv4/xfrm4_state.c +++ b/net/ipv4/xfrm4_state.c | |||
@@ -21,21 +21,25 @@ static int xfrm4_init_flags(struct xfrm_state *x) | |||
21 | } | 21 | } |
22 | 22 | ||
23 | static void | 23 | static void |
24 | __xfrm4_init_tempsel(struct xfrm_state *x, struct flowi *fl, | 24 | __xfrm4_init_tempsel(struct xfrm_selector *sel, struct flowi *fl) |
25 | struct xfrm_tmpl *tmpl, | 25 | { |
26 | xfrm_address_t *daddr, xfrm_address_t *saddr) | 26 | sel->daddr.a4 = fl->fl4_dst; |
27 | sel->saddr.a4 = fl->fl4_src; | ||
28 | sel->dport = xfrm_flowi_dport(fl); | ||
29 | sel->dport_mask = htons(0xffff); | ||
30 | sel->sport = xfrm_flowi_sport(fl); | ||
31 | sel->sport_mask = htons(0xffff); | ||
32 | sel->family = AF_INET; | ||
33 | sel->prefixlen_d = 32; | ||
34 | sel->prefixlen_s = 32; | ||
35 | sel->proto = fl->proto; | ||
36 | sel->ifindex = fl->oif; | ||
37 | } | ||
38 | |||
39 | static void | ||
40 | xfrm4_init_temprop(struct xfrm_state *x, struct xfrm_tmpl *tmpl, | ||
41 | xfrm_address_t *daddr, xfrm_address_t *saddr) | ||
27 | { | 42 | { |
28 | x->sel.daddr.a4 = fl->fl4_dst; | ||
29 | x->sel.saddr.a4 = fl->fl4_src; | ||
30 | x->sel.dport = xfrm_flowi_dport(fl); | ||
31 | x->sel.dport_mask = htons(0xffff); | ||
32 | x->sel.sport = xfrm_flowi_sport(fl); | ||
33 | x->sel.sport_mask = htons(0xffff); | ||
34 | x->sel.family = AF_INET; | ||
35 | x->sel.prefixlen_d = 32; | ||
36 | x->sel.prefixlen_s = 32; | ||
37 | x->sel.proto = fl->proto; | ||
38 | x->sel.ifindex = fl->oif; | ||
39 | x->id = tmpl->id; | 43 | x->id = tmpl->id; |
40 | if (x->id.daddr.a4 == 0) | 44 | if (x->id.daddr.a4 == 0) |
41 | x->id.daddr.a4 = daddr->a4; | 45 | x->id.daddr.a4 = daddr->a4; |
@@ -70,6 +74,7 @@ static struct xfrm_state_afinfo xfrm4_state_afinfo = { | |||
70 | .owner = THIS_MODULE, | 74 | .owner = THIS_MODULE, |
71 | .init_flags = xfrm4_init_flags, | 75 | .init_flags = xfrm4_init_flags, |
72 | .init_tempsel = __xfrm4_init_tempsel, | 76 | .init_tempsel = __xfrm4_init_tempsel, |
77 | .init_temprop = xfrm4_init_temprop, | ||
73 | .output = xfrm4_output, | 78 | .output = xfrm4_output, |
74 | .extract_input = xfrm4_extract_input, | 79 | .extract_input = xfrm4_extract_input, |
75 | .extract_output = xfrm4_extract_output, | 80 | .extract_output = xfrm4_extract_output, |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index ab70a3fbcaf..324fac3b6c1 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -4637,10 +4637,12 @@ int __init addrconf_init(void) | |||
4637 | if (err < 0) { | 4637 | if (err < 0) { |
4638 | printk(KERN_CRIT "IPv6 Addrconf:" | 4638 | printk(KERN_CRIT "IPv6 Addrconf:" |
4639 | " cannot initialize default policy table: %d.\n", err); | 4639 | " cannot initialize default policy table: %d.\n", err); |
4640 | return err; | 4640 | goto out; |
4641 | } | 4641 | } |
4642 | 4642 | ||
4643 | register_pernet_subsys(&addrconf_ops); | 4643 | err = register_pernet_subsys(&addrconf_ops); |
4644 | if (err < 0) | ||
4645 | goto out_addrlabel; | ||
4644 | 4646 | ||
4645 | /* The addrconf netdev notifier requires that loopback_dev | 4647 | /* The addrconf netdev notifier requires that loopback_dev |
4646 | * has it's ipv6 private information allocated and setup | 4648 | * has it's ipv6 private information allocated and setup |
@@ -4692,7 +4694,9 @@ errout: | |||
4692 | unregister_netdevice_notifier(&ipv6_dev_notf); | 4694 | unregister_netdevice_notifier(&ipv6_dev_notf); |
4693 | errlo: | 4695 | errlo: |
4694 | unregister_pernet_subsys(&addrconf_ops); | 4696 | unregister_pernet_subsys(&addrconf_ops); |
4695 | 4697 | out_addrlabel: | |
4698 | ipv6_addr_label_cleanup(); | ||
4699 | out: | ||
4696 | return err; | 4700 | return err; |
4697 | } | 4701 | } |
4698 | 4702 | ||
@@ -4703,6 +4707,7 @@ void addrconf_cleanup(void) | |||
4703 | 4707 | ||
4704 | unregister_netdevice_notifier(&ipv6_dev_notf); | 4708 | unregister_netdevice_notifier(&ipv6_dev_notf); |
4705 | unregister_pernet_subsys(&addrconf_ops); | 4709 | unregister_pernet_subsys(&addrconf_ops); |
4710 | ipv6_addr_label_cleanup(); | ||
4706 | 4711 | ||
4707 | rtnl_lock(); | 4712 | rtnl_lock(); |
4708 | 4713 | ||
diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c index f0e774cea38..8175f802651 100644 --- a/net/ipv6/addrlabel.c +++ b/net/ipv6/addrlabel.c | |||
@@ -393,6 +393,11 @@ int __init ipv6_addr_label_init(void) | |||
393 | return register_pernet_subsys(&ipv6_addr_label_ops); | 393 | return register_pernet_subsys(&ipv6_addr_label_ops); |
394 | } | 394 | } |
395 | 395 | ||
396 | void ipv6_addr_label_cleanup(void) | ||
397 | { | ||
398 | unregister_pernet_subsys(&ipv6_addr_label_ops); | ||
399 | } | ||
400 | |||
396 | static const struct nla_policy ifal_policy[IFAL_MAX+1] = { | 401 | static const struct nla_policy ifal_policy[IFAL_MAX+1] = { |
397 | [IFAL_ADDRESS] = { .len = sizeof(struct in6_addr), }, | 402 | [IFAL_ADDRESS] = { .len = sizeof(struct in6_addr), }, |
398 | [IFAL_LABEL] = { .len = sizeof(u32), }, | 403 | [IFAL_LABEL] = { .len = sizeof(u32), }, |
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 7d929a22cbc..ef371aa01ac 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
@@ -105,9 +105,12 @@ ipv4_connected: | |||
105 | if (ipv6_addr_any(&np->saddr)) | 105 | if (ipv6_addr_any(&np->saddr)) |
106 | ipv6_addr_set_v4mapped(inet->inet_saddr, &np->saddr); | 106 | ipv6_addr_set_v4mapped(inet->inet_saddr, &np->saddr); |
107 | 107 | ||
108 | if (ipv6_addr_any(&np->rcv_saddr)) | 108 | if (ipv6_addr_any(&np->rcv_saddr)) { |
109 | ipv6_addr_set_v4mapped(inet->inet_rcv_saddr, | 109 | ipv6_addr_set_v4mapped(inet->inet_rcv_saddr, |
110 | &np->rcv_saddr); | 110 | &np->rcv_saddr); |
111 | if (sk->sk_prot->rehash) | ||
112 | sk->sk_prot->rehash(sk); | ||
113 | } | ||
111 | 114 | ||
112 | goto out; | 115 | goto out; |
113 | } | 116 | } |
@@ -181,6 +184,8 @@ ipv4_connected: | |||
181 | if (ipv6_addr_any(&np->rcv_saddr)) { | 184 | if (ipv6_addr_any(&np->rcv_saddr)) { |
182 | ipv6_addr_copy(&np->rcv_saddr, &fl.fl6_src); | 185 | ipv6_addr_copy(&np->rcv_saddr, &fl.fl6_src); |
183 | inet->inet_rcv_saddr = LOOPBACK4_IPV6; | 186 | inet->inet_rcv_saddr = LOOPBACK4_IPV6; |
187 | if (sk->sk_prot->rehash) | ||
188 | sk->sk_prot->rehash(sk); | ||
184 | } | 189 | } |
185 | 190 | ||
186 | ip6_dst_store(sk, dst, | 191 | ip6_dst_store(sk, dst, |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index d40b330c0ee..980912ed7a3 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -639,7 +639,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
639 | 639 | ||
640 | if (skb_has_frags(skb)) { | 640 | if (skb_has_frags(skb)) { |
641 | int first_len = skb_pagelen(skb); | 641 | int first_len = skb_pagelen(skb); |
642 | int truesizes = 0; | 642 | struct sk_buff *frag2; |
643 | 643 | ||
644 | if (first_len - hlen > mtu || | 644 | if (first_len - hlen > mtu || |
645 | ((first_len - hlen) & 7) || | 645 | ((first_len - hlen) & 7) || |
@@ -651,18 +651,18 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
651 | if (frag->len > mtu || | 651 | if (frag->len > mtu || |
652 | ((frag->len & 7) && frag->next) || | 652 | ((frag->len & 7) && frag->next) || |
653 | skb_headroom(frag) < hlen) | 653 | skb_headroom(frag) < hlen) |
654 | goto slow_path; | 654 | goto slow_path_clean; |
655 | 655 | ||
656 | /* Partially cloned skb? */ | 656 | /* Partially cloned skb? */ |
657 | if (skb_shared(frag)) | 657 | if (skb_shared(frag)) |
658 | goto slow_path; | 658 | goto slow_path_clean; |
659 | 659 | ||
660 | BUG_ON(frag->sk); | 660 | BUG_ON(frag->sk); |
661 | if (skb->sk) { | 661 | if (skb->sk) { |
662 | frag->sk = skb->sk; | 662 | frag->sk = skb->sk; |
663 | frag->destructor = sock_wfree; | 663 | frag->destructor = sock_wfree; |
664 | truesizes += frag->truesize; | ||
665 | } | 664 | } |
665 | skb->truesize -= frag->truesize; | ||
666 | } | 666 | } |
667 | 667 | ||
668 | err = 0; | 668 | err = 0; |
@@ -693,7 +693,6 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
693 | 693 | ||
694 | first_len = skb_pagelen(skb); | 694 | first_len = skb_pagelen(skb); |
695 | skb->data_len = first_len - skb_headlen(skb); | 695 | skb->data_len = first_len - skb_headlen(skb); |
696 | skb->truesize -= truesizes; | ||
697 | skb->len = first_len; | 696 | skb->len = first_len; |
698 | ipv6_hdr(skb)->payload_len = htons(first_len - | 697 | ipv6_hdr(skb)->payload_len = htons(first_len - |
699 | sizeof(struct ipv6hdr)); | 698 | sizeof(struct ipv6hdr)); |
@@ -756,6 +755,15 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
756 | IPSTATS_MIB_FRAGFAILS); | 755 | IPSTATS_MIB_FRAGFAILS); |
757 | dst_release(&rt->dst); | 756 | dst_release(&rt->dst); |
758 | return err; | 757 | return err; |
758 | |||
759 | slow_path_clean: | ||
760 | skb_walk_frags(skb, frag2) { | ||
761 | if (frag2 == frag) | ||
762 | break; | ||
763 | frag2->sk = NULL; | ||
764 | frag2->destructor = NULL; | ||
765 | skb->truesize += frag2->truesize; | ||
766 | } | ||
759 | } | 767 | } |
760 | 768 | ||
761 | slow_path: | 769 | slow_path: |
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 29a7bca29e3..8e754be92c2 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
@@ -1766,6 +1766,9 @@ translate_compat_table(struct net *net, | |||
1766 | if (ret != 0) | 1766 | if (ret != 0) |
1767 | break; | 1767 | break; |
1768 | ++i; | 1768 | ++i; |
1769 | if (strcmp(ip6t_get_target(iter1)->u.user.name, | ||
1770 | XT_ERROR_TARGET) == 0) | ||
1771 | ++newinfo->stacksize; | ||
1769 | } | 1772 | } |
1770 | if (ret) { | 1773 | if (ret) { |
1771 | /* | 1774 | /* |
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index 13ef5bc05cf..578f3c1a16d 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c | |||
@@ -113,14 +113,6 @@ static void nf_skb_free(struct sk_buff *skb) | |||
113 | kfree_skb(NFCT_FRAG6_CB(skb)->orig); | 113 | kfree_skb(NFCT_FRAG6_CB(skb)->orig); |
114 | } | 114 | } |
115 | 115 | ||
116 | /* Memory Tracking Functions. */ | ||
117 | static void frag_kfree_skb(struct sk_buff *skb) | ||
118 | { | ||
119 | atomic_sub(skb->truesize, &nf_init_frags.mem); | ||
120 | nf_skb_free(skb); | ||
121 | kfree_skb(skb); | ||
122 | } | ||
123 | |||
124 | /* Destruction primitives. */ | 116 | /* Destruction primitives. */ |
125 | 117 | ||
126 | static __inline__ void fq_put(struct nf_ct_frag6_queue *fq) | 118 | static __inline__ void fq_put(struct nf_ct_frag6_queue *fq) |
@@ -282,66 +274,22 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb, | |||
282 | } | 274 | } |
283 | 275 | ||
284 | found: | 276 | found: |
285 | /* We found where to put this one. Check for overlap with | 277 | /* RFC5722, Section 4: |
286 | * preceding fragment, and, if needed, align things so that | 278 | * When reassembling an IPv6 datagram, if |
287 | * any overlaps are eliminated. | 279 | * one or more its constituent fragments is determined to be an |
288 | */ | 280 | * overlapping fragment, the entire datagram (and any constituent |
289 | if (prev) { | 281 | * fragments, including those not yet received) MUST be silently |
290 | int i = (NFCT_FRAG6_CB(prev)->offset + prev->len) - offset; | 282 | * discarded. |
291 | |||
292 | if (i > 0) { | ||
293 | offset += i; | ||
294 | if (end <= offset) { | ||
295 | pr_debug("overlap\n"); | ||
296 | goto err; | ||
297 | } | ||
298 | if (!pskb_pull(skb, i)) { | ||
299 | pr_debug("Can't pull\n"); | ||
300 | goto err; | ||
301 | } | ||
302 | if (skb->ip_summed != CHECKSUM_UNNECESSARY) | ||
303 | skb->ip_summed = CHECKSUM_NONE; | ||
304 | } | ||
305 | } | ||
306 | |||
307 | /* Look for overlap with succeeding segments. | ||
308 | * If we can merge fragments, do it. | ||
309 | */ | 283 | */ |
310 | while (next && NFCT_FRAG6_CB(next)->offset < end) { | ||
311 | /* overlap is 'i' bytes */ | ||
312 | int i = end - NFCT_FRAG6_CB(next)->offset; | ||
313 | |||
314 | if (i < next->len) { | ||
315 | /* Eat head of the next overlapped fragment | ||
316 | * and leave the loop. The next ones cannot overlap. | ||
317 | */ | ||
318 | pr_debug("Eat head of the overlapped parts.: %d", i); | ||
319 | if (!pskb_pull(next, i)) | ||
320 | goto err; | ||
321 | 284 | ||
322 | /* next fragment */ | 285 | /* Check for overlap with preceding fragment. */ |
323 | NFCT_FRAG6_CB(next)->offset += i; | 286 | if (prev && |
324 | fq->q.meat -= i; | 287 | (NFCT_FRAG6_CB(prev)->offset + prev->len) - offset > 0) |
325 | if (next->ip_summed != CHECKSUM_UNNECESSARY) | 288 | goto discard_fq; |
326 | next->ip_summed = CHECKSUM_NONE; | ||
327 | break; | ||
328 | } else { | ||
329 | struct sk_buff *free_it = next; | ||
330 | |||
331 | /* Old fragmnet is completely overridden with | ||
332 | * new one drop it. | ||
333 | */ | ||
334 | next = next->next; | ||
335 | 289 | ||
336 | if (prev) | 290 | /* Look for overlap with succeeding segment. */ |
337 | prev->next = next; | 291 | if (next && NFCT_FRAG6_CB(next)->offset < end) |
338 | else | 292 | goto discard_fq; |
339 | fq->q.fragments = next; | ||
340 | |||
341 | fq->q.meat -= free_it->len; | ||
342 | frag_kfree_skb(free_it); | ||
343 | } | ||
344 | } | ||
345 | 293 | ||
346 | NFCT_FRAG6_CB(skb)->offset = offset; | 294 | NFCT_FRAG6_CB(skb)->offset = offset; |
347 | 295 | ||
@@ -371,6 +319,8 @@ found: | |||
371 | write_unlock(&nf_frags.lock); | 319 | write_unlock(&nf_frags.lock); |
372 | return 0; | 320 | return 0; |
373 | 321 | ||
322 | discard_fq: | ||
323 | fq_kill(fq); | ||
374 | err: | 324 | err: |
375 | return -1; | 325 | return -1; |
376 | } | 326 | } |
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index 545c4141b75..64cfef1b0a4 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c | |||
@@ -149,13 +149,6 @@ int ip6_frag_match(struct inet_frag_queue *q, void *a) | |||
149 | } | 149 | } |
150 | EXPORT_SYMBOL(ip6_frag_match); | 150 | EXPORT_SYMBOL(ip6_frag_match); |
151 | 151 | ||
152 | /* Memory Tracking Functions. */ | ||
153 | static void frag_kfree_skb(struct netns_frags *nf, struct sk_buff *skb) | ||
154 | { | ||
155 | atomic_sub(skb->truesize, &nf->mem); | ||
156 | kfree_skb(skb); | ||
157 | } | ||
158 | |||
159 | void ip6_frag_init(struct inet_frag_queue *q, void *a) | 152 | void ip6_frag_init(struct inet_frag_queue *q, void *a) |
160 | { | 153 | { |
161 | struct frag_queue *fq = container_of(q, struct frag_queue, q); | 154 | struct frag_queue *fq = container_of(q, struct frag_queue, q); |
@@ -346,58 +339,22 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, | |||
346 | } | 339 | } |
347 | 340 | ||
348 | found: | 341 | found: |
349 | /* We found where to put this one. Check for overlap with | 342 | /* RFC5722, Section 4: |
350 | * preceding fragment, and, if needed, align things so that | 343 | * When reassembling an IPv6 datagram, if |
351 | * any overlaps are eliminated. | 344 | * one or more its constituent fragments is determined to be an |
345 | * overlapping fragment, the entire datagram (and any constituent | ||
346 | * fragments, including those not yet received) MUST be silently | ||
347 | * discarded. | ||
352 | */ | 348 | */ |
353 | if (prev) { | ||
354 | int i = (FRAG6_CB(prev)->offset + prev->len) - offset; | ||
355 | 349 | ||
356 | if (i > 0) { | 350 | /* Check for overlap with preceding fragment. */ |
357 | offset += i; | 351 | if (prev && |
358 | if (end <= offset) | 352 | (FRAG6_CB(prev)->offset + prev->len) - offset > 0) |
359 | goto err; | 353 | goto discard_fq; |
360 | if (!pskb_pull(skb, i)) | ||
361 | goto err; | ||
362 | if (skb->ip_summed != CHECKSUM_UNNECESSARY) | ||
363 | skb->ip_summed = CHECKSUM_NONE; | ||
364 | } | ||
365 | } | ||
366 | 354 | ||
367 | /* Look for overlap with succeeding segments. | 355 | /* Look for overlap with succeeding segment. */ |
368 | * If we can merge fragments, do it. | 356 | if (next && FRAG6_CB(next)->offset < end) |
369 | */ | 357 | goto discard_fq; |
370 | while (next && FRAG6_CB(next)->offset < end) { | ||
371 | int i = end - FRAG6_CB(next)->offset; /* overlap is 'i' bytes */ | ||
372 | |||
373 | if (i < next->len) { | ||
374 | /* Eat head of the next overlapped fragment | ||
375 | * and leave the loop. The next ones cannot overlap. | ||
376 | */ | ||
377 | if (!pskb_pull(next, i)) | ||
378 | goto err; | ||
379 | FRAG6_CB(next)->offset += i; /* next fragment */ | ||
380 | fq->q.meat -= i; | ||
381 | if (next->ip_summed != CHECKSUM_UNNECESSARY) | ||
382 | next->ip_summed = CHECKSUM_NONE; | ||
383 | break; | ||
384 | } else { | ||
385 | struct sk_buff *free_it = next; | ||
386 | |||
387 | /* Old fragment is completely overridden with | ||
388 | * new one drop it. | ||
389 | */ | ||
390 | next = next->next; | ||
391 | |||
392 | if (prev) | ||
393 | prev->next = next; | ||
394 | else | ||
395 | fq->q.fragments = next; | ||
396 | |||
397 | fq->q.meat -= free_it->len; | ||
398 | frag_kfree_skb(fq->q.net, free_it); | ||
399 | } | ||
400 | } | ||
401 | 358 | ||
402 | FRAG6_CB(skb)->offset = offset; | 359 | FRAG6_CB(skb)->offset = offset; |
403 | 360 | ||
@@ -436,6 +393,8 @@ found: | |||
436 | write_unlock(&ip6_frags.lock); | 393 | write_unlock(&ip6_frags.lock); |
437 | return -1; | 394 | return -1; |
438 | 395 | ||
396 | discard_fq: | ||
397 | fq_kill(fq); | ||
439 | err: | 398 | err: |
440 | IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), | 399 | IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), |
441 | IPSTATS_MIB_REASMFAILS); | 400 | IPSTATS_MIB_REASMFAILS); |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index d126365ac04..a275c6e1e25 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -670,7 +670,7 @@ static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, struct in6_addr *dad | |||
670 | 670 | ||
671 | if (net_ratelimit()) | 671 | if (net_ratelimit()) |
672 | printk(KERN_WARNING | 672 | printk(KERN_WARNING |
673 | "Neighbour table overflow.\n"); | 673 | "ipv6: Neighbour table overflow.\n"); |
674 | dst_free(&rt->dst); | 674 | dst_free(&rt->dst); |
675 | return NULL; | 675 | return NULL; |
676 | } | 676 | } |
@@ -1556,14 +1556,13 @@ out: | |||
1556 | * i.e. Path MTU discovery | 1556 | * i.e. Path MTU discovery |
1557 | */ | 1557 | */ |
1558 | 1558 | ||
1559 | void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr, | 1559 | static void rt6_do_pmtu_disc(struct in6_addr *daddr, struct in6_addr *saddr, |
1560 | struct net_device *dev, u32 pmtu) | 1560 | struct net *net, u32 pmtu, int ifindex) |
1561 | { | 1561 | { |
1562 | struct rt6_info *rt, *nrt; | 1562 | struct rt6_info *rt, *nrt; |
1563 | struct net *net = dev_net(dev); | ||
1564 | int allfrag = 0; | 1563 | int allfrag = 0; |
1565 | 1564 | ||
1566 | rt = rt6_lookup(net, daddr, saddr, dev->ifindex, 0); | 1565 | rt = rt6_lookup(net, daddr, saddr, ifindex, 0); |
1567 | if (rt == NULL) | 1566 | if (rt == NULL) |
1568 | return; | 1567 | return; |
1569 | 1568 | ||
@@ -1631,6 +1630,27 @@ out: | |||
1631 | dst_release(&rt->dst); | 1630 | dst_release(&rt->dst); |
1632 | } | 1631 | } |
1633 | 1632 | ||
1633 | void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr, | ||
1634 | struct net_device *dev, u32 pmtu) | ||
1635 | { | ||
1636 | struct net *net = dev_net(dev); | ||
1637 | |||
1638 | /* | ||
1639 | * RFC 1981 states that a node "MUST reduce the size of the packets it | ||
1640 | * is sending along the path" that caused the Packet Too Big message. | ||
1641 | * Since it's not possible in the general case to determine which | ||
1642 | * interface was used to send the original packet, we update the MTU | ||
1643 | * on the interface that will be used to send future packets. We also | ||
1644 | * update the MTU on the interface that received the Packet Too Big in | ||
1645 | * case the original packet was forced out that interface with | ||
1646 | * SO_BINDTODEVICE or similar. This is the next best thing to the | ||
1647 | * correct behaviour, which would be to update the MTU on all | ||
1648 | * interfaces. | ||
1649 | */ | ||
1650 | rt6_do_pmtu_disc(daddr, saddr, net, pmtu, 0); | ||
1651 | rt6_do_pmtu_disc(daddr, saddr, net, pmtu, dev->ifindex); | ||
1652 | } | ||
1653 | |||
1634 | /* | 1654 | /* |
1635 | * Misc support functions | 1655 | * Misc support functions |
1636 | */ | 1656 | */ |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 1dd1affdead..5acb3560ff1 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -111,6 +111,15 @@ int udp_v6_get_port(struct sock *sk, unsigned short snum) | |||
111 | return udp_lib_get_port(sk, snum, ipv6_rcv_saddr_equal, hash2_nulladdr); | 111 | return udp_lib_get_port(sk, snum, ipv6_rcv_saddr_equal, hash2_nulladdr); |
112 | } | 112 | } |
113 | 113 | ||
114 | static void udp_v6_rehash(struct sock *sk) | ||
115 | { | ||
116 | u16 new_hash = udp6_portaddr_hash(sock_net(sk), | ||
117 | &inet6_sk(sk)->rcv_saddr, | ||
118 | inet_sk(sk)->inet_num); | ||
119 | |||
120 | udp_lib_rehash(sk, new_hash); | ||
121 | } | ||
122 | |||
114 | static inline int compute_score(struct sock *sk, struct net *net, | 123 | static inline int compute_score(struct sock *sk, struct net *net, |
115 | unsigned short hnum, | 124 | unsigned short hnum, |
116 | struct in6_addr *saddr, __be16 sport, | 125 | struct in6_addr *saddr, __be16 sport, |
@@ -1447,6 +1456,7 @@ struct proto udpv6_prot = { | |||
1447 | .backlog_rcv = udpv6_queue_rcv_skb, | 1456 | .backlog_rcv = udpv6_queue_rcv_skb, |
1448 | .hash = udp_lib_hash, | 1457 | .hash = udp_lib_hash, |
1449 | .unhash = udp_lib_unhash, | 1458 | .unhash = udp_lib_unhash, |
1459 | .rehash = udp_v6_rehash, | ||
1450 | .get_port = udp_v6_get_port, | 1460 | .get_port = udp_v6_get_port, |
1451 | .memory_allocated = &udp_memory_allocated, | 1461 | .memory_allocated = &udp_memory_allocated, |
1452 | .sysctl_mem = sysctl_udp_mem, | 1462 | .sysctl_mem = sysctl_udp_mem, |
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c index f417b77fa0e..a67575d472a 100644 --- a/net/ipv6/xfrm6_state.c +++ b/net/ipv6/xfrm6_state.c | |||
@@ -20,23 +20,27 @@ | |||
20 | #include <net/addrconf.h> | 20 | #include <net/addrconf.h> |
21 | 21 | ||
22 | static void | 22 | static void |
23 | __xfrm6_init_tempsel(struct xfrm_state *x, struct flowi *fl, | 23 | __xfrm6_init_tempsel(struct xfrm_selector *sel, struct flowi *fl) |
24 | struct xfrm_tmpl *tmpl, | ||
25 | xfrm_address_t *daddr, xfrm_address_t *saddr) | ||
26 | { | 24 | { |
27 | /* Initialize temporary selector matching only | 25 | /* Initialize temporary selector matching only |
28 | * to current session. */ | 26 | * to current session. */ |
29 | ipv6_addr_copy((struct in6_addr *)&x->sel.daddr, &fl->fl6_dst); | 27 | ipv6_addr_copy((struct in6_addr *)&sel->daddr, &fl->fl6_dst); |
30 | ipv6_addr_copy((struct in6_addr *)&x->sel.saddr, &fl->fl6_src); | 28 | ipv6_addr_copy((struct in6_addr *)&sel->saddr, &fl->fl6_src); |
31 | x->sel.dport = xfrm_flowi_dport(fl); | 29 | sel->dport = xfrm_flowi_dport(fl); |
32 | x->sel.dport_mask = htons(0xffff); | 30 | sel->dport_mask = htons(0xffff); |
33 | x->sel.sport = xfrm_flowi_sport(fl); | 31 | sel->sport = xfrm_flowi_sport(fl); |
34 | x->sel.sport_mask = htons(0xffff); | 32 | sel->sport_mask = htons(0xffff); |
35 | x->sel.family = AF_INET6; | 33 | sel->family = AF_INET6; |
36 | x->sel.prefixlen_d = 128; | 34 | sel->prefixlen_d = 128; |
37 | x->sel.prefixlen_s = 128; | 35 | sel->prefixlen_s = 128; |
38 | x->sel.proto = fl->proto; | 36 | sel->proto = fl->proto; |
39 | x->sel.ifindex = fl->oif; | 37 | sel->ifindex = fl->oif; |
38 | } | ||
39 | |||
40 | static void | ||
41 | xfrm6_init_temprop(struct xfrm_state *x, struct xfrm_tmpl *tmpl, | ||
42 | xfrm_address_t *daddr, xfrm_address_t *saddr) | ||
43 | { | ||
40 | x->id = tmpl->id; | 44 | x->id = tmpl->id; |
41 | if (ipv6_addr_any((struct in6_addr*)&x->id.daddr)) | 45 | if (ipv6_addr_any((struct in6_addr*)&x->id.daddr)) |
42 | memcpy(&x->id.daddr, daddr, sizeof(x->sel.daddr)); | 46 | memcpy(&x->id.daddr, daddr, sizeof(x->sel.daddr)); |
@@ -168,6 +172,7 @@ static struct xfrm_state_afinfo xfrm6_state_afinfo = { | |||
168 | .eth_proto = htons(ETH_P_IPV6), | 172 | .eth_proto = htons(ETH_P_IPV6), |
169 | .owner = THIS_MODULE, | 173 | .owner = THIS_MODULE, |
170 | .init_tempsel = __xfrm6_init_tempsel, | 174 | .init_tempsel = __xfrm6_init_tempsel, |
175 | .init_temprop = xfrm6_init_temprop, | ||
171 | .tmpl_sort = __xfrm6_tmpl_sort, | 176 | .tmpl_sort = __xfrm6_tmpl_sort, |
172 | .state_sort = __xfrm6_state_sort, | 177 | .state_sort = __xfrm6_state_sort, |
173 | .output = xfrm6_output, | 178 | .output = xfrm6_output, |
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index 79986a674f6..fd55b5135de 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c | |||
@@ -824,8 +824,8 @@ static int irda_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
824 | 824 | ||
825 | err = irda_open_tsap(self, addr->sir_lsap_sel, addr->sir_name); | 825 | err = irda_open_tsap(self, addr->sir_lsap_sel, addr->sir_name); |
826 | if (err < 0) { | 826 | if (err < 0) { |
827 | kfree(self->ias_obj->name); | 827 | irias_delete_object(self->ias_obj); |
828 | kfree(self->ias_obj); | 828 | self->ias_obj = NULL; |
829 | goto out; | 829 | goto out; |
830 | } | 830 | } |
831 | 831 | ||
diff --git a/net/irda/irlan/irlan_common.c b/net/irda/irlan/irlan_common.c index a788f9e9427..6130f9d9dbe 100644 --- a/net/irda/irlan/irlan_common.c +++ b/net/irda/irlan/irlan_common.c | |||
@@ -1102,7 +1102,7 @@ int irlan_extract_param(__u8 *buf, char *name, char *value, __u16 *len) | |||
1102 | memcpy(&val_len, buf+n, 2); /* To avoid alignment problems */ | 1102 | memcpy(&val_len, buf+n, 2); /* To avoid alignment problems */ |
1103 | le16_to_cpus(&val_len); n+=2; | 1103 | le16_to_cpus(&val_len); n+=2; |
1104 | 1104 | ||
1105 | if (val_len > 1016) { | 1105 | if (val_len >= 1016) { |
1106 | IRDA_DEBUG(2, "%s(), parameter length to long\n", __func__ ); | 1106 | IRDA_DEBUG(2, "%s(), parameter length to long\n", __func__ ); |
1107 | return -RSP_INVALID_COMMAND_FORMAT; | 1107 | return -RSP_INVALID_COMMAND_FORMAT; |
1108 | } | 1108 | } |
diff --git a/net/irda/irlan/irlan_eth.c b/net/irda/irlan/irlan_eth.c index 9616c32d107..5bb8353105c 100644 --- a/net/irda/irlan/irlan_eth.c +++ b/net/irda/irlan/irlan_eth.c | |||
@@ -169,6 +169,7 @@ static netdev_tx_t irlan_eth_xmit(struct sk_buff *skb, | |||
169 | { | 169 | { |
170 | struct irlan_cb *self = netdev_priv(dev); | 170 | struct irlan_cb *self = netdev_priv(dev); |
171 | int ret; | 171 | int ret; |
172 | unsigned int len; | ||
172 | 173 | ||
173 | /* skb headroom large enough to contain all IrDA-headers? */ | 174 | /* skb headroom large enough to contain all IrDA-headers? */ |
174 | if ((skb_headroom(skb) < self->max_header_size) || (skb_shared(skb))) { | 175 | if ((skb_headroom(skb) < self->max_header_size) || (skb_shared(skb))) { |
@@ -188,6 +189,7 @@ static netdev_tx_t irlan_eth_xmit(struct sk_buff *skb, | |||
188 | 189 | ||
189 | dev->trans_start = jiffies; | 190 | dev->trans_start = jiffies; |
190 | 191 | ||
192 | len = skb->len; | ||
191 | /* Now queue the packet in the transport layer */ | 193 | /* Now queue the packet in the transport layer */ |
192 | if (self->use_udata) | 194 | if (self->use_udata) |
193 | ret = irttp_udata_request(self->tsap_data, skb); | 195 | ret = irttp_udata_request(self->tsap_data, skb); |
@@ -209,7 +211,7 @@ static netdev_tx_t irlan_eth_xmit(struct sk_buff *skb, | |||
209 | self->stats.tx_dropped++; | 211 | self->stats.tx_dropped++; |
210 | } else { | 212 | } else { |
211 | self->stats.tx_packets++; | 213 | self->stats.tx_packets++; |
212 | self->stats.tx_bytes += skb->len; | 214 | self->stats.tx_bytes += len; |
213 | } | 215 | } |
214 | 216 | ||
215 | return NETDEV_TX_OK; | 217 | return NETDEV_TX_OK; |
diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c index 58c6c4cda73..1ae697681bc 100644 --- a/net/l2tp/l2tp_eth.c +++ b/net/l2tp/l2tp_eth.c | |||
@@ -132,7 +132,7 @@ static void l2tp_eth_dev_recv(struct l2tp_session *session, struct sk_buff *skb, | |||
132 | printk("\n"); | 132 | printk("\n"); |
133 | } | 133 | } |
134 | 134 | ||
135 | if (data_len < ETH_HLEN) | 135 | if (!pskb_may_pull(skb, sizeof(ETH_HLEN))) |
136 | goto error; | 136 | goto error; |
137 | 137 | ||
138 | secpath_reset(skb); | 138 | secpath_reset(skb); |
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c index 023ba820236..58261299821 100644 --- a/net/llc/af_llc.c +++ b/net/llc/af_llc.c | |||
@@ -1024,7 +1024,8 @@ static int llc_ui_setsockopt(struct socket *sock, int level, int optname, | |||
1024 | { | 1024 | { |
1025 | struct sock *sk = sock->sk; | 1025 | struct sock *sk = sock->sk; |
1026 | struct llc_sock *llc = llc_sk(sk); | 1026 | struct llc_sock *llc = llc_sk(sk); |
1027 | int rc = -EINVAL, opt; | 1027 | unsigned int opt; |
1028 | int rc = -EINVAL; | ||
1028 | 1029 | ||
1029 | lock_sock(sk); | 1030 | lock_sock(sk); |
1030 | if (unlikely(level != SOL_LLC || optlen != sizeof(int))) | 1031 | if (unlikely(level != SOL_LLC || optlen != sizeof(int))) |
diff --git a/net/llc/llc_station.c b/net/llc/llc_station.c index e4dae0244d7..cf4aea3ba30 100644 --- a/net/llc/llc_station.c +++ b/net/llc/llc_station.c | |||
@@ -689,7 +689,7 @@ static void llc_station_rcv(struct sk_buff *skb) | |||
689 | 689 | ||
690 | int __init llc_station_init(void) | 690 | int __init llc_station_init(void) |
691 | { | 691 | { |
692 | u16 rc = -ENOBUFS; | 692 | int rc = -ENOBUFS; |
693 | struct sk_buff *skb; | 693 | struct sk_buff *skb; |
694 | struct llc_station_state_ev *ev; | 694 | struct llc_station_state_ev *ev; |
695 | 695 | ||
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index c893f236ace..8f23401832b 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c | |||
@@ -175,6 +175,8 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | |||
175 | 175 | ||
176 | set_bit(HT_AGG_STATE_STOPPING, &tid_tx->state); | 176 | set_bit(HT_AGG_STATE_STOPPING, &tid_tx->state); |
177 | 177 | ||
178 | del_timer_sync(&tid_tx->addba_resp_timer); | ||
179 | |||
178 | /* | 180 | /* |
179 | * After this packets are no longer handed right through | 181 | * After this packets are no longer handed right through |
180 | * to the driver but are put onto tid_tx->pending instead, | 182 | * to the driver but are put onto tid_tx->pending instead, |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 798a91b100c..ded5c3843e0 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -732,6 +732,12 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
732 | 732 | ||
733 | rtnl_unlock(); | 733 | rtnl_unlock(); |
734 | 734 | ||
735 | /* | ||
736 | * Now all work items will be gone, but the | ||
737 | * timer might still be armed, so delete it | ||
738 | */ | ||
739 | del_timer_sync(&local->work_timer); | ||
740 | |||
735 | cancel_work_sync(&local->reconfig_filter); | 741 | cancel_work_sync(&local->reconfig_filter); |
736 | 742 | ||
737 | ieee80211_clear_tx_pending(local); | 743 | ieee80211_clear_tx_pending(local); |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index fa0f37e4afe..28624282c5f 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -2199,9 +2199,6 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, | |||
2199 | struct net_device *prev_dev = NULL; | 2199 | struct net_device *prev_dev = NULL; |
2200 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 2200 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
2201 | 2201 | ||
2202 | if (status->flag & RX_FLAG_INTERNAL_CMTR) | ||
2203 | goto out_free_skb; | ||
2204 | |||
2205 | if (skb_headroom(skb) < sizeof(*rthdr) && | 2202 | if (skb_headroom(skb) < sizeof(*rthdr) && |
2206 | pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC)) | 2203 | pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC)) |
2207 | goto out_free_skb; | 2204 | goto out_free_skb; |
@@ -2260,7 +2257,6 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, | |||
2260 | } else | 2257 | } else |
2261 | goto out_free_skb; | 2258 | goto out_free_skb; |
2262 | 2259 | ||
2263 | status->flag |= RX_FLAG_INTERNAL_CMTR; | ||
2264 | return; | 2260 | return; |
2265 | 2261 | ||
2266 | out_free_skb: | 2262 | out_free_skb: |
diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 10caec5ea8f..34da67995d9 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c | |||
@@ -377,7 +377,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
377 | skb2 = skb_clone(skb, GFP_ATOMIC); | 377 | skb2 = skb_clone(skb, GFP_ATOMIC); |
378 | if (skb2) { | 378 | if (skb2) { |
379 | skb2->dev = prev_dev; | 379 | skb2->dev = prev_dev; |
380 | netif_receive_skb(skb2); | 380 | netif_rx(skb2); |
381 | } | 381 | } |
382 | } | 382 | } |
383 | 383 | ||
@@ -386,7 +386,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
386 | } | 386 | } |
387 | if (prev_dev) { | 387 | if (prev_dev) { |
388 | skb->dev = prev_dev; | 388 | skb->dev = prev_dev; |
389 | netif_receive_skb(skb); | 389 | netif_rx(skb); |
390 | skb = NULL; | 390 | skb = NULL; |
391 | } | 391 | } |
392 | rcu_read_unlock(); | 392 | rcu_read_unlock(); |
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index 4f8ddba4801..4c2f89df5cc 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c | |||
@@ -924,6 +924,7 @@ handle_response(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, | |||
924 | 924 | ||
925 | ip_vs_out_stats(cp, skb); | 925 | ip_vs_out_stats(cp, skb); |
926 | ip_vs_set_state(cp, IP_VS_DIR_OUTPUT, skb, pp); | 926 | ip_vs_set_state(cp, IP_VS_DIR_OUTPUT, skb, pp); |
927 | ip_vs_update_conntrack(skb, cp, 0); | ||
927 | ip_vs_conn_put(cp); | 928 | ip_vs_conn_put(cp); |
928 | 929 | ||
929 | skb->ipvs_property = 1; | 930 | skb->ipvs_property = 1; |
diff --git a/net/netfilter/ipvs/ip_vs_ftp.c b/net/netfilter/ipvs/ip_vs_ftp.c index f228a17ec64..7e9af5b76d9 100644 --- a/net/netfilter/ipvs/ip_vs_ftp.c +++ b/net/netfilter/ipvs/ip_vs_ftp.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <linux/netfilter.h> | 45 | #include <linux/netfilter.h> |
46 | #include <net/netfilter/nf_conntrack.h> | 46 | #include <net/netfilter/nf_conntrack.h> |
47 | #include <net/netfilter/nf_conntrack_expect.h> | 47 | #include <net/netfilter/nf_conntrack_expect.h> |
48 | #include <net/netfilter/nf_nat.h> | ||
48 | #include <net/netfilter/nf_nat_helper.h> | 49 | #include <net/netfilter/nf_nat_helper.h> |
49 | #include <linux/gfp.h> | 50 | #include <linux/gfp.h> |
50 | #include <net/protocol.h> | 51 | #include <net/protocol.h> |
@@ -359,7 +360,7 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp, | |||
359 | buf_len = strlen(buf); | 360 | buf_len = strlen(buf); |
360 | 361 | ||
361 | ct = nf_ct_get(skb, &ctinfo); | 362 | ct = nf_ct_get(skb, &ctinfo); |
362 | if (ct && !nf_ct_is_untracked(ct)) { | 363 | if (ct && !nf_ct_is_untracked(ct) && nfct_nat(ct)) { |
363 | /* If mangling fails this function will return 0 | 364 | /* If mangling fails this function will return 0 |
364 | * which will cause the packet to be dropped. | 365 | * which will cause the packet to be dropped. |
365 | * Mangling can only fail under memory pressure, | 366 | * Mangling can only fail under memory pressure, |
@@ -409,7 +410,6 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp, | |||
409 | union nf_inet_addr to; | 410 | union nf_inet_addr to; |
410 | __be16 port; | 411 | __be16 port; |
411 | struct ip_vs_conn *n_cp; | 412 | struct ip_vs_conn *n_cp; |
412 | struct nf_conn *ct; | ||
413 | 413 | ||
414 | #ifdef CONFIG_IP_VS_IPV6 | 414 | #ifdef CONFIG_IP_VS_IPV6 |
415 | /* This application helper doesn't work with IPv6 yet, | 415 | /* This application helper doesn't work with IPv6 yet, |
@@ -496,11 +496,6 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp, | |||
496 | ip_vs_control_add(n_cp, cp); | 496 | ip_vs_control_add(n_cp, cp); |
497 | } | 497 | } |
498 | 498 | ||
499 | ct = (struct nf_conn *)skb->nfct; | ||
500 | if (ct && ct != &nf_conntrack_untracked) | ||
501 | ip_vs_expect_related(skb, ct, n_cp, | ||
502 | IPPROTO_TCP, &n_cp->dport, 1); | ||
503 | |||
504 | /* | 499 | /* |
505 | * Move tunnel to listen state | 500 | * Move tunnel to listen state |
506 | */ | 501 | */ |
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c index 21e1a5e9b9d..49df6bea6a2 100644 --- a/net/netfilter/ipvs/ip_vs_xmit.c +++ b/net/netfilter/ipvs/ip_vs_xmit.c | |||
@@ -349,8 +349,8 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
349 | } | 349 | } |
350 | #endif | 350 | #endif |
351 | 351 | ||
352 | static void | 352 | void |
353 | ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp) | 353 | ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp, int outin) |
354 | { | 354 | { |
355 | struct nf_conn *ct = (struct nf_conn *)skb->nfct; | 355 | struct nf_conn *ct = (struct nf_conn *)skb->nfct; |
356 | struct nf_conntrack_tuple new_tuple; | 356 | struct nf_conntrack_tuple new_tuple; |
@@ -365,11 +365,17 @@ ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp) | |||
365 | * real-server we will see RIP->DIP. | 365 | * real-server we will see RIP->DIP. |
366 | */ | 366 | */ |
367 | new_tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple; | 367 | new_tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple; |
368 | new_tuple.src.u3 = cp->daddr; | 368 | if (outin) |
369 | new_tuple.src.u3 = cp->daddr; | ||
370 | else | ||
371 | new_tuple.dst.u3 = cp->vaddr; | ||
369 | /* | 372 | /* |
370 | * This will also take care of UDP and other protocols. | 373 | * This will also take care of UDP and other protocols. |
371 | */ | 374 | */ |
372 | new_tuple.src.u.tcp.port = cp->dport; | 375 | if (outin) |
376 | new_tuple.src.u.tcp.port = cp->dport; | ||
377 | else | ||
378 | new_tuple.dst.u.tcp.port = cp->vport; | ||
373 | nf_conntrack_alter_reply(ct, &new_tuple); | 379 | nf_conntrack_alter_reply(ct, &new_tuple); |
374 | } | 380 | } |
375 | 381 | ||
@@ -428,7 +434,7 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
428 | 434 | ||
429 | IP_VS_DBG_PKT(10, pp, skb, 0, "After DNAT"); | 435 | IP_VS_DBG_PKT(10, pp, skb, 0, "After DNAT"); |
430 | 436 | ||
431 | ip_vs_update_conntrack(skb, cp); | 437 | ip_vs_update_conntrack(skb, cp, 1); |
432 | 438 | ||
433 | /* FIXME: when application helper enlarges the packet and the length | 439 | /* FIXME: when application helper enlarges the packet and the length |
434 | is larger than the MTU of outgoing device, there will be still | 440 | is larger than the MTU of outgoing device, there will be still |
@@ -506,7 +512,7 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
506 | 512 | ||
507 | IP_VS_DBG_PKT(10, pp, skb, 0, "After DNAT"); | 513 | IP_VS_DBG_PKT(10, pp, skb, 0, "After DNAT"); |
508 | 514 | ||
509 | ip_vs_update_conntrack(skb, cp); | 515 | ip_vs_update_conntrack(skb, cp, 1); |
510 | 516 | ||
511 | /* FIXME: when application helper enlarges the packet and the length | 517 | /* FIXME: when application helper enlarges the packet and the length |
512 | is larger than the MTU of outgoing device, there will be still | 518 | is larger than the MTU of outgoing device, there will be still |
diff --git a/net/netfilter/nf_conntrack_extend.c b/net/netfilter/nf_conntrack_extend.c index 7dcf7a40419..8d9e4c949b9 100644 --- a/net/netfilter/nf_conntrack_extend.c +++ b/net/netfilter/nf_conntrack_extend.c | |||
@@ -48,15 +48,17 @@ nf_ct_ext_create(struct nf_ct_ext **ext, enum nf_ct_ext_id id, gfp_t gfp) | |||
48 | { | 48 | { |
49 | unsigned int off, len; | 49 | unsigned int off, len; |
50 | struct nf_ct_ext_type *t; | 50 | struct nf_ct_ext_type *t; |
51 | size_t alloc_size; | ||
51 | 52 | ||
52 | rcu_read_lock(); | 53 | rcu_read_lock(); |
53 | t = rcu_dereference(nf_ct_ext_types[id]); | 54 | t = rcu_dereference(nf_ct_ext_types[id]); |
54 | BUG_ON(t == NULL); | 55 | BUG_ON(t == NULL); |
55 | off = ALIGN(sizeof(struct nf_ct_ext), t->align); | 56 | off = ALIGN(sizeof(struct nf_ct_ext), t->align); |
56 | len = off + t->len; | 57 | len = off + t->len; |
58 | alloc_size = t->alloc_size; | ||
57 | rcu_read_unlock(); | 59 | rcu_read_unlock(); |
58 | 60 | ||
59 | *ext = kzalloc(t->alloc_size, gfp); | 61 | *ext = kzalloc(alloc_size, gfp); |
60 | if (!*ext) | 62 | if (!*ext) |
61 | return NULL; | 63 | return NULL; |
62 | 64 | ||
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index 53d892210a0..f64de954486 100644 --- a/net/netfilter/nf_conntrack_sip.c +++ b/net/netfilter/nf_conntrack_sip.c | |||
@@ -1376,7 +1376,7 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff, | |||
1376 | unsigned int msglen, origlen; | 1376 | unsigned int msglen, origlen; |
1377 | const char *dptr, *end; | 1377 | const char *dptr, *end; |
1378 | s16 diff, tdiff = 0; | 1378 | s16 diff, tdiff = 0; |
1379 | int ret; | 1379 | int ret = NF_ACCEPT; |
1380 | typeof(nf_nat_sip_seq_adjust_hook) nf_nat_sip_seq_adjust; | 1380 | typeof(nf_nat_sip_seq_adjust_hook) nf_nat_sip_seq_adjust; |
1381 | 1381 | ||
1382 | if (ctinfo != IP_CT_ESTABLISHED && | 1382 | if (ctinfo != IP_CT_ESTABLISHED && |
diff --git a/net/netfilter/nf_tproxy_core.c b/net/netfilter/nf_tproxy_core.c index 5490fc37c92..daab8c4a903 100644 --- a/net/netfilter/nf_tproxy_core.c +++ b/net/netfilter/nf_tproxy_core.c | |||
@@ -70,7 +70,11 @@ nf_tproxy_destructor(struct sk_buff *skb) | |||
70 | int | 70 | int |
71 | nf_tproxy_assign_sock(struct sk_buff *skb, struct sock *sk) | 71 | nf_tproxy_assign_sock(struct sk_buff *skb, struct sock *sk) |
72 | { | 72 | { |
73 | if (inet_sk(sk)->transparent) { | 73 | bool transparent = (sk->sk_state == TCP_TIME_WAIT) ? |
74 | inet_twsk(sk)->tw_transparent : | ||
75 | inet_sk(sk)->transparent; | ||
76 | |||
77 | if (transparent) { | ||
74 | skb_orphan(skb); | 78 | skb_orphan(skb); |
75 | skb->sk = sk; | 79 | skb->sk = sk; |
76 | skb->destructor = nf_tproxy_destructor; | 80 | skb->destructor = nf_tproxy_destructor; |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 8648a9922aa..cd96ed3ccee 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -1406,7 +1406,7 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock, | |||
1406 | struct netlink_sock *nlk = nlk_sk(sk); | 1406 | struct netlink_sock *nlk = nlk_sk(sk); |
1407 | int noblock = flags&MSG_DONTWAIT; | 1407 | int noblock = flags&MSG_DONTWAIT; |
1408 | size_t copied; | 1408 | size_t copied; |
1409 | struct sk_buff *skb, *frag __maybe_unused = NULL; | 1409 | struct sk_buff *skb, *data_skb; |
1410 | int err; | 1410 | int err; |
1411 | 1411 | ||
1412 | if (flags&MSG_OOB) | 1412 | if (flags&MSG_OOB) |
@@ -1418,45 +1418,35 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock, | |||
1418 | if (skb == NULL) | 1418 | if (skb == NULL) |
1419 | goto out; | 1419 | goto out; |
1420 | 1420 | ||
1421 | data_skb = skb; | ||
1422 | |||
1421 | #ifdef CONFIG_COMPAT_NETLINK_MESSAGES | 1423 | #ifdef CONFIG_COMPAT_NETLINK_MESSAGES |
1422 | if (unlikely(skb_shinfo(skb)->frag_list)) { | 1424 | if (unlikely(skb_shinfo(skb)->frag_list)) { |
1423 | bool need_compat = !!(flags & MSG_CMSG_COMPAT); | ||
1424 | |||
1425 | /* | 1425 | /* |
1426 | * If this skb has a frag_list, then here that means that | 1426 | * If this skb has a frag_list, then here that means that we |
1427 | * we will have to use the frag_list skb for compat tasks | 1427 | * will have to use the frag_list skb's data for compat tasks |
1428 | * and the regular skb for non-compat tasks. | 1428 | * and the regular skb's data for normal (non-compat) tasks. |
1429 | * | 1429 | * |
1430 | * The skb might (and likely will) be cloned, so we can't | 1430 | * If we need to send the compat skb, assign it to the |
1431 | * just reset frag_list and go on with things -- we need to | 1431 | * 'data_skb' variable so that it will be used below for data |
1432 | * keep that. For the compat case that's easy -- simply get | 1432 | * copying. We keep 'skb' for everything else, including |
1433 | * a reference to the compat skb and free the regular one | 1433 | * freeing both later. |
1434 | * including the frag. For the non-compat case, we need to | ||
1435 | * avoid sending the frag to the user -- so assign NULL but | ||
1436 | * restore it below before freeing the skb. | ||
1437 | */ | 1434 | */ |
1438 | if (need_compat) { | 1435 | if (flags & MSG_CMSG_COMPAT) |
1439 | struct sk_buff *compskb = skb_shinfo(skb)->frag_list; | 1436 | data_skb = skb_shinfo(skb)->frag_list; |
1440 | skb_get(compskb); | ||
1441 | kfree_skb(skb); | ||
1442 | skb = compskb; | ||
1443 | } else { | ||
1444 | frag = skb_shinfo(skb)->frag_list; | ||
1445 | skb_shinfo(skb)->frag_list = NULL; | ||
1446 | } | ||
1447 | } | 1437 | } |
1448 | #endif | 1438 | #endif |
1449 | 1439 | ||
1450 | msg->msg_namelen = 0; | 1440 | msg->msg_namelen = 0; |
1451 | 1441 | ||
1452 | copied = skb->len; | 1442 | copied = data_skb->len; |
1453 | if (len < copied) { | 1443 | if (len < copied) { |
1454 | msg->msg_flags |= MSG_TRUNC; | 1444 | msg->msg_flags |= MSG_TRUNC; |
1455 | copied = len; | 1445 | copied = len; |
1456 | } | 1446 | } |
1457 | 1447 | ||
1458 | skb_reset_transport_header(skb); | 1448 | skb_reset_transport_header(data_skb); |
1459 | err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); | 1449 | err = skb_copy_datagram_iovec(data_skb, 0, msg->msg_iov, copied); |
1460 | 1450 | ||
1461 | if (msg->msg_name) { | 1451 | if (msg->msg_name) { |
1462 | struct sockaddr_nl *addr = (struct sockaddr_nl *)msg->msg_name; | 1452 | struct sockaddr_nl *addr = (struct sockaddr_nl *)msg->msg_name; |
@@ -1476,11 +1466,7 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock, | |||
1476 | } | 1466 | } |
1477 | siocb->scm->creds = *NETLINK_CREDS(skb); | 1467 | siocb->scm->creds = *NETLINK_CREDS(skb); |
1478 | if (flags & MSG_TRUNC) | 1468 | if (flags & MSG_TRUNC) |
1479 | copied = skb->len; | 1469 | copied = data_skb->len; |
1480 | |||
1481 | #ifdef CONFIG_COMPAT_NETLINK_MESSAGES | ||
1482 | skb_shinfo(skb)->frag_list = frag; | ||
1483 | #endif | ||
1484 | 1470 | ||
1485 | skb_free_datagram(sk, skb); | 1471 | skb_free_datagram(sk, skb); |
1486 | 1472 | ||
@@ -2116,6 +2102,26 @@ static void __net_exit netlink_net_exit(struct net *net) | |||
2116 | #endif | 2102 | #endif |
2117 | } | 2103 | } |
2118 | 2104 | ||
2105 | static void __init netlink_add_usersock_entry(void) | ||
2106 | { | ||
2107 | unsigned long *listeners; | ||
2108 | int groups = 32; | ||
2109 | |||
2110 | listeners = kzalloc(NLGRPSZ(groups) + sizeof(struct listeners_rcu_head), | ||
2111 | GFP_KERNEL); | ||
2112 | if (!listeners) | ||
2113 | panic("netlink_add_usersock_entry: Cannot allocate listneres\n"); | ||
2114 | |||
2115 | netlink_table_grab(); | ||
2116 | |||
2117 | nl_table[NETLINK_USERSOCK].groups = groups; | ||
2118 | nl_table[NETLINK_USERSOCK].listeners = listeners; | ||
2119 | nl_table[NETLINK_USERSOCK].module = THIS_MODULE; | ||
2120 | nl_table[NETLINK_USERSOCK].registered = 1; | ||
2121 | |||
2122 | netlink_table_ungrab(); | ||
2123 | } | ||
2124 | |||
2119 | static struct pernet_operations __net_initdata netlink_net_ops = { | 2125 | static struct pernet_operations __net_initdata netlink_net_ops = { |
2120 | .init = netlink_net_init, | 2126 | .init = netlink_net_init, |
2121 | .exit = netlink_net_exit, | 2127 | .exit = netlink_net_exit, |
@@ -2164,6 +2170,8 @@ static int __init netlink_proto_init(void) | |||
2164 | hash->rehash_time = jiffies; | 2170 | hash->rehash_time = jiffies; |
2165 | } | 2171 | } |
2166 | 2172 | ||
2173 | netlink_add_usersock_entry(); | ||
2174 | |||
2167 | sock_register(&netlink_family_ops); | 2175 | sock_register(&netlink_family_ops); |
2168 | register_pernet_subsys(&netlink_net_ops); | 2176 | register_pernet_subsys(&netlink_net_ops); |
2169 | /* The netlink device handler may be needed early. */ | 2177 | /* The netlink device handler may be needed early. */ |
diff --git a/net/phonet/pep.c b/net/phonet/pep.c index b2a3ae6cad7..15003021f4f 100644 --- a/net/phonet/pep.c +++ b/net/phonet/pep.c | |||
@@ -225,12 +225,13 @@ static void pipe_grant_credits(struct sock *sk) | |||
225 | static int pipe_rcv_status(struct sock *sk, struct sk_buff *skb) | 225 | static int pipe_rcv_status(struct sock *sk, struct sk_buff *skb) |
226 | { | 226 | { |
227 | struct pep_sock *pn = pep_sk(sk); | 227 | struct pep_sock *pn = pep_sk(sk); |
228 | struct pnpipehdr *hdr = pnp_hdr(skb); | 228 | struct pnpipehdr *hdr; |
229 | int wake = 0; | 229 | int wake = 0; |
230 | 230 | ||
231 | if (!pskb_may_pull(skb, sizeof(*hdr) + 4)) | 231 | if (!pskb_may_pull(skb, sizeof(*hdr) + 4)) |
232 | return -EINVAL; | 232 | return -EINVAL; |
233 | 233 | ||
234 | hdr = pnp_hdr(skb); | ||
234 | if (hdr->data[0] != PN_PEP_TYPE_COMMON) { | 235 | if (hdr->data[0] != PN_PEP_TYPE_COMMON) { |
235 | LIMIT_NETDEBUG(KERN_DEBUG"Phonet unknown PEP type: %u\n", | 236 | LIMIT_NETDEBUG(KERN_DEBUG"Phonet unknown PEP type: %u\n", |
236 | (unsigned)hdr->data[0]); | 237 | (unsigned)hdr->data[0]); |
diff --git a/net/rds/recv.c b/net/rds/recv.c index 795a00b7f2c..c93588c2d55 100644 --- a/net/rds/recv.c +++ b/net/rds/recv.c | |||
@@ -297,7 +297,7 @@ static int rds_still_queued(struct rds_sock *rs, struct rds_incoming *inc, | |||
297 | int rds_notify_queue_get(struct rds_sock *rs, struct msghdr *msghdr) | 297 | int rds_notify_queue_get(struct rds_sock *rs, struct msghdr *msghdr) |
298 | { | 298 | { |
299 | struct rds_notifier *notifier; | 299 | struct rds_notifier *notifier; |
300 | struct rds_rdma_notify cmsg; | 300 | struct rds_rdma_notify cmsg = { 0 }; /* fill holes with zero */ |
301 | unsigned int count = 0, max_messages = ~0U; | 301 | unsigned int count = 0, max_messages = ~0U; |
302 | unsigned long flags; | 302 | unsigned long flags; |
303 | LIST_HEAD(copy); | 303 | LIST_HEAD(copy); |
diff --git a/net/rds/tcp_connect.c b/net/rds/tcp_connect.c index c397524c039..c519939e8da 100644 --- a/net/rds/tcp_connect.c +++ b/net/rds/tcp_connect.c | |||
@@ -43,7 +43,7 @@ void rds_tcp_state_change(struct sock *sk) | |||
43 | struct rds_connection *conn; | 43 | struct rds_connection *conn; |
44 | struct rds_tcp_connection *tc; | 44 | struct rds_tcp_connection *tc; |
45 | 45 | ||
46 | read_lock(&sk->sk_callback_lock); | 46 | read_lock_bh(&sk->sk_callback_lock); |
47 | conn = sk->sk_user_data; | 47 | conn = sk->sk_user_data; |
48 | if (conn == NULL) { | 48 | if (conn == NULL) { |
49 | state_change = sk->sk_state_change; | 49 | state_change = sk->sk_state_change; |
@@ -68,7 +68,7 @@ void rds_tcp_state_change(struct sock *sk) | |||
68 | break; | 68 | break; |
69 | } | 69 | } |
70 | out: | 70 | out: |
71 | read_unlock(&sk->sk_callback_lock); | 71 | read_unlock_bh(&sk->sk_callback_lock); |
72 | state_change(sk); | 72 | state_change(sk); |
73 | } | 73 | } |
74 | 74 | ||
diff --git a/net/rds/tcp_listen.c b/net/rds/tcp_listen.c index 975183fe695..27844f231d1 100644 --- a/net/rds/tcp_listen.c +++ b/net/rds/tcp_listen.c | |||
@@ -114,7 +114,7 @@ void rds_tcp_listen_data_ready(struct sock *sk, int bytes) | |||
114 | 114 | ||
115 | rdsdebug("listen data ready sk %p\n", sk); | 115 | rdsdebug("listen data ready sk %p\n", sk); |
116 | 116 | ||
117 | read_lock(&sk->sk_callback_lock); | 117 | read_lock_bh(&sk->sk_callback_lock); |
118 | ready = sk->sk_user_data; | 118 | ready = sk->sk_user_data; |
119 | if (ready == NULL) { /* check for teardown race */ | 119 | if (ready == NULL) { /* check for teardown race */ |
120 | ready = sk->sk_data_ready; | 120 | ready = sk->sk_data_ready; |
@@ -131,7 +131,7 @@ void rds_tcp_listen_data_ready(struct sock *sk, int bytes) | |||
131 | queue_work(rds_wq, &rds_tcp_listen_work); | 131 | queue_work(rds_wq, &rds_tcp_listen_work); |
132 | 132 | ||
133 | out: | 133 | out: |
134 | read_unlock(&sk->sk_callback_lock); | 134 | read_unlock_bh(&sk->sk_callback_lock); |
135 | ready(sk, bytes); | 135 | ready(sk, bytes); |
136 | } | 136 | } |
137 | 137 | ||
diff --git a/net/rds/tcp_recv.c b/net/rds/tcp_recv.c index 1aba6878fa5..e4379740410 100644 --- a/net/rds/tcp_recv.c +++ b/net/rds/tcp_recv.c | |||
@@ -324,7 +324,7 @@ void rds_tcp_data_ready(struct sock *sk, int bytes) | |||
324 | 324 | ||
325 | rdsdebug("data ready sk %p bytes %d\n", sk, bytes); | 325 | rdsdebug("data ready sk %p bytes %d\n", sk, bytes); |
326 | 326 | ||
327 | read_lock(&sk->sk_callback_lock); | 327 | read_lock_bh(&sk->sk_callback_lock); |
328 | conn = sk->sk_user_data; | 328 | conn = sk->sk_user_data; |
329 | if (conn == NULL) { /* check for teardown race */ | 329 | if (conn == NULL) { /* check for teardown race */ |
330 | ready = sk->sk_data_ready; | 330 | ready = sk->sk_data_ready; |
@@ -338,7 +338,7 @@ void rds_tcp_data_ready(struct sock *sk, int bytes) | |||
338 | if (rds_tcp_read_sock(conn, GFP_ATOMIC, KM_SOFTIRQ0) == -ENOMEM) | 338 | if (rds_tcp_read_sock(conn, GFP_ATOMIC, KM_SOFTIRQ0) == -ENOMEM) |
339 | queue_delayed_work(rds_wq, &conn->c_recv_w, 0); | 339 | queue_delayed_work(rds_wq, &conn->c_recv_w, 0); |
340 | out: | 340 | out: |
341 | read_unlock(&sk->sk_callback_lock); | 341 | read_unlock_bh(&sk->sk_callback_lock); |
342 | ready(sk, bytes); | 342 | ready(sk, bytes); |
343 | } | 343 | } |
344 | 344 | ||
diff --git a/net/rds/tcp_send.c b/net/rds/tcp_send.c index a28b895ff0d..2f012a07d94 100644 --- a/net/rds/tcp_send.c +++ b/net/rds/tcp_send.c | |||
@@ -224,7 +224,7 @@ void rds_tcp_write_space(struct sock *sk) | |||
224 | struct rds_connection *conn; | 224 | struct rds_connection *conn; |
225 | struct rds_tcp_connection *tc; | 225 | struct rds_tcp_connection *tc; |
226 | 226 | ||
227 | read_lock(&sk->sk_callback_lock); | 227 | read_lock_bh(&sk->sk_callback_lock); |
228 | conn = sk->sk_user_data; | 228 | conn = sk->sk_user_data; |
229 | if (conn == NULL) { | 229 | if (conn == NULL) { |
230 | write_space = sk->sk_write_space; | 230 | write_space = sk->sk_write_space; |
@@ -244,7 +244,7 @@ void rds_tcp_write_space(struct sock *sk) | |||
244 | queue_delayed_work(rds_wq, &conn->c_send_w, 0); | 244 | queue_delayed_work(rds_wq, &conn->c_send_w, 0); |
245 | 245 | ||
246 | out: | 246 | out: |
247 | read_unlock(&sk->sk_callback_lock); | 247 | read_unlock_bh(&sk->sk_callback_lock); |
248 | 248 | ||
249 | /* | 249 | /* |
250 | * write_space is only called when data leaves tcp's send queue if | 250 | * write_space is only called when data leaves tcp's send queue if |
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index 8e45e76a95f..d952e7eac18 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c | |||
@@ -679,7 +679,7 @@ static int rose_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
679 | if (addr_len == sizeof(struct sockaddr_rose) && addr->srose_ndigis > 1) | 679 | if (addr_len == sizeof(struct sockaddr_rose) && addr->srose_ndigis > 1) |
680 | return -EINVAL; | 680 | return -EINVAL; |
681 | 681 | ||
682 | if (addr->srose_ndigis > ROSE_MAX_DIGIS) | 682 | if ((unsigned int) addr->srose_ndigis > ROSE_MAX_DIGIS) |
683 | return -EINVAL; | 683 | return -EINVAL; |
684 | 684 | ||
685 | if ((dev = rose_dev_get(&addr->srose_addr)) == NULL) { | 685 | if ((dev = rose_dev_get(&addr->srose_addr)) == NULL) { |
@@ -739,7 +739,7 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le | |||
739 | if (addr_len == sizeof(struct sockaddr_rose) && addr->srose_ndigis > 1) | 739 | if (addr_len == sizeof(struct sockaddr_rose) && addr->srose_ndigis > 1) |
740 | return -EINVAL; | 740 | return -EINVAL; |
741 | 741 | ||
742 | if (addr->srose_ndigis > ROSE_MAX_DIGIS) | 742 | if ((unsigned int) addr->srose_ndigis > ROSE_MAX_DIGIS) |
743 | return -EINVAL; | 743 | return -EINVAL; |
744 | 744 | ||
745 | /* Source + Destination digis should not exceed ROSE_MAX_DIGIS */ | 745 | /* Source + Destination digis should not exceed ROSE_MAX_DIGIS */ |
diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 537a48732e9..7ebf7439b47 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c | |||
@@ -350,22 +350,19 @@ tcf_act_police_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) | |||
350 | { | 350 | { |
351 | unsigned char *b = skb_tail_pointer(skb); | 351 | unsigned char *b = skb_tail_pointer(skb); |
352 | struct tcf_police *police = a->priv; | 352 | struct tcf_police *police = a->priv; |
353 | struct tc_police opt; | 353 | struct tc_police opt = { |
354 | 354 | .index = police->tcf_index, | |
355 | opt.index = police->tcf_index; | 355 | .action = police->tcf_action, |
356 | opt.action = police->tcf_action; | 356 | .mtu = police->tcfp_mtu, |
357 | opt.mtu = police->tcfp_mtu; | 357 | .burst = police->tcfp_burst, |
358 | opt.burst = police->tcfp_burst; | 358 | .refcnt = police->tcf_refcnt - ref, |
359 | opt.refcnt = police->tcf_refcnt - ref; | 359 | .bindcnt = police->tcf_bindcnt - bind, |
360 | opt.bindcnt = police->tcf_bindcnt - bind; | 360 | }; |
361 | |||
361 | if (police->tcfp_R_tab) | 362 | if (police->tcfp_R_tab) |
362 | opt.rate = police->tcfp_R_tab->rate; | 363 | opt.rate = police->tcfp_R_tab->rate; |
363 | else | ||
364 | memset(&opt.rate, 0, sizeof(opt.rate)); | ||
365 | if (police->tcfp_P_tab) | 364 | if (police->tcfp_P_tab) |
366 | opt.peakrate = police->tcfp_P_tab->rate; | 365 | opt.peakrate = police->tcfp_P_tab->rate; |
367 | else | ||
368 | memset(&opt.peakrate, 0, sizeof(opt.peakrate)); | ||
369 | NLA_PUT(skb, TCA_POLICE_TBF, sizeof(opt), &opt); | 366 | NLA_PUT(skb, TCA_POLICE_TBF, sizeof(opt), &opt); |
370 | if (police->tcfp_result) | 367 | if (police->tcfp_result) |
371 | NLA_PUT_U32(skb, TCA_POLICE_RESULT, police->tcfp_result); | 368 | NLA_PUT_U32(skb, TCA_POLICE_RESULT, police->tcfp_result); |
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index 7416a5c73b2..b0c2a82178a 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c | |||
@@ -137,7 +137,7 @@ next_knode: | |||
137 | int toff = off + key->off + (off2 & key->offmask); | 137 | int toff = off + key->off + (off2 & key->offmask); |
138 | __be32 *data, _data; | 138 | __be32 *data, _data; |
139 | 139 | ||
140 | if (skb_headroom(skb) + toff < 0) | 140 | if (skb_headroom(skb) + toff > INT_MAX) |
141 | goto out; | 141 | goto out; |
142 | 142 | ||
143 | data = skb_header_pointer(skb, toff, 4, &_data); | 143 | data = skb_header_pointer(skb, toff, 4, &_data); |
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c index 34066278952..6318e1136b8 100644 --- a/net/sched/sch_atm.c +++ b/net/sched/sch_atm.c | |||
@@ -255,10 +255,6 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent, | |||
255 | error = -EINVAL; | 255 | error = -EINVAL; |
256 | goto err_out; | 256 | goto err_out; |
257 | } | 257 | } |
258 | if (!list_empty(&flow->list)) { | ||
259 | error = -EEXIST; | ||
260 | goto err_out; | ||
261 | } | ||
262 | } else { | 258 | } else { |
263 | int i; | 259 | int i; |
264 | unsigned long cl; | 260 | unsigned long cl; |
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c index abd904be428..47496098d35 100644 --- a/net/sched/sch_hfsc.c +++ b/net/sched/sch_hfsc.c | |||
@@ -761,8 +761,8 @@ init_vf(struct hfsc_class *cl, unsigned int len) | |||
761 | if (f != cl->cl_f) { | 761 | if (f != cl->cl_f) { |
762 | cl->cl_f = f; | 762 | cl->cl_f = f; |
763 | cftree_update(cl); | 763 | cftree_update(cl); |
764 | update_cfmin(cl->cl_parent); | ||
765 | } | 764 | } |
765 | update_cfmin(cl->cl_parent); | ||
766 | } | 766 | } |
767 | } | 767 | } |
768 | 768 | ||
diff --git a/net/sctp/auth.c b/net/sctp/auth.c index 86366390038..ddbbf7c81fa 100644 --- a/net/sctp/auth.c +++ b/net/sctp/auth.c | |||
@@ -543,16 +543,20 @@ struct sctp_hmac *sctp_auth_asoc_get_hmac(const struct sctp_association *asoc) | |||
543 | id = ntohs(hmacs->hmac_ids[i]); | 543 | id = ntohs(hmacs->hmac_ids[i]); |
544 | 544 | ||
545 | /* Check the id is in the supported range */ | 545 | /* Check the id is in the supported range */ |
546 | if (id > SCTP_AUTH_HMAC_ID_MAX) | 546 | if (id > SCTP_AUTH_HMAC_ID_MAX) { |
547 | id = 0; | ||
547 | continue; | 548 | continue; |
549 | } | ||
548 | 550 | ||
549 | /* See is we support the id. Supported IDs have name and | 551 | /* See is we support the id. Supported IDs have name and |
550 | * length fields set, so that we can allocated and use | 552 | * length fields set, so that we can allocated and use |
551 | * them. We can safely just check for name, for without the | 553 | * them. We can safely just check for name, for without the |
552 | * name, we can't allocate the TFM. | 554 | * name, we can't allocate the TFM. |
553 | */ | 555 | */ |
554 | if (!sctp_hmac_list[id].hmac_name) | 556 | if (!sctp_hmac_list[id].hmac_name) { |
557 | id = 0; | ||
555 | continue; | 558 | continue; |
559 | } | ||
556 | 560 | ||
557 | break; | 561 | break; |
558 | } | 562 | } |
diff --git a/net/sctp/output.c b/net/sctp/output.c index a646681f5ac..bcc4590ccaf 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c | |||
@@ -92,7 +92,6 @@ struct sctp_packet *sctp_packet_config(struct sctp_packet *packet, | |||
92 | SCTP_DEBUG_PRINTK("%s: packet:%p vtag:0x%x\n", __func__, | 92 | SCTP_DEBUG_PRINTK("%s: packet:%p vtag:0x%x\n", __func__, |
93 | packet, vtag); | 93 | packet, vtag); |
94 | 94 | ||
95 | sctp_packet_reset(packet); | ||
96 | packet->vtag = vtag; | 95 | packet->vtag = vtag; |
97 | 96 | ||
98 | if (ecn_capable && sctp_packet_empty(packet)) { | 97 | if (ecn_capable && sctp_packet_empty(packet)) { |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 24b2cd55563..d344dc481cc 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -1232,6 +1232,18 @@ out: | |||
1232 | return 0; | 1232 | return 0; |
1233 | } | 1233 | } |
1234 | 1234 | ||
1235 | static bool list_has_sctp_addr(const struct list_head *list, | ||
1236 | union sctp_addr *ipaddr) | ||
1237 | { | ||
1238 | struct sctp_transport *addr; | ||
1239 | |||
1240 | list_for_each_entry(addr, list, transports) { | ||
1241 | if (sctp_cmp_addr_exact(ipaddr, &addr->ipaddr)) | ||
1242 | return true; | ||
1243 | } | ||
1244 | |||
1245 | return false; | ||
1246 | } | ||
1235 | /* A restart is occurring, check to make sure no new addresses | 1247 | /* A restart is occurring, check to make sure no new addresses |
1236 | * are being added as we may be under a takeover attack. | 1248 | * are being added as we may be under a takeover attack. |
1237 | */ | 1249 | */ |
@@ -1240,10 +1252,10 @@ static int sctp_sf_check_restart_addrs(const struct sctp_association *new_asoc, | |||
1240 | struct sctp_chunk *init, | 1252 | struct sctp_chunk *init, |
1241 | sctp_cmd_seq_t *commands) | 1253 | sctp_cmd_seq_t *commands) |
1242 | { | 1254 | { |
1243 | struct sctp_transport *new_addr, *addr; | 1255 | struct sctp_transport *new_addr; |
1244 | int found; | 1256 | int ret = 1; |
1245 | 1257 | ||
1246 | /* Implementor's Guide - Sectin 5.2.2 | 1258 | /* Implementor's Guide - Section 5.2.2 |
1247 | * ... | 1259 | * ... |
1248 | * Before responding the endpoint MUST check to see if the | 1260 | * Before responding the endpoint MUST check to see if the |
1249 | * unexpected INIT adds new addresses to the association. If new | 1261 | * unexpected INIT adds new addresses to the association. If new |
@@ -1254,31 +1266,19 @@ static int sctp_sf_check_restart_addrs(const struct sctp_association *new_asoc, | |||
1254 | /* Search through all current addresses and make sure | 1266 | /* Search through all current addresses and make sure |
1255 | * we aren't adding any new ones. | 1267 | * we aren't adding any new ones. |
1256 | */ | 1268 | */ |
1257 | new_addr = NULL; | ||
1258 | found = 0; | ||
1259 | |||
1260 | list_for_each_entry(new_addr, &new_asoc->peer.transport_addr_list, | 1269 | list_for_each_entry(new_addr, &new_asoc->peer.transport_addr_list, |
1261 | transports) { | 1270 | transports) { |
1262 | found = 0; | 1271 | if (!list_has_sctp_addr(&asoc->peer.transport_addr_list, |
1263 | list_for_each_entry(addr, &asoc->peer.transport_addr_list, | 1272 | &new_addr->ipaddr)) { |
1264 | transports) { | 1273 | sctp_sf_send_restart_abort(&new_addr->ipaddr, init, |
1265 | if (sctp_cmp_addr_exact(&new_addr->ipaddr, | 1274 | commands); |
1266 | &addr->ipaddr)) { | 1275 | ret = 0; |
1267 | found = 1; | ||
1268 | break; | ||
1269 | } | ||
1270 | } | ||
1271 | if (!found) | ||
1272 | break; | 1276 | break; |
1273 | } | 1277 | } |
1274 | |||
1275 | /* If a new address was added, ABORT the sender. */ | ||
1276 | if (!found && new_addr) { | ||
1277 | sctp_sf_send_restart_abort(&new_addr->ipaddr, init, commands); | ||
1278 | } | 1278 | } |
1279 | 1279 | ||
1280 | /* Return success if all addresses were found. */ | 1280 | /* Return success if all addresses were found. */ |
1281 | return found; | 1281 | return ret; |
1282 | } | 1282 | } |
1283 | 1283 | ||
1284 | /* Populate the verification/tie tags based on overlapping INIT | 1284 | /* Populate the verification/tie tags based on overlapping INIT |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index ca44917872d..fbb70770ad0 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -916,6 +916,11 @@ SCTP_STATIC int sctp_setsockopt_bindx(struct sock* sk, | |||
916 | /* Walk through the addrs buffer and count the number of addresses. */ | 916 | /* Walk through the addrs buffer and count the number of addresses. */ |
917 | addr_buf = kaddrs; | 917 | addr_buf = kaddrs; |
918 | while (walk_size < addrs_size) { | 918 | while (walk_size < addrs_size) { |
919 | if (walk_size + sizeof(sa_family_t) > addrs_size) { | ||
920 | kfree(kaddrs); | ||
921 | return -EINVAL; | ||
922 | } | ||
923 | |||
919 | sa_addr = (struct sockaddr *)addr_buf; | 924 | sa_addr = (struct sockaddr *)addr_buf; |
920 | af = sctp_get_af_specific(sa_addr->sa_family); | 925 | af = sctp_get_af_specific(sa_addr->sa_family); |
921 | 926 | ||
@@ -1002,9 +1007,13 @@ static int __sctp_connect(struct sock* sk, | |||
1002 | /* Walk through the addrs buffer and count the number of addresses. */ | 1007 | /* Walk through the addrs buffer and count the number of addresses. */ |
1003 | addr_buf = kaddrs; | 1008 | addr_buf = kaddrs; |
1004 | while (walk_size < addrs_size) { | 1009 | while (walk_size < addrs_size) { |
1010 | if (walk_size + sizeof(sa_family_t) > addrs_size) { | ||
1011 | err = -EINVAL; | ||
1012 | goto out_free; | ||
1013 | } | ||
1014 | |||
1005 | sa_addr = (union sctp_addr *)addr_buf; | 1015 | sa_addr = (union sctp_addr *)addr_buf; |
1006 | af = sctp_get_af_specific(sa_addr->sa.sa_family); | 1016 | af = sctp_get_af_specific(sa_addr->sa.sa_family); |
1007 | port = ntohs(sa_addr->v4.sin_port); | ||
1008 | 1017 | ||
1009 | /* If the address family is not supported or if this address | 1018 | /* If the address family is not supported or if this address |
1010 | * causes the address buffer to overflow return EINVAL. | 1019 | * causes the address buffer to overflow return EINVAL. |
@@ -1014,6 +1023,8 @@ static int __sctp_connect(struct sock* sk, | |||
1014 | goto out_free; | 1023 | goto out_free; |
1015 | } | 1024 | } |
1016 | 1025 | ||
1026 | port = ntohs(sa_addr->v4.sin_port); | ||
1027 | |||
1017 | /* Save current address so we can work with it */ | 1028 | /* Save current address so we can work with it */ |
1018 | memcpy(&to, sa_addr, af->sockaddr_len); | 1029 | memcpy(&to, sa_addr, af->sockaddr_len); |
1019 | 1030 | ||
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index 36cb66022a2..e9eaaf7d43c 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c | |||
@@ -38,7 +38,7 @@ static const struct rpc_authops *auth_flavors[RPC_AUTH_MAXFLAVOR] = { | |||
38 | static LIST_HEAD(cred_unused); | 38 | static LIST_HEAD(cred_unused); |
39 | static unsigned long number_cred_unused; | 39 | static unsigned long number_cred_unused; |
40 | 40 | ||
41 | #define MAX_HASHTABLE_BITS (10) | 41 | #define MAX_HASHTABLE_BITS (14) |
42 | static int param_set_hashtbl_sz(const char *val, const struct kernel_param *kp) | 42 | static int param_set_hashtbl_sz(const char *val, const struct kernel_param *kp) |
43 | { | 43 | { |
44 | unsigned long num; | 44 | unsigned long num; |
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index dcfc66bab2b..12c48598281 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
@@ -745,17 +745,18 @@ gss_pipe_release(struct inode *inode) | |||
745 | struct rpc_inode *rpci = RPC_I(inode); | 745 | struct rpc_inode *rpci = RPC_I(inode); |
746 | struct gss_upcall_msg *gss_msg; | 746 | struct gss_upcall_msg *gss_msg; |
747 | 747 | ||
748 | restart: | ||
748 | spin_lock(&inode->i_lock); | 749 | spin_lock(&inode->i_lock); |
749 | while (!list_empty(&rpci->in_downcall)) { | 750 | list_for_each_entry(gss_msg, &rpci->in_downcall, list) { |
750 | 751 | ||
751 | gss_msg = list_entry(rpci->in_downcall.next, | 752 | if (!list_empty(&gss_msg->msg.list)) |
752 | struct gss_upcall_msg, list); | 753 | continue; |
753 | gss_msg->msg.errno = -EPIPE; | 754 | gss_msg->msg.errno = -EPIPE; |
754 | atomic_inc(&gss_msg->count); | 755 | atomic_inc(&gss_msg->count); |
755 | __gss_unhash_msg(gss_msg); | 756 | __gss_unhash_msg(gss_msg); |
756 | spin_unlock(&inode->i_lock); | 757 | spin_unlock(&inode->i_lock); |
757 | gss_release_msg(gss_msg); | 758 | gss_release_msg(gss_msg); |
758 | spin_lock(&inode->i_lock); | 759 | goto restart; |
759 | } | 760 | } |
760 | spin_unlock(&inode->i_lock); | 761 | spin_unlock(&inode->i_lock); |
761 | 762 | ||
diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index 03264461052..778e5dfc514 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c | |||
@@ -237,6 +237,7 @@ get_key(const void *p, const void *end, | |||
237 | if (!supported_gss_krb5_enctype(alg)) { | 237 | if (!supported_gss_krb5_enctype(alg)) { |
238 | printk(KERN_WARNING "gss_kerberos_mech: unsupported " | 238 | printk(KERN_WARNING "gss_kerberos_mech: unsupported " |
239 | "encryption key algorithm %d\n", alg); | 239 | "encryption key algorithm %d\n", alg); |
240 | p = ERR_PTR(-EINVAL); | ||
240 | goto out_err; | 241 | goto out_err; |
241 | } | 242 | } |
242 | p = simple_get_netobj(p, end, &key); | 243 | p = simple_get_netobj(p, end, &key); |
@@ -282,15 +283,19 @@ gss_import_v1_context(const void *p, const void *end, struct krb5_ctx *ctx) | |||
282 | ctx->enctype = ENCTYPE_DES_CBC_RAW; | 283 | ctx->enctype = ENCTYPE_DES_CBC_RAW; |
283 | 284 | ||
284 | ctx->gk5e = get_gss_krb5_enctype(ctx->enctype); | 285 | ctx->gk5e = get_gss_krb5_enctype(ctx->enctype); |
285 | if (ctx->gk5e == NULL) | 286 | if (ctx->gk5e == NULL) { |
287 | p = ERR_PTR(-EINVAL); | ||
286 | goto out_err; | 288 | goto out_err; |
289 | } | ||
287 | 290 | ||
288 | /* The downcall format was designed before we completely understood | 291 | /* The downcall format was designed before we completely understood |
289 | * the uses of the context fields; so it includes some stuff we | 292 | * the uses of the context fields; so it includes some stuff we |
290 | * just give some minimal sanity-checking, and some we ignore | 293 | * just give some minimal sanity-checking, and some we ignore |
291 | * completely (like the next twenty bytes): */ | 294 | * completely (like the next twenty bytes): */ |
292 | if (unlikely(p + 20 > end || p + 20 < p)) | 295 | if (unlikely(p + 20 > end || p + 20 < p)) { |
296 | p = ERR_PTR(-EFAULT); | ||
293 | goto out_err; | 297 | goto out_err; |
298 | } | ||
294 | p += 20; | 299 | p += 20; |
295 | p = simple_get_bytes(p, end, &tmp, sizeof(tmp)); | 300 | p = simple_get_bytes(p, end, &tmp, sizeof(tmp)); |
296 | if (IS_ERR(p)) | 301 | if (IS_ERR(p)) |
@@ -619,6 +624,7 @@ gss_import_v2_context(const void *p, const void *end, struct krb5_ctx *ctx, | |||
619 | if (ctx->seq_send64 != ctx->seq_send) { | 624 | if (ctx->seq_send64 != ctx->seq_send) { |
620 | dprintk("%s: seq_send64 %lx, seq_send %x overflow?\n", __func__, | 625 | dprintk("%s: seq_send64 %lx, seq_send %x overflow?\n", __func__, |
621 | (long unsigned)ctx->seq_send64, ctx->seq_send); | 626 | (long unsigned)ctx->seq_send64, ctx->seq_send); |
627 | p = ERR_PTR(-EINVAL); | ||
622 | goto out_err; | 628 | goto out_err; |
623 | } | 629 | } |
624 | p = simple_get_bytes(p, end, &ctx->enctype, sizeof(ctx->enctype)); | 630 | p = simple_get_bytes(p, end, &ctx->enctype, sizeof(ctx->enctype)); |
diff --git a/net/sunrpc/auth_gss/gss_spkm3_mech.c b/net/sunrpc/auth_gss/gss_spkm3_mech.c index dc3f1f5ed86..adade3d313f 100644 --- a/net/sunrpc/auth_gss/gss_spkm3_mech.c +++ b/net/sunrpc/auth_gss/gss_spkm3_mech.c | |||
@@ -100,6 +100,7 @@ gss_import_sec_context_spkm3(const void *p, size_t len, | |||
100 | if (version != 1) { | 100 | if (version != 1) { |
101 | dprintk("RPC: unknown spkm3 token format: " | 101 | dprintk("RPC: unknown spkm3 token format: " |
102 | "obsolete nfs-utils?\n"); | 102 | "obsolete nfs-utils?\n"); |
103 | p = ERR_PTR(-EINVAL); | ||
103 | goto out_err_free_ctx; | 104 | goto out_err_free_ctx; |
104 | } | 105 | } |
105 | 106 | ||
@@ -135,8 +136,10 @@ gss_import_sec_context_spkm3(const void *p, size_t len, | |||
135 | if (IS_ERR(p)) | 136 | if (IS_ERR(p)) |
136 | goto out_err_free_intg_alg; | 137 | goto out_err_free_intg_alg; |
137 | 138 | ||
138 | if (p != end) | 139 | if (p != end) { |
140 | p = ERR_PTR(-EFAULT); | ||
139 | goto out_err_free_intg_key; | 141 | goto out_err_free_intg_key; |
142 | } | ||
140 | 143 | ||
141 | ctx_id->internal_ctx_id = ctx; | 144 | ctx_id->internal_ctx_id = ctx; |
142 | 145 | ||
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 2388d83b68f..fa5549079d7 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
@@ -226,7 +226,7 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru | |||
226 | goto out_no_principal; | 226 | goto out_no_principal; |
227 | } | 227 | } |
228 | 228 | ||
229 | kref_init(&clnt->cl_kref); | 229 | atomic_set(&clnt->cl_count, 1); |
230 | 230 | ||
231 | err = rpc_setup_pipedir(clnt, program->pipe_dir_name); | 231 | err = rpc_setup_pipedir(clnt, program->pipe_dir_name); |
232 | if (err < 0) | 232 | if (err < 0) |
@@ -390,14 +390,14 @@ rpc_clone_client(struct rpc_clnt *clnt) | |||
390 | if (new->cl_principal == NULL) | 390 | if (new->cl_principal == NULL) |
391 | goto out_no_principal; | 391 | goto out_no_principal; |
392 | } | 392 | } |
393 | kref_init(&new->cl_kref); | 393 | atomic_set(&new->cl_count, 1); |
394 | err = rpc_setup_pipedir(new, clnt->cl_program->pipe_dir_name); | 394 | err = rpc_setup_pipedir(new, clnt->cl_program->pipe_dir_name); |
395 | if (err != 0) | 395 | if (err != 0) |
396 | goto out_no_path; | 396 | goto out_no_path; |
397 | if (new->cl_auth) | 397 | if (new->cl_auth) |
398 | atomic_inc(&new->cl_auth->au_count); | 398 | atomic_inc(&new->cl_auth->au_count); |
399 | xprt_get(clnt->cl_xprt); | 399 | xprt_get(clnt->cl_xprt); |
400 | kref_get(&clnt->cl_kref); | 400 | atomic_inc(&clnt->cl_count); |
401 | rpc_register_client(new); | 401 | rpc_register_client(new); |
402 | rpciod_up(); | 402 | rpciod_up(); |
403 | return new; | 403 | return new; |
@@ -465,10 +465,8 @@ EXPORT_SYMBOL_GPL(rpc_shutdown_client); | |||
465 | * Free an RPC client | 465 | * Free an RPC client |
466 | */ | 466 | */ |
467 | static void | 467 | static void |
468 | rpc_free_client(struct kref *kref) | 468 | rpc_free_client(struct rpc_clnt *clnt) |
469 | { | 469 | { |
470 | struct rpc_clnt *clnt = container_of(kref, struct rpc_clnt, cl_kref); | ||
471 | |||
472 | dprintk("RPC: destroying %s client for %s\n", | 470 | dprintk("RPC: destroying %s client for %s\n", |
473 | clnt->cl_protname, clnt->cl_server); | 471 | clnt->cl_protname, clnt->cl_server); |
474 | if (!IS_ERR(clnt->cl_path.dentry)) { | 472 | if (!IS_ERR(clnt->cl_path.dentry)) { |
@@ -495,12 +493,10 @@ out_free: | |||
495 | * Free an RPC client | 493 | * Free an RPC client |
496 | */ | 494 | */ |
497 | static void | 495 | static void |
498 | rpc_free_auth(struct kref *kref) | 496 | rpc_free_auth(struct rpc_clnt *clnt) |
499 | { | 497 | { |
500 | struct rpc_clnt *clnt = container_of(kref, struct rpc_clnt, cl_kref); | ||
501 | |||
502 | if (clnt->cl_auth == NULL) { | 498 | if (clnt->cl_auth == NULL) { |
503 | rpc_free_client(kref); | 499 | rpc_free_client(clnt); |
504 | return; | 500 | return; |
505 | } | 501 | } |
506 | 502 | ||
@@ -509,10 +505,11 @@ rpc_free_auth(struct kref *kref) | |||
509 | * release remaining GSS contexts. This mechanism ensures | 505 | * release remaining GSS contexts. This mechanism ensures |
510 | * that it can do so safely. | 506 | * that it can do so safely. |
511 | */ | 507 | */ |
512 | kref_init(kref); | 508 | atomic_inc(&clnt->cl_count); |
513 | rpcauth_release(clnt->cl_auth); | 509 | rpcauth_release(clnt->cl_auth); |
514 | clnt->cl_auth = NULL; | 510 | clnt->cl_auth = NULL; |
515 | kref_put(kref, rpc_free_client); | 511 | if (atomic_dec_and_test(&clnt->cl_count)) |
512 | rpc_free_client(clnt); | ||
516 | } | 513 | } |
517 | 514 | ||
518 | /* | 515 | /* |
@@ -525,7 +522,8 @@ rpc_release_client(struct rpc_clnt *clnt) | |||
525 | 522 | ||
526 | if (list_empty(&clnt->cl_tasks)) | 523 | if (list_empty(&clnt->cl_tasks)) |
527 | wake_up(&destroy_wait); | 524 | wake_up(&destroy_wait); |
528 | kref_put(&clnt->cl_kref, rpc_free_auth); | 525 | if (atomic_dec_and_test(&clnt->cl_count)) |
526 | rpc_free_auth(clnt); | ||
529 | } | 527 | } |
530 | 528 | ||
531 | /** | 529 | /** |
@@ -588,7 +586,7 @@ void rpc_task_set_client(struct rpc_task *task, struct rpc_clnt *clnt) | |||
588 | if (clnt != NULL) { | 586 | if (clnt != NULL) { |
589 | rpc_task_release_client(task); | 587 | rpc_task_release_client(task); |
590 | task->tk_client = clnt; | 588 | task->tk_client = clnt; |
591 | kref_get(&clnt->cl_kref); | 589 | atomic_inc(&clnt->cl_count); |
592 | if (clnt->cl_softrtry) | 590 | if (clnt->cl_softrtry) |
593 | task->tk_flags |= RPC_TASK_SOFT; | 591 | task->tk_flags |= RPC_TASK_SOFT; |
594 | /* Add to the client's list of all tasks */ | 592 | /* Add to the client's list of all tasks */ |
@@ -931,7 +929,7 @@ call_reserveresult(struct rpc_task *task) | |||
931 | task->tk_status = 0; | 929 | task->tk_status = 0; |
932 | if (status >= 0) { | 930 | if (status >= 0) { |
933 | if (task->tk_rqstp) { | 931 | if (task->tk_rqstp) { |
934 | task->tk_action = call_allocate; | 932 | task->tk_action = call_refresh; |
935 | return; | 933 | return; |
936 | } | 934 | } |
937 | 935 | ||
@@ -966,13 +964,54 @@ call_reserveresult(struct rpc_task *task) | |||
966 | } | 964 | } |
967 | 965 | ||
968 | /* | 966 | /* |
969 | * 2. Allocate the buffer. For details, see sched.c:rpc_malloc. | 967 | * 2. Bind and/or refresh the credentials |
968 | */ | ||
969 | static void | ||
970 | call_refresh(struct rpc_task *task) | ||
971 | { | ||
972 | dprint_status(task); | ||
973 | |||
974 | task->tk_action = call_refreshresult; | ||
975 | task->tk_status = 0; | ||
976 | task->tk_client->cl_stats->rpcauthrefresh++; | ||
977 | rpcauth_refreshcred(task); | ||
978 | } | ||
979 | |||
980 | /* | ||
981 | * 2a. Process the results of a credential refresh | ||
982 | */ | ||
983 | static void | ||
984 | call_refreshresult(struct rpc_task *task) | ||
985 | { | ||
986 | int status = task->tk_status; | ||
987 | |||
988 | dprint_status(task); | ||
989 | |||
990 | task->tk_status = 0; | ||
991 | task->tk_action = call_allocate; | ||
992 | if (status >= 0 && rpcauth_uptodatecred(task)) | ||
993 | return; | ||
994 | switch (status) { | ||
995 | case -EACCES: | ||
996 | rpc_exit(task, -EACCES); | ||
997 | return; | ||
998 | case -ENOMEM: | ||
999 | rpc_exit(task, -ENOMEM); | ||
1000 | return; | ||
1001 | case -ETIMEDOUT: | ||
1002 | rpc_delay(task, 3*HZ); | ||
1003 | } | ||
1004 | task->tk_action = call_refresh; | ||
1005 | } | ||
1006 | |||
1007 | /* | ||
1008 | * 2b. Allocate the buffer. For details, see sched.c:rpc_malloc. | ||
970 | * (Note: buffer memory is freed in xprt_release). | 1009 | * (Note: buffer memory is freed in xprt_release). |
971 | */ | 1010 | */ |
972 | static void | 1011 | static void |
973 | call_allocate(struct rpc_task *task) | 1012 | call_allocate(struct rpc_task *task) |
974 | { | 1013 | { |
975 | unsigned int slack = task->tk_client->cl_auth->au_cslack; | 1014 | unsigned int slack = task->tk_rqstp->rq_cred->cr_auth->au_cslack; |
976 | struct rpc_rqst *req = task->tk_rqstp; | 1015 | struct rpc_rqst *req = task->tk_rqstp; |
977 | struct rpc_xprt *xprt = task->tk_xprt; | 1016 | struct rpc_xprt *xprt = task->tk_xprt; |
978 | struct rpc_procinfo *proc = task->tk_msg.rpc_proc; | 1017 | struct rpc_procinfo *proc = task->tk_msg.rpc_proc; |
@@ -980,7 +1019,7 @@ call_allocate(struct rpc_task *task) | |||
980 | dprint_status(task); | 1019 | dprint_status(task); |
981 | 1020 | ||
982 | task->tk_status = 0; | 1021 | task->tk_status = 0; |
983 | task->tk_action = call_refresh; | 1022 | task->tk_action = call_bind; |
984 | 1023 | ||
985 | if (req->rq_buffer) | 1024 | if (req->rq_buffer) |
986 | return; | 1025 | return; |
@@ -1017,47 +1056,6 @@ call_allocate(struct rpc_task *task) | |||
1017 | rpc_exit(task, -ERESTARTSYS); | 1056 | rpc_exit(task, -ERESTARTSYS); |
1018 | } | 1057 | } |
1019 | 1058 | ||
1020 | /* | ||
1021 | * 2a. Bind and/or refresh the credentials | ||
1022 | */ | ||
1023 | static void | ||
1024 | call_refresh(struct rpc_task *task) | ||
1025 | { | ||
1026 | dprint_status(task); | ||
1027 | |||
1028 | task->tk_action = call_refreshresult; | ||
1029 | task->tk_status = 0; | ||
1030 | task->tk_client->cl_stats->rpcauthrefresh++; | ||
1031 | rpcauth_refreshcred(task); | ||
1032 | } | ||
1033 | |||
1034 | /* | ||
1035 | * 2b. Process the results of a credential refresh | ||
1036 | */ | ||
1037 | static void | ||
1038 | call_refreshresult(struct rpc_task *task) | ||
1039 | { | ||
1040 | int status = task->tk_status; | ||
1041 | |||
1042 | dprint_status(task); | ||
1043 | |||
1044 | task->tk_status = 0; | ||
1045 | task->tk_action = call_bind; | ||
1046 | if (status >= 0 && rpcauth_uptodatecred(task)) | ||
1047 | return; | ||
1048 | switch (status) { | ||
1049 | case -EACCES: | ||
1050 | rpc_exit(task, -EACCES); | ||
1051 | return; | ||
1052 | case -ENOMEM: | ||
1053 | rpc_exit(task, -ENOMEM); | ||
1054 | return; | ||
1055 | case -ETIMEDOUT: | ||
1056 | rpc_delay(task, 3*HZ); | ||
1057 | } | ||
1058 | task->tk_action = call_refresh; | ||
1059 | } | ||
1060 | |||
1061 | static inline int | 1059 | static inline int |
1062 | rpc_task_need_encode(struct rpc_task *task) | 1060 | rpc_task_need_encode(struct rpc_task *task) |
1063 | { | 1061 | { |
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 95ccbcf45d3..8c8eef2b8f2 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
@@ -48,7 +48,7 @@ static void rpc_purge_list(struct rpc_inode *rpci, struct list_head *head, | |||
48 | return; | 48 | return; |
49 | do { | 49 | do { |
50 | msg = list_entry(head->next, struct rpc_pipe_msg, list); | 50 | msg = list_entry(head->next, struct rpc_pipe_msg, list); |
51 | list_del(&msg->list); | 51 | list_del_init(&msg->list); |
52 | msg->errno = err; | 52 | msg->errno = err; |
53 | destroy_msg(msg); | 53 | destroy_msg(msg); |
54 | } while (!list_empty(head)); | 54 | } while (!list_empty(head)); |
@@ -208,7 +208,7 @@ rpc_pipe_release(struct inode *inode, struct file *filp) | |||
208 | if (msg != NULL) { | 208 | if (msg != NULL) { |
209 | spin_lock(&inode->i_lock); | 209 | spin_lock(&inode->i_lock); |
210 | msg->errno = -EAGAIN; | 210 | msg->errno = -EAGAIN; |
211 | list_del(&msg->list); | 211 | list_del_init(&msg->list); |
212 | spin_unlock(&inode->i_lock); | 212 | spin_unlock(&inode->i_lock); |
213 | rpci->ops->destroy_msg(msg); | 213 | rpci->ops->destroy_msg(msg); |
214 | } | 214 | } |
@@ -268,7 +268,7 @@ rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset) | |||
268 | if (res < 0 || msg->len == msg->copied) { | 268 | if (res < 0 || msg->len == msg->copied) { |
269 | filp->private_data = NULL; | 269 | filp->private_data = NULL; |
270 | spin_lock(&inode->i_lock); | 270 | spin_lock(&inode->i_lock); |
271 | list_del(&msg->list); | 271 | list_del_init(&msg->list); |
272 | spin_unlock(&inode->i_lock); | 272 | spin_unlock(&inode->i_lock); |
273 | rpci->ops->destroy_msg(msg); | 273 | rpci->ops->destroy_msg(msg); |
274 | } | 274 | } |
@@ -371,21 +371,23 @@ rpc_show_info(struct seq_file *m, void *v) | |||
371 | static int | 371 | static int |
372 | rpc_info_open(struct inode *inode, struct file *file) | 372 | rpc_info_open(struct inode *inode, struct file *file) |
373 | { | 373 | { |
374 | struct rpc_clnt *clnt; | 374 | struct rpc_clnt *clnt = NULL; |
375 | int ret = single_open(file, rpc_show_info, NULL); | 375 | int ret = single_open(file, rpc_show_info, NULL); |
376 | 376 | ||
377 | if (!ret) { | 377 | if (!ret) { |
378 | struct seq_file *m = file->private_data; | 378 | struct seq_file *m = file->private_data; |
379 | mutex_lock(&inode->i_mutex); | 379 | |
380 | clnt = RPC_I(inode)->private; | 380 | spin_lock(&file->f_path.dentry->d_lock); |
381 | if (clnt) { | 381 | if (!d_unhashed(file->f_path.dentry)) |
382 | kref_get(&clnt->cl_kref); | 382 | clnt = RPC_I(inode)->private; |
383 | if (clnt != NULL && atomic_inc_not_zero(&clnt->cl_count)) { | ||
384 | spin_unlock(&file->f_path.dentry->d_lock); | ||
383 | m->private = clnt; | 385 | m->private = clnt; |
384 | } else { | 386 | } else { |
387 | spin_unlock(&file->f_path.dentry->d_lock); | ||
385 | single_release(inode, file); | 388 | single_release(inode, file); |
386 | ret = -EINVAL; | 389 | ret = -EINVAL; |
387 | } | 390 | } |
388 | mutex_unlock(&inode->i_mutex); | ||
389 | } | 391 | } |
390 | return ret; | 392 | return ret; |
391 | } | 393 | } |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index b6309db5622..fe9306bf10c 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -800,7 +800,7 @@ static void xs_udp_data_ready(struct sock *sk, int len) | |||
800 | u32 _xid; | 800 | u32 _xid; |
801 | __be32 *xp; | 801 | __be32 *xp; |
802 | 802 | ||
803 | read_lock(&sk->sk_callback_lock); | 803 | read_lock_bh(&sk->sk_callback_lock); |
804 | dprintk("RPC: xs_udp_data_ready...\n"); | 804 | dprintk("RPC: xs_udp_data_ready...\n"); |
805 | if (!(xprt = xprt_from_sock(sk))) | 805 | if (!(xprt = xprt_from_sock(sk))) |
806 | goto out; | 806 | goto out; |
@@ -852,7 +852,7 @@ static void xs_udp_data_ready(struct sock *sk, int len) | |||
852 | dropit: | 852 | dropit: |
853 | skb_free_datagram(sk, skb); | 853 | skb_free_datagram(sk, skb); |
854 | out: | 854 | out: |
855 | read_unlock(&sk->sk_callback_lock); | 855 | read_unlock_bh(&sk->sk_callback_lock); |
856 | } | 856 | } |
857 | 857 | ||
858 | static inline void xs_tcp_read_fraghdr(struct rpc_xprt *xprt, struct xdr_skb_reader *desc) | 858 | static inline void xs_tcp_read_fraghdr(struct rpc_xprt *xprt, struct xdr_skb_reader *desc) |
@@ -1229,7 +1229,7 @@ static void xs_tcp_data_ready(struct sock *sk, int bytes) | |||
1229 | 1229 | ||
1230 | dprintk("RPC: xs_tcp_data_ready...\n"); | 1230 | dprintk("RPC: xs_tcp_data_ready...\n"); |
1231 | 1231 | ||
1232 | read_lock(&sk->sk_callback_lock); | 1232 | read_lock_bh(&sk->sk_callback_lock); |
1233 | if (!(xprt = xprt_from_sock(sk))) | 1233 | if (!(xprt = xprt_from_sock(sk))) |
1234 | goto out; | 1234 | goto out; |
1235 | if (xprt->shutdown) | 1235 | if (xprt->shutdown) |
@@ -1248,7 +1248,7 @@ static void xs_tcp_data_ready(struct sock *sk, int bytes) | |||
1248 | read = tcp_read_sock(sk, &rd_desc, xs_tcp_data_recv); | 1248 | read = tcp_read_sock(sk, &rd_desc, xs_tcp_data_recv); |
1249 | } while (read > 0); | 1249 | } while (read > 0); |
1250 | out: | 1250 | out: |
1251 | read_unlock(&sk->sk_callback_lock); | 1251 | read_unlock_bh(&sk->sk_callback_lock); |
1252 | } | 1252 | } |
1253 | 1253 | ||
1254 | /* | 1254 | /* |
@@ -1301,7 +1301,7 @@ static void xs_tcp_state_change(struct sock *sk) | |||
1301 | { | 1301 | { |
1302 | struct rpc_xprt *xprt; | 1302 | struct rpc_xprt *xprt; |
1303 | 1303 | ||
1304 | read_lock(&sk->sk_callback_lock); | 1304 | read_lock_bh(&sk->sk_callback_lock); |
1305 | if (!(xprt = xprt_from_sock(sk))) | 1305 | if (!(xprt = xprt_from_sock(sk))) |
1306 | goto out; | 1306 | goto out; |
1307 | dprintk("RPC: xs_tcp_state_change client %p...\n", xprt); | 1307 | dprintk("RPC: xs_tcp_state_change client %p...\n", xprt); |
@@ -1313,7 +1313,7 @@ static void xs_tcp_state_change(struct sock *sk) | |||
1313 | 1313 | ||
1314 | switch (sk->sk_state) { | 1314 | switch (sk->sk_state) { |
1315 | case TCP_ESTABLISHED: | 1315 | case TCP_ESTABLISHED: |
1316 | spin_lock_bh(&xprt->transport_lock); | 1316 | spin_lock(&xprt->transport_lock); |
1317 | if (!xprt_test_and_set_connected(xprt)) { | 1317 | if (!xprt_test_and_set_connected(xprt)) { |
1318 | struct sock_xprt *transport = container_of(xprt, | 1318 | struct sock_xprt *transport = container_of(xprt, |
1319 | struct sock_xprt, xprt); | 1319 | struct sock_xprt, xprt); |
@@ -1327,7 +1327,7 @@ static void xs_tcp_state_change(struct sock *sk) | |||
1327 | 1327 | ||
1328 | xprt_wake_pending_tasks(xprt, -EAGAIN); | 1328 | xprt_wake_pending_tasks(xprt, -EAGAIN); |
1329 | } | 1329 | } |
1330 | spin_unlock_bh(&xprt->transport_lock); | 1330 | spin_unlock(&xprt->transport_lock); |
1331 | break; | 1331 | break; |
1332 | case TCP_FIN_WAIT1: | 1332 | case TCP_FIN_WAIT1: |
1333 | /* The client initiated a shutdown of the socket */ | 1333 | /* The client initiated a shutdown of the socket */ |
@@ -1365,7 +1365,7 @@ static void xs_tcp_state_change(struct sock *sk) | |||
1365 | xs_sock_mark_closed(xprt); | 1365 | xs_sock_mark_closed(xprt); |
1366 | } | 1366 | } |
1367 | out: | 1367 | out: |
1368 | read_unlock(&sk->sk_callback_lock); | 1368 | read_unlock_bh(&sk->sk_callback_lock); |
1369 | } | 1369 | } |
1370 | 1370 | ||
1371 | /** | 1371 | /** |
@@ -1376,7 +1376,7 @@ static void xs_error_report(struct sock *sk) | |||
1376 | { | 1376 | { |
1377 | struct rpc_xprt *xprt; | 1377 | struct rpc_xprt *xprt; |
1378 | 1378 | ||
1379 | read_lock(&sk->sk_callback_lock); | 1379 | read_lock_bh(&sk->sk_callback_lock); |
1380 | if (!(xprt = xprt_from_sock(sk))) | 1380 | if (!(xprt = xprt_from_sock(sk))) |
1381 | goto out; | 1381 | goto out; |
1382 | dprintk("RPC: %s client %p...\n" | 1382 | dprintk("RPC: %s client %p...\n" |
@@ -1384,7 +1384,7 @@ static void xs_error_report(struct sock *sk) | |||
1384 | __func__, xprt, sk->sk_err); | 1384 | __func__, xprt, sk->sk_err); |
1385 | xprt_wake_pending_tasks(xprt, -EAGAIN); | 1385 | xprt_wake_pending_tasks(xprt, -EAGAIN); |
1386 | out: | 1386 | out: |
1387 | read_unlock(&sk->sk_callback_lock); | 1387 | read_unlock_bh(&sk->sk_callback_lock); |
1388 | } | 1388 | } |
1389 | 1389 | ||
1390 | static void xs_write_space(struct sock *sk) | 1390 | static void xs_write_space(struct sock *sk) |
@@ -1416,13 +1416,13 @@ static void xs_write_space(struct sock *sk) | |||
1416 | */ | 1416 | */ |
1417 | static void xs_udp_write_space(struct sock *sk) | 1417 | static void xs_udp_write_space(struct sock *sk) |
1418 | { | 1418 | { |
1419 | read_lock(&sk->sk_callback_lock); | 1419 | read_lock_bh(&sk->sk_callback_lock); |
1420 | 1420 | ||
1421 | /* from net/core/sock.c:sock_def_write_space */ | 1421 | /* from net/core/sock.c:sock_def_write_space */ |
1422 | if (sock_writeable(sk)) | 1422 | if (sock_writeable(sk)) |
1423 | xs_write_space(sk); | 1423 | xs_write_space(sk); |
1424 | 1424 | ||
1425 | read_unlock(&sk->sk_callback_lock); | 1425 | read_unlock_bh(&sk->sk_callback_lock); |
1426 | } | 1426 | } |
1427 | 1427 | ||
1428 | /** | 1428 | /** |
@@ -1437,13 +1437,13 @@ static void xs_udp_write_space(struct sock *sk) | |||
1437 | */ | 1437 | */ |
1438 | static void xs_tcp_write_space(struct sock *sk) | 1438 | static void xs_tcp_write_space(struct sock *sk) |
1439 | { | 1439 | { |
1440 | read_lock(&sk->sk_callback_lock); | 1440 | read_lock_bh(&sk->sk_callback_lock); |
1441 | 1441 | ||
1442 | /* from net/core/stream.c:sk_stream_write_space */ | 1442 | /* from net/core/stream.c:sk_stream_write_space */ |
1443 | if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk)) | 1443 | if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk)) |
1444 | xs_write_space(sk); | 1444 | xs_write_space(sk); |
1445 | 1445 | ||
1446 | read_unlock(&sk->sk_callback_lock); | 1446 | read_unlock_bh(&sk->sk_callback_lock); |
1447 | } | 1447 | } |
1448 | 1448 | ||
1449 | static void xs_udp_do_set_buffer_size(struct rpc_xprt *xprt) | 1449 | static void xs_udp_do_set_buffer_size(struct rpc_xprt *xprt) |
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 4414a18c63b..0b39b2451ea 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -692,6 +692,7 @@ static int unix_autobind(struct socket *sock) | |||
692 | static u32 ordernum = 1; | 692 | static u32 ordernum = 1; |
693 | struct unix_address *addr; | 693 | struct unix_address *addr; |
694 | int err; | 694 | int err; |
695 | unsigned int retries = 0; | ||
695 | 696 | ||
696 | mutex_lock(&u->readlock); | 697 | mutex_lock(&u->readlock); |
697 | 698 | ||
@@ -717,9 +718,17 @@ retry: | |||
717 | if (__unix_find_socket_byname(net, addr->name, addr->len, sock->type, | 718 | if (__unix_find_socket_byname(net, addr->name, addr->len, sock->type, |
718 | addr->hash)) { | 719 | addr->hash)) { |
719 | spin_unlock(&unix_table_lock); | 720 | spin_unlock(&unix_table_lock); |
720 | /* Sanity yield. It is unusual case, but yet... */ | 721 | /* |
721 | if (!(ordernum&0xFF)) | 722 | * __unix_find_socket_byname() may take long time if many names |
722 | yield(); | 723 | * are already in use. |
724 | */ | ||
725 | cond_resched(); | ||
726 | /* Give up if all names seems to be in use. */ | ||
727 | if (retries++ == 0xFFFFF) { | ||
728 | err = -ENOSPC; | ||
729 | kfree(addr); | ||
730 | goto out; | ||
731 | } | ||
723 | goto retry; | 732 | goto retry; |
724 | } | 733 | } |
725 | addr->hash ^= sk->sk_type; | 734 | addr->hash ^= sk->sk_type; |
diff --git a/net/wireless/core.c b/net/wireless/core.c index 541e2fff5e9..d6d046b9f6f 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -475,12 +475,10 @@ int wiphy_register(struct wiphy *wiphy) | |||
475 | mutex_lock(&cfg80211_mutex); | 475 | mutex_lock(&cfg80211_mutex); |
476 | 476 | ||
477 | res = device_add(&rdev->wiphy.dev); | 477 | res = device_add(&rdev->wiphy.dev); |
478 | if (res) | 478 | if (res) { |
479 | goto out_unlock; | 479 | mutex_unlock(&cfg80211_mutex); |
480 | 480 | return res; | |
481 | res = rfkill_register(rdev->rfkill); | 481 | } |
482 | if (res) | ||
483 | goto out_rm_dev; | ||
484 | 482 | ||
485 | /* set up regulatory info */ | 483 | /* set up regulatory info */ |
486 | wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE); | 484 | wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE); |
@@ -509,13 +507,18 @@ int wiphy_register(struct wiphy *wiphy) | |||
509 | cfg80211_debugfs_rdev_add(rdev); | 507 | cfg80211_debugfs_rdev_add(rdev); |
510 | mutex_unlock(&cfg80211_mutex); | 508 | mutex_unlock(&cfg80211_mutex); |
511 | 509 | ||
510 | /* | ||
511 | * due to a locking dependency this has to be outside of the | ||
512 | * cfg80211_mutex lock | ||
513 | */ | ||
514 | res = rfkill_register(rdev->rfkill); | ||
515 | if (res) | ||
516 | goto out_rm_dev; | ||
517 | |||
512 | return 0; | 518 | return 0; |
513 | 519 | ||
514 | out_rm_dev: | 520 | out_rm_dev: |
515 | device_del(&rdev->wiphy.dev); | 521 | device_del(&rdev->wiphy.dev); |
516 | |||
517 | out_unlock: | ||
518 | mutex_unlock(&cfg80211_mutex); | ||
519 | return res; | 522 | return res; |
520 | } | 523 | } |
521 | EXPORT_SYMBOL(wiphy_register); | 524 | EXPORT_SYMBOL(wiphy_register); |
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index bb5e0a5ecfa..7e5c3a45f81 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c | |||
@@ -1420,6 +1420,9 @@ int cfg80211_wext_giwessid(struct net_device *dev, | |||
1420 | { | 1420 | { |
1421 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 1421 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
1422 | 1422 | ||
1423 | data->flags = 0; | ||
1424 | data->length = 0; | ||
1425 | |||
1423 | switch (wdev->iftype) { | 1426 | switch (wdev->iftype) { |
1424 | case NL80211_IFTYPE_ADHOC: | 1427 | case NL80211_IFTYPE_ADHOC: |
1425 | return cfg80211_ibss_wext_giwessid(dev, info, data, ssid); | 1428 | return cfg80211_ibss_wext_giwessid(dev, info, data, ssid); |
diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c index 0ef17bc42ba..8f5116f5af1 100644 --- a/net/wireless/wext-core.c +++ b/net/wireless/wext-core.c | |||
@@ -782,6 +782,22 @@ static int ioctl_standard_iw_point(struct iw_point *iwp, unsigned int cmd, | |||
782 | } | 782 | } |
783 | } | 783 | } |
784 | 784 | ||
785 | if (IW_IS_GET(cmd) && !(descr->flags & IW_DESCR_FLAG_NOMAX)) { | ||
786 | /* | ||
787 | * If this is a GET, but not NOMAX, it means that the extra | ||
788 | * data is not bounded by userspace, but by max_tokens. Thus | ||
789 | * set the length to max_tokens. This matches the extra data | ||
790 | * allocation. | ||
791 | * The driver should fill it with the number of tokens it | ||
792 | * provided, and it may check iwp->length rather than having | ||
793 | * knowledge of max_tokens. If the driver doesn't change the | ||
794 | * iwp->length, this ioctl just copies back max_token tokens | ||
795 | * filled with zeroes. Hopefully the driver isn't claiming | ||
796 | * them to be valid data. | ||
797 | */ | ||
798 | iwp->length = descr->max_tokens; | ||
799 | } | ||
800 | |||
785 | err = handler(dev, info, (union iwreq_data *) iwp, extra); | 801 | err = handler(dev, info, (union iwreq_data *) iwp, extra); |
786 | 802 | ||
787 | iwp->length += essid_compat; | 803 | iwp->length += essid_compat; |
diff --git a/net/wireless/wext-priv.c b/net/wireless/wext-priv.c index 3feb28e41c5..674d426a9d2 100644 --- a/net/wireless/wext-priv.c +++ b/net/wireless/wext-priv.c | |||
@@ -152,7 +152,7 @@ static int ioctl_private_iw_point(struct iw_point *iwp, unsigned int cmd, | |||
152 | } else if (!iwp->pointer) | 152 | } else if (!iwp->pointer) |
153 | return -EFAULT; | 153 | return -EFAULT; |
154 | 154 | ||
155 | extra = kmalloc(extra_size, GFP_KERNEL); | 155 | extra = kzalloc(extra_size, GFP_KERNEL); |
156 | if (!extra) | 156 | if (!extra) |
157 | return -ENOMEM; | 157 | return -ENOMEM; |
158 | 158 | ||
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c index a3cca0a9434..64f2ae1fdc1 100644 --- a/net/xfrm/xfrm_output.c +++ b/net/xfrm/xfrm_output.c | |||
@@ -101,7 +101,7 @@ resume: | |||
101 | err = -EHOSTUNREACH; | 101 | err = -EHOSTUNREACH; |
102 | goto error_nolock; | 102 | goto error_nolock; |
103 | } | 103 | } |
104 | skb_dst_set_noref(skb, dst); | 104 | skb_dst_set(skb, dst_clone(dst)); |
105 | x = dst->xfrm; | 105 | x = dst->xfrm; |
106 | } while (x && !(x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL)); | 106 | } while (x && !(x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL)); |
107 | 107 | ||
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 2b3ed7ad493..cbab6e1a8c9 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -1175,9 +1175,8 @@ xfrm_tmpl_resolve_one(struct xfrm_policy *policy, struct flowi *fl, | |||
1175 | tmpl->mode == XFRM_MODE_BEET) { | 1175 | tmpl->mode == XFRM_MODE_BEET) { |
1176 | remote = &tmpl->id.daddr; | 1176 | remote = &tmpl->id.daddr; |
1177 | local = &tmpl->saddr; | 1177 | local = &tmpl->saddr; |
1178 | family = tmpl->encap_family; | 1178 | if (xfrm_addr_any(local, tmpl->encap_family)) { |
1179 | if (xfrm_addr_any(local, family)) { | 1179 | error = xfrm_get_saddr(net, &tmp, remote, tmpl->encap_family); |
1180 | error = xfrm_get_saddr(net, &tmp, remote, family); | ||
1181 | if (error) | 1180 | if (error) |
1182 | goto fail; | 1181 | goto fail; |
1183 | local = &tmp; | 1182 | local = &tmp; |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 5208b12fbfb..eb96ce52f17 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -656,15 +656,23 @@ void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si) | |||
656 | EXPORT_SYMBOL(xfrm_sad_getinfo); | 656 | EXPORT_SYMBOL(xfrm_sad_getinfo); |
657 | 657 | ||
658 | static int | 658 | static int |
659 | xfrm_init_tempsel(struct xfrm_state *x, struct flowi *fl, | 659 | xfrm_init_tempstate(struct xfrm_state *x, struct flowi *fl, |
660 | struct xfrm_tmpl *tmpl, | 660 | struct xfrm_tmpl *tmpl, |
661 | xfrm_address_t *daddr, xfrm_address_t *saddr, | 661 | xfrm_address_t *daddr, xfrm_address_t *saddr, |
662 | unsigned short family) | 662 | unsigned short family) |
663 | { | 663 | { |
664 | struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family); | 664 | struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family); |
665 | if (!afinfo) | 665 | if (!afinfo) |
666 | return -1; | 666 | return -1; |
667 | afinfo->init_tempsel(x, fl, tmpl, daddr, saddr); | 667 | afinfo->init_tempsel(&x->sel, fl); |
668 | |||
669 | if (family != tmpl->encap_family) { | ||
670 | xfrm_state_put_afinfo(afinfo); | ||
671 | afinfo = xfrm_state_get_afinfo(tmpl->encap_family); | ||
672 | if (!afinfo) | ||
673 | return -1; | ||
674 | } | ||
675 | afinfo->init_temprop(x, tmpl, daddr, saddr); | ||
668 | xfrm_state_put_afinfo(afinfo); | 676 | xfrm_state_put_afinfo(afinfo); |
669 | return 0; | 677 | return 0; |
670 | } | 678 | } |
@@ -790,37 +798,38 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, | |||
790 | int error = 0; | 798 | int error = 0; |
791 | struct xfrm_state *best = NULL; | 799 | struct xfrm_state *best = NULL; |
792 | u32 mark = pol->mark.v & pol->mark.m; | 800 | u32 mark = pol->mark.v & pol->mark.m; |
801 | unsigned short encap_family = tmpl->encap_family; | ||
793 | 802 | ||
794 | to_put = NULL; | 803 | to_put = NULL; |
795 | 804 | ||
796 | spin_lock_bh(&xfrm_state_lock); | 805 | spin_lock_bh(&xfrm_state_lock); |
797 | h = xfrm_dst_hash(net, daddr, saddr, tmpl->reqid, family); | 806 | h = xfrm_dst_hash(net, daddr, saddr, tmpl->reqid, encap_family); |
798 | hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h, bydst) { | 807 | hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h, bydst) { |
799 | if (x->props.family == family && | 808 | if (x->props.family == encap_family && |
800 | x->props.reqid == tmpl->reqid && | 809 | x->props.reqid == tmpl->reqid && |
801 | (mark & x->mark.m) == x->mark.v && | 810 | (mark & x->mark.m) == x->mark.v && |
802 | !(x->props.flags & XFRM_STATE_WILDRECV) && | 811 | !(x->props.flags & XFRM_STATE_WILDRECV) && |
803 | xfrm_state_addr_check(x, daddr, saddr, family) && | 812 | xfrm_state_addr_check(x, daddr, saddr, encap_family) && |
804 | tmpl->mode == x->props.mode && | 813 | tmpl->mode == x->props.mode && |
805 | tmpl->id.proto == x->id.proto && | 814 | tmpl->id.proto == x->id.proto && |
806 | (tmpl->id.spi == x->id.spi || !tmpl->id.spi)) | 815 | (tmpl->id.spi == x->id.spi || !tmpl->id.spi)) |
807 | xfrm_state_look_at(pol, x, fl, family, daddr, saddr, | 816 | xfrm_state_look_at(pol, x, fl, encap_family, daddr, saddr, |
808 | &best, &acquire_in_progress, &error); | 817 | &best, &acquire_in_progress, &error); |
809 | } | 818 | } |
810 | if (best) | 819 | if (best) |
811 | goto found; | 820 | goto found; |
812 | 821 | ||
813 | h_wildcard = xfrm_dst_hash(net, daddr, &saddr_wildcard, tmpl->reqid, family); | 822 | h_wildcard = xfrm_dst_hash(net, daddr, &saddr_wildcard, tmpl->reqid, encap_family); |
814 | hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h_wildcard, bydst) { | 823 | hlist_for_each_entry(x, entry, net->xfrm.state_bydst+h_wildcard, bydst) { |
815 | if (x->props.family == family && | 824 | if (x->props.family == encap_family && |
816 | x->props.reqid == tmpl->reqid && | 825 | x->props.reqid == tmpl->reqid && |
817 | (mark & x->mark.m) == x->mark.v && | 826 | (mark & x->mark.m) == x->mark.v && |
818 | !(x->props.flags & XFRM_STATE_WILDRECV) && | 827 | !(x->props.flags & XFRM_STATE_WILDRECV) && |
819 | xfrm_state_addr_check(x, daddr, saddr, family) && | 828 | xfrm_state_addr_check(x, daddr, saddr, encap_family) && |
820 | tmpl->mode == x->props.mode && | 829 | tmpl->mode == x->props.mode && |
821 | tmpl->id.proto == x->id.proto && | 830 | tmpl->id.proto == x->id.proto && |
822 | (tmpl->id.spi == x->id.spi || !tmpl->id.spi)) | 831 | (tmpl->id.spi == x->id.spi || !tmpl->id.spi)) |
823 | xfrm_state_look_at(pol, x, fl, family, daddr, saddr, | 832 | xfrm_state_look_at(pol, x, fl, encap_family, daddr, saddr, |
824 | &best, &acquire_in_progress, &error); | 833 | &best, &acquire_in_progress, &error); |
825 | } | 834 | } |
826 | 835 | ||
@@ -829,7 +838,7 @@ found: | |||
829 | if (!x && !error && !acquire_in_progress) { | 838 | if (!x && !error && !acquire_in_progress) { |
830 | if (tmpl->id.spi && | 839 | if (tmpl->id.spi && |
831 | (x0 = __xfrm_state_lookup(net, mark, daddr, tmpl->id.spi, | 840 | (x0 = __xfrm_state_lookup(net, mark, daddr, tmpl->id.spi, |
832 | tmpl->id.proto, family)) != NULL) { | 841 | tmpl->id.proto, encap_family)) != NULL) { |
833 | to_put = x0; | 842 | to_put = x0; |
834 | error = -EEXIST; | 843 | error = -EEXIST; |
835 | goto out; | 844 | goto out; |
@@ -839,9 +848,9 @@ found: | |||
839 | error = -ENOMEM; | 848 | error = -ENOMEM; |
840 | goto out; | 849 | goto out; |
841 | } | 850 | } |
842 | /* Initialize temporary selector matching only | 851 | /* Initialize temporary state matching only |
843 | * to current session. */ | 852 | * to current session. */ |
844 | xfrm_init_tempsel(x, fl, tmpl, daddr, saddr, family); | 853 | xfrm_init_tempstate(x, fl, tmpl, daddr, saddr, family); |
845 | memcpy(&x->mark, &pol->mark, sizeof(x->mark)); | 854 | memcpy(&x->mark, &pol->mark, sizeof(x->mark)); |
846 | 855 | ||
847 | error = security_xfrm_state_alloc_acquire(x, pol->security, fl->secid); | 856 | error = security_xfrm_state_alloc_acquire(x, pol->security, fl->secid); |
@@ -856,10 +865,10 @@ found: | |||
856 | x->km.state = XFRM_STATE_ACQ; | 865 | x->km.state = XFRM_STATE_ACQ; |
857 | list_add(&x->km.all, &net->xfrm.state_all); | 866 | list_add(&x->km.all, &net->xfrm.state_all); |
858 | hlist_add_head(&x->bydst, net->xfrm.state_bydst+h); | 867 | hlist_add_head(&x->bydst, net->xfrm.state_bydst+h); |
859 | h = xfrm_src_hash(net, daddr, saddr, family); | 868 | h = xfrm_src_hash(net, daddr, saddr, encap_family); |
860 | hlist_add_head(&x->bysrc, net->xfrm.state_bysrc+h); | 869 | hlist_add_head(&x->bysrc, net->xfrm.state_bysrc+h); |
861 | if (x->id.spi) { | 870 | if (x->id.spi) { |
862 | h = xfrm_spi_hash(net, &x->id.daddr, x->id.spi, x->id.proto, family); | 871 | h = xfrm_spi_hash(net, &x->id.daddr, x->id.spi, x->id.proto, encap_family); |
863 | hlist_add_head(&x->byspi, net->xfrm.state_byspi+h); | 872 | hlist_add_head(&x->byspi, net->xfrm.state_byspi+h); |
864 | } | 873 | } |
865 | x->lft.hard_add_expires_seconds = net->xfrm.sysctl_acq_expires; | 874 | x->lft.hard_add_expires_seconds = net->xfrm.sysctl_acq_expires; |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index b14ed4b1f27..8bae6b22c84 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -1801,7 +1801,7 @@ static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1801 | struct xfrm_user_expire *ue = nlmsg_data(nlh); | 1801 | struct xfrm_user_expire *ue = nlmsg_data(nlh); |
1802 | struct xfrm_usersa_info *p = &ue->state; | 1802 | struct xfrm_usersa_info *p = &ue->state; |
1803 | struct xfrm_mark m; | 1803 | struct xfrm_mark m; |
1804 | u32 mark = xfrm_mark_get(attrs, &m);; | 1804 | u32 mark = xfrm_mark_get(attrs, &m); |
1805 | 1805 | ||
1806 | x = xfrm_state_lookup(net, mark, &p->id.daddr, p->id.spi, p->id.proto, p->family); | 1806 | x = xfrm_state_lookup(net, mark, &p->id.daddr, p->id.spi, p->id.proto, p->family); |
1807 | 1807 | ||
diff --git a/samples/kfifo/dma-example.c b/samples/kfifo/dma-example.c index ee03a4f0b64..06473791c08 100644 --- a/samples/kfifo/dma-example.c +++ b/samples/kfifo/dma-example.c | |||
@@ -24,6 +24,7 @@ static int __init example_init(void) | |||
24 | { | 24 | { |
25 | int i; | 25 | int i; |
26 | unsigned int ret; | 26 | unsigned int ret; |
27 | unsigned int nents; | ||
27 | struct scatterlist sg[10]; | 28 | struct scatterlist sg[10]; |
28 | 29 | ||
29 | printk(KERN_INFO "DMA fifo test start\n"); | 30 | printk(KERN_INFO "DMA fifo test start\n"); |
@@ -61,9 +62,9 @@ static int __init example_init(void) | |||
61 | * byte at the beginning, after the kfifo_skip(). | 62 | * byte at the beginning, after the kfifo_skip(). |
62 | */ | 63 | */ |
63 | sg_init_table(sg, ARRAY_SIZE(sg)); | 64 | sg_init_table(sg, ARRAY_SIZE(sg)); |
64 | ret = kfifo_dma_in_prepare(&fifo, sg, ARRAY_SIZE(sg), FIFO_SIZE); | 65 | nents = kfifo_dma_in_prepare(&fifo, sg, ARRAY_SIZE(sg), FIFO_SIZE); |
65 | printk(KERN_INFO "DMA sgl entries: %d\n", ret); | 66 | printk(KERN_INFO "DMA sgl entries: %d\n", nents); |
66 | if (!ret) { | 67 | if (!nents) { |
67 | /* fifo is full and no sgl was created */ | 68 | /* fifo is full and no sgl was created */ |
68 | printk(KERN_WARNING "error kfifo_dma_in_prepare\n"); | 69 | printk(KERN_WARNING "error kfifo_dma_in_prepare\n"); |
69 | return -EIO; | 70 | return -EIO; |
@@ -71,7 +72,7 @@ static int __init example_init(void) | |||
71 | 72 | ||
72 | /* receive data */ | 73 | /* receive data */ |
73 | printk(KERN_INFO "scatterlist for receive:\n"); | 74 | printk(KERN_INFO "scatterlist for receive:\n"); |
74 | for (i = 0; i < ARRAY_SIZE(sg); i++) { | 75 | for (i = 0; i < nents; i++) { |
75 | printk(KERN_INFO | 76 | printk(KERN_INFO |
76 | "sg[%d] -> " | 77 | "sg[%d] -> " |
77 | "page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n", | 78 | "page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n", |
@@ -91,16 +92,16 @@ static int __init example_init(void) | |||
91 | kfifo_dma_in_finish(&fifo, ret); | 92 | kfifo_dma_in_finish(&fifo, ret); |
92 | 93 | ||
93 | /* Prepare to transmit data, example: 8 bytes */ | 94 | /* Prepare to transmit data, example: 8 bytes */ |
94 | ret = kfifo_dma_out_prepare(&fifo, sg, ARRAY_SIZE(sg), 8); | 95 | nents = kfifo_dma_out_prepare(&fifo, sg, ARRAY_SIZE(sg), 8); |
95 | printk(KERN_INFO "DMA sgl entries: %d\n", ret); | 96 | printk(KERN_INFO "DMA sgl entries: %d\n", nents); |
96 | if (!ret) { | 97 | if (!nents) { |
97 | /* no data was available and no sgl was created */ | 98 | /* no data was available and no sgl was created */ |
98 | printk(KERN_WARNING "error kfifo_dma_out_prepare\n"); | 99 | printk(KERN_WARNING "error kfifo_dma_out_prepare\n"); |
99 | return -EIO; | 100 | return -EIO; |
100 | } | 101 | } |
101 | 102 | ||
102 | printk(KERN_INFO "scatterlist for transmit:\n"); | 103 | printk(KERN_INFO "scatterlist for transmit:\n"); |
103 | for (i = 0; i < ARRAY_SIZE(sg); i++) { | 104 | for (i = 0; i < nents; i++) { |
104 | printk(KERN_INFO | 105 | printk(KERN_INFO |
105 | "sg[%d] -> " | 106 | "sg[%d] -> " |
106 | "page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n", | 107 | "page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n", |
diff --git a/scripts/basic/docproc.c b/scripts/basic/docproc.c index 79ab973fb43..fc3b18d844a 100644 --- a/scripts/basic/docproc.c +++ b/scripts/basic/docproc.c | |||
@@ -34,12 +34,14 @@ | |||
34 | * | 34 | * |
35 | */ | 35 | */ |
36 | 36 | ||
37 | #define _GNU_SOURCE | ||
37 | #include <stdio.h> | 38 | #include <stdio.h> |
38 | #include <stdlib.h> | 39 | #include <stdlib.h> |
39 | #include <string.h> | 40 | #include <string.h> |
40 | #include <ctype.h> | 41 | #include <ctype.h> |
41 | #include <unistd.h> | 42 | #include <unistd.h> |
42 | #include <limits.h> | 43 | #include <limits.h> |
44 | #include <errno.h> | ||
43 | #include <sys/types.h> | 45 | #include <sys/types.h> |
44 | #include <sys/wait.h> | 46 | #include <sys/wait.h> |
45 | 47 | ||
@@ -54,6 +56,7 @@ typedef void FILEONLY(char * file); | |||
54 | FILEONLY *internalfunctions; | 56 | FILEONLY *internalfunctions; |
55 | FILEONLY *externalfunctions; | 57 | FILEONLY *externalfunctions; |
56 | FILEONLY *symbolsonly; | 58 | FILEONLY *symbolsonly; |
59 | FILEONLY *findall; | ||
57 | 60 | ||
58 | typedef void FILELINE(char * file, char * line); | 61 | typedef void FILELINE(char * file, char * line); |
59 | FILELINE * singlefunctions; | 62 | FILELINE * singlefunctions; |
@@ -65,12 +68,30 @@ FILELINE * docsection; | |||
65 | #define KERNELDOCPATH "scripts/" | 68 | #define KERNELDOCPATH "scripts/" |
66 | #define KERNELDOC "kernel-doc" | 69 | #define KERNELDOC "kernel-doc" |
67 | #define DOCBOOK "-docbook" | 70 | #define DOCBOOK "-docbook" |
71 | #define LIST "-list" | ||
68 | #define FUNCTION "-function" | 72 | #define FUNCTION "-function" |
69 | #define NOFUNCTION "-nofunction" | 73 | #define NOFUNCTION "-nofunction" |
70 | #define NODOCSECTIONS "-no-doc-sections" | 74 | #define NODOCSECTIONS "-no-doc-sections" |
71 | 75 | ||
72 | static char *srctree, *kernsrctree; | 76 | static char *srctree, *kernsrctree; |
73 | 77 | ||
78 | static char **all_list = NULL; | ||
79 | static int all_list_len = 0; | ||
80 | |||
81 | static void consume_symbol(const char *sym) | ||
82 | { | ||
83 | int i; | ||
84 | |||
85 | for (i = 0; i < all_list_len; i++) { | ||
86 | if (!all_list[i]) | ||
87 | continue; | ||
88 | if (strcmp(sym, all_list[i])) | ||
89 | continue; | ||
90 | all_list[i] = NULL; | ||
91 | break; | ||
92 | } | ||
93 | } | ||
94 | |||
74 | static void usage (void) | 95 | static void usage (void) |
75 | { | 96 | { |
76 | fprintf(stderr, "Usage: docproc {doc|depend} file\n"); | 97 | fprintf(stderr, "Usage: docproc {doc|depend} file\n"); |
@@ -248,6 +269,7 @@ static void docfunctions(char * filename, char * type) | |||
248 | struct symfile * sym = &symfilelist[i]; | 269 | struct symfile * sym = &symfilelist[i]; |
249 | for (j=0; j < sym->symbolcnt; j++) { | 270 | for (j=0; j < sym->symbolcnt; j++) { |
250 | vec[idx++] = type; | 271 | vec[idx++] = type; |
272 | consume_symbol(sym->symbollist[j].name); | ||
251 | vec[idx++] = sym->symbollist[j].name; | 273 | vec[idx++] = sym->symbollist[j].name; |
252 | } | 274 | } |
253 | } | 275 | } |
@@ -287,6 +309,11 @@ static void singfunc(char * filename, char * line) | |||
287 | vec[idx++] = &line[i]; | 309 | vec[idx++] = &line[i]; |
288 | } | 310 | } |
289 | } | 311 | } |
312 | for (i = 0; i < idx; i++) { | ||
313 | if (strcmp(vec[i], FUNCTION)) | ||
314 | continue; | ||
315 | consume_symbol(vec[i + 1]); | ||
316 | } | ||
290 | vec[idx++] = filename; | 317 | vec[idx++] = filename; |
291 | vec[idx] = NULL; | 318 | vec[idx] = NULL; |
292 | exec_kernel_doc(vec); | 319 | exec_kernel_doc(vec); |
@@ -306,6 +333,10 @@ static void docsect(char *filename, char *line) | |||
306 | if (*s == '\n') | 333 | if (*s == '\n') |
307 | *s = '\0'; | 334 | *s = '\0'; |
308 | 335 | ||
336 | asprintf(&s, "DOC: %s", line); | ||
337 | consume_symbol(s); | ||
338 | free(s); | ||
339 | |||
309 | vec[0] = KERNELDOC; | 340 | vec[0] = KERNELDOC; |
310 | vec[1] = DOCBOOK; | 341 | vec[1] = DOCBOOK; |
311 | vec[2] = FUNCTION; | 342 | vec[2] = FUNCTION; |
@@ -315,6 +346,84 @@ static void docsect(char *filename, char *line) | |||
315 | exec_kernel_doc(vec); | 346 | exec_kernel_doc(vec); |
316 | } | 347 | } |
317 | 348 | ||
349 | static void find_all_symbols(char *filename) | ||
350 | { | ||
351 | char *vec[4]; /* kerneldoc -list file NULL */ | ||
352 | pid_t pid; | ||
353 | int ret, i, count, start; | ||
354 | char real_filename[PATH_MAX + 1]; | ||
355 | int pipefd[2]; | ||
356 | char *data, *str; | ||
357 | size_t data_len = 0; | ||
358 | |||
359 | vec[0] = KERNELDOC; | ||
360 | vec[1] = LIST; | ||
361 | vec[2] = filename; | ||
362 | vec[3] = NULL; | ||
363 | |||
364 | if (pipe(pipefd)) { | ||
365 | perror("pipe"); | ||
366 | exit(1); | ||
367 | } | ||
368 | |||
369 | switch (pid=fork()) { | ||
370 | case -1: | ||
371 | perror("fork"); | ||
372 | exit(1); | ||
373 | case 0: | ||
374 | close(pipefd[0]); | ||
375 | dup2(pipefd[1], 1); | ||
376 | memset(real_filename, 0, sizeof(real_filename)); | ||
377 | strncat(real_filename, kernsrctree, PATH_MAX); | ||
378 | strncat(real_filename, "/" KERNELDOCPATH KERNELDOC, | ||
379 | PATH_MAX - strlen(real_filename)); | ||
380 | execvp(real_filename, vec); | ||
381 | fprintf(stderr, "exec "); | ||
382 | perror(real_filename); | ||
383 | exit(1); | ||
384 | default: | ||
385 | close(pipefd[1]); | ||
386 | data = malloc(4096); | ||
387 | do { | ||
388 | while ((ret = read(pipefd[0], | ||
389 | data + data_len, | ||
390 | 4096)) > 0) { | ||
391 | data_len += ret; | ||
392 | data = realloc(data, data_len + 4096); | ||
393 | } | ||
394 | } while (ret == -EAGAIN); | ||
395 | if (ret != 0) { | ||
396 | perror("read"); | ||
397 | exit(1); | ||
398 | } | ||
399 | waitpid(pid, &ret ,0); | ||
400 | } | ||
401 | if (WIFEXITED(ret)) | ||
402 | exitstatus |= WEXITSTATUS(ret); | ||
403 | else | ||
404 | exitstatus = 0xff; | ||
405 | |||
406 | count = 0; | ||
407 | /* poor man's strtok, but with counting */ | ||
408 | for (i = 0; i < data_len; i++) { | ||
409 | if (data[i] == '\n') { | ||
410 | count++; | ||
411 | data[i] = '\0'; | ||
412 | } | ||
413 | } | ||
414 | start = all_list_len; | ||
415 | all_list_len += count; | ||
416 | all_list = realloc(all_list, sizeof(char *) * all_list_len); | ||
417 | str = data; | ||
418 | for (i = 0; i < data_len && start != all_list_len; i++) { | ||
419 | if (data[i] == '\0') { | ||
420 | all_list[start] = str; | ||
421 | str = data + i + 1; | ||
422 | start++; | ||
423 | } | ||
424 | } | ||
425 | } | ||
426 | |||
318 | /* | 427 | /* |
319 | * Parse file, calling action specific functions for: | 428 | * Parse file, calling action specific functions for: |
320 | * 1) Lines containing !E | 429 | * 1) Lines containing !E |
@@ -322,7 +431,8 @@ static void docsect(char *filename, char *line) | |||
322 | * 3) Lines containing !D | 431 | * 3) Lines containing !D |
323 | * 4) Lines containing !F | 432 | * 4) Lines containing !F |
324 | * 5) Lines containing !P | 433 | * 5) Lines containing !P |
325 | * 6) Default lines - lines not matching the above | 434 | * 6) Lines containing !C |
435 | * 7) Default lines - lines not matching the above | ||
326 | */ | 436 | */ |
327 | static void parse_file(FILE *infile) | 437 | static void parse_file(FILE *infile) |
328 | { | 438 | { |
@@ -365,6 +475,12 @@ static void parse_file(FILE *infile) | |||
365 | s++; | 475 | s++; |
366 | docsection(line + 2, s); | 476 | docsection(line + 2, s); |
367 | break; | 477 | break; |
478 | case 'C': | ||
479 | while (*s && !isspace(*s)) s++; | ||
480 | *s = '\0'; | ||
481 | if (findall) | ||
482 | findall(line+2); | ||
483 | break; | ||
368 | default: | 484 | default: |
369 | defaultline(line); | 485 | defaultline(line); |
370 | } | 486 | } |
@@ -380,6 +496,7 @@ static void parse_file(FILE *infile) | |||
380 | int main(int argc, char *argv[]) | 496 | int main(int argc, char *argv[]) |
381 | { | 497 | { |
382 | FILE * infile; | 498 | FILE * infile; |
499 | int i; | ||
383 | 500 | ||
384 | srctree = getenv("SRCTREE"); | 501 | srctree = getenv("SRCTREE"); |
385 | if (!srctree) | 502 | if (!srctree) |
@@ -415,6 +532,7 @@ int main(int argc, char *argv[]) | |||
415 | symbolsonly = find_export_symbols; | 532 | symbolsonly = find_export_symbols; |
416 | singlefunctions = noaction2; | 533 | singlefunctions = noaction2; |
417 | docsection = noaction2; | 534 | docsection = noaction2; |
535 | findall = find_all_symbols; | ||
418 | parse_file(infile); | 536 | parse_file(infile); |
419 | 537 | ||
420 | /* Rewind to start from beginning of file again */ | 538 | /* Rewind to start from beginning of file again */ |
@@ -425,8 +543,16 @@ int main(int argc, char *argv[]) | |||
425 | symbolsonly = printline; | 543 | symbolsonly = printline; |
426 | singlefunctions = singfunc; | 544 | singlefunctions = singfunc; |
427 | docsection = docsect; | 545 | docsection = docsect; |
546 | findall = NULL; | ||
428 | 547 | ||
429 | parse_file(infile); | 548 | parse_file(infile); |
549 | |||
550 | for (i = 0; i < all_list_len; i++) { | ||
551 | if (!all_list[i]) | ||
552 | continue; | ||
553 | fprintf(stderr, "Warning: didn't use docs for %s\n", | ||
554 | all_list[i]); | ||
555 | } | ||
430 | } | 556 | } |
431 | else if (strcmp("depend", argv[1]) == 0) | 557 | else if (strcmp("depend", argv[1]) == 0) |
432 | { | 558 | { |
@@ -439,6 +565,7 @@ int main(int argc, char *argv[]) | |||
439 | symbolsonly = adddep; | 565 | symbolsonly = adddep; |
440 | singlefunctions = adddep2; | 566 | singlefunctions = adddep2; |
441 | docsection = adddep2; | 567 | docsection = adddep2; |
568 | findall = adddep; | ||
442 | parse_file(infile); | 569 | parse_file(infile); |
443 | printf("\n"); | 570 | printf("\n"); |
444 | } | 571 | } |
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 5b7c86ea43a..7ef429cd5cb 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c | |||
@@ -427,7 +427,7 @@ static void check_conf(struct menu *menu) | |||
427 | if (sym->name && !sym_is_choice_value(sym)) { | 427 | if (sym->name && !sym_is_choice_value(sym)) { |
428 | printf("CONFIG_%s\n", sym->name); | 428 | printf("CONFIG_%s\n", sym->name); |
429 | } | 429 | } |
430 | } else { | 430 | } else if (input_mode != oldnoconfig) { |
431 | if (!conf_cnt++) | 431 | if (!conf_cnt++) |
432 | printf(_("*\n* Restart config...\n*\n")); | 432 | printf(_("*\n* Restart config...\n*\n")); |
433 | rootEntry = menu_get_parent_menu(menu); | 433 | rootEntry = menu_get_parent_menu(menu); |
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index c39327e60ea..515253fe46c 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c | |||
@@ -497,7 +497,9 @@ int conf_write_defconfig(const char *filename) | |||
497 | /* | 497 | /* |
498 | * If symbol is a choice value and equals to the | 498 | * If symbol is a choice value and equals to the |
499 | * default for a choice - skip. | 499 | * default for a choice - skip. |
500 | * But only if value is bool and equal to "y" . | 500 | * But only if value is bool and equal to "y" and |
501 | * choice is not "optional". | ||
502 | * (If choice is "optional" then all values can be "n") | ||
501 | */ | 503 | */ |
502 | if (sym_is_choice_value(sym)) { | 504 | if (sym_is_choice_value(sym)) { |
503 | struct symbol *cs; | 505 | struct symbol *cs; |
@@ -505,7 +507,7 @@ int conf_write_defconfig(const char *filename) | |||
505 | 507 | ||
506 | cs = prop_get_symbol(sym_get_choice_prop(sym)); | 508 | cs = prop_get_symbol(sym_get_choice_prop(sym)); |
507 | ds = sym_choice_default(cs); | 509 | ds = sym_choice_default(cs); |
508 | if (sym == ds) { | 510 | if (!sym_is_optional(cs) && sym == ds) { |
509 | if ((sym->type == S_BOOLEAN) && | 511 | if ((sym->type == S_BOOLEAN) && |
510 | sym_get_tristate_value(sym) == yes) | 512 | sym_get_tristate_value(sym) == yes) |
511 | goto next_menu; | 513 | goto next_menu; |
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index 6ee2e4fb148..170459c224a 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h | |||
@@ -165,7 +165,6 @@ struct menu { | |||
165 | struct symbol *sym; | 165 | struct symbol *sym; |
166 | struct property *prompt; | 166 | struct property *prompt; |
167 | struct expr *dep; | 167 | struct expr *dep; |
168 | struct expr *dir_dep; | ||
169 | unsigned int flags; | 168 | unsigned int flags; |
170 | char *help; | 169 | char *help; |
171 | struct file *file; | 170 | struct file *file; |
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 4fb590247f3..edda8b49619 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c | |||
@@ -107,7 +107,6 @@ static struct expr *menu_check_dep(struct expr *e) | |||
107 | void menu_add_dep(struct expr *dep) | 107 | void menu_add_dep(struct expr *dep) |
108 | { | 108 | { |
109 | current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep)); | 109 | current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep)); |
110 | current_entry->dir_dep = current_entry->dep; | ||
111 | } | 110 | } |
112 | 111 | ||
113 | void menu_set_type(int type) | 112 | void menu_set_type(int type) |
@@ -291,10 +290,6 @@ void menu_finalize(struct menu *parent) | |||
291 | for (menu = parent->list; menu; menu = menu->next) | 290 | for (menu = parent->list; menu; menu = menu->next) |
292 | menu_finalize(menu); | 291 | menu_finalize(menu); |
293 | } else if (sym) { | 292 | } else if (sym) { |
294 | /* ignore inherited dependencies for dir_dep */ | ||
295 | sym->dir_dep.expr = expr_transform(expr_copy(parent->dir_dep)); | ||
296 | sym->dir_dep.expr = expr_eliminate_dups(sym->dir_dep.expr); | ||
297 | |||
298 | basedep = parent->prompt ? parent->prompt->visible.expr : NULL; | 293 | basedep = parent->prompt ? parent->prompt->visible.expr : NULL; |
299 | basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no); | 294 | basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no); |
300 | basedep = expr_eliminate_dups(expr_transform(basedep)); | 295 | basedep = expr_eliminate_dups(expr_transform(basedep)); |
@@ -325,6 +320,8 @@ void menu_finalize(struct menu *parent) | |||
325 | parent->next = last_menu->next; | 320 | parent->next = last_menu->next; |
326 | last_menu->next = NULL; | 321 | last_menu->next = NULL; |
327 | } | 322 | } |
323 | |||
324 | sym->dir_dep.expr = parent->dep; | ||
328 | } | 325 | } |
329 | for (menu = parent->list; menu; menu = menu->next) { | 326 | for (menu = parent->list; menu; menu = menu->next) { |
330 | if (sym && sym_is_choice(sym) && | 327 | if (sym && sym_is_choice(sym) && |
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index e95718fea35..1f8b305449d 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c | |||
@@ -350,6 +350,7 @@ void sym_calc_value(struct symbol *sym) | |||
350 | } | 350 | } |
351 | } | 351 | } |
352 | calc_newval: | 352 | calc_newval: |
353 | #if 0 | ||
353 | if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) { | 354 | if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) { |
354 | fprintf(stderr, "warning: ("); | 355 | fprintf(stderr, "warning: ("); |
355 | expr_fprint(sym->rev_dep.expr, stderr); | 356 | expr_fprint(sym->rev_dep.expr, stderr); |
@@ -358,6 +359,7 @@ void sym_calc_value(struct symbol *sym) | |||
358 | expr_fprint(sym->dir_dep.expr, stderr); | 359 | expr_fprint(sym->dir_dep.expr, stderr); |
359 | fprintf(stderr, ")\n"); | 360 | fprintf(stderr, ")\n"); |
360 | } | 361 | } |
362 | #endif | ||
361 | newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri); | 363 | newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri); |
362 | } | 364 | } |
363 | if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN) | 365 | if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN) |
@@ -937,6 +939,8 @@ static void sym_check_print_recursive(struct symbol *last_sym) | |||
937 | sym = stack->sym; | 939 | sym = stack->sym; |
938 | next_sym = stack->next ? stack->next->sym : last_sym; | 940 | next_sym = stack->next ? stack->next->sym : last_sym; |
939 | prop = stack->prop; | 941 | prop = stack->prop; |
942 | if (prop == NULL) | ||
943 | prop = stack->sym->prop; | ||
940 | 944 | ||
941 | /* for choice values find the menu entry (used below) */ | 945 | /* for choice values find the menu entry (used below) */ |
942 | if (sym_is_choice(sym) || sym_is_choice_value(sym)) { | 946 | if (sym_is_choice(sym) || sym_is_choice_value(sym)) { |
diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 102e1235fd5..cdb6dc1f645 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc | |||
@@ -44,12 +44,13 @@ use strict; | |||
44 | # Note: This only supports 'c'. | 44 | # Note: This only supports 'c'. |
45 | 45 | ||
46 | # usage: | 46 | # usage: |
47 | # kernel-doc [ -docbook | -html | -text | -man ] [ -no-doc-sections ] | 47 | # kernel-doc [ -docbook | -html | -text | -man | -list ] [ -no-doc-sections ] |
48 | # [ -function funcname [ -function funcname ...] ] c file(s)s > outputfile | 48 | # [ -function funcname [ -function funcname ...] ] c file(s)s > outputfile |
49 | # or | 49 | # or |
50 | # [ -nofunction funcname [ -function funcname ...] ] c file(s)s > outputfile | 50 | # [ -nofunction funcname [ -function funcname ...] ] c file(s)s > outputfile |
51 | # | 51 | # |
52 | # Set output format using one of -docbook -html -text or -man. Default is man. | 52 | # Set output format using one of -docbook -html -text or -man. Default is man. |
53 | # The -list format is for internal use by docproc. | ||
53 | # | 54 | # |
54 | # -no-doc-sections | 55 | # -no-doc-sections |
55 | # Do not output DOC: sections | 56 | # Do not output DOC: sections |
@@ -210,9 +211,16 @@ my %highlights_text = ( $type_constant, "\$1", | |||
210 | $type_param, "\$1" ); | 211 | $type_param, "\$1" ); |
211 | my $blankline_text = ""; | 212 | my $blankline_text = ""; |
212 | 213 | ||
214 | # list mode | ||
215 | my %highlights_list = ( $type_constant, "\$1", | ||
216 | $type_func, "\$1", | ||
217 | $type_struct, "\$1", | ||
218 | $type_param, "\$1" ); | ||
219 | my $blankline_list = ""; | ||
213 | 220 | ||
214 | sub usage { | 221 | sub usage { |
215 | print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man ] [ -no-doc-sections ]\n"; | 222 | print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man | -list ]\n"; |
223 | print " [ -no-doc-sections ]\n"; | ||
216 | print " [ -function funcname [ -function funcname ...] ]\n"; | 224 | print " [ -function funcname [ -function funcname ...] ]\n"; |
217 | print " [ -nofunction funcname [ -nofunction funcname ...] ]\n"; | 225 | print " [ -nofunction funcname [ -nofunction funcname ...] ]\n"; |
218 | print " c source file(s) > outputfile\n"; | 226 | print " c source file(s) > outputfile\n"; |
@@ -318,6 +326,10 @@ while ($ARGV[0] =~ m/^-(.*)/) { | |||
318 | $output_mode = "xml"; | 326 | $output_mode = "xml"; |
319 | %highlights = %highlights_xml; | 327 | %highlights = %highlights_xml; |
320 | $blankline = $blankline_xml; | 328 | $blankline = $blankline_xml; |
329 | } elsif ($cmd eq "-list") { | ||
330 | $output_mode = "list"; | ||
331 | %highlights = %highlights_list; | ||
332 | $blankline = $blankline_list; | ||
321 | } elsif ($cmd eq "-gnome") { | 333 | } elsif ($cmd eq "-gnome") { |
322 | $output_mode = "gnome"; | 334 | $output_mode = "gnome"; |
323 | %highlights = %highlights_gnome; | 335 | %highlights = %highlights_gnome; |
@@ -1361,6 +1373,42 @@ sub output_blockhead_text(%) { | |||
1361 | } | 1373 | } |
1362 | } | 1374 | } |
1363 | 1375 | ||
1376 | ## list mode output functions | ||
1377 | |||
1378 | sub output_function_list(%) { | ||
1379 | my %args = %{$_[0]}; | ||
1380 | |||
1381 | print $args{'function'} . "\n"; | ||
1382 | } | ||
1383 | |||
1384 | # output enum in list | ||
1385 | sub output_enum_list(%) { | ||
1386 | my %args = %{$_[0]}; | ||
1387 | print $args{'enum'} . "\n"; | ||
1388 | } | ||
1389 | |||
1390 | # output typedef in list | ||
1391 | sub output_typedef_list(%) { | ||
1392 | my %args = %{$_[0]}; | ||
1393 | print $args{'typedef'} . "\n"; | ||
1394 | } | ||
1395 | |||
1396 | # output struct as list | ||
1397 | sub output_struct_list(%) { | ||
1398 | my %args = %{$_[0]}; | ||
1399 | |||
1400 | print $args{'struct'} . "\n"; | ||
1401 | } | ||
1402 | |||
1403 | sub output_blockhead_list(%) { | ||
1404 | my %args = %{$_[0]}; | ||
1405 | my ($parameter, $section); | ||
1406 | |||
1407 | foreach $section (@{$args{'sectionlist'}}) { | ||
1408 | print "DOC: $section\n"; | ||
1409 | } | ||
1410 | } | ||
1411 | |||
1364 | ## | 1412 | ## |
1365 | # generic output function for all types (function, struct/union, typedef, enum); | 1413 | # generic output function for all types (function, struct/union, typedef, enum); |
1366 | # calls the generated, variable output_ function name based on | 1414 | # calls the generated, variable output_ function name based on |
@@ -1679,7 +1727,7 @@ sub check_sections($$$$$$) { | |||
1679 | foreach $px (0 .. $#prms) { | 1727 | foreach $px (0 .. $#prms) { |
1680 | $prm_clean = $prms[$px]; | 1728 | $prm_clean = $prms[$px]; |
1681 | $prm_clean =~ s/\[.*\]//; | 1729 | $prm_clean =~ s/\[.*\]//; |
1682 | $prm_clean =~ s/__attribute__\s*\(\([a-z,_\*\s\(\)]*\)\)//; | 1730 | $prm_clean =~ s/__attribute__\s*\(\([a-z,_\*\s\(\)]*\)\)//i; |
1683 | # ignore array size in a parameter string; | 1731 | # ignore array size in a parameter string; |
1684 | # however, the original param string may contain | 1732 | # however, the original param string may contain |
1685 | # spaces, e.g.: addr[6 + 2] | 1733 | # spaces, e.g.: addr[6 + 2] |
diff --git a/scripts/mkmakefile b/scripts/mkmakefile index 67d59c7a18d..5325423ceab 100644 --- a/scripts/mkmakefile +++ b/scripts/mkmakefile | |||
@@ -44,7 +44,9 @@ all: | |||
44 | 44 | ||
45 | Makefile:; | 45 | Makefile:; |
46 | 46 | ||
47 | \$(all) %/: all | 47 | \$(all): all |
48 | @: | 48 | @: |
49 | 49 | ||
50 | %/: all | ||
51 | @: | ||
50 | EOF | 52 | EOF |
diff --git a/scripts/setlocalversion b/scripts/setlocalversion index e90a91cc518..057b6b3c5df 100755 --- a/scripts/setlocalversion +++ b/scripts/setlocalversion | |||
@@ -43,7 +43,7 @@ scm_version() | |||
43 | fi | 43 | fi |
44 | 44 | ||
45 | # Check for git and a git repo. | 45 | # Check for git and a git repo. |
46 | if head=`git rev-parse --verify --short HEAD 2>/dev/null`; then | 46 | if test -d .git && head=`git rev-parse --verify --short HEAD 2>/dev/null`; then |
47 | 47 | ||
48 | # If we are at a tagged commit (like "v2.6.30-rc6"), we ignore | 48 | # If we are at a tagged commit (like "v2.6.30-rc6"), we ignore |
49 | # it, because this version is defined in the top level Makefile. | 49 | # it, because this version is defined in the top level Makefile. |
@@ -85,7 +85,7 @@ scm_version() | |||
85 | fi | 85 | fi |
86 | 86 | ||
87 | # Check for mercurial and a mercurial repo. | 87 | # Check for mercurial and a mercurial repo. |
88 | if hgid=`hg id 2>/dev/null`; then | 88 | if test -d .hg && hgid=`hg id 2>/dev/null`; then |
89 | tag=`printf '%s' "$hgid" | cut -s -d' ' -f2` | 89 | tag=`printf '%s' "$hgid" | cut -s -d' ' -f2` |
90 | 90 | ||
91 | # Do we have an untagged version? | 91 | # Do we have an untagged version? |
diff --git a/security/apparmor/include/resource.h b/security/apparmor/include/resource.h index 3c88be94649..02baec732bb 100644 --- a/security/apparmor/include/resource.h +++ b/security/apparmor/include/resource.h | |||
@@ -33,8 +33,8 @@ struct aa_rlimit { | |||
33 | }; | 33 | }; |
34 | 34 | ||
35 | int aa_map_resource(int resource); | 35 | int aa_map_resource(int resource); |
36 | int aa_task_setrlimit(struct aa_profile *profile, unsigned int resource, | 36 | int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *, |
37 | struct rlimit *new_rlim); | 37 | unsigned int resource, struct rlimit *new_rlim); |
38 | 38 | ||
39 | void __aa_transition_rlimits(struct aa_profile *old, struct aa_profile *new); | 39 | void __aa_transition_rlimits(struct aa_profile *old, struct aa_profile *new); |
40 | 40 | ||
diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c index 6e85cdb4303..506d2baf614 100644 --- a/security/apparmor/lib.c +++ b/security/apparmor/lib.c | |||
@@ -40,6 +40,7 @@ char *aa_split_fqname(char *fqname, char **ns_name) | |||
40 | *ns_name = NULL; | 40 | *ns_name = NULL; |
41 | if (name[0] == ':') { | 41 | if (name[0] == ':') { |
42 | char *split = strchr(&name[1], ':'); | 42 | char *split = strchr(&name[1], ':'); |
43 | *ns_name = skip_spaces(&name[1]); | ||
43 | if (split) { | 44 | if (split) { |
44 | /* overwrite ':' with \0 */ | 45 | /* overwrite ':' with \0 */ |
45 | *split = 0; | 46 | *split = 0; |
@@ -47,7 +48,6 @@ char *aa_split_fqname(char *fqname, char **ns_name) | |||
47 | } else | 48 | } else |
48 | /* a ns name without a following profile is allowed */ | 49 | /* a ns name without a following profile is allowed */ |
49 | name = NULL; | 50 | name = NULL; |
50 | *ns_name = &name[1]; | ||
51 | } | 51 | } |
52 | if (name && *name == 0) | 52 | if (name && *name == 0) |
53 | name = NULL; | 53 | name = NULL; |
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index f73e2c20421..cf1de4462cc 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c | |||
@@ -614,7 +614,7 @@ static int apparmor_task_setrlimit(struct task_struct *task, | |||
614 | int error = 0; | 614 | int error = 0; |
615 | 615 | ||
616 | if (!unconfined(profile)) | 616 | if (!unconfined(profile)) |
617 | error = aa_task_setrlimit(profile, resource, new_rlim); | 617 | error = aa_task_setrlimit(profile, task, resource, new_rlim); |
618 | 618 | ||
619 | return error; | 619 | return error; |
620 | } | 620 | } |
diff --git a/security/apparmor/path.c b/security/apparmor/path.c index 19358dc1460..82396050f18 100644 --- a/security/apparmor/path.c +++ b/security/apparmor/path.c | |||
@@ -59,8 +59,7 @@ static int d_namespace_path(struct path *path, char *buf, int buflen, | |||
59 | { | 59 | { |
60 | struct path root, tmp; | 60 | struct path root, tmp; |
61 | char *res; | 61 | char *res; |
62 | int deleted, connected; | 62 | int connected, error = 0; |
63 | int error = 0; | ||
64 | 63 | ||
65 | /* Get the root we want to resolve too, released below */ | 64 | /* Get the root we want to resolve too, released below */ |
66 | if (flags & PATH_CHROOT_REL) { | 65 | if (flags & PATH_CHROOT_REL) { |
@@ -74,19 +73,8 @@ static int d_namespace_path(struct path *path, char *buf, int buflen, | |||
74 | } | 73 | } |
75 | 74 | ||
76 | spin_lock(&dcache_lock); | 75 | spin_lock(&dcache_lock); |
77 | /* There is a race window between path lookup here and the | 76 | tmp = root; |
78 | * need to strip the " (deleted) string that __d_path applies | 77 | res = __d_path(path, &tmp, buf, buflen); |
79 | * Detect the race and relookup the path | ||
80 | * | ||
81 | * The stripping of (deleted) is a hack that could be removed | ||
82 | * with an updated __d_path | ||
83 | */ | ||
84 | do { | ||
85 | tmp = root; | ||
86 | deleted = d_unlinked(path->dentry); | ||
87 | res = __d_path(path, &tmp, buf, buflen); | ||
88 | |||
89 | } while (deleted != d_unlinked(path->dentry)); | ||
90 | spin_unlock(&dcache_lock); | 78 | spin_unlock(&dcache_lock); |
91 | 79 | ||
92 | *name = res; | 80 | *name = res; |
@@ -98,21 +86,17 @@ static int d_namespace_path(struct path *path, char *buf, int buflen, | |||
98 | *name = buf; | 86 | *name = buf; |
99 | goto out; | 87 | goto out; |
100 | } | 88 | } |
101 | if (deleted) { | ||
102 | /* On some filesystems, newly allocated dentries appear to the | ||
103 | * security_path hooks as a deleted dentry except without an | ||
104 | * inode allocated. | ||
105 | * | ||
106 | * Remove the appended deleted text and return as string for | ||
107 | * normal mediation, or auditing. The (deleted) string is | ||
108 | * guaranteed to be added in this case, so just strip it. | ||
109 | */ | ||
110 | buf[buflen - 11] = 0; /* - (len(" (deleted)") +\0) */ | ||
111 | 89 | ||
112 | if (path->dentry->d_inode && !(flags & PATH_MEDIATE_DELETED)) { | 90 | /* Handle two cases: |
91 | * 1. A deleted dentry && profile is not allowing mediation of deleted | ||
92 | * 2. On some filesystems, newly allocated dentries appear to the | ||
93 | * security_path hooks as a deleted dentry except without an inode | ||
94 | * allocated. | ||
95 | */ | ||
96 | if (d_unlinked(path->dentry) && path->dentry->d_inode && | ||
97 | !(flags & PATH_MEDIATE_DELETED)) { | ||
113 | error = -ENOENT; | 98 | error = -ENOENT; |
114 | goto out; | 99 | goto out; |
115 | } | ||
116 | } | 100 | } |
117 | 101 | ||
118 | /* Determine if the path is connected to the expected root */ | 102 | /* Determine if the path is connected to the expected root */ |
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c index 3cdc1ad0787..52cc865f146 100644 --- a/security/apparmor/policy.c +++ b/security/apparmor/policy.c | |||
@@ -1151,12 +1151,14 @@ ssize_t aa_remove_profiles(char *fqname, size_t size) | |||
1151 | /* released below */ | 1151 | /* released below */ |
1152 | ns = aa_get_namespace(root); | 1152 | ns = aa_get_namespace(root); |
1153 | 1153 | ||
1154 | write_lock(&ns->lock); | ||
1155 | if (!name) { | 1154 | if (!name) { |
1156 | /* remove namespace - can only happen if fqname[0] == ':' */ | 1155 | /* remove namespace - can only happen if fqname[0] == ':' */ |
1156 | write_lock(&ns->parent->lock); | ||
1157 | __remove_namespace(ns); | 1157 | __remove_namespace(ns); |
1158 | write_unlock(&ns->parent->lock); | ||
1158 | } else { | 1159 | } else { |
1159 | /* remove profile */ | 1160 | /* remove profile */ |
1161 | write_lock(&ns->lock); | ||
1160 | profile = aa_get_profile(__lookup_profile(&ns->base, name)); | 1162 | profile = aa_get_profile(__lookup_profile(&ns->base, name)); |
1161 | if (!profile) { | 1163 | if (!profile) { |
1162 | error = -ENOENT; | 1164 | error = -ENOENT; |
@@ -1165,8 +1167,8 @@ ssize_t aa_remove_profiles(char *fqname, size_t size) | |||
1165 | } | 1167 | } |
1166 | name = profile->base.hname; | 1168 | name = profile->base.hname; |
1167 | __remove_profile(profile); | 1169 | __remove_profile(profile); |
1170 | write_unlock(&ns->lock); | ||
1168 | } | 1171 | } |
1169 | write_unlock(&ns->lock); | ||
1170 | 1172 | ||
1171 | /* don't fail removal if audit fails */ | 1173 | /* don't fail removal if audit fails */ |
1172 | (void) audit_policy(OP_PROF_RM, GFP_KERNEL, name, info, error); | 1174 | (void) audit_policy(OP_PROF_RM, GFP_KERNEL, name, info, error); |
diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c index 4a368f1fd36..a4136c10b1c 100644 --- a/security/apparmor/resource.c +++ b/security/apparmor/resource.c | |||
@@ -72,6 +72,7 @@ int aa_map_resource(int resource) | |||
72 | /** | 72 | /** |
73 | * aa_task_setrlimit - test permission to set an rlimit | 73 | * aa_task_setrlimit - test permission to set an rlimit |
74 | * @profile - profile confining the task (NOT NULL) | 74 | * @profile - profile confining the task (NOT NULL) |
75 | * @task - task the resource is being set on | ||
75 | * @resource - the resource being set | 76 | * @resource - the resource being set |
76 | * @new_rlim - the new resource limit (NOT NULL) | 77 | * @new_rlim - the new resource limit (NOT NULL) |
77 | * | 78 | * |
@@ -79,18 +80,21 @@ int aa_map_resource(int resource) | |||
79 | * | 80 | * |
80 | * Returns: 0 or error code if setting resource failed | 81 | * Returns: 0 or error code if setting resource failed |
81 | */ | 82 | */ |
82 | int aa_task_setrlimit(struct aa_profile *profile, unsigned int resource, | 83 | int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *task, |
83 | struct rlimit *new_rlim) | 84 | unsigned int resource, struct rlimit *new_rlim) |
84 | { | 85 | { |
85 | int error = 0; | 86 | int error = 0; |
86 | 87 | ||
87 | if (profile->rlimits.mask & (1 << resource) && | 88 | /* TODO: extend resource control to handle other (non current) |
88 | new_rlim->rlim_max > profile->rlimits.limits[resource].rlim_max) | 89 | * processes. AppArmor rules currently have the implicit assumption |
89 | 90 | * that the task is setting the resource of the current process | |
90 | error = audit_resource(profile, resource, new_rlim->rlim_max, | 91 | */ |
91 | -EACCES); | 92 | if ((task != current->group_leader) || |
93 | (profile->rlimits.mask & (1 << resource) && | ||
94 | new_rlim->rlim_max > profile->rlimits.limits[resource].rlim_max)) | ||
95 | error = -EACCES; | ||
92 | 96 | ||
93 | return error; | 97 | return audit_resource(profile, resource, new_rlim->rlim_max, error); |
94 | } | 98 | } |
95 | 99 | ||
96 | /** | 100 | /** |
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 16d100d3fc3..3fbcd1dda0e 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h | |||
@@ -35,6 +35,7 @@ enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 }; | |||
35 | #define IMA_MEASURE_HTABLE_SIZE (1 << IMA_HASH_BITS) | 35 | #define IMA_MEASURE_HTABLE_SIZE (1 << IMA_HASH_BITS) |
36 | 36 | ||
37 | /* set during initialization */ | 37 | /* set during initialization */ |
38 | extern int iint_initialized; | ||
38 | extern int ima_initialized; | 39 | extern int ima_initialized; |
39 | extern int ima_used_chip; | 40 | extern int ima_used_chip; |
40 | extern char *ima_hash; | 41 | extern char *ima_hash; |
diff --git a/security/integrity/ima/ima_iint.c b/security/integrity/ima/ima_iint.c index 7625b85c227..afba4aef812 100644 --- a/security/integrity/ima/ima_iint.c +++ b/security/integrity/ima/ima_iint.c | |||
@@ -22,9 +22,10 @@ | |||
22 | 22 | ||
23 | RADIX_TREE(ima_iint_store, GFP_ATOMIC); | 23 | RADIX_TREE(ima_iint_store, GFP_ATOMIC); |
24 | DEFINE_SPINLOCK(ima_iint_lock); | 24 | DEFINE_SPINLOCK(ima_iint_lock); |
25 | |||
26 | static struct kmem_cache *iint_cache __read_mostly; | 25 | static struct kmem_cache *iint_cache __read_mostly; |
27 | 26 | ||
27 | int iint_initialized = 0; | ||
28 | |||
28 | /* ima_iint_find_get - return the iint associated with an inode | 29 | /* ima_iint_find_get - return the iint associated with an inode |
29 | * | 30 | * |
30 | * ima_iint_find_get gets a reference to the iint. Caller must | 31 | * ima_iint_find_get gets a reference to the iint. Caller must |
@@ -141,6 +142,7 @@ static int __init ima_iintcache_init(void) | |||
141 | iint_cache = | 142 | iint_cache = |
142 | kmem_cache_create("iint_cache", sizeof(struct ima_iint_cache), 0, | 143 | kmem_cache_create("iint_cache", sizeof(struct ima_iint_cache), 0, |
143 | SLAB_PANIC, init_once); | 144 | SLAB_PANIC, init_once); |
145 | iint_initialized = 1; | ||
144 | return 0; | 146 | return 0; |
145 | } | 147 | } |
146 | security_initcall(ima_iintcache_init); | 148 | security_initcall(ima_iintcache_init); |
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index f93641382e9..e662b89d407 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c | |||
@@ -148,12 +148,14 @@ void ima_counts_get(struct file *file) | |||
148 | struct ima_iint_cache *iint; | 148 | struct ima_iint_cache *iint; |
149 | int rc; | 149 | int rc; |
150 | 150 | ||
151 | if (!ima_initialized || !S_ISREG(inode->i_mode)) | 151 | if (!iint_initialized || !S_ISREG(inode->i_mode)) |
152 | return; | 152 | return; |
153 | iint = ima_iint_find_get(inode); | 153 | iint = ima_iint_find_get(inode); |
154 | if (!iint) | 154 | if (!iint) |
155 | return; | 155 | return; |
156 | mutex_lock(&iint->mutex); | 156 | mutex_lock(&iint->mutex); |
157 | if (!ima_initialized) | ||
158 | goto out; | ||
157 | rc = ima_must_measure(iint, inode, MAY_READ, FILE_CHECK); | 159 | rc = ima_must_measure(iint, inode, MAY_READ, FILE_CHECK); |
158 | if (rc < 0) | 160 | if (rc < 0) |
159 | goto out; | 161 | goto out; |
@@ -213,7 +215,7 @@ void ima_file_free(struct file *file) | |||
213 | struct inode *inode = file->f_dentry->d_inode; | 215 | struct inode *inode = file->f_dentry->d_inode; |
214 | struct ima_iint_cache *iint; | 216 | struct ima_iint_cache *iint; |
215 | 217 | ||
216 | if (!ima_initialized || !S_ISREG(inode->i_mode)) | 218 | if (!iint_initialized || !S_ISREG(inode->i_mode)) |
217 | return; | 219 | return; |
218 | iint = ima_iint_find_get(inode); | 220 | iint = ima_iint_find_get(inode); |
219 | if (!iint) | 221 | if (!iint) |
@@ -230,7 +232,7 @@ static int process_measurement(struct file *file, const unsigned char *filename, | |||
230 | { | 232 | { |
231 | struct inode *inode = file->f_dentry->d_inode; | 233 | struct inode *inode = file->f_dentry->d_inode; |
232 | struct ima_iint_cache *iint; | 234 | struct ima_iint_cache *iint; |
233 | int rc; | 235 | int rc = 0; |
234 | 236 | ||
235 | if (!ima_initialized || !S_ISREG(inode->i_mode)) | 237 | if (!ima_initialized || !S_ISREG(inode->i_mode)) |
236 | return 0; | 238 | return 0; |
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index b2b0998d6ab..60924f6a52d 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c | |||
@@ -1272,6 +1272,7 @@ long keyctl_session_to_parent(void) | |||
1272 | keyring_r = NULL; | 1272 | keyring_r = NULL; |
1273 | 1273 | ||
1274 | me = current; | 1274 | me = current; |
1275 | rcu_read_lock(); | ||
1275 | write_lock_irq(&tasklist_lock); | 1276 | write_lock_irq(&tasklist_lock); |
1276 | 1277 | ||
1277 | parent = me->real_parent; | 1278 | parent = me->real_parent; |
@@ -1304,7 +1305,8 @@ long keyctl_session_to_parent(void) | |||
1304 | goto not_permitted; | 1305 | goto not_permitted; |
1305 | 1306 | ||
1306 | /* the keyrings must have the same UID */ | 1307 | /* the keyrings must have the same UID */ |
1307 | if (pcred->tgcred->session_keyring->uid != mycred->euid || | 1308 | if ((pcred->tgcred->session_keyring && |
1309 | pcred->tgcred->session_keyring->uid != mycred->euid) || | ||
1308 | mycred->tgcred->session_keyring->uid != mycred->euid) | 1310 | mycred->tgcred->session_keyring->uid != mycred->euid) |
1309 | goto not_permitted; | 1311 | goto not_permitted; |
1310 | 1312 | ||
@@ -1319,6 +1321,7 @@ long keyctl_session_to_parent(void) | |||
1319 | set_ti_thread_flag(task_thread_info(parent), TIF_NOTIFY_RESUME); | 1321 | set_ti_thread_flag(task_thread_info(parent), TIF_NOTIFY_RESUME); |
1320 | 1322 | ||
1321 | write_unlock_irq(&tasklist_lock); | 1323 | write_unlock_irq(&tasklist_lock); |
1324 | rcu_read_unlock(); | ||
1322 | if (oldcred) | 1325 | if (oldcred) |
1323 | put_cred(oldcred); | 1326 | put_cred(oldcred); |
1324 | return 0; | 1327 | return 0; |
@@ -1327,6 +1330,7 @@ already_same: | |||
1327 | ret = 0; | 1330 | ret = 0; |
1328 | not_permitted: | 1331 | not_permitted: |
1329 | write_unlock_irq(&tasklist_lock); | 1332 | write_unlock_irq(&tasklist_lock); |
1333 | rcu_read_unlock(); | ||
1330 | put_cred(cred); | 1334 | put_cred(cred); |
1331 | return ret; | 1335 | return ret; |
1332 | 1336 | ||
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index ef43995119a..c668b447c72 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c | |||
@@ -1416,15 +1416,19 @@ static char *tomoyo_print_header(struct tomoyo_request_info *r) | |||
1416 | const pid_t gpid = task_pid_nr(current); | 1416 | const pid_t gpid = task_pid_nr(current); |
1417 | static const int tomoyo_buffer_len = 4096; | 1417 | static const int tomoyo_buffer_len = 4096; |
1418 | char *buffer = kmalloc(tomoyo_buffer_len, GFP_NOFS); | 1418 | char *buffer = kmalloc(tomoyo_buffer_len, GFP_NOFS); |
1419 | pid_t ppid; | ||
1419 | if (!buffer) | 1420 | if (!buffer) |
1420 | return NULL; | 1421 | return NULL; |
1421 | do_gettimeofday(&tv); | 1422 | do_gettimeofday(&tv); |
1423 | rcu_read_lock(); | ||
1424 | ppid = task_tgid_vnr(current->real_parent); | ||
1425 | rcu_read_unlock(); | ||
1422 | snprintf(buffer, tomoyo_buffer_len - 1, | 1426 | snprintf(buffer, tomoyo_buffer_len - 1, |
1423 | "#timestamp=%lu profile=%u mode=%s (global-pid=%u)" | 1427 | "#timestamp=%lu profile=%u mode=%s (global-pid=%u)" |
1424 | " task={ pid=%u ppid=%u uid=%u gid=%u euid=%u" | 1428 | " task={ pid=%u ppid=%u uid=%u gid=%u euid=%u" |
1425 | " egid=%u suid=%u sgid=%u fsuid=%u fsgid=%u }", | 1429 | " egid=%u suid=%u sgid=%u fsuid=%u fsgid=%u }", |
1426 | tv.tv_sec, r->profile, tomoyo_mode[r->mode], gpid, | 1430 | tv.tv_sec, r->profile, tomoyo_mode[r->mode], gpid, |
1427 | (pid_t) sys_getpid(), (pid_t) sys_getppid(), | 1431 | task_tgid_vnr(current), ppid, |
1428 | current_uid(), current_gid(), current_euid(), | 1432 | current_uid(), current_gid(), current_euid(), |
1429 | current_egid(), current_suid(), current_sgid(), | 1433 | current_egid(), current_suid(), current_sgid(), |
1430 | current_fsuid(), current_fsgid()); | 1434 | current_fsuid(), current_fsgid()); |
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h index 04454cb7b24..7c66bd89878 100644 --- a/security/tomoyo/common.h +++ b/security/tomoyo/common.h | |||
@@ -689,9 +689,6 @@ struct tomoyo_profile { | |||
689 | 689 | ||
690 | /********** Function prototypes. **********/ | 690 | /********** Function prototypes. **********/ |
691 | 691 | ||
692 | extern asmlinkage long sys_getpid(void); | ||
693 | extern asmlinkage long sys_getppid(void); | ||
694 | |||
695 | /* Check whether the given string starts with the given keyword. */ | 692 | /* Check whether the given string starts with the given keyword. */ |
696 | bool tomoyo_str_starts(char **src, const char *find); | 693 | bool tomoyo_str_starts(char **src, const char *find); |
697 | /* Get tomoyo_realpath() of current process. */ | 694 | /* Get tomoyo_realpath() of current process. */ |
diff --git a/sound/core/control.c b/sound/core/control.c index 070aab49019..45a818002d9 100644 --- a/sound/core/control.c +++ b/sound/core/control.c | |||
@@ -31,6 +31,7 @@ | |||
31 | 31 | ||
32 | /* max number of user-defined controls */ | 32 | /* max number of user-defined controls */ |
33 | #define MAX_USER_CONTROLS 32 | 33 | #define MAX_USER_CONTROLS 32 |
34 | #define MAX_CONTROL_COUNT 1028 | ||
34 | 35 | ||
35 | struct snd_kctl_ioctl { | 36 | struct snd_kctl_ioctl { |
36 | struct list_head list; /* list of all ioctls */ | 37 | struct list_head list; /* list of all ioctls */ |
@@ -195,6 +196,10 @@ static struct snd_kcontrol *snd_ctl_new(struct snd_kcontrol *control, | |||
195 | 196 | ||
196 | if (snd_BUG_ON(!control || !control->count)) | 197 | if (snd_BUG_ON(!control || !control->count)) |
197 | return NULL; | 198 | return NULL; |
199 | |||
200 | if (control->count > MAX_CONTROL_COUNT) | ||
201 | return NULL; | ||
202 | |||
198 | kctl = kzalloc(sizeof(*kctl) + sizeof(struct snd_kcontrol_volatile) * control->count, GFP_KERNEL); | 203 | kctl = kzalloc(sizeof(*kctl) + sizeof(struct snd_kcontrol_volatile) * control->count, GFP_KERNEL); |
199 | if (kctl == NULL) { | 204 | if (kctl == NULL) { |
200 | snd_printk(KERN_ERR "Cannot allocate control instance\n"); | 205 | snd_printk(KERN_ERR "Cannot allocate control instance\n"); |
diff --git a/sound/core/pcm.c b/sound/core/pcm.c index cbe815dfbdc..ac242a377ae 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c | |||
@@ -203,10 +203,16 @@ static char *snd_pcm_format_names[] = { | |||
203 | FORMAT(S18_3BE), | 203 | FORMAT(S18_3BE), |
204 | FORMAT(U18_3LE), | 204 | FORMAT(U18_3LE), |
205 | FORMAT(U18_3BE), | 205 | FORMAT(U18_3BE), |
206 | FORMAT(G723_24), | ||
207 | FORMAT(G723_24_1B), | ||
208 | FORMAT(G723_40), | ||
209 | FORMAT(G723_40_1B), | ||
206 | }; | 210 | }; |
207 | 211 | ||
208 | const char *snd_pcm_format_name(snd_pcm_format_t format) | 212 | const char *snd_pcm_format_name(snd_pcm_format_t format) |
209 | { | 213 | { |
214 | if (format >= ARRAY_SIZE(snd_pcm_format_names)) | ||
215 | return "Unknown"; | ||
210 | return snd_pcm_format_names[format]; | 216 | return snd_pcm_format_names[format]; |
211 | } | 217 | } |
212 | EXPORT_SYMBOL_GPL(snd_pcm_format_name); | 218 | EXPORT_SYMBOL_GPL(snd_pcm_format_name); |
@@ -366,14 +372,17 @@ static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry, | |||
366 | struct snd_info_buffer *buffer) | 372 | struct snd_info_buffer *buffer) |
367 | { | 373 | { |
368 | struct snd_pcm_substream *substream = entry->private_data; | 374 | struct snd_pcm_substream *substream = entry->private_data; |
369 | struct snd_pcm_runtime *runtime = substream->runtime; | 375 | struct snd_pcm_runtime *runtime; |
376 | |||
377 | mutex_lock(&substream->pcm->open_mutex); | ||
378 | runtime = substream->runtime; | ||
370 | if (!runtime) { | 379 | if (!runtime) { |
371 | snd_iprintf(buffer, "closed\n"); | 380 | snd_iprintf(buffer, "closed\n"); |
372 | return; | 381 | goto unlock; |
373 | } | 382 | } |
374 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { | 383 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { |
375 | snd_iprintf(buffer, "no setup\n"); | 384 | snd_iprintf(buffer, "no setup\n"); |
376 | return; | 385 | goto unlock; |
377 | } | 386 | } |
378 | snd_iprintf(buffer, "access: %s\n", snd_pcm_access_name(runtime->access)); | 387 | snd_iprintf(buffer, "access: %s\n", snd_pcm_access_name(runtime->access)); |
379 | snd_iprintf(buffer, "format: %s\n", snd_pcm_format_name(runtime->format)); | 388 | snd_iprintf(buffer, "format: %s\n", snd_pcm_format_name(runtime->format)); |
@@ -392,20 +401,25 @@ static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry, | |||
392 | snd_iprintf(buffer, "OSS period frames: %lu\n", (unsigned long)runtime->oss.period_frames); | 401 | snd_iprintf(buffer, "OSS period frames: %lu\n", (unsigned long)runtime->oss.period_frames); |
393 | } | 402 | } |
394 | #endif | 403 | #endif |
404 | unlock: | ||
405 | mutex_unlock(&substream->pcm->open_mutex); | ||
395 | } | 406 | } |
396 | 407 | ||
397 | static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry, | 408 | static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry, |
398 | struct snd_info_buffer *buffer) | 409 | struct snd_info_buffer *buffer) |
399 | { | 410 | { |
400 | struct snd_pcm_substream *substream = entry->private_data; | 411 | struct snd_pcm_substream *substream = entry->private_data; |
401 | struct snd_pcm_runtime *runtime = substream->runtime; | 412 | struct snd_pcm_runtime *runtime; |
413 | |||
414 | mutex_lock(&substream->pcm->open_mutex); | ||
415 | runtime = substream->runtime; | ||
402 | if (!runtime) { | 416 | if (!runtime) { |
403 | snd_iprintf(buffer, "closed\n"); | 417 | snd_iprintf(buffer, "closed\n"); |
404 | return; | 418 | goto unlock; |
405 | } | 419 | } |
406 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { | 420 | if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { |
407 | snd_iprintf(buffer, "no setup\n"); | 421 | snd_iprintf(buffer, "no setup\n"); |
408 | return; | 422 | goto unlock; |
409 | } | 423 | } |
410 | snd_iprintf(buffer, "tstamp_mode: %s\n", snd_pcm_tstamp_mode_name(runtime->tstamp_mode)); | 424 | snd_iprintf(buffer, "tstamp_mode: %s\n", snd_pcm_tstamp_mode_name(runtime->tstamp_mode)); |
411 | snd_iprintf(buffer, "period_step: %u\n", runtime->period_step); | 425 | snd_iprintf(buffer, "period_step: %u\n", runtime->period_step); |
@@ -415,24 +429,29 @@ static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry, | |||
415 | snd_iprintf(buffer, "silence_threshold: %lu\n", runtime->silence_threshold); | 429 | snd_iprintf(buffer, "silence_threshold: %lu\n", runtime->silence_threshold); |
416 | snd_iprintf(buffer, "silence_size: %lu\n", runtime->silence_size); | 430 | snd_iprintf(buffer, "silence_size: %lu\n", runtime->silence_size); |
417 | snd_iprintf(buffer, "boundary: %lu\n", runtime->boundary); | 431 | snd_iprintf(buffer, "boundary: %lu\n", runtime->boundary); |
432 | unlock: | ||
433 | mutex_unlock(&substream->pcm->open_mutex); | ||
418 | } | 434 | } |
419 | 435 | ||
420 | static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry, | 436 | static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry, |
421 | struct snd_info_buffer *buffer) | 437 | struct snd_info_buffer *buffer) |
422 | { | 438 | { |
423 | struct snd_pcm_substream *substream = entry->private_data; | 439 | struct snd_pcm_substream *substream = entry->private_data; |
424 | struct snd_pcm_runtime *runtime = substream->runtime; | 440 | struct snd_pcm_runtime *runtime; |
425 | struct snd_pcm_status status; | 441 | struct snd_pcm_status status; |
426 | int err; | 442 | int err; |
443 | |||
444 | mutex_lock(&substream->pcm->open_mutex); | ||
445 | runtime = substream->runtime; | ||
427 | if (!runtime) { | 446 | if (!runtime) { |
428 | snd_iprintf(buffer, "closed\n"); | 447 | snd_iprintf(buffer, "closed\n"); |
429 | return; | 448 | goto unlock; |
430 | } | 449 | } |
431 | memset(&status, 0, sizeof(status)); | 450 | memset(&status, 0, sizeof(status)); |
432 | err = snd_pcm_status(substream, &status); | 451 | err = snd_pcm_status(substream, &status); |
433 | if (err < 0) { | 452 | if (err < 0) { |
434 | snd_iprintf(buffer, "error %d\n", err); | 453 | snd_iprintf(buffer, "error %d\n", err); |
435 | return; | 454 | goto unlock; |
436 | } | 455 | } |
437 | snd_iprintf(buffer, "state: %s\n", snd_pcm_state_name(status.state)); | 456 | snd_iprintf(buffer, "state: %s\n", snd_pcm_state_name(status.state)); |
438 | snd_iprintf(buffer, "owner_pid : %d\n", pid_vnr(substream->pid)); | 457 | snd_iprintf(buffer, "owner_pid : %d\n", pid_vnr(substream->pid)); |
@@ -446,6 +465,8 @@ static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry, | |||
446 | snd_iprintf(buffer, "-----\n"); | 465 | snd_iprintf(buffer, "-----\n"); |
447 | snd_iprintf(buffer, "hw_ptr : %ld\n", runtime->status->hw_ptr); | 466 | snd_iprintf(buffer, "hw_ptr : %ld\n", runtime->status->hw_ptr); |
448 | snd_iprintf(buffer, "appl_ptr : %ld\n", runtime->control->appl_ptr); | 467 | snd_iprintf(buffer, "appl_ptr : %ld\n", runtime->control->appl_ptr); |
468 | unlock: | ||
469 | mutex_unlock(&substream->pcm->open_mutex); | ||
449 | } | 470 | } |
450 | 471 | ||
451 | #ifdef CONFIG_SND_PCM_XRUN_DEBUG | 472 | #ifdef CONFIG_SND_PCM_XRUN_DEBUG |
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 134fc6c2e08..d4eb2ef8078 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
@@ -1992,6 +1992,8 @@ void snd_pcm_release_substream(struct snd_pcm_substream *substream) | |||
1992 | substream->ops->close(substream); | 1992 | substream->ops->close(substream); |
1993 | substream->hw_opened = 0; | 1993 | substream->hw_opened = 0; |
1994 | } | 1994 | } |
1995 | if (pm_qos_request_active(&substream->latency_pm_qos_req)) | ||
1996 | pm_qos_remove_request(&substream->latency_pm_qos_req); | ||
1995 | if (substream->pcm_release) { | 1997 | if (substream->pcm_release) { |
1996 | substream->pcm_release(substream); | 1998 | substream->pcm_release(substream); |
1997 | substream->pcm_release = NULL; | 1999 | substream->pcm_release = NULL; |
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index eb68326c37d..a7868ad4d53 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c | |||
@@ -829,6 +829,8 @@ static int snd_rawmidi_control_ioctl(struct snd_card *card, | |||
829 | 829 | ||
830 | if (get_user(device, (int __user *)argp)) | 830 | if (get_user(device, (int __user *)argp)) |
831 | return -EFAULT; | 831 | return -EFAULT; |
832 | if (device >= SNDRV_RAWMIDI_DEVICES) /* next device is -1 */ | ||
833 | device = SNDRV_RAWMIDI_DEVICES - 1; | ||
832 | mutex_lock(®ister_mutex); | 834 | mutex_lock(®ister_mutex); |
833 | device = device < 0 ? 0 : device + 1; | 835 | device = device < 0 ? 0 : device + 1; |
834 | while (device < SNDRV_RAWMIDI_DEVICES) { | 836 | while (device < SNDRV_RAWMIDI_DEVICES) { |
diff --git a/sound/core/seq/oss/seq_oss_init.c b/sound/core/seq/oss/seq_oss_init.c index 685712276ac..69cd7b3c362 100644 --- a/sound/core/seq/oss/seq_oss_init.c +++ b/sound/core/seq/oss/seq_oss_init.c | |||
@@ -281,13 +281,10 @@ snd_seq_oss_open(struct file *file, int level) | |||
281 | return 0; | 281 | return 0; |
282 | 282 | ||
283 | _error: | 283 | _error: |
284 | snd_seq_oss_writeq_delete(dp->writeq); | ||
285 | snd_seq_oss_readq_delete(dp->readq); | ||
286 | snd_seq_oss_synth_cleanup(dp); | 284 | snd_seq_oss_synth_cleanup(dp); |
287 | snd_seq_oss_midi_cleanup(dp); | 285 | snd_seq_oss_midi_cleanup(dp); |
288 | delete_port(dp); | ||
289 | delete_seq_queue(dp->queue); | 286 | delete_seq_queue(dp->queue); |
290 | kfree(dp); | 287 | delete_port(dp); |
291 | 288 | ||
292 | return rc; | 289 | return rc; |
293 | } | 290 | } |
@@ -350,8 +347,10 @@ create_port(struct seq_oss_devinfo *dp) | |||
350 | static int | 347 | static int |
351 | delete_port(struct seq_oss_devinfo *dp) | 348 | delete_port(struct seq_oss_devinfo *dp) |
352 | { | 349 | { |
353 | if (dp->port < 0) | 350 | if (dp->port < 0) { |
351 | kfree(dp); | ||
354 | return 0; | 352 | return 0; |
353 | } | ||
355 | 354 | ||
356 | debug_printk(("delete_port %i\n", dp->port)); | 355 | debug_printk(("delete_port %i\n", dp->port)); |
357 | return snd_seq_event_port_detach(dp->cseq, dp->port); | 356 | return snd_seq_event_port_detach(dp->cseq, dp->port); |
diff --git a/sound/i2c/other/ak4xxx-adda.c b/sound/i2c/other/ak4xxx-adda.c index 1adb8a3c2b6..42d7844ecd0 100644 --- a/sound/i2c/other/ak4xxx-adda.c +++ b/sound/i2c/other/ak4xxx-adda.c | |||
@@ -900,7 +900,7 @@ static int proc_init(struct snd_akm4xxx *ak) | |||
900 | return 0; | 900 | return 0; |
901 | } | 901 | } |
902 | #else /* !CONFIG_PROC_FS */ | 902 | #else /* !CONFIG_PROC_FS */ |
903 | static int proc_init(struct snd_akm4xxx *ak) {} | 903 | static int proc_init(struct snd_akm4xxx *ak) { return 0; } |
904 | #endif | 904 | #endif |
905 | 905 | ||
906 | int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak) | 906 | int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak) |
diff --git a/sound/isa/msnd/msnd_pinnacle.c b/sound/isa/msnd/msnd_pinnacle.c index 5f3e68401f9..91d6023a63e 100644 --- a/sound/isa/msnd/msnd_pinnacle.c +++ b/sound/isa/msnd/msnd_pinnacle.c | |||
@@ -764,9 +764,9 @@ static long io[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; | |||
764 | static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; | 764 | static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; |
765 | static long mem[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; | 765 | static long mem[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; |
766 | 766 | ||
767 | #ifndef MSND_CLASSIC | ||
767 | static long cfg[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; | 768 | static long cfg[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; |
768 | 769 | ||
769 | #ifndef MSND_CLASSIC | ||
770 | /* Extra Peripheral Configuration (Default: Disable) */ | 770 | /* Extra Peripheral Configuration (Default: Disable) */ |
771 | static long ide_io0[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; | 771 | static long ide_io0[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; |
772 | static long ide_io1[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; | 772 | static long ide_io1[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; |
@@ -894,7 +894,11 @@ static int __devinit snd_msnd_isa_probe(struct device *pdev, unsigned int idx) | |||
894 | struct snd_card *card; | 894 | struct snd_card *card; |
895 | struct snd_msnd *chip; | 895 | struct snd_msnd *chip; |
896 | 896 | ||
897 | if (has_isapnp(idx) || cfg[idx] == SNDRV_AUTO_PORT) { | 897 | if (has_isapnp(idx) |
898 | #ifndef MSND_CLASSIC | ||
899 | || cfg[idx] == SNDRV_AUTO_PORT | ||
900 | #endif | ||
901 | ) { | ||
898 | printk(KERN_INFO LOGNAME ": Assuming PnP mode\n"); | 902 | printk(KERN_INFO LOGNAME ": Assuming PnP mode\n"); |
899 | return -ENODEV; | 903 | return -ENODEV; |
900 | } | 904 | } |
diff --git a/sound/oss/sound_timer.c b/sound/oss/sound_timer.c index f0f0c19fbff..48cda6c4c25 100644 --- a/sound/oss/sound_timer.c +++ b/sound/oss/sound_timer.c | |||
@@ -26,7 +26,7 @@ static unsigned long prev_event_time; | |||
26 | static volatile unsigned long usecs_per_tmr; /* Length of the current interval */ | 26 | static volatile unsigned long usecs_per_tmr; /* Length of the current interval */ |
27 | 27 | ||
28 | static struct sound_lowlev_timer *tmr; | 28 | static struct sound_lowlev_timer *tmr; |
29 | static spinlock_t lock; | 29 | static DEFINE_SPINLOCK(lock); |
30 | 30 | ||
31 | static unsigned long tmr2ticks(int tmr_value) | 31 | static unsigned long tmr2ticks(int tmr_value) |
32 | { | 32 | { |
diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c index 92aa762ffb7..07f803e6d20 100644 --- a/sound/oss/soundcard.c +++ b/sound/oss/soundcard.c | |||
@@ -391,11 +391,11 @@ static long sound_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
391 | case SND_DEV_DSP: | 391 | case SND_DEV_DSP: |
392 | case SND_DEV_DSP16: | 392 | case SND_DEV_DSP16: |
393 | case SND_DEV_AUDIO: | 393 | case SND_DEV_AUDIO: |
394 | return audio_ioctl(dev, file, cmd, p); | 394 | ret = audio_ioctl(dev, file, cmd, p); |
395 | break; | 395 | break; |
396 | 396 | ||
397 | case SND_DEV_MIDIN: | 397 | case SND_DEV_MIDIN: |
398 | return MIDIbuf_ioctl(dev, file, cmd, p); | 398 | ret = MIDIbuf_ioctl(dev, file, cmd, p); |
399 | break; | 399 | break; |
400 | 400 | ||
401 | } | 401 | } |
diff --git a/sound/pci/asihpi/hpi6205.c b/sound/pci/asihpi/hpi6205.c index 3b441344822..22c5fc62553 100644 --- a/sound/pci/asihpi/hpi6205.c +++ b/sound/pci/asihpi/hpi6205.c | |||
@@ -941,8 +941,7 @@ static void outstream_host_buffer_free(struct hpi_adapter_obj *pao, | |||
941 | 941 | ||
942 | } | 942 | } |
943 | 943 | ||
944 | static u32 outstream_get_space_available(struct hpi_hostbuffer_status | 944 | static u32 outstream_get_space_available(struct hpi_hostbuffer_status *status) |
945 | *status) | ||
946 | { | 945 | { |
947 | return status->size_in_bytes - (status->host_index - | 946 | return status->size_in_bytes - (status->host_index - |
948 | status->dSP_index); | 947 | status->dSP_index); |
@@ -987,6 +986,10 @@ static void outstream_write(struct hpi_adapter_obj *pao, | |||
987 | /* write it */ | 986 | /* write it */ |
988 | phm->function = HPI_OSTREAM_WRITE; | 987 | phm->function = HPI_OSTREAM_WRITE; |
989 | hw_message(pao, phm, phr); | 988 | hw_message(pao, phm, phr); |
989 | |||
990 | if (phr->error) | ||
991 | return; | ||
992 | |||
990 | /* update status information that the DSP would typically | 993 | /* update status information that the DSP would typically |
991 | * update (and will update next time the DSP | 994 | * update (and will update next time the DSP |
992 | * buffer update task reads data from the host BBM buffer) | 995 | * buffer update task reads data from the host BBM buffer) |
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index dd8fb86c842..14829210ef0 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -589,6 +589,7 @@ int /*__devinit*/ snd_hda_bus_new(struct snd_card *card, | |||
589 | bus->ops = temp->ops; | 589 | bus->ops = temp->ops; |
590 | 590 | ||
591 | mutex_init(&bus->cmd_mutex); | 591 | mutex_init(&bus->cmd_mutex); |
592 | mutex_init(&bus->prepare_mutex); | ||
592 | INIT_LIST_HEAD(&bus->codec_list); | 593 | INIT_LIST_HEAD(&bus->codec_list); |
593 | 594 | ||
594 | snprintf(bus->workq_name, sizeof(bus->workq_name), | 595 | snprintf(bus->workq_name, sizeof(bus->workq_name), |
@@ -1068,7 +1069,6 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, | |||
1068 | codec->addr = codec_addr; | 1069 | codec->addr = codec_addr; |
1069 | mutex_init(&codec->spdif_mutex); | 1070 | mutex_init(&codec->spdif_mutex); |
1070 | mutex_init(&codec->control_mutex); | 1071 | mutex_init(&codec->control_mutex); |
1071 | mutex_init(&codec->prepare_mutex); | ||
1072 | init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info)); | 1072 | init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info)); |
1073 | init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head)); | 1073 | init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head)); |
1074 | snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32); | 1074 | snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32); |
@@ -1213,6 +1213,7 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, | |||
1213 | u32 stream_tag, | 1213 | u32 stream_tag, |
1214 | int channel_id, int format) | 1214 | int channel_id, int format) |
1215 | { | 1215 | { |
1216 | struct hda_codec *c; | ||
1216 | struct hda_cvt_setup *p; | 1217 | struct hda_cvt_setup *p; |
1217 | unsigned int oldval, newval; | 1218 | unsigned int oldval, newval; |
1218 | int i; | 1219 | int i; |
@@ -1253,10 +1254,12 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, | |||
1253 | p->dirty = 0; | 1254 | p->dirty = 0; |
1254 | 1255 | ||
1255 | /* make other inactive cvts with the same stream-tag dirty */ | 1256 | /* make other inactive cvts with the same stream-tag dirty */ |
1256 | for (i = 0; i < codec->cvt_setups.used; i++) { | 1257 | list_for_each_entry(c, &codec->bus->codec_list, list) { |
1257 | p = snd_array_elem(&codec->cvt_setups, i); | 1258 | for (i = 0; i < c->cvt_setups.used; i++) { |
1258 | if (!p->active && p->stream_tag == stream_tag) | 1259 | p = snd_array_elem(&c->cvt_setups, i); |
1259 | p->dirty = 1; | 1260 | if (!p->active && p->stream_tag == stream_tag) |
1261 | p->dirty = 1; | ||
1262 | } | ||
1260 | } | 1263 | } |
1261 | } | 1264 | } |
1262 | EXPORT_SYMBOL_HDA(snd_hda_codec_setup_stream); | 1265 | EXPORT_SYMBOL_HDA(snd_hda_codec_setup_stream); |
@@ -1306,12 +1309,16 @@ static void really_cleanup_stream(struct hda_codec *codec, | |||
1306 | /* clean up the all conflicting obsolete streams */ | 1309 | /* clean up the all conflicting obsolete streams */ |
1307 | static void purify_inactive_streams(struct hda_codec *codec) | 1310 | static void purify_inactive_streams(struct hda_codec *codec) |
1308 | { | 1311 | { |
1312 | struct hda_codec *c; | ||
1309 | int i; | 1313 | int i; |
1310 | 1314 | ||
1311 | for (i = 0; i < codec->cvt_setups.used; i++) { | 1315 | list_for_each_entry(c, &codec->bus->codec_list, list) { |
1312 | struct hda_cvt_setup *p = snd_array_elem(&codec->cvt_setups, i); | 1316 | for (i = 0; i < c->cvt_setups.used; i++) { |
1313 | if (p->dirty) | 1317 | struct hda_cvt_setup *p; |
1314 | really_cleanup_stream(codec, p); | 1318 | p = snd_array_elem(&c->cvt_setups, i); |
1319 | if (p->dirty) | ||
1320 | really_cleanup_stream(c, p); | ||
1321 | } | ||
1315 | } | 1322 | } |
1316 | } | 1323 | } |
1317 | 1324 | ||
@@ -3502,11 +3509,11 @@ int snd_hda_codec_prepare(struct hda_codec *codec, | |||
3502 | struct snd_pcm_substream *substream) | 3509 | struct snd_pcm_substream *substream) |
3503 | { | 3510 | { |
3504 | int ret; | 3511 | int ret; |
3505 | mutex_lock(&codec->prepare_mutex); | 3512 | mutex_lock(&codec->bus->prepare_mutex); |
3506 | ret = hinfo->ops.prepare(hinfo, codec, stream, format, substream); | 3513 | ret = hinfo->ops.prepare(hinfo, codec, stream, format, substream); |
3507 | if (ret >= 0) | 3514 | if (ret >= 0) |
3508 | purify_inactive_streams(codec); | 3515 | purify_inactive_streams(codec); |
3509 | mutex_unlock(&codec->prepare_mutex); | 3516 | mutex_unlock(&codec->bus->prepare_mutex); |
3510 | return ret; | 3517 | return ret; |
3511 | } | 3518 | } |
3512 | EXPORT_SYMBOL_HDA(snd_hda_codec_prepare); | 3519 | EXPORT_SYMBOL_HDA(snd_hda_codec_prepare); |
@@ -3515,9 +3522,9 @@ void snd_hda_codec_cleanup(struct hda_codec *codec, | |||
3515 | struct hda_pcm_stream *hinfo, | 3522 | struct hda_pcm_stream *hinfo, |
3516 | struct snd_pcm_substream *substream) | 3523 | struct snd_pcm_substream *substream) |
3517 | { | 3524 | { |
3518 | mutex_lock(&codec->prepare_mutex); | 3525 | mutex_lock(&codec->bus->prepare_mutex); |
3519 | hinfo->ops.cleanup(hinfo, codec, substream); | 3526 | hinfo->ops.cleanup(hinfo, codec, substream); |
3520 | mutex_unlock(&codec->prepare_mutex); | 3527 | mutex_unlock(&codec->bus->prepare_mutex); |
3521 | } | 3528 | } |
3522 | EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup); | 3529 | EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup); |
3523 | 3530 | ||
@@ -4529,7 +4536,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, | |||
4529 | cfg->hp_outs--; | 4536 | cfg->hp_outs--; |
4530 | memmove(cfg->hp_pins + i, cfg->hp_pins + i + 1, | 4537 | memmove(cfg->hp_pins + i, cfg->hp_pins + i + 1, |
4531 | sizeof(cfg->hp_pins[0]) * (cfg->hp_outs - i)); | 4538 | sizeof(cfg->hp_pins[0]) * (cfg->hp_outs - i)); |
4532 | memmove(sequences_hp + i - 1, sequences_hp + i, | 4539 | memmove(sequences_hp + i, sequences_hp + i + 1, |
4533 | sizeof(sequences_hp[0]) * (cfg->hp_outs - i)); | 4540 | sizeof(sequences_hp[0]) * (cfg->hp_outs - i)); |
4534 | } | 4541 | } |
4535 | } | 4542 | } |
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 4303353feda..62c70224010 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -648,6 +648,7 @@ struct hda_bus { | |||
648 | struct hda_codec *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1]; | 648 | struct hda_codec *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1]; |
649 | 649 | ||
650 | struct mutex cmd_mutex; | 650 | struct mutex cmd_mutex; |
651 | struct mutex prepare_mutex; | ||
651 | 652 | ||
652 | /* unsolicited event queue */ | 653 | /* unsolicited event queue */ |
653 | struct hda_bus_unsolicited *unsol; | 654 | struct hda_bus_unsolicited *unsol; |
@@ -826,7 +827,6 @@ struct hda_codec { | |||
826 | 827 | ||
827 | struct mutex spdif_mutex; | 828 | struct mutex spdif_mutex; |
828 | struct mutex control_mutex; | 829 | struct mutex control_mutex; |
829 | struct mutex prepare_mutex; | ||
830 | unsigned int spdif_status; /* IEC958 status bits */ | 830 | unsigned int spdif_status; /* IEC958 status bits */ |
831 | unsigned short spdif_ctls; /* SPDIF control bits */ | 831 | unsigned short spdif_ctls; /* SPDIF control bits */ |
832 | unsigned int spdif_in_enable; /* SPDIF input enable? */ | 832 | unsigned int spdif_in_enable; /* SPDIF input enable? */ |
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c index 803b298f741..26c3ade7358 100644 --- a/sound/pci/hda/hda_eld.c +++ b/sound/pci/hda/hda_eld.c | |||
@@ -596,6 +596,8 @@ void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld) | |||
596 | } | 596 | } |
597 | EXPORT_SYMBOL_HDA(snd_hda_eld_proc_free); | 597 | EXPORT_SYMBOL_HDA(snd_hda_eld_proc_free); |
598 | 598 | ||
599 | #endif /* CONFIG_PROC_FS */ | ||
600 | |||
599 | /* update PCM info based on ELD */ | 601 | /* update PCM info based on ELD */ |
600 | void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm, | 602 | void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm, |
601 | struct hda_pcm_stream *codec_pars) | 603 | struct hda_pcm_stream *codec_pars) |
@@ -644,5 +646,3 @@ void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm, | |||
644 | pcm->maxbps = min(pcm->maxbps, codec_pars->maxbps); | 646 | pcm->maxbps = min(pcm->maxbps, codec_pars->maxbps); |
645 | } | 647 | } |
646 | EXPORT_SYMBOL_HDA(hdmi_eld_update_pcm_info); | 648 | EXPORT_SYMBOL_HDA(hdmi_eld_update_pcm_info); |
647 | |||
648 | #endif /* CONFIG_PROC_FS */ | ||
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 1053fff4bd0..34940a07905 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -126,6 +126,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," | |||
126 | "{Intel, ICH10}," | 126 | "{Intel, ICH10}," |
127 | "{Intel, PCH}," | 127 | "{Intel, PCH}," |
128 | "{Intel, CPT}," | 128 | "{Intel, CPT}," |
129 | "{Intel, PBG}," | ||
129 | "{Intel, SCH}," | 130 | "{Intel, SCH}," |
130 | "{ATI, SB450}," | 131 | "{ATI, SB450}," |
131 | "{ATI, SB600}," | 132 | "{ATI, SB600}," |
@@ -2749,6 +2750,8 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { | |||
2749 | { PCI_DEVICE(0x8086, 0x3b57), .driver_data = AZX_DRIVER_ICH }, | 2750 | { PCI_DEVICE(0x8086, 0x3b57), .driver_data = AZX_DRIVER_ICH }, |
2750 | /* CPT */ | 2751 | /* CPT */ |
2751 | { PCI_DEVICE(0x8086, 0x1c20), .driver_data = AZX_DRIVER_PCH }, | 2752 | { PCI_DEVICE(0x8086, 0x1c20), .driver_data = AZX_DRIVER_PCH }, |
2753 | /* PBG */ | ||
2754 | { PCI_DEVICE(0x8086, 0x1d20), .driver_data = AZX_DRIVER_PCH }, | ||
2752 | /* SCH */ | 2755 | /* SCH */ |
2753 | { PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH }, | 2756 | { PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH }, |
2754 | /* ATI SB 450/600 */ | 2757 | /* ATI SB 450/600 */ |
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index b697fd2a6f8..10bbbaf6ebc 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -3641,6 +3641,7 @@ static struct snd_pci_quirk ad1984_cfg_tbl[] = { | |||
3641 | /* Lenovo Thinkpad T61/X61 */ | 3641 | /* Lenovo Thinkpad T61/X61 */ |
3642 | SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1984_THINKPAD), | 3642 | SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1984_THINKPAD), |
3643 | SND_PCI_QUIRK(0x1028, 0x0214, "Dell T3400", AD1984_DELL_DESKTOP), | 3643 | SND_PCI_QUIRK(0x1028, 0x0214, "Dell T3400", AD1984_DELL_DESKTOP), |
3644 | SND_PCI_QUIRK(0x1028, 0x0233, "Dell Latitude E6400", AD1984_DELL_DESKTOP), | ||
3644 | {} | 3645 | {} |
3645 | }; | 3646 | }; |
3646 | 3647 | ||
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index 4ef5efaaaef..488fd9ade1b 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c | |||
@@ -972,6 +972,53 @@ static struct hda_verb cs_coef_init_verbs[] = { | |||
972 | {} /* terminator */ | 972 | {} /* terminator */ |
973 | }; | 973 | }; |
974 | 974 | ||
975 | /* Errata: CS4207 rev C0/C1/C2 Silicon | ||
976 | * | ||
977 | * http://www.cirrus.com/en/pubs/errata/ER880C3.pdf | ||
978 | * | ||
979 | * 6. At high temperature (TA > +85°C), the digital supply current (IVD) | ||
980 | * may be excessive (up to an additional 200 μA), which is most easily | ||
981 | * observed while the part is being held in reset (RESET# active low). | ||
982 | * | ||
983 | * Root Cause: At initial powerup of the device, the logic that drives | ||
984 | * the clock and write enable to the S/PDIF SRC RAMs is not properly | ||
985 | * initialized. | ||
986 | * Certain random patterns will cause a steady leakage current in those | ||
987 | * RAM cells. The issue will resolve once the SRCs are used (turned on). | ||
988 | * | ||
989 | * Workaround: The following verb sequence briefly turns on the S/PDIF SRC | ||
990 | * blocks, which will alleviate the issue. | ||
991 | */ | ||
992 | |||
993 | static struct hda_verb cs_errata_init_verbs[] = { | ||
994 | {0x01, AC_VERB_SET_POWER_STATE, 0x00}, /* AFG: D0 */ | ||
995 | {0x11, AC_VERB_SET_PROC_STATE, 0x01}, /* VPW: processing on */ | ||
996 | |||
997 | {0x11, AC_VERB_SET_COEF_INDEX, 0x0008}, | ||
998 | {0x11, AC_VERB_SET_PROC_COEF, 0x9999}, | ||
999 | {0x11, AC_VERB_SET_COEF_INDEX, 0x0017}, | ||
1000 | {0x11, AC_VERB_SET_PROC_COEF, 0xa412}, | ||
1001 | {0x11, AC_VERB_SET_COEF_INDEX, 0x0001}, | ||
1002 | {0x11, AC_VERB_SET_PROC_COEF, 0x0009}, | ||
1003 | |||
1004 | {0x07, AC_VERB_SET_POWER_STATE, 0x00}, /* S/PDIF Rx: D0 */ | ||
1005 | {0x08, AC_VERB_SET_POWER_STATE, 0x00}, /* S/PDIF Tx: D0 */ | ||
1006 | |||
1007 | {0x11, AC_VERB_SET_COEF_INDEX, 0x0017}, | ||
1008 | {0x11, AC_VERB_SET_PROC_COEF, 0x2412}, | ||
1009 | {0x11, AC_VERB_SET_COEF_INDEX, 0x0008}, | ||
1010 | {0x11, AC_VERB_SET_PROC_COEF, 0x0000}, | ||
1011 | {0x11, AC_VERB_SET_COEF_INDEX, 0x0001}, | ||
1012 | {0x11, AC_VERB_SET_PROC_COEF, 0x0008}, | ||
1013 | {0x11, AC_VERB_SET_PROC_STATE, 0x00}, | ||
1014 | |||
1015 | {0x07, AC_VERB_SET_POWER_STATE, 0x03}, /* S/PDIF Rx: D3 */ | ||
1016 | {0x08, AC_VERB_SET_POWER_STATE, 0x03}, /* S/PDIF Tx: D3 */ | ||
1017 | /*{0x01, AC_VERB_SET_POWER_STATE, 0x03},*/ /* AFG: D3 This is already handled */ | ||
1018 | |||
1019 | {} /* terminator */ | ||
1020 | }; | ||
1021 | |||
975 | /* SPDIF setup */ | 1022 | /* SPDIF setup */ |
976 | static void init_digital(struct hda_codec *codec) | 1023 | static void init_digital(struct hda_codec *codec) |
977 | { | 1024 | { |
@@ -991,6 +1038,9 @@ static int cs_init(struct hda_codec *codec) | |||
991 | { | 1038 | { |
992 | struct cs_spec *spec = codec->spec; | 1039 | struct cs_spec *spec = codec->spec; |
993 | 1040 | ||
1041 | /* init_verb sequence for C0/C1/C2 errata*/ | ||
1042 | snd_hda_sequence_write(codec, cs_errata_init_verbs); | ||
1043 | |||
994 | snd_hda_sequence_write(codec, cs_coef_init_verbs); | 1044 | snd_hda_sequence_write(codec, cs_coef_init_verbs); |
995 | 1045 | ||
996 | if (spec->gpio_mask) { | 1046 | if (spec->gpio_mask) { |
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index c424952a734..972e7c453b3 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -116,6 +116,7 @@ struct conexant_spec { | |||
116 | unsigned int dell_vostro:1; | 116 | unsigned int dell_vostro:1; |
117 | unsigned int ideapad:1; | 117 | unsigned int ideapad:1; |
118 | unsigned int thinkpad:1; | 118 | unsigned int thinkpad:1; |
119 | unsigned int hp_laptop:1; | ||
119 | 120 | ||
120 | unsigned int ext_mic_present; | 121 | unsigned int ext_mic_present; |
121 | unsigned int recording; | 122 | unsigned int recording; |
@@ -2299,6 +2300,18 @@ static void cxt5066_ideapad_automic(struct hda_codec *codec) | |||
2299 | } | 2300 | } |
2300 | } | 2301 | } |
2301 | 2302 | ||
2303 | /* toggle input of built-in digital mic and mic jack appropriately */ | ||
2304 | static void cxt5066_hp_laptop_automic(struct hda_codec *codec) | ||
2305 | { | ||
2306 | unsigned int present; | ||
2307 | |||
2308 | present = snd_hda_jack_detect(codec, 0x1b); | ||
2309 | snd_printdd("CXT5066: external microphone present=%d\n", present); | ||
2310 | snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_CONNECT_SEL, | ||
2311 | present ? 1 : 3); | ||
2312 | } | ||
2313 | |||
2314 | |||
2302 | /* toggle input of built-in digital mic and mic jack appropriately | 2315 | /* toggle input of built-in digital mic and mic jack appropriately |
2303 | order is: external mic -> dock mic -> interal mic */ | 2316 | order is: external mic -> dock mic -> interal mic */ |
2304 | static void cxt5066_thinkpad_automic(struct hda_codec *codec) | 2317 | static void cxt5066_thinkpad_automic(struct hda_codec *codec) |
@@ -2408,6 +2421,20 @@ static void cxt5066_ideapad_event(struct hda_codec *codec, unsigned int res) | |||
2408 | } | 2421 | } |
2409 | 2422 | ||
2410 | /* unsolicited event for jack sensing */ | 2423 | /* unsolicited event for jack sensing */ |
2424 | static void cxt5066_hp_laptop_event(struct hda_codec *codec, unsigned int res) | ||
2425 | { | ||
2426 | snd_printdd("CXT5066_hp_laptop: unsol event %x (%x)\n", res, res >> 26); | ||
2427 | switch (res >> 26) { | ||
2428 | case CONEXANT_HP_EVENT: | ||
2429 | cxt5066_hp_automute(codec); | ||
2430 | break; | ||
2431 | case CONEXANT_MIC_EVENT: | ||
2432 | cxt5066_hp_laptop_automic(codec); | ||
2433 | break; | ||
2434 | } | ||
2435 | } | ||
2436 | |||
2437 | /* unsolicited event for jack sensing */ | ||
2411 | static void cxt5066_thinkpad_event(struct hda_codec *codec, unsigned int res) | 2438 | static void cxt5066_thinkpad_event(struct hda_codec *codec, unsigned int res) |
2412 | { | 2439 | { |
2413 | snd_printdd("CXT5066_thinkpad: unsol event %x (%x)\n", res, res >> 26); | 2440 | snd_printdd("CXT5066_thinkpad: unsol event %x (%x)\n", res, res >> 26); |
@@ -2989,6 +3016,14 @@ static struct hda_verb cxt5066_init_verbs_portd_lo[] = { | |||
2989 | { } /* end */ | 3016 | { } /* end */ |
2990 | }; | 3017 | }; |
2991 | 3018 | ||
3019 | |||
3020 | static struct hda_verb cxt5066_init_verbs_hp_laptop[] = { | ||
3021 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x0}, | ||
3022 | {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, | ||
3023 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, | ||
3024 | { } /* end */ | ||
3025 | }; | ||
3026 | |||
2992 | /* initialize jack-sensing, too */ | 3027 | /* initialize jack-sensing, too */ |
2993 | static int cxt5066_init(struct hda_codec *codec) | 3028 | static int cxt5066_init(struct hda_codec *codec) |
2994 | { | 3029 | { |
@@ -3004,6 +3039,8 @@ static int cxt5066_init(struct hda_codec *codec) | |||
3004 | cxt5066_ideapad_automic(codec); | 3039 | cxt5066_ideapad_automic(codec); |
3005 | else if (spec->thinkpad) | 3040 | else if (spec->thinkpad) |
3006 | cxt5066_thinkpad_automic(codec); | 3041 | cxt5066_thinkpad_automic(codec); |
3042 | else if (spec->hp_laptop) | ||
3043 | cxt5066_hp_laptop_automic(codec); | ||
3007 | } | 3044 | } |
3008 | cxt5066_set_mic_boost(codec); | 3045 | cxt5066_set_mic_boost(codec); |
3009 | return 0; | 3046 | return 0; |
@@ -3031,6 +3068,7 @@ enum { | |||
3031 | CXT5066_DELL_VOSTO, /* Dell Vostro 1015i */ | 3068 | CXT5066_DELL_VOSTO, /* Dell Vostro 1015i */ |
3032 | CXT5066_IDEAPAD, /* Lenovo IdeaPad U150 */ | 3069 | CXT5066_IDEAPAD, /* Lenovo IdeaPad U150 */ |
3033 | CXT5066_THINKPAD, /* Lenovo ThinkPad T410s, others? */ | 3070 | CXT5066_THINKPAD, /* Lenovo ThinkPad T410s, others? */ |
3071 | CXT5066_HP_LAPTOP, /* HP Laptop */ | ||
3034 | CXT5066_MODELS | 3072 | CXT5066_MODELS |
3035 | }; | 3073 | }; |
3036 | 3074 | ||
@@ -3041,6 +3079,7 @@ static const char *cxt5066_models[CXT5066_MODELS] = { | |||
3041 | [CXT5066_DELL_VOSTO] = "dell-vostro", | 3079 | [CXT5066_DELL_VOSTO] = "dell-vostro", |
3042 | [CXT5066_IDEAPAD] = "ideapad", | 3080 | [CXT5066_IDEAPAD] = "ideapad", |
3043 | [CXT5066_THINKPAD] = "thinkpad", | 3081 | [CXT5066_THINKPAD] = "thinkpad", |
3082 | [CXT5066_HP_LAPTOP] = "hp-laptop", | ||
3044 | }; | 3083 | }; |
3045 | 3084 | ||
3046 | static struct snd_pci_quirk cxt5066_cfg_tbl[] = { | 3085 | static struct snd_pci_quirk cxt5066_cfg_tbl[] = { |
@@ -3052,13 +3091,17 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { | |||
3052 | SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTO), | 3091 | SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTO), |
3053 | SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTO), | 3092 | SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTO), |
3054 | SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD), | 3093 | SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD), |
3094 | SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP), | ||
3095 | SND_PCI_QUIRK(0x1179, 0xff1e, "Toshiba Satellite C650D", CXT5066_IDEAPAD), | ||
3055 | SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5), | 3096 | SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5), |
3056 | SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5), | 3097 | SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5), |
3098 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD), | ||
3057 | SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD), | 3099 | SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD), |
3058 | SND_PCI_QUIRK(0x17aa, 0x21b3, "Thinkpad Edge 13 (197)", CXT5066_IDEAPAD), | 3100 | SND_PCI_QUIRK(0x17aa, 0x21b3, "Thinkpad Edge 13 (197)", CXT5066_IDEAPAD), |
3059 | SND_PCI_QUIRK(0x17aa, 0x21b4, "Thinkpad Edge", CXT5066_IDEAPAD), | 3101 | SND_PCI_QUIRK(0x17aa, 0x21b4, "Thinkpad Edge", CXT5066_IDEAPAD), |
3060 | SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD), | 3102 | SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD), |
3061 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G series", CXT5066_IDEAPAD), | 3103 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G series", CXT5066_IDEAPAD), |
3104 | SND_PCI_QUIRK(0x17aa, 0x390a, "Lenovo S10-3t", CXT5066_IDEAPAD), | ||
3062 | SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G series (AMD)", CXT5066_IDEAPAD), | 3105 | SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G series (AMD)", CXT5066_IDEAPAD), |
3063 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD), | 3106 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD), |
3064 | {} | 3107 | {} |
@@ -3115,6 +3158,23 @@ static int patch_cxt5066(struct hda_codec *codec) | |||
3115 | spec->num_init_verbs++; | 3158 | spec->num_init_verbs++; |
3116 | spec->dell_automute = 1; | 3159 | spec->dell_automute = 1; |
3117 | break; | 3160 | break; |
3161 | case CXT5066_HP_LAPTOP: | ||
3162 | codec->patch_ops.init = cxt5066_init; | ||
3163 | codec->patch_ops.unsol_event = cxt5066_hp_laptop_event; | ||
3164 | spec->init_verbs[spec->num_init_verbs] = | ||
3165 | cxt5066_init_verbs_hp_laptop; | ||
3166 | spec->num_init_verbs++; | ||
3167 | spec->hp_laptop = 1; | ||
3168 | spec->mixers[spec->num_mixers++] = cxt5066_mixer_master; | ||
3169 | spec->mixers[spec->num_mixers++] = cxt5066_mixers; | ||
3170 | /* no S/PDIF out */ | ||
3171 | spec->multiout.dig_out_nid = 0; | ||
3172 | /* input source automatically selected */ | ||
3173 | spec->input_mux = NULL; | ||
3174 | spec->port_d_mode = 0; | ||
3175 | spec->mic_boost = 3; /* default 30dB gain */ | ||
3176 | break; | ||
3177 | |||
3118 | case CXT5066_OLPC_XO_1_5: | 3178 | case CXT5066_OLPC_XO_1_5: |
3119 | codec->patch_ops.init = cxt5066_olpc_init; | 3179 | codec->patch_ops.init = cxt5066_olpc_init; |
3120 | codec->patch_ops.unsol_event = cxt5066_olpc_unsol_event; | 3180 | codec->patch_ops.unsol_event = cxt5066_olpc_unsol_event; |
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 2bc0f07cf33..afd6022a96a 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
@@ -707,8 +707,6 @@ static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid, | |||
707 | u32 stream_tag, int format) | 707 | u32 stream_tag, int format) |
708 | { | 708 | { |
709 | struct hdmi_spec *spec = codec->spec; | 709 | struct hdmi_spec *spec = codec->spec; |
710 | int tag; | ||
711 | int fmt; | ||
712 | int pinctl; | 710 | int pinctl; |
713 | int new_pinctl = 0; | 711 | int new_pinctl = 0; |
714 | int i; | 712 | int i; |
@@ -745,24 +743,7 @@ static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid, | |||
745 | return -EINVAL; | 743 | return -EINVAL; |
746 | } | 744 | } |
747 | 745 | ||
748 | tag = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0) >> 4; | 746 | snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); |
749 | fmt = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_STREAM_FORMAT, 0); | ||
750 | |||
751 | snd_printdd("hdmi_setup_stream: " | ||
752 | "NID=0x%x, %sstream=0x%x, %sformat=0x%x\n", | ||
753 | nid, | ||
754 | tag == stream_tag ? "" : "new-", | ||
755 | stream_tag, | ||
756 | fmt == format ? "" : "new-", | ||
757 | format); | ||
758 | |||
759 | if (tag != stream_tag) | ||
760 | snd_hda_codec_write(codec, nid, 0, | ||
761 | AC_VERB_SET_CHANNEL_STREAMID, | ||
762 | stream_tag << 4); | ||
763 | if (fmt != format) | ||
764 | snd_hda_codec_write(codec, nid, 0, | ||
765 | AC_VERB_SET_STREAM_FORMAT, format); | ||
766 | return 0; | 747 | return 0; |
767 | } | 748 | } |
768 | 749 | ||
diff --git a/sound/pci/hda/patch_intelhdmi.c b/sound/pci/hda/patch_intelhdmi.c index d382d3c81c0..36a9b83a617 100644 --- a/sound/pci/hda/patch_intelhdmi.c +++ b/sound/pci/hda/patch_intelhdmi.c | |||
@@ -69,20 +69,12 @@ static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
69 | return hdmi_setup_stream(codec, hinfo->nid, stream_tag, format); | 69 | return hdmi_setup_stream(codec, hinfo->nid, stream_tag, format); |
70 | } | 70 | } |
71 | 71 | ||
72 | static int intel_hdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
73 | struct hda_codec *codec, | ||
74 | struct snd_pcm_substream *substream) | ||
75 | { | ||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | static struct hda_pcm_stream intel_hdmi_pcm_playback = { | 72 | static struct hda_pcm_stream intel_hdmi_pcm_playback = { |
80 | .substreams = 1, | 73 | .substreams = 1, |
81 | .channels_min = 2, | 74 | .channels_min = 2, |
82 | .ops = { | 75 | .ops = { |
83 | .open = hdmi_pcm_open, | 76 | .open = hdmi_pcm_open, |
84 | .prepare = intel_hdmi_playback_pcm_prepare, | 77 | .prepare = intel_hdmi_playback_pcm_prepare, |
85 | .cleanup = intel_hdmi_playback_pcm_cleanup, | ||
86 | }, | 78 | }, |
87 | }; | 79 | }; |
88 | 80 | ||
diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c index f636870dc71..baa108b9d6a 100644 --- a/sound/pci/hda/patch_nvhdmi.c +++ b/sound/pci/hda/patch_nvhdmi.c | |||
@@ -84,7 +84,7 @@ static struct hda_verb nvhdmi_basic_init_7x[] = { | |||
84 | #else | 84 | #else |
85 | /* support all rates and formats */ | 85 | /* support all rates and formats */ |
86 | #define SUPPORTED_RATES \ | 86 | #define SUPPORTED_RATES \ |
87 | (SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\ | 87 | (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\ |
88 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |\ | 88 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |\ |
89 | SNDRV_PCM_RATE_192000) | 89 | SNDRV_PCM_RATE_192000) |
90 | #define SUPPORTED_MAXBPS 24 | 90 | #define SUPPORTED_MAXBPS 24 |
@@ -326,13 +326,6 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo, | |||
326 | return 0; | 326 | return 0; |
327 | } | 327 | } |
328 | 328 | ||
329 | static int nvhdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
330 | struct hda_codec *codec, | ||
331 | struct snd_pcm_substream *substream) | ||
332 | { | ||
333 | return 0; | ||
334 | } | ||
335 | |||
336 | static int nvhdmi_dig_playback_pcm_prepare_2ch(struct hda_pcm_stream *hinfo, | 329 | static int nvhdmi_dig_playback_pcm_prepare_2ch(struct hda_pcm_stream *hinfo, |
337 | struct hda_codec *codec, | 330 | struct hda_codec *codec, |
338 | unsigned int stream_tag, | 331 | unsigned int stream_tag, |
@@ -350,7 +343,6 @@ static struct hda_pcm_stream nvhdmi_pcm_digital_playback_8ch_89 = { | |||
350 | .ops = { | 343 | .ops = { |
351 | .open = hdmi_pcm_open, | 344 | .open = hdmi_pcm_open, |
352 | .prepare = nvhdmi_dig_playback_pcm_prepare_8ch_89, | 345 | .prepare = nvhdmi_dig_playback_pcm_prepare_8ch_89, |
353 | .cleanup = nvhdmi_playback_pcm_cleanup, | ||
354 | }, | 346 | }, |
355 | }; | 347 | }; |
356 | 348 | ||
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index a4dd04524e4..a432e6efd19 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -1594,12 +1594,22 @@ static void alc_auto_parse_digital(struct hda_codec *codec) | |||
1594 | } | 1594 | } |
1595 | 1595 | ||
1596 | if (spec->autocfg.dig_in_pin) { | 1596 | if (spec->autocfg.dig_in_pin) { |
1597 | hda_nid_t dig_nid; | 1597 | dig_nid = codec->start_nid; |
1598 | err = snd_hda_get_connections(codec, | 1598 | for (i = 0; i < codec->num_nodes; i++, dig_nid++) { |
1599 | spec->autocfg.dig_in_pin, | 1599 | unsigned int wcaps = get_wcaps(codec, dig_nid); |
1600 | &dig_nid, 1); | 1600 | if (get_wcaps_type(wcaps) != AC_WID_AUD_IN) |
1601 | if (err > 0) | 1601 | continue; |
1602 | spec->dig_in_nid = dig_nid; | 1602 | if (!(wcaps & AC_WCAP_DIGITAL)) |
1603 | continue; | ||
1604 | if (!(wcaps & AC_WCAP_CONN_LIST)) | ||
1605 | continue; | ||
1606 | err = get_connection_index(codec, dig_nid, | ||
1607 | spec->autocfg.dig_in_pin); | ||
1608 | if (err >= 0) { | ||
1609 | spec->dig_in_nid = dig_nid; | ||
1610 | break; | ||
1611 | } | ||
1612 | } | ||
1603 | } | 1613 | } |
1604 | } | 1614 | } |
1605 | 1615 | ||
@@ -5334,6 +5344,7 @@ static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids, | |||
5334 | 5344 | ||
5335 | static struct snd_pci_quirk beep_white_list[] = { | 5345 | static struct snd_pci_quirk beep_white_list[] = { |
5336 | SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1), | 5346 | SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1), |
5347 | SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1), | ||
5337 | SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1), | 5348 | SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1), |
5338 | {} | 5349 | {} |
5339 | }; | 5350 | }; |
@@ -14452,6 +14463,7 @@ static void alc269_auto_init(struct hda_codec *codec) | |||
14452 | 14463 | ||
14453 | enum { | 14464 | enum { |
14454 | ALC269_FIXUP_SONY_VAIO, | 14465 | ALC269_FIXUP_SONY_VAIO, |
14466 | ALC269_FIXUP_DELL_M101Z, | ||
14455 | }; | 14467 | }; |
14456 | 14468 | ||
14457 | static const struct hda_verb alc269_sony_vaio_fixup_verbs[] = { | 14469 | static const struct hda_verb alc269_sony_vaio_fixup_verbs[] = { |
@@ -14463,10 +14475,20 @@ static const struct alc_fixup alc269_fixups[] = { | |||
14463 | [ALC269_FIXUP_SONY_VAIO] = { | 14475 | [ALC269_FIXUP_SONY_VAIO] = { |
14464 | .verbs = alc269_sony_vaio_fixup_verbs | 14476 | .verbs = alc269_sony_vaio_fixup_verbs |
14465 | }, | 14477 | }, |
14478 | [ALC269_FIXUP_DELL_M101Z] = { | ||
14479 | .verbs = (const struct hda_verb[]) { | ||
14480 | /* Enables internal speaker */ | ||
14481 | {0x20, AC_VERB_SET_COEF_INDEX, 13}, | ||
14482 | {0x20, AC_VERB_SET_PROC_COEF, 0x4040}, | ||
14483 | {} | ||
14484 | } | ||
14485 | }, | ||
14466 | }; | 14486 | }; |
14467 | 14487 | ||
14468 | static struct snd_pci_quirk alc269_fixup_tbl[] = { | 14488 | static struct snd_pci_quirk alc269_fixup_tbl[] = { |
14469 | SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), | 14489 | SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), |
14490 | SND_PCI_QUIRK(0x104d, 0x9077, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), | ||
14491 | SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), | ||
14470 | {} | 14492 | {} |
14471 | }; | 14493 | }; |
14472 | 14494 | ||
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index f3f861bd1bf..c16c5ba0fda 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -1747,6 +1747,8 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { | |||
1747 | "HP dv6", STAC_HP_DV5), | 1747 | "HP dv6", STAC_HP_DV5), |
1748 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3061, | 1748 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3061, |
1749 | "HP dv6", STAC_HP_DV5), /* HP dv6-1110ax */ | 1749 | "HP dv6", STAC_HP_DV5), /* HP dv6-1110ax */ |
1750 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x363e, | ||
1751 | "HP DV6", STAC_HP_DV5), | ||
1750 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x7010, | 1752 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x7010, |
1751 | "HP", STAC_HP_DV5), | 1753 | "HP", STAC_HP_DV5), |
1752 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, | 1754 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, |
@@ -6303,6 +6305,21 @@ static struct hda_codec_preset snd_hda_preset_sigmatel[] = { | |||
6303 | { .id = 0x111d76b5, .name = "92HD71B6X", .patch = patch_stac92hd71bxx }, | 6305 | { .id = 0x111d76b5, .name = "92HD71B6X", .patch = patch_stac92hd71bxx }, |
6304 | { .id = 0x111d76b6, .name = "92HD71B5X", .patch = patch_stac92hd71bxx }, | 6306 | { .id = 0x111d76b6, .name = "92HD71B5X", .patch = patch_stac92hd71bxx }, |
6305 | { .id = 0x111d76b7, .name = "92HD71B5X", .patch = patch_stac92hd71bxx }, | 6307 | { .id = 0x111d76b7, .name = "92HD71B5X", .patch = patch_stac92hd71bxx }, |
6308 | { .id = 0x111d76c0, .name = "92HD89C3", .patch = patch_stac92hd73xx }, | ||
6309 | { .id = 0x111d76c1, .name = "92HD89C2", .patch = patch_stac92hd73xx }, | ||
6310 | { .id = 0x111d76c2, .name = "92HD89C1", .patch = patch_stac92hd73xx }, | ||
6311 | { .id = 0x111d76c3, .name = "92HD89B3", .patch = patch_stac92hd73xx }, | ||
6312 | { .id = 0x111d76c4, .name = "92HD89B2", .patch = patch_stac92hd73xx }, | ||
6313 | { .id = 0x111d76c5, .name = "92HD89B1", .patch = patch_stac92hd73xx }, | ||
6314 | { .id = 0x111d76c6, .name = "92HD89E3", .patch = patch_stac92hd73xx }, | ||
6315 | { .id = 0x111d76c7, .name = "92HD89E2", .patch = patch_stac92hd73xx }, | ||
6316 | { .id = 0x111d76c8, .name = "92HD89E1", .patch = patch_stac92hd73xx }, | ||
6317 | { .id = 0x111d76c9, .name = "92HD89D3", .patch = patch_stac92hd73xx }, | ||
6318 | { .id = 0x111d76ca, .name = "92HD89D2", .patch = patch_stac92hd73xx }, | ||
6319 | { .id = 0x111d76cb, .name = "92HD89D1", .patch = patch_stac92hd73xx }, | ||
6320 | { .id = 0x111d76cc, .name = "92HD89F3", .patch = patch_stac92hd73xx }, | ||
6321 | { .id = 0x111d76cd, .name = "92HD89F2", .patch = patch_stac92hd73xx }, | ||
6322 | { .id = 0x111d76ce, .name = "92HD89F1", .patch = patch_stac92hd73xx }, | ||
6306 | {} /* terminator */ | 6323 | {} /* terminator */ |
6307 | }; | 6324 | }; |
6308 | 6325 | ||
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 6433e65c950..46774924957 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c | |||
@@ -1776,6 +1776,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = { | |||
1776 | }, | 1776 | }, |
1777 | { | 1777 | { |
1778 | .subvendor = 0x1014, | 1778 | .subvendor = 0x1014, |
1779 | .subdevice = 0x0534, | ||
1780 | .name = "ThinkPad X31", | ||
1781 | .type = AC97_TUNE_INV_EAPD | ||
1782 | }, | ||
1783 | { | ||
1784 | .subvendor = 0x1014, | ||
1779 | .subdevice = 0x1f00, | 1785 | .subdevice = 0x1f00, |
1780 | .name = "MS-9128", | 1786 | .name = "MS-9128", |
1781 | .type = AC97_TUNE_ALC_JACK | 1787 | .type = AC97_TUNE_ALC_JACK |
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index 289cb4dacfc..6c0a11adb2a 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c | |||
@@ -543,6 +543,10 @@ static int __devinit get_oxygen_model(struct oxygen *chip, | |||
543 | chip->model.suspend = claro_suspend; | 543 | chip->model.suspend = claro_suspend; |
544 | chip->model.resume = claro_resume; | 544 | chip->model.resume = claro_resume; |
545 | chip->model.set_adc_params = set_ak5385_params; | 545 | chip->model.set_adc_params = set_ak5385_params; |
546 | chip->model.device_config = PLAYBACK_0_TO_I2S | | ||
547 | PLAYBACK_1_TO_SPDIF | | ||
548 | CAPTURE_0_FROM_I2S_2 | | ||
549 | CAPTURE_1_FROM_SPDIF; | ||
546 | break; | 550 | break; |
547 | } | 551 | } |
548 | if (id->driver_data == MODEL_MERIDIAN || | 552 | if (id->driver_data == MODEL_MERIDIAN || |
diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h index 6147216af74..a3409edcfb5 100644 --- a/sound/pci/oxygen/oxygen.h +++ b/sound/pci/oxygen/oxygen.h | |||
@@ -155,6 +155,7 @@ void oxygen_pci_remove(struct pci_dev *pci); | |||
155 | int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state); | 155 | int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state); |
156 | int oxygen_pci_resume(struct pci_dev *pci); | 156 | int oxygen_pci_resume(struct pci_dev *pci); |
157 | #endif | 157 | #endif |
158 | void oxygen_pci_shutdown(struct pci_dev *pci); | ||
158 | 159 | ||
159 | /* oxygen_mixer.c */ | 160 | /* oxygen_mixer.c */ |
160 | 161 | ||
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index fad03d64e3a..7e93cf88443 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c | |||
@@ -519,16 +519,21 @@ static void oxygen_init(struct oxygen *chip) | |||
519 | } | 519 | } |
520 | } | 520 | } |
521 | 521 | ||
522 | static void oxygen_card_free(struct snd_card *card) | 522 | static void oxygen_shutdown(struct oxygen *chip) |
523 | { | 523 | { |
524 | struct oxygen *chip = card->private_data; | ||
525 | |||
526 | spin_lock_irq(&chip->reg_lock); | 524 | spin_lock_irq(&chip->reg_lock); |
527 | chip->interrupt_mask = 0; | 525 | chip->interrupt_mask = 0; |
528 | chip->pcm_running = 0; | 526 | chip->pcm_running = 0; |
529 | oxygen_write16(chip, OXYGEN_DMA_STATUS, 0); | 527 | oxygen_write16(chip, OXYGEN_DMA_STATUS, 0); |
530 | oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, 0); | 528 | oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, 0); |
531 | spin_unlock_irq(&chip->reg_lock); | 529 | spin_unlock_irq(&chip->reg_lock); |
530 | } | ||
531 | |||
532 | static void oxygen_card_free(struct snd_card *card) | ||
533 | { | ||
534 | struct oxygen *chip = card->private_data; | ||
535 | |||
536 | oxygen_shutdown(chip); | ||
532 | if (chip->irq >= 0) | 537 | if (chip->irq >= 0) |
533 | free_irq(chip->irq, chip); | 538 | free_irq(chip->irq, chip); |
534 | flush_scheduled_work(); | 539 | flush_scheduled_work(); |
@@ -778,3 +783,13 @@ int oxygen_pci_resume(struct pci_dev *pci) | |||
778 | } | 783 | } |
779 | EXPORT_SYMBOL(oxygen_pci_resume); | 784 | EXPORT_SYMBOL(oxygen_pci_resume); |
780 | #endif /* CONFIG_PM */ | 785 | #endif /* CONFIG_PM */ |
786 | |||
787 | void oxygen_pci_shutdown(struct pci_dev *pci) | ||
788 | { | ||
789 | struct snd_card *card = pci_get_drvdata(pci); | ||
790 | struct oxygen *chip = card->private_data; | ||
791 | |||
792 | oxygen_shutdown(chip); | ||
793 | chip->model.cleanup(chip); | ||
794 | } | ||
795 | EXPORT_SYMBOL(oxygen_pci_shutdown); | ||
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index f03a2f2cffe..06c863e86e3 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c | |||
@@ -95,6 +95,7 @@ static struct pci_driver xonar_driver = { | |||
95 | .suspend = oxygen_pci_suspend, | 95 | .suspend = oxygen_pci_suspend, |
96 | .resume = oxygen_pci_resume, | 96 | .resume = oxygen_pci_resume, |
97 | #endif | 97 | #endif |
98 | .shutdown = oxygen_pci_shutdown, | ||
98 | }; | 99 | }; |
99 | 100 | ||
100 | static int __init alsa_card_xonar_init(void) | 101 | static int __init alsa_card_xonar_init(void) |
diff --git a/sound/pci/oxygen/xonar_wm87x6.c b/sound/pci/oxygen/xonar_wm87x6.c index dbc4b89d74e..b82c1cfa96f 100644 --- a/sound/pci/oxygen/xonar_wm87x6.c +++ b/sound/pci/oxygen/xonar_wm87x6.c | |||
@@ -53,6 +53,8 @@ struct xonar_wm87x6 { | |||
53 | struct xonar_generic generic; | 53 | struct xonar_generic generic; |
54 | u16 wm8776_regs[0x17]; | 54 | u16 wm8776_regs[0x17]; |
55 | u16 wm8766_regs[0x10]; | 55 | u16 wm8766_regs[0x10]; |
56 | struct snd_kcontrol *line_adcmux_control; | ||
57 | struct snd_kcontrol *mic_adcmux_control; | ||
56 | struct snd_kcontrol *lc_controls[13]; | 58 | struct snd_kcontrol *lc_controls[13]; |
57 | }; | 59 | }; |
58 | 60 | ||
@@ -193,6 +195,7 @@ static void xonar_ds_init(struct oxygen *chip) | |||
193 | static void xonar_ds_cleanup(struct oxygen *chip) | 195 | static void xonar_ds_cleanup(struct oxygen *chip) |
194 | { | 196 | { |
195 | xonar_disable_output(chip); | 197 | xonar_disable_output(chip); |
198 | wm8776_write(chip, WM8776_RESET, 0); | ||
196 | } | 199 | } |
197 | 200 | ||
198 | static void xonar_ds_suspend(struct oxygen *chip) | 201 | static void xonar_ds_suspend(struct oxygen *chip) |
@@ -603,6 +606,7 @@ static int wm8776_input_mux_put(struct snd_kcontrol *ctl, | |||
603 | { | 606 | { |
604 | struct oxygen *chip = ctl->private_data; | 607 | struct oxygen *chip = ctl->private_data; |
605 | struct xonar_wm87x6 *data = chip->model_data; | 608 | struct xonar_wm87x6 *data = chip->model_data; |
609 | struct snd_kcontrol *other_ctl; | ||
606 | unsigned int mux_bit = ctl->private_value; | 610 | unsigned int mux_bit = ctl->private_value; |
607 | u16 reg; | 611 | u16 reg; |
608 | int changed; | 612 | int changed; |
@@ -610,8 +614,18 @@ static int wm8776_input_mux_put(struct snd_kcontrol *ctl, | |||
610 | mutex_lock(&chip->mutex); | 614 | mutex_lock(&chip->mutex); |
611 | reg = data->wm8776_regs[WM8776_ADCMUX]; | 615 | reg = data->wm8776_regs[WM8776_ADCMUX]; |
612 | if (value->value.integer.value[0]) { | 616 | if (value->value.integer.value[0]) { |
613 | reg &= ~0x003; | ||
614 | reg |= mux_bit; | 617 | reg |= mux_bit; |
618 | /* line-in and mic-in are exclusive */ | ||
619 | mux_bit ^= 3; | ||
620 | if (reg & mux_bit) { | ||
621 | reg &= ~mux_bit; | ||
622 | if (mux_bit == 1) | ||
623 | other_ctl = data->line_adcmux_control; | ||
624 | else | ||
625 | other_ctl = data->mic_adcmux_control; | ||
626 | snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, | ||
627 | &other_ctl->id); | ||
628 | } | ||
615 | } else | 629 | } else |
616 | reg &= ~mux_bit; | 630 | reg &= ~mux_bit; |
617 | changed = reg != data->wm8776_regs[WM8776_ADCMUX]; | 631 | changed = reg != data->wm8776_regs[WM8776_ADCMUX]; |
@@ -963,7 +977,13 @@ static int xonar_ds_mixer_init(struct oxygen *chip) | |||
963 | err = snd_ctl_add(chip->card, ctl); | 977 | err = snd_ctl_add(chip->card, ctl); |
964 | if (err < 0) | 978 | if (err < 0) |
965 | return err; | 979 | return err; |
980 | if (!strcmp(ctl->id.name, "Line Capture Switch")) | ||
981 | data->line_adcmux_control = ctl; | ||
982 | else if (!strcmp(ctl->id.name, "Mic Capture Switch")) | ||
983 | data->mic_adcmux_control = ctl; | ||
966 | } | 984 | } |
985 | if (!data->line_adcmux_control || !data->mic_adcmux_control) | ||
986 | return -ENXIO; | ||
967 | BUILD_BUG_ON(ARRAY_SIZE(lc_controls) != ARRAY_SIZE(data->lc_controls)); | 987 | BUILD_BUG_ON(ARRAY_SIZE(lc_controls) != ARRAY_SIZE(data->lc_controls)); |
968 | for (i = 0; i < ARRAY_SIZE(lc_controls); ++i) { | 988 | for (i = 0; i < ARRAY_SIZE(lc_controls); ++i) { |
969 | ctl = snd_ctl_new1(&lc_controls[i], chip); | 989 | ctl = snd_ctl_new1(&lc_controls[i], chip); |
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index b92adef8e81..d6fa7bfd9aa 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c | |||
@@ -4609,6 +4609,7 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne | |||
4609 | if (err < 0) | 4609 | if (err < 0) |
4610 | return err; | 4610 | return err; |
4611 | 4611 | ||
4612 | memset(&info, 0, sizeof(info)); | ||
4612 | spin_lock_irqsave(&hdsp->lock, flags); | 4613 | spin_lock_irqsave(&hdsp->lock, flags); |
4613 | info.pref_sync_ref = (unsigned char)hdsp_pref_sync_ref(hdsp); | 4614 | info.pref_sync_ref = (unsigned char)hdsp_pref_sync_ref(hdsp); |
4614 | info.wordclock_sync_check = (unsigned char)hdsp_wc_sync_check(hdsp); | 4615 | info.wordclock_sync_check = (unsigned char)hdsp_wc_sync_check(hdsp); |
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 547b713d720..0c98ef9156d 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c | |||
@@ -4127,6 +4127,7 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep * hw, struct file *file, | |||
4127 | 4127 | ||
4128 | case SNDRV_HDSPM_IOCTL_GET_CONFIG_INFO: | 4128 | case SNDRV_HDSPM_IOCTL_GET_CONFIG_INFO: |
4129 | 4129 | ||
4130 | memset(&info, 0, sizeof(info)); | ||
4130 | spin_lock_irq(&hdspm->lock); | 4131 | spin_lock_irq(&hdspm->lock); |
4131 | info.pref_sync_ref = hdspm_pref_sync_ref(hdspm); | 4132 | info.pref_sync_ref = hdspm_pref_sync_ref(hdspm); |
4132 | info.wordclock_sync_check = hdspm_wc_sync_check(hdspm); | 4133 | info.wordclock_sync_check = hdspm_wc_sync_check(hdspm); |
diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c index 2f12da4da56..581a670e826 100644 --- a/sound/ppc/snd_ps3.c +++ b/sound/ppc/snd_ps3.c | |||
@@ -579,7 +579,7 @@ static int snd_ps3_delay_to_bytes(struct snd_pcm_substream *substream, | |||
579 | rate * delay_ms / 1000) | 579 | rate * delay_ms / 1000) |
580 | * substream->runtime->channels; | 580 | * substream->runtime->channels; |
581 | 581 | ||
582 | pr_debug(KERN_ERR "%s: time=%d rate=%d bytes=%ld, frames=%d, ret=%d\n", | 582 | pr_debug("%s: time=%d rate=%d bytes=%ld, frames=%d, ret=%d\n", |
583 | __func__, | 583 | __func__, |
584 | delay_ms, | 584 | delay_ms, |
585 | rate, | 585 | rate, |
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c index a11daa1e905..c81da05a4f1 100644 --- a/sound/soc/imx/imx-ssi.c +++ b/sound/soc/imx/imx-ssi.c | |||
@@ -254,6 +254,9 @@ static int imx_ssi_hw_params(struct snd_pcm_substream *substream, | |||
254 | dma_data = &ssi->dma_params_rx; | 254 | dma_data = &ssi->dma_params_rx; |
255 | } | 255 | } |
256 | 256 | ||
257 | if (ssi->flags & IMX_SSI_SYN) | ||
258 | reg = SSI_STCCR; | ||
259 | |||
257 | snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); | 260 | snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); |
258 | 261 | ||
259 | sccr = readl(ssi->base + reg) & ~SSI_STCCR_WL_MASK; | 262 | sccr = readl(ssi->base + reg) & ~SSI_STCCR_WL_MASK; |
diff --git a/sound/soc/s3c24xx/s3c-dma.c b/sound/soc/s3c24xx/s3c-dma.c index 1b61c23ff30..f1b1bc4bacf 100644 --- a/sound/soc/s3c24xx/s3c-dma.c +++ b/sound/soc/s3c24xx/s3c-dma.c | |||
@@ -94,8 +94,7 @@ static void s3c_dma_enqueue(struct snd_pcm_substream *substream) | |||
94 | 94 | ||
95 | if ((pos + len) > prtd->dma_end) { | 95 | if ((pos + len) > prtd->dma_end) { |
96 | len = prtd->dma_end - pos; | 96 | len = prtd->dma_end - pos; |
97 | pr_debug(KERN_DEBUG "%s: corrected dma len %ld\n", | 97 | pr_debug("%s: corrected dma len %ld\n", __func__, len); |
98 | __func__, len); | ||
99 | } | 98 | } |
100 | 99 | ||
101 | ret = s3c2410_dma_enqueue(prtd->params->channel, | 100 | ret = s3c2410_dma_enqueue(prtd->params->channel, |
diff --git a/sound/soc/sh/migor.c b/sound/soc/sh/migor.c index b823a5c9b9b..87e2b7fcbf1 100644 --- a/sound/soc/sh/migor.c +++ b/sound/soc/sh/migor.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/firmware.h> | 12 | #include <linux/firmware.h> |
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | 14 | ||
15 | #include <asm/clkdev.h> | ||
15 | #include <asm/clock.h> | 16 | #include <asm/clock.h> |
16 | 17 | ||
17 | #include <cpu/sh7722.h> | 18 | #include <cpu/sh7722.h> |
@@ -40,12 +41,12 @@ static struct clk_ops siumckb_clk_ops = { | |||
40 | }; | 41 | }; |
41 | 42 | ||
42 | static struct clk siumckb_clk = { | 43 | static struct clk siumckb_clk = { |
43 | .name = "siumckb_clk", | ||
44 | .id = -1, | ||
45 | .ops = &siumckb_clk_ops, | 44 | .ops = &siumckb_clk_ops, |
46 | .rate = 0, /* initialised at run-time */ | 45 | .rate = 0, /* initialised at run-time */ |
47 | }; | 46 | }; |
48 | 47 | ||
48 | static struct clk_lookup *siumckb_lookup; | ||
49 | |||
49 | static int migor_hw_params(struct snd_pcm_substream *substream, | 50 | static int migor_hw_params(struct snd_pcm_substream *substream, |
50 | struct snd_pcm_hw_params *params) | 51 | struct snd_pcm_hw_params *params) |
51 | { | 52 | { |
@@ -180,6 +181,13 @@ static int __init migor_init(void) | |||
180 | if (ret < 0) | 181 | if (ret < 0) |
181 | return ret; | 182 | return ret; |
182 | 183 | ||
184 | siumckb_lookup = clkdev_alloc(&siumckb_clk, "siumckb_clk", NULL); | ||
185 | if (!siumckb_lookup) { | ||
186 | ret = -ENOMEM; | ||
187 | goto eclkdevalloc; | ||
188 | } | ||
189 | clkdev_add(siumckb_lookup); | ||
190 | |||
183 | /* Port number used on this machine: port B */ | 191 | /* Port number used on this machine: port B */ |
184 | migor_snd_device = platform_device_alloc("soc-audio", 1); | 192 | migor_snd_device = platform_device_alloc("soc-audio", 1); |
185 | if (!migor_snd_device) { | 193 | if (!migor_snd_device) { |
@@ -200,12 +208,15 @@ static int __init migor_init(void) | |||
200 | epdevadd: | 208 | epdevadd: |
201 | platform_device_put(migor_snd_device); | 209 | platform_device_put(migor_snd_device); |
202 | epdevalloc: | 210 | epdevalloc: |
211 | clkdev_drop(siumckb_lookup); | ||
212 | eclkdevalloc: | ||
203 | clk_unregister(&siumckb_clk); | 213 | clk_unregister(&siumckb_clk); |
204 | return ret; | 214 | return ret; |
205 | } | 215 | } |
206 | 216 | ||
207 | static void __exit migor_exit(void) | 217 | static void __exit migor_exit(void) |
208 | { | 218 | { |
219 | clkdev_drop(siumckb_lookup); | ||
209 | clk_unregister(&siumckb_clk); | 220 | clk_unregister(&siumckb_clk); |
210 | platform_device_unregister(migor_snd_device); | 221 | platform_device_unregister(migor_snd_device); |
211 | } | 222 | } |
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index adbc68ce905..f6b0d2829ea 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c | |||
@@ -203,8 +203,9 @@ static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg, | |||
203 | data[1] = (value >> 8) & 0xff; | 203 | data[1] = (value >> 8) & 0xff; |
204 | data[2] = value & 0xff; | 204 | data[2] = value & 0xff; |
205 | 205 | ||
206 | if (!snd_soc_codec_volatile_register(codec, reg)) | 206 | if (!snd_soc_codec_volatile_register(codec, reg) |
207 | reg_cache[reg] = value; | 207 | && reg < codec->reg_cache_size) |
208 | reg_cache[reg] = value; | ||
208 | 209 | ||
209 | if (codec->cache_only) { | 210 | if (codec->cache_only) { |
210 | codec->cache_sync = 1; | 211 | codec->cache_sync = 1; |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 844ae8221a3..acc91daa1c5 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -251,7 +251,7 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec) | |||
251 | printk(KERN_WARNING | 251 | printk(KERN_WARNING |
252 | "ASoC: Failed to create codec register debugfs file\n"); | 252 | "ASoC: Failed to create codec register debugfs file\n"); |
253 | 253 | ||
254 | codec->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0744, | 254 | codec->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0644, |
255 | codec->debugfs_codec_root, | 255 | codec->debugfs_codec_root, |
256 | &codec->pop_time); | 256 | &codec->pop_time); |
257 | if (!codec->debugfs_pop_time) | 257 | if (!codec->debugfs_pop_time) |
diff --git a/sound/usb/card.c b/sound/usb/card.c index 9feb00c831a..4eabafa5b03 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c | |||
@@ -126,7 +126,7 @@ static void snd_usb_stream_disconnect(struct list_head *head) | |||
126 | for (idx = 0; idx < 2; idx++) { | 126 | for (idx = 0; idx < 2; idx++) { |
127 | subs = &as->substream[idx]; | 127 | subs = &as->substream[idx]; |
128 | if (!subs->num_formats) | 128 | if (!subs->num_formats) |
129 | return; | 129 | continue; |
130 | snd_usb_release_substream_urbs(subs, 1); | 130 | snd_usb_release_substream_urbs(subs, 1); |
131 | subs->interface = -1; | 131 | subs->interface = -1; |
132 | } | 132 | } |
@@ -216,6 +216,11 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif) | |||
216 | } | 216 | } |
217 | 217 | ||
218 | switch (protocol) { | 218 | switch (protocol) { |
219 | default: | ||
220 | snd_printdd(KERN_WARNING "unknown interface protocol %#02x, assuming v1\n", | ||
221 | protocol); | ||
222 | /* fall through */ | ||
223 | |||
219 | case UAC_VERSION_1: { | 224 | case UAC_VERSION_1: { |
220 | struct uac1_ac_header_descriptor *h1 = control_header; | 225 | struct uac1_ac_header_descriptor *h1 = control_header; |
221 | 226 | ||
@@ -253,10 +258,6 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif) | |||
253 | 258 | ||
254 | break; | 259 | break; |
255 | } | 260 | } |
256 | |||
257 | default: | ||
258 | snd_printk(KERN_ERR "unknown protocol version 0x%02x\n", protocol); | ||
259 | return -EINVAL; | ||
260 | } | 261 | } |
261 | 262 | ||
262 | return 0; | 263 | return 0; |
@@ -465,7 +466,13 @@ static void *snd_usb_audio_probe(struct usb_device *dev, | |||
465 | goto __error; | 466 | goto __error; |
466 | } | 467 | } |
467 | 468 | ||
468 | chip->ctrl_intf = alts; | 469 | /* |
470 | * For devices with more than one control interface, we assume the | ||
471 | * first contains the audio controls. We might need a more specific | ||
472 | * check here in the future. | ||
473 | */ | ||
474 | if (!chip->ctrl_intf) | ||
475 | chip->ctrl_intf = alts; | ||
469 | 476 | ||
470 | if (err > 0) { | 477 | if (err > 0) { |
471 | /* create normal USB audio interfaces */ | 478 | /* create normal USB audio interfaces */ |
diff --git a/sound/usb/clock.c b/sound/usb/clock.c index b853f8df794..7754a103454 100644 --- a/sound/usb/clock.c +++ b/sound/usb/clock.c | |||
@@ -295,12 +295,11 @@ int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface, | |||
295 | 295 | ||
296 | switch (altsd->bInterfaceProtocol) { | 296 | switch (altsd->bInterfaceProtocol) { |
297 | case UAC_VERSION_1: | 297 | case UAC_VERSION_1: |
298 | default: | ||
298 | return set_sample_rate_v1(chip, iface, alts, fmt, rate); | 299 | return set_sample_rate_v1(chip, iface, alts, fmt, rate); |
299 | 300 | ||
300 | case UAC_VERSION_2: | 301 | case UAC_VERSION_2: |
301 | return set_sample_rate_v2(chip, iface, alts, fmt, rate); | 302 | return set_sample_rate_v2(chip, iface, alts, fmt, rate); |
302 | } | 303 | } |
303 | |||
304 | return -EINVAL; | ||
305 | } | 304 | } |
306 | 305 | ||
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index 1a701f1e8f5..ef0a07e3484 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c | |||
@@ -275,6 +275,12 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
275 | 275 | ||
276 | /* get audio formats */ | 276 | /* get audio formats */ |
277 | switch (protocol) { | 277 | switch (protocol) { |
278 | default: | ||
279 | snd_printdd(KERN_WARNING "%d:%u:%d: unknown interface protocol %#02x, assuming v1\n", | ||
280 | dev->devnum, iface_no, altno, protocol); | ||
281 | protocol = UAC_VERSION_1; | ||
282 | /* fall through */ | ||
283 | |||
278 | case UAC_VERSION_1: { | 284 | case UAC_VERSION_1: { |
279 | struct uac1_as_header_descriptor *as = | 285 | struct uac1_as_header_descriptor *as = |
280 | snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL); | 286 | snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL); |
@@ -336,11 +342,6 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
336 | dev->devnum, iface_no, altno, as->bTerminalLink); | 342 | dev->devnum, iface_no, altno, as->bTerminalLink); |
337 | continue; | 343 | continue; |
338 | } | 344 | } |
339 | |||
340 | default: | ||
341 | snd_printk(KERN_ERR "%d:%u:%d : unknown interface protocol %04x\n", | ||
342 | dev->devnum, iface_no, altno, protocol); | ||
343 | continue; | ||
344 | } | 345 | } |
345 | 346 | ||
346 | /* get format type */ | 347 | /* get format type */ |
diff --git a/sound/usb/format.c b/sound/usb/format.c index 3a1375459c0..69148212aa7 100644 --- a/sound/usb/format.c +++ b/sound/usb/format.c | |||
@@ -49,7 +49,8 @@ static u64 parse_audio_format_i_type(struct snd_usb_audio *chip, | |||
49 | u64 pcm_formats; | 49 | u64 pcm_formats; |
50 | 50 | ||
51 | switch (protocol) { | 51 | switch (protocol) { |
52 | case UAC_VERSION_1: { | 52 | case UAC_VERSION_1: |
53 | default: { | ||
53 | struct uac_format_type_i_discrete_descriptor *fmt = _fmt; | 54 | struct uac_format_type_i_discrete_descriptor *fmt = _fmt; |
54 | sample_width = fmt->bBitResolution; | 55 | sample_width = fmt->bBitResolution; |
55 | sample_bytes = fmt->bSubframeSize; | 56 | sample_bytes = fmt->bSubframeSize; |
@@ -64,9 +65,6 @@ static u64 parse_audio_format_i_type(struct snd_usb_audio *chip, | |||
64 | format <<= 1; | 65 | format <<= 1; |
65 | break; | 66 | break; |
66 | } | 67 | } |
67 | |||
68 | default: | ||
69 | return -EINVAL; | ||
70 | } | 68 | } |
71 | 69 | ||
72 | pcm_formats = 0; | 70 | pcm_formats = 0; |
@@ -384,6 +382,10 @@ static int parse_audio_format_i(struct snd_usb_audio *chip, | |||
384 | * audio class v2 uses class specific EP0 range requests for that. | 382 | * audio class v2 uses class specific EP0 range requests for that. |
385 | */ | 383 | */ |
386 | switch (protocol) { | 384 | switch (protocol) { |
385 | default: | ||
386 | snd_printdd(KERN_WARNING "%d:%u:%d : invalid protocol version %d, assuming v1\n", | ||
387 | chip->dev->devnum, fp->iface, fp->altsetting, protocol); | ||
388 | /* fall through */ | ||
387 | case UAC_VERSION_1: | 389 | case UAC_VERSION_1: |
388 | fp->channels = fmt->bNrChannels; | 390 | fp->channels = fmt->bNrChannels; |
389 | ret = parse_audio_format_rates_v1(chip, fp, (unsigned char *) fmt, 7); | 391 | ret = parse_audio_format_rates_v1(chip, fp, (unsigned char *) fmt, 7); |
@@ -392,10 +394,6 @@ static int parse_audio_format_i(struct snd_usb_audio *chip, | |||
392 | /* fp->channels is already set in this case */ | 394 | /* fp->channels is already set in this case */ |
393 | ret = parse_audio_format_rates_v2(chip, fp); | 395 | ret = parse_audio_format_rates_v2(chip, fp); |
394 | break; | 396 | break; |
395 | default: | ||
396 | snd_printk(KERN_ERR "%d:%u:%d : invalid protocol version %d\n", | ||
397 | chip->dev->devnum, fp->iface, fp->altsetting, protocol); | ||
398 | return -EINVAL; | ||
399 | } | 397 | } |
400 | 398 | ||
401 | if (fp->channels < 1) { | 399 | if (fp->channels < 1) { |
@@ -438,6 +436,10 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip, | |||
438 | fp->channels = 1; | 436 | fp->channels = 1; |
439 | 437 | ||
440 | switch (protocol) { | 438 | switch (protocol) { |
439 | default: | ||
440 | snd_printdd(KERN_WARNING "%d:%u:%d : invalid protocol version %d, assuming v1\n", | ||
441 | chip->dev->devnum, fp->iface, fp->altsetting, protocol); | ||
442 | /* fall through */ | ||
441 | case UAC_VERSION_1: { | 443 | case UAC_VERSION_1: { |
442 | struct uac_format_type_ii_discrete_descriptor *fmt = _fmt; | 444 | struct uac_format_type_ii_discrete_descriptor *fmt = _fmt; |
443 | brate = le16_to_cpu(fmt->wMaxBitRate); | 445 | brate = le16_to_cpu(fmt->wMaxBitRate); |
@@ -456,10 +458,6 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip, | |||
456 | ret = parse_audio_format_rates_v2(chip, fp); | 458 | ret = parse_audio_format_rates_v2(chip, fp); |
457 | break; | 459 | break; |
458 | } | 460 | } |
459 | default: | ||
460 | snd_printk(KERN_ERR "%d:%u:%d : invalid protocol version %d\n", | ||
461 | chip->dev->devnum, fp->iface, fp->altsetting, protocol); | ||
462 | return -EINVAL; | ||
463 | } | 461 | } |
464 | 462 | ||
465 | return ret; | 463 | return ret; |
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index c166db0057d..3ed3901369c 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c | |||
@@ -2175,7 +2175,15 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, | |||
2175 | } | 2175 | } |
2176 | 2176 | ||
2177 | host_iface = &usb_ifnum_to_if(chip->dev, ctrlif)->altsetting[0]; | 2177 | host_iface = &usb_ifnum_to_if(chip->dev, ctrlif)->altsetting[0]; |
2178 | mixer->protocol = get_iface_desc(host_iface)->bInterfaceProtocol; | 2178 | switch (get_iface_desc(host_iface)->bInterfaceProtocol) { |
2179 | case UAC_VERSION_1: | ||
2180 | default: | ||
2181 | mixer->protocol = UAC_VERSION_1; | ||
2182 | break; | ||
2183 | case UAC_VERSION_2: | ||
2184 | mixer->protocol = UAC_VERSION_2; | ||
2185 | break; | ||
2186 | } | ||
2179 | 2187 | ||
2180 | if ((err = snd_usb_mixer_controls(mixer)) < 0 || | 2188 | if ((err = snd_usb_mixer_controls(mixer)) < 0 || |
2181 | (err = snd_usb_mixer_status_create(mixer)) < 0) | 2189 | (err = snd_usb_mixer_status_create(mixer)) < 0) |
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index 3634cedf930..3b5135c9306 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c | |||
@@ -173,13 +173,12 @@ int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface, | |||
173 | 173 | ||
174 | switch (altsd->bInterfaceProtocol) { | 174 | switch (altsd->bInterfaceProtocol) { |
175 | case UAC_VERSION_1: | 175 | case UAC_VERSION_1: |
176 | default: | ||
176 | return init_pitch_v1(chip, iface, alts, fmt); | 177 | return init_pitch_v1(chip, iface, alts, fmt); |
177 | 178 | ||
178 | case UAC_VERSION_2: | 179 | case UAC_VERSION_2: |
179 | return init_pitch_v2(chip, iface, alts, fmt); | 180 | return init_pitch_v2(chip, iface, alts, fmt); |
180 | } | 181 | } |
181 | |||
182 | return -EINVAL; | ||
183 | } | 182 | } |
184 | 183 | ||
185 | /* | 184 | /* |
diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 4f1fa77c1fe..1950e19af1c 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile | |||
@@ -1017,7 +1017,7 @@ builtin-revert.o wt-status.o: wt-status.h | |||
1017 | # we compile into subdirectories. if the target directory is not the source directory, they might not exists. So | 1017 | # we compile into subdirectories. if the target directory is not the source directory, they might not exists. So |
1018 | # we depend the various files onto their directories. | 1018 | # we depend the various files onto their directories. |
1019 | DIRECTORY_DEPS = $(LIB_OBJS) $(BUILTIN_OBJS) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h | 1019 | DIRECTORY_DEPS = $(LIB_OBJS) $(BUILTIN_OBJS) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h |
1020 | $(DIRECTORY_DEPS): $(sort $(dir $(DIRECTORY_DEPS))) | 1020 | $(DIRECTORY_DEPS): | $(sort $(dir $(DIRECTORY_DEPS))) |
1021 | # In the second step, we make a rule to actually create these directories | 1021 | # In the second step, we make a rule to actually create these directories |
1022 | $(sort $(dir $(DIRECTORY_DEPS))): | 1022 | $(sort $(dir $(DIRECTORY_DEPS))): |
1023 | $(QUIET_MKDIR)$(MKDIR) -p $@ 2>/dev/null | 1023 | $(QUIET_MKDIR)$(MKDIR) -p $@ 2>/dev/null |
diff --git a/tools/perf/perf.h b/tools/perf/perf.h index ef7aa0a0c52..95aaf565c70 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h | |||
@@ -73,6 +73,18 @@ void get_term_dimensions(struct winsize *ws); | |||
73 | #define cpu_relax() asm volatile("":::"memory") | 73 | #define cpu_relax() asm volatile("":::"memory") |
74 | #endif | 74 | #endif |
75 | 75 | ||
76 | #ifdef __mips__ | ||
77 | #include "../../arch/mips/include/asm/unistd.h" | ||
78 | #define rmb() asm volatile( \ | ||
79 | ".set mips2\n\t" \ | ||
80 | "sync\n\t" \ | ||
81 | ".set mips0" \ | ||
82 | : /* no output */ \ | ||
83 | : /* no input */ \ | ||
84 | : "memory") | ||
85 | #define cpu_relax() asm volatile("" ::: "memory") | ||
86 | #endif | ||
87 | |||
76 | #include <time.h> | 88 | #include <time.h> |
77 | #include <unistd.h> | 89 | #include <unistd.h> |
78 | #include <sys/types.h> | 90 | #include <sys/types.h> |
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index 624a96c636f..6de4313924f 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h | |||
@@ -50,6 +50,7 @@ static inline void callchain_init(struct callchain_node *node) | |||
50 | INIT_LIST_HEAD(&node->children); | 50 | INIT_LIST_HEAD(&node->children); |
51 | INIT_LIST_HEAD(&node->val); | 51 | INIT_LIST_HEAD(&node->val); |
52 | 52 | ||
53 | node->children_hit = 0; | ||
53 | node->parent = NULL; | 54 | node->parent = NULL; |
54 | node->hit = 0; | 55 | node->hit = 0; |
55 | } | 56 | } |
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index e72f05c3bef..fcc16e4349d 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c | |||
@@ -1539,6 +1539,7 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev, | |||
1539 | goto error; | 1539 | goto error; |
1540 | } | 1540 | } |
1541 | tev->point.offset = pev->point.offset; | 1541 | tev->point.offset = pev->point.offset; |
1542 | tev->point.retprobe = pev->point.retprobe; | ||
1542 | tev->nargs = pev->nargs; | 1543 | tev->nargs = pev->nargs; |
1543 | if (tev->nargs) { | 1544 | if (tev->nargs) { |
1544 | tev->args = zalloc(sizeof(struct probe_trace_arg) | 1545 | tev->args = zalloc(sizeof(struct probe_trace_arg) |
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 525136684d4..32b81f707ff 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c | |||
@@ -686,6 +686,25 @@ static int find_variable(Dwarf_Die *sp_die, struct probe_finder *pf) | |||
686 | char buf[32], *ptr; | 686 | char buf[32], *ptr; |
687 | int ret, nscopes; | 687 | int ret, nscopes; |
688 | 688 | ||
689 | if (!is_c_varname(pf->pvar->var)) { | ||
690 | /* Copy raw parameters */ | ||
691 | pf->tvar->value = strdup(pf->pvar->var); | ||
692 | if (pf->tvar->value == NULL) | ||
693 | return -ENOMEM; | ||
694 | if (pf->pvar->type) { | ||
695 | pf->tvar->type = strdup(pf->pvar->type); | ||
696 | if (pf->tvar->type == NULL) | ||
697 | return -ENOMEM; | ||
698 | } | ||
699 | if (pf->pvar->name) { | ||
700 | pf->tvar->name = strdup(pf->pvar->name); | ||
701 | if (pf->tvar->name == NULL) | ||
702 | return -ENOMEM; | ||
703 | } else | ||
704 | pf->tvar->name = NULL; | ||
705 | return 0; | ||
706 | } | ||
707 | |||
689 | if (pf->pvar->name) | 708 | if (pf->pvar->name) |
690 | pf->tvar->name = strdup(pf->pvar->name); | 709 | pf->tvar->name = strdup(pf->pvar->name); |
691 | else { | 710 | else { |
@@ -700,19 +719,6 @@ static int find_variable(Dwarf_Die *sp_die, struct probe_finder *pf) | |||
700 | if (pf->tvar->name == NULL) | 719 | if (pf->tvar->name == NULL) |
701 | return -ENOMEM; | 720 | return -ENOMEM; |
702 | 721 | ||
703 | if (!is_c_varname(pf->pvar->var)) { | ||
704 | /* Copy raw parameters */ | ||
705 | pf->tvar->value = strdup(pf->pvar->var); | ||
706 | if (pf->tvar->value == NULL) | ||
707 | return -ENOMEM; | ||
708 | if (pf->pvar->type) { | ||
709 | pf->tvar->type = strdup(pf->pvar->type); | ||
710 | if (pf->tvar->type == NULL) | ||
711 | return -ENOMEM; | ||
712 | } | ||
713 | return 0; | ||
714 | } | ||
715 | |||
716 | pr_debug("Searching '%s' variable in context.\n", | 722 | pr_debug("Searching '%s' variable in context.\n", |
717 | pf->pvar->var); | 723 | pf->pvar->var); |
718 | /* Search child die for local variables and parameters. */ | 724 | /* Search child die for local variables and parameters. */ |
@@ -783,6 +789,16 @@ static int convert_probe_point(Dwarf_Die *sp_die, struct probe_finder *pf) | |||
783 | /* This function has no name. */ | 789 | /* This function has no name. */ |
784 | tev->point.offset = (unsigned long)pf->addr; | 790 | tev->point.offset = (unsigned long)pf->addr; |
785 | 791 | ||
792 | /* Return probe must be on the head of a subprogram */ | ||
793 | if (pf->pev->point.retprobe) { | ||
794 | if (tev->point.offset != 0) { | ||
795 | pr_warning("Return probe must be on the head of" | ||
796 | " a real function\n"); | ||
797 | return -EINVAL; | ||
798 | } | ||
799 | tev->point.retprobe = true; | ||
800 | } | ||
801 | |||
786 | pr_debug("Probe point found: %s+%lu\n", tev->point.symbol, | 802 | pr_debug("Probe point found: %s+%lu\n", tev->point.symbol, |
787 | tev->point.offset); | 803 | tev->point.offset); |
788 | 804 | ||
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 1a367734e01..b2f5ae97f33 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -2268,6 +2268,9 @@ static int setup_list(struct strlist **list, const char *list_str, | |||
2268 | 2268 | ||
2269 | int symbol__init(void) | 2269 | int symbol__init(void) |
2270 | { | 2270 | { |
2271 | if (symbol_conf.initialized) | ||
2272 | return 0; | ||
2273 | |||
2271 | elf_version(EV_CURRENT); | 2274 | elf_version(EV_CURRENT); |
2272 | if (symbol_conf.sort_by_name) | 2275 | if (symbol_conf.sort_by_name) |
2273 | symbol_conf.priv_size += (sizeof(struct symbol_name_rb_node) - | 2276 | symbol_conf.priv_size += (sizeof(struct symbol_name_rb_node) - |
@@ -2293,6 +2296,7 @@ int symbol__init(void) | |||
2293 | symbol_conf.sym_list_str, "symbol") < 0) | 2296 | symbol_conf.sym_list_str, "symbol") < 0) |
2294 | goto out_free_comm_list; | 2297 | goto out_free_comm_list; |
2295 | 2298 | ||
2299 | symbol_conf.initialized = true; | ||
2296 | return 0; | 2300 | return 0; |
2297 | 2301 | ||
2298 | out_free_dso_list: | 2302 | out_free_dso_list: |
@@ -2304,11 +2308,14 @@ out_free_comm_list: | |||
2304 | 2308 | ||
2305 | void symbol__exit(void) | 2309 | void symbol__exit(void) |
2306 | { | 2310 | { |
2311 | if (!symbol_conf.initialized) | ||
2312 | return; | ||
2307 | strlist__delete(symbol_conf.sym_list); | 2313 | strlist__delete(symbol_conf.sym_list); |
2308 | strlist__delete(symbol_conf.dso_list); | 2314 | strlist__delete(symbol_conf.dso_list); |
2309 | strlist__delete(symbol_conf.comm_list); | 2315 | strlist__delete(symbol_conf.comm_list); |
2310 | vmlinux_path__exit(); | 2316 | vmlinux_path__exit(); |
2311 | symbol_conf.sym_list = symbol_conf.dso_list = symbol_conf.comm_list = NULL; | 2317 | symbol_conf.sym_list = symbol_conf.dso_list = symbol_conf.comm_list = NULL; |
2318 | symbol_conf.initialized = false; | ||
2312 | } | 2319 | } |
2313 | 2320 | ||
2314 | int machines__create_kernel_maps(struct rb_root *self, pid_t pid) | 2321 | int machines__create_kernel_maps(struct rb_root *self, pid_t pid) |
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index b7a8da4af5a..ea95c2756f0 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
@@ -69,7 +69,8 @@ struct symbol_conf { | |||
69 | show_nr_samples, | 69 | show_nr_samples, |
70 | use_callchain, | 70 | use_callchain, |
71 | exclude_other, | 71 | exclude_other, |
72 | show_cpu_utilization; | 72 | show_cpu_utilization, |
73 | initialized; | ||
73 | const char *vmlinux_name, | 74 | const char *vmlinux_name, |
74 | *source_prefix, | 75 | *source_prefix, |
75 | *field_sep; | 76 | *field_sep; |
diff --git a/tools/perf/util/trace-event-scripting.c b/tools/perf/util/trace-event-scripting.c index 7ea983acfae..f7af2fca965 100644 --- a/tools/perf/util/trace-event-scripting.c +++ b/tools/perf/util/trace-event-scripting.c | |||
@@ -97,7 +97,7 @@ void setup_python_scripting(void) | |||
97 | register_python_scripting(&python_scripting_unsupported_ops); | 97 | register_python_scripting(&python_scripting_unsupported_ops); |
98 | } | 98 | } |
99 | #else | 99 | #else |
100 | struct scripting_ops python_scripting_ops; | 100 | extern struct scripting_ops python_scripting_ops; |
101 | 101 | ||
102 | void setup_python_scripting(void) | 102 | void setup_python_scripting(void) |
103 | { | 103 | { |
@@ -158,7 +158,7 @@ void setup_perl_scripting(void) | |||
158 | register_perl_scripting(&perl_scripting_unsupported_ops); | 158 | register_perl_scripting(&perl_scripting_unsupported_ops); |
159 | } | 159 | } |
160 | #else | 160 | #else |
161 | struct scripting_ops perl_scripting_ops; | 161 | extern struct scripting_ops perl_scripting_ops; |
162 | 162 | ||
163 | void setup_perl_scripting(void) | 163 | void setup_perl_scripting(void) |
164 | { | 164 | { |
diff --git a/tools/perf/util/ui/browsers/hists.c b/tools/perf/util/ui/browsers/hists.c index dafdf6775d7..6866aa4c41e 100644 --- a/tools/perf/util/ui/browsers/hists.c +++ b/tools/perf/util/ui/browsers/hists.c | |||
@@ -773,7 +773,7 @@ int hists__browse(struct hists *self, const char *helpline, const char *ev_name) | |||
773 | 773 | ||
774 | switch (key) { | 774 | switch (key) { |
775 | case 'a': | 775 | case 'a': |
776 | if (browser->selection->map == NULL && | 776 | if (browser->selection->map == NULL || |
777 | browser->selection->map->dso->annotate_warned) | 777 | browser->selection->map->dso->annotate_warned) |
778 | continue; | 778 | continue; |
779 | goto do_annotate; | 779 | goto do_annotate; |
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c index 66cf65b510b..c1f1e3c6298 100644 --- a/virt/kvm/eventfd.c +++ b/virt/kvm/eventfd.c | |||
@@ -218,7 +218,6 @@ kvm_irqfd_assign(struct kvm *kvm, int fd, int gsi) | |||
218 | events = file->f_op->poll(file, &irqfd->pt); | 218 | events = file->f_op->poll(file, &irqfd->pt); |
219 | 219 | ||
220 | list_add_tail(&irqfd->list, &kvm->irqfds.items); | 220 | list_add_tail(&irqfd->list, &kvm->irqfds.items); |
221 | spin_unlock_irq(&kvm->irqfds.lock); | ||
222 | 221 | ||
223 | /* | 222 | /* |
224 | * Check if there was an event already pending on the eventfd | 223 | * Check if there was an event already pending on the eventfd |
@@ -227,6 +226,8 @@ kvm_irqfd_assign(struct kvm *kvm, int fd, int gsi) | |||
227 | if (events & POLLIN) | 226 | if (events & POLLIN) |
228 | schedule_work(&irqfd->inject); | 227 | schedule_work(&irqfd->inject); |
229 | 228 | ||
229 | spin_unlock_irq(&kvm->irqfds.lock); | ||
230 | |||
230 | /* | 231 | /* |
231 | * do not drop the file until the irqfd is fully initialized, otherwise | 232 | * do not drop the file until the irqfd is fully initialized, otherwise |
232 | * we might race against the POLLHUP | 233 | * we might race against the POLLHUP |
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index b78b794c103..5186e728c53 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -1958,10 +1958,10 @@ static int kvm_cpu_hotplug(struct notifier_block *notifier, unsigned long val, | |||
1958 | cpu); | 1958 | cpu); |
1959 | hardware_disable(NULL); | 1959 | hardware_disable(NULL); |
1960 | break; | 1960 | break; |
1961 | case CPU_ONLINE: | 1961 | case CPU_STARTING: |
1962 | printk(KERN_INFO "kvm: enabling virtualization on CPU%d\n", | 1962 | printk(KERN_INFO "kvm: enabling virtualization on CPU%d\n", |
1963 | cpu); | 1963 | cpu); |
1964 | smp_call_function_single(cpu, hardware_enable, NULL, 1); | 1964 | hardware_enable(NULL); |
1965 | break; | 1965 | break; |
1966 | } | 1966 | } |
1967 | return NOTIFY_OK; | 1967 | return NOTIFY_OK; |
@@ -1970,10 +1970,12 @@ static int kvm_cpu_hotplug(struct notifier_block *notifier, unsigned long val, | |||
1970 | 1970 | ||
1971 | asmlinkage void kvm_handle_fault_on_reboot(void) | 1971 | asmlinkage void kvm_handle_fault_on_reboot(void) |
1972 | { | 1972 | { |
1973 | if (kvm_rebooting) | 1973 | if (kvm_rebooting) { |
1974 | /* spin while reset goes on */ | 1974 | /* spin while reset goes on */ |
1975 | local_irq_enable(); | ||
1975 | while (true) | 1976 | while (true) |
1976 | ; | 1977 | ; |
1978 | } | ||
1977 | /* Fault while not rebooting. We want the trace. */ | 1979 | /* Fault while not rebooting. We want the trace. */ |
1978 | BUG(); | 1980 | BUG(); |
1979 | } | 1981 | } |
@@ -2096,7 +2098,6 @@ int kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx, | |||
2096 | 2098 | ||
2097 | static struct notifier_block kvm_cpu_notifier = { | 2099 | static struct notifier_block kvm_cpu_notifier = { |
2098 | .notifier_call = kvm_cpu_hotplug, | 2100 | .notifier_call = kvm_cpu_hotplug, |
2099 | .priority = 20, /* must be > scheduler priority */ | ||
2100 | }; | 2101 | }; |
2101 | 2102 | ||
2102 | static int vm_stat_get(void *_offset, u64 *val) | 2103 | static int vm_stat_get(void *_offset, u64 *val) |