diff options
author | Tony Lindgren <tony@atomide.com> | 2011-06-13 10:40:25 -0400 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2011-06-13 10:40:25 -0400 |
commit | c8e0bf95fc01d6e2ca585fe08010800b6c56e823 (patch) | |
tree | f901bdcb5b20e93261cf9cf324ebbcf3fd24ce58 | |
parent | 9d5ae7cd6cb9ead43336fec1094184d1dc740fbd (diff) | |
parent | 345f79b3de7f6d651e4dba794af7c7303bdfd649 (diff) |
Merge branch 'for_3.0/pm-fixes' of ssh://master.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap-pm into fixes
529 files changed, 15348 insertions, 6583 deletions
diff --git a/Documentation/RCU/trace.txt b/Documentation/RCU/trace.txt index c078ad48f7a1..8173cec473aa 100644 --- a/Documentation/RCU/trace.txt +++ b/Documentation/RCU/trace.txt | |||
@@ -99,18 +99,11 @@ o "qp" indicates that RCU still expects a quiescent state from | |||
99 | 99 | ||
100 | o "dt" is the current value of the dyntick counter that is incremented | 100 | o "dt" is the current value of the dyntick counter that is incremented |
101 | when entering or leaving dynticks idle state, either by the | 101 | when entering or leaving dynticks idle state, either by the |
102 | scheduler or by irq. The number after the "/" is the interrupt | 102 | scheduler or by irq. This number is even if the CPU is in |
103 | nesting depth when in dyntick-idle state, or one greater than | 103 | dyntick idle mode and odd otherwise. The number after the first |
104 | the interrupt-nesting depth otherwise. | 104 | "/" is the interrupt nesting depth when in dyntick-idle state, |
105 | 105 | or one greater than the interrupt-nesting depth otherwise. | |
106 | This field is displayed only for CONFIG_NO_HZ kernels. | 106 | The number after the second "/" is the NMI nesting depth. |
107 | |||
108 | o "dn" is the current value of the dyntick counter that is incremented | ||
109 | when entering or leaving dynticks idle state via NMI. If both | ||
110 | the "dt" and "dn" values are even, then this CPU is in dynticks | ||
111 | idle mode and may be ignored by RCU. If either of these two | ||
112 | counters is odd, then RCU must be alert to the possibility of | ||
113 | an RCU read-side critical section running on this CPU. | ||
114 | 107 | ||
115 | This field is displayed only for CONFIG_NO_HZ kernels. | 108 | This field is displayed only for CONFIG_NO_HZ kernels. |
116 | 109 | ||
diff --git a/Documentation/acpi/method-customizing.txt b/Documentation/acpi/method-customizing.txt index 3e1d25aee3fb..5f55373dd53b 100644 --- a/Documentation/acpi/method-customizing.txt +++ b/Documentation/acpi/method-customizing.txt | |||
@@ -66,3 +66,8 @@ Note: We can use a kernel with multiple custom ACPI method running, | |||
66 | But each individual write to debugfs can implement a SINGLE | 66 | But each individual write to debugfs can implement a SINGLE |
67 | method override. i.e. if we want to insert/override multiple | 67 | method override. i.e. if we want to insert/override multiple |
68 | ACPI methods, we need to redo step c) ~ g) for multiple times. | 68 | ACPI methods, we need to redo step c) ~ g) for multiple times. |
69 | |||
70 | Note: Be aware that root can mis-use this driver to modify arbitrary | ||
71 | memory and gain additional rights, if root's privileges got | ||
72 | restricted (for example if root is not allowed to load additional | ||
73 | modules after boot). | ||
diff --git a/Documentation/dmaengine.txt b/Documentation/dmaengine.txt index 0c1c2f63c0a9..5a0cb1ef6164 100644 --- a/Documentation/dmaengine.txt +++ b/Documentation/dmaengine.txt | |||
@@ -1 +1,96 @@ | |||
1 | See Documentation/crypto/async-tx-api.txt | 1 | DMA Engine API Guide |
2 | ==================== | ||
3 | |||
4 | Vinod Koul <vinod dot koul at intel.com> | ||
5 | |||
6 | NOTE: For DMA Engine usage in async_tx please see: | ||
7 | Documentation/crypto/async-tx-api.txt | ||
8 | |||
9 | |||
10 | Below is a guide to device driver writers on how to use the Slave-DMA API of the | ||
11 | DMA Engine. This is applicable only for slave DMA usage only. | ||
12 | |||
13 | The slave DMA usage consists of following steps | ||
14 | 1. Allocate a DMA slave channel | ||
15 | 2. Set slave and controller specific parameters | ||
16 | 3. Get a descriptor for transaction | ||
17 | 4. Submit the transaction and wait for callback notification | ||
18 | |||
19 | 1. Allocate a DMA slave channel | ||
20 | Channel allocation is slightly different in the slave DMA context, client | ||
21 | drivers typically need a channel from a particular DMA controller only and even | ||
22 | in some cases a specific channel is desired. To request a channel | ||
23 | dma_request_channel() API is used. | ||
24 | |||
25 | Interface: | ||
26 | struct dma_chan *dma_request_channel(dma_cap_mask_t mask, | ||
27 | dma_filter_fn filter_fn, | ||
28 | void *filter_param); | ||
29 | where dma_filter_fn is defined as: | ||
30 | typedef bool (*dma_filter_fn)(struct dma_chan *chan, void *filter_param); | ||
31 | |||
32 | When the optional 'filter_fn' parameter is set to NULL dma_request_channel | ||
33 | simply returns the first channel that satisfies the capability mask. Otherwise, | ||
34 | when the mask parameter is insufficient for specifying the necessary channel, | ||
35 | the filter_fn routine can be used to disposition the available channels in the | ||
36 | system. The filter_fn routine is called once for each free channel in the | ||
37 | system. Upon seeing a suitable channel filter_fn returns DMA_ACK which flags | ||
38 | that channel to be the return value from dma_request_channel. A channel | ||
39 | allocated via this interface is exclusive to the caller, until | ||
40 | dma_release_channel() is called. | ||
41 | |||
42 | 2. Set slave and controller specific parameters | ||
43 | Next step is always to pass some specific information to the DMA driver. Most of | ||
44 | the generic information which a slave DMA can use is in struct dma_slave_config. | ||
45 | It allows the clients to specify DMA direction, DMA addresses, bus widths, DMA | ||
46 | burst lengths etc. If some DMA controllers have more parameters to be sent then | ||
47 | they should try to embed struct dma_slave_config in their controller specific | ||
48 | structure. That gives flexibility to client to pass more parameters, if | ||
49 | required. | ||
50 | |||
51 | Interface: | ||
52 | int dmaengine_slave_config(struct dma_chan *chan, | ||
53 | struct dma_slave_config *config) | ||
54 | |||
55 | 3. Get a descriptor for transaction | ||
56 | For slave usage the various modes of slave transfers supported by the | ||
57 | DMA-engine are: | ||
58 | slave_sg - DMA a list of scatter gather buffers from/to a peripheral | ||
59 | dma_cyclic - Perform a cyclic DMA operation from/to a peripheral till the | ||
60 | operation is explicitly stopped. | ||
61 | The non NULL return of this transfer API represents a "descriptor" for the given | ||
62 | transaction. | ||
63 | |||
64 | Interface: | ||
65 | struct dma_async_tx_descriptor *(*chan->device->device_prep_dma_sg)( | ||
66 | struct dma_chan *chan, | ||
67 | struct scatterlist *dst_sg, unsigned int dst_nents, | ||
68 | struct scatterlist *src_sg, unsigned int src_nents, | ||
69 | unsigned long flags); | ||
70 | struct dma_async_tx_descriptor *(*chan->device->device_prep_dma_cyclic)( | ||
71 | struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len, | ||
72 | size_t period_len, enum dma_data_direction direction); | ||
73 | |||
74 | 4. Submit the transaction and wait for callback notification | ||
75 | To schedule the transaction to be scheduled by dma device, the "descriptor" | ||
76 | returned in above (3) needs to be submitted. | ||
77 | To tell the dma driver that a transaction is ready to be serviced, the | ||
78 | descriptor->submit() callback needs to be invoked. This chains the descriptor to | ||
79 | the pending queue. | ||
80 | The transactions in the pending queue can be activated by calling the | ||
81 | issue_pending API. If channel is idle then the first transaction in queue is | ||
82 | started and subsequent ones queued up. | ||
83 | On completion of the DMA operation the next in queue is submitted and a tasklet | ||
84 | triggered. The tasklet would then call the client driver completion callback | ||
85 | routine for notification, if set. | ||
86 | Interface: | ||
87 | void dma_async_issue_pending(struct dma_chan *chan); | ||
88 | |||
89 | ============================================================================== | ||
90 | |||
91 | Additional usage notes for dma driver writers | ||
92 | 1/ Although DMA engine specifies that completion callback routines cannot submit | ||
93 | any new operations, but typically for slave DMA subsequent transaction may not | ||
94 | be available for submit prior to callback routine being called. This requirement | ||
95 | is not a requirement for DMA-slave devices. But they should take care to drop | ||
96 | the spin-lock they might be holding before calling the callback routine | ||
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index ff31b1cc50aa..1a9446b59153 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
@@ -6,6 +6,42 @@ be removed from this file. | |||
6 | 6 | ||
7 | --------------------------- | 7 | --------------------------- |
8 | 8 | ||
9 | What: x86 floppy disable_hlt | ||
10 | When: 2012 | ||
11 | Why: ancient workaround of dubious utility clutters the | ||
12 | code used by everybody else. | ||
13 | Who: Len Brown <len.brown@intel.com> | ||
14 | |||
15 | --------------------------- | ||
16 | |||
17 | What: CONFIG_APM_CPU_IDLE, and its ability to call APM BIOS in idle | ||
18 | When: 2012 | ||
19 | Why: This optional sub-feature of APM is of dubious reliability, | ||
20 | and ancient APM laptops are likely better served by calling HLT. | ||
21 | Deleting CONFIG_APM_CPU_IDLE allows x86 to stop exporting | ||
22 | the pm_idle function pointer to modules. | ||
23 | Who: Len Brown <len.brown@intel.com> | ||
24 | |||
25 | ---------------------------- | ||
26 | |||
27 | What: x86_32 "no-hlt" cmdline param | ||
28 | When: 2012 | ||
29 | Why: remove a branch from idle path, simplify code used by everybody. | ||
30 | This option disabled the use of HLT in idle and machine_halt() | ||
31 | for hardware that was flakey 15-years ago. Today we have | ||
32 | "idle=poll" that removed HLT from idle, and so if such a machine | ||
33 | is still running the upstream kernel, "idle=poll" is likely sufficient. | ||
34 | Who: Len Brown <len.brown@intel.com> | ||
35 | |||
36 | ---------------------------- | ||
37 | |||
38 | What: x86 "idle=mwait" cmdline param | ||
39 | When: 2012 | ||
40 | Why: simplify x86 idle code | ||
41 | Who: Len Brown <len.brown@intel.com> | ||
42 | |||
43 | ---------------------------- | ||
44 | |||
9 | What: PRISM54 | 45 | What: PRISM54 |
10 | When: 2.6.34 | 46 | When: 2.6.34 |
11 | 47 | ||
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index 61b31acb9176..57d827d6071d 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking | |||
@@ -104,7 +104,7 @@ of the locking scheme for directory operations. | |||
104 | prototypes: | 104 | prototypes: |
105 | struct inode *(*alloc_inode)(struct super_block *sb); | 105 | struct inode *(*alloc_inode)(struct super_block *sb); |
106 | void (*destroy_inode)(struct inode *); | 106 | void (*destroy_inode)(struct inode *); |
107 | void (*dirty_inode) (struct inode *); | 107 | void (*dirty_inode) (struct inode *, int flags); |
108 | int (*write_inode) (struct inode *, struct writeback_control *wbc); | 108 | int (*write_inode) (struct inode *, struct writeback_control *wbc); |
109 | int (*drop_inode) (struct inode *); | 109 | int (*drop_inode) (struct inode *); |
110 | void (*evict_inode) (struct inode *); | 110 | void (*evict_inode) (struct inode *); |
@@ -126,7 +126,7 @@ locking rules: | |||
126 | s_umount | 126 | s_umount |
127 | alloc_inode: | 127 | alloc_inode: |
128 | destroy_inode: | 128 | destroy_inode: |
129 | dirty_inode: (must not sleep) | 129 | dirty_inode: |
130 | write_inode: | 130 | write_inode: |
131 | drop_inode: !!!inode->i_lock!!! | 131 | drop_inode: !!!inode->i_lock!!! |
132 | evict_inode: | 132 | evict_inode: |
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index 21a7dc467bba..88b9f5519af9 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt | |||
@@ -211,7 +211,7 @@ struct super_operations { | |||
211 | struct inode *(*alloc_inode)(struct super_block *sb); | 211 | struct inode *(*alloc_inode)(struct super_block *sb); |
212 | void (*destroy_inode)(struct inode *); | 212 | void (*destroy_inode)(struct inode *); |
213 | 213 | ||
214 | void (*dirty_inode) (struct inode *); | 214 | void (*dirty_inode) (struct inode *, int flags); |
215 | int (*write_inode) (struct inode *, int); | 215 | int (*write_inode) (struct inode *, int); |
216 | void (*drop_inode) (struct inode *); | 216 | void (*drop_inode) (struct inode *); |
217 | void (*delete_inode) (struct inode *); | 217 | void (*delete_inode) (struct inode *); |
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 5438a2d7907f..d9a203b058f1 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -999,7 +999,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
999 | With this option on every unmap_single operation will | 999 | With this option on every unmap_single operation will |
1000 | result in a hardware IOTLB flush operation as opposed | 1000 | result in a hardware IOTLB flush operation as opposed |
1001 | to batching them for performance. | 1001 | to batching them for performance. |
1002 | 1002 | sp_off [Default Off] | |
1003 | By default, super page will be supported if Intel IOMMU | ||
1004 | has the capability. With this option, super page will | ||
1005 | not be supported. | ||
1003 | intremap= [X86-64, Intel-IOMMU] | 1006 | intremap= [X86-64, Intel-IOMMU] |
1004 | Format: { on (default) | off | nosid } | 1007 | Format: { on (default) | off | nosid } |
1005 | on enable Interrupt Remapping (default) | 1008 | on enable Interrupt Remapping (default) |
diff --git a/Documentation/laptops/acer-wmi.txt b/Documentation/laptops/acer-wmi.txt deleted file mode 100644 index 4beafa663dd6..000000000000 --- a/Documentation/laptops/acer-wmi.txt +++ /dev/null | |||
@@ -1,184 +0,0 @@ | |||
1 | Acer Laptop WMI Extras Driver | ||
2 | http://code.google.com/p/aceracpi | ||
3 | Version 0.3 | ||
4 | 4th April 2009 | ||
5 | |||
6 | Copyright 2007-2009 Carlos Corbacho <carlos@strangeworlds.co.uk> | ||
7 | |||
8 | acer-wmi is a driver to allow you to control various parts of your Acer laptop | ||
9 | hardware under Linux which are exposed via ACPI-WMI. | ||
10 | |||
11 | This driver completely replaces the old out-of-tree acer_acpi, which I am | ||
12 | currently maintaining for bug fixes only on pre-2.6.25 kernels. All development | ||
13 | work is now focused solely on acer-wmi. | ||
14 | |||
15 | Disclaimer | ||
16 | ********** | ||
17 | |||
18 | Acer and Wistron have provided nothing towards the development acer_acpi or | ||
19 | acer-wmi. All information we have has been through the efforts of the developers | ||
20 | and the users to discover as much as possible about the hardware. | ||
21 | |||
22 | As such, I do warn that this could break your hardware - this is extremely | ||
23 | unlikely of course, but please bear this in mind. | ||
24 | |||
25 | Background | ||
26 | ********** | ||
27 | |||
28 | acer-wmi is derived from acer_acpi, originally developed by Mark | ||
29 | Smith in 2005, then taken over by Carlos Corbacho in 2007, in order to activate | ||
30 | the wireless LAN card under a 64-bit version of Linux, as acerhk[1] (the | ||
31 | previous solution to the problem) relied on making 32 bit BIOS calls which are | ||
32 | not possible in kernel space from a 64 bit OS. | ||
33 | |||
34 | [1] acerhk: http://www.cakey.de/acerhk/ | ||
35 | |||
36 | Supported Hardware | ||
37 | ****************** | ||
38 | |||
39 | NOTE: The Acer Aspire One is not supported hardware. It cannot work with | ||
40 | acer-wmi until Acer fix their ACPI-WMI implementation on them, so has been | ||
41 | blacklisted until that happens. | ||
42 | |||
43 | Please see the website for the current list of known working hardware: | ||
44 | |||
45 | http://code.google.com/p/aceracpi/wiki/SupportedHardware | ||
46 | |||
47 | If your laptop is not listed, or listed as unknown, and works with acer-wmi, | ||
48 | please contact me with a copy of the DSDT. | ||
49 | |||
50 | If your Acer laptop doesn't work with acer-wmi, I would also like to see the | ||
51 | DSDT. | ||
52 | |||
53 | To send me the DSDT, as root/sudo: | ||
54 | |||
55 | cat /sys/firmware/acpi/tables/DSDT > dsdt | ||
56 | |||
57 | And send me the resulting 'dsdt' file. | ||
58 | |||
59 | Usage | ||
60 | ***** | ||
61 | |||
62 | On Acer laptops, acer-wmi should already be autoloaded based on DMI matching. | ||
63 | For non-Acer laptops, until WMI based autoloading support is added, you will | ||
64 | need to manually load acer-wmi. | ||
65 | |||
66 | acer-wmi creates /sys/devices/platform/acer-wmi, and fills it with various | ||
67 | files whose usage is detailed below, which enables you to control some of the | ||
68 | following (varies between models): | ||
69 | |||
70 | * the wireless LAN card radio | ||
71 | * inbuilt Bluetooth adapter | ||
72 | * inbuilt 3G card | ||
73 | * mail LED of your laptop | ||
74 | * brightness of the LCD panel | ||
75 | |||
76 | Wireless | ||
77 | ******** | ||
78 | |||
79 | With regards to wireless, all acer-wmi does is enable the radio on the card. It | ||
80 | is not responsible for the wireless LED - once the radio is enabled, this is | ||
81 | down to the wireless driver for your card. So the behaviour of the wireless LED, | ||
82 | once you enable the radio, will depend on your hardware and driver combination. | ||
83 | |||
84 | e.g. With the BCM4318 on the Acer Aspire 5020 series: | ||
85 | |||
86 | ndiswrapper: Light blinks on when transmitting | ||
87 | b43: Solid light, blinks off when transmitting | ||
88 | |||
89 | Wireless radio control is unconditionally enabled - all Acer laptops that support | ||
90 | acer-wmi come with built-in wireless. However, should you feel so inclined to | ||
91 | ever wish to remove the card, or swap it out at some point, please get in touch | ||
92 | with me, as we may well be able to gain some data on wireless card detection. | ||
93 | |||
94 | The wireless radio is exposed through rfkill. | ||
95 | |||
96 | Bluetooth | ||
97 | ********* | ||
98 | |||
99 | For bluetooth, this is an internal USB dongle, so once enabled, you will get | ||
100 | a USB device connection event, and a new USB device appears. When you disable | ||
101 | bluetooth, you get the reverse - a USB device disconnect event, followed by the | ||
102 | device disappearing again. | ||
103 | |||
104 | Bluetooth is autodetected by acer-wmi, so if you do not have a bluetooth module | ||
105 | installed in your laptop, this file won't exist (please be aware that it is | ||
106 | quite common for Acer not to fit bluetooth to their laptops - so just because | ||
107 | you have a bluetooth button on the laptop, doesn't mean that bluetooth is | ||
108 | installed). | ||
109 | |||
110 | For the adventurously minded - if you want to buy an internal bluetooth | ||
111 | module off the internet that is compatible with your laptop and fit it, then | ||
112 | it will work just fine with acer-wmi. | ||
113 | |||
114 | Bluetooth is exposed through rfkill. | ||
115 | |||
116 | 3G | ||
117 | ** | ||
118 | |||
119 | 3G is currently not autodetected, so the 'threeg' file is always created under | ||
120 | sysfs. So far, no-one in possession of an Acer laptop with 3G built-in appears to | ||
121 | have tried Linux, or reported back, so we don't have any information on this. | ||
122 | |||
123 | If you have an Acer laptop that does have a 3G card in, please contact me so we | ||
124 | can properly detect these, and find out a bit more about them. | ||
125 | |||
126 | To read the status of the 3G card (0=off, 1=on): | ||
127 | cat /sys/devices/platform/acer-wmi/threeg | ||
128 | |||
129 | To enable the 3G card: | ||
130 | echo 1 > /sys/devices/platform/acer-wmi/threeg | ||
131 | |||
132 | To disable the 3G card: | ||
133 | echo 0 > /sys/devices/platform/acer-wmi/threeg | ||
134 | |||
135 | To set the state of the 3G card when loading acer-wmi, pass: | ||
136 | threeg=X (where X is 0 or 1) | ||
137 | |||
138 | Mail LED | ||
139 | ******** | ||
140 | |||
141 | This can be found in most older Acer laptops supported by acer-wmi, and many | ||
142 | newer ones - it is built into the 'mail' button, and blinks when active. | ||
143 | |||
144 | On newer (WMID) laptops though, we have no way of detecting the mail LED. If | ||
145 | your laptop identifies itself in dmesg as a WMID model, then please try loading | ||
146 | acer_acpi with: | ||
147 | |||
148 | force_series=2490 | ||
149 | |||
150 | This will use a known alternative method of reading/ writing the mail LED. If | ||
151 | it works, please report back to me with the DMI data from your laptop so this | ||
152 | can be added to acer-wmi. | ||
153 | |||
154 | The LED is exposed through the LED subsystem, and can be found in: | ||
155 | |||
156 | /sys/devices/platform/acer-wmi/leds/acer-wmi::mail/ | ||
157 | |||
158 | The mail LED is autodetected, so if you don't have one, the LED device won't | ||
159 | be registered. | ||
160 | |||
161 | Backlight | ||
162 | ********* | ||
163 | |||
164 | The backlight brightness control is available on all acer-wmi supported | ||
165 | hardware. The maximum brightness level is usually 15, but on some newer laptops | ||
166 | it's 10 (this is again autodetected). | ||
167 | |||
168 | The backlight is exposed through the backlight subsystem, and can be found in: | ||
169 | |||
170 | /sys/devices/platform/acer-wmi/backlight/acer-wmi/ | ||
171 | |||
172 | Credits | ||
173 | ******* | ||
174 | |||
175 | Olaf Tauber, who did the real hard work when he developed acerhk | ||
176 | http://www.cakey.de/acerhk/ | ||
177 | All the authors of laptop ACPI modules in the kernel, whose work | ||
178 | was an inspiration in the early days of acer_acpi | ||
179 | Mathieu Segaud, who solved the problem with having to modprobe the driver | ||
180 | twice in acer_acpi 0.2. | ||
181 | Jim Ramsay, who added support for the WMID interface | ||
182 | Mark Smith, who started the original acer_acpi | ||
183 | |||
184 | And the many people who have used both acer_acpi and acer-wmi. | ||
diff --git a/Documentation/lockstat.txt b/Documentation/lockstat.txt index 9c0a80d17a23..cef00d42ed5b 100644 --- a/Documentation/lockstat.txt +++ b/Documentation/lockstat.txt | |||
@@ -12,8 +12,9 @@ Because things like lock contention can severely impact performance. | |||
12 | - HOW | 12 | - HOW |
13 | 13 | ||
14 | Lockdep already has hooks in the lock functions and maps lock instances to | 14 | Lockdep already has hooks in the lock functions and maps lock instances to |
15 | lock classes. We build on that. The graph below shows the relation between | 15 | lock classes. We build on that (see Documentation/lockdep-design.txt). |
16 | the lock functions and the various hooks therein. | 16 | The graph below shows the relation between the lock functions and the various |
17 | hooks therein. | ||
17 | 18 | ||
18 | __acquire | 19 | __acquire |
19 | | | 20 | | |
@@ -128,6 +129,37 @@ points are the points we're contending with. | |||
128 | 129 | ||
129 | The integer part of the time values is in us. | 130 | The integer part of the time values is in us. |
130 | 131 | ||
132 | Dealing with nested locks, subclasses may appear: | ||
133 | |||
134 | 32............................................................................................................................................................................................... | ||
135 | 33 | ||
136 | 34 &rq->lock: 13128 13128 0.43 190.53 103881.26 97454 3453404 0.00 401.11 13224683.11 | ||
137 | 35 --------- | ||
138 | 36 &rq->lock 645 [<ffffffff8103bfc4>] task_rq_lock+0x43/0x75 | ||
139 | 37 &rq->lock 297 [<ffffffff8104ba65>] try_to_wake_up+0x127/0x25a | ||
140 | 38 &rq->lock 360 [<ffffffff8103c4c5>] select_task_rq_fair+0x1f0/0x74a | ||
141 | 39 &rq->lock 428 [<ffffffff81045f98>] scheduler_tick+0x46/0x1fb | ||
142 | 40 --------- | ||
143 | 41 &rq->lock 77 [<ffffffff8103bfc4>] task_rq_lock+0x43/0x75 | ||
144 | 42 &rq->lock 174 [<ffffffff8104ba65>] try_to_wake_up+0x127/0x25a | ||
145 | 43 &rq->lock 4715 [<ffffffff8103ed4b>] double_rq_lock+0x42/0x54 | ||
146 | 44 &rq->lock 893 [<ffffffff81340524>] schedule+0x157/0x7b8 | ||
147 | 45 | ||
148 | 46............................................................................................................................................................................................... | ||
149 | 47 | ||
150 | 48 &rq->lock/1: 11526 11488 0.33 388.73 136294.31 21461 38404 0.00 37.93 109388.53 | ||
151 | 49 ----------- | ||
152 | 50 &rq->lock/1 11526 [<ffffffff8103ed58>] double_rq_lock+0x4f/0x54 | ||
153 | 51 ----------- | ||
154 | 52 &rq->lock/1 5645 [<ffffffff8103ed4b>] double_rq_lock+0x42/0x54 | ||
155 | 53 &rq->lock/1 1224 [<ffffffff81340524>] schedule+0x157/0x7b8 | ||
156 | 54 &rq->lock/1 4336 [<ffffffff8103ed58>] double_rq_lock+0x4f/0x54 | ||
157 | 55 &rq->lock/1 181 [<ffffffff8104ba65>] try_to_wake_up+0x127/0x25a | ||
158 | |||
159 | Line 48 shows statistics for the second subclass (/1) of &rq->lock class | ||
160 | (subclass starts from 0), since in this case, as line 50 suggests, | ||
161 | double_rq_lock actually acquires a nested lock of two spinlocks. | ||
162 | |||
131 | View the top contending locks: | 163 | View the top contending locks: |
132 | 164 | ||
133 | # grep : /proc/lock_stat | head | 165 | # grep : /proc/lock_stat | head |
diff --git a/Documentation/virtual/lguest/Makefile b/Documentation/virtual/lguest/Makefile index bebac6b4f332..0ac34206f7a7 100644 --- a/Documentation/virtual/lguest/Makefile +++ b/Documentation/virtual/lguest/Makefile | |||
@@ -1,5 +1,5 @@ | |||
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 | # Missing headers? Add "-I../../include -I../../arch/x86/include" | 2 | # Missing headers? Add "-I../../../include -I../../../arch/x86/include" |
3 | CFLAGS:=-m32 -Wall -Wmissing-declarations -Wmissing-prototypes -O3 -U_FORTIFY_SOURCE | 3 | CFLAGS:=-m32 -Wall -Wmissing-declarations -Wmissing-prototypes -O3 -U_FORTIFY_SOURCE |
4 | 4 | ||
5 | all: lguest | 5 | all: lguest |
diff --git a/Documentation/virtual/lguest/lguest.c b/Documentation/virtual/lguest/lguest.c index d9da7e148538..cd9d6af61d07 100644 --- a/Documentation/virtual/lguest/lguest.c +++ b/Documentation/virtual/lguest/lguest.c | |||
@@ -49,7 +49,7 @@ | |||
49 | #include <linux/virtio_rng.h> | 49 | #include <linux/virtio_rng.h> |
50 | #include <linux/virtio_ring.h> | 50 | #include <linux/virtio_ring.h> |
51 | #include <asm/bootparam.h> | 51 | #include <asm/bootparam.h> |
52 | #include "../../include/linux/lguest_launcher.h" | 52 | #include "../../../include/linux/lguest_launcher.h" |
53 | /*L:110 | 53 | /*L:110 |
54 | * We can ignore the 42 include files we need for this program, but I do want | 54 | * We can ignore the 42 include files we need for this program, but I do want |
55 | * to draw attention to the use of kernel-style types. | 55 | * to draw attention to the use of kernel-style types. |
@@ -135,9 +135,6 @@ struct device { | |||
135 | /* Is it operational */ | 135 | /* Is it operational */ |
136 | bool running; | 136 | bool running; |
137 | 137 | ||
138 | /* Does Guest want an intrrupt on empty? */ | ||
139 | bool irq_on_empty; | ||
140 | |||
141 | /* Device-specific data. */ | 138 | /* Device-specific data. */ |
142 | void *priv; | 139 | void *priv; |
143 | }; | 140 | }; |
@@ -637,10 +634,7 @@ static void trigger_irq(struct virtqueue *vq) | |||
637 | 634 | ||
638 | /* If they don't want an interrupt, don't send one... */ | 635 | /* If they don't want an interrupt, don't send one... */ |
639 | if (vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT) { | 636 | if (vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT) { |
640 | /* ... unless they've asked us to force one on empty. */ | 637 | return; |
641 | if (!vq->dev->irq_on_empty | ||
642 | || lg_last_avail(vq) != vq->vring.avail->idx) | ||
643 | return; | ||
644 | } | 638 | } |
645 | 639 | ||
646 | /* Send the Guest an interrupt tell them we used something up. */ | 640 | /* Send the Guest an interrupt tell them we used something up. */ |
@@ -1057,15 +1051,6 @@ static void create_thread(struct virtqueue *vq) | |||
1057 | close(vq->eventfd); | 1051 | close(vq->eventfd); |
1058 | } | 1052 | } |
1059 | 1053 | ||
1060 | static bool accepted_feature(struct device *dev, unsigned int bit) | ||
1061 | { | ||
1062 | const u8 *features = get_feature_bits(dev) + dev->feature_len; | ||
1063 | |||
1064 | if (dev->feature_len < bit / CHAR_BIT) | ||
1065 | return false; | ||
1066 | return features[bit / CHAR_BIT] & (1 << (bit % CHAR_BIT)); | ||
1067 | } | ||
1068 | |||
1069 | static void start_device(struct device *dev) | 1054 | static void start_device(struct device *dev) |
1070 | { | 1055 | { |
1071 | unsigned int i; | 1056 | unsigned int i; |
@@ -1079,8 +1064,6 @@ static void start_device(struct device *dev) | |||
1079 | verbose(" %02x", get_feature_bits(dev) | 1064 | verbose(" %02x", get_feature_bits(dev) |
1080 | [dev->feature_len+i]); | 1065 | [dev->feature_len+i]); |
1081 | 1066 | ||
1082 | dev->irq_on_empty = accepted_feature(dev, VIRTIO_F_NOTIFY_ON_EMPTY); | ||
1083 | |||
1084 | for (vq = dev->vq; vq; vq = vq->next) { | 1067 | for (vq = dev->vq; vq; vq = vq->next) { |
1085 | if (vq->service) | 1068 | if (vq->service) |
1086 | create_thread(vq); | 1069 | create_thread(vq); |
@@ -1564,7 +1547,6 @@ static void setup_tun_net(char *arg) | |||
1564 | /* Set up the tun device. */ | 1547 | /* Set up the tun device. */ |
1565 | configure_device(ipfd, tapif, ip); | 1548 | configure_device(ipfd, tapif, ip); |
1566 | 1549 | ||
1567 | add_feature(dev, VIRTIO_F_NOTIFY_ON_EMPTY); | ||
1568 | /* Expect Guest to handle everything except UFO */ | 1550 | /* Expect Guest to handle everything except UFO */ |
1569 | add_feature(dev, VIRTIO_NET_F_CSUM); | 1551 | add_feature(dev, VIRTIO_NET_F_CSUM); |
1570 | add_feature(dev, VIRTIO_NET_F_GUEST_CSUM); | 1552 | add_feature(dev, VIRTIO_NET_F_GUEST_CSUM); |
diff --git a/MAINTAINERS b/MAINTAINERS index b9f5aee36375..29801f760b6f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -223,10 +223,8 @@ S: Maintained | |||
223 | F: drivers/platform/x86/acerhdf.c | 223 | F: drivers/platform/x86/acerhdf.c |
224 | 224 | ||
225 | ACER WMI LAPTOP EXTRAS | 225 | ACER WMI LAPTOP EXTRAS |
226 | M: Carlos Corbacho <carlos@strangeworlds.co.uk> | 226 | M: Joey Lee <jlee@novell.com> |
227 | L: aceracpi@googlegroups.com (subscribers-only) | ||
228 | L: platform-driver-x86@vger.kernel.org | 227 | L: platform-driver-x86@vger.kernel.org |
229 | W: http://code.google.com/p/aceracpi | ||
230 | S: Maintained | 228 | S: Maintained |
231 | F: drivers/platform/x86/acer-wmi.c | 229 | F: drivers/platform/x86/acer-wmi.c |
232 | 230 | ||
@@ -271,10 +269,8 @@ S: Supported | |||
271 | F: drivers/acpi/video.c | 269 | F: drivers/acpi/video.c |
272 | 270 | ||
273 | ACPI WMI DRIVER | 271 | ACPI WMI DRIVER |
274 | M: Carlos Corbacho <carlos@strangeworlds.co.uk> | ||
275 | L: platform-driver-x86@vger.kernel.org | 272 | L: platform-driver-x86@vger.kernel.org |
276 | W: http://www.lesswatts.org/projects/acpi/ | 273 | S: Orphan |
277 | S: Maintained | ||
278 | F: drivers/platform/x86/wmi.c | 274 | F: drivers/platform/x86/wmi.c |
279 | 275 | ||
280 | AD1889 ALSA SOUND DRIVER | 276 | AD1889 ALSA SOUND DRIVER |
@@ -2178,6 +2174,8 @@ M: Dan Williams <dan.j.williams@intel.com> | |||
2178 | S: Supported | 2174 | S: Supported |
2179 | F: drivers/dma/ | 2175 | F: drivers/dma/ |
2180 | F: include/linux/dma* | 2176 | F: include/linux/dma* |
2177 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/djbw/async_tx.git | ||
2178 | T: git git://git.infradead.org/users/vkoul/slave-dma.git (slave-dma) | ||
2181 | 2179 | ||
2182 | DME1737 HARDWARE MONITOR DRIVER | 2180 | DME1737 HARDWARE MONITOR DRIVER |
2183 | M: Juerg Haefliger <juergh@gmail.com> | 2181 | M: Juerg Haefliger <juergh@gmail.com> |
@@ -3031,9 +3029,8 @@ S: Maintained | |||
3031 | F: drivers/net/wireless/hostap/ | 3029 | F: drivers/net/wireless/hostap/ |
3032 | 3030 | ||
3033 | HP COMPAQ TC1100 TABLET WMI EXTRAS DRIVER | 3031 | HP COMPAQ TC1100 TABLET WMI EXTRAS DRIVER |
3034 | M: Carlos Corbacho <carlos@strangeworlds.co.uk> | ||
3035 | L: platform-driver-x86@vger.kernel.org | 3032 | L: platform-driver-x86@vger.kernel.org |
3036 | S: Odd Fixes | 3033 | S: Orphan |
3037 | F: drivers/platform/x86/tc1100-wmi.c | 3034 | F: drivers/platform/x86/tc1100-wmi.c |
3038 | 3035 | ||
3039 | HP100: Driver for HP 10/100 Mbit/s Voice Grade Network Adapter Series | 3036 | HP100: Driver for HP 10/100 Mbit/s Voice Grade Network Adapter Series |
@@ -5451,6 +5448,13 @@ L: linux-serial@vger.kernel.org | |||
5451 | S: Maintained | 5448 | S: Maintained |
5452 | F: drivers/tty/serial | 5449 | F: drivers/tty/serial |
5453 | 5450 | ||
5451 | SYNOPSYS DESIGNWARE DMAC DRIVER | ||
5452 | M: Viresh Kumar <viresh.kumar@st.com> | ||
5453 | S: Maintained | ||
5454 | F: include/linux/dw_dmac.h | ||
5455 | F: drivers/dma/dw_dmac_regs.h | ||
5456 | F: drivers/dma/dw_dmac.c | ||
5457 | |||
5454 | TIMEKEEPING, NTP | 5458 | TIMEKEEPING, NTP |
5455 | M: John Stultz <johnstul@us.ibm.com> | 5459 | M: John Stultz <johnstul@us.ibm.com> |
5456 | M: Thomas Gleixner <tglx@linutronix.de> | 5460 | M: Thomas Gleixner <tglx@linutronix.de> |
@@ -1,8 +1,8 @@ | |||
1 | VERSION = 2 | 1 | VERSION = 3 |
2 | PATCHLEVEL = 6 | 2 | PATCHLEVEL = 0 |
3 | SUBLEVEL = 39 | 3 | SUBLEVEL = 0 |
4 | EXTRAVERSION = | 4 | EXTRAVERSION = -rc2 |
5 | NAME = Flesh-Eating Bats with Fangs | 5 | NAME = Sneaky Weasel |
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" |
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c index a5a83b358ddd..e01da45c0537 100644 --- a/arch/arm/mach-omap2/pm-debug.c +++ b/arch/arm/mach-omap2/pm-debug.c | |||
@@ -189,7 +189,7 @@ static struct dentry *pm_dbg_dir; | |||
189 | 189 | ||
190 | static int pm_dbg_init_done; | 190 | static int pm_dbg_init_done; |
191 | 191 | ||
192 | static int __init pm_dbg_init(void); | 192 | static int pm_dbg_init(void); |
193 | 193 | ||
194 | enum { | 194 | enum { |
195 | DEBUG_FILE_COUNTERS = 0, | 195 | DEBUG_FILE_COUNTERS = 0, |
@@ -595,7 +595,7 @@ static int option_set(void *data, u64 val) | |||
595 | 595 | ||
596 | DEFINE_SIMPLE_ATTRIBUTE(pm_dbg_option_fops, option_get, option_set, "%llu\n"); | 596 | DEFINE_SIMPLE_ATTRIBUTE(pm_dbg_option_fops, option_get, option_set, "%llu\n"); |
597 | 597 | ||
598 | static int __init pm_dbg_init(void) | 598 | static int pm_dbg_init(void) |
599 | { | 599 | { |
600 | int i; | 600 | int i; |
601 | struct dentry *d; | 601 | struct dentry *d; |
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index 08acb6ec8139..f6b687f61c28 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c | |||
@@ -249,6 +249,29 @@ static int slot_cn7_get_cd(struct platform_device *pdev) | |||
249 | { | 249 | { |
250 | return !gpio_get_value(GPIO_PORT41); | 250 | return !gpio_get_value(GPIO_PORT41); |
251 | } | 251 | } |
252 | /* MERAM */ | ||
253 | static struct sh_mobile_meram_info meram_info = { | ||
254 | .addr_mode = SH_MOBILE_MERAM_MODE1, | ||
255 | }; | ||
256 | |||
257 | static struct resource meram_resources[] = { | ||
258 | [0] = { | ||
259 | .name = "MERAM", | ||
260 | .start = 0xe8000000, | ||
261 | .end = 0xe81fffff, | ||
262 | .flags = IORESOURCE_MEM, | ||
263 | }, | ||
264 | }; | ||
265 | |||
266 | static struct platform_device meram_device = { | ||
267 | .name = "sh_mobile_meram", | ||
268 | .id = 0, | ||
269 | .num_resources = ARRAY_SIZE(meram_resources), | ||
270 | .resource = meram_resources, | ||
271 | .dev = { | ||
272 | .platform_data = &meram_info, | ||
273 | }, | ||
274 | }; | ||
252 | 275 | ||
253 | /* SH_MMCIF */ | 276 | /* SH_MMCIF */ |
254 | static struct resource sh_mmcif_resources[] = { | 277 | static struct resource sh_mmcif_resources[] = { |
@@ -447,13 +470,29 @@ const static struct fb_videomode ap4evb_lcdc_modes[] = { | |||
447 | #endif | 470 | #endif |
448 | }, | 471 | }, |
449 | }; | 472 | }; |
473 | static struct sh_mobile_meram_cfg lcd_meram_cfg = { | ||
474 | .icb[0] = { | ||
475 | .marker_icb = 28, | ||
476 | .cache_icb = 24, | ||
477 | .meram_offset = 0x0, | ||
478 | .meram_size = 0x40, | ||
479 | }, | ||
480 | .icb[1] = { | ||
481 | .marker_icb = 29, | ||
482 | .cache_icb = 25, | ||
483 | .meram_offset = 0x40, | ||
484 | .meram_size = 0x40, | ||
485 | }, | ||
486 | }; | ||
450 | 487 | ||
451 | static struct sh_mobile_lcdc_info lcdc_info = { | 488 | static struct sh_mobile_lcdc_info lcdc_info = { |
489 | .meram_dev = &meram_info, | ||
452 | .ch[0] = { | 490 | .ch[0] = { |
453 | .chan = LCDC_CHAN_MAINLCD, | 491 | .chan = LCDC_CHAN_MAINLCD, |
454 | .bpp = 16, | 492 | .bpp = 16, |
455 | .lcd_cfg = ap4evb_lcdc_modes, | 493 | .lcd_cfg = ap4evb_lcdc_modes, |
456 | .num_cfg = ARRAY_SIZE(ap4evb_lcdc_modes), | 494 | .num_cfg = ARRAY_SIZE(ap4evb_lcdc_modes), |
495 | .meram_cfg = &lcd_meram_cfg, | ||
457 | } | 496 | } |
458 | }; | 497 | }; |
459 | 498 | ||
@@ -724,15 +763,31 @@ static struct platform_device fsi_device = { | |||
724 | static struct platform_device fsi_ak4643_device = { | 763 | static struct platform_device fsi_ak4643_device = { |
725 | .name = "sh_fsi2_a_ak4643", | 764 | .name = "sh_fsi2_a_ak4643", |
726 | }; | 765 | }; |
766 | static struct sh_mobile_meram_cfg hdmi_meram_cfg = { | ||
767 | .icb[0] = { | ||
768 | .marker_icb = 30, | ||
769 | .cache_icb = 26, | ||
770 | .meram_offset = 0x80, | ||
771 | .meram_size = 0x100, | ||
772 | }, | ||
773 | .icb[1] = { | ||
774 | .marker_icb = 31, | ||
775 | .cache_icb = 27, | ||
776 | .meram_offset = 0x180, | ||
777 | .meram_size = 0x100, | ||
778 | }, | ||
779 | }; | ||
727 | 780 | ||
728 | static struct sh_mobile_lcdc_info sh_mobile_lcdc1_info = { | 781 | static struct sh_mobile_lcdc_info sh_mobile_lcdc1_info = { |
729 | .clock_source = LCDC_CLK_EXTERNAL, | 782 | .clock_source = LCDC_CLK_EXTERNAL, |
783 | .meram_dev = &meram_info, | ||
730 | .ch[0] = { | 784 | .ch[0] = { |
731 | .chan = LCDC_CHAN_MAINLCD, | 785 | .chan = LCDC_CHAN_MAINLCD, |
732 | .bpp = 16, | 786 | .bpp = 16, |
733 | .interface_type = RGB24, | 787 | .interface_type = RGB24, |
734 | .clock_divider = 1, | 788 | .clock_divider = 1, |
735 | .flags = LCDC_FLAGS_DWPOL, | 789 | .flags = LCDC_FLAGS_DWPOL, |
790 | .meram_cfg = &hdmi_meram_cfg, | ||
736 | } | 791 | } |
737 | }; | 792 | }; |
738 | 793 | ||
@@ -961,6 +1016,7 @@ static struct platform_device *ap4evb_devices[] __initdata = { | |||
961 | &csi2_device, | 1016 | &csi2_device, |
962 | &ceu_device, | 1017 | &ceu_device, |
963 | &ap4evb_camera, | 1018 | &ap4evb_camera, |
1019 | &meram_device, | ||
964 | }; | 1020 | }; |
965 | 1021 | ||
966 | static void __init hdmi_init_pm_clock(void) | 1022 | static void __init hdmi_init_pm_clock(void) |
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c index 448ddbe43335..776f20560e72 100644 --- a/arch/arm/mach-shmobile/board-mackerel.c +++ b/arch/arm/mach-shmobile/board-mackerel.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/mtd/mtd.h> | 39 | #include <linux/mtd/mtd.h> |
40 | #include <linux/mtd/partitions.h> | 40 | #include <linux/mtd/partitions.h> |
41 | #include <linux/mtd/physmap.h> | 41 | #include <linux/mtd/physmap.h> |
42 | #include <linux/pm_runtime.h> | ||
42 | #include <linux/smsc911x.h> | 43 | #include <linux/smsc911x.h> |
43 | #include <linux/sh_intc.h> | 44 | #include <linux/sh_intc.h> |
44 | #include <linux/tca6416_keypad.h> | 45 | #include <linux/tca6416_keypad.h> |
@@ -314,6 +315,30 @@ static struct platform_device smc911x_device = { | |||
314 | }, | 315 | }, |
315 | }; | 316 | }; |
316 | 317 | ||
318 | /* MERAM */ | ||
319 | static struct sh_mobile_meram_info mackerel_meram_info = { | ||
320 | .addr_mode = SH_MOBILE_MERAM_MODE1, | ||
321 | }; | ||
322 | |||
323 | static struct resource meram_resources[] = { | ||
324 | [0] = { | ||
325 | .name = "MERAM", | ||
326 | .start = 0xe8000000, | ||
327 | .end = 0xe81fffff, | ||
328 | .flags = IORESOURCE_MEM, | ||
329 | }, | ||
330 | }; | ||
331 | |||
332 | static struct platform_device meram_device = { | ||
333 | .name = "sh_mobile_meram", | ||
334 | .id = 0, | ||
335 | .num_resources = ARRAY_SIZE(meram_resources), | ||
336 | .resource = meram_resources, | ||
337 | .dev = { | ||
338 | .platform_data = &mackerel_meram_info, | ||
339 | }, | ||
340 | }; | ||
341 | |||
317 | /* LCDC */ | 342 | /* LCDC */ |
318 | static struct fb_videomode mackerel_lcdc_modes[] = { | 343 | static struct fb_videomode mackerel_lcdc_modes[] = { |
319 | { | 344 | { |
@@ -342,7 +367,23 @@ static int mackerel_get_brightness(void *board_data) | |||
342 | return gpio_get_value(GPIO_PORT31); | 367 | return gpio_get_value(GPIO_PORT31); |
343 | } | 368 | } |
344 | 369 | ||
370 | static struct sh_mobile_meram_cfg lcd_meram_cfg = { | ||
371 | .icb[0] = { | ||
372 | .marker_icb = 28, | ||
373 | .cache_icb = 24, | ||
374 | .meram_offset = 0x0, | ||
375 | .meram_size = 0x40, | ||
376 | }, | ||
377 | .icb[1] = { | ||
378 | .marker_icb = 29, | ||
379 | .cache_icb = 25, | ||
380 | .meram_offset = 0x40, | ||
381 | .meram_size = 0x40, | ||
382 | }, | ||
383 | }; | ||
384 | |||
345 | static struct sh_mobile_lcdc_info lcdc_info = { | 385 | static struct sh_mobile_lcdc_info lcdc_info = { |
386 | .meram_dev = &mackerel_meram_info, | ||
346 | .clock_source = LCDC_CLK_BUS, | 387 | .clock_source = LCDC_CLK_BUS, |
347 | .ch[0] = { | 388 | .ch[0] = { |
348 | .chan = LCDC_CHAN_MAINLCD, | 389 | .chan = LCDC_CHAN_MAINLCD, |
@@ -362,6 +403,7 @@ static struct sh_mobile_lcdc_info lcdc_info = { | |||
362 | .name = "sh_mobile_lcdc_bl", | 403 | .name = "sh_mobile_lcdc_bl", |
363 | .max_brightness = 1, | 404 | .max_brightness = 1, |
364 | }, | 405 | }, |
406 | .meram_cfg = &lcd_meram_cfg, | ||
365 | } | 407 | } |
366 | }; | 408 | }; |
367 | 409 | ||
@@ -388,8 +430,23 @@ static struct platform_device lcdc_device = { | |||
388 | }, | 430 | }, |
389 | }; | 431 | }; |
390 | 432 | ||
433 | static struct sh_mobile_meram_cfg hdmi_meram_cfg = { | ||
434 | .icb[0] = { | ||
435 | .marker_icb = 30, | ||
436 | .cache_icb = 26, | ||
437 | .meram_offset = 0x80, | ||
438 | .meram_size = 0x100, | ||
439 | }, | ||
440 | .icb[1] = { | ||
441 | .marker_icb = 31, | ||
442 | .cache_icb = 27, | ||
443 | .meram_offset = 0x180, | ||
444 | .meram_size = 0x100, | ||
445 | }, | ||
446 | }; | ||
391 | /* HDMI */ | 447 | /* HDMI */ |
392 | static struct sh_mobile_lcdc_info hdmi_lcdc_info = { | 448 | static struct sh_mobile_lcdc_info hdmi_lcdc_info = { |
449 | .meram_dev = &mackerel_meram_info, | ||
393 | .clock_source = LCDC_CLK_EXTERNAL, | 450 | .clock_source = LCDC_CLK_EXTERNAL, |
394 | .ch[0] = { | 451 | .ch[0] = { |
395 | .chan = LCDC_CHAN_MAINLCD, | 452 | .chan = LCDC_CHAN_MAINLCD, |
@@ -397,6 +454,7 @@ static struct sh_mobile_lcdc_info hdmi_lcdc_info = { | |||
397 | .interface_type = RGB24, | 454 | .interface_type = RGB24, |
398 | .clock_divider = 1, | 455 | .clock_divider = 1, |
399 | .flags = LCDC_FLAGS_DWPOL, | 456 | .flags = LCDC_FLAGS_DWPOL, |
457 | .meram_cfg = &hdmi_meram_cfg, | ||
400 | } | 458 | } |
401 | }; | 459 | }; |
402 | 460 | ||
@@ -856,6 +914,17 @@ static int slot_cn7_get_cd(struct platform_device *pdev) | |||
856 | } | 914 | } |
857 | 915 | ||
858 | /* SDHI0 */ | 916 | /* SDHI0 */ |
917 | static irqreturn_t mackerel_sdhi0_gpio_cd(int irq, void *arg) | ||
918 | { | ||
919 | struct device *dev = arg; | ||
920 | struct sh_mobile_sdhi_info *info = dev->platform_data; | ||
921 | struct tmio_mmc_data *pdata = info->pdata; | ||
922 | |||
923 | tmio_mmc_cd_wakeup(pdata); | ||
924 | |||
925 | return IRQ_HANDLED; | ||
926 | } | ||
927 | |||
859 | static struct sh_mobile_sdhi_info sdhi0_info = { | 928 | static struct sh_mobile_sdhi_info sdhi0_info = { |
860 | .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, | 929 | .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, |
861 | .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, | 930 | .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, |
@@ -1150,6 +1219,7 @@ static struct platform_device *mackerel_devices[] __initdata = { | |||
1150 | &mackerel_camera, | 1219 | &mackerel_camera, |
1151 | &hdmi_lcdc_device, | 1220 | &hdmi_lcdc_device, |
1152 | &hdmi_device, | 1221 | &hdmi_device, |
1222 | &meram_device, | ||
1153 | }; | 1223 | }; |
1154 | 1224 | ||
1155 | /* Keypad Initialization */ | 1225 | /* Keypad Initialization */ |
@@ -1238,6 +1308,7 @@ static void __init mackerel_init(void) | |||
1238 | { | 1308 | { |
1239 | u32 srcr4; | 1309 | u32 srcr4; |
1240 | struct clk *clk; | 1310 | struct clk *clk; |
1311 | int ret; | ||
1241 | 1312 | ||
1242 | sh7372_pinmux_init(); | 1313 | sh7372_pinmux_init(); |
1243 | 1314 | ||
@@ -1343,6 +1414,13 @@ static void __init mackerel_init(void) | |||
1343 | gpio_request(GPIO_FN_SDHID0_1, NULL); | 1414 | gpio_request(GPIO_FN_SDHID0_1, NULL); |
1344 | gpio_request(GPIO_FN_SDHID0_0, NULL); | 1415 | gpio_request(GPIO_FN_SDHID0_0, NULL); |
1345 | 1416 | ||
1417 | ret = request_irq(evt2irq(0x3340), mackerel_sdhi0_gpio_cd, | ||
1418 | IRQF_TRIGGER_FALLING, "sdhi0 cd", &sdhi0_device.dev); | ||
1419 | if (!ret) | ||
1420 | sdhi0_info.tmio_flags |= TMIO_MMC_HAS_COLD_CD; | ||
1421 | else | ||
1422 | pr_err("Cannot get IRQ #%d: %d\n", evt2irq(0x3340), ret); | ||
1423 | |||
1346 | #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) | 1424 | #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) |
1347 | /* enable SDHI1 */ | 1425 | /* enable SDHI1 */ |
1348 | gpio_request(GPIO_FN_SDHICMD1, NULL); | 1426 | gpio_request(GPIO_FN_SDHICMD1, NULL); |
diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c index d17eb66f4ac2..c0800d83971e 100644 --- a/arch/arm/mach-shmobile/clock-sh7372.c +++ b/arch/arm/mach-shmobile/clock-sh7372.c | |||
@@ -509,6 +509,7 @@ enum { MSTP001, | |||
509 | MSTP118, MSTP117, MSTP116, MSTP113, | 509 | MSTP118, MSTP117, MSTP116, MSTP113, |
510 | MSTP106, MSTP101, MSTP100, | 510 | MSTP106, MSTP101, MSTP100, |
511 | MSTP223, | 511 | MSTP223, |
512 | MSTP218, MSTP217, MSTP216, | ||
512 | MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, | 513 | MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, |
513 | MSTP329, MSTP328, MSTP323, MSTP322, MSTP314, MSTP313, MSTP312, | 514 | MSTP329, MSTP328, MSTP323, MSTP322, MSTP314, MSTP313, MSTP312, |
514 | MSTP423, MSTP415, MSTP413, MSTP411, MSTP410, MSTP406, MSTP403, | 515 | MSTP423, MSTP415, MSTP413, MSTP411, MSTP410, MSTP406, MSTP403, |
@@ -534,6 +535,9 @@ static struct clk mstp_clks[MSTP_NR] = { | |||
534 | [MSTP101] = MSTP(&div4_clks[DIV4_M1], SMSTPCR1, 1, 0), /* VPU */ | 535 | [MSTP101] = MSTP(&div4_clks[DIV4_M1], SMSTPCR1, 1, 0), /* VPU */ |
535 | [MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */ | 536 | [MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */ |
536 | [MSTP223] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR2, 23, 0), /* SPU2 */ | 537 | [MSTP223] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR2, 23, 0), /* SPU2 */ |
538 | [MSTP218] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* DMAC1 */ | ||
539 | [MSTP217] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 17, 0), /* DMAC2 */ | ||
540 | [MSTP216] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 16, 0), /* DMAC3 */ | ||
537 | [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */ | 541 | [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */ |
538 | [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */ | 542 | [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */ |
539 | [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */ | 543 | [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */ |
@@ -626,6 +630,9 @@ static struct clk_lookup lookups[] = { | |||
626 | CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */ | 630 | CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */ |
627 | CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[MSTP223]), /* SPU2DSP0 */ | 631 | CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[MSTP223]), /* SPU2DSP0 */ |
628 | CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[MSTP223]), /* SPU2DSP1 */ | 632 | CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[MSTP223]), /* SPU2DSP1 */ |
633 | CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* DMAC1 */ | ||
634 | CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]), /* DMAC2 */ | ||
635 | CLKDEV_DEV_ID("sh-dma-engine.2", &mstp_clks[MSTP216]), /* DMAC3 */ | ||
629 | CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */ | 636 | CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */ |
630 | CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP206]), /* SCIFB */ | 637 | CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP206]), /* SCIFB */ |
631 | CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */ | 638 | CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */ |
diff --git a/arch/arm/mach-tegra/board-harmony-power.c b/arch/arm/mach-tegra/board-harmony-power.c index c84442cabe07..5ad8b2f94f8d 100644 --- a/arch/arm/mach-tegra/board-harmony-power.c +++ b/arch/arm/mach-tegra/board-harmony-power.c | |||
@@ -24,6 +24,8 @@ | |||
24 | 24 | ||
25 | #include <mach/irqs.h> | 25 | #include <mach/irqs.h> |
26 | 26 | ||
27 | #include "board-harmony.h" | ||
28 | |||
27 | #define PMC_CTRL 0x0 | 29 | #define PMC_CTRL 0x0 |
28 | #define PMC_CTRL_INTR_LOW (1 << 17) | 30 | #define PMC_CTRL_INTR_LOW (1 << 17) |
29 | 31 | ||
@@ -98,7 +100,7 @@ static struct tps6586x_platform_data tps_platform = { | |||
98 | .irq_base = TEGRA_NR_IRQS, | 100 | .irq_base = TEGRA_NR_IRQS, |
99 | .num_subdevs = ARRAY_SIZE(tps_devs), | 101 | .num_subdevs = ARRAY_SIZE(tps_devs), |
100 | .subdevs = tps_devs, | 102 | .subdevs = tps_devs, |
101 | .gpio_base = TEGRA_NR_GPIOS, | 103 | .gpio_base = HARMONY_GPIO_TPS6586X(0), |
102 | }; | 104 | }; |
103 | 105 | ||
104 | static struct i2c_board_info __initdata harmony_regulators[] = { | 106 | static struct i2c_board_info __initdata harmony_regulators[] = { |
diff --git a/arch/arm/mach-tegra/board-harmony.h b/arch/arm/mach-tegra/board-harmony.h index 1e57b071f52d..d85142edaf6b 100644 --- a/arch/arm/mach-tegra/board-harmony.h +++ b/arch/arm/mach-tegra/board-harmony.h | |||
@@ -17,7 +17,8 @@ | |||
17 | #ifndef _MACH_TEGRA_BOARD_HARMONY_H | 17 | #ifndef _MACH_TEGRA_BOARD_HARMONY_H |
18 | #define _MACH_TEGRA_BOARD_HARMONY_H | 18 | #define _MACH_TEGRA_BOARD_HARMONY_H |
19 | 19 | ||
20 | #define HARMONY_GPIO_WM8903(_x_) (TEGRA_NR_GPIOS + (_x_)) | 20 | #define HARMONY_GPIO_TPS6586X(_x_) (TEGRA_NR_GPIOS + (_x_)) |
21 | #define HARMONY_GPIO_WM8903(_x_) (HARMONY_GPIO_TPS6586X(4) + (_x_)) | ||
21 | 22 | ||
22 | #define TEGRA_GPIO_SD2_CD TEGRA_GPIO_PI5 | 23 | #define TEGRA_GPIO_SD2_CD TEGRA_GPIO_PI5 |
23 | #define TEGRA_GPIO_SD2_WP TEGRA_GPIO_PH1 | 24 | #define TEGRA_GPIO_SD2_WP TEGRA_GPIO_PH1 |
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c index a37b8eb65b76..49fc0df0c21f 100644 --- a/arch/arm/plat-omap/omap_device.c +++ b/arch/arm/plat-omap/omap_device.c | |||
@@ -84,6 +84,7 @@ | |||
84 | #include <linux/io.h> | 84 | #include <linux/io.h> |
85 | #include <linux/clk.h> | 85 | #include <linux/clk.h> |
86 | #include <linux/clkdev.h> | 86 | #include <linux/clkdev.h> |
87 | #include <linux/pm_runtime.h> | ||
87 | 88 | ||
88 | #include <plat/omap_device.h> | 89 | #include <plat/omap_device.h> |
89 | #include <plat/omap_hwmod.h> | 90 | #include <plat/omap_hwmod.h> |
@@ -539,20 +540,34 @@ int omap_early_device_register(struct omap_device *od) | |||
539 | static int _od_runtime_suspend(struct device *dev) | 540 | static int _od_runtime_suspend(struct device *dev) |
540 | { | 541 | { |
541 | struct platform_device *pdev = to_platform_device(dev); | 542 | struct platform_device *pdev = to_platform_device(dev); |
543 | int ret; | ||
544 | |||
545 | ret = pm_generic_runtime_suspend(dev); | ||
546 | |||
547 | if (!ret) | ||
548 | omap_device_idle(pdev); | ||
549 | |||
550 | return ret; | ||
551 | } | ||
542 | 552 | ||
543 | return omap_device_idle(pdev); | 553 | static int _od_runtime_idle(struct device *dev) |
554 | { | ||
555 | return pm_generic_runtime_idle(dev); | ||
544 | } | 556 | } |
545 | 557 | ||
546 | static int _od_runtime_resume(struct device *dev) | 558 | static int _od_runtime_resume(struct device *dev) |
547 | { | 559 | { |
548 | struct platform_device *pdev = to_platform_device(dev); | 560 | struct platform_device *pdev = to_platform_device(dev); |
549 | 561 | ||
550 | return omap_device_enable(pdev); | 562 | omap_device_enable(pdev); |
563 | |||
564 | return pm_generic_runtime_resume(dev); | ||
551 | } | 565 | } |
552 | 566 | ||
553 | static struct dev_power_domain omap_device_power_domain = { | 567 | static struct dev_power_domain omap_device_power_domain = { |
554 | .ops = { | 568 | .ops = { |
555 | .runtime_suspend = _od_runtime_suspend, | 569 | .runtime_suspend = _od_runtime_suspend, |
570 | .runtime_idle = _od_runtime_idle, | ||
556 | .runtime_resume = _od_runtime_resume, | 571 | .runtime_resume = _od_runtime_resume, |
557 | USE_PLATFORM_PM_SLEEP_OPS | 572 | USE_PLATFORM_PM_SLEEP_OPS |
558 | } | 573 | } |
diff --git a/arch/blackfin/include/asm/bfin_serial.h b/arch/blackfin/include/asm/bfin_serial.h index 7dbc664eab1e..7fd0ec7b5b0f 100644 --- a/arch/blackfin/include/asm/bfin_serial.h +++ b/arch/blackfin/include/asm/bfin_serial.h | |||
@@ -184,7 +184,7 @@ struct bfin_uart_regs { | |||
184 | #undef __BFP | 184 | #undef __BFP |
185 | 185 | ||
186 | #ifndef port_membase | 186 | #ifndef port_membase |
187 | # define port_membase(p) (((struct bfin_serial_port *)(p))->port.membase) | 187 | # define port_membase(p) 0 |
188 | #endif | 188 | #endif |
189 | 189 | ||
190 | #define UART_GET_CHAR(p) bfin_read16(port_membase(p) + OFFSET_RBR) | 190 | #define UART_GET_CHAR(p) bfin_read16(port_membase(p) + OFFSET_RBR) |
@@ -235,10 +235,10 @@ struct bfin_uart_regs { | |||
235 | #define UART_SET_DLAB(p) do { UART_PUT_LCR(p, UART_GET_LCR(p) | DLAB); SSYNC(); } while (0) | 235 | #define UART_SET_DLAB(p) do { UART_PUT_LCR(p, UART_GET_LCR(p) | DLAB); SSYNC(); } while (0) |
236 | 236 | ||
237 | #ifndef put_lsr_cache | 237 | #ifndef put_lsr_cache |
238 | # define put_lsr_cache(p, v) (((struct bfin_serial_port *)(p))->lsr = (v)) | 238 | # define put_lsr_cache(p, v) |
239 | #endif | 239 | #endif |
240 | #ifndef get_lsr_cache | 240 | #ifndef get_lsr_cache |
241 | # define get_lsr_cache(p) (((struct bfin_serial_port *)(p))->lsr) | 241 | # define get_lsr_cache(p) 0 |
242 | #endif | 242 | #endif |
243 | 243 | ||
244 | /* The hardware clears the LSR bits upon read, so we need to cache | 244 | /* The hardware clears the LSR bits upon read, so we need to cache |
diff --git a/arch/blackfin/include/asm/gptimers.h b/arch/blackfin/include/asm/gptimers.h index c722acdda0d3..38657dac1235 100644 --- a/arch/blackfin/include/asm/gptimers.h +++ b/arch/blackfin/include/asm/gptimers.h | |||
@@ -193,4 +193,22 @@ uint16_t get_enabled_gptimers(void); | |||
193 | uint32_t get_gptimer_status(unsigned int group); | 193 | uint32_t get_gptimer_status(unsigned int group); |
194 | void set_gptimer_status(unsigned int group, uint32_t value); | 194 | void set_gptimer_status(unsigned int group, uint32_t value); |
195 | 195 | ||
196 | /* | ||
197 | * All Blackfin system MMRs are padded to 32bits even if the register | ||
198 | * itself is only 16bits. So use a helper macro to streamline this. | ||
199 | */ | ||
200 | #define __BFP(m) u16 m; u16 __pad_##m | ||
201 | |||
202 | /* | ||
203 | * bfin timer registers layout | ||
204 | */ | ||
205 | struct bfin_gptimer_regs { | ||
206 | __BFP(config); | ||
207 | u32 counter; | ||
208 | u32 period; | ||
209 | u32 width; | ||
210 | }; | ||
211 | |||
212 | #undef __BFP | ||
213 | |||
196 | #endif | 214 | #endif |
diff --git a/arch/blackfin/include/asm/unistd.h b/arch/blackfin/include/asm/unistd.h index 6ff9c411b145..0ccba60b9ccf 100644 --- a/arch/blackfin/include/asm/unistd.h +++ b/arch/blackfin/include/asm/unistd.h | |||
@@ -398,8 +398,9 @@ | |||
398 | #define __NR_clock_adjtime 377 | 398 | #define __NR_clock_adjtime 377 |
399 | #define __NR_syncfs 378 | 399 | #define __NR_syncfs 378 |
400 | #define __NR_setns 379 | 400 | #define __NR_setns 379 |
401 | #define __NR_sendmmsg 380 | ||
401 | 402 | ||
402 | #define __NR_syscall 380 | 403 | #define __NR_syscall 381 |
403 | #define NR_syscalls __NR_syscall | 404 | #define NR_syscalls __NR_syscall |
404 | 405 | ||
405 | /* Old optional stuff no one actually uses */ | 406 | /* Old optional stuff no one actually uses */ |
diff --git a/arch/blackfin/kernel/debug-mmrs.c b/arch/blackfin/kernel/debug-mmrs.c index 94b1d8a0256a..fce4807ceef9 100644 --- a/arch/blackfin/kernel/debug-mmrs.c +++ b/arch/blackfin/kernel/debug-mmrs.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include <asm/blackfin.h> | 14 | #include <asm/blackfin.h> |
15 | #include <asm/gpio.h> | 15 | #include <asm/gpio.h> |
16 | #include <asm/gptimers.h> | ||
16 | #include <asm/bfin_can.h> | 17 | #include <asm/bfin_can.h> |
17 | #include <asm/bfin_dma.h> | 18 | #include <asm/bfin_dma.h> |
18 | #include <asm/bfin_ppi.h> | 19 | #include <asm/bfin_ppi.h> |
@@ -230,8 +231,8 @@ bfin_debug_mmrs_dma(struct dentry *parent, unsigned long base, int num, char mdm | |||
230 | #define DMA(num) _DMA(num, DMA##num##_NEXT_DESC_PTR, 0, "") | 231 | #define DMA(num) _DMA(num, DMA##num##_NEXT_DESC_PTR, 0, "") |
231 | #define _MDMA(num, x) \ | 232 | #define _MDMA(num, x) \ |
232 | do { \ | 233 | do { \ |
233 | _DMA(num, x##DMA_D##num##_CONFIG, 'D', #x); \ | 234 | _DMA(num, x##DMA_D##num##_NEXT_DESC_PTR, 'D', #x); \ |
234 | _DMA(num, x##DMA_S##num##_CONFIG, 'S', #x); \ | 235 | _DMA(num, x##DMA_S##num##_NEXT_DESC_PTR, 'S', #x); \ |
235 | } while (0) | 236 | } while (0) |
236 | #define MDMA(num) _MDMA(num, M) | 237 | #define MDMA(num) _MDMA(num, M) |
237 | #define IMDMA(num) _MDMA(num, IM) | 238 | #define IMDMA(num) _MDMA(num, IM) |
@@ -264,20 +265,15 @@ bfin_debug_mmrs_eppi(struct dentry *parent, unsigned long base, int num) | |||
264 | /* | 265 | /* |
265 | * General Purpose Timers | 266 | * General Purpose Timers |
266 | */ | 267 | */ |
267 | #define GPTIMER_OFF(mmr) (TIMER0_##mmr - TIMER0_CONFIG) | 268 | #define __GPTIMER(uname, lname) __REGS(gptimer, #uname, lname) |
268 | #define __GPTIMER(name) \ | ||
269 | do { \ | ||
270 | strcpy(_buf, #name); \ | ||
271 | debugfs_create_x16(buf, S_IRUSR|S_IWUSR, parent, (u16 *)(base + GPTIMER_OFF(name))); \ | ||
272 | } while (0) | ||
273 | static void __init __maybe_unused | 269 | static void __init __maybe_unused |
274 | bfin_debug_mmrs_gptimer(struct dentry *parent, unsigned long base, int num) | 270 | bfin_debug_mmrs_gptimer(struct dentry *parent, unsigned long base, int num) |
275 | { | 271 | { |
276 | char buf[32], *_buf = REGS_STR_PFX(buf, TIMER, num); | 272 | char buf[32], *_buf = REGS_STR_PFX(buf, TIMER, num); |
277 | __GPTIMER(CONFIG); | 273 | __GPTIMER(CONFIG, config); |
278 | __GPTIMER(COUNTER); | 274 | __GPTIMER(COUNTER, counter); |
279 | __GPTIMER(PERIOD); | 275 | __GPTIMER(PERIOD, period); |
280 | __GPTIMER(WIDTH); | 276 | __GPTIMER(WIDTH, width); |
281 | } | 277 | } |
282 | #define GPTIMER(num) bfin_debug_mmrs_gptimer(parent, TIMER##num##_CONFIG, num) | 278 | #define GPTIMER(num) bfin_debug_mmrs_gptimer(parent, TIMER##num##_CONFIG, num) |
283 | 279 | ||
@@ -355,7 +351,7 @@ bfin_debug_mmrs_ppi(struct dentry *parent, unsigned long base, int num) | |||
355 | __PPI(DELAY, delay); | 351 | __PPI(DELAY, delay); |
356 | __PPI(FRAME, frame); | 352 | __PPI(FRAME, frame); |
357 | } | 353 | } |
358 | #define PPI(num) bfin_debug_mmrs_ppi(parent, PPI##num##_STATUS, num) | 354 | #define PPI(num) bfin_debug_mmrs_ppi(parent, PPI##num##_CONTROL, num) |
359 | 355 | ||
360 | /* | 356 | /* |
361 | * SPI | 357 | * SPI |
@@ -1288,15 +1284,15 @@ static int __init bfin_debug_mmrs_init(void) | |||
1288 | D16(VR_CTL); | 1284 | D16(VR_CTL); |
1289 | D32(CHIPID); /* it's part of this hardware block */ | 1285 | D32(CHIPID); /* it's part of this hardware block */ |
1290 | 1286 | ||
1291 | #if defined(PPI_STATUS) || defined(PPI0_STATUS) || defined(PPI1_STATUS) | 1287 | #if defined(PPI_CONTROL) || defined(PPI0_CONTROL) || defined(PPI1_CONTROL) |
1292 | parent = debugfs_create_dir("ppi", top); | 1288 | parent = debugfs_create_dir("ppi", top); |
1293 | # ifdef PPI_STATUS | 1289 | # ifdef PPI_CONTROL |
1294 | bfin_debug_mmrs_ppi(parent, PPI_STATUS, -1); | 1290 | bfin_debug_mmrs_ppi(parent, PPI_CONTROL, -1); |
1295 | # endif | 1291 | # endif |
1296 | # ifdef PPI0_STATUS | 1292 | # ifdef PPI0_CONTROL |
1297 | PPI(0); | 1293 | PPI(0); |
1298 | # endif | 1294 | # endif |
1299 | # ifdef PPI1_STATUS | 1295 | # ifdef PPI1_CONTROL |
1300 | PPI(1); | 1296 | PPI(1); |
1301 | # endif | 1297 | # endif |
1302 | #endif | 1298 | #endif |
@@ -1341,6 +1337,10 @@ static int __init bfin_debug_mmrs_init(void) | |||
1341 | D16(RSI_PID1); | 1337 | D16(RSI_PID1); |
1342 | D16(RSI_PID2); | 1338 | D16(RSI_PID2); |
1343 | D16(RSI_PID3); | 1339 | D16(RSI_PID3); |
1340 | D16(RSI_PID4); | ||
1341 | D16(RSI_PID5); | ||
1342 | D16(RSI_PID6); | ||
1343 | D16(RSI_PID7); | ||
1344 | D16(RSI_PWR_CONTROL); | 1344 | D16(RSI_PWR_CONTROL); |
1345 | D16(RSI_RD_WAIT_EN); | 1345 | D16(RSI_RD_WAIT_EN); |
1346 | D32(RSI_RESPONSE0); | 1346 | D32(RSI_RESPONSE0); |
diff --git a/arch/blackfin/lib/strncpy.S b/arch/blackfin/lib/strncpy.S index f3931d50b4a7..2c07dddac995 100644 --- a/arch/blackfin/lib/strncpy.S +++ b/arch/blackfin/lib/strncpy.S | |||
@@ -25,7 +25,7 @@ | |||
25 | 25 | ||
26 | ENTRY(_strncpy) | 26 | ENTRY(_strncpy) |
27 | CC = R2 == 0; | 27 | CC = R2 == 0; |
28 | if CC JUMP 4f; | 28 | if CC JUMP 6f; |
29 | 29 | ||
30 | P2 = R2 ; /* size */ | 30 | P2 = R2 ; /* size */ |
31 | P0 = R0 ; /* dst*/ | 31 | P0 = R0 ; /* dst*/ |
diff --git a/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h deleted file mode 100644 index f6d924ac0c44..000000000000 --- a/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h +++ /dev/null | |||
@@ -1,79 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2008-2009 Analog Devices Inc. | ||
3 | * | ||
4 | * Licensed under the GPL-2 or later | ||
5 | */ | ||
6 | |||
7 | #include <asm/dma.h> | ||
8 | #include <asm/portmux.h> | ||
9 | |||
10 | #if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS) | ||
11 | # define CONFIG_SERIAL_BFIN_CTSRTS | ||
12 | |||
13 | # ifndef CONFIG_UART0_CTS_PIN | ||
14 | # define CONFIG_UART0_CTS_PIN -1 | ||
15 | # endif | ||
16 | |||
17 | # ifndef CONFIG_UART0_RTS_PIN | ||
18 | # define CONFIG_UART0_RTS_PIN -1 | ||
19 | # endif | ||
20 | |||
21 | # ifndef CONFIG_UART1_CTS_PIN | ||
22 | # define CONFIG_UART1_CTS_PIN -1 | ||
23 | # endif | ||
24 | |||
25 | # ifndef CONFIG_UART1_RTS_PIN | ||
26 | # define CONFIG_UART1_RTS_PIN -1 | ||
27 | # endif | ||
28 | #endif | ||
29 | |||
30 | struct bfin_serial_res { | ||
31 | unsigned long uart_base_addr; | ||
32 | int uart_irq; | ||
33 | int uart_status_irq; | ||
34 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
35 | unsigned int uart_tx_dma_channel; | ||
36 | unsigned int uart_rx_dma_channel; | ||
37 | #endif | ||
38 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
39 | int uart_cts_pin; | ||
40 | int uart_rts_pin; | ||
41 | #endif | ||
42 | }; | ||
43 | |||
44 | struct bfin_serial_res bfin_serial_resource[] = { | ||
45 | #ifdef CONFIG_SERIAL_BFIN_UART0 | ||
46 | { | ||
47 | 0xFFC00400, | ||
48 | IRQ_UART0_RX, | ||
49 | IRQ_UART0_ERROR, | ||
50 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
51 | CH_UART0_TX, | ||
52 | CH_UART0_RX, | ||
53 | #endif | ||
54 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
55 | CONFIG_UART0_CTS_PIN, | ||
56 | CONFIG_UART0_RTS_PIN, | ||
57 | #endif | ||
58 | }, | ||
59 | #endif | ||
60 | #ifdef CONFIG_SERIAL_BFIN_UART1 | ||
61 | { | ||
62 | 0xFFC02000, | ||
63 | IRQ_UART1_RX, | ||
64 | IRQ_UART1_ERROR, | ||
65 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
66 | CH_UART1_TX, | ||
67 | CH_UART1_RX, | ||
68 | #endif | ||
69 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
70 | CONFIG_UART1_CTS_PIN, | ||
71 | CONFIG_UART1_RTS_PIN, | ||
72 | #endif | ||
73 | }, | ||
74 | #endif | ||
75 | }; | ||
76 | |||
77 | #define DRIVER_NAME "bfin-uart" | ||
78 | |||
79 | #include <asm/bfin_serial.h> | ||
diff --git a/arch/blackfin/mach-bf518/include/mach/defBF514.h b/arch/blackfin/mach-bf518/include/mach/defBF514.h index 98a51c479290..cfab428e577c 100644 --- a/arch/blackfin/mach-bf518/include/mach/defBF514.h +++ b/arch/blackfin/mach-bf518/include/mach/defBF514.h | |||
@@ -36,13 +36,13 @@ | |||
36 | #define RSI_EMASK 0xFFC038C4 /* RSI Exception Mask Register */ | 36 | #define RSI_EMASK 0xFFC038C4 /* RSI Exception Mask Register */ |
37 | #define RSI_CONFIG 0xFFC038C8 /* RSI Configuration Register */ | 37 | #define RSI_CONFIG 0xFFC038C8 /* RSI Configuration Register */ |
38 | #define RSI_RD_WAIT_EN 0xFFC038CC /* RSI Read Wait Enable Register */ | 38 | #define RSI_RD_WAIT_EN 0xFFC038CC /* RSI Read Wait Enable Register */ |
39 | #define RSI_PID0 0xFFC03FE0 /* RSI Peripheral ID Register 0 */ | 39 | #define RSI_PID0 0xFFC038D0 /* RSI Peripheral ID Register 0 */ |
40 | #define RSI_PID1 0xFFC03FE4 /* RSI Peripheral ID Register 1 */ | 40 | #define RSI_PID1 0xFFC038D4 /* RSI Peripheral ID Register 1 */ |
41 | #define RSI_PID2 0xFFC03FE8 /* RSI Peripheral ID Register 2 */ | 41 | #define RSI_PID2 0xFFC038D8 /* RSI Peripheral ID Register 2 */ |
42 | #define RSI_PID3 0xFFC03FEC /* RSI Peripheral ID Register 3 */ | 42 | #define RSI_PID3 0xFFC038DC /* RSI Peripheral ID Register 3 */ |
43 | #define RSI_PID4 0xFFC03FF0 /* RSI Peripheral ID Register 4 */ | 43 | #define RSI_PID4 0xFFC038E0 /* RSI Peripheral ID Register 0 */ |
44 | #define RSI_PID5 0xFFC03FF4 /* RSI Peripheral ID Register 5 */ | 44 | #define RSI_PID5 0xFFC038E4 /* RSI Peripheral ID Register 1 */ |
45 | #define RSI_PID6 0xFFC03FF8 /* RSI Peripheral ID Register 6 */ | 45 | #define RSI_PID6 0xFFC038E8 /* RSI Peripheral ID Register 2 */ |
46 | #define RSI_PID7 0xFFC03FFC /* RSI Peripheral ID Register 7 */ | 46 | #define RSI_PID7 0xFFC038EC /* RSI Peripheral ID Register 3 */ |
47 | 47 | ||
48 | #endif /* _DEF_BF514_H */ | 48 | #endif /* _DEF_BF514_H */ |
diff --git a/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h deleted file mode 100644 index 960e08919def..000000000000 --- a/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h +++ /dev/null | |||
@@ -1,79 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2007-2009 Analog Devices Inc. | ||
3 | * | ||
4 | * Licensed under the GPL-2 or later | ||
5 | */ | ||
6 | |||
7 | #include <asm/dma.h> | ||
8 | #include <asm/portmux.h> | ||
9 | |||
10 | #if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS) | ||
11 | # define CONFIG_SERIAL_BFIN_CTSRTS | ||
12 | |||
13 | # ifndef CONFIG_UART0_CTS_PIN | ||
14 | # define CONFIG_UART0_CTS_PIN -1 | ||
15 | # endif | ||
16 | |||
17 | # ifndef CONFIG_UART0_RTS_PIN | ||
18 | # define CONFIG_UART0_RTS_PIN -1 | ||
19 | # endif | ||
20 | |||
21 | # ifndef CONFIG_UART1_CTS_PIN | ||
22 | # define CONFIG_UART1_CTS_PIN -1 | ||
23 | # endif | ||
24 | |||
25 | # ifndef CONFIG_UART1_RTS_PIN | ||
26 | # define CONFIG_UART1_RTS_PIN -1 | ||
27 | # endif | ||
28 | #endif | ||
29 | |||
30 | struct bfin_serial_res { | ||
31 | unsigned long uart_base_addr; | ||
32 | int uart_irq; | ||
33 | int uart_status_irq; | ||
34 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
35 | unsigned int uart_tx_dma_channel; | ||
36 | unsigned int uart_rx_dma_channel; | ||
37 | #endif | ||
38 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
39 | int uart_cts_pin; | ||
40 | int uart_rts_pin; | ||
41 | #endif | ||
42 | }; | ||
43 | |||
44 | struct bfin_serial_res bfin_serial_resource[] = { | ||
45 | #ifdef CONFIG_SERIAL_BFIN_UART0 | ||
46 | { | ||
47 | 0xFFC00400, | ||
48 | IRQ_UART0_RX, | ||
49 | IRQ_UART0_ERROR, | ||
50 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
51 | CH_UART0_TX, | ||
52 | CH_UART0_RX, | ||
53 | #endif | ||
54 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
55 | CONFIG_UART0_CTS_PIN, | ||
56 | CONFIG_UART0_RTS_PIN, | ||
57 | #endif | ||
58 | }, | ||
59 | #endif | ||
60 | #ifdef CONFIG_SERIAL_BFIN_UART1 | ||
61 | { | ||
62 | 0xFFC02000, | ||
63 | IRQ_UART1_RX, | ||
64 | IRQ_UART1_ERROR, | ||
65 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
66 | CH_UART1_TX, | ||
67 | CH_UART1_RX, | ||
68 | #endif | ||
69 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
70 | CONFIG_UART1_CTS_PIN, | ||
71 | CONFIG_UART1_RTS_PIN, | ||
72 | #endif | ||
73 | }, | ||
74 | #endif | ||
75 | }; | ||
76 | |||
77 | #define DRIVER_NAME "bfin-uart" | ||
78 | |||
79 | #include <asm/bfin_serial.h> | ||
diff --git a/arch/blackfin/mach-bf527/include/mach/defBF525.h b/arch/blackfin/mach-bf527/include/mach/defBF525.h index cc383adfdffa..aab80bb1a683 100644 --- a/arch/blackfin/mach-bf527/include/mach/defBF525.h +++ b/arch/blackfin/mach-bf527/include/mach/defBF525.h | |||
@@ -185,8 +185,8 @@ | |||
185 | #define USB_EP_NI7_TXTYPE 0xffc03bd4 /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint7 */ | 185 | #define USB_EP_NI7_TXTYPE 0xffc03bd4 /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint7 */ |
186 | #define USB_EP_NI7_TXINTERVAL 0xffc03bd8 /* Sets the NAK response timeout on Endpoint7 */ | 186 | #define USB_EP_NI7_TXINTERVAL 0xffc03bd8 /* Sets the NAK response timeout on Endpoint7 */ |
187 | #define USB_EP_NI7_RXTYPE 0xffc03bdc /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint7 */ | 187 | #define USB_EP_NI7_RXTYPE 0xffc03bdc /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint7 */ |
188 | #define USB_EP_NI7_RXINTERVAL 0xffc03bf0 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint7 */ | 188 | #define USB_EP_NI7_RXINTERVAL 0xffc03be0 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint7 */ |
189 | #define USB_EP_NI7_TXCOUNT 0xffc03bf8 /* Number of bytes to be written to the endpoint7 Tx FIFO */ | 189 | #define USB_EP_NI7_TXCOUNT 0xffc03be8 /* Number of bytes to be written to the endpoint7 Tx FIFO */ |
190 | 190 | ||
191 | #define USB_DMA_INTERRUPT 0xffc03c00 /* Indicates pending interrupts for the DMA channels */ | 191 | #define USB_DMA_INTERRUPT 0xffc03c00 /* Indicates pending interrupts for the DMA channels */ |
192 | 192 | ||
diff --git a/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h deleted file mode 100644 index 45dcaa4f3e41..000000000000 --- a/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h +++ /dev/null | |||
@@ -1,52 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2006-2009 Analog Devices Inc. | ||
3 | * | ||
4 | * Licensed under the GPL-2 or later | ||
5 | */ | ||
6 | |||
7 | #include <asm/dma.h> | ||
8 | #include <asm/portmux.h> | ||
9 | |||
10 | #ifdef CONFIG_BFIN_UART0_CTSRTS | ||
11 | # define CONFIG_SERIAL_BFIN_CTSRTS | ||
12 | # ifndef CONFIG_UART0_CTS_PIN | ||
13 | # define CONFIG_UART0_CTS_PIN -1 | ||
14 | # endif | ||
15 | # ifndef CONFIG_UART0_RTS_PIN | ||
16 | # define CONFIG_UART0_RTS_PIN -1 | ||
17 | # endif | ||
18 | #endif | ||
19 | |||
20 | struct bfin_serial_res { | ||
21 | unsigned long uart_base_addr; | ||
22 | int uart_irq; | ||
23 | int uart_status_irq; | ||
24 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
25 | unsigned int uart_tx_dma_channel; | ||
26 | unsigned int uart_rx_dma_channel; | ||
27 | #endif | ||
28 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
29 | int uart_cts_pin; | ||
30 | int uart_rts_pin; | ||
31 | #endif | ||
32 | }; | ||
33 | |||
34 | struct bfin_serial_res bfin_serial_resource[] = { | ||
35 | { | ||
36 | 0xFFC00400, | ||
37 | IRQ_UART0_RX, | ||
38 | IRQ_UART0_ERROR, | ||
39 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
40 | CH_UART0_TX, | ||
41 | CH_UART0_RX, | ||
42 | #endif | ||
43 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
44 | CONFIG_UART0_CTS_PIN, | ||
45 | CONFIG_UART0_RTS_PIN, | ||
46 | #endif | ||
47 | } | ||
48 | }; | ||
49 | |||
50 | #define DRIVER_NAME "bfin-uart" | ||
51 | |||
52 | #include <asm/bfin_serial.h> | ||
diff --git a/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h deleted file mode 100644 index 3e955dba8951..000000000000 --- a/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h +++ /dev/null | |||
@@ -1,79 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2006-2009 Analog Devices Inc. | ||
3 | * | ||
4 | * Licensed under the GPL-2 or later | ||
5 | */ | ||
6 | |||
7 | #include <asm/dma.h> | ||
8 | #include <asm/portmux.h> | ||
9 | |||
10 | #if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS) | ||
11 | # define CONFIG_SERIAL_BFIN_CTSRTS | ||
12 | |||
13 | # ifndef CONFIG_UART0_CTS_PIN | ||
14 | # define CONFIG_UART0_CTS_PIN -1 | ||
15 | # endif | ||
16 | |||
17 | # ifndef CONFIG_UART0_RTS_PIN | ||
18 | # define CONFIG_UART0_RTS_PIN -1 | ||
19 | # endif | ||
20 | |||
21 | # ifndef CONFIG_UART1_CTS_PIN | ||
22 | # define CONFIG_UART1_CTS_PIN -1 | ||
23 | # endif | ||
24 | |||
25 | # ifndef CONFIG_UART1_RTS_PIN | ||
26 | # define CONFIG_UART1_RTS_PIN -1 | ||
27 | # endif | ||
28 | #endif | ||
29 | |||
30 | struct bfin_serial_res { | ||
31 | unsigned long uart_base_addr; | ||
32 | int uart_irq; | ||
33 | int uart_status_irq; | ||
34 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
35 | unsigned int uart_tx_dma_channel; | ||
36 | unsigned int uart_rx_dma_channel; | ||
37 | #endif | ||
38 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
39 | int uart_cts_pin; | ||
40 | int uart_rts_pin; | ||
41 | #endif | ||
42 | }; | ||
43 | |||
44 | struct bfin_serial_res bfin_serial_resource[] = { | ||
45 | #ifdef CONFIG_SERIAL_BFIN_UART0 | ||
46 | { | ||
47 | 0xFFC00400, | ||
48 | IRQ_UART0_RX, | ||
49 | IRQ_UART0_ERROR, | ||
50 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
51 | CH_UART0_TX, | ||
52 | CH_UART0_RX, | ||
53 | #endif | ||
54 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
55 | CONFIG_UART0_CTS_PIN, | ||
56 | CONFIG_UART0_RTS_PIN, | ||
57 | #endif | ||
58 | }, | ||
59 | #endif | ||
60 | #ifdef CONFIG_SERIAL_BFIN_UART1 | ||
61 | { | ||
62 | 0xFFC02000, | ||
63 | IRQ_UART1_RX, | ||
64 | IRQ_UART1_ERROR, | ||
65 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
66 | CH_UART1_TX, | ||
67 | CH_UART1_RX, | ||
68 | #endif | ||
69 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
70 | CONFIG_UART1_CTS_PIN, | ||
71 | CONFIG_UART1_RTS_PIN, | ||
72 | #endif | ||
73 | }, | ||
74 | #endif | ||
75 | }; | ||
76 | |||
77 | #define DRIVER_NAME "bfin-uart" | ||
78 | |||
79 | #include <asm/bfin_serial.h> | ||
diff --git a/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h deleted file mode 100644 index beb502e9cb33..000000000000 --- a/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h +++ /dev/null | |||
@@ -1,93 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2008-2009 Analog Devices Inc. | ||
3 | * | ||
4 | * Licensed under the GPL-2 or later. | ||
5 | */ | ||
6 | |||
7 | #include <asm/dma.h> | ||
8 | #include <asm/portmux.h> | ||
9 | |||
10 | #if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS) | ||
11 | # define CONFIG_SERIAL_BFIN_CTSRTS | ||
12 | |||
13 | # ifndef CONFIG_UART0_CTS_PIN | ||
14 | # define CONFIG_UART0_CTS_PIN -1 | ||
15 | # endif | ||
16 | |||
17 | # ifndef CONFIG_UART0_RTS_PIN | ||
18 | # define CONFIG_UART0_RTS_PIN -1 | ||
19 | # endif | ||
20 | |||
21 | # ifndef CONFIG_UART1_CTS_PIN | ||
22 | # define CONFIG_UART1_CTS_PIN -1 | ||
23 | # endif | ||
24 | |||
25 | # ifndef CONFIG_UART1_RTS_PIN | ||
26 | # define CONFIG_UART1_RTS_PIN -1 | ||
27 | # endif | ||
28 | #endif | ||
29 | |||
30 | struct bfin_serial_res { | ||
31 | unsigned long uart_base_addr; | ||
32 | int uart_irq; | ||
33 | int uart_status_irq; | ||
34 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
35 | unsigned int uart_tx_dma_channel; | ||
36 | unsigned int uart_rx_dma_channel; | ||
37 | #endif | ||
38 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
39 | int uart_cts_pin; | ||
40 | int uart_rts_pin; | ||
41 | #endif | ||
42 | }; | ||
43 | |||
44 | struct bfin_serial_res bfin_serial_resource[] = { | ||
45 | #ifdef CONFIG_SERIAL_BFIN_UART0 | ||
46 | { | ||
47 | 0xFFC00400, | ||
48 | IRQ_UART0_RX, | ||
49 | IRQ_UART0_ERROR, | ||
50 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
51 | CH_UART0_TX, | ||
52 | CH_UART0_RX, | ||
53 | #endif | ||
54 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
55 | CONFIG_UART0_CTS_PIN, | ||
56 | CONFIG_UART0_RTS_PIN, | ||
57 | #endif | ||
58 | }, | ||
59 | #endif | ||
60 | #ifdef CONFIG_SERIAL_BFIN_UART1 | ||
61 | { | ||
62 | 0xFFC02000, | ||
63 | IRQ_UART1_RX, | ||
64 | IRQ_UART1_ERROR, | ||
65 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
66 | CH_UART1_TX, | ||
67 | CH_UART1_RX, | ||
68 | #endif | ||
69 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
70 | CONFIG_UART1_CTS_PIN, | ||
71 | CONFIG_UART1_RTS_PIN, | ||
72 | #endif | ||
73 | }, | ||
74 | #endif | ||
75 | #ifdef CONFIG_SERIAL_BFIN_UART2 | ||
76 | { | ||
77 | 0xFFC02100, | ||
78 | IRQ_UART2_RX, | ||
79 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
80 | CH_UART2_TX, | ||
81 | CH_UART2_RX, | ||
82 | #endif | ||
83 | #ifdef CONFIG_BFIN_UART2_CTSRTS | ||
84 | CONFIG_UART2_CTS_PIN, | ||
85 | CONFIG_UART2_RTS_PIN, | ||
86 | #endif | ||
87 | }, | ||
88 | #endif | ||
89 | }; | ||
90 | |||
91 | #define DRIVER_NAME "bfin-uart" | ||
92 | |||
93 | #include <asm/bfin_serial.h> | ||
diff --git a/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h deleted file mode 100644 index 0d94edaaaa2e..000000000000 --- a/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h +++ /dev/null | |||
@@ -1,94 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2007-2009 Analog Devices Inc. | ||
3 | * | ||
4 | * Licensed under the GPL-2 or later. | ||
5 | */ | ||
6 | |||
7 | #include <asm/dma.h> | ||
8 | #include <asm/portmux.h> | ||
9 | |||
10 | #if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS) || \ | ||
11 | defined(CONFIG_BFIN_UART2_CTSRTS) || defined(CONFIG_BFIN_UART3_CTSRTS) | ||
12 | # define CONFIG_SERIAL_BFIN_HARD_CTSRTS | ||
13 | #endif | ||
14 | |||
15 | struct bfin_serial_res { | ||
16 | unsigned long uart_base_addr; | ||
17 | int uart_irq; | ||
18 | int uart_status_irq; | ||
19 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
20 | unsigned int uart_tx_dma_channel; | ||
21 | unsigned int uart_rx_dma_channel; | ||
22 | #endif | ||
23 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS | ||
24 | int uart_cts_pin; | ||
25 | int uart_rts_pin; | ||
26 | #endif | ||
27 | }; | ||
28 | |||
29 | struct bfin_serial_res bfin_serial_resource[] = { | ||
30 | #ifdef CONFIG_SERIAL_BFIN_UART0 | ||
31 | { | ||
32 | 0xFFC00400, | ||
33 | IRQ_UART0_RX, | ||
34 | IRQ_UART0_ERROR, | ||
35 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
36 | CH_UART0_TX, | ||
37 | CH_UART0_RX, | ||
38 | #endif | ||
39 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS | ||
40 | 0, | ||
41 | 0, | ||
42 | #endif | ||
43 | }, | ||
44 | #endif | ||
45 | #ifdef CONFIG_SERIAL_BFIN_UART1 | ||
46 | { | ||
47 | 0xFFC02000, | ||
48 | IRQ_UART1_RX, | ||
49 | IRQ_UART1_ERROR, | ||
50 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
51 | CH_UART1_TX, | ||
52 | CH_UART1_RX, | ||
53 | #endif | ||
54 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS | ||
55 | GPIO_PE10, | ||
56 | GPIO_PE9, | ||
57 | #endif | ||
58 | }, | ||
59 | #endif | ||
60 | #ifdef CONFIG_SERIAL_BFIN_UART2 | ||
61 | { | ||
62 | 0xFFC02100, | ||
63 | IRQ_UART2_RX, | ||
64 | IRQ_UART2_ERROR, | ||
65 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
66 | CH_UART2_TX, | ||
67 | CH_UART2_RX, | ||
68 | #endif | ||
69 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS | ||
70 | 0, | ||
71 | 0, | ||
72 | #endif | ||
73 | }, | ||
74 | #endif | ||
75 | #ifdef CONFIG_SERIAL_BFIN_UART3 | ||
76 | { | ||
77 | 0xFFC03100, | ||
78 | IRQ_UART3_RX, | ||
79 | IRQ_UART3_ERROR, | ||
80 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
81 | CH_UART3_TX, | ||
82 | CH_UART3_RX, | ||
83 | #endif | ||
84 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS | ||
85 | GPIO_PB3, | ||
86 | GPIO_PB2, | ||
87 | #endif | ||
88 | }, | ||
89 | #endif | ||
90 | }; | ||
91 | |||
92 | #define DRIVER_NAME "bfin-uart" | ||
93 | |||
94 | #include <asm/bfin_serial.h> | ||
diff --git a/arch/blackfin/mach-bf548/include/mach/defBF547.h b/arch/blackfin/mach-bf548/include/mach/defBF547.h index 1cbba115f96f..1fa41ec03f31 100644 --- a/arch/blackfin/mach-bf548/include/mach/defBF547.h +++ b/arch/blackfin/mach-bf548/include/mach/defBF547.h | |||
@@ -271,10 +271,10 @@ | |||
271 | #define USB_EP_NI0_TXINTERVAL 0xffc03e18 /* Sets the NAK response timeout on Endpoint 0 */ | 271 | #define USB_EP_NI0_TXINTERVAL 0xffc03e18 /* Sets the NAK response timeout on Endpoint 0 */ |
272 | #define USB_EP_NI0_RXTYPE 0xffc03e1c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint0 */ | 272 | #define USB_EP_NI0_RXTYPE 0xffc03e1c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint0 */ |
273 | #define USB_EP_NI0_RXINTERVAL 0xffc03e20 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint0 */ | 273 | #define USB_EP_NI0_RXINTERVAL 0xffc03e20 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint0 */ |
274 | #define USB_EP_NI0_TXCOUNT 0xffc03e28 /* Number of bytes to be written to the endpoint0 Tx FIFO */ | ||
274 | 275 | ||
275 | /* USB Endpoint 1 Control Registers */ | 276 | /* USB Endpoint 1 Control Registers */ |
276 | 277 | ||
277 | #define USB_EP_NI0_TXCOUNT 0xffc03e28 /* Number of bytes to be written to the endpoint0 Tx FIFO */ | ||
278 | #define USB_EP_NI1_TXMAXP 0xffc03e40 /* Maximum packet size for Host Tx endpoint1 */ | 278 | #define USB_EP_NI1_TXMAXP 0xffc03e40 /* Maximum packet size for Host Tx endpoint1 */ |
279 | #define USB_EP_NI1_TXCSR 0xffc03e44 /* Control Status register for endpoint1 */ | 279 | #define USB_EP_NI1_TXCSR 0xffc03e44 /* Control Status register for endpoint1 */ |
280 | #define USB_EP_NI1_RXMAXP 0xffc03e48 /* Maximum packet size for Host Rx endpoint1 */ | 280 | #define USB_EP_NI1_RXMAXP 0xffc03e48 /* Maximum packet size for Host Rx endpoint1 */ |
@@ -284,10 +284,10 @@ | |||
284 | #define USB_EP_NI1_TXINTERVAL 0xffc03e58 /* Sets the NAK response timeout on Endpoint1 */ | 284 | #define USB_EP_NI1_TXINTERVAL 0xffc03e58 /* Sets the NAK response timeout on Endpoint1 */ |
285 | #define USB_EP_NI1_RXTYPE 0xffc03e5c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint1 */ | 285 | #define USB_EP_NI1_RXTYPE 0xffc03e5c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint1 */ |
286 | #define USB_EP_NI1_RXINTERVAL 0xffc03e60 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint1 */ | 286 | #define USB_EP_NI1_RXINTERVAL 0xffc03e60 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint1 */ |
287 | #define USB_EP_NI1_TXCOUNT 0xffc03e68 /* Number of bytes to be written to the+H102 endpoint1 Tx FIFO */ | ||
287 | 288 | ||
288 | /* USB Endpoint 2 Control Registers */ | 289 | /* USB Endpoint 2 Control Registers */ |
289 | 290 | ||
290 | #define USB_EP_NI1_TXCOUNT 0xffc03e68 /* Number of bytes to be written to the+H102 endpoint1 Tx FIFO */ | ||
291 | #define USB_EP_NI2_TXMAXP 0xffc03e80 /* Maximum packet size for Host Tx endpoint2 */ | 291 | #define USB_EP_NI2_TXMAXP 0xffc03e80 /* Maximum packet size for Host Tx endpoint2 */ |
292 | #define USB_EP_NI2_TXCSR 0xffc03e84 /* Control Status register for endpoint2 */ | 292 | #define USB_EP_NI2_TXCSR 0xffc03e84 /* Control Status register for endpoint2 */ |
293 | #define USB_EP_NI2_RXMAXP 0xffc03e88 /* Maximum packet size for Host Rx endpoint2 */ | 293 | #define USB_EP_NI2_RXMAXP 0xffc03e88 /* Maximum packet size for Host Rx endpoint2 */ |
@@ -297,10 +297,10 @@ | |||
297 | #define USB_EP_NI2_TXINTERVAL 0xffc03e98 /* Sets the NAK response timeout on Endpoint2 */ | 297 | #define USB_EP_NI2_TXINTERVAL 0xffc03e98 /* Sets the NAK response timeout on Endpoint2 */ |
298 | #define USB_EP_NI2_RXTYPE 0xffc03e9c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint2 */ | 298 | #define USB_EP_NI2_RXTYPE 0xffc03e9c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint2 */ |
299 | #define USB_EP_NI2_RXINTERVAL 0xffc03ea0 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint2 */ | 299 | #define USB_EP_NI2_RXINTERVAL 0xffc03ea0 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint2 */ |
300 | #define USB_EP_NI2_TXCOUNT 0xffc03ea8 /* Number of bytes to be written to the endpoint2 Tx FIFO */ | ||
300 | 301 | ||
301 | /* USB Endpoint 3 Control Registers */ | 302 | /* USB Endpoint 3 Control Registers */ |
302 | 303 | ||
303 | #define USB_EP_NI2_TXCOUNT 0xffc03ea8 /* Number of bytes to be written to the endpoint2 Tx FIFO */ | ||
304 | #define USB_EP_NI3_TXMAXP 0xffc03ec0 /* Maximum packet size for Host Tx endpoint3 */ | 304 | #define USB_EP_NI3_TXMAXP 0xffc03ec0 /* Maximum packet size for Host Tx endpoint3 */ |
305 | #define USB_EP_NI3_TXCSR 0xffc03ec4 /* Control Status register for endpoint3 */ | 305 | #define USB_EP_NI3_TXCSR 0xffc03ec4 /* Control Status register for endpoint3 */ |
306 | #define USB_EP_NI3_RXMAXP 0xffc03ec8 /* Maximum packet size for Host Rx endpoint3 */ | 306 | #define USB_EP_NI3_RXMAXP 0xffc03ec8 /* Maximum packet size for Host Rx endpoint3 */ |
@@ -310,10 +310,10 @@ | |||
310 | #define USB_EP_NI3_TXINTERVAL 0xffc03ed8 /* Sets the NAK response timeout on Endpoint3 */ | 310 | #define USB_EP_NI3_TXINTERVAL 0xffc03ed8 /* Sets the NAK response timeout on Endpoint3 */ |
311 | #define USB_EP_NI3_RXTYPE 0xffc03edc /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint3 */ | 311 | #define USB_EP_NI3_RXTYPE 0xffc03edc /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint3 */ |
312 | #define USB_EP_NI3_RXINTERVAL 0xffc03ee0 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint3 */ | 312 | #define USB_EP_NI3_RXINTERVAL 0xffc03ee0 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint3 */ |
313 | #define USB_EP_NI3_TXCOUNT 0xffc03ee8 /* Number of bytes to be written to the H124endpoint3 Tx FIFO */ | ||
313 | 314 | ||
314 | /* USB Endpoint 4 Control Registers */ | 315 | /* USB Endpoint 4 Control Registers */ |
315 | 316 | ||
316 | #define USB_EP_NI3_TXCOUNT 0xffc03ee8 /* Number of bytes to be written to the H124endpoint3 Tx FIFO */ | ||
317 | #define USB_EP_NI4_TXMAXP 0xffc03f00 /* Maximum packet size for Host Tx endpoint4 */ | 317 | #define USB_EP_NI4_TXMAXP 0xffc03f00 /* Maximum packet size for Host Tx endpoint4 */ |
318 | #define USB_EP_NI4_TXCSR 0xffc03f04 /* Control Status register for endpoint4 */ | 318 | #define USB_EP_NI4_TXCSR 0xffc03f04 /* Control Status register for endpoint4 */ |
319 | #define USB_EP_NI4_RXMAXP 0xffc03f08 /* Maximum packet size for Host Rx endpoint4 */ | 319 | #define USB_EP_NI4_RXMAXP 0xffc03f08 /* Maximum packet size for Host Rx endpoint4 */ |
@@ -323,10 +323,10 @@ | |||
323 | #define USB_EP_NI4_TXINTERVAL 0xffc03f18 /* Sets the NAK response timeout on Endpoint4 */ | 323 | #define USB_EP_NI4_TXINTERVAL 0xffc03f18 /* Sets the NAK response timeout on Endpoint4 */ |
324 | #define USB_EP_NI4_RXTYPE 0xffc03f1c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint4 */ | 324 | #define USB_EP_NI4_RXTYPE 0xffc03f1c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint4 */ |
325 | #define USB_EP_NI4_RXINTERVAL 0xffc03f20 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint4 */ | 325 | #define USB_EP_NI4_RXINTERVAL 0xffc03f20 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint4 */ |
326 | #define USB_EP_NI4_TXCOUNT 0xffc03f28 /* Number of bytes to be written to the endpoint4 Tx FIFO */ | ||
326 | 327 | ||
327 | /* USB Endpoint 5 Control Registers */ | 328 | /* USB Endpoint 5 Control Registers */ |
328 | 329 | ||
329 | #define USB_EP_NI4_TXCOUNT 0xffc03f28 /* Number of bytes to be written to the endpoint4 Tx FIFO */ | ||
330 | #define USB_EP_NI5_TXMAXP 0xffc03f40 /* Maximum packet size for Host Tx endpoint5 */ | 330 | #define USB_EP_NI5_TXMAXP 0xffc03f40 /* Maximum packet size for Host Tx endpoint5 */ |
331 | #define USB_EP_NI5_TXCSR 0xffc03f44 /* Control Status register for endpoint5 */ | 331 | #define USB_EP_NI5_TXCSR 0xffc03f44 /* Control Status register for endpoint5 */ |
332 | #define USB_EP_NI5_RXMAXP 0xffc03f48 /* Maximum packet size for Host Rx endpoint5 */ | 332 | #define USB_EP_NI5_RXMAXP 0xffc03f48 /* Maximum packet size for Host Rx endpoint5 */ |
@@ -336,10 +336,10 @@ | |||
336 | #define USB_EP_NI5_TXINTERVAL 0xffc03f58 /* Sets the NAK response timeout on Endpoint5 */ | 336 | #define USB_EP_NI5_TXINTERVAL 0xffc03f58 /* Sets the NAK response timeout on Endpoint5 */ |
337 | #define USB_EP_NI5_RXTYPE 0xffc03f5c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint5 */ | 337 | #define USB_EP_NI5_RXTYPE 0xffc03f5c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint5 */ |
338 | #define USB_EP_NI5_RXINTERVAL 0xffc03f60 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint5 */ | 338 | #define USB_EP_NI5_RXINTERVAL 0xffc03f60 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint5 */ |
339 | #define USB_EP_NI5_TXCOUNT 0xffc03f68 /* Number of bytes to be written to the H145endpoint5 Tx FIFO */ | ||
339 | 340 | ||
340 | /* USB Endpoint 6 Control Registers */ | 341 | /* USB Endpoint 6 Control Registers */ |
341 | 342 | ||
342 | #define USB_EP_NI5_TXCOUNT 0xffc03f68 /* Number of bytes to be written to the H145endpoint5 Tx FIFO */ | ||
343 | #define USB_EP_NI6_TXMAXP 0xffc03f80 /* Maximum packet size for Host Tx endpoint6 */ | 343 | #define USB_EP_NI6_TXMAXP 0xffc03f80 /* Maximum packet size for Host Tx endpoint6 */ |
344 | #define USB_EP_NI6_TXCSR 0xffc03f84 /* Control Status register for endpoint6 */ | 344 | #define USB_EP_NI6_TXCSR 0xffc03f84 /* Control Status register for endpoint6 */ |
345 | #define USB_EP_NI6_RXMAXP 0xffc03f88 /* Maximum packet size for Host Rx endpoint6 */ | 345 | #define USB_EP_NI6_RXMAXP 0xffc03f88 /* Maximum packet size for Host Rx endpoint6 */ |
@@ -349,10 +349,10 @@ | |||
349 | #define USB_EP_NI6_TXINTERVAL 0xffc03f98 /* Sets the NAK response timeout on Endpoint6 */ | 349 | #define USB_EP_NI6_TXINTERVAL 0xffc03f98 /* Sets the NAK response timeout on Endpoint6 */ |
350 | #define USB_EP_NI6_RXTYPE 0xffc03f9c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint6 */ | 350 | #define USB_EP_NI6_RXTYPE 0xffc03f9c /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint6 */ |
351 | #define USB_EP_NI6_RXINTERVAL 0xffc03fa0 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint6 */ | 351 | #define USB_EP_NI6_RXINTERVAL 0xffc03fa0 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint6 */ |
352 | #define USB_EP_NI6_TXCOUNT 0xffc03fa8 /* Number of bytes to be written to the endpoint6 Tx FIFO */ | ||
352 | 353 | ||
353 | /* USB Endpoint 7 Control Registers */ | 354 | /* USB Endpoint 7 Control Registers */ |
354 | 355 | ||
355 | #define USB_EP_NI6_TXCOUNT 0xffc03fa8 /* Number of bytes to be written to the endpoint6 Tx FIFO */ | ||
356 | #define USB_EP_NI7_TXMAXP 0xffc03fc0 /* Maximum packet size for Host Tx endpoint7 */ | 356 | #define USB_EP_NI7_TXMAXP 0xffc03fc0 /* Maximum packet size for Host Tx endpoint7 */ |
357 | #define USB_EP_NI7_TXCSR 0xffc03fc4 /* Control Status register for endpoint7 */ | 357 | #define USB_EP_NI7_TXCSR 0xffc03fc4 /* Control Status register for endpoint7 */ |
358 | #define USB_EP_NI7_RXMAXP 0xffc03fc8 /* Maximum packet size for Host Rx endpoint7 */ | 358 | #define USB_EP_NI7_RXMAXP 0xffc03fc8 /* Maximum packet size for Host Rx endpoint7 */ |
@@ -361,8 +361,9 @@ | |||
361 | #define USB_EP_NI7_TXTYPE 0xffc03fd4 /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint7 */ | 361 | #define USB_EP_NI7_TXTYPE 0xffc03fd4 /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint7 */ |
362 | #define USB_EP_NI7_TXINTERVAL 0xffc03fd8 /* Sets the NAK response timeout on Endpoint7 */ | 362 | #define USB_EP_NI7_TXINTERVAL 0xffc03fd8 /* Sets the NAK response timeout on Endpoint7 */ |
363 | #define USB_EP_NI7_RXTYPE 0xffc03fdc /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint7 */ | 363 | #define USB_EP_NI7_RXTYPE 0xffc03fdc /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint7 */ |
364 | #define USB_EP_NI7_RXINTERVAL 0xffc03ff0 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint7 */ | 364 | #define USB_EP_NI7_RXINTERVAL 0xffc03fe0 /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint7 */ |
365 | #define USB_EP_NI7_TXCOUNT 0xffc03ff8 /* Number of bytes to be written to the endpoint7 Tx FIFO */ | 365 | #define USB_EP_NI7_TXCOUNT 0xffc03fe8 /* Number of bytes to be written to the endpoint7 Tx FIFO */ |
366 | |||
366 | #define USB_DMA_INTERRUPT 0xffc04000 /* Indicates pending interrupts for the DMA channels */ | 367 | #define USB_DMA_INTERRUPT 0xffc04000 /* Indicates pending interrupts for the DMA channels */ |
367 | 368 | ||
368 | /* USB Channel 0 Config Registers */ | 369 | /* USB Channel 0 Config Registers */ |
diff --git a/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h deleted file mode 100644 index 3a6947456cf1..000000000000 --- a/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h +++ /dev/null | |||
@@ -1,52 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2006-2009 Analog Devices Inc. | ||
3 | * | ||
4 | * Licensed under the GPL-2 or later. | ||
5 | */ | ||
6 | |||
7 | #include <asm/dma.h> | ||
8 | #include <asm/portmux.h> | ||
9 | |||
10 | #ifdef CONFIG_BFIN_UART0_CTSRTS | ||
11 | # define CONFIG_SERIAL_BFIN_CTSRTS | ||
12 | # ifndef CONFIG_UART0_CTS_PIN | ||
13 | # define CONFIG_UART0_CTS_PIN -1 | ||
14 | # endif | ||
15 | # ifndef CONFIG_UART0_RTS_PIN | ||
16 | # define CONFIG_UART0_RTS_PIN -1 | ||
17 | # endif | ||
18 | #endif | ||
19 | |||
20 | struct bfin_serial_res { | ||
21 | unsigned long uart_base_addr; | ||
22 | int uart_irq; | ||
23 | int uart_status_irq; | ||
24 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
25 | unsigned int uart_tx_dma_channel; | ||
26 | unsigned int uart_rx_dma_channel; | ||
27 | #endif | ||
28 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
29 | int uart_cts_pin; | ||
30 | int uart_rts_pin; | ||
31 | #endif | ||
32 | }; | ||
33 | |||
34 | struct bfin_serial_res bfin_serial_resource[] = { | ||
35 | { | ||
36 | 0xFFC00400, | ||
37 | IRQ_UART_RX, | ||
38 | IRQ_UART_ERROR, | ||
39 | #ifdef CONFIG_SERIAL_BFIN_DMA | ||
40 | CH_UART_TX, | ||
41 | CH_UART_RX, | ||
42 | #endif | ||
43 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
44 | CONFIG_UART0_CTS_PIN, | ||
45 | CONFIG_UART0_RTS_PIN, | ||
46 | #endif | ||
47 | } | ||
48 | }; | ||
49 | |||
50 | #define DRIVER_NAME "bfin-uart" | ||
51 | |||
52 | #include <asm/bfin_serial.h> | ||
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index dda11ef06be5..225d311c9701 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S | |||
@@ -1754,6 +1754,7 @@ ENTRY(_sys_call_table) | |||
1754 | .long _sys_clock_adjtime | 1754 | .long _sys_clock_adjtime |
1755 | .long _sys_syncfs | 1755 | .long _sys_syncfs |
1756 | .long _sys_setns | 1756 | .long _sys_setns |
1757 | .long _sys_sendmmsg /* 380 */ | ||
1757 | 1758 | ||
1758 | .rept NR_syscalls-(.-_sys_call_table)/4 | 1759 | .rept NR_syscalls-(.-_sys_call_table)/4 |
1759 | .long _sys_ni_syscall | 1760 | .long _sys_ni_syscall |
diff --git a/arch/blackfin/mm/maccess.c b/arch/blackfin/mm/maccess.c index b71cebc1f8a3..e2532114c5fd 100644 --- a/arch/blackfin/mm/maccess.c +++ b/arch/blackfin/mm/maccess.c | |||
@@ -16,7 +16,7 @@ static int validate_memory_access_address(unsigned long addr, int size) | |||
16 | return bfin_mem_access_type(addr, size); | 16 | return bfin_mem_access_type(addr, size); |
17 | } | 17 | } |
18 | 18 | ||
19 | long probe_kernel_read(void *dst, void *src, size_t size) | 19 | long probe_kernel_read(void *dst, const void *src, size_t size) |
20 | { | 20 | { |
21 | unsigned long lsrc = (unsigned long)src; | 21 | unsigned long lsrc = (unsigned long)src; |
22 | int mem_type; | 22 | int mem_type; |
@@ -55,7 +55,7 @@ long probe_kernel_read(void *dst, void *src, size_t size) | |||
55 | return -EFAULT; | 55 | return -EFAULT; |
56 | } | 56 | } |
57 | 57 | ||
58 | long probe_kernel_write(void *dst, void *src, size_t size) | 58 | long probe_kernel_write(void *dst, const void *src, size_t size) |
59 | { | 59 | { |
60 | unsigned long ldst = (unsigned long)dst; | 60 | unsigned long ldst = (unsigned long)dst; |
61 | int mem_type; | 61 | int mem_type; |
diff --git a/arch/ia64/include/asm/unistd.h b/arch/ia64/include/asm/unistd.h index 1cf0f496f744..7c928da35b17 100644 --- a/arch/ia64/include/asm/unistd.h +++ b/arch/ia64/include/asm/unistd.h | |||
@@ -320,11 +320,12 @@ | |||
320 | #define __NR_clock_adjtime 1328 | 320 | #define __NR_clock_adjtime 1328 |
321 | #define __NR_syncfs 1329 | 321 | #define __NR_syncfs 1329 |
322 | #define __NR_setns 1330 | 322 | #define __NR_setns 1330 |
323 | #define __NR_sendmmsg 1331 | ||
323 | 324 | ||
324 | #ifdef __KERNEL__ | 325 | #ifdef __KERNEL__ |
325 | 326 | ||
326 | 327 | ||
327 | #define NR_syscalls 307 /* length of syscall table */ | 328 | #define NR_syscalls 308 /* length of syscall table */ |
328 | 329 | ||
329 | /* | 330 | /* |
330 | * The following defines stop scripts/checksyscalls.sh from complaining about | 331 | * The following defines stop scripts/checksyscalls.sh from complaining about |
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 9ca80193cd4e..97dd2abdeb1a 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S | |||
@@ -1776,6 +1776,7 @@ sys_call_table: | |||
1776 | data8 sys_clock_adjtime | 1776 | data8 sys_clock_adjtime |
1777 | data8 sys_syncfs | 1777 | data8 sys_syncfs |
1778 | data8 sys_setns // 1330 | 1778 | data8 sys_setns // 1330 |
1779 | data8 sys_sendmmsg | ||
1779 | 1780 | ||
1780 | .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls | 1781 | .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls |
1781 | #endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */ | 1782 | #endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */ |
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index 9089b0421191..7667db448aa7 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c | |||
@@ -715,7 +715,8 @@ static struct syscore_ops pmacpic_syscore_ops = { | |||
715 | 715 | ||
716 | static int __init init_pmacpic_syscore(void) | 716 | static int __init init_pmacpic_syscore(void) |
717 | { | 717 | { |
718 | register_syscore_ops(&pmacpic_syscore_ops); | 718 | if (pmac_irq_hw[0]) |
719 | register_syscore_ops(&pmacpic_syscore_ops); | ||
719 | return 0; | 720 | return 0; |
720 | } | 721 | } |
721 | 722 | ||
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index c4773a2ef3d3..e4efacfe1b63 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h | |||
@@ -577,16 +577,16 @@ static inline void pgste_set_unlock(pte_t *ptep, pgste_t pgste) | |||
577 | static inline pgste_t pgste_update_all(pte_t *ptep, pgste_t pgste) | 577 | static inline pgste_t pgste_update_all(pte_t *ptep, pgste_t pgste) |
578 | { | 578 | { |
579 | #ifdef CONFIG_PGSTE | 579 | #ifdef CONFIG_PGSTE |
580 | unsigned long pfn, bits; | 580 | unsigned long address, bits; |
581 | unsigned char skey; | 581 | unsigned char skey; |
582 | 582 | ||
583 | pfn = pte_val(*ptep) >> PAGE_SHIFT; | 583 | address = pte_val(*ptep) & PAGE_MASK; |
584 | skey = page_get_storage_key(pfn); | 584 | skey = page_get_storage_key(address); |
585 | bits = skey & (_PAGE_CHANGED | _PAGE_REFERENCED); | 585 | bits = skey & (_PAGE_CHANGED | _PAGE_REFERENCED); |
586 | /* Clear page changed & referenced bit in the storage key */ | 586 | /* Clear page changed & referenced bit in the storage key */ |
587 | if (bits) { | 587 | if (bits) { |
588 | skey ^= bits; | 588 | skey ^= bits; |
589 | page_set_storage_key(pfn, skey, 1); | 589 | page_set_storage_key(address, skey, 1); |
590 | } | 590 | } |
591 | /* Transfer page changed & referenced bit to guest bits in pgste */ | 591 | /* Transfer page changed & referenced bit to guest bits in pgste */ |
592 | pgste_val(pgste) |= bits << 48; /* RCP_GR_BIT & RCP_GC_BIT */ | 592 | pgste_val(pgste) |= bits << 48; /* RCP_GR_BIT & RCP_GC_BIT */ |
@@ -628,16 +628,16 @@ static inline pgste_t pgste_update_young(pte_t *ptep, pgste_t pgste) | |||
628 | static inline void pgste_set_pte(pte_t *ptep, pgste_t pgste) | 628 | static inline void pgste_set_pte(pte_t *ptep, pgste_t pgste) |
629 | { | 629 | { |
630 | #ifdef CONFIG_PGSTE | 630 | #ifdef CONFIG_PGSTE |
631 | unsigned long pfn; | 631 | unsigned long address; |
632 | unsigned long okey, nkey; | 632 | unsigned long okey, nkey; |
633 | 633 | ||
634 | pfn = pte_val(*ptep) >> PAGE_SHIFT; | 634 | address = pte_val(*ptep) & PAGE_MASK; |
635 | okey = nkey = page_get_storage_key(pfn); | 635 | okey = nkey = page_get_storage_key(address); |
636 | nkey &= ~(_PAGE_ACC_BITS | _PAGE_FP_BIT); | 636 | nkey &= ~(_PAGE_ACC_BITS | _PAGE_FP_BIT); |
637 | /* Set page access key and fetch protection bit from pgste */ | 637 | /* Set page access key and fetch protection bit from pgste */ |
638 | nkey |= (pgste_val(pgste) & (RCP_ACC_BITS | RCP_FP_BIT)) >> 56; | 638 | nkey |= (pgste_val(pgste) & (RCP_ACC_BITS | RCP_FP_BIT)) >> 56; |
639 | if (okey != nkey) | 639 | if (okey != nkey) |
640 | page_set_storage_key(pfn, nkey, 1); | 640 | page_set_storage_key(address, nkey, 1); |
641 | #endif | 641 | #endif |
642 | } | 642 | } |
643 | 643 | ||
diff --git a/arch/s390/mm/maccess.c b/arch/s390/mm/maccess.c index 71a4b0d34be0..51e5cd9b906a 100644 --- a/arch/s390/mm/maccess.c +++ b/arch/s390/mm/maccess.c | |||
@@ -19,7 +19,7 @@ | |||
19 | * using the stura instruction. | 19 | * using the stura instruction. |
20 | * Returns the number of bytes copied or -EFAULT. | 20 | * Returns the number of bytes copied or -EFAULT. |
21 | */ | 21 | */ |
22 | static long probe_kernel_write_odd(void *dst, void *src, size_t size) | 22 | static long probe_kernel_write_odd(void *dst, const void *src, size_t size) |
23 | { | 23 | { |
24 | unsigned long count, aligned; | 24 | unsigned long count, aligned; |
25 | int offset, mask; | 25 | int offset, mask; |
@@ -45,7 +45,7 @@ static long probe_kernel_write_odd(void *dst, void *src, size_t size) | |||
45 | return rc ? rc : count; | 45 | return rc ? rc : count; |
46 | } | 46 | } |
47 | 47 | ||
48 | long probe_kernel_write(void *dst, void *src, size_t size) | 48 | long probe_kernel_write(void *dst, const void *src, size_t size) |
49 | { | 49 | { |
50 | long copied = 0; | 50 | long copied = 0; |
51 | 51 | ||
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 14c6fae6fe6b..b09763fe5da1 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c | |||
@@ -71,12 +71,15 @@ static void rcu_table_freelist_callback(struct rcu_head *head) | |||
71 | 71 | ||
72 | void rcu_table_freelist_finish(void) | 72 | void rcu_table_freelist_finish(void) |
73 | { | 73 | { |
74 | struct rcu_table_freelist *batch = __get_cpu_var(rcu_table_freelist); | 74 | struct rcu_table_freelist **batchp = &get_cpu_var(rcu_table_freelist); |
75 | struct rcu_table_freelist *batch = *batchp; | ||
75 | 76 | ||
76 | if (!batch) | 77 | if (!batch) |
77 | return; | 78 | goto out; |
78 | call_rcu(&batch->rcu, rcu_table_freelist_callback); | 79 | call_rcu(&batch->rcu, rcu_table_freelist_callback); |
79 | __get_cpu_var(rcu_table_freelist) = NULL; | 80 | *batchp = NULL; |
81 | out: | ||
82 | put_cpu_var(rcu_table_freelist); | ||
80 | } | 83 | } |
81 | 84 | ||
82 | static void smp_sync(void *arg) | 85 | static void smp_sync(void *arg) |
@@ -141,20 +144,23 @@ void crst_table_free_rcu(struct mm_struct *mm, unsigned long *table) | |||
141 | { | 144 | { |
142 | struct rcu_table_freelist *batch; | 145 | struct rcu_table_freelist *batch; |
143 | 146 | ||
147 | preempt_disable(); | ||
144 | if (atomic_read(&mm->mm_users) < 2 && | 148 | if (atomic_read(&mm->mm_users) < 2 && |
145 | cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) { | 149 | cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) { |
146 | crst_table_free(mm, table); | 150 | crst_table_free(mm, table); |
147 | return; | 151 | goto out; |
148 | } | 152 | } |
149 | batch = rcu_table_freelist_get(mm); | 153 | batch = rcu_table_freelist_get(mm); |
150 | if (!batch) { | 154 | if (!batch) { |
151 | smp_call_function(smp_sync, NULL, 1); | 155 | smp_call_function(smp_sync, NULL, 1); |
152 | crst_table_free(mm, table); | 156 | crst_table_free(mm, table); |
153 | return; | 157 | goto out; |
154 | } | 158 | } |
155 | batch->table[--batch->crst_index] = table; | 159 | batch->table[--batch->crst_index] = table; |
156 | if (batch->pgt_index >= batch->crst_index) | 160 | if (batch->pgt_index >= batch->crst_index) |
157 | rcu_table_freelist_finish(); | 161 | rcu_table_freelist_finish(); |
162 | out: | ||
163 | preempt_enable(); | ||
158 | } | 164 | } |
159 | 165 | ||
160 | #ifdef CONFIG_64BIT | 166 | #ifdef CONFIG_64BIT |
@@ -323,16 +329,17 @@ void page_table_free_rcu(struct mm_struct *mm, unsigned long *table) | |||
323 | struct page *page; | 329 | struct page *page; |
324 | unsigned long bits; | 330 | unsigned long bits; |
325 | 331 | ||
332 | preempt_disable(); | ||
326 | if (atomic_read(&mm->mm_users) < 2 && | 333 | if (atomic_read(&mm->mm_users) < 2 && |
327 | cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) { | 334 | cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) { |
328 | page_table_free(mm, table); | 335 | page_table_free(mm, table); |
329 | return; | 336 | goto out; |
330 | } | 337 | } |
331 | batch = rcu_table_freelist_get(mm); | 338 | batch = rcu_table_freelist_get(mm); |
332 | if (!batch) { | 339 | if (!batch) { |
333 | smp_call_function(smp_sync, NULL, 1); | 340 | smp_call_function(smp_sync, NULL, 1); |
334 | page_table_free(mm, table); | 341 | page_table_free(mm, table); |
335 | return; | 342 | goto out; |
336 | } | 343 | } |
337 | bits = (mm->context.has_pgste) ? 3UL : 1UL; | 344 | bits = (mm->context.has_pgste) ? 3UL : 1UL; |
338 | bits <<= (__pa(table) & (PAGE_SIZE - 1)) / 256 / sizeof(unsigned long); | 345 | bits <<= (__pa(table) & (PAGE_SIZE - 1)) / 256 / sizeof(unsigned long); |
@@ -345,6 +352,8 @@ void page_table_free_rcu(struct mm_struct *mm, unsigned long *table) | |||
345 | batch->table[batch->pgt_index++] = table; | 352 | batch->table[batch->pgt_index++] = table; |
346 | if (batch->pgt_index >= batch->crst_index) | 353 | if (batch->pgt_index >= batch->crst_index) |
347 | rcu_table_freelist_finish(); | 354 | rcu_table_freelist_finish(); |
355 | out: | ||
356 | preempt_enable(); | ||
348 | } | 357 | } |
349 | 358 | ||
350 | /* | 359 | /* |
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 74495a5ea027..f03338c2f088 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig | |||
@@ -161,7 +161,7 @@ config ARCH_HAS_CPU_IDLE_WAIT | |||
161 | 161 | ||
162 | config NO_IOPORT | 162 | config NO_IOPORT |
163 | def_bool !PCI | 163 | def_bool !PCI |
164 | depends on !SH_CAYMAN && !SH_SH4202_MICRODEV | 164 | depends on !SH_CAYMAN && !SH_SH4202_MICRODEV && !SH_SHMIN |
165 | 165 | ||
166 | config IO_TRAPPED | 166 | config IO_TRAPPED |
167 | bool | 167 | bool |
diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c index 618bd566cf53..969421f64a15 100644 --- a/arch/sh/boards/mach-ap325rxa/setup.c +++ b/arch/sh/boards/mach-ap325rxa/setup.c | |||
@@ -359,37 +359,31 @@ static struct soc_camera_link camera_link = { | |||
359 | .priv = &camera_info, | 359 | .priv = &camera_info, |
360 | }; | 360 | }; |
361 | 361 | ||
362 | static void dummy_release(struct device *dev) | 362 | static struct platform_device *camera_device; |
363 | |||
364 | static void ap325rxa_camera_release(struct device *dev) | ||
363 | { | 365 | { |
366 | soc_camera_platform_release(&camera_device); | ||
364 | } | 367 | } |
365 | 368 | ||
366 | static struct platform_device camera_device = { | ||
367 | .name = "soc_camera_platform", | ||
368 | .dev = { | ||
369 | .platform_data = &camera_info, | ||
370 | .release = dummy_release, | ||
371 | }, | ||
372 | }; | ||
373 | |||
374 | static int ap325rxa_camera_add(struct soc_camera_link *icl, | 369 | static int ap325rxa_camera_add(struct soc_camera_link *icl, |
375 | struct device *dev) | 370 | struct device *dev) |
376 | { | 371 | { |
377 | if (icl != &camera_link || camera_probe() <= 0) | 372 | int ret = soc_camera_platform_add(icl, dev, &camera_device, &camera_link, |
378 | return -ENODEV; | 373 | ap325rxa_camera_release, 0); |
374 | if (ret < 0) | ||
375 | return ret; | ||
379 | 376 | ||
380 | camera_info.dev = dev; | 377 | ret = camera_probe(); |
378 | if (ret < 0) | ||
379 | soc_camera_platform_del(icl, camera_device, &camera_link); | ||
381 | 380 | ||
382 | return platform_device_register(&camera_device); | 381 | return ret; |
383 | } | 382 | } |
384 | 383 | ||
385 | static void ap325rxa_camera_del(struct soc_camera_link *icl) | 384 | static void ap325rxa_camera_del(struct soc_camera_link *icl) |
386 | { | 385 | { |
387 | if (icl != &camera_link) | 386 | soc_camera_platform_del(icl, camera_device, &camera_link); |
388 | return; | ||
389 | |||
390 | platform_device_unregister(&camera_device); | ||
391 | memset(&camera_device.dev.kobj, 0, | ||
392 | sizeof(camera_device.dev.kobj)); | ||
393 | } | 387 | } |
394 | #endif /* CONFIG_I2C */ | 388 | #endif /* CONFIG_I2C */ |
395 | 389 | ||
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index bb13d0e1b964..3a32741cc0ac 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c | |||
@@ -885,6 +885,9 @@ static struct platform_device sh_mmcif_device = { | |||
885 | }, | 885 | }, |
886 | .num_resources = ARRAY_SIZE(sh_mmcif_resources), | 886 | .num_resources = ARRAY_SIZE(sh_mmcif_resources), |
887 | .resource = sh_mmcif_resources, | 887 | .resource = sh_mmcif_resources, |
888 | .archdata = { | ||
889 | .hwblk_id = HWBLK_MMC, | ||
890 | }, | ||
888 | }; | 891 | }; |
889 | #endif | 892 | #endif |
890 | 893 | ||
diff --git a/arch/sh/include/asm/pgtable.h b/arch/sh/include/asm/pgtable.h index db85916b9e95..9210e93a92c3 100644 --- a/arch/sh/include/asm/pgtable.h +++ b/arch/sh/include/asm/pgtable.h | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <asm/pgtable-2level.h> | 18 | #include <asm/pgtable-2level.h> |
19 | #endif | 19 | #endif |
20 | #include <asm/page.h> | 20 | #include <asm/page.h> |
21 | #include <asm/mmu.h> | ||
21 | 22 | ||
22 | #ifndef __ASSEMBLY__ | 23 | #ifndef __ASSEMBLY__ |
23 | #include <asm/addrspace.h> | 24 | #include <asm/addrspace.h> |
diff --git a/arch/sh/include/asm/ptrace.h b/arch/sh/include/asm/ptrace.h index 40725b4a8018..88bd6be168a9 100644 --- a/arch/sh/include/asm/ptrace.h +++ b/arch/sh/include/asm/ptrace.h | |||
@@ -41,7 +41,9 @@ | |||
41 | 41 | ||
42 | #define user_mode(regs) (((regs)->sr & 0x40000000)==0) | 42 | #define user_mode(regs) (((regs)->sr & 0x40000000)==0) |
43 | #define kernel_stack_pointer(_regs) ((unsigned long)(_regs)->regs[15]) | 43 | #define kernel_stack_pointer(_regs) ((unsigned long)(_regs)->regs[15]) |
44 | #define GET_USP(regs) ((regs)->regs[15]) | 44 | |
45 | #define GET_FP(regs) ((regs)->regs[14]) | ||
46 | #define GET_USP(regs) ((regs)->regs[15]) | ||
45 | 47 | ||
46 | extern void show_regs(struct pt_regs *); | 48 | extern void show_regs(struct pt_regs *); |
47 | 49 | ||
@@ -131,7 +133,7 @@ extern void ptrace_triggered(struct perf_event *bp, int nmi, | |||
131 | 133 | ||
132 | static inline unsigned long profile_pc(struct pt_regs *regs) | 134 | static inline unsigned long profile_pc(struct pt_regs *regs) |
133 | { | 135 | { |
134 | unsigned long pc = instruction_pointer(regs); | 136 | unsigned long pc = regs->pc; |
135 | 137 | ||
136 | if (virt_addr_uncached(pc)) | 138 | if (virt_addr_uncached(pc)) |
137 | return CAC_ADDR(pc); | 139 | return CAC_ADDR(pc); |
diff --git a/arch/sh/include/asm/tlb.h b/arch/sh/include/asm/tlb.h index 6c308d8b9a50..ec88bfcdf7ce 100644 --- a/arch/sh/include/asm/tlb.h +++ b/arch/sh/include/asm/tlb.h | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/pagemap.h> | 9 | #include <linux/pagemap.h> |
10 | 10 | ||
11 | #ifdef CONFIG_MMU | 11 | #ifdef CONFIG_MMU |
12 | #include <linux/swap.h> | ||
12 | #include <asm/pgalloc.h> | 13 | #include <asm/pgalloc.h> |
13 | #include <asm/tlbflush.h> | 14 | #include <asm/tlbflush.h> |
14 | #include <asm/mmu_context.h> | 15 | #include <asm/mmu_context.h> |
diff --git a/arch/sh/include/cpu-sh4/cpu/sh7722.h b/arch/sh/include/cpu-sh4/cpu/sh7722.h index 7a5b8a331b4a..bd0622788d64 100644 --- a/arch/sh/include/cpu-sh4/cpu/sh7722.h +++ b/arch/sh/include/cpu-sh4/cpu/sh7722.h | |||
@@ -236,6 +236,7 @@ enum { | |||
236 | }; | 236 | }; |
237 | 237 | ||
238 | enum { | 238 | enum { |
239 | SHDMA_SLAVE_INVALID, | ||
239 | SHDMA_SLAVE_SCIF0_TX, | 240 | SHDMA_SLAVE_SCIF0_TX, |
240 | SHDMA_SLAVE_SCIF0_RX, | 241 | SHDMA_SLAVE_SCIF0_RX, |
241 | SHDMA_SLAVE_SCIF1_TX, | 242 | SHDMA_SLAVE_SCIF1_TX, |
diff --git a/arch/sh/include/cpu-sh4/cpu/sh7724.h b/arch/sh/include/cpu-sh4/cpu/sh7724.h index 7eb435999426..3daef8ecbc63 100644 --- a/arch/sh/include/cpu-sh4/cpu/sh7724.h +++ b/arch/sh/include/cpu-sh4/cpu/sh7724.h | |||
@@ -285,6 +285,7 @@ enum { | |||
285 | }; | 285 | }; |
286 | 286 | ||
287 | enum { | 287 | enum { |
288 | SHDMA_SLAVE_INVALID, | ||
288 | SHDMA_SLAVE_SCIF0_TX, | 289 | SHDMA_SLAVE_SCIF0_TX, |
289 | SHDMA_SLAVE_SCIF0_RX, | 290 | SHDMA_SLAVE_SCIF0_RX, |
290 | SHDMA_SLAVE_SCIF1_TX, | 291 | SHDMA_SLAVE_SCIF1_TX, |
diff --git a/arch/sh/include/cpu-sh4/cpu/sh7757.h b/arch/sh/include/cpu-sh4/cpu/sh7757.h index 05b8196c7753..41f9f8b9db73 100644 --- a/arch/sh/include/cpu-sh4/cpu/sh7757.h +++ b/arch/sh/include/cpu-sh4/cpu/sh7757.h | |||
@@ -252,6 +252,7 @@ enum { | |||
252 | }; | 252 | }; |
253 | 253 | ||
254 | enum { | 254 | enum { |
255 | SHDMA_SLAVE_INVALID, | ||
255 | SHDMA_SLAVE_SDHI_TX, | 256 | SHDMA_SLAVE_SDHI_TX, |
256 | SHDMA_SLAVE_SDHI_RX, | 257 | SHDMA_SLAVE_SDHI_RX, |
257 | SHDMA_SLAVE_MMCIF_TX, | 258 | SHDMA_SLAVE_MMCIF_TX, |
diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c index 762a13984bbd..b473f0c06fbc 100644 --- a/arch/sh/kernel/process_32.c +++ b/arch/sh/kernel/process_32.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/fs.h> | 21 | #include <linux/fs.h> |
22 | #include <linux/ftrace.h> | 22 | #include <linux/ftrace.h> |
23 | #include <linux/hw_breakpoint.h> | 23 | #include <linux/hw_breakpoint.h> |
24 | #include <linux/prefetch.h> | ||
24 | #include <asm/uaccess.h> | 25 | #include <asm/uaccess.h> |
25 | #include <asm/mmu_context.h> | 26 | #include <asm/mmu_context.h> |
26 | #include <asm/system.h> | 27 | #include <asm/system.h> |
diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c index 40733a952402..f251b5f27652 100644 --- a/arch/sh/mm/consistent.c +++ b/arch/sh/mm/consistent.c | |||
@@ -82,7 +82,7 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size, | |||
82 | void *addr; | 82 | void *addr; |
83 | 83 | ||
84 | addr = __in_29bit_mode() ? | 84 | addr = __in_29bit_mode() ? |
85 | (void *)P1SEGADDR((unsigned long)vaddr) : vaddr; | 85 | (void *)CAC_ADDR((unsigned long)vaddr) : vaddr; |
86 | 86 | ||
87 | switch (direction) { | 87 | switch (direction) { |
88 | case DMA_FROM_DEVICE: /* invalidate only */ | 88 | case DMA_FROM_DEVICE: /* invalidate only */ |
diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig index e1e50101b3bb..0249b8b4db54 100644 --- a/arch/tile/Kconfig +++ b/arch/tile/Kconfig | |||
@@ -11,6 +11,7 @@ config TILE | |||
11 | select GENERIC_IRQ_PROBE | 11 | select GENERIC_IRQ_PROBE |
12 | select GENERIC_PENDING_IRQ if SMP | 12 | select GENERIC_PENDING_IRQ if SMP |
13 | select GENERIC_IRQ_SHOW | 13 | select GENERIC_IRQ_SHOW |
14 | select SYS_HYPERVISOR | ||
14 | 15 | ||
15 | # FIXME: investigate whether we need/want these options. | 16 | # FIXME: investigate whether we need/want these options. |
16 | # select HAVE_IOREMAP_PROT | 17 | # select HAVE_IOREMAP_PROT |
diff --git a/arch/tile/include/asm/hardwall.h b/arch/tile/include/asm/hardwall.h index 0bed3ec7b42c..2ac422848c7d 100644 --- a/arch/tile/include/asm/hardwall.h +++ b/arch/tile/include/asm/hardwall.h | |||
@@ -40,6 +40,10 @@ | |||
40 | #define HARDWALL_DEACTIVATE \ | 40 | #define HARDWALL_DEACTIVATE \ |
41 | _IO(HARDWALL_IOCTL_BASE, _HARDWALL_DEACTIVATE) | 41 | _IO(HARDWALL_IOCTL_BASE, _HARDWALL_DEACTIVATE) |
42 | 42 | ||
43 | #define _HARDWALL_GET_ID 4 | ||
44 | #define HARDWALL_GET_ID \ | ||
45 | _IO(HARDWALL_IOCTL_BASE, _HARDWALL_GET_ID) | ||
46 | |||
43 | #ifndef __KERNEL__ | 47 | #ifndef __KERNEL__ |
44 | 48 | ||
45 | /* This is the canonical name expected by userspace. */ | 49 | /* This is the canonical name expected by userspace. */ |
@@ -47,9 +51,14 @@ | |||
47 | 51 | ||
48 | #else | 52 | #else |
49 | 53 | ||
50 | /* Hook for /proc/tile/hardwall. */ | 54 | /* /proc hooks for hardwall. */ |
51 | struct seq_file; | 55 | struct proc_dir_entry; |
52 | int proc_tile_hardwall_show(struct seq_file *sf, void *v); | 56 | #ifdef CONFIG_HARDWALL |
57 | void proc_tile_hardwall_init(struct proc_dir_entry *root); | ||
58 | int proc_pid_hardwall(struct task_struct *task, char *buffer); | ||
59 | #else | ||
60 | static inline void proc_tile_hardwall_init(struct proc_dir_entry *root) {} | ||
61 | #endif | ||
53 | 62 | ||
54 | #endif | 63 | #endif |
55 | 64 | ||
diff --git a/arch/tile/kernel/Makefile b/arch/tile/kernel/Makefile index b4c8e8ec45dc..b4dbc057baad 100644 --- a/arch/tile/kernel/Makefile +++ b/arch/tile/kernel/Makefile | |||
@@ -5,7 +5,7 @@ | |||
5 | extra-y := vmlinux.lds head_$(BITS).o | 5 | extra-y := vmlinux.lds head_$(BITS).o |
6 | obj-y := backtrace.o entry.o init_task.o irq.o messaging.o \ | 6 | obj-y := backtrace.o entry.o init_task.o irq.o messaging.o \ |
7 | pci-dma.o proc.o process.o ptrace.o reboot.o \ | 7 | pci-dma.o proc.o process.o ptrace.o reboot.o \ |
8 | setup.o signal.o single_step.o stack.o sys.o time.o traps.o \ | 8 | setup.o signal.o single_step.o stack.o sys.o sysfs.o time.o traps.o \ |
9 | intvec_$(BITS).o regs_$(BITS).o tile-desc_$(BITS).o | 9 | intvec_$(BITS).o regs_$(BITS).o tile-desc_$(BITS).o |
10 | 10 | ||
11 | obj-$(CONFIG_HARDWALL) += hardwall.o | 11 | obj-$(CONFIG_HARDWALL) += hardwall.o |
diff --git a/arch/tile/kernel/hardwall.c b/arch/tile/kernel/hardwall.c index 3bddef710de4..8c41891aab34 100644 --- a/arch/tile/kernel/hardwall.c +++ b/arch/tile/kernel/hardwall.c | |||
@@ -40,16 +40,25 @@ | |||
40 | struct hardwall_info { | 40 | struct hardwall_info { |
41 | struct list_head list; /* "rectangles" list */ | 41 | struct list_head list; /* "rectangles" list */ |
42 | struct list_head task_head; /* head of tasks in this hardwall */ | 42 | struct list_head task_head; /* head of tasks in this hardwall */ |
43 | struct cpumask cpumask; /* cpus in the rectangle */ | ||
43 | int ulhc_x; /* upper left hand corner x coord */ | 44 | int ulhc_x; /* upper left hand corner x coord */ |
44 | int ulhc_y; /* upper left hand corner y coord */ | 45 | int ulhc_y; /* upper left hand corner y coord */ |
45 | int width; /* rectangle width */ | 46 | int width; /* rectangle width */ |
46 | int height; /* rectangle height */ | 47 | int height; /* rectangle height */ |
48 | int id; /* integer id for this hardwall */ | ||
47 | int teardown_in_progress; /* are we tearing this one down? */ | 49 | int teardown_in_progress; /* are we tearing this one down? */ |
48 | }; | 50 | }; |
49 | 51 | ||
50 | /* Currently allocated hardwall rectangles */ | 52 | /* Currently allocated hardwall rectangles */ |
51 | static LIST_HEAD(rectangles); | 53 | static LIST_HEAD(rectangles); |
52 | 54 | ||
55 | /* /proc/tile/hardwall */ | ||
56 | static struct proc_dir_entry *hardwall_proc_dir; | ||
57 | |||
58 | /* Functions to manage files in /proc/tile/hardwall. */ | ||
59 | static void hardwall_add_proc(struct hardwall_info *rect); | ||
60 | static void hardwall_remove_proc(struct hardwall_info *rect); | ||
61 | |||
53 | /* | 62 | /* |
54 | * Guard changes to the hardwall data structures. | 63 | * Guard changes to the hardwall data structures. |
55 | * This could be finer grained (e.g. one lock for the list of hardwall | 64 | * This could be finer grained (e.g. one lock for the list of hardwall |
@@ -105,6 +114,8 @@ static int setup_rectangle(struct hardwall_info *r, struct cpumask *mask) | |||
105 | r->ulhc_y = cpu_y(ulhc); | 114 | r->ulhc_y = cpu_y(ulhc); |
106 | r->width = cpu_x(lrhc) - r->ulhc_x + 1; | 115 | r->width = cpu_x(lrhc) - r->ulhc_x + 1; |
107 | r->height = cpu_y(lrhc) - r->ulhc_y + 1; | 116 | r->height = cpu_y(lrhc) - r->ulhc_y + 1; |
117 | cpumask_copy(&r->cpumask, mask); | ||
118 | r->id = ulhc; /* The ulhc cpu id can be the hardwall id. */ | ||
108 | 119 | ||
109 | /* Width and height must be positive */ | 120 | /* Width and height must be positive */ |
110 | if (r->width <= 0 || r->height <= 0) | 121 | if (r->width <= 0 || r->height <= 0) |
@@ -388,6 +399,9 @@ static struct hardwall_info *hardwall_create( | |||
388 | /* Set up appropriate hardwalling on all affected cpus. */ | 399 | /* Set up appropriate hardwalling on all affected cpus. */ |
389 | hardwall_setup(rect); | 400 | hardwall_setup(rect); |
390 | 401 | ||
402 | /* Create a /proc/tile/hardwall entry. */ | ||
403 | hardwall_add_proc(rect); | ||
404 | |||
391 | return rect; | 405 | return rect; |
392 | } | 406 | } |
393 | 407 | ||
@@ -645,6 +659,9 @@ static void hardwall_destroy(struct hardwall_info *rect) | |||
645 | /* Restart switch and disable firewall. */ | 659 | /* Restart switch and disable firewall. */ |
646 | on_each_cpu_mask(&mask, restart_udn_switch, NULL, 1); | 660 | on_each_cpu_mask(&mask, restart_udn_switch, NULL, 1); |
647 | 661 | ||
662 | /* Remove the /proc/tile/hardwall entry. */ | ||
663 | hardwall_remove_proc(rect); | ||
664 | |||
648 | /* Now free the rectangle from the list. */ | 665 | /* Now free the rectangle from the list. */ |
649 | spin_lock_irqsave(&hardwall_lock, flags); | 666 | spin_lock_irqsave(&hardwall_lock, flags); |
650 | BUG_ON(!list_empty(&rect->task_head)); | 667 | BUG_ON(!list_empty(&rect->task_head)); |
@@ -654,35 +671,57 @@ static void hardwall_destroy(struct hardwall_info *rect) | |||
654 | } | 671 | } |
655 | 672 | ||
656 | 673 | ||
657 | /* | 674 | static int hardwall_proc_show(struct seq_file *sf, void *v) |
658 | * Dump hardwall state via /proc; initialized in arch/tile/sys/proc.c. | ||
659 | */ | ||
660 | int proc_tile_hardwall_show(struct seq_file *sf, void *v) | ||
661 | { | 675 | { |
662 | struct hardwall_info *r; | 676 | struct hardwall_info *rect = sf->private; |
677 | char buf[256]; | ||
663 | 678 | ||
664 | if (udn_disabled) { | 679 | int rc = cpulist_scnprintf(buf, sizeof(buf), &rect->cpumask); |
665 | seq_printf(sf, "%dx%d 0,0 pids:\n", smp_width, smp_height); | 680 | buf[rc++] = '\n'; |
666 | return 0; | 681 | seq_write(sf, buf, rc); |
667 | } | ||
668 | |||
669 | spin_lock_irq(&hardwall_lock); | ||
670 | list_for_each_entry(r, &rectangles, list) { | ||
671 | struct task_struct *p; | ||
672 | seq_printf(sf, "%dx%d %d,%d pids:", | ||
673 | r->width, r->height, r->ulhc_x, r->ulhc_y); | ||
674 | list_for_each_entry(p, &r->task_head, thread.hardwall_list) { | ||
675 | unsigned int cpu = cpumask_first(&p->cpus_allowed); | ||
676 | unsigned int x = cpu % smp_width; | ||
677 | unsigned int y = cpu / smp_width; | ||
678 | seq_printf(sf, " %d@%d,%d", p->pid, x, y); | ||
679 | } | ||
680 | seq_printf(sf, "\n"); | ||
681 | } | ||
682 | spin_unlock_irq(&hardwall_lock); | ||
683 | return 0; | 682 | return 0; |
684 | } | 683 | } |
685 | 684 | ||
685 | static int hardwall_proc_open(struct inode *inode, | ||
686 | struct file *file) | ||
687 | { | ||
688 | return single_open(file, hardwall_proc_show, PDE(inode)->data); | ||
689 | } | ||
690 | |||
691 | static const struct file_operations hardwall_proc_fops = { | ||
692 | .open = hardwall_proc_open, | ||
693 | .read = seq_read, | ||
694 | .llseek = seq_lseek, | ||
695 | .release = single_release, | ||
696 | }; | ||
697 | |||
698 | static void hardwall_add_proc(struct hardwall_info *rect) | ||
699 | { | ||
700 | char buf[64]; | ||
701 | snprintf(buf, sizeof(buf), "%d", rect->id); | ||
702 | proc_create_data(buf, 0444, hardwall_proc_dir, | ||
703 | &hardwall_proc_fops, rect); | ||
704 | } | ||
705 | |||
706 | static void hardwall_remove_proc(struct hardwall_info *rect) | ||
707 | { | ||
708 | char buf[64]; | ||
709 | snprintf(buf, sizeof(buf), "%d", rect->id); | ||
710 | remove_proc_entry(buf, hardwall_proc_dir); | ||
711 | } | ||
712 | |||
713 | int proc_pid_hardwall(struct task_struct *task, char *buffer) | ||
714 | { | ||
715 | struct hardwall_info *rect = task->thread.hardwall; | ||
716 | return rect ? sprintf(buffer, "%d\n", rect->id) : 0; | ||
717 | } | ||
718 | |||
719 | void proc_tile_hardwall_init(struct proc_dir_entry *root) | ||
720 | { | ||
721 | if (!udn_disabled) | ||
722 | hardwall_proc_dir = proc_mkdir("hardwall", root); | ||
723 | } | ||
724 | |||
686 | 725 | ||
687 | /* | 726 | /* |
688 | * Character device support via ioctl/close. | 727 | * Character device support via ioctl/close. |
@@ -716,6 +755,9 @@ static long hardwall_ioctl(struct file *file, unsigned int a, unsigned long b) | |||
716 | return -EINVAL; | 755 | return -EINVAL; |
717 | return hardwall_deactivate(current); | 756 | return hardwall_deactivate(current); |
718 | 757 | ||
758 | case _HARDWALL_GET_ID: | ||
759 | return rect ? rect->id : -EINVAL; | ||
760 | |||
719 | default: | 761 | default: |
720 | return -EINVAL; | 762 | return -EINVAL; |
721 | } | 763 | } |
diff --git a/arch/tile/kernel/proc.c b/arch/tile/kernel/proc.c index 2e02c41ddf3b..62d820833c68 100644 --- a/arch/tile/kernel/proc.c +++ b/arch/tile/kernel/proc.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <asm/processor.h> | 27 | #include <asm/processor.h> |
28 | #include <asm/sections.h> | 28 | #include <asm/sections.h> |
29 | #include <asm/homecache.h> | 29 | #include <asm/homecache.h> |
30 | #include <asm/hardwall.h> | ||
30 | #include <arch/chip.h> | 31 | #include <arch/chip.h> |
31 | 32 | ||
32 | 33 | ||
@@ -88,3 +89,75 @@ const struct seq_operations cpuinfo_op = { | |||
88 | .stop = c_stop, | 89 | .stop = c_stop, |
89 | .show = show_cpuinfo, | 90 | .show = show_cpuinfo, |
90 | }; | 91 | }; |
92 | |||
93 | /* | ||
94 | * Support /proc/tile directory | ||
95 | */ | ||
96 | |||
97 | static int __init proc_tile_init(void) | ||
98 | { | ||
99 | struct proc_dir_entry *root = proc_mkdir("tile", NULL); | ||
100 | if (root == NULL) | ||
101 | return 0; | ||
102 | |||
103 | proc_tile_hardwall_init(root); | ||
104 | |||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | arch_initcall(proc_tile_init); | ||
109 | |||
110 | /* | ||
111 | * Support /proc/sys/tile directory | ||
112 | */ | ||
113 | |||
114 | #ifndef __tilegx__ /* FIXME: GX: no support for unaligned access yet */ | ||
115 | static ctl_table unaligned_subtable[] = { | ||
116 | { | ||
117 | .procname = "enabled", | ||
118 | .data = &unaligned_fixup, | ||
119 | .maxlen = sizeof(int), | ||
120 | .mode = 0644, | ||
121 | .proc_handler = &proc_dointvec | ||
122 | }, | ||
123 | { | ||
124 | .procname = "printk", | ||
125 | .data = &unaligned_printk, | ||
126 | .maxlen = sizeof(int), | ||
127 | .mode = 0644, | ||
128 | .proc_handler = &proc_dointvec | ||
129 | }, | ||
130 | { | ||
131 | .procname = "count", | ||
132 | .data = &unaligned_fixup_count, | ||
133 | .maxlen = sizeof(int), | ||
134 | .mode = 0644, | ||
135 | .proc_handler = &proc_dointvec | ||
136 | }, | ||
137 | {} | ||
138 | }; | ||
139 | |||
140 | static ctl_table unaligned_table[] = { | ||
141 | { | ||
142 | .procname = "unaligned_fixup", | ||
143 | .mode = 0555, | ||
144 | .child = unaligned_subtable | ||
145 | }, | ||
146 | {} | ||
147 | }; | ||
148 | #endif | ||
149 | |||
150 | static struct ctl_path tile_path[] = { | ||
151 | { .procname = "tile" }, | ||
152 | { } | ||
153 | }; | ||
154 | |||
155 | static int __init proc_sys_tile_init(void) | ||
156 | { | ||
157 | #ifndef __tilegx__ /* FIXME: GX: no support for unaligned access yet */ | ||
158 | register_sysctl_paths(tile_path, unaligned_table); | ||
159 | #endif | ||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | arch_initcall(proc_sys_tile_init); | ||
diff --git a/arch/tile/kernel/sysfs.c b/arch/tile/kernel/sysfs.c new file mode 100644 index 000000000000..b671a86f4515 --- /dev/null +++ b/arch/tile/kernel/sysfs.c | |||
@@ -0,0 +1,185 @@ | |||
1 | /* | ||
2 | * Copyright 2011 Tilera Corporation. All Rights Reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation, version 2. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, but | ||
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
11 | * NON INFRINGEMENT. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * /sys entry support. | ||
15 | */ | ||
16 | |||
17 | #include <linux/sysdev.h> | ||
18 | #include <linux/cpu.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/smp.h> | ||
21 | #include <hv/hypervisor.h> | ||
22 | |||
23 | /* Return a string queried from the hypervisor, truncated to page size. */ | ||
24 | static ssize_t get_hv_confstr(char *page, int query) | ||
25 | { | ||
26 | ssize_t n = hv_confstr(query, (unsigned long)page, PAGE_SIZE - 1); | ||
27 | n = n < 0 ? 0 : min(n, (ssize_t)PAGE_SIZE - 1) - 1; | ||
28 | if (n) | ||
29 | page[n++] = '\n'; | ||
30 | page[n] = '\0'; | ||
31 | return n; | ||
32 | } | ||
33 | |||
34 | static ssize_t chip_width_show(struct sysdev_class *dev, | ||
35 | struct sysdev_class_attribute *attr, | ||
36 | char *page) | ||
37 | { | ||
38 | return sprintf(page, "%u\n", smp_width); | ||
39 | } | ||
40 | static SYSDEV_CLASS_ATTR(chip_width, 0444, chip_width_show, NULL); | ||
41 | |||
42 | static ssize_t chip_height_show(struct sysdev_class *dev, | ||
43 | struct sysdev_class_attribute *attr, | ||
44 | char *page) | ||
45 | { | ||
46 | return sprintf(page, "%u\n", smp_height); | ||
47 | } | ||
48 | static SYSDEV_CLASS_ATTR(chip_height, 0444, chip_height_show, NULL); | ||
49 | |||
50 | static ssize_t chip_serial_show(struct sysdev_class *dev, | ||
51 | struct sysdev_class_attribute *attr, | ||
52 | char *page) | ||
53 | { | ||
54 | return get_hv_confstr(page, HV_CONFSTR_CHIP_SERIAL_NUM); | ||
55 | } | ||
56 | static SYSDEV_CLASS_ATTR(chip_serial, 0444, chip_serial_show, NULL); | ||
57 | |||
58 | static ssize_t chip_revision_show(struct sysdev_class *dev, | ||
59 | struct sysdev_class_attribute *attr, | ||
60 | char *page) | ||
61 | { | ||
62 | return get_hv_confstr(page, HV_CONFSTR_CHIP_REV); | ||
63 | } | ||
64 | static SYSDEV_CLASS_ATTR(chip_revision, 0444, chip_revision_show, NULL); | ||
65 | |||
66 | |||
67 | static ssize_t type_show(struct sysdev_class *dev, | ||
68 | struct sysdev_class_attribute *attr, | ||
69 | char *page) | ||
70 | { | ||
71 | return sprintf(page, "tilera\n"); | ||
72 | } | ||
73 | static SYSDEV_CLASS_ATTR(type, 0444, type_show, NULL); | ||
74 | |||
75 | #define HV_CONF_ATTR(name, conf) \ | ||
76 | static ssize_t name ## _show(struct sysdev_class *dev, \ | ||
77 | struct sysdev_class_attribute *attr, \ | ||
78 | char *page) \ | ||
79 | { \ | ||
80 | return get_hv_confstr(page, conf); \ | ||
81 | } \ | ||
82 | static SYSDEV_CLASS_ATTR(name, 0444, name ## _show, NULL); | ||
83 | |||
84 | HV_CONF_ATTR(version, HV_CONFSTR_HV_SW_VER) | ||
85 | HV_CONF_ATTR(config_version, HV_CONFSTR_HV_CONFIG_VER) | ||
86 | |||
87 | HV_CONF_ATTR(board_part, HV_CONFSTR_BOARD_PART_NUM) | ||
88 | HV_CONF_ATTR(board_serial, HV_CONFSTR_BOARD_SERIAL_NUM) | ||
89 | HV_CONF_ATTR(board_revision, HV_CONFSTR_BOARD_REV) | ||
90 | HV_CONF_ATTR(board_description, HV_CONFSTR_BOARD_DESC) | ||
91 | HV_CONF_ATTR(mezz_part, HV_CONFSTR_MEZZ_PART_NUM) | ||
92 | HV_CONF_ATTR(mezz_serial, HV_CONFSTR_MEZZ_SERIAL_NUM) | ||
93 | HV_CONF_ATTR(mezz_revision, HV_CONFSTR_MEZZ_REV) | ||
94 | HV_CONF_ATTR(mezz_description, HV_CONFSTR_MEZZ_DESC) | ||
95 | HV_CONF_ATTR(switch_control, HV_CONFSTR_SWITCH_CONTROL) | ||
96 | |||
97 | static struct attribute *board_attrs[] = { | ||
98 | &attr_board_part.attr, | ||
99 | &attr_board_serial.attr, | ||
100 | &attr_board_revision.attr, | ||
101 | &attr_board_description.attr, | ||
102 | &attr_mezz_part.attr, | ||
103 | &attr_mezz_serial.attr, | ||
104 | &attr_mezz_revision.attr, | ||
105 | &attr_mezz_description.attr, | ||
106 | &attr_switch_control.attr, | ||
107 | NULL | ||
108 | }; | ||
109 | |||
110 | static struct attribute_group board_attr_group = { | ||
111 | .name = "board", | ||
112 | .attrs = board_attrs, | ||
113 | }; | ||
114 | |||
115 | |||
116 | static struct bin_attribute hvconfig_bin; | ||
117 | |||
118 | static ssize_t | ||
119 | hvconfig_bin_read(struct file *filp, struct kobject *kobj, | ||
120 | struct bin_attribute *bin_attr, | ||
121 | char *buf, loff_t off, size_t count) | ||
122 | { | ||
123 | static size_t size; | ||
124 | |||
125 | /* Lazily learn the true size (minus the trailing NUL). */ | ||
126 | if (size == 0) | ||
127 | size = hv_confstr(HV_CONFSTR_HV_CONFIG, 0, 0) - 1; | ||
128 | |||
129 | /* Check and adjust input parameters. */ | ||
130 | if (off > size) | ||
131 | return -EINVAL; | ||
132 | if (count > size - off) | ||
133 | count = size - off; | ||
134 | |||
135 | if (count) { | ||
136 | /* Get a copy of the hvc and copy out the relevant portion. */ | ||
137 | char *hvc; | ||
138 | |||
139 | size = off + count; | ||
140 | hvc = kmalloc(size, GFP_KERNEL); | ||
141 | if (hvc == NULL) | ||
142 | return -ENOMEM; | ||
143 | hv_confstr(HV_CONFSTR_HV_CONFIG, (unsigned long)hvc, size); | ||
144 | memcpy(buf, hvc + off, count); | ||
145 | kfree(hvc); | ||
146 | } | ||
147 | |||
148 | return count; | ||
149 | } | ||
150 | |||
151 | static int __init create_sysfs_entries(void) | ||
152 | { | ||
153 | struct sysdev_class *cls = &cpu_sysdev_class; | ||
154 | int err = 0; | ||
155 | |||
156 | #define create_cpu_attr(name) \ | ||
157 | if (!err) \ | ||
158 | err = sysfs_create_file(&cls->kset.kobj, &attr_##name.attr); | ||
159 | create_cpu_attr(chip_width); | ||
160 | create_cpu_attr(chip_height); | ||
161 | create_cpu_attr(chip_serial); | ||
162 | create_cpu_attr(chip_revision); | ||
163 | |||
164 | #define create_hv_attr(name) \ | ||
165 | if (!err) \ | ||
166 | err = sysfs_create_file(hypervisor_kobj, &attr_##name.attr); | ||
167 | create_hv_attr(type); | ||
168 | create_hv_attr(version); | ||
169 | create_hv_attr(config_version); | ||
170 | |||
171 | if (!err) | ||
172 | err = sysfs_create_group(hypervisor_kobj, &board_attr_group); | ||
173 | |||
174 | if (!err) { | ||
175 | sysfs_bin_attr_init(&hvconfig_bin); | ||
176 | hvconfig_bin.attr.name = "hvconfig"; | ||
177 | hvconfig_bin.attr.mode = S_IRUGO; | ||
178 | hvconfig_bin.read = hvconfig_bin_read; | ||
179 | hvconfig_bin.size = PAGE_SIZE; | ||
180 | err = sysfs_create_bin_file(hypervisor_kobj, &hvconfig_bin); | ||
181 | } | ||
182 | |||
183 | return err; | ||
184 | } | ||
185 | subsys_initcall(create_sysfs_entries); | ||
diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index 416d865eae39..610001d385dd 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h | |||
@@ -139,7 +139,7 @@ static inline unsigned int acpi_processor_cstate_check(unsigned int max_cstate) | |||
139 | boot_cpu_data.x86_model <= 0x05 && | 139 | boot_cpu_data.x86_model <= 0x05 && |
140 | boot_cpu_data.x86_mask < 0x0A) | 140 | boot_cpu_data.x86_mask < 0x0A) |
141 | return 1; | 141 | return 1; |
142 | else if (c1e_detected) | 142 | else if (amd_e400_c1e_detected) |
143 | return 1; | 143 | return 1; |
144 | else | 144 | else |
145 | return max_cstate; | 145 | return max_cstate; |
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index 5dc6acc98dbd..71cc3800712c 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h | |||
@@ -125,7 +125,7 @@ | |||
125 | #define X86_FEATURE_OSXSAVE (4*32+27) /* "" XSAVE enabled in the OS */ | 125 | #define X86_FEATURE_OSXSAVE (4*32+27) /* "" XSAVE enabled in the OS */ |
126 | #define X86_FEATURE_AVX (4*32+28) /* Advanced Vector Extensions */ | 126 | #define X86_FEATURE_AVX (4*32+28) /* Advanced Vector Extensions */ |
127 | #define X86_FEATURE_F16C (4*32+29) /* 16-bit fp conversions */ | 127 | #define X86_FEATURE_F16C (4*32+29) /* 16-bit fp conversions */ |
128 | #define X86_FEATURE_RDRND (4*32+30) /* The RDRAND instruction */ | 128 | #define X86_FEATURE_RDRAND (4*32+30) /* The RDRAND instruction */ |
129 | #define X86_FEATURE_HYPERVISOR (4*32+31) /* Running on a hypervisor */ | 129 | #define X86_FEATURE_HYPERVISOR (4*32+31) /* Running on a hypervisor */ |
130 | 130 | ||
131 | /* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */ | 131 | /* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */ |
diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h index 617bd56b3070..7b439d9aea2a 100644 --- a/arch/x86/include/asm/desc.h +++ b/arch/x86/include/asm/desc.h | |||
@@ -4,30 +4,33 @@ | |||
4 | #include <asm/desc_defs.h> | 4 | #include <asm/desc_defs.h> |
5 | #include <asm/ldt.h> | 5 | #include <asm/ldt.h> |
6 | #include <asm/mmu.h> | 6 | #include <asm/mmu.h> |
7 | |||
7 | #include <linux/smp.h> | 8 | #include <linux/smp.h> |
8 | 9 | ||
9 | static inline void fill_ldt(struct desc_struct *desc, | 10 | static inline void fill_ldt(struct desc_struct *desc, const struct user_desc *info) |
10 | const struct user_desc *info) | 11 | { |
11 | { | 12 | desc->limit0 = info->limit & 0x0ffff; |
12 | desc->limit0 = info->limit & 0x0ffff; | 13 | |
13 | desc->base0 = info->base_addr & 0x0000ffff; | 14 | desc->base0 = (info->base_addr & 0x0000ffff); |
14 | 15 | desc->base1 = (info->base_addr & 0x00ff0000) >> 16; | |
15 | desc->base1 = (info->base_addr & 0x00ff0000) >> 16; | 16 | |
16 | desc->type = (info->read_exec_only ^ 1) << 1; | 17 | desc->type = (info->read_exec_only ^ 1) << 1; |
17 | desc->type |= info->contents << 2; | 18 | desc->type |= info->contents << 2; |
18 | desc->s = 1; | 19 | |
19 | desc->dpl = 0x3; | 20 | desc->s = 1; |
20 | desc->p = info->seg_not_present ^ 1; | 21 | desc->dpl = 0x3; |
21 | desc->limit = (info->limit & 0xf0000) >> 16; | 22 | desc->p = info->seg_not_present ^ 1; |
22 | desc->avl = info->useable; | 23 | desc->limit = (info->limit & 0xf0000) >> 16; |
23 | desc->d = info->seg_32bit; | 24 | desc->avl = info->useable; |
24 | desc->g = info->limit_in_pages; | 25 | desc->d = info->seg_32bit; |
25 | desc->base2 = (info->base_addr & 0xff000000) >> 24; | 26 | desc->g = info->limit_in_pages; |
27 | |||
28 | desc->base2 = (info->base_addr & 0xff000000) >> 24; | ||
26 | /* | 29 | /* |
27 | * Don't allow setting of the lm bit. It is useless anyway | 30 | * Don't allow setting of the lm bit. It is useless anyway |
28 | * because 64bit system calls require __USER_CS: | 31 | * because 64bit system calls require __USER_CS: |
29 | */ | 32 | */ |
30 | desc->l = 0; | 33 | desc->l = 0; |
31 | } | 34 | } |
32 | 35 | ||
33 | extern struct desc_ptr idt_descr; | 36 | extern struct desc_ptr idt_descr; |
@@ -36,6 +39,7 @@ extern gate_desc idt_table[]; | |||
36 | struct gdt_page { | 39 | struct gdt_page { |
37 | struct desc_struct gdt[GDT_ENTRIES]; | 40 | struct desc_struct gdt[GDT_ENTRIES]; |
38 | } __attribute__((aligned(PAGE_SIZE))); | 41 | } __attribute__((aligned(PAGE_SIZE))); |
42 | |||
39 | DECLARE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page); | 43 | DECLARE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page); |
40 | 44 | ||
41 | static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) | 45 | static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) |
@@ -48,16 +52,16 @@ static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) | |||
48 | static inline void pack_gate(gate_desc *gate, unsigned type, unsigned long func, | 52 | static inline void pack_gate(gate_desc *gate, unsigned type, unsigned long func, |
49 | unsigned dpl, unsigned ist, unsigned seg) | 53 | unsigned dpl, unsigned ist, unsigned seg) |
50 | { | 54 | { |
51 | gate->offset_low = PTR_LOW(func); | 55 | gate->offset_low = PTR_LOW(func); |
52 | gate->segment = __KERNEL_CS; | 56 | gate->segment = __KERNEL_CS; |
53 | gate->ist = ist; | 57 | gate->ist = ist; |
54 | gate->p = 1; | 58 | gate->p = 1; |
55 | gate->dpl = dpl; | 59 | gate->dpl = dpl; |
56 | gate->zero0 = 0; | 60 | gate->zero0 = 0; |
57 | gate->zero1 = 0; | 61 | gate->zero1 = 0; |
58 | gate->type = type; | 62 | gate->type = type; |
59 | gate->offset_middle = PTR_MIDDLE(func); | 63 | gate->offset_middle = PTR_MIDDLE(func); |
60 | gate->offset_high = PTR_HIGH(func); | 64 | gate->offset_high = PTR_HIGH(func); |
61 | } | 65 | } |
62 | 66 | ||
63 | #else | 67 | #else |
@@ -66,8 +70,7 @@ static inline void pack_gate(gate_desc *gate, unsigned char type, | |||
66 | unsigned short seg) | 70 | unsigned short seg) |
67 | { | 71 | { |
68 | gate->a = (seg << 16) | (base & 0xffff); | 72 | gate->a = (seg << 16) | (base & 0xffff); |
69 | gate->b = (base & 0xffff0000) | | 73 | gate->b = (base & 0xffff0000) | (((0x80 | type | (dpl << 5)) & 0xff) << 8); |
70 | (((0x80 | type | (dpl << 5)) & 0xff) << 8); | ||
71 | } | 74 | } |
72 | 75 | ||
73 | #endif | 76 | #endif |
@@ -75,31 +78,29 @@ static inline void pack_gate(gate_desc *gate, unsigned char type, | |||
75 | static inline int desc_empty(const void *ptr) | 78 | static inline int desc_empty(const void *ptr) |
76 | { | 79 | { |
77 | const u32 *desc = ptr; | 80 | const u32 *desc = ptr; |
81 | |||
78 | return !(desc[0] | desc[1]); | 82 | return !(desc[0] | desc[1]); |
79 | } | 83 | } |
80 | 84 | ||
81 | #ifdef CONFIG_PARAVIRT | 85 | #ifdef CONFIG_PARAVIRT |
82 | #include <asm/paravirt.h> | 86 | #include <asm/paravirt.h> |
83 | #else | 87 | #else |
84 | #define load_TR_desc() native_load_tr_desc() | 88 | #define load_TR_desc() native_load_tr_desc() |
85 | #define load_gdt(dtr) native_load_gdt(dtr) | 89 | #define load_gdt(dtr) native_load_gdt(dtr) |
86 | #define load_idt(dtr) native_load_idt(dtr) | 90 | #define load_idt(dtr) native_load_idt(dtr) |
87 | #define load_tr(tr) asm volatile("ltr %0"::"m" (tr)) | 91 | #define load_tr(tr) asm volatile("ltr %0"::"m" (tr)) |
88 | #define load_ldt(ldt) asm volatile("lldt %0"::"m" (ldt)) | 92 | #define load_ldt(ldt) asm volatile("lldt %0"::"m" (ldt)) |
89 | 93 | ||
90 | #define store_gdt(dtr) native_store_gdt(dtr) | 94 | #define store_gdt(dtr) native_store_gdt(dtr) |
91 | #define store_idt(dtr) native_store_idt(dtr) | 95 | #define store_idt(dtr) native_store_idt(dtr) |
92 | #define store_tr(tr) (tr = native_store_tr()) | 96 | #define store_tr(tr) (tr = native_store_tr()) |
93 | 97 | ||
94 | #define load_TLS(t, cpu) native_load_tls(t, cpu) | 98 | #define load_TLS(t, cpu) native_load_tls(t, cpu) |
95 | #define set_ldt native_set_ldt | 99 | #define set_ldt native_set_ldt |
96 | 100 | ||
97 | #define write_ldt_entry(dt, entry, desc) \ | 101 | #define write_ldt_entry(dt, entry, desc) native_write_ldt_entry(dt, entry, desc) |
98 | native_write_ldt_entry(dt, entry, desc) | 102 | #define write_gdt_entry(dt, entry, desc, type) native_write_gdt_entry(dt, entry, desc, type) |
99 | #define write_gdt_entry(dt, entry, desc, type) \ | 103 | #define write_idt_entry(dt, entry, g) native_write_idt_entry(dt, entry, g) |
100 | native_write_gdt_entry(dt, entry, desc, type) | ||
101 | #define write_idt_entry(dt, entry, g) \ | ||
102 | native_write_idt_entry(dt, entry, g) | ||
103 | 104 | ||
104 | static inline void paravirt_alloc_ldt(struct desc_struct *ldt, unsigned entries) | 105 | static inline void paravirt_alloc_ldt(struct desc_struct *ldt, unsigned entries) |
105 | { | 106 | { |
@@ -112,33 +113,27 @@ static inline void paravirt_free_ldt(struct desc_struct *ldt, unsigned entries) | |||
112 | 113 | ||
113 | #define store_ldt(ldt) asm("sldt %0" : "=m"(ldt)) | 114 | #define store_ldt(ldt) asm("sldt %0" : "=m"(ldt)) |
114 | 115 | ||
115 | static inline void native_write_idt_entry(gate_desc *idt, int entry, | 116 | static inline void native_write_idt_entry(gate_desc *idt, int entry, const gate_desc *gate) |
116 | const gate_desc *gate) | ||
117 | { | 117 | { |
118 | memcpy(&idt[entry], gate, sizeof(*gate)); | 118 | memcpy(&idt[entry], gate, sizeof(*gate)); |
119 | } | 119 | } |
120 | 120 | ||
121 | static inline void native_write_ldt_entry(struct desc_struct *ldt, int entry, | 121 | static inline void native_write_ldt_entry(struct desc_struct *ldt, int entry, const void *desc) |
122 | const void *desc) | ||
123 | { | 122 | { |
124 | memcpy(&ldt[entry], desc, 8); | 123 | memcpy(&ldt[entry], desc, 8); |
125 | } | 124 | } |
126 | 125 | ||
127 | static inline void native_write_gdt_entry(struct desc_struct *gdt, int entry, | 126 | static inline void |
128 | const void *desc, int type) | 127 | native_write_gdt_entry(struct desc_struct *gdt, int entry, const void *desc, int type) |
129 | { | 128 | { |
130 | unsigned int size; | 129 | unsigned int size; |
130 | |||
131 | switch (type) { | 131 | switch (type) { |
132 | case DESC_TSS: | 132 | case DESC_TSS: size = sizeof(tss_desc); break; |
133 | size = sizeof(tss_desc); | 133 | case DESC_LDT: size = sizeof(ldt_desc); break; |
134 | break; | 134 | default: size = sizeof(*gdt); break; |
135 | case DESC_LDT: | ||
136 | size = sizeof(ldt_desc); | ||
137 | break; | ||
138 | default: | ||
139 | size = sizeof(struct desc_struct); | ||
140 | break; | ||
141 | } | 135 | } |
136 | |||
142 | memcpy(&gdt[entry], desc, size); | 137 | memcpy(&gdt[entry], desc, size); |
143 | } | 138 | } |
144 | 139 | ||
@@ -154,20 +149,21 @@ static inline void pack_descriptor(struct desc_struct *desc, unsigned long base, | |||
154 | } | 149 | } |
155 | 150 | ||
156 | 151 | ||
157 | static inline void set_tssldt_descriptor(void *d, unsigned long addr, | 152 | static inline void set_tssldt_descriptor(void *d, unsigned long addr, unsigned type, unsigned size) |
158 | unsigned type, unsigned size) | ||
159 | { | 153 | { |
160 | #ifdef CONFIG_X86_64 | 154 | #ifdef CONFIG_X86_64 |
161 | struct ldttss_desc64 *desc = d; | 155 | struct ldttss_desc64 *desc = d; |
156 | |||
162 | memset(desc, 0, sizeof(*desc)); | 157 | memset(desc, 0, sizeof(*desc)); |
163 | desc->limit0 = size & 0xFFFF; | 158 | |
164 | desc->base0 = PTR_LOW(addr); | 159 | desc->limit0 = size & 0xFFFF; |
165 | desc->base1 = PTR_MIDDLE(addr) & 0xFF; | 160 | desc->base0 = PTR_LOW(addr); |
166 | desc->type = type; | 161 | desc->base1 = PTR_MIDDLE(addr) & 0xFF; |
167 | desc->p = 1; | 162 | desc->type = type; |
168 | desc->limit1 = (size >> 16) & 0xF; | 163 | desc->p = 1; |
169 | desc->base2 = (PTR_MIDDLE(addr) >> 8) & 0xFF; | 164 | desc->limit1 = (size >> 16) & 0xF; |
170 | desc->base3 = PTR_HIGH(addr); | 165 | desc->base2 = (PTR_MIDDLE(addr) >> 8) & 0xFF; |
166 | desc->base3 = PTR_HIGH(addr); | ||
171 | #else | 167 | #else |
172 | pack_descriptor((struct desc_struct *)d, addr, size, 0x80 | type, 0); | 168 | pack_descriptor((struct desc_struct *)d, addr, size, 0x80 | type, 0); |
173 | #endif | 169 | #endif |
@@ -237,14 +233,16 @@ static inline void native_store_idt(struct desc_ptr *dtr) | |||
237 | static inline unsigned long native_store_tr(void) | 233 | static inline unsigned long native_store_tr(void) |
238 | { | 234 | { |
239 | unsigned long tr; | 235 | unsigned long tr; |
236 | |||
240 | asm volatile("str %0":"=r" (tr)); | 237 | asm volatile("str %0":"=r" (tr)); |
238 | |||
241 | return tr; | 239 | return tr; |
242 | } | 240 | } |
243 | 241 | ||
244 | static inline void native_load_tls(struct thread_struct *t, unsigned int cpu) | 242 | static inline void native_load_tls(struct thread_struct *t, unsigned int cpu) |
245 | { | 243 | { |
246 | unsigned int i; | ||
247 | struct desc_struct *gdt = get_cpu_gdt_table(cpu); | 244 | struct desc_struct *gdt = get_cpu_gdt_table(cpu); |
245 | unsigned int i; | ||
248 | 246 | ||
249 | for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++) | 247 | for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++) |
250 | gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]; | 248 | gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]; |
@@ -313,6 +311,7 @@ static inline void _set_gate(int gate, unsigned type, void *addr, | |||
313 | unsigned dpl, unsigned ist, unsigned seg) | 311 | unsigned dpl, unsigned ist, unsigned seg) |
314 | { | 312 | { |
315 | gate_desc s; | 313 | gate_desc s; |
314 | |||
316 | pack_gate(&s, type, (unsigned long)addr, dpl, ist, seg); | 315 | pack_gate(&s, type, (unsigned long)addr, dpl, ist, seg); |
317 | /* | 316 | /* |
318 | * does not need to be atomic because it is only done once at | 317 | * does not need to be atomic because it is only done once at |
@@ -343,8 +342,9 @@ static inline void alloc_system_vector(int vector) | |||
343 | set_bit(vector, used_vectors); | 342 | set_bit(vector, used_vectors); |
344 | if (first_system_vector > vector) | 343 | if (first_system_vector > vector) |
345 | first_system_vector = vector; | 344 | first_system_vector = vector; |
346 | } else | 345 | } else { |
347 | BUG(); | 346 | BUG(); |
347 | } | ||
348 | } | 348 | } |
349 | 349 | ||
350 | static inline void alloc_intr_gate(unsigned int n, void *addr) | 350 | static inline void alloc_intr_gate(unsigned int n, void *addr) |
diff --git a/arch/x86/include/asm/idle.h b/arch/x86/include/asm/idle.h index 38d87379e270..f49253d75710 100644 --- a/arch/x86/include/asm/idle.h +++ b/arch/x86/include/asm/idle.h | |||
@@ -16,6 +16,6 @@ static inline void enter_idle(void) { } | |||
16 | static inline void exit_idle(void) { } | 16 | static inline void exit_idle(void) { } |
17 | #endif /* CONFIG_X86_64 */ | 17 | #endif /* CONFIG_X86_64 */ |
18 | 18 | ||
19 | void c1e_remove_cpu(int cpu); | 19 | void amd_e400_remove_cpu(int cpu); |
20 | 20 | ||
21 | #endif /* _ASM_X86_IDLE_H */ | 21 | #endif /* _ASM_X86_IDLE_H */ |
diff --git a/arch/x86/include/asm/mmu.h b/arch/x86/include/asm/mmu.h index aeff3e89b222..5f55e6962769 100644 --- a/arch/x86/include/asm/mmu.h +++ b/arch/x86/include/asm/mmu.h | |||
@@ -11,14 +11,14 @@ | |||
11 | typedef struct { | 11 | typedef struct { |
12 | void *ldt; | 12 | void *ldt; |
13 | int size; | 13 | int size; |
14 | struct mutex lock; | ||
15 | void *vdso; | ||
16 | 14 | ||
17 | #ifdef CONFIG_X86_64 | 15 | #ifdef CONFIG_X86_64 |
18 | /* True if mm supports a task running in 32 bit compatibility mode. */ | 16 | /* True if mm supports a task running in 32 bit compatibility mode. */ |
19 | unsigned short ia32_compat; | 17 | unsigned short ia32_compat; |
20 | #endif | 18 | #endif |
21 | 19 | ||
20 | struct mutex lock; | ||
21 | void *vdso; | ||
22 | } mm_context_t; | 22 | } mm_context_t; |
23 | 23 | ||
24 | #ifdef CONFIG_SMP | 24 | #ifdef CONFIG_SMP |
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 4c25ab48257b..219371546afd 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h | |||
@@ -754,10 +754,10 @@ static inline void __sti_mwait(unsigned long eax, unsigned long ecx) | |||
754 | extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx); | 754 | extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx); |
755 | 755 | ||
756 | extern void select_idle_routine(const struct cpuinfo_x86 *c); | 756 | extern void select_idle_routine(const struct cpuinfo_x86 *c); |
757 | extern void init_c1e_mask(void); | 757 | extern void init_amd_e400_c1e_mask(void); |
758 | 758 | ||
759 | extern unsigned long boot_option_idle_override; | 759 | extern unsigned long boot_option_idle_override; |
760 | extern bool c1e_detected; | 760 | extern bool amd_e400_c1e_detected; |
761 | 761 | ||
762 | enum idle_boot_override {IDLE_NO_OVERRIDE=0, IDLE_HALT, IDLE_NOMWAIT, | 762 | enum idle_boot_override {IDLE_NO_OVERRIDE=0, IDLE_HALT, IDLE_NOMWAIT, |
763 | IDLE_POLL, IDLE_FORCE_MWAIT}; | 763 | IDLE_POLL, IDLE_FORCE_MWAIT}; |
diff --git a/arch/x86/include/asm/uv/uv_bau.h b/arch/x86/include/asm/uv/uv_bau.h index 130f1eeee5fe..a291c40efd43 100644 --- a/arch/x86/include/asm/uv/uv_bau.h +++ b/arch/x86/include/asm/uv/uv_bau.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * SGI UV Broadcast Assist Unit definitions | 6 | * SGI UV Broadcast Assist Unit definitions |
7 | * | 7 | * |
8 | * Copyright (C) 2008 Silicon Graphics, Inc. All rights reserved. | 8 | * Copyright (C) 2008-2011 Silicon Graphics, Inc. All rights reserved. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #ifndef _ASM_X86_UV_UV_BAU_H | 11 | #ifndef _ASM_X86_UV_UV_BAU_H |
@@ -35,17 +35,20 @@ | |||
35 | 35 | ||
36 | #define MAX_CPUS_PER_UVHUB 64 | 36 | #define MAX_CPUS_PER_UVHUB 64 |
37 | #define MAX_CPUS_PER_SOCKET 32 | 37 | #define MAX_CPUS_PER_SOCKET 32 |
38 | #define UV_ADP_SIZE 64 /* hardware-provided max. */ | 38 | #define ADP_SZ 64 /* hardware-provided max. */ |
39 | #define UV_CPUS_PER_ACT_STATUS 32 /* hardware-provided max. */ | 39 | #define UV_CPUS_PER_AS 32 /* hardware-provided max. */ |
40 | #define UV_ITEMS_PER_DESCRIPTOR 8 | 40 | #define ITEMS_PER_DESC 8 |
41 | /* the 'throttle' to prevent the hardware stay-busy bug */ | 41 | /* the 'throttle' to prevent the hardware stay-busy bug */ |
42 | #define MAX_BAU_CONCURRENT 3 | 42 | #define MAX_BAU_CONCURRENT 3 |
43 | #define UV_ACT_STATUS_MASK 0x3 | 43 | #define UV_ACT_STATUS_MASK 0x3 |
44 | #define UV_ACT_STATUS_SIZE 2 | 44 | #define UV_ACT_STATUS_SIZE 2 |
45 | #define UV_DISTRIBUTION_SIZE 256 | 45 | #define UV_DISTRIBUTION_SIZE 256 |
46 | #define UV_SW_ACK_NPENDING 8 | 46 | #define UV_SW_ACK_NPENDING 8 |
47 | #define UV_NET_ENDPOINT_INTD 0x38 | 47 | #define UV1_NET_ENDPOINT_INTD 0x38 |
48 | #define UV_DESC_BASE_PNODE_SHIFT 49 | 48 | #define UV2_NET_ENDPOINT_INTD 0x28 |
49 | #define UV_NET_ENDPOINT_INTD (is_uv1_hub() ? \ | ||
50 | UV1_NET_ENDPOINT_INTD : UV2_NET_ENDPOINT_INTD) | ||
51 | #define UV_DESC_PSHIFT 49 | ||
49 | #define UV_PAYLOADQ_PNODE_SHIFT 49 | 52 | #define UV_PAYLOADQ_PNODE_SHIFT 49 |
50 | #define UV_PTC_BASENAME "sgi_uv/ptc_statistics" | 53 | #define UV_PTC_BASENAME "sgi_uv/ptc_statistics" |
51 | #define UV_BAU_BASENAME "sgi_uv/bau_tunables" | 54 | #define UV_BAU_BASENAME "sgi_uv/bau_tunables" |
@@ -53,29 +56,64 @@ | |||
53 | #define UV_BAU_TUNABLES_FILE "bau_tunables" | 56 | #define UV_BAU_TUNABLES_FILE "bau_tunables" |
54 | #define WHITESPACE " \t\n" | 57 | #define WHITESPACE " \t\n" |
55 | #define uv_physnodeaddr(x) ((__pa((unsigned long)(x)) & uv_mmask)) | 58 | #define uv_physnodeaddr(x) ((__pa((unsigned long)(x)) & uv_mmask)) |
56 | #define UV_ENABLE_INTD_SOFT_ACK_MODE_SHIFT 15 | 59 | #define cpubit_isset(cpu, bau_local_cpumask) \ |
57 | #define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHIFT 16 | 60 | test_bit((cpu), (bau_local_cpumask).bits) |
58 | #define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD 0x0000000009UL | 61 | |
59 | /* [19:16] SOFT_ACK timeout period 19: 1 is urgency 7 17:16 1 is multiplier */ | 62 | /* [19:16] SOFT_ACK timeout period 19: 1 is urgency 7 17:16 1 is multiplier */ |
60 | #define BAU_MISC_CONTROL_MULT_MASK 3 | 63 | /* |
64 | * UV2: Bit 19 selects between | ||
65 | * (0): 10 microsecond timebase and | ||
66 | * (1): 80 microseconds | ||
67 | * we're using 655us, similar to UV1: 65 units of 10us | ||
68 | */ | ||
69 | #define UV1_INTD_SOFT_ACK_TIMEOUT_PERIOD (9UL) | ||
70 | #define UV2_INTD_SOFT_ACK_TIMEOUT_PERIOD (65*10UL) | ||
71 | |||
72 | #define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD (is_uv1_hub() ? \ | ||
73 | UV1_INTD_SOFT_ACK_TIMEOUT_PERIOD : \ | ||
74 | UV2_INTD_SOFT_ACK_TIMEOUT_PERIOD) | ||
61 | 75 | ||
62 | #define UVH_AGING_PRESCALE_SEL 0x000000b000UL | 76 | #define BAU_MISC_CONTROL_MULT_MASK 3 |
77 | |||
78 | #define UVH_AGING_PRESCALE_SEL 0x000000b000UL | ||
63 | /* [30:28] URGENCY_7 an index into a table of times */ | 79 | /* [30:28] URGENCY_7 an index into a table of times */ |
64 | #define BAU_URGENCY_7_SHIFT 28 | 80 | #define BAU_URGENCY_7_SHIFT 28 |
65 | #define BAU_URGENCY_7_MASK 7 | 81 | #define BAU_URGENCY_7_MASK 7 |
66 | 82 | ||
67 | #define UVH_TRANSACTION_TIMEOUT 0x000000b200UL | 83 | #define UVH_TRANSACTION_TIMEOUT 0x000000b200UL |
68 | /* [45:40] BAU - BAU transaction timeout select - a multiplier */ | 84 | /* [45:40] BAU - BAU transaction timeout select - a multiplier */ |
69 | #define BAU_TRANS_SHIFT 40 | 85 | #define BAU_TRANS_SHIFT 40 |
70 | #define BAU_TRANS_MASK 0x3f | 86 | #define BAU_TRANS_MASK 0x3f |
87 | |||
88 | /* | ||
89 | * shorten some awkward names | ||
90 | */ | ||
91 | #define AS_PUSH_SHIFT UVH_LB_BAU_SB_ACTIVATION_CONTROL_PUSH_SHFT | ||
92 | #define SOFTACK_MSHIFT UVH_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT | ||
93 | #define SOFTACK_PSHIFT UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT | ||
94 | #define SOFTACK_TIMEOUT_PERIOD UV_INTD_SOFT_ACK_TIMEOUT_PERIOD | ||
95 | #define write_gmmr uv_write_global_mmr64 | ||
96 | #define write_lmmr uv_write_local_mmr | ||
97 | #define read_lmmr uv_read_local_mmr | ||
98 | #define read_gmmr uv_read_global_mmr64 | ||
71 | 99 | ||
72 | /* | 100 | /* |
73 | * bits in UVH_LB_BAU_SB_ACTIVATION_STATUS_0/1 | 101 | * bits in UVH_LB_BAU_SB_ACTIVATION_STATUS_0/1 |
74 | */ | 102 | */ |
75 | #define DESC_STATUS_IDLE 0 | 103 | #define DS_IDLE 0 |
76 | #define DESC_STATUS_ACTIVE 1 | 104 | #define DS_ACTIVE 1 |
77 | #define DESC_STATUS_DESTINATION_TIMEOUT 2 | 105 | #define DS_DESTINATION_TIMEOUT 2 |
78 | #define DESC_STATUS_SOURCE_TIMEOUT 3 | 106 | #define DS_SOURCE_TIMEOUT 3 |
107 | /* | ||
108 | * bits put together from HRP_LB_BAU_SB_ACTIVATION_STATUS_0/1/2 | ||
109 | * values 1 and 5 will not occur | ||
110 | */ | ||
111 | #define UV2H_DESC_IDLE 0 | ||
112 | #define UV2H_DESC_DEST_TIMEOUT 2 | ||
113 | #define UV2H_DESC_DEST_STRONG_NACK 3 | ||
114 | #define UV2H_DESC_BUSY 4 | ||
115 | #define UV2H_DESC_SOURCE_TIMEOUT 6 | ||
116 | #define UV2H_DESC_DEST_PUT_ERR 7 | ||
79 | 117 | ||
80 | /* | 118 | /* |
81 | * delay for 'plugged' timeout retries, in microseconds | 119 | * delay for 'plugged' timeout retries, in microseconds |
@@ -86,15 +124,24 @@ | |||
86 | * threshholds at which to use IPI to free resources | 124 | * threshholds at which to use IPI to free resources |
87 | */ | 125 | */ |
88 | /* after this # consecutive 'plugged' timeouts, use IPI to release resources */ | 126 | /* after this # consecutive 'plugged' timeouts, use IPI to release resources */ |
89 | #define PLUGSB4RESET 100 | 127 | #define PLUGSB4RESET 100 |
90 | /* after this many consecutive timeouts, use IPI to release resources */ | 128 | /* after this many consecutive timeouts, use IPI to release resources */ |
91 | #define TIMEOUTSB4RESET 1 | 129 | #define TIMEOUTSB4RESET 1 |
92 | /* at this number uses of IPI to release resources, giveup the request */ | 130 | /* at this number uses of IPI to release resources, giveup the request */ |
93 | #define IPI_RESET_LIMIT 1 | 131 | #define IPI_RESET_LIMIT 1 |
94 | /* after this # consecutive successes, bump up the throttle if it was lowered */ | 132 | /* after this # consecutive successes, bump up the throttle if it was lowered */ |
95 | #define COMPLETE_THRESHOLD 5 | 133 | #define COMPLETE_THRESHOLD 5 |
134 | |||
135 | #define UV_LB_SUBNODEID 0x10 | ||
96 | 136 | ||
97 | #define UV_LB_SUBNODEID 0x10 | 137 | /* these two are the same for UV1 and UV2: */ |
138 | #define UV_SA_SHFT UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT | ||
139 | #define UV_SA_MASK UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_MASK | ||
140 | /* 4 bits of software ack period */ | ||
141 | #define UV2_ACK_MASK 0x7UL | ||
142 | #define UV2_ACK_UNITS_SHFT 3 | ||
143 | #define UV2_LEG_SHFT UV2H_LB_BAU_MISC_CONTROL_USE_LEGACY_DESCRIPTOR_FORMATS_SHFT | ||
144 | #define UV2_EXT_SHFT UV2H_LB_BAU_MISC_CONTROL_ENABLE_EXTENDED_SB_STATUS_SHFT | ||
98 | 145 | ||
99 | /* | 146 | /* |
100 | * number of entries in the destination side payload queue | 147 | * number of entries in the destination side payload queue |
@@ -115,9 +162,16 @@ | |||
115 | /* | 162 | /* |
116 | * tuning the action when the numalink network is extremely delayed | 163 | * tuning the action when the numalink network is extremely delayed |
117 | */ | 164 | */ |
118 | #define CONGESTED_RESPONSE_US 1000 /* 'long' response time, in microseconds */ | 165 | #define CONGESTED_RESPONSE_US 1000 /* 'long' response time, in |
119 | #define CONGESTED_REPS 10 /* long delays averaged over this many broadcasts */ | 166 | microseconds */ |
120 | #define CONGESTED_PERIOD 30 /* time for the bau to be disabled, in seconds */ | 167 | #define CONGESTED_REPS 10 /* long delays averaged over |
168 | this many broadcasts */ | ||
169 | #define CONGESTED_PERIOD 30 /* time for the bau to be | ||
170 | disabled, in seconds */ | ||
171 | /* see msg_type: */ | ||
172 | #define MSG_NOOP 0 | ||
173 | #define MSG_REGULAR 1 | ||
174 | #define MSG_RETRY 2 | ||
121 | 175 | ||
122 | /* | 176 | /* |
123 | * Distribution: 32 bytes (256 bits) (bytes 0-0x1f of descriptor) | 177 | * Distribution: 32 bytes (256 bits) (bytes 0-0x1f of descriptor) |
@@ -129,8 +183,8 @@ | |||
129 | * 'base_dest_nasid' field of the header corresponds to the | 183 | * 'base_dest_nasid' field of the header corresponds to the |
130 | * destination nodeID associated with that specified bit. | 184 | * destination nodeID associated with that specified bit. |
131 | */ | 185 | */ |
132 | struct bau_target_uvhubmask { | 186 | struct bau_targ_hubmask { |
133 | unsigned long bits[BITS_TO_LONGS(UV_DISTRIBUTION_SIZE)]; | 187 | unsigned long bits[BITS_TO_LONGS(UV_DISTRIBUTION_SIZE)]; |
134 | }; | 188 | }; |
135 | 189 | ||
136 | /* | 190 | /* |
@@ -139,7 +193,7 @@ struct bau_target_uvhubmask { | |||
139 | * enough bits for max. cpu's per uvhub) | 193 | * enough bits for max. cpu's per uvhub) |
140 | */ | 194 | */ |
141 | struct bau_local_cpumask { | 195 | struct bau_local_cpumask { |
142 | unsigned long bits; | 196 | unsigned long bits; |
143 | }; | 197 | }; |
144 | 198 | ||
145 | /* | 199 | /* |
@@ -160,14 +214,14 @@ struct bau_local_cpumask { | |||
160 | * The payload is software-defined for INTD transactions | 214 | * The payload is software-defined for INTD transactions |
161 | */ | 215 | */ |
162 | struct bau_msg_payload { | 216 | struct bau_msg_payload { |
163 | unsigned long address; /* signifies a page or all TLB's | 217 | unsigned long address; /* signifies a page or all |
164 | of the cpu */ | 218 | TLB's of the cpu */ |
165 | /* 64 bits */ | 219 | /* 64 bits */ |
166 | unsigned short sending_cpu; /* filled in by sender */ | 220 | unsigned short sending_cpu; /* filled in by sender */ |
167 | /* 16 bits */ | 221 | /* 16 bits */ |
168 | unsigned short acknowledge_count;/* filled in by destination */ | 222 | unsigned short acknowledge_count; /* filled in by destination */ |
169 | /* 16 bits */ | 223 | /* 16 bits */ |
170 | unsigned int reserved1:32; /* not usable */ | 224 | unsigned int reserved1:32; /* not usable */ |
171 | }; | 225 | }; |
172 | 226 | ||
173 | 227 | ||
@@ -176,93 +230,96 @@ struct bau_msg_payload { | |||
176 | * see table 4.2.3.0.1 in broacast_assist spec. | 230 | * see table 4.2.3.0.1 in broacast_assist spec. |
177 | */ | 231 | */ |
178 | struct bau_msg_header { | 232 | struct bau_msg_header { |
179 | unsigned int dest_subnodeid:6; /* must be 0x10, for the LB */ | 233 | unsigned int dest_subnodeid:6; /* must be 0x10, for the LB */ |
180 | /* bits 5:0 */ | 234 | /* bits 5:0 */ |
181 | unsigned int base_dest_nasid:15; /* nasid of the */ | 235 | unsigned int base_dest_nasid:15; /* nasid of the first bit */ |
182 | /* bits 20:6 */ /* first bit in uvhub map */ | 236 | /* bits 20:6 */ /* in uvhub map */ |
183 | unsigned int command:8; /* message type */ | 237 | unsigned int command:8; /* message type */ |
184 | /* bits 28:21 */ | 238 | /* bits 28:21 */ |
185 | /* 0x38: SN3net EndPoint Message */ | 239 | /* 0x38: SN3net EndPoint Message */ |
186 | unsigned int rsvd_1:3; /* must be zero */ | 240 | unsigned int rsvd_1:3; /* must be zero */ |
187 | /* bits 31:29 */ | 241 | /* bits 31:29 */ |
188 | /* int will align on 32 bits */ | 242 | /* int will align on 32 bits */ |
189 | unsigned int rsvd_2:9; /* must be zero */ | 243 | unsigned int rsvd_2:9; /* must be zero */ |
190 | /* bits 40:32 */ | 244 | /* bits 40:32 */ |
191 | /* Suppl_A is 56-41 */ | 245 | /* Suppl_A is 56-41 */ |
192 | unsigned int sequence:16;/* message sequence number */ | 246 | unsigned int sequence:16; /* message sequence number */ |
193 | /* bits 56:41 */ /* becomes bytes 16-17 of msg */ | 247 | /* bits 56:41 */ /* becomes bytes 16-17 of msg */ |
194 | /* Address field (96:57) is never used as an | 248 | /* Address field (96:57) is |
195 | address (these are address bits 42:3) */ | 249 | never used as an address |
196 | 250 | (these are address bits | |
197 | unsigned int rsvd_3:1; /* must be zero */ | 251 | 42:3) */ |
252 | |||
253 | unsigned int rsvd_3:1; /* must be zero */ | ||
198 | /* bit 57 */ | 254 | /* bit 57 */ |
199 | /* address bits 27:4 are payload */ | 255 | /* address bits 27:4 are payload */ |
200 | /* these next 24 (58-81) bits become bytes 12-14 of msg */ | 256 | /* these next 24 (58-81) bits become bytes 12-14 of msg */ |
201 | |||
202 | /* bits 65:58 land in byte 12 */ | 257 | /* bits 65:58 land in byte 12 */ |
203 | unsigned int replied_to:1;/* sent as 0 by the source to byte 12 */ | 258 | unsigned int replied_to:1; /* sent as 0 by the source to |
259 | byte 12 */ | ||
204 | /* bit 58 */ | 260 | /* bit 58 */ |
205 | unsigned int msg_type:3; /* software type of the message*/ | 261 | unsigned int msg_type:3; /* software type of the |
262 | message */ | ||
206 | /* bits 61:59 */ | 263 | /* bits 61:59 */ |
207 | unsigned int canceled:1; /* message canceled, resource to be freed*/ | 264 | unsigned int canceled:1; /* message canceled, resource |
265 | is to be freed*/ | ||
208 | /* bit 62 */ | 266 | /* bit 62 */ |
209 | unsigned int payload_1a:1;/* not currently used */ | 267 | unsigned int payload_1a:1; /* not currently used */ |
210 | /* bit 63 */ | 268 | /* bit 63 */ |
211 | unsigned int payload_1b:2;/* not currently used */ | 269 | unsigned int payload_1b:2; /* not currently used */ |
212 | /* bits 65:64 */ | 270 | /* bits 65:64 */ |
213 | 271 | ||
214 | /* bits 73:66 land in byte 13 */ | 272 | /* bits 73:66 land in byte 13 */ |
215 | unsigned int payload_1ca:6;/* not currently used */ | 273 | unsigned int payload_1ca:6; /* not currently used */ |
216 | /* bits 71:66 */ | 274 | /* bits 71:66 */ |
217 | unsigned int payload_1c:2;/* not currently used */ | 275 | unsigned int payload_1c:2; /* not currently used */ |
218 | /* bits 73:72 */ | 276 | /* bits 73:72 */ |
219 | 277 | ||
220 | /* bits 81:74 land in byte 14 */ | 278 | /* bits 81:74 land in byte 14 */ |
221 | unsigned int payload_1d:6;/* not currently used */ | 279 | unsigned int payload_1d:6; /* not currently used */ |
222 | /* bits 79:74 */ | 280 | /* bits 79:74 */ |
223 | unsigned int payload_1e:2;/* not currently used */ | 281 | unsigned int payload_1e:2; /* not currently used */ |
224 | /* bits 81:80 */ | 282 | /* bits 81:80 */ |
225 | 283 | ||
226 | unsigned int rsvd_4:7; /* must be zero */ | 284 | unsigned int rsvd_4:7; /* must be zero */ |
227 | /* bits 88:82 */ | 285 | /* bits 88:82 */ |
228 | unsigned int sw_ack_flag:1;/* software acknowledge flag */ | 286 | unsigned int swack_flag:1; /* software acknowledge flag */ |
229 | /* bit 89 */ | 287 | /* bit 89 */ |
230 | /* INTD trasactions at destination are to | 288 | /* INTD trasactions at |
231 | wait for software acknowledge */ | 289 | destination are to wait for |
232 | unsigned int rsvd_5:6; /* must be zero */ | 290 | software acknowledge */ |
291 | unsigned int rsvd_5:6; /* must be zero */ | ||
233 | /* bits 95:90 */ | 292 | /* bits 95:90 */ |
234 | unsigned int rsvd_6:5; /* must be zero */ | 293 | unsigned int rsvd_6:5; /* must be zero */ |
235 | /* bits 100:96 */ | 294 | /* bits 100:96 */ |
236 | unsigned int int_both:1;/* if 1, interrupt both sockets on the uvhub */ | 295 | unsigned int int_both:1; /* if 1, interrupt both sockets |
296 | on the uvhub */ | ||
237 | /* bit 101*/ | 297 | /* bit 101*/ |
238 | unsigned int fairness:3;/* usually zero */ | 298 | unsigned int fairness:3; /* usually zero */ |
239 | /* bits 104:102 */ | 299 | /* bits 104:102 */ |
240 | unsigned int multilevel:1; /* multi-level multicast format */ | 300 | unsigned int multilevel:1; /* multi-level multicast |
301 | format */ | ||
241 | /* bit 105 */ | 302 | /* bit 105 */ |
242 | /* 0 for TLB: endpoint multi-unicast messages */ | 303 | /* 0 for TLB: endpoint multi-unicast messages */ |
243 | unsigned int chaining:1;/* next descriptor is part of this activation*/ | 304 | unsigned int chaining:1; /* next descriptor is part of |
305 | this activation*/ | ||
244 | /* bit 106 */ | 306 | /* bit 106 */ |
245 | unsigned int rsvd_7:21; /* must be zero */ | 307 | unsigned int rsvd_7:21; /* must be zero */ |
246 | /* bits 127:107 */ | 308 | /* bits 127:107 */ |
247 | }; | 309 | }; |
248 | 310 | ||
249 | /* see msg_type: */ | ||
250 | #define MSG_NOOP 0 | ||
251 | #define MSG_REGULAR 1 | ||
252 | #define MSG_RETRY 2 | ||
253 | |||
254 | /* | 311 | /* |
255 | * The activation descriptor: | 312 | * The activation descriptor: |
256 | * The format of the message to send, plus all accompanying control | 313 | * The format of the message to send, plus all accompanying control |
257 | * Should be 64 bytes | 314 | * Should be 64 bytes |
258 | */ | 315 | */ |
259 | struct bau_desc { | 316 | struct bau_desc { |
260 | struct bau_target_uvhubmask distribution; | 317 | struct bau_targ_hubmask distribution; |
261 | /* | 318 | /* |
262 | * message template, consisting of header and payload: | 319 | * message template, consisting of header and payload: |
263 | */ | 320 | */ |
264 | struct bau_msg_header header; | 321 | struct bau_msg_header header; |
265 | struct bau_msg_payload payload; | 322 | struct bau_msg_payload payload; |
266 | }; | 323 | }; |
267 | /* | 324 | /* |
268 | * -payload-- ---------header------ | 325 | * -payload-- ---------header------ |
@@ -281,59 +338,51 @@ struct bau_desc { | |||
281 | * are 32 bytes (2 micropackets) (256 bits) in length, but contain only 17 | 338 | * are 32 bytes (2 micropackets) (256 bits) in length, but contain only 17 |
282 | * bytes of usable data, including the sw ack vector in byte 15 (bits 127:120) | 339 | * bytes of usable data, including the sw ack vector in byte 15 (bits 127:120) |
283 | * (12 bytes come from bau_msg_payload, 3 from payload_1, 2 from | 340 | * (12 bytes come from bau_msg_payload, 3 from payload_1, 2 from |
284 | * sw_ack_vector and payload_2) | 341 | * swack_vec and payload_2) |
285 | * "Enabling Software Acknowledgment mode (see Section 4.3.3 Software | 342 | * "Enabling Software Acknowledgment mode (see Section 4.3.3 Software |
286 | * Acknowledge Processing) also selects 32 byte (17 bytes usable) payload | 343 | * Acknowledge Processing) also selects 32 byte (17 bytes usable) payload |
287 | * operation." | 344 | * operation." |
288 | */ | 345 | */ |
289 | struct bau_payload_queue_entry { | 346 | struct bau_pq_entry { |
290 | unsigned long address; /* signifies a page or all TLB's | 347 | unsigned long address; /* signifies a page or all TLB's |
291 | of the cpu */ | 348 | of the cpu */ |
292 | /* 64 bits, bytes 0-7 */ | 349 | /* 64 bits, bytes 0-7 */ |
293 | 350 | unsigned short sending_cpu; /* cpu that sent the message */ | |
294 | unsigned short sending_cpu; /* cpu that sent the message */ | ||
295 | /* 16 bits, bytes 8-9 */ | 351 | /* 16 bits, bytes 8-9 */ |
296 | 352 | unsigned short acknowledge_count; /* filled in by destination */ | |
297 | unsigned short acknowledge_count; /* filled in by destination */ | ||
298 | /* 16 bits, bytes 10-11 */ | 353 | /* 16 bits, bytes 10-11 */ |
299 | |||
300 | /* these next 3 bytes come from bits 58-81 of the message header */ | 354 | /* these next 3 bytes come from bits 58-81 of the message header */ |
301 | unsigned short replied_to:1; /* sent as 0 by the source */ | 355 | unsigned short replied_to:1; /* sent as 0 by the source */ |
302 | unsigned short msg_type:3; /* software message type */ | 356 | unsigned short msg_type:3; /* software message type */ |
303 | unsigned short canceled:1; /* sent as 0 by the source */ | 357 | unsigned short canceled:1; /* sent as 0 by the source */ |
304 | unsigned short unused1:3; /* not currently using */ | 358 | unsigned short unused1:3; /* not currently using */ |
305 | /* byte 12 */ | 359 | /* byte 12 */ |
306 | 360 | unsigned char unused2a; /* not currently using */ | |
307 | unsigned char unused2a; /* not currently using */ | ||
308 | /* byte 13 */ | 361 | /* byte 13 */ |
309 | unsigned char unused2; /* not currently using */ | 362 | unsigned char unused2; /* not currently using */ |
310 | /* byte 14 */ | 363 | /* byte 14 */ |
311 | 364 | unsigned char swack_vec; /* filled in by the hardware */ | |
312 | unsigned char sw_ack_vector; /* filled in by the hardware */ | ||
313 | /* byte 15 (bits 127:120) */ | 365 | /* byte 15 (bits 127:120) */ |
314 | 366 | unsigned short sequence; /* message sequence number */ | |
315 | unsigned short sequence; /* message sequence number */ | ||
316 | /* bytes 16-17 */ | 367 | /* bytes 16-17 */ |
317 | unsigned char unused4[2]; /* not currently using bytes 18-19 */ | 368 | unsigned char unused4[2]; /* not currently using bytes 18-19 */ |
318 | /* bytes 18-19 */ | 369 | /* bytes 18-19 */ |
319 | 370 | int number_of_cpus; /* filled in at destination */ | |
320 | int number_of_cpus; /* filled in at destination */ | ||
321 | /* 32 bits, bytes 20-23 (aligned) */ | 371 | /* 32 bits, bytes 20-23 (aligned) */ |
322 | 372 | unsigned char unused5[8]; /* not using */ | |
323 | unsigned char unused5[8]; /* not using */ | ||
324 | /* bytes 24-31 */ | 373 | /* bytes 24-31 */ |
325 | }; | 374 | }; |
326 | 375 | ||
327 | struct msg_desc { | 376 | struct msg_desc { |
328 | struct bau_payload_queue_entry *msg; | 377 | struct bau_pq_entry *msg; |
329 | int msg_slot; | 378 | int msg_slot; |
330 | int sw_ack_slot; | 379 | int swack_slot; |
331 | struct bau_payload_queue_entry *va_queue_first; | 380 | struct bau_pq_entry *queue_first; |
332 | struct bau_payload_queue_entry *va_queue_last; | 381 | struct bau_pq_entry *queue_last; |
333 | }; | 382 | }; |
334 | 383 | ||
335 | struct reset_args { | 384 | struct reset_args { |
336 | int sender; | 385 | int sender; |
337 | }; | 386 | }; |
338 | 387 | ||
339 | /* | 388 | /* |
@@ -341,112 +390,226 @@ struct reset_args { | |||
341 | */ | 390 | */ |
342 | struct ptc_stats { | 391 | struct ptc_stats { |
343 | /* sender statistics */ | 392 | /* sender statistics */ |
344 | unsigned long s_giveup; /* number of fall backs to IPI-style flushes */ | 393 | unsigned long s_giveup; /* number of fall backs to |
345 | unsigned long s_requestor; /* number of shootdown requests */ | 394 | IPI-style flushes */ |
346 | unsigned long s_stimeout; /* source side timeouts */ | 395 | unsigned long s_requestor; /* number of shootdown |
347 | unsigned long s_dtimeout; /* destination side timeouts */ | 396 | requests */ |
348 | unsigned long s_time; /* time spent in sending side */ | 397 | unsigned long s_stimeout; /* source side timeouts */ |
349 | unsigned long s_retriesok; /* successful retries */ | 398 | unsigned long s_dtimeout; /* destination side timeouts */ |
350 | unsigned long s_ntargcpu; /* total number of cpu's targeted */ | 399 | unsigned long s_time; /* time spent in sending side */ |
351 | unsigned long s_ntargself; /* times the sending cpu was targeted */ | 400 | unsigned long s_retriesok; /* successful retries */ |
352 | unsigned long s_ntarglocals; /* targets of cpus on the local blade */ | 401 | unsigned long s_ntargcpu; /* total number of cpu's |
353 | unsigned long s_ntargremotes; /* targets of cpus on remote blades */ | 402 | targeted */ |
354 | unsigned long s_ntarglocaluvhub; /* targets of the local hub */ | 403 | unsigned long s_ntargself; /* times the sending cpu was |
355 | unsigned long s_ntargremoteuvhub; /* remotes hubs targeted */ | 404 | targeted */ |
356 | unsigned long s_ntarguvhub; /* total number of uvhubs targeted */ | 405 | unsigned long s_ntarglocals; /* targets of cpus on the local |
357 | unsigned long s_ntarguvhub16; /* number of times target hubs >= 16*/ | 406 | blade */ |
358 | unsigned long s_ntarguvhub8; /* number of times target hubs >= 8 */ | 407 | unsigned long s_ntargremotes; /* targets of cpus on remote |
359 | unsigned long s_ntarguvhub4; /* number of times target hubs >= 4 */ | 408 | blades */ |
360 | unsigned long s_ntarguvhub2; /* number of times target hubs >= 2 */ | 409 | unsigned long s_ntarglocaluvhub; /* targets of the local hub */ |
361 | unsigned long s_ntarguvhub1; /* number of times target hubs == 1 */ | 410 | unsigned long s_ntargremoteuvhub; /* remotes hubs targeted */ |
362 | unsigned long s_resets_plug; /* ipi-style resets from plug state */ | 411 | unsigned long s_ntarguvhub; /* total number of uvhubs |
363 | unsigned long s_resets_timeout; /* ipi-style resets from timeouts */ | 412 | targeted */ |
364 | unsigned long s_busy; /* status stayed busy past s/w timer */ | 413 | unsigned long s_ntarguvhub16; /* number of times target |
365 | unsigned long s_throttles; /* waits in throttle */ | 414 | hubs >= 16*/ |
366 | unsigned long s_retry_messages; /* retry broadcasts */ | 415 | unsigned long s_ntarguvhub8; /* number of times target |
367 | unsigned long s_bau_reenabled; /* for bau enable/disable */ | 416 | hubs >= 8 */ |
368 | unsigned long s_bau_disabled; /* for bau enable/disable */ | 417 | unsigned long s_ntarguvhub4; /* number of times target |
418 | hubs >= 4 */ | ||
419 | unsigned long s_ntarguvhub2; /* number of times target | ||
420 | hubs >= 2 */ | ||
421 | unsigned long s_ntarguvhub1; /* number of times target | ||
422 | hubs == 1 */ | ||
423 | unsigned long s_resets_plug; /* ipi-style resets from plug | ||
424 | state */ | ||
425 | unsigned long s_resets_timeout; /* ipi-style resets from | ||
426 | timeouts */ | ||
427 | unsigned long s_busy; /* status stayed busy past | ||
428 | s/w timer */ | ||
429 | unsigned long s_throttles; /* waits in throttle */ | ||
430 | unsigned long s_retry_messages; /* retry broadcasts */ | ||
431 | unsigned long s_bau_reenabled; /* for bau enable/disable */ | ||
432 | unsigned long s_bau_disabled; /* for bau enable/disable */ | ||
369 | /* destination statistics */ | 433 | /* destination statistics */ |
370 | unsigned long d_alltlb; /* times all tlb's on this cpu were flushed */ | 434 | unsigned long d_alltlb; /* times all tlb's on this |
371 | unsigned long d_onetlb; /* times just one tlb on this cpu was flushed */ | 435 | cpu were flushed */ |
372 | unsigned long d_multmsg; /* interrupts with multiple messages */ | 436 | unsigned long d_onetlb; /* times just one tlb on this |
373 | unsigned long d_nomsg; /* interrupts with no message */ | 437 | cpu was flushed */ |
374 | unsigned long d_time; /* time spent on destination side */ | 438 | unsigned long d_multmsg; /* interrupts with multiple |
375 | unsigned long d_requestee; /* number of messages processed */ | 439 | messages */ |
376 | unsigned long d_retries; /* number of retry messages processed */ | 440 | unsigned long d_nomsg; /* interrupts with no message */ |
377 | unsigned long d_canceled; /* number of messages canceled by retries */ | 441 | unsigned long d_time; /* time spent on destination |
378 | unsigned long d_nocanceled; /* retries that found nothing to cancel */ | 442 | side */ |
379 | unsigned long d_resets; /* number of ipi-style requests processed */ | 443 | unsigned long d_requestee; /* number of messages |
380 | unsigned long d_rcanceled; /* number of messages canceled by resets */ | 444 | processed */ |
445 | unsigned long d_retries; /* number of retry messages | ||
446 | processed */ | ||
447 | unsigned long d_canceled; /* number of messages canceled | ||
448 | by retries */ | ||
449 | unsigned long d_nocanceled; /* retries that found nothing | ||
450 | to cancel */ | ||
451 | unsigned long d_resets; /* number of ipi-style requests | ||
452 | processed */ | ||
453 | unsigned long d_rcanceled; /* number of messages canceled | ||
454 | by resets */ | ||
455 | }; | ||
456 | |||
457 | struct tunables { | ||
458 | int *tunp; | ||
459 | int deflt; | ||
381 | }; | 460 | }; |
382 | 461 | ||
383 | struct hub_and_pnode { | 462 | struct hub_and_pnode { |
384 | short uvhub; | 463 | short uvhub; |
385 | short pnode; | 464 | short pnode; |
386 | }; | 465 | }; |
466 | |||
467 | struct socket_desc { | ||
468 | short num_cpus; | ||
469 | short cpu_number[MAX_CPUS_PER_SOCKET]; | ||
470 | }; | ||
471 | |||
472 | struct uvhub_desc { | ||
473 | unsigned short socket_mask; | ||
474 | short num_cpus; | ||
475 | short uvhub; | ||
476 | short pnode; | ||
477 | struct socket_desc socket[2]; | ||
478 | }; | ||
479 | |||
387 | /* | 480 | /* |
388 | * one per-cpu; to locate the software tables | 481 | * one per-cpu; to locate the software tables |
389 | */ | 482 | */ |
390 | struct bau_control { | 483 | struct bau_control { |
391 | struct bau_desc *descriptor_base; | 484 | struct bau_desc *descriptor_base; |
392 | struct bau_payload_queue_entry *va_queue_first; | 485 | struct bau_pq_entry *queue_first; |
393 | struct bau_payload_queue_entry *va_queue_last; | 486 | struct bau_pq_entry *queue_last; |
394 | struct bau_payload_queue_entry *bau_msg_head; | 487 | struct bau_pq_entry *bau_msg_head; |
395 | struct bau_control *uvhub_master; | 488 | struct bau_control *uvhub_master; |
396 | struct bau_control *socket_master; | 489 | struct bau_control *socket_master; |
397 | struct ptc_stats *statp; | 490 | struct ptc_stats *statp; |
398 | unsigned long timeout_interval; | 491 | unsigned long timeout_interval; |
399 | unsigned long set_bau_on_time; | 492 | unsigned long set_bau_on_time; |
400 | atomic_t active_descriptor_count; | 493 | atomic_t active_descriptor_count; |
401 | int plugged_tries; | 494 | int plugged_tries; |
402 | int timeout_tries; | 495 | int timeout_tries; |
403 | int ipi_attempts; | 496 | int ipi_attempts; |
404 | int conseccompletes; | 497 | int conseccompletes; |
405 | int baudisabled; | 498 | int baudisabled; |
406 | int set_bau_off; | 499 | int set_bau_off; |
407 | short cpu; | 500 | short cpu; |
408 | short osnode; | 501 | short osnode; |
409 | short uvhub_cpu; | 502 | short uvhub_cpu; |
410 | short uvhub; | 503 | short uvhub; |
411 | short cpus_in_socket; | 504 | short cpus_in_socket; |
412 | short cpus_in_uvhub; | 505 | short cpus_in_uvhub; |
413 | short partition_base_pnode; | 506 | short partition_base_pnode; |
414 | unsigned short message_number; | 507 | unsigned short message_number; |
415 | unsigned short uvhub_quiesce; | 508 | unsigned short uvhub_quiesce; |
416 | short socket_acknowledge_count[DEST_Q_SIZE]; | 509 | short socket_acknowledge_count[DEST_Q_SIZE]; |
417 | cycles_t send_message; | 510 | cycles_t send_message; |
418 | spinlock_t uvhub_lock; | 511 | spinlock_t uvhub_lock; |
419 | spinlock_t queue_lock; | 512 | spinlock_t queue_lock; |
420 | /* tunables */ | 513 | /* tunables */ |
421 | int max_bau_concurrent; | 514 | int max_concurr; |
422 | int max_bau_concurrent_constant; | 515 | int max_concurr_const; |
423 | int plugged_delay; | 516 | int plugged_delay; |
424 | int plugsb4reset; | 517 | int plugsb4reset; |
425 | int timeoutsb4reset; | 518 | int timeoutsb4reset; |
426 | int ipi_reset_limit; | 519 | int ipi_reset_limit; |
427 | int complete_threshold; | 520 | int complete_threshold; |
428 | int congested_response_us; | 521 | int cong_response_us; |
429 | int congested_reps; | 522 | int cong_reps; |
430 | int congested_period; | 523 | int cong_period; |
431 | cycles_t period_time; | 524 | cycles_t period_time; |
432 | long period_requests; | 525 | long period_requests; |
433 | struct hub_and_pnode *target_hub_and_pnode; | 526 | struct hub_and_pnode *thp; |
434 | }; | 527 | }; |
435 | 528 | ||
436 | static inline int bau_uvhub_isset(int uvhub, struct bau_target_uvhubmask *dstp) | 529 | static unsigned long read_mmr_uv2_status(void) |
530 | { | ||
531 | return read_lmmr(UV2H_LB_BAU_SB_ACTIVATION_STATUS_2); | ||
532 | } | ||
533 | |||
534 | static void write_mmr_data_broadcast(int pnode, unsigned long mmr_image) | ||
535 | { | ||
536 | write_gmmr(pnode, UVH_BAU_DATA_BROADCAST, mmr_image); | ||
537 | } | ||
538 | |||
539 | static void write_mmr_descriptor_base(int pnode, unsigned long mmr_image) | ||
540 | { | ||
541 | write_gmmr(pnode, UVH_LB_BAU_SB_DESCRIPTOR_BASE, mmr_image); | ||
542 | } | ||
543 | |||
544 | static void write_mmr_activation(unsigned long index) | ||
545 | { | ||
546 | write_lmmr(UVH_LB_BAU_SB_ACTIVATION_CONTROL, index); | ||
547 | } | ||
548 | |||
549 | static void write_gmmr_activation(int pnode, unsigned long mmr_image) | ||
550 | { | ||
551 | write_gmmr(pnode, UVH_LB_BAU_SB_ACTIVATION_CONTROL, mmr_image); | ||
552 | } | ||
553 | |||
554 | static void write_mmr_payload_first(int pnode, unsigned long mmr_image) | ||
555 | { | ||
556 | write_gmmr(pnode, UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST, mmr_image); | ||
557 | } | ||
558 | |||
559 | static void write_mmr_payload_tail(int pnode, unsigned long mmr_image) | ||
560 | { | ||
561 | write_gmmr(pnode, UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL, mmr_image); | ||
562 | } | ||
563 | |||
564 | static void write_mmr_payload_last(int pnode, unsigned long mmr_image) | ||
565 | { | ||
566 | write_gmmr(pnode, UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST, mmr_image); | ||
567 | } | ||
568 | |||
569 | static void write_mmr_misc_control(int pnode, unsigned long mmr_image) | ||
570 | { | ||
571 | write_gmmr(pnode, UVH_LB_BAU_MISC_CONTROL, mmr_image); | ||
572 | } | ||
573 | |||
574 | static unsigned long read_mmr_misc_control(int pnode) | ||
575 | { | ||
576 | return read_gmmr(pnode, UVH_LB_BAU_MISC_CONTROL); | ||
577 | } | ||
578 | |||
579 | static void write_mmr_sw_ack(unsigned long mr) | ||
580 | { | ||
581 | uv_write_local_mmr(UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS, mr); | ||
582 | } | ||
583 | |||
584 | static unsigned long read_mmr_sw_ack(void) | ||
585 | { | ||
586 | return read_lmmr(UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE); | ||
587 | } | ||
588 | |||
589 | static unsigned long read_gmmr_sw_ack(int pnode) | ||
590 | { | ||
591 | return read_gmmr(pnode, UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE); | ||
592 | } | ||
593 | |||
594 | static void write_mmr_data_config(int pnode, unsigned long mr) | ||
595 | { | ||
596 | uv_write_global_mmr64(pnode, UVH_BAU_DATA_CONFIG, mr); | ||
597 | } | ||
598 | |||
599 | static inline int bau_uvhub_isset(int uvhub, struct bau_targ_hubmask *dstp) | ||
437 | { | 600 | { |
438 | return constant_test_bit(uvhub, &dstp->bits[0]); | 601 | return constant_test_bit(uvhub, &dstp->bits[0]); |
439 | } | 602 | } |
440 | static inline void bau_uvhub_set(int pnode, struct bau_target_uvhubmask *dstp) | 603 | static inline void bau_uvhub_set(int pnode, struct bau_targ_hubmask *dstp) |
441 | { | 604 | { |
442 | __set_bit(pnode, &dstp->bits[0]); | 605 | __set_bit(pnode, &dstp->bits[0]); |
443 | } | 606 | } |
444 | static inline void bau_uvhubs_clear(struct bau_target_uvhubmask *dstp, | 607 | static inline void bau_uvhubs_clear(struct bau_targ_hubmask *dstp, |
445 | int nbits) | 608 | int nbits) |
446 | { | 609 | { |
447 | bitmap_zero(&dstp->bits[0], nbits); | 610 | bitmap_zero(&dstp->bits[0], nbits); |
448 | } | 611 | } |
449 | static inline int bau_uvhub_weight(struct bau_target_uvhubmask *dstp) | 612 | static inline int bau_uvhub_weight(struct bau_targ_hubmask *dstp) |
450 | { | 613 | { |
451 | return bitmap_weight((unsigned long *)&dstp->bits[0], | 614 | return bitmap_weight((unsigned long *)&dstp->bits[0], |
452 | UV_DISTRIBUTION_SIZE); | 615 | UV_DISTRIBUTION_SIZE); |
@@ -457,9 +620,6 @@ static inline void bau_cpubits_clear(struct bau_local_cpumask *dstp, int nbits) | |||
457 | bitmap_zero(&dstp->bits, nbits); | 620 | bitmap_zero(&dstp->bits, nbits); |
458 | } | 621 | } |
459 | 622 | ||
460 | #define cpubit_isset(cpu, bau_local_cpumask) \ | ||
461 | test_bit((cpu), (bau_local_cpumask).bits) | ||
462 | |||
463 | extern void uv_bau_message_intr1(void); | 623 | extern void uv_bau_message_intr1(void); |
464 | extern void uv_bau_timeout_intr1(void); | 624 | extern void uv_bau_timeout_intr1(void); |
465 | 625 | ||
@@ -467,7 +627,7 @@ struct atomic_short { | |||
467 | short counter; | 627 | short counter; |
468 | }; | 628 | }; |
469 | 629 | ||
470 | /** | 630 | /* |
471 | * atomic_read_short - read a short atomic variable | 631 | * atomic_read_short - read a short atomic variable |
472 | * @v: pointer of type atomic_short | 632 | * @v: pointer of type atomic_short |
473 | * | 633 | * |
@@ -478,14 +638,14 @@ static inline int atomic_read_short(const struct atomic_short *v) | |||
478 | return v->counter; | 638 | return v->counter; |
479 | } | 639 | } |
480 | 640 | ||
481 | /** | 641 | /* |
482 | * atomic_add_short_return - add and return a short int | 642 | * atom_asr - add and return a short int |
483 | * @i: short value to add | 643 | * @i: short value to add |
484 | * @v: pointer of type atomic_short | 644 | * @v: pointer of type atomic_short |
485 | * | 645 | * |
486 | * Atomically adds @i to @v and returns @i + @v | 646 | * Atomically adds @i to @v and returns @i + @v |
487 | */ | 647 | */ |
488 | static inline int atomic_add_short_return(short i, struct atomic_short *v) | 648 | static inline int atom_asr(short i, struct atomic_short *v) |
489 | { | 649 | { |
490 | short __i = i; | 650 | short __i = i; |
491 | asm volatile(LOCK_PREFIX "xaddw %0, %1" | 651 | asm volatile(LOCK_PREFIX "xaddw %0, %1" |
@@ -494,4 +654,26 @@ static inline int atomic_add_short_return(short i, struct atomic_short *v) | |||
494 | return i + __i; | 654 | return i + __i; |
495 | } | 655 | } |
496 | 656 | ||
657 | /* | ||
658 | * conditionally add 1 to *v, unless *v is >= u | ||
659 | * return 0 if we cannot add 1 to *v because it is >= u | ||
660 | * return 1 if we can add 1 to *v because it is < u | ||
661 | * the add is atomic | ||
662 | * | ||
663 | * This is close to atomic_add_unless(), but this allows the 'u' value | ||
664 | * to be lowered below the current 'v'. atomic_add_unless can only stop | ||
665 | * on equal. | ||
666 | */ | ||
667 | static inline int atomic_inc_unless_ge(spinlock_t *lock, atomic_t *v, int u) | ||
668 | { | ||
669 | spin_lock(lock); | ||
670 | if (atomic_read(v) >= u) { | ||
671 | spin_unlock(lock); | ||
672 | return 0; | ||
673 | } | ||
674 | atomic_inc(v); | ||
675 | spin_unlock(lock); | ||
676 | return 1; | ||
677 | } | ||
678 | |||
497 | #endif /* _ASM_X86_UV_UV_BAU_H */ | 679 | #endif /* _ASM_X86_UV_UV_BAU_H */ |
diff --git a/arch/x86/include/asm/uv/uv_hub.h b/arch/x86/include/asm/uv/uv_hub.h index 4298002d0c83..f26544a15214 100644 --- a/arch/x86/include/asm/uv/uv_hub.h +++ b/arch/x86/include/asm/uv/uv_hub.h | |||
@@ -77,8 +77,9 @@ | |||
77 | * | 77 | * |
78 | * 1111110000000000 | 78 | * 1111110000000000 |
79 | * 5432109876543210 | 79 | * 5432109876543210 |
80 | * pppppppppplc0cch Nehalem-EX | 80 | * pppppppppplc0cch Nehalem-EX (12 bits in hdw reg) |
81 | * ppppppppplcc0cch Westmere-EX | 81 | * ppppppppplcc0cch Westmere-EX (12 bits in hdw reg) |
82 | * pppppppppppcccch SandyBridge (15 bits in hdw reg) | ||
82 | * sssssssssss | 83 | * sssssssssss |
83 | * | 84 | * |
84 | * p = pnode bits | 85 | * p = pnode bits |
@@ -87,7 +88,7 @@ | |||
87 | * h = hyperthread | 88 | * h = hyperthread |
88 | * s = bits that are in the SOCKET_ID CSR | 89 | * s = bits that are in the SOCKET_ID CSR |
89 | * | 90 | * |
90 | * Note: Processor only supports 12 bits in the APICID register. The ACPI | 91 | * Note: Processor may support fewer bits in the APICID register. The ACPI |
91 | * tables hold all 16 bits. Software needs to be aware of this. | 92 | * tables hold all 16 bits. Software needs to be aware of this. |
92 | * | 93 | * |
93 | * Unless otherwise specified, all references to APICID refer to | 94 | * Unless otherwise specified, all references to APICID refer to |
@@ -138,6 +139,8 @@ struct uv_hub_info_s { | |||
138 | unsigned long global_mmr_base; | 139 | unsigned long global_mmr_base; |
139 | unsigned long gpa_mask; | 140 | unsigned long gpa_mask; |
140 | unsigned int gnode_extra; | 141 | unsigned int gnode_extra; |
142 | unsigned char hub_revision; | ||
143 | unsigned char apic_pnode_shift; | ||
141 | unsigned long gnode_upper; | 144 | unsigned long gnode_upper; |
142 | unsigned long lowmem_remap_top; | 145 | unsigned long lowmem_remap_top; |
143 | unsigned long lowmem_remap_base; | 146 | unsigned long lowmem_remap_base; |
@@ -149,13 +152,31 @@ struct uv_hub_info_s { | |||
149 | unsigned char m_val; | 152 | unsigned char m_val; |
150 | unsigned char n_val; | 153 | unsigned char n_val; |
151 | struct uv_scir_s scir; | 154 | struct uv_scir_s scir; |
152 | unsigned char apic_pnode_shift; | ||
153 | }; | 155 | }; |
154 | 156 | ||
155 | DECLARE_PER_CPU(struct uv_hub_info_s, __uv_hub_info); | 157 | DECLARE_PER_CPU(struct uv_hub_info_s, __uv_hub_info); |
156 | #define uv_hub_info (&__get_cpu_var(__uv_hub_info)) | 158 | #define uv_hub_info (&__get_cpu_var(__uv_hub_info)) |
157 | #define uv_cpu_hub_info(cpu) (&per_cpu(__uv_hub_info, cpu)) | 159 | #define uv_cpu_hub_info(cpu) (&per_cpu(__uv_hub_info, cpu)) |
158 | 160 | ||
161 | /* | ||
162 | * Hub revisions less than UV2_HUB_REVISION_BASE are UV1 hubs. All UV2 | ||
163 | * hubs have revision numbers greater than or equal to UV2_HUB_REVISION_BASE. | ||
164 | * This is a software convention - NOT the hardware revision numbers in | ||
165 | * the hub chip. | ||
166 | */ | ||
167 | #define UV1_HUB_REVISION_BASE 1 | ||
168 | #define UV2_HUB_REVISION_BASE 3 | ||
169 | |||
170 | static inline int is_uv1_hub(void) | ||
171 | { | ||
172 | return uv_hub_info->hub_revision < UV2_HUB_REVISION_BASE; | ||
173 | } | ||
174 | |||
175 | static inline int is_uv2_hub(void) | ||
176 | { | ||
177 | return uv_hub_info->hub_revision >= UV2_HUB_REVISION_BASE; | ||
178 | } | ||
179 | |||
159 | union uvh_apicid { | 180 | union uvh_apicid { |
160 | unsigned long v; | 181 | unsigned long v; |
161 | struct uvh_apicid_s { | 182 | struct uvh_apicid_s { |
@@ -180,11 +201,25 @@ union uvh_apicid { | |||
180 | #define UV_PNODE_TO_GNODE(p) ((p) |uv_hub_info->gnode_extra) | 201 | #define UV_PNODE_TO_GNODE(p) ((p) |uv_hub_info->gnode_extra) |
181 | #define UV_PNODE_TO_NASID(p) (UV_PNODE_TO_GNODE(p) << 1) | 202 | #define UV_PNODE_TO_NASID(p) (UV_PNODE_TO_GNODE(p) << 1) |
182 | 203 | ||
183 | #define UV_LOCAL_MMR_BASE 0xf4000000UL | 204 | #define UV1_LOCAL_MMR_BASE 0xf4000000UL |
184 | #define UV_GLOBAL_MMR32_BASE 0xf8000000UL | 205 | #define UV1_GLOBAL_MMR32_BASE 0xf8000000UL |
206 | #define UV1_LOCAL_MMR_SIZE (64UL * 1024 * 1024) | ||
207 | #define UV1_GLOBAL_MMR32_SIZE (64UL * 1024 * 1024) | ||
208 | |||
209 | #define UV2_LOCAL_MMR_BASE 0xfa000000UL | ||
210 | #define UV2_GLOBAL_MMR32_BASE 0xfc000000UL | ||
211 | #define UV2_LOCAL_MMR_SIZE (32UL * 1024 * 1024) | ||
212 | #define UV2_GLOBAL_MMR32_SIZE (32UL * 1024 * 1024) | ||
213 | |||
214 | #define UV_LOCAL_MMR_BASE (is_uv1_hub() ? UV1_LOCAL_MMR_BASE \ | ||
215 | : UV2_LOCAL_MMR_BASE) | ||
216 | #define UV_GLOBAL_MMR32_BASE (is_uv1_hub() ? UV1_GLOBAL_MMR32_BASE \ | ||
217 | : UV2_GLOBAL_MMR32_BASE) | ||
218 | #define UV_LOCAL_MMR_SIZE (is_uv1_hub() ? UV1_LOCAL_MMR_SIZE : \ | ||
219 | UV2_LOCAL_MMR_SIZE) | ||
220 | #define UV_GLOBAL_MMR32_SIZE (is_uv1_hub() ? UV1_GLOBAL_MMR32_SIZE :\ | ||
221 | UV2_GLOBAL_MMR32_SIZE) | ||
185 | #define UV_GLOBAL_MMR64_BASE (uv_hub_info->global_mmr_base) | 222 | #define UV_GLOBAL_MMR64_BASE (uv_hub_info->global_mmr_base) |
186 | #define UV_LOCAL_MMR_SIZE (64UL * 1024 * 1024) | ||
187 | #define UV_GLOBAL_MMR32_SIZE (64UL * 1024 * 1024) | ||
188 | 223 | ||
189 | #define UV_GLOBAL_GRU_MMR_BASE 0x4000000 | 224 | #define UV_GLOBAL_GRU_MMR_BASE 0x4000000 |
190 | 225 | ||
@@ -301,6 +336,17 @@ static inline int uv_apicid_to_pnode(int apicid) | |||
301 | } | 336 | } |
302 | 337 | ||
303 | /* | 338 | /* |
339 | * Convert an apicid to the socket number on the blade | ||
340 | */ | ||
341 | static inline int uv_apicid_to_socket(int apicid) | ||
342 | { | ||
343 | if (is_uv1_hub()) | ||
344 | return (apicid >> (uv_hub_info->apic_pnode_shift - 1)) & 1; | ||
345 | else | ||
346 | return 0; | ||
347 | } | ||
348 | |||
349 | /* | ||
304 | * Access global MMRs using the low memory MMR32 space. This region supports | 350 | * Access global MMRs using the low memory MMR32 space. This region supports |
305 | * faster MMR access but not all MMRs are accessible in this space. | 351 | * faster MMR access but not all MMRs are accessible in this space. |
306 | */ | 352 | */ |
@@ -519,14 +565,13 @@ static inline void uv_hub_send_ipi(int pnode, int apicid, int vector) | |||
519 | 565 | ||
520 | /* | 566 | /* |
521 | * Get the minimum revision number of the hub chips within the partition. | 567 | * Get the minimum revision number of the hub chips within the partition. |
522 | * 1 - initial rev 1.0 silicon | 568 | * 1 - UV1 rev 1.0 initial silicon |
523 | * 2 - rev 2.0 production silicon | 569 | * 2 - UV1 rev 2.0 production silicon |
570 | * 3 - UV2 rev 1.0 initial silicon | ||
524 | */ | 571 | */ |
525 | static inline int uv_get_min_hub_revision_id(void) | 572 | static inline int uv_get_min_hub_revision_id(void) |
526 | { | 573 | { |
527 | extern int uv_min_hub_revision_id; | 574 | return uv_hub_info->hub_revision; |
528 | |||
529 | return uv_min_hub_revision_id; | ||
530 | } | 575 | } |
531 | 576 | ||
532 | #endif /* CONFIG_X86_64 */ | 577 | #endif /* CONFIG_X86_64 */ |
diff --git a/arch/x86/include/asm/uv/uv_mmrs.h b/arch/x86/include/asm/uv/uv_mmrs.h index f5bb64a823d7..4be52c863448 100644 --- a/arch/x86/include/asm/uv/uv_mmrs.h +++ b/arch/x86/include/asm/uv/uv_mmrs.h | |||
@@ -11,13 +11,64 @@ | |||
11 | #ifndef _ASM_X86_UV_UV_MMRS_H | 11 | #ifndef _ASM_X86_UV_UV_MMRS_H |
12 | #define _ASM_X86_UV_UV_MMRS_H | 12 | #define _ASM_X86_UV_UV_MMRS_H |
13 | 13 | ||
14 | /* | ||
15 | * This file contains MMR definitions for both UV1 & UV2 hubs. | ||
16 | * | ||
17 | * In general, MMR addresses and structures are identical on both hubs. | ||
18 | * These MMRs are identified as: | ||
19 | * #define UVH_xxx <address> | ||
20 | * union uvh_xxx { | ||
21 | * unsigned long v; | ||
22 | * struct uvh_int_cmpd_s { | ||
23 | * } s; | ||
24 | * }; | ||
25 | * | ||
26 | * If the MMR exists on both hub type but has different addresses or | ||
27 | * contents, the MMR definition is similar to: | ||
28 | * #define UV1H_xxx <uv1 address> | ||
29 | * #define UV2H_xxx <uv2address> | ||
30 | * #define UVH_xxx (is_uv1_hub() ? UV1H_xxx : UV2H_xxx) | ||
31 | * union uvh_xxx { | ||
32 | * unsigned long v; | ||
33 | * struct uv1h_int_cmpd_s { (Common fields only) | ||
34 | * } s; | ||
35 | * struct uv1h_int_cmpd_s { (Full UV1 definition) | ||
36 | * } s1; | ||
37 | * struct uv2h_int_cmpd_s { (Full UV2 definition) | ||
38 | * } s2; | ||
39 | * }; | ||
40 | * | ||
41 | * Only essential difference are enumerated. For example, if the address is | ||
42 | * the same for both UV1 & UV2, only a single #define is generated. Likewise, | ||
43 | * if the contents is the same for both hubs, only the "s" structure is | ||
44 | * generated. | ||
45 | * | ||
46 | * If the MMR exists on ONLY 1 type of hub, no generic definition is | ||
47 | * generated: | ||
48 | * #define UVnH_xxx <uvn address> | ||
49 | * union uvnh_xxx { | ||
50 | * unsigned long v; | ||
51 | * struct uvh_int_cmpd_s { | ||
52 | * } sn; | ||
53 | * }; | ||
54 | */ | ||
55 | |||
14 | #define UV_MMR_ENABLE (1UL << 63) | 56 | #define UV_MMR_ENABLE (1UL << 63) |
15 | 57 | ||
58 | #define UV1_HUB_PART_NUMBER 0x88a5 | ||
59 | #define UV2_HUB_PART_NUMBER 0x8eb8 | ||
60 | |||
61 | /* Compat: if this #define is present, UV headers support UV2 */ | ||
62 | #define UV2_HUB_IS_SUPPORTED 1 | ||
63 | |||
64 | /* KABI compat: if this #define is present, KABI hacks are present */ | ||
65 | #define UV2_HUB_KABI_HACKS 1 | ||
66 | |||
16 | /* ========================================================================= */ | 67 | /* ========================================================================= */ |
17 | /* UVH_BAU_DATA_BROADCAST */ | 68 | /* UVH_BAU_DATA_BROADCAST */ |
18 | /* ========================================================================= */ | 69 | /* ========================================================================= */ |
19 | #define UVH_BAU_DATA_BROADCAST 0x61688UL | 70 | #define UVH_BAU_DATA_BROADCAST 0x61688UL |
20 | #define UVH_BAU_DATA_BROADCAST_32 0x0440 | 71 | #define UVH_BAU_DATA_BROADCAST_32 0x440 |
21 | 72 | ||
22 | #define UVH_BAU_DATA_BROADCAST_ENABLE_SHFT 0 | 73 | #define UVH_BAU_DATA_BROADCAST_ENABLE_SHFT 0 |
23 | #define UVH_BAU_DATA_BROADCAST_ENABLE_MASK 0x0000000000000001UL | 74 | #define UVH_BAU_DATA_BROADCAST_ENABLE_MASK 0x0000000000000001UL |
@@ -34,7 +85,7 @@ union uvh_bau_data_broadcast_u { | |||
34 | /* UVH_BAU_DATA_CONFIG */ | 85 | /* UVH_BAU_DATA_CONFIG */ |
35 | /* ========================================================================= */ | 86 | /* ========================================================================= */ |
36 | #define UVH_BAU_DATA_CONFIG 0x61680UL | 87 | #define UVH_BAU_DATA_CONFIG 0x61680UL |
37 | #define UVH_BAU_DATA_CONFIG_32 0x0438 | 88 | #define UVH_BAU_DATA_CONFIG_32 0x438 |
38 | 89 | ||
39 | #define UVH_BAU_DATA_CONFIG_VECTOR_SHFT 0 | 90 | #define UVH_BAU_DATA_CONFIG_VECTOR_SHFT 0 |
40 | #define UVH_BAU_DATA_CONFIG_VECTOR_MASK 0x00000000000000ffUL | 91 | #define UVH_BAU_DATA_CONFIG_VECTOR_MASK 0x00000000000000ffUL |
@@ -73,125 +124,245 @@ union uvh_bau_data_config_u { | |||
73 | /* UVH_EVENT_OCCURRED0 */ | 124 | /* UVH_EVENT_OCCURRED0 */ |
74 | /* ========================================================================= */ | 125 | /* ========================================================================= */ |
75 | #define UVH_EVENT_OCCURRED0 0x70000UL | 126 | #define UVH_EVENT_OCCURRED0 0x70000UL |
76 | #define UVH_EVENT_OCCURRED0_32 0x005e8 | 127 | #define UVH_EVENT_OCCURRED0_32 0x5e8 |
77 | 128 | ||
78 | #define UVH_EVENT_OCCURRED0_LB_HCERR_SHFT 0 | 129 | #define UV1H_EVENT_OCCURRED0_LB_HCERR_SHFT 0 |
79 | #define UVH_EVENT_OCCURRED0_LB_HCERR_MASK 0x0000000000000001UL | 130 | #define UV1H_EVENT_OCCURRED0_LB_HCERR_MASK 0x0000000000000001UL |
80 | #define UVH_EVENT_OCCURRED0_GR0_HCERR_SHFT 1 | 131 | #define UV1H_EVENT_OCCURRED0_GR0_HCERR_SHFT 1 |
81 | #define UVH_EVENT_OCCURRED0_GR0_HCERR_MASK 0x0000000000000002UL | 132 | #define UV1H_EVENT_OCCURRED0_GR0_HCERR_MASK 0x0000000000000002UL |
82 | #define UVH_EVENT_OCCURRED0_GR1_HCERR_SHFT 2 | 133 | #define UV1H_EVENT_OCCURRED0_GR1_HCERR_SHFT 2 |
83 | #define UVH_EVENT_OCCURRED0_GR1_HCERR_MASK 0x0000000000000004UL | 134 | #define UV1H_EVENT_OCCURRED0_GR1_HCERR_MASK 0x0000000000000004UL |
84 | #define UVH_EVENT_OCCURRED0_LH_HCERR_SHFT 3 | 135 | #define UV1H_EVENT_OCCURRED0_LH_HCERR_SHFT 3 |
85 | #define UVH_EVENT_OCCURRED0_LH_HCERR_MASK 0x0000000000000008UL | 136 | #define UV1H_EVENT_OCCURRED0_LH_HCERR_MASK 0x0000000000000008UL |
86 | #define UVH_EVENT_OCCURRED0_RH_HCERR_SHFT 4 | 137 | #define UV1H_EVENT_OCCURRED0_RH_HCERR_SHFT 4 |
87 | #define UVH_EVENT_OCCURRED0_RH_HCERR_MASK 0x0000000000000010UL | 138 | #define UV1H_EVENT_OCCURRED0_RH_HCERR_MASK 0x0000000000000010UL |
88 | #define UVH_EVENT_OCCURRED0_XN_HCERR_SHFT 5 | 139 | #define UV1H_EVENT_OCCURRED0_XN_HCERR_SHFT 5 |
89 | #define UVH_EVENT_OCCURRED0_XN_HCERR_MASK 0x0000000000000020UL | 140 | #define UV1H_EVENT_OCCURRED0_XN_HCERR_MASK 0x0000000000000020UL |
90 | #define UVH_EVENT_OCCURRED0_SI_HCERR_SHFT 6 | 141 | #define UV1H_EVENT_OCCURRED0_SI_HCERR_SHFT 6 |
91 | #define UVH_EVENT_OCCURRED0_SI_HCERR_MASK 0x0000000000000040UL | 142 | #define UV1H_EVENT_OCCURRED0_SI_HCERR_MASK 0x0000000000000040UL |
92 | #define UVH_EVENT_OCCURRED0_LB_AOERR0_SHFT 7 | 143 | #define UV1H_EVENT_OCCURRED0_LB_AOERR0_SHFT 7 |
93 | #define UVH_EVENT_OCCURRED0_LB_AOERR0_MASK 0x0000000000000080UL | 144 | #define UV1H_EVENT_OCCURRED0_LB_AOERR0_MASK 0x0000000000000080UL |
94 | #define UVH_EVENT_OCCURRED0_GR0_AOERR0_SHFT 8 | 145 | #define UV1H_EVENT_OCCURRED0_GR0_AOERR0_SHFT 8 |
95 | #define UVH_EVENT_OCCURRED0_GR0_AOERR0_MASK 0x0000000000000100UL | 146 | #define UV1H_EVENT_OCCURRED0_GR0_AOERR0_MASK 0x0000000000000100UL |
96 | #define UVH_EVENT_OCCURRED0_GR1_AOERR0_SHFT 9 | 147 | #define UV1H_EVENT_OCCURRED0_GR1_AOERR0_SHFT 9 |
97 | #define UVH_EVENT_OCCURRED0_GR1_AOERR0_MASK 0x0000000000000200UL | 148 | #define UV1H_EVENT_OCCURRED0_GR1_AOERR0_MASK 0x0000000000000200UL |
98 | #define UVH_EVENT_OCCURRED0_LH_AOERR0_SHFT 10 | 149 | #define UV1H_EVENT_OCCURRED0_LH_AOERR0_SHFT 10 |
99 | #define UVH_EVENT_OCCURRED0_LH_AOERR0_MASK 0x0000000000000400UL | 150 | #define UV1H_EVENT_OCCURRED0_LH_AOERR0_MASK 0x0000000000000400UL |
100 | #define UVH_EVENT_OCCURRED0_RH_AOERR0_SHFT 11 | 151 | #define UV1H_EVENT_OCCURRED0_RH_AOERR0_SHFT 11 |
101 | #define UVH_EVENT_OCCURRED0_RH_AOERR0_MASK 0x0000000000000800UL | 152 | #define UV1H_EVENT_OCCURRED0_RH_AOERR0_MASK 0x0000000000000800UL |
102 | #define UVH_EVENT_OCCURRED0_XN_AOERR0_SHFT 12 | 153 | #define UV1H_EVENT_OCCURRED0_XN_AOERR0_SHFT 12 |
103 | #define UVH_EVENT_OCCURRED0_XN_AOERR0_MASK 0x0000000000001000UL | 154 | #define UV1H_EVENT_OCCURRED0_XN_AOERR0_MASK 0x0000000000001000UL |
104 | #define UVH_EVENT_OCCURRED0_SI_AOERR0_SHFT 13 | 155 | #define UV1H_EVENT_OCCURRED0_SI_AOERR0_SHFT 13 |
105 | #define UVH_EVENT_OCCURRED0_SI_AOERR0_MASK 0x0000000000002000UL | 156 | #define UV1H_EVENT_OCCURRED0_SI_AOERR0_MASK 0x0000000000002000UL |
106 | #define UVH_EVENT_OCCURRED0_LB_AOERR1_SHFT 14 | 157 | #define UV1H_EVENT_OCCURRED0_LB_AOERR1_SHFT 14 |
107 | #define UVH_EVENT_OCCURRED0_LB_AOERR1_MASK 0x0000000000004000UL | 158 | #define UV1H_EVENT_OCCURRED0_LB_AOERR1_MASK 0x0000000000004000UL |
108 | #define UVH_EVENT_OCCURRED0_GR0_AOERR1_SHFT 15 | 159 | #define UV1H_EVENT_OCCURRED0_GR0_AOERR1_SHFT 15 |
109 | #define UVH_EVENT_OCCURRED0_GR0_AOERR1_MASK 0x0000000000008000UL | 160 | #define UV1H_EVENT_OCCURRED0_GR0_AOERR1_MASK 0x0000000000008000UL |
110 | #define UVH_EVENT_OCCURRED0_GR1_AOERR1_SHFT 16 | 161 | #define UV1H_EVENT_OCCURRED0_GR1_AOERR1_SHFT 16 |
111 | #define UVH_EVENT_OCCURRED0_GR1_AOERR1_MASK 0x0000000000010000UL | 162 | #define UV1H_EVENT_OCCURRED0_GR1_AOERR1_MASK 0x0000000000010000UL |
112 | #define UVH_EVENT_OCCURRED0_LH_AOERR1_SHFT 17 | 163 | #define UV1H_EVENT_OCCURRED0_LH_AOERR1_SHFT 17 |
113 | #define UVH_EVENT_OCCURRED0_LH_AOERR1_MASK 0x0000000000020000UL | 164 | #define UV1H_EVENT_OCCURRED0_LH_AOERR1_MASK 0x0000000000020000UL |
114 | #define UVH_EVENT_OCCURRED0_RH_AOERR1_SHFT 18 | 165 | #define UV1H_EVENT_OCCURRED0_RH_AOERR1_SHFT 18 |
115 | #define UVH_EVENT_OCCURRED0_RH_AOERR1_MASK 0x0000000000040000UL | 166 | #define UV1H_EVENT_OCCURRED0_RH_AOERR1_MASK 0x0000000000040000UL |
116 | #define UVH_EVENT_OCCURRED0_XN_AOERR1_SHFT 19 | 167 | #define UV1H_EVENT_OCCURRED0_XN_AOERR1_SHFT 19 |
117 | #define UVH_EVENT_OCCURRED0_XN_AOERR1_MASK 0x0000000000080000UL | 168 | #define UV1H_EVENT_OCCURRED0_XN_AOERR1_MASK 0x0000000000080000UL |
118 | #define UVH_EVENT_OCCURRED0_SI_AOERR1_SHFT 20 | 169 | #define UV1H_EVENT_OCCURRED0_SI_AOERR1_SHFT 20 |
119 | #define UVH_EVENT_OCCURRED0_SI_AOERR1_MASK 0x0000000000100000UL | 170 | #define UV1H_EVENT_OCCURRED0_SI_AOERR1_MASK 0x0000000000100000UL |
120 | #define UVH_EVENT_OCCURRED0_RH_VPI_INT_SHFT 21 | 171 | #define UV1H_EVENT_OCCURRED0_RH_VPI_INT_SHFT 21 |
121 | #define UVH_EVENT_OCCURRED0_RH_VPI_INT_MASK 0x0000000000200000UL | 172 | #define UV1H_EVENT_OCCURRED0_RH_VPI_INT_MASK 0x0000000000200000UL |
122 | #define UVH_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_SHFT 22 | 173 | #define UV1H_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_SHFT 22 |
123 | #define UVH_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_MASK 0x0000000000400000UL | 174 | #define UV1H_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_MASK 0x0000000000400000UL |
124 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_0_SHFT 23 | 175 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_0_SHFT 23 |
125 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_0_MASK 0x0000000000800000UL | 176 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_0_MASK 0x0000000000800000UL |
126 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_1_SHFT 24 | 177 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_1_SHFT 24 |
127 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_1_MASK 0x0000000001000000UL | 178 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_1_MASK 0x0000000001000000UL |
128 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_2_SHFT 25 | 179 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_2_SHFT 25 |
129 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_2_MASK 0x0000000002000000UL | 180 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_2_MASK 0x0000000002000000UL |
130 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_3_SHFT 26 | 181 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_3_SHFT 26 |
131 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_3_MASK 0x0000000004000000UL | 182 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_3_MASK 0x0000000004000000UL |
132 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_4_SHFT 27 | 183 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_4_SHFT 27 |
133 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_4_MASK 0x0000000008000000UL | 184 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_4_MASK 0x0000000008000000UL |
134 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_5_SHFT 28 | 185 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_5_SHFT 28 |
135 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_5_MASK 0x0000000010000000UL | 186 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_5_MASK 0x0000000010000000UL |
136 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_6_SHFT 29 | 187 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_6_SHFT 29 |
137 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_6_MASK 0x0000000020000000UL | 188 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_6_MASK 0x0000000020000000UL |
138 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_7_SHFT 30 | 189 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_7_SHFT 30 |
139 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_7_MASK 0x0000000040000000UL | 190 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_7_MASK 0x0000000040000000UL |
140 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_8_SHFT 31 | 191 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_8_SHFT 31 |
141 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_8_MASK 0x0000000080000000UL | 192 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_8_MASK 0x0000000080000000UL |
142 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_9_SHFT 32 | 193 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_9_SHFT 32 |
143 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_9_MASK 0x0000000100000000UL | 194 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_9_MASK 0x0000000100000000UL |
144 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_10_SHFT 33 | 195 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_10_SHFT 33 |
145 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_10_MASK 0x0000000200000000UL | 196 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_10_MASK 0x0000000200000000UL |
146 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_11_SHFT 34 | 197 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_11_SHFT 34 |
147 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_11_MASK 0x0000000400000000UL | 198 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_11_MASK 0x0000000400000000UL |
148 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_12_SHFT 35 | 199 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_12_SHFT 35 |
149 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_12_MASK 0x0000000800000000UL | 200 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_12_MASK 0x0000000800000000UL |
150 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_13_SHFT 36 | 201 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_13_SHFT 36 |
151 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_13_MASK 0x0000001000000000UL | 202 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_13_MASK 0x0000001000000000UL |
152 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_14_SHFT 37 | 203 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_14_SHFT 37 |
153 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_14_MASK 0x0000002000000000UL | 204 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_14_MASK 0x0000002000000000UL |
154 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_15_SHFT 38 | 205 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_15_SHFT 38 |
155 | #define UVH_EVENT_OCCURRED0_LB_IRQ_INT_15_MASK 0x0000004000000000UL | 206 | #define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_15_MASK 0x0000004000000000UL |
156 | #define UVH_EVENT_OCCURRED0_L1_NMI_INT_SHFT 39 | 207 | #define UV1H_EVENT_OCCURRED0_L1_NMI_INT_SHFT 39 |
157 | #define UVH_EVENT_OCCURRED0_L1_NMI_INT_MASK 0x0000008000000000UL | 208 | #define UV1H_EVENT_OCCURRED0_L1_NMI_INT_MASK 0x0000008000000000UL |
158 | #define UVH_EVENT_OCCURRED0_STOP_CLOCK_SHFT 40 | 209 | #define UV1H_EVENT_OCCURRED0_STOP_CLOCK_SHFT 40 |
159 | #define UVH_EVENT_OCCURRED0_STOP_CLOCK_MASK 0x0000010000000000UL | 210 | #define UV1H_EVENT_OCCURRED0_STOP_CLOCK_MASK 0x0000010000000000UL |
160 | #define UVH_EVENT_OCCURRED0_ASIC_TO_L1_SHFT 41 | 211 | #define UV1H_EVENT_OCCURRED0_ASIC_TO_L1_SHFT 41 |
161 | #define UVH_EVENT_OCCURRED0_ASIC_TO_L1_MASK 0x0000020000000000UL | 212 | #define UV1H_EVENT_OCCURRED0_ASIC_TO_L1_MASK 0x0000020000000000UL |
162 | #define UVH_EVENT_OCCURRED0_L1_TO_ASIC_SHFT 42 | 213 | #define UV1H_EVENT_OCCURRED0_L1_TO_ASIC_SHFT 42 |
163 | #define UVH_EVENT_OCCURRED0_L1_TO_ASIC_MASK 0x0000040000000000UL | 214 | #define UV1H_EVENT_OCCURRED0_L1_TO_ASIC_MASK 0x0000040000000000UL |
164 | #define UVH_EVENT_OCCURRED0_LTC_INT_SHFT 43 | 215 | #define UV1H_EVENT_OCCURRED0_LTC_INT_SHFT 43 |
165 | #define UVH_EVENT_OCCURRED0_LTC_INT_MASK 0x0000080000000000UL | 216 | #define UV1H_EVENT_OCCURRED0_LTC_INT_MASK 0x0000080000000000UL |
166 | #define UVH_EVENT_OCCURRED0_LA_SEQ_TRIGGER_SHFT 44 | 217 | #define UV1H_EVENT_OCCURRED0_LA_SEQ_TRIGGER_SHFT 44 |
167 | #define UVH_EVENT_OCCURRED0_LA_SEQ_TRIGGER_MASK 0x0000100000000000UL | 218 | #define UV1H_EVENT_OCCURRED0_LA_SEQ_TRIGGER_MASK 0x0000100000000000UL |
168 | #define UVH_EVENT_OCCURRED0_IPI_INT_SHFT 45 | 219 | #define UV1H_EVENT_OCCURRED0_IPI_INT_SHFT 45 |
169 | #define UVH_EVENT_OCCURRED0_IPI_INT_MASK 0x0000200000000000UL | 220 | #define UV1H_EVENT_OCCURRED0_IPI_INT_MASK 0x0000200000000000UL |
170 | #define UVH_EVENT_OCCURRED0_EXTIO_INT0_SHFT 46 | 221 | #define UV1H_EVENT_OCCURRED0_EXTIO_INT0_SHFT 46 |
171 | #define UVH_EVENT_OCCURRED0_EXTIO_INT0_MASK 0x0000400000000000UL | 222 | #define UV1H_EVENT_OCCURRED0_EXTIO_INT0_MASK 0x0000400000000000UL |
172 | #define UVH_EVENT_OCCURRED0_EXTIO_INT1_SHFT 47 | 223 | #define UV1H_EVENT_OCCURRED0_EXTIO_INT1_SHFT 47 |
173 | #define UVH_EVENT_OCCURRED0_EXTIO_INT1_MASK 0x0000800000000000UL | 224 | #define UV1H_EVENT_OCCURRED0_EXTIO_INT1_MASK 0x0000800000000000UL |
174 | #define UVH_EVENT_OCCURRED0_EXTIO_INT2_SHFT 48 | 225 | #define UV1H_EVENT_OCCURRED0_EXTIO_INT2_SHFT 48 |
175 | #define UVH_EVENT_OCCURRED0_EXTIO_INT2_MASK 0x0001000000000000UL | 226 | #define UV1H_EVENT_OCCURRED0_EXTIO_INT2_MASK 0x0001000000000000UL |
176 | #define UVH_EVENT_OCCURRED0_EXTIO_INT3_SHFT 49 | 227 | #define UV1H_EVENT_OCCURRED0_EXTIO_INT3_SHFT 49 |
177 | #define UVH_EVENT_OCCURRED0_EXTIO_INT3_MASK 0x0002000000000000UL | 228 | #define UV1H_EVENT_OCCURRED0_EXTIO_INT3_MASK 0x0002000000000000UL |
178 | #define UVH_EVENT_OCCURRED0_PROFILE_INT_SHFT 50 | 229 | #define UV1H_EVENT_OCCURRED0_PROFILE_INT_SHFT 50 |
179 | #define UVH_EVENT_OCCURRED0_PROFILE_INT_MASK 0x0004000000000000UL | 230 | #define UV1H_EVENT_OCCURRED0_PROFILE_INT_MASK 0x0004000000000000UL |
180 | #define UVH_EVENT_OCCURRED0_RTC0_SHFT 51 | 231 | #define UV1H_EVENT_OCCURRED0_RTC0_SHFT 51 |
181 | #define UVH_EVENT_OCCURRED0_RTC0_MASK 0x0008000000000000UL | 232 | #define UV1H_EVENT_OCCURRED0_RTC0_MASK 0x0008000000000000UL |
182 | #define UVH_EVENT_OCCURRED0_RTC1_SHFT 52 | 233 | #define UV1H_EVENT_OCCURRED0_RTC1_SHFT 52 |
183 | #define UVH_EVENT_OCCURRED0_RTC1_MASK 0x0010000000000000UL | 234 | #define UV1H_EVENT_OCCURRED0_RTC1_MASK 0x0010000000000000UL |
184 | #define UVH_EVENT_OCCURRED0_RTC2_SHFT 53 | 235 | #define UV1H_EVENT_OCCURRED0_RTC2_SHFT 53 |
185 | #define UVH_EVENT_OCCURRED0_RTC2_MASK 0x0020000000000000UL | 236 | #define UV1H_EVENT_OCCURRED0_RTC2_MASK 0x0020000000000000UL |
186 | #define UVH_EVENT_OCCURRED0_RTC3_SHFT 54 | 237 | #define UV1H_EVENT_OCCURRED0_RTC3_SHFT 54 |
187 | #define UVH_EVENT_OCCURRED0_RTC3_MASK 0x0040000000000000UL | 238 | #define UV1H_EVENT_OCCURRED0_RTC3_MASK 0x0040000000000000UL |
188 | #define UVH_EVENT_OCCURRED0_BAU_DATA_SHFT 55 | 239 | #define UV1H_EVENT_OCCURRED0_BAU_DATA_SHFT 55 |
189 | #define UVH_EVENT_OCCURRED0_BAU_DATA_MASK 0x0080000000000000UL | 240 | #define UV1H_EVENT_OCCURRED0_BAU_DATA_MASK 0x0080000000000000UL |
190 | #define UVH_EVENT_OCCURRED0_POWER_MANAGEMENT_REQ_SHFT 56 | 241 | #define UV1H_EVENT_OCCURRED0_POWER_MANAGEMENT_REQ_SHFT 56 |
191 | #define UVH_EVENT_OCCURRED0_POWER_MANAGEMENT_REQ_MASK 0x0100000000000000UL | 242 | #define UV1H_EVENT_OCCURRED0_POWER_MANAGEMENT_REQ_MASK 0x0100000000000000UL |
243 | |||
244 | #define UV2H_EVENT_OCCURRED0_LB_HCERR_SHFT 0 | ||
245 | #define UV2H_EVENT_OCCURRED0_LB_HCERR_MASK 0x0000000000000001UL | ||
246 | #define UV2H_EVENT_OCCURRED0_QP_HCERR_SHFT 1 | ||
247 | #define UV2H_EVENT_OCCURRED0_QP_HCERR_MASK 0x0000000000000002UL | ||
248 | #define UV2H_EVENT_OCCURRED0_RH_HCERR_SHFT 2 | ||
249 | #define UV2H_EVENT_OCCURRED0_RH_HCERR_MASK 0x0000000000000004UL | ||
250 | #define UV2H_EVENT_OCCURRED0_LH0_HCERR_SHFT 3 | ||
251 | #define UV2H_EVENT_OCCURRED0_LH0_HCERR_MASK 0x0000000000000008UL | ||
252 | #define UV2H_EVENT_OCCURRED0_LH1_HCERR_SHFT 4 | ||
253 | #define UV2H_EVENT_OCCURRED0_LH1_HCERR_MASK 0x0000000000000010UL | ||
254 | #define UV2H_EVENT_OCCURRED0_GR0_HCERR_SHFT 5 | ||
255 | #define UV2H_EVENT_OCCURRED0_GR0_HCERR_MASK 0x0000000000000020UL | ||
256 | #define UV2H_EVENT_OCCURRED0_GR1_HCERR_SHFT 6 | ||
257 | #define UV2H_EVENT_OCCURRED0_GR1_HCERR_MASK 0x0000000000000040UL | ||
258 | #define UV2H_EVENT_OCCURRED0_NI0_HCERR_SHFT 7 | ||
259 | #define UV2H_EVENT_OCCURRED0_NI0_HCERR_MASK 0x0000000000000080UL | ||
260 | #define UV2H_EVENT_OCCURRED0_NI1_HCERR_SHFT 8 | ||
261 | #define UV2H_EVENT_OCCURRED0_NI1_HCERR_MASK 0x0000000000000100UL | ||
262 | #define UV2H_EVENT_OCCURRED0_LB_AOERR0_SHFT 9 | ||
263 | #define UV2H_EVENT_OCCURRED0_LB_AOERR0_MASK 0x0000000000000200UL | ||
264 | #define UV2H_EVENT_OCCURRED0_QP_AOERR0_SHFT 10 | ||
265 | #define UV2H_EVENT_OCCURRED0_QP_AOERR0_MASK 0x0000000000000400UL | ||
266 | #define UV2H_EVENT_OCCURRED0_RH_AOERR0_SHFT 11 | ||
267 | #define UV2H_EVENT_OCCURRED0_RH_AOERR0_MASK 0x0000000000000800UL | ||
268 | #define UV2H_EVENT_OCCURRED0_LH0_AOERR0_SHFT 12 | ||
269 | #define UV2H_EVENT_OCCURRED0_LH0_AOERR0_MASK 0x0000000000001000UL | ||
270 | #define UV2H_EVENT_OCCURRED0_LH1_AOERR0_SHFT 13 | ||
271 | #define UV2H_EVENT_OCCURRED0_LH1_AOERR0_MASK 0x0000000000002000UL | ||
272 | #define UV2H_EVENT_OCCURRED0_GR0_AOERR0_SHFT 14 | ||
273 | #define UV2H_EVENT_OCCURRED0_GR0_AOERR0_MASK 0x0000000000004000UL | ||
274 | #define UV2H_EVENT_OCCURRED0_GR1_AOERR0_SHFT 15 | ||
275 | #define UV2H_EVENT_OCCURRED0_GR1_AOERR0_MASK 0x0000000000008000UL | ||
276 | #define UV2H_EVENT_OCCURRED0_XB_AOERR0_SHFT 16 | ||
277 | #define UV2H_EVENT_OCCURRED0_XB_AOERR0_MASK 0x0000000000010000UL | ||
278 | #define UV2H_EVENT_OCCURRED0_RT_AOERR0_SHFT 17 | ||
279 | #define UV2H_EVENT_OCCURRED0_RT_AOERR0_MASK 0x0000000000020000UL | ||
280 | #define UV2H_EVENT_OCCURRED0_NI0_AOERR0_SHFT 18 | ||
281 | #define UV2H_EVENT_OCCURRED0_NI0_AOERR0_MASK 0x0000000000040000UL | ||
282 | #define UV2H_EVENT_OCCURRED0_NI1_AOERR0_SHFT 19 | ||
283 | #define UV2H_EVENT_OCCURRED0_NI1_AOERR0_MASK 0x0000000000080000UL | ||
284 | #define UV2H_EVENT_OCCURRED0_LB_AOERR1_SHFT 20 | ||
285 | #define UV2H_EVENT_OCCURRED0_LB_AOERR1_MASK 0x0000000000100000UL | ||
286 | #define UV2H_EVENT_OCCURRED0_QP_AOERR1_SHFT 21 | ||
287 | #define UV2H_EVENT_OCCURRED0_QP_AOERR1_MASK 0x0000000000200000UL | ||
288 | #define UV2H_EVENT_OCCURRED0_RH_AOERR1_SHFT 22 | ||
289 | #define UV2H_EVENT_OCCURRED0_RH_AOERR1_MASK 0x0000000000400000UL | ||
290 | #define UV2H_EVENT_OCCURRED0_LH0_AOERR1_SHFT 23 | ||
291 | #define UV2H_EVENT_OCCURRED0_LH0_AOERR1_MASK 0x0000000000800000UL | ||
292 | #define UV2H_EVENT_OCCURRED0_LH1_AOERR1_SHFT 24 | ||
293 | #define UV2H_EVENT_OCCURRED0_LH1_AOERR1_MASK 0x0000000001000000UL | ||
294 | #define UV2H_EVENT_OCCURRED0_GR0_AOERR1_SHFT 25 | ||
295 | #define UV2H_EVENT_OCCURRED0_GR0_AOERR1_MASK 0x0000000002000000UL | ||
296 | #define UV2H_EVENT_OCCURRED0_GR1_AOERR1_SHFT 26 | ||
297 | #define UV2H_EVENT_OCCURRED0_GR1_AOERR1_MASK 0x0000000004000000UL | ||
298 | #define UV2H_EVENT_OCCURRED0_XB_AOERR1_SHFT 27 | ||
299 | #define UV2H_EVENT_OCCURRED0_XB_AOERR1_MASK 0x0000000008000000UL | ||
300 | #define UV2H_EVENT_OCCURRED0_RT_AOERR1_SHFT 28 | ||
301 | #define UV2H_EVENT_OCCURRED0_RT_AOERR1_MASK 0x0000000010000000UL | ||
302 | #define UV2H_EVENT_OCCURRED0_NI0_AOERR1_SHFT 29 | ||
303 | #define UV2H_EVENT_OCCURRED0_NI0_AOERR1_MASK 0x0000000020000000UL | ||
304 | #define UV2H_EVENT_OCCURRED0_NI1_AOERR1_SHFT 30 | ||
305 | #define UV2H_EVENT_OCCURRED0_NI1_AOERR1_MASK 0x0000000040000000UL | ||
306 | #define UV2H_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_SHFT 31 | ||
307 | #define UV2H_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_MASK 0x0000000080000000UL | ||
308 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_0_SHFT 32 | ||
309 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_0_MASK 0x0000000100000000UL | ||
310 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_1_SHFT 33 | ||
311 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_1_MASK 0x0000000200000000UL | ||
312 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_2_SHFT 34 | ||
313 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_2_MASK 0x0000000400000000UL | ||
314 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_3_SHFT 35 | ||
315 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_3_MASK 0x0000000800000000UL | ||
316 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_4_SHFT 36 | ||
317 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_4_MASK 0x0000001000000000UL | ||
318 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_5_SHFT 37 | ||
319 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_5_MASK 0x0000002000000000UL | ||
320 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_6_SHFT 38 | ||
321 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_6_MASK 0x0000004000000000UL | ||
322 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_7_SHFT 39 | ||
323 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_7_MASK 0x0000008000000000UL | ||
324 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_8_SHFT 40 | ||
325 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_8_MASK 0x0000010000000000UL | ||
326 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_9_SHFT 41 | ||
327 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_9_MASK 0x0000020000000000UL | ||
328 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_10_SHFT 42 | ||
329 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_10_MASK 0x0000040000000000UL | ||
330 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_11_SHFT 43 | ||
331 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_11_MASK 0x0000080000000000UL | ||
332 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_12_SHFT 44 | ||
333 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_12_MASK 0x0000100000000000UL | ||
334 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_13_SHFT 45 | ||
335 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_13_MASK 0x0000200000000000UL | ||
336 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_14_SHFT 46 | ||
337 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_14_MASK 0x0000400000000000UL | ||
338 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_15_SHFT 47 | ||
339 | #define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_15_MASK 0x0000800000000000UL | ||
340 | #define UV2H_EVENT_OCCURRED0_L1_NMI_INT_SHFT 48 | ||
341 | #define UV2H_EVENT_OCCURRED0_L1_NMI_INT_MASK 0x0001000000000000UL | ||
342 | #define UV2H_EVENT_OCCURRED0_STOP_CLOCK_SHFT 49 | ||
343 | #define UV2H_EVENT_OCCURRED0_STOP_CLOCK_MASK 0x0002000000000000UL | ||
344 | #define UV2H_EVENT_OCCURRED0_ASIC_TO_L1_SHFT 50 | ||
345 | #define UV2H_EVENT_OCCURRED0_ASIC_TO_L1_MASK 0x0004000000000000UL | ||
346 | #define UV2H_EVENT_OCCURRED0_L1_TO_ASIC_SHFT 51 | ||
347 | #define UV2H_EVENT_OCCURRED0_L1_TO_ASIC_MASK 0x0008000000000000UL | ||
348 | #define UV2H_EVENT_OCCURRED0_LA_SEQ_TRIGGER_SHFT 52 | ||
349 | #define UV2H_EVENT_OCCURRED0_LA_SEQ_TRIGGER_MASK 0x0010000000000000UL | ||
350 | #define UV2H_EVENT_OCCURRED0_IPI_INT_SHFT 53 | ||
351 | #define UV2H_EVENT_OCCURRED0_IPI_INT_MASK 0x0020000000000000UL | ||
352 | #define UV2H_EVENT_OCCURRED0_EXTIO_INT0_SHFT 54 | ||
353 | #define UV2H_EVENT_OCCURRED0_EXTIO_INT0_MASK 0x0040000000000000UL | ||
354 | #define UV2H_EVENT_OCCURRED0_EXTIO_INT1_SHFT 55 | ||
355 | #define UV2H_EVENT_OCCURRED0_EXTIO_INT1_MASK 0x0080000000000000UL | ||
356 | #define UV2H_EVENT_OCCURRED0_EXTIO_INT2_SHFT 56 | ||
357 | #define UV2H_EVENT_OCCURRED0_EXTIO_INT2_MASK 0x0100000000000000UL | ||
358 | #define UV2H_EVENT_OCCURRED0_EXTIO_INT3_SHFT 57 | ||
359 | #define UV2H_EVENT_OCCURRED0_EXTIO_INT3_MASK 0x0200000000000000UL | ||
360 | #define UV2H_EVENT_OCCURRED0_PROFILE_INT_SHFT 58 | ||
361 | #define UV2H_EVENT_OCCURRED0_PROFILE_INT_MASK 0x0400000000000000UL | ||
362 | |||
192 | union uvh_event_occurred0_u { | 363 | union uvh_event_occurred0_u { |
193 | unsigned long v; | 364 | unsigned long v; |
194 | struct uvh_event_occurred0_s { | 365 | struct uv1h_event_occurred0_s { |
195 | unsigned long lb_hcerr : 1; /* RW, W1C */ | 366 | unsigned long lb_hcerr : 1; /* RW, W1C */ |
196 | unsigned long gr0_hcerr : 1; /* RW, W1C */ | 367 | unsigned long gr0_hcerr : 1; /* RW, W1C */ |
197 | unsigned long gr1_hcerr : 1; /* RW, W1C */ | 368 | unsigned long gr1_hcerr : 1; /* RW, W1C */ |
@@ -250,14 +421,76 @@ union uvh_event_occurred0_u { | |||
250 | unsigned long bau_data : 1; /* RW, W1C */ | 421 | unsigned long bau_data : 1; /* RW, W1C */ |
251 | unsigned long power_management_req : 1; /* RW, W1C */ | 422 | unsigned long power_management_req : 1; /* RW, W1C */ |
252 | unsigned long rsvd_57_63 : 7; /* */ | 423 | unsigned long rsvd_57_63 : 7; /* */ |
253 | } s; | 424 | } s1; |
425 | struct uv2h_event_occurred0_s { | ||
426 | unsigned long lb_hcerr : 1; /* RW */ | ||
427 | unsigned long qp_hcerr : 1; /* RW */ | ||
428 | unsigned long rh_hcerr : 1; /* RW */ | ||
429 | unsigned long lh0_hcerr : 1; /* RW */ | ||
430 | unsigned long lh1_hcerr : 1; /* RW */ | ||
431 | unsigned long gr0_hcerr : 1; /* RW */ | ||
432 | unsigned long gr1_hcerr : 1; /* RW */ | ||
433 | unsigned long ni0_hcerr : 1; /* RW */ | ||
434 | unsigned long ni1_hcerr : 1; /* RW */ | ||
435 | unsigned long lb_aoerr0 : 1; /* RW */ | ||
436 | unsigned long qp_aoerr0 : 1; /* RW */ | ||
437 | unsigned long rh_aoerr0 : 1; /* RW */ | ||
438 | unsigned long lh0_aoerr0 : 1; /* RW */ | ||
439 | unsigned long lh1_aoerr0 : 1; /* RW */ | ||
440 | unsigned long gr0_aoerr0 : 1; /* RW */ | ||
441 | unsigned long gr1_aoerr0 : 1; /* RW */ | ||
442 | unsigned long xb_aoerr0 : 1; /* RW */ | ||
443 | unsigned long rt_aoerr0 : 1; /* RW */ | ||
444 | unsigned long ni0_aoerr0 : 1; /* RW */ | ||
445 | unsigned long ni1_aoerr0 : 1; /* RW */ | ||
446 | unsigned long lb_aoerr1 : 1; /* RW */ | ||
447 | unsigned long qp_aoerr1 : 1; /* RW */ | ||
448 | unsigned long rh_aoerr1 : 1; /* RW */ | ||
449 | unsigned long lh0_aoerr1 : 1; /* RW */ | ||
450 | unsigned long lh1_aoerr1 : 1; /* RW */ | ||
451 | unsigned long gr0_aoerr1 : 1; /* RW */ | ||
452 | unsigned long gr1_aoerr1 : 1; /* RW */ | ||
453 | unsigned long xb_aoerr1 : 1; /* RW */ | ||
454 | unsigned long rt_aoerr1 : 1; /* RW */ | ||
455 | unsigned long ni0_aoerr1 : 1; /* RW */ | ||
456 | unsigned long ni1_aoerr1 : 1; /* RW */ | ||
457 | unsigned long system_shutdown_int : 1; /* RW */ | ||
458 | unsigned long lb_irq_int_0 : 1; /* RW */ | ||
459 | unsigned long lb_irq_int_1 : 1; /* RW */ | ||
460 | unsigned long lb_irq_int_2 : 1; /* RW */ | ||
461 | unsigned long lb_irq_int_3 : 1; /* RW */ | ||
462 | unsigned long lb_irq_int_4 : 1; /* RW */ | ||
463 | unsigned long lb_irq_int_5 : 1; /* RW */ | ||
464 | unsigned long lb_irq_int_6 : 1; /* RW */ | ||
465 | unsigned long lb_irq_int_7 : 1; /* RW */ | ||
466 | unsigned long lb_irq_int_8 : 1; /* RW */ | ||
467 | unsigned long lb_irq_int_9 : 1; /* RW */ | ||
468 | unsigned long lb_irq_int_10 : 1; /* RW */ | ||
469 | unsigned long lb_irq_int_11 : 1; /* RW */ | ||
470 | unsigned long lb_irq_int_12 : 1; /* RW */ | ||
471 | unsigned long lb_irq_int_13 : 1; /* RW */ | ||
472 | unsigned long lb_irq_int_14 : 1; /* RW */ | ||
473 | unsigned long lb_irq_int_15 : 1; /* RW */ | ||
474 | unsigned long l1_nmi_int : 1; /* RW */ | ||
475 | unsigned long stop_clock : 1; /* RW */ | ||
476 | unsigned long asic_to_l1 : 1; /* RW */ | ||
477 | unsigned long l1_to_asic : 1; /* RW */ | ||
478 | unsigned long la_seq_trigger : 1; /* RW */ | ||
479 | unsigned long ipi_int : 1; /* RW */ | ||
480 | unsigned long extio_int0 : 1; /* RW */ | ||
481 | unsigned long extio_int1 : 1; /* RW */ | ||
482 | unsigned long extio_int2 : 1; /* RW */ | ||
483 | unsigned long extio_int3 : 1; /* RW */ | ||
484 | unsigned long profile_int : 1; /* RW */ | ||
485 | unsigned long rsvd_59_63 : 5; /* */ | ||
486 | } s2; | ||
254 | }; | 487 | }; |
255 | 488 | ||
256 | /* ========================================================================= */ | 489 | /* ========================================================================= */ |
257 | /* UVH_EVENT_OCCURRED0_ALIAS */ | 490 | /* UVH_EVENT_OCCURRED0_ALIAS */ |
258 | /* ========================================================================= */ | 491 | /* ========================================================================= */ |
259 | #define UVH_EVENT_OCCURRED0_ALIAS 0x0000000000070008UL | 492 | #define UVH_EVENT_OCCURRED0_ALIAS 0x0000000000070008UL |
260 | #define UVH_EVENT_OCCURRED0_ALIAS_32 0x005f0 | 493 | #define UVH_EVENT_OCCURRED0_ALIAS_32 0x5f0 |
261 | 494 | ||
262 | /* ========================================================================= */ | 495 | /* ========================================================================= */ |
263 | /* UVH_GR0_TLB_INT0_CONFIG */ | 496 | /* UVH_GR0_TLB_INT0_CONFIG */ |
@@ -432,8 +665,16 @@ union uvh_int_cmpb_u { | |||
432 | /* ========================================================================= */ | 665 | /* ========================================================================= */ |
433 | #define UVH_INT_CMPC 0x22100UL | 666 | #define UVH_INT_CMPC 0x22100UL |
434 | 667 | ||
435 | #define UVH_INT_CMPC_REAL_TIME_CMPC_SHFT 0 | 668 | #define UV1H_INT_CMPC_REAL_TIME_CMPC_SHFT 0 |
436 | #define UVH_INT_CMPC_REAL_TIME_CMPC_MASK 0x00ffffffffffffffUL | 669 | #define UV2H_INT_CMPC_REAL_TIME_CMPC_SHFT 0 |
670 | #define UVH_INT_CMPC_REAL_TIME_CMPC_SHFT (is_uv1_hub() ? \ | ||
671 | UV1H_INT_CMPC_REAL_TIME_CMPC_SHFT : \ | ||
672 | UV2H_INT_CMPC_REAL_TIME_CMPC_SHFT) | ||
673 | #define UV1H_INT_CMPC_REAL_TIME_CMPC_MASK 0xffffffffffffffUL | ||
674 | #define UV2H_INT_CMPC_REAL_TIME_CMPC_MASK 0xffffffffffffffUL | ||
675 | #define UVH_INT_CMPC_REAL_TIME_CMPC_MASK (is_uv1_hub() ? \ | ||
676 | UV1H_INT_CMPC_REAL_TIME_CMPC_MASK : \ | ||
677 | UV2H_INT_CMPC_REAL_TIME_CMPC_MASK) | ||
437 | 678 | ||
438 | union uvh_int_cmpc_u { | 679 | union uvh_int_cmpc_u { |
439 | unsigned long v; | 680 | unsigned long v; |
@@ -448,8 +689,16 @@ union uvh_int_cmpc_u { | |||
448 | /* ========================================================================= */ | 689 | /* ========================================================================= */ |
449 | #define UVH_INT_CMPD 0x22180UL | 690 | #define UVH_INT_CMPD 0x22180UL |
450 | 691 | ||
451 | #define UVH_INT_CMPD_REAL_TIME_CMPD_SHFT 0 | 692 | #define UV1H_INT_CMPD_REAL_TIME_CMPD_SHFT 0 |
452 | #define UVH_INT_CMPD_REAL_TIME_CMPD_MASK 0x00ffffffffffffffUL | 693 | #define UV2H_INT_CMPD_REAL_TIME_CMPD_SHFT 0 |
694 | #define UVH_INT_CMPD_REAL_TIME_CMPD_SHFT (is_uv1_hub() ? \ | ||
695 | UV1H_INT_CMPD_REAL_TIME_CMPD_SHFT : \ | ||
696 | UV2H_INT_CMPD_REAL_TIME_CMPD_SHFT) | ||
697 | #define UV1H_INT_CMPD_REAL_TIME_CMPD_MASK 0xffffffffffffffUL | ||
698 | #define UV2H_INT_CMPD_REAL_TIME_CMPD_MASK 0xffffffffffffffUL | ||
699 | #define UVH_INT_CMPD_REAL_TIME_CMPD_MASK (is_uv1_hub() ? \ | ||
700 | UV1H_INT_CMPD_REAL_TIME_CMPD_MASK : \ | ||
701 | UV2H_INT_CMPD_REAL_TIME_CMPD_MASK) | ||
453 | 702 | ||
454 | union uvh_int_cmpd_u { | 703 | union uvh_int_cmpd_u { |
455 | unsigned long v; | 704 | unsigned long v; |
@@ -463,7 +712,7 @@ union uvh_int_cmpd_u { | |||
463 | /* UVH_IPI_INT */ | 712 | /* UVH_IPI_INT */ |
464 | /* ========================================================================= */ | 713 | /* ========================================================================= */ |
465 | #define UVH_IPI_INT 0x60500UL | 714 | #define UVH_IPI_INT 0x60500UL |
466 | #define UVH_IPI_INT_32 0x0348 | 715 | #define UVH_IPI_INT_32 0x348 |
467 | 716 | ||
468 | #define UVH_IPI_INT_VECTOR_SHFT 0 | 717 | #define UVH_IPI_INT_VECTOR_SHFT 0 |
469 | #define UVH_IPI_INT_VECTOR_MASK 0x00000000000000ffUL | 718 | #define UVH_IPI_INT_VECTOR_MASK 0x00000000000000ffUL |
@@ -493,7 +742,7 @@ union uvh_ipi_int_u { | |||
493 | /* UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST */ | 742 | /* UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST */ |
494 | /* ========================================================================= */ | 743 | /* ========================================================================= */ |
495 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST 0x320050UL | 744 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST 0x320050UL |
496 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST_32 0x009c0 | 745 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST_32 0x9c0 |
497 | 746 | ||
498 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST_ADDRESS_SHFT 4 | 747 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST_ADDRESS_SHFT 4 |
499 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST_ADDRESS_MASK 0x000007fffffffff0UL | 748 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST_ADDRESS_MASK 0x000007fffffffff0UL |
@@ -515,7 +764,7 @@ union uvh_lb_bau_intd_payload_queue_first_u { | |||
515 | /* UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST */ | 764 | /* UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST */ |
516 | /* ========================================================================= */ | 765 | /* ========================================================================= */ |
517 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST 0x320060UL | 766 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST 0x320060UL |
518 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST_32 0x009c8 | 767 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST_32 0x9c8 |
519 | 768 | ||
520 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST_ADDRESS_SHFT 4 | 769 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST_ADDRESS_SHFT 4 |
521 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST_ADDRESS_MASK 0x000007fffffffff0UL | 770 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST_ADDRESS_MASK 0x000007fffffffff0UL |
@@ -533,7 +782,7 @@ union uvh_lb_bau_intd_payload_queue_last_u { | |||
533 | /* UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL */ | 782 | /* UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL */ |
534 | /* ========================================================================= */ | 783 | /* ========================================================================= */ |
535 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL 0x320070UL | 784 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL 0x320070UL |
536 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL_32 0x009d0 | 785 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL_32 0x9d0 |
537 | 786 | ||
538 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL_ADDRESS_SHFT 4 | 787 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL_ADDRESS_SHFT 4 |
539 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL_ADDRESS_MASK 0x000007fffffffff0UL | 788 | #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL_ADDRESS_MASK 0x000007fffffffff0UL |
@@ -551,7 +800,7 @@ union uvh_lb_bau_intd_payload_queue_tail_u { | |||
551 | /* UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE */ | 800 | /* UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE */ |
552 | /* ========================================================================= */ | 801 | /* ========================================================================= */ |
553 | #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE 0x320080UL | 802 | #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE 0x320080UL |
554 | #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_32 0x0a68 | 803 | #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_32 0xa68 |
555 | 804 | ||
556 | #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_0_SHFT 0 | 805 | #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_0_SHFT 0 |
557 | #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_0_MASK 0x0000000000000001UL | 806 | #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_0_MASK 0x0000000000000001UL |
@@ -585,6 +834,7 @@ union uvh_lb_bau_intd_payload_queue_tail_u { | |||
585 | #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_6_MASK 0x0000000000004000UL | 834 | #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_6_MASK 0x0000000000004000UL |
586 | #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_7_SHFT 15 | 835 | #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_7_SHFT 15 |
587 | #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_7_MASK 0x0000000000008000UL | 836 | #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_7_MASK 0x0000000000008000UL |
837 | |||
588 | union uvh_lb_bau_intd_software_acknowledge_u { | 838 | union uvh_lb_bau_intd_software_acknowledge_u { |
589 | unsigned long v; | 839 | unsigned long v; |
590 | struct uvh_lb_bau_intd_software_acknowledge_s { | 840 | struct uvh_lb_bau_intd_software_acknowledge_s { |
@@ -612,13 +862,13 @@ union uvh_lb_bau_intd_software_acknowledge_u { | |||
612 | /* UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS */ | 862 | /* UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS */ |
613 | /* ========================================================================= */ | 863 | /* ========================================================================= */ |
614 | #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS 0x0000000000320088UL | 864 | #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS 0x0000000000320088UL |
615 | #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS_32 0x0a70 | 865 | #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS_32 0xa70 |
616 | 866 | ||
617 | /* ========================================================================= */ | 867 | /* ========================================================================= */ |
618 | /* UVH_LB_BAU_MISC_CONTROL */ | 868 | /* UVH_LB_BAU_MISC_CONTROL */ |
619 | /* ========================================================================= */ | 869 | /* ========================================================================= */ |
620 | #define UVH_LB_BAU_MISC_CONTROL 0x320170UL | 870 | #define UVH_LB_BAU_MISC_CONTROL 0x320170UL |
621 | #define UVH_LB_BAU_MISC_CONTROL_32 0x00a10 | 871 | #define UVH_LB_BAU_MISC_CONTROL_32 0xa10 |
622 | 872 | ||
623 | #define UVH_LB_BAU_MISC_CONTROL_REJECTION_DELAY_SHFT 0 | 873 | #define UVH_LB_BAU_MISC_CONTROL_REJECTION_DELAY_SHFT 0 |
624 | #define UVH_LB_BAU_MISC_CONTROL_REJECTION_DELAY_MASK 0x00000000000000ffUL | 874 | #define UVH_LB_BAU_MISC_CONTROL_REJECTION_DELAY_MASK 0x00000000000000ffUL |
@@ -628,8 +878,8 @@ union uvh_lb_bau_intd_software_acknowledge_u { | |||
628 | #define UVH_LB_BAU_MISC_CONTROL_FORCE_BROADCAST_MASK 0x0000000000000200UL | 878 | #define UVH_LB_BAU_MISC_CONTROL_FORCE_BROADCAST_MASK 0x0000000000000200UL |
629 | #define UVH_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_SHFT 10 | 879 | #define UVH_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_SHFT 10 |
630 | #define UVH_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_MASK 0x0000000000000400UL | 880 | #define UVH_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_MASK 0x0000000000000400UL |
631 | #define UVH_LB_BAU_MISC_CONTROL_CSI_AGENT_PRESENCE_VECTOR_SHFT 11 | 881 | #define UVH_LB_BAU_MISC_CONTROL_QPI_AGENT_PRESENCE_VECTOR_SHFT 11 |
632 | #define UVH_LB_BAU_MISC_CONTROL_CSI_AGENT_PRESENCE_VECTOR_MASK 0x0000000000003800UL | 882 | #define UVH_LB_BAU_MISC_CONTROL_QPI_AGENT_PRESENCE_VECTOR_MASK 0x0000000000003800UL |
633 | #define UVH_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_SHFT 14 | 883 | #define UVH_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_SHFT 14 |
634 | #define UVH_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_MASK 0x0000000000004000UL | 884 | #define UVH_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_MASK 0x0000000000004000UL |
635 | #define UVH_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT 15 | 885 | #define UVH_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT 15 |
@@ -650,8 +900,86 @@ union uvh_lb_bau_intd_software_acknowledge_u { | |||
650 | #define UVH_LB_BAU_MISC_CONTROL_USE_INCOMING_PRIORITY_MASK 0x0000000008000000UL | 900 | #define UVH_LB_BAU_MISC_CONTROL_USE_INCOMING_PRIORITY_MASK 0x0000000008000000UL |
651 | #define UVH_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_SHFT 28 | 901 | #define UVH_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_SHFT 28 |
652 | #define UVH_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_MASK 0x0000000010000000UL | 902 | #define UVH_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_MASK 0x0000000010000000UL |
653 | #define UVH_LB_BAU_MISC_CONTROL_FUN_SHFT 48 | 903 | |
654 | #define UVH_LB_BAU_MISC_CONTROL_FUN_MASK 0xffff000000000000UL | 904 | #define UV1H_LB_BAU_MISC_CONTROL_REJECTION_DELAY_SHFT 0 |
905 | #define UV1H_LB_BAU_MISC_CONTROL_REJECTION_DELAY_MASK 0x00000000000000ffUL | ||
906 | #define UV1H_LB_BAU_MISC_CONTROL_APIC_MODE_SHFT 8 | ||
907 | #define UV1H_LB_BAU_MISC_CONTROL_APIC_MODE_MASK 0x0000000000000100UL | ||
908 | #define UV1H_LB_BAU_MISC_CONTROL_FORCE_BROADCAST_SHFT 9 | ||
909 | #define UV1H_LB_BAU_MISC_CONTROL_FORCE_BROADCAST_MASK 0x0000000000000200UL | ||
910 | #define UV1H_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_SHFT 10 | ||
911 | #define UV1H_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_MASK 0x0000000000000400UL | ||
912 | #define UV1H_LB_BAU_MISC_CONTROL_QPI_AGENT_PRESENCE_VECTOR_SHFT 11 | ||
913 | #define UV1H_LB_BAU_MISC_CONTROL_QPI_AGENT_PRESENCE_VECTOR_MASK 0x0000000000003800UL | ||
914 | #define UV1H_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_SHFT 14 | ||
915 | #define UV1H_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_MASK 0x0000000000004000UL | ||
916 | #define UV1H_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT 15 | ||
917 | #define UV1H_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_MASK 0x0000000000008000UL | ||
918 | #define UV1H_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT 16 | ||
919 | #define UV1H_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_MASK 0x00000000000f0000UL | ||
920 | #define UV1H_LB_BAU_MISC_CONTROL_ENABLE_DUAL_MAPPING_MODE_SHFT 20 | ||
921 | #define UV1H_LB_BAU_MISC_CONTROL_ENABLE_DUAL_MAPPING_MODE_MASK 0x0000000000100000UL | ||
922 | #define UV1H_LB_BAU_MISC_CONTROL_VGA_IO_PORT_DECODE_ENABLE_SHFT 21 | ||
923 | #define UV1H_LB_BAU_MISC_CONTROL_VGA_IO_PORT_DECODE_ENABLE_MASK 0x0000000000200000UL | ||
924 | #define UV1H_LB_BAU_MISC_CONTROL_VGA_IO_PORT_16_BIT_DECODE_SHFT 22 | ||
925 | #define UV1H_LB_BAU_MISC_CONTROL_VGA_IO_PORT_16_BIT_DECODE_MASK 0x0000000000400000UL | ||
926 | #define UV1H_LB_BAU_MISC_CONTROL_SUPPRESS_DEST_REGISTRATION_SHFT 23 | ||
927 | #define UV1H_LB_BAU_MISC_CONTROL_SUPPRESS_DEST_REGISTRATION_MASK 0x0000000000800000UL | ||
928 | #define UV1H_LB_BAU_MISC_CONTROL_PROGRAMMED_INITIAL_PRIORITY_SHFT 24 | ||
929 | #define UV1H_LB_BAU_MISC_CONTROL_PROGRAMMED_INITIAL_PRIORITY_MASK 0x0000000007000000UL | ||
930 | #define UV1H_LB_BAU_MISC_CONTROL_USE_INCOMING_PRIORITY_SHFT 27 | ||
931 | #define UV1H_LB_BAU_MISC_CONTROL_USE_INCOMING_PRIORITY_MASK 0x0000000008000000UL | ||
932 | #define UV1H_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_SHFT 28 | ||
933 | #define UV1H_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_MASK 0x0000000010000000UL | ||
934 | #define UV1H_LB_BAU_MISC_CONTROL_FUN_SHFT 48 | ||
935 | #define UV1H_LB_BAU_MISC_CONTROL_FUN_MASK 0xffff000000000000UL | ||
936 | |||
937 | #define UV2H_LB_BAU_MISC_CONTROL_REJECTION_DELAY_SHFT 0 | ||
938 | #define UV2H_LB_BAU_MISC_CONTROL_REJECTION_DELAY_MASK 0x00000000000000ffUL | ||
939 | #define UV2H_LB_BAU_MISC_CONTROL_APIC_MODE_SHFT 8 | ||
940 | #define UV2H_LB_BAU_MISC_CONTROL_APIC_MODE_MASK 0x0000000000000100UL | ||
941 | #define UV2H_LB_BAU_MISC_CONTROL_FORCE_BROADCAST_SHFT 9 | ||
942 | #define UV2H_LB_BAU_MISC_CONTROL_FORCE_BROADCAST_MASK 0x0000000000000200UL | ||
943 | #define UV2H_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_SHFT 10 | ||
944 | #define UV2H_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_MASK 0x0000000000000400UL | ||
945 | #define UV2H_LB_BAU_MISC_CONTROL_QPI_AGENT_PRESENCE_VECTOR_SHFT 11 | ||
946 | #define UV2H_LB_BAU_MISC_CONTROL_QPI_AGENT_PRESENCE_VECTOR_MASK 0x0000000000003800UL | ||
947 | #define UV2H_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_SHFT 14 | ||
948 | #define UV2H_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_MASK 0x0000000000004000UL | ||
949 | #define UV2H_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT 15 | ||
950 | #define UV2H_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_MASK 0x0000000000008000UL | ||
951 | #define UV2H_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT 16 | ||
952 | #define UV2H_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_MASK 0x00000000000f0000UL | ||
953 | #define UV2H_LB_BAU_MISC_CONTROL_ENABLE_DUAL_MAPPING_MODE_SHFT 20 | ||
954 | #define UV2H_LB_BAU_MISC_CONTROL_ENABLE_DUAL_MAPPING_MODE_MASK 0x0000000000100000UL | ||
955 | #define UV2H_LB_BAU_MISC_CONTROL_VGA_IO_PORT_DECODE_ENABLE_SHFT 21 | ||
956 | #define UV2H_LB_BAU_MISC_CONTROL_VGA_IO_PORT_DECODE_ENABLE_MASK 0x0000000000200000UL | ||
957 | #define UV2H_LB_BAU_MISC_CONTROL_VGA_IO_PORT_16_BIT_DECODE_SHFT 22 | ||
958 | #define UV2H_LB_BAU_MISC_CONTROL_VGA_IO_PORT_16_BIT_DECODE_MASK 0x0000000000400000UL | ||
959 | #define UV2H_LB_BAU_MISC_CONTROL_SUPPRESS_DEST_REGISTRATION_SHFT 23 | ||
960 | #define UV2H_LB_BAU_MISC_CONTROL_SUPPRESS_DEST_REGISTRATION_MASK 0x0000000000800000UL | ||
961 | #define UV2H_LB_BAU_MISC_CONTROL_PROGRAMMED_INITIAL_PRIORITY_SHFT 24 | ||
962 | #define UV2H_LB_BAU_MISC_CONTROL_PROGRAMMED_INITIAL_PRIORITY_MASK 0x0000000007000000UL | ||
963 | #define UV2H_LB_BAU_MISC_CONTROL_USE_INCOMING_PRIORITY_SHFT 27 | ||
964 | #define UV2H_LB_BAU_MISC_CONTROL_USE_INCOMING_PRIORITY_MASK 0x0000000008000000UL | ||
965 | #define UV2H_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_SHFT 28 | ||
966 | #define UV2H_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_MASK 0x0000000010000000UL | ||
967 | #define UV2H_LB_BAU_MISC_CONTROL_ENABLE_AUTOMATIC_APIC_MODE_SELECTION_SHFT 29 | ||
968 | #define UV2H_LB_BAU_MISC_CONTROL_ENABLE_AUTOMATIC_APIC_MODE_SELECTION_MASK 0x0000000020000000UL | ||
969 | #define UV2H_LB_BAU_MISC_CONTROL_APIC_MODE_STATUS_SHFT 30 | ||
970 | #define UV2H_LB_BAU_MISC_CONTROL_APIC_MODE_STATUS_MASK 0x0000000040000000UL | ||
971 | #define UV2H_LB_BAU_MISC_CONTROL_SUPPRESS_INTERRUPTS_TO_SELF_SHFT 31 | ||
972 | #define UV2H_LB_BAU_MISC_CONTROL_SUPPRESS_INTERRUPTS_TO_SELF_MASK 0x0000000080000000UL | ||
973 | #define UV2H_LB_BAU_MISC_CONTROL_ENABLE_LOCK_BASED_SYSTEM_FLUSH_SHFT 32 | ||
974 | #define UV2H_LB_BAU_MISC_CONTROL_ENABLE_LOCK_BASED_SYSTEM_FLUSH_MASK 0x0000000100000000UL | ||
975 | #define UV2H_LB_BAU_MISC_CONTROL_ENABLE_EXTENDED_SB_STATUS_SHFT 33 | ||
976 | #define UV2H_LB_BAU_MISC_CONTROL_ENABLE_EXTENDED_SB_STATUS_MASK 0x0000000200000000UL | ||
977 | #define UV2H_LB_BAU_MISC_CONTROL_SUPPRESS_INT_PRIO_UDT_TO_SELF_SHFT 34 | ||
978 | #define UV2H_LB_BAU_MISC_CONTROL_SUPPRESS_INT_PRIO_UDT_TO_SELF_MASK 0x0000000400000000UL | ||
979 | #define UV2H_LB_BAU_MISC_CONTROL_USE_LEGACY_DESCRIPTOR_FORMATS_SHFT 35 | ||
980 | #define UV2H_LB_BAU_MISC_CONTROL_USE_LEGACY_DESCRIPTOR_FORMATS_MASK 0x0000000800000000UL | ||
981 | #define UV2H_LB_BAU_MISC_CONTROL_FUN_SHFT 48 | ||
982 | #define UV2H_LB_BAU_MISC_CONTROL_FUN_MASK 0xffff000000000000UL | ||
655 | 983 | ||
656 | union uvh_lb_bau_misc_control_u { | 984 | union uvh_lb_bau_misc_control_u { |
657 | unsigned long v; | 985 | unsigned long v; |
@@ -660,7 +988,25 @@ union uvh_lb_bau_misc_control_u { | |||
660 | unsigned long apic_mode : 1; /* RW */ | 988 | unsigned long apic_mode : 1; /* RW */ |
661 | unsigned long force_broadcast : 1; /* RW */ | 989 | unsigned long force_broadcast : 1; /* RW */ |
662 | unsigned long force_lock_nop : 1; /* RW */ | 990 | unsigned long force_lock_nop : 1; /* RW */ |
663 | unsigned long csi_agent_presence_vector : 3; /* RW */ | 991 | unsigned long qpi_agent_presence_vector : 3; /* RW */ |
992 | unsigned long descriptor_fetch_mode : 1; /* RW */ | ||
993 | unsigned long enable_intd_soft_ack_mode : 1; /* RW */ | ||
994 | unsigned long intd_soft_ack_timeout_period : 4; /* RW */ | ||
995 | unsigned long enable_dual_mapping_mode : 1; /* RW */ | ||
996 | unsigned long vga_io_port_decode_enable : 1; /* RW */ | ||
997 | unsigned long vga_io_port_16_bit_decode : 1; /* RW */ | ||
998 | unsigned long suppress_dest_registration : 1; /* RW */ | ||
999 | unsigned long programmed_initial_priority : 3; /* RW */ | ||
1000 | unsigned long use_incoming_priority : 1; /* RW */ | ||
1001 | unsigned long enable_programmed_initial_priority : 1; /* RW */ | ||
1002 | unsigned long rsvd_29_63 : 35; | ||
1003 | } s; | ||
1004 | struct uv1h_lb_bau_misc_control_s { | ||
1005 | unsigned long rejection_delay : 8; /* RW */ | ||
1006 | unsigned long apic_mode : 1; /* RW */ | ||
1007 | unsigned long force_broadcast : 1; /* RW */ | ||
1008 | unsigned long force_lock_nop : 1; /* RW */ | ||
1009 | unsigned long qpi_agent_presence_vector : 3; /* RW */ | ||
664 | unsigned long descriptor_fetch_mode : 1; /* RW */ | 1010 | unsigned long descriptor_fetch_mode : 1; /* RW */ |
665 | unsigned long enable_intd_soft_ack_mode : 1; /* RW */ | 1011 | unsigned long enable_intd_soft_ack_mode : 1; /* RW */ |
666 | unsigned long intd_soft_ack_timeout_period : 4; /* RW */ | 1012 | unsigned long intd_soft_ack_timeout_period : 4; /* RW */ |
@@ -673,14 +1019,40 @@ union uvh_lb_bau_misc_control_u { | |||
673 | unsigned long enable_programmed_initial_priority : 1; /* RW */ | 1019 | unsigned long enable_programmed_initial_priority : 1; /* RW */ |
674 | unsigned long rsvd_29_47 : 19; /* */ | 1020 | unsigned long rsvd_29_47 : 19; /* */ |
675 | unsigned long fun : 16; /* RW */ | 1021 | unsigned long fun : 16; /* RW */ |
676 | } s; | 1022 | } s1; |
1023 | struct uv2h_lb_bau_misc_control_s { | ||
1024 | unsigned long rejection_delay : 8; /* RW */ | ||
1025 | unsigned long apic_mode : 1; /* RW */ | ||
1026 | unsigned long force_broadcast : 1; /* RW */ | ||
1027 | unsigned long force_lock_nop : 1; /* RW */ | ||
1028 | unsigned long qpi_agent_presence_vector : 3; /* RW */ | ||
1029 | unsigned long descriptor_fetch_mode : 1; /* RW */ | ||
1030 | unsigned long enable_intd_soft_ack_mode : 1; /* RW */ | ||
1031 | unsigned long intd_soft_ack_timeout_period : 4; /* RW */ | ||
1032 | unsigned long enable_dual_mapping_mode : 1; /* RW */ | ||
1033 | unsigned long vga_io_port_decode_enable : 1; /* RW */ | ||
1034 | unsigned long vga_io_port_16_bit_decode : 1; /* RW */ | ||
1035 | unsigned long suppress_dest_registration : 1; /* RW */ | ||
1036 | unsigned long programmed_initial_priority : 3; /* RW */ | ||
1037 | unsigned long use_incoming_priority : 1; /* RW */ | ||
1038 | unsigned long enable_programmed_initial_priority : 1; /* RW */ | ||
1039 | unsigned long enable_automatic_apic_mode_selection : 1; /* RW */ | ||
1040 | unsigned long apic_mode_status : 1; /* RO */ | ||
1041 | unsigned long suppress_interrupts_to_self : 1; /* RW */ | ||
1042 | unsigned long enable_lock_based_system_flush : 1; /* RW */ | ||
1043 | unsigned long enable_extended_sb_status : 1; /* RW */ | ||
1044 | unsigned long suppress_int_prio_udt_to_self : 1; /* RW */ | ||
1045 | unsigned long use_legacy_descriptor_formats : 1; /* RW */ | ||
1046 | unsigned long rsvd_36_47 : 12; /* */ | ||
1047 | unsigned long fun : 16; /* RW */ | ||
1048 | } s2; | ||
677 | }; | 1049 | }; |
678 | 1050 | ||
679 | /* ========================================================================= */ | 1051 | /* ========================================================================= */ |
680 | /* UVH_LB_BAU_SB_ACTIVATION_CONTROL */ | 1052 | /* UVH_LB_BAU_SB_ACTIVATION_CONTROL */ |
681 | /* ========================================================================= */ | 1053 | /* ========================================================================= */ |
682 | #define UVH_LB_BAU_SB_ACTIVATION_CONTROL 0x320020UL | 1054 | #define UVH_LB_BAU_SB_ACTIVATION_CONTROL 0x320020UL |
683 | #define UVH_LB_BAU_SB_ACTIVATION_CONTROL_32 0x009a8 | 1055 | #define UVH_LB_BAU_SB_ACTIVATION_CONTROL_32 0x9a8 |
684 | 1056 | ||
685 | #define UVH_LB_BAU_SB_ACTIVATION_CONTROL_INDEX_SHFT 0 | 1057 | #define UVH_LB_BAU_SB_ACTIVATION_CONTROL_INDEX_SHFT 0 |
686 | #define UVH_LB_BAU_SB_ACTIVATION_CONTROL_INDEX_MASK 0x000000000000003fUL | 1058 | #define UVH_LB_BAU_SB_ACTIVATION_CONTROL_INDEX_MASK 0x000000000000003fUL |
@@ -703,7 +1075,7 @@ union uvh_lb_bau_sb_activation_control_u { | |||
703 | /* UVH_LB_BAU_SB_ACTIVATION_STATUS_0 */ | 1075 | /* UVH_LB_BAU_SB_ACTIVATION_STATUS_0 */ |
704 | /* ========================================================================= */ | 1076 | /* ========================================================================= */ |
705 | #define UVH_LB_BAU_SB_ACTIVATION_STATUS_0 0x320030UL | 1077 | #define UVH_LB_BAU_SB_ACTIVATION_STATUS_0 0x320030UL |
706 | #define UVH_LB_BAU_SB_ACTIVATION_STATUS_0_32 0x009b0 | 1078 | #define UVH_LB_BAU_SB_ACTIVATION_STATUS_0_32 0x9b0 |
707 | 1079 | ||
708 | #define UVH_LB_BAU_SB_ACTIVATION_STATUS_0_STATUS_SHFT 0 | 1080 | #define UVH_LB_BAU_SB_ACTIVATION_STATUS_0_STATUS_SHFT 0 |
709 | #define UVH_LB_BAU_SB_ACTIVATION_STATUS_0_STATUS_MASK 0xffffffffffffffffUL | 1081 | #define UVH_LB_BAU_SB_ACTIVATION_STATUS_0_STATUS_MASK 0xffffffffffffffffUL |
@@ -719,7 +1091,7 @@ union uvh_lb_bau_sb_activation_status_0_u { | |||
719 | /* UVH_LB_BAU_SB_ACTIVATION_STATUS_1 */ | 1091 | /* UVH_LB_BAU_SB_ACTIVATION_STATUS_1 */ |
720 | /* ========================================================================= */ | 1092 | /* ========================================================================= */ |
721 | #define UVH_LB_BAU_SB_ACTIVATION_STATUS_1 0x320040UL | 1093 | #define UVH_LB_BAU_SB_ACTIVATION_STATUS_1 0x320040UL |
722 | #define UVH_LB_BAU_SB_ACTIVATION_STATUS_1_32 0x009b8 | 1094 | #define UVH_LB_BAU_SB_ACTIVATION_STATUS_1_32 0x9b8 |
723 | 1095 | ||
724 | #define UVH_LB_BAU_SB_ACTIVATION_STATUS_1_STATUS_SHFT 0 | 1096 | #define UVH_LB_BAU_SB_ACTIVATION_STATUS_1_STATUS_SHFT 0 |
725 | #define UVH_LB_BAU_SB_ACTIVATION_STATUS_1_STATUS_MASK 0xffffffffffffffffUL | 1097 | #define UVH_LB_BAU_SB_ACTIVATION_STATUS_1_STATUS_MASK 0xffffffffffffffffUL |
@@ -735,7 +1107,7 @@ union uvh_lb_bau_sb_activation_status_1_u { | |||
735 | /* UVH_LB_BAU_SB_DESCRIPTOR_BASE */ | 1107 | /* UVH_LB_BAU_SB_DESCRIPTOR_BASE */ |
736 | /* ========================================================================= */ | 1108 | /* ========================================================================= */ |
737 | #define UVH_LB_BAU_SB_DESCRIPTOR_BASE 0x320010UL | 1109 | #define UVH_LB_BAU_SB_DESCRIPTOR_BASE 0x320010UL |
738 | #define UVH_LB_BAU_SB_DESCRIPTOR_BASE_32 0x009a0 | 1110 | #define UVH_LB_BAU_SB_DESCRIPTOR_BASE_32 0x9a0 |
739 | 1111 | ||
740 | #define UVH_LB_BAU_SB_DESCRIPTOR_BASE_PAGE_ADDRESS_SHFT 12 | 1112 | #define UVH_LB_BAU_SB_DESCRIPTOR_BASE_PAGE_ADDRESS_SHFT 12 |
741 | #define UVH_LB_BAU_SB_DESCRIPTOR_BASE_PAGE_ADDRESS_MASK 0x000007fffffff000UL | 1113 | #define UVH_LB_BAU_SB_DESCRIPTOR_BASE_PAGE_ADDRESS_MASK 0x000007fffffff000UL |
@@ -754,23 +1126,6 @@ union uvh_lb_bau_sb_descriptor_base_u { | |||
754 | }; | 1126 | }; |
755 | 1127 | ||
756 | /* ========================================================================= */ | 1128 | /* ========================================================================= */ |
757 | /* UVH_LB_TARGET_PHYSICAL_APIC_ID_MASK */ | ||
758 | /* ========================================================================= */ | ||
759 | #define UVH_LB_TARGET_PHYSICAL_APIC_ID_MASK 0x320130UL | ||
760 | #define UVH_LB_TARGET_PHYSICAL_APIC_ID_MASK_32 0x009f0 | ||
761 | |||
762 | #define UVH_LB_TARGET_PHYSICAL_APIC_ID_MASK_BIT_ENABLES_SHFT 0 | ||
763 | #define UVH_LB_TARGET_PHYSICAL_APIC_ID_MASK_BIT_ENABLES_MASK 0x00000000ffffffffUL | ||
764 | |||
765 | union uvh_lb_target_physical_apic_id_mask_u { | ||
766 | unsigned long v; | ||
767 | struct uvh_lb_target_physical_apic_id_mask_s { | ||
768 | unsigned long bit_enables : 32; /* RW */ | ||
769 | unsigned long rsvd_32_63 : 32; /* */ | ||
770 | } s; | ||
771 | }; | ||
772 | |||
773 | /* ========================================================================= */ | ||
774 | /* UVH_NODE_ID */ | 1129 | /* UVH_NODE_ID */ |
775 | /* ========================================================================= */ | 1130 | /* ========================================================================= */ |
776 | #define UVH_NODE_ID 0x0UL | 1131 | #define UVH_NODE_ID 0x0UL |
@@ -785,10 +1140,36 @@ union uvh_lb_target_physical_apic_id_mask_u { | |||
785 | #define UVH_NODE_ID_REVISION_MASK 0x00000000f0000000UL | 1140 | #define UVH_NODE_ID_REVISION_MASK 0x00000000f0000000UL |
786 | #define UVH_NODE_ID_NODE_ID_SHFT 32 | 1141 | #define UVH_NODE_ID_NODE_ID_SHFT 32 |
787 | #define UVH_NODE_ID_NODE_ID_MASK 0x00007fff00000000UL | 1142 | #define UVH_NODE_ID_NODE_ID_MASK 0x00007fff00000000UL |
788 | #define UVH_NODE_ID_NODES_PER_BIT_SHFT 48 | 1143 | |
789 | #define UVH_NODE_ID_NODES_PER_BIT_MASK 0x007f000000000000UL | 1144 | #define UV1H_NODE_ID_FORCE1_SHFT 0 |
790 | #define UVH_NODE_ID_NI_PORT_SHFT 56 | 1145 | #define UV1H_NODE_ID_FORCE1_MASK 0x0000000000000001UL |
791 | #define UVH_NODE_ID_NI_PORT_MASK 0x0f00000000000000UL | 1146 | #define UV1H_NODE_ID_MANUFACTURER_SHFT 1 |
1147 | #define UV1H_NODE_ID_MANUFACTURER_MASK 0x0000000000000ffeUL | ||
1148 | #define UV1H_NODE_ID_PART_NUMBER_SHFT 12 | ||
1149 | #define UV1H_NODE_ID_PART_NUMBER_MASK 0x000000000ffff000UL | ||
1150 | #define UV1H_NODE_ID_REVISION_SHFT 28 | ||
1151 | #define UV1H_NODE_ID_REVISION_MASK 0x00000000f0000000UL | ||
1152 | #define UV1H_NODE_ID_NODE_ID_SHFT 32 | ||
1153 | #define UV1H_NODE_ID_NODE_ID_MASK 0x00007fff00000000UL | ||
1154 | #define UV1H_NODE_ID_NODES_PER_BIT_SHFT 48 | ||
1155 | #define UV1H_NODE_ID_NODES_PER_BIT_MASK 0x007f000000000000UL | ||
1156 | #define UV1H_NODE_ID_NI_PORT_SHFT 56 | ||
1157 | #define UV1H_NODE_ID_NI_PORT_MASK 0x0f00000000000000UL | ||
1158 | |||
1159 | #define UV2H_NODE_ID_FORCE1_SHFT 0 | ||
1160 | #define UV2H_NODE_ID_FORCE1_MASK 0x0000000000000001UL | ||
1161 | #define UV2H_NODE_ID_MANUFACTURER_SHFT 1 | ||
1162 | #define UV2H_NODE_ID_MANUFACTURER_MASK 0x0000000000000ffeUL | ||
1163 | #define UV2H_NODE_ID_PART_NUMBER_SHFT 12 | ||
1164 | #define UV2H_NODE_ID_PART_NUMBER_MASK 0x000000000ffff000UL | ||
1165 | #define UV2H_NODE_ID_REVISION_SHFT 28 | ||
1166 | #define UV2H_NODE_ID_REVISION_MASK 0x00000000f0000000UL | ||
1167 | #define UV2H_NODE_ID_NODE_ID_SHFT 32 | ||
1168 | #define UV2H_NODE_ID_NODE_ID_MASK 0x00007fff00000000UL | ||
1169 | #define UV2H_NODE_ID_NODES_PER_BIT_SHFT 50 | ||
1170 | #define UV2H_NODE_ID_NODES_PER_BIT_MASK 0x01fc000000000000UL | ||
1171 | #define UV2H_NODE_ID_NI_PORT_SHFT 57 | ||
1172 | #define UV2H_NODE_ID_NI_PORT_MASK 0x3e00000000000000UL | ||
792 | 1173 | ||
793 | union uvh_node_id_u { | 1174 | union uvh_node_id_u { |
794 | unsigned long v; | 1175 | unsigned long v; |
@@ -798,12 +1179,31 @@ union uvh_node_id_u { | |||
798 | unsigned long part_number : 16; /* RO */ | 1179 | unsigned long part_number : 16; /* RO */ |
799 | unsigned long revision : 4; /* RO */ | 1180 | unsigned long revision : 4; /* RO */ |
800 | unsigned long node_id : 15; /* RW */ | 1181 | unsigned long node_id : 15; /* RW */ |
1182 | unsigned long rsvd_47_63 : 17; | ||
1183 | } s; | ||
1184 | struct uv1h_node_id_s { | ||
1185 | unsigned long force1 : 1; /* RO */ | ||
1186 | unsigned long manufacturer : 11; /* RO */ | ||
1187 | unsigned long part_number : 16; /* RO */ | ||
1188 | unsigned long revision : 4; /* RO */ | ||
1189 | unsigned long node_id : 15; /* RW */ | ||
801 | unsigned long rsvd_47 : 1; /* */ | 1190 | unsigned long rsvd_47 : 1; /* */ |
802 | unsigned long nodes_per_bit : 7; /* RW */ | 1191 | unsigned long nodes_per_bit : 7; /* RW */ |
803 | unsigned long rsvd_55 : 1; /* */ | 1192 | unsigned long rsvd_55 : 1; /* */ |
804 | unsigned long ni_port : 4; /* RO */ | 1193 | unsigned long ni_port : 4; /* RO */ |
805 | unsigned long rsvd_60_63 : 4; /* */ | 1194 | unsigned long rsvd_60_63 : 4; /* */ |
806 | } s; | 1195 | } s1; |
1196 | struct uv2h_node_id_s { | ||
1197 | unsigned long force1 : 1; /* RO */ | ||
1198 | unsigned long manufacturer : 11; /* RO */ | ||
1199 | unsigned long part_number : 16; /* RO */ | ||
1200 | unsigned long revision : 4; /* RO */ | ||
1201 | unsigned long node_id : 15; /* RW */ | ||
1202 | unsigned long rsvd_47_49 : 3; /* */ | ||
1203 | unsigned long nodes_per_bit : 7; /* RO */ | ||
1204 | unsigned long ni_port : 5; /* RO */ | ||
1205 | unsigned long rsvd_62_63 : 2; /* */ | ||
1206 | } s2; | ||
807 | }; | 1207 | }; |
808 | 1208 | ||
809 | /* ========================================================================= */ | 1209 | /* ========================================================================= */ |
@@ -954,18 +1354,38 @@ union uvh_rh_gam_alias210_redirect_config_2_mmr_u { | |||
954 | #define UVH_RH_GAM_CONFIG_MMR_M_SKT_MASK 0x000000000000003fUL | 1354 | #define UVH_RH_GAM_CONFIG_MMR_M_SKT_MASK 0x000000000000003fUL |
955 | #define UVH_RH_GAM_CONFIG_MMR_N_SKT_SHFT 6 | 1355 | #define UVH_RH_GAM_CONFIG_MMR_N_SKT_SHFT 6 |
956 | #define UVH_RH_GAM_CONFIG_MMR_N_SKT_MASK 0x00000000000003c0UL | 1356 | #define UVH_RH_GAM_CONFIG_MMR_N_SKT_MASK 0x00000000000003c0UL |
957 | #define UVH_RH_GAM_CONFIG_MMR_MMIOL_CFG_SHFT 12 | 1357 | |
958 | #define UVH_RH_GAM_CONFIG_MMR_MMIOL_CFG_MASK 0x0000000000001000UL | 1358 | #define UV1H_RH_GAM_CONFIG_MMR_M_SKT_SHFT 0 |
1359 | #define UV1H_RH_GAM_CONFIG_MMR_M_SKT_MASK 0x000000000000003fUL | ||
1360 | #define UV1H_RH_GAM_CONFIG_MMR_N_SKT_SHFT 6 | ||
1361 | #define UV1H_RH_GAM_CONFIG_MMR_N_SKT_MASK 0x00000000000003c0UL | ||
1362 | #define UV1H_RH_GAM_CONFIG_MMR_MMIOL_CFG_SHFT 12 | ||
1363 | #define UV1H_RH_GAM_CONFIG_MMR_MMIOL_CFG_MASK 0x0000000000001000UL | ||
1364 | |||
1365 | #define UV2H_RH_GAM_CONFIG_MMR_M_SKT_SHFT 0 | ||
1366 | #define UV2H_RH_GAM_CONFIG_MMR_M_SKT_MASK 0x000000000000003fUL | ||
1367 | #define UV2H_RH_GAM_CONFIG_MMR_N_SKT_SHFT 6 | ||
1368 | #define UV2H_RH_GAM_CONFIG_MMR_N_SKT_MASK 0x00000000000003c0UL | ||
959 | 1369 | ||
960 | union uvh_rh_gam_config_mmr_u { | 1370 | union uvh_rh_gam_config_mmr_u { |
961 | unsigned long v; | 1371 | unsigned long v; |
962 | struct uvh_rh_gam_config_mmr_s { | 1372 | struct uvh_rh_gam_config_mmr_s { |
963 | unsigned long m_skt : 6; /* RW */ | 1373 | unsigned long m_skt : 6; /* RW */ |
964 | unsigned long n_skt : 4; /* RW */ | 1374 | unsigned long n_skt : 4; /* RW */ |
1375 | unsigned long rsvd_10_63 : 54; | ||
1376 | } s; | ||
1377 | struct uv1h_rh_gam_config_mmr_s { | ||
1378 | unsigned long m_skt : 6; /* RW */ | ||
1379 | unsigned long n_skt : 4; /* RW */ | ||
965 | unsigned long rsvd_10_11: 2; /* */ | 1380 | unsigned long rsvd_10_11: 2; /* */ |
966 | unsigned long mmiol_cfg : 1; /* RW */ | 1381 | unsigned long mmiol_cfg : 1; /* RW */ |
967 | unsigned long rsvd_13_63: 51; /* */ | 1382 | unsigned long rsvd_13_63: 51; /* */ |
968 | } s; | 1383 | } s1; |
1384 | struct uv2h_rh_gam_config_mmr_s { | ||
1385 | unsigned long m_skt : 6; /* RW */ | ||
1386 | unsigned long n_skt : 4; /* RW */ | ||
1387 | unsigned long rsvd_10_63: 54; /* */ | ||
1388 | } s2; | ||
969 | }; | 1389 | }; |
970 | 1390 | ||
971 | /* ========================================================================= */ | 1391 | /* ========================================================================= */ |
@@ -975,25 +1395,49 @@ union uvh_rh_gam_config_mmr_u { | |||
975 | 1395 | ||
976 | #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT 28 | 1396 | #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT 28 |
977 | #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffff0000000UL | 1397 | #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffff0000000UL |
978 | #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_GR4_SHFT 48 | 1398 | |
979 | #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_GR4_MASK 0x0001000000000000UL | 1399 | #define UV1H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT 28 |
980 | #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_N_GRU_SHFT 52 | 1400 | #define UV1H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffff0000000UL |
981 | #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_N_GRU_MASK 0x00f0000000000000UL | 1401 | #define UV1H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_GR4_SHFT 48 |
982 | #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 | 1402 | #define UV1H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_GR4_MASK 0x0001000000000000UL |
983 | #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL | 1403 | #define UV1H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_N_GRU_SHFT 52 |
1404 | #define UV1H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_N_GRU_MASK 0x00f0000000000000UL | ||
1405 | #define UV1H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 | ||
1406 | #define UV1H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL | ||
1407 | |||
1408 | #define UV2H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT 28 | ||
1409 | #define UV2H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffff0000000UL | ||
1410 | #define UV2H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_N_GRU_SHFT 52 | ||
1411 | #define UV2H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_N_GRU_MASK 0x00f0000000000000UL | ||
1412 | #define UV2H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 | ||
1413 | #define UV2H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL | ||
984 | 1414 | ||
985 | union uvh_rh_gam_gru_overlay_config_mmr_u { | 1415 | union uvh_rh_gam_gru_overlay_config_mmr_u { |
986 | unsigned long v; | 1416 | unsigned long v; |
987 | struct uvh_rh_gam_gru_overlay_config_mmr_s { | 1417 | struct uvh_rh_gam_gru_overlay_config_mmr_s { |
988 | unsigned long rsvd_0_27: 28; /* */ | 1418 | unsigned long rsvd_0_27: 28; /* */ |
989 | unsigned long base : 18; /* RW */ | 1419 | unsigned long base : 18; /* RW */ |
1420 | unsigned long rsvd_46_62 : 17; | ||
1421 | unsigned long enable : 1; /* RW */ | ||
1422 | } s; | ||
1423 | struct uv1h_rh_gam_gru_overlay_config_mmr_s { | ||
1424 | unsigned long rsvd_0_27: 28; /* */ | ||
1425 | unsigned long base : 18; /* RW */ | ||
990 | unsigned long rsvd_46_47: 2; /* */ | 1426 | unsigned long rsvd_46_47: 2; /* */ |
991 | unsigned long gr4 : 1; /* RW */ | 1427 | unsigned long gr4 : 1; /* RW */ |
992 | unsigned long rsvd_49_51: 3; /* */ | 1428 | unsigned long rsvd_49_51: 3; /* */ |
993 | unsigned long n_gru : 4; /* RW */ | 1429 | unsigned long n_gru : 4; /* RW */ |
994 | unsigned long rsvd_56_62: 7; /* */ | 1430 | unsigned long rsvd_56_62: 7; /* */ |
995 | unsigned long enable : 1; /* RW */ | 1431 | unsigned long enable : 1; /* RW */ |
996 | } s; | 1432 | } s1; |
1433 | struct uv2h_rh_gam_gru_overlay_config_mmr_s { | ||
1434 | unsigned long rsvd_0_27: 28; /* */ | ||
1435 | unsigned long base : 18; /* RW */ | ||
1436 | unsigned long rsvd_46_51: 6; /* */ | ||
1437 | unsigned long n_gru : 4; /* RW */ | ||
1438 | unsigned long rsvd_56_62: 7; /* */ | ||
1439 | unsigned long enable : 1; /* RW */ | ||
1440 | } s2; | ||
997 | }; | 1441 | }; |
998 | 1442 | ||
999 | /* ========================================================================= */ | 1443 | /* ========================================================================= */ |
@@ -1001,25 +1445,42 @@ union uvh_rh_gam_gru_overlay_config_mmr_u { | |||
1001 | /* ========================================================================= */ | 1445 | /* ========================================================================= */ |
1002 | #define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR 0x1600030UL | 1446 | #define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR 0x1600030UL |
1003 | 1447 | ||
1004 | #define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT 30 | 1448 | #define UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT 30 |
1005 | #define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003fffc0000000UL | 1449 | #define UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003fffc0000000UL |
1006 | #define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_M_IO_SHFT 46 | 1450 | #define UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_M_IO_SHFT 46 |
1007 | #define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_M_IO_MASK 0x000fc00000000000UL | 1451 | #define UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_M_IO_MASK 0x000fc00000000000UL |
1008 | #define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_N_IO_SHFT 52 | 1452 | #define UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_N_IO_SHFT 52 |
1009 | #define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_N_IO_MASK 0x00f0000000000000UL | 1453 | #define UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_N_IO_MASK 0x00f0000000000000UL |
1010 | #define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 | 1454 | #define UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 |
1011 | #define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL | 1455 | #define UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL |
1456 | |||
1457 | #define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT 27 | ||
1458 | #define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffff8000000UL | ||
1459 | #define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_M_IO_SHFT 46 | ||
1460 | #define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_M_IO_MASK 0x000fc00000000000UL | ||
1461 | #define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_N_IO_SHFT 52 | ||
1462 | #define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_N_IO_MASK 0x00f0000000000000UL | ||
1463 | #define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 | ||
1464 | #define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL | ||
1012 | 1465 | ||
1013 | union uvh_rh_gam_mmioh_overlay_config_mmr_u { | 1466 | union uvh_rh_gam_mmioh_overlay_config_mmr_u { |
1014 | unsigned long v; | 1467 | unsigned long v; |
1015 | struct uvh_rh_gam_mmioh_overlay_config_mmr_s { | 1468 | struct uv1h_rh_gam_mmioh_overlay_config_mmr_s { |
1016 | unsigned long rsvd_0_29: 30; /* */ | 1469 | unsigned long rsvd_0_29: 30; /* */ |
1017 | unsigned long base : 16; /* RW */ | 1470 | unsigned long base : 16; /* RW */ |
1018 | unsigned long m_io : 6; /* RW */ | 1471 | unsigned long m_io : 6; /* RW */ |
1019 | unsigned long n_io : 4; /* RW */ | 1472 | unsigned long n_io : 4; /* RW */ |
1020 | unsigned long rsvd_56_62: 7; /* */ | 1473 | unsigned long rsvd_56_62: 7; /* */ |
1021 | unsigned long enable : 1; /* RW */ | 1474 | unsigned long enable : 1; /* RW */ |
1022 | } s; | 1475 | } s1; |
1476 | struct uv2h_rh_gam_mmioh_overlay_config_mmr_s { | ||
1477 | unsigned long rsvd_0_26: 27; /* */ | ||
1478 | unsigned long base : 19; /* RW */ | ||
1479 | unsigned long m_io : 6; /* RW */ | ||
1480 | unsigned long n_io : 4; /* RW */ | ||
1481 | unsigned long rsvd_56_62: 7; /* */ | ||
1482 | unsigned long enable : 1; /* RW */ | ||
1483 | } s2; | ||
1023 | }; | 1484 | }; |
1024 | 1485 | ||
1025 | /* ========================================================================= */ | 1486 | /* ========================================================================= */ |
@@ -1029,20 +1490,40 @@ union uvh_rh_gam_mmioh_overlay_config_mmr_u { | |||
1029 | 1490 | ||
1030 | #define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_SHFT 26 | 1491 | #define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_SHFT 26 |
1031 | #define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffffc000000UL | 1492 | #define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffffc000000UL |
1032 | #define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_DUAL_HUB_SHFT 46 | 1493 | |
1033 | #define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_DUAL_HUB_MASK 0x0000400000000000UL | 1494 | #define UV1H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_SHFT 26 |
1034 | #define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 | 1495 | #define UV1H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffffc000000UL |
1035 | #define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL | 1496 | #define UV1H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_DUAL_HUB_SHFT 46 |
1497 | #define UV1H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_DUAL_HUB_MASK 0x0000400000000000UL | ||
1498 | #define UV1H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 | ||
1499 | #define UV1H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL | ||
1500 | |||
1501 | #define UV2H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_SHFT 26 | ||
1502 | #define UV2H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffffc000000UL | ||
1503 | #define UV2H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63 | ||
1504 | #define UV2H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL | ||
1036 | 1505 | ||
1037 | union uvh_rh_gam_mmr_overlay_config_mmr_u { | 1506 | union uvh_rh_gam_mmr_overlay_config_mmr_u { |
1038 | unsigned long v; | 1507 | unsigned long v; |
1039 | struct uvh_rh_gam_mmr_overlay_config_mmr_s { | 1508 | struct uvh_rh_gam_mmr_overlay_config_mmr_s { |
1040 | unsigned long rsvd_0_25: 26; /* */ | 1509 | unsigned long rsvd_0_25: 26; /* */ |
1041 | unsigned long base : 20; /* RW */ | 1510 | unsigned long base : 20; /* RW */ |
1511 | unsigned long rsvd_46_62 : 17; | ||
1512 | unsigned long enable : 1; /* RW */ | ||
1513 | } s; | ||
1514 | struct uv1h_rh_gam_mmr_overlay_config_mmr_s { | ||
1515 | unsigned long rsvd_0_25: 26; /* */ | ||
1516 | unsigned long base : 20; /* RW */ | ||
1042 | unsigned long dual_hub : 1; /* RW */ | 1517 | unsigned long dual_hub : 1; /* RW */ |
1043 | unsigned long rsvd_47_62: 16; /* */ | 1518 | unsigned long rsvd_47_62: 16; /* */ |
1044 | unsigned long enable : 1; /* RW */ | 1519 | unsigned long enable : 1; /* RW */ |
1045 | } s; | 1520 | } s1; |
1521 | struct uv2h_rh_gam_mmr_overlay_config_mmr_s { | ||
1522 | unsigned long rsvd_0_25: 26; /* */ | ||
1523 | unsigned long base : 20; /* RW */ | ||
1524 | unsigned long rsvd_46_62: 17; /* */ | ||
1525 | unsigned long enable : 1; /* RW */ | ||
1526 | } s2; | ||
1046 | }; | 1527 | }; |
1047 | 1528 | ||
1048 | /* ========================================================================= */ | 1529 | /* ========================================================================= */ |
@@ -1103,10 +1584,11 @@ union uvh_rtc1_int_config_u { | |||
1103 | /* UVH_SCRATCH5 */ | 1584 | /* UVH_SCRATCH5 */ |
1104 | /* ========================================================================= */ | 1585 | /* ========================================================================= */ |
1105 | #define UVH_SCRATCH5 0x2d0200UL | 1586 | #define UVH_SCRATCH5 0x2d0200UL |
1106 | #define UVH_SCRATCH5_32 0x00778 | 1587 | #define UVH_SCRATCH5_32 0x778 |
1107 | 1588 | ||
1108 | #define UVH_SCRATCH5_SCRATCH5_SHFT 0 | 1589 | #define UVH_SCRATCH5_SCRATCH5_SHFT 0 |
1109 | #define UVH_SCRATCH5_SCRATCH5_MASK 0xffffffffffffffffUL | 1590 | #define UVH_SCRATCH5_SCRATCH5_MASK 0xffffffffffffffffUL |
1591 | |||
1110 | union uvh_scratch5_u { | 1592 | union uvh_scratch5_u { |
1111 | unsigned long v; | 1593 | unsigned long v; |
1112 | struct uvh_scratch5_s { | 1594 | struct uvh_scratch5_s { |
@@ -1114,4 +1596,154 @@ union uvh_scratch5_u { | |||
1114 | } s; | 1596 | } s; |
1115 | }; | 1597 | }; |
1116 | 1598 | ||
1599 | /* ========================================================================= */ | ||
1600 | /* UV2H_EVENT_OCCURRED2 */ | ||
1601 | /* ========================================================================= */ | ||
1602 | #define UV2H_EVENT_OCCURRED2 0x70100UL | ||
1603 | #define UV2H_EVENT_OCCURRED2_32 0xb68 | ||
1604 | |||
1605 | #define UV2H_EVENT_OCCURRED2_RTC_0_SHFT 0 | ||
1606 | #define UV2H_EVENT_OCCURRED2_RTC_0_MASK 0x0000000000000001UL | ||
1607 | #define UV2H_EVENT_OCCURRED2_RTC_1_SHFT 1 | ||
1608 | #define UV2H_EVENT_OCCURRED2_RTC_1_MASK 0x0000000000000002UL | ||
1609 | #define UV2H_EVENT_OCCURRED2_RTC_2_SHFT 2 | ||
1610 | #define UV2H_EVENT_OCCURRED2_RTC_2_MASK 0x0000000000000004UL | ||
1611 | #define UV2H_EVENT_OCCURRED2_RTC_3_SHFT 3 | ||
1612 | #define UV2H_EVENT_OCCURRED2_RTC_3_MASK 0x0000000000000008UL | ||
1613 | #define UV2H_EVENT_OCCURRED2_RTC_4_SHFT 4 | ||
1614 | #define UV2H_EVENT_OCCURRED2_RTC_4_MASK 0x0000000000000010UL | ||
1615 | #define UV2H_EVENT_OCCURRED2_RTC_5_SHFT 5 | ||
1616 | #define UV2H_EVENT_OCCURRED2_RTC_5_MASK 0x0000000000000020UL | ||
1617 | #define UV2H_EVENT_OCCURRED2_RTC_6_SHFT 6 | ||
1618 | #define UV2H_EVENT_OCCURRED2_RTC_6_MASK 0x0000000000000040UL | ||
1619 | #define UV2H_EVENT_OCCURRED2_RTC_7_SHFT 7 | ||
1620 | #define UV2H_EVENT_OCCURRED2_RTC_7_MASK 0x0000000000000080UL | ||
1621 | #define UV2H_EVENT_OCCURRED2_RTC_8_SHFT 8 | ||
1622 | #define UV2H_EVENT_OCCURRED2_RTC_8_MASK 0x0000000000000100UL | ||
1623 | #define UV2H_EVENT_OCCURRED2_RTC_9_SHFT 9 | ||
1624 | #define UV2H_EVENT_OCCURRED2_RTC_9_MASK 0x0000000000000200UL | ||
1625 | #define UV2H_EVENT_OCCURRED2_RTC_10_SHFT 10 | ||
1626 | #define UV2H_EVENT_OCCURRED2_RTC_10_MASK 0x0000000000000400UL | ||
1627 | #define UV2H_EVENT_OCCURRED2_RTC_11_SHFT 11 | ||
1628 | #define UV2H_EVENT_OCCURRED2_RTC_11_MASK 0x0000000000000800UL | ||
1629 | #define UV2H_EVENT_OCCURRED2_RTC_12_SHFT 12 | ||
1630 | #define UV2H_EVENT_OCCURRED2_RTC_12_MASK 0x0000000000001000UL | ||
1631 | #define UV2H_EVENT_OCCURRED2_RTC_13_SHFT 13 | ||
1632 | #define UV2H_EVENT_OCCURRED2_RTC_13_MASK 0x0000000000002000UL | ||
1633 | #define UV2H_EVENT_OCCURRED2_RTC_14_SHFT 14 | ||
1634 | #define UV2H_EVENT_OCCURRED2_RTC_14_MASK 0x0000000000004000UL | ||
1635 | #define UV2H_EVENT_OCCURRED2_RTC_15_SHFT 15 | ||
1636 | #define UV2H_EVENT_OCCURRED2_RTC_15_MASK 0x0000000000008000UL | ||
1637 | #define UV2H_EVENT_OCCURRED2_RTC_16_SHFT 16 | ||
1638 | #define UV2H_EVENT_OCCURRED2_RTC_16_MASK 0x0000000000010000UL | ||
1639 | #define UV2H_EVENT_OCCURRED2_RTC_17_SHFT 17 | ||
1640 | #define UV2H_EVENT_OCCURRED2_RTC_17_MASK 0x0000000000020000UL | ||
1641 | #define UV2H_EVENT_OCCURRED2_RTC_18_SHFT 18 | ||
1642 | #define UV2H_EVENT_OCCURRED2_RTC_18_MASK 0x0000000000040000UL | ||
1643 | #define UV2H_EVENT_OCCURRED2_RTC_19_SHFT 19 | ||
1644 | #define UV2H_EVENT_OCCURRED2_RTC_19_MASK 0x0000000000080000UL | ||
1645 | #define UV2H_EVENT_OCCURRED2_RTC_20_SHFT 20 | ||
1646 | #define UV2H_EVENT_OCCURRED2_RTC_20_MASK 0x0000000000100000UL | ||
1647 | #define UV2H_EVENT_OCCURRED2_RTC_21_SHFT 21 | ||
1648 | #define UV2H_EVENT_OCCURRED2_RTC_21_MASK 0x0000000000200000UL | ||
1649 | #define UV2H_EVENT_OCCURRED2_RTC_22_SHFT 22 | ||
1650 | #define UV2H_EVENT_OCCURRED2_RTC_22_MASK 0x0000000000400000UL | ||
1651 | #define UV2H_EVENT_OCCURRED2_RTC_23_SHFT 23 | ||
1652 | #define UV2H_EVENT_OCCURRED2_RTC_23_MASK 0x0000000000800000UL | ||
1653 | #define UV2H_EVENT_OCCURRED2_RTC_24_SHFT 24 | ||
1654 | #define UV2H_EVENT_OCCURRED2_RTC_24_MASK 0x0000000001000000UL | ||
1655 | #define UV2H_EVENT_OCCURRED2_RTC_25_SHFT 25 | ||
1656 | #define UV2H_EVENT_OCCURRED2_RTC_25_MASK 0x0000000002000000UL | ||
1657 | #define UV2H_EVENT_OCCURRED2_RTC_26_SHFT 26 | ||
1658 | #define UV2H_EVENT_OCCURRED2_RTC_26_MASK 0x0000000004000000UL | ||
1659 | #define UV2H_EVENT_OCCURRED2_RTC_27_SHFT 27 | ||
1660 | #define UV2H_EVENT_OCCURRED2_RTC_27_MASK 0x0000000008000000UL | ||
1661 | #define UV2H_EVENT_OCCURRED2_RTC_28_SHFT 28 | ||
1662 | #define UV2H_EVENT_OCCURRED2_RTC_28_MASK 0x0000000010000000UL | ||
1663 | #define UV2H_EVENT_OCCURRED2_RTC_29_SHFT 29 | ||
1664 | #define UV2H_EVENT_OCCURRED2_RTC_29_MASK 0x0000000020000000UL | ||
1665 | #define UV2H_EVENT_OCCURRED2_RTC_30_SHFT 30 | ||
1666 | #define UV2H_EVENT_OCCURRED2_RTC_30_MASK 0x0000000040000000UL | ||
1667 | #define UV2H_EVENT_OCCURRED2_RTC_31_SHFT 31 | ||
1668 | #define UV2H_EVENT_OCCURRED2_RTC_31_MASK 0x0000000080000000UL | ||
1669 | |||
1670 | union uv2h_event_occurred2_u { | ||
1671 | unsigned long v; | ||
1672 | struct uv2h_event_occurred2_s { | ||
1673 | unsigned long rtc_0 : 1; /* RW */ | ||
1674 | unsigned long rtc_1 : 1; /* RW */ | ||
1675 | unsigned long rtc_2 : 1; /* RW */ | ||
1676 | unsigned long rtc_3 : 1; /* RW */ | ||
1677 | unsigned long rtc_4 : 1; /* RW */ | ||
1678 | unsigned long rtc_5 : 1; /* RW */ | ||
1679 | unsigned long rtc_6 : 1; /* RW */ | ||
1680 | unsigned long rtc_7 : 1; /* RW */ | ||
1681 | unsigned long rtc_8 : 1; /* RW */ | ||
1682 | unsigned long rtc_9 : 1; /* RW */ | ||
1683 | unsigned long rtc_10 : 1; /* RW */ | ||
1684 | unsigned long rtc_11 : 1; /* RW */ | ||
1685 | unsigned long rtc_12 : 1; /* RW */ | ||
1686 | unsigned long rtc_13 : 1; /* RW */ | ||
1687 | unsigned long rtc_14 : 1; /* RW */ | ||
1688 | unsigned long rtc_15 : 1; /* RW */ | ||
1689 | unsigned long rtc_16 : 1; /* RW */ | ||
1690 | unsigned long rtc_17 : 1; /* RW */ | ||
1691 | unsigned long rtc_18 : 1; /* RW */ | ||
1692 | unsigned long rtc_19 : 1; /* RW */ | ||
1693 | unsigned long rtc_20 : 1; /* RW */ | ||
1694 | unsigned long rtc_21 : 1; /* RW */ | ||
1695 | unsigned long rtc_22 : 1; /* RW */ | ||
1696 | unsigned long rtc_23 : 1; /* RW */ | ||
1697 | unsigned long rtc_24 : 1; /* RW */ | ||
1698 | unsigned long rtc_25 : 1; /* RW */ | ||
1699 | unsigned long rtc_26 : 1; /* RW */ | ||
1700 | unsigned long rtc_27 : 1; /* RW */ | ||
1701 | unsigned long rtc_28 : 1; /* RW */ | ||
1702 | unsigned long rtc_29 : 1; /* RW */ | ||
1703 | unsigned long rtc_30 : 1; /* RW */ | ||
1704 | unsigned long rtc_31 : 1; /* RW */ | ||
1705 | unsigned long rsvd_32_63: 32; /* */ | ||
1706 | } s1; | ||
1707 | }; | ||
1708 | |||
1709 | /* ========================================================================= */ | ||
1710 | /* UV2H_EVENT_OCCURRED2_ALIAS */ | ||
1711 | /* ========================================================================= */ | ||
1712 | #define UV2H_EVENT_OCCURRED2_ALIAS 0x70108UL | ||
1713 | #define UV2H_EVENT_OCCURRED2_ALIAS_32 0xb70 | ||
1714 | |||
1715 | /* ========================================================================= */ | ||
1716 | /* UV2H_LB_BAU_SB_ACTIVATION_STATUS_2 */ | ||
1717 | /* ========================================================================= */ | ||
1718 | #define UV2H_LB_BAU_SB_ACTIVATION_STATUS_2 0x320130UL | ||
1719 | #define UV2H_LB_BAU_SB_ACTIVATION_STATUS_2_32 0x9f0 | ||
1720 | |||
1721 | #define UV2H_LB_BAU_SB_ACTIVATION_STATUS_2_AUX_ERROR_SHFT 0 | ||
1722 | #define UV2H_LB_BAU_SB_ACTIVATION_STATUS_2_AUX_ERROR_MASK 0xffffffffffffffffUL | ||
1723 | |||
1724 | union uv2h_lb_bau_sb_activation_status_2_u { | ||
1725 | unsigned long v; | ||
1726 | struct uv2h_lb_bau_sb_activation_status_2_s { | ||
1727 | unsigned long aux_error : 64; /* RW */ | ||
1728 | } s1; | ||
1729 | }; | ||
1730 | |||
1731 | /* ========================================================================= */ | ||
1732 | /* UV1H_LB_TARGET_PHYSICAL_APIC_ID_MASK */ | ||
1733 | /* ========================================================================= */ | ||
1734 | #define UV1H_LB_TARGET_PHYSICAL_APIC_ID_MASK 0x320130UL | ||
1735 | #define UV1H_LB_TARGET_PHYSICAL_APIC_ID_MASK_32 0x9f0 | ||
1736 | |||
1737 | #define UV1H_LB_TARGET_PHYSICAL_APIC_ID_MASK_BIT_ENABLES_SHFT 0 | ||
1738 | #define UV1H_LB_TARGET_PHYSICAL_APIC_ID_MASK_BIT_ENABLES_MASK 0x00000000ffffffffUL | ||
1739 | |||
1740 | union uv1h_lb_target_physical_apic_id_mask_u { | ||
1741 | unsigned long v; | ||
1742 | struct uv1h_lb_target_physical_apic_id_mask_s { | ||
1743 | unsigned long bit_enables : 32; /* RW */ | ||
1744 | unsigned long rsvd_32_63 : 32; /* */ | ||
1745 | } s1; | ||
1746 | }; | ||
1747 | |||
1748 | |||
1117 | #endif /* __ASM_UV_MMRS_X86_H__ */ | 1749 | #endif /* __ASM_UV_MMRS_X86_H__ */ |
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index f5abe3a245b8..90b06d4daee2 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile | |||
@@ -8,6 +8,7 @@ CPPFLAGS_vmlinux.lds += -U$(UTS_MACHINE) | |||
8 | 8 | ||
9 | ifdef CONFIG_FUNCTION_TRACER | 9 | ifdef CONFIG_FUNCTION_TRACER |
10 | # Do not profile debug and lowlevel utilities | 10 | # Do not profile debug and lowlevel utilities |
11 | CFLAGS_REMOVE_tsc.o = -pg | ||
11 | CFLAGS_REMOVE_rtc.o = -pg | 12 | CFLAGS_REMOVE_rtc.o = -pg |
12 | CFLAGS_REMOVE_paravirt-spinlocks.o = -pg | 13 | CFLAGS_REMOVE_paravirt-spinlocks.o = -pg |
13 | CFLAGS_REMOVE_pvclock.o = -pg | 14 | CFLAGS_REMOVE_pvclock.o = -pg |
@@ -28,6 +29,7 @@ CFLAGS_paravirt.o := $(nostackp) | |||
28 | GCOV_PROFILE_vsyscall_64.o := n | 29 | GCOV_PROFILE_vsyscall_64.o := n |
29 | GCOV_PROFILE_hpet.o := n | 30 | GCOV_PROFILE_hpet.o := n |
30 | GCOV_PROFILE_tsc.o := n | 31 | GCOV_PROFILE_tsc.o := n |
32 | GCOV_PROFILE_vread_tsc_64.o := n | ||
31 | GCOV_PROFILE_paravirt.o := n | 33 | GCOV_PROFILE_paravirt.o := n |
32 | 34 | ||
33 | # vread_tsc_64 is hot and should be fully optimized: | 35 | # vread_tsc_64 is hot and should be fully optimized: |
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index f450b683dfcf..b511a011b7d0 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c | |||
@@ -91,6 +91,10 @@ static int __init early_get_pnodeid(void) | |||
91 | m_n_config.v = uv_early_read_mmr(UVH_RH_GAM_CONFIG_MMR); | 91 | m_n_config.v = uv_early_read_mmr(UVH_RH_GAM_CONFIG_MMR); |
92 | uv_min_hub_revision_id = node_id.s.revision; | 92 | uv_min_hub_revision_id = node_id.s.revision; |
93 | 93 | ||
94 | if (node_id.s.part_number == UV2_HUB_PART_NUMBER) | ||
95 | uv_min_hub_revision_id += UV2_HUB_REVISION_BASE - 1; | ||
96 | |||
97 | uv_hub_info->hub_revision = uv_min_hub_revision_id; | ||
94 | pnode = (node_id.s.node_id >> 1) & ((1 << m_n_config.s.n_skt) - 1); | 98 | pnode = (node_id.s.node_id >> 1) & ((1 << m_n_config.s.n_skt) - 1); |
95 | return pnode; | 99 | return pnode; |
96 | } | 100 | } |
@@ -112,17 +116,25 @@ static void __init early_get_apic_pnode_shift(void) | |||
112 | */ | 116 | */ |
113 | static void __init uv_set_apicid_hibit(void) | 117 | static void __init uv_set_apicid_hibit(void) |
114 | { | 118 | { |
115 | union uvh_lb_target_physical_apic_id_mask_u apicid_mask; | 119 | union uv1h_lb_target_physical_apic_id_mask_u apicid_mask; |
116 | 120 | ||
117 | apicid_mask.v = uv_early_read_mmr(UVH_LB_TARGET_PHYSICAL_APIC_ID_MASK); | 121 | if (is_uv1_hub()) { |
118 | uv_apicid_hibits = apicid_mask.s.bit_enables & UV_APICID_HIBIT_MASK; | 122 | apicid_mask.v = |
123 | uv_early_read_mmr(UV1H_LB_TARGET_PHYSICAL_APIC_ID_MASK); | ||
124 | uv_apicid_hibits = | ||
125 | apicid_mask.s1.bit_enables & UV_APICID_HIBIT_MASK; | ||
126 | } | ||
119 | } | 127 | } |
120 | 128 | ||
121 | static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id) | 129 | static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id) |
122 | { | 130 | { |
123 | int pnodeid; | 131 | int pnodeid, is_uv1, is_uv2; |
124 | 132 | ||
125 | if (!strcmp(oem_id, "SGI")) { | 133 | is_uv1 = !strcmp(oem_id, "SGI"); |
134 | is_uv2 = !strcmp(oem_id, "SGI2"); | ||
135 | if (is_uv1 || is_uv2) { | ||
136 | uv_hub_info->hub_revision = | ||
137 | is_uv1 ? UV1_HUB_REVISION_BASE : UV2_HUB_REVISION_BASE; | ||
126 | pnodeid = early_get_pnodeid(); | 138 | pnodeid = early_get_pnodeid(); |
127 | early_get_apic_pnode_shift(); | 139 | early_get_apic_pnode_shift(); |
128 | x86_platform.is_untracked_pat_range = uv_is_untracked_pat_range; | 140 | x86_platform.is_untracked_pat_range = uv_is_untracked_pat_range; |
@@ -484,12 +496,19 @@ static __init void map_mmr_high(int max_pnode) | |||
484 | static __init void map_mmioh_high(int max_pnode) | 496 | static __init void map_mmioh_high(int max_pnode) |
485 | { | 497 | { |
486 | union uvh_rh_gam_mmioh_overlay_config_mmr_u mmioh; | 498 | union uvh_rh_gam_mmioh_overlay_config_mmr_u mmioh; |
487 | int shift = UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT; | 499 | int shift; |
488 | 500 | ||
489 | mmioh.v = uv_read_local_mmr(UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR); | 501 | mmioh.v = uv_read_local_mmr(UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR); |
490 | if (mmioh.s.enable) | 502 | if (is_uv1_hub() && mmioh.s1.enable) { |
491 | map_high("MMIOH", mmioh.s.base, shift, mmioh.s.m_io, | 503 | shift = UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT; |
504 | map_high("MMIOH", mmioh.s1.base, shift, mmioh.s1.m_io, | ||
505 | max_pnode, map_uc); | ||
506 | } | ||
507 | if (is_uv2_hub() && mmioh.s2.enable) { | ||
508 | shift = UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT; | ||
509 | map_high("MMIOH", mmioh.s2.base, shift, mmioh.s2.m_io, | ||
492 | max_pnode, map_uc); | 510 | max_pnode, map_uc); |
511 | } | ||
493 | } | 512 | } |
494 | 513 | ||
495 | static __init void map_low_mmrs(void) | 514 | static __init void map_low_mmrs(void) |
@@ -736,13 +755,14 @@ void __init uv_system_init(void) | |||
736 | unsigned long mmr_base, present, paddr; | 755 | unsigned long mmr_base, present, paddr; |
737 | unsigned short pnode_mask, pnode_io_mask; | 756 | unsigned short pnode_mask, pnode_io_mask; |
738 | 757 | ||
758 | printk(KERN_INFO "UV: Found %s hub\n", is_uv1_hub() ? "UV1" : "UV2"); | ||
739 | map_low_mmrs(); | 759 | map_low_mmrs(); |
740 | 760 | ||
741 | m_n_config.v = uv_read_local_mmr(UVH_RH_GAM_CONFIG_MMR ); | 761 | m_n_config.v = uv_read_local_mmr(UVH_RH_GAM_CONFIG_MMR ); |
742 | m_val = m_n_config.s.m_skt; | 762 | m_val = m_n_config.s.m_skt; |
743 | n_val = m_n_config.s.n_skt; | 763 | n_val = m_n_config.s.n_skt; |
744 | mmioh.v = uv_read_local_mmr(UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR); | 764 | mmioh.v = uv_read_local_mmr(UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR); |
745 | n_io = mmioh.s.n_io; | 765 | n_io = is_uv1_hub() ? mmioh.s1.n_io : mmioh.s2.n_io; |
746 | mmr_base = | 766 | mmr_base = |
747 | uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR) & | 767 | uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR) & |
748 | ~UV_MMR_ENABLE; | 768 | ~UV_MMR_ENABLE; |
@@ -811,6 +831,8 @@ void __init uv_system_init(void) | |||
811 | */ | 831 | */ |
812 | uv_cpu_hub_info(cpu)->pnode_mask = pnode_mask; | 832 | uv_cpu_hub_info(cpu)->pnode_mask = pnode_mask; |
813 | uv_cpu_hub_info(cpu)->apic_pnode_shift = uvh_apicid.s.pnode_shift; | 833 | uv_cpu_hub_info(cpu)->apic_pnode_shift = uvh_apicid.s.pnode_shift; |
834 | uv_cpu_hub_info(cpu)->hub_revision = uv_hub_info->hub_revision; | ||
835 | |||
814 | pnode = uv_apicid_to_pnode(apicid); | 836 | pnode = uv_apicid_to_pnode(apicid); |
815 | blade = boot_pnode_to_blade(pnode); | 837 | blade = boot_pnode_to_blade(pnode); |
816 | lcpu = uv_blade_info[blade].nr_possible_cpus; | 838 | lcpu = uv_blade_info[blade].nr_possible_cpus; |
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c index 3bfa02235965..965a7666c283 100644 --- a/arch/x86/kernel/apm_32.c +++ b/arch/x86/kernel/apm_32.c | |||
@@ -361,6 +361,7 @@ struct apm_user { | |||
361 | * idle percentage above which bios idle calls are done | 361 | * idle percentage above which bios idle calls are done |
362 | */ | 362 | */ |
363 | #ifdef CONFIG_APM_CPU_IDLE | 363 | #ifdef CONFIG_APM_CPU_IDLE |
364 | #warning deprecated CONFIG_APM_CPU_IDLE will be deleted in 2012 | ||
364 | #define DEFAULT_IDLE_THRESHOLD 95 | 365 | #define DEFAULT_IDLE_THRESHOLD 95 |
365 | #else | 366 | #else |
366 | #define DEFAULT_IDLE_THRESHOLD 100 | 367 | #define DEFAULT_IDLE_THRESHOLD 100 |
@@ -904,6 +905,7 @@ static void apm_cpu_idle(void) | |||
904 | unsigned int jiffies_since_last_check = jiffies - last_jiffies; | 905 | unsigned int jiffies_since_last_check = jiffies - last_jiffies; |
905 | unsigned int bucket; | 906 | unsigned int bucket; |
906 | 907 | ||
908 | WARN_ONCE(1, "deprecated apm_cpu_idle will be deleted in 2012"); | ||
907 | recalc: | 909 | recalc: |
908 | if (jiffies_since_last_check > IDLE_CALC_LIMIT) { | 910 | if (jiffies_since_last_check > IDLE_CALC_LIMIT) { |
909 | use_apm_idle = 0; | 911 | use_apm_idle = 0; |
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 8f5cabb3c5b0..b13ed393dfce 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c | |||
@@ -612,8 +612,11 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) | |||
612 | } | 612 | } |
613 | #endif | 613 | #endif |
614 | 614 | ||
615 | /* As a rule processors have APIC timer running in deep C states */ | 615 | /* |
616 | if (c->x86 > 0xf && !cpu_has_amd_erratum(amd_erratum_400)) | 616 | * Family 0x12 and above processors have APIC timer |
617 | * running in deep C states. | ||
618 | */ | ||
619 | if (c->x86 > 0x11) | ||
617 | set_cpu_cap(c, X86_FEATURE_ARAT); | 620 | set_cpu_cap(c, X86_FEATURE_ARAT); |
618 | 621 | ||
619 | /* | 622 | /* |
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index c39576cb3018..525514cf33c3 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c | |||
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | static int __init no_halt(char *s) | 20 | static int __init no_halt(char *s) |
21 | { | 21 | { |
22 | WARN_ONCE(1, "\"no-hlt\" is deprecated, please use \"idle=poll\"\n"); | ||
22 | boot_cpu_data.hlt_works_ok = 0; | 23 | boot_cpu_data.hlt_works_ok = 0; |
23 | return 1; | 24 | return 1; |
24 | } | 25 | } |
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index c8b41623377f..22a073d7fbff 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -477,13 +477,6 @@ void __cpuinit detect_ht(struct cpuinfo_x86 *c) | |||
477 | if (smp_num_siblings <= 1) | 477 | if (smp_num_siblings <= 1) |
478 | goto out; | 478 | goto out; |
479 | 479 | ||
480 | if (smp_num_siblings > nr_cpu_ids) { | ||
481 | pr_warning("CPU: Unsupported number of siblings %d", | ||
482 | smp_num_siblings); | ||
483 | smp_num_siblings = 1; | ||
484 | return; | ||
485 | } | ||
486 | |||
487 | index_msb = get_count_order(smp_num_siblings); | 480 | index_msb = get_count_order(smp_num_siblings); |
488 | c->phys_proc_id = apic->phys_pkg_id(c->initial_apicid, index_msb); | 481 | c->phys_proc_id = apic->phys_pkg_id(c->initial_apicid, index_msb); |
489 | 482 | ||
@@ -909,7 +902,7 @@ static void vgetcpu_set_mode(void) | |||
909 | void __init identify_boot_cpu(void) | 902 | void __init identify_boot_cpu(void) |
910 | { | 903 | { |
911 | identify_cpu(&boot_cpu_data); | 904 | identify_cpu(&boot_cpu_data); |
912 | init_c1e_mask(); | 905 | init_amd_e400_c1e_mask(); |
913 | #ifdef CONFIG_X86_32 | 906 | #ifdef CONFIG_X86_32 |
914 | sysenter_setup(); | 907 | sysenter_setup(); |
915 | enable_sep_cpu(); | 908 | enable_sep_cpu(); |
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index 0ba15a6cc57e..c9a281f272fd 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c | |||
@@ -123,7 +123,7 @@ static unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr) | |||
123 | static atomic_t nmi_running = ATOMIC_INIT(0); | 123 | static atomic_t nmi_running = ATOMIC_INIT(0); |
124 | static int mod_code_status; /* holds return value of text write */ | 124 | static int mod_code_status; /* holds return value of text write */ |
125 | static void *mod_code_ip; /* holds the IP to write to */ | 125 | static void *mod_code_ip; /* holds the IP to write to */ |
126 | static void *mod_code_newcode; /* holds the text to write to the IP */ | 126 | static const void *mod_code_newcode; /* holds the text to write to the IP */ |
127 | 127 | ||
128 | static unsigned nmi_wait_count; | 128 | static unsigned nmi_wait_count; |
129 | static atomic_t nmi_update_count = ATOMIC_INIT(0); | 129 | static atomic_t nmi_update_count = ATOMIC_INIT(0); |
@@ -225,7 +225,7 @@ within(unsigned long addr, unsigned long start, unsigned long end) | |||
225 | } | 225 | } |
226 | 226 | ||
227 | static int | 227 | static int |
228 | do_ftrace_mod_code(unsigned long ip, void *new_code) | 228 | do_ftrace_mod_code(unsigned long ip, const void *new_code) |
229 | { | 229 | { |
230 | /* | 230 | /* |
231 | * On x86_64, kernel text mappings are mapped read-only with | 231 | * On x86_64, kernel text mappings are mapped read-only with |
@@ -266,8 +266,8 @@ static const unsigned char *ftrace_nop_replace(void) | |||
266 | } | 266 | } |
267 | 267 | ||
268 | static int | 268 | static int |
269 | ftrace_modify_code(unsigned long ip, unsigned char *old_code, | 269 | ftrace_modify_code(unsigned long ip, unsigned const char *old_code, |
270 | unsigned char *new_code) | 270 | unsigned const char *new_code) |
271 | { | 271 | { |
272 | unsigned char replaced[MCOUNT_INSN_SIZE]; | 272 | unsigned char replaced[MCOUNT_INSN_SIZE]; |
273 | 273 | ||
@@ -301,7 +301,7 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code, | |||
301 | int ftrace_make_nop(struct module *mod, | 301 | int ftrace_make_nop(struct module *mod, |
302 | struct dyn_ftrace *rec, unsigned long addr) | 302 | struct dyn_ftrace *rec, unsigned long addr) |
303 | { | 303 | { |
304 | unsigned char *new, *old; | 304 | unsigned const char *new, *old; |
305 | unsigned long ip = rec->ip; | 305 | unsigned long ip = rec->ip; |
306 | 306 | ||
307 | old = ftrace_call_replace(ip, addr); | 307 | old = ftrace_call_replace(ip, addr); |
@@ -312,7 +312,7 @@ int ftrace_make_nop(struct module *mod, | |||
312 | 312 | ||
313 | int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) | 313 | int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) |
314 | { | 314 | { |
315 | unsigned char *new, *old; | 315 | unsigned const char *new, *old; |
316 | unsigned long ip = rec->ip; | 316 | unsigned long ip = rec->ip; |
317 | 317 | ||
318 | old = ftrace_nop_replace(); | 318 | old = ftrace_nop_replace(); |
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 88a90a977f8e..2e4928d45a2d 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c | |||
@@ -337,7 +337,9 @@ EXPORT_SYMBOL(boot_option_idle_override); | |||
337 | * Powermanagement idle function, if any.. | 337 | * Powermanagement idle function, if any.. |
338 | */ | 338 | */ |
339 | void (*pm_idle)(void); | 339 | void (*pm_idle)(void); |
340 | #if defined(CONFIG_APM_MODULE) && defined(CONFIG_APM_CPU_IDLE) | ||
340 | EXPORT_SYMBOL(pm_idle); | 341 | EXPORT_SYMBOL(pm_idle); |
342 | #endif | ||
341 | 343 | ||
342 | #ifdef CONFIG_X86_32 | 344 | #ifdef CONFIG_X86_32 |
343 | /* | 345 | /* |
@@ -397,7 +399,7 @@ void default_idle(void) | |||
397 | cpu_relax(); | 399 | cpu_relax(); |
398 | } | 400 | } |
399 | } | 401 | } |
400 | #ifdef CONFIG_APM_MODULE | 402 | #if defined(CONFIG_APM_MODULE) && defined(CONFIG_APM_CPU_IDLE) |
401 | EXPORT_SYMBOL(default_idle); | 403 | EXPORT_SYMBOL(default_idle); |
402 | #endif | 404 | #endif |
403 | 405 | ||
@@ -535,45 +537,45 @@ int mwait_usable(const struct cpuinfo_x86 *c) | |||
535 | return (edx & MWAIT_EDX_C1); | 537 | return (edx & MWAIT_EDX_C1); |
536 | } | 538 | } |
537 | 539 | ||
538 | bool c1e_detected; | 540 | bool amd_e400_c1e_detected; |
539 | EXPORT_SYMBOL(c1e_detected); | 541 | EXPORT_SYMBOL(amd_e400_c1e_detected); |
540 | 542 | ||
541 | static cpumask_var_t c1e_mask; | 543 | static cpumask_var_t amd_e400_c1e_mask; |
542 | 544 | ||
543 | void c1e_remove_cpu(int cpu) | 545 | void amd_e400_remove_cpu(int cpu) |
544 | { | 546 | { |
545 | if (c1e_mask != NULL) | 547 | if (amd_e400_c1e_mask != NULL) |
546 | cpumask_clear_cpu(cpu, c1e_mask); | 548 | cpumask_clear_cpu(cpu, amd_e400_c1e_mask); |
547 | } | 549 | } |
548 | 550 | ||
549 | /* | 551 | /* |
550 | * C1E aware idle routine. We check for C1E active in the interrupt | 552 | * AMD Erratum 400 aware idle routine. We check for C1E active in the interrupt |
551 | * pending message MSR. If we detect C1E, then we handle it the same | 553 | * pending message MSR. If we detect C1E, then we handle it the same |
552 | * way as C3 power states (local apic timer and TSC stop) | 554 | * way as C3 power states (local apic timer and TSC stop) |
553 | */ | 555 | */ |
554 | static void c1e_idle(void) | 556 | static void amd_e400_idle(void) |
555 | { | 557 | { |
556 | if (need_resched()) | 558 | if (need_resched()) |
557 | return; | 559 | return; |
558 | 560 | ||
559 | if (!c1e_detected) { | 561 | if (!amd_e400_c1e_detected) { |
560 | u32 lo, hi; | 562 | u32 lo, hi; |
561 | 563 | ||
562 | rdmsr(MSR_K8_INT_PENDING_MSG, lo, hi); | 564 | rdmsr(MSR_K8_INT_PENDING_MSG, lo, hi); |
563 | 565 | ||
564 | if (lo & K8_INTP_C1E_ACTIVE_MASK) { | 566 | if (lo & K8_INTP_C1E_ACTIVE_MASK) { |
565 | c1e_detected = true; | 567 | amd_e400_c1e_detected = true; |
566 | if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) | 568 | if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) |
567 | mark_tsc_unstable("TSC halt in AMD C1E"); | 569 | mark_tsc_unstable("TSC halt in AMD C1E"); |
568 | printk(KERN_INFO "System has AMD C1E enabled\n"); | 570 | printk(KERN_INFO "System has AMD C1E enabled\n"); |
569 | } | 571 | } |
570 | } | 572 | } |
571 | 573 | ||
572 | if (c1e_detected) { | 574 | if (amd_e400_c1e_detected) { |
573 | int cpu = smp_processor_id(); | 575 | int cpu = smp_processor_id(); |
574 | 576 | ||
575 | if (!cpumask_test_cpu(cpu, c1e_mask)) { | 577 | if (!cpumask_test_cpu(cpu, amd_e400_c1e_mask)) { |
576 | cpumask_set_cpu(cpu, c1e_mask); | 578 | cpumask_set_cpu(cpu, amd_e400_c1e_mask); |
577 | /* | 579 | /* |
578 | * Force broadcast so ACPI can not interfere. | 580 | * Force broadcast so ACPI can not interfere. |
579 | */ | 581 | */ |
@@ -616,17 +618,17 @@ void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) | |||
616 | pm_idle = mwait_idle; | 618 | pm_idle = mwait_idle; |
617 | } else if (cpu_has_amd_erratum(amd_erratum_400)) { | 619 | } else if (cpu_has_amd_erratum(amd_erratum_400)) { |
618 | /* E400: APIC timer interrupt does not wake up CPU from C1e */ | 620 | /* E400: APIC timer interrupt does not wake up CPU from C1e */ |
619 | printk(KERN_INFO "using C1E aware idle routine\n"); | 621 | printk(KERN_INFO "using AMD E400 aware idle routine\n"); |
620 | pm_idle = c1e_idle; | 622 | pm_idle = amd_e400_idle; |
621 | } else | 623 | } else |
622 | pm_idle = default_idle; | 624 | pm_idle = default_idle; |
623 | } | 625 | } |
624 | 626 | ||
625 | void __init init_c1e_mask(void) | 627 | void __init init_amd_e400_c1e_mask(void) |
626 | { | 628 | { |
627 | /* If we're using c1e_idle, we need to allocate c1e_mask. */ | 629 | /* If we're using amd_e400_idle, we need to allocate amd_e400_c1e_mask. */ |
628 | if (pm_idle == c1e_idle) | 630 | if (pm_idle == amd_e400_idle) |
629 | zalloc_cpumask_var(&c1e_mask, GFP_KERNEL); | 631 | zalloc_cpumask_var(&amd_e400_c1e_mask, GFP_KERNEL); |
630 | } | 632 | } |
631 | 633 | ||
632 | static int __init idle_setup(char *str) | 634 | static int __init idle_setup(char *str) |
@@ -640,6 +642,7 @@ static int __init idle_setup(char *str) | |||
640 | boot_option_idle_override = IDLE_POLL; | 642 | boot_option_idle_override = IDLE_POLL; |
641 | } else if (!strcmp(str, "mwait")) { | 643 | } else if (!strcmp(str, "mwait")) { |
642 | boot_option_idle_override = IDLE_FORCE_MWAIT; | 644 | boot_option_idle_override = IDLE_FORCE_MWAIT; |
645 | WARN_ONCE(1, "\"idle=mwait\" will be removed in 2012\n"); | ||
643 | } else if (!strcmp(str, "halt")) { | 646 | } else if (!strcmp(str, "halt")) { |
644 | /* | 647 | /* |
645 | * When the boot option of idle=halt is added, halt is | 648 | * When the boot option of idle=halt is added, halt is |
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index a3e5948670c2..afaf38447ef5 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
@@ -910,6 +910,13 @@ void __init setup_arch(char **cmdline_p) | |||
910 | memblock.current_limit = get_max_mapped(); | 910 | memblock.current_limit = get_max_mapped(); |
911 | memblock_x86_fill(); | 911 | memblock_x86_fill(); |
912 | 912 | ||
913 | /* | ||
914 | * The EFI specification says that boot service code won't be called | ||
915 | * after ExitBootServices(). This is, in fact, a lie. | ||
916 | */ | ||
917 | if (efi_enabled) | ||
918 | efi_reserve_boot_services(); | ||
919 | |||
913 | /* preallocate 4k for mptable mpc */ | 920 | /* preallocate 4k for mptable mpc */ |
914 | early_reserve_e820_mpc_new(); | 921 | early_reserve_e820_mpc_new(); |
915 | 922 | ||
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index a3c430bdfb60..33a0c11797de 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
@@ -1307,7 +1307,7 @@ void play_dead_common(void) | |||
1307 | { | 1307 | { |
1308 | idle_task_exit(); | 1308 | idle_task_exit(); |
1309 | reset_lazy_tlbstate(); | 1309 | reset_lazy_tlbstate(); |
1310 | c1e_remove_cpu(raw_smp_processor_id()); | 1310 | amd_e400_remove_cpu(raw_smp_processor_id()); |
1311 | 1311 | ||
1312 | mb(); | 1312 | mb(); |
1313 | /* Ack it */ | 1313 | /* Ack it */ |
@@ -1332,7 +1332,7 @@ static inline void mwait_play_dead(void) | |||
1332 | void *mwait_ptr; | 1332 | void *mwait_ptr; |
1333 | struct cpuinfo_x86 *c = __this_cpu_ptr(&cpu_info); | 1333 | struct cpuinfo_x86 *c = __this_cpu_ptr(&cpu_info); |
1334 | 1334 | ||
1335 | if (!this_cpu_has(X86_FEATURE_MWAIT) && mwait_usable(c)) | 1335 | if (!(this_cpu_has(X86_FEATURE_MWAIT) && mwait_usable(c))) |
1336 | return; | 1336 | return; |
1337 | if (!this_cpu_has(X86_FEATURE_CLFLSH)) | 1337 | if (!this_cpu_has(X86_FEATURE_CLFLSH)) |
1338 | return; | 1338 | return; |
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index e191c096ab90..db832fd65ecb 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c | |||
@@ -993,6 +993,7 @@ static void lguest_time_irq(unsigned int irq, struct irq_desc *desc) | |||
993 | static void lguest_time_init(void) | 993 | static void lguest_time_init(void) |
994 | { | 994 | { |
995 | /* Set up the timer interrupt (0) to go to our simple timer routine */ | 995 | /* Set up the timer interrupt (0) to go to our simple timer routine */ |
996 | lguest_setup_irq(0); | ||
996 | irq_set_handler(0, lguest_time_irq); | 997 | irq_set_handler(0, lguest_time_irq); |
997 | 998 | ||
998 | clocksource_register_hz(&lguest_clock, NSEC_PER_SEC); | 999 | clocksource_register_hz(&lguest_clock, NSEC_PER_SEC); |
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index f7a2a054a3c0..2dbf6bf4c7e5 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c | |||
@@ -823,16 +823,30 @@ do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address, | |||
823 | force_sig_info_fault(SIGBUS, code, address, tsk, fault); | 823 | force_sig_info_fault(SIGBUS, code, address, tsk, fault); |
824 | } | 824 | } |
825 | 825 | ||
826 | static noinline void | 826 | static noinline int |
827 | mm_fault_error(struct pt_regs *regs, unsigned long error_code, | 827 | mm_fault_error(struct pt_regs *regs, unsigned long error_code, |
828 | unsigned long address, unsigned int fault) | 828 | unsigned long address, unsigned int fault) |
829 | { | 829 | { |
830 | /* | ||
831 | * Pagefault was interrupted by SIGKILL. We have no reason to | ||
832 | * continue pagefault. | ||
833 | */ | ||
834 | if (fatal_signal_pending(current)) { | ||
835 | if (!(fault & VM_FAULT_RETRY)) | ||
836 | up_read(¤t->mm->mmap_sem); | ||
837 | if (!(error_code & PF_USER)) | ||
838 | no_context(regs, error_code, address); | ||
839 | return 1; | ||
840 | } | ||
841 | if (!(fault & VM_FAULT_ERROR)) | ||
842 | return 0; | ||
843 | |||
830 | if (fault & VM_FAULT_OOM) { | 844 | if (fault & VM_FAULT_OOM) { |
831 | /* Kernel mode? Handle exceptions or die: */ | 845 | /* Kernel mode? Handle exceptions or die: */ |
832 | if (!(error_code & PF_USER)) { | 846 | if (!(error_code & PF_USER)) { |
833 | up_read(¤t->mm->mmap_sem); | 847 | up_read(¤t->mm->mmap_sem); |
834 | no_context(regs, error_code, address); | 848 | no_context(regs, error_code, address); |
835 | return; | 849 | return 1; |
836 | } | 850 | } |
837 | 851 | ||
838 | out_of_memory(regs, error_code, address); | 852 | out_of_memory(regs, error_code, address); |
@@ -843,6 +857,7 @@ mm_fault_error(struct pt_regs *regs, unsigned long error_code, | |||
843 | else | 857 | else |
844 | BUG(); | 858 | BUG(); |
845 | } | 859 | } |
860 | return 1; | ||
846 | } | 861 | } |
847 | 862 | ||
848 | static int spurious_fault_check(unsigned long error_code, pte_t *pte) | 863 | static int spurious_fault_check(unsigned long error_code, pte_t *pte) |
@@ -1133,19 +1148,9 @@ good_area: | |||
1133 | */ | 1148 | */ |
1134 | fault = handle_mm_fault(mm, vma, address, flags); | 1149 | fault = handle_mm_fault(mm, vma, address, flags); |
1135 | 1150 | ||
1136 | if (unlikely(fault & VM_FAULT_ERROR)) { | 1151 | if (unlikely(fault & (VM_FAULT_RETRY|VM_FAULT_ERROR))) { |
1137 | mm_fault_error(regs, error_code, address, fault); | 1152 | if (mm_fault_error(regs, error_code, address, fault)) |
1138 | return; | 1153 | return; |
1139 | } | ||
1140 | |||
1141 | /* | ||
1142 | * Pagefault was interrupted by SIGKILL. We have no reason to | ||
1143 | * continue pagefault. | ||
1144 | */ | ||
1145 | if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) { | ||
1146 | if (!(error_code & PF_USER)) | ||
1147 | no_context(regs, error_code, address); | ||
1148 | return; | ||
1149 | } | 1154 | } |
1150 | 1155 | ||
1151 | /* | 1156 | /* |
diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c index c3b8e24f2b16..9fd8a567fe1e 100644 --- a/arch/x86/oprofile/op_model_amd.c +++ b/arch/x86/oprofile/op_model_amd.c | |||
@@ -316,16 +316,23 @@ static void op_amd_stop_ibs(void) | |||
316 | wrmsrl(MSR_AMD64_IBSOPCTL, 0); | 316 | wrmsrl(MSR_AMD64_IBSOPCTL, 0); |
317 | } | 317 | } |
318 | 318 | ||
319 | static inline int eilvt_is_available(int offset) | 319 | static inline int get_eilvt(int offset) |
320 | { | 320 | { |
321 | /* check if we may assign a vector */ | ||
322 | return !setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_NMI, 1); | 321 | return !setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_NMI, 1); |
323 | } | 322 | } |
324 | 323 | ||
324 | static inline int put_eilvt(int offset) | ||
325 | { | ||
326 | return !setup_APIC_eilvt(offset, 0, 0, 1); | ||
327 | } | ||
328 | |||
325 | static inline int ibs_eilvt_valid(void) | 329 | static inline int ibs_eilvt_valid(void) |
326 | { | 330 | { |
327 | int offset; | 331 | int offset; |
328 | u64 val; | 332 | u64 val; |
333 | int valid = 0; | ||
334 | |||
335 | preempt_disable(); | ||
329 | 336 | ||
330 | rdmsrl(MSR_AMD64_IBSCTL, val); | 337 | rdmsrl(MSR_AMD64_IBSCTL, val); |
331 | offset = val & IBSCTL_LVT_OFFSET_MASK; | 338 | offset = val & IBSCTL_LVT_OFFSET_MASK; |
@@ -333,16 +340,20 @@ static inline int ibs_eilvt_valid(void) | |||
333 | if (!(val & IBSCTL_LVT_OFFSET_VALID)) { | 340 | if (!(val & IBSCTL_LVT_OFFSET_VALID)) { |
334 | pr_err(FW_BUG "cpu %d, invalid IBS interrupt offset %d (MSR%08X=0x%016llx)\n", | 341 | pr_err(FW_BUG "cpu %d, invalid IBS interrupt offset %d (MSR%08X=0x%016llx)\n", |
335 | smp_processor_id(), offset, MSR_AMD64_IBSCTL, val); | 342 | smp_processor_id(), offset, MSR_AMD64_IBSCTL, val); |
336 | return 0; | 343 | goto out; |
337 | } | 344 | } |
338 | 345 | ||
339 | if (!eilvt_is_available(offset)) { | 346 | if (!get_eilvt(offset)) { |
340 | pr_err(FW_BUG "cpu %d, IBS interrupt offset %d not available (MSR%08X=0x%016llx)\n", | 347 | pr_err(FW_BUG "cpu %d, IBS interrupt offset %d not available (MSR%08X=0x%016llx)\n", |
341 | smp_processor_id(), offset, MSR_AMD64_IBSCTL, val); | 348 | smp_processor_id(), offset, MSR_AMD64_IBSCTL, val); |
342 | return 0; | 349 | goto out; |
343 | } | 350 | } |
344 | 351 | ||
345 | return 1; | 352 | valid = 1; |
353 | out: | ||
354 | preempt_enable(); | ||
355 | |||
356 | return valid; | ||
346 | } | 357 | } |
347 | 358 | ||
348 | static inline int get_ibs_offset(void) | 359 | static inline int get_ibs_offset(void) |
@@ -600,67 +611,69 @@ static int setup_ibs_ctl(int ibs_eilvt_off) | |||
600 | 611 | ||
601 | static int force_ibs_eilvt_setup(void) | 612 | static int force_ibs_eilvt_setup(void) |
602 | { | 613 | { |
603 | int i; | 614 | int offset; |
604 | int ret; | 615 | int ret; |
605 | 616 | ||
606 | /* find the next free available EILVT entry */ | 617 | /* |
607 | for (i = 1; i < 4; i++) { | 618 | * find the next free available EILVT entry, skip offset 0, |
608 | if (!eilvt_is_available(i)) | 619 | * pin search to this cpu |
609 | continue; | 620 | */ |
610 | ret = setup_ibs_ctl(i); | 621 | preempt_disable(); |
611 | if (ret) | 622 | for (offset = 1; offset < APIC_EILVT_NR_MAX; offset++) { |
612 | return ret; | 623 | if (get_eilvt(offset)) |
613 | pr_err(FW_BUG "using offset %d for IBS interrupts\n", i); | 624 | break; |
614 | return 0; | ||
615 | } | 625 | } |
626 | preempt_enable(); | ||
616 | 627 | ||
617 | printk(KERN_DEBUG "No EILVT entry available\n"); | 628 | if (offset == APIC_EILVT_NR_MAX) { |
618 | 629 | printk(KERN_DEBUG "No EILVT entry available\n"); | |
619 | return -EBUSY; | 630 | return -EBUSY; |
620 | } | 631 | } |
621 | |||
622 | static int __init_ibs_nmi(void) | ||
623 | { | ||
624 | int ret; | ||
625 | |||
626 | if (ibs_eilvt_valid()) | ||
627 | return 0; | ||
628 | 632 | ||
629 | ret = force_ibs_eilvt_setup(); | 633 | ret = setup_ibs_ctl(offset); |
630 | if (ret) | 634 | if (ret) |
631 | return ret; | 635 | goto out; |
632 | 636 | ||
633 | if (!ibs_eilvt_valid()) | 637 | if (!ibs_eilvt_valid()) { |
634 | return -EFAULT; | 638 | ret = -EFAULT; |
639 | goto out; | ||
640 | } | ||
635 | 641 | ||
642 | pr_err(FW_BUG "using offset %d for IBS interrupts\n", offset); | ||
636 | pr_err(FW_BUG "workaround enabled for IBS LVT offset\n"); | 643 | pr_err(FW_BUG "workaround enabled for IBS LVT offset\n"); |
637 | 644 | ||
638 | return 0; | 645 | return 0; |
646 | out: | ||
647 | preempt_disable(); | ||
648 | put_eilvt(offset); | ||
649 | preempt_enable(); | ||
650 | return ret; | ||
639 | } | 651 | } |
640 | 652 | ||
641 | /* | 653 | /* |
642 | * check and reserve APIC extended interrupt LVT offset for IBS if | 654 | * check and reserve APIC extended interrupt LVT offset for IBS if |
643 | * available | 655 | * available |
644 | * | ||
645 | * init_ibs() preforms implicitly cpu-local operations, so pin this | ||
646 | * thread to its current CPU | ||
647 | */ | 656 | */ |
648 | 657 | ||
649 | static void init_ibs(void) | 658 | static void init_ibs(void) |
650 | { | 659 | { |
651 | preempt_disable(); | ||
652 | |||
653 | ibs_caps = get_ibs_caps(); | 660 | ibs_caps = get_ibs_caps(); |
661 | |||
654 | if (!ibs_caps) | 662 | if (!ibs_caps) |
663 | return; | ||
664 | |||
665 | if (ibs_eilvt_valid()) | ||
655 | goto out; | 666 | goto out; |
656 | 667 | ||
657 | if (__init_ibs_nmi() < 0) | 668 | if (!force_ibs_eilvt_setup()) |
658 | ibs_caps = 0; | 669 | goto out; |
659 | else | 670 | |
660 | printk(KERN_INFO "oprofile: AMD IBS detected (0x%08x)\n", ibs_caps); | 671 | /* Failed to setup ibs */ |
672 | ibs_caps = 0; | ||
673 | return; | ||
661 | 674 | ||
662 | out: | 675 | out: |
663 | preempt_enable(); | 676 | printk(KERN_INFO "oprofile: AMD IBS detected (0x%08x)\n", ibs_caps); |
664 | } | 677 | } |
665 | 678 | ||
666 | static int (*create_arch_files)(struct super_block *sb, struct dentry *root); | 679 | static int (*create_arch_files)(struct super_block *sb, struct dentry *root); |
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index b30aa26a8df2..0d3a4fa34560 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c | |||
@@ -304,6 +304,40 @@ static void __init print_efi_memmap(void) | |||
304 | } | 304 | } |
305 | #endif /* EFI_DEBUG */ | 305 | #endif /* EFI_DEBUG */ |
306 | 306 | ||
307 | void __init efi_reserve_boot_services(void) | ||
308 | { | ||
309 | void *p; | ||
310 | |||
311 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | ||
312 | efi_memory_desc_t *md = p; | ||
313 | unsigned long long start = md->phys_addr; | ||
314 | unsigned long long size = md->num_pages << EFI_PAGE_SHIFT; | ||
315 | |||
316 | if (md->type != EFI_BOOT_SERVICES_CODE && | ||
317 | md->type != EFI_BOOT_SERVICES_DATA) | ||
318 | continue; | ||
319 | |||
320 | memblock_x86_reserve_range(start, start + size, "EFI Boot"); | ||
321 | } | ||
322 | } | ||
323 | |||
324 | static void __init efi_free_boot_services(void) | ||
325 | { | ||
326 | void *p; | ||
327 | |||
328 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | ||
329 | efi_memory_desc_t *md = p; | ||
330 | unsigned long long start = md->phys_addr; | ||
331 | unsigned long long size = md->num_pages << EFI_PAGE_SHIFT; | ||
332 | |||
333 | if (md->type != EFI_BOOT_SERVICES_CODE && | ||
334 | md->type != EFI_BOOT_SERVICES_DATA) | ||
335 | continue; | ||
336 | |||
337 | free_bootmem_late(start, size); | ||
338 | } | ||
339 | } | ||
340 | |||
307 | void __init efi_init(void) | 341 | void __init efi_init(void) |
308 | { | 342 | { |
309 | efi_config_table_t *config_tables; | 343 | efi_config_table_t *config_tables; |
@@ -536,7 +570,9 @@ void __init efi_enter_virtual_mode(void) | |||
536 | 570 | ||
537 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | 571 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { |
538 | md = p; | 572 | md = p; |
539 | if (!(md->attribute & EFI_MEMORY_RUNTIME)) | 573 | if (!(md->attribute & EFI_MEMORY_RUNTIME) && |
574 | md->type != EFI_BOOT_SERVICES_CODE && | ||
575 | md->type != EFI_BOOT_SERVICES_DATA) | ||
540 | continue; | 576 | continue; |
541 | 577 | ||
542 | size = md->num_pages << EFI_PAGE_SHIFT; | 578 | size = md->num_pages << EFI_PAGE_SHIFT; |
@@ -593,6 +629,13 @@ void __init efi_enter_virtual_mode(void) | |||
593 | } | 629 | } |
594 | 630 | ||
595 | /* | 631 | /* |
632 | * Thankfully, it does seem that no runtime services other than | ||
633 | * SetVirtualAddressMap() will touch boot services code, so we can | ||
634 | * get rid of it all at this point | ||
635 | */ | ||
636 | efi_free_boot_services(); | ||
637 | |||
638 | /* | ||
596 | * Now that EFI is in virtual mode, update the function | 639 | * Now that EFI is in virtual mode, update the function |
597 | * pointers in the runtime service table to the new virtual addresses. | 640 | * pointers in the runtime service table to the new virtual addresses. |
598 | * | 641 | * |
diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index 2649426a7905..ac3aa54e2654 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c | |||
@@ -49,10 +49,11 @@ static void __init early_code_mapping_set_exec(int executable) | |||
49 | if (!(__supported_pte_mask & _PAGE_NX)) | 49 | if (!(__supported_pte_mask & _PAGE_NX)) |
50 | return; | 50 | return; |
51 | 51 | ||
52 | /* Make EFI runtime service code area executable */ | 52 | /* Make EFI service code area executable */ |
53 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | 53 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { |
54 | md = p; | 54 | md = p; |
55 | if (md->type == EFI_RUNTIME_SERVICES_CODE) | 55 | if (md->type == EFI_RUNTIME_SERVICES_CODE || |
56 | md->type == EFI_BOOT_SERVICES_CODE) | ||
56 | efi_set_executable(md, executable); | 57 | efi_set_executable(md, executable); |
57 | } | 58 | } |
58 | } | 59 | } |
diff --git a/arch/x86/platform/uv/tlb_uv.c b/arch/x86/platform/uv/tlb_uv.c index c58e0ea39ef5..68e467f69fec 100644 --- a/arch/x86/platform/uv/tlb_uv.c +++ b/arch/x86/platform/uv/tlb_uv.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * SGI UltraViolet TLB flush routines. | 2 | * SGI UltraViolet TLB flush routines. |
3 | * | 3 | * |
4 | * (c) 2008-2010 Cliff Wickman <cpw@sgi.com>, SGI. | 4 | * (c) 2008-2011 Cliff Wickman <cpw@sgi.com>, SGI. |
5 | * | 5 | * |
6 | * This code is released under the GNU General Public License version 2 or | 6 | * This code is released under the GNU General Public License version 2 or |
7 | * later. | 7 | * later. |
@@ -35,6 +35,7 @@ static int timeout_base_ns[] = { | |||
35 | 5242880, | 35 | 5242880, |
36 | 167772160 | 36 | 167772160 |
37 | }; | 37 | }; |
38 | |||
38 | static int timeout_us; | 39 | static int timeout_us; |
39 | static int nobau; | 40 | static int nobau; |
40 | static int baudisabled; | 41 | static int baudisabled; |
@@ -42,20 +43,70 @@ static spinlock_t disable_lock; | |||
42 | static cycles_t congested_cycles; | 43 | static cycles_t congested_cycles; |
43 | 44 | ||
44 | /* tunables: */ | 45 | /* tunables: */ |
45 | static int max_bau_concurrent = MAX_BAU_CONCURRENT; | 46 | static int max_concurr = MAX_BAU_CONCURRENT; |
46 | static int max_bau_concurrent_constant = MAX_BAU_CONCURRENT; | 47 | static int max_concurr_const = MAX_BAU_CONCURRENT; |
47 | static int plugged_delay = PLUGGED_DELAY; | 48 | static int plugged_delay = PLUGGED_DELAY; |
48 | static int plugsb4reset = PLUGSB4RESET; | 49 | static int plugsb4reset = PLUGSB4RESET; |
49 | static int timeoutsb4reset = TIMEOUTSB4RESET; | 50 | static int timeoutsb4reset = TIMEOUTSB4RESET; |
50 | static int ipi_reset_limit = IPI_RESET_LIMIT; | 51 | static int ipi_reset_limit = IPI_RESET_LIMIT; |
51 | static int complete_threshold = COMPLETE_THRESHOLD; | 52 | static int complete_threshold = COMPLETE_THRESHOLD; |
52 | static int congested_response_us = CONGESTED_RESPONSE_US; | 53 | static int congested_respns_us = CONGESTED_RESPONSE_US; |
53 | static int congested_reps = CONGESTED_REPS; | 54 | static int congested_reps = CONGESTED_REPS; |
54 | static int congested_period = CONGESTED_PERIOD; | 55 | static int congested_period = CONGESTED_PERIOD; |
56 | |||
57 | static struct tunables tunables[] = { | ||
58 | {&max_concurr, MAX_BAU_CONCURRENT}, /* must be [0] */ | ||
59 | {&plugged_delay, PLUGGED_DELAY}, | ||
60 | {&plugsb4reset, PLUGSB4RESET}, | ||
61 | {&timeoutsb4reset, TIMEOUTSB4RESET}, | ||
62 | {&ipi_reset_limit, IPI_RESET_LIMIT}, | ||
63 | {&complete_threshold, COMPLETE_THRESHOLD}, | ||
64 | {&congested_respns_us, CONGESTED_RESPONSE_US}, | ||
65 | {&congested_reps, CONGESTED_REPS}, | ||
66 | {&congested_period, CONGESTED_PERIOD} | ||
67 | }; | ||
68 | |||
55 | static struct dentry *tunables_dir; | 69 | static struct dentry *tunables_dir; |
56 | static struct dentry *tunables_file; | 70 | static struct dentry *tunables_file; |
57 | 71 | ||
58 | static int __init setup_nobau(char *arg) | 72 | /* these correspond to the statistics printed by ptc_seq_show() */ |
73 | static char *stat_description[] = { | ||
74 | "sent: number of shootdown messages sent", | ||
75 | "stime: time spent sending messages", | ||
76 | "numuvhubs: number of hubs targeted with shootdown", | ||
77 | "numuvhubs16: number times 16 or more hubs targeted", | ||
78 | "numuvhubs8: number times 8 or more hubs targeted", | ||
79 | "numuvhubs4: number times 4 or more hubs targeted", | ||
80 | "numuvhubs2: number times 2 or more hubs targeted", | ||
81 | "numuvhubs1: number times 1 hub targeted", | ||
82 | "numcpus: number of cpus targeted with shootdown", | ||
83 | "dto: number of destination timeouts", | ||
84 | "retries: destination timeout retries sent", | ||
85 | "rok: : destination timeouts successfully retried", | ||
86 | "resetp: ipi-style resource resets for plugs", | ||
87 | "resett: ipi-style resource resets for timeouts", | ||
88 | "giveup: fall-backs to ipi-style shootdowns", | ||
89 | "sto: number of source timeouts", | ||
90 | "bz: number of stay-busy's", | ||
91 | "throt: number times spun in throttle", | ||
92 | "swack: image of UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE", | ||
93 | "recv: shootdown messages received", | ||
94 | "rtime: time spent processing messages", | ||
95 | "all: shootdown all-tlb messages", | ||
96 | "one: shootdown one-tlb messages", | ||
97 | "mult: interrupts that found multiple messages", | ||
98 | "none: interrupts that found no messages", | ||
99 | "retry: number of retry messages processed", | ||
100 | "canc: number messages canceled by retries", | ||
101 | "nocan: number retries that found nothing to cancel", | ||
102 | "reset: number of ipi-style reset requests processed", | ||
103 | "rcan: number messages canceled by reset requests", | ||
104 | "disable: number times use of the BAU was disabled", | ||
105 | "enable: number times use of the BAU was re-enabled" | ||
106 | }; | ||
107 | |||
108 | static int __init | ||
109 | setup_nobau(char *arg) | ||
59 | { | 110 | { |
60 | nobau = 1; | 111 | nobau = 1; |
61 | return 0; | 112 | return 0; |
@@ -63,7 +114,7 @@ static int __init setup_nobau(char *arg) | |||
63 | early_param("nobau", setup_nobau); | 114 | early_param("nobau", setup_nobau); |
64 | 115 | ||
65 | /* base pnode in this partition */ | 116 | /* base pnode in this partition */ |
66 | static int uv_partition_base_pnode __read_mostly; | 117 | static int uv_base_pnode __read_mostly; |
67 | /* position of pnode (which is nasid>>1): */ | 118 | /* position of pnode (which is nasid>>1): */ |
68 | static int uv_nshift __read_mostly; | 119 | static int uv_nshift __read_mostly; |
69 | static unsigned long uv_mmask __read_mostly; | 120 | static unsigned long uv_mmask __read_mostly; |
@@ -109,60 +160,52 @@ static int __init uvhub_to_first_apicid(int uvhub) | |||
109 | * clear of the Timeout bit (as well) will free the resource. No reply will | 160 | * clear of the Timeout bit (as well) will free the resource. No reply will |
110 | * be sent (the hardware will only do one reply per message). | 161 | * be sent (the hardware will only do one reply per message). |
111 | */ | 162 | */ |
112 | static inline void uv_reply_to_message(struct msg_desc *mdp, | 163 | static void reply_to_message(struct msg_desc *mdp, struct bau_control *bcp) |
113 | struct bau_control *bcp) | ||
114 | { | 164 | { |
115 | unsigned long dw; | 165 | unsigned long dw; |
116 | struct bau_payload_queue_entry *msg; | 166 | struct bau_pq_entry *msg; |
117 | 167 | ||
118 | msg = mdp->msg; | 168 | msg = mdp->msg; |
119 | if (!msg->canceled) { | 169 | if (!msg->canceled) { |
120 | dw = (msg->sw_ack_vector << UV_SW_ACK_NPENDING) | | 170 | dw = (msg->swack_vec << UV_SW_ACK_NPENDING) | msg->swack_vec; |
121 | msg->sw_ack_vector; | 171 | write_mmr_sw_ack(dw); |
122 | uv_write_local_mmr( | ||
123 | UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS, dw); | ||
124 | } | 172 | } |
125 | msg->replied_to = 1; | 173 | msg->replied_to = 1; |
126 | msg->sw_ack_vector = 0; | 174 | msg->swack_vec = 0; |
127 | } | 175 | } |
128 | 176 | ||
129 | /* | 177 | /* |
130 | * Process the receipt of a RETRY message | 178 | * Process the receipt of a RETRY message |
131 | */ | 179 | */ |
132 | static inline void uv_bau_process_retry_msg(struct msg_desc *mdp, | 180 | static void bau_process_retry_msg(struct msg_desc *mdp, |
133 | struct bau_control *bcp) | 181 | struct bau_control *bcp) |
134 | { | 182 | { |
135 | int i; | 183 | int i; |
136 | int cancel_count = 0; | 184 | int cancel_count = 0; |
137 | int slot2; | ||
138 | unsigned long msg_res; | 185 | unsigned long msg_res; |
139 | unsigned long mmr = 0; | 186 | unsigned long mmr = 0; |
140 | struct bau_payload_queue_entry *msg; | 187 | struct bau_pq_entry *msg = mdp->msg; |
141 | struct bau_payload_queue_entry *msg2; | 188 | struct bau_pq_entry *msg2; |
142 | struct ptc_stats *stat; | 189 | struct ptc_stats *stat = bcp->statp; |
143 | 190 | ||
144 | msg = mdp->msg; | ||
145 | stat = bcp->statp; | ||
146 | stat->d_retries++; | 191 | stat->d_retries++; |
147 | /* | 192 | /* |
148 | * cancel any message from msg+1 to the retry itself | 193 | * cancel any message from msg+1 to the retry itself |
149 | */ | 194 | */ |
150 | for (msg2 = msg+1, i = 0; i < DEST_Q_SIZE; msg2++, i++) { | 195 | for (msg2 = msg+1, i = 0; i < DEST_Q_SIZE; msg2++, i++) { |
151 | if (msg2 > mdp->va_queue_last) | 196 | if (msg2 > mdp->queue_last) |
152 | msg2 = mdp->va_queue_first; | 197 | msg2 = mdp->queue_first; |
153 | if (msg2 == msg) | 198 | if (msg2 == msg) |
154 | break; | 199 | break; |
155 | 200 | ||
156 | /* same conditions for cancellation as uv_do_reset */ | 201 | /* same conditions for cancellation as do_reset */ |
157 | if ((msg2->replied_to == 0) && (msg2->canceled == 0) && | 202 | if ((msg2->replied_to == 0) && (msg2->canceled == 0) && |
158 | (msg2->sw_ack_vector) && ((msg2->sw_ack_vector & | 203 | (msg2->swack_vec) && ((msg2->swack_vec & |
159 | msg->sw_ack_vector) == 0) && | 204 | msg->swack_vec) == 0) && |
160 | (msg2->sending_cpu == msg->sending_cpu) && | 205 | (msg2->sending_cpu == msg->sending_cpu) && |
161 | (msg2->msg_type != MSG_NOOP)) { | 206 | (msg2->msg_type != MSG_NOOP)) { |
162 | slot2 = msg2 - mdp->va_queue_first; | 207 | mmr = read_mmr_sw_ack(); |
163 | mmr = uv_read_local_mmr | 208 | msg_res = msg2->swack_vec; |
164 | (UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE); | ||
165 | msg_res = msg2->sw_ack_vector; | ||
166 | /* | 209 | /* |
167 | * This is a message retry; clear the resources held | 210 | * This is a message retry; clear the resources held |
168 | * by the previous message only if they timed out. | 211 | * by the previous message only if they timed out. |
@@ -170,6 +213,7 @@ static inline void uv_bau_process_retry_msg(struct msg_desc *mdp, | |||
170 | * situation to report. | 213 | * situation to report. |
171 | */ | 214 | */ |
172 | if (mmr & (msg_res << UV_SW_ACK_NPENDING)) { | 215 | if (mmr & (msg_res << UV_SW_ACK_NPENDING)) { |
216 | unsigned long mr; | ||
173 | /* | 217 | /* |
174 | * is the resource timed out? | 218 | * is the resource timed out? |
175 | * make everyone ignore the cancelled message. | 219 | * make everyone ignore the cancelled message. |
@@ -177,10 +221,8 @@ static inline void uv_bau_process_retry_msg(struct msg_desc *mdp, | |||
177 | msg2->canceled = 1; | 221 | msg2->canceled = 1; |
178 | stat->d_canceled++; | 222 | stat->d_canceled++; |
179 | cancel_count++; | 223 | cancel_count++; |
180 | uv_write_local_mmr( | 224 | mr = (msg_res << UV_SW_ACK_NPENDING) | msg_res; |
181 | UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS, | 225 | write_mmr_sw_ack(mr); |
182 | (msg_res << UV_SW_ACK_NPENDING) | | ||
183 | msg_res); | ||
184 | } | 226 | } |
185 | } | 227 | } |
186 | } | 228 | } |
@@ -192,20 +234,19 @@ static inline void uv_bau_process_retry_msg(struct msg_desc *mdp, | |||
192 | * Do all the things a cpu should do for a TLB shootdown message. | 234 | * Do all the things a cpu should do for a TLB shootdown message. |
193 | * Other cpu's may come here at the same time for this message. | 235 | * Other cpu's may come here at the same time for this message. |
194 | */ | 236 | */ |
195 | static void uv_bau_process_message(struct msg_desc *mdp, | 237 | static void bau_process_message(struct msg_desc *mdp, |
196 | struct bau_control *bcp) | 238 | struct bau_control *bcp) |
197 | { | 239 | { |
198 | int msg_ack_count; | ||
199 | short socket_ack_count = 0; | 240 | short socket_ack_count = 0; |
200 | struct ptc_stats *stat; | 241 | short *sp; |
201 | struct bau_payload_queue_entry *msg; | 242 | struct atomic_short *asp; |
243 | struct ptc_stats *stat = bcp->statp; | ||
244 | struct bau_pq_entry *msg = mdp->msg; | ||
202 | struct bau_control *smaster = bcp->socket_master; | 245 | struct bau_control *smaster = bcp->socket_master; |
203 | 246 | ||
204 | /* | 247 | /* |
205 | * This must be a normal message, or retry of a normal message | 248 | * This must be a normal message, or retry of a normal message |
206 | */ | 249 | */ |
207 | msg = mdp->msg; | ||
208 | stat = bcp->statp; | ||
209 | if (msg->address == TLB_FLUSH_ALL) { | 250 | if (msg->address == TLB_FLUSH_ALL) { |
210 | local_flush_tlb(); | 251 | local_flush_tlb(); |
211 | stat->d_alltlb++; | 252 | stat->d_alltlb++; |
@@ -222,30 +263,32 @@ static void uv_bau_process_message(struct msg_desc *mdp, | |||
222 | * cpu number. | 263 | * cpu number. |
223 | */ | 264 | */ |
224 | if (msg->msg_type == MSG_RETRY && bcp == bcp->uvhub_master) | 265 | if (msg->msg_type == MSG_RETRY && bcp == bcp->uvhub_master) |
225 | uv_bau_process_retry_msg(mdp, bcp); | 266 | bau_process_retry_msg(mdp, bcp); |
226 | 267 | ||
227 | /* | 268 | /* |
228 | * This is a sw_ack message, so we have to reply to it. | 269 | * This is a swack message, so we have to reply to it. |
229 | * Count each responding cpu on the socket. This avoids | 270 | * Count each responding cpu on the socket. This avoids |
230 | * pinging the count's cache line back and forth between | 271 | * pinging the count's cache line back and forth between |
231 | * the sockets. | 272 | * the sockets. |
232 | */ | 273 | */ |
233 | socket_ack_count = atomic_add_short_return(1, (struct atomic_short *) | 274 | sp = &smaster->socket_acknowledge_count[mdp->msg_slot]; |
234 | &smaster->socket_acknowledge_count[mdp->msg_slot]); | 275 | asp = (struct atomic_short *)sp; |
276 | socket_ack_count = atom_asr(1, asp); | ||
235 | if (socket_ack_count == bcp->cpus_in_socket) { | 277 | if (socket_ack_count == bcp->cpus_in_socket) { |
278 | int msg_ack_count; | ||
236 | /* | 279 | /* |
237 | * Both sockets dump their completed count total into | 280 | * Both sockets dump their completed count total into |
238 | * the message's count. | 281 | * the message's count. |
239 | */ | 282 | */ |
240 | smaster->socket_acknowledge_count[mdp->msg_slot] = 0; | 283 | smaster->socket_acknowledge_count[mdp->msg_slot] = 0; |
241 | msg_ack_count = atomic_add_short_return(socket_ack_count, | 284 | asp = (struct atomic_short *)&msg->acknowledge_count; |
242 | (struct atomic_short *)&msg->acknowledge_count); | 285 | msg_ack_count = atom_asr(socket_ack_count, asp); |
243 | 286 | ||
244 | if (msg_ack_count == bcp->cpus_in_uvhub) { | 287 | if (msg_ack_count == bcp->cpus_in_uvhub) { |
245 | /* | 288 | /* |
246 | * All cpus in uvhub saw it; reply | 289 | * All cpus in uvhub saw it; reply |
247 | */ | 290 | */ |
248 | uv_reply_to_message(mdp, bcp); | 291 | reply_to_message(mdp, bcp); |
249 | } | 292 | } |
250 | } | 293 | } |
251 | 294 | ||
@@ -268,62 +311,51 @@ static int uvhub_to_first_cpu(int uvhub) | |||
268 | * Last resort when we get a large number of destination timeouts is | 311 | * Last resort when we get a large number of destination timeouts is |
269 | * to clear resources held by a given cpu. | 312 | * to clear resources held by a given cpu. |
270 | * Do this with IPI so that all messages in the BAU message queue | 313 | * Do this with IPI so that all messages in the BAU message queue |
271 | * can be identified by their nonzero sw_ack_vector field. | 314 | * can be identified by their nonzero swack_vec field. |
272 | * | 315 | * |
273 | * This is entered for a single cpu on the uvhub. | 316 | * This is entered for a single cpu on the uvhub. |
274 | * The sender want's this uvhub to free a specific message's | 317 | * The sender want's this uvhub to free a specific message's |
275 | * sw_ack resources. | 318 | * swack resources. |
276 | */ | 319 | */ |
277 | static void | 320 | static void do_reset(void *ptr) |
278 | uv_do_reset(void *ptr) | ||
279 | { | 321 | { |
280 | int i; | 322 | int i; |
281 | int slot; | 323 | struct bau_control *bcp = &per_cpu(bau_control, smp_processor_id()); |
282 | int count = 0; | 324 | struct reset_args *rap = (struct reset_args *)ptr; |
283 | unsigned long mmr; | 325 | struct bau_pq_entry *msg; |
284 | unsigned long msg_res; | 326 | struct ptc_stats *stat = bcp->statp; |
285 | struct bau_control *bcp; | ||
286 | struct reset_args *rap; | ||
287 | struct bau_payload_queue_entry *msg; | ||
288 | struct ptc_stats *stat; | ||
289 | 327 | ||
290 | bcp = &per_cpu(bau_control, smp_processor_id()); | ||
291 | rap = (struct reset_args *)ptr; | ||
292 | stat = bcp->statp; | ||
293 | stat->d_resets++; | 328 | stat->d_resets++; |
294 | |||
295 | /* | 329 | /* |
296 | * We're looking for the given sender, and | 330 | * We're looking for the given sender, and |
297 | * will free its sw_ack resource. | 331 | * will free its swack resource. |
298 | * If all cpu's finally responded after the timeout, its | 332 | * If all cpu's finally responded after the timeout, its |
299 | * message 'replied_to' was set. | 333 | * message 'replied_to' was set. |
300 | */ | 334 | */ |
301 | for (msg = bcp->va_queue_first, i = 0; i < DEST_Q_SIZE; msg++, i++) { | 335 | for (msg = bcp->queue_first, i = 0; i < DEST_Q_SIZE; msg++, i++) { |
302 | /* uv_do_reset: same conditions for cancellation as | 336 | unsigned long msg_res; |
303 | uv_bau_process_retry_msg() */ | 337 | /* do_reset: same conditions for cancellation as |
338 | bau_process_retry_msg() */ | ||
304 | if ((msg->replied_to == 0) && | 339 | if ((msg->replied_to == 0) && |
305 | (msg->canceled == 0) && | 340 | (msg->canceled == 0) && |
306 | (msg->sending_cpu == rap->sender) && | 341 | (msg->sending_cpu == rap->sender) && |
307 | (msg->sw_ack_vector) && | 342 | (msg->swack_vec) && |
308 | (msg->msg_type != MSG_NOOP)) { | 343 | (msg->msg_type != MSG_NOOP)) { |
344 | unsigned long mmr; | ||
345 | unsigned long mr; | ||
309 | /* | 346 | /* |
310 | * make everyone else ignore this message | 347 | * make everyone else ignore this message |
311 | */ | 348 | */ |
312 | msg->canceled = 1; | 349 | msg->canceled = 1; |
313 | slot = msg - bcp->va_queue_first; | ||
314 | count++; | ||
315 | /* | 350 | /* |
316 | * only reset the resource if it is still pending | 351 | * only reset the resource if it is still pending |
317 | */ | 352 | */ |
318 | mmr = uv_read_local_mmr | 353 | mmr = read_mmr_sw_ack(); |
319 | (UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE); | 354 | msg_res = msg->swack_vec; |
320 | msg_res = msg->sw_ack_vector; | 355 | mr = (msg_res << UV_SW_ACK_NPENDING) | msg_res; |
321 | if (mmr & msg_res) { | 356 | if (mmr & msg_res) { |
322 | stat->d_rcanceled++; | 357 | stat->d_rcanceled++; |
323 | uv_write_local_mmr( | 358 | write_mmr_sw_ack(mr); |
324 | UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS, | ||
325 | (msg_res << UV_SW_ACK_NPENDING) | | ||
326 | msg_res); | ||
327 | } | 359 | } |
328 | } | 360 | } |
329 | } | 361 | } |
@@ -334,39 +366,38 @@ uv_do_reset(void *ptr) | |||
334 | * Use IPI to get all target uvhubs to release resources held by | 366 | * Use IPI to get all target uvhubs to release resources held by |
335 | * a given sending cpu number. | 367 | * a given sending cpu number. |
336 | */ | 368 | */ |
337 | static void uv_reset_with_ipi(struct bau_target_uvhubmask *distribution, | 369 | static void reset_with_ipi(struct bau_targ_hubmask *distribution, int sender) |
338 | int sender) | ||
339 | { | 370 | { |
340 | int uvhub; | 371 | int uvhub; |
341 | int cpu; | 372 | int maskbits; |
342 | cpumask_t mask; | 373 | cpumask_t mask; |
343 | struct reset_args reset_args; | 374 | struct reset_args reset_args; |
344 | 375 | ||
345 | reset_args.sender = sender; | 376 | reset_args.sender = sender; |
346 | |||
347 | cpus_clear(mask); | 377 | cpus_clear(mask); |
348 | /* find a single cpu for each uvhub in this distribution mask */ | 378 | /* find a single cpu for each uvhub in this distribution mask */ |
349 | for (uvhub = 0; | 379 | maskbits = sizeof(struct bau_targ_hubmask) * BITSPERBYTE; |
350 | uvhub < sizeof(struct bau_target_uvhubmask) * BITSPERBYTE; | 380 | for (uvhub = 0; uvhub < maskbits; uvhub++) { |
351 | uvhub++) { | 381 | int cpu; |
352 | if (!bau_uvhub_isset(uvhub, distribution)) | 382 | if (!bau_uvhub_isset(uvhub, distribution)) |
353 | continue; | 383 | continue; |
354 | /* find a cpu for this uvhub */ | 384 | /* find a cpu for this uvhub */ |
355 | cpu = uvhub_to_first_cpu(uvhub); | 385 | cpu = uvhub_to_first_cpu(uvhub); |
356 | cpu_set(cpu, mask); | 386 | cpu_set(cpu, mask); |
357 | } | 387 | } |
358 | /* IPI all cpus; Preemption is already disabled */ | 388 | |
359 | smp_call_function_many(&mask, uv_do_reset, (void *)&reset_args, 1); | 389 | /* IPI all cpus; preemption is already disabled */ |
390 | smp_call_function_many(&mask, do_reset, (void *)&reset_args, 1); | ||
360 | return; | 391 | return; |
361 | } | 392 | } |
362 | 393 | ||
363 | static inline unsigned long | 394 | static inline unsigned long cycles_2_us(unsigned long long cyc) |
364 | cycles_2_us(unsigned long long cyc) | ||
365 | { | 395 | { |
366 | unsigned long long ns; | 396 | unsigned long long ns; |
367 | unsigned long us; | 397 | unsigned long us; |
368 | ns = (cyc * per_cpu(cyc2ns, smp_processor_id())) | 398 | int cpu = smp_processor_id(); |
369 | >> CYC2NS_SCALE_FACTOR; | 399 | |
400 | ns = (cyc * per_cpu(cyc2ns, cpu)) >> CYC2NS_SCALE_FACTOR; | ||
370 | us = ns / 1000; | 401 | us = ns / 1000; |
371 | return us; | 402 | return us; |
372 | } | 403 | } |
@@ -376,56 +407,56 @@ cycles_2_us(unsigned long long cyc) | |||
376 | * leaves uvhub_quiesce set so that no new broadcasts are started by | 407 | * leaves uvhub_quiesce set so that no new broadcasts are started by |
377 | * bau_flush_send_and_wait() | 408 | * bau_flush_send_and_wait() |
378 | */ | 409 | */ |
379 | static inline void | 410 | static inline void quiesce_local_uvhub(struct bau_control *hmaster) |
380 | quiesce_local_uvhub(struct bau_control *hmaster) | ||
381 | { | 411 | { |
382 | atomic_add_short_return(1, (struct atomic_short *) | 412 | atom_asr(1, (struct atomic_short *)&hmaster->uvhub_quiesce); |
383 | &hmaster->uvhub_quiesce); | ||
384 | } | 413 | } |
385 | 414 | ||
386 | /* | 415 | /* |
387 | * mark this quiet-requestor as done | 416 | * mark this quiet-requestor as done |
388 | */ | 417 | */ |
389 | static inline void | 418 | static inline void end_uvhub_quiesce(struct bau_control *hmaster) |
390 | end_uvhub_quiesce(struct bau_control *hmaster) | ||
391 | { | 419 | { |
392 | atomic_add_short_return(-1, (struct atomic_short *) | 420 | atom_asr(-1, (struct atomic_short *)&hmaster->uvhub_quiesce); |
393 | &hmaster->uvhub_quiesce); | 421 | } |
422 | |||
423 | static unsigned long uv1_read_status(unsigned long mmr_offset, int right_shift) | ||
424 | { | ||
425 | unsigned long descriptor_status; | ||
426 | |||
427 | descriptor_status = uv_read_local_mmr(mmr_offset); | ||
428 | descriptor_status >>= right_shift; | ||
429 | descriptor_status &= UV_ACT_STATUS_MASK; | ||
430 | return descriptor_status; | ||
394 | } | 431 | } |
395 | 432 | ||
396 | /* | 433 | /* |
397 | * Wait for completion of a broadcast software ack message | 434 | * Wait for completion of a broadcast software ack message |
398 | * return COMPLETE, RETRY(PLUGGED or TIMEOUT) or GIVEUP | 435 | * return COMPLETE, RETRY(PLUGGED or TIMEOUT) or GIVEUP |
399 | */ | 436 | */ |
400 | static int uv_wait_completion(struct bau_desc *bau_desc, | 437 | static int uv1_wait_completion(struct bau_desc *bau_desc, |
401 | unsigned long mmr_offset, int right_shift, int this_cpu, | 438 | unsigned long mmr_offset, int right_shift, |
402 | struct bau_control *bcp, struct bau_control *smaster, long try) | 439 | struct bau_control *bcp, long try) |
403 | { | 440 | { |
404 | unsigned long descriptor_status; | 441 | unsigned long descriptor_status; |
405 | cycles_t ttime; | 442 | cycles_t ttm; |
406 | struct ptc_stats *stat = bcp->statp; | 443 | struct ptc_stats *stat = bcp->statp; |
407 | struct bau_control *hmaster; | ||
408 | |||
409 | hmaster = bcp->uvhub_master; | ||
410 | 444 | ||
445 | descriptor_status = uv1_read_status(mmr_offset, right_shift); | ||
411 | /* spin on the status MMR, waiting for it to go idle */ | 446 | /* spin on the status MMR, waiting for it to go idle */ |
412 | while ((descriptor_status = (((unsigned long) | 447 | while ((descriptor_status != DS_IDLE)) { |
413 | uv_read_local_mmr(mmr_offset) >> | ||
414 | right_shift) & UV_ACT_STATUS_MASK)) != | ||
415 | DESC_STATUS_IDLE) { | ||
416 | /* | 448 | /* |
417 | * Our software ack messages may be blocked because there are | 449 | * Our software ack messages may be blocked because |
418 | * no swack resources available. As long as none of them | 450 | * there are no swack resources available. As long |
419 | * has timed out hardware will NACK our message and its | 451 | * as none of them has timed out hardware will NACK |
420 | * state will stay IDLE. | 452 | * our message and its state will stay IDLE. |
421 | */ | 453 | */ |
422 | if (descriptor_status == DESC_STATUS_SOURCE_TIMEOUT) { | 454 | if (descriptor_status == DS_SOURCE_TIMEOUT) { |
423 | stat->s_stimeout++; | 455 | stat->s_stimeout++; |
424 | return FLUSH_GIVEUP; | 456 | return FLUSH_GIVEUP; |
425 | } else if (descriptor_status == | 457 | } else if (descriptor_status == DS_DESTINATION_TIMEOUT) { |
426 | DESC_STATUS_DESTINATION_TIMEOUT) { | ||
427 | stat->s_dtimeout++; | 458 | stat->s_dtimeout++; |
428 | ttime = get_cycles(); | 459 | ttm = get_cycles(); |
429 | 460 | ||
430 | /* | 461 | /* |
431 | * Our retries may be blocked by all destination | 462 | * Our retries may be blocked by all destination |
@@ -433,8 +464,7 @@ static int uv_wait_completion(struct bau_desc *bau_desc, | |||
433 | * pending. In that case hardware returns the | 464 | * pending. In that case hardware returns the |
434 | * ERROR that looks like a destination timeout. | 465 | * ERROR that looks like a destination timeout. |
435 | */ | 466 | */ |
436 | if (cycles_2_us(ttime - bcp->send_message) < | 467 | if (cycles_2_us(ttm - bcp->send_message) < timeout_us) { |
437 | timeout_us) { | ||
438 | bcp->conseccompletes = 0; | 468 | bcp->conseccompletes = 0; |
439 | return FLUSH_RETRY_PLUGGED; | 469 | return FLUSH_RETRY_PLUGGED; |
440 | } | 470 | } |
@@ -447,80 +477,160 @@ static int uv_wait_completion(struct bau_desc *bau_desc, | |||
447 | */ | 477 | */ |
448 | cpu_relax(); | 478 | cpu_relax(); |
449 | } | 479 | } |
480 | descriptor_status = uv1_read_status(mmr_offset, right_shift); | ||
450 | } | 481 | } |
451 | bcp->conseccompletes++; | 482 | bcp->conseccompletes++; |
452 | return FLUSH_COMPLETE; | 483 | return FLUSH_COMPLETE; |
453 | } | 484 | } |
454 | 485 | ||
455 | static inline cycles_t | 486 | /* |
456 | sec_2_cycles(unsigned long sec) | 487 | * UV2 has an extra bit of status in the ACTIVATION_STATUS_2 register. |
488 | */ | ||
489 | static unsigned long uv2_read_status(unsigned long offset, int rshft, int cpu) | ||
457 | { | 490 | { |
458 | unsigned long ns; | 491 | unsigned long descriptor_status; |
459 | cycles_t cyc; | 492 | unsigned long descriptor_status2; |
460 | 493 | ||
461 | ns = sec * 1000000000; | 494 | descriptor_status = ((read_lmmr(offset) >> rshft) & UV_ACT_STATUS_MASK); |
462 | cyc = (ns << CYC2NS_SCALE_FACTOR)/(per_cpu(cyc2ns, smp_processor_id())); | 495 | descriptor_status2 = (read_mmr_uv2_status() >> cpu) & 0x1UL; |
463 | return cyc; | 496 | descriptor_status = (descriptor_status << 1) | descriptor_status2; |
497 | return descriptor_status; | ||
498 | } | ||
499 | |||
500 | static int uv2_wait_completion(struct bau_desc *bau_desc, | ||
501 | unsigned long mmr_offset, int right_shift, | ||
502 | struct bau_control *bcp, long try) | ||
503 | { | ||
504 | unsigned long descriptor_stat; | ||
505 | cycles_t ttm; | ||
506 | int cpu = bcp->uvhub_cpu; | ||
507 | struct ptc_stats *stat = bcp->statp; | ||
508 | |||
509 | descriptor_stat = uv2_read_status(mmr_offset, right_shift, cpu); | ||
510 | |||
511 | /* spin on the status MMR, waiting for it to go idle */ | ||
512 | while (descriptor_stat != UV2H_DESC_IDLE) { | ||
513 | /* | ||
514 | * Our software ack messages may be blocked because | ||
515 | * there are no swack resources available. As long | ||
516 | * as none of them has timed out hardware will NACK | ||
517 | * our message and its state will stay IDLE. | ||
518 | */ | ||
519 | if ((descriptor_stat == UV2H_DESC_SOURCE_TIMEOUT) || | ||
520 | (descriptor_stat == UV2H_DESC_DEST_STRONG_NACK) || | ||
521 | (descriptor_stat == UV2H_DESC_DEST_PUT_ERR)) { | ||
522 | stat->s_stimeout++; | ||
523 | return FLUSH_GIVEUP; | ||
524 | } else if (descriptor_stat == UV2H_DESC_DEST_TIMEOUT) { | ||
525 | stat->s_dtimeout++; | ||
526 | ttm = get_cycles(); | ||
527 | /* | ||
528 | * Our retries may be blocked by all destination | ||
529 | * swack resources being consumed, and a timeout | ||
530 | * pending. In that case hardware returns the | ||
531 | * ERROR that looks like a destination timeout. | ||
532 | */ | ||
533 | if (cycles_2_us(ttm - bcp->send_message) < timeout_us) { | ||
534 | bcp->conseccompletes = 0; | ||
535 | return FLUSH_RETRY_PLUGGED; | ||
536 | } | ||
537 | bcp->conseccompletes = 0; | ||
538 | return FLUSH_RETRY_TIMEOUT; | ||
539 | } else { | ||
540 | /* | ||
541 | * descriptor_stat is still BUSY | ||
542 | */ | ||
543 | cpu_relax(); | ||
544 | } | ||
545 | descriptor_stat = uv2_read_status(mmr_offset, right_shift, cpu); | ||
546 | } | ||
547 | bcp->conseccompletes++; | ||
548 | return FLUSH_COMPLETE; | ||
464 | } | 549 | } |
465 | 550 | ||
466 | /* | 551 | /* |
467 | * conditionally add 1 to *v, unless *v is >= u | 552 | * There are 2 status registers; each and array[32] of 2 bits. Set up for |
468 | * return 0 if we cannot add 1 to *v because it is >= u | 553 | * which register to read and position in that register based on cpu in |
469 | * return 1 if we can add 1 to *v because it is < u | 554 | * current hub. |
470 | * the add is atomic | ||
471 | * | ||
472 | * This is close to atomic_add_unless(), but this allows the 'u' value | ||
473 | * to be lowered below the current 'v'. atomic_add_unless can only stop | ||
474 | * on equal. | ||
475 | */ | 555 | */ |
476 | static inline int atomic_inc_unless_ge(spinlock_t *lock, atomic_t *v, int u) | 556 | static int wait_completion(struct bau_desc *bau_desc, |
557 | struct bau_control *bcp, long try) | ||
477 | { | 558 | { |
478 | spin_lock(lock); | 559 | int right_shift; |
479 | if (atomic_read(v) >= u) { | 560 | unsigned long mmr_offset; |
480 | spin_unlock(lock); | 561 | int cpu = bcp->uvhub_cpu; |
481 | return 0; | 562 | |
563 | if (cpu < UV_CPUS_PER_AS) { | ||
564 | mmr_offset = UVH_LB_BAU_SB_ACTIVATION_STATUS_0; | ||
565 | right_shift = cpu * UV_ACT_STATUS_SIZE; | ||
566 | } else { | ||
567 | mmr_offset = UVH_LB_BAU_SB_ACTIVATION_STATUS_1; | ||
568 | right_shift = ((cpu - UV_CPUS_PER_AS) * UV_ACT_STATUS_SIZE); | ||
482 | } | 569 | } |
483 | atomic_inc(v); | 570 | |
484 | spin_unlock(lock); | 571 | if (is_uv1_hub()) |
485 | return 1; | 572 | return uv1_wait_completion(bau_desc, mmr_offset, right_shift, |
573 | bcp, try); | ||
574 | else | ||
575 | return uv2_wait_completion(bau_desc, mmr_offset, right_shift, | ||
576 | bcp, try); | ||
577 | } | ||
578 | |||
579 | static inline cycles_t sec_2_cycles(unsigned long sec) | ||
580 | { | ||
581 | unsigned long ns; | ||
582 | cycles_t cyc; | ||
583 | |||
584 | ns = sec * 1000000000; | ||
585 | cyc = (ns << CYC2NS_SCALE_FACTOR)/(per_cpu(cyc2ns, smp_processor_id())); | ||
586 | return cyc; | ||
486 | } | 587 | } |
487 | 588 | ||
488 | /* | 589 | /* |
489 | * Our retries are blocked by all destination swack resources being | 590 | * Our retries are blocked by all destination sw ack resources being |
490 | * in use, and a timeout is pending. In that case hardware immediately | 591 | * in use, and a timeout is pending. In that case hardware immediately |
491 | * returns the ERROR that looks like a destination timeout. | 592 | * returns the ERROR that looks like a destination timeout. |
492 | */ | 593 | */ |
493 | static void | 594 | static void destination_plugged(struct bau_desc *bau_desc, |
494 | destination_plugged(struct bau_desc *bau_desc, struct bau_control *bcp, | 595 | struct bau_control *bcp, |
495 | struct bau_control *hmaster, struct ptc_stats *stat) | 596 | struct bau_control *hmaster, struct ptc_stats *stat) |
496 | { | 597 | { |
497 | udelay(bcp->plugged_delay); | 598 | udelay(bcp->plugged_delay); |
498 | bcp->plugged_tries++; | 599 | bcp->plugged_tries++; |
600 | |||
499 | if (bcp->plugged_tries >= bcp->plugsb4reset) { | 601 | if (bcp->plugged_tries >= bcp->plugsb4reset) { |
500 | bcp->plugged_tries = 0; | 602 | bcp->plugged_tries = 0; |
603 | |||
501 | quiesce_local_uvhub(hmaster); | 604 | quiesce_local_uvhub(hmaster); |
605 | |||
502 | spin_lock(&hmaster->queue_lock); | 606 | spin_lock(&hmaster->queue_lock); |
503 | uv_reset_with_ipi(&bau_desc->distribution, bcp->cpu); | 607 | reset_with_ipi(&bau_desc->distribution, bcp->cpu); |
504 | spin_unlock(&hmaster->queue_lock); | 608 | spin_unlock(&hmaster->queue_lock); |
609 | |||
505 | end_uvhub_quiesce(hmaster); | 610 | end_uvhub_quiesce(hmaster); |
611 | |||
506 | bcp->ipi_attempts++; | 612 | bcp->ipi_attempts++; |
507 | stat->s_resets_plug++; | 613 | stat->s_resets_plug++; |
508 | } | 614 | } |
509 | } | 615 | } |
510 | 616 | ||
511 | static void | 617 | static void destination_timeout(struct bau_desc *bau_desc, |
512 | destination_timeout(struct bau_desc *bau_desc, struct bau_control *bcp, | 618 | struct bau_control *bcp, struct bau_control *hmaster, |
513 | struct bau_control *hmaster, struct ptc_stats *stat) | 619 | struct ptc_stats *stat) |
514 | { | 620 | { |
515 | hmaster->max_bau_concurrent = 1; | 621 | hmaster->max_concurr = 1; |
516 | bcp->timeout_tries++; | 622 | bcp->timeout_tries++; |
517 | if (bcp->timeout_tries >= bcp->timeoutsb4reset) { | 623 | if (bcp->timeout_tries >= bcp->timeoutsb4reset) { |
518 | bcp->timeout_tries = 0; | 624 | bcp->timeout_tries = 0; |
625 | |||
519 | quiesce_local_uvhub(hmaster); | 626 | quiesce_local_uvhub(hmaster); |
627 | |||
520 | spin_lock(&hmaster->queue_lock); | 628 | spin_lock(&hmaster->queue_lock); |
521 | uv_reset_with_ipi(&bau_desc->distribution, bcp->cpu); | 629 | reset_with_ipi(&bau_desc->distribution, bcp->cpu); |
522 | spin_unlock(&hmaster->queue_lock); | 630 | spin_unlock(&hmaster->queue_lock); |
631 | |||
523 | end_uvhub_quiesce(hmaster); | 632 | end_uvhub_quiesce(hmaster); |
633 | |||
524 | bcp->ipi_attempts++; | 634 | bcp->ipi_attempts++; |
525 | stat->s_resets_timeout++; | 635 | stat->s_resets_timeout++; |
526 | } | 636 | } |
@@ -530,34 +640,104 @@ destination_timeout(struct bau_desc *bau_desc, struct bau_control *bcp, | |||
530 | * Completions are taking a very long time due to a congested numalink | 640 | * Completions are taking a very long time due to a congested numalink |
531 | * network. | 641 | * network. |
532 | */ | 642 | */ |
533 | static void | 643 | static void disable_for_congestion(struct bau_control *bcp, |
534 | disable_for_congestion(struct bau_control *bcp, struct ptc_stats *stat) | 644 | struct ptc_stats *stat) |
535 | { | 645 | { |
536 | int tcpu; | ||
537 | struct bau_control *tbcp; | ||
538 | |||
539 | /* let only one cpu do this disabling */ | 646 | /* let only one cpu do this disabling */ |
540 | spin_lock(&disable_lock); | 647 | spin_lock(&disable_lock); |
648 | |||
541 | if (!baudisabled && bcp->period_requests && | 649 | if (!baudisabled && bcp->period_requests && |
542 | ((bcp->period_time / bcp->period_requests) > congested_cycles)) { | 650 | ((bcp->period_time / bcp->period_requests) > congested_cycles)) { |
651 | int tcpu; | ||
652 | struct bau_control *tbcp; | ||
543 | /* it becomes this cpu's job to turn on the use of the | 653 | /* it becomes this cpu's job to turn on the use of the |
544 | BAU again */ | 654 | BAU again */ |
545 | baudisabled = 1; | 655 | baudisabled = 1; |
546 | bcp->set_bau_off = 1; | 656 | bcp->set_bau_off = 1; |
547 | bcp->set_bau_on_time = get_cycles() + | 657 | bcp->set_bau_on_time = get_cycles(); |
548 | sec_2_cycles(bcp->congested_period); | 658 | bcp->set_bau_on_time += sec_2_cycles(bcp->cong_period); |
549 | stat->s_bau_disabled++; | 659 | stat->s_bau_disabled++; |
550 | for_each_present_cpu(tcpu) { | 660 | for_each_present_cpu(tcpu) { |
551 | tbcp = &per_cpu(bau_control, tcpu); | 661 | tbcp = &per_cpu(bau_control, tcpu); |
552 | tbcp->baudisabled = 1; | 662 | tbcp->baudisabled = 1; |
553 | } | 663 | } |
554 | } | 664 | } |
665 | |||
555 | spin_unlock(&disable_lock); | 666 | spin_unlock(&disable_lock); |
556 | } | 667 | } |
557 | 668 | ||
558 | /** | 669 | static void count_max_concurr(int stat, struct bau_control *bcp, |
559 | * uv_flush_send_and_wait | 670 | struct bau_control *hmaster) |
560 | * | 671 | { |
672 | bcp->plugged_tries = 0; | ||
673 | bcp->timeout_tries = 0; | ||
674 | if (stat != FLUSH_COMPLETE) | ||
675 | return; | ||
676 | if (bcp->conseccompletes <= bcp->complete_threshold) | ||
677 | return; | ||
678 | if (hmaster->max_concurr >= hmaster->max_concurr_const) | ||
679 | return; | ||
680 | hmaster->max_concurr++; | ||
681 | } | ||
682 | |||
683 | static void record_send_stats(cycles_t time1, cycles_t time2, | ||
684 | struct bau_control *bcp, struct ptc_stats *stat, | ||
685 | int completion_status, int try) | ||
686 | { | ||
687 | cycles_t elapsed; | ||
688 | |||
689 | if (time2 > time1) { | ||
690 | elapsed = time2 - time1; | ||
691 | stat->s_time += elapsed; | ||
692 | |||
693 | if ((completion_status == FLUSH_COMPLETE) && (try == 1)) { | ||
694 | bcp->period_requests++; | ||
695 | bcp->period_time += elapsed; | ||
696 | if ((elapsed > congested_cycles) && | ||
697 | (bcp->period_requests > bcp->cong_reps)) | ||
698 | disable_for_congestion(bcp, stat); | ||
699 | } | ||
700 | } else | ||
701 | stat->s_requestor--; | ||
702 | |||
703 | if (completion_status == FLUSH_COMPLETE && try > 1) | ||
704 | stat->s_retriesok++; | ||
705 | else if (completion_status == FLUSH_GIVEUP) | ||
706 | stat->s_giveup++; | ||
707 | } | ||
708 | |||
709 | /* | ||
710 | * Because of a uv1 hardware bug only a limited number of concurrent | ||
711 | * requests can be made. | ||
712 | */ | ||
713 | static void uv1_throttle(struct bau_control *hmaster, struct ptc_stats *stat) | ||
714 | { | ||
715 | spinlock_t *lock = &hmaster->uvhub_lock; | ||
716 | atomic_t *v; | ||
717 | |||
718 | v = &hmaster->active_descriptor_count; | ||
719 | if (!atomic_inc_unless_ge(lock, v, hmaster->max_concurr)) { | ||
720 | stat->s_throttles++; | ||
721 | do { | ||
722 | cpu_relax(); | ||
723 | } while (!atomic_inc_unless_ge(lock, v, hmaster->max_concurr)); | ||
724 | } | ||
725 | } | ||
726 | |||
727 | /* | ||
728 | * Handle the completion status of a message send. | ||
729 | */ | ||
730 | static void handle_cmplt(int completion_status, struct bau_desc *bau_desc, | ||
731 | struct bau_control *bcp, struct bau_control *hmaster, | ||
732 | struct ptc_stats *stat) | ||
733 | { | ||
734 | if (completion_status == FLUSH_RETRY_PLUGGED) | ||
735 | destination_plugged(bau_desc, bcp, hmaster, stat); | ||
736 | else if (completion_status == FLUSH_RETRY_TIMEOUT) | ||
737 | destination_timeout(bau_desc, bcp, hmaster, stat); | ||
738 | } | ||
739 | |||
740 | /* | ||
561 | * Send a broadcast and wait for it to complete. | 741 | * Send a broadcast and wait for it to complete. |
562 | * | 742 | * |
563 | * The flush_mask contains the cpus the broadcast is to be sent to including | 743 | * The flush_mask contains the cpus the broadcast is to be sent to including |
@@ -568,44 +748,23 @@ disable_for_congestion(struct bau_control *bcp, struct ptc_stats *stat) | |||
568 | * returned to the kernel. | 748 | * returned to the kernel. |
569 | */ | 749 | */ |
570 | int uv_flush_send_and_wait(struct bau_desc *bau_desc, | 750 | int uv_flush_send_and_wait(struct bau_desc *bau_desc, |
571 | struct cpumask *flush_mask, struct bau_control *bcp) | 751 | struct cpumask *flush_mask, struct bau_control *bcp) |
572 | { | 752 | { |
573 | int right_shift; | ||
574 | int completion_status = 0; | ||
575 | int seq_number = 0; | 753 | int seq_number = 0; |
754 | int completion_stat = 0; | ||
576 | long try = 0; | 755 | long try = 0; |
577 | int cpu = bcp->uvhub_cpu; | ||
578 | int this_cpu = bcp->cpu; | ||
579 | unsigned long mmr_offset; | ||
580 | unsigned long index; | 756 | unsigned long index; |
581 | cycles_t time1; | 757 | cycles_t time1; |
582 | cycles_t time2; | 758 | cycles_t time2; |
583 | cycles_t elapsed; | ||
584 | struct ptc_stats *stat = bcp->statp; | 759 | struct ptc_stats *stat = bcp->statp; |
585 | struct bau_control *smaster = bcp->socket_master; | ||
586 | struct bau_control *hmaster = bcp->uvhub_master; | 760 | struct bau_control *hmaster = bcp->uvhub_master; |
587 | 761 | ||
588 | if (!atomic_inc_unless_ge(&hmaster->uvhub_lock, | 762 | if (is_uv1_hub()) |
589 | &hmaster->active_descriptor_count, | 763 | uv1_throttle(hmaster, stat); |
590 | hmaster->max_bau_concurrent)) { | 764 | |
591 | stat->s_throttles++; | ||
592 | do { | ||
593 | cpu_relax(); | ||
594 | } while (!atomic_inc_unless_ge(&hmaster->uvhub_lock, | ||
595 | &hmaster->active_descriptor_count, | ||
596 | hmaster->max_bau_concurrent)); | ||
597 | } | ||
598 | while (hmaster->uvhub_quiesce) | 765 | while (hmaster->uvhub_quiesce) |
599 | cpu_relax(); | 766 | cpu_relax(); |
600 | 767 | ||
601 | if (cpu < UV_CPUS_PER_ACT_STATUS) { | ||
602 | mmr_offset = UVH_LB_BAU_SB_ACTIVATION_STATUS_0; | ||
603 | right_shift = cpu * UV_ACT_STATUS_SIZE; | ||
604 | } else { | ||
605 | mmr_offset = UVH_LB_BAU_SB_ACTIVATION_STATUS_1; | ||
606 | right_shift = | ||
607 | ((cpu - UV_CPUS_PER_ACT_STATUS) * UV_ACT_STATUS_SIZE); | ||
608 | } | ||
609 | time1 = get_cycles(); | 768 | time1 = get_cycles(); |
610 | do { | 769 | do { |
611 | if (try == 0) { | 770 | if (try == 0) { |
@@ -615,64 +774,134 @@ int uv_flush_send_and_wait(struct bau_desc *bau_desc, | |||
615 | bau_desc->header.msg_type = MSG_RETRY; | 774 | bau_desc->header.msg_type = MSG_RETRY; |
616 | stat->s_retry_messages++; | 775 | stat->s_retry_messages++; |
617 | } | 776 | } |
777 | |||
618 | bau_desc->header.sequence = seq_number; | 778 | bau_desc->header.sequence = seq_number; |
619 | index = (1UL << UVH_LB_BAU_SB_ACTIVATION_CONTROL_PUSH_SHFT) | | 779 | index = (1UL << AS_PUSH_SHIFT) | bcp->uvhub_cpu; |
620 | bcp->uvhub_cpu; | ||
621 | bcp->send_message = get_cycles(); | 780 | bcp->send_message = get_cycles(); |
622 | uv_write_local_mmr(UVH_LB_BAU_SB_ACTIVATION_CONTROL, index); | 781 | |
782 | write_mmr_activation(index); | ||
783 | |||
623 | try++; | 784 | try++; |
624 | completion_status = uv_wait_completion(bau_desc, mmr_offset, | 785 | completion_stat = wait_completion(bau_desc, bcp, try); |
625 | right_shift, this_cpu, bcp, smaster, try); | 786 | |
787 | handle_cmplt(completion_stat, bau_desc, bcp, hmaster, stat); | ||
626 | 788 | ||
627 | if (completion_status == FLUSH_RETRY_PLUGGED) { | ||
628 | destination_plugged(bau_desc, bcp, hmaster, stat); | ||
629 | } else if (completion_status == FLUSH_RETRY_TIMEOUT) { | ||
630 | destination_timeout(bau_desc, bcp, hmaster, stat); | ||
631 | } | ||
632 | if (bcp->ipi_attempts >= bcp->ipi_reset_limit) { | 789 | if (bcp->ipi_attempts >= bcp->ipi_reset_limit) { |
633 | bcp->ipi_attempts = 0; | 790 | bcp->ipi_attempts = 0; |
634 | completion_status = FLUSH_GIVEUP; | 791 | completion_stat = FLUSH_GIVEUP; |
635 | break; | 792 | break; |
636 | } | 793 | } |
637 | cpu_relax(); | 794 | cpu_relax(); |
638 | } while ((completion_status == FLUSH_RETRY_PLUGGED) || | 795 | } while ((completion_stat == FLUSH_RETRY_PLUGGED) || |
639 | (completion_status == FLUSH_RETRY_TIMEOUT)); | 796 | (completion_stat == FLUSH_RETRY_TIMEOUT)); |
797 | |||
640 | time2 = get_cycles(); | 798 | time2 = get_cycles(); |
641 | bcp->plugged_tries = 0; | 799 | |
642 | bcp->timeout_tries = 0; | 800 | count_max_concurr(completion_stat, bcp, hmaster); |
643 | if ((completion_status == FLUSH_COMPLETE) && | 801 | |
644 | (bcp->conseccompletes > bcp->complete_threshold) && | ||
645 | (hmaster->max_bau_concurrent < | ||
646 | hmaster->max_bau_concurrent_constant)) | ||
647 | hmaster->max_bau_concurrent++; | ||
648 | while (hmaster->uvhub_quiesce) | 802 | while (hmaster->uvhub_quiesce) |
649 | cpu_relax(); | 803 | cpu_relax(); |
804 | |||
650 | atomic_dec(&hmaster->active_descriptor_count); | 805 | atomic_dec(&hmaster->active_descriptor_count); |
651 | if (time2 > time1) { | 806 | |
652 | elapsed = time2 - time1; | 807 | record_send_stats(time1, time2, bcp, stat, completion_stat, try); |
653 | stat->s_time += elapsed; | 808 | |
654 | if ((completion_status == FLUSH_COMPLETE) && (try == 1)) { | 809 | if (completion_stat == FLUSH_GIVEUP) |
655 | bcp->period_requests++; | 810 | return 1; |
656 | bcp->period_time += elapsed; | 811 | return 0; |
657 | if ((elapsed > congested_cycles) && | 812 | } |
658 | (bcp->period_requests > bcp->congested_reps)) { | 813 | |
659 | disable_for_congestion(bcp, stat); | 814 | /* |
815 | * The BAU is disabled. When the disabled time period has expired, the cpu | ||
816 | * that disabled it must re-enable it. | ||
817 | * Return 0 if it is re-enabled for all cpus. | ||
818 | */ | ||
819 | static int check_enable(struct bau_control *bcp, struct ptc_stats *stat) | ||
820 | { | ||
821 | int tcpu; | ||
822 | struct bau_control *tbcp; | ||
823 | |||
824 | if (bcp->set_bau_off) { | ||
825 | if (get_cycles() >= bcp->set_bau_on_time) { | ||
826 | stat->s_bau_reenabled++; | ||
827 | baudisabled = 0; | ||
828 | for_each_present_cpu(tcpu) { | ||
829 | tbcp = &per_cpu(bau_control, tcpu); | ||
830 | tbcp->baudisabled = 0; | ||
831 | tbcp->period_requests = 0; | ||
832 | tbcp->period_time = 0; | ||
660 | } | 833 | } |
834 | return 0; | ||
661 | } | 835 | } |
836 | } | ||
837 | return -1; | ||
838 | } | ||
839 | |||
840 | static void record_send_statistics(struct ptc_stats *stat, int locals, int hubs, | ||
841 | int remotes, struct bau_desc *bau_desc) | ||
842 | { | ||
843 | stat->s_requestor++; | ||
844 | stat->s_ntargcpu += remotes + locals; | ||
845 | stat->s_ntargremotes += remotes; | ||
846 | stat->s_ntarglocals += locals; | ||
847 | |||
848 | /* uvhub statistics */ | ||
849 | hubs = bau_uvhub_weight(&bau_desc->distribution); | ||
850 | if (locals) { | ||
851 | stat->s_ntarglocaluvhub++; | ||
852 | stat->s_ntargremoteuvhub += (hubs - 1); | ||
662 | } else | 853 | } else |
663 | stat->s_requestor--; | 854 | stat->s_ntargremoteuvhub += hubs; |
664 | if (completion_status == FLUSH_COMPLETE && try > 1) | 855 | |
665 | stat->s_retriesok++; | 856 | stat->s_ntarguvhub += hubs; |
666 | else if (completion_status == FLUSH_GIVEUP) { | 857 | |
667 | stat->s_giveup++; | 858 | if (hubs >= 16) |
668 | return 1; | 859 | stat->s_ntarguvhub16++; |
860 | else if (hubs >= 8) | ||
861 | stat->s_ntarguvhub8++; | ||
862 | else if (hubs >= 4) | ||
863 | stat->s_ntarguvhub4++; | ||
864 | else if (hubs >= 2) | ||
865 | stat->s_ntarguvhub2++; | ||
866 | else | ||
867 | stat->s_ntarguvhub1++; | ||
868 | } | ||
869 | |||
870 | /* | ||
871 | * Translate a cpu mask to the uvhub distribution mask in the BAU | ||
872 | * activation descriptor. | ||
873 | */ | ||
874 | static int set_distrib_bits(struct cpumask *flush_mask, struct bau_control *bcp, | ||
875 | struct bau_desc *bau_desc, int *localsp, int *remotesp) | ||
876 | { | ||
877 | int cpu; | ||
878 | int pnode; | ||
879 | int cnt = 0; | ||
880 | struct hub_and_pnode *hpp; | ||
881 | |||
882 | for_each_cpu(cpu, flush_mask) { | ||
883 | /* | ||
884 | * The distribution vector is a bit map of pnodes, relative | ||
885 | * to the partition base pnode (and the partition base nasid | ||
886 | * in the header). | ||
887 | * Translate cpu to pnode and hub using a local memory array. | ||
888 | */ | ||
889 | hpp = &bcp->socket_master->thp[cpu]; | ||
890 | pnode = hpp->pnode - bcp->partition_base_pnode; | ||
891 | bau_uvhub_set(pnode, &bau_desc->distribution); | ||
892 | cnt++; | ||
893 | if (hpp->uvhub == bcp->uvhub) | ||
894 | (*localsp)++; | ||
895 | else | ||
896 | (*remotesp)++; | ||
669 | } | 897 | } |
898 | if (!cnt) | ||
899 | return 1; | ||
670 | return 0; | 900 | return 0; |
671 | } | 901 | } |
672 | 902 | ||
673 | /** | 903 | /* |
674 | * uv_flush_tlb_others - globally purge translation cache of a virtual | 904 | * globally purge translation cache of a virtual address or all TLB's |
675 | * address or all TLB's | ||
676 | * @cpumask: mask of all cpu's in which the address is to be removed | 905 | * @cpumask: mask of all cpu's in which the address is to be removed |
677 | * @mm: mm_struct containing virtual address range | 906 | * @mm: mm_struct containing virtual address range |
678 | * @va: virtual address to be removed (or TLB_FLUSH_ALL for all TLB's on cpu) | 907 | * @va: virtual address to be removed (or TLB_FLUSH_ALL for all TLB's on cpu) |
@@ -696,20 +925,16 @@ int uv_flush_send_and_wait(struct bau_desc *bau_desc, | |||
696 | * done. The returned pointer is valid till preemption is re-enabled. | 925 | * done. The returned pointer is valid till preemption is re-enabled. |
697 | */ | 926 | */ |
698 | const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, | 927 | const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, |
699 | struct mm_struct *mm, | 928 | struct mm_struct *mm, unsigned long va, |
700 | unsigned long va, unsigned int cpu) | 929 | unsigned int cpu) |
701 | { | 930 | { |
702 | int locals = 0; | 931 | int locals = 0; |
703 | int remotes = 0; | 932 | int remotes = 0; |
704 | int hubs = 0; | 933 | int hubs = 0; |
705 | int tcpu; | ||
706 | int tpnode; | ||
707 | struct bau_desc *bau_desc; | 934 | struct bau_desc *bau_desc; |
708 | struct cpumask *flush_mask; | 935 | struct cpumask *flush_mask; |
709 | struct ptc_stats *stat; | 936 | struct ptc_stats *stat; |
710 | struct bau_control *bcp; | 937 | struct bau_control *bcp; |
711 | struct bau_control *tbcp; | ||
712 | struct hub_and_pnode *hpp; | ||
713 | 938 | ||
714 | /* kernel was booted 'nobau' */ | 939 | /* kernel was booted 'nobau' */ |
715 | if (nobau) | 940 | if (nobau) |
@@ -720,20 +945,8 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, | |||
720 | 945 | ||
721 | /* bau was disabled due to slow response */ | 946 | /* bau was disabled due to slow response */ |
722 | if (bcp->baudisabled) { | 947 | if (bcp->baudisabled) { |
723 | /* the cpu that disabled it must re-enable it */ | 948 | if (check_enable(bcp, stat)) |
724 | if (bcp->set_bau_off) { | 949 | return cpumask; |
725 | if (get_cycles() >= bcp->set_bau_on_time) { | ||
726 | stat->s_bau_reenabled++; | ||
727 | baudisabled = 0; | ||
728 | for_each_present_cpu(tcpu) { | ||
729 | tbcp = &per_cpu(bau_control, tcpu); | ||
730 | tbcp->baudisabled = 0; | ||
731 | tbcp->period_requests = 0; | ||
732 | tbcp->period_time = 0; | ||
733 | } | ||
734 | } | ||
735 | } | ||
736 | return cpumask; | ||
737 | } | 950 | } |
738 | 951 | ||
739 | /* | 952 | /* |
@@ -744,59 +957,20 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, | |||
744 | flush_mask = (struct cpumask *)per_cpu(uv_flush_tlb_mask, cpu); | 957 | flush_mask = (struct cpumask *)per_cpu(uv_flush_tlb_mask, cpu); |
745 | /* don't actually do a shootdown of the local cpu */ | 958 | /* don't actually do a shootdown of the local cpu */ |
746 | cpumask_andnot(flush_mask, cpumask, cpumask_of(cpu)); | 959 | cpumask_andnot(flush_mask, cpumask, cpumask_of(cpu)); |
960 | |||
747 | if (cpu_isset(cpu, *cpumask)) | 961 | if (cpu_isset(cpu, *cpumask)) |
748 | stat->s_ntargself++; | 962 | stat->s_ntargself++; |
749 | 963 | ||
750 | bau_desc = bcp->descriptor_base; | 964 | bau_desc = bcp->descriptor_base; |
751 | bau_desc += UV_ITEMS_PER_DESCRIPTOR * bcp->uvhub_cpu; | 965 | bau_desc += ITEMS_PER_DESC * bcp->uvhub_cpu; |
752 | bau_uvhubs_clear(&bau_desc->distribution, UV_DISTRIBUTION_SIZE); | 966 | bau_uvhubs_clear(&bau_desc->distribution, UV_DISTRIBUTION_SIZE); |
753 | 967 | if (set_distrib_bits(flush_mask, bcp, bau_desc, &locals, &remotes)) | |
754 | for_each_cpu(tcpu, flush_mask) { | ||
755 | /* | ||
756 | * The distribution vector is a bit map of pnodes, relative | ||
757 | * to the partition base pnode (and the partition base nasid | ||
758 | * in the header). | ||
759 | * Translate cpu to pnode and hub using an array stored | ||
760 | * in local memory. | ||
761 | */ | ||
762 | hpp = &bcp->socket_master->target_hub_and_pnode[tcpu]; | ||
763 | tpnode = hpp->pnode - bcp->partition_base_pnode; | ||
764 | bau_uvhub_set(tpnode, &bau_desc->distribution); | ||
765 | if (hpp->uvhub == bcp->uvhub) | ||
766 | locals++; | ||
767 | else | ||
768 | remotes++; | ||
769 | } | ||
770 | if ((locals + remotes) == 0) | ||
771 | return NULL; | 968 | return NULL; |
772 | stat->s_requestor++; | ||
773 | stat->s_ntargcpu += remotes + locals; | ||
774 | stat->s_ntargremotes += remotes; | ||
775 | stat->s_ntarglocals += locals; | ||
776 | remotes = bau_uvhub_weight(&bau_desc->distribution); | ||
777 | 969 | ||
778 | /* uvhub statistics */ | 970 | record_send_statistics(stat, locals, hubs, remotes, bau_desc); |
779 | hubs = bau_uvhub_weight(&bau_desc->distribution); | ||
780 | if (locals) { | ||
781 | stat->s_ntarglocaluvhub++; | ||
782 | stat->s_ntargremoteuvhub += (hubs - 1); | ||
783 | } else | ||
784 | stat->s_ntargremoteuvhub += hubs; | ||
785 | stat->s_ntarguvhub += hubs; | ||
786 | if (hubs >= 16) | ||
787 | stat->s_ntarguvhub16++; | ||
788 | else if (hubs >= 8) | ||
789 | stat->s_ntarguvhub8++; | ||
790 | else if (hubs >= 4) | ||
791 | stat->s_ntarguvhub4++; | ||
792 | else if (hubs >= 2) | ||
793 | stat->s_ntarguvhub2++; | ||
794 | else | ||
795 | stat->s_ntarguvhub1++; | ||
796 | 971 | ||
797 | bau_desc->payload.address = va; | 972 | bau_desc->payload.address = va; |
798 | bau_desc->payload.sending_cpu = cpu; | 973 | bau_desc->payload.sending_cpu = cpu; |
799 | |||
800 | /* | 974 | /* |
801 | * uv_flush_send_and_wait returns 0 if all cpu's were messaged, | 975 | * uv_flush_send_and_wait returns 0 if all cpu's were messaged, |
802 | * or 1 if it gave up and the original cpumask should be returned. | 976 | * or 1 if it gave up and the original cpumask should be returned. |
@@ -825,26 +999,31 @@ void uv_bau_message_interrupt(struct pt_regs *regs) | |||
825 | { | 999 | { |
826 | int count = 0; | 1000 | int count = 0; |
827 | cycles_t time_start; | 1001 | cycles_t time_start; |
828 | struct bau_payload_queue_entry *msg; | 1002 | struct bau_pq_entry *msg; |
829 | struct bau_control *bcp; | 1003 | struct bau_control *bcp; |
830 | struct ptc_stats *stat; | 1004 | struct ptc_stats *stat; |
831 | struct msg_desc msgdesc; | 1005 | struct msg_desc msgdesc; |
832 | 1006 | ||
833 | time_start = get_cycles(); | 1007 | time_start = get_cycles(); |
1008 | |||
834 | bcp = &per_cpu(bau_control, smp_processor_id()); | 1009 | bcp = &per_cpu(bau_control, smp_processor_id()); |
835 | stat = bcp->statp; | 1010 | stat = bcp->statp; |
836 | msgdesc.va_queue_first = bcp->va_queue_first; | 1011 | |
837 | msgdesc.va_queue_last = bcp->va_queue_last; | 1012 | msgdesc.queue_first = bcp->queue_first; |
1013 | msgdesc.queue_last = bcp->queue_last; | ||
1014 | |||
838 | msg = bcp->bau_msg_head; | 1015 | msg = bcp->bau_msg_head; |
839 | while (msg->sw_ack_vector) { | 1016 | while (msg->swack_vec) { |
840 | count++; | 1017 | count++; |
841 | msgdesc.msg_slot = msg - msgdesc.va_queue_first; | 1018 | |
842 | msgdesc.sw_ack_slot = ffs(msg->sw_ack_vector) - 1; | 1019 | msgdesc.msg_slot = msg - msgdesc.queue_first; |
1020 | msgdesc.swack_slot = ffs(msg->swack_vec) - 1; | ||
843 | msgdesc.msg = msg; | 1021 | msgdesc.msg = msg; |
844 | uv_bau_process_message(&msgdesc, bcp); | 1022 | bau_process_message(&msgdesc, bcp); |
1023 | |||
845 | msg++; | 1024 | msg++; |
846 | if (msg > msgdesc.va_queue_last) | 1025 | if (msg > msgdesc.queue_last) |
847 | msg = msgdesc.va_queue_first; | 1026 | msg = msgdesc.queue_first; |
848 | bcp->bau_msg_head = msg; | 1027 | bcp->bau_msg_head = msg; |
849 | } | 1028 | } |
850 | stat->d_time += (get_cycles() - time_start); | 1029 | stat->d_time += (get_cycles() - time_start); |
@@ -852,18 +1031,17 @@ void uv_bau_message_interrupt(struct pt_regs *regs) | |||
852 | stat->d_nomsg++; | 1031 | stat->d_nomsg++; |
853 | else if (count > 1) | 1032 | else if (count > 1) |
854 | stat->d_multmsg++; | 1033 | stat->d_multmsg++; |
1034 | |||
855 | ack_APIC_irq(); | 1035 | ack_APIC_irq(); |
856 | } | 1036 | } |
857 | 1037 | ||
858 | /* | 1038 | /* |
859 | * uv_enable_timeouts | 1039 | * Each target uvhub (i.e. a uvhub that has cpu's) needs to have |
860 | * | ||
861 | * Each target uvhub (i.e. a uvhub that has no cpu's) needs to have | ||
862 | * shootdown message timeouts enabled. The timeout does not cause | 1040 | * shootdown message timeouts enabled. The timeout does not cause |
863 | * an interrupt, but causes an error message to be returned to | 1041 | * an interrupt, but causes an error message to be returned to |
864 | * the sender. | 1042 | * the sender. |
865 | */ | 1043 | */ |
866 | static void __init uv_enable_timeouts(void) | 1044 | static void __init enable_timeouts(void) |
867 | { | 1045 | { |
868 | int uvhub; | 1046 | int uvhub; |
869 | int nuvhubs; | 1047 | int nuvhubs; |
@@ -877,47 +1055,44 @@ static void __init uv_enable_timeouts(void) | |||
877 | continue; | 1055 | continue; |
878 | 1056 | ||
879 | pnode = uv_blade_to_pnode(uvhub); | 1057 | pnode = uv_blade_to_pnode(uvhub); |
880 | mmr_image = | 1058 | mmr_image = read_mmr_misc_control(pnode); |
881 | uv_read_global_mmr64(pnode, UVH_LB_BAU_MISC_CONTROL); | ||
882 | /* | 1059 | /* |
883 | * Set the timeout period and then lock it in, in three | 1060 | * Set the timeout period and then lock it in, in three |
884 | * steps; captures and locks in the period. | 1061 | * steps; captures and locks in the period. |
885 | * | 1062 | * |
886 | * To program the period, the SOFT_ACK_MODE must be off. | 1063 | * To program the period, the SOFT_ACK_MODE must be off. |
887 | */ | 1064 | */ |
888 | mmr_image &= ~((unsigned long)1 << | 1065 | mmr_image &= ~(1L << SOFTACK_MSHIFT); |
889 | UVH_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT); | 1066 | write_mmr_misc_control(pnode, mmr_image); |
890 | uv_write_global_mmr64 | ||
891 | (pnode, UVH_LB_BAU_MISC_CONTROL, mmr_image); | ||
892 | /* | 1067 | /* |
893 | * Set the 4-bit period. | 1068 | * Set the 4-bit period. |
894 | */ | 1069 | */ |
895 | mmr_image &= ~((unsigned long)0xf << | 1070 | mmr_image &= ~((unsigned long)0xf << SOFTACK_PSHIFT); |
896 | UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT); | 1071 | mmr_image |= (SOFTACK_TIMEOUT_PERIOD << SOFTACK_PSHIFT); |
897 | mmr_image |= (UV_INTD_SOFT_ACK_TIMEOUT_PERIOD << | 1072 | write_mmr_misc_control(pnode, mmr_image); |
898 | UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT); | ||
899 | uv_write_global_mmr64 | ||
900 | (pnode, UVH_LB_BAU_MISC_CONTROL, mmr_image); | ||
901 | /* | 1073 | /* |
1074 | * UV1: | ||
902 | * Subsequent reversals of the timebase bit (3) cause an | 1075 | * Subsequent reversals of the timebase bit (3) cause an |
903 | * immediate timeout of one or all INTD resources as | 1076 | * immediate timeout of one or all INTD resources as |
904 | * indicated in bits 2:0 (7 causes all of them to timeout). | 1077 | * indicated in bits 2:0 (7 causes all of them to timeout). |
905 | */ | 1078 | */ |
906 | mmr_image |= ((unsigned long)1 << | 1079 | mmr_image |= (1L << SOFTACK_MSHIFT); |
907 | UVH_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT); | 1080 | if (is_uv2_hub()) { |
908 | uv_write_global_mmr64 | 1081 | mmr_image |= (1L << UV2_LEG_SHFT); |
909 | (pnode, UVH_LB_BAU_MISC_CONTROL, mmr_image); | 1082 | mmr_image |= (1L << UV2_EXT_SHFT); |
1083 | } | ||
1084 | write_mmr_misc_control(pnode, mmr_image); | ||
910 | } | 1085 | } |
911 | } | 1086 | } |
912 | 1087 | ||
913 | static void *uv_ptc_seq_start(struct seq_file *file, loff_t *offset) | 1088 | static void *ptc_seq_start(struct seq_file *file, loff_t *offset) |
914 | { | 1089 | { |
915 | if (*offset < num_possible_cpus()) | 1090 | if (*offset < num_possible_cpus()) |
916 | return offset; | 1091 | return offset; |
917 | return NULL; | 1092 | return NULL; |
918 | } | 1093 | } |
919 | 1094 | ||
920 | static void *uv_ptc_seq_next(struct seq_file *file, void *data, loff_t *offset) | 1095 | static void *ptc_seq_next(struct seq_file *file, void *data, loff_t *offset) |
921 | { | 1096 | { |
922 | (*offset)++; | 1097 | (*offset)++; |
923 | if (*offset < num_possible_cpus()) | 1098 | if (*offset < num_possible_cpus()) |
@@ -925,12 +1100,11 @@ static void *uv_ptc_seq_next(struct seq_file *file, void *data, loff_t *offset) | |||
925 | return NULL; | 1100 | return NULL; |
926 | } | 1101 | } |
927 | 1102 | ||
928 | static void uv_ptc_seq_stop(struct seq_file *file, void *data) | 1103 | static void ptc_seq_stop(struct seq_file *file, void *data) |
929 | { | 1104 | { |
930 | } | 1105 | } |
931 | 1106 | ||
932 | static inline unsigned long long | 1107 | static inline unsigned long long usec_2_cycles(unsigned long microsec) |
933 | microsec_2_cycles(unsigned long microsec) | ||
934 | { | 1108 | { |
935 | unsigned long ns; | 1109 | unsigned long ns; |
936 | unsigned long long cyc; | 1110 | unsigned long long cyc; |
@@ -941,29 +1115,27 @@ microsec_2_cycles(unsigned long microsec) | |||
941 | } | 1115 | } |
942 | 1116 | ||
943 | /* | 1117 | /* |
944 | * Display the statistics thru /proc. | 1118 | * Display the statistics thru /proc/sgi_uv/ptc_statistics |
945 | * 'data' points to the cpu number | 1119 | * 'data' points to the cpu number |
1120 | * Note: see the descriptions in stat_description[]. | ||
946 | */ | 1121 | */ |
947 | static int uv_ptc_seq_show(struct seq_file *file, void *data) | 1122 | static int ptc_seq_show(struct seq_file *file, void *data) |
948 | { | 1123 | { |
949 | struct ptc_stats *stat; | 1124 | struct ptc_stats *stat; |
950 | int cpu; | 1125 | int cpu; |
951 | 1126 | ||
952 | cpu = *(loff_t *)data; | 1127 | cpu = *(loff_t *)data; |
953 | |||
954 | if (!cpu) { | 1128 | if (!cpu) { |
955 | seq_printf(file, | 1129 | seq_printf(file, |
956 | "# cpu sent stime self locals remotes ncpus localhub "); | 1130 | "# cpu sent stime self locals remotes ncpus localhub "); |
957 | seq_printf(file, | 1131 | seq_printf(file, |
958 | "remotehub numuvhubs numuvhubs16 numuvhubs8 "); | 1132 | "remotehub numuvhubs numuvhubs16 numuvhubs8 "); |
959 | seq_printf(file, | 1133 | seq_printf(file, |
960 | "numuvhubs4 numuvhubs2 numuvhubs1 dto "); | 1134 | "numuvhubs4 numuvhubs2 numuvhubs1 dto retries rok "); |
961 | seq_printf(file, | ||
962 | "retries rok resetp resett giveup sto bz throt "); | ||
963 | seq_printf(file, | 1135 | seq_printf(file, |
964 | "sw_ack recv rtime all "); | 1136 | "resetp resett giveup sto bz throt swack recv rtime "); |
965 | seq_printf(file, | 1137 | seq_printf(file, |
966 | "one mult none retry canc nocan reset rcan "); | 1138 | "all one mult none retry canc nocan reset rcan "); |
967 | seq_printf(file, | 1139 | seq_printf(file, |
968 | "disable enable\n"); | 1140 | "disable enable\n"); |
969 | } | 1141 | } |
@@ -990,8 +1162,7 @@ static int uv_ptc_seq_show(struct seq_file *file, void *data) | |||
990 | /* destination side statistics */ | 1162 | /* destination side statistics */ |
991 | seq_printf(file, | 1163 | seq_printf(file, |
992 | "%lx %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld ", | 1164 | "%lx %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld ", |
993 | uv_read_global_mmr64(uv_cpu_to_pnode(cpu), | 1165 | read_gmmr_sw_ack(uv_cpu_to_pnode(cpu)), |
994 | UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE), | ||
995 | stat->d_requestee, cycles_2_us(stat->d_time), | 1166 | stat->d_requestee, cycles_2_us(stat->d_time), |
996 | stat->d_alltlb, stat->d_onetlb, stat->d_multmsg, | 1167 | stat->d_alltlb, stat->d_onetlb, stat->d_multmsg, |
997 | stat->d_nomsg, stat->d_retries, stat->d_canceled, | 1168 | stat->d_nomsg, stat->d_retries, stat->d_canceled, |
@@ -1000,7 +1171,6 @@ static int uv_ptc_seq_show(struct seq_file *file, void *data) | |||
1000 | seq_printf(file, "%ld %ld\n", | 1171 | seq_printf(file, "%ld %ld\n", |
1001 | stat->s_bau_disabled, stat->s_bau_reenabled); | 1172 | stat->s_bau_disabled, stat->s_bau_reenabled); |
1002 | } | 1173 | } |
1003 | |||
1004 | return 0; | 1174 | return 0; |
1005 | } | 1175 | } |
1006 | 1176 | ||
@@ -1008,18 +1178,18 @@ static int uv_ptc_seq_show(struct seq_file *file, void *data) | |||
1008 | * Display the tunables thru debugfs | 1178 | * Display the tunables thru debugfs |
1009 | */ | 1179 | */ |
1010 | static ssize_t tunables_read(struct file *file, char __user *userbuf, | 1180 | static ssize_t tunables_read(struct file *file, char __user *userbuf, |
1011 | size_t count, loff_t *ppos) | 1181 | size_t count, loff_t *ppos) |
1012 | { | 1182 | { |
1013 | char *buf; | 1183 | char *buf; |
1014 | int ret; | 1184 | int ret; |
1015 | 1185 | ||
1016 | buf = kasprintf(GFP_KERNEL, "%s %s %s\n%d %d %d %d %d %d %d %d %d\n", | 1186 | buf = kasprintf(GFP_KERNEL, "%s %s %s\n%d %d %d %d %d %d %d %d %d\n", |
1017 | "max_bau_concurrent plugged_delay plugsb4reset", | 1187 | "max_concur plugged_delay plugsb4reset", |
1018 | "timeoutsb4reset ipi_reset_limit complete_threshold", | 1188 | "timeoutsb4reset ipi_reset_limit complete_threshold", |
1019 | "congested_response_us congested_reps congested_period", | 1189 | "congested_response_us congested_reps congested_period", |
1020 | max_bau_concurrent, plugged_delay, plugsb4reset, | 1190 | max_concurr, plugged_delay, plugsb4reset, |
1021 | timeoutsb4reset, ipi_reset_limit, complete_threshold, | 1191 | timeoutsb4reset, ipi_reset_limit, complete_threshold, |
1022 | congested_response_us, congested_reps, congested_period); | 1192 | congested_respns_us, congested_reps, congested_period); |
1023 | 1193 | ||
1024 | if (!buf) | 1194 | if (!buf) |
1025 | return -ENOMEM; | 1195 | return -ENOMEM; |
@@ -1030,13 +1200,16 @@ static ssize_t tunables_read(struct file *file, char __user *userbuf, | |||
1030 | } | 1200 | } |
1031 | 1201 | ||
1032 | /* | 1202 | /* |
1033 | * -1: resetf the statistics | 1203 | * handle a write to /proc/sgi_uv/ptc_statistics |
1204 | * -1: reset the statistics | ||
1034 | * 0: display meaning of the statistics | 1205 | * 0: display meaning of the statistics |
1035 | */ | 1206 | */ |
1036 | static ssize_t uv_ptc_proc_write(struct file *file, const char __user *user, | 1207 | static ssize_t ptc_proc_write(struct file *file, const char __user *user, |
1037 | size_t count, loff_t *data) | 1208 | size_t count, loff_t *data) |
1038 | { | 1209 | { |
1039 | int cpu; | 1210 | int cpu; |
1211 | int i; | ||
1212 | int elements; | ||
1040 | long input_arg; | 1213 | long input_arg; |
1041 | char optstr[64]; | 1214 | char optstr[64]; |
1042 | struct ptc_stats *stat; | 1215 | struct ptc_stats *stat; |
@@ -1046,79 +1219,18 @@ static ssize_t uv_ptc_proc_write(struct file *file, const char __user *user, | |||
1046 | if (copy_from_user(optstr, user, count)) | 1219 | if (copy_from_user(optstr, user, count)) |
1047 | return -EFAULT; | 1220 | return -EFAULT; |
1048 | optstr[count - 1] = '\0'; | 1221 | optstr[count - 1] = '\0'; |
1222 | |||
1049 | if (strict_strtol(optstr, 10, &input_arg) < 0) { | 1223 | if (strict_strtol(optstr, 10, &input_arg) < 0) { |
1050 | printk(KERN_DEBUG "%s is invalid\n", optstr); | 1224 | printk(KERN_DEBUG "%s is invalid\n", optstr); |
1051 | return -EINVAL; | 1225 | return -EINVAL; |
1052 | } | 1226 | } |
1053 | 1227 | ||
1054 | if (input_arg == 0) { | 1228 | if (input_arg == 0) { |
1229 | elements = sizeof(stat_description)/sizeof(*stat_description); | ||
1055 | printk(KERN_DEBUG "# cpu: cpu number\n"); | 1230 | printk(KERN_DEBUG "# cpu: cpu number\n"); |
1056 | printk(KERN_DEBUG "Sender statistics:\n"); | 1231 | printk(KERN_DEBUG "Sender statistics:\n"); |
1057 | printk(KERN_DEBUG | 1232 | for (i = 0; i < elements; i++) |
1058 | "sent: number of shootdown messages sent\n"); | 1233 | printk(KERN_DEBUG "%s\n", stat_description[i]); |
1059 | printk(KERN_DEBUG | ||
1060 | "stime: time spent sending messages\n"); | ||
1061 | printk(KERN_DEBUG | ||
1062 | "numuvhubs: number of hubs targeted with shootdown\n"); | ||
1063 | printk(KERN_DEBUG | ||
1064 | "numuvhubs16: number times 16 or more hubs targeted\n"); | ||
1065 | printk(KERN_DEBUG | ||
1066 | "numuvhubs8: number times 8 or more hubs targeted\n"); | ||
1067 | printk(KERN_DEBUG | ||
1068 | "numuvhubs4: number times 4 or more hubs targeted\n"); | ||
1069 | printk(KERN_DEBUG | ||
1070 | "numuvhubs2: number times 2 or more hubs targeted\n"); | ||
1071 | printk(KERN_DEBUG | ||
1072 | "numuvhubs1: number times 1 hub targeted\n"); | ||
1073 | printk(KERN_DEBUG | ||
1074 | "numcpus: number of cpus targeted with shootdown\n"); | ||
1075 | printk(KERN_DEBUG | ||
1076 | "dto: number of destination timeouts\n"); | ||
1077 | printk(KERN_DEBUG | ||
1078 | "retries: destination timeout retries sent\n"); | ||
1079 | printk(KERN_DEBUG | ||
1080 | "rok: : destination timeouts successfully retried\n"); | ||
1081 | printk(KERN_DEBUG | ||
1082 | "resetp: ipi-style resource resets for plugs\n"); | ||
1083 | printk(KERN_DEBUG | ||
1084 | "resett: ipi-style resource resets for timeouts\n"); | ||
1085 | printk(KERN_DEBUG | ||
1086 | "giveup: fall-backs to ipi-style shootdowns\n"); | ||
1087 | printk(KERN_DEBUG | ||
1088 | "sto: number of source timeouts\n"); | ||
1089 | printk(KERN_DEBUG | ||
1090 | "bz: number of stay-busy's\n"); | ||
1091 | printk(KERN_DEBUG | ||
1092 | "throt: number times spun in throttle\n"); | ||
1093 | printk(KERN_DEBUG "Destination side statistics:\n"); | ||
1094 | printk(KERN_DEBUG | ||
1095 | "sw_ack: image of UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE\n"); | ||
1096 | printk(KERN_DEBUG | ||
1097 | "recv: shootdown messages received\n"); | ||
1098 | printk(KERN_DEBUG | ||
1099 | "rtime: time spent processing messages\n"); | ||
1100 | printk(KERN_DEBUG | ||
1101 | "all: shootdown all-tlb messages\n"); | ||
1102 | printk(KERN_DEBUG | ||
1103 | "one: shootdown one-tlb messages\n"); | ||
1104 | printk(KERN_DEBUG | ||
1105 | "mult: interrupts that found multiple messages\n"); | ||
1106 | printk(KERN_DEBUG | ||
1107 | "none: interrupts that found no messages\n"); | ||
1108 | printk(KERN_DEBUG | ||
1109 | "retry: number of retry messages processed\n"); | ||
1110 | printk(KERN_DEBUG | ||
1111 | "canc: number messages canceled by retries\n"); | ||
1112 | printk(KERN_DEBUG | ||
1113 | "nocan: number retries that found nothing to cancel\n"); | ||
1114 | printk(KERN_DEBUG | ||
1115 | "reset: number of ipi-style reset requests processed\n"); | ||
1116 | printk(KERN_DEBUG | ||
1117 | "rcan: number messages canceled by reset requests\n"); | ||
1118 | printk(KERN_DEBUG | ||
1119 | "disable: number times use of the BAU was disabled\n"); | ||
1120 | printk(KERN_DEBUG | ||
1121 | "enable: number times use of the BAU was re-enabled\n"); | ||
1122 | } else if (input_arg == -1) { | 1234 | } else if (input_arg == -1) { |
1123 | for_each_present_cpu(cpu) { | 1235 | for_each_present_cpu(cpu) { |
1124 | stat = &per_cpu(ptcstats, cpu); | 1236 | stat = &per_cpu(ptcstats, cpu); |
@@ -1145,27 +1257,18 @@ static int local_atoi(const char *name) | |||
1145 | } | 1257 | } |
1146 | 1258 | ||
1147 | /* | 1259 | /* |
1148 | * set the tunables | 1260 | * Parse the values written to /sys/kernel/debug/sgi_uv/bau_tunables. |
1149 | * 0 values reset them to defaults | 1261 | * Zero values reset them to defaults. |
1150 | */ | 1262 | */ |
1151 | static ssize_t tunables_write(struct file *file, const char __user *user, | 1263 | static int parse_tunables_write(struct bau_control *bcp, char *instr, |
1152 | size_t count, loff_t *data) | 1264 | int count) |
1153 | { | 1265 | { |
1154 | int cpu; | ||
1155 | int cnt = 0; | ||
1156 | int val; | ||
1157 | char *p; | 1266 | char *p; |
1158 | char *q; | 1267 | char *q; |
1159 | char instr[64]; | 1268 | int cnt = 0; |
1160 | struct bau_control *bcp; | 1269 | int val; |
1161 | 1270 | int e = sizeof(tunables) / sizeof(*tunables); | |
1162 | if (count == 0 || count > sizeof(instr)-1) | ||
1163 | return -EINVAL; | ||
1164 | if (copy_from_user(instr, user, count)) | ||
1165 | return -EFAULT; | ||
1166 | 1271 | ||
1167 | instr[count] = '\0'; | ||
1168 | /* count the fields */ | ||
1169 | p = instr + strspn(instr, WHITESPACE); | 1272 | p = instr + strspn(instr, WHITESPACE); |
1170 | q = p; | 1273 | q = p; |
1171 | for (; *p; p = q + strspn(q, WHITESPACE)) { | 1274 | for (; *p; p = q + strspn(q, WHITESPACE)) { |
@@ -1174,8 +1277,8 @@ static ssize_t tunables_write(struct file *file, const char __user *user, | |||
1174 | if (q == p) | 1277 | if (q == p) |
1175 | break; | 1278 | break; |
1176 | } | 1279 | } |
1177 | if (cnt != 9) { | 1280 | if (cnt != e) { |
1178 | printk(KERN_INFO "bau tunable error: should be 9 numbers\n"); | 1281 | printk(KERN_INFO "bau tunable error: should be %d values\n", e); |
1179 | return -EINVAL; | 1282 | return -EINVAL; |
1180 | } | 1283 | } |
1181 | 1284 | ||
@@ -1187,97 +1290,80 @@ static ssize_t tunables_write(struct file *file, const char __user *user, | |||
1187 | switch (cnt) { | 1290 | switch (cnt) { |
1188 | case 0: | 1291 | case 0: |
1189 | if (val == 0) { | 1292 | if (val == 0) { |
1190 | max_bau_concurrent = MAX_BAU_CONCURRENT; | 1293 | max_concurr = MAX_BAU_CONCURRENT; |
1191 | max_bau_concurrent_constant = | 1294 | max_concurr_const = MAX_BAU_CONCURRENT; |
1192 | MAX_BAU_CONCURRENT; | ||
1193 | continue; | 1295 | continue; |
1194 | } | 1296 | } |
1195 | bcp = &per_cpu(bau_control, smp_processor_id()); | ||
1196 | if (val < 1 || val > bcp->cpus_in_uvhub) { | 1297 | if (val < 1 || val > bcp->cpus_in_uvhub) { |
1197 | printk(KERN_DEBUG | 1298 | printk(KERN_DEBUG |
1198 | "Error: BAU max concurrent %d is invalid\n", | 1299 | "Error: BAU max concurrent %d is invalid\n", |
1199 | val); | 1300 | val); |
1200 | return -EINVAL; | 1301 | return -EINVAL; |
1201 | } | 1302 | } |
1202 | max_bau_concurrent = val; | 1303 | max_concurr = val; |
1203 | max_bau_concurrent_constant = val; | 1304 | max_concurr_const = val; |
1204 | continue; | ||
1205 | case 1: | ||
1206 | if (val == 0) | ||
1207 | plugged_delay = PLUGGED_DELAY; | ||
1208 | else | ||
1209 | plugged_delay = val; | ||
1210 | continue; | ||
1211 | case 2: | ||
1212 | if (val == 0) | ||
1213 | plugsb4reset = PLUGSB4RESET; | ||
1214 | else | ||
1215 | plugsb4reset = val; | ||
1216 | continue; | ||
1217 | case 3: | ||
1218 | if (val == 0) | ||
1219 | timeoutsb4reset = TIMEOUTSB4RESET; | ||
1220 | else | ||
1221 | timeoutsb4reset = val; | ||
1222 | continue; | ||
1223 | case 4: | ||
1224 | if (val == 0) | ||
1225 | ipi_reset_limit = IPI_RESET_LIMIT; | ||
1226 | else | ||
1227 | ipi_reset_limit = val; | ||
1228 | continue; | ||
1229 | case 5: | ||
1230 | if (val == 0) | ||
1231 | complete_threshold = COMPLETE_THRESHOLD; | ||
1232 | else | ||
1233 | complete_threshold = val; | ||
1234 | continue; | ||
1235 | case 6: | ||
1236 | if (val == 0) | ||
1237 | congested_response_us = CONGESTED_RESPONSE_US; | ||
1238 | else | ||
1239 | congested_response_us = val; | ||
1240 | continue; | ||
1241 | case 7: | ||
1242 | if (val == 0) | ||
1243 | congested_reps = CONGESTED_REPS; | ||
1244 | else | ||
1245 | congested_reps = val; | ||
1246 | continue; | 1305 | continue; |
1247 | case 8: | 1306 | default: |
1248 | if (val == 0) | 1307 | if (val == 0) |
1249 | congested_period = CONGESTED_PERIOD; | 1308 | *tunables[cnt].tunp = tunables[cnt].deflt; |
1250 | else | 1309 | else |
1251 | congested_period = val; | 1310 | *tunables[cnt].tunp = val; |
1252 | continue; | 1311 | continue; |
1253 | } | 1312 | } |
1254 | if (q == p) | 1313 | if (q == p) |
1255 | break; | 1314 | break; |
1256 | } | 1315 | } |
1316 | return 0; | ||
1317 | } | ||
1318 | |||
1319 | /* | ||
1320 | * Handle a write to debugfs. (/sys/kernel/debug/sgi_uv/bau_tunables) | ||
1321 | */ | ||
1322 | static ssize_t tunables_write(struct file *file, const char __user *user, | ||
1323 | size_t count, loff_t *data) | ||
1324 | { | ||
1325 | int cpu; | ||
1326 | int ret; | ||
1327 | char instr[100]; | ||
1328 | struct bau_control *bcp; | ||
1329 | |||
1330 | if (count == 0 || count > sizeof(instr)-1) | ||
1331 | return -EINVAL; | ||
1332 | if (copy_from_user(instr, user, count)) | ||
1333 | return -EFAULT; | ||
1334 | |||
1335 | instr[count] = '\0'; | ||
1336 | |||
1337 | bcp = &per_cpu(bau_control, smp_processor_id()); | ||
1338 | |||
1339 | ret = parse_tunables_write(bcp, instr, count); | ||
1340 | if (ret) | ||
1341 | return ret; | ||
1342 | |||
1257 | for_each_present_cpu(cpu) { | 1343 | for_each_present_cpu(cpu) { |
1258 | bcp = &per_cpu(bau_control, cpu); | 1344 | bcp = &per_cpu(bau_control, cpu); |
1259 | bcp->max_bau_concurrent = max_bau_concurrent; | 1345 | bcp->max_concurr = max_concurr; |
1260 | bcp->max_bau_concurrent_constant = max_bau_concurrent; | 1346 | bcp->max_concurr_const = max_concurr; |
1261 | bcp->plugged_delay = plugged_delay; | 1347 | bcp->plugged_delay = plugged_delay; |
1262 | bcp->plugsb4reset = plugsb4reset; | 1348 | bcp->plugsb4reset = plugsb4reset; |
1263 | bcp->timeoutsb4reset = timeoutsb4reset; | 1349 | bcp->timeoutsb4reset = timeoutsb4reset; |
1264 | bcp->ipi_reset_limit = ipi_reset_limit; | 1350 | bcp->ipi_reset_limit = ipi_reset_limit; |
1265 | bcp->complete_threshold = complete_threshold; | 1351 | bcp->complete_threshold = complete_threshold; |
1266 | bcp->congested_response_us = congested_response_us; | 1352 | bcp->cong_response_us = congested_respns_us; |
1267 | bcp->congested_reps = congested_reps; | 1353 | bcp->cong_reps = congested_reps; |
1268 | bcp->congested_period = congested_period; | 1354 | bcp->cong_period = congested_period; |
1269 | } | 1355 | } |
1270 | return count; | 1356 | return count; |
1271 | } | 1357 | } |
1272 | 1358 | ||
1273 | static const struct seq_operations uv_ptc_seq_ops = { | 1359 | static const struct seq_operations uv_ptc_seq_ops = { |
1274 | .start = uv_ptc_seq_start, | 1360 | .start = ptc_seq_start, |
1275 | .next = uv_ptc_seq_next, | 1361 | .next = ptc_seq_next, |
1276 | .stop = uv_ptc_seq_stop, | 1362 | .stop = ptc_seq_stop, |
1277 | .show = uv_ptc_seq_show | 1363 | .show = ptc_seq_show |
1278 | }; | 1364 | }; |
1279 | 1365 | ||
1280 | static int uv_ptc_proc_open(struct inode *inode, struct file *file) | 1366 | static int ptc_proc_open(struct inode *inode, struct file *file) |
1281 | { | 1367 | { |
1282 | return seq_open(file, &uv_ptc_seq_ops); | 1368 | return seq_open(file, &uv_ptc_seq_ops); |
1283 | } | 1369 | } |
@@ -1288,9 +1374,9 @@ static int tunables_open(struct inode *inode, struct file *file) | |||
1288 | } | 1374 | } |
1289 | 1375 | ||
1290 | static const struct file_operations proc_uv_ptc_operations = { | 1376 | static const struct file_operations proc_uv_ptc_operations = { |
1291 | .open = uv_ptc_proc_open, | 1377 | .open = ptc_proc_open, |
1292 | .read = seq_read, | 1378 | .read = seq_read, |
1293 | .write = uv_ptc_proc_write, | 1379 | .write = ptc_proc_write, |
1294 | .llseek = seq_lseek, | 1380 | .llseek = seq_lseek, |
1295 | .release = seq_release, | 1381 | .release = seq_release, |
1296 | }; | 1382 | }; |
@@ -1324,7 +1410,7 @@ static int __init uv_ptc_init(void) | |||
1324 | return -EINVAL; | 1410 | return -EINVAL; |
1325 | } | 1411 | } |
1326 | tunables_file = debugfs_create_file(UV_BAU_TUNABLES_FILE, 0600, | 1412 | tunables_file = debugfs_create_file(UV_BAU_TUNABLES_FILE, 0600, |
1327 | tunables_dir, NULL, &tunables_fops); | 1413 | tunables_dir, NULL, &tunables_fops); |
1328 | if (!tunables_file) { | 1414 | if (!tunables_file) { |
1329 | printk(KERN_ERR "unable to create debugfs file %s\n", | 1415 | printk(KERN_ERR "unable to create debugfs file %s\n", |
1330 | UV_BAU_TUNABLES_FILE); | 1416 | UV_BAU_TUNABLES_FILE); |
@@ -1336,24 +1422,24 @@ static int __init uv_ptc_init(void) | |||
1336 | /* | 1422 | /* |
1337 | * Initialize the sending side's sending buffers. | 1423 | * Initialize the sending side's sending buffers. |
1338 | */ | 1424 | */ |
1339 | static void | 1425 | static void activation_descriptor_init(int node, int pnode, int base_pnode) |
1340 | uv_activation_descriptor_init(int node, int pnode, int base_pnode) | ||
1341 | { | 1426 | { |
1342 | int i; | 1427 | int i; |
1343 | int cpu; | 1428 | int cpu; |
1344 | unsigned long pa; | 1429 | unsigned long pa; |
1345 | unsigned long m; | 1430 | unsigned long m; |
1346 | unsigned long n; | 1431 | unsigned long n; |
1432 | size_t dsize; | ||
1347 | struct bau_desc *bau_desc; | 1433 | struct bau_desc *bau_desc; |
1348 | struct bau_desc *bd2; | 1434 | struct bau_desc *bd2; |
1349 | struct bau_control *bcp; | 1435 | struct bau_control *bcp; |
1350 | 1436 | ||
1351 | /* | 1437 | /* |
1352 | * each bau_desc is 64 bytes; there are 8 (UV_ITEMS_PER_DESCRIPTOR) | 1438 | * each bau_desc is 64 bytes; there are 8 (ITEMS_PER_DESC) |
1353 | * per cpu; and one per cpu on the uvhub (UV_ADP_SIZE) | 1439 | * per cpu; and one per cpu on the uvhub (ADP_SZ) |
1354 | */ | 1440 | */ |
1355 | bau_desc = kmalloc_node(sizeof(struct bau_desc) * UV_ADP_SIZE | 1441 | dsize = sizeof(struct bau_desc) * ADP_SZ * ITEMS_PER_DESC; |
1356 | * UV_ITEMS_PER_DESCRIPTOR, GFP_KERNEL, node); | 1442 | bau_desc = kmalloc_node(dsize, GFP_KERNEL, node); |
1357 | BUG_ON(!bau_desc); | 1443 | BUG_ON(!bau_desc); |
1358 | 1444 | ||
1359 | pa = uv_gpa(bau_desc); /* need the real nasid*/ | 1445 | pa = uv_gpa(bau_desc); /* need the real nasid*/ |
@@ -1361,27 +1447,25 @@ uv_activation_descriptor_init(int node, int pnode, int base_pnode) | |||
1361 | m = pa & uv_mmask; | 1447 | m = pa & uv_mmask; |
1362 | 1448 | ||
1363 | /* the 14-bit pnode */ | 1449 | /* the 14-bit pnode */ |
1364 | uv_write_global_mmr64(pnode, UVH_LB_BAU_SB_DESCRIPTOR_BASE, | 1450 | write_mmr_descriptor_base(pnode, (n << UV_DESC_PSHIFT | m)); |
1365 | (n << UV_DESC_BASE_PNODE_SHIFT | m)); | ||
1366 | /* | 1451 | /* |
1367 | * Initializing all 8 (UV_ITEMS_PER_DESCRIPTOR) descriptors for each | 1452 | * Initializing all 8 (ITEMS_PER_DESC) descriptors for each |
1368 | * cpu even though we only use the first one; one descriptor can | 1453 | * cpu even though we only use the first one; one descriptor can |
1369 | * describe a broadcast to 256 uv hubs. | 1454 | * describe a broadcast to 256 uv hubs. |
1370 | */ | 1455 | */ |
1371 | for (i = 0, bd2 = bau_desc; i < (UV_ADP_SIZE*UV_ITEMS_PER_DESCRIPTOR); | 1456 | for (i = 0, bd2 = bau_desc; i < (ADP_SZ * ITEMS_PER_DESC); i++, bd2++) { |
1372 | i++, bd2++) { | ||
1373 | memset(bd2, 0, sizeof(struct bau_desc)); | 1457 | memset(bd2, 0, sizeof(struct bau_desc)); |
1374 | bd2->header.sw_ack_flag = 1; | 1458 | bd2->header.swack_flag = 1; |
1375 | /* | 1459 | /* |
1376 | * The base_dest_nasid set in the message header is the nasid | 1460 | * The base_dest_nasid set in the message header is the nasid |
1377 | * of the first uvhub in the partition. The bit map will | 1461 | * of the first uvhub in the partition. The bit map will |
1378 | * indicate destination pnode numbers relative to that base. | 1462 | * indicate destination pnode numbers relative to that base. |
1379 | * They may not be consecutive if nasid striding is being used. | 1463 | * They may not be consecutive if nasid striding is being used. |
1380 | */ | 1464 | */ |
1381 | bd2->header.base_dest_nasid = UV_PNODE_TO_NASID(base_pnode); | 1465 | bd2->header.base_dest_nasid = UV_PNODE_TO_NASID(base_pnode); |
1382 | bd2->header.dest_subnodeid = UV_LB_SUBNODEID; | 1466 | bd2->header.dest_subnodeid = UV_LB_SUBNODEID; |
1383 | bd2->header.command = UV_NET_ENDPOINT_INTD; | 1467 | bd2->header.command = UV_NET_ENDPOINT_INTD; |
1384 | bd2->header.int_both = 1; | 1468 | bd2->header.int_both = 1; |
1385 | /* | 1469 | /* |
1386 | * all others need to be set to zero: | 1470 | * all others need to be set to zero: |
1387 | * fairness chaining multilevel count replied_to | 1471 | * fairness chaining multilevel count replied_to |
@@ -1401,57 +1485,55 @@ uv_activation_descriptor_init(int node, int pnode, int base_pnode) | |||
1401 | * - node is first node (kernel memory notion) on the uvhub | 1485 | * - node is first node (kernel memory notion) on the uvhub |
1402 | * - pnode is the uvhub's physical identifier | 1486 | * - pnode is the uvhub's physical identifier |
1403 | */ | 1487 | */ |
1404 | static void | 1488 | static void pq_init(int node, int pnode) |
1405 | uv_payload_queue_init(int node, int pnode) | ||
1406 | { | 1489 | { |
1407 | int pn; | ||
1408 | int cpu; | 1490 | int cpu; |
1491 | size_t plsize; | ||
1409 | char *cp; | 1492 | char *cp; |
1410 | unsigned long pa; | 1493 | void *vp; |
1411 | struct bau_payload_queue_entry *pqp; | 1494 | unsigned long pn; |
1412 | struct bau_payload_queue_entry *pqp_malloc; | 1495 | unsigned long first; |
1496 | unsigned long pn_first; | ||
1497 | unsigned long last; | ||
1498 | struct bau_pq_entry *pqp; | ||
1413 | struct bau_control *bcp; | 1499 | struct bau_control *bcp; |
1414 | 1500 | ||
1415 | pqp = kmalloc_node((DEST_Q_SIZE + 1) | 1501 | plsize = (DEST_Q_SIZE + 1) * sizeof(struct bau_pq_entry); |
1416 | * sizeof(struct bau_payload_queue_entry), | 1502 | vp = kmalloc_node(plsize, GFP_KERNEL, node); |
1417 | GFP_KERNEL, node); | 1503 | pqp = (struct bau_pq_entry *)vp; |
1418 | BUG_ON(!pqp); | 1504 | BUG_ON(!pqp); |
1419 | pqp_malloc = pqp; | ||
1420 | 1505 | ||
1421 | cp = (char *)pqp + 31; | 1506 | cp = (char *)pqp + 31; |
1422 | pqp = (struct bau_payload_queue_entry *)(((unsigned long)cp >> 5) << 5); | 1507 | pqp = (struct bau_pq_entry *)(((unsigned long)cp >> 5) << 5); |
1423 | 1508 | ||
1424 | for_each_present_cpu(cpu) { | 1509 | for_each_present_cpu(cpu) { |
1425 | if (pnode != uv_cpu_to_pnode(cpu)) | 1510 | if (pnode != uv_cpu_to_pnode(cpu)) |
1426 | continue; | 1511 | continue; |
1427 | /* for every cpu on this pnode: */ | 1512 | /* for every cpu on this pnode: */ |
1428 | bcp = &per_cpu(bau_control, cpu); | 1513 | bcp = &per_cpu(bau_control, cpu); |
1429 | bcp->va_queue_first = pqp; | 1514 | bcp->queue_first = pqp; |
1430 | bcp->bau_msg_head = pqp; | 1515 | bcp->bau_msg_head = pqp; |
1431 | bcp->va_queue_last = pqp + (DEST_Q_SIZE - 1); | 1516 | bcp->queue_last = pqp + (DEST_Q_SIZE - 1); |
1432 | } | 1517 | } |
1433 | /* | 1518 | /* |
1434 | * need the pnode of where the memory was really allocated | 1519 | * need the pnode of where the memory was really allocated |
1435 | */ | 1520 | */ |
1436 | pa = uv_gpa(pqp); | 1521 | pn = uv_gpa(pqp) >> uv_nshift; |
1437 | pn = pa >> uv_nshift; | 1522 | first = uv_physnodeaddr(pqp); |
1438 | uv_write_global_mmr64(pnode, | 1523 | pn_first = ((unsigned long)pn << UV_PAYLOADQ_PNODE_SHIFT) | first; |
1439 | UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST, | 1524 | last = uv_physnodeaddr(pqp + (DEST_Q_SIZE - 1)); |
1440 | ((unsigned long)pn << UV_PAYLOADQ_PNODE_SHIFT) | | 1525 | write_mmr_payload_first(pnode, pn_first); |
1441 | uv_physnodeaddr(pqp)); | 1526 | write_mmr_payload_tail(pnode, first); |
1442 | uv_write_global_mmr64(pnode, UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL, | 1527 | write_mmr_payload_last(pnode, last); |
1443 | uv_physnodeaddr(pqp)); | 1528 | |
1444 | uv_write_global_mmr64(pnode, UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST, | ||
1445 | (unsigned long) | ||
1446 | uv_physnodeaddr(pqp + (DEST_Q_SIZE - 1))); | ||
1447 | /* in effect, all msg_type's are set to MSG_NOOP */ | 1529 | /* in effect, all msg_type's are set to MSG_NOOP */ |
1448 | memset(pqp, 0, sizeof(struct bau_payload_queue_entry) * DEST_Q_SIZE); | 1530 | memset(pqp, 0, sizeof(struct bau_pq_entry) * DEST_Q_SIZE); |
1449 | } | 1531 | } |
1450 | 1532 | ||
1451 | /* | 1533 | /* |
1452 | * Initialization of each UV hub's structures | 1534 | * Initialization of each UV hub's structures |
1453 | */ | 1535 | */ |
1454 | static void __init uv_init_uvhub(int uvhub, int vector, int base_pnode) | 1536 | static void __init init_uvhub(int uvhub, int vector, int base_pnode) |
1455 | { | 1537 | { |
1456 | int node; | 1538 | int node; |
1457 | int pnode; | 1539 | int pnode; |
@@ -1459,24 +1541,24 @@ static void __init uv_init_uvhub(int uvhub, int vector, int base_pnode) | |||
1459 | 1541 | ||
1460 | node = uvhub_to_first_node(uvhub); | 1542 | node = uvhub_to_first_node(uvhub); |
1461 | pnode = uv_blade_to_pnode(uvhub); | 1543 | pnode = uv_blade_to_pnode(uvhub); |
1462 | uv_activation_descriptor_init(node, pnode, base_pnode); | 1544 | |
1463 | uv_payload_queue_init(node, pnode); | 1545 | activation_descriptor_init(node, pnode, base_pnode); |
1546 | |||
1547 | pq_init(node, pnode); | ||
1464 | /* | 1548 | /* |
1465 | * The below initialization can't be in firmware because the | 1549 | * The below initialization can't be in firmware because the |
1466 | * messaging IRQ will be determined by the OS. | 1550 | * messaging IRQ will be determined by the OS. |
1467 | */ | 1551 | */ |
1468 | apicid = uvhub_to_first_apicid(uvhub) | uv_apicid_hibits; | 1552 | apicid = uvhub_to_first_apicid(uvhub) | uv_apicid_hibits; |
1469 | uv_write_global_mmr64(pnode, UVH_BAU_DATA_CONFIG, | 1553 | write_mmr_data_config(pnode, ((apicid << 32) | vector)); |
1470 | ((apicid << 32) | vector)); | ||
1471 | } | 1554 | } |
1472 | 1555 | ||
1473 | /* | 1556 | /* |
1474 | * We will set BAU_MISC_CONTROL with a timeout period. | 1557 | * We will set BAU_MISC_CONTROL with a timeout period. |
1475 | * But the BIOS has set UVH_AGING_PRESCALE_SEL and UVH_TRANSACTION_TIMEOUT. | 1558 | * But the BIOS has set UVH_AGING_PRESCALE_SEL and UVH_TRANSACTION_TIMEOUT. |
1476 | * So the destination timeout period has be be calculated from them. | 1559 | * So the destination timeout period has to be calculated from them. |
1477 | */ | 1560 | */ |
1478 | static int | 1561 | static int calculate_destination_timeout(void) |
1479 | calculate_destination_timeout(void) | ||
1480 | { | 1562 | { |
1481 | unsigned long mmr_image; | 1563 | unsigned long mmr_image; |
1482 | int mult1; | 1564 | int mult1; |
@@ -1486,73 +1568,92 @@ calculate_destination_timeout(void) | |||
1486 | int ret; | 1568 | int ret; |
1487 | unsigned long ts_ns; | 1569 | unsigned long ts_ns; |
1488 | 1570 | ||
1489 | mult1 = UV_INTD_SOFT_ACK_TIMEOUT_PERIOD & BAU_MISC_CONTROL_MULT_MASK; | 1571 | if (is_uv1_hub()) { |
1490 | mmr_image = uv_read_local_mmr(UVH_AGING_PRESCALE_SEL); | 1572 | mult1 = SOFTACK_TIMEOUT_PERIOD & BAU_MISC_CONTROL_MULT_MASK; |
1491 | index = (mmr_image >> BAU_URGENCY_7_SHIFT) & BAU_URGENCY_7_MASK; | 1573 | mmr_image = uv_read_local_mmr(UVH_AGING_PRESCALE_SEL); |
1492 | mmr_image = uv_read_local_mmr(UVH_TRANSACTION_TIMEOUT); | 1574 | index = (mmr_image >> BAU_URGENCY_7_SHIFT) & BAU_URGENCY_7_MASK; |
1493 | mult2 = (mmr_image >> BAU_TRANS_SHIFT) & BAU_TRANS_MASK; | 1575 | mmr_image = uv_read_local_mmr(UVH_TRANSACTION_TIMEOUT); |
1494 | base = timeout_base_ns[index]; | 1576 | mult2 = (mmr_image >> BAU_TRANS_SHIFT) & BAU_TRANS_MASK; |
1495 | ts_ns = base * mult1 * mult2; | 1577 | base = timeout_base_ns[index]; |
1496 | ret = ts_ns / 1000; | 1578 | ts_ns = base * mult1 * mult2; |
1579 | ret = ts_ns / 1000; | ||
1580 | } else { | ||
1581 | /* 4 bits 0/1 for 10/80us, 3 bits of multiplier */ | ||
1582 | mmr_image = uv_read_local_mmr(UVH_AGING_PRESCALE_SEL); | ||
1583 | mmr_image = (mmr_image & UV_SA_MASK) >> UV_SA_SHFT; | ||
1584 | if (mmr_image & (1L << UV2_ACK_UNITS_SHFT)) | ||
1585 | mult1 = 80; | ||
1586 | else | ||
1587 | mult1 = 10; | ||
1588 | base = mmr_image & UV2_ACK_MASK; | ||
1589 | ret = mult1 * base; | ||
1590 | } | ||
1497 | return ret; | 1591 | return ret; |
1498 | } | 1592 | } |
1499 | 1593 | ||
1594 | static void __init init_per_cpu_tunables(void) | ||
1595 | { | ||
1596 | int cpu; | ||
1597 | struct bau_control *bcp; | ||
1598 | |||
1599 | for_each_present_cpu(cpu) { | ||
1600 | bcp = &per_cpu(bau_control, cpu); | ||
1601 | bcp->baudisabled = 0; | ||
1602 | bcp->statp = &per_cpu(ptcstats, cpu); | ||
1603 | /* time interval to catch a hardware stay-busy bug */ | ||
1604 | bcp->timeout_interval = usec_2_cycles(2*timeout_us); | ||
1605 | bcp->max_concurr = max_concurr; | ||
1606 | bcp->max_concurr_const = max_concurr; | ||
1607 | bcp->plugged_delay = plugged_delay; | ||
1608 | bcp->plugsb4reset = plugsb4reset; | ||
1609 | bcp->timeoutsb4reset = timeoutsb4reset; | ||
1610 | bcp->ipi_reset_limit = ipi_reset_limit; | ||
1611 | bcp->complete_threshold = complete_threshold; | ||
1612 | bcp->cong_response_us = congested_respns_us; | ||
1613 | bcp->cong_reps = congested_reps; | ||
1614 | bcp->cong_period = congested_period; | ||
1615 | } | ||
1616 | } | ||
1617 | |||
1500 | /* | 1618 | /* |
1501 | * initialize the bau_control structure for each cpu | 1619 | * Scan all cpus to collect blade and socket summaries. |
1502 | */ | 1620 | */ |
1503 | static int __init uv_init_per_cpu(int nuvhubs, int base_part_pnode) | 1621 | static int __init get_cpu_topology(int base_pnode, |
1622 | struct uvhub_desc *uvhub_descs, | ||
1623 | unsigned char *uvhub_mask) | ||
1504 | { | 1624 | { |
1505 | int i; | ||
1506 | int cpu; | 1625 | int cpu; |
1507 | int tcpu; | ||
1508 | int pnode; | 1626 | int pnode; |
1509 | int uvhub; | 1627 | int uvhub; |
1510 | int have_hmaster; | 1628 | int socket; |
1511 | short socket = 0; | ||
1512 | unsigned short socket_mask; | ||
1513 | unsigned char *uvhub_mask; | ||
1514 | struct bau_control *bcp; | 1629 | struct bau_control *bcp; |
1515 | struct uvhub_desc *bdp; | 1630 | struct uvhub_desc *bdp; |
1516 | struct socket_desc *sdp; | 1631 | struct socket_desc *sdp; |
1517 | struct bau_control *hmaster = NULL; | ||
1518 | struct bau_control *smaster = NULL; | ||
1519 | struct socket_desc { | ||
1520 | short num_cpus; | ||
1521 | short cpu_number[MAX_CPUS_PER_SOCKET]; | ||
1522 | }; | ||
1523 | struct uvhub_desc { | ||
1524 | unsigned short socket_mask; | ||
1525 | short num_cpus; | ||
1526 | short uvhub; | ||
1527 | short pnode; | ||
1528 | struct socket_desc socket[2]; | ||
1529 | }; | ||
1530 | struct uvhub_desc *uvhub_descs; | ||
1531 | |||
1532 | timeout_us = calculate_destination_timeout(); | ||
1533 | 1632 | ||
1534 | uvhub_descs = kmalloc(nuvhubs * sizeof(struct uvhub_desc), GFP_KERNEL); | ||
1535 | memset(uvhub_descs, 0, nuvhubs * sizeof(struct uvhub_desc)); | ||
1536 | uvhub_mask = kzalloc((nuvhubs+7)/8, GFP_KERNEL); | ||
1537 | for_each_present_cpu(cpu) { | 1633 | for_each_present_cpu(cpu) { |
1538 | bcp = &per_cpu(bau_control, cpu); | 1634 | bcp = &per_cpu(bau_control, cpu); |
1635 | |||
1539 | memset(bcp, 0, sizeof(struct bau_control)); | 1636 | memset(bcp, 0, sizeof(struct bau_control)); |
1637 | |||
1540 | pnode = uv_cpu_hub_info(cpu)->pnode; | 1638 | pnode = uv_cpu_hub_info(cpu)->pnode; |
1541 | if ((pnode - base_part_pnode) >= UV_DISTRIBUTION_SIZE) { | 1639 | if ((pnode - base_pnode) >= UV_DISTRIBUTION_SIZE) { |
1542 | printk(KERN_EMERG | 1640 | printk(KERN_EMERG |
1543 | "cpu %d pnode %d-%d beyond %d; BAU disabled\n", | 1641 | "cpu %d pnode %d-%d beyond %d; BAU disabled\n", |
1544 | cpu, pnode, base_part_pnode, | 1642 | cpu, pnode, base_pnode, UV_DISTRIBUTION_SIZE); |
1545 | UV_DISTRIBUTION_SIZE); | ||
1546 | return 1; | 1643 | return 1; |
1547 | } | 1644 | } |
1645 | |||
1548 | bcp->osnode = cpu_to_node(cpu); | 1646 | bcp->osnode = cpu_to_node(cpu); |
1549 | bcp->partition_base_pnode = uv_partition_base_pnode; | 1647 | bcp->partition_base_pnode = base_pnode; |
1648 | |||
1550 | uvhub = uv_cpu_hub_info(cpu)->numa_blade_id; | 1649 | uvhub = uv_cpu_hub_info(cpu)->numa_blade_id; |
1551 | *(uvhub_mask + (uvhub/8)) |= (1 << (uvhub%8)); | 1650 | *(uvhub_mask + (uvhub/8)) |= (1 << (uvhub%8)); |
1552 | bdp = &uvhub_descs[uvhub]; | 1651 | bdp = &uvhub_descs[uvhub]; |
1652 | |||
1553 | bdp->num_cpus++; | 1653 | bdp->num_cpus++; |
1554 | bdp->uvhub = uvhub; | 1654 | bdp->uvhub = uvhub; |
1555 | bdp->pnode = pnode; | 1655 | bdp->pnode = pnode; |
1656 | |||
1556 | /* kludge: 'assuming' one node per socket, and assuming that | 1657 | /* kludge: 'assuming' one node per socket, and assuming that |
1557 | disabling a socket just leaves a gap in node numbers */ | 1658 | disabling a socket just leaves a gap in node numbers */ |
1558 | socket = bcp->osnode & 1; | 1659 | socket = bcp->osnode & 1; |
@@ -1561,84 +1662,129 @@ static int __init uv_init_per_cpu(int nuvhubs, int base_part_pnode) | |||
1561 | sdp->cpu_number[sdp->num_cpus] = cpu; | 1662 | sdp->cpu_number[sdp->num_cpus] = cpu; |
1562 | sdp->num_cpus++; | 1663 | sdp->num_cpus++; |
1563 | if (sdp->num_cpus > MAX_CPUS_PER_SOCKET) { | 1664 | if (sdp->num_cpus > MAX_CPUS_PER_SOCKET) { |
1564 | printk(KERN_EMERG "%d cpus per socket invalid\n", sdp->num_cpus); | 1665 | printk(KERN_EMERG "%d cpus per socket invalid\n", |
1666 | sdp->num_cpus); | ||
1565 | return 1; | 1667 | return 1; |
1566 | } | 1668 | } |
1567 | } | 1669 | } |
1670 | return 0; | ||
1671 | } | ||
1672 | |||
1673 | /* | ||
1674 | * Each socket is to get a local array of pnodes/hubs. | ||
1675 | */ | ||
1676 | static void make_per_cpu_thp(struct bau_control *smaster) | ||
1677 | { | ||
1678 | int cpu; | ||
1679 | size_t hpsz = sizeof(struct hub_and_pnode) * num_possible_cpus(); | ||
1680 | |||
1681 | smaster->thp = kmalloc_node(hpsz, GFP_KERNEL, smaster->osnode); | ||
1682 | memset(smaster->thp, 0, hpsz); | ||
1683 | for_each_present_cpu(cpu) { | ||
1684 | smaster->thp[cpu].pnode = uv_cpu_hub_info(cpu)->pnode; | ||
1685 | smaster->thp[cpu].uvhub = uv_cpu_hub_info(cpu)->numa_blade_id; | ||
1686 | } | ||
1687 | } | ||
1688 | |||
1689 | /* | ||
1690 | * Initialize all the per_cpu information for the cpu's on a given socket, | ||
1691 | * given what has been gathered into the socket_desc struct. | ||
1692 | * And reports the chosen hub and socket masters back to the caller. | ||
1693 | */ | ||
1694 | static int scan_sock(struct socket_desc *sdp, struct uvhub_desc *bdp, | ||
1695 | struct bau_control **smasterp, | ||
1696 | struct bau_control **hmasterp) | ||
1697 | { | ||
1698 | int i; | ||
1699 | int cpu; | ||
1700 | struct bau_control *bcp; | ||
1701 | |||
1702 | for (i = 0; i < sdp->num_cpus; i++) { | ||
1703 | cpu = sdp->cpu_number[i]; | ||
1704 | bcp = &per_cpu(bau_control, cpu); | ||
1705 | bcp->cpu = cpu; | ||
1706 | if (i == 0) { | ||
1707 | *smasterp = bcp; | ||
1708 | if (!(*hmasterp)) | ||
1709 | *hmasterp = bcp; | ||
1710 | } | ||
1711 | bcp->cpus_in_uvhub = bdp->num_cpus; | ||
1712 | bcp->cpus_in_socket = sdp->num_cpus; | ||
1713 | bcp->socket_master = *smasterp; | ||
1714 | bcp->uvhub = bdp->uvhub; | ||
1715 | bcp->uvhub_master = *hmasterp; | ||
1716 | bcp->uvhub_cpu = uv_cpu_hub_info(cpu)->blade_processor_id; | ||
1717 | if (bcp->uvhub_cpu >= MAX_CPUS_PER_UVHUB) { | ||
1718 | printk(KERN_EMERG "%d cpus per uvhub invalid\n", | ||
1719 | bcp->uvhub_cpu); | ||
1720 | return 1; | ||
1721 | } | ||
1722 | } | ||
1723 | return 0; | ||
1724 | } | ||
1725 | |||
1726 | /* | ||
1727 | * Summarize the blade and socket topology into the per_cpu structures. | ||
1728 | */ | ||
1729 | static int __init summarize_uvhub_sockets(int nuvhubs, | ||
1730 | struct uvhub_desc *uvhub_descs, | ||
1731 | unsigned char *uvhub_mask) | ||
1732 | { | ||
1733 | int socket; | ||
1734 | int uvhub; | ||
1735 | unsigned short socket_mask; | ||
1736 | |||
1568 | for (uvhub = 0; uvhub < nuvhubs; uvhub++) { | 1737 | for (uvhub = 0; uvhub < nuvhubs; uvhub++) { |
1738 | struct uvhub_desc *bdp; | ||
1739 | struct bau_control *smaster = NULL; | ||
1740 | struct bau_control *hmaster = NULL; | ||
1741 | |||
1569 | if (!(*(uvhub_mask + (uvhub/8)) & (1 << (uvhub%8)))) | 1742 | if (!(*(uvhub_mask + (uvhub/8)) & (1 << (uvhub%8)))) |
1570 | continue; | 1743 | continue; |
1571 | have_hmaster = 0; | 1744 | |
1572 | bdp = &uvhub_descs[uvhub]; | 1745 | bdp = &uvhub_descs[uvhub]; |
1573 | socket_mask = bdp->socket_mask; | 1746 | socket_mask = bdp->socket_mask; |
1574 | socket = 0; | 1747 | socket = 0; |
1575 | while (socket_mask) { | 1748 | while (socket_mask) { |
1576 | if (!(socket_mask & 1)) | 1749 | struct socket_desc *sdp; |
1577 | goto nextsocket; | 1750 | if ((socket_mask & 1)) { |
1578 | sdp = &bdp->socket[socket]; | 1751 | sdp = &bdp->socket[socket]; |
1579 | for (i = 0; i < sdp->num_cpus; i++) { | 1752 | if (scan_sock(sdp, bdp, &smaster, &hmaster)) |
1580 | cpu = sdp->cpu_number[i]; | ||
1581 | bcp = &per_cpu(bau_control, cpu); | ||
1582 | bcp->cpu = cpu; | ||
1583 | if (i == 0) { | ||
1584 | smaster = bcp; | ||
1585 | if (!have_hmaster) { | ||
1586 | have_hmaster++; | ||
1587 | hmaster = bcp; | ||
1588 | } | ||
1589 | } | ||
1590 | bcp->cpus_in_uvhub = bdp->num_cpus; | ||
1591 | bcp->cpus_in_socket = sdp->num_cpus; | ||
1592 | bcp->socket_master = smaster; | ||
1593 | bcp->uvhub = bdp->uvhub; | ||
1594 | bcp->uvhub_master = hmaster; | ||
1595 | bcp->uvhub_cpu = uv_cpu_hub_info(cpu)-> | ||
1596 | blade_processor_id; | ||
1597 | if (bcp->uvhub_cpu >= MAX_CPUS_PER_UVHUB) { | ||
1598 | printk(KERN_EMERG | ||
1599 | "%d cpus per uvhub invalid\n", | ||
1600 | bcp->uvhub_cpu); | ||
1601 | return 1; | 1753 | return 1; |
1602 | } | ||
1603 | } | 1754 | } |
1604 | nextsocket: | ||
1605 | socket++; | 1755 | socket++; |
1606 | socket_mask = (socket_mask >> 1); | 1756 | socket_mask = (socket_mask >> 1); |
1607 | /* each socket gets a local array of pnodes/hubs */ | 1757 | make_per_cpu_thp(smaster); |
1608 | bcp = smaster; | ||
1609 | bcp->target_hub_and_pnode = kmalloc_node( | ||
1610 | sizeof(struct hub_and_pnode) * | ||
1611 | num_possible_cpus(), GFP_KERNEL, bcp->osnode); | ||
1612 | memset(bcp->target_hub_and_pnode, 0, | ||
1613 | sizeof(struct hub_and_pnode) * | ||
1614 | num_possible_cpus()); | ||
1615 | for_each_present_cpu(tcpu) { | ||
1616 | bcp->target_hub_and_pnode[tcpu].pnode = | ||
1617 | uv_cpu_hub_info(tcpu)->pnode; | ||
1618 | bcp->target_hub_and_pnode[tcpu].uvhub = | ||
1619 | uv_cpu_hub_info(tcpu)->numa_blade_id; | ||
1620 | } | ||
1621 | } | 1758 | } |
1622 | } | 1759 | } |
1760 | return 0; | ||
1761 | } | ||
1762 | |||
1763 | /* | ||
1764 | * initialize the bau_control structure for each cpu | ||
1765 | */ | ||
1766 | static int __init init_per_cpu(int nuvhubs, int base_part_pnode) | ||
1767 | { | ||
1768 | unsigned char *uvhub_mask; | ||
1769 | void *vp; | ||
1770 | struct uvhub_desc *uvhub_descs; | ||
1771 | |||
1772 | timeout_us = calculate_destination_timeout(); | ||
1773 | |||
1774 | vp = kmalloc(nuvhubs * sizeof(struct uvhub_desc), GFP_KERNEL); | ||
1775 | uvhub_descs = (struct uvhub_desc *)vp; | ||
1776 | memset(uvhub_descs, 0, nuvhubs * sizeof(struct uvhub_desc)); | ||
1777 | uvhub_mask = kzalloc((nuvhubs+7)/8, GFP_KERNEL); | ||
1778 | |||
1779 | if (get_cpu_topology(base_part_pnode, uvhub_descs, uvhub_mask)) | ||
1780 | return 1; | ||
1781 | |||
1782 | if (summarize_uvhub_sockets(nuvhubs, uvhub_descs, uvhub_mask)) | ||
1783 | return 1; | ||
1784 | |||
1623 | kfree(uvhub_descs); | 1785 | kfree(uvhub_descs); |
1624 | kfree(uvhub_mask); | 1786 | kfree(uvhub_mask); |
1625 | for_each_present_cpu(cpu) { | 1787 | init_per_cpu_tunables(); |
1626 | bcp = &per_cpu(bau_control, cpu); | ||
1627 | bcp->baudisabled = 0; | ||
1628 | bcp->statp = &per_cpu(ptcstats, cpu); | ||
1629 | /* time interval to catch a hardware stay-busy bug */ | ||
1630 | bcp->timeout_interval = microsec_2_cycles(2*timeout_us); | ||
1631 | bcp->max_bau_concurrent = max_bau_concurrent; | ||
1632 | bcp->max_bau_concurrent_constant = max_bau_concurrent; | ||
1633 | bcp->plugged_delay = plugged_delay; | ||
1634 | bcp->plugsb4reset = plugsb4reset; | ||
1635 | bcp->timeoutsb4reset = timeoutsb4reset; | ||
1636 | bcp->ipi_reset_limit = ipi_reset_limit; | ||
1637 | bcp->complete_threshold = complete_threshold; | ||
1638 | bcp->congested_response_us = congested_response_us; | ||
1639 | bcp->congested_reps = congested_reps; | ||
1640 | bcp->congested_period = congested_period; | ||
1641 | } | ||
1642 | return 0; | 1788 | return 0; |
1643 | } | 1789 | } |
1644 | 1790 | ||
@@ -1651,8 +1797,9 @@ static int __init uv_bau_init(void) | |||
1651 | int pnode; | 1797 | int pnode; |
1652 | int nuvhubs; | 1798 | int nuvhubs; |
1653 | int cur_cpu; | 1799 | int cur_cpu; |
1800 | int cpus; | ||
1654 | int vector; | 1801 | int vector; |
1655 | unsigned long mmr; | 1802 | cpumask_var_t *mask; |
1656 | 1803 | ||
1657 | if (!is_uv_system()) | 1804 | if (!is_uv_system()) |
1658 | return 0; | 1805 | return 0; |
@@ -1660,24 +1807,25 @@ static int __init uv_bau_init(void) | |||
1660 | if (nobau) | 1807 | if (nobau) |
1661 | return 0; | 1808 | return 0; |
1662 | 1809 | ||
1663 | for_each_possible_cpu(cur_cpu) | 1810 | for_each_possible_cpu(cur_cpu) { |
1664 | zalloc_cpumask_var_node(&per_cpu(uv_flush_tlb_mask, cur_cpu), | 1811 | mask = &per_cpu(uv_flush_tlb_mask, cur_cpu); |
1665 | GFP_KERNEL, cpu_to_node(cur_cpu)); | 1812 | zalloc_cpumask_var_node(mask, GFP_KERNEL, cpu_to_node(cur_cpu)); |
1813 | } | ||
1666 | 1814 | ||
1667 | uv_nshift = uv_hub_info->m_val; | 1815 | uv_nshift = uv_hub_info->m_val; |
1668 | uv_mmask = (1UL << uv_hub_info->m_val) - 1; | 1816 | uv_mmask = (1UL << uv_hub_info->m_val) - 1; |
1669 | nuvhubs = uv_num_possible_blades(); | 1817 | nuvhubs = uv_num_possible_blades(); |
1670 | spin_lock_init(&disable_lock); | 1818 | spin_lock_init(&disable_lock); |
1671 | congested_cycles = microsec_2_cycles(congested_response_us); | 1819 | congested_cycles = usec_2_cycles(congested_respns_us); |
1672 | 1820 | ||
1673 | uv_partition_base_pnode = 0x7fffffff; | 1821 | uv_base_pnode = 0x7fffffff; |
1674 | for (uvhub = 0; uvhub < nuvhubs; uvhub++) { | 1822 | for (uvhub = 0; uvhub < nuvhubs; uvhub++) { |
1675 | if (uv_blade_nr_possible_cpus(uvhub) && | 1823 | cpus = uv_blade_nr_possible_cpus(uvhub); |
1676 | (uv_blade_to_pnode(uvhub) < uv_partition_base_pnode)) | 1824 | if (cpus && (uv_blade_to_pnode(uvhub) < uv_base_pnode)) |
1677 | uv_partition_base_pnode = uv_blade_to_pnode(uvhub); | 1825 | uv_base_pnode = uv_blade_to_pnode(uvhub); |
1678 | } | 1826 | } |
1679 | 1827 | ||
1680 | if (uv_init_per_cpu(nuvhubs, uv_partition_base_pnode)) { | 1828 | if (init_per_cpu(nuvhubs, uv_base_pnode)) { |
1681 | nobau = 1; | 1829 | nobau = 1; |
1682 | return 0; | 1830 | return 0; |
1683 | } | 1831 | } |
@@ -1685,21 +1833,21 @@ static int __init uv_bau_init(void) | |||
1685 | vector = UV_BAU_MESSAGE; | 1833 | vector = UV_BAU_MESSAGE; |
1686 | for_each_possible_blade(uvhub) | 1834 | for_each_possible_blade(uvhub) |
1687 | if (uv_blade_nr_possible_cpus(uvhub)) | 1835 | if (uv_blade_nr_possible_cpus(uvhub)) |
1688 | uv_init_uvhub(uvhub, vector, uv_partition_base_pnode); | 1836 | init_uvhub(uvhub, vector, uv_base_pnode); |
1689 | 1837 | ||
1690 | uv_enable_timeouts(); | 1838 | enable_timeouts(); |
1691 | alloc_intr_gate(vector, uv_bau_message_intr1); | 1839 | alloc_intr_gate(vector, uv_bau_message_intr1); |
1692 | 1840 | ||
1693 | for_each_possible_blade(uvhub) { | 1841 | for_each_possible_blade(uvhub) { |
1694 | if (uv_blade_nr_possible_cpus(uvhub)) { | 1842 | if (uv_blade_nr_possible_cpus(uvhub)) { |
1843 | unsigned long val; | ||
1844 | unsigned long mmr; | ||
1695 | pnode = uv_blade_to_pnode(uvhub); | 1845 | pnode = uv_blade_to_pnode(uvhub); |
1696 | /* INIT the bau */ | 1846 | /* INIT the bau */ |
1697 | uv_write_global_mmr64(pnode, | 1847 | val = 1L << 63; |
1698 | UVH_LB_BAU_SB_ACTIVATION_CONTROL, | 1848 | write_gmmr_activation(pnode, val); |
1699 | ((unsigned long)1 << 63)); | ||
1700 | mmr = 1; /* should be 1 to broadcast to both sockets */ | 1849 | mmr = 1; /* should be 1 to broadcast to both sockets */ |
1701 | uv_write_global_mmr64(pnode, UVH_BAU_DATA_BROADCAST, | 1850 | write_mmr_data_broadcast(pnode, mmr); |
1702 | mmr); | ||
1703 | } | 1851 | } |
1704 | } | 1852 | } |
1705 | 1853 | ||
diff --git a/arch/x86/platform/uv/uv_time.c b/arch/x86/platform/uv/uv_time.c index 0eb90184515f..9f29a01ee1b3 100644 --- a/arch/x86/platform/uv/uv_time.c +++ b/arch/x86/platform/uv/uv_time.c | |||
@@ -99,8 +99,12 @@ static void uv_rtc_send_IPI(int cpu) | |||
99 | /* Check for an RTC interrupt pending */ | 99 | /* Check for an RTC interrupt pending */ |
100 | static int uv_intr_pending(int pnode) | 100 | static int uv_intr_pending(int pnode) |
101 | { | 101 | { |
102 | return uv_read_global_mmr64(pnode, UVH_EVENT_OCCURRED0) & | 102 | if (is_uv1_hub()) |
103 | UVH_EVENT_OCCURRED0_RTC1_MASK; | 103 | return uv_read_global_mmr64(pnode, UVH_EVENT_OCCURRED0) & |
104 | UV1H_EVENT_OCCURRED0_RTC1_MASK; | ||
105 | else | ||
106 | return uv_read_global_mmr64(pnode, UV2H_EVENT_OCCURRED2) & | ||
107 | UV2H_EVENT_OCCURRED2_RTC_1_MASK; | ||
104 | } | 108 | } |
105 | 109 | ||
106 | /* Setup interrupt and return non-zero if early expiration occurred. */ | 110 | /* Setup interrupt and return non-zero if early expiration occurred. */ |
@@ -114,8 +118,12 @@ static int uv_setup_intr(int cpu, u64 expires) | |||
114 | UVH_RTC1_INT_CONFIG_M_MASK); | 118 | UVH_RTC1_INT_CONFIG_M_MASK); |
115 | uv_write_global_mmr64(pnode, UVH_INT_CMPB, -1L); | 119 | uv_write_global_mmr64(pnode, UVH_INT_CMPB, -1L); |
116 | 120 | ||
117 | uv_write_global_mmr64(pnode, UVH_EVENT_OCCURRED0_ALIAS, | 121 | if (is_uv1_hub()) |
118 | UVH_EVENT_OCCURRED0_RTC1_MASK); | 122 | uv_write_global_mmr64(pnode, UVH_EVENT_OCCURRED0_ALIAS, |
123 | UV1H_EVENT_OCCURRED0_RTC1_MASK); | ||
124 | else | ||
125 | uv_write_global_mmr64(pnode, UV2H_EVENT_OCCURRED2_ALIAS, | ||
126 | UV2H_EVENT_OCCURRED2_RTC_1_MASK); | ||
119 | 127 | ||
120 | val = (X86_PLATFORM_IPI_VECTOR << UVH_RTC1_INT_CONFIG_VECTOR_SHFT) | | 128 | val = (X86_PLATFORM_IPI_VECTOR << UVH_RTC1_INT_CONFIG_VECTOR_SHFT) | |
121 | ((u64)apicid << UVH_RTC1_INT_CONFIG_APIC_ID_SHFT); | 129 | ((u64)apicid << UVH_RTC1_INT_CONFIG_APIC_ID_SHFT); |
diff --git a/block/blk-ioc.c b/block/blk-ioc.c index c898049dafd5..342eae9b0d3c 100644 --- a/block/blk-ioc.c +++ b/block/blk-ioc.c | |||
@@ -21,7 +21,7 @@ static void cfq_dtor(struct io_context *ioc) | |||
21 | if (!hlist_empty(&ioc->cic_list)) { | 21 | if (!hlist_empty(&ioc->cic_list)) { |
22 | struct cfq_io_context *cic; | 22 | struct cfq_io_context *cic; |
23 | 23 | ||
24 | cic = list_entry(ioc->cic_list.first, struct cfq_io_context, | 24 | cic = hlist_entry(ioc->cic_list.first, struct cfq_io_context, |
25 | cic_list); | 25 | cic_list); |
26 | cic->dtor(ioc); | 26 | cic->dtor(ioc); |
27 | } | 27 | } |
@@ -57,7 +57,7 @@ static void cfq_exit(struct io_context *ioc) | |||
57 | if (!hlist_empty(&ioc->cic_list)) { | 57 | if (!hlist_empty(&ioc->cic_list)) { |
58 | struct cfq_io_context *cic; | 58 | struct cfq_io_context *cic; |
59 | 59 | ||
60 | cic = list_entry(ioc->cic_list.first, struct cfq_io_context, | 60 | cic = hlist_entry(ioc->cic_list.first, struct cfq_io_context, |
61 | cic_list); | 61 | cic_list); |
62 | cic->exit(ioc); | 62 | cic->exit(ioc); |
63 | } | 63 | } |
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 7c52d6888924..3c7b537bf908 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
@@ -185,7 +185,7 @@ struct cfq_group { | |||
185 | int nr_cfqq; | 185 | int nr_cfqq; |
186 | 186 | ||
187 | /* | 187 | /* |
188 | * Per group busy queus average. Useful for workload slice calc. We | 188 | * Per group busy queues average. Useful for workload slice calc. We |
189 | * create the array for each prio class but at run time it is used | 189 | * create the array for each prio class but at run time it is used |
190 | * only for RT and BE class and slot for IDLE class remains unused. | 190 | * only for RT and BE class and slot for IDLE class remains unused. |
191 | * This is primarily done to avoid confusion and a gcc warning. | 191 | * This is primarily done to avoid confusion and a gcc warning. |
@@ -369,16 +369,16 @@ CFQ_CFQQ_FNS(wait_busy); | |||
369 | #define cfq_log_cfqq(cfqd, cfqq, fmt, args...) \ | 369 | #define cfq_log_cfqq(cfqd, cfqq, fmt, args...) \ |
370 | blk_add_trace_msg((cfqd)->queue, "cfq%d%c %s " fmt, (cfqq)->pid, \ | 370 | blk_add_trace_msg((cfqd)->queue, "cfq%d%c %s " fmt, (cfqq)->pid, \ |
371 | cfq_cfqq_sync((cfqq)) ? 'S' : 'A', \ | 371 | cfq_cfqq_sync((cfqq)) ? 'S' : 'A', \ |
372 | blkg_path(&(cfqq)->cfqg->blkg), ##args); | 372 | blkg_path(&(cfqq)->cfqg->blkg), ##args) |
373 | 373 | ||
374 | #define cfq_log_cfqg(cfqd, cfqg, fmt, args...) \ | 374 | #define cfq_log_cfqg(cfqd, cfqg, fmt, args...) \ |
375 | blk_add_trace_msg((cfqd)->queue, "%s " fmt, \ | 375 | blk_add_trace_msg((cfqd)->queue, "%s " fmt, \ |
376 | blkg_path(&(cfqg)->blkg), ##args); \ | 376 | blkg_path(&(cfqg)->blkg), ##args) \ |
377 | 377 | ||
378 | #else | 378 | #else |
379 | #define cfq_log_cfqq(cfqd, cfqq, fmt, args...) \ | 379 | #define cfq_log_cfqq(cfqd, cfqq, fmt, args...) \ |
380 | blk_add_trace_msg((cfqd)->queue, "cfq%d " fmt, (cfqq)->pid, ##args) | 380 | blk_add_trace_msg((cfqd)->queue, "cfq%d " fmt, (cfqq)->pid, ##args) |
381 | #define cfq_log_cfqg(cfqd, cfqg, fmt, args...) do {} while (0); | 381 | #define cfq_log_cfqg(cfqd, cfqg, fmt, args...) do {} while (0) |
382 | #endif | 382 | #endif |
383 | #define cfq_log(cfqd, fmt, args...) \ | 383 | #define cfq_log(cfqd, fmt, args...) \ |
384 | blk_add_trace_msg((cfqd)->queue, "cfq " fmt, ##args) | 384 | blk_add_trace_msg((cfqd)->queue, "cfq " fmt, ##args) |
@@ -3786,9 +3786,6 @@ new_queue: | |||
3786 | return 0; | 3786 | return 0; |
3787 | 3787 | ||
3788 | queue_fail: | 3788 | queue_fail: |
3789 | if (cic) | ||
3790 | put_io_context(cic->ioc); | ||
3791 | |||
3792 | cfq_schedule_dispatch(cfqd); | 3789 | cfq_schedule_dispatch(cfqd); |
3793 | spin_unlock_irqrestore(q->queue_lock, flags); | 3790 | spin_unlock_irqrestore(q->queue_lock, flags); |
3794 | cfq_log(cfqd, "set_request fail"); | 3791 | cfq_log(cfqd, "set_request fail"); |
diff --git a/drivers/Makefile b/drivers/Makefile index 6b17f5864340..09f3232bcdcd 100644 --- a/drivers/Makefile +++ b/drivers/Makefile | |||
@@ -17,6 +17,9 @@ obj-$(CONFIG_SFI) += sfi/ | |||
17 | # was used and do nothing if so | 17 | # was used and do nothing if so |
18 | obj-$(CONFIG_PNP) += pnp/ | 18 | obj-$(CONFIG_PNP) += pnp/ |
19 | obj-$(CONFIG_ARM_AMBA) += amba/ | 19 | obj-$(CONFIG_ARM_AMBA) += amba/ |
20 | # Many drivers will want to use DMA so this has to be made available | ||
21 | # really early. | ||
22 | obj-$(CONFIG_DMA_ENGINE) += dma/ | ||
20 | 23 | ||
21 | obj-$(CONFIG_VIRTIO) += virtio/ | 24 | obj-$(CONFIG_VIRTIO) += virtio/ |
22 | obj-$(CONFIG_XEN) += xen/ | 25 | obj-$(CONFIG_XEN) += xen/ |
@@ -92,7 +95,6 @@ obj-$(CONFIG_EISA) += eisa/ | |||
92 | obj-y += lguest/ | 95 | obj-y += lguest/ |
93 | obj-$(CONFIG_CPU_FREQ) += cpufreq/ | 96 | obj-$(CONFIG_CPU_FREQ) += cpufreq/ |
94 | obj-$(CONFIG_CPU_IDLE) += cpuidle/ | 97 | obj-$(CONFIG_CPU_IDLE) += cpuidle/ |
95 | obj-$(CONFIG_DMA_ENGINE) += dma/ | ||
96 | obj-$(CONFIG_MMC) += mmc/ | 98 | obj-$(CONFIG_MMC) += mmc/ |
97 | obj-$(CONFIG_MEMSTICK) += memstick/ | 99 | obj-$(CONFIG_MEMSTICK) += memstick/ |
98 | obj-y += leds/ | 100 | obj-y += leds/ |
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index bc2218db5ba9..de0e3df76776 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -369,6 +369,21 @@ config ACPI_HED | |||
369 | which is used to report some hardware errors notified via | 369 | which is used to report some hardware errors notified via |
370 | SCI, mainly the corrected errors. | 370 | SCI, mainly the corrected errors. |
371 | 371 | ||
372 | config ACPI_CUSTOM_METHOD | ||
373 | tristate "Allow ACPI methods to be inserted/replaced at run time" | ||
374 | depends on DEBUG_FS | ||
375 | default n | ||
376 | help | ||
377 | This debug facility allows ACPI AML methods to me inserted and/or | ||
378 | replaced without rebooting the system. For details refer to: | ||
379 | Documentation/acpi/method-customizing.txt. | ||
380 | |||
381 | NOTE: This option is security sensitive, because it allows arbitrary | ||
382 | kernel memory to be written to by root (uid=0) users, allowing them | ||
383 | to bypass certain security measures (e.g. if root is not allowed to | ||
384 | load additional kernel modules after boot, this feature may be used | ||
385 | to override that restriction). | ||
386 | |||
372 | source "drivers/acpi/apei/Kconfig" | 387 | source "drivers/acpi/apei/Kconfig" |
373 | 388 | ||
374 | endif # ACPI | 389 | endif # ACPI |
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index b66fbb2fc85f..ecb26b4f29a0 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
@@ -61,6 +61,7 @@ obj-$(CONFIG_ACPI_SBS) += sbshc.o | |||
61 | obj-$(CONFIG_ACPI_SBS) += sbs.o | 61 | obj-$(CONFIG_ACPI_SBS) += sbs.o |
62 | obj-$(CONFIG_ACPI_HED) += hed.o | 62 | obj-$(CONFIG_ACPI_HED) += hed.o |
63 | obj-$(CONFIG_ACPI_EC_DEBUGFS) += ec_sys.o | 63 | obj-$(CONFIG_ACPI_EC_DEBUGFS) += ec_sys.o |
64 | obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o | ||
64 | 65 | ||
65 | # processor has its own "processor." module_param namespace | 66 | # processor has its own "processor." module_param namespace |
66 | processor-y := processor_driver.o processor_throttling.o | 67 | processor-y := processor_driver.o processor_throttling.o |
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index a1224712fd0c..301bd2d388ad 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile | |||
@@ -14,7 +14,7 @@ acpi-y := dsfield.o dsmthdat.o dsopcode.o dswexec.o dswscope.o \ | |||
14 | 14 | ||
15 | acpi-y += evevent.o evregion.o evsci.o evxfevnt.o \ | 15 | acpi-y += evevent.o evregion.o evsci.o evxfevnt.o \ |
16 | evmisc.o evrgnini.o evxface.o evxfregn.o \ | 16 | evmisc.o evrgnini.o evxface.o evxfregn.o \ |
17 | evgpe.o evgpeblk.o evgpeinit.o evgpeutil.o evxfgpe.o | 17 | evgpe.o evgpeblk.o evgpeinit.o evgpeutil.o evxfgpe.o evglock.o |
18 | 18 | ||
19 | acpi-y += exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\ | 19 | acpi-y += exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\ |
20 | exconvrt.o exfldio.o exoparg1.o exprep.o exresop.o exsystem.o\ | 20 | exconvrt.o exfldio.o exoparg1.o exprep.o exresop.o exsystem.o\ |
diff --git a/drivers/acpi/acpica/acconfig.h b/drivers/acpi/acpica/acconfig.h index ab87396c2c07..bc533dde16c4 100644 --- a/drivers/acpi/acpica/acconfig.h +++ b/drivers/acpi/acpica/acconfig.h | |||
@@ -187,7 +187,6 @@ | |||
187 | 187 | ||
188 | /* Operation regions */ | 188 | /* Operation regions */ |
189 | 189 | ||
190 | #define ACPI_NUM_PREDEFINED_REGIONS 9 | ||
191 | #define ACPI_USER_REGION_BEGIN 0x80 | 190 | #define ACPI_USER_REGION_BEGIN 0x80 |
192 | 191 | ||
193 | /* Maximum space_ids for Operation Regions */ | 192 | /* Maximum space_ids for Operation Regions */ |
diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index 41d247daf461..bea3b4899183 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h | |||
@@ -58,12 +58,6 @@ u32 acpi_ev_fixed_event_detect(void); | |||
58 | */ | 58 | */ |
59 | u8 acpi_ev_is_notify_object(struct acpi_namespace_node *node); | 59 | u8 acpi_ev_is_notify_object(struct acpi_namespace_node *node); |
60 | 60 | ||
61 | acpi_status acpi_ev_acquire_global_lock(u16 timeout); | ||
62 | |||
63 | acpi_status acpi_ev_release_global_lock(void); | ||
64 | |||
65 | acpi_status acpi_ev_init_global_lock_handler(void); | ||
66 | |||
67 | u32 acpi_ev_get_gpe_number_index(u32 gpe_number); | 61 | u32 acpi_ev_get_gpe_number_index(u32 gpe_number); |
68 | 62 | ||
69 | acpi_status | 63 | acpi_status |
@@ -71,6 +65,17 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node *node, | |||
71 | u32 notify_value); | 65 | u32 notify_value); |
72 | 66 | ||
73 | /* | 67 | /* |
68 | * evglock - Global Lock support | ||
69 | */ | ||
70 | acpi_status acpi_ev_init_global_lock_handler(void); | ||
71 | |||
72 | acpi_status acpi_ev_acquire_global_lock(u16 timeout); | ||
73 | |||
74 | acpi_status acpi_ev_release_global_lock(void); | ||
75 | |||
76 | acpi_status acpi_ev_remove_global_lock_handler(void); | ||
77 | |||
78 | /* | ||
74 | * evgpe - Low-level GPE support | 79 | * evgpe - Low-level GPE support |
75 | */ | 80 | */ |
76 | u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list); | 81 | u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list); |
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index d69750b83b36..73863d86f022 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h | |||
@@ -214,24 +214,23 @@ ACPI_EXTERN struct acpi_mutex_info acpi_gbl_mutex_info[ACPI_NUM_MUTEX]; | |||
214 | 214 | ||
215 | /* | 215 | /* |
216 | * Global lock mutex is an actual AML mutex object | 216 | * Global lock mutex is an actual AML mutex object |
217 | * Global lock semaphore works in conjunction with the HW global lock | 217 | * Global lock semaphore works in conjunction with the actual global lock |
218 | * Global lock spinlock is used for "pending" handshake | ||
218 | */ | 219 | */ |
219 | ACPI_EXTERN union acpi_operand_object *acpi_gbl_global_lock_mutex; | 220 | ACPI_EXTERN union acpi_operand_object *acpi_gbl_global_lock_mutex; |
220 | ACPI_EXTERN acpi_semaphore acpi_gbl_global_lock_semaphore; | 221 | ACPI_EXTERN acpi_semaphore acpi_gbl_global_lock_semaphore; |
222 | ACPI_EXTERN acpi_spinlock acpi_gbl_global_lock_pending_lock; | ||
221 | ACPI_EXTERN u16 acpi_gbl_global_lock_handle; | 223 | ACPI_EXTERN u16 acpi_gbl_global_lock_handle; |
222 | ACPI_EXTERN u8 acpi_gbl_global_lock_acquired; | 224 | ACPI_EXTERN u8 acpi_gbl_global_lock_acquired; |
223 | ACPI_EXTERN u8 acpi_gbl_global_lock_present; | 225 | ACPI_EXTERN u8 acpi_gbl_global_lock_present; |
226 | ACPI_EXTERN u8 acpi_gbl_global_lock_pending; | ||
224 | 227 | ||
225 | /* | 228 | /* |
226 | * Spinlocks are used for interfaces that can be possibly called at | 229 | * Spinlocks are used for interfaces that can be possibly called at |
227 | * interrupt level | 230 | * interrupt level |
228 | */ | 231 | */ |
229 | ACPI_EXTERN spinlock_t _acpi_gbl_gpe_lock; /* For GPE data structs and registers */ | 232 | ACPI_EXTERN acpi_spinlock acpi_gbl_gpe_lock; /* For GPE data structs and registers */ |
230 | ACPI_EXTERN spinlock_t _acpi_gbl_hardware_lock; /* For ACPI H/W except GPE registers */ | 233 | ACPI_EXTERN acpi_spinlock acpi_gbl_hardware_lock; /* For ACPI H/W except GPE registers */ |
231 | ACPI_EXTERN spinlock_t _acpi_ev_global_lock_pending_lock; /* For global lock */ | ||
232 | #define acpi_gbl_gpe_lock &_acpi_gbl_gpe_lock | ||
233 | #define acpi_gbl_hardware_lock &_acpi_gbl_hardware_lock | ||
234 | #define acpi_ev_global_lock_pending_lock &_acpi_ev_global_lock_pending_lock | ||
235 | 234 | ||
236 | /***************************************************************************** | 235 | /***************************************************************************** |
237 | * | 236 | * |
diff --git a/drivers/acpi/acpica/amlcode.h b/drivers/acpi/acpica/amlcode.h index f4f0998d3967..1077f17859ed 100644 --- a/drivers/acpi/acpica/amlcode.h +++ b/drivers/acpi/acpica/amlcode.h | |||
@@ -394,21 +394,6 @@ | |||
394 | #define AML_CLASS_METHOD_CALL 0x09 | 394 | #define AML_CLASS_METHOD_CALL 0x09 |
395 | #define AML_CLASS_UNKNOWN 0x0A | 395 | #define AML_CLASS_UNKNOWN 0x0A |
396 | 396 | ||
397 | /* Predefined Operation Region space_iDs */ | ||
398 | |||
399 | typedef enum { | ||
400 | REGION_MEMORY = 0, | ||
401 | REGION_IO, | ||
402 | REGION_PCI_CONFIG, | ||
403 | REGION_EC, | ||
404 | REGION_SMBUS, | ||
405 | REGION_CMOS, | ||
406 | REGION_PCI_BAR, | ||
407 | REGION_IPMI, | ||
408 | REGION_DATA_TABLE, /* Internal use only */ | ||
409 | REGION_FIXED_HW = 0x7F | ||
410 | } AML_REGION_TYPES; | ||
411 | |||
412 | /* Comparison operation codes for match_op operator */ | 397 | /* Comparison operation codes for match_op operator */ |
413 | 398 | ||
414 | typedef enum { | 399 | typedef enum { |
diff --git a/drivers/acpi/acpica/dswload.c b/drivers/acpi/acpica/dswload.c index 23a3b1ab20c1..324acec1179a 100644 --- a/drivers/acpi/acpica/dswload.c +++ b/drivers/acpi/acpica/dswload.c | |||
@@ -450,7 +450,7 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state) | |||
450 | status = | 450 | status = |
451 | acpi_ex_create_region(op->named.data, | 451 | acpi_ex_create_region(op->named.data, |
452 | op->named.length, | 452 | op->named.length, |
453 | REGION_DATA_TABLE, | 453 | ACPI_ADR_SPACE_DATA_TABLE, |
454 | walk_state); | 454 | walk_state); |
455 | if (ACPI_FAILURE(status)) { | 455 | if (ACPI_FAILURE(status)) { |
456 | return_ACPI_STATUS(status); | 456 | return_ACPI_STATUS(status); |
diff --git a/drivers/acpi/acpica/dswload2.c b/drivers/acpi/acpica/dswload2.c index 4be4e921dfe1..976318138c56 100644 --- a/drivers/acpi/acpica/dswload2.c +++ b/drivers/acpi/acpica/dswload2.c | |||
@@ -562,7 +562,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) | |||
562 | ((op->common.value.arg)->common.value. | 562 | ((op->common.value.arg)->common.value. |
563 | integer); | 563 | integer); |
564 | } else { | 564 | } else { |
565 | region_space = REGION_DATA_TABLE; | 565 | region_space = ACPI_ADR_SPACE_DATA_TABLE; |
566 | } | 566 | } |
567 | 567 | ||
568 | /* | 568 | /* |
diff --git a/drivers/acpi/acpica/evglock.c b/drivers/acpi/acpica/evglock.c new file mode 100644 index 000000000000..56a562a1e5d7 --- /dev/null +++ b/drivers/acpi/acpica/evglock.c | |||
@@ -0,0 +1,335 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: evglock - Global Lock support | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2011, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include "accommon.h" | ||
46 | #include "acevents.h" | ||
47 | #include "acinterp.h" | ||
48 | |||
49 | #define _COMPONENT ACPI_EVENTS | ||
50 | ACPI_MODULE_NAME("evglock") | ||
51 | |||
52 | /* Local prototypes */ | ||
53 | static u32 acpi_ev_global_lock_handler(void *context); | ||
54 | |||
55 | /******************************************************************************* | ||
56 | * | ||
57 | * FUNCTION: acpi_ev_init_global_lock_handler | ||
58 | * | ||
59 | * PARAMETERS: None | ||
60 | * | ||
61 | * RETURN: Status | ||
62 | * | ||
63 | * DESCRIPTION: Install a handler for the global lock release event | ||
64 | * | ||
65 | ******************************************************************************/ | ||
66 | |||
67 | acpi_status acpi_ev_init_global_lock_handler(void) | ||
68 | { | ||
69 | acpi_status status; | ||
70 | |||
71 | ACPI_FUNCTION_TRACE(ev_init_global_lock_handler); | ||
72 | |||
73 | /* Attempt installation of the global lock handler */ | ||
74 | |||
75 | status = acpi_install_fixed_event_handler(ACPI_EVENT_GLOBAL, | ||
76 | acpi_ev_global_lock_handler, | ||
77 | NULL); | ||
78 | |||
79 | /* | ||
80 | * If the global lock does not exist on this platform, the attempt to | ||
81 | * enable GBL_STATUS will fail (the GBL_ENABLE bit will not stick). | ||
82 | * Map to AE_OK, but mark global lock as not present. Any attempt to | ||
83 | * actually use the global lock will be flagged with an error. | ||
84 | */ | ||
85 | acpi_gbl_global_lock_present = FALSE; | ||
86 | if (status == AE_NO_HARDWARE_RESPONSE) { | ||
87 | ACPI_ERROR((AE_INFO, | ||
88 | "No response from Global Lock hardware, disabling lock")); | ||
89 | |||
90 | return_ACPI_STATUS(AE_OK); | ||
91 | } | ||
92 | |||
93 | status = acpi_os_create_lock(&acpi_gbl_global_lock_pending_lock); | ||
94 | if (ACPI_FAILURE(status)) { | ||
95 | return_ACPI_STATUS(status); | ||
96 | } | ||
97 | |||
98 | acpi_gbl_global_lock_pending = FALSE; | ||
99 | acpi_gbl_global_lock_present = TRUE; | ||
100 | return_ACPI_STATUS(status); | ||
101 | } | ||
102 | |||
103 | /******************************************************************************* | ||
104 | * | ||
105 | * FUNCTION: acpi_ev_remove_global_lock_handler | ||
106 | * | ||
107 | * PARAMETERS: None | ||
108 | * | ||
109 | * RETURN: Status | ||
110 | * | ||
111 | * DESCRIPTION: Remove the handler for the Global Lock | ||
112 | * | ||
113 | ******************************************************************************/ | ||
114 | |||
115 | acpi_status acpi_ev_remove_global_lock_handler(void) | ||
116 | { | ||
117 | acpi_status status; | ||
118 | |||
119 | ACPI_FUNCTION_TRACE(ev_remove_global_lock_handler); | ||
120 | |||
121 | acpi_gbl_global_lock_present = FALSE; | ||
122 | status = acpi_remove_fixed_event_handler(ACPI_EVENT_GLOBAL, | ||
123 | acpi_ev_global_lock_handler); | ||
124 | |||
125 | return_ACPI_STATUS(status); | ||
126 | } | ||
127 | |||
128 | /******************************************************************************* | ||
129 | * | ||
130 | * FUNCTION: acpi_ev_global_lock_handler | ||
131 | * | ||
132 | * PARAMETERS: Context - From thread interface, not used | ||
133 | * | ||
134 | * RETURN: ACPI_INTERRUPT_HANDLED | ||
135 | * | ||
136 | * DESCRIPTION: Invoked directly from the SCI handler when a global lock | ||
137 | * release interrupt occurs. If there is actually a pending | ||
138 | * request for the lock, signal the waiting thread. | ||
139 | * | ||
140 | ******************************************************************************/ | ||
141 | |||
142 | static u32 acpi_ev_global_lock_handler(void *context) | ||
143 | { | ||
144 | acpi_status status; | ||
145 | acpi_cpu_flags flags; | ||
146 | |||
147 | flags = acpi_os_acquire_lock(acpi_gbl_global_lock_pending_lock); | ||
148 | |||
149 | /* | ||
150 | * If a request for the global lock is not actually pending, | ||
151 | * we are done. This handles "spurious" global lock interrupts | ||
152 | * which are possible (and have been seen) with bad BIOSs. | ||
153 | */ | ||
154 | if (!acpi_gbl_global_lock_pending) { | ||
155 | goto cleanup_and_exit; | ||
156 | } | ||
157 | |||
158 | /* | ||
159 | * Send a unit to the global lock semaphore. The actual acquisition | ||
160 | * of the global lock will be performed by the waiting thread. | ||
161 | */ | ||
162 | status = acpi_os_signal_semaphore(acpi_gbl_global_lock_semaphore, 1); | ||
163 | if (ACPI_FAILURE(status)) { | ||
164 | ACPI_ERROR((AE_INFO, "Could not signal Global Lock semaphore")); | ||
165 | } | ||
166 | |||
167 | acpi_gbl_global_lock_pending = FALSE; | ||
168 | |||
169 | cleanup_and_exit: | ||
170 | |||
171 | acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags); | ||
172 | return (ACPI_INTERRUPT_HANDLED); | ||
173 | } | ||
174 | |||
175 | /****************************************************************************** | ||
176 | * | ||
177 | * FUNCTION: acpi_ev_acquire_global_lock | ||
178 | * | ||
179 | * PARAMETERS: Timeout - Max time to wait for the lock, in millisec. | ||
180 | * | ||
181 | * RETURN: Status | ||
182 | * | ||
183 | * DESCRIPTION: Attempt to gain ownership of the Global Lock. | ||
184 | * | ||
185 | * MUTEX: Interpreter must be locked | ||
186 | * | ||
187 | * Note: The original implementation allowed multiple threads to "acquire" the | ||
188 | * Global Lock, and the OS would hold the lock until the last thread had | ||
189 | * released it. However, this could potentially starve the BIOS out of the | ||
190 | * lock, especially in the case where there is a tight handshake between the | ||
191 | * Embedded Controller driver and the BIOS. Therefore, this implementation | ||
192 | * allows only one thread to acquire the HW Global Lock at a time, and makes | ||
193 | * the global lock appear as a standard mutex on the OS side. | ||
194 | * | ||
195 | *****************************************************************************/ | ||
196 | |||
197 | acpi_status acpi_ev_acquire_global_lock(u16 timeout) | ||
198 | { | ||
199 | acpi_cpu_flags flags; | ||
200 | acpi_status status; | ||
201 | u8 acquired = FALSE; | ||
202 | |||
203 | ACPI_FUNCTION_TRACE(ev_acquire_global_lock); | ||
204 | |||
205 | /* | ||
206 | * Only one thread can acquire the GL at a time, the global_lock_mutex | ||
207 | * enforces this. This interface releases the interpreter if we must wait. | ||
208 | */ | ||
209 | status = | ||
210 | acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex->mutex. | ||
211 | os_mutex, timeout); | ||
212 | if (ACPI_FAILURE(status)) { | ||
213 | return_ACPI_STATUS(status); | ||
214 | } | ||
215 | |||
216 | /* | ||
217 | * Update the global lock handle and check for wraparound. The handle is | ||
218 | * only used for the external global lock interfaces, but it is updated | ||
219 | * here to properly handle the case where a single thread may acquire the | ||
220 | * lock via both the AML and the acpi_acquire_global_lock interfaces. The | ||
221 | * handle is therefore updated on the first acquire from a given thread | ||
222 | * regardless of where the acquisition request originated. | ||
223 | */ | ||
224 | acpi_gbl_global_lock_handle++; | ||
225 | if (acpi_gbl_global_lock_handle == 0) { | ||
226 | acpi_gbl_global_lock_handle = 1; | ||
227 | } | ||
228 | |||
229 | /* | ||
230 | * Make sure that a global lock actually exists. If not, just | ||
231 | * treat the lock as a standard mutex. | ||
232 | */ | ||
233 | if (!acpi_gbl_global_lock_present) { | ||
234 | acpi_gbl_global_lock_acquired = TRUE; | ||
235 | return_ACPI_STATUS(AE_OK); | ||
236 | } | ||
237 | |||
238 | flags = acpi_os_acquire_lock(acpi_gbl_global_lock_pending_lock); | ||
239 | |||
240 | do { | ||
241 | |||
242 | /* Attempt to acquire the actual hardware lock */ | ||
243 | |||
244 | ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired); | ||
245 | if (acquired) { | ||
246 | acpi_gbl_global_lock_acquired = TRUE; | ||
247 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
248 | "Acquired hardware Global Lock\n")); | ||
249 | break; | ||
250 | } | ||
251 | |||
252 | /* | ||
253 | * Did not get the lock. The pending bit was set above, and | ||
254 | * we must now wait until we receive the global lock | ||
255 | * released interrupt. | ||
256 | */ | ||
257 | acpi_gbl_global_lock_pending = TRUE; | ||
258 | acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags); | ||
259 | |||
260 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
261 | "Waiting for hardware Global Lock\n")); | ||
262 | |||
263 | /* | ||
264 | * Wait for handshake with the global lock interrupt handler. | ||
265 | * This interface releases the interpreter if we must wait. | ||
266 | */ | ||
267 | status = | ||
268 | acpi_ex_system_wait_semaphore | ||
269 | (acpi_gbl_global_lock_semaphore, ACPI_WAIT_FOREVER); | ||
270 | |||
271 | flags = acpi_os_acquire_lock(acpi_gbl_global_lock_pending_lock); | ||
272 | |||
273 | } while (ACPI_SUCCESS(status)); | ||
274 | |||
275 | acpi_gbl_global_lock_pending = FALSE; | ||
276 | acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags); | ||
277 | |||
278 | return_ACPI_STATUS(status); | ||
279 | } | ||
280 | |||
281 | /******************************************************************************* | ||
282 | * | ||
283 | * FUNCTION: acpi_ev_release_global_lock | ||
284 | * | ||
285 | * PARAMETERS: None | ||
286 | * | ||
287 | * RETURN: Status | ||
288 | * | ||
289 | * DESCRIPTION: Releases ownership of the Global Lock. | ||
290 | * | ||
291 | ******************************************************************************/ | ||
292 | |||
293 | acpi_status acpi_ev_release_global_lock(void) | ||
294 | { | ||
295 | u8 pending = FALSE; | ||
296 | acpi_status status = AE_OK; | ||
297 | |||
298 | ACPI_FUNCTION_TRACE(ev_release_global_lock); | ||
299 | |||
300 | /* Lock must be already acquired */ | ||
301 | |||
302 | if (!acpi_gbl_global_lock_acquired) { | ||
303 | ACPI_WARNING((AE_INFO, | ||
304 | "Cannot release the ACPI Global Lock, it has not been acquired")); | ||
305 | return_ACPI_STATUS(AE_NOT_ACQUIRED); | ||
306 | } | ||
307 | |||
308 | if (acpi_gbl_global_lock_present) { | ||
309 | |||
310 | /* Allow any thread to release the lock */ | ||
311 | |||
312 | ACPI_RELEASE_GLOBAL_LOCK(acpi_gbl_FACS, pending); | ||
313 | |||
314 | /* | ||
315 | * If the pending bit was set, we must write GBL_RLS to the control | ||
316 | * register | ||
317 | */ | ||
318 | if (pending) { | ||
319 | status = | ||
320 | acpi_write_bit_register | ||
321 | (ACPI_BITREG_GLOBAL_LOCK_RELEASE, | ||
322 | ACPI_ENABLE_EVENT); | ||
323 | } | ||
324 | |||
325 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
326 | "Released hardware Global Lock\n")); | ||
327 | } | ||
328 | |||
329 | acpi_gbl_global_lock_acquired = FALSE; | ||
330 | |||
331 | /* Release the local GL mutex */ | ||
332 | |||
333 | acpi_os_release_mutex(acpi_gbl_global_lock_mutex->mutex.os_mutex); | ||
334 | return_ACPI_STATUS(status); | ||
335 | } | ||
diff --git a/drivers/acpi/acpica/evmisc.c b/drivers/acpi/acpica/evmisc.c index 7dc80946f7bd..d0b331844427 100644 --- a/drivers/acpi/acpica/evmisc.c +++ b/drivers/acpi/acpica/evmisc.c | |||
@@ -45,7 +45,6 @@ | |||
45 | #include "accommon.h" | 45 | #include "accommon.h" |
46 | #include "acevents.h" | 46 | #include "acevents.h" |
47 | #include "acnamesp.h" | 47 | #include "acnamesp.h" |
48 | #include "acinterp.h" | ||
49 | 48 | ||
50 | #define _COMPONENT ACPI_EVENTS | 49 | #define _COMPONENT ACPI_EVENTS |
51 | ACPI_MODULE_NAME("evmisc") | 50 | ACPI_MODULE_NAME("evmisc") |
@@ -53,10 +52,6 @@ ACPI_MODULE_NAME("evmisc") | |||
53 | /* Local prototypes */ | 52 | /* Local prototypes */ |
54 | static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context); | 53 | static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context); |
55 | 54 | ||
56 | static u32 acpi_ev_global_lock_handler(void *context); | ||
57 | |||
58 | static acpi_status acpi_ev_remove_global_lock_handler(void); | ||
59 | |||
60 | /******************************************************************************* | 55 | /******************************************************************************* |
61 | * | 56 | * |
62 | * FUNCTION: acpi_ev_is_notify_object | 57 | * FUNCTION: acpi_ev_is_notify_object |
@@ -275,304 +270,6 @@ static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context) | |||
275 | acpi_ut_delete_generic_state(notify_info); | 270 | acpi_ut_delete_generic_state(notify_info); |
276 | } | 271 | } |
277 | 272 | ||
278 | /******************************************************************************* | ||
279 | * | ||
280 | * FUNCTION: acpi_ev_global_lock_handler | ||
281 | * | ||
282 | * PARAMETERS: Context - From thread interface, not used | ||
283 | * | ||
284 | * RETURN: ACPI_INTERRUPT_HANDLED | ||
285 | * | ||
286 | * DESCRIPTION: Invoked directly from the SCI handler when a global lock | ||
287 | * release interrupt occurs. If there's a thread waiting for | ||
288 | * the global lock, signal it. | ||
289 | * | ||
290 | * NOTE: Assumes that the semaphore can be signaled from interrupt level. If | ||
291 | * this is not possible for some reason, a separate thread will have to be | ||
292 | * scheduled to do this. | ||
293 | * | ||
294 | ******************************************************************************/ | ||
295 | static u8 acpi_ev_global_lock_pending; | ||
296 | |||
297 | static u32 acpi_ev_global_lock_handler(void *context) | ||
298 | { | ||
299 | acpi_status status; | ||
300 | acpi_cpu_flags flags; | ||
301 | |||
302 | flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock); | ||
303 | |||
304 | if (!acpi_ev_global_lock_pending) { | ||
305 | goto out; | ||
306 | } | ||
307 | |||
308 | /* Send a unit to the semaphore */ | ||
309 | |||
310 | status = acpi_os_signal_semaphore(acpi_gbl_global_lock_semaphore, 1); | ||
311 | if (ACPI_FAILURE(status)) { | ||
312 | ACPI_ERROR((AE_INFO, "Could not signal Global Lock semaphore")); | ||
313 | } | ||
314 | |||
315 | acpi_ev_global_lock_pending = FALSE; | ||
316 | |||
317 | out: | ||
318 | acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags); | ||
319 | |||
320 | return (ACPI_INTERRUPT_HANDLED); | ||
321 | } | ||
322 | |||
323 | /******************************************************************************* | ||
324 | * | ||
325 | * FUNCTION: acpi_ev_init_global_lock_handler | ||
326 | * | ||
327 | * PARAMETERS: None | ||
328 | * | ||
329 | * RETURN: Status | ||
330 | * | ||
331 | * DESCRIPTION: Install a handler for the global lock release event | ||
332 | * | ||
333 | ******************************************************************************/ | ||
334 | |||
335 | acpi_status acpi_ev_init_global_lock_handler(void) | ||
336 | { | ||
337 | acpi_status status; | ||
338 | |||
339 | ACPI_FUNCTION_TRACE(ev_init_global_lock_handler); | ||
340 | |||
341 | /* Attempt installation of the global lock handler */ | ||
342 | |||
343 | status = acpi_install_fixed_event_handler(ACPI_EVENT_GLOBAL, | ||
344 | acpi_ev_global_lock_handler, | ||
345 | NULL); | ||
346 | |||
347 | /* | ||
348 | * If the global lock does not exist on this platform, the attempt to | ||
349 | * enable GBL_STATUS will fail (the GBL_ENABLE bit will not stick). | ||
350 | * Map to AE_OK, but mark global lock as not present. Any attempt to | ||
351 | * actually use the global lock will be flagged with an error. | ||
352 | */ | ||
353 | if (status == AE_NO_HARDWARE_RESPONSE) { | ||
354 | ACPI_ERROR((AE_INFO, | ||
355 | "No response from Global Lock hardware, disabling lock")); | ||
356 | |||
357 | acpi_gbl_global_lock_present = FALSE; | ||
358 | return_ACPI_STATUS(AE_OK); | ||
359 | } | ||
360 | |||
361 | acpi_gbl_global_lock_present = TRUE; | ||
362 | return_ACPI_STATUS(status); | ||
363 | } | ||
364 | |||
365 | /******************************************************************************* | ||
366 | * | ||
367 | * FUNCTION: acpi_ev_remove_global_lock_handler | ||
368 | * | ||
369 | * PARAMETERS: None | ||
370 | * | ||
371 | * RETURN: Status | ||
372 | * | ||
373 | * DESCRIPTION: Remove the handler for the Global Lock | ||
374 | * | ||
375 | ******************************************************************************/ | ||
376 | |||
377 | static acpi_status acpi_ev_remove_global_lock_handler(void) | ||
378 | { | ||
379 | acpi_status status; | ||
380 | |||
381 | ACPI_FUNCTION_TRACE(ev_remove_global_lock_handler); | ||
382 | |||
383 | acpi_gbl_global_lock_present = FALSE; | ||
384 | status = acpi_remove_fixed_event_handler(ACPI_EVENT_GLOBAL, | ||
385 | acpi_ev_global_lock_handler); | ||
386 | |||
387 | return_ACPI_STATUS(status); | ||
388 | } | ||
389 | |||
390 | /****************************************************************************** | ||
391 | * | ||
392 | * FUNCTION: acpi_ev_acquire_global_lock | ||
393 | * | ||
394 | * PARAMETERS: Timeout - Max time to wait for the lock, in millisec. | ||
395 | * | ||
396 | * RETURN: Status | ||
397 | * | ||
398 | * DESCRIPTION: Attempt to gain ownership of the Global Lock. | ||
399 | * | ||
400 | * MUTEX: Interpreter must be locked | ||
401 | * | ||
402 | * Note: The original implementation allowed multiple threads to "acquire" the | ||
403 | * Global Lock, and the OS would hold the lock until the last thread had | ||
404 | * released it. However, this could potentially starve the BIOS out of the | ||
405 | * lock, especially in the case where there is a tight handshake between the | ||
406 | * Embedded Controller driver and the BIOS. Therefore, this implementation | ||
407 | * allows only one thread to acquire the HW Global Lock at a time, and makes | ||
408 | * the global lock appear as a standard mutex on the OS side. | ||
409 | * | ||
410 | *****************************************************************************/ | ||
411 | static acpi_thread_id acpi_ev_global_lock_thread_id; | ||
412 | static int acpi_ev_global_lock_acquired; | ||
413 | |||
414 | acpi_status acpi_ev_acquire_global_lock(u16 timeout) | ||
415 | { | ||
416 | acpi_cpu_flags flags; | ||
417 | acpi_status status = AE_OK; | ||
418 | u8 acquired = FALSE; | ||
419 | |||
420 | ACPI_FUNCTION_TRACE(ev_acquire_global_lock); | ||
421 | |||
422 | /* | ||
423 | * Only one thread can acquire the GL at a time, the global_lock_mutex | ||
424 | * enforces this. This interface releases the interpreter if we must wait. | ||
425 | */ | ||
426 | status = acpi_ex_system_wait_mutex( | ||
427 | acpi_gbl_global_lock_mutex->mutex.os_mutex, 0); | ||
428 | if (status == AE_TIME) { | ||
429 | if (acpi_ev_global_lock_thread_id == acpi_os_get_thread_id()) { | ||
430 | acpi_ev_global_lock_acquired++; | ||
431 | return AE_OK; | ||
432 | } | ||
433 | } | ||
434 | |||
435 | if (ACPI_FAILURE(status)) { | ||
436 | status = acpi_ex_system_wait_mutex( | ||
437 | acpi_gbl_global_lock_mutex->mutex.os_mutex, | ||
438 | timeout); | ||
439 | } | ||
440 | if (ACPI_FAILURE(status)) { | ||
441 | return_ACPI_STATUS(status); | ||
442 | } | ||
443 | |||
444 | acpi_ev_global_lock_thread_id = acpi_os_get_thread_id(); | ||
445 | acpi_ev_global_lock_acquired++; | ||
446 | |||
447 | /* | ||
448 | * Update the global lock handle and check for wraparound. The handle is | ||
449 | * only used for the external global lock interfaces, but it is updated | ||
450 | * here to properly handle the case where a single thread may acquire the | ||
451 | * lock via both the AML and the acpi_acquire_global_lock interfaces. The | ||
452 | * handle is therefore updated on the first acquire from a given thread | ||
453 | * regardless of where the acquisition request originated. | ||
454 | */ | ||
455 | acpi_gbl_global_lock_handle++; | ||
456 | if (acpi_gbl_global_lock_handle == 0) { | ||
457 | acpi_gbl_global_lock_handle = 1; | ||
458 | } | ||
459 | |||
460 | /* | ||
461 | * Make sure that a global lock actually exists. If not, just treat the | ||
462 | * lock as a standard mutex. | ||
463 | */ | ||
464 | if (!acpi_gbl_global_lock_present) { | ||
465 | acpi_gbl_global_lock_acquired = TRUE; | ||
466 | return_ACPI_STATUS(AE_OK); | ||
467 | } | ||
468 | |||
469 | flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock); | ||
470 | |||
471 | do { | ||
472 | |||
473 | /* Attempt to acquire the actual hardware lock */ | ||
474 | |||
475 | ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired); | ||
476 | if (acquired) { | ||
477 | acpi_gbl_global_lock_acquired = TRUE; | ||
478 | |||
479 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
480 | "Acquired hardware Global Lock\n")); | ||
481 | break; | ||
482 | } | ||
483 | |||
484 | acpi_ev_global_lock_pending = TRUE; | ||
485 | |||
486 | acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags); | ||
487 | |||
488 | /* | ||
489 | * Did not get the lock. The pending bit was set above, and we | ||
490 | * must wait until we get the global lock released interrupt. | ||
491 | */ | ||
492 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
493 | "Waiting for hardware Global Lock\n")); | ||
494 | |||
495 | /* | ||
496 | * Wait for handshake with the global lock interrupt handler. | ||
497 | * This interface releases the interpreter if we must wait. | ||
498 | */ | ||
499 | status = acpi_ex_system_wait_semaphore( | ||
500 | acpi_gbl_global_lock_semaphore, | ||
501 | ACPI_WAIT_FOREVER); | ||
502 | |||
503 | flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock); | ||
504 | |||
505 | } while (ACPI_SUCCESS(status)); | ||
506 | |||
507 | acpi_ev_global_lock_pending = FALSE; | ||
508 | |||
509 | acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags); | ||
510 | |||
511 | return_ACPI_STATUS(status); | ||
512 | } | ||
513 | |||
514 | /******************************************************************************* | ||
515 | * | ||
516 | * FUNCTION: acpi_ev_release_global_lock | ||
517 | * | ||
518 | * PARAMETERS: None | ||
519 | * | ||
520 | * RETURN: Status | ||
521 | * | ||
522 | * DESCRIPTION: Releases ownership of the Global Lock. | ||
523 | * | ||
524 | ******************************************************************************/ | ||
525 | |||
526 | acpi_status acpi_ev_release_global_lock(void) | ||
527 | { | ||
528 | u8 pending = FALSE; | ||
529 | acpi_status status = AE_OK; | ||
530 | |||
531 | ACPI_FUNCTION_TRACE(ev_release_global_lock); | ||
532 | |||
533 | /* Lock must be already acquired */ | ||
534 | |||
535 | if (!acpi_gbl_global_lock_acquired) { | ||
536 | ACPI_WARNING((AE_INFO, | ||
537 | "Cannot release the ACPI Global Lock, it has not been acquired")); | ||
538 | return_ACPI_STATUS(AE_NOT_ACQUIRED); | ||
539 | } | ||
540 | |||
541 | acpi_ev_global_lock_acquired--; | ||
542 | if (acpi_ev_global_lock_acquired > 0) { | ||
543 | return AE_OK; | ||
544 | } | ||
545 | |||
546 | if (acpi_gbl_global_lock_present) { | ||
547 | |||
548 | /* Allow any thread to release the lock */ | ||
549 | |||
550 | ACPI_RELEASE_GLOBAL_LOCK(acpi_gbl_FACS, pending); | ||
551 | |||
552 | /* | ||
553 | * If the pending bit was set, we must write GBL_RLS to the control | ||
554 | * register | ||
555 | */ | ||
556 | if (pending) { | ||
557 | status = | ||
558 | acpi_write_bit_register | ||
559 | (ACPI_BITREG_GLOBAL_LOCK_RELEASE, | ||
560 | ACPI_ENABLE_EVENT); | ||
561 | } | ||
562 | |||
563 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
564 | "Released hardware Global Lock\n")); | ||
565 | } | ||
566 | |||
567 | acpi_gbl_global_lock_acquired = FALSE; | ||
568 | |||
569 | /* Release the local GL mutex */ | ||
570 | acpi_ev_global_lock_thread_id = 0; | ||
571 | acpi_ev_global_lock_acquired = 0; | ||
572 | acpi_os_release_mutex(acpi_gbl_global_lock_mutex->mutex.os_mutex); | ||
573 | return_ACPI_STATUS(status); | ||
574 | } | ||
575 | |||
576 | /****************************************************************************** | 273 | /****************************************************************************** |
577 | * | 274 | * |
578 | * FUNCTION: acpi_ev_terminate | 275 | * FUNCTION: acpi_ev_terminate |
diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c index bea7223d7a71..f0edf5c43c03 100644 --- a/drivers/acpi/acpica/evregion.c +++ b/drivers/acpi/acpica/evregion.c | |||
@@ -55,6 +55,8 @@ static u8 | |||
55 | acpi_ev_has_default_handler(struct acpi_namespace_node *node, | 55 | acpi_ev_has_default_handler(struct acpi_namespace_node *node, |
56 | acpi_adr_space_type space_id); | 56 | acpi_adr_space_type space_id); |
57 | 57 | ||
58 | static void acpi_ev_orphan_ec_reg_method(void); | ||
59 | |||
58 | static acpi_status | 60 | static acpi_status |
59 | acpi_ev_reg_run(acpi_handle obj_handle, | 61 | acpi_ev_reg_run(acpi_handle obj_handle, |
60 | u32 level, void *context, void **return_value); | 62 | u32 level, void *context, void **return_value); |
@@ -561,7 +563,9 @@ acpi_ev_detach_region(union acpi_operand_object *region_obj, | |||
561 | 563 | ||
562 | /* Now stop region accesses by executing the _REG method */ | 564 | /* Now stop region accesses by executing the _REG method */ |
563 | 565 | ||
564 | status = acpi_ev_execute_reg_method(region_obj, 0); | 566 | status = |
567 | acpi_ev_execute_reg_method(region_obj, | ||
568 | ACPI_REG_DISCONNECT); | ||
565 | if (ACPI_FAILURE(status)) { | 569 | if (ACPI_FAILURE(status)) { |
566 | ACPI_EXCEPTION((AE_INFO, status, | 570 | ACPI_EXCEPTION((AE_INFO, status, |
567 | "from region _REG, [%s]", | 571 | "from region _REG, [%s]", |
@@ -1062,6 +1066,12 @@ acpi_ev_execute_reg_methods(struct acpi_namespace_node *node, | |||
1062 | ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run, | 1066 | ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run, |
1063 | NULL, &space_id, NULL); | 1067 | NULL, &space_id, NULL); |
1064 | 1068 | ||
1069 | /* Special case for EC: handle "orphan" _REG methods with no region */ | ||
1070 | |||
1071 | if (space_id == ACPI_ADR_SPACE_EC) { | ||
1072 | acpi_ev_orphan_ec_reg_method(); | ||
1073 | } | ||
1074 | |||
1065 | return_ACPI_STATUS(status); | 1075 | return_ACPI_STATUS(status); |
1066 | } | 1076 | } |
1067 | 1077 | ||
@@ -1120,6 +1130,113 @@ acpi_ev_reg_run(acpi_handle obj_handle, | |||
1120 | return (AE_OK); | 1130 | return (AE_OK); |
1121 | } | 1131 | } |
1122 | 1132 | ||
1123 | status = acpi_ev_execute_reg_method(obj_desc, 1); | 1133 | status = acpi_ev_execute_reg_method(obj_desc, ACPI_REG_CONNECT); |
1124 | return (status); | 1134 | return (status); |
1125 | } | 1135 | } |
1136 | |||
1137 | /******************************************************************************* | ||
1138 | * | ||
1139 | * FUNCTION: acpi_ev_orphan_ec_reg_method | ||
1140 | * | ||
1141 | * PARAMETERS: None | ||
1142 | * | ||
1143 | * RETURN: None | ||
1144 | * | ||
1145 | * DESCRIPTION: Execute an "orphan" _REG method that appears under the EC | ||
1146 | * device. This is a _REG method that has no corresponding region | ||
1147 | * within the EC device scope. The orphan _REG method appears to | ||
1148 | * have been enabled by the description of the ECDT in the ACPI | ||
1149 | * specification: "The availability of the region space can be | ||
1150 | * detected by providing a _REG method object underneath the | ||
1151 | * Embedded Controller device." | ||
1152 | * | ||
1153 | * To quickly access the EC device, we use the EC_ID that appears | ||
1154 | * within the ECDT. Otherwise, we would need to perform a time- | ||
1155 | * consuming namespace walk, executing _HID methods to find the | ||
1156 | * EC device. | ||
1157 | * | ||
1158 | ******************************************************************************/ | ||
1159 | |||
1160 | static void acpi_ev_orphan_ec_reg_method(void) | ||
1161 | { | ||
1162 | struct acpi_table_ecdt *table; | ||
1163 | acpi_status status; | ||
1164 | struct acpi_object_list args; | ||
1165 | union acpi_object objects[2]; | ||
1166 | struct acpi_namespace_node *ec_device_node; | ||
1167 | struct acpi_namespace_node *reg_method; | ||
1168 | struct acpi_namespace_node *next_node; | ||
1169 | |||
1170 | ACPI_FUNCTION_TRACE(ev_orphan_ec_reg_method); | ||
1171 | |||
1172 | /* Get the ECDT (if present in system) */ | ||
1173 | |||
1174 | status = acpi_get_table(ACPI_SIG_ECDT, 0, | ||
1175 | ACPI_CAST_INDIRECT_PTR(struct acpi_table_header, | ||
1176 | &table)); | ||
1177 | if (ACPI_FAILURE(status)) { | ||
1178 | return_VOID; | ||
1179 | } | ||
1180 | |||
1181 | /* We need a valid EC_ID string */ | ||
1182 | |||
1183 | if (!(*table->id)) { | ||
1184 | return_VOID; | ||
1185 | } | ||
1186 | |||
1187 | /* Namespace is currently locked, must release */ | ||
1188 | |||
1189 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
1190 | |||
1191 | /* Get a handle to the EC device referenced in the ECDT */ | ||
1192 | |||
1193 | status = acpi_get_handle(NULL, | ||
1194 | ACPI_CAST_PTR(char, table->id), | ||
1195 | ACPI_CAST_PTR(acpi_handle, &ec_device_node)); | ||
1196 | if (ACPI_FAILURE(status)) { | ||
1197 | goto exit; | ||
1198 | } | ||
1199 | |||
1200 | /* Get a handle to a _REG method immediately under the EC device */ | ||
1201 | |||
1202 | status = acpi_get_handle(ec_device_node, | ||
1203 | METHOD_NAME__REG, ACPI_CAST_PTR(acpi_handle, | ||
1204 | ®_method)); | ||
1205 | if (ACPI_FAILURE(status)) { | ||
1206 | goto exit; | ||
1207 | } | ||
1208 | |||
1209 | /* | ||
1210 | * Execute the _REG method only if there is no Operation Region in | ||
1211 | * this scope with the Embedded Controller space ID. Otherwise, it | ||
1212 | * will already have been executed. Note, this allows for Regions | ||
1213 | * with other space IDs to be present; but the code below will then | ||
1214 | * execute the _REG method with the EC space ID argument. | ||
1215 | */ | ||
1216 | next_node = acpi_ns_get_next_node(ec_device_node, NULL); | ||
1217 | while (next_node) { | ||
1218 | if ((next_node->type == ACPI_TYPE_REGION) && | ||
1219 | (next_node->object) && | ||
1220 | (next_node->object->region.space_id == ACPI_ADR_SPACE_EC)) { | ||
1221 | goto exit; /* Do not execute _REG */ | ||
1222 | } | ||
1223 | next_node = acpi_ns_get_next_node(ec_device_node, next_node); | ||
1224 | } | ||
1225 | |||
1226 | /* Evaluate the _REG(EC,Connect) method */ | ||
1227 | |||
1228 | args.count = 2; | ||
1229 | args.pointer = objects; | ||
1230 | objects[0].type = ACPI_TYPE_INTEGER; | ||
1231 | objects[0].integer.value = ACPI_ADR_SPACE_EC; | ||
1232 | objects[1].type = ACPI_TYPE_INTEGER; | ||
1233 | objects[1].integer.value = ACPI_REG_CONNECT; | ||
1234 | |||
1235 | status = acpi_evaluate_object(reg_method, NULL, &args, NULL); | ||
1236 | |||
1237 | exit: | ||
1238 | /* We ignore all errors from above, don't care */ | ||
1239 | |||
1240 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
1241 | return_VOID; | ||
1242 | } | ||
diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c index 9659cee6093e..55a5d35ef34a 100644 --- a/drivers/acpi/acpica/evrgnini.c +++ b/drivers/acpi/acpica/evrgnini.c | |||
@@ -637,7 +637,7 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj, | |||
637 | 637 | ||
638 | status = | 638 | status = |
639 | acpi_ev_execute_reg_method | 639 | acpi_ev_execute_reg_method |
640 | (region_obj, 1); | 640 | (region_obj, ACPI_REG_CONNECT); |
641 | 641 | ||
642 | if (acpi_ns_locked) { | 642 | if (acpi_ns_locked) { |
643 | status = | 643 | status = |
diff --git a/drivers/acpi/acpica/evxfregn.c b/drivers/acpi/acpica/evxfregn.c index c85c8c45599d..00cd95692a91 100644 --- a/drivers/acpi/acpica/evxfregn.c +++ b/drivers/acpi/acpica/evxfregn.c | |||
@@ -130,20 +130,21 @@ acpi_install_address_space_handler(acpi_handle device, | |||
130 | case ACPI_ADR_SPACE_PCI_CONFIG: | 130 | case ACPI_ADR_SPACE_PCI_CONFIG: |
131 | case ACPI_ADR_SPACE_DATA_TABLE: | 131 | case ACPI_ADR_SPACE_DATA_TABLE: |
132 | 132 | ||
133 | if (acpi_gbl_reg_methods_executed) { | 133 | if (!acpi_gbl_reg_methods_executed) { |
134 | 134 | ||
135 | /* Run all _REG methods for this address space */ | 135 | /* We will defer execution of the _REG methods for this space */ |
136 | 136 | goto unlock_and_exit; | |
137 | status = acpi_ev_execute_reg_methods(node, space_id); | ||
138 | } | 137 | } |
139 | break; | 138 | break; |
140 | 139 | ||
141 | default: | 140 | default: |
142 | |||
143 | status = acpi_ev_execute_reg_methods(node, space_id); | ||
144 | break; | 141 | break; |
145 | } | 142 | } |
146 | 143 | ||
144 | /* Run all _REG methods for this address space */ | ||
145 | |||
146 | status = acpi_ev_execute_reg_methods(node, space_id); | ||
147 | |||
147 | unlock_and_exit: | 148 | unlock_and_exit: |
148 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 149 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
149 | return_ACPI_STATUS(status); | 150 | return_ACPI_STATUS(status); |
diff --git a/drivers/acpi/acpica/excreate.c b/drivers/acpi/acpica/excreate.c index e7b372d17667..110711afada8 100644 --- a/drivers/acpi/acpica/excreate.c +++ b/drivers/acpi/acpica/excreate.c | |||
@@ -305,7 +305,8 @@ acpi_ex_create_region(u8 * aml_start, | |||
305 | * range | 305 | * range |
306 | */ | 306 | */ |
307 | if ((region_space >= ACPI_NUM_PREDEFINED_REGIONS) && | 307 | if ((region_space >= ACPI_NUM_PREDEFINED_REGIONS) && |
308 | (region_space < ACPI_USER_REGION_BEGIN)) { | 308 | (region_space < ACPI_USER_REGION_BEGIN) && |
309 | (region_space != ACPI_ADR_SPACE_DATA_TABLE)) { | ||
309 | ACPI_ERROR((AE_INFO, "Invalid AddressSpace type 0x%X", | 310 | ACPI_ERROR((AE_INFO, "Invalid AddressSpace type 0x%X", |
310 | region_space)); | 311 | region_space)); |
311 | return_ACPI_STATUS(AE_AML_INVALID_SPACE_ID); | 312 | return_ACPI_STATUS(AE_AML_INVALID_SPACE_ID); |
diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c index 1d76ac85b5e7..ac7b854b0bd7 100644 --- a/drivers/acpi/acpica/nsrepair.c +++ b/drivers/acpi/acpica/nsrepair.c | |||
@@ -74,7 +74,6 @@ ACPI_MODULE_NAME("nsrepair") | |||
74 | * | 74 | * |
75 | * Additional possible repairs: | 75 | * Additional possible repairs: |
76 | * | 76 | * |
77 | * Optional/unnecessary NULL package elements removed | ||
78 | * Required package elements that are NULL replaced by Integer/String/Buffer | 77 | * Required package elements that are NULL replaced by Integer/String/Buffer |
79 | * Incorrect standalone package wrapped with required outer package | 78 | * Incorrect standalone package wrapped with required outer package |
80 | * | 79 | * |
@@ -623,16 +622,12 @@ acpi_ns_remove_null_elements(struct acpi_predefined_data *data, | |||
623 | ACPI_FUNCTION_NAME(ns_remove_null_elements); | 622 | ACPI_FUNCTION_NAME(ns_remove_null_elements); |
624 | 623 | ||
625 | /* | 624 | /* |
626 | * PTYPE1 packages contain no subpackages. | 625 | * We can safely remove all NULL elements from these package types: |
627 | * PTYPE2 packages contain a variable number of sub-packages. We can | 626 | * PTYPE1_VAR packages contain a variable number of simple data types. |
628 | * safely remove all NULL elements from the PTYPE2 packages. | 627 | * PTYPE2 packages contain a variable number of sub-packages. |
629 | */ | 628 | */ |
630 | switch (package_type) { | 629 | switch (package_type) { |
631 | case ACPI_PTYPE1_FIXED: | ||
632 | case ACPI_PTYPE1_VAR: | 630 | case ACPI_PTYPE1_VAR: |
633 | case ACPI_PTYPE1_OPTION: | ||
634 | return; | ||
635 | |||
636 | case ACPI_PTYPE2: | 631 | case ACPI_PTYPE2: |
637 | case ACPI_PTYPE2_COUNT: | 632 | case ACPI_PTYPE2_COUNT: |
638 | case ACPI_PTYPE2_PKG_COUNT: | 633 | case ACPI_PTYPE2_PKG_COUNT: |
@@ -642,6 +637,8 @@ acpi_ns_remove_null_elements(struct acpi_predefined_data *data, | |||
642 | break; | 637 | break; |
643 | 638 | ||
644 | default: | 639 | default: |
640 | case ACPI_PTYPE1_FIXED: | ||
641 | case ACPI_PTYPE1_OPTION: | ||
645 | return; | 642 | return; |
646 | } | 643 | } |
647 | 644 | ||
diff --git a/drivers/acpi/acpica/utdecode.c b/drivers/acpi/acpica/utdecode.c index 136a814cec69..97cb36f85ce9 100644 --- a/drivers/acpi/acpica/utdecode.c +++ b/drivers/acpi/acpica/utdecode.c | |||
@@ -170,8 +170,7 @@ const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS] = { | |||
170 | "SMBus", | 170 | "SMBus", |
171 | "SystemCMOS", | 171 | "SystemCMOS", |
172 | "PCIBARTarget", | 172 | "PCIBARTarget", |
173 | "IPMI", | 173 | "IPMI" |
174 | "DataTable" | ||
175 | }; | 174 | }; |
176 | 175 | ||
177 | char *acpi_ut_get_region_name(u8 space_id) | 176 | char *acpi_ut_get_region_name(u8 space_id) |
@@ -179,6 +178,8 @@ char *acpi_ut_get_region_name(u8 space_id) | |||
179 | 178 | ||
180 | if (space_id >= ACPI_USER_REGION_BEGIN) { | 179 | if (space_id >= ACPI_USER_REGION_BEGIN) { |
181 | return ("UserDefinedRegion"); | 180 | return ("UserDefinedRegion"); |
181 | } else if (space_id == ACPI_ADR_SPACE_DATA_TABLE) { | ||
182 | return ("DataTable"); | ||
182 | } else if (space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) { | 183 | } else if (space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) { |
183 | return ("FunctionalFixedHW"); | 184 | return ("FunctionalFixedHW"); |
184 | } else if (space_id >= ACPI_NUM_PREDEFINED_REGIONS) { | 185 | } else if (space_id >= ACPI_NUM_PREDEFINED_REGIONS) { |
diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c index a946c689f03b..7d797e2baecd 100644 --- a/drivers/acpi/acpica/utmutex.c +++ b/drivers/acpi/acpica/utmutex.c | |||
@@ -83,9 +83,15 @@ acpi_status acpi_ut_mutex_initialize(void) | |||
83 | 83 | ||
84 | /* Create the spinlocks for use at interrupt level */ | 84 | /* Create the spinlocks for use at interrupt level */ |
85 | 85 | ||
86 | spin_lock_init(acpi_gbl_gpe_lock); | 86 | status = acpi_os_create_lock (&acpi_gbl_gpe_lock); |
87 | spin_lock_init(acpi_gbl_hardware_lock); | 87 | if (ACPI_FAILURE (status)) { |
88 | spin_lock_init(acpi_ev_global_lock_pending_lock); | 88 | return_ACPI_STATUS (status); |
89 | } | ||
90 | |||
91 | status = acpi_os_create_lock (&acpi_gbl_hardware_lock); | ||
92 | if (ACPI_FAILURE (status)) { | ||
93 | return_ACPI_STATUS (status); | ||
94 | } | ||
89 | 95 | ||
90 | /* Mutex for _OSI support */ | 96 | /* Mutex for _OSI support */ |
91 | status = acpi_os_create_mutex(&acpi_gbl_osi_mutex); | 97 | status = acpi_os_create_mutex(&acpi_gbl_osi_mutex); |
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 9749980ca6ca..d1e06c182cdb 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -227,7 +227,7 @@ static int __acpi_bus_set_power(struct acpi_device *device, int state) | |||
227 | acpi_status status = AE_OK; | 227 | acpi_status status = AE_OK; |
228 | char object_name[5] = { '_', 'P', 'S', '0' + state, '\0' }; | 228 | char object_name[5] = { '_', 'P', 'S', '0' + state, '\0' }; |
229 | 229 | ||
230 | if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3)) | 230 | if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD)) |
231 | return -EINVAL; | 231 | return -EINVAL; |
232 | 232 | ||
233 | /* Make sure this is a valid target state */ | 233 | /* Make sure this is a valid target state */ |
diff --git a/drivers/acpi/custom_method.c b/drivers/acpi/custom_method.c new file mode 100644 index 000000000000..5d42c2414ae5 --- /dev/null +++ b/drivers/acpi/custom_method.c | |||
@@ -0,0 +1,100 @@ | |||
1 | /* | ||
2 | * debugfs.c - ACPI debugfs interface to userspace. | ||
3 | */ | ||
4 | |||
5 | #include <linux/init.h> | ||
6 | #include <linux/module.h> | ||
7 | #include <linux/kernel.h> | ||
8 | #include <linux/uaccess.h> | ||
9 | #include <linux/debugfs.h> | ||
10 | #include <acpi/acpi_drivers.h> | ||
11 | |||
12 | #include "internal.h" | ||
13 | |||
14 | #define _COMPONENT ACPI_SYSTEM_COMPONENT | ||
15 | ACPI_MODULE_NAME("custom_method"); | ||
16 | MODULE_LICENSE("GPL"); | ||
17 | |||
18 | static struct dentry *cm_dentry; | ||
19 | |||
20 | /* /sys/kernel/debug/acpi/custom_method */ | ||
21 | |||
22 | static ssize_t cm_write(struct file *file, const char __user * user_buf, | ||
23 | size_t count, loff_t *ppos) | ||
24 | { | ||
25 | static char *buf; | ||
26 | static u32 max_size; | ||
27 | static u32 uncopied_bytes; | ||
28 | |||
29 | struct acpi_table_header table; | ||
30 | acpi_status status; | ||
31 | |||
32 | if (!(*ppos)) { | ||
33 | /* parse the table header to get the table length */ | ||
34 | if (count <= sizeof(struct acpi_table_header)) | ||
35 | return -EINVAL; | ||
36 | if (copy_from_user(&table, user_buf, | ||
37 | sizeof(struct acpi_table_header))) | ||
38 | return -EFAULT; | ||
39 | uncopied_bytes = max_size = table.length; | ||
40 | buf = kzalloc(max_size, GFP_KERNEL); | ||
41 | if (!buf) | ||
42 | return -ENOMEM; | ||
43 | } | ||
44 | |||
45 | if (buf == NULL) | ||
46 | return -EINVAL; | ||
47 | |||
48 | if ((*ppos > max_size) || | ||
49 | (*ppos + count > max_size) || | ||
50 | (*ppos + count < count) || | ||
51 | (count > uncopied_bytes)) | ||
52 | return -EINVAL; | ||
53 | |||
54 | if (copy_from_user(buf + (*ppos), user_buf, count)) { | ||
55 | kfree(buf); | ||
56 | buf = NULL; | ||
57 | return -EFAULT; | ||
58 | } | ||
59 | |||
60 | uncopied_bytes -= count; | ||
61 | *ppos += count; | ||
62 | |||
63 | if (!uncopied_bytes) { | ||
64 | status = acpi_install_method(buf); | ||
65 | kfree(buf); | ||
66 | buf = NULL; | ||
67 | if (ACPI_FAILURE(status)) | ||
68 | return -EINVAL; | ||
69 | add_taint(TAINT_OVERRIDDEN_ACPI_TABLE); | ||
70 | } | ||
71 | |||
72 | return count; | ||
73 | } | ||
74 | |||
75 | static const struct file_operations cm_fops = { | ||
76 | .write = cm_write, | ||
77 | .llseek = default_llseek, | ||
78 | }; | ||
79 | |||
80 | static int __init acpi_custom_method_init(void) | ||
81 | { | ||
82 | if (acpi_debugfs_dir == NULL) | ||
83 | return -ENOENT; | ||
84 | |||
85 | cm_dentry = debugfs_create_file("custom_method", S_IWUSR, | ||
86 | acpi_debugfs_dir, NULL, &cm_fops); | ||
87 | if (cm_dentry == NULL) | ||
88 | return -ENODEV; | ||
89 | |||
90 | return 0; | ||
91 | } | ||
92 | |||
93 | static void __exit acpi_custom_method_exit(void) | ||
94 | { | ||
95 | if (cm_dentry) | ||
96 | debugfs_remove(cm_dentry); | ||
97 | } | ||
98 | |||
99 | module_init(acpi_custom_method_init); | ||
100 | module_exit(acpi_custom_method_exit); | ||
diff --git a/drivers/acpi/debugfs.c b/drivers/acpi/debugfs.c index 384f7abcff77..182a9fc36355 100644 --- a/drivers/acpi/debugfs.c +++ b/drivers/acpi/debugfs.c | |||
@@ -3,100 +3,16 @@ | |||
3 | */ | 3 | */ |
4 | 4 | ||
5 | #include <linux/init.h> | 5 | #include <linux/init.h> |
6 | #include <linux/module.h> | ||
7 | #include <linux/kernel.h> | ||
8 | #include <linux/uaccess.h> | ||
9 | #include <linux/debugfs.h> | 6 | #include <linux/debugfs.h> |
10 | #include <acpi/acpi_drivers.h> | 7 | #include <acpi/acpi_drivers.h> |
11 | 8 | ||
12 | #define _COMPONENT ACPI_SYSTEM_COMPONENT | 9 | #define _COMPONENT ACPI_SYSTEM_COMPONENT |
13 | ACPI_MODULE_NAME("debugfs"); | 10 | ACPI_MODULE_NAME("debugfs"); |
14 | 11 | ||
12 | struct dentry *acpi_debugfs_dir; | ||
13 | EXPORT_SYMBOL_GPL(acpi_debugfs_dir); | ||
15 | 14 | ||
16 | /* /sys/modules/acpi/parameters/aml_debug_output */ | 15 | void __init acpi_debugfs_init(void) |
17 | |||
18 | module_param_named(aml_debug_output, acpi_gbl_enable_aml_debug_object, | ||
19 | bool, 0644); | ||
20 | MODULE_PARM_DESC(aml_debug_output, | ||
21 | "To enable/disable the ACPI Debug Object output."); | ||
22 | |||
23 | /* /sys/kernel/debug/acpi/custom_method */ | ||
24 | |||
25 | static ssize_t cm_write(struct file *file, const char __user * user_buf, | ||
26 | size_t count, loff_t *ppos) | ||
27 | { | 16 | { |
28 | static char *buf; | 17 | acpi_debugfs_dir = debugfs_create_dir("acpi", NULL); |
29 | static u32 max_size; | ||
30 | static u32 uncopied_bytes; | ||
31 | |||
32 | struct acpi_table_header table; | ||
33 | acpi_status status; | ||
34 | |||
35 | if (!(*ppos)) { | ||
36 | /* parse the table header to get the table length */ | ||
37 | if (count <= sizeof(struct acpi_table_header)) | ||
38 | return -EINVAL; | ||
39 | if (copy_from_user(&table, user_buf, | ||
40 | sizeof(struct acpi_table_header))) | ||
41 | return -EFAULT; | ||
42 | uncopied_bytes = max_size = table.length; | ||
43 | buf = kzalloc(max_size, GFP_KERNEL); | ||
44 | if (!buf) | ||
45 | return -ENOMEM; | ||
46 | } | ||
47 | |||
48 | if (buf == NULL) | ||
49 | return -EINVAL; | ||
50 | |||
51 | if ((*ppos > max_size) || | ||
52 | (*ppos + count > max_size) || | ||
53 | (*ppos + count < count) || | ||
54 | (count > uncopied_bytes)) | ||
55 | return -EINVAL; | ||
56 | |||
57 | if (copy_from_user(buf + (*ppos), user_buf, count)) { | ||
58 | kfree(buf); | ||
59 | buf = NULL; | ||
60 | return -EFAULT; | ||
61 | } | ||
62 | |||
63 | uncopied_bytes -= count; | ||
64 | *ppos += count; | ||
65 | |||
66 | if (!uncopied_bytes) { | ||
67 | status = acpi_install_method(buf); | ||
68 | kfree(buf); | ||
69 | buf = NULL; | ||
70 | if (ACPI_FAILURE(status)) | ||
71 | return -EINVAL; | ||
72 | add_taint(TAINT_OVERRIDDEN_ACPI_TABLE); | ||
73 | } | ||
74 | |||
75 | return count; | ||
76 | } | ||
77 | |||
78 | static const struct file_operations cm_fops = { | ||
79 | .write = cm_write, | ||
80 | .llseek = default_llseek, | ||
81 | }; | ||
82 | |||
83 | int __init acpi_debugfs_init(void) | ||
84 | { | ||
85 | struct dentry *acpi_dir, *cm_dentry; | ||
86 | |||
87 | acpi_dir = debugfs_create_dir("acpi", NULL); | ||
88 | if (!acpi_dir) | ||
89 | goto err; | ||
90 | |||
91 | cm_dentry = debugfs_create_file("custom_method", S_IWUSR, | ||
92 | acpi_dir, NULL, &cm_fops); | ||
93 | if (!cm_dentry) | ||
94 | goto err; | ||
95 | |||
96 | return 0; | ||
97 | |||
98 | err: | ||
99 | if (acpi_dir) | ||
100 | debugfs_remove(acpi_dir); | ||
101 | return -EINVAL; | ||
102 | } | 18 | } |
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index fa848c4116a8..b19a18dd994f 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -69,7 +69,6 @@ enum ec_command { | |||
69 | 69 | ||
70 | #define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ | 70 | #define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ |
71 | #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ | 71 | #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ |
72 | #define ACPI_EC_CDELAY 10 /* Wait 10us before polling EC */ | ||
73 | #define ACPI_EC_MSI_UDELAY 550 /* Wait 550us for MSI EC */ | 72 | #define ACPI_EC_MSI_UDELAY 550 /* Wait 550us for MSI EC */ |
74 | 73 | ||
75 | #define ACPI_EC_STORM_THRESHOLD 8 /* number of false interrupts | 74 | #define ACPI_EC_STORM_THRESHOLD 8 /* number of false interrupts |
@@ -433,8 +432,7 @@ EXPORT_SYMBOL(ec_write); | |||
433 | 432 | ||
434 | int ec_transaction(u8 command, | 433 | int ec_transaction(u8 command, |
435 | const u8 * wdata, unsigned wdata_len, | 434 | const u8 * wdata, unsigned wdata_len, |
436 | u8 * rdata, unsigned rdata_len, | 435 | u8 * rdata, unsigned rdata_len) |
437 | int force_poll) | ||
438 | { | 436 | { |
439 | struct transaction t = {.command = command, | 437 | struct transaction t = {.command = command, |
440 | .wdata = wdata, .rdata = rdata, | 438 | .wdata = wdata, .rdata = rdata, |
@@ -592,8 +590,6 @@ static void acpi_ec_gpe_query(void *ec_cxt) | |||
592 | mutex_unlock(&ec->lock); | 590 | mutex_unlock(&ec->lock); |
593 | } | 591 | } |
594 | 592 | ||
595 | static void acpi_ec_gpe_query(void *ec_cxt); | ||
596 | |||
597 | static int ec_check_sci(struct acpi_ec *ec, u8 state) | 593 | static int ec_check_sci(struct acpi_ec *ec, u8 state) |
598 | { | 594 | { |
599 | if (state & ACPI_EC_FLAG_SCI) { | 595 | if (state & ACPI_EC_FLAG_SCI) { |
@@ -808,8 +804,6 @@ static int acpi_ec_add(struct acpi_device *device) | |||
808 | return -EINVAL; | 804 | return -EINVAL; |
809 | } | 805 | } |
810 | 806 | ||
811 | ec->handle = device->handle; | ||
812 | |||
813 | /* Find and register all query methods */ | 807 | /* Find and register all query methods */ |
814 | acpi_walk_namespace(ACPI_TYPE_METHOD, ec->handle, 1, | 808 | acpi_walk_namespace(ACPI_TYPE_METHOD, ec->handle, 1, |
815 | acpi_ec_register_query_methods, NULL, ec, NULL); | 809 | acpi_ec_register_query_methods, NULL, ec, NULL); |
@@ -938,8 +932,19 @@ static struct dmi_system_id __initdata ec_dmi_table[] = { | |||
938 | ec_flag_msi, "MSI hardware", { | 932 | ec_flag_msi, "MSI hardware", { |
939 | DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR")}, NULL}, | 933 | DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR")}, NULL}, |
940 | { | 934 | { |
935 | ec_flag_msi, "Quanta hardware", { | ||
936 | DMI_MATCH(DMI_SYS_VENDOR, "Quanta"), | ||
937 | DMI_MATCH(DMI_PRODUCT_NAME, "TW8/SW8/DW8"),}, NULL}, | ||
938 | { | ||
939 | ec_flag_msi, "Quanta hardware", { | ||
940 | DMI_MATCH(DMI_SYS_VENDOR, "Quanta"), | ||
941 | DMI_MATCH(DMI_PRODUCT_NAME, "TW9/SW9"),}, NULL}, | ||
942 | { | ||
941 | ec_validate_ecdt, "ASUS hardware", { | 943 | ec_validate_ecdt, "ASUS hardware", { |
942 | DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL}, | 944 | DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL}, |
945 | { | ||
946 | ec_validate_ecdt, "ASUS hardware", { | ||
947 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc.") }, NULL}, | ||
943 | {}, | 948 | {}, |
944 | }; | 949 | }; |
945 | 950 | ||
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 4bfb759deb10..ca75b9ce0489 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h | |||
@@ -28,9 +28,10 @@ int acpi_scan_init(void); | |||
28 | int acpi_sysfs_init(void); | 28 | int acpi_sysfs_init(void); |
29 | 29 | ||
30 | #ifdef CONFIG_DEBUG_FS | 30 | #ifdef CONFIG_DEBUG_FS |
31 | extern struct dentry *acpi_debugfs_dir; | ||
31 | int acpi_debugfs_init(void); | 32 | int acpi_debugfs_init(void); |
32 | #else | 33 | #else |
33 | static inline int acpi_debugfs_init(void) { return 0; } | 34 | static inline void acpi_debugfs_init(void) { return; } |
34 | #endif | 35 | #endif |
35 | 36 | ||
36 | /* -------------------------------------------------------------------------- | 37 | /* -------------------------------------------------------------------------- |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 45ad4ffef533..52ca9649d769 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -902,14 +902,6 @@ void acpi_os_wait_events_complete(void *context) | |||
902 | 902 | ||
903 | EXPORT_SYMBOL(acpi_os_wait_events_complete); | 903 | EXPORT_SYMBOL(acpi_os_wait_events_complete); |
904 | 904 | ||
905 | /* | ||
906 | * Deallocate the memory for a spinlock. | ||
907 | */ | ||
908 | void acpi_os_delete_lock(acpi_spinlock handle) | ||
909 | { | ||
910 | return; | ||
911 | } | ||
912 | |||
913 | acpi_status | 905 | acpi_status |
914 | acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle * handle) | 906 | acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle * handle) |
915 | { | 907 | { |
@@ -1341,6 +1333,31 @@ int acpi_resources_are_enforced(void) | |||
1341 | EXPORT_SYMBOL(acpi_resources_are_enforced); | 1333 | EXPORT_SYMBOL(acpi_resources_are_enforced); |
1342 | 1334 | ||
1343 | /* | 1335 | /* |
1336 | * Create and initialize a spinlock. | ||
1337 | */ | ||
1338 | acpi_status | ||
1339 | acpi_os_create_lock(acpi_spinlock *out_handle) | ||
1340 | { | ||
1341 | spinlock_t *lock; | ||
1342 | |||
1343 | lock = ACPI_ALLOCATE(sizeof(spinlock_t)); | ||
1344 | if (!lock) | ||
1345 | return AE_NO_MEMORY; | ||
1346 | spin_lock_init(lock); | ||
1347 | *out_handle = lock; | ||
1348 | |||
1349 | return AE_OK; | ||
1350 | } | ||
1351 | |||
1352 | /* | ||
1353 | * Deallocate the memory for a spinlock. | ||
1354 | */ | ||
1355 | void acpi_os_delete_lock(acpi_spinlock handle) | ||
1356 | { | ||
1357 | ACPI_FREE(handle); | ||
1358 | } | ||
1359 | |||
1360 | /* | ||
1344 | * Acquire a spinlock. | 1361 | * Acquire a spinlock. |
1345 | * | 1362 | * |
1346 | * handle is a pointer to the spinlock_t. | 1363 | * handle is a pointer to the spinlock_t. |
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 25bf17da69fd..02d2a4c9084d 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -37,7 +37,6 @@ static struct dmi_system_id __initdata processor_idle_dmi_table[] = { | |||
37 | {}, | 37 | {}, |
38 | }; | 38 | }; |
39 | 39 | ||
40 | #ifdef CONFIG_SMP | ||
41 | static int map_lapic_id(struct acpi_subtable_header *entry, | 40 | static int map_lapic_id(struct acpi_subtable_header *entry, |
42 | u32 acpi_id, int *apic_id) | 41 | u32 acpi_id, int *apic_id) |
43 | { | 42 | { |
@@ -165,7 +164,9 @@ exit: | |||
165 | 164 | ||
166 | int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) | 165 | int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) |
167 | { | 166 | { |
167 | #ifdef CONFIG_SMP | ||
168 | int i; | 168 | int i; |
169 | #endif | ||
169 | int apic_id = -1; | 170 | int apic_id = -1; |
170 | 171 | ||
171 | apic_id = map_mat_entry(handle, type, acpi_id); | 172 | apic_id = map_mat_entry(handle, type, acpi_id); |
@@ -174,14 +175,19 @@ int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) | |||
174 | if (apic_id == -1) | 175 | if (apic_id == -1) |
175 | return apic_id; | 176 | return apic_id; |
176 | 177 | ||
178 | #ifdef CONFIG_SMP | ||
177 | for_each_possible_cpu(i) { | 179 | for_each_possible_cpu(i) { |
178 | if (cpu_physical_id(i) == apic_id) | 180 | if (cpu_physical_id(i) == apic_id) |
179 | return i; | 181 | return i; |
180 | } | 182 | } |
183 | #else | ||
184 | /* In UP kernel, only processor 0 is valid */ | ||
185 | if (apic_id == 0) | ||
186 | return apic_id; | ||
187 | #endif | ||
181 | return -1; | 188 | return -1; |
182 | } | 189 | } |
183 | EXPORT_SYMBOL_GPL(acpi_get_cpuid); | 190 | EXPORT_SYMBOL_GPL(acpi_get_cpuid); |
184 | #endif | ||
185 | 191 | ||
186 | static bool __init processor_physically_present(acpi_handle handle) | 192 | static bool __init processor_physically_present(acpi_handle handle) |
187 | { | 193 | { |
@@ -217,7 +223,7 @@ static bool __init processor_physically_present(acpi_handle handle) | |||
217 | type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0; | 223 | type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0; |
218 | cpuid = acpi_get_cpuid(handle, type, acpi_id); | 224 | cpuid = acpi_get_cpuid(handle, type, acpi_id); |
219 | 225 | ||
220 | if ((cpuid == -1) && (num_possible_cpus() > 1)) | 226 | if (cpuid == -1) |
221 | return false; | 227 | return false; |
222 | 228 | ||
223 | return true; | 229 | return true; |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index d615b7d69bca..431ab11c8c1b 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -161,7 +161,7 @@ static void lapic_timer_check_state(int state, struct acpi_processor *pr, | |||
161 | if (cpu_has(&cpu_data(pr->id), X86_FEATURE_ARAT)) | 161 | if (cpu_has(&cpu_data(pr->id), X86_FEATURE_ARAT)) |
162 | return; | 162 | return; |
163 | 163 | ||
164 | if (c1e_detected) | 164 | if (amd_e400_c1e_detected) |
165 | type = ACPI_STATE_C1; | 165 | type = ACPI_STATE_C1; |
166 | 166 | ||
167 | /* | 167 | /* |
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 61891e75583d..77255f250dbb 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c | |||
@@ -220,6 +220,14 @@ module_param_call(trace_state, param_set_trace_state, param_get_trace_state, | |||
220 | NULL, 0644); | 220 | NULL, 0644); |
221 | #endif /* CONFIG_ACPI_DEBUG */ | 221 | #endif /* CONFIG_ACPI_DEBUG */ |
222 | 222 | ||
223 | |||
224 | /* /sys/modules/acpi/parameters/aml_debug_output */ | ||
225 | |||
226 | module_param_named(aml_debug_output, acpi_gbl_enable_aml_debug_object, | ||
227 | bool, 0644); | ||
228 | MODULE_PARM_DESC(aml_debug_output, | ||
229 | "To enable/disable the ACPI Debug Object output."); | ||
230 | |||
223 | /* /sys/module/acpi/parameters/acpica_version */ | 231 | /* /sys/module/acpi/parameters/acpica_version */ |
224 | static int param_get_acpica_version(char *buffer, struct kernel_param *kp) | 232 | static int param_get_acpica_version(char *buffer, struct kernel_param *kp) |
225 | { | 233 | { |
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index db8f88586c8d..98de8f418676 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c | |||
@@ -1038,6 +1038,7 @@ static void floppy_disable_hlt(void) | |||
1038 | { | 1038 | { |
1039 | unsigned long flags; | 1039 | unsigned long flags; |
1040 | 1040 | ||
1041 | WARN_ONCE(1, "floppy_disable_hlt() scheduled for removal in 2012"); | ||
1041 | spin_lock_irqsave(&floppy_hlt_lock, flags); | 1042 | spin_lock_irqsave(&floppy_hlt_lock, flags); |
1042 | if (!hlt_disabled) { | 1043 | if (!hlt_disabled) { |
1043 | hlt_disabled = 1; | 1044 | hlt_disabled = 1; |
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index e6fc716aca45..f533f3375e24 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c | |||
@@ -192,7 +192,8 @@ static int sock_xmit(struct nbd_device *lo, int send, void *buf, int size, | |||
192 | if (lo->xmit_timeout) | 192 | if (lo->xmit_timeout) |
193 | del_timer_sync(&ti); | 193 | del_timer_sync(&ti); |
194 | } else | 194 | } else |
195 | result = kernel_recvmsg(sock, &msg, &iov, 1, size, 0); | 195 | result = kernel_recvmsg(sock, &msg, &iov, 1, size, |
196 | msg.msg_flags); | ||
196 | 197 | ||
197 | if (signal_pending(current)) { | 198 | if (signal_pending(current)) { |
198 | siginfo_t info; | 199 | siginfo_t info; |
@@ -753,9 +754,26 @@ static int __init nbd_init(void) | |||
753 | return -ENOMEM; | 754 | return -ENOMEM; |
754 | 755 | ||
755 | part_shift = 0; | 756 | part_shift = 0; |
756 | if (max_part > 0) | 757 | if (max_part > 0) { |
757 | part_shift = fls(max_part); | 758 | part_shift = fls(max_part); |
758 | 759 | ||
760 | /* | ||
761 | * Adjust max_part according to part_shift as it is exported | ||
762 | * to user space so that user can know the max number of | ||
763 | * partition kernel should be able to manage. | ||
764 | * | ||
765 | * Note that -1 is required because partition 0 is reserved | ||
766 | * for the whole disk. | ||
767 | */ | ||
768 | max_part = (1UL << part_shift) - 1; | ||
769 | } | ||
770 | |||
771 | if ((1UL << part_shift) > DISK_MAX_PARTS) | ||
772 | return -EINVAL; | ||
773 | |||
774 | if (nbds_max > 1UL << (MINORBITS - part_shift)) | ||
775 | return -EINVAL; | ||
776 | |||
759 | for (i = 0; i < nbds_max; i++) { | 777 | for (i = 0; i < nbds_max; i++) { |
760 | struct gendisk *disk = alloc_disk(1 << part_shift); | 778 | struct gendisk *disk = alloc_disk(1 << part_shift); |
761 | if (!disk) | 779 | if (!disk) |
diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c index a0aabd904a51..46b8136c31bb 100644 --- a/drivers/block/paride/pcd.c +++ b/drivers/block/paride/pcd.c | |||
@@ -321,7 +321,6 @@ static void pcd_init_units(void) | |||
321 | strcpy(disk->disk_name, cd->name); /* umm... */ | 321 | strcpy(disk->disk_name, cd->name); /* umm... */ |
322 | disk->fops = &pcd_bdops; | 322 | disk->fops = &pcd_bdops; |
323 | disk->flags = GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE; | 323 | disk->flags = GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE; |
324 | disk->events = DISK_EVENT_MEDIA_CHANGE; | ||
325 | } | 324 | } |
326 | } | 325 | } |
327 | 326 | ||
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 6ecf89cdf006..079c08808d8a 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c | |||
@@ -6,10 +6,13 @@ | |||
6 | #include <linux/virtio.h> | 6 | #include <linux/virtio.h> |
7 | #include <linux/virtio_blk.h> | 7 | #include <linux/virtio_blk.h> |
8 | #include <linux/scatterlist.h> | 8 | #include <linux/scatterlist.h> |
9 | #include <linux/string_helpers.h> | ||
10 | #include <scsi/scsi_cmnd.h> | ||
9 | 11 | ||
10 | #define PART_BITS 4 | 12 | #define PART_BITS 4 |
11 | 13 | ||
12 | static int major, index; | 14 | static int major, index; |
15 | struct workqueue_struct *virtblk_wq; | ||
13 | 16 | ||
14 | struct virtio_blk | 17 | struct virtio_blk |
15 | { | 18 | { |
@@ -26,6 +29,9 @@ struct virtio_blk | |||
26 | 29 | ||
27 | mempool_t *pool; | 30 | mempool_t *pool; |
28 | 31 | ||
32 | /* Process context for config space updates */ | ||
33 | struct work_struct config_work; | ||
34 | |||
29 | /* What host tells us, plus 2 for header & tailer. */ | 35 | /* What host tells us, plus 2 for header & tailer. */ |
30 | unsigned int sg_elems; | 36 | unsigned int sg_elems; |
31 | 37 | ||
@@ -141,7 +147,7 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk, | |||
141 | num = blk_rq_map_sg(q, vbr->req, vblk->sg + out); | 147 | num = blk_rq_map_sg(q, vbr->req, vblk->sg + out); |
142 | 148 | ||
143 | if (vbr->req->cmd_type == REQ_TYPE_BLOCK_PC) { | 149 | if (vbr->req->cmd_type == REQ_TYPE_BLOCK_PC) { |
144 | sg_set_buf(&vblk->sg[num + out + in++], vbr->req->sense, 96); | 150 | sg_set_buf(&vblk->sg[num + out + in++], vbr->req->sense, SCSI_SENSE_BUFFERSIZE); |
145 | sg_set_buf(&vblk->sg[num + out + in++], &vbr->in_hdr, | 151 | sg_set_buf(&vblk->sg[num + out + in++], &vbr->in_hdr, |
146 | sizeof(vbr->in_hdr)); | 152 | sizeof(vbr->in_hdr)); |
147 | } | 153 | } |
@@ -291,6 +297,46 @@ static ssize_t virtblk_serial_show(struct device *dev, | |||
291 | } | 297 | } |
292 | DEVICE_ATTR(serial, S_IRUGO, virtblk_serial_show, NULL); | 298 | DEVICE_ATTR(serial, S_IRUGO, virtblk_serial_show, NULL); |
293 | 299 | ||
300 | static void virtblk_config_changed_work(struct work_struct *work) | ||
301 | { | ||
302 | struct virtio_blk *vblk = | ||
303 | container_of(work, struct virtio_blk, config_work); | ||
304 | struct virtio_device *vdev = vblk->vdev; | ||
305 | struct request_queue *q = vblk->disk->queue; | ||
306 | char cap_str_2[10], cap_str_10[10]; | ||
307 | u64 capacity, size; | ||
308 | |||
309 | /* Host must always specify the capacity. */ | ||
310 | vdev->config->get(vdev, offsetof(struct virtio_blk_config, capacity), | ||
311 | &capacity, sizeof(capacity)); | ||
312 | |||
313 | /* If capacity is too big, truncate with warning. */ | ||
314 | if ((sector_t)capacity != capacity) { | ||
315 | dev_warn(&vdev->dev, "Capacity %llu too large: truncating\n", | ||
316 | (unsigned long long)capacity); | ||
317 | capacity = (sector_t)-1; | ||
318 | } | ||
319 | |||
320 | size = capacity * queue_logical_block_size(q); | ||
321 | string_get_size(size, STRING_UNITS_2, cap_str_2, sizeof(cap_str_2)); | ||
322 | string_get_size(size, STRING_UNITS_10, cap_str_10, sizeof(cap_str_10)); | ||
323 | |||
324 | dev_notice(&vdev->dev, | ||
325 | "new size: %llu %d-byte logical blocks (%s/%s)\n", | ||
326 | (unsigned long long)capacity, | ||
327 | queue_logical_block_size(q), | ||
328 | cap_str_10, cap_str_2); | ||
329 | |||
330 | set_capacity(vblk->disk, capacity); | ||
331 | } | ||
332 | |||
333 | static void virtblk_config_changed(struct virtio_device *vdev) | ||
334 | { | ||
335 | struct virtio_blk *vblk = vdev->priv; | ||
336 | |||
337 | queue_work(virtblk_wq, &vblk->config_work); | ||
338 | } | ||
339 | |||
294 | static int __devinit virtblk_probe(struct virtio_device *vdev) | 340 | static int __devinit virtblk_probe(struct virtio_device *vdev) |
295 | { | 341 | { |
296 | struct virtio_blk *vblk; | 342 | struct virtio_blk *vblk; |
@@ -327,6 +373,7 @@ static int __devinit virtblk_probe(struct virtio_device *vdev) | |||
327 | vblk->vdev = vdev; | 373 | vblk->vdev = vdev; |
328 | vblk->sg_elems = sg_elems; | 374 | vblk->sg_elems = sg_elems; |
329 | sg_init_table(vblk->sg, vblk->sg_elems); | 375 | sg_init_table(vblk->sg, vblk->sg_elems); |
376 | INIT_WORK(&vblk->config_work, virtblk_config_changed_work); | ||
330 | 377 | ||
331 | /* We expect one virtqueue, for output. */ | 378 | /* We expect one virtqueue, for output. */ |
332 | vblk->vq = virtio_find_single_vq(vdev, blk_done, "requests"); | 379 | vblk->vq = virtio_find_single_vq(vdev, blk_done, "requests"); |
@@ -477,6 +524,8 @@ static void __devexit virtblk_remove(struct virtio_device *vdev) | |||
477 | { | 524 | { |
478 | struct virtio_blk *vblk = vdev->priv; | 525 | struct virtio_blk *vblk = vdev->priv; |
479 | 526 | ||
527 | flush_work(&vblk->config_work); | ||
528 | |||
480 | /* Nothing should be pending. */ | 529 | /* Nothing should be pending. */ |
481 | BUG_ON(!list_empty(&vblk->reqs)); | 530 | BUG_ON(!list_empty(&vblk->reqs)); |
482 | 531 | ||
@@ -508,27 +557,47 @@ static unsigned int features[] = { | |||
508 | * Use __refdata to avoid this warning. | 557 | * Use __refdata to avoid this warning. |
509 | */ | 558 | */ |
510 | static struct virtio_driver __refdata virtio_blk = { | 559 | static struct virtio_driver __refdata virtio_blk = { |
511 | .feature_table = features, | 560 | .feature_table = features, |
512 | .feature_table_size = ARRAY_SIZE(features), | 561 | .feature_table_size = ARRAY_SIZE(features), |
513 | .driver.name = KBUILD_MODNAME, | 562 | .driver.name = KBUILD_MODNAME, |
514 | .driver.owner = THIS_MODULE, | 563 | .driver.owner = THIS_MODULE, |
515 | .id_table = id_table, | 564 | .id_table = id_table, |
516 | .probe = virtblk_probe, | 565 | .probe = virtblk_probe, |
517 | .remove = __devexit_p(virtblk_remove), | 566 | .remove = __devexit_p(virtblk_remove), |
567 | .config_changed = virtblk_config_changed, | ||
518 | }; | 568 | }; |
519 | 569 | ||
520 | static int __init init(void) | 570 | static int __init init(void) |
521 | { | 571 | { |
572 | int error; | ||
573 | |||
574 | virtblk_wq = alloc_workqueue("virtio-blk", 0, 0); | ||
575 | if (!virtblk_wq) | ||
576 | return -ENOMEM; | ||
577 | |||
522 | major = register_blkdev(0, "virtblk"); | 578 | major = register_blkdev(0, "virtblk"); |
523 | if (major < 0) | 579 | if (major < 0) { |
524 | return major; | 580 | error = major; |
525 | return register_virtio_driver(&virtio_blk); | 581 | goto out_destroy_workqueue; |
582 | } | ||
583 | |||
584 | error = register_virtio_driver(&virtio_blk); | ||
585 | if (error) | ||
586 | goto out_unregister_blkdev; | ||
587 | return 0; | ||
588 | |||
589 | out_unregister_blkdev: | ||
590 | unregister_blkdev(major, "virtblk"); | ||
591 | out_destroy_workqueue: | ||
592 | destroy_workqueue(virtblk_wq); | ||
593 | return error; | ||
526 | } | 594 | } |
527 | 595 | ||
528 | static void __exit fini(void) | 596 | static void __exit fini(void) |
529 | { | 597 | { |
530 | unregister_blkdev(major, "virtblk"); | 598 | unregister_blkdev(major, "virtblk"); |
531 | unregister_virtio_driver(&virtio_blk); | 599 | unregister_virtio_driver(&virtio_blk); |
600 | destroy_workqueue(virtblk_wq); | ||
532 | } | 601 | } |
533 | module_init(init); | 602 | module_init(init); |
534 | module_exit(fini); | 603 | module_exit(fini); |
diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index c73910cc28c9..5cf2993a8338 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c | |||
@@ -809,11 +809,13 @@ static int __init xen_blkif_init(void) | |||
809 | failed_init: | 809 | failed_init: |
810 | kfree(blkbk->pending_reqs); | 810 | kfree(blkbk->pending_reqs); |
811 | kfree(blkbk->pending_grant_handles); | 811 | kfree(blkbk->pending_grant_handles); |
812 | for (i = 0; i < mmap_pages; i++) { | 812 | if (blkbk->pending_pages) { |
813 | if (blkbk->pending_pages[i]) | 813 | for (i = 0; i < mmap_pages; i++) { |
814 | __free_page(blkbk->pending_pages[i]); | 814 | if (blkbk->pending_pages[i]) |
815 | __free_page(blkbk->pending_pages[i]); | ||
816 | } | ||
817 | kfree(blkbk->pending_pages); | ||
815 | } | 818 | } |
816 | kfree(blkbk->pending_pages); | ||
817 | kfree(blkbk); | 819 | kfree(blkbk); |
818 | blkbk = NULL; | 820 | blkbk = NULL; |
819 | return rc; | 821 | return rc; |
diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c index 34570823355b..6cc0db1bf522 100644 --- a/drivers/block/xen-blkback/xenbus.c +++ b/drivers/block/xen-blkback/xenbus.c | |||
@@ -357,14 +357,13 @@ static int xen_vbd_create(struct xen_blkif *blkif, blkif_vdev_t handle, | |||
357 | } | 357 | } |
358 | 358 | ||
359 | vbd->bdev = bdev; | 359 | vbd->bdev = bdev; |
360 | vbd->size = vbd_sz(vbd); | ||
361 | |||
362 | if (vbd->bdev->bd_disk == NULL) { | 360 | if (vbd->bdev->bd_disk == NULL) { |
363 | DPRINTK("xen_vbd_create: device %08x doesn't exist.\n", | 361 | DPRINTK("xen_vbd_create: device %08x doesn't exist.\n", |
364 | vbd->pdevice); | 362 | vbd->pdevice); |
365 | xen_vbd_free(vbd); | 363 | xen_vbd_free(vbd); |
366 | return -ENOENT; | 364 | return -ENOENT; |
367 | } | 365 | } |
366 | vbd->size = vbd_sz(vbd); | ||
368 | 367 | ||
369 | if (vbd->bdev->bd_disk->flags & GENHD_FL_CD || cdrom) | 368 | if (vbd->bdev->bd_disk->flags & GENHD_FL_CD || cdrom) |
370 | vbd->type |= VDISK_CDROM; | 369 | vbd->type |= VDISK_CDROM; |
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index b3f01996318f..48ad2a7ab080 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c | |||
@@ -355,29 +355,24 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty) | |||
355 | * flags pointer to flags for data | 355 | * flags pointer to flags for data |
356 | * count count of received data in bytes | 356 | * count count of received data in bytes |
357 | * | 357 | * |
358 | * Return Value: Number of bytes received | 358 | * Return Value: None |
359 | */ | 359 | */ |
360 | static unsigned int hci_uart_tty_receive(struct tty_struct *tty, | 360 | static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *flags, int count) |
361 | const u8 *data, char *flags, int count) | ||
362 | { | 361 | { |
363 | struct hci_uart *hu = (void *)tty->disc_data; | 362 | struct hci_uart *hu = (void *)tty->disc_data; |
364 | int received; | ||
365 | 363 | ||
366 | if (!hu || tty != hu->tty) | 364 | if (!hu || tty != hu->tty) |
367 | return -ENODEV; | 365 | return; |
368 | 366 | ||
369 | if (!test_bit(HCI_UART_PROTO_SET, &hu->flags)) | 367 | if (!test_bit(HCI_UART_PROTO_SET, &hu->flags)) |
370 | return -EINVAL; | 368 | return; |
371 | 369 | ||
372 | spin_lock(&hu->rx_lock); | 370 | spin_lock(&hu->rx_lock); |
373 | received = hu->proto->recv(hu, (void *) data, count); | 371 | hu->proto->recv(hu, (void *) data, count); |
374 | if (received > 0) | 372 | hu->hdev->stat.byte_rx += count; |
375 | hu->hdev->stat.byte_rx += received; | ||
376 | spin_unlock(&hu->rx_lock); | 373 | spin_unlock(&hu->rx_lock); |
377 | 374 | ||
378 | tty_unthrottle(tty); | 375 | tty_unthrottle(tty); |
379 | |||
380 | return received; | ||
381 | } | 376 | } |
382 | 377 | ||
383 | static int hci_uart_register_dev(struct hci_uart *hu) | 378 | static int hci_uart_register_dev(struct hci_uart *hu) |
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index ae15a4ddaa9b..7878da89d29e 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c | |||
@@ -627,7 +627,6 @@ static int viocd_probe(struct vio_dev *vdev, const struct vio_device_id *id) | |||
627 | gendisk->fops = &viocd_fops; | 627 | gendisk->fops = &viocd_fops; |
628 | gendisk->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE | | 628 | gendisk->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE | |
629 | GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE; | 629 | GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE; |
630 | gendisk->events = DISK_EVENT_MEDIA_CHANGE; | ||
631 | set_capacity(gendisk, 0); | 630 | set_capacity(gendisk, 0); |
632 | gendisk->private_data = d; | 631 | gendisk->private_data = d; |
633 | d->viocd_disk = gendisk; | 632 | d->viocd_disk = gendisk; |
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 838568a7dbf5..fb68b1295373 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c | |||
@@ -1677,17 +1677,12 @@ static int __devinit virtcons_probe(struct virtio_device *vdev) | |||
1677 | portdev->config.max_nr_ports = 1; | 1677 | portdev->config.max_nr_ports = 1; |
1678 | if (virtio_has_feature(vdev, VIRTIO_CONSOLE_F_MULTIPORT)) { | 1678 | if (virtio_has_feature(vdev, VIRTIO_CONSOLE_F_MULTIPORT)) { |
1679 | multiport = true; | 1679 | multiport = true; |
1680 | vdev->features[0] |= 1 << VIRTIO_CONSOLE_F_MULTIPORT; | ||
1681 | |||
1682 | vdev->config->get(vdev, offsetof(struct virtio_console_config, | 1680 | vdev->config->get(vdev, offsetof(struct virtio_console_config, |
1683 | max_nr_ports), | 1681 | max_nr_ports), |
1684 | &portdev->config.max_nr_ports, | 1682 | &portdev->config.max_nr_ports, |
1685 | sizeof(portdev->config.max_nr_ports)); | 1683 | sizeof(portdev->config.max_nr_ports)); |
1686 | } | 1684 | } |
1687 | 1685 | ||
1688 | /* Let the Host know we support multiple ports.*/ | ||
1689 | vdev->config->finalize_features(vdev); | ||
1690 | |||
1691 | err = init_vqs(portdev); | 1686 | err = init_vqs(portdev); |
1692 | if (err < 0) { | 1687 | if (err < 0) { |
1693 | dev_err(&vdev->dev, "Error %d initializing vqs\n", err); | 1688 | dev_err(&vdev->dev, "Error %d initializing vqs\n", err); |
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index 036e5865eb40..dc7c033ef587 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/ioport.h> | 24 | #include <linux/ioport.h> |
25 | #include <linux/io.h> | 25 | #include <linux/io.h> |
26 | #include <linux/clk.h> | 26 | #include <linux/clk.h> |
27 | #include <linux/pm_runtime.h> | ||
28 | #include <linux/irq.h> | 27 | #include <linux/irq.h> |
29 | #include <linux/err.h> | 28 | #include <linux/err.h> |
30 | #include <linux/clocksource.h> | 29 | #include <linux/clocksource.h> |
@@ -153,12 +152,10 @@ static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate) | |||
153 | { | 152 | { |
154 | int ret; | 153 | int ret; |
155 | 154 | ||
156 | /* wake up device and enable clock */ | 155 | /* enable clock */ |
157 | pm_runtime_get_sync(&p->pdev->dev); | ||
158 | ret = clk_enable(p->clk); | 156 | ret = clk_enable(p->clk); |
159 | if (ret) { | 157 | if (ret) { |
160 | dev_err(&p->pdev->dev, "cannot enable clock\n"); | 158 | dev_err(&p->pdev->dev, "cannot enable clock\n"); |
161 | pm_runtime_put_sync(&p->pdev->dev); | ||
162 | return ret; | 159 | return ret; |
163 | } | 160 | } |
164 | 161 | ||
@@ -190,9 +187,8 @@ static void sh_cmt_disable(struct sh_cmt_priv *p) | |||
190 | /* disable interrupts in CMT block */ | 187 | /* disable interrupts in CMT block */ |
191 | sh_cmt_write(p, CMCSR, 0); | 188 | sh_cmt_write(p, CMCSR, 0); |
192 | 189 | ||
193 | /* stop clock and mark device as idle */ | 190 | /* stop clock */ |
194 | clk_disable(p->clk); | 191 | clk_disable(p->clk); |
195 | pm_runtime_put_sync(&p->pdev->dev); | ||
196 | } | 192 | } |
197 | 193 | ||
198 | /* private flags */ | 194 | /* private flags */ |
@@ -664,7 +660,6 @@ static int __devinit sh_cmt_probe(struct platform_device *pdev) | |||
664 | 660 | ||
665 | if (p) { | 661 | if (p) { |
666 | dev_info(&pdev->dev, "kept as earlytimer\n"); | 662 | dev_info(&pdev->dev, "kept as earlytimer\n"); |
667 | pm_runtime_enable(&pdev->dev); | ||
668 | return 0; | 663 | return 0; |
669 | } | 664 | } |
670 | 665 | ||
@@ -679,9 +674,6 @@ static int __devinit sh_cmt_probe(struct platform_device *pdev) | |||
679 | kfree(p); | 674 | kfree(p); |
680 | platform_set_drvdata(pdev, NULL); | 675 | platform_set_drvdata(pdev, NULL); |
681 | } | 676 | } |
682 | |||
683 | if (!is_early_platform_device(pdev)) | ||
684 | pm_runtime_enable(&pdev->dev); | ||
685 | return ret; | 677 | return ret; |
686 | } | 678 | } |
687 | 679 | ||
diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c index 17296288a205..808135768617 100644 --- a/drivers/clocksource/sh_tmu.c +++ b/drivers/clocksource/sh_tmu.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
26 | #include <linux/io.h> | 26 | #include <linux/io.h> |
27 | #include <linux/clk.h> | 27 | #include <linux/clk.h> |
28 | #include <linux/pm_runtime.h> | ||
29 | #include <linux/irq.h> | 28 | #include <linux/irq.h> |
30 | #include <linux/err.h> | 29 | #include <linux/err.h> |
31 | #include <linux/clocksource.h> | 30 | #include <linux/clocksource.h> |
@@ -110,12 +109,10 @@ static int sh_tmu_enable(struct sh_tmu_priv *p) | |||
110 | { | 109 | { |
111 | int ret; | 110 | int ret; |
112 | 111 | ||
113 | /* wake up device and enable clock */ | 112 | /* enable clock */ |
114 | pm_runtime_get_sync(&p->pdev->dev); | ||
115 | ret = clk_enable(p->clk); | 113 | ret = clk_enable(p->clk); |
116 | if (ret) { | 114 | if (ret) { |
117 | dev_err(&p->pdev->dev, "cannot enable clock\n"); | 115 | dev_err(&p->pdev->dev, "cannot enable clock\n"); |
118 | pm_runtime_put_sync(&p->pdev->dev); | ||
119 | return ret; | 116 | return ret; |
120 | } | 117 | } |
121 | 118 | ||
@@ -144,9 +141,8 @@ static void sh_tmu_disable(struct sh_tmu_priv *p) | |||
144 | /* disable interrupts in TMU block */ | 141 | /* disable interrupts in TMU block */ |
145 | sh_tmu_write(p, TCR, 0x0000); | 142 | sh_tmu_write(p, TCR, 0x0000); |
146 | 143 | ||
147 | /* stop clock and mark device as idle */ | 144 | /* stop clock */ |
148 | clk_disable(p->clk); | 145 | clk_disable(p->clk); |
149 | pm_runtime_put_sync(&p->pdev->dev); | ||
150 | } | 146 | } |
151 | 147 | ||
152 | static void sh_tmu_set_next(struct sh_tmu_priv *p, unsigned long delta, | 148 | static void sh_tmu_set_next(struct sh_tmu_priv *p, unsigned long delta, |
@@ -415,7 +411,6 @@ static int __devinit sh_tmu_probe(struct platform_device *pdev) | |||
415 | 411 | ||
416 | if (p) { | 412 | if (p) { |
417 | dev_info(&pdev->dev, "kept as earlytimer\n"); | 413 | dev_info(&pdev->dev, "kept as earlytimer\n"); |
418 | pm_runtime_enable(&pdev->dev); | ||
419 | return 0; | 414 | return 0; |
420 | } | 415 | } |
421 | 416 | ||
@@ -430,9 +425,6 @@ static int __devinit sh_tmu_probe(struct platform_device *pdev) | |||
430 | kfree(p); | 425 | kfree(p); |
431 | platform_set_drvdata(pdev, NULL); | 426 | platform_set_drvdata(pdev, NULL); |
432 | } | 427 | } |
433 | |||
434 | if (!is_early_platform_device(pdev)) | ||
435 | pm_runtime_enable(&pdev->dev); | ||
436 | return ret; | 428 | return ret; |
437 | } | 429 | } |
438 | 430 | ||
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index f508690eb958..c47f3d09c1ee 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c | |||
@@ -237,6 +237,7 @@ static int menu_select(struct cpuidle_device *dev) | |||
237 | unsigned int power_usage = -1; | 237 | unsigned int power_usage = -1; |
238 | int i; | 238 | int i; |
239 | int multiplier; | 239 | int multiplier; |
240 | struct timespec t; | ||
240 | 241 | ||
241 | if (data->needs_update) { | 242 | if (data->needs_update) { |
242 | menu_update(dev); | 243 | menu_update(dev); |
@@ -251,8 +252,9 @@ static int menu_select(struct cpuidle_device *dev) | |||
251 | return 0; | 252 | return 0; |
252 | 253 | ||
253 | /* determine the expected residency time, round up */ | 254 | /* determine the expected residency time, round up */ |
255 | t = ktime_to_timespec(tick_nohz_get_sleep_length()); | ||
254 | data->expected_us = | 256 | data->expected_us = |
255 | DIV_ROUND_UP((u32)ktime_to_ns(tick_nohz_get_sleep_length()), 1000); | 257 | t.tv_sec * USEC_PER_SEC + t.tv_nsec / NSEC_PER_USEC; |
256 | 258 | ||
257 | 259 | ||
258 | data->bucket = which_bucket(data->expected_us); | 260 | data->bucket = which_bucket(data->expected_us); |
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index a572600e44eb..25cf327cd1cb 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig | |||
@@ -200,16 +200,18 @@ config PL330_DMA | |||
200 | platform_data for a dma-pl330 device. | 200 | platform_data for a dma-pl330 device. |
201 | 201 | ||
202 | config PCH_DMA | 202 | config PCH_DMA |
203 | tristate "Intel EG20T PCH / OKI SEMICONDUCTOR ML7213 IOH DMA support" | 203 | tristate "Intel EG20T PCH / OKI Semi IOH(ML7213/ML7223) DMA support" |
204 | depends on PCI && X86 | 204 | depends on PCI && X86 |
205 | select DMA_ENGINE | 205 | select DMA_ENGINE |
206 | help | 206 | help |
207 | Enable support for Intel EG20T PCH DMA engine. | 207 | Enable support for Intel EG20T PCH DMA engine. |
208 | 208 | ||
209 | This driver also can be used for OKI SEMICONDUCTOR ML7213 IOH(Input/ | 209 | This driver also can be used for OKI SEMICONDUCTOR IOH(Input/ |
210 | Output Hub) which is for IVI(In-Vehicle Infotainment) use. | 210 | Output Hub), ML7213 and ML7223. |
211 | ML7213 is companion chip for Intel Atom E6xx series. | 211 | ML7213 IOH is for IVI(In-Vehicle Infotainment) use and ML7223 IOH is |
212 | ML7213 is completely compatible for Intel EG20T PCH. | 212 | for MP(Media Phone) use. |
213 | ML7213/ML7223 is companion chip for Intel Atom E6xx series. | ||
214 | ML7213/ML7223 is completely compatible for Intel EG20T PCH. | ||
213 | 215 | ||
214 | config IMX_SDMA | 216 | config IMX_SDMA |
215 | tristate "i.MX SDMA support" | 217 | tristate "i.MX SDMA support" |
diff --git a/drivers/dma/TODO b/drivers/dma/TODO new file mode 100644 index 000000000000..a4af8589330c --- /dev/null +++ b/drivers/dma/TODO | |||
@@ -0,0 +1,14 @@ | |||
1 | TODO for slave dma | ||
2 | |||
3 | 1. Move remaining drivers to use new slave interface | ||
4 | 2. Remove old slave pointer machansim | ||
5 | 3. Make issue_pending to start the transaction in below drivers | ||
6 | - mpc512x_dma | ||
7 | - imx-dma | ||
8 | - imx-sdma | ||
9 | - mxs-dma.c | ||
10 | - dw_dmac | ||
11 | - intel_mid_dma | ||
12 | - ste_dma40 | ||
13 | 4. Check other subsystems for dma drivers and merge/move to dmaengine | ||
14 | 5. Remove dma_slave_config's dma direction. | ||
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index 235f53bf494e..36144f88d718 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c | |||
@@ -37,8 +37,8 @@ | |||
37 | 37 | ||
38 | #define ATC_DEFAULT_CFG (ATC_FIFOCFG_HALFFIFO) | 38 | #define ATC_DEFAULT_CFG (ATC_FIFOCFG_HALFFIFO) |
39 | #define ATC_DEFAULT_CTRLA (0) | 39 | #define ATC_DEFAULT_CTRLA (0) |
40 | #define ATC_DEFAULT_CTRLB (ATC_SIF(0) \ | 40 | #define ATC_DEFAULT_CTRLB (ATC_SIF(AT_DMA_MEM_IF) \ |
41 | |ATC_DIF(1)) | 41 | |ATC_DIF(AT_DMA_MEM_IF)) |
42 | 42 | ||
43 | /* | 43 | /* |
44 | * Initial number of descriptors to allocate for each channel. This could | 44 | * Initial number of descriptors to allocate for each channel. This could |
@@ -165,6 +165,29 @@ static void atc_desc_put(struct at_dma_chan *atchan, struct at_desc *desc) | |||
165 | } | 165 | } |
166 | 166 | ||
167 | /** | 167 | /** |
168 | * atc_desc_chain - build chain adding a descripor | ||
169 | * @first: address of first descripor of the chain | ||
170 | * @prev: address of previous descripor of the chain | ||
171 | * @desc: descriptor to queue | ||
172 | * | ||
173 | * Called from prep_* functions | ||
174 | */ | ||
175 | static void atc_desc_chain(struct at_desc **first, struct at_desc **prev, | ||
176 | struct at_desc *desc) | ||
177 | { | ||
178 | if (!(*first)) { | ||
179 | *first = desc; | ||
180 | } else { | ||
181 | /* inform the HW lli about chaining */ | ||
182 | (*prev)->lli.dscr = desc->txd.phys; | ||
183 | /* insert the link descriptor to the LD ring */ | ||
184 | list_add_tail(&desc->desc_node, | ||
185 | &(*first)->tx_list); | ||
186 | } | ||
187 | *prev = desc; | ||
188 | } | ||
189 | |||
190 | /** | ||
168 | * atc_assign_cookie - compute and assign new cookie | 191 | * atc_assign_cookie - compute and assign new cookie |
169 | * @atchan: channel we work on | 192 | * @atchan: channel we work on |
170 | * @desc: descriptor to assign cookie for | 193 | * @desc: descriptor to assign cookie for |
@@ -237,16 +260,12 @@ static void atc_dostart(struct at_dma_chan *atchan, struct at_desc *first) | |||
237 | static void | 260 | static void |
238 | atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc) | 261 | atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc) |
239 | { | 262 | { |
240 | dma_async_tx_callback callback; | ||
241 | void *param; | ||
242 | struct dma_async_tx_descriptor *txd = &desc->txd; | 263 | struct dma_async_tx_descriptor *txd = &desc->txd; |
243 | 264 | ||
244 | dev_vdbg(chan2dev(&atchan->chan_common), | 265 | dev_vdbg(chan2dev(&atchan->chan_common), |
245 | "descriptor %u complete\n", txd->cookie); | 266 | "descriptor %u complete\n", txd->cookie); |
246 | 267 | ||
247 | atchan->completed_cookie = txd->cookie; | 268 | atchan->completed_cookie = txd->cookie; |
248 | callback = txd->callback; | ||
249 | param = txd->callback_param; | ||
250 | 269 | ||
251 | /* move children to free_list */ | 270 | /* move children to free_list */ |
252 | list_splice_init(&desc->tx_list, &atchan->free_list); | 271 | list_splice_init(&desc->tx_list, &atchan->free_list); |
@@ -278,12 +297,19 @@ atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc) | |||
278 | } | 297 | } |
279 | } | 298 | } |
280 | 299 | ||
281 | /* | 300 | /* for cyclic transfers, |
282 | * The API requires that no submissions are done from a | 301 | * no need to replay callback function while stopping */ |
283 | * callback, so we don't need to drop the lock here | 302 | if (!test_bit(ATC_IS_CYCLIC, &atchan->status)) { |
284 | */ | 303 | dma_async_tx_callback callback = txd->callback; |
285 | if (callback) | 304 | void *param = txd->callback_param; |
286 | callback(param); | 305 | |
306 | /* | ||
307 | * The API requires that no submissions are done from a | ||
308 | * callback, so we don't need to drop the lock here | ||
309 | */ | ||
310 | if (callback) | ||
311 | callback(param); | ||
312 | } | ||
287 | 313 | ||
288 | dma_run_dependencies(txd); | 314 | dma_run_dependencies(txd); |
289 | } | 315 | } |
@@ -419,6 +445,26 @@ static void atc_handle_error(struct at_dma_chan *atchan) | |||
419 | atc_chain_complete(atchan, bad_desc); | 445 | atc_chain_complete(atchan, bad_desc); |
420 | } | 446 | } |
421 | 447 | ||
448 | /** | ||
449 | * atc_handle_cyclic - at the end of a period, run callback function | ||
450 | * @atchan: channel used for cyclic operations | ||
451 | * | ||
452 | * Called with atchan->lock held and bh disabled | ||
453 | */ | ||
454 | static void atc_handle_cyclic(struct at_dma_chan *atchan) | ||
455 | { | ||
456 | struct at_desc *first = atc_first_active(atchan); | ||
457 | struct dma_async_tx_descriptor *txd = &first->txd; | ||
458 | dma_async_tx_callback callback = txd->callback; | ||
459 | void *param = txd->callback_param; | ||
460 | |||
461 | dev_vdbg(chan2dev(&atchan->chan_common), | ||
462 | "new cyclic period llp 0x%08x\n", | ||
463 | channel_readl(atchan, DSCR)); | ||
464 | |||
465 | if (callback) | ||
466 | callback(param); | ||
467 | } | ||
422 | 468 | ||
423 | /*-- IRQ & Tasklet ---------------------------------------------------*/ | 469 | /*-- IRQ & Tasklet ---------------------------------------------------*/ |
424 | 470 | ||
@@ -426,16 +472,11 @@ static void atc_tasklet(unsigned long data) | |||
426 | { | 472 | { |
427 | struct at_dma_chan *atchan = (struct at_dma_chan *)data; | 473 | struct at_dma_chan *atchan = (struct at_dma_chan *)data; |
428 | 474 | ||
429 | /* Channel cannot be enabled here */ | ||
430 | if (atc_chan_is_enabled(atchan)) { | ||
431 | dev_err(chan2dev(&atchan->chan_common), | ||
432 | "BUG: channel enabled in tasklet\n"); | ||
433 | return; | ||
434 | } | ||
435 | |||
436 | spin_lock(&atchan->lock); | 475 | spin_lock(&atchan->lock); |
437 | if (test_and_clear_bit(0, &atchan->error_status)) | 476 | if (test_and_clear_bit(ATC_IS_ERROR, &atchan->status)) |
438 | atc_handle_error(atchan); | 477 | atc_handle_error(atchan); |
478 | else if (test_bit(ATC_IS_CYCLIC, &atchan->status)) | ||
479 | atc_handle_cyclic(atchan); | ||
439 | else | 480 | else |
440 | atc_advance_work(atchan); | 481 | atc_advance_work(atchan); |
441 | 482 | ||
@@ -464,12 +505,13 @@ static irqreturn_t at_dma_interrupt(int irq, void *dev_id) | |||
464 | 505 | ||
465 | for (i = 0; i < atdma->dma_common.chancnt; i++) { | 506 | for (i = 0; i < atdma->dma_common.chancnt; i++) { |
466 | atchan = &atdma->chan[i]; | 507 | atchan = &atdma->chan[i]; |
467 | if (pending & (AT_DMA_CBTC(i) | AT_DMA_ERR(i))) { | 508 | if (pending & (AT_DMA_BTC(i) | AT_DMA_ERR(i))) { |
468 | if (pending & AT_DMA_ERR(i)) { | 509 | if (pending & AT_DMA_ERR(i)) { |
469 | /* Disable channel on AHB error */ | 510 | /* Disable channel on AHB error */ |
470 | dma_writel(atdma, CHDR, atchan->mask); | 511 | dma_writel(atdma, CHDR, |
512 | AT_DMA_RES(i) | atchan->mask); | ||
471 | /* Give information to tasklet */ | 513 | /* Give information to tasklet */ |
472 | set_bit(0, &atchan->error_status); | 514 | set_bit(ATC_IS_ERROR, &atchan->status); |
473 | } | 515 | } |
474 | tasklet_schedule(&atchan->tasklet); | 516 | tasklet_schedule(&atchan->tasklet); |
475 | ret = IRQ_HANDLED; | 517 | ret = IRQ_HANDLED; |
@@ -549,7 +591,7 @@ atc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, | |||
549 | } | 591 | } |
550 | 592 | ||
551 | ctrla = ATC_DEFAULT_CTRLA; | 593 | ctrla = ATC_DEFAULT_CTRLA; |
552 | ctrlb = ATC_DEFAULT_CTRLB | 594 | ctrlb = ATC_DEFAULT_CTRLB | ATC_IEN |
553 | | ATC_SRC_ADDR_MODE_INCR | 595 | | ATC_SRC_ADDR_MODE_INCR |
554 | | ATC_DST_ADDR_MODE_INCR | 596 | | ATC_DST_ADDR_MODE_INCR |
555 | | ATC_FC_MEM2MEM; | 597 | | ATC_FC_MEM2MEM; |
@@ -584,16 +626,7 @@ atc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, | |||
584 | 626 | ||
585 | desc->txd.cookie = 0; | 627 | desc->txd.cookie = 0; |
586 | 628 | ||
587 | if (!first) { | 629 | atc_desc_chain(&first, &prev, desc); |
588 | first = desc; | ||
589 | } else { | ||
590 | /* inform the HW lli about chaining */ | ||
591 | prev->lli.dscr = desc->txd.phys; | ||
592 | /* insert the link descriptor to the LD ring */ | ||
593 | list_add_tail(&desc->desc_node, | ||
594 | &first->tx_list); | ||
595 | } | ||
596 | prev = desc; | ||
597 | } | 630 | } |
598 | 631 | ||
599 | /* First descriptor of the chain embedds additional information */ | 632 | /* First descriptor of the chain embedds additional information */ |
@@ -639,7 +672,8 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
639 | struct scatterlist *sg; | 672 | struct scatterlist *sg; |
640 | size_t total_len = 0; | 673 | size_t total_len = 0; |
641 | 674 | ||
642 | dev_vdbg(chan2dev(chan), "prep_slave_sg: %s f0x%lx\n", | 675 | dev_vdbg(chan2dev(chan), "prep_slave_sg (%d): %s f0x%lx\n", |
676 | sg_len, | ||
643 | direction == DMA_TO_DEVICE ? "TO DEVICE" : "FROM DEVICE", | 677 | direction == DMA_TO_DEVICE ? "TO DEVICE" : "FROM DEVICE", |
644 | flags); | 678 | flags); |
645 | 679 | ||
@@ -651,14 +685,15 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
651 | reg_width = atslave->reg_width; | 685 | reg_width = atslave->reg_width; |
652 | 686 | ||
653 | ctrla = ATC_DEFAULT_CTRLA | atslave->ctrla; | 687 | ctrla = ATC_DEFAULT_CTRLA | atslave->ctrla; |
654 | ctrlb = ATC_DEFAULT_CTRLB | ATC_IEN; | 688 | ctrlb = ATC_IEN; |
655 | 689 | ||
656 | switch (direction) { | 690 | switch (direction) { |
657 | case DMA_TO_DEVICE: | 691 | case DMA_TO_DEVICE: |
658 | ctrla |= ATC_DST_WIDTH(reg_width); | 692 | ctrla |= ATC_DST_WIDTH(reg_width); |
659 | ctrlb |= ATC_DST_ADDR_MODE_FIXED | 693 | ctrlb |= ATC_DST_ADDR_MODE_FIXED |
660 | | ATC_SRC_ADDR_MODE_INCR | 694 | | ATC_SRC_ADDR_MODE_INCR |
661 | | ATC_FC_MEM2PER; | 695 | | ATC_FC_MEM2PER |
696 | | ATC_SIF(AT_DMA_MEM_IF) | ATC_DIF(AT_DMA_PER_IF); | ||
662 | reg = atslave->tx_reg; | 697 | reg = atslave->tx_reg; |
663 | for_each_sg(sgl, sg, sg_len, i) { | 698 | for_each_sg(sgl, sg, sg_len, i) { |
664 | struct at_desc *desc; | 699 | struct at_desc *desc; |
@@ -682,16 +717,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
682 | | len >> mem_width; | 717 | | len >> mem_width; |
683 | desc->lli.ctrlb = ctrlb; | 718 | desc->lli.ctrlb = ctrlb; |
684 | 719 | ||
685 | if (!first) { | 720 | atc_desc_chain(&first, &prev, desc); |
686 | first = desc; | ||
687 | } else { | ||
688 | /* inform the HW lli about chaining */ | ||
689 | prev->lli.dscr = desc->txd.phys; | ||
690 | /* insert the link descriptor to the LD ring */ | ||
691 | list_add_tail(&desc->desc_node, | ||
692 | &first->tx_list); | ||
693 | } | ||
694 | prev = desc; | ||
695 | total_len += len; | 721 | total_len += len; |
696 | } | 722 | } |
697 | break; | 723 | break; |
@@ -699,7 +725,8 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
699 | ctrla |= ATC_SRC_WIDTH(reg_width); | 725 | ctrla |= ATC_SRC_WIDTH(reg_width); |
700 | ctrlb |= ATC_DST_ADDR_MODE_INCR | 726 | ctrlb |= ATC_DST_ADDR_MODE_INCR |
701 | | ATC_SRC_ADDR_MODE_FIXED | 727 | | ATC_SRC_ADDR_MODE_FIXED |
702 | | ATC_FC_PER2MEM; | 728 | | ATC_FC_PER2MEM |
729 | | ATC_SIF(AT_DMA_PER_IF) | ATC_DIF(AT_DMA_MEM_IF); | ||
703 | 730 | ||
704 | reg = atslave->rx_reg; | 731 | reg = atslave->rx_reg; |
705 | for_each_sg(sgl, sg, sg_len, i) { | 732 | for_each_sg(sgl, sg, sg_len, i) { |
@@ -724,16 +751,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
724 | | len >> reg_width; | 751 | | len >> reg_width; |
725 | desc->lli.ctrlb = ctrlb; | 752 | desc->lli.ctrlb = ctrlb; |
726 | 753 | ||
727 | if (!first) { | 754 | atc_desc_chain(&first, &prev, desc); |
728 | first = desc; | ||
729 | } else { | ||
730 | /* inform the HW lli about chaining */ | ||
731 | prev->lli.dscr = desc->txd.phys; | ||
732 | /* insert the link descriptor to the LD ring */ | ||
733 | list_add_tail(&desc->desc_node, | ||
734 | &first->tx_list); | ||
735 | } | ||
736 | prev = desc; | ||
737 | total_len += len; | 755 | total_len += len; |
738 | } | 756 | } |
739 | break; | 757 | break; |
@@ -759,41 +777,211 @@ err_desc_get: | |||
759 | return NULL; | 777 | return NULL; |
760 | } | 778 | } |
761 | 779 | ||
780 | /** | ||
781 | * atc_dma_cyclic_check_values | ||
782 | * Check for too big/unaligned periods and unaligned DMA buffer | ||
783 | */ | ||
784 | static int | ||
785 | atc_dma_cyclic_check_values(unsigned int reg_width, dma_addr_t buf_addr, | ||
786 | size_t period_len, enum dma_data_direction direction) | ||
787 | { | ||
788 | if (period_len > (ATC_BTSIZE_MAX << reg_width)) | ||
789 | goto err_out; | ||
790 | if (unlikely(period_len & ((1 << reg_width) - 1))) | ||
791 | goto err_out; | ||
792 | if (unlikely(buf_addr & ((1 << reg_width) - 1))) | ||
793 | goto err_out; | ||
794 | if (unlikely(!(direction & (DMA_TO_DEVICE | DMA_FROM_DEVICE)))) | ||
795 | goto err_out; | ||
796 | |||
797 | return 0; | ||
798 | |||
799 | err_out: | ||
800 | return -EINVAL; | ||
801 | } | ||
802 | |||
803 | /** | ||
804 | * atc_dma_cyclic_fill_desc - Fill one period decriptor | ||
805 | */ | ||
806 | static int | ||
807 | atc_dma_cyclic_fill_desc(struct at_dma_slave *atslave, struct at_desc *desc, | ||
808 | unsigned int period_index, dma_addr_t buf_addr, | ||
809 | size_t period_len, enum dma_data_direction direction) | ||
810 | { | ||
811 | u32 ctrla; | ||
812 | unsigned int reg_width = atslave->reg_width; | ||
813 | |||
814 | /* prepare common CRTLA value */ | ||
815 | ctrla = ATC_DEFAULT_CTRLA | atslave->ctrla | ||
816 | | ATC_DST_WIDTH(reg_width) | ||
817 | | ATC_SRC_WIDTH(reg_width) | ||
818 | | period_len >> reg_width; | ||
819 | |||
820 | switch (direction) { | ||
821 | case DMA_TO_DEVICE: | ||
822 | desc->lli.saddr = buf_addr + (period_len * period_index); | ||
823 | desc->lli.daddr = atslave->tx_reg; | ||
824 | desc->lli.ctrla = ctrla; | ||
825 | desc->lli.ctrlb = ATC_DST_ADDR_MODE_FIXED | ||
826 | | ATC_SRC_ADDR_MODE_INCR | ||
827 | | ATC_FC_MEM2PER | ||
828 | | ATC_SIF(AT_DMA_MEM_IF) | ||
829 | | ATC_DIF(AT_DMA_PER_IF); | ||
830 | break; | ||
831 | |||
832 | case DMA_FROM_DEVICE: | ||
833 | desc->lli.saddr = atslave->rx_reg; | ||
834 | desc->lli.daddr = buf_addr + (period_len * period_index); | ||
835 | desc->lli.ctrla = ctrla; | ||
836 | desc->lli.ctrlb = ATC_DST_ADDR_MODE_INCR | ||
837 | | ATC_SRC_ADDR_MODE_FIXED | ||
838 | | ATC_FC_PER2MEM | ||
839 | | ATC_SIF(AT_DMA_PER_IF) | ||
840 | | ATC_DIF(AT_DMA_MEM_IF); | ||
841 | break; | ||
842 | |||
843 | default: | ||
844 | return -EINVAL; | ||
845 | } | ||
846 | |||
847 | return 0; | ||
848 | } | ||
849 | |||
850 | /** | ||
851 | * atc_prep_dma_cyclic - prepare the cyclic DMA transfer | ||
852 | * @chan: the DMA channel to prepare | ||
853 | * @buf_addr: physical DMA address where the buffer starts | ||
854 | * @buf_len: total number of bytes for the entire buffer | ||
855 | * @period_len: number of bytes for each period | ||
856 | * @direction: transfer direction, to or from device | ||
857 | */ | ||
858 | static struct dma_async_tx_descriptor * | ||
859 | atc_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len, | ||
860 | size_t period_len, enum dma_data_direction direction) | ||
861 | { | ||
862 | struct at_dma_chan *atchan = to_at_dma_chan(chan); | ||
863 | struct at_dma_slave *atslave = chan->private; | ||
864 | struct at_desc *first = NULL; | ||
865 | struct at_desc *prev = NULL; | ||
866 | unsigned long was_cyclic; | ||
867 | unsigned int periods = buf_len / period_len; | ||
868 | unsigned int i; | ||
869 | |||
870 | dev_vdbg(chan2dev(chan), "prep_dma_cyclic: %s buf@0x%08x - %d (%d/%d)\n", | ||
871 | direction == DMA_TO_DEVICE ? "TO DEVICE" : "FROM DEVICE", | ||
872 | buf_addr, | ||
873 | periods, buf_len, period_len); | ||
874 | |||
875 | if (unlikely(!atslave || !buf_len || !period_len)) { | ||
876 | dev_dbg(chan2dev(chan), "prep_dma_cyclic: length is zero!\n"); | ||
877 | return NULL; | ||
878 | } | ||
879 | |||
880 | was_cyclic = test_and_set_bit(ATC_IS_CYCLIC, &atchan->status); | ||
881 | if (was_cyclic) { | ||
882 | dev_dbg(chan2dev(chan), "prep_dma_cyclic: channel in use!\n"); | ||
883 | return NULL; | ||
884 | } | ||
885 | |||
886 | /* Check for too big/unaligned periods and unaligned DMA buffer */ | ||
887 | if (atc_dma_cyclic_check_values(atslave->reg_width, buf_addr, | ||
888 | period_len, direction)) | ||
889 | goto err_out; | ||
890 | |||
891 | /* build cyclic linked list */ | ||
892 | for (i = 0; i < periods; i++) { | ||
893 | struct at_desc *desc; | ||
894 | |||
895 | desc = atc_desc_get(atchan); | ||
896 | if (!desc) | ||
897 | goto err_desc_get; | ||
898 | |||
899 | if (atc_dma_cyclic_fill_desc(atslave, desc, i, buf_addr, | ||
900 | period_len, direction)) | ||
901 | goto err_desc_get; | ||
902 | |||
903 | atc_desc_chain(&first, &prev, desc); | ||
904 | } | ||
905 | |||
906 | /* lets make a cyclic list */ | ||
907 | prev->lli.dscr = first->txd.phys; | ||
908 | |||
909 | /* First descriptor of the chain embedds additional information */ | ||
910 | first->txd.cookie = -EBUSY; | ||
911 | first->len = buf_len; | ||
912 | |||
913 | return &first->txd; | ||
914 | |||
915 | err_desc_get: | ||
916 | dev_err(chan2dev(chan), "not enough descriptors available\n"); | ||
917 | atc_desc_put(atchan, first); | ||
918 | err_out: | ||
919 | clear_bit(ATC_IS_CYCLIC, &atchan->status); | ||
920 | return NULL; | ||
921 | } | ||
922 | |||
923 | |||
762 | static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, | 924 | static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, |
763 | unsigned long arg) | 925 | unsigned long arg) |
764 | { | 926 | { |
765 | struct at_dma_chan *atchan = to_at_dma_chan(chan); | 927 | struct at_dma_chan *atchan = to_at_dma_chan(chan); |
766 | struct at_dma *atdma = to_at_dma(chan->device); | 928 | struct at_dma *atdma = to_at_dma(chan->device); |
767 | struct at_desc *desc, *_desc; | 929 | int chan_id = atchan->chan_common.chan_id; |
930 | |||
768 | LIST_HEAD(list); | 931 | LIST_HEAD(list); |
769 | 932 | ||
770 | /* Only supports DMA_TERMINATE_ALL */ | 933 | dev_vdbg(chan2dev(chan), "atc_control (%d)\n", cmd); |
771 | if (cmd != DMA_TERMINATE_ALL) | ||
772 | return -ENXIO; | ||
773 | 934 | ||
774 | /* | 935 | if (cmd == DMA_PAUSE) { |
775 | * This is only called when something went wrong elsewhere, so | 936 | spin_lock_bh(&atchan->lock); |
776 | * we don't really care about the data. Just disable the | ||
777 | * channel. We still have to poll the channel enable bit due | ||
778 | * to AHB/HSB limitations. | ||
779 | */ | ||
780 | spin_lock_bh(&atchan->lock); | ||
781 | 937 | ||
782 | dma_writel(atdma, CHDR, atchan->mask); | 938 | dma_writel(atdma, CHER, AT_DMA_SUSP(chan_id)); |
939 | set_bit(ATC_IS_PAUSED, &atchan->status); | ||
783 | 940 | ||
784 | /* confirm that this channel is disabled */ | 941 | spin_unlock_bh(&atchan->lock); |
785 | while (dma_readl(atdma, CHSR) & atchan->mask) | 942 | } else if (cmd == DMA_RESUME) { |
786 | cpu_relax(); | 943 | if (!test_bit(ATC_IS_PAUSED, &atchan->status)) |
944 | return 0; | ||
787 | 945 | ||
788 | /* active_list entries will end up before queued entries */ | 946 | spin_lock_bh(&atchan->lock); |
789 | list_splice_init(&atchan->queue, &list); | ||
790 | list_splice_init(&atchan->active_list, &list); | ||
791 | 947 | ||
792 | /* Flush all pending and queued descriptors */ | 948 | dma_writel(atdma, CHDR, AT_DMA_RES(chan_id)); |
793 | list_for_each_entry_safe(desc, _desc, &list, desc_node) | 949 | clear_bit(ATC_IS_PAUSED, &atchan->status); |
794 | atc_chain_complete(atchan, desc); | ||
795 | 950 | ||
796 | spin_unlock_bh(&atchan->lock); | 951 | spin_unlock_bh(&atchan->lock); |
952 | } else if (cmd == DMA_TERMINATE_ALL) { | ||
953 | struct at_desc *desc, *_desc; | ||
954 | /* | ||
955 | * This is only called when something went wrong elsewhere, so | ||
956 | * we don't really care about the data. Just disable the | ||
957 | * channel. We still have to poll the channel enable bit due | ||
958 | * to AHB/HSB limitations. | ||
959 | */ | ||
960 | spin_lock_bh(&atchan->lock); | ||
961 | |||
962 | /* disabling channel: must also remove suspend state */ | ||
963 | dma_writel(atdma, CHDR, AT_DMA_RES(chan_id) | atchan->mask); | ||
964 | |||
965 | /* confirm that this channel is disabled */ | ||
966 | while (dma_readl(atdma, CHSR) & atchan->mask) | ||
967 | cpu_relax(); | ||
968 | |||
969 | /* active_list entries will end up before queued entries */ | ||
970 | list_splice_init(&atchan->queue, &list); | ||
971 | list_splice_init(&atchan->active_list, &list); | ||
972 | |||
973 | /* Flush all pending and queued descriptors */ | ||
974 | list_for_each_entry_safe(desc, _desc, &list, desc_node) | ||
975 | atc_chain_complete(atchan, desc); | ||
976 | |||
977 | clear_bit(ATC_IS_PAUSED, &atchan->status); | ||
978 | /* if channel dedicated to cyclic operations, free it */ | ||
979 | clear_bit(ATC_IS_CYCLIC, &atchan->status); | ||
980 | |||
981 | spin_unlock_bh(&atchan->lock); | ||
982 | } else { | ||
983 | return -ENXIO; | ||
984 | } | ||
797 | 985 | ||
798 | return 0; | 986 | return 0; |
799 | } | 987 | } |
@@ -835,9 +1023,17 @@ atc_tx_status(struct dma_chan *chan, | |||
835 | 1023 | ||
836 | spin_unlock_bh(&atchan->lock); | 1024 | spin_unlock_bh(&atchan->lock); |
837 | 1025 | ||
838 | dma_set_tx_state(txstate, last_complete, last_used, 0); | 1026 | if (ret != DMA_SUCCESS) |
839 | dev_vdbg(chan2dev(chan), "tx_status: %d (d%d, u%d)\n", | 1027 | dma_set_tx_state(txstate, last_complete, last_used, |
840 | cookie, last_complete ? last_complete : 0, | 1028 | atc_first_active(atchan)->len); |
1029 | else | ||
1030 | dma_set_tx_state(txstate, last_complete, last_used, 0); | ||
1031 | |||
1032 | if (test_bit(ATC_IS_PAUSED, &atchan->status)) | ||
1033 | ret = DMA_PAUSED; | ||
1034 | |||
1035 | dev_vdbg(chan2dev(chan), "tx_status %d: cookie = %d (d%d, u%d)\n", | ||
1036 | ret, cookie, last_complete ? last_complete : 0, | ||
841 | last_used ? last_used : 0); | 1037 | last_used ? last_used : 0); |
842 | 1038 | ||
843 | return ret; | 1039 | return ret; |
@@ -853,6 +1049,10 @@ static void atc_issue_pending(struct dma_chan *chan) | |||
853 | 1049 | ||
854 | dev_vdbg(chan2dev(chan), "issue_pending\n"); | 1050 | dev_vdbg(chan2dev(chan), "issue_pending\n"); |
855 | 1051 | ||
1052 | /* Not needed for cyclic transfers */ | ||
1053 | if (test_bit(ATC_IS_CYCLIC, &atchan->status)) | ||
1054 | return; | ||
1055 | |||
856 | spin_lock_bh(&atchan->lock); | 1056 | spin_lock_bh(&atchan->lock); |
857 | if (!atc_chan_is_enabled(atchan)) { | 1057 | if (!atc_chan_is_enabled(atchan)) { |
858 | atc_advance_work(atchan); | 1058 | atc_advance_work(atchan); |
@@ -959,6 +1159,7 @@ static void atc_free_chan_resources(struct dma_chan *chan) | |||
959 | } | 1159 | } |
960 | list_splice_init(&atchan->free_list, &list); | 1160 | list_splice_init(&atchan->free_list, &list); |
961 | atchan->descs_allocated = 0; | 1161 | atchan->descs_allocated = 0; |
1162 | atchan->status = 0; | ||
962 | 1163 | ||
963 | dev_vdbg(chan2dev(chan), "free_chan_resources: done\n"); | 1164 | dev_vdbg(chan2dev(chan), "free_chan_resources: done\n"); |
964 | } | 1165 | } |
@@ -1092,10 +1293,15 @@ static int __init at_dma_probe(struct platform_device *pdev) | |||
1092 | if (dma_has_cap(DMA_MEMCPY, atdma->dma_common.cap_mask)) | 1293 | if (dma_has_cap(DMA_MEMCPY, atdma->dma_common.cap_mask)) |
1093 | atdma->dma_common.device_prep_dma_memcpy = atc_prep_dma_memcpy; | 1294 | atdma->dma_common.device_prep_dma_memcpy = atc_prep_dma_memcpy; |
1094 | 1295 | ||
1095 | if (dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask)) { | 1296 | if (dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask)) |
1096 | atdma->dma_common.device_prep_slave_sg = atc_prep_slave_sg; | 1297 | atdma->dma_common.device_prep_slave_sg = atc_prep_slave_sg; |
1298 | |||
1299 | if (dma_has_cap(DMA_CYCLIC, atdma->dma_common.cap_mask)) | ||
1300 | atdma->dma_common.device_prep_dma_cyclic = atc_prep_dma_cyclic; | ||
1301 | |||
1302 | if (dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask) || | ||
1303 | dma_has_cap(DMA_CYCLIC, atdma->dma_common.cap_mask)) | ||
1097 | atdma->dma_common.device_control = atc_control; | 1304 | atdma->dma_common.device_control = atc_control; |
1098 | } | ||
1099 | 1305 | ||
1100 | dma_writel(atdma, EN, AT_DMA_ENABLE); | 1306 | dma_writel(atdma, EN, AT_DMA_ENABLE); |
1101 | 1307 | ||
diff --git a/drivers/dma/at_hdmac_regs.h b/drivers/dma/at_hdmac_regs.h index 495457e3dc4b..087dbf1dd39c 100644 --- a/drivers/dma/at_hdmac_regs.h +++ b/drivers/dma/at_hdmac_regs.h | |||
@@ -103,6 +103,10 @@ | |||
103 | /* Bitfields in CTRLB */ | 103 | /* Bitfields in CTRLB */ |
104 | #define ATC_SIF(i) (0x3 & (i)) /* Src tx done via AHB-Lite Interface i */ | 104 | #define ATC_SIF(i) (0x3 & (i)) /* Src tx done via AHB-Lite Interface i */ |
105 | #define ATC_DIF(i) ((0x3 & (i)) << 4) /* Dst tx done via AHB-Lite Interface i */ | 105 | #define ATC_DIF(i) ((0x3 & (i)) << 4) /* Dst tx done via AHB-Lite Interface i */ |
106 | /* Specify AHB interfaces */ | ||
107 | #define AT_DMA_MEM_IF 0 /* interface 0 as memory interface */ | ||
108 | #define AT_DMA_PER_IF 1 /* interface 1 as peripheral interface */ | ||
109 | |||
106 | #define ATC_SRC_PIP (0x1 << 8) /* Source Picture-in-Picture enabled */ | 110 | #define ATC_SRC_PIP (0x1 << 8) /* Source Picture-in-Picture enabled */ |
107 | #define ATC_DST_PIP (0x1 << 12) /* Destination Picture-in-Picture enabled */ | 111 | #define ATC_DST_PIP (0x1 << 12) /* Destination Picture-in-Picture enabled */ |
108 | #define ATC_SRC_DSCR_DIS (0x1 << 16) /* Src Descriptor fetch disable */ | 112 | #define ATC_SRC_DSCR_DIS (0x1 << 16) /* Src Descriptor fetch disable */ |
@@ -181,12 +185,23 @@ txd_to_at_desc(struct dma_async_tx_descriptor *txd) | |||
181 | /*-- Channels --------------------------------------------------------*/ | 185 | /*-- Channels --------------------------------------------------------*/ |
182 | 186 | ||
183 | /** | 187 | /** |
188 | * atc_status - information bits stored in channel status flag | ||
189 | * | ||
190 | * Manipulated with atomic operations. | ||
191 | */ | ||
192 | enum atc_status { | ||
193 | ATC_IS_ERROR = 0, | ||
194 | ATC_IS_PAUSED = 1, | ||
195 | ATC_IS_CYCLIC = 24, | ||
196 | }; | ||
197 | |||
198 | /** | ||
184 | * struct at_dma_chan - internal representation of an Atmel HDMAC channel | 199 | * struct at_dma_chan - internal representation of an Atmel HDMAC channel |
185 | * @chan_common: common dmaengine channel object members | 200 | * @chan_common: common dmaengine channel object members |
186 | * @device: parent device | 201 | * @device: parent device |
187 | * @ch_regs: memory mapped register base | 202 | * @ch_regs: memory mapped register base |
188 | * @mask: channel index in a mask | 203 | * @mask: channel index in a mask |
189 | * @error_status: transmit error status information from irq handler | 204 | * @status: transmit status information from irq/prep* functions |
190 | * to tasklet (use atomic operations) | 205 | * to tasklet (use atomic operations) |
191 | * @tasklet: bottom half to finish transaction work | 206 | * @tasklet: bottom half to finish transaction work |
192 | * @lock: serializes enqueue/dequeue operations to descriptors lists | 207 | * @lock: serializes enqueue/dequeue operations to descriptors lists |
@@ -201,7 +216,7 @@ struct at_dma_chan { | |||
201 | struct at_dma *device; | 216 | struct at_dma *device; |
202 | void __iomem *ch_regs; | 217 | void __iomem *ch_regs; |
203 | u8 mask; | 218 | u8 mask; |
204 | unsigned long error_status; | 219 | unsigned long status; |
205 | struct tasklet_struct tasklet; | 220 | struct tasklet_struct tasklet; |
206 | 221 | ||
207 | spinlock_t lock; | 222 | spinlock_t lock; |
@@ -309,8 +324,8 @@ static void atc_setup_irq(struct at_dma_chan *atchan, int on) | |||
309 | struct at_dma *atdma = to_at_dma(atchan->chan_common.device); | 324 | struct at_dma *atdma = to_at_dma(atchan->chan_common.device); |
310 | u32 ebci; | 325 | u32 ebci; |
311 | 326 | ||
312 | /* enable interrupts on buffer chain completion & error */ | 327 | /* enable interrupts on buffer transfer completion & error */ |
313 | ebci = AT_DMA_CBTC(atchan->chan_common.chan_id) | 328 | ebci = AT_DMA_BTC(atchan->chan_common.chan_id) |
314 | | AT_DMA_ERR(atchan->chan_common.chan_id); | 329 | | AT_DMA_ERR(atchan->chan_common.chan_id); |
315 | if (on) | 330 | if (on) |
316 | dma_writel(atdma, EBCIER, ebci); | 331 | dma_writel(atdma, EBCIER, ebci); |
@@ -347,7 +362,12 @@ static inline int atc_chan_is_enabled(struct at_dma_chan *atchan) | |||
347 | */ | 362 | */ |
348 | static void set_desc_eol(struct at_desc *desc) | 363 | static void set_desc_eol(struct at_desc *desc) |
349 | { | 364 | { |
350 | desc->lli.ctrlb |= ATC_SRC_DSCR_DIS | ATC_DST_DSCR_DIS; | 365 | u32 ctrlb = desc->lli.ctrlb; |
366 | |||
367 | ctrlb &= ~ATC_IEN; | ||
368 | ctrlb |= ATC_SRC_DSCR_DIS | ATC_DST_DSCR_DIS; | ||
369 | |||
370 | desc->lli.ctrlb = ctrlb; | ||
351 | desc->lli.dscr = 0; | 371 | desc->lli.dscr = 0; |
352 | } | 372 | } |
353 | 373 | ||
diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c index f48e54006518..af8c0b5ed70f 100644 --- a/drivers/dma/coh901318.c +++ b/drivers/dma/coh901318.c | |||
@@ -1610,7 +1610,7 @@ int __init coh901318_init(void) | |||
1610 | { | 1610 | { |
1611 | return platform_driver_probe(&coh901318_driver, coh901318_probe); | 1611 | return platform_driver_probe(&coh901318_driver, coh901318_probe); |
1612 | } | 1612 | } |
1613 | arch_initcall(coh901318_init); | 1613 | subsys_initcall(coh901318_init); |
1614 | 1614 | ||
1615 | void __exit coh901318_exit(void) | 1615 | void __exit coh901318_exit(void) |
1616 | { | 1616 | { |
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index 2a2e2fa00e91..4d180ca9a1d8 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * AVR32 systems.) | 3 | * AVR32 systems.) |
4 | * | 4 | * |
5 | * Copyright (C) 2007-2008 Atmel Corporation | 5 | * Copyright (C) 2007-2008 Atmel Corporation |
6 | * Copyright (C) 2010-2011 ST Microelectronics | ||
6 | * | 7 | * |
7 | * 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 |
8 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
@@ -93,8 +94,9 @@ static struct dw_desc *dwc_desc_get(struct dw_dma_chan *dwc) | |||
93 | struct dw_desc *desc, *_desc; | 94 | struct dw_desc *desc, *_desc; |
94 | struct dw_desc *ret = NULL; | 95 | struct dw_desc *ret = NULL; |
95 | unsigned int i = 0; | 96 | unsigned int i = 0; |
97 | unsigned long flags; | ||
96 | 98 | ||
97 | spin_lock_bh(&dwc->lock); | 99 | spin_lock_irqsave(&dwc->lock, flags); |
98 | list_for_each_entry_safe(desc, _desc, &dwc->free_list, desc_node) { | 100 | list_for_each_entry_safe(desc, _desc, &dwc->free_list, desc_node) { |
99 | if (async_tx_test_ack(&desc->txd)) { | 101 | if (async_tx_test_ack(&desc->txd)) { |
100 | list_del(&desc->desc_node); | 102 | list_del(&desc->desc_node); |
@@ -104,7 +106,7 @@ static struct dw_desc *dwc_desc_get(struct dw_dma_chan *dwc) | |||
104 | dev_dbg(chan2dev(&dwc->chan), "desc %p not ACKed\n", desc); | 106 | dev_dbg(chan2dev(&dwc->chan), "desc %p not ACKed\n", desc); |
105 | i++; | 107 | i++; |
106 | } | 108 | } |
107 | spin_unlock_bh(&dwc->lock); | 109 | spin_unlock_irqrestore(&dwc->lock, flags); |
108 | 110 | ||
109 | dev_vdbg(chan2dev(&dwc->chan), "scanned %u descriptors on freelist\n", i); | 111 | dev_vdbg(chan2dev(&dwc->chan), "scanned %u descriptors on freelist\n", i); |
110 | 112 | ||
@@ -130,12 +132,14 @@ static void dwc_sync_desc_for_cpu(struct dw_dma_chan *dwc, struct dw_desc *desc) | |||
130 | */ | 132 | */ |
131 | static void dwc_desc_put(struct dw_dma_chan *dwc, struct dw_desc *desc) | 133 | static void dwc_desc_put(struct dw_dma_chan *dwc, struct dw_desc *desc) |
132 | { | 134 | { |
135 | unsigned long flags; | ||
136 | |||
133 | if (desc) { | 137 | if (desc) { |
134 | struct dw_desc *child; | 138 | struct dw_desc *child; |
135 | 139 | ||
136 | dwc_sync_desc_for_cpu(dwc, desc); | 140 | dwc_sync_desc_for_cpu(dwc, desc); |
137 | 141 | ||
138 | spin_lock_bh(&dwc->lock); | 142 | spin_lock_irqsave(&dwc->lock, flags); |
139 | list_for_each_entry(child, &desc->tx_list, desc_node) | 143 | list_for_each_entry(child, &desc->tx_list, desc_node) |
140 | dev_vdbg(chan2dev(&dwc->chan), | 144 | dev_vdbg(chan2dev(&dwc->chan), |
141 | "moving child desc %p to freelist\n", | 145 | "moving child desc %p to freelist\n", |
@@ -143,7 +147,7 @@ static void dwc_desc_put(struct dw_dma_chan *dwc, struct dw_desc *desc) | |||
143 | list_splice_init(&desc->tx_list, &dwc->free_list); | 147 | list_splice_init(&desc->tx_list, &dwc->free_list); |
144 | dev_vdbg(chan2dev(&dwc->chan), "moving desc %p to freelist\n", desc); | 148 | dev_vdbg(chan2dev(&dwc->chan), "moving desc %p to freelist\n", desc); |
145 | list_add(&desc->desc_node, &dwc->free_list); | 149 | list_add(&desc->desc_node, &dwc->free_list); |
146 | spin_unlock_bh(&dwc->lock); | 150 | spin_unlock_irqrestore(&dwc->lock, flags); |
147 | } | 151 | } |
148 | } | 152 | } |
149 | 153 | ||
@@ -195,18 +199,23 @@ static void dwc_dostart(struct dw_dma_chan *dwc, struct dw_desc *first) | |||
195 | /*----------------------------------------------------------------------*/ | 199 | /*----------------------------------------------------------------------*/ |
196 | 200 | ||
197 | static void | 201 | static void |
198 | dwc_descriptor_complete(struct dw_dma_chan *dwc, struct dw_desc *desc) | 202 | dwc_descriptor_complete(struct dw_dma_chan *dwc, struct dw_desc *desc, |
203 | bool callback_required) | ||
199 | { | 204 | { |
200 | dma_async_tx_callback callback; | 205 | dma_async_tx_callback callback = NULL; |
201 | void *param; | 206 | void *param = NULL; |
202 | struct dma_async_tx_descriptor *txd = &desc->txd; | 207 | struct dma_async_tx_descriptor *txd = &desc->txd; |
203 | struct dw_desc *child; | 208 | struct dw_desc *child; |
209 | unsigned long flags; | ||
204 | 210 | ||
205 | dev_vdbg(chan2dev(&dwc->chan), "descriptor %u complete\n", txd->cookie); | 211 | dev_vdbg(chan2dev(&dwc->chan), "descriptor %u complete\n", txd->cookie); |
206 | 212 | ||
213 | spin_lock_irqsave(&dwc->lock, flags); | ||
207 | dwc->completed = txd->cookie; | 214 | dwc->completed = txd->cookie; |
208 | callback = txd->callback; | 215 | if (callback_required) { |
209 | param = txd->callback_param; | 216 | callback = txd->callback; |
217 | param = txd->callback_param; | ||
218 | } | ||
210 | 219 | ||
211 | dwc_sync_desc_for_cpu(dwc, desc); | 220 | dwc_sync_desc_for_cpu(dwc, desc); |
212 | 221 | ||
@@ -238,11 +247,9 @@ dwc_descriptor_complete(struct dw_dma_chan *dwc, struct dw_desc *desc) | |||
238 | } | 247 | } |
239 | } | 248 | } |
240 | 249 | ||
241 | /* | 250 | spin_unlock_irqrestore(&dwc->lock, flags); |
242 | * The API requires that no submissions are done from a | 251 | |
243 | * callback, so we don't need to drop the lock here | 252 | if (callback_required && callback) |
244 | */ | ||
245 | if (callback) | ||
246 | callback(param); | 253 | callback(param); |
247 | } | 254 | } |
248 | 255 | ||
@@ -250,7 +257,9 @@ static void dwc_complete_all(struct dw_dma *dw, struct dw_dma_chan *dwc) | |||
250 | { | 257 | { |
251 | struct dw_desc *desc, *_desc; | 258 | struct dw_desc *desc, *_desc; |
252 | LIST_HEAD(list); | 259 | LIST_HEAD(list); |
260 | unsigned long flags; | ||
253 | 261 | ||
262 | spin_lock_irqsave(&dwc->lock, flags); | ||
254 | if (dma_readl(dw, CH_EN) & dwc->mask) { | 263 | if (dma_readl(dw, CH_EN) & dwc->mask) { |
255 | dev_err(chan2dev(&dwc->chan), | 264 | dev_err(chan2dev(&dwc->chan), |
256 | "BUG: XFER bit set, but channel not idle!\n"); | 265 | "BUG: XFER bit set, but channel not idle!\n"); |
@@ -271,8 +280,10 @@ static void dwc_complete_all(struct dw_dma *dw, struct dw_dma_chan *dwc) | |||
271 | dwc_dostart(dwc, dwc_first_active(dwc)); | 280 | dwc_dostart(dwc, dwc_first_active(dwc)); |
272 | } | 281 | } |
273 | 282 | ||
283 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
284 | |||
274 | list_for_each_entry_safe(desc, _desc, &list, desc_node) | 285 | list_for_each_entry_safe(desc, _desc, &list, desc_node) |
275 | dwc_descriptor_complete(dwc, desc); | 286 | dwc_descriptor_complete(dwc, desc, true); |
276 | } | 287 | } |
277 | 288 | ||
278 | static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc) | 289 | static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc) |
@@ -281,7 +292,9 @@ static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc) | |||
281 | struct dw_desc *desc, *_desc; | 292 | struct dw_desc *desc, *_desc; |
282 | struct dw_desc *child; | 293 | struct dw_desc *child; |
283 | u32 status_xfer; | 294 | u32 status_xfer; |
295 | unsigned long flags; | ||
284 | 296 | ||
297 | spin_lock_irqsave(&dwc->lock, flags); | ||
285 | /* | 298 | /* |
286 | * Clear block interrupt flag before scanning so that we don't | 299 | * Clear block interrupt flag before scanning so that we don't |
287 | * miss any, and read LLP before RAW_XFER to ensure it is | 300 | * miss any, and read LLP before RAW_XFER to ensure it is |
@@ -294,30 +307,47 @@ static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc) | |||
294 | if (status_xfer & dwc->mask) { | 307 | if (status_xfer & dwc->mask) { |
295 | /* Everything we've submitted is done */ | 308 | /* Everything we've submitted is done */ |
296 | dma_writel(dw, CLEAR.XFER, dwc->mask); | 309 | dma_writel(dw, CLEAR.XFER, dwc->mask); |
310 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
311 | |||
297 | dwc_complete_all(dw, dwc); | 312 | dwc_complete_all(dw, dwc); |
298 | return; | 313 | return; |
299 | } | 314 | } |
300 | 315 | ||
301 | if (list_empty(&dwc->active_list)) | 316 | if (list_empty(&dwc->active_list)) { |
317 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
302 | return; | 318 | return; |
319 | } | ||
303 | 320 | ||
304 | dev_vdbg(chan2dev(&dwc->chan), "scan_descriptors: llp=0x%x\n", llp); | 321 | dev_vdbg(chan2dev(&dwc->chan), "scan_descriptors: llp=0x%x\n", llp); |
305 | 322 | ||
306 | list_for_each_entry_safe(desc, _desc, &dwc->active_list, desc_node) { | 323 | list_for_each_entry_safe(desc, _desc, &dwc->active_list, desc_node) { |
307 | if (desc->lli.llp == llp) | 324 | /* check first descriptors addr */ |
325 | if (desc->txd.phys == llp) { | ||
326 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
327 | return; | ||
328 | } | ||
329 | |||
330 | /* check first descriptors llp */ | ||
331 | if (desc->lli.llp == llp) { | ||
308 | /* This one is currently in progress */ | 332 | /* This one is currently in progress */ |
333 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
309 | return; | 334 | return; |
335 | } | ||
310 | 336 | ||
311 | list_for_each_entry(child, &desc->tx_list, desc_node) | 337 | list_for_each_entry(child, &desc->tx_list, desc_node) |
312 | if (child->lli.llp == llp) | 338 | if (child->lli.llp == llp) { |
313 | /* Currently in progress */ | 339 | /* Currently in progress */ |
340 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
314 | return; | 341 | return; |
342 | } | ||
315 | 343 | ||
316 | /* | 344 | /* |
317 | * No descriptors so far seem to be in progress, i.e. | 345 | * No descriptors so far seem to be in progress, i.e. |
318 | * this one must be done. | 346 | * this one must be done. |
319 | */ | 347 | */ |
320 | dwc_descriptor_complete(dwc, desc); | 348 | spin_unlock_irqrestore(&dwc->lock, flags); |
349 | dwc_descriptor_complete(dwc, desc, true); | ||
350 | spin_lock_irqsave(&dwc->lock, flags); | ||
321 | } | 351 | } |
322 | 352 | ||
323 | dev_err(chan2dev(&dwc->chan), | 353 | dev_err(chan2dev(&dwc->chan), |
@@ -332,6 +362,7 @@ static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc) | |||
332 | list_move(dwc->queue.next, &dwc->active_list); | 362 | list_move(dwc->queue.next, &dwc->active_list); |
333 | dwc_dostart(dwc, dwc_first_active(dwc)); | 363 | dwc_dostart(dwc, dwc_first_active(dwc)); |
334 | } | 364 | } |
365 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
335 | } | 366 | } |
336 | 367 | ||
337 | static void dwc_dump_lli(struct dw_dma_chan *dwc, struct dw_lli *lli) | 368 | static void dwc_dump_lli(struct dw_dma_chan *dwc, struct dw_lli *lli) |
@@ -346,9 +377,12 @@ static void dwc_handle_error(struct dw_dma *dw, struct dw_dma_chan *dwc) | |||
346 | { | 377 | { |
347 | struct dw_desc *bad_desc; | 378 | struct dw_desc *bad_desc; |
348 | struct dw_desc *child; | 379 | struct dw_desc *child; |
380 | unsigned long flags; | ||
349 | 381 | ||
350 | dwc_scan_descriptors(dw, dwc); | 382 | dwc_scan_descriptors(dw, dwc); |
351 | 383 | ||
384 | spin_lock_irqsave(&dwc->lock, flags); | ||
385 | |||
352 | /* | 386 | /* |
353 | * The descriptor currently at the head of the active list is | 387 | * The descriptor currently at the head of the active list is |
354 | * borked. Since we don't have any way to report errors, we'll | 388 | * borked. Since we don't have any way to report errors, we'll |
@@ -378,8 +412,10 @@ static void dwc_handle_error(struct dw_dma *dw, struct dw_dma_chan *dwc) | |||
378 | list_for_each_entry(child, &bad_desc->tx_list, desc_node) | 412 | list_for_each_entry(child, &bad_desc->tx_list, desc_node) |
379 | dwc_dump_lli(dwc, &child->lli); | 413 | dwc_dump_lli(dwc, &child->lli); |
380 | 414 | ||
415 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
416 | |||
381 | /* Pretend the descriptor completed successfully */ | 417 | /* Pretend the descriptor completed successfully */ |
382 | dwc_descriptor_complete(dwc, bad_desc); | 418 | dwc_descriptor_complete(dwc, bad_desc, true); |
383 | } | 419 | } |
384 | 420 | ||
385 | /* --------------------- Cyclic DMA API extensions -------------------- */ | 421 | /* --------------------- Cyclic DMA API extensions -------------------- */ |
@@ -402,6 +438,8 @@ EXPORT_SYMBOL(dw_dma_get_dst_addr); | |||
402 | static void dwc_handle_cyclic(struct dw_dma *dw, struct dw_dma_chan *dwc, | 438 | static void dwc_handle_cyclic(struct dw_dma *dw, struct dw_dma_chan *dwc, |
403 | u32 status_block, u32 status_err, u32 status_xfer) | 439 | u32 status_block, u32 status_err, u32 status_xfer) |
404 | { | 440 | { |
441 | unsigned long flags; | ||
442 | |||
405 | if (status_block & dwc->mask) { | 443 | if (status_block & dwc->mask) { |
406 | void (*callback)(void *param); | 444 | void (*callback)(void *param); |
407 | void *callback_param; | 445 | void *callback_param; |
@@ -412,11 +450,9 @@ static void dwc_handle_cyclic(struct dw_dma *dw, struct dw_dma_chan *dwc, | |||
412 | 450 | ||
413 | callback = dwc->cdesc->period_callback; | 451 | callback = dwc->cdesc->period_callback; |
414 | callback_param = dwc->cdesc->period_callback_param; | 452 | callback_param = dwc->cdesc->period_callback_param; |
415 | if (callback) { | 453 | |
416 | spin_unlock(&dwc->lock); | 454 | if (callback) |
417 | callback(callback_param); | 455 | callback(callback_param); |
418 | spin_lock(&dwc->lock); | ||
419 | } | ||
420 | } | 456 | } |
421 | 457 | ||
422 | /* | 458 | /* |
@@ -430,6 +466,9 @@ static void dwc_handle_cyclic(struct dw_dma *dw, struct dw_dma_chan *dwc, | |||
430 | dev_err(chan2dev(&dwc->chan), "cyclic DMA unexpected %s " | 466 | dev_err(chan2dev(&dwc->chan), "cyclic DMA unexpected %s " |
431 | "interrupt, stopping DMA transfer\n", | 467 | "interrupt, stopping DMA transfer\n", |
432 | status_xfer ? "xfer" : "error"); | 468 | status_xfer ? "xfer" : "error"); |
469 | |||
470 | spin_lock_irqsave(&dwc->lock, flags); | ||
471 | |||
433 | dev_err(chan2dev(&dwc->chan), | 472 | dev_err(chan2dev(&dwc->chan), |
434 | " SAR: 0x%x DAR: 0x%x LLP: 0x%x CTL: 0x%x:%08x\n", | 473 | " SAR: 0x%x DAR: 0x%x LLP: 0x%x CTL: 0x%x:%08x\n", |
435 | channel_readl(dwc, SAR), | 474 | channel_readl(dwc, SAR), |
@@ -453,6 +492,8 @@ static void dwc_handle_cyclic(struct dw_dma *dw, struct dw_dma_chan *dwc, | |||
453 | 492 | ||
454 | for (i = 0; i < dwc->cdesc->periods; i++) | 493 | for (i = 0; i < dwc->cdesc->periods; i++) |
455 | dwc_dump_lli(dwc, &dwc->cdesc->desc[i]->lli); | 494 | dwc_dump_lli(dwc, &dwc->cdesc->desc[i]->lli); |
495 | |||
496 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
456 | } | 497 | } |
457 | } | 498 | } |
458 | 499 | ||
@@ -476,7 +517,6 @@ static void dw_dma_tasklet(unsigned long data) | |||
476 | 517 | ||
477 | for (i = 0; i < dw->dma.chancnt; i++) { | 518 | for (i = 0; i < dw->dma.chancnt; i++) { |
478 | dwc = &dw->chan[i]; | 519 | dwc = &dw->chan[i]; |
479 | spin_lock(&dwc->lock); | ||
480 | if (test_bit(DW_DMA_IS_CYCLIC, &dwc->flags)) | 520 | if (test_bit(DW_DMA_IS_CYCLIC, &dwc->flags)) |
481 | dwc_handle_cyclic(dw, dwc, status_block, status_err, | 521 | dwc_handle_cyclic(dw, dwc, status_block, status_err, |
482 | status_xfer); | 522 | status_xfer); |
@@ -484,7 +524,6 @@ static void dw_dma_tasklet(unsigned long data) | |||
484 | dwc_handle_error(dw, dwc); | 524 | dwc_handle_error(dw, dwc); |
485 | else if ((status_block | status_xfer) & (1 << i)) | 525 | else if ((status_block | status_xfer) & (1 << i)) |
486 | dwc_scan_descriptors(dw, dwc); | 526 | dwc_scan_descriptors(dw, dwc); |
487 | spin_unlock(&dwc->lock); | ||
488 | } | 527 | } |
489 | 528 | ||
490 | /* | 529 | /* |
@@ -539,8 +578,9 @@ static dma_cookie_t dwc_tx_submit(struct dma_async_tx_descriptor *tx) | |||
539 | struct dw_desc *desc = txd_to_dw_desc(tx); | 578 | struct dw_desc *desc = txd_to_dw_desc(tx); |
540 | struct dw_dma_chan *dwc = to_dw_dma_chan(tx->chan); | 579 | struct dw_dma_chan *dwc = to_dw_dma_chan(tx->chan); |
541 | dma_cookie_t cookie; | 580 | dma_cookie_t cookie; |
581 | unsigned long flags; | ||
542 | 582 | ||
543 | spin_lock_bh(&dwc->lock); | 583 | spin_lock_irqsave(&dwc->lock, flags); |
544 | cookie = dwc_assign_cookie(dwc, desc); | 584 | cookie = dwc_assign_cookie(dwc, desc); |
545 | 585 | ||
546 | /* | 586 | /* |
@@ -560,7 +600,7 @@ static dma_cookie_t dwc_tx_submit(struct dma_async_tx_descriptor *tx) | |||
560 | list_add_tail(&desc->desc_node, &dwc->queue); | 600 | list_add_tail(&desc->desc_node, &dwc->queue); |
561 | } | 601 | } |
562 | 602 | ||
563 | spin_unlock_bh(&dwc->lock); | 603 | spin_unlock_irqrestore(&dwc->lock, flags); |
564 | 604 | ||
565 | return cookie; | 605 | return cookie; |
566 | } | 606 | } |
@@ -689,9 +729,15 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
689 | reg = dws->tx_reg; | 729 | reg = dws->tx_reg; |
690 | for_each_sg(sgl, sg, sg_len, i) { | 730 | for_each_sg(sgl, sg, sg_len, i) { |
691 | struct dw_desc *desc; | 731 | struct dw_desc *desc; |
692 | u32 len; | 732 | u32 len, dlen, mem; |
693 | u32 mem; | 733 | |
734 | mem = sg_phys(sg); | ||
735 | len = sg_dma_len(sg); | ||
736 | mem_width = 2; | ||
737 | if (unlikely(mem & 3 || len & 3)) | ||
738 | mem_width = 0; | ||
694 | 739 | ||
740 | slave_sg_todev_fill_desc: | ||
695 | desc = dwc_desc_get(dwc); | 741 | desc = dwc_desc_get(dwc); |
696 | if (!desc) { | 742 | if (!desc) { |
697 | dev_err(chan2dev(chan), | 743 | dev_err(chan2dev(chan), |
@@ -699,16 +745,19 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
699 | goto err_desc_get; | 745 | goto err_desc_get; |
700 | } | 746 | } |
701 | 747 | ||
702 | mem = sg_phys(sg); | ||
703 | len = sg_dma_len(sg); | ||
704 | mem_width = 2; | ||
705 | if (unlikely(mem & 3 || len & 3)) | ||
706 | mem_width = 0; | ||
707 | |||
708 | desc->lli.sar = mem; | 748 | desc->lli.sar = mem; |
709 | desc->lli.dar = reg; | 749 | desc->lli.dar = reg; |
710 | desc->lli.ctllo = ctllo | DWC_CTLL_SRC_WIDTH(mem_width); | 750 | desc->lli.ctllo = ctllo | DWC_CTLL_SRC_WIDTH(mem_width); |
711 | desc->lli.ctlhi = len >> mem_width; | 751 | if ((len >> mem_width) > DWC_MAX_COUNT) { |
752 | dlen = DWC_MAX_COUNT << mem_width; | ||
753 | mem += dlen; | ||
754 | len -= dlen; | ||
755 | } else { | ||
756 | dlen = len; | ||
757 | len = 0; | ||
758 | } | ||
759 | |||
760 | desc->lli.ctlhi = dlen >> mem_width; | ||
712 | 761 | ||
713 | if (!first) { | 762 | if (!first) { |
714 | first = desc; | 763 | first = desc; |
@@ -722,7 +771,10 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
722 | &first->tx_list); | 771 | &first->tx_list); |
723 | } | 772 | } |
724 | prev = desc; | 773 | prev = desc; |
725 | total_len += len; | 774 | total_len += dlen; |
775 | |||
776 | if (len) | ||
777 | goto slave_sg_todev_fill_desc; | ||
726 | } | 778 | } |
727 | break; | 779 | break; |
728 | case DMA_FROM_DEVICE: | 780 | case DMA_FROM_DEVICE: |
@@ -735,15 +787,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
735 | reg = dws->rx_reg; | 787 | reg = dws->rx_reg; |
736 | for_each_sg(sgl, sg, sg_len, i) { | 788 | for_each_sg(sgl, sg, sg_len, i) { |
737 | struct dw_desc *desc; | 789 | struct dw_desc *desc; |
738 | u32 len; | 790 | u32 len, dlen, mem; |
739 | u32 mem; | ||
740 | |||
741 | desc = dwc_desc_get(dwc); | ||
742 | if (!desc) { | ||
743 | dev_err(chan2dev(chan), | ||
744 | "not enough descriptors available\n"); | ||
745 | goto err_desc_get; | ||
746 | } | ||
747 | 791 | ||
748 | mem = sg_phys(sg); | 792 | mem = sg_phys(sg); |
749 | len = sg_dma_len(sg); | 793 | len = sg_dma_len(sg); |
@@ -751,10 +795,26 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
751 | if (unlikely(mem & 3 || len & 3)) | 795 | if (unlikely(mem & 3 || len & 3)) |
752 | mem_width = 0; | 796 | mem_width = 0; |
753 | 797 | ||
798 | slave_sg_fromdev_fill_desc: | ||
799 | desc = dwc_desc_get(dwc); | ||
800 | if (!desc) { | ||
801 | dev_err(chan2dev(chan), | ||
802 | "not enough descriptors available\n"); | ||
803 | goto err_desc_get; | ||
804 | } | ||
805 | |||
754 | desc->lli.sar = reg; | 806 | desc->lli.sar = reg; |
755 | desc->lli.dar = mem; | 807 | desc->lli.dar = mem; |
756 | desc->lli.ctllo = ctllo | DWC_CTLL_DST_WIDTH(mem_width); | 808 | desc->lli.ctllo = ctllo | DWC_CTLL_DST_WIDTH(mem_width); |
757 | desc->lli.ctlhi = len >> reg_width; | 809 | if ((len >> reg_width) > DWC_MAX_COUNT) { |
810 | dlen = DWC_MAX_COUNT << reg_width; | ||
811 | mem += dlen; | ||
812 | len -= dlen; | ||
813 | } else { | ||
814 | dlen = len; | ||
815 | len = 0; | ||
816 | } | ||
817 | desc->lli.ctlhi = dlen >> reg_width; | ||
758 | 818 | ||
759 | if (!first) { | 819 | if (!first) { |
760 | first = desc; | 820 | first = desc; |
@@ -768,7 +828,10 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
768 | &first->tx_list); | 828 | &first->tx_list); |
769 | } | 829 | } |
770 | prev = desc; | 830 | prev = desc; |
771 | total_len += len; | 831 | total_len += dlen; |
832 | |||
833 | if (len) | ||
834 | goto slave_sg_fromdev_fill_desc; | ||
772 | } | 835 | } |
773 | break; | 836 | break; |
774 | default: | 837 | default: |
@@ -799,34 +862,51 @@ static int dwc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, | |||
799 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); | 862 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); |
800 | struct dw_dma *dw = to_dw_dma(chan->device); | 863 | struct dw_dma *dw = to_dw_dma(chan->device); |
801 | struct dw_desc *desc, *_desc; | 864 | struct dw_desc *desc, *_desc; |
865 | unsigned long flags; | ||
866 | u32 cfglo; | ||
802 | LIST_HEAD(list); | 867 | LIST_HEAD(list); |
803 | 868 | ||
804 | /* Only supports DMA_TERMINATE_ALL */ | 869 | if (cmd == DMA_PAUSE) { |
805 | if (cmd != DMA_TERMINATE_ALL) | 870 | spin_lock_irqsave(&dwc->lock, flags); |
806 | return -ENXIO; | ||
807 | 871 | ||
808 | /* | 872 | cfglo = channel_readl(dwc, CFG_LO); |
809 | * This is only called when something went wrong elsewhere, so | 873 | channel_writel(dwc, CFG_LO, cfglo | DWC_CFGL_CH_SUSP); |
810 | * we don't really care about the data. Just disable the | 874 | while (!(channel_readl(dwc, CFG_LO) & DWC_CFGL_FIFO_EMPTY)) |
811 | * channel. We still have to poll the channel enable bit due | 875 | cpu_relax(); |
812 | * to AHB/HSB limitations. | ||
813 | */ | ||
814 | spin_lock_bh(&dwc->lock); | ||
815 | 876 | ||
816 | channel_clear_bit(dw, CH_EN, dwc->mask); | 877 | dwc->paused = true; |
878 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
879 | } else if (cmd == DMA_RESUME) { | ||
880 | if (!dwc->paused) | ||
881 | return 0; | ||
817 | 882 | ||
818 | while (dma_readl(dw, CH_EN) & dwc->mask) | 883 | spin_lock_irqsave(&dwc->lock, flags); |
819 | cpu_relax(); | ||
820 | 884 | ||
821 | /* active_list entries will end up before queued entries */ | 885 | cfglo = channel_readl(dwc, CFG_LO); |
822 | list_splice_init(&dwc->queue, &list); | 886 | channel_writel(dwc, CFG_LO, cfglo & ~DWC_CFGL_CH_SUSP); |
823 | list_splice_init(&dwc->active_list, &list); | 887 | dwc->paused = false; |
824 | 888 | ||
825 | spin_unlock_bh(&dwc->lock); | 889 | spin_unlock_irqrestore(&dwc->lock, flags); |
890 | } else if (cmd == DMA_TERMINATE_ALL) { | ||
891 | spin_lock_irqsave(&dwc->lock, flags); | ||
826 | 892 | ||
827 | /* Flush all pending and queued descriptors */ | 893 | channel_clear_bit(dw, CH_EN, dwc->mask); |
828 | list_for_each_entry_safe(desc, _desc, &list, desc_node) | 894 | while (dma_readl(dw, CH_EN) & dwc->mask) |
829 | dwc_descriptor_complete(dwc, desc); | 895 | cpu_relax(); |
896 | |||
897 | dwc->paused = false; | ||
898 | |||
899 | /* active_list entries will end up before queued entries */ | ||
900 | list_splice_init(&dwc->queue, &list); | ||
901 | list_splice_init(&dwc->active_list, &list); | ||
902 | |||
903 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
904 | |||
905 | /* Flush all pending and queued descriptors */ | ||
906 | list_for_each_entry_safe(desc, _desc, &list, desc_node) | ||
907 | dwc_descriptor_complete(dwc, desc, false); | ||
908 | } else | ||
909 | return -ENXIO; | ||
830 | 910 | ||
831 | return 0; | 911 | return 0; |
832 | } | 912 | } |
@@ -846,9 +926,7 @@ dwc_tx_status(struct dma_chan *chan, | |||
846 | 926 | ||
847 | ret = dma_async_is_complete(cookie, last_complete, last_used); | 927 | ret = dma_async_is_complete(cookie, last_complete, last_used); |
848 | if (ret != DMA_SUCCESS) { | 928 | if (ret != DMA_SUCCESS) { |
849 | spin_lock_bh(&dwc->lock); | ||
850 | dwc_scan_descriptors(to_dw_dma(chan->device), dwc); | 929 | dwc_scan_descriptors(to_dw_dma(chan->device), dwc); |
851 | spin_unlock_bh(&dwc->lock); | ||
852 | 930 | ||
853 | last_complete = dwc->completed; | 931 | last_complete = dwc->completed; |
854 | last_used = chan->cookie; | 932 | last_used = chan->cookie; |
@@ -856,7 +934,14 @@ dwc_tx_status(struct dma_chan *chan, | |||
856 | ret = dma_async_is_complete(cookie, last_complete, last_used); | 934 | ret = dma_async_is_complete(cookie, last_complete, last_used); |
857 | } | 935 | } |
858 | 936 | ||
859 | dma_set_tx_state(txstate, last_complete, last_used, 0); | 937 | if (ret != DMA_SUCCESS) |
938 | dma_set_tx_state(txstate, last_complete, last_used, | ||
939 | dwc_first_active(dwc)->len); | ||
940 | else | ||
941 | dma_set_tx_state(txstate, last_complete, last_used, 0); | ||
942 | |||
943 | if (dwc->paused) | ||
944 | return DMA_PAUSED; | ||
860 | 945 | ||
861 | return ret; | 946 | return ret; |
862 | } | 947 | } |
@@ -865,10 +950,8 @@ static void dwc_issue_pending(struct dma_chan *chan) | |||
865 | { | 950 | { |
866 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); | 951 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); |
867 | 952 | ||
868 | spin_lock_bh(&dwc->lock); | ||
869 | if (!list_empty(&dwc->queue)) | 953 | if (!list_empty(&dwc->queue)) |
870 | dwc_scan_descriptors(to_dw_dma(chan->device), dwc); | 954 | dwc_scan_descriptors(to_dw_dma(chan->device), dwc); |
871 | spin_unlock_bh(&dwc->lock); | ||
872 | } | 955 | } |
873 | 956 | ||
874 | static int dwc_alloc_chan_resources(struct dma_chan *chan) | 957 | static int dwc_alloc_chan_resources(struct dma_chan *chan) |
@@ -880,6 +963,7 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan) | |||
880 | int i; | 963 | int i; |
881 | u32 cfghi; | 964 | u32 cfghi; |
882 | u32 cfglo; | 965 | u32 cfglo; |
966 | unsigned long flags; | ||
883 | 967 | ||
884 | dev_vdbg(chan2dev(chan), "alloc_chan_resources\n"); | 968 | dev_vdbg(chan2dev(chan), "alloc_chan_resources\n"); |
885 | 969 | ||
@@ -917,16 +1001,16 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan) | |||
917 | * doesn't mean what you think it means), and status writeback. | 1001 | * doesn't mean what you think it means), and status writeback. |
918 | */ | 1002 | */ |
919 | 1003 | ||
920 | spin_lock_bh(&dwc->lock); | 1004 | spin_lock_irqsave(&dwc->lock, flags); |
921 | i = dwc->descs_allocated; | 1005 | i = dwc->descs_allocated; |
922 | while (dwc->descs_allocated < NR_DESCS_PER_CHANNEL) { | 1006 | while (dwc->descs_allocated < NR_DESCS_PER_CHANNEL) { |
923 | spin_unlock_bh(&dwc->lock); | 1007 | spin_unlock_irqrestore(&dwc->lock, flags); |
924 | 1008 | ||
925 | desc = kzalloc(sizeof(struct dw_desc), GFP_KERNEL); | 1009 | desc = kzalloc(sizeof(struct dw_desc), GFP_KERNEL); |
926 | if (!desc) { | 1010 | if (!desc) { |
927 | dev_info(chan2dev(chan), | 1011 | dev_info(chan2dev(chan), |
928 | "only allocated %d descriptors\n", i); | 1012 | "only allocated %d descriptors\n", i); |
929 | spin_lock_bh(&dwc->lock); | 1013 | spin_lock_irqsave(&dwc->lock, flags); |
930 | break; | 1014 | break; |
931 | } | 1015 | } |
932 | 1016 | ||
@@ -938,7 +1022,7 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan) | |||
938 | sizeof(desc->lli), DMA_TO_DEVICE); | 1022 | sizeof(desc->lli), DMA_TO_DEVICE); |
939 | dwc_desc_put(dwc, desc); | 1023 | dwc_desc_put(dwc, desc); |
940 | 1024 | ||
941 | spin_lock_bh(&dwc->lock); | 1025 | spin_lock_irqsave(&dwc->lock, flags); |
942 | i = ++dwc->descs_allocated; | 1026 | i = ++dwc->descs_allocated; |
943 | } | 1027 | } |
944 | 1028 | ||
@@ -947,7 +1031,7 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan) | |||
947 | channel_set_bit(dw, MASK.BLOCK, dwc->mask); | 1031 | channel_set_bit(dw, MASK.BLOCK, dwc->mask); |
948 | channel_set_bit(dw, MASK.ERROR, dwc->mask); | 1032 | channel_set_bit(dw, MASK.ERROR, dwc->mask); |
949 | 1033 | ||
950 | spin_unlock_bh(&dwc->lock); | 1034 | spin_unlock_irqrestore(&dwc->lock, flags); |
951 | 1035 | ||
952 | dev_dbg(chan2dev(chan), | 1036 | dev_dbg(chan2dev(chan), |
953 | "alloc_chan_resources allocated %d descriptors\n", i); | 1037 | "alloc_chan_resources allocated %d descriptors\n", i); |
@@ -960,6 +1044,7 @@ static void dwc_free_chan_resources(struct dma_chan *chan) | |||
960 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); | 1044 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); |
961 | struct dw_dma *dw = to_dw_dma(chan->device); | 1045 | struct dw_dma *dw = to_dw_dma(chan->device); |
962 | struct dw_desc *desc, *_desc; | 1046 | struct dw_desc *desc, *_desc; |
1047 | unsigned long flags; | ||
963 | LIST_HEAD(list); | 1048 | LIST_HEAD(list); |
964 | 1049 | ||
965 | dev_dbg(chan2dev(chan), "free_chan_resources (descs allocated=%u)\n", | 1050 | dev_dbg(chan2dev(chan), "free_chan_resources (descs allocated=%u)\n", |
@@ -970,7 +1055,7 @@ static void dwc_free_chan_resources(struct dma_chan *chan) | |||
970 | BUG_ON(!list_empty(&dwc->queue)); | 1055 | BUG_ON(!list_empty(&dwc->queue)); |
971 | BUG_ON(dma_readl(to_dw_dma(chan->device), CH_EN) & dwc->mask); | 1056 | BUG_ON(dma_readl(to_dw_dma(chan->device), CH_EN) & dwc->mask); |
972 | 1057 | ||
973 | spin_lock_bh(&dwc->lock); | 1058 | spin_lock_irqsave(&dwc->lock, flags); |
974 | list_splice_init(&dwc->free_list, &list); | 1059 | list_splice_init(&dwc->free_list, &list); |
975 | dwc->descs_allocated = 0; | 1060 | dwc->descs_allocated = 0; |
976 | 1061 | ||
@@ -979,7 +1064,7 @@ static void dwc_free_chan_resources(struct dma_chan *chan) | |||
979 | channel_clear_bit(dw, MASK.BLOCK, dwc->mask); | 1064 | channel_clear_bit(dw, MASK.BLOCK, dwc->mask); |
980 | channel_clear_bit(dw, MASK.ERROR, dwc->mask); | 1065 | channel_clear_bit(dw, MASK.ERROR, dwc->mask); |
981 | 1066 | ||
982 | spin_unlock_bh(&dwc->lock); | 1067 | spin_unlock_irqrestore(&dwc->lock, flags); |
983 | 1068 | ||
984 | list_for_each_entry_safe(desc, _desc, &list, desc_node) { | 1069 | list_for_each_entry_safe(desc, _desc, &list, desc_node) { |
985 | dev_vdbg(chan2dev(chan), " freeing descriptor %p\n", desc); | 1070 | dev_vdbg(chan2dev(chan), " freeing descriptor %p\n", desc); |
@@ -1004,13 +1089,14 @@ int dw_dma_cyclic_start(struct dma_chan *chan) | |||
1004 | { | 1089 | { |
1005 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); | 1090 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); |
1006 | struct dw_dma *dw = to_dw_dma(dwc->chan.device); | 1091 | struct dw_dma *dw = to_dw_dma(dwc->chan.device); |
1092 | unsigned long flags; | ||
1007 | 1093 | ||
1008 | if (!test_bit(DW_DMA_IS_CYCLIC, &dwc->flags)) { | 1094 | if (!test_bit(DW_DMA_IS_CYCLIC, &dwc->flags)) { |
1009 | dev_err(chan2dev(&dwc->chan), "missing prep for cyclic DMA\n"); | 1095 | dev_err(chan2dev(&dwc->chan), "missing prep for cyclic DMA\n"); |
1010 | return -ENODEV; | 1096 | return -ENODEV; |
1011 | } | 1097 | } |
1012 | 1098 | ||
1013 | spin_lock(&dwc->lock); | 1099 | spin_lock_irqsave(&dwc->lock, flags); |
1014 | 1100 | ||
1015 | /* assert channel is idle */ | 1101 | /* assert channel is idle */ |
1016 | if (dma_readl(dw, CH_EN) & dwc->mask) { | 1102 | if (dma_readl(dw, CH_EN) & dwc->mask) { |
@@ -1023,7 +1109,7 @@ int dw_dma_cyclic_start(struct dma_chan *chan) | |||
1023 | channel_readl(dwc, LLP), | 1109 | channel_readl(dwc, LLP), |
1024 | channel_readl(dwc, CTL_HI), | 1110 | channel_readl(dwc, CTL_HI), |
1025 | channel_readl(dwc, CTL_LO)); | 1111 | channel_readl(dwc, CTL_LO)); |
1026 | spin_unlock(&dwc->lock); | 1112 | spin_unlock_irqrestore(&dwc->lock, flags); |
1027 | return -EBUSY; | 1113 | return -EBUSY; |
1028 | } | 1114 | } |
1029 | 1115 | ||
@@ -1038,7 +1124,7 @@ int dw_dma_cyclic_start(struct dma_chan *chan) | |||
1038 | 1124 | ||
1039 | channel_set_bit(dw, CH_EN, dwc->mask); | 1125 | channel_set_bit(dw, CH_EN, dwc->mask); |
1040 | 1126 | ||
1041 | spin_unlock(&dwc->lock); | 1127 | spin_unlock_irqrestore(&dwc->lock, flags); |
1042 | 1128 | ||
1043 | return 0; | 1129 | return 0; |
1044 | } | 1130 | } |
@@ -1054,14 +1140,15 @@ void dw_dma_cyclic_stop(struct dma_chan *chan) | |||
1054 | { | 1140 | { |
1055 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); | 1141 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); |
1056 | struct dw_dma *dw = to_dw_dma(dwc->chan.device); | 1142 | struct dw_dma *dw = to_dw_dma(dwc->chan.device); |
1143 | unsigned long flags; | ||
1057 | 1144 | ||
1058 | spin_lock(&dwc->lock); | 1145 | spin_lock_irqsave(&dwc->lock, flags); |
1059 | 1146 | ||
1060 | channel_clear_bit(dw, CH_EN, dwc->mask); | 1147 | channel_clear_bit(dw, CH_EN, dwc->mask); |
1061 | while (dma_readl(dw, CH_EN) & dwc->mask) | 1148 | while (dma_readl(dw, CH_EN) & dwc->mask) |
1062 | cpu_relax(); | 1149 | cpu_relax(); |
1063 | 1150 | ||
1064 | spin_unlock(&dwc->lock); | 1151 | spin_unlock_irqrestore(&dwc->lock, flags); |
1065 | } | 1152 | } |
1066 | EXPORT_SYMBOL(dw_dma_cyclic_stop); | 1153 | EXPORT_SYMBOL(dw_dma_cyclic_stop); |
1067 | 1154 | ||
@@ -1090,17 +1177,18 @@ struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan, | |||
1090 | unsigned int reg_width; | 1177 | unsigned int reg_width; |
1091 | unsigned int periods; | 1178 | unsigned int periods; |
1092 | unsigned int i; | 1179 | unsigned int i; |
1180 | unsigned long flags; | ||
1093 | 1181 | ||
1094 | spin_lock_bh(&dwc->lock); | 1182 | spin_lock_irqsave(&dwc->lock, flags); |
1095 | if (!list_empty(&dwc->queue) || !list_empty(&dwc->active_list)) { | 1183 | if (!list_empty(&dwc->queue) || !list_empty(&dwc->active_list)) { |
1096 | spin_unlock_bh(&dwc->lock); | 1184 | spin_unlock_irqrestore(&dwc->lock, flags); |
1097 | dev_dbg(chan2dev(&dwc->chan), | 1185 | dev_dbg(chan2dev(&dwc->chan), |
1098 | "queue and/or active list are not empty\n"); | 1186 | "queue and/or active list are not empty\n"); |
1099 | return ERR_PTR(-EBUSY); | 1187 | return ERR_PTR(-EBUSY); |
1100 | } | 1188 | } |
1101 | 1189 | ||
1102 | was_cyclic = test_and_set_bit(DW_DMA_IS_CYCLIC, &dwc->flags); | 1190 | was_cyclic = test_and_set_bit(DW_DMA_IS_CYCLIC, &dwc->flags); |
1103 | spin_unlock_bh(&dwc->lock); | 1191 | spin_unlock_irqrestore(&dwc->lock, flags); |
1104 | if (was_cyclic) { | 1192 | if (was_cyclic) { |
1105 | dev_dbg(chan2dev(&dwc->chan), | 1193 | dev_dbg(chan2dev(&dwc->chan), |
1106 | "channel already prepared for cyclic DMA\n"); | 1194 | "channel already prepared for cyclic DMA\n"); |
@@ -1214,13 +1302,14 @@ void dw_dma_cyclic_free(struct dma_chan *chan) | |||
1214 | struct dw_dma *dw = to_dw_dma(dwc->chan.device); | 1302 | struct dw_dma *dw = to_dw_dma(dwc->chan.device); |
1215 | struct dw_cyclic_desc *cdesc = dwc->cdesc; | 1303 | struct dw_cyclic_desc *cdesc = dwc->cdesc; |
1216 | int i; | 1304 | int i; |
1305 | unsigned long flags; | ||
1217 | 1306 | ||
1218 | dev_dbg(chan2dev(&dwc->chan), "cyclic free\n"); | 1307 | dev_dbg(chan2dev(&dwc->chan), "cyclic free\n"); |
1219 | 1308 | ||
1220 | if (!cdesc) | 1309 | if (!cdesc) |
1221 | return; | 1310 | return; |
1222 | 1311 | ||
1223 | spin_lock_bh(&dwc->lock); | 1312 | spin_lock_irqsave(&dwc->lock, flags); |
1224 | 1313 | ||
1225 | channel_clear_bit(dw, CH_EN, dwc->mask); | 1314 | channel_clear_bit(dw, CH_EN, dwc->mask); |
1226 | while (dma_readl(dw, CH_EN) & dwc->mask) | 1315 | while (dma_readl(dw, CH_EN) & dwc->mask) |
@@ -1230,7 +1319,7 @@ void dw_dma_cyclic_free(struct dma_chan *chan) | |||
1230 | dma_writel(dw, CLEAR.ERROR, dwc->mask); | 1319 | dma_writel(dw, CLEAR.ERROR, dwc->mask); |
1231 | dma_writel(dw, CLEAR.XFER, dwc->mask); | 1320 | dma_writel(dw, CLEAR.XFER, dwc->mask); |
1232 | 1321 | ||
1233 | spin_unlock_bh(&dwc->lock); | 1322 | spin_unlock_irqrestore(&dwc->lock, flags); |
1234 | 1323 | ||
1235 | for (i = 0; i < cdesc->periods; i++) | 1324 | for (i = 0; i < cdesc->periods; i++) |
1236 | dwc_desc_put(dwc, cdesc->desc[i]); | 1325 | dwc_desc_put(dwc, cdesc->desc[i]); |
@@ -1487,3 +1576,4 @@ module_exit(dw_exit); | |||
1487 | MODULE_LICENSE("GPL v2"); | 1576 | MODULE_LICENSE("GPL v2"); |
1488 | MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller driver"); | 1577 | MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller driver"); |
1489 | MODULE_AUTHOR("Haavard Skinnemoen (Atmel)"); | 1578 | MODULE_AUTHOR("Haavard Skinnemoen (Atmel)"); |
1579 | MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>"); | ||
diff --git a/drivers/dma/dw_dmac_regs.h b/drivers/dma/dw_dmac_regs.h index 720f821527f8..c3419518d701 100644 --- a/drivers/dma/dw_dmac_regs.h +++ b/drivers/dma/dw_dmac_regs.h | |||
@@ -2,6 +2,7 @@ | |||
2 | * Driver for the Synopsys DesignWare AHB DMA Controller | 2 | * Driver for the Synopsys DesignWare AHB DMA Controller |
3 | * | 3 | * |
4 | * Copyright (C) 2005-2007 Atmel Corporation | 4 | * Copyright (C) 2005-2007 Atmel Corporation |
5 | * Copyright (C) 2010-2011 ST Microelectronics | ||
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
@@ -138,6 +139,7 @@ struct dw_dma_chan { | |||
138 | void __iomem *ch_regs; | 139 | void __iomem *ch_regs; |
139 | u8 mask; | 140 | u8 mask; |
140 | u8 priority; | 141 | u8 priority; |
142 | bool paused; | ||
141 | 143 | ||
142 | spinlock_t lock; | 144 | spinlock_t lock; |
143 | 145 | ||
diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c index 3d4ec38b9b62..f653517ef744 100644 --- a/drivers/dma/intel_mid_dma.c +++ b/drivers/dma/intel_mid_dma.c | |||
@@ -1292,8 +1292,7 @@ static int __devinit intel_mid_dma_probe(struct pci_dev *pdev, | |||
1292 | if (err) | 1292 | if (err) |
1293 | goto err_dma; | 1293 | goto err_dma; |
1294 | 1294 | ||
1295 | pm_runtime_set_active(&pdev->dev); | 1295 | pm_runtime_put_noidle(&pdev->dev); |
1296 | pm_runtime_enable(&pdev->dev); | ||
1297 | pm_runtime_allow(&pdev->dev); | 1296 | pm_runtime_allow(&pdev->dev); |
1298 | return 0; | 1297 | return 0; |
1299 | 1298 | ||
@@ -1322,6 +1321,9 @@ err_enable_device: | |||
1322 | static void __devexit intel_mid_dma_remove(struct pci_dev *pdev) | 1321 | static void __devexit intel_mid_dma_remove(struct pci_dev *pdev) |
1323 | { | 1322 | { |
1324 | struct middma_device *device = pci_get_drvdata(pdev); | 1323 | struct middma_device *device = pci_get_drvdata(pdev); |
1324 | |||
1325 | pm_runtime_get_noresume(&pdev->dev); | ||
1326 | pm_runtime_forbid(&pdev->dev); | ||
1325 | middma_shutdown(pdev); | 1327 | middma_shutdown(pdev); |
1326 | pci_dev_put(pdev); | 1328 | pci_dev_put(pdev); |
1327 | kfree(device); | 1329 | kfree(device); |
@@ -1385,13 +1387,20 @@ int dma_resume(struct pci_dev *pci) | |||
1385 | static int dma_runtime_suspend(struct device *dev) | 1387 | static int dma_runtime_suspend(struct device *dev) |
1386 | { | 1388 | { |
1387 | struct pci_dev *pci_dev = to_pci_dev(dev); | 1389 | struct pci_dev *pci_dev = to_pci_dev(dev); |
1388 | return dma_suspend(pci_dev, PMSG_SUSPEND); | 1390 | struct middma_device *device = pci_get_drvdata(pci_dev); |
1391 | |||
1392 | device->state = SUSPENDED; | ||
1393 | return 0; | ||
1389 | } | 1394 | } |
1390 | 1395 | ||
1391 | static int dma_runtime_resume(struct device *dev) | 1396 | static int dma_runtime_resume(struct device *dev) |
1392 | { | 1397 | { |
1393 | struct pci_dev *pci_dev = to_pci_dev(dev); | 1398 | struct pci_dev *pci_dev = to_pci_dev(dev); |
1394 | return dma_resume(pci_dev); | 1399 | struct middma_device *device = pci_get_drvdata(pci_dev); |
1400 | |||
1401 | device->state = RUNNING; | ||
1402 | iowrite32(REG_BIT0, device->dma_base + DMA_CFG); | ||
1403 | return 0; | ||
1395 | } | 1404 | } |
1396 | 1405 | ||
1397 | static int dma_runtime_idle(struct device *dev) | 1406 | static int dma_runtime_idle(struct device *dev) |
diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c index f4a51d4d0349..5d65f8377971 100644 --- a/drivers/dma/ioat/dma_v2.c +++ b/drivers/dma/ioat/dma_v2.c | |||
@@ -508,6 +508,7 @@ int ioat2_alloc_chan_resources(struct dma_chan *c) | |||
508 | struct ioat_ring_ent **ring; | 508 | struct ioat_ring_ent **ring; |
509 | u64 status; | 509 | u64 status; |
510 | int order; | 510 | int order; |
511 | int i = 0; | ||
511 | 512 | ||
512 | /* have we already been set up? */ | 513 | /* have we already been set up? */ |
513 | if (ioat->ring) | 514 | if (ioat->ring) |
@@ -548,8 +549,11 @@ int ioat2_alloc_chan_resources(struct dma_chan *c) | |||
548 | ioat2_start_null_desc(ioat); | 549 | ioat2_start_null_desc(ioat); |
549 | 550 | ||
550 | /* check that we got off the ground */ | 551 | /* check that we got off the ground */ |
551 | udelay(5); | 552 | do { |
552 | status = ioat_chansts(chan); | 553 | udelay(1); |
554 | status = ioat_chansts(chan); | ||
555 | } while (i++ < 20 && !is_ioat_active(status) && !is_ioat_idle(status)); | ||
556 | |||
553 | if (is_ioat_active(status) || is_ioat_idle(status)) { | 557 | if (is_ioat_active(status) || is_ioat_idle(status)) { |
554 | set_bit(IOAT_RUN, &chan->state); | 558 | set_bit(IOAT_RUN, &chan->state); |
555 | return 1 << ioat->alloc_order; | 559 | return 1 << ioat->alloc_order; |
diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c index c6b01f535b29..e03f811a83dd 100644 --- a/drivers/dma/iop-adma.c +++ b/drivers/dma/iop-adma.c | |||
@@ -619,7 +619,7 @@ iop_adma_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dma_dest, | |||
619 | 619 | ||
620 | if (unlikely(!len)) | 620 | if (unlikely(!len)) |
621 | return NULL; | 621 | return NULL; |
622 | BUG_ON(unlikely(len > IOP_ADMA_MAX_BYTE_COUNT)); | 622 | BUG_ON(len > IOP_ADMA_MAX_BYTE_COUNT); |
623 | 623 | ||
624 | dev_dbg(iop_chan->device->common.dev, "%s len: %u\n", | 624 | dev_dbg(iop_chan->device->common.dev, "%s len: %u\n", |
625 | __func__, len); | 625 | __func__, len); |
@@ -652,7 +652,7 @@ iop_adma_prep_dma_memset(struct dma_chan *chan, dma_addr_t dma_dest, | |||
652 | 652 | ||
653 | if (unlikely(!len)) | 653 | if (unlikely(!len)) |
654 | return NULL; | 654 | return NULL; |
655 | BUG_ON(unlikely(len > IOP_ADMA_MAX_BYTE_COUNT)); | 655 | BUG_ON(len > IOP_ADMA_MAX_BYTE_COUNT); |
656 | 656 | ||
657 | dev_dbg(iop_chan->device->common.dev, "%s len: %u\n", | 657 | dev_dbg(iop_chan->device->common.dev, "%s len: %u\n", |
658 | __func__, len); | 658 | __func__, len); |
@@ -686,7 +686,7 @@ iop_adma_prep_dma_xor(struct dma_chan *chan, dma_addr_t dma_dest, | |||
686 | 686 | ||
687 | if (unlikely(!len)) | 687 | if (unlikely(!len)) |
688 | return NULL; | 688 | return NULL; |
689 | BUG_ON(unlikely(len > IOP_ADMA_XOR_MAX_BYTE_COUNT)); | 689 | BUG_ON(len > IOP_ADMA_XOR_MAX_BYTE_COUNT); |
690 | 690 | ||
691 | dev_dbg(iop_chan->device->common.dev, | 691 | dev_dbg(iop_chan->device->common.dev, |
692 | "%s src_cnt: %d len: %u flags: %lx\n", | 692 | "%s src_cnt: %d len: %u flags: %lx\n", |
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index a25f5f61e0e0..954e334e01bb 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c | |||
@@ -671,7 +671,7 @@ mv_xor_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, | |||
671 | if (unlikely(len < MV_XOR_MIN_BYTE_COUNT)) | 671 | if (unlikely(len < MV_XOR_MIN_BYTE_COUNT)) |
672 | return NULL; | 672 | return NULL; |
673 | 673 | ||
674 | BUG_ON(unlikely(len > MV_XOR_MAX_BYTE_COUNT)); | 674 | BUG_ON(len > MV_XOR_MAX_BYTE_COUNT); |
675 | 675 | ||
676 | spin_lock_bh(&mv_chan->lock); | 676 | spin_lock_bh(&mv_chan->lock); |
677 | slot_cnt = mv_chan_memcpy_slot_count(len); | 677 | slot_cnt = mv_chan_memcpy_slot_count(len); |
@@ -710,7 +710,7 @@ mv_xor_prep_dma_memset(struct dma_chan *chan, dma_addr_t dest, int value, | |||
710 | if (unlikely(len < MV_XOR_MIN_BYTE_COUNT)) | 710 | if (unlikely(len < MV_XOR_MIN_BYTE_COUNT)) |
711 | return NULL; | 711 | return NULL; |
712 | 712 | ||
713 | BUG_ON(unlikely(len > MV_XOR_MAX_BYTE_COUNT)); | 713 | BUG_ON(len > MV_XOR_MAX_BYTE_COUNT); |
714 | 714 | ||
715 | spin_lock_bh(&mv_chan->lock); | 715 | spin_lock_bh(&mv_chan->lock); |
716 | slot_cnt = mv_chan_memset_slot_count(len); | 716 | slot_cnt = mv_chan_memset_slot_count(len); |
@@ -744,7 +744,7 @@ mv_xor_prep_dma_xor(struct dma_chan *chan, dma_addr_t dest, dma_addr_t *src, | |||
744 | if (unlikely(len < MV_XOR_MIN_BYTE_COUNT)) | 744 | if (unlikely(len < MV_XOR_MIN_BYTE_COUNT)) |
745 | return NULL; | 745 | return NULL; |
746 | 746 | ||
747 | BUG_ON(unlikely(len > MV_XOR_MAX_BYTE_COUNT)); | 747 | BUG_ON(len > MV_XOR_MAX_BYTE_COUNT); |
748 | 748 | ||
749 | dev_dbg(mv_chan->device->common.dev, | 749 | dev_dbg(mv_chan->device->common.dev, |
750 | "%s src_cnt: %d len: dest %x %u flags: %ld\n", | 750 | "%s src_cnt: %d len: dest %x %u flags: %ld\n", |
diff --git a/drivers/dma/pch_dma.c b/drivers/dma/pch_dma.c index 8d8fef1480a9..ff5b38f9d45b 100644 --- a/drivers/dma/pch_dma.c +++ b/drivers/dma/pch_dma.c | |||
@@ -77,10 +77,10 @@ struct pch_dma_regs { | |||
77 | u32 dma_ctl0; | 77 | u32 dma_ctl0; |
78 | u32 dma_ctl1; | 78 | u32 dma_ctl1; |
79 | u32 dma_ctl2; | 79 | u32 dma_ctl2; |
80 | u32 reserved1; | 80 | u32 dma_ctl3; |
81 | u32 dma_sts0; | 81 | u32 dma_sts0; |
82 | u32 dma_sts1; | 82 | u32 dma_sts1; |
83 | u32 reserved2; | 83 | u32 dma_sts2; |
84 | u32 reserved3; | 84 | u32 reserved3; |
85 | struct pch_dma_desc_regs desc[MAX_CHAN_NR]; | 85 | struct pch_dma_desc_regs desc[MAX_CHAN_NR]; |
86 | }; | 86 | }; |
@@ -130,6 +130,7 @@ struct pch_dma { | |||
130 | #define PCH_DMA_CTL0 0x00 | 130 | #define PCH_DMA_CTL0 0x00 |
131 | #define PCH_DMA_CTL1 0x04 | 131 | #define PCH_DMA_CTL1 0x04 |
132 | #define PCH_DMA_CTL2 0x08 | 132 | #define PCH_DMA_CTL2 0x08 |
133 | #define PCH_DMA_CTL3 0x0C | ||
133 | #define PCH_DMA_STS0 0x10 | 134 | #define PCH_DMA_STS0 0x10 |
134 | #define PCH_DMA_STS1 0x14 | 135 | #define PCH_DMA_STS1 0x14 |
135 | 136 | ||
@@ -138,7 +139,8 @@ struct pch_dma { | |||
138 | #define dma_writel(pd, name, val) \ | 139 | #define dma_writel(pd, name, val) \ |
139 | writel((val), (pd)->membase + PCH_DMA_##name) | 140 | writel((val), (pd)->membase + PCH_DMA_##name) |
140 | 141 | ||
141 | static inline struct pch_dma_desc *to_pd_desc(struct dma_async_tx_descriptor *txd) | 142 | static inline |
143 | struct pch_dma_desc *to_pd_desc(struct dma_async_tx_descriptor *txd) | ||
142 | { | 144 | { |
143 | return container_of(txd, struct pch_dma_desc, txd); | 145 | return container_of(txd, struct pch_dma_desc, txd); |
144 | } | 146 | } |
@@ -163,13 +165,15 @@ static inline struct device *chan2parent(struct dma_chan *chan) | |||
163 | return chan->dev->device.parent; | 165 | return chan->dev->device.parent; |
164 | } | 166 | } |
165 | 167 | ||
166 | static inline struct pch_dma_desc *pdc_first_active(struct pch_dma_chan *pd_chan) | 168 | static inline |
169 | struct pch_dma_desc *pdc_first_active(struct pch_dma_chan *pd_chan) | ||
167 | { | 170 | { |
168 | return list_first_entry(&pd_chan->active_list, | 171 | return list_first_entry(&pd_chan->active_list, |
169 | struct pch_dma_desc, desc_node); | 172 | struct pch_dma_desc, desc_node); |
170 | } | 173 | } |
171 | 174 | ||
172 | static inline struct pch_dma_desc *pdc_first_queued(struct pch_dma_chan *pd_chan) | 175 | static inline |
176 | struct pch_dma_desc *pdc_first_queued(struct pch_dma_chan *pd_chan) | ||
173 | { | 177 | { |
174 | return list_first_entry(&pd_chan->queue, | 178 | return list_first_entry(&pd_chan->queue, |
175 | struct pch_dma_desc, desc_node); | 179 | struct pch_dma_desc, desc_node); |
@@ -199,16 +203,30 @@ static void pdc_set_dir(struct dma_chan *chan) | |||
199 | struct pch_dma *pd = to_pd(chan->device); | 203 | struct pch_dma *pd = to_pd(chan->device); |
200 | u32 val; | 204 | u32 val; |
201 | 205 | ||
202 | val = dma_readl(pd, CTL0); | 206 | if (chan->chan_id < 8) { |
207 | val = dma_readl(pd, CTL0); | ||
203 | 208 | ||
204 | if (pd_chan->dir == DMA_TO_DEVICE) | 209 | if (pd_chan->dir == DMA_TO_DEVICE) |
205 | val |= 0x1 << (DMA_CTL0_BITS_PER_CH * chan->chan_id + | 210 | val |= 0x1 << (DMA_CTL0_BITS_PER_CH * chan->chan_id + |
206 | DMA_CTL0_DIR_SHIFT_BITS); | 211 | DMA_CTL0_DIR_SHIFT_BITS); |
207 | else | 212 | else |
208 | val &= ~(0x1 << (DMA_CTL0_BITS_PER_CH * chan->chan_id + | 213 | val &= ~(0x1 << (DMA_CTL0_BITS_PER_CH * chan->chan_id + |
209 | DMA_CTL0_DIR_SHIFT_BITS)); | 214 | DMA_CTL0_DIR_SHIFT_BITS)); |
215 | |||
216 | dma_writel(pd, CTL0, val); | ||
217 | } else { | ||
218 | int ch = chan->chan_id - 8; /* ch8-->0 ch9-->1 ... ch11->3 */ | ||
219 | val = dma_readl(pd, CTL3); | ||
210 | 220 | ||
211 | dma_writel(pd, CTL0, val); | 221 | if (pd_chan->dir == DMA_TO_DEVICE) |
222 | val |= 0x1 << (DMA_CTL0_BITS_PER_CH * ch + | ||
223 | DMA_CTL0_DIR_SHIFT_BITS); | ||
224 | else | ||
225 | val &= ~(0x1 << (DMA_CTL0_BITS_PER_CH * ch + | ||
226 | DMA_CTL0_DIR_SHIFT_BITS)); | ||
227 | |||
228 | dma_writel(pd, CTL3, val); | ||
229 | } | ||
212 | 230 | ||
213 | dev_dbg(chan2dev(chan), "pdc_set_dir: chan %d -> %x\n", | 231 | dev_dbg(chan2dev(chan), "pdc_set_dir: chan %d -> %x\n", |
214 | chan->chan_id, val); | 232 | chan->chan_id, val); |
@@ -219,13 +237,26 @@ static void pdc_set_mode(struct dma_chan *chan, u32 mode) | |||
219 | struct pch_dma *pd = to_pd(chan->device); | 237 | struct pch_dma *pd = to_pd(chan->device); |
220 | u32 val; | 238 | u32 val; |
221 | 239 | ||
222 | val = dma_readl(pd, CTL0); | 240 | if (chan->chan_id < 8) { |
241 | val = dma_readl(pd, CTL0); | ||
242 | |||
243 | val &= ~(DMA_CTL0_MODE_MASK_BITS << | ||
244 | (DMA_CTL0_BITS_PER_CH * chan->chan_id)); | ||
245 | val |= mode << (DMA_CTL0_BITS_PER_CH * chan->chan_id); | ||
223 | 246 | ||
224 | val &= ~(DMA_CTL0_MODE_MASK_BITS << | 247 | dma_writel(pd, CTL0, val); |
225 | (DMA_CTL0_BITS_PER_CH * chan->chan_id)); | 248 | } else { |
226 | val |= mode << (DMA_CTL0_BITS_PER_CH * chan->chan_id); | 249 | int ch = chan->chan_id - 8; /* ch8-->0 ch9-->1 ... ch11->3 */ |
250 | |||
251 | val = dma_readl(pd, CTL3); | ||
252 | |||
253 | val &= ~(DMA_CTL0_MODE_MASK_BITS << | ||
254 | (DMA_CTL0_BITS_PER_CH * ch)); | ||
255 | val |= mode << (DMA_CTL0_BITS_PER_CH * ch); | ||
227 | 256 | ||
228 | dma_writel(pd, CTL0, val); | 257 | dma_writel(pd, CTL3, val); |
258 | |||
259 | } | ||
229 | 260 | ||
230 | dev_dbg(chan2dev(chan), "pdc_set_mode: chan %d -> %x\n", | 261 | dev_dbg(chan2dev(chan), "pdc_set_mode: chan %d -> %x\n", |
231 | chan->chan_id, val); | 262 | chan->chan_id, val); |
@@ -251,9 +282,6 @@ static bool pdc_is_idle(struct pch_dma_chan *pd_chan) | |||
251 | 282 | ||
252 | static void pdc_dostart(struct pch_dma_chan *pd_chan, struct pch_dma_desc* desc) | 283 | static void pdc_dostart(struct pch_dma_chan *pd_chan, struct pch_dma_desc* desc) |
253 | { | 284 | { |
254 | struct pch_dma *pd = to_pd(pd_chan->chan.device); | ||
255 | u32 val; | ||
256 | |||
257 | if (!pdc_is_idle(pd_chan)) { | 285 | if (!pdc_is_idle(pd_chan)) { |
258 | dev_err(chan2dev(&pd_chan->chan), | 286 | dev_err(chan2dev(&pd_chan->chan), |
259 | "BUG: Attempt to start non-idle channel\n"); | 287 | "BUG: Attempt to start non-idle channel\n"); |
@@ -279,10 +307,6 @@ static void pdc_dostart(struct pch_dma_chan *pd_chan, struct pch_dma_desc* desc) | |||
279 | channel_writel(pd_chan, NEXT, desc->txd.phys); | 307 | channel_writel(pd_chan, NEXT, desc->txd.phys); |
280 | pdc_set_mode(&pd_chan->chan, DMA_CTL0_SG); | 308 | pdc_set_mode(&pd_chan->chan, DMA_CTL0_SG); |
281 | } | 309 | } |
282 | |||
283 | val = dma_readl(pd, CTL2); | ||
284 | val |= 1 << (DMA_CTL2_START_SHIFT_BITS + pd_chan->chan.chan_id); | ||
285 | dma_writel(pd, CTL2, val); | ||
286 | } | 310 | } |
287 | 311 | ||
288 | static void pdc_chain_complete(struct pch_dma_chan *pd_chan, | 312 | static void pdc_chain_complete(struct pch_dma_chan *pd_chan, |
@@ -403,7 +427,7 @@ static struct pch_dma_desc *pdc_desc_get(struct pch_dma_chan *pd_chan) | |||
403 | { | 427 | { |
404 | struct pch_dma_desc *desc, *_d; | 428 | struct pch_dma_desc *desc, *_d; |
405 | struct pch_dma_desc *ret = NULL; | 429 | struct pch_dma_desc *ret = NULL; |
406 | int i; | 430 | int i = 0; |
407 | 431 | ||
408 | spin_lock(&pd_chan->lock); | 432 | spin_lock(&pd_chan->lock); |
409 | list_for_each_entry_safe(desc, _d, &pd_chan->free_list, desc_node) { | 433 | list_for_each_entry_safe(desc, _d, &pd_chan->free_list, desc_node) { |
@@ -478,7 +502,6 @@ static int pd_alloc_chan_resources(struct dma_chan *chan) | |||
478 | spin_unlock_bh(&pd_chan->lock); | 502 | spin_unlock_bh(&pd_chan->lock); |
479 | 503 | ||
480 | pdc_enable_irq(chan, 1); | 504 | pdc_enable_irq(chan, 1); |
481 | pdc_set_dir(chan); | ||
482 | 505 | ||
483 | return pd_chan->descs_allocated; | 506 | return pd_chan->descs_allocated; |
484 | } | 507 | } |
@@ -561,6 +584,9 @@ static struct dma_async_tx_descriptor *pd_prep_slave_sg(struct dma_chan *chan, | |||
561 | else | 584 | else |
562 | return NULL; | 585 | return NULL; |
563 | 586 | ||
587 | pd_chan->dir = direction; | ||
588 | pdc_set_dir(chan); | ||
589 | |||
564 | for_each_sg(sgl, sg, sg_len, i) { | 590 | for_each_sg(sgl, sg, sg_len, i) { |
565 | desc = pdc_desc_get(pd_chan); | 591 | desc = pdc_desc_get(pd_chan); |
566 | 592 | ||
@@ -703,6 +729,7 @@ static void pch_dma_save_regs(struct pch_dma *pd) | |||
703 | pd->regs.dma_ctl0 = dma_readl(pd, CTL0); | 729 | pd->regs.dma_ctl0 = dma_readl(pd, CTL0); |
704 | pd->regs.dma_ctl1 = dma_readl(pd, CTL1); | 730 | pd->regs.dma_ctl1 = dma_readl(pd, CTL1); |
705 | pd->regs.dma_ctl2 = dma_readl(pd, CTL2); | 731 | pd->regs.dma_ctl2 = dma_readl(pd, CTL2); |
732 | pd->regs.dma_ctl3 = dma_readl(pd, CTL3); | ||
706 | 733 | ||
707 | list_for_each_entry_safe(chan, _c, &pd->dma.channels, device_node) { | 734 | list_for_each_entry_safe(chan, _c, &pd->dma.channels, device_node) { |
708 | pd_chan = to_pd_chan(chan); | 735 | pd_chan = to_pd_chan(chan); |
@@ -725,6 +752,7 @@ static void pch_dma_restore_regs(struct pch_dma *pd) | |||
725 | dma_writel(pd, CTL0, pd->regs.dma_ctl0); | 752 | dma_writel(pd, CTL0, pd->regs.dma_ctl0); |
726 | dma_writel(pd, CTL1, pd->regs.dma_ctl1); | 753 | dma_writel(pd, CTL1, pd->regs.dma_ctl1); |
727 | dma_writel(pd, CTL2, pd->regs.dma_ctl2); | 754 | dma_writel(pd, CTL2, pd->regs.dma_ctl2); |
755 | dma_writel(pd, CTL3, pd->regs.dma_ctl3); | ||
728 | 756 | ||
729 | list_for_each_entry_safe(chan, _c, &pd->dma.channels, device_node) { | 757 | list_for_each_entry_safe(chan, _c, &pd->dma.channels, device_node) { |
730 | pd_chan = to_pd_chan(chan); | 758 | pd_chan = to_pd_chan(chan); |
@@ -850,8 +878,6 @@ static int __devinit pch_dma_probe(struct pci_dev *pdev, | |||
850 | 878 | ||
851 | pd_chan->membase = ®s->desc[i]; | 879 | pd_chan->membase = ®s->desc[i]; |
852 | 880 | ||
853 | pd_chan->dir = (i % 2) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; | ||
854 | |||
855 | spin_lock_init(&pd_chan->lock); | 881 | spin_lock_init(&pd_chan->lock); |
856 | 882 | ||
857 | INIT_LIST_HEAD(&pd_chan->active_list); | 883 | INIT_LIST_HEAD(&pd_chan->active_list); |
@@ -929,13 +955,23 @@ static void __devexit pch_dma_remove(struct pci_dev *pdev) | |||
929 | #define PCI_DEVICE_ID_ML7213_DMA1_8CH 0x8026 | 955 | #define PCI_DEVICE_ID_ML7213_DMA1_8CH 0x8026 |
930 | #define PCI_DEVICE_ID_ML7213_DMA2_8CH 0x802B | 956 | #define PCI_DEVICE_ID_ML7213_DMA2_8CH 0x802B |
931 | #define PCI_DEVICE_ID_ML7213_DMA3_4CH 0x8034 | 957 | #define PCI_DEVICE_ID_ML7213_DMA3_4CH 0x8034 |
958 | #define PCI_DEVICE_ID_ML7213_DMA4_12CH 0x8032 | ||
959 | #define PCI_DEVICE_ID_ML7223_DMA1_4CH 0x800B | ||
960 | #define PCI_DEVICE_ID_ML7223_DMA2_4CH 0x800E | ||
961 | #define PCI_DEVICE_ID_ML7223_DMA3_4CH 0x8017 | ||
962 | #define PCI_DEVICE_ID_ML7223_DMA4_4CH 0x803B | ||
932 | 963 | ||
933 | static const struct pci_device_id pch_dma_id_table[] = { | 964 | DEFINE_PCI_DEVICE_TABLE(pch_dma_id_table) = { |
934 | { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_EG20T_PCH_DMA_8CH), 8 }, | 965 | { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_EG20T_PCH_DMA_8CH), 8 }, |
935 | { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_EG20T_PCH_DMA_4CH), 4 }, | 966 | { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_EG20T_PCH_DMA_4CH), 4 }, |
936 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_DMA1_8CH), 8}, /* UART Video */ | 967 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_DMA1_8CH), 8}, /* UART Video */ |
937 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_DMA2_8CH), 8}, /* PCMIF SPI */ | 968 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_DMA2_8CH), 8}, /* PCMIF SPI */ |
938 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_DMA3_4CH), 4}, /* FPGA */ | 969 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_DMA3_4CH), 4}, /* FPGA */ |
970 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_DMA4_12CH), 12}, /* I2S */ | ||
971 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7223_DMA1_4CH), 4}, /* UART */ | ||
972 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7223_DMA2_4CH), 4}, /* Video SPI */ | ||
973 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7223_DMA3_4CH), 4}, /* Security */ | ||
974 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7223_DMA4_4CH), 4}, /* FPGA */ | ||
939 | { 0, }, | 975 | { 0, }, |
940 | }; | 976 | }; |
941 | 977 | ||
diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c index 3b0247e74cc4..fc457a7e8832 100644 --- a/drivers/dma/ppc4xx/adma.c +++ b/drivers/dma/ppc4xx/adma.c | |||
@@ -2313,7 +2313,7 @@ static struct dma_async_tx_descriptor *ppc440spe_adma_prep_dma_memcpy( | |||
2313 | if (unlikely(!len)) | 2313 | if (unlikely(!len)) |
2314 | return NULL; | 2314 | return NULL; |
2315 | 2315 | ||
2316 | BUG_ON(unlikely(len > PPC440SPE_ADMA_DMA_MAX_BYTE_COUNT)); | 2316 | BUG_ON(len > PPC440SPE_ADMA_DMA_MAX_BYTE_COUNT); |
2317 | 2317 | ||
2318 | spin_lock_bh(&ppc440spe_chan->lock); | 2318 | spin_lock_bh(&ppc440spe_chan->lock); |
2319 | 2319 | ||
@@ -2354,7 +2354,7 @@ static struct dma_async_tx_descriptor *ppc440spe_adma_prep_dma_memset( | |||
2354 | if (unlikely(!len)) | 2354 | if (unlikely(!len)) |
2355 | return NULL; | 2355 | return NULL; |
2356 | 2356 | ||
2357 | BUG_ON(unlikely(len > PPC440SPE_ADMA_DMA_MAX_BYTE_COUNT)); | 2357 | BUG_ON(len > PPC440SPE_ADMA_DMA_MAX_BYTE_COUNT); |
2358 | 2358 | ||
2359 | spin_lock_bh(&ppc440spe_chan->lock); | 2359 | spin_lock_bh(&ppc440spe_chan->lock); |
2360 | 2360 | ||
@@ -2397,7 +2397,7 @@ static struct dma_async_tx_descriptor *ppc440spe_adma_prep_dma_xor( | |||
2397 | dma_dest, dma_src, src_cnt)); | 2397 | dma_dest, dma_src, src_cnt)); |
2398 | if (unlikely(!len)) | 2398 | if (unlikely(!len)) |
2399 | return NULL; | 2399 | return NULL; |
2400 | BUG_ON(unlikely(len > PPC440SPE_ADMA_XOR_MAX_BYTE_COUNT)); | 2400 | BUG_ON(len > PPC440SPE_ADMA_XOR_MAX_BYTE_COUNT); |
2401 | 2401 | ||
2402 | dev_dbg(ppc440spe_chan->device->common.dev, | 2402 | dev_dbg(ppc440spe_chan->device->common.dev, |
2403 | "ppc440spe adma%d: %s src_cnt: %d len: %u int_en: %d\n", | 2403 | "ppc440spe adma%d: %s src_cnt: %d len: %u int_en: %d\n", |
@@ -2887,7 +2887,7 @@ static struct dma_async_tx_descriptor *ppc440spe_adma_prep_dma_pq( | |||
2887 | ADMA_LL_DBG(prep_dma_pq_dbg(ppc440spe_chan->device->id, | 2887 | ADMA_LL_DBG(prep_dma_pq_dbg(ppc440spe_chan->device->id, |
2888 | dst, src, src_cnt)); | 2888 | dst, src, src_cnt)); |
2889 | BUG_ON(!len); | 2889 | BUG_ON(!len); |
2890 | BUG_ON(unlikely(len > PPC440SPE_ADMA_XOR_MAX_BYTE_COUNT)); | 2890 | BUG_ON(len > PPC440SPE_ADMA_XOR_MAX_BYTE_COUNT); |
2891 | BUG_ON(!src_cnt); | 2891 | BUG_ON(!src_cnt); |
2892 | 2892 | ||
2893 | if (src_cnt == 1 && dst[1] == src[0]) { | 2893 | if (src_cnt == 1 && dst[1] == src[0]) { |
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index 636e40925b16..2a638f9f09a2 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c | |||
@@ -343,7 +343,7 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan) | |||
343 | 343 | ||
344 | dmae_set_dmars(sh_chan, cfg->mid_rid); | 344 | dmae_set_dmars(sh_chan, cfg->mid_rid); |
345 | dmae_set_chcr(sh_chan, cfg->chcr); | 345 | dmae_set_chcr(sh_chan, cfg->chcr); |
346 | } else if ((sh_dmae_readl(sh_chan, CHCR) & 0xf00) != 0x400) { | 346 | } else { |
347 | dmae_init(sh_chan); | 347 | dmae_init(sh_chan); |
348 | } | 348 | } |
349 | 349 | ||
@@ -1144,6 +1144,8 @@ static int __init sh_dmae_probe(struct platform_device *pdev) | |||
1144 | /* platform data */ | 1144 | /* platform data */ |
1145 | shdev->pdata = pdata; | 1145 | shdev->pdata = pdata; |
1146 | 1146 | ||
1147 | platform_set_drvdata(pdev, shdev); | ||
1148 | |||
1147 | pm_runtime_enable(&pdev->dev); | 1149 | pm_runtime_enable(&pdev->dev); |
1148 | pm_runtime_get_sync(&pdev->dev); | 1150 | pm_runtime_get_sync(&pdev->dev); |
1149 | 1151 | ||
@@ -1256,7 +1258,6 @@ static int __init sh_dmae_probe(struct platform_device *pdev) | |||
1256 | 1258 | ||
1257 | pm_runtime_put(&pdev->dev); | 1259 | pm_runtime_put(&pdev->dev); |
1258 | 1260 | ||
1259 | platform_set_drvdata(pdev, shdev); | ||
1260 | dma_async_device_register(&shdev->common); | 1261 | dma_async_device_register(&shdev->common); |
1261 | 1262 | ||
1262 | return err; | 1263 | return err; |
@@ -1278,6 +1279,8 @@ rst_err: | |||
1278 | 1279 | ||
1279 | if (dmars) | 1280 | if (dmars) |
1280 | iounmap(shdev->dmars); | 1281 | iounmap(shdev->dmars); |
1282 | |||
1283 | platform_set_drvdata(pdev, NULL); | ||
1281 | emapdmars: | 1284 | emapdmars: |
1282 | iounmap(shdev->chan_reg); | 1285 | iounmap(shdev->chan_reg); |
1283 | synchronize_rcu(); | 1286 | synchronize_rcu(); |
@@ -1316,6 +1319,8 @@ static int __exit sh_dmae_remove(struct platform_device *pdev) | |||
1316 | iounmap(shdev->dmars); | 1319 | iounmap(shdev->dmars); |
1317 | iounmap(shdev->chan_reg); | 1320 | iounmap(shdev->chan_reg); |
1318 | 1321 | ||
1322 | platform_set_drvdata(pdev, NULL); | ||
1323 | |||
1319 | synchronize_rcu(); | 1324 | synchronize_rcu(); |
1320 | kfree(shdev); | 1325 | kfree(shdev); |
1321 | 1326 | ||
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 94ee15dd3aed..8f222d4db7de 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c | |||
@@ -1829,7 +1829,7 @@ d40_get_dev_addr(struct d40_chan *chan, enum dma_data_direction direction) | |||
1829 | { | 1829 | { |
1830 | struct stedma40_platform_data *plat = chan->base->plat_data; | 1830 | struct stedma40_platform_data *plat = chan->base->plat_data; |
1831 | struct stedma40_chan_cfg *cfg = &chan->dma_cfg; | 1831 | struct stedma40_chan_cfg *cfg = &chan->dma_cfg; |
1832 | dma_addr_t addr; | 1832 | dma_addr_t addr = 0; |
1833 | 1833 | ||
1834 | if (chan->runtime_addr) | 1834 | if (chan->runtime_addr) |
1835 | return chan->runtime_addr; | 1835 | return chan->runtime_addr; |
@@ -2962,4 +2962,4 @@ static int __init stedma40_init(void) | |||
2962 | { | 2962 | { |
2963 | return platform_driver_probe(&d40_driver, d40_probe); | 2963 | return platform_driver_probe(&d40_driver, d40_probe); |
2964 | } | 2964 | } |
2965 | arch_initcall(stedma40_init); | 2965 | subsys_initcall(stedma40_init); |
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 592397629ddc..4a7f63143455 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -89,24 +89,28 @@ config GPIO_IT8761E | |||
89 | config GPIO_EXYNOS4 | 89 | config GPIO_EXYNOS4 |
90 | bool "Samsung Exynos4 GPIO library support" | 90 | bool "Samsung Exynos4 GPIO library support" |
91 | default y if CPU_EXYNOS4210 | 91 | default y if CPU_EXYNOS4210 |
92 | depends on ARM | ||
92 | help | 93 | help |
93 | Say yes here to support Samsung Exynos4 series SoCs GPIO library | 94 | Say yes here to support Samsung Exynos4 series SoCs GPIO library |
94 | 95 | ||
95 | config GPIO_PLAT_SAMSUNG | 96 | config GPIO_PLAT_SAMSUNG |
96 | bool "Samsung SoCs GPIO library support" | 97 | bool "Samsung SoCs GPIO library support" |
97 | default y if SAMSUNG_GPIOLIB_4BIT | 98 | default y if SAMSUNG_GPIOLIB_4BIT |
99 | depends on ARM | ||
98 | help | 100 | help |
99 | Say yes here to support Samsung SoCs GPIO library | 101 | Say yes here to support Samsung SoCs GPIO library |
100 | 102 | ||
101 | config GPIO_S5PC100 | 103 | config GPIO_S5PC100 |
102 | bool "Samsung S5PC100 GPIO library support" | 104 | bool "Samsung S5PC100 GPIO library support" |
103 | default y if CPU_S5PC100 | 105 | default y if CPU_S5PC100 |
106 | depends on ARM | ||
104 | help | 107 | help |
105 | Say yes here to support Samsung S5PC100 SoCs GPIO library | 108 | Say yes here to support Samsung S5PC100 SoCs GPIO library |
106 | 109 | ||
107 | config GPIO_S5PV210 | 110 | config GPIO_S5PV210 |
108 | bool "Samsung S5PV210/S5PC110 GPIO library support" | 111 | bool "Samsung S5PV210/S5PC110 GPIO library support" |
109 | default y if CPU_S5PV210 | 112 | default y if CPU_S5PV210 |
113 | depends on ARM | ||
110 | help | 114 | help |
111 | Say yes here to support Samsung S5PV210/S5PC110 SoCs GPIO library | 115 | Say yes here to support Samsung S5PV210/S5PC110 SoCs GPIO library |
112 | 116 | ||
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index de3d2465fe24..85e937984ff7 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c | |||
@@ -296,7 +296,7 @@ static int get_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev) | |||
296 | * If the TjMax is not plausible, an assumption | 296 | * If the TjMax is not plausible, an assumption |
297 | * will be used | 297 | * will be used |
298 | */ | 298 | */ |
299 | if (val > 80 && val < 120) { | 299 | if (val) { |
300 | dev_info(dev, "TjMax is %d C.\n", val); | 300 | dev_info(dev, "TjMax is %d C.\n", val); |
301 | return val * 1000; | 301 | return val * 1000; |
302 | } | 302 | } |
@@ -304,24 +304,9 @@ static int get_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev) | |||
304 | 304 | ||
305 | /* | 305 | /* |
306 | * An assumption is made for early CPUs and unreadable MSR. | 306 | * An assumption is made for early CPUs and unreadable MSR. |
307 | * NOTE: the given value may not be correct. | 307 | * NOTE: the calculated value may not be correct. |
308 | */ | 308 | */ |
309 | 309 | return adjust_tjmax(c, id, dev); | |
310 | switch (c->x86_model) { | ||
311 | case 0xe: | ||
312 | case 0xf: | ||
313 | case 0x16: | ||
314 | case 0x1a: | ||
315 | dev_warn(dev, "TjMax is assumed as 100 C!\n"); | ||
316 | return 100000; | ||
317 | case 0x17: | ||
318 | case 0x1c: /* Atom CPUs */ | ||
319 | return adjust_tjmax(c, id, dev); | ||
320 | default: | ||
321 | dev_warn(dev, "CPU (model=0x%x) is not supported yet," | ||
322 | " using default TjMax of 100C.\n", c->x86_model); | ||
323 | return 100000; | ||
324 | } | ||
325 | } | 310 | } |
326 | 311 | ||
327 | static void __devinit get_ucode_rev_on_cpu(void *edx) | 312 | static void __devinit get_ucode_rev_on_cpu(void *edx) |
@@ -341,7 +326,7 @@ static int get_pkg_tjmax(unsigned int cpu, struct device *dev) | |||
341 | err = rdmsr_safe_on_cpu(cpu, MSR_IA32_TEMPERATURE_TARGET, &eax, &edx); | 326 | err = rdmsr_safe_on_cpu(cpu, MSR_IA32_TEMPERATURE_TARGET, &eax, &edx); |
342 | if (!err) { | 327 | if (!err) { |
343 | val = (eax >> 16) & 0xff; | 328 | val = (eax >> 16) & 0xff; |
344 | if (val > 80 && val < 120) | 329 | if (val) |
345 | return val * 1000; | 330 | return val * 1000; |
346 | } | 331 | } |
347 | dev_warn(dev, "Unable to read Pkg-TjMax from CPU:%u\n", cpu); | 332 | dev_warn(dev, "Unable to read Pkg-TjMax from CPU:%u\n", cpu); |
diff --git a/drivers/hwmon/max6642.c b/drivers/hwmon/max6642.c index 0f9fc40379cd..e855d3b0bd1f 100644 --- a/drivers/hwmon/max6642.c +++ b/drivers/hwmon/max6642.c | |||
@@ -136,15 +136,29 @@ static int max6642_detect(struct i2c_client *client, | |||
136 | if (man_id != 0x4D) | 136 | if (man_id != 0x4D) |
137 | return -ENODEV; | 137 | return -ENODEV; |
138 | 138 | ||
139 | /* sanity check */ | ||
140 | if (i2c_smbus_read_byte_data(client, 0x04) != 0x4D | ||
141 | || i2c_smbus_read_byte_data(client, 0x06) != 0x4D | ||
142 | || i2c_smbus_read_byte_data(client, 0xff) != 0x4D) | ||
143 | return -ENODEV; | ||
144 | |||
139 | /* | 145 | /* |
140 | * We read the config and status register, the 4 lower bits in the | 146 | * We read the config and status register, the 4 lower bits in the |
141 | * config register should be zero and bit 5, 3, 1 and 0 should be | 147 | * config register should be zero and bit 5, 3, 1 and 0 should be |
142 | * zero in the status register. | 148 | * zero in the status register. |
143 | */ | 149 | */ |
144 | reg_config = i2c_smbus_read_byte_data(client, MAX6642_REG_R_CONFIG); | 150 | reg_config = i2c_smbus_read_byte_data(client, MAX6642_REG_R_CONFIG); |
151 | if ((reg_config & 0x0f) != 0x00) | ||
152 | return -ENODEV; | ||
153 | |||
154 | /* in between, another round of sanity checks */ | ||
155 | if (i2c_smbus_read_byte_data(client, 0x04) != reg_config | ||
156 | || i2c_smbus_read_byte_data(client, 0x06) != reg_config | ||
157 | || i2c_smbus_read_byte_data(client, 0xff) != reg_config) | ||
158 | return -ENODEV; | ||
159 | |||
145 | reg_status = i2c_smbus_read_byte_data(client, MAX6642_REG_R_STATUS); | 160 | reg_status = i2c_smbus_read_byte_data(client, MAX6642_REG_R_STATUS); |
146 | if (((reg_config & 0x0f) != 0x00) || | 161 | if ((reg_status & 0x2b) != 0x00) |
147 | ((reg_status & 0x2b) != 0x00)) | ||
148 | return -ENODEV; | 162 | return -ENODEV; |
149 | 163 | ||
150 | strlcpy(info->type, "max6642", I2C_NAME_SIZE); | 164 | strlcpy(info->type, "max6642", I2C_NAME_SIZE); |
@@ -246,7 +260,7 @@ static SENSOR_DEVICE_ATTR_2(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, | |||
246 | set_temp_max, 0, MAX6642_REG_W_LOCAL_HIGH); | 260 | set_temp_max, 0, MAX6642_REG_W_LOCAL_HIGH); |
247 | static SENSOR_DEVICE_ATTR_2(temp2_max, S_IWUSR | S_IRUGO, show_temp_max, | 261 | static SENSOR_DEVICE_ATTR_2(temp2_max, S_IWUSR | S_IRUGO, show_temp_max, |
248 | set_temp_max, 1, MAX6642_REG_W_REMOTE_HIGH); | 262 | set_temp_max, 1, MAX6642_REG_W_REMOTE_HIGH); |
249 | static SENSOR_DEVICE_ATTR(temp_fault, S_IRUGO, show_alarm, NULL, 2); | 263 | static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 2); |
250 | static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6); | 264 | static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6); |
251 | static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4); | 265 | static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4); |
252 | 266 | ||
@@ -256,7 +270,7 @@ static struct attribute *max6642_attributes[] = { | |||
256 | &sensor_dev_attr_temp1_max.dev_attr.attr, | 270 | &sensor_dev_attr_temp1_max.dev_attr.attr, |
257 | &sensor_dev_attr_temp2_max.dev_attr.attr, | 271 | &sensor_dev_attr_temp2_max.dev_attr.attr, |
258 | 272 | ||
259 | &sensor_dev_attr_temp_fault.dev_attr.attr, | 273 | &sensor_dev_attr_temp2_fault.dev_attr.attr, |
260 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, | 274 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, |
261 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, | 275 | &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, |
262 | NULL | 276 | NULL |
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 6e5123b1d341..144d27261e43 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
@@ -1782,7 +1782,6 @@ static int ide_cd_probe(ide_drive_t *drive) | |||
1782 | ide_cd_read_toc(drive, &sense); | 1782 | ide_cd_read_toc(drive, &sense); |
1783 | g->fops = &idecd_ops; | 1783 | g->fops = &idecd_ops; |
1784 | g->flags |= GENHD_FL_REMOVABLE | GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE; | 1784 | g->flags |= GENHD_FL_REMOVABLE | GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE; |
1785 | g->events = DISK_EVENT_MEDIA_CHANGE; | ||
1786 | add_disk(g); | 1785 | add_disk(g); |
1787 | return 0; | 1786 | return 0; |
1788 | 1787 | ||
diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c index f3698967edf6..8755f5f3ad37 100644 --- a/drivers/input/serio/serport.c +++ b/drivers/input/serio/serport.c | |||
@@ -120,21 +120,17 @@ static void serport_ldisc_close(struct tty_struct *tty) | |||
120 | * 'interrupt' routine. | 120 | * 'interrupt' routine. |
121 | */ | 121 | */ |
122 | 122 | ||
123 | static unsigned int serport_ldisc_receive(struct tty_struct *tty, | 123 | static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) |
124 | const unsigned char *cp, char *fp, int count) | ||
125 | { | 124 | { |
126 | struct serport *serport = (struct serport*) tty->disc_data; | 125 | struct serport *serport = (struct serport*) tty->disc_data; |
127 | unsigned long flags; | 126 | unsigned long flags; |
128 | unsigned int ch_flags; | 127 | unsigned int ch_flags; |
129 | int ret = 0; | ||
130 | int i; | 128 | int i; |
131 | 129 | ||
132 | spin_lock_irqsave(&serport->lock, flags); | 130 | spin_lock_irqsave(&serport->lock, flags); |
133 | 131 | ||
134 | if (!test_bit(SERPORT_ACTIVE, &serport->flags)) { | 132 | if (!test_bit(SERPORT_ACTIVE, &serport->flags)) |
135 | ret = -EINVAL; | ||
136 | goto out; | 133 | goto out; |
137 | } | ||
138 | 134 | ||
139 | for (i = 0; i < count; i++) { | 135 | for (i = 0; i < count; i++) { |
140 | switch (fp[i]) { | 136 | switch (fp[i]) { |
@@ -156,8 +152,6 @@ static unsigned int serport_ldisc_receive(struct tty_struct *tty, | |||
156 | 152 | ||
157 | out: | 153 | out: |
158 | spin_unlock_irqrestore(&serport->lock, flags); | 154 | spin_unlock_irqrestore(&serport->lock, flags); |
159 | |||
160 | return ret == 0 ? count : ret; | ||
161 | } | 155 | } |
162 | 156 | ||
163 | /* | 157 | /* |
diff --git a/drivers/isdn/gigaset/ser-gigaset.c b/drivers/isdn/gigaset/ser-gigaset.c index 1d44d470897c..86a5c4f7775e 100644 --- a/drivers/isdn/gigaset/ser-gigaset.c +++ b/drivers/isdn/gigaset/ser-gigaset.c | |||
@@ -674,7 +674,7 @@ gigaset_tty_ioctl(struct tty_struct *tty, struct file *file, | |||
674 | * cflags buffer containing error flags for received characters (ignored) | 674 | * cflags buffer containing error flags for received characters (ignored) |
675 | * count number of received characters | 675 | * count number of received characters |
676 | */ | 676 | */ |
677 | static unsigned int | 677 | static void |
678 | gigaset_tty_receive(struct tty_struct *tty, const unsigned char *buf, | 678 | gigaset_tty_receive(struct tty_struct *tty, const unsigned char *buf, |
679 | char *cflags, int count) | 679 | char *cflags, int count) |
680 | { | 680 | { |
@@ -683,12 +683,12 @@ gigaset_tty_receive(struct tty_struct *tty, const unsigned char *buf, | |||
683 | struct inbuf_t *inbuf; | 683 | struct inbuf_t *inbuf; |
684 | 684 | ||
685 | if (!cs) | 685 | if (!cs) |
686 | return -ENODEV; | 686 | return; |
687 | inbuf = cs->inbuf; | 687 | inbuf = cs->inbuf; |
688 | if (!inbuf) { | 688 | if (!inbuf) { |
689 | dev_err(cs->dev, "%s: no inbuf\n", __func__); | 689 | dev_err(cs->dev, "%s: no inbuf\n", __func__); |
690 | cs_put(cs); | 690 | cs_put(cs); |
691 | return -EINVAL; | 691 | return; |
692 | } | 692 | } |
693 | 693 | ||
694 | tail = inbuf->tail; | 694 | tail = inbuf->tail; |
@@ -725,8 +725,6 @@ gigaset_tty_receive(struct tty_struct *tty, const unsigned char *buf, | |||
725 | gig_dbg(DEBUG_INTR, "%s-->BH", __func__); | 725 | gig_dbg(DEBUG_INTR, "%s-->BH", __func__); |
726 | gigaset_schedule_event(cs); | 726 | gigaset_schedule_event(cs); |
727 | cs_put(cs); | 727 | cs_put(cs); |
728 | |||
729 | return count; | ||
730 | } | 728 | } |
731 | 729 | ||
732 | /* | 730 | /* |
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c index 76a5af00a26b..2067288f61f9 100644 --- a/drivers/md/dm-io.c +++ b/drivers/md/dm-io.c | |||
@@ -19,6 +19,8 @@ | |||
19 | #define DM_MSG_PREFIX "io" | 19 | #define DM_MSG_PREFIX "io" |
20 | 20 | ||
21 | #define DM_IO_MAX_REGIONS BITS_PER_LONG | 21 | #define DM_IO_MAX_REGIONS BITS_PER_LONG |
22 | #define MIN_IOS 16 | ||
23 | #define MIN_BIOS 16 | ||
22 | 24 | ||
23 | struct dm_io_client { | 25 | struct dm_io_client { |
24 | mempool_t *pool; | 26 | mempool_t *pool; |
@@ -41,33 +43,21 @@ struct io { | |||
41 | static struct kmem_cache *_dm_io_cache; | 43 | static struct kmem_cache *_dm_io_cache; |
42 | 44 | ||
43 | /* | 45 | /* |
44 | * io contexts are only dynamically allocated for asynchronous | ||
45 | * io. Since async io is likely to be the majority of io we'll | ||
46 | * have the same number of io contexts as bios! (FIXME: must reduce this). | ||
47 | */ | ||
48 | |||
49 | static unsigned int pages_to_ios(unsigned int pages) | ||
50 | { | ||
51 | return 4 * pages; /* too many ? */ | ||
52 | } | ||
53 | |||
54 | /* | ||
55 | * Create a client with mempool and bioset. | 46 | * Create a client with mempool and bioset. |
56 | */ | 47 | */ |
57 | struct dm_io_client *dm_io_client_create(unsigned num_pages) | 48 | struct dm_io_client *dm_io_client_create(void) |
58 | { | 49 | { |
59 | unsigned ios = pages_to_ios(num_pages); | ||
60 | struct dm_io_client *client; | 50 | struct dm_io_client *client; |
61 | 51 | ||
62 | client = kmalloc(sizeof(*client), GFP_KERNEL); | 52 | client = kmalloc(sizeof(*client), GFP_KERNEL); |
63 | if (!client) | 53 | if (!client) |
64 | return ERR_PTR(-ENOMEM); | 54 | return ERR_PTR(-ENOMEM); |
65 | 55 | ||
66 | client->pool = mempool_create_slab_pool(ios, _dm_io_cache); | 56 | client->pool = mempool_create_slab_pool(MIN_IOS, _dm_io_cache); |
67 | if (!client->pool) | 57 | if (!client->pool) |
68 | goto bad; | 58 | goto bad; |
69 | 59 | ||
70 | client->bios = bioset_create(16, 0); | 60 | client->bios = bioset_create(MIN_BIOS, 0); |
71 | if (!client->bios) | 61 | if (!client->bios) |
72 | goto bad; | 62 | goto bad; |
73 | 63 | ||
@@ -81,13 +71,6 @@ struct dm_io_client *dm_io_client_create(unsigned num_pages) | |||
81 | } | 71 | } |
82 | EXPORT_SYMBOL(dm_io_client_create); | 72 | EXPORT_SYMBOL(dm_io_client_create); |
83 | 73 | ||
84 | int dm_io_client_resize(unsigned num_pages, struct dm_io_client *client) | ||
85 | { | ||
86 | return mempool_resize(client->pool, pages_to_ios(num_pages), | ||
87 | GFP_KERNEL); | ||
88 | } | ||
89 | EXPORT_SYMBOL(dm_io_client_resize); | ||
90 | |||
91 | void dm_io_client_destroy(struct dm_io_client *client) | 74 | void dm_io_client_destroy(struct dm_io_client *client) |
92 | { | 75 | { |
93 | mempool_destroy(client->pool); | 76 | mempool_destroy(client->pool); |
diff --git a/drivers/md/dm-kcopyd.c b/drivers/md/dm-kcopyd.c index 1bb73a13ca40..819e37eaaeba 100644 --- a/drivers/md/dm-kcopyd.c +++ b/drivers/md/dm-kcopyd.c | |||
@@ -27,15 +27,19 @@ | |||
27 | 27 | ||
28 | #include "dm.h" | 28 | #include "dm.h" |
29 | 29 | ||
30 | #define SUB_JOB_SIZE 128 | ||
31 | #define SPLIT_COUNT 8 | ||
32 | #define MIN_JOBS 8 | ||
33 | #define RESERVE_PAGES (DIV_ROUND_UP(SUB_JOB_SIZE << SECTOR_SHIFT, PAGE_SIZE)) | ||
34 | |||
30 | /*----------------------------------------------------------------- | 35 | /*----------------------------------------------------------------- |
31 | * Each kcopyd client has its own little pool of preallocated | 36 | * Each kcopyd client has its own little pool of preallocated |
32 | * pages for kcopyd io. | 37 | * pages for kcopyd io. |
33 | *---------------------------------------------------------------*/ | 38 | *---------------------------------------------------------------*/ |
34 | struct dm_kcopyd_client { | 39 | struct dm_kcopyd_client { |
35 | spinlock_t lock; | ||
36 | struct page_list *pages; | 40 | struct page_list *pages; |
37 | unsigned int nr_pages; | 41 | unsigned nr_reserved_pages; |
38 | unsigned int nr_free_pages; | 42 | unsigned nr_free_pages; |
39 | 43 | ||
40 | struct dm_io_client *io_client; | 44 | struct dm_io_client *io_client; |
41 | 45 | ||
@@ -67,15 +71,18 @@ static void wake(struct dm_kcopyd_client *kc) | |||
67 | queue_work(kc->kcopyd_wq, &kc->kcopyd_work); | 71 | queue_work(kc->kcopyd_wq, &kc->kcopyd_work); |
68 | } | 72 | } |
69 | 73 | ||
70 | static struct page_list *alloc_pl(void) | 74 | /* |
75 | * Obtain one page for the use of kcopyd. | ||
76 | */ | ||
77 | static struct page_list *alloc_pl(gfp_t gfp) | ||
71 | { | 78 | { |
72 | struct page_list *pl; | 79 | struct page_list *pl; |
73 | 80 | ||
74 | pl = kmalloc(sizeof(*pl), GFP_KERNEL); | 81 | pl = kmalloc(sizeof(*pl), gfp); |
75 | if (!pl) | 82 | if (!pl) |
76 | return NULL; | 83 | return NULL; |
77 | 84 | ||
78 | pl->page = alloc_page(GFP_KERNEL); | 85 | pl->page = alloc_page(gfp); |
79 | if (!pl->page) { | 86 | if (!pl->page) { |
80 | kfree(pl); | 87 | kfree(pl); |
81 | return NULL; | 88 | return NULL; |
@@ -90,41 +97,56 @@ static void free_pl(struct page_list *pl) | |||
90 | kfree(pl); | 97 | kfree(pl); |
91 | } | 98 | } |
92 | 99 | ||
93 | static int kcopyd_get_pages(struct dm_kcopyd_client *kc, | 100 | /* |
94 | unsigned int nr, struct page_list **pages) | 101 | * Add the provided pages to a client's free page list, releasing |
102 | * back to the system any beyond the reserved_pages limit. | ||
103 | */ | ||
104 | static void kcopyd_put_pages(struct dm_kcopyd_client *kc, struct page_list *pl) | ||
95 | { | 105 | { |
96 | struct page_list *pl; | 106 | struct page_list *next; |
97 | |||
98 | spin_lock(&kc->lock); | ||
99 | if (kc->nr_free_pages < nr) { | ||
100 | spin_unlock(&kc->lock); | ||
101 | return -ENOMEM; | ||
102 | } | ||
103 | |||
104 | kc->nr_free_pages -= nr; | ||
105 | for (*pages = pl = kc->pages; --nr; pl = pl->next) | ||
106 | ; | ||
107 | 107 | ||
108 | kc->pages = pl->next; | 108 | do { |
109 | pl->next = NULL; | 109 | next = pl->next; |
110 | 110 | ||
111 | spin_unlock(&kc->lock); | 111 | if (kc->nr_free_pages >= kc->nr_reserved_pages) |
112 | free_pl(pl); | ||
113 | else { | ||
114 | pl->next = kc->pages; | ||
115 | kc->pages = pl; | ||
116 | kc->nr_free_pages++; | ||
117 | } | ||
112 | 118 | ||
113 | return 0; | 119 | pl = next; |
120 | } while (pl); | ||
114 | } | 121 | } |
115 | 122 | ||
116 | static void kcopyd_put_pages(struct dm_kcopyd_client *kc, struct page_list *pl) | 123 | static int kcopyd_get_pages(struct dm_kcopyd_client *kc, |
124 | unsigned int nr, struct page_list **pages) | ||
117 | { | 125 | { |
118 | struct page_list *cursor; | 126 | struct page_list *pl; |
127 | |||
128 | *pages = NULL; | ||
129 | |||
130 | do { | ||
131 | pl = alloc_pl(__GFP_NOWARN | __GFP_NORETRY); | ||
132 | if (unlikely(!pl)) { | ||
133 | /* Use reserved pages */ | ||
134 | pl = kc->pages; | ||
135 | if (unlikely(!pl)) | ||
136 | goto out_of_memory; | ||
137 | kc->pages = pl->next; | ||
138 | kc->nr_free_pages--; | ||
139 | } | ||
140 | pl->next = *pages; | ||
141 | *pages = pl; | ||
142 | } while (--nr); | ||
119 | 143 | ||
120 | spin_lock(&kc->lock); | 144 | return 0; |
121 | for (cursor = pl; cursor->next; cursor = cursor->next) | ||
122 | kc->nr_free_pages++; | ||
123 | 145 | ||
124 | kc->nr_free_pages++; | 146 | out_of_memory: |
125 | cursor->next = kc->pages; | 147 | if (*pages) |
126 | kc->pages = pl; | 148 | kcopyd_put_pages(kc, *pages); |
127 | spin_unlock(&kc->lock); | 149 | return -ENOMEM; |
128 | } | 150 | } |
129 | 151 | ||
130 | /* | 152 | /* |
@@ -141,13 +163,16 @@ static void drop_pages(struct page_list *pl) | |||
141 | } | 163 | } |
142 | } | 164 | } |
143 | 165 | ||
144 | static int client_alloc_pages(struct dm_kcopyd_client *kc, unsigned int nr) | 166 | /* |
167 | * Allocate and reserve nr_pages for the use of a specific client. | ||
168 | */ | ||
169 | static int client_reserve_pages(struct dm_kcopyd_client *kc, unsigned nr_pages) | ||
145 | { | 170 | { |
146 | unsigned int i; | 171 | unsigned i; |
147 | struct page_list *pl = NULL, *next; | 172 | struct page_list *pl = NULL, *next; |
148 | 173 | ||
149 | for (i = 0; i < nr; i++) { | 174 | for (i = 0; i < nr_pages; i++) { |
150 | next = alloc_pl(); | 175 | next = alloc_pl(GFP_KERNEL); |
151 | if (!next) { | 176 | if (!next) { |
152 | if (pl) | 177 | if (pl) |
153 | drop_pages(pl); | 178 | drop_pages(pl); |
@@ -157,17 +182,18 @@ static int client_alloc_pages(struct dm_kcopyd_client *kc, unsigned int nr) | |||
157 | pl = next; | 182 | pl = next; |
158 | } | 183 | } |
159 | 184 | ||
185 | kc->nr_reserved_pages += nr_pages; | ||
160 | kcopyd_put_pages(kc, pl); | 186 | kcopyd_put_pages(kc, pl); |
161 | kc->nr_pages += nr; | 187 | |
162 | return 0; | 188 | return 0; |
163 | } | 189 | } |
164 | 190 | ||
165 | static void client_free_pages(struct dm_kcopyd_client *kc) | 191 | static void client_free_pages(struct dm_kcopyd_client *kc) |
166 | { | 192 | { |
167 | BUG_ON(kc->nr_free_pages != kc->nr_pages); | 193 | BUG_ON(kc->nr_free_pages != kc->nr_reserved_pages); |
168 | drop_pages(kc->pages); | 194 | drop_pages(kc->pages); |
169 | kc->pages = NULL; | 195 | kc->pages = NULL; |
170 | kc->nr_free_pages = kc->nr_pages = 0; | 196 | kc->nr_free_pages = kc->nr_reserved_pages = 0; |
171 | } | 197 | } |
172 | 198 | ||
173 | /*----------------------------------------------------------------- | 199 | /*----------------------------------------------------------------- |
@@ -216,16 +242,17 @@ struct kcopyd_job { | |||
216 | struct mutex lock; | 242 | struct mutex lock; |
217 | atomic_t sub_jobs; | 243 | atomic_t sub_jobs; |
218 | sector_t progress; | 244 | sector_t progress; |
219 | }; | ||
220 | 245 | ||
221 | /* FIXME: this should scale with the number of pages */ | 246 | struct kcopyd_job *master_job; |
222 | #define MIN_JOBS 512 | 247 | }; |
223 | 248 | ||
224 | static struct kmem_cache *_job_cache; | 249 | static struct kmem_cache *_job_cache; |
225 | 250 | ||
226 | int __init dm_kcopyd_init(void) | 251 | int __init dm_kcopyd_init(void) |
227 | { | 252 | { |
228 | _job_cache = KMEM_CACHE(kcopyd_job, 0); | 253 | _job_cache = kmem_cache_create("kcopyd_job", |
254 | sizeof(struct kcopyd_job) * (SPLIT_COUNT + 1), | ||
255 | __alignof__(struct kcopyd_job), 0, NULL); | ||
229 | if (!_job_cache) | 256 | if (!_job_cache) |
230 | return -ENOMEM; | 257 | return -ENOMEM; |
231 | 258 | ||
@@ -299,7 +326,12 @@ static int run_complete_job(struct kcopyd_job *job) | |||
299 | 326 | ||
300 | if (job->pages) | 327 | if (job->pages) |
301 | kcopyd_put_pages(kc, job->pages); | 328 | kcopyd_put_pages(kc, job->pages); |
302 | mempool_free(job, kc->job_pool); | 329 | /* |
330 | * If this is the master job, the sub jobs have already | ||
331 | * completed so we can free everything. | ||
332 | */ | ||
333 | if (job->master_job == job) | ||
334 | mempool_free(job, kc->job_pool); | ||
303 | fn(read_err, write_err, context); | 335 | fn(read_err, write_err, context); |
304 | 336 | ||
305 | if (atomic_dec_and_test(&kc->nr_jobs)) | 337 | if (atomic_dec_and_test(&kc->nr_jobs)) |
@@ -460,14 +492,14 @@ static void dispatch_job(struct kcopyd_job *job) | |||
460 | wake(kc); | 492 | wake(kc); |
461 | } | 493 | } |
462 | 494 | ||
463 | #define SUB_JOB_SIZE 128 | ||
464 | static void segment_complete(int read_err, unsigned long write_err, | 495 | static void segment_complete(int read_err, unsigned long write_err, |
465 | void *context) | 496 | void *context) |
466 | { | 497 | { |
467 | /* FIXME: tidy this function */ | 498 | /* FIXME: tidy this function */ |
468 | sector_t progress = 0; | 499 | sector_t progress = 0; |
469 | sector_t count = 0; | 500 | sector_t count = 0; |
470 | struct kcopyd_job *job = (struct kcopyd_job *) context; | 501 | struct kcopyd_job *sub_job = (struct kcopyd_job *) context; |
502 | struct kcopyd_job *job = sub_job->master_job; | ||
471 | struct dm_kcopyd_client *kc = job->kc; | 503 | struct dm_kcopyd_client *kc = job->kc; |
472 | 504 | ||
473 | mutex_lock(&job->lock); | 505 | mutex_lock(&job->lock); |
@@ -498,8 +530,6 @@ static void segment_complete(int read_err, unsigned long write_err, | |||
498 | 530 | ||
499 | if (count) { | 531 | if (count) { |
500 | int i; | 532 | int i; |
501 | struct kcopyd_job *sub_job = mempool_alloc(kc->job_pool, | ||
502 | GFP_NOIO); | ||
503 | 533 | ||
504 | *sub_job = *job; | 534 | *sub_job = *job; |
505 | sub_job->source.sector += progress; | 535 | sub_job->source.sector += progress; |
@@ -511,7 +541,7 @@ static void segment_complete(int read_err, unsigned long write_err, | |||
511 | } | 541 | } |
512 | 542 | ||
513 | sub_job->fn = segment_complete; | 543 | sub_job->fn = segment_complete; |
514 | sub_job->context = job; | 544 | sub_job->context = sub_job; |
515 | dispatch_job(sub_job); | 545 | dispatch_job(sub_job); |
516 | 546 | ||
517 | } else if (atomic_dec_and_test(&job->sub_jobs)) { | 547 | } else if (atomic_dec_and_test(&job->sub_jobs)) { |
@@ -531,19 +561,19 @@ static void segment_complete(int read_err, unsigned long write_err, | |||
531 | } | 561 | } |
532 | 562 | ||
533 | /* | 563 | /* |
534 | * Create some little jobs that will do the move between | 564 | * Create some sub jobs to share the work between them. |
535 | * them. | ||
536 | */ | 565 | */ |
537 | #define SPLIT_COUNT 8 | 566 | static void split_job(struct kcopyd_job *master_job) |
538 | static void split_job(struct kcopyd_job *job) | ||
539 | { | 567 | { |
540 | int i; | 568 | int i; |
541 | 569 | ||
542 | atomic_inc(&job->kc->nr_jobs); | 570 | atomic_inc(&master_job->kc->nr_jobs); |
543 | 571 | ||
544 | atomic_set(&job->sub_jobs, SPLIT_COUNT); | 572 | atomic_set(&master_job->sub_jobs, SPLIT_COUNT); |
545 | for (i = 0; i < SPLIT_COUNT; i++) | 573 | for (i = 0; i < SPLIT_COUNT; i++) { |
546 | segment_complete(0, 0u, job); | 574 | master_job[i + 1].master_job = master_job; |
575 | segment_complete(0, 0u, &master_job[i + 1]); | ||
576 | } | ||
547 | } | 577 | } |
548 | 578 | ||
549 | int dm_kcopyd_copy(struct dm_kcopyd_client *kc, struct dm_io_region *from, | 579 | int dm_kcopyd_copy(struct dm_kcopyd_client *kc, struct dm_io_region *from, |
@@ -553,7 +583,8 @@ int dm_kcopyd_copy(struct dm_kcopyd_client *kc, struct dm_io_region *from, | |||
553 | struct kcopyd_job *job; | 583 | struct kcopyd_job *job; |
554 | 584 | ||
555 | /* | 585 | /* |
556 | * Allocate a new job. | 586 | * Allocate an array of jobs consisting of one master job |
587 | * followed by SPLIT_COUNT sub jobs. | ||
557 | */ | 588 | */ |
558 | job = mempool_alloc(kc->job_pool, GFP_NOIO); | 589 | job = mempool_alloc(kc->job_pool, GFP_NOIO); |
559 | 590 | ||
@@ -577,10 +608,10 @@ int dm_kcopyd_copy(struct dm_kcopyd_client *kc, struct dm_io_region *from, | |||
577 | 608 | ||
578 | job->fn = fn; | 609 | job->fn = fn; |
579 | job->context = context; | 610 | job->context = context; |
611 | job->master_job = job; | ||
580 | 612 | ||
581 | if (job->source.count < SUB_JOB_SIZE) | 613 | if (job->source.count <= SUB_JOB_SIZE) |
582 | dispatch_job(job); | 614 | dispatch_job(job); |
583 | |||
584 | else { | 615 | else { |
585 | mutex_init(&job->lock); | 616 | mutex_init(&job->lock); |
586 | job->progress = 0; | 617 | job->progress = 0; |
@@ -606,17 +637,15 @@ int kcopyd_cancel(struct kcopyd_job *job, int block) | |||
606 | /*----------------------------------------------------------------- | 637 | /*----------------------------------------------------------------- |
607 | * Client setup | 638 | * Client setup |
608 | *---------------------------------------------------------------*/ | 639 | *---------------------------------------------------------------*/ |
609 | int dm_kcopyd_client_create(unsigned int nr_pages, | 640 | struct dm_kcopyd_client *dm_kcopyd_client_create(void) |
610 | struct dm_kcopyd_client **result) | ||
611 | { | 641 | { |
612 | int r = -ENOMEM; | 642 | int r = -ENOMEM; |
613 | struct dm_kcopyd_client *kc; | 643 | struct dm_kcopyd_client *kc; |
614 | 644 | ||
615 | kc = kmalloc(sizeof(*kc), GFP_KERNEL); | 645 | kc = kmalloc(sizeof(*kc), GFP_KERNEL); |
616 | if (!kc) | 646 | if (!kc) |
617 | return -ENOMEM; | 647 | return ERR_PTR(-ENOMEM); |
618 | 648 | ||
619 | spin_lock_init(&kc->lock); | ||
620 | spin_lock_init(&kc->job_lock); | 649 | spin_lock_init(&kc->job_lock); |
621 | INIT_LIST_HEAD(&kc->complete_jobs); | 650 | INIT_LIST_HEAD(&kc->complete_jobs); |
622 | INIT_LIST_HEAD(&kc->io_jobs); | 651 | INIT_LIST_HEAD(&kc->io_jobs); |
@@ -633,12 +662,12 @@ int dm_kcopyd_client_create(unsigned int nr_pages, | |||
633 | goto bad_workqueue; | 662 | goto bad_workqueue; |
634 | 663 | ||
635 | kc->pages = NULL; | 664 | kc->pages = NULL; |
636 | kc->nr_pages = kc->nr_free_pages = 0; | 665 | kc->nr_reserved_pages = kc->nr_free_pages = 0; |
637 | r = client_alloc_pages(kc, nr_pages); | 666 | r = client_reserve_pages(kc, RESERVE_PAGES); |
638 | if (r) | 667 | if (r) |
639 | goto bad_client_pages; | 668 | goto bad_client_pages; |
640 | 669 | ||
641 | kc->io_client = dm_io_client_create(nr_pages); | 670 | kc->io_client = dm_io_client_create(); |
642 | if (IS_ERR(kc->io_client)) { | 671 | if (IS_ERR(kc->io_client)) { |
643 | r = PTR_ERR(kc->io_client); | 672 | r = PTR_ERR(kc->io_client); |
644 | goto bad_io_client; | 673 | goto bad_io_client; |
@@ -647,8 +676,7 @@ int dm_kcopyd_client_create(unsigned int nr_pages, | |||
647 | init_waitqueue_head(&kc->destroyq); | 676 | init_waitqueue_head(&kc->destroyq); |
648 | atomic_set(&kc->nr_jobs, 0); | 677 | atomic_set(&kc->nr_jobs, 0); |
649 | 678 | ||
650 | *result = kc; | 679 | return kc; |
651 | return 0; | ||
652 | 680 | ||
653 | bad_io_client: | 681 | bad_io_client: |
654 | client_free_pages(kc); | 682 | client_free_pages(kc); |
@@ -659,7 +687,7 @@ bad_workqueue: | |||
659 | bad_slab: | 687 | bad_slab: |
660 | kfree(kc); | 688 | kfree(kc); |
661 | 689 | ||
662 | return r; | 690 | return ERR_PTR(r); |
663 | } | 691 | } |
664 | EXPORT_SYMBOL(dm_kcopyd_client_create); | 692 | EXPORT_SYMBOL(dm_kcopyd_client_create); |
665 | 693 | ||
diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c index a1f321889676..948e3f4925bf 100644 --- a/drivers/md/dm-log.c +++ b/drivers/md/dm-log.c | |||
@@ -449,8 +449,7 @@ static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti, | |||
449 | 449 | ||
450 | lc->io_req.mem.type = DM_IO_VMA; | 450 | lc->io_req.mem.type = DM_IO_VMA; |
451 | lc->io_req.notify.fn = NULL; | 451 | lc->io_req.notify.fn = NULL; |
452 | lc->io_req.client = dm_io_client_create(dm_div_up(buf_size, | 452 | lc->io_req.client = dm_io_client_create(); |
453 | PAGE_SIZE)); | ||
454 | if (IS_ERR(lc->io_req.client)) { | 453 | if (IS_ERR(lc->io_req.client)) { |
455 | r = PTR_ERR(lc->io_req.client); | 454 | r = PTR_ERR(lc->io_req.client); |
456 | DMWARN("couldn't allocate disk io client"); | 455 | DMWARN("couldn't allocate disk io client"); |
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index a550a057d991..aa4e570c2cb5 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c | |||
@@ -1290,7 +1290,7 @@ static int do_end_io(struct multipath *m, struct request *clone, | |||
1290 | if (!error && !clone->errors) | 1290 | if (!error && !clone->errors) |
1291 | return 0; /* I/O complete */ | 1291 | return 0; /* I/O complete */ |
1292 | 1292 | ||
1293 | if (error == -EOPNOTSUPP || error == -EREMOTEIO) | 1293 | if (error == -EOPNOTSUPP || error == -EREMOTEIO || error == -EILSEQ) |
1294 | return error; | 1294 | return error; |
1295 | 1295 | ||
1296 | if (mpio->pgpath) | 1296 | if (mpio->pgpath) |
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 976ad4688afc..9bfd057be686 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c | |||
@@ -22,8 +22,6 @@ | |||
22 | #define DM_MSG_PREFIX "raid1" | 22 | #define DM_MSG_PREFIX "raid1" |
23 | 23 | ||
24 | #define MAX_RECOVERY 1 /* Maximum number of regions recovered in parallel. */ | 24 | #define MAX_RECOVERY 1 /* Maximum number of regions recovered in parallel. */ |
25 | #define DM_IO_PAGES 64 | ||
26 | #define DM_KCOPYD_PAGES 64 | ||
27 | 25 | ||
28 | #define DM_RAID1_HANDLE_ERRORS 0x01 | 26 | #define DM_RAID1_HANDLE_ERRORS 0x01 |
29 | #define errors_handled(p) ((p)->features & DM_RAID1_HANDLE_ERRORS) | 27 | #define errors_handled(p) ((p)->features & DM_RAID1_HANDLE_ERRORS) |
@@ -887,7 +885,7 @@ static struct mirror_set *alloc_context(unsigned int nr_mirrors, | |||
887 | return NULL; | 885 | return NULL; |
888 | } | 886 | } |
889 | 887 | ||
890 | ms->io_client = dm_io_client_create(DM_IO_PAGES); | 888 | ms->io_client = dm_io_client_create(); |
891 | if (IS_ERR(ms->io_client)) { | 889 | if (IS_ERR(ms->io_client)) { |
892 | ti->error = "Error creating dm_io client"; | 890 | ti->error = "Error creating dm_io client"; |
893 | mempool_destroy(ms->read_record_pool); | 891 | mempool_destroy(ms->read_record_pool); |
@@ -1117,9 +1115,11 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
1117 | goto err_destroy_wq; | 1115 | goto err_destroy_wq; |
1118 | } | 1116 | } |
1119 | 1117 | ||
1120 | r = dm_kcopyd_client_create(DM_KCOPYD_PAGES, &ms->kcopyd_client); | 1118 | ms->kcopyd_client = dm_kcopyd_client_create(); |
1121 | if (r) | 1119 | if (IS_ERR(ms->kcopyd_client)) { |
1120 | r = PTR_ERR(ms->kcopyd_client); | ||
1122 | goto err_destroy_wq; | 1121 | goto err_destroy_wq; |
1122 | } | ||
1123 | 1123 | ||
1124 | wakeup_mirrord(ms); | 1124 | wakeup_mirrord(ms); |
1125 | return 0; | 1125 | return 0; |
diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c index 95891dfcbca0..135c2f1fdbfc 100644 --- a/drivers/md/dm-snap-persistent.c +++ b/drivers/md/dm-snap-persistent.c | |||
@@ -154,11 +154,6 @@ struct pstore { | |||
154 | struct workqueue_struct *metadata_wq; | 154 | struct workqueue_struct *metadata_wq; |
155 | }; | 155 | }; |
156 | 156 | ||
157 | static unsigned sectors_to_pages(unsigned sectors) | ||
158 | { | ||
159 | return DIV_ROUND_UP(sectors, PAGE_SIZE >> 9); | ||
160 | } | ||
161 | |||
162 | static int alloc_area(struct pstore *ps) | 157 | static int alloc_area(struct pstore *ps) |
163 | { | 158 | { |
164 | int r = -ENOMEM; | 159 | int r = -ENOMEM; |
@@ -318,8 +313,7 @@ static int read_header(struct pstore *ps, int *new_snapshot) | |||
318 | chunk_size_supplied = 0; | 313 | chunk_size_supplied = 0; |
319 | } | 314 | } |
320 | 315 | ||
321 | ps->io_client = dm_io_client_create(sectors_to_pages(ps->store-> | 316 | ps->io_client = dm_io_client_create(); |
322 | chunk_size)); | ||
323 | if (IS_ERR(ps->io_client)) | 317 | if (IS_ERR(ps->io_client)) |
324 | return PTR_ERR(ps->io_client); | 318 | return PTR_ERR(ps->io_client); |
325 | 319 | ||
@@ -368,11 +362,6 @@ static int read_header(struct pstore *ps, int *new_snapshot) | |||
368 | return r; | 362 | return r; |
369 | } | 363 | } |
370 | 364 | ||
371 | r = dm_io_client_resize(sectors_to_pages(ps->store->chunk_size), | ||
372 | ps->io_client); | ||
373 | if (r) | ||
374 | return r; | ||
375 | |||
376 | r = alloc_area(ps); | 365 | r = alloc_area(ps); |
377 | return r; | 366 | return r; |
378 | 367 | ||
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index a2d330942cb2..9ecff5f3023a 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c | |||
@@ -40,11 +40,6 @@ static const char dm_snapshot_merge_target_name[] = "snapshot-merge"; | |||
40 | #define SNAPSHOT_COPY_PRIORITY 2 | 40 | #define SNAPSHOT_COPY_PRIORITY 2 |
41 | 41 | ||
42 | /* | 42 | /* |
43 | * Reserve 1MB for each snapshot initially (with minimum of 1 page). | ||
44 | */ | ||
45 | #define SNAPSHOT_PAGES (((1UL << 20) >> PAGE_SHIFT) ? : 1) | ||
46 | |||
47 | /* | ||
48 | * The size of the mempool used to track chunks in use. | 43 | * The size of the mempool used to track chunks in use. |
49 | */ | 44 | */ |
50 | #define MIN_IOS 256 | 45 | #define MIN_IOS 256 |
@@ -1116,8 +1111,9 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
1116 | goto bad_hash_tables; | 1111 | goto bad_hash_tables; |
1117 | } | 1112 | } |
1118 | 1113 | ||
1119 | r = dm_kcopyd_client_create(SNAPSHOT_PAGES, &s->kcopyd_client); | 1114 | s->kcopyd_client = dm_kcopyd_client_create(); |
1120 | if (r) { | 1115 | if (IS_ERR(s->kcopyd_client)) { |
1116 | r = PTR_ERR(s->kcopyd_client); | ||
1121 | ti->error = "Could not create kcopyd client"; | 1117 | ti->error = "Could not create kcopyd client"; |
1122 | goto bad_kcopyd; | 1118 | goto bad_kcopyd; |
1123 | } | 1119 | } |
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index cb8380c9767f..451c3bb176d2 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c | |||
@@ -362,6 +362,7 @@ static void close_dev(struct dm_dev_internal *d, struct mapped_device *md) | |||
362 | static int device_area_is_invalid(struct dm_target *ti, struct dm_dev *dev, | 362 | static int device_area_is_invalid(struct dm_target *ti, struct dm_dev *dev, |
363 | sector_t start, sector_t len, void *data) | 363 | sector_t start, sector_t len, void *data) |
364 | { | 364 | { |
365 | struct request_queue *q; | ||
365 | struct queue_limits *limits = data; | 366 | struct queue_limits *limits = data; |
366 | struct block_device *bdev = dev->bdev; | 367 | struct block_device *bdev = dev->bdev; |
367 | sector_t dev_size = | 368 | sector_t dev_size = |
@@ -370,6 +371,22 @@ static int device_area_is_invalid(struct dm_target *ti, struct dm_dev *dev, | |||
370 | limits->logical_block_size >> SECTOR_SHIFT; | 371 | limits->logical_block_size >> SECTOR_SHIFT; |
371 | char b[BDEVNAME_SIZE]; | 372 | char b[BDEVNAME_SIZE]; |
372 | 373 | ||
374 | /* | ||
375 | * Some devices exist without request functions, | ||
376 | * such as loop devices not yet bound to backing files. | ||
377 | * Forbid the use of such devices. | ||
378 | */ | ||
379 | q = bdev_get_queue(bdev); | ||
380 | if (!q || !q->make_request_fn) { | ||
381 | DMWARN("%s: %s is not yet initialised: " | ||
382 | "start=%llu, len=%llu, dev_size=%llu", | ||
383 | dm_device_name(ti->table->md), bdevname(bdev, b), | ||
384 | (unsigned long long)start, | ||
385 | (unsigned long long)len, | ||
386 | (unsigned long long)dev_size); | ||
387 | return 1; | ||
388 | } | ||
389 | |||
373 | if (!dev_size) | 390 | if (!dev_size) |
374 | return 0; | 391 | return 0; |
375 | 392 | ||
@@ -1346,7 +1363,8 @@ bool dm_table_supports_discards(struct dm_table *t) | |||
1346 | return 0; | 1363 | return 0; |
1347 | 1364 | ||
1348 | /* | 1365 | /* |
1349 | * Ensure that at least one underlying device supports discards. | 1366 | * Unless any target used by the table set discards_supported, |
1367 | * require at least one underlying device to support discards. | ||
1350 | * t->devices includes internal dm devices such as mirror logs | 1368 | * t->devices includes internal dm devices such as mirror logs |
1351 | * so we need to use iterate_devices here, which targets | 1369 | * so we need to use iterate_devices here, which targets |
1352 | * supporting discard must provide. | 1370 | * supporting discard must provide. |
@@ -1354,6 +1372,9 @@ bool dm_table_supports_discards(struct dm_table *t) | |||
1354 | while (i < dm_table_get_num_targets(t)) { | 1372 | while (i < dm_table_get_num_targets(t)) { |
1355 | ti = dm_table_get_target(t, i++); | 1373 | ti = dm_table_get_target(t, i++); |
1356 | 1374 | ||
1375 | if (ti->discards_supported) | ||
1376 | return 1; | ||
1377 | |||
1357 | if (ti->type->iterate_devices && | 1378 | if (ti->type->iterate_devices && |
1358 | ti->type->iterate_devices(ti, device_discard_capable, NULL)) | 1379 | ti->type->iterate_devices(ti, device_discard_capable, NULL)) |
1359 | return 1; | 1380 | return 1; |
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index b6c267724e14..0f09c057e796 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig | |||
@@ -721,7 +721,7 @@ config MFD_PM8XXX_IRQ | |||
721 | 721 | ||
722 | config MFD_TPS65910 | 722 | config MFD_TPS65910 |
723 | bool "TPS65910 Power Management chip" | 723 | bool "TPS65910 Power Management chip" |
724 | depends on I2C=y | 724 | depends on I2C=y && GPIOLIB |
725 | select MFD_CORE | 725 | select MFD_CORE |
726 | select GPIO_TPS65910 | 726 | select GPIO_TPS65910 |
727 | help | 727 | help |
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index e63782107e2f..02a15d7cb3b0 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c | |||
@@ -2005,7 +2005,8 @@ static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = { | |||
2005 | static struct mfd_cell db8500_prcmu_devs[] = { | 2005 | static struct mfd_cell db8500_prcmu_devs[] = { |
2006 | { | 2006 | { |
2007 | .name = "db8500-prcmu-regulators", | 2007 | .name = "db8500-prcmu-regulators", |
2008 | .mfd_data = &db8500_regulators, | 2008 | .platform_data = &db8500_regulators, |
2009 | .pdata_size = sizeof(db8500_regulators), | ||
2009 | }, | 2010 | }, |
2010 | { | 2011 | { |
2011 | .name = "cpufreq-u8500", | 2012 | .name = "cpufreq-u8500", |
diff --git a/drivers/misc/kgdbts.c b/drivers/misc/kgdbts.c index b0c56313dbbb..8cebec5e85ee 100644 --- a/drivers/misc/kgdbts.c +++ b/drivers/misc/kgdbts.c | |||
@@ -304,7 +304,10 @@ static int check_and_rewind_pc(char *put_str, char *arg) | |||
304 | return 1; | 304 | return 1; |
305 | } | 305 | } |
306 | /* Readjust the instruction pointer if needed */ | 306 | /* Readjust the instruction pointer if needed */ |
307 | instruction_pointer_set(&kgdbts_regs, ip + offset); | 307 | ip += offset; |
308 | #ifdef GDB_ADJUSTS_BREAK_OFFSET | ||
309 | instruction_pointer_set(&kgdbts_regs, ip); | ||
310 | #endif | ||
308 | return 0; | 311 | return 0; |
309 | } | 312 | } |
310 | 313 | ||
diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c index 1a05fe08e2cb..f91f82eabda7 100644 --- a/drivers/misc/ti-st/st_core.c +++ b/drivers/misc/ti-st/st_core.c | |||
@@ -747,8 +747,8 @@ static void st_tty_close(struct tty_struct *tty) | |||
747 | pr_debug("%s: done ", __func__); | 747 | pr_debug("%s: done ", __func__); |
748 | } | 748 | } |
749 | 749 | ||
750 | static unsigned int st_tty_receive(struct tty_struct *tty, | 750 | static void st_tty_receive(struct tty_struct *tty, const unsigned char *data, |
751 | const unsigned char *data, char *tty_flags, int count) | 751 | char *tty_flags, int count) |
752 | { | 752 | { |
753 | #ifdef VERBOSE | 753 | #ifdef VERBOSE |
754 | print_hex_dump(KERN_DEBUG, ">in>", DUMP_PREFIX_NONE, | 754 | print_hex_dump(KERN_DEBUG, ">in>", DUMP_PREFIX_NONE, |
@@ -761,8 +761,6 @@ static unsigned int st_tty_receive(struct tty_struct *tty, | |||
761 | */ | 761 | */ |
762 | st_recv(tty->disc_data, data, count); | 762 | st_recv(tty->disc_data, data, count); |
763 | pr_debug("done %s", __func__); | 763 | pr_debug("done %s", __func__); |
764 | |||
765 | return count; | ||
766 | } | 764 | } |
767 | 765 | ||
768 | /* wake-up function called in from the TTY layer | 766 | /* wake-up function called in from the TTY layer |
diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c index 5f25889e27ef..44b28b2d7003 100644 --- a/drivers/net/3c509.c +++ b/drivers/net/3c509.c | |||
@@ -185,7 +185,7 @@ static int max_interrupt_work = 10; | |||
185 | static int nopnp; | 185 | static int nopnp; |
186 | #endif | 186 | #endif |
187 | 187 | ||
188 | static int el3_common_init(struct net_device *dev); | 188 | static int __devinit el3_common_init(struct net_device *dev); |
189 | static void el3_common_remove(struct net_device *dev); | 189 | static void el3_common_remove(struct net_device *dev); |
190 | static ushort id_read_eeprom(int index); | 190 | static ushort id_read_eeprom(int index); |
191 | static ushort read_eeprom(int ioaddr, int index); | 191 | static ushort read_eeprom(int ioaddr, int index); |
@@ -395,7 +395,7 @@ static struct isa_driver el3_isa_driver = { | |||
395 | static int isa_registered; | 395 | static int isa_registered; |
396 | 396 | ||
397 | #ifdef CONFIG_PNP | 397 | #ifdef CONFIG_PNP |
398 | static const struct pnp_device_id el3_pnp_ids[] __devinitconst = { | 398 | static struct pnp_device_id el3_pnp_ids[] = { |
399 | { .id = "TCM5090" }, /* 3Com Etherlink III (TP) */ | 399 | { .id = "TCM5090" }, /* 3Com Etherlink III (TP) */ |
400 | { .id = "TCM5091" }, /* 3Com Etherlink III */ | 400 | { .id = "TCM5091" }, /* 3Com Etherlink III */ |
401 | { .id = "TCM5094" }, /* 3Com Etherlink III (combo) */ | 401 | { .id = "TCM5094" }, /* 3Com Etherlink III (combo) */ |
@@ -478,7 +478,7 @@ static int pnp_registered; | |||
478 | #endif /* CONFIG_PNP */ | 478 | #endif /* CONFIG_PNP */ |
479 | 479 | ||
480 | #ifdef CONFIG_EISA | 480 | #ifdef CONFIG_EISA |
481 | static const struct eisa_device_id el3_eisa_ids[] __devinitconst = { | 481 | static struct eisa_device_id el3_eisa_ids[] = { |
482 | { "TCM5090" }, | 482 | { "TCM5090" }, |
483 | { "TCM5091" }, | 483 | { "TCM5091" }, |
484 | { "TCM5092" }, | 484 | { "TCM5092" }, |
@@ -508,7 +508,7 @@ static int eisa_registered; | |||
508 | #ifdef CONFIG_MCA | 508 | #ifdef CONFIG_MCA |
509 | static int el3_mca_probe(struct device *dev); | 509 | static int el3_mca_probe(struct device *dev); |
510 | 510 | ||
511 | static const short el3_mca_adapter_ids[] __devinitconst = { | 511 | static short el3_mca_adapter_ids[] __initdata = { |
512 | 0x627c, | 512 | 0x627c, |
513 | 0x627d, | 513 | 0x627d, |
514 | 0x62db, | 514 | 0x62db, |
@@ -517,7 +517,7 @@ static const short el3_mca_adapter_ids[] __devinitconst = { | |||
517 | 0x0000 | 517 | 0x0000 |
518 | }; | 518 | }; |
519 | 519 | ||
520 | static const char *const el3_mca_adapter_names[] __devinitconst = { | 520 | static char *el3_mca_adapter_names[] __initdata = { |
521 | "3Com 3c529 EtherLink III (10base2)", | 521 | "3Com 3c529 EtherLink III (10base2)", |
522 | "3Com 3c529 EtherLink III (10baseT)", | 522 | "3Com 3c529 EtherLink III (10baseT)", |
523 | "3Com 3c529 EtherLink III (test mode)", | 523 | "3Com 3c529 EtherLink III (test mode)", |
@@ -601,7 +601,7 @@ static void el3_common_remove (struct net_device *dev) | |||
601 | } | 601 | } |
602 | 602 | ||
603 | #ifdef CONFIG_MCA | 603 | #ifdef CONFIG_MCA |
604 | static int __devinit el3_mca_probe(struct device *device) | 604 | static int __init el3_mca_probe(struct device *device) |
605 | { | 605 | { |
606 | /* Based on Erik Nygren's (nygren@mit.edu) 3c529 patch, | 606 | /* Based on Erik Nygren's (nygren@mit.edu) 3c529 patch, |
607 | * heavily modified by Chris Beauregard | 607 | * heavily modified by Chris Beauregard |
@@ -671,7 +671,7 @@ static int __devinit el3_mca_probe(struct device *device) | |||
671 | #endif /* CONFIG_MCA */ | 671 | #endif /* CONFIG_MCA */ |
672 | 672 | ||
673 | #ifdef CONFIG_EISA | 673 | #ifdef CONFIG_EISA |
674 | static int __devinit el3_eisa_probe (struct device *device) | 674 | static int __init el3_eisa_probe (struct device *device) |
675 | { | 675 | { |
676 | short i; | 676 | short i; |
677 | int ioaddr, irq, if_port; | 677 | int ioaddr, irq, if_port; |
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index 99f43d275442..8cc22568ebd3 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c | |||
@@ -901,14 +901,14 @@ static const struct dev_pm_ops vortex_pm_ops = { | |||
901 | #endif /* !CONFIG_PM */ | 901 | #endif /* !CONFIG_PM */ |
902 | 902 | ||
903 | #ifdef CONFIG_EISA | 903 | #ifdef CONFIG_EISA |
904 | static const struct eisa_device_id vortex_eisa_ids[] __devinitconst = { | 904 | static struct eisa_device_id vortex_eisa_ids[] = { |
905 | { "TCM5920", CH_3C592 }, | 905 | { "TCM5920", CH_3C592 }, |
906 | { "TCM5970", CH_3C597 }, | 906 | { "TCM5970", CH_3C597 }, |
907 | { "" } | 907 | { "" } |
908 | }; | 908 | }; |
909 | MODULE_DEVICE_TABLE(eisa, vortex_eisa_ids); | 909 | MODULE_DEVICE_TABLE(eisa, vortex_eisa_ids); |
910 | 910 | ||
911 | static int __devinit vortex_eisa_probe(struct device *device) | 911 | static int __init vortex_eisa_probe(struct device *device) |
912 | { | 912 | { |
913 | void __iomem *ioaddr; | 913 | void __iomem *ioaddr; |
914 | struct eisa_device *edev; | 914 | struct eisa_device *edev; |
diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c index 73c7e03617ec..3df0c0f8b8bf 100644 --- a/drivers/net/caif/caif_serial.c +++ b/drivers/net/caif/caif_serial.c | |||
@@ -167,8 +167,8 @@ static inline void debugfs_tx(struct ser_device *ser, const u8 *data, int size) | |||
167 | 167 | ||
168 | #endif | 168 | #endif |
169 | 169 | ||
170 | static unsigned int ldisc_receive(struct tty_struct *tty, | 170 | static void ldisc_receive(struct tty_struct *tty, const u8 *data, |
171 | const u8 *data, char *flags, int count) | 171 | char *flags, int count) |
172 | { | 172 | { |
173 | struct sk_buff *skb = NULL; | 173 | struct sk_buff *skb = NULL; |
174 | struct ser_device *ser; | 174 | struct ser_device *ser; |
@@ -215,8 +215,6 @@ static unsigned int ldisc_receive(struct tty_struct *tty, | |||
215 | } else | 215 | } else |
216 | ++ser->dev->stats.rx_dropped; | 216 | ++ser->dev->stats.rx_dropped; |
217 | update_tty_status(ser); | 217 | update_tty_status(ser); |
218 | |||
219 | return count; | ||
220 | } | 218 | } |
221 | 219 | ||
222 | static int handle_tx(struct ser_device *ser) | 220 | static int handle_tx(struct ser_device *ser) |
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index d4990568baee..17678117ed69 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c | |||
@@ -923,7 +923,7 @@ static int __devinit flexcan_probe(struct platform_device *pdev) | |||
923 | mem_size = resource_size(mem); | 923 | mem_size = resource_size(mem); |
924 | if (!request_mem_region(mem->start, mem_size, pdev->name)) { | 924 | if (!request_mem_region(mem->start, mem_size, pdev->name)) { |
925 | err = -EBUSY; | 925 | err = -EBUSY; |
926 | goto failed_req; | 926 | goto failed_get; |
927 | } | 927 | } |
928 | 928 | ||
929 | base = ioremap(mem->start, mem_size); | 929 | base = ioremap(mem->start, mem_size); |
@@ -977,9 +977,8 @@ static int __devinit flexcan_probe(struct platform_device *pdev) | |||
977 | iounmap(base); | 977 | iounmap(base); |
978 | failed_map: | 978 | failed_map: |
979 | release_mem_region(mem->start, mem_size); | 979 | release_mem_region(mem->start, mem_size); |
980 | failed_req: | ||
981 | clk_put(clk); | ||
982 | failed_get: | 980 | failed_get: |
981 | clk_put(clk); | ||
983 | failed_clock: | 982 | failed_clock: |
984 | return err; | 983 | return err; |
985 | } | 984 | } |
diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c index 75622d54581f..1b49df6b2470 100644 --- a/drivers/net/can/slcan.c +++ b/drivers/net/can/slcan.c | |||
@@ -425,17 +425,16 @@ static void slc_setup(struct net_device *dev) | |||
425 | * in parallel | 425 | * in parallel |
426 | */ | 426 | */ |
427 | 427 | ||
428 | static unsigned int slcan_receive_buf(struct tty_struct *tty, | 428 | static void slcan_receive_buf(struct tty_struct *tty, |
429 | const unsigned char *cp, char *fp, int count) | 429 | const unsigned char *cp, char *fp, int count) |
430 | { | 430 | { |
431 | struct slcan *sl = (struct slcan *) tty->disc_data; | 431 | struct slcan *sl = (struct slcan *) tty->disc_data; |
432 | int bytes = count; | ||
433 | 432 | ||
434 | if (!sl || sl->magic != SLCAN_MAGIC || !netif_running(sl->dev)) | 433 | if (!sl || sl->magic != SLCAN_MAGIC || !netif_running(sl->dev)) |
435 | return -ENODEV; | 434 | return; |
436 | 435 | ||
437 | /* Read the characters out of the buffer */ | 436 | /* Read the characters out of the buffer */ |
438 | while (bytes--) { | 437 | while (count--) { |
439 | if (fp && *fp++) { | 438 | if (fp && *fp++) { |
440 | if (!test_and_set_bit(SLF_ERROR, &sl->flags)) | 439 | if (!test_and_set_bit(SLF_ERROR, &sl->flags)) |
441 | sl->dev->stats.rx_errors++; | 440 | sl->dev->stats.rx_errors++; |
@@ -444,8 +443,6 @@ static unsigned int slcan_receive_buf(struct tty_struct *tty, | |||
444 | } | 443 | } |
445 | slcan_unesc(sl, *cp++); | 444 | slcan_unesc(sl, *cp++); |
446 | } | 445 | } |
447 | |||
448 | return count; | ||
449 | } | 446 | } |
450 | 447 | ||
451 | /************************************ | 448 | /************************************ |
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index 29a4f06fbfcf..dcc4a170b0f3 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c | |||
@@ -1781,8 +1781,8 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev) | |||
1781 | ndev = alloc_etherdev(sizeof(struct emac_priv)); | 1781 | ndev = alloc_etherdev(sizeof(struct emac_priv)); |
1782 | if (!ndev) { | 1782 | if (!ndev) { |
1783 | dev_err(&pdev->dev, "error allocating net_device\n"); | 1783 | dev_err(&pdev->dev, "error allocating net_device\n"); |
1784 | clk_put(emac_clk); | 1784 | rc = -ENOMEM; |
1785 | return -ENOMEM; | 1785 | goto free_clk; |
1786 | } | 1786 | } |
1787 | 1787 | ||
1788 | platform_set_drvdata(pdev, ndev); | 1788 | platform_set_drvdata(pdev, ndev); |
@@ -1796,7 +1796,8 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev) | |||
1796 | pdata = pdev->dev.platform_data; | 1796 | pdata = pdev->dev.platform_data; |
1797 | if (!pdata) { | 1797 | if (!pdata) { |
1798 | dev_err(&pdev->dev, "no platform data\n"); | 1798 | dev_err(&pdev->dev, "no platform data\n"); |
1799 | return -ENODEV; | 1799 | rc = -ENODEV; |
1800 | goto probe_quit; | ||
1800 | } | 1801 | } |
1801 | 1802 | ||
1802 | /* MAC addr and PHY mask , RMII enable info from platform_data */ | 1803 | /* MAC addr and PHY mask , RMII enable info from platform_data */ |
@@ -1929,8 +1930,9 @@ no_dma: | |||
1929 | iounmap(priv->remap_addr); | 1930 | iounmap(priv->remap_addr); |
1930 | 1931 | ||
1931 | probe_quit: | 1932 | probe_quit: |
1932 | clk_put(emac_clk); | ||
1933 | free_netdev(ndev); | 1933 | free_netdev(ndev); |
1934 | free_clk: | ||
1935 | clk_put(emac_clk); | ||
1934 | return rc; | 1936 | return rc; |
1935 | } | 1937 | } |
1936 | 1938 | ||
diff --git a/drivers/net/depca.c b/drivers/net/depca.c index 17654059922d..8b0084d17c8c 100644 --- a/drivers/net/depca.c +++ b/drivers/net/depca.c | |||
@@ -331,18 +331,18 @@ static struct { | |||
331 | "DE422",\ | 331 | "DE422",\ |
332 | ""} | 332 | ""} |
333 | 333 | ||
334 | static const char* const depca_signature[] __devinitconst = DEPCA_SIGNATURE; | 334 | static char* __initdata depca_signature[] = DEPCA_SIGNATURE; |
335 | 335 | ||
336 | enum depca_type { | 336 | enum depca_type { |
337 | DEPCA, de100, de101, de200, de201, de202, de210, de212, de422, unknown | 337 | DEPCA, de100, de101, de200, de201, de202, de210, de212, de422, unknown |
338 | }; | 338 | }; |
339 | 339 | ||
340 | static const char depca_string[] = "depca"; | 340 | static char depca_string[] = "depca"; |
341 | 341 | ||
342 | static int depca_device_remove (struct device *device); | 342 | static int depca_device_remove (struct device *device); |
343 | 343 | ||
344 | #ifdef CONFIG_EISA | 344 | #ifdef CONFIG_EISA |
345 | static const struct eisa_device_id depca_eisa_ids[] __devinitconst = { | 345 | static struct eisa_device_id depca_eisa_ids[] = { |
346 | { "DEC4220", de422 }, | 346 | { "DEC4220", de422 }, |
347 | { "" } | 347 | { "" } |
348 | }; | 348 | }; |
@@ -367,19 +367,19 @@ static struct eisa_driver depca_eisa_driver = { | |||
367 | #define DE210_ID 0x628d | 367 | #define DE210_ID 0x628d |
368 | #define DE212_ID 0x6def | 368 | #define DE212_ID 0x6def |
369 | 369 | ||
370 | static const short depca_mca_adapter_ids[] __devinitconst = { | 370 | static short depca_mca_adapter_ids[] = { |
371 | DE210_ID, | 371 | DE210_ID, |
372 | DE212_ID, | 372 | DE212_ID, |
373 | 0x0000 | 373 | 0x0000 |
374 | }; | 374 | }; |
375 | 375 | ||
376 | static const char *depca_mca_adapter_name[] = { | 376 | static char *depca_mca_adapter_name[] = { |
377 | "DEC EtherWORKS MC Adapter (DE210)", | 377 | "DEC EtherWORKS MC Adapter (DE210)", |
378 | "DEC EtherWORKS MC Adapter (DE212)", | 378 | "DEC EtherWORKS MC Adapter (DE212)", |
379 | NULL | 379 | NULL |
380 | }; | 380 | }; |
381 | 381 | ||
382 | static const enum depca_type depca_mca_adapter_type[] = { | 382 | static enum depca_type depca_mca_adapter_type[] = { |
383 | de210, | 383 | de210, |
384 | de212, | 384 | de212, |
385 | 0 | 385 | 0 |
@@ -541,9 +541,10 @@ static void SetMulticastFilter(struct net_device *dev); | |||
541 | static int load_packet(struct net_device *dev, struct sk_buff *skb); | 541 | static int load_packet(struct net_device *dev, struct sk_buff *skb); |
542 | static void depca_dbg_open(struct net_device *dev); | 542 | static void depca_dbg_open(struct net_device *dev); |
543 | 543 | ||
544 | static const u_char de1xx_irq[] __devinitconst = { 2, 3, 4, 5, 7, 9, 0 }; | 544 | static u_char de1xx_irq[] __initdata = { 2, 3, 4, 5, 7, 9, 0 }; |
545 | static const u_char de2xx_irq[] __devinitconst = { 5, 9, 10, 11, 15, 0 }; | 545 | static u_char de2xx_irq[] __initdata = { 5, 9, 10, 11, 15, 0 }; |
546 | static const u_char de422_irq[] __devinitconst = { 5, 9, 10, 11, 0 }; | 546 | static u_char de422_irq[] __initdata = { 5, 9, 10, 11, 0 }; |
547 | static u_char *depca_irq; | ||
547 | 548 | ||
548 | static int irq; | 549 | static int irq; |
549 | static int io; | 550 | static int io; |
@@ -579,7 +580,7 @@ static const struct net_device_ops depca_netdev_ops = { | |||
579 | .ndo_validate_addr = eth_validate_addr, | 580 | .ndo_validate_addr = eth_validate_addr, |
580 | }; | 581 | }; |
581 | 582 | ||
582 | static int __devinit depca_hw_init (struct net_device *dev, struct device *device) | 583 | static int __init depca_hw_init (struct net_device *dev, struct device *device) |
583 | { | 584 | { |
584 | struct depca_private *lp; | 585 | struct depca_private *lp; |
585 | int i, j, offset, netRAM, mem_len, status = 0; | 586 | int i, j, offset, netRAM, mem_len, status = 0; |
@@ -747,7 +748,6 @@ static int __devinit depca_hw_init (struct net_device *dev, struct device *devic | |||
747 | if (dev->irq < 2) { | 748 | if (dev->irq < 2) { |
748 | unsigned char irqnum; | 749 | unsigned char irqnum; |
749 | unsigned long irq_mask, delay; | 750 | unsigned long irq_mask, delay; |
750 | const u_char *depca_irq; | ||
751 | 751 | ||
752 | irq_mask = probe_irq_on(); | 752 | irq_mask = probe_irq_on(); |
753 | 753 | ||
@@ -770,7 +770,6 @@ static int __devinit depca_hw_init (struct net_device *dev, struct device *devic | |||
770 | break; | 770 | break; |
771 | 771 | ||
772 | default: | 772 | default: |
773 | depca_irq = NULL; | ||
774 | break; /* Not reached */ | 773 | break; /* Not reached */ |
775 | } | 774 | } |
776 | 775 | ||
@@ -1303,7 +1302,7 @@ static void SetMulticastFilter(struct net_device *dev) | |||
1303 | } | 1302 | } |
1304 | } | 1303 | } |
1305 | 1304 | ||
1306 | static int __devinit depca_common_init (u_long ioaddr, struct net_device **devp) | 1305 | static int __init depca_common_init (u_long ioaddr, struct net_device **devp) |
1307 | { | 1306 | { |
1308 | int status = 0; | 1307 | int status = 0; |
1309 | 1308 | ||
@@ -1334,7 +1333,7 @@ static int __devinit depca_common_init (u_long ioaddr, struct net_device **devp) | |||
1334 | /* | 1333 | /* |
1335 | ** Microchannel bus I/O device probe | 1334 | ** Microchannel bus I/O device probe |
1336 | */ | 1335 | */ |
1337 | static int __devinit depca_mca_probe(struct device *device) | 1336 | static int __init depca_mca_probe(struct device *device) |
1338 | { | 1337 | { |
1339 | unsigned char pos[2]; | 1338 | unsigned char pos[2]; |
1340 | unsigned char where; | 1339 | unsigned char where; |
@@ -1458,7 +1457,7 @@ static int __devinit depca_mca_probe(struct device *device) | |||
1458 | ** ISA bus I/O device probe | 1457 | ** ISA bus I/O device probe |
1459 | */ | 1458 | */ |
1460 | 1459 | ||
1461 | static void __devinit depca_platform_probe (void) | 1460 | static void __init depca_platform_probe (void) |
1462 | { | 1461 | { |
1463 | int i; | 1462 | int i; |
1464 | struct platform_device *pldev; | 1463 | struct platform_device *pldev; |
@@ -1498,7 +1497,7 @@ static void __devinit depca_platform_probe (void) | |||
1498 | } | 1497 | } |
1499 | } | 1498 | } |
1500 | 1499 | ||
1501 | static enum depca_type __devinit depca_shmem_probe (ulong *mem_start) | 1500 | static enum depca_type __init depca_shmem_probe (ulong *mem_start) |
1502 | { | 1501 | { |
1503 | u_long mem_base[] = DEPCA_RAM_BASE_ADDRESSES; | 1502 | u_long mem_base[] = DEPCA_RAM_BASE_ADDRESSES; |
1504 | enum depca_type adapter = unknown; | 1503 | enum depca_type adapter = unknown; |
@@ -1559,7 +1558,7 @@ static int __devinit depca_isa_probe (struct platform_device *device) | |||
1559 | */ | 1558 | */ |
1560 | 1559 | ||
1561 | #ifdef CONFIG_EISA | 1560 | #ifdef CONFIG_EISA |
1562 | static int __devinit depca_eisa_probe (struct device *device) | 1561 | static int __init depca_eisa_probe (struct device *device) |
1563 | { | 1562 | { |
1564 | enum depca_type adapter = unknown; | 1563 | enum depca_type adapter = unknown; |
1565 | struct eisa_device *edev; | 1564 | struct eisa_device *edev; |
@@ -1630,7 +1629,7 @@ static int __devexit depca_device_remove (struct device *device) | |||
1630 | ** and Boot (readb) ROM. This will also give us a clue to the network RAM | 1629 | ** and Boot (readb) ROM. This will also give us a clue to the network RAM |
1631 | ** base address. | 1630 | ** base address. |
1632 | */ | 1631 | */ |
1633 | static int __devinit DepcaSignature(char *name, u_long base_addr) | 1632 | static int __init DepcaSignature(char *name, u_long base_addr) |
1634 | { | 1633 | { |
1635 | u_int i, j, k; | 1634 | u_int i, j, k; |
1636 | void __iomem *ptr; | 1635 | void __iomem *ptr; |
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index fbaff3584bd4..ee597e676ee5 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c | |||
@@ -1157,9 +1157,6 @@ dm9000_open(struct net_device *dev) | |||
1157 | 1157 | ||
1158 | irqflags |= IRQF_SHARED; | 1158 | irqflags |= IRQF_SHARED; |
1159 | 1159 | ||
1160 | if (request_irq(dev->irq, dm9000_interrupt, irqflags, dev->name, dev)) | ||
1161 | return -EAGAIN; | ||
1162 | |||
1163 | /* GPIO0 on pre-activate PHY, Reg 1F is not set by reset */ | 1160 | /* GPIO0 on pre-activate PHY, Reg 1F is not set by reset */ |
1164 | iow(db, DM9000_GPR, 0); /* REG_1F bit0 activate phyxcer */ | 1161 | iow(db, DM9000_GPR, 0); /* REG_1F bit0 activate phyxcer */ |
1165 | mdelay(1); /* delay needs by DM9000B */ | 1162 | mdelay(1); /* delay needs by DM9000B */ |
@@ -1168,6 +1165,9 @@ dm9000_open(struct net_device *dev) | |||
1168 | dm9000_reset(db); | 1165 | dm9000_reset(db); |
1169 | dm9000_init_dm9000(dev); | 1166 | dm9000_init_dm9000(dev); |
1170 | 1167 | ||
1168 | if (request_irq(dev->irq, dm9000_interrupt, irqflags, dev->name, dev)) | ||
1169 | return -EAGAIN; | ||
1170 | |||
1171 | /* Init driver variable */ | 1171 | /* Init driver variable */ |
1172 | db->dbug_cnt = 0; | 1172 | db->dbug_cnt = 0; |
1173 | 1173 | ||
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 992089639ea4..3e5d0b6b6516 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c | |||
@@ -456,7 +456,7 @@ out: | |||
456 | * a block of 6pack data has been received, which can now be decapsulated | 456 | * a block of 6pack data has been received, which can now be decapsulated |
457 | * and sent on to some IP layer for further processing. | 457 | * and sent on to some IP layer for further processing. |
458 | */ | 458 | */ |
459 | static unsigned int sixpack_receive_buf(struct tty_struct *tty, | 459 | static void sixpack_receive_buf(struct tty_struct *tty, |
460 | const unsigned char *cp, char *fp, int count) | 460 | const unsigned char *cp, char *fp, int count) |
461 | { | 461 | { |
462 | struct sixpack *sp; | 462 | struct sixpack *sp; |
@@ -464,11 +464,11 @@ static unsigned int sixpack_receive_buf(struct tty_struct *tty, | |||
464 | int count1; | 464 | int count1; |
465 | 465 | ||
466 | if (!count) | 466 | if (!count) |
467 | return 0; | 467 | return; |
468 | 468 | ||
469 | sp = sp_get(tty); | 469 | sp = sp_get(tty); |
470 | if (!sp) | 470 | if (!sp) |
471 | return -ENODEV; | 471 | return; |
472 | 472 | ||
473 | memcpy(buf, cp, count < sizeof(buf) ? count : sizeof(buf)); | 473 | memcpy(buf, cp, count < sizeof(buf) ? count : sizeof(buf)); |
474 | 474 | ||
@@ -487,8 +487,6 @@ static unsigned int sixpack_receive_buf(struct tty_struct *tty, | |||
487 | 487 | ||
488 | sp_put(sp); | 488 | sp_put(sp); |
489 | tty_unthrottle(tty); | 489 | tty_unthrottle(tty); |
490 | |||
491 | return count1; | ||
492 | } | 490 | } |
493 | 491 | ||
494 | /* | 492 | /* |
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index 0e4f23531140..4c628393c8b1 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c | |||
@@ -923,14 +923,13 @@ static long mkiss_compat_ioctl(struct tty_struct *tty, struct file *file, | |||
923 | * a block of data has been received, which can now be decapsulated | 923 | * a block of data has been received, which can now be decapsulated |
924 | * and sent on to the AX.25 layer for further processing. | 924 | * and sent on to the AX.25 layer for further processing. |
925 | */ | 925 | */ |
926 | static unsigned int mkiss_receive_buf(struct tty_struct *tty, | 926 | static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp, |
927 | const unsigned char *cp, char *fp, int count) | 927 | char *fp, int count) |
928 | { | 928 | { |
929 | struct mkiss *ax = mkiss_get(tty); | 929 | struct mkiss *ax = mkiss_get(tty); |
930 | int bytes = count; | ||
931 | 930 | ||
932 | if (!ax) | 931 | if (!ax) |
933 | return -ENODEV; | 932 | return; |
934 | 933 | ||
935 | /* | 934 | /* |
936 | * Argh! mtu change time! - costs us the packet part received | 935 | * Argh! mtu change time! - costs us the packet part received |
@@ -940,7 +939,7 @@ static unsigned int mkiss_receive_buf(struct tty_struct *tty, | |||
940 | ax_changedmtu(ax); | 939 | ax_changedmtu(ax); |
941 | 940 | ||
942 | /* Read the characters out of the buffer */ | 941 | /* Read the characters out of the buffer */ |
943 | while (bytes--) { | 942 | while (count--) { |
944 | if (fp != NULL && *fp++) { | 943 | if (fp != NULL && *fp++) { |
945 | if (!test_and_set_bit(AXF_ERROR, &ax->flags)) | 944 | if (!test_and_set_bit(AXF_ERROR, &ax->flags)) |
946 | ax->dev->stats.rx_errors++; | 945 | ax->dev->stats.rx_errors++; |
@@ -953,8 +952,6 @@ static unsigned int mkiss_receive_buf(struct tty_struct *tty, | |||
953 | 952 | ||
954 | mkiss_put(ax); | 953 | mkiss_put(ax); |
955 | tty_unthrottle(tty); | 954 | tty_unthrottle(tty); |
956 | |||
957 | return count; | ||
958 | } | 955 | } |
959 | 956 | ||
960 | /* | 957 | /* |
diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c index c52a1df5d922..8e10d2f6a5ad 100644 --- a/drivers/net/hp100.c +++ b/drivers/net/hp100.c | |||
@@ -188,14 +188,14 @@ struct hp100_private { | |||
188 | * variables | 188 | * variables |
189 | */ | 189 | */ |
190 | #ifdef CONFIG_ISA | 190 | #ifdef CONFIG_ISA |
191 | static const char *const hp100_isa_tbl[] __devinitconst = { | 191 | static const char *hp100_isa_tbl[] = { |
192 | "HWPF150", /* HP J2573 rev A */ | 192 | "HWPF150", /* HP J2573 rev A */ |
193 | "HWP1950", /* HP J2573 */ | 193 | "HWP1950", /* HP J2573 */ |
194 | }; | 194 | }; |
195 | #endif | 195 | #endif |
196 | 196 | ||
197 | #ifdef CONFIG_EISA | 197 | #ifdef CONFIG_EISA |
198 | static const struct eisa_device_id hp100_eisa_tbl[] __devinitconst = { | 198 | static struct eisa_device_id hp100_eisa_tbl[] = { |
199 | { "HWPF180" }, /* HP J2577 rev A */ | 199 | { "HWPF180" }, /* HP J2577 rev A */ |
200 | { "HWP1920" }, /* HP 27248B */ | 200 | { "HWP1920" }, /* HP 27248B */ |
201 | { "HWP1940" }, /* HP J2577 */ | 201 | { "HWP1940" }, /* HP J2577 */ |
@@ -336,7 +336,7 @@ static __devinit const char *hp100_read_id(int ioaddr) | |||
336 | } | 336 | } |
337 | 337 | ||
338 | #ifdef CONFIG_ISA | 338 | #ifdef CONFIG_ISA |
339 | static __devinit int hp100_isa_probe1(struct net_device *dev, int ioaddr) | 339 | static __init int hp100_isa_probe1(struct net_device *dev, int ioaddr) |
340 | { | 340 | { |
341 | const char *sig; | 341 | const char *sig; |
342 | int i; | 342 | int i; |
@@ -372,7 +372,7 @@ static __devinit int hp100_isa_probe1(struct net_device *dev, int ioaddr) | |||
372 | * EISA and PCI are handled by device infrastructure. | 372 | * EISA and PCI are handled by device infrastructure. |
373 | */ | 373 | */ |
374 | 374 | ||
375 | static int __devinit hp100_isa_probe(struct net_device *dev, int addr) | 375 | static int __init hp100_isa_probe(struct net_device *dev, int addr) |
376 | { | 376 | { |
377 | int err = -ENODEV; | 377 | int err = -ENODEV; |
378 | 378 | ||
@@ -396,7 +396,7 @@ static int __devinit hp100_isa_probe(struct net_device *dev, int addr) | |||
396 | #endif /* CONFIG_ISA */ | 396 | #endif /* CONFIG_ISA */ |
397 | 397 | ||
398 | #if !defined(MODULE) && defined(CONFIG_ISA) | 398 | #if !defined(MODULE) && defined(CONFIG_ISA) |
399 | struct net_device * __devinit hp100_probe(int unit) | 399 | struct net_device * __init hp100_probe(int unit) |
400 | { | 400 | { |
401 | struct net_device *dev = alloc_etherdev(sizeof(struct hp100_private)); | 401 | struct net_device *dev = alloc_etherdev(sizeof(struct hp100_private)); |
402 | int err; | 402 | int err; |
@@ -2843,7 +2843,7 @@ static void cleanup_dev(struct net_device *d) | |||
2843 | } | 2843 | } |
2844 | 2844 | ||
2845 | #ifdef CONFIG_EISA | 2845 | #ifdef CONFIG_EISA |
2846 | static int __devinit hp100_eisa_probe (struct device *gendev) | 2846 | static int __init hp100_eisa_probe (struct device *gendev) |
2847 | { | 2847 | { |
2848 | struct net_device *dev = alloc_etherdev(sizeof(struct hp100_private)); | 2848 | struct net_device *dev = alloc_etherdev(sizeof(struct hp100_private)); |
2849 | struct eisa_device *edev = to_eisa_device(gendev); | 2849 | struct eisa_device *edev = to_eisa_device(gendev); |
diff --git a/drivers/net/ibmlana.c b/drivers/net/ibmlana.c index 136d7544cc33..a7d6cad32953 100644 --- a/drivers/net/ibmlana.c +++ b/drivers/net/ibmlana.c | |||
@@ -895,12 +895,12 @@ static int ibmlana_irq; | |||
895 | static int ibmlana_io; | 895 | static int ibmlana_io; |
896 | static int startslot; /* counts through slots when probing multiple devices */ | 896 | static int startslot; /* counts through slots when probing multiple devices */ |
897 | 897 | ||
898 | static const short ibmlana_adapter_ids[] __devinitconst = { | 898 | static short ibmlana_adapter_ids[] __initdata = { |
899 | IBM_LANA_ID, | 899 | IBM_LANA_ID, |
900 | 0x0000 | 900 | 0x0000 |
901 | }; | 901 | }; |
902 | 902 | ||
903 | static const char *const ibmlana_adapter_names[] __devinitconst = { | 903 | static char *ibmlana_adapter_names[] __devinitdata = { |
904 | "IBM LAN Adapter/A", | 904 | "IBM LAN Adapter/A", |
905 | NULL | 905 | NULL |
906 | }; | 906 | }; |
diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c index 035861d8acb1..3352b2443e58 100644 --- a/drivers/net/irda/irtty-sir.c +++ b/drivers/net/irda/irtty-sir.c | |||
@@ -216,23 +216,23 @@ static int irtty_do_write(struct sir_dev *dev, const unsigned char *ptr, size_t | |||
216 | * usbserial: urb-complete-interrupt / softint | 216 | * usbserial: urb-complete-interrupt / softint |
217 | */ | 217 | */ |
218 | 218 | ||
219 | static unsigned int irtty_receive_buf(struct tty_struct *tty, | 219 | static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp, |
220 | const unsigned char *cp, char *fp, int count) | 220 | char *fp, int count) |
221 | { | 221 | { |
222 | struct sir_dev *dev; | 222 | struct sir_dev *dev; |
223 | struct sirtty_cb *priv = tty->disc_data; | 223 | struct sirtty_cb *priv = tty->disc_data; |
224 | int i; | 224 | int i; |
225 | 225 | ||
226 | IRDA_ASSERT(priv != NULL, return -ENODEV;); | 226 | IRDA_ASSERT(priv != NULL, return;); |
227 | IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return -EINVAL;); | 227 | IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return;); |
228 | 228 | ||
229 | if (unlikely(count==0)) /* yes, this happens */ | 229 | if (unlikely(count==0)) /* yes, this happens */ |
230 | return 0; | 230 | return; |
231 | 231 | ||
232 | dev = priv->dev; | 232 | dev = priv->dev; |
233 | if (!dev) { | 233 | if (!dev) { |
234 | IRDA_WARNING("%s(), not ready yet!\n", __func__); | 234 | IRDA_WARNING("%s(), not ready yet!\n", __func__); |
235 | return -ENODEV; | 235 | return; |
236 | } | 236 | } |
237 | 237 | ||
238 | for (i = 0; i < count; i++) { | 238 | for (i = 0; i < count; i++) { |
@@ -242,13 +242,11 @@ static unsigned int irtty_receive_buf(struct tty_struct *tty, | |||
242 | if (fp && *fp++) { | 242 | if (fp && *fp++) { |
243 | IRDA_DEBUG(0, "Framing or parity error!\n"); | 243 | IRDA_DEBUG(0, "Framing or parity error!\n"); |
244 | sirdev_receive(dev, NULL, 0); /* notify sir_dev (updating stats) */ | 244 | sirdev_receive(dev, NULL, 0); /* notify sir_dev (updating stats) */ |
245 | return -EINVAL; | 245 | return; |
246 | } | 246 | } |
247 | } | 247 | } |
248 | 248 | ||
249 | sirdev_receive(dev, cp, count); | 249 | sirdev_receive(dev, cp, count); |
250 | |||
251 | return count; | ||
252 | } | 250 | } |
253 | 251 | ||
254 | /* | 252 | /* |
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c index 69b5707db369..8800e1fe4129 100644 --- a/drivers/net/irda/smsc-ircc2.c +++ b/drivers/net/irda/smsc-ircc2.c | |||
@@ -222,19 +222,19 @@ static void smsc_ircc_set_transceiver_for_speed(struct smsc_ircc_cb *self, u32 s | |||
222 | static void smsc_ircc_sir_wait_hw_transmitter_finish(struct smsc_ircc_cb *self); | 222 | static void smsc_ircc_sir_wait_hw_transmitter_finish(struct smsc_ircc_cb *self); |
223 | 223 | ||
224 | /* Probing */ | 224 | /* Probing */ |
225 | static int smsc_ircc_look_for_chips(void); | 225 | static int __init smsc_ircc_look_for_chips(void); |
226 | static const struct smsc_chip * smsc_ircc_probe(unsigned short cfg_base, u8 reg, const struct smsc_chip *chip, char *type); | 226 | static const struct smsc_chip * __init smsc_ircc_probe(unsigned short cfg_base, u8 reg, const struct smsc_chip *chip, char *type); |
227 | static int smsc_superio_flat(const struct smsc_chip *chips, unsigned short cfg_base, char *type); | 227 | static int __init smsc_superio_flat(const struct smsc_chip *chips, unsigned short cfg_base, char *type); |
228 | static int smsc_superio_paged(const struct smsc_chip *chips, unsigned short cfg_base, char *type); | 228 | static int __init smsc_superio_paged(const struct smsc_chip *chips, unsigned short cfg_base, char *type); |
229 | static int smsc_superio_fdc(unsigned short cfg_base); | 229 | static int __init smsc_superio_fdc(unsigned short cfg_base); |
230 | static int smsc_superio_lpc(unsigned short cfg_base); | 230 | static int __init smsc_superio_lpc(unsigned short cfg_base); |
231 | #ifdef CONFIG_PCI | 231 | #ifdef CONFIG_PCI |
232 | static int preconfigure_smsc_chip(struct smsc_ircc_subsystem_configuration *conf); | 232 | static int __init preconfigure_smsc_chip(struct smsc_ircc_subsystem_configuration *conf); |
233 | static int preconfigure_through_82801(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf); | 233 | static int __init preconfigure_through_82801(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf); |
234 | static void preconfigure_ali_port(struct pci_dev *dev, | 234 | static void __init preconfigure_ali_port(struct pci_dev *dev, |
235 | unsigned short port); | 235 | unsigned short port); |
236 | static int preconfigure_through_ali(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf); | 236 | static int __init preconfigure_through_ali(struct pci_dev *dev, struct smsc_ircc_subsystem_configuration *conf); |
237 | static int smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg, | 237 | static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg, |
238 | unsigned short ircc_fir, | 238 | unsigned short ircc_fir, |
239 | unsigned short ircc_sir, | 239 | unsigned short ircc_sir, |
240 | unsigned char ircc_dma, | 240 | unsigned char ircc_dma, |
@@ -366,7 +366,7 @@ static inline void register_bank(int iobase, int bank) | |||
366 | } | 366 | } |
367 | 367 | ||
368 | /* PNP hotplug support */ | 368 | /* PNP hotplug support */ |
369 | static const struct pnp_device_id smsc_ircc_pnp_table[] __devinitconst = { | 369 | static const struct pnp_device_id smsc_ircc_pnp_table[] = { |
370 | { .id = "SMCf010", .driver_data = 0 }, | 370 | { .id = "SMCf010", .driver_data = 0 }, |
371 | /* and presumably others */ | 371 | /* and presumably others */ |
372 | { } | 372 | { } |
@@ -515,7 +515,7 @@ static const struct net_device_ops smsc_ircc_netdev_ops = { | |||
515 | * Try to open driver instance | 515 | * Try to open driver instance |
516 | * | 516 | * |
517 | */ | 517 | */ |
518 | static int __devinit smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u8 dma, u8 irq) | 518 | static int __init smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u8 dma, u8 irq) |
519 | { | 519 | { |
520 | struct smsc_ircc_cb *self; | 520 | struct smsc_ircc_cb *self; |
521 | struct net_device *dev; | 521 | struct net_device *dev; |
@@ -2273,7 +2273,7 @@ static int __init smsc_superio_paged(const struct smsc_chip *chips, unsigned sho | |||
2273 | } | 2273 | } |
2274 | 2274 | ||
2275 | 2275 | ||
2276 | static int __devinit smsc_access(unsigned short cfg_base, unsigned char reg) | 2276 | static int __init smsc_access(unsigned short cfg_base, unsigned char reg) |
2277 | { | 2277 | { |
2278 | IRDA_DEBUG(1, "%s\n", __func__); | 2278 | IRDA_DEBUG(1, "%s\n", __func__); |
2279 | 2279 | ||
@@ -2281,7 +2281,7 @@ static int __devinit smsc_access(unsigned short cfg_base, unsigned char reg) | |||
2281 | return inb(cfg_base) != reg ? -1 : 0; | 2281 | return inb(cfg_base) != reg ? -1 : 0; |
2282 | } | 2282 | } |
2283 | 2283 | ||
2284 | static const struct smsc_chip * __devinit smsc_ircc_probe(unsigned short cfg_base, u8 reg, const struct smsc_chip *chip, char *type) | 2284 | static const struct smsc_chip * __init smsc_ircc_probe(unsigned short cfg_base, u8 reg, const struct smsc_chip *chip, char *type) |
2285 | { | 2285 | { |
2286 | u8 devid, xdevid, rev; | 2286 | u8 devid, xdevid, rev; |
2287 | 2287 | ||
@@ -2406,7 +2406,7 @@ static int __init smsc_superio_lpc(unsigned short cfg_base) | |||
2406 | #ifdef CONFIG_PCI | 2406 | #ifdef CONFIG_PCI |
2407 | #define PCIID_VENDOR_INTEL 0x8086 | 2407 | #define PCIID_VENDOR_INTEL 0x8086 |
2408 | #define PCIID_VENDOR_ALI 0x10b9 | 2408 | #define PCIID_VENDOR_ALI 0x10b9 |
2409 | static const struct smsc_ircc_subsystem_configuration subsystem_configurations[] __devinitconst = { | 2409 | static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __initdata = { |
2410 | /* | 2410 | /* |
2411 | * Subsystems needing entries: | 2411 | * Subsystems needing entries: |
2412 | * 0x10b9:0x1533 0x103c:0x0850 HP nx9010 family | 2412 | * 0x10b9:0x1533 0x103c:0x0850 HP nx9010 family |
@@ -2532,7 +2532,7 @@ static const struct smsc_ircc_subsystem_configuration subsystem_configurations[] | |||
2532 | * (FIR port, SIR port, FIR DMA, FIR IRQ) | 2532 | * (FIR port, SIR port, FIR DMA, FIR IRQ) |
2533 | * through the chip configuration port. | 2533 | * through the chip configuration port. |
2534 | */ | 2534 | */ |
2535 | static int __devinit preconfigure_smsc_chip(struct | 2535 | static int __init preconfigure_smsc_chip(struct |
2536 | smsc_ircc_subsystem_configuration | 2536 | smsc_ircc_subsystem_configuration |
2537 | *conf) | 2537 | *conf) |
2538 | { | 2538 | { |
@@ -2633,7 +2633,7 @@ static int __devinit preconfigure_smsc_chip(struct | |||
2633 | * or Intel 82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge. | 2633 | * or Intel 82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge. |
2634 | * They all work the same way! | 2634 | * They all work the same way! |
2635 | */ | 2635 | */ |
2636 | static int __devinit preconfigure_through_82801(struct pci_dev *dev, | 2636 | static int __init preconfigure_through_82801(struct pci_dev *dev, |
2637 | struct | 2637 | struct |
2638 | smsc_ircc_subsystem_configuration | 2638 | smsc_ircc_subsystem_configuration |
2639 | *conf) | 2639 | *conf) |
@@ -2786,7 +2786,7 @@ static int __devinit preconfigure_through_82801(struct pci_dev *dev, | |||
2786 | * This is based on reverse-engineering since ALi does not | 2786 | * This is based on reverse-engineering since ALi does not |
2787 | * provide any data sheet for the 1533 chip. | 2787 | * provide any data sheet for the 1533 chip. |
2788 | */ | 2788 | */ |
2789 | static void __devinit preconfigure_ali_port(struct pci_dev *dev, | 2789 | static void __init preconfigure_ali_port(struct pci_dev *dev, |
2790 | unsigned short port) | 2790 | unsigned short port) |
2791 | { | 2791 | { |
2792 | unsigned char reg; | 2792 | unsigned char reg; |
@@ -2824,7 +2824,7 @@ static void __devinit preconfigure_ali_port(struct pci_dev *dev, | |||
2824 | IRDA_MESSAGE("Activated ALi 1533 ISA bridge port 0x%04x.\n", port); | 2824 | IRDA_MESSAGE("Activated ALi 1533 ISA bridge port 0x%04x.\n", port); |
2825 | } | 2825 | } |
2826 | 2826 | ||
2827 | static int __devinit preconfigure_through_ali(struct pci_dev *dev, | 2827 | static int __init preconfigure_through_ali(struct pci_dev *dev, |
2828 | struct | 2828 | struct |
2829 | smsc_ircc_subsystem_configuration | 2829 | smsc_ircc_subsystem_configuration |
2830 | *conf) | 2830 | *conf) |
@@ -2837,7 +2837,7 @@ static int __devinit preconfigure_through_ali(struct pci_dev *dev, | |||
2837 | return preconfigure_smsc_chip(conf); | 2837 | return preconfigure_smsc_chip(conf); |
2838 | } | 2838 | } |
2839 | 2839 | ||
2840 | static int __devinit smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg, | 2840 | static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg, |
2841 | unsigned short ircc_fir, | 2841 | unsigned short ircc_fir, |
2842 | unsigned short ircc_sir, | 2842 | unsigned short ircc_sir, |
2843 | unsigned char ircc_dma, | 2843 | unsigned char ircc_dma, |
@@ -2849,7 +2849,7 @@ static int __devinit smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg, | |||
2849 | int ret = 0; | 2849 | int ret = 0; |
2850 | 2850 | ||
2851 | for_each_pci_dev(dev) { | 2851 | for_each_pci_dev(dev) { |
2852 | const struct smsc_ircc_subsystem_configuration *conf; | 2852 | struct smsc_ircc_subsystem_configuration *conf; |
2853 | 2853 | ||
2854 | /* | 2854 | /* |
2855 | * Cache the subsystem vendor/device: | 2855 | * Cache the subsystem vendor/device: |
diff --git a/drivers/net/ks8842.c b/drivers/net/ks8842.c index 4d40626b3bfa..fc12ac0d9f2e 100644 --- a/drivers/net/ks8842.c +++ b/drivers/net/ks8842.c | |||
@@ -661,7 +661,7 @@ static void ks8842_rx_frame(struct net_device *netdev, | |||
661 | 661 | ||
662 | /* check the status */ | 662 | /* check the status */ |
663 | if ((status & RXSR_VALID) && !(status & RXSR_ERROR)) { | 663 | if ((status & RXSR_VALID) && !(status & RXSR_ERROR)) { |
664 | struct sk_buff *skb = netdev_alloc_skb_ip_align(netdev, len); | 664 | struct sk_buff *skb = netdev_alloc_skb_ip_align(netdev, len + 3); |
665 | 665 | ||
666 | if (skb) { | 666 | if (skb) { |
667 | 667 | ||
diff --git a/drivers/net/ne3210.c b/drivers/net/ne3210.c index e8984b0ca521..243ed2aee88e 100644 --- a/drivers/net/ne3210.c +++ b/drivers/net/ne3210.c | |||
@@ -80,20 +80,17 @@ static void ne3210_block_output(struct net_device *dev, int count, const unsigne | |||
80 | 80 | ||
81 | #define NE3210_DEBUG 0x0 | 81 | #define NE3210_DEBUG 0x0 |
82 | 82 | ||
83 | static const unsigned char irq_map[] __devinitconst = | 83 | static unsigned char irq_map[] __initdata = {15, 12, 11, 10, 9, 7, 5, 3}; |
84 | { 15, 12, 11, 10, 9, 7, 5, 3 }; | 84 | static unsigned int shmem_map[] __initdata = {0xff0, 0xfe0, 0xfff0, 0xd8, 0xffe0, 0xffc0, 0xd0, 0x0}; |
85 | static const unsigned int shmem_map[] __devinitconst = | 85 | static const char *ifmap[] __initdata = {"UTP", "?", "BNC", "AUI"}; |
86 | { 0xff0, 0xfe0, 0xfff0, 0xd8, 0xffe0, 0xffc0, 0xd0, 0x0 }; | 86 | static int ifmap_val[] __initdata = { |
87 | static const char *const ifmap[] __devinitconst = | ||
88 | { "UTP", "?", "BNC", "AUI" }; | ||
89 | static const int ifmap_val[] __devinitconst = { | ||
90 | IF_PORT_10BASET, | 87 | IF_PORT_10BASET, |
91 | IF_PORT_UNKNOWN, | 88 | IF_PORT_UNKNOWN, |
92 | IF_PORT_10BASE2, | 89 | IF_PORT_10BASE2, |
93 | IF_PORT_AUI, | 90 | IF_PORT_AUI, |
94 | }; | 91 | }; |
95 | 92 | ||
96 | static int __devinit ne3210_eisa_probe (struct device *device) | 93 | static int __init ne3210_eisa_probe (struct device *device) |
97 | { | 94 | { |
98 | unsigned long ioaddr, phys_mem; | 95 | unsigned long ioaddr, phys_mem; |
99 | int i, retval, port_index; | 96 | int i, retval, port_index; |
@@ -316,7 +313,7 @@ static void ne3210_block_output(struct net_device *dev, int count, | |||
316 | memcpy_toio(shmem, buf, count); | 313 | memcpy_toio(shmem, buf, count); |
317 | } | 314 | } |
318 | 315 | ||
319 | static const struct eisa_device_id ne3210_ids[] __devinitconst = { | 316 | static struct eisa_device_id ne3210_ids[] = { |
320 | { "EGL0101" }, | 317 | { "EGL0101" }, |
321 | { "NVL1801" }, | 318 | { "NVL1801" }, |
322 | { "" }, | 319 | { "" }, |
diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c index 53872d7d7382..a1b82c9c67d2 100644 --- a/drivers/net/ppp_async.c +++ b/drivers/net/ppp_async.c | |||
@@ -340,7 +340,7 @@ ppp_asynctty_poll(struct tty_struct *tty, struct file *file, poll_table *wait) | |||
340 | } | 340 | } |
341 | 341 | ||
342 | /* May sleep, don't call from interrupt level or with interrupts disabled */ | 342 | /* May sleep, don't call from interrupt level or with interrupts disabled */ |
343 | static unsigned int | 343 | static void |
344 | ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf, | 344 | ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf, |
345 | char *cflags, int count) | 345 | char *cflags, int count) |
346 | { | 346 | { |
@@ -348,7 +348,7 @@ ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf, | |||
348 | unsigned long flags; | 348 | unsigned long flags; |
349 | 349 | ||
350 | if (!ap) | 350 | if (!ap) |
351 | return -ENODEV; | 351 | return; |
352 | spin_lock_irqsave(&ap->recv_lock, flags); | 352 | spin_lock_irqsave(&ap->recv_lock, flags); |
353 | ppp_async_input(ap, buf, cflags, count); | 353 | ppp_async_input(ap, buf, cflags, count); |
354 | spin_unlock_irqrestore(&ap->recv_lock, flags); | 354 | spin_unlock_irqrestore(&ap->recv_lock, flags); |
@@ -356,8 +356,6 @@ ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf, | |||
356 | tasklet_schedule(&ap->tsk); | 356 | tasklet_schedule(&ap->tsk); |
357 | ap_put(ap); | 357 | ap_put(ap); |
358 | tty_unthrottle(tty); | 358 | tty_unthrottle(tty); |
359 | |||
360 | return count; | ||
361 | } | 359 | } |
362 | 360 | ||
363 | static void | 361 | static void |
diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c index 0815790a5cf9..2573f525f11c 100644 --- a/drivers/net/ppp_synctty.c +++ b/drivers/net/ppp_synctty.c | |||
@@ -381,7 +381,7 @@ ppp_sync_poll(struct tty_struct *tty, struct file *file, poll_table *wait) | |||
381 | } | 381 | } |
382 | 382 | ||
383 | /* May sleep, don't call from interrupt level or with interrupts disabled */ | 383 | /* May sleep, don't call from interrupt level or with interrupts disabled */ |
384 | static unsigned int | 384 | static void |
385 | ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf, | 385 | ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf, |
386 | char *cflags, int count) | 386 | char *cflags, int count) |
387 | { | 387 | { |
@@ -389,7 +389,7 @@ ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf, | |||
389 | unsigned long flags; | 389 | unsigned long flags; |
390 | 390 | ||
391 | if (!ap) | 391 | if (!ap) |
392 | return -ENODEV; | 392 | return; |
393 | spin_lock_irqsave(&ap->recv_lock, flags); | 393 | spin_lock_irqsave(&ap->recv_lock, flags); |
394 | ppp_sync_input(ap, buf, cflags, count); | 394 | ppp_sync_input(ap, buf, cflags, count); |
395 | spin_unlock_irqrestore(&ap->recv_lock, flags); | 395 | spin_unlock_irqrestore(&ap->recv_lock, flags); |
@@ -397,8 +397,6 @@ ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf, | |||
397 | tasklet_schedule(&ap->tsk); | 397 | tasklet_schedule(&ap->tsk); |
398 | sp_put(ap); | 398 | sp_put(ap); |
399 | tty_unthrottle(tty); | 399 | tty_unthrottle(tty); |
400 | |||
401 | return count; | ||
402 | } | 400 | } |
403 | 401 | ||
404 | static void | 402 | static void |
diff --git a/drivers/net/slip.c b/drivers/net/slip.c index 584809c656d5..8ec1a9a0bb9a 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c | |||
@@ -670,17 +670,16 @@ static void sl_setup(struct net_device *dev) | |||
670 | * in parallel | 670 | * in parallel |
671 | */ | 671 | */ |
672 | 672 | ||
673 | static unsigned int slip_receive_buf(struct tty_struct *tty, | 673 | static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp, |
674 | const unsigned char *cp, char *fp, int count) | 674 | char *fp, int count) |
675 | { | 675 | { |
676 | struct slip *sl = tty->disc_data; | 676 | struct slip *sl = tty->disc_data; |
677 | int bytes = count; | ||
678 | 677 | ||
679 | if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev)) | 678 | if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev)) |
680 | return -ENODEV; | 679 | return; |
681 | 680 | ||
682 | /* Read the characters out of the buffer */ | 681 | /* Read the characters out of the buffer */ |
683 | while (bytes--) { | 682 | while (count--) { |
684 | if (fp && *fp++) { | 683 | if (fp && *fp++) { |
685 | if (!test_and_set_bit(SLF_ERROR, &sl->flags)) | 684 | if (!test_and_set_bit(SLF_ERROR, &sl->flags)) |
686 | sl->dev->stats.rx_errors++; | 685 | sl->dev->stats.rx_errors++; |
@@ -694,8 +693,6 @@ static unsigned int slip_receive_buf(struct tty_struct *tty, | |||
694 | #endif | 693 | #endif |
695 | slip_unesc(sl, *cp++); | 694 | slip_unesc(sl, *cp++); |
696 | } | 695 | } |
697 | |||
698 | return count; | ||
699 | } | 696 | } |
700 | 697 | ||
701 | /************************************ | 698 | /************************************ |
diff --git a/drivers/net/smc-mca.c b/drivers/net/smc-mca.c index 0f29f261fcfe..d07c39cb4daf 100644 --- a/drivers/net/smc-mca.c +++ b/drivers/net/smc-mca.c | |||
@@ -156,7 +156,7 @@ static const struct { | |||
156 | { 14, 15 } | 156 | { 14, 15 } |
157 | }; | 157 | }; |
158 | 158 | ||
159 | static const short smc_mca_adapter_ids[] __devinitconst = { | 159 | static short smc_mca_adapter_ids[] __initdata = { |
160 | 0x61c8, | 160 | 0x61c8, |
161 | 0x61c9, | 161 | 0x61c9, |
162 | 0x6fc0, | 162 | 0x6fc0, |
@@ -168,7 +168,7 @@ static const short smc_mca_adapter_ids[] __devinitconst = { | |||
168 | 0x0000 | 168 | 0x0000 |
169 | }; | 169 | }; |
170 | 170 | ||
171 | static const char *const smc_mca_adapter_names[] __devinitconst = { | 171 | static char *smc_mca_adapter_names[] __initdata = { |
172 | "SMC Ethercard PLUS Elite/A BNC/AUI (WD8013EP/A)", | 172 | "SMC Ethercard PLUS Elite/A BNC/AUI (WD8013EP/A)", |
173 | "SMC Ethercard PLUS Elite/A UTP/AUI (WD8013WP/A)", | 173 | "SMC Ethercard PLUS Elite/A UTP/AUI (WD8013WP/A)", |
174 | "WD Ethercard PLUS/A (WD8003E/A or WD8003ET/A)", | 174 | "WD Ethercard PLUS/A (WD8003E/A or WD8003ET/A)", |
@@ -199,7 +199,7 @@ static const struct net_device_ops ultramca_netdev_ops = { | |||
199 | #endif | 199 | #endif |
200 | }; | 200 | }; |
201 | 201 | ||
202 | static int __devinit ultramca_probe(struct device *gen_dev) | 202 | static int __init ultramca_probe(struct device *gen_dev) |
203 | { | 203 | { |
204 | unsigned short ioaddr; | 204 | unsigned short ioaddr; |
205 | struct net_device *dev; | 205 | struct net_device *dev; |
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index f4b01c638a33..a1f9f9eef37d 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -5774,7 +5774,7 @@ static void tg3_skb_error_unmap(struct tg3_napi *tnapi, | |||
5774 | dma_unmap_addr(txb, mapping), | 5774 | dma_unmap_addr(txb, mapping), |
5775 | skb_headlen(skb), | 5775 | skb_headlen(skb), |
5776 | PCI_DMA_TODEVICE); | 5776 | PCI_DMA_TODEVICE); |
5777 | for (i = 0; i <= last; i++) { | 5777 | for (i = 0; i < last; i++) { |
5778 | skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; | 5778 | skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; |
5779 | 5779 | ||
5780 | entry = NEXT_TX(entry); | 5780 | entry = NEXT_TX(entry); |
diff --git a/drivers/net/tokenring/madgemc.c b/drivers/net/tokenring/madgemc.c index 1313aa1315f0..2bedc0ace812 100644 --- a/drivers/net/tokenring/madgemc.c +++ b/drivers/net/tokenring/madgemc.c | |||
@@ -727,7 +727,7 @@ static int __devexit madgemc_remove(struct device *device) | |||
727 | return 0; | 727 | return 0; |
728 | } | 728 | } |
729 | 729 | ||
730 | static const short madgemc_adapter_ids[] __devinitconst = { | 730 | static short madgemc_adapter_ids[] __initdata = { |
731 | 0x002d, | 731 | 0x002d, |
732 | 0x0000 | 732 | 0x0000 |
733 | }; | 733 | }; |
diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c index 45144d5bd11b..efaa1d69b720 100644 --- a/drivers/net/tulip/de4x5.c +++ b/drivers/net/tulip/de4x5.c | |||
@@ -1995,7 +1995,7 @@ SetMulticastFilter(struct net_device *dev) | |||
1995 | 1995 | ||
1996 | static u_char de4x5_irq[] = EISA_ALLOWED_IRQ_LIST; | 1996 | static u_char de4x5_irq[] = EISA_ALLOWED_IRQ_LIST; |
1997 | 1997 | ||
1998 | static int __devinit de4x5_eisa_probe (struct device *gendev) | 1998 | static int __init de4x5_eisa_probe (struct device *gendev) |
1999 | { | 1999 | { |
2000 | struct eisa_device *edev; | 2000 | struct eisa_device *edev; |
2001 | u_long iobase; | 2001 | u_long iobase; |
@@ -2097,7 +2097,7 @@ static int __devexit de4x5_eisa_remove (struct device *device) | |||
2097 | return 0; | 2097 | return 0; |
2098 | } | 2098 | } |
2099 | 2099 | ||
2100 | static const struct eisa_device_id de4x5_eisa_ids[] __devinitconst = { | 2100 | static struct eisa_device_id de4x5_eisa_ids[] = { |
2101 | { "DEC4250", 0 }, /* 0 is the board name index... */ | 2101 | { "DEC4250", 0 }, /* 0 is the board name index... */ |
2102 | { "" } | 2102 | { "" } |
2103 | }; | 2103 | }; |
diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c index d7221c4a5dcf..8056f8a27c6a 100644 --- a/drivers/net/usb/catc.c +++ b/drivers/net/usb/catc.c | |||
@@ -495,7 +495,7 @@ static void catc_ctrl_run(struct catc *catc) | |||
495 | if (!q->dir && q->buf && q->len) | 495 | if (!q->dir && q->buf && q->len) |
496 | memcpy(catc->ctrl_buf, q->buf, q->len); | 496 | memcpy(catc->ctrl_buf, q->buf, q->len); |
497 | 497 | ||
498 | if ((status = usb_submit_urb(catc->ctrl_urb, GFP_KERNEL))) | 498 | if ((status = usb_submit_urb(catc->ctrl_urb, GFP_ATOMIC))) |
499 | err("submit(ctrl_urb) status %d", status); | 499 | err("submit(ctrl_urb) status %d", status); |
500 | } | 500 | } |
501 | 501 | ||
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index cdd3ae486109..f33ca6aa29e9 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c | |||
@@ -54,7 +54,7 @@ | |||
54 | #include <linux/usb/usbnet.h> | 54 | #include <linux/usb/usbnet.h> |
55 | #include <linux/usb/cdc.h> | 55 | #include <linux/usb/cdc.h> |
56 | 56 | ||
57 | #define DRIVER_VERSION "24-May-2011" | 57 | #define DRIVER_VERSION "01-June-2011" |
58 | 58 | ||
59 | /* CDC NCM subclass 3.2.1 */ | 59 | /* CDC NCM subclass 3.2.1 */ |
60 | #define USB_CDC_NCM_NDP16_LENGTH_MIN 0x10 | 60 | #define USB_CDC_NCM_NDP16_LENGTH_MIN 0x10 |
@@ -1234,6 +1234,7 @@ static struct usb_driver cdc_ncm_driver = { | |||
1234 | .disconnect = cdc_ncm_disconnect, | 1234 | .disconnect = cdc_ncm_disconnect, |
1235 | .suspend = usbnet_suspend, | 1235 | .suspend = usbnet_suspend, |
1236 | .resume = usbnet_resume, | 1236 | .resume = usbnet_resume, |
1237 | .reset_resume = usbnet_resume, | ||
1237 | .supports_autosuspend = 1, | 1238 | .supports_autosuspend = 1, |
1238 | }; | 1239 | }; |
1239 | 1240 | ||
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 0cb0b0632672..f6853247a620 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -609,7 +609,7 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
609 | * before it gets out of hand. Naturally, this wastes entries. */ | 609 | * before it gets out of hand. Naturally, this wastes entries. */ |
610 | if (capacity < 2+MAX_SKB_FRAGS) { | 610 | if (capacity < 2+MAX_SKB_FRAGS) { |
611 | netif_stop_queue(dev); | 611 | netif_stop_queue(dev); |
612 | if (unlikely(!virtqueue_enable_cb(vi->svq))) { | 612 | if (unlikely(!virtqueue_enable_cb_delayed(vi->svq))) { |
613 | /* More just got used, free them then recheck. */ | 613 | /* More just got used, free them then recheck. */ |
614 | capacity += free_old_xmit_skbs(vi); | 614 | capacity += free_old_xmit_skbs(vi); |
615 | if (capacity >= 2+MAX_SKB_FRAGS) { | 615 | if (capacity >= 2+MAX_SKB_FRAGS) { |
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c index 40398bf7d036..24297b274cd4 100644 --- a/drivers/net/wan/x25_asy.c +++ b/drivers/net/wan/x25_asy.c | |||
@@ -517,18 +517,17 @@ static int x25_asy_close(struct net_device *dev) | |||
517 | * and sent on to some IP layer for further processing. | 517 | * and sent on to some IP layer for further processing. |
518 | */ | 518 | */ |
519 | 519 | ||
520 | static unsigned int x25_asy_receive_buf(struct tty_struct *tty, | 520 | static void x25_asy_receive_buf(struct tty_struct *tty, |
521 | const unsigned char *cp, char *fp, int count) | 521 | const unsigned char *cp, char *fp, int count) |
522 | { | 522 | { |
523 | struct x25_asy *sl = tty->disc_data; | 523 | struct x25_asy *sl = tty->disc_data; |
524 | int bytes = count; | ||
525 | 524 | ||
526 | if (!sl || sl->magic != X25_ASY_MAGIC || !netif_running(sl->dev)) | 525 | if (!sl || sl->magic != X25_ASY_MAGIC || !netif_running(sl->dev)) |
527 | return; | 526 | return; |
528 | 527 | ||
529 | 528 | ||
530 | /* Read the characters out of the buffer */ | 529 | /* Read the characters out of the buffer */ |
531 | while (bytes--) { | 530 | while (count--) { |
532 | if (fp && *fp++) { | 531 | if (fp && *fp++) { |
533 | if (!test_and_set_bit(SLF_ERROR, &sl->flags)) | 532 | if (!test_and_set_bit(SLF_ERROR, &sl->flags)) |
534 | sl->dev->stats.rx_errors++; | 533 | sl->dev->stats.rx_errors++; |
@@ -537,8 +536,6 @@ static unsigned int x25_asy_receive_buf(struct tty_struct *tty, | |||
537 | } | 536 | } |
538 | x25_asy_unesc(sl, *cp++); | 537 | x25_asy_unesc(sl, *cp++); |
539 | } | 538 | } |
540 | |||
541 | return count; | ||
542 | } | 539 | } |
543 | 540 | ||
544 | /* | 541 | /* |
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig index d9ff8413ab9a..d9c08c619a3a 100644 --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig | |||
@@ -26,7 +26,6 @@ config ATH9K | |||
26 | config ATH9K_PCI | 26 | config ATH9K_PCI |
27 | bool "Atheros ath9k PCI/PCIe bus support" | 27 | bool "Atheros ath9k PCI/PCIe bus support" |
28 | depends on ATH9K && PCI | 28 | depends on ATH9K && PCI |
29 | default PCI | ||
30 | ---help--- | 29 | ---help--- |
31 | This option enables the PCI bus support in ath9k. | 30 | This option enables the PCI bus support in ath9k. |
32 | 31 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c index 015d97439935..2d4c0910295b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c | |||
@@ -829,7 +829,7 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) | |||
829 | if (AR_SREV_9271(ah)) { | 829 | if (AR_SREV_9271(ah)) { |
830 | if (!ar9285_hw_cl_cal(ah, chan)) | 830 | if (!ar9285_hw_cl_cal(ah, chan)) |
831 | return false; | 831 | return false; |
832 | } else if (AR_SREV_9285_12_OR_LATER(ah)) { | 832 | } else if (AR_SREV_9285(ah) && AR_SREV_9285_12_OR_LATER(ah)) { |
833 | if (!ar9285_hw_clc(ah, chan)) | 833 | if (!ar9285_hw_clc(ah, chan)) |
834 | return false; | 834 | return false; |
835 | } else { | 835 | } else { |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 0ca7635d0669..ff8150e46f0e 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | |||
@@ -4645,10 +4645,16 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah, | |||
4645 | case 1: | 4645 | case 1: |
4646 | break; | 4646 | break; |
4647 | case 2: | 4647 | case 2: |
4648 | scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; | 4648 | if (scaledPower > REDUCE_SCALED_POWER_BY_TWO_CHAIN) |
4649 | scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; | ||
4650 | else | ||
4651 | scaledPower = 0; | ||
4649 | break; | 4652 | break; |
4650 | case 3: | 4653 | case 3: |
4651 | scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; | 4654 | if (scaledPower > REDUCE_SCALED_POWER_BY_THREE_CHAIN) |
4655 | scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; | ||
4656 | else | ||
4657 | scaledPower = 0; | ||
4652 | break; | 4658 | break; |
4653 | } | 4659 | } |
4654 | 4660 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index eee23ecd118a..892c48b15434 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c | |||
@@ -1381,3 +1381,25 @@ void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah) | |||
1381 | "==== BB update: done ====\n\n"); | 1381 | "==== BB update: done ====\n\n"); |
1382 | } | 1382 | } |
1383 | EXPORT_SYMBOL(ar9003_hw_bb_watchdog_dbg_info); | 1383 | EXPORT_SYMBOL(ar9003_hw_bb_watchdog_dbg_info); |
1384 | |||
1385 | void ar9003_hw_disable_phy_restart(struct ath_hw *ah) | ||
1386 | { | ||
1387 | u32 val; | ||
1388 | |||
1389 | /* While receiving unsupported rate frame rx state machine | ||
1390 | * gets into a state 0xb and if phy_restart happens in that | ||
1391 | * state, BB would go hang. If RXSM is in 0xb state after | ||
1392 | * first bb panic, ensure to disable the phy_restart. | ||
1393 | */ | ||
1394 | if (!((MS(ah->bb_watchdog_last_status, | ||
1395 | AR_PHY_WATCHDOG_RX_OFDM_SM) == 0xb) || | ||
1396 | ah->bb_hang_rx_ofdm)) | ||
1397 | return; | ||
1398 | |||
1399 | ah->bb_hang_rx_ofdm = true; | ||
1400 | val = REG_READ(ah, AR_PHY_RESTART); | ||
1401 | val &= ~AR_PHY_RESTART_ENA; | ||
1402 | |||
1403 | REG_WRITE(ah, AR_PHY_RESTART, val); | ||
1404 | } | ||
1405 | EXPORT_SYMBOL(ar9003_hw_disable_phy_restart); | ||
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index 7856f0d4512d..343fc9f946db 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c | |||
@@ -524,10 +524,16 @@ static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah, | |||
524 | case 1: | 524 | case 1: |
525 | break; | 525 | break; |
526 | case 2: | 526 | case 2: |
527 | scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; | 527 | if (scaledPower > REDUCE_SCALED_POWER_BY_TWO_CHAIN) |
528 | scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; | ||
529 | else | ||
530 | scaledPower = 0; | ||
528 | break; | 531 | break; |
529 | case 3: | 532 | case 3: |
530 | scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; | 533 | if (scaledPower > REDUCE_SCALED_POWER_BY_THREE_CHAIN) |
534 | scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; | ||
535 | else | ||
536 | scaledPower = 0; | ||
531 | break; | 537 | break; |
532 | } | 538 | } |
533 | scaledPower = max((u16)0, scaledPower); | 539 | scaledPower = max((u16)0, scaledPower); |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 72543ce8f616..1be7c8bbef84 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -1555,9 +1555,12 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1555 | if (ah->btcoex_hw.enabled) | 1555 | if (ah->btcoex_hw.enabled) |
1556 | ath9k_hw_btcoex_enable(ah); | 1556 | ath9k_hw_btcoex_enable(ah); |
1557 | 1557 | ||
1558 | if (AR_SREV_9300_20_OR_LATER(ah)) | 1558 | if (AR_SREV_9300_20_OR_LATER(ah)) { |
1559 | ar9003_hw_bb_watchdog_config(ah); | 1559 | ar9003_hw_bb_watchdog_config(ah); |
1560 | 1560 | ||
1561 | ar9003_hw_disable_phy_restart(ah); | ||
1562 | } | ||
1563 | |||
1561 | ath9k_hw_apply_gpio_override(ah); | 1564 | ath9k_hw_apply_gpio_override(ah); |
1562 | 1565 | ||
1563 | return 0; | 1566 | return 0; |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 57435ce62792..4b157c53d1a8 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -842,6 +842,7 @@ struct ath_hw { | |||
842 | 842 | ||
843 | u32 bb_watchdog_last_status; | 843 | u32 bb_watchdog_last_status; |
844 | u32 bb_watchdog_timeout_ms; /* in ms, 0 to disable */ | 844 | u32 bb_watchdog_timeout_ms; /* in ms, 0 to disable */ |
845 | u8 bb_hang_rx_ofdm; /* true if bb hang due to rx_ofdm */ | ||
845 | 846 | ||
846 | unsigned int paprd_target_power; | 847 | unsigned int paprd_target_power; |
847 | unsigned int paprd_training_power; | 848 | unsigned int paprd_training_power; |
@@ -990,6 +991,7 @@ void ar9002_hw_enable_wep_aggregation(struct ath_hw *ah); | |||
990 | void ar9003_hw_bb_watchdog_config(struct ath_hw *ah); | 991 | void ar9003_hw_bb_watchdog_config(struct ath_hw *ah); |
991 | void ar9003_hw_bb_watchdog_read(struct ath_hw *ah); | 992 | void ar9003_hw_bb_watchdog_read(struct ath_hw *ah); |
992 | void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah); | 993 | void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah); |
994 | void ar9003_hw_disable_phy_restart(struct ath_hw *ah); | ||
993 | void ar9003_paprd_enable(struct ath_hw *ah, bool val); | 995 | void ar9003_paprd_enable(struct ath_hw *ah, bool val); |
994 | void ar9003_paprd_populate_single_table(struct ath_hw *ah, | 996 | void ar9003_paprd_populate_single_table(struct ath_hw *ah, |
995 | struct ath9k_hw_cal_data *caldata, | 997 | struct ath9k_hw_cal_data *caldata, |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index a198ee374b05..2ca351fe6d3c 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -670,7 +670,8 @@ void ath9k_tasklet(unsigned long data) | |||
670 | u32 status = sc->intrstatus; | 670 | u32 status = sc->intrstatus; |
671 | u32 rxmask; | 671 | u32 rxmask; |
672 | 672 | ||
673 | if (status & ATH9K_INT_FATAL) { | 673 | if ((status & ATH9K_INT_FATAL) || |
674 | (status & ATH9K_INT_BB_WATCHDOG)) { | ||
674 | ath_reset(sc, true); | 675 | ath_reset(sc, true); |
675 | return; | 676 | return; |
676 | } | 677 | } |
@@ -737,6 +738,7 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
737 | { | 738 | { |
738 | #define SCHED_INTR ( \ | 739 | #define SCHED_INTR ( \ |
739 | ATH9K_INT_FATAL | \ | 740 | ATH9K_INT_FATAL | \ |
741 | ATH9K_INT_BB_WATCHDOG | \ | ||
740 | ATH9K_INT_RXORN | \ | 742 | ATH9K_INT_RXORN | \ |
741 | ATH9K_INT_RXEOL | \ | 743 | ATH9K_INT_RXEOL | \ |
742 | ATH9K_INT_RX | \ | 744 | ATH9K_INT_RX | \ |
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 17542214c93f..ba7f36ab0a74 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c | |||
@@ -689,7 +689,8 @@ static void ath_rc_rate_set_series(const struct ath_rate_table *rate_table, | |||
689 | 689 | ||
690 | if (WLAN_RC_PHY_HT(rate_table->info[rix].phy)) { | 690 | if (WLAN_RC_PHY_HT(rate_table->info[rix].phy)) { |
691 | rate->flags |= IEEE80211_TX_RC_MCS; | 691 | rate->flags |= IEEE80211_TX_RC_MCS; |
692 | if (WLAN_RC_PHY_40(rate_table->info[rix].phy)) | 692 | if (WLAN_RC_PHY_40(rate_table->info[rix].phy) && |
693 | conf_is_ht40(&txrc->hw->conf)) | ||
693 | rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; | 694 | rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; |
694 | if (WLAN_RC_PHY_SGI(rate_table->info[rix].phy)) | 695 | if (WLAN_RC_PHY_SGI(rate_table->info[rix].phy)) |
695 | rate->flags |= IEEE80211_TX_RC_SHORT_GI; | 696 | rate->flags |= IEEE80211_TX_RC_SHORT_GI; |
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 9ed65157bef5..05960ddde24e 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c | |||
@@ -3093,7 +3093,7 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev, | |||
3093 | int freq; | 3093 | int freq; |
3094 | bool avoid = false; | 3094 | bool avoid = false; |
3095 | u8 length; | 3095 | u8 length; |
3096 | u16 tmp, core, type, count, max, numb, last, cmd; | 3096 | u16 tmp, core, type, count, max, numb, last = 0, cmd; |
3097 | const u16 *table; | 3097 | const u16 *table; |
3098 | bool phy6or5x; | 3098 | bool phy6or5x; |
3099 | 3099 | ||
diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-lib.c b/drivers/net/wireless/iwlegacy/iwl-4965-lib.c index 7e5e85a017b5..a7a4739880dc 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965-lib.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965-lib.c | |||
@@ -628,11 +628,11 @@ void iwl4965_rx_reply_rx(struct iwl_priv *priv, | |||
628 | 628 | ||
629 | /* rx_status carries information about the packet to mac80211 */ | 629 | /* rx_status carries information about the packet to mac80211 */ |
630 | rx_status.mactime = le64_to_cpu(phy_res->timestamp); | 630 | rx_status.mactime = le64_to_cpu(phy_res->timestamp); |
631 | rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? | ||
632 | IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; | ||
631 | rx_status.freq = | 633 | rx_status.freq = |
632 | ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel), | 634 | ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel), |
633 | rx_status.band); | 635 | rx_status.band); |
634 | rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? | ||
635 | IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; | ||
636 | rx_status.rate_idx = | 636 | rx_status.rate_idx = |
637 | iwl4965_hwrate_to_mac80211_idx(rate_n_flags, rx_status.band); | 637 | iwl4965_hwrate_to_mac80211_idx(rate_n_flags, rx_status.band); |
638 | rx_status.flag = 0; | 638 | rx_status.flag = 0; |
diff --git a/drivers/net/wireless/iwlegacy/iwl-4965.c b/drivers/net/wireless/iwlegacy/iwl-4965.c index f5433c74b845..f9db25bb35c3 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965.c | |||
@@ -1543,7 +1543,7 @@ static void iwl4965_temperature_calib(struct iwl_priv *priv) | |||
1543 | s32 temp; | 1543 | s32 temp; |
1544 | 1544 | ||
1545 | temp = iwl4965_hw_get_temperature(priv); | 1545 | temp = iwl4965_hw_get_temperature(priv); |
1546 | if (temp < 0) | 1546 | if (IWL_TX_POWER_TEMPERATURE_OUT_OF_RANGE(temp)) |
1547 | return; | 1547 | return; |
1548 | 1548 | ||
1549 | if (priv->temperature != temp) { | 1549 | if (priv->temperature != temp) { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index f8c710db6e6f..fda6fe08cf91 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c | |||
@@ -603,19 +603,27 @@ struct iwl_cfg iwl6050_2abg_cfg = { | |||
603 | IWL_DEVICE_6050, | 603 | IWL_DEVICE_6050, |
604 | }; | 604 | }; |
605 | 605 | ||
606 | #define IWL_DEVICE_6150 \ | ||
607 | .fw_name_pre = IWL6050_FW_PRE, \ | ||
608 | .ucode_api_max = IWL6050_UCODE_API_MAX, \ | ||
609 | .ucode_api_min = IWL6050_UCODE_API_MIN, \ | ||
610 | .ops = &iwl6150_ops, \ | ||
611 | .eeprom_ver = EEPROM_6150_EEPROM_VERSION, \ | ||
612 | .eeprom_calib_ver = EEPROM_6150_TX_POWER_VERSION, \ | ||
613 | .base_params = &iwl6050_base_params, \ | ||
614 | .need_dc_calib = true, \ | ||
615 | .led_mode = IWL_LED_BLINK, \ | ||
616 | .internal_wimax_coex = true | ||
617 | |||
606 | struct iwl_cfg iwl6150_bgn_cfg = { | 618 | struct iwl_cfg iwl6150_bgn_cfg = { |
607 | .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BGN", | 619 | .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BGN", |
608 | .fw_name_pre = IWL6050_FW_PRE, | 620 | IWL_DEVICE_6150, |
609 | .ucode_api_max = IWL6050_UCODE_API_MAX, | ||
610 | .ucode_api_min = IWL6050_UCODE_API_MIN, | ||
611 | .eeprom_ver = EEPROM_6150_EEPROM_VERSION, | ||
612 | .eeprom_calib_ver = EEPROM_6150_TX_POWER_VERSION, | ||
613 | .ops = &iwl6150_ops, | ||
614 | .base_params = &iwl6050_base_params, | ||
615 | .ht_params = &iwl6000_ht_params, | 621 | .ht_params = &iwl6000_ht_params, |
616 | .need_dc_calib = true, | 622 | }; |
617 | .led_mode = IWL_LED_RF_STATE, | 623 | |
618 | .internal_wimax_coex = true, | 624 | struct iwl_cfg iwl6150_bg_cfg = { |
625 | .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BG", | ||
626 | IWL_DEVICE_6150, | ||
619 | }; | 627 | }; |
620 | 628 | ||
621 | struct iwl_cfg iwl6000_3agn_cfg = { | 629 | struct iwl_cfg iwl6000_3agn_cfg = { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 11c6c1169e78..a662adcb2adb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -3831,11 +3831,11 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { | |||
3831 | 3831 | ||
3832 | /* 6150 WiFi/WiMax Series */ | 3832 | /* 6150 WiFi/WiMax Series */ |
3833 | {IWL_PCI_DEVICE(0x0885, 0x1305, iwl6150_bgn_cfg)}, | 3833 | {IWL_PCI_DEVICE(0x0885, 0x1305, iwl6150_bgn_cfg)}, |
3834 | {IWL_PCI_DEVICE(0x0885, 0x1306, iwl6150_bgn_cfg)}, | 3834 | {IWL_PCI_DEVICE(0x0885, 0x1307, iwl6150_bg_cfg)}, |
3835 | {IWL_PCI_DEVICE(0x0885, 0x1325, iwl6150_bgn_cfg)}, | 3835 | {IWL_PCI_DEVICE(0x0885, 0x1325, iwl6150_bgn_cfg)}, |
3836 | {IWL_PCI_DEVICE(0x0885, 0x1326, iwl6150_bgn_cfg)}, | 3836 | {IWL_PCI_DEVICE(0x0885, 0x1327, iwl6150_bg_cfg)}, |
3837 | {IWL_PCI_DEVICE(0x0886, 0x1315, iwl6150_bgn_cfg)}, | 3837 | {IWL_PCI_DEVICE(0x0886, 0x1315, iwl6150_bgn_cfg)}, |
3838 | {IWL_PCI_DEVICE(0x0886, 0x1316, iwl6150_bgn_cfg)}, | 3838 | {IWL_PCI_DEVICE(0x0886, 0x1317, iwl6150_bg_cfg)}, |
3839 | 3839 | ||
3840 | /* 1000 Series WiFi */ | 3840 | /* 1000 Series WiFi */ |
3841 | {IWL_PCI_DEVICE(0x0083, 0x1205, iwl1000_bgn_cfg)}, | 3841 | {IWL_PCI_DEVICE(0x0083, 0x1205, iwl1000_bgn_cfg)}, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 2495fe7a58cb..d1716844002e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h | |||
@@ -89,6 +89,7 @@ extern struct iwl_cfg iwl6000_3agn_cfg; | |||
89 | extern struct iwl_cfg iwl6050_2agn_cfg; | 89 | extern struct iwl_cfg iwl6050_2agn_cfg; |
90 | extern struct iwl_cfg iwl6050_2abg_cfg; | 90 | extern struct iwl_cfg iwl6050_2abg_cfg; |
91 | extern struct iwl_cfg iwl6150_bgn_cfg; | 91 | extern struct iwl_cfg iwl6150_bgn_cfg; |
92 | extern struct iwl_cfg iwl6150_bg_cfg; | ||
92 | extern struct iwl_cfg iwl1000_bgn_cfg; | 93 | extern struct iwl_cfg iwl1000_bgn_cfg; |
93 | extern struct iwl_cfg iwl1000_bg_cfg; | 94 | extern struct iwl_cfg iwl1000_bg_cfg; |
94 | extern struct iwl_cfg iwl100_bgn_cfg; | 95 | extern struct iwl_cfg iwl100_bgn_cfg; |
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 84566db486d2..71c8f3fccfa1 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c | |||
@@ -994,6 +994,8 @@ static void lbs_submit_command(struct lbs_private *priv, | |||
994 | cmd = cmdnode->cmdbuf; | 994 | cmd = cmdnode->cmdbuf; |
995 | 995 | ||
996 | spin_lock_irqsave(&priv->driver_lock, flags); | 996 | spin_lock_irqsave(&priv->driver_lock, flags); |
997 | priv->seqnum++; | ||
998 | cmd->seqnum = cpu_to_le16(priv->seqnum); | ||
997 | priv->cur_cmd = cmdnode; | 999 | priv->cur_cmd = cmdnode; |
998 | spin_unlock_irqrestore(&priv->driver_lock, flags); | 1000 | spin_unlock_irqrestore(&priv->driver_lock, flags); |
999 | 1001 | ||
@@ -1621,11 +1623,9 @@ struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv, | |||
1621 | /* Copy the incoming command to the buffer */ | 1623 | /* Copy the incoming command to the buffer */ |
1622 | memcpy(cmdnode->cmdbuf, in_cmd, in_cmd_size); | 1624 | memcpy(cmdnode->cmdbuf, in_cmd, in_cmd_size); |
1623 | 1625 | ||
1624 | /* Set sequence number, clean result, move to buffer */ | 1626 | /* Set command, clean result, move to buffer */ |
1625 | priv->seqnum++; | ||
1626 | cmdnode->cmdbuf->command = cpu_to_le16(command); | 1627 | cmdnode->cmdbuf->command = cpu_to_le16(command); |
1627 | cmdnode->cmdbuf->size = cpu_to_le16(in_cmd_size); | 1628 | cmdnode->cmdbuf->size = cpu_to_le16(in_cmd_size); |
1628 | cmdnode->cmdbuf->seqnum = cpu_to_le16(priv->seqnum); | ||
1629 | cmdnode->cmdbuf->result = 0; | 1629 | cmdnode->cmdbuf->result = 0; |
1630 | 1630 | ||
1631 | lbs_deb_host("PREP_CMD: command 0x%04x\n", command); | 1631 | lbs_deb_host("PREP_CMD: command 0x%04x\n", command); |
diff --git a/drivers/net/wireless/mwifiex/sdio.h b/drivers/net/wireless/mwifiex/sdio.h index a0e9bc5253e0..4e97e90aa399 100644 --- a/drivers/net/wireless/mwifiex/sdio.h +++ b/drivers/net/wireless/mwifiex/sdio.h | |||
@@ -167,8 +167,8 @@ | |||
167 | /* Rx unit register */ | 167 | /* Rx unit register */ |
168 | #define CARD_RX_UNIT_REG 0x63 | 168 | #define CARD_RX_UNIT_REG 0x63 |
169 | 169 | ||
170 | /* Event header Len*/ | 170 | /* Event header len w/o 4 bytes of interface header */ |
171 | #define MWIFIEX_EVENT_HEADER_LEN 8 | 171 | #define MWIFIEX_EVENT_HEADER_LEN 4 |
172 | 172 | ||
173 | /* Max retry number of CMD53 write */ | 173 | /* Max retry number of CMD53 write */ |
174 | #define MAX_WRITE_IOMEM_RETRY 2 | 174 | #define MAX_WRITE_IOMEM_RETRY 2 |
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index 9def1e5369a1..b2f8b8fd4d2d 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig | |||
@@ -166,7 +166,6 @@ config RT2800USB_RT35XX | |||
166 | config RT2800USB_RT53XX | 166 | config RT2800USB_RT53XX |
167 | bool "rt2800usb - Include support for rt53xx devices (EXPERIMENTAL)" | 167 | bool "rt2800usb - Include support for rt53xx devices (EXPERIMENTAL)" |
168 | depends on EXPERIMENTAL | 168 | depends on EXPERIMENTAL |
169 | default y | ||
170 | ---help--- | 169 | ---help--- |
171 | This adds support for rt53xx wireless chipset family to the | 170 | This adds support for rt53xx wireless chipset family to the |
172 | rt2800pci driver. | 171 | rt2800pci driver. |
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index a40952845436..89100e7c553b 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c | |||
@@ -669,11 +669,6 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) | |||
669 | &rx_status, | 669 | &rx_status, |
670 | (u8 *) pdesc, skb); | 670 | (u8 *) pdesc, skb); |
671 | 671 | ||
672 | pci_unmap_single(rtlpci->pdev, | ||
673 | *((dma_addr_t *) skb->cb), | ||
674 | rtlpci->rxbuffersize, | ||
675 | PCI_DMA_FROMDEVICE); | ||
676 | |||
677 | skb_put(skb, rtlpriv->cfg->ops->get_desc((u8 *) pdesc, | 672 | skb_put(skb, rtlpriv->cfg->ops->get_desc((u8 *) pdesc, |
678 | false, | 673 | false, |
679 | HW_DESC_RXPKT_LEN)); | 674 | HW_DESC_RXPKT_LEN)); |
@@ -690,6 +685,21 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) | |||
690 | hdr = rtl_get_hdr(skb); | 685 | hdr = rtl_get_hdr(skb); |
691 | fc = rtl_get_fc(skb); | 686 | fc = rtl_get_fc(skb); |
692 | 687 | ||
688 | /* try for new buffer - if allocation fails, drop | ||
689 | * frame and reuse old buffer | ||
690 | */ | ||
691 | new_skb = dev_alloc_skb(rtlpci->rxbuffersize); | ||
692 | if (unlikely(!new_skb)) { | ||
693 | RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV), | ||
694 | DBG_DMESG, | ||
695 | ("can't alloc skb for rx\n")); | ||
696 | goto done; | ||
697 | } | ||
698 | pci_unmap_single(rtlpci->pdev, | ||
699 | *((dma_addr_t *) skb->cb), | ||
700 | rtlpci->rxbuffersize, | ||
701 | PCI_DMA_FROMDEVICE); | ||
702 | |||
693 | if (!stats.crc || !stats.hwerror) { | 703 | if (!stats.crc || !stats.hwerror) { |
694 | memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, | 704 | memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, |
695 | sizeof(rx_status)); | 705 | sizeof(rx_status)); |
@@ -758,15 +768,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) | |||
758 | rtl_lps_leave(hw); | 768 | rtl_lps_leave(hw); |
759 | } | 769 | } |
760 | 770 | ||
761 | new_skb = dev_alloc_skb(rtlpci->rxbuffersize); | ||
762 | if (unlikely(!new_skb)) { | ||
763 | RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV), | ||
764 | DBG_DMESG, | ||
765 | ("can't alloc skb for rx\n")); | ||
766 | goto done; | ||
767 | } | ||
768 | skb = new_skb; | 771 | skb = new_skb; |
769 | /*skb->dev = dev; */ | ||
770 | 772 | ||
771 | rtlpci->rx_ring[rx_queue_idx].rx_buf[rtlpci-> | 773 | rtlpci->rx_ring[rx_queue_idx].rx_buf[rtlpci-> |
772 | rx_ring | 774 | rx_ring |
@@ -1113,6 +1115,13 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw) | |||
1113 | 1115 | ||
1114 | rtlpci->rx_ring[rx_queue_idx].idx = 0; | 1116 | rtlpci->rx_ring[rx_queue_idx].idx = 0; |
1115 | 1117 | ||
1118 | /* If amsdu_8k is disabled, set buffersize to 4096. This | ||
1119 | * change will reduce memory fragmentation. | ||
1120 | */ | ||
1121 | if (rtlpci->rxbuffersize > 4096 && | ||
1122 | rtlpriv->rtlhal.disable_amsdu_8k) | ||
1123 | rtlpci->rxbuffersize = 4096; | ||
1124 | |||
1116 | for (i = 0; i < rtlpci->rxringcount; i++) { | 1125 | for (i = 0; i < rtlpci->rxringcount; i++) { |
1117 | struct sk_buff *skb = | 1126 | struct sk_buff *skb = |
1118 | dev_alloc_skb(rtlpci->rxbuffersize); | 1127 | dev_alloc_skb(rtlpci->rxbuffersize); |
diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h index 1ab6c86aac40..c83fefb6662f 100644 --- a/drivers/net/wireless/wl12xx/conf.h +++ b/drivers/net/wireless/wl12xx/conf.h | |||
@@ -1157,6 +1157,9 @@ struct conf_sched_scan_settings { | |||
1157 | /* time to wait on the channel for passive scans (in TUs) */ | 1157 | /* time to wait on the channel for passive scans (in TUs) */ |
1158 | u32 dwell_time_passive; | 1158 | u32 dwell_time_passive; |
1159 | 1159 | ||
1160 | /* time to wait on the channel for DFS scans (in TUs) */ | ||
1161 | u32 dwell_time_dfs; | ||
1162 | |||
1160 | /* number of probe requests to send on each channel in active scans */ | 1163 | /* number of probe requests to send on each channel in active scans */ |
1161 | u8 num_probe_reqs; | 1164 | u8 num_probe_reqs; |
1162 | 1165 | ||
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index bc00e52f6445..e6497dc669df 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c | |||
@@ -311,6 +311,7 @@ static struct conf_drv_settings default_conf = { | |||
311 | .min_dwell_time_active = 8, | 311 | .min_dwell_time_active = 8, |
312 | .max_dwell_time_active = 30, | 312 | .max_dwell_time_active = 30, |
313 | .dwell_time_passive = 100, | 313 | .dwell_time_passive = 100, |
314 | .dwell_time_dfs = 150, | ||
314 | .num_probe_reqs = 2, | 315 | .num_probe_reqs = 2, |
315 | .rssi_threshold = -90, | 316 | .rssi_threshold = -90, |
316 | .snr_threshold = 0, | 317 | .snr_threshold = 0, |
diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c index f37e5a391976..56f76abc754d 100644 --- a/drivers/net/wireless/wl12xx/scan.c +++ b/drivers/net/wireless/wl12xx/scan.c | |||
@@ -331,16 +331,22 @@ wl1271_scan_get_sched_scan_channels(struct wl1271 *wl, | |||
331 | struct conf_sched_scan_settings *c = &wl->conf.sched_scan; | 331 | struct conf_sched_scan_settings *c = &wl->conf.sched_scan; |
332 | int i, j; | 332 | int i, j; |
333 | u32 flags; | 333 | u32 flags; |
334 | bool force_passive = !req->n_ssids; | ||
334 | 335 | ||
335 | for (i = 0, j = start; | 336 | for (i = 0, j = start; |
336 | i < req->n_channels && j < MAX_CHANNELS_ALL_BANDS; | 337 | i < req->n_channels && j < MAX_CHANNELS_ALL_BANDS; |
337 | i++) { | 338 | i++) { |
338 | flags = req->channels[i]->flags; | 339 | flags = req->channels[i]->flags; |
339 | 340 | ||
340 | if (!(flags & IEEE80211_CHAN_DISABLED) && | 341 | if (force_passive) |
341 | ((flags & IEEE80211_CHAN_PASSIVE_SCAN) == passive) && | 342 | flags |= IEEE80211_CHAN_PASSIVE_SCAN; |
342 | ((flags & IEEE80211_CHAN_RADAR) == radar) && | 343 | |
343 | (req->channels[i]->band == band)) { | 344 | if ((req->channels[i]->band == band) && |
345 | !(flags & IEEE80211_CHAN_DISABLED) && | ||
346 | (!!(flags & IEEE80211_CHAN_RADAR) == radar) && | ||
347 | /* if radar is set, we ignore the passive flag */ | ||
348 | (radar || | ||
349 | !!(flags & IEEE80211_CHAN_PASSIVE_SCAN) == passive)) { | ||
344 | wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ", | 350 | wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ", |
345 | req->channels[i]->band, | 351 | req->channels[i]->band, |
346 | req->channels[i]->center_freq); | 352 | req->channels[i]->center_freq); |
@@ -350,7 +356,12 @@ wl1271_scan_get_sched_scan_channels(struct wl1271 *wl, | |||
350 | wl1271_debug(DEBUG_SCAN, "max_power %d", | 356 | wl1271_debug(DEBUG_SCAN, "max_power %d", |
351 | req->channels[i]->max_power); | 357 | req->channels[i]->max_power); |
352 | 358 | ||
353 | if (flags & IEEE80211_CHAN_PASSIVE_SCAN) { | 359 | if (flags & IEEE80211_CHAN_RADAR) { |
360 | channels[j].flags |= SCAN_CHANNEL_FLAGS_DFS; | ||
361 | channels[j].passive_duration = | ||
362 | cpu_to_le16(c->dwell_time_dfs); | ||
363 | } | ||
364 | else if (flags & IEEE80211_CHAN_PASSIVE_SCAN) { | ||
354 | channels[j].passive_duration = | 365 | channels[j].passive_duration = |
355 | cpu_to_le16(c->dwell_time_passive); | 366 | cpu_to_le16(c->dwell_time_passive); |
356 | } else { | 367 | } else { |
@@ -359,7 +370,7 @@ wl1271_scan_get_sched_scan_channels(struct wl1271 *wl, | |||
359 | channels[j].max_duration = | 370 | channels[j].max_duration = |
360 | cpu_to_le16(c->max_dwell_time_active); | 371 | cpu_to_le16(c->max_dwell_time_active); |
361 | } | 372 | } |
362 | channels[j].tx_power_att = req->channels[j]->max_power; | 373 | channels[j].tx_power_att = req->channels[i]->max_power; |
363 | channels[j].channel = req->channels[i]->hw_value; | 374 | channels[j].channel = req->channels[i]->hw_value; |
364 | 375 | ||
365 | j++; | 376 | j++; |
@@ -386,7 +397,11 @@ wl1271_scan_sched_scan_channels(struct wl1271 *wl, | |||
386 | wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels, | 397 | wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels, |
387 | IEEE80211_BAND_2GHZ, | 398 | IEEE80211_BAND_2GHZ, |
388 | false, false, idx); | 399 | false, false, idx); |
389 | idx += cfg->active[0]; | 400 | /* |
401 | * 5GHz channels always start at position 14, not immediately | ||
402 | * after the last 2.4GHz channel | ||
403 | */ | ||
404 | idx = 14; | ||
390 | 405 | ||
391 | cfg->passive[1] = | 406 | cfg->passive[1] = |
392 | wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels, | 407 | wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels, |
@@ -394,22 +409,23 @@ wl1271_scan_sched_scan_channels(struct wl1271 *wl, | |||
394 | false, true, idx); | 409 | false, true, idx); |
395 | idx += cfg->passive[1]; | 410 | idx += cfg->passive[1]; |
396 | 411 | ||
397 | cfg->active[1] = | 412 | cfg->dfs = |
398 | wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels, | 413 | wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels, |
399 | IEEE80211_BAND_5GHZ, | 414 | IEEE80211_BAND_5GHZ, |
400 | false, false, 14); | 415 | true, true, idx); |
401 | idx += cfg->active[1]; | 416 | idx += cfg->dfs; |
402 | 417 | ||
403 | cfg->dfs = | 418 | cfg->active[1] = |
404 | wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels, | 419 | wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels, |
405 | IEEE80211_BAND_5GHZ, | 420 | IEEE80211_BAND_5GHZ, |
406 | true, false, idx); | 421 | false, false, idx); |
407 | idx += cfg->dfs; | 422 | idx += cfg->active[1]; |
408 | 423 | ||
409 | wl1271_debug(DEBUG_SCAN, " 2.4GHz: active %d passive %d", | 424 | wl1271_debug(DEBUG_SCAN, " 2.4GHz: active %d passive %d", |
410 | cfg->active[0], cfg->passive[0]); | 425 | cfg->active[0], cfg->passive[0]); |
411 | wl1271_debug(DEBUG_SCAN, " 5GHz: active %d passive %d", | 426 | wl1271_debug(DEBUG_SCAN, " 5GHz: active %d passive %d", |
412 | cfg->active[1], cfg->passive[1]); | 427 | cfg->active[1], cfg->passive[1]); |
428 | wl1271_debug(DEBUG_SCAN, " DFS: %d", cfg->dfs); | ||
413 | 429 | ||
414 | return idx; | 430 | return idx; |
415 | } | 431 | } |
@@ -421,6 +437,7 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl, | |||
421 | struct wl1271_cmd_sched_scan_config *cfg = NULL; | 437 | struct wl1271_cmd_sched_scan_config *cfg = NULL; |
422 | struct conf_sched_scan_settings *c = &wl->conf.sched_scan; | 438 | struct conf_sched_scan_settings *c = &wl->conf.sched_scan; |
423 | int i, total_channels, ret; | 439 | int i, total_channels, ret; |
440 | bool force_passive = !req->n_ssids; | ||
424 | 441 | ||
425 | wl1271_debug(DEBUG_CMD, "cmd sched_scan scan config"); | 442 | wl1271_debug(DEBUG_CMD, "cmd sched_scan scan config"); |
426 | 443 | ||
@@ -444,7 +461,7 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl, | |||
444 | for (i = 0; i < SCAN_MAX_CYCLE_INTERVALS; i++) | 461 | for (i = 0; i < SCAN_MAX_CYCLE_INTERVALS; i++) |
445 | cfg->intervals[i] = cpu_to_le32(req->interval); | 462 | cfg->intervals[i] = cpu_to_le32(req->interval); |
446 | 463 | ||
447 | if (req->ssids[0].ssid_len && req->ssids[0].ssid) { | 464 | if (!force_passive && req->ssids[0].ssid_len && req->ssids[0].ssid) { |
448 | cfg->filter_type = SCAN_SSID_FILTER_SPECIFIC; | 465 | cfg->filter_type = SCAN_SSID_FILTER_SPECIFIC; |
449 | cfg->ssid_len = req->ssids[0].ssid_len; | 466 | cfg->ssid_len = req->ssids[0].ssid_len; |
450 | memcpy(cfg->ssid, req->ssids[0].ssid, | 467 | memcpy(cfg->ssid, req->ssids[0].ssid, |
@@ -461,7 +478,7 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl, | |||
461 | goto out; | 478 | goto out; |
462 | } | 479 | } |
463 | 480 | ||
464 | if (cfg->active[0]) { | 481 | if (!force_passive && cfg->active[0]) { |
465 | ret = wl1271_cmd_build_probe_req(wl, req->ssids[0].ssid, | 482 | ret = wl1271_cmd_build_probe_req(wl, req->ssids[0].ssid, |
466 | req->ssids[0].ssid_len, | 483 | req->ssids[0].ssid_len, |
467 | ies->ie[IEEE80211_BAND_2GHZ], | 484 | ies->ie[IEEE80211_BAND_2GHZ], |
@@ -473,7 +490,7 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl, | |||
473 | } | 490 | } |
474 | } | 491 | } |
475 | 492 | ||
476 | if (cfg->active[1]) { | 493 | if (!force_passive && cfg->active[1]) { |
477 | ret = wl1271_cmd_build_probe_req(wl, req->ssids[0].ssid, | 494 | ret = wl1271_cmd_build_probe_req(wl, req->ssids[0].ssid, |
478 | req->ssids[0].ssid_len, | 495 | req->ssids[0].ssid_len, |
479 | ies->ie[IEEE80211_BAND_5GHZ], | 496 | ies->ie[IEEE80211_BAND_5GHZ], |
diff --git a/drivers/net/wireless/wl12xx/scan.h b/drivers/net/wireless/wl12xx/scan.h index c83319579ca3..a0b6c5d67b07 100644 --- a/drivers/net/wireless/wl12xx/scan.h +++ b/drivers/net/wireless/wl12xx/scan.h | |||
@@ -137,6 +137,9 @@ enum { | |||
137 | SCAN_BSS_TYPE_ANY, | 137 | SCAN_BSS_TYPE_ANY, |
138 | }; | 138 | }; |
139 | 139 | ||
140 | #define SCAN_CHANNEL_FLAGS_DFS BIT(0) | ||
141 | #define SCAN_CHANNEL_FLAGS_DFS_ENABLED BIT(1) | ||
142 | |||
140 | struct conn_scan_ch_params { | 143 | struct conn_scan_ch_params { |
141 | __le16 min_duration; | 144 | __le16 min_duration; |
142 | __le16 max_duration; | 145 | __le16 max_duration; |
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 0e819943b9e4..631194d49828 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c | |||
@@ -1533,6 +1533,31 @@ static void __exit usb_exit(void) | |||
1533 | module_init(usb_init); | 1533 | module_init(usb_init); |
1534 | module_exit(usb_exit); | 1534 | module_exit(usb_exit); |
1535 | 1535 | ||
1536 | static int zd_ep_regs_out_msg(struct usb_device *udev, void *data, int len, | ||
1537 | int *actual_length, int timeout) | ||
1538 | { | ||
1539 | /* In USB 2.0 mode EP_REGS_OUT endpoint is interrupt type. However in | ||
1540 | * USB 1.1 mode endpoint is bulk. Select correct type URB by endpoint | ||
1541 | * descriptor. | ||
1542 | */ | ||
1543 | struct usb_host_endpoint *ep; | ||
1544 | unsigned int pipe; | ||
1545 | |||
1546 | pipe = usb_sndintpipe(udev, EP_REGS_OUT); | ||
1547 | ep = usb_pipe_endpoint(udev, pipe); | ||
1548 | if (!ep) | ||
1549 | return -EINVAL; | ||
1550 | |||
1551 | if (usb_endpoint_xfer_int(&ep->desc)) { | ||
1552 | return usb_interrupt_msg(udev, pipe, data, len, | ||
1553 | actual_length, timeout); | ||
1554 | } else { | ||
1555 | pipe = usb_sndbulkpipe(udev, EP_REGS_OUT); | ||
1556 | return usb_bulk_msg(udev, pipe, data, len, actual_length, | ||
1557 | timeout); | ||
1558 | } | ||
1559 | } | ||
1560 | |||
1536 | static int usb_int_regs_length(unsigned int count) | 1561 | static int usb_int_regs_length(unsigned int count) |
1537 | { | 1562 | { |
1538 | return sizeof(struct usb_int_regs) + count * sizeof(struct reg_data); | 1563 | return sizeof(struct usb_int_regs) + count * sizeof(struct reg_data); |
@@ -1648,15 +1673,14 @@ int zd_usb_ioread16v(struct zd_usb *usb, u16 *values, | |||
1648 | 1673 | ||
1649 | udev = zd_usb_to_usbdev(usb); | 1674 | udev = zd_usb_to_usbdev(usb); |
1650 | prepare_read_regs_int(usb); | 1675 | prepare_read_regs_int(usb); |
1651 | r = usb_interrupt_msg(udev, usb_sndintpipe(udev, EP_REGS_OUT), | 1676 | r = zd_ep_regs_out_msg(udev, req, req_len, &actual_req_len, 50 /*ms*/); |
1652 | req, req_len, &actual_req_len, 50 /* ms */); | ||
1653 | if (r) { | 1677 | if (r) { |
1654 | dev_dbg_f(zd_usb_dev(usb), | 1678 | dev_dbg_f(zd_usb_dev(usb), |
1655 | "error in usb_interrupt_msg(). Error number %d\n", r); | 1679 | "error in zd_ep_regs_out_msg(). Error number %d\n", r); |
1656 | goto error; | 1680 | goto error; |
1657 | } | 1681 | } |
1658 | if (req_len != actual_req_len) { | 1682 | if (req_len != actual_req_len) { |
1659 | dev_dbg_f(zd_usb_dev(usb), "error in usb_interrupt_msg()\n" | 1683 | dev_dbg_f(zd_usb_dev(usb), "error in zd_ep_regs_out_msg()\n" |
1660 | " req_len %d != actual_req_len %d\n", | 1684 | " req_len %d != actual_req_len %d\n", |
1661 | req_len, actual_req_len); | 1685 | req_len, actual_req_len); |
1662 | r = -EIO; | 1686 | r = -EIO; |
@@ -1818,9 +1842,17 @@ int zd_usb_iowrite16v_async(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, | |||
1818 | rw->value = cpu_to_le16(ioreqs[i].value); | 1842 | rw->value = cpu_to_le16(ioreqs[i].value); |
1819 | } | 1843 | } |
1820 | 1844 | ||
1821 | usb_fill_int_urb(urb, udev, usb_sndintpipe(udev, EP_REGS_OUT), | 1845 | /* In USB 2.0 mode endpoint is interrupt type. However in USB 1.1 mode |
1822 | req, req_len, iowrite16v_urb_complete, usb, | 1846 | * endpoint is bulk. Select correct type URB by endpoint descriptor. |
1823 | ep->desc.bInterval); | 1847 | */ |
1848 | if (usb_endpoint_xfer_int(&ep->desc)) | ||
1849 | usb_fill_int_urb(urb, udev, usb_sndintpipe(udev, EP_REGS_OUT), | ||
1850 | req, req_len, iowrite16v_urb_complete, usb, | ||
1851 | ep->desc.bInterval); | ||
1852 | else | ||
1853 | usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, EP_REGS_OUT), | ||
1854 | req, req_len, iowrite16v_urb_complete, usb); | ||
1855 | |||
1824 | urb->transfer_flags |= URB_FREE_BUFFER; | 1856 | urb->transfer_flags |= URB_FREE_BUFFER; |
1825 | 1857 | ||
1826 | /* Submit previous URB */ | 1858 | /* Submit previous URB */ |
@@ -1924,15 +1956,14 @@ int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits) | |||
1924 | } | 1956 | } |
1925 | 1957 | ||
1926 | udev = zd_usb_to_usbdev(usb); | 1958 | udev = zd_usb_to_usbdev(usb); |
1927 | r = usb_interrupt_msg(udev, usb_sndintpipe(udev, EP_REGS_OUT), | 1959 | r = zd_ep_regs_out_msg(udev, req, req_len, &actual_req_len, 50 /*ms*/); |
1928 | req, req_len, &actual_req_len, 50 /* ms */); | ||
1929 | if (r) { | 1960 | if (r) { |
1930 | dev_dbg_f(zd_usb_dev(usb), | 1961 | dev_dbg_f(zd_usb_dev(usb), |
1931 | "error in usb_interrupt_msg(). Error number %d\n", r); | 1962 | "error in zd_ep_regs_out_msg(). Error number %d\n", r); |
1932 | goto out; | 1963 | goto out; |
1933 | } | 1964 | } |
1934 | if (req_len != actual_req_len) { | 1965 | if (req_len != actual_req_len) { |
1935 | dev_dbg_f(zd_usb_dev(usb), "error in usb_interrupt_msg()" | 1966 | dev_dbg_f(zd_usb_dev(usb), "error in zd_ep_regs_out_msg()" |
1936 | " req_len %d != actual_req_len %d\n", | 1967 | " req_len %d != actual_req_len %d\n", |
1937 | req_len, actual_req_len); | 1968 | req_len, actual_req_len); |
1938 | r = -EIO; | 1969 | r = -EIO; |
diff --git a/drivers/oprofile/event_buffer.h b/drivers/oprofile/event_buffer.h index 4e70749f8d16..a8d5bb3cba89 100644 --- a/drivers/oprofile/event_buffer.h +++ b/drivers/oprofile/event_buffer.h | |||
@@ -11,7 +11,7 @@ | |||
11 | #define EVENT_BUFFER_H | 11 | #define EVENT_BUFFER_H |
12 | 12 | ||
13 | #include <linux/types.h> | 13 | #include <linux/types.h> |
14 | #include <asm/mutex.h> | 14 | #include <linux/mutex.h> |
15 | 15 | ||
16 | int alloc_event_buffer(void); | 16 | int alloc_event_buffer(void); |
17 | 17 | ||
diff --git a/drivers/oprofile/oprof.c b/drivers/oprofile/oprof.c index f9bda64fcd1b..dccd8636095c 100644 --- a/drivers/oprofile/oprof.c +++ b/drivers/oprofile/oprof.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include <linux/moduleparam.h> | 14 | #include <linux/moduleparam.h> |
15 | #include <linux/workqueue.h> | 15 | #include <linux/workqueue.h> |
16 | #include <linux/time.h> | 16 | #include <linux/time.h> |
17 | #include <asm/mutex.h> | 17 | #include <linux/mutex.h> |
18 | 18 | ||
19 | #include "oprof.h" | 19 | #include "oprof.h" |
20 | #include "event_buffer.h" | 20 | #include "event_buffer.h" |
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index 12e02bf92c4a..3dc9befa5aec 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c | |||
@@ -698,12 +698,7 @@ int __init detect_intel_iommu(void) | |||
698 | { | 698 | { |
699 | #ifdef CONFIG_INTR_REMAP | 699 | #ifdef CONFIG_INTR_REMAP |
700 | struct acpi_table_dmar *dmar; | 700 | struct acpi_table_dmar *dmar; |
701 | /* | 701 | |
702 | * for now we will disable dma-remapping when interrupt | ||
703 | * remapping is enabled. | ||
704 | * When support for queued invalidation for IOTLB invalidation | ||
705 | * is added, we will not need this any more. | ||
706 | */ | ||
707 | dmar = (struct acpi_table_dmar *) dmar_tbl; | 702 | dmar = (struct acpi_table_dmar *) dmar_tbl; |
708 | if (ret && cpu_has_x2apic && dmar->flags & 0x1) | 703 | if (ret && cpu_has_x2apic && dmar->flags & 0x1) |
709 | printk(KERN_INFO | 704 | printk(KERN_INFO |
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 6af6b628175b..59f17acf7f68 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c | |||
@@ -47,6 +47,8 @@ | |||
47 | #define ROOT_SIZE VTD_PAGE_SIZE | 47 | #define ROOT_SIZE VTD_PAGE_SIZE |
48 | #define CONTEXT_SIZE VTD_PAGE_SIZE | 48 | #define CONTEXT_SIZE VTD_PAGE_SIZE |
49 | 49 | ||
50 | #define IS_BRIDGE_HOST_DEVICE(pdev) \ | ||
51 | ((pdev->class >> 8) == PCI_CLASS_BRIDGE_HOST) | ||
50 | #define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) | 52 | #define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) |
51 | #define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA) | 53 | #define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA) |
52 | #define IS_AZALIA(pdev) ((pdev)->vendor == 0x8086 && (pdev)->device == 0x3a3e) | 54 | #define IS_AZALIA(pdev) ((pdev)->vendor == 0x8086 && (pdev)->device == 0x3a3e) |
@@ -116,6 +118,11 @@ static inline unsigned long align_to_level(unsigned long pfn, int level) | |||
116 | return (pfn + level_size(level) - 1) & level_mask(level); | 118 | return (pfn + level_size(level) - 1) & level_mask(level); |
117 | } | 119 | } |
118 | 120 | ||
121 | static inline unsigned long lvl_to_nr_pages(unsigned int lvl) | ||
122 | { | ||
123 | return 1 << ((lvl - 1) * LEVEL_STRIDE); | ||
124 | } | ||
125 | |||
119 | /* VT-d pages must always be _smaller_ than MM pages. Otherwise things | 126 | /* VT-d pages must always be _smaller_ than MM pages. Otherwise things |
120 | are never going to work. */ | 127 | are never going to work. */ |
121 | static inline unsigned long dma_to_mm_pfn(unsigned long dma_pfn) | 128 | static inline unsigned long dma_to_mm_pfn(unsigned long dma_pfn) |
@@ -143,6 +150,12 @@ static void __init check_tylersburg_isoch(void); | |||
143 | static int rwbf_quirk; | 150 | static int rwbf_quirk; |
144 | 151 | ||
145 | /* | 152 | /* |
153 | * set to 1 to panic kernel if can't successfully enable VT-d | ||
154 | * (used when kernel is launched w/ TXT) | ||
155 | */ | ||
156 | static int force_on = 0; | ||
157 | |||
158 | /* | ||
146 | * 0: Present | 159 | * 0: Present |
147 | * 1-11: Reserved | 160 | * 1-11: Reserved |
148 | * 12-63: Context Ptr (12 - (haw-1)) | 161 | * 12-63: Context Ptr (12 - (haw-1)) |
@@ -338,6 +351,9 @@ struct dmar_domain { | |||
338 | int iommu_coherency;/* indicate coherency of iommu access */ | 351 | int iommu_coherency;/* indicate coherency of iommu access */ |
339 | int iommu_snooping; /* indicate snooping control feature*/ | 352 | int iommu_snooping; /* indicate snooping control feature*/ |
340 | int iommu_count; /* reference count of iommu */ | 353 | int iommu_count; /* reference count of iommu */ |
354 | int iommu_superpage;/* Level of superpages supported: | ||
355 | 0 == 4KiB (no superpages), 1 == 2MiB, | ||
356 | 2 == 1GiB, 3 == 512GiB, 4 == 1TiB */ | ||
341 | spinlock_t iommu_lock; /* protect iommu set in domain */ | 357 | spinlock_t iommu_lock; /* protect iommu set in domain */ |
342 | u64 max_addr; /* maximum mapped address */ | 358 | u64 max_addr; /* maximum mapped address */ |
343 | }; | 359 | }; |
@@ -387,6 +403,7 @@ int dmar_disabled = 1; | |||
387 | static int dmar_map_gfx = 1; | 403 | static int dmar_map_gfx = 1; |
388 | static int dmar_forcedac; | 404 | static int dmar_forcedac; |
389 | static int intel_iommu_strict; | 405 | static int intel_iommu_strict; |
406 | static int intel_iommu_superpage = 1; | ||
390 | 407 | ||
391 | #define DUMMY_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-1)) | 408 | #define DUMMY_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-1)) |
392 | static DEFINE_SPINLOCK(device_domain_lock); | 409 | static DEFINE_SPINLOCK(device_domain_lock); |
@@ -417,6 +434,10 @@ static int __init intel_iommu_setup(char *str) | |||
417 | printk(KERN_INFO | 434 | printk(KERN_INFO |
418 | "Intel-IOMMU: disable batched IOTLB flush\n"); | 435 | "Intel-IOMMU: disable batched IOTLB flush\n"); |
419 | intel_iommu_strict = 1; | 436 | intel_iommu_strict = 1; |
437 | } else if (!strncmp(str, "sp_off", 6)) { | ||
438 | printk(KERN_INFO | ||
439 | "Intel-IOMMU: disable supported super page\n"); | ||
440 | intel_iommu_superpage = 0; | ||
420 | } | 441 | } |
421 | 442 | ||
422 | str += strcspn(str, ","); | 443 | str += strcspn(str, ","); |
@@ -555,11 +576,32 @@ static void domain_update_iommu_snooping(struct dmar_domain *domain) | |||
555 | } | 576 | } |
556 | } | 577 | } |
557 | 578 | ||
579 | static void domain_update_iommu_superpage(struct dmar_domain *domain) | ||
580 | { | ||
581 | int i, mask = 0xf; | ||
582 | |||
583 | if (!intel_iommu_superpage) { | ||
584 | domain->iommu_superpage = 0; | ||
585 | return; | ||
586 | } | ||
587 | |||
588 | domain->iommu_superpage = 4; /* 1TiB */ | ||
589 | |||
590 | for_each_set_bit(i, &domain->iommu_bmp, g_num_of_iommus) { | ||
591 | mask |= cap_super_page_val(g_iommus[i]->cap); | ||
592 | if (!mask) { | ||
593 | break; | ||
594 | } | ||
595 | } | ||
596 | domain->iommu_superpage = fls(mask); | ||
597 | } | ||
598 | |||
558 | /* Some capabilities may be different across iommus */ | 599 | /* Some capabilities may be different across iommus */ |
559 | static void domain_update_iommu_cap(struct dmar_domain *domain) | 600 | static void domain_update_iommu_cap(struct dmar_domain *domain) |
560 | { | 601 | { |
561 | domain_update_iommu_coherency(domain); | 602 | domain_update_iommu_coherency(domain); |
562 | domain_update_iommu_snooping(domain); | 603 | domain_update_iommu_snooping(domain); |
604 | domain_update_iommu_superpage(domain); | ||
563 | } | 605 | } |
564 | 606 | ||
565 | static struct intel_iommu *device_to_iommu(int segment, u8 bus, u8 devfn) | 607 | static struct intel_iommu *device_to_iommu(int segment, u8 bus, u8 devfn) |
@@ -689,23 +731,31 @@ out: | |||
689 | } | 731 | } |
690 | 732 | ||
691 | static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain, | 733 | static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain, |
692 | unsigned long pfn) | 734 | unsigned long pfn, int large_level) |
693 | { | 735 | { |
694 | int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT; | 736 | int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT; |
695 | struct dma_pte *parent, *pte = NULL; | 737 | struct dma_pte *parent, *pte = NULL; |
696 | int level = agaw_to_level(domain->agaw); | 738 | int level = agaw_to_level(domain->agaw); |
697 | int offset; | 739 | int offset, target_level; |
698 | 740 | ||
699 | BUG_ON(!domain->pgd); | 741 | BUG_ON(!domain->pgd); |
700 | BUG_ON(addr_width < BITS_PER_LONG && pfn >> addr_width); | 742 | BUG_ON(addr_width < BITS_PER_LONG && pfn >> addr_width); |
701 | parent = domain->pgd; | 743 | parent = domain->pgd; |
702 | 744 | ||
745 | /* Search pte */ | ||
746 | if (!large_level) | ||
747 | target_level = 1; | ||
748 | else | ||
749 | target_level = large_level; | ||
750 | |||
703 | while (level > 0) { | 751 | while (level > 0) { |
704 | void *tmp_page; | 752 | void *tmp_page; |
705 | 753 | ||
706 | offset = pfn_level_offset(pfn, level); | 754 | offset = pfn_level_offset(pfn, level); |
707 | pte = &parent[offset]; | 755 | pte = &parent[offset]; |
708 | if (level == 1) | 756 | if (!large_level && (pte->val & DMA_PTE_LARGE_PAGE)) |
757 | break; | ||
758 | if (level == target_level) | ||
709 | break; | 759 | break; |
710 | 760 | ||
711 | if (!dma_pte_present(pte)) { | 761 | if (!dma_pte_present(pte)) { |
@@ -733,10 +783,11 @@ static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain, | |||
733 | return pte; | 783 | return pte; |
734 | } | 784 | } |
735 | 785 | ||
786 | |||
736 | /* return address's pte at specific level */ | 787 | /* return address's pte at specific level */ |
737 | static struct dma_pte *dma_pfn_level_pte(struct dmar_domain *domain, | 788 | static struct dma_pte *dma_pfn_level_pte(struct dmar_domain *domain, |
738 | unsigned long pfn, | 789 | unsigned long pfn, |
739 | int level) | 790 | int level, int *large_page) |
740 | { | 791 | { |
741 | struct dma_pte *parent, *pte = NULL; | 792 | struct dma_pte *parent, *pte = NULL; |
742 | int total = agaw_to_level(domain->agaw); | 793 | int total = agaw_to_level(domain->agaw); |
@@ -749,8 +800,16 @@ static struct dma_pte *dma_pfn_level_pte(struct dmar_domain *domain, | |||
749 | if (level == total) | 800 | if (level == total) |
750 | return pte; | 801 | return pte; |
751 | 802 | ||
752 | if (!dma_pte_present(pte)) | 803 | if (!dma_pte_present(pte)) { |
804 | *large_page = total; | ||
753 | break; | 805 | break; |
806 | } | ||
807 | |||
808 | if (pte->val & DMA_PTE_LARGE_PAGE) { | ||
809 | *large_page = total; | ||
810 | return pte; | ||
811 | } | ||
812 | |||
754 | parent = phys_to_virt(dma_pte_addr(pte)); | 813 | parent = phys_to_virt(dma_pte_addr(pte)); |
755 | total--; | 814 | total--; |
756 | } | 815 | } |
@@ -763,6 +822,7 @@ static void dma_pte_clear_range(struct dmar_domain *domain, | |||
763 | unsigned long last_pfn) | 822 | unsigned long last_pfn) |
764 | { | 823 | { |
765 | int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT; | 824 | int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT; |
825 | unsigned int large_page = 1; | ||
766 | struct dma_pte *first_pte, *pte; | 826 | struct dma_pte *first_pte, *pte; |
767 | 827 | ||
768 | BUG_ON(addr_width < BITS_PER_LONG && start_pfn >> addr_width); | 828 | BUG_ON(addr_width < BITS_PER_LONG && start_pfn >> addr_width); |
@@ -771,14 +831,15 @@ static void dma_pte_clear_range(struct dmar_domain *domain, | |||
771 | 831 | ||
772 | /* we don't need lock here; nobody else touches the iova range */ | 832 | /* we don't need lock here; nobody else touches the iova range */ |
773 | do { | 833 | do { |
774 | first_pte = pte = dma_pfn_level_pte(domain, start_pfn, 1); | 834 | large_page = 1; |
835 | first_pte = pte = dma_pfn_level_pte(domain, start_pfn, 1, &large_page); | ||
775 | if (!pte) { | 836 | if (!pte) { |
776 | start_pfn = align_to_level(start_pfn + 1, 2); | 837 | start_pfn = align_to_level(start_pfn + 1, large_page + 1); |
777 | continue; | 838 | continue; |
778 | } | 839 | } |
779 | do { | 840 | do { |
780 | dma_clear_pte(pte); | 841 | dma_clear_pte(pte); |
781 | start_pfn++; | 842 | start_pfn += lvl_to_nr_pages(large_page); |
782 | pte++; | 843 | pte++; |
783 | } while (start_pfn <= last_pfn && !first_pte_in_page(pte)); | 844 | } while (start_pfn <= last_pfn && !first_pte_in_page(pte)); |
784 | 845 | ||
@@ -798,6 +859,7 @@ static void dma_pte_free_pagetable(struct dmar_domain *domain, | |||
798 | int total = agaw_to_level(domain->agaw); | 859 | int total = agaw_to_level(domain->agaw); |
799 | int level; | 860 | int level; |
800 | unsigned long tmp; | 861 | unsigned long tmp; |
862 | int large_page = 2; | ||
801 | 863 | ||
802 | BUG_ON(addr_width < BITS_PER_LONG && start_pfn >> addr_width); | 864 | BUG_ON(addr_width < BITS_PER_LONG && start_pfn >> addr_width); |
803 | BUG_ON(addr_width < BITS_PER_LONG && last_pfn >> addr_width); | 865 | BUG_ON(addr_width < BITS_PER_LONG && last_pfn >> addr_width); |
@@ -813,7 +875,10 @@ static void dma_pte_free_pagetable(struct dmar_domain *domain, | |||
813 | return; | 875 | return; |
814 | 876 | ||
815 | do { | 877 | do { |
816 | first_pte = pte = dma_pfn_level_pte(domain, tmp, level); | 878 | large_page = level; |
879 | first_pte = pte = dma_pfn_level_pte(domain, tmp, level, &large_page); | ||
880 | if (large_page > level) | ||
881 | level = large_page + 1; | ||
817 | if (!pte) { | 882 | if (!pte) { |
818 | tmp = align_to_level(tmp + 1, level + 1); | 883 | tmp = align_to_level(tmp + 1, level + 1); |
819 | continue; | 884 | continue; |
@@ -1397,6 +1462,7 @@ static int domain_init(struct dmar_domain *domain, int guest_width) | |||
1397 | else | 1462 | else |
1398 | domain->iommu_snooping = 0; | 1463 | domain->iommu_snooping = 0; |
1399 | 1464 | ||
1465 | domain->iommu_superpage = fls(cap_super_page_val(iommu->cap)); | ||
1400 | domain->iommu_count = 1; | 1466 | domain->iommu_count = 1; |
1401 | domain->nid = iommu->node; | 1467 | domain->nid = iommu->node; |
1402 | 1468 | ||
@@ -1417,6 +1483,10 @@ static void domain_exit(struct dmar_domain *domain) | |||
1417 | if (!domain) | 1483 | if (!domain) |
1418 | return; | 1484 | return; |
1419 | 1485 | ||
1486 | /* Flush any lazy unmaps that may reference this domain */ | ||
1487 | if (!intel_iommu_strict) | ||
1488 | flush_unmaps_timeout(0); | ||
1489 | |||
1420 | domain_remove_dev_info(domain); | 1490 | domain_remove_dev_info(domain); |
1421 | /* destroy iovas */ | 1491 | /* destroy iovas */ |
1422 | put_iova_domain(&domain->iovad); | 1492 | put_iova_domain(&domain->iovad); |
@@ -1648,6 +1718,34 @@ static inline unsigned long aligned_nrpages(unsigned long host_addr, | |||
1648 | return PAGE_ALIGN(host_addr + size) >> VTD_PAGE_SHIFT; | 1718 | return PAGE_ALIGN(host_addr + size) >> VTD_PAGE_SHIFT; |
1649 | } | 1719 | } |
1650 | 1720 | ||
1721 | /* Return largest possible superpage level for a given mapping */ | ||
1722 | static inline int hardware_largepage_caps(struct dmar_domain *domain, | ||
1723 | unsigned long iov_pfn, | ||
1724 | unsigned long phy_pfn, | ||
1725 | unsigned long pages) | ||
1726 | { | ||
1727 | int support, level = 1; | ||
1728 | unsigned long pfnmerge; | ||
1729 | |||
1730 | support = domain->iommu_superpage; | ||
1731 | |||
1732 | /* To use a large page, the virtual *and* physical addresses | ||
1733 | must be aligned to 2MiB/1GiB/etc. Lower bits set in either | ||
1734 | of them will mean we have to use smaller pages. So just | ||
1735 | merge them and check both at once. */ | ||
1736 | pfnmerge = iov_pfn | phy_pfn; | ||
1737 | |||
1738 | while (support && !(pfnmerge & ~VTD_STRIDE_MASK)) { | ||
1739 | pages >>= VTD_STRIDE_SHIFT; | ||
1740 | if (!pages) | ||
1741 | break; | ||
1742 | pfnmerge >>= VTD_STRIDE_SHIFT; | ||
1743 | level++; | ||
1744 | support--; | ||
1745 | } | ||
1746 | return level; | ||
1747 | } | ||
1748 | |||
1651 | static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn, | 1749 | static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn, |
1652 | struct scatterlist *sg, unsigned long phys_pfn, | 1750 | struct scatterlist *sg, unsigned long phys_pfn, |
1653 | unsigned long nr_pages, int prot) | 1751 | unsigned long nr_pages, int prot) |
@@ -1656,6 +1754,8 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn, | |||
1656 | phys_addr_t uninitialized_var(pteval); | 1754 | phys_addr_t uninitialized_var(pteval); |
1657 | int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT; | 1755 | int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT; |
1658 | unsigned long sg_res; | 1756 | unsigned long sg_res; |
1757 | unsigned int largepage_lvl = 0; | ||
1758 | unsigned long lvl_pages = 0; | ||
1659 | 1759 | ||
1660 | BUG_ON(addr_width < BITS_PER_LONG && (iov_pfn + nr_pages - 1) >> addr_width); | 1760 | BUG_ON(addr_width < BITS_PER_LONG && (iov_pfn + nr_pages - 1) >> addr_width); |
1661 | 1761 | ||
@@ -1671,7 +1771,7 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn, | |||
1671 | pteval = ((phys_addr_t)phys_pfn << VTD_PAGE_SHIFT) | prot; | 1771 | pteval = ((phys_addr_t)phys_pfn << VTD_PAGE_SHIFT) | prot; |
1672 | } | 1772 | } |
1673 | 1773 | ||
1674 | while (nr_pages--) { | 1774 | while (nr_pages > 0) { |
1675 | uint64_t tmp; | 1775 | uint64_t tmp; |
1676 | 1776 | ||
1677 | if (!sg_res) { | 1777 | if (!sg_res) { |
@@ -1679,11 +1779,21 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn, | |||
1679 | sg->dma_address = ((dma_addr_t)iov_pfn << VTD_PAGE_SHIFT) + sg->offset; | 1779 | sg->dma_address = ((dma_addr_t)iov_pfn << VTD_PAGE_SHIFT) + sg->offset; |
1680 | sg->dma_length = sg->length; | 1780 | sg->dma_length = sg->length; |
1681 | pteval = page_to_phys(sg_page(sg)) | prot; | 1781 | pteval = page_to_phys(sg_page(sg)) | prot; |
1782 | phys_pfn = pteval >> VTD_PAGE_SHIFT; | ||
1682 | } | 1783 | } |
1784 | |||
1683 | if (!pte) { | 1785 | if (!pte) { |
1684 | first_pte = pte = pfn_to_dma_pte(domain, iov_pfn); | 1786 | largepage_lvl = hardware_largepage_caps(domain, iov_pfn, phys_pfn, sg_res); |
1787 | |||
1788 | first_pte = pte = pfn_to_dma_pte(domain, iov_pfn, largepage_lvl); | ||
1685 | if (!pte) | 1789 | if (!pte) |
1686 | return -ENOMEM; | 1790 | return -ENOMEM; |
1791 | /* It is large page*/ | ||
1792 | if (largepage_lvl > 1) | ||
1793 | pteval |= DMA_PTE_LARGE_PAGE; | ||
1794 | else | ||
1795 | pteval &= ~(uint64_t)DMA_PTE_LARGE_PAGE; | ||
1796 | |||
1687 | } | 1797 | } |
1688 | /* We don't need lock here, nobody else | 1798 | /* We don't need lock here, nobody else |
1689 | * touches the iova range | 1799 | * touches the iova range |
@@ -1699,16 +1809,38 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn, | |||
1699 | } | 1809 | } |
1700 | WARN_ON(1); | 1810 | WARN_ON(1); |
1701 | } | 1811 | } |
1812 | |||
1813 | lvl_pages = lvl_to_nr_pages(largepage_lvl); | ||
1814 | |||
1815 | BUG_ON(nr_pages < lvl_pages); | ||
1816 | BUG_ON(sg_res < lvl_pages); | ||
1817 | |||
1818 | nr_pages -= lvl_pages; | ||
1819 | iov_pfn += lvl_pages; | ||
1820 | phys_pfn += lvl_pages; | ||
1821 | pteval += lvl_pages * VTD_PAGE_SIZE; | ||
1822 | sg_res -= lvl_pages; | ||
1823 | |||
1824 | /* If the next PTE would be the first in a new page, then we | ||
1825 | need to flush the cache on the entries we've just written. | ||
1826 | And then we'll need to recalculate 'pte', so clear it and | ||
1827 | let it get set again in the if (!pte) block above. | ||
1828 | |||
1829 | If we're done (!nr_pages) we need to flush the cache too. | ||
1830 | |||
1831 | Also if we've been setting superpages, we may need to | ||
1832 | recalculate 'pte' and switch back to smaller pages for the | ||
1833 | end of the mapping, if the trailing size is not enough to | ||
1834 | use another superpage (i.e. sg_res < lvl_pages). */ | ||
1702 | pte++; | 1835 | pte++; |
1703 | if (!nr_pages || first_pte_in_page(pte)) { | 1836 | if (!nr_pages || first_pte_in_page(pte) || |
1837 | (largepage_lvl > 1 && sg_res < lvl_pages)) { | ||
1704 | domain_flush_cache(domain, first_pte, | 1838 | domain_flush_cache(domain, first_pte, |
1705 | (void *)pte - (void *)first_pte); | 1839 | (void *)pte - (void *)first_pte); |
1706 | pte = NULL; | 1840 | pte = NULL; |
1707 | } | 1841 | } |
1708 | iov_pfn++; | 1842 | |
1709 | pteval += VTD_PAGE_SIZE; | 1843 | if (!sg_res && nr_pages) |
1710 | sg_res--; | ||
1711 | if (!sg_res) | ||
1712 | sg = sg_next(sg); | 1844 | sg = sg_next(sg); |
1713 | } | 1845 | } |
1714 | return 0; | 1846 | return 0; |
@@ -2016,7 +2148,7 @@ static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr, | |||
2016 | if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO) | 2148 | if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO) |
2017 | return 0; | 2149 | return 0; |
2018 | return iommu_prepare_identity_map(pdev, rmrr->base_address, | 2150 | return iommu_prepare_identity_map(pdev, rmrr->base_address, |
2019 | rmrr->end_address + 1); | 2151 | rmrr->end_address); |
2020 | } | 2152 | } |
2021 | 2153 | ||
2022 | #ifdef CONFIG_DMAR_FLOPPY_WA | 2154 | #ifdef CONFIG_DMAR_FLOPPY_WA |
@@ -2030,7 +2162,7 @@ static inline void iommu_prepare_isa(void) | |||
2030 | return; | 2162 | return; |
2031 | 2163 | ||
2032 | printk(KERN_INFO "IOMMU: Prepare 0-16MiB unity mapping for LPC\n"); | 2164 | printk(KERN_INFO "IOMMU: Prepare 0-16MiB unity mapping for LPC\n"); |
2033 | ret = iommu_prepare_identity_map(pdev, 0, 16*1024*1024); | 2165 | ret = iommu_prepare_identity_map(pdev, 0, 16*1024*1024 - 1); |
2034 | 2166 | ||
2035 | if (ret) | 2167 | if (ret) |
2036 | printk(KERN_ERR "IOMMU: Failed to create 0-16MiB identity map; " | 2168 | printk(KERN_ERR "IOMMU: Failed to create 0-16MiB identity map; " |
@@ -2106,10 +2238,10 @@ static int identity_mapping(struct pci_dev *pdev) | |||
2106 | if (likely(!iommu_identity_mapping)) | 2238 | if (likely(!iommu_identity_mapping)) |
2107 | return 0; | 2239 | return 0; |
2108 | 2240 | ||
2241 | info = pdev->dev.archdata.iommu; | ||
2242 | if (info && info != DUMMY_DEVICE_DOMAIN_INFO) | ||
2243 | return (info->domain == si_domain); | ||
2109 | 2244 | ||
2110 | list_for_each_entry(info, &si_domain->devices, link) | ||
2111 | if (info->dev == pdev) | ||
2112 | return 1; | ||
2113 | return 0; | 2245 | return 0; |
2114 | } | 2246 | } |
2115 | 2247 | ||
@@ -2187,8 +2319,19 @@ static int iommu_should_identity_map(struct pci_dev *pdev, int startup) | |||
2187 | * Assume that they will -- if they turn out not to be, then we can | 2319 | * Assume that they will -- if they turn out not to be, then we can |
2188 | * take them out of the 1:1 domain later. | 2320 | * take them out of the 1:1 domain later. |
2189 | */ | 2321 | */ |
2190 | if (!startup) | 2322 | if (!startup) { |
2191 | return pdev->dma_mask > DMA_BIT_MASK(32); | 2323 | /* |
2324 | * If the device's dma_mask is less than the system's memory | ||
2325 | * size then this is not a candidate for identity mapping. | ||
2326 | */ | ||
2327 | u64 dma_mask = pdev->dma_mask; | ||
2328 | |||
2329 | if (pdev->dev.coherent_dma_mask && | ||
2330 | pdev->dev.coherent_dma_mask < dma_mask) | ||
2331 | dma_mask = pdev->dev.coherent_dma_mask; | ||
2332 | |||
2333 | return dma_mask >= dma_get_required_mask(&pdev->dev); | ||
2334 | } | ||
2192 | 2335 | ||
2193 | return 1; | 2336 | return 1; |
2194 | } | 2337 | } |
@@ -2203,6 +2346,9 @@ static int __init iommu_prepare_static_identity_mapping(int hw) | |||
2203 | return -EFAULT; | 2346 | return -EFAULT; |
2204 | 2347 | ||
2205 | for_each_pci_dev(pdev) { | 2348 | for_each_pci_dev(pdev) { |
2349 | /* Skip Host/PCI Bridge devices */ | ||
2350 | if (IS_BRIDGE_HOST_DEVICE(pdev)) | ||
2351 | continue; | ||
2206 | if (iommu_should_identity_map(pdev, 1)) { | 2352 | if (iommu_should_identity_map(pdev, 1)) { |
2207 | printk(KERN_INFO "IOMMU: %s identity mapping for device %s\n", | 2353 | printk(KERN_INFO "IOMMU: %s identity mapping for device %s\n", |
2208 | hw ? "hardware" : "software", pci_name(pdev)); | 2354 | hw ? "hardware" : "software", pci_name(pdev)); |
@@ -2218,7 +2364,7 @@ static int __init iommu_prepare_static_identity_mapping(int hw) | |||
2218 | return 0; | 2364 | return 0; |
2219 | } | 2365 | } |
2220 | 2366 | ||
2221 | static int __init init_dmars(int force_on) | 2367 | static int __init init_dmars(void) |
2222 | { | 2368 | { |
2223 | struct dmar_drhd_unit *drhd; | 2369 | struct dmar_drhd_unit *drhd; |
2224 | struct dmar_rmrr_unit *rmrr; | 2370 | struct dmar_rmrr_unit *rmrr; |
@@ -2592,8 +2738,7 @@ static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr, | |||
2592 | iommu = domain_get_iommu(domain); | 2738 | iommu = domain_get_iommu(domain); |
2593 | size = aligned_nrpages(paddr, size); | 2739 | size = aligned_nrpages(paddr, size); |
2594 | 2740 | ||
2595 | iova = intel_alloc_iova(hwdev, domain, dma_to_mm_pfn(size), | 2741 | iova = intel_alloc_iova(hwdev, domain, dma_to_mm_pfn(size), dma_mask); |
2596 | pdev->dma_mask); | ||
2597 | if (!iova) | 2742 | if (!iova) |
2598 | goto error; | 2743 | goto error; |
2599 | 2744 | ||
@@ -3118,7 +3263,17 @@ static int init_iommu_hw(void) | |||
3118 | if (iommu->qi) | 3263 | if (iommu->qi) |
3119 | dmar_reenable_qi(iommu); | 3264 | dmar_reenable_qi(iommu); |
3120 | 3265 | ||
3121 | for_each_active_iommu(iommu, drhd) { | 3266 | for_each_iommu(iommu, drhd) { |
3267 | if (drhd->ignored) { | ||
3268 | /* | ||
3269 | * we always have to disable PMRs or DMA may fail on | ||
3270 | * this device | ||
3271 | */ | ||
3272 | if (force_on) | ||
3273 | iommu_disable_protect_mem_regions(iommu); | ||
3274 | continue; | ||
3275 | } | ||
3276 | |||
3122 | iommu_flush_write_buffer(iommu); | 3277 | iommu_flush_write_buffer(iommu); |
3123 | 3278 | ||
3124 | iommu_set_root_entry(iommu); | 3279 | iommu_set_root_entry(iommu); |
@@ -3127,7 +3282,8 @@ static int init_iommu_hw(void) | |||
3127 | DMA_CCMD_GLOBAL_INVL); | 3282 | DMA_CCMD_GLOBAL_INVL); |
3128 | iommu->flush.flush_iotlb(iommu, 0, 0, 0, | 3283 | iommu->flush.flush_iotlb(iommu, 0, 0, 0, |
3129 | DMA_TLB_GLOBAL_FLUSH); | 3284 | DMA_TLB_GLOBAL_FLUSH); |
3130 | iommu_enable_translation(iommu); | 3285 | if (iommu_enable_translation(iommu)) |
3286 | return 1; | ||
3131 | iommu_disable_protect_mem_regions(iommu); | 3287 | iommu_disable_protect_mem_regions(iommu); |
3132 | } | 3288 | } |
3133 | 3289 | ||
@@ -3194,7 +3350,10 @@ static void iommu_resume(void) | |||
3194 | unsigned long flag; | 3350 | unsigned long flag; |
3195 | 3351 | ||
3196 | if (init_iommu_hw()) { | 3352 | if (init_iommu_hw()) { |
3197 | WARN(1, "IOMMU setup failed, DMAR can not resume!\n"); | 3353 | if (force_on) |
3354 | panic("tboot: IOMMU setup failed, DMAR can not resume!\n"); | ||
3355 | else | ||
3356 | WARN(1, "IOMMU setup failed, DMAR can not resume!\n"); | ||
3198 | return; | 3357 | return; |
3199 | } | 3358 | } |
3200 | 3359 | ||
@@ -3271,7 +3430,6 @@ static struct notifier_block device_nb = { | |||
3271 | int __init intel_iommu_init(void) | 3430 | int __init intel_iommu_init(void) |
3272 | { | 3431 | { |
3273 | int ret = 0; | 3432 | int ret = 0; |
3274 | int force_on = 0; | ||
3275 | 3433 | ||
3276 | /* VT-d is required for a TXT/tboot launch, so enforce that */ | 3434 | /* VT-d is required for a TXT/tboot launch, so enforce that */ |
3277 | force_on = tboot_force_iommu(); | 3435 | force_on = tboot_force_iommu(); |
@@ -3309,7 +3467,7 @@ int __init intel_iommu_init(void) | |||
3309 | 3467 | ||
3310 | init_no_remapping_devices(); | 3468 | init_no_remapping_devices(); |
3311 | 3469 | ||
3312 | ret = init_dmars(force_on); | 3470 | ret = init_dmars(); |
3313 | if (ret) { | 3471 | if (ret) { |
3314 | if (force_on) | 3472 | if (force_on) |
3315 | panic("tboot: Failed to initialize DMARs\n"); | 3473 | panic("tboot: Failed to initialize DMARs\n"); |
@@ -3380,8 +3538,8 @@ static void domain_remove_one_dev_info(struct dmar_domain *domain, | |||
3380 | spin_lock_irqsave(&device_domain_lock, flags); | 3538 | spin_lock_irqsave(&device_domain_lock, flags); |
3381 | list_for_each_safe(entry, tmp, &domain->devices) { | 3539 | list_for_each_safe(entry, tmp, &domain->devices) { |
3382 | info = list_entry(entry, struct device_domain_info, link); | 3540 | info = list_entry(entry, struct device_domain_info, link); |
3383 | /* No need to compare PCI domain; it has to be the same */ | 3541 | if (info->segment == pci_domain_nr(pdev->bus) && |
3384 | if (info->bus == pdev->bus->number && | 3542 | info->bus == pdev->bus->number && |
3385 | info->devfn == pdev->devfn) { | 3543 | info->devfn == pdev->devfn) { |
3386 | list_del(&info->link); | 3544 | list_del(&info->link); |
3387 | list_del(&info->global); | 3545 | list_del(&info->global); |
@@ -3419,10 +3577,13 @@ static void domain_remove_one_dev_info(struct dmar_domain *domain, | |||
3419 | domain_update_iommu_cap(domain); | 3577 | domain_update_iommu_cap(domain); |
3420 | spin_unlock_irqrestore(&domain->iommu_lock, tmp_flags); | 3578 | spin_unlock_irqrestore(&domain->iommu_lock, tmp_flags); |
3421 | 3579 | ||
3422 | spin_lock_irqsave(&iommu->lock, tmp_flags); | 3580 | if (!(domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE) && |
3423 | clear_bit(domain->id, iommu->domain_ids); | 3581 | !(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY)) { |
3424 | iommu->domains[domain->id] = NULL; | 3582 | spin_lock_irqsave(&iommu->lock, tmp_flags); |
3425 | spin_unlock_irqrestore(&iommu->lock, tmp_flags); | 3583 | clear_bit(domain->id, iommu->domain_ids); |
3584 | iommu->domains[domain->id] = NULL; | ||
3585 | spin_unlock_irqrestore(&iommu->lock, tmp_flags); | ||
3586 | } | ||
3426 | } | 3587 | } |
3427 | 3588 | ||
3428 | spin_unlock_irqrestore(&device_domain_lock, flags); | 3589 | spin_unlock_irqrestore(&device_domain_lock, flags); |
@@ -3505,6 +3666,7 @@ static int md_domain_init(struct dmar_domain *domain, int guest_width) | |||
3505 | domain->iommu_count = 0; | 3666 | domain->iommu_count = 0; |
3506 | domain->iommu_coherency = 0; | 3667 | domain->iommu_coherency = 0; |
3507 | domain->iommu_snooping = 0; | 3668 | domain->iommu_snooping = 0; |
3669 | domain->iommu_superpage = 0; | ||
3508 | domain->max_addr = 0; | 3670 | domain->max_addr = 0; |
3509 | domain->nid = -1; | 3671 | domain->nid = -1; |
3510 | 3672 | ||
@@ -3720,7 +3882,7 @@ static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain, | |||
3720 | struct dma_pte *pte; | 3882 | struct dma_pte *pte; |
3721 | u64 phys = 0; | 3883 | u64 phys = 0; |
3722 | 3884 | ||
3723 | pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT); | 3885 | pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, 0); |
3724 | if (pte) | 3886 | if (pte) |
3725 | phys = dma_pte_addr(pte); | 3887 | phys = dma_pte_addr(pte); |
3726 | 3888 | ||
diff --git a/drivers/pci/iova.c b/drivers/pci/iova.c index 9606e599a475..c5c274ab5c5a 100644 --- a/drivers/pci/iova.c +++ b/drivers/pci/iova.c | |||
@@ -63,8 +63,16 @@ __cached_rbnode_delete_update(struct iova_domain *iovad, struct iova *free) | |||
63 | curr = iovad->cached32_node; | 63 | curr = iovad->cached32_node; |
64 | cached_iova = container_of(curr, struct iova, node); | 64 | cached_iova = container_of(curr, struct iova, node); |
65 | 65 | ||
66 | if (free->pfn_lo >= cached_iova->pfn_lo) | 66 | if (free->pfn_lo >= cached_iova->pfn_lo) { |
67 | iovad->cached32_node = rb_next(&free->node); | 67 | struct rb_node *node = rb_next(&free->node); |
68 | struct iova *iova = container_of(node, struct iova, node); | ||
69 | |||
70 | /* only cache if it's below 32bit pfn */ | ||
71 | if (node && iova->pfn_lo < iovad->dma_32bit_pfn) | ||
72 | iovad->cached32_node = node; | ||
73 | else | ||
74 | iovad->cached32_node = NULL; | ||
75 | } | ||
68 | } | 76 | } |
69 | 77 | ||
70 | /* Computes the padding size required, to make the | 78 | /* Computes the padding size required, to make the |
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 7c3b18e78cee..d36f41ea8cbf 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
@@ -195,6 +195,8 @@ static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev) | |||
195 | return PCI_D2; | 195 | return PCI_D2; |
196 | case ACPI_STATE_D3: | 196 | case ACPI_STATE_D3: |
197 | return PCI_D3hot; | 197 | return PCI_D3hot; |
198 | case ACPI_STATE_D3_COLD: | ||
199 | return PCI_D3cold; | ||
198 | } | 200 | } |
199 | return PCI_POWER_ERROR; | 201 | return PCI_POWER_ERROR; |
200 | } | 202 | } |
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 5cb999b50f95..45e0191c35dd 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig | |||
@@ -39,7 +39,7 @@ config ACER_WMI | |||
39 | 39 | ||
40 | config ACERHDF | 40 | config ACERHDF |
41 | tristate "Acer Aspire One temperature and fan driver" | 41 | tristate "Acer Aspire One temperature and fan driver" |
42 | depends on THERMAL && THERMAL_HWMON && ACPI | 42 | depends on THERMAL && ACPI |
43 | ---help--- | 43 | ---help--- |
44 | This is a driver for Acer Aspire One netbooks. It allows to access | 44 | This is a driver for Acer Aspire One netbooks. It allows to access |
45 | the temperature sensor and to control the fan. | 45 | the temperature sensor and to control the fan. |
@@ -760,4 +760,13 @@ config MXM_WMI | |||
760 | MXM is a standard for laptop graphics cards, the WMI interface | 760 | MXM is a standard for laptop graphics cards, the WMI interface |
761 | is required for switchable nvidia graphics machines | 761 | is required for switchable nvidia graphics machines |
762 | 762 | ||
763 | config INTEL_OAKTRAIL | ||
764 | tristate "Intel Oaktrail Platform Extras" | ||
765 | depends on ACPI | ||
766 | depends on RFKILL && BACKLIGHT_CLASS_DEVICE && ACPI | ||
767 | ---help--- | ||
768 | Intel Oaktrail platform need this driver to provide interfaces to | ||
769 | enable/disable the Camera, WiFi, BT etc. devices. If in doubt, say Y | ||
770 | here; it will only load on supported platforms. | ||
771 | |||
763 | endif # X86_PLATFORM_DEVICES | 772 | endif # X86_PLATFORM_DEVICES |
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index a7ab3bc7b3a1..afc1f832aa67 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile | |||
@@ -41,5 +41,6 @@ obj-$(CONFIG_XO1_RFKILL) += xo1-rfkill.o | |||
41 | obj-$(CONFIG_XO15_EBOOK) += xo15-ebook.o | 41 | obj-$(CONFIG_XO15_EBOOK) += xo15-ebook.o |
42 | obj-$(CONFIG_IBM_RTL) += ibm_rtl.o | 42 | obj-$(CONFIG_IBM_RTL) += ibm_rtl.o |
43 | obj-$(CONFIG_SAMSUNG_LAPTOP) += samsung-laptop.o | 43 | obj-$(CONFIG_SAMSUNG_LAPTOP) += samsung-laptop.o |
44 | obj-$(CONFIG_INTEL_MFLD_THERMAL) += intel_mid_thermal.o | ||
45 | obj-$(CONFIG_MXM_WMI) += mxm-wmi.o | 44 | obj-$(CONFIG_MXM_WMI) += mxm-wmi.o |
45 | obj-$(CONFIG_INTEL_MID_POWER_BUTTON) += intel_mid_powerbtn.o | ||
46 | obj-$(CONFIG_INTEL_OAKTRAIL) += intel_oaktrail.o | ||
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index ac4e7f83ce6c..005417bd429e 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c | |||
@@ -98,13 +98,26 @@ enum acer_wmi_event_ids { | |||
98 | 98 | ||
99 | static const struct key_entry acer_wmi_keymap[] = { | 99 | static const struct key_entry acer_wmi_keymap[] = { |
100 | {KE_KEY, 0x01, {KEY_WLAN} }, /* WiFi */ | 100 | {KE_KEY, 0x01, {KEY_WLAN} }, /* WiFi */ |
101 | {KE_KEY, 0x03, {KEY_WLAN} }, /* WiFi */ | ||
101 | {KE_KEY, 0x12, {KEY_BLUETOOTH} }, /* BT */ | 102 | {KE_KEY, 0x12, {KEY_BLUETOOTH} }, /* BT */ |
102 | {KE_KEY, 0x21, {KEY_PROG1} }, /* Backup */ | 103 | {KE_KEY, 0x21, {KEY_PROG1} }, /* Backup */ |
103 | {KE_KEY, 0x22, {KEY_PROG2} }, /* Arcade */ | 104 | {KE_KEY, 0x22, {KEY_PROG2} }, /* Arcade */ |
104 | {KE_KEY, 0x23, {KEY_PROG3} }, /* P_Key */ | 105 | {KE_KEY, 0x23, {KEY_PROG3} }, /* P_Key */ |
105 | {KE_KEY, 0x24, {KEY_PROG4} }, /* Social networking_Key */ | 106 | {KE_KEY, 0x24, {KEY_PROG4} }, /* Social networking_Key */ |
107 | {KE_IGNORE, 0x41, {KEY_MUTE} }, | ||
108 | {KE_IGNORE, 0x42, {KEY_PREVIOUSSONG} }, | ||
109 | {KE_IGNORE, 0x43, {KEY_NEXTSONG} }, | ||
110 | {KE_IGNORE, 0x44, {KEY_PLAYPAUSE} }, | ||
111 | {KE_IGNORE, 0x45, {KEY_STOP} }, | ||
112 | {KE_IGNORE, 0x48, {KEY_VOLUMEUP} }, | ||
113 | {KE_IGNORE, 0x49, {KEY_VOLUMEDOWN} }, | ||
114 | {KE_IGNORE, 0x61, {KEY_SWITCHVIDEOMODE} }, | ||
115 | {KE_IGNORE, 0x62, {KEY_BRIGHTNESSUP} }, | ||
116 | {KE_IGNORE, 0x63, {KEY_BRIGHTNESSDOWN} }, | ||
106 | {KE_KEY, 0x64, {KEY_SWITCHVIDEOMODE} }, /* Display Switch */ | 117 | {KE_KEY, 0x64, {KEY_SWITCHVIDEOMODE} }, /* Display Switch */ |
118 | {KE_IGNORE, 0x81, {KEY_SLEEP} }, | ||
107 | {KE_KEY, 0x82, {KEY_TOUCHPAD_TOGGLE} }, /* Touch Pad On/Off */ | 119 | {KE_KEY, 0x82, {KEY_TOUCHPAD_TOGGLE} }, /* Touch Pad On/Off */ |
120 | {KE_IGNORE, 0x83, {KEY_TOUCHPAD_TOGGLE} }, | ||
108 | {KE_END, 0} | 121 | {KE_END, 0} |
109 | }; | 122 | }; |
110 | 123 | ||
@@ -122,6 +135,7 @@ struct event_return_value { | |||
122 | */ | 135 | */ |
123 | #define ACER_WMID3_GDS_WIRELESS (1<<0) /* WiFi */ | 136 | #define ACER_WMID3_GDS_WIRELESS (1<<0) /* WiFi */ |
124 | #define ACER_WMID3_GDS_THREEG (1<<6) /* 3G */ | 137 | #define ACER_WMID3_GDS_THREEG (1<<6) /* 3G */ |
138 | #define ACER_WMID3_GDS_WIMAX (1<<7) /* WiMAX */ | ||
125 | #define ACER_WMID3_GDS_BLUETOOTH (1<<11) /* BT */ | 139 | #define ACER_WMID3_GDS_BLUETOOTH (1<<11) /* BT */ |
126 | 140 | ||
127 | struct lm_input_params { | 141 | struct lm_input_params { |
@@ -737,8 +751,11 @@ WMI_execute_u32(u32 method_id, u32 in, u32 *out) | |||
737 | 751 | ||
738 | obj = (union acpi_object *) result.pointer; | 752 | obj = (union acpi_object *) result.pointer; |
739 | if (obj && obj->type == ACPI_TYPE_BUFFER && | 753 | if (obj && obj->type == ACPI_TYPE_BUFFER && |
740 | obj->buffer.length == sizeof(u32)) { | 754 | (obj->buffer.length == sizeof(u32) || |
755 | obj->buffer.length == sizeof(u64))) { | ||
741 | tmp = *((u32 *) obj->buffer.pointer); | 756 | tmp = *((u32 *) obj->buffer.pointer); |
757 | } else if (obj->type == ACPI_TYPE_INTEGER) { | ||
758 | tmp = (u32) obj->integer.value; | ||
742 | } else { | 759 | } else { |
743 | tmp = 0; | 760 | tmp = 0; |
744 | } | 761 | } |
@@ -866,8 +883,11 @@ static acpi_status WMID_set_capabilities(void) | |||
866 | 883 | ||
867 | obj = (union acpi_object *) out.pointer; | 884 | obj = (union acpi_object *) out.pointer; |
868 | if (obj && obj->type == ACPI_TYPE_BUFFER && | 885 | if (obj && obj->type == ACPI_TYPE_BUFFER && |
869 | obj->buffer.length == sizeof(u32)) { | 886 | (obj->buffer.length == sizeof(u32) || |
887 | obj->buffer.length == sizeof(u64))) { | ||
870 | devices = *((u32 *) obj->buffer.pointer); | 888 | devices = *((u32 *) obj->buffer.pointer); |
889 | } else if (obj->type == ACPI_TYPE_INTEGER) { | ||
890 | devices = (u32) obj->integer.value; | ||
871 | } else { | 891 | } else { |
872 | kfree(out.pointer); | 892 | kfree(out.pointer); |
873 | return AE_ERROR; | 893 | return AE_ERROR; |
@@ -876,7 +896,8 @@ static acpi_status WMID_set_capabilities(void) | |||
876 | dmi_walk(type_aa_dmi_decode, NULL); | 896 | dmi_walk(type_aa_dmi_decode, NULL); |
877 | if (!has_type_aa) { | 897 | if (!has_type_aa) { |
878 | interface->capability |= ACER_CAP_WIRELESS; | 898 | interface->capability |= ACER_CAP_WIRELESS; |
879 | interface->capability |= ACER_CAP_THREEG; | 899 | if (devices & 0x40) |
900 | interface->capability |= ACER_CAP_THREEG; | ||
880 | if (devices & 0x10) | 901 | if (devices & 0x10) |
881 | interface->capability |= ACER_CAP_BLUETOOTH; | 902 | interface->capability |= ACER_CAP_BLUETOOTH; |
882 | } | 903 | } |
@@ -961,10 +982,12 @@ static void __init acer_commandline_init(void) | |||
961 | * These will all fail silently if the value given is invalid, or the | 982 | * These will all fail silently if the value given is invalid, or the |
962 | * capability isn't available on the given interface | 983 | * capability isn't available on the given interface |
963 | */ | 984 | */ |
964 | set_u32(mailled, ACER_CAP_MAILLED); | 985 | if (mailled >= 0) |
965 | if (!has_type_aa) | 986 | set_u32(mailled, ACER_CAP_MAILLED); |
987 | if (!has_type_aa && threeg >= 0) | ||
966 | set_u32(threeg, ACER_CAP_THREEG); | 988 | set_u32(threeg, ACER_CAP_THREEG); |
967 | set_u32(brightness, ACER_CAP_BRIGHTNESS); | 989 | if (brightness >= 0) |
990 | set_u32(brightness, ACER_CAP_BRIGHTNESS); | ||
968 | } | 991 | } |
969 | 992 | ||
970 | /* | 993 | /* |
@@ -1081,7 +1104,7 @@ static acpi_status wmid3_get_device_status(u32 *value, u16 device) | |||
1081 | return AE_ERROR; | 1104 | return AE_ERROR; |
1082 | } | 1105 | } |
1083 | if (obj->buffer.length != 8) { | 1106 | if (obj->buffer.length != 8) { |
1084 | pr_warning("Unknown buffer length %d\n", obj->buffer.length); | 1107 | pr_warn("Unknown buffer length %d\n", obj->buffer.length); |
1085 | kfree(obj); | 1108 | kfree(obj); |
1086 | return AE_ERROR; | 1109 | return AE_ERROR; |
1087 | } | 1110 | } |
@@ -1090,8 +1113,8 @@ static acpi_status wmid3_get_device_status(u32 *value, u16 device) | |||
1090 | kfree(obj); | 1113 | kfree(obj); |
1091 | 1114 | ||
1092 | if (return_value.error_code || return_value.ec_return_value) | 1115 | if (return_value.error_code || return_value.ec_return_value) |
1093 | pr_warning("Get Device Status failed: " | 1116 | pr_warn("Get Device Status failed: 0x%x - 0x%x\n", |
1094 | "0x%x - 0x%x\n", return_value.error_code, | 1117 | return_value.error_code, |
1095 | return_value.ec_return_value); | 1118 | return_value.ec_return_value); |
1096 | else | 1119 | else |
1097 | *value = !!(return_value.devices & device); | 1120 | *value = !!(return_value.devices & device); |
@@ -1124,6 +1147,114 @@ static acpi_status get_device_status(u32 *value, u32 cap) | |||
1124 | } | 1147 | } |
1125 | } | 1148 | } |
1126 | 1149 | ||
1150 | static acpi_status wmid3_set_device_status(u32 value, u16 device) | ||
1151 | { | ||
1152 | struct wmid3_gds_return_value return_value; | ||
1153 | acpi_status status; | ||
1154 | union acpi_object *obj; | ||
1155 | u16 devices; | ||
1156 | struct wmid3_gds_input_param params = { | ||
1157 | .function_num = 0x1, | ||
1158 | .hotkey_number = 0x01, | ||
1159 | .devices = ACER_WMID3_GDS_WIRELESS & | ||
1160 | ACER_WMID3_GDS_THREEG & | ||
1161 | ACER_WMID3_GDS_WIMAX & | ||
1162 | ACER_WMID3_GDS_BLUETOOTH, | ||
1163 | }; | ||
1164 | struct acpi_buffer input = { | ||
1165 | sizeof(struct wmid3_gds_input_param), | ||
1166 | ¶ms | ||
1167 | }; | ||
1168 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
1169 | struct acpi_buffer output2 = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
1170 | |||
1171 | status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &input, &output); | ||
1172 | if (ACPI_FAILURE(status)) | ||
1173 | return status; | ||
1174 | |||
1175 | obj = output.pointer; | ||
1176 | |||
1177 | if (!obj) | ||
1178 | return AE_ERROR; | ||
1179 | else if (obj->type != ACPI_TYPE_BUFFER) { | ||
1180 | kfree(obj); | ||
1181 | return AE_ERROR; | ||
1182 | } | ||
1183 | if (obj->buffer.length != 8) { | ||
1184 | pr_warning("Unknown buffer length %d\n", obj->buffer.length); | ||
1185 | kfree(obj); | ||
1186 | return AE_ERROR; | ||
1187 | } | ||
1188 | |||
1189 | return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer); | ||
1190 | kfree(obj); | ||
1191 | |||
1192 | if (return_value.error_code || return_value.ec_return_value) { | ||
1193 | pr_warning("Get Current Device Status failed: " | ||
1194 | "0x%x - 0x%x\n", return_value.error_code, | ||
1195 | return_value.ec_return_value); | ||
1196 | return status; | ||
1197 | } | ||
1198 | |||
1199 | devices = return_value.devices; | ||
1200 | params.function_num = 0x2; | ||
1201 | params.hotkey_number = 0x01; | ||
1202 | params.devices = (value) ? (devices | device) : (devices & ~device); | ||
1203 | |||
1204 | status = wmi_evaluate_method(WMID_GUID3, 0, 0x1, &input, &output2); | ||
1205 | if (ACPI_FAILURE(status)) | ||
1206 | return status; | ||
1207 | |||
1208 | obj = output2.pointer; | ||
1209 | |||
1210 | if (!obj) | ||
1211 | return AE_ERROR; | ||
1212 | else if (obj->type != ACPI_TYPE_BUFFER) { | ||
1213 | kfree(obj); | ||
1214 | return AE_ERROR; | ||
1215 | } | ||
1216 | if (obj->buffer.length != 4) { | ||
1217 | pr_warning("Unknown buffer length %d\n", obj->buffer.length); | ||
1218 | kfree(obj); | ||
1219 | return AE_ERROR; | ||
1220 | } | ||
1221 | |||
1222 | return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer); | ||
1223 | kfree(obj); | ||
1224 | |||
1225 | if (return_value.error_code || return_value.ec_return_value) | ||
1226 | pr_warning("Set Device Status failed: " | ||
1227 | "0x%x - 0x%x\n", return_value.error_code, | ||
1228 | return_value.ec_return_value); | ||
1229 | |||
1230 | return status; | ||
1231 | } | ||
1232 | |||
1233 | static acpi_status set_device_status(u32 value, u32 cap) | ||
1234 | { | ||
1235 | if (wmi_has_guid(WMID_GUID3)) { | ||
1236 | u16 device; | ||
1237 | |||
1238 | switch (cap) { | ||
1239 | case ACER_CAP_WIRELESS: | ||
1240 | device = ACER_WMID3_GDS_WIRELESS; | ||
1241 | break; | ||
1242 | case ACER_CAP_BLUETOOTH: | ||
1243 | device = ACER_WMID3_GDS_BLUETOOTH; | ||
1244 | break; | ||
1245 | case ACER_CAP_THREEG: | ||
1246 | device = ACER_WMID3_GDS_THREEG; | ||
1247 | break; | ||
1248 | default: | ||
1249 | return AE_ERROR; | ||
1250 | } | ||
1251 | return wmid3_set_device_status(value, device); | ||
1252 | |||
1253 | } else { | ||
1254 | return set_u32(value, cap); | ||
1255 | } | ||
1256 | } | ||
1257 | |||
1127 | /* | 1258 | /* |
1128 | * Rfkill devices | 1259 | * Rfkill devices |
1129 | */ | 1260 | */ |
@@ -1160,7 +1291,7 @@ static int acer_rfkill_set(void *data, bool blocked) | |||
1160 | u32 cap = (unsigned long)data; | 1291 | u32 cap = (unsigned long)data; |
1161 | 1292 | ||
1162 | if (rfkill_inited) { | 1293 | if (rfkill_inited) { |
1163 | status = set_u32(!blocked, cap); | 1294 | status = set_device_status(!blocked, cap); |
1164 | if (ACPI_FAILURE(status)) | 1295 | if (ACPI_FAILURE(status)) |
1165 | return -ENODEV; | 1296 | return -ENODEV; |
1166 | } | 1297 | } |
@@ -1317,7 +1448,7 @@ static void acer_wmi_notify(u32 value, void *context) | |||
1317 | 1448 | ||
1318 | status = wmi_get_event_data(value, &response); | 1449 | status = wmi_get_event_data(value, &response); |
1319 | if (status != AE_OK) { | 1450 | if (status != AE_OK) { |
1320 | pr_warning("bad event status 0x%x\n", status); | 1451 | pr_warn("bad event status 0x%x\n", status); |
1321 | return; | 1452 | return; |
1322 | } | 1453 | } |
1323 | 1454 | ||
@@ -1326,12 +1457,12 @@ static void acer_wmi_notify(u32 value, void *context) | |||
1326 | if (!obj) | 1457 | if (!obj) |
1327 | return; | 1458 | return; |
1328 | if (obj->type != ACPI_TYPE_BUFFER) { | 1459 | if (obj->type != ACPI_TYPE_BUFFER) { |
1329 | pr_warning("Unknown response received %d\n", obj->type); | 1460 | pr_warn("Unknown response received %d\n", obj->type); |
1330 | kfree(obj); | 1461 | kfree(obj); |
1331 | return; | 1462 | return; |
1332 | } | 1463 | } |
1333 | if (obj->buffer.length != 8) { | 1464 | if (obj->buffer.length != 8) { |
1334 | pr_warning("Unknown buffer length %d\n", obj->buffer.length); | 1465 | pr_warn("Unknown buffer length %d\n", obj->buffer.length); |
1335 | kfree(obj); | 1466 | kfree(obj); |
1336 | return; | 1467 | return; |
1337 | } | 1468 | } |
@@ -1343,7 +1474,7 @@ static void acer_wmi_notify(u32 value, void *context) | |||
1343 | case WMID_HOTKEY_EVENT: | 1474 | case WMID_HOTKEY_EVENT: |
1344 | if (return_value.device_state) { | 1475 | if (return_value.device_state) { |
1345 | u16 device_state = return_value.device_state; | 1476 | u16 device_state = return_value.device_state; |
1346 | pr_debug("deivces states: 0x%x\n", device_state); | 1477 | pr_debug("device state: 0x%x\n", device_state); |
1347 | if (has_cap(ACER_CAP_WIRELESS)) | 1478 | if (has_cap(ACER_CAP_WIRELESS)) |
1348 | rfkill_set_sw_state(wireless_rfkill, | 1479 | rfkill_set_sw_state(wireless_rfkill, |
1349 | !(device_state & ACER_WMID3_GDS_WIRELESS)); | 1480 | !(device_state & ACER_WMID3_GDS_WIRELESS)); |
@@ -1356,11 +1487,11 @@ static void acer_wmi_notify(u32 value, void *context) | |||
1356 | } | 1487 | } |
1357 | if (!sparse_keymap_report_event(acer_wmi_input_dev, | 1488 | if (!sparse_keymap_report_event(acer_wmi_input_dev, |
1358 | return_value.key_num, 1, true)) | 1489 | return_value.key_num, 1, true)) |
1359 | pr_warning("Unknown key number - 0x%x\n", | 1490 | pr_warn("Unknown key number - 0x%x\n", |
1360 | return_value.key_num); | 1491 | return_value.key_num); |
1361 | break; | 1492 | break; |
1362 | default: | 1493 | default: |
1363 | pr_warning("Unknown function number - %d - %d\n", | 1494 | pr_warn("Unknown function number - %d - %d\n", |
1364 | return_value.function, return_value.key_num); | 1495 | return_value.function, return_value.key_num); |
1365 | break; | 1496 | break; |
1366 | } | 1497 | } |
@@ -1389,7 +1520,7 @@ wmid3_set_lm_mode(struct lm_input_params *params, | |||
1389 | return AE_ERROR; | 1520 | return AE_ERROR; |
1390 | } | 1521 | } |
1391 | if (obj->buffer.length != 4) { | 1522 | if (obj->buffer.length != 4) { |
1392 | pr_warning("Unknown buffer length %d\n", obj->buffer.length); | 1523 | pr_warn("Unknown buffer length %d\n", obj->buffer.length); |
1393 | kfree(obj); | 1524 | kfree(obj); |
1394 | return AE_ERROR; | 1525 | return AE_ERROR; |
1395 | } | 1526 | } |
@@ -1414,11 +1545,11 @@ static int acer_wmi_enable_ec_raw(void) | |||
1414 | status = wmid3_set_lm_mode(¶ms, &return_value); | 1545 | status = wmid3_set_lm_mode(¶ms, &return_value); |
1415 | 1546 | ||
1416 | if (return_value.error_code || return_value.ec_return_value) | 1547 | if (return_value.error_code || return_value.ec_return_value) |
1417 | pr_warning("Enabling EC raw mode failed: " | 1548 | pr_warn("Enabling EC raw mode failed: 0x%x - 0x%x\n", |
1418 | "0x%x - 0x%x\n", return_value.error_code, | 1549 | return_value.error_code, |
1419 | return_value.ec_return_value); | 1550 | return_value.ec_return_value); |
1420 | else | 1551 | else |
1421 | pr_info("Enabled EC raw mode"); | 1552 | pr_info("Enabled EC raw mode\n"); |
1422 | 1553 | ||
1423 | return status; | 1554 | return status; |
1424 | } | 1555 | } |
@@ -1437,9 +1568,9 @@ static int acer_wmi_enable_lm(void) | |||
1437 | status = wmid3_set_lm_mode(¶ms, &return_value); | 1568 | status = wmid3_set_lm_mode(¶ms, &return_value); |
1438 | 1569 | ||
1439 | if (return_value.error_code || return_value.ec_return_value) | 1570 | if (return_value.error_code || return_value.ec_return_value) |
1440 | pr_warning("Enabling Launch Manager failed: " | 1571 | pr_warn("Enabling Launch Manager failed: 0x%x - 0x%x\n", |
1441 | "0x%x - 0x%x\n", return_value.error_code, | 1572 | return_value.error_code, |
1442 | return_value.ec_return_value); | 1573 | return_value.ec_return_value); |
1443 | 1574 | ||
1444 | return status; | 1575 | return status; |
1445 | } | 1576 | } |
@@ -1506,8 +1637,11 @@ static u32 get_wmid_devices(void) | |||
1506 | 1637 | ||
1507 | obj = (union acpi_object *) out.pointer; | 1638 | obj = (union acpi_object *) out.pointer; |
1508 | if (obj && obj->type == ACPI_TYPE_BUFFER && | 1639 | if (obj && obj->type == ACPI_TYPE_BUFFER && |
1509 | obj->buffer.length == sizeof(u32)) { | 1640 | (obj->buffer.length == sizeof(u32) || |
1641 | obj->buffer.length == sizeof(u64))) { | ||
1510 | devices = *((u32 *) obj->buffer.pointer); | 1642 | devices = *((u32 *) obj->buffer.pointer); |
1643 | } else if (obj->type == ACPI_TYPE_INTEGER) { | ||
1644 | devices = (u32) obj->integer.value; | ||
1511 | } | 1645 | } |
1512 | 1646 | ||
1513 | kfree(out.pointer); | 1647 | kfree(out.pointer); |
diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c index 60f9cfcac93f..fca3489218b7 100644 --- a/drivers/platform/x86/acerhdf.c +++ b/drivers/platform/x86/acerhdf.c | |||
@@ -35,10 +35,8 @@ | |||
35 | 35 | ||
36 | #include <linux/kernel.h> | 36 | #include <linux/kernel.h> |
37 | #include <linux/module.h> | 37 | #include <linux/module.h> |
38 | #include <linux/fs.h> | ||
39 | #include <linux/dmi.h> | 38 | #include <linux/dmi.h> |
40 | #include <acpi/acpi_drivers.h> | 39 | #include <linux/acpi.h> |
41 | #include <linux/sched.h> | ||
42 | #include <linux/thermal.h> | 40 | #include <linux/thermal.h> |
43 | #include <linux/platform_device.h> | 41 | #include <linux/platform_device.h> |
44 | 42 | ||
diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index c53b3ff7978a..d65df92e2acc 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c | |||
@@ -318,7 +318,7 @@ static int acpi_check_handle(acpi_handle handle, const char *method, | |||
318 | 318 | ||
319 | if (status != AE_OK) { | 319 | if (status != AE_OK) { |
320 | if (ret) | 320 | if (ret) |
321 | pr_warning("Error finding %s\n", method); | 321 | pr_warn("Error finding %s\n", method); |
322 | return -ENODEV; | 322 | return -ENODEV; |
323 | } | 323 | } |
324 | return 0; | 324 | return 0; |
@@ -383,7 +383,7 @@ static int asus_kled_lvl(struct asus_laptop *asus) | |||
383 | rv = acpi_evaluate_integer(asus->handle, METHOD_KBD_LIGHT_GET, | 383 | rv = acpi_evaluate_integer(asus->handle, METHOD_KBD_LIGHT_GET, |
384 | ¶ms, &kblv); | 384 | ¶ms, &kblv); |
385 | if (ACPI_FAILURE(rv)) { | 385 | if (ACPI_FAILURE(rv)) { |
386 | pr_warning("Error reading kled level\n"); | 386 | pr_warn("Error reading kled level\n"); |
387 | return -ENODEV; | 387 | return -ENODEV; |
388 | } | 388 | } |
389 | return kblv; | 389 | return kblv; |
@@ -397,7 +397,7 @@ static int asus_kled_set(struct asus_laptop *asus, int kblv) | |||
397 | kblv = 0; | 397 | kblv = 0; |
398 | 398 | ||
399 | if (write_acpi_int(asus->handle, METHOD_KBD_LIGHT_SET, kblv)) { | 399 | if (write_acpi_int(asus->handle, METHOD_KBD_LIGHT_SET, kblv)) { |
400 | pr_warning("Keyboard LED display write failed\n"); | 400 | pr_warn("Keyboard LED display write failed\n"); |
401 | return -EINVAL; | 401 | return -EINVAL; |
402 | } | 402 | } |
403 | return 0; | 403 | return 0; |
@@ -531,7 +531,7 @@ static int asus_read_brightness(struct backlight_device *bd) | |||
531 | rv = acpi_evaluate_integer(asus->handle, METHOD_BRIGHTNESS_GET, | 531 | rv = acpi_evaluate_integer(asus->handle, METHOD_BRIGHTNESS_GET, |
532 | NULL, &value); | 532 | NULL, &value); |
533 | if (ACPI_FAILURE(rv)) | 533 | if (ACPI_FAILURE(rv)) |
534 | pr_warning("Error reading brightness\n"); | 534 | pr_warn("Error reading brightness\n"); |
535 | 535 | ||
536 | return value; | 536 | return value; |
537 | } | 537 | } |
@@ -541,7 +541,7 @@ static int asus_set_brightness(struct backlight_device *bd, int value) | |||
541 | struct asus_laptop *asus = bl_get_data(bd); | 541 | struct asus_laptop *asus = bl_get_data(bd); |
542 | 542 | ||
543 | if (write_acpi_int(asus->handle, METHOD_BRIGHTNESS_SET, value)) { | 543 | if (write_acpi_int(asus->handle, METHOD_BRIGHTNESS_SET, value)) { |
544 | pr_warning("Error changing brightness\n"); | 544 | pr_warn("Error changing brightness\n"); |
545 | return -EIO; | 545 | return -EIO; |
546 | } | 546 | } |
547 | return 0; | 547 | return 0; |
@@ -730,7 +730,7 @@ static ssize_t store_ledd(struct device *dev, struct device_attribute *attr, | |||
730 | rv = parse_arg(buf, count, &value); | 730 | rv = parse_arg(buf, count, &value); |
731 | if (rv > 0) { | 731 | if (rv > 0) { |
732 | if (write_acpi_int(asus->handle, METHOD_LEDD, value)) { | 732 | if (write_acpi_int(asus->handle, METHOD_LEDD, value)) { |
733 | pr_warning("LED display write failed\n"); | 733 | pr_warn("LED display write failed\n"); |
734 | return -ENODEV; | 734 | return -ENODEV; |
735 | } | 735 | } |
736 | asus->ledd_status = (u32) value; | 736 | asus->ledd_status = (u32) value; |
@@ -752,7 +752,7 @@ static int asus_wireless_status(struct asus_laptop *asus, int mask) | |||
752 | rv = acpi_evaluate_integer(asus->handle, METHOD_WL_STATUS, | 752 | rv = acpi_evaluate_integer(asus->handle, METHOD_WL_STATUS, |
753 | NULL, &status); | 753 | NULL, &status); |
754 | if (ACPI_FAILURE(rv)) { | 754 | if (ACPI_FAILURE(rv)) { |
755 | pr_warning("Error reading Wireless status\n"); | 755 | pr_warn("Error reading Wireless status\n"); |
756 | return -EINVAL; | 756 | return -EINVAL; |
757 | } | 757 | } |
758 | return !!(status & mask); | 758 | return !!(status & mask); |
@@ -764,7 +764,7 @@ static int asus_wireless_status(struct asus_laptop *asus, int mask) | |||
764 | static int asus_wlan_set(struct asus_laptop *asus, int status) | 764 | static int asus_wlan_set(struct asus_laptop *asus, int status) |
765 | { | 765 | { |
766 | if (write_acpi_int(asus->handle, METHOD_WLAN, !!status)) { | 766 | if (write_acpi_int(asus->handle, METHOD_WLAN, !!status)) { |
767 | pr_warning("Error setting wlan status to %d", status); | 767 | pr_warn("Error setting wlan status to %d\n", status); |
768 | return -EIO; | 768 | return -EIO; |
769 | } | 769 | } |
770 | return 0; | 770 | return 0; |
@@ -792,7 +792,7 @@ static ssize_t store_wlan(struct device *dev, struct device_attribute *attr, | |||
792 | static int asus_bluetooth_set(struct asus_laptop *asus, int status) | 792 | static int asus_bluetooth_set(struct asus_laptop *asus, int status) |
793 | { | 793 | { |
794 | if (write_acpi_int(asus->handle, METHOD_BLUETOOTH, !!status)) { | 794 | if (write_acpi_int(asus->handle, METHOD_BLUETOOTH, !!status)) { |
795 | pr_warning("Error setting bluetooth status to %d", status); | 795 | pr_warn("Error setting bluetooth status to %d\n", status); |
796 | return -EIO; | 796 | return -EIO; |
797 | } | 797 | } |
798 | return 0; | 798 | return 0; |
@@ -821,7 +821,7 @@ static ssize_t store_bluetooth(struct device *dev, | |||
821 | static int asus_wimax_set(struct asus_laptop *asus, int status) | 821 | static int asus_wimax_set(struct asus_laptop *asus, int status) |
822 | { | 822 | { |
823 | if (write_acpi_int(asus->handle, METHOD_WIMAX, !!status)) { | 823 | if (write_acpi_int(asus->handle, METHOD_WIMAX, !!status)) { |
824 | pr_warning("Error setting wimax status to %d", status); | 824 | pr_warn("Error setting wimax status to %d\n", status); |
825 | return -EIO; | 825 | return -EIO; |
826 | } | 826 | } |
827 | return 0; | 827 | return 0; |
@@ -850,7 +850,7 @@ static ssize_t store_wimax(struct device *dev, | |||
850 | static int asus_wwan_set(struct asus_laptop *asus, int status) | 850 | static int asus_wwan_set(struct asus_laptop *asus, int status) |
851 | { | 851 | { |
852 | if (write_acpi_int(asus->handle, METHOD_WWAN, !!status)) { | 852 | if (write_acpi_int(asus->handle, METHOD_WWAN, !!status)) { |
853 | pr_warning("Error setting wwan status to %d", status); | 853 | pr_warn("Error setting wwan status to %d\n", status); |
854 | return -EIO; | 854 | return -EIO; |
855 | } | 855 | } |
856 | return 0; | 856 | return 0; |
@@ -880,7 +880,7 @@ static void asus_set_display(struct asus_laptop *asus, int value) | |||
880 | { | 880 | { |
881 | /* no sanity check needed for now */ | 881 | /* no sanity check needed for now */ |
882 | if (write_acpi_int(asus->handle, METHOD_SWITCH_DISPLAY, value)) | 882 | if (write_acpi_int(asus->handle, METHOD_SWITCH_DISPLAY, value)) |
883 | pr_warning("Error setting display\n"); | 883 | pr_warn("Error setting display\n"); |
884 | return; | 884 | return; |
885 | } | 885 | } |
886 | 886 | ||
@@ -909,7 +909,7 @@ static ssize_t store_disp(struct device *dev, struct device_attribute *attr, | |||
909 | static void asus_als_switch(struct asus_laptop *asus, int value) | 909 | static void asus_als_switch(struct asus_laptop *asus, int value) |
910 | { | 910 | { |
911 | if (write_acpi_int(asus->handle, METHOD_ALS_CONTROL, value)) | 911 | if (write_acpi_int(asus->handle, METHOD_ALS_CONTROL, value)) |
912 | pr_warning("Error setting light sensor switch\n"); | 912 | pr_warn("Error setting light sensor switch\n"); |
913 | asus->light_switch = value; | 913 | asus->light_switch = value; |
914 | } | 914 | } |
915 | 915 | ||
@@ -937,7 +937,7 @@ static ssize_t store_lssw(struct device *dev, struct device_attribute *attr, | |||
937 | static void asus_als_level(struct asus_laptop *asus, int value) | 937 | static void asus_als_level(struct asus_laptop *asus, int value) |
938 | { | 938 | { |
939 | if (write_acpi_int(asus->handle, METHOD_ALS_LEVEL, value)) | 939 | if (write_acpi_int(asus->handle, METHOD_ALS_LEVEL, value)) |
940 | pr_warning("Error setting light sensor level\n"); | 940 | pr_warn("Error setting light sensor level\n"); |
941 | asus->light_level = value; | 941 | asus->light_level = value; |
942 | } | 942 | } |
943 | 943 | ||
@@ -976,7 +976,7 @@ static int asus_gps_status(struct asus_laptop *asus) | |||
976 | rv = acpi_evaluate_integer(asus->handle, METHOD_GPS_STATUS, | 976 | rv = acpi_evaluate_integer(asus->handle, METHOD_GPS_STATUS, |
977 | NULL, &status); | 977 | NULL, &status); |
978 | if (ACPI_FAILURE(rv)) { | 978 | if (ACPI_FAILURE(rv)) { |
979 | pr_warning("Error reading GPS status\n"); | 979 | pr_warn("Error reading GPS status\n"); |
980 | return -ENODEV; | 980 | return -ENODEV; |
981 | } | 981 | } |
982 | return !!status; | 982 | return !!status; |
@@ -1284,7 +1284,7 @@ static int asus_laptop_get_info(struct asus_laptop *asus) | |||
1284 | */ | 1284 | */ |
1285 | status = acpi_get_table(ACPI_SIG_DSDT, 1, &asus->dsdt_info); | 1285 | status = acpi_get_table(ACPI_SIG_DSDT, 1, &asus->dsdt_info); |
1286 | if (ACPI_FAILURE(status)) | 1286 | if (ACPI_FAILURE(status)) |
1287 | pr_warning("Couldn't get the DSDT table header\n"); | 1287 | pr_warn("Couldn't get the DSDT table header\n"); |
1288 | 1288 | ||
1289 | /* We have to write 0 on init this far for all ASUS models */ | 1289 | /* We have to write 0 on init this far for all ASUS models */ |
1290 | if (write_acpi_int_ret(asus->handle, "INIT", 0, &buffer)) { | 1290 | if (write_acpi_int_ret(asus->handle, "INIT", 0, &buffer)) { |
@@ -1296,7 +1296,7 @@ static int asus_laptop_get_info(struct asus_laptop *asus) | |||
1296 | status = | 1296 | status = |
1297 | acpi_evaluate_integer(asus->handle, "BSTS", NULL, &bsts_result); | 1297 | acpi_evaluate_integer(asus->handle, "BSTS", NULL, &bsts_result); |
1298 | if (ACPI_FAILURE(status)) | 1298 | if (ACPI_FAILURE(status)) |
1299 | pr_warning("Error calling BSTS\n"); | 1299 | pr_warn("Error calling BSTS\n"); |
1300 | else if (bsts_result) | 1300 | else if (bsts_result) |
1301 | pr_notice("BSTS called, 0x%02x returned\n", | 1301 | pr_notice("BSTS called, 0x%02x returned\n", |
1302 | (uint) bsts_result); | 1302 | (uint) bsts_result); |
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 832a3fd7c1c8..00460cb9587b 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c | |||
@@ -425,7 +425,7 @@ static void asus_rfkill_hotplug(struct asus_wmi *asus) | |||
425 | if (asus->hotplug_slot) { | 425 | if (asus->hotplug_slot) { |
426 | bus = pci_find_bus(0, 1); | 426 | bus = pci_find_bus(0, 1); |
427 | if (!bus) { | 427 | if (!bus) { |
428 | pr_warning("Unable to find PCI bus 1?\n"); | 428 | pr_warn("Unable to find PCI bus 1?\n"); |
429 | goto out_unlock; | 429 | goto out_unlock; |
430 | } | 430 | } |
431 | 431 | ||
@@ -436,12 +436,12 @@ static void asus_rfkill_hotplug(struct asus_wmi *asus) | |||
436 | absent = (l == 0xffffffff); | 436 | absent = (l == 0xffffffff); |
437 | 437 | ||
438 | if (blocked != absent) { | 438 | if (blocked != absent) { |
439 | pr_warning("BIOS says wireless lan is %s, " | 439 | pr_warn("BIOS says wireless lan is %s, " |
440 | "but the pci device is %s\n", | 440 | "but the pci device is %s\n", |
441 | blocked ? "blocked" : "unblocked", | 441 | blocked ? "blocked" : "unblocked", |
442 | absent ? "absent" : "present"); | 442 | absent ? "absent" : "present"); |
443 | pr_warning("skipped wireless hotplug as probably " | 443 | pr_warn("skipped wireless hotplug as probably " |
444 | "inappropriate for this model\n"); | 444 | "inappropriate for this model\n"); |
445 | goto out_unlock; | 445 | goto out_unlock; |
446 | } | 446 | } |
447 | 447 | ||
@@ -500,7 +500,7 @@ static int asus_register_rfkill_notifier(struct asus_wmi *asus, char *node) | |||
500 | ACPI_SYSTEM_NOTIFY, | 500 | ACPI_SYSTEM_NOTIFY, |
501 | asus_rfkill_notify, asus); | 501 | asus_rfkill_notify, asus); |
502 | if (ACPI_FAILURE(status)) | 502 | if (ACPI_FAILURE(status)) |
503 | pr_warning("Failed to register notify on %s\n", node); | 503 | pr_warn("Failed to register notify on %s\n", node); |
504 | } else | 504 | } else |
505 | return -ENODEV; | 505 | return -ENODEV; |
506 | 506 | ||
@@ -1223,7 +1223,7 @@ static int asus_wmi_sysfs_init(struct platform_device *device) | |||
1223 | /* | 1223 | /* |
1224 | * Platform device | 1224 | * Platform device |
1225 | */ | 1225 | */ |
1226 | static int __init asus_wmi_platform_init(struct asus_wmi *asus) | 1226 | static int asus_wmi_platform_init(struct asus_wmi *asus) |
1227 | { | 1227 | { |
1228 | int rv; | 1228 | int rv; |
1229 | 1229 | ||
@@ -1583,12 +1583,12 @@ static int asus_wmi_probe(struct platform_device *pdev) | |||
1583 | int ret; | 1583 | int ret; |
1584 | 1584 | ||
1585 | if (!wmi_has_guid(ASUS_WMI_MGMT_GUID)) { | 1585 | if (!wmi_has_guid(ASUS_WMI_MGMT_GUID)) { |
1586 | pr_warning("Management GUID not found\n"); | 1586 | pr_warn("Management GUID not found\n"); |
1587 | return -ENODEV; | 1587 | return -ENODEV; |
1588 | } | 1588 | } |
1589 | 1589 | ||
1590 | if (wdrv->event_guid && !wmi_has_guid(wdrv->event_guid)) { | 1590 | if (wdrv->event_guid && !wmi_has_guid(wdrv->event_guid)) { |
1591 | pr_warning("Event GUID not found\n"); | 1591 | pr_warn("Event GUID not found\n"); |
1592 | return -ENODEV; | 1592 | return -ENODEV; |
1593 | } | 1593 | } |
1594 | 1594 | ||
diff --git a/drivers/platform/x86/asus_acpi.c b/drivers/platform/x86/asus_acpi.c index f503607c0645..d9312b3073e5 100644 --- a/drivers/platform/x86/asus_acpi.c +++ b/drivers/platform/x86/asus_acpi.c | |||
@@ -30,6 +30,8 @@ | |||
30 | * | 30 | * |
31 | */ | 31 | */ |
32 | 32 | ||
33 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
34 | |||
33 | #include <linux/kernel.h> | 35 | #include <linux/kernel.h> |
34 | #include <linux/module.h> | 36 | #include <linux/module.h> |
35 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
@@ -581,8 +583,7 @@ static int read_led(const char *ledname, int ledmask) | |||
581 | if (read_acpi_int(NULL, ledname, &led_status)) | 583 | if (read_acpi_int(NULL, ledname, &led_status)) |
582 | return led_status; | 584 | return led_status; |
583 | else | 585 | else |
584 | printk(KERN_WARNING "Asus ACPI: Error reading LED " | 586 | pr_warn("Error reading LED status\n"); |
585 | "status\n"); | ||
586 | } | 587 | } |
587 | return (hotk->status & ledmask) ? 1 : 0; | 588 | return (hotk->status & ledmask) ? 1 : 0; |
588 | } | 589 | } |
@@ -621,8 +622,7 @@ write_led(const char __user *buffer, unsigned long count, | |||
621 | led_out = !led_out; | 622 | led_out = !led_out; |
622 | 623 | ||
623 | if (!write_acpi_int(hotk->handle, ledname, led_out, NULL)) | 624 | if (!write_acpi_int(hotk->handle, ledname, led_out, NULL)) |
624 | printk(KERN_WARNING "Asus ACPI: LED (%s) write failed\n", | 625 | pr_warn("LED (%s) write failed\n", ledname); |
625 | ledname); | ||
626 | 626 | ||
627 | return rv; | 627 | return rv; |
628 | } | 628 | } |
@@ -679,8 +679,7 @@ static ssize_t ledd_proc_write(struct file *file, const char __user *buffer, | |||
679 | if (rv > 0) { | 679 | if (rv > 0) { |
680 | if (!write_acpi_int | 680 | if (!write_acpi_int |
681 | (hotk->handle, hotk->methods->mt_ledd, value, NULL)) | 681 | (hotk->handle, hotk->methods->mt_ledd, value, NULL)) |
682 | printk(KERN_WARNING | 682 | pr_warn("LED display write failed\n"); |
683 | "Asus ACPI: LED display write failed\n"); | ||
684 | else | 683 | else |
685 | hotk->ledd_status = (u32) value; | 684 | hotk->ledd_status = (u32) value; |
686 | } | 685 | } |
@@ -838,8 +837,7 @@ static int get_lcd_state(void) | |||
838 | } else { | 837 | } else { |
839 | /* We don't have to check anything if we are here */ | 838 | /* We don't have to check anything if we are here */ |
840 | if (!read_acpi_int(NULL, hotk->methods->lcd_status, &lcd)) | 839 | if (!read_acpi_int(NULL, hotk->methods->lcd_status, &lcd)) |
841 | printk(KERN_WARNING | 840 | pr_warn("Error reading LCD status\n"); |
842 | "Asus ACPI: Error reading LCD status\n"); | ||
843 | 841 | ||
844 | if (hotk->model == L2D) | 842 | if (hotk->model == L2D) |
845 | lcd = ~lcd; | 843 | lcd = ~lcd; |
@@ -871,7 +869,7 @@ static int set_lcd_state(int value) | |||
871 | the exact behaviour is simulated here */ | 869 | the exact behaviour is simulated here */ |
872 | } | 870 | } |
873 | if (ACPI_FAILURE(status)) | 871 | if (ACPI_FAILURE(status)) |
874 | printk(KERN_WARNING "Asus ACPI: Error switching LCD\n"); | 872 | pr_warn("Error switching LCD\n"); |
875 | } | 873 | } |
876 | return 0; | 874 | return 0; |
877 | 875 | ||
@@ -915,13 +913,11 @@ static int read_brightness(struct backlight_device *bd) | |||
915 | if (hotk->methods->brightness_get) { /* SPLV/GPLV laptop */ | 913 | if (hotk->methods->brightness_get) { /* SPLV/GPLV laptop */ |
916 | if (!read_acpi_int(hotk->handle, hotk->methods->brightness_get, | 914 | if (!read_acpi_int(hotk->handle, hotk->methods->brightness_get, |
917 | &value)) | 915 | &value)) |
918 | printk(KERN_WARNING | 916 | pr_warn("Error reading brightness\n"); |
919 | "Asus ACPI: Error reading brightness\n"); | ||
920 | } else if (hotk->methods->brightness_status) { /* For D1 for example */ | 917 | } else if (hotk->methods->brightness_status) { /* For D1 for example */ |
921 | if (!read_acpi_int(NULL, hotk->methods->brightness_status, | 918 | if (!read_acpi_int(NULL, hotk->methods->brightness_status, |
922 | &value)) | 919 | &value)) |
923 | printk(KERN_WARNING | 920 | pr_warn("Error reading brightness\n"); |
924 | "Asus ACPI: Error reading brightness\n"); | ||
925 | } else /* No GPLV method */ | 921 | } else /* No GPLV method */ |
926 | value = hotk->brightness; | 922 | value = hotk->brightness; |
927 | return value; | 923 | return value; |
@@ -939,8 +935,7 @@ static int set_brightness(int value) | |||
939 | if (hotk->methods->brightness_set) { | 935 | if (hotk->methods->brightness_set) { |
940 | if (!write_acpi_int(hotk->handle, hotk->methods->brightness_set, | 936 | if (!write_acpi_int(hotk->handle, hotk->methods->brightness_set, |
941 | value, NULL)) { | 937 | value, NULL)) { |
942 | printk(KERN_WARNING | 938 | pr_warn("Error changing brightness\n"); |
943 | "Asus ACPI: Error changing brightness\n"); | ||
944 | ret = -EIO; | 939 | ret = -EIO; |
945 | } | 940 | } |
946 | goto out; | 941 | goto out; |
@@ -955,8 +950,7 @@ static int set_brightness(int value) | |||
955 | NULL, NULL); | 950 | NULL, NULL); |
956 | (value > 0) ? value-- : value++; | 951 | (value > 0) ? value-- : value++; |
957 | if (ACPI_FAILURE(status)) { | 952 | if (ACPI_FAILURE(status)) { |
958 | printk(KERN_WARNING | 953 | pr_warn("Error changing brightness\n"); |
959 | "Asus ACPI: Error changing brightness\n"); | ||
960 | ret = -EIO; | 954 | ret = -EIO; |
961 | } | 955 | } |
962 | } | 956 | } |
@@ -1008,7 +1002,7 @@ static void set_display(int value) | |||
1008 | /* no sanity check needed for now */ | 1002 | /* no sanity check needed for now */ |
1009 | if (!write_acpi_int(hotk->handle, hotk->methods->display_set, | 1003 | if (!write_acpi_int(hotk->handle, hotk->methods->display_set, |
1010 | value, NULL)) | 1004 | value, NULL)) |
1011 | printk(KERN_WARNING "Asus ACPI: Error setting display\n"); | 1005 | pr_warn("Error setting display\n"); |
1012 | return; | 1006 | return; |
1013 | } | 1007 | } |
1014 | 1008 | ||
@@ -1021,8 +1015,7 @@ static int disp_proc_show(struct seq_file *m, void *v) | |||
1021 | int value = 0; | 1015 | int value = 0; |
1022 | 1016 | ||
1023 | if (!read_acpi_int(hotk->handle, hotk->methods->display_get, &value)) | 1017 | if (!read_acpi_int(hotk->handle, hotk->methods->display_get, &value)) |
1024 | printk(KERN_WARNING | 1018 | pr_warn("Error reading display status\n"); |
1025 | "Asus ACPI: Error reading display status\n"); | ||
1026 | value &= 0x07; /* needed for some models, shouldn't hurt others */ | 1019 | value &= 0x07; /* needed for some models, shouldn't hurt others */ |
1027 | seq_printf(m, "%d\n", value); | 1020 | seq_printf(m, "%d\n", value); |
1028 | return 0; | 1021 | return 0; |
@@ -1068,7 +1061,7 @@ asus_proc_add(char *name, const struct file_operations *proc_fops, mode_t mode, | |||
1068 | proc = proc_create_data(name, mode, acpi_device_dir(device), | 1061 | proc = proc_create_data(name, mode, acpi_device_dir(device), |
1069 | proc_fops, acpi_driver_data(device)); | 1062 | proc_fops, acpi_driver_data(device)); |
1070 | if (!proc) { | 1063 | if (!proc) { |
1071 | printk(KERN_WARNING " Unable to create %s fs entry\n", name); | 1064 | pr_warn(" Unable to create %s fs entry\n", name); |
1072 | return -1; | 1065 | return -1; |
1073 | } | 1066 | } |
1074 | proc->uid = asus_uid; | 1067 | proc->uid = asus_uid; |
@@ -1085,8 +1078,8 @@ static int asus_hotk_add_fs(struct acpi_device *device) | |||
1085 | mode = S_IFREG | S_IRUGO | S_IWUSR | S_IWGRP; | 1078 | mode = S_IFREG | S_IRUGO | S_IWUSR | S_IWGRP; |
1086 | } else { | 1079 | } else { |
1087 | mode = S_IFREG | S_IRUSR | S_IRGRP | S_IWUSR | S_IWGRP; | 1080 | mode = S_IFREG | S_IRUSR | S_IRGRP | S_IWUSR | S_IWGRP; |
1088 | printk(KERN_WARNING " asus_uid and asus_gid parameters are " | 1081 | pr_warn(" asus_uid and asus_gid parameters are " |
1089 | "deprecated, use chown and chmod instead!\n"); | 1082 | "deprecated, use chown and chmod instead!\n"); |
1090 | } | 1083 | } |
1091 | 1084 | ||
1092 | acpi_device_dir(device) = asus_proc_dir; | 1085 | acpi_device_dir(device) = asus_proc_dir; |
@@ -1099,8 +1092,7 @@ static int asus_hotk_add_fs(struct acpi_device *device) | |||
1099 | proc->uid = asus_uid; | 1092 | proc->uid = asus_uid; |
1100 | proc->gid = asus_gid; | 1093 | proc->gid = asus_gid; |
1101 | } else { | 1094 | } else { |
1102 | printk(KERN_WARNING " Unable to create " PROC_INFO | 1095 | pr_warn(" Unable to create " PROC_INFO " fs entry\n"); |
1103 | " fs entry\n"); | ||
1104 | } | 1096 | } |
1105 | 1097 | ||
1106 | if (hotk->methods->mt_wled) { | 1098 | if (hotk->methods->mt_wled) { |
@@ -1283,20 +1275,19 @@ static int asus_hotk_get_info(void) | |||
1283 | */ | 1275 | */ |
1284 | status = acpi_get_table(ACPI_SIG_DSDT, 1, &asus_info); | 1276 | status = acpi_get_table(ACPI_SIG_DSDT, 1, &asus_info); |
1285 | if (ACPI_FAILURE(status)) | 1277 | if (ACPI_FAILURE(status)) |
1286 | printk(KERN_WARNING " Couldn't get the DSDT table header\n"); | 1278 | pr_warn(" Couldn't get the DSDT table header\n"); |
1287 | 1279 | ||
1288 | /* We have to write 0 on init this far for all ASUS models */ | 1280 | /* We have to write 0 on init this far for all ASUS models */ |
1289 | if (!write_acpi_int(hotk->handle, "INIT", 0, &buffer)) { | 1281 | if (!write_acpi_int(hotk->handle, "INIT", 0, &buffer)) { |
1290 | printk(KERN_ERR " Hotkey initialization failed\n"); | 1282 | pr_err(" Hotkey initialization failed\n"); |
1291 | return -ENODEV; | 1283 | return -ENODEV; |
1292 | } | 1284 | } |
1293 | 1285 | ||
1294 | /* This needs to be called for some laptops to init properly */ | 1286 | /* This needs to be called for some laptops to init properly */ |
1295 | if (!read_acpi_int(hotk->handle, "BSTS", &bsts_result)) | 1287 | if (!read_acpi_int(hotk->handle, "BSTS", &bsts_result)) |
1296 | printk(KERN_WARNING " Error calling BSTS\n"); | 1288 | pr_warn(" Error calling BSTS\n"); |
1297 | else if (bsts_result) | 1289 | else if (bsts_result) |
1298 | printk(KERN_NOTICE " BSTS called, 0x%02x returned\n", | 1290 | pr_notice(" BSTS called, 0x%02x returned\n", bsts_result); |
1299 | bsts_result); | ||
1300 | 1291 | ||
1301 | /* | 1292 | /* |
1302 | * Try to match the object returned by INIT to the specific model. | 1293 | * Try to match the object returned by INIT to the specific model. |
@@ -1324,23 +1315,21 @@ static int asus_hotk_get_info(void) | |||
1324 | if (asus_info && | 1315 | if (asus_info && |
1325 | strncmp(asus_info->oem_table_id, "ODEM", 4) == 0) { | 1316 | strncmp(asus_info->oem_table_id, "ODEM", 4) == 0) { |
1326 | hotk->model = P30; | 1317 | hotk->model = P30; |
1327 | printk(KERN_NOTICE | 1318 | pr_notice(" Samsung P30 detected, supported\n"); |
1328 | " Samsung P30 detected, supported\n"); | ||
1329 | hotk->methods = &model_conf[hotk->model]; | 1319 | hotk->methods = &model_conf[hotk->model]; |
1330 | kfree(model); | 1320 | kfree(model); |
1331 | return 0; | 1321 | return 0; |
1332 | } else { | 1322 | } else { |
1333 | hotk->model = M2E; | 1323 | hotk->model = M2E; |
1334 | printk(KERN_NOTICE " unsupported model %s, trying " | 1324 | pr_notice(" unsupported model %s, trying default values\n", |
1335 | "default values\n", string); | 1325 | string); |
1336 | printk(KERN_NOTICE | 1326 | pr_notice(" send /proc/acpi/dsdt to the developers\n"); |
1337 | " send /proc/acpi/dsdt to the developers\n"); | ||
1338 | kfree(model); | 1327 | kfree(model); |
1339 | return -ENODEV; | 1328 | return -ENODEV; |
1340 | } | 1329 | } |
1341 | } | 1330 | } |
1342 | hotk->methods = &model_conf[hotk->model]; | 1331 | hotk->methods = &model_conf[hotk->model]; |
1343 | printk(KERN_NOTICE " %s model detected, supported\n", string); | 1332 | pr_notice(" %s model detected, supported\n", string); |
1344 | 1333 | ||
1345 | /* Sort of per-model blacklist */ | 1334 | /* Sort of per-model blacklist */ |
1346 | if (strncmp(string, "L2B", 3) == 0) | 1335 | if (strncmp(string, "L2B", 3) == 0) |
@@ -1385,7 +1374,7 @@ static int asus_hotk_check(void) | |||
1385 | if (hotk->device->status.present) { | 1374 | if (hotk->device->status.present) { |
1386 | result = asus_hotk_get_info(); | 1375 | result = asus_hotk_get_info(); |
1387 | } else { | 1376 | } else { |
1388 | printk(KERN_ERR " Hotkey device not present, aborting\n"); | 1377 | pr_err(" Hotkey device not present, aborting\n"); |
1389 | return -EINVAL; | 1378 | return -EINVAL; |
1390 | } | 1379 | } |
1391 | 1380 | ||
@@ -1399,8 +1388,7 @@ static int asus_hotk_add(struct acpi_device *device) | |||
1399 | acpi_status status = AE_OK; | 1388 | acpi_status status = AE_OK; |
1400 | int result; | 1389 | int result; |
1401 | 1390 | ||
1402 | printk(KERN_NOTICE "Asus Laptop ACPI Extras version %s\n", | 1391 | pr_notice("Asus Laptop ACPI Extras version %s\n", ASUS_ACPI_VERSION); |
1403 | ASUS_ACPI_VERSION); | ||
1404 | 1392 | ||
1405 | hotk = kzalloc(sizeof(struct asus_hotk), GFP_KERNEL); | 1393 | hotk = kzalloc(sizeof(struct asus_hotk), GFP_KERNEL); |
1406 | if (!hotk) | 1394 | if (!hotk) |
@@ -1428,15 +1416,14 @@ static int asus_hotk_add(struct acpi_device *device) | |||
1428 | acpi_evaluate_object(NULL, hotk->methods->brightness_down, | 1416 | acpi_evaluate_object(NULL, hotk->methods->brightness_down, |
1429 | NULL, NULL); | 1417 | NULL, NULL); |
1430 | if (ACPI_FAILURE(status)) | 1418 | if (ACPI_FAILURE(status)) |
1431 | printk(KERN_WARNING " Error changing brightness\n"); | 1419 | pr_warn(" Error changing brightness\n"); |
1432 | else { | 1420 | else { |
1433 | status = | 1421 | status = |
1434 | acpi_evaluate_object(NULL, | 1422 | acpi_evaluate_object(NULL, |
1435 | hotk->methods->brightness_up, | 1423 | hotk->methods->brightness_up, |
1436 | NULL, NULL); | 1424 | NULL, NULL); |
1437 | if (ACPI_FAILURE(status)) | 1425 | if (ACPI_FAILURE(status)) |
1438 | printk(KERN_WARNING " Strange, error changing" | 1426 | pr_warn(" Strange, error changing brightness\n"); |
1439 | " brightness\n"); | ||
1440 | } | 1427 | } |
1441 | } | 1428 | } |
1442 | 1429 | ||
@@ -1488,7 +1475,7 @@ static int __init asus_acpi_init(void) | |||
1488 | 1475 | ||
1489 | asus_proc_dir = proc_mkdir(PROC_ASUS, acpi_root_dir); | 1476 | asus_proc_dir = proc_mkdir(PROC_ASUS, acpi_root_dir); |
1490 | if (!asus_proc_dir) { | 1477 | if (!asus_proc_dir) { |
1491 | printk(KERN_ERR "Asus ACPI: Unable to create /proc entry\n"); | 1478 | pr_err("Unable to create /proc entry\n"); |
1492 | acpi_bus_unregister_driver(&asus_hotk_driver); | 1479 | acpi_bus_unregister_driver(&asus_hotk_driver); |
1493 | return -ENODEV; | 1480 | return -ENODEV; |
1494 | } | 1481 | } |
@@ -1513,7 +1500,7 @@ static int __init asus_acpi_init(void) | |||
1513 | &asus_backlight_data, | 1500 | &asus_backlight_data, |
1514 | &props); | 1501 | &props); |
1515 | if (IS_ERR(asus_backlight_device)) { | 1502 | if (IS_ERR(asus_backlight_device)) { |
1516 | printk(KERN_ERR "Could not register asus backlight device\n"); | 1503 | pr_err("Could not register asus backlight device\n"); |
1517 | asus_backlight_device = NULL; | 1504 | asus_backlight_device = NULL; |
1518 | asus_acpi_exit(); | 1505 | asus_acpi_exit(); |
1519 | return -ENODEV; | 1506 | return -ENODEV; |
diff --git a/drivers/platform/x86/compal-laptop.c b/drivers/platform/x86/compal-laptop.c index c16a27641ced..3f204fde1b02 100644 --- a/drivers/platform/x86/compal-laptop.c +++ b/drivers/platform/x86/compal-laptop.c | |||
@@ -68,6 +68,8 @@ | |||
68 | * only enabled on a JHL90 board until it is verified that they work on the | 68 | * only enabled on a JHL90 board until it is verified that they work on the |
69 | * other boards too. See the extra_features variable. */ | 69 | * other boards too. See the extra_features variable. */ |
70 | 70 | ||
71 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
72 | |||
71 | #include <linux/module.h> | 73 | #include <linux/module.h> |
72 | #include <linux/kernel.h> | 74 | #include <linux/kernel.h> |
73 | #include <linux/init.h> | 75 | #include <linux/init.h> |
@@ -200,8 +202,8 @@ static bool extra_features; | |||
200 | * watching the output of address 0x4F (do an ec_transaction writing 0x33 | 202 | * watching the output of address 0x4F (do an ec_transaction writing 0x33 |
201 | * into 0x4F and read a few bytes from the output, like so: | 203 | * into 0x4F and read a few bytes from the output, like so: |
202 | * u8 writeData = 0x33; | 204 | * u8 writeData = 0x33; |
203 | * ec_transaction(0x4F, &writeData, 1, buffer, 32, 0); | 205 | * ec_transaction(0x4F, &writeData, 1, buffer, 32); |
204 | * That address is labelled "fan1 table information" in the service manual. | 206 | * That address is labeled "fan1 table information" in the service manual. |
205 | * It should be clear which value in 'buffer' changes). This seems to be | 207 | * It should be clear which value in 'buffer' changes). This seems to be |
206 | * related to fan speed. It isn't a proper 'realtime' fan speed value | 208 | * related to fan speed. It isn't a proper 'realtime' fan speed value |
207 | * though, because physically stopping or speeding up the fan doesn't | 209 | * though, because physically stopping or speeding up the fan doesn't |
@@ -286,7 +288,7 @@ static int get_backlight_level(void) | |||
286 | static void set_backlight_state(bool on) | 288 | static void set_backlight_state(bool on) |
287 | { | 289 | { |
288 | u8 data = on ? BACKLIGHT_STATE_ON_DATA : BACKLIGHT_STATE_OFF_DATA; | 290 | u8 data = on ? BACKLIGHT_STATE_ON_DATA : BACKLIGHT_STATE_OFF_DATA; |
289 | ec_transaction(BACKLIGHT_STATE_ADDR, &data, 1, NULL, 0, 0); | 291 | ec_transaction(BACKLIGHT_STATE_ADDR, &data, 1, NULL, 0); |
290 | } | 292 | } |
291 | 293 | ||
292 | 294 | ||
@@ -294,24 +296,24 @@ static void set_backlight_state(bool on) | |||
294 | static void pwm_enable_control(void) | 296 | static void pwm_enable_control(void) |
295 | { | 297 | { |
296 | unsigned char writeData = PWM_ENABLE_DATA; | 298 | unsigned char writeData = PWM_ENABLE_DATA; |
297 | ec_transaction(PWM_ENABLE_ADDR, &writeData, 1, NULL, 0, 0); | 299 | ec_transaction(PWM_ENABLE_ADDR, &writeData, 1, NULL, 0); |
298 | } | 300 | } |
299 | 301 | ||
300 | static void pwm_disable_control(void) | 302 | static void pwm_disable_control(void) |
301 | { | 303 | { |
302 | unsigned char writeData = PWM_DISABLE_DATA; | 304 | unsigned char writeData = PWM_DISABLE_DATA; |
303 | ec_transaction(PWM_DISABLE_ADDR, &writeData, 1, NULL, 0, 0); | 305 | ec_transaction(PWM_DISABLE_ADDR, &writeData, 1, NULL, 0); |
304 | } | 306 | } |
305 | 307 | ||
306 | static void set_pwm(int pwm) | 308 | static void set_pwm(int pwm) |
307 | { | 309 | { |
308 | ec_transaction(PWM_ADDRESS, &pwm_lookup_table[pwm], 1, NULL, 0, 0); | 310 | ec_transaction(PWM_ADDRESS, &pwm_lookup_table[pwm], 1, NULL, 0); |
309 | } | 311 | } |
310 | 312 | ||
311 | static int get_fan_rpm(void) | 313 | static int get_fan_rpm(void) |
312 | { | 314 | { |
313 | u8 value, data = FAN_DATA; | 315 | u8 value, data = FAN_DATA; |
314 | ec_transaction(FAN_ADDRESS, &data, 1, &value, 1, 0); | 316 | ec_transaction(FAN_ADDRESS, &data, 1, &value, 1); |
315 | return 100 * (int)value; | 317 | return 100 * (int)value; |
316 | } | 318 | } |
317 | 319 | ||
@@ -760,16 +762,14 @@ static struct rfkill *bt_rfkill; | |||
760 | 762 | ||
761 | static int dmi_check_cb(const struct dmi_system_id *id) | 763 | static int dmi_check_cb(const struct dmi_system_id *id) |
762 | { | 764 | { |
763 | printk(KERN_INFO DRIVER_NAME": Identified laptop model '%s'\n", | 765 | pr_info("Identified laptop model '%s'\n", id->ident); |
764 | id->ident); | ||
765 | extra_features = false; | 766 | extra_features = false; |
766 | return 1; | 767 | return 1; |
767 | } | 768 | } |
768 | 769 | ||
769 | static int dmi_check_cb_extra(const struct dmi_system_id *id) | 770 | static int dmi_check_cb_extra(const struct dmi_system_id *id) |
770 | { | 771 | { |
771 | printk(KERN_INFO DRIVER_NAME": Identified laptop model '%s', " | 772 | pr_info("Identified laptop model '%s', enabling extra features\n", |
772 | "enabling extra features\n", | ||
773 | id->ident); | 773 | id->ident); |
774 | extra_features = true; | 774 | extra_features = true; |
775 | return 1; | 775 | return 1; |
@@ -956,14 +956,12 @@ static int __init compal_init(void) | |||
956 | int ret; | 956 | int ret; |
957 | 957 | ||
958 | if (acpi_disabled) { | 958 | if (acpi_disabled) { |
959 | printk(KERN_ERR DRIVER_NAME": ACPI needs to be enabled for " | 959 | pr_err("ACPI needs to be enabled for this driver to work!\n"); |
960 | "this driver to work!\n"); | ||
961 | return -ENODEV; | 960 | return -ENODEV; |
962 | } | 961 | } |
963 | 962 | ||
964 | if (!force && !dmi_check_system(compal_dmi_table)) { | 963 | if (!force && !dmi_check_system(compal_dmi_table)) { |
965 | printk(KERN_ERR DRIVER_NAME": Motherboard not recognized (You " | 964 | pr_err("Motherboard not recognized (You could try the module's force-parameter)\n"); |
966 | "could try the module's force-parameter)"); | ||
967 | return -ENODEV; | 965 | return -ENODEV; |
968 | } | 966 | } |
969 | 967 | ||
@@ -998,8 +996,7 @@ static int __init compal_init(void) | |||
998 | if (ret) | 996 | if (ret) |
999 | goto err_rfkill; | 997 | goto err_rfkill; |
1000 | 998 | ||
1001 | printk(KERN_INFO DRIVER_NAME": Driver "DRIVER_VERSION | 999 | pr_info("Driver " DRIVER_VERSION " successfully loaded\n"); |
1002 | " successfully loaded\n"); | ||
1003 | return 0; | 1000 | return 0; |
1004 | 1001 | ||
1005 | err_rfkill: | 1002 | err_rfkill: |
@@ -1064,7 +1061,7 @@ static void __exit compal_cleanup(void) | |||
1064 | rfkill_destroy(wifi_rfkill); | 1061 | rfkill_destroy(wifi_rfkill); |
1065 | rfkill_destroy(bt_rfkill); | 1062 | rfkill_destroy(bt_rfkill); |
1066 | 1063 | ||
1067 | printk(KERN_INFO DRIVER_NAME": Driver unloaded\n"); | 1064 | pr_info("Driver unloaded\n"); |
1068 | } | 1065 | } |
1069 | 1066 | ||
1070 | static int __devexit compal_remove(struct platform_device *pdev) | 1067 | static int __devexit compal_remove(struct platform_device *pdev) |
@@ -1074,8 +1071,7 @@ static int __devexit compal_remove(struct platform_device *pdev) | |||
1074 | if (!extra_features) | 1071 | if (!extra_features) |
1075 | return 0; | 1072 | return 0; |
1076 | 1073 | ||
1077 | printk(KERN_INFO DRIVER_NAME": Unloading: resetting fan control " | 1074 | pr_info("Unloading: resetting fan control to motherboard\n"); |
1078 | "to motherboard\n"); | ||
1079 | pwm_disable_control(); | 1075 | pwm_disable_control(); |
1080 | 1076 | ||
1081 | data = platform_get_drvdata(pdev); | 1077 | data = platform_get_drvdata(pdev); |
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index de301aa8e5c3..d3841de6a8cf 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c | |||
@@ -11,6 +11,8 @@ | |||
11 | * published by the Free Software Foundation. | 11 | * published by the Free Software Foundation. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
15 | |||
14 | #include <linux/module.h> | 16 | #include <linux/module.h> |
15 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
16 | #include <linux/init.h> | 18 | #include <linux/init.h> |
@@ -434,8 +436,7 @@ static int __init dell_setup_rfkill(void) | |||
434 | int ret; | 436 | int ret; |
435 | 437 | ||
436 | if (dmi_check_system(dell_blacklist)) { | 438 | if (dmi_check_system(dell_blacklist)) { |
437 | printk(KERN_INFO "dell-laptop: Blacklisted hardware detected - " | 439 | pr_info("Blacklisted hardware detected - not enabling rfkill\n"); |
438 | "not enabling rfkill\n"); | ||
439 | return 0; | 440 | return 0; |
440 | } | 441 | } |
441 | 442 | ||
@@ -606,7 +607,7 @@ static int __init dell_init(void) | |||
606 | dmi_walk(find_tokens, NULL); | 607 | dmi_walk(find_tokens, NULL); |
607 | 608 | ||
608 | if (!da_tokens) { | 609 | if (!da_tokens) { |
609 | printk(KERN_INFO "dell-laptop: Unable to find dmi tokens\n"); | 610 | pr_info("Unable to find dmi tokens\n"); |
610 | return -ENODEV; | 611 | return -ENODEV; |
611 | } | 612 | } |
612 | 613 | ||
@@ -636,14 +637,13 @@ static int __init dell_init(void) | |||
636 | ret = dell_setup_rfkill(); | 637 | ret = dell_setup_rfkill(); |
637 | 638 | ||
638 | if (ret) { | 639 | if (ret) { |
639 | printk(KERN_WARNING "dell-laptop: Unable to setup rfkill\n"); | 640 | pr_warn("Unable to setup rfkill\n"); |
640 | goto fail_rfkill; | 641 | goto fail_rfkill; |
641 | } | 642 | } |
642 | 643 | ||
643 | ret = i8042_install_filter(dell_laptop_i8042_filter); | 644 | ret = i8042_install_filter(dell_laptop_i8042_filter); |
644 | if (ret) { | 645 | if (ret) { |
645 | printk(KERN_WARNING | 646 | pr_warn("Unable to install key filter\n"); |
646 | "dell-laptop: Unable to install key filter\n"); | ||
647 | goto fail_filter; | 647 | goto fail_filter; |
648 | } | 648 | } |
649 | 649 | ||
diff --git a/drivers/platform/x86/dell-wmi-aio.c b/drivers/platform/x86/dell-wmi-aio.c index 0ed84573ae1f..3f945457f71c 100644 --- a/drivers/platform/x86/dell-wmi-aio.c +++ b/drivers/platform/x86/dell-wmi-aio.c | |||
@@ -15,6 +15,7 @@ | |||
15 | * along with this program; if not, write to the Free Software | 15 | * along with this program; if not, write to the Free Software |
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
17 | */ | 17 | */ |
18 | |||
18 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 19 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
19 | 20 | ||
20 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
@@ -138,7 +139,7 @@ static int __init dell_wmi_aio_init(void) | |||
138 | 139 | ||
139 | guid = dell_wmi_aio_find(); | 140 | guid = dell_wmi_aio_find(); |
140 | if (!guid) { | 141 | if (!guid) { |
141 | pr_warning("No known WMI GUID found\n"); | 142 | pr_warn("No known WMI GUID found\n"); |
142 | return -ENXIO; | 143 | return -ENXIO; |
143 | } | 144 | } |
144 | 145 | ||
diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c index 77f1d55414c6..ce790827e199 100644 --- a/drivers/platform/x86/dell-wmi.c +++ b/drivers/platform/x86/dell-wmi.c | |||
@@ -23,6 +23,8 @@ | |||
23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
24 | */ | 24 | */ |
25 | 25 | ||
26 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
27 | |||
26 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
27 | #include <linux/module.h> | 29 | #include <linux/module.h> |
28 | #include <linux/init.h> | 30 | #include <linux/init.h> |
@@ -141,7 +143,7 @@ static void dell_wmi_notify(u32 value, void *context) | |||
141 | 143 | ||
142 | status = wmi_get_event_data(value, &response); | 144 | status = wmi_get_event_data(value, &response); |
143 | if (status != AE_OK) { | 145 | if (status != AE_OK) { |
144 | printk(KERN_INFO "dell-wmi: bad event status 0x%x\n", status); | 146 | pr_info("bad event status 0x%x\n", status); |
145 | return; | 147 | return; |
146 | } | 148 | } |
147 | 149 | ||
@@ -153,8 +155,8 @@ static void dell_wmi_notify(u32 value, void *context) | |||
153 | u16 *buffer_entry = (u16 *)obj->buffer.pointer; | 155 | u16 *buffer_entry = (u16 *)obj->buffer.pointer; |
154 | 156 | ||
155 | if (dell_new_hk_type && (buffer_entry[1] != 0x10)) { | 157 | if (dell_new_hk_type && (buffer_entry[1] != 0x10)) { |
156 | printk(KERN_INFO "dell-wmi: Received unknown WMI event" | 158 | pr_info("Received unknown WMI event (0x%x)\n", |
157 | " (0x%x)\n", buffer_entry[1]); | 159 | buffer_entry[1]); |
158 | kfree(obj); | 160 | kfree(obj); |
159 | return; | 161 | return; |
160 | } | 162 | } |
@@ -167,8 +169,7 @@ static void dell_wmi_notify(u32 value, void *context) | |||
167 | key = sparse_keymap_entry_from_scancode(dell_wmi_input_dev, | 169 | key = sparse_keymap_entry_from_scancode(dell_wmi_input_dev, |
168 | reported_key); | 170 | reported_key); |
169 | if (!key) { | 171 | if (!key) { |
170 | printk(KERN_INFO "dell-wmi: Unknown key %x pressed\n", | 172 | pr_info("Unknown key %x pressed\n", reported_key); |
171 | reported_key); | ||
172 | } else if ((key->keycode == KEY_BRIGHTNESSUP || | 173 | } else if ((key->keycode == KEY_BRIGHTNESSUP || |
173 | key->keycode == KEY_BRIGHTNESSDOWN) && acpi_video) { | 174 | key->keycode == KEY_BRIGHTNESSDOWN) && acpi_video) { |
174 | /* Don't report brightness notifications that will also | 175 | /* Don't report brightness notifications that will also |
@@ -275,7 +276,7 @@ static int __init dell_wmi_init(void) | |||
275 | acpi_status status; | 276 | acpi_status status; |
276 | 277 | ||
277 | if (!wmi_has_guid(DELL_EVENT_GUID)) { | 278 | if (!wmi_has_guid(DELL_EVENT_GUID)) { |
278 | printk(KERN_WARNING "dell-wmi: No known WMI GUID found\n"); | 279 | pr_warn("No known WMI GUID found\n"); |
279 | return -ENODEV; | 280 | return -ENODEV; |
280 | } | 281 | } |
281 | 282 | ||
@@ -290,9 +291,7 @@ static int __init dell_wmi_init(void) | |||
290 | dell_wmi_notify, NULL); | 291 | dell_wmi_notify, NULL); |
291 | if (ACPI_FAILURE(status)) { | 292 | if (ACPI_FAILURE(status)) { |
292 | dell_wmi_input_destroy(); | 293 | dell_wmi_input_destroy(); |
293 | printk(KERN_ERR | 294 | pr_err("Unable to register notify handler - %d\n", status); |
294 | "dell-wmi: Unable to register notify handler - %d\n", | ||
295 | status); | ||
296 | return -ENODEV; | 295 | return -ENODEV; |
297 | } | 296 | } |
298 | 297 | ||
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 2c1abf63957f..1c45d92e2163 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c | |||
@@ -228,7 +228,7 @@ static int set_acpi(struct eeepc_laptop *eeepc, int cm, int value) | |||
228 | return -ENODEV; | 228 | return -ENODEV; |
229 | 229 | ||
230 | if (write_acpi_int(eeepc->handle, method, value)) | 230 | if (write_acpi_int(eeepc->handle, method, value)) |
231 | pr_warning("Error writing %s\n", method); | 231 | pr_warn("Error writing %s\n", method); |
232 | return 0; | 232 | return 0; |
233 | } | 233 | } |
234 | 234 | ||
@@ -243,7 +243,7 @@ static int get_acpi(struct eeepc_laptop *eeepc, int cm) | |||
243 | return -ENODEV; | 243 | return -ENODEV; |
244 | 244 | ||
245 | if (read_acpi_int(eeepc->handle, method, &value)) | 245 | if (read_acpi_int(eeepc->handle, method, &value)) |
246 | pr_warning("Error reading %s\n", method); | 246 | pr_warn("Error reading %s\n", method); |
247 | return value; | 247 | return value; |
248 | } | 248 | } |
249 | 249 | ||
@@ -261,7 +261,7 @@ static int acpi_setter_handle(struct eeepc_laptop *eeepc, int cm, | |||
261 | status = acpi_get_handle(eeepc->handle, (char *)method, | 261 | status = acpi_get_handle(eeepc->handle, (char *)method, |
262 | handle); | 262 | handle); |
263 | if (status != AE_OK) { | 263 | if (status != AE_OK) { |
264 | pr_warning("Error finding %s\n", method); | 264 | pr_warn("Error finding %s\n", method); |
265 | return -ENODEV; | 265 | return -ENODEV; |
266 | } | 266 | } |
267 | return 0; | 267 | return 0; |
@@ -417,7 +417,7 @@ static ssize_t store_cpufv_disabled(struct device *dev, | |||
417 | switch (value) { | 417 | switch (value) { |
418 | case 0: | 418 | case 0: |
419 | if (eeepc->cpufv_disabled) | 419 | if (eeepc->cpufv_disabled) |
420 | pr_warning("cpufv enabled (not officially supported " | 420 | pr_warn("cpufv enabled (not officially supported " |
421 | "on this model)\n"); | 421 | "on this model)\n"); |
422 | eeepc->cpufv_disabled = false; | 422 | eeepc->cpufv_disabled = false; |
423 | return rv; | 423 | return rv; |
@@ -609,7 +609,7 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle) | |||
609 | bus = port->subordinate; | 609 | bus = port->subordinate; |
610 | 610 | ||
611 | if (!bus) { | 611 | if (!bus) { |
612 | pr_warning("Unable to find PCI bus?\n"); | 612 | pr_warn("Unable to find PCI bus 1?\n"); |
613 | goto out_unlock; | 613 | goto out_unlock; |
614 | } | 614 | } |
615 | 615 | ||
@@ -621,12 +621,12 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle) | |||
621 | absent = (l == 0xffffffff); | 621 | absent = (l == 0xffffffff); |
622 | 622 | ||
623 | if (blocked != absent) { | 623 | if (blocked != absent) { |
624 | pr_warning("BIOS says wireless lan is %s, " | 624 | pr_warn("BIOS says wireless lan is %s, " |
625 | "but the pci device is %s\n", | 625 | "but the pci device is %s\n", |
626 | blocked ? "blocked" : "unblocked", | 626 | blocked ? "blocked" : "unblocked", |
627 | absent ? "absent" : "present"); | 627 | absent ? "absent" : "present"); |
628 | pr_warning("skipped wireless hotplug as probably " | 628 | pr_warn("skipped wireless hotplug as probably " |
629 | "inappropriate for this model\n"); | 629 | "inappropriate for this model\n"); |
630 | goto out_unlock; | 630 | goto out_unlock; |
631 | } | 631 | } |
632 | 632 | ||
@@ -691,7 +691,8 @@ static int eeepc_register_rfkill_notifier(struct eeepc_laptop *eeepc, | |||
691 | eeepc_rfkill_notify, | 691 | eeepc_rfkill_notify, |
692 | eeepc); | 692 | eeepc); |
693 | if (ACPI_FAILURE(status)) | 693 | if (ACPI_FAILURE(status)) |
694 | pr_warning("Failed to register notify on %s\n", node); | 694 | pr_warn("Failed to register notify on %s\n", node); |
695 | |||
695 | /* | 696 | /* |
696 | * Refresh pci hotplug in case the rfkill state was | 697 | * Refresh pci hotplug in case the rfkill state was |
697 | * changed during setup. | 698 | * changed during setup. |
diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c index 649dcadd8ea3..4aa867a9b88b 100644 --- a/drivers/platform/x86/eeepc-wmi.c +++ b/drivers/platform/x86/eeepc-wmi.c | |||
@@ -84,7 +84,7 @@ static const struct key_entry eeepc_wmi_keymap[] = { | |||
84 | static acpi_status eeepc_wmi_parse_device(acpi_handle handle, u32 level, | 84 | static acpi_status eeepc_wmi_parse_device(acpi_handle handle, u32 level, |
85 | void *context, void **retval) | 85 | void *context, void **retval) |
86 | { | 86 | { |
87 | pr_warning("Found legacy ATKD device (%s)", EEEPC_ACPI_HID); | 87 | pr_warn("Found legacy ATKD device (%s)\n", EEEPC_ACPI_HID); |
88 | *(bool *)context = true; | 88 | *(bool *)context = true; |
89 | return AE_CTRL_TERMINATE; | 89 | return AE_CTRL_TERMINATE; |
90 | } | 90 | } |
@@ -105,12 +105,12 @@ static int eeepc_wmi_check_atkd(void) | |||
105 | static int eeepc_wmi_probe(struct platform_device *pdev) | 105 | static int eeepc_wmi_probe(struct platform_device *pdev) |
106 | { | 106 | { |
107 | if (eeepc_wmi_check_atkd()) { | 107 | if (eeepc_wmi_check_atkd()) { |
108 | pr_warning("WMI device present, but legacy ATKD device is also " | 108 | pr_warn("WMI device present, but legacy ATKD device is also " |
109 | "present and enabled."); | 109 | "present and enabled\n"); |
110 | pr_warning("You probably booted with acpi_osi=\"Linux\" or " | 110 | pr_warn("You probably booted with acpi_osi=\"Linux\" or " |
111 | "acpi_osi=\"!Windows 2009\""); | 111 | "acpi_osi=\"!Windows 2009\"\n"); |
112 | pr_warning("Can't load eeepc-wmi, use default acpi_osi " | 112 | pr_warn("Can't load eeepc-wmi, use default acpi_osi " |
113 | "(preferred) or eeepc-laptop"); | 113 | "(preferred) or eeepc-laptop\n"); |
114 | return -EBUSY; | 114 | return -EBUSY; |
115 | } | 115 | } |
116 | return 0; | 116 | return 0; |
diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index 493054c2dbe1..6b26666b37f2 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c | |||
@@ -56,6 +56,8 @@ | |||
56 | * | 56 | * |
57 | */ | 57 | */ |
58 | 58 | ||
59 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
60 | |||
59 | #include <linux/module.h> | 61 | #include <linux/module.h> |
60 | #include <linux/kernel.h> | 62 | #include <linux/kernel.h> |
61 | #include <linux/init.h> | 63 | #include <linux/init.h> |
@@ -585,8 +587,7 @@ static struct platform_driver fujitsupf_driver = { | |||
585 | static void dmi_check_cb_common(const struct dmi_system_id *id) | 587 | static void dmi_check_cb_common(const struct dmi_system_id *id) |
586 | { | 588 | { |
587 | acpi_handle handle; | 589 | acpi_handle handle; |
588 | printk(KERN_INFO "fujitsu-laptop: Identified laptop model '%s'.\n", | 590 | pr_info("Identified laptop model '%s'\n", id->ident); |
589 | id->ident); | ||
590 | if (use_alt_lcd_levels == -1) { | 591 | if (use_alt_lcd_levels == -1) { |
591 | if (ACPI_SUCCESS(acpi_get_handle(NULL, | 592 | if (ACPI_SUCCESS(acpi_get_handle(NULL, |
592 | "\\_SB.PCI0.LPCB.FJEX.SBL2", &handle))) | 593 | "\\_SB.PCI0.LPCB.FJEX.SBL2", &handle))) |
@@ -691,11 +692,11 @@ static int acpi_fujitsu_add(struct acpi_device *device) | |||
691 | 692 | ||
692 | result = acpi_bus_update_power(fujitsu->acpi_handle, &state); | 693 | result = acpi_bus_update_power(fujitsu->acpi_handle, &state); |
693 | if (result) { | 694 | if (result) { |
694 | printk(KERN_ERR "Error reading power state\n"); | 695 | pr_err("Error reading power state\n"); |
695 | goto err_unregister_input_dev; | 696 | goto err_unregister_input_dev; |
696 | } | 697 | } |
697 | 698 | ||
698 | printk(KERN_INFO "ACPI: %s [%s] (%s)\n", | 699 | pr_info("ACPI: %s [%s] (%s)\n", |
699 | acpi_device_name(device), acpi_device_bid(device), | 700 | acpi_device_name(device), acpi_device_bid(device), |
700 | !device->power.state ? "on" : "off"); | 701 | !device->power.state ? "on" : "off"); |
701 | 702 | ||
@@ -707,7 +708,7 @@ static int acpi_fujitsu_add(struct acpi_device *device) | |||
707 | if (ACPI_FAILURE | 708 | if (ACPI_FAILURE |
708 | (acpi_evaluate_object | 709 | (acpi_evaluate_object |
709 | (device->handle, METHOD_NAME__INI, NULL, NULL))) | 710 | (device->handle, METHOD_NAME__INI, NULL, NULL))) |
710 | printk(KERN_ERR "_INI Method failed\n"); | 711 | pr_err("_INI Method failed\n"); |
711 | } | 712 | } |
712 | 713 | ||
713 | /* do config (detect defaults) */ | 714 | /* do config (detect defaults) */ |
@@ -827,7 +828,7 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) | |||
827 | error = kfifo_alloc(&fujitsu_hotkey->fifo, RINGBUFFERSIZE * sizeof(int), | 828 | error = kfifo_alloc(&fujitsu_hotkey->fifo, RINGBUFFERSIZE * sizeof(int), |
828 | GFP_KERNEL); | 829 | GFP_KERNEL); |
829 | if (error) { | 830 | if (error) { |
830 | printk(KERN_ERR "kfifo_alloc failed\n"); | 831 | pr_err("kfifo_alloc failed\n"); |
831 | goto err_stop; | 832 | goto err_stop; |
832 | } | 833 | } |
833 | 834 | ||
@@ -859,13 +860,13 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) | |||
859 | 860 | ||
860 | result = acpi_bus_update_power(fujitsu_hotkey->acpi_handle, &state); | 861 | result = acpi_bus_update_power(fujitsu_hotkey->acpi_handle, &state); |
861 | if (result) { | 862 | if (result) { |
862 | printk(KERN_ERR "Error reading power state\n"); | 863 | pr_err("Error reading power state\n"); |
863 | goto err_unregister_input_dev; | 864 | goto err_unregister_input_dev; |
864 | } | 865 | } |
865 | 866 | ||
866 | printk(KERN_INFO "ACPI: %s [%s] (%s)\n", | 867 | pr_info("ACPI: %s [%s] (%s)\n", |
867 | acpi_device_name(device), acpi_device_bid(device), | 868 | acpi_device_name(device), acpi_device_bid(device), |
868 | !device->power.state ? "on" : "off"); | 869 | !device->power.state ? "on" : "off"); |
869 | 870 | ||
870 | fujitsu_hotkey->dev = device; | 871 | fujitsu_hotkey->dev = device; |
871 | 872 | ||
@@ -875,7 +876,7 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) | |||
875 | if (ACPI_FAILURE | 876 | if (ACPI_FAILURE |
876 | (acpi_evaluate_object | 877 | (acpi_evaluate_object |
877 | (device->handle, METHOD_NAME__INI, NULL, NULL))) | 878 | (device->handle, METHOD_NAME__INI, NULL, NULL))) |
878 | printk(KERN_ERR "_INI Method failed\n"); | 879 | pr_err("_INI Method failed\n"); |
879 | } | 880 | } |
880 | 881 | ||
881 | i = 0; | 882 | i = 0; |
@@ -897,8 +898,7 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) | |||
897 | call_fext_func(FUNC_RFKILL, 0x4, 0x0, 0x0); | 898 | call_fext_func(FUNC_RFKILL, 0x4, 0x0, 0x0); |
898 | 899 | ||
899 | /* Suspect this is a keymap of the application panel, print it */ | 900 | /* Suspect this is a keymap of the application panel, print it */ |
900 | printk(KERN_INFO "fujitsu-laptop: BTNI: [0x%x]\n", | 901 | pr_info("BTNI: [0x%x]\n", call_fext_func(FUNC_BUTTONS, 0x0, 0x0, 0x0)); |
901 | call_fext_func(FUNC_BUTTONS, 0x0, 0x0, 0x0)); | ||
902 | 902 | ||
903 | #if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) | 903 | #if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) |
904 | if (call_fext_func(FUNC_LEDS, 0x0, 0x0, 0x0) & LOGOLAMP_POWERON) { | 904 | if (call_fext_func(FUNC_LEDS, 0x0, 0x0, 0x0) & LOGOLAMP_POWERON) { |
@@ -907,8 +907,8 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) | |||
907 | if (result == 0) { | 907 | if (result == 0) { |
908 | fujitsu_hotkey->logolamp_registered = 1; | 908 | fujitsu_hotkey->logolamp_registered = 1; |
909 | } else { | 909 | } else { |
910 | printk(KERN_ERR "fujitsu-laptop: Could not register " | 910 | pr_err("Could not register LED handler for logo lamp, error %i\n", |
911 | "LED handler for logo lamp, error %i\n", result); | 911 | result); |
912 | } | 912 | } |
913 | } | 913 | } |
914 | 914 | ||
@@ -919,8 +919,8 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) | |||
919 | if (result == 0) { | 919 | if (result == 0) { |
920 | fujitsu_hotkey->kblamps_registered = 1; | 920 | fujitsu_hotkey->kblamps_registered = 1; |
921 | } else { | 921 | } else { |
922 | printk(KERN_ERR "fujitsu-laptop: Could not register " | 922 | pr_err("Could not register LED handler for keyboard lamps, error %i\n", |
923 | "LED handler for keyboard lamps, error %i\n", result); | 923 | result); |
924 | } | 924 | } |
925 | } | 925 | } |
926 | #endif | 926 | #endif |
@@ -1169,8 +1169,7 @@ static int __init fujitsu_init(void) | |||
1169 | fujitsu->bl_device->props.power = 0; | 1169 | fujitsu->bl_device->props.power = 0; |
1170 | } | 1170 | } |
1171 | 1171 | ||
1172 | printk(KERN_INFO "fujitsu-laptop: driver " FUJITSU_DRIVER_VERSION | 1172 | pr_info("driver " FUJITSU_DRIVER_VERSION " successfully loaded\n"); |
1173 | " successfully loaded.\n"); | ||
1174 | 1173 | ||
1175 | return 0; | 1174 | return 0; |
1176 | 1175 | ||
@@ -1216,7 +1215,7 @@ static void __exit fujitsu_cleanup(void) | |||
1216 | 1215 | ||
1217 | kfree(fujitsu); | 1216 | kfree(fujitsu); |
1218 | 1217 | ||
1219 | printk(KERN_INFO "fujitsu-laptop: driver unloaded.\n"); | 1218 | pr_info("driver unloaded\n"); |
1220 | } | 1219 | } |
1221 | 1220 | ||
1222 | module_init(fujitsu_init); | 1221 | module_init(fujitsu_init); |
diff --git a/drivers/platform/x86/hdaps.c b/drivers/platform/x86/hdaps.c index 067bf36d32f3..5a34973dc164 100644 --- a/drivers/platform/x86/hdaps.c +++ b/drivers/platform/x86/hdaps.c | |||
@@ -26,6 +26,8 @@ | |||
26 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA | 26 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
30 | |||
29 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
30 | #include <linux/platform_device.h> | 32 | #include <linux/platform_device.h> |
31 | #include <linux/input-polldev.h> | 33 | #include <linux/input-polldev.h> |
@@ -238,7 +240,7 @@ static int hdaps_device_init(void) | |||
238 | __check_latch(0x1611, 0x01)) | 240 | __check_latch(0x1611, 0x01)) |
239 | goto out; | 241 | goto out; |
240 | 242 | ||
241 | printk(KERN_DEBUG "hdaps: initial latch check good (0x%02x).\n", | 243 | printk(KERN_DEBUG "hdaps: initial latch check good (0x%02x)\n", |
242 | __get_latch(0x1611)); | 244 | __get_latch(0x1611)); |
243 | 245 | ||
244 | outb(0x17, 0x1610); | 246 | outb(0x17, 0x1610); |
@@ -299,7 +301,7 @@ static int hdaps_probe(struct platform_device *dev) | |||
299 | if (ret) | 301 | if (ret) |
300 | return ret; | 302 | return ret; |
301 | 303 | ||
302 | printk(KERN_INFO "hdaps: device successfully initialized.\n"); | 304 | pr_info("device successfully initialized\n"); |
303 | return 0; | 305 | return 0; |
304 | } | 306 | } |
305 | 307 | ||
@@ -480,7 +482,7 @@ static struct attribute_group hdaps_attribute_group = { | |||
480 | /* hdaps_dmi_match - found a match. return one, short-circuiting the hunt. */ | 482 | /* hdaps_dmi_match - found a match. return one, short-circuiting the hunt. */ |
481 | static int __init hdaps_dmi_match(const struct dmi_system_id *id) | 483 | static int __init hdaps_dmi_match(const struct dmi_system_id *id) |
482 | { | 484 | { |
483 | printk(KERN_INFO "hdaps: %s detected.\n", id->ident); | 485 | pr_info("%s detected\n", id->ident); |
484 | return 1; | 486 | return 1; |
485 | } | 487 | } |
486 | 488 | ||
@@ -488,8 +490,7 @@ static int __init hdaps_dmi_match(const struct dmi_system_id *id) | |||
488 | static int __init hdaps_dmi_match_invert(const struct dmi_system_id *id) | 490 | static int __init hdaps_dmi_match_invert(const struct dmi_system_id *id) |
489 | { | 491 | { |
490 | hdaps_invert = (unsigned long)id->driver_data; | 492 | hdaps_invert = (unsigned long)id->driver_data; |
491 | printk(KERN_INFO "hdaps: inverting axis (%u) readings.\n", | 493 | pr_info("inverting axis (%u) readings\n", hdaps_invert); |
492 | hdaps_invert); | ||
493 | return hdaps_dmi_match(id); | 494 | return hdaps_dmi_match(id); |
494 | } | 495 | } |
495 | 496 | ||
@@ -543,7 +544,7 @@ static int __init hdaps_init(void) | |||
543 | int ret; | 544 | int ret; |
544 | 545 | ||
545 | if (!dmi_check_system(hdaps_whitelist)) { | 546 | if (!dmi_check_system(hdaps_whitelist)) { |
546 | printk(KERN_WARNING "hdaps: supported laptop not found!\n"); | 547 | pr_warn("supported laptop not found!\n"); |
547 | ret = -ENODEV; | 548 | ret = -ENODEV; |
548 | goto out; | 549 | goto out; |
549 | } | 550 | } |
@@ -595,7 +596,7 @@ static int __init hdaps_init(void) | |||
595 | if (ret) | 596 | if (ret) |
596 | goto out_idev; | 597 | goto out_idev; |
597 | 598 | ||
598 | printk(KERN_INFO "hdaps: driver successfully loaded.\n"); | 599 | pr_info("driver successfully loaded\n"); |
599 | return 0; | 600 | return 0; |
600 | 601 | ||
601 | out_idev: | 602 | out_idev: |
@@ -609,7 +610,7 @@ out_driver: | |||
609 | out_region: | 610 | out_region: |
610 | release_region(HDAPS_LOW_PORT, HDAPS_NR_PORTS); | 611 | release_region(HDAPS_LOW_PORT, HDAPS_NR_PORTS); |
611 | out: | 612 | out: |
612 | printk(KERN_WARNING "hdaps: driver init failed (ret=%d)!\n", ret); | 613 | pr_warn("driver init failed (ret=%d)!\n", ret); |
613 | return ret; | 614 | return ret; |
614 | } | 615 | } |
615 | 616 | ||
@@ -622,7 +623,7 @@ static void __exit hdaps_exit(void) | |||
622 | platform_driver_unregister(&hdaps_driver); | 623 | platform_driver_unregister(&hdaps_driver); |
623 | release_region(HDAPS_LOW_PORT, HDAPS_NR_PORTS); | 624 | release_region(HDAPS_LOW_PORT, HDAPS_NR_PORTS); |
624 | 625 | ||
625 | printk(KERN_INFO "hdaps: driver unloaded.\n"); | 626 | pr_info("driver unloaded\n"); |
626 | } | 627 | } |
627 | 628 | ||
628 | module_init(hdaps_init); | 629 | module_init(hdaps_init); |
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index 1bc4a7539ba9..f94017bcdd6e 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c | |||
@@ -24,6 +24,8 @@ | |||
24 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 24 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
25 | */ | 25 | */ |
26 | 26 | ||
27 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
28 | |||
27 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
28 | #include <linux/module.h> | 30 | #include <linux/module.h> |
29 | #include <linux/init.h> | 31 | #include <linux/init.h> |
@@ -54,9 +56,6 @@ MODULE_ALIAS("wmi:5FB7F034-2C63-45e9-BE91-3D44E2C707E4"); | |||
54 | #define HPWMI_HOTKEY_QUERY 0xc | 56 | #define HPWMI_HOTKEY_QUERY 0xc |
55 | #define HPWMI_WIRELESS2_QUERY 0x1b | 57 | #define HPWMI_WIRELESS2_QUERY 0x1b |
56 | 58 | ||
57 | #define PREFIX "HP WMI: " | ||
58 | #define UNIMP "Unimplemented " | ||
59 | |||
60 | enum hp_wmi_radio { | 59 | enum hp_wmi_radio { |
61 | HPWMI_WIFI = 0, | 60 | HPWMI_WIFI = 0, |
62 | HPWMI_BLUETOOTH = 1, | 61 | HPWMI_BLUETOOTH = 1, |
@@ -228,9 +227,8 @@ static int hp_wmi_perform_query(int query, int write, void *buffer, | |||
228 | 227 | ||
229 | if (bios_return->return_code) { | 228 | if (bios_return->return_code) { |
230 | if (bios_return->return_code != HPWMI_RET_UNKNOWN_CMDTYPE) | 229 | if (bios_return->return_code != HPWMI_RET_UNKNOWN_CMDTYPE) |
231 | printk(KERN_WARNING PREFIX "query 0x%x returned " | 230 | pr_warn("query 0x%x returned error 0x%x\n", |
232 | "error 0x%x\n", | 231 | query, bios_return->return_code); |
233 | query, bios_return->return_code); | ||
234 | kfree(obj); | 232 | kfree(obj); |
235 | return bios_return->return_code; | 233 | return bios_return->return_code; |
236 | } | 234 | } |
@@ -384,8 +382,7 @@ static int hp_wmi_rfkill2_refresh(void) | |||
384 | 382 | ||
385 | if (num >= state.count || | 383 | if (num >= state.count || |
386 | devstate->rfkill_id != rfkill2[i].id) { | 384 | devstate->rfkill_id != rfkill2[i].id) { |
387 | printk(KERN_WARNING PREFIX "power configuration of " | 385 | pr_warn("power configuration of the wireless devices unexpectedly changed\n"); |
388 | "the wireless devices unexpectedly changed\n"); | ||
389 | continue; | 386 | continue; |
390 | } | 387 | } |
391 | 388 | ||
@@ -471,7 +468,7 @@ static void hp_wmi_notify(u32 value, void *context) | |||
471 | 468 | ||
472 | status = wmi_get_event_data(value, &response); | 469 | status = wmi_get_event_data(value, &response); |
473 | if (status != AE_OK) { | 470 | if (status != AE_OK) { |
474 | printk(KERN_INFO PREFIX "bad event status 0x%x\n", status); | 471 | pr_info("bad event status 0x%x\n", status); |
475 | return; | 472 | return; |
476 | } | 473 | } |
477 | 474 | ||
@@ -480,8 +477,7 @@ static void hp_wmi_notify(u32 value, void *context) | |||
480 | if (!obj) | 477 | if (!obj) |
481 | return; | 478 | return; |
482 | if (obj->type != ACPI_TYPE_BUFFER) { | 479 | if (obj->type != ACPI_TYPE_BUFFER) { |
483 | printk(KERN_INFO "hp-wmi: Unknown response received %d\n", | 480 | pr_info("Unknown response received %d\n", obj->type); |
484 | obj->type); | ||
485 | kfree(obj); | 481 | kfree(obj); |
486 | return; | 482 | return; |
487 | } | 483 | } |
@@ -498,8 +494,7 @@ static void hp_wmi_notify(u32 value, void *context) | |||
498 | event_id = *location; | 494 | event_id = *location; |
499 | event_data = *(location + 2); | 495 | event_data = *(location + 2); |
500 | } else { | 496 | } else { |
501 | printk(KERN_INFO "hp-wmi: Unknown buffer length %d\n", | 497 | pr_info("Unknown buffer length %d\n", obj->buffer.length); |
502 | obj->buffer.length); | ||
503 | kfree(obj); | 498 | kfree(obj); |
504 | return; | 499 | return; |
505 | } | 500 | } |
@@ -527,8 +522,7 @@ static void hp_wmi_notify(u32 value, void *context) | |||
527 | 522 | ||
528 | if (!sparse_keymap_report_event(hp_wmi_input_dev, | 523 | if (!sparse_keymap_report_event(hp_wmi_input_dev, |
529 | key_code, 1, true)) | 524 | key_code, 1, true)) |
530 | printk(KERN_INFO PREFIX "Unknown key code - 0x%x\n", | 525 | pr_info("Unknown key code - 0x%x\n", key_code); |
531 | key_code); | ||
532 | break; | 526 | break; |
533 | case HPWMI_WIRELESS: | 527 | case HPWMI_WIRELESS: |
534 | if (rfkill2_count) { | 528 | if (rfkill2_count) { |
@@ -550,14 +544,12 @@ static void hp_wmi_notify(u32 value, void *context) | |||
550 | hp_wmi_get_hw_state(HPWMI_WWAN)); | 544 | hp_wmi_get_hw_state(HPWMI_WWAN)); |
551 | break; | 545 | break; |
552 | case HPWMI_CPU_BATTERY_THROTTLE: | 546 | case HPWMI_CPU_BATTERY_THROTTLE: |
553 | printk(KERN_INFO PREFIX UNIMP "CPU throttle because of 3 Cell" | 547 | pr_info("Unimplemented CPU throttle because of 3 Cell battery event detected\n"); |
554 | " battery event detected\n"); | ||
555 | break; | 548 | break; |
556 | case HPWMI_LOCK_SWITCH: | 549 | case HPWMI_LOCK_SWITCH: |
557 | break; | 550 | break; |
558 | default: | 551 | default: |
559 | printk(KERN_INFO PREFIX "Unknown event_id - %d - 0x%x\n", | 552 | pr_info("Unknown event_id - %d - 0x%x\n", event_id, event_data); |
560 | event_id, event_data); | ||
561 | break; | 553 | break; |
562 | } | 554 | } |
563 | } | 555 | } |
@@ -705,7 +697,7 @@ static int __devinit hp_wmi_rfkill2_setup(struct platform_device *device) | |||
705 | return err; | 697 | return err; |
706 | 698 | ||
707 | if (state.count > HPWMI_MAX_RFKILL2_DEVICES) { | 699 | if (state.count > HPWMI_MAX_RFKILL2_DEVICES) { |
708 | printk(KERN_WARNING PREFIX "unable to parse 0x1b query output\n"); | 700 | pr_warn("unable to parse 0x1b query output\n"); |
709 | return -EINVAL; | 701 | return -EINVAL; |
710 | } | 702 | } |
711 | 703 | ||
@@ -727,14 +719,14 @@ static int __devinit hp_wmi_rfkill2_setup(struct platform_device *device) | |||
727 | name = "hp-wwan"; | 719 | name = "hp-wwan"; |
728 | break; | 720 | break; |
729 | default: | 721 | default: |
730 | printk(KERN_WARNING PREFIX "unknown device type 0x%x\n", | 722 | pr_warn("unknown device type 0x%x\n", |
731 | state.device[i].radio_type); | 723 | state.device[i].radio_type); |
732 | continue; | 724 | continue; |
733 | } | 725 | } |
734 | 726 | ||
735 | if (!state.device[i].vendor_id) { | 727 | if (!state.device[i].vendor_id) { |
736 | printk(KERN_WARNING PREFIX "zero device %d while %d " | 728 | pr_warn("zero device %d while %d reported\n", |
737 | "reported\n", i, state.count); | 729 | i, state.count); |
738 | continue; | 730 | continue; |
739 | } | 731 | } |
740 | 732 | ||
@@ -755,8 +747,7 @@ static int __devinit hp_wmi_rfkill2_setup(struct platform_device *device) | |||
755 | IS_HWBLOCKED(state.device[i].power)); | 747 | IS_HWBLOCKED(state.device[i].power)); |
756 | 748 | ||
757 | if (!(state.device[i].power & HPWMI_POWER_BIOS)) | 749 | if (!(state.device[i].power & HPWMI_POWER_BIOS)) |
758 | printk(KERN_INFO PREFIX "device %s blocked by BIOS\n", | 750 | pr_info("device %s blocked by BIOS\n", name); |
759 | name); | ||
760 | 751 | ||
761 | err = rfkill_register(rfkill); | 752 | err = rfkill_register(rfkill); |
762 | if (err) { | 753 | if (err) { |
diff --git a/drivers/platform/x86/ibm_rtl.c b/drivers/platform/x86/ibm_rtl.c index b1396e5b2953..811d436cd677 100644 --- a/drivers/platform/x86/ibm_rtl.c +++ b/drivers/platform/x86/ibm_rtl.c | |||
@@ -22,6 +22,8 @@ | |||
22 | * | 22 | * |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
26 | |||
25 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
26 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
27 | #include <linux/module.h> | 29 | #include <linux/module.h> |
@@ -69,9 +71,10 @@ struct ibm_rtl_table { | |||
69 | #define RTL_SIGNATURE 0x0000005f4c54525fULL | 71 | #define RTL_SIGNATURE 0x0000005f4c54525fULL |
70 | #define RTL_MASK 0x000000ffffffffffULL | 72 | #define RTL_MASK 0x000000ffffffffffULL |
71 | 73 | ||
72 | #define RTL_DEBUG(A, ...) do { \ | 74 | #define RTL_DEBUG(fmt, ...) \ |
73 | if (debug) \ | 75 | do { \ |
74 | pr_info("ibm-rtl: " A, ##__VA_ARGS__ ); \ | 76 | if (debug) \ |
77 | pr_info(fmt, ##__VA_ARGS__); \ | ||
75 | } while (0) | 78 | } while (0) |
76 | 79 | ||
77 | static DEFINE_MUTEX(rtl_lock); | 80 | static DEFINE_MUTEX(rtl_lock); |
@@ -114,7 +117,7 @@ static int ibm_rtl_write(u8 value) | |||
114 | int ret = 0, count = 0; | 117 | int ret = 0, count = 0; |
115 | static u32 cmd_port_val; | 118 | static u32 cmd_port_val; |
116 | 119 | ||
117 | RTL_DEBUG("%s(%d)\n", __FUNCTION__, value); | 120 | RTL_DEBUG("%s(%d)\n", __func__, value); |
118 | 121 | ||
119 | value = value == 1 ? RTL_CMD_ENTER_PRTM : RTL_CMD_EXIT_PRTM; | 122 | value = value == 1 ? RTL_CMD_ENTER_PRTM : RTL_CMD_EXIT_PRTM; |
120 | 123 | ||
@@ -144,8 +147,8 @@ static int ibm_rtl_write(u8 value) | |||
144 | while (ioread8(&rtl_table->command)) { | 147 | while (ioread8(&rtl_table->command)) { |
145 | msleep(10); | 148 | msleep(10); |
146 | if (count++ > 500) { | 149 | if (count++ > 500) { |
147 | pr_err("ibm-rtl: Hardware not responding to " | 150 | pr_err("Hardware not responding to " |
148 | "mode switch request\n"); | 151 | "mode switch request\n"); |
149 | ret = -EIO; | 152 | ret = -EIO; |
150 | break; | 153 | break; |
151 | } | 154 | } |
@@ -250,7 +253,7 @@ static int __init ibm_rtl_init(void) { | |||
250 | int ret = -ENODEV, i; | 253 | int ret = -ENODEV, i; |
251 | 254 | ||
252 | if (force) | 255 | if (force) |
253 | pr_warning("ibm-rtl: module loaded by force\n"); | 256 | pr_warn("module loaded by force\n"); |
254 | /* first ensure that we are running on IBM HW */ | 257 | /* first ensure that we are running on IBM HW */ |
255 | else if (efi_enabled || !dmi_check_system(ibm_rtl_dmi_table)) | 258 | else if (efi_enabled || !dmi_check_system(ibm_rtl_dmi_table)) |
256 | return -ENODEV; | 259 | return -ENODEV; |
@@ -288,19 +291,19 @@ static int __init ibm_rtl_init(void) { | |||
288 | if ((readq(&tmp->signature) & RTL_MASK) == RTL_SIGNATURE) { | 291 | if ((readq(&tmp->signature) & RTL_MASK) == RTL_SIGNATURE) { |
289 | phys_addr_t addr; | 292 | phys_addr_t addr; |
290 | unsigned int plen; | 293 | unsigned int plen; |
291 | RTL_DEBUG("found RTL_SIGNATURE at %#llx\n", (u64)tmp); | 294 | RTL_DEBUG("found RTL_SIGNATURE at %p\n", tmp); |
292 | rtl_table = tmp; | 295 | rtl_table = tmp; |
293 | /* The address, value, width and offset are platform | 296 | /* The address, value, width and offset are platform |
294 | * dependent and found in the ibm_rtl_table */ | 297 | * dependent and found in the ibm_rtl_table */ |
295 | rtl_cmd_width = ioread8(&rtl_table->cmd_granularity); | 298 | rtl_cmd_width = ioread8(&rtl_table->cmd_granularity); |
296 | rtl_cmd_type = ioread8(&rtl_table->cmd_address_type); | 299 | rtl_cmd_type = ioread8(&rtl_table->cmd_address_type); |
297 | RTL_DEBUG("rtl_cmd_width = %u, rtl_cmd_type = %u\n", | 300 | RTL_DEBUG("rtl_cmd_width = %u, rtl_cmd_type = %u\n", |
298 | rtl_cmd_width, rtl_cmd_type); | 301 | rtl_cmd_width, rtl_cmd_type); |
299 | addr = ioread32(&rtl_table->cmd_port_address); | 302 | addr = ioread32(&rtl_table->cmd_port_address); |
300 | RTL_DEBUG("addr = %#llx\n", (unsigned long long)addr); | 303 | RTL_DEBUG("addr = %#llx\n", (unsigned long long)addr); |
301 | plen = rtl_cmd_width/sizeof(char); | 304 | plen = rtl_cmd_width/sizeof(char); |
302 | rtl_cmd_addr = rtl_port_map(addr, plen); | 305 | rtl_cmd_addr = rtl_port_map(addr, plen); |
303 | RTL_DEBUG("rtl_cmd_addr = %#llx\n", (u64)rtl_cmd_addr); | 306 | RTL_DEBUG("rtl_cmd_addr = %p\n", rtl_cmd_addr); |
304 | if (!rtl_cmd_addr) { | 307 | if (!rtl_cmd_addr) { |
305 | ret = -ENOMEM; | 308 | ret = -ENOMEM; |
306 | break; | 309 | break; |
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index 21b101899bae..bfdda33feb26 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c | |||
@@ -20,6 +20,8 @@ | |||
20 | * 02110-1301, USA. | 20 | * 02110-1301, USA. |
21 | */ | 21 | */ |
22 | 22 | ||
23 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
24 | |||
23 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
24 | #include <linux/module.h> | 26 | #include <linux/module.h> |
25 | #include <linux/init.h> | 27 | #include <linux/init.h> |
diff --git a/drivers/platform/x86/intel_menlow.c b/drivers/platform/x86/intel_menlow.c index eacd5da7dd24..809adea4965f 100644 --- a/drivers/platform/x86/intel_menlow.c +++ b/drivers/platform/x86/intel_menlow.c | |||
@@ -27,6 +27,8 @@ | |||
27 | * to get/set bandwidth. | 27 | * to get/set bandwidth. |
28 | */ | 28 | */ |
29 | 29 | ||
30 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
31 | |||
30 | #include <linux/kernel.h> | 32 | #include <linux/kernel.h> |
31 | #include <linux/module.h> | 33 | #include <linux/module.h> |
32 | #include <linux/init.h> | 34 | #include <linux/init.h> |
@@ -135,8 +137,7 @@ static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev, | |||
135 | acpi_evaluate_integer(handle, MEMORY_SET_BANDWIDTH, &arg_list, | 137 | acpi_evaluate_integer(handle, MEMORY_SET_BANDWIDTH, &arg_list, |
136 | &temp); | 138 | &temp); |
137 | 139 | ||
138 | printk(KERN_INFO | 140 | pr_info("Bandwidth value was %ld: status is %d\n", state, status); |
139 | "Bandwidth value was %ld: status is %d\n", state, status); | ||
140 | if (ACPI_FAILURE(status)) | 141 | if (ACPI_FAILURE(status)) |
141 | return -EFAULT; | 142 | return -EFAULT; |
142 | 143 | ||
diff --git a/drivers/platform/x86/intel_mid_powerbtn.c b/drivers/platform/x86/intel_mid_powerbtn.c index 213e79ba68d5..f1ae5078b7ec 100644 --- a/drivers/platform/x86/intel_mid_powerbtn.c +++ b/drivers/platform/x86/intel_mid_powerbtn.c | |||
@@ -23,58 +23,48 @@ | |||
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
25 | #include <linux/input.h> | 25 | #include <linux/input.h> |
26 | |||
26 | #include <asm/intel_scu_ipc.h> | 27 | #include <asm/intel_scu_ipc.h> |
27 | 28 | ||
28 | #define DRIVER_NAME "msic_power_btn" | 29 | #define DRIVER_NAME "msic_power_btn" |
29 | 30 | ||
30 | #define MSIC_IRQ_STAT 0x02 | ||
31 | #define MSIC_IRQ_PB (1 << 0) | ||
32 | #define MSIC_PB_CONFIG 0x3e | ||
33 | #define MSIC_PB_STATUS 0x3f | 31 | #define MSIC_PB_STATUS 0x3f |
34 | #define MSIC_PB_LEVEL (1 << 3) /* 1 - release, 0 - press */ | 32 | #define MSIC_PB_LEVEL (1 << 3) /* 1 - release, 0 - press */ |
35 | |||
36 | struct mfld_pb_priv { | ||
37 | struct input_dev *input; | ||
38 | unsigned int irq; | ||
39 | }; | ||
40 | 33 | ||
41 | static irqreturn_t mfld_pb_isr(int irq, void *dev_id) | 34 | static irqreturn_t mfld_pb_isr(int irq, void *dev_id) |
42 | { | 35 | { |
43 | struct mfld_pb_priv *priv = dev_id; | 36 | struct input_dev *input = dev_id; |
44 | int ret; | 37 | int ret; |
45 | u8 pbstat; | 38 | u8 pbstat; |
46 | 39 | ||
47 | ret = intel_scu_ipc_ioread8(MSIC_PB_STATUS, &pbstat); | 40 | ret = intel_scu_ipc_ioread8(MSIC_PB_STATUS, &pbstat); |
48 | if (ret < 0) | 41 | if (ret < 0) { |
49 | return IRQ_HANDLED; | 42 | dev_err(input->dev.parent, "Read error %d while reading" |
50 | 43 | " MSIC_PB_STATUS\n", ret); | |
51 | input_event(priv->input, EV_KEY, KEY_POWER, !(pbstat & MSIC_PB_LEVEL)); | 44 | } else { |
52 | input_sync(priv->input); | 45 | input_event(input, EV_KEY, KEY_POWER, |
46 | !(pbstat & MSIC_PB_LEVEL)); | ||
47 | input_sync(input); | ||
48 | } | ||
53 | 49 | ||
54 | return IRQ_HANDLED; | 50 | return IRQ_HANDLED; |
55 | } | 51 | } |
56 | 52 | ||
57 | static int __devinit mfld_pb_probe(struct platform_device *pdev) | 53 | static int __devinit mfld_pb_probe(struct platform_device *pdev) |
58 | { | 54 | { |
59 | struct mfld_pb_priv *priv; | ||
60 | struct input_dev *input; | 55 | struct input_dev *input; |
61 | int irq; | 56 | int irq = platform_get_irq(pdev, 0); |
62 | int error; | 57 | int error; |
63 | 58 | ||
64 | irq = platform_get_irq(pdev, 0); | ||
65 | if (irq < 0) | 59 | if (irq < 0) |
66 | return -EINVAL; | 60 | return -EINVAL; |
67 | 61 | ||
68 | priv = kzalloc(sizeof(struct mfld_pb_priv), GFP_KERNEL); | ||
69 | input = input_allocate_device(); | 62 | input = input_allocate_device(); |
70 | if (!priv || !input) { | 63 | if (!input) { |
71 | error = -ENOMEM; | 64 | dev_err(&pdev->dev, "Input device allocation error\n"); |
72 | goto err_free_mem; | 65 | return -ENOMEM; |
73 | } | 66 | } |
74 | 67 | ||
75 | priv->input = input; | ||
76 | priv->irq = irq; | ||
77 | |||
78 | input->name = pdev->name; | 68 | input->name = pdev->name; |
79 | input->phys = "power-button/input0"; | 69 | input->phys = "power-button/input0"; |
80 | input->id.bustype = BUS_HOST; | 70 | input->id.bustype = BUS_HOST; |
@@ -82,42 +72,40 @@ static int __devinit mfld_pb_probe(struct platform_device *pdev) | |||
82 | 72 | ||
83 | input_set_capability(input, EV_KEY, KEY_POWER); | 73 | input_set_capability(input, EV_KEY, KEY_POWER); |
84 | 74 | ||
85 | error = request_threaded_irq(priv->irq, NULL, mfld_pb_isr, | 75 | error = request_threaded_irq(irq, NULL, mfld_pb_isr, 0, |
86 | 0, DRIVER_NAME, priv); | 76 | DRIVER_NAME, input); |
87 | if (error) { | 77 | if (error) { |
88 | dev_err(&pdev->dev, | 78 | dev_err(&pdev->dev, "Unable to request irq %d for mfld power" |
89 | "unable to request irq %d for mfld power button\n", | 79 | "button\n", irq); |
90 | irq); | 80 | goto err_free_input; |
91 | goto err_free_mem; | ||
92 | } | 81 | } |
93 | 82 | ||
94 | error = input_register_device(input); | 83 | error = input_register_device(input); |
95 | if (error) { | 84 | if (error) { |
96 | dev_err(&pdev->dev, | 85 | dev_err(&pdev->dev, "Unable to register input dev, error " |
97 | "unable to register input dev, error %d\n", error); | 86 | "%d\n", error); |
98 | goto err_free_irq; | 87 | goto err_free_irq; |
99 | } | 88 | } |
100 | 89 | ||
101 | platform_set_drvdata(pdev, priv); | 90 | platform_set_drvdata(pdev, input); |
102 | return 0; | 91 | return 0; |
103 | 92 | ||
104 | err_free_irq: | 93 | err_free_irq: |
105 | free_irq(priv->irq, priv); | 94 | free_irq(irq, input); |
106 | err_free_mem: | 95 | err_free_input: |
107 | input_free_device(input); | 96 | input_free_device(input); |
108 | kfree(priv); | ||
109 | return error; | 97 | return error; |
110 | } | 98 | } |
111 | 99 | ||
112 | static int __devexit mfld_pb_remove(struct platform_device *pdev) | 100 | static int __devexit mfld_pb_remove(struct platform_device *pdev) |
113 | { | 101 | { |
114 | struct mfld_pb_priv *priv = platform_get_drvdata(pdev); | 102 | struct input_dev *input = platform_get_drvdata(pdev); |
115 | 103 | int irq = platform_get_irq(pdev, 0); | |
116 | free_irq(priv->irq, priv); | ||
117 | input_unregister_device(priv->input); | ||
118 | kfree(priv); | ||
119 | 104 | ||
105 | free_irq(irq, input); | ||
106 | input_unregister_device(input); | ||
120 | platform_set_drvdata(pdev, NULL); | 107 | platform_set_drvdata(pdev, NULL); |
108 | |||
121 | return 0; | 109 | return 0; |
122 | } | 110 | } |
123 | 111 | ||
diff --git a/drivers/platform/x86/intel_mid_thermal.c b/drivers/platform/x86/intel_mid_thermal.c index c2f4bd8013b5..3a578323122b 100644 --- a/drivers/platform/x86/intel_mid_thermal.c +++ b/drivers/platform/x86/intel_mid_thermal.c | |||
@@ -37,49 +37,50 @@ | |||
37 | #include <asm/intel_scu_ipc.h> | 37 | #include <asm/intel_scu_ipc.h> |
38 | 38 | ||
39 | /* Number of thermal sensors */ | 39 | /* Number of thermal sensors */ |
40 | #define MSIC_THERMAL_SENSORS 4 | 40 | #define MSIC_THERMAL_SENSORS 4 |
41 | 41 | ||
42 | /* ADC1 - thermal registers */ | 42 | /* ADC1 - thermal registers */ |
43 | #define MSIC_THERM_ADC1CNTL1 0x1C0 | 43 | #define MSIC_THERM_ADC1CNTL1 0x1C0 |
44 | #define MSIC_ADC_ENBL 0x10 | 44 | #define MSIC_ADC_ENBL 0x10 |
45 | #define MSIC_ADC_START 0x08 | 45 | #define MSIC_ADC_START 0x08 |
46 | 46 | ||
47 | #define MSIC_THERM_ADC1CNTL3 0x1C2 | 47 | #define MSIC_THERM_ADC1CNTL3 0x1C2 |
48 | #define MSIC_ADCTHERM_ENBL 0x04 | 48 | #define MSIC_ADCTHERM_ENBL 0x04 |
49 | #define MSIC_ADCRRDATA_ENBL 0x05 | 49 | #define MSIC_ADCRRDATA_ENBL 0x05 |
50 | #define MSIC_CHANL_MASK_VAL 0x0F | 50 | #define MSIC_CHANL_MASK_VAL 0x0F |
51 | 51 | ||
52 | #define MSIC_STOPBIT_MASK 16 | 52 | #define MSIC_STOPBIT_MASK 16 |
53 | #define MSIC_ADCTHERM_MASK 4 | 53 | #define MSIC_ADCTHERM_MASK 4 |
54 | #define ADC_CHANLS_MAX 15 /* Number of ADC channels */ | 54 | /* Number of ADC channels */ |
55 | #define ADC_LOOP_MAX (ADC_CHANLS_MAX - MSIC_THERMAL_SENSORS) | 55 | #define ADC_CHANLS_MAX 15 |
56 | #define ADC_LOOP_MAX (ADC_CHANLS_MAX - MSIC_THERMAL_SENSORS) | ||
56 | 57 | ||
57 | /* ADC channel code values */ | 58 | /* ADC channel code values */ |
58 | #define SKIN_SENSOR0_CODE 0x08 | 59 | #define SKIN_SENSOR0_CODE 0x08 |
59 | #define SKIN_SENSOR1_CODE 0x09 | 60 | #define SKIN_SENSOR1_CODE 0x09 |
60 | #define SYS_SENSOR_CODE 0x0A | 61 | #define SYS_SENSOR_CODE 0x0A |
61 | #define MSIC_DIE_SENSOR_CODE 0x03 | 62 | #define MSIC_DIE_SENSOR_CODE 0x03 |
62 | 63 | ||
63 | #define SKIN_THERM_SENSOR0 0 | 64 | #define SKIN_THERM_SENSOR0 0 |
64 | #define SKIN_THERM_SENSOR1 1 | 65 | #define SKIN_THERM_SENSOR1 1 |
65 | #define SYS_THERM_SENSOR2 2 | 66 | #define SYS_THERM_SENSOR2 2 |
66 | #define MSIC_DIE_THERM_SENSOR3 3 | 67 | #define MSIC_DIE_THERM_SENSOR3 3 |
67 | 68 | ||
68 | /* ADC code range */ | 69 | /* ADC code range */ |
69 | #define ADC_MAX 977 | 70 | #define ADC_MAX 977 |
70 | #define ADC_MIN 162 | 71 | #define ADC_MIN 162 |
71 | #define ADC_VAL0C 887 | 72 | #define ADC_VAL0C 887 |
72 | #define ADC_VAL20C 720 | 73 | #define ADC_VAL20C 720 |
73 | #define ADC_VAL40C 508 | 74 | #define ADC_VAL40C 508 |
74 | #define ADC_VAL60C 315 | 75 | #define ADC_VAL60C 315 |
75 | 76 | ||
76 | /* ADC base addresses */ | 77 | /* ADC base addresses */ |
77 | #define ADC_CHNL_START_ADDR 0x1C5 /* increments by 1 */ | 78 | #define ADC_CHNL_START_ADDR 0x1C5 /* increments by 1 */ |
78 | #define ADC_DATA_START_ADDR 0x1D4 /* increments by 2 */ | 79 | #define ADC_DATA_START_ADDR 0x1D4 /* increments by 2 */ |
79 | 80 | ||
80 | /* MSIC die attributes */ | 81 | /* MSIC die attributes */ |
81 | #define MSIC_DIE_ADC_MIN 488 | 82 | #define MSIC_DIE_ADC_MIN 488 |
82 | #define MSIC_DIE_ADC_MAX 1004 | 83 | #define MSIC_DIE_ADC_MAX 1004 |
83 | 84 | ||
84 | /* This holds the address of the first free ADC channel, | 85 | /* This holds the address of the first free ADC channel, |
85 | * among the 15 channels | 86 | * among the 15 channels |
@@ -87,15 +88,15 @@ | |||
87 | static int channel_index; | 88 | static int channel_index; |
88 | 89 | ||
89 | struct platform_info { | 90 | struct platform_info { |
90 | struct platform_device *pdev; | 91 | struct platform_device *pdev; |
91 | struct thermal_zone_device *tzd[MSIC_THERMAL_SENSORS]; | 92 | struct thermal_zone_device *tzd[MSIC_THERMAL_SENSORS]; |
92 | }; | 93 | }; |
93 | 94 | ||
94 | struct thermal_device_info { | 95 | struct thermal_device_info { |
95 | unsigned int chnl_addr; | 96 | unsigned int chnl_addr; |
96 | int direct; | 97 | int direct; |
97 | /* This holds the current temperature in millidegree celsius */ | 98 | /* This holds the current temperature in millidegree celsius */ |
98 | long curr_temp; | 99 | long curr_temp; |
99 | }; | 100 | }; |
100 | 101 | ||
101 | /** | 102 | /** |
@@ -106,7 +107,7 @@ struct thermal_device_info { | |||
106 | */ | 107 | */ |
107 | static int to_msic_die_temp(uint16_t adc_val) | 108 | static int to_msic_die_temp(uint16_t adc_val) |
108 | { | 109 | { |
109 | return (368 * (adc_val) / 1000) - 220; | 110 | return (368 * (adc_val) / 1000) - 220; |
110 | } | 111 | } |
111 | 112 | ||
112 | /** | 113 | /** |
@@ -118,7 +119,7 @@ static int to_msic_die_temp(uint16_t adc_val) | |||
118 | */ | 119 | */ |
119 | static int is_valid_adc(uint16_t adc_val, uint16_t min, uint16_t max) | 120 | static int is_valid_adc(uint16_t adc_val, uint16_t min, uint16_t max) |
120 | { | 121 | { |
121 | return (adc_val >= min) && (adc_val <= max); | 122 | return (adc_val >= min) && (adc_val <= max); |
122 | } | 123 | } |
123 | 124 | ||
124 | /** | 125 | /** |
@@ -136,35 +137,35 @@ static int is_valid_adc(uint16_t adc_val, uint16_t min, uint16_t max) | |||
136 | */ | 137 | */ |
137 | static int adc_to_temp(int direct, uint16_t adc_val, unsigned long *tp) | 138 | static int adc_to_temp(int direct, uint16_t adc_val, unsigned long *tp) |
138 | { | 139 | { |
139 | int temp; | 140 | int temp; |
140 | 141 | ||
141 | /* Direct conversion for die temperature */ | 142 | /* Direct conversion for die temperature */ |
142 | if (direct) { | 143 | if (direct) { |
143 | if (is_valid_adc(adc_val, MSIC_DIE_ADC_MIN, MSIC_DIE_ADC_MAX)) { | 144 | if (is_valid_adc(adc_val, MSIC_DIE_ADC_MIN, MSIC_DIE_ADC_MAX)) { |
144 | *tp = to_msic_die_temp(adc_val) * 1000; | 145 | *tp = to_msic_die_temp(adc_val) * 1000; |
145 | return 0; | 146 | return 0; |
146 | } | 147 | } |
147 | return -ERANGE; | 148 | return -ERANGE; |
148 | } | 149 | } |
149 | 150 | ||
150 | if (!is_valid_adc(adc_val, ADC_MIN, ADC_MAX)) | 151 | if (!is_valid_adc(adc_val, ADC_MIN, ADC_MAX)) |
151 | return -ERANGE; | 152 | return -ERANGE; |
152 | 153 | ||
153 | /* Linear approximation for skin temperature */ | 154 | /* Linear approximation for skin temperature */ |
154 | if (adc_val > ADC_VAL0C) | 155 | if (adc_val > ADC_VAL0C) |
155 | temp = 177 - (adc_val/5); | 156 | temp = 177 - (adc_val/5); |
156 | else if ((adc_val <= ADC_VAL0C) && (adc_val > ADC_VAL20C)) | 157 | else if ((adc_val <= ADC_VAL0C) && (adc_val > ADC_VAL20C)) |
157 | temp = 111 - (adc_val/8); | 158 | temp = 111 - (adc_val/8); |
158 | else if ((adc_val <= ADC_VAL20C) && (adc_val > ADC_VAL40C)) | 159 | else if ((adc_val <= ADC_VAL20C) && (adc_val > ADC_VAL40C)) |
159 | temp = 92 - (adc_val/10); | 160 | temp = 92 - (adc_val/10); |
160 | else if ((adc_val <= ADC_VAL40C) && (adc_val > ADC_VAL60C)) | 161 | else if ((adc_val <= ADC_VAL40C) && (adc_val > ADC_VAL60C)) |
161 | temp = 91 - (adc_val/10); | 162 | temp = 91 - (adc_val/10); |
162 | else | 163 | else |
163 | temp = 112 - (adc_val/6); | 164 | temp = 112 - (adc_val/6); |
164 | 165 | ||
165 | /* Convert temperature in celsius to milli degree celsius */ | 166 | /* Convert temperature in celsius to milli degree celsius */ |
166 | *tp = temp * 1000; | 167 | *tp = temp * 1000; |
167 | return 0; | 168 | return 0; |
168 | } | 169 | } |
169 | 170 | ||
170 | /** | 171 | /** |
@@ -178,47 +179,47 @@ static int adc_to_temp(int direct, uint16_t adc_val, unsigned long *tp) | |||
178 | */ | 179 | */ |
179 | static int mid_read_temp(struct thermal_zone_device *tzd, unsigned long *temp) | 180 | static int mid_read_temp(struct thermal_zone_device *tzd, unsigned long *temp) |
180 | { | 181 | { |
181 | struct thermal_device_info *td_info = tzd->devdata; | 182 | struct thermal_device_info *td_info = tzd->devdata; |
182 | uint16_t adc_val, addr; | 183 | uint16_t adc_val, addr; |
183 | uint8_t data = 0; | 184 | uint8_t data = 0; |
184 | int ret; | 185 | int ret; |
185 | unsigned long curr_temp; | 186 | unsigned long curr_temp; |
186 | 187 | ||
187 | 188 | ||
188 | addr = td_info->chnl_addr; | 189 | addr = td_info->chnl_addr; |
189 | 190 | ||
190 | /* Enable the msic for conversion before reading */ | 191 | /* Enable the msic for conversion before reading */ |
191 | ret = intel_scu_ipc_iowrite8(MSIC_THERM_ADC1CNTL3, MSIC_ADCRRDATA_ENBL); | 192 | ret = intel_scu_ipc_iowrite8(MSIC_THERM_ADC1CNTL3, MSIC_ADCRRDATA_ENBL); |
192 | if (ret) | 193 | if (ret) |
193 | return ret; | 194 | return ret; |
194 | 195 | ||
195 | /* Re-toggle the RRDATARD bit (temporary workaround) */ | 196 | /* Re-toggle the RRDATARD bit (temporary workaround) */ |
196 | ret = intel_scu_ipc_iowrite8(MSIC_THERM_ADC1CNTL3, MSIC_ADCTHERM_ENBL); | 197 | ret = intel_scu_ipc_iowrite8(MSIC_THERM_ADC1CNTL3, MSIC_ADCTHERM_ENBL); |
197 | if (ret) | 198 | if (ret) |
198 | return ret; | 199 | return ret; |
199 | 200 | ||
200 | /* Read the higher bits of data */ | 201 | /* Read the higher bits of data */ |
201 | ret = intel_scu_ipc_ioread8(addr, &data); | 202 | ret = intel_scu_ipc_ioread8(addr, &data); |
202 | if (ret) | 203 | if (ret) |
203 | return ret; | 204 | return ret; |
204 | 205 | ||
205 | /* Shift bits to accommodate the lower two data bits */ | 206 | /* Shift bits to accommodate the lower two data bits */ |
206 | adc_val = (data << 2); | 207 | adc_val = (data << 2); |
207 | addr++; | 208 | addr++; |
208 | 209 | ||
209 | ret = intel_scu_ipc_ioread8(addr, &data);/* Read lower bits */ | 210 | ret = intel_scu_ipc_ioread8(addr, &data);/* Read lower bits */ |
210 | if (ret) | 211 | if (ret) |
211 | return ret; | 212 | return ret; |
212 | 213 | ||
213 | /* Adding lower two bits to the higher bits */ | 214 | /* Adding lower two bits to the higher bits */ |
214 | data &= 03; | 215 | data &= 03; |
215 | adc_val += data; | 216 | adc_val += data; |
216 | 217 | ||
217 | /* Convert ADC value to temperature */ | 218 | /* Convert ADC value to temperature */ |
218 | ret = adc_to_temp(td_info->direct, adc_val, &curr_temp); | 219 | ret = adc_to_temp(td_info->direct, adc_val, &curr_temp); |
219 | if (ret == 0) | 220 | if (ret == 0) |
220 | *temp = td_info->curr_temp = curr_temp; | 221 | *temp = td_info->curr_temp = curr_temp; |
221 | return ret; | 222 | return ret; |
222 | } | 223 | } |
223 | 224 | ||
224 | /** | 225 | /** |
@@ -231,22 +232,21 @@ static int mid_read_temp(struct thermal_zone_device *tzd, unsigned long *temp) | |||
231 | */ | 232 | */ |
232 | static int configure_adc(int val) | 233 | static int configure_adc(int val) |
233 | { | 234 | { |
234 | int ret; | 235 | int ret; |
235 | uint8_t data; | 236 | uint8_t data; |
236 | 237 | ||
237 | ret = intel_scu_ipc_ioread8(MSIC_THERM_ADC1CNTL1, &data); | 238 | ret = intel_scu_ipc_ioread8(MSIC_THERM_ADC1CNTL1, &data); |
238 | if (ret) | 239 | if (ret) |
239 | return ret; | 240 | return ret; |
240 | 241 | ||
241 | if (val) { | 242 | if (val) { |
242 | /* Enable and start the ADC */ | 243 | /* Enable and start the ADC */ |
243 | data |= (MSIC_ADC_ENBL | MSIC_ADC_START); | 244 | data |= (MSIC_ADC_ENBL | MSIC_ADC_START); |
244 | } else { | 245 | } else { |
245 | /* Just stop the ADC */ | 246 | /* Just stop the ADC */ |
246 | data &= (~MSIC_ADC_START); | 247 | data &= (~MSIC_ADC_START); |
247 | } | 248 | } |
248 | 249 | return intel_scu_ipc_iowrite8(MSIC_THERM_ADC1CNTL1, data); | |
249 | return intel_scu_ipc_iowrite8(MSIC_THERM_ADC1CNTL1, data); | ||
250 | } | 250 | } |
251 | 251 | ||
252 | /** | 252 | /** |
@@ -259,30 +259,30 @@ static int configure_adc(int val) | |||
259 | */ | 259 | */ |
260 | static int set_up_therm_channel(u16 base_addr) | 260 | static int set_up_therm_channel(u16 base_addr) |
261 | { | 261 | { |
262 | int ret; | 262 | int ret; |
263 | 263 | ||
264 | /* Enable all the sensor channels */ | 264 | /* Enable all the sensor channels */ |
265 | ret = intel_scu_ipc_iowrite8(base_addr, SKIN_SENSOR0_CODE); | 265 | ret = intel_scu_ipc_iowrite8(base_addr, SKIN_SENSOR0_CODE); |
266 | if (ret) | 266 | if (ret) |
267 | return ret; | 267 | return ret; |
268 | 268 | ||
269 | ret = intel_scu_ipc_iowrite8(base_addr + 1, SKIN_SENSOR1_CODE); | 269 | ret = intel_scu_ipc_iowrite8(base_addr + 1, SKIN_SENSOR1_CODE); |
270 | if (ret) | 270 | if (ret) |
271 | return ret; | 271 | return ret; |
272 | 272 | ||
273 | ret = intel_scu_ipc_iowrite8(base_addr + 2, SYS_SENSOR_CODE); | 273 | ret = intel_scu_ipc_iowrite8(base_addr + 2, SYS_SENSOR_CODE); |
274 | if (ret) | 274 | if (ret) |
275 | return ret; | 275 | return ret; |
276 | 276 | ||
277 | /* Since this is the last channel, set the stop bit | 277 | /* Since this is the last channel, set the stop bit |
278 | to 1 by ORing the DIE_SENSOR_CODE with 0x10 */ | 278 | * to 1 by ORing the DIE_SENSOR_CODE with 0x10 */ |
279 | ret = intel_scu_ipc_iowrite8(base_addr + 3, | 279 | ret = intel_scu_ipc_iowrite8(base_addr + 3, |
280 | (MSIC_DIE_SENSOR_CODE | 0x10)); | 280 | (MSIC_DIE_SENSOR_CODE | 0x10)); |
281 | if (ret) | 281 | if (ret) |
282 | return ret; | 282 | return ret; |
283 | 283 | ||
284 | /* Enable ADC and start it */ | 284 | /* Enable ADC and start it */ |
285 | return configure_adc(1); | 285 | return configure_adc(1); |
286 | } | 286 | } |
287 | 287 | ||
288 | /** | 288 | /** |
@@ -293,13 +293,13 @@ static int set_up_therm_channel(u16 base_addr) | |||
293 | */ | 293 | */ |
294 | static int reset_stopbit(uint16_t addr) | 294 | static int reset_stopbit(uint16_t addr) |
295 | { | 295 | { |
296 | int ret; | 296 | int ret; |
297 | uint8_t data; | 297 | uint8_t data; |
298 | ret = intel_scu_ipc_ioread8(addr, &data); | 298 | ret = intel_scu_ipc_ioread8(addr, &data); |
299 | if (ret) | 299 | if (ret) |
300 | return ret; | 300 | return ret; |
301 | /* Set the stop bit to zero */ | 301 | /* Set the stop bit to zero */ |
302 | return intel_scu_ipc_iowrite8(addr, (data & 0xEF)); | 302 | return intel_scu_ipc_iowrite8(addr, (data & 0xEF)); |
303 | } | 303 | } |
304 | 304 | ||
305 | /** | 305 | /** |
@@ -317,30 +317,30 @@ static int reset_stopbit(uint16_t addr) | |||
317 | */ | 317 | */ |
318 | static int find_free_channel(void) | 318 | static int find_free_channel(void) |
319 | { | 319 | { |
320 | int ret; | 320 | int ret; |
321 | int i; | 321 | int i; |
322 | uint8_t data; | 322 | uint8_t data; |
323 | 323 | ||
324 | /* check whether ADC is enabled */ | 324 | /* check whether ADC is enabled */ |
325 | ret = intel_scu_ipc_ioread8(MSIC_THERM_ADC1CNTL1, &data); | 325 | ret = intel_scu_ipc_ioread8(MSIC_THERM_ADC1CNTL1, &data); |
326 | if (ret) | 326 | if (ret) |
327 | return ret; | 327 | return ret; |
328 | 328 | ||
329 | if ((data & MSIC_ADC_ENBL) == 0) | 329 | if ((data & MSIC_ADC_ENBL) == 0) |
330 | return 0; | 330 | return 0; |
331 | 331 | ||
332 | /* ADC is already enabled; Looking for an empty channel */ | 332 | /* ADC is already enabled; Looking for an empty channel */ |
333 | for (i = 0; i < ADC_CHANLS_MAX; i++) { | 333 | for (i = 0; i < ADC_CHANLS_MAX; i++) { |
334 | ret = intel_scu_ipc_ioread8(ADC_CHNL_START_ADDR + i, &data); | 334 | ret = intel_scu_ipc_ioread8(ADC_CHNL_START_ADDR + i, &data); |
335 | if (ret) | 335 | if (ret) |
336 | return ret; | 336 | return ret; |
337 | 337 | ||
338 | if (data & MSIC_STOPBIT_MASK) { | 338 | if (data & MSIC_STOPBIT_MASK) { |
339 | ret = i; | 339 | ret = i; |
340 | break; | 340 | break; |
341 | } | 341 | } |
342 | } | 342 | } |
343 | return (ret > ADC_LOOP_MAX) ? (-EINVAL) : ret; | 343 | return (ret > ADC_LOOP_MAX) ? (-EINVAL) : ret; |
344 | } | 344 | } |
345 | 345 | ||
346 | /** | 346 | /** |
@@ -351,48 +351,48 @@ static int find_free_channel(void) | |||
351 | */ | 351 | */ |
352 | static int mid_initialize_adc(struct device *dev) | 352 | static int mid_initialize_adc(struct device *dev) |
353 | { | 353 | { |
354 | u8 data; | 354 | u8 data; |
355 | u16 base_addr; | 355 | u16 base_addr; |
356 | int ret; | 356 | int ret; |
357 | 357 | ||
358 | /* | 358 | /* |
359 | * Ensure that adctherm is disabled before we | 359 | * Ensure that adctherm is disabled before we |
360 | * initialize the ADC | 360 | * initialize the ADC |
361 | */ | 361 | */ |
362 | ret = intel_scu_ipc_ioread8(MSIC_THERM_ADC1CNTL3, &data); | 362 | ret = intel_scu_ipc_ioread8(MSIC_THERM_ADC1CNTL3, &data); |
363 | if (ret) | 363 | if (ret) |
364 | return ret; | 364 | return ret; |
365 | 365 | ||
366 | if (data & MSIC_ADCTHERM_MASK) | 366 | if (data & MSIC_ADCTHERM_MASK) |
367 | dev_warn(dev, "ADCTHERM already set"); | 367 | dev_warn(dev, "ADCTHERM already set"); |
368 | 368 | ||
369 | /* Index of the first channel in which the stop bit is set */ | 369 | /* Index of the first channel in which the stop bit is set */ |
370 | channel_index = find_free_channel(); | 370 | channel_index = find_free_channel(); |
371 | if (channel_index < 0) { | 371 | if (channel_index < 0) { |
372 | dev_err(dev, "No free ADC channels"); | 372 | dev_err(dev, "No free ADC channels"); |
373 | return channel_index; | 373 | return channel_index; |
374 | } | 374 | } |
375 | 375 | ||
376 | base_addr = ADC_CHNL_START_ADDR + channel_index; | 376 | base_addr = ADC_CHNL_START_ADDR + channel_index; |
377 | 377 | ||
378 | if (!(channel_index == 0 || channel_index == ADC_LOOP_MAX)) { | 378 | if (!(channel_index == 0 || channel_index == ADC_LOOP_MAX)) { |
379 | /* Reset stop bit for channels other than 0 and 12 */ | 379 | /* Reset stop bit for channels other than 0 and 12 */ |
380 | ret = reset_stopbit(base_addr); | 380 | ret = reset_stopbit(base_addr); |
381 | if (ret) | 381 | if (ret) |
382 | return ret; | 382 | return ret; |
383 | 383 | ||
384 | /* Index of the first free channel */ | 384 | /* Index of the first free channel */ |
385 | base_addr++; | 385 | base_addr++; |
386 | channel_index++; | 386 | channel_index++; |
387 | } | 387 | } |
388 | 388 | ||
389 | ret = set_up_therm_channel(base_addr); | 389 | ret = set_up_therm_channel(base_addr); |
390 | if (ret) { | 390 | if (ret) { |
391 | dev_err(dev, "unable to enable ADC"); | 391 | dev_err(dev, "unable to enable ADC"); |
392 | return ret; | 392 | return ret; |
393 | } | 393 | } |
394 | dev_dbg(dev, "ADC initialization successful"); | 394 | dev_dbg(dev, "ADC initialization successful"); |
395 | return ret; | 395 | return ret; |
396 | } | 396 | } |
397 | 397 | ||
398 | /** | 398 | /** |
@@ -403,18 +403,18 @@ static int mid_initialize_adc(struct device *dev) | |||
403 | */ | 403 | */ |
404 | static struct thermal_device_info *initialize_sensor(int index) | 404 | static struct thermal_device_info *initialize_sensor(int index) |
405 | { | 405 | { |
406 | struct thermal_device_info *td_info = | 406 | struct thermal_device_info *td_info = |
407 | kzalloc(sizeof(struct thermal_device_info), GFP_KERNEL); | 407 | kzalloc(sizeof(struct thermal_device_info), GFP_KERNEL); |
408 | 408 | ||
409 | if (!td_info) | 409 | if (!td_info) |
410 | return NULL; | 410 | return NULL; |
411 | 411 | ||
412 | /* Set the base addr of the channel for this sensor */ | 412 | /* Set the base addr of the channel for this sensor */ |
413 | td_info->chnl_addr = ADC_DATA_START_ADDR + 2 * (channel_index + index); | 413 | td_info->chnl_addr = ADC_DATA_START_ADDR + 2 * (channel_index + index); |
414 | /* Sensor 3 is direct conversion */ | 414 | /* Sensor 3 is direct conversion */ |
415 | if (index == 3) | 415 | if (index == 3) |
416 | td_info->direct = 1; | 416 | td_info->direct = 1; |
417 | return td_info; | 417 | return td_info; |
418 | } | 418 | } |
419 | 419 | ||
420 | /** | 420 | /** |
@@ -425,7 +425,7 @@ static struct thermal_device_info *initialize_sensor(int index) | |||
425 | */ | 425 | */ |
426 | static int mid_thermal_resume(struct platform_device *pdev) | 426 | static int mid_thermal_resume(struct platform_device *pdev) |
427 | { | 427 | { |
428 | return mid_initialize_adc(&pdev->dev); | 428 | return mid_initialize_adc(&pdev->dev); |
429 | } | 429 | } |
430 | 430 | ||
431 | /** | 431 | /** |
@@ -437,12 +437,12 @@ static int mid_thermal_resume(struct platform_device *pdev) | |||
437 | */ | 437 | */ |
438 | static int mid_thermal_suspend(struct platform_device *pdev, pm_message_t mesg) | 438 | static int mid_thermal_suspend(struct platform_device *pdev, pm_message_t mesg) |
439 | { | 439 | { |
440 | /* | 440 | /* |
441 | * This just stops the ADC and does not disable it. | 441 | * This just stops the ADC and does not disable it. |
442 | * temporary workaround until we have a generic ADC driver. | 442 | * temporary workaround until we have a generic ADC driver. |
443 | * If 0 is passed, it disables the ADC. | 443 | * If 0 is passed, it disables the ADC. |
444 | */ | 444 | */ |
445 | return configure_adc(0); | 445 | return configure_adc(0); |
446 | } | 446 | } |
447 | 447 | ||
448 | /** | 448 | /** |
@@ -453,16 +453,15 @@ static int mid_thermal_suspend(struct platform_device *pdev, pm_message_t mesg) | |||
453 | */ | 453 | */ |
454 | static int read_curr_temp(struct thermal_zone_device *tzd, unsigned long *temp) | 454 | static int read_curr_temp(struct thermal_zone_device *tzd, unsigned long *temp) |
455 | { | 455 | { |
456 | WARN_ON(tzd == NULL); | 456 | WARN_ON(tzd == NULL); |
457 | return mid_read_temp(tzd, temp); | 457 | return mid_read_temp(tzd, temp); |
458 | } | 458 | } |
459 | 459 | ||
460 | /* Can't be const */ | 460 | /* Can't be const */ |
461 | static struct thermal_zone_device_ops tzd_ops = { | 461 | static struct thermal_zone_device_ops tzd_ops = { |
462 | .get_temp = read_curr_temp, | 462 | .get_temp = read_curr_temp, |
463 | }; | 463 | }; |
464 | 464 | ||
465 | |||
466 | /** | 465 | /** |
467 | * mid_thermal_probe - mfld thermal initialize | 466 | * mid_thermal_probe - mfld thermal initialize |
468 | * @pdev: platform device structure | 467 | * @pdev: platform device structure |
@@ -472,46 +471,45 @@ static struct thermal_zone_device_ops tzd_ops = { | |||
472 | */ | 471 | */ |
473 | static int mid_thermal_probe(struct platform_device *pdev) | 472 | static int mid_thermal_probe(struct platform_device *pdev) |
474 | { | 473 | { |
475 | static char *name[MSIC_THERMAL_SENSORS] = { | 474 | static char *name[MSIC_THERMAL_SENSORS] = { |
476 | "skin0", "skin1", "sys", "msicdie" | 475 | "skin0", "skin1", "sys", "msicdie" |
477 | }; | 476 | }; |
478 | 477 | ||
479 | int ret; | 478 | int ret; |
480 | int i; | 479 | int i; |
481 | struct platform_info *pinfo; | 480 | struct platform_info *pinfo; |
482 | 481 | ||
483 | pinfo = kzalloc(sizeof(struct platform_info), GFP_KERNEL); | 482 | pinfo = kzalloc(sizeof(struct platform_info), GFP_KERNEL); |
484 | if (!pinfo) | 483 | if (!pinfo) |
485 | return -ENOMEM; | 484 | return -ENOMEM; |
486 | 485 | ||
487 | /* Initializing the hardware */ | 486 | /* Initializing the hardware */ |
488 | ret = mid_initialize_adc(&pdev->dev); | 487 | ret = mid_initialize_adc(&pdev->dev); |
489 | if (ret) { | 488 | if (ret) { |
490 | dev_err(&pdev->dev, "ADC init failed"); | 489 | dev_err(&pdev->dev, "ADC init failed"); |
491 | kfree(pinfo); | 490 | kfree(pinfo); |
492 | return ret; | 491 | return ret; |
493 | } | 492 | } |
494 | 493 | ||
495 | /* Register each sensor with the generic thermal framework*/ | 494 | /* Register each sensor with the generic thermal framework*/ |
496 | for (i = 0; i < MSIC_THERMAL_SENSORS; i++) { | 495 | for (i = 0; i < MSIC_THERMAL_SENSORS; i++) { |
497 | pinfo->tzd[i] = thermal_zone_device_register(name[i], | 496 | pinfo->tzd[i] = thermal_zone_device_register(name[i], |
498 | 0, initialize_sensor(i), | 497 | 0, initialize_sensor(i), &tzd_ops, 0, 0, 0, 0); |
499 | &tzd_ops, 0, 0, 0, 0); | 498 | if (IS_ERR(pinfo->tzd[i])) |
500 | if (IS_ERR(pinfo->tzd[i])) | 499 | goto reg_fail; |
501 | goto reg_fail; | 500 | } |
502 | } | 501 | |
503 | 502 | pinfo->pdev = pdev; | |
504 | pinfo->pdev = pdev; | 503 | platform_set_drvdata(pdev, pinfo); |
505 | platform_set_drvdata(pdev, pinfo); | 504 | return 0; |
506 | return 0; | ||
507 | 505 | ||
508 | reg_fail: | 506 | reg_fail: |
509 | ret = PTR_ERR(pinfo->tzd[i]); | 507 | ret = PTR_ERR(pinfo->tzd[i]); |
510 | while (--i >= 0) | 508 | while (--i >= 0) |
511 | thermal_zone_device_unregister(pinfo->tzd[i]); | 509 | thermal_zone_device_unregister(pinfo->tzd[i]); |
512 | configure_adc(0); | 510 | configure_adc(0); |
513 | kfree(pinfo); | 511 | kfree(pinfo); |
514 | return ret; | 512 | return ret; |
515 | } | 513 | } |
516 | 514 | ||
517 | /** | 515 | /** |
@@ -523,49 +521,46 @@ reg_fail: | |||
523 | */ | 521 | */ |
524 | static int mid_thermal_remove(struct platform_device *pdev) | 522 | static int mid_thermal_remove(struct platform_device *pdev) |
525 | { | 523 | { |
526 | int i; | 524 | int i; |
527 | struct platform_info *pinfo = platform_get_drvdata(pdev); | 525 | struct platform_info *pinfo = platform_get_drvdata(pdev); |
528 | 526 | ||
529 | for (i = 0; i < MSIC_THERMAL_SENSORS; i++) | 527 | for (i = 0; i < MSIC_THERMAL_SENSORS; i++) |
530 | thermal_zone_device_unregister(pinfo->tzd[i]); | 528 | thermal_zone_device_unregister(pinfo->tzd[i]); |
531 | 529 | ||
532 | platform_set_drvdata(pdev, NULL); | 530 | kfree(pinfo); |
531 | platform_set_drvdata(pdev, NULL); | ||
533 | 532 | ||
534 | /* Stop the ADC */ | 533 | /* Stop the ADC */ |
535 | return configure_adc(0); | 534 | return configure_adc(0); |
536 | } | 535 | } |
537 | 536 | ||
538 | /********************************************************************* | ||
539 | * Driver initialisation and finalization | ||
540 | *********************************************************************/ | ||
541 | |||
542 | #define DRIVER_NAME "msic_sensor" | 537 | #define DRIVER_NAME "msic_sensor" |
543 | 538 | ||
544 | static const struct platform_device_id therm_id_table[] = { | 539 | static const struct platform_device_id therm_id_table[] = { |
545 | { DRIVER_NAME, 1 }, | 540 | { DRIVER_NAME, 1 }, |
546 | { } | 541 | { } |
547 | }; | 542 | }; |
548 | 543 | ||
549 | static struct platform_driver mid_thermal_driver = { | 544 | static struct platform_driver mid_thermal_driver = { |
550 | .driver = { | 545 | .driver = { |
551 | .name = DRIVER_NAME, | 546 | .name = DRIVER_NAME, |
552 | .owner = THIS_MODULE, | 547 | .owner = THIS_MODULE, |
553 | }, | 548 | }, |
554 | .probe = mid_thermal_probe, | 549 | .probe = mid_thermal_probe, |
555 | .suspend = mid_thermal_suspend, | 550 | .suspend = mid_thermal_suspend, |
556 | .resume = mid_thermal_resume, | 551 | .resume = mid_thermal_resume, |
557 | .remove = __devexit_p(mid_thermal_remove), | 552 | .remove = __devexit_p(mid_thermal_remove), |
558 | .id_table = therm_id_table, | 553 | .id_table = therm_id_table, |
559 | }; | 554 | }; |
560 | 555 | ||
561 | static int __init mid_thermal_module_init(void) | 556 | static int __init mid_thermal_module_init(void) |
562 | { | 557 | { |
563 | return platform_driver_register(&mid_thermal_driver); | 558 | return platform_driver_register(&mid_thermal_driver); |
564 | } | 559 | } |
565 | 560 | ||
566 | static void __exit mid_thermal_module_exit(void) | 561 | static void __exit mid_thermal_module_exit(void) |
567 | { | 562 | { |
568 | platform_driver_unregister(&mid_thermal_driver); | 563 | platform_driver_unregister(&mid_thermal_driver); |
569 | } | 564 | } |
570 | 565 | ||
571 | module_init(mid_thermal_module_init); | 566 | module_init(mid_thermal_module_init); |
diff --git a/drivers/platform/x86/intel_oaktrail.c b/drivers/platform/x86/intel_oaktrail.c new file mode 100644 index 000000000000..e936364a609d --- /dev/null +++ b/drivers/platform/x86/intel_oaktrail.c | |||
@@ -0,0 +1,396 @@ | |||
1 | /* | ||
2 | * intel_oaktrail.c - Intel OakTrail Platform support. | ||
3 | * | ||
4 | * Copyright (C) 2010-2011 Intel Corporation | ||
5 | * Author: Yin Kangkai (kangkai.yin@intel.com) | ||
6 | * | ||
7 | * based on Compal driver, Copyright (C) 2008 Cezary Jackiewicz | ||
8 | * <cezary.jackiewicz (at) gmail.com>, based on MSI driver | ||
9 | * Copyright (C) 2006 Lennart Poettering <mzxreary (at) 0pointer (dot) de> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, but | ||
17 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
19 | * General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program; if not, write to the Free Software | ||
23 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
24 | * 02110-1301, USA. | ||
25 | * | ||
26 | * This driver does below things: | ||
27 | * 1. registers itself in the Linux backlight control in | ||
28 | * /sys/class/backlight/intel_oaktrail/ | ||
29 | * | ||
30 | * 2. registers in the rfkill subsystem here: /sys/class/rfkill/rfkillX/ | ||
31 | * for these components: wifi, bluetooth, wwan (3g), gps | ||
32 | * | ||
33 | * This driver might work on other products based on Oaktrail. If you | ||
34 | * want to try it you can pass force=1 as argument to the module which | ||
35 | * will force it to load even when the DMI data doesn't identify the | ||
36 | * product as compatible. | ||
37 | */ | ||
38 | |||
39 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
40 | |||
41 | #include <linux/module.h> | ||
42 | #include <linux/kernel.h> | ||
43 | #include <linux/init.h> | ||
44 | #include <linux/acpi.h> | ||
45 | #include <linux/fb.h> | ||
46 | #include <linux/mutex.h> | ||
47 | #include <linux/err.h> | ||
48 | #include <linux/i2c.h> | ||
49 | #include <linux/backlight.h> | ||
50 | #include <linux/platform_device.h> | ||
51 | #include <linux/dmi.h> | ||
52 | #include <linux/rfkill.h> | ||
53 | #include <acpi/acpi_bus.h> | ||
54 | #include <acpi/acpi_drivers.h> | ||
55 | |||
56 | |||
57 | #define DRIVER_NAME "intel_oaktrail" | ||
58 | #define DRIVER_VERSION "0.4ac1" | ||
59 | |||
60 | /* | ||
61 | * This is the devices status address in EC space, and the control bits | ||
62 | * definition: | ||
63 | * | ||
64 | * (1 << 0): Camera enable/disable, RW. | ||
65 | * (1 << 1): Bluetooth enable/disable, RW. | ||
66 | * (1 << 2): GPS enable/disable, RW. | ||
67 | * (1 << 3): WiFi enable/disable, RW. | ||
68 | * (1 << 4): WWAN (3G) enable/disalbe, RW. | ||
69 | * (1 << 5): Touchscreen enable/disable, Read Only. | ||
70 | */ | ||
71 | #define OT_EC_DEVICE_STATE_ADDRESS 0xD6 | ||
72 | |||
73 | #define OT_EC_CAMERA_MASK (1 << 0) | ||
74 | #define OT_EC_BT_MASK (1 << 1) | ||
75 | #define OT_EC_GPS_MASK (1 << 2) | ||
76 | #define OT_EC_WIFI_MASK (1 << 3) | ||
77 | #define OT_EC_WWAN_MASK (1 << 4) | ||
78 | #define OT_EC_TS_MASK (1 << 5) | ||
79 | |||
80 | /* | ||
81 | * This is the address in EC space and commands used to control LCD backlight: | ||
82 | * | ||
83 | * Two steps needed to change the LCD backlight: | ||
84 | * 1. write the backlight percentage into OT_EC_BL_BRIGHTNESS_ADDRESS; | ||
85 | * 2. write OT_EC_BL_CONTROL_ON_DATA into OT_EC_BL_CONTROL_ADDRESS. | ||
86 | * | ||
87 | * To read the LCD back light, just read out the value from | ||
88 | * OT_EC_BL_BRIGHTNESS_ADDRESS. | ||
89 | * | ||
90 | * LCD backlight brightness range: 0 - 100 (OT_EC_BL_BRIGHTNESS_MAX) | ||
91 | */ | ||
92 | #define OT_EC_BL_BRIGHTNESS_ADDRESS 0x44 | ||
93 | #define OT_EC_BL_BRIGHTNESS_MAX 100 | ||
94 | #define OT_EC_BL_CONTROL_ADDRESS 0x3A | ||
95 | #define OT_EC_BL_CONTROL_ON_DATA 0x1A | ||
96 | |||
97 | |||
98 | static int force; | ||
99 | module_param(force, bool, 0); | ||
100 | MODULE_PARM_DESC(force, "Force driver load, ignore DMI data"); | ||
101 | |||
102 | static struct platform_device *oaktrail_device; | ||
103 | static struct backlight_device *oaktrail_bl_device; | ||
104 | static struct rfkill *bt_rfkill; | ||
105 | static struct rfkill *gps_rfkill; | ||
106 | static struct rfkill *wifi_rfkill; | ||
107 | static struct rfkill *wwan_rfkill; | ||
108 | |||
109 | |||
110 | /* rfkill */ | ||
111 | static int oaktrail_rfkill_set(void *data, bool blocked) | ||
112 | { | ||
113 | u8 value; | ||
114 | u8 result; | ||
115 | unsigned long radio = (unsigned long) data; | ||
116 | |||
117 | ec_read(OT_EC_DEVICE_STATE_ADDRESS, &result); | ||
118 | |||
119 | if (!blocked) | ||
120 | value = (u8) (result | radio); | ||
121 | else | ||
122 | value = (u8) (result & ~radio); | ||
123 | |||
124 | ec_write(OT_EC_DEVICE_STATE_ADDRESS, value); | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static const struct rfkill_ops oaktrail_rfkill_ops = { | ||
130 | .set_block = oaktrail_rfkill_set, | ||
131 | }; | ||
132 | |||
133 | static struct rfkill *oaktrail_rfkill_new(char *name, enum rfkill_type type, | ||
134 | unsigned long mask) | ||
135 | { | ||
136 | struct rfkill *rfkill_dev; | ||
137 | u8 value; | ||
138 | int err; | ||
139 | |||
140 | rfkill_dev = rfkill_alloc(name, &oaktrail_device->dev, type, | ||
141 | &oaktrail_rfkill_ops, (void *)mask); | ||
142 | if (!rfkill_dev) | ||
143 | return ERR_PTR(-ENOMEM); | ||
144 | |||
145 | ec_read(OT_EC_DEVICE_STATE_ADDRESS, &value); | ||
146 | rfkill_init_sw_state(rfkill_dev, (value & mask) != 1); | ||
147 | |||
148 | err = rfkill_register(rfkill_dev); | ||
149 | if (err) { | ||
150 | rfkill_destroy(rfkill_dev); | ||
151 | return ERR_PTR(err); | ||
152 | } | ||
153 | |||
154 | return rfkill_dev; | ||
155 | } | ||
156 | |||
157 | static inline void __oaktrail_rfkill_cleanup(struct rfkill *rf) | ||
158 | { | ||
159 | if (rf) { | ||
160 | rfkill_unregister(rf); | ||
161 | rfkill_destroy(rf); | ||
162 | } | ||
163 | } | ||
164 | |||
165 | static void oaktrail_rfkill_cleanup(void) | ||
166 | { | ||
167 | __oaktrail_rfkill_cleanup(wifi_rfkill); | ||
168 | __oaktrail_rfkill_cleanup(bt_rfkill); | ||
169 | __oaktrail_rfkill_cleanup(gps_rfkill); | ||
170 | __oaktrail_rfkill_cleanup(wwan_rfkill); | ||
171 | } | ||
172 | |||
173 | static int oaktrail_rfkill_init(void) | ||
174 | { | ||
175 | int ret; | ||
176 | |||
177 | wifi_rfkill = oaktrail_rfkill_new("oaktrail-wifi", | ||
178 | RFKILL_TYPE_WLAN, | ||
179 | OT_EC_WIFI_MASK); | ||
180 | if (IS_ERR(wifi_rfkill)) { | ||
181 | ret = PTR_ERR(wifi_rfkill); | ||
182 | wifi_rfkill = NULL; | ||
183 | goto cleanup; | ||
184 | } | ||
185 | |||
186 | bt_rfkill = oaktrail_rfkill_new("oaktrail-bluetooth", | ||
187 | RFKILL_TYPE_BLUETOOTH, | ||
188 | OT_EC_BT_MASK); | ||
189 | if (IS_ERR(bt_rfkill)) { | ||
190 | ret = PTR_ERR(bt_rfkill); | ||
191 | bt_rfkill = NULL; | ||
192 | goto cleanup; | ||
193 | } | ||
194 | |||
195 | gps_rfkill = oaktrail_rfkill_new("oaktrail-gps", | ||
196 | RFKILL_TYPE_GPS, | ||
197 | OT_EC_GPS_MASK); | ||
198 | if (IS_ERR(gps_rfkill)) { | ||
199 | ret = PTR_ERR(gps_rfkill); | ||
200 | gps_rfkill = NULL; | ||
201 | goto cleanup; | ||
202 | } | ||
203 | |||
204 | wwan_rfkill = oaktrail_rfkill_new("oaktrail-wwan", | ||
205 | RFKILL_TYPE_WWAN, | ||
206 | OT_EC_WWAN_MASK); | ||
207 | if (IS_ERR(wwan_rfkill)) { | ||
208 | ret = PTR_ERR(wwan_rfkill); | ||
209 | wwan_rfkill = NULL; | ||
210 | goto cleanup; | ||
211 | } | ||
212 | |||
213 | return 0; | ||
214 | |||
215 | cleanup: | ||
216 | oaktrail_rfkill_cleanup(); | ||
217 | return ret; | ||
218 | } | ||
219 | |||
220 | |||
221 | /* backlight */ | ||
222 | static int get_backlight_brightness(struct backlight_device *b) | ||
223 | { | ||
224 | u8 value; | ||
225 | ec_read(OT_EC_BL_BRIGHTNESS_ADDRESS, &value); | ||
226 | |||
227 | return value; | ||
228 | } | ||
229 | |||
230 | static int set_backlight_brightness(struct backlight_device *b) | ||
231 | { | ||
232 | u8 percent = (u8) b->props.brightness; | ||
233 | if (percent < 0 || percent > OT_EC_BL_BRIGHTNESS_MAX) | ||
234 | return -EINVAL; | ||
235 | |||
236 | ec_write(OT_EC_BL_BRIGHTNESS_ADDRESS, percent); | ||
237 | ec_write(OT_EC_BL_CONTROL_ADDRESS, OT_EC_BL_CONTROL_ON_DATA); | ||
238 | |||
239 | return 0; | ||
240 | } | ||
241 | |||
242 | static const struct backlight_ops oaktrail_bl_ops = { | ||
243 | .get_brightness = get_backlight_brightness, | ||
244 | .update_status = set_backlight_brightness, | ||
245 | }; | ||
246 | |||
247 | static int oaktrail_backlight_init(void) | ||
248 | { | ||
249 | struct backlight_device *bd; | ||
250 | struct backlight_properties props; | ||
251 | |||
252 | memset(&props, 0, sizeof(struct backlight_properties)); | ||
253 | props.max_brightness = OT_EC_BL_BRIGHTNESS_MAX; | ||
254 | bd = backlight_device_register(DRIVER_NAME, | ||
255 | &oaktrail_device->dev, NULL, | ||
256 | &oaktrail_bl_ops, | ||
257 | &props); | ||
258 | |||
259 | if (IS_ERR(bd)) { | ||
260 | oaktrail_bl_device = NULL; | ||
261 | pr_warning("Unable to register backlight device\n"); | ||
262 | return PTR_ERR(bd); | ||
263 | } | ||
264 | |||
265 | oaktrail_bl_device = bd; | ||
266 | |||
267 | bd->props.brightness = get_backlight_brightness(bd); | ||
268 | bd->props.power = FB_BLANK_UNBLANK; | ||
269 | backlight_update_status(bd); | ||
270 | |||
271 | return 0; | ||
272 | } | ||
273 | |||
274 | static void oaktrail_backlight_exit(void) | ||
275 | { | ||
276 | if (oaktrail_bl_device) | ||
277 | backlight_device_unregister(oaktrail_bl_device); | ||
278 | } | ||
279 | |||
280 | static int __devinit oaktrail_probe(struct platform_device *pdev) | ||
281 | { | ||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | static int __devexit oaktrail_remove(struct platform_device *pdev) | ||
286 | { | ||
287 | return 0; | ||
288 | } | ||
289 | |||
290 | static struct platform_driver oaktrail_driver = { | ||
291 | .driver = { | ||
292 | .name = DRIVER_NAME, | ||
293 | .owner = THIS_MODULE, | ||
294 | }, | ||
295 | .probe = oaktrail_probe, | ||
296 | .remove = __devexit_p(oaktrail_remove) | ||
297 | }; | ||
298 | |||
299 | static int dmi_check_cb(const struct dmi_system_id *id) | ||
300 | { | ||
301 | pr_info("Identified model '%s'\n", id->ident); | ||
302 | return 0; | ||
303 | } | ||
304 | |||
305 | static struct dmi_system_id __initdata oaktrail_dmi_table[] = { | ||
306 | { | ||
307 | .ident = "OakTrail platform", | ||
308 | .matches = { | ||
309 | DMI_MATCH(DMI_PRODUCT_NAME, "OakTrail platform"), | ||
310 | }, | ||
311 | .callback = dmi_check_cb | ||
312 | }, | ||
313 | { } | ||
314 | }; | ||
315 | |||
316 | static int __init oaktrail_init(void) | ||
317 | { | ||
318 | int ret; | ||
319 | |||
320 | if (acpi_disabled) { | ||
321 | pr_err("ACPI needs to be enabled for this driver to work!\n"); | ||
322 | return -ENODEV; | ||
323 | } | ||
324 | |||
325 | if (!force && !dmi_check_system(oaktrail_dmi_table)) { | ||
326 | pr_err("Platform not recognized (You could try the module's force-parameter)"); | ||
327 | return -ENODEV; | ||
328 | } | ||
329 | |||
330 | ret = platform_driver_register(&oaktrail_driver); | ||
331 | if (ret) { | ||
332 | pr_warning("Unable to register platform driver\n"); | ||
333 | goto err_driver_reg; | ||
334 | } | ||
335 | |||
336 | oaktrail_device = platform_device_alloc(DRIVER_NAME, -1); | ||
337 | if (!oaktrail_device) { | ||
338 | pr_warning("Unable to allocate platform device\n"); | ||
339 | ret = -ENOMEM; | ||
340 | goto err_device_alloc; | ||
341 | } | ||
342 | |||
343 | ret = platform_device_add(oaktrail_device); | ||
344 | if (ret) { | ||
345 | pr_warning("Unable to add platform device\n"); | ||
346 | goto err_device_add; | ||
347 | } | ||
348 | |||
349 | if (!acpi_video_backlight_support()) { | ||
350 | ret = oaktrail_backlight_init(); | ||
351 | if (ret) | ||
352 | goto err_backlight; | ||
353 | |||
354 | } else | ||
355 | pr_info("Backlight controlled by ACPI video driver\n"); | ||
356 | |||
357 | ret = oaktrail_rfkill_init(); | ||
358 | if (ret) { | ||
359 | pr_warning("Setup rfkill failed\n"); | ||
360 | goto err_rfkill; | ||
361 | } | ||
362 | |||
363 | pr_info("Driver "DRIVER_VERSION" successfully loaded\n"); | ||
364 | return 0; | ||
365 | |||
366 | err_rfkill: | ||
367 | oaktrail_backlight_exit(); | ||
368 | err_backlight: | ||
369 | platform_device_del(oaktrail_device); | ||
370 | err_device_add: | ||
371 | platform_device_put(oaktrail_device); | ||
372 | err_device_alloc: | ||
373 | platform_driver_unregister(&oaktrail_driver); | ||
374 | err_driver_reg: | ||
375 | |||
376 | return ret; | ||
377 | } | ||
378 | |||
379 | static void __exit oaktrail_cleanup(void) | ||
380 | { | ||
381 | oaktrail_backlight_exit(); | ||
382 | oaktrail_rfkill_cleanup(); | ||
383 | platform_device_unregister(oaktrail_device); | ||
384 | platform_driver_unregister(&oaktrail_driver); | ||
385 | |||
386 | pr_info("Driver unloaded\n"); | ||
387 | } | ||
388 | |||
389 | module_init(oaktrail_init); | ||
390 | module_exit(oaktrail_cleanup); | ||
391 | |||
392 | MODULE_AUTHOR("Yin Kangkai (kangkai.yin@intel.com)"); | ||
393 | MODULE_DESCRIPTION("Intel Oaktrail Platform ACPI Extras"); | ||
394 | MODULE_VERSION(DRIVER_VERSION); | ||
395 | MODULE_LICENSE("GPL"); | ||
396 | MODULE_ALIAS("dmi:*:svnIntelCorporation:pnOakTrailplatform:*"); | ||
diff --git a/drivers/platform/x86/intel_pmic_gpio.c b/drivers/platform/x86/intel_pmic_gpio.c index 464bb3fc4d88..1686c1e07d5d 100644 --- a/drivers/platform/x86/intel_pmic_gpio.c +++ b/drivers/platform/x86/intel_pmic_gpio.c | |||
@@ -19,6 +19,8 @@ | |||
19 | * Moorestown platform PMIC chip | 19 | * Moorestown platform PMIC chip |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #define pr_fmt(fmt) "%s: " fmt, __func__ | ||
23 | |||
22 | #include <linux/module.h> | 24 | #include <linux/module.h> |
23 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
24 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
@@ -90,8 +92,7 @@ static void pmic_program_irqtype(int gpio, int type) | |||
90 | static int pmic_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | 92 | static int pmic_gpio_direction_input(struct gpio_chip *chip, unsigned offset) |
91 | { | 93 | { |
92 | if (offset > 8) { | 94 | if (offset > 8) { |
93 | printk(KERN_ERR | 95 | pr_err("only pin 0-7 support input\n"); |
94 | "%s: only pin 0-7 support input\n", __func__); | ||
95 | return -1;/* we only have 8 GPIO can use as input */ | 96 | return -1;/* we only have 8 GPIO can use as input */ |
96 | } | 97 | } |
97 | return intel_scu_ipc_update_register(GPIO0 + offset, | 98 | return intel_scu_ipc_update_register(GPIO0 + offset, |
@@ -116,8 +117,7 @@ static int pmic_gpio_direction_output(struct gpio_chip *chip, | |||
116 | value ? 1 << (offset - 16) : 0, | 117 | value ? 1 << (offset - 16) : 0, |
117 | 1 << (offset - 16)); | 118 | 1 << (offset - 16)); |
118 | else { | 119 | else { |
119 | printk(KERN_ERR | 120 | pr_err("invalid PMIC GPIO pin %d!\n", offset); |
120 | "%s: invalid PMIC GPIO pin %d!\n", __func__, offset); | ||
121 | WARN_ON(1); | 121 | WARN_ON(1); |
122 | } | 122 | } |
123 | 123 | ||
@@ -260,7 +260,7 @@ static int __devinit platform_pmic_gpio_probe(struct platform_device *pdev) | |||
260 | /* setting up SRAM mapping for GPIOINT register */ | 260 | /* setting up SRAM mapping for GPIOINT register */ |
261 | pg->gpiointr = ioremap_nocache(pdata->gpiointr, 8); | 261 | pg->gpiointr = ioremap_nocache(pdata->gpiointr, 8); |
262 | if (!pg->gpiointr) { | 262 | if (!pg->gpiointr) { |
263 | printk(KERN_ERR "%s: Can not map GPIOINT.\n", __func__); | 263 | pr_err("Can not map GPIOINT\n"); |
264 | retval = -EINVAL; | 264 | retval = -EINVAL; |
265 | goto err2; | 265 | goto err2; |
266 | } | 266 | } |
@@ -281,13 +281,13 @@ static int __devinit platform_pmic_gpio_probe(struct platform_device *pdev) | |||
281 | pg->chip.dev = dev; | 281 | pg->chip.dev = dev; |
282 | retval = gpiochip_add(&pg->chip); | 282 | retval = gpiochip_add(&pg->chip); |
283 | if (retval) { | 283 | if (retval) { |
284 | printk(KERN_ERR "%s: Can not add pmic gpio chip.\n", __func__); | 284 | pr_err("Can not add pmic gpio chip\n"); |
285 | goto err; | 285 | goto err; |
286 | } | 286 | } |
287 | 287 | ||
288 | retval = request_irq(pg->irq, pmic_irq_handler, 0, "pmic", pg); | 288 | retval = request_irq(pg->irq, pmic_irq_handler, 0, "pmic", pg); |
289 | if (retval) { | 289 | if (retval) { |
290 | printk(KERN_WARNING "pmic: Interrupt request failed\n"); | 290 | pr_warn("Interrupt request failed\n"); |
291 | goto err; | 291 | goto err; |
292 | } | 292 | } |
293 | 293 | ||
diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c index 23fb2afda00b..3ff629df9f01 100644 --- a/drivers/platform/x86/msi-laptop.c +++ b/drivers/platform/x86/msi-laptop.c | |||
@@ -135,7 +135,7 @@ static int set_lcd_level(int level) | |||
135 | buf[1] = (u8) (level*31); | 135 | buf[1] = (u8) (level*31); |
136 | 136 | ||
137 | return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, buf, sizeof(buf), | 137 | return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, buf, sizeof(buf), |
138 | NULL, 0, 1); | 138 | NULL, 0); |
139 | } | 139 | } |
140 | 140 | ||
141 | static int get_lcd_level(void) | 141 | static int get_lcd_level(void) |
@@ -144,7 +144,7 @@ static int get_lcd_level(void) | |||
144 | int result; | 144 | int result; |
145 | 145 | ||
146 | result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1, | 146 | result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1, |
147 | &rdata, 1, 1); | 147 | &rdata, 1); |
148 | if (result < 0) | 148 | if (result < 0) |
149 | return result; | 149 | return result; |
150 | 150 | ||
@@ -157,7 +157,7 @@ static int get_auto_brightness(void) | |||
157 | int result; | 157 | int result; |
158 | 158 | ||
159 | result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1, | 159 | result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1, |
160 | &rdata, 1, 1); | 160 | &rdata, 1); |
161 | if (result < 0) | 161 | if (result < 0) |
162 | return result; | 162 | return result; |
163 | 163 | ||
@@ -172,7 +172,7 @@ static int set_auto_brightness(int enable) | |||
172 | wdata[0] = 4; | 172 | wdata[0] = 4; |
173 | 173 | ||
174 | result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 1, | 174 | result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 1, |
175 | &rdata, 1, 1); | 175 | &rdata, 1); |
176 | if (result < 0) | 176 | if (result < 0) |
177 | return result; | 177 | return result; |
178 | 178 | ||
@@ -180,7 +180,7 @@ static int set_auto_brightness(int enable) | |||
180 | wdata[1] = (rdata & 0xF7) | (enable ? 8 : 0); | 180 | wdata[1] = (rdata & 0xF7) | (enable ? 8 : 0); |
181 | 181 | ||
182 | return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 2, | 182 | return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 2, |
183 | NULL, 0, 1); | 183 | NULL, 0); |
184 | } | 184 | } |
185 | 185 | ||
186 | static ssize_t set_device_state(const char *buf, size_t count, u8 mask) | 186 | static ssize_t set_device_state(const char *buf, size_t count, u8 mask) |
@@ -217,7 +217,7 @@ static int get_wireless_state(int *wlan, int *bluetooth) | |||
217 | u8 wdata = 0, rdata; | 217 | u8 wdata = 0, rdata; |
218 | int result; | 218 | int result; |
219 | 219 | ||
220 | result = ec_transaction(MSI_EC_COMMAND_WIRELESS, &wdata, 1, &rdata, 1, 1); | 220 | result = ec_transaction(MSI_EC_COMMAND_WIRELESS, &wdata, 1, &rdata, 1); |
221 | if (result < 0) | 221 | if (result < 0) |
222 | return -1; | 222 | return -1; |
223 | 223 | ||
@@ -447,7 +447,7 @@ static struct platform_device *msipf_device; | |||
447 | 447 | ||
448 | static int dmi_check_cb(const struct dmi_system_id *id) | 448 | static int dmi_check_cb(const struct dmi_system_id *id) |
449 | { | 449 | { |
450 | pr_info("Identified laptop model '%s'.\n", id->ident); | 450 | pr_info("Identified laptop model '%s'\n", id->ident); |
451 | return 1; | 451 | return 1; |
452 | } | 452 | } |
453 | 453 | ||
@@ -800,7 +800,7 @@ static void msi_laptop_input_destroy(void) | |||
800 | input_unregister_device(msi_laptop_input_dev); | 800 | input_unregister_device(msi_laptop_input_dev); |
801 | } | 801 | } |
802 | 802 | ||
803 | static int load_scm_model_init(struct platform_device *sdev) | 803 | static int __init load_scm_model_init(struct platform_device *sdev) |
804 | { | 804 | { |
805 | u8 data; | 805 | u8 data; |
806 | int result; | 806 | int result; |
@@ -875,8 +875,7 @@ static int __init msi_init(void) | |||
875 | /* Register backlight stuff */ | 875 | /* Register backlight stuff */ |
876 | 876 | ||
877 | if (acpi_video_backlight_support()) { | 877 | if (acpi_video_backlight_support()) { |
878 | pr_info("Brightness ignored, must be controlled " | 878 | pr_info("Brightness ignored, must be controlled by ACPI video driver\n"); |
879 | "by ACPI video driver\n"); | ||
880 | } else { | 879 | } else { |
881 | struct backlight_properties props; | 880 | struct backlight_properties props; |
882 | memset(&props, 0, sizeof(struct backlight_properties)); | 881 | memset(&props, 0, sizeof(struct backlight_properties)); |
@@ -930,7 +929,7 @@ static int __init msi_init(void) | |||
930 | if (auto_brightness != 2) | 929 | if (auto_brightness != 2) |
931 | set_auto_brightness(auto_brightness); | 930 | set_auto_brightness(auto_brightness); |
932 | 931 | ||
933 | pr_info("driver "MSI_DRIVER_VERSION" successfully loaded.\n"); | 932 | pr_info("driver " MSI_DRIVER_VERSION " successfully loaded\n"); |
934 | 933 | ||
935 | return 0; | 934 | return 0; |
936 | 935 | ||
@@ -978,7 +977,7 @@ static void __exit msi_cleanup(void) | |||
978 | if (auto_brightness != 2) | 977 | if (auto_brightness != 2) |
979 | set_auto_brightness(1); | 978 | set_auto_brightness(1); |
980 | 979 | ||
981 | pr_info("driver unloaded.\n"); | 980 | pr_info("driver unloaded\n"); |
982 | } | 981 | } |
983 | 982 | ||
984 | module_init(msi_init); | 983 | module_init(msi_init); |
diff --git a/drivers/platform/x86/msi-wmi.c b/drivers/platform/x86/msi-wmi.c index d5419c9ec07a..c832e3356cd6 100644 --- a/drivers/platform/x86/msi-wmi.c +++ b/drivers/platform/x86/msi-wmi.c | |||
@@ -20,6 +20,7 @@ | |||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
21 | */ | 21 | */ |
22 | 22 | ||
23 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
23 | 24 | ||
24 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
25 | #include <linux/input.h> | 26 | #include <linux/input.h> |
@@ -36,13 +37,10 @@ MODULE_ALIAS("wmi:551A1F84-FBDD-4125-91DB-3EA8F44F1D45"); | |||
36 | MODULE_ALIAS("wmi:B6F3EEF2-3D2F-49DC-9DE3-85BCE18C62F2"); | 37 | MODULE_ALIAS("wmi:B6F3EEF2-3D2F-49DC-9DE3-85BCE18C62F2"); |
37 | 38 | ||
38 | #define DRV_NAME "msi-wmi" | 39 | #define DRV_NAME "msi-wmi" |
39 | #define DRV_PFX DRV_NAME ": " | ||
40 | 40 | ||
41 | #define MSIWMI_BIOS_GUID "551A1F84-FBDD-4125-91DB-3EA8F44F1D45" | 41 | #define MSIWMI_BIOS_GUID "551A1F84-FBDD-4125-91DB-3EA8F44F1D45" |
42 | #define MSIWMI_EVENT_GUID "B6F3EEF2-3D2F-49DC-9DE3-85BCE18C62F2" | 42 | #define MSIWMI_EVENT_GUID "B6F3EEF2-3D2F-49DC-9DE3-85BCE18C62F2" |
43 | 43 | ||
44 | #define dprintk(msg...) pr_debug(DRV_PFX msg) | ||
45 | |||
46 | #define SCANCODE_BASE 0xD0 | 44 | #define SCANCODE_BASE 0xD0 |
47 | #define MSI_WMI_BRIGHTNESSUP SCANCODE_BASE | 45 | #define MSI_WMI_BRIGHTNESSUP SCANCODE_BASE |
48 | #define MSI_WMI_BRIGHTNESSDOWN (SCANCODE_BASE + 1) | 46 | #define MSI_WMI_BRIGHTNESSDOWN (SCANCODE_BASE + 1) |
@@ -78,7 +76,7 @@ static int msi_wmi_query_block(int instance, int *ret) | |||
78 | 76 | ||
79 | if (!obj || obj->type != ACPI_TYPE_INTEGER) { | 77 | if (!obj || obj->type != ACPI_TYPE_INTEGER) { |
80 | if (obj) { | 78 | if (obj) { |
81 | printk(KERN_ERR DRV_PFX "query block returned object " | 79 | pr_err("query block returned object " |
82 | "type: %d - buffer length:%d\n", obj->type, | 80 | "type: %d - buffer length:%d\n", obj->type, |
83 | obj->type == ACPI_TYPE_BUFFER ? | 81 | obj->type == ACPI_TYPE_BUFFER ? |
84 | obj->buffer.length : 0); | 82 | obj->buffer.length : 0); |
@@ -97,8 +95,8 @@ static int msi_wmi_set_block(int instance, int value) | |||
97 | 95 | ||
98 | struct acpi_buffer input = { sizeof(int), &value }; | 96 | struct acpi_buffer input = { sizeof(int), &value }; |
99 | 97 | ||
100 | dprintk("Going to set block of instance: %d - value: %d\n", | 98 | pr_debug("Going to set block of instance: %d - value: %d\n", |
101 | instance, value); | 99 | instance, value); |
102 | 100 | ||
103 | status = wmi_set_block(MSIWMI_BIOS_GUID, instance, &input); | 101 | status = wmi_set_block(MSIWMI_BIOS_GUID, instance, &input); |
104 | 102 | ||
@@ -112,20 +110,19 @@ static int bl_get(struct backlight_device *bd) | |||
112 | /* Instance 1 is "get backlight", cmp with DSDT */ | 110 | /* Instance 1 is "get backlight", cmp with DSDT */ |
113 | err = msi_wmi_query_block(1, &ret); | 111 | err = msi_wmi_query_block(1, &ret); |
114 | if (err) { | 112 | if (err) { |
115 | printk(KERN_ERR DRV_PFX "Could not query backlight: %d\n", err); | 113 | pr_err("Could not query backlight: %d\n", err); |
116 | return -EINVAL; | 114 | return -EINVAL; |
117 | } | 115 | } |
118 | dprintk("Get: Query block returned: %d\n", ret); | 116 | pr_debug("Get: Query block returned: %d\n", ret); |
119 | for (level = 0; level < ARRAY_SIZE(backlight_map); level++) { | 117 | for (level = 0; level < ARRAY_SIZE(backlight_map); level++) { |
120 | if (backlight_map[level] == ret) { | 118 | if (backlight_map[level] == ret) { |
121 | dprintk("Current backlight level: 0x%X - index: %d\n", | 119 | pr_debug("Current backlight level: 0x%X - index: %d\n", |
122 | backlight_map[level], level); | 120 | backlight_map[level], level); |
123 | break; | 121 | break; |
124 | } | 122 | } |
125 | } | 123 | } |
126 | if (level == ARRAY_SIZE(backlight_map)) { | 124 | if (level == ARRAY_SIZE(backlight_map)) { |
127 | printk(KERN_ERR DRV_PFX "get: Invalid brightness value: 0x%X\n", | 125 | pr_err("get: Invalid brightness value: 0x%X\n", ret); |
128 | ret); | ||
129 | return -EINVAL; | 126 | return -EINVAL; |
130 | } | 127 | } |
131 | return level; | 128 | return level; |
@@ -156,7 +153,7 @@ static void msi_wmi_notify(u32 value, void *context) | |||
156 | 153 | ||
157 | status = wmi_get_event_data(value, &response); | 154 | status = wmi_get_event_data(value, &response); |
158 | if (status != AE_OK) { | 155 | if (status != AE_OK) { |
159 | printk(KERN_INFO DRV_PFX "bad event status 0x%x\n", status); | 156 | pr_info("bad event status 0x%x\n", status); |
160 | return; | 157 | return; |
161 | } | 158 | } |
162 | 159 | ||
@@ -164,7 +161,7 @@ static void msi_wmi_notify(u32 value, void *context) | |||
164 | 161 | ||
165 | if (obj && obj->type == ACPI_TYPE_INTEGER) { | 162 | if (obj && obj->type == ACPI_TYPE_INTEGER) { |
166 | int eventcode = obj->integer.value; | 163 | int eventcode = obj->integer.value; |
167 | dprintk("Eventcode: 0x%x\n", eventcode); | 164 | pr_debug("Eventcode: 0x%x\n", eventcode); |
168 | key = sparse_keymap_entry_from_scancode(msi_wmi_input_dev, | 165 | key = sparse_keymap_entry_from_scancode(msi_wmi_input_dev, |
169 | eventcode); | 166 | eventcode); |
170 | if (key) { | 167 | if (key) { |
@@ -175,8 +172,8 @@ static void msi_wmi_notify(u32 value, void *context) | |||
175 | /* Ignore event if the same event happened in a 50 ms | 172 | /* Ignore event if the same event happened in a 50 ms |
176 | timeframe -> Key press may result in 10-20 GPEs */ | 173 | timeframe -> Key press may result in 10-20 GPEs */ |
177 | if (ktime_to_us(diff) < 1000 * 50) { | 174 | if (ktime_to_us(diff) < 1000 * 50) { |
178 | dprintk("Suppressed key event 0x%X - " | 175 | pr_debug("Suppressed key event 0x%X - " |
179 | "Last press was %lld us ago\n", | 176 | "Last press was %lld us ago\n", |
180 | key->code, ktime_to_us(diff)); | 177 | key->code, ktime_to_us(diff)); |
181 | return; | 178 | return; |
182 | } | 179 | } |
@@ -187,17 +184,16 @@ static void msi_wmi_notify(u32 value, void *context) | |||
187 | (!acpi_video_backlight_support() || | 184 | (!acpi_video_backlight_support() || |
188 | (key->code != MSI_WMI_BRIGHTNESSUP && | 185 | (key->code != MSI_WMI_BRIGHTNESSUP && |
189 | key->code != MSI_WMI_BRIGHTNESSDOWN))) { | 186 | key->code != MSI_WMI_BRIGHTNESSDOWN))) { |
190 | dprintk("Send key: 0x%X - " | 187 | pr_debug("Send key: 0x%X - " |
191 | "Input layer keycode: %d\n", key->code, | 188 | "Input layer keycode: %d\n", |
192 | key->keycode); | 189 | key->code, key->keycode); |
193 | sparse_keymap_report_entry(msi_wmi_input_dev, | 190 | sparse_keymap_report_entry(msi_wmi_input_dev, |
194 | key, 1, true); | 191 | key, 1, true); |
195 | } | 192 | } |
196 | } else | 193 | } else |
197 | printk(KERN_INFO "Unknown key pressed - %x\n", | 194 | pr_info("Unknown key pressed - %x\n", eventcode); |
198 | eventcode); | ||
199 | } else | 195 | } else |
200 | printk(KERN_INFO DRV_PFX "Unknown event received\n"); | 196 | pr_info("Unknown event received\n"); |
201 | kfree(response.pointer); | 197 | kfree(response.pointer); |
202 | } | 198 | } |
203 | 199 | ||
@@ -238,8 +234,7 @@ static int __init msi_wmi_init(void) | |||
238 | int err; | 234 | int err; |
239 | 235 | ||
240 | if (!wmi_has_guid(MSIWMI_EVENT_GUID)) { | 236 | if (!wmi_has_guid(MSIWMI_EVENT_GUID)) { |
241 | printk(KERN_ERR | 237 | pr_err("This machine doesn't have MSI-hotkeys through WMI\n"); |
242 | "This machine doesn't have MSI-hotkeys through WMI\n"); | ||
243 | return -ENODEV; | 238 | return -ENODEV; |
244 | } | 239 | } |
245 | err = wmi_install_notify_handler(MSIWMI_EVENT_GUID, | 240 | err = wmi_install_notify_handler(MSIWMI_EVENT_GUID, |
@@ -270,7 +265,7 @@ static int __init msi_wmi_init(void) | |||
270 | 265 | ||
271 | backlight->props.brightness = err; | 266 | backlight->props.brightness = err; |
272 | } | 267 | } |
273 | dprintk("Event handler installed\n"); | 268 | pr_debug("Event handler installed\n"); |
274 | 269 | ||
275 | return 0; | 270 | return 0; |
276 | 271 | ||
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 6fe8cd6e23b5..bbd182e178cb 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c | |||
@@ -42,6 +42,8 @@ | |||
42 | * | 42 | * |
43 | */ | 43 | */ |
44 | 44 | ||
45 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
46 | |||
45 | #include <linux/kernel.h> | 47 | #include <linux/kernel.h> |
46 | #include <linux/module.h> | 48 | #include <linux/module.h> |
47 | #include <linux/moduleparam.h> | 49 | #include <linux/moduleparam.h> |
@@ -70,10 +72,10 @@ | |||
70 | #include <linux/miscdevice.h> | 72 | #include <linux/miscdevice.h> |
71 | #endif | 73 | #endif |
72 | 74 | ||
73 | #define DRV_PFX "sony-laptop: " | 75 | #define dprintk(fmt, ...) \ |
74 | #define dprintk(msg...) do { \ | 76 | do { \ |
75 | if (debug) \ | 77 | if (debug) \ |
76 | pr_warn(DRV_PFX msg); \ | 78 | pr_warn(fmt, ##__VA_ARGS__); \ |
77 | } while (0) | 79 | } while (0) |
78 | 80 | ||
79 | #define SONY_LAPTOP_DRIVER_VERSION "0.6" | 81 | #define SONY_LAPTOP_DRIVER_VERSION "0.6" |
@@ -418,7 +420,7 @@ static int sony_laptop_setup_input(struct acpi_device *acpi_device) | |||
418 | error = kfifo_alloc(&sony_laptop_input.fifo, | 420 | error = kfifo_alloc(&sony_laptop_input.fifo, |
419 | SONY_LAPTOP_BUF_SIZE, GFP_KERNEL); | 421 | SONY_LAPTOP_BUF_SIZE, GFP_KERNEL); |
420 | if (error) { | 422 | if (error) { |
421 | pr_err(DRV_PFX "kfifo_alloc failed\n"); | 423 | pr_err("kfifo_alloc failed\n"); |
422 | goto err_dec_users; | 424 | goto err_dec_users; |
423 | } | 425 | } |
424 | 426 | ||
@@ -702,7 +704,7 @@ static int acpi_callgetfunc(acpi_handle handle, char *name, int *result) | |||
702 | return 0; | 704 | return 0; |
703 | } | 705 | } |
704 | 706 | ||
705 | pr_warn(DRV_PFX "acpi_callreadfunc failed\n"); | 707 | pr_warn("acpi_callreadfunc failed\n"); |
706 | 708 | ||
707 | return -1; | 709 | return -1; |
708 | } | 710 | } |
@@ -728,8 +730,7 @@ static int acpi_callsetfunc(acpi_handle handle, char *name, int value, | |||
728 | if (status == AE_OK) { | 730 | if (status == AE_OK) { |
729 | if (result != NULL) { | 731 | if (result != NULL) { |
730 | if (out_obj.type != ACPI_TYPE_INTEGER) { | 732 | if (out_obj.type != ACPI_TYPE_INTEGER) { |
731 | pr_warn(DRV_PFX "acpi_evaluate_object bad " | 733 | pr_warn("acpi_evaluate_object bad return type\n"); |
732 | "return type\n"); | ||
733 | return -1; | 734 | return -1; |
734 | } | 735 | } |
735 | *result = out_obj.integer.value; | 736 | *result = out_obj.integer.value; |
@@ -737,7 +738,7 @@ static int acpi_callsetfunc(acpi_handle handle, char *name, int value, | |||
737 | return 0; | 738 | return 0; |
738 | } | 739 | } |
739 | 740 | ||
740 | pr_warn(DRV_PFX "acpi_evaluate_object failed\n"); | 741 | pr_warn("acpi_evaluate_object failed\n"); |
741 | 742 | ||
742 | return -1; | 743 | return -1; |
743 | } | 744 | } |
@@ -961,7 +962,6 @@ static int sony_backlight_get_brightness(struct backlight_device *bd) | |||
961 | static int sony_nc_get_brightness_ng(struct backlight_device *bd) | 962 | static int sony_nc_get_brightness_ng(struct backlight_device *bd) |
962 | { | 963 | { |
963 | int result; | 964 | int result; |
964 | int *handle = (int *)bl_get_data(bd); | ||
965 | struct sony_backlight_props *sdev = | 965 | struct sony_backlight_props *sdev = |
966 | (struct sony_backlight_props *)bl_get_data(bd); | 966 | (struct sony_backlight_props *)bl_get_data(bd); |
967 | 967 | ||
@@ -973,7 +973,6 @@ static int sony_nc_get_brightness_ng(struct backlight_device *bd) | |||
973 | static int sony_nc_update_status_ng(struct backlight_device *bd) | 973 | static int sony_nc_update_status_ng(struct backlight_device *bd) |
974 | { | 974 | { |
975 | int value, result; | 975 | int value, result; |
976 | int *handle = (int *)bl_get_data(bd); | ||
977 | struct sony_backlight_props *sdev = | 976 | struct sony_backlight_props *sdev = |
978 | (struct sony_backlight_props *)bl_get_data(bd); | 977 | (struct sony_backlight_props *)bl_get_data(bd); |
979 | 978 | ||
@@ -1104,10 +1103,8 @@ static void sony_nc_notify(struct acpi_device *device, u32 event) | |||
1104 | } | 1103 | } |
1105 | 1104 | ||
1106 | if (!key_event->data) | 1105 | if (!key_event->data) |
1107 | pr_info(DRV_PFX | 1106 | pr_info("Unknown event: 0x%x 0x%x\n", |
1108 | "Unknown event: 0x%x 0x%x\n", | 1107 | key_handle, ev); |
1109 | key_handle, | ||
1110 | ev); | ||
1111 | else | 1108 | else |
1112 | sony_laptop_report_input_event(ev); | 1109 | sony_laptop_report_input_event(ev); |
1113 | } | 1110 | } |
@@ -1128,7 +1125,7 @@ static acpi_status sony_walk_callback(acpi_handle handle, u32 level, | |||
1128 | struct acpi_device_info *info; | 1125 | struct acpi_device_info *info; |
1129 | 1126 | ||
1130 | if (ACPI_SUCCESS(acpi_get_object_info(handle, &info))) { | 1127 | if (ACPI_SUCCESS(acpi_get_object_info(handle, &info))) { |
1131 | pr_warn(DRV_PFX "method: name: %4.4s, args %X\n", | 1128 | pr_warn("method: name: %4.4s, args %X\n", |
1132 | (char *)&info->name, info->param_count); | 1129 | (char *)&info->name, info->param_count); |
1133 | 1130 | ||
1134 | kfree(info); | 1131 | kfree(info); |
@@ -1169,7 +1166,7 @@ static int sony_nc_resume(struct acpi_device *device) | |||
1169 | ret = acpi_callsetfunc(sony_nc_acpi_handle, *item->acpiset, | 1166 | ret = acpi_callsetfunc(sony_nc_acpi_handle, *item->acpiset, |
1170 | item->value, NULL); | 1167 | item->value, NULL); |
1171 | if (ret < 0) { | 1168 | if (ret < 0) { |
1172 | pr_err(DRV_PFX "%s: %d\n", __func__, ret); | 1169 | pr_err("%s: %d\n", __func__, ret); |
1173 | break; | 1170 | break; |
1174 | } | 1171 | } |
1175 | } | 1172 | } |
@@ -1336,12 +1333,12 @@ static void sony_nc_rfkill_setup(struct acpi_device *device) | |||
1336 | 1333 | ||
1337 | device_enum = (union acpi_object *) buffer.pointer; | 1334 | device_enum = (union acpi_object *) buffer.pointer; |
1338 | if (!device_enum) { | 1335 | if (!device_enum) { |
1339 | pr_err(DRV_PFX "No SN06 return object."); | 1336 | pr_err("No SN06 return object\n"); |
1340 | goto out_no_enum; | 1337 | goto out_no_enum; |
1341 | } | 1338 | } |
1342 | if (device_enum->type != ACPI_TYPE_BUFFER) { | 1339 | if (device_enum->type != ACPI_TYPE_BUFFER) { |
1343 | pr_err(DRV_PFX "Invalid SN06 return object 0x%.2x\n", | 1340 | pr_err("Invalid SN06 return object 0x%.2x\n", |
1344 | device_enum->type); | 1341 | device_enum->type); |
1345 | goto out_no_enum; | 1342 | goto out_no_enum; |
1346 | } | 1343 | } |
1347 | 1344 | ||
@@ -1662,7 +1659,7 @@ static void sony_nc_backlight_setup(void) | |||
1662 | ops, &props); | 1659 | ops, &props); |
1663 | 1660 | ||
1664 | if (IS_ERR(sony_bl_props.dev)) { | 1661 | if (IS_ERR(sony_bl_props.dev)) { |
1665 | pr_warn(DRV_PFX "unable to register backlight device\n"); | 1662 | pr_warn("unable to register backlight device\n"); |
1666 | sony_bl_props.dev = NULL; | 1663 | sony_bl_props.dev = NULL; |
1667 | } else | 1664 | } else |
1668 | sony_bl_props.dev->props.brightness = | 1665 | sony_bl_props.dev->props.brightness = |
@@ -1682,8 +1679,7 @@ static int sony_nc_add(struct acpi_device *device) | |||
1682 | acpi_handle handle; | 1679 | acpi_handle handle; |
1683 | struct sony_nc_value *item; | 1680 | struct sony_nc_value *item; |
1684 | 1681 | ||
1685 | pr_info(DRV_PFX "%s v%s.\n", SONY_NC_DRIVER_NAME, | 1682 | pr_info("%s v%s\n", SONY_NC_DRIVER_NAME, SONY_LAPTOP_DRIVER_VERSION); |
1686 | SONY_LAPTOP_DRIVER_VERSION); | ||
1687 | 1683 | ||
1688 | sony_nc_acpi_device = device; | 1684 | sony_nc_acpi_device = device; |
1689 | strcpy(acpi_device_class(device), "sony/hotkey"); | 1685 | strcpy(acpi_device_class(device), "sony/hotkey"); |
@@ -1708,7 +1704,7 @@ static int sony_nc_add(struct acpi_device *device) | |||
1708 | sony_nc_acpi_handle, 1, sony_walk_callback, | 1704 | sony_nc_acpi_handle, 1, sony_walk_callback, |
1709 | NULL, NULL, NULL); | 1705 | NULL, NULL, NULL); |
1710 | if (ACPI_FAILURE(status)) { | 1706 | if (ACPI_FAILURE(status)) { |
1711 | pr_warn(DRV_PFX "unable to walk acpi resources\n"); | 1707 | pr_warn("unable to walk acpi resources\n"); |
1712 | result = -ENODEV; | 1708 | result = -ENODEV; |
1713 | goto outpresent; | 1709 | goto outpresent; |
1714 | } | 1710 | } |
@@ -1736,13 +1732,12 @@ static int sony_nc_add(struct acpi_device *device) | |||
1736 | /* setup input devices and helper fifo */ | 1732 | /* setup input devices and helper fifo */ |
1737 | result = sony_laptop_setup_input(device); | 1733 | result = sony_laptop_setup_input(device); |
1738 | if (result) { | 1734 | if (result) { |
1739 | pr_err(DRV_PFX "Unable to create input devices.\n"); | 1735 | pr_err("Unable to create input devices\n"); |
1740 | goto outkbdbacklight; | 1736 | goto outkbdbacklight; |
1741 | } | 1737 | } |
1742 | 1738 | ||
1743 | if (acpi_video_backlight_support()) { | 1739 | if (acpi_video_backlight_support()) { |
1744 | pr_info(DRV_PFX "brightness ignored, must be " | 1740 | pr_info("brightness ignored, must be controlled by ACPI video driver\n"); |
1745 | "controlled by ACPI video driver\n"); | ||
1746 | } else { | 1741 | } else { |
1747 | sony_nc_backlight_setup(); | 1742 | sony_nc_backlight_setup(); |
1748 | } | 1743 | } |
@@ -2265,9 +2260,9 @@ out: | |||
2265 | if (pcidev) | 2260 | if (pcidev) |
2266 | pci_dev_put(pcidev); | 2261 | pci_dev_put(pcidev); |
2267 | 2262 | ||
2268 | pr_info(DRV_PFX "detected Type%d model\n", | 2263 | pr_info("detected Type%d model\n", |
2269 | dev->model == SONYPI_DEVICE_TYPE1 ? 1 : | 2264 | dev->model == SONYPI_DEVICE_TYPE1 ? 1 : |
2270 | dev->model == SONYPI_DEVICE_TYPE2 ? 2 : 3); | 2265 | dev->model == SONYPI_DEVICE_TYPE2 ? 2 : 3); |
2271 | } | 2266 | } |
2272 | 2267 | ||
2273 | /* camera tests and poweron/poweroff */ | 2268 | /* camera tests and poweron/poweroff */ |
@@ -2313,7 +2308,7 @@ static int __sony_pic_camera_ready(void) | |||
2313 | static int __sony_pic_camera_off(void) | 2308 | static int __sony_pic_camera_off(void) |
2314 | { | 2309 | { |
2315 | if (!camera) { | 2310 | if (!camera) { |
2316 | pr_warn(DRV_PFX "camera control not enabled\n"); | 2311 | pr_warn("camera control not enabled\n"); |
2317 | return -ENODEV; | 2312 | return -ENODEV; |
2318 | } | 2313 | } |
2319 | 2314 | ||
@@ -2333,7 +2328,7 @@ static int __sony_pic_camera_on(void) | |||
2333 | int i, j, x; | 2328 | int i, j, x; |
2334 | 2329 | ||
2335 | if (!camera) { | 2330 | if (!camera) { |
2336 | pr_warn(DRV_PFX "camera control not enabled\n"); | 2331 | pr_warn("camera control not enabled\n"); |
2337 | return -ENODEV; | 2332 | return -ENODEV; |
2338 | } | 2333 | } |
2339 | 2334 | ||
@@ -2356,7 +2351,7 @@ static int __sony_pic_camera_on(void) | |||
2356 | } | 2351 | } |
2357 | 2352 | ||
2358 | if (j == 0) { | 2353 | if (j == 0) { |
2359 | pr_warn(DRV_PFX "failed to power on camera\n"); | 2354 | pr_warn("failed to power on camera\n"); |
2360 | return -ENODEV; | 2355 | return -ENODEV; |
2361 | } | 2356 | } |
2362 | 2357 | ||
@@ -2412,8 +2407,7 @@ int sony_pic_camera_command(int command, u8 value) | |||
2412 | ITERATIONS_SHORT); | 2407 | ITERATIONS_SHORT); |
2413 | break; | 2408 | break; |
2414 | default: | 2409 | default: |
2415 | pr_err(DRV_PFX "sony_pic_camera_command invalid: %d\n", | 2410 | pr_err("sony_pic_camera_command invalid: %d\n", command); |
2416 | command); | ||
2417 | break; | 2411 | break; |
2418 | } | 2412 | } |
2419 | mutex_unlock(&spic_dev.lock); | 2413 | mutex_unlock(&spic_dev.lock); |
@@ -2819,7 +2813,7 @@ static int sonypi_compat_init(void) | |||
2819 | error = | 2813 | error = |
2820 | kfifo_alloc(&sonypi_compat.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL); | 2814 | kfifo_alloc(&sonypi_compat.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL); |
2821 | if (error) { | 2815 | if (error) { |
2822 | pr_err(DRV_PFX "kfifo_alloc failed\n"); | 2816 | pr_err("kfifo_alloc failed\n"); |
2823 | return error; | 2817 | return error; |
2824 | } | 2818 | } |
2825 | 2819 | ||
@@ -2829,12 +2823,12 @@ static int sonypi_compat_init(void) | |||
2829 | sonypi_misc_device.minor = minor; | 2823 | sonypi_misc_device.minor = minor; |
2830 | error = misc_register(&sonypi_misc_device); | 2824 | error = misc_register(&sonypi_misc_device); |
2831 | if (error) { | 2825 | if (error) { |
2832 | pr_err(DRV_PFX "misc_register failed\n"); | 2826 | pr_err("misc_register failed\n"); |
2833 | goto err_free_kfifo; | 2827 | goto err_free_kfifo; |
2834 | } | 2828 | } |
2835 | if (minor == -1) | 2829 | if (minor == -1) |
2836 | pr_info(DRV_PFX "device allocated minor is %d\n", | 2830 | pr_info("device allocated minor is %d\n", |
2837 | sonypi_misc_device.minor); | 2831 | sonypi_misc_device.minor); |
2838 | 2832 | ||
2839 | return 0; | 2833 | return 0; |
2840 | 2834 | ||
@@ -2893,8 +2887,8 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context) | |||
2893 | } | 2887 | } |
2894 | for (i = 0; i < p->interrupt_count; i++) { | 2888 | for (i = 0; i < p->interrupt_count; i++) { |
2895 | if (!p->interrupts[i]) { | 2889 | if (!p->interrupts[i]) { |
2896 | pr_warn(DRV_PFX "Invalid IRQ %d\n", | 2890 | pr_warn("Invalid IRQ %d\n", |
2897 | p->interrupts[i]); | 2891 | p->interrupts[i]); |
2898 | continue; | 2892 | continue; |
2899 | } | 2893 | } |
2900 | interrupt = kzalloc(sizeof(*interrupt), | 2894 | interrupt = kzalloc(sizeof(*interrupt), |
@@ -2932,14 +2926,14 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context) | |||
2932 | ioport->io2.address_length); | 2926 | ioport->io2.address_length); |
2933 | } | 2927 | } |
2934 | else { | 2928 | else { |
2935 | pr_err(DRV_PFX "Unknown SPIC Type, more than 2 IO Ports\n"); | 2929 | pr_err("Unknown SPIC Type, more than 2 IO Ports\n"); |
2936 | return AE_ERROR; | 2930 | return AE_ERROR; |
2937 | } | 2931 | } |
2938 | return AE_OK; | 2932 | return AE_OK; |
2939 | } | 2933 | } |
2940 | default: | 2934 | default: |
2941 | dprintk("Resource %d isn't an IRQ nor an IO port\n", | 2935 | dprintk("Resource %d isn't an IRQ nor an IO port\n", |
2942 | resource->type); | 2936 | resource->type); |
2943 | 2937 | ||
2944 | case ACPI_RESOURCE_TYPE_END_TAG: | 2938 | case ACPI_RESOURCE_TYPE_END_TAG: |
2945 | return AE_OK; | 2939 | return AE_OK; |
@@ -2960,7 +2954,7 @@ static int sony_pic_possible_resources(struct acpi_device *device) | |||
2960 | dprintk("Evaluating _STA\n"); | 2954 | dprintk("Evaluating _STA\n"); |
2961 | result = acpi_bus_get_status(device); | 2955 | result = acpi_bus_get_status(device); |
2962 | if (result) { | 2956 | if (result) { |
2963 | pr_warn(DRV_PFX "Unable to read status\n"); | 2957 | pr_warn("Unable to read status\n"); |
2964 | goto end; | 2958 | goto end; |
2965 | } | 2959 | } |
2966 | 2960 | ||
@@ -2976,8 +2970,7 @@ static int sony_pic_possible_resources(struct acpi_device *device) | |||
2976 | status = acpi_walk_resources(device->handle, METHOD_NAME__PRS, | 2970 | status = acpi_walk_resources(device->handle, METHOD_NAME__PRS, |
2977 | sony_pic_read_possible_resource, &spic_dev); | 2971 | sony_pic_read_possible_resource, &spic_dev); |
2978 | if (ACPI_FAILURE(status)) { | 2972 | if (ACPI_FAILURE(status)) { |
2979 | pr_warn(DRV_PFX "Failure evaluating %s\n", | 2973 | pr_warn("Failure evaluating %s\n", METHOD_NAME__PRS); |
2980 | METHOD_NAME__PRS); | ||
2981 | result = -ENODEV; | 2974 | result = -ENODEV; |
2982 | } | 2975 | } |
2983 | end: | 2976 | end: |
@@ -3090,7 +3083,7 @@ static int sony_pic_enable(struct acpi_device *device, | |||
3090 | 3083 | ||
3091 | /* check for total failure */ | 3084 | /* check for total failure */ |
3092 | if (ACPI_FAILURE(status)) { | 3085 | if (ACPI_FAILURE(status)) { |
3093 | pr_err(DRV_PFX "Error evaluating _SRS\n"); | 3086 | pr_err("Error evaluating _SRS\n"); |
3094 | result = -ENODEV; | 3087 | result = -ENODEV; |
3095 | goto end; | 3088 | goto end; |
3096 | } | 3089 | } |
@@ -3182,7 +3175,7 @@ static int sony_pic_remove(struct acpi_device *device, int type) | |||
3182 | struct sony_pic_irq *irq, *tmp_irq; | 3175 | struct sony_pic_irq *irq, *tmp_irq; |
3183 | 3176 | ||
3184 | if (sony_pic_disable(device)) { | 3177 | if (sony_pic_disable(device)) { |
3185 | pr_err(DRV_PFX "Couldn't disable device.\n"); | 3178 | pr_err("Couldn't disable device\n"); |
3186 | return -ENXIO; | 3179 | return -ENXIO; |
3187 | } | 3180 | } |
3188 | 3181 | ||
@@ -3222,8 +3215,7 @@ static int sony_pic_add(struct acpi_device *device) | |||
3222 | struct sony_pic_ioport *io, *tmp_io; | 3215 | struct sony_pic_ioport *io, *tmp_io; |
3223 | struct sony_pic_irq *irq, *tmp_irq; | 3216 | struct sony_pic_irq *irq, *tmp_irq; |
3224 | 3217 | ||
3225 | pr_info(DRV_PFX "%s v%s.\n", SONY_PIC_DRIVER_NAME, | 3218 | pr_info("%s v%s\n", SONY_PIC_DRIVER_NAME, SONY_LAPTOP_DRIVER_VERSION); |
3226 | SONY_LAPTOP_DRIVER_VERSION); | ||
3227 | 3219 | ||
3228 | spic_dev.acpi_dev = device; | 3220 | spic_dev.acpi_dev = device; |
3229 | strcpy(acpi_device_class(device), "sony/hotkey"); | 3221 | strcpy(acpi_device_class(device), "sony/hotkey"); |
@@ -3233,14 +3225,14 @@ static int sony_pic_add(struct acpi_device *device) | |||
3233 | /* read _PRS resources */ | 3225 | /* read _PRS resources */ |
3234 | result = sony_pic_possible_resources(device); | 3226 | result = sony_pic_possible_resources(device); |
3235 | if (result) { | 3227 | if (result) { |
3236 | pr_err(DRV_PFX "Unable to read possible resources.\n"); | 3228 | pr_err("Unable to read possible resources\n"); |
3237 | goto err_free_resources; | 3229 | goto err_free_resources; |
3238 | } | 3230 | } |
3239 | 3231 | ||
3240 | /* setup input devices and helper fifo */ | 3232 | /* setup input devices and helper fifo */ |
3241 | result = sony_laptop_setup_input(device); | 3233 | result = sony_laptop_setup_input(device); |
3242 | if (result) { | 3234 | if (result) { |
3243 | pr_err(DRV_PFX "Unable to create input devices.\n"); | 3235 | pr_err("Unable to create input devices\n"); |
3244 | goto err_free_resources; | 3236 | goto err_free_resources; |
3245 | } | 3237 | } |
3246 | 3238 | ||
@@ -3281,7 +3273,7 @@ static int sony_pic_add(struct acpi_device *device) | |||
3281 | } | 3273 | } |
3282 | } | 3274 | } |
3283 | if (!spic_dev.cur_ioport) { | 3275 | if (!spic_dev.cur_ioport) { |
3284 | pr_err(DRV_PFX "Failed to request_region.\n"); | 3276 | pr_err("Failed to request_region\n"); |
3285 | result = -ENODEV; | 3277 | result = -ENODEV; |
3286 | goto err_remove_compat; | 3278 | goto err_remove_compat; |
3287 | } | 3279 | } |
@@ -3301,7 +3293,7 @@ static int sony_pic_add(struct acpi_device *device) | |||
3301 | } | 3293 | } |
3302 | } | 3294 | } |
3303 | if (!spic_dev.cur_irq) { | 3295 | if (!spic_dev.cur_irq) { |
3304 | pr_err(DRV_PFX "Failed to request_irq.\n"); | 3296 | pr_err("Failed to request_irq\n"); |
3305 | result = -ENODEV; | 3297 | result = -ENODEV; |
3306 | goto err_release_region; | 3298 | goto err_release_region; |
3307 | } | 3299 | } |
@@ -3309,7 +3301,7 @@ static int sony_pic_add(struct acpi_device *device) | |||
3309 | /* set resource status _SRS */ | 3301 | /* set resource status _SRS */ |
3310 | result = sony_pic_enable(device, spic_dev.cur_ioport, spic_dev.cur_irq); | 3302 | result = sony_pic_enable(device, spic_dev.cur_ioport, spic_dev.cur_irq); |
3311 | if (result) { | 3303 | if (result) { |
3312 | pr_err(DRV_PFX "Couldn't enable device.\n"); | 3304 | pr_err("Couldn't enable device\n"); |
3313 | goto err_free_irq; | 3305 | goto err_free_irq; |
3314 | } | 3306 | } |
3315 | 3307 | ||
@@ -3418,7 +3410,7 @@ static int __init sony_laptop_init(void) | |||
3418 | if (!no_spic && dmi_check_system(sonypi_dmi_table)) { | 3410 | if (!no_spic && dmi_check_system(sonypi_dmi_table)) { |
3419 | result = acpi_bus_register_driver(&sony_pic_driver); | 3411 | result = acpi_bus_register_driver(&sony_pic_driver); |
3420 | if (result) { | 3412 | if (result) { |
3421 | pr_err(DRV_PFX "Unable to register SPIC driver."); | 3413 | pr_err("Unable to register SPIC driver\n"); |
3422 | goto out; | 3414 | goto out; |
3423 | } | 3415 | } |
3424 | spic_drv_registered = 1; | 3416 | spic_drv_registered = 1; |
@@ -3426,7 +3418,7 @@ static int __init sony_laptop_init(void) | |||
3426 | 3418 | ||
3427 | result = acpi_bus_register_driver(&sony_nc_driver); | 3419 | result = acpi_bus_register_driver(&sony_nc_driver); |
3428 | if (result) { | 3420 | if (result) { |
3429 | pr_err(DRV_PFX "Unable to register SNC driver."); | 3421 | pr_err("Unable to register SNC driver\n"); |
3430 | goto out_unregister_pic; | 3422 | goto out_unregister_pic; |
3431 | } | 3423 | } |
3432 | 3424 | ||
diff --git a/drivers/platform/x86/tc1100-wmi.c b/drivers/platform/x86/tc1100-wmi.c index 865ef78d6f1a..e24f5ae475af 100644 --- a/drivers/platform/x86/tc1100-wmi.c +++ b/drivers/platform/x86/tc1100-wmi.c | |||
@@ -25,6 +25,8 @@ | |||
25 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 25 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
26 | */ | 26 | */ |
27 | 27 | ||
28 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
29 | |||
28 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
29 | #include <linux/module.h> | 31 | #include <linux/module.h> |
30 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
@@ -40,9 +42,6 @@ | |||
40 | #define TC1100_INSTANCE_WIRELESS 1 | 42 | #define TC1100_INSTANCE_WIRELESS 1 |
41 | #define TC1100_INSTANCE_JOGDIAL 2 | 43 | #define TC1100_INSTANCE_JOGDIAL 2 |
42 | 44 | ||
43 | #define TC1100_LOGPREFIX "tc1100-wmi: " | ||
44 | #define TC1100_INFO KERN_INFO TC1100_LOGPREFIX | ||
45 | |||
46 | MODULE_AUTHOR("Jamey Hicks, Carlos Corbacho"); | 45 | MODULE_AUTHOR("Jamey Hicks, Carlos Corbacho"); |
47 | MODULE_DESCRIPTION("HP Compaq TC1100 Tablet WMI Extras"); | 46 | MODULE_DESCRIPTION("HP Compaq TC1100 Tablet WMI Extras"); |
48 | MODULE_LICENSE("GPL"); | 47 | MODULE_LICENSE("GPL"); |
@@ -264,7 +263,7 @@ static int __init tc1100_init(void) | |||
264 | if (error) | 263 | if (error) |
265 | goto err_device_del; | 264 | goto err_device_del; |
266 | 265 | ||
267 | printk(TC1100_INFO "HP Compaq TC1100 Tablet WMI Extras loaded\n"); | 266 | pr_info("HP Compaq TC1100 Tablet WMI Extras loaded\n"); |
268 | return 0; | 267 | return 0; |
269 | 268 | ||
270 | err_device_del: | 269 | err_device_del: |
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 562fcf0dd2b5..77f6e707a2a9 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
@@ -21,6 +21,8 @@ | |||
21 | * 02110-1301, USA. | 21 | * 02110-1301, USA. |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
25 | |||
24 | #define TPACPI_VERSION "0.24" | 26 | #define TPACPI_VERSION "0.24" |
25 | #define TPACPI_SYSFS_VERSION 0x020700 | 27 | #define TPACPI_SYSFS_VERSION 0x020700 |
26 | 28 | ||
@@ -224,17 +226,6 @@ enum tpacpi_hkey_event_t { | |||
224 | 226 | ||
225 | #define TPACPI_MAX_ACPI_ARGS 3 | 227 | #define TPACPI_MAX_ACPI_ARGS 3 |
226 | 228 | ||
227 | /* printk headers */ | ||
228 | #define TPACPI_LOG TPACPI_FILE ": " | ||
229 | #define TPACPI_EMERG KERN_EMERG TPACPI_LOG | ||
230 | #define TPACPI_ALERT KERN_ALERT TPACPI_LOG | ||
231 | #define TPACPI_CRIT KERN_CRIT TPACPI_LOG | ||
232 | #define TPACPI_ERR KERN_ERR TPACPI_LOG | ||
233 | #define TPACPI_WARN KERN_WARNING TPACPI_LOG | ||
234 | #define TPACPI_NOTICE KERN_NOTICE TPACPI_LOG | ||
235 | #define TPACPI_INFO KERN_INFO TPACPI_LOG | ||
236 | #define TPACPI_DEBUG KERN_DEBUG TPACPI_LOG | ||
237 | |||
238 | /* Debugging printk groups */ | 229 | /* Debugging printk groups */ |
239 | #define TPACPI_DBG_ALL 0xffff | 230 | #define TPACPI_DBG_ALL 0xffff |
240 | #define TPACPI_DBG_DISCLOSETASK 0x8000 | 231 | #define TPACPI_DBG_DISCLOSETASK 0x8000 |
@@ -389,34 +380,36 @@ static int tpacpi_uwb_emulstate; | |||
389 | * Debugging helpers | 380 | * Debugging helpers |
390 | */ | 381 | */ |
391 | 382 | ||
392 | #define dbg_printk(a_dbg_level, format, arg...) \ | 383 | #define dbg_printk(a_dbg_level, format, arg...) \ |
393 | do { if (dbg_level & (a_dbg_level)) \ | 384 | do { \ |
394 | printk(TPACPI_DEBUG "%s: " format, __func__ , ## arg); \ | 385 | if (dbg_level & (a_dbg_level)) \ |
395 | } while (0) | 386 | printk(KERN_DEBUG pr_fmt("%s: " format), \ |
387 | __func__, ##arg); \ | ||
388 | } while (0) | ||
396 | 389 | ||
397 | #ifdef CONFIG_THINKPAD_ACPI_DEBUG | 390 | #ifdef CONFIG_THINKPAD_ACPI_DEBUG |
398 | #define vdbg_printk dbg_printk | 391 | #define vdbg_printk dbg_printk |
399 | static const char *str_supported(int is_supported); | 392 | static const char *str_supported(int is_supported); |
400 | #else | 393 | #else |
401 | #define vdbg_printk(a_dbg_level, format, arg...) \ | 394 | static inline const char *str_supported(int is_supported) { return ""; } |
402 | do { } while (0) | 395 | #define vdbg_printk(a_dbg_level, format, arg...) \ |
396 | no_printk(format, ##arg) | ||
403 | #endif | 397 | #endif |
404 | 398 | ||
405 | static void tpacpi_log_usertask(const char * const what) | 399 | static void tpacpi_log_usertask(const char * const what) |
406 | { | 400 | { |
407 | printk(TPACPI_DEBUG "%s: access by process with PID %d\n", | 401 | printk(KERN_DEBUG pr_fmt("%s: access by process with PID %d\n"), |
408 | what, task_tgid_vnr(current)); | 402 | what, task_tgid_vnr(current)); |
409 | } | 403 | } |
410 | 404 | ||
411 | #define tpacpi_disclose_usertask(what, format, arg...) \ | 405 | #define tpacpi_disclose_usertask(what, format, arg...) \ |
412 | do { \ | 406 | do { \ |
413 | if (unlikely( \ | 407 | if (unlikely((dbg_level & TPACPI_DBG_DISCLOSETASK) && \ |
414 | (dbg_level & TPACPI_DBG_DISCLOSETASK) && \ | 408 | (tpacpi_lifecycle == TPACPI_LIFE_RUNNING))) { \ |
415 | (tpacpi_lifecycle == TPACPI_LIFE_RUNNING))) { \ | 409 | printk(KERN_DEBUG pr_fmt("%s: PID %d: " format), \ |
416 | printk(TPACPI_DEBUG "%s: PID %d: " format, \ | 410 | what, task_tgid_vnr(current), ## arg); \ |
417 | what, task_tgid_vnr(current), ## arg); \ | 411 | } \ |
418 | } \ | 412 | } while (0) |
419 | } while (0) | ||
420 | 413 | ||
421 | /* | 414 | /* |
422 | * Quirk handling helpers | 415 | * Quirk handling helpers |
@@ -535,15 +528,6 @@ TPACPI_HANDLE(hkey, ec, "\\_SB.HKEY", /* 600e/x, 770e, 770x */ | |||
535 | "HKEY", /* all others */ | 528 | "HKEY", /* all others */ |
536 | ); /* 570 */ | 529 | ); /* 570 */ |
537 | 530 | ||
538 | TPACPI_HANDLE(vid, root, "\\_SB.PCI.AGP.VGA", /* 570 */ | ||
539 | "\\_SB.PCI0.AGP0.VID0", /* 600e/x, 770x */ | ||
540 | "\\_SB.PCI0.VID0", /* 770e */ | ||
541 | "\\_SB.PCI0.VID", /* A21e, G4x, R50e, X30, X40 */ | ||
542 | "\\_SB.PCI0.AGP.VGA", /* X100e and a few others */ | ||
543 | "\\_SB.PCI0.AGP.VID", /* all others */ | ||
544 | ); /* R30, R31 */ | ||
545 | |||
546 | |||
547 | /************************************************************************* | 531 | /************************************************************************* |
548 | * ACPI helpers | 532 | * ACPI helpers |
549 | */ | 533 | */ |
@@ -563,7 +547,7 @@ static int acpi_evalf(acpi_handle handle, | |||
563 | int quiet; | 547 | int quiet; |
564 | 548 | ||
565 | if (!*fmt) { | 549 | if (!*fmt) { |
566 | printk(TPACPI_ERR "acpi_evalf() called with empty format\n"); | 550 | pr_err("acpi_evalf() called with empty format\n"); |
567 | return 0; | 551 | return 0; |
568 | } | 552 | } |
569 | 553 | ||
@@ -588,7 +572,7 @@ static int acpi_evalf(acpi_handle handle, | |||
588 | break; | 572 | break; |
589 | /* add more types as needed */ | 573 | /* add more types as needed */ |
590 | default: | 574 | default: |
591 | printk(TPACPI_ERR "acpi_evalf() called " | 575 | pr_err("acpi_evalf() called " |
592 | "with invalid format character '%c'\n", c); | 576 | "with invalid format character '%c'\n", c); |
593 | va_end(ap); | 577 | va_end(ap); |
594 | return 0; | 578 | return 0; |
@@ -617,13 +601,13 @@ static int acpi_evalf(acpi_handle handle, | |||
617 | break; | 601 | break; |
618 | /* add more types as needed */ | 602 | /* add more types as needed */ |
619 | default: | 603 | default: |
620 | printk(TPACPI_ERR "acpi_evalf() called " | 604 | pr_err("acpi_evalf() called " |
621 | "with invalid format character '%c'\n", res_type); | 605 | "with invalid format character '%c'\n", res_type); |
622 | return 0; | 606 | return 0; |
623 | } | 607 | } |
624 | 608 | ||
625 | if (!success && !quiet) | 609 | if (!success && !quiet) |
626 | printk(TPACPI_ERR "acpi_evalf(%s, %s, ...) failed: %s\n", | 610 | pr_err("acpi_evalf(%s, %s, ...) failed: %s\n", |
627 | method, fmt0, acpi_format_exception(status)); | 611 | method, fmt0, acpi_format_exception(status)); |
628 | 612 | ||
629 | return success; | 613 | return success; |
@@ -767,8 +751,7 @@ static int __init setup_acpi_notify(struct ibm_struct *ibm) | |||
767 | 751 | ||
768 | rc = acpi_bus_get_device(*ibm->acpi->handle, &ibm->acpi->device); | 752 | rc = acpi_bus_get_device(*ibm->acpi->handle, &ibm->acpi->device); |
769 | if (rc < 0) { | 753 | if (rc < 0) { |
770 | printk(TPACPI_ERR "acpi_bus_get_device(%s) failed: %d\n", | 754 | pr_err("acpi_bus_get_device(%s) failed: %d\n", ibm->name, rc); |
771 | ibm->name, rc); | ||
772 | return -ENODEV; | 755 | return -ENODEV; |
773 | } | 756 | } |
774 | 757 | ||
@@ -781,12 +764,10 @@ static int __init setup_acpi_notify(struct ibm_struct *ibm) | |||
781 | ibm->acpi->type, dispatch_acpi_notify, ibm); | 764 | ibm->acpi->type, dispatch_acpi_notify, ibm); |
782 | if (ACPI_FAILURE(status)) { | 765 | if (ACPI_FAILURE(status)) { |
783 | if (status == AE_ALREADY_EXISTS) { | 766 | if (status == AE_ALREADY_EXISTS) { |
784 | printk(TPACPI_NOTICE | 767 | pr_notice("another device driver is already " |
785 | "another device driver is already " | 768 | "handling %s events\n", ibm->name); |
786 | "handling %s events\n", ibm->name); | ||
787 | } else { | 769 | } else { |
788 | printk(TPACPI_ERR | 770 | pr_err("acpi_install_notify_handler(%s) failed: %s\n", |
789 | "acpi_install_notify_handler(%s) failed: %s\n", | ||
790 | ibm->name, acpi_format_exception(status)); | 771 | ibm->name, acpi_format_exception(status)); |
791 | } | 772 | } |
792 | return -ENODEV; | 773 | return -ENODEV; |
@@ -811,8 +792,7 @@ static int __init register_tpacpi_subdriver(struct ibm_struct *ibm) | |||
811 | 792 | ||
812 | ibm->acpi->driver = kzalloc(sizeof(struct acpi_driver), GFP_KERNEL); | 793 | ibm->acpi->driver = kzalloc(sizeof(struct acpi_driver), GFP_KERNEL); |
813 | if (!ibm->acpi->driver) { | 794 | if (!ibm->acpi->driver) { |
814 | printk(TPACPI_ERR | 795 | pr_err("failed to allocate memory for ibm->acpi->driver\n"); |
815 | "failed to allocate memory for ibm->acpi->driver\n"); | ||
816 | return -ENOMEM; | 796 | return -ENOMEM; |
817 | } | 797 | } |
818 | 798 | ||
@@ -823,7 +803,7 @@ static int __init register_tpacpi_subdriver(struct ibm_struct *ibm) | |||
823 | 803 | ||
824 | rc = acpi_bus_register_driver(ibm->acpi->driver); | 804 | rc = acpi_bus_register_driver(ibm->acpi->driver); |
825 | if (rc < 0) { | 805 | if (rc < 0) { |
826 | printk(TPACPI_ERR "acpi_bus_register_driver(%s) failed: %d\n", | 806 | pr_err("acpi_bus_register_driver(%s) failed: %d\n", |
827 | ibm->name, rc); | 807 | ibm->name, rc); |
828 | kfree(ibm->acpi->driver); | 808 | kfree(ibm->acpi->driver); |
829 | ibm->acpi->driver = NULL; | 809 | ibm->acpi->driver = NULL; |
@@ -1081,15 +1061,14 @@ static int parse_strtoul(const char *buf, | |||
1081 | static void tpacpi_disable_brightness_delay(void) | 1061 | static void tpacpi_disable_brightness_delay(void) |
1082 | { | 1062 | { |
1083 | if (acpi_evalf(hkey_handle, NULL, "PWMS", "qvd", 0)) | 1063 | if (acpi_evalf(hkey_handle, NULL, "PWMS", "qvd", 0)) |
1084 | printk(TPACPI_NOTICE | 1064 | pr_notice("ACPI backlight control delay disabled\n"); |
1085 | "ACPI backlight control delay disabled\n"); | ||
1086 | } | 1065 | } |
1087 | 1066 | ||
1088 | static void printk_deprecated_attribute(const char * const what, | 1067 | static void printk_deprecated_attribute(const char * const what, |
1089 | const char * const details) | 1068 | const char * const details) |
1090 | { | 1069 | { |
1091 | tpacpi_log_usertask("deprecated sysfs attribute"); | 1070 | tpacpi_log_usertask("deprecated sysfs attribute"); |
1092 | printk(TPACPI_WARN "WARNING: sysfs attribute %s is deprecated and " | 1071 | pr_warn("WARNING: sysfs attribute %s is deprecated and " |
1093 | "will be removed. %s\n", | 1072 | "will be removed. %s\n", |
1094 | what, details); | 1073 | what, details); |
1095 | } | 1074 | } |
@@ -1264,8 +1243,7 @@ static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id, | |||
1264 | &tpacpi_rfk_rfkill_ops, | 1243 | &tpacpi_rfk_rfkill_ops, |
1265 | atp_rfk); | 1244 | atp_rfk); |
1266 | if (!atp_rfk || !atp_rfk->rfkill) { | 1245 | if (!atp_rfk || !atp_rfk->rfkill) { |
1267 | printk(TPACPI_ERR | 1246 | pr_err("failed to allocate memory for rfkill class\n"); |
1268 | "failed to allocate memory for rfkill class\n"); | ||
1269 | kfree(atp_rfk); | 1247 | kfree(atp_rfk); |
1270 | return -ENOMEM; | 1248 | return -ENOMEM; |
1271 | } | 1249 | } |
@@ -1275,9 +1253,8 @@ static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id, | |||
1275 | 1253 | ||
1276 | sw_status = (tp_rfkops->get_status)(); | 1254 | sw_status = (tp_rfkops->get_status)(); |
1277 | if (sw_status < 0) { | 1255 | if (sw_status < 0) { |
1278 | printk(TPACPI_ERR | 1256 | pr_err("failed to read initial state for %s, error %d\n", |
1279 | "failed to read initial state for %s, error %d\n", | 1257 | name, sw_status); |
1280 | name, sw_status); | ||
1281 | } else { | 1258 | } else { |
1282 | sw_state = (sw_status == TPACPI_RFK_RADIO_OFF); | 1259 | sw_state = (sw_status == TPACPI_RFK_RADIO_OFF); |
1283 | if (set_default) { | 1260 | if (set_default) { |
@@ -1291,9 +1268,7 @@ static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id, | |||
1291 | 1268 | ||
1292 | res = rfkill_register(atp_rfk->rfkill); | 1269 | res = rfkill_register(atp_rfk->rfkill); |
1293 | if (res < 0) { | 1270 | if (res < 0) { |
1294 | printk(TPACPI_ERR | 1271 | pr_err("failed to register %s rfkill switch: %d\n", name, res); |
1295 | "failed to register %s rfkill switch: %d\n", | ||
1296 | name, res); | ||
1297 | rfkill_destroy(atp_rfk->rfkill); | 1272 | rfkill_destroy(atp_rfk->rfkill); |
1298 | kfree(atp_rfk); | 1273 | kfree(atp_rfk); |
1299 | return res; | 1274 | return res; |
@@ -1301,7 +1276,7 @@ static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id, | |||
1301 | 1276 | ||
1302 | tpacpi_rfkill_switches[id] = atp_rfk; | 1277 | tpacpi_rfkill_switches[id] = atp_rfk; |
1303 | 1278 | ||
1304 | printk(TPACPI_INFO "rfkill switch %s: radio is %sblocked\n", | 1279 | pr_info("rfkill switch %s: radio is %sblocked\n", |
1305 | name, (sw_state || hw_state) ? "" : "un"); | 1280 | name, (sw_state || hw_state) ? "" : "un"); |
1306 | return 0; | 1281 | return 0; |
1307 | } | 1282 | } |
@@ -1825,10 +1800,8 @@ static void __init tpacpi_check_outdated_fw(void) | |||
1825 | * broken, or really stable to begin with, so it is | 1800 | * broken, or really stable to begin with, so it is |
1826 | * best if the user upgrades the firmware anyway. | 1801 | * best if the user upgrades the firmware anyway. |
1827 | */ | 1802 | */ |
1828 | printk(TPACPI_WARN | 1803 | pr_warn("WARNING: Outdated ThinkPad BIOS/EC firmware\n"); |
1829 | "WARNING: Outdated ThinkPad BIOS/EC firmware\n"); | 1804 | pr_warn("WARNING: This firmware may be missing critical bug " |
1830 | printk(TPACPI_WARN | ||
1831 | "WARNING: This firmware may be missing critical bug " | ||
1832 | "fixes and/or important features\n"); | 1805 | "fixes and/or important features\n"); |
1833 | } | 1806 | } |
1834 | } | 1807 | } |
@@ -2117,9 +2090,7 @@ void static hotkey_mask_warn_incomplete_mask(void) | |||
2117 | (hotkey_all_mask | TPACPI_HKEY_NVRAM_KNOWN_MASK); | 2090 | (hotkey_all_mask | TPACPI_HKEY_NVRAM_KNOWN_MASK); |
2118 | 2091 | ||
2119 | if (wantedmask) | 2092 | if (wantedmask) |
2120 | printk(TPACPI_NOTICE | 2093 | pr_notice("required events 0x%08x not enabled!\n", wantedmask); |
2121 | "required events 0x%08x not enabled!\n", | ||
2122 | wantedmask); | ||
2123 | } | 2094 | } |
2124 | 2095 | ||
2125 | /* | 2096 | /* |
@@ -2157,10 +2128,9 @@ static int hotkey_mask_set(u32 mask) | |||
2157 | * a given event. | 2128 | * a given event. |
2158 | */ | 2129 | */ |
2159 | if (!hotkey_mask_get() && !rc && (fwmask & ~hotkey_acpi_mask)) { | 2130 | if (!hotkey_mask_get() && !rc && (fwmask & ~hotkey_acpi_mask)) { |
2160 | printk(TPACPI_NOTICE | 2131 | pr_notice("asked for hotkey mask 0x%08x, but " |
2161 | "asked for hotkey mask 0x%08x, but " | 2132 | "firmware forced it to 0x%08x\n", |
2162 | "firmware forced it to 0x%08x\n", | 2133 | fwmask, hotkey_acpi_mask); |
2163 | fwmask, hotkey_acpi_mask); | ||
2164 | } | 2134 | } |
2165 | 2135 | ||
2166 | if (tpacpi_lifecycle != TPACPI_LIFE_EXITING) | 2136 | if (tpacpi_lifecycle != TPACPI_LIFE_EXITING) |
@@ -2184,13 +2154,11 @@ static int hotkey_user_mask_set(const u32 mask) | |||
2184 | (mask == 0xffff || mask == 0xffffff || | 2154 | (mask == 0xffff || mask == 0xffffff || |
2185 | mask == 0xffffffff)) { | 2155 | mask == 0xffffffff)) { |
2186 | tp_warned.hotkey_mask_ff = 1; | 2156 | tp_warned.hotkey_mask_ff = 1; |
2187 | printk(TPACPI_NOTICE | 2157 | pr_notice("setting the hotkey mask to 0x%08x is likely " |
2188 | "setting the hotkey mask to 0x%08x is likely " | 2158 | "not the best way to go about it\n", mask); |
2189 | "not the best way to go about it\n", mask); | 2159 | pr_notice("please consider using the driver defaults, " |
2190 | printk(TPACPI_NOTICE | 2160 | "and refer to up-to-date thinkpad-acpi " |
2191 | "please consider using the driver defaults, " | 2161 | "documentation\n"); |
2192 | "and refer to up-to-date thinkpad-acpi " | ||
2193 | "documentation\n"); | ||
2194 | } | 2162 | } |
2195 | 2163 | ||
2196 | /* Try to enable what the user asked for, plus whatever we need. | 2164 | /* Try to enable what the user asked for, plus whatever we need. |
@@ -2574,8 +2542,7 @@ static void hotkey_poll_setup(const bool may_warn) | |||
2574 | NULL, TPACPI_NVRAM_KTHREAD_NAME); | 2542 | NULL, TPACPI_NVRAM_KTHREAD_NAME); |
2575 | if (IS_ERR(tpacpi_hotkey_task)) { | 2543 | if (IS_ERR(tpacpi_hotkey_task)) { |
2576 | tpacpi_hotkey_task = NULL; | 2544 | tpacpi_hotkey_task = NULL; |
2577 | printk(TPACPI_ERR | 2545 | pr_err("could not create kernel thread " |
2578 | "could not create kernel thread " | ||
2579 | "for hotkey polling\n"); | 2546 | "for hotkey polling\n"); |
2580 | } | 2547 | } |
2581 | } | 2548 | } |
@@ -2583,11 +2550,10 @@ static void hotkey_poll_setup(const bool may_warn) | |||
2583 | hotkey_poll_stop_sync(); | 2550 | hotkey_poll_stop_sync(); |
2584 | if (may_warn && (poll_driver_mask || poll_user_mask) && | 2551 | if (may_warn && (poll_driver_mask || poll_user_mask) && |
2585 | hotkey_poll_freq == 0) { | 2552 | hotkey_poll_freq == 0) { |
2586 | printk(TPACPI_NOTICE | 2553 | pr_notice("hot keys 0x%08x and/or events 0x%08x " |
2587 | "hot keys 0x%08x and/or events 0x%08x " | 2554 | "require polling, which is currently " |
2588 | "require polling, which is currently " | 2555 | "disabled\n", |
2589 | "disabled\n", | 2556 | poll_user_mask, poll_driver_mask); |
2590 | poll_user_mask, poll_driver_mask); | ||
2591 | } | 2557 | } |
2592 | } | 2558 | } |
2593 | } | 2559 | } |
@@ -2811,13 +2777,13 @@ static ssize_t hotkey_source_mask_store(struct device *dev, | |||
2811 | mutex_unlock(&hotkey_mutex); | 2777 | mutex_unlock(&hotkey_mutex); |
2812 | 2778 | ||
2813 | if (rc < 0) | 2779 | if (rc < 0) |
2814 | printk(TPACPI_ERR "hotkey_source_mask: failed to update the" | 2780 | pr_err("hotkey_source_mask: " |
2815 | "firmware event mask!\n"); | 2781 | "failed to update the firmware event mask!\n"); |
2816 | 2782 | ||
2817 | if (r_ev) | 2783 | if (r_ev) |
2818 | printk(TPACPI_NOTICE "hotkey_source_mask: " | 2784 | pr_notice("hotkey_source_mask: " |
2819 | "some important events were disabled: " | 2785 | "some important events were disabled: 0x%04x\n", |
2820 | "0x%04x\n", r_ev); | 2786 | r_ev); |
2821 | 2787 | ||
2822 | tpacpi_disclose_usertask("hotkey_source_mask", "set to 0x%08lx\n", t); | 2788 | tpacpi_disclose_usertask("hotkey_source_mask", "set to 0x%08lx\n", t); |
2823 | 2789 | ||
@@ -3048,8 +3014,7 @@ static void hotkey_exit(void) | |||
3048 | if (((tp_features.hotkey_mask && | 3014 | if (((tp_features.hotkey_mask && |
3049 | hotkey_mask_set(hotkey_orig_mask)) | | 3015 | hotkey_mask_set(hotkey_orig_mask)) | |
3050 | hotkey_status_set(false)) != 0) | 3016 | hotkey_status_set(false)) != 0) |
3051 | printk(TPACPI_ERR | 3017 | pr_err("failed to restore hot key mask " |
3052 | "failed to restore hot key mask " | ||
3053 | "to BIOS defaults\n"); | 3018 | "to BIOS defaults\n"); |
3054 | } | 3019 | } |
3055 | 3020 | ||
@@ -3288,10 +3253,9 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
3288 | for HKEY interface version 0x100 */ | 3253 | for HKEY interface version 0x100 */ |
3289 | if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) { | 3254 | if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) { |
3290 | if ((hkeyv >> 8) != 1) { | 3255 | if ((hkeyv >> 8) != 1) { |
3291 | printk(TPACPI_ERR "unknown version of the " | 3256 | pr_err("unknown version of the HKEY interface: 0x%x\n", |
3292 | "HKEY interface: 0x%x\n", hkeyv); | 3257 | hkeyv); |
3293 | printk(TPACPI_ERR "please report this to %s\n", | 3258 | pr_err("please report this to %s\n", TPACPI_MAIL); |
3294 | TPACPI_MAIL); | ||
3295 | } else { | 3259 | } else { |
3296 | /* | 3260 | /* |
3297 | * MHKV 0x100 in A31, R40, R40e, | 3261 | * MHKV 0x100 in A31, R40, R40e, |
@@ -3304,8 +3268,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
3304 | /* Paranoia check AND init hotkey_all_mask */ | 3268 | /* Paranoia check AND init hotkey_all_mask */ |
3305 | if (!acpi_evalf(hkey_handle, &hotkey_all_mask, | 3269 | if (!acpi_evalf(hkey_handle, &hotkey_all_mask, |
3306 | "MHKA", "qd")) { | 3270 | "MHKA", "qd")) { |
3307 | printk(TPACPI_ERR | 3271 | pr_err("missing MHKA handler, " |
3308 | "missing MHKA handler, " | ||
3309 | "please report this to %s\n", | 3272 | "please report this to %s\n", |
3310 | TPACPI_MAIL); | 3273 | TPACPI_MAIL); |
3311 | /* Fallback: pre-init for FN+F3,F4,F12 */ | 3274 | /* Fallback: pre-init for FN+F3,F4,F12 */ |
@@ -3343,16 +3306,14 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
3343 | if (dbg_wlswemul) { | 3306 | if (dbg_wlswemul) { |
3344 | tp_features.hotkey_wlsw = 1; | 3307 | tp_features.hotkey_wlsw = 1; |
3345 | radiosw_state = !!tpacpi_wlsw_emulstate; | 3308 | radiosw_state = !!tpacpi_wlsw_emulstate; |
3346 | printk(TPACPI_INFO | 3309 | pr_info("radio switch emulation enabled\n"); |
3347 | "radio switch emulation enabled\n"); | ||
3348 | } else | 3310 | } else |
3349 | #endif | 3311 | #endif |
3350 | /* Not all thinkpads have a hardware radio switch */ | 3312 | /* Not all thinkpads have a hardware radio switch */ |
3351 | if (acpi_evalf(hkey_handle, &status, "WLSW", "qd")) { | 3313 | if (acpi_evalf(hkey_handle, &status, "WLSW", "qd")) { |
3352 | tp_features.hotkey_wlsw = 1; | 3314 | tp_features.hotkey_wlsw = 1; |
3353 | radiosw_state = !!status; | 3315 | radiosw_state = !!status; |
3354 | printk(TPACPI_INFO | 3316 | pr_info("radio switch found; radios are %s\n", |
3355 | "radio switch found; radios are %s\n", | ||
3356 | enabled(status, 0)); | 3317 | enabled(status, 0)); |
3357 | } | 3318 | } |
3358 | if (tp_features.hotkey_wlsw) | 3319 | if (tp_features.hotkey_wlsw) |
@@ -3363,8 +3324,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
3363 | if (!res && acpi_evalf(hkey_handle, &status, "MHKG", "qd")) { | 3324 | if (!res && acpi_evalf(hkey_handle, &status, "MHKG", "qd")) { |
3364 | tp_features.hotkey_tablet = 1; | 3325 | tp_features.hotkey_tablet = 1; |
3365 | tabletsw_state = !!(status & TP_HOTKEY_TABLET_MASK); | 3326 | tabletsw_state = !!(status & TP_HOTKEY_TABLET_MASK); |
3366 | printk(TPACPI_INFO | 3327 | pr_info("possible tablet mode switch found; " |
3367 | "possible tablet mode switch found; " | ||
3368 | "ThinkPad in %s mode\n", | 3328 | "ThinkPad in %s mode\n", |
3369 | (tabletsw_state) ? "tablet" : "laptop"); | 3329 | (tabletsw_state) ? "tablet" : "laptop"); |
3370 | res = add_to_attr_set(hotkey_dev_attributes, | 3330 | res = add_to_attr_set(hotkey_dev_attributes, |
@@ -3382,8 +3342,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
3382 | hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE, | 3342 | hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE, |
3383 | GFP_KERNEL); | 3343 | GFP_KERNEL); |
3384 | if (!hotkey_keycode_map) { | 3344 | if (!hotkey_keycode_map) { |
3385 | printk(TPACPI_ERR | 3345 | pr_err("failed to allocate memory for key map\n"); |
3386 | "failed to allocate memory for key map\n"); | ||
3387 | res = -ENOMEM; | 3346 | res = -ENOMEM; |
3388 | goto err_exit; | 3347 | goto err_exit; |
3389 | } | 3348 | } |
@@ -3426,13 +3385,11 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
3426 | * userspace. tpacpi_detect_brightness_capabilities() must have | 3385 | * userspace. tpacpi_detect_brightness_capabilities() must have |
3427 | * been called before this point */ | 3386 | * been called before this point */ |
3428 | if (tp_features.bright_acpimode && acpi_video_backlight_support()) { | 3387 | if (tp_features.bright_acpimode && acpi_video_backlight_support()) { |
3429 | printk(TPACPI_INFO | 3388 | pr_info("This ThinkPad has standard ACPI backlight " |
3430 | "This ThinkPad has standard ACPI backlight " | 3389 | "brightness control, supported by the ACPI " |
3431 | "brightness control, supported by the ACPI " | 3390 | "video driver\n"); |
3432 | "video driver\n"); | 3391 | pr_notice("Disabling thinkpad-acpi brightness events " |
3433 | printk(TPACPI_NOTICE | 3392 | "by default...\n"); |
3434 | "Disabling thinkpad-acpi brightness events " | ||
3435 | "by default...\n"); | ||
3436 | 3393 | ||
3437 | /* Disable brightness up/down on Lenovo thinkpads when | 3394 | /* Disable brightness up/down on Lenovo thinkpads when |
3438 | * ACPI is handling them, otherwise it is plain impossible | 3395 | * ACPI is handling them, otherwise it is plain impossible |
@@ -3539,8 +3496,7 @@ static bool hotkey_notify_wakeup(const u32 hkey, | |||
3539 | 3496 | ||
3540 | case TP_HKEY_EV_WKUP_S3_BATLOW: /* Battery on critical low level/S3 */ | 3497 | case TP_HKEY_EV_WKUP_S3_BATLOW: /* Battery on critical low level/S3 */ |
3541 | case TP_HKEY_EV_WKUP_S4_BATLOW: /* Battery on critical low level/S4 */ | 3498 | case TP_HKEY_EV_WKUP_S4_BATLOW: /* Battery on critical low level/S4 */ |
3542 | printk(TPACPI_ALERT | 3499 | pr_alert("EMERGENCY WAKEUP: battery almost empty\n"); |
3543 | "EMERGENCY WAKEUP: battery almost empty\n"); | ||
3544 | /* how to auto-heal: */ | 3500 | /* how to auto-heal: */ |
3545 | /* 2313: woke up from S3, go to S4/S5 */ | 3501 | /* 2313: woke up from S3, go to S4/S5 */ |
3546 | /* 2413: woke up from S4, go to S5 */ | 3502 | /* 2413: woke up from S4, go to S5 */ |
@@ -3551,9 +3507,7 @@ static bool hotkey_notify_wakeup(const u32 hkey, | |||
3551 | } | 3507 | } |
3552 | 3508 | ||
3553 | if (hotkey_wakeup_reason != TP_ACPI_WAKEUP_NONE) { | 3509 | if (hotkey_wakeup_reason != TP_ACPI_WAKEUP_NONE) { |
3554 | printk(TPACPI_INFO | 3510 | pr_info("woke up due to a hot-unplug request...\n"); |
3555 | "woke up due to a hot-unplug " | ||
3556 | "request...\n"); | ||
3557 | hotkey_wakeup_reason_notify_change(); | 3511 | hotkey_wakeup_reason_notify_change(); |
3558 | } | 3512 | } |
3559 | return true; | 3513 | return true; |
@@ -3605,37 +3559,31 @@ static bool hotkey_notify_thermal(const u32 hkey, | |||
3605 | 3559 | ||
3606 | switch (hkey) { | 3560 | switch (hkey) { |
3607 | case TP_HKEY_EV_THM_TABLE_CHANGED: | 3561 | case TP_HKEY_EV_THM_TABLE_CHANGED: |
3608 | printk(TPACPI_INFO | 3562 | pr_info("EC reports that Thermal Table has changed\n"); |
3609 | "EC reports that Thermal Table has changed\n"); | ||
3610 | /* recommended action: do nothing, we don't have | 3563 | /* recommended action: do nothing, we don't have |
3611 | * Lenovo ATM information */ | 3564 | * Lenovo ATM information */ |
3612 | return true; | 3565 | return true; |
3613 | case TP_HKEY_EV_ALARM_BAT_HOT: | 3566 | case TP_HKEY_EV_ALARM_BAT_HOT: |
3614 | printk(TPACPI_CRIT | 3567 | pr_crit("THERMAL ALARM: battery is too hot!\n"); |
3615 | "THERMAL ALARM: battery is too hot!\n"); | ||
3616 | /* recommended action: warn user through gui */ | 3568 | /* recommended action: warn user through gui */ |
3617 | break; | 3569 | break; |
3618 | case TP_HKEY_EV_ALARM_BAT_XHOT: | 3570 | case TP_HKEY_EV_ALARM_BAT_XHOT: |
3619 | printk(TPACPI_ALERT | 3571 | pr_alert("THERMAL EMERGENCY: battery is extremely hot!\n"); |
3620 | "THERMAL EMERGENCY: battery is extremely hot!\n"); | ||
3621 | /* recommended action: immediate sleep/hibernate */ | 3572 | /* recommended action: immediate sleep/hibernate */ |
3622 | break; | 3573 | break; |
3623 | case TP_HKEY_EV_ALARM_SENSOR_HOT: | 3574 | case TP_HKEY_EV_ALARM_SENSOR_HOT: |
3624 | printk(TPACPI_CRIT | 3575 | pr_crit("THERMAL ALARM: " |
3625 | "THERMAL ALARM: " | ||
3626 | "a sensor reports something is too hot!\n"); | 3576 | "a sensor reports something is too hot!\n"); |
3627 | /* recommended action: warn user through gui, that */ | 3577 | /* recommended action: warn user through gui, that */ |
3628 | /* some internal component is too hot */ | 3578 | /* some internal component is too hot */ |
3629 | break; | 3579 | break; |
3630 | case TP_HKEY_EV_ALARM_SENSOR_XHOT: | 3580 | case TP_HKEY_EV_ALARM_SENSOR_XHOT: |
3631 | printk(TPACPI_ALERT | 3581 | pr_alert("THERMAL EMERGENCY: " |
3632 | "THERMAL EMERGENCY: " | 3582 | "a sensor reports something is extremely hot!\n"); |
3633 | "a sensor reports something is extremely hot!\n"); | ||
3634 | /* recommended action: immediate sleep/hibernate */ | 3583 | /* recommended action: immediate sleep/hibernate */ |
3635 | break; | 3584 | break; |
3636 | default: | 3585 | default: |
3637 | printk(TPACPI_ALERT | 3586 | pr_alert("THERMAL ALERT: unknown thermal alarm received\n"); |
3638 | "THERMAL ALERT: unknown thermal alarm received\n"); | ||
3639 | known = false; | 3587 | known = false; |
3640 | } | 3588 | } |
3641 | 3589 | ||
@@ -3652,8 +3600,7 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) | |||
3652 | bool known_ev; | 3600 | bool known_ev; |
3653 | 3601 | ||
3654 | if (event != 0x80) { | 3602 | if (event != 0x80) { |
3655 | printk(TPACPI_ERR | 3603 | pr_err("unknown HKEY notification event %d\n", event); |
3656 | "unknown HKEY notification event %d\n", event); | ||
3657 | /* forward it to userspace, maybe it knows how to handle it */ | 3604 | /* forward it to userspace, maybe it knows how to handle it */ |
3658 | acpi_bus_generate_netlink_event( | 3605 | acpi_bus_generate_netlink_event( |
3659 | ibm->acpi->device->pnp.device_class, | 3606 | ibm->acpi->device->pnp.device_class, |
@@ -3664,7 +3611,7 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) | |||
3664 | 3611 | ||
3665 | while (1) { | 3612 | while (1) { |
3666 | if (!acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) { | 3613 | if (!acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) { |
3667 | printk(TPACPI_ERR "failed to retrieve HKEY event\n"); | 3614 | pr_err("failed to retrieve HKEY event\n"); |
3668 | return; | 3615 | return; |
3669 | } | 3616 | } |
3670 | 3617 | ||
@@ -3692,8 +3639,7 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) | |||
3692 | switch (hkey) { | 3639 | switch (hkey) { |
3693 | case TP_HKEY_EV_BAYEJ_ACK: | 3640 | case TP_HKEY_EV_BAYEJ_ACK: |
3694 | hotkey_autosleep_ack = 1; | 3641 | hotkey_autosleep_ack = 1; |
3695 | printk(TPACPI_INFO | 3642 | pr_info("bay ejected\n"); |
3696 | "bay ejected\n"); | ||
3697 | hotkey_wakeup_hotunplug_complete_notify_change(); | 3643 | hotkey_wakeup_hotunplug_complete_notify_change(); |
3698 | known_ev = true; | 3644 | known_ev = true; |
3699 | break; | 3645 | break; |
@@ -3709,8 +3655,7 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) | |||
3709 | /* 0x4000-0x4FFF: dock-related wakeups */ | 3655 | /* 0x4000-0x4FFF: dock-related wakeups */ |
3710 | if (hkey == TP_HKEY_EV_UNDOCK_ACK) { | 3656 | if (hkey == TP_HKEY_EV_UNDOCK_ACK) { |
3711 | hotkey_autosleep_ack = 1; | 3657 | hotkey_autosleep_ack = 1; |
3712 | printk(TPACPI_INFO | 3658 | pr_info("undocked\n"); |
3713 | "undocked\n"); | ||
3714 | hotkey_wakeup_hotunplug_complete_notify_change(); | 3659 | hotkey_wakeup_hotunplug_complete_notify_change(); |
3715 | known_ev = true; | 3660 | known_ev = true; |
3716 | } else { | 3661 | } else { |
@@ -3741,11 +3686,9 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) | |||
3741 | known_ev = false; | 3686 | known_ev = false; |
3742 | } | 3687 | } |
3743 | if (!known_ev) { | 3688 | if (!known_ev) { |
3744 | printk(TPACPI_NOTICE | 3689 | pr_notice("unhandled HKEY event 0x%04x\n", hkey); |
3745 | "unhandled HKEY event 0x%04x\n", hkey); | 3690 | pr_notice("please report the conditions when this " |
3746 | printk(TPACPI_NOTICE | 3691 | "event happened to %s\n", TPACPI_MAIL); |
3747 | "please report the conditions when this " | ||
3748 | "event happened to %s\n", TPACPI_MAIL); | ||
3749 | } | 3692 | } |
3750 | 3693 | ||
3751 | /* Legacy events */ | 3694 | /* Legacy events */ |
@@ -3778,8 +3721,7 @@ static void hotkey_resume(void) | |||
3778 | 3721 | ||
3779 | if (hotkey_status_set(true) < 0 || | 3722 | if (hotkey_status_set(true) < 0 || |
3780 | hotkey_mask_set(hotkey_acpi_mask) < 0) | 3723 | hotkey_mask_set(hotkey_acpi_mask) < 0) |
3781 | printk(TPACPI_ERR | 3724 | pr_err("error while attempting to reset the event " |
3782 | "error while attempting to reset the event " | ||
3783 | "firmware interface\n"); | 3725 | "firmware interface\n"); |
3784 | 3726 | ||
3785 | tpacpi_send_radiosw_update(); | 3727 | tpacpi_send_radiosw_update(); |
@@ -3824,14 +3766,12 @@ static void hotkey_enabledisable_warn(bool enable) | |||
3824 | { | 3766 | { |
3825 | tpacpi_log_usertask("procfs hotkey enable/disable"); | 3767 | tpacpi_log_usertask("procfs hotkey enable/disable"); |
3826 | if (!WARN((tpacpi_lifecycle == TPACPI_LIFE_RUNNING || !enable), | 3768 | if (!WARN((tpacpi_lifecycle == TPACPI_LIFE_RUNNING || !enable), |
3827 | TPACPI_WARN | 3769 | pr_fmt("hotkey enable/disable functionality has been " |
3828 | "hotkey enable/disable functionality has been " | 3770 | "removed from the driver. " |
3829 | "removed from the driver. Hotkeys are always " | 3771 | "Hotkeys are always enabled.\n"))) |
3830 | "enabled\n")) | 3772 | pr_err("Please remove the hotkey=enable module " |
3831 | printk(TPACPI_ERR | 3773 | "parameter, it is deprecated. " |
3832 | "Please remove the hotkey=enable module " | 3774 | "Hotkeys are always enabled.\n"); |
3833 | "parameter, it is deprecated. Hotkeys are always " | ||
3834 | "enabled\n"); | ||
3835 | } | 3775 | } |
3836 | 3776 | ||
3837 | static int hotkey_write(char *buf) | 3777 | static int hotkey_write(char *buf) |
@@ -4011,8 +3951,7 @@ static void bluetooth_shutdown(void) | |||
4011 | /* Order firmware to save current state to NVRAM */ | 3951 | /* Order firmware to save current state to NVRAM */ |
4012 | if (!acpi_evalf(NULL, NULL, "\\BLTH", "vd", | 3952 | if (!acpi_evalf(NULL, NULL, "\\BLTH", "vd", |
4013 | TP_ACPI_BLTH_SAVE_STATE)) | 3953 | TP_ACPI_BLTH_SAVE_STATE)) |
4014 | printk(TPACPI_NOTICE | 3954 | pr_notice("failed to save bluetooth state to NVRAM\n"); |
4015 | "failed to save bluetooth state to NVRAM\n"); | ||
4016 | else | 3955 | else |
4017 | vdbg_printk(TPACPI_DBG_RFKILL, | 3956 | vdbg_printk(TPACPI_DBG_RFKILL, |
4018 | "bluestooth state saved to NVRAM\n"); | 3957 | "bluestooth state saved to NVRAM\n"); |
@@ -4051,8 +3990,7 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm) | |||
4051 | #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES | 3990 | #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES |
4052 | if (dbg_bluetoothemul) { | 3991 | if (dbg_bluetoothemul) { |
4053 | tp_features.bluetooth = 1; | 3992 | tp_features.bluetooth = 1; |
4054 | printk(TPACPI_INFO | 3993 | pr_info("bluetooth switch emulation enabled\n"); |
4055 | "bluetooth switch emulation enabled\n"); | ||
4056 | } else | 3994 | } else |
4057 | #endif | 3995 | #endif |
4058 | if (tp_features.bluetooth && | 3996 | if (tp_features.bluetooth && |
@@ -4203,8 +4141,7 @@ static void wan_shutdown(void) | |||
4203 | /* Order firmware to save current state to NVRAM */ | 4141 | /* Order firmware to save current state to NVRAM */ |
4204 | if (!acpi_evalf(NULL, NULL, "\\WGSV", "vd", | 4142 | if (!acpi_evalf(NULL, NULL, "\\WGSV", "vd", |
4205 | TP_ACPI_WGSV_SAVE_STATE)) | 4143 | TP_ACPI_WGSV_SAVE_STATE)) |
4206 | printk(TPACPI_NOTICE | 4144 | pr_notice("failed to save WWAN state to NVRAM\n"); |
4207 | "failed to save WWAN state to NVRAM\n"); | ||
4208 | else | 4145 | else |
4209 | vdbg_printk(TPACPI_DBG_RFKILL, | 4146 | vdbg_printk(TPACPI_DBG_RFKILL, |
4210 | "WWAN state saved to NVRAM\n"); | 4147 | "WWAN state saved to NVRAM\n"); |
@@ -4241,8 +4178,7 @@ static int __init wan_init(struct ibm_init_struct *iibm) | |||
4241 | #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES | 4178 | #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES |
4242 | if (dbg_wwanemul) { | 4179 | if (dbg_wwanemul) { |
4243 | tp_features.wan = 1; | 4180 | tp_features.wan = 1; |
4244 | printk(TPACPI_INFO | 4181 | pr_info("wwan switch emulation enabled\n"); |
4245 | "wwan switch emulation enabled\n"); | ||
4246 | } else | 4182 | } else |
4247 | #endif | 4183 | #endif |
4248 | if (tp_features.wan && | 4184 | if (tp_features.wan && |
@@ -4382,8 +4318,7 @@ static int __init uwb_init(struct ibm_init_struct *iibm) | |||
4382 | #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES | 4318 | #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES |
4383 | if (dbg_uwbemul) { | 4319 | if (dbg_uwbemul) { |
4384 | tp_features.uwb = 1; | 4320 | tp_features.uwb = 1; |
4385 | printk(TPACPI_INFO | 4321 | pr_info("uwb switch emulation enabled\n"); |
4386 | "uwb switch emulation enabled\n"); | ||
4387 | } else | 4322 | } else |
4388 | #endif | 4323 | #endif |
4389 | if (tp_features.uwb && | 4324 | if (tp_features.uwb && |
@@ -4444,6 +4379,15 @@ static int video_orig_autosw; | |||
4444 | static int video_autosw_get(void); | 4379 | static int video_autosw_get(void); |
4445 | static int video_autosw_set(int enable); | 4380 | static int video_autosw_set(int enable); |
4446 | 4381 | ||
4382 | TPACPI_HANDLE(vid, root, | ||
4383 | "\\_SB.PCI.AGP.VGA", /* 570 */ | ||
4384 | "\\_SB.PCI0.AGP0.VID0", /* 600e/x, 770x */ | ||
4385 | "\\_SB.PCI0.VID0", /* 770e */ | ||
4386 | "\\_SB.PCI0.VID", /* A21e, G4x, R50e, X30, X40 */ | ||
4387 | "\\_SB.PCI0.AGP.VGA", /* X100e and a few others */ | ||
4388 | "\\_SB.PCI0.AGP.VID", /* all others */ | ||
4389 | ); /* R30, R31 */ | ||
4390 | |||
4447 | TPACPI_HANDLE(vid2, root, "\\_SB.PCI0.AGPB.VID"); /* G41 */ | 4391 | TPACPI_HANDLE(vid2, root, "\\_SB.PCI0.AGPB.VID"); /* G41 */ |
4448 | 4392 | ||
4449 | static int __init video_init(struct ibm_init_struct *iibm) | 4393 | static int __init video_init(struct ibm_init_struct *iibm) |
@@ -4487,7 +4431,7 @@ static void video_exit(void) | |||
4487 | dbg_printk(TPACPI_DBG_EXIT, | 4431 | dbg_printk(TPACPI_DBG_EXIT, |
4488 | "restoring original video autoswitch mode\n"); | 4432 | "restoring original video autoswitch mode\n"); |
4489 | if (video_autosw_set(video_orig_autosw)) | 4433 | if (video_autosw_set(video_orig_autosw)) |
4490 | printk(TPACPI_ERR "error while trying to restore original " | 4434 | pr_err("error while trying to restore original " |
4491 | "video autoswitch mode\n"); | 4435 | "video autoswitch mode\n"); |
4492 | } | 4436 | } |
4493 | 4437 | ||
@@ -4560,8 +4504,7 @@ static int video_outputsw_set(int status) | |||
4560 | res = acpi_evalf(vid_handle, NULL, | 4504 | res = acpi_evalf(vid_handle, NULL, |
4561 | "ASWT", "vdd", status * 0x100, 0); | 4505 | "ASWT", "vdd", status * 0x100, 0); |
4562 | if (!autosw && video_autosw_set(autosw)) { | 4506 | if (!autosw && video_autosw_set(autosw)) { |
4563 | printk(TPACPI_ERR | 4507 | pr_err("video auto-switch left enabled due to error\n"); |
4564 | "video auto-switch left enabled due to error\n"); | ||
4565 | return -EIO; | 4508 | return -EIO; |
4566 | } | 4509 | } |
4567 | break; | 4510 | break; |
@@ -4630,8 +4573,7 @@ static int video_outputsw_cycle(void) | |||
4630 | return -ENOSYS; | 4573 | return -ENOSYS; |
4631 | } | 4574 | } |
4632 | if (!autosw && video_autosw_set(autosw)) { | 4575 | if (!autosw && video_autosw_set(autosw)) { |
4633 | printk(TPACPI_ERR | 4576 | pr_err("video auto-switch left enabled due to error\n"); |
4634 | "video auto-switch left enabled due to error\n"); | ||
4635 | return -EIO; | 4577 | return -EIO; |
4636 | } | 4578 | } |
4637 | 4579 | ||
@@ -5348,7 +5290,7 @@ static int __init led_init(struct ibm_init_struct *iibm) | |||
5348 | tpacpi_leds = kzalloc(sizeof(*tpacpi_leds) * TPACPI_LED_NUMLEDS, | 5290 | tpacpi_leds = kzalloc(sizeof(*tpacpi_leds) * TPACPI_LED_NUMLEDS, |
5349 | GFP_KERNEL); | 5291 | GFP_KERNEL); |
5350 | if (!tpacpi_leds) { | 5292 | if (!tpacpi_leds) { |
5351 | printk(TPACPI_ERR "Out of memory for LED data\n"); | 5293 | pr_err("Out of memory for LED data\n"); |
5352 | return -ENOMEM; | 5294 | return -ENOMEM; |
5353 | } | 5295 | } |
5354 | 5296 | ||
@@ -5367,9 +5309,8 @@ static int __init led_init(struct ibm_init_struct *iibm) | |||
5367 | } | 5309 | } |
5368 | 5310 | ||
5369 | #ifdef CONFIG_THINKPAD_ACPI_UNSAFE_LEDS | 5311 | #ifdef CONFIG_THINKPAD_ACPI_UNSAFE_LEDS |
5370 | printk(TPACPI_NOTICE | 5312 | pr_notice("warning: userspace override of important " |
5371 | "warning: userspace override of important " | 5313 | "firmware LEDs is enabled\n"); |
5372 | "firmware LEDs is enabled\n"); | ||
5373 | #endif | 5314 | #endif |
5374 | return 0; | 5315 | return 0; |
5375 | } | 5316 | } |
@@ -5639,17 +5580,16 @@ static void thermal_dump_all_sensors(void) | |||
5639 | if (n <= 0) | 5580 | if (n <= 0) |
5640 | return; | 5581 | return; |
5641 | 5582 | ||
5642 | printk(TPACPI_NOTICE | 5583 | pr_notice("temperatures (Celsius):"); |
5643 | "temperatures (Celsius):"); | ||
5644 | 5584 | ||
5645 | for (i = 0; i < n; i++) { | 5585 | for (i = 0; i < n; i++) { |
5646 | if (t.temp[i] != TPACPI_THERMAL_SENSOR_NA) | 5586 | if (t.temp[i] != TPACPI_THERMAL_SENSOR_NA) |
5647 | printk(KERN_CONT " %d", (int)(t.temp[i] / 1000)); | 5587 | pr_cont(" %d", (int)(t.temp[i] / 1000)); |
5648 | else | 5588 | else |
5649 | printk(KERN_CONT " N/A"); | 5589 | pr_cont(" N/A"); |
5650 | } | 5590 | } |
5651 | 5591 | ||
5652 | printk(KERN_CONT "\n"); | 5592 | pr_cont("\n"); |
5653 | } | 5593 | } |
5654 | 5594 | ||
5655 | /* sysfs temp##_input -------------------------------------------------- */ | 5595 | /* sysfs temp##_input -------------------------------------------------- */ |
@@ -5769,14 +5709,12 @@ static int __init thermal_init(struct ibm_init_struct *iibm) | |||
5769 | if (ta1 == 0) { | 5709 | if (ta1 == 0) { |
5770 | /* This is sheer paranoia, but we handle it anyway */ | 5710 | /* This is sheer paranoia, but we handle it anyway */ |
5771 | if (acpi_tmp7) { | 5711 | if (acpi_tmp7) { |
5772 | printk(TPACPI_ERR | 5712 | pr_err("ThinkPad ACPI EC access misbehaving, " |
5773 | "ThinkPad ACPI EC access misbehaving, " | ||
5774 | "falling back to ACPI TMPx access " | 5713 | "falling back to ACPI TMPx access " |
5775 | "mode\n"); | 5714 | "mode\n"); |
5776 | thermal_read_mode = TPACPI_THERMAL_ACPI_TMP07; | 5715 | thermal_read_mode = TPACPI_THERMAL_ACPI_TMP07; |
5777 | } else { | 5716 | } else { |
5778 | printk(TPACPI_ERR | 5717 | pr_err("ThinkPad ACPI EC access misbehaving, " |
5779 | "ThinkPad ACPI EC access misbehaving, " | ||
5780 | "disabling thermal sensors access\n"); | 5718 | "disabling thermal sensors access\n"); |
5781 | thermal_read_mode = TPACPI_THERMAL_NONE; | 5719 | thermal_read_mode = TPACPI_THERMAL_NONE; |
5782 | } | 5720 | } |
@@ -6129,8 +6067,8 @@ static int __init tpacpi_query_bcl_levels(acpi_handle handle) | |||
6129 | if (ACPI_SUCCESS(acpi_evaluate_object(handle, "_BCL", NULL, &buffer))) { | 6067 | if (ACPI_SUCCESS(acpi_evaluate_object(handle, "_BCL", NULL, &buffer))) { |
6130 | obj = (union acpi_object *)buffer.pointer; | 6068 | obj = (union acpi_object *)buffer.pointer; |
6131 | if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) { | 6069 | if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) { |
6132 | printk(TPACPI_ERR "Unknown _BCL data, " | 6070 | pr_err("Unknown _BCL data, please report this to %s\n", |
6133 | "please report this to %s\n", TPACPI_MAIL); | 6071 | TPACPI_MAIL); |
6134 | rc = 0; | 6072 | rc = 0; |
6135 | } else { | 6073 | } else { |
6136 | rc = obj->package.count; | 6074 | rc = obj->package.count; |
@@ -6214,18 +6152,15 @@ static void __init tpacpi_detect_brightness_capabilities(void) | |||
6214 | switch (b) { | 6152 | switch (b) { |
6215 | case 16: | 6153 | case 16: |
6216 | bright_maxlvl = 15; | 6154 | bright_maxlvl = 15; |
6217 | printk(TPACPI_INFO | 6155 | pr_info("detected a 16-level brightness capable ThinkPad\n"); |
6218 | "detected a 16-level brightness capable ThinkPad\n"); | ||
6219 | break; | 6156 | break; |
6220 | case 8: | 6157 | case 8: |
6221 | case 0: | 6158 | case 0: |
6222 | bright_maxlvl = 7; | 6159 | bright_maxlvl = 7; |
6223 | printk(TPACPI_INFO | 6160 | pr_info("detected a 8-level brightness capable ThinkPad\n"); |
6224 | "detected a 8-level brightness capable ThinkPad\n"); | ||
6225 | break; | 6161 | break; |
6226 | default: | 6162 | default: |
6227 | printk(TPACPI_ERR | 6163 | pr_err("Unsupported brightness interface, " |
6228 | "Unsupported brightness interface, " | ||
6229 | "please contact %s\n", TPACPI_MAIL); | 6164 | "please contact %s\n", TPACPI_MAIL); |
6230 | tp_features.bright_unkfw = 1; | 6165 | tp_features.bright_unkfw = 1; |
6231 | bright_maxlvl = b - 1; | 6166 | bright_maxlvl = b - 1; |
@@ -6260,22 +6195,19 @@ static int __init brightness_init(struct ibm_init_struct *iibm) | |||
6260 | 6195 | ||
6261 | if (acpi_video_backlight_support()) { | 6196 | if (acpi_video_backlight_support()) { |
6262 | if (brightness_enable > 1) { | 6197 | if (brightness_enable > 1) { |
6263 | printk(TPACPI_INFO | 6198 | pr_info("Standard ACPI backlight interface " |
6264 | "Standard ACPI backlight interface " | 6199 | "available, not loading native one\n"); |
6265 | "available, not loading native one.\n"); | ||
6266 | return 1; | 6200 | return 1; |
6267 | } else if (brightness_enable == 1) { | 6201 | } else if (brightness_enable == 1) { |
6268 | printk(TPACPI_WARN | 6202 | pr_warn("Cannot enable backlight brightness support, " |
6269 | "Cannot enable backlight brightness support, " | ||
6270 | "ACPI is already handling it. Refer to the " | 6203 | "ACPI is already handling it. Refer to the " |
6271 | "acpi_backlight kernel parameter\n"); | 6204 | "acpi_backlight kernel parameter.\n"); |
6272 | return 1; | 6205 | return 1; |
6273 | } | 6206 | } |
6274 | } else if (tp_features.bright_acpimode && brightness_enable > 1) { | 6207 | } else if (tp_features.bright_acpimode && brightness_enable > 1) { |
6275 | printk(TPACPI_NOTICE | 6208 | pr_notice("Standard ACPI backlight interface not " |
6276 | "Standard ACPI backlight interface not " | 6209 | "available, thinkpad_acpi native " |
6277 | "available, thinkpad_acpi native " | 6210 | "brightness control enabled\n"); |
6278 | "brightness control enabled\n"); | ||
6279 | } | 6211 | } |
6280 | 6212 | ||
6281 | /* | 6213 | /* |
@@ -6319,19 +6251,17 @@ static int __init brightness_init(struct ibm_init_struct *iibm) | |||
6319 | if (IS_ERR(ibm_backlight_device)) { | 6251 | if (IS_ERR(ibm_backlight_device)) { |
6320 | int rc = PTR_ERR(ibm_backlight_device); | 6252 | int rc = PTR_ERR(ibm_backlight_device); |
6321 | ibm_backlight_device = NULL; | 6253 | ibm_backlight_device = NULL; |
6322 | printk(TPACPI_ERR "Could not register backlight device\n"); | 6254 | pr_err("Could not register backlight device\n"); |
6323 | return rc; | 6255 | return rc; |
6324 | } | 6256 | } |
6325 | vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT, | 6257 | vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT, |
6326 | "brightness is supported\n"); | 6258 | "brightness is supported\n"); |
6327 | 6259 | ||
6328 | if (quirks & TPACPI_BRGHT_Q_ASK) { | 6260 | if (quirks & TPACPI_BRGHT_Q_ASK) { |
6329 | printk(TPACPI_NOTICE | 6261 | pr_notice("brightness: will use unverified default: " |
6330 | "brightness: will use unverified default: " | 6262 | "brightness_mode=%d\n", brightness_mode); |
6331 | "brightness_mode=%d\n", brightness_mode); | 6263 | pr_notice("brightness: please report to %s whether it works well " |
6332 | printk(TPACPI_NOTICE | 6264 | "or not on your ThinkPad\n", TPACPI_MAIL); |
6333 | "brightness: please report to %s whether it works well " | ||
6334 | "or not on your ThinkPad\n", TPACPI_MAIL); | ||
6335 | } | 6265 | } |
6336 | 6266 | ||
6337 | /* Added by mistake in early 2007. Probably useless, but it could | 6267 | /* Added by mistake in early 2007. Probably useless, but it could |
@@ -6804,8 +6734,7 @@ static int __init volume_create_alsa_mixer(void) | |||
6804 | rc = snd_card_create(alsa_index, alsa_id, THIS_MODULE, | 6734 | rc = snd_card_create(alsa_index, alsa_id, THIS_MODULE, |
6805 | sizeof(struct tpacpi_alsa_data), &card); | 6735 | sizeof(struct tpacpi_alsa_data), &card); |
6806 | if (rc < 0 || !card) { | 6736 | if (rc < 0 || !card) { |
6807 | printk(TPACPI_ERR | 6737 | pr_err("Failed to create ALSA card structures: %d\n", rc); |
6808 | "Failed to create ALSA card structures: %d\n", rc); | ||
6809 | return 1; | 6738 | return 1; |
6810 | } | 6739 | } |
6811 | 6740 | ||
@@ -6839,9 +6768,8 @@ static int __init volume_create_alsa_mixer(void) | |||
6839 | ctl_vol = snd_ctl_new1(&volume_alsa_control_vol, NULL); | 6768 | ctl_vol = snd_ctl_new1(&volume_alsa_control_vol, NULL); |
6840 | rc = snd_ctl_add(card, ctl_vol); | 6769 | rc = snd_ctl_add(card, ctl_vol); |
6841 | if (rc < 0) { | 6770 | if (rc < 0) { |
6842 | printk(TPACPI_ERR | 6771 | pr_err("Failed to create ALSA volume control: %d\n", |
6843 | "Failed to create ALSA volume control: %d\n", | 6772 | rc); |
6844 | rc); | ||
6845 | goto err_exit; | 6773 | goto err_exit; |
6846 | } | 6774 | } |
6847 | data->ctl_vol_id = &ctl_vol->id; | 6775 | data->ctl_vol_id = &ctl_vol->id; |
@@ -6850,8 +6778,7 @@ static int __init volume_create_alsa_mixer(void) | |||
6850 | ctl_mute = snd_ctl_new1(&volume_alsa_control_mute, NULL); | 6778 | ctl_mute = snd_ctl_new1(&volume_alsa_control_mute, NULL); |
6851 | rc = snd_ctl_add(card, ctl_mute); | 6779 | rc = snd_ctl_add(card, ctl_mute); |
6852 | if (rc < 0) { | 6780 | if (rc < 0) { |
6853 | printk(TPACPI_ERR "Failed to create ALSA mute control: %d\n", | 6781 | pr_err("Failed to create ALSA mute control: %d\n", rc); |
6854 | rc); | ||
6855 | goto err_exit; | 6782 | goto err_exit; |
6856 | } | 6783 | } |
6857 | data->ctl_mute_id = &ctl_mute->id; | 6784 | data->ctl_mute_id = &ctl_mute->id; |
@@ -6859,7 +6786,7 @@ static int __init volume_create_alsa_mixer(void) | |||
6859 | snd_card_set_dev(card, &tpacpi_pdev->dev); | 6786 | snd_card_set_dev(card, &tpacpi_pdev->dev); |
6860 | rc = snd_card_register(card); | 6787 | rc = snd_card_register(card); |
6861 | if (rc < 0) { | 6788 | if (rc < 0) { |
6862 | printk(TPACPI_ERR "Failed to register ALSA card: %d\n", rc); | 6789 | pr_err("Failed to register ALSA card: %d\n", rc); |
6863 | goto err_exit; | 6790 | goto err_exit; |
6864 | } | 6791 | } |
6865 | 6792 | ||
@@ -6915,9 +6842,8 @@ static int __init volume_init(struct ibm_init_struct *iibm) | |||
6915 | return -EINVAL; | 6842 | return -EINVAL; |
6916 | 6843 | ||
6917 | if (volume_mode == TPACPI_VOL_MODE_UCMS_STEP) { | 6844 | if (volume_mode == TPACPI_VOL_MODE_UCMS_STEP) { |
6918 | printk(TPACPI_ERR | 6845 | pr_err("UCMS step volume mode not implemented, " |
6919 | "UCMS step volume mode not implemented, " | 6846 | "please contact %s\n", TPACPI_MAIL); |
6920 | "please contact %s\n", TPACPI_MAIL); | ||
6921 | return 1; | 6847 | return 1; |
6922 | } | 6848 | } |
6923 | 6849 | ||
@@ -6981,13 +6907,11 @@ static int __init volume_init(struct ibm_init_struct *iibm) | |||
6981 | 6907 | ||
6982 | rc = volume_create_alsa_mixer(); | 6908 | rc = volume_create_alsa_mixer(); |
6983 | if (rc) { | 6909 | if (rc) { |
6984 | printk(TPACPI_ERR | 6910 | pr_err("Could not create the ALSA mixer interface\n"); |
6985 | "Could not create the ALSA mixer interface\n"); | ||
6986 | return rc; | 6911 | return rc; |
6987 | } | 6912 | } |
6988 | 6913 | ||
6989 | printk(TPACPI_INFO | 6914 | pr_info("Console audio control enabled, mode: %s\n", |
6990 | "Console audio control enabled, mode: %s\n", | ||
6991 | (volume_control_allowed) ? | 6915 | (volume_control_allowed) ? |
6992 | "override (read/write)" : | 6916 | "override (read/write)" : |
6993 | "monitor (read only)"); | 6917 | "monitor (read only)"); |
@@ -7049,12 +6973,10 @@ static int volume_write(char *buf) | |||
7049 | if (!volume_control_allowed && tpacpi_lifecycle != TPACPI_LIFE_INIT) { | 6973 | if (!volume_control_allowed && tpacpi_lifecycle != TPACPI_LIFE_INIT) { |
7050 | if (unlikely(!tp_warned.volume_ctrl_forbidden)) { | 6974 | if (unlikely(!tp_warned.volume_ctrl_forbidden)) { |
7051 | tp_warned.volume_ctrl_forbidden = 1; | 6975 | tp_warned.volume_ctrl_forbidden = 1; |
7052 | printk(TPACPI_NOTICE | 6976 | pr_notice("Console audio control in monitor mode, " |
7053 | "Console audio control in monitor mode, " | 6977 | "changes are not allowed\n"); |
7054 | "changes are not allowed.\n"); | 6978 | pr_notice("Use the volume_control=1 module parameter " |
7055 | printk(TPACPI_NOTICE | 6979 | "to enable volume control\n"); |
7056 | "Use the volume_control=1 module parameter " | ||
7057 | "to enable volume control\n"); | ||
7058 | } | 6980 | } |
7059 | return -EPERM; | 6981 | return -EPERM; |
7060 | } | 6982 | } |
@@ -7129,8 +7051,7 @@ static void inline volume_alsa_notify_change(void) | |||
7129 | 7051 | ||
7130 | static int __init volume_init(struct ibm_init_struct *iibm) | 7052 | static int __init volume_init(struct ibm_init_struct *iibm) |
7131 | { | 7053 | { |
7132 | printk(TPACPI_INFO | 7054 | pr_info("volume: disabled as there is no ALSA support in this kernel\n"); |
7133 | "volume: disabled as there is no ALSA support in this kernel\n"); | ||
7134 | 7055 | ||
7135 | return 1; | 7056 | return 1; |
7136 | } | 7057 | } |
@@ -7337,9 +7258,8 @@ TPACPI_HANDLE(sfan, ec, "SFAN", /* 570 */ | |||
7337 | static void fan_quirk1_setup(void) | 7258 | static void fan_quirk1_setup(void) |
7338 | { | 7259 | { |
7339 | if (fan_control_initial_status == 0x07) { | 7260 | if (fan_control_initial_status == 0x07) { |
7340 | printk(TPACPI_NOTICE | 7261 | pr_notice("fan_init: initial fan status is unknown, " |
7341 | "fan_init: initial fan status is unknown, " | 7262 | "assuming it is in auto mode\n"); |
7342 | "assuming it is in auto mode\n"); | ||
7343 | tp_features.fan_ctrl_status_undef = 1; | 7263 | tp_features.fan_ctrl_status_undef = 1; |
7344 | } | 7264 | } |
7345 | } | 7265 | } |
@@ -7726,8 +7646,7 @@ static void fan_watchdog_reset(void) | |||
7726 | if (!queue_delayed_work(tpacpi_wq, &fan_watchdog_task, | 7646 | if (!queue_delayed_work(tpacpi_wq, &fan_watchdog_task, |
7727 | msecs_to_jiffies(fan_watchdog_maxinterval | 7647 | msecs_to_jiffies(fan_watchdog_maxinterval |
7728 | * 1000))) { | 7648 | * 1000))) { |
7729 | printk(TPACPI_ERR | 7649 | pr_err("failed to queue the fan watchdog, " |
7730 | "failed to queue the fan watchdog, " | ||
7731 | "watchdog will not trigger\n"); | 7650 | "watchdog will not trigger\n"); |
7732 | } | 7651 | } |
7733 | } else | 7652 | } else |
@@ -7741,11 +7660,11 @@ static void fan_watchdog_fire(struct work_struct *ignored) | |||
7741 | if (tpacpi_lifecycle != TPACPI_LIFE_RUNNING) | 7660 | if (tpacpi_lifecycle != TPACPI_LIFE_RUNNING) |
7742 | return; | 7661 | return; |
7743 | 7662 | ||
7744 | printk(TPACPI_NOTICE "fan watchdog: enabling fan\n"); | 7663 | pr_notice("fan watchdog: enabling fan\n"); |
7745 | rc = fan_set_enable(); | 7664 | rc = fan_set_enable(); |
7746 | if (rc < 0) { | 7665 | if (rc < 0) { |
7747 | printk(TPACPI_ERR "fan watchdog: error %d while enabling fan, " | 7666 | pr_err("fan watchdog: error %d while enabling fan, " |
7748 | "will try again later...\n", -rc); | 7667 | "will try again later...\n", -rc); |
7749 | /* reschedule for later */ | 7668 | /* reschedule for later */ |
7750 | fan_watchdog_reset(); | 7669 | fan_watchdog_reset(); |
7751 | } | 7670 | } |
@@ -8049,8 +7968,7 @@ static int __init fan_init(struct ibm_init_struct *iibm) | |||
8049 | "secondary fan support enabled\n"); | 7968 | "secondary fan support enabled\n"); |
8050 | } | 7969 | } |
8051 | } else { | 7970 | } else { |
8052 | printk(TPACPI_ERR | 7971 | pr_err("ThinkPad ACPI EC access misbehaving, " |
8053 | "ThinkPad ACPI EC access misbehaving, " | ||
8054 | "fan status and control unavailable\n"); | 7972 | "fan status and control unavailable\n"); |
8055 | return 1; | 7973 | return 1; |
8056 | } | 7974 | } |
@@ -8150,9 +8068,8 @@ static void fan_suspend(pm_message_t state) | |||
8150 | fan_control_resume_level = 0; | 8068 | fan_control_resume_level = 0; |
8151 | rc = fan_get_status_safe(&fan_control_resume_level); | 8069 | rc = fan_get_status_safe(&fan_control_resume_level); |
8152 | if (rc < 0) | 8070 | if (rc < 0) |
8153 | printk(TPACPI_NOTICE | 8071 | pr_notice("failed to read fan level for later " |
8154 | "failed to read fan level for later " | 8072 | "restore during resume: %d\n", rc); |
8155 | "restore during resume: %d\n", rc); | ||
8156 | 8073 | ||
8157 | /* if it is undefined, don't attempt to restore it. | 8074 | /* if it is undefined, don't attempt to restore it. |
8158 | * KEEP THIS LAST */ | 8075 | * KEEP THIS LAST */ |
@@ -8207,13 +8124,11 @@ static void fan_resume(void) | |||
8207 | return; | 8124 | return; |
8208 | } | 8125 | } |
8209 | if (do_set) { | 8126 | if (do_set) { |
8210 | printk(TPACPI_NOTICE | 8127 | pr_notice("restoring fan level to 0x%02x\n", |
8211 | "restoring fan level to 0x%02x\n", | 8128 | fan_control_resume_level); |
8212 | fan_control_resume_level); | ||
8213 | rc = fan_set_level_safe(fan_control_resume_level); | 8129 | rc = fan_set_level_safe(fan_control_resume_level); |
8214 | if (rc < 0) | 8130 | if (rc < 0) |
8215 | printk(TPACPI_NOTICE | 8131 | pr_notice("failed to restore fan level: %d\n", rc); |
8216 | "failed to restore fan level: %d\n", rc); | ||
8217 | } | 8132 | } |
8218 | } | 8133 | } |
8219 | 8134 | ||
@@ -8305,8 +8220,8 @@ static int fan_write_cmd_level(const char *cmd, int *rc) | |||
8305 | 8220 | ||
8306 | *rc = fan_set_level_safe(level); | 8221 | *rc = fan_set_level_safe(level); |
8307 | if (*rc == -ENXIO) | 8222 | if (*rc == -ENXIO) |
8308 | printk(TPACPI_ERR "level command accepted for unsupported " | 8223 | pr_err("level command accepted for unsupported access mode %d\n", |
8309 | "access mode %d", fan_control_access_mode); | 8224 | fan_control_access_mode); |
8310 | else if (!*rc) | 8225 | else if (!*rc) |
8311 | tpacpi_disclose_usertask("procfs fan", | 8226 | tpacpi_disclose_usertask("procfs fan", |
8312 | "set level to %d\n", level); | 8227 | "set level to %d\n", level); |
@@ -8321,8 +8236,8 @@ static int fan_write_cmd_enable(const char *cmd, int *rc) | |||
8321 | 8236 | ||
8322 | *rc = fan_set_enable(); | 8237 | *rc = fan_set_enable(); |
8323 | if (*rc == -ENXIO) | 8238 | if (*rc == -ENXIO) |
8324 | printk(TPACPI_ERR "enable command accepted for unsupported " | 8239 | pr_err("enable command accepted for unsupported access mode %d\n", |
8325 | "access mode %d", fan_control_access_mode); | 8240 | fan_control_access_mode); |
8326 | else if (!*rc) | 8241 | else if (!*rc) |
8327 | tpacpi_disclose_usertask("procfs fan", "enable\n"); | 8242 | tpacpi_disclose_usertask("procfs fan", "enable\n"); |
8328 | 8243 | ||
@@ -8336,8 +8251,8 @@ static int fan_write_cmd_disable(const char *cmd, int *rc) | |||
8336 | 8251 | ||
8337 | *rc = fan_set_disable(); | 8252 | *rc = fan_set_disable(); |
8338 | if (*rc == -ENXIO) | 8253 | if (*rc == -ENXIO) |
8339 | printk(TPACPI_ERR "disable command accepted for unsupported " | 8254 | pr_err("disable command accepted for unsupported access mode %d\n", |
8340 | "access mode %d", fan_control_access_mode); | 8255 | fan_control_access_mode); |
8341 | else if (!*rc) | 8256 | else if (!*rc) |
8342 | tpacpi_disclose_usertask("procfs fan", "disable\n"); | 8257 | tpacpi_disclose_usertask("procfs fan", "disable\n"); |
8343 | 8258 | ||
@@ -8356,8 +8271,8 @@ static int fan_write_cmd_speed(const char *cmd, int *rc) | |||
8356 | 8271 | ||
8357 | *rc = fan_set_speed(speed); | 8272 | *rc = fan_set_speed(speed); |
8358 | if (*rc == -ENXIO) | 8273 | if (*rc == -ENXIO) |
8359 | printk(TPACPI_ERR "speed command accepted for unsupported " | 8274 | pr_err("speed command accepted for unsupported access mode %d\n", |
8360 | "access mode %d", fan_control_access_mode); | 8275 | fan_control_access_mode); |
8361 | else if (!*rc) | 8276 | else if (!*rc) |
8362 | tpacpi_disclose_usertask("procfs fan", | 8277 | tpacpi_disclose_usertask("procfs fan", |
8363 | "set speed to %d\n", speed); | 8278 | "set speed to %d\n", speed); |
@@ -8560,8 +8475,8 @@ static int __init ibm_init(struct ibm_init_struct *iibm) | |||
8560 | if (ibm->acpi->notify) { | 8475 | if (ibm->acpi->notify) { |
8561 | ret = setup_acpi_notify(ibm); | 8476 | ret = setup_acpi_notify(ibm); |
8562 | if (ret == -ENODEV) { | 8477 | if (ret == -ENODEV) { |
8563 | printk(TPACPI_NOTICE "disabling subdriver %s\n", | 8478 | pr_notice("disabling subdriver %s\n", |
8564 | ibm->name); | 8479 | ibm->name); |
8565 | ret = 0; | 8480 | ret = 0; |
8566 | goto err_out; | 8481 | goto err_out; |
8567 | } | 8482 | } |
@@ -8583,8 +8498,7 @@ static int __init ibm_init(struct ibm_init_struct *iibm) | |||
8583 | entry = proc_create_data(ibm->name, mode, proc_dir, | 8498 | entry = proc_create_data(ibm->name, mode, proc_dir, |
8584 | &dispatch_proc_fops, ibm); | 8499 | &dispatch_proc_fops, ibm); |
8585 | if (!entry) { | 8500 | if (!entry) { |
8586 | printk(TPACPI_ERR "unable to create proc entry %s\n", | 8501 | pr_err("unable to create proc entry %s\n", ibm->name); |
8587 | ibm->name); | ||
8588 | ret = -ENODEV; | 8502 | ret = -ENODEV; |
8589 | goto err_out; | 8503 | goto err_out; |
8590 | } | 8504 | } |
@@ -8683,13 +8597,11 @@ static int __must_check __init get_thinkpad_model_data( | |||
8683 | tp->ec_release = (ec_fw_string[4] << 8) | 8597 | tp->ec_release = (ec_fw_string[4] << 8) |
8684 | | ec_fw_string[5]; | 8598 | | ec_fw_string[5]; |
8685 | } else { | 8599 | } else { |
8686 | printk(TPACPI_NOTICE | 8600 | pr_notice("ThinkPad firmware release %s " |
8687 | "ThinkPad firmware release %s " | 8601 | "doesn't match the known patterns\n", |
8688 | "doesn't match the known patterns\n", | 8602 | ec_fw_string); |
8689 | ec_fw_string); | 8603 | pr_notice("please report this to %s\n", |
8690 | printk(TPACPI_NOTICE | 8604 | TPACPI_MAIL); |
8691 | "please report this to %s\n", | ||
8692 | TPACPI_MAIL); | ||
8693 | } | 8605 | } |
8694 | break; | 8606 | break; |
8695 | } | 8607 | } |
@@ -8733,8 +8645,7 @@ static int __init probe_for_thinkpad(void) | |||
8733 | tpacpi_acpi_handle_locate("ec", TPACPI_ACPI_EC_HID, &ec_handle); | 8645 | tpacpi_acpi_handle_locate("ec", TPACPI_ACPI_EC_HID, &ec_handle); |
8734 | if (!ec_handle) { | 8646 | if (!ec_handle) { |
8735 | if (is_thinkpad) | 8647 | if (is_thinkpad) |
8736 | printk(TPACPI_ERR | 8648 | pr_err("Not yet supported ThinkPad detected!\n"); |
8737 | "Not yet supported ThinkPad detected!\n"); | ||
8738 | return -ENODEV; | 8649 | return -ENODEV; |
8739 | } | 8650 | } |
8740 | 8651 | ||
@@ -8746,10 +8657,10 @@ static int __init probe_for_thinkpad(void) | |||
8746 | 8657 | ||
8747 | static void __init thinkpad_acpi_init_banner(void) | 8658 | static void __init thinkpad_acpi_init_banner(void) |
8748 | { | 8659 | { |
8749 | printk(TPACPI_INFO "%s v%s\n", TPACPI_DESC, TPACPI_VERSION); | 8660 | pr_info("%s v%s\n", TPACPI_DESC, TPACPI_VERSION); |
8750 | printk(TPACPI_INFO "%s\n", TPACPI_URL); | 8661 | pr_info("%s\n", TPACPI_URL); |
8751 | 8662 | ||
8752 | printk(TPACPI_INFO "ThinkPad BIOS %s, EC %s\n", | 8663 | pr_info("ThinkPad BIOS %s, EC %s\n", |
8753 | (thinkpad_id.bios_version_str) ? | 8664 | (thinkpad_id.bios_version_str) ? |
8754 | thinkpad_id.bios_version_str : "unknown", | 8665 | thinkpad_id.bios_version_str : "unknown", |
8755 | (thinkpad_id.ec_version_str) ? | 8666 | (thinkpad_id.ec_version_str) ? |
@@ -8758,7 +8669,7 @@ static void __init thinkpad_acpi_init_banner(void) | |||
8758 | BUG_ON(!thinkpad_id.vendor); | 8669 | BUG_ON(!thinkpad_id.vendor); |
8759 | 8670 | ||
8760 | if (thinkpad_id.model_str) | 8671 | if (thinkpad_id.model_str) |
8761 | printk(TPACPI_INFO "%s %s, model %s\n", | 8672 | pr_info("%s %s, model %s\n", |
8762 | (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) ? | 8673 | (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) ? |
8763 | "IBM" : ((thinkpad_id.vendor == | 8674 | "IBM" : ((thinkpad_id.vendor == |
8764 | PCI_VENDOR_ID_LENOVO) ? | 8675 | PCI_VENDOR_ID_LENOVO) ? |
@@ -9024,8 +8935,7 @@ static int __init thinkpad_acpi_module_init(void) | |||
9024 | 8935 | ||
9025 | ret = get_thinkpad_model_data(&thinkpad_id); | 8936 | ret = get_thinkpad_model_data(&thinkpad_id); |
9026 | if (ret) { | 8937 | if (ret) { |
9027 | printk(TPACPI_ERR | 8938 | pr_err("unable to get DMI data: %d\n", ret); |
9028 | "unable to get DMI data: %d\n", ret); | ||
9029 | thinkpad_acpi_module_exit(); | 8939 | thinkpad_acpi_module_exit(); |
9030 | return ret; | 8940 | return ret; |
9031 | } | 8941 | } |
@@ -9051,16 +8961,14 @@ static int __init thinkpad_acpi_module_init(void) | |||
9051 | 8961 | ||
9052 | proc_dir = proc_mkdir(TPACPI_PROC_DIR, acpi_root_dir); | 8962 | proc_dir = proc_mkdir(TPACPI_PROC_DIR, acpi_root_dir); |
9053 | if (!proc_dir) { | 8963 | if (!proc_dir) { |
9054 | printk(TPACPI_ERR | 8964 | pr_err("unable to create proc dir " TPACPI_PROC_DIR "\n"); |
9055 | "unable to create proc dir " TPACPI_PROC_DIR); | ||
9056 | thinkpad_acpi_module_exit(); | 8965 | thinkpad_acpi_module_exit(); |
9057 | return -ENODEV; | 8966 | return -ENODEV; |
9058 | } | 8967 | } |
9059 | 8968 | ||
9060 | ret = platform_driver_register(&tpacpi_pdriver); | 8969 | ret = platform_driver_register(&tpacpi_pdriver); |
9061 | if (ret) { | 8970 | if (ret) { |
9062 | printk(TPACPI_ERR | 8971 | pr_err("unable to register main platform driver\n"); |
9063 | "unable to register main platform driver\n"); | ||
9064 | thinkpad_acpi_module_exit(); | 8972 | thinkpad_acpi_module_exit(); |
9065 | return ret; | 8973 | return ret; |
9066 | } | 8974 | } |
@@ -9068,8 +8976,7 @@ static int __init thinkpad_acpi_module_init(void) | |||
9068 | 8976 | ||
9069 | ret = platform_driver_register(&tpacpi_hwmon_pdriver); | 8977 | ret = platform_driver_register(&tpacpi_hwmon_pdriver); |
9070 | if (ret) { | 8978 | if (ret) { |
9071 | printk(TPACPI_ERR | 8979 | pr_err("unable to register hwmon platform driver\n"); |
9072 | "unable to register hwmon platform driver\n"); | ||
9073 | thinkpad_acpi_module_exit(); | 8980 | thinkpad_acpi_module_exit(); |
9074 | return ret; | 8981 | return ret; |
9075 | } | 8982 | } |
@@ -9082,8 +8989,7 @@ static int __init thinkpad_acpi_module_init(void) | |||
9082 | &tpacpi_hwmon_pdriver.driver); | 8989 | &tpacpi_hwmon_pdriver.driver); |
9083 | } | 8990 | } |
9084 | if (ret) { | 8991 | if (ret) { |
9085 | printk(TPACPI_ERR | 8992 | pr_err("unable to create sysfs driver attributes\n"); |
9086 | "unable to create sysfs driver attributes\n"); | ||
9087 | thinkpad_acpi_module_exit(); | 8993 | thinkpad_acpi_module_exit(); |
9088 | return ret; | 8994 | return ret; |
9089 | } | 8995 | } |
@@ -9096,7 +9002,7 @@ static int __init thinkpad_acpi_module_init(void) | |||
9096 | if (IS_ERR(tpacpi_pdev)) { | 9002 | if (IS_ERR(tpacpi_pdev)) { |
9097 | ret = PTR_ERR(tpacpi_pdev); | 9003 | ret = PTR_ERR(tpacpi_pdev); |
9098 | tpacpi_pdev = NULL; | 9004 | tpacpi_pdev = NULL; |
9099 | printk(TPACPI_ERR "unable to register platform device\n"); | 9005 | pr_err("unable to register platform device\n"); |
9100 | thinkpad_acpi_module_exit(); | 9006 | thinkpad_acpi_module_exit(); |
9101 | return ret; | 9007 | return ret; |
9102 | } | 9008 | } |
@@ -9106,16 +9012,14 @@ static int __init thinkpad_acpi_module_init(void) | |||
9106 | if (IS_ERR(tpacpi_sensors_pdev)) { | 9012 | if (IS_ERR(tpacpi_sensors_pdev)) { |
9107 | ret = PTR_ERR(tpacpi_sensors_pdev); | 9013 | ret = PTR_ERR(tpacpi_sensors_pdev); |
9108 | tpacpi_sensors_pdev = NULL; | 9014 | tpacpi_sensors_pdev = NULL; |
9109 | printk(TPACPI_ERR | 9015 | pr_err("unable to register hwmon platform device\n"); |
9110 | "unable to register hwmon platform device\n"); | ||
9111 | thinkpad_acpi_module_exit(); | 9016 | thinkpad_acpi_module_exit(); |
9112 | return ret; | 9017 | return ret; |
9113 | } | 9018 | } |
9114 | ret = device_create_file(&tpacpi_sensors_pdev->dev, | 9019 | ret = device_create_file(&tpacpi_sensors_pdev->dev, |
9115 | &dev_attr_thinkpad_acpi_pdev_name); | 9020 | &dev_attr_thinkpad_acpi_pdev_name); |
9116 | if (ret) { | 9021 | if (ret) { |
9117 | printk(TPACPI_ERR | 9022 | pr_err("unable to create sysfs hwmon device attributes\n"); |
9118 | "unable to create sysfs hwmon device attributes\n"); | ||
9119 | thinkpad_acpi_module_exit(); | 9023 | thinkpad_acpi_module_exit(); |
9120 | return ret; | 9024 | return ret; |
9121 | } | 9025 | } |
@@ -9124,14 +9028,14 @@ static int __init thinkpad_acpi_module_init(void) | |||
9124 | if (IS_ERR(tpacpi_hwmon)) { | 9028 | if (IS_ERR(tpacpi_hwmon)) { |
9125 | ret = PTR_ERR(tpacpi_hwmon); | 9029 | ret = PTR_ERR(tpacpi_hwmon); |
9126 | tpacpi_hwmon = NULL; | 9030 | tpacpi_hwmon = NULL; |
9127 | printk(TPACPI_ERR "unable to register hwmon device\n"); | 9031 | pr_err("unable to register hwmon device\n"); |
9128 | thinkpad_acpi_module_exit(); | 9032 | thinkpad_acpi_module_exit(); |
9129 | return ret; | 9033 | return ret; |
9130 | } | 9034 | } |
9131 | mutex_init(&tpacpi_inputdev_send_mutex); | 9035 | mutex_init(&tpacpi_inputdev_send_mutex); |
9132 | tpacpi_inputdev = input_allocate_device(); | 9036 | tpacpi_inputdev = input_allocate_device(); |
9133 | if (!tpacpi_inputdev) { | 9037 | if (!tpacpi_inputdev) { |
9134 | printk(TPACPI_ERR "unable to allocate input device\n"); | 9038 | pr_err("unable to allocate input device\n"); |
9135 | thinkpad_acpi_module_exit(); | 9039 | thinkpad_acpi_module_exit(); |
9136 | return -ENOMEM; | 9040 | return -ENOMEM; |
9137 | } else { | 9041 | } else { |
@@ -9163,7 +9067,7 @@ static int __init thinkpad_acpi_module_init(void) | |||
9163 | 9067 | ||
9164 | ret = input_register_device(tpacpi_inputdev); | 9068 | ret = input_register_device(tpacpi_inputdev); |
9165 | if (ret < 0) { | 9069 | if (ret < 0) { |
9166 | printk(TPACPI_ERR "unable to register input device\n"); | 9070 | pr_err("unable to register input device\n"); |
9167 | thinkpad_acpi_module_exit(); | 9071 | thinkpad_acpi_module_exit(); |
9168 | return ret; | 9072 | return ret; |
9169 | } else { | 9073 | } else { |
diff --git a/drivers/platform/x86/topstar-laptop.c b/drivers/platform/x86/topstar-laptop.c index 1d07d6d09f27..4c20447ddbb7 100644 --- a/drivers/platform/x86/topstar-laptop.c +++ b/drivers/platform/x86/topstar-laptop.c | |||
@@ -194,7 +194,7 @@ static int __init topstar_laptop_init(void) | |||
194 | if (ret < 0) | 194 | if (ret < 0) |
195 | return ret; | 195 | return ret; |
196 | 196 | ||
197 | printk(KERN_INFO "Topstar Laptop ACPI extras driver loaded\n"); | 197 | pr_info("ACPI extras driver loaded\n"); |
198 | 198 | ||
199 | return 0; | 199 | return 0; |
200 | } | 200 | } |
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 63f42a22e102..cb009b2629ee 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c | |||
@@ -35,6 +35,8 @@ | |||
35 | * | 35 | * |
36 | */ | 36 | */ |
37 | 37 | ||
38 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
39 | |||
38 | #define TOSHIBA_ACPI_VERSION "0.19" | 40 | #define TOSHIBA_ACPI_VERSION "0.19" |
39 | #define PROC_INTERFACE_VERSION 1 | 41 | #define PROC_INTERFACE_VERSION 1 |
40 | 42 | ||
@@ -60,11 +62,6 @@ MODULE_AUTHOR("John Belmonte"); | |||
60 | MODULE_DESCRIPTION("Toshiba Laptop ACPI Extras Driver"); | 62 | MODULE_DESCRIPTION("Toshiba Laptop ACPI Extras Driver"); |
61 | MODULE_LICENSE("GPL"); | 63 | MODULE_LICENSE("GPL"); |
62 | 64 | ||
63 | #define MY_LOGPREFIX "toshiba_acpi: " | ||
64 | #define MY_ERR KERN_ERR MY_LOGPREFIX | ||
65 | #define MY_NOTICE KERN_NOTICE MY_LOGPREFIX | ||
66 | #define MY_INFO KERN_INFO MY_LOGPREFIX | ||
67 | |||
68 | /* Toshiba ACPI method paths */ | 65 | /* Toshiba ACPI method paths */ |
69 | #define METHOD_LCD_BRIGHTNESS "\\_SB_.PCI0.VGA_.LCD_._BCM" | 66 | #define METHOD_LCD_BRIGHTNESS "\\_SB_.PCI0.VGA_.LCD_._BCM" |
70 | #define TOSH_INTERFACE_1 "\\_SB_.VALD" | 67 | #define TOSH_INTERFACE_1 "\\_SB_.VALD" |
@@ -301,7 +298,7 @@ static int toshiba_illumination_available(void) | |||
301 | in[0] = 0xf100; | 298 | in[0] = 0xf100; |
302 | status = hci_raw(in, out); | 299 | status = hci_raw(in, out); |
303 | if (ACPI_FAILURE(status)) { | 300 | if (ACPI_FAILURE(status)) { |
304 | printk(MY_INFO "Illumination device not available\n"); | 301 | pr_info("Illumination device not available\n"); |
305 | return 0; | 302 | return 0; |
306 | } | 303 | } |
307 | in[0] = 0xf400; | 304 | in[0] = 0xf400; |
@@ -320,7 +317,7 @@ static void toshiba_illumination_set(struct led_classdev *cdev, | |||
320 | in[0] = 0xf100; | 317 | in[0] = 0xf100; |
321 | status = hci_raw(in, out); | 318 | status = hci_raw(in, out); |
322 | if (ACPI_FAILURE(status)) { | 319 | if (ACPI_FAILURE(status)) { |
323 | printk(MY_INFO "Illumination device not available\n"); | 320 | pr_info("Illumination device not available\n"); |
324 | return; | 321 | return; |
325 | } | 322 | } |
326 | 323 | ||
@@ -331,7 +328,7 @@ static void toshiba_illumination_set(struct led_classdev *cdev, | |||
331 | in[2] = 1; | 328 | in[2] = 1; |
332 | status = hci_raw(in, out); | 329 | status = hci_raw(in, out); |
333 | if (ACPI_FAILURE(status)) { | 330 | if (ACPI_FAILURE(status)) { |
334 | printk(MY_INFO "ACPI call for illumination failed.\n"); | 331 | pr_info("ACPI call for illumination failed\n"); |
335 | return; | 332 | return; |
336 | } | 333 | } |
337 | } else { | 334 | } else { |
@@ -341,7 +338,7 @@ static void toshiba_illumination_set(struct led_classdev *cdev, | |||
341 | in[2] = 0; | 338 | in[2] = 0; |
342 | status = hci_raw(in, out); | 339 | status = hci_raw(in, out); |
343 | if (ACPI_FAILURE(status)) { | 340 | if (ACPI_FAILURE(status)) { |
344 | printk(MY_INFO "ACPI call for illumination failed.\n"); | 341 | pr_info("ACPI call for illumination failed.\n"); |
345 | return; | 342 | return; |
346 | } | 343 | } |
347 | } | 344 | } |
@@ -364,7 +361,7 @@ static enum led_brightness toshiba_illumination_get(struct led_classdev *cdev) | |||
364 | in[0] = 0xf100; | 361 | in[0] = 0xf100; |
365 | status = hci_raw(in, out); | 362 | status = hci_raw(in, out); |
366 | if (ACPI_FAILURE(status)) { | 363 | if (ACPI_FAILURE(status)) { |
367 | printk(MY_INFO "Illumination device not available\n"); | 364 | pr_info("Illumination device not available\n"); |
368 | return LED_OFF; | 365 | return LED_OFF; |
369 | } | 366 | } |
370 | 367 | ||
@@ -373,7 +370,7 @@ static enum led_brightness toshiba_illumination_get(struct led_classdev *cdev) | |||
373 | in[1] = 0x14e; | 370 | in[1] = 0x14e; |
374 | status = hci_raw(in, out); | 371 | status = hci_raw(in, out); |
375 | if (ACPI_FAILURE(status)) { | 372 | if (ACPI_FAILURE(status)) { |
376 | printk(MY_INFO "ACPI call for illumination failed.\n"); | 373 | pr_info("ACPI call for illumination failed.\n"); |
377 | return LED_OFF; | 374 | return LED_OFF; |
378 | } | 375 | } |
379 | 376 | ||
@@ -517,7 +514,7 @@ static int lcd_proc_show(struct seq_file *m, void *v) | |||
517 | seq_printf(m, "brightness_levels: %d\n", | 514 | seq_printf(m, "brightness_levels: %d\n", |
518 | HCI_LCD_BRIGHTNESS_LEVELS); | 515 | HCI_LCD_BRIGHTNESS_LEVELS); |
519 | } else { | 516 | } else { |
520 | printk(MY_ERR "Error reading LCD brightness\n"); | 517 | pr_err("Error reading LCD brightness\n"); |
521 | } | 518 | } |
522 | 519 | ||
523 | return 0; | 520 | return 0; |
@@ -592,7 +589,7 @@ static int video_proc_show(struct seq_file *m, void *v) | |||
592 | seq_printf(m, "crt_out: %d\n", is_crt); | 589 | seq_printf(m, "crt_out: %d\n", is_crt); |
593 | seq_printf(m, "tv_out: %d\n", is_tv); | 590 | seq_printf(m, "tv_out: %d\n", is_tv); |
594 | } else { | 591 | } else { |
595 | printk(MY_ERR "Error reading video out status\n"); | 592 | pr_err("Error reading video out status\n"); |
596 | } | 593 | } |
597 | 594 | ||
598 | return 0; | 595 | return 0; |
@@ -686,7 +683,7 @@ static int fan_proc_show(struct seq_file *m, void *v) | |||
686 | seq_printf(m, "running: %d\n", (value > 0)); | 683 | seq_printf(m, "running: %d\n", (value > 0)); |
687 | seq_printf(m, "force_on: %d\n", force_fan); | 684 | seq_printf(m, "force_on: %d\n", force_fan); |
688 | } else { | 685 | } else { |
689 | printk(MY_ERR "Error reading fan status\n"); | 686 | pr_err("Error reading fan status\n"); |
690 | } | 687 | } |
691 | 688 | ||
692 | return 0; | 689 | return 0; |
@@ -750,9 +747,9 @@ static int keys_proc_show(struct seq_file *m, void *v) | |||
750 | * some machines where system events sporadically | 747 | * some machines where system events sporadically |
751 | * become disabled. */ | 748 | * become disabled. */ |
752 | hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result); | 749 | hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result); |
753 | printk(MY_NOTICE "Re-enabled hotkeys\n"); | 750 | pr_notice("Re-enabled hotkeys\n"); |
754 | } else { | 751 | } else { |
755 | printk(MY_ERR "Error reading hotkey status\n"); | 752 | pr_err("Error reading hotkey status\n"); |
756 | goto end; | 753 | goto end; |
757 | } | 754 | } |
758 | } | 755 | } |
@@ -863,7 +860,7 @@ static void toshiba_acpi_notify(acpi_handle handle, u32 event, void *context) | |||
863 | 860 | ||
864 | if (!sparse_keymap_report_event(toshiba_acpi.hotkey_dev, | 861 | if (!sparse_keymap_report_event(toshiba_acpi.hotkey_dev, |
865 | value, 1, true)) { | 862 | value, 1, true)) { |
866 | printk(MY_INFO "Unknown key %x\n", | 863 | pr_info("Unknown key %x\n", |
867 | value); | 864 | value); |
868 | } | 865 | } |
869 | } else if (hci_result == HCI_NOT_SUPPORTED) { | 866 | } else if (hci_result == HCI_NOT_SUPPORTED) { |
@@ -871,7 +868,7 @@ static void toshiba_acpi_notify(acpi_handle handle, u32 event, void *context) | |||
871 | * some machines where system events sporadically | 868 | * some machines where system events sporadically |
872 | * become disabled. */ | 869 | * become disabled. */ |
873 | hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result); | 870 | hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result); |
874 | printk(MY_NOTICE "Re-enabled hotkeys\n"); | 871 | pr_notice("Re-enabled hotkeys\n"); |
875 | } | 872 | } |
876 | } while (hci_result != HCI_EMPTY); | 873 | } while (hci_result != HCI_EMPTY); |
877 | } | 874 | } |
@@ -883,13 +880,13 @@ static int __init toshiba_acpi_setup_keyboard(char *device) | |||
883 | 880 | ||
884 | status = acpi_get_handle(NULL, device, &toshiba_acpi.handle); | 881 | status = acpi_get_handle(NULL, device, &toshiba_acpi.handle); |
885 | if (ACPI_FAILURE(status)) { | 882 | if (ACPI_FAILURE(status)) { |
886 | printk(MY_INFO "Unable to get notification device\n"); | 883 | pr_info("Unable to get notification device\n"); |
887 | return -ENODEV; | 884 | return -ENODEV; |
888 | } | 885 | } |
889 | 886 | ||
890 | toshiba_acpi.hotkey_dev = input_allocate_device(); | 887 | toshiba_acpi.hotkey_dev = input_allocate_device(); |
891 | if (!toshiba_acpi.hotkey_dev) { | 888 | if (!toshiba_acpi.hotkey_dev) { |
892 | printk(MY_INFO "Unable to register input device\n"); | 889 | pr_info("Unable to register input device\n"); |
893 | return -ENOMEM; | 890 | return -ENOMEM; |
894 | } | 891 | } |
895 | 892 | ||
@@ -905,21 +902,21 @@ static int __init toshiba_acpi_setup_keyboard(char *device) | |||
905 | status = acpi_install_notify_handler(toshiba_acpi.handle, | 902 | status = acpi_install_notify_handler(toshiba_acpi.handle, |
906 | ACPI_DEVICE_NOTIFY, toshiba_acpi_notify, NULL); | 903 | ACPI_DEVICE_NOTIFY, toshiba_acpi_notify, NULL); |
907 | if (ACPI_FAILURE(status)) { | 904 | if (ACPI_FAILURE(status)) { |
908 | printk(MY_INFO "Unable to install hotkey notification\n"); | 905 | pr_info("Unable to install hotkey notification\n"); |
909 | error = -ENODEV; | 906 | error = -ENODEV; |
910 | goto err_free_keymap; | 907 | goto err_free_keymap; |
911 | } | 908 | } |
912 | 909 | ||
913 | status = acpi_evaluate_object(toshiba_acpi.handle, "ENAB", NULL, NULL); | 910 | status = acpi_evaluate_object(toshiba_acpi.handle, "ENAB", NULL, NULL); |
914 | if (ACPI_FAILURE(status)) { | 911 | if (ACPI_FAILURE(status)) { |
915 | printk(MY_INFO "Unable to enable hotkeys\n"); | 912 | pr_info("Unable to enable hotkeys\n"); |
916 | error = -ENODEV; | 913 | error = -ENODEV; |
917 | goto err_remove_notify; | 914 | goto err_remove_notify; |
918 | } | 915 | } |
919 | 916 | ||
920 | error = input_register_device(toshiba_acpi.hotkey_dev); | 917 | error = input_register_device(toshiba_acpi.hotkey_dev); |
921 | if (error) { | 918 | if (error) { |
922 | printk(MY_INFO "Unable to register input device\n"); | 919 | pr_info("Unable to register input device\n"); |
923 | goto err_remove_notify; | 920 | goto err_remove_notify; |
924 | } | 921 | } |
925 | 922 | ||
@@ -980,17 +977,17 @@ static int __init toshiba_acpi_init(void) | |||
980 | if (is_valid_acpi_path(TOSH_INTERFACE_1 GHCI_METHOD)) { | 977 | if (is_valid_acpi_path(TOSH_INTERFACE_1 GHCI_METHOD)) { |
981 | method_hci = TOSH_INTERFACE_1 GHCI_METHOD; | 978 | method_hci = TOSH_INTERFACE_1 GHCI_METHOD; |
982 | if (toshiba_acpi_setup_keyboard(TOSH_INTERFACE_1)) | 979 | if (toshiba_acpi_setup_keyboard(TOSH_INTERFACE_1)) |
983 | printk(MY_INFO "Unable to activate hotkeys\n"); | 980 | pr_info("Unable to activate hotkeys\n"); |
984 | } else if (is_valid_acpi_path(TOSH_INTERFACE_2 GHCI_METHOD)) { | 981 | } else if (is_valid_acpi_path(TOSH_INTERFACE_2 GHCI_METHOD)) { |
985 | method_hci = TOSH_INTERFACE_2 GHCI_METHOD; | 982 | method_hci = TOSH_INTERFACE_2 GHCI_METHOD; |
986 | if (toshiba_acpi_setup_keyboard(TOSH_INTERFACE_2)) | 983 | if (toshiba_acpi_setup_keyboard(TOSH_INTERFACE_2)) |
987 | printk(MY_INFO "Unable to activate hotkeys\n"); | 984 | pr_info("Unable to activate hotkeys\n"); |
988 | } else | 985 | } else |
989 | return -ENODEV; | 986 | return -ENODEV; |
990 | 987 | ||
991 | printk(MY_INFO "Toshiba Laptop ACPI Extras version %s\n", | 988 | pr_info("Toshiba Laptop ACPI Extras version %s\n", |
992 | TOSHIBA_ACPI_VERSION); | 989 | TOSHIBA_ACPI_VERSION); |
993 | printk(MY_INFO " HCI method: %s\n", method_hci); | 990 | pr_info(" HCI method: %s\n", method_hci); |
994 | 991 | ||
995 | mutex_init(&toshiba_acpi.mutex); | 992 | mutex_init(&toshiba_acpi.mutex); |
996 | 993 | ||
@@ -998,7 +995,7 @@ static int __init toshiba_acpi_init(void) | |||
998 | -1, NULL, 0); | 995 | -1, NULL, 0); |
999 | if (IS_ERR(toshiba_acpi.p_dev)) { | 996 | if (IS_ERR(toshiba_acpi.p_dev)) { |
1000 | ret = PTR_ERR(toshiba_acpi.p_dev); | 997 | ret = PTR_ERR(toshiba_acpi.p_dev); |
1001 | printk(MY_ERR "unable to register platform device\n"); | 998 | pr_err("unable to register platform device\n"); |
1002 | toshiba_acpi.p_dev = NULL; | 999 | toshiba_acpi.p_dev = NULL; |
1003 | toshiba_acpi_exit(); | 1000 | toshiba_acpi_exit(); |
1004 | return ret; | 1001 | return ret; |
@@ -1028,7 +1025,7 @@ static int __init toshiba_acpi_init(void) | |||
1028 | if (IS_ERR(toshiba_backlight_device)) { | 1025 | if (IS_ERR(toshiba_backlight_device)) { |
1029 | ret = PTR_ERR(toshiba_backlight_device); | 1026 | ret = PTR_ERR(toshiba_backlight_device); |
1030 | 1027 | ||
1031 | printk(KERN_ERR "Could not register toshiba backlight device\n"); | 1028 | pr_err("Could not register toshiba backlight device\n"); |
1032 | toshiba_backlight_device = NULL; | 1029 | toshiba_backlight_device = NULL; |
1033 | toshiba_acpi_exit(); | 1030 | toshiba_acpi_exit(); |
1034 | return ret; | 1031 | return ret; |
@@ -1042,14 +1039,14 @@ static int __init toshiba_acpi_init(void) | |||
1042 | &toshiba_rfk_ops, | 1039 | &toshiba_rfk_ops, |
1043 | &toshiba_acpi); | 1040 | &toshiba_acpi); |
1044 | if (!toshiba_acpi.bt_rfk) { | 1041 | if (!toshiba_acpi.bt_rfk) { |
1045 | printk(MY_ERR "unable to allocate rfkill device\n"); | 1042 | pr_err("unable to allocate rfkill device\n"); |
1046 | toshiba_acpi_exit(); | 1043 | toshiba_acpi_exit(); |
1047 | return -ENOMEM; | 1044 | return -ENOMEM; |
1048 | } | 1045 | } |
1049 | 1046 | ||
1050 | ret = rfkill_register(toshiba_acpi.bt_rfk); | 1047 | ret = rfkill_register(toshiba_acpi.bt_rfk); |
1051 | if (ret) { | 1048 | if (ret) { |
1052 | printk(MY_ERR "unable to register rfkill device\n"); | 1049 | pr_err("unable to register rfkill device\n"); |
1053 | rfkill_destroy(toshiba_acpi.bt_rfk); | 1050 | rfkill_destroy(toshiba_acpi.bt_rfk); |
1054 | toshiba_acpi_exit(); | 1051 | toshiba_acpi_exit(); |
1055 | return ret; | 1052 | return ret; |
diff --git a/drivers/platform/x86/toshiba_bluetooth.c b/drivers/platform/x86/toshiba_bluetooth.c index 944068611919..5fb7186694df 100644 --- a/drivers/platform/x86/toshiba_bluetooth.c +++ b/drivers/platform/x86/toshiba_bluetooth.c | |||
@@ -17,6 +17,8 @@ | |||
17 | * delivered. | 17 | * delivered. |
18 | */ | 18 | */ |
19 | 19 | ||
20 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
21 | |||
20 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
21 | #include <linux/module.h> | 23 | #include <linux/module.h> |
22 | #include <linux/init.h> | 24 | #include <linux/init.h> |
@@ -70,14 +72,13 @@ static int toshiba_bluetooth_enable(acpi_handle handle) | |||
70 | if (!(result & 0x01)) | 72 | if (!(result & 0x01)) |
71 | return 0; | 73 | return 0; |
72 | 74 | ||
73 | printk(KERN_INFO "toshiba_bluetooth: Re-enabling Toshiba Bluetooth\n"); | 75 | pr_info("Re-enabling Toshiba Bluetooth\n"); |
74 | res1 = acpi_evaluate_object(handle, "AUSB", NULL, NULL); | 76 | res1 = acpi_evaluate_object(handle, "AUSB", NULL, NULL); |
75 | res2 = acpi_evaluate_object(handle, "BTPO", NULL, NULL); | 77 | res2 = acpi_evaluate_object(handle, "BTPO", NULL, NULL); |
76 | if (!ACPI_FAILURE(res1) || !ACPI_FAILURE(res2)) | 78 | if (!ACPI_FAILURE(res1) || !ACPI_FAILURE(res2)) |
77 | return 0; | 79 | return 0; |
78 | 80 | ||
79 | printk(KERN_WARNING "toshiba_bluetooth: Failed to re-enable " | 81 | pr_warn("Failed to re-enable Toshiba Bluetooth\n"); |
80 | "Toshiba Bluetooth\n"); | ||
81 | 82 | ||
82 | return -ENODEV; | 83 | return -ENODEV; |
83 | } | 84 | } |
@@ -107,8 +108,8 @@ static int toshiba_bt_rfkill_add(struct acpi_device *device) | |||
107 | &bt_present); | 108 | &bt_present); |
108 | 109 | ||
109 | if (!ACPI_FAILURE(status) && bt_present) { | 110 | if (!ACPI_FAILURE(status) && bt_present) { |
110 | printk(KERN_INFO "Detected Toshiba ACPI Bluetooth device - " | 111 | pr_info("Detected Toshiba ACPI Bluetooth device - " |
111 | "installing RFKill handler\n"); | 112 | "installing RFKill handler\n"); |
112 | result = toshiba_bluetooth_enable(device->handle); | 113 | result = toshiba_bluetooth_enable(device->handle); |
113 | } | 114 | } |
114 | 115 | ||
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index 05cc79672a8b..f23d5a84e7b1 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c | |||
@@ -486,16 +486,16 @@ static void wmi_dump_wdg(const struct guid_block *g) | |||
486 | pr_info("\tnotify_id: %02X\n", g->notify_id); | 486 | pr_info("\tnotify_id: %02X\n", g->notify_id); |
487 | pr_info("\treserved: %02X\n", g->reserved); | 487 | pr_info("\treserved: %02X\n", g->reserved); |
488 | pr_info("\tinstance_count: %d\n", g->instance_count); | 488 | pr_info("\tinstance_count: %d\n", g->instance_count); |
489 | pr_info("\tflags: %#x ", g->flags); | 489 | pr_info("\tflags: %#x", g->flags); |
490 | if (g->flags) { | 490 | if (g->flags) { |
491 | if (g->flags & ACPI_WMI_EXPENSIVE) | 491 | if (g->flags & ACPI_WMI_EXPENSIVE) |
492 | pr_cont("ACPI_WMI_EXPENSIVE "); | 492 | pr_cont(" ACPI_WMI_EXPENSIVE"); |
493 | if (g->flags & ACPI_WMI_METHOD) | 493 | if (g->flags & ACPI_WMI_METHOD) |
494 | pr_cont("ACPI_WMI_METHOD "); | 494 | pr_cont(" ACPI_WMI_METHOD"); |
495 | if (g->flags & ACPI_WMI_STRING) | 495 | if (g->flags & ACPI_WMI_STRING) |
496 | pr_cont("ACPI_WMI_STRING "); | 496 | pr_cont(" ACPI_WMI_STRING"); |
497 | if (g->flags & ACPI_WMI_EVENT) | 497 | if (g->flags & ACPI_WMI_EVENT) |
498 | pr_cont("ACPI_WMI_EVENT "); | 498 | pr_cont(" ACPI_WMI_EVENT"); |
499 | } | 499 | } |
500 | pr_cont("\n"); | 500 | pr_cont("\n"); |
501 | 501 | ||
diff --git a/drivers/platform/x86/xo15-ebook.c b/drivers/platform/x86/xo15-ebook.c index c1372ed9d2e9..fad153dc0355 100644 --- a/drivers/platform/x86/xo15-ebook.c +++ b/drivers/platform/x86/xo15-ebook.c | |||
@@ -11,6 +11,8 @@ | |||
11 | * your option) any later version. | 11 | * your option) any later version. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
15 | |||
14 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
15 | #include <linux/module.h> | 17 | #include <linux/module.h> |
16 | #include <linux/init.h> | 18 | #include <linux/init.h> |
@@ -20,7 +22,6 @@ | |||
20 | #include <acpi/acpi_drivers.h> | 22 | #include <acpi/acpi_drivers.h> |
21 | 23 | ||
22 | #define MODULE_NAME "xo15-ebook" | 24 | #define MODULE_NAME "xo15-ebook" |
23 | #define PREFIX MODULE_NAME ": " | ||
24 | 25 | ||
25 | #define XO15_EBOOK_CLASS MODULE_NAME | 26 | #define XO15_EBOOK_CLASS MODULE_NAME |
26 | #define XO15_EBOOK_TYPE_UNKNOWN 0x00 | 27 | #define XO15_EBOOK_TYPE_UNKNOWN 0x00 |
@@ -105,7 +106,7 @@ static int ebook_switch_add(struct acpi_device *device) | |||
105 | class = acpi_device_class(device); | 106 | class = acpi_device_class(device); |
106 | 107 | ||
107 | if (strcmp(hid, XO15_EBOOK_HID)) { | 108 | if (strcmp(hid, XO15_EBOOK_HID)) { |
108 | printk(KERN_ERR PREFIX "Unsupported hid [%s]\n", hid); | 109 | pr_err("Unsupported hid [%s]\n", hid); |
109 | error = -ENODEV; | 110 | error = -ENODEV; |
110 | goto err_free_input; | 111 | goto err_free_input; |
111 | } | 112 | } |
diff --git a/drivers/scsi/scsi_proc.c b/drivers/scsi/scsi_proc.c index f46855cd853d..ad747dc337da 100644 --- a/drivers/scsi/scsi_proc.c +++ b/drivers/scsi/scsi_proc.c | |||
@@ -381,11 +381,6 @@ static ssize_t proc_scsi_write(struct file *file, const char __user *buf, | |||
381 | return err; | 381 | return err; |
382 | } | 382 | } |
383 | 383 | ||
384 | /** | ||
385 | * proc_scsi_show - show contents of /proc/scsi/scsi (attached devices) | ||
386 | * @s: output goes here | ||
387 | * @p: not used | ||
388 | */ | ||
389 | static int always_match(struct device *dev, void *data) | 384 | static int always_match(struct device *dev, void *data) |
390 | { | 385 | { |
391 | return 1; | 386 | return 1; |
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 58584dc0724a..44e8ca398efa 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c | |||
@@ -297,7 +297,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget, | |||
297 | kfree(sdev); | 297 | kfree(sdev); |
298 | goto out; | 298 | goto out; |
299 | } | 299 | } |
300 | 300 | blk_get_queue(sdev->request_queue); | |
301 | sdev->request_queue->queuedata = sdev; | 301 | sdev->request_queue->queuedata = sdev; |
302 | scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun); | 302 | scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun); |
303 | 303 | ||
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index e63912510fb9..e0bd3f790fca 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c | |||
@@ -322,6 +322,7 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work) | |||
322 | kfree(evt); | 322 | kfree(evt); |
323 | } | 323 | } |
324 | 324 | ||
325 | blk_put_queue(sdev->request_queue); | ||
325 | /* NULL queue means the device can't be used */ | 326 | /* NULL queue means the device can't be used */ |
326 | sdev->request_queue = NULL; | 327 | sdev->request_queue = NULL; |
327 | 328 | ||
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index fbd96b29530d..de35c3ad8a69 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
@@ -80,6 +80,15 @@ config SPI_BFIN | |||
80 | help | 80 | help |
81 | This is the SPI controller master driver for Blackfin 5xx processor. | 81 | This is the SPI controller master driver for Blackfin 5xx processor. |
82 | 82 | ||
83 | config SPI_BFIN_SPORT | ||
84 | tristate "SPI bus via Blackfin SPORT" | ||
85 | depends on BLACKFIN | ||
86 | help | ||
87 | Enable support for a SPI bus via the Blackfin SPORT peripheral. | ||
88 | |||
89 | This driver can also be built as a module. If so, the module | ||
90 | will be called spi_bfin_sport. | ||
91 | |||
83 | config SPI_AU1550 | 92 | config SPI_AU1550 |
84 | tristate "Au1550/Au12x0 SPI Controller" | 93 | tristate "Au1550/Au12x0 SPI Controller" |
85 | depends on (SOC_AU1550 || SOC_AU1200) && EXPERIMENTAL | 94 | depends on (SOC_AU1550 || SOC_AU1200) && EXPERIMENTAL |
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index fd2fc5f6505f..0f8c69b6b19e 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile | |||
@@ -13,6 +13,7 @@ obj-$(CONFIG_SPI_ALTERA) += spi_altera.o | |||
13 | obj-$(CONFIG_SPI_ATMEL) += atmel_spi.o | 13 | obj-$(CONFIG_SPI_ATMEL) += atmel_spi.o |
14 | obj-$(CONFIG_SPI_ATH79) += ath79_spi.o | 14 | obj-$(CONFIG_SPI_ATH79) += ath79_spi.o |
15 | obj-$(CONFIG_SPI_BFIN) += spi_bfin5xx.o | 15 | obj-$(CONFIG_SPI_BFIN) += spi_bfin5xx.o |
16 | obj-$(CONFIG_SPI_BFIN_SPORT) += spi_bfin_sport.o | ||
16 | obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o | 17 | obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o |
17 | obj-$(CONFIG_SPI_AU1550) += au1550_spi.o | 18 | obj-$(CONFIG_SPI_AU1550) += au1550_spi.o |
18 | obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o | 19 | obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o |
diff --git a/drivers/spi/spi_bfin_sport.c b/drivers/spi/spi_bfin_sport.c new file mode 100644 index 000000000000..e557ff617b11 --- /dev/null +++ b/drivers/spi/spi_bfin_sport.c | |||
@@ -0,0 +1,952 @@ | |||
1 | /* | ||
2 | * SPI bus via the Blackfin SPORT peripheral | ||
3 | * | ||
4 | * Enter bugs at http://blackfin.uclinux.org/ | ||
5 | * | ||
6 | * Copyright 2009-2011 Analog Devices Inc. | ||
7 | * | ||
8 | * Licensed under the GPL-2 or later. | ||
9 | */ | ||
10 | |||
11 | #include <linux/init.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/delay.h> | ||
14 | #include <linux/device.h> | ||
15 | #include <linux/gpio.h> | ||
16 | #include <linux/io.h> | ||
17 | #include <linux/ioport.h> | ||
18 | #include <linux/irq.h> | ||
19 | #include <linux/errno.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/spi/spi.h> | ||
23 | #include <linux/workqueue.h> | ||
24 | |||
25 | #include <asm/portmux.h> | ||
26 | #include <asm/bfin5xx_spi.h> | ||
27 | #include <asm/blackfin.h> | ||
28 | #include <asm/bfin_sport.h> | ||
29 | #include <asm/cacheflush.h> | ||
30 | |||
31 | #define DRV_NAME "bfin-sport-spi" | ||
32 | #define DRV_DESC "SPI bus via the Blackfin SPORT" | ||
33 | |||
34 | MODULE_AUTHOR("Cliff Cai"); | ||
35 | MODULE_DESCRIPTION(DRV_DESC); | ||
36 | MODULE_LICENSE("GPL"); | ||
37 | MODULE_ALIAS("platform:bfin-sport-spi"); | ||
38 | |||
39 | enum bfin_sport_spi_state { | ||
40 | START_STATE, | ||
41 | RUNNING_STATE, | ||
42 | DONE_STATE, | ||
43 | ERROR_STATE, | ||
44 | }; | ||
45 | |||
46 | struct bfin_sport_spi_master_data; | ||
47 | |||
48 | struct bfin_sport_transfer_ops { | ||
49 | void (*write) (struct bfin_sport_spi_master_data *); | ||
50 | void (*read) (struct bfin_sport_spi_master_data *); | ||
51 | void (*duplex) (struct bfin_sport_spi_master_data *); | ||
52 | }; | ||
53 | |||
54 | struct bfin_sport_spi_master_data { | ||
55 | /* Driver model hookup */ | ||
56 | struct device *dev; | ||
57 | |||
58 | /* SPI framework hookup */ | ||
59 | struct spi_master *master; | ||
60 | |||
61 | /* Regs base of SPI controller */ | ||
62 | struct sport_register __iomem *regs; | ||
63 | int err_irq; | ||
64 | |||
65 | /* Pin request list */ | ||
66 | u16 *pin_req; | ||
67 | |||
68 | /* Driver message queue */ | ||
69 | struct workqueue_struct *workqueue; | ||
70 | struct work_struct pump_messages; | ||
71 | spinlock_t lock; | ||
72 | struct list_head queue; | ||
73 | int busy; | ||
74 | bool run; | ||
75 | |||
76 | /* Message Transfer pump */ | ||
77 | struct tasklet_struct pump_transfers; | ||
78 | |||
79 | /* Current message transfer state info */ | ||
80 | enum bfin_sport_spi_state state; | ||
81 | struct spi_message *cur_msg; | ||
82 | struct spi_transfer *cur_transfer; | ||
83 | struct bfin_sport_spi_slave_data *cur_chip; | ||
84 | union { | ||
85 | void *tx; | ||
86 | u8 *tx8; | ||
87 | u16 *tx16; | ||
88 | }; | ||
89 | void *tx_end; | ||
90 | union { | ||
91 | void *rx; | ||
92 | u8 *rx8; | ||
93 | u16 *rx16; | ||
94 | }; | ||
95 | void *rx_end; | ||
96 | |||
97 | int cs_change; | ||
98 | struct bfin_sport_transfer_ops *ops; | ||
99 | }; | ||
100 | |||
101 | struct bfin_sport_spi_slave_data { | ||
102 | u16 ctl_reg; | ||
103 | u16 baud; | ||
104 | u16 cs_chg_udelay; /* Some devices require > 255usec delay */ | ||
105 | u32 cs_gpio; | ||
106 | u16 idle_tx_val; | ||
107 | struct bfin_sport_transfer_ops *ops; | ||
108 | }; | ||
109 | |||
110 | static void | ||
111 | bfin_sport_spi_enable(struct bfin_sport_spi_master_data *drv_data) | ||
112 | { | ||
113 | bfin_write_or(&drv_data->regs->tcr1, TSPEN); | ||
114 | bfin_write_or(&drv_data->regs->rcr1, TSPEN); | ||
115 | SSYNC(); | ||
116 | } | ||
117 | |||
118 | static void | ||
119 | bfin_sport_spi_disable(struct bfin_sport_spi_master_data *drv_data) | ||
120 | { | ||
121 | bfin_write_and(&drv_data->regs->tcr1, ~TSPEN); | ||
122 | bfin_write_and(&drv_data->regs->rcr1, ~TSPEN); | ||
123 | SSYNC(); | ||
124 | } | ||
125 | |||
126 | /* Caculate the SPI_BAUD register value based on input HZ */ | ||
127 | static u16 | ||
128 | bfin_sport_hz_to_spi_baud(u32 speed_hz) | ||
129 | { | ||
130 | u_long clk, sclk = get_sclk(); | ||
131 | int div = (sclk / (2 * speed_hz)) - 1; | ||
132 | |||
133 | if (div < 0) | ||
134 | div = 0; | ||
135 | |||
136 | clk = sclk / (2 * (div + 1)); | ||
137 | |||
138 | if (clk > speed_hz) | ||
139 | div++; | ||
140 | |||
141 | return div; | ||
142 | } | ||
143 | |||
144 | /* Chip select operation functions for cs_change flag */ | ||
145 | static void | ||
146 | bfin_sport_spi_cs_active(struct bfin_sport_spi_slave_data *chip) | ||
147 | { | ||
148 | gpio_direction_output(chip->cs_gpio, 0); | ||
149 | } | ||
150 | |||
151 | static void | ||
152 | bfin_sport_spi_cs_deactive(struct bfin_sport_spi_slave_data *chip) | ||
153 | { | ||
154 | gpio_direction_output(chip->cs_gpio, 1); | ||
155 | /* Move delay here for consistency */ | ||
156 | if (chip->cs_chg_udelay) | ||
157 | udelay(chip->cs_chg_udelay); | ||
158 | } | ||
159 | |||
160 | static void | ||
161 | bfin_sport_spi_stat_poll_complete(struct bfin_sport_spi_master_data *drv_data) | ||
162 | { | ||
163 | unsigned long timeout = jiffies + HZ; | ||
164 | while (!(bfin_read(&drv_data->regs->stat) & RXNE)) { | ||
165 | if (!time_before(jiffies, timeout)) | ||
166 | break; | ||
167 | } | ||
168 | } | ||
169 | |||
170 | static void | ||
171 | bfin_sport_spi_u8_writer(struct bfin_sport_spi_master_data *drv_data) | ||
172 | { | ||
173 | u16 dummy; | ||
174 | |||
175 | while (drv_data->tx < drv_data->tx_end) { | ||
176 | bfin_write(&drv_data->regs->tx16, *drv_data->tx8++); | ||
177 | bfin_sport_spi_stat_poll_complete(drv_data); | ||
178 | dummy = bfin_read(&drv_data->regs->rx16); | ||
179 | } | ||
180 | } | ||
181 | |||
182 | static void | ||
183 | bfin_sport_spi_u8_reader(struct bfin_sport_spi_master_data *drv_data) | ||
184 | { | ||
185 | u16 tx_val = drv_data->cur_chip->idle_tx_val; | ||
186 | |||
187 | while (drv_data->rx < drv_data->rx_end) { | ||
188 | bfin_write(&drv_data->regs->tx16, tx_val); | ||
189 | bfin_sport_spi_stat_poll_complete(drv_data); | ||
190 | *drv_data->rx8++ = bfin_read(&drv_data->regs->rx16); | ||
191 | } | ||
192 | } | ||
193 | |||
194 | static void | ||
195 | bfin_sport_spi_u8_duplex(struct bfin_sport_spi_master_data *drv_data) | ||
196 | { | ||
197 | while (drv_data->rx < drv_data->rx_end) { | ||
198 | bfin_write(&drv_data->regs->tx16, *drv_data->tx8++); | ||
199 | bfin_sport_spi_stat_poll_complete(drv_data); | ||
200 | *drv_data->rx8++ = bfin_read(&drv_data->regs->rx16); | ||
201 | } | ||
202 | } | ||
203 | |||
204 | static struct bfin_sport_transfer_ops bfin_sport_transfer_ops_u8 = { | ||
205 | .write = bfin_sport_spi_u8_writer, | ||
206 | .read = bfin_sport_spi_u8_reader, | ||
207 | .duplex = bfin_sport_spi_u8_duplex, | ||
208 | }; | ||
209 | |||
210 | static void | ||
211 | bfin_sport_spi_u16_writer(struct bfin_sport_spi_master_data *drv_data) | ||
212 | { | ||
213 | u16 dummy; | ||
214 | |||
215 | while (drv_data->tx < drv_data->tx_end) { | ||
216 | bfin_write(&drv_data->regs->tx16, *drv_data->tx16++); | ||
217 | bfin_sport_spi_stat_poll_complete(drv_data); | ||
218 | dummy = bfin_read(&drv_data->regs->rx16); | ||
219 | } | ||
220 | } | ||
221 | |||
222 | static void | ||
223 | bfin_sport_spi_u16_reader(struct bfin_sport_spi_master_data *drv_data) | ||
224 | { | ||
225 | u16 tx_val = drv_data->cur_chip->idle_tx_val; | ||
226 | |||
227 | while (drv_data->rx < drv_data->rx_end) { | ||
228 | bfin_write(&drv_data->regs->tx16, tx_val); | ||
229 | bfin_sport_spi_stat_poll_complete(drv_data); | ||
230 | *drv_data->rx16++ = bfin_read(&drv_data->regs->rx16); | ||
231 | } | ||
232 | } | ||
233 | |||
234 | static void | ||
235 | bfin_sport_spi_u16_duplex(struct bfin_sport_spi_master_data *drv_data) | ||
236 | { | ||
237 | while (drv_data->rx < drv_data->rx_end) { | ||
238 | bfin_write(&drv_data->regs->tx16, *drv_data->tx16++); | ||
239 | bfin_sport_spi_stat_poll_complete(drv_data); | ||
240 | *drv_data->rx16++ = bfin_read(&drv_data->regs->rx16); | ||
241 | } | ||
242 | } | ||
243 | |||
244 | static struct bfin_sport_transfer_ops bfin_sport_transfer_ops_u16 = { | ||
245 | .write = bfin_sport_spi_u16_writer, | ||
246 | .read = bfin_sport_spi_u16_reader, | ||
247 | .duplex = bfin_sport_spi_u16_duplex, | ||
248 | }; | ||
249 | |||
250 | /* stop controller and re-config current chip */ | ||
251 | static void | ||
252 | bfin_sport_spi_restore_state(struct bfin_sport_spi_master_data *drv_data) | ||
253 | { | ||
254 | struct bfin_sport_spi_slave_data *chip = drv_data->cur_chip; | ||
255 | unsigned int bits = (drv_data->ops == &bfin_sport_transfer_ops_u8 ? 7 : 15); | ||
256 | |||
257 | bfin_sport_spi_disable(drv_data); | ||
258 | dev_dbg(drv_data->dev, "restoring spi ctl state\n"); | ||
259 | |||
260 | bfin_write(&drv_data->regs->tcr1, chip->ctl_reg); | ||
261 | bfin_write(&drv_data->regs->tcr2, bits); | ||
262 | bfin_write(&drv_data->regs->tclkdiv, chip->baud); | ||
263 | bfin_write(&drv_data->regs->tfsdiv, bits); | ||
264 | SSYNC(); | ||
265 | |||
266 | bfin_write(&drv_data->regs->rcr1, chip->ctl_reg & ~(ITCLK | ITFS)); | ||
267 | bfin_write(&drv_data->regs->rcr2, bits); | ||
268 | SSYNC(); | ||
269 | |||
270 | bfin_sport_spi_cs_active(chip); | ||
271 | } | ||
272 | |||
273 | /* test if there is more transfer to be done */ | ||
274 | static enum bfin_sport_spi_state | ||
275 | bfin_sport_spi_next_transfer(struct bfin_sport_spi_master_data *drv_data) | ||
276 | { | ||
277 | struct spi_message *msg = drv_data->cur_msg; | ||
278 | struct spi_transfer *trans = drv_data->cur_transfer; | ||
279 | |||
280 | /* Move to next transfer */ | ||
281 | if (trans->transfer_list.next != &msg->transfers) { | ||
282 | drv_data->cur_transfer = | ||
283 | list_entry(trans->transfer_list.next, | ||
284 | struct spi_transfer, transfer_list); | ||
285 | return RUNNING_STATE; | ||
286 | } | ||
287 | |||
288 | return DONE_STATE; | ||
289 | } | ||
290 | |||
291 | /* | ||
292 | * caller already set message->status; | ||
293 | * dma and pio irqs are blocked give finished message back | ||
294 | */ | ||
295 | static void | ||
296 | bfin_sport_spi_giveback(struct bfin_sport_spi_master_data *drv_data) | ||
297 | { | ||
298 | struct bfin_sport_spi_slave_data *chip = drv_data->cur_chip; | ||
299 | unsigned long flags; | ||
300 | struct spi_message *msg; | ||
301 | |||
302 | spin_lock_irqsave(&drv_data->lock, flags); | ||
303 | msg = drv_data->cur_msg; | ||
304 | drv_data->state = START_STATE; | ||
305 | drv_data->cur_msg = NULL; | ||
306 | drv_data->cur_transfer = NULL; | ||
307 | drv_data->cur_chip = NULL; | ||
308 | queue_work(drv_data->workqueue, &drv_data->pump_messages); | ||
309 | spin_unlock_irqrestore(&drv_data->lock, flags); | ||
310 | |||
311 | if (!drv_data->cs_change) | ||
312 | bfin_sport_spi_cs_deactive(chip); | ||
313 | |||
314 | if (msg->complete) | ||
315 | msg->complete(msg->context); | ||
316 | } | ||
317 | |||
318 | static irqreturn_t | ||
319 | sport_err_handler(int irq, void *dev_id) | ||
320 | { | ||
321 | struct bfin_sport_spi_master_data *drv_data = dev_id; | ||
322 | u16 status; | ||
323 | |||
324 | dev_dbg(drv_data->dev, "%s enter\n", __func__); | ||
325 | status = bfin_read(&drv_data->regs->stat) & (TOVF | TUVF | ROVF | RUVF); | ||
326 | |||
327 | if (status) { | ||
328 | bfin_write(&drv_data->regs->stat, status); | ||
329 | SSYNC(); | ||
330 | |||
331 | bfin_sport_spi_disable(drv_data); | ||
332 | dev_err(drv_data->dev, "status error:%s%s%s%s\n", | ||
333 | status & TOVF ? " TOVF" : "", | ||
334 | status & TUVF ? " TUVF" : "", | ||
335 | status & ROVF ? " ROVF" : "", | ||
336 | status & RUVF ? " RUVF" : ""); | ||
337 | } | ||
338 | |||
339 | return IRQ_HANDLED; | ||
340 | } | ||
341 | |||
342 | static void | ||
343 | bfin_sport_spi_pump_transfers(unsigned long data) | ||
344 | { | ||
345 | struct bfin_sport_spi_master_data *drv_data = (void *)data; | ||
346 | struct spi_message *message = NULL; | ||
347 | struct spi_transfer *transfer = NULL; | ||
348 | struct spi_transfer *previous = NULL; | ||
349 | struct bfin_sport_spi_slave_data *chip = NULL; | ||
350 | unsigned int bits_per_word; | ||
351 | u32 tranf_success = 1; | ||
352 | u32 transfer_speed; | ||
353 | u8 full_duplex = 0; | ||
354 | |||
355 | /* Get current state information */ | ||
356 | message = drv_data->cur_msg; | ||
357 | transfer = drv_data->cur_transfer; | ||
358 | chip = drv_data->cur_chip; | ||
359 | |||
360 | if (transfer->speed_hz) | ||
361 | transfer_speed = bfin_sport_hz_to_spi_baud(transfer->speed_hz); | ||
362 | else | ||
363 | transfer_speed = chip->baud; | ||
364 | bfin_write(&drv_data->regs->tclkdiv, transfer_speed); | ||
365 | SSYNC(); | ||
366 | |||
367 | /* | ||
368 | * if msg is error or done, report it back using complete() callback | ||
369 | */ | ||
370 | |||
371 | /* Handle for abort */ | ||
372 | if (drv_data->state == ERROR_STATE) { | ||
373 | dev_dbg(drv_data->dev, "transfer: we've hit an error\n"); | ||
374 | message->status = -EIO; | ||
375 | bfin_sport_spi_giveback(drv_data); | ||
376 | return; | ||
377 | } | ||
378 | |||
379 | /* Handle end of message */ | ||
380 | if (drv_data->state == DONE_STATE) { | ||
381 | dev_dbg(drv_data->dev, "transfer: all done!\n"); | ||
382 | message->status = 0; | ||
383 | bfin_sport_spi_giveback(drv_data); | ||
384 | return; | ||
385 | } | ||
386 | |||
387 | /* Delay if requested at end of transfer */ | ||
388 | if (drv_data->state == RUNNING_STATE) { | ||
389 | dev_dbg(drv_data->dev, "transfer: still running ...\n"); | ||
390 | previous = list_entry(transfer->transfer_list.prev, | ||
391 | struct spi_transfer, transfer_list); | ||
392 | if (previous->delay_usecs) | ||
393 | udelay(previous->delay_usecs); | ||
394 | } | ||
395 | |||
396 | if (transfer->len == 0) { | ||
397 | /* Move to next transfer of this msg */ | ||
398 | drv_data->state = bfin_sport_spi_next_transfer(drv_data); | ||
399 | /* Schedule next transfer tasklet */ | ||
400 | tasklet_schedule(&drv_data->pump_transfers); | ||
401 | } | ||
402 | |||
403 | if (transfer->tx_buf != NULL) { | ||
404 | drv_data->tx = (void *)transfer->tx_buf; | ||
405 | drv_data->tx_end = drv_data->tx + transfer->len; | ||
406 | dev_dbg(drv_data->dev, "tx_buf is %p, tx_end is %p\n", | ||
407 | transfer->tx_buf, drv_data->tx_end); | ||
408 | } else | ||
409 | drv_data->tx = NULL; | ||
410 | |||
411 | if (transfer->rx_buf != NULL) { | ||
412 | full_duplex = transfer->tx_buf != NULL; | ||
413 | drv_data->rx = transfer->rx_buf; | ||
414 | drv_data->rx_end = drv_data->rx + transfer->len; | ||
415 | dev_dbg(drv_data->dev, "rx_buf is %p, rx_end is %p\n", | ||
416 | transfer->rx_buf, drv_data->rx_end); | ||
417 | } else | ||
418 | drv_data->rx = NULL; | ||
419 | |||
420 | drv_data->cs_change = transfer->cs_change; | ||
421 | |||
422 | /* Bits per word setup */ | ||
423 | bits_per_word = transfer->bits_per_word ? : message->spi->bits_per_word; | ||
424 | if (bits_per_word == 8) | ||
425 | drv_data->ops = &bfin_sport_transfer_ops_u8; | ||
426 | else | ||
427 | drv_data->ops = &bfin_sport_transfer_ops_u16; | ||
428 | |||
429 | drv_data->state = RUNNING_STATE; | ||
430 | |||
431 | if (drv_data->cs_change) | ||
432 | bfin_sport_spi_cs_active(chip); | ||
433 | |||
434 | dev_dbg(drv_data->dev, | ||
435 | "now pumping a transfer: width is %d, len is %d\n", | ||
436 | bits_per_word, transfer->len); | ||
437 | |||
438 | /* PIO mode write then read */ | ||
439 | dev_dbg(drv_data->dev, "doing IO transfer\n"); | ||
440 | |||
441 | bfin_sport_spi_enable(drv_data); | ||
442 | if (full_duplex) { | ||
443 | /* full duplex mode */ | ||
444 | BUG_ON((drv_data->tx_end - drv_data->tx) != | ||
445 | (drv_data->rx_end - drv_data->rx)); | ||
446 | drv_data->ops->duplex(drv_data); | ||
447 | |||
448 | if (drv_data->tx != drv_data->tx_end) | ||
449 | tranf_success = 0; | ||
450 | } else if (drv_data->tx != NULL) { | ||
451 | /* write only half duplex */ | ||
452 | |||
453 | drv_data->ops->write(drv_data); | ||
454 | |||
455 | if (drv_data->tx != drv_data->tx_end) | ||
456 | tranf_success = 0; | ||
457 | } else if (drv_data->rx != NULL) { | ||
458 | /* read only half duplex */ | ||
459 | |||
460 | drv_data->ops->read(drv_data); | ||
461 | if (drv_data->rx != drv_data->rx_end) | ||
462 | tranf_success = 0; | ||
463 | } | ||
464 | bfin_sport_spi_disable(drv_data); | ||
465 | |||
466 | if (!tranf_success) { | ||
467 | dev_dbg(drv_data->dev, "IO write error!\n"); | ||
468 | drv_data->state = ERROR_STATE; | ||
469 | } else { | ||
470 | /* Update total byte transfered */ | ||
471 | message->actual_length += transfer->len; | ||
472 | /* Move to next transfer of this msg */ | ||
473 | drv_data->state = bfin_sport_spi_next_transfer(drv_data); | ||
474 | if (drv_data->cs_change) | ||
475 | bfin_sport_spi_cs_deactive(chip); | ||
476 | } | ||
477 | |||
478 | /* Schedule next transfer tasklet */ | ||
479 | tasklet_schedule(&drv_data->pump_transfers); | ||
480 | } | ||
481 | |||
482 | /* pop a msg from queue and kick off real transfer */ | ||
483 | static void | ||
484 | bfin_sport_spi_pump_messages(struct work_struct *work) | ||
485 | { | ||
486 | struct bfin_sport_spi_master_data *drv_data; | ||
487 | unsigned long flags; | ||
488 | struct spi_message *next_msg; | ||
489 | |||
490 | drv_data = container_of(work, struct bfin_sport_spi_master_data, pump_messages); | ||
491 | |||
492 | /* Lock queue and check for queue work */ | ||
493 | spin_lock_irqsave(&drv_data->lock, flags); | ||
494 | if (list_empty(&drv_data->queue) || !drv_data->run) { | ||
495 | /* pumper kicked off but no work to do */ | ||
496 | drv_data->busy = 0; | ||
497 | spin_unlock_irqrestore(&drv_data->lock, flags); | ||
498 | return; | ||
499 | } | ||
500 | |||
501 | /* Make sure we are not already running a message */ | ||
502 | if (drv_data->cur_msg) { | ||
503 | spin_unlock_irqrestore(&drv_data->lock, flags); | ||
504 | return; | ||
505 | } | ||
506 | |||
507 | /* Extract head of queue */ | ||
508 | next_msg = list_entry(drv_data->queue.next, | ||
509 | struct spi_message, queue); | ||
510 | |||
511 | drv_data->cur_msg = next_msg; | ||
512 | |||
513 | /* Setup the SSP using the per chip configuration */ | ||
514 | drv_data->cur_chip = spi_get_ctldata(drv_data->cur_msg->spi); | ||
515 | |||
516 | list_del_init(&drv_data->cur_msg->queue); | ||
517 | |||
518 | /* Initialize message state */ | ||
519 | drv_data->cur_msg->state = START_STATE; | ||
520 | drv_data->cur_transfer = list_entry(drv_data->cur_msg->transfers.next, | ||
521 | struct spi_transfer, transfer_list); | ||
522 | bfin_sport_spi_restore_state(drv_data); | ||
523 | dev_dbg(drv_data->dev, "got a message to pump, " | ||
524 | "state is set to: baud %d, cs_gpio %i, ctl 0x%x\n", | ||
525 | drv_data->cur_chip->baud, drv_data->cur_chip->cs_gpio, | ||
526 | drv_data->cur_chip->ctl_reg); | ||
527 | |||
528 | dev_dbg(drv_data->dev, | ||
529 | "the first transfer len is %d\n", | ||
530 | drv_data->cur_transfer->len); | ||
531 | |||
532 | /* Mark as busy and launch transfers */ | ||
533 | tasklet_schedule(&drv_data->pump_transfers); | ||
534 | |||
535 | drv_data->busy = 1; | ||
536 | spin_unlock_irqrestore(&drv_data->lock, flags); | ||
537 | } | ||
538 | |||
539 | /* | ||
540 | * got a msg to transfer, queue it in drv_data->queue. | ||
541 | * And kick off message pumper | ||
542 | */ | ||
543 | static int | ||
544 | bfin_sport_spi_transfer(struct spi_device *spi, struct spi_message *msg) | ||
545 | { | ||
546 | struct bfin_sport_spi_master_data *drv_data = spi_master_get_devdata(spi->master); | ||
547 | unsigned long flags; | ||
548 | |||
549 | spin_lock_irqsave(&drv_data->lock, flags); | ||
550 | |||
551 | if (!drv_data->run) { | ||
552 | spin_unlock_irqrestore(&drv_data->lock, flags); | ||
553 | return -ESHUTDOWN; | ||
554 | } | ||
555 | |||
556 | msg->actual_length = 0; | ||
557 | msg->status = -EINPROGRESS; | ||
558 | msg->state = START_STATE; | ||
559 | |||
560 | dev_dbg(&spi->dev, "adding an msg in transfer()\n"); | ||
561 | list_add_tail(&msg->queue, &drv_data->queue); | ||
562 | |||
563 | if (drv_data->run && !drv_data->busy) | ||
564 | queue_work(drv_data->workqueue, &drv_data->pump_messages); | ||
565 | |||
566 | spin_unlock_irqrestore(&drv_data->lock, flags); | ||
567 | |||
568 | return 0; | ||
569 | } | ||
570 | |||
571 | /* Called every time common spi devices change state */ | ||
572 | static int | ||
573 | bfin_sport_spi_setup(struct spi_device *spi) | ||
574 | { | ||
575 | struct bfin_sport_spi_slave_data *chip, *first = NULL; | ||
576 | int ret; | ||
577 | |||
578 | /* Only alloc (or use chip_info) on first setup */ | ||
579 | chip = spi_get_ctldata(spi); | ||
580 | if (chip == NULL) { | ||
581 | struct bfin5xx_spi_chip *chip_info; | ||
582 | |||
583 | chip = first = kzalloc(sizeof(*chip), GFP_KERNEL); | ||
584 | if (!chip) | ||
585 | return -ENOMEM; | ||
586 | |||
587 | /* platform chip_info isn't required */ | ||
588 | chip_info = spi->controller_data; | ||
589 | if (chip_info) { | ||
590 | /* | ||
591 | * DITFS and TDTYPE are only thing we don't set, but | ||
592 | * they probably shouldn't be changed by people. | ||
593 | */ | ||
594 | if (chip_info->ctl_reg || chip_info->enable_dma) { | ||
595 | ret = -EINVAL; | ||
596 | dev_err(&spi->dev, "don't set ctl_reg/enable_dma fields"); | ||
597 | goto error; | ||
598 | } | ||
599 | chip->cs_chg_udelay = chip_info->cs_chg_udelay; | ||
600 | chip->idle_tx_val = chip_info->idle_tx_val; | ||
601 | spi->bits_per_word = chip_info->bits_per_word; | ||
602 | } | ||
603 | } | ||
604 | |||
605 | if (spi->bits_per_word != 8 && spi->bits_per_word != 16) { | ||
606 | ret = -EINVAL; | ||
607 | goto error; | ||
608 | } | ||
609 | |||
610 | /* translate common spi framework into our register | ||
611 | * following configure contents are same for tx and rx. | ||
612 | */ | ||
613 | |||
614 | if (spi->mode & SPI_CPHA) | ||
615 | chip->ctl_reg &= ~TCKFE; | ||
616 | else | ||
617 | chip->ctl_reg |= TCKFE; | ||
618 | |||
619 | if (spi->mode & SPI_LSB_FIRST) | ||
620 | chip->ctl_reg |= TLSBIT; | ||
621 | else | ||
622 | chip->ctl_reg &= ~TLSBIT; | ||
623 | |||
624 | /* Sport in master mode */ | ||
625 | chip->ctl_reg |= ITCLK | ITFS | TFSR | LATFS | LTFS; | ||
626 | |||
627 | chip->baud = bfin_sport_hz_to_spi_baud(spi->max_speed_hz); | ||
628 | |||
629 | chip->cs_gpio = spi->chip_select; | ||
630 | ret = gpio_request(chip->cs_gpio, spi->modalias); | ||
631 | if (ret) | ||
632 | goto error; | ||
633 | |||
634 | dev_dbg(&spi->dev, "setup spi chip %s, width is %d\n", | ||
635 | spi->modalias, spi->bits_per_word); | ||
636 | dev_dbg(&spi->dev, "ctl_reg is 0x%x, GPIO is %i\n", | ||
637 | chip->ctl_reg, spi->chip_select); | ||
638 | |||
639 | spi_set_ctldata(spi, chip); | ||
640 | |||
641 | bfin_sport_spi_cs_deactive(chip); | ||
642 | |||
643 | return ret; | ||
644 | |||
645 | error: | ||
646 | kfree(first); | ||
647 | return ret; | ||
648 | } | ||
649 | |||
650 | /* | ||
651 | * callback for spi framework. | ||
652 | * clean driver specific data | ||
653 | */ | ||
654 | static void | ||
655 | bfin_sport_spi_cleanup(struct spi_device *spi) | ||
656 | { | ||
657 | struct bfin_sport_spi_slave_data *chip = spi_get_ctldata(spi); | ||
658 | |||
659 | if (!chip) | ||
660 | return; | ||
661 | |||
662 | gpio_free(chip->cs_gpio); | ||
663 | |||
664 | kfree(chip); | ||
665 | } | ||
666 | |||
667 | static int | ||
668 | bfin_sport_spi_init_queue(struct bfin_sport_spi_master_data *drv_data) | ||
669 | { | ||
670 | INIT_LIST_HEAD(&drv_data->queue); | ||
671 | spin_lock_init(&drv_data->lock); | ||
672 | |||
673 | drv_data->run = false; | ||
674 | drv_data->busy = 0; | ||
675 | |||
676 | /* init transfer tasklet */ | ||
677 | tasklet_init(&drv_data->pump_transfers, | ||
678 | bfin_sport_spi_pump_transfers, (unsigned long)drv_data); | ||
679 | |||
680 | /* init messages workqueue */ | ||
681 | INIT_WORK(&drv_data->pump_messages, bfin_sport_spi_pump_messages); | ||
682 | drv_data->workqueue = | ||
683 | create_singlethread_workqueue(dev_name(drv_data->master->dev.parent)); | ||
684 | if (drv_data->workqueue == NULL) | ||
685 | return -EBUSY; | ||
686 | |||
687 | return 0; | ||
688 | } | ||
689 | |||
690 | static int | ||
691 | bfin_sport_spi_start_queue(struct bfin_sport_spi_master_data *drv_data) | ||
692 | { | ||
693 | unsigned long flags; | ||
694 | |||
695 | spin_lock_irqsave(&drv_data->lock, flags); | ||
696 | |||
697 | if (drv_data->run || drv_data->busy) { | ||
698 | spin_unlock_irqrestore(&drv_data->lock, flags); | ||
699 | return -EBUSY; | ||
700 | } | ||
701 | |||
702 | drv_data->run = true; | ||
703 | drv_data->cur_msg = NULL; | ||
704 | drv_data->cur_transfer = NULL; | ||
705 | drv_data->cur_chip = NULL; | ||
706 | spin_unlock_irqrestore(&drv_data->lock, flags); | ||
707 | |||
708 | queue_work(drv_data->workqueue, &drv_data->pump_messages); | ||
709 | |||
710 | return 0; | ||
711 | } | ||
712 | |||
713 | static inline int | ||
714 | bfin_sport_spi_stop_queue(struct bfin_sport_spi_master_data *drv_data) | ||
715 | { | ||
716 | unsigned long flags; | ||
717 | unsigned limit = 500; | ||
718 | int status = 0; | ||
719 | |||
720 | spin_lock_irqsave(&drv_data->lock, flags); | ||
721 | |||
722 | /* | ||
723 | * This is a bit lame, but is optimized for the common execution path. | ||
724 | * A wait_queue on the drv_data->busy could be used, but then the common | ||
725 | * execution path (pump_messages) would be required to call wake_up or | ||
726 | * friends on every SPI message. Do this instead | ||
727 | */ | ||
728 | drv_data->run = false; | ||
729 | while (!list_empty(&drv_data->queue) && drv_data->busy && limit--) { | ||
730 | spin_unlock_irqrestore(&drv_data->lock, flags); | ||
731 | msleep(10); | ||
732 | spin_lock_irqsave(&drv_data->lock, flags); | ||
733 | } | ||
734 | |||
735 | if (!list_empty(&drv_data->queue) || drv_data->busy) | ||
736 | status = -EBUSY; | ||
737 | |||
738 | spin_unlock_irqrestore(&drv_data->lock, flags); | ||
739 | |||
740 | return status; | ||
741 | } | ||
742 | |||
743 | static inline int | ||
744 | bfin_sport_spi_destroy_queue(struct bfin_sport_spi_master_data *drv_data) | ||
745 | { | ||
746 | int status; | ||
747 | |||
748 | status = bfin_sport_spi_stop_queue(drv_data); | ||
749 | if (status) | ||
750 | return status; | ||
751 | |||
752 | destroy_workqueue(drv_data->workqueue); | ||
753 | |||
754 | return 0; | ||
755 | } | ||
756 | |||
757 | static int __devinit | ||
758 | bfin_sport_spi_probe(struct platform_device *pdev) | ||
759 | { | ||
760 | struct device *dev = &pdev->dev; | ||
761 | struct bfin5xx_spi_master *platform_info; | ||
762 | struct spi_master *master; | ||
763 | struct resource *res, *ires; | ||
764 | struct bfin_sport_spi_master_data *drv_data; | ||
765 | int status; | ||
766 | |||
767 | platform_info = dev->platform_data; | ||
768 | |||
769 | /* Allocate master with space for drv_data */ | ||
770 | master = spi_alloc_master(dev, sizeof(*master) + 16); | ||
771 | if (!master) { | ||
772 | dev_err(dev, "cannot alloc spi_master\n"); | ||
773 | return -ENOMEM; | ||
774 | } | ||
775 | |||
776 | drv_data = spi_master_get_devdata(master); | ||
777 | drv_data->master = master; | ||
778 | drv_data->dev = dev; | ||
779 | drv_data->pin_req = platform_info->pin_req; | ||
780 | |||
781 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST; | ||
782 | master->bus_num = pdev->id; | ||
783 | master->num_chipselect = platform_info->num_chipselect; | ||
784 | master->cleanup = bfin_sport_spi_cleanup; | ||
785 | master->setup = bfin_sport_spi_setup; | ||
786 | master->transfer = bfin_sport_spi_transfer; | ||
787 | |||
788 | /* Find and map our resources */ | ||
789 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
790 | if (res == NULL) { | ||
791 | dev_err(dev, "cannot get IORESOURCE_MEM\n"); | ||
792 | status = -ENOENT; | ||
793 | goto out_error_get_res; | ||
794 | } | ||
795 | |||
796 | drv_data->regs = ioremap(res->start, resource_size(res)); | ||
797 | if (drv_data->regs == NULL) { | ||
798 | dev_err(dev, "cannot map registers\n"); | ||
799 | status = -ENXIO; | ||
800 | goto out_error_ioremap; | ||
801 | } | ||
802 | |||
803 | ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
804 | if (!ires) { | ||
805 | dev_err(dev, "cannot get IORESOURCE_IRQ\n"); | ||
806 | status = -ENODEV; | ||
807 | goto out_error_get_ires; | ||
808 | } | ||
809 | drv_data->err_irq = ires->start; | ||
810 | |||
811 | /* Initial and start queue */ | ||
812 | status = bfin_sport_spi_init_queue(drv_data); | ||
813 | if (status) { | ||
814 | dev_err(dev, "problem initializing queue\n"); | ||
815 | goto out_error_queue_alloc; | ||
816 | } | ||
817 | |||
818 | status = bfin_sport_spi_start_queue(drv_data); | ||
819 | if (status) { | ||
820 | dev_err(dev, "problem starting queue\n"); | ||
821 | goto out_error_queue_alloc; | ||
822 | } | ||
823 | |||
824 | status = request_irq(drv_data->err_irq, sport_err_handler, | ||
825 | 0, "sport_spi_err", drv_data); | ||
826 | if (status) { | ||
827 | dev_err(dev, "unable to request sport err irq\n"); | ||
828 | goto out_error_irq; | ||
829 | } | ||
830 | |||
831 | status = peripheral_request_list(drv_data->pin_req, DRV_NAME); | ||
832 | if (status) { | ||
833 | dev_err(dev, "requesting peripherals failed\n"); | ||
834 | goto out_error_peripheral; | ||
835 | } | ||
836 | |||
837 | /* Register with the SPI framework */ | ||
838 | platform_set_drvdata(pdev, drv_data); | ||
839 | status = spi_register_master(master); | ||
840 | if (status) { | ||
841 | dev_err(dev, "problem registering spi master\n"); | ||
842 | goto out_error_master; | ||
843 | } | ||
844 | |||
845 | dev_info(dev, "%s, regs_base@%p\n", DRV_DESC, drv_data->regs); | ||
846 | return 0; | ||
847 | |||
848 | out_error_master: | ||
849 | peripheral_free_list(drv_data->pin_req); | ||
850 | out_error_peripheral: | ||
851 | free_irq(drv_data->err_irq, drv_data); | ||
852 | out_error_irq: | ||
853 | out_error_queue_alloc: | ||
854 | bfin_sport_spi_destroy_queue(drv_data); | ||
855 | out_error_get_ires: | ||
856 | iounmap(drv_data->regs); | ||
857 | out_error_ioremap: | ||
858 | out_error_get_res: | ||
859 | spi_master_put(master); | ||
860 | |||
861 | return status; | ||
862 | } | ||
863 | |||
864 | /* stop hardware and remove the driver */ | ||
865 | static int __devexit | ||
866 | bfin_sport_spi_remove(struct platform_device *pdev) | ||
867 | { | ||
868 | struct bfin_sport_spi_master_data *drv_data = platform_get_drvdata(pdev); | ||
869 | int status = 0; | ||
870 | |||
871 | if (!drv_data) | ||
872 | return 0; | ||
873 | |||
874 | /* Remove the queue */ | ||
875 | status = bfin_sport_spi_destroy_queue(drv_data); | ||
876 | if (status) | ||
877 | return status; | ||
878 | |||
879 | /* Disable the SSP at the peripheral and SOC level */ | ||
880 | bfin_sport_spi_disable(drv_data); | ||
881 | |||
882 | /* Disconnect from the SPI framework */ | ||
883 | spi_unregister_master(drv_data->master); | ||
884 | |||
885 | peripheral_free_list(drv_data->pin_req); | ||
886 | |||
887 | /* Prevent double remove */ | ||
888 | platform_set_drvdata(pdev, NULL); | ||
889 | |||
890 | return 0; | ||
891 | } | ||
892 | |||
893 | #ifdef CONFIG_PM | ||
894 | static int | ||
895 | bfin_sport_spi_suspend(struct platform_device *pdev, pm_message_t state) | ||
896 | { | ||
897 | struct bfin_sport_spi_master_data *drv_data = platform_get_drvdata(pdev); | ||
898 | int status; | ||
899 | |||
900 | status = bfin_sport_spi_stop_queue(drv_data); | ||
901 | if (status) | ||
902 | return status; | ||
903 | |||
904 | /* stop hardware */ | ||
905 | bfin_sport_spi_disable(drv_data); | ||
906 | |||
907 | return status; | ||
908 | } | ||
909 | |||
910 | static int | ||
911 | bfin_sport_spi_resume(struct platform_device *pdev) | ||
912 | { | ||
913 | struct bfin_sport_spi_master_data *drv_data = platform_get_drvdata(pdev); | ||
914 | int status; | ||
915 | |||
916 | /* Enable the SPI interface */ | ||
917 | bfin_sport_spi_enable(drv_data); | ||
918 | |||
919 | /* Start the queue running */ | ||
920 | status = bfin_sport_spi_start_queue(drv_data); | ||
921 | if (status) | ||
922 | dev_err(drv_data->dev, "problem resuming queue\n"); | ||
923 | |||
924 | return status; | ||
925 | } | ||
926 | #else | ||
927 | # define bfin_sport_spi_suspend NULL | ||
928 | # define bfin_sport_spi_resume NULL | ||
929 | #endif | ||
930 | |||
931 | static struct platform_driver bfin_sport_spi_driver = { | ||
932 | .driver = { | ||
933 | .name = DRV_NAME, | ||
934 | .owner = THIS_MODULE, | ||
935 | }, | ||
936 | .probe = bfin_sport_spi_probe, | ||
937 | .remove = __devexit_p(bfin_sport_spi_remove), | ||
938 | .suspend = bfin_sport_spi_suspend, | ||
939 | .resume = bfin_sport_spi_resume, | ||
940 | }; | ||
941 | |||
942 | static int __init bfin_sport_spi_init(void) | ||
943 | { | ||
944 | return platform_driver_register(&bfin_sport_spi_driver); | ||
945 | } | ||
946 | module_init(bfin_sport_spi_init); | ||
947 | |||
948 | static void __exit bfin_sport_spi_exit(void) | ||
949 | { | ||
950 | platform_driver_unregister(&bfin_sport_spi_driver); | ||
951 | } | ||
952 | module_exit(bfin_sport_spi_exit); | ||
diff --git a/drivers/spi/tle62x0.c b/drivers/spi/tle62x0.c index a3938958147c..32a40876532f 100644 --- a/drivers/spi/tle62x0.c +++ b/drivers/spi/tle62x0.c | |||
@@ -283,7 +283,7 @@ static int __devinit tle62x0_probe(struct spi_device *spi) | |||
283 | return 0; | 283 | return 0; |
284 | 284 | ||
285 | err_gpios: | 285 | err_gpios: |
286 | for (; ptr > 0; ptr--) | 286 | while (--ptr >= 0) |
287 | device_remove_file(&spi->dev, gpio_attrs[ptr]); | 287 | device_remove_file(&spi->dev, gpio_attrs[ptr]); |
288 | 288 | ||
289 | device_remove_file(&spi->dev, &dev_attr_status_show); | 289 | device_remove_file(&spi->dev, &dev_attr_status_show); |
@@ -301,6 +301,7 @@ static int __devexit tle62x0_remove(struct spi_device *spi) | |||
301 | for (ptr = 0; ptr < st->nr_gpio; ptr++) | 301 | for (ptr = 0; ptr < st->nr_gpio; ptr++) |
302 | device_remove_file(&spi->dev, gpio_attrs[ptr]); | 302 | device_remove_file(&spi->dev, gpio_attrs[ptr]); |
303 | 303 | ||
304 | device_remove_file(&spi->dev, &dev_attr_status_show); | ||
304 | kfree(st); | 305 | kfree(st); |
305 | return 0; | 306 | return 0; |
306 | } | 307 | } |
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c index fc6f2a5bde01..0b1c82ad6805 100644 --- a/drivers/thermal/thermal_sys.c +++ b/drivers/thermal/thermal_sys.c | |||
@@ -499,7 +499,7 @@ thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) | |||
499 | dev_set_drvdata(hwmon->device, hwmon); | 499 | dev_set_drvdata(hwmon->device, hwmon); |
500 | result = device_create_file(hwmon->device, &dev_attr_name); | 500 | result = device_create_file(hwmon->device, &dev_attr_name); |
501 | if (result) | 501 | if (result) |
502 | goto unregister_hwmon_device; | 502 | goto free_mem; |
503 | 503 | ||
504 | register_sys_interface: | 504 | register_sys_interface: |
505 | tz->hwmon = hwmon; | 505 | tz->hwmon = hwmon; |
@@ -513,7 +513,7 @@ thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) | |||
513 | sysfs_attr_init(&tz->temp_input.attr.attr); | 513 | sysfs_attr_init(&tz->temp_input.attr.attr); |
514 | result = device_create_file(hwmon->device, &tz->temp_input.attr); | 514 | result = device_create_file(hwmon->device, &tz->temp_input.attr); |
515 | if (result) | 515 | if (result) |
516 | goto unregister_hwmon_device; | 516 | goto unregister_name; |
517 | 517 | ||
518 | if (tz->ops->get_crit_temp) { | 518 | if (tz->ops->get_crit_temp) { |
519 | unsigned long temperature; | 519 | unsigned long temperature; |
@@ -527,7 +527,7 @@ thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) | |||
527 | result = device_create_file(hwmon->device, | 527 | result = device_create_file(hwmon->device, |
528 | &tz->temp_crit.attr); | 528 | &tz->temp_crit.attr); |
529 | if (result) | 529 | if (result) |
530 | goto unregister_hwmon_device; | 530 | goto unregister_input; |
531 | } | 531 | } |
532 | } | 532 | } |
533 | 533 | ||
@@ -539,9 +539,9 @@ thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) | |||
539 | 539 | ||
540 | return 0; | 540 | return 0; |
541 | 541 | ||
542 | unregister_hwmon_device: | 542 | unregister_input: |
543 | device_remove_file(hwmon->device, &tz->temp_crit.attr); | ||
544 | device_remove_file(hwmon->device, &tz->temp_input.attr); | 543 | device_remove_file(hwmon->device, &tz->temp_input.attr); |
544 | unregister_name: | ||
545 | if (new_hwmon_device) { | 545 | if (new_hwmon_device) { |
546 | device_remove_file(hwmon->device, &dev_attr_name); | 546 | device_remove_file(hwmon->device, &dev_attr_name); |
547 | hwmon_device_unregister(hwmon->device); | 547 | hwmon_device_unregister(hwmon->device); |
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index a4c42a75a3bf..09e8c7d53af3 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c | |||
@@ -2128,8 +2128,8 @@ static void gsmld_detach_gsm(struct tty_struct *tty, struct gsm_mux *gsm) | |||
2128 | gsm->tty = NULL; | 2128 | gsm->tty = NULL; |
2129 | } | 2129 | } |
2130 | 2130 | ||
2131 | static unsigned int gsmld_receive_buf(struct tty_struct *tty, | 2131 | static void gsmld_receive_buf(struct tty_struct *tty, const unsigned char *cp, |
2132 | const unsigned char *cp, char *fp, int count) | 2132 | char *fp, int count) |
2133 | { | 2133 | { |
2134 | struct gsm_mux *gsm = tty->disc_data; | 2134 | struct gsm_mux *gsm = tty->disc_data; |
2135 | const unsigned char *dp; | 2135 | const unsigned char *dp; |
@@ -2162,8 +2162,6 @@ static unsigned int gsmld_receive_buf(struct tty_struct *tty, | |||
2162 | } | 2162 | } |
2163 | /* FASYNC if needed ? */ | 2163 | /* FASYNC if needed ? */ |
2164 | /* If clogged call tty_throttle(tty); */ | 2164 | /* If clogged call tty_throttle(tty); */ |
2165 | |||
2166 | return count; | ||
2167 | } | 2165 | } |
2168 | 2166 | ||
2169 | /** | 2167 | /** |
diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c index cac666314aef..cea56033b34c 100644 --- a/drivers/tty/n_hdlc.c +++ b/drivers/tty/n_hdlc.c | |||
@@ -188,8 +188,8 @@ static unsigned int n_hdlc_tty_poll(struct tty_struct *tty, struct file *filp, | |||
188 | poll_table *wait); | 188 | poll_table *wait); |
189 | static int n_hdlc_tty_open(struct tty_struct *tty); | 189 | static int n_hdlc_tty_open(struct tty_struct *tty); |
190 | static void n_hdlc_tty_close(struct tty_struct *tty); | 190 | static void n_hdlc_tty_close(struct tty_struct *tty); |
191 | static unsigned int n_hdlc_tty_receive(struct tty_struct *tty, | 191 | static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *cp, |
192 | const __u8 *cp, char *fp, int count); | 192 | char *fp, int count); |
193 | static void n_hdlc_tty_wakeup(struct tty_struct *tty); | 193 | static void n_hdlc_tty_wakeup(struct tty_struct *tty); |
194 | 194 | ||
195 | #define bset(p,b) ((p)[(b) >> 5] |= (1 << ((b) & 0x1f))) | 195 | #define bset(p,b) ((p)[(b) >> 5] |= (1 << ((b) & 0x1f))) |
@@ -509,8 +509,8 @@ static void n_hdlc_tty_wakeup(struct tty_struct *tty) | |||
509 | * Called by tty low level driver when receive data is available. Data is | 509 | * Called by tty low level driver when receive data is available. Data is |
510 | * interpreted as one HDLC frame. | 510 | * interpreted as one HDLC frame. |
511 | */ | 511 | */ |
512 | static unsigned int n_hdlc_tty_receive(struct tty_struct *tty, | 512 | static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data, |
513 | const __u8 *data, char *flags, int count) | 513 | char *flags, int count) |
514 | { | 514 | { |
515 | register struct n_hdlc *n_hdlc = tty2n_hdlc (tty); | 515 | register struct n_hdlc *n_hdlc = tty2n_hdlc (tty); |
516 | register struct n_hdlc_buf *buf; | 516 | register struct n_hdlc_buf *buf; |
@@ -521,20 +521,20 @@ static unsigned int n_hdlc_tty_receive(struct tty_struct *tty, | |||
521 | 521 | ||
522 | /* This can happen if stuff comes in on the backup tty */ | 522 | /* This can happen if stuff comes in on the backup tty */ |
523 | if (!n_hdlc || tty != n_hdlc->tty) | 523 | if (!n_hdlc || tty != n_hdlc->tty) |
524 | return -ENODEV; | 524 | return; |
525 | 525 | ||
526 | /* verify line is using HDLC discipline */ | 526 | /* verify line is using HDLC discipline */ |
527 | if (n_hdlc->magic != HDLC_MAGIC) { | 527 | if (n_hdlc->magic != HDLC_MAGIC) { |
528 | printk("%s(%d) line not using HDLC discipline\n", | 528 | printk("%s(%d) line not using HDLC discipline\n", |
529 | __FILE__,__LINE__); | 529 | __FILE__,__LINE__); |
530 | return -EINVAL; | 530 | return; |
531 | } | 531 | } |
532 | 532 | ||
533 | if ( count>maxframe ) { | 533 | if ( count>maxframe ) { |
534 | if (debuglevel >= DEBUG_LEVEL_INFO) | 534 | if (debuglevel >= DEBUG_LEVEL_INFO) |
535 | printk("%s(%d) rx count>maxframesize, data discarded\n", | 535 | printk("%s(%d) rx count>maxframesize, data discarded\n", |
536 | __FILE__,__LINE__); | 536 | __FILE__,__LINE__); |
537 | return -EINVAL; | 537 | return; |
538 | } | 538 | } |
539 | 539 | ||
540 | /* get a free HDLC buffer */ | 540 | /* get a free HDLC buffer */ |
@@ -550,7 +550,7 @@ static unsigned int n_hdlc_tty_receive(struct tty_struct *tty, | |||
550 | if (debuglevel >= DEBUG_LEVEL_INFO) | 550 | if (debuglevel >= DEBUG_LEVEL_INFO) |
551 | printk("%s(%d) no more rx buffers, data discarded\n", | 551 | printk("%s(%d) no more rx buffers, data discarded\n", |
552 | __FILE__,__LINE__); | 552 | __FILE__,__LINE__); |
553 | return -EINVAL; | 553 | return; |
554 | } | 554 | } |
555 | 555 | ||
556 | /* copy received data to HDLC buffer */ | 556 | /* copy received data to HDLC buffer */ |
@@ -565,8 +565,6 @@ static unsigned int n_hdlc_tty_receive(struct tty_struct *tty, | |||
565 | if (n_hdlc->tty->fasync != NULL) | 565 | if (n_hdlc->tty->fasync != NULL) |
566 | kill_fasync (&n_hdlc->tty->fasync, SIGIO, POLL_IN); | 566 | kill_fasync (&n_hdlc->tty->fasync, SIGIO, POLL_IN); |
567 | 567 | ||
568 | return count; | ||
569 | |||
570 | } /* end of n_hdlc_tty_receive() */ | 568 | } /* end of n_hdlc_tty_receive() */ |
571 | 569 | ||
572 | /** | 570 | /** |
diff --git a/drivers/tty/n_r3964.c b/drivers/tty/n_r3964.c index a4bc39c21a43..5c6c31459a2f 100644 --- a/drivers/tty/n_r3964.c +++ b/drivers/tty/n_r3964.c | |||
@@ -139,8 +139,8 @@ static int r3964_ioctl(struct tty_struct *tty, struct file *file, | |||
139 | static void r3964_set_termios(struct tty_struct *tty, struct ktermios *old); | 139 | static void r3964_set_termios(struct tty_struct *tty, struct ktermios *old); |
140 | static unsigned int r3964_poll(struct tty_struct *tty, struct file *file, | 140 | static unsigned int r3964_poll(struct tty_struct *tty, struct file *file, |
141 | struct poll_table_struct *wait); | 141 | struct poll_table_struct *wait); |
142 | static unsigned int r3964_receive_buf(struct tty_struct *tty, | 142 | static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp, |
143 | const unsigned char *cp, char *fp, int count); | 143 | char *fp, int count); |
144 | 144 | ||
145 | static struct tty_ldisc_ops tty_ldisc_N_R3964 = { | 145 | static struct tty_ldisc_ops tty_ldisc_N_R3964 = { |
146 | .owner = THIS_MODULE, | 146 | .owner = THIS_MODULE, |
@@ -1239,8 +1239,8 @@ static unsigned int r3964_poll(struct tty_struct *tty, struct file *file, | |||
1239 | return result; | 1239 | return result; |
1240 | } | 1240 | } |
1241 | 1241 | ||
1242 | static unsigned int r3964_receive_buf(struct tty_struct *tty, | 1242 | static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp, |
1243 | const unsigned char *cp, char *fp, int count) | 1243 | char *fp, int count) |
1244 | { | 1244 | { |
1245 | struct r3964_info *pInfo = tty->disc_data; | 1245 | struct r3964_info *pInfo = tty->disc_data; |
1246 | const unsigned char *p; | 1246 | const unsigned char *p; |
@@ -1257,8 +1257,6 @@ static unsigned int r3964_receive_buf(struct tty_struct *tty, | |||
1257 | } | 1257 | } |
1258 | 1258 | ||
1259 | } | 1259 | } |
1260 | |||
1261 | return count; | ||
1262 | } | 1260 | } |
1263 | 1261 | ||
1264 | MODULE_LICENSE("GPL"); | 1262 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 95d0a9c2dd13..0ad32888091c 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c | |||
@@ -81,6 +81,38 @@ static inline int tty_put_user(struct tty_struct *tty, unsigned char x, | |||
81 | return put_user(x, ptr); | 81 | return put_user(x, ptr); |
82 | } | 82 | } |
83 | 83 | ||
84 | /** | ||
85 | * n_tty_set__room - receive space | ||
86 | * @tty: terminal | ||
87 | * | ||
88 | * Called by the driver to find out how much data it is | ||
89 | * permitted to feed to the line discipline without any being lost | ||
90 | * and thus to manage flow control. Not serialized. Answers for the | ||
91 | * "instant". | ||
92 | */ | ||
93 | |||
94 | static void n_tty_set_room(struct tty_struct *tty) | ||
95 | { | ||
96 | /* tty->read_cnt is not read locked ? */ | ||
97 | int left = N_TTY_BUF_SIZE - tty->read_cnt - 1; | ||
98 | int old_left; | ||
99 | |||
100 | /* | ||
101 | * If we are doing input canonicalization, and there are no | ||
102 | * pending newlines, let characters through without limit, so | ||
103 | * that erase characters will be handled. Other excess | ||
104 | * characters will be beeped. | ||
105 | */ | ||
106 | if (left <= 0) | ||
107 | left = tty->icanon && !tty->canon_data; | ||
108 | old_left = tty->receive_room; | ||
109 | tty->receive_room = left; | ||
110 | |||
111 | /* Did this open up the receive buffer? We may need to flip */ | ||
112 | if (left && !old_left) | ||
113 | schedule_work(&tty->buf.work); | ||
114 | } | ||
115 | |||
84 | static void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty) | 116 | static void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty) |
85 | { | 117 | { |
86 | if (tty->read_cnt < N_TTY_BUF_SIZE) { | 118 | if (tty->read_cnt < N_TTY_BUF_SIZE) { |
@@ -152,6 +184,7 @@ static void reset_buffer_flags(struct tty_struct *tty) | |||
152 | 184 | ||
153 | tty->canon_head = tty->canon_data = tty->erasing = 0; | 185 | tty->canon_head = tty->canon_data = tty->erasing = 0; |
154 | memset(&tty->read_flags, 0, sizeof tty->read_flags); | 186 | memset(&tty->read_flags, 0, sizeof tty->read_flags); |
187 | n_tty_set_room(tty); | ||
155 | check_unthrottle(tty); | 188 | check_unthrottle(tty); |
156 | } | 189 | } |
157 | 190 | ||
@@ -1327,19 +1360,17 @@ static void n_tty_write_wakeup(struct tty_struct *tty) | |||
1327 | * calls one at a time and in order (or using flush_to_ldisc) | 1360 | * calls one at a time and in order (or using flush_to_ldisc) |
1328 | */ | 1361 | */ |
1329 | 1362 | ||
1330 | static unsigned int n_tty_receive_buf(struct tty_struct *tty, | 1363 | static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, |
1331 | const unsigned char *cp, char *fp, int count) | 1364 | char *fp, int count) |
1332 | { | 1365 | { |
1333 | const unsigned char *p; | 1366 | const unsigned char *p; |
1334 | char *f, flags = TTY_NORMAL; | 1367 | char *f, flags = TTY_NORMAL; |
1335 | int i; | 1368 | int i; |
1336 | char buf[64]; | 1369 | char buf[64]; |
1337 | unsigned long cpuflags; | 1370 | unsigned long cpuflags; |
1338 | int left; | ||
1339 | int ret = 0; | ||
1340 | 1371 | ||
1341 | if (!tty->read_buf) | 1372 | if (!tty->read_buf) |
1342 | return 0; | 1373 | return; |
1343 | 1374 | ||
1344 | if (tty->real_raw) { | 1375 | if (tty->real_raw) { |
1345 | spin_lock_irqsave(&tty->read_lock, cpuflags); | 1376 | spin_lock_irqsave(&tty->read_lock, cpuflags); |
@@ -1349,7 +1380,6 @@ static unsigned int n_tty_receive_buf(struct tty_struct *tty, | |||
1349 | memcpy(tty->read_buf + tty->read_head, cp, i); | 1380 | memcpy(tty->read_buf + tty->read_head, cp, i); |
1350 | tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1); | 1381 | tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1); |
1351 | tty->read_cnt += i; | 1382 | tty->read_cnt += i; |
1352 | ret += i; | ||
1353 | cp += i; | 1383 | cp += i; |
1354 | count -= i; | 1384 | count -= i; |
1355 | 1385 | ||
@@ -1359,10 +1389,8 @@ static unsigned int n_tty_receive_buf(struct tty_struct *tty, | |||
1359 | memcpy(tty->read_buf + tty->read_head, cp, i); | 1389 | memcpy(tty->read_buf + tty->read_head, cp, i); |
1360 | tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1); | 1390 | tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1); |
1361 | tty->read_cnt += i; | 1391 | tty->read_cnt += i; |
1362 | ret += i; | ||
1363 | spin_unlock_irqrestore(&tty->read_lock, cpuflags); | 1392 | spin_unlock_irqrestore(&tty->read_lock, cpuflags); |
1364 | } else { | 1393 | } else { |
1365 | ret = count; | ||
1366 | for (i = count, p = cp, f = fp; i; i--, p++) { | 1394 | for (i = count, p = cp, f = fp; i; i--, p++) { |
1367 | if (f) | 1395 | if (f) |
1368 | flags = *f++; | 1396 | flags = *f++; |
@@ -1390,6 +1418,8 @@ static unsigned int n_tty_receive_buf(struct tty_struct *tty, | |||
1390 | tty->ops->flush_chars(tty); | 1418 | tty->ops->flush_chars(tty); |
1391 | } | 1419 | } |
1392 | 1420 | ||
1421 | n_tty_set_room(tty); | ||
1422 | |||
1393 | if ((!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) || | 1423 | if ((!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) || |
1394 | L_EXTPROC(tty)) { | 1424 | L_EXTPROC(tty)) { |
1395 | kill_fasync(&tty->fasync, SIGIO, POLL_IN); | 1425 | kill_fasync(&tty->fasync, SIGIO, POLL_IN); |
@@ -1402,12 +1432,8 @@ static unsigned int n_tty_receive_buf(struct tty_struct *tty, | |||
1402 | * mode. We don't want to throttle the driver if we're in | 1432 | * mode. We don't want to throttle the driver if we're in |
1403 | * canonical mode and don't have a newline yet! | 1433 | * canonical mode and don't have a newline yet! |
1404 | */ | 1434 | */ |
1405 | left = N_TTY_BUF_SIZE - tty->read_cnt - 1; | 1435 | if (tty->receive_room < TTY_THRESHOLD_THROTTLE) |
1406 | |||
1407 | if (left < TTY_THRESHOLD_THROTTLE) | ||
1408 | tty_throttle(tty); | 1436 | tty_throttle(tty); |
1409 | |||
1410 | return ret; | ||
1411 | } | 1437 | } |
1412 | 1438 | ||
1413 | int is_ignored(int sig) | 1439 | int is_ignored(int sig) |
@@ -1451,6 +1477,7 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) | |||
1451 | if (test_bit(TTY_HW_COOK_IN, &tty->flags)) { | 1477 | if (test_bit(TTY_HW_COOK_IN, &tty->flags)) { |
1452 | tty->raw = 1; | 1478 | tty->raw = 1; |
1453 | tty->real_raw = 1; | 1479 | tty->real_raw = 1; |
1480 | n_tty_set_room(tty); | ||
1454 | return; | 1481 | return; |
1455 | } | 1482 | } |
1456 | if (I_ISTRIP(tty) || I_IUCLC(tty) || I_IGNCR(tty) || | 1483 | if (I_ISTRIP(tty) || I_IUCLC(tty) || I_IGNCR(tty) || |
@@ -1503,6 +1530,7 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) | |||
1503 | else | 1530 | else |
1504 | tty->real_raw = 0; | 1531 | tty->real_raw = 0; |
1505 | } | 1532 | } |
1533 | n_tty_set_room(tty); | ||
1506 | /* The termios change make the tty ready for I/O */ | 1534 | /* The termios change make the tty ready for I/O */ |
1507 | wake_up_interruptible(&tty->write_wait); | 1535 | wake_up_interruptible(&tty->write_wait); |
1508 | wake_up_interruptible(&tty->read_wait); | 1536 | wake_up_interruptible(&tty->read_wait); |
@@ -1784,6 +1812,8 @@ do_it_again: | |||
1784 | retval = -ERESTARTSYS; | 1812 | retval = -ERESTARTSYS; |
1785 | break; | 1813 | break; |
1786 | } | 1814 | } |
1815 | /* FIXME: does n_tty_set_room need locking ? */ | ||
1816 | n_tty_set_room(tty); | ||
1787 | timeout = schedule_timeout(timeout); | 1817 | timeout = schedule_timeout(timeout); |
1788 | continue; | 1818 | continue; |
1789 | } | 1819 | } |
@@ -1855,8 +1885,10 @@ do_it_again: | |||
1855 | * longer than TTY_THRESHOLD_UNTHROTTLE in canonical mode, | 1885 | * longer than TTY_THRESHOLD_UNTHROTTLE in canonical mode, |
1856 | * we won't get any more characters. | 1886 | * we won't get any more characters. |
1857 | */ | 1887 | */ |
1858 | if (n_tty_chars_in_buffer(tty) <= TTY_THRESHOLD_UNTHROTTLE) | 1888 | if (n_tty_chars_in_buffer(tty) <= TTY_THRESHOLD_UNTHROTTLE) { |
1889 | n_tty_set_room(tty); | ||
1859 | check_unthrottle(tty); | 1890 | check_unthrottle(tty); |
1891 | } | ||
1860 | 1892 | ||
1861 | if (b - buf >= minimum) | 1893 | if (b - buf >= minimum) |
1862 | break; | 1894 | break; |
@@ -1878,6 +1910,7 @@ do_it_again: | |||
1878 | } else if (test_and_clear_bit(TTY_PUSH, &tty->flags)) | 1910 | } else if (test_and_clear_bit(TTY_PUSH, &tty->flags)) |
1879 | goto do_it_again; | 1911 | goto do_it_again; |
1880 | 1912 | ||
1913 | n_tty_set_room(tty); | ||
1881 | return retval; | 1914 | return retval; |
1882 | } | 1915 | } |
1883 | 1916 | ||
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 46de2e075dac..f1a7918d71aa 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c | |||
@@ -416,7 +416,6 @@ static void flush_to_ldisc(struct work_struct *work) | |||
416 | struct tty_buffer *head, *tail = tty->buf.tail; | 416 | struct tty_buffer *head, *tail = tty->buf.tail; |
417 | int seen_tail = 0; | 417 | int seen_tail = 0; |
418 | while ((head = tty->buf.head) != NULL) { | 418 | while ((head = tty->buf.head) != NULL) { |
419 | int copied; | ||
420 | int count; | 419 | int count; |
421 | char *char_buf; | 420 | char *char_buf; |
422 | unsigned char *flag_buf; | 421 | unsigned char *flag_buf; |
@@ -443,19 +442,17 @@ static void flush_to_ldisc(struct work_struct *work) | |||
443 | line discipline as we want to empty the queue */ | 442 | line discipline as we want to empty the queue */ |
444 | if (test_bit(TTY_FLUSHPENDING, &tty->flags)) | 443 | if (test_bit(TTY_FLUSHPENDING, &tty->flags)) |
445 | break; | 444 | break; |
445 | if (!tty->receive_room || seen_tail) | ||
446 | break; | ||
447 | if (count > tty->receive_room) | ||
448 | count = tty->receive_room; | ||
446 | char_buf = head->char_buf_ptr + head->read; | 449 | char_buf = head->char_buf_ptr + head->read; |
447 | flag_buf = head->flag_buf_ptr + head->read; | 450 | flag_buf = head->flag_buf_ptr + head->read; |
451 | head->read += count; | ||
448 | spin_unlock_irqrestore(&tty->buf.lock, flags); | 452 | spin_unlock_irqrestore(&tty->buf.lock, flags); |
449 | copied = disc->ops->receive_buf(tty, char_buf, | 453 | disc->ops->receive_buf(tty, char_buf, |
450 | flag_buf, count); | 454 | flag_buf, count); |
451 | spin_lock_irqsave(&tty->buf.lock, flags); | 455 | spin_lock_irqsave(&tty->buf.lock, flags); |
452 | |||
453 | head->read += copied; | ||
454 | |||
455 | if (copied == 0 || seen_tail) { | ||
456 | schedule_work(&tty->buf.work); | ||
457 | break; | ||
458 | } | ||
459 | } | 456 | } |
460 | clear_bit(TTY_FLUSHING, &tty->flags); | 457 | clear_bit(TTY_FLUSHING, &tty->flags); |
461 | } | 458 | } |
diff --git a/drivers/tty/vt/selection.c b/drivers/tty/vt/selection.c index 67b1d0d7c8ac..fb864e7fcd13 100644 --- a/drivers/tty/vt/selection.c +++ b/drivers/tty/vt/selection.c | |||
@@ -332,7 +332,8 @@ int paste_selection(struct tty_struct *tty) | |||
332 | continue; | 332 | continue; |
333 | } | 333 | } |
334 | count = sel_buffer_lth - pasted; | 334 | count = sel_buffer_lth - pasted; |
335 | count = tty->ldisc->ops->receive_buf(tty, sel_buffer + pasted, | 335 | count = min(count, tty->receive_room); |
336 | tty->ldisc->ops->receive_buf(tty, sel_buffer + pasted, | ||
336 | NULL, count); | 337 | NULL, count); |
337 | pasted += count; | 338 | pasted += count; |
338 | } | 339 | } |
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 660b80a75cac..1102ce65a3a9 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c | |||
@@ -348,11 +348,50 @@ static int ehci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) | |||
348 | return rc; | 348 | return rc; |
349 | } | 349 | } |
350 | 350 | ||
351 | static bool usb_is_intel_switchable_ehci(struct pci_dev *pdev) | ||
352 | { | ||
353 | return pdev->class == PCI_CLASS_SERIAL_USB_EHCI && | ||
354 | pdev->vendor == PCI_VENDOR_ID_INTEL && | ||
355 | pdev->device == 0x1E26; | ||
356 | } | ||
357 | |||
358 | static void ehci_enable_xhci_companion(void) | ||
359 | { | ||
360 | struct pci_dev *companion = NULL; | ||
361 | |||
362 | /* The xHCI and EHCI controllers are not on the same PCI slot */ | ||
363 | for_each_pci_dev(companion) { | ||
364 | if (!usb_is_intel_switchable_xhci(companion)) | ||
365 | continue; | ||
366 | usb_enable_xhci_ports(companion); | ||
367 | return; | ||
368 | } | ||
369 | } | ||
370 | |||
351 | static int ehci_pci_resume(struct usb_hcd *hcd, bool hibernated) | 371 | static int ehci_pci_resume(struct usb_hcd *hcd, bool hibernated) |
352 | { | 372 | { |
353 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | 373 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); |
354 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); | 374 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); |
355 | 375 | ||
376 | /* The BIOS on systems with the Intel Panther Point chipset may or may | ||
377 | * not support xHCI natively. That means that during system resume, it | ||
378 | * may switch the ports back to EHCI so that users can use their | ||
379 | * keyboard to select a kernel from GRUB after resume from hibernate. | ||
380 | * | ||
381 | * The BIOS is supposed to remember whether the OS had xHCI ports | ||
382 | * enabled before resume, and switch the ports back to xHCI when the | ||
383 | * BIOS/OS semaphore is written, but we all know we can't trust BIOS | ||
384 | * writers. | ||
385 | * | ||
386 | * Unconditionally switch the ports back to xHCI after a system resume. | ||
387 | * We can't tell whether the EHCI or xHCI controller will be resumed | ||
388 | * first, so we have to do the port switchover in both drivers. Writing | ||
389 | * a '1' to the port switchover registers should have no effect if the | ||
390 | * port was already switched over. | ||
391 | */ | ||
392 | if (usb_is_intel_switchable_ehci(pdev)) | ||
393 | ehci_enable_xhci_companion(); | ||
394 | |||
356 | // maybe restore FLADJ | 395 | // maybe restore FLADJ |
357 | 396 | ||
358 | if (time_before(jiffies, ehci->next_statechange)) | 397 | if (time_before(jiffies, ehci->next_statechange)) |
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index f16c59d5f487..fd930618c28f 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c | |||
@@ -69,6 +69,9 @@ | |||
69 | #define NB_PIF0_PWRDOWN_0 0x01100012 | 69 | #define NB_PIF0_PWRDOWN_0 0x01100012 |
70 | #define NB_PIF0_PWRDOWN_1 0x01100013 | 70 | #define NB_PIF0_PWRDOWN_1 0x01100013 |
71 | 71 | ||
72 | #define USB_INTEL_XUSB2PR 0xD0 | ||
73 | #define USB_INTEL_USB3_PSSEN 0xD8 | ||
74 | |||
72 | static struct amd_chipset_info { | 75 | static struct amd_chipset_info { |
73 | struct pci_dev *nb_dev; | 76 | struct pci_dev *nb_dev; |
74 | struct pci_dev *smbus_dev; | 77 | struct pci_dev *smbus_dev; |
@@ -673,6 +676,64 @@ static int handshake(void __iomem *ptr, u32 mask, u32 done, | |||
673 | return -ETIMEDOUT; | 676 | return -ETIMEDOUT; |
674 | } | 677 | } |
675 | 678 | ||
679 | bool usb_is_intel_switchable_xhci(struct pci_dev *pdev) | ||
680 | { | ||
681 | return pdev->class == PCI_CLASS_SERIAL_USB_XHCI && | ||
682 | pdev->vendor == PCI_VENDOR_ID_INTEL && | ||
683 | pdev->device == PCI_DEVICE_ID_INTEL_PANTHERPOINT_XHCI; | ||
684 | } | ||
685 | EXPORT_SYMBOL_GPL(usb_is_intel_switchable_xhci); | ||
686 | |||
687 | /* | ||
688 | * Intel's Panther Point chipset has two host controllers (EHCI and xHCI) that | ||
689 | * share some number of ports. These ports can be switched between either | ||
690 | * controller. Not all of the ports under the EHCI host controller may be | ||
691 | * switchable. | ||
692 | * | ||
693 | * The ports should be switched over to xHCI before PCI probes for any device | ||
694 | * start. This avoids active devices under EHCI being disconnected during the | ||
695 | * port switchover, which could cause loss of data on USB storage devices, or | ||
696 | * failed boot when the root file system is on a USB mass storage device and is | ||
697 | * enumerated under EHCI first. | ||
698 | * | ||
699 | * We write into the xHC's PCI configuration space in some Intel-specific | ||
700 | * registers to switch the ports over. The USB 3.0 terminations and the USB | ||
701 | * 2.0 data wires are switched separately. We want to enable the SuperSpeed | ||
702 | * terminations before switching the USB 2.0 wires over, so that USB 3.0 | ||
703 | * devices connect at SuperSpeed, rather than at USB 2.0 speeds. | ||
704 | */ | ||
705 | void usb_enable_xhci_ports(struct pci_dev *xhci_pdev) | ||
706 | { | ||
707 | u32 ports_available; | ||
708 | |||
709 | ports_available = 0xffffffff; | ||
710 | /* Write USB3_PSSEN, the USB 3.0 Port SuperSpeed Enable | ||
711 | * Register, to turn on SuperSpeed terminations for all | ||
712 | * available ports. | ||
713 | */ | ||
714 | pci_write_config_dword(xhci_pdev, USB_INTEL_USB3_PSSEN, | ||
715 | cpu_to_le32(ports_available)); | ||
716 | |||
717 | pci_read_config_dword(xhci_pdev, USB_INTEL_USB3_PSSEN, | ||
718 | &ports_available); | ||
719 | dev_dbg(&xhci_pdev->dev, "USB 3.0 ports that are now enabled " | ||
720 | "under xHCI: 0x%x\n", ports_available); | ||
721 | |||
722 | ports_available = 0xffffffff; | ||
723 | /* Write XUSB2PR, the xHC USB 2.0 Port Routing Register, to | ||
724 | * switch the USB 2.0 power and data lines over to the xHCI | ||
725 | * host. | ||
726 | */ | ||
727 | pci_write_config_dword(xhci_pdev, USB_INTEL_XUSB2PR, | ||
728 | cpu_to_le32(ports_available)); | ||
729 | |||
730 | pci_read_config_dword(xhci_pdev, USB_INTEL_XUSB2PR, | ||
731 | &ports_available); | ||
732 | dev_dbg(&xhci_pdev->dev, "USB 2.0 ports that are now switched over " | ||
733 | "to xHCI: 0x%x\n", ports_available); | ||
734 | } | ||
735 | EXPORT_SYMBOL_GPL(usb_enable_xhci_ports); | ||
736 | |||
676 | /** | 737 | /** |
677 | * PCI Quirks for xHCI. | 738 | * PCI Quirks for xHCI. |
678 | * | 739 | * |
@@ -732,6 +793,8 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev) | |||
732 | writel(XHCI_LEGACY_DISABLE_SMI, | 793 | writel(XHCI_LEGACY_DISABLE_SMI, |
733 | base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET); | 794 | base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET); |
734 | 795 | ||
796 | if (usb_is_intel_switchable_xhci(pdev)) | ||
797 | usb_enable_xhci_ports(pdev); | ||
735 | hc_init: | 798 | hc_init: |
736 | op_reg_base = base + XHCI_HC_LENGTH(readl(base)); | 799 | op_reg_base = base + XHCI_HC_LENGTH(readl(base)); |
737 | 800 | ||
diff --git a/drivers/usb/host/pci-quirks.h b/drivers/usb/host/pci-quirks.h index 6ae9f78e9938..b1002a8ef96f 100644 --- a/drivers/usb/host/pci-quirks.h +++ b/drivers/usb/host/pci-quirks.h | |||
@@ -8,6 +8,8 @@ int usb_amd_find_chipset_info(void); | |||
8 | void usb_amd_dev_put(void); | 8 | void usb_amd_dev_put(void); |
9 | void usb_amd_quirk_pll_disable(void); | 9 | void usb_amd_quirk_pll_disable(void); |
10 | void usb_amd_quirk_pll_enable(void); | 10 | void usb_amd_quirk_pll_enable(void); |
11 | bool usb_is_intel_switchable_xhci(struct pci_dev *pdev); | ||
12 | void usb_enable_xhci_ports(struct pci_dev *xhci_pdev); | ||
11 | #else | 13 | #else |
12 | static inline void usb_amd_quirk_pll_disable(void) {} | 14 | static inline void usb_amd_quirk_pll_disable(void) {} |
13 | static inline void usb_amd_quirk_pll_enable(void) {} | 15 | static inline void usb_amd_quirk_pll_enable(void) {} |
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index cbc4d491e626..c408e9f6a707 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c | |||
@@ -118,6 +118,12 @@ static int xhci_pci_setup(struct usb_hcd *hcd) | |||
118 | /* AMD PLL quirk */ | 118 | /* AMD PLL quirk */ |
119 | if (pdev->vendor == PCI_VENDOR_ID_AMD && usb_amd_find_chipset_info()) | 119 | if (pdev->vendor == PCI_VENDOR_ID_AMD && usb_amd_find_chipset_info()) |
120 | xhci->quirks |= XHCI_AMD_PLL_FIX; | 120 | xhci->quirks |= XHCI_AMD_PLL_FIX; |
121 | if (pdev->vendor == PCI_VENDOR_ID_INTEL && | ||
122 | pdev->device == PCI_DEVICE_ID_INTEL_PANTHERPOINT_XHCI) { | ||
123 | xhci->quirks |= XHCI_SPURIOUS_SUCCESS; | ||
124 | xhci->quirks |= XHCI_EP_LIMIT_QUIRK; | ||
125 | xhci->limit_active_eps = 64; | ||
126 | } | ||
121 | 127 | ||
122 | /* Make sure the HC is halted. */ | 128 | /* Make sure the HC is halted. */ |
123 | retval = xhci_halt(xhci); | 129 | retval = xhci_halt(xhci); |
@@ -242,8 +248,28 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) | |||
242 | static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated) | 248 | static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated) |
243 | { | 249 | { |
244 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 250 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
251 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); | ||
245 | int retval = 0; | 252 | int retval = 0; |
246 | 253 | ||
254 | /* The BIOS on systems with the Intel Panther Point chipset may or may | ||
255 | * not support xHCI natively. That means that during system resume, it | ||
256 | * may switch the ports back to EHCI so that users can use their | ||
257 | * keyboard to select a kernel from GRUB after resume from hibernate. | ||
258 | * | ||
259 | * The BIOS is supposed to remember whether the OS had xHCI ports | ||
260 | * enabled before resume, and switch the ports back to xHCI when the | ||
261 | * BIOS/OS semaphore is written, but we all know we can't trust BIOS | ||
262 | * writers. | ||
263 | * | ||
264 | * Unconditionally switch the ports back to xHCI after a system resume. | ||
265 | * We can't tell whether the EHCI or xHCI controller will be resumed | ||
266 | * first, so we have to do the port switchover in both drivers. Writing | ||
267 | * a '1' to the port switchover registers should have no effect if the | ||
268 | * port was already switched over. | ||
269 | */ | ||
270 | if (usb_is_intel_switchable_xhci(pdev)) | ||
271 | usb_enable_xhci_ports(pdev); | ||
272 | |||
247 | retval = xhci_resume(xhci, hibernated); | 273 | retval = xhci_resume(xhci, hibernated); |
248 | return retval; | 274 | return retval; |
249 | } | 275 | } |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 237a765f8d18..cc1485bfed38 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -167,12 +167,6 @@ static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer | |||
167 | next = ring->dequeue; | 167 | next = ring->dequeue; |
168 | } | 168 | } |
169 | addr = (unsigned long long) xhci_trb_virt_to_dma(ring->deq_seg, ring->dequeue); | 169 | addr = (unsigned long long) xhci_trb_virt_to_dma(ring->deq_seg, ring->dequeue); |
170 | if (ring == xhci->event_ring) | ||
171 | xhci_dbg(xhci, "Event ring deq = 0x%llx (DMA)\n", addr); | ||
172 | else if (ring == xhci->cmd_ring) | ||
173 | xhci_dbg(xhci, "Command ring deq = 0x%llx (DMA)\n", addr); | ||
174 | else | ||
175 | xhci_dbg(xhci, "Ring deq = 0x%llx (DMA)\n", addr); | ||
176 | } | 170 | } |
177 | 171 | ||
178 | /* | 172 | /* |
@@ -248,12 +242,6 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, | |||
248 | next = ring->enqueue; | 242 | next = ring->enqueue; |
249 | } | 243 | } |
250 | addr = (unsigned long long) xhci_trb_virt_to_dma(ring->enq_seg, ring->enqueue); | 244 | addr = (unsigned long long) xhci_trb_virt_to_dma(ring->enq_seg, ring->enqueue); |
251 | if (ring == xhci->event_ring) | ||
252 | xhci_dbg(xhci, "Event ring enq = 0x%llx (DMA)\n", addr); | ||
253 | else if (ring == xhci->cmd_ring) | ||
254 | xhci_dbg(xhci, "Command ring enq = 0x%llx (DMA)\n", addr); | ||
255 | else | ||
256 | xhci_dbg(xhci, "Ring enq = 0x%llx (DMA)\n", addr); | ||
257 | } | 245 | } |
258 | 246 | ||
259 | /* | 247 | /* |
@@ -636,13 +624,11 @@ static void xhci_giveback_urb_in_irq(struct xhci_hcd *xhci, | |||
636 | } | 624 | } |
637 | } | 625 | } |
638 | usb_hcd_unlink_urb_from_ep(hcd, urb); | 626 | usb_hcd_unlink_urb_from_ep(hcd, urb); |
639 | xhci_dbg(xhci, "Giveback %s URB %p\n", adjective, urb); | ||
640 | 627 | ||
641 | spin_unlock(&xhci->lock); | 628 | spin_unlock(&xhci->lock); |
642 | usb_hcd_giveback_urb(hcd, urb, status); | 629 | usb_hcd_giveback_urb(hcd, urb, status); |
643 | xhci_urb_free_priv(xhci, urb_priv); | 630 | xhci_urb_free_priv(xhci, urb_priv); |
644 | spin_lock(&xhci->lock); | 631 | spin_lock(&xhci->lock); |
645 | xhci_dbg(xhci, "%s URB given back\n", adjective); | ||
646 | } | 632 | } |
647 | } | 633 | } |
648 | 634 | ||
@@ -692,6 +678,8 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci, | |||
692 | 678 | ||
693 | if (list_empty(&ep->cancelled_td_list)) { | 679 | if (list_empty(&ep->cancelled_td_list)) { |
694 | xhci_stop_watchdog_timer_in_irq(xhci, ep); | 680 | xhci_stop_watchdog_timer_in_irq(xhci, ep); |
681 | ep->stopped_td = NULL; | ||
682 | ep->stopped_trb = NULL; | ||
695 | ring_doorbell_for_active_rings(xhci, slot_id, ep_index); | 683 | ring_doorbell_for_active_rings(xhci, slot_id, ep_index); |
696 | return; | 684 | return; |
697 | } | 685 | } |
@@ -1093,8 +1081,13 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, | |||
1093 | complete(&xhci->addr_dev); | 1081 | complete(&xhci->addr_dev); |
1094 | break; | 1082 | break; |
1095 | case TRB_TYPE(TRB_DISABLE_SLOT): | 1083 | case TRB_TYPE(TRB_DISABLE_SLOT): |
1096 | if (xhci->devs[slot_id]) | 1084 | if (xhci->devs[slot_id]) { |
1085 | if (xhci->quirks & XHCI_EP_LIMIT_QUIRK) | ||
1086 | /* Delete default control endpoint resources */ | ||
1087 | xhci_free_device_endpoint_resources(xhci, | ||
1088 | xhci->devs[slot_id], true); | ||
1097 | xhci_free_virt_device(xhci, slot_id); | 1089 | xhci_free_virt_device(xhci, slot_id); |
1090 | } | ||
1098 | break; | 1091 | break; |
1099 | case TRB_TYPE(TRB_CONFIG_EP): | 1092 | case TRB_TYPE(TRB_CONFIG_EP): |
1100 | virt_dev = xhci->devs[slot_id]; | 1093 | virt_dev = xhci->devs[slot_id]; |
@@ -1630,7 +1623,6 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, | |||
1630 | "without IOC set??\n"); | 1623 | "without IOC set??\n"); |
1631 | *status = -ESHUTDOWN; | 1624 | *status = -ESHUTDOWN; |
1632 | } else { | 1625 | } else { |
1633 | xhci_dbg(xhci, "Successful control transfer!\n"); | ||
1634 | *status = 0; | 1626 | *status = 0; |
1635 | } | 1627 | } |
1636 | break; | 1628 | break; |
@@ -1727,7 +1719,6 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, | |||
1727 | switch (trb_comp_code) { | 1719 | switch (trb_comp_code) { |
1728 | case COMP_SUCCESS: | 1720 | case COMP_SUCCESS: |
1729 | frame->status = 0; | 1721 | frame->status = 0; |
1730 | xhci_dbg(xhci, "Successful isoc transfer!\n"); | ||
1731 | break; | 1722 | break; |
1732 | case COMP_SHORT_TX: | 1723 | case COMP_SHORT_TX: |
1733 | frame->status = td->urb->transfer_flags & URB_SHORT_NOT_OK ? | 1724 | frame->status = td->urb->transfer_flags & URB_SHORT_NOT_OK ? |
@@ -1837,12 +1828,6 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, | |||
1837 | else | 1828 | else |
1838 | *status = 0; | 1829 | *status = 0; |
1839 | } else { | 1830 | } else { |
1840 | if (usb_endpoint_xfer_bulk(&td->urb->ep->desc)) | ||
1841 | xhci_dbg(xhci, "Successful bulk " | ||
1842 | "transfer!\n"); | ||
1843 | else | ||
1844 | xhci_dbg(xhci, "Successful interrupt " | ||
1845 | "transfer!\n"); | ||
1846 | *status = 0; | 1831 | *status = 0; |
1847 | } | 1832 | } |
1848 | break; | 1833 | break; |
@@ -1856,11 +1841,12 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, | |||
1856 | /* Others already handled above */ | 1841 | /* Others already handled above */ |
1857 | break; | 1842 | break; |
1858 | } | 1843 | } |
1859 | xhci_dbg(xhci, "ep %#x - asked for %d bytes, " | 1844 | if (trb_comp_code == COMP_SHORT_TX) |
1860 | "%d bytes untransferred\n", | 1845 | xhci_dbg(xhci, "ep %#x - asked for %d bytes, " |
1861 | td->urb->ep->desc.bEndpointAddress, | 1846 | "%d bytes untransferred\n", |
1862 | td->urb->transfer_buffer_length, | 1847 | td->urb->ep->desc.bEndpointAddress, |
1863 | TRB_LEN(le32_to_cpu(event->transfer_len))); | 1848 | td->urb->transfer_buffer_length, |
1849 | TRB_LEN(le32_to_cpu(event->transfer_len))); | ||
1864 | /* Fast path - was this the last TRB in the TD for this URB? */ | 1850 | /* Fast path - was this the last TRB in the TD for this URB? */ |
1865 | if (event_trb == td->last_trb) { | 1851 | if (event_trb == td->last_trb) { |
1866 | if (TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) { | 1852 | if (TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) { |
@@ -1954,7 +1940,6 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
1954 | 1940 | ||
1955 | /* Endpoint ID is 1 based, our index is zero based */ | 1941 | /* Endpoint ID is 1 based, our index is zero based */ |
1956 | ep_index = TRB_TO_EP_ID(le32_to_cpu(event->flags)) - 1; | 1942 | ep_index = TRB_TO_EP_ID(le32_to_cpu(event->flags)) - 1; |
1957 | xhci_dbg(xhci, "%s - ep index = %d\n", __func__, ep_index); | ||
1958 | ep = &xdev->eps[ep_index]; | 1943 | ep = &xdev->eps[ep_index]; |
1959 | ep_ring = xhci_dma_to_transfer_ring(ep, le64_to_cpu(event->buffer)); | 1944 | ep_ring = xhci_dma_to_transfer_ring(ep, le64_to_cpu(event->buffer)); |
1960 | ep_ctx = xhci_get_ep_ctx(xhci, xdev->out_ctx, ep_index); | 1945 | ep_ctx = xhci_get_ep_ctx(xhci, xdev->out_ctx, ep_index); |
@@ -2081,6 +2066,16 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
2081 | if (!event_seg) { | 2066 | if (!event_seg) { |
2082 | if (!ep->skip || | 2067 | if (!ep->skip || |
2083 | !usb_endpoint_xfer_isoc(&td->urb->ep->desc)) { | 2068 | !usb_endpoint_xfer_isoc(&td->urb->ep->desc)) { |
2069 | /* Some host controllers give a spurious | ||
2070 | * successful event after a short transfer. | ||
2071 | * Ignore it. | ||
2072 | */ | ||
2073 | if ((xhci->quirks & XHCI_SPURIOUS_SUCCESS) && | ||
2074 | ep_ring->last_td_was_short) { | ||
2075 | ep_ring->last_td_was_short = false; | ||
2076 | ret = 0; | ||
2077 | goto cleanup; | ||
2078 | } | ||
2084 | /* HC is busted, give up! */ | 2079 | /* HC is busted, give up! */ |
2085 | xhci_err(xhci, | 2080 | xhci_err(xhci, |
2086 | "ERROR Transfer event TRB DMA ptr not " | 2081 | "ERROR Transfer event TRB DMA ptr not " |
@@ -2091,6 +2086,10 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
2091 | ret = skip_isoc_td(xhci, td, event, ep, &status); | 2086 | ret = skip_isoc_td(xhci, td, event, ep, &status); |
2092 | goto cleanup; | 2087 | goto cleanup; |
2093 | } | 2088 | } |
2089 | if (trb_comp_code == COMP_SHORT_TX) | ||
2090 | ep_ring->last_td_was_short = true; | ||
2091 | else | ||
2092 | ep_ring->last_td_was_short = false; | ||
2094 | 2093 | ||
2095 | if (ep->skip) { | 2094 | if (ep->skip) { |
2096 | xhci_dbg(xhci, "Found td. Clear skip flag.\n"); | 2095 | xhci_dbg(xhci, "Found td. Clear skip flag.\n"); |
@@ -2149,9 +2148,15 @@ cleanup: | |||
2149 | xhci_urb_free_priv(xhci, urb_priv); | 2148 | xhci_urb_free_priv(xhci, urb_priv); |
2150 | 2149 | ||
2151 | usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb); | 2150 | usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb); |
2152 | xhci_dbg(xhci, "Giveback URB %p, len = %d, " | 2151 | if ((urb->actual_length != urb->transfer_buffer_length && |
2153 | "status = %d\n", | 2152 | (urb->transfer_flags & |
2154 | urb, urb->actual_length, status); | 2153 | URB_SHORT_NOT_OK)) || |
2154 | status != 0) | ||
2155 | xhci_dbg(xhci, "Giveback URB %p, len = %d, " | ||
2156 | "expected = %x, status = %d\n", | ||
2157 | urb, urb->actual_length, | ||
2158 | urb->transfer_buffer_length, | ||
2159 | status); | ||
2155 | spin_unlock(&xhci->lock); | 2160 | spin_unlock(&xhci->lock); |
2156 | usb_hcd_giveback_urb(bus_to_hcd(urb->dev->bus), urb, status); | 2161 | usb_hcd_giveback_urb(bus_to_hcd(urb->dev->bus), urb, status); |
2157 | spin_lock(&xhci->lock); | 2162 | spin_lock(&xhci->lock); |
@@ -2180,7 +2185,6 @@ static int xhci_handle_event(struct xhci_hcd *xhci) | |||
2180 | int update_ptrs = 1; | 2185 | int update_ptrs = 1; |
2181 | int ret; | 2186 | int ret; |
2182 | 2187 | ||
2183 | xhci_dbg(xhci, "In %s\n", __func__); | ||
2184 | if (!xhci->event_ring || !xhci->event_ring->dequeue) { | 2188 | if (!xhci->event_ring || !xhci->event_ring->dequeue) { |
2185 | xhci->error_bitmask |= 1 << 1; | 2189 | xhci->error_bitmask |= 1 << 1; |
2186 | return 0; | 2190 | return 0; |
@@ -2193,7 +2197,6 @@ static int xhci_handle_event(struct xhci_hcd *xhci) | |||
2193 | xhci->error_bitmask |= 1 << 2; | 2197 | xhci->error_bitmask |= 1 << 2; |
2194 | return 0; | 2198 | return 0; |
2195 | } | 2199 | } |
2196 | xhci_dbg(xhci, "%s - OS owns TRB\n", __func__); | ||
2197 | 2200 | ||
2198 | /* | 2201 | /* |
2199 | * Barrier between reading the TRB_CYCLE (valid) flag above and any | 2202 | * Barrier between reading the TRB_CYCLE (valid) flag above and any |
@@ -2203,20 +2206,14 @@ static int xhci_handle_event(struct xhci_hcd *xhci) | |||
2203 | /* FIXME: Handle more event types. */ | 2206 | /* FIXME: Handle more event types. */ |
2204 | switch ((le32_to_cpu(event->event_cmd.flags) & TRB_TYPE_BITMASK)) { | 2207 | switch ((le32_to_cpu(event->event_cmd.flags) & TRB_TYPE_BITMASK)) { |
2205 | case TRB_TYPE(TRB_COMPLETION): | 2208 | case TRB_TYPE(TRB_COMPLETION): |
2206 | xhci_dbg(xhci, "%s - calling handle_cmd_completion\n", __func__); | ||
2207 | handle_cmd_completion(xhci, &event->event_cmd); | 2209 | handle_cmd_completion(xhci, &event->event_cmd); |
2208 | xhci_dbg(xhci, "%s - returned from handle_cmd_completion\n", __func__); | ||
2209 | break; | 2210 | break; |
2210 | case TRB_TYPE(TRB_PORT_STATUS): | 2211 | case TRB_TYPE(TRB_PORT_STATUS): |
2211 | xhci_dbg(xhci, "%s - calling handle_port_status\n", __func__); | ||
2212 | handle_port_status(xhci, event); | 2212 | handle_port_status(xhci, event); |
2213 | xhci_dbg(xhci, "%s - returned from handle_port_status\n", __func__); | ||
2214 | update_ptrs = 0; | 2213 | update_ptrs = 0; |
2215 | break; | 2214 | break; |
2216 | case TRB_TYPE(TRB_TRANSFER): | 2215 | case TRB_TYPE(TRB_TRANSFER): |
2217 | xhci_dbg(xhci, "%s - calling handle_tx_event\n", __func__); | ||
2218 | ret = handle_tx_event(xhci, &event->trans_event); | 2216 | ret = handle_tx_event(xhci, &event->trans_event); |
2219 | xhci_dbg(xhci, "%s - returned from handle_tx_event\n", __func__); | ||
2220 | if (ret < 0) | 2217 | if (ret < 0) |
2221 | xhci->error_bitmask |= 1 << 9; | 2218 | xhci->error_bitmask |= 1 << 9; |
2222 | else | 2219 | else |
@@ -2273,16 +2270,6 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd) | |||
2273 | spin_unlock(&xhci->lock); | 2270 | spin_unlock(&xhci->lock); |
2274 | return IRQ_NONE; | 2271 | return IRQ_NONE; |
2275 | } | 2272 | } |
2276 | xhci_dbg(xhci, "op reg status = %08x\n", status); | ||
2277 | xhci_dbg(xhci, "Event ring dequeue ptr:\n"); | ||
2278 | xhci_dbg(xhci, "@%llx %08x %08x %08x %08x\n", | ||
2279 | (unsigned long long) | ||
2280 | xhci_trb_virt_to_dma(xhci->event_ring->deq_seg, trb), | ||
2281 | lower_32_bits(le64_to_cpu(trb->link.segment_ptr)), | ||
2282 | upper_32_bits(le64_to_cpu(trb->link.segment_ptr)), | ||
2283 | (unsigned int) le32_to_cpu(trb->link.intr_target), | ||
2284 | (unsigned int) le32_to_cpu(trb->link.control)); | ||
2285 | |||
2286 | if (status & STS_FATAL) { | 2273 | if (status & STS_FATAL) { |
2287 | xhci_warn(xhci, "WARNING: Host System Error\n"); | 2274 | xhci_warn(xhci, "WARNING: Host System Error\n"); |
2288 | xhci_halt(xhci); | 2275 | xhci_halt(xhci); |
@@ -2397,7 +2384,6 @@ static int prepare_ring(struct xhci_hcd *xhci, struct xhci_ring *ep_ring, | |||
2397 | u32 ep_state, unsigned int num_trbs, gfp_t mem_flags) | 2384 | u32 ep_state, unsigned int num_trbs, gfp_t mem_flags) |
2398 | { | 2385 | { |
2399 | /* Make sure the endpoint has been added to xHC schedule */ | 2386 | /* Make sure the endpoint has been added to xHC schedule */ |
2400 | xhci_dbg(xhci, "Endpoint state = 0x%x\n", ep_state); | ||
2401 | switch (ep_state) { | 2387 | switch (ep_state) { |
2402 | case EP_STATE_DISABLED: | 2388 | case EP_STATE_DISABLED: |
2403 | /* | 2389 | /* |
@@ -2434,7 +2420,6 @@ static int prepare_ring(struct xhci_hcd *xhci, struct xhci_ring *ep_ring, | |||
2434 | struct xhci_ring *ring = ep_ring; | 2420 | struct xhci_ring *ring = ep_ring; |
2435 | union xhci_trb *next; | 2421 | union xhci_trb *next; |
2436 | 2422 | ||
2437 | xhci_dbg(xhci, "prepare_ring: pointing to link trb\n"); | ||
2438 | next = ring->enqueue; | 2423 | next = ring->enqueue; |
2439 | 2424 | ||
2440 | while (last_trb(xhci, ring, ring->enq_seg, next)) { | 2425 | while (last_trb(xhci, ring, ring->enq_seg, next)) { |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 8f2a56ece44f..d9660eb97eb9 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -1314,8 +1314,10 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | |||
1314 | if (ret <= 0) | 1314 | if (ret <= 0) |
1315 | return ret; | 1315 | return ret; |
1316 | xhci = hcd_to_xhci(hcd); | 1316 | xhci = hcd_to_xhci(hcd); |
1317 | xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); | 1317 | if (xhci->xhc_state & XHCI_STATE_DYING) |
1318 | return -ENODEV; | ||
1318 | 1319 | ||
1320 | xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); | ||
1319 | drop_flag = xhci_get_endpoint_flag(&ep->desc); | 1321 | drop_flag = xhci_get_endpoint_flag(&ep->desc); |
1320 | if (drop_flag == SLOT_FLAG || drop_flag == EP0_FLAG) { | 1322 | if (drop_flag == SLOT_FLAG || drop_flag == EP0_FLAG) { |
1321 | xhci_dbg(xhci, "xHCI %s - can't drop slot or ep 0 %#x\n", | 1323 | xhci_dbg(xhci, "xHCI %s - can't drop slot or ep 0 %#x\n", |
@@ -1401,6 +1403,8 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | |||
1401 | return ret; | 1403 | return ret; |
1402 | } | 1404 | } |
1403 | xhci = hcd_to_xhci(hcd); | 1405 | xhci = hcd_to_xhci(hcd); |
1406 | if (xhci->xhc_state & XHCI_STATE_DYING) | ||
1407 | return -ENODEV; | ||
1404 | 1408 | ||
1405 | added_ctxs = xhci_get_endpoint_flag(&ep->desc); | 1409 | added_ctxs = xhci_get_endpoint_flag(&ep->desc); |
1406 | last_ctx = xhci_last_valid_endpoint(added_ctxs); | 1410 | last_ctx = xhci_last_valid_endpoint(added_ctxs); |
@@ -1578,6 +1582,113 @@ static int xhci_evaluate_context_result(struct xhci_hcd *xhci, | |||
1578 | return ret; | 1582 | return ret; |
1579 | } | 1583 | } |
1580 | 1584 | ||
1585 | static u32 xhci_count_num_new_endpoints(struct xhci_hcd *xhci, | ||
1586 | struct xhci_container_ctx *in_ctx) | ||
1587 | { | ||
1588 | struct xhci_input_control_ctx *ctrl_ctx; | ||
1589 | u32 valid_add_flags; | ||
1590 | u32 valid_drop_flags; | ||
1591 | |||
1592 | ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); | ||
1593 | /* Ignore the slot flag (bit 0), and the default control endpoint flag | ||
1594 | * (bit 1). The default control endpoint is added during the Address | ||
1595 | * Device command and is never removed until the slot is disabled. | ||
1596 | */ | ||
1597 | valid_add_flags = ctrl_ctx->add_flags >> 2; | ||
1598 | valid_drop_flags = ctrl_ctx->drop_flags >> 2; | ||
1599 | |||
1600 | /* Use hweight32 to count the number of ones in the add flags, or | ||
1601 | * number of endpoints added. Don't count endpoints that are changed | ||
1602 | * (both added and dropped). | ||
1603 | */ | ||
1604 | return hweight32(valid_add_flags) - | ||
1605 | hweight32(valid_add_flags & valid_drop_flags); | ||
1606 | } | ||
1607 | |||
1608 | static unsigned int xhci_count_num_dropped_endpoints(struct xhci_hcd *xhci, | ||
1609 | struct xhci_container_ctx *in_ctx) | ||
1610 | { | ||
1611 | struct xhci_input_control_ctx *ctrl_ctx; | ||
1612 | u32 valid_add_flags; | ||
1613 | u32 valid_drop_flags; | ||
1614 | |||
1615 | ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); | ||
1616 | valid_add_flags = ctrl_ctx->add_flags >> 2; | ||
1617 | valid_drop_flags = ctrl_ctx->drop_flags >> 2; | ||
1618 | |||
1619 | return hweight32(valid_drop_flags) - | ||
1620 | hweight32(valid_add_flags & valid_drop_flags); | ||
1621 | } | ||
1622 | |||
1623 | /* | ||
1624 | * We need to reserve the new number of endpoints before the configure endpoint | ||
1625 | * command completes. We can't subtract the dropped endpoints from the number | ||
1626 | * of active endpoints until the command completes because we can oversubscribe | ||
1627 | * the host in this case: | ||
1628 | * | ||
1629 | * - the first configure endpoint command drops more endpoints than it adds | ||
1630 | * - a second configure endpoint command that adds more endpoints is queued | ||
1631 | * - the first configure endpoint command fails, so the config is unchanged | ||
1632 | * - the second command may succeed, even though there isn't enough resources | ||
1633 | * | ||
1634 | * Must be called with xhci->lock held. | ||
1635 | */ | ||
1636 | static int xhci_reserve_host_resources(struct xhci_hcd *xhci, | ||
1637 | struct xhci_container_ctx *in_ctx) | ||
1638 | { | ||
1639 | u32 added_eps; | ||
1640 | |||
1641 | added_eps = xhci_count_num_new_endpoints(xhci, in_ctx); | ||
1642 | if (xhci->num_active_eps + added_eps > xhci->limit_active_eps) { | ||
1643 | xhci_dbg(xhci, "Not enough ep ctxs: " | ||
1644 | "%u active, need to add %u, limit is %u.\n", | ||
1645 | xhci->num_active_eps, added_eps, | ||
1646 | xhci->limit_active_eps); | ||
1647 | return -ENOMEM; | ||
1648 | } | ||
1649 | xhci->num_active_eps += added_eps; | ||
1650 | xhci_dbg(xhci, "Adding %u ep ctxs, %u now active.\n", added_eps, | ||
1651 | xhci->num_active_eps); | ||
1652 | return 0; | ||
1653 | } | ||
1654 | |||
1655 | /* | ||
1656 | * The configure endpoint was failed by the xHC for some other reason, so we | ||
1657 | * need to revert the resources that failed configuration would have used. | ||
1658 | * | ||
1659 | * Must be called with xhci->lock held. | ||
1660 | */ | ||
1661 | static void xhci_free_host_resources(struct xhci_hcd *xhci, | ||
1662 | struct xhci_container_ctx *in_ctx) | ||
1663 | { | ||
1664 | u32 num_failed_eps; | ||
1665 | |||
1666 | num_failed_eps = xhci_count_num_new_endpoints(xhci, in_ctx); | ||
1667 | xhci->num_active_eps -= num_failed_eps; | ||
1668 | xhci_dbg(xhci, "Removing %u failed ep ctxs, %u now active.\n", | ||
1669 | num_failed_eps, | ||
1670 | xhci->num_active_eps); | ||
1671 | } | ||
1672 | |||
1673 | /* | ||
1674 | * Now that the command has completed, clean up the active endpoint count by | ||
1675 | * subtracting out the endpoints that were dropped (but not changed). | ||
1676 | * | ||
1677 | * Must be called with xhci->lock held. | ||
1678 | */ | ||
1679 | static void xhci_finish_resource_reservation(struct xhci_hcd *xhci, | ||
1680 | struct xhci_container_ctx *in_ctx) | ||
1681 | { | ||
1682 | u32 num_dropped_eps; | ||
1683 | |||
1684 | num_dropped_eps = xhci_count_num_dropped_endpoints(xhci, in_ctx); | ||
1685 | xhci->num_active_eps -= num_dropped_eps; | ||
1686 | if (num_dropped_eps) | ||
1687 | xhci_dbg(xhci, "Removing %u dropped ep ctxs, %u now active.\n", | ||
1688 | num_dropped_eps, | ||
1689 | xhci->num_active_eps); | ||
1690 | } | ||
1691 | |||
1581 | /* Issue a configure endpoint command or evaluate context command | 1692 | /* Issue a configure endpoint command or evaluate context command |
1582 | * and wait for it to finish. | 1693 | * and wait for it to finish. |
1583 | */ | 1694 | */ |
@@ -1598,6 +1709,15 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, | |||
1598 | virt_dev = xhci->devs[udev->slot_id]; | 1709 | virt_dev = xhci->devs[udev->slot_id]; |
1599 | if (command) { | 1710 | if (command) { |
1600 | in_ctx = command->in_ctx; | 1711 | in_ctx = command->in_ctx; |
1712 | if ((xhci->quirks & XHCI_EP_LIMIT_QUIRK) && | ||
1713 | xhci_reserve_host_resources(xhci, in_ctx)) { | ||
1714 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
1715 | xhci_warn(xhci, "Not enough host resources, " | ||
1716 | "active endpoint contexts = %u\n", | ||
1717 | xhci->num_active_eps); | ||
1718 | return -ENOMEM; | ||
1719 | } | ||
1720 | |||
1601 | cmd_completion = command->completion; | 1721 | cmd_completion = command->completion; |
1602 | cmd_status = &command->status; | 1722 | cmd_status = &command->status; |
1603 | command->command_trb = xhci->cmd_ring->enqueue; | 1723 | command->command_trb = xhci->cmd_ring->enqueue; |
@@ -1613,6 +1733,14 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, | |||
1613 | list_add_tail(&command->cmd_list, &virt_dev->cmd_list); | 1733 | list_add_tail(&command->cmd_list, &virt_dev->cmd_list); |
1614 | } else { | 1734 | } else { |
1615 | in_ctx = virt_dev->in_ctx; | 1735 | in_ctx = virt_dev->in_ctx; |
1736 | if ((xhci->quirks & XHCI_EP_LIMIT_QUIRK) && | ||
1737 | xhci_reserve_host_resources(xhci, in_ctx)) { | ||
1738 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
1739 | xhci_warn(xhci, "Not enough host resources, " | ||
1740 | "active endpoint contexts = %u\n", | ||
1741 | xhci->num_active_eps); | ||
1742 | return -ENOMEM; | ||
1743 | } | ||
1616 | cmd_completion = &virt_dev->cmd_completion; | 1744 | cmd_completion = &virt_dev->cmd_completion; |
1617 | cmd_status = &virt_dev->cmd_status; | 1745 | cmd_status = &virt_dev->cmd_status; |
1618 | } | 1746 | } |
@@ -1627,6 +1755,8 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, | |||
1627 | if (ret < 0) { | 1755 | if (ret < 0) { |
1628 | if (command) | 1756 | if (command) |
1629 | list_del(&command->cmd_list); | 1757 | list_del(&command->cmd_list); |
1758 | if ((xhci->quirks & XHCI_EP_LIMIT_QUIRK)) | ||
1759 | xhci_free_host_resources(xhci, in_ctx); | ||
1630 | spin_unlock_irqrestore(&xhci->lock, flags); | 1760 | spin_unlock_irqrestore(&xhci->lock, flags); |
1631 | xhci_dbg(xhci, "FIXME allocate a new ring segment\n"); | 1761 | xhci_dbg(xhci, "FIXME allocate a new ring segment\n"); |
1632 | return -ENOMEM; | 1762 | return -ENOMEM; |
@@ -1649,8 +1779,22 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, | |||
1649 | } | 1779 | } |
1650 | 1780 | ||
1651 | if (!ctx_change) | 1781 | if (!ctx_change) |
1652 | return xhci_configure_endpoint_result(xhci, udev, cmd_status); | 1782 | ret = xhci_configure_endpoint_result(xhci, udev, cmd_status); |
1653 | return xhci_evaluate_context_result(xhci, udev, cmd_status); | 1783 | else |
1784 | ret = xhci_evaluate_context_result(xhci, udev, cmd_status); | ||
1785 | |||
1786 | if ((xhci->quirks & XHCI_EP_LIMIT_QUIRK)) { | ||
1787 | spin_lock_irqsave(&xhci->lock, flags); | ||
1788 | /* If the command failed, remove the reserved resources. | ||
1789 | * Otherwise, clean up the estimate to include dropped eps. | ||
1790 | */ | ||
1791 | if (ret) | ||
1792 | xhci_free_host_resources(xhci, in_ctx); | ||
1793 | else | ||
1794 | xhci_finish_resource_reservation(xhci, in_ctx); | ||
1795 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
1796 | } | ||
1797 | return ret; | ||
1654 | } | 1798 | } |
1655 | 1799 | ||
1656 | /* Called after one or more calls to xhci_add_endpoint() or | 1800 | /* Called after one or more calls to xhci_add_endpoint() or |
@@ -1676,6 +1820,8 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) | |||
1676 | if (ret <= 0) | 1820 | if (ret <= 0) |
1677 | return ret; | 1821 | return ret; |
1678 | xhci = hcd_to_xhci(hcd); | 1822 | xhci = hcd_to_xhci(hcd); |
1823 | if (xhci->xhc_state & XHCI_STATE_DYING) | ||
1824 | return -ENODEV; | ||
1679 | 1825 | ||
1680 | xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); | 1826 | xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); |
1681 | virt_dev = xhci->devs[udev->slot_id]; | 1827 | virt_dev = xhci->devs[udev->slot_id]; |
@@ -2266,6 +2412,34 @@ int xhci_free_streams(struct usb_hcd *hcd, struct usb_device *udev, | |||
2266 | } | 2412 | } |
2267 | 2413 | ||
2268 | /* | 2414 | /* |
2415 | * Deletes endpoint resources for endpoints that were active before a Reset | ||
2416 | * Device command, or a Disable Slot command. The Reset Device command leaves | ||
2417 | * the control endpoint intact, whereas the Disable Slot command deletes it. | ||
2418 | * | ||
2419 | * Must be called with xhci->lock held. | ||
2420 | */ | ||
2421 | void xhci_free_device_endpoint_resources(struct xhci_hcd *xhci, | ||
2422 | struct xhci_virt_device *virt_dev, bool drop_control_ep) | ||
2423 | { | ||
2424 | int i; | ||
2425 | unsigned int num_dropped_eps = 0; | ||
2426 | unsigned int drop_flags = 0; | ||
2427 | |||
2428 | for (i = (drop_control_ep ? 0 : 1); i < 31; i++) { | ||
2429 | if (virt_dev->eps[i].ring) { | ||
2430 | drop_flags |= 1 << i; | ||
2431 | num_dropped_eps++; | ||
2432 | } | ||
2433 | } | ||
2434 | xhci->num_active_eps -= num_dropped_eps; | ||
2435 | if (num_dropped_eps) | ||
2436 | xhci_dbg(xhci, "Dropped %u ep ctxs, flags = 0x%x, " | ||
2437 | "%u now active.\n", | ||
2438 | num_dropped_eps, drop_flags, | ||
2439 | xhci->num_active_eps); | ||
2440 | } | ||
2441 | |||
2442 | /* | ||
2269 | * This submits a Reset Device Command, which will set the device state to 0, | 2443 | * This submits a Reset Device Command, which will set the device state to 0, |
2270 | * set the device address to 0, and disable all the endpoints except the default | 2444 | * set the device address to 0, and disable all the endpoints except the default |
2271 | * control endpoint. The USB core should come back and call | 2445 | * control endpoint. The USB core should come back and call |
@@ -2406,6 +2580,14 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
2406 | goto command_cleanup; | 2580 | goto command_cleanup; |
2407 | } | 2581 | } |
2408 | 2582 | ||
2583 | /* Free up host controller endpoint resources */ | ||
2584 | if ((xhci->quirks & XHCI_EP_LIMIT_QUIRK)) { | ||
2585 | spin_lock_irqsave(&xhci->lock, flags); | ||
2586 | /* Don't delete the default control endpoint resources */ | ||
2587 | xhci_free_device_endpoint_resources(xhci, virt_dev, false); | ||
2588 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
2589 | } | ||
2590 | |||
2409 | /* Everything but endpoint 0 is disabled, so free or cache the rings. */ | 2591 | /* Everything but endpoint 0 is disabled, so free or cache the rings. */ |
2410 | last_freed_endpoint = 1; | 2592 | last_freed_endpoint = 1; |
2411 | for (i = 1; i < 31; ++i) { | 2593 | for (i = 1; i < 31; ++i) { |
@@ -2479,6 +2661,27 @@ void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev) | |||
2479 | } | 2661 | } |
2480 | 2662 | ||
2481 | /* | 2663 | /* |
2664 | * Checks if we have enough host controller resources for the default control | ||
2665 | * endpoint. | ||
2666 | * | ||
2667 | * Must be called with xhci->lock held. | ||
2668 | */ | ||
2669 | static int xhci_reserve_host_control_ep_resources(struct xhci_hcd *xhci) | ||
2670 | { | ||
2671 | if (xhci->num_active_eps + 1 > xhci->limit_active_eps) { | ||
2672 | xhci_dbg(xhci, "Not enough ep ctxs: " | ||
2673 | "%u active, need to add 1, limit is %u.\n", | ||
2674 | xhci->num_active_eps, xhci->limit_active_eps); | ||
2675 | return -ENOMEM; | ||
2676 | } | ||
2677 | xhci->num_active_eps += 1; | ||
2678 | xhci_dbg(xhci, "Adding 1 ep ctx, %u now active.\n", | ||
2679 | xhci->num_active_eps); | ||
2680 | return 0; | ||
2681 | } | ||
2682 | |||
2683 | |||
2684 | /* | ||
2482 | * Returns 0 if the xHC ran out of device slots, the Enable Slot command | 2685 | * Returns 0 if the xHC ran out of device slots, the Enable Slot command |
2483 | * timed out, or allocating memory failed. Returns 1 on success. | 2686 | * timed out, or allocating memory failed. Returns 1 on success. |
2484 | */ | 2687 | */ |
@@ -2513,24 +2716,39 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) | |||
2513 | xhci_err(xhci, "Error while assigning device slot ID\n"); | 2716 | xhci_err(xhci, "Error while assigning device slot ID\n"); |
2514 | return 0; | 2717 | return 0; |
2515 | } | 2718 | } |
2516 | /* xhci_alloc_virt_device() does not touch rings; no need to lock. | 2719 | |
2517 | * Use GFP_NOIO, since this function can be called from | 2720 | if ((xhci->quirks & XHCI_EP_LIMIT_QUIRK)) { |
2721 | spin_lock_irqsave(&xhci->lock, flags); | ||
2722 | ret = xhci_reserve_host_control_ep_resources(xhci); | ||
2723 | if (ret) { | ||
2724 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
2725 | xhci_warn(xhci, "Not enough host resources, " | ||
2726 | "active endpoint contexts = %u\n", | ||
2727 | xhci->num_active_eps); | ||
2728 | goto disable_slot; | ||
2729 | } | ||
2730 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
2731 | } | ||
2732 | /* Use GFP_NOIO, since this function can be called from | ||
2518 | * xhci_discover_or_reset_device(), which may be called as part of | 2733 | * xhci_discover_or_reset_device(), which may be called as part of |
2519 | * mass storage driver error handling. | 2734 | * mass storage driver error handling. |
2520 | */ | 2735 | */ |
2521 | if (!xhci_alloc_virt_device(xhci, xhci->slot_id, udev, GFP_NOIO)) { | 2736 | if (!xhci_alloc_virt_device(xhci, xhci->slot_id, udev, GFP_NOIO)) { |
2522 | /* Disable slot, if we can do it without mem alloc */ | ||
2523 | xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n"); | 2737 | xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n"); |
2524 | spin_lock_irqsave(&xhci->lock, flags); | 2738 | goto disable_slot; |
2525 | if (!xhci_queue_slot_control(xhci, TRB_DISABLE_SLOT, udev->slot_id)) | ||
2526 | xhci_ring_cmd_db(xhci); | ||
2527 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
2528 | return 0; | ||
2529 | } | 2739 | } |
2530 | udev->slot_id = xhci->slot_id; | 2740 | udev->slot_id = xhci->slot_id; |
2531 | /* Is this a LS or FS device under a HS hub? */ | 2741 | /* Is this a LS or FS device under a HS hub? */ |
2532 | /* Hub or peripherial? */ | 2742 | /* Hub or peripherial? */ |
2533 | return 1; | 2743 | return 1; |
2744 | |||
2745 | disable_slot: | ||
2746 | /* Disable slot, if we can do it without mem alloc */ | ||
2747 | spin_lock_irqsave(&xhci->lock, flags); | ||
2748 | if (!xhci_queue_slot_control(xhci, TRB_DISABLE_SLOT, udev->slot_id)) | ||
2749 | xhci_ring_cmd_db(xhci); | ||
2750 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
2751 | return 0; | ||
2534 | } | 2752 | } |
2535 | 2753 | ||
2536 | /* | 2754 | /* |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index e12db7cfb9bb..ac0196e7fcf1 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -1123,6 +1123,7 @@ struct xhci_ring { | |||
1123 | */ | 1123 | */ |
1124 | u32 cycle_state; | 1124 | u32 cycle_state; |
1125 | unsigned int stream_id; | 1125 | unsigned int stream_id; |
1126 | bool last_td_was_short; | ||
1126 | }; | 1127 | }; |
1127 | 1128 | ||
1128 | struct xhci_erst_entry { | 1129 | struct xhci_erst_entry { |
@@ -1290,6 +1291,19 @@ struct xhci_hcd { | |||
1290 | #define XHCI_RESET_EP_QUIRK (1 << 1) | 1291 | #define XHCI_RESET_EP_QUIRK (1 << 1) |
1291 | #define XHCI_NEC_HOST (1 << 2) | 1292 | #define XHCI_NEC_HOST (1 << 2) |
1292 | #define XHCI_AMD_PLL_FIX (1 << 3) | 1293 | #define XHCI_AMD_PLL_FIX (1 << 3) |
1294 | #define XHCI_SPURIOUS_SUCCESS (1 << 4) | ||
1295 | /* | ||
1296 | * Certain Intel host controllers have a limit to the number of endpoint | ||
1297 | * contexts they can handle. Ideally, they would signal that they can't handle | ||
1298 | * anymore endpoint contexts by returning a Resource Error for the Configure | ||
1299 | * Endpoint command, but they don't. Instead they expect software to keep track | ||
1300 | * of the number of active endpoints for them, across configure endpoint | ||
1301 | * commands, reset device commands, disable slot commands, and address device | ||
1302 | * commands. | ||
1303 | */ | ||
1304 | #define XHCI_EP_LIMIT_QUIRK (1 << 5) | ||
1305 | unsigned int num_active_eps; | ||
1306 | unsigned int limit_active_eps; | ||
1293 | /* There are two roothubs to keep track of bus suspend info for */ | 1307 | /* There are two roothubs to keep track of bus suspend info for */ |
1294 | struct xhci_bus_state bus_state[2]; | 1308 | struct xhci_bus_state bus_state[2]; |
1295 | /* Is each xHCI roothub port a USB 3.0, USB 2.0, or USB 1.1 port? */ | 1309 | /* Is each xHCI roothub port a USB 3.0, USB 2.0, or USB 1.1 port? */ |
@@ -1338,9 +1352,6 @@ static inline unsigned int xhci_readl(const struct xhci_hcd *xhci, | |||
1338 | static inline void xhci_writel(struct xhci_hcd *xhci, | 1352 | static inline void xhci_writel(struct xhci_hcd *xhci, |
1339 | const unsigned int val, __le32 __iomem *regs) | 1353 | const unsigned int val, __le32 __iomem *regs) |
1340 | { | 1354 | { |
1341 | xhci_dbg(xhci, | ||
1342 | "`MEM_WRITE_DWORD(3'b000, 32'h%p, 32'h%0x, 4'hf);\n", | ||
1343 | regs, val); | ||
1344 | writel(val, regs); | 1355 | writel(val, regs); |
1345 | } | 1356 | } |
1346 | 1357 | ||
@@ -1368,9 +1379,6 @@ static inline void xhci_write_64(struct xhci_hcd *xhci, | |||
1368 | u32 val_lo = lower_32_bits(val); | 1379 | u32 val_lo = lower_32_bits(val); |
1369 | u32 val_hi = upper_32_bits(val); | 1380 | u32 val_hi = upper_32_bits(val); |
1370 | 1381 | ||
1371 | xhci_dbg(xhci, | ||
1372 | "`MEM_WRITE_DWORD(3'b000, 64'h%p, 64'h%0lx, 4'hf);\n", | ||
1373 | regs, (long unsigned int) val); | ||
1374 | writel(val_lo, ptr); | 1382 | writel(val_lo, ptr); |
1375 | writel(val_hi, ptr + 1); | 1383 | writel(val_hi, ptr + 1); |
1376 | } | 1384 | } |
@@ -1439,6 +1447,8 @@ void xhci_setup_streams_ep_input_ctx(struct xhci_hcd *xhci, | |||
1439 | void xhci_setup_no_streams_ep_input_ctx(struct xhci_hcd *xhci, | 1447 | void xhci_setup_no_streams_ep_input_ctx(struct xhci_hcd *xhci, |
1440 | struct xhci_ep_ctx *ep_ctx, | 1448 | struct xhci_ep_ctx *ep_ctx, |
1441 | struct xhci_virt_ep *ep); | 1449 | struct xhci_virt_ep *ep); |
1450 | void xhci_free_device_endpoint_resources(struct xhci_hcd *xhci, | ||
1451 | struct xhci_virt_device *virt_dev, bool drop_control_ep); | ||
1442 | struct xhci_ring *xhci_dma_to_transfer_ring( | 1452 | struct xhci_ring *xhci_dma_to_transfer_ring( |
1443 | struct xhci_virt_ep *ep, | 1453 | struct xhci_virt_ep *ep, |
1444 | u64 address); | 1454 | u64 address); |
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 2f7c76a85e53..e224a92baa16 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c | |||
@@ -144,7 +144,7 @@ static void handle_tx(struct vhost_net *net) | |||
144 | } | 144 | } |
145 | 145 | ||
146 | mutex_lock(&vq->mutex); | 146 | mutex_lock(&vq->mutex); |
147 | vhost_disable_notify(vq); | 147 | vhost_disable_notify(&net->dev, vq); |
148 | 148 | ||
149 | if (wmem < sock->sk->sk_sndbuf / 2) | 149 | if (wmem < sock->sk->sk_sndbuf / 2) |
150 | tx_poll_stop(net); | 150 | tx_poll_stop(net); |
@@ -166,8 +166,8 @@ static void handle_tx(struct vhost_net *net) | |||
166 | set_bit(SOCK_ASYNC_NOSPACE, &sock->flags); | 166 | set_bit(SOCK_ASYNC_NOSPACE, &sock->flags); |
167 | break; | 167 | break; |
168 | } | 168 | } |
169 | if (unlikely(vhost_enable_notify(vq))) { | 169 | if (unlikely(vhost_enable_notify(&net->dev, vq))) { |
170 | vhost_disable_notify(vq); | 170 | vhost_disable_notify(&net->dev, vq); |
171 | continue; | 171 | continue; |
172 | } | 172 | } |
173 | break; | 173 | break; |
@@ -315,7 +315,7 @@ static void handle_rx(struct vhost_net *net) | |||
315 | return; | 315 | return; |
316 | 316 | ||
317 | mutex_lock(&vq->mutex); | 317 | mutex_lock(&vq->mutex); |
318 | vhost_disable_notify(vq); | 318 | vhost_disable_notify(&net->dev, vq); |
319 | vhost_hlen = vq->vhost_hlen; | 319 | vhost_hlen = vq->vhost_hlen; |
320 | sock_hlen = vq->sock_hlen; | 320 | sock_hlen = vq->sock_hlen; |
321 | 321 | ||
@@ -334,10 +334,10 @@ static void handle_rx(struct vhost_net *net) | |||
334 | break; | 334 | break; |
335 | /* OK, now we need to know about added descriptors. */ | 335 | /* OK, now we need to know about added descriptors. */ |
336 | if (!headcount) { | 336 | if (!headcount) { |
337 | if (unlikely(vhost_enable_notify(vq))) { | 337 | if (unlikely(vhost_enable_notify(&net->dev, vq))) { |
338 | /* They have slipped one in as we were | 338 | /* They have slipped one in as we were |
339 | * doing that: check again. */ | 339 | * doing that: check again. */ |
340 | vhost_disable_notify(vq); | 340 | vhost_disable_notify(&net->dev, vq); |
341 | continue; | 341 | continue; |
342 | } | 342 | } |
343 | /* Nothing new? Wait for eventfd to tell us | 343 | /* Nothing new? Wait for eventfd to tell us |
diff --git a/drivers/vhost/test.c b/drivers/vhost/test.c index 099f30230d06..734e1d74ad80 100644 --- a/drivers/vhost/test.c +++ b/drivers/vhost/test.c | |||
@@ -49,7 +49,7 @@ static void handle_vq(struct vhost_test *n) | |||
49 | return; | 49 | return; |
50 | 50 | ||
51 | mutex_lock(&vq->mutex); | 51 | mutex_lock(&vq->mutex); |
52 | vhost_disable_notify(vq); | 52 | vhost_disable_notify(&n->dev, vq); |
53 | 53 | ||
54 | for (;;) { | 54 | for (;;) { |
55 | head = vhost_get_vq_desc(&n->dev, vq, vq->iov, | 55 | head = vhost_get_vq_desc(&n->dev, vq, vq->iov, |
@@ -61,8 +61,8 @@ static void handle_vq(struct vhost_test *n) | |||
61 | break; | 61 | break; |
62 | /* Nothing new? Wait for eventfd to tell us they refilled. */ | 62 | /* Nothing new? Wait for eventfd to tell us they refilled. */ |
63 | if (head == vq->num) { | 63 | if (head == vq->num) { |
64 | if (unlikely(vhost_enable_notify(vq))) { | 64 | if (unlikely(vhost_enable_notify(&n->dev, vq))) { |
65 | vhost_disable_notify(vq); | 65 | vhost_disable_notify(&n->dev, vq); |
66 | continue; | 66 | continue; |
67 | } | 67 | } |
68 | break; | 68 | break; |
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 7aa4eea930f1..ea966b356352 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c | |||
@@ -37,6 +37,9 @@ enum { | |||
37 | VHOST_MEMORY_F_LOG = 0x1, | 37 | VHOST_MEMORY_F_LOG = 0x1, |
38 | }; | 38 | }; |
39 | 39 | ||
40 | #define vhost_used_event(vq) ((u16 __user *)&vq->avail->ring[vq->num]) | ||
41 | #define vhost_avail_event(vq) ((u16 __user *)&vq->used->ring[vq->num]) | ||
42 | |||
40 | static void vhost_poll_func(struct file *file, wait_queue_head_t *wqh, | 43 | static void vhost_poll_func(struct file *file, wait_queue_head_t *wqh, |
41 | poll_table *pt) | 44 | poll_table *pt) |
42 | { | 45 | { |
@@ -161,6 +164,8 @@ static void vhost_vq_reset(struct vhost_dev *dev, | |||
161 | vq->last_avail_idx = 0; | 164 | vq->last_avail_idx = 0; |
162 | vq->avail_idx = 0; | 165 | vq->avail_idx = 0; |
163 | vq->last_used_idx = 0; | 166 | vq->last_used_idx = 0; |
167 | vq->signalled_used = 0; | ||
168 | vq->signalled_used_valid = false; | ||
164 | vq->used_flags = 0; | 169 | vq->used_flags = 0; |
165 | vq->log_used = false; | 170 | vq->log_used = false; |
166 | vq->log_addr = -1ull; | 171 | vq->log_addr = -1ull; |
@@ -489,16 +494,17 @@ static int memory_access_ok(struct vhost_dev *d, struct vhost_memory *mem, | |||
489 | return 1; | 494 | return 1; |
490 | } | 495 | } |
491 | 496 | ||
492 | static int vq_access_ok(unsigned int num, | 497 | static int vq_access_ok(struct vhost_dev *d, unsigned int num, |
493 | struct vring_desc __user *desc, | 498 | struct vring_desc __user *desc, |
494 | struct vring_avail __user *avail, | 499 | struct vring_avail __user *avail, |
495 | struct vring_used __user *used) | 500 | struct vring_used __user *used) |
496 | { | 501 | { |
502 | size_t s = vhost_has_feature(d, VIRTIO_RING_F_EVENT_IDX) ? 2 : 0; | ||
497 | return access_ok(VERIFY_READ, desc, num * sizeof *desc) && | 503 | return access_ok(VERIFY_READ, desc, num * sizeof *desc) && |
498 | access_ok(VERIFY_READ, avail, | 504 | access_ok(VERIFY_READ, avail, |
499 | sizeof *avail + num * sizeof *avail->ring) && | 505 | sizeof *avail + num * sizeof *avail->ring + s) && |
500 | access_ok(VERIFY_WRITE, used, | 506 | access_ok(VERIFY_WRITE, used, |
501 | sizeof *used + num * sizeof *used->ring); | 507 | sizeof *used + num * sizeof *used->ring + s); |
502 | } | 508 | } |
503 | 509 | ||
504 | /* Can we log writes? */ | 510 | /* Can we log writes? */ |
@@ -514,9 +520,11 @@ int vhost_log_access_ok(struct vhost_dev *dev) | |||
514 | 520 | ||
515 | /* Verify access for write logging. */ | 521 | /* Verify access for write logging. */ |
516 | /* Caller should have vq mutex and device mutex */ | 522 | /* Caller should have vq mutex and device mutex */ |
517 | static int vq_log_access_ok(struct vhost_virtqueue *vq, void __user *log_base) | 523 | static int vq_log_access_ok(struct vhost_dev *d, struct vhost_virtqueue *vq, |
524 | void __user *log_base) | ||
518 | { | 525 | { |
519 | struct vhost_memory *mp; | 526 | struct vhost_memory *mp; |
527 | size_t s = vhost_has_feature(d, VIRTIO_RING_F_EVENT_IDX) ? 2 : 0; | ||
520 | 528 | ||
521 | mp = rcu_dereference_protected(vq->dev->memory, | 529 | mp = rcu_dereference_protected(vq->dev->memory, |
522 | lockdep_is_held(&vq->mutex)); | 530 | lockdep_is_held(&vq->mutex)); |
@@ -524,15 +532,15 @@ static int vq_log_access_ok(struct vhost_virtqueue *vq, void __user *log_base) | |||
524 | vhost_has_feature(vq->dev, VHOST_F_LOG_ALL)) && | 532 | vhost_has_feature(vq->dev, VHOST_F_LOG_ALL)) && |
525 | (!vq->log_used || log_access_ok(log_base, vq->log_addr, | 533 | (!vq->log_used || log_access_ok(log_base, vq->log_addr, |
526 | sizeof *vq->used + | 534 | sizeof *vq->used + |
527 | vq->num * sizeof *vq->used->ring)); | 535 | vq->num * sizeof *vq->used->ring + s)); |
528 | } | 536 | } |
529 | 537 | ||
530 | /* Can we start vq? */ | 538 | /* Can we start vq? */ |
531 | /* Caller should have vq mutex and device mutex */ | 539 | /* Caller should have vq mutex and device mutex */ |
532 | int vhost_vq_access_ok(struct vhost_virtqueue *vq) | 540 | int vhost_vq_access_ok(struct vhost_virtqueue *vq) |
533 | { | 541 | { |
534 | return vq_access_ok(vq->num, vq->desc, vq->avail, vq->used) && | 542 | return vq_access_ok(vq->dev, vq->num, vq->desc, vq->avail, vq->used) && |
535 | vq_log_access_ok(vq, vq->log_base); | 543 | vq_log_access_ok(vq->dev, vq, vq->log_base); |
536 | } | 544 | } |
537 | 545 | ||
538 | static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m) | 546 | static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m) |
@@ -577,6 +585,7 @@ static int init_used(struct vhost_virtqueue *vq, | |||
577 | 585 | ||
578 | if (r) | 586 | if (r) |
579 | return r; | 587 | return r; |
588 | vq->signalled_used_valid = false; | ||
580 | return get_user(vq->last_used_idx, &used->idx); | 589 | return get_user(vq->last_used_idx, &used->idx); |
581 | } | 590 | } |
582 | 591 | ||
@@ -674,7 +683,7 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp) | |||
674 | * If it is not, we don't as size might not have been setup. | 683 | * If it is not, we don't as size might not have been setup. |
675 | * We will verify when backend is configured. */ | 684 | * We will verify when backend is configured. */ |
676 | if (vq->private_data) { | 685 | if (vq->private_data) { |
677 | if (!vq_access_ok(vq->num, | 686 | if (!vq_access_ok(d, vq->num, |
678 | (void __user *)(unsigned long)a.desc_user_addr, | 687 | (void __user *)(unsigned long)a.desc_user_addr, |
679 | (void __user *)(unsigned long)a.avail_user_addr, | 688 | (void __user *)(unsigned long)a.avail_user_addr, |
680 | (void __user *)(unsigned long)a.used_user_addr)) { | 689 | (void __user *)(unsigned long)a.used_user_addr)) { |
@@ -818,7 +827,7 @@ long vhost_dev_ioctl(struct vhost_dev *d, unsigned int ioctl, unsigned long arg) | |||
818 | vq = d->vqs + i; | 827 | vq = d->vqs + i; |
819 | mutex_lock(&vq->mutex); | 828 | mutex_lock(&vq->mutex); |
820 | /* If ring is inactive, will check when it's enabled. */ | 829 | /* If ring is inactive, will check when it's enabled. */ |
821 | if (vq->private_data && !vq_log_access_ok(vq, base)) | 830 | if (vq->private_data && !vq_log_access_ok(d, vq, base)) |
822 | r = -EFAULT; | 831 | r = -EFAULT; |
823 | else | 832 | else |
824 | vq->log_base = base; | 833 | vq->log_base = base; |
@@ -1219,6 +1228,10 @@ int vhost_get_vq_desc(struct vhost_dev *dev, struct vhost_virtqueue *vq, | |||
1219 | 1228 | ||
1220 | /* On success, increment avail index. */ | 1229 | /* On success, increment avail index. */ |
1221 | vq->last_avail_idx++; | 1230 | vq->last_avail_idx++; |
1231 | |||
1232 | /* Assume notifications from guest are disabled at this point, | ||
1233 | * if they aren't we would need to update avail_event index. */ | ||
1234 | BUG_ON(!(vq->used_flags & VRING_USED_F_NO_NOTIFY)); | ||
1222 | return head; | 1235 | return head; |
1223 | } | 1236 | } |
1224 | 1237 | ||
@@ -1267,6 +1280,12 @@ int vhost_add_used(struct vhost_virtqueue *vq, unsigned int head, int len) | |||
1267 | eventfd_signal(vq->log_ctx, 1); | 1280 | eventfd_signal(vq->log_ctx, 1); |
1268 | } | 1281 | } |
1269 | vq->last_used_idx++; | 1282 | vq->last_used_idx++; |
1283 | /* If the driver never bothers to signal in a very long while, | ||
1284 | * used index might wrap around. If that happens, invalidate | ||
1285 | * signalled_used index we stored. TODO: make sure driver | ||
1286 | * signals at least once in 2^16 and remove this. */ | ||
1287 | if (unlikely(vq->last_used_idx == vq->signalled_used)) | ||
1288 | vq->signalled_used_valid = false; | ||
1270 | return 0; | 1289 | return 0; |
1271 | } | 1290 | } |
1272 | 1291 | ||
@@ -1275,6 +1294,7 @@ static int __vhost_add_used_n(struct vhost_virtqueue *vq, | |||
1275 | unsigned count) | 1294 | unsigned count) |
1276 | { | 1295 | { |
1277 | struct vring_used_elem __user *used; | 1296 | struct vring_used_elem __user *used; |
1297 | u16 old, new; | ||
1278 | int start; | 1298 | int start; |
1279 | 1299 | ||
1280 | start = vq->last_used_idx % vq->num; | 1300 | start = vq->last_used_idx % vq->num; |
@@ -1292,7 +1312,14 @@ static int __vhost_add_used_n(struct vhost_virtqueue *vq, | |||
1292 | ((void __user *)used - (void __user *)vq->used), | 1312 | ((void __user *)used - (void __user *)vq->used), |
1293 | count * sizeof *used); | 1313 | count * sizeof *used); |
1294 | } | 1314 | } |
1295 | vq->last_used_idx += count; | 1315 | old = vq->last_used_idx; |
1316 | new = (vq->last_used_idx += count); | ||
1317 | /* If the driver never bothers to signal in a very long while, | ||
1318 | * used index might wrap around. If that happens, invalidate | ||
1319 | * signalled_used index we stored. TODO: make sure driver | ||
1320 | * signals at least once in 2^16 and remove this. */ | ||
1321 | if (unlikely((u16)(new - vq->signalled_used) < (u16)(new - old))) | ||
1322 | vq->signalled_used_valid = false; | ||
1296 | return 0; | 1323 | return 0; |
1297 | } | 1324 | } |
1298 | 1325 | ||
@@ -1331,29 +1358,47 @@ int vhost_add_used_n(struct vhost_virtqueue *vq, struct vring_used_elem *heads, | |||
1331 | return r; | 1358 | return r; |
1332 | } | 1359 | } |
1333 | 1360 | ||
1334 | /* This actually signals the guest, using eventfd. */ | 1361 | static bool vhost_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq) |
1335 | void vhost_signal(struct vhost_dev *dev, struct vhost_virtqueue *vq) | ||
1336 | { | 1362 | { |
1337 | __u16 flags; | 1363 | __u16 old, new, event; |
1338 | 1364 | bool v; | |
1339 | /* Flush out used index updates. This is paired | 1365 | /* Flush out used index updates. This is paired |
1340 | * with the barrier that the Guest executes when enabling | 1366 | * with the barrier that the Guest executes when enabling |
1341 | * interrupts. */ | 1367 | * interrupts. */ |
1342 | smp_mb(); | 1368 | smp_mb(); |
1343 | 1369 | ||
1344 | if (__get_user(flags, &vq->avail->flags)) { | 1370 | if (vhost_has_feature(dev, VIRTIO_F_NOTIFY_ON_EMPTY) && |
1345 | vq_err(vq, "Failed to get flags"); | 1371 | unlikely(vq->avail_idx == vq->last_avail_idx)) |
1346 | return; | 1372 | return true; |
1373 | |||
1374 | if (!vhost_has_feature(dev, VIRTIO_RING_F_EVENT_IDX)) { | ||
1375 | __u16 flags; | ||
1376 | if (__get_user(flags, &vq->avail->flags)) { | ||
1377 | vq_err(vq, "Failed to get flags"); | ||
1378 | return true; | ||
1379 | } | ||
1380 | return !(flags & VRING_AVAIL_F_NO_INTERRUPT); | ||
1347 | } | 1381 | } |
1382 | old = vq->signalled_used; | ||
1383 | v = vq->signalled_used_valid; | ||
1384 | new = vq->signalled_used = vq->last_used_idx; | ||
1385 | vq->signalled_used_valid = true; | ||
1348 | 1386 | ||
1349 | /* If they don't want an interrupt, don't signal, unless empty. */ | 1387 | if (unlikely(!v)) |
1350 | if ((flags & VRING_AVAIL_F_NO_INTERRUPT) && | 1388 | return true; |
1351 | (vq->avail_idx != vq->last_avail_idx || | ||
1352 | !vhost_has_feature(dev, VIRTIO_F_NOTIFY_ON_EMPTY))) | ||
1353 | return; | ||
1354 | 1389 | ||
1390 | if (get_user(event, vhost_used_event(vq))) { | ||
1391 | vq_err(vq, "Failed to get used event idx"); | ||
1392 | return true; | ||
1393 | } | ||
1394 | return vring_need_event(event, new, old); | ||
1395 | } | ||
1396 | |||
1397 | /* This actually signals the guest, using eventfd. */ | ||
1398 | void vhost_signal(struct vhost_dev *dev, struct vhost_virtqueue *vq) | ||
1399 | { | ||
1355 | /* Signal the Guest tell them we used something up. */ | 1400 | /* Signal the Guest tell them we used something up. */ |
1356 | if (vq->call_ctx) | 1401 | if (vq->call_ctx && vhost_notify(dev, vq)) |
1357 | eventfd_signal(vq->call_ctx, 1); | 1402 | eventfd_signal(vq->call_ctx, 1); |
1358 | } | 1403 | } |
1359 | 1404 | ||
@@ -1376,7 +1421,7 @@ void vhost_add_used_and_signal_n(struct vhost_dev *dev, | |||
1376 | } | 1421 | } |
1377 | 1422 | ||
1378 | /* OK, now we need to know about added descriptors. */ | 1423 | /* OK, now we need to know about added descriptors. */ |
1379 | bool vhost_enable_notify(struct vhost_virtqueue *vq) | 1424 | bool vhost_enable_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq) |
1380 | { | 1425 | { |
1381 | u16 avail_idx; | 1426 | u16 avail_idx; |
1382 | int r; | 1427 | int r; |
@@ -1384,11 +1429,34 @@ bool vhost_enable_notify(struct vhost_virtqueue *vq) | |||
1384 | if (!(vq->used_flags & VRING_USED_F_NO_NOTIFY)) | 1429 | if (!(vq->used_flags & VRING_USED_F_NO_NOTIFY)) |
1385 | return false; | 1430 | return false; |
1386 | vq->used_flags &= ~VRING_USED_F_NO_NOTIFY; | 1431 | vq->used_flags &= ~VRING_USED_F_NO_NOTIFY; |
1387 | r = put_user(vq->used_flags, &vq->used->flags); | 1432 | if (!vhost_has_feature(dev, VIRTIO_RING_F_EVENT_IDX)) { |
1388 | if (r) { | 1433 | r = put_user(vq->used_flags, &vq->used->flags); |
1389 | vq_err(vq, "Failed to enable notification at %p: %d\n", | 1434 | if (r) { |
1390 | &vq->used->flags, r); | 1435 | vq_err(vq, "Failed to enable notification at %p: %d\n", |
1391 | return false; | 1436 | &vq->used->flags, r); |
1437 | return false; | ||
1438 | } | ||
1439 | } else { | ||
1440 | r = put_user(vq->avail_idx, vhost_avail_event(vq)); | ||
1441 | if (r) { | ||
1442 | vq_err(vq, "Failed to update avail event index at %p: %d\n", | ||
1443 | vhost_avail_event(vq), r); | ||
1444 | return false; | ||
1445 | } | ||
1446 | } | ||
1447 | if (unlikely(vq->log_used)) { | ||
1448 | void __user *used; | ||
1449 | /* Make sure data is seen before log. */ | ||
1450 | smp_wmb(); | ||
1451 | used = vhost_has_feature(dev, VIRTIO_RING_F_EVENT_IDX) ? | ||
1452 | &vq->used->flags : vhost_avail_event(vq); | ||
1453 | /* Log used flags or event index entry write. Both are 16 bit | ||
1454 | * fields. */ | ||
1455 | log_write(vq->log_base, vq->log_addr + | ||
1456 | (used - (void __user *)vq->used), | ||
1457 | sizeof(u16)); | ||
1458 | if (vq->log_ctx) | ||
1459 | eventfd_signal(vq->log_ctx, 1); | ||
1392 | } | 1460 | } |
1393 | /* They could have slipped one in as we were doing that: make | 1461 | /* They could have slipped one in as we were doing that: make |
1394 | * sure it's written, then check again. */ | 1462 | * sure it's written, then check again. */ |
@@ -1404,15 +1472,17 @@ bool vhost_enable_notify(struct vhost_virtqueue *vq) | |||
1404 | } | 1472 | } |
1405 | 1473 | ||
1406 | /* We don't need to be notified again. */ | 1474 | /* We don't need to be notified again. */ |
1407 | void vhost_disable_notify(struct vhost_virtqueue *vq) | 1475 | void vhost_disable_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq) |
1408 | { | 1476 | { |
1409 | int r; | 1477 | int r; |
1410 | 1478 | ||
1411 | if (vq->used_flags & VRING_USED_F_NO_NOTIFY) | 1479 | if (vq->used_flags & VRING_USED_F_NO_NOTIFY) |
1412 | return; | 1480 | return; |
1413 | vq->used_flags |= VRING_USED_F_NO_NOTIFY; | 1481 | vq->used_flags |= VRING_USED_F_NO_NOTIFY; |
1414 | r = put_user(vq->used_flags, &vq->used->flags); | 1482 | if (!vhost_has_feature(dev, VIRTIO_RING_F_EVENT_IDX)) { |
1415 | if (r) | 1483 | r = put_user(vq->used_flags, &vq->used->flags); |
1416 | vq_err(vq, "Failed to enable notification at %p: %d\n", | 1484 | if (r) |
1417 | &vq->used->flags, r); | 1485 | vq_err(vq, "Failed to enable notification at %p: %d\n", |
1486 | &vq->used->flags, r); | ||
1487 | } | ||
1418 | } | 1488 | } |
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h index b3363ae38518..8e03379dd30f 100644 --- a/drivers/vhost/vhost.h +++ b/drivers/vhost/vhost.h | |||
@@ -84,6 +84,12 @@ struct vhost_virtqueue { | |||
84 | /* Used flags */ | 84 | /* Used flags */ |
85 | u16 used_flags; | 85 | u16 used_flags; |
86 | 86 | ||
87 | /* Last used index value we have signalled on */ | ||
88 | u16 signalled_used; | ||
89 | |||
90 | /* Last used index value we have signalled on */ | ||
91 | bool signalled_used_valid; | ||
92 | |||
87 | /* Log writes to used structure. */ | 93 | /* Log writes to used structure. */ |
88 | bool log_used; | 94 | bool log_used; |
89 | u64 log_addr; | 95 | u64 log_addr; |
@@ -149,8 +155,8 @@ void vhost_add_used_and_signal(struct vhost_dev *, struct vhost_virtqueue *, | |||
149 | void vhost_add_used_and_signal_n(struct vhost_dev *, struct vhost_virtqueue *, | 155 | void vhost_add_used_and_signal_n(struct vhost_dev *, struct vhost_virtqueue *, |
150 | struct vring_used_elem *heads, unsigned count); | 156 | struct vring_used_elem *heads, unsigned count); |
151 | void vhost_signal(struct vhost_dev *, struct vhost_virtqueue *); | 157 | void vhost_signal(struct vhost_dev *, struct vhost_virtqueue *); |
152 | void vhost_disable_notify(struct vhost_virtqueue *); | 158 | void vhost_disable_notify(struct vhost_dev *, struct vhost_virtqueue *); |
153 | bool vhost_enable_notify(struct vhost_virtqueue *); | 159 | bool vhost_enable_notify(struct vhost_dev *, struct vhost_virtqueue *); |
154 | 160 | ||
155 | int vhost_log_write(struct vhost_virtqueue *vq, struct vhost_log *log, | 161 | int vhost_log_write(struct vhost_virtqueue *vq, struct vhost_log *log, |
156 | unsigned int log_num, u64 len); | 162 | unsigned int log_num, u64 len); |
@@ -162,11 +168,12 @@ int vhost_log_write(struct vhost_virtqueue *vq, struct vhost_log *log, | |||
162 | } while (0) | 168 | } while (0) |
163 | 169 | ||
164 | enum { | 170 | enum { |
165 | VHOST_FEATURES = (1 << VIRTIO_F_NOTIFY_ON_EMPTY) | | 171 | VHOST_FEATURES = (1ULL << VIRTIO_F_NOTIFY_ON_EMPTY) | |
166 | (1 << VIRTIO_RING_F_INDIRECT_DESC) | | 172 | (1ULL << VIRTIO_RING_F_INDIRECT_DESC) | |
167 | (1 << VHOST_F_LOG_ALL) | | 173 | (1ULL << VIRTIO_RING_F_EVENT_IDX) | |
168 | (1 << VHOST_NET_F_VIRTIO_NET_HDR) | | 174 | (1ULL << VHOST_F_LOG_ALL) | |
169 | (1 << VIRTIO_NET_F_MRG_RXBUF), | 175 | (1ULL << VHOST_NET_F_VIRTIO_NET_HDR) | |
176 | (1ULL << VIRTIO_NET_F_MRG_RXBUF), | ||
170 | }; | 177 | }; |
171 | 178 | ||
172 | static inline int vhost_has_feature(struct vhost_dev *dev, int bit) | 179 | static inline int vhost_has_feature(struct vhost_dev *dev, int bit) |
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index 0f1da45ba47d..e058ace2a4ad 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c | |||
@@ -40,9 +40,6 @@ struct virtio_balloon | |||
40 | /* Waiting for host to ack the pages we released. */ | 40 | /* Waiting for host to ack the pages we released. */ |
41 | struct completion acked; | 41 | struct completion acked; |
42 | 42 | ||
43 | /* Do we have to tell Host *before* we reuse pages? */ | ||
44 | bool tell_host_first; | ||
45 | |||
46 | /* The pages we've told the Host we're not using. */ | 43 | /* The pages we've told the Host we're not using. */ |
47 | unsigned int num_pages; | 44 | unsigned int num_pages; |
48 | struct list_head pages; | 45 | struct list_head pages; |
@@ -151,13 +148,14 @@ static void leak_balloon(struct virtio_balloon *vb, size_t num) | |||
151 | vb->num_pages--; | 148 | vb->num_pages--; |
152 | } | 149 | } |
153 | 150 | ||
154 | if (vb->tell_host_first) { | 151 | |
155 | tell_host(vb, vb->deflate_vq); | 152 | /* |
156 | release_pages_by_pfn(vb->pfns, vb->num_pfns); | 153 | * Note that if |
157 | } else { | 154 | * virtio_has_feature(vdev, VIRTIO_BALLOON_F_MUST_TELL_HOST); |
158 | release_pages_by_pfn(vb->pfns, vb->num_pfns); | 155 | * is true, we *have* to do it in this order |
159 | tell_host(vb, vb->deflate_vq); | 156 | */ |
160 | } | 157 | tell_host(vb, vb->deflate_vq); |
158 | release_pages_by_pfn(vb->pfns, vb->num_pfns); | ||
161 | } | 159 | } |
162 | 160 | ||
163 | static inline void update_stat(struct virtio_balloon *vb, int idx, | 161 | static inline void update_stat(struct virtio_balloon *vb, int idx, |
@@ -325,9 +323,6 @@ static int virtballoon_probe(struct virtio_device *vdev) | |||
325 | goto out_del_vqs; | 323 | goto out_del_vqs; |
326 | } | 324 | } |
327 | 325 | ||
328 | vb->tell_host_first | ||
329 | = virtio_has_feature(vdev, VIRTIO_BALLOON_F_MUST_TELL_HOST); | ||
330 | |||
331 | return 0; | 326 | return 0; |
332 | 327 | ||
333 | out_del_vqs: | 328 | out_del_vqs: |
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index b0043fb26a4d..68b9136847af 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c | |||
@@ -82,6 +82,9 @@ struct vring_virtqueue | |||
82 | /* Host supports indirect buffers */ | 82 | /* Host supports indirect buffers */ |
83 | bool indirect; | 83 | bool indirect; |
84 | 84 | ||
85 | /* Host publishes avail event idx */ | ||
86 | bool event; | ||
87 | |||
85 | /* Number of free buffers */ | 88 | /* Number of free buffers */ |
86 | unsigned int num_free; | 89 | unsigned int num_free; |
87 | /* Head of free buffer list. */ | 90 | /* Head of free buffer list. */ |
@@ -237,18 +240,22 @@ EXPORT_SYMBOL_GPL(virtqueue_add_buf_gfp); | |||
237 | void virtqueue_kick(struct virtqueue *_vq) | 240 | void virtqueue_kick(struct virtqueue *_vq) |
238 | { | 241 | { |
239 | struct vring_virtqueue *vq = to_vvq(_vq); | 242 | struct vring_virtqueue *vq = to_vvq(_vq); |
243 | u16 new, old; | ||
240 | START_USE(vq); | 244 | START_USE(vq); |
241 | /* Descriptors and available array need to be set before we expose the | 245 | /* Descriptors and available array need to be set before we expose the |
242 | * new available array entries. */ | 246 | * new available array entries. */ |
243 | virtio_wmb(); | 247 | virtio_wmb(); |
244 | 248 | ||
245 | vq->vring.avail->idx += vq->num_added; | 249 | old = vq->vring.avail->idx; |
250 | new = vq->vring.avail->idx = old + vq->num_added; | ||
246 | vq->num_added = 0; | 251 | vq->num_added = 0; |
247 | 252 | ||
248 | /* Need to update avail index before checking if we should notify */ | 253 | /* Need to update avail index before checking if we should notify */ |
249 | virtio_mb(); | 254 | virtio_mb(); |
250 | 255 | ||
251 | if (!(vq->vring.used->flags & VRING_USED_F_NO_NOTIFY)) | 256 | if (vq->event ? |
257 | vring_need_event(vring_avail_event(&vq->vring), new, old) : | ||
258 | !(vq->vring.used->flags & VRING_USED_F_NO_NOTIFY)) | ||
252 | /* Prod other side to tell it about changes. */ | 259 | /* Prod other side to tell it about changes. */ |
253 | vq->notify(&vq->vq); | 260 | vq->notify(&vq->vq); |
254 | 261 | ||
@@ -324,6 +331,14 @@ void *virtqueue_get_buf(struct virtqueue *_vq, unsigned int *len) | |||
324 | ret = vq->data[i]; | 331 | ret = vq->data[i]; |
325 | detach_buf(vq, i); | 332 | detach_buf(vq, i); |
326 | vq->last_used_idx++; | 333 | vq->last_used_idx++; |
334 | /* If we expect an interrupt for the next entry, tell host | ||
335 | * by writing event index and flush out the write before | ||
336 | * the read in the next get_buf call. */ | ||
337 | if (!(vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT)) { | ||
338 | vring_used_event(&vq->vring) = vq->last_used_idx; | ||
339 | virtio_mb(); | ||
340 | } | ||
341 | |||
327 | END_USE(vq); | 342 | END_USE(vq); |
328 | return ret; | 343 | return ret; |
329 | } | 344 | } |
@@ -345,7 +360,11 @@ bool virtqueue_enable_cb(struct virtqueue *_vq) | |||
345 | 360 | ||
346 | /* We optimistically turn back on interrupts, then check if there was | 361 | /* We optimistically turn back on interrupts, then check if there was |
347 | * more to do. */ | 362 | * more to do. */ |
363 | /* Depending on the VIRTIO_RING_F_EVENT_IDX feature, we need to | ||
364 | * either clear the flags bit or point the event index at the next | ||
365 | * entry. Always do both to keep code simple. */ | ||
348 | vq->vring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT; | 366 | vq->vring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT; |
367 | vring_used_event(&vq->vring) = vq->last_used_idx; | ||
349 | virtio_mb(); | 368 | virtio_mb(); |
350 | if (unlikely(more_used(vq))) { | 369 | if (unlikely(more_used(vq))) { |
351 | END_USE(vq); | 370 | END_USE(vq); |
@@ -357,6 +376,33 @@ bool virtqueue_enable_cb(struct virtqueue *_vq) | |||
357 | } | 376 | } |
358 | EXPORT_SYMBOL_GPL(virtqueue_enable_cb); | 377 | EXPORT_SYMBOL_GPL(virtqueue_enable_cb); |
359 | 378 | ||
379 | bool virtqueue_enable_cb_delayed(struct virtqueue *_vq) | ||
380 | { | ||
381 | struct vring_virtqueue *vq = to_vvq(_vq); | ||
382 | u16 bufs; | ||
383 | |||
384 | START_USE(vq); | ||
385 | |||
386 | /* We optimistically turn back on interrupts, then check if there was | ||
387 | * more to do. */ | ||
388 | /* Depending on the VIRTIO_RING_F_USED_EVENT_IDX feature, we need to | ||
389 | * either clear the flags bit or point the event index at the next | ||
390 | * entry. Always do both to keep code simple. */ | ||
391 | vq->vring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT; | ||
392 | /* TODO: tune this threshold */ | ||
393 | bufs = (u16)(vq->vring.avail->idx - vq->last_used_idx) * 3 / 4; | ||
394 | vring_used_event(&vq->vring) = vq->last_used_idx + bufs; | ||
395 | virtio_mb(); | ||
396 | if (unlikely((u16)(vq->vring.used->idx - vq->last_used_idx) > bufs)) { | ||
397 | END_USE(vq); | ||
398 | return false; | ||
399 | } | ||
400 | |||
401 | END_USE(vq); | ||
402 | return true; | ||
403 | } | ||
404 | EXPORT_SYMBOL_GPL(virtqueue_enable_cb_delayed); | ||
405 | |||
360 | void *virtqueue_detach_unused_buf(struct virtqueue *_vq) | 406 | void *virtqueue_detach_unused_buf(struct virtqueue *_vq) |
361 | { | 407 | { |
362 | struct vring_virtqueue *vq = to_vvq(_vq); | 408 | struct vring_virtqueue *vq = to_vvq(_vq); |
@@ -438,6 +484,7 @@ struct virtqueue *vring_new_virtqueue(unsigned int num, | |||
438 | #endif | 484 | #endif |
439 | 485 | ||
440 | vq->indirect = virtio_has_feature(vdev, VIRTIO_RING_F_INDIRECT_DESC); | 486 | vq->indirect = virtio_has_feature(vdev, VIRTIO_RING_F_INDIRECT_DESC); |
487 | vq->event = virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX); | ||
441 | 488 | ||
442 | /* No callback? Tell other side not to bother us. */ | 489 | /* No callback? Tell other side not to bother us. */ |
443 | if (!callback) | 490 | if (!callback) |
@@ -472,6 +519,8 @@ void vring_transport_features(struct virtio_device *vdev) | |||
472 | switch (i) { | 519 | switch (i) { |
473 | case VIRTIO_RING_F_INDIRECT_DESC: | 520 | case VIRTIO_RING_F_INDIRECT_DESC: |
474 | break; | 521 | break; |
522 | case VIRTIO_RING_F_EVENT_IDX: | ||
523 | break; | ||
475 | default: | 524 | default: |
476 | /* We don't understand this bit. */ | 525 | /* We don't understand this bit. */ |
477 | clear_bit(i, vdev->features); | 526 | clear_bit(i, vdev->features); |
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 8d7f3e69ae29..7f6c67703195 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -814,7 +814,6 @@ int v9fs_vfs_unlink(struct inode *i, struct dentry *d) | |||
814 | 814 | ||
815 | int v9fs_vfs_rmdir(struct inode *i, struct dentry *d) | 815 | int v9fs_vfs_rmdir(struct inode *i, struct dentry *d) |
816 | { | 816 | { |
817 | dentry_unhash(d); | ||
818 | return v9fs_remove(i, d, 1); | 817 | return v9fs_remove(i, d, 1); |
819 | } | 818 | } |
820 | 819 | ||
@@ -840,9 +839,6 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
840 | struct p9_fid *newdirfid; | 839 | struct p9_fid *newdirfid; |
841 | struct p9_wstat wstat; | 840 | struct p9_wstat wstat; |
842 | 841 | ||
843 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | ||
844 | dentry_unhash(new_dentry); | ||
845 | |||
846 | P9_DPRINTK(P9_DEBUG_VFS, "\n"); | 842 | P9_DPRINTK(P9_DEBUG_VFS, "\n"); |
847 | retval = 0; | 843 | retval = 0; |
848 | old_inode = old_dentry->d_inode; | 844 | old_inode = old_dentry->d_inode; |
diff --git a/fs/affs/namei.c b/fs/affs/namei.c index 03330e2e390c..e3e9efc1fdd8 100644 --- a/fs/affs/namei.c +++ b/fs/affs/namei.c | |||
@@ -320,8 +320,6 @@ affs_rmdir(struct inode *dir, struct dentry *dentry) | |||
320 | dentry->d_inode->i_ino, | 320 | dentry->d_inode->i_ino, |
321 | (int)dentry->d_name.len, dentry->d_name.name); | 321 | (int)dentry->d_name.len, dentry->d_name.name); |
322 | 322 | ||
323 | dentry_unhash(dentry); | ||
324 | |||
325 | return affs_remove_header(dentry); | 323 | return affs_remove_header(dentry); |
326 | } | 324 | } |
327 | 325 | ||
@@ -419,9 +417,6 @@ affs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
419 | struct buffer_head *bh = NULL; | 417 | struct buffer_head *bh = NULL; |
420 | int retval; | 418 | int retval; |
421 | 419 | ||
422 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | ||
423 | dentry_unhash(new_dentry); | ||
424 | |||
425 | pr_debug("AFFS: rename(old=%u,\"%*s\" to new=%u,\"%*s\")\n", | 420 | pr_debug("AFFS: rename(old=%u,\"%*s\" to new=%u,\"%*s\")\n", |
426 | (u32)old_dir->i_ino, (int)old_dentry->d_name.len, old_dentry->d_name.name, | 421 | (u32)old_dir->i_ino, (int)old_dentry->d_name.len, old_dentry->d_name.name, |
427 | (u32)new_dir->i_ino, (int)new_dentry->d_name.len, new_dentry->d_name.name); | 422 | (u32)new_dir->i_ino, (int)new_dentry->d_name.len, new_dentry->d_name.name); |
diff --git a/fs/afs/dir.c b/fs/afs/dir.c index 2c4e05160042..20c106f24927 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c | |||
@@ -845,8 +845,6 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry) | |||
845 | _enter("{%x:%u},{%s}", | 845 | _enter("{%x:%u},{%s}", |
846 | dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name); | 846 | dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name); |
847 | 847 | ||
848 | dentry_unhash(dentry); | ||
849 | |||
850 | ret = -ENAMETOOLONG; | 848 | ret = -ENAMETOOLONG; |
851 | if (dentry->d_name.len >= AFSNAMEMAX) | 849 | if (dentry->d_name.len >= AFSNAMEMAX) |
852 | goto error; | 850 | goto error; |
@@ -1148,9 +1146,6 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1148 | struct key *key; | 1146 | struct key *key; |
1149 | int ret; | 1147 | int ret; |
1150 | 1148 | ||
1151 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | ||
1152 | dentry_unhash(new_dentry); | ||
1153 | |||
1154 | vnode = AFS_FS_I(old_dentry->d_inode); | 1149 | vnode = AFS_FS_I(old_dentry->d_inode); |
1155 | orig_dvnode = AFS_FS_I(old_dir); | 1150 | orig_dvnode = AFS_FS_I(old_dir); |
1156 | new_dvnode = AFS_FS_I(new_dir); | 1151 | new_dvnode = AFS_FS_I(new_dir); |
@@ -175,6 +175,13 @@ int notify_change(struct dentry * dentry, struct iattr * attr) | |||
175 | return -EPERM; | 175 | return -EPERM; |
176 | } | 176 | } |
177 | 177 | ||
178 | if ((ia_valid & ATTR_MODE)) { | ||
179 | mode_t amode = attr->ia_mode; | ||
180 | /* Flag setting protected by i_mutex */ | ||
181 | if (is_sxid(amode)) | ||
182 | inode->i_flags &= ~S_NOSEC; | ||
183 | } | ||
184 | |||
178 | now = current_fs_time(inode->i_sb); | 185 | now = current_fs_time(inode->i_sb); |
179 | 186 | ||
180 | attr->ia_ctime = now; | 187 | attr->ia_ctime = now; |
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index 87d95a8cddbc..f55ae23b137e 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c | |||
@@ -583,8 +583,6 @@ static int autofs4_dir_unlink(struct inode *dir, struct dentry *dentry) | |||
583 | if (!autofs4_oz_mode(sbi) && !capable(CAP_SYS_ADMIN)) | 583 | if (!autofs4_oz_mode(sbi) && !capable(CAP_SYS_ADMIN)) |
584 | return -EACCES; | 584 | return -EACCES; |
585 | 585 | ||
586 | dentry_unhash(dentry); | ||
587 | |||
588 | if (atomic_dec_and_test(&ino->count)) { | 586 | if (atomic_dec_and_test(&ino->count)) { |
589 | p_ino = autofs4_dentry_ino(dentry->d_parent); | 587 | p_ino = autofs4_dentry_ino(dentry->d_parent); |
590 | if (p_ino && dentry->d_parent != dentry) | 588 | if (p_ino && dentry->d_parent != dentry) |
diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c index c7d1d06b0483..b14cebfd9047 100644 --- a/fs/bfs/dir.c +++ b/fs/bfs/dir.c | |||
@@ -224,9 +224,6 @@ static int bfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
224 | struct bfs_sb_info *info; | 224 | struct bfs_sb_info *info; |
225 | int error = -ENOENT; | 225 | int error = -ENOENT; |
226 | 226 | ||
227 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | ||
228 | dentry_unhash(new_dentry); | ||
229 | |||
230 | old_bh = new_bh = NULL; | 227 | old_bh = new_bh = NULL; |
231 | old_inode = old_dentry->d_inode; | 228 | old_inode = old_dentry->d_inode; |
232 | if (S_ISDIR(old_inode->i_mode)) | 229 | if (S_ISDIR(old_inode->i_mode)) |
@@ -638,10 +638,11 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page | |||
638 | * @offset: vec entry offset | 638 | * @offset: vec entry offset |
639 | * | 639 | * |
640 | * Attempt to add a page to the bio_vec maplist. This can fail for a | 640 | * Attempt to add a page to the bio_vec maplist. This can fail for a |
641 | * number of reasons, such as the bio being full or target block | 641 | * number of reasons, such as the bio being full or target block device |
642 | * device limitations. The target block device must allow bio's | 642 | * limitations. The target block device must allow bio's up to PAGE_SIZE, |
643 | * smaller than PAGE_SIZE, so it is always possible to add a single | 643 | * so it is always possible to add a single page to an empty bio. |
644 | * page to an empty bio. This should only be used by REQ_PC bios. | 644 | * |
645 | * This should only be used by REQ_PC bios. | ||
645 | */ | 646 | */ |
646 | int bio_add_pc_page(struct request_queue *q, struct bio *bio, struct page *page, | 647 | int bio_add_pc_page(struct request_queue *q, struct bio *bio, struct page *page, |
647 | unsigned int len, unsigned int offset) | 648 | unsigned int len, unsigned int offset) |
@@ -659,10 +660,9 @@ EXPORT_SYMBOL(bio_add_pc_page); | |||
659 | * @offset: vec entry offset | 660 | * @offset: vec entry offset |
660 | * | 661 | * |
661 | * Attempt to add a page to the bio_vec maplist. This can fail for a | 662 | * Attempt to add a page to the bio_vec maplist. This can fail for a |
662 | * number of reasons, such as the bio being full or target block | 663 | * number of reasons, such as the bio being full or target block device |
663 | * device limitations. The target block device must allow bio's | 664 | * limitations. The target block device must allow bio's up to PAGE_SIZE, |
664 | * smaller than PAGE_SIZE, so it is always possible to add a single | 665 | * so it is always possible to add a single page to an empty bio. |
665 | * page to an empty bio. | ||
666 | */ | 666 | */ |
667 | int bio_add_page(struct bio *bio, struct page *page, unsigned int len, | 667 | int bio_add_page(struct bio *bio, struct page *page, unsigned int len, |
668 | unsigned int offset) | 668 | unsigned int offset) |
diff --git a/fs/block_dev.c b/fs/block_dev.c index 1f2b19978333..1a2421f908f0 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -1272,8 +1272,8 @@ int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder) | |||
1272 | * individual writeable reference is too fragile given the | 1272 | * individual writeable reference is too fragile given the |
1273 | * way @mode is used in blkdev_get/put(). | 1273 | * way @mode is used in blkdev_get/put(). |
1274 | */ | 1274 | */ |
1275 | if ((disk->flags & GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE) && | 1275 | if (!res && (mode & FMODE_WRITE) && !bdev->bd_write_holder && |
1276 | !res && (mode & FMODE_WRITE) && !bdev->bd_write_holder) { | 1276 | (disk->flags & GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE)) { |
1277 | bdev->bd_write_holder = true; | 1277 | bdev->bd_write_holder = true; |
1278 | disk_block_events(disk); | 1278 | disk_block_events(disk); |
1279 | } | 1279 | } |
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h index 93b1aa932014..52d7eca8c7bf 100644 --- a/fs/btrfs/btrfs_inode.h +++ b/fs/btrfs/btrfs_inode.h | |||
@@ -121,9 +121,6 @@ struct btrfs_inode { | |||
121 | */ | 121 | */ |
122 | u64 index_cnt; | 122 | u64 index_cnt; |
123 | 123 | ||
124 | /* the start of block group preferred for allocations. */ | ||
125 | u64 block_group; | ||
126 | |||
127 | /* the fsync log has some corner cases that mean we have to check | 124 | /* the fsync log has some corner cases that mean we have to check |
128 | * directories to see if any unlinks have been done before | 125 | * directories to see if any unlinks have been done before |
129 | * the directory was logged. See tree-log.c for all the | 126 | * the directory was logged. See tree-log.c for all the |
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index b0e18d986e0a..d84089349c82 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -43,8 +43,6 @@ struct btrfs_path *btrfs_alloc_path(void) | |||
43 | { | 43 | { |
44 | struct btrfs_path *path; | 44 | struct btrfs_path *path; |
45 | path = kmem_cache_zalloc(btrfs_path_cachep, GFP_NOFS); | 45 | path = kmem_cache_zalloc(btrfs_path_cachep, GFP_NOFS); |
46 | if (path) | ||
47 | path->reada = 1; | ||
48 | return path; | 46 | return path; |
49 | } | 47 | } |
50 | 48 | ||
@@ -1224,6 +1222,7 @@ static void reada_for_search(struct btrfs_root *root, | |||
1224 | u64 search; | 1222 | u64 search; |
1225 | u64 target; | 1223 | u64 target; |
1226 | u64 nread = 0; | 1224 | u64 nread = 0; |
1225 | u64 gen; | ||
1227 | int direction = path->reada; | 1226 | int direction = path->reada; |
1228 | struct extent_buffer *eb; | 1227 | struct extent_buffer *eb; |
1229 | u32 nr; | 1228 | u32 nr; |
@@ -1251,6 +1250,15 @@ static void reada_for_search(struct btrfs_root *root, | |||
1251 | nritems = btrfs_header_nritems(node); | 1250 | nritems = btrfs_header_nritems(node); |
1252 | nr = slot; | 1251 | nr = slot; |
1253 | while (1) { | 1252 | while (1) { |
1253 | if (!node->map_token) { | ||
1254 | unsigned long offset = btrfs_node_key_ptr_offset(nr); | ||
1255 | map_private_extent_buffer(node, offset, | ||
1256 | sizeof(struct btrfs_key_ptr), | ||
1257 | &node->map_token, | ||
1258 | &node->kaddr, | ||
1259 | &node->map_start, | ||
1260 | &node->map_len, KM_USER1); | ||
1261 | } | ||
1254 | if (direction < 0) { | 1262 | if (direction < 0) { |
1255 | if (nr == 0) | 1263 | if (nr == 0) |
1256 | break; | 1264 | break; |
@@ -1268,14 +1276,23 @@ static void reada_for_search(struct btrfs_root *root, | |||
1268 | search = btrfs_node_blockptr(node, nr); | 1276 | search = btrfs_node_blockptr(node, nr); |
1269 | if ((search <= target && target - search <= 65536) || | 1277 | if ((search <= target && target - search <= 65536) || |
1270 | (search > target && search - target <= 65536)) { | 1278 | (search > target && search - target <= 65536)) { |
1271 | readahead_tree_block(root, search, blocksize, | 1279 | gen = btrfs_node_ptr_generation(node, nr); |
1272 | btrfs_node_ptr_generation(node, nr)); | 1280 | if (node->map_token) { |
1281 | unmap_extent_buffer(node, node->map_token, | ||
1282 | KM_USER1); | ||
1283 | node->map_token = NULL; | ||
1284 | } | ||
1285 | readahead_tree_block(root, search, blocksize, gen); | ||
1273 | nread += blocksize; | 1286 | nread += blocksize; |
1274 | } | 1287 | } |
1275 | nscan++; | 1288 | nscan++; |
1276 | if ((nread > 65536 || nscan > 32)) | 1289 | if ((nread > 65536 || nscan > 32)) |
1277 | break; | 1290 | break; |
1278 | } | 1291 | } |
1292 | if (node->map_token) { | ||
1293 | unmap_extent_buffer(node, node->map_token, KM_USER1); | ||
1294 | node->map_token = NULL; | ||
1295 | } | ||
1279 | } | 1296 | } |
1280 | 1297 | ||
1281 | /* | 1298 | /* |
@@ -1648,9 +1665,6 @@ again: | |||
1648 | } | 1665 | } |
1649 | cow_done: | 1666 | cow_done: |
1650 | BUG_ON(!cow && ins_len); | 1667 | BUG_ON(!cow && ins_len); |
1651 | if (level != btrfs_header_level(b)) | ||
1652 | WARN_ON(1); | ||
1653 | level = btrfs_header_level(b); | ||
1654 | 1668 | ||
1655 | p->nodes[level] = b; | 1669 | p->nodes[level] = b; |
1656 | if (!p->skip_locking) | 1670 | if (!p->skip_locking) |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 332323e19dd1..378b5b4443f3 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -930,7 +930,6 @@ struct btrfs_fs_info { | |||
930 | * is required instead of the faster short fsync log commits | 930 | * is required instead of the faster short fsync log commits |
931 | */ | 931 | */ |
932 | u64 last_trans_log_full_commit; | 932 | u64 last_trans_log_full_commit; |
933 | u64 open_ioctl_trans; | ||
934 | unsigned long mount_opt:20; | 933 | unsigned long mount_opt:20; |
935 | unsigned long compress_type:4; | 934 | unsigned long compress_type:4; |
936 | u64 max_inline; | 935 | u64 max_inline; |
@@ -947,7 +946,6 @@ struct btrfs_fs_info { | |||
947 | struct super_block *sb; | 946 | struct super_block *sb; |
948 | struct inode *btree_inode; | 947 | struct inode *btree_inode; |
949 | struct backing_dev_info bdi; | 948 | struct backing_dev_info bdi; |
950 | struct mutex trans_mutex; | ||
951 | struct mutex tree_log_mutex; | 949 | struct mutex tree_log_mutex; |
952 | struct mutex transaction_kthread_mutex; | 950 | struct mutex transaction_kthread_mutex; |
953 | struct mutex cleaner_mutex; | 951 | struct mutex cleaner_mutex; |
@@ -968,6 +966,7 @@ struct btrfs_fs_info { | |||
968 | struct rw_semaphore subvol_sem; | 966 | struct rw_semaphore subvol_sem; |
969 | struct srcu_struct subvol_srcu; | 967 | struct srcu_struct subvol_srcu; |
970 | 968 | ||
969 | spinlock_t trans_lock; | ||
971 | struct list_head trans_list; | 970 | struct list_head trans_list; |
972 | struct list_head hashers; | 971 | struct list_head hashers; |
973 | struct list_head dead_roots; | 972 | struct list_head dead_roots; |
@@ -980,6 +979,7 @@ struct btrfs_fs_info { | |||
980 | atomic_t async_submit_draining; | 979 | atomic_t async_submit_draining; |
981 | atomic_t nr_async_bios; | 980 | atomic_t nr_async_bios; |
982 | atomic_t async_delalloc_pages; | 981 | atomic_t async_delalloc_pages; |
982 | atomic_t open_ioctl_trans; | ||
983 | 983 | ||
984 | /* | 984 | /* |
985 | * this is used by the balancing code to wait for all the pending | 985 | * this is used by the balancing code to wait for all the pending |
@@ -1044,6 +1044,7 @@ struct btrfs_fs_info { | |||
1044 | int closing; | 1044 | int closing; |
1045 | int log_root_recovering; | 1045 | int log_root_recovering; |
1046 | int enospc_unlink; | 1046 | int enospc_unlink; |
1047 | int trans_no_join; | ||
1047 | 1048 | ||
1048 | u64 total_pinned; | 1049 | u64 total_pinned; |
1049 | 1050 | ||
@@ -1065,7 +1066,6 @@ struct btrfs_fs_info { | |||
1065 | struct reloc_control *reloc_ctl; | 1066 | struct reloc_control *reloc_ctl; |
1066 | 1067 | ||
1067 | spinlock_t delalloc_lock; | 1068 | spinlock_t delalloc_lock; |
1068 | spinlock_t new_trans_lock; | ||
1069 | u64 delalloc_bytes; | 1069 | u64 delalloc_bytes; |
1070 | 1070 | ||
1071 | /* data_alloc_cluster is only used in ssd mode */ | 1071 | /* data_alloc_cluster is only used in ssd mode */ |
@@ -1340,6 +1340,7 @@ struct btrfs_ioctl_defrag_range_args { | |||
1340 | #define BTRFS_MOUNT_USER_SUBVOL_RM_ALLOWED (1 << 14) | 1340 | #define BTRFS_MOUNT_USER_SUBVOL_RM_ALLOWED (1 << 14) |
1341 | #define BTRFS_MOUNT_ENOSPC_DEBUG (1 << 15) | 1341 | #define BTRFS_MOUNT_ENOSPC_DEBUG (1 << 15) |
1342 | #define BTRFS_MOUNT_AUTO_DEFRAG (1 << 16) | 1342 | #define BTRFS_MOUNT_AUTO_DEFRAG (1 << 16) |
1343 | #define BTRFS_MOUNT_INODE_MAP_CACHE (1 << 17) | ||
1343 | 1344 | ||
1344 | #define btrfs_clear_opt(o, opt) ((o) &= ~BTRFS_MOUNT_##opt) | 1345 | #define btrfs_clear_opt(o, opt) ((o) &= ~BTRFS_MOUNT_##opt) |
1345 | #define btrfs_set_opt(o, opt) ((o) |= BTRFS_MOUNT_##opt) | 1346 | #define btrfs_set_opt(o, opt) ((o) |= BTRFS_MOUNT_##opt) |
@@ -2238,6 +2239,9 @@ int btrfs_block_rsv_migrate(struct btrfs_block_rsv *src_rsv, | |||
2238 | void btrfs_block_rsv_release(struct btrfs_root *root, | 2239 | void btrfs_block_rsv_release(struct btrfs_root *root, |
2239 | struct btrfs_block_rsv *block_rsv, | 2240 | struct btrfs_block_rsv *block_rsv, |
2240 | u64 num_bytes); | 2241 | u64 num_bytes); |
2242 | int btrfs_truncate_reserve_metadata(struct btrfs_trans_handle *trans, | ||
2243 | struct btrfs_root *root, | ||
2244 | struct btrfs_block_rsv *rsv); | ||
2241 | int btrfs_set_block_group_ro(struct btrfs_root *root, | 2245 | int btrfs_set_block_group_ro(struct btrfs_root *root, |
2242 | struct btrfs_block_group_cache *cache); | 2246 | struct btrfs_block_group_cache *cache); |
2243 | int btrfs_set_block_group_rw(struct btrfs_root *root, | 2247 | int btrfs_set_block_group_rw(struct btrfs_root *root, |
@@ -2350,6 +2354,15 @@ int btrfs_drop_subtree(struct btrfs_trans_handle *trans, | |||
2350 | struct btrfs_root *root, | 2354 | struct btrfs_root *root, |
2351 | struct extent_buffer *node, | 2355 | struct extent_buffer *node, |
2352 | struct extent_buffer *parent); | 2356 | struct extent_buffer *parent); |
2357 | static inline int btrfs_fs_closing(struct btrfs_fs_info *fs_info) | ||
2358 | { | ||
2359 | /* | ||
2360 | * Get synced with close_ctree() | ||
2361 | */ | ||
2362 | smp_mb(); | ||
2363 | return fs_info->closing; | ||
2364 | } | ||
2365 | |||
2353 | /* root-item.c */ | 2366 | /* root-item.c */ |
2354 | int btrfs_find_root_ref(struct btrfs_root *tree_root, | 2367 | int btrfs_find_root_ref(struct btrfs_root *tree_root, |
2355 | struct btrfs_path *path, | 2368 | struct btrfs_path *path, |
@@ -2512,8 +2525,7 @@ int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end, | |||
2512 | int btrfs_writepages(struct address_space *mapping, | 2525 | int btrfs_writepages(struct address_space *mapping, |
2513 | struct writeback_control *wbc); | 2526 | struct writeback_control *wbc); |
2514 | int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, | 2527 | int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, |
2515 | struct btrfs_root *new_root, | 2528 | struct btrfs_root *new_root, u64 new_dirid); |
2516 | u64 new_dirid, u64 alloc_hint); | ||
2517 | int btrfs_merge_bio_hook(struct page *page, unsigned long offset, | 2529 | int btrfs_merge_bio_hook(struct page *page, unsigned long offset, |
2518 | size_t size, struct bio *bio, unsigned long bio_flags); | 2530 | size_t size, struct bio *bio, unsigned long bio_flags); |
2519 | 2531 | ||
@@ -2524,7 +2536,7 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf); | |||
2524 | int btrfs_readpage(struct file *file, struct page *page); | 2536 | int btrfs_readpage(struct file *file, struct page *page); |
2525 | void btrfs_evict_inode(struct inode *inode); | 2537 | void btrfs_evict_inode(struct inode *inode); |
2526 | int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc); | 2538 | int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc); |
2527 | void btrfs_dirty_inode(struct inode *inode); | 2539 | void btrfs_dirty_inode(struct inode *inode, int flags); |
2528 | struct inode *btrfs_alloc_inode(struct super_block *sb); | 2540 | struct inode *btrfs_alloc_inode(struct super_block *sb); |
2529 | void btrfs_destroy_inode(struct inode *inode); | 2541 | void btrfs_destroy_inode(struct inode *inode); |
2530 | int btrfs_drop_inode(struct inode *inode); | 2542 | int btrfs_drop_inode(struct inode *inode); |
diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c index 01e29503a54b..6462c29d2d37 100644 --- a/fs/btrfs/delayed-inode.c +++ b/fs/btrfs/delayed-inode.c | |||
@@ -678,6 +678,7 @@ static int btrfs_batch_insert_items(struct btrfs_trans_handle *trans, | |||
678 | INIT_LIST_HEAD(&head); | 678 | INIT_LIST_HEAD(&head); |
679 | 679 | ||
680 | next = item; | 680 | next = item; |
681 | nitems = 0; | ||
681 | 682 | ||
682 | /* | 683 | /* |
683 | * count the number of the continuous items that we can insert in batch | 684 | * count the number of the continuous items that we can insert in batch |
@@ -1129,7 +1130,7 @@ static void btrfs_async_run_delayed_node_done(struct btrfs_work *work) | |||
1129 | delayed_node = async_node->delayed_node; | 1130 | delayed_node = async_node->delayed_node; |
1130 | root = delayed_node->root; | 1131 | root = delayed_node->root; |
1131 | 1132 | ||
1132 | trans = btrfs_join_transaction(root, 0); | 1133 | trans = btrfs_join_transaction(root); |
1133 | if (IS_ERR(trans)) | 1134 | if (IS_ERR(trans)) |
1134 | goto free_path; | 1135 | goto free_path; |
1135 | 1136 | ||
@@ -1572,8 +1573,7 @@ static void fill_stack_inode_item(struct btrfs_trans_handle *trans, | |||
1572 | btrfs_set_stack_inode_transid(inode_item, trans->transid); | 1573 | btrfs_set_stack_inode_transid(inode_item, trans->transid); |
1573 | btrfs_set_stack_inode_rdev(inode_item, inode->i_rdev); | 1574 | btrfs_set_stack_inode_rdev(inode_item, inode->i_rdev); |
1574 | btrfs_set_stack_inode_flags(inode_item, BTRFS_I(inode)->flags); | 1575 | btrfs_set_stack_inode_flags(inode_item, BTRFS_I(inode)->flags); |
1575 | btrfs_set_stack_inode_block_group(inode_item, | 1576 | btrfs_set_stack_inode_block_group(inode_item, 0); |
1576 | BTRFS_I(inode)->block_group); | ||
1577 | 1577 | ||
1578 | btrfs_set_stack_timespec_sec(btrfs_inode_atime(inode_item), | 1578 | btrfs_set_stack_timespec_sec(btrfs_inode_atime(inode_item), |
1579 | inode->i_atime.tv_sec); | 1579 | inode->i_atime.tv_sec); |
@@ -1595,7 +1595,7 @@ int btrfs_delayed_update_inode(struct btrfs_trans_handle *trans, | |||
1595 | struct btrfs_root *root, struct inode *inode) | 1595 | struct btrfs_root *root, struct inode *inode) |
1596 | { | 1596 | { |
1597 | struct btrfs_delayed_node *delayed_node; | 1597 | struct btrfs_delayed_node *delayed_node; |
1598 | int ret; | 1598 | int ret = 0; |
1599 | 1599 | ||
1600 | delayed_node = btrfs_get_or_create_delayed_node(inode); | 1600 | delayed_node = btrfs_get_or_create_delayed_node(inode); |
1601 | if (IS_ERR(delayed_node)) | 1601 | if (IS_ERR(delayed_node)) |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 98b6a71decba..a203d363184d 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -1505,24 +1505,24 @@ static int transaction_kthread(void *arg) | |||
1505 | vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE); | 1505 | vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE); |
1506 | mutex_lock(&root->fs_info->transaction_kthread_mutex); | 1506 | mutex_lock(&root->fs_info->transaction_kthread_mutex); |
1507 | 1507 | ||
1508 | spin_lock(&root->fs_info->new_trans_lock); | 1508 | spin_lock(&root->fs_info->trans_lock); |
1509 | cur = root->fs_info->running_transaction; | 1509 | cur = root->fs_info->running_transaction; |
1510 | if (!cur) { | 1510 | if (!cur) { |
1511 | spin_unlock(&root->fs_info->new_trans_lock); | 1511 | spin_unlock(&root->fs_info->trans_lock); |
1512 | goto sleep; | 1512 | goto sleep; |
1513 | } | 1513 | } |
1514 | 1514 | ||
1515 | now = get_seconds(); | 1515 | now = get_seconds(); |
1516 | if (!cur->blocked && | 1516 | if (!cur->blocked && |
1517 | (now < cur->start_time || now - cur->start_time < 30)) { | 1517 | (now < cur->start_time || now - cur->start_time < 30)) { |
1518 | spin_unlock(&root->fs_info->new_trans_lock); | 1518 | spin_unlock(&root->fs_info->trans_lock); |
1519 | delay = HZ * 5; | 1519 | delay = HZ * 5; |
1520 | goto sleep; | 1520 | goto sleep; |
1521 | } | 1521 | } |
1522 | transid = cur->transid; | 1522 | transid = cur->transid; |
1523 | spin_unlock(&root->fs_info->new_trans_lock); | 1523 | spin_unlock(&root->fs_info->trans_lock); |
1524 | 1524 | ||
1525 | trans = btrfs_join_transaction(root, 1); | 1525 | trans = btrfs_join_transaction(root); |
1526 | BUG_ON(IS_ERR(trans)); | 1526 | BUG_ON(IS_ERR(trans)); |
1527 | if (transid == trans->transid) { | 1527 | if (transid == trans->transid) { |
1528 | ret = btrfs_commit_transaction(trans, root); | 1528 | ret = btrfs_commit_transaction(trans, root); |
@@ -1613,7 +1613,7 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1613 | INIT_LIST_HEAD(&fs_info->ordered_operations); | 1613 | INIT_LIST_HEAD(&fs_info->ordered_operations); |
1614 | INIT_LIST_HEAD(&fs_info->caching_block_groups); | 1614 | INIT_LIST_HEAD(&fs_info->caching_block_groups); |
1615 | spin_lock_init(&fs_info->delalloc_lock); | 1615 | spin_lock_init(&fs_info->delalloc_lock); |
1616 | spin_lock_init(&fs_info->new_trans_lock); | 1616 | spin_lock_init(&fs_info->trans_lock); |
1617 | spin_lock_init(&fs_info->ref_cache_lock); | 1617 | spin_lock_init(&fs_info->ref_cache_lock); |
1618 | spin_lock_init(&fs_info->fs_roots_radix_lock); | 1618 | spin_lock_init(&fs_info->fs_roots_radix_lock); |
1619 | spin_lock_init(&fs_info->delayed_iput_lock); | 1619 | spin_lock_init(&fs_info->delayed_iput_lock); |
@@ -1645,6 +1645,7 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1645 | fs_info->max_inline = 8192 * 1024; | 1645 | fs_info->max_inline = 8192 * 1024; |
1646 | fs_info->metadata_ratio = 0; | 1646 | fs_info->metadata_ratio = 0; |
1647 | fs_info->defrag_inodes = RB_ROOT; | 1647 | fs_info->defrag_inodes = RB_ROOT; |
1648 | fs_info->trans_no_join = 0; | ||
1648 | 1649 | ||
1649 | fs_info->thread_pool_size = min_t(unsigned long, | 1650 | fs_info->thread_pool_size = min_t(unsigned long, |
1650 | num_online_cpus() + 2, 8); | 1651 | num_online_cpus() + 2, 8); |
@@ -1709,7 +1710,6 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1709 | fs_info->do_barriers = 1; | 1710 | fs_info->do_barriers = 1; |
1710 | 1711 | ||
1711 | 1712 | ||
1712 | mutex_init(&fs_info->trans_mutex); | ||
1713 | mutex_init(&fs_info->ordered_operations_mutex); | 1713 | mutex_init(&fs_info->ordered_operations_mutex); |
1714 | mutex_init(&fs_info->tree_log_mutex); | 1714 | mutex_init(&fs_info->tree_log_mutex); |
1715 | mutex_init(&fs_info->chunk_mutex); | 1715 | mutex_init(&fs_info->chunk_mutex); |
@@ -2479,13 +2479,13 @@ int btrfs_commit_super(struct btrfs_root *root) | |||
2479 | down_write(&root->fs_info->cleanup_work_sem); | 2479 | down_write(&root->fs_info->cleanup_work_sem); |
2480 | up_write(&root->fs_info->cleanup_work_sem); | 2480 | up_write(&root->fs_info->cleanup_work_sem); |
2481 | 2481 | ||
2482 | trans = btrfs_join_transaction(root, 1); | 2482 | trans = btrfs_join_transaction(root); |
2483 | if (IS_ERR(trans)) | 2483 | if (IS_ERR(trans)) |
2484 | return PTR_ERR(trans); | 2484 | return PTR_ERR(trans); |
2485 | ret = btrfs_commit_transaction(trans, root); | 2485 | ret = btrfs_commit_transaction(trans, root); |
2486 | BUG_ON(ret); | 2486 | BUG_ON(ret); |
2487 | /* run commit again to drop the original snapshot */ | 2487 | /* run commit again to drop the original snapshot */ |
2488 | trans = btrfs_join_transaction(root, 1); | 2488 | trans = btrfs_join_transaction(root); |
2489 | if (IS_ERR(trans)) | 2489 | if (IS_ERR(trans)) |
2490 | return PTR_ERR(trans); | 2490 | return PTR_ERR(trans); |
2491 | btrfs_commit_transaction(trans, root); | 2491 | btrfs_commit_transaction(trans, root); |
@@ -3024,10 +3024,13 @@ static int btrfs_cleanup_transaction(struct btrfs_root *root) | |||
3024 | 3024 | ||
3025 | WARN_ON(1); | 3025 | WARN_ON(1); |
3026 | 3026 | ||
3027 | mutex_lock(&root->fs_info->trans_mutex); | ||
3028 | mutex_lock(&root->fs_info->transaction_kthread_mutex); | 3027 | mutex_lock(&root->fs_info->transaction_kthread_mutex); |
3029 | 3028 | ||
3029 | spin_lock(&root->fs_info->trans_lock); | ||
3030 | list_splice_init(&root->fs_info->trans_list, &list); | 3030 | list_splice_init(&root->fs_info->trans_list, &list); |
3031 | root->fs_info->trans_no_join = 1; | ||
3032 | spin_unlock(&root->fs_info->trans_lock); | ||
3033 | |||
3031 | while (!list_empty(&list)) { | 3034 | while (!list_empty(&list)) { |
3032 | t = list_entry(list.next, struct btrfs_transaction, list); | 3035 | t = list_entry(list.next, struct btrfs_transaction, list); |
3033 | if (!t) | 3036 | if (!t) |
@@ -3052,23 +3055,18 @@ static int btrfs_cleanup_transaction(struct btrfs_root *root) | |||
3052 | t->blocked = 0; | 3055 | t->blocked = 0; |
3053 | if (waitqueue_active(&root->fs_info->transaction_wait)) | 3056 | if (waitqueue_active(&root->fs_info->transaction_wait)) |
3054 | wake_up(&root->fs_info->transaction_wait); | 3057 | wake_up(&root->fs_info->transaction_wait); |
3055 | mutex_unlock(&root->fs_info->trans_mutex); | ||
3056 | 3058 | ||
3057 | mutex_lock(&root->fs_info->trans_mutex); | ||
3058 | t->commit_done = 1; | 3059 | t->commit_done = 1; |
3059 | if (waitqueue_active(&t->commit_wait)) | 3060 | if (waitqueue_active(&t->commit_wait)) |
3060 | wake_up(&t->commit_wait); | 3061 | wake_up(&t->commit_wait); |
3061 | mutex_unlock(&root->fs_info->trans_mutex); | ||
3062 | |||
3063 | mutex_lock(&root->fs_info->trans_mutex); | ||
3064 | 3062 | ||
3065 | btrfs_destroy_pending_snapshots(t); | 3063 | btrfs_destroy_pending_snapshots(t); |
3066 | 3064 | ||
3067 | btrfs_destroy_delalloc_inodes(root); | 3065 | btrfs_destroy_delalloc_inodes(root); |
3068 | 3066 | ||
3069 | spin_lock(&root->fs_info->new_trans_lock); | 3067 | spin_lock(&root->fs_info->trans_lock); |
3070 | root->fs_info->running_transaction = NULL; | 3068 | root->fs_info->running_transaction = NULL; |
3071 | spin_unlock(&root->fs_info->new_trans_lock); | 3069 | spin_unlock(&root->fs_info->trans_lock); |
3072 | 3070 | ||
3073 | btrfs_destroy_marked_extents(root, &t->dirty_pages, | 3071 | btrfs_destroy_marked_extents(root, &t->dirty_pages, |
3074 | EXTENT_DIRTY); | 3072 | EXTENT_DIRTY); |
@@ -3082,8 +3080,10 @@ static int btrfs_cleanup_transaction(struct btrfs_root *root) | |||
3082 | kmem_cache_free(btrfs_transaction_cachep, t); | 3080 | kmem_cache_free(btrfs_transaction_cachep, t); |
3083 | } | 3081 | } |
3084 | 3082 | ||
3083 | spin_lock(&root->fs_info->trans_lock); | ||
3084 | root->fs_info->trans_no_join = 0; | ||
3085 | spin_unlock(&root->fs_info->trans_lock); | ||
3085 | mutex_unlock(&root->fs_info->transaction_kthread_mutex); | 3086 | mutex_unlock(&root->fs_info->transaction_kthread_mutex); |
3086 | mutex_unlock(&root->fs_info->trans_mutex); | ||
3087 | 3087 | ||
3088 | return 0; | 3088 | return 0; |
3089 | } | 3089 | } |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 169bd62ce776..5b9b6b6df242 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -348,7 +348,7 @@ static int caching_kthread(void *data) | |||
348 | */ | 348 | */ |
349 | path->skip_locking = 1; | 349 | path->skip_locking = 1; |
350 | path->search_commit_root = 1; | 350 | path->search_commit_root = 1; |
351 | path->reada = 2; | 351 | path->reada = 1; |
352 | 352 | ||
353 | key.objectid = last; | 353 | key.objectid = last; |
354 | key.offset = 0; | 354 | key.offset = 0; |
@@ -366,8 +366,7 @@ again: | |||
366 | nritems = btrfs_header_nritems(leaf); | 366 | nritems = btrfs_header_nritems(leaf); |
367 | 367 | ||
368 | while (1) { | 368 | while (1) { |
369 | smp_mb(); | 369 | if (btrfs_fs_closing(fs_info) > 1) { |
370 | if (fs_info->closing > 1) { | ||
371 | last = (u64)-1; | 370 | last = (u64)-1; |
372 | break; | 371 | break; |
373 | } | 372 | } |
@@ -379,15 +378,18 @@ again: | |||
379 | if (ret) | 378 | if (ret) |
380 | break; | 379 | break; |
381 | 380 | ||
382 | caching_ctl->progress = last; | 381 | if (need_resched() || |
383 | btrfs_release_path(path); | 382 | btrfs_next_leaf(extent_root, path)) { |
384 | up_read(&fs_info->extent_commit_sem); | 383 | caching_ctl->progress = last; |
385 | mutex_unlock(&caching_ctl->mutex); | 384 | btrfs_release_path(path); |
386 | if (btrfs_transaction_in_commit(fs_info)) | 385 | up_read(&fs_info->extent_commit_sem); |
387 | schedule_timeout(1); | 386 | mutex_unlock(&caching_ctl->mutex); |
388 | else | ||
389 | cond_resched(); | 387 | cond_resched(); |
390 | goto again; | 388 | goto again; |
389 | } | ||
390 | leaf = path->nodes[0]; | ||
391 | nritems = btrfs_header_nritems(leaf); | ||
392 | continue; | ||
391 | } | 393 | } |
392 | 394 | ||
393 | if (key.objectid < block_group->key.objectid) { | 395 | if (key.objectid < block_group->key.objectid) { |
@@ -3065,7 +3067,7 @@ again: | |||
3065 | spin_unlock(&data_sinfo->lock); | 3067 | spin_unlock(&data_sinfo->lock); |
3066 | alloc: | 3068 | alloc: |
3067 | alloc_target = btrfs_get_alloc_profile(root, 1); | 3069 | alloc_target = btrfs_get_alloc_profile(root, 1); |
3068 | trans = btrfs_join_transaction(root, 1); | 3070 | trans = btrfs_join_transaction(root); |
3069 | if (IS_ERR(trans)) | 3071 | if (IS_ERR(trans)) |
3070 | return PTR_ERR(trans); | 3072 | return PTR_ERR(trans); |
3071 | 3073 | ||
@@ -3091,9 +3093,10 @@ alloc: | |||
3091 | 3093 | ||
3092 | /* commit the current transaction and try again */ | 3094 | /* commit the current transaction and try again */ |
3093 | commit_trans: | 3095 | commit_trans: |
3094 | if (!committed && !root->fs_info->open_ioctl_trans) { | 3096 | if (!committed && |
3097 | !atomic_read(&root->fs_info->open_ioctl_trans)) { | ||
3095 | committed = 1; | 3098 | committed = 1; |
3096 | trans = btrfs_join_transaction(root, 1); | 3099 | trans = btrfs_join_transaction(root); |
3097 | if (IS_ERR(trans)) | 3100 | if (IS_ERR(trans)) |
3098 | return PTR_ERR(trans); | 3101 | return PTR_ERR(trans); |
3099 | ret = btrfs_commit_transaction(trans, root); | 3102 | ret = btrfs_commit_transaction(trans, root); |
@@ -3472,7 +3475,7 @@ again: | |||
3472 | goto out; | 3475 | goto out; |
3473 | 3476 | ||
3474 | ret = -ENOSPC; | 3477 | ret = -ENOSPC; |
3475 | trans = btrfs_join_transaction(root, 1); | 3478 | trans = btrfs_join_transaction(root); |
3476 | if (IS_ERR(trans)) | 3479 | if (IS_ERR(trans)) |
3477 | goto out; | 3480 | goto out; |
3478 | ret = btrfs_commit_transaction(trans, root); | 3481 | ret = btrfs_commit_transaction(trans, root); |
@@ -3699,7 +3702,7 @@ int btrfs_block_rsv_check(struct btrfs_trans_handle *trans, | |||
3699 | if (trans) | 3702 | if (trans) |
3700 | return -EAGAIN; | 3703 | return -EAGAIN; |
3701 | 3704 | ||
3702 | trans = btrfs_join_transaction(root, 1); | 3705 | trans = btrfs_join_transaction(root); |
3703 | BUG_ON(IS_ERR(trans)); | 3706 | BUG_ON(IS_ERR(trans)); |
3704 | ret = btrfs_commit_transaction(trans, root); | 3707 | ret = btrfs_commit_transaction(trans, root); |
3705 | return 0; | 3708 | return 0; |
@@ -3837,6 +3840,37 @@ static void release_global_block_rsv(struct btrfs_fs_info *fs_info) | |||
3837 | WARN_ON(fs_info->chunk_block_rsv.reserved > 0); | 3840 | WARN_ON(fs_info->chunk_block_rsv.reserved > 0); |
3838 | } | 3841 | } |
3839 | 3842 | ||
3843 | int btrfs_truncate_reserve_metadata(struct btrfs_trans_handle *trans, | ||
3844 | struct btrfs_root *root, | ||
3845 | struct btrfs_block_rsv *rsv) | ||
3846 | { | ||
3847 | struct btrfs_block_rsv *trans_rsv = &root->fs_info->trans_block_rsv; | ||
3848 | u64 num_bytes; | ||
3849 | int ret; | ||
3850 | |||
3851 | /* | ||
3852 | * Truncate should be freeing data, but give us 2 items just in case it | ||
3853 | * needs to use some space. We may want to be smarter about this in the | ||
3854 | * future. | ||
3855 | */ | ||
3856 | num_bytes = btrfs_calc_trans_metadata_size(root, 2); | ||
3857 | |||
3858 | /* We already have enough bytes, just return */ | ||
3859 | if (rsv->reserved >= num_bytes) | ||
3860 | return 0; | ||
3861 | |||
3862 | num_bytes -= rsv->reserved; | ||
3863 | |||
3864 | /* | ||
3865 | * You should have reserved enough space before hand to do this, so this | ||
3866 | * should not fail. | ||
3867 | */ | ||
3868 | ret = block_rsv_migrate_bytes(trans_rsv, rsv, num_bytes); | ||
3869 | BUG_ON(ret); | ||
3870 | |||
3871 | return 0; | ||
3872 | } | ||
3873 | |||
3840 | int btrfs_trans_reserve_metadata(struct btrfs_trans_handle *trans, | 3874 | int btrfs_trans_reserve_metadata(struct btrfs_trans_handle *trans, |
3841 | struct btrfs_root *root, | 3875 | struct btrfs_root *root, |
3842 | int num_items) | 3876 | int num_items) |
@@ -3877,23 +3911,18 @@ int btrfs_orphan_reserve_metadata(struct btrfs_trans_handle *trans, | |||
3877 | struct btrfs_block_rsv *dst_rsv = root->orphan_block_rsv; | 3911 | struct btrfs_block_rsv *dst_rsv = root->orphan_block_rsv; |
3878 | 3912 | ||
3879 | /* | 3913 | /* |
3880 | * one for deleting orphan item, one for updating inode and | 3914 | * We need to hold space in order to delete our orphan item once we've |
3881 | * two for calling btrfs_truncate_inode_items. | 3915 | * added it, so this takes the reservation so we can release it later |
3882 | * | 3916 | * when we are truly done with the orphan item. |
3883 | * btrfs_truncate_inode_items is a delete operation, it frees | ||
3884 | * more space than it uses in most cases. So two units of | ||
3885 | * metadata space should be enough for calling it many times. | ||
3886 | * If all of the metadata space is used, we can commit | ||
3887 | * transaction and use space it freed. | ||
3888 | */ | 3917 | */ |
3889 | u64 num_bytes = btrfs_calc_trans_metadata_size(root, 4); | 3918 | u64 num_bytes = btrfs_calc_trans_metadata_size(root, 1); |
3890 | return block_rsv_migrate_bytes(src_rsv, dst_rsv, num_bytes); | 3919 | return block_rsv_migrate_bytes(src_rsv, dst_rsv, num_bytes); |
3891 | } | 3920 | } |
3892 | 3921 | ||
3893 | void btrfs_orphan_release_metadata(struct inode *inode) | 3922 | void btrfs_orphan_release_metadata(struct inode *inode) |
3894 | { | 3923 | { |
3895 | struct btrfs_root *root = BTRFS_I(inode)->root; | 3924 | struct btrfs_root *root = BTRFS_I(inode)->root; |
3896 | u64 num_bytes = btrfs_calc_trans_metadata_size(root, 4); | 3925 | u64 num_bytes = btrfs_calc_trans_metadata_size(root, 1); |
3897 | btrfs_block_rsv_release(root, root->orphan_block_rsv, num_bytes); | 3926 | btrfs_block_rsv_release(root, root->orphan_block_rsv, num_bytes); |
3898 | } | 3927 | } |
3899 | 3928 | ||
@@ -4987,6 +5016,15 @@ have_block_group: | |||
4987 | if (unlikely(block_group->ro)) | 5016 | if (unlikely(block_group->ro)) |
4988 | goto loop; | 5017 | goto loop; |
4989 | 5018 | ||
5019 | spin_lock(&block_group->free_space_ctl->tree_lock); | ||
5020 | if (cached && | ||
5021 | block_group->free_space_ctl->free_space < | ||
5022 | num_bytes + empty_size) { | ||
5023 | spin_unlock(&block_group->free_space_ctl->tree_lock); | ||
5024 | goto loop; | ||
5025 | } | ||
5026 | spin_unlock(&block_group->free_space_ctl->tree_lock); | ||
5027 | |||
4990 | /* | 5028 | /* |
4991 | * Ok we want to try and use the cluster allocator, so lets look | 5029 | * Ok we want to try and use the cluster allocator, so lets look |
4992 | * there, unless we are on LOOP_NO_EMPTY_SIZE, since we will | 5030 | * there, unless we are on LOOP_NO_EMPTY_SIZE, since we will |
@@ -5150,6 +5188,7 @@ checks: | |||
5150 | btrfs_add_free_space(block_group, offset, | 5188 | btrfs_add_free_space(block_group, offset, |
5151 | search_start - offset); | 5189 | search_start - offset); |
5152 | BUG_ON(offset > search_start); | 5190 | BUG_ON(offset > search_start); |
5191 | btrfs_put_block_group(block_group); | ||
5153 | break; | 5192 | break; |
5154 | loop: | 5193 | loop: |
5155 | failed_cluster_refill = false; | 5194 | failed_cluster_refill = false; |
@@ -5242,14 +5281,7 @@ loop: | |||
5242 | ret = -ENOSPC; | 5281 | ret = -ENOSPC; |
5243 | } else if (!ins->objectid) { | 5282 | } else if (!ins->objectid) { |
5244 | ret = -ENOSPC; | 5283 | ret = -ENOSPC; |
5245 | } | 5284 | } else if (ins->objectid) { |
5246 | |||
5247 | /* we found what we needed */ | ||
5248 | if (ins->objectid) { | ||
5249 | if (!(data & BTRFS_BLOCK_GROUP_DATA)) | ||
5250 | trans->block_group = block_group->key.objectid; | ||
5251 | |||
5252 | btrfs_put_block_group(block_group); | ||
5253 | ret = 0; | 5285 | ret = 0; |
5254 | } | 5286 | } |
5255 | 5287 | ||
@@ -6526,7 +6558,7 @@ int btrfs_set_block_group_ro(struct btrfs_root *root, | |||
6526 | 6558 | ||
6527 | BUG_ON(cache->ro); | 6559 | BUG_ON(cache->ro); |
6528 | 6560 | ||
6529 | trans = btrfs_join_transaction(root, 1); | 6561 | trans = btrfs_join_transaction(root); |
6530 | BUG_ON(IS_ERR(trans)); | 6562 | BUG_ON(IS_ERR(trans)); |
6531 | 6563 | ||
6532 | alloc_flags = update_block_group_flags(root, cache->flags); | 6564 | alloc_flags = update_block_group_flags(root, cache->flags); |
@@ -6882,6 +6914,7 @@ int btrfs_read_block_groups(struct btrfs_root *root) | |||
6882 | path = btrfs_alloc_path(); | 6914 | path = btrfs_alloc_path(); |
6883 | if (!path) | 6915 | if (!path) |
6884 | return -ENOMEM; | 6916 | return -ENOMEM; |
6917 | path->reada = 1; | ||
6885 | 6918 | ||
6886 | cache_gen = btrfs_super_cache_generation(&root->fs_info->super_copy); | 6919 | cache_gen = btrfs_super_cache_generation(&root->fs_info->super_copy); |
6887 | if (cache_gen != 0 && | 6920 | if (cache_gen != 0 && |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index c5d9fbb92bc3..7055d11c1efd 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -1476,7 +1476,7 @@ u64 count_range_bits(struct extent_io_tree *tree, | |||
1476 | if (total_bytes >= max_bytes) | 1476 | if (total_bytes >= max_bytes) |
1477 | break; | 1477 | break; |
1478 | if (!found) { | 1478 | if (!found) { |
1479 | *start = state->start; | 1479 | *start = max(cur_start, state->start); |
1480 | found = 1; | 1480 | found = 1; |
1481 | } | 1481 | } |
1482 | last = state->end; | 1482 | last = state->end; |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index c6a22d783c35..fa4ef18b66b1 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -129,7 +129,7 @@ int btrfs_add_inode_defrag(struct btrfs_trans_handle *trans, | |||
129 | if (!btrfs_test_opt(root, AUTO_DEFRAG)) | 129 | if (!btrfs_test_opt(root, AUTO_DEFRAG)) |
130 | return 0; | 130 | return 0; |
131 | 131 | ||
132 | if (root->fs_info->closing) | 132 | if (btrfs_fs_closing(root->fs_info)) |
133 | return 0; | 133 | return 0; |
134 | 134 | ||
135 | if (BTRFS_I(inode)->in_defrag) | 135 | if (BTRFS_I(inode)->in_defrag) |
@@ -144,7 +144,7 @@ int btrfs_add_inode_defrag(struct btrfs_trans_handle *trans, | |||
144 | if (!defrag) | 144 | if (!defrag) |
145 | return -ENOMEM; | 145 | return -ENOMEM; |
146 | 146 | ||
147 | defrag->ino = inode->i_ino; | 147 | defrag->ino = btrfs_ino(inode); |
148 | defrag->transid = transid; | 148 | defrag->transid = transid; |
149 | defrag->root = root->root_key.objectid; | 149 | defrag->root = root->root_key.objectid; |
150 | 150 | ||
@@ -229,7 +229,7 @@ int btrfs_run_defrag_inodes(struct btrfs_fs_info *fs_info) | |||
229 | first_ino = defrag->ino + 1; | 229 | first_ino = defrag->ino + 1; |
230 | rb_erase(&defrag->rb_node, &fs_info->defrag_inodes); | 230 | rb_erase(&defrag->rb_node, &fs_info->defrag_inodes); |
231 | 231 | ||
232 | if (fs_info->closing) | 232 | if (btrfs_fs_closing(fs_info)) |
233 | goto next_free; | 233 | goto next_free; |
234 | 234 | ||
235 | spin_unlock(&fs_info->defrag_inodes_lock); | 235 | spin_unlock(&fs_info->defrag_inodes_lock); |
@@ -1480,14 +1480,12 @@ int btrfs_sync_file(struct file *file, int datasync) | |||
1480 | * the current transaction, we can bail out now without any | 1480 | * the current transaction, we can bail out now without any |
1481 | * syncing | 1481 | * syncing |
1482 | */ | 1482 | */ |
1483 | mutex_lock(&root->fs_info->trans_mutex); | 1483 | smp_mb(); |
1484 | if (BTRFS_I(inode)->last_trans <= | 1484 | if (BTRFS_I(inode)->last_trans <= |
1485 | root->fs_info->last_trans_committed) { | 1485 | root->fs_info->last_trans_committed) { |
1486 | BTRFS_I(inode)->last_trans = 0; | 1486 | BTRFS_I(inode)->last_trans = 0; |
1487 | mutex_unlock(&root->fs_info->trans_mutex); | ||
1488 | goto out; | 1487 | goto out; |
1489 | } | 1488 | } |
1490 | mutex_unlock(&root->fs_info->trans_mutex); | ||
1491 | 1489 | ||
1492 | /* | 1490 | /* |
1493 | * ok we haven't committed the transaction yet, lets do a commit | 1491 | * ok we haven't committed the transaction yet, lets do a commit |
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index 70d45795d758..ad144736a5fd 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c | |||
@@ -98,7 +98,7 @@ struct inode *lookup_free_space_inode(struct btrfs_root *root, | |||
98 | return inode; | 98 | return inode; |
99 | 99 | ||
100 | spin_lock(&block_group->lock); | 100 | spin_lock(&block_group->lock); |
101 | if (!root->fs_info->closing) { | 101 | if (!btrfs_fs_closing(root->fs_info)) { |
102 | block_group->inode = igrab(inode); | 102 | block_group->inode = igrab(inode); |
103 | block_group->iref = 1; | 103 | block_group->iref = 1; |
104 | } | 104 | } |
@@ -402,7 +402,14 @@ int __load_free_space_cache(struct btrfs_root *root, struct inode *inode, | |||
402 | spin_lock(&ctl->tree_lock); | 402 | spin_lock(&ctl->tree_lock); |
403 | ret = link_free_space(ctl, e); | 403 | ret = link_free_space(ctl, e); |
404 | spin_unlock(&ctl->tree_lock); | 404 | spin_unlock(&ctl->tree_lock); |
405 | BUG_ON(ret); | 405 | if (ret) { |
406 | printk(KERN_ERR "Duplicate entries in " | ||
407 | "free space cache, dumping\n"); | ||
408 | kunmap(page); | ||
409 | unlock_page(page); | ||
410 | page_cache_release(page); | ||
411 | goto free_cache; | ||
412 | } | ||
406 | } else { | 413 | } else { |
407 | e->bitmap = kzalloc(PAGE_CACHE_SIZE, GFP_NOFS); | 414 | e->bitmap = kzalloc(PAGE_CACHE_SIZE, GFP_NOFS); |
408 | if (!e->bitmap) { | 415 | if (!e->bitmap) { |
@@ -419,6 +426,14 @@ int __load_free_space_cache(struct btrfs_root *root, struct inode *inode, | |||
419 | ctl->op->recalc_thresholds(ctl); | 426 | ctl->op->recalc_thresholds(ctl); |
420 | spin_unlock(&ctl->tree_lock); | 427 | spin_unlock(&ctl->tree_lock); |
421 | list_add_tail(&e->list, &bitmaps); | 428 | list_add_tail(&e->list, &bitmaps); |
429 | if (ret) { | ||
430 | printk(KERN_ERR "Duplicate entries in " | ||
431 | "free space cache, dumping\n"); | ||
432 | kunmap(page); | ||
433 | unlock_page(page); | ||
434 | page_cache_release(page); | ||
435 | goto free_cache; | ||
436 | } | ||
422 | } | 437 | } |
423 | 438 | ||
424 | num_entries--; | 439 | num_entries--; |
@@ -478,8 +493,7 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info, | |||
478 | * If we're unmounting then just return, since this does a search on the | 493 | * If we're unmounting then just return, since this does a search on the |
479 | * normal root and not the commit root and we could deadlock. | 494 | * normal root and not the commit root and we could deadlock. |
480 | */ | 495 | */ |
481 | smp_mb(); | 496 | if (btrfs_fs_closing(fs_info)) |
482 | if (fs_info->closing) | ||
483 | return 0; | 497 | return 0; |
484 | 498 | ||
485 | /* | 499 | /* |
@@ -575,10 +589,25 @@ int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode, | |||
575 | 589 | ||
576 | num_pages = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> | 590 | num_pages = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> |
577 | PAGE_CACHE_SHIFT; | 591 | PAGE_CACHE_SHIFT; |
592 | |||
593 | /* Since the first page has all of our checksums and our generation we | ||
594 | * need to calculate the offset into the page that we can start writing | ||
595 | * our entries. | ||
596 | */ | ||
597 | first_page_offset = (sizeof(u32) * num_pages) + sizeof(u64); | ||
598 | |||
578 | filemap_write_and_wait(inode->i_mapping); | 599 | filemap_write_and_wait(inode->i_mapping); |
579 | btrfs_wait_ordered_range(inode, inode->i_size & | 600 | btrfs_wait_ordered_range(inode, inode->i_size & |
580 | ~(root->sectorsize - 1), (u64)-1); | 601 | ~(root->sectorsize - 1), (u64)-1); |
581 | 602 | ||
603 | /* make sure we don't overflow that first page */ | ||
604 | if (first_page_offset + sizeof(struct btrfs_free_space_entry) >= PAGE_CACHE_SIZE) { | ||
605 | /* this is really the same as running out of space, where we also return 0 */ | ||
606 | printk(KERN_CRIT "Btrfs: free space cache was too big for the crc page\n"); | ||
607 | ret = 0; | ||
608 | goto out_update; | ||
609 | } | ||
610 | |||
582 | /* We need a checksum per page. */ | 611 | /* We need a checksum per page. */ |
583 | crc = checksums = kzalloc(sizeof(u32) * num_pages, GFP_NOFS); | 612 | crc = checksums = kzalloc(sizeof(u32) * num_pages, GFP_NOFS); |
584 | if (!crc) | 613 | if (!crc) |
@@ -590,12 +619,6 @@ int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode, | |||
590 | return -1; | 619 | return -1; |
591 | } | 620 | } |
592 | 621 | ||
593 | /* Since the first page has all of our checksums and our generation we | ||
594 | * need to calculate the offset into the page that we can start writing | ||
595 | * our entries. | ||
596 | */ | ||
597 | first_page_offset = (sizeof(u32) * num_pages) + sizeof(u64); | ||
598 | |||
599 | /* Get the cluster for this block_group if it exists */ | 622 | /* Get the cluster for this block_group if it exists */ |
600 | if (block_group && !list_empty(&block_group->cluster_list)) | 623 | if (block_group && !list_empty(&block_group->cluster_list)) |
601 | cluster = list_entry(block_group->cluster_list.next, | 624 | cluster = list_entry(block_group->cluster_list.next, |
@@ -857,12 +880,14 @@ int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode, | |||
857 | ret = 1; | 880 | ret = 1; |
858 | 881 | ||
859 | out_free: | 882 | out_free: |
883 | kfree(checksums); | ||
884 | kfree(pages); | ||
885 | |||
886 | out_update: | ||
860 | if (ret != 1) { | 887 | if (ret != 1) { |
861 | invalidate_inode_pages2_range(inode->i_mapping, 0, index); | 888 | invalidate_inode_pages2_range(inode->i_mapping, 0, index); |
862 | BTRFS_I(inode)->generation = 0; | 889 | BTRFS_I(inode)->generation = 0; |
863 | } | 890 | } |
864 | kfree(checksums); | ||
865 | kfree(pages); | ||
866 | btrfs_update_inode(trans, root, inode); | 891 | btrfs_update_inode(trans, root, inode); |
867 | return ret; | 892 | return ret; |
868 | } | 893 | } |
@@ -963,10 +988,16 @@ static int tree_insert_offset(struct rb_root *root, u64 offset, | |||
963 | * logically. | 988 | * logically. |
964 | */ | 989 | */ |
965 | if (bitmap) { | 990 | if (bitmap) { |
966 | WARN_ON(info->bitmap); | 991 | if (info->bitmap) { |
992 | WARN_ON_ONCE(1); | ||
993 | return -EEXIST; | ||
994 | } | ||
967 | p = &(*p)->rb_right; | 995 | p = &(*p)->rb_right; |
968 | } else { | 996 | } else { |
969 | WARN_ON(!info->bitmap); | 997 | if (!info->bitmap) { |
998 | WARN_ON_ONCE(1); | ||
999 | return -EEXIST; | ||
1000 | } | ||
970 | p = &(*p)->rb_left; | 1001 | p = &(*p)->rb_left; |
971 | } | 1002 | } |
972 | } | 1003 | } |
@@ -2481,7 +2512,7 @@ struct inode *lookup_free_ino_inode(struct btrfs_root *root, | |||
2481 | return inode; | 2512 | return inode; |
2482 | 2513 | ||
2483 | spin_lock(&root->cache_lock); | 2514 | spin_lock(&root->cache_lock); |
2484 | if (!root->fs_info->closing) | 2515 | if (!btrfs_fs_closing(root->fs_info)) |
2485 | root->cache_inode = igrab(inode); | 2516 | root->cache_inode = igrab(inode); |
2486 | spin_unlock(&root->cache_lock); | 2517 | spin_unlock(&root->cache_lock); |
2487 | 2518 | ||
@@ -2504,12 +2535,14 @@ int load_free_ino_cache(struct btrfs_fs_info *fs_info, struct btrfs_root *root) | |||
2504 | int ret = 0; | 2535 | int ret = 0; |
2505 | u64 root_gen = btrfs_root_generation(&root->root_item); | 2536 | u64 root_gen = btrfs_root_generation(&root->root_item); |
2506 | 2537 | ||
2538 | if (!btrfs_test_opt(root, INODE_MAP_CACHE)) | ||
2539 | return 0; | ||
2540 | |||
2507 | /* | 2541 | /* |
2508 | * If we're unmounting then just return, since this does a search on the | 2542 | * If we're unmounting then just return, since this does a search on the |
2509 | * normal root and not the commit root and we could deadlock. | 2543 | * normal root and not the commit root and we could deadlock. |
2510 | */ | 2544 | */ |
2511 | smp_mb(); | 2545 | if (btrfs_fs_closing(fs_info)) |
2512 | if (fs_info->closing) | ||
2513 | return 0; | 2546 | return 0; |
2514 | 2547 | ||
2515 | path = btrfs_alloc_path(); | 2548 | path = btrfs_alloc_path(); |
@@ -2543,6 +2576,9 @@ int btrfs_write_out_ino_cache(struct btrfs_root *root, | |||
2543 | struct inode *inode; | 2576 | struct inode *inode; |
2544 | int ret; | 2577 | int ret; |
2545 | 2578 | ||
2579 | if (!btrfs_test_opt(root, INODE_MAP_CACHE)) | ||
2580 | return 0; | ||
2581 | |||
2546 | inode = lookup_free_ino_inode(root, path); | 2582 | inode = lookup_free_ino_inode(root, path); |
2547 | if (IS_ERR(inode)) | 2583 | if (IS_ERR(inode)) |
2548 | return 0; | 2584 | return 0; |
diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c index 3262cd17a12f..b4087e0fa871 100644 --- a/fs/btrfs/inode-map.c +++ b/fs/btrfs/inode-map.c | |||
@@ -38,6 +38,9 @@ static int caching_kthread(void *data) | |||
38 | int slot; | 38 | int slot; |
39 | int ret; | 39 | int ret; |
40 | 40 | ||
41 | if (!btrfs_test_opt(root, INODE_MAP_CACHE)) | ||
42 | return 0; | ||
43 | |||
41 | path = btrfs_alloc_path(); | 44 | path = btrfs_alloc_path(); |
42 | if (!path) | 45 | if (!path) |
43 | return -ENOMEM; | 46 | return -ENOMEM; |
@@ -59,8 +62,7 @@ again: | |||
59 | goto out; | 62 | goto out; |
60 | 63 | ||
61 | while (1) { | 64 | while (1) { |
62 | smp_mb(); | 65 | if (btrfs_fs_closing(fs_info)) |
63 | if (fs_info->closing) | ||
64 | goto out; | 66 | goto out; |
65 | 67 | ||
66 | leaf = path->nodes[0]; | 68 | leaf = path->nodes[0]; |
@@ -141,6 +143,9 @@ static void start_caching(struct btrfs_root *root) | |||
141 | int ret; | 143 | int ret; |
142 | u64 objectid; | 144 | u64 objectid; |
143 | 145 | ||
146 | if (!btrfs_test_opt(root, INODE_MAP_CACHE)) | ||
147 | return; | ||
148 | |||
144 | spin_lock(&root->cache_lock); | 149 | spin_lock(&root->cache_lock); |
145 | if (root->cached != BTRFS_CACHE_NO) { | 150 | if (root->cached != BTRFS_CACHE_NO) { |
146 | spin_unlock(&root->cache_lock); | 151 | spin_unlock(&root->cache_lock); |
@@ -178,6 +183,9 @@ static void start_caching(struct btrfs_root *root) | |||
178 | 183 | ||
179 | int btrfs_find_free_ino(struct btrfs_root *root, u64 *objectid) | 184 | int btrfs_find_free_ino(struct btrfs_root *root, u64 *objectid) |
180 | { | 185 | { |
186 | if (!btrfs_test_opt(root, INODE_MAP_CACHE)) | ||
187 | return btrfs_find_free_objectid(root, objectid); | ||
188 | |||
181 | again: | 189 | again: |
182 | *objectid = btrfs_find_ino_for_alloc(root); | 190 | *objectid = btrfs_find_ino_for_alloc(root); |
183 | 191 | ||
@@ -201,6 +209,10 @@ void btrfs_return_ino(struct btrfs_root *root, u64 objectid) | |||
201 | { | 209 | { |
202 | struct btrfs_free_space_ctl *ctl = root->free_ino_ctl; | 210 | struct btrfs_free_space_ctl *ctl = root->free_ino_ctl; |
203 | struct btrfs_free_space_ctl *pinned = root->free_ino_pinned; | 211 | struct btrfs_free_space_ctl *pinned = root->free_ino_pinned; |
212 | |||
213 | if (!btrfs_test_opt(root, INODE_MAP_CACHE)) | ||
214 | return; | ||
215 | |||
204 | again: | 216 | again: |
205 | if (root->cached == BTRFS_CACHE_FINISHED) { | 217 | if (root->cached == BTRFS_CACHE_FINISHED) { |
206 | __btrfs_add_free_space(ctl, objectid, 1); | 218 | __btrfs_add_free_space(ctl, objectid, 1); |
@@ -250,6 +262,9 @@ void btrfs_unpin_free_ino(struct btrfs_root *root) | |||
250 | struct rb_node *n; | 262 | struct rb_node *n; |
251 | u64 count; | 263 | u64 count; |
252 | 264 | ||
265 | if (!btrfs_test_opt(root, INODE_MAP_CACHE)) | ||
266 | return; | ||
267 | |||
253 | while (1) { | 268 | while (1) { |
254 | n = rb_first(rbroot); | 269 | n = rb_first(rbroot); |
255 | if (!n) | 270 | if (!n) |
@@ -388,9 +403,24 @@ int btrfs_save_ino_cache(struct btrfs_root *root, | |||
388 | int prealloc; | 403 | int prealloc; |
389 | bool retry = false; | 404 | bool retry = false; |
390 | 405 | ||
406 | /* only fs tree and subvol/snap needs ino cache */ | ||
407 | if (root->root_key.objectid != BTRFS_FS_TREE_OBJECTID && | ||
408 | (root->root_key.objectid < BTRFS_FIRST_FREE_OBJECTID || | ||
409 | root->root_key.objectid > BTRFS_LAST_FREE_OBJECTID)) | ||
410 | return 0; | ||
411 | |||
412 | /* Don't save inode cache if we are deleting this root */ | ||
413 | if (btrfs_root_refs(&root->root_item) == 0 && | ||
414 | root != root->fs_info->tree_root) | ||
415 | return 0; | ||
416 | |||
417 | if (!btrfs_test_opt(root, INODE_MAP_CACHE)) | ||
418 | return 0; | ||
419 | |||
391 | path = btrfs_alloc_path(); | 420 | path = btrfs_alloc_path(); |
392 | if (!path) | 421 | if (!path) |
393 | return -ENOMEM; | 422 | return -ENOMEM; |
423 | |||
394 | again: | 424 | again: |
395 | inode = lookup_free_ino_inode(root, path); | 425 | inode = lookup_free_ino_inode(root, path); |
396 | if (IS_ERR(inode) && PTR_ERR(inode) != -ENOENT) { | 426 | if (IS_ERR(inode) && PTR_ERR(inode) != -ENOENT) { |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index bb51bb1fa44f..ebf95f7a44d6 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -138,7 +138,6 @@ static noinline int insert_inline_extent(struct btrfs_trans_handle *trans, | |||
138 | return -ENOMEM; | 138 | return -ENOMEM; |
139 | 139 | ||
140 | path->leave_spinning = 1; | 140 | path->leave_spinning = 1; |
141 | btrfs_set_trans_block_group(trans, inode); | ||
142 | 141 | ||
143 | key.objectid = btrfs_ino(inode); | 142 | key.objectid = btrfs_ino(inode); |
144 | key.offset = start; | 143 | key.offset = start; |
@@ -426,9 +425,8 @@ again: | |||
426 | } | 425 | } |
427 | } | 426 | } |
428 | if (start == 0) { | 427 | if (start == 0) { |
429 | trans = btrfs_join_transaction(root, 1); | 428 | trans = btrfs_join_transaction(root); |
430 | BUG_ON(IS_ERR(trans)); | 429 | BUG_ON(IS_ERR(trans)); |
431 | btrfs_set_trans_block_group(trans, inode); | ||
432 | trans->block_rsv = &root->fs_info->delalloc_block_rsv; | 430 | trans->block_rsv = &root->fs_info->delalloc_block_rsv; |
433 | 431 | ||
434 | /* lets try to make an inline extent */ | 432 | /* lets try to make an inline extent */ |
@@ -623,8 +621,9 @@ retry: | |||
623 | async_extent->start + async_extent->ram_size - 1, | 621 | async_extent->start + async_extent->ram_size - 1, |
624 | GFP_NOFS); | 622 | GFP_NOFS); |
625 | 623 | ||
626 | trans = btrfs_join_transaction(root, 1); | 624 | trans = btrfs_join_transaction(root); |
627 | BUG_ON(IS_ERR(trans)); | 625 | BUG_ON(IS_ERR(trans)); |
626 | trans->block_rsv = &root->fs_info->delalloc_block_rsv; | ||
628 | ret = btrfs_reserve_extent(trans, root, | 627 | ret = btrfs_reserve_extent(trans, root, |
629 | async_extent->compressed_size, | 628 | async_extent->compressed_size, |
630 | async_extent->compressed_size, | 629 | async_extent->compressed_size, |
@@ -793,9 +792,8 @@ static noinline int cow_file_range(struct inode *inode, | |||
793 | int ret = 0; | 792 | int ret = 0; |
794 | 793 | ||
795 | BUG_ON(is_free_space_inode(root, inode)); | 794 | BUG_ON(is_free_space_inode(root, inode)); |
796 | trans = btrfs_join_transaction(root, 1); | 795 | trans = btrfs_join_transaction(root); |
797 | BUG_ON(IS_ERR(trans)); | 796 | BUG_ON(IS_ERR(trans)); |
798 | btrfs_set_trans_block_group(trans, inode); | ||
799 | trans->block_rsv = &root->fs_info->delalloc_block_rsv; | 797 | trans->block_rsv = &root->fs_info->delalloc_block_rsv; |
800 | 798 | ||
801 | num_bytes = (end - start + blocksize) & ~(blocksize - 1); | 799 | num_bytes = (end - start + blocksize) & ~(blocksize - 1); |
@@ -1077,10 +1075,12 @@ static noinline int run_delalloc_nocow(struct inode *inode, | |||
1077 | nolock = is_free_space_inode(root, inode); | 1075 | nolock = is_free_space_inode(root, inode); |
1078 | 1076 | ||
1079 | if (nolock) | 1077 | if (nolock) |
1080 | trans = btrfs_join_transaction_nolock(root, 1); | 1078 | trans = btrfs_join_transaction_nolock(root); |
1081 | else | 1079 | else |
1082 | trans = btrfs_join_transaction(root, 1); | 1080 | trans = btrfs_join_transaction(root); |
1081 | |||
1083 | BUG_ON(IS_ERR(trans)); | 1082 | BUG_ON(IS_ERR(trans)); |
1083 | trans->block_rsv = &root->fs_info->delalloc_block_rsv; | ||
1084 | 1084 | ||
1085 | cow_start = (u64)-1; | 1085 | cow_start = (u64)-1; |
1086 | cur_offset = start; | 1086 | cur_offset = start; |
@@ -1519,8 +1519,6 @@ static noinline int add_pending_csums(struct btrfs_trans_handle *trans, | |||
1519 | { | 1519 | { |
1520 | struct btrfs_ordered_sum *sum; | 1520 | struct btrfs_ordered_sum *sum; |
1521 | 1521 | ||
1522 | btrfs_set_trans_block_group(trans, inode); | ||
1523 | |||
1524 | list_for_each_entry(sum, list, list) { | 1522 | list_for_each_entry(sum, list, list) { |
1525 | btrfs_csum_file_blocks(trans, | 1523 | btrfs_csum_file_blocks(trans, |
1526 | BTRFS_I(inode)->root->fs_info->csum_root, sum); | 1524 | BTRFS_I(inode)->root->fs_info->csum_root, sum); |
@@ -1735,11 +1733,10 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) | |||
1735 | ret = btrfs_ordered_update_i_size(inode, 0, ordered_extent); | 1733 | ret = btrfs_ordered_update_i_size(inode, 0, ordered_extent); |
1736 | if (!ret) { | 1734 | if (!ret) { |
1737 | if (nolock) | 1735 | if (nolock) |
1738 | trans = btrfs_join_transaction_nolock(root, 1); | 1736 | trans = btrfs_join_transaction_nolock(root); |
1739 | else | 1737 | else |
1740 | trans = btrfs_join_transaction(root, 1); | 1738 | trans = btrfs_join_transaction(root); |
1741 | BUG_ON(IS_ERR(trans)); | 1739 | BUG_ON(IS_ERR(trans)); |
1742 | btrfs_set_trans_block_group(trans, inode); | ||
1743 | trans->block_rsv = &root->fs_info->delalloc_block_rsv; | 1740 | trans->block_rsv = &root->fs_info->delalloc_block_rsv; |
1744 | ret = btrfs_update_inode(trans, root, inode); | 1741 | ret = btrfs_update_inode(trans, root, inode); |
1745 | BUG_ON(ret); | 1742 | BUG_ON(ret); |
@@ -1752,11 +1749,10 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) | |||
1752 | 0, &cached_state, GFP_NOFS); | 1749 | 0, &cached_state, GFP_NOFS); |
1753 | 1750 | ||
1754 | if (nolock) | 1751 | if (nolock) |
1755 | trans = btrfs_join_transaction_nolock(root, 1); | 1752 | trans = btrfs_join_transaction_nolock(root); |
1756 | else | 1753 | else |
1757 | trans = btrfs_join_transaction(root, 1); | 1754 | trans = btrfs_join_transaction(root); |
1758 | BUG_ON(IS_ERR(trans)); | 1755 | BUG_ON(IS_ERR(trans)); |
1759 | btrfs_set_trans_block_group(trans, inode); | ||
1760 | trans->block_rsv = &root->fs_info->delalloc_block_rsv; | 1756 | trans->block_rsv = &root->fs_info->delalloc_block_rsv; |
1761 | 1757 | ||
1762 | if (test_bit(BTRFS_ORDERED_COMPRESSED, &ordered_extent->flags)) | 1758 | if (test_bit(BTRFS_ORDERED_COMPRESSED, &ordered_extent->flags)) |
@@ -2431,7 +2427,7 @@ int btrfs_orphan_cleanup(struct btrfs_root *root) | |||
2431 | (u64)-1); | 2427 | (u64)-1); |
2432 | 2428 | ||
2433 | if (root->orphan_block_rsv || root->orphan_item_inserted) { | 2429 | if (root->orphan_block_rsv || root->orphan_item_inserted) { |
2434 | trans = btrfs_join_transaction(root, 1); | 2430 | trans = btrfs_join_transaction(root); |
2435 | if (!IS_ERR(trans)) | 2431 | if (!IS_ERR(trans)) |
2436 | btrfs_end_transaction(trans, root); | 2432 | btrfs_end_transaction(trans, root); |
2437 | } | 2433 | } |
@@ -2511,12 +2507,12 @@ static void btrfs_read_locked_inode(struct inode *inode) | |||
2511 | struct btrfs_root *root = BTRFS_I(inode)->root; | 2507 | struct btrfs_root *root = BTRFS_I(inode)->root; |
2512 | struct btrfs_key location; | 2508 | struct btrfs_key location; |
2513 | int maybe_acls; | 2509 | int maybe_acls; |
2514 | u64 alloc_group_block; | ||
2515 | u32 rdev; | 2510 | u32 rdev; |
2516 | int ret; | 2511 | int ret; |
2517 | 2512 | ||
2518 | path = btrfs_alloc_path(); | 2513 | path = btrfs_alloc_path(); |
2519 | BUG_ON(!path); | 2514 | BUG_ON(!path); |
2515 | path->leave_spinning = 1; | ||
2520 | memcpy(&location, &BTRFS_I(inode)->location, sizeof(location)); | 2516 | memcpy(&location, &BTRFS_I(inode)->location, sizeof(location)); |
2521 | 2517 | ||
2522 | ret = btrfs_lookup_inode(NULL, root, path, &location, 0); | 2518 | ret = btrfs_lookup_inode(NULL, root, path, &location, 0); |
@@ -2526,6 +2522,12 @@ static void btrfs_read_locked_inode(struct inode *inode) | |||
2526 | leaf = path->nodes[0]; | 2522 | leaf = path->nodes[0]; |
2527 | inode_item = btrfs_item_ptr(leaf, path->slots[0], | 2523 | inode_item = btrfs_item_ptr(leaf, path->slots[0], |
2528 | struct btrfs_inode_item); | 2524 | struct btrfs_inode_item); |
2525 | if (!leaf->map_token) | ||
2526 | map_private_extent_buffer(leaf, (unsigned long)inode_item, | ||
2527 | sizeof(struct btrfs_inode_item), | ||
2528 | &leaf->map_token, &leaf->kaddr, | ||
2529 | &leaf->map_start, &leaf->map_len, | ||
2530 | KM_USER1); | ||
2529 | 2531 | ||
2530 | inode->i_mode = btrfs_inode_mode(leaf, inode_item); | 2532 | inode->i_mode = btrfs_inode_mode(leaf, inode_item); |
2531 | inode->i_nlink = btrfs_inode_nlink(leaf, inode_item); | 2533 | inode->i_nlink = btrfs_inode_nlink(leaf, inode_item); |
@@ -2555,8 +2557,6 @@ static void btrfs_read_locked_inode(struct inode *inode) | |||
2555 | BTRFS_I(inode)->index_cnt = (u64)-1; | 2557 | BTRFS_I(inode)->index_cnt = (u64)-1; |
2556 | BTRFS_I(inode)->flags = btrfs_inode_flags(leaf, inode_item); | 2558 | BTRFS_I(inode)->flags = btrfs_inode_flags(leaf, inode_item); |
2557 | 2559 | ||
2558 | alloc_group_block = btrfs_inode_block_group(leaf, inode_item); | ||
2559 | |||
2560 | /* | 2560 | /* |
2561 | * try to precache a NULL acl entry for files that don't have | 2561 | * try to precache a NULL acl entry for files that don't have |
2562 | * any xattrs or acls | 2562 | * any xattrs or acls |
@@ -2566,8 +2566,11 @@ static void btrfs_read_locked_inode(struct inode *inode) | |||
2566 | if (!maybe_acls) | 2566 | if (!maybe_acls) |
2567 | cache_no_acl(inode); | 2567 | cache_no_acl(inode); |
2568 | 2568 | ||
2569 | BTRFS_I(inode)->block_group = btrfs_find_block_group(root, 0, | 2569 | if (leaf->map_token) { |
2570 | alloc_group_block, 0); | 2570 | unmap_extent_buffer(leaf, leaf->map_token, KM_USER1); |
2571 | leaf->map_token = NULL; | ||
2572 | } | ||
2573 | |||
2571 | btrfs_free_path(path); | 2574 | btrfs_free_path(path); |
2572 | inode_item = NULL; | 2575 | inode_item = NULL; |
2573 | 2576 | ||
@@ -2647,7 +2650,7 @@ static void fill_inode_item(struct btrfs_trans_handle *trans, | |||
2647 | btrfs_set_inode_transid(leaf, item, trans->transid); | 2650 | btrfs_set_inode_transid(leaf, item, trans->transid); |
2648 | btrfs_set_inode_rdev(leaf, item, inode->i_rdev); | 2651 | btrfs_set_inode_rdev(leaf, item, inode->i_rdev); |
2649 | btrfs_set_inode_flags(leaf, item, BTRFS_I(inode)->flags); | 2652 | btrfs_set_inode_flags(leaf, item, BTRFS_I(inode)->flags); |
2650 | btrfs_set_inode_block_group(leaf, item, BTRFS_I(inode)->block_group); | 2653 | btrfs_set_inode_block_group(leaf, item, 0); |
2651 | 2654 | ||
2652 | if (leaf->map_token) { | 2655 | if (leaf->map_token) { |
2653 | unmap_extent_buffer(leaf, leaf->map_token, KM_USER1); | 2656 | unmap_extent_buffer(leaf, leaf->map_token, KM_USER1); |
@@ -3004,8 +3007,6 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry) | |||
3004 | if (IS_ERR(trans)) | 3007 | if (IS_ERR(trans)) |
3005 | return PTR_ERR(trans); | 3008 | return PTR_ERR(trans); |
3006 | 3009 | ||
3007 | btrfs_set_trans_block_group(trans, dir); | ||
3008 | |||
3009 | btrfs_record_unlink_dir(trans, dir, dentry->d_inode, 0); | 3010 | btrfs_record_unlink_dir(trans, dir, dentry->d_inode, 0); |
3010 | 3011 | ||
3011 | ret = btrfs_unlink_inode(trans, root, dir, dentry->d_inode, | 3012 | ret = btrfs_unlink_inode(trans, root, dir, dentry->d_inode, |
@@ -3094,8 +3095,6 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
3094 | if (IS_ERR(trans)) | 3095 | if (IS_ERR(trans)) |
3095 | return PTR_ERR(trans); | 3096 | return PTR_ERR(trans); |
3096 | 3097 | ||
3097 | btrfs_set_trans_block_group(trans, dir); | ||
3098 | |||
3099 | if (unlikely(btrfs_ino(inode) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID)) { | 3098 | if (unlikely(btrfs_ino(inode) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID)) { |
3100 | err = btrfs_unlink_subvol(trans, root, dir, | 3099 | err = btrfs_unlink_subvol(trans, root, dir, |
3101 | BTRFS_I(inode)->location.objectid, | 3100 | BTRFS_I(inode)->location.objectid, |
@@ -3514,7 +3513,6 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size) | |||
3514 | err = PTR_ERR(trans); | 3513 | err = PTR_ERR(trans); |
3515 | break; | 3514 | break; |
3516 | } | 3515 | } |
3517 | btrfs_set_trans_block_group(trans, inode); | ||
3518 | 3516 | ||
3519 | err = btrfs_drop_extents(trans, inode, cur_offset, | 3517 | err = btrfs_drop_extents(trans, inode, cur_offset, |
3520 | cur_offset + hole_size, | 3518 | cur_offset + hole_size, |
@@ -3650,7 +3648,6 @@ void btrfs_evict_inode(struct inode *inode) | |||
3650 | while (1) { | 3648 | while (1) { |
3651 | trans = btrfs_start_transaction(root, 0); | 3649 | trans = btrfs_start_transaction(root, 0); |
3652 | BUG_ON(IS_ERR(trans)); | 3650 | BUG_ON(IS_ERR(trans)); |
3653 | btrfs_set_trans_block_group(trans, inode); | ||
3654 | trans->block_rsv = root->orphan_block_rsv; | 3651 | trans->block_rsv = root->orphan_block_rsv; |
3655 | 3652 | ||
3656 | ret = btrfs_block_rsv_check(trans, root, | 3653 | ret = btrfs_block_rsv_check(trans, root, |
@@ -4133,7 +4130,8 @@ static int btrfs_real_readdir(struct file *filp, void *dirent, | |||
4133 | path = btrfs_alloc_path(); | 4130 | path = btrfs_alloc_path(); |
4134 | if (!path) | 4131 | if (!path) |
4135 | return -ENOMEM; | 4132 | return -ENOMEM; |
4136 | path->reada = 2; | 4133 | |
4134 | path->reada = 1; | ||
4137 | 4135 | ||
4138 | if (key_type == BTRFS_DIR_INDEX_KEY) { | 4136 | if (key_type == BTRFS_DIR_INDEX_KEY) { |
4139 | INIT_LIST_HEAD(&ins_list); | 4137 | INIT_LIST_HEAD(&ins_list); |
@@ -4268,18 +4266,16 @@ int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
4268 | if (BTRFS_I(inode)->dummy_inode) | 4266 | if (BTRFS_I(inode)->dummy_inode) |
4269 | return 0; | 4267 | return 0; |
4270 | 4268 | ||
4271 | smp_mb(); | 4269 | if (btrfs_fs_closing(root->fs_info) && is_free_space_inode(root, inode)) |
4272 | if (root->fs_info->closing && is_free_space_inode(root, inode)) | ||
4273 | nolock = true; | 4270 | nolock = true; |
4274 | 4271 | ||
4275 | if (wbc->sync_mode == WB_SYNC_ALL) { | 4272 | if (wbc->sync_mode == WB_SYNC_ALL) { |
4276 | if (nolock) | 4273 | if (nolock) |
4277 | trans = btrfs_join_transaction_nolock(root, 1); | 4274 | trans = btrfs_join_transaction_nolock(root); |
4278 | else | 4275 | else |
4279 | trans = btrfs_join_transaction(root, 1); | 4276 | trans = btrfs_join_transaction(root); |
4280 | if (IS_ERR(trans)) | 4277 | if (IS_ERR(trans)) |
4281 | return PTR_ERR(trans); | 4278 | return PTR_ERR(trans); |
4282 | btrfs_set_trans_block_group(trans, inode); | ||
4283 | if (nolock) | 4279 | if (nolock) |
4284 | ret = btrfs_end_transaction_nolock(trans, root); | 4280 | ret = btrfs_end_transaction_nolock(trans, root); |
4285 | else | 4281 | else |
@@ -4294,7 +4290,7 @@ int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
4294 | * FIXME, needs more benchmarking...there are no reasons other than performance | 4290 | * FIXME, needs more benchmarking...there are no reasons other than performance |
4295 | * to keep or drop this code. | 4291 | * to keep or drop this code. |
4296 | */ | 4292 | */ |
4297 | void btrfs_dirty_inode(struct inode *inode) | 4293 | void btrfs_dirty_inode(struct inode *inode, int flags) |
4298 | { | 4294 | { |
4299 | struct btrfs_root *root = BTRFS_I(inode)->root; | 4295 | struct btrfs_root *root = BTRFS_I(inode)->root; |
4300 | struct btrfs_trans_handle *trans; | 4296 | struct btrfs_trans_handle *trans; |
@@ -4303,9 +4299,8 @@ void btrfs_dirty_inode(struct inode *inode) | |||
4303 | if (BTRFS_I(inode)->dummy_inode) | 4299 | if (BTRFS_I(inode)->dummy_inode) |
4304 | return; | 4300 | return; |
4305 | 4301 | ||
4306 | trans = btrfs_join_transaction(root, 1); | 4302 | trans = btrfs_join_transaction(root); |
4307 | BUG_ON(IS_ERR(trans)); | 4303 | BUG_ON(IS_ERR(trans)); |
4308 | btrfs_set_trans_block_group(trans, inode); | ||
4309 | 4304 | ||
4310 | ret = btrfs_update_inode(trans, root, inode); | 4305 | ret = btrfs_update_inode(trans, root, inode); |
4311 | if (ret && ret == -ENOSPC) { | 4306 | if (ret && ret == -ENOSPC) { |
@@ -4319,7 +4314,6 @@ void btrfs_dirty_inode(struct inode *inode) | |||
4319 | PTR_ERR(trans)); | 4314 | PTR_ERR(trans)); |
4320 | return; | 4315 | return; |
4321 | } | 4316 | } |
4322 | btrfs_set_trans_block_group(trans, inode); | ||
4323 | 4317 | ||
4324 | ret = btrfs_update_inode(trans, root, inode); | 4318 | ret = btrfs_update_inode(trans, root, inode); |
4325 | if (ret) { | 4319 | if (ret) { |
@@ -4418,8 +4412,8 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | |||
4418 | struct btrfs_root *root, | 4412 | struct btrfs_root *root, |
4419 | struct inode *dir, | 4413 | struct inode *dir, |
4420 | const char *name, int name_len, | 4414 | const char *name, int name_len, |
4421 | u64 ref_objectid, u64 objectid, | 4415 | u64 ref_objectid, u64 objectid, int mode, |
4422 | u64 alloc_hint, int mode, u64 *index) | 4416 | u64 *index) |
4423 | { | 4417 | { |
4424 | struct inode *inode; | 4418 | struct inode *inode; |
4425 | struct btrfs_inode_item *inode_item; | 4419 | struct btrfs_inode_item *inode_item; |
@@ -4472,8 +4466,6 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | |||
4472 | owner = 0; | 4466 | owner = 0; |
4473 | else | 4467 | else |
4474 | owner = 1; | 4468 | owner = 1; |
4475 | BTRFS_I(inode)->block_group = | ||
4476 | btrfs_find_block_group(root, 0, alloc_hint, owner); | ||
4477 | 4469 | ||
4478 | key[0].objectid = objectid; | 4470 | key[0].objectid = objectid; |
4479 | btrfs_set_key_type(&key[0], BTRFS_INODE_ITEM_KEY); | 4471 | btrfs_set_key_type(&key[0], BTRFS_INODE_ITEM_KEY); |
@@ -4629,15 +4621,13 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry, | |||
4629 | if (IS_ERR(trans)) | 4621 | if (IS_ERR(trans)) |
4630 | return PTR_ERR(trans); | 4622 | return PTR_ERR(trans); |
4631 | 4623 | ||
4632 | btrfs_set_trans_block_group(trans, dir); | ||
4633 | |||
4634 | err = btrfs_find_free_ino(root, &objectid); | 4624 | err = btrfs_find_free_ino(root, &objectid); |
4635 | if (err) | 4625 | if (err) |
4636 | goto out_unlock; | 4626 | goto out_unlock; |
4637 | 4627 | ||
4638 | inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, | 4628 | inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, |
4639 | dentry->d_name.len, btrfs_ino(dir), objectid, | 4629 | dentry->d_name.len, btrfs_ino(dir), objectid, |
4640 | BTRFS_I(dir)->block_group, mode, &index); | 4630 | mode, &index); |
4641 | if (IS_ERR(inode)) { | 4631 | if (IS_ERR(inode)) { |
4642 | err = PTR_ERR(inode); | 4632 | err = PTR_ERR(inode); |
4643 | goto out_unlock; | 4633 | goto out_unlock; |
@@ -4649,7 +4639,6 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry, | |||
4649 | goto out_unlock; | 4639 | goto out_unlock; |
4650 | } | 4640 | } |
4651 | 4641 | ||
4652 | btrfs_set_trans_block_group(trans, inode); | ||
4653 | err = btrfs_add_nondir(trans, dir, dentry, inode, 0, index); | 4642 | err = btrfs_add_nondir(trans, dir, dentry, inode, 0, index); |
4654 | if (err) | 4643 | if (err) |
4655 | drop_inode = 1; | 4644 | drop_inode = 1; |
@@ -4658,8 +4647,6 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry, | |||
4658 | init_special_inode(inode, inode->i_mode, rdev); | 4647 | init_special_inode(inode, inode->i_mode, rdev); |
4659 | btrfs_update_inode(trans, root, inode); | 4648 | btrfs_update_inode(trans, root, inode); |
4660 | } | 4649 | } |
4661 | btrfs_update_inode_block_group(trans, inode); | ||
4662 | btrfs_update_inode_block_group(trans, dir); | ||
4663 | out_unlock: | 4650 | out_unlock: |
4664 | nr = trans->blocks_used; | 4651 | nr = trans->blocks_used; |
4665 | btrfs_end_transaction_throttle(trans, root); | 4652 | btrfs_end_transaction_throttle(trans, root); |
@@ -4692,15 +4679,13 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, | |||
4692 | if (IS_ERR(trans)) | 4679 | if (IS_ERR(trans)) |
4693 | return PTR_ERR(trans); | 4680 | return PTR_ERR(trans); |
4694 | 4681 | ||
4695 | btrfs_set_trans_block_group(trans, dir); | ||
4696 | |||
4697 | err = btrfs_find_free_ino(root, &objectid); | 4682 | err = btrfs_find_free_ino(root, &objectid); |
4698 | if (err) | 4683 | if (err) |
4699 | goto out_unlock; | 4684 | goto out_unlock; |
4700 | 4685 | ||
4701 | inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, | 4686 | inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, |
4702 | dentry->d_name.len, btrfs_ino(dir), objectid, | 4687 | dentry->d_name.len, btrfs_ino(dir), objectid, |
4703 | BTRFS_I(dir)->block_group, mode, &index); | 4688 | mode, &index); |
4704 | if (IS_ERR(inode)) { | 4689 | if (IS_ERR(inode)) { |
4705 | err = PTR_ERR(inode); | 4690 | err = PTR_ERR(inode); |
4706 | goto out_unlock; | 4691 | goto out_unlock; |
@@ -4712,7 +4697,6 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, | |||
4712 | goto out_unlock; | 4697 | goto out_unlock; |
4713 | } | 4698 | } |
4714 | 4699 | ||
4715 | btrfs_set_trans_block_group(trans, inode); | ||
4716 | err = btrfs_add_nondir(trans, dir, dentry, inode, 0, index); | 4700 | err = btrfs_add_nondir(trans, dir, dentry, inode, 0, index); |
4717 | if (err) | 4701 | if (err) |
4718 | drop_inode = 1; | 4702 | drop_inode = 1; |
@@ -4723,8 +4707,6 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, | |||
4723 | inode->i_op = &btrfs_file_inode_operations; | 4707 | inode->i_op = &btrfs_file_inode_operations; |
4724 | BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops; | 4708 | BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops; |
4725 | } | 4709 | } |
4726 | btrfs_update_inode_block_group(trans, inode); | ||
4727 | btrfs_update_inode_block_group(trans, dir); | ||
4728 | out_unlock: | 4710 | out_unlock: |
4729 | nr = trans->blocks_used; | 4711 | nr = trans->blocks_used; |
4730 | btrfs_end_transaction_throttle(trans, root); | 4712 | btrfs_end_transaction_throttle(trans, root); |
@@ -4771,8 +4753,6 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, | |||
4771 | 4753 | ||
4772 | btrfs_inc_nlink(inode); | 4754 | btrfs_inc_nlink(inode); |
4773 | inode->i_ctime = CURRENT_TIME; | 4755 | inode->i_ctime = CURRENT_TIME; |
4774 | |||
4775 | btrfs_set_trans_block_group(trans, dir); | ||
4776 | ihold(inode); | 4756 | ihold(inode); |
4777 | 4757 | ||
4778 | err = btrfs_add_nondir(trans, dir, dentry, inode, 1, index); | 4758 | err = btrfs_add_nondir(trans, dir, dentry, inode, 1, index); |
@@ -4781,7 +4761,6 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, | |||
4781 | drop_inode = 1; | 4761 | drop_inode = 1; |
4782 | } else { | 4762 | } else { |
4783 | struct dentry *parent = dget_parent(dentry); | 4763 | struct dentry *parent = dget_parent(dentry); |
4784 | btrfs_update_inode_block_group(trans, dir); | ||
4785 | err = btrfs_update_inode(trans, root, inode); | 4764 | err = btrfs_update_inode(trans, root, inode); |
4786 | BUG_ON(err); | 4765 | BUG_ON(err); |
4787 | btrfs_log_new_name(trans, inode, NULL, parent); | 4766 | btrfs_log_new_name(trans, inode, NULL, parent); |
@@ -4818,7 +4797,6 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
4818 | trans = btrfs_start_transaction(root, 5); | 4797 | trans = btrfs_start_transaction(root, 5); |
4819 | if (IS_ERR(trans)) | 4798 | if (IS_ERR(trans)) |
4820 | return PTR_ERR(trans); | 4799 | return PTR_ERR(trans); |
4821 | btrfs_set_trans_block_group(trans, dir); | ||
4822 | 4800 | ||
4823 | err = btrfs_find_free_ino(root, &objectid); | 4801 | err = btrfs_find_free_ino(root, &objectid); |
4824 | if (err) | 4802 | if (err) |
@@ -4826,8 +4804,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
4826 | 4804 | ||
4827 | inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, | 4805 | inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, |
4828 | dentry->d_name.len, btrfs_ino(dir), objectid, | 4806 | dentry->d_name.len, btrfs_ino(dir), objectid, |
4829 | BTRFS_I(dir)->block_group, S_IFDIR | mode, | 4807 | S_IFDIR | mode, &index); |
4830 | &index); | ||
4831 | if (IS_ERR(inode)) { | 4808 | if (IS_ERR(inode)) { |
4832 | err = PTR_ERR(inode); | 4809 | err = PTR_ERR(inode); |
4833 | goto out_fail; | 4810 | goto out_fail; |
@@ -4841,7 +4818,6 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
4841 | 4818 | ||
4842 | inode->i_op = &btrfs_dir_inode_operations; | 4819 | inode->i_op = &btrfs_dir_inode_operations; |
4843 | inode->i_fop = &btrfs_dir_file_operations; | 4820 | inode->i_fop = &btrfs_dir_file_operations; |
4844 | btrfs_set_trans_block_group(trans, inode); | ||
4845 | 4821 | ||
4846 | btrfs_i_size_write(inode, 0); | 4822 | btrfs_i_size_write(inode, 0); |
4847 | err = btrfs_update_inode(trans, root, inode); | 4823 | err = btrfs_update_inode(trans, root, inode); |
@@ -4855,8 +4831,6 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
4855 | 4831 | ||
4856 | d_instantiate(dentry, inode); | 4832 | d_instantiate(dentry, inode); |
4857 | drop_on_err = 0; | 4833 | drop_on_err = 0; |
4858 | btrfs_update_inode_block_group(trans, inode); | ||
4859 | btrfs_update_inode_block_group(trans, dir); | ||
4860 | 4834 | ||
4861 | out_fail: | 4835 | out_fail: |
4862 | nr = trans->blocks_used; | 4836 | nr = trans->blocks_used; |
@@ -4989,7 +4963,15 @@ again: | |||
4989 | 4963 | ||
4990 | if (!path) { | 4964 | if (!path) { |
4991 | path = btrfs_alloc_path(); | 4965 | path = btrfs_alloc_path(); |
4992 | BUG_ON(!path); | 4966 | if (!path) { |
4967 | err = -ENOMEM; | ||
4968 | goto out; | ||
4969 | } | ||
4970 | /* | ||
4971 | * Chances are we'll be called again, so go ahead and do | ||
4972 | * readahead | ||
4973 | */ | ||
4974 | path->reada = 1; | ||
4993 | } | 4975 | } |
4994 | 4976 | ||
4995 | ret = btrfs_lookup_file_extent(trans, root, path, | 4977 | ret = btrfs_lookup_file_extent(trans, root, path, |
@@ -5130,8 +5112,10 @@ again: | |||
5130 | kunmap(page); | 5112 | kunmap(page); |
5131 | free_extent_map(em); | 5113 | free_extent_map(em); |
5132 | em = NULL; | 5114 | em = NULL; |
5115 | |||
5133 | btrfs_release_path(path); | 5116 | btrfs_release_path(path); |
5134 | trans = btrfs_join_transaction(root, 1); | 5117 | trans = btrfs_join_transaction(root); |
5118 | |||
5135 | if (IS_ERR(trans)) | 5119 | if (IS_ERR(trans)) |
5136 | return ERR_CAST(trans); | 5120 | return ERR_CAST(trans); |
5137 | goto again; | 5121 | goto again; |
@@ -5375,7 +5359,7 @@ static struct extent_map *btrfs_new_extent_direct(struct inode *inode, | |||
5375 | btrfs_drop_extent_cache(inode, start, start + len - 1, 0); | 5359 | btrfs_drop_extent_cache(inode, start, start + len - 1, 0); |
5376 | } | 5360 | } |
5377 | 5361 | ||
5378 | trans = btrfs_join_transaction(root, 0); | 5362 | trans = btrfs_join_transaction(root); |
5379 | if (IS_ERR(trans)) | 5363 | if (IS_ERR(trans)) |
5380 | return ERR_CAST(trans); | 5364 | return ERR_CAST(trans); |
5381 | 5365 | ||
@@ -5611,7 +5595,7 @@ static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock, | |||
5611 | * to make sure the current transaction stays open | 5595 | * to make sure the current transaction stays open |
5612 | * while we look for nocow cross refs | 5596 | * while we look for nocow cross refs |
5613 | */ | 5597 | */ |
5614 | trans = btrfs_join_transaction(root, 0); | 5598 | trans = btrfs_join_transaction(root); |
5615 | if (IS_ERR(trans)) | 5599 | if (IS_ERR(trans)) |
5616 | goto must_cow; | 5600 | goto must_cow; |
5617 | 5601 | ||
@@ -5750,7 +5734,7 @@ again: | |||
5750 | 5734 | ||
5751 | BUG_ON(!ordered); | 5735 | BUG_ON(!ordered); |
5752 | 5736 | ||
5753 | trans = btrfs_join_transaction(root, 1); | 5737 | trans = btrfs_join_transaction(root); |
5754 | if (IS_ERR(trans)) { | 5738 | if (IS_ERR(trans)) { |
5755 | err = -ENOMEM; | 5739 | err = -ENOMEM; |
5756 | goto out; | 5740 | goto out; |
@@ -6500,6 +6484,7 @@ out: | |||
6500 | static int btrfs_truncate(struct inode *inode) | 6484 | static int btrfs_truncate(struct inode *inode) |
6501 | { | 6485 | { |
6502 | struct btrfs_root *root = BTRFS_I(inode)->root; | 6486 | struct btrfs_root *root = BTRFS_I(inode)->root; |
6487 | struct btrfs_block_rsv *rsv; | ||
6503 | int ret; | 6488 | int ret; |
6504 | int err = 0; | 6489 | int err = 0; |
6505 | struct btrfs_trans_handle *trans; | 6490 | struct btrfs_trans_handle *trans; |
@@ -6513,28 +6498,80 @@ static int btrfs_truncate(struct inode *inode) | |||
6513 | btrfs_wait_ordered_range(inode, inode->i_size & (~mask), (u64)-1); | 6498 | btrfs_wait_ordered_range(inode, inode->i_size & (~mask), (u64)-1); |
6514 | btrfs_ordered_update_i_size(inode, inode->i_size, NULL); | 6499 | btrfs_ordered_update_i_size(inode, inode->i_size, NULL); |
6515 | 6500 | ||
6516 | trans = btrfs_start_transaction(root, 5); | 6501 | /* |
6517 | if (IS_ERR(trans)) | 6502 | * Yes ladies and gentelment, this is indeed ugly. The fact is we have |
6518 | return PTR_ERR(trans); | 6503 | * 3 things going on here |
6504 | * | ||
6505 | * 1) We need to reserve space for our orphan item and the space to | ||
6506 | * delete our orphan item. Lord knows we don't want to have a dangling | ||
6507 | * orphan item because we didn't reserve space to remove it. | ||
6508 | * | ||
6509 | * 2) We need to reserve space to update our inode. | ||
6510 | * | ||
6511 | * 3) We need to have something to cache all the space that is going to | ||
6512 | * be free'd up by the truncate operation, but also have some slack | ||
6513 | * space reserved in case it uses space during the truncate (thank you | ||
6514 | * very much snapshotting). | ||
6515 | * | ||
6516 | * And we need these to all be seperate. The fact is we can use alot of | ||
6517 | * space doing the truncate, and we have no earthly idea how much space | ||
6518 | * we will use, so we need the truncate reservation to be seperate so it | ||
6519 | * doesn't end up using space reserved for updating the inode or | ||
6520 | * removing the orphan item. We also need to be able to stop the | ||
6521 | * transaction and start a new one, which means we need to be able to | ||
6522 | * update the inode several times, and we have no idea of knowing how | ||
6523 | * many times that will be, so we can't just reserve 1 item for the | ||
6524 | * entirety of the opration, so that has to be done seperately as well. | ||
6525 | * Then there is the orphan item, which does indeed need to be held on | ||
6526 | * to for the whole operation, and we need nobody to touch this reserved | ||
6527 | * space except the orphan code. | ||
6528 | * | ||
6529 | * So that leaves us with | ||
6530 | * | ||
6531 | * 1) root->orphan_block_rsv - for the orphan deletion. | ||
6532 | * 2) rsv - for the truncate reservation, which we will steal from the | ||
6533 | * transaction reservation. | ||
6534 | * 3) fs_info->trans_block_rsv - this will have 1 items worth left for | ||
6535 | * updating the inode. | ||
6536 | */ | ||
6537 | rsv = btrfs_alloc_block_rsv(root); | ||
6538 | if (!rsv) | ||
6539 | return -ENOMEM; | ||
6540 | btrfs_add_durable_block_rsv(root->fs_info, rsv); | ||
6541 | |||
6542 | trans = btrfs_start_transaction(root, 4); | ||
6543 | if (IS_ERR(trans)) { | ||
6544 | err = PTR_ERR(trans); | ||
6545 | goto out; | ||
6546 | } | ||
6519 | 6547 | ||
6520 | btrfs_set_trans_block_group(trans, inode); | 6548 | /* |
6549 | * Reserve space for the truncate process. Truncate should be adding | ||
6550 | * space, but if there are snapshots it may end up using space. | ||
6551 | */ | ||
6552 | ret = btrfs_truncate_reserve_metadata(trans, root, rsv); | ||
6553 | BUG_ON(ret); | ||
6521 | 6554 | ||
6522 | ret = btrfs_orphan_add(trans, inode); | 6555 | ret = btrfs_orphan_add(trans, inode); |
6523 | if (ret) { | 6556 | if (ret) { |
6524 | btrfs_end_transaction(trans, root); | 6557 | btrfs_end_transaction(trans, root); |
6525 | return ret; | 6558 | goto out; |
6526 | } | 6559 | } |
6527 | 6560 | ||
6528 | nr = trans->blocks_used; | 6561 | nr = trans->blocks_used; |
6529 | btrfs_end_transaction(trans, root); | 6562 | btrfs_end_transaction(trans, root); |
6530 | btrfs_btree_balance_dirty(root, nr); | 6563 | btrfs_btree_balance_dirty(root, nr); |
6531 | 6564 | ||
6532 | /* Now start a transaction for the truncate */ | 6565 | /* |
6533 | trans = btrfs_start_transaction(root, 0); | 6566 | * Ok so we've already migrated our bytes over for the truncate, so here |
6534 | if (IS_ERR(trans)) | 6567 | * just reserve the one slot we need for updating the inode. |
6535 | return PTR_ERR(trans); | 6568 | */ |
6536 | btrfs_set_trans_block_group(trans, inode); | 6569 | trans = btrfs_start_transaction(root, 1); |
6537 | trans->block_rsv = root->orphan_block_rsv; | 6570 | if (IS_ERR(trans)) { |
6571 | err = PTR_ERR(trans); | ||
6572 | goto out; | ||
6573 | } | ||
6574 | trans->block_rsv = rsv; | ||
6538 | 6575 | ||
6539 | /* | 6576 | /* |
6540 | * setattr is responsible for setting the ordered_data_close flag, | 6577 | * setattr is responsible for setting the ordered_data_close flag, |
@@ -6558,24 +6595,17 @@ static int btrfs_truncate(struct inode *inode) | |||
6558 | 6595 | ||
6559 | while (1) { | 6596 | while (1) { |
6560 | if (!trans) { | 6597 | if (!trans) { |
6561 | trans = btrfs_start_transaction(root, 0); | 6598 | trans = btrfs_start_transaction(root, 3); |
6562 | if (IS_ERR(trans)) | 6599 | if (IS_ERR(trans)) { |
6563 | return PTR_ERR(trans); | 6600 | err = PTR_ERR(trans); |
6564 | btrfs_set_trans_block_group(trans, inode); | 6601 | goto out; |
6565 | trans->block_rsv = root->orphan_block_rsv; | 6602 | } |
6566 | } | ||
6567 | 6603 | ||
6568 | ret = btrfs_block_rsv_check(trans, root, | 6604 | ret = btrfs_truncate_reserve_metadata(trans, root, |
6569 | root->orphan_block_rsv, 0, 5); | 6605 | rsv); |
6570 | if (ret == -EAGAIN) { | 6606 | BUG_ON(ret); |
6571 | ret = btrfs_commit_transaction(trans, root); | 6607 | |
6572 | if (ret) | 6608 | trans->block_rsv = rsv; |
6573 | return ret; | ||
6574 | trans = NULL; | ||
6575 | continue; | ||
6576 | } else if (ret) { | ||
6577 | err = ret; | ||
6578 | break; | ||
6579 | } | 6609 | } |
6580 | 6610 | ||
6581 | ret = btrfs_truncate_inode_items(trans, root, inode, | 6611 | ret = btrfs_truncate_inode_items(trans, root, inode, |
@@ -6586,6 +6616,7 @@ static int btrfs_truncate(struct inode *inode) | |||
6586 | break; | 6616 | break; |
6587 | } | 6617 | } |
6588 | 6618 | ||
6619 | trans->block_rsv = &root->fs_info->trans_block_rsv; | ||
6589 | ret = btrfs_update_inode(trans, root, inode); | 6620 | ret = btrfs_update_inode(trans, root, inode); |
6590 | if (ret) { | 6621 | if (ret) { |
6591 | err = ret; | 6622 | err = ret; |
@@ -6599,6 +6630,7 @@ static int btrfs_truncate(struct inode *inode) | |||
6599 | } | 6630 | } |
6600 | 6631 | ||
6601 | if (ret == 0 && inode->i_nlink > 0) { | 6632 | if (ret == 0 && inode->i_nlink > 0) { |
6633 | trans->block_rsv = root->orphan_block_rsv; | ||
6602 | ret = btrfs_orphan_del(trans, inode); | 6634 | ret = btrfs_orphan_del(trans, inode); |
6603 | if (ret) | 6635 | if (ret) |
6604 | err = ret; | 6636 | err = ret; |
@@ -6610,15 +6642,20 @@ static int btrfs_truncate(struct inode *inode) | |||
6610 | ret = btrfs_orphan_del(NULL, inode); | 6642 | ret = btrfs_orphan_del(NULL, inode); |
6611 | } | 6643 | } |
6612 | 6644 | ||
6645 | trans->block_rsv = &root->fs_info->trans_block_rsv; | ||
6613 | ret = btrfs_update_inode(trans, root, inode); | 6646 | ret = btrfs_update_inode(trans, root, inode); |
6614 | if (ret && !err) | 6647 | if (ret && !err) |
6615 | err = ret; | 6648 | err = ret; |
6616 | 6649 | ||
6617 | nr = trans->blocks_used; | 6650 | nr = trans->blocks_used; |
6618 | ret = btrfs_end_transaction_throttle(trans, root); | 6651 | ret = btrfs_end_transaction_throttle(trans, root); |
6652 | btrfs_btree_balance_dirty(root, nr); | ||
6653 | |||
6654 | out: | ||
6655 | btrfs_free_block_rsv(root, rsv); | ||
6656 | |||
6619 | if (ret && !err) | 6657 | if (ret && !err) |
6620 | err = ret; | 6658 | err = ret; |
6621 | btrfs_btree_balance_dirty(root, nr); | ||
6622 | 6659 | ||
6623 | return err; | 6660 | return err; |
6624 | } | 6661 | } |
@@ -6627,15 +6664,14 @@ static int btrfs_truncate(struct inode *inode) | |||
6627 | * create a new subvolume directory/inode (helper for the ioctl). | 6664 | * create a new subvolume directory/inode (helper for the ioctl). |
6628 | */ | 6665 | */ |
6629 | int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, | 6666 | int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, |
6630 | struct btrfs_root *new_root, | 6667 | struct btrfs_root *new_root, u64 new_dirid) |
6631 | u64 new_dirid, u64 alloc_hint) | ||
6632 | { | 6668 | { |
6633 | struct inode *inode; | 6669 | struct inode *inode; |
6634 | int err; | 6670 | int err; |
6635 | u64 index = 0; | 6671 | u64 index = 0; |
6636 | 6672 | ||
6637 | inode = btrfs_new_inode(trans, new_root, NULL, "..", 2, new_dirid, | 6673 | inode = btrfs_new_inode(trans, new_root, NULL, "..", 2, new_dirid, |
6638 | new_dirid, alloc_hint, S_IFDIR | 0700, &index); | 6674 | new_dirid, S_IFDIR | 0700, &index); |
6639 | if (IS_ERR(inode)) | 6675 | if (IS_ERR(inode)) |
6640 | return PTR_ERR(inode); | 6676 | return PTR_ERR(inode); |
6641 | inode->i_op = &btrfs_dir_inode_operations; | 6677 | inode->i_op = &btrfs_dir_inode_operations; |
@@ -6748,21 +6784,6 @@ void btrfs_destroy_inode(struct inode *inode) | |||
6748 | spin_unlock(&root->fs_info->ordered_extent_lock); | 6784 | spin_unlock(&root->fs_info->ordered_extent_lock); |
6749 | } | 6785 | } |
6750 | 6786 | ||
6751 | if (root == root->fs_info->tree_root) { | ||
6752 | struct btrfs_block_group_cache *block_group; | ||
6753 | |||
6754 | block_group = btrfs_lookup_block_group(root->fs_info, | ||
6755 | BTRFS_I(inode)->block_group); | ||
6756 | if (block_group && block_group->inode == inode) { | ||
6757 | spin_lock(&block_group->lock); | ||
6758 | block_group->inode = NULL; | ||
6759 | spin_unlock(&block_group->lock); | ||
6760 | btrfs_put_block_group(block_group); | ||
6761 | } else if (block_group) { | ||
6762 | btrfs_put_block_group(block_group); | ||
6763 | } | ||
6764 | } | ||
6765 | |||
6766 | spin_lock(&root->orphan_lock); | 6787 | spin_lock(&root->orphan_lock); |
6767 | if (!list_empty(&BTRFS_I(inode)->i_orphan)) { | 6788 | if (!list_empty(&BTRFS_I(inode)->i_orphan)) { |
6768 | printk(KERN_INFO "BTRFS: inode %llu still on the orphan list\n", | 6789 | printk(KERN_INFO "BTRFS: inode %llu still on the orphan list\n", |
@@ -6948,8 +6969,6 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
6948 | goto out_notrans; | 6969 | goto out_notrans; |
6949 | } | 6970 | } |
6950 | 6971 | ||
6951 | btrfs_set_trans_block_group(trans, new_dir); | ||
6952 | |||
6953 | if (dest != root) | 6972 | if (dest != root) |
6954 | btrfs_record_root_in_trans(trans, dest); | 6973 | btrfs_record_root_in_trans(trans, dest); |
6955 | 6974 | ||
@@ -7131,16 +7150,13 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, | |||
7131 | if (IS_ERR(trans)) | 7150 | if (IS_ERR(trans)) |
7132 | return PTR_ERR(trans); | 7151 | return PTR_ERR(trans); |
7133 | 7152 | ||
7134 | btrfs_set_trans_block_group(trans, dir); | ||
7135 | |||
7136 | err = btrfs_find_free_ino(root, &objectid); | 7153 | err = btrfs_find_free_ino(root, &objectid); |
7137 | if (err) | 7154 | if (err) |
7138 | goto out_unlock; | 7155 | goto out_unlock; |
7139 | 7156 | ||
7140 | inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, | 7157 | inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, |
7141 | dentry->d_name.len, btrfs_ino(dir), objectid, | 7158 | dentry->d_name.len, btrfs_ino(dir), objectid, |
7142 | BTRFS_I(dir)->block_group, S_IFLNK|S_IRWXUGO, | 7159 | S_IFLNK|S_IRWXUGO, &index); |
7143 | &index); | ||
7144 | if (IS_ERR(inode)) { | 7160 | if (IS_ERR(inode)) { |
7145 | err = PTR_ERR(inode); | 7161 | err = PTR_ERR(inode); |
7146 | goto out_unlock; | 7162 | goto out_unlock; |
@@ -7152,7 +7168,6 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, | |||
7152 | goto out_unlock; | 7168 | goto out_unlock; |
7153 | } | 7169 | } |
7154 | 7170 | ||
7155 | btrfs_set_trans_block_group(trans, inode); | ||
7156 | err = btrfs_add_nondir(trans, dir, dentry, inode, 0, index); | 7171 | err = btrfs_add_nondir(trans, dir, dentry, inode, 0, index); |
7157 | if (err) | 7172 | if (err) |
7158 | drop_inode = 1; | 7173 | drop_inode = 1; |
@@ -7163,8 +7178,6 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, | |||
7163 | inode->i_op = &btrfs_file_inode_operations; | 7178 | inode->i_op = &btrfs_file_inode_operations; |
7164 | BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops; | 7179 | BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops; |
7165 | } | 7180 | } |
7166 | btrfs_update_inode_block_group(trans, inode); | ||
7167 | btrfs_update_inode_block_group(trans, dir); | ||
7168 | if (drop_inode) | 7181 | if (drop_inode) |
7169 | goto out_unlock; | 7182 | goto out_unlock; |
7170 | 7183 | ||
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 85e818ce00c5..ac37040e426a 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -243,7 +243,7 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg) | |||
243 | ip->flags &= ~(BTRFS_INODE_COMPRESS | BTRFS_INODE_NOCOMPRESS); | 243 | ip->flags &= ~(BTRFS_INODE_COMPRESS | BTRFS_INODE_NOCOMPRESS); |
244 | } | 244 | } |
245 | 245 | ||
246 | trans = btrfs_join_transaction(root, 1); | 246 | trans = btrfs_join_transaction(root); |
247 | BUG_ON(IS_ERR(trans)); | 247 | BUG_ON(IS_ERR(trans)); |
248 | 248 | ||
249 | ret = btrfs_update_inode(trans, root, inode); | 249 | ret = btrfs_update_inode(trans, root, inode); |
@@ -414,8 +414,7 @@ static noinline int create_subvol(struct btrfs_root *root, | |||
414 | 414 | ||
415 | btrfs_record_root_in_trans(trans, new_root); | 415 | btrfs_record_root_in_trans(trans, new_root); |
416 | 416 | ||
417 | ret = btrfs_create_subvol_root(trans, new_root, new_dirid, | 417 | ret = btrfs_create_subvol_root(trans, new_root, new_dirid); |
418 | BTRFS_I(dir)->block_group); | ||
419 | /* | 418 | /* |
420 | * insert the directory item | 419 | * insert the directory item |
421 | */ | 420 | */ |
@@ -707,16 +706,17 @@ static int find_new_extents(struct btrfs_root *root, | |||
707 | struct btrfs_file_extent_item *extent; | 706 | struct btrfs_file_extent_item *extent; |
708 | int type; | 707 | int type; |
709 | int ret; | 708 | int ret; |
709 | u64 ino = btrfs_ino(inode); | ||
710 | 710 | ||
711 | path = btrfs_alloc_path(); | 711 | path = btrfs_alloc_path(); |
712 | if (!path) | 712 | if (!path) |
713 | return -ENOMEM; | 713 | return -ENOMEM; |
714 | 714 | ||
715 | min_key.objectid = inode->i_ino; | 715 | min_key.objectid = ino; |
716 | min_key.type = BTRFS_EXTENT_DATA_KEY; | 716 | min_key.type = BTRFS_EXTENT_DATA_KEY; |
717 | min_key.offset = *off; | 717 | min_key.offset = *off; |
718 | 718 | ||
719 | max_key.objectid = inode->i_ino; | 719 | max_key.objectid = ino; |
720 | max_key.type = (u8)-1; | 720 | max_key.type = (u8)-1; |
721 | max_key.offset = (u64)-1; | 721 | max_key.offset = (u64)-1; |
722 | 722 | ||
@@ -727,7 +727,7 @@ static int find_new_extents(struct btrfs_root *root, | |||
727 | path, 0, newer_than); | 727 | path, 0, newer_than); |
728 | if (ret != 0) | 728 | if (ret != 0) |
729 | goto none; | 729 | goto none; |
730 | if (min_key.objectid != inode->i_ino) | 730 | if (min_key.objectid != ino) |
731 | goto none; | 731 | goto none; |
732 | if (min_key.type != BTRFS_EXTENT_DATA_KEY) | 732 | if (min_key.type != BTRFS_EXTENT_DATA_KEY) |
733 | goto none; | 733 | goto none; |
@@ -2489,12 +2489,10 @@ static long btrfs_ioctl_trans_start(struct file *file) | |||
2489 | if (ret) | 2489 | if (ret) |
2490 | goto out; | 2490 | goto out; |
2491 | 2491 | ||
2492 | mutex_lock(&root->fs_info->trans_mutex); | 2492 | atomic_inc(&root->fs_info->open_ioctl_trans); |
2493 | root->fs_info->open_ioctl_trans++; | ||
2494 | mutex_unlock(&root->fs_info->trans_mutex); | ||
2495 | 2493 | ||
2496 | ret = -ENOMEM; | 2494 | ret = -ENOMEM; |
2497 | trans = btrfs_start_ioctl_transaction(root, 0); | 2495 | trans = btrfs_start_ioctl_transaction(root); |
2498 | if (IS_ERR(trans)) | 2496 | if (IS_ERR(trans)) |
2499 | goto out_drop; | 2497 | goto out_drop; |
2500 | 2498 | ||
@@ -2502,9 +2500,7 @@ static long btrfs_ioctl_trans_start(struct file *file) | |||
2502 | return 0; | 2500 | return 0; |
2503 | 2501 | ||
2504 | out_drop: | 2502 | out_drop: |
2505 | mutex_lock(&root->fs_info->trans_mutex); | 2503 | atomic_dec(&root->fs_info->open_ioctl_trans); |
2506 | root->fs_info->open_ioctl_trans--; | ||
2507 | mutex_unlock(&root->fs_info->trans_mutex); | ||
2508 | mnt_drop_write(file->f_path.mnt); | 2504 | mnt_drop_write(file->f_path.mnt); |
2509 | out: | 2505 | out: |
2510 | return ret; | 2506 | return ret; |
@@ -2738,9 +2734,7 @@ long btrfs_ioctl_trans_end(struct file *file) | |||
2738 | 2734 | ||
2739 | btrfs_end_transaction(trans, root); | 2735 | btrfs_end_transaction(trans, root); |
2740 | 2736 | ||
2741 | mutex_lock(&root->fs_info->trans_mutex); | 2737 | atomic_dec(&root->fs_info->open_ioctl_trans); |
2742 | root->fs_info->open_ioctl_trans--; | ||
2743 | mutex_unlock(&root->fs_info->trans_mutex); | ||
2744 | 2738 | ||
2745 | mnt_drop_write(file->f_path.mnt); | 2739 | mnt_drop_write(file->f_path.mnt); |
2746 | return 0; | 2740 | return 0; |
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index ca38eca70af0..b1ef27cc673b 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c | |||
@@ -677,6 +677,8 @@ struct backref_node *build_backref_tree(struct reloc_control *rc, | |||
677 | err = -ENOMEM; | 677 | err = -ENOMEM; |
678 | goto out; | 678 | goto out; |
679 | } | 679 | } |
680 | path1->reada = 1; | ||
681 | path2->reada = 2; | ||
680 | 682 | ||
681 | node = alloc_backref_node(cache); | 683 | node = alloc_backref_node(cache); |
682 | if (!node) { | 684 | if (!node) { |
@@ -1999,6 +2001,7 @@ static noinline_for_stack int merge_reloc_root(struct reloc_control *rc, | |||
1999 | path = btrfs_alloc_path(); | 2001 | path = btrfs_alloc_path(); |
2000 | if (!path) | 2002 | if (!path) |
2001 | return -ENOMEM; | 2003 | return -ENOMEM; |
2004 | path->reada = 1; | ||
2002 | 2005 | ||
2003 | reloc_root = root->reloc_root; | 2006 | reloc_root = root->reloc_root; |
2004 | root_item = &reloc_root->root_item; | 2007 | root_item = &reloc_root->root_item; |
@@ -2139,10 +2142,10 @@ int prepare_to_merge(struct reloc_control *rc, int err) | |||
2139 | u64 num_bytes = 0; | 2142 | u64 num_bytes = 0; |
2140 | int ret; | 2143 | int ret; |
2141 | 2144 | ||
2142 | mutex_lock(&root->fs_info->trans_mutex); | 2145 | spin_lock(&root->fs_info->trans_lock); |
2143 | rc->merging_rsv_size += root->nodesize * (BTRFS_MAX_LEVEL - 1) * 2; | 2146 | rc->merging_rsv_size += root->nodesize * (BTRFS_MAX_LEVEL - 1) * 2; |
2144 | rc->merging_rsv_size += rc->nodes_relocated * 2; | 2147 | rc->merging_rsv_size += rc->nodes_relocated * 2; |
2145 | mutex_unlock(&root->fs_info->trans_mutex); | 2148 | spin_unlock(&root->fs_info->trans_lock); |
2146 | again: | 2149 | again: |
2147 | if (!err) { | 2150 | if (!err) { |
2148 | num_bytes = rc->merging_rsv_size; | 2151 | num_bytes = rc->merging_rsv_size; |
@@ -2152,7 +2155,7 @@ again: | |||
2152 | err = ret; | 2155 | err = ret; |
2153 | } | 2156 | } |
2154 | 2157 | ||
2155 | trans = btrfs_join_transaction(rc->extent_root, 1); | 2158 | trans = btrfs_join_transaction(rc->extent_root); |
2156 | if (IS_ERR(trans)) { | 2159 | if (IS_ERR(trans)) { |
2157 | if (!err) | 2160 | if (!err) |
2158 | btrfs_block_rsv_release(rc->extent_root, | 2161 | btrfs_block_rsv_release(rc->extent_root, |
@@ -2211,9 +2214,9 @@ int merge_reloc_roots(struct reloc_control *rc) | |||
2211 | int ret; | 2214 | int ret; |
2212 | again: | 2215 | again: |
2213 | root = rc->extent_root; | 2216 | root = rc->extent_root; |
2214 | mutex_lock(&root->fs_info->trans_mutex); | 2217 | spin_lock(&root->fs_info->trans_lock); |
2215 | list_splice_init(&rc->reloc_roots, &reloc_roots); | 2218 | list_splice_init(&rc->reloc_roots, &reloc_roots); |
2216 | mutex_unlock(&root->fs_info->trans_mutex); | 2219 | spin_unlock(&root->fs_info->trans_lock); |
2217 | 2220 | ||
2218 | while (!list_empty(&reloc_roots)) { | 2221 | while (!list_empty(&reloc_roots)) { |
2219 | found = 1; | 2222 | found = 1; |
@@ -3236,7 +3239,7 @@ truncate: | |||
3236 | goto out; | 3239 | goto out; |
3237 | } | 3240 | } |
3238 | 3241 | ||
3239 | trans = btrfs_join_transaction(root, 0); | 3242 | trans = btrfs_join_transaction(root); |
3240 | if (IS_ERR(trans)) { | 3243 | if (IS_ERR(trans)) { |
3241 | btrfs_free_path(path); | 3244 | btrfs_free_path(path); |
3242 | ret = PTR_ERR(trans); | 3245 | ret = PTR_ERR(trans); |
@@ -3300,6 +3303,7 @@ static int find_data_references(struct reloc_control *rc, | |||
3300 | path = btrfs_alloc_path(); | 3303 | path = btrfs_alloc_path(); |
3301 | if (!path) | 3304 | if (!path) |
3302 | return -ENOMEM; | 3305 | return -ENOMEM; |
3306 | path->reada = 1; | ||
3303 | 3307 | ||
3304 | root = read_fs_root(rc->extent_root->fs_info, ref_root); | 3308 | root = read_fs_root(rc->extent_root->fs_info, ref_root); |
3305 | if (IS_ERR(root)) { | 3309 | if (IS_ERR(root)) { |
@@ -3586,17 +3590,17 @@ next: | |||
3586 | static void set_reloc_control(struct reloc_control *rc) | 3590 | static void set_reloc_control(struct reloc_control *rc) |
3587 | { | 3591 | { |
3588 | struct btrfs_fs_info *fs_info = rc->extent_root->fs_info; | 3592 | struct btrfs_fs_info *fs_info = rc->extent_root->fs_info; |
3589 | mutex_lock(&fs_info->trans_mutex); | 3593 | spin_lock(&fs_info->trans_lock); |
3590 | fs_info->reloc_ctl = rc; | 3594 | fs_info->reloc_ctl = rc; |
3591 | mutex_unlock(&fs_info->trans_mutex); | 3595 | spin_unlock(&fs_info->trans_lock); |
3592 | } | 3596 | } |
3593 | 3597 | ||
3594 | static void unset_reloc_control(struct reloc_control *rc) | 3598 | static void unset_reloc_control(struct reloc_control *rc) |
3595 | { | 3599 | { |
3596 | struct btrfs_fs_info *fs_info = rc->extent_root->fs_info; | 3600 | struct btrfs_fs_info *fs_info = rc->extent_root->fs_info; |
3597 | mutex_lock(&fs_info->trans_mutex); | 3601 | spin_lock(&fs_info->trans_lock); |
3598 | fs_info->reloc_ctl = NULL; | 3602 | fs_info->reloc_ctl = NULL; |
3599 | mutex_unlock(&fs_info->trans_mutex); | 3603 | spin_unlock(&fs_info->trans_lock); |
3600 | } | 3604 | } |
3601 | 3605 | ||
3602 | static int check_extent_flags(u64 flags) | 3606 | static int check_extent_flags(u64 flags) |
@@ -3645,7 +3649,7 @@ int prepare_to_relocate(struct reloc_control *rc) | |||
3645 | rc->create_reloc_tree = 1; | 3649 | rc->create_reloc_tree = 1; |
3646 | set_reloc_control(rc); | 3650 | set_reloc_control(rc); |
3647 | 3651 | ||
3648 | trans = btrfs_join_transaction(rc->extent_root, 1); | 3652 | trans = btrfs_join_transaction(rc->extent_root); |
3649 | BUG_ON(IS_ERR(trans)); | 3653 | BUG_ON(IS_ERR(trans)); |
3650 | btrfs_commit_transaction(trans, rc->extent_root); | 3654 | btrfs_commit_transaction(trans, rc->extent_root); |
3651 | return 0; | 3655 | return 0; |
@@ -3668,6 +3672,7 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc) | |||
3668 | path = btrfs_alloc_path(); | 3672 | path = btrfs_alloc_path(); |
3669 | if (!path) | 3673 | if (!path) |
3670 | return -ENOMEM; | 3674 | return -ENOMEM; |
3675 | path->reada = 1; | ||
3671 | 3676 | ||
3672 | ret = prepare_to_relocate(rc); | 3677 | ret = prepare_to_relocate(rc); |
3673 | if (ret) { | 3678 | if (ret) { |
@@ -3834,7 +3839,7 @@ restart: | |||
3834 | btrfs_block_rsv_release(rc->extent_root, rc->block_rsv, (u64)-1); | 3839 | btrfs_block_rsv_release(rc->extent_root, rc->block_rsv, (u64)-1); |
3835 | 3840 | ||
3836 | /* get rid of pinned extents */ | 3841 | /* get rid of pinned extents */ |
3837 | trans = btrfs_join_transaction(rc->extent_root, 1); | 3842 | trans = btrfs_join_transaction(rc->extent_root); |
3838 | if (IS_ERR(trans)) | 3843 | if (IS_ERR(trans)) |
3839 | err = PTR_ERR(trans); | 3844 | err = PTR_ERR(trans); |
3840 | else | 3845 | else |
@@ -4093,6 +4098,7 @@ int btrfs_recover_relocation(struct btrfs_root *root) | |||
4093 | path = btrfs_alloc_path(); | 4098 | path = btrfs_alloc_path(); |
4094 | if (!path) | 4099 | if (!path) |
4095 | return -ENOMEM; | 4100 | return -ENOMEM; |
4101 | path->reada = -1; | ||
4096 | 4102 | ||
4097 | key.objectid = BTRFS_TREE_RELOC_OBJECTID; | 4103 | key.objectid = BTRFS_TREE_RELOC_OBJECTID; |
4098 | key.type = BTRFS_ROOT_ITEM_KEY; | 4104 | key.type = BTRFS_ROOT_ITEM_KEY; |
@@ -4159,7 +4165,7 @@ int btrfs_recover_relocation(struct btrfs_root *root) | |||
4159 | 4165 | ||
4160 | set_reloc_control(rc); | 4166 | set_reloc_control(rc); |
4161 | 4167 | ||
4162 | trans = btrfs_join_transaction(rc->extent_root, 1); | 4168 | trans = btrfs_join_transaction(rc->extent_root); |
4163 | if (IS_ERR(trans)) { | 4169 | if (IS_ERR(trans)) { |
4164 | unset_reloc_control(rc); | 4170 | unset_reloc_control(rc); |
4165 | err = PTR_ERR(trans); | 4171 | err = PTR_ERR(trans); |
@@ -4193,7 +4199,7 @@ int btrfs_recover_relocation(struct btrfs_root *root) | |||
4193 | 4199 | ||
4194 | unset_reloc_control(rc); | 4200 | unset_reloc_control(rc); |
4195 | 4201 | ||
4196 | trans = btrfs_join_transaction(rc->extent_root, 1); | 4202 | trans = btrfs_join_transaction(rc->extent_root); |
4197 | if (IS_ERR(trans)) | 4203 | if (IS_ERR(trans)) |
4198 | err = PTR_ERR(trans); | 4204 | err = PTR_ERR(trans); |
4199 | else | 4205 | else |
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index 6dfed0c27ac3..df50fd1eca8f 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c | |||
@@ -117,33 +117,37 @@ static void scrub_free_csums(struct scrub_dev *sdev) | |||
117 | } | 117 | } |
118 | } | 118 | } |
119 | 119 | ||
120 | static void scrub_free_bio(struct bio *bio) | ||
121 | { | ||
122 | int i; | ||
123 | struct page *last_page = NULL; | ||
124 | |||
125 | if (!bio) | ||
126 | return; | ||
127 | |||
128 | for (i = 0; i < bio->bi_vcnt; ++i) { | ||
129 | if (bio->bi_io_vec[i].bv_page == last_page) | ||
130 | continue; | ||
131 | last_page = bio->bi_io_vec[i].bv_page; | ||
132 | __free_page(last_page); | ||
133 | } | ||
134 | bio_put(bio); | ||
135 | } | ||
136 | |||
120 | static noinline_for_stack void scrub_free_dev(struct scrub_dev *sdev) | 137 | static noinline_for_stack void scrub_free_dev(struct scrub_dev *sdev) |
121 | { | 138 | { |
122 | int i; | 139 | int i; |
123 | int j; | ||
124 | struct page *last_page; | ||
125 | 140 | ||
126 | if (!sdev) | 141 | if (!sdev) |
127 | return; | 142 | return; |
128 | 143 | ||
129 | for (i = 0; i < SCRUB_BIOS_PER_DEV; ++i) { | 144 | for (i = 0; i < SCRUB_BIOS_PER_DEV; ++i) { |
130 | struct scrub_bio *sbio = sdev->bios[i]; | 145 | struct scrub_bio *sbio = sdev->bios[i]; |
131 | struct bio *bio; | ||
132 | 146 | ||
133 | if (!sbio) | 147 | if (!sbio) |
134 | break; | 148 | break; |
135 | 149 | ||
136 | bio = sbio->bio; | 150 | scrub_free_bio(sbio->bio); |
137 | if (bio) { | ||
138 | last_page = NULL; | ||
139 | for (j = 0; j < bio->bi_vcnt; ++j) { | ||
140 | if (bio->bi_io_vec[j].bv_page == last_page) | ||
141 | continue; | ||
142 | last_page = bio->bi_io_vec[j].bv_page; | ||
143 | __free_page(last_page); | ||
144 | } | ||
145 | bio_put(bio); | ||
146 | } | ||
147 | kfree(sbio); | 151 | kfree(sbio); |
148 | } | 152 | } |
149 | 153 | ||
@@ -156,8 +160,6 @@ struct scrub_dev *scrub_setup_dev(struct btrfs_device *dev) | |||
156 | { | 160 | { |
157 | struct scrub_dev *sdev; | 161 | struct scrub_dev *sdev; |
158 | int i; | 162 | int i; |
159 | int j; | ||
160 | int ret; | ||
161 | struct btrfs_fs_info *fs_info = dev->dev_root->fs_info; | 163 | struct btrfs_fs_info *fs_info = dev->dev_root->fs_info; |
162 | 164 | ||
163 | sdev = kzalloc(sizeof(*sdev), GFP_NOFS); | 165 | sdev = kzalloc(sizeof(*sdev), GFP_NOFS); |
@@ -165,7 +167,6 @@ struct scrub_dev *scrub_setup_dev(struct btrfs_device *dev) | |||
165 | goto nomem; | 167 | goto nomem; |
166 | sdev->dev = dev; | 168 | sdev->dev = dev; |
167 | for (i = 0; i < SCRUB_BIOS_PER_DEV; ++i) { | 169 | for (i = 0; i < SCRUB_BIOS_PER_DEV; ++i) { |
168 | struct bio *bio; | ||
169 | struct scrub_bio *sbio; | 170 | struct scrub_bio *sbio; |
170 | 171 | ||
171 | sbio = kzalloc(sizeof(*sbio), GFP_NOFS); | 172 | sbio = kzalloc(sizeof(*sbio), GFP_NOFS); |
@@ -173,32 +174,10 @@ struct scrub_dev *scrub_setup_dev(struct btrfs_device *dev) | |||
173 | goto nomem; | 174 | goto nomem; |
174 | sdev->bios[i] = sbio; | 175 | sdev->bios[i] = sbio; |
175 | 176 | ||
176 | bio = bio_kmalloc(GFP_NOFS, SCRUB_PAGES_PER_BIO); | ||
177 | if (!bio) | ||
178 | goto nomem; | ||
179 | |||
180 | sbio->index = i; | 177 | sbio->index = i; |
181 | sbio->sdev = sdev; | 178 | sbio->sdev = sdev; |
182 | sbio->bio = bio; | ||
183 | sbio->count = 0; | 179 | sbio->count = 0; |
184 | sbio->work.func = scrub_checksum; | 180 | sbio->work.func = scrub_checksum; |
185 | bio->bi_private = sdev->bios[i]; | ||
186 | bio->bi_end_io = scrub_bio_end_io; | ||
187 | bio->bi_sector = 0; | ||
188 | bio->bi_bdev = dev->bdev; | ||
189 | bio->bi_size = 0; | ||
190 | |||
191 | for (j = 0; j < SCRUB_PAGES_PER_BIO; ++j) { | ||
192 | struct page *page; | ||
193 | page = alloc_page(GFP_NOFS); | ||
194 | if (!page) | ||
195 | goto nomem; | ||
196 | |||
197 | ret = bio_add_page(bio, page, PAGE_SIZE, 0); | ||
198 | if (!ret) | ||
199 | goto nomem; | ||
200 | } | ||
201 | WARN_ON(bio->bi_vcnt != SCRUB_PAGES_PER_BIO); | ||
202 | 181 | ||
203 | if (i != SCRUB_BIOS_PER_DEV-1) | 182 | if (i != SCRUB_BIOS_PER_DEV-1) |
204 | sdev->bios[i]->next_free = i + 1; | 183 | sdev->bios[i]->next_free = i + 1; |
@@ -369,9 +348,6 @@ static int scrub_fixup_io(int rw, struct block_device *bdev, sector_t sector, | |||
369 | int ret; | 348 | int ret; |
370 | DECLARE_COMPLETION_ONSTACK(complete); | 349 | DECLARE_COMPLETION_ONSTACK(complete); |
371 | 350 | ||
372 | /* we are going to wait on this IO */ | ||
373 | rw |= REQ_SYNC; | ||
374 | |||
375 | bio = bio_alloc(GFP_NOFS, 1); | 351 | bio = bio_alloc(GFP_NOFS, 1); |
376 | bio->bi_bdev = bdev; | 352 | bio->bi_bdev = bdev; |
377 | bio->bi_sector = sector; | 353 | bio->bi_sector = sector; |
@@ -380,6 +356,7 @@ static int scrub_fixup_io(int rw, struct block_device *bdev, sector_t sector, | |||
380 | bio->bi_private = &complete; | 356 | bio->bi_private = &complete; |
381 | submit_bio(rw, bio); | 357 | submit_bio(rw, bio); |
382 | 358 | ||
359 | /* this will also unplug the queue */ | ||
383 | wait_for_completion(&complete); | 360 | wait_for_completion(&complete); |
384 | 361 | ||
385 | ret = !test_bit(BIO_UPTODATE, &bio->bi_flags); | 362 | ret = !test_bit(BIO_UPTODATE, &bio->bi_flags); |
@@ -394,6 +371,7 @@ static void scrub_bio_end_io(struct bio *bio, int err) | |||
394 | struct btrfs_fs_info *fs_info = sdev->dev->dev_root->fs_info; | 371 | struct btrfs_fs_info *fs_info = sdev->dev->dev_root->fs_info; |
395 | 372 | ||
396 | sbio->err = err; | 373 | sbio->err = err; |
374 | sbio->bio = bio; | ||
397 | 375 | ||
398 | btrfs_queue_worker(&fs_info->scrub_workers, &sbio->work); | 376 | btrfs_queue_worker(&fs_info->scrub_workers, &sbio->work); |
399 | } | 377 | } |
@@ -453,6 +431,8 @@ static void scrub_checksum(struct btrfs_work *work) | |||
453 | } | 431 | } |
454 | 432 | ||
455 | out: | 433 | out: |
434 | scrub_free_bio(sbio->bio); | ||
435 | sbio->bio = NULL; | ||
456 | spin_lock(&sdev->list_lock); | 436 | spin_lock(&sdev->list_lock); |
457 | sbio->next_free = sdev->first_free; | 437 | sbio->next_free = sdev->first_free; |
458 | sdev->first_free = sbio->index; | 438 | sdev->first_free = sbio->index; |
@@ -583,25 +563,50 @@ static int scrub_checksum_super(struct scrub_bio *sbio, void *buffer) | |||
583 | static int scrub_submit(struct scrub_dev *sdev) | 563 | static int scrub_submit(struct scrub_dev *sdev) |
584 | { | 564 | { |
585 | struct scrub_bio *sbio; | 565 | struct scrub_bio *sbio; |
566 | struct bio *bio; | ||
567 | int i; | ||
586 | 568 | ||
587 | if (sdev->curr == -1) | 569 | if (sdev->curr == -1) |
588 | return 0; | 570 | return 0; |
589 | 571 | ||
590 | sbio = sdev->bios[sdev->curr]; | 572 | sbio = sdev->bios[sdev->curr]; |
591 | 573 | ||
592 | sbio->bio->bi_sector = sbio->physical >> 9; | 574 | bio = bio_alloc(GFP_NOFS, sbio->count); |
593 | sbio->bio->bi_size = sbio->count * PAGE_SIZE; | 575 | if (!bio) |
594 | sbio->bio->bi_next = NULL; | 576 | goto nomem; |
595 | sbio->bio->bi_flags |= 1 << BIO_UPTODATE; | 577 | |
596 | sbio->bio->bi_comp_cpu = -1; | 578 | bio->bi_private = sbio; |
597 | sbio->bio->bi_bdev = sdev->dev->bdev; | 579 | bio->bi_end_io = scrub_bio_end_io; |
580 | bio->bi_bdev = sdev->dev->bdev; | ||
581 | bio->bi_sector = sbio->physical >> 9; | ||
582 | |||
583 | for (i = 0; i < sbio->count; ++i) { | ||
584 | struct page *page; | ||
585 | int ret; | ||
586 | |||
587 | page = alloc_page(GFP_NOFS); | ||
588 | if (!page) | ||
589 | goto nomem; | ||
590 | |||
591 | ret = bio_add_page(bio, page, PAGE_SIZE, 0); | ||
592 | if (!ret) { | ||
593 | __free_page(page); | ||
594 | goto nomem; | ||
595 | } | ||
596 | } | ||
597 | |||
598 | sbio->err = 0; | 598 | sbio->err = 0; |
599 | sdev->curr = -1; | 599 | sdev->curr = -1; |
600 | atomic_inc(&sdev->in_flight); | 600 | atomic_inc(&sdev->in_flight); |
601 | 601 | ||
602 | submit_bio(0, sbio->bio); | 602 | submit_bio(READ, bio); |
603 | 603 | ||
604 | return 0; | 604 | return 0; |
605 | |||
606 | nomem: | ||
607 | scrub_free_bio(bio); | ||
608 | |||
609 | return -ENOMEM; | ||
605 | } | 610 | } |
606 | 611 | ||
607 | static int scrub_page(struct scrub_dev *sdev, u64 logical, u64 len, | 612 | static int scrub_page(struct scrub_dev *sdev, u64 logical, u64 len, |
@@ -633,7 +638,11 @@ again: | |||
633 | sbio->logical = logical; | 638 | sbio->logical = logical; |
634 | } else if (sbio->physical + sbio->count * PAGE_SIZE != physical || | 639 | } else if (sbio->physical + sbio->count * PAGE_SIZE != physical || |
635 | sbio->logical + sbio->count * PAGE_SIZE != logical) { | 640 | sbio->logical + sbio->count * PAGE_SIZE != logical) { |
636 | scrub_submit(sdev); | 641 | int ret; |
642 | |||
643 | ret = scrub_submit(sdev); | ||
644 | if (ret) | ||
645 | return ret; | ||
637 | goto again; | 646 | goto again; |
638 | } | 647 | } |
639 | sbio->spag[sbio->count].flags = flags; | 648 | sbio->spag[sbio->count].flags = flags; |
@@ -645,8 +654,13 @@ again: | |||
645 | memcpy(sbio->spag[sbio->count].csum, csum, sdev->csum_size); | 654 | memcpy(sbio->spag[sbio->count].csum, csum, sdev->csum_size); |
646 | } | 655 | } |
647 | ++sbio->count; | 656 | ++sbio->count; |
648 | if (sbio->count == SCRUB_PAGES_PER_BIO || force) | 657 | if (sbio->count == SCRUB_PAGES_PER_BIO || force) { |
649 | scrub_submit(sdev); | 658 | int ret; |
659 | |||
660 | ret = scrub_submit(sdev); | ||
661 | if (ret) | ||
662 | return ret; | ||
663 | } | ||
650 | 664 | ||
651 | return 0; | 665 | return 0; |
652 | } | 666 | } |
@@ -727,6 +741,7 @@ static noinline_for_stack int scrub_stripe(struct scrub_dev *sdev, | |||
727 | struct btrfs_root *root = fs_info->extent_root; | 741 | struct btrfs_root *root = fs_info->extent_root; |
728 | struct btrfs_root *csum_root = fs_info->csum_root; | 742 | struct btrfs_root *csum_root = fs_info->csum_root; |
729 | struct btrfs_extent_item *extent; | 743 | struct btrfs_extent_item *extent; |
744 | struct blk_plug plug; | ||
730 | u64 flags; | 745 | u64 flags; |
731 | int ret; | 746 | int ret; |
732 | int slot; | 747 | int slot; |
@@ -831,6 +846,7 @@ static noinline_for_stack int scrub_stripe(struct scrub_dev *sdev, | |||
831 | * the scrub. This might currently (crc32) end up to be about 1MB | 846 | * the scrub. This might currently (crc32) end up to be about 1MB |
832 | */ | 847 | */ |
833 | start_stripe = 0; | 848 | start_stripe = 0; |
849 | blk_start_plug(&plug); | ||
834 | again: | 850 | again: |
835 | logical = base + offset + start_stripe * increment; | 851 | logical = base + offset + start_stripe * increment; |
836 | for (i = start_stripe; i < nstripes; ++i) { | 852 | for (i = start_stripe; i < nstripes; ++i) { |
@@ -972,6 +988,7 @@ next: | |||
972 | scrub_submit(sdev); | 988 | scrub_submit(sdev); |
973 | 989 | ||
974 | out: | 990 | out: |
991 | blk_finish_plug(&plug); | ||
975 | btrfs_free_path(path); | 992 | btrfs_free_path(path); |
976 | return ret < 0 ? ret : 0; | 993 | return ret < 0 ? ret : 0; |
977 | } | 994 | } |
@@ -1166,7 +1183,7 @@ int btrfs_scrub_dev(struct btrfs_root *root, u64 devid, u64 start, u64 end, | |||
1166 | int ret; | 1183 | int ret; |
1167 | struct btrfs_device *dev; | 1184 | struct btrfs_device *dev; |
1168 | 1185 | ||
1169 | if (root->fs_info->closing) | 1186 | if (btrfs_fs_closing(root->fs_info)) |
1170 | return -EINVAL; | 1187 | return -EINVAL; |
1171 | 1188 | ||
1172 | /* | 1189 | /* |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 9b2e7e5bc3ef..117e74e3604b 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -161,7 +161,8 @@ enum { | |||
161 | Opt_compress_type, Opt_compress_force, Opt_compress_force_type, | 161 | Opt_compress_type, Opt_compress_force, Opt_compress_force_type, |
162 | Opt_notreelog, Opt_ratio, Opt_flushoncommit, Opt_discard, | 162 | Opt_notreelog, Opt_ratio, Opt_flushoncommit, Opt_discard, |
163 | Opt_space_cache, Opt_clear_cache, Opt_user_subvol_rm_allowed, | 163 | Opt_space_cache, Opt_clear_cache, Opt_user_subvol_rm_allowed, |
164 | Opt_enospc_debug, Opt_subvolrootid, Opt_defrag, Opt_err, | 164 | Opt_enospc_debug, Opt_subvolrootid, Opt_defrag, |
165 | Opt_inode_cache, Opt_err, | ||
165 | }; | 166 | }; |
166 | 167 | ||
167 | static match_table_t tokens = { | 168 | static match_table_t tokens = { |
@@ -193,6 +194,7 @@ static match_table_t tokens = { | |||
193 | {Opt_enospc_debug, "enospc_debug"}, | 194 | {Opt_enospc_debug, "enospc_debug"}, |
194 | {Opt_subvolrootid, "subvolrootid=%d"}, | 195 | {Opt_subvolrootid, "subvolrootid=%d"}, |
195 | {Opt_defrag, "autodefrag"}, | 196 | {Opt_defrag, "autodefrag"}, |
197 | {Opt_inode_cache, "inode_cache"}, | ||
196 | {Opt_err, NULL}, | 198 | {Opt_err, NULL}, |
197 | }; | 199 | }; |
198 | 200 | ||
@@ -361,6 +363,10 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) | |||
361 | printk(KERN_INFO "btrfs: enabling disk space caching\n"); | 363 | printk(KERN_INFO "btrfs: enabling disk space caching\n"); |
362 | btrfs_set_opt(info->mount_opt, SPACE_CACHE); | 364 | btrfs_set_opt(info->mount_opt, SPACE_CACHE); |
363 | break; | 365 | break; |
366 | case Opt_inode_cache: | ||
367 | printk(KERN_INFO "btrfs: enabling inode map caching\n"); | ||
368 | btrfs_set_opt(info->mount_opt, INODE_MAP_CACHE); | ||
369 | break; | ||
364 | case Opt_clear_cache: | 370 | case Opt_clear_cache: |
365 | printk(KERN_INFO "btrfs: force clearing of disk cache\n"); | 371 | printk(KERN_INFO "btrfs: force clearing of disk cache\n"); |
366 | btrfs_set_opt(info->mount_opt, CLEAR_CACHE); | 372 | btrfs_set_opt(info->mount_opt, CLEAR_CACHE); |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index dc80f7156923..dd719662340e 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -35,6 +35,7 @@ static noinline void put_transaction(struct btrfs_transaction *transaction) | |||
35 | { | 35 | { |
36 | WARN_ON(atomic_read(&transaction->use_count) == 0); | 36 | WARN_ON(atomic_read(&transaction->use_count) == 0); |
37 | if (atomic_dec_and_test(&transaction->use_count)) { | 37 | if (atomic_dec_and_test(&transaction->use_count)) { |
38 | BUG_ON(!list_empty(&transaction->list)); | ||
38 | memset(transaction, 0, sizeof(*transaction)); | 39 | memset(transaction, 0, sizeof(*transaction)); |
39 | kmem_cache_free(btrfs_transaction_cachep, transaction); | 40 | kmem_cache_free(btrfs_transaction_cachep, transaction); |
40 | } | 41 | } |
@@ -49,46 +50,72 @@ static noinline void switch_commit_root(struct btrfs_root *root) | |||
49 | /* | 50 | /* |
50 | * either allocate a new transaction or hop into the existing one | 51 | * either allocate a new transaction or hop into the existing one |
51 | */ | 52 | */ |
52 | static noinline int join_transaction(struct btrfs_root *root) | 53 | static noinline int join_transaction(struct btrfs_root *root, int nofail) |
53 | { | 54 | { |
54 | struct btrfs_transaction *cur_trans; | 55 | struct btrfs_transaction *cur_trans; |
56 | |||
57 | spin_lock(&root->fs_info->trans_lock); | ||
58 | if (root->fs_info->trans_no_join) { | ||
59 | if (!nofail) { | ||
60 | spin_unlock(&root->fs_info->trans_lock); | ||
61 | return -EBUSY; | ||
62 | } | ||
63 | } | ||
64 | |||
55 | cur_trans = root->fs_info->running_transaction; | 65 | cur_trans = root->fs_info->running_transaction; |
56 | if (!cur_trans) { | 66 | if (cur_trans) { |
57 | cur_trans = kmem_cache_alloc(btrfs_transaction_cachep, | 67 | atomic_inc(&cur_trans->use_count); |
58 | GFP_NOFS); | ||
59 | if (!cur_trans) | ||
60 | return -ENOMEM; | ||
61 | root->fs_info->generation++; | ||
62 | atomic_set(&cur_trans->num_writers, 1); | ||
63 | cur_trans->num_joined = 0; | ||
64 | cur_trans->transid = root->fs_info->generation; | ||
65 | init_waitqueue_head(&cur_trans->writer_wait); | ||
66 | init_waitqueue_head(&cur_trans->commit_wait); | ||
67 | cur_trans->in_commit = 0; | ||
68 | cur_trans->blocked = 0; | ||
69 | atomic_set(&cur_trans->use_count, 1); | ||
70 | cur_trans->commit_done = 0; | ||
71 | cur_trans->start_time = get_seconds(); | ||
72 | |||
73 | cur_trans->delayed_refs.root = RB_ROOT; | ||
74 | cur_trans->delayed_refs.num_entries = 0; | ||
75 | cur_trans->delayed_refs.num_heads_ready = 0; | ||
76 | cur_trans->delayed_refs.num_heads = 0; | ||
77 | cur_trans->delayed_refs.flushing = 0; | ||
78 | cur_trans->delayed_refs.run_delayed_start = 0; | ||
79 | spin_lock_init(&cur_trans->delayed_refs.lock); | ||
80 | |||
81 | INIT_LIST_HEAD(&cur_trans->pending_snapshots); | ||
82 | list_add_tail(&cur_trans->list, &root->fs_info->trans_list); | ||
83 | extent_io_tree_init(&cur_trans->dirty_pages, | ||
84 | root->fs_info->btree_inode->i_mapping); | ||
85 | spin_lock(&root->fs_info->new_trans_lock); | ||
86 | root->fs_info->running_transaction = cur_trans; | ||
87 | spin_unlock(&root->fs_info->new_trans_lock); | ||
88 | } else { | ||
89 | atomic_inc(&cur_trans->num_writers); | 68 | atomic_inc(&cur_trans->num_writers); |
90 | cur_trans->num_joined++; | 69 | cur_trans->num_joined++; |
70 | spin_unlock(&root->fs_info->trans_lock); | ||
71 | return 0; | ||
91 | } | 72 | } |
73 | spin_unlock(&root->fs_info->trans_lock); | ||
74 | |||
75 | cur_trans = kmem_cache_alloc(btrfs_transaction_cachep, GFP_NOFS); | ||
76 | if (!cur_trans) | ||
77 | return -ENOMEM; | ||
78 | spin_lock(&root->fs_info->trans_lock); | ||
79 | if (root->fs_info->running_transaction) { | ||
80 | kmem_cache_free(btrfs_transaction_cachep, cur_trans); | ||
81 | cur_trans = root->fs_info->running_transaction; | ||
82 | atomic_inc(&cur_trans->use_count); | ||
83 | atomic_inc(&cur_trans->num_writers); | ||
84 | cur_trans->num_joined++; | ||
85 | spin_unlock(&root->fs_info->trans_lock); | ||
86 | return 0; | ||
87 | } | ||
88 | atomic_set(&cur_trans->num_writers, 1); | ||
89 | cur_trans->num_joined = 0; | ||
90 | init_waitqueue_head(&cur_trans->writer_wait); | ||
91 | init_waitqueue_head(&cur_trans->commit_wait); | ||
92 | cur_trans->in_commit = 0; | ||
93 | cur_trans->blocked = 0; | ||
94 | /* | ||
95 | * One for this trans handle, one so it will live on until we | ||
96 | * commit the transaction. | ||
97 | */ | ||
98 | atomic_set(&cur_trans->use_count, 2); | ||
99 | cur_trans->commit_done = 0; | ||
100 | cur_trans->start_time = get_seconds(); | ||
101 | |||
102 | cur_trans->delayed_refs.root = RB_ROOT; | ||
103 | cur_trans->delayed_refs.num_entries = 0; | ||
104 | cur_trans->delayed_refs.num_heads_ready = 0; | ||
105 | cur_trans->delayed_refs.num_heads = 0; | ||
106 | cur_trans->delayed_refs.flushing = 0; | ||
107 | cur_trans->delayed_refs.run_delayed_start = 0; | ||
108 | spin_lock_init(&cur_trans->commit_lock); | ||
109 | spin_lock_init(&cur_trans->delayed_refs.lock); | ||
110 | |||
111 | INIT_LIST_HEAD(&cur_trans->pending_snapshots); | ||
112 | list_add_tail(&cur_trans->list, &root->fs_info->trans_list); | ||
113 | extent_io_tree_init(&cur_trans->dirty_pages, | ||
114 | root->fs_info->btree_inode->i_mapping); | ||
115 | root->fs_info->generation++; | ||
116 | cur_trans->transid = root->fs_info->generation; | ||
117 | root->fs_info->running_transaction = cur_trans; | ||
118 | spin_unlock(&root->fs_info->trans_lock); | ||
92 | 119 | ||
93 | return 0; | 120 | return 0; |
94 | } | 121 | } |
@@ -99,39 +126,28 @@ static noinline int join_transaction(struct btrfs_root *root) | |||
99 | * to make sure the old root from before we joined the transaction is deleted | 126 | * to make sure the old root from before we joined the transaction is deleted |
100 | * when the transaction commits | 127 | * when the transaction commits |
101 | */ | 128 | */ |
102 | static noinline int record_root_in_trans(struct btrfs_trans_handle *trans, | 129 | int btrfs_record_root_in_trans(struct btrfs_trans_handle *trans, |
103 | struct btrfs_root *root) | 130 | struct btrfs_root *root) |
104 | { | 131 | { |
105 | if (root->ref_cows && root->last_trans < trans->transid) { | 132 | if (root->ref_cows && root->last_trans < trans->transid) { |
106 | WARN_ON(root == root->fs_info->extent_root); | 133 | WARN_ON(root == root->fs_info->extent_root); |
107 | WARN_ON(root->commit_root != root->node); | 134 | WARN_ON(root->commit_root != root->node); |
108 | 135 | ||
136 | spin_lock(&root->fs_info->fs_roots_radix_lock); | ||
137 | if (root->last_trans == trans->transid) { | ||
138 | spin_unlock(&root->fs_info->fs_roots_radix_lock); | ||
139 | return 0; | ||
140 | } | ||
141 | root->last_trans = trans->transid; | ||
109 | radix_tree_tag_set(&root->fs_info->fs_roots_radix, | 142 | radix_tree_tag_set(&root->fs_info->fs_roots_radix, |
110 | (unsigned long)root->root_key.objectid, | 143 | (unsigned long)root->root_key.objectid, |
111 | BTRFS_ROOT_TRANS_TAG); | 144 | BTRFS_ROOT_TRANS_TAG); |
112 | root->last_trans = trans->transid; | 145 | spin_unlock(&root->fs_info->fs_roots_radix_lock); |
113 | btrfs_init_reloc_root(trans, root); | 146 | btrfs_init_reloc_root(trans, root); |
114 | } | 147 | } |
115 | return 0; | 148 | return 0; |
116 | } | 149 | } |
117 | 150 | ||
118 | int btrfs_record_root_in_trans(struct btrfs_trans_handle *trans, | ||
119 | struct btrfs_root *root) | ||
120 | { | ||
121 | if (!root->ref_cows) | ||
122 | return 0; | ||
123 | |||
124 | mutex_lock(&root->fs_info->trans_mutex); | ||
125 | if (root->last_trans == trans->transid) { | ||
126 | mutex_unlock(&root->fs_info->trans_mutex); | ||
127 | return 0; | ||
128 | } | ||
129 | |||
130 | record_root_in_trans(trans, root); | ||
131 | mutex_unlock(&root->fs_info->trans_mutex); | ||
132 | return 0; | ||
133 | } | ||
134 | |||
135 | /* wait for commit against the current transaction to become unblocked | 151 | /* wait for commit against the current transaction to become unblocked |
136 | * when this is done, it is safe to start a new transaction, but the current | 152 | * when this is done, it is safe to start a new transaction, but the current |
137 | * transaction might not be fully on disk. | 153 | * transaction might not be fully on disk. |
@@ -140,21 +156,23 @@ static void wait_current_trans(struct btrfs_root *root) | |||
140 | { | 156 | { |
141 | struct btrfs_transaction *cur_trans; | 157 | struct btrfs_transaction *cur_trans; |
142 | 158 | ||
159 | spin_lock(&root->fs_info->trans_lock); | ||
143 | cur_trans = root->fs_info->running_transaction; | 160 | cur_trans = root->fs_info->running_transaction; |
144 | if (cur_trans && cur_trans->blocked) { | 161 | if (cur_trans && cur_trans->blocked) { |
145 | DEFINE_WAIT(wait); | 162 | DEFINE_WAIT(wait); |
146 | atomic_inc(&cur_trans->use_count); | 163 | atomic_inc(&cur_trans->use_count); |
164 | spin_unlock(&root->fs_info->trans_lock); | ||
147 | while (1) { | 165 | while (1) { |
148 | prepare_to_wait(&root->fs_info->transaction_wait, &wait, | 166 | prepare_to_wait(&root->fs_info->transaction_wait, &wait, |
149 | TASK_UNINTERRUPTIBLE); | 167 | TASK_UNINTERRUPTIBLE); |
150 | if (!cur_trans->blocked) | 168 | if (!cur_trans->blocked) |
151 | break; | 169 | break; |
152 | mutex_unlock(&root->fs_info->trans_mutex); | ||
153 | schedule(); | 170 | schedule(); |
154 | mutex_lock(&root->fs_info->trans_mutex); | ||
155 | } | 171 | } |
156 | finish_wait(&root->fs_info->transaction_wait, &wait); | 172 | finish_wait(&root->fs_info->transaction_wait, &wait); |
157 | put_transaction(cur_trans); | 173 | put_transaction(cur_trans); |
174 | } else { | ||
175 | spin_unlock(&root->fs_info->trans_lock); | ||
158 | } | 176 | } |
159 | } | 177 | } |
160 | 178 | ||
@@ -167,10 +185,16 @@ enum btrfs_trans_type { | |||
167 | 185 | ||
168 | static int may_wait_transaction(struct btrfs_root *root, int type) | 186 | static int may_wait_transaction(struct btrfs_root *root, int type) |
169 | { | 187 | { |
170 | if (!root->fs_info->log_root_recovering && | 188 | if (root->fs_info->log_root_recovering) |
171 | ((type == TRANS_START && !root->fs_info->open_ioctl_trans) || | 189 | return 0; |
172 | type == TRANS_USERSPACE)) | 190 | |
191 | if (type == TRANS_USERSPACE) | ||
192 | return 1; | ||
193 | |||
194 | if (type == TRANS_START && | ||
195 | !atomic_read(&root->fs_info->open_ioctl_trans)) | ||
173 | return 1; | 196 | return 1; |
197 | |||
174 | return 0; | 198 | return 0; |
175 | } | 199 | } |
176 | 200 | ||
@@ -184,36 +208,44 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root, | |||
184 | 208 | ||
185 | if (root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) | 209 | if (root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) |
186 | return ERR_PTR(-EROFS); | 210 | return ERR_PTR(-EROFS); |
211 | |||
212 | if (current->journal_info) { | ||
213 | WARN_ON(type != TRANS_JOIN && type != TRANS_JOIN_NOLOCK); | ||
214 | h = current->journal_info; | ||
215 | h->use_count++; | ||
216 | h->orig_rsv = h->block_rsv; | ||
217 | h->block_rsv = NULL; | ||
218 | goto got_it; | ||
219 | } | ||
187 | again: | 220 | again: |
188 | h = kmem_cache_alloc(btrfs_trans_handle_cachep, GFP_NOFS); | 221 | h = kmem_cache_alloc(btrfs_trans_handle_cachep, GFP_NOFS); |
189 | if (!h) | 222 | if (!h) |
190 | return ERR_PTR(-ENOMEM); | 223 | return ERR_PTR(-ENOMEM); |
191 | 224 | ||
192 | if (type != TRANS_JOIN_NOLOCK) | ||
193 | mutex_lock(&root->fs_info->trans_mutex); | ||
194 | if (may_wait_transaction(root, type)) | 225 | if (may_wait_transaction(root, type)) |
195 | wait_current_trans(root); | 226 | wait_current_trans(root); |
196 | 227 | ||
197 | ret = join_transaction(root); | 228 | do { |
229 | ret = join_transaction(root, type == TRANS_JOIN_NOLOCK); | ||
230 | if (ret == -EBUSY) | ||
231 | wait_current_trans(root); | ||
232 | } while (ret == -EBUSY); | ||
233 | |||
198 | if (ret < 0) { | 234 | if (ret < 0) { |
199 | kmem_cache_free(btrfs_trans_handle_cachep, h); | 235 | kmem_cache_free(btrfs_trans_handle_cachep, h); |
200 | if (type != TRANS_JOIN_NOLOCK) | ||
201 | mutex_unlock(&root->fs_info->trans_mutex); | ||
202 | return ERR_PTR(ret); | 236 | return ERR_PTR(ret); |
203 | } | 237 | } |
204 | 238 | ||
205 | cur_trans = root->fs_info->running_transaction; | 239 | cur_trans = root->fs_info->running_transaction; |
206 | atomic_inc(&cur_trans->use_count); | ||
207 | if (type != TRANS_JOIN_NOLOCK) | ||
208 | mutex_unlock(&root->fs_info->trans_mutex); | ||
209 | 240 | ||
210 | h->transid = cur_trans->transid; | 241 | h->transid = cur_trans->transid; |
211 | h->transaction = cur_trans; | 242 | h->transaction = cur_trans; |
212 | h->blocks_used = 0; | 243 | h->blocks_used = 0; |
213 | h->block_group = 0; | ||
214 | h->bytes_reserved = 0; | 244 | h->bytes_reserved = 0; |
215 | h->delayed_ref_updates = 0; | 245 | h->delayed_ref_updates = 0; |
246 | h->use_count = 1; | ||
216 | h->block_rsv = NULL; | 247 | h->block_rsv = NULL; |
248 | h->orig_rsv = NULL; | ||
217 | 249 | ||
218 | smp_mb(); | 250 | smp_mb(); |
219 | if (cur_trans->blocked && may_wait_transaction(root, type)) { | 251 | if (cur_trans->blocked && may_wait_transaction(root, type)) { |
@@ -241,11 +273,8 @@ again: | |||
241 | } | 273 | } |
242 | } | 274 | } |
243 | 275 | ||
244 | if (type != TRANS_JOIN_NOLOCK) | 276 | got_it: |
245 | mutex_lock(&root->fs_info->trans_mutex); | 277 | btrfs_record_root_in_trans(h, root); |
246 | record_root_in_trans(h, root); | ||
247 | if (type != TRANS_JOIN_NOLOCK) | ||
248 | mutex_unlock(&root->fs_info->trans_mutex); | ||
249 | 278 | ||
250 | if (!current->journal_info && type != TRANS_USERSPACE) | 279 | if (!current->journal_info && type != TRANS_USERSPACE) |
251 | current->journal_info = h; | 280 | current->journal_info = h; |
@@ -257,22 +286,19 @@ struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root, | |||
257 | { | 286 | { |
258 | return start_transaction(root, num_items, TRANS_START); | 287 | return start_transaction(root, num_items, TRANS_START); |
259 | } | 288 | } |
260 | struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root, | 289 | struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root) |
261 | int num_blocks) | ||
262 | { | 290 | { |
263 | return start_transaction(root, 0, TRANS_JOIN); | 291 | return start_transaction(root, 0, TRANS_JOIN); |
264 | } | 292 | } |
265 | 293 | ||
266 | struct btrfs_trans_handle *btrfs_join_transaction_nolock(struct btrfs_root *root, | 294 | struct btrfs_trans_handle *btrfs_join_transaction_nolock(struct btrfs_root *root) |
267 | int num_blocks) | ||
268 | { | 295 | { |
269 | return start_transaction(root, 0, TRANS_JOIN_NOLOCK); | 296 | return start_transaction(root, 0, TRANS_JOIN_NOLOCK); |
270 | } | 297 | } |
271 | 298 | ||
272 | struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *r, | 299 | struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *root) |
273 | int num_blocks) | ||
274 | { | 300 | { |
275 | return start_transaction(r, 0, TRANS_USERSPACE); | 301 | return start_transaction(root, 0, TRANS_USERSPACE); |
276 | } | 302 | } |
277 | 303 | ||
278 | /* wait for a transaction commit to be fully complete */ | 304 | /* wait for a transaction commit to be fully complete */ |
@@ -280,17 +306,13 @@ static noinline int wait_for_commit(struct btrfs_root *root, | |||
280 | struct btrfs_transaction *commit) | 306 | struct btrfs_transaction *commit) |
281 | { | 307 | { |
282 | DEFINE_WAIT(wait); | 308 | DEFINE_WAIT(wait); |
283 | mutex_lock(&root->fs_info->trans_mutex); | ||
284 | while (!commit->commit_done) { | 309 | while (!commit->commit_done) { |
285 | prepare_to_wait(&commit->commit_wait, &wait, | 310 | prepare_to_wait(&commit->commit_wait, &wait, |
286 | TASK_UNINTERRUPTIBLE); | 311 | TASK_UNINTERRUPTIBLE); |
287 | if (commit->commit_done) | 312 | if (commit->commit_done) |
288 | break; | 313 | break; |
289 | mutex_unlock(&root->fs_info->trans_mutex); | ||
290 | schedule(); | 314 | schedule(); |
291 | mutex_lock(&root->fs_info->trans_mutex); | ||
292 | } | 315 | } |
293 | mutex_unlock(&root->fs_info->trans_mutex); | ||
294 | finish_wait(&commit->commit_wait, &wait); | 316 | finish_wait(&commit->commit_wait, &wait); |
295 | return 0; | 317 | return 0; |
296 | } | 318 | } |
@@ -300,59 +322,56 @@ int btrfs_wait_for_commit(struct btrfs_root *root, u64 transid) | |||
300 | struct btrfs_transaction *cur_trans = NULL, *t; | 322 | struct btrfs_transaction *cur_trans = NULL, *t; |
301 | int ret; | 323 | int ret; |
302 | 324 | ||
303 | mutex_lock(&root->fs_info->trans_mutex); | ||
304 | |||
305 | ret = 0; | 325 | ret = 0; |
306 | if (transid) { | 326 | if (transid) { |
307 | if (transid <= root->fs_info->last_trans_committed) | 327 | if (transid <= root->fs_info->last_trans_committed) |
308 | goto out_unlock; | 328 | goto out; |
309 | 329 | ||
310 | /* find specified transaction */ | 330 | /* find specified transaction */ |
331 | spin_lock(&root->fs_info->trans_lock); | ||
311 | list_for_each_entry(t, &root->fs_info->trans_list, list) { | 332 | list_for_each_entry(t, &root->fs_info->trans_list, list) { |
312 | if (t->transid == transid) { | 333 | if (t->transid == transid) { |
313 | cur_trans = t; | 334 | cur_trans = t; |
335 | atomic_inc(&cur_trans->use_count); | ||
314 | break; | 336 | break; |
315 | } | 337 | } |
316 | if (t->transid > transid) | 338 | if (t->transid > transid) |
317 | break; | 339 | break; |
318 | } | 340 | } |
341 | spin_unlock(&root->fs_info->trans_lock); | ||
319 | ret = -EINVAL; | 342 | ret = -EINVAL; |
320 | if (!cur_trans) | 343 | if (!cur_trans) |
321 | goto out_unlock; /* bad transid */ | 344 | goto out; /* bad transid */ |
322 | } else { | 345 | } else { |
323 | /* find newest transaction that is committing | committed */ | 346 | /* find newest transaction that is committing | committed */ |
347 | spin_lock(&root->fs_info->trans_lock); | ||
324 | list_for_each_entry_reverse(t, &root->fs_info->trans_list, | 348 | list_for_each_entry_reverse(t, &root->fs_info->trans_list, |
325 | list) { | 349 | list) { |
326 | if (t->in_commit) { | 350 | if (t->in_commit) { |
327 | if (t->commit_done) | 351 | if (t->commit_done) |
328 | goto out_unlock; | 352 | goto out; |
329 | cur_trans = t; | 353 | cur_trans = t; |
354 | atomic_inc(&cur_trans->use_count); | ||
330 | break; | 355 | break; |
331 | } | 356 | } |
332 | } | 357 | } |
358 | spin_unlock(&root->fs_info->trans_lock); | ||
333 | if (!cur_trans) | 359 | if (!cur_trans) |
334 | goto out_unlock; /* nothing committing|committed */ | 360 | goto out; /* nothing committing|committed */ |
335 | } | 361 | } |
336 | 362 | ||
337 | atomic_inc(&cur_trans->use_count); | ||
338 | mutex_unlock(&root->fs_info->trans_mutex); | ||
339 | |||
340 | wait_for_commit(root, cur_trans); | 363 | wait_for_commit(root, cur_trans); |
341 | 364 | ||
342 | mutex_lock(&root->fs_info->trans_mutex); | ||
343 | put_transaction(cur_trans); | 365 | put_transaction(cur_trans); |
344 | ret = 0; | 366 | ret = 0; |
345 | out_unlock: | 367 | out: |
346 | mutex_unlock(&root->fs_info->trans_mutex); | ||
347 | return ret; | 368 | return ret; |
348 | } | 369 | } |
349 | 370 | ||
350 | void btrfs_throttle(struct btrfs_root *root) | 371 | void btrfs_throttle(struct btrfs_root *root) |
351 | { | 372 | { |
352 | mutex_lock(&root->fs_info->trans_mutex); | 373 | if (!atomic_read(&root->fs_info->open_ioctl_trans)) |
353 | if (!root->fs_info->open_ioctl_trans) | ||
354 | wait_current_trans(root); | 374 | wait_current_trans(root); |
355 | mutex_unlock(&root->fs_info->trans_mutex); | ||
356 | } | 375 | } |
357 | 376 | ||
358 | static int should_end_transaction(struct btrfs_trans_handle *trans, | 377 | static int should_end_transaction(struct btrfs_trans_handle *trans, |
@@ -370,6 +389,7 @@ int btrfs_should_end_transaction(struct btrfs_trans_handle *trans, | |||
370 | struct btrfs_transaction *cur_trans = trans->transaction; | 389 | struct btrfs_transaction *cur_trans = trans->transaction; |
371 | int updates; | 390 | int updates; |
372 | 391 | ||
392 | smp_mb(); | ||
373 | if (cur_trans->blocked || cur_trans->delayed_refs.flushing) | 393 | if (cur_trans->blocked || cur_trans->delayed_refs.flushing) |
374 | return 1; | 394 | return 1; |
375 | 395 | ||
@@ -388,6 +408,11 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, | |||
388 | struct btrfs_fs_info *info = root->fs_info; | 408 | struct btrfs_fs_info *info = root->fs_info; |
389 | int count = 0; | 409 | int count = 0; |
390 | 410 | ||
411 | if (--trans->use_count) { | ||
412 | trans->block_rsv = trans->orig_rsv; | ||
413 | return 0; | ||
414 | } | ||
415 | |||
391 | while (count < 4) { | 416 | while (count < 4) { |
392 | unsigned long cur = trans->delayed_ref_updates; | 417 | unsigned long cur = trans->delayed_ref_updates; |
393 | trans->delayed_ref_updates = 0; | 418 | trans->delayed_ref_updates = 0; |
@@ -410,9 +435,11 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, | |||
410 | 435 | ||
411 | btrfs_trans_release_metadata(trans, root); | 436 | btrfs_trans_release_metadata(trans, root); |
412 | 437 | ||
413 | if (lock && !root->fs_info->open_ioctl_trans && | 438 | if (lock && !atomic_read(&root->fs_info->open_ioctl_trans) && |
414 | should_end_transaction(trans, root)) | 439 | should_end_transaction(trans, root)) { |
415 | trans->transaction->blocked = 1; | 440 | trans->transaction->blocked = 1; |
441 | smp_wmb(); | ||
442 | } | ||
416 | 443 | ||
417 | if (lock && cur_trans->blocked && !cur_trans->in_commit) { | 444 | if (lock && cur_trans->blocked && !cur_trans->in_commit) { |
418 | if (throttle) | 445 | if (throttle) |
@@ -703,9 +730,9 @@ static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans, | |||
703 | */ | 730 | */ |
704 | int btrfs_add_dead_root(struct btrfs_root *root) | 731 | int btrfs_add_dead_root(struct btrfs_root *root) |
705 | { | 732 | { |
706 | mutex_lock(&root->fs_info->trans_mutex); | 733 | spin_lock(&root->fs_info->trans_lock); |
707 | list_add(&root->root_list, &root->fs_info->dead_roots); | 734 | list_add(&root->root_list, &root->fs_info->dead_roots); |
708 | mutex_unlock(&root->fs_info->trans_mutex); | 735 | spin_unlock(&root->fs_info->trans_lock); |
709 | return 0; | 736 | return 0; |
710 | } | 737 | } |
711 | 738 | ||
@@ -721,6 +748,7 @@ static noinline int commit_fs_roots(struct btrfs_trans_handle *trans, | |||
721 | int ret; | 748 | int ret; |
722 | int err = 0; | 749 | int err = 0; |
723 | 750 | ||
751 | spin_lock(&fs_info->fs_roots_radix_lock); | ||
724 | while (1) { | 752 | while (1) { |
725 | ret = radix_tree_gang_lookup_tag(&fs_info->fs_roots_radix, | 753 | ret = radix_tree_gang_lookup_tag(&fs_info->fs_roots_radix, |
726 | (void **)gang, 0, | 754 | (void **)gang, 0, |
@@ -733,6 +761,7 @@ static noinline int commit_fs_roots(struct btrfs_trans_handle *trans, | |||
733 | radix_tree_tag_clear(&fs_info->fs_roots_radix, | 761 | radix_tree_tag_clear(&fs_info->fs_roots_radix, |
734 | (unsigned long)root->root_key.objectid, | 762 | (unsigned long)root->root_key.objectid, |
735 | BTRFS_ROOT_TRANS_TAG); | 763 | BTRFS_ROOT_TRANS_TAG); |
764 | spin_unlock(&fs_info->fs_roots_radix_lock); | ||
736 | 765 | ||
737 | btrfs_free_log(trans, root); | 766 | btrfs_free_log(trans, root); |
738 | btrfs_update_reloc_root(trans, root); | 767 | btrfs_update_reloc_root(trans, root); |
@@ -753,10 +782,12 @@ static noinline int commit_fs_roots(struct btrfs_trans_handle *trans, | |||
753 | err = btrfs_update_root(trans, fs_info->tree_root, | 782 | err = btrfs_update_root(trans, fs_info->tree_root, |
754 | &root->root_key, | 783 | &root->root_key, |
755 | &root->root_item); | 784 | &root->root_item); |
785 | spin_lock(&fs_info->fs_roots_radix_lock); | ||
756 | if (err) | 786 | if (err) |
757 | break; | 787 | break; |
758 | } | 788 | } |
759 | } | 789 | } |
790 | spin_unlock(&fs_info->fs_roots_radix_lock); | ||
760 | return err; | 791 | return err; |
761 | } | 792 | } |
762 | 793 | ||
@@ -786,7 +817,7 @@ int btrfs_defrag_root(struct btrfs_root *root, int cacheonly) | |||
786 | btrfs_btree_balance_dirty(info->tree_root, nr); | 817 | btrfs_btree_balance_dirty(info->tree_root, nr); |
787 | cond_resched(); | 818 | cond_resched(); |
788 | 819 | ||
789 | if (root->fs_info->closing || ret != -EAGAIN) | 820 | if (btrfs_fs_closing(root->fs_info) || ret != -EAGAIN) |
790 | break; | 821 | break; |
791 | } | 822 | } |
792 | root->defrag_running = 0; | 823 | root->defrag_running = 0; |
@@ -851,7 +882,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
851 | parent = dget_parent(dentry); | 882 | parent = dget_parent(dentry); |
852 | parent_inode = parent->d_inode; | 883 | parent_inode = parent->d_inode; |
853 | parent_root = BTRFS_I(parent_inode)->root; | 884 | parent_root = BTRFS_I(parent_inode)->root; |
854 | record_root_in_trans(trans, parent_root); | 885 | btrfs_record_root_in_trans(trans, parent_root); |
855 | 886 | ||
856 | /* | 887 | /* |
857 | * insert the directory item | 888 | * insert the directory item |
@@ -869,7 +900,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
869 | ret = btrfs_update_inode(trans, parent_root, parent_inode); | 900 | ret = btrfs_update_inode(trans, parent_root, parent_inode); |
870 | BUG_ON(ret); | 901 | BUG_ON(ret); |
871 | 902 | ||
872 | record_root_in_trans(trans, root); | 903 | btrfs_record_root_in_trans(trans, root); |
873 | btrfs_set_root_last_snapshot(&root->root_item, trans->transid); | 904 | btrfs_set_root_last_snapshot(&root->root_item, trans->transid); |
874 | memcpy(new_root_item, &root->root_item, sizeof(*new_root_item)); | 905 | memcpy(new_root_item, &root->root_item, sizeof(*new_root_item)); |
875 | btrfs_check_and_init_root_item(new_root_item); | 906 | btrfs_check_and_init_root_item(new_root_item); |
@@ -967,20 +998,20 @@ static void update_super_roots(struct btrfs_root *root) | |||
967 | int btrfs_transaction_in_commit(struct btrfs_fs_info *info) | 998 | int btrfs_transaction_in_commit(struct btrfs_fs_info *info) |
968 | { | 999 | { |
969 | int ret = 0; | 1000 | int ret = 0; |
970 | spin_lock(&info->new_trans_lock); | 1001 | spin_lock(&info->trans_lock); |
971 | if (info->running_transaction) | 1002 | if (info->running_transaction) |
972 | ret = info->running_transaction->in_commit; | 1003 | ret = info->running_transaction->in_commit; |
973 | spin_unlock(&info->new_trans_lock); | 1004 | spin_unlock(&info->trans_lock); |
974 | return ret; | 1005 | return ret; |
975 | } | 1006 | } |
976 | 1007 | ||
977 | int btrfs_transaction_blocked(struct btrfs_fs_info *info) | 1008 | int btrfs_transaction_blocked(struct btrfs_fs_info *info) |
978 | { | 1009 | { |
979 | int ret = 0; | 1010 | int ret = 0; |
980 | spin_lock(&info->new_trans_lock); | 1011 | spin_lock(&info->trans_lock); |
981 | if (info->running_transaction) | 1012 | if (info->running_transaction) |
982 | ret = info->running_transaction->blocked; | 1013 | ret = info->running_transaction->blocked; |
983 | spin_unlock(&info->new_trans_lock); | 1014 | spin_unlock(&info->trans_lock); |
984 | return ret; | 1015 | return ret; |
985 | } | 1016 | } |
986 | 1017 | ||
@@ -1004,9 +1035,7 @@ static void wait_current_trans_commit_start(struct btrfs_root *root, | |||
1004 | &wait); | 1035 | &wait); |
1005 | break; | 1036 | break; |
1006 | } | 1037 | } |
1007 | mutex_unlock(&root->fs_info->trans_mutex); | ||
1008 | schedule(); | 1038 | schedule(); |
1009 | mutex_lock(&root->fs_info->trans_mutex); | ||
1010 | finish_wait(&root->fs_info->transaction_blocked_wait, &wait); | 1039 | finish_wait(&root->fs_info->transaction_blocked_wait, &wait); |
1011 | } | 1040 | } |
1012 | } | 1041 | } |
@@ -1032,9 +1061,7 @@ static void wait_current_trans_commit_start_and_unblock(struct btrfs_root *root, | |||
1032 | &wait); | 1061 | &wait); |
1033 | break; | 1062 | break; |
1034 | } | 1063 | } |
1035 | mutex_unlock(&root->fs_info->trans_mutex); | ||
1036 | schedule(); | 1064 | schedule(); |
1037 | mutex_lock(&root->fs_info->trans_mutex); | ||
1038 | finish_wait(&root->fs_info->transaction_wait, | 1065 | finish_wait(&root->fs_info->transaction_wait, |
1039 | &wait); | 1066 | &wait); |
1040 | } | 1067 | } |
@@ -1072,7 +1099,7 @@ int btrfs_commit_transaction_async(struct btrfs_trans_handle *trans, | |||
1072 | 1099 | ||
1073 | INIT_DELAYED_WORK(&ac->work, do_async_commit); | 1100 | INIT_DELAYED_WORK(&ac->work, do_async_commit); |
1074 | ac->root = root; | 1101 | ac->root = root; |
1075 | ac->newtrans = btrfs_join_transaction(root, 0); | 1102 | ac->newtrans = btrfs_join_transaction(root); |
1076 | if (IS_ERR(ac->newtrans)) { | 1103 | if (IS_ERR(ac->newtrans)) { |
1077 | int err = PTR_ERR(ac->newtrans); | 1104 | int err = PTR_ERR(ac->newtrans); |
1078 | kfree(ac); | 1105 | kfree(ac); |
@@ -1080,22 +1107,18 @@ int btrfs_commit_transaction_async(struct btrfs_trans_handle *trans, | |||
1080 | } | 1107 | } |
1081 | 1108 | ||
1082 | /* take transaction reference */ | 1109 | /* take transaction reference */ |
1083 | mutex_lock(&root->fs_info->trans_mutex); | ||
1084 | cur_trans = trans->transaction; | 1110 | cur_trans = trans->transaction; |
1085 | atomic_inc(&cur_trans->use_count); | 1111 | atomic_inc(&cur_trans->use_count); |
1086 | mutex_unlock(&root->fs_info->trans_mutex); | ||
1087 | 1112 | ||
1088 | btrfs_end_transaction(trans, root); | 1113 | btrfs_end_transaction(trans, root); |
1089 | schedule_delayed_work(&ac->work, 0); | 1114 | schedule_delayed_work(&ac->work, 0); |
1090 | 1115 | ||
1091 | /* wait for transaction to start and unblock */ | 1116 | /* wait for transaction to start and unblock */ |
1092 | mutex_lock(&root->fs_info->trans_mutex); | ||
1093 | if (wait_for_unblock) | 1117 | if (wait_for_unblock) |
1094 | wait_current_trans_commit_start_and_unblock(root, cur_trans); | 1118 | wait_current_trans_commit_start_and_unblock(root, cur_trans); |
1095 | else | 1119 | else |
1096 | wait_current_trans_commit_start(root, cur_trans); | 1120 | wait_current_trans_commit_start(root, cur_trans); |
1097 | put_transaction(cur_trans); | 1121 | put_transaction(cur_trans); |
1098 | mutex_unlock(&root->fs_info->trans_mutex); | ||
1099 | 1122 | ||
1100 | return 0; | 1123 | return 0; |
1101 | } | 1124 | } |
@@ -1139,38 +1162,41 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1139 | ret = btrfs_run_delayed_refs(trans, root, 0); | 1162 | ret = btrfs_run_delayed_refs(trans, root, 0); |
1140 | BUG_ON(ret); | 1163 | BUG_ON(ret); |
1141 | 1164 | ||
1142 | mutex_lock(&root->fs_info->trans_mutex); | 1165 | spin_lock(&cur_trans->commit_lock); |
1143 | if (cur_trans->in_commit) { | 1166 | if (cur_trans->in_commit) { |
1167 | spin_unlock(&cur_trans->commit_lock); | ||
1144 | atomic_inc(&cur_trans->use_count); | 1168 | atomic_inc(&cur_trans->use_count); |
1145 | mutex_unlock(&root->fs_info->trans_mutex); | ||
1146 | btrfs_end_transaction(trans, root); | 1169 | btrfs_end_transaction(trans, root); |
1147 | 1170 | ||
1148 | ret = wait_for_commit(root, cur_trans); | 1171 | ret = wait_for_commit(root, cur_trans); |
1149 | BUG_ON(ret); | 1172 | BUG_ON(ret); |
1150 | 1173 | ||
1151 | mutex_lock(&root->fs_info->trans_mutex); | ||
1152 | put_transaction(cur_trans); | 1174 | put_transaction(cur_trans); |
1153 | mutex_unlock(&root->fs_info->trans_mutex); | ||
1154 | 1175 | ||
1155 | return 0; | 1176 | return 0; |
1156 | } | 1177 | } |
1157 | 1178 | ||
1158 | trans->transaction->in_commit = 1; | 1179 | trans->transaction->in_commit = 1; |
1159 | trans->transaction->blocked = 1; | 1180 | trans->transaction->blocked = 1; |
1181 | spin_unlock(&cur_trans->commit_lock); | ||
1160 | wake_up(&root->fs_info->transaction_blocked_wait); | 1182 | wake_up(&root->fs_info->transaction_blocked_wait); |
1161 | 1183 | ||
1184 | spin_lock(&root->fs_info->trans_lock); | ||
1162 | if (cur_trans->list.prev != &root->fs_info->trans_list) { | 1185 | if (cur_trans->list.prev != &root->fs_info->trans_list) { |
1163 | prev_trans = list_entry(cur_trans->list.prev, | 1186 | prev_trans = list_entry(cur_trans->list.prev, |
1164 | struct btrfs_transaction, list); | 1187 | struct btrfs_transaction, list); |
1165 | if (!prev_trans->commit_done) { | 1188 | if (!prev_trans->commit_done) { |
1166 | atomic_inc(&prev_trans->use_count); | 1189 | atomic_inc(&prev_trans->use_count); |
1167 | mutex_unlock(&root->fs_info->trans_mutex); | 1190 | spin_unlock(&root->fs_info->trans_lock); |
1168 | 1191 | ||
1169 | wait_for_commit(root, prev_trans); | 1192 | wait_for_commit(root, prev_trans); |
1170 | 1193 | ||
1171 | mutex_lock(&root->fs_info->trans_mutex); | ||
1172 | put_transaction(prev_trans); | 1194 | put_transaction(prev_trans); |
1195 | } else { | ||
1196 | spin_unlock(&root->fs_info->trans_lock); | ||
1173 | } | 1197 | } |
1198 | } else { | ||
1199 | spin_unlock(&root->fs_info->trans_lock); | ||
1174 | } | 1200 | } |
1175 | 1201 | ||
1176 | if (now < cur_trans->start_time || now - cur_trans->start_time < 1) | 1202 | if (now < cur_trans->start_time || now - cur_trans->start_time < 1) |
@@ -1178,12 +1204,12 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1178 | 1204 | ||
1179 | do { | 1205 | do { |
1180 | int snap_pending = 0; | 1206 | int snap_pending = 0; |
1207 | |||
1181 | joined = cur_trans->num_joined; | 1208 | joined = cur_trans->num_joined; |
1182 | if (!list_empty(&trans->transaction->pending_snapshots)) | 1209 | if (!list_empty(&trans->transaction->pending_snapshots)) |
1183 | snap_pending = 1; | 1210 | snap_pending = 1; |
1184 | 1211 | ||
1185 | WARN_ON(cur_trans != trans->transaction); | 1212 | WARN_ON(cur_trans != trans->transaction); |
1186 | mutex_unlock(&root->fs_info->trans_mutex); | ||
1187 | 1213 | ||
1188 | if (flush_on_commit || snap_pending) { | 1214 | if (flush_on_commit || snap_pending) { |
1189 | btrfs_start_delalloc_inodes(root, 1); | 1215 | btrfs_start_delalloc_inodes(root, 1); |
@@ -1206,14 +1232,15 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1206 | prepare_to_wait(&cur_trans->writer_wait, &wait, | 1232 | prepare_to_wait(&cur_trans->writer_wait, &wait, |
1207 | TASK_UNINTERRUPTIBLE); | 1233 | TASK_UNINTERRUPTIBLE); |
1208 | 1234 | ||
1209 | smp_mb(); | ||
1210 | if (atomic_read(&cur_trans->num_writers) > 1) | 1235 | if (atomic_read(&cur_trans->num_writers) > 1) |
1211 | schedule_timeout(MAX_SCHEDULE_TIMEOUT); | 1236 | schedule_timeout(MAX_SCHEDULE_TIMEOUT); |
1212 | else if (should_grow) | 1237 | else if (should_grow) |
1213 | schedule_timeout(1); | 1238 | schedule_timeout(1); |
1214 | 1239 | ||
1215 | mutex_lock(&root->fs_info->trans_mutex); | ||
1216 | finish_wait(&cur_trans->writer_wait, &wait); | 1240 | finish_wait(&cur_trans->writer_wait, &wait); |
1241 | spin_lock(&root->fs_info->trans_lock); | ||
1242 | root->fs_info->trans_no_join = 1; | ||
1243 | spin_unlock(&root->fs_info->trans_lock); | ||
1217 | } while (atomic_read(&cur_trans->num_writers) > 1 || | 1244 | } while (atomic_read(&cur_trans->num_writers) > 1 || |
1218 | (should_grow && cur_trans->num_joined != joined)); | 1245 | (should_grow && cur_trans->num_joined != joined)); |
1219 | 1246 | ||
@@ -1258,9 +1285,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1258 | btrfs_prepare_extent_commit(trans, root); | 1285 | btrfs_prepare_extent_commit(trans, root); |
1259 | 1286 | ||
1260 | cur_trans = root->fs_info->running_transaction; | 1287 | cur_trans = root->fs_info->running_transaction; |
1261 | spin_lock(&root->fs_info->new_trans_lock); | ||
1262 | root->fs_info->running_transaction = NULL; | ||
1263 | spin_unlock(&root->fs_info->new_trans_lock); | ||
1264 | 1288 | ||
1265 | btrfs_set_root_node(&root->fs_info->tree_root->root_item, | 1289 | btrfs_set_root_node(&root->fs_info->tree_root->root_item, |
1266 | root->fs_info->tree_root->node); | 1290 | root->fs_info->tree_root->node); |
@@ -1281,10 +1305,13 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1281 | sizeof(root->fs_info->super_copy)); | 1305 | sizeof(root->fs_info->super_copy)); |
1282 | 1306 | ||
1283 | trans->transaction->blocked = 0; | 1307 | trans->transaction->blocked = 0; |
1308 | spin_lock(&root->fs_info->trans_lock); | ||
1309 | root->fs_info->running_transaction = NULL; | ||
1310 | root->fs_info->trans_no_join = 0; | ||
1311 | spin_unlock(&root->fs_info->trans_lock); | ||
1284 | 1312 | ||
1285 | wake_up(&root->fs_info->transaction_wait); | 1313 | wake_up(&root->fs_info->transaction_wait); |
1286 | 1314 | ||
1287 | mutex_unlock(&root->fs_info->trans_mutex); | ||
1288 | ret = btrfs_write_and_wait_transaction(trans, root); | 1315 | ret = btrfs_write_and_wait_transaction(trans, root); |
1289 | BUG_ON(ret); | 1316 | BUG_ON(ret); |
1290 | write_ctree_super(trans, root, 0); | 1317 | write_ctree_super(trans, root, 0); |
@@ -1297,22 +1324,21 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1297 | 1324 | ||
1298 | btrfs_finish_extent_commit(trans, root); | 1325 | btrfs_finish_extent_commit(trans, root); |
1299 | 1326 | ||
1300 | mutex_lock(&root->fs_info->trans_mutex); | ||
1301 | |||
1302 | cur_trans->commit_done = 1; | 1327 | cur_trans->commit_done = 1; |
1303 | 1328 | ||
1304 | root->fs_info->last_trans_committed = cur_trans->transid; | 1329 | root->fs_info->last_trans_committed = cur_trans->transid; |
1305 | 1330 | ||
1306 | wake_up(&cur_trans->commit_wait); | 1331 | wake_up(&cur_trans->commit_wait); |
1307 | 1332 | ||
1333 | spin_lock(&root->fs_info->trans_lock); | ||
1308 | list_del_init(&cur_trans->list); | 1334 | list_del_init(&cur_trans->list); |
1335 | spin_unlock(&root->fs_info->trans_lock); | ||
1336 | |||
1309 | put_transaction(cur_trans); | 1337 | put_transaction(cur_trans); |
1310 | put_transaction(cur_trans); | 1338 | put_transaction(cur_trans); |
1311 | 1339 | ||
1312 | trace_btrfs_transaction_commit(root); | 1340 | trace_btrfs_transaction_commit(root); |
1313 | 1341 | ||
1314 | mutex_unlock(&root->fs_info->trans_mutex); | ||
1315 | |||
1316 | btrfs_scrub_continue(root); | 1342 | btrfs_scrub_continue(root); |
1317 | 1343 | ||
1318 | if (current->journal_info == trans) | 1344 | if (current->journal_info == trans) |
@@ -1334,9 +1360,9 @@ int btrfs_clean_old_snapshots(struct btrfs_root *root) | |||
1334 | LIST_HEAD(list); | 1360 | LIST_HEAD(list); |
1335 | struct btrfs_fs_info *fs_info = root->fs_info; | 1361 | struct btrfs_fs_info *fs_info = root->fs_info; |
1336 | 1362 | ||
1337 | mutex_lock(&fs_info->trans_mutex); | 1363 | spin_lock(&fs_info->trans_lock); |
1338 | list_splice_init(&fs_info->dead_roots, &list); | 1364 | list_splice_init(&fs_info->dead_roots, &list); |
1339 | mutex_unlock(&fs_info->trans_mutex); | 1365 | spin_unlock(&fs_info->trans_lock); |
1340 | 1366 | ||
1341 | while (!list_empty(&list)) { | 1367 | while (!list_empty(&list)) { |
1342 | root = list_entry(list.next, struct btrfs_root, root_list); | 1368 | root = list_entry(list.next, struct btrfs_root, root_list); |
diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h index 804c88639e5d..02564e6230ac 100644 --- a/fs/btrfs/transaction.h +++ b/fs/btrfs/transaction.h | |||
@@ -28,10 +28,12 @@ struct btrfs_transaction { | |||
28 | * transaction can end | 28 | * transaction can end |
29 | */ | 29 | */ |
30 | atomic_t num_writers; | 30 | atomic_t num_writers; |
31 | atomic_t use_count; | ||
31 | 32 | ||
32 | unsigned long num_joined; | 33 | unsigned long num_joined; |
34 | |||
35 | spinlock_t commit_lock; | ||
33 | int in_commit; | 36 | int in_commit; |
34 | atomic_t use_count; | ||
35 | int commit_done; | 37 | int commit_done; |
36 | int blocked; | 38 | int blocked; |
37 | struct list_head list; | 39 | struct list_head list; |
@@ -45,13 +47,14 @@ struct btrfs_transaction { | |||
45 | 47 | ||
46 | struct btrfs_trans_handle { | 48 | struct btrfs_trans_handle { |
47 | u64 transid; | 49 | u64 transid; |
48 | u64 block_group; | ||
49 | u64 bytes_reserved; | 50 | u64 bytes_reserved; |
51 | unsigned long use_count; | ||
50 | unsigned long blocks_reserved; | 52 | unsigned long blocks_reserved; |
51 | unsigned long blocks_used; | 53 | unsigned long blocks_used; |
52 | unsigned long delayed_ref_updates; | 54 | unsigned long delayed_ref_updates; |
53 | struct btrfs_transaction *transaction; | 55 | struct btrfs_transaction *transaction; |
54 | struct btrfs_block_rsv *block_rsv; | 56 | struct btrfs_block_rsv *block_rsv; |
57 | struct btrfs_block_rsv *orig_rsv; | ||
55 | }; | 58 | }; |
56 | 59 | ||
57 | struct btrfs_pending_snapshot { | 60 | struct btrfs_pending_snapshot { |
@@ -66,19 +69,6 @@ struct btrfs_pending_snapshot { | |||
66 | struct list_head list; | 69 | struct list_head list; |
67 | }; | 70 | }; |
68 | 71 | ||
69 | static inline void btrfs_set_trans_block_group(struct btrfs_trans_handle *trans, | ||
70 | struct inode *inode) | ||
71 | { | ||
72 | trans->block_group = BTRFS_I(inode)->block_group; | ||
73 | } | ||
74 | |||
75 | static inline void btrfs_update_inode_block_group( | ||
76 | struct btrfs_trans_handle *trans, | ||
77 | struct inode *inode) | ||
78 | { | ||
79 | BTRFS_I(inode)->block_group = trans->block_group; | ||
80 | } | ||
81 | |||
82 | static inline void btrfs_set_inode_last_trans(struct btrfs_trans_handle *trans, | 72 | static inline void btrfs_set_inode_last_trans(struct btrfs_trans_handle *trans, |
83 | struct inode *inode) | 73 | struct inode *inode) |
84 | { | 74 | { |
@@ -92,12 +82,9 @@ int btrfs_end_transaction_nolock(struct btrfs_trans_handle *trans, | |||
92 | struct btrfs_root *root); | 82 | struct btrfs_root *root); |
93 | struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root, | 83 | struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root, |
94 | int num_items); | 84 | int num_items); |
95 | struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root, | 85 | struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root); |
96 | int num_blocks); | 86 | struct btrfs_trans_handle *btrfs_join_transaction_nolock(struct btrfs_root *root); |
97 | struct btrfs_trans_handle *btrfs_join_transaction_nolock(struct btrfs_root *root, | 87 | struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *root); |
98 | int num_blocks); | ||
99 | struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *r, | ||
100 | int num_blocks); | ||
101 | int btrfs_wait_for_commit(struct btrfs_root *root, u64 transid); | 88 | int btrfs_wait_for_commit(struct btrfs_root *root, u64 transid); |
102 | int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, | 89 | int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, |
103 | struct btrfs_root *root); | 90 | struct btrfs_root *root); |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index c48214ef5c09..da541dfca2e3 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -504,7 +504,7 @@ static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices) | |||
504 | BUG_ON(!new_device); | 504 | BUG_ON(!new_device); |
505 | memcpy(new_device, device, sizeof(*new_device)); | 505 | memcpy(new_device, device, sizeof(*new_device)); |
506 | new_device->name = kstrdup(device->name, GFP_NOFS); | 506 | new_device->name = kstrdup(device->name, GFP_NOFS); |
507 | BUG_ON(!new_device->name); | 507 | BUG_ON(device->name && !new_device->name); |
508 | new_device->bdev = NULL; | 508 | new_device->bdev = NULL; |
509 | new_device->writeable = 0; | 509 | new_device->writeable = 0; |
510 | new_device->in_fs_metadata = 0; | 510 | new_device->in_fs_metadata = 0; |
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c index f3107e4b4d56..5366fe452ab0 100644 --- a/fs/btrfs/xattr.c +++ b/fs/btrfs/xattr.c | |||
@@ -158,8 +158,6 @@ int __btrfs_setxattr(struct btrfs_trans_handle *trans, | |||
158 | if (IS_ERR(trans)) | 158 | if (IS_ERR(trans)) |
159 | return PTR_ERR(trans); | 159 | return PTR_ERR(trans); |
160 | 160 | ||
161 | btrfs_set_trans_block_group(trans, inode); | ||
162 | |||
163 | ret = do_setxattr(trans, inode, name, value, size, flags); | 161 | ret = do_setxattr(trans, inode, name, value, size, flags); |
164 | if (ret) | 162 | if (ret) |
165 | goto out; | 163 | goto out; |
diff --git a/fs/buffer.c b/fs/buffer.c index 698c6b2cc462..49c9aada0374 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -2382,6 +2382,7 @@ int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, | |||
2382 | ret = -EAGAIN; | 2382 | ret = -EAGAIN; |
2383 | goto out_unlock; | 2383 | goto out_unlock; |
2384 | } | 2384 | } |
2385 | wait_on_page_writeback(page); | ||
2385 | return 0; | 2386 | return 0; |
2386 | out_unlock: | 2387 | out_unlock: |
2387 | unlock_page(page); | 2388 | unlock_page(page); |
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index 8f1700623b41..21de1d6d5849 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c | |||
@@ -74,8 +74,9 @@ shrink_idmap_tree(struct rb_root *root, int nr_to_scan, int *nr_rem, | |||
74 | * Run idmap cache shrinker. | 74 | * Run idmap cache shrinker. |
75 | */ | 75 | */ |
76 | static int | 76 | static int |
77 | cifs_idmap_shrinker(struct shrinker *shrink, int nr_to_scan, gfp_t gfp_mask) | 77 | cifs_idmap_shrinker(struct shrinker *shrink, struct shrink_control *sc) |
78 | { | 78 | { |
79 | int nr_to_scan = sc->nr_to_scan; | ||
79 | int nr_del = 0; | 80 | int nr_del = 0; |
80 | int nr_rem = 0; | 81 | int nr_rem = 0; |
81 | struct rb_root *root; | 82 | struct rb_root *root; |
diff --git a/fs/coda/dir.c b/fs/coda/dir.c index a46126fd5735..2b8dae4d121e 100644 --- a/fs/coda/dir.c +++ b/fs/coda/dir.c | |||
@@ -336,8 +336,6 @@ static int coda_rmdir(struct inode *dir, struct dentry *de) | |||
336 | int len = de->d_name.len; | 336 | int len = de->d_name.len; |
337 | int error; | 337 | int error; |
338 | 338 | ||
339 | dentry_unhash(de); | ||
340 | |||
341 | error = venus_rmdir(dir->i_sb, coda_i2f(dir), name, len); | 339 | error = venus_rmdir(dir->i_sb, coda_i2f(dir), name, len); |
342 | if (!error) { | 340 | if (!error) { |
343 | /* VFS may delete the child */ | 341 | /* VFS may delete the child */ |
@@ -361,9 +359,6 @@ static int coda_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
361 | int new_length = new_dentry->d_name.len; | 359 | int new_length = new_dentry->d_name.len; |
362 | int error; | 360 | int error; |
363 | 361 | ||
364 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | ||
365 | dentry_unhash(new_dentry); | ||
366 | |||
367 | error = venus_rename(old_dir->i_sb, coda_i2f(old_dir), | 362 | error = venus_rename(old_dir->i_sb, coda_i2f(old_dir), |
368 | coda_i2f(new_dir), old_length, new_length, | 363 | coda_i2f(new_dir), old_length, new_length, |
369 | (const char *) old_name, (const char *)new_name); | 364 | (const char *) old_name, (const char *)new_name); |
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 9d17d350abc5..9a37a9b6de3a 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c | |||
@@ -1359,8 +1359,6 @@ static int configfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
1359 | struct module *subsys_owner = NULL, *dead_item_owner = NULL; | 1359 | struct module *subsys_owner = NULL, *dead_item_owner = NULL; |
1360 | int ret; | 1360 | int ret; |
1361 | 1361 | ||
1362 | dentry_unhash(dentry); | ||
1363 | |||
1364 | if (dentry->d_parent == configfs_sb->s_root) | 1362 | if (dentry->d_parent == configfs_sb->s_root) |
1365 | return -EPERM; | 1363 | return -EPERM; |
1366 | 1364 | ||
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index b8d5c8091024..58609bde3b9f 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c | |||
@@ -1024,25 +1024,25 @@ out: | |||
1024 | } | 1024 | } |
1025 | 1025 | ||
1026 | /** | 1026 | /** |
1027 | * contains_ecryptfs_marker - check for the ecryptfs marker | 1027 | * ecryptfs_validate_marker - check for the ecryptfs marker |
1028 | * @data: The data block in which to check | 1028 | * @data: The data block in which to check |
1029 | * | 1029 | * |
1030 | * Returns one if marker found; zero if not found | 1030 | * Returns zero if marker found; -EINVAL if not found |
1031 | */ | 1031 | */ |
1032 | static int contains_ecryptfs_marker(char *data) | 1032 | static int ecryptfs_validate_marker(char *data) |
1033 | { | 1033 | { |
1034 | u32 m_1, m_2; | 1034 | u32 m_1, m_2; |
1035 | 1035 | ||
1036 | m_1 = get_unaligned_be32(data); | 1036 | m_1 = get_unaligned_be32(data); |
1037 | m_2 = get_unaligned_be32(data + 4); | 1037 | m_2 = get_unaligned_be32(data + 4); |
1038 | if ((m_1 ^ MAGIC_ECRYPTFS_MARKER) == m_2) | 1038 | if ((m_1 ^ MAGIC_ECRYPTFS_MARKER) == m_2) |
1039 | return 1; | 1039 | return 0; |
1040 | ecryptfs_printk(KERN_DEBUG, "m_1 = [0x%.8x]; m_2 = [0x%.8x]; " | 1040 | ecryptfs_printk(KERN_DEBUG, "m_1 = [0x%.8x]; m_2 = [0x%.8x]; " |
1041 | "MAGIC_ECRYPTFS_MARKER = [0x%.8x]\n", m_1, m_2, | 1041 | "MAGIC_ECRYPTFS_MARKER = [0x%.8x]\n", m_1, m_2, |
1042 | MAGIC_ECRYPTFS_MARKER); | 1042 | MAGIC_ECRYPTFS_MARKER); |
1043 | ecryptfs_printk(KERN_DEBUG, "(m_1 ^ MAGIC_ECRYPTFS_MARKER) = " | 1043 | ecryptfs_printk(KERN_DEBUG, "(m_1 ^ MAGIC_ECRYPTFS_MARKER) = " |
1044 | "[0x%.8x]\n", (m_1 ^ MAGIC_ECRYPTFS_MARKER)); | 1044 | "[0x%.8x]\n", (m_1 ^ MAGIC_ECRYPTFS_MARKER)); |
1045 | return 0; | 1045 | return -EINVAL; |
1046 | } | 1046 | } |
1047 | 1047 | ||
1048 | struct ecryptfs_flag_map_elem { | 1048 | struct ecryptfs_flag_map_elem { |
@@ -1201,27 +1201,19 @@ int ecryptfs_cipher_code_to_string(char *str, u8 cipher_code) | |||
1201 | return rc; | 1201 | return rc; |
1202 | } | 1202 | } |
1203 | 1203 | ||
1204 | int ecryptfs_read_and_validate_header_region(char *data, | 1204 | int ecryptfs_read_and_validate_header_region(struct inode *inode) |
1205 | struct inode *ecryptfs_inode) | ||
1206 | { | 1205 | { |
1207 | struct ecryptfs_crypt_stat *crypt_stat = | 1206 | u8 file_size[ECRYPTFS_SIZE_AND_MARKER_BYTES]; |
1208 | &(ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat); | 1207 | u8 *marker = file_size + ECRYPTFS_FILE_SIZE_BYTES; |
1209 | int rc; | 1208 | int rc; |
1210 | 1209 | ||
1211 | if (crypt_stat->extent_size == 0) | 1210 | rc = ecryptfs_read_lower(file_size, 0, ECRYPTFS_SIZE_AND_MARKER_BYTES, |
1212 | crypt_stat->extent_size = ECRYPTFS_DEFAULT_EXTENT_SIZE; | 1211 | inode); |
1213 | rc = ecryptfs_read_lower(data, 0, crypt_stat->extent_size, | 1212 | if (rc < ECRYPTFS_SIZE_AND_MARKER_BYTES) |
1214 | ecryptfs_inode); | 1213 | return rc >= 0 ? -EINVAL : rc; |
1215 | if (rc < 0) { | 1214 | rc = ecryptfs_validate_marker(marker); |
1216 | printk(KERN_ERR "%s: Error reading header region; rc = [%d]\n", | 1215 | if (!rc) |
1217 | __func__, rc); | 1216 | ecryptfs_i_size_init(file_size, inode); |
1218 | goto out; | ||
1219 | } | ||
1220 | if (!contains_ecryptfs_marker(data + ECRYPTFS_FILE_SIZE_BYTES)) { | ||
1221 | rc = -EINVAL; | ||
1222 | } else | ||
1223 | rc = 0; | ||
1224 | out: | ||
1225 | return rc; | 1217 | return rc; |
1226 | } | 1218 | } |
1227 | 1219 | ||
@@ -1242,8 +1234,7 @@ ecryptfs_write_header_metadata(char *virt, | |||
1242 | (*written) = 6; | 1234 | (*written) = 6; |
1243 | } | 1235 | } |
1244 | 1236 | ||
1245 | struct kmem_cache *ecryptfs_header_cache_1; | 1237 | struct kmem_cache *ecryptfs_header_cache; |
1246 | struct kmem_cache *ecryptfs_header_cache_2; | ||
1247 | 1238 | ||
1248 | /** | 1239 | /** |
1249 | * ecryptfs_write_headers_virt | 1240 | * ecryptfs_write_headers_virt |
@@ -1496,11 +1487,9 @@ static int ecryptfs_read_headers_virt(char *page_virt, | |||
1496 | crypt_stat->mount_crypt_stat = &ecryptfs_superblock_to_private( | 1487 | crypt_stat->mount_crypt_stat = &ecryptfs_superblock_to_private( |
1497 | ecryptfs_dentry->d_sb)->mount_crypt_stat; | 1488 | ecryptfs_dentry->d_sb)->mount_crypt_stat; |
1498 | offset = ECRYPTFS_FILE_SIZE_BYTES; | 1489 | offset = ECRYPTFS_FILE_SIZE_BYTES; |
1499 | rc = contains_ecryptfs_marker(page_virt + offset); | 1490 | rc = ecryptfs_validate_marker(page_virt + offset); |
1500 | if (rc == 0) { | 1491 | if (rc) |
1501 | rc = -EINVAL; | ||
1502 | goto out; | 1492 | goto out; |
1503 | } | ||
1504 | if (!(crypt_stat->flags & ECRYPTFS_I_SIZE_INITIALIZED)) | 1493 | if (!(crypt_stat->flags & ECRYPTFS_I_SIZE_INITIALIZED)) |
1505 | ecryptfs_i_size_init(page_virt, ecryptfs_dentry->d_inode); | 1494 | ecryptfs_i_size_init(page_virt, ecryptfs_dentry->d_inode); |
1506 | offset += MAGIC_ECRYPTFS_MARKER_SIZE_BYTES; | 1495 | offset += MAGIC_ECRYPTFS_MARKER_SIZE_BYTES; |
@@ -1567,20 +1556,21 @@ out: | |||
1567 | return rc; | 1556 | return rc; |
1568 | } | 1557 | } |
1569 | 1558 | ||
1570 | int ecryptfs_read_and_validate_xattr_region(char *page_virt, | 1559 | int ecryptfs_read_and_validate_xattr_region(struct dentry *dentry, |
1571 | struct dentry *ecryptfs_dentry) | 1560 | struct inode *inode) |
1572 | { | 1561 | { |
1562 | u8 file_size[ECRYPTFS_SIZE_AND_MARKER_BYTES]; | ||
1563 | u8 *marker = file_size + ECRYPTFS_FILE_SIZE_BYTES; | ||
1573 | int rc; | 1564 | int rc; |
1574 | 1565 | ||
1575 | rc = ecryptfs_read_xattr_region(page_virt, ecryptfs_dentry->d_inode); | 1566 | rc = ecryptfs_getxattr_lower(ecryptfs_dentry_to_lower(dentry), |
1576 | if (rc) | 1567 | ECRYPTFS_XATTR_NAME, file_size, |
1577 | goto out; | 1568 | ECRYPTFS_SIZE_AND_MARKER_BYTES); |
1578 | if (!contains_ecryptfs_marker(page_virt + ECRYPTFS_FILE_SIZE_BYTES)) { | 1569 | if (rc < ECRYPTFS_SIZE_AND_MARKER_BYTES) |
1579 | printk(KERN_WARNING "Valid data found in [%s] xattr, but " | 1570 | return rc >= 0 ? -EINVAL : rc; |
1580 | "the marker is invalid\n", ECRYPTFS_XATTR_NAME); | 1571 | rc = ecryptfs_validate_marker(marker); |
1581 | rc = -EINVAL; | 1572 | if (!rc) |
1582 | } | 1573 | ecryptfs_i_size_init(file_size, inode); |
1583 | out: | ||
1584 | return rc; | 1574 | return rc; |
1585 | } | 1575 | } |
1586 | 1576 | ||
@@ -1610,7 +1600,7 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry) | |||
1610 | ecryptfs_copy_mount_wide_flags_to_inode_flags(crypt_stat, | 1600 | ecryptfs_copy_mount_wide_flags_to_inode_flags(crypt_stat, |
1611 | mount_crypt_stat); | 1601 | mount_crypt_stat); |
1612 | /* Read the first page from the underlying file */ | 1602 | /* Read the first page from the underlying file */ |
1613 | page_virt = kmem_cache_alloc(ecryptfs_header_cache_1, GFP_USER); | 1603 | page_virt = kmem_cache_alloc(ecryptfs_header_cache, GFP_USER); |
1614 | if (!page_virt) { | 1604 | if (!page_virt) { |
1615 | rc = -ENOMEM; | 1605 | rc = -ENOMEM; |
1616 | printk(KERN_ERR "%s: Unable to allocate page_virt\n", | 1606 | printk(KERN_ERR "%s: Unable to allocate page_virt\n", |
@@ -1655,7 +1645,7 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry) | |||
1655 | out: | 1645 | out: |
1656 | if (page_virt) { | 1646 | if (page_virt) { |
1657 | memset(page_virt, 0, PAGE_CACHE_SIZE); | 1647 | memset(page_virt, 0, PAGE_CACHE_SIZE); |
1658 | kmem_cache_free(ecryptfs_header_cache_1, page_virt); | 1648 | kmem_cache_free(ecryptfs_header_cache, page_virt); |
1659 | } | 1649 | } |
1660 | return rc; | 1650 | return rc; |
1661 | } | 1651 | } |
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index e70282775e2c..43c7c43b06f5 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
@@ -200,6 +200,8 @@ ecryptfs_get_key_payload_data(struct key *key) | |||
200 | #define MAGIC_ECRYPTFS_MARKER 0x3c81b7f5 | 200 | #define MAGIC_ECRYPTFS_MARKER 0x3c81b7f5 |
201 | #define MAGIC_ECRYPTFS_MARKER_SIZE_BYTES 8 /* 4*2 */ | 201 | #define MAGIC_ECRYPTFS_MARKER_SIZE_BYTES 8 /* 4*2 */ |
202 | #define ECRYPTFS_FILE_SIZE_BYTES (sizeof(u64)) | 202 | #define ECRYPTFS_FILE_SIZE_BYTES (sizeof(u64)) |
203 | #define ECRYPTFS_SIZE_AND_MARKER_BYTES (ECRYPTFS_FILE_SIZE_BYTES \ | ||
204 | + MAGIC_ECRYPTFS_MARKER_SIZE_BYTES) | ||
203 | #define ECRYPTFS_DEFAULT_CIPHER "aes" | 205 | #define ECRYPTFS_DEFAULT_CIPHER "aes" |
204 | #define ECRYPTFS_DEFAULT_KEY_BYTES 16 | 206 | #define ECRYPTFS_DEFAULT_KEY_BYTES 16 |
205 | #define ECRYPTFS_DEFAULT_HASH "md5" | 207 | #define ECRYPTFS_DEFAULT_HASH "md5" |
@@ -603,8 +605,7 @@ extern struct kmem_cache *ecryptfs_file_info_cache; | |||
603 | extern struct kmem_cache *ecryptfs_dentry_info_cache; | 605 | extern struct kmem_cache *ecryptfs_dentry_info_cache; |
604 | extern struct kmem_cache *ecryptfs_inode_info_cache; | 606 | extern struct kmem_cache *ecryptfs_inode_info_cache; |
605 | extern struct kmem_cache *ecryptfs_sb_info_cache; | 607 | extern struct kmem_cache *ecryptfs_sb_info_cache; |
606 | extern struct kmem_cache *ecryptfs_header_cache_1; | 608 | extern struct kmem_cache *ecryptfs_header_cache; |
607 | extern struct kmem_cache *ecryptfs_header_cache_2; | ||
608 | extern struct kmem_cache *ecryptfs_xattr_cache; | 609 | extern struct kmem_cache *ecryptfs_xattr_cache; |
609 | extern struct kmem_cache *ecryptfs_key_record_cache; | 610 | extern struct kmem_cache *ecryptfs_key_record_cache; |
610 | extern struct kmem_cache *ecryptfs_key_sig_cache; | 611 | extern struct kmem_cache *ecryptfs_key_sig_cache; |
@@ -625,14 +626,9 @@ struct ecryptfs_open_req { | |||
625 | struct list_head kthread_ctl_list; | 626 | struct list_head kthread_ctl_list; |
626 | }; | 627 | }; |
627 | 628 | ||
628 | #define ECRYPTFS_INTERPOSE_FLAG_D_ADD 0x00000001 | 629 | struct inode *ecryptfs_get_inode(struct inode *lower_inode, |
629 | int ecryptfs_interpose(struct dentry *hidden_dentry, | 630 | struct super_block *sb); |
630 | struct dentry *this_dentry, struct super_block *sb, | ||
631 | u32 flags); | ||
632 | void ecryptfs_i_size_init(const char *page_virt, struct inode *inode); | 631 | void ecryptfs_i_size_init(const char *page_virt, struct inode *inode); |
633 | int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, | ||
634 | struct dentry *lower_dentry, | ||
635 | struct inode *ecryptfs_dir_inode); | ||
636 | int ecryptfs_decode_and_decrypt_filename(char **decrypted_name, | 632 | int ecryptfs_decode_and_decrypt_filename(char **decrypted_name, |
637 | size_t *decrypted_name_size, | 633 | size_t *decrypted_name_size, |
638 | struct dentry *ecryptfs_dentry, | 634 | struct dentry *ecryptfs_dentry, |
@@ -664,10 +660,9 @@ int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry); | |||
664 | void ecryptfs_write_crypt_stat_flags(char *page_virt, | 660 | void ecryptfs_write_crypt_stat_flags(char *page_virt, |
665 | struct ecryptfs_crypt_stat *crypt_stat, | 661 | struct ecryptfs_crypt_stat *crypt_stat, |
666 | size_t *written); | 662 | size_t *written); |
667 | int ecryptfs_read_and_validate_header_region(char *data, | 663 | int ecryptfs_read_and_validate_header_region(struct inode *inode); |
668 | struct inode *ecryptfs_inode); | 664 | int ecryptfs_read_and_validate_xattr_region(struct dentry *dentry, |
669 | int ecryptfs_read_and_validate_xattr_region(char *page_virt, | 665 | struct inode *inode); |
670 | struct dentry *ecryptfs_dentry); | ||
671 | u8 ecryptfs_code_for_cipher_string(char *cipher_name, size_t key_bytes); | 666 | u8 ecryptfs_code_for_cipher_string(char *cipher_name, size_t key_bytes); |
672 | int ecryptfs_cipher_code_to_string(char *str, u8 cipher_code); | 667 | int ecryptfs_cipher_code_to_string(char *str, u8 cipher_code); |
673 | void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat); | 668 | void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat); |
@@ -679,9 +674,6 @@ int | |||
679 | ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, | 674 | ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, |
680 | unsigned char *src, struct dentry *ecryptfs_dentry); | 675 | unsigned char *src, struct dentry *ecryptfs_dentry); |
681 | int ecryptfs_truncate(struct dentry *dentry, loff_t new_length); | 676 | int ecryptfs_truncate(struct dentry *dentry, loff_t new_length); |
682 | int ecryptfs_inode_test(struct inode *inode, void *candidate_lower_inode); | ||
683 | int ecryptfs_inode_set(struct inode *inode, void *lower_inode); | ||
684 | void ecryptfs_init_inode(struct inode *inode, struct inode *lower_inode); | ||
685 | ssize_t | 677 | ssize_t |
686 | ecryptfs_getxattr_lower(struct dentry *lower_dentry, const char *name, | 678 | ecryptfs_getxattr_lower(struct dentry *lower_dentry, const char *name, |
687 | void *value, size_t size); | 679 | void *value, size_t size); |
@@ -761,7 +753,7 @@ int ecryptfs_privileged_open(struct file **lower_file, | |||
761 | struct dentry *lower_dentry, | 753 | struct dentry *lower_dentry, |
762 | struct vfsmount *lower_mnt, | 754 | struct vfsmount *lower_mnt, |
763 | const struct cred *cred); | 755 | const struct cred *cred); |
764 | int ecryptfs_get_lower_file(struct dentry *ecryptfs_dentry); | 756 | int ecryptfs_get_lower_file(struct dentry *dentry, struct inode *inode); |
765 | void ecryptfs_put_lower_file(struct inode *inode); | 757 | void ecryptfs_put_lower_file(struct inode *inode); |
766 | int | 758 | int |
767 | ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, | 759 | ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, |
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index 566e5472f78c..4ec9eb00a241 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c | |||
@@ -191,7 +191,7 @@ static int ecryptfs_open(struct inode *inode, struct file *file) | |||
191 | | ECRYPTFS_ENCRYPTED); | 191 | | ECRYPTFS_ENCRYPTED); |
192 | } | 192 | } |
193 | mutex_unlock(&crypt_stat->cs_mutex); | 193 | mutex_unlock(&crypt_stat->cs_mutex); |
194 | rc = ecryptfs_get_lower_file(ecryptfs_dentry); | 194 | rc = ecryptfs_get_lower_file(ecryptfs_dentry, inode); |
195 | if (rc) { | 195 | if (rc) { |
196 | printk(KERN_ERR "%s: Error attempting to initialize " | 196 | printk(KERN_ERR "%s: Error attempting to initialize " |
197 | "the lower file for the dentry with name " | 197 | "the lower file for the dentry with name " |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index bc116b9ffcf2..7349ade17de6 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -51,6 +51,97 @@ static void unlock_dir(struct dentry *dir) | |||
51 | dput(dir); | 51 | dput(dir); |
52 | } | 52 | } |
53 | 53 | ||
54 | static int ecryptfs_inode_test(struct inode *inode, void *lower_inode) | ||
55 | { | ||
56 | if (ecryptfs_inode_to_lower(inode) == (struct inode *)lower_inode) | ||
57 | return 1; | ||
58 | return 0; | ||
59 | } | ||
60 | |||
61 | static int ecryptfs_inode_set(struct inode *inode, void *opaque) | ||
62 | { | ||
63 | struct inode *lower_inode = opaque; | ||
64 | |||
65 | ecryptfs_set_inode_lower(inode, lower_inode); | ||
66 | fsstack_copy_attr_all(inode, lower_inode); | ||
67 | /* i_size will be overwritten for encrypted regular files */ | ||
68 | fsstack_copy_inode_size(inode, lower_inode); | ||
69 | inode->i_ino = lower_inode->i_ino; | ||
70 | inode->i_version++; | ||
71 | inode->i_mapping->a_ops = &ecryptfs_aops; | ||
72 | |||
73 | if (S_ISLNK(inode->i_mode)) | ||
74 | inode->i_op = &ecryptfs_symlink_iops; | ||
75 | else if (S_ISDIR(inode->i_mode)) | ||
76 | inode->i_op = &ecryptfs_dir_iops; | ||
77 | else | ||
78 | inode->i_op = &ecryptfs_main_iops; | ||
79 | |||
80 | if (S_ISDIR(inode->i_mode)) | ||
81 | inode->i_fop = &ecryptfs_dir_fops; | ||
82 | else if (special_file(inode->i_mode)) | ||
83 | init_special_inode(inode, inode->i_mode, inode->i_rdev); | ||
84 | else | ||
85 | inode->i_fop = &ecryptfs_main_fops; | ||
86 | |||
87 | return 0; | ||
88 | } | ||
89 | |||
90 | static struct inode *__ecryptfs_get_inode(struct inode *lower_inode, | ||
91 | struct super_block *sb) | ||
92 | { | ||
93 | struct inode *inode; | ||
94 | |||
95 | if (lower_inode->i_sb != ecryptfs_superblock_to_lower(sb)) | ||
96 | return ERR_PTR(-EXDEV); | ||
97 | if (!igrab(lower_inode)) | ||
98 | return ERR_PTR(-ESTALE); | ||
99 | inode = iget5_locked(sb, (unsigned long)lower_inode, | ||
100 | ecryptfs_inode_test, ecryptfs_inode_set, | ||
101 | lower_inode); | ||
102 | if (!inode) { | ||
103 | iput(lower_inode); | ||
104 | return ERR_PTR(-EACCES); | ||
105 | } | ||
106 | if (!(inode->i_state & I_NEW)) | ||
107 | iput(lower_inode); | ||
108 | |||
109 | return inode; | ||
110 | } | ||
111 | |||
112 | struct inode *ecryptfs_get_inode(struct inode *lower_inode, | ||
113 | struct super_block *sb) | ||
114 | { | ||
115 | struct inode *inode = __ecryptfs_get_inode(lower_inode, sb); | ||
116 | |||
117 | if (!IS_ERR(inode) && (inode->i_state & I_NEW)) | ||
118 | unlock_new_inode(inode); | ||
119 | |||
120 | return inode; | ||
121 | } | ||
122 | |||
123 | /** | ||
124 | * ecryptfs_interpose | ||
125 | * @lower_dentry: Existing dentry in the lower filesystem | ||
126 | * @dentry: ecryptfs' dentry | ||
127 | * @sb: ecryptfs's super_block | ||
128 | * | ||
129 | * Interposes upper and lower dentries. | ||
130 | * | ||
131 | * Returns zero on success; non-zero otherwise | ||
132 | */ | ||
133 | static int ecryptfs_interpose(struct dentry *lower_dentry, | ||
134 | struct dentry *dentry, struct super_block *sb) | ||
135 | { | ||
136 | struct inode *inode = ecryptfs_get_inode(lower_dentry->d_inode, sb); | ||
137 | |||
138 | if (IS_ERR(inode)) | ||
139 | return PTR_ERR(inode); | ||
140 | d_instantiate(dentry, inode); | ||
141 | |||
142 | return 0; | ||
143 | } | ||
144 | |||
54 | /** | 145 | /** |
55 | * ecryptfs_create_underlying_file | 146 | * ecryptfs_create_underlying_file |
56 | * @lower_dir_inode: inode of the parent in the lower fs of the new file | 147 | * @lower_dir_inode: inode of the parent in the lower fs of the new file |
@@ -129,7 +220,7 @@ ecryptfs_do_create(struct inode *directory_inode, | |||
129 | goto out_lock; | 220 | goto out_lock; |
130 | } | 221 | } |
131 | rc = ecryptfs_interpose(lower_dentry, ecryptfs_dentry, | 222 | rc = ecryptfs_interpose(lower_dentry, ecryptfs_dentry, |
132 | directory_inode->i_sb, 0); | 223 | directory_inode->i_sb); |
133 | if (rc) { | 224 | if (rc) { |
134 | ecryptfs_printk(KERN_ERR, "Failure in ecryptfs_interpose\n"); | 225 | ecryptfs_printk(KERN_ERR, "Failure in ecryptfs_interpose\n"); |
135 | goto out_lock; | 226 | goto out_lock; |
@@ -168,7 +259,8 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) | |||
168 | "context; rc = [%d]\n", rc); | 259 | "context; rc = [%d]\n", rc); |
169 | goto out; | 260 | goto out; |
170 | } | 261 | } |
171 | rc = ecryptfs_get_lower_file(ecryptfs_dentry); | 262 | rc = ecryptfs_get_lower_file(ecryptfs_dentry, |
263 | ecryptfs_dentry->d_inode); | ||
172 | if (rc) { | 264 | if (rc) { |
173 | printk(KERN_ERR "%s: Error attempting to initialize " | 265 | printk(KERN_ERR "%s: Error attempting to initialize " |
174 | "the lower file for the dentry with name " | 266 | "the lower file for the dentry with name " |
@@ -215,102 +307,90 @@ out: | |||
215 | return rc; | 307 | return rc; |
216 | } | 308 | } |
217 | 309 | ||
310 | static int ecryptfs_i_size_read(struct dentry *dentry, struct inode *inode) | ||
311 | { | ||
312 | struct ecryptfs_crypt_stat *crypt_stat; | ||
313 | int rc; | ||
314 | |||
315 | rc = ecryptfs_get_lower_file(dentry, inode); | ||
316 | if (rc) { | ||
317 | printk(KERN_ERR "%s: Error attempting to initialize " | ||
318 | "the lower file for the dentry with name " | ||
319 | "[%s]; rc = [%d]\n", __func__, | ||
320 | dentry->d_name.name, rc); | ||
321 | return rc; | ||
322 | } | ||
323 | |||
324 | crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; | ||
325 | /* TODO: lock for crypt_stat comparison */ | ||
326 | if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)) | ||
327 | ecryptfs_set_default_sizes(crypt_stat); | ||
328 | |||
329 | rc = ecryptfs_read_and_validate_header_region(inode); | ||
330 | ecryptfs_put_lower_file(inode); | ||
331 | if (rc) { | ||
332 | rc = ecryptfs_read_and_validate_xattr_region(dentry, inode); | ||
333 | if (!rc) | ||
334 | crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR; | ||
335 | } | ||
336 | |||
337 | /* Must return 0 to allow non-eCryptfs files to be looked up, too */ | ||
338 | return 0; | ||
339 | } | ||
340 | |||
218 | /** | 341 | /** |
219 | * ecryptfs_lookup_and_interpose_lower - Perform a lookup | 342 | * ecryptfs_lookup_interpose - Dentry interposition for a lookup |
220 | */ | 343 | */ |
221 | int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, | 344 | static int ecryptfs_lookup_interpose(struct dentry *dentry, |
222 | struct dentry *lower_dentry, | 345 | struct dentry *lower_dentry, |
223 | struct inode *ecryptfs_dir_inode) | 346 | struct inode *dir_inode) |
224 | { | 347 | { |
225 | struct dentry *lower_dir_dentry; | 348 | struct inode *inode, *lower_inode = lower_dentry->d_inode; |
349 | struct ecryptfs_dentry_info *dentry_info; | ||
226 | struct vfsmount *lower_mnt; | 350 | struct vfsmount *lower_mnt; |
227 | struct inode *lower_inode; | 351 | int rc = 0; |
228 | struct ecryptfs_crypt_stat *crypt_stat; | 352 | |
229 | char *page_virt = NULL; | 353 | lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt(dentry->d_parent)); |
230 | int put_lower = 0, rc = 0; | 354 | fsstack_copy_attr_atime(dir_inode, lower_dentry->d_parent->d_inode); |
231 | |||
232 | lower_dir_dentry = lower_dentry->d_parent; | ||
233 | lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt( | ||
234 | ecryptfs_dentry->d_parent)); | ||
235 | lower_inode = lower_dentry->d_inode; | ||
236 | fsstack_copy_attr_atime(ecryptfs_dir_inode, lower_dir_dentry->d_inode); | ||
237 | BUG_ON(!lower_dentry->d_count); | 355 | BUG_ON(!lower_dentry->d_count); |
238 | ecryptfs_set_dentry_private(ecryptfs_dentry, | 356 | |
239 | kmem_cache_alloc(ecryptfs_dentry_info_cache, | 357 | dentry_info = kmem_cache_alloc(ecryptfs_dentry_info_cache, GFP_KERNEL); |
240 | GFP_KERNEL)); | 358 | ecryptfs_set_dentry_private(dentry, dentry_info); |
241 | if (!ecryptfs_dentry_to_private(ecryptfs_dentry)) { | 359 | if (!dentry_info) { |
242 | rc = -ENOMEM; | ||
243 | printk(KERN_ERR "%s: Out of memory whilst attempting " | 360 | printk(KERN_ERR "%s: Out of memory whilst attempting " |
244 | "to allocate ecryptfs_dentry_info struct\n", | 361 | "to allocate ecryptfs_dentry_info struct\n", |
245 | __func__); | 362 | __func__); |
246 | goto out_put; | 363 | dput(lower_dentry); |
364 | mntput(lower_mnt); | ||
365 | d_drop(dentry); | ||
366 | return -ENOMEM; | ||
247 | } | 367 | } |
248 | ecryptfs_set_dentry_lower(ecryptfs_dentry, lower_dentry); | 368 | ecryptfs_set_dentry_lower(dentry, lower_dentry); |
249 | ecryptfs_set_dentry_lower_mnt(ecryptfs_dentry, lower_mnt); | 369 | ecryptfs_set_dentry_lower_mnt(dentry, lower_mnt); |
370 | |||
250 | if (!lower_dentry->d_inode) { | 371 | if (!lower_dentry->d_inode) { |
251 | /* We want to add because we couldn't find in lower */ | 372 | /* We want to add because we couldn't find in lower */ |
252 | d_add(ecryptfs_dentry, NULL); | 373 | d_add(dentry, NULL); |
253 | goto out; | 374 | return 0; |
254 | } | ||
255 | rc = ecryptfs_interpose(lower_dentry, ecryptfs_dentry, | ||
256 | ecryptfs_dir_inode->i_sb, | ||
257 | ECRYPTFS_INTERPOSE_FLAG_D_ADD); | ||
258 | if (rc) { | ||
259 | printk(KERN_ERR "%s: Error interposing; rc = [%d]\n", | ||
260 | __func__, rc); | ||
261 | goto out; | ||
262 | } | ||
263 | if (S_ISDIR(lower_inode->i_mode)) | ||
264 | goto out; | ||
265 | if (S_ISLNK(lower_inode->i_mode)) | ||
266 | goto out; | ||
267 | if (special_file(lower_inode->i_mode)) | ||
268 | goto out; | ||
269 | /* Released in this function */ | ||
270 | page_virt = kmem_cache_zalloc(ecryptfs_header_cache_2, GFP_USER); | ||
271 | if (!page_virt) { | ||
272 | printk(KERN_ERR "%s: Cannot kmem_cache_zalloc() a page\n", | ||
273 | __func__); | ||
274 | rc = -ENOMEM; | ||
275 | goto out; | ||
276 | } | 375 | } |
277 | rc = ecryptfs_get_lower_file(ecryptfs_dentry); | 376 | inode = __ecryptfs_get_inode(lower_inode, dir_inode->i_sb); |
278 | if (rc) { | 377 | if (IS_ERR(inode)) { |
279 | printk(KERN_ERR "%s: Error attempting to initialize " | 378 | printk(KERN_ERR "%s: Error interposing; rc = [%ld]\n", |
280 | "the lower file for the dentry with name " | 379 | __func__, PTR_ERR(inode)); |
281 | "[%s]; rc = [%d]\n", __func__, | 380 | return PTR_ERR(inode); |
282 | ecryptfs_dentry->d_name.name, rc); | ||
283 | goto out_free_kmem; | ||
284 | } | 381 | } |
285 | put_lower = 1; | 382 | if (S_ISREG(inode->i_mode)) { |
286 | crypt_stat = &ecryptfs_inode_to_private( | 383 | rc = ecryptfs_i_size_read(dentry, inode); |
287 | ecryptfs_dentry->d_inode)->crypt_stat; | ||
288 | /* TODO: lock for crypt_stat comparison */ | ||
289 | if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)) | ||
290 | ecryptfs_set_default_sizes(crypt_stat); | ||
291 | rc = ecryptfs_read_and_validate_header_region(page_virt, | ||
292 | ecryptfs_dentry->d_inode); | ||
293 | if (rc) { | ||
294 | memset(page_virt, 0, PAGE_CACHE_SIZE); | ||
295 | rc = ecryptfs_read_and_validate_xattr_region(page_virt, | ||
296 | ecryptfs_dentry); | ||
297 | if (rc) { | 384 | if (rc) { |
298 | rc = 0; | 385 | make_bad_inode(inode); |
299 | goto out_free_kmem; | 386 | return rc; |
300 | } | 387 | } |
301 | crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR; | ||
302 | } | 388 | } |
303 | ecryptfs_i_size_init(page_virt, ecryptfs_dentry->d_inode); | 389 | |
304 | out_free_kmem: | 390 | if (inode->i_state & I_NEW) |
305 | kmem_cache_free(ecryptfs_header_cache_2, page_virt); | 391 | unlock_new_inode(inode); |
306 | goto out; | 392 | d_add(dentry, inode); |
307 | out_put: | 393 | |
308 | dput(lower_dentry); | ||
309 | mntput(lower_mnt); | ||
310 | d_drop(ecryptfs_dentry); | ||
311 | out: | ||
312 | if (put_lower) | ||
313 | ecryptfs_put_lower_file(ecryptfs_dentry->d_inode); | ||
314 | return rc; | 394 | return rc; |
315 | } | 395 | } |
316 | 396 | ||
@@ -353,12 +433,12 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | |||
353 | goto out_d_drop; | 433 | goto out_d_drop; |
354 | } | 434 | } |
355 | if (lower_dentry->d_inode) | 435 | if (lower_dentry->d_inode) |
356 | goto lookup_and_interpose; | 436 | goto interpose; |
357 | mount_crypt_stat = &ecryptfs_superblock_to_private( | 437 | mount_crypt_stat = &ecryptfs_superblock_to_private( |
358 | ecryptfs_dentry->d_sb)->mount_crypt_stat; | 438 | ecryptfs_dentry->d_sb)->mount_crypt_stat; |
359 | if (!(mount_crypt_stat | 439 | if (!(mount_crypt_stat |
360 | && (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES))) | 440 | && (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES))) |
361 | goto lookup_and_interpose; | 441 | goto interpose; |
362 | dput(lower_dentry); | 442 | dput(lower_dentry); |
363 | rc = ecryptfs_encrypt_and_encode_filename( | 443 | rc = ecryptfs_encrypt_and_encode_filename( |
364 | &encrypted_and_encoded_name, &encrypted_and_encoded_name_size, | 444 | &encrypted_and_encoded_name, &encrypted_and_encoded_name_size, |
@@ -381,9 +461,9 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | |||
381 | encrypted_and_encoded_name); | 461 | encrypted_and_encoded_name); |
382 | goto out_d_drop; | 462 | goto out_d_drop; |
383 | } | 463 | } |
384 | lookup_and_interpose: | 464 | interpose: |
385 | rc = ecryptfs_lookup_and_interpose_lower(ecryptfs_dentry, lower_dentry, | 465 | rc = ecryptfs_lookup_interpose(ecryptfs_dentry, lower_dentry, |
386 | ecryptfs_dir_inode); | 466 | ecryptfs_dir_inode); |
387 | goto out; | 467 | goto out; |
388 | out_d_drop: | 468 | out_d_drop: |
389 | d_drop(ecryptfs_dentry); | 469 | d_drop(ecryptfs_dentry); |
@@ -411,7 +491,7 @@ static int ecryptfs_link(struct dentry *old_dentry, struct inode *dir, | |||
411 | lower_new_dentry); | 491 | lower_new_dentry); |
412 | if (rc || !lower_new_dentry->d_inode) | 492 | if (rc || !lower_new_dentry->d_inode) |
413 | goto out_lock; | 493 | goto out_lock; |
414 | rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb, 0); | 494 | rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb); |
415 | if (rc) | 495 | if (rc) |
416 | goto out_lock; | 496 | goto out_lock; |
417 | fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); | 497 | fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); |
@@ -478,7 +558,7 @@ static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry, | |||
478 | kfree(encoded_symname); | 558 | kfree(encoded_symname); |
479 | if (rc || !lower_dentry->d_inode) | 559 | if (rc || !lower_dentry->d_inode) |
480 | goto out_lock; | 560 | goto out_lock; |
481 | rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0); | 561 | rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb); |
482 | if (rc) | 562 | if (rc) |
483 | goto out_lock; | 563 | goto out_lock; |
484 | fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); | 564 | fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); |
@@ -502,7 +582,7 @@ static int ecryptfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
502 | rc = vfs_mkdir(lower_dir_dentry->d_inode, lower_dentry, mode); | 582 | rc = vfs_mkdir(lower_dir_dentry->d_inode, lower_dentry, mode); |
503 | if (rc || !lower_dentry->d_inode) | 583 | if (rc || !lower_dentry->d_inode) |
504 | goto out; | 584 | goto out; |
505 | rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0); | 585 | rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb); |
506 | if (rc) | 586 | if (rc) |
507 | goto out; | 587 | goto out; |
508 | fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); | 588 | fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); |
@@ -521,8 +601,6 @@ static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
521 | struct dentry *lower_dir_dentry; | 601 | struct dentry *lower_dir_dentry; |
522 | int rc; | 602 | int rc; |
523 | 603 | ||
524 | dentry_unhash(dentry); | ||
525 | |||
526 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | 604 | lower_dentry = ecryptfs_dentry_to_lower(dentry); |
527 | dget(dentry); | 605 | dget(dentry); |
528 | lower_dir_dentry = lock_parent(lower_dentry); | 606 | lower_dir_dentry = lock_parent(lower_dentry); |
@@ -552,7 +630,7 @@ ecryptfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) | |||
552 | rc = vfs_mknod(lower_dir_dentry->d_inode, lower_dentry, mode, dev); | 630 | rc = vfs_mknod(lower_dir_dentry->d_inode, lower_dentry, mode, dev); |
553 | if (rc || !lower_dentry->d_inode) | 631 | if (rc || !lower_dentry->d_inode) |
554 | goto out; | 632 | goto out; |
555 | rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0); | 633 | rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb); |
556 | if (rc) | 634 | if (rc) |
557 | goto out; | 635 | goto out; |
558 | fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); | 636 | fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); |
@@ -575,9 +653,6 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
575 | struct dentry *lower_new_dir_dentry; | 653 | struct dentry *lower_new_dir_dentry; |
576 | struct dentry *trap = NULL; | 654 | struct dentry *trap = NULL; |
577 | 655 | ||
578 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | ||
579 | dentry_unhash(new_dentry); | ||
580 | |||
581 | lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); | 656 | lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); |
582 | lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); | 657 | lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); |
583 | dget(lower_old_dentry); | 658 | dget(lower_old_dentry); |
@@ -755,7 +830,7 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, | |||
755 | lower_ia->ia_valid &= ~ATTR_SIZE; | 830 | lower_ia->ia_valid &= ~ATTR_SIZE; |
756 | return 0; | 831 | return 0; |
757 | } | 832 | } |
758 | rc = ecryptfs_get_lower_file(dentry); | 833 | rc = ecryptfs_get_lower_file(dentry, inode); |
759 | if (rc) | 834 | if (rc) |
760 | return rc; | 835 | return rc; |
761 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; | 836 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; |
@@ -911,7 +986,7 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) | |||
911 | 986 | ||
912 | mount_crypt_stat = &ecryptfs_superblock_to_private( | 987 | mount_crypt_stat = &ecryptfs_superblock_to_private( |
913 | dentry->d_sb)->mount_crypt_stat; | 988 | dentry->d_sb)->mount_crypt_stat; |
914 | rc = ecryptfs_get_lower_file(dentry); | 989 | rc = ecryptfs_get_lower_file(dentry, inode); |
915 | if (rc) { | 990 | if (rc) { |
916 | mutex_unlock(&crypt_stat->cs_mutex); | 991 | mutex_unlock(&crypt_stat->cs_mutex); |
917 | goto out; | 992 | goto out; |
@@ -1084,21 +1159,6 @@ out: | |||
1084 | return rc; | 1159 | return rc; |
1085 | } | 1160 | } |
1086 | 1161 | ||
1087 | int ecryptfs_inode_test(struct inode *inode, void *candidate_lower_inode) | ||
1088 | { | ||
1089 | if ((ecryptfs_inode_to_lower(inode) | ||
1090 | == (struct inode *)candidate_lower_inode)) | ||
1091 | return 1; | ||
1092 | else | ||
1093 | return 0; | ||
1094 | } | ||
1095 | |||
1096 | int ecryptfs_inode_set(struct inode *inode, void *lower_inode) | ||
1097 | { | ||
1098 | ecryptfs_init_inode(inode, (struct inode *)lower_inode); | ||
1099 | return 0; | ||
1100 | } | ||
1101 | |||
1102 | const struct inode_operations ecryptfs_symlink_iops = { | 1162 | const struct inode_operations ecryptfs_symlink_iops = { |
1103 | .readlink = ecryptfs_readlink, | 1163 | .readlink = ecryptfs_readlink, |
1104 | .follow_link = ecryptfs_follow_link, | 1164 | .follow_link = ecryptfs_follow_link, |
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 89b93389af8e..9f1bb747d77d 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
@@ -135,12 +135,12 @@ static int ecryptfs_init_lower_file(struct dentry *dentry, | |||
135 | return rc; | 135 | return rc; |
136 | } | 136 | } |
137 | 137 | ||
138 | int ecryptfs_get_lower_file(struct dentry *dentry) | 138 | int ecryptfs_get_lower_file(struct dentry *dentry, struct inode *inode) |
139 | { | 139 | { |
140 | struct ecryptfs_inode_info *inode_info = | 140 | struct ecryptfs_inode_info *inode_info; |
141 | ecryptfs_inode_to_private(dentry->d_inode); | ||
142 | int count, rc = 0; | 141 | int count, rc = 0; |
143 | 142 | ||
143 | inode_info = ecryptfs_inode_to_private(inode); | ||
144 | mutex_lock(&inode_info->lower_file_mutex); | 144 | mutex_lock(&inode_info->lower_file_mutex); |
145 | count = atomic_inc_return(&inode_info->lower_file_count); | 145 | count = atomic_inc_return(&inode_info->lower_file_count); |
146 | if (WARN_ON_ONCE(count < 1)) | 146 | if (WARN_ON_ONCE(count < 1)) |
@@ -168,75 +168,6 @@ void ecryptfs_put_lower_file(struct inode *inode) | |||
168 | } | 168 | } |
169 | } | 169 | } |
170 | 170 | ||
171 | static struct inode *ecryptfs_get_inode(struct inode *lower_inode, | ||
172 | struct super_block *sb) | ||
173 | { | ||
174 | struct inode *inode; | ||
175 | int rc = 0; | ||
176 | |||
177 | if (lower_inode->i_sb != ecryptfs_superblock_to_lower(sb)) { | ||
178 | rc = -EXDEV; | ||
179 | goto out; | ||
180 | } | ||
181 | if (!igrab(lower_inode)) { | ||
182 | rc = -ESTALE; | ||
183 | goto out; | ||
184 | } | ||
185 | inode = iget5_locked(sb, (unsigned long)lower_inode, | ||
186 | ecryptfs_inode_test, ecryptfs_inode_set, | ||
187 | lower_inode); | ||
188 | if (!inode) { | ||
189 | rc = -EACCES; | ||
190 | iput(lower_inode); | ||
191 | goto out; | ||
192 | } | ||
193 | if (inode->i_state & I_NEW) | ||
194 | unlock_new_inode(inode); | ||
195 | else | ||
196 | iput(lower_inode); | ||
197 | if (S_ISLNK(lower_inode->i_mode)) | ||
198 | inode->i_op = &ecryptfs_symlink_iops; | ||
199 | else if (S_ISDIR(lower_inode->i_mode)) | ||
200 | inode->i_op = &ecryptfs_dir_iops; | ||
201 | if (S_ISDIR(lower_inode->i_mode)) | ||
202 | inode->i_fop = &ecryptfs_dir_fops; | ||
203 | if (special_file(lower_inode->i_mode)) | ||
204 | init_special_inode(inode, lower_inode->i_mode, | ||
205 | lower_inode->i_rdev); | ||
206 | fsstack_copy_attr_all(inode, lower_inode); | ||
207 | /* This size will be overwritten for real files w/ headers and | ||
208 | * other metadata */ | ||
209 | fsstack_copy_inode_size(inode, lower_inode); | ||
210 | return inode; | ||
211 | out: | ||
212 | return ERR_PTR(rc); | ||
213 | } | ||
214 | |||
215 | /** | ||
216 | * ecryptfs_interpose | ||
217 | * @lower_dentry: Existing dentry in the lower filesystem | ||
218 | * @dentry: ecryptfs' dentry | ||
219 | * @sb: ecryptfs's super_block | ||
220 | * @flags: flags to govern behavior of interpose procedure | ||
221 | * | ||
222 | * Interposes upper and lower dentries. | ||
223 | * | ||
224 | * Returns zero on success; non-zero otherwise | ||
225 | */ | ||
226 | int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry, | ||
227 | struct super_block *sb, u32 flags) | ||
228 | { | ||
229 | struct inode *lower_inode = lower_dentry->d_inode; | ||
230 | struct inode *inode = ecryptfs_get_inode(lower_inode, sb); | ||
231 | if (IS_ERR(inode)) | ||
232 | return PTR_ERR(inode); | ||
233 | if (flags & ECRYPTFS_INTERPOSE_FLAG_D_ADD) | ||
234 | d_add(dentry, inode); | ||
235 | else | ||
236 | d_instantiate(dentry, inode); | ||
237 | return 0; | ||
238 | } | ||
239 | |||
240 | enum { ecryptfs_opt_sig, ecryptfs_opt_ecryptfs_sig, | 171 | enum { ecryptfs_opt_sig, ecryptfs_opt_ecryptfs_sig, |
241 | ecryptfs_opt_cipher, ecryptfs_opt_ecryptfs_cipher, | 172 | ecryptfs_opt_cipher, ecryptfs_opt_ecryptfs_cipher, |
242 | ecryptfs_opt_ecryptfs_key_bytes, | 173 | ecryptfs_opt_ecryptfs_key_bytes, |
@@ -704,13 +635,8 @@ static struct ecryptfs_cache_info { | |||
704 | .size = sizeof(struct ecryptfs_sb_info), | 635 | .size = sizeof(struct ecryptfs_sb_info), |
705 | }, | 636 | }, |
706 | { | 637 | { |
707 | .cache = &ecryptfs_header_cache_1, | 638 | .cache = &ecryptfs_header_cache, |
708 | .name = "ecryptfs_headers_1", | 639 | .name = "ecryptfs_headers", |
709 | .size = PAGE_CACHE_SIZE, | ||
710 | }, | ||
711 | { | ||
712 | .cache = &ecryptfs_header_cache_2, | ||
713 | .name = "ecryptfs_headers_2", | ||
714 | .size = PAGE_CACHE_SIZE, | 640 | .size = PAGE_CACHE_SIZE, |
715 | }, | 641 | }, |
716 | { | 642 | { |
diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c index 245b517bf1b6..dbd52d40df4c 100644 --- a/fs/ecryptfs/super.c +++ b/fs/ecryptfs/super.c | |||
@@ -93,22 +93,6 @@ static void ecryptfs_destroy_inode(struct inode *inode) | |||
93 | } | 93 | } |
94 | 94 | ||
95 | /** | 95 | /** |
96 | * ecryptfs_init_inode | ||
97 | * @inode: The ecryptfs inode | ||
98 | * | ||
99 | * Set up the ecryptfs inode. | ||
100 | */ | ||
101 | void ecryptfs_init_inode(struct inode *inode, struct inode *lower_inode) | ||
102 | { | ||
103 | ecryptfs_set_inode_lower(inode, lower_inode); | ||
104 | inode->i_ino = lower_inode->i_ino; | ||
105 | inode->i_version++; | ||
106 | inode->i_op = &ecryptfs_main_iops; | ||
107 | inode->i_fop = &ecryptfs_main_fops; | ||
108 | inode->i_mapping->a_ops = &ecryptfs_aops; | ||
109 | } | ||
110 | |||
111 | /** | ||
112 | * ecryptfs_statfs | 96 | * ecryptfs_statfs |
113 | * @sb: The ecryptfs super block | 97 | * @sb: The ecryptfs super block |
114 | * @buf: The struct kstatfs to fill in with stats | 98 | * @buf: The struct kstatfs to fill in with stats |
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 68b2e43d7c35..3451d23c3bae 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -3392,7 +3392,7 @@ int ext3_mark_inode_dirty(handle_t *handle, struct inode *inode) | |||
3392 | * so would cause a commit on atime updates, which we don't bother doing. | 3392 | * so would cause a commit on atime updates, which we don't bother doing. |
3393 | * We handle synchronous inodes at the highest possible level. | 3393 | * We handle synchronous inodes at the highest possible level. |
3394 | */ | 3394 | */ |
3395 | void ext3_dirty_inode(struct inode *inode) | 3395 | void ext3_dirty_inode(struct inode *inode, int flags) |
3396 | { | 3396 | { |
3397 | handle_t *current_handle = ext3_journal_current_handle(); | 3397 | handle_t *current_handle = ext3_journal_current_handle(); |
3398 | handle_t *handle; | 3398 | handle_t *handle; |
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index a74b89c09f90..1921392cd708 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
@@ -1813,7 +1813,7 @@ extern int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry, | |||
1813 | extern void ext4_evict_inode(struct inode *); | 1813 | extern void ext4_evict_inode(struct inode *); |
1814 | extern void ext4_clear_inode(struct inode *); | 1814 | extern void ext4_clear_inode(struct inode *); |
1815 | extern int ext4_sync_inode(handle_t *, struct inode *); | 1815 | extern int ext4_sync_inode(handle_t *, struct inode *); |
1816 | extern void ext4_dirty_inode(struct inode *); | 1816 | extern void ext4_dirty_inode(struct inode *, int); |
1817 | extern int ext4_change_inode_journal_flag(struct inode *, int); | 1817 | extern int ext4_change_inode_journal_flag(struct inode *, int); |
1818 | extern int ext4_get_inode_loc(struct inode *, struct ext4_iloc *); | 1818 | extern int ext4_get_inode_loc(struct inode *, struct ext4_iloc *); |
1819 | extern int ext4_can_truncate(struct inode *inode); | 1819 | extern int ext4_can_truncate(struct inode *inode); |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 50d0e9c64584..a5763e3505ba 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -5733,7 +5733,7 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode) | |||
5733 | * so would cause a commit on atime updates, which we don't bother doing. | 5733 | * so would cause a commit on atime updates, which we don't bother doing. |
5734 | * We handle synchronous inodes at the highest possible level. | 5734 | * We handle synchronous inodes at the highest possible level. |
5735 | */ | 5735 | */ |
5736 | void ext4_dirty_inode(struct inode *inode) | 5736 | void ext4_dirty_inode(struct inode *inode, int flags) |
5737 | { | 5737 | { |
5738 | handle_t *handle; | 5738 | handle_t *handle; |
5739 | 5739 | ||
diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c index be15437c272e..3b222dafd15b 100644 --- a/fs/fat/namei_msdos.c +++ b/fs/fat/namei_msdos.c | |||
@@ -326,8 +326,6 @@ static int msdos_rmdir(struct inode *dir, struct dentry *dentry) | |||
326 | struct fat_slot_info sinfo; | 326 | struct fat_slot_info sinfo; |
327 | int err; | 327 | int err; |
328 | 328 | ||
329 | dentry_unhash(dentry); | ||
330 | |||
331 | lock_super(sb); | 329 | lock_super(sb); |
332 | /* | 330 | /* |
333 | * Check whether the directory is not in use, then check | 331 | * Check whether the directory is not in use, then check |
@@ -459,9 +457,6 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name, | |||
459 | old_inode = old_dentry->d_inode; | 457 | old_inode = old_dentry->d_inode; |
460 | new_inode = new_dentry->d_inode; | 458 | new_inode = new_dentry->d_inode; |
461 | 459 | ||
462 | if (new_inode && S_ISDIR(new_inode->i_mode)) | ||
463 | dentry_unhash(new_dentry); | ||
464 | |||
465 | err = fat_scan(old_dir, old_name, &old_sinfo); | 460 | err = fat_scan(old_dir, old_name, &old_sinfo); |
466 | if (err) { | 461 | if (err) { |
467 | err = -EIO; | 462 | err = -EIO; |
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index c61a6789f36c..20b4ea53fdc4 100644 --- a/fs/fat/namei_vfat.c +++ b/fs/fat/namei_vfat.c | |||
@@ -824,8 +824,6 @@ static int vfat_rmdir(struct inode *dir, struct dentry *dentry) | |||
824 | struct fat_slot_info sinfo; | 824 | struct fat_slot_info sinfo; |
825 | int err; | 825 | int err; |
826 | 826 | ||
827 | dentry_unhash(dentry); | ||
828 | |||
829 | lock_super(sb); | 827 | lock_super(sb); |
830 | 828 | ||
831 | err = fat_dir_empty(inode); | 829 | err = fat_dir_empty(inode); |
@@ -933,9 +931,6 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
933 | int err, is_dir, update_dotdot, corrupt = 0; | 931 | int err, is_dir, update_dotdot, corrupt = 0; |
934 | struct super_block *sb = old_dir->i_sb; | 932 | struct super_block *sb = old_dir->i_sb; |
935 | 933 | ||
936 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | ||
937 | dentry_unhash(new_dentry); | ||
938 | |||
939 | old_sinfo.bh = sinfo.bh = dotdot_bh = NULL; | 934 | old_sinfo.bh = sinfo.bh = dotdot_bh = NULL; |
940 | old_inode = old_dentry->d_inode; | 935 | old_inode = old_dentry->d_inode; |
941 | new_inode = new_dentry->d_inode; | 936 | new_inode = new_dentry->d_inode; |
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 34591ee804b5..0f015a0468de 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
@@ -1007,9 +1007,6 @@ static noinline void block_dump___mark_inode_dirty(struct inode *inode) | |||
1007 | * In short, make sure you hash any inodes _before_ you start marking | 1007 | * In short, make sure you hash any inodes _before_ you start marking |
1008 | * them dirty. | 1008 | * them dirty. |
1009 | * | 1009 | * |
1010 | * This function *must* be atomic for the I_DIRTY_PAGES case - | ||
1011 | * set_page_dirty() is called under spinlock in several places. | ||
1012 | * | ||
1013 | * Note that for blockdevs, inode->dirtied_when represents the dirtying time of | 1010 | * Note that for blockdevs, inode->dirtied_when represents the dirtying time of |
1014 | * the block-special inode (/dev/hda1) itself. And the ->dirtied_when field of | 1011 | * the block-special inode (/dev/hda1) itself. And the ->dirtied_when field of |
1015 | * the kernel-internal blockdev inode represents the dirtying time of the | 1012 | * the kernel-internal blockdev inode represents the dirtying time of the |
@@ -1028,7 +1025,7 @@ void __mark_inode_dirty(struct inode *inode, int flags) | |||
1028 | */ | 1025 | */ |
1029 | if (flags & (I_DIRTY_SYNC | I_DIRTY_DATASYNC)) { | 1026 | if (flags & (I_DIRTY_SYNC | I_DIRTY_DATASYNC)) { |
1030 | if (sb->s_op->dirty_inode) | 1027 | if (sb->s_op->dirty_inode) |
1031 | sb->s_op->dirty_inode(inode); | 1028 | sb->s_op->dirty_inode(inode, flags); |
1032 | } | 1029 | } |
1033 | 1030 | ||
1034 | /* | 1031 | /* |
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 0d0e3faddcfa..d50160714595 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -667,8 +667,6 @@ static int fuse_rmdir(struct inode *dir, struct dentry *entry) | |||
667 | if (IS_ERR(req)) | 667 | if (IS_ERR(req)) |
668 | return PTR_ERR(req); | 668 | return PTR_ERR(req); |
669 | 669 | ||
670 | dentry_unhash(entry); | ||
671 | |||
672 | req->in.h.opcode = FUSE_RMDIR; | 670 | req->in.h.opcode = FUSE_RMDIR; |
673 | req->in.h.nodeid = get_node_id(dir); | 671 | req->in.h.nodeid = get_node_id(dir); |
674 | req->in.numargs = 1; | 672 | req->in.numargs = 1; |
@@ -694,9 +692,6 @@ static int fuse_rename(struct inode *olddir, struct dentry *oldent, | |||
694 | struct fuse_conn *fc = get_fuse_conn(olddir); | 692 | struct fuse_conn *fc = get_fuse_conn(olddir); |
695 | struct fuse_req *req = fuse_get_req(fc); | 693 | struct fuse_req *req = fuse_get_req(fc); |
696 | 694 | ||
697 | if (newent->d_inode && S_ISDIR(newent->d_inode->i_mode)) | ||
698 | dentry_unhash(newent); | ||
699 | |||
700 | if (IS_ERR(req)) | 695 | if (IS_ERR(req)) |
701 | return PTR_ERR(req); | 696 | return PTR_ERR(req); |
702 | 697 | ||
diff --git a/fs/hfs/dir.c b/fs/hfs/dir.c index 1cb70cdba2c1..b4d70b13be92 100644 --- a/fs/hfs/dir.c +++ b/fs/hfs/dir.c | |||
@@ -253,9 +253,6 @@ static int hfs_remove(struct inode *dir, struct dentry *dentry) | |||
253 | struct inode *inode = dentry->d_inode; | 253 | struct inode *inode = dentry->d_inode; |
254 | int res; | 254 | int res; |
255 | 255 | ||
256 | if (S_ISDIR(inode->i_mode)) | ||
257 | dentry_unhash(dentry); | ||
258 | |||
259 | if (S_ISDIR(inode->i_mode) && inode->i_size != 2) | 256 | if (S_ISDIR(inode->i_mode) && inode->i_size != 2) |
260 | return -ENOTEMPTY; | 257 | return -ENOTEMPTY; |
261 | res = hfs_cat_delete(inode->i_ino, dir, &dentry->d_name); | 258 | res = hfs_cat_delete(inode->i_ino, dir, &dentry->d_name); |
@@ -286,9 +283,6 @@ static int hfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
286 | 283 | ||
287 | /* Unlink destination if it already exists */ | 284 | /* Unlink destination if it already exists */ |
288 | if (new_dentry->d_inode) { | 285 | if (new_dentry->d_inode) { |
289 | if (S_ISDIR(new_dentry->d_inode->i_mode)) | ||
290 | dentry_unhash(new_dentry); | ||
291 | |||
292 | res = hfs_remove(new_dir, new_dentry); | 286 | res = hfs_remove(new_dir, new_dentry); |
293 | if (res) | 287 | if (res) |
294 | return res; | 288 | return res; |
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index b28835091dd0..4df5059c25da 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c | |||
@@ -370,8 +370,6 @@ static int hfsplus_rmdir(struct inode *dir, struct dentry *dentry) | |||
370 | struct inode *inode = dentry->d_inode; | 370 | struct inode *inode = dentry->d_inode; |
371 | int res; | 371 | int res; |
372 | 372 | ||
373 | dentry_unhash(dentry); | ||
374 | |||
375 | if (inode->i_size != 2) | 373 | if (inode->i_size != 2) |
376 | return -ENOTEMPTY; | 374 | return -ENOTEMPTY; |
377 | 375 | ||
@@ -469,12 +467,10 @@ static int hfsplus_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
469 | 467 | ||
470 | /* Unlink destination if it already exists */ | 468 | /* Unlink destination if it already exists */ |
471 | if (new_dentry->d_inode) { | 469 | if (new_dentry->d_inode) { |
472 | if (S_ISDIR(new_dentry->d_inode->i_mode)) { | 470 | if (S_ISDIR(new_dentry->d_inode->i_mode)) |
473 | dentry_unhash(new_dentry); | ||
474 | res = hfsplus_rmdir(new_dir, new_dentry); | 471 | res = hfsplus_rmdir(new_dir, new_dentry); |
475 | } else { | 472 | else |
476 | res = hfsplus_unlink(new_dir, new_dentry); | 473 | res = hfsplus_unlink(new_dir, new_dentry); |
477 | } | ||
478 | if (res) | 474 | if (res) |
479 | return res; | 475 | return res; |
480 | } | 476 | } |
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index e6816b9e6903..2638c834ed28 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c | |||
@@ -683,8 +683,6 @@ int hostfs_rmdir(struct inode *ino, struct dentry *dentry) | |||
683 | char *file; | 683 | char *file; |
684 | int err; | 684 | int err; |
685 | 685 | ||
686 | dentry_unhash(dentry); | ||
687 | |||
688 | if ((file = dentry_name(dentry)) == NULL) | 686 | if ((file = dentry_name(dentry)) == NULL) |
689 | return -ENOMEM; | 687 | return -ENOMEM; |
690 | err = do_rmdir(file); | 688 | err = do_rmdir(file); |
@@ -738,9 +736,6 @@ int hostfs_rename(struct inode *from_ino, struct dentry *from, | |||
738 | char *from_name, *to_name; | 736 | char *from_name, *to_name; |
739 | int err; | 737 | int err; |
740 | 738 | ||
741 | if (to->d_inode && S_ISDIR(to->d_inode->i_mode)) | ||
742 | dentry_unhash(to); | ||
743 | |||
744 | if ((from_name = dentry_name(from)) == NULL) | 739 | if ((from_name = dentry_name(from)) == NULL) |
745 | return -ENOMEM; | 740 | return -ENOMEM; |
746 | if ((to_name = dentry_name(to)) == NULL) { | 741 | if ((to_name = dentry_name(to)) == NULL) { |
diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c index ff0ce21c0867..acf95dab2aac 100644 --- a/fs/hpfs/namei.c +++ b/fs/hpfs/namei.c | |||
@@ -439,8 +439,6 @@ static int hpfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
439 | int err; | 439 | int err; |
440 | int r; | 440 | int r; |
441 | 441 | ||
442 | dentry_unhash(dentry); | ||
443 | |||
444 | hpfs_adjust_length(name, &len); | 442 | hpfs_adjust_length(name, &len); |
445 | hpfs_lock(dir->i_sb); | 443 | hpfs_lock(dir->i_sb); |
446 | err = -ENOENT; | 444 | err = -ENOENT; |
@@ -535,9 +533,6 @@ static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
535 | struct fnode *fnode; | 533 | struct fnode *fnode; |
536 | int err; | 534 | int err; |
537 | 535 | ||
538 | if (new_inode && S_ISDIR(new_inode->i_mode)) | ||
539 | dentry_unhash(new_dentry); | ||
540 | |||
541 | if ((err = hpfs_chk_name(new_name, &new_len))) return err; | 536 | if ((err = hpfs_chk_name(new_name, &new_len))) return err; |
542 | err = 0; | 537 | err = 0; |
543 | hpfs_adjust_length(old_name, &old_len); | 538 | hpfs_adjust_length(old_name, &old_len); |
diff --git a/fs/inode.c b/fs/inode.c index 990d284877a1..0f7e88a7803f 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -1,9 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * linux/fs/inode.c | ||
3 | * | ||
4 | * (C) 1997 Linus Torvalds | 2 | * (C) 1997 Linus Torvalds |
3 | * (C) 1999 Andrea Arcangeli <andrea@suse.de> (dynamic inode allocation) | ||
5 | */ | 4 | */ |
6 | |||
7 | #include <linux/fs.h> | 5 | #include <linux/fs.h> |
8 | #include <linux/mm.h> | 6 | #include <linux/mm.h> |
9 | #include <linux/dcache.h> | 7 | #include <linux/dcache.h> |
@@ -27,10 +25,11 @@ | |||
27 | #include <linux/prefetch.h> | 25 | #include <linux/prefetch.h> |
28 | #include <linux/ima.h> | 26 | #include <linux/ima.h> |
29 | #include <linux/cred.h> | 27 | #include <linux/cred.h> |
28 | #include <linux/buffer_head.h> /* for inode_has_buffers */ | ||
30 | #include "internal.h" | 29 | #include "internal.h" |
31 | 30 | ||
32 | /* | 31 | /* |
33 | * inode locking rules. | 32 | * Inode locking rules: |
34 | * | 33 | * |
35 | * inode->i_lock protects: | 34 | * inode->i_lock protects: |
36 | * inode->i_state, inode->i_hash, __iget() | 35 | * inode->i_state, inode->i_hash, __iget() |
@@ -60,54 +59,11 @@ | |||
60 | * inode_hash_lock | 59 | * inode_hash_lock |
61 | */ | 60 | */ |
62 | 61 | ||
63 | /* | ||
64 | * This is needed for the following functions: | ||
65 | * - inode_has_buffers | ||
66 | * - invalidate_bdev | ||
67 | * | ||
68 | * FIXME: remove all knowledge of the buffer layer from this file | ||
69 | */ | ||
70 | #include <linux/buffer_head.h> | ||
71 | |||
72 | /* | ||
73 | * New inode.c implementation. | ||
74 | * | ||
75 | * This implementation has the basic premise of trying | ||
76 | * to be extremely low-overhead and SMP-safe, yet be | ||
77 | * simple enough to be "obviously correct". | ||
78 | * | ||
79 | * Famous last words. | ||
80 | */ | ||
81 | |||
82 | /* inode dynamic allocation 1999, Andrea Arcangeli <andrea@suse.de> */ | ||
83 | |||
84 | /* #define INODE_PARANOIA 1 */ | ||
85 | /* #define INODE_DEBUG 1 */ | ||
86 | |||
87 | /* | ||
88 | * Inode lookup is no longer as critical as it used to be: | ||
89 | * most of the lookups are going to be through the dcache. | ||
90 | */ | ||
91 | #define I_HASHBITS i_hash_shift | ||
92 | #define I_HASHMASK i_hash_mask | ||
93 | |||
94 | static unsigned int i_hash_mask __read_mostly; | 62 | static unsigned int i_hash_mask __read_mostly; |
95 | static unsigned int i_hash_shift __read_mostly; | 63 | static unsigned int i_hash_shift __read_mostly; |
96 | static struct hlist_head *inode_hashtable __read_mostly; | 64 | static struct hlist_head *inode_hashtable __read_mostly; |
97 | static __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_hash_lock); | 65 | static __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_hash_lock); |
98 | 66 | ||
99 | /* | ||
100 | * Each inode can be on two separate lists. One is | ||
101 | * the hash list of the inode, used for lookups. The | ||
102 | * other linked list is the "type" list: | ||
103 | * "in_use" - valid inode, i_count > 0, i_nlink > 0 | ||
104 | * "dirty" - as "in_use" but also dirty | ||
105 | * "unused" - valid inode, i_count = 0 | ||
106 | * | ||
107 | * A "dirty" list is maintained for each super block, | ||
108 | * allowing for low-overhead inode sync() operations. | ||
109 | */ | ||
110 | |||
111 | static LIST_HEAD(inode_lru); | 67 | static LIST_HEAD(inode_lru); |
112 | static DEFINE_SPINLOCK(inode_lru_lock); | 68 | static DEFINE_SPINLOCK(inode_lru_lock); |
113 | 69 | ||
@@ -424,8 +380,8 @@ static unsigned long hash(struct super_block *sb, unsigned long hashval) | |||
424 | 380 | ||
425 | tmp = (hashval * (unsigned long)sb) ^ (GOLDEN_RATIO_PRIME + hashval) / | 381 | tmp = (hashval * (unsigned long)sb) ^ (GOLDEN_RATIO_PRIME + hashval) / |
426 | L1_CACHE_BYTES; | 382 | L1_CACHE_BYTES; |
427 | tmp = tmp ^ ((tmp ^ GOLDEN_RATIO_PRIME) >> I_HASHBITS); | 383 | tmp = tmp ^ ((tmp ^ GOLDEN_RATIO_PRIME) >> i_hash_shift); |
428 | return tmp & I_HASHMASK; | 384 | return tmp & i_hash_mask; |
429 | } | 385 | } |
430 | 386 | ||
431 | /** | 387 | /** |
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c index 9a1e86fc1362..4bca6a2e5c07 100644 --- a/fs/jffs2/dir.c +++ b/fs/jffs2/dir.c | |||
@@ -605,8 +605,6 @@ static int jffs2_rmdir (struct inode *dir_i, struct dentry *dentry) | |||
605 | int ret; | 605 | int ret; |
606 | uint32_t now = get_seconds(); | 606 | uint32_t now = get_seconds(); |
607 | 607 | ||
608 | dentry_unhash(dentry); | ||
609 | |||
610 | for (fd = f->dents ; fd; fd = fd->next) { | 608 | for (fd = f->dents ; fd; fd = fd->next) { |
611 | if (fd->ino) | 609 | if (fd->ino) |
612 | return -ENOTEMPTY; | 610 | return -ENOTEMPTY; |
@@ -782,9 +780,6 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, | |||
782 | uint8_t type; | 780 | uint8_t type; |
783 | uint32_t now; | 781 | uint32_t now; |
784 | 782 | ||
785 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | ||
786 | dentry_unhash(new_dentry); | ||
787 | |||
788 | /* The VFS will check for us and prevent trying to rename a | 783 | /* The VFS will check for us and prevent trying to rename a |
789 | * file over a directory and vice versa, but if it's a directory, | 784 | * file over a directory and vice versa, but if it's a directory, |
790 | * the VFS can't check whether the victim is empty. The filesystem | 785 | * the VFS can't check whether the victim is empty. The filesystem |
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c index e896e67767eb..46ad619b6124 100644 --- a/fs/jffs2/fs.c +++ b/fs/jffs2/fs.c | |||
@@ -357,7 +357,7 @@ error: | |||
357 | return ERR_PTR(ret); | 357 | return ERR_PTR(ret); |
358 | } | 358 | } |
359 | 359 | ||
360 | void jffs2_dirty_inode(struct inode *inode) | 360 | void jffs2_dirty_inode(struct inode *inode, int flags) |
361 | { | 361 | { |
362 | struct iattr iattr; | 362 | struct iattr iattr; |
363 | 363 | ||
diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h index 00bae7cc2e48..65c6c43ca482 100644 --- a/fs/jffs2/os-linux.h +++ b/fs/jffs2/os-linux.h | |||
@@ -172,7 +172,7 @@ int jffs2_setattr (struct dentry *, struct iattr *); | |||
172 | int jffs2_do_setattr (struct inode *, struct iattr *); | 172 | int jffs2_do_setattr (struct inode *, struct iattr *); |
173 | struct inode *jffs2_iget(struct super_block *, unsigned long); | 173 | struct inode *jffs2_iget(struct super_block *, unsigned long); |
174 | void jffs2_evict_inode (struct inode *); | 174 | void jffs2_evict_inode (struct inode *); |
175 | void jffs2_dirty_inode(struct inode *inode); | 175 | void jffs2_dirty_inode(struct inode *inode, int flags); |
176 | struct inode *jffs2_new_inode (struct inode *dir_i, int mode, | 176 | struct inode *jffs2_new_inode (struct inode *dir_i, int mode, |
177 | struct jffs2_raw_inode *ri); | 177 | struct jffs2_raw_inode *ri); |
178 | int jffs2_statfs (struct dentry *, struct kstatfs *); | 178 | int jffs2_statfs (struct dentry *, struct kstatfs *); |
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c index eddbb373209e..109655904bbc 100644 --- a/fs/jfs/inode.c +++ b/fs/jfs/inode.c | |||
@@ -173,7 +173,7 @@ void jfs_evict_inode(struct inode *inode) | |||
173 | dquot_drop(inode); | 173 | dquot_drop(inode); |
174 | } | 174 | } |
175 | 175 | ||
176 | void jfs_dirty_inode(struct inode *inode) | 176 | void jfs_dirty_inode(struct inode *inode, int flags) |
177 | { | 177 | { |
178 | static int noisy = 5; | 178 | static int noisy = 5; |
179 | 179 | ||
diff --git a/fs/jfs/jfs_inode.h b/fs/jfs/jfs_inode.h index 155e91eff07d..ec2fb8b945fc 100644 --- a/fs/jfs/jfs_inode.h +++ b/fs/jfs/jfs_inode.h | |||
@@ -28,7 +28,7 @@ extern struct inode *jfs_iget(struct super_block *, unsigned long); | |||
28 | extern int jfs_commit_inode(struct inode *, int); | 28 | extern int jfs_commit_inode(struct inode *, int); |
29 | extern int jfs_write_inode(struct inode *, struct writeback_control *); | 29 | extern int jfs_write_inode(struct inode *, struct writeback_control *); |
30 | extern void jfs_evict_inode(struct inode *); | 30 | extern void jfs_evict_inode(struct inode *); |
31 | extern void jfs_dirty_inode(struct inode *); | 31 | extern void jfs_dirty_inode(struct inode *, int); |
32 | extern void jfs_truncate(struct inode *); | 32 | extern void jfs_truncate(struct inode *); |
33 | extern void jfs_truncate_nolock(struct inode *, loff_t); | 33 | extern void jfs_truncate_nolock(struct inode *, loff_t); |
34 | extern void jfs_free_zero_link(struct inode *); | 34 | extern void jfs_free_zero_link(struct inode *); |
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 865df16a6cf3..eaaf2b511e89 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c | |||
@@ -360,8 +360,6 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry) | |||
360 | 360 | ||
361 | jfs_info("jfs_rmdir: dip:0x%p name:%s", dip, dentry->d_name.name); | 361 | jfs_info("jfs_rmdir: dip:0x%p name:%s", dip, dentry->d_name.name); |
362 | 362 | ||
363 | dentry_unhash(dentry); | ||
364 | |||
365 | /* Init inode for quota operations. */ | 363 | /* Init inode for quota operations. */ |
366 | dquot_initialize(dip); | 364 | dquot_initialize(dip); |
367 | dquot_initialize(ip); | 365 | dquot_initialize(ip); |
@@ -1097,9 +1095,6 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1097 | jfs_info("jfs_rename: %s %s", old_dentry->d_name.name, | 1095 | jfs_info("jfs_rename: %s %s", old_dentry->d_name.name, |
1098 | new_dentry->d_name.name); | 1096 | new_dentry->d_name.name); |
1099 | 1097 | ||
1100 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | ||
1101 | dentry_unhash(new_dentry); | ||
1102 | |||
1103 | dquot_initialize(old_dir); | 1098 | dquot_initialize(old_dir); |
1104 | dquot_initialize(new_dir); | 1099 | dquot_initialize(new_dir); |
1105 | 1100 | ||
diff --git a/fs/logfs/dir.c b/fs/logfs/dir.c index f34c9cde9e94..9ed89d1663f8 100644 --- a/fs/logfs/dir.c +++ b/fs/logfs/dir.c | |||
@@ -273,8 +273,6 @@ static int logfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
273 | { | 273 | { |
274 | struct inode *inode = dentry->d_inode; | 274 | struct inode *inode = dentry->d_inode; |
275 | 275 | ||
276 | dentry_unhash(dentry); | ||
277 | |||
278 | if (!logfs_empty_dir(inode)) | 276 | if (!logfs_empty_dir(inode)) |
279 | return -ENOTEMPTY; | 277 | return -ENOTEMPTY; |
280 | 278 | ||
@@ -624,9 +622,6 @@ static int logfs_rename_cross(struct inode *old_dir, struct dentry *old_dentry, | |||
624 | loff_t pos; | 622 | loff_t pos; |
625 | int err; | 623 | int err; |
626 | 624 | ||
627 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | ||
628 | dentry_unhash(new_dentry); | ||
629 | |||
630 | /* 1. locate source dd */ | 625 | /* 1. locate source dd */ |
631 | err = logfs_get_dd(old_dir, old_dentry, &dd, &pos); | 626 | err = logfs_get_dd(old_dir, old_dentry, &dd, &pos); |
632 | if (err) | 627 | if (err) |
diff --git a/fs/minix/namei.c b/fs/minix/namei.c index f60aed8db9c4..6e6777f1b4b2 100644 --- a/fs/minix/namei.c +++ b/fs/minix/namei.c | |||
@@ -168,8 +168,6 @@ static int minix_rmdir(struct inode * dir, struct dentry *dentry) | |||
168 | struct inode * inode = dentry->d_inode; | 168 | struct inode * inode = dentry->d_inode; |
169 | int err = -ENOTEMPTY; | 169 | int err = -ENOTEMPTY; |
170 | 170 | ||
171 | dentry_unhash(dentry); | ||
172 | |||
173 | if (minix_empty_dir(inode)) { | 171 | if (minix_empty_dir(inode)) { |
174 | err = minix_unlink(dir, dentry); | 172 | err = minix_unlink(dir, dentry); |
175 | if (!err) { | 173 | if (!err) { |
@@ -192,9 +190,6 @@ static int minix_rename(struct inode * old_dir, struct dentry *old_dentry, | |||
192 | struct minix_dir_entry * old_de; | 190 | struct minix_dir_entry * old_de; |
193 | int err = -ENOENT; | 191 | int err = -ENOENT; |
194 | 192 | ||
195 | if (new_inode && S_ISDIR(new_inode->i_mode)) | ||
196 | dentry_unhash(new_dentry); | ||
197 | |||
198 | old_de = minix_find_entry(old_dentry, &old_page); | 193 | old_de = minix_find_entry(old_dentry, &old_page); |
199 | if (!old_de) | 194 | if (!old_de) |
200 | goto out; | 195 | goto out; |
diff --git a/fs/namei.c b/fs/namei.c index 2358b326b221..e2e4e8d032ee 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -919,12 +919,11 @@ static inline bool managed_dentry_might_block(struct dentry *dentry) | |||
919 | } | 919 | } |
920 | 920 | ||
921 | /* | 921 | /* |
922 | * Skip to top of mountpoint pile in rcuwalk mode. We abort the rcu-walk if we | 922 | * Try to skip to top of mountpoint pile in rcuwalk mode. Fail if |
923 | * meet a managed dentry and we're not walking to "..". True is returned to | 923 | * we meet a managed dentry that would need blocking. |
924 | * continue, false to abort. | ||
925 | */ | 924 | */ |
926 | static bool __follow_mount_rcu(struct nameidata *nd, struct path *path, | 925 | static bool __follow_mount_rcu(struct nameidata *nd, struct path *path, |
927 | struct inode **inode, bool reverse_transit) | 926 | struct inode **inode) |
928 | { | 927 | { |
929 | for (;;) { | 928 | for (;;) { |
930 | struct vfsmount *mounted; | 929 | struct vfsmount *mounted; |
@@ -933,8 +932,7 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path, | |||
933 | * that wants to block transit. | 932 | * that wants to block transit. |
934 | */ | 933 | */ |
935 | *inode = path->dentry->d_inode; | 934 | *inode = path->dentry->d_inode; |
936 | if (!reverse_transit && | 935 | if (unlikely(managed_dentry_might_block(path->dentry))) |
937 | unlikely(managed_dentry_might_block(path->dentry))) | ||
938 | return false; | 936 | return false; |
939 | 937 | ||
940 | if (!d_mountpoint(path->dentry)) | 938 | if (!d_mountpoint(path->dentry)) |
@@ -947,16 +945,24 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path, | |||
947 | path->dentry = mounted->mnt_root; | 945 | path->dentry = mounted->mnt_root; |
948 | nd->seq = read_seqcount_begin(&path->dentry->d_seq); | 946 | nd->seq = read_seqcount_begin(&path->dentry->d_seq); |
949 | } | 947 | } |
950 | |||
951 | if (unlikely(path->dentry->d_flags & DCACHE_NEED_AUTOMOUNT)) | ||
952 | return reverse_transit; | ||
953 | return true; | 948 | return true; |
954 | } | 949 | } |
955 | 950 | ||
956 | static int follow_dotdot_rcu(struct nameidata *nd) | 951 | static void follow_mount_rcu(struct nameidata *nd) |
957 | { | 952 | { |
958 | struct inode *inode = nd->inode; | 953 | while (d_mountpoint(nd->path.dentry)) { |
954 | struct vfsmount *mounted; | ||
955 | mounted = __lookup_mnt(nd->path.mnt, nd->path.dentry, 1); | ||
956 | if (!mounted) | ||
957 | break; | ||
958 | nd->path.mnt = mounted; | ||
959 | nd->path.dentry = mounted->mnt_root; | ||
960 | nd->seq = read_seqcount_begin(&nd->path.dentry->d_seq); | ||
961 | } | ||
962 | } | ||
959 | 963 | ||
964 | static int follow_dotdot_rcu(struct nameidata *nd) | ||
965 | { | ||
960 | set_root_rcu(nd); | 966 | set_root_rcu(nd); |
961 | 967 | ||
962 | while (1) { | 968 | while (1) { |
@@ -972,7 +978,6 @@ static int follow_dotdot_rcu(struct nameidata *nd) | |||
972 | seq = read_seqcount_begin(&parent->d_seq); | 978 | seq = read_seqcount_begin(&parent->d_seq); |
973 | if (read_seqcount_retry(&old->d_seq, nd->seq)) | 979 | if (read_seqcount_retry(&old->d_seq, nd->seq)) |
974 | goto failed; | 980 | goto failed; |
975 | inode = parent->d_inode; | ||
976 | nd->path.dentry = parent; | 981 | nd->path.dentry = parent; |
977 | nd->seq = seq; | 982 | nd->seq = seq; |
978 | break; | 983 | break; |
@@ -980,10 +985,9 @@ static int follow_dotdot_rcu(struct nameidata *nd) | |||
980 | if (!follow_up_rcu(&nd->path)) | 985 | if (!follow_up_rcu(&nd->path)) |
981 | break; | 986 | break; |
982 | nd->seq = read_seqcount_begin(&nd->path.dentry->d_seq); | 987 | nd->seq = read_seqcount_begin(&nd->path.dentry->d_seq); |
983 | inode = nd->path.dentry->d_inode; | ||
984 | } | 988 | } |
985 | __follow_mount_rcu(nd, &nd->path, &inode, true); | 989 | follow_mount_rcu(nd); |
986 | nd->inode = inode; | 990 | nd->inode = nd->path.dentry->d_inode; |
987 | return 0; | 991 | return 0; |
988 | 992 | ||
989 | failed: | 993 | failed: |
@@ -1157,8 +1161,11 @@ static int do_lookup(struct nameidata *nd, struct qstr *name, | |||
1157 | } | 1161 | } |
1158 | path->mnt = mnt; | 1162 | path->mnt = mnt; |
1159 | path->dentry = dentry; | 1163 | path->dentry = dentry; |
1160 | if (likely(__follow_mount_rcu(nd, path, inode, false))) | 1164 | if (unlikely(!__follow_mount_rcu(nd, path, inode))) |
1161 | return 0; | 1165 | goto unlazy; |
1166 | if (unlikely(path->dentry->d_flags & DCACHE_NEED_AUTOMOUNT)) | ||
1167 | goto unlazy; | ||
1168 | return 0; | ||
1162 | unlazy: | 1169 | unlazy: |
1163 | if (unlazy_walk(nd, dentry)) | 1170 | if (unlazy_walk(nd, dentry)) |
1164 | return -ECHILD; | 1171 | return -ECHILD; |
@@ -2572,6 +2579,7 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
2572 | if (error) | 2579 | if (error) |
2573 | goto out; | 2580 | goto out; |
2574 | 2581 | ||
2582 | shrink_dcache_parent(dentry); | ||
2575 | error = dir->i_op->rmdir(dir, dentry); | 2583 | error = dir->i_op->rmdir(dir, dentry); |
2576 | if (error) | 2584 | if (error) |
2577 | goto out; | 2585 | goto out; |
@@ -2986,6 +2994,8 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, | |||
2986 | if (d_mountpoint(old_dentry) || d_mountpoint(new_dentry)) | 2994 | if (d_mountpoint(old_dentry) || d_mountpoint(new_dentry)) |
2987 | goto out; | 2995 | goto out; |
2988 | 2996 | ||
2997 | if (target) | ||
2998 | shrink_dcache_parent(new_dentry); | ||
2989 | error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); | 2999 | error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); |
2990 | if (error) | 3000 | if (error) |
2991 | goto out; | 3001 | goto out; |
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index e3e646b06404..9c51f621e901 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c | |||
@@ -1033,8 +1033,11 @@ static int ncp_rmdir(struct inode *dir, struct dentry *dentry) | |||
1033 | DPRINTK("ncp_rmdir: removing %s/%s\n", | 1033 | DPRINTK("ncp_rmdir: removing %s/%s\n", |
1034 | dentry->d_parent->d_name.name, dentry->d_name.name); | 1034 | dentry->d_parent->d_name.name, dentry->d_name.name); |
1035 | 1035 | ||
1036 | /* | ||
1037 | * fail with EBUSY if there are still references to this | ||
1038 | * directory. | ||
1039 | */ | ||
1036 | dentry_unhash(dentry); | 1040 | dentry_unhash(dentry); |
1037 | |||
1038 | error = -EBUSY; | 1041 | error = -EBUSY; |
1039 | if (!d_unhashed(dentry)) | 1042 | if (!d_unhashed(dentry)) |
1040 | goto out; | 1043 | goto out; |
@@ -1141,8 +1144,16 @@ static int ncp_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1141 | old_dentry->d_parent->d_name.name, old_dentry->d_name.name, | 1144 | old_dentry->d_parent->d_name.name, old_dentry->d_name.name, |
1142 | new_dentry->d_parent->d_name.name, new_dentry->d_name.name); | 1145 | new_dentry->d_parent->d_name.name, new_dentry->d_name.name); |
1143 | 1146 | ||
1144 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | 1147 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) { |
1148 | /* | ||
1149 | * fail with EBUSY if there are still references to this | ||
1150 | * directory. | ||
1151 | */ | ||
1145 | dentry_unhash(new_dentry); | 1152 | dentry_unhash(new_dentry); |
1153 | error = -EBUSY; | ||
1154 | if (!d_unhashed(new_dentry)) | ||
1155 | goto out; | ||
1156 | } | ||
1146 | 1157 | ||
1147 | ncp_age_dentry(server, old_dentry); | 1158 | ncp_age_dentry(server, old_dentry); |
1148 | ncp_age_dentry(server, new_dentry); | 1159 | ncp_age_dentry(server, new_dentry); |
diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig index ba306658a6db..81515545ba75 100644 --- a/fs/nfs/Kconfig +++ b/fs/nfs/Kconfig | |||
@@ -87,6 +87,16 @@ config NFS_V4_1 | |||
87 | config PNFS_FILE_LAYOUT | 87 | config PNFS_FILE_LAYOUT |
88 | tristate | 88 | tristate |
89 | 89 | ||
90 | config PNFS_OBJLAYOUT | ||
91 | tristate "Provide support for the pNFS Objects Layout Driver for NFSv4.1 pNFS (EXPERIMENTAL)" | ||
92 | depends on NFS_FS && NFS_V4_1 && SCSI_OSD_ULD | ||
93 | help | ||
94 | Say M here if you want your pNFS client to support the Objects Layout Driver. | ||
95 | Requires the SCSI osd initiator library (SCSI_OSD_INITIATOR) and | ||
96 | upper level driver (SCSI_OSD_ULD). | ||
97 | |||
98 | If unsure, say N. | ||
99 | |||
90 | config ROOT_NFS | 100 | config ROOT_NFS |
91 | bool "Root file system on NFS" | 101 | bool "Root file system on NFS" |
92 | depends on NFS_FS=y && IP_PNP | 102 | depends on NFS_FS=y && IP_PNP |
diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile index 4776ff9e3814..6a34f7dd0e6f 100644 --- a/fs/nfs/Makefile +++ b/fs/nfs/Makefile | |||
@@ -15,9 +15,11 @@ nfs-$(CONFIG_NFS_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \ | |||
15 | delegation.o idmap.o \ | 15 | delegation.o idmap.o \ |
16 | callback.o callback_xdr.o callback_proc.o \ | 16 | callback.o callback_xdr.o callback_proc.o \ |
17 | nfs4namespace.o | 17 | nfs4namespace.o |
18 | nfs-$(CONFIG_NFS_V4_1) += pnfs.o | 18 | nfs-$(CONFIG_NFS_V4_1) += pnfs.o pnfs_dev.o |
19 | nfs-$(CONFIG_SYSCTL) += sysctl.o | 19 | nfs-$(CONFIG_SYSCTL) += sysctl.o |
20 | nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o | 20 | nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o |
21 | 21 | ||
22 | obj-$(CONFIG_PNFS_FILE_LAYOUT) += nfs_layout_nfsv41_files.o | 22 | obj-$(CONFIG_PNFS_FILE_LAYOUT) += nfs_layout_nfsv41_files.o |
23 | nfs_layout_nfsv41_files-y := nfs4filelayout.o nfs4filelayoutdev.o | 23 | nfs_layout_nfsv41_files-y := nfs4filelayout.o nfs4filelayoutdev.o |
24 | |||
25 | obj-$(CONFIG_PNFS_OBJLAYOUT) += objlayout/ | ||
diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h index 46d93ce7311b..b257383bb565 100644 --- a/fs/nfs/callback.h +++ b/fs/nfs/callback.h | |||
@@ -167,6 +167,23 @@ extern unsigned nfs4_callback_layoutrecall( | |||
167 | 167 | ||
168 | extern void nfs4_check_drain_bc_complete(struct nfs4_session *ses); | 168 | extern void nfs4_check_drain_bc_complete(struct nfs4_session *ses); |
169 | extern void nfs4_cb_take_slot(struct nfs_client *clp); | 169 | extern void nfs4_cb_take_slot(struct nfs_client *clp); |
170 | |||
171 | struct cb_devicenotifyitem { | ||
172 | uint32_t cbd_notify_type; | ||
173 | uint32_t cbd_layout_type; | ||
174 | struct nfs4_deviceid cbd_dev_id; | ||
175 | uint32_t cbd_immediate; | ||
176 | }; | ||
177 | |||
178 | struct cb_devicenotifyargs { | ||
179 | int ndevs; | ||
180 | struct cb_devicenotifyitem *devs; | ||
181 | }; | ||
182 | |||
183 | extern __be32 nfs4_callback_devicenotify( | ||
184 | struct cb_devicenotifyargs *args, | ||
185 | void *dummy, struct cb_process_state *cps); | ||
186 | |||
170 | #endif /* CONFIG_NFS_V4_1 */ | 187 | #endif /* CONFIG_NFS_V4_1 */ |
171 | extern int check_gss_callback_principal(struct nfs_client *, struct svc_rqst *); | 188 | extern int check_gss_callback_principal(struct nfs_client *, struct svc_rqst *); |
172 | extern __be32 nfs4_callback_getattr(struct cb_getattrargs *args, | 189 | extern __be32 nfs4_callback_getattr(struct cb_getattrargs *args, |
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index 2f41dccea18e..d4d1954e9bb9 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c | |||
@@ -139,7 +139,7 @@ static u32 initiate_file_draining(struct nfs_client *clp, | |||
139 | spin_lock(&ino->i_lock); | 139 | spin_lock(&ino->i_lock); |
140 | if (test_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags) || | 140 | if (test_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags) || |
141 | mark_matching_lsegs_invalid(lo, &free_me_list, | 141 | mark_matching_lsegs_invalid(lo, &free_me_list, |
142 | args->cbl_range.iomode)) | 142 | &args->cbl_range)) |
143 | rv = NFS4ERR_DELAY; | 143 | rv = NFS4ERR_DELAY; |
144 | else | 144 | else |
145 | rv = NFS4ERR_NOMATCHING_LAYOUT; | 145 | rv = NFS4ERR_NOMATCHING_LAYOUT; |
@@ -184,7 +184,7 @@ static u32 initiate_bulk_draining(struct nfs_client *clp, | |||
184 | ino = lo->plh_inode; | 184 | ino = lo->plh_inode; |
185 | spin_lock(&ino->i_lock); | 185 | spin_lock(&ino->i_lock); |
186 | set_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags); | 186 | set_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags); |
187 | if (mark_matching_lsegs_invalid(lo, &free_me_list, range.iomode)) | 187 | if (mark_matching_lsegs_invalid(lo, &free_me_list, &range)) |
188 | rv = NFS4ERR_DELAY; | 188 | rv = NFS4ERR_DELAY; |
189 | list_del_init(&lo->plh_bulk_recall); | 189 | list_del_init(&lo->plh_bulk_recall); |
190 | spin_unlock(&ino->i_lock); | 190 | spin_unlock(&ino->i_lock); |
@@ -241,6 +241,53 @@ static void pnfs_recall_all_layouts(struct nfs_client *clp) | |||
241 | do_callback_layoutrecall(clp, &args); | 241 | do_callback_layoutrecall(clp, &args); |
242 | } | 242 | } |
243 | 243 | ||
244 | __be32 nfs4_callback_devicenotify(struct cb_devicenotifyargs *args, | ||
245 | void *dummy, struct cb_process_state *cps) | ||
246 | { | ||
247 | int i; | ||
248 | __be32 res = 0; | ||
249 | struct nfs_client *clp = cps->clp; | ||
250 | struct nfs_server *server = NULL; | ||
251 | |||
252 | dprintk("%s: -->\n", __func__); | ||
253 | |||
254 | if (!clp) { | ||
255 | res = cpu_to_be32(NFS4ERR_OP_NOT_IN_SESSION); | ||
256 | goto out; | ||
257 | } | ||
258 | |||
259 | for (i = 0; i < args->ndevs; i++) { | ||
260 | struct cb_devicenotifyitem *dev = &args->devs[i]; | ||
261 | |||
262 | if (!server || | ||
263 | server->pnfs_curr_ld->id != dev->cbd_layout_type) { | ||
264 | rcu_read_lock(); | ||
265 | list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) | ||
266 | if (server->pnfs_curr_ld && | ||
267 | server->pnfs_curr_ld->id == dev->cbd_layout_type) { | ||
268 | rcu_read_unlock(); | ||
269 | goto found; | ||
270 | } | ||
271 | rcu_read_unlock(); | ||
272 | dprintk("%s: layout type %u not found\n", | ||
273 | __func__, dev->cbd_layout_type); | ||
274 | continue; | ||
275 | } | ||
276 | |||
277 | found: | ||
278 | if (dev->cbd_notify_type == NOTIFY_DEVICEID4_CHANGE) | ||
279 | dprintk("%s: NOTIFY_DEVICEID4_CHANGE not supported, " | ||
280 | "deleting instead\n", __func__); | ||
281 | nfs4_delete_deviceid(server->pnfs_curr_ld, clp, &dev->cbd_dev_id); | ||
282 | } | ||
283 | |||
284 | out: | ||
285 | kfree(args->devs); | ||
286 | dprintk("%s: exit with status = %u\n", | ||
287 | __func__, be32_to_cpu(res)); | ||
288 | return res; | ||
289 | } | ||
290 | |||
244 | int nfs41_validate_delegation_stateid(struct nfs_delegation *delegation, const nfs4_stateid *stateid) | 291 | int nfs41_validate_delegation_stateid(struct nfs_delegation *delegation, const nfs4_stateid *stateid) |
245 | { | 292 | { |
246 | if (delegation == NULL) | 293 | if (delegation == NULL) |
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c index 00ecf62ce7c1..c6c86a77e043 100644 --- a/fs/nfs/callback_xdr.c +++ b/fs/nfs/callback_xdr.c | |||
@@ -25,6 +25,7 @@ | |||
25 | 25 | ||
26 | #if defined(CONFIG_NFS_V4_1) | 26 | #if defined(CONFIG_NFS_V4_1) |
27 | #define CB_OP_LAYOUTRECALL_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ) | 27 | #define CB_OP_LAYOUTRECALL_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ) |
28 | #define CB_OP_DEVICENOTIFY_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ) | ||
28 | #define CB_OP_SEQUENCE_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ + \ | 29 | #define CB_OP_SEQUENCE_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ + \ |
29 | 4 + 1 + 3) | 30 | 4 + 1 + 3) |
30 | #define CB_OP_RECALLANY_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ) | 31 | #define CB_OP_RECALLANY_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ) |
@@ -284,6 +285,93 @@ out: | |||
284 | return status; | 285 | return status; |
285 | } | 286 | } |
286 | 287 | ||
288 | static | ||
289 | __be32 decode_devicenotify_args(struct svc_rqst *rqstp, | ||
290 | struct xdr_stream *xdr, | ||
291 | struct cb_devicenotifyargs *args) | ||
292 | { | ||
293 | __be32 *p; | ||
294 | __be32 status = 0; | ||
295 | u32 tmp; | ||
296 | int n, i; | ||
297 | args->ndevs = 0; | ||
298 | |||
299 | /* Num of device notifications */ | ||
300 | p = read_buf(xdr, sizeof(uint32_t)); | ||
301 | if (unlikely(p == NULL)) { | ||
302 | status = htonl(NFS4ERR_BADXDR); | ||
303 | goto out; | ||
304 | } | ||
305 | n = ntohl(*p++); | ||
306 | if (n <= 0) | ||
307 | goto out; | ||
308 | |||
309 | args->devs = kmalloc(n * sizeof(*args->devs), GFP_KERNEL); | ||
310 | if (!args->devs) { | ||
311 | status = htonl(NFS4ERR_DELAY); | ||
312 | goto out; | ||
313 | } | ||
314 | |||
315 | /* Decode each dev notification */ | ||
316 | for (i = 0; i < n; i++) { | ||
317 | struct cb_devicenotifyitem *dev = &args->devs[i]; | ||
318 | |||
319 | p = read_buf(xdr, (4 * sizeof(uint32_t)) + NFS4_DEVICEID4_SIZE); | ||
320 | if (unlikely(p == NULL)) { | ||
321 | status = htonl(NFS4ERR_BADXDR); | ||
322 | goto err; | ||
323 | } | ||
324 | |||
325 | tmp = ntohl(*p++); /* bitmap size */ | ||
326 | if (tmp != 1) { | ||
327 | status = htonl(NFS4ERR_INVAL); | ||
328 | goto err; | ||
329 | } | ||
330 | dev->cbd_notify_type = ntohl(*p++); | ||
331 | if (dev->cbd_notify_type != NOTIFY_DEVICEID4_CHANGE && | ||
332 | dev->cbd_notify_type != NOTIFY_DEVICEID4_DELETE) { | ||
333 | status = htonl(NFS4ERR_INVAL); | ||
334 | goto err; | ||
335 | } | ||
336 | |||
337 | tmp = ntohl(*p++); /* opaque size */ | ||
338 | if (((dev->cbd_notify_type == NOTIFY_DEVICEID4_CHANGE) && | ||
339 | (tmp != NFS4_DEVICEID4_SIZE + 8)) || | ||
340 | ((dev->cbd_notify_type == NOTIFY_DEVICEID4_DELETE) && | ||
341 | (tmp != NFS4_DEVICEID4_SIZE + 4))) { | ||
342 | status = htonl(NFS4ERR_INVAL); | ||
343 | goto err; | ||
344 | } | ||
345 | dev->cbd_layout_type = ntohl(*p++); | ||
346 | memcpy(dev->cbd_dev_id.data, p, NFS4_DEVICEID4_SIZE); | ||
347 | p += XDR_QUADLEN(NFS4_DEVICEID4_SIZE); | ||
348 | |||
349 | if (dev->cbd_layout_type == NOTIFY_DEVICEID4_CHANGE) { | ||
350 | p = read_buf(xdr, sizeof(uint32_t)); | ||
351 | if (unlikely(p == NULL)) { | ||
352 | status = htonl(NFS4ERR_BADXDR); | ||
353 | goto err; | ||
354 | } | ||
355 | dev->cbd_immediate = ntohl(*p++); | ||
356 | } else { | ||
357 | dev->cbd_immediate = 0; | ||
358 | } | ||
359 | |||
360 | args->ndevs++; | ||
361 | |||
362 | dprintk("%s: type %d layout 0x%x immediate %d\n", | ||
363 | __func__, dev->cbd_notify_type, dev->cbd_layout_type, | ||
364 | dev->cbd_immediate); | ||
365 | } | ||
366 | out: | ||
367 | dprintk("%s: status %d ndevs %d\n", | ||
368 | __func__, ntohl(status), args->ndevs); | ||
369 | return status; | ||
370 | err: | ||
371 | kfree(args->devs); | ||
372 | goto out; | ||
373 | } | ||
374 | |||
287 | static __be32 decode_sessionid(struct xdr_stream *xdr, | 375 | static __be32 decode_sessionid(struct xdr_stream *xdr, |
288 | struct nfs4_sessionid *sid) | 376 | struct nfs4_sessionid *sid) |
289 | { | 377 | { |
@@ -639,10 +727,10 @@ preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op) | |||
639 | case OP_CB_RECALL_ANY: | 727 | case OP_CB_RECALL_ANY: |
640 | case OP_CB_RECALL_SLOT: | 728 | case OP_CB_RECALL_SLOT: |
641 | case OP_CB_LAYOUTRECALL: | 729 | case OP_CB_LAYOUTRECALL: |
730 | case OP_CB_NOTIFY_DEVICEID: | ||
642 | *op = &callback_ops[op_nr]; | 731 | *op = &callback_ops[op_nr]; |
643 | break; | 732 | break; |
644 | 733 | ||
645 | case OP_CB_NOTIFY_DEVICEID: | ||
646 | case OP_CB_NOTIFY: | 734 | case OP_CB_NOTIFY: |
647 | case OP_CB_PUSH_DELEG: | 735 | case OP_CB_PUSH_DELEG: |
648 | case OP_CB_RECALLABLE_OBJ_AVAIL: | 736 | case OP_CB_RECALLABLE_OBJ_AVAIL: |
@@ -849,6 +937,12 @@ static struct callback_op callback_ops[] = { | |||
849 | (callback_decode_arg_t)decode_layoutrecall_args, | 937 | (callback_decode_arg_t)decode_layoutrecall_args, |
850 | .res_maxsize = CB_OP_LAYOUTRECALL_RES_MAXSZ, | 938 | .res_maxsize = CB_OP_LAYOUTRECALL_RES_MAXSZ, |
851 | }, | 939 | }, |
940 | [OP_CB_NOTIFY_DEVICEID] = { | ||
941 | .process_op = (callback_process_op_t)nfs4_callback_devicenotify, | ||
942 | .decode_args = | ||
943 | (callback_decode_arg_t)decode_devicenotify_args, | ||
944 | .res_maxsize = CB_OP_DEVICENOTIFY_RES_MAXSZ, | ||
945 | }, | ||
852 | [OP_CB_SEQUENCE] = { | 946 | [OP_CB_SEQUENCE] = { |
853 | .process_op = (callback_process_op_t)nfs4_callback_sequence, | 947 | .process_op = (callback_process_op_t)nfs4_callback_sequence, |
854 | .decode_args = (callback_decode_arg_t)decode_cb_sequence_args, | 948 | .decode_args = (callback_decode_arg_t)decode_cb_sequence_args, |
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 139be9647d80..b3dc2b88b65b 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
@@ -290,6 +290,8 @@ static void nfs_free_client(struct nfs_client *clp) | |||
290 | if (clp->cl_machine_cred != NULL) | 290 | if (clp->cl_machine_cred != NULL) |
291 | put_rpccred(clp->cl_machine_cred); | 291 | put_rpccred(clp->cl_machine_cred); |
292 | 292 | ||
293 | nfs4_deviceid_purge_client(clp); | ||
294 | |||
293 | kfree(clp->cl_hostname); | 295 | kfree(clp->cl_hostname); |
294 | kfree(clp); | 296 | kfree(clp); |
295 | 297 | ||
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index bbbc6bf5cb2e..dd25c2aec375 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c | |||
@@ -21,25 +21,13 @@ | |||
21 | #include "delegation.h" | 21 | #include "delegation.h" |
22 | #include "internal.h" | 22 | #include "internal.h" |
23 | 23 | ||
24 | static void nfs_do_free_delegation(struct nfs_delegation *delegation) | ||
25 | { | ||
26 | kfree(delegation); | ||
27 | } | ||
28 | |||
29 | static void nfs_free_delegation_callback(struct rcu_head *head) | ||
30 | { | ||
31 | struct nfs_delegation *delegation = container_of(head, struct nfs_delegation, rcu); | ||
32 | |||
33 | nfs_do_free_delegation(delegation); | ||
34 | } | ||
35 | |||
36 | static void nfs_free_delegation(struct nfs_delegation *delegation) | 24 | static void nfs_free_delegation(struct nfs_delegation *delegation) |
37 | { | 25 | { |
38 | if (delegation->cred) { | 26 | if (delegation->cred) { |
39 | put_rpccred(delegation->cred); | 27 | put_rpccred(delegation->cred); |
40 | delegation->cred = NULL; | 28 | delegation->cred = NULL; |
41 | } | 29 | } |
42 | call_rcu(&delegation->rcu, nfs_free_delegation_callback); | 30 | kfree_rcu(delegation, rcu); |
43 | } | 31 | } |
44 | 32 | ||
45 | /** | 33 | /** |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 424e47773a84..ededdbd0db38 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -512,12 +512,7 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en | |||
512 | struct page **xdr_pages, struct page *page, unsigned int buflen) | 512 | struct page **xdr_pages, struct page *page, unsigned int buflen) |
513 | { | 513 | { |
514 | struct xdr_stream stream; | 514 | struct xdr_stream stream; |
515 | struct xdr_buf buf = { | 515 | struct xdr_buf buf; |
516 | .pages = xdr_pages, | ||
517 | .page_len = buflen, | ||
518 | .buflen = buflen, | ||
519 | .len = buflen, | ||
520 | }; | ||
521 | struct page *scratch; | 516 | struct page *scratch; |
522 | struct nfs_cache_array *array; | 517 | struct nfs_cache_array *array; |
523 | unsigned int count = 0; | 518 | unsigned int count = 0; |
@@ -527,7 +522,7 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en | |||
527 | if (scratch == NULL) | 522 | if (scratch == NULL) |
528 | return -ENOMEM; | 523 | return -ENOMEM; |
529 | 524 | ||
530 | xdr_init_decode(&stream, &buf, NULL); | 525 | xdr_init_decode_pages(&stream, &buf, xdr_pages, buflen); |
531 | xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE); | 526 | xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE); |
532 | 527 | ||
533 | do { | 528 | do { |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 57bb31ad7a5e..144f2a3c7185 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -1298,8 +1298,12 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1298 | i_size_write(inode, new_isize); | 1298 | i_size_write(inode, new_isize); |
1299 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; | 1299 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; |
1300 | } | 1300 | } |
1301 | dprintk("NFS: isize change on server for file %s/%ld\n", | 1301 | dprintk("NFS: isize change on server for file %s/%ld " |
1302 | inode->i_sb->s_id, inode->i_ino); | 1302 | "(%Ld to %Ld)\n", |
1303 | inode->i_sb->s_id, | ||
1304 | inode->i_ino, | ||
1305 | (long long)cur_isize, | ||
1306 | (long long)new_isize); | ||
1303 | } | 1307 | } |
1304 | } else | 1308 | } else |
1305 | invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR | 1309 | invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR |
@@ -1424,9 +1428,10 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1424 | */ | 1428 | */ |
1425 | void nfs4_evict_inode(struct inode *inode) | 1429 | void nfs4_evict_inode(struct inode *inode) |
1426 | { | 1430 | { |
1427 | pnfs_destroy_layout(NFS_I(inode)); | ||
1428 | truncate_inode_pages(&inode->i_data, 0); | 1431 | truncate_inode_pages(&inode->i_data, 0); |
1429 | end_writeback(inode); | 1432 | end_writeback(inode); |
1433 | pnfs_return_layout(inode); | ||
1434 | pnfs_destroy_layout(NFS_I(inode)); | ||
1430 | /* If we are holding a delegation, return it! */ | 1435 | /* If we are holding a delegation, return it! */ |
1431 | nfs_inode_return_delegation_noreclaim(inode); | 1436 | nfs_inode_return_delegation_noreclaim(inode); |
1432 | /* First call standard NFS clear_inode() code */ | 1437 | /* First call standard NFS clear_inode() code */ |
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 2df6ca7b5898..b9056cbe68d6 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h | |||
@@ -310,6 +310,7 @@ extern int nfs_migrate_page(struct address_space *, | |||
310 | #endif | 310 | #endif |
311 | 311 | ||
312 | /* nfs4proc.c */ | 312 | /* nfs4proc.c */ |
313 | extern void __nfs4_read_done_cb(struct nfs_read_data *); | ||
313 | extern void nfs4_reset_read(struct rpc_task *task, struct nfs_read_data *data); | 314 | extern void nfs4_reset_read(struct rpc_task *task, struct nfs_read_data *data); |
314 | extern int nfs4_init_client(struct nfs_client *clp, | 315 | extern int nfs4_init_client(struct nfs_client *clp, |
315 | const struct rpc_timeout *timeparms, | 316 | const struct rpc_timeout *timeparms, |
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c index be79dc9f386d..426908809c97 100644 --- a/fs/nfs/nfs4filelayout.c +++ b/fs/nfs/nfs4filelayout.c | |||
@@ -421,6 +421,7 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo, | |||
421 | struct nfs4_deviceid *id, | 421 | struct nfs4_deviceid *id, |
422 | gfp_t gfp_flags) | 422 | gfp_t gfp_flags) |
423 | { | 423 | { |
424 | struct nfs4_deviceid_node *d; | ||
424 | struct nfs4_file_layout_dsaddr *dsaddr; | 425 | struct nfs4_file_layout_dsaddr *dsaddr; |
425 | int status = -EINVAL; | 426 | int status = -EINVAL; |
426 | struct nfs_server *nfss = NFS_SERVER(lo->plh_inode); | 427 | struct nfs_server *nfss = NFS_SERVER(lo->plh_inode); |
@@ -428,7 +429,7 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo, | |||
428 | dprintk("--> %s\n", __func__); | 429 | dprintk("--> %s\n", __func__); |
429 | 430 | ||
430 | if (fl->pattern_offset > lgr->range.offset) { | 431 | if (fl->pattern_offset > lgr->range.offset) { |
431 | dprintk("%s pattern_offset %lld to large\n", | 432 | dprintk("%s pattern_offset %lld too large\n", |
432 | __func__, fl->pattern_offset); | 433 | __func__, fl->pattern_offset); |
433 | goto out; | 434 | goto out; |
434 | } | 435 | } |
@@ -440,12 +441,14 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo, | |||
440 | } | 441 | } |
441 | 442 | ||
442 | /* find and reference the deviceid */ | 443 | /* find and reference the deviceid */ |
443 | dsaddr = nfs4_fl_find_get_deviceid(id); | 444 | d = nfs4_find_get_deviceid(NFS_SERVER(lo->plh_inode)->pnfs_curr_ld, |
444 | if (dsaddr == NULL) { | 445 | NFS_SERVER(lo->plh_inode)->nfs_client, id); |
446 | if (d == NULL) { | ||
445 | dsaddr = get_device_info(lo->plh_inode, id, gfp_flags); | 447 | dsaddr = get_device_info(lo->plh_inode, id, gfp_flags); |
446 | if (dsaddr == NULL) | 448 | if (dsaddr == NULL) |
447 | goto out; | 449 | goto out; |
448 | } | 450 | } else |
451 | dsaddr = container_of(d, struct nfs4_file_layout_dsaddr, id_node); | ||
449 | fl->dsaddr = dsaddr; | 452 | fl->dsaddr = dsaddr; |
450 | 453 | ||
451 | if (fl->first_stripe_index < 0 || | 454 | if (fl->first_stripe_index < 0 || |
@@ -507,12 +510,7 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo, | |||
507 | gfp_t gfp_flags) | 510 | gfp_t gfp_flags) |
508 | { | 511 | { |
509 | struct xdr_stream stream; | 512 | struct xdr_stream stream; |
510 | struct xdr_buf buf = { | 513 | struct xdr_buf buf; |
511 | .pages = lgr->layoutp->pages, | ||
512 | .page_len = lgr->layoutp->len, | ||
513 | .buflen = lgr->layoutp->len, | ||
514 | .len = lgr->layoutp->len, | ||
515 | }; | ||
516 | struct page *scratch; | 514 | struct page *scratch; |
517 | __be32 *p; | 515 | __be32 *p; |
518 | uint32_t nfl_util; | 516 | uint32_t nfl_util; |
@@ -524,7 +522,7 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo, | |||
524 | if (!scratch) | 522 | if (!scratch) |
525 | return -ENOMEM; | 523 | return -ENOMEM; |
526 | 524 | ||
527 | xdr_init_decode(&stream, &buf, NULL); | 525 | xdr_init_decode_pages(&stream, &buf, lgr->layoutp->pages, lgr->layoutp->len); |
528 | xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE); | 526 | xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE); |
529 | 527 | ||
530 | /* 20 = ufl_util (4), first_stripe_index (4), pattern_offset (8), | 528 | /* 20 = ufl_util (4), first_stripe_index (4), pattern_offset (8), |
@@ -535,7 +533,7 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo, | |||
535 | 533 | ||
536 | memcpy(id, p, sizeof(*id)); | 534 | memcpy(id, p, sizeof(*id)); |
537 | p += XDR_QUADLEN(NFS4_DEVICEID4_SIZE); | 535 | p += XDR_QUADLEN(NFS4_DEVICEID4_SIZE); |
538 | print_deviceid(id); | 536 | nfs4_print_deviceid(id); |
539 | 537 | ||
540 | nfl_util = be32_to_cpup(p++); | 538 | nfl_util = be32_to_cpup(p++); |
541 | if (nfl_util & NFL4_UFLG_COMMIT_THRU_MDS) | 539 | if (nfl_util & NFL4_UFLG_COMMIT_THRU_MDS) |
@@ -653,16 +651,19 @@ filelayout_alloc_lseg(struct pnfs_layout_hdr *layoutid, | |||
653 | /* | 651 | /* |
654 | * filelayout_pg_test(). Called by nfs_can_coalesce_requests() | 652 | * filelayout_pg_test(). Called by nfs_can_coalesce_requests() |
655 | * | 653 | * |
656 | * return 1 : coalesce page | 654 | * return true : coalesce page |
657 | * return 0 : don't coalesce page | 655 | * return false : don't coalesce page |
658 | */ | 656 | */ |
659 | int | 657 | bool |
660 | filelayout_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, | 658 | filelayout_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, |
661 | struct nfs_page *req) | 659 | struct nfs_page *req) |
662 | { | 660 | { |
663 | u64 p_stripe, r_stripe; | 661 | u64 p_stripe, r_stripe; |
664 | u32 stripe_unit; | 662 | u32 stripe_unit; |
665 | 663 | ||
664 | if (!pnfs_generic_pg_test(pgio, prev, req)) | ||
665 | return 0; | ||
666 | |||
666 | if (!pgio->pg_lseg) | 667 | if (!pgio->pg_lseg) |
667 | return 1; | 668 | return 1; |
668 | p_stripe = (u64)prev->wb_index << PAGE_CACHE_SHIFT; | 669 | p_stripe = (u64)prev->wb_index << PAGE_CACHE_SHIFT; |
@@ -860,6 +861,12 @@ filelayout_commit_pagelist(struct inode *inode, struct list_head *mds_pages, | |||
860 | return -ENOMEM; | 861 | return -ENOMEM; |
861 | } | 862 | } |
862 | 863 | ||
864 | static void | ||
865 | filelayout_free_deveiceid_node(struct nfs4_deviceid_node *d) | ||
866 | { | ||
867 | nfs4_fl_free_deviceid(container_of(d, struct nfs4_file_layout_dsaddr, id_node)); | ||
868 | } | ||
869 | |||
863 | static struct pnfs_layoutdriver_type filelayout_type = { | 870 | static struct pnfs_layoutdriver_type filelayout_type = { |
864 | .id = LAYOUT_NFSV4_1_FILES, | 871 | .id = LAYOUT_NFSV4_1_FILES, |
865 | .name = "LAYOUT_NFSV4_1_FILES", | 872 | .name = "LAYOUT_NFSV4_1_FILES", |
@@ -872,6 +879,7 @@ static struct pnfs_layoutdriver_type filelayout_type = { | |||
872 | .commit_pagelist = filelayout_commit_pagelist, | 879 | .commit_pagelist = filelayout_commit_pagelist, |
873 | .read_pagelist = filelayout_read_pagelist, | 880 | .read_pagelist = filelayout_read_pagelist, |
874 | .write_pagelist = filelayout_write_pagelist, | 881 | .write_pagelist = filelayout_write_pagelist, |
882 | .free_deviceid_node = filelayout_free_deveiceid_node, | ||
875 | }; | 883 | }; |
876 | 884 | ||
877 | static int __init nfs4filelayout_init(void) | 885 | static int __init nfs4filelayout_init(void) |
diff --git a/fs/nfs/nfs4filelayout.h b/fs/nfs/nfs4filelayout.h index 2b461d77b43a..cebe01e3795e 100644 --- a/fs/nfs/nfs4filelayout.h +++ b/fs/nfs/nfs4filelayout.h | |||
@@ -59,9 +59,7 @@ struct nfs4_pnfs_ds { | |||
59 | #define NFS4_DEVICE_ID_NEG_ENTRY 0x00000001 | 59 | #define NFS4_DEVICE_ID_NEG_ENTRY 0x00000001 |
60 | 60 | ||
61 | struct nfs4_file_layout_dsaddr { | 61 | struct nfs4_file_layout_dsaddr { |
62 | struct hlist_node node; | 62 | struct nfs4_deviceid_node id_node; |
63 | struct nfs4_deviceid deviceid; | ||
64 | atomic_t ref; | ||
65 | unsigned long flags; | 63 | unsigned long flags; |
66 | u32 stripe_count; | 64 | u32 stripe_count; |
67 | u8 *stripe_indices; | 65 | u8 *stripe_indices; |
@@ -95,14 +93,12 @@ extern struct nfs_fh * | |||
95 | nfs4_fl_select_ds_fh(struct pnfs_layout_segment *lseg, u32 j); | 93 | nfs4_fl_select_ds_fh(struct pnfs_layout_segment *lseg, u32 j); |
96 | 94 | ||
97 | extern void print_ds(struct nfs4_pnfs_ds *ds); | 95 | extern void print_ds(struct nfs4_pnfs_ds *ds); |
98 | extern void print_deviceid(struct nfs4_deviceid *dev_id); | ||
99 | u32 nfs4_fl_calc_j_index(struct pnfs_layout_segment *lseg, loff_t offset); | 96 | u32 nfs4_fl_calc_j_index(struct pnfs_layout_segment *lseg, loff_t offset); |
100 | u32 nfs4_fl_calc_ds_index(struct pnfs_layout_segment *lseg, u32 j); | 97 | u32 nfs4_fl_calc_ds_index(struct pnfs_layout_segment *lseg, u32 j); |
101 | struct nfs4_pnfs_ds *nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, | 98 | struct nfs4_pnfs_ds *nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, |
102 | u32 ds_idx); | 99 | u32 ds_idx); |
103 | extern struct nfs4_file_layout_dsaddr * | ||
104 | nfs4_fl_find_get_deviceid(struct nfs4_deviceid *dev_id); | ||
105 | extern void nfs4_fl_put_deviceid(struct nfs4_file_layout_dsaddr *dsaddr); | 100 | extern void nfs4_fl_put_deviceid(struct nfs4_file_layout_dsaddr *dsaddr); |
101 | extern void nfs4_fl_free_deviceid(struct nfs4_file_layout_dsaddr *dsaddr); | ||
106 | struct nfs4_file_layout_dsaddr * | 102 | struct nfs4_file_layout_dsaddr * |
107 | get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_flags); | 103 | get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_flags); |
108 | 104 | ||
diff --git a/fs/nfs/nfs4filelayoutdev.c b/fs/nfs/nfs4filelayoutdev.c index db07c7af1395..3b7bf1377264 100644 --- a/fs/nfs/nfs4filelayoutdev.c +++ b/fs/nfs/nfs4filelayoutdev.c | |||
@@ -37,30 +37,6 @@ | |||
37 | #define NFSDBG_FACILITY NFSDBG_PNFS_LD | 37 | #define NFSDBG_FACILITY NFSDBG_PNFS_LD |
38 | 38 | ||
39 | /* | 39 | /* |
40 | * Device ID RCU cache. A device ID is unique per client ID and layout type. | ||
41 | */ | ||
42 | #define NFS4_FL_DEVICE_ID_HASH_BITS 5 | ||
43 | #define NFS4_FL_DEVICE_ID_HASH_SIZE (1 << NFS4_FL_DEVICE_ID_HASH_BITS) | ||
44 | #define NFS4_FL_DEVICE_ID_HASH_MASK (NFS4_FL_DEVICE_ID_HASH_SIZE - 1) | ||
45 | |||
46 | static inline u32 | ||
47 | nfs4_fl_deviceid_hash(struct nfs4_deviceid *id) | ||
48 | { | ||
49 | unsigned char *cptr = (unsigned char *)id->data; | ||
50 | unsigned int nbytes = NFS4_DEVICEID4_SIZE; | ||
51 | u32 x = 0; | ||
52 | |||
53 | while (nbytes--) { | ||
54 | x *= 37; | ||
55 | x += *cptr++; | ||
56 | } | ||
57 | return x & NFS4_FL_DEVICE_ID_HASH_MASK; | ||
58 | } | ||
59 | |||
60 | static struct hlist_head filelayout_deviceid_cache[NFS4_FL_DEVICE_ID_HASH_SIZE]; | ||
61 | static DEFINE_SPINLOCK(filelayout_deviceid_lock); | ||
62 | |||
63 | /* | ||
64 | * Data server cache | 40 | * Data server cache |
65 | * | 41 | * |
66 | * Data servers can be mapped to different device ids. | 42 | * Data servers can be mapped to different device ids. |
@@ -89,27 +65,6 @@ print_ds(struct nfs4_pnfs_ds *ds) | |||
89 | ds->ds_clp ? ds->ds_clp->cl_exchange_flags : 0); | 65 | ds->ds_clp ? ds->ds_clp->cl_exchange_flags : 0); |
90 | } | 66 | } |
91 | 67 | ||
92 | void | ||
93 | print_ds_list(struct nfs4_file_layout_dsaddr *dsaddr) | ||
94 | { | ||
95 | int i; | ||
96 | |||
97 | ifdebug(FACILITY) { | ||
98 | printk("%s dsaddr->ds_num %d\n", __func__, | ||
99 | dsaddr->ds_num); | ||
100 | for (i = 0; i < dsaddr->ds_num; i++) | ||
101 | print_ds(dsaddr->ds_list[i]); | ||
102 | } | ||
103 | } | ||
104 | |||
105 | void print_deviceid(struct nfs4_deviceid *id) | ||
106 | { | ||
107 | u32 *p = (u32 *)id; | ||
108 | |||
109 | dprintk("%s: device id= [%x%x%x%x]\n", __func__, | ||
110 | p[0], p[1], p[2], p[3]); | ||
111 | } | ||
112 | |||
113 | /* nfs4_ds_cache_lock is held */ | 68 | /* nfs4_ds_cache_lock is held */ |
114 | static struct nfs4_pnfs_ds * | 69 | static struct nfs4_pnfs_ds * |
115 | _data_server_lookup_locked(u32 ip_addr, u32 port) | 70 | _data_server_lookup_locked(u32 ip_addr, u32 port) |
@@ -201,13 +156,13 @@ destroy_ds(struct nfs4_pnfs_ds *ds) | |||
201 | kfree(ds); | 156 | kfree(ds); |
202 | } | 157 | } |
203 | 158 | ||
204 | static void | 159 | void |
205 | nfs4_fl_free_deviceid(struct nfs4_file_layout_dsaddr *dsaddr) | 160 | nfs4_fl_free_deviceid(struct nfs4_file_layout_dsaddr *dsaddr) |
206 | { | 161 | { |
207 | struct nfs4_pnfs_ds *ds; | 162 | struct nfs4_pnfs_ds *ds; |
208 | int i; | 163 | int i; |
209 | 164 | ||
210 | print_deviceid(&dsaddr->deviceid); | 165 | nfs4_print_deviceid(&dsaddr->id_node.deviceid); |
211 | 166 | ||
212 | for (i = 0; i < dsaddr->ds_num; i++) { | 167 | for (i = 0; i < dsaddr->ds_num; i++) { |
213 | ds = dsaddr->ds_list[i]; | 168 | ds = dsaddr->ds_list[i]; |
@@ -353,12 +308,7 @@ decode_device(struct inode *ino, struct pnfs_device *pdev, gfp_t gfp_flags) | |||
353 | u8 max_stripe_index; | 308 | u8 max_stripe_index; |
354 | struct nfs4_file_layout_dsaddr *dsaddr = NULL; | 309 | struct nfs4_file_layout_dsaddr *dsaddr = NULL; |
355 | struct xdr_stream stream; | 310 | struct xdr_stream stream; |
356 | struct xdr_buf buf = { | 311 | struct xdr_buf buf; |
357 | .pages = pdev->pages, | ||
358 | .page_len = pdev->pglen, | ||
359 | .buflen = pdev->pglen, | ||
360 | .len = pdev->pglen, | ||
361 | }; | ||
362 | struct page *scratch; | 312 | struct page *scratch; |
363 | 313 | ||
364 | /* set up xdr stream */ | 314 | /* set up xdr stream */ |
@@ -366,7 +316,7 @@ decode_device(struct inode *ino, struct pnfs_device *pdev, gfp_t gfp_flags) | |||
366 | if (!scratch) | 316 | if (!scratch) |
367 | goto out_err; | 317 | goto out_err; |
368 | 318 | ||
369 | xdr_init_decode(&stream, &buf, NULL); | 319 | xdr_init_decode_pages(&stream, &buf, pdev->pages, pdev->pglen); |
370 | xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE); | 320 | xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE); |
371 | 321 | ||
372 | /* Get the stripe count (number of stripe index) */ | 322 | /* Get the stripe count (number of stripe index) */ |
@@ -431,8 +381,10 @@ decode_device(struct inode *ino, struct pnfs_device *pdev, gfp_t gfp_flags) | |||
431 | dsaddr->stripe_indices = stripe_indices; | 381 | dsaddr->stripe_indices = stripe_indices; |
432 | stripe_indices = NULL; | 382 | stripe_indices = NULL; |
433 | dsaddr->ds_num = num; | 383 | dsaddr->ds_num = num; |
434 | 384 | nfs4_init_deviceid_node(&dsaddr->id_node, | |
435 | memcpy(&dsaddr->deviceid, &pdev->dev_id, sizeof(pdev->dev_id)); | 385 | NFS_SERVER(ino)->pnfs_curr_ld, |
386 | NFS_SERVER(ino)->nfs_client, | ||
387 | &pdev->dev_id); | ||
436 | 388 | ||
437 | for (i = 0; i < dsaddr->ds_num; i++) { | 389 | for (i = 0; i < dsaddr->ds_num; i++) { |
438 | int j; | 390 | int j; |
@@ -505,8 +457,8 @@ out_err: | |||
505 | static struct nfs4_file_layout_dsaddr * | 457 | static struct nfs4_file_layout_dsaddr * |
506 | decode_and_add_device(struct inode *inode, struct pnfs_device *dev, gfp_t gfp_flags) | 458 | decode_and_add_device(struct inode *inode, struct pnfs_device *dev, gfp_t gfp_flags) |
507 | { | 459 | { |
508 | struct nfs4_file_layout_dsaddr *d, *new; | 460 | struct nfs4_deviceid_node *d; |
509 | long hash; | 461 | struct nfs4_file_layout_dsaddr *n, *new; |
510 | 462 | ||
511 | new = decode_device(inode, dev, gfp_flags); | 463 | new = decode_device(inode, dev, gfp_flags); |
512 | if (!new) { | 464 | if (!new) { |
@@ -515,20 +467,13 @@ decode_and_add_device(struct inode *inode, struct pnfs_device *dev, gfp_t gfp_fl | |||
515 | return NULL; | 467 | return NULL; |
516 | } | 468 | } |
517 | 469 | ||
518 | spin_lock(&filelayout_deviceid_lock); | 470 | d = nfs4_insert_deviceid_node(&new->id_node); |
519 | d = nfs4_fl_find_get_deviceid(&new->deviceid); | 471 | n = container_of(d, struct nfs4_file_layout_dsaddr, id_node); |
520 | if (d) { | 472 | if (n != new) { |
521 | spin_unlock(&filelayout_deviceid_lock); | ||
522 | nfs4_fl_free_deviceid(new); | 473 | nfs4_fl_free_deviceid(new); |
523 | return d; | 474 | return n; |
524 | } | 475 | } |
525 | 476 | ||
526 | INIT_HLIST_NODE(&new->node); | ||
527 | atomic_set(&new->ref, 1); | ||
528 | hash = nfs4_fl_deviceid_hash(&new->deviceid); | ||
529 | hlist_add_head_rcu(&new->node, &filelayout_deviceid_cache[hash]); | ||
530 | spin_unlock(&filelayout_deviceid_lock); | ||
531 | |||
532 | return new; | 477 | return new; |
533 | } | 478 | } |
534 | 479 | ||
@@ -600,35 +545,7 @@ out_free: | |||
600 | void | 545 | void |
601 | nfs4_fl_put_deviceid(struct nfs4_file_layout_dsaddr *dsaddr) | 546 | nfs4_fl_put_deviceid(struct nfs4_file_layout_dsaddr *dsaddr) |
602 | { | 547 | { |
603 | if (atomic_dec_and_lock(&dsaddr->ref, &filelayout_deviceid_lock)) { | 548 | nfs4_put_deviceid_node(&dsaddr->id_node); |
604 | hlist_del_rcu(&dsaddr->node); | ||
605 | spin_unlock(&filelayout_deviceid_lock); | ||
606 | |||
607 | synchronize_rcu(); | ||
608 | nfs4_fl_free_deviceid(dsaddr); | ||
609 | } | ||
610 | } | ||
611 | |||
612 | struct nfs4_file_layout_dsaddr * | ||
613 | nfs4_fl_find_get_deviceid(struct nfs4_deviceid *id) | ||
614 | { | ||
615 | struct nfs4_file_layout_dsaddr *d; | ||
616 | struct hlist_node *n; | ||
617 | long hash = nfs4_fl_deviceid_hash(id); | ||
618 | |||
619 | |||
620 | rcu_read_lock(); | ||
621 | hlist_for_each_entry_rcu(d, n, &filelayout_deviceid_cache[hash], node) { | ||
622 | if (!memcmp(&d->deviceid, id, sizeof(*id))) { | ||
623 | if (!atomic_inc_not_zero(&d->ref)) | ||
624 | goto fail; | ||
625 | rcu_read_unlock(); | ||
626 | return d; | ||
627 | } | ||
628 | } | ||
629 | fail: | ||
630 | rcu_read_unlock(); | ||
631 | return NULL; | ||
632 | } | 549 | } |
633 | 550 | ||
634 | /* | 551 | /* |
@@ -676,15 +593,15 @@ static void | |||
676 | filelayout_mark_devid_negative(struct nfs4_file_layout_dsaddr *dsaddr, | 593 | filelayout_mark_devid_negative(struct nfs4_file_layout_dsaddr *dsaddr, |
677 | int err, u32 ds_addr) | 594 | int err, u32 ds_addr) |
678 | { | 595 | { |
679 | u32 *p = (u32 *)&dsaddr->deviceid; | 596 | u32 *p = (u32 *)&dsaddr->id_node.deviceid; |
680 | 597 | ||
681 | printk(KERN_ERR "NFS: data server %x connection error %d." | 598 | printk(KERN_ERR "NFS: data server %x connection error %d." |
682 | " Deviceid [%x%x%x%x] marked out of use.\n", | 599 | " Deviceid [%x%x%x%x] marked out of use.\n", |
683 | ds_addr, err, p[0], p[1], p[2], p[3]); | 600 | ds_addr, err, p[0], p[1], p[2], p[3]); |
684 | 601 | ||
685 | spin_lock(&filelayout_deviceid_lock); | 602 | spin_lock(&nfs4_ds_cache_lock); |
686 | dsaddr->flags |= NFS4_DEVICE_ID_NEG_ENTRY; | 603 | dsaddr->flags |= NFS4_DEVICE_ID_NEG_ENTRY; |
687 | spin_unlock(&filelayout_deviceid_lock); | 604 | spin_unlock(&nfs4_ds_cache_lock); |
688 | } | 605 | } |
689 | 606 | ||
690 | struct nfs4_pnfs_ds * | 607 | struct nfs4_pnfs_ds * |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index cf1b339c3937..d2c4b59c896d 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -267,9 +267,11 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc | |||
267 | break; | 267 | break; |
268 | nfs4_schedule_stateid_recovery(server, state); | 268 | nfs4_schedule_stateid_recovery(server, state); |
269 | goto wait_on_recovery; | 269 | goto wait_on_recovery; |
270 | case -NFS4ERR_EXPIRED: | ||
271 | if (state != NULL) | ||
272 | nfs4_schedule_stateid_recovery(server, state); | ||
270 | case -NFS4ERR_STALE_STATEID: | 273 | case -NFS4ERR_STALE_STATEID: |
271 | case -NFS4ERR_STALE_CLIENTID: | 274 | case -NFS4ERR_STALE_CLIENTID: |
272 | case -NFS4ERR_EXPIRED: | ||
273 | nfs4_schedule_lease_recovery(clp); | 275 | nfs4_schedule_lease_recovery(clp); |
274 | goto wait_on_recovery; | 276 | goto wait_on_recovery; |
275 | #if defined(CONFIG_NFS_V4_1) | 277 | #if defined(CONFIG_NFS_V4_1) |
@@ -2361,6 +2363,9 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr, | |||
2361 | struct nfs4_state *state = NULL; | 2363 | struct nfs4_state *state = NULL; |
2362 | int status; | 2364 | int status; |
2363 | 2365 | ||
2366 | if (pnfs_ld_layoutret_on_setattr(inode)) | ||
2367 | pnfs_return_layout(inode); | ||
2368 | |||
2364 | nfs_fattr_init(fattr); | 2369 | nfs_fattr_init(fattr); |
2365 | 2370 | ||
2366 | /* Search for an existing open(O_WRITE) file */ | 2371 | /* Search for an existing open(O_WRITE) file */ |
@@ -3175,6 +3180,11 @@ static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle, | |||
3175 | return err; | 3180 | return err; |
3176 | } | 3181 | } |
3177 | 3182 | ||
3183 | void __nfs4_read_done_cb(struct nfs_read_data *data) | ||
3184 | { | ||
3185 | nfs_invalidate_atime(data->inode); | ||
3186 | } | ||
3187 | |||
3178 | static int nfs4_read_done_cb(struct rpc_task *task, struct nfs_read_data *data) | 3188 | static int nfs4_read_done_cb(struct rpc_task *task, struct nfs_read_data *data) |
3179 | { | 3189 | { |
3180 | struct nfs_server *server = NFS_SERVER(data->inode); | 3190 | struct nfs_server *server = NFS_SERVER(data->inode); |
@@ -3184,7 +3194,7 @@ static int nfs4_read_done_cb(struct rpc_task *task, struct nfs_read_data *data) | |||
3184 | return -EAGAIN; | 3194 | return -EAGAIN; |
3185 | } | 3195 | } |
3186 | 3196 | ||
3187 | nfs_invalidate_atime(data->inode); | 3197 | __nfs4_read_done_cb(data); |
3188 | if (task->tk_status > 0) | 3198 | if (task->tk_status > 0) |
3189 | renew_lease(server, data->timestamp); | 3199 | renew_lease(server, data->timestamp); |
3190 | return 0; | 3200 | return 0; |
@@ -3198,7 +3208,8 @@ static int nfs4_read_done(struct rpc_task *task, struct nfs_read_data *data) | |||
3198 | if (!nfs4_sequence_done(task, &data->res.seq_res)) | 3208 | if (!nfs4_sequence_done(task, &data->res.seq_res)) |
3199 | return -EAGAIN; | 3209 | return -EAGAIN; |
3200 | 3210 | ||
3201 | return data->read_done_cb(task, data); | 3211 | return data->read_done_cb ? data->read_done_cb(task, data) : |
3212 | nfs4_read_done_cb(task, data); | ||
3202 | } | 3213 | } |
3203 | 3214 | ||
3204 | static void nfs4_proc_read_setup(struct nfs_read_data *data, struct rpc_message *msg) | 3215 | static void nfs4_proc_read_setup(struct nfs_read_data *data, struct rpc_message *msg) |
@@ -3243,7 +3254,8 @@ static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data) | |||
3243 | { | 3254 | { |
3244 | if (!nfs4_sequence_done(task, &data->res.seq_res)) | 3255 | if (!nfs4_sequence_done(task, &data->res.seq_res)) |
3245 | return -EAGAIN; | 3256 | return -EAGAIN; |
3246 | return data->write_done_cb(task, data); | 3257 | return data->write_done_cb ? data->write_done_cb(task, data) : |
3258 | nfs4_write_done_cb(task, data); | ||
3247 | } | 3259 | } |
3248 | 3260 | ||
3249 | /* Reset the the nfs_write_data to send the write to the MDS. */ | 3261 | /* Reset the the nfs_write_data to send the write to the MDS. */ |
@@ -3670,9 +3682,11 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, | |||
3670 | break; | 3682 | break; |
3671 | nfs4_schedule_stateid_recovery(server, state); | 3683 | nfs4_schedule_stateid_recovery(server, state); |
3672 | goto wait_on_recovery; | 3684 | goto wait_on_recovery; |
3685 | case -NFS4ERR_EXPIRED: | ||
3686 | if (state != NULL) | ||
3687 | nfs4_schedule_stateid_recovery(server, state); | ||
3673 | case -NFS4ERR_STALE_STATEID: | 3688 | case -NFS4ERR_STALE_STATEID: |
3674 | case -NFS4ERR_STALE_CLIENTID: | 3689 | case -NFS4ERR_STALE_CLIENTID: |
3675 | case -NFS4ERR_EXPIRED: | ||
3676 | nfs4_schedule_lease_recovery(clp); | 3690 | nfs4_schedule_lease_recovery(clp); |
3677 | goto wait_on_recovery; | 3691 | goto wait_on_recovery; |
3678 | #if defined(CONFIG_NFS_V4_1) | 3692 | #if defined(CONFIG_NFS_V4_1) |
@@ -4543,6 +4557,7 @@ int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl) | |||
4543 | case -ESTALE: | 4557 | case -ESTALE: |
4544 | goto out; | 4558 | goto out; |
4545 | case -NFS4ERR_EXPIRED: | 4559 | case -NFS4ERR_EXPIRED: |
4560 | nfs4_schedule_stateid_recovery(server, state); | ||
4546 | case -NFS4ERR_STALE_CLIENTID: | 4561 | case -NFS4ERR_STALE_CLIENTID: |
4547 | case -NFS4ERR_STALE_STATEID: | 4562 | case -NFS4ERR_STALE_STATEID: |
4548 | nfs4_schedule_lease_recovery(server->nfs_client); | 4563 | nfs4_schedule_lease_recovery(server->nfs_client); |
@@ -5666,6 +5681,88 @@ int nfs4_proc_layoutget(struct nfs4_layoutget *lgp) | |||
5666 | return status; | 5681 | return status; |
5667 | } | 5682 | } |
5668 | 5683 | ||
5684 | static void | ||
5685 | nfs4_layoutreturn_prepare(struct rpc_task *task, void *calldata) | ||
5686 | { | ||
5687 | struct nfs4_layoutreturn *lrp = calldata; | ||
5688 | |||
5689 | dprintk("--> %s\n", __func__); | ||
5690 | if (nfs41_setup_sequence(lrp->clp->cl_session, &lrp->args.seq_args, | ||
5691 | &lrp->res.seq_res, 0, task)) | ||
5692 | return; | ||
5693 | rpc_call_start(task); | ||
5694 | } | ||
5695 | |||
5696 | static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata) | ||
5697 | { | ||
5698 | struct nfs4_layoutreturn *lrp = calldata; | ||
5699 | struct nfs_server *server; | ||
5700 | |||
5701 | dprintk("--> %s\n", __func__); | ||
5702 | |||
5703 | if (!nfs4_sequence_done(task, &lrp->res.seq_res)) | ||
5704 | return; | ||
5705 | |||
5706 | server = NFS_SERVER(lrp->args.inode); | ||
5707 | if (nfs4_async_handle_error(task, server, NULL) == -EAGAIN) { | ||
5708 | nfs_restart_rpc(task, lrp->clp); | ||
5709 | return; | ||
5710 | } | ||
5711 | if (task->tk_status == 0) { | ||
5712 | struct pnfs_layout_hdr *lo = NFS_I(lrp->args.inode)->layout; | ||
5713 | |||
5714 | if (lrp->res.lrs_present) { | ||
5715 | spin_lock(&lo->plh_inode->i_lock); | ||
5716 | pnfs_set_layout_stateid(lo, &lrp->res.stateid, true); | ||
5717 | spin_unlock(&lo->plh_inode->i_lock); | ||
5718 | } else | ||
5719 | BUG_ON(!list_empty(&lo->plh_segs)); | ||
5720 | } | ||
5721 | dprintk("<-- %s\n", __func__); | ||
5722 | } | ||
5723 | |||
5724 | static void nfs4_layoutreturn_release(void *calldata) | ||
5725 | { | ||
5726 | struct nfs4_layoutreturn *lrp = calldata; | ||
5727 | |||
5728 | dprintk("--> %s\n", __func__); | ||
5729 | put_layout_hdr(NFS_I(lrp->args.inode)->layout); | ||
5730 | kfree(calldata); | ||
5731 | dprintk("<-- %s\n", __func__); | ||
5732 | } | ||
5733 | |||
5734 | static const struct rpc_call_ops nfs4_layoutreturn_call_ops = { | ||
5735 | .rpc_call_prepare = nfs4_layoutreturn_prepare, | ||
5736 | .rpc_call_done = nfs4_layoutreturn_done, | ||
5737 | .rpc_release = nfs4_layoutreturn_release, | ||
5738 | }; | ||
5739 | |||
5740 | int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp) | ||
5741 | { | ||
5742 | struct rpc_task *task; | ||
5743 | struct rpc_message msg = { | ||
5744 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LAYOUTRETURN], | ||
5745 | .rpc_argp = &lrp->args, | ||
5746 | .rpc_resp = &lrp->res, | ||
5747 | }; | ||
5748 | struct rpc_task_setup task_setup_data = { | ||
5749 | .rpc_client = lrp->clp->cl_rpcclient, | ||
5750 | .rpc_message = &msg, | ||
5751 | .callback_ops = &nfs4_layoutreturn_call_ops, | ||
5752 | .callback_data = lrp, | ||
5753 | }; | ||
5754 | int status; | ||
5755 | |||
5756 | dprintk("--> %s\n", __func__); | ||
5757 | task = rpc_run_task(&task_setup_data); | ||
5758 | if (IS_ERR(task)) | ||
5759 | return PTR_ERR(task); | ||
5760 | status = task->tk_status; | ||
5761 | dprintk("<-- %s status=%d\n", __func__, status); | ||
5762 | rpc_put_task(task); | ||
5763 | return status; | ||
5764 | } | ||
5765 | |||
5669 | static int | 5766 | static int |
5670 | _nfs4_proc_getdeviceinfo(struct nfs_server *server, struct pnfs_device *pdev) | 5767 | _nfs4_proc_getdeviceinfo(struct nfs_server *server, struct pnfs_device *pdev) |
5671 | { | 5768 | { |
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 036f5adc9e1f..e97dd219f84f 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -1466,7 +1466,10 @@ static int nfs4_reclaim_lease(struct nfs_client *clp) | |||
1466 | #ifdef CONFIG_NFS_V4_1 | 1466 | #ifdef CONFIG_NFS_V4_1 |
1467 | void nfs4_schedule_session_recovery(struct nfs4_session *session) | 1467 | void nfs4_schedule_session_recovery(struct nfs4_session *session) |
1468 | { | 1468 | { |
1469 | nfs4_schedule_lease_recovery(session->clp); | 1469 | struct nfs_client *clp = session->clp; |
1470 | |||
1471 | set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state); | ||
1472 | nfs4_schedule_lease_recovery(clp); | ||
1470 | } | 1473 | } |
1471 | EXPORT_SYMBOL_GPL(nfs4_schedule_session_recovery); | 1474 | EXPORT_SYMBOL_GPL(nfs4_schedule_session_recovery); |
1472 | 1475 | ||
@@ -1549,6 +1552,7 @@ static int nfs4_reset_session(struct nfs_client *clp) | |||
1549 | status = nfs4_recovery_handle_error(clp, status); | 1552 | status = nfs4_recovery_handle_error(clp, status); |
1550 | goto out; | 1553 | goto out; |
1551 | } | 1554 | } |
1555 | clear_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state); | ||
1552 | /* create_session negotiated new slot table */ | 1556 | /* create_session negotiated new slot table */ |
1553 | clear_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state); | 1557 | clear_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state); |
1554 | 1558 | ||
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index c3ccd2c46834..d869a5e5464b 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -338,7 +338,11 @@ static int nfs4_stat_to_errno(int); | |||
338 | 1 /* layoutupdate4 layout type */ + \ | 338 | 1 /* layoutupdate4 layout type */ + \ |
339 | 1 /* NULL filelayout layoutupdate4 payload */) | 339 | 1 /* NULL filelayout layoutupdate4 payload */) |
340 | #define decode_layoutcommit_maxsz (op_decode_hdr_maxsz + 3) | 340 | #define decode_layoutcommit_maxsz (op_decode_hdr_maxsz + 3) |
341 | 341 | #define encode_layoutreturn_maxsz (8 + op_encode_hdr_maxsz + \ | |
342 | encode_stateid_maxsz + \ | ||
343 | 1 /* FIXME: opaque lrf_body always empty at the moment */) | ||
344 | #define decode_layoutreturn_maxsz (op_decode_hdr_maxsz + \ | ||
345 | 1 + decode_stateid_maxsz) | ||
342 | #else /* CONFIG_NFS_V4_1 */ | 346 | #else /* CONFIG_NFS_V4_1 */ |
343 | #define encode_sequence_maxsz 0 | 347 | #define encode_sequence_maxsz 0 |
344 | #define decode_sequence_maxsz 0 | 348 | #define decode_sequence_maxsz 0 |
@@ -760,7 +764,14 @@ static int nfs4_stat_to_errno(int); | |||
760 | decode_putfh_maxsz + \ | 764 | decode_putfh_maxsz + \ |
761 | decode_layoutcommit_maxsz + \ | 765 | decode_layoutcommit_maxsz + \ |
762 | decode_getattr_maxsz) | 766 | decode_getattr_maxsz) |
763 | 767 | #define NFS4_enc_layoutreturn_sz (compound_encode_hdr_maxsz + \ | |
768 | encode_sequence_maxsz + \ | ||
769 | encode_putfh_maxsz + \ | ||
770 | encode_layoutreturn_maxsz) | ||
771 | #define NFS4_dec_layoutreturn_sz (compound_decode_hdr_maxsz + \ | ||
772 | decode_sequence_maxsz + \ | ||
773 | decode_putfh_maxsz + \ | ||
774 | decode_layoutreturn_maxsz) | ||
764 | 775 | ||
765 | const u32 nfs41_maxwrite_overhead = ((RPC_MAX_HEADER_WITH_AUTH + | 776 | const u32 nfs41_maxwrite_overhead = ((RPC_MAX_HEADER_WITH_AUTH + |
766 | compound_encode_hdr_maxsz + | 777 | compound_encode_hdr_maxsz + |
@@ -1864,6 +1875,7 @@ encode_layoutget(struct xdr_stream *xdr, | |||
1864 | 1875 | ||
1865 | static int | 1876 | static int |
1866 | encode_layoutcommit(struct xdr_stream *xdr, | 1877 | encode_layoutcommit(struct xdr_stream *xdr, |
1878 | struct inode *inode, | ||
1867 | const struct nfs4_layoutcommit_args *args, | 1879 | const struct nfs4_layoutcommit_args *args, |
1868 | struct compound_hdr *hdr) | 1880 | struct compound_hdr *hdr) |
1869 | { | 1881 | { |
@@ -1872,7 +1884,7 @@ encode_layoutcommit(struct xdr_stream *xdr, | |||
1872 | dprintk("%s: lbw: %llu type: %d\n", __func__, args->lastbytewritten, | 1884 | dprintk("%s: lbw: %llu type: %d\n", __func__, args->lastbytewritten, |
1873 | NFS_SERVER(args->inode)->pnfs_curr_ld->id); | 1885 | NFS_SERVER(args->inode)->pnfs_curr_ld->id); |
1874 | 1886 | ||
1875 | p = reserve_space(xdr, 48 + NFS4_STATEID_SIZE); | 1887 | p = reserve_space(xdr, 44 + NFS4_STATEID_SIZE); |
1876 | *p++ = cpu_to_be32(OP_LAYOUTCOMMIT); | 1888 | *p++ = cpu_to_be32(OP_LAYOUTCOMMIT); |
1877 | /* Only whole file layouts */ | 1889 | /* Only whole file layouts */ |
1878 | p = xdr_encode_hyper(p, 0); /* offset */ | 1890 | p = xdr_encode_hyper(p, 0); /* offset */ |
@@ -1883,12 +1895,49 @@ encode_layoutcommit(struct xdr_stream *xdr, | |||
1883 | p = xdr_encode_hyper(p, args->lastbytewritten); | 1895 | p = xdr_encode_hyper(p, args->lastbytewritten); |
1884 | *p++ = cpu_to_be32(0); /* Never send time_modify_changed */ | 1896 | *p++ = cpu_to_be32(0); /* Never send time_modify_changed */ |
1885 | *p++ = cpu_to_be32(NFS_SERVER(args->inode)->pnfs_curr_ld->id);/* type */ | 1897 | *p++ = cpu_to_be32(NFS_SERVER(args->inode)->pnfs_curr_ld->id);/* type */ |
1886 | *p++ = cpu_to_be32(0); /* no file layout payload */ | 1898 | |
1899 | if (NFS_SERVER(inode)->pnfs_curr_ld->encode_layoutcommit) | ||
1900 | NFS_SERVER(inode)->pnfs_curr_ld->encode_layoutcommit( | ||
1901 | NFS_I(inode)->layout, xdr, args); | ||
1902 | else { | ||
1903 | p = reserve_space(xdr, 4); | ||
1904 | *p = cpu_to_be32(0); /* no layout-type payload */ | ||
1905 | } | ||
1887 | 1906 | ||
1888 | hdr->nops++; | 1907 | hdr->nops++; |
1889 | hdr->replen += decode_layoutcommit_maxsz; | 1908 | hdr->replen += decode_layoutcommit_maxsz; |
1890 | return 0; | 1909 | return 0; |
1891 | } | 1910 | } |
1911 | |||
1912 | static void | ||
1913 | encode_layoutreturn(struct xdr_stream *xdr, | ||
1914 | const struct nfs4_layoutreturn_args *args, | ||
1915 | struct compound_hdr *hdr) | ||
1916 | { | ||
1917 | __be32 *p; | ||
1918 | |||
1919 | p = reserve_space(xdr, 20); | ||
1920 | *p++ = cpu_to_be32(OP_LAYOUTRETURN); | ||
1921 | *p++ = cpu_to_be32(0); /* reclaim. always 0 for now */ | ||
1922 | *p++ = cpu_to_be32(args->layout_type); | ||
1923 | *p++ = cpu_to_be32(IOMODE_ANY); | ||
1924 | *p = cpu_to_be32(RETURN_FILE); | ||
1925 | p = reserve_space(xdr, 16 + NFS4_STATEID_SIZE); | ||
1926 | p = xdr_encode_hyper(p, 0); | ||
1927 | p = xdr_encode_hyper(p, NFS4_MAX_UINT64); | ||
1928 | spin_lock(&args->inode->i_lock); | ||
1929 | xdr_encode_opaque_fixed(p, &args->stateid.data, NFS4_STATEID_SIZE); | ||
1930 | spin_unlock(&args->inode->i_lock); | ||
1931 | if (NFS_SERVER(args->inode)->pnfs_curr_ld->encode_layoutreturn) { | ||
1932 | NFS_SERVER(args->inode)->pnfs_curr_ld->encode_layoutreturn( | ||
1933 | NFS_I(args->inode)->layout, xdr, args); | ||
1934 | } else { | ||
1935 | p = reserve_space(xdr, 4); | ||
1936 | *p = cpu_to_be32(0); | ||
1937 | } | ||
1938 | hdr->nops++; | ||
1939 | hdr->replen += decode_layoutreturn_maxsz; | ||
1940 | } | ||
1892 | #endif /* CONFIG_NFS_V4_1 */ | 1941 | #endif /* CONFIG_NFS_V4_1 */ |
1893 | 1942 | ||
1894 | /* | 1943 | /* |
@@ -2706,10 +2755,12 @@ static void nfs4_xdr_enc_layoutget(struct rpc_rqst *req, | |||
2706 | /* | 2755 | /* |
2707 | * Encode LAYOUTCOMMIT request | 2756 | * Encode LAYOUTCOMMIT request |
2708 | */ | 2757 | */ |
2709 | static int nfs4_xdr_enc_layoutcommit(struct rpc_rqst *req, | 2758 | static void nfs4_xdr_enc_layoutcommit(struct rpc_rqst *req, |
2710 | struct xdr_stream *xdr, | 2759 | struct xdr_stream *xdr, |
2711 | struct nfs4_layoutcommit_args *args) | 2760 | struct nfs4_layoutcommit_args *args) |
2712 | { | 2761 | { |
2762 | struct nfs4_layoutcommit_data *data = | ||
2763 | container_of(args, struct nfs4_layoutcommit_data, args); | ||
2713 | struct compound_hdr hdr = { | 2764 | struct compound_hdr hdr = { |
2714 | .minorversion = nfs4_xdr_minorversion(&args->seq_args), | 2765 | .minorversion = nfs4_xdr_minorversion(&args->seq_args), |
2715 | }; | 2766 | }; |
@@ -2717,10 +2768,27 @@ static int nfs4_xdr_enc_layoutcommit(struct rpc_rqst *req, | |||
2717 | encode_compound_hdr(xdr, req, &hdr); | 2768 | encode_compound_hdr(xdr, req, &hdr); |
2718 | encode_sequence(xdr, &args->seq_args, &hdr); | 2769 | encode_sequence(xdr, &args->seq_args, &hdr); |
2719 | encode_putfh(xdr, NFS_FH(args->inode), &hdr); | 2770 | encode_putfh(xdr, NFS_FH(args->inode), &hdr); |
2720 | encode_layoutcommit(xdr, args, &hdr); | 2771 | encode_layoutcommit(xdr, data->args.inode, args, &hdr); |
2721 | encode_getfattr(xdr, args->bitmask, &hdr); | 2772 | encode_getfattr(xdr, args->bitmask, &hdr); |
2722 | encode_nops(&hdr); | 2773 | encode_nops(&hdr); |
2723 | return 0; | 2774 | } |
2775 | |||
2776 | /* | ||
2777 | * Encode LAYOUTRETURN request | ||
2778 | */ | ||
2779 | static void nfs4_xdr_enc_layoutreturn(struct rpc_rqst *req, | ||
2780 | struct xdr_stream *xdr, | ||
2781 | struct nfs4_layoutreturn_args *args) | ||
2782 | { | ||
2783 | struct compound_hdr hdr = { | ||
2784 | .minorversion = nfs4_xdr_minorversion(&args->seq_args), | ||
2785 | }; | ||
2786 | |||
2787 | encode_compound_hdr(xdr, req, &hdr); | ||
2788 | encode_sequence(xdr, &args->seq_args, &hdr); | ||
2789 | encode_putfh(xdr, NFS_FH(args->inode), &hdr); | ||
2790 | encode_layoutreturn(xdr, args, &hdr); | ||
2791 | encode_nops(&hdr); | ||
2724 | } | 2792 | } |
2725 | #endif /* CONFIG_NFS_V4_1 */ | 2793 | #endif /* CONFIG_NFS_V4_1 */ |
2726 | 2794 | ||
@@ -5203,6 +5271,27 @@ out_overflow: | |||
5203 | return -EIO; | 5271 | return -EIO; |
5204 | } | 5272 | } |
5205 | 5273 | ||
5274 | static int decode_layoutreturn(struct xdr_stream *xdr, | ||
5275 | struct nfs4_layoutreturn_res *res) | ||
5276 | { | ||
5277 | __be32 *p; | ||
5278 | int status; | ||
5279 | |||
5280 | status = decode_op_hdr(xdr, OP_LAYOUTRETURN); | ||
5281 | if (status) | ||
5282 | return status; | ||
5283 | p = xdr_inline_decode(xdr, 4); | ||
5284 | if (unlikely(!p)) | ||
5285 | goto out_overflow; | ||
5286 | res->lrs_present = be32_to_cpup(p); | ||
5287 | if (res->lrs_present) | ||
5288 | status = decode_stateid(xdr, &res->stateid); | ||
5289 | return status; | ||
5290 | out_overflow: | ||
5291 | print_overflow_msg(__func__, xdr); | ||
5292 | return -EIO; | ||
5293 | } | ||
5294 | |||
5206 | static int decode_layoutcommit(struct xdr_stream *xdr, | 5295 | static int decode_layoutcommit(struct xdr_stream *xdr, |
5207 | struct rpc_rqst *req, | 5296 | struct rpc_rqst *req, |
5208 | struct nfs4_layoutcommit_res *res) | 5297 | struct nfs4_layoutcommit_res *res) |
@@ -6320,6 +6409,30 @@ out: | |||
6320 | } | 6409 | } |
6321 | 6410 | ||
6322 | /* | 6411 | /* |
6412 | * Decode LAYOUTRETURN response | ||
6413 | */ | ||
6414 | static int nfs4_xdr_dec_layoutreturn(struct rpc_rqst *rqstp, | ||
6415 | struct xdr_stream *xdr, | ||
6416 | struct nfs4_layoutreturn_res *res) | ||
6417 | { | ||
6418 | struct compound_hdr hdr; | ||
6419 | int status; | ||
6420 | |||
6421 | status = decode_compound_hdr(xdr, &hdr); | ||
6422 | if (status) | ||
6423 | goto out; | ||
6424 | status = decode_sequence(xdr, &res->seq_res, rqstp); | ||
6425 | if (status) | ||
6426 | goto out; | ||
6427 | status = decode_putfh(xdr); | ||
6428 | if (status) | ||
6429 | goto out; | ||
6430 | status = decode_layoutreturn(xdr, res); | ||
6431 | out: | ||
6432 | return status; | ||
6433 | } | ||
6434 | |||
6435 | /* | ||
6323 | * Decode LAYOUTCOMMIT response | 6436 | * Decode LAYOUTCOMMIT response |
6324 | */ | 6437 | */ |
6325 | static int nfs4_xdr_dec_layoutcommit(struct rpc_rqst *rqstp, | 6438 | static int nfs4_xdr_dec_layoutcommit(struct rpc_rqst *rqstp, |
@@ -6547,6 +6660,7 @@ struct rpc_procinfo nfs4_procedures[] = { | |||
6547 | PROC(GETDEVICEINFO, enc_getdeviceinfo, dec_getdeviceinfo), | 6660 | PROC(GETDEVICEINFO, enc_getdeviceinfo, dec_getdeviceinfo), |
6548 | PROC(LAYOUTGET, enc_layoutget, dec_layoutget), | 6661 | PROC(LAYOUTGET, enc_layoutget, dec_layoutget), |
6549 | PROC(LAYOUTCOMMIT, enc_layoutcommit, dec_layoutcommit), | 6662 | PROC(LAYOUTCOMMIT, enc_layoutcommit, dec_layoutcommit), |
6663 | PROC(LAYOUTRETURN, enc_layoutreturn, dec_layoutreturn), | ||
6550 | #endif /* CONFIG_NFS_V4_1 */ | 6664 | #endif /* CONFIG_NFS_V4_1 */ |
6551 | }; | 6665 | }; |
6552 | 6666 | ||
diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c index c541093a5bf2..c4744e1d513c 100644 --- a/fs/nfs/nfsroot.c +++ b/fs/nfs/nfsroot.c | |||
@@ -87,7 +87,7 @@ | |||
87 | #define NFS_ROOT "/tftpboot/%s" | 87 | #define NFS_ROOT "/tftpboot/%s" |
88 | 88 | ||
89 | /* Default NFSROOT mount options. */ | 89 | /* Default NFSROOT mount options. */ |
90 | #define NFS_DEF_OPTIONS "udp" | 90 | #define NFS_DEF_OPTIONS "vers=2,udp,rsize=4096,wsize=4096" |
91 | 91 | ||
92 | /* Parameters passed from the kernel command line */ | 92 | /* Parameters passed from the kernel command line */ |
93 | static char nfs_root_parms[256] __initdata = ""; | 93 | static char nfs_root_parms[256] __initdata = ""; |
diff --git a/fs/nfs/objlayout/Kbuild b/fs/nfs/objlayout/Kbuild new file mode 100644 index 000000000000..ed30ea072bb8 --- /dev/null +++ b/fs/nfs/objlayout/Kbuild | |||
@@ -0,0 +1,5 @@ | |||
1 | # | ||
2 | # Makefile for the pNFS Objects Layout Driver kernel module | ||
3 | # | ||
4 | objlayoutdriver-y := objio_osd.o pnfs_osd_xdr_cli.o objlayout.o | ||
5 | obj-$(CONFIG_PNFS_OBJLAYOUT) += objlayoutdriver.o | ||
diff --git a/fs/nfs/objlayout/objio_osd.c b/fs/nfs/objlayout/objio_osd.c new file mode 100644 index 000000000000..9cf208df1f25 --- /dev/null +++ b/fs/nfs/objlayout/objio_osd.c | |||
@@ -0,0 +1,1057 @@ | |||
1 | /* | ||
2 | * pNFS Objects layout implementation over open-osd initiator library | ||
3 | * | ||
4 | * Copyright (C) 2009 Panasas Inc. [year of first publication] | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Benny Halevy <bhalevy@panasas.com> | ||
8 | * Boaz Harrosh <bharrosh@panasas.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 | ||
12 | * See the file COPYING included with this distribution for more details. | ||
13 | * | ||
14 | * Redistribution and use in source and binary forms, with or without | ||
15 | * modification, are permitted provided that the following conditions | ||
16 | * are met: | ||
17 | * | ||
18 | * 1. Redistributions of source code must retain the above copyright | ||
19 | * notice, this list of conditions and the following disclaimer. | ||
20 | * 2. Redistributions in binary form must reproduce the above copyright | ||
21 | * notice, this list of conditions and the following disclaimer in the | ||
22 | * documentation and/or other materials provided with the distribution. | ||
23 | * 3. Neither the name of the Panasas company nor the names of its | ||
24 | * contributors may be used to endorse or promote products derived | ||
25 | * from this software without specific prior written permission. | ||
26 | * | ||
27 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
28 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
29 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
30 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
31 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
32 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
33 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
34 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
35 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
36 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
37 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
38 | */ | ||
39 | |||
40 | #include <linux/module.h> | ||
41 | #include <scsi/osd_initiator.h> | ||
42 | |||
43 | #include "objlayout.h" | ||
44 | |||
45 | #define NFSDBG_FACILITY NFSDBG_PNFS_LD | ||
46 | |||
47 | #define _LLU(x) ((unsigned long long)x) | ||
48 | |||
49 | enum { BIO_MAX_PAGES_KMALLOC = | ||
50 | (PAGE_SIZE - sizeof(struct bio)) / sizeof(struct bio_vec), | ||
51 | }; | ||
52 | |||
53 | struct objio_dev_ent { | ||
54 | struct nfs4_deviceid_node id_node; | ||
55 | struct osd_dev *od; | ||
56 | }; | ||
57 | |||
58 | static void | ||
59 | objio_free_deviceid_node(struct nfs4_deviceid_node *d) | ||
60 | { | ||
61 | struct objio_dev_ent *de = container_of(d, struct objio_dev_ent, id_node); | ||
62 | |||
63 | dprintk("%s: free od=%p\n", __func__, de->od); | ||
64 | osduld_put_device(de->od); | ||
65 | kfree(de); | ||
66 | } | ||
67 | |||
68 | static struct objio_dev_ent *_dev_list_find(const struct nfs_server *nfss, | ||
69 | const struct nfs4_deviceid *d_id) | ||
70 | { | ||
71 | struct nfs4_deviceid_node *d; | ||
72 | struct objio_dev_ent *de; | ||
73 | |||
74 | d = nfs4_find_get_deviceid(nfss->pnfs_curr_ld, nfss->nfs_client, d_id); | ||
75 | if (!d) | ||
76 | return NULL; | ||
77 | |||
78 | de = container_of(d, struct objio_dev_ent, id_node); | ||
79 | return de; | ||
80 | } | ||
81 | |||
82 | static struct objio_dev_ent * | ||
83 | _dev_list_add(const struct nfs_server *nfss, | ||
84 | const struct nfs4_deviceid *d_id, struct osd_dev *od, | ||
85 | gfp_t gfp_flags) | ||
86 | { | ||
87 | struct nfs4_deviceid_node *d; | ||
88 | struct objio_dev_ent *de = kzalloc(sizeof(*de), gfp_flags); | ||
89 | struct objio_dev_ent *n; | ||
90 | |||
91 | if (!de) { | ||
92 | dprintk("%s: -ENOMEM od=%p\n", __func__, od); | ||
93 | return NULL; | ||
94 | } | ||
95 | |||
96 | dprintk("%s: Adding od=%p\n", __func__, od); | ||
97 | nfs4_init_deviceid_node(&de->id_node, | ||
98 | nfss->pnfs_curr_ld, | ||
99 | nfss->nfs_client, | ||
100 | d_id); | ||
101 | de->od = od; | ||
102 | |||
103 | d = nfs4_insert_deviceid_node(&de->id_node); | ||
104 | n = container_of(d, struct objio_dev_ent, id_node); | ||
105 | if (n != de) { | ||
106 | dprintk("%s: Race with other n->od=%p\n", __func__, n->od); | ||
107 | objio_free_deviceid_node(&de->id_node); | ||
108 | de = n; | ||
109 | } | ||
110 | |||
111 | atomic_inc(&de->id_node.ref); | ||
112 | return de; | ||
113 | } | ||
114 | |||
115 | struct caps_buffers { | ||
116 | u8 caps_key[OSD_CRYPTO_KEYID_SIZE]; | ||
117 | u8 creds[OSD_CAP_LEN]; | ||
118 | }; | ||
119 | |||
120 | struct objio_segment { | ||
121 | struct pnfs_layout_segment lseg; | ||
122 | |||
123 | struct pnfs_osd_object_cred *comps; | ||
124 | |||
125 | unsigned mirrors_p1; | ||
126 | unsigned stripe_unit; | ||
127 | unsigned group_width; /* Data stripe_units without integrity comps */ | ||
128 | u64 group_depth; | ||
129 | unsigned group_count; | ||
130 | |||
131 | unsigned max_io_size; | ||
132 | |||
133 | unsigned comps_index; | ||
134 | unsigned num_comps; | ||
135 | /* variable length */ | ||
136 | struct objio_dev_ent *ods[]; | ||
137 | }; | ||
138 | |||
139 | static inline struct objio_segment * | ||
140 | OBJIO_LSEG(struct pnfs_layout_segment *lseg) | ||
141 | { | ||
142 | return container_of(lseg, struct objio_segment, lseg); | ||
143 | } | ||
144 | |||
145 | struct objio_state; | ||
146 | typedef ssize_t (*objio_done_fn)(struct objio_state *ios); | ||
147 | |||
148 | struct objio_state { | ||
149 | /* Generic layer */ | ||
150 | struct objlayout_io_state ol_state; | ||
151 | |||
152 | struct objio_segment *layout; | ||
153 | |||
154 | struct kref kref; | ||
155 | objio_done_fn done; | ||
156 | void *private; | ||
157 | |||
158 | unsigned long length; | ||
159 | unsigned numdevs; /* Actually used devs in this IO */ | ||
160 | /* A per-device variable array of size numdevs */ | ||
161 | struct _objio_per_comp { | ||
162 | struct bio *bio; | ||
163 | struct osd_request *or; | ||
164 | unsigned long length; | ||
165 | u64 offset; | ||
166 | unsigned dev; | ||
167 | } per_dev[]; | ||
168 | }; | ||
169 | |||
170 | /* Send and wait for a get_device_info of devices in the layout, | ||
171 | then look them up with the osd_initiator library */ | ||
172 | static struct objio_dev_ent *_device_lookup(struct pnfs_layout_hdr *pnfslay, | ||
173 | struct objio_segment *objio_seg, unsigned comp, | ||
174 | gfp_t gfp_flags) | ||
175 | { | ||
176 | struct pnfs_osd_deviceaddr *deviceaddr; | ||
177 | struct nfs4_deviceid *d_id; | ||
178 | struct objio_dev_ent *ode; | ||
179 | struct osd_dev *od; | ||
180 | struct osd_dev_info odi; | ||
181 | int err; | ||
182 | |||
183 | d_id = &objio_seg->comps[comp].oc_object_id.oid_device_id; | ||
184 | |||
185 | ode = _dev_list_find(NFS_SERVER(pnfslay->plh_inode), d_id); | ||
186 | if (ode) | ||
187 | return ode; | ||
188 | |||
189 | err = objlayout_get_deviceinfo(pnfslay, d_id, &deviceaddr, gfp_flags); | ||
190 | if (unlikely(err)) { | ||
191 | dprintk("%s: objlayout_get_deviceinfo dev(%llx:%llx) =>%d\n", | ||
192 | __func__, _DEVID_LO(d_id), _DEVID_HI(d_id), err); | ||
193 | return ERR_PTR(err); | ||
194 | } | ||
195 | |||
196 | odi.systemid_len = deviceaddr->oda_systemid.len; | ||
197 | if (odi.systemid_len > sizeof(odi.systemid)) { | ||
198 | err = -EINVAL; | ||
199 | goto out; | ||
200 | } else if (odi.systemid_len) | ||
201 | memcpy(odi.systemid, deviceaddr->oda_systemid.data, | ||
202 | odi.systemid_len); | ||
203 | odi.osdname_len = deviceaddr->oda_osdname.len; | ||
204 | odi.osdname = (u8 *)deviceaddr->oda_osdname.data; | ||
205 | |||
206 | if (!odi.osdname_len && !odi.systemid_len) { | ||
207 | dprintk("%s: !odi.osdname_len && !odi.systemid_len\n", | ||
208 | __func__); | ||
209 | err = -ENODEV; | ||
210 | goto out; | ||
211 | } | ||
212 | |||
213 | od = osduld_info_lookup(&odi); | ||
214 | if (unlikely(IS_ERR(od))) { | ||
215 | err = PTR_ERR(od); | ||
216 | dprintk("%s: osduld_info_lookup => %d\n", __func__, err); | ||
217 | goto out; | ||
218 | } | ||
219 | |||
220 | ode = _dev_list_add(NFS_SERVER(pnfslay->plh_inode), d_id, od, | ||
221 | gfp_flags); | ||
222 | |||
223 | out: | ||
224 | dprintk("%s: return=%d\n", __func__, err); | ||
225 | objlayout_put_deviceinfo(deviceaddr); | ||
226 | return err ? ERR_PTR(err) : ode; | ||
227 | } | ||
228 | |||
229 | static int objio_devices_lookup(struct pnfs_layout_hdr *pnfslay, | ||
230 | struct objio_segment *objio_seg, | ||
231 | gfp_t gfp_flags) | ||
232 | { | ||
233 | unsigned i; | ||
234 | int err; | ||
235 | |||
236 | /* lookup all devices */ | ||
237 | for (i = 0; i < objio_seg->num_comps; i++) { | ||
238 | struct objio_dev_ent *ode; | ||
239 | |||
240 | ode = _device_lookup(pnfslay, objio_seg, i, gfp_flags); | ||
241 | if (unlikely(IS_ERR(ode))) { | ||
242 | err = PTR_ERR(ode); | ||
243 | goto out; | ||
244 | } | ||
245 | objio_seg->ods[i] = ode; | ||
246 | } | ||
247 | err = 0; | ||
248 | |||
249 | out: | ||
250 | dprintk("%s: return=%d\n", __func__, err); | ||
251 | return err; | ||
252 | } | ||
253 | |||
254 | static int _verify_data_map(struct pnfs_osd_layout *layout) | ||
255 | { | ||
256 | struct pnfs_osd_data_map *data_map = &layout->olo_map; | ||
257 | u64 stripe_length; | ||
258 | u32 group_width; | ||
259 | |||
260 | /* FIXME: Only raid0 for now. if not go through MDS */ | ||
261 | if (data_map->odm_raid_algorithm != PNFS_OSD_RAID_0) { | ||
262 | printk(KERN_ERR "Only RAID_0 for now\n"); | ||
263 | return -ENOTSUPP; | ||
264 | } | ||
265 | if (0 != (data_map->odm_num_comps % (data_map->odm_mirror_cnt + 1))) { | ||
266 | printk(KERN_ERR "Data Map wrong, num_comps=%u mirrors=%u\n", | ||
267 | data_map->odm_num_comps, data_map->odm_mirror_cnt); | ||
268 | return -EINVAL; | ||
269 | } | ||
270 | |||
271 | if (data_map->odm_group_width) | ||
272 | group_width = data_map->odm_group_width; | ||
273 | else | ||
274 | group_width = data_map->odm_num_comps / | ||
275 | (data_map->odm_mirror_cnt + 1); | ||
276 | |||
277 | stripe_length = (u64)data_map->odm_stripe_unit * group_width; | ||
278 | if (stripe_length >= (1ULL << 32)) { | ||
279 | printk(KERN_ERR "Total Stripe length(0x%llx)" | ||
280 | " >= 32bit is not supported\n", _LLU(stripe_length)); | ||
281 | return -ENOTSUPP; | ||
282 | } | ||
283 | |||
284 | if (0 != (data_map->odm_stripe_unit & ~PAGE_MASK)) { | ||
285 | printk(KERN_ERR "Stripe Unit(0x%llx)" | ||
286 | " must be Multples of PAGE_SIZE(0x%lx)\n", | ||
287 | _LLU(data_map->odm_stripe_unit), PAGE_SIZE); | ||
288 | return -ENOTSUPP; | ||
289 | } | ||
290 | |||
291 | return 0; | ||
292 | } | ||
293 | |||
294 | static void copy_single_comp(struct pnfs_osd_object_cred *cur_comp, | ||
295 | struct pnfs_osd_object_cred *src_comp, | ||
296 | struct caps_buffers *caps_p) | ||
297 | { | ||
298 | WARN_ON(src_comp->oc_cap_key.cred_len > sizeof(caps_p->caps_key)); | ||
299 | WARN_ON(src_comp->oc_cap.cred_len > sizeof(caps_p->creds)); | ||
300 | |||
301 | *cur_comp = *src_comp; | ||
302 | |||
303 | memcpy(caps_p->caps_key, src_comp->oc_cap_key.cred, | ||
304 | sizeof(caps_p->caps_key)); | ||
305 | cur_comp->oc_cap_key.cred = caps_p->caps_key; | ||
306 | |||
307 | memcpy(caps_p->creds, src_comp->oc_cap.cred, | ||
308 | sizeof(caps_p->creds)); | ||
309 | cur_comp->oc_cap.cred = caps_p->creds; | ||
310 | } | ||
311 | |||
312 | int objio_alloc_lseg(struct pnfs_layout_segment **outp, | ||
313 | struct pnfs_layout_hdr *pnfslay, | ||
314 | struct pnfs_layout_range *range, | ||
315 | struct xdr_stream *xdr, | ||
316 | gfp_t gfp_flags) | ||
317 | { | ||
318 | struct objio_segment *objio_seg; | ||
319 | struct pnfs_osd_xdr_decode_layout_iter iter; | ||
320 | struct pnfs_osd_layout layout; | ||
321 | struct pnfs_osd_object_cred *cur_comp, src_comp; | ||
322 | struct caps_buffers *caps_p; | ||
323 | int err; | ||
324 | |||
325 | err = pnfs_osd_xdr_decode_layout_map(&layout, &iter, xdr); | ||
326 | if (unlikely(err)) | ||
327 | return err; | ||
328 | |||
329 | err = _verify_data_map(&layout); | ||
330 | if (unlikely(err)) | ||
331 | return err; | ||
332 | |||
333 | objio_seg = kzalloc(sizeof(*objio_seg) + | ||
334 | sizeof(objio_seg->ods[0]) * layout.olo_num_comps + | ||
335 | sizeof(*objio_seg->comps) * layout.olo_num_comps + | ||
336 | sizeof(struct caps_buffers) * layout.olo_num_comps, | ||
337 | gfp_flags); | ||
338 | if (!objio_seg) | ||
339 | return -ENOMEM; | ||
340 | |||
341 | objio_seg->comps = (void *)(objio_seg->ods + layout.olo_num_comps); | ||
342 | cur_comp = objio_seg->comps; | ||
343 | caps_p = (void *)(cur_comp + layout.olo_num_comps); | ||
344 | while (pnfs_osd_xdr_decode_layout_comp(&src_comp, &iter, xdr, &err)) | ||
345 | copy_single_comp(cur_comp++, &src_comp, caps_p++); | ||
346 | if (unlikely(err)) | ||
347 | goto err; | ||
348 | |||
349 | objio_seg->num_comps = layout.olo_num_comps; | ||
350 | objio_seg->comps_index = layout.olo_comps_index; | ||
351 | err = objio_devices_lookup(pnfslay, objio_seg, gfp_flags); | ||
352 | if (err) | ||
353 | goto err; | ||
354 | |||
355 | objio_seg->mirrors_p1 = layout.olo_map.odm_mirror_cnt + 1; | ||
356 | objio_seg->stripe_unit = layout.olo_map.odm_stripe_unit; | ||
357 | if (layout.olo_map.odm_group_width) { | ||
358 | objio_seg->group_width = layout.olo_map.odm_group_width; | ||
359 | objio_seg->group_depth = layout.olo_map.odm_group_depth; | ||
360 | objio_seg->group_count = layout.olo_map.odm_num_comps / | ||
361 | objio_seg->mirrors_p1 / | ||
362 | objio_seg->group_width; | ||
363 | } else { | ||
364 | objio_seg->group_width = layout.olo_map.odm_num_comps / | ||
365 | objio_seg->mirrors_p1; | ||
366 | objio_seg->group_depth = -1; | ||
367 | objio_seg->group_count = 1; | ||
368 | } | ||
369 | |||
370 | /* Cache this calculation it will hit for every page */ | ||
371 | objio_seg->max_io_size = (BIO_MAX_PAGES_KMALLOC * PAGE_SIZE - | ||
372 | objio_seg->stripe_unit) * | ||
373 | objio_seg->group_width; | ||
374 | |||
375 | *outp = &objio_seg->lseg; | ||
376 | return 0; | ||
377 | |||
378 | err: | ||
379 | kfree(objio_seg); | ||
380 | dprintk("%s: Error: return %d\n", __func__, err); | ||
381 | *outp = NULL; | ||
382 | return err; | ||
383 | } | ||
384 | |||
385 | void objio_free_lseg(struct pnfs_layout_segment *lseg) | ||
386 | { | ||
387 | int i; | ||
388 | struct objio_segment *objio_seg = OBJIO_LSEG(lseg); | ||
389 | |||
390 | for (i = 0; i < objio_seg->num_comps; i++) { | ||
391 | if (!objio_seg->ods[i]) | ||
392 | break; | ||
393 | nfs4_put_deviceid_node(&objio_seg->ods[i]->id_node); | ||
394 | } | ||
395 | kfree(objio_seg); | ||
396 | } | ||
397 | |||
398 | int objio_alloc_io_state(struct pnfs_layout_segment *lseg, | ||
399 | struct objlayout_io_state **outp, | ||
400 | gfp_t gfp_flags) | ||
401 | { | ||
402 | struct objio_segment *objio_seg = OBJIO_LSEG(lseg); | ||
403 | struct objio_state *ios; | ||
404 | const unsigned first_size = sizeof(*ios) + | ||
405 | objio_seg->num_comps * sizeof(ios->per_dev[0]); | ||
406 | const unsigned sec_size = objio_seg->num_comps * | ||
407 | sizeof(ios->ol_state.ioerrs[0]); | ||
408 | |||
409 | ios = kzalloc(first_size + sec_size, gfp_flags); | ||
410 | if (unlikely(!ios)) | ||
411 | return -ENOMEM; | ||
412 | |||
413 | ios->layout = objio_seg; | ||
414 | ios->ol_state.ioerrs = ((void *)ios) + first_size; | ||
415 | ios->ol_state.num_comps = objio_seg->num_comps; | ||
416 | |||
417 | *outp = &ios->ol_state; | ||
418 | return 0; | ||
419 | } | ||
420 | |||
421 | void objio_free_io_state(struct objlayout_io_state *ol_state) | ||
422 | { | ||
423 | struct objio_state *ios = container_of(ol_state, struct objio_state, | ||
424 | ol_state); | ||
425 | |||
426 | kfree(ios); | ||
427 | } | ||
428 | |||
429 | enum pnfs_osd_errno osd_pri_2_pnfs_err(enum osd_err_priority oep) | ||
430 | { | ||
431 | switch (oep) { | ||
432 | case OSD_ERR_PRI_NO_ERROR: | ||
433 | return (enum pnfs_osd_errno)0; | ||
434 | |||
435 | case OSD_ERR_PRI_CLEAR_PAGES: | ||
436 | BUG_ON(1); | ||
437 | return 0; | ||
438 | |||
439 | case OSD_ERR_PRI_RESOURCE: | ||
440 | return PNFS_OSD_ERR_RESOURCE; | ||
441 | case OSD_ERR_PRI_BAD_CRED: | ||
442 | return PNFS_OSD_ERR_BAD_CRED; | ||
443 | case OSD_ERR_PRI_NO_ACCESS: | ||
444 | return PNFS_OSD_ERR_NO_ACCESS; | ||
445 | case OSD_ERR_PRI_UNREACHABLE: | ||
446 | return PNFS_OSD_ERR_UNREACHABLE; | ||
447 | case OSD_ERR_PRI_NOT_FOUND: | ||
448 | return PNFS_OSD_ERR_NOT_FOUND; | ||
449 | case OSD_ERR_PRI_NO_SPACE: | ||
450 | return PNFS_OSD_ERR_NO_SPACE; | ||
451 | default: | ||
452 | WARN_ON(1); | ||
453 | /* fallthrough */ | ||
454 | case OSD_ERR_PRI_EIO: | ||
455 | return PNFS_OSD_ERR_EIO; | ||
456 | } | ||
457 | } | ||
458 | |||
459 | static void _clear_bio(struct bio *bio) | ||
460 | { | ||
461 | struct bio_vec *bv; | ||
462 | unsigned i; | ||
463 | |||
464 | __bio_for_each_segment(bv, bio, i, 0) { | ||
465 | unsigned this_count = bv->bv_len; | ||
466 | |||
467 | if (likely(PAGE_SIZE == this_count)) | ||
468 | clear_highpage(bv->bv_page); | ||
469 | else | ||
470 | zero_user(bv->bv_page, bv->bv_offset, this_count); | ||
471 | } | ||
472 | } | ||
473 | |||
474 | static int _io_check(struct objio_state *ios, bool is_write) | ||
475 | { | ||
476 | enum osd_err_priority oep = OSD_ERR_PRI_NO_ERROR; | ||
477 | int lin_ret = 0; | ||
478 | int i; | ||
479 | |||
480 | for (i = 0; i < ios->numdevs; i++) { | ||
481 | struct osd_sense_info osi; | ||
482 | struct osd_request *or = ios->per_dev[i].or; | ||
483 | unsigned dev; | ||
484 | int ret; | ||
485 | |||
486 | if (!or) | ||
487 | continue; | ||
488 | |||
489 | ret = osd_req_decode_sense(or, &osi); | ||
490 | if (likely(!ret)) | ||
491 | continue; | ||
492 | |||
493 | if (OSD_ERR_PRI_CLEAR_PAGES == osi.osd_err_pri) { | ||
494 | /* start read offset passed endof file */ | ||
495 | BUG_ON(is_write); | ||
496 | _clear_bio(ios->per_dev[i].bio); | ||
497 | dprintk("%s: start read offset passed end of file " | ||
498 | "offset=0x%llx, length=0x%lx\n", __func__, | ||
499 | _LLU(ios->per_dev[i].offset), | ||
500 | ios->per_dev[i].length); | ||
501 | |||
502 | continue; /* we recovered */ | ||
503 | } | ||
504 | dev = ios->per_dev[i].dev; | ||
505 | objlayout_io_set_result(&ios->ol_state, dev, | ||
506 | &ios->layout->comps[dev].oc_object_id, | ||
507 | osd_pri_2_pnfs_err(osi.osd_err_pri), | ||
508 | ios->per_dev[i].offset, | ||
509 | ios->per_dev[i].length, | ||
510 | is_write); | ||
511 | |||
512 | if (osi.osd_err_pri >= oep) { | ||
513 | oep = osi.osd_err_pri; | ||
514 | lin_ret = ret; | ||
515 | } | ||
516 | } | ||
517 | |||
518 | return lin_ret; | ||
519 | } | ||
520 | |||
521 | /* | ||
522 | * Common IO state helpers. | ||
523 | */ | ||
524 | static void _io_free(struct objio_state *ios) | ||
525 | { | ||
526 | unsigned i; | ||
527 | |||
528 | for (i = 0; i < ios->numdevs; i++) { | ||
529 | struct _objio_per_comp *per_dev = &ios->per_dev[i]; | ||
530 | |||
531 | if (per_dev->or) { | ||
532 | osd_end_request(per_dev->or); | ||
533 | per_dev->or = NULL; | ||
534 | } | ||
535 | |||
536 | if (per_dev->bio) { | ||
537 | bio_put(per_dev->bio); | ||
538 | per_dev->bio = NULL; | ||
539 | } | ||
540 | } | ||
541 | } | ||
542 | |||
543 | struct osd_dev *_io_od(struct objio_state *ios, unsigned dev) | ||
544 | { | ||
545 | unsigned min_dev = ios->layout->comps_index; | ||
546 | unsigned max_dev = min_dev + ios->layout->num_comps; | ||
547 | |||
548 | BUG_ON(dev < min_dev || max_dev <= dev); | ||
549 | return ios->layout->ods[dev - min_dev]->od; | ||
550 | } | ||
551 | |||
552 | struct _striping_info { | ||
553 | u64 obj_offset; | ||
554 | u64 group_length; | ||
555 | unsigned dev; | ||
556 | unsigned unit_off; | ||
557 | }; | ||
558 | |||
559 | static void _calc_stripe_info(struct objio_state *ios, u64 file_offset, | ||
560 | struct _striping_info *si) | ||
561 | { | ||
562 | u32 stripe_unit = ios->layout->stripe_unit; | ||
563 | u32 group_width = ios->layout->group_width; | ||
564 | u64 group_depth = ios->layout->group_depth; | ||
565 | u32 U = stripe_unit * group_width; | ||
566 | |||
567 | u64 T = U * group_depth; | ||
568 | u64 S = T * ios->layout->group_count; | ||
569 | u64 M = div64_u64(file_offset, S); | ||
570 | |||
571 | /* | ||
572 | G = (L - (M * S)) / T | ||
573 | H = (L - (M * S)) % T | ||
574 | */ | ||
575 | u64 LmodU = file_offset - M * S; | ||
576 | u32 G = div64_u64(LmodU, T); | ||
577 | u64 H = LmodU - G * T; | ||
578 | |||
579 | u32 N = div_u64(H, U); | ||
580 | |||
581 | div_u64_rem(file_offset, stripe_unit, &si->unit_off); | ||
582 | si->obj_offset = si->unit_off + (N * stripe_unit) + | ||
583 | (M * group_depth * stripe_unit); | ||
584 | |||
585 | /* "H - (N * U)" is just "H % U" so it's bound to u32 */ | ||
586 | si->dev = (u32)(H - (N * U)) / stripe_unit + G * group_width; | ||
587 | si->dev *= ios->layout->mirrors_p1; | ||
588 | |||
589 | si->group_length = T - H; | ||
590 | } | ||
591 | |||
592 | static int _add_stripe_unit(struct objio_state *ios, unsigned *cur_pg, | ||
593 | unsigned pgbase, struct _objio_per_comp *per_dev, int cur_len, | ||
594 | gfp_t gfp_flags) | ||
595 | { | ||
596 | unsigned pg = *cur_pg; | ||
597 | struct request_queue *q = | ||
598 | osd_request_queue(_io_od(ios, per_dev->dev)); | ||
599 | |||
600 | per_dev->length += cur_len; | ||
601 | |||
602 | if (per_dev->bio == NULL) { | ||
603 | unsigned stripes = ios->layout->num_comps / | ||
604 | ios->layout->mirrors_p1; | ||
605 | unsigned pages_in_stripe = stripes * | ||
606 | (ios->layout->stripe_unit / PAGE_SIZE); | ||
607 | unsigned bio_size = (ios->ol_state.nr_pages + pages_in_stripe) / | ||
608 | stripes; | ||
609 | |||
610 | if (BIO_MAX_PAGES_KMALLOC < bio_size) | ||
611 | bio_size = BIO_MAX_PAGES_KMALLOC; | ||
612 | |||
613 | per_dev->bio = bio_kmalloc(gfp_flags, bio_size); | ||
614 | if (unlikely(!per_dev->bio)) { | ||
615 | dprintk("Faild to allocate BIO size=%u\n", bio_size); | ||
616 | return -ENOMEM; | ||
617 | } | ||
618 | } | ||
619 | |||
620 | while (cur_len > 0) { | ||
621 | unsigned pglen = min_t(unsigned, PAGE_SIZE - pgbase, cur_len); | ||
622 | unsigned added_len; | ||
623 | |||
624 | BUG_ON(ios->ol_state.nr_pages <= pg); | ||
625 | cur_len -= pglen; | ||
626 | |||
627 | added_len = bio_add_pc_page(q, per_dev->bio, | ||
628 | ios->ol_state.pages[pg], pglen, pgbase); | ||
629 | if (unlikely(pglen != added_len)) | ||
630 | return -ENOMEM; | ||
631 | pgbase = 0; | ||
632 | ++pg; | ||
633 | } | ||
634 | BUG_ON(cur_len); | ||
635 | |||
636 | *cur_pg = pg; | ||
637 | return 0; | ||
638 | } | ||
639 | |||
640 | static int _prepare_one_group(struct objio_state *ios, u64 length, | ||
641 | struct _striping_info *si, unsigned *last_pg, | ||
642 | gfp_t gfp_flags) | ||
643 | { | ||
644 | unsigned stripe_unit = ios->layout->stripe_unit; | ||
645 | unsigned mirrors_p1 = ios->layout->mirrors_p1; | ||
646 | unsigned devs_in_group = ios->layout->group_width * mirrors_p1; | ||
647 | unsigned dev = si->dev; | ||
648 | unsigned first_dev = dev - (dev % devs_in_group); | ||
649 | unsigned max_comp = ios->numdevs ? ios->numdevs - mirrors_p1 : 0; | ||
650 | unsigned cur_pg = *last_pg; | ||
651 | int ret = 0; | ||
652 | |||
653 | while (length) { | ||
654 | struct _objio_per_comp *per_dev = &ios->per_dev[dev]; | ||
655 | unsigned cur_len, page_off = 0; | ||
656 | |||
657 | if (!per_dev->length) { | ||
658 | per_dev->dev = dev; | ||
659 | if (dev < si->dev) { | ||
660 | per_dev->offset = si->obj_offset + stripe_unit - | ||
661 | si->unit_off; | ||
662 | cur_len = stripe_unit; | ||
663 | } else if (dev == si->dev) { | ||
664 | per_dev->offset = si->obj_offset; | ||
665 | cur_len = stripe_unit - si->unit_off; | ||
666 | page_off = si->unit_off & ~PAGE_MASK; | ||
667 | BUG_ON(page_off && | ||
668 | (page_off != ios->ol_state.pgbase)); | ||
669 | } else { /* dev > si->dev */ | ||
670 | per_dev->offset = si->obj_offset - si->unit_off; | ||
671 | cur_len = stripe_unit; | ||
672 | } | ||
673 | |||
674 | if (max_comp < dev) | ||
675 | max_comp = dev; | ||
676 | } else { | ||
677 | cur_len = stripe_unit; | ||
678 | } | ||
679 | if (cur_len >= length) | ||
680 | cur_len = length; | ||
681 | |||
682 | ret = _add_stripe_unit(ios, &cur_pg, page_off , per_dev, | ||
683 | cur_len, gfp_flags); | ||
684 | if (unlikely(ret)) | ||
685 | goto out; | ||
686 | |||
687 | dev += mirrors_p1; | ||
688 | dev = (dev % devs_in_group) + first_dev; | ||
689 | |||
690 | length -= cur_len; | ||
691 | ios->length += cur_len; | ||
692 | } | ||
693 | out: | ||
694 | ios->numdevs = max_comp + mirrors_p1; | ||
695 | *last_pg = cur_pg; | ||
696 | return ret; | ||
697 | } | ||
698 | |||
699 | static int _io_rw_pagelist(struct objio_state *ios, gfp_t gfp_flags) | ||
700 | { | ||
701 | u64 length = ios->ol_state.count; | ||
702 | u64 offset = ios->ol_state.offset; | ||
703 | struct _striping_info si; | ||
704 | unsigned last_pg = 0; | ||
705 | int ret = 0; | ||
706 | |||
707 | while (length) { | ||
708 | _calc_stripe_info(ios, offset, &si); | ||
709 | |||
710 | if (length < si.group_length) | ||
711 | si.group_length = length; | ||
712 | |||
713 | ret = _prepare_one_group(ios, si.group_length, &si, &last_pg, gfp_flags); | ||
714 | if (unlikely(ret)) | ||
715 | goto out; | ||
716 | |||
717 | offset += si.group_length; | ||
718 | length -= si.group_length; | ||
719 | } | ||
720 | |||
721 | out: | ||
722 | if (!ios->length) | ||
723 | return ret; | ||
724 | |||
725 | return 0; | ||
726 | } | ||
727 | |||
728 | static ssize_t _sync_done(struct objio_state *ios) | ||
729 | { | ||
730 | struct completion *waiting = ios->private; | ||
731 | |||
732 | complete(waiting); | ||
733 | return 0; | ||
734 | } | ||
735 | |||
736 | static void _last_io(struct kref *kref) | ||
737 | { | ||
738 | struct objio_state *ios = container_of(kref, struct objio_state, kref); | ||
739 | |||
740 | ios->done(ios); | ||
741 | } | ||
742 | |||
743 | static void _done_io(struct osd_request *or, void *p) | ||
744 | { | ||
745 | struct objio_state *ios = p; | ||
746 | |||
747 | kref_put(&ios->kref, _last_io); | ||
748 | } | ||
749 | |||
750 | static ssize_t _io_exec(struct objio_state *ios) | ||
751 | { | ||
752 | DECLARE_COMPLETION_ONSTACK(wait); | ||
753 | ssize_t status = 0; /* sync status */ | ||
754 | unsigned i; | ||
755 | objio_done_fn saved_done_fn = ios->done; | ||
756 | bool sync = ios->ol_state.sync; | ||
757 | |||
758 | if (sync) { | ||
759 | ios->done = _sync_done; | ||
760 | ios->private = &wait; | ||
761 | } | ||
762 | |||
763 | kref_init(&ios->kref); | ||
764 | |||
765 | for (i = 0; i < ios->numdevs; i++) { | ||
766 | struct osd_request *or = ios->per_dev[i].or; | ||
767 | |||
768 | if (!or) | ||
769 | continue; | ||
770 | |||
771 | kref_get(&ios->kref); | ||
772 | osd_execute_request_async(or, _done_io, ios); | ||
773 | } | ||
774 | |||
775 | kref_put(&ios->kref, _last_io); | ||
776 | |||
777 | if (sync) { | ||
778 | wait_for_completion(&wait); | ||
779 | status = saved_done_fn(ios); | ||
780 | } | ||
781 | |||
782 | return status; | ||
783 | } | ||
784 | |||
785 | /* | ||
786 | * read | ||
787 | */ | ||
788 | static ssize_t _read_done(struct objio_state *ios) | ||
789 | { | ||
790 | ssize_t status; | ||
791 | int ret = _io_check(ios, false); | ||
792 | |||
793 | _io_free(ios); | ||
794 | |||
795 | if (likely(!ret)) | ||
796 | status = ios->length; | ||
797 | else | ||
798 | status = ret; | ||
799 | |||
800 | objlayout_read_done(&ios->ol_state, status, ios->ol_state.sync); | ||
801 | return status; | ||
802 | } | ||
803 | |||
804 | static int _read_mirrors(struct objio_state *ios, unsigned cur_comp) | ||
805 | { | ||
806 | struct osd_request *or = NULL; | ||
807 | struct _objio_per_comp *per_dev = &ios->per_dev[cur_comp]; | ||
808 | unsigned dev = per_dev->dev; | ||
809 | struct pnfs_osd_object_cred *cred = | ||
810 | &ios->layout->comps[dev]; | ||
811 | struct osd_obj_id obj = { | ||
812 | .partition = cred->oc_object_id.oid_partition_id, | ||
813 | .id = cred->oc_object_id.oid_object_id, | ||
814 | }; | ||
815 | int ret; | ||
816 | |||
817 | or = osd_start_request(_io_od(ios, dev), GFP_KERNEL); | ||
818 | if (unlikely(!or)) { | ||
819 | ret = -ENOMEM; | ||
820 | goto err; | ||
821 | } | ||
822 | per_dev->or = or; | ||
823 | |||
824 | osd_req_read(or, &obj, per_dev->offset, per_dev->bio, per_dev->length); | ||
825 | |||
826 | ret = osd_finalize_request(or, 0, cred->oc_cap.cred, NULL); | ||
827 | if (ret) { | ||
828 | dprintk("%s: Faild to osd_finalize_request() => %d\n", | ||
829 | __func__, ret); | ||
830 | goto err; | ||
831 | } | ||
832 | |||
833 | dprintk("%s:[%d] dev=%d obj=0x%llx start=0x%llx length=0x%lx\n", | ||
834 | __func__, cur_comp, dev, obj.id, _LLU(per_dev->offset), | ||
835 | per_dev->length); | ||
836 | |||
837 | err: | ||
838 | return ret; | ||
839 | } | ||
840 | |||
841 | static ssize_t _read_exec(struct objio_state *ios) | ||
842 | { | ||
843 | unsigned i; | ||
844 | int ret; | ||
845 | |||
846 | for (i = 0; i < ios->numdevs; i += ios->layout->mirrors_p1) { | ||
847 | if (!ios->per_dev[i].length) | ||
848 | continue; | ||
849 | ret = _read_mirrors(ios, i); | ||
850 | if (unlikely(ret)) | ||
851 | goto err; | ||
852 | } | ||
853 | |||
854 | ios->done = _read_done; | ||
855 | return _io_exec(ios); /* In sync mode exec returns the io status */ | ||
856 | |||
857 | err: | ||
858 | _io_free(ios); | ||
859 | return ret; | ||
860 | } | ||
861 | |||
862 | ssize_t objio_read_pagelist(struct objlayout_io_state *ol_state) | ||
863 | { | ||
864 | struct objio_state *ios = container_of(ol_state, struct objio_state, | ||
865 | ol_state); | ||
866 | int ret; | ||
867 | |||
868 | ret = _io_rw_pagelist(ios, GFP_KERNEL); | ||
869 | if (unlikely(ret)) | ||
870 | return ret; | ||
871 | |||
872 | return _read_exec(ios); | ||
873 | } | ||
874 | |||
875 | /* | ||
876 | * write | ||
877 | */ | ||
878 | static ssize_t _write_done(struct objio_state *ios) | ||
879 | { | ||
880 | ssize_t status; | ||
881 | int ret = _io_check(ios, true); | ||
882 | |||
883 | _io_free(ios); | ||
884 | |||
885 | if (likely(!ret)) { | ||
886 | /* FIXME: should be based on the OSD's persistence model | ||
887 | * See OSD2r05 Section 4.13 Data persistence model */ | ||
888 | ios->ol_state.committed = NFS_FILE_SYNC; | ||
889 | status = ios->length; | ||
890 | } else { | ||
891 | status = ret; | ||
892 | } | ||
893 | |||
894 | objlayout_write_done(&ios->ol_state, status, ios->ol_state.sync); | ||
895 | return status; | ||
896 | } | ||
897 | |||
898 | static int _write_mirrors(struct objio_state *ios, unsigned cur_comp) | ||
899 | { | ||
900 | struct _objio_per_comp *master_dev = &ios->per_dev[cur_comp]; | ||
901 | unsigned dev = ios->per_dev[cur_comp].dev; | ||
902 | unsigned last_comp = cur_comp + ios->layout->mirrors_p1; | ||
903 | int ret; | ||
904 | |||
905 | for (; cur_comp < last_comp; ++cur_comp, ++dev) { | ||
906 | struct osd_request *or = NULL; | ||
907 | struct pnfs_osd_object_cred *cred = | ||
908 | &ios->layout->comps[dev]; | ||
909 | struct osd_obj_id obj = { | ||
910 | .partition = cred->oc_object_id.oid_partition_id, | ||
911 | .id = cred->oc_object_id.oid_object_id, | ||
912 | }; | ||
913 | struct _objio_per_comp *per_dev = &ios->per_dev[cur_comp]; | ||
914 | struct bio *bio; | ||
915 | |||
916 | or = osd_start_request(_io_od(ios, dev), GFP_NOFS); | ||
917 | if (unlikely(!or)) { | ||
918 | ret = -ENOMEM; | ||
919 | goto err; | ||
920 | } | ||
921 | per_dev->or = or; | ||
922 | |||
923 | if (per_dev != master_dev) { | ||
924 | bio = bio_kmalloc(GFP_NOFS, | ||
925 | master_dev->bio->bi_max_vecs); | ||
926 | if (unlikely(!bio)) { | ||
927 | dprintk("Faild to allocate BIO size=%u\n", | ||
928 | master_dev->bio->bi_max_vecs); | ||
929 | ret = -ENOMEM; | ||
930 | goto err; | ||
931 | } | ||
932 | |||
933 | __bio_clone(bio, master_dev->bio); | ||
934 | bio->bi_bdev = NULL; | ||
935 | bio->bi_next = NULL; | ||
936 | per_dev->bio = bio; | ||
937 | per_dev->dev = dev; | ||
938 | per_dev->length = master_dev->length; | ||
939 | per_dev->offset = master_dev->offset; | ||
940 | } else { | ||
941 | bio = master_dev->bio; | ||
942 | bio->bi_rw |= REQ_WRITE; | ||
943 | } | ||
944 | |||
945 | osd_req_write(or, &obj, per_dev->offset, bio, per_dev->length); | ||
946 | |||
947 | ret = osd_finalize_request(or, 0, cred->oc_cap.cred, NULL); | ||
948 | if (ret) { | ||
949 | dprintk("%s: Faild to osd_finalize_request() => %d\n", | ||
950 | __func__, ret); | ||
951 | goto err; | ||
952 | } | ||
953 | |||
954 | dprintk("%s:[%d] dev=%d obj=0x%llx start=0x%llx length=0x%lx\n", | ||
955 | __func__, cur_comp, dev, obj.id, _LLU(per_dev->offset), | ||
956 | per_dev->length); | ||
957 | } | ||
958 | |||
959 | err: | ||
960 | return ret; | ||
961 | } | ||
962 | |||
963 | static ssize_t _write_exec(struct objio_state *ios) | ||
964 | { | ||
965 | unsigned i; | ||
966 | int ret; | ||
967 | |||
968 | for (i = 0; i < ios->numdevs; i += ios->layout->mirrors_p1) { | ||
969 | if (!ios->per_dev[i].length) | ||
970 | continue; | ||
971 | ret = _write_mirrors(ios, i); | ||
972 | if (unlikely(ret)) | ||
973 | goto err; | ||
974 | } | ||
975 | |||
976 | ios->done = _write_done; | ||
977 | return _io_exec(ios); /* In sync mode exec returns the io->status */ | ||
978 | |||
979 | err: | ||
980 | _io_free(ios); | ||
981 | return ret; | ||
982 | } | ||
983 | |||
984 | ssize_t objio_write_pagelist(struct objlayout_io_state *ol_state, bool stable) | ||
985 | { | ||
986 | struct objio_state *ios = container_of(ol_state, struct objio_state, | ||
987 | ol_state); | ||
988 | int ret; | ||
989 | |||
990 | /* TODO: ios->stable = stable; */ | ||
991 | ret = _io_rw_pagelist(ios, GFP_NOFS); | ||
992 | if (unlikely(ret)) | ||
993 | return ret; | ||
994 | |||
995 | return _write_exec(ios); | ||
996 | } | ||
997 | |||
998 | static bool objio_pg_test(struct nfs_pageio_descriptor *pgio, | ||
999 | struct nfs_page *prev, struct nfs_page *req) | ||
1000 | { | ||
1001 | if (!pnfs_generic_pg_test(pgio, prev, req)) | ||
1002 | return false; | ||
1003 | |||
1004 | return pgio->pg_count + req->wb_bytes <= | ||
1005 | OBJIO_LSEG(pgio->pg_lseg)->max_io_size; | ||
1006 | } | ||
1007 | |||
1008 | static struct pnfs_layoutdriver_type objlayout_type = { | ||
1009 | .id = LAYOUT_OSD2_OBJECTS, | ||
1010 | .name = "LAYOUT_OSD2_OBJECTS", | ||
1011 | .flags = PNFS_LAYOUTRET_ON_SETATTR, | ||
1012 | |||
1013 | .alloc_layout_hdr = objlayout_alloc_layout_hdr, | ||
1014 | .free_layout_hdr = objlayout_free_layout_hdr, | ||
1015 | |||
1016 | .alloc_lseg = objlayout_alloc_lseg, | ||
1017 | .free_lseg = objlayout_free_lseg, | ||
1018 | |||
1019 | .read_pagelist = objlayout_read_pagelist, | ||
1020 | .write_pagelist = objlayout_write_pagelist, | ||
1021 | .pg_test = objio_pg_test, | ||
1022 | |||
1023 | .free_deviceid_node = objio_free_deviceid_node, | ||
1024 | |||
1025 | .encode_layoutcommit = objlayout_encode_layoutcommit, | ||
1026 | .encode_layoutreturn = objlayout_encode_layoutreturn, | ||
1027 | }; | ||
1028 | |||
1029 | MODULE_DESCRIPTION("pNFS Layout Driver for OSD2 objects"); | ||
1030 | MODULE_AUTHOR("Benny Halevy <bhalevy@panasas.com>"); | ||
1031 | MODULE_LICENSE("GPL"); | ||
1032 | |||
1033 | static int __init | ||
1034 | objlayout_init(void) | ||
1035 | { | ||
1036 | int ret = pnfs_register_layoutdriver(&objlayout_type); | ||
1037 | |||
1038 | if (ret) | ||
1039 | printk(KERN_INFO | ||
1040 | "%s: Registering OSD pNFS Layout Driver failed: error=%d\n", | ||
1041 | __func__, ret); | ||
1042 | else | ||
1043 | printk(KERN_INFO "%s: Registered OSD pNFS Layout Driver\n", | ||
1044 | __func__); | ||
1045 | return ret; | ||
1046 | } | ||
1047 | |||
1048 | static void __exit | ||
1049 | objlayout_exit(void) | ||
1050 | { | ||
1051 | pnfs_unregister_layoutdriver(&objlayout_type); | ||
1052 | printk(KERN_INFO "%s: Unregistered OSD pNFS Layout Driver\n", | ||
1053 | __func__); | ||
1054 | } | ||
1055 | |||
1056 | module_init(objlayout_init); | ||
1057 | module_exit(objlayout_exit); | ||
diff --git a/fs/nfs/objlayout/objlayout.c b/fs/nfs/objlayout/objlayout.c new file mode 100644 index 000000000000..dc3956c0de80 --- /dev/null +++ b/fs/nfs/objlayout/objlayout.c | |||
@@ -0,0 +1,712 @@ | |||
1 | /* | ||
2 | * pNFS Objects layout driver high level definitions | ||
3 | * | ||
4 | * Copyright (C) 2007 Panasas Inc. [year of first publication] | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Benny Halevy <bhalevy@panasas.com> | ||
8 | * Boaz Harrosh <bharrosh@panasas.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 | ||
12 | * See the file COPYING included with this distribution for more details. | ||
13 | * | ||
14 | * Redistribution and use in source and binary forms, with or without | ||
15 | * modification, are permitted provided that the following conditions | ||
16 | * are met: | ||
17 | * | ||
18 | * 1. Redistributions of source code must retain the above copyright | ||
19 | * notice, this list of conditions and the following disclaimer. | ||
20 | * 2. Redistributions in binary form must reproduce the above copyright | ||
21 | * notice, this list of conditions and the following disclaimer in the | ||
22 | * documentation and/or other materials provided with the distribution. | ||
23 | * 3. Neither the name of the Panasas company nor the names of its | ||
24 | * contributors may be used to endorse or promote products derived | ||
25 | * from this software without specific prior written permission. | ||
26 | * | ||
27 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
28 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
29 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
30 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
31 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
32 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
33 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
34 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
35 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
36 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
37 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
38 | */ | ||
39 | |||
40 | #include <scsi/osd_initiator.h> | ||
41 | #include "objlayout.h" | ||
42 | |||
43 | #define NFSDBG_FACILITY NFSDBG_PNFS_LD | ||
44 | /* | ||
45 | * Create a objlayout layout structure for the given inode and return it. | ||
46 | */ | ||
47 | struct pnfs_layout_hdr * | ||
48 | objlayout_alloc_layout_hdr(struct inode *inode, gfp_t gfp_flags) | ||
49 | { | ||
50 | struct objlayout *objlay; | ||
51 | |||
52 | objlay = kzalloc(sizeof(struct objlayout), gfp_flags); | ||
53 | if (objlay) { | ||
54 | spin_lock_init(&objlay->lock); | ||
55 | INIT_LIST_HEAD(&objlay->err_list); | ||
56 | } | ||
57 | dprintk("%s: Return %p\n", __func__, objlay); | ||
58 | return &objlay->pnfs_layout; | ||
59 | } | ||
60 | |||
61 | /* | ||
62 | * Free an objlayout layout structure | ||
63 | */ | ||
64 | void | ||
65 | objlayout_free_layout_hdr(struct pnfs_layout_hdr *lo) | ||
66 | { | ||
67 | struct objlayout *objlay = OBJLAYOUT(lo); | ||
68 | |||
69 | dprintk("%s: objlay %p\n", __func__, objlay); | ||
70 | |||
71 | WARN_ON(!list_empty(&objlay->err_list)); | ||
72 | kfree(objlay); | ||
73 | } | ||
74 | |||
75 | /* | ||
76 | * Unmarshall layout and store it in pnfslay. | ||
77 | */ | ||
78 | struct pnfs_layout_segment * | ||
79 | objlayout_alloc_lseg(struct pnfs_layout_hdr *pnfslay, | ||
80 | struct nfs4_layoutget_res *lgr, | ||
81 | gfp_t gfp_flags) | ||
82 | { | ||
83 | int status = -ENOMEM; | ||
84 | struct xdr_stream stream; | ||
85 | struct xdr_buf buf = { | ||
86 | .pages = lgr->layoutp->pages, | ||
87 | .page_len = lgr->layoutp->len, | ||
88 | .buflen = lgr->layoutp->len, | ||
89 | .len = lgr->layoutp->len, | ||
90 | }; | ||
91 | struct page *scratch; | ||
92 | struct pnfs_layout_segment *lseg; | ||
93 | |||
94 | dprintk("%s: Begin pnfslay %p\n", __func__, pnfslay); | ||
95 | |||
96 | scratch = alloc_page(gfp_flags); | ||
97 | if (!scratch) | ||
98 | goto err_nofree; | ||
99 | |||
100 | xdr_init_decode(&stream, &buf, NULL); | ||
101 | xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE); | ||
102 | |||
103 | status = objio_alloc_lseg(&lseg, pnfslay, &lgr->range, &stream, gfp_flags); | ||
104 | if (unlikely(status)) { | ||
105 | dprintk("%s: objio_alloc_lseg Return err %d\n", __func__, | ||
106 | status); | ||
107 | goto err; | ||
108 | } | ||
109 | |||
110 | __free_page(scratch); | ||
111 | |||
112 | dprintk("%s: Return %p\n", __func__, lseg); | ||
113 | return lseg; | ||
114 | |||
115 | err: | ||
116 | __free_page(scratch); | ||
117 | err_nofree: | ||
118 | dprintk("%s: Err Return=>%d\n", __func__, status); | ||
119 | return ERR_PTR(status); | ||
120 | } | ||
121 | |||
122 | /* | ||
123 | * Free a layout segement | ||
124 | */ | ||
125 | void | ||
126 | objlayout_free_lseg(struct pnfs_layout_segment *lseg) | ||
127 | { | ||
128 | dprintk("%s: freeing layout segment %p\n", __func__, lseg); | ||
129 | |||
130 | if (unlikely(!lseg)) | ||
131 | return; | ||
132 | |||
133 | objio_free_lseg(lseg); | ||
134 | } | ||
135 | |||
136 | /* | ||
137 | * I/O Operations | ||
138 | */ | ||
139 | static inline u64 | ||
140 | end_offset(u64 start, u64 len) | ||
141 | { | ||
142 | u64 end; | ||
143 | |||
144 | end = start + len; | ||
145 | return end >= start ? end : NFS4_MAX_UINT64; | ||
146 | } | ||
147 | |||
148 | /* last octet in a range */ | ||
149 | static inline u64 | ||
150 | last_byte_offset(u64 start, u64 len) | ||
151 | { | ||
152 | u64 end; | ||
153 | |||
154 | BUG_ON(!len); | ||
155 | end = start + len; | ||
156 | return end > start ? end - 1 : NFS4_MAX_UINT64; | ||
157 | } | ||
158 | |||
159 | static struct objlayout_io_state * | ||
160 | objlayout_alloc_io_state(struct pnfs_layout_hdr *pnfs_layout_type, | ||
161 | struct page **pages, | ||
162 | unsigned pgbase, | ||
163 | loff_t offset, | ||
164 | size_t count, | ||
165 | struct pnfs_layout_segment *lseg, | ||
166 | void *rpcdata, | ||
167 | gfp_t gfp_flags) | ||
168 | { | ||
169 | struct objlayout_io_state *state; | ||
170 | u64 lseg_end_offset; | ||
171 | |||
172 | dprintk("%s: allocating io_state\n", __func__); | ||
173 | if (objio_alloc_io_state(lseg, &state, gfp_flags)) | ||
174 | return NULL; | ||
175 | |||
176 | BUG_ON(offset < lseg->pls_range.offset); | ||
177 | lseg_end_offset = end_offset(lseg->pls_range.offset, | ||
178 | lseg->pls_range.length); | ||
179 | BUG_ON(offset >= lseg_end_offset); | ||
180 | if (offset + count > lseg_end_offset) { | ||
181 | count = lseg->pls_range.length - | ||
182 | (offset - lseg->pls_range.offset); | ||
183 | dprintk("%s: truncated count %Zd\n", __func__, count); | ||
184 | } | ||
185 | |||
186 | if (pgbase > PAGE_SIZE) { | ||
187 | pages += pgbase >> PAGE_SHIFT; | ||
188 | pgbase &= ~PAGE_MASK; | ||
189 | } | ||
190 | |||
191 | INIT_LIST_HEAD(&state->err_list); | ||
192 | state->lseg = lseg; | ||
193 | state->rpcdata = rpcdata; | ||
194 | state->pages = pages; | ||
195 | state->pgbase = pgbase; | ||
196 | state->nr_pages = (pgbase + count + PAGE_SIZE - 1) >> PAGE_SHIFT; | ||
197 | state->offset = offset; | ||
198 | state->count = count; | ||
199 | state->sync = 0; | ||
200 | |||
201 | return state; | ||
202 | } | ||
203 | |||
204 | static void | ||
205 | objlayout_free_io_state(struct objlayout_io_state *state) | ||
206 | { | ||
207 | dprintk("%s: freeing io_state\n", __func__); | ||
208 | if (unlikely(!state)) | ||
209 | return; | ||
210 | |||
211 | objio_free_io_state(state); | ||
212 | } | ||
213 | |||
214 | /* | ||
215 | * I/O done common code | ||
216 | */ | ||
217 | static void | ||
218 | objlayout_iodone(struct objlayout_io_state *state) | ||
219 | { | ||
220 | dprintk("%s: state %p status\n", __func__, state); | ||
221 | |||
222 | if (likely(state->status >= 0)) { | ||
223 | objlayout_free_io_state(state); | ||
224 | } else { | ||
225 | struct objlayout *objlay = OBJLAYOUT(state->lseg->pls_layout); | ||
226 | |||
227 | spin_lock(&objlay->lock); | ||
228 | objlay->delta_space_valid = OBJ_DSU_INVALID; | ||
229 | list_add(&objlay->err_list, &state->err_list); | ||
230 | spin_unlock(&objlay->lock); | ||
231 | } | ||
232 | } | ||
233 | |||
234 | /* | ||
235 | * objlayout_io_set_result - Set an osd_error code on a specific osd comp. | ||
236 | * | ||
237 | * The @index component IO failed (error returned from target). Register | ||
238 | * the error for later reporting at layout-return. | ||
239 | */ | ||
240 | void | ||
241 | objlayout_io_set_result(struct objlayout_io_state *state, unsigned index, | ||
242 | struct pnfs_osd_objid *pooid, int osd_error, | ||
243 | u64 offset, u64 length, bool is_write) | ||
244 | { | ||
245 | struct pnfs_osd_ioerr *ioerr = &state->ioerrs[index]; | ||
246 | |||
247 | BUG_ON(index >= state->num_comps); | ||
248 | if (osd_error) { | ||
249 | ioerr->oer_component = *pooid; | ||
250 | ioerr->oer_comp_offset = offset; | ||
251 | ioerr->oer_comp_length = length; | ||
252 | ioerr->oer_iswrite = is_write; | ||
253 | ioerr->oer_errno = osd_error; | ||
254 | |||
255 | dprintk("%s: err[%d]: errno=%d is_write=%d dev(%llx:%llx) " | ||
256 | "par=0x%llx obj=0x%llx offset=0x%llx length=0x%llx\n", | ||
257 | __func__, index, ioerr->oer_errno, | ||
258 | ioerr->oer_iswrite, | ||
259 | _DEVID_LO(&ioerr->oer_component.oid_device_id), | ||
260 | _DEVID_HI(&ioerr->oer_component.oid_device_id), | ||
261 | ioerr->oer_component.oid_partition_id, | ||
262 | ioerr->oer_component.oid_object_id, | ||
263 | ioerr->oer_comp_offset, | ||
264 | ioerr->oer_comp_length); | ||
265 | } else { | ||
266 | /* User need not call if no error is reported */ | ||
267 | ioerr->oer_errno = 0; | ||
268 | } | ||
269 | } | ||
270 | |||
271 | /* Function scheduled on rpc workqueue to call ->nfs_readlist_complete(). | ||
272 | * This is because the osd completion is called with ints-off from | ||
273 | * the block layer | ||
274 | */ | ||
275 | static void _rpc_read_complete(struct work_struct *work) | ||
276 | { | ||
277 | struct rpc_task *task; | ||
278 | struct nfs_read_data *rdata; | ||
279 | |||
280 | dprintk("%s enter\n", __func__); | ||
281 | task = container_of(work, struct rpc_task, u.tk_work); | ||
282 | rdata = container_of(task, struct nfs_read_data, task); | ||
283 | |||
284 | pnfs_ld_read_done(rdata); | ||
285 | } | ||
286 | |||
287 | void | ||
288 | objlayout_read_done(struct objlayout_io_state *state, ssize_t status, bool sync) | ||
289 | { | ||
290 | int eof = state->eof; | ||
291 | struct nfs_read_data *rdata; | ||
292 | |||
293 | state->status = status; | ||
294 | dprintk("%s: Begin status=%ld eof=%d\n", __func__, status, eof); | ||
295 | rdata = state->rpcdata; | ||
296 | rdata->task.tk_status = status; | ||
297 | if (status >= 0) { | ||
298 | rdata->res.count = status; | ||
299 | rdata->res.eof = eof; | ||
300 | } | ||
301 | objlayout_iodone(state); | ||
302 | /* must not use state after this point */ | ||
303 | |||
304 | if (sync) | ||
305 | pnfs_ld_read_done(rdata); | ||
306 | else { | ||
307 | INIT_WORK(&rdata->task.u.tk_work, _rpc_read_complete); | ||
308 | schedule_work(&rdata->task.u.tk_work); | ||
309 | } | ||
310 | } | ||
311 | |||
312 | /* | ||
313 | * Perform sync or async reads. | ||
314 | */ | ||
315 | enum pnfs_try_status | ||
316 | objlayout_read_pagelist(struct nfs_read_data *rdata) | ||
317 | { | ||
318 | loff_t offset = rdata->args.offset; | ||
319 | size_t count = rdata->args.count; | ||
320 | struct objlayout_io_state *state; | ||
321 | ssize_t status = 0; | ||
322 | loff_t eof; | ||
323 | |||
324 | dprintk("%s: Begin inode %p offset %llu count %d\n", | ||
325 | __func__, rdata->inode, offset, (int)count); | ||
326 | |||
327 | eof = i_size_read(rdata->inode); | ||
328 | if (unlikely(offset + count > eof)) { | ||
329 | if (offset >= eof) { | ||
330 | status = 0; | ||
331 | rdata->res.count = 0; | ||
332 | rdata->res.eof = 1; | ||
333 | goto out; | ||
334 | } | ||
335 | count = eof - offset; | ||
336 | } | ||
337 | |||
338 | state = objlayout_alloc_io_state(NFS_I(rdata->inode)->layout, | ||
339 | rdata->args.pages, rdata->args.pgbase, | ||
340 | offset, count, | ||
341 | rdata->lseg, rdata, | ||
342 | GFP_KERNEL); | ||
343 | if (unlikely(!state)) { | ||
344 | status = -ENOMEM; | ||
345 | goto out; | ||
346 | } | ||
347 | |||
348 | state->eof = state->offset + state->count >= eof; | ||
349 | |||
350 | status = objio_read_pagelist(state); | ||
351 | out: | ||
352 | dprintk("%s: Return status %Zd\n", __func__, status); | ||
353 | rdata->pnfs_error = status; | ||
354 | return PNFS_ATTEMPTED; | ||
355 | } | ||
356 | |||
357 | /* Function scheduled on rpc workqueue to call ->nfs_writelist_complete(). | ||
358 | * This is because the osd completion is called with ints-off from | ||
359 | * the block layer | ||
360 | */ | ||
361 | static void _rpc_write_complete(struct work_struct *work) | ||
362 | { | ||
363 | struct rpc_task *task; | ||
364 | struct nfs_write_data *wdata; | ||
365 | |||
366 | dprintk("%s enter\n", __func__); | ||
367 | task = container_of(work, struct rpc_task, u.tk_work); | ||
368 | wdata = container_of(task, struct nfs_write_data, task); | ||
369 | |||
370 | pnfs_ld_write_done(wdata); | ||
371 | } | ||
372 | |||
373 | void | ||
374 | objlayout_write_done(struct objlayout_io_state *state, ssize_t status, | ||
375 | bool sync) | ||
376 | { | ||
377 | struct nfs_write_data *wdata; | ||
378 | |||
379 | dprintk("%s: Begin\n", __func__); | ||
380 | wdata = state->rpcdata; | ||
381 | state->status = status; | ||
382 | wdata->task.tk_status = status; | ||
383 | if (status >= 0) { | ||
384 | wdata->res.count = status; | ||
385 | wdata->verf.committed = state->committed; | ||
386 | dprintk("%s: Return status %d committed %d\n", | ||
387 | __func__, wdata->task.tk_status, | ||
388 | wdata->verf.committed); | ||
389 | } else | ||
390 | dprintk("%s: Return status %d\n", | ||
391 | __func__, wdata->task.tk_status); | ||
392 | objlayout_iodone(state); | ||
393 | /* must not use state after this point */ | ||
394 | |||
395 | if (sync) | ||
396 | pnfs_ld_write_done(wdata); | ||
397 | else { | ||
398 | INIT_WORK(&wdata->task.u.tk_work, _rpc_write_complete); | ||
399 | schedule_work(&wdata->task.u.tk_work); | ||
400 | } | ||
401 | } | ||
402 | |||
403 | /* | ||
404 | * Perform sync or async writes. | ||
405 | */ | ||
406 | enum pnfs_try_status | ||
407 | objlayout_write_pagelist(struct nfs_write_data *wdata, | ||
408 | int how) | ||
409 | { | ||
410 | struct objlayout_io_state *state; | ||
411 | ssize_t status; | ||
412 | |||
413 | dprintk("%s: Begin inode %p offset %llu count %u\n", | ||
414 | __func__, wdata->inode, wdata->args.offset, wdata->args.count); | ||
415 | |||
416 | state = objlayout_alloc_io_state(NFS_I(wdata->inode)->layout, | ||
417 | wdata->args.pages, | ||
418 | wdata->args.pgbase, | ||
419 | wdata->args.offset, | ||
420 | wdata->args.count, | ||
421 | wdata->lseg, wdata, | ||
422 | GFP_NOFS); | ||
423 | if (unlikely(!state)) { | ||
424 | status = -ENOMEM; | ||
425 | goto out; | ||
426 | } | ||
427 | |||
428 | state->sync = how & FLUSH_SYNC; | ||
429 | |||
430 | status = objio_write_pagelist(state, how & FLUSH_STABLE); | ||
431 | out: | ||
432 | dprintk("%s: Return status %Zd\n", __func__, status); | ||
433 | wdata->pnfs_error = status; | ||
434 | return PNFS_ATTEMPTED; | ||
435 | } | ||
436 | |||
437 | void | ||
438 | objlayout_encode_layoutcommit(struct pnfs_layout_hdr *pnfslay, | ||
439 | struct xdr_stream *xdr, | ||
440 | const struct nfs4_layoutcommit_args *args) | ||
441 | { | ||
442 | struct objlayout *objlay = OBJLAYOUT(pnfslay); | ||
443 | struct pnfs_osd_layoutupdate lou; | ||
444 | __be32 *start; | ||
445 | |||
446 | dprintk("%s: Begin\n", __func__); | ||
447 | |||
448 | spin_lock(&objlay->lock); | ||
449 | lou.dsu_valid = (objlay->delta_space_valid == OBJ_DSU_VALID); | ||
450 | lou.dsu_delta = objlay->delta_space_used; | ||
451 | objlay->delta_space_used = 0; | ||
452 | objlay->delta_space_valid = OBJ_DSU_INIT; | ||
453 | lou.olu_ioerr_flag = !list_empty(&objlay->err_list); | ||
454 | spin_unlock(&objlay->lock); | ||
455 | |||
456 | start = xdr_reserve_space(xdr, 4); | ||
457 | |||
458 | BUG_ON(pnfs_osd_xdr_encode_layoutupdate(xdr, &lou)); | ||
459 | |||
460 | *start = cpu_to_be32((xdr->p - start - 1) * 4); | ||
461 | |||
462 | dprintk("%s: Return delta_space_used %lld err %d\n", __func__, | ||
463 | lou.dsu_delta, lou.olu_ioerr_flag); | ||
464 | } | ||
465 | |||
466 | static int | ||
467 | err_prio(u32 oer_errno) | ||
468 | { | ||
469 | switch (oer_errno) { | ||
470 | case 0: | ||
471 | return 0; | ||
472 | |||
473 | case PNFS_OSD_ERR_RESOURCE: | ||
474 | return OSD_ERR_PRI_RESOURCE; | ||
475 | case PNFS_OSD_ERR_BAD_CRED: | ||
476 | return OSD_ERR_PRI_BAD_CRED; | ||
477 | case PNFS_OSD_ERR_NO_ACCESS: | ||
478 | return OSD_ERR_PRI_NO_ACCESS; | ||
479 | case PNFS_OSD_ERR_UNREACHABLE: | ||
480 | return OSD_ERR_PRI_UNREACHABLE; | ||
481 | case PNFS_OSD_ERR_NOT_FOUND: | ||
482 | return OSD_ERR_PRI_NOT_FOUND; | ||
483 | case PNFS_OSD_ERR_NO_SPACE: | ||
484 | return OSD_ERR_PRI_NO_SPACE; | ||
485 | default: | ||
486 | WARN_ON(1); | ||
487 | /* fallthrough */ | ||
488 | case PNFS_OSD_ERR_EIO: | ||
489 | return OSD_ERR_PRI_EIO; | ||
490 | } | ||
491 | } | ||
492 | |||
493 | static void | ||
494 | merge_ioerr(struct pnfs_osd_ioerr *dest_err, | ||
495 | const struct pnfs_osd_ioerr *src_err) | ||
496 | { | ||
497 | u64 dest_end, src_end; | ||
498 | |||
499 | if (!dest_err->oer_errno) { | ||
500 | *dest_err = *src_err; | ||
501 | /* accumulated device must be blank */ | ||
502 | memset(&dest_err->oer_component.oid_device_id, 0, | ||
503 | sizeof(dest_err->oer_component.oid_device_id)); | ||
504 | |||
505 | return; | ||
506 | } | ||
507 | |||
508 | if (dest_err->oer_component.oid_partition_id != | ||
509 | src_err->oer_component.oid_partition_id) | ||
510 | dest_err->oer_component.oid_partition_id = 0; | ||
511 | |||
512 | if (dest_err->oer_component.oid_object_id != | ||
513 | src_err->oer_component.oid_object_id) | ||
514 | dest_err->oer_component.oid_object_id = 0; | ||
515 | |||
516 | if (dest_err->oer_comp_offset > src_err->oer_comp_offset) | ||
517 | dest_err->oer_comp_offset = src_err->oer_comp_offset; | ||
518 | |||
519 | dest_end = end_offset(dest_err->oer_comp_offset, | ||
520 | dest_err->oer_comp_length); | ||
521 | src_end = end_offset(src_err->oer_comp_offset, | ||
522 | src_err->oer_comp_length); | ||
523 | if (dest_end < src_end) | ||
524 | dest_end = src_end; | ||
525 | |||
526 | dest_err->oer_comp_length = dest_end - dest_err->oer_comp_offset; | ||
527 | |||
528 | if ((src_err->oer_iswrite == dest_err->oer_iswrite) && | ||
529 | (err_prio(src_err->oer_errno) > err_prio(dest_err->oer_errno))) { | ||
530 | dest_err->oer_errno = src_err->oer_errno; | ||
531 | } else if (src_err->oer_iswrite) { | ||
532 | dest_err->oer_iswrite = true; | ||
533 | dest_err->oer_errno = src_err->oer_errno; | ||
534 | } | ||
535 | } | ||
536 | |||
537 | static void | ||
538 | encode_accumulated_error(struct objlayout *objlay, __be32 *p) | ||
539 | { | ||
540 | struct objlayout_io_state *state, *tmp; | ||
541 | struct pnfs_osd_ioerr accumulated_err = {.oer_errno = 0}; | ||
542 | |||
543 | list_for_each_entry_safe(state, tmp, &objlay->err_list, err_list) { | ||
544 | unsigned i; | ||
545 | |||
546 | for (i = 0; i < state->num_comps; i++) { | ||
547 | struct pnfs_osd_ioerr *ioerr = &state->ioerrs[i]; | ||
548 | |||
549 | if (!ioerr->oer_errno) | ||
550 | continue; | ||
551 | |||
552 | printk(KERN_ERR "%s: err[%d]: errno=%d is_write=%d " | ||
553 | "dev(%llx:%llx) par=0x%llx obj=0x%llx " | ||
554 | "offset=0x%llx length=0x%llx\n", | ||
555 | __func__, i, ioerr->oer_errno, | ||
556 | ioerr->oer_iswrite, | ||
557 | _DEVID_LO(&ioerr->oer_component.oid_device_id), | ||
558 | _DEVID_HI(&ioerr->oer_component.oid_device_id), | ||
559 | ioerr->oer_component.oid_partition_id, | ||
560 | ioerr->oer_component.oid_object_id, | ||
561 | ioerr->oer_comp_offset, | ||
562 | ioerr->oer_comp_length); | ||
563 | |||
564 | merge_ioerr(&accumulated_err, ioerr); | ||
565 | } | ||
566 | list_del(&state->err_list); | ||
567 | objlayout_free_io_state(state); | ||
568 | } | ||
569 | |||
570 | pnfs_osd_xdr_encode_ioerr(p, &accumulated_err); | ||
571 | } | ||
572 | |||
573 | void | ||
574 | objlayout_encode_layoutreturn(struct pnfs_layout_hdr *pnfslay, | ||
575 | struct xdr_stream *xdr, | ||
576 | const struct nfs4_layoutreturn_args *args) | ||
577 | { | ||
578 | struct objlayout *objlay = OBJLAYOUT(pnfslay); | ||
579 | struct objlayout_io_state *state, *tmp; | ||
580 | __be32 *start; | ||
581 | |||
582 | dprintk("%s: Begin\n", __func__); | ||
583 | start = xdr_reserve_space(xdr, 4); | ||
584 | BUG_ON(!start); | ||
585 | |||
586 | spin_lock(&objlay->lock); | ||
587 | |||
588 | list_for_each_entry_safe(state, tmp, &objlay->err_list, err_list) { | ||
589 | __be32 *last_xdr = NULL, *p; | ||
590 | unsigned i; | ||
591 | int res = 0; | ||
592 | |||
593 | for (i = 0; i < state->num_comps; i++) { | ||
594 | struct pnfs_osd_ioerr *ioerr = &state->ioerrs[i]; | ||
595 | |||
596 | if (!ioerr->oer_errno) | ||
597 | continue; | ||
598 | |||
599 | dprintk("%s: err[%d]: errno=%d is_write=%d " | ||
600 | "dev(%llx:%llx) par=0x%llx obj=0x%llx " | ||
601 | "offset=0x%llx length=0x%llx\n", | ||
602 | __func__, i, ioerr->oer_errno, | ||
603 | ioerr->oer_iswrite, | ||
604 | _DEVID_LO(&ioerr->oer_component.oid_device_id), | ||
605 | _DEVID_HI(&ioerr->oer_component.oid_device_id), | ||
606 | ioerr->oer_component.oid_partition_id, | ||
607 | ioerr->oer_component.oid_object_id, | ||
608 | ioerr->oer_comp_offset, | ||
609 | ioerr->oer_comp_length); | ||
610 | |||
611 | p = pnfs_osd_xdr_ioerr_reserve_space(xdr); | ||
612 | if (unlikely(!p)) { | ||
613 | res = -E2BIG; | ||
614 | break; /* accumulated_error */ | ||
615 | } | ||
616 | |||
617 | last_xdr = p; | ||
618 | pnfs_osd_xdr_encode_ioerr(p, &state->ioerrs[i]); | ||
619 | } | ||
620 | |||
621 | /* TODO: use xdr_write_pages */ | ||
622 | if (unlikely(res)) { | ||
623 | /* no space for even one error descriptor */ | ||
624 | BUG_ON(!last_xdr); | ||
625 | |||
626 | /* we've encountered a situation with lots and lots of | ||
627 | * errors and no space to encode them all. Use the last | ||
628 | * available slot to report the union of all the | ||
629 | * remaining errors. | ||
630 | */ | ||
631 | encode_accumulated_error(objlay, last_xdr); | ||
632 | goto loop_done; | ||
633 | } | ||
634 | list_del(&state->err_list); | ||
635 | objlayout_free_io_state(state); | ||
636 | } | ||
637 | loop_done: | ||
638 | spin_unlock(&objlay->lock); | ||
639 | |||
640 | *start = cpu_to_be32((xdr->p - start - 1) * 4); | ||
641 | dprintk("%s: Return\n", __func__); | ||
642 | } | ||
643 | |||
644 | |||
645 | /* | ||
646 | * Get Device Info API for io engines | ||
647 | */ | ||
648 | struct objlayout_deviceinfo { | ||
649 | struct page *page; | ||
650 | struct pnfs_osd_deviceaddr da; /* This must be last */ | ||
651 | }; | ||
652 | |||
653 | /* Initialize and call nfs_getdeviceinfo, then decode and return a | ||
654 | * "struct pnfs_osd_deviceaddr *" Eventually objlayout_put_deviceinfo() | ||
655 | * should be called. | ||
656 | */ | ||
657 | int objlayout_get_deviceinfo(struct pnfs_layout_hdr *pnfslay, | ||
658 | struct nfs4_deviceid *d_id, struct pnfs_osd_deviceaddr **deviceaddr, | ||
659 | gfp_t gfp_flags) | ||
660 | { | ||
661 | struct objlayout_deviceinfo *odi; | ||
662 | struct pnfs_device pd; | ||
663 | struct super_block *sb; | ||
664 | struct page *page, **pages; | ||
665 | u32 *p; | ||
666 | int err; | ||
667 | |||
668 | page = alloc_page(gfp_flags); | ||
669 | if (!page) | ||
670 | return -ENOMEM; | ||
671 | |||
672 | pages = &page; | ||
673 | pd.pages = pages; | ||
674 | |||
675 | memcpy(&pd.dev_id, d_id, sizeof(*d_id)); | ||
676 | pd.layout_type = LAYOUT_OSD2_OBJECTS; | ||
677 | pd.pages = &page; | ||
678 | pd.pgbase = 0; | ||
679 | pd.pglen = PAGE_SIZE; | ||
680 | pd.mincount = 0; | ||
681 | |||
682 | sb = pnfslay->plh_inode->i_sb; | ||
683 | err = nfs4_proc_getdeviceinfo(NFS_SERVER(pnfslay->plh_inode), &pd); | ||
684 | dprintk("%s nfs_getdeviceinfo returned %d\n", __func__, err); | ||
685 | if (err) | ||
686 | goto err_out; | ||
687 | |||
688 | p = page_address(page); | ||
689 | odi = kzalloc(sizeof(*odi), gfp_flags); | ||
690 | if (!odi) { | ||
691 | err = -ENOMEM; | ||
692 | goto err_out; | ||
693 | } | ||
694 | pnfs_osd_xdr_decode_deviceaddr(&odi->da, p); | ||
695 | odi->page = page; | ||
696 | *deviceaddr = &odi->da; | ||
697 | return 0; | ||
698 | |||
699 | err_out: | ||
700 | __free_page(page); | ||
701 | return err; | ||
702 | } | ||
703 | |||
704 | void objlayout_put_deviceinfo(struct pnfs_osd_deviceaddr *deviceaddr) | ||
705 | { | ||
706 | struct objlayout_deviceinfo *odi = container_of(deviceaddr, | ||
707 | struct objlayout_deviceinfo, | ||
708 | da); | ||
709 | |||
710 | __free_page(odi->page); | ||
711 | kfree(odi); | ||
712 | } | ||
diff --git a/fs/nfs/objlayout/objlayout.h b/fs/nfs/objlayout/objlayout.h new file mode 100644 index 000000000000..a8244c8e042d --- /dev/null +++ b/fs/nfs/objlayout/objlayout.h | |||
@@ -0,0 +1,187 @@ | |||
1 | /* | ||
2 | * Data types and function declerations for interfacing with the | ||
3 | * pNFS standard object layout driver. | ||
4 | * | ||
5 | * Copyright (C) 2007 Panasas Inc. [year of first publication] | ||
6 | * All rights reserved. | ||
7 | * | ||
8 | * Benny Halevy <bhalevy@panasas.com> | ||
9 | * Boaz Harrosh <bharrosh@panasas.com> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 | ||
13 | * See the file COPYING included with this distribution for more details. | ||
14 | * | ||
15 | * Redistribution and use in source and binary forms, with or without | ||
16 | * modification, are permitted provided that the following conditions | ||
17 | * are met: | ||
18 | * | ||
19 | * 1. Redistributions of source code must retain the above copyright | ||
20 | * notice, this list of conditions and the following disclaimer. | ||
21 | * 2. Redistributions in binary form must reproduce the above copyright | ||
22 | * notice, this list of conditions and the following disclaimer in the | ||
23 | * documentation and/or other materials provided with the distribution. | ||
24 | * 3. Neither the name of the Panasas company nor the names of its | ||
25 | * contributors may be used to endorse or promote products derived | ||
26 | * from this software without specific prior written permission. | ||
27 | * | ||
28 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
29 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
30 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
31 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
32 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
33 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
34 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
35 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
36 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
37 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
38 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
39 | */ | ||
40 | |||
41 | #ifndef _OBJLAYOUT_H | ||
42 | #define _OBJLAYOUT_H | ||
43 | |||
44 | #include <linux/nfs_fs.h> | ||
45 | #include <linux/pnfs_osd_xdr.h> | ||
46 | #include "../pnfs.h" | ||
47 | |||
48 | /* | ||
49 | * per-inode layout | ||
50 | */ | ||
51 | struct objlayout { | ||
52 | struct pnfs_layout_hdr pnfs_layout; | ||
53 | |||
54 | /* for layout_commit */ | ||
55 | enum osd_delta_space_valid_enum { | ||
56 | OBJ_DSU_INIT = 0, | ||
57 | OBJ_DSU_VALID, | ||
58 | OBJ_DSU_INVALID, | ||
59 | } delta_space_valid; | ||
60 | s64 delta_space_used; /* consumed by write ops */ | ||
61 | |||
62 | /* for layout_return */ | ||
63 | spinlock_t lock; | ||
64 | struct list_head err_list; | ||
65 | }; | ||
66 | |||
67 | static inline struct objlayout * | ||
68 | OBJLAYOUT(struct pnfs_layout_hdr *lo) | ||
69 | { | ||
70 | return container_of(lo, struct objlayout, pnfs_layout); | ||
71 | } | ||
72 | |||
73 | /* | ||
74 | * per-I/O operation state | ||
75 | * embedded in objects provider io_state data structure | ||
76 | */ | ||
77 | struct objlayout_io_state { | ||
78 | struct pnfs_layout_segment *lseg; | ||
79 | |||
80 | struct page **pages; | ||
81 | unsigned pgbase; | ||
82 | unsigned nr_pages; | ||
83 | unsigned long count; | ||
84 | loff_t offset; | ||
85 | bool sync; | ||
86 | |||
87 | void *rpcdata; | ||
88 | int status; /* res */ | ||
89 | int eof; /* res */ | ||
90 | int committed; /* res */ | ||
91 | |||
92 | /* Error reporting (layout_return) */ | ||
93 | struct list_head err_list; | ||
94 | unsigned num_comps; | ||
95 | /* Pointer to array of error descriptors of size num_comps. | ||
96 | * It should contain as many entries as devices in the osd_layout | ||
97 | * that participate in the I/O. It is up to the io_engine to allocate | ||
98 | * needed space and set num_comps. | ||
99 | */ | ||
100 | struct pnfs_osd_ioerr *ioerrs; | ||
101 | }; | ||
102 | |||
103 | /* | ||
104 | * Raid engine I/O API | ||
105 | */ | ||
106 | extern int objio_alloc_lseg(struct pnfs_layout_segment **outp, | ||
107 | struct pnfs_layout_hdr *pnfslay, | ||
108 | struct pnfs_layout_range *range, | ||
109 | struct xdr_stream *xdr, | ||
110 | gfp_t gfp_flags); | ||
111 | extern void objio_free_lseg(struct pnfs_layout_segment *lseg); | ||
112 | |||
113 | extern int objio_alloc_io_state( | ||
114 | struct pnfs_layout_segment *lseg, | ||
115 | struct objlayout_io_state **outp, | ||
116 | gfp_t gfp_flags); | ||
117 | extern void objio_free_io_state(struct objlayout_io_state *state); | ||
118 | |||
119 | extern ssize_t objio_read_pagelist(struct objlayout_io_state *ol_state); | ||
120 | extern ssize_t objio_write_pagelist(struct objlayout_io_state *ol_state, | ||
121 | bool stable); | ||
122 | |||
123 | /* | ||
124 | * callback API | ||
125 | */ | ||
126 | extern void objlayout_io_set_result(struct objlayout_io_state *state, | ||
127 | unsigned index, struct pnfs_osd_objid *pooid, | ||
128 | int osd_error, u64 offset, u64 length, bool is_write); | ||
129 | |||
130 | static inline void | ||
131 | objlayout_add_delta_space_used(struct objlayout_io_state *state, s64 space_used) | ||
132 | { | ||
133 | struct objlayout *objlay = OBJLAYOUT(state->lseg->pls_layout); | ||
134 | |||
135 | /* If one of the I/Os errored out and the delta_space_used was | ||
136 | * invalid we render the complete report as invalid. Protocol mandate | ||
137 | * the DSU be accurate or not reported. | ||
138 | */ | ||
139 | spin_lock(&objlay->lock); | ||
140 | if (objlay->delta_space_valid != OBJ_DSU_INVALID) { | ||
141 | objlay->delta_space_valid = OBJ_DSU_VALID; | ||
142 | objlay->delta_space_used += space_used; | ||
143 | } | ||
144 | spin_unlock(&objlay->lock); | ||
145 | } | ||
146 | |||
147 | extern void objlayout_read_done(struct objlayout_io_state *state, | ||
148 | ssize_t status, bool sync); | ||
149 | extern void objlayout_write_done(struct objlayout_io_state *state, | ||
150 | ssize_t status, bool sync); | ||
151 | |||
152 | extern int objlayout_get_deviceinfo(struct pnfs_layout_hdr *pnfslay, | ||
153 | struct nfs4_deviceid *d_id, struct pnfs_osd_deviceaddr **deviceaddr, | ||
154 | gfp_t gfp_flags); | ||
155 | extern void objlayout_put_deviceinfo(struct pnfs_osd_deviceaddr *deviceaddr); | ||
156 | |||
157 | /* | ||
158 | * exported generic objects function vectors | ||
159 | */ | ||
160 | |||
161 | extern struct pnfs_layout_hdr *objlayout_alloc_layout_hdr(struct inode *, gfp_t gfp_flags); | ||
162 | extern void objlayout_free_layout_hdr(struct pnfs_layout_hdr *); | ||
163 | |||
164 | extern struct pnfs_layout_segment *objlayout_alloc_lseg( | ||
165 | struct pnfs_layout_hdr *, | ||
166 | struct nfs4_layoutget_res *, | ||
167 | gfp_t gfp_flags); | ||
168 | extern void objlayout_free_lseg(struct pnfs_layout_segment *); | ||
169 | |||
170 | extern enum pnfs_try_status objlayout_read_pagelist( | ||
171 | struct nfs_read_data *); | ||
172 | |||
173 | extern enum pnfs_try_status objlayout_write_pagelist( | ||
174 | struct nfs_write_data *, | ||
175 | int how); | ||
176 | |||
177 | extern void objlayout_encode_layoutcommit( | ||
178 | struct pnfs_layout_hdr *, | ||
179 | struct xdr_stream *, | ||
180 | const struct nfs4_layoutcommit_args *); | ||
181 | |||
182 | extern void objlayout_encode_layoutreturn( | ||
183 | struct pnfs_layout_hdr *, | ||
184 | struct xdr_stream *, | ||
185 | const struct nfs4_layoutreturn_args *); | ||
186 | |||
187 | #endif /* _OBJLAYOUT_H */ | ||
diff --git a/fs/nfs/objlayout/pnfs_osd_xdr_cli.c b/fs/nfs/objlayout/pnfs_osd_xdr_cli.c new file mode 100644 index 000000000000..16fc758e9123 --- /dev/null +++ b/fs/nfs/objlayout/pnfs_osd_xdr_cli.c | |||
@@ -0,0 +1,412 @@ | |||
1 | /* | ||
2 | * Object-Based pNFS Layout XDR layer | ||
3 | * | ||
4 | * Copyright (C) 2007 Panasas Inc. [year of first publication] | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Benny Halevy <bhalevy@panasas.com> | ||
8 | * Boaz Harrosh <bharrosh@panasas.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 | ||
12 | * See the file COPYING included with this distribution for more details. | ||
13 | * | ||
14 | * Redistribution and use in source and binary forms, with or without | ||
15 | * modification, are permitted provided that the following conditions | ||
16 | * are met: | ||
17 | * | ||
18 | * 1. Redistributions of source code must retain the above copyright | ||
19 | * notice, this list of conditions and the following disclaimer. | ||
20 | * 2. Redistributions in binary form must reproduce the above copyright | ||
21 | * notice, this list of conditions and the following disclaimer in the | ||
22 | * documentation and/or other materials provided with the distribution. | ||
23 | * 3. Neither the name of the Panasas company nor the names of its | ||
24 | * contributors may be used to endorse or promote products derived | ||
25 | * from this software without specific prior written permission. | ||
26 | * | ||
27 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
28 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
29 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
30 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
31 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
32 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
33 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
34 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
35 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
36 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
37 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
38 | */ | ||
39 | |||
40 | #include <linux/pnfs_osd_xdr.h> | ||
41 | |||
42 | #define NFSDBG_FACILITY NFSDBG_PNFS_LD | ||
43 | |||
44 | /* | ||
45 | * The following implementation is based on RFC5664 | ||
46 | */ | ||
47 | |||
48 | /* | ||
49 | * struct pnfs_osd_objid { | ||
50 | * struct nfs4_deviceid oid_device_id; | ||
51 | * u64 oid_partition_id; | ||
52 | * u64 oid_object_id; | ||
53 | * }; // xdr size 32 bytes | ||
54 | */ | ||
55 | static __be32 * | ||
56 | _osd_xdr_decode_objid(__be32 *p, struct pnfs_osd_objid *objid) | ||
57 | { | ||
58 | p = xdr_decode_opaque_fixed(p, objid->oid_device_id.data, | ||
59 | sizeof(objid->oid_device_id.data)); | ||
60 | |||
61 | p = xdr_decode_hyper(p, &objid->oid_partition_id); | ||
62 | p = xdr_decode_hyper(p, &objid->oid_object_id); | ||
63 | return p; | ||
64 | } | ||
65 | /* | ||
66 | * struct pnfs_osd_opaque_cred { | ||
67 | * u32 cred_len; | ||
68 | * void *cred; | ||
69 | * }; // xdr size [variable] | ||
70 | * The return pointers are from the xdr buffer | ||
71 | */ | ||
72 | static int | ||
73 | _osd_xdr_decode_opaque_cred(struct pnfs_osd_opaque_cred *opaque_cred, | ||
74 | struct xdr_stream *xdr) | ||
75 | { | ||
76 | __be32 *p = xdr_inline_decode(xdr, 1); | ||
77 | |||
78 | if (!p) | ||
79 | return -EINVAL; | ||
80 | |||
81 | opaque_cred->cred_len = be32_to_cpu(*p++); | ||
82 | |||
83 | p = xdr_inline_decode(xdr, opaque_cred->cred_len); | ||
84 | if (!p) | ||
85 | return -EINVAL; | ||
86 | |||
87 | opaque_cred->cred = p; | ||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | /* | ||
92 | * struct pnfs_osd_object_cred { | ||
93 | * struct pnfs_osd_objid oc_object_id; | ||
94 | * u32 oc_osd_version; | ||
95 | * u32 oc_cap_key_sec; | ||
96 | * struct pnfs_osd_opaque_cred oc_cap_key | ||
97 | * struct pnfs_osd_opaque_cred oc_cap; | ||
98 | * }; // xdr size 32 + 4 + 4 + [variable] + [variable] | ||
99 | */ | ||
100 | static int | ||
101 | _osd_xdr_decode_object_cred(struct pnfs_osd_object_cred *comp, | ||
102 | struct xdr_stream *xdr) | ||
103 | { | ||
104 | __be32 *p = xdr_inline_decode(xdr, 32 + 4 + 4); | ||
105 | int ret; | ||
106 | |||
107 | if (!p) | ||
108 | return -EIO; | ||
109 | |||
110 | p = _osd_xdr_decode_objid(p, &comp->oc_object_id); | ||
111 | comp->oc_osd_version = be32_to_cpup(p++); | ||
112 | comp->oc_cap_key_sec = be32_to_cpup(p); | ||
113 | |||
114 | ret = _osd_xdr_decode_opaque_cred(&comp->oc_cap_key, xdr); | ||
115 | if (unlikely(ret)) | ||
116 | return ret; | ||
117 | |||
118 | ret = _osd_xdr_decode_opaque_cred(&comp->oc_cap, xdr); | ||
119 | return ret; | ||
120 | } | ||
121 | |||
122 | /* | ||
123 | * struct pnfs_osd_data_map { | ||
124 | * u32 odm_num_comps; | ||
125 | * u64 odm_stripe_unit; | ||
126 | * u32 odm_group_width; | ||
127 | * u32 odm_group_depth; | ||
128 | * u32 odm_mirror_cnt; | ||
129 | * u32 odm_raid_algorithm; | ||
130 | * }; // xdr size 4 + 8 + 4 + 4 + 4 + 4 | ||
131 | */ | ||
132 | static inline int | ||
133 | _osd_data_map_xdr_sz(void) | ||
134 | { | ||
135 | return 4 + 8 + 4 + 4 + 4 + 4; | ||
136 | } | ||
137 | |||
138 | static __be32 * | ||
139 | _osd_xdr_decode_data_map(__be32 *p, struct pnfs_osd_data_map *data_map) | ||
140 | { | ||
141 | data_map->odm_num_comps = be32_to_cpup(p++); | ||
142 | p = xdr_decode_hyper(p, &data_map->odm_stripe_unit); | ||
143 | data_map->odm_group_width = be32_to_cpup(p++); | ||
144 | data_map->odm_group_depth = be32_to_cpup(p++); | ||
145 | data_map->odm_mirror_cnt = be32_to_cpup(p++); | ||
146 | data_map->odm_raid_algorithm = be32_to_cpup(p++); | ||
147 | dprintk("%s: odm_num_comps=%u odm_stripe_unit=%llu odm_group_width=%u " | ||
148 | "odm_group_depth=%u odm_mirror_cnt=%u odm_raid_algorithm=%u\n", | ||
149 | __func__, | ||
150 | data_map->odm_num_comps, | ||
151 | (unsigned long long)data_map->odm_stripe_unit, | ||
152 | data_map->odm_group_width, | ||
153 | data_map->odm_group_depth, | ||
154 | data_map->odm_mirror_cnt, | ||
155 | data_map->odm_raid_algorithm); | ||
156 | return p; | ||
157 | } | ||
158 | |||
159 | int pnfs_osd_xdr_decode_layout_map(struct pnfs_osd_layout *layout, | ||
160 | struct pnfs_osd_xdr_decode_layout_iter *iter, struct xdr_stream *xdr) | ||
161 | { | ||
162 | __be32 *p; | ||
163 | |||
164 | memset(iter, 0, sizeof(*iter)); | ||
165 | |||
166 | p = xdr_inline_decode(xdr, _osd_data_map_xdr_sz() + 4 + 4); | ||
167 | if (unlikely(!p)) | ||
168 | return -EINVAL; | ||
169 | |||
170 | p = _osd_xdr_decode_data_map(p, &layout->olo_map); | ||
171 | layout->olo_comps_index = be32_to_cpup(p++); | ||
172 | layout->olo_num_comps = be32_to_cpup(p++); | ||
173 | iter->total_comps = layout->olo_num_comps; | ||
174 | return 0; | ||
175 | } | ||
176 | |||
177 | bool pnfs_osd_xdr_decode_layout_comp(struct pnfs_osd_object_cred *comp, | ||
178 | struct pnfs_osd_xdr_decode_layout_iter *iter, struct xdr_stream *xdr, | ||
179 | int *err) | ||
180 | { | ||
181 | BUG_ON(iter->decoded_comps > iter->total_comps); | ||
182 | if (iter->decoded_comps == iter->total_comps) | ||
183 | return false; | ||
184 | |||
185 | *err = _osd_xdr_decode_object_cred(comp, xdr); | ||
186 | if (unlikely(*err)) { | ||
187 | dprintk("%s: _osd_xdr_decode_object_cred=>%d decoded_comps=%d " | ||
188 | "total_comps=%d\n", __func__, *err, | ||
189 | iter->decoded_comps, iter->total_comps); | ||
190 | return false; /* stop the loop */ | ||
191 | } | ||
192 | dprintk("%s: dev(%llx:%llx) par=0x%llx obj=0x%llx " | ||
193 | "key_len=%u cap_len=%u\n", | ||
194 | __func__, | ||
195 | _DEVID_LO(&comp->oc_object_id.oid_device_id), | ||
196 | _DEVID_HI(&comp->oc_object_id.oid_device_id), | ||
197 | comp->oc_object_id.oid_partition_id, | ||
198 | comp->oc_object_id.oid_object_id, | ||
199 | comp->oc_cap_key.cred_len, comp->oc_cap.cred_len); | ||
200 | |||
201 | iter->decoded_comps++; | ||
202 | return true; | ||
203 | } | ||
204 | |||
205 | /* | ||
206 | * Get Device Information Decoding | ||
207 | * | ||
208 | * Note: since Device Information is currently done synchronously, all | ||
209 | * variable strings fields are left inside the rpc buffer and are only | ||
210 | * pointed to by the pnfs_osd_deviceaddr members. So the read buffer | ||
211 | * should not be freed while the returned information is in use. | ||
212 | */ | ||
213 | /* | ||
214 | *struct nfs4_string { | ||
215 | * unsigned int len; | ||
216 | * char *data; | ||
217 | *}; // size [variable] | ||
218 | * NOTE: Returned string points to inside the XDR buffer | ||
219 | */ | ||
220 | static __be32 * | ||
221 | __read_u8_opaque(__be32 *p, struct nfs4_string *str) | ||
222 | { | ||
223 | str->len = be32_to_cpup(p++); | ||
224 | str->data = (char *)p; | ||
225 | |||
226 | p += XDR_QUADLEN(str->len); | ||
227 | return p; | ||
228 | } | ||
229 | |||
230 | /* | ||
231 | * struct pnfs_osd_targetid { | ||
232 | * u32 oti_type; | ||
233 | * struct nfs4_string oti_scsi_device_id; | ||
234 | * };// size 4 + [variable] | ||
235 | */ | ||
236 | static __be32 * | ||
237 | __read_targetid(__be32 *p, struct pnfs_osd_targetid* targetid) | ||
238 | { | ||
239 | u32 oti_type; | ||
240 | |||
241 | oti_type = be32_to_cpup(p++); | ||
242 | targetid->oti_type = oti_type; | ||
243 | |||
244 | switch (oti_type) { | ||
245 | case OBJ_TARGET_SCSI_NAME: | ||
246 | case OBJ_TARGET_SCSI_DEVICE_ID: | ||
247 | p = __read_u8_opaque(p, &targetid->oti_scsi_device_id); | ||
248 | } | ||
249 | |||
250 | return p; | ||
251 | } | ||
252 | |||
253 | /* | ||
254 | * struct pnfs_osd_net_addr { | ||
255 | * struct nfs4_string r_netid; | ||
256 | * struct nfs4_string r_addr; | ||
257 | * }; | ||
258 | */ | ||
259 | static __be32 * | ||
260 | __read_net_addr(__be32 *p, struct pnfs_osd_net_addr* netaddr) | ||
261 | { | ||
262 | p = __read_u8_opaque(p, &netaddr->r_netid); | ||
263 | p = __read_u8_opaque(p, &netaddr->r_addr); | ||
264 | |||
265 | return p; | ||
266 | } | ||
267 | |||
268 | /* | ||
269 | * struct pnfs_osd_targetaddr { | ||
270 | * u32 ota_available; | ||
271 | * struct pnfs_osd_net_addr ota_netaddr; | ||
272 | * }; | ||
273 | */ | ||
274 | static __be32 * | ||
275 | __read_targetaddr(__be32 *p, struct pnfs_osd_targetaddr *targetaddr) | ||
276 | { | ||
277 | u32 ota_available; | ||
278 | |||
279 | ota_available = be32_to_cpup(p++); | ||
280 | targetaddr->ota_available = ota_available; | ||
281 | |||
282 | if (ota_available) | ||
283 | p = __read_net_addr(p, &targetaddr->ota_netaddr); | ||
284 | |||
285 | |||
286 | return p; | ||
287 | } | ||
288 | |||
289 | /* | ||
290 | * struct pnfs_osd_deviceaddr { | ||
291 | * struct pnfs_osd_targetid oda_targetid; | ||
292 | * struct pnfs_osd_targetaddr oda_targetaddr; | ||
293 | * u8 oda_lun[8]; | ||
294 | * struct nfs4_string oda_systemid; | ||
295 | * struct pnfs_osd_object_cred oda_root_obj_cred; | ||
296 | * struct nfs4_string oda_osdname; | ||
297 | * }; | ||
298 | */ | ||
299 | |||
300 | /* We need this version for the pnfs_osd_xdr_decode_deviceaddr which does | ||
301 | * not have an xdr_stream | ||
302 | */ | ||
303 | static __be32 * | ||
304 | __read_opaque_cred(__be32 *p, | ||
305 | struct pnfs_osd_opaque_cred *opaque_cred) | ||
306 | { | ||
307 | opaque_cred->cred_len = be32_to_cpu(*p++); | ||
308 | opaque_cred->cred = p; | ||
309 | return p + XDR_QUADLEN(opaque_cred->cred_len); | ||
310 | } | ||
311 | |||
312 | static __be32 * | ||
313 | __read_object_cred(__be32 *p, struct pnfs_osd_object_cred *comp) | ||
314 | { | ||
315 | p = _osd_xdr_decode_objid(p, &comp->oc_object_id); | ||
316 | comp->oc_osd_version = be32_to_cpup(p++); | ||
317 | comp->oc_cap_key_sec = be32_to_cpup(p++); | ||
318 | |||
319 | p = __read_opaque_cred(p, &comp->oc_cap_key); | ||
320 | p = __read_opaque_cred(p, &comp->oc_cap); | ||
321 | return p; | ||
322 | } | ||
323 | |||
324 | void pnfs_osd_xdr_decode_deviceaddr( | ||
325 | struct pnfs_osd_deviceaddr *deviceaddr, __be32 *p) | ||
326 | { | ||
327 | p = __read_targetid(p, &deviceaddr->oda_targetid); | ||
328 | |||
329 | p = __read_targetaddr(p, &deviceaddr->oda_targetaddr); | ||
330 | |||
331 | p = xdr_decode_opaque_fixed(p, deviceaddr->oda_lun, | ||
332 | sizeof(deviceaddr->oda_lun)); | ||
333 | |||
334 | p = __read_u8_opaque(p, &deviceaddr->oda_systemid); | ||
335 | |||
336 | p = __read_object_cred(p, &deviceaddr->oda_root_obj_cred); | ||
337 | |||
338 | p = __read_u8_opaque(p, &deviceaddr->oda_osdname); | ||
339 | |||
340 | /* libosd likes this terminated in dbg. It's last, so no problems */ | ||
341 | deviceaddr->oda_osdname.data[deviceaddr->oda_osdname.len] = 0; | ||
342 | } | ||
343 | |||
344 | /* | ||
345 | * struct pnfs_osd_layoutupdate { | ||
346 | * u32 dsu_valid; | ||
347 | * s64 dsu_delta; | ||
348 | * u32 olu_ioerr_flag; | ||
349 | * }; xdr size 4 + 8 + 4 | ||
350 | */ | ||
351 | int | ||
352 | pnfs_osd_xdr_encode_layoutupdate(struct xdr_stream *xdr, | ||
353 | struct pnfs_osd_layoutupdate *lou) | ||
354 | { | ||
355 | __be32 *p = xdr_reserve_space(xdr, 4 + 8 + 4); | ||
356 | |||
357 | if (!p) | ||
358 | return -E2BIG; | ||
359 | |||
360 | *p++ = cpu_to_be32(lou->dsu_valid); | ||
361 | if (lou->dsu_valid) | ||
362 | p = xdr_encode_hyper(p, lou->dsu_delta); | ||
363 | *p++ = cpu_to_be32(lou->olu_ioerr_flag); | ||
364 | return 0; | ||
365 | } | ||
366 | |||
367 | /* | ||
368 | * struct pnfs_osd_objid { | ||
369 | * struct nfs4_deviceid oid_device_id; | ||
370 | * u64 oid_partition_id; | ||
371 | * u64 oid_object_id; | ||
372 | * }; // xdr size 32 bytes | ||
373 | */ | ||
374 | static inline __be32 * | ||
375 | pnfs_osd_xdr_encode_objid(__be32 *p, struct pnfs_osd_objid *object_id) | ||
376 | { | ||
377 | p = xdr_encode_opaque_fixed(p, &object_id->oid_device_id.data, | ||
378 | sizeof(object_id->oid_device_id.data)); | ||
379 | p = xdr_encode_hyper(p, object_id->oid_partition_id); | ||
380 | p = xdr_encode_hyper(p, object_id->oid_object_id); | ||
381 | |||
382 | return p; | ||
383 | } | ||
384 | |||
385 | /* | ||
386 | * struct pnfs_osd_ioerr { | ||
387 | * struct pnfs_osd_objid oer_component; | ||
388 | * u64 oer_comp_offset; | ||
389 | * u64 oer_comp_length; | ||
390 | * u32 oer_iswrite; | ||
391 | * u32 oer_errno; | ||
392 | * }; // xdr size 32 + 24 bytes | ||
393 | */ | ||
394 | void pnfs_osd_xdr_encode_ioerr(__be32 *p, struct pnfs_osd_ioerr *ioerr) | ||
395 | { | ||
396 | p = pnfs_osd_xdr_encode_objid(p, &ioerr->oer_component); | ||
397 | p = xdr_encode_hyper(p, ioerr->oer_comp_offset); | ||
398 | p = xdr_encode_hyper(p, ioerr->oer_comp_length); | ||
399 | *p++ = cpu_to_be32(ioerr->oer_iswrite); | ||
400 | *p = cpu_to_be32(ioerr->oer_errno); | ||
401 | } | ||
402 | |||
403 | __be32 *pnfs_osd_xdr_ioerr_reserve_space(struct xdr_stream *xdr) | ||
404 | { | ||
405 | __be32 *p; | ||
406 | |||
407 | p = xdr_reserve_space(xdr, 32 + 24); | ||
408 | if (unlikely(!p)) | ||
409 | dprintk("%s: out of xdr space\n", __func__); | ||
410 | |||
411 | return p; | ||
412 | } | ||
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index c80add6e2213..7913961aff22 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c | |||
@@ -204,6 +204,21 @@ nfs_wait_on_request(struct nfs_page *req) | |||
204 | TASK_UNINTERRUPTIBLE); | 204 | TASK_UNINTERRUPTIBLE); |
205 | } | 205 | } |
206 | 206 | ||
207 | static bool nfs_generic_pg_test(struct nfs_pageio_descriptor *desc, struct nfs_page *prev, struct nfs_page *req) | ||
208 | { | ||
209 | /* | ||
210 | * FIXME: ideally we should be able to coalesce all requests | ||
211 | * that are not block boundary aligned, but currently this | ||
212 | * is problematic for the case of bsize < PAGE_CACHE_SIZE, | ||
213 | * since nfs_flush_multi and nfs_pagein_multi assume you | ||
214 | * can have only one struct nfs_page. | ||
215 | */ | ||
216 | if (desc->pg_bsize < PAGE_SIZE) | ||
217 | return 0; | ||
218 | |||
219 | return desc->pg_count + req->wb_bytes <= desc->pg_bsize; | ||
220 | } | ||
221 | |||
207 | /** | 222 | /** |
208 | * nfs_pageio_init - initialise a page io descriptor | 223 | * nfs_pageio_init - initialise a page io descriptor |
209 | * @desc: pointer to descriptor | 224 | * @desc: pointer to descriptor |
@@ -229,6 +244,8 @@ void nfs_pageio_init(struct nfs_pageio_descriptor *desc, | |||
229 | desc->pg_ioflags = io_flags; | 244 | desc->pg_ioflags = io_flags; |
230 | desc->pg_error = 0; | 245 | desc->pg_error = 0; |
231 | desc->pg_lseg = NULL; | 246 | desc->pg_lseg = NULL; |
247 | desc->pg_test = nfs_generic_pg_test; | ||
248 | pnfs_pageio_init(desc, inode); | ||
232 | } | 249 | } |
233 | 250 | ||
234 | /** | 251 | /** |
@@ -242,29 +259,23 @@ void nfs_pageio_init(struct nfs_pageio_descriptor *desc, | |||
242 | * | 259 | * |
243 | * Return 'true' if this is the case, else return 'false'. | 260 | * Return 'true' if this is the case, else return 'false'. |
244 | */ | 261 | */ |
245 | static int nfs_can_coalesce_requests(struct nfs_page *prev, | 262 | static bool nfs_can_coalesce_requests(struct nfs_page *prev, |
246 | struct nfs_page *req, | 263 | struct nfs_page *req, |
247 | struct nfs_pageio_descriptor *pgio) | 264 | struct nfs_pageio_descriptor *pgio) |
248 | { | 265 | { |
249 | if (req->wb_context->cred != prev->wb_context->cred) | 266 | if (req->wb_context->cred != prev->wb_context->cred) |
250 | return 0; | 267 | return false; |
251 | if (req->wb_lock_context->lockowner != prev->wb_lock_context->lockowner) | 268 | if (req->wb_lock_context->lockowner != prev->wb_lock_context->lockowner) |
252 | return 0; | 269 | return false; |
253 | if (req->wb_context->state != prev->wb_context->state) | 270 | if (req->wb_context->state != prev->wb_context->state) |
254 | return 0; | 271 | return false; |
255 | if (req->wb_index != (prev->wb_index + 1)) | 272 | if (req->wb_index != (prev->wb_index + 1)) |
256 | return 0; | 273 | return false; |
257 | if (req->wb_pgbase != 0) | 274 | if (req->wb_pgbase != 0) |
258 | return 0; | 275 | return false; |
259 | if (prev->wb_pgbase + prev->wb_bytes != PAGE_CACHE_SIZE) | 276 | if (prev->wb_pgbase + prev->wb_bytes != PAGE_CACHE_SIZE) |
260 | return 0; | 277 | return false; |
261 | /* | 278 | return pgio->pg_test(pgio, prev, req); |
262 | * Non-whole file layouts need to check that req is inside of | ||
263 | * pgio->pg_lseg. | ||
264 | */ | ||
265 | if (pgio->pg_test && !pgio->pg_test(pgio, prev, req)) | ||
266 | return 0; | ||
267 | return 1; | ||
268 | } | 279 | } |
269 | 280 | ||
270 | /** | 281 | /** |
@@ -278,31 +289,18 @@ static int nfs_can_coalesce_requests(struct nfs_page *prev, | |||
278 | static int nfs_pageio_do_add_request(struct nfs_pageio_descriptor *desc, | 289 | static int nfs_pageio_do_add_request(struct nfs_pageio_descriptor *desc, |
279 | struct nfs_page *req) | 290 | struct nfs_page *req) |
280 | { | 291 | { |
281 | size_t newlen = req->wb_bytes; | ||
282 | |||
283 | if (desc->pg_count != 0) { | 292 | if (desc->pg_count != 0) { |
284 | struct nfs_page *prev; | 293 | struct nfs_page *prev; |
285 | 294 | ||
286 | /* | ||
287 | * FIXME: ideally we should be able to coalesce all requests | ||
288 | * that are not block boundary aligned, but currently this | ||
289 | * is problematic for the case of bsize < PAGE_CACHE_SIZE, | ||
290 | * since nfs_flush_multi and nfs_pagein_multi assume you | ||
291 | * can have only one struct nfs_page. | ||
292 | */ | ||
293 | if (desc->pg_bsize < PAGE_SIZE) | ||
294 | return 0; | ||
295 | newlen += desc->pg_count; | ||
296 | if (newlen > desc->pg_bsize) | ||
297 | return 0; | ||
298 | prev = nfs_list_entry(desc->pg_list.prev); | 295 | prev = nfs_list_entry(desc->pg_list.prev); |
299 | if (!nfs_can_coalesce_requests(prev, req, desc)) | 296 | if (!nfs_can_coalesce_requests(prev, req, desc)) |
300 | return 0; | 297 | return 0; |
301 | } else | 298 | } else { |
302 | desc->pg_base = req->wb_pgbase; | 299 | desc->pg_base = req->wb_pgbase; |
300 | } | ||
303 | nfs_list_remove_request(req); | 301 | nfs_list_remove_request(req); |
304 | nfs_list_add_request(req, &desc->pg_list); | 302 | nfs_list_add_request(req, &desc->pg_list); |
305 | desc->pg_count = newlen; | 303 | desc->pg_count += req->wb_bytes; |
306 | return 1; | 304 | return 1; |
307 | } | 305 | } |
308 | 306 | ||
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index f57f5281a520..8c1309d852a6 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c | |||
@@ -177,13 +177,28 @@ get_layout_hdr(struct pnfs_layout_hdr *lo) | |||
177 | atomic_inc(&lo->plh_refcount); | 177 | atomic_inc(&lo->plh_refcount); |
178 | } | 178 | } |
179 | 179 | ||
180 | static struct pnfs_layout_hdr * | ||
181 | pnfs_alloc_layout_hdr(struct inode *ino, gfp_t gfp_flags) | ||
182 | { | ||
183 | struct pnfs_layoutdriver_type *ld = NFS_SERVER(ino)->pnfs_curr_ld; | ||
184 | return ld->alloc_layout_hdr ? ld->alloc_layout_hdr(ino, gfp_flags) : | ||
185 | kzalloc(sizeof(struct pnfs_layout_hdr), gfp_flags); | ||
186 | } | ||
187 | |||
188 | static void | ||
189 | pnfs_free_layout_hdr(struct pnfs_layout_hdr *lo) | ||
190 | { | ||
191 | struct pnfs_layoutdriver_type *ld = NFS_SERVER(lo->plh_inode)->pnfs_curr_ld; | ||
192 | return ld->alloc_layout_hdr ? ld->free_layout_hdr(lo) : kfree(lo); | ||
193 | } | ||
194 | |||
180 | static void | 195 | static void |
181 | destroy_layout_hdr(struct pnfs_layout_hdr *lo) | 196 | destroy_layout_hdr(struct pnfs_layout_hdr *lo) |
182 | { | 197 | { |
183 | dprintk("%s: freeing layout cache %p\n", __func__, lo); | 198 | dprintk("%s: freeing layout cache %p\n", __func__, lo); |
184 | BUG_ON(!list_empty(&lo->plh_layouts)); | 199 | BUG_ON(!list_empty(&lo->plh_layouts)); |
185 | NFS_I(lo->plh_inode)->layout = NULL; | 200 | NFS_I(lo->plh_inode)->layout = NULL; |
186 | kfree(lo); | 201 | pnfs_free_layout_hdr(lo); |
187 | } | 202 | } |
188 | 203 | ||
189 | static void | 204 | static void |
@@ -228,7 +243,7 @@ put_lseg_common(struct pnfs_layout_segment *lseg) | |||
228 | { | 243 | { |
229 | struct inode *inode = lseg->pls_layout->plh_inode; | 244 | struct inode *inode = lseg->pls_layout->plh_inode; |
230 | 245 | ||
231 | BUG_ON(test_bit(NFS_LSEG_VALID, &lseg->pls_flags)); | 246 | WARN_ON(test_bit(NFS_LSEG_VALID, &lseg->pls_flags)); |
232 | list_del_init(&lseg->pls_list); | 247 | list_del_init(&lseg->pls_list); |
233 | if (list_empty(&lseg->pls_layout->plh_segs)) { | 248 | if (list_empty(&lseg->pls_layout->plh_segs)) { |
234 | set_bit(NFS_LAYOUT_DESTROYED, &lseg->pls_layout->plh_flags); | 249 | set_bit(NFS_LAYOUT_DESTROYED, &lseg->pls_layout->plh_flags); |
@@ -261,11 +276,72 @@ put_lseg(struct pnfs_layout_segment *lseg) | |||
261 | } | 276 | } |
262 | EXPORT_SYMBOL_GPL(put_lseg); | 277 | EXPORT_SYMBOL_GPL(put_lseg); |
263 | 278 | ||
279 | static inline u64 | ||
280 | end_offset(u64 start, u64 len) | ||
281 | { | ||
282 | u64 end; | ||
283 | |||
284 | end = start + len; | ||
285 | return end >= start ? end : NFS4_MAX_UINT64; | ||
286 | } | ||
287 | |||
288 | /* last octet in a range */ | ||
289 | static inline u64 | ||
290 | last_byte_offset(u64 start, u64 len) | ||
291 | { | ||
292 | u64 end; | ||
293 | |||
294 | BUG_ON(!len); | ||
295 | end = start + len; | ||
296 | return end > start ? end - 1 : NFS4_MAX_UINT64; | ||
297 | } | ||
298 | |||
299 | /* | ||
300 | * is l2 fully contained in l1? | ||
301 | * start1 end1 | ||
302 | * [----------------------------------) | ||
303 | * start2 end2 | ||
304 | * [----------------) | ||
305 | */ | ||
306 | static inline int | ||
307 | lo_seg_contained(struct pnfs_layout_range *l1, | ||
308 | struct pnfs_layout_range *l2) | ||
309 | { | ||
310 | u64 start1 = l1->offset; | ||
311 | u64 end1 = end_offset(start1, l1->length); | ||
312 | u64 start2 = l2->offset; | ||
313 | u64 end2 = end_offset(start2, l2->length); | ||
314 | |||
315 | return (start1 <= start2) && (end1 >= end2); | ||
316 | } | ||
317 | |||
318 | /* | ||
319 | * is l1 and l2 intersecting? | ||
320 | * start1 end1 | ||
321 | * [----------------------------------) | ||
322 | * start2 end2 | ||
323 | * [----------------) | ||
324 | */ | ||
325 | static inline int | ||
326 | lo_seg_intersecting(struct pnfs_layout_range *l1, | ||
327 | struct pnfs_layout_range *l2) | ||
328 | { | ||
329 | u64 start1 = l1->offset; | ||
330 | u64 end1 = end_offset(start1, l1->length); | ||
331 | u64 start2 = l2->offset; | ||
332 | u64 end2 = end_offset(start2, l2->length); | ||
333 | |||
334 | return (end1 == NFS4_MAX_UINT64 || end1 > start2) && | ||
335 | (end2 == NFS4_MAX_UINT64 || end2 > start1); | ||
336 | } | ||
337 | |||
264 | static bool | 338 | static bool |
265 | should_free_lseg(u32 lseg_iomode, u32 recall_iomode) | 339 | should_free_lseg(struct pnfs_layout_range *lseg_range, |
340 | struct pnfs_layout_range *recall_range) | ||
266 | { | 341 | { |
267 | return (recall_iomode == IOMODE_ANY || | 342 | return (recall_range->iomode == IOMODE_ANY || |
268 | lseg_iomode == recall_iomode); | 343 | lseg_range->iomode == recall_range->iomode) && |
344 | lo_seg_intersecting(lseg_range, recall_range); | ||
269 | } | 345 | } |
270 | 346 | ||
271 | /* Returns 1 if lseg is removed from list, 0 otherwise */ | 347 | /* Returns 1 if lseg is removed from list, 0 otherwise */ |
@@ -296,7 +372,7 @@ static int mark_lseg_invalid(struct pnfs_layout_segment *lseg, | |||
296 | int | 372 | int |
297 | mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo, | 373 | mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo, |
298 | struct list_head *tmp_list, | 374 | struct list_head *tmp_list, |
299 | u32 iomode) | 375 | struct pnfs_layout_range *recall_range) |
300 | { | 376 | { |
301 | struct pnfs_layout_segment *lseg, *next; | 377 | struct pnfs_layout_segment *lseg, *next; |
302 | int invalid = 0, removed = 0; | 378 | int invalid = 0, removed = 0; |
@@ -309,7 +385,8 @@ mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo, | |||
309 | return 0; | 385 | return 0; |
310 | } | 386 | } |
311 | list_for_each_entry_safe(lseg, next, &lo->plh_segs, pls_list) | 387 | list_for_each_entry_safe(lseg, next, &lo->plh_segs, pls_list) |
312 | if (should_free_lseg(lseg->pls_range.iomode, iomode)) { | 388 | if (!recall_range || |
389 | should_free_lseg(&lseg->pls_range, recall_range)) { | ||
313 | dprintk("%s: freeing lseg %p iomode %d " | 390 | dprintk("%s: freeing lseg %p iomode %d " |
314 | "offset %llu length %llu\n", __func__, | 391 | "offset %llu length %llu\n", __func__, |
315 | lseg, lseg->pls_range.iomode, lseg->pls_range.offset, | 392 | lseg, lseg->pls_range.iomode, lseg->pls_range.offset, |
@@ -358,7 +435,7 @@ pnfs_destroy_layout(struct nfs_inode *nfsi) | |||
358 | lo = nfsi->layout; | 435 | lo = nfsi->layout; |
359 | if (lo) { | 436 | if (lo) { |
360 | lo->plh_block_lgets++; /* permanently block new LAYOUTGETs */ | 437 | lo->plh_block_lgets++; /* permanently block new LAYOUTGETs */ |
361 | mark_matching_lsegs_invalid(lo, &tmp_list, IOMODE_ANY); | 438 | mark_matching_lsegs_invalid(lo, &tmp_list, NULL); |
362 | } | 439 | } |
363 | spin_unlock(&nfsi->vfs_inode.i_lock); | 440 | spin_unlock(&nfsi->vfs_inode.i_lock); |
364 | pnfs_free_lseg_list(&tmp_list); | 441 | pnfs_free_lseg_list(&tmp_list); |
@@ -467,7 +544,7 @@ pnfs_choose_layoutget_stateid(nfs4_stateid *dst, struct pnfs_layout_hdr *lo, | |||
467 | static struct pnfs_layout_segment * | 544 | static struct pnfs_layout_segment * |
468 | send_layoutget(struct pnfs_layout_hdr *lo, | 545 | send_layoutget(struct pnfs_layout_hdr *lo, |
469 | struct nfs_open_context *ctx, | 546 | struct nfs_open_context *ctx, |
470 | u32 iomode, | 547 | struct pnfs_layout_range *range, |
471 | gfp_t gfp_flags) | 548 | gfp_t gfp_flags) |
472 | { | 549 | { |
473 | struct inode *ino = lo->plh_inode; | 550 | struct inode *ino = lo->plh_inode; |
@@ -499,11 +576,11 @@ send_layoutget(struct pnfs_layout_hdr *lo, | |||
499 | goto out_err_free; | 576 | goto out_err_free; |
500 | } | 577 | } |
501 | 578 | ||
502 | lgp->args.minlength = NFS4_MAX_UINT64; | 579 | lgp->args.minlength = PAGE_CACHE_SIZE; |
580 | if (lgp->args.minlength > range->length) | ||
581 | lgp->args.minlength = range->length; | ||
503 | lgp->args.maxcount = PNFS_LAYOUT_MAXSIZE; | 582 | lgp->args.maxcount = PNFS_LAYOUT_MAXSIZE; |
504 | lgp->args.range.iomode = iomode; | 583 | lgp->args.range = *range; |
505 | lgp->args.range.offset = 0; | ||
506 | lgp->args.range.length = NFS4_MAX_UINT64; | ||
507 | lgp->args.type = server->pnfs_curr_ld->id; | 584 | lgp->args.type = server->pnfs_curr_ld->id; |
508 | lgp->args.inode = ino; | 585 | lgp->args.inode = ino; |
509 | lgp->args.ctx = get_nfs_open_context(ctx); | 586 | lgp->args.ctx = get_nfs_open_context(ctx); |
@@ -518,7 +595,7 @@ send_layoutget(struct pnfs_layout_hdr *lo, | |||
518 | nfs4_proc_layoutget(lgp); | 595 | nfs4_proc_layoutget(lgp); |
519 | if (!lseg) { | 596 | if (!lseg) { |
520 | /* remember that LAYOUTGET failed and suspend trying */ | 597 | /* remember that LAYOUTGET failed and suspend trying */ |
521 | set_bit(lo_fail_bit(iomode), &lo->plh_flags); | 598 | set_bit(lo_fail_bit(range->iomode), &lo->plh_flags); |
522 | } | 599 | } |
523 | 600 | ||
524 | /* free xdr pages */ | 601 | /* free xdr pages */ |
@@ -542,6 +619,51 @@ out_err_free: | |||
542 | return NULL; | 619 | return NULL; |
543 | } | 620 | } |
544 | 621 | ||
622 | /* Initiates a LAYOUTRETURN(FILE) */ | ||
623 | int | ||
624 | _pnfs_return_layout(struct inode *ino) | ||
625 | { | ||
626 | struct pnfs_layout_hdr *lo = NULL; | ||
627 | struct nfs_inode *nfsi = NFS_I(ino); | ||
628 | LIST_HEAD(tmp_list); | ||
629 | struct nfs4_layoutreturn *lrp; | ||
630 | nfs4_stateid stateid; | ||
631 | int status = 0; | ||
632 | |||
633 | dprintk("--> %s\n", __func__); | ||
634 | |||
635 | spin_lock(&ino->i_lock); | ||
636 | lo = nfsi->layout; | ||
637 | if (!lo || !mark_matching_lsegs_invalid(lo, &tmp_list, NULL)) { | ||
638 | spin_unlock(&ino->i_lock); | ||
639 | dprintk("%s: no layout segments to return\n", __func__); | ||
640 | goto out; | ||
641 | } | ||
642 | stateid = nfsi->layout->plh_stateid; | ||
643 | /* Reference matched in nfs4_layoutreturn_release */ | ||
644 | get_layout_hdr(lo); | ||
645 | spin_unlock(&ino->i_lock); | ||
646 | pnfs_free_lseg_list(&tmp_list); | ||
647 | |||
648 | WARN_ON(test_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)); | ||
649 | |||
650 | lrp = kzalloc(sizeof(*lrp), GFP_KERNEL); | ||
651 | if (unlikely(lrp == NULL)) { | ||
652 | status = -ENOMEM; | ||
653 | goto out; | ||
654 | } | ||
655 | |||
656 | lrp->args.stateid = stateid; | ||
657 | lrp->args.layout_type = NFS_SERVER(ino)->pnfs_curr_ld->id; | ||
658 | lrp->args.inode = ino; | ||
659 | lrp->clp = NFS_SERVER(ino)->nfs_client; | ||
660 | |||
661 | status = nfs4_proc_layoutreturn(lrp); | ||
662 | out: | ||
663 | dprintk("<-- %s status: %d\n", __func__, status); | ||
664 | return status; | ||
665 | } | ||
666 | |||
545 | bool pnfs_roc(struct inode *ino) | 667 | bool pnfs_roc(struct inode *ino) |
546 | { | 668 | { |
547 | struct pnfs_layout_hdr *lo; | 669 | struct pnfs_layout_hdr *lo; |
@@ -625,10 +747,23 @@ bool pnfs_roc_drain(struct inode *ino, u32 *barrier) | |||
625 | * are seen first. | 747 | * are seen first. |
626 | */ | 748 | */ |
627 | static s64 | 749 | static s64 |
628 | cmp_layout(u32 iomode1, u32 iomode2) | 750 | cmp_layout(struct pnfs_layout_range *l1, |
751 | struct pnfs_layout_range *l2) | ||
629 | { | 752 | { |
753 | s64 d; | ||
754 | |||
755 | /* high offset > low offset */ | ||
756 | d = l1->offset - l2->offset; | ||
757 | if (d) | ||
758 | return d; | ||
759 | |||
760 | /* short length > long length */ | ||
761 | d = l2->length - l1->length; | ||
762 | if (d) | ||
763 | return d; | ||
764 | |||
630 | /* read > read/write */ | 765 | /* read > read/write */ |
631 | return (int)(iomode2 == IOMODE_READ) - (int)(iomode1 == IOMODE_READ); | 766 | return (int)(l1->iomode == IOMODE_READ) - (int)(l2->iomode == IOMODE_READ); |
632 | } | 767 | } |
633 | 768 | ||
634 | static void | 769 | static void |
@@ -636,13 +771,12 @@ pnfs_insert_layout(struct pnfs_layout_hdr *lo, | |||
636 | struct pnfs_layout_segment *lseg) | 771 | struct pnfs_layout_segment *lseg) |
637 | { | 772 | { |
638 | struct pnfs_layout_segment *lp; | 773 | struct pnfs_layout_segment *lp; |
639 | int found = 0; | ||
640 | 774 | ||
641 | dprintk("%s:Begin\n", __func__); | 775 | dprintk("%s:Begin\n", __func__); |
642 | 776 | ||
643 | assert_spin_locked(&lo->plh_inode->i_lock); | 777 | assert_spin_locked(&lo->plh_inode->i_lock); |
644 | list_for_each_entry(lp, &lo->plh_segs, pls_list) { | 778 | list_for_each_entry(lp, &lo->plh_segs, pls_list) { |
645 | if (cmp_layout(lp->pls_range.iomode, lseg->pls_range.iomode) > 0) | 779 | if (cmp_layout(&lseg->pls_range, &lp->pls_range) > 0) |
646 | continue; | 780 | continue; |
647 | list_add_tail(&lseg->pls_list, &lp->pls_list); | 781 | list_add_tail(&lseg->pls_list, &lp->pls_list); |
648 | dprintk("%s: inserted lseg %p " | 782 | dprintk("%s: inserted lseg %p " |
@@ -652,16 +786,14 @@ pnfs_insert_layout(struct pnfs_layout_hdr *lo, | |||
652 | lseg->pls_range.offset, lseg->pls_range.length, | 786 | lseg->pls_range.offset, lseg->pls_range.length, |
653 | lp, lp->pls_range.iomode, lp->pls_range.offset, | 787 | lp, lp->pls_range.iomode, lp->pls_range.offset, |
654 | lp->pls_range.length); | 788 | lp->pls_range.length); |
655 | found = 1; | 789 | goto out; |
656 | break; | ||
657 | } | ||
658 | if (!found) { | ||
659 | list_add_tail(&lseg->pls_list, &lo->plh_segs); | ||
660 | dprintk("%s: inserted lseg %p " | ||
661 | "iomode %d offset %llu length %llu at tail\n", | ||
662 | __func__, lseg, lseg->pls_range.iomode, | ||
663 | lseg->pls_range.offset, lseg->pls_range.length); | ||
664 | } | 790 | } |
791 | list_add_tail(&lseg->pls_list, &lo->plh_segs); | ||
792 | dprintk("%s: inserted lseg %p " | ||
793 | "iomode %d offset %llu length %llu at tail\n", | ||
794 | __func__, lseg, lseg->pls_range.iomode, | ||
795 | lseg->pls_range.offset, lseg->pls_range.length); | ||
796 | out: | ||
665 | get_layout_hdr(lo); | 797 | get_layout_hdr(lo); |
666 | 798 | ||
667 | dprintk("%s:Return\n", __func__); | 799 | dprintk("%s:Return\n", __func__); |
@@ -672,7 +804,7 @@ alloc_init_layout_hdr(struct inode *ino, gfp_t gfp_flags) | |||
672 | { | 804 | { |
673 | struct pnfs_layout_hdr *lo; | 805 | struct pnfs_layout_hdr *lo; |
674 | 806 | ||
675 | lo = kzalloc(sizeof(struct pnfs_layout_hdr), gfp_flags); | 807 | lo = pnfs_alloc_layout_hdr(ino, gfp_flags); |
676 | if (!lo) | 808 | if (!lo) |
677 | return NULL; | 809 | return NULL; |
678 | atomic_set(&lo->plh_refcount, 1); | 810 | atomic_set(&lo->plh_refcount, 1); |
@@ -705,7 +837,7 @@ pnfs_find_alloc_layout(struct inode *ino, gfp_t gfp_flags) | |||
705 | if (likely(nfsi->layout == NULL)) /* Won the race? */ | 837 | if (likely(nfsi->layout == NULL)) /* Won the race? */ |
706 | nfsi->layout = new; | 838 | nfsi->layout = new; |
707 | else | 839 | else |
708 | kfree(new); | 840 | pnfs_free_layout_hdr(new); |
709 | return nfsi->layout; | 841 | return nfsi->layout; |
710 | } | 842 | } |
711 | 843 | ||
@@ -721,16 +853,28 @@ pnfs_find_alloc_layout(struct inode *ino, gfp_t gfp_flags) | |||
721 | * READ RW true | 853 | * READ RW true |
722 | */ | 854 | */ |
723 | static int | 855 | static int |
724 | is_matching_lseg(struct pnfs_layout_segment *lseg, u32 iomode) | 856 | is_matching_lseg(struct pnfs_layout_range *ls_range, |
857 | struct pnfs_layout_range *range) | ||
725 | { | 858 | { |
726 | return (iomode != IOMODE_RW || lseg->pls_range.iomode == IOMODE_RW); | 859 | struct pnfs_layout_range range1; |
860 | |||
861 | if ((range->iomode == IOMODE_RW && | ||
862 | ls_range->iomode != IOMODE_RW) || | ||
863 | !lo_seg_intersecting(ls_range, range)) | ||
864 | return 0; | ||
865 | |||
866 | /* range1 covers only the first byte in the range */ | ||
867 | range1 = *range; | ||
868 | range1.length = 1; | ||
869 | return lo_seg_contained(ls_range, &range1); | ||
727 | } | 870 | } |
728 | 871 | ||
729 | /* | 872 | /* |
730 | * lookup range in layout | 873 | * lookup range in layout |
731 | */ | 874 | */ |
732 | static struct pnfs_layout_segment * | 875 | static struct pnfs_layout_segment * |
733 | pnfs_find_lseg(struct pnfs_layout_hdr *lo, u32 iomode) | 876 | pnfs_find_lseg(struct pnfs_layout_hdr *lo, |
877 | struct pnfs_layout_range *range) | ||
734 | { | 878 | { |
735 | struct pnfs_layout_segment *lseg, *ret = NULL; | 879 | struct pnfs_layout_segment *lseg, *ret = NULL; |
736 | 880 | ||
@@ -739,11 +883,11 @@ pnfs_find_lseg(struct pnfs_layout_hdr *lo, u32 iomode) | |||
739 | assert_spin_locked(&lo->plh_inode->i_lock); | 883 | assert_spin_locked(&lo->plh_inode->i_lock); |
740 | list_for_each_entry(lseg, &lo->plh_segs, pls_list) { | 884 | list_for_each_entry(lseg, &lo->plh_segs, pls_list) { |
741 | if (test_bit(NFS_LSEG_VALID, &lseg->pls_flags) && | 885 | if (test_bit(NFS_LSEG_VALID, &lseg->pls_flags) && |
742 | is_matching_lseg(lseg, iomode)) { | 886 | is_matching_lseg(&lseg->pls_range, range)) { |
743 | ret = get_lseg(lseg); | 887 | ret = get_lseg(lseg); |
744 | break; | 888 | break; |
745 | } | 889 | } |
746 | if (cmp_layout(iomode, lseg->pls_range.iomode) > 0) | 890 | if (cmp_layout(range, &lseg->pls_range) > 0) |
747 | break; | 891 | break; |
748 | } | 892 | } |
749 | 893 | ||
@@ -759,9 +903,17 @@ pnfs_find_lseg(struct pnfs_layout_hdr *lo, u32 iomode) | |||
759 | struct pnfs_layout_segment * | 903 | struct pnfs_layout_segment * |
760 | pnfs_update_layout(struct inode *ino, | 904 | pnfs_update_layout(struct inode *ino, |
761 | struct nfs_open_context *ctx, | 905 | struct nfs_open_context *ctx, |
906 | loff_t pos, | ||
907 | u64 count, | ||
762 | enum pnfs_iomode iomode, | 908 | enum pnfs_iomode iomode, |
763 | gfp_t gfp_flags) | 909 | gfp_t gfp_flags) |
764 | { | 910 | { |
911 | struct pnfs_layout_range arg = { | ||
912 | .iomode = iomode, | ||
913 | .offset = pos, | ||
914 | .length = count, | ||
915 | }; | ||
916 | unsigned pg_offset; | ||
765 | struct nfs_inode *nfsi = NFS_I(ino); | 917 | struct nfs_inode *nfsi = NFS_I(ino); |
766 | struct nfs_client *clp = NFS_SERVER(ino)->nfs_client; | 918 | struct nfs_client *clp = NFS_SERVER(ino)->nfs_client; |
767 | struct pnfs_layout_hdr *lo; | 919 | struct pnfs_layout_hdr *lo; |
@@ -789,7 +941,7 @@ pnfs_update_layout(struct inode *ino, | |||
789 | goto out_unlock; | 941 | goto out_unlock; |
790 | 942 | ||
791 | /* Check to see if the layout for the given range already exists */ | 943 | /* Check to see if the layout for the given range already exists */ |
792 | lseg = pnfs_find_lseg(lo, iomode); | 944 | lseg = pnfs_find_lseg(lo, &arg); |
793 | if (lseg) | 945 | if (lseg) |
794 | goto out_unlock; | 946 | goto out_unlock; |
795 | 947 | ||
@@ -811,7 +963,14 @@ pnfs_update_layout(struct inode *ino, | |||
811 | spin_unlock(&clp->cl_lock); | 963 | spin_unlock(&clp->cl_lock); |
812 | } | 964 | } |
813 | 965 | ||
814 | lseg = send_layoutget(lo, ctx, iomode, gfp_flags); | 966 | pg_offset = arg.offset & ~PAGE_CACHE_MASK; |
967 | if (pg_offset) { | ||
968 | arg.offset -= pg_offset; | ||
969 | arg.length += pg_offset; | ||
970 | } | ||
971 | arg.length = PAGE_CACHE_ALIGN(arg.length); | ||
972 | |||
973 | lseg = send_layoutget(lo, ctx, &arg, gfp_flags); | ||
815 | if (!lseg && first) { | 974 | if (!lseg && first) { |
816 | spin_lock(&clp->cl_lock); | 975 | spin_lock(&clp->cl_lock); |
817 | list_del_init(&lo->plh_layouts); | 976 | list_del_init(&lo->plh_layouts); |
@@ -838,17 +997,6 @@ pnfs_layout_process(struct nfs4_layoutget *lgp) | |||
838 | struct nfs_client *clp = NFS_SERVER(ino)->nfs_client; | 997 | struct nfs_client *clp = NFS_SERVER(ino)->nfs_client; |
839 | int status = 0; | 998 | int status = 0; |
840 | 999 | ||
841 | /* Verify we got what we asked for. | ||
842 | * Note that because the xdr parsing only accepts a single | ||
843 | * element array, this can fail even if the server is behaving | ||
844 | * correctly. | ||
845 | */ | ||
846 | if (lgp->args.range.iomode > res->range.iomode || | ||
847 | res->range.offset != 0 || | ||
848 | res->range.length != NFS4_MAX_UINT64) { | ||
849 | status = -EINVAL; | ||
850 | goto out; | ||
851 | } | ||
852 | /* Inject layout blob into I/O device driver */ | 1000 | /* Inject layout blob into I/O device driver */ |
853 | lseg = NFS_SERVER(ino)->pnfs_curr_ld->alloc_lseg(lo, res, lgp->gfp_flags); | 1001 | lseg = NFS_SERVER(ino)->pnfs_curr_ld->alloc_lseg(lo, res, lgp->gfp_flags); |
854 | if (!lseg || IS_ERR(lseg)) { | 1002 | if (!lseg || IS_ERR(lseg)) { |
@@ -895,51 +1043,64 @@ out_forget_reply: | |||
895 | goto out; | 1043 | goto out; |
896 | } | 1044 | } |
897 | 1045 | ||
898 | static int pnfs_read_pg_test(struct nfs_pageio_descriptor *pgio, | 1046 | bool |
899 | struct nfs_page *prev, | 1047 | pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, |
900 | struct nfs_page *req) | 1048 | struct nfs_page *req) |
901 | { | 1049 | { |
1050 | enum pnfs_iomode access_type; | ||
1051 | gfp_t gfp_flags; | ||
1052 | |||
1053 | /* We assume that pg_ioflags == 0 iff we're reading a page */ | ||
1054 | if (pgio->pg_ioflags == 0) { | ||
1055 | access_type = IOMODE_READ; | ||
1056 | gfp_flags = GFP_KERNEL; | ||
1057 | } else { | ||
1058 | access_type = IOMODE_RW; | ||
1059 | gfp_flags = GFP_NOFS; | ||
1060 | } | ||
1061 | |||
902 | if (pgio->pg_count == prev->wb_bytes) { | 1062 | if (pgio->pg_count == prev->wb_bytes) { |
903 | /* This is first coelesce call for a series of nfs_pages */ | 1063 | /* This is first coelesce call for a series of nfs_pages */ |
904 | pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, | 1064 | pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, |
905 | prev->wb_context, | 1065 | prev->wb_context, |
906 | IOMODE_READ, | 1066 | req_offset(req), |
907 | GFP_KERNEL); | 1067 | pgio->pg_count, |
1068 | access_type, | ||
1069 | gfp_flags); | ||
1070 | return true; | ||
908 | } | 1071 | } |
909 | return NFS_SERVER(pgio->pg_inode)->pnfs_curr_ld->pg_test(pgio, prev, req); | ||
910 | } | ||
911 | 1072 | ||
912 | void | 1073 | if (pgio->pg_lseg && |
913 | pnfs_pageio_init_read(struct nfs_pageio_descriptor *pgio, struct inode *inode) | 1074 | req_offset(req) > end_offset(pgio->pg_lseg->pls_range.offset, |
914 | { | 1075 | pgio->pg_lseg->pls_range.length)) |
915 | struct pnfs_layoutdriver_type *ld; | 1076 | return false; |
916 | 1077 | ||
917 | ld = NFS_SERVER(inode)->pnfs_curr_ld; | 1078 | return true; |
918 | pgio->pg_test = (ld && ld->pg_test) ? pnfs_read_pg_test : NULL; | ||
919 | } | 1079 | } |
1080 | EXPORT_SYMBOL_GPL(pnfs_generic_pg_test); | ||
920 | 1081 | ||
921 | static int pnfs_write_pg_test(struct nfs_pageio_descriptor *pgio, | 1082 | /* |
922 | struct nfs_page *prev, | 1083 | * Called by non rpc-based layout drivers |
923 | struct nfs_page *req) | 1084 | */ |
1085 | int | ||
1086 | pnfs_ld_write_done(struct nfs_write_data *data) | ||
924 | { | 1087 | { |
925 | if (pgio->pg_count == prev->wb_bytes) { | 1088 | int status; |
926 | /* This is first coelesce call for a series of nfs_pages */ | ||
927 | pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, | ||
928 | prev->wb_context, | ||
929 | IOMODE_RW, | ||
930 | GFP_NOFS); | ||
931 | } | ||
932 | return NFS_SERVER(pgio->pg_inode)->pnfs_curr_ld->pg_test(pgio, prev, req); | ||
933 | } | ||
934 | 1089 | ||
935 | void | 1090 | if (!data->pnfs_error) { |
936 | pnfs_pageio_init_write(struct nfs_pageio_descriptor *pgio, struct inode *inode) | 1091 | pnfs_set_layoutcommit(data); |
937 | { | 1092 | data->mds_ops->rpc_call_done(&data->task, data); |
938 | struct pnfs_layoutdriver_type *ld; | 1093 | data->mds_ops->rpc_release(data); |
1094 | return 0; | ||
1095 | } | ||
939 | 1096 | ||
940 | ld = NFS_SERVER(inode)->pnfs_curr_ld; | 1097 | dprintk("%s: pnfs_error=%d, retry via MDS\n", __func__, |
941 | pgio->pg_test = (ld && ld->pg_test) ? pnfs_write_pg_test : NULL; | 1098 | data->pnfs_error); |
1099 | status = nfs_initiate_write(data, NFS_CLIENT(data->inode), | ||
1100 | data->mds_ops, NFS_FILE_SYNC); | ||
1101 | return status ? : -EAGAIN; | ||
942 | } | 1102 | } |
1103 | EXPORT_SYMBOL_GPL(pnfs_ld_write_done); | ||
943 | 1104 | ||
944 | enum pnfs_try_status | 1105 | enum pnfs_try_status |
945 | pnfs_try_to_write_data(struct nfs_write_data *wdata, | 1106 | pnfs_try_to_write_data(struct nfs_write_data *wdata, |
@@ -966,6 +1127,29 @@ pnfs_try_to_write_data(struct nfs_write_data *wdata, | |||
966 | } | 1127 | } |
967 | 1128 | ||
968 | /* | 1129 | /* |
1130 | * Called by non rpc-based layout drivers | ||
1131 | */ | ||
1132 | int | ||
1133 | pnfs_ld_read_done(struct nfs_read_data *data) | ||
1134 | { | ||
1135 | int status; | ||
1136 | |||
1137 | if (!data->pnfs_error) { | ||
1138 | __nfs4_read_done_cb(data); | ||
1139 | data->mds_ops->rpc_call_done(&data->task, data); | ||
1140 | data->mds_ops->rpc_release(data); | ||
1141 | return 0; | ||
1142 | } | ||
1143 | |||
1144 | dprintk("%s: pnfs_error=%d, retry via MDS\n", __func__, | ||
1145 | data->pnfs_error); | ||
1146 | status = nfs_initiate_read(data, NFS_CLIENT(data->inode), | ||
1147 | data->mds_ops); | ||
1148 | return status ? : -EAGAIN; | ||
1149 | } | ||
1150 | EXPORT_SYMBOL_GPL(pnfs_ld_read_done); | ||
1151 | |||
1152 | /* | ||
969 | * Call the appropriate parallel I/O subsystem read function. | 1153 | * Call the appropriate parallel I/O subsystem read function. |
970 | */ | 1154 | */ |
971 | enum pnfs_try_status | 1155 | enum pnfs_try_status |
@@ -1009,7 +1193,7 @@ void | |||
1009 | pnfs_set_layoutcommit(struct nfs_write_data *wdata) | 1193 | pnfs_set_layoutcommit(struct nfs_write_data *wdata) |
1010 | { | 1194 | { |
1011 | struct nfs_inode *nfsi = NFS_I(wdata->inode); | 1195 | struct nfs_inode *nfsi = NFS_I(wdata->inode); |
1012 | loff_t end_pos = wdata->args.offset + wdata->res.count; | 1196 | loff_t end_pos = wdata->mds_offset + wdata->res.count; |
1013 | bool mark_as_dirty = false; | 1197 | bool mark_as_dirty = false; |
1014 | 1198 | ||
1015 | spin_lock(&nfsi->vfs_inode.i_lock); | 1199 | spin_lock(&nfsi->vfs_inode.i_lock); |
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h index 0c015bad9e7a..48d0a8e4d062 100644 --- a/fs/nfs/pnfs.h +++ b/fs/nfs/pnfs.h | |||
@@ -30,6 +30,7 @@ | |||
30 | #ifndef FS_NFS_PNFS_H | 30 | #ifndef FS_NFS_PNFS_H |
31 | #define FS_NFS_PNFS_H | 31 | #define FS_NFS_PNFS_H |
32 | 32 | ||
33 | #include <linux/nfs_fs.h> | ||
33 | #include <linux/nfs_page.h> | 34 | #include <linux/nfs_page.h> |
34 | 35 | ||
35 | enum { | 36 | enum { |
@@ -64,17 +65,29 @@ enum { | |||
64 | NFS_LAYOUT_DESTROYED, /* no new use of layout allowed */ | 65 | NFS_LAYOUT_DESTROYED, /* no new use of layout allowed */ |
65 | }; | 66 | }; |
66 | 67 | ||
68 | enum layoutdriver_policy_flags { | ||
69 | /* Should the pNFS client commit and return the layout upon a setattr */ | ||
70 | PNFS_LAYOUTRET_ON_SETATTR = 1 << 0, | ||
71 | }; | ||
72 | |||
73 | struct nfs4_deviceid_node; | ||
74 | |||
67 | /* Per-layout driver specific registration structure */ | 75 | /* Per-layout driver specific registration structure */ |
68 | struct pnfs_layoutdriver_type { | 76 | struct pnfs_layoutdriver_type { |
69 | struct list_head pnfs_tblid; | 77 | struct list_head pnfs_tblid; |
70 | const u32 id; | 78 | const u32 id; |
71 | const char *name; | 79 | const char *name; |
72 | struct module *owner; | 80 | struct module *owner; |
81 | unsigned flags; | ||
82 | |||
83 | struct pnfs_layout_hdr * (*alloc_layout_hdr) (struct inode *inode, gfp_t gfp_flags); | ||
84 | void (*free_layout_hdr) (struct pnfs_layout_hdr *); | ||
85 | |||
73 | struct pnfs_layout_segment * (*alloc_lseg) (struct pnfs_layout_hdr *layoutid, struct nfs4_layoutget_res *lgr, gfp_t gfp_flags); | 86 | struct pnfs_layout_segment * (*alloc_lseg) (struct pnfs_layout_hdr *layoutid, struct nfs4_layoutget_res *lgr, gfp_t gfp_flags); |
74 | void (*free_lseg) (struct pnfs_layout_segment *lseg); | 87 | void (*free_lseg) (struct pnfs_layout_segment *lseg); |
75 | 88 | ||
76 | /* test for nfs page cache coalescing */ | 89 | /* test for nfs page cache coalescing */ |
77 | int (*pg_test)(struct nfs_pageio_descriptor *, struct nfs_page *, struct nfs_page *); | 90 | bool (*pg_test)(struct nfs_pageio_descriptor *, struct nfs_page *, struct nfs_page *); |
78 | 91 | ||
79 | /* Returns true if layoutdriver wants to divert this request to | 92 | /* Returns true if layoutdriver wants to divert this request to |
80 | * driver's commit routine. | 93 | * driver's commit routine. |
@@ -89,6 +102,16 @@ struct pnfs_layoutdriver_type { | |||
89 | */ | 102 | */ |
90 | enum pnfs_try_status (*read_pagelist) (struct nfs_read_data *nfs_data); | 103 | enum pnfs_try_status (*read_pagelist) (struct nfs_read_data *nfs_data); |
91 | enum pnfs_try_status (*write_pagelist) (struct nfs_write_data *nfs_data, int how); | 104 | enum pnfs_try_status (*write_pagelist) (struct nfs_write_data *nfs_data, int how); |
105 | |||
106 | void (*free_deviceid_node) (struct nfs4_deviceid_node *); | ||
107 | |||
108 | void (*encode_layoutreturn) (struct pnfs_layout_hdr *layoutid, | ||
109 | struct xdr_stream *xdr, | ||
110 | const struct nfs4_layoutreturn_args *args); | ||
111 | |||
112 | void (*encode_layoutcommit) (struct pnfs_layout_hdr *layoutid, | ||
113 | struct xdr_stream *xdr, | ||
114 | const struct nfs4_layoutcommit_args *args); | ||
92 | }; | 115 | }; |
93 | 116 | ||
94 | struct pnfs_layout_hdr { | 117 | struct pnfs_layout_hdr { |
@@ -120,21 +143,22 @@ extern void pnfs_unregister_layoutdriver(struct pnfs_layoutdriver_type *); | |||
120 | extern int nfs4_proc_getdeviceinfo(struct nfs_server *server, | 143 | extern int nfs4_proc_getdeviceinfo(struct nfs_server *server, |
121 | struct pnfs_device *dev); | 144 | struct pnfs_device *dev); |
122 | extern int nfs4_proc_layoutget(struct nfs4_layoutget *lgp); | 145 | extern int nfs4_proc_layoutget(struct nfs4_layoutget *lgp); |
146 | extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp); | ||
123 | 147 | ||
124 | /* pnfs.c */ | 148 | /* pnfs.c */ |
125 | void get_layout_hdr(struct pnfs_layout_hdr *lo); | 149 | void get_layout_hdr(struct pnfs_layout_hdr *lo); |
126 | void put_lseg(struct pnfs_layout_segment *lseg); | 150 | void put_lseg(struct pnfs_layout_segment *lseg); |
127 | struct pnfs_layout_segment * | 151 | struct pnfs_layout_segment * |
128 | pnfs_update_layout(struct inode *ino, struct nfs_open_context *ctx, | 152 | pnfs_update_layout(struct inode *ino, struct nfs_open_context *ctx, |
129 | enum pnfs_iomode access_type, gfp_t gfp_flags); | 153 | loff_t pos, u64 count, enum pnfs_iomode access_type, |
154 | gfp_t gfp_flags); | ||
130 | void set_pnfs_layoutdriver(struct nfs_server *, u32 id); | 155 | void set_pnfs_layoutdriver(struct nfs_server *, u32 id); |
131 | void unset_pnfs_layoutdriver(struct nfs_server *); | 156 | void unset_pnfs_layoutdriver(struct nfs_server *); |
132 | enum pnfs_try_status pnfs_try_to_write_data(struct nfs_write_data *, | 157 | enum pnfs_try_status pnfs_try_to_write_data(struct nfs_write_data *, |
133 | const struct rpc_call_ops *, int); | 158 | const struct rpc_call_ops *, int); |
134 | enum pnfs_try_status pnfs_try_to_read_data(struct nfs_read_data *, | 159 | enum pnfs_try_status pnfs_try_to_read_data(struct nfs_read_data *, |
135 | const struct rpc_call_ops *); | 160 | const struct rpc_call_ops *); |
136 | void pnfs_pageio_init_read(struct nfs_pageio_descriptor *, struct inode *); | 161 | bool pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, struct nfs_page *req); |
137 | void pnfs_pageio_init_write(struct nfs_pageio_descriptor *, struct inode *); | ||
138 | int pnfs_layout_process(struct nfs4_layoutget *lgp); | 162 | int pnfs_layout_process(struct nfs4_layoutget *lgp); |
139 | void pnfs_free_lseg_list(struct list_head *tmp_list); | 163 | void pnfs_free_lseg_list(struct list_head *tmp_list); |
140 | void pnfs_destroy_layout(struct nfs_inode *); | 164 | void pnfs_destroy_layout(struct nfs_inode *); |
@@ -148,13 +172,37 @@ int pnfs_choose_layoutget_stateid(nfs4_stateid *dst, | |||
148 | struct nfs4_state *open_state); | 172 | struct nfs4_state *open_state); |
149 | int mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo, | 173 | int mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo, |
150 | struct list_head *tmp_list, | 174 | struct list_head *tmp_list, |
151 | u32 iomode); | 175 | struct pnfs_layout_range *recall_range); |
152 | bool pnfs_roc(struct inode *ino); | 176 | bool pnfs_roc(struct inode *ino); |
153 | void pnfs_roc_release(struct inode *ino); | 177 | void pnfs_roc_release(struct inode *ino); |
154 | void pnfs_roc_set_barrier(struct inode *ino, u32 barrier); | 178 | void pnfs_roc_set_barrier(struct inode *ino, u32 barrier); |
155 | bool pnfs_roc_drain(struct inode *ino, u32 *barrier); | 179 | bool pnfs_roc_drain(struct inode *ino, u32 *barrier); |
156 | void pnfs_set_layoutcommit(struct nfs_write_data *wdata); | 180 | void pnfs_set_layoutcommit(struct nfs_write_data *wdata); |
157 | int pnfs_layoutcommit_inode(struct inode *inode, bool sync); | 181 | int pnfs_layoutcommit_inode(struct inode *inode, bool sync); |
182 | int _pnfs_return_layout(struct inode *); | ||
183 | int pnfs_ld_write_done(struct nfs_write_data *); | ||
184 | int pnfs_ld_read_done(struct nfs_read_data *); | ||
185 | |||
186 | /* pnfs_dev.c */ | ||
187 | struct nfs4_deviceid_node { | ||
188 | struct hlist_node node; | ||
189 | const struct pnfs_layoutdriver_type *ld; | ||
190 | const struct nfs_client *nfs_client; | ||
191 | struct nfs4_deviceid deviceid; | ||
192 | atomic_t ref; | ||
193 | }; | ||
194 | |||
195 | void nfs4_print_deviceid(const struct nfs4_deviceid *dev_id); | ||
196 | struct nfs4_deviceid_node *nfs4_find_get_deviceid(const struct pnfs_layoutdriver_type *, const struct nfs_client *, const struct nfs4_deviceid *); | ||
197 | struct nfs4_deviceid_node *nfs4_unhash_put_deviceid(const struct pnfs_layoutdriver_type *, const struct nfs_client *, const struct nfs4_deviceid *); | ||
198 | void nfs4_delete_deviceid(const struct pnfs_layoutdriver_type *, const struct nfs_client *, const struct nfs4_deviceid *); | ||
199 | void nfs4_init_deviceid_node(struct nfs4_deviceid_node *, | ||
200 | const struct pnfs_layoutdriver_type *, | ||
201 | const struct nfs_client *, | ||
202 | const struct nfs4_deviceid *); | ||
203 | struct nfs4_deviceid_node *nfs4_insert_deviceid_node(struct nfs4_deviceid_node *); | ||
204 | bool nfs4_put_deviceid_node(struct nfs4_deviceid_node *); | ||
205 | void nfs4_deviceid_purge_client(const struct nfs_client *); | ||
158 | 206 | ||
159 | static inline int lo_fail_bit(u32 iomode) | 207 | static inline int lo_fail_bit(u32 iomode) |
160 | { | 208 | { |
@@ -223,6 +271,36 @@ static inline void pnfs_clear_request_commit(struct nfs_page *req) | |||
223 | put_lseg(req->wb_commit_lseg); | 271 | put_lseg(req->wb_commit_lseg); |
224 | } | 272 | } |
225 | 273 | ||
274 | /* Should the pNFS client commit and return the layout upon a setattr */ | ||
275 | static inline bool | ||
276 | pnfs_ld_layoutret_on_setattr(struct inode *inode) | ||
277 | { | ||
278 | if (!pnfs_enabled_sb(NFS_SERVER(inode))) | ||
279 | return false; | ||
280 | return NFS_SERVER(inode)->pnfs_curr_ld->flags & | ||
281 | PNFS_LAYOUTRET_ON_SETATTR; | ||
282 | } | ||
283 | |||
284 | static inline int pnfs_return_layout(struct inode *ino) | ||
285 | { | ||
286 | struct nfs_inode *nfsi = NFS_I(ino); | ||
287 | struct nfs_server *nfss = NFS_SERVER(ino); | ||
288 | |||
289 | if (pnfs_enabled_sb(nfss) && nfsi->layout) | ||
290 | return _pnfs_return_layout(ino); | ||
291 | |||
292 | return 0; | ||
293 | } | ||
294 | |||
295 | static inline void pnfs_pageio_init(struct nfs_pageio_descriptor *pgio, | ||
296 | struct inode *inode) | ||
297 | { | ||
298 | struct pnfs_layoutdriver_type *ld = NFS_SERVER(inode)->pnfs_curr_ld; | ||
299 | |||
300 | if (ld) | ||
301 | pgio->pg_test = ld->pg_test; | ||
302 | } | ||
303 | |||
226 | #else /* CONFIG_NFS_V4_1 */ | 304 | #else /* CONFIG_NFS_V4_1 */ |
227 | 305 | ||
228 | static inline void pnfs_destroy_all_layouts(struct nfs_client *clp) | 306 | static inline void pnfs_destroy_all_layouts(struct nfs_client *clp) |
@@ -245,7 +323,8 @@ static inline void put_lseg(struct pnfs_layout_segment *lseg) | |||
245 | 323 | ||
246 | static inline struct pnfs_layout_segment * | 324 | static inline struct pnfs_layout_segment * |
247 | pnfs_update_layout(struct inode *ino, struct nfs_open_context *ctx, | 325 | pnfs_update_layout(struct inode *ino, struct nfs_open_context *ctx, |
248 | enum pnfs_iomode access_type, gfp_t gfp_flags) | 326 | loff_t pos, u64 count, enum pnfs_iomode access_type, |
327 | gfp_t gfp_flags) | ||
249 | { | 328 | { |
250 | return NULL; | 329 | return NULL; |
251 | } | 330 | } |
@@ -264,6 +343,17 @@ pnfs_try_to_write_data(struct nfs_write_data *data, | |||
264 | return PNFS_NOT_ATTEMPTED; | 343 | return PNFS_NOT_ATTEMPTED; |
265 | } | 344 | } |
266 | 345 | ||
346 | static inline int pnfs_return_layout(struct inode *ino) | ||
347 | { | ||
348 | return 0; | ||
349 | } | ||
350 | |||
351 | static inline bool | ||
352 | pnfs_ld_layoutret_on_setattr(struct inode *inode) | ||
353 | { | ||
354 | return false; | ||
355 | } | ||
356 | |||
267 | static inline bool | 357 | static inline bool |
268 | pnfs_roc(struct inode *ino) | 358 | pnfs_roc(struct inode *ino) |
269 | { | 359 | { |
@@ -294,16 +384,9 @@ static inline void unset_pnfs_layoutdriver(struct nfs_server *s) | |||
294 | { | 384 | { |
295 | } | 385 | } |
296 | 386 | ||
297 | static inline void | 387 | static inline void pnfs_pageio_init(struct nfs_pageio_descriptor *pgio, |
298 | pnfs_pageio_init_read(struct nfs_pageio_descriptor *pgio, struct inode *ino) | 388 | struct inode *inode) |
299 | { | ||
300 | pgio->pg_test = NULL; | ||
301 | } | ||
302 | |||
303 | static inline void | ||
304 | pnfs_pageio_init_write(struct nfs_pageio_descriptor *pgio, struct inode *ino) | ||
305 | { | 389 | { |
306 | pgio->pg_test = NULL; | ||
307 | } | 390 | } |
308 | 391 | ||
309 | static inline void | 392 | static inline void |
@@ -331,6 +414,10 @@ static inline int pnfs_layoutcommit_inode(struct inode *inode, bool sync) | |||
331 | { | 414 | { |
332 | return 0; | 415 | return 0; |
333 | } | 416 | } |
417 | |||
418 | static inline void nfs4_deviceid_purge_client(struct nfs_client *ncl) | ||
419 | { | ||
420 | } | ||
334 | #endif /* CONFIG_NFS_V4_1 */ | 421 | #endif /* CONFIG_NFS_V4_1 */ |
335 | 422 | ||
336 | #endif /* FS_NFS_PNFS_H */ | 423 | #endif /* FS_NFS_PNFS_H */ |
diff --git a/fs/nfs/pnfs_dev.c b/fs/nfs/pnfs_dev.c new file mode 100644 index 000000000000..c65e133ce9c0 --- /dev/null +++ b/fs/nfs/pnfs_dev.c | |||
@@ -0,0 +1,270 @@ | |||
1 | /* | ||
2 | * Device operations for the pnfs client. | ||
3 | * | ||
4 | * Copyright (c) 2002 | ||
5 | * The Regents of the University of Michigan | ||
6 | * All Rights Reserved | ||
7 | * | ||
8 | * Dean Hildebrand <dhildebz@umich.edu> | ||
9 | * Garth Goodson <Garth.Goodson@netapp.com> | ||
10 | * | ||
11 | * Permission is granted to use, copy, create derivative works, and | ||
12 | * redistribute this software and such derivative works for any purpose, | ||
13 | * so long as the name of the University of Michigan is not used in | ||
14 | * any advertising or publicity pertaining to the use or distribution | ||
15 | * of this software without specific, written prior authorization. If | ||
16 | * the above copyright notice or any other identification of the | ||
17 | * University of Michigan is included in any copy of any portion of | ||
18 | * this software, then the disclaimer below must also be included. | ||
19 | * | ||
20 | * This software is provided as is, without representation or warranty | ||
21 | * of any kind either express or implied, including without limitation | ||
22 | * the implied warranties of merchantability, fitness for a particular | ||
23 | * purpose, or noninfringement. The Regents of the University of | ||
24 | * Michigan shall not be liable for any damages, including special, | ||
25 | * indirect, incidental, or consequential damages, with respect to any | ||
26 | * claim arising out of or in connection with the use of the software, | ||
27 | * even if it has been or is hereafter advised of the possibility of | ||
28 | * such damages. | ||
29 | */ | ||
30 | |||
31 | #include "pnfs.h" | ||
32 | |||
33 | #define NFSDBG_FACILITY NFSDBG_PNFS | ||
34 | |||
35 | /* | ||
36 | * Device ID RCU cache. A device ID is unique per server and layout type. | ||
37 | */ | ||
38 | #define NFS4_DEVICE_ID_HASH_BITS 5 | ||
39 | #define NFS4_DEVICE_ID_HASH_SIZE (1 << NFS4_DEVICE_ID_HASH_BITS) | ||
40 | #define NFS4_DEVICE_ID_HASH_MASK (NFS4_DEVICE_ID_HASH_SIZE - 1) | ||
41 | |||
42 | static struct hlist_head nfs4_deviceid_cache[NFS4_DEVICE_ID_HASH_SIZE]; | ||
43 | static DEFINE_SPINLOCK(nfs4_deviceid_lock); | ||
44 | |||
45 | void | ||
46 | nfs4_print_deviceid(const struct nfs4_deviceid *id) | ||
47 | { | ||
48 | u32 *p = (u32 *)id; | ||
49 | |||
50 | dprintk("%s: device id= [%x%x%x%x]\n", __func__, | ||
51 | p[0], p[1], p[2], p[3]); | ||
52 | } | ||
53 | EXPORT_SYMBOL_GPL(nfs4_print_deviceid); | ||
54 | |||
55 | static inline u32 | ||
56 | nfs4_deviceid_hash(const struct nfs4_deviceid *id) | ||
57 | { | ||
58 | unsigned char *cptr = (unsigned char *)id->data; | ||
59 | unsigned int nbytes = NFS4_DEVICEID4_SIZE; | ||
60 | u32 x = 0; | ||
61 | |||
62 | while (nbytes--) { | ||
63 | x *= 37; | ||
64 | x += *cptr++; | ||
65 | } | ||
66 | return x & NFS4_DEVICE_ID_HASH_MASK; | ||
67 | } | ||
68 | |||
69 | static struct nfs4_deviceid_node * | ||
70 | _lookup_deviceid(const struct pnfs_layoutdriver_type *ld, | ||
71 | const struct nfs_client *clp, const struct nfs4_deviceid *id, | ||
72 | long hash) | ||
73 | { | ||
74 | struct nfs4_deviceid_node *d; | ||
75 | struct hlist_node *n; | ||
76 | |||
77 | hlist_for_each_entry_rcu(d, n, &nfs4_deviceid_cache[hash], node) | ||
78 | if (d->ld == ld && d->nfs_client == clp && | ||
79 | !memcmp(&d->deviceid, id, sizeof(*id))) { | ||
80 | if (atomic_read(&d->ref)) | ||
81 | return d; | ||
82 | else | ||
83 | continue; | ||
84 | } | ||
85 | return NULL; | ||
86 | } | ||
87 | |||
88 | /* | ||
89 | * Lookup a deviceid in cache and get a reference count on it if found | ||
90 | * | ||
91 | * @clp nfs_client associated with deviceid | ||
92 | * @id deviceid to look up | ||
93 | */ | ||
94 | struct nfs4_deviceid_node * | ||
95 | _find_get_deviceid(const struct pnfs_layoutdriver_type *ld, | ||
96 | const struct nfs_client *clp, const struct nfs4_deviceid *id, | ||
97 | long hash) | ||
98 | { | ||
99 | struct nfs4_deviceid_node *d; | ||
100 | |||
101 | rcu_read_lock(); | ||
102 | d = _lookup_deviceid(ld, clp, id, hash); | ||
103 | if (d && !atomic_inc_not_zero(&d->ref)) | ||
104 | d = NULL; | ||
105 | rcu_read_unlock(); | ||
106 | return d; | ||
107 | } | ||
108 | |||
109 | struct nfs4_deviceid_node * | ||
110 | nfs4_find_get_deviceid(const struct pnfs_layoutdriver_type *ld, | ||
111 | const struct nfs_client *clp, const struct nfs4_deviceid *id) | ||
112 | { | ||
113 | return _find_get_deviceid(ld, clp, id, nfs4_deviceid_hash(id)); | ||
114 | } | ||
115 | EXPORT_SYMBOL_GPL(nfs4_find_get_deviceid); | ||
116 | |||
117 | /* | ||
118 | * Unhash and put deviceid | ||
119 | * | ||
120 | * @clp nfs_client associated with deviceid | ||
121 | * @id the deviceid to unhash | ||
122 | * | ||
123 | * @ret the unhashed node, if found and dereferenced to zero, NULL otherwise. | ||
124 | */ | ||
125 | struct nfs4_deviceid_node * | ||
126 | nfs4_unhash_put_deviceid(const struct pnfs_layoutdriver_type *ld, | ||
127 | const struct nfs_client *clp, const struct nfs4_deviceid *id) | ||
128 | { | ||
129 | struct nfs4_deviceid_node *d; | ||
130 | |||
131 | spin_lock(&nfs4_deviceid_lock); | ||
132 | rcu_read_lock(); | ||
133 | d = _lookup_deviceid(ld, clp, id, nfs4_deviceid_hash(id)); | ||
134 | rcu_read_unlock(); | ||
135 | if (!d) { | ||
136 | spin_unlock(&nfs4_deviceid_lock); | ||
137 | return NULL; | ||
138 | } | ||
139 | hlist_del_init_rcu(&d->node); | ||
140 | spin_unlock(&nfs4_deviceid_lock); | ||
141 | synchronize_rcu(); | ||
142 | |||
143 | /* balance the initial ref set in pnfs_insert_deviceid */ | ||
144 | if (atomic_dec_and_test(&d->ref)) | ||
145 | return d; | ||
146 | |||
147 | return NULL; | ||
148 | } | ||
149 | EXPORT_SYMBOL_GPL(nfs4_unhash_put_deviceid); | ||
150 | |||
151 | /* | ||
152 | * Delete a deviceid from cache | ||
153 | * | ||
154 | * @clp struct nfs_client qualifying the deviceid | ||
155 | * @id deviceid to delete | ||
156 | */ | ||
157 | void | ||
158 | nfs4_delete_deviceid(const struct pnfs_layoutdriver_type *ld, | ||
159 | const struct nfs_client *clp, const struct nfs4_deviceid *id) | ||
160 | { | ||
161 | struct nfs4_deviceid_node *d; | ||
162 | |||
163 | d = nfs4_unhash_put_deviceid(ld, clp, id); | ||
164 | if (!d) | ||
165 | return; | ||
166 | d->ld->free_deviceid_node(d); | ||
167 | } | ||
168 | EXPORT_SYMBOL_GPL(nfs4_delete_deviceid); | ||
169 | |||
170 | void | ||
171 | nfs4_init_deviceid_node(struct nfs4_deviceid_node *d, | ||
172 | const struct pnfs_layoutdriver_type *ld, | ||
173 | const struct nfs_client *nfs_client, | ||
174 | const struct nfs4_deviceid *id) | ||
175 | { | ||
176 | INIT_HLIST_NODE(&d->node); | ||
177 | d->ld = ld; | ||
178 | d->nfs_client = nfs_client; | ||
179 | d->deviceid = *id; | ||
180 | atomic_set(&d->ref, 1); | ||
181 | } | ||
182 | EXPORT_SYMBOL_GPL(nfs4_init_deviceid_node); | ||
183 | |||
184 | /* | ||
185 | * Uniquely initialize and insert a deviceid node into cache | ||
186 | * | ||
187 | * @new new deviceid node | ||
188 | * Note that the caller must set up the following members: | ||
189 | * new->ld | ||
190 | * new->nfs_client | ||
191 | * new->deviceid | ||
192 | * | ||
193 | * @ret the inserted node, if none found, otherwise, the found entry. | ||
194 | */ | ||
195 | struct nfs4_deviceid_node * | ||
196 | nfs4_insert_deviceid_node(struct nfs4_deviceid_node *new) | ||
197 | { | ||
198 | struct nfs4_deviceid_node *d; | ||
199 | long hash; | ||
200 | |||
201 | spin_lock(&nfs4_deviceid_lock); | ||
202 | hash = nfs4_deviceid_hash(&new->deviceid); | ||
203 | d = _find_get_deviceid(new->ld, new->nfs_client, &new->deviceid, hash); | ||
204 | if (d) { | ||
205 | spin_unlock(&nfs4_deviceid_lock); | ||
206 | return d; | ||
207 | } | ||
208 | |||
209 | hlist_add_head_rcu(&new->node, &nfs4_deviceid_cache[hash]); | ||
210 | spin_unlock(&nfs4_deviceid_lock); | ||
211 | |||
212 | return new; | ||
213 | } | ||
214 | EXPORT_SYMBOL_GPL(nfs4_insert_deviceid_node); | ||
215 | |||
216 | /* | ||
217 | * Dereference a deviceid node and delete it when its reference count drops | ||
218 | * to zero. | ||
219 | * | ||
220 | * @d deviceid node to put | ||
221 | * | ||
222 | * @ret true iff the node was deleted | ||
223 | */ | ||
224 | bool | ||
225 | nfs4_put_deviceid_node(struct nfs4_deviceid_node *d) | ||
226 | { | ||
227 | if (!atomic_dec_and_lock(&d->ref, &nfs4_deviceid_lock)) | ||
228 | return false; | ||
229 | hlist_del_init_rcu(&d->node); | ||
230 | spin_unlock(&nfs4_deviceid_lock); | ||
231 | synchronize_rcu(); | ||
232 | d->ld->free_deviceid_node(d); | ||
233 | return true; | ||
234 | } | ||
235 | EXPORT_SYMBOL_GPL(nfs4_put_deviceid_node); | ||
236 | |||
237 | static void | ||
238 | _deviceid_purge_client(const struct nfs_client *clp, long hash) | ||
239 | { | ||
240 | struct nfs4_deviceid_node *d; | ||
241 | struct hlist_node *n, *next; | ||
242 | HLIST_HEAD(tmp); | ||
243 | |||
244 | rcu_read_lock(); | ||
245 | hlist_for_each_entry_rcu(d, n, &nfs4_deviceid_cache[hash], node) | ||
246 | if (d->nfs_client == clp && atomic_read(&d->ref)) { | ||
247 | hlist_del_init_rcu(&d->node); | ||
248 | hlist_add_head(&d->node, &tmp); | ||
249 | } | ||
250 | rcu_read_unlock(); | ||
251 | |||
252 | if (hlist_empty(&tmp)) | ||
253 | return; | ||
254 | |||
255 | synchronize_rcu(); | ||
256 | hlist_for_each_entry_safe(d, n, next, &tmp, node) | ||
257 | if (atomic_dec_and_test(&d->ref)) | ||
258 | d->ld->free_deviceid_node(d); | ||
259 | } | ||
260 | |||
261 | void | ||
262 | nfs4_deviceid_purge_client(const struct nfs_client *clp) | ||
263 | { | ||
264 | long h; | ||
265 | |||
266 | spin_lock(&nfs4_deviceid_lock); | ||
267 | for (h = 0; h < NFS4_DEVICE_ID_HASH_SIZE; h++) | ||
268 | _deviceid_purge_client(clp, h); | ||
269 | spin_unlock(&nfs4_deviceid_lock); | ||
270 | } | ||
diff --git a/fs/nfs/read.c b/fs/nfs/read.c index 2bcf0dc306a1..20a7f952e244 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c | |||
@@ -288,7 +288,9 @@ static int nfs_pagein_multi(struct nfs_pageio_descriptor *desc) | |||
288 | atomic_set(&req->wb_complete, requests); | 288 | atomic_set(&req->wb_complete, requests); |
289 | 289 | ||
290 | BUG_ON(desc->pg_lseg != NULL); | 290 | BUG_ON(desc->pg_lseg != NULL); |
291 | lseg = pnfs_update_layout(desc->pg_inode, req->wb_context, IOMODE_READ, GFP_KERNEL); | 291 | lseg = pnfs_update_layout(desc->pg_inode, req->wb_context, |
292 | req_offset(req), desc->pg_count, | ||
293 | IOMODE_READ, GFP_KERNEL); | ||
292 | ClearPageError(page); | 294 | ClearPageError(page); |
293 | offset = 0; | 295 | offset = 0; |
294 | nbytes = desc->pg_count; | 296 | nbytes = desc->pg_count; |
@@ -351,7 +353,9 @@ static int nfs_pagein_one(struct nfs_pageio_descriptor *desc) | |||
351 | } | 353 | } |
352 | req = nfs_list_entry(data->pages.next); | 354 | req = nfs_list_entry(data->pages.next); |
353 | if ((!lseg) && list_is_singular(&data->pages)) | 355 | if ((!lseg) && list_is_singular(&data->pages)) |
354 | lseg = pnfs_update_layout(desc->pg_inode, req->wb_context, IOMODE_READ, GFP_KERNEL); | 356 | lseg = pnfs_update_layout(desc->pg_inode, req->wb_context, |
357 | req_offset(req), desc->pg_count, | ||
358 | IOMODE_READ, GFP_KERNEL); | ||
355 | 359 | ||
356 | ret = nfs_read_rpcsetup(req, data, &nfs_read_full_ops, desc->pg_count, | 360 | ret = nfs_read_rpcsetup(req, data, &nfs_read_full_ops, desc->pg_count, |
357 | 0, lseg); | 361 | 0, lseg); |
@@ -660,7 +664,6 @@ int nfs_readpages(struct file *filp, struct address_space *mapping, | |||
660 | if (ret == 0) | 664 | if (ret == 0) |
661 | goto read_complete; /* all pages were read */ | 665 | goto read_complete; /* all pages were read */ |
662 | 666 | ||
663 | pnfs_pageio_init_read(&pgio, inode); | ||
664 | if (rsize < PAGE_CACHE_SIZE) | 667 | if (rsize < PAGE_CACHE_SIZE) |
665 | nfs_pageio_init(&pgio, inode, nfs_pagein_multi, rsize, 0); | 668 | nfs_pageio_init(&pgio, inode, nfs_pagein_multi, rsize, 0); |
666 | else | 669 | else |
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index e288f06d3fa7..ce40e5c568ba 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -63,6 +63,7 @@ | |||
63 | #include "iostat.h" | 63 | #include "iostat.h" |
64 | #include "internal.h" | 64 | #include "internal.h" |
65 | #include "fscache.h" | 65 | #include "fscache.h" |
66 | #include "pnfs.h" | ||
66 | 67 | ||
67 | #define NFSDBG_FACILITY NFSDBG_VFS | 68 | #define NFSDBG_FACILITY NFSDBG_VFS |
68 | 69 | ||
@@ -732,6 +733,28 @@ static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt) | |||
732 | 733 | ||
733 | return 0; | 734 | return 0; |
734 | } | 735 | } |
736 | #ifdef CONFIG_NFS_V4_1 | ||
737 | void show_sessions(struct seq_file *m, struct nfs_server *server) | ||
738 | { | ||
739 | if (nfs4_has_session(server->nfs_client)) | ||
740 | seq_printf(m, ",sessions"); | ||
741 | } | ||
742 | #else | ||
743 | void show_sessions(struct seq_file *m, struct nfs_server *server) {} | ||
744 | #endif | ||
745 | |||
746 | #ifdef CONFIG_NFS_V4_1 | ||
747 | void show_pnfs(struct seq_file *m, struct nfs_server *server) | ||
748 | { | ||
749 | seq_printf(m, ",pnfs="); | ||
750 | if (server->pnfs_curr_ld) | ||
751 | seq_printf(m, "%s", server->pnfs_curr_ld->name); | ||
752 | else | ||
753 | seq_printf(m, "not configured"); | ||
754 | } | ||
755 | #else /* CONFIG_NFS_V4_1 */ | ||
756 | void show_pnfs(struct seq_file *m, struct nfs_server *server) {} | ||
757 | #endif /* CONFIG_NFS_V4_1 */ | ||
735 | 758 | ||
736 | static int nfs_show_devname(struct seq_file *m, struct vfsmount *mnt) | 759 | static int nfs_show_devname(struct seq_file *m, struct vfsmount *mnt) |
737 | { | 760 | { |
@@ -792,6 +815,8 @@ static int nfs_show_stats(struct seq_file *m, struct vfsmount *mnt) | |||
792 | seq_printf(m, "bm0=0x%x", nfss->attr_bitmask[0]); | 815 | seq_printf(m, "bm0=0x%x", nfss->attr_bitmask[0]); |
793 | seq_printf(m, ",bm1=0x%x", nfss->attr_bitmask[1]); | 816 | seq_printf(m, ",bm1=0x%x", nfss->attr_bitmask[1]); |
794 | seq_printf(m, ",acl=0x%x", nfss->acl_bitmask); | 817 | seq_printf(m, ",acl=0x%x", nfss->acl_bitmask); |
818 | show_sessions(m, nfss); | ||
819 | show_pnfs(m, nfss); | ||
795 | } | 820 | } |
796 | #endif | 821 | #endif |
797 | 822 | ||
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 49c715b4ac92..e268e3b23497 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -939,7 +939,9 @@ static int nfs_flush_multi(struct nfs_pageio_descriptor *desc) | |||
939 | atomic_set(&req->wb_complete, requests); | 939 | atomic_set(&req->wb_complete, requests); |
940 | 940 | ||
941 | BUG_ON(desc->pg_lseg); | 941 | BUG_ON(desc->pg_lseg); |
942 | lseg = pnfs_update_layout(desc->pg_inode, req->wb_context, IOMODE_RW, GFP_NOFS); | 942 | lseg = pnfs_update_layout(desc->pg_inode, req->wb_context, |
943 | req_offset(req), desc->pg_count, | ||
944 | IOMODE_RW, GFP_NOFS); | ||
943 | ClearPageError(page); | 945 | ClearPageError(page); |
944 | offset = 0; | 946 | offset = 0; |
945 | nbytes = desc->pg_count; | 947 | nbytes = desc->pg_count; |
@@ -1013,7 +1015,9 @@ static int nfs_flush_one(struct nfs_pageio_descriptor *desc) | |||
1013 | } | 1015 | } |
1014 | req = nfs_list_entry(data->pages.next); | 1016 | req = nfs_list_entry(data->pages.next); |
1015 | if ((!lseg) && list_is_singular(&data->pages)) | 1017 | if ((!lseg) && list_is_singular(&data->pages)) |
1016 | lseg = pnfs_update_layout(desc->pg_inode, req->wb_context, IOMODE_RW, GFP_NOFS); | 1018 | lseg = pnfs_update_layout(desc->pg_inode, req->wb_context, |
1019 | req_offset(req), desc->pg_count, | ||
1020 | IOMODE_RW, GFP_NOFS); | ||
1017 | 1021 | ||
1018 | if ((desc->pg_ioflags & FLUSH_COND_STABLE) && | 1022 | if ((desc->pg_ioflags & FLUSH_COND_STABLE) && |
1019 | (desc->pg_moreio || NFS_I(desc->pg_inode)->ncommit)) | 1023 | (desc->pg_moreio || NFS_I(desc->pg_inode)->ncommit)) |
@@ -1032,8 +1036,6 @@ static void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio, | |||
1032 | { | 1036 | { |
1033 | size_t wsize = NFS_SERVER(inode)->wsize; | 1037 | size_t wsize = NFS_SERVER(inode)->wsize; |
1034 | 1038 | ||
1035 | pnfs_pageio_init_write(pgio, inode); | ||
1036 | |||
1037 | if (wsize < PAGE_CACHE_SIZE) | 1039 | if (wsize < PAGE_CACHE_SIZE) |
1038 | nfs_pageio_init(pgio, inode, nfs_flush_multi, wsize, ioflags); | 1040 | nfs_pageio_init(pgio, inode, nfs_flush_multi, wsize, ioflags); |
1039 | else | 1041 | else |
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index ad000aeb21a2..b9566e46219f 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c | |||
@@ -1354,12 +1354,6 @@ exp_pseudoroot(struct svc_rqst *rqstp, struct svc_fh *fhp) | |||
1354 | if (IS_ERR(exp)) | 1354 | if (IS_ERR(exp)) |
1355 | return nfserrno(PTR_ERR(exp)); | 1355 | return nfserrno(PTR_ERR(exp)); |
1356 | rv = fh_compose(fhp, exp, exp->ex_path.dentry, NULL); | 1356 | rv = fh_compose(fhp, exp, exp->ex_path.dentry, NULL); |
1357 | if (rv) | ||
1358 | goto out; | ||
1359 | rv = check_nfsd_access(exp, rqstp); | ||
1360 | if (rv) | ||
1361 | fh_put(fhp); | ||
1362 | out: | ||
1363 | exp_put(exp); | 1357 | exp_put(exp); |
1364 | return rv; | 1358 | return rv; |
1365 | } | 1359 | } |
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c index 2247fc91d5e9..9095f3c21df9 100644 --- a/fs/nfsd/nfs3proc.c +++ b/fs/nfsd/nfs3proc.c | |||
@@ -245,7 +245,7 @@ nfsd3_proc_create(struct svc_rqst *rqstp, struct nfsd3_createargs *argp, | |||
245 | } | 245 | } |
246 | 246 | ||
247 | /* Now create the file and set attributes */ | 247 | /* Now create the file and set attributes */ |
248 | nfserr = nfsd_create_v3(rqstp, dirfhp, argp->name, argp->len, | 248 | nfserr = do_nfsd_create(rqstp, dirfhp, argp->name, argp->len, |
249 | attr, newfhp, | 249 | attr, newfhp, |
250 | argp->createmode, argp->verf, NULL, NULL); | 250 | argp->createmode, argp->verf, NULL, NULL); |
251 | 251 | ||
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index ad48faca20fc..08c6e36ab2eb 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c | |||
@@ -842,7 +842,7 @@ out: | |||
842 | return rv; | 842 | return rv; |
843 | } | 843 | } |
844 | 844 | ||
845 | __be32 *encode_entryplus_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, int namlen) | 845 | static __be32 *encode_entryplus_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, int namlen) |
846 | { | 846 | { |
847 | struct svc_fh fh; | 847 | struct svc_fh fh; |
848 | int err; | 848 | int err; |
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 5fcb1396a7e3..3a6dbd70b34b 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c | |||
@@ -196,9 +196,9 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o | |||
196 | 196 | ||
197 | /* | 197 | /* |
198 | * Note: create modes (UNCHECKED,GUARDED...) are the same | 198 | * Note: create modes (UNCHECKED,GUARDED...) are the same |
199 | * in NFSv4 as in v3. | 199 | * in NFSv4 as in v3 except EXCLUSIVE4_1. |
200 | */ | 200 | */ |
201 | status = nfsd_create_v3(rqstp, current_fh, open->op_fname.data, | 201 | status = do_nfsd_create(rqstp, current_fh, open->op_fname.data, |
202 | open->op_fname.len, &open->op_iattr, | 202 | open->op_fname.len, &open->op_iattr, |
203 | &resfh, open->op_createmode, | 203 | &resfh, open->op_createmode, |
204 | (u32 *)open->op_verf.data, | 204 | (u32 *)open->op_verf.data, |
@@ -403,7 +403,7 @@ nfsd4_putfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
403 | cstate->current_fh.fh_handle.fh_size = putfh->pf_fhlen; | 403 | cstate->current_fh.fh_handle.fh_size = putfh->pf_fhlen; |
404 | memcpy(&cstate->current_fh.fh_handle.fh_base, putfh->pf_fhval, | 404 | memcpy(&cstate->current_fh.fh_handle.fh_base, putfh->pf_fhval, |
405 | putfh->pf_fhlen); | 405 | putfh->pf_fhlen); |
406 | return fh_verify(rqstp, &cstate->current_fh, 0, NFSD_MAY_NOP); | 406 | return fh_verify(rqstp, &cstate->current_fh, 0, NFSD_MAY_BYPASS_GSS); |
407 | } | 407 | } |
408 | 408 | ||
409 | static __be32 | 409 | static __be32 |
@@ -762,6 +762,9 @@ nfsd4_secinfo(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
762 | __be32 err; | 762 | __be32 err; |
763 | 763 | ||
764 | fh_init(&resfh, NFS4_FHSIZE); | 764 | fh_init(&resfh, NFS4_FHSIZE); |
765 | err = fh_verify(rqstp, &cstate->current_fh, S_IFDIR, NFSD_MAY_EXEC); | ||
766 | if (err) | ||
767 | return err; | ||
765 | err = nfsd_lookup_dentry(rqstp, &cstate->current_fh, | 768 | err = nfsd_lookup_dentry(rqstp, &cstate->current_fh, |
766 | secinfo->si_name, secinfo->si_namelen, | 769 | secinfo->si_name, secinfo->si_namelen, |
767 | &exp, &dentry); | 770 | &exp, &dentry); |
@@ -986,6 +989,9 @@ enum nfsd4_op_flags { | |||
986 | ALLOWED_WITHOUT_FH = 1 << 0, /* No current filehandle required */ | 989 | ALLOWED_WITHOUT_FH = 1 << 0, /* No current filehandle required */ |
987 | ALLOWED_ON_ABSENT_FS = 1 << 1, /* ops processed on absent fs */ | 990 | ALLOWED_ON_ABSENT_FS = 1 << 1, /* ops processed on absent fs */ |
988 | ALLOWED_AS_FIRST_OP = 1 << 2, /* ops reqired first in compound */ | 991 | ALLOWED_AS_FIRST_OP = 1 << 2, /* ops reqired first in compound */ |
992 | /* For rfc 5661 section 2.6.3.1.1: */ | ||
993 | OP_HANDLES_WRONGSEC = 1 << 3, | ||
994 | OP_IS_PUTFH_LIKE = 1 << 4, | ||
989 | }; | 995 | }; |
990 | 996 | ||
991 | struct nfsd4_operation { | 997 | struct nfsd4_operation { |
@@ -1031,6 +1037,44 @@ static __be32 nfs41_check_op_ordering(struct nfsd4_compoundargs *args) | |||
1031 | return nfs_ok; | 1037 | return nfs_ok; |
1032 | } | 1038 | } |
1033 | 1039 | ||
1040 | static inline struct nfsd4_operation *OPDESC(struct nfsd4_op *op) | ||
1041 | { | ||
1042 | return &nfsd4_ops[op->opnum]; | ||
1043 | } | ||
1044 | |||
1045 | static bool need_wrongsec_check(struct svc_rqst *rqstp) | ||
1046 | { | ||
1047 | struct nfsd4_compoundres *resp = rqstp->rq_resp; | ||
1048 | struct nfsd4_compoundargs *argp = rqstp->rq_argp; | ||
1049 | struct nfsd4_op *this = &argp->ops[resp->opcnt - 1]; | ||
1050 | struct nfsd4_op *next = &argp->ops[resp->opcnt]; | ||
1051 | struct nfsd4_operation *thisd; | ||
1052 | struct nfsd4_operation *nextd; | ||
1053 | |||
1054 | thisd = OPDESC(this); | ||
1055 | /* | ||
1056 | * Most ops check wronsec on our own; only the putfh-like ops | ||
1057 | * have special rules. | ||
1058 | */ | ||
1059 | if (!(thisd->op_flags & OP_IS_PUTFH_LIKE)) | ||
1060 | return false; | ||
1061 | /* | ||
1062 | * rfc 5661 2.6.3.1.1.6: don't bother erroring out a | ||
1063 | * put-filehandle operation if we're not going to use the | ||
1064 | * result: | ||
1065 | */ | ||
1066 | if (argp->opcnt == resp->opcnt) | ||
1067 | return false; | ||
1068 | |||
1069 | nextd = OPDESC(next); | ||
1070 | /* | ||
1071 | * Rest of 2.6.3.1.1: certain operations will return WRONGSEC | ||
1072 | * errors themselves as necessary; others should check for them | ||
1073 | * now: | ||
1074 | */ | ||
1075 | return !(nextd->op_flags & OP_HANDLES_WRONGSEC); | ||
1076 | } | ||
1077 | |||
1034 | /* | 1078 | /* |
1035 | * COMPOUND call. | 1079 | * COMPOUND call. |
1036 | */ | 1080 | */ |
@@ -1108,7 +1152,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, | |||
1108 | goto encode_op; | 1152 | goto encode_op; |
1109 | } | 1153 | } |
1110 | 1154 | ||
1111 | opdesc = &nfsd4_ops[op->opnum]; | 1155 | opdesc = OPDESC(op); |
1112 | 1156 | ||
1113 | if (!cstate->current_fh.fh_dentry) { | 1157 | if (!cstate->current_fh.fh_dentry) { |
1114 | if (!(opdesc->op_flags & ALLOWED_WITHOUT_FH)) { | 1158 | if (!(opdesc->op_flags & ALLOWED_WITHOUT_FH)) { |
@@ -1126,6 +1170,9 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, | |||
1126 | else | 1170 | else |
1127 | BUG_ON(op->status == nfs_ok); | 1171 | BUG_ON(op->status == nfs_ok); |
1128 | 1172 | ||
1173 | if (!op->status && need_wrongsec_check(rqstp)) | ||
1174 | op->status = check_nfsd_access(cstate->current_fh.fh_export, rqstp); | ||
1175 | |||
1129 | encode_op: | 1176 | encode_op: |
1130 | /* Only from SEQUENCE */ | 1177 | /* Only from SEQUENCE */ |
1131 | if (resp->cstate.status == nfserr_replay_cache) { | 1178 | if (resp->cstate.status == nfserr_replay_cache) { |
@@ -1217,10 +1264,12 @@ static struct nfsd4_operation nfsd4_ops[] = { | |||
1217 | }, | 1264 | }, |
1218 | [OP_LOOKUP] = { | 1265 | [OP_LOOKUP] = { |
1219 | .op_func = (nfsd4op_func)nfsd4_lookup, | 1266 | .op_func = (nfsd4op_func)nfsd4_lookup, |
1267 | .op_flags = OP_HANDLES_WRONGSEC, | ||
1220 | .op_name = "OP_LOOKUP", | 1268 | .op_name = "OP_LOOKUP", |
1221 | }, | 1269 | }, |
1222 | [OP_LOOKUPP] = { | 1270 | [OP_LOOKUPP] = { |
1223 | .op_func = (nfsd4op_func)nfsd4_lookupp, | 1271 | .op_func = (nfsd4op_func)nfsd4_lookupp, |
1272 | .op_flags = OP_HANDLES_WRONGSEC, | ||
1224 | .op_name = "OP_LOOKUPP", | 1273 | .op_name = "OP_LOOKUPP", |
1225 | }, | 1274 | }, |
1226 | [OP_NVERIFY] = { | 1275 | [OP_NVERIFY] = { |
@@ -1229,6 +1278,7 @@ static struct nfsd4_operation nfsd4_ops[] = { | |||
1229 | }, | 1278 | }, |
1230 | [OP_OPEN] = { | 1279 | [OP_OPEN] = { |
1231 | .op_func = (nfsd4op_func)nfsd4_open, | 1280 | .op_func = (nfsd4op_func)nfsd4_open, |
1281 | .op_flags = OP_HANDLES_WRONGSEC, | ||
1232 | .op_name = "OP_OPEN", | 1282 | .op_name = "OP_OPEN", |
1233 | }, | 1283 | }, |
1234 | [OP_OPEN_CONFIRM] = { | 1284 | [OP_OPEN_CONFIRM] = { |
@@ -1241,17 +1291,20 @@ static struct nfsd4_operation nfsd4_ops[] = { | |||
1241 | }, | 1291 | }, |
1242 | [OP_PUTFH] = { | 1292 | [OP_PUTFH] = { |
1243 | .op_func = (nfsd4op_func)nfsd4_putfh, | 1293 | .op_func = (nfsd4op_func)nfsd4_putfh, |
1244 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, | 1294 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS |
1295 | | OP_IS_PUTFH_LIKE, | ||
1245 | .op_name = "OP_PUTFH", | 1296 | .op_name = "OP_PUTFH", |
1246 | }, | 1297 | }, |
1247 | [OP_PUTPUBFH] = { | 1298 | [OP_PUTPUBFH] = { |
1248 | .op_func = (nfsd4op_func)nfsd4_putrootfh, | 1299 | .op_func = (nfsd4op_func)nfsd4_putrootfh, |
1249 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, | 1300 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS |
1301 | | OP_IS_PUTFH_LIKE, | ||
1250 | .op_name = "OP_PUTPUBFH", | 1302 | .op_name = "OP_PUTPUBFH", |
1251 | }, | 1303 | }, |
1252 | [OP_PUTROOTFH] = { | 1304 | [OP_PUTROOTFH] = { |
1253 | .op_func = (nfsd4op_func)nfsd4_putrootfh, | 1305 | .op_func = (nfsd4op_func)nfsd4_putrootfh, |
1254 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, | 1306 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS |
1307 | | OP_IS_PUTFH_LIKE, | ||
1255 | .op_name = "OP_PUTROOTFH", | 1308 | .op_name = "OP_PUTROOTFH", |
1256 | }, | 1309 | }, |
1257 | [OP_READ] = { | 1310 | [OP_READ] = { |
@@ -1281,15 +1334,18 @@ static struct nfsd4_operation nfsd4_ops[] = { | |||
1281 | }, | 1334 | }, |
1282 | [OP_RESTOREFH] = { | 1335 | [OP_RESTOREFH] = { |
1283 | .op_func = (nfsd4op_func)nfsd4_restorefh, | 1336 | .op_func = (nfsd4op_func)nfsd4_restorefh, |
1284 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS, | 1337 | .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS |
1338 | | OP_IS_PUTFH_LIKE, | ||
1285 | .op_name = "OP_RESTOREFH", | 1339 | .op_name = "OP_RESTOREFH", |
1286 | }, | 1340 | }, |
1287 | [OP_SAVEFH] = { | 1341 | [OP_SAVEFH] = { |
1288 | .op_func = (nfsd4op_func)nfsd4_savefh, | 1342 | .op_func = (nfsd4op_func)nfsd4_savefh, |
1343 | .op_flags = OP_HANDLES_WRONGSEC, | ||
1289 | .op_name = "OP_SAVEFH", | 1344 | .op_name = "OP_SAVEFH", |
1290 | }, | 1345 | }, |
1291 | [OP_SECINFO] = { | 1346 | [OP_SECINFO] = { |
1292 | .op_func = (nfsd4op_func)nfsd4_secinfo, | 1347 | .op_func = (nfsd4op_func)nfsd4_secinfo, |
1348 | .op_flags = OP_HANDLES_WRONGSEC, | ||
1293 | .op_name = "OP_SECINFO", | 1349 | .op_name = "OP_SECINFO", |
1294 | }, | 1350 | }, |
1295 | [OP_SETATTR] = { | 1351 | [OP_SETATTR] = { |
@@ -1353,6 +1409,7 @@ static struct nfsd4_operation nfsd4_ops[] = { | |||
1353 | }, | 1409 | }, |
1354 | [OP_SECINFO_NO_NAME] = { | 1410 | [OP_SECINFO_NO_NAME] = { |
1355 | .op_func = (nfsd4op_func)nfsd4_secinfo_no_name, | 1411 | .op_func = (nfsd4op_func)nfsd4_secinfo_no_name, |
1412 | .op_flags = OP_HANDLES_WRONGSEC, | ||
1356 | .op_name = "OP_SECINFO_NO_NAME", | 1413 | .op_name = "OP_SECINFO_NO_NAME", |
1357 | }, | 1414 | }, |
1358 | }; | 1415 | }; |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 4cf04e11c66c..e98f3c2e9492 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -1519,6 +1519,9 @@ nfsd4_create_session(struct svc_rqst *rqstp, | |||
1519 | bool confirm_me = false; | 1519 | bool confirm_me = false; |
1520 | int status = 0; | 1520 | int status = 0; |
1521 | 1521 | ||
1522 | if (cr_ses->flags & ~SESSION4_FLAG_MASK_A) | ||
1523 | return nfserr_inval; | ||
1524 | |||
1522 | nfs4_lock_state(); | 1525 | nfs4_lock_state(); |
1523 | unconf = find_unconfirmed_client(&cr_ses->clientid); | 1526 | unconf = find_unconfirmed_client(&cr_ses->clientid); |
1524 | conf = find_confirmed_client(&cr_ses->clientid); | 1527 | conf = find_confirmed_client(&cr_ses->clientid); |
@@ -1637,8 +1640,9 @@ __be32 nfsd4_bind_conn_to_session(struct svc_rqst *rqstp, | |||
1637 | return nfserr_badsession; | 1640 | return nfserr_badsession; |
1638 | 1641 | ||
1639 | status = nfsd4_map_bcts_dir(&bcts->dir); | 1642 | status = nfsd4_map_bcts_dir(&bcts->dir); |
1640 | nfsd4_new_conn(rqstp, cstate->session, bcts->dir); | 1643 | if (!status) |
1641 | return nfs_ok; | 1644 | nfsd4_new_conn(rqstp, cstate->session, bcts->dir); |
1645 | return status; | ||
1642 | } | 1646 | } |
1643 | 1647 | ||
1644 | static bool nfsd4_compound_in_session(struct nfsd4_session *session, struct nfs4_sessionid *sid) | 1648 | static bool nfsd4_compound_in_session(struct nfsd4_session *session, struct nfs4_sessionid *sid) |
@@ -1725,6 +1729,13 @@ static void nfsd4_sequence_check_conn(struct nfsd4_conn *new, struct nfsd4_sessi | |||
1725 | return; | 1729 | return; |
1726 | } | 1730 | } |
1727 | 1731 | ||
1732 | static bool nfsd4_session_too_many_ops(struct svc_rqst *rqstp, struct nfsd4_session *session) | ||
1733 | { | ||
1734 | struct nfsd4_compoundargs *args = rqstp->rq_argp; | ||
1735 | |||
1736 | return args->opcnt > session->se_fchannel.maxops; | ||
1737 | } | ||
1738 | |||
1728 | __be32 | 1739 | __be32 |
1729 | nfsd4_sequence(struct svc_rqst *rqstp, | 1740 | nfsd4_sequence(struct svc_rqst *rqstp, |
1730 | struct nfsd4_compound_state *cstate, | 1741 | struct nfsd4_compound_state *cstate, |
@@ -1753,6 +1764,10 @@ nfsd4_sequence(struct svc_rqst *rqstp, | |||
1753 | if (!session) | 1764 | if (!session) |
1754 | goto out; | 1765 | goto out; |
1755 | 1766 | ||
1767 | status = nfserr_too_many_ops; | ||
1768 | if (nfsd4_session_too_many_ops(rqstp, session)) | ||
1769 | goto out; | ||
1770 | |||
1756 | status = nfserr_badslot; | 1771 | status = nfserr_badslot; |
1757 | if (seq->slotid >= session->se_fchannel.maxreqs) | 1772 | if (seq->slotid >= session->se_fchannel.maxreqs) |
1758 | goto out; | 1773 | goto out; |
@@ -1808,6 +1823,8 @@ out: | |||
1808 | __be32 | 1823 | __be32 |
1809 | nfsd4_reclaim_complete(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_reclaim_complete *rc) | 1824 | nfsd4_reclaim_complete(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_reclaim_complete *rc) |
1810 | { | 1825 | { |
1826 | int status = 0; | ||
1827 | |||
1811 | if (rc->rca_one_fs) { | 1828 | if (rc->rca_one_fs) { |
1812 | if (!cstate->current_fh.fh_dentry) | 1829 | if (!cstate->current_fh.fh_dentry) |
1813 | return nfserr_nofilehandle; | 1830 | return nfserr_nofilehandle; |
@@ -1817,9 +1834,14 @@ nfsd4_reclaim_complete(struct svc_rqst *rqstp, struct nfsd4_compound_state *csta | |||
1817 | */ | 1834 | */ |
1818 | return nfs_ok; | 1835 | return nfs_ok; |
1819 | } | 1836 | } |
1837 | |||
1820 | nfs4_lock_state(); | 1838 | nfs4_lock_state(); |
1821 | if (is_client_expired(cstate->session->se_client)) { | 1839 | status = nfserr_complete_already; |
1822 | nfs4_unlock_state(); | 1840 | if (cstate->session->se_client->cl_firststate) |
1841 | goto out; | ||
1842 | |||
1843 | status = nfserr_stale_clientid; | ||
1844 | if (is_client_expired(cstate->session->se_client)) | ||
1823 | /* | 1845 | /* |
1824 | * The following error isn't really legal. | 1846 | * The following error isn't really legal. |
1825 | * But we only get here if the client just explicitly | 1847 | * But we only get here if the client just explicitly |
@@ -1827,11 +1849,13 @@ nfsd4_reclaim_complete(struct svc_rqst *rqstp, struct nfsd4_compound_state *csta | |||
1827 | * error it gets back on an operation for the dead | 1849 | * error it gets back on an operation for the dead |
1828 | * client. | 1850 | * client. |
1829 | */ | 1851 | */ |
1830 | return nfserr_stale_clientid; | 1852 | goto out; |
1831 | } | 1853 | |
1854 | status = nfs_ok; | ||
1832 | nfsd4_create_clid_dir(cstate->session->se_client); | 1855 | nfsd4_create_clid_dir(cstate->session->se_client); |
1856 | out: | ||
1833 | nfs4_unlock_state(); | 1857 | nfs4_unlock_state(); |
1834 | return nfs_ok; | 1858 | return status; |
1835 | } | 1859 | } |
1836 | 1860 | ||
1837 | __be32 | 1861 | __be32 |
@@ -2462,7 +2486,7 @@ find_delegation_file(struct nfs4_file *fp, stateid_t *stid) | |||
2462 | return NULL; | 2486 | return NULL; |
2463 | } | 2487 | } |
2464 | 2488 | ||
2465 | int share_access_to_flags(u32 share_access) | 2489 | static int share_access_to_flags(u32 share_access) |
2466 | { | 2490 | { |
2467 | share_access &= ~NFS4_SHARE_WANT_MASK; | 2491 | share_access &= ~NFS4_SHARE_WANT_MASK; |
2468 | 2492 | ||
@@ -2882,7 +2906,7 @@ out: | |||
2882 | return status; | 2906 | return status; |
2883 | } | 2907 | } |
2884 | 2908 | ||
2885 | struct lock_manager nfsd4_manager = { | 2909 | static struct lock_manager nfsd4_manager = { |
2886 | }; | 2910 | }; |
2887 | 2911 | ||
2888 | static void | 2912 | static void |
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index c6766af00d98..990181103214 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
@@ -424,15 +424,12 @@ nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access | |||
424 | static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp, struct nfsd4_bind_conn_to_session *bcts) | 424 | static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp, struct nfsd4_bind_conn_to_session *bcts) |
425 | { | 425 | { |
426 | DECODE_HEAD; | 426 | DECODE_HEAD; |
427 | u32 dummy; | ||
428 | 427 | ||
429 | READ_BUF(NFS4_MAX_SESSIONID_LEN + 8); | 428 | READ_BUF(NFS4_MAX_SESSIONID_LEN + 8); |
430 | COPYMEM(bcts->sessionid.data, NFS4_MAX_SESSIONID_LEN); | 429 | COPYMEM(bcts->sessionid.data, NFS4_MAX_SESSIONID_LEN); |
431 | READ32(bcts->dir); | 430 | READ32(bcts->dir); |
432 | /* XXX: Perhaps Tom Tucker could help us figure out how we | 431 | /* XXX: skipping ctsa_use_conn_in_rdma_mode. Perhaps Tom Tucker |
433 | * should be using ctsa_use_conn_in_rdma_mode: */ | 432 | * could help us figure out we should be using it. */ |
434 | READ32(dummy); | ||
435 | |||
436 | DECODE_TAIL; | 433 | DECODE_TAIL; |
437 | } | 434 | } |
438 | 435 | ||
@@ -588,8 +585,6 @@ nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, struct nfsd4_lockt *lockt) | |||
588 | READ_BUF(lockt->lt_owner.len); | 585 | READ_BUF(lockt->lt_owner.len); |
589 | READMEM(lockt->lt_owner.data, lockt->lt_owner.len); | 586 | READMEM(lockt->lt_owner.data, lockt->lt_owner.len); |
590 | 587 | ||
591 | if (argp->minorversion && !zero_clientid(&lockt->lt_clientid)) | ||
592 | return nfserr_inval; | ||
593 | DECODE_TAIL; | 588 | DECODE_TAIL; |
594 | } | 589 | } |
595 | 590 | ||
@@ -3120,7 +3115,7 @@ nfsd4_encode_destroy_session(struct nfsd4_compoundres *resp, int nfserr, | |||
3120 | return nfserr; | 3115 | return nfserr; |
3121 | } | 3116 | } |
3122 | 3117 | ||
3123 | __be32 | 3118 | static __be32 |
3124 | nfsd4_encode_sequence(struct nfsd4_compoundres *resp, int nfserr, | 3119 | nfsd4_encode_sequence(struct nfsd4_compoundres *resp, int nfserr, |
3125 | struct nfsd4_sequence *seq) | 3120 | struct nfsd4_sequence *seq) |
3126 | { | 3121 | { |
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 55c8e63af0be..90c6aa6d5e0f 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c | |||
@@ -344,7 +344,7 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) | |||
344 | * which clients virtually always use auth_sys for, | 344 | * which clients virtually always use auth_sys for, |
345 | * even while using RPCSEC_GSS for NFS. | 345 | * even while using RPCSEC_GSS for NFS. |
346 | */ | 346 | */ |
347 | if (access & NFSD_MAY_LOCK) | 347 | if (access & NFSD_MAY_LOCK || access & NFSD_MAY_BYPASS_GSS) |
348 | goto skip_pseudoflavor_check; | 348 | goto skip_pseudoflavor_check; |
349 | /* | 349 | /* |
350 | * Clients may expect to be able to use auth_sys during mount, | 350 | * Clients may expect to be able to use auth_sys during mount, |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 129f3c9f62d5..d5718273bb32 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -181,16 +181,10 @@ nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
181 | struct svc_export *exp; | 181 | struct svc_export *exp; |
182 | struct dentry *dparent; | 182 | struct dentry *dparent; |
183 | struct dentry *dentry; | 183 | struct dentry *dentry; |
184 | __be32 err; | ||
185 | int host_err; | 184 | int host_err; |
186 | 185 | ||
187 | dprintk("nfsd: nfsd_lookup(fh %s, %.*s)\n", SVCFH_fmt(fhp), len,name); | 186 | dprintk("nfsd: nfsd_lookup(fh %s, %.*s)\n", SVCFH_fmt(fhp), len,name); |
188 | 187 | ||
189 | /* Obtain dentry and export. */ | ||
190 | err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_EXEC); | ||
191 | if (err) | ||
192 | return err; | ||
193 | |||
194 | dparent = fhp->fh_dentry; | 188 | dparent = fhp->fh_dentry; |
195 | exp = fhp->fh_export; | 189 | exp = fhp->fh_export; |
196 | exp_get(exp); | 190 | exp_get(exp); |
@@ -254,6 +248,9 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name, | |||
254 | struct dentry *dentry; | 248 | struct dentry *dentry; |
255 | __be32 err; | 249 | __be32 err; |
256 | 250 | ||
251 | err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_EXEC); | ||
252 | if (err) | ||
253 | return err; | ||
257 | err = nfsd_lookup_dentry(rqstp, fhp, name, len, &exp, &dentry); | 254 | err = nfsd_lookup_dentry(rqstp, fhp, name, len, &exp, &dentry); |
258 | if (err) | 255 | if (err) |
259 | return err; | 256 | return err; |
@@ -877,13 +874,11 @@ static __be32 | |||
877 | nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, | 874 | nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, |
878 | loff_t offset, struct kvec *vec, int vlen, unsigned long *count) | 875 | loff_t offset, struct kvec *vec, int vlen, unsigned long *count) |
879 | { | 876 | { |
880 | struct inode *inode; | ||
881 | mm_segment_t oldfs; | 877 | mm_segment_t oldfs; |
882 | __be32 err; | 878 | __be32 err; |
883 | int host_err; | 879 | int host_err; |
884 | 880 | ||
885 | err = nfserr_perm; | 881 | err = nfserr_perm; |
886 | inode = file->f_path.dentry->d_inode; | ||
887 | 882 | ||
888 | if (file->f_op->splice_read && rqstp->rq_splice_ok) { | 883 | if (file->f_op->splice_read && rqstp->rq_splice_ok) { |
889 | struct splice_desc sd = { | 884 | struct splice_desc sd = { |
@@ -1340,11 +1335,18 @@ out_nfserr: | |||
1340 | } | 1335 | } |
1341 | 1336 | ||
1342 | #ifdef CONFIG_NFSD_V3 | 1337 | #ifdef CONFIG_NFSD_V3 |
1338 | |||
1339 | static inline int nfsd_create_is_exclusive(int createmode) | ||
1340 | { | ||
1341 | return createmode == NFS3_CREATE_EXCLUSIVE | ||
1342 | || createmode == NFS4_CREATE_EXCLUSIVE4_1; | ||
1343 | } | ||
1344 | |||
1343 | /* | 1345 | /* |
1344 | * NFSv3 version of nfsd_create | 1346 | * NFSv3 and NFSv4 version of nfsd_create |
1345 | */ | 1347 | */ |
1346 | __be32 | 1348 | __be32 |
1347 | nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, | 1349 | do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, |
1348 | char *fname, int flen, struct iattr *iap, | 1350 | char *fname, int flen, struct iattr *iap, |
1349 | struct svc_fh *resfhp, int createmode, u32 *verifier, | 1351 | struct svc_fh *resfhp, int createmode, u32 *verifier, |
1350 | int *truncp, int *created) | 1352 | int *truncp, int *created) |
@@ -1396,7 +1398,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1396 | if (err) | 1398 | if (err) |
1397 | goto out; | 1399 | goto out; |
1398 | 1400 | ||
1399 | if (createmode == NFS3_CREATE_EXCLUSIVE) { | 1401 | if (nfsd_create_is_exclusive(createmode)) { |
1400 | /* solaris7 gets confused (bugid 4218508) if these have | 1402 | /* solaris7 gets confused (bugid 4218508) if these have |
1401 | * the high bit set, so just clear the high bits. If this is | 1403 | * the high bit set, so just clear the high bits. If this is |
1402 | * ever changed to use different attrs for storing the | 1404 | * ever changed to use different attrs for storing the |
@@ -1437,6 +1439,11 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1437 | && dchild->d_inode->i_atime.tv_sec == v_atime | 1439 | && dchild->d_inode->i_atime.tv_sec == v_atime |
1438 | && dchild->d_inode->i_size == 0 ) | 1440 | && dchild->d_inode->i_size == 0 ) |
1439 | break; | 1441 | break; |
1442 | case NFS4_CREATE_EXCLUSIVE4_1: | ||
1443 | if ( dchild->d_inode->i_mtime.tv_sec == v_mtime | ||
1444 | && dchild->d_inode->i_atime.tv_sec == v_atime | ||
1445 | && dchild->d_inode->i_size == 0 ) | ||
1446 | goto set_attr; | ||
1440 | /* fallthru */ | 1447 | /* fallthru */ |
1441 | case NFS3_CREATE_GUARDED: | 1448 | case NFS3_CREATE_GUARDED: |
1442 | err = nfserr_exist; | 1449 | err = nfserr_exist; |
@@ -1455,7 +1462,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1455 | 1462 | ||
1456 | nfsd_check_ignore_resizing(iap); | 1463 | nfsd_check_ignore_resizing(iap); |
1457 | 1464 | ||
1458 | if (createmode == NFS3_CREATE_EXCLUSIVE) { | 1465 | if (nfsd_create_is_exclusive(createmode)) { |
1459 | /* Cram the verifier into atime/mtime */ | 1466 | /* Cram the verifier into atime/mtime */ |
1460 | iap->ia_valid = ATTR_MTIME|ATTR_ATIME | 1467 | iap->ia_valid = ATTR_MTIME|ATTR_ATIME |
1461 | | ATTR_MTIME_SET|ATTR_ATIME_SET; | 1468 | | ATTR_MTIME_SET|ATTR_ATIME_SET; |
@@ -2034,7 +2041,7 @@ nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp, | |||
2034 | struct inode *inode = dentry->d_inode; | 2041 | struct inode *inode = dentry->d_inode; |
2035 | int err; | 2042 | int err; |
2036 | 2043 | ||
2037 | if (acc == NFSD_MAY_NOP) | 2044 | if ((acc & NFSD_MAY_MASK) == NFSD_MAY_NOP) |
2038 | return 0; | 2045 | return 0; |
2039 | #if 0 | 2046 | #if 0 |
2040 | dprintk("nfsd: permission 0x%x%s%s%s%s%s%s%s mode 0%o%s%s%s\n", | 2047 | dprintk("nfsd: permission 0x%x%s%s%s%s%s%s%s mode 0%o%s%s%s\n", |
diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h index 9a370a5e36b7..e0bbac04d1dd 100644 --- a/fs/nfsd/vfs.h +++ b/fs/nfsd/vfs.h | |||
@@ -17,10 +17,14 @@ | |||
17 | #define NFSD_MAY_SATTR 8 | 17 | #define NFSD_MAY_SATTR 8 |
18 | #define NFSD_MAY_TRUNC 16 | 18 | #define NFSD_MAY_TRUNC 16 |
19 | #define NFSD_MAY_LOCK 32 | 19 | #define NFSD_MAY_LOCK 32 |
20 | #define NFSD_MAY_MASK 63 | ||
21 | |||
22 | /* extra hints to permission and open routines: */ | ||
20 | #define NFSD_MAY_OWNER_OVERRIDE 64 | 23 | #define NFSD_MAY_OWNER_OVERRIDE 64 |
21 | #define NFSD_MAY_LOCAL_ACCESS 128 /* IRIX doing local access check on device special file*/ | 24 | #define NFSD_MAY_LOCAL_ACCESS 128 /* IRIX doing local access check on device special file*/ |
22 | #define NFSD_MAY_BYPASS_GSS_ON_ROOT 256 | 25 | #define NFSD_MAY_BYPASS_GSS_ON_ROOT 256 |
23 | #define NFSD_MAY_NOT_BREAK_LEASE 512 | 26 | #define NFSD_MAY_NOT_BREAK_LEASE 512 |
27 | #define NFSD_MAY_BYPASS_GSS 1024 | ||
24 | 28 | ||
25 | #define NFSD_MAY_CREATE (NFSD_MAY_EXEC|NFSD_MAY_WRITE) | 29 | #define NFSD_MAY_CREATE (NFSD_MAY_EXEC|NFSD_MAY_WRITE) |
26 | #define NFSD_MAY_REMOVE (NFSD_MAY_EXEC|NFSD_MAY_WRITE|NFSD_MAY_TRUNC) | 30 | #define NFSD_MAY_REMOVE (NFSD_MAY_EXEC|NFSD_MAY_WRITE|NFSD_MAY_TRUNC) |
@@ -54,7 +58,7 @@ __be32 nfsd_create(struct svc_rqst *, struct svc_fh *, | |||
54 | int type, dev_t rdev, struct svc_fh *res); | 58 | int type, dev_t rdev, struct svc_fh *res); |
55 | #ifdef CONFIG_NFSD_V3 | 59 | #ifdef CONFIG_NFSD_V3 |
56 | __be32 nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *); | 60 | __be32 nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *); |
57 | __be32 nfsd_create_v3(struct svc_rqst *, struct svc_fh *, | 61 | __be32 do_nfsd_create(struct svc_rqst *, struct svc_fh *, |
58 | char *name, int len, struct iattr *attrs, | 62 | char *name, int len, struct iattr *attrs, |
59 | struct svc_fh *res, int createmode, | 63 | struct svc_fh *res, int createmode, |
60 | u32 *verifier, int *truncp, int *created); | 64 | u32 *verifier, int *truncp, int *created); |
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index 587f18432832..b954878ad6ce 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c | |||
@@ -917,7 +917,7 @@ int nilfs_mark_inode_dirty(struct inode *inode) | |||
917 | * construction. This function can be called both as a single operation | 917 | * construction. This function can be called both as a single operation |
918 | * and as a part of indivisible file operations. | 918 | * and as a part of indivisible file operations. |
919 | */ | 919 | */ |
920 | void nilfs_dirty_inode(struct inode *inode) | 920 | void nilfs_dirty_inode(struct inode *inode, int flags) |
921 | { | 921 | { |
922 | struct nilfs_transaction_info ti; | 922 | struct nilfs_transaction_info ti; |
923 | struct nilfs_mdt_info *mdi = NILFS_MDT(inode); | 923 | struct nilfs_mdt_info *mdi = NILFS_MDT(inode); |
diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c index 1102a5fbb744..546849b3e88f 100644 --- a/fs/nilfs2/namei.c +++ b/fs/nilfs2/namei.c | |||
@@ -334,8 +334,6 @@ static int nilfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
334 | struct nilfs_transaction_info ti; | 334 | struct nilfs_transaction_info ti; |
335 | int err; | 335 | int err; |
336 | 336 | ||
337 | dentry_unhash(dentry); | ||
338 | |||
339 | err = nilfs_transaction_begin(dir->i_sb, &ti, 0); | 337 | err = nilfs_transaction_begin(dir->i_sb, &ti, 0); |
340 | if (err) | 338 | if (err) |
341 | return err; | 339 | return err; |
@@ -371,9 +369,6 @@ static int nilfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
371 | struct nilfs_transaction_info ti; | 369 | struct nilfs_transaction_info ti; |
372 | int err; | 370 | int err; |
373 | 371 | ||
374 | if (new_inode && S_ISDIR(new_inode->i_mode)) | ||
375 | dentry_unhash(new_dentry); | ||
376 | |||
377 | err = nilfs_transaction_begin(old_dir->i_sb, &ti, 1); | 372 | err = nilfs_transaction_begin(old_dir->i_sb, &ti, 1); |
378 | if (unlikely(err)) | 373 | if (unlikely(err)) |
379 | return err; | 374 | return err; |
diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h index a9c6a531f80c..f02b9ad43a21 100644 --- a/fs/nilfs2/nilfs.h +++ b/fs/nilfs2/nilfs.h | |||
@@ -269,7 +269,7 @@ int nilfs_load_inode_block(struct inode *inode, struct buffer_head **pbh); | |||
269 | extern int nilfs_inode_dirty(struct inode *); | 269 | extern int nilfs_inode_dirty(struct inode *); |
270 | int nilfs_set_file_dirty(struct inode *inode, unsigned nr_dirty); | 270 | int nilfs_set_file_dirty(struct inode *inode, unsigned nr_dirty); |
271 | extern int nilfs_mark_inode_dirty(struct inode *); | 271 | extern int nilfs_mark_inode_dirty(struct inode *); |
272 | extern void nilfs_dirty_inode(struct inode *); | 272 | extern void nilfs_dirty_inode(struct inode *, int flags); |
273 | int nilfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | 273 | int nilfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, |
274 | __u64 start, __u64 len); | 274 | __u64 start, __u64 len); |
275 | 275 | ||
diff --git a/fs/omfs/dir.c b/fs/omfs/dir.c index c368360c35a1..3b8d3979e03b 100644 --- a/fs/omfs/dir.c +++ b/fs/omfs/dir.c | |||
@@ -241,11 +241,9 @@ static int omfs_remove(struct inode *dir, struct dentry *dentry) | |||
241 | int ret; | 241 | int ret; |
242 | 242 | ||
243 | 243 | ||
244 | if (S_ISDIR(inode->i_mode)) { | 244 | if (S_ISDIR(inode->i_mode) && |
245 | dentry_unhash(dentry); | 245 | !omfs_dir_is_empty(inode)) |
246 | if (!omfs_dir_is_empty(inode)) | 246 | return -ENOTEMPTY; |
247 | return -ENOTEMPTY; | ||
248 | } | ||
249 | 247 | ||
250 | ret = omfs_delete_entry(dentry); | 248 | ret = omfs_delete_entry(dentry); |
251 | if (ret) | 249 | if (ret) |
@@ -382,9 +380,6 @@ static int omfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
382 | int err; | 380 | int err; |
383 | 381 | ||
384 | if (new_inode) { | 382 | if (new_inode) { |
385 | if (S_ISDIR(new_inode->i_mode)) | ||
386 | dentry_unhash(new_dentry); | ||
387 | |||
388 | /* overwriting existing file/dir */ | 383 | /* overwriting existing file/dir */ |
389 | err = omfs_remove(new_dir, new_dentry); | 384 | err = omfs_remove(new_dir, new_dentry); |
390 | if (err) | 385 | if (err) |
diff --git a/fs/partitions/check.c b/fs/partitions/check.c index f82e762eeca2..d545e97d99c3 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c | |||
@@ -255,13 +255,7 @@ ssize_t part_discard_alignment_show(struct device *dev, | |||
255 | struct device_attribute *attr, char *buf) | 255 | struct device_attribute *attr, char *buf) |
256 | { | 256 | { |
257 | struct hd_struct *p = dev_to_part(dev); | 257 | struct hd_struct *p = dev_to_part(dev); |
258 | struct gendisk *disk = dev_to_disk(dev); | 258 | return sprintf(buf, "%u\n", p->discard_alignment); |
259 | unsigned int alignment = 0; | ||
260 | |||
261 | if (disk->queue) | ||
262 | alignment = queue_limit_discard_alignment(&disk->queue->limits, | ||
263 | p->start_sect); | ||
264 | return sprintf(buf, "%u\n", alignment); | ||
265 | } | 259 | } |
266 | 260 | ||
267 | ssize_t part_stat_show(struct device *dev, | 261 | ssize_t part_stat_show(struct device *dev, |
@@ -455,6 +449,8 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno, | |||
455 | p->start_sect = start; | 449 | p->start_sect = start; |
456 | p->alignment_offset = | 450 | p->alignment_offset = |
457 | queue_limit_alignment_offset(&disk->queue->limits, start); | 451 | queue_limit_alignment_offset(&disk->queue->limits, start); |
452 | p->discard_alignment = | ||
453 | queue_limit_discard_alignment(&disk->queue->limits, start); | ||
458 | p->nr_sects = len; | 454 | p->nr_sects = len; |
459 | p->partno = partno; | 455 | p->partno = partno; |
460 | p->policy = get_disk_ro(disk); | 456 | p->policy = get_disk_ro(disk); |
diff --git a/fs/proc/base.c b/fs/proc/base.c index 4ede550517a6..14def991d9dd 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -83,6 +83,9 @@ | |||
83 | #include <linux/pid_namespace.h> | 83 | #include <linux/pid_namespace.h> |
84 | #include <linux/fs_struct.h> | 84 | #include <linux/fs_struct.h> |
85 | #include <linux/slab.h> | 85 | #include <linux/slab.h> |
86 | #ifdef CONFIG_HARDWALL | ||
87 | #include <asm/hardwall.h> | ||
88 | #endif | ||
86 | #include "internal.h" | 89 | #include "internal.h" |
87 | 90 | ||
88 | /* NOTE: | 91 | /* NOTE: |
@@ -2842,6 +2845,9 @@ static const struct pid_entry tgid_base_stuff[] = { | |||
2842 | #ifdef CONFIG_TASK_IO_ACCOUNTING | 2845 | #ifdef CONFIG_TASK_IO_ACCOUNTING |
2843 | INF("io", S_IRUGO, proc_tgid_io_accounting), | 2846 | INF("io", S_IRUGO, proc_tgid_io_accounting), |
2844 | #endif | 2847 | #endif |
2848 | #ifdef CONFIG_HARDWALL | ||
2849 | INF("hardwall", S_IRUGO, proc_pid_hardwall), | ||
2850 | #endif | ||
2845 | }; | 2851 | }; |
2846 | 2852 | ||
2847 | static int proc_tgid_base_readdir(struct file * filp, | 2853 | static int proc_tgid_base_readdir(struct file * filp, |
@@ -3181,6 +3187,9 @@ static const struct pid_entry tid_base_stuff[] = { | |||
3181 | #ifdef CONFIG_TASK_IO_ACCOUNTING | 3187 | #ifdef CONFIG_TASK_IO_ACCOUNTING |
3182 | INF("io", S_IRUGO, proc_tid_io_accounting), | 3188 | INF("io", S_IRUGO, proc_tid_io_accounting), |
3183 | #endif | 3189 | #endif |
3190 | #ifdef CONFIG_HARDWALL | ||
3191 | INF("hardwall", S_IRUGO, proc_pid_hardwall), | ||
3192 | #endif | ||
3184 | }; | 3193 | }; |
3185 | 3194 | ||
3186 | static int proc_tid_base_readdir(struct file * filp, | 3195 | static int proc_tid_base_readdir(struct file * filp, |
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index 76c8164d5651..118662690cdf 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c | |||
@@ -831,8 +831,6 @@ static int reiserfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
831 | INITIALIZE_PATH(path); | 831 | INITIALIZE_PATH(path); |
832 | struct reiserfs_dir_entry de; | 832 | struct reiserfs_dir_entry de; |
833 | 833 | ||
834 | dentry_unhash(dentry); | ||
835 | |||
836 | /* we will be doing 2 balancings and update 2 stat data, we change quotas | 834 | /* we will be doing 2 balancings and update 2 stat data, we change quotas |
837 | * of the owner of the directory and of the owner of the parent directory. | 835 | * of the owner of the directory and of the owner of the parent directory. |
838 | * The quota structure is possibly deleted only on last iput => outside | 836 | * The quota structure is possibly deleted only on last iput => outside |
@@ -1227,9 +1225,6 @@ static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1227 | unsigned long savelink = 1; | 1225 | unsigned long savelink = 1; |
1228 | struct timespec ctime; | 1226 | struct timespec ctime; |
1229 | 1227 | ||
1230 | if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) | ||
1231 | dentry_unhash(new_dentry); | ||
1232 | |||
1233 | /* three balancings: (1) old name removal, (2) new name insertion | 1228 | /* three balancings: (1) old name removal, (2) new name insertion |
1234 | and (3) maybe "save" link insertion | 1229 | and (3) maybe "save" link insertion |
1235 | stat data updates: (1) old directory, | 1230 | stat data updates: (1) old directory, |
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index b216ff6be1c9..aa91089162cb 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
@@ -568,7 +568,7 @@ static void destroy_inodecache(void) | |||
568 | } | 568 | } |
569 | 569 | ||
570 | /* we don't mark inodes dirty, we just log them */ | 570 | /* we don't mark inodes dirty, we just log them */ |
571 | static void reiserfs_dirty_inode(struct inode *inode) | 571 | static void reiserfs_dirty_inode(struct inode *inode, int flags) |
572 | { | 572 | { |
573 | struct reiserfs_transaction_handle th; | 573 | struct reiserfs_transaction_handle th; |
574 | 574 | ||
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 50f1abccd1cd..e8a62f41b458 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
@@ -98,7 +98,6 @@ static int xattr_rmdir(struct inode *dir, struct dentry *dentry) | |||
98 | 98 | ||
99 | reiserfs_mutex_lock_nested_safe(&dentry->d_inode->i_mutex, | 99 | reiserfs_mutex_lock_nested_safe(&dentry->d_inode->i_mutex, |
100 | I_MUTEX_CHILD, dir->i_sb); | 100 | I_MUTEX_CHILD, dir->i_sb); |
101 | dentry_unhash(dentry); | ||
102 | error = dir->i_op->rmdir(dir, dentry); | 101 | error = dir->i_op->rmdir(dir, dentry); |
103 | if (!error) | 102 | if (!error) |
104 | dentry->d_inode->i_flags |= S_DEAD; | 103 | dentry->d_inode->i_flags |= S_DEAD; |
diff --git a/fs/squashfs/export.c b/fs/squashfs/export.c index 730c56248c9b..5e1101ff276f 100644 --- a/fs/squashfs/export.c +++ b/fs/squashfs/export.c | |||
@@ -147,7 +147,7 @@ __le64 *squashfs_read_inode_lookup_table(struct super_block *sb, | |||
147 | * table[0] points to the first inode lookup table metadata block, | 147 | * table[0] points to the first inode lookup table metadata block, |
148 | * this should be less than lookup_table_start | 148 | * this should be less than lookup_table_start |
149 | */ | 149 | */ |
150 | if (!IS_ERR(table) && table[0] >= lookup_table_start) { | 150 | if (!IS_ERR(table) && le64_to_cpu(table[0]) >= lookup_table_start) { |
151 | kfree(table); | 151 | kfree(table); |
152 | return ERR_PTR(-EINVAL); | 152 | return ERR_PTR(-EINVAL); |
153 | } | 153 | } |
diff --git a/fs/squashfs/fragment.c b/fs/squashfs/fragment.c index 1516a6490bfb..0ed6edbc5c71 100644 --- a/fs/squashfs/fragment.c +++ b/fs/squashfs/fragment.c | |||
@@ -90,7 +90,7 @@ __le64 *squashfs_read_fragment_index_table(struct super_block *sb, | |||
90 | * table[0] points to the first fragment table metadata block, this | 90 | * table[0] points to the first fragment table metadata block, this |
91 | * should be less than fragment_table_start | 91 | * should be less than fragment_table_start |
92 | */ | 92 | */ |
93 | if (!IS_ERR(table) && table[0] >= fragment_table_start) { | 93 | if (!IS_ERR(table) && le64_to_cpu(table[0]) >= fragment_table_start) { |
94 | kfree(table); | 94 | kfree(table); |
95 | return ERR_PTR(-EINVAL); | 95 | return ERR_PTR(-EINVAL); |
96 | } | 96 | } |
diff --git a/fs/squashfs/id.c b/fs/squashfs/id.c index a70858e0fb44..d38ea3dab951 100644 --- a/fs/squashfs/id.c +++ b/fs/squashfs/id.c | |||
@@ -93,7 +93,7 @@ __le64 *squashfs_read_id_index_table(struct super_block *sb, | |||
93 | * table[0] points to the first id lookup table metadata block, this | 93 | * table[0] points to the first id lookup table metadata block, this |
94 | * should be less than id_table_start | 94 | * should be less than id_table_start |
95 | */ | 95 | */ |
96 | if (!IS_ERR(table) && table[0] >= id_table_start) { | 96 | if (!IS_ERR(table) && le64_to_cpu(table[0]) >= id_table_start) { |
97 | kfree(table); | 97 | kfree(table); |
98 | return ERR_PTR(-EINVAL); | 98 | return ERR_PTR(-EINVAL); |
99 | } | 99 | } |
diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c index 6f26abee3597..7438850c62d0 100644 --- a/fs/squashfs/super.c +++ b/fs/squashfs/super.c | |||
@@ -245,7 +245,7 @@ allocate_id_index_table: | |||
245 | msblk->id_table = NULL; | 245 | msblk->id_table = NULL; |
246 | goto failed_mount; | 246 | goto failed_mount; |
247 | } | 247 | } |
248 | next_table = msblk->id_table[0]; | 248 | next_table = le64_to_cpu(msblk->id_table[0]); |
249 | 249 | ||
250 | /* Handle inode lookup table */ | 250 | /* Handle inode lookup table */ |
251 | lookup_table_start = le64_to_cpu(sblk->lookup_table_start); | 251 | lookup_table_start = le64_to_cpu(sblk->lookup_table_start); |
@@ -261,7 +261,7 @@ allocate_id_index_table: | |||
261 | msblk->inode_lookup_table = NULL; | 261 | msblk->inode_lookup_table = NULL; |
262 | goto failed_mount; | 262 | goto failed_mount; |
263 | } | 263 | } |
264 | next_table = msblk->inode_lookup_table[0]; | 264 | next_table = le64_to_cpu(msblk->inode_lookup_table[0]); |
265 | 265 | ||
266 | sb->s_export_op = &squashfs_export_ops; | 266 | sb->s_export_op = &squashfs_export_ops; |
267 | 267 | ||
@@ -286,7 +286,7 @@ handle_fragments: | |||
286 | msblk->fragment_index = NULL; | 286 | msblk->fragment_index = NULL; |
287 | goto failed_mount; | 287 | goto failed_mount; |
288 | } | 288 | } |
289 | next_table = msblk->fragment_index[0]; | 289 | next_table = le64_to_cpu(msblk->fragment_index[0]); |
290 | 290 | ||
291 | check_directory_table: | 291 | check_directory_table: |
292 | /* Sanity check directory_table */ | 292 | /* Sanity check directory_table */ |
diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c index e2cc6756f3b1..e474fbcf8bde 100644 --- a/fs/sysv/namei.c +++ b/fs/sysv/namei.c | |||
@@ -196,8 +196,6 @@ static int sysv_rmdir(struct inode * dir, struct dentry * dentry) | |||
196 | struct inode *inode = dentry->d_inode; | 196 | struct inode *inode = dentry->d_inode; |
197 | int err = -ENOTEMPTY; | 197 | int err = -ENOTEMPTY; |
198 | 198 | ||
199 | dentry_unhash(dentry); | ||
200 | |||
201 | if (sysv_empty_dir(inode)) { | 199 | if (sysv_empty_dir(inode)) { |
202 | err = sysv_unlink(dir, dentry); | 200 | err = sysv_unlink(dir, dentry); |
203 | if (!err) { | 201 | if (!err) { |
@@ -224,9 +222,6 @@ static int sysv_rename(struct inode * old_dir, struct dentry * old_dentry, | |||
224 | struct sysv_dir_entry * old_de; | 222 | struct sysv_dir_entry * old_de; |
225 | int err = -ENOENT; | 223 | int err = -ENOENT; |
226 | 224 | ||
227 | if (new_inode && S_ISDIR(new_inode->i_mode)) | ||
228 | dentry_unhash(new_dentry); | ||
229 | |||
230 | old_de = sysv_find_entry(old_dentry, &old_page); | 225 | old_de = sysv_find_entry(old_dentry, &old_page); |
231 | if (!old_de) | 226 | if (!old_de) |
232 | goto out; | 227 | goto out; |
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index c2b80943560d..ef5abd38f0bf 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c | |||
@@ -656,8 +656,6 @@ static int ubifs_rmdir(struct inode *dir, struct dentry *dentry) | |||
656 | struct ubifs_inode *dir_ui = ubifs_inode(dir); | 656 | struct ubifs_inode *dir_ui = ubifs_inode(dir); |
657 | struct ubifs_budget_req req = { .mod_dent = 1, .dirtied_ino = 2 }; | 657 | struct ubifs_budget_req req = { .mod_dent = 1, .dirtied_ino = 2 }; |
658 | 658 | ||
659 | dentry_unhash(dentry); | ||
660 | |||
661 | /* | 659 | /* |
662 | * Budget request settings: deletion direntry, deletion inode and | 660 | * Budget request settings: deletion direntry, deletion inode and |
663 | * changing the parent inode. If budgeting fails, go ahead anyway | 661 | * changing the parent inode. If budgeting fails, go ahead anyway |
@@ -978,9 +976,6 @@ static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
978 | .dirtied_ino_d = ALIGN(old_inode_ui->data_len, 8) }; | 976 | .dirtied_ino_d = ALIGN(old_inode_ui->data_len, 8) }; |
979 | struct timespec time; | 977 | struct timespec time; |
980 | 978 | ||
981 | if (new_inode && S_ISDIR(new_inode->i_mode)) | ||
982 | dentry_unhash(new_dentry); | ||
983 | |||
984 | /* | 979 | /* |
985 | * Budget request settings: deletion direntry, new direntry, removing | 980 | * Budget request settings: deletion direntry, new direntry, removing |
986 | * the old inode, and changing old and new parent directory inodes. | 981 | * the old inode, and changing old and new parent directory inodes. |
diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c index 166951e0dcd3..3be645e012c9 100644 --- a/fs/ubifs/io.c +++ b/fs/ubifs/io.c | |||
@@ -581,6 +581,7 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len) | |||
581 | ubifs_assert(wbuf->size % c->min_io_size == 0); | 581 | ubifs_assert(wbuf->size % c->min_io_size == 0); |
582 | ubifs_assert(mutex_is_locked(&wbuf->io_mutex)); | 582 | ubifs_assert(mutex_is_locked(&wbuf->io_mutex)); |
583 | ubifs_assert(!c->ro_media && !c->ro_mount); | 583 | ubifs_assert(!c->ro_media && !c->ro_mount); |
584 | ubifs_assert(!c->space_fixup); | ||
584 | if (c->leb_size - wbuf->offs >= c->max_write_size) | 585 | if (c->leb_size - wbuf->offs >= c->max_write_size) |
585 | ubifs_assert(!((wbuf->offs + wbuf->size) % c->max_write_size)); | 586 | ubifs_assert(!((wbuf->offs + wbuf->size) % c->max_write_size)); |
586 | 587 | ||
@@ -759,6 +760,7 @@ int ubifs_write_node(struct ubifs_info *c, void *buf, int len, int lnum, | |||
759 | ubifs_assert(lnum >= 0 && lnum < c->leb_cnt && offs >= 0); | 760 | ubifs_assert(lnum >= 0 && lnum < c->leb_cnt && offs >= 0); |
760 | ubifs_assert(offs % c->min_io_size == 0 && offs < c->leb_size); | 761 | ubifs_assert(offs % c->min_io_size == 0 && offs < c->leb_size); |
761 | ubifs_assert(!c->ro_media && !c->ro_mount); | 762 | ubifs_assert(!c->ro_media && !c->ro_mount); |
763 | ubifs_assert(!c->space_fixup); | ||
762 | 764 | ||
763 | if (c->ro_error) | 765 | if (c->ro_error) |
764 | return -EROFS; | 766 | return -EROFS; |
diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c index 34b1679e6e3a..cef0460f4c54 100644 --- a/fs/ubifs/journal.c +++ b/fs/ubifs/journal.c | |||
@@ -669,6 +669,7 @@ out_free: | |||
669 | 669 | ||
670 | out_release: | 670 | out_release: |
671 | release_head(c, BASEHD); | 671 | release_head(c, BASEHD); |
672 | kfree(dent); | ||
672 | out_ro: | 673 | out_ro: |
673 | ubifs_ro_mode(c, err); | 674 | ubifs_ro_mode(c, err); |
674 | if (last_reference) | 675 | if (last_reference) |
diff --git a/fs/ubifs/orphan.c b/fs/ubifs/orphan.c index bd644bf587a8..a5422fffbd69 100644 --- a/fs/ubifs/orphan.c +++ b/fs/ubifs/orphan.c | |||
@@ -674,7 +674,7 @@ static int kill_orphans(struct ubifs_info *c) | |||
674 | if (IS_ERR(sleb)) { | 674 | if (IS_ERR(sleb)) { |
675 | if (PTR_ERR(sleb) == -EUCLEAN) | 675 | if (PTR_ERR(sleb) == -EUCLEAN) |
676 | sleb = ubifs_recover_leb(c, lnum, 0, | 676 | sleb = ubifs_recover_leb(c, lnum, 0, |
677 | c->sbuf, 0); | 677 | c->sbuf, -1); |
678 | if (IS_ERR(sleb)) { | 678 | if (IS_ERR(sleb)) { |
679 | err = PTR_ERR(sleb); | 679 | err = PTR_ERR(sleb); |
680 | break; | 680 | break; |
diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c index 731d9e2e7b50..783d8e0beb76 100644 --- a/fs/ubifs/recovery.c +++ b/fs/ubifs/recovery.c | |||
@@ -564,19 +564,15 @@ static int fix_unclean_leb(struct ubifs_info *c, struct ubifs_scan_leb *sleb, | |||
564 | } | 564 | } |
565 | 565 | ||
566 | /** | 566 | /** |
567 | * drop_last_node - drop the last node or group of nodes. | 567 | * drop_last_group - drop the last group of nodes. |
568 | * @sleb: scanned LEB information | 568 | * @sleb: scanned LEB information |
569 | * @offs: offset of dropped nodes is returned here | 569 | * @offs: offset of dropped nodes is returned here |
570 | * @grouped: non-zero if whole group of nodes have to be dropped | ||
571 | * | 570 | * |
572 | * This is a helper function for 'ubifs_recover_leb()' which drops the last | 571 | * This is a helper function for 'ubifs_recover_leb()' which drops the last |
573 | * node of the scanned LEB or the last group of nodes if @grouped is not zero. | 572 | * group of nodes of the scanned LEB. |
574 | * This function returns %1 if a node was dropped and %0 otherwise. | ||
575 | */ | 573 | */ |
576 | static int drop_last_node(struct ubifs_scan_leb *sleb, int *offs, int grouped) | 574 | static void drop_last_group(struct ubifs_scan_leb *sleb, int *offs) |
577 | { | 575 | { |
578 | int dropped = 0; | ||
579 | |||
580 | while (!list_empty(&sleb->nodes)) { | 576 | while (!list_empty(&sleb->nodes)) { |
581 | struct ubifs_scan_node *snod; | 577 | struct ubifs_scan_node *snod; |
582 | struct ubifs_ch *ch; | 578 | struct ubifs_ch *ch; |
@@ -585,17 +581,40 @@ static int drop_last_node(struct ubifs_scan_leb *sleb, int *offs, int grouped) | |||
585 | list); | 581 | list); |
586 | ch = snod->node; | 582 | ch = snod->node; |
587 | if (ch->group_type != UBIFS_IN_NODE_GROUP) | 583 | if (ch->group_type != UBIFS_IN_NODE_GROUP) |
588 | return dropped; | 584 | break; |
589 | dbg_rcvry("dropping node at %d:%d", sleb->lnum, snod->offs); | 585 | |
586 | dbg_rcvry("dropping grouped node at %d:%d", | ||
587 | sleb->lnum, snod->offs); | ||
588 | *offs = snod->offs; | ||
589 | list_del(&snod->list); | ||
590 | kfree(snod); | ||
591 | sleb->nodes_cnt -= 1; | ||
592 | } | ||
593 | } | ||
594 | |||
595 | /** | ||
596 | * drop_last_node - drop the last node. | ||
597 | * @sleb: scanned LEB information | ||
598 | * @offs: offset of dropped nodes is returned here | ||
599 | * @grouped: non-zero if whole group of nodes have to be dropped | ||
600 | * | ||
601 | * This is a helper function for 'ubifs_recover_leb()' which drops the last | ||
602 | * node of the scanned LEB. | ||
603 | */ | ||
604 | static void drop_last_node(struct ubifs_scan_leb *sleb, int *offs) | ||
605 | { | ||
606 | struct ubifs_scan_node *snod; | ||
607 | |||
608 | if (!list_empty(&sleb->nodes)) { | ||
609 | snod = list_entry(sleb->nodes.prev, struct ubifs_scan_node, | ||
610 | list); | ||
611 | |||
612 | dbg_rcvry("dropping last node at %d:%d", sleb->lnum, snod->offs); | ||
590 | *offs = snod->offs; | 613 | *offs = snod->offs; |
591 | list_del(&snod->list); | 614 | list_del(&snod->list); |
592 | kfree(snod); | 615 | kfree(snod); |
593 | sleb->nodes_cnt -= 1; | 616 | sleb->nodes_cnt -= 1; |
594 | dropped = 1; | ||
595 | if (!grouped) | ||
596 | break; | ||
597 | } | 617 | } |
598 | return dropped; | ||
599 | } | 618 | } |
600 | 619 | ||
601 | /** | 620 | /** |
@@ -604,7 +623,8 @@ static int drop_last_node(struct ubifs_scan_leb *sleb, int *offs, int grouped) | |||
604 | * @lnum: LEB number | 623 | * @lnum: LEB number |
605 | * @offs: offset | 624 | * @offs: offset |
606 | * @sbuf: LEB-sized buffer to use | 625 | * @sbuf: LEB-sized buffer to use |
607 | * @grouped: nodes may be grouped for recovery | 626 | * @jhead: journal head number this LEB belongs to (%-1 if the LEB does not |
627 | * belong to any journal head) | ||
608 | * | 628 | * |
609 | * This function does a scan of a LEB, but caters for errors that might have | 629 | * This function does a scan of a LEB, but caters for errors that might have |
610 | * been caused by the unclean unmount from which we are attempting to recover. | 630 | * been caused by the unclean unmount from which we are attempting to recover. |
@@ -612,13 +632,14 @@ static int drop_last_node(struct ubifs_scan_leb *sleb, int *offs, int grouped) | |||
612 | * found, and a negative error code in case of failure. | 632 | * found, and a negative error code in case of failure. |
613 | */ | 633 | */ |
614 | struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, | 634 | struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, |
615 | int offs, void *sbuf, int grouped) | 635 | int offs, void *sbuf, int jhead) |
616 | { | 636 | { |
617 | int ret = 0, err, len = c->leb_size - offs, start = offs, min_io_unit; | 637 | int ret = 0, err, len = c->leb_size - offs, start = offs, min_io_unit; |
638 | int grouped = jhead == -1 ? 0 : c->jheads[jhead].grouped; | ||
618 | struct ubifs_scan_leb *sleb; | 639 | struct ubifs_scan_leb *sleb; |
619 | void *buf = sbuf + offs; | 640 | void *buf = sbuf + offs; |
620 | 641 | ||
621 | dbg_rcvry("%d:%d", lnum, offs); | 642 | dbg_rcvry("%d:%d, jhead %d, grouped %d", lnum, offs, jhead, grouped); |
622 | 643 | ||
623 | sleb = ubifs_start_scan(c, lnum, offs, sbuf); | 644 | sleb = ubifs_start_scan(c, lnum, offs, sbuf); |
624 | if (IS_ERR(sleb)) | 645 | if (IS_ERR(sleb)) |
@@ -635,7 +656,7 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, | |||
635 | * Scan quietly until there is an error from which we cannot | 656 | * Scan quietly until there is an error from which we cannot |
636 | * recover | 657 | * recover |
637 | */ | 658 | */ |
638 | ret = ubifs_scan_a_node(c, buf, len, lnum, offs, 0); | 659 | ret = ubifs_scan_a_node(c, buf, len, lnum, offs, 1); |
639 | if (ret == SCANNED_A_NODE) { | 660 | if (ret == SCANNED_A_NODE) { |
640 | /* A valid node, and not a padding node */ | 661 | /* A valid node, and not a padding node */ |
641 | struct ubifs_ch *ch = buf; | 662 | struct ubifs_ch *ch = buf; |
@@ -695,59 +716,62 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, | |||
695 | * If nodes are grouped, always drop the incomplete group at | 716 | * If nodes are grouped, always drop the incomplete group at |
696 | * the end. | 717 | * the end. |
697 | */ | 718 | */ |
698 | drop_last_node(sleb, &offs, 1); | 719 | drop_last_group(sleb, &offs); |
699 | 720 | ||
700 | /* | 721 | if (jhead == GCHD) { |
701 | * While we are in the middle of the same min. I/O unit keep dropping | 722 | /* |
702 | * nodes. So basically, what we want is to make sure that the last min. | 723 | * If this LEB belongs to the GC head then while we are in the |
703 | * I/O unit where we saw the corruption is dropped completely with all | 724 | * middle of the same min. I/O unit keep dropping nodes. So |
704 | * the uncorrupted node which may possibly sit there. | 725 | * basically, what we want is to make sure that the last min. |
705 | * | 726 | * I/O unit where we saw the corruption is dropped completely |
706 | * In other words, let's name the min. I/O unit where the corruption | 727 | * with all the uncorrupted nodes which may possibly sit there. |
707 | * starts B, and the previous min. I/O unit A. The below code tries to | 728 | * |
708 | * deal with a situation when half of B contains valid nodes or the end | 729 | * In other words, let's name the min. I/O unit where the |
709 | * of a valid node, and the second half of B contains corrupted data or | 730 | * corruption starts B, and the previous min. I/O unit A. The |
710 | * garbage. This means that UBIFS had been writing to B just before the | 731 | * below code tries to deal with a situation when half of B |
711 | * power cut happened. I do not know how realistic is this scenario | 732 | * contains valid nodes or the end of a valid node, and the |
712 | * that half of the min. I/O unit had been written successfully and the | 733 | * second half of B contains corrupted data or garbage. This |
713 | * other half not, but this is possible in our 'failure mode emulation' | 734 | * means that UBIFS had been writing to B just before the power |
714 | * infrastructure at least. | 735 | * cut happened. I do not know how realistic is this scenario |
715 | * | 736 | * that half of the min. I/O unit had been written successfully |
716 | * So what is the problem, why we need to drop those nodes? Whey can't | 737 | * and the other half not, but this is possible in our 'failure |
717 | * we just clean-up the second half of B by putting a padding node | 738 | * mode emulation' infrastructure at least. |
718 | * there? We can, and this works fine with one exception which was | 739 | * |
719 | * reproduced with power cut emulation testing and happens extremely | 740 | * So what is the problem, why we need to drop those nodes? Why |
720 | * rarely. The description follows, but it is worth noting that that is | 741 | * can't we just clean-up the second half of B by putting a |
721 | * only about the GC head, so we could do this trick only if the bud | 742 | * padding node there? We can, and this works fine with one |
722 | * belongs to the GC head, but it does not seem to be worth an | 743 | * exception which was reproduced with power cut emulation |
723 | * additional "if" statement. | 744 | * testing and happens extremely rarely. |
724 | * | 745 | * |
725 | * So, imagine the file-system is full, we run GC which is moving valid | 746 | * Imagine the file-system is full, we run GC which starts |
726 | * nodes from LEB X to LEB Y (obviously, LEB Y is the current GC head | 747 | * moving valid nodes from LEB X to LEB Y (obviously, LEB Y is |
727 | * LEB). The @c->gc_lnum is -1, which means that GC will retain LEB X | 748 | * the current GC head LEB). The @c->gc_lnum is -1, which means |
728 | * and will try to continue. Imagine that LEB X is currently the | 749 | * that GC will retain LEB X and will try to continue. Imagine |
729 | * dirtiest LEB, and the amount of used space in LEB Y is exactly the | 750 | * that LEB X is currently the dirtiest LEB, and the amount of |
730 | * same as amount of free space in LEB X. | 751 | * used space in LEB Y is exactly the same as amount of free |
731 | * | 752 | * space in LEB X. |
732 | * And a power cut happens when nodes are moved from LEB X to LEB Y. We | 753 | * |
733 | * are here trying to recover LEB Y which is the GC head LEB. We find | 754 | * And a power cut happens when nodes are moved from LEB X to |
734 | * the min. I/O unit B as described above. Then we clean-up LEB Y by | 755 | * LEB Y. We are here trying to recover LEB Y which is the GC |
735 | * padding min. I/O unit. And later 'ubifs_rcvry_gc_commit()' function | 756 | * head LEB. We find the min. I/O unit B as described above. |
736 | * fails, because it cannot find a dirty LEB which could be GC'd into | 757 | * Then we clean-up LEB Y by padding min. I/O unit. And later |
737 | * LEB Y! Even LEB X does not match because the amount of valid nodes | 758 | * 'ubifs_rcvry_gc_commit()' function fails, because it cannot |
738 | * there does not fit the free space in LEB Y any more! And this is | 759 | * find a dirty LEB which could be GC'd into LEB Y! Even LEB X |
739 | * because of the padding node which we added to LEB Y. The | 760 | * does not match because the amount of valid nodes there does |
740 | * user-visible effect of this which I once observed and analysed is | 761 | * not fit the free space in LEB Y any more! And this is |
741 | * that we cannot mount the file-system with -ENOSPC error. | 762 | * because of the padding node which we added to LEB Y. The |
742 | * | 763 | * user-visible effect of this which I once observed and |
743 | * So obviously, to make sure that situation does not happen we should | 764 | * analysed is that we cannot mount the file-system with |
744 | * free min. I/O unit B in LEB Y completely and the last used min. I/O | 765 | * -ENOSPC error. |
745 | * unit in LEB Y should be A. This is basically what the below code | 766 | * |
746 | * tries to do. | 767 | * So obviously, to make sure that situation does not happen we |
747 | */ | 768 | * should free min. I/O unit B in LEB Y completely and the last |
748 | while (min_io_unit == round_down(offs, c->min_io_size) && | 769 | * used min. I/O unit in LEB Y should be A. This is basically |
749 | min_io_unit != offs && | 770 | * what the below code tries to do. |
750 | drop_last_node(sleb, &offs, grouped)); | 771 | */ |
772 | while (offs > min_io_unit) | ||
773 | drop_last_node(sleb, &offs); | ||
774 | } | ||
751 | 775 | ||
752 | buf = sbuf + offs; | 776 | buf = sbuf + offs; |
753 | len = c->leb_size - offs; | 777 | len = c->leb_size - offs; |
@@ -881,7 +905,7 @@ struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum, | |||
881 | } | 905 | } |
882 | ubifs_scan_destroy(sleb); | 906 | ubifs_scan_destroy(sleb); |
883 | } | 907 | } |
884 | return ubifs_recover_leb(c, lnum, offs, sbuf, 0); | 908 | return ubifs_recover_leb(c, lnum, offs, sbuf, -1); |
885 | } | 909 | } |
886 | 910 | ||
887 | /** | 911 | /** |
diff --git a/fs/ubifs/replay.c b/fs/ubifs/replay.c index 6617280d1679..5e97161ce4d3 100644 --- a/fs/ubifs/replay.c +++ b/fs/ubifs/replay.c | |||
@@ -557,8 +557,7 @@ static int replay_bud(struct ubifs_info *c, struct bud_entry *b) | |||
557 | * these LEBs could possibly be written to at the power cut | 557 | * these LEBs could possibly be written to at the power cut |
558 | * time. | 558 | * time. |
559 | */ | 559 | */ |
560 | sleb = ubifs_recover_leb(c, lnum, offs, c->sbuf, | 560 | sleb = ubifs_recover_leb(c, lnum, offs, c->sbuf, b->bud->jhead); |
561 | b->bud->jhead != GCHD); | ||
562 | else | 561 | else |
563 | sleb = ubifs_scan(c, lnum, offs, c->sbuf, 0); | 562 | sleb = ubifs_scan(c, lnum, offs, c->sbuf, 0); |
564 | if (IS_ERR(sleb)) | 563 | if (IS_ERR(sleb)) |
diff --git a/fs/ubifs/shrinker.c b/fs/ubifs/shrinker.c index 46961c003236..9e1d05666fed 100644 --- a/fs/ubifs/shrinker.c +++ b/fs/ubifs/shrinker.c | |||
@@ -277,13 +277,18 @@ static int kick_a_thread(void) | |||
277 | return 0; | 277 | return 0; |
278 | } | 278 | } |
279 | 279 | ||
280 | int ubifs_shrinker(struct shrinker *shrink, int nr, gfp_t gfp_mask) | 280 | int ubifs_shrinker(struct shrinker *shrink, struct shrink_control *sc) |
281 | { | 281 | { |
282 | int nr = sc->nr_to_scan; | ||
282 | int freed, contention = 0; | 283 | int freed, contention = 0; |
283 | long clean_zn_cnt = atomic_long_read(&ubifs_clean_zn_cnt); | 284 | long clean_zn_cnt = atomic_long_read(&ubifs_clean_zn_cnt); |
284 | 285 | ||
285 | if (nr == 0) | 286 | if (nr == 0) |
286 | return clean_zn_cnt; | 287 | /* |
288 | * Due to the way UBIFS updates the clean znode counter it may | ||
289 | * temporarily be negative. | ||
290 | */ | ||
291 | return clean_zn_cnt >= 0 ? clean_zn_cnt : 1; | ||
287 | 292 | ||
288 | if (!clean_zn_cnt) { | 293 | if (!clean_zn_cnt) { |
289 | /* | 294 | /* |
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 6db0bdaa9f74..b5aeb5a8ebed 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
@@ -382,7 +382,7 @@ done: | |||
382 | end_writeback(inode); | 382 | end_writeback(inode); |
383 | } | 383 | } |
384 | 384 | ||
385 | static void ubifs_dirty_inode(struct inode *inode) | 385 | static void ubifs_dirty_inode(struct inode *inode, int flags) |
386 | { | 386 | { |
387 | struct ubifs_inode *ui = ubifs_inode(inode); | 387 | struct ubifs_inode *ui = ubifs_inode(inode); |
388 | 388 | ||
@@ -811,15 +811,18 @@ static int alloc_wbufs(struct ubifs_info *c) | |||
811 | 811 | ||
812 | c->jheads[i].wbuf.sync_callback = &bud_wbuf_callback; | 812 | c->jheads[i].wbuf.sync_callback = &bud_wbuf_callback; |
813 | c->jheads[i].wbuf.jhead = i; | 813 | c->jheads[i].wbuf.jhead = i; |
814 | c->jheads[i].grouped = 1; | ||
814 | } | 815 | } |
815 | 816 | ||
816 | c->jheads[BASEHD].wbuf.dtype = UBI_SHORTTERM; | 817 | c->jheads[BASEHD].wbuf.dtype = UBI_SHORTTERM; |
817 | /* | 818 | /* |
818 | * Garbage Collector head likely contains long-term data and | 819 | * Garbage Collector head likely contains long-term data and |
819 | * does not need to be synchronized by timer. | 820 | * does not need to be synchronized by timer. Also GC head nodes are |
821 | * not grouped. | ||
820 | */ | 822 | */ |
821 | c->jheads[GCHD].wbuf.dtype = UBI_LONGTERM; | 823 | c->jheads[GCHD].wbuf.dtype = UBI_LONGTERM; |
822 | c->jheads[GCHD].wbuf.no_timer = 1; | 824 | c->jheads[GCHD].wbuf.no_timer = 1; |
825 | c->jheads[GCHD].grouped = 0; | ||
823 | 826 | ||
824 | return 0; | 827 | return 0; |
825 | } | 828 | } |
@@ -1284,12 +1287,25 @@ static int mount_ubifs(struct ubifs_info *c) | |||
1284 | if ((c->mst_node->flags & cpu_to_le32(UBIFS_MST_DIRTY)) != 0) { | 1287 | if ((c->mst_node->flags & cpu_to_le32(UBIFS_MST_DIRTY)) != 0) { |
1285 | ubifs_msg("recovery needed"); | 1288 | ubifs_msg("recovery needed"); |
1286 | c->need_recovery = 1; | 1289 | c->need_recovery = 1; |
1287 | if (!c->ro_mount) { | 1290 | } |
1288 | err = ubifs_recover_inl_heads(c, c->sbuf); | 1291 | |
1289 | if (err) | 1292 | if (c->need_recovery && !c->ro_mount) { |
1290 | goto out_master; | 1293 | err = ubifs_recover_inl_heads(c, c->sbuf); |
1291 | } | 1294 | if (err) |
1292 | } else if (!c->ro_mount) { | 1295 | goto out_master; |
1296 | } | ||
1297 | |||
1298 | err = ubifs_lpt_init(c, 1, !c->ro_mount); | ||
1299 | if (err) | ||
1300 | goto out_master; | ||
1301 | |||
1302 | if (!c->ro_mount && c->space_fixup) { | ||
1303 | err = ubifs_fixup_free_space(c); | ||
1304 | if (err) | ||
1305 | goto out_master; | ||
1306 | } | ||
1307 | |||
1308 | if (!c->ro_mount) { | ||
1293 | /* | 1309 | /* |
1294 | * Set the "dirty" flag so that if we reboot uncleanly we | 1310 | * Set the "dirty" flag so that if we reboot uncleanly we |
1295 | * will notice this immediately on the next mount. | 1311 | * will notice this immediately on the next mount. |
@@ -1297,13 +1313,9 @@ static int mount_ubifs(struct ubifs_info *c) | |||
1297 | c->mst_node->flags |= cpu_to_le32(UBIFS_MST_DIRTY); | 1313 | c->mst_node->flags |= cpu_to_le32(UBIFS_MST_DIRTY); |
1298 | err = ubifs_write_master(c); | 1314 | err = ubifs_write_master(c); |
1299 | if (err) | 1315 | if (err) |
1300 | goto out_master; | 1316 | goto out_lpt; |
1301 | } | 1317 | } |
1302 | 1318 | ||
1303 | err = ubifs_lpt_init(c, 1, !c->ro_mount); | ||
1304 | if (err) | ||
1305 | goto out_lpt; | ||
1306 | |||
1307 | err = dbg_check_idx_size(c, c->bi.old_idx_sz); | 1319 | err = dbg_check_idx_size(c, c->bi.old_idx_sz); |
1308 | if (err) | 1320 | if (err) |
1309 | goto out_lpt; | 1321 | goto out_lpt; |
@@ -1396,12 +1408,6 @@ static int mount_ubifs(struct ubifs_info *c) | |||
1396 | } else | 1408 | } else |
1397 | ubifs_assert(c->lst.taken_empty_lebs > 0); | 1409 | ubifs_assert(c->lst.taken_empty_lebs > 0); |
1398 | 1410 | ||
1399 | if (!c->ro_mount && c->space_fixup) { | ||
1400 | err = ubifs_fixup_free_space(c); | ||
1401 | if (err) | ||
1402 | goto out_infos; | ||
1403 | } | ||
1404 | |||
1405 | err = dbg_check_filesystem(c); | 1411 | err = dbg_check_filesystem(c); |
1406 | if (err) | 1412 | if (err) |
1407 | goto out_infos; | 1413 | goto out_infos; |
diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c index 8119b1fd8d94..91b4213dde84 100644 --- a/fs/ubifs/tnc.c +++ b/fs/ubifs/tnc.c | |||
@@ -2876,12 +2876,13 @@ static void tnc_destroy_cnext(struct ubifs_info *c) | |||
2876 | */ | 2876 | */ |
2877 | void ubifs_tnc_close(struct ubifs_info *c) | 2877 | void ubifs_tnc_close(struct ubifs_info *c) |
2878 | { | 2878 | { |
2879 | long clean_freed; | ||
2880 | |||
2881 | tnc_destroy_cnext(c); | 2879 | tnc_destroy_cnext(c); |
2882 | if (c->zroot.znode) { | 2880 | if (c->zroot.znode) { |
2883 | clean_freed = ubifs_destroy_tnc_subtree(c->zroot.znode); | 2881 | long n; |
2884 | atomic_long_sub(clean_freed, &ubifs_clean_zn_cnt); | 2882 | |
2883 | ubifs_destroy_tnc_subtree(c->zroot.znode); | ||
2884 | n = atomic_long_read(&c->clean_zn_cnt); | ||
2885 | atomic_long_sub(n, &ubifs_clean_zn_cnt); | ||
2885 | } | 2886 | } |
2886 | kfree(c->gap_lebs); | 2887 | kfree(c->gap_lebs); |
2887 | kfree(c->ilebs); | 2888 | kfree(c->ilebs); |
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index 93d1412a06f0..f79983d6f860 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h | |||
@@ -722,12 +722,14 @@ struct ubifs_bud { | |||
722 | * struct ubifs_jhead - journal head. | 722 | * struct ubifs_jhead - journal head. |
723 | * @wbuf: head's write-buffer | 723 | * @wbuf: head's write-buffer |
724 | * @buds_list: list of bud LEBs belonging to this journal head | 724 | * @buds_list: list of bud LEBs belonging to this journal head |
725 | * @grouped: non-zero if UBIFS groups nodes when writing to this journal head | ||
725 | * | 726 | * |
726 | * Note, the @buds list is protected by the @c->buds_lock. | 727 | * Note, the @buds list is protected by the @c->buds_lock. |
727 | */ | 728 | */ |
728 | struct ubifs_jhead { | 729 | struct ubifs_jhead { |
729 | struct ubifs_wbuf wbuf; | 730 | struct ubifs_wbuf wbuf; |
730 | struct list_head buds_list; | 731 | struct list_head buds_list; |
732 | unsigned int grouped:1; | ||
731 | }; | 733 | }; |
732 | 734 | ||
733 | /** | 735 | /** |
@@ -1614,7 +1616,7 @@ int ubifs_tnc_start_commit(struct ubifs_info *c, struct ubifs_zbranch *zroot); | |||
1614 | int ubifs_tnc_end_commit(struct ubifs_info *c); | 1616 | int ubifs_tnc_end_commit(struct ubifs_info *c); |
1615 | 1617 | ||
1616 | /* shrinker.c */ | 1618 | /* shrinker.c */ |
1617 | int ubifs_shrinker(struct shrinker *shrink, int nr_to_scan, gfp_t gfp_mask); | 1619 | int ubifs_shrinker(struct shrinker *shrink, struct shrink_control *sc); |
1618 | 1620 | ||
1619 | /* commit.c */ | 1621 | /* commit.c */ |
1620 | int ubifs_bg_thread(void *info); | 1622 | int ubifs_bg_thread(void *info); |
@@ -1742,7 +1744,7 @@ struct inode *ubifs_iget(struct super_block *sb, unsigned long inum); | |||
1742 | int ubifs_recover_master_node(struct ubifs_info *c); | 1744 | int ubifs_recover_master_node(struct ubifs_info *c); |
1743 | int ubifs_write_rcvrd_mst_node(struct ubifs_info *c); | 1745 | int ubifs_write_rcvrd_mst_node(struct ubifs_info *c); |
1744 | struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, | 1746 | struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, |
1745 | int offs, void *sbuf, int grouped); | 1747 | int offs, void *sbuf, int jhead); |
1746 | struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum, | 1748 | struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum, |
1747 | int offs, void *sbuf); | 1749 | int offs, void *sbuf); |
1748 | int ubifs_recover_inl_heads(const struct ubifs_info *c, void *sbuf); | 1750 | int ubifs_recover_inl_heads(const struct ubifs_info *c, void *sbuf); |
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 4d76594c2a8f..f1dce848ef96 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c | |||
@@ -783,8 +783,6 @@ static int udf_rmdir(struct inode *dir, struct dentry *dentry) | |||
783 | struct fileIdentDesc *fi, cfi; | 783 | struct fileIdentDesc *fi, cfi; |
784 | struct kernel_lb_addr tloc; | 784 | struct kernel_lb_addr tloc; |
785 | 785 | ||
786 | dentry_unhash(dentry); | ||
787 | |||
788 | retval = -ENOENT; | 786 | retval = -ENOENT; |
789 | fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); | 787 | fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); |
790 | if (!fi) | 788 | if (!fi) |
@@ -1083,9 +1081,6 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1083 | struct kernel_lb_addr tloc; | 1081 | struct kernel_lb_addr tloc; |
1084 | struct udf_inode_info *old_iinfo = UDF_I(old_inode); | 1082 | struct udf_inode_info *old_iinfo = UDF_I(old_inode); |
1085 | 1083 | ||
1086 | if (new_inode && S_ISDIR(new_inode->i_mode)) | ||
1087 | dentry_unhash(new_dentry); | ||
1088 | |||
1089 | ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi); | 1084 | ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi); |
1090 | if (ofi) { | 1085 | if (ofi) { |
1091 | if (ofibh.sbh != ofibh.ebh) | 1086 | if (ofibh.sbh != ofibh.ebh) |
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c index 953ebdfc5bf7..29309e25417f 100644 --- a/fs/ufs/namei.c +++ b/fs/ufs/namei.c | |||
@@ -258,8 +258,6 @@ static int ufs_rmdir (struct inode * dir, struct dentry *dentry) | |||
258 | struct inode * inode = dentry->d_inode; | 258 | struct inode * inode = dentry->d_inode; |
259 | int err= -ENOTEMPTY; | 259 | int err= -ENOTEMPTY; |
260 | 260 | ||
261 | dentry_unhash(dentry); | ||
262 | |||
263 | lock_ufs(dir->i_sb); | 261 | lock_ufs(dir->i_sb); |
264 | if (ufs_empty_dir (inode)) { | 262 | if (ufs_empty_dir (inode)) { |
265 | err = ufs_unlink(dir, dentry); | 263 | err = ufs_unlink(dir, dentry); |
@@ -284,9 +282,6 @@ static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
284 | struct ufs_dir_entry *old_de; | 282 | struct ufs_dir_entry *old_de; |
285 | int err = -ENOENT; | 283 | int err = -ENOENT; |
286 | 284 | ||
287 | if (new_inode && S_ISDIR(new_inode->i_mode)) | ||
288 | dentry_unhash(new_dentry); | ||
289 | |||
290 | old_de = ufs_find_entry(old_dir, &old_dentry->d_name, &old_page); | 285 | old_de = ufs_find_entry(old_dir, &old_dentry->d_name, &old_page); |
291 | if (!old_de) | 286 | if (!old_de) |
292 | goto out; | 287 | goto out; |
diff --git a/fs/xattr.c b/fs/xattr.c index f1ef94974dea..f060663ab70c 100644 --- a/fs/xattr.c +++ b/fs/xattr.c | |||
@@ -46,18 +46,22 @@ xattr_permission(struct inode *inode, const char *name, int mask) | |||
46 | return 0; | 46 | return 0; |
47 | 47 | ||
48 | /* | 48 | /* |
49 | * The trusted.* namespace can only be accessed by a privileged user. | 49 | * The trusted.* namespace can only be accessed by privileged users. |
50 | */ | 50 | */ |
51 | if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) | 51 | if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) { |
52 | return (capable(CAP_SYS_ADMIN) ? 0 : -EPERM); | 52 | if (!capable(CAP_SYS_ADMIN)) |
53 | return (mask & MAY_WRITE) ? -EPERM : -ENODATA; | ||
54 | return 0; | ||
55 | } | ||
53 | 56 | ||
54 | /* In user.* namespace, only regular files and directories can have | 57 | /* |
58 | * In the user.* namespace, only regular files and directories can have | ||
55 | * extended attributes. For sticky directories, only the owner and | 59 | * extended attributes. For sticky directories, only the owner and |
56 | * privileged user can write attributes. | 60 | * privileged users can write attributes. |
57 | */ | 61 | */ |
58 | if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) { | 62 | if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) { |
59 | if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode)) | 63 | if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode)) |
60 | return -EPERM; | 64 | return (mask & MAY_WRITE) ? -EPERM : -ENODATA; |
61 | if (S_ISDIR(inode->i_mode) && (inode->i_mode & S_ISVTX) && | 65 | if (S_ISDIR(inode->i_mode) && (inode->i_mode & S_ISVTX) && |
62 | (mask & MAY_WRITE) && !inode_owner_or_capable(inode)) | 66 | (mask & MAY_WRITE) && !inode_owner_or_capable(inode)) |
63 | return -EPERM; | 67 | return -EPERM; |
@@ -87,7 +91,11 @@ int __vfs_setxattr_noperm(struct dentry *dentry, const char *name, | |||
87 | { | 91 | { |
88 | struct inode *inode = dentry->d_inode; | 92 | struct inode *inode = dentry->d_inode; |
89 | int error = -EOPNOTSUPP; | 93 | int error = -EOPNOTSUPP; |
94 | int issec = !strncmp(name, XATTR_SECURITY_PREFIX, | ||
95 | XATTR_SECURITY_PREFIX_LEN); | ||
90 | 96 | ||
97 | if (issec) | ||
98 | inode->i_flags &= ~S_NOSEC; | ||
91 | if (inode->i_op->setxattr) { | 99 | if (inode->i_op->setxattr) { |
92 | error = inode->i_op->setxattr(dentry, name, value, size, flags); | 100 | error = inode->i_op->setxattr(dentry, name, value, size, flags); |
93 | if (!error) { | 101 | if (!error) { |
@@ -95,8 +103,7 @@ int __vfs_setxattr_noperm(struct dentry *dentry, const char *name, | |||
95 | security_inode_post_setxattr(dentry, name, value, | 103 | security_inode_post_setxattr(dentry, name, value, |
96 | size, flags); | 104 | size, flags); |
97 | } | 105 | } |
98 | } else if (!strncmp(name, XATTR_SECURITY_PREFIX, | 106 | } else if (issec) { |
99 | XATTR_SECURITY_PREFIX_LEN)) { | ||
100 | const char *suffix = name + XATTR_SECURITY_PREFIX_LEN; | 107 | const char *suffix = name + XATTR_SECURITY_PREFIX_LEN; |
101 | error = security_inode_setsecurity(inode, suffix, value, | 108 | error = security_inode_setsecurity(inode, suffix, value, |
102 | size, flags); | 109 | size, flags); |
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 98b9c91fcdf1..1e3a7ce804dc 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
@@ -925,7 +925,8 @@ xfs_fs_inode_init_once( | |||
925 | */ | 925 | */ |
926 | STATIC void | 926 | STATIC void |
927 | xfs_fs_dirty_inode( | 927 | xfs_fs_dirty_inode( |
928 | struct inode *inode) | 928 | struct inode *inode, |
929 | int flags) | ||
929 | { | 930 | { |
930 | barrier(); | 931 | barrier(); |
931 | XFS_I(inode)->i_update_core = 1; | 932 | XFS_I(inode)->i_update_core = 1; |
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h index a3252a5ead66..a756bc8d866d 100644 --- a/include/acpi/acpiosxf.h +++ b/include/acpi/acpiosxf.h | |||
@@ -98,6 +98,9 @@ acpi_os_table_override(struct acpi_table_header *existing_table, | |||
98 | /* | 98 | /* |
99 | * Spinlock primitives | 99 | * Spinlock primitives |
100 | */ | 100 | */ |
101 | acpi_status | ||
102 | acpi_os_create_lock(acpi_spinlock *out_handle); | ||
103 | |||
101 | void acpi_os_delete_lock(acpi_spinlock handle); | 104 | void acpi_os_delete_lock(acpi_spinlock handle); |
102 | 105 | ||
103 | acpi_cpu_flags acpi_os_acquire_lock(acpi_spinlock handle); | 106 | acpi_cpu_flags acpi_os_acquire_lock(acpi_spinlock handle); |
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index f6ad63d25b73..2ed0a8486c19 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h | |||
@@ -47,7 +47,7 @@ | |||
47 | 47 | ||
48 | /* Current ACPICA subsystem version in YYYYMMDD format */ | 48 | /* Current ACPICA subsystem version in YYYYMMDD format */ |
49 | 49 | ||
50 | #define ACPI_CA_VERSION 0x20110316 | 50 | #define ACPI_CA_VERSION 0x20110413 |
51 | 51 | ||
52 | #include "actypes.h" | 52 | #include "actypes.h" |
53 | #include "actbl.h" | 53 | #include "actbl.h" |
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 64f838beaabf..b67231bef632 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h | |||
@@ -501,8 +501,9 @@ typedef u64 acpi_integer; | |||
501 | #define ACPI_STATE_D1 (u8) 1 | 501 | #define ACPI_STATE_D1 (u8) 1 |
502 | #define ACPI_STATE_D2 (u8) 2 | 502 | #define ACPI_STATE_D2 (u8) 2 |
503 | #define ACPI_STATE_D3 (u8) 3 | 503 | #define ACPI_STATE_D3 (u8) 3 |
504 | #define ACPI_D_STATES_MAX ACPI_STATE_D3 | 504 | #define ACPI_STATE_D3_COLD (u8) 4 |
505 | #define ACPI_D_STATE_COUNT 4 | 505 | #define ACPI_D_STATES_MAX ACPI_STATE_D3_COLD |
506 | #define ACPI_D_STATE_COUNT 5 | ||
506 | 507 | ||
507 | #define ACPI_STATE_C0 (u8) 0 | 508 | #define ACPI_STATE_C0 (u8) 0 |
508 | #define ACPI_STATE_C1 (u8) 1 | 509 | #define ACPI_STATE_C1 (u8) 1 |
@@ -712,8 +713,24 @@ typedef u8 acpi_adr_space_type; | |||
712 | #define ACPI_ADR_SPACE_CMOS (acpi_adr_space_type) 5 | 713 | #define ACPI_ADR_SPACE_CMOS (acpi_adr_space_type) 5 |
713 | #define ACPI_ADR_SPACE_PCI_BAR_TARGET (acpi_adr_space_type) 6 | 714 | #define ACPI_ADR_SPACE_PCI_BAR_TARGET (acpi_adr_space_type) 6 |
714 | #define ACPI_ADR_SPACE_IPMI (acpi_adr_space_type) 7 | 715 | #define ACPI_ADR_SPACE_IPMI (acpi_adr_space_type) 7 |
715 | #define ACPI_ADR_SPACE_DATA_TABLE (acpi_adr_space_type) 8 | 716 | |
716 | #define ACPI_ADR_SPACE_FIXED_HARDWARE (acpi_adr_space_type) 127 | 717 | #define ACPI_NUM_PREDEFINED_REGIONS 8 |
718 | |||
719 | /* | ||
720 | * Special Address Spaces | ||
721 | * | ||
722 | * Note: A Data Table region is a special type of operation region | ||
723 | * that has its own AML opcode. However, internally, the AML | ||
724 | * interpreter simply creates an operation region with an an address | ||
725 | * space type of ACPI_ADR_SPACE_DATA_TABLE. | ||
726 | */ | ||
727 | #define ACPI_ADR_SPACE_DATA_TABLE (acpi_adr_space_type) 0x7E /* Internal to ACPICA only */ | ||
728 | #define ACPI_ADR_SPACE_FIXED_HARDWARE (acpi_adr_space_type) 0x7F | ||
729 | |||
730 | /* Values for _REG connection code */ | ||
731 | |||
732 | #define ACPI_REG_DISCONNECT 0 | ||
733 | #define ACPI_REG_CONNECT 1 | ||
717 | 734 | ||
718 | /* | 735 | /* |
719 | * bit_register IDs | 736 | * bit_register IDs |
diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 55192ac0cede..ba4928cae473 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h | |||
@@ -310,14 +310,7 @@ static inline int acpi_processor_get_bios_limit(int cpu, unsigned int *limit) | |||
310 | 310 | ||
311 | /* in processor_core.c */ | 311 | /* in processor_core.c */ |
312 | void acpi_processor_set_pdc(acpi_handle handle); | 312 | void acpi_processor_set_pdc(acpi_handle handle); |
313 | #ifdef CONFIG_SMP | ||
314 | int acpi_get_cpuid(acpi_handle, int type, u32 acpi_id); | 313 | int acpi_get_cpuid(acpi_handle, int type, u32 acpi_id); |
315 | #else | ||
316 | static inline int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) | ||
317 | { | ||
318 | return -1; | ||
319 | } | ||
320 | #endif | ||
321 | 314 | ||
322 | /* in processor_throttling.c */ | 315 | /* in processor_throttling.c */ |
323 | int acpi_processor_tstate_has_changed(struct acpi_processor *pr); | 316 | int acpi_processor_tstate_has_changed(struct acpi_processor *pr); |
diff --git a/include/asm-generic/unistd.h b/include/asm-generic/unistd.h index ae90e0f63995..4f76959397fa 100644 --- a/include/asm-generic/unistd.h +++ b/include/asm-generic/unistd.h | |||
@@ -683,9 +683,11 @@ __SC_COMP(__NR_clock_adjtime, sys_clock_adjtime, compat_sys_clock_adjtime) | |||
683 | __SYSCALL(__NR_syncfs, sys_syncfs) | 683 | __SYSCALL(__NR_syncfs, sys_syncfs) |
684 | #define __NR_setns 268 | 684 | #define __NR_setns 268 |
685 | __SYSCALL(__NR_setns, sys_setns) | 685 | __SYSCALL(__NR_setns, sys_setns) |
686 | #define __NR_sendmmsg 269 | ||
687 | __SC_COMP(__NR_sendmmsg, sys_sendmmsg, compat_sys_sendmmsg) | ||
686 | 688 | ||
687 | #undef __NR_syscalls | 689 | #undef __NR_syscalls |
688 | #define __NR_syscalls 269 | 690 | #define __NR_syscalls 270 |
689 | 691 | ||
690 | /* | 692 | /* |
691 | * All syscalls below here should go away really, | 693 | * All syscalls below here should go away really, |
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index a2e910e01293..1deb2a73c2da 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -150,8 +150,7 @@ extern int ec_read(u8 addr, u8 *val); | |||
150 | extern int ec_write(u8 addr, u8 val); | 150 | extern int ec_write(u8 addr, u8 val); |
151 | extern int ec_transaction(u8 command, | 151 | extern int ec_transaction(u8 command, |
152 | const u8 *wdata, unsigned wdata_len, | 152 | const u8 *wdata, unsigned wdata_len, |
153 | u8 *rdata, unsigned rdata_len, | 153 | u8 *rdata, unsigned rdata_len); |
154 | int force_poll); | ||
155 | 154 | ||
156 | #if defined(CONFIG_ACPI_WMI) || defined(CONFIG_ACPI_WMI_MODULE) | 155 | #if defined(CONFIG_ACPI_WMI) || defined(CONFIG_ACPI_WMI_MODULE) |
157 | 156 | ||
diff --git a/include/linux/atomic.h b/include/linux/atomic.h index 96c038e43d66..ee456c79b0e6 100644 --- a/include/linux/atomic.h +++ b/include/linux/atomic.h | |||
@@ -34,4 +34,17 @@ static inline int atomic_inc_not_zero_hint(atomic_t *v, int hint) | |||
34 | } | 34 | } |
35 | #endif | 35 | #endif |
36 | 36 | ||
37 | #ifndef CONFIG_ARCH_HAS_ATOMIC_OR | ||
38 | static inline void atomic_or(int i, atomic_t *v) | ||
39 | { | ||
40 | int old; | ||
41 | int new; | ||
42 | |||
43 | do { | ||
44 | old = atomic_read(v); | ||
45 | new = old | i; | ||
46 | } while (atomic_cmpxchg(v, old, new) != old); | ||
47 | } | ||
48 | #endif /* #ifndef CONFIG_ARCH_HAS_ATOMIC_OR */ | ||
49 | |||
37 | #endif /* _LINUX_ATOMIC_H */ | 50 | #endif /* _LINUX_ATOMIC_H */ |
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index ae9091a68480..1a23722e8878 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
@@ -1282,8 +1282,8 @@ queue_max_integrity_segments(struct request_queue *q) | |||
1282 | #define blk_get_integrity(a) (0) | 1282 | #define blk_get_integrity(a) (0) |
1283 | #define blk_integrity_compare(a, b) (0) | 1283 | #define blk_integrity_compare(a, b) (0) |
1284 | #define blk_integrity_register(a, b) (0) | 1284 | #define blk_integrity_register(a, b) (0) |
1285 | #define blk_integrity_unregister(a) do { } while (0); | 1285 | #define blk_integrity_unregister(a) do { } while (0) |
1286 | #define blk_queue_max_integrity_segments(a, b) do { } while (0); | 1286 | #define blk_queue_max_integrity_segments(a, b) do { } while (0) |
1287 | #define queue_max_integrity_segments(a) (0) | 1287 | #define queue_max_integrity_segments(a) (0) |
1288 | #define blk_integrity_merge_rq(a, b, c) (0) | 1288 | #define blk_integrity_merge_rq(a, b, c) (0) |
1289 | #define blk_integrity_merge_bio(a, b, c) (0) | 1289 | #define blk_integrity_merge_bio(a, b, c) (0) |
diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h index f20eb8f16025..e9eaec522655 100644 --- a/include/linux/cpuset.h +++ b/include/linux/cpuset.h | |||
@@ -146,7 +146,7 @@ static inline void cpuset_cpus_allowed(struct task_struct *p, | |||
146 | 146 | ||
147 | static inline int cpuset_cpus_allowed_fallback(struct task_struct *p) | 147 | static inline int cpuset_cpus_allowed_fallback(struct task_struct *p) |
148 | { | 148 | { |
149 | cpumask_copy(&p->cpus_allowed, cpu_possible_mask); | 149 | do_set_cpus_allowed(p, cpu_possible_mask); |
150 | return cpumask_any(cpu_active_mask); | 150 | return cpumask_any(cpu_active_mask); |
151 | } | 151 | } |
152 | 152 | ||
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 32a4423710f5..4427e0454051 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h | |||
@@ -191,6 +191,12 @@ struct dm_target { | |||
191 | 191 | ||
192 | /* Used to provide an error string from the ctr */ | 192 | /* Used to provide an error string from the ctr */ |
193 | char *error; | 193 | char *error; |
194 | |||
195 | /* | ||
196 | * Set if this target needs to receive discards regardless of | ||
197 | * whether or not its underlying devices have support. | ||
198 | */ | ||
199 | unsigned discards_supported:1; | ||
194 | }; | 200 | }; |
195 | 201 | ||
196 | /* Each target can link one of these into the table */ | 202 | /* Each target can link one of these into the table */ |
diff --git a/include/linux/dm-io.h b/include/linux/dm-io.h index 5c9186b93fff..f4b0aa3126f5 100644 --- a/include/linux/dm-io.h +++ b/include/linux/dm-io.h | |||
@@ -69,8 +69,7 @@ struct dm_io_request { | |||
69 | * | 69 | * |
70 | * Create/destroy may block. | 70 | * Create/destroy may block. |
71 | */ | 71 | */ |
72 | struct dm_io_client *dm_io_client_create(unsigned num_pages); | 72 | struct dm_io_client *dm_io_client_create(void); |
73 | int dm_io_client_resize(unsigned num_pages, struct dm_io_client *client); | ||
74 | void dm_io_client_destroy(struct dm_io_client *client); | 73 | void dm_io_client_destroy(struct dm_io_client *client); |
75 | 74 | ||
76 | /* | 75 | /* |
diff --git a/include/linux/dm-kcopyd.h b/include/linux/dm-kcopyd.h index 5db216311695..298d587e349b 100644 --- a/include/linux/dm-kcopyd.h +++ b/include/linux/dm-kcopyd.h | |||
@@ -25,8 +25,7 @@ | |||
25 | * To use kcopyd you must first create a dm_kcopyd_client object. | 25 | * To use kcopyd you must first create a dm_kcopyd_client object. |
26 | */ | 26 | */ |
27 | struct dm_kcopyd_client; | 27 | struct dm_kcopyd_client; |
28 | int dm_kcopyd_client_create(unsigned num_pages, | 28 | struct dm_kcopyd_client *dm_kcopyd_client_create(void); |
29 | struct dm_kcopyd_client **result); | ||
30 | void dm_kcopyd_client_destroy(struct dm_kcopyd_client *kc); | 29 | void dm_kcopyd_client_destroy(struct dm_kcopyd_client *kc); |
31 | 30 | ||
32 | /* | 31 | /* |
diff --git a/include/linux/dma_remapping.h b/include/linux/dma_remapping.h index 5619f8522738..bbd8661b3473 100644 --- a/include/linux/dma_remapping.h +++ b/include/linux/dma_remapping.h | |||
@@ -9,8 +9,12 @@ | |||
9 | #define VTD_PAGE_MASK (((u64)-1) << VTD_PAGE_SHIFT) | 9 | #define VTD_PAGE_MASK (((u64)-1) << VTD_PAGE_SHIFT) |
10 | #define VTD_PAGE_ALIGN(addr) (((addr) + VTD_PAGE_SIZE - 1) & VTD_PAGE_MASK) | 10 | #define VTD_PAGE_ALIGN(addr) (((addr) + VTD_PAGE_SIZE - 1) & VTD_PAGE_MASK) |
11 | 11 | ||
12 | #define VTD_STRIDE_SHIFT (9) | ||
13 | #define VTD_STRIDE_MASK (((u64)-1) << VTD_STRIDE_SHIFT) | ||
14 | |||
12 | #define DMA_PTE_READ (1) | 15 | #define DMA_PTE_READ (1) |
13 | #define DMA_PTE_WRITE (2) | 16 | #define DMA_PTE_WRITE (2) |
17 | #define DMA_PTE_LARGE_PAGE (1 << 7) | ||
14 | #define DMA_PTE_SNP (1 << 11) | 18 | #define DMA_PTE_SNP (1 << 11) |
15 | 19 | ||
16 | #define CONTEXT_TT_MULTI_LEVEL 0 | 20 | #define CONTEXT_TT_MULTI_LEVEL 0 |
diff --git a/include/linux/dw_dmac.h b/include/linux/dw_dmac.h index 6998d9376ef9..4bfe0a2f7d50 100644 --- a/include/linux/dw_dmac.h +++ b/include/linux/dw_dmac.h | |||
@@ -3,6 +3,7 @@ | |||
3 | * AVR32 systems.) | 3 | * AVR32 systems.) |
4 | * | 4 | * |
5 | * Copyright (C) 2007 Atmel Corporation | 5 | * Copyright (C) 2007 Atmel Corporation |
6 | * Copyright (C) 2010-2011 ST Microelectronics | ||
6 | * | 7 | * |
7 | * 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 |
8 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
diff --git a/include/linux/efi.h b/include/linux/efi.h index 33fa1203024e..e376270cd26e 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h | |||
@@ -299,6 +299,7 @@ extern void efi_initialize_iomem_resources(struct resource *code_resource, | |||
299 | struct resource *data_resource, struct resource *bss_resource); | 299 | struct resource *data_resource, struct resource *bss_resource); |
300 | extern unsigned long efi_get_time(void); | 300 | extern unsigned long efi_get_time(void); |
301 | extern int efi_set_rtc_mmss(unsigned long nowtime); | 301 | extern int efi_set_rtc_mmss(unsigned long nowtime); |
302 | extern void efi_reserve_boot_services(void); | ||
302 | extern struct efi_memory_map memmap; | 303 | extern struct efi_memory_map memmap; |
303 | 304 | ||
304 | /** | 305 | /** |
diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h index 85c1d302c12e..5e06acf95d0f 100644 --- a/include/linux/ext3_fs.h +++ b/include/linux/ext3_fs.h | |||
@@ -909,7 +909,7 @@ extern int ext3_setattr (struct dentry *, struct iattr *); | |||
909 | extern void ext3_evict_inode (struct inode *); | 909 | extern void ext3_evict_inode (struct inode *); |
910 | extern int ext3_sync_inode (handle_t *, struct inode *); | 910 | extern int ext3_sync_inode (handle_t *, struct inode *); |
911 | extern void ext3_discard_reservation (struct inode *); | 911 | extern void ext3_discard_reservation (struct inode *); |
912 | extern void ext3_dirty_inode(struct inode *); | 912 | extern void ext3_dirty_inode(struct inode *, int); |
913 | extern int ext3_change_inode_journal_flag(struct inode *, int); | 913 | extern int ext3_change_inode_journal_flag(struct inode *, int); |
914 | extern int ext3_get_inode_loc(struct inode *, struct ext3_iloc *); | 914 | extern int ext3_get_inode_loc(struct inode *, struct ext3_iloc *); |
915 | extern int ext3_can_truncate(struct inode *inode); | 915 | extern int ext3_can_truncate(struct inode *inode); |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 241609346dfb..c55d6b7cd5d6 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -237,6 +237,7 @@ struct inodes_stat_t { | |||
237 | #define S_PRIVATE 512 /* Inode is fs-internal */ | 237 | #define S_PRIVATE 512 /* Inode is fs-internal */ |
238 | #define S_IMA 1024 /* Inode has an associated IMA struct */ | 238 | #define S_IMA 1024 /* Inode has an associated IMA struct */ |
239 | #define S_AUTOMOUNT 2048 /* Automount/referral quasi-directory */ | 239 | #define S_AUTOMOUNT 2048 /* Automount/referral quasi-directory */ |
240 | #define S_NOSEC 4096 /* no suid or xattr security attributes */ | ||
240 | 241 | ||
241 | /* | 242 | /* |
242 | * Note that nosuid etc flags are inode-specific: setting some file-system | 243 | * Note that nosuid etc flags are inode-specific: setting some file-system |
@@ -273,6 +274,7 @@ struct inodes_stat_t { | |||
273 | #define IS_PRIVATE(inode) ((inode)->i_flags & S_PRIVATE) | 274 | #define IS_PRIVATE(inode) ((inode)->i_flags & S_PRIVATE) |
274 | #define IS_IMA(inode) ((inode)->i_flags & S_IMA) | 275 | #define IS_IMA(inode) ((inode)->i_flags & S_IMA) |
275 | #define IS_AUTOMOUNT(inode) ((inode)->i_flags & S_AUTOMOUNT) | 276 | #define IS_AUTOMOUNT(inode) ((inode)->i_flags & S_AUTOMOUNT) |
277 | #define IS_NOSEC(inode) ((inode)->i_flags & S_NOSEC) | ||
276 | 278 | ||
277 | /* the read-only stuff doesn't really belong here, but any other place is | 279 | /* the read-only stuff doesn't really belong here, but any other place is |
278 | probably as bad and I don't want to create yet another include file. */ | 280 | probably as bad and I don't want to create yet another include file. */ |
@@ -1618,7 +1620,7 @@ struct super_operations { | |||
1618 | struct inode *(*alloc_inode)(struct super_block *sb); | 1620 | struct inode *(*alloc_inode)(struct super_block *sb); |
1619 | void (*destroy_inode)(struct inode *); | 1621 | void (*destroy_inode)(struct inode *); |
1620 | 1622 | ||
1621 | void (*dirty_inode) (struct inode *); | 1623 | void (*dirty_inode) (struct inode *, int flags); |
1622 | int (*write_inode) (struct inode *, struct writeback_control *wbc); | 1624 | int (*write_inode) (struct inode *, struct writeback_control *wbc); |
1623 | int (*drop_inode) (struct inode *); | 1625 | int (*drop_inode) (struct inode *); |
1624 | void (*evict_inode) (struct inode *); | 1626 | void (*evict_inode) (struct inode *); |
@@ -2582,5 +2584,16 @@ int __init get_filesystem_list(char *buf); | |||
2582 | #define OPEN_FMODE(flag) ((__force fmode_t)(((flag + 1) & O_ACCMODE) | \ | 2584 | #define OPEN_FMODE(flag) ((__force fmode_t)(((flag + 1) & O_ACCMODE) | \ |
2583 | (flag & __FMODE_NONOTIFY))) | 2585 | (flag & __FMODE_NONOTIFY))) |
2584 | 2586 | ||
2587 | static inline int is_sxid(mode_t mode) | ||
2588 | { | ||
2589 | return (mode & S_ISUID) || ((mode & S_ISGID) && (mode & S_IXGRP)); | ||
2590 | } | ||
2591 | |||
2592 | static inline void inode_has_no_xattr(struct inode *inode) | ||
2593 | { | ||
2594 | if (!is_sxid(inode->i_mode)) | ||
2595 | inode->i_flags |= S_NOSEC; | ||
2596 | } | ||
2597 | |||
2585 | #endif /* __KERNEL__ */ | 2598 | #endif /* __KERNEL__ */ |
2586 | #endif /* _LINUX_FS_H */ | 2599 | #endif /* _LINUX_FS_H */ |
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index b5a550a39a70..59d3ef100eb9 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h | |||
@@ -16,6 +16,11 @@ struct trace_print_flags { | |||
16 | const char *name; | 16 | const char *name; |
17 | }; | 17 | }; |
18 | 18 | ||
19 | struct trace_print_flags_u64 { | ||
20 | unsigned long long mask; | ||
21 | const char *name; | ||
22 | }; | ||
23 | |||
19 | const char *ftrace_print_flags_seq(struct trace_seq *p, const char *delim, | 24 | const char *ftrace_print_flags_seq(struct trace_seq *p, const char *delim, |
20 | unsigned long flags, | 25 | unsigned long flags, |
21 | const struct trace_print_flags *flag_array); | 26 | const struct trace_print_flags *flag_array); |
@@ -23,6 +28,13 @@ const char *ftrace_print_flags_seq(struct trace_seq *p, const char *delim, | |||
23 | const char *ftrace_print_symbols_seq(struct trace_seq *p, unsigned long val, | 28 | const char *ftrace_print_symbols_seq(struct trace_seq *p, unsigned long val, |
24 | const struct trace_print_flags *symbol_array); | 29 | const struct trace_print_flags *symbol_array); |
25 | 30 | ||
31 | #if BITS_PER_LONG == 32 | ||
32 | const char *ftrace_print_symbols_seq_u64(struct trace_seq *p, | ||
33 | unsigned long long val, | ||
34 | const struct trace_print_flags_u64 | ||
35 | *symbol_array); | ||
36 | #endif | ||
37 | |||
26 | const char *ftrace_print_hex_seq(struct trace_seq *p, | 38 | const char *ftrace_print_hex_seq(struct trace_seq *p, |
27 | const unsigned char *buf, int len); | 39 | const unsigned char *buf, int len); |
28 | 40 | ||
diff --git a/include/linux/genhd.h b/include/linux/genhd.h index b78956b3c2e7..300d7582006e 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h | |||
@@ -100,6 +100,7 @@ struct hd_struct { | |||
100 | sector_t start_sect; | 100 | sector_t start_sect; |
101 | sector_t nr_sects; | 101 | sector_t nr_sects; |
102 | sector_t alignment_offset; | 102 | sector_t alignment_offset; |
103 | unsigned int discard_alignment; | ||
103 | struct device __dev; | 104 | struct device __dev; |
104 | struct kobject *holder_dir; | 105 | struct kobject *holder_dir; |
105 | int policy, partno; | 106 | int policy, partno; |
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index b2eee5879883..bf56b6f78270 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h | |||
@@ -1003,8 +1003,12 @@ struct ieee80211_ht_info { | |||
1003 | #define WLAN_CAPABILITY_ESS (1<<0) | 1003 | #define WLAN_CAPABILITY_ESS (1<<0) |
1004 | #define WLAN_CAPABILITY_IBSS (1<<1) | 1004 | #define WLAN_CAPABILITY_IBSS (1<<1) |
1005 | 1005 | ||
1006 | /* A mesh STA sets the ESS and IBSS capability bits to zero */ | 1006 | /* |
1007 | #define WLAN_CAPABILITY_IS_MBSS(cap) \ | 1007 | * A mesh STA sets the ESS and IBSS capability bits to zero. |
1008 | * however, this holds true for p2p probe responses (in the p2p_find | ||
1009 | * phase) as well. | ||
1010 | */ | ||
1011 | #define WLAN_CAPABILITY_IS_STA_BSS(cap) \ | ||
1008 | (!((cap) & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS))) | 1012 | (!((cap) & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS))) |
1009 | 1013 | ||
1010 | #define WLAN_CAPABILITY_CF_POLLABLE (1<<2) | 1014 | #define WLAN_CAPABILITY_CF_POLLABLE (1<<2) |
diff --git a/include/linux/if_packet.h b/include/linux/if_packet.h index 72bfa5a034dd..6d66ce1791a9 100644 --- a/include/linux/if_packet.h +++ b/include/linux/if_packet.h | |||
@@ -70,6 +70,7 @@ struct tpacket_auxdata { | |||
70 | #define TP_STATUS_COPY 0x2 | 70 | #define TP_STATUS_COPY 0x2 |
71 | #define TP_STATUS_LOSING 0x4 | 71 | #define TP_STATUS_LOSING 0x4 |
72 | #define TP_STATUS_CSUMNOTREADY 0x8 | 72 | #define TP_STATUS_CSUMNOTREADY 0x8 |
73 | #define TP_STATUS_VLAN_VALID 0x10 /* auxdata has valid tp_vlan_tci */ | ||
73 | 74 | ||
74 | /* Tx ring - header status */ | 75 | /* Tx ring - header status */ |
75 | #define TP_STATUS_AVAILABLE 0x0 | 76 | #define TP_STATUS_AVAILABLE 0x0 |
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 2a78aae78c69..027935c86c68 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h | |||
@@ -264,6 +264,8 @@ struct mm_struct { | |||
264 | 264 | ||
265 | struct linux_binfmt *binfmt; | 265 | struct linux_binfmt *binfmt; |
266 | 266 | ||
267 | cpumask_var_t cpu_vm_mask_var; | ||
268 | |||
267 | /* Architecture-specific MM context */ | 269 | /* Architecture-specific MM context */ |
268 | mm_context_t context; | 270 | mm_context_t context; |
269 | 271 | ||
@@ -311,10 +313,18 @@ struct mm_struct { | |||
311 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 313 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
312 | pgtable_t pmd_huge_pte; /* protected by page_table_lock */ | 314 | pgtable_t pmd_huge_pte; /* protected by page_table_lock */ |
313 | #endif | 315 | #endif |
314 | 316 | #ifdef CONFIG_CPUMASK_OFFSTACK | |
315 | cpumask_var_t cpu_vm_mask_var; | 317 | struct cpumask cpumask_allocation; |
318 | #endif | ||
316 | }; | 319 | }; |
317 | 320 | ||
321 | static inline void mm_init_cpumask(struct mm_struct *mm) | ||
322 | { | ||
323 | #ifdef CONFIG_CPUMASK_OFFSTACK | ||
324 | mm->cpu_vm_mask_var = &mm->cpumask_allocation; | ||
325 | #endif | ||
326 | } | ||
327 | |||
318 | /* Future-safe accessor for struct mm_struct's cpu_vm_mask. */ | 328 | /* Future-safe accessor for struct mm_struct's cpu_vm_mask. */ |
319 | static inline cpumask_t *mm_cpumask(struct mm_struct *mm) | 329 | static inline cpumask_t *mm_cpumask(struct mm_struct *mm) |
320 | { | 330 | { |
diff --git a/include/linux/mtd/physmap.h b/include/linux/mtd/physmap.h index d40bfa1d9c91..e5f21d293c70 100644 --- a/include/linux/mtd/physmap.h +++ b/include/linux/mtd/physmap.h | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/mtd/partitions.h> | 19 | #include <linux/mtd/partitions.h> |
20 | 20 | ||
21 | struct map_info; | 21 | struct map_info; |
22 | struct platform_device; | ||
22 | 23 | ||
23 | struct physmap_flash_data { | 24 | struct physmap_flash_data { |
24 | unsigned int width; | 25 | unsigned int width; |
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index 178fafe0ff93..504b289ba680 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h | |||
@@ -562,6 +562,7 @@ enum { | |||
562 | NFSPROC4_CLNT_LAYOUTGET, | 562 | NFSPROC4_CLNT_LAYOUTGET, |
563 | NFSPROC4_CLNT_GETDEVICEINFO, | 563 | NFSPROC4_CLNT_GETDEVICEINFO, |
564 | NFSPROC4_CLNT_LAYOUTCOMMIT, | 564 | NFSPROC4_CLNT_LAYOUTCOMMIT, |
565 | NFSPROC4_CLNT_LAYOUTRETURN, | ||
565 | }; | 566 | }; |
566 | 567 | ||
567 | /* nfs41 types */ | 568 | /* nfs41 types */ |
@@ -570,9 +571,11 @@ struct nfs4_sessionid { | |||
570 | }; | 571 | }; |
571 | 572 | ||
572 | /* Create Session Flags */ | 573 | /* Create Session Flags */ |
573 | #define SESSION4_PERSIST 0x001 | 574 | #define SESSION4_PERSIST 0x001 |
574 | #define SESSION4_BACK_CHAN 0x002 | 575 | #define SESSION4_BACK_CHAN 0x002 |
575 | #define SESSION4_RDMA 0x004 | 576 | #define SESSION4_RDMA 0x004 |
577 | |||
578 | #define SESSION4_FLAG_MASK_A 0x007 | ||
576 | 579 | ||
577 | enum state_protect_how4 { | 580 | enum state_protect_how4 { |
578 | SP4_NONE = 0, | 581 | SP4_NONE = 0, |
diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h index 91af2e49fa3a..3a34e80ae92f 100644 --- a/include/linux/nfs_page.h +++ b/include/linux/nfs_page.h | |||
@@ -68,7 +68,7 @@ struct nfs_pageio_descriptor { | |||
68 | int pg_ioflags; | 68 | int pg_ioflags; |
69 | int pg_error; | 69 | int pg_error; |
70 | struct pnfs_layout_segment *pg_lseg; | 70 | struct pnfs_layout_segment *pg_lseg; |
71 | int (*pg_test)(struct nfs_pageio_descriptor *, struct nfs_page *, struct nfs_page *); | 71 | bool (*pg_test)(struct nfs_pageio_descriptor *, struct nfs_page *, struct nfs_page *); |
72 | }; | 72 | }; |
73 | 73 | ||
74 | #define NFS_WBACK_BUSY(req) (test_bit(PG_BUSY,&(req)->wb_flags)) | 74 | #define NFS_WBACK_BUSY(req) (test_bit(PG_BUSY,&(req)->wb_flags)) |
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 7e371f7df9c4..5e8444a11adf 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h | |||
@@ -269,6 +269,27 @@ struct nfs4_layoutcommit_data { | |||
269 | struct nfs4_layoutcommit_res res; | 269 | struct nfs4_layoutcommit_res res; |
270 | }; | 270 | }; |
271 | 271 | ||
272 | struct nfs4_layoutreturn_args { | ||
273 | __u32 layout_type; | ||
274 | struct inode *inode; | ||
275 | nfs4_stateid stateid; | ||
276 | struct nfs4_sequence_args seq_args; | ||
277 | }; | ||
278 | |||
279 | struct nfs4_layoutreturn_res { | ||
280 | struct nfs4_sequence_res seq_res; | ||
281 | u32 lrs_present; | ||
282 | nfs4_stateid stateid; | ||
283 | }; | ||
284 | |||
285 | struct nfs4_layoutreturn { | ||
286 | struct nfs4_layoutreturn_args args; | ||
287 | struct nfs4_layoutreturn_res res; | ||
288 | struct rpc_cred *cred; | ||
289 | struct nfs_client *clp; | ||
290 | int rpc_status; | ||
291 | }; | ||
292 | |||
272 | /* | 293 | /* |
273 | * Arguments to the open call. | 294 | * Arguments to the open call. |
274 | */ | 295 | */ |
@@ -1087,6 +1108,7 @@ struct nfs_read_data { | |||
1087 | const struct rpc_call_ops *mds_ops; | 1108 | const struct rpc_call_ops *mds_ops; |
1088 | int (*read_done_cb) (struct rpc_task *task, struct nfs_read_data *data); | 1109 | int (*read_done_cb) (struct rpc_task *task, struct nfs_read_data *data); |
1089 | __u64 mds_offset; | 1110 | __u64 mds_offset; |
1111 | int pnfs_error; | ||
1090 | struct page *page_array[NFS_PAGEVEC_SIZE]; | 1112 | struct page *page_array[NFS_PAGEVEC_SIZE]; |
1091 | }; | 1113 | }; |
1092 | 1114 | ||
@@ -1112,6 +1134,7 @@ struct nfs_write_data { | |||
1112 | unsigned long timestamp; /* For lease renewal */ | 1134 | unsigned long timestamp; /* For lease renewal */ |
1113 | #endif | 1135 | #endif |
1114 | __u64 mds_offset; /* Filelayout dense stripe */ | 1136 | __u64 mds_offset; /* Filelayout dense stripe */ |
1137 | int pnfs_error; | ||
1115 | struct page *page_array[NFS_PAGEVEC_SIZE]; | 1138 | struct page *page_array[NFS_PAGEVEC_SIZE]; |
1116 | }; | 1139 | }; |
1117 | 1140 | ||
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index 79a6700b7162..6081493db68f 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h | |||
@@ -308,7 +308,7 @@ static inline void SetPageUptodate(struct page *page) | |||
308 | { | 308 | { |
309 | #ifdef CONFIG_S390 | 309 | #ifdef CONFIG_S390 |
310 | if (!test_and_set_bit(PG_uptodate, &page->flags)) | 310 | if (!test_and_set_bit(PG_uptodate, &page->flags)) |
311 | page_set_storage_key(page_to_pfn(page), PAGE_DEFAULT_KEY, 0); | 311 | page_set_storage_key(page_to_phys(page), PAGE_DEFAULT_KEY, 0); |
312 | #else | 312 | #else |
313 | /* | 313 | /* |
314 | * Memory barrier must be issued before setting the PG_uptodate bit, | 314 | * Memory barrier must be issued before setting the PG_uptodate bit, |
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 24787b751286..a311008af5e1 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
@@ -2483,6 +2483,7 @@ | |||
2483 | #define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX 0x1c5f | 2483 | #define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX 0x1c5f |
2484 | #define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_0 0x1d40 | 2484 | #define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_0 0x1d40 |
2485 | #define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_1 0x1d41 | 2485 | #define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_1 0x1d41 |
2486 | #define PCI_DEVICE_ID_INTEL_PANTHERPOINT_XHCI 0x1e31 | ||
2486 | #define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MIN 0x1e40 | 2487 | #define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MIN 0x1e40 |
2487 | #define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MAX 0x1e5f | 2488 | #define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MAX 0x1e5f |
2488 | #define PCI_DEVICE_ID_INTEL_DH89XXCC_LPC_MIN 0x2310 | 2489 | #define PCI_DEVICE_ID_INTEL_DH89XXCC_LPC_MIN 0x2310 |
diff --git a/include/linux/pm_qos_params.h b/include/linux/pm_qos_params.h index 77cbddb3784c..a7d87f911cab 100644 --- a/include/linux/pm_qos_params.h +++ b/include/linux/pm_qos_params.h | |||
@@ -16,6 +16,10 @@ | |||
16 | #define PM_QOS_NUM_CLASSES 4 | 16 | #define PM_QOS_NUM_CLASSES 4 |
17 | #define PM_QOS_DEFAULT_VALUE -1 | 17 | #define PM_QOS_DEFAULT_VALUE -1 |
18 | 18 | ||
19 | #define PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC) | ||
20 | #define PM_QOS_NETWORK_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC) | ||
21 | #define PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE 0 | ||
22 | |||
19 | struct pm_qos_request_list { | 23 | struct pm_qos_request_list { |
20 | struct plist_node list; | 24 | struct plist_node list; |
21 | int pm_qos_class; | 25 | int pm_qos_class; |
diff --git a/include/linux/pnfs_osd_xdr.h b/include/linux/pnfs_osd_xdr.h new file mode 100644 index 000000000000..76efbdd01622 --- /dev/null +++ b/include/linux/pnfs_osd_xdr.h | |||
@@ -0,0 +1,345 @@ | |||
1 | /* | ||
2 | * pNFS-osd on-the-wire data structures | ||
3 | * | ||
4 | * Copyright (C) 2007 Panasas Inc. [year of first publication] | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Benny Halevy <bhalevy@panasas.com> | ||
8 | * Boaz Harrosh <bharrosh@panasas.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 | ||
12 | * See the file COPYING included with this distribution for more details. | ||
13 | * | ||
14 | * Redistribution and use in source and binary forms, with or without | ||
15 | * modification, are permitted provided that the following conditions | ||
16 | * are met: | ||
17 | * | ||
18 | * 1. Redistributions of source code must retain the above copyright | ||
19 | * notice, this list of conditions and the following disclaimer. | ||
20 | * 2. Redistributions in binary form must reproduce the above copyright | ||
21 | * notice, this list of conditions and the following disclaimer in the | ||
22 | * documentation and/or other materials provided with the distribution. | ||
23 | * 3. Neither the name of the Panasas company nor the names of its | ||
24 | * contributors may be used to endorse or promote products derived | ||
25 | * from this software without specific prior written permission. | ||
26 | * | ||
27 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
28 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
29 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
30 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
31 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
32 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
33 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
34 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
35 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
36 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
37 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
38 | */ | ||
39 | #ifndef __PNFS_OSD_XDR_H__ | ||
40 | #define __PNFS_OSD_XDR_H__ | ||
41 | |||
42 | #include <linux/nfs_fs.h> | ||
43 | #include <linux/nfs_page.h> | ||
44 | #include <scsi/osd_protocol.h> | ||
45 | |||
46 | #define PNFS_OSD_OSDNAME_MAXSIZE 256 | ||
47 | |||
48 | /* | ||
49 | * draft-ietf-nfsv4-minorversion-22 | ||
50 | * draft-ietf-nfsv4-pnfs-obj-12 | ||
51 | */ | ||
52 | |||
53 | /* Layout Structure */ | ||
54 | |||
55 | enum pnfs_osd_raid_algorithm4 { | ||
56 | PNFS_OSD_RAID_0 = 1, | ||
57 | PNFS_OSD_RAID_4 = 2, | ||
58 | PNFS_OSD_RAID_5 = 3, | ||
59 | PNFS_OSD_RAID_PQ = 4 /* Reed-Solomon P+Q */ | ||
60 | }; | ||
61 | |||
62 | /* struct pnfs_osd_data_map4 { | ||
63 | * uint32_t odm_num_comps; | ||
64 | * length4 odm_stripe_unit; | ||
65 | * uint32_t odm_group_width; | ||
66 | * uint32_t odm_group_depth; | ||
67 | * uint32_t odm_mirror_cnt; | ||
68 | * pnfs_osd_raid_algorithm4 odm_raid_algorithm; | ||
69 | * }; | ||
70 | */ | ||
71 | struct pnfs_osd_data_map { | ||
72 | u32 odm_num_comps; | ||
73 | u64 odm_stripe_unit; | ||
74 | u32 odm_group_width; | ||
75 | u32 odm_group_depth; | ||
76 | u32 odm_mirror_cnt; | ||
77 | u32 odm_raid_algorithm; | ||
78 | }; | ||
79 | |||
80 | /* struct pnfs_osd_objid4 { | ||
81 | * deviceid4 oid_device_id; | ||
82 | * uint64_t oid_partition_id; | ||
83 | * uint64_t oid_object_id; | ||
84 | * }; | ||
85 | */ | ||
86 | struct pnfs_osd_objid { | ||
87 | struct nfs4_deviceid oid_device_id; | ||
88 | u64 oid_partition_id; | ||
89 | u64 oid_object_id; | ||
90 | }; | ||
91 | |||
92 | /* For printout. I use: | ||
93 | * kprint("dev(%llx:%llx)", _DEVID_LO(pointer), _DEVID_HI(pointer)); | ||
94 | * BE style | ||
95 | */ | ||
96 | #define _DEVID_LO(oid_device_id) \ | ||
97 | (unsigned long long)be64_to_cpup((__be64 *)(oid_device_id)->data) | ||
98 | |||
99 | #define _DEVID_HI(oid_device_id) \ | ||
100 | (unsigned long long)be64_to_cpup(((__be64 *)(oid_device_id)->data) + 1) | ||
101 | |||
102 | static inline int | ||
103 | pnfs_osd_objid_xdr_sz(void) | ||
104 | { | ||
105 | return (NFS4_DEVICEID4_SIZE / 4) + 2 + 2; | ||
106 | } | ||
107 | |||
108 | enum pnfs_osd_version { | ||
109 | PNFS_OSD_MISSING = 0, | ||
110 | PNFS_OSD_VERSION_1 = 1, | ||
111 | PNFS_OSD_VERSION_2 = 2 | ||
112 | }; | ||
113 | |||
114 | struct pnfs_osd_opaque_cred { | ||
115 | u32 cred_len; | ||
116 | void *cred; | ||
117 | }; | ||
118 | |||
119 | enum pnfs_osd_cap_key_sec { | ||
120 | PNFS_OSD_CAP_KEY_SEC_NONE = 0, | ||
121 | PNFS_OSD_CAP_KEY_SEC_SSV = 1, | ||
122 | }; | ||
123 | |||
124 | /* struct pnfs_osd_object_cred4 { | ||
125 | * pnfs_osd_objid4 oc_object_id; | ||
126 | * pnfs_osd_version4 oc_osd_version; | ||
127 | * pnfs_osd_cap_key_sec4 oc_cap_key_sec; | ||
128 | * opaque oc_capability_key<>; | ||
129 | * opaque oc_capability<>; | ||
130 | * }; | ||
131 | */ | ||
132 | struct pnfs_osd_object_cred { | ||
133 | struct pnfs_osd_objid oc_object_id; | ||
134 | u32 oc_osd_version; | ||
135 | u32 oc_cap_key_sec; | ||
136 | struct pnfs_osd_opaque_cred oc_cap_key; | ||
137 | struct pnfs_osd_opaque_cred oc_cap; | ||
138 | }; | ||
139 | |||
140 | /* struct pnfs_osd_layout4 { | ||
141 | * pnfs_osd_data_map4 olo_map; | ||
142 | * uint32_t olo_comps_index; | ||
143 | * pnfs_osd_object_cred4 olo_components<>; | ||
144 | * }; | ||
145 | */ | ||
146 | struct pnfs_osd_layout { | ||
147 | struct pnfs_osd_data_map olo_map; | ||
148 | u32 olo_comps_index; | ||
149 | u32 olo_num_comps; | ||
150 | struct pnfs_osd_object_cred *olo_comps; | ||
151 | }; | ||
152 | |||
153 | /* Device Address */ | ||
154 | enum pnfs_osd_targetid_type { | ||
155 | OBJ_TARGET_ANON = 1, | ||
156 | OBJ_TARGET_SCSI_NAME = 2, | ||
157 | OBJ_TARGET_SCSI_DEVICE_ID = 3, | ||
158 | }; | ||
159 | |||
160 | /* union pnfs_osd_targetid4 switch (pnfs_osd_targetid_type4 oti_type) { | ||
161 | * case OBJ_TARGET_SCSI_NAME: | ||
162 | * string oti_scsi_name<>; | ||
163 | * | ||
164 | * case OBJ_TARGET_SCSI_DEVICE_ID: | ||
165 | * opaque oti_scsi_device_id<>; | ||
166 | * | ||
167 | * default: | ||
168 | * void; | ||
169 | * }; | ||
170 | * | ||
171 | * union pnfs_osd_targetaddr4 switch (bool ota_available) { | ||
172 | * case TRUE: | ||
173 | * netaddr4 ota_netaddr; | ||
174 | * case FALSE: | ||
175 | * void; | ||
176 | * }; | ||
177 | * | ||
178 | * struct pnfs_osd_deviceaddr4 { | ||
179 | * pnfs_osd_targetid4 oda_targetid; | ||
180 | * pnfs_osd_targetaddr4 oda_targetaddr; | ||
181 | * uint64_t oda_lun; | ||
182 | * opaque oda_systemid<>; | ||
183 | * pnfs_osd_object_cred4 oda_root_obj_cred; | ||
184 | * opaque oda_osdname<>; | ||
185 | * }; | ||
186 | */ | ||
187 | struct pnfs_osd_targetid { | ||
188 | u32 oti_type; | ||
189 | struct nfs4_string oti_scsi_device_id; | ||
190 | }; | ||
191 | |||
192 | enum { PNFS_OSD_TARGETID_MAX = 1 + PNFS_OSD_OSDNAME_MAXSIZE / 4 }; | ||
193 | |||
194 | /* struct netaddr4 { | ||
195 | * // see struct rpcb in RFC1833 | ||
196 | * string r_netid<>; // network id | ||
197 | * string r_addr<>; // universal address | ||
198 | * }; | ||
199 | */ | ||
200 | struct pnfs_osd_net_addr { | ||
201 | struct nfs4_string r_netid; | ||
202 | struct nfs4_string r_addr; | ||
203 | }; | ||
204 | |||
205 | struct pnfs_osd_targetaddr { | ||
206 | u32 ota_available; | ||
207 | struct pnfs_osd_net_addr ota_netaddr; | ||
208 | }; | ||
209 | |||
210 | enum { | ||
211 | NETWORK_ID_MAX = 16 / 4, | ||
212 | UNIVERSAL_ADDRESS_MAX = 64 / 4, | ||
213 | PNFS_OSD_TARGETADDR_MAX = 3 + NETWORK_ID_MAX + UNIVERSAL_ADDRESS_MAX, | ||
214 | }; | ||
215 | |||
216 | struct pnfs_osd_deviceaddr { | ||
217 | struct pnfs_osd_targetid oda_targetid; | ||
218 | struct pnfs_osd_targetaddr oda_targetaddr; | ||
219 | u8 oda_lun[8]; | ||
220 | struct nfs4_string oda_systemid; | ||
221 | struct pnfs_osd_object_cred oda_root_obj_cred; | ||
222 | struct nfs4_string oda_osdname; | ||
223 | }; | ||
224 | |||
225 | enum { | ||
226 | ODA_OSDNAME_MAX = PNFS_OSD_OSDNAME_MAXSIZE / 4, | ||
227 | PNFS_OSD_DEVICEADDR_MAX = | ||
228 | PNFS_OSD_TARGETID_MAX + PNFS_OSD_TARGETADDR_MAX + | ||
229 | 2 /*oda_lun*/ + | ||
230 | 1 + OSD_SYSTEMID_LEN + | ||
231 | 1 + ODA_OSDNAME_MAX, | ||
232 | }; | ||
233 | |||
234 | /* LAYOUTCOMMIT: layoutupdate */ | ||
235 | |||
236 | /* union pnfs_osd_deltaspaceused4 switch (bool dsu_valid) { | ||
237 | * case TRUE: | ||
238 | * int64_t dsu_delta; | ||
239 | * case FALSE: | ||
240 | * void; | ||
241 | * }; | ||
242 | * | ||
243 | * struct pnfs_osd_layoutupdate4 { | ||
244 | * pnfs_osd_deltaspaceused4 olu_delta_space_used; | ||
245 | * bool olu_ioerr_flag; | ||
246 | * }; | ||
247 | */ | ||
248 | struct pnfs_osd_layoutupdate { | ||
249 | u32 dsu_valid; | ||
250 | s64 dsu_delta; | ||
251 | u32 olu_ioerr_flag; | ||
252 | }; | ||
253 | |||
254 | /* LAYOUTRETURN: I/O Rrror Report */ | ||
255 | |||
256 | enum pnfs_osd_errno { | ||
257 | PNFS_OSD_ERR_EIO = 1, | ||
258 | PNFS_OSD_ERR_NOT_FOUND = 2, | ||
259 | PNFS_OSD_ERR_NO_SPACE = 3, | ||
260 | PNFS_OSD_ERR_BAD_CRED = 4, | ||
261 | PNFS_OSD_ERR_NO_ACCESS = 5, | ||
262 | PNFS_OSD_ERR_UNREACHABLE = 6, | ||
263 | PNFS_OSD_ERR_RESOURCE = 7 | ||
264 | }; | ||
265 | |||
266 | /* struct pnfs_osd_ioerr4 { | ||
267 | * pnfs_osd_objid4 oer_component; | ||
268 | * length4 oer_comp_offset; | ||
269 | * length4 oer_comp_length; | ||
270 | * bool oer_iswrite; | ||
271 | * pnfs_osd_errno4 oer_errno; | ||
272 | * }; | ||
273 | */ | ||
274 | struct pnfs_osd_ioerr { | ||
275 | struct pnfs_osd_objid oer_component; | ||
276 | u64 oer_comp_offset; | ||
277 | u64 oer_comp_length; | ||
278 | u32 oer_iswrite; | ||
279 | u32 oer_errno; | ||
280 | }; | ||
281 | |||
282 | /* OSD XDR API */ | ||
283 | /* Layout helpers */ | ||
284 | /* Layout decoding is done in two parts: | ||
285 | * 1. First Call pnfs_osd_xdr_decode_layout_map to read in only the header part | ||
286 | * of the layout. @iter members need not be initialized. | ||
287 | * Returned: | ||
288 | * @layout members are set. (@layout->olo_comps set to NULL). | ||
289 | * | ||
290 | * Zero on success, or negative error if passed xdr is broken. | ||
291 | * | ||
292 | * 2. 2nd Call pnfs_osd_xdr_decode_layout_comp() in a loop until it returns | ||
293 | * false, to decode the next component. | ||
294 | * Returned: | ||
295 | * true if there is more to decode or false if we are done or error. | ||
296 | * | ||
297 | * Example: | ||
298 | * struct pnfs_osd_xdr_decode_layout_iter iter; | ||
299 | * struct pnfs_osd_layout layout; | ||
300 | * struct pnfs_osd_object_cred comp; | ||
301 | * int status; | ||
302 | * | ||
303 | * status = pnfs_osd_xdr_decode_layout_map(&layout, &iter, xdr); | ||
304 | * if (unlikely(status)) | ||
305 | * goto err; | ||
306 | * while(pnfs_osd_xdr_decode_layout_comp(&comp, &iter, xdr, &status)) { | ||
307 | * // All of @comp strings point to inside the xdr_buffer | ||
308 | * // or scrach buffer. Copy them out to user memory eg. | ||
309 | * copy_single_comp(dest_comp++, &comp); | ||
310 | * } | ||
311 | * if (unlikely(status)) | ||
312 | * goto err; | ||
313 | */ | ||
314 | |||
315 | struct pnfs_osd_xdr_decode_layout_iter { | ||
316 | unsigned total_comps; | ||
317 | unsigned decoded_comps; | ||
318 | }; | ||
319 | |||
320 | extern int pnfs_osd_xdr_decode_layout_map(struct pnfs_osd_layout *layout, | ||
321 | struct pnfs_osd_xdr_decode_layout_iter *iter, struct xdr_stream *xdr); | ||
322 | |||
323 | extern bool pnfs_osd_xdr_decode_layout_comp(struct pnfs_osd_object_cred *comp, | ||
324 | struct pnfs_osd_xdr_decode_layout_iter *iter, struct xdr_stream *xdr, | ||
325 | int *err); | ||
326 | |||
327 | /* Device Info helpers */ | ||
328 | |||
329 | /* Note: All strings inside @deviceaddr point to space inside @p. | ||
330 | * @p should stay valid while @deviceaddr is in use. | ||
331 | */ | ||
332 | extern void pnfs_osd_xdr_decode_deviceaddr( | ||
333 | struct pnfs_osd_deviceaddr *deviceaddr, __be32 *p); | ||
334 | |||
335 | /* layoutupdate (layout_commit) xdr helpers */ | ||
336 | extern int | ||
337 | pnfs_osd_xdr_encode_layoutupdate(struct xdr_stream *xdr, | ||
338 | struct pnfs_osd_layoutupdate *lou); | ||
339 | |||
340 | /* osd_ioerror encoding/decoding (layout_return) */ | ||
341 | /* Client */ | ||
342 | extern __be32 *pnfs_osd_xdr_ioerr_reserve_space(struct xdr_stream *xdr); | ||
343 | extern void pnfs_osd_xdr_encode_ioerr(__be32 *p, struct pnfs_osd_ioerr *ioerr); | ||
344 | |||
345 | #endif /* __PNFS_OSD_XDR_H__ */ | ||
diff --git a/include/linux/sched.h b/include/linux/sched.h index dc8871295a5a..2a8621c4be1e 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -1546,7 +1546,7 @@ struct task_struct { | |||
1546 | #ifdef CONFIG_TRACING | 1546 | #ifdef CONFIG_TRACING |
1547 | /* state flags for use by tracers */ | 1547 | /* state flags for use by tracers */ |
1548 | unsigned long trace; | 1548 | unsigned long trace; |
1549 | /* bitmask of trace recursion */ | 1549 | /* bitmask and counter of trace recursion */ |
1550 | unsigned long trace_recursion; | 1550 | unsigned long trace_recursion; |
1551 | #endif /* CONFIG_TRACING */ | 1551 | #endif /* CONFIG_TRACING */ |
1552 | #ifdef CONFIG_CGROUP_MEM_RES_CTLR /* memcg uses this to do batch job */ | 1552 | #ifdef CONFIG_CGROUP_MEM_RES_CTLR /* memcg uses this to do batch job */ |
@@ -1841,9 +1841,16 @@ static inline void rcu_copy_process(struct task_struct *p) | |||
1841 | #endif | 1841 | #endif |
1842 | 1842 | ||
1843 | #ifdef CONFIG_SMP | 1843 | #ifdef CONFIG_SMP |
1844 | extern void do_set_cpus_allowed(struct task_struct *p, | ||
1845 | const struct cpumask *new_mask); | ||
1846 | |||
1844 | extern int set_cpus_allowed_ptr(struct task_struct *p, | 1847 | extern int set_cpus_allowed_ptr(struct task_struct *p, |
1845 | const struct cpumask *new_mask); | 1848 | const struct cpumask *new_mask); |
1846 | #else | 1849 | #else |
1850 | static inline void do_set_cpus_allowed(struct task_struct *p, | ||
1851 | const struct cpumask *new_mask) | ||
1852 | { | ||
1853 | } | ||
1847 | static inline int set_cpus_allowed_ptr(struct task_struct *p, | 1854 | static inline int set_cpus_allowed_ptr(struct task_struct *p, |
1848 | const struct cpumask *new_mask) | 1855 | const struct cpumask *new_mask) |
1849 | { | 1856 | { |
@@ -2187,7 +2194,6 @@ static inline void mmdrop(struct mm_struct * mm) | |||
2187 | if (unlikely(atomic_dec_and_test(&mm->mm_count))) | 2194 | if (unlikely(atomic_dec_and_test(&mm->mm_count))) |
2188 | __mmdrop(mm); | 2195 | __mmdrop(mm); |
2189 | } | 2196 | } |
2190 | extern int mm_init_cpumask(struct mm_struct *mm, struct mm_struct *oldmm); | ||
2191 | 2197 | ||
2192 | /* mmput gets rid of the mappings and all user-space */ | 2198 | /* mmput gets rid of the mappings and all user-space */ |
2193 | extern void mmput(struct mm_struct *); | 2199 | extern void mmput(struct mm_struct *); |
diff --git a/include/linux/sunrpc/msg_prot.h b/include/linux/sunrpc/msg_prot.h index 77e624883393..c68a147939a6 100644 --- a/include/linux/sunrpc/msg_prot.h +++ b/include/linux/sunrpc/msg_prot.h | |||
@@ -145,6 +145,7 @@ typedef __be32 rpc_fraghdr; | |||
145 | #define RPCBIND_NETID_TCP "tcp" | 145 | #define RPCBIND_NETID_TCP "tcp" |
146 | #define RPCBIND_NETID_UDP6 "udp6" | 146 | #define RPCBIND_NETID_UDP6 "udp6" |
147 | #define RPCBIND_NETID_TCP6 "tcp6" | 147 | #define RPCBIND_NETID_TCP6 "tcp6" |
148 | #define RPCBIND_NETID_LOCAL "local" | ||
148 | 149 | ||
149 | /* | 150 | /* |
150 | * Note that RFC 1833 does not put any size restrictions on the | 151 | * Note that RFC 1833 does not put any size restrictions on the |
diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h index 04dba23c59f2..85c50b40759d 100644 --- a/include/linux/sunrpc/svcsock.h +++ b/include/linux/sunrpc/svcsock.h | |||
@@ -28,6 +28,7 @@ struct svc_sock { | |||
28 | /* private TCP part */ | 28 | /* private TCP part */ |
29 | u32 sk_reclen; /* length of record */ | 29 | u32 sk_reclen; /* length of record */ |
30 | u32 sk_tcplen; /* current read length */ | 30 | u32 sk_tcplen; /* current read length */ |
31 | struct page * sk_pages[RPCSVC_MAXPAGES]; /* received data */ | ||
31 | }; | 32 | }; |
32 | 33 | ||
33 | /* | 34 | /* |
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h index fc84b7a19ca3..a20970ef9e4e 100644 --- a/include/linux/sunrpc/xdr.h +++ b/include/linux/sunrpc/xdr.h | |||
@@ -216,6 +216,8 @@ extern __be32 *xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes); | |||
216 | extern void xdr_write_pages(struct xdr_stream *xdr, struct page **pages, | 216 | extern void xdr_write_pages(struct xdr_stream *xdr, struct page **pages, |
217 | unsigned int base, unsigned int len); | 217 | unsigned int base, unsigned int len); |
218 | extern void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p); | 218 | extern void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p); |
219 | extern void xdr_init_decode_pages(struct xdr_stream *xdr, struct xdr_buf *buf, | ||
220 | struct page **pages, unsigned int len); | ||
219 | extern void xdr_set_scratch_buffer(struct xdr_stream *xdr, void *buf, size_t buflen); | 221 | extern void xdr_set_scratch_buffer(struct xdr_stream *xdr, void *buf, size_t buflen); |
220 | extern __be32 *xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes); | 222 | extern __be32 *xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes); |
221 | extern void xdr_read_pages(struct xdr_stream *xdr, unsigned int len); | 223 | extern void xdr_read_pages(struct xdr_stream *xdr, unsigned int len); |
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h index a0f998c07c65..81cce3b3ee66 100644 --- a/include/linux/sunrpc/xprt.h +++ b/include/linux/sunrpc/xprt.h | |||
@@ -141,7 +141,8 @@ enum xprt_transports { | |||
141 | XPRT_TRANSPORT_UDP = IPPROTO_UDP, | 141 | XPRT_TRANSPORT_UDP = IPPROTO_UDP, |
142 | XPRT_TRANSPORT_TCP = IPPROTO_TCP, | 142 | XPRT_TRANSPORT_TCP = IPPROTO_TCP, |
143 | XPRT_TRANSPORT_BC_TCP = IPPROTO_TCP | XPRT_TRANSPORT_BC, | 143 | XPRT_TRANSPORT_BC_TCP = IPPROTO_TCP | XPRT_TRANSPORT_BC, |
144 | XPRT_TRANSPORT_RDMA = 256 | 144 | XPRT_TRANSPORT_RDMA = 256, |
145 | XPRT_TRANSPORT_LOCAL = 257, | ||
145 | }; | 146 | }; |
146 | 147 | ||
147 | struct rpc_xprt { | 148 | struct rpc_xprt { |
diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h index 5b07792ccb46..ff7dc08696a8 100644 --- a/include/linux/tty_ldisc.h +++ b/include/linux/tty_ldisc.h | |||
@@ -76,7 +76,7 @@ | |||
76 | * tty device. It is solely the responsibility of the line | 76 | * tty device. It is solely the responsibility of the line |
77 | * discipline to handle poll requests. | 77 | * discipline to handle poll requests. |
78 | * | 78 | * |
79 | * unsigned int (*receive_buf)(struct tty_struct *, const unsigned char *cp, | 79 | * void (*receive_buf)(struct tty_struct *, const unsigned char *cp, |
80 | * char *fp, int count); | 80 | * char *fp, int count); |
81 | * | 81 | * |
82 | * This function is called by the low-level tty driver to send | 82 | * This function is called by the low-level tty driver to send |
@@ -84,8 +84,7 @@ | |||
84 | * processing. <cp> is a pointer to the buffer of input | 84 | * processing. <cp> is a pointer to the buffer of input |
85 | * character received by the device. <fp> is a pointer to a | 85 | * character received by the device. <fp> is a pointer to a |
86 | * pointer of flag bytes which indicate whether a character was | 86 | * pointer of flag bytes which indicate whether a character was |
87 | * received with a parity error, etc. Returns the amount of bytes | 87 | * received with a parity error, etc. |
88 | * received. | ||
89 | * | 88 | * |
90 | * void (*write_wakeup)(struct tty_struct *); | 89 | * void (*write_wakeup)(struct tty_struct *); |
91 | * | 90 | * |
@@ -141,8 +140,8 @@ struct tty_ldisc_ops { | |||
141 | /* | 140 | /* |
142 | * The following routines are called from below. | 141 | * The following routines are called from below. |
143 | */ | 142 | */ |
144 | unsigned int (*receive_buf)(struct tty_struct *, | 143 | void (*receive_buf)(struct tty_struct *, const unsigned char *cp, |
145 | const unsigned char *cp, char *fp, int count); | 144 | char *fp, int count); |
146 | void (*write_wakeup)(struct tty_struct *); | 145 | void (*write_wakeup)(struct tty_struct *); |
147 | void (*dcd_change)(struct tty_struct *, unsigned int, | 146 | void (*dcd_change)(struct tty_struct *, unsigned int, |
148 | struct pps_event_time *); | 147 | struct pps_event_time *); |
diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h index d512d98dfb7d..5ca0951e1855 100644 --- a/include/linux/uaccess.h +++ b/include/linux/uaccess.h | |||
@@ -93,8 +93,8 @@ static inline unsigned long __copy_from_user_nocache(void *to, | |||
93 | * Safely read from address @src to the buffer at @dst. If a kernel fault | 93 | * Safely read from address @src to the buffer at @dst. If a kernel fault |
94 | * happens, handle that and return -EFAULT. | 94 | * happens, handle that and return -EFAULT. |
95 | */ | 95 | */ |
96 | extern long probe_kernel_read(void *dst, void *src, size_t size); | 96 | extern long probe_kernel_read(void *dst, const void *src, size_t size); |
97 | extern long __probe_kernel_read(void *dst, void *src, size_t size); | 97 | extern long __probe_kernel_read(void *dst, const void *src, size_t size); |
98 | 98 | ||
99 | /* | 99 | /* |
100 | * probe_kernel_write(): safely attempt to write to a location | 100 | * probe_kernel_write(): safely attempt to write to a location |
@@ -105,7 +105,7 @@ extern long __probe_kernel_read(void *dst, void *src, size_t size); | |||
105 | * Safely write to address @dst from the buffer at @src. If a kernel fault | 105 | * Safely write to address @dst from the buffer at @src. If a kernel fault |
106 | * happens, handle that and return -EFAULT. | 106 | * happens, handle that and return -EFAULT. |
107 | */ | 107 | */ |
108 | extern long notrace probe_kernel_write(void *dst, void *src, size_t size); | 108 | extern long notrace probe_kernel_write(void *dst, const void *src, size_t size); |
109 | extern long notrace __probe_kernel_write(void *dst, void *src, size_t size); | 109 | extern long notrace __probe_kernel_write(void *dst, const void *src, size_t size); |
110 | 110 | ||
111 | #endif /* __LINUX_UACCESS_H__ */ | 111 | #endif /* __LINUX_UACCESS_H__ */ |
diff --git a/include/linux/virtio.h b/include/linux/virtio.h index aff5b4f74041..710885749605 100644 --- a/include/linux/virtio.h +++ b/include/linux/virtio.h | |||
@@ -51,6 +51,13 @@ struct virtqueue { | |||
51 | * This re-enables callbacks; it returns "false" if there are pending | 51 | * This re-enables callbacks; it returns "false" if there are pending |
52 | * buffers in the queue, to detect a possible race between the driver | 52 | * buffers in the queue, to detect a possible race between the driver |
53 | * checking for more work, and enabling callbacks. | 53 | * checking for more work, and enabling callbacks. |
54 | * virtqueue_enable_cb_delayed: restart callbacks after disable_cb. | ||
55 | * vq: the struct virtqueue we're talking about. | ||
56 | * This re-enables callbacks but hints to the other side to delay | ||
57 | * interrupts until most of the available buffers have been processed; | ||
58 | * it returns "false" if there are many pending buffers in the queue, | ||
59 | * to detect a possible race between the driver checking for more work, | ||
60 | * and enabling callbacks. | ||
54 | * virtqueue_detach_unused_buf: detach first unused buffer | 61 | * virtqueue_detach_unused_buf: detach first unused buffer |
55 | * vq: the struct virtqueue we're talking about. | 62 | * vq: the struct virtqueue we're talking about. |
56 | * Returns NULL or the "data" token handed to add_buf | 63 | * Returns NULL or the "data" token handed to add_buf |
@@ -86,6 +93,8 @@ void virtqueue_disable_cb(struct virtqueue *vq); | |||
86 | 93 | ||
87 | bool virtqueue_enable_cb(struct virtqueue *vq); | 94 | bool virtqueue_enable_cb(struct virtqueue *vq); |
88 | 95 | ||
96 | bool virtqueue_enable_cb_delayed(struct virtqueue *vq); | ||
97 | |||
89 | void *virtqueue_detach_unused_buf(struct virtqueue *vq); | 98 | void *virtqueue_detach_unused_buf(struct virtqueue *vq); |
90 | 99 | ||
91 | /** | 100 | /** |
diff --git a/include/linux/virtio_9p.h b/include/linux/virtio_9p.h index e68b439b2860..277c4ad44e84 100644 --- a/include/linux/virtio_9p.h +++ b/include/linux/virtio_9p.h | |||
@@ -1,7 +1,30 @@ | |||
1 | #ifndef _LINUX_VIRTIO_9P_H | 1 | #ifndef _LINUX_VIRTIO_9P_H |
2 | #define _LINUX_VIRTIO_9P_H | 2 | #define _LINUX_VIRTIO_9P_H |
3 | /* This header is BSD licensed so anyone can use the definitions to implement | 3 | /* This header is BSD licensed so anyone can use the definitions to implement |
4 | * compatible drivers/servers. */ | 4 | * compatible drivers/servers. |
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions | ||
8 | * are met: | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * 2. Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * 3. Neither the name of IBM nor the names of its contributors | ||
15 | * may be used to endorse or promote products derived from this software | ||
16 | * without specific prior written permission. | ||
17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND | ||
18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
20 | * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE | ||
21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
27 | * SUCH DAMAGE. */ | ||
5 | #include <linux/types.h> | 28 | #include <linux/types.h> |
6 | #include <linux/virtio_ids.h> | 29 | #include <linux/virtio_ids.h> |
7 | #include <linux/virtio_config.h> | 30 | #include <linux/virtio_config.h> |
diff --git a/include/linux/virtio_balloon.h b/include/linux/virtio_balloon.h index a50ecd1b81a2..652dc8bea921 100644 --- a/include/linux/virtio_balloon.h +++ b/include/linux/virtio_balloon.h | |||
@@ -1,7 +1,30 @@ | |||
1 | #ifndef _LINUX_VIRTIO_BALLOON_H | 1 | #ifndef _LINUX_VIRTIO_BALLOON_H |
2 | #define _LINUX_VIRTIO_BALLOON_H | 2 | #define _LINUX_VIRTIO_BALLOON_H |
3 | /* This header is BSD licensed so anyone can use the definitions to implement | 3 | /* This header is BSD licensed so anyone can use the definitions to implement |
4 | * compatible drivers/servers. */ | 4 | * compatible drivers/servers. |
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions | ||
8 | * are met: | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * 2. Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * 3. Neither the name of IBM nor the names of its contributors | ||
15 | * may be used to endorse or promote products derived from this software | ||
16 | * without specific prior written permission. | ||
17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND | ||
18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
20 | * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE | ||
21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
27 | * SUCH DAMAGE. */ | ||
5 | #include <linux/virtio_ids.h> | 28 | #include <linux/virtio_ids.h> |
6 | #include <linux/virtio_config.h> | 29 | #include <linux/virtio_config.h> |
7 | 30 | ||
diff --git a/include/linux/virtio_blk.h b/include/linux/virtio_blk.h index 167720d695ed..e0edb40ca7aa 100644 --- a/include/linux/virtio_blk.h +++ b/include/linux/virtio_blk.h | |||
@@ -1,7 +1,30 @@ | |||
1 | #ifndef _LINUX_VIRTIO_BLK_H | 1 | #ifndef _LINUX_VIRTIO_BLK_H |
2 | #define _LINUX_VIRTIO_BLK_H | 2 | #define _LINUX_VIRTIO_BLK_H |
3 | /* This header is BSD licensed so anyone can use the definitions to implement | 3 | /* This header is BSD licensed so anyone can use the definitions to implement |
4 | * compatible drivers/servers. */ | 4 | * compatible drivers/servers. |
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions | ||
8 | * are met: | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * 2. Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * 3. Neither the name of IBM nor the names of its contributors | ||
15 | * may be used to endorse or promote products derived from this software | ||
16 | * without specific prior written permission. | ||
17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND | ||
18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
20 | * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE | ||
21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
27 | * SUCH DAMAGE. */ | ||
5 | #include <linux/types.h> | 28 | #include <linux/types.h> |
6 | #include <linux/virtio_ids.h> | 29 | #include <linux/virtio_ids.h> |
7 | #include <linux/virtio_config.h> | 30 | #include <linux/virtio_config.h> |
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h index 800617b4ddd5..39c88c5ad19d 100644 --- a/include/linux/virtio_config.h +++ b/include/linux/virtio_config.h | |||
@@ -1,7 +1,30 @@ | |||
1 | #ifndef _LINUX_VIRTIO_CONFIG_H | 1 | #ifndef _LINUX_VIRTIO_CONFIG_H |
2 | #define _LINUX_VIRTIO_CONFIG_H | 2 | #define _LINUX_VIRTIO_CONFIG_H |
3 | /* This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so | 3 | /* This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so |
4 | * anyone can use the definitions to implement compatible drivers/servers. */ | 4 | * anyone can use the definitions to implement compatible drivers/servers. |
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions | ||
8 | * are met: | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * 2. Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * 3. Neither the name of IBM nor the names of its contributors | ||
15 | * may be used to endorse or promote products derived from this software | ||
16 | * without specific prior written permission. | ||
17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND | ||
18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
20 | * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE | ||
21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
27 | * SUCH DAMAGE. */ | ||
5 | 28 | ||
6 | /* Virtio devices use a standardized configuration space to define their | 29 | /* Virtio devices use a standardized configuration space to define their |
7 | * features and pass configuration information, but each implementation can | 30 | * features and pass configuration information, but each implementation can |
diff --git a/include/linux/virtio_console.h b/include/linux/virtio_console.h index e4d333543a33..bdf4b0034739 100644 --- a/include/linux/virtio_console.h +++ b/include/linux/virtio_console.h | |||
@@ -5,7 +5,31 @@ | |||
5 | #include <linux/virtio_config.h> | 5 | #include <linux/virtio_config.h> |
6 | /* | 6 | /* |
7 | * This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so | 7 | * This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so |
8 | * anyone can use the definitions to implement compatible drivers/servers. | 8 | * anyone can use the definitions to implement compatible drivers/servers: |
9 | * | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer. | ||
16 | * 2. Redistributions in binary form must reproduce the above copyright | ||
17 | * notice, this list of conditions and the following disclaimer in the | ||
18 | * documentation and/or other materials provided with the distribution. | ||
19 | * 3. Neither the name of IBM nor the names of its contributors | ||
20 | * may be used to endorse or promote products derived from this software | ||
21 | * without specific prior written permission. | ||
22 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND | ||
23 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
25 | * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE | ||
26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
32 | * SUCH DAMAGE. | ||
9 | * | 33 | * |
10 | * Copyright (C) Red Hat, Inc., 2009, 2010, 2011 | 34 | * Copyright (C) Red Hat, Inc., 2009, 2010, 2011 |
11 | * Copyright (C) Amit Shah <amit.shah@redhat.com>, 2009, 2010, 2011 | 35 | * Copyright (C) Amit Shah <amit.shah@redhat.com>, 2009, 2010, 2011 |
diff --git a/include/linux/virtio_ids.h b/include/linux/virtio_ids.h index 06660c0a78d7..85bb0bb66ffc 100644 --- a/include/linux/virtio_ids.h +++ b/include/linux/virtio_ids.h | |||
@@ -5,7 +5,29 @@ | |||
5 | * | 5 | * |
6 | * This header is BSD licensed so anyone can use the definitions to implement | 6 | * This header is BSD licensed so anyone can use the definitions to implement |
7 | * compatible drivers/servers. | 7 | * compatible drivers/servers. |
8 | */ | 8 | * |
9 | * Redistribution and use in source and binary forms, with or without | ||
10 | * modification, are permitted provided that the following conditions | ||
11 | * are met: | ||
12 | * 1. Redistributions of source code must retain the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer. | ||
14 | * 2. Redistributions in binary form must reproduce the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer in the | ||
16 | * documentation and/or other materials provided with the distribution. | ||
17 | * 3. Neither the name of IBM nor the names of its contributors | ||
18 | * may be used to endorse or promote products derived from this software | ||
19 | * without specific prior written permission. | ||
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND | ||
21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
23 | * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE | ||
24 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
25 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
26 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
28 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
29 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
30 | * SUCH DAMAGE. */ | ||
9 | 31 | ||
10 | #define VIRTIO_ID_NET 1 /* virtio net */ | 32 | #define VIRTIO_ID_NET 1 /* virtio net */ |
11 | #define VIRTIO_ID_BLOCK 2 /* virtio block */ | 33 | #define VIRTIO_ID_BLOCK 2 /* virtio block */ |
diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h index 085e42298ce5..136040bba3e3 100644 --- a/include/linux/virtio_net.h +++ b/include/linux/virtio_net.h | |||
@@ -1,7 +1,30 @@ | |||
1 | #ifndef _LINUX_VIRTIO_NET_H | 1 | #ifndef _LINUX_VIRTIO_NET_H |
2 | #define _LINUX_VIRTIO_NET_H | 2 | #define _LINUX_VIRTIO_NET_H |
3 | /* This header is BSD licensed so anyone can use the definitions to implement | 3 | /* This header is BSD licensed so anyone can use the definitions to implement |
4 | * compatible drivers/servers. */ | 4 | * compatible drivers/servers. |
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions | ||
8 | * are met: | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * 2. Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * 3. Neither the name of IBM nor the names of its contributors | ||
15 | * may be used to endorse or promote products derived from this software | ||
16 | * without specific prior written permission. | ||
17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND | ||
18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
20 | * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE | ||
21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
27 | * SUCH DAMAGE. */ | ||
5 | #include <linux/types.h> | 28 | #include <linux/types.h> |
6 | #include <linux/virtio_ids.h> | 29 | #include <linux/virtio_ids.h> |
7 | #include <linux/virtio_config.h> | 30 | #include <linux/virtio_config.h> |
diff --git a/include/linux/virtio_pci.h b/include/linux/virtio_pci.h index 9a3d7c48c622..ea66f3f60d63 100644 --- a/include/linux/virtio_pci.h +++ b/include/linux/virtio_pci.h | |||
@@ -11,6 +11,29 @@ | |||
11 | * | 11 | * |
12 | * This header is BSD licensed so anyone can use the definitions to implement | 12 | * This header is BSD licensed so anyone can use the definitions to implement |
13 | * compatible drivers/servers. | 13 | * compatible drivers/servers. |
14 | * | ||
15 | * Redistribution and use in source and binary forms, with or without | ||
16 | * modification, are permitted provided that the following conditions | ||
17 | * are met: | ||
18 | * 1. Redistributions of source code must retain the above copyright | ||
19 | * notice, this list of conditions and the following disclaimer. | ||
20 | * 2. Redistributions in binary form must reproduce the above copyright | ||
21 | * notice, this list of conditions and the following disclaimer in the | ||
22 | * documentation and/or other materials provided with the distribution. | ||
23 | * 3. Neither the name of IBM nor the names of its contributors | ||
24 | * may be used to endorse or promote products derived from this software | ||
25 | * without specific prior written permission. | ||
26 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND | ||
27 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
28 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
29 | * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE | ||
30 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
31 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
32 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
33 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
34 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
35 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
36 | * SUCH DAMAGE. | ||
14 | */ | 37 | */ |
15 | 38 | ||
16 | #ifndef _LINUX_VIRTIO_PCI_H | 39 | #ifndef _LINUX_VIRTIO_PCI_H |
diff --git a/include/linux/virtio_ring.h b/include/linux/virtio_ring.h index e4d144b132b5..4a32cb6da425 100644 --- a/include/linux/virtio_ring.h +++ b/include/linux/virtio_ring.h | |||
@@ -7,6 +7,29 @@ | |||
7 | * This header is BSD licensed so anyone can use the definitions to implement | 7 | * This header is BSD licensed so anyone can use the definitions to implement |
8 | * compatible drivers/servers. | 8 | * compatible drivers/servers. |
9 | * | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | ||
11 | * modification, are permitted provided that the following conditions | ||
12 | * are met: | ||
13 | * 1. Redistributions of source code must retain the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer. | ||
15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer in the | ||
17 | * documentation and/or other materials provided with the distribution. | ||
18 | * 3. Neither the name of IBM nor the names of its contributors | ||
19 | * may be used to endorse or promote products derived from this software | ||
20 | * without specific prior written permission. | ||
21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND | ||
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
24 | * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE | ||
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
31 | * SUCH DAMAGE. | ||
32 | * | ||
10 | * Copyright Rusty Russell IBM Corporation 2007. */ | 33 | * Copyright Rusty Russell IBM Corporation 2007. */ |
11 | #include <linux/types.h> | 34 | #include <linux/types.h> |
12 | 35 | ||
@@ -29,6 +52,12 @@ | |||
29 | /* We support indirect buffer descriptors */ | 52 | /* We support indirect buffer descriptors */ |
30 | #define VIRTIO_RING_F_INDIRECT_DESC 28 | 53 | #define VIRTIO_RING_F_INDIRECT_DESC 28 |
31 | 54 | ||
55 | /* The Guest publishes the used index for which it expects an interrupt | ||
56 | * at the end of the avail ring. Host should ignore the avail->flags field. */ | ||
57 | /* The Host publishes the avail index for which it expects a kick | ||
58 | * at the end of the used ring. Guest should ignore the used->flags field. */ | ||
59 | #define VIRTIO_RING_F_EVENT_IDX 29 | ||
60 | |||
32 | /* Virtio ring descriptors: 16 bytes. These can chain together via "next". */ | 61 | /* Virtio ring descriptors: 16 bytes. These can chain together via "next". */ |
33 | struct vring_desc { | 62 | struct vring_desc { |
34 | /* Address (guest-physical). */ | 63 | /* Address (guest-physical). */ |
@@ -83,6 +112,7 @@ struct vring { | |||
83 | * __u16 avail_flags; | 112 | * __u16 avail_flags; |
84 | * __u16 avail_idx; | 113 | * __u16 avail_idx; |
85 | * __u16 available[num]; | 114 | * __u16 available[num]; |
115 | * __u16 used_event_idx; | ||
86 | * | 116 | * |
87 | * // Padding to the next align boundary. | 117 | * // Padding to the next align boundary. |
88 | * char pad[]; | 118 | * char pad[]; |
@@ -91,8 +121,14 @@ struct vring { | |||
91 | * __u16 used_flags; | 121 | * __u16 used_flags; |
92 | * __u16 used_idx; | 122 | * __u16 used_idx; |
93 | * struct vring_used_elem used[num]; | 123 | * struct vring_used_elem used[num]; |
124 | * __u16 avail_event_idx; | ||
94 | * }; | 125 | * }; |
95 | */ | 126 | */ |
127 | /* We publish the used event index at the end of the available ring, and vice | ||
128 | * versa. They are at the end for backwards compatibility. */ | ||
129 | #define vring_used_event(vr) ((vr)->avail->ring[(vr)->num]) | ||
130 | #define vring_avail_event(vr) (*(__u16 *)&(vr)->used->ring[(vr)->num]) | ||
131 | |||
96 | static inline void vring_init(struct vring *vr, unsigned int num, void *p, | 132 | static inline void vring_init(struct vring *vr, unsigned int num, void *p, |
97 | unsigned long align) | 133 | unsigned long align) |
98 | { | 134 | { |
@@ -107,7 +143,21 @@ static inline unsigned vring_size(unsigned int num, unsigned long align) | |||
107 | { | 143 | { |
108 | return ((sizeof(struct vring_desc) * num + sizeof(__u16) * (2 + num) | 144 | return ((sizeof(struct vring_desc) * num + sizeof(__u16) * (2 + num) |
109 | + align - 1) & ~(align - 1)) | 145 | + align - 1) & ~(align - 1)) |
110 | + sizeof(__u16) * 2 + sizeof(struct vring_used_elem) * num; | 146 | + sizeof(__u16) * 3 + sizeof(struct vring_used_elem) * num; |
147 | } | ||
148 | |||
149 | /* The following is used with USED_EVENT_IDX and AVAIL_EVENT_IDX */ | ||
150 | /* Assuming a given event_idx value from the other size, if | ||
151 | * we have just incremented index from old to new_idx, | ||
152 | * should we trigger an event? */ | ||
153 | static inline int vring_need_event(__u16 event_idx, __u16 new_idx, __u16 old) | ||
154 | { | ||
155 | /* Note: Xen has similar logic for notification hold-off | ||
156 | * in include/xen/interface/io/ring.h with req_event and req_prod | ||
157 | * corresponding to event_idx + 1 and new_idx respectively. | ||
158 | * Note also that req_event and req_prod in Xen start at 1, | ||
159 | * event indexes in virtio start at 0. */ | ||
160 | return (__u16)(new_idx - event_idx - 1) < (__u16)(new_idx - old); | ||
111 | } | 161 | } |
112 | 162 | ||
113 | #ifdef __KERNEL__ | 163 | #ifdef __KERNEL__ |
diff --git a/include/net/sctp/command.h b/include/net/sctp/command.h index 2b447646ce4b..dd6847e5d6e4 100644 --- a/include/net/sctp/command.h +++ b/include/net/sctp/command.h | |||
@@ -107,6 +107,7 @@ typedef enum { | |||
107 | SCTP_CMD_UPDATE_INITTAG, /* Update peer inittag */ | 107 | SCTP_CMD_UPDATE_INITTAG, /* Update peer inittag */ |
108 | SCTP_CMD_SEND_MSG, /* Send the whole use message */ | 108 | SCTP_CMD_SEND_MSG, /* Send the whole use message */ |
109 | SCTP_CMD_SEND_NEXT_ASCONF, /* Send the next ASCONF after ACK */ | 109 | SCTP_CMD_SEND_NEXT_ASCONF, /* Send the next ASCONF after ACK */ |
110 | SCTP_CMD_PURGE_ASCONF_QUEUE, /* Purge all asconf queues.*/ | ||
110 | SCTP_CMD_LAST | 111 | SCTP_CMD_LAST |
111 | } sctp_verb_t; | 112 | } sctp_verb_t; |
112 | 113 | ||
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 795f4886e111..7df327a6d564 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h | |||
@@ -1993,7 +1993,7 @@ void sctp_assoc_clean_asconf_ack_cache(const struct sctp_association *asoc); | |||
1993 | struct sctp_chunk *sctp_assoc_lookup_asconf_ack( | 1993 | struct sctp_chunk *sctp_assoc_lookup_asconf_ack( |
1994 | const struct sctp_association *asoc, | 1994 | const struct sctp_association *asoc, |
1995 | __be32 serial); | 1995 | __be32 serial); |
1996 | 1996 | void sctp_asconf_queue_teardown(struct sctp_association *asoc); | |
1997 | 1997 | ||
1998 | int sctp_cmp_addr_exact(const union sctp_addr *ss1, | 1998 | int sctp_cmp_addr_exact(const union sctp_addr *ss1, |
1999 | const union sctp_addr *ss2); | 1999 | const union sctp_addr *ss2); |
diff --git a/include/trace/events/btrfs.h b/include/trace/events/btrfs.h index f445cff66ab7..4114129f0794 100644 --- a/include/trace/events/btrfs.h +++ b/include/trace/events/btrfs.h | |||
@@ -28,7 +28,7 @@ struct extent_buffer; | |||
28 | { BTRFS_SHARED_DATA_REF_KEY, "SHARED_DATA_REF" }) | 28 | { BTRFS_SHARED_DATA_REF_KEY, "SHARED_DATA_REF" }) |
29 | 29 | ||
30 | #define __show_root_type(obj) \ | 30 | #define __show_root_type(obj) \ |
31 | __print_symbolic(obj, \ | 31 | __print_symbolic_u64(obj, \ |
32 | { BTRFS_ROOT_TREE_OBJECTID, "ROOT_TREE" }, \ | 32 | { BTRFS_ROOT_TREE_OBJECTID, "ROOT_TREE" }, \ |
33 | { BTRFS_EXTENT_TREE_OBJECTID, "EXTENT_TREE" }, \ | 33 | { BTRFS_EXTENT_TREE_OBJECTID, "EXTENT_TREE" }, \ |
34 | { BTRFS_CHUNK_TREE_OBJECTID, "CHUNK_TREE" }, \ | 34 | { BTRFS_CHUNK_TREE_OBJECTID, "CHUNK_TREE" }, \ |
@@ -125,7 +125,7 @@ DEFINE_EVENT(btrfs__inode, btrfs_inode_evict, | |||
125 | ); | 125 | ); |
126 | 126 | ||
127 | #define __show_map_type(type) \ | 127 | #define __show_map_type(type) \ |
128 | __print_symbolic(type, \ | 128 | __print_symbolic_u64(type, \ |
129 | { EXTENT_MAP_LAST_BYTE, "LAST_BYTE" }, \ | 129 | { EXTENT_MAP_LAST_BYTE, "LAST_BYTE" }, \ |
130 | { EXTENT_MAP_HOLE, "HOLE" }, \ | 130 | { EXTENT_MAP_HOLE, "HOLE" }, \ |
131 | { EXTENT_MAP_INLINE, "INLINE" }, \ | 131 | { EXTENT_MAP_INLINE, "INLINE" }, \ |
diff --git a/include/trace/events/net.h b/include/trace/events/net.h index 5f247f5ffc56..f99645d05a8f 100644 --- a/include/trace/events/net.h +++ b/include/trace/events/net.h | |||
@@ -12,22 +12,24 @@ | |||
12 | TRACE_EVENT(net_dev_xmit, | 12 | TRACE_EVENT(net_dev_xmit, |
13 | 13 | ||
14 | TP_PROTO(struct sk_buff *skb, | 14 | TP_PROTO(struct sk_buff *skb, |
15 | int rc), | 15 | int rc, |
16 | struct net_device *dev, | ||
17 | unsigned int skb_len), | ||
16 | 18 | ||
17 | TP_ARGS(skb, rc), | 19 | TP_ARGS(skb, rc, dev, skb_len), |
18 | 20 | ||
19 | TP_STRUCT__entry( | 21 | TP_STRUCT__entry( |
20 | __field( void *, skbaddr ) | 22 | __field( void *, skbaddr ) |
21 | __field( unsigned int, len ) | 23 | __field( unsigned int, len ) |
22 | __field( int, rc ) | 24 | __field( int, rc ) |
23 | __string( name, skb->dev->name ) | 25 | __string( name, dev->name ) |
24 | ), | 26 | ), |
25 | 27 | ||
26 | TP_fast_assign( | 28 | TP_fast_assign( |
27 | __entry->skbaddr = skb; | 29 | __entry->skbaddr = skb; |
28 | __entry->len = skb->len; | 30 | __entry->len = skb_len; |
29 | __entry->rc = rc; | 31 | __entry->rc = rc; |
30 | __assign_str(name, skb->dev->name); | 32 | __assign_str(name, dev->name); |
31 | ), | 33 | ), |
32 | 34 | ||
33 | TP_printk("dev=%s skbaddr=%p len=%u rc=%d", | 35 | TP_printk("dev=%s skbaddr=%p len=%u rc=%d", |
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index 3e68366d485a..533c49f48047 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h | |||
@@ -205,6 +205,19 @@ | |||
205 | ftrace_print_symbols_seq(p, value, symbols); \ | 205 | ftrace_print_symbols_seq(p, value, symbols); \ |
206 | }) | 206 | }) |
207 | 207 | ||
208 | #undef __print_symbolic_u64 | ||
209 | #if BITS_PER_LONG == 32 | ||
210 | #define __print_symbolic_u64(value, symbol_array...) \ | ||
211 | ({ \ | ||
212 | static const struct trace_print_flags_u64 symbols[] = \ | ||
213 | { symbol_array, { -1, NULL } }; \ | ||
214 | ftrace_print_symbols_seq_u64(p, value, symbols); \ | ||
215 | }) | ||
216 | #else | ||
217 | #define __print_symbolic_u64(value, symbol_array...) \ | ||
218 | __print_symbolic(value, symbol_array) | ||
219 | #endif | ||
220 | |||
208 | #undef __print_hex | 221 | #undef __print_hex |
209 | #define __print_hex(buf, buf_len) ftrace_print_hex_seq(p, buf, buf_len) | 222 | #define __print_hex(buf, buf_len) ftrace_print_hex_seq(p, buf, buf_len) |
210 | 223 | ||
diff --git a/init/main.c b/init/main.c index d2f1e086bf33..cafba67c13bf 100644 --- a/init/main.c +++ b/init/main.c | |||
@@ -487,6 +487,7 @@ asmlinkage void __init start_kernel(void) | |||
487 | printk(KERN_NOTICE "%s", linux_banner); | 487 | printk(KERN_NOTICE "%s", linux_banner); |
488 | setup_arch(&command_line); | 488 | setup_arch(&command_line); |
489 | mm_init_owner(&init_mm, &init_task); | 489 | mm_init_owner(&init_mm, &init_task); |
490 | mm_init_cpumask(&init_mm); | ||
490 | setup_command_line(command_line); | 491 | setup_command_line(command_line); |
491 | setup_nr_cpu_ids(); | 492 | setup_nr_cpu_ids(); |
492 | setup_per_cpu_areas(); | 493 | setup_per_cpu_areas(); |
@@ -510,7 +511,6 @@ asmlinkage void __init start_kernel(void) | |||
510 | sort_main_extable(); | 511 | sort_main_extable(); |
511 | trap_init(); | 512 | trap_init(); |
512 | mm_init(); | 513 | mm_init(); |
513 | BUG_ON(mm_init_cpumask(&init_mm, 0)); | ||
514 | 514 | ||
515 | /* | 515 | /* |
516 | * Set up the scheduler prior starting any interrupts (such as the | 516 | * Set up the scheduler prior starting any interrupts (such as the |
diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 1ceeb049c827..9c9b7545c810 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c | |||
@@ -2190,7 +2190,7 @@ int cpuset_cpus_allowed_fallback(struct task_struct *tsk) | |||
2190 | rcu_read_lock(); | 2190 | rcu_read_lock(); |
2191 | cs = task_cs(tsk); | 2191 | cs = task_cs(tsk); |
2192 | if (cs) | 2192 | if (cs) |
2193 | cpumask_copy(&tsk->cpus_allowed, cs->cpus_allowed); | 2193 | do_set_cpus_allowed(tsk, cs->cpus_allowed); |
2194 | rcu_read_unlock(); | 2194 | rcu_read_unlock(); |
2195 | 2195 | ||
2196 | /* | 2196 | /* |
@@ -2217,7 +2217,7 @@ int cpuset_cpus_allowed_fallback(struct task_struct *tsk) | |||
2217 | * Like above we can temporary set any mask and rely on | 2217 | * Like above we can temporary set any mask and rely on |
2218 | * set_cpus_allowed_ptr() as synchronization point. | 2218 | * set_cpus_allowed_ptr() as synchronization point. |
2219 | */ | 2219 | */ |
2220 | cpumask_copy(&tsk->cpus_allowed, cpu_possible_mask); | 2220 | do_set_cpus_allowed(tsk, cpu_possible_mask); |
2221 | cpu = cpumask_any(cpu_active_mask); | 2221 | cpu = cpumask_any(cpu_active_mask); |
2222 | } | 2222 | } |
2223 | 2223 | ||
diff --git a/kernel/events/core.c b/kernel/events/core.c index c09767f7db3e..d863b3c057bb 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
@@ -5028,6 +5028,14 @@ static int __perf_event_overflow(struct perf_event *event, int nmi, | |||
5028 | else | 5028 | else |
5029 | perf_event_output(event, nmi, data, regs); | 5029 | perf_event_output(event, nmi, data, regs); |
5030 | 5030 | ||
5031 | if (event->fasync && event->pending_kill) { | ||
5032 | if (nmi) { | ||
5033 | event->pending_wakeup = 1; | ||
5034 | irq_work_queue(&event->pending); | ||
5035 | } else | ||
5036 | perf_event_wakeup(event); | ||
5037 | } | ||
5038 | |||
5031 | return ret; | 5039 | return ret; |
5032 | } | 5040 | } |
5033 | 5041 | ||
diff --git a/kernel/fork.c b/kernel/fork.c index ca406d916713..0276c30401a0 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -484,20 +484,6 @@ static void mm_init_aio(struct mm_struct *mm) | |||
484 | #endif | 484 | #endif |
485 | } | 485 | } |
486 | 486 | ||
487 | int mm_init_cpumask(struct mm_struct *mm, struct mm_struct *oldmm) | ||
488 | { | ||
489 | #ifdef CONFIG_CPUMASK_OFFSTACK | ||
490 | if (!alloc_cpumask_var(&mm->cpu_vm_mask_var, GFP_KERNEL)) | ||
491 | return -ENOMEM; | ||
492 | |||
493 | if (oldmm) | ||
494 | cpumask_copy(mm_cpumask(mm), mm_cpumask(oldmm)); | ||
495 | else | ||
496 | memset(mm_cpumask(mm), 0, cpumask_size()); | ||
497 | #endif | ||
498 | return 0; | ||
499 | } | ||
500 | |||
501 | static struct mm_struct * mm_init(struct mm_struct * mm, struct task_struct *p) | 487 | static struct mm_struct * mm_init(struct mm_struct * mm, struct task_struct *p) |
502 | { | 488 | { |
503 | atomic_set(&mm->mm_users, 1); | 489 | atomic_set(&mm->mm_users, 1); |
@@ -538,17 +524,8 @@ struct mm_struct * mm_alloc(void) | |||
538 | return NULL; | 524 | return NULL; |
539 | 525 | ||
540 | memset(mm, 0, sizeof(*mm)); | 526 | memset(mm, 0, sizeof(*mm)); |
541 | mm = mm_init(mm, current); | 527 | mm_init_cpumask(mm); |
542 | if (!mm) | 528 | return mm_init(mm, current); |
543 | return NULL; | ||
544 | |||
545 | if (mm_init_cpumask(mm, NULL)) { | ||
546 | mm_free_pgd(mm); | ||
547 | free_mm(mm); | ||
548 | return NULL; | ||
549 | } | ||
550 | |||
551 | return mm; | ||
552 | } | 529 | } |
553 | 530 | ||
554 | /* | 531 | /* |
@@ -559,7 +536,6 @@ struct mm_struct * mm_alloc(void) | |||
559 | void __mmdrop(struct mm_struct *mm) | 536 | void __mmdrop(struct mm_struct *mm) |
560 | { | 537 | { |
561 | BUG_ON(mm == &init_mm); | 538 | BUG_ON(mm == &init_mm); |
562 | free_cpumask_var(mm->cpu_vm_mask_var); | ||
563 | mm_free_pgd(mm); | 539 | mm_free_pgd(mm); |
564 | destroy_context(mm); | 540 | destroy_context(mm); |
565 | mmu_notifier_mm_destroy(mm); | 541 | mmu_notifier_mm_destroy(mm); |
@@ -753,6 +729,7 @@ struct mm_struct *dup_mm(struct task_struct *tsk) | |||
753 | goto fail_nomem; | 729 | goto fail_nomem; |
754 | 730 | ||
755 | memcpy(mm, oldmm, sizeof(*mm)); | 731 | memcpy(mm, oldmm, sizeof(*mm)); |
732 | mm_init_cpumask(mm); | ||
756 | 733 | ||
757 | /* Initializing for Swap token stuff */ | 734 | /* Initializing for Swap token stuff */ |
758 | mm->token_priority = 0; | 735 | mm->token_priority = 0; |
@@ -765,9 +742,6 @@ struct mm_struct *dup_mm(struct task_struct *tsk) | |||
765 | if (!mm_init(mm, tsk)) | 742 | if (!mm_init(mm, tsk)) |
766 | goto fail_nomem; | 743 | goto fail_nomem; |
767 | 744 | ||
768 | if (mm_init_cpumask(mm, oldmm)) | ||
769 | goto fail_nocpumask; | ||
770 | |||
771 | if (init_new_context(tsk, mm)) | 745 | if (init_new_context(tsk, mm)) |
772 | goto fail_nocontext; | 746 | goto fail_nocontext; |
773 | 747 | ||
@@ -794,9 +768,6 @@ fail_nomem: | |||
794 | return NULL; | 768 | return NULL; |
795 | 769 | ||
796 | fail_nocontext: | 770 | fail_nocontext: |
797 | free_cpumask_var(mm->cpu_vm_mask_var); | ||
798 | |||
799 | fail_nocpumask: | ||
800 | /* | 771 | /* |
801 | * If init_new_context() failed, we cannot use mmput() to free the mm | 772 | * If init_new_context() failed, we cannot use mmput() to free the mm |
802 | * because it calls destroy_context() | 773 | * because it calls destroy_context() |
@@ -1591,6 +1562,13 @@ void __init proc_caches_init(void) | |||
1591 | fs_cachep = kmem_cache_create("fs_cache", | 1562 | fs_cachep = kmem_cache_create("fs_cache", |
1592 | sizeof(struct fs_struct), 0, | 1563 | sizeof(struct fs_struct), 0, |
1593 | SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL); | 1564 | SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL); |
1565 | /* | ||
1566 | * FIXME! The "sizeof(struct mm_struct)" currently includes the | ||
1567 | * whole struct cpumask for the OFFSTACK case. We could change | ||
1568 | * this to *only* allocate as much of it as required by the | ||
1569 | * maximum number of CPU's we can ever have. The cpumask_allocation | ||
1570 | * is at the end of the structure, exactly for that reason. | ||
1571 | */ | ||
1594 | mm_cachep = kmem_cache_create("mm_struct", | 1572 | mm_cachep = kmem_cache_create("mm_struct", |
1595 | sizeof(struct mm_struct), ARCH_MIN_MMSTRUCT_ALIGN, | 1573 | sizeof(struct mm_struct), ARCH_MIN_MMSTRUCT_ALIGN, |
1596 | SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL); | 1574 | SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL); |
diff --git a/kernel/jump_label.c b/kernel/jump_label.c index 74d1c099fbd1..fa27e750dbc0 100644 --- a/kernel/jump_label.c +++ b/kernel/jump_label.c | |||
@@ -105,9 +105,12 @@ static int __jump_label_text_reserved(struct jump_entry *iter_start, | |||
105 | } | 105 | } |
106 | 106 | ||
107 | static void __jump_label_update(struct jump_label_key *key, | 107 | static void __jump_label_update(struct jump_label_key *key, |
108 | struct jump_entry *entry, int enable) | 108 | struct jump_entry *entry, |
109 | struct jump_entry *stop, int enable) | ||
109 | { | 110 | { |
110 | for (; entry->key == (jump_label_t)(unsigned long)key; entry++) { | 111 | for (; (entry < stop) && |
112 | (entry->key == (jump_label_t)(unsigned long)key); | ||
113 | entry++) { | ||
111 | /* | 114 | /* |
112 | * entry->code set to 0 invalidates module init text sections | 115 | * entry->code set to 0 invalidates module init text sections |
113 | * kernel_text_address() verifies we are not in core kernel | 116 | * kernel_text_address() verifies we are not in core kernel |
@@ -181,7 +184,11 @@ static void __jump_label_mod_update(struct jump_label_key *key, int enable) | |||
181 | struct jump_label_mod *mod = key->next; | 184 | struct jump_label_mod *mod = key->next; |
182 | 185 | ||
183 | while (mod) { | 186 | while (mod) { |
184 | __jump_label_update(key, mod->entries, enable); | 187 | struct module *m = mod->mod; |
188 | |||
189 | __jump_label_update(key, mod->entries, | ||
190 | m->jump_entries + m->num_jump_entries, | ||
191 | enable); | ||
185 | mod = mod->next; | 192 | mod = mod->next; |
186 | } | 193 | } |
187 | } | 194 | } |
@@ -245,7 +252,8 @@ static int jump_label_add_module(struct module *mod) | |||
245 | key->next = jlm; | 252 | key->next = jlm; |
246 | 253 | ||
247 | if (jump_label_enabled(key)) | 254 | if (jump_label_enabled(key)) |
248 | __jump_label_update(key, iter, JUMP_LABEL_ENABLE); | 255 | __jump_label_update(key, iter, iter_stop, |
256 | JUMP_LABEL_ENABLE); | ||
249 | } | 257 | } |
250 | 258 | ||
251 | return 0; | 259 | return 0; |
@@ -371,7 +379,7 @@ static void jump_label_update(struct jump_label_key *key, int enable) | |||
371 | 379 | ||
372 | /* if there are no users, entry can be NULL */ | 380 | /* if there are no users, entry can be NULL */ |
373 | if (entry) | 381 | if (entry) |
374 | __jump_label_update(key, entry, enable); | 382 | __jump_label_update(key, entry, __stop___jump_table, enable); |
375 | 383 | ||
376 | #ifdef CONFIG_MODULES | 384 | #ifdef CONFIG_MODULES |
377 | __jump_label_mod_update(key, enable); | 385 | __jump_label_mod_update(key, enable); |
diff --git a/kernel/kthread.c b/kernel/kthread.c index 3b34d2732bce..4ba7cccb4994 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c | |||
@@ -202,8 +202,8 @@ void kthread_bind(struct task_struct *p, unsigned int cpu) | |||
202 | return; | 202 | return; |
203 | } | 203 | } |
204 | 204 | ||
205 | p->cpus_allowed = cpumask_of_cpu(cpu); | 205 | /* It's safe because the task is inactive. */ |
206 | p->rt.nr_cpus_allowed = 1; | 206 | do_set_cpus_allowed(p, cpumask_of(cpu)); |
207 | p->flags |= PF_THREAD_BOUND; | 207 | p->flags |= PF_THREAD_BOUND; |
208 | } | 208 | } |
209 | EXPORT_SYMBOL(kthread_bind); | 209 | EXPORT_SYMBOL(kthread_bind); |
diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c index fd8d1e035df9..6824ca7d4d0c 100644 --- a/kernel/pm_qos_params.c +++ b/kernel/pm_qos_params.c | |||
@@ -54,11 +54,17 @@ enum pm_qos_type { | |||
54 | PM_QOS_MIN /* return the smallest value */ | 54 | PM_QOS_MIN /* return the smallest value */ |
55 | }; | 55 | }; |
56 | 56 | ||
57 | /* | ||
58 | * Note: The lockless read path depends on the CPU accessing | ||
59 | * target_value atomically. Atomic access is only guaranteed on all CPU | ||
60 | * types linux supports for 32 bit quantites | ||
61 | */ | ||
57 | struct pm_qos_object { | 62 | struct pm_qos_object { |
58 | struct plist_head requests; | 63 | struct plist_head requests; |
59 | struct blocking_notifier_head *notifiers; | 64 | struct blocking_notifier_head *notifiers; |
60 | struct miscdevice pm_qos_power_miscdev; | 65 | struct miscdevice pm_qos_power_miscdev; |
61 | char *name; | 66 | char *name; |
67 | s32 target_value; /* Do not change to 64 bit */ | ||
62 | s32 default_value; | 68 | s32 default_value; |
63 | enum pm_qos_type type; | 69 | enum pm_qos_type type; |
64 | }; | 70 | }; |
@@ -71,7 +77,8 @@ static struct pm_qos_object cpu_dma_pm_qos = { | |||
71 | .requests = PLIST_HEAD_INIT(cpu_dma_pm_qos.requests, pm_qos_lock), | 77 | .requests = PLIST_HEAD_INIT(cpu_dma_pm_qos.requests, pm_qos_lock), |
72 | .notifiers = &cpu_dma_lat_notifier, | 78 | .notifiers = &cpu_dma_lat_notifier, |
73 | .name = "cpu_dma_latency", | 79 | .name = "cpu_dma_latency", |
74 | .default_value = 2000 * USEC_PER_SEC, | 80 | .target_value = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE, |
81 | .default_value = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE, | ||
75 | .type = PM_QOS_MIN, | 82 | .type = PM_QOS_MIN, |
76 | }; | 83 | }; |
77 | 84 | ||
@@ -80,7 +87,8 @@ static struct pm_qos_object network_lat_pm_qos = { | |||
80 | .requests = PLIST_HEAD_INIT(network_lat_pm_qos.requests, pm_qos_lock), | 87 | .requests = PLIST_HEAD_INIT(network_lat_pm_qos.requests, pm_qos_lock), |
81 | .notifiers = &network_lat_notifier, | 88 | .notifiers = &network_lat_notifier, |
82 | .name = "network_latency", | 89 | .name = "network_latency", |
83 | .default_value = 2000 * USEC_PER_SEC, | 90 | .target_value = PM_QOS_NETWORK_LAT_DEFAULT_VALUE, |
91 | .default_value = PM_QOS_NETWORK_LAT_DEFAULT_VALUE, | ||
84 | .type = PM_QOS_MIN | 92 | .type = PM_QOS_MIN |
85 | }; | 93 | }; |
86 | 94 | ||
@@ -90,7 +98,8 @@ static struct pm_qos_object network_throughput_pm_qos = { | |||
90 | .requests = PLIST_HEAD_INIT(network_throughput_pm_qos.requests, pm_qos_lock), | 98 | .requests = PLIST_HEAD_INIT(network_throughput_pm_qos.requests, pm_qos_lock), |
91 | .notifiers = &network_throughput_notifier, | 99 | .notifiers = &network_throughput_notifier, |
92 | .name = "network_throughput", | 100 | .name = "network_throughput", |
93 | .default_value = 0, | 101 | .target_value = PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE, |
102 | .default_value = PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE, | ||
94 | .type = PM_QOS_MAX, | 103 | .type = PM_QOS_MAX, |
95 | }; | 104 | }; |
96 | 105 | ||
@@ -136,6 +145,16 @@ static inline int pm_qos_get_value(struct pm_qos_object *o) | |||
136 | } | 145 | } |
137 | } | 146 | } |
138 | 147 | ||
148 | static inline s32 pm_qos_read_value(struct pm_qos_object *o) | ||
149 | { | ||
150 | return o->target_value; | ||
151 | } | ||
152 | |||
153 | static inline void pm_qos_set_value(struct pm_qos_object *o, s32 value) | ||
154 | { | ||
155 | o->target_value = value; | ||
156 | } | ||
157 | |||
139 | static void update_target(struct pm_qos_object *o, struct plist_node *node, | 158 | static void update_target(struct pm_qos_object *o, struct plist_node *node, |
140 | int del, int value) | 159 | int del, int value) |
141 | { | 160 | { |
@@ -160,6 +179,7 @@ static void update_target(struct pm_qos_object *o, struct plist_node *node, | |||
160 | plist_add(node, &o->requests); | 179 | plist_add(node, &o->requests); |
161 | } | 180 | } |
162 | curr_value = pm_qos_get_value(o); | 181 | curr_value = pm_qos_get_value(o); |
182 | pm_qos_set_value(o, curr_value); | ||
163 | spin_unlock_irqrestore(&pm_qos_lock, flags); | 183 | spin_unlock_irqrestore(&pm_qos_lock, flags); |
164 | 184 | ||
165 | if (prev_value != curr_value) | 185 | if (prev_value != curr_value) |
@@ -194,18 +214,11 @@ static int find_pm_qos_object_by_minor(int minor) | |||
194 | * pm_qos_request - returns current system wide qos expectation | 214 | * pm_qos_request - returns current system wide qos expectation |
195 | * @pm_qos_class: identification of which qos value is requested | 215 | * @pm_qos_class: identification of which qos value is requested |
196 | * | 216 | * |
197 | * This function returns the current target value in an atomic manner. | 217 | * This function returns the current target value. |
198 | */ | 218 | */ |
199 | int pm_qos_request(int pm_qos_class) | 219 | int pm_qos_request(int pm_qos_class) |
200 | { | 220 | { |
201 | unsigned long flags; | 221 | return pm_qos_read_value(pm_qos_array[pm_qos_class]); |
202 | int value; | ||
203 | |||
204 | spin_lock_irqsave(&pm_qos_lock, flags); | ||
205 | value = pm_qos_get_value(pm_qos_array[pm_qos_class]); | ||
206 | spin_unlock_irqrestore(&pm_qos_lock, flags); | ||
207 | |||
208 | return value; | ||
209 | } | 222 | } |
210 | EXPORT_SYMBOL_GPL(pm_qos_request); | 223 | EXPORT_SYMBOL_GPL(pm_qos_request); |
211 | 224 | ||
diff --git a/kernel/rcutree.c b/kernel/rcutree.c index f07d2f03181a..89419ff92e99 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c | |||
@@ -36,7 +36,7 @@ | |||
36 | #include <linux/interrupt.h> | 36 | #include <linux/interrupt.h> |
37 | #include <linux/sched.h> | 37 | #include <linux/sched.h> |
38 | #include <linux/nmi.h> | 38 | #include <linux/nmi.h> |
39 | #include <asm/atomic.h> | 39 | #include <linux/atomic.h> |
40 | #include <linux/bitops.h> | 40 | #include <linux/bitops.h> |
41 | #include <linux/module.h> | 41 | #include <linux/module.h> |
42 | #include <linux/completion.h> | 42 | #include <linux/completion.h> |
@@ -95,7 +95,6 @@ static DEFINE_PER_CPU(struct task_struct *, rcu_cpu_kthread_task); | |||
95 | DEFINE_PER_CPU(unsigned int, rcu_cpu_kthread_status); | 95 | DEFINE_PER_CPU(unsigned int, rcu_cpu_kthread_status); |
96 | DEFINE_PER_CPU(int, rcu_cpu_kthread_cpu); | 96 | DEFINE_PER_CPU(int, rcu_cpu_kthread_cpu); |
97 | DEFINE_PER_CPU(unsigned int, rcu_cpu_kthread_loops); | 97 | DEFINE_PER_CPU(unsigned int, rcu_cpu_kthread_loops); |
98 | static DEFINE_PER_CPU(wait_queue_head_t, rcu_cpu_wq); | ||
99 | DEFINE_PER_CPU(char, rcu_cpu_has_work); | 98 | DEFINE_PER_CPU(char, rcu_cpu_has_work); |
100 | static char rcu_kthreads_spawnable; | 99 | static char rcu_kthreads_spawnable; |
101 | 100 | ||
@@ -163,7 +162,7 @@ EXPORT_SYMBOL_GPL(rcu_note_context_switch); | |||
163 | #ifdef CONFIG_NO_HZ | 162 | #ifdef CONFIG_NO_HZ |
164 | DEFINE_PER_CPU(struct rcu_dynticks, rcu_dynticks) = { | 163 | DEFINE_PER_CPU(struct rcu_dynticks, rcu_dynticks) = { |
165 | .dynticks_nesting = 1, | 164 | .dynticks_nesting = 1, |
166 | .dynticks = 1, | 165 | .dynticks = ATOMIC_INIT(1), |
167 | }; | 166 | }; |
168 | #endif /* #ifdef CONFIG_NO_HZ */ | 167 | #endif /* #ifdef CONFIG_NO_HZ */ |
169 | 168 | ||
@@ -322,13 +321,25 @@ void rcu_enter_nohz(void) | |||
322 | unsigned long flags; | 321 | unsigned long flags; |
323 | struct rcu_dynticks *rdtp; | 322 | struct rcu_dynticks *rdtp; |
324 | 323 | ||
325 | smp_mb(); /* CPUs seeing ++ must see prior RCU read-side crit sects */ | ||
326 | local_irq_save(flags); | 324 | local_irq_save(flags); |
327 | rdtp = &__get_cpu_var(rcu_dynticks); | 325 | rdtp = &__get_cpu_var(rcu_dynticks); |
328 | rdtp->dynticks++; | 326 | if (--rdtp->dynticks_nesting) { |
329 | rdtp->dynticks_nesting--; | 327 | local_irq_restore(flags); |
330 | WARN_ON_ONCE(rdtp->dynticks & 0x1); | 328 | return; |
329 | } | ||
330 | /* CPUs seeing atomic_inc() must see prior RCU read-side crit sects */ | ||
331 | smp_mb__before_atomic_inc(); /* See above. */ | ||
332 | atomic_inc(&rdtp->dynticks); | ||
333 | smp_mb__after_atomic_inc(); /* Force ordering with next sojourn. */ | ||
334 | WARN_ON_ONCE(atomic_read(&rdtp->dynticks) & 0x1); | ||
331 | local_irq_restore(flags); | 335 | local_irq_restore(flags); |
336 | |||
337 | /* If the interrupt queued a callback, get out of dyntick mode. */ | ||
338 | if (in_irq() && | ||
339 | (__get_cpu_var(rcu_sched_data).nxtlist || | ||
340 | __get_cpu_var(rcu_bh_data).nxtlist || | ||
341 | rcu_preempt_needs_cpu(smp_processor_id()))) | ||
342 | set_need_resched(); | ||
332 | } | 343 | } |
333 | 344 | ||
334 | /* | 345 | /* |
@@ -344,11 +355,16 @@ void rcu_exit_nohz(void) | |||
344 | 355 | ||
345 | local_irq_save(flags); | 356 | local_irq_save(flags); |
346 | rdtp = &__get_cpu_var(rcu_dynticks); | 357 | rdtp = &__get_cpu_var(rcu_dynticks); |
347 | rdtp->dynticks++; | 358 | if (rdtp->dynticks_nesting++) { |
348 | rdtp->dynticks_nesting++; | 359 | local_irq_restore(flags); |
349 | WARN_ON_ONCE(!(rdtp->dynticks & 0x1)); | 360 | return; |
361 | } | ||
362 | smp_mb__before_atomic_inc(); /* Force ordering w/previous sojourn. */ | ||
363 | atomic_inc(&rdtp->dynticks); | ||
364 | /* CPUs seeing atomic_inc() must see later RCU read-side crit sects */ | ||
365 | smp_mb__after_atomic_inc(); /* See above. */ | ||
366 | WARN_ON_ONCE(!(atomic_read(&rdtp->dynticks) & 0x1)); | ||
350 | local_irq_restore(flags); | 367 | local_irq_restore(flags); |
351 | smp_mb(); /* CPUs seeing ++ must see later RCU read-side crit sects */ | ||
352 | } | 368 | } |
353 | 369 | ||
354 | /** | 370 | /** |
@@ -362,11 +378,15 @@ void rcu_nmi_enter(void) | |||
362 | { | 378 | { |
363 | struct rcu_dynticks *rdtp = &__get_cpu_var(rcu_dynticks); | 379 | struct rcu_dynticks *rdtp = &__get_cpu_var(rcu_dynticks); |
364 | 380 | ||
365 | if (rdtp->dynticks & 0x1) | 381 | if (rdtp->dynticks_nmi_nesting == 0 && |
382 | (atomic_read(&rdtp->dynticks) & 0x1)) | ||
366 | return; | 383 | return; |
367 | rdtp->dynticks_nmi++; | 384 | rdtp->dynticks_nmi_nesting++; |
368 | WARN_ON_ONCE(!(rdtp->dynticks_nmi & 0x1)); | 385 | smp_mb__before_atomic_inc(); /* Force delay from prior write. */ |
369 | smp_mb(); /* CPUs seeing ++ must see later RCU read-side crit sects */ | 386 | atomic_inc(&rdtp->dynticks); |
387 | /* CPUs seeing atomic_inc() must see later RCU read-side crit sects */ | ||
388 | smp_mb__after_atomic_inc(); /* See above. */ | ||
389 | WARN_ON_ONCE(!(atomic_read(&rdtp->dynticks) & 0x1)); | ||
370 | } | 390 | } |
371 | 391 | ||
372 | /** | 392 | /** |
@@ -380,11 +400,14 @@ void rcu_nmi_exit(void) | |||
380 | { | 400 | { |
381 | struct rcu_dynticks *rdtp = &__get_cpu_var(rcu_dynticks); | 401 | struct rcu_dynticks *rdtp = &__get_cpu_var(rcu_dynticks); |
382 | 402 | ||
383 | if (rdtp->dynticks & 0x1) | 403 | if (rdtp->dynticks_nmi_nesting == 0 || |
404 | --rdtp->dynticks_nmi_nesting != 0) | ||
384 | return; | 405 | return; |
385 | smp_mb(); /* CPUs seeing ++ must see prior RCU read-side crit sects */ | 406 | /* CPUs seeing atomic_inc() must see prior RCU read-side crit sects */ |
386 | rdtp->dynticks_nmi++; | 407 | smp_mb__before_atomic_inc(); /* See above. */ |
387 | WARN_ON_ONCE(rdtp->dynticks_nmi & 0x1); | 408 | atomic_inc(&rdtp->dynticks); |
409 | smp_mb__after_atomic_inc(); /* Force delay to next write. */ | ||
410 | WARN_ON_ONCE(atomic_read(&rdtp->dynticks) & 0x1); | ||
388 | } | 411 | } |
389 | 412 | ||
390 | /** | 413 | /** |
@@ -395,13 +418,7 @@ void rcu_nmi_exit(void) | |||
395 | */ | 418 | */ |
396 | void rcu_irq_enter(void) | 419 | void rcu_irq_enter(void) |
397 | { | 420 | { |
398 | struct rcu_dynticks *rdtp = &__get_cpu_var(rcu_dynticks); | 421 | rcu_exit_nohz(); |
399 | |||
400 | if (rdtp->dynticks_nesting++) | ||
401 | return; | ||
402 | rdtp->dynticks++; | ||
403 | WARN_ON_ONCE(!(rdtp->dynticks & 0x1)); | ||
404 | smp_mb(); /* CPUs seeing ++ must see later RCU read-side crit sects */ | ||
405 | } | 422 | } |
406 | 423 | ||
407 | /** | 424 | /** |
@@ -413,18 +430,7 @@ void rcu_irq_enter(void) | |||
413 | */ | 430 | */ |
414 | void rcu_irq_exit(void) | 431 | void rcu_irq_exit(void) |
415 | { | 432 | { |
416 | struct rcu_dynticks *rdtp = &__get_cpu_var(rcu_dynticks); | 433 | rcu_enter_nohz(); |
417 | |||
418 | if (--rdtp->dynticks_nesting) | ||
419 | return; | ||
420 | smp_mb(); /* CPUs seeing ++ must see prior RCU read-side crit sects */ | ||
421 | rdtp->dynticks++; | ||
422 | WARN_ON_ONCE(rdtp->dynticks & 0x1); | ||
423 | |||
424 | /* If the interrupt queued a callback, get out of dyntick mode. */ | ||
425 | if (__this_cpu_read(rcu_sched_data.nxtlist) || | ||
426 | __this_cpu_read(rcu_bh_data.nxtlist)) | ||
427 | set_need_resched(); | ||
428 | } | 434 | } |
429 | 435 | ||
430 | #ifdef CONFIG_SMP | 436 | #ifdef CONFIG_SMP |
@@ -436,19 +442,8 @@ void rcu_irq_exit(void) | |||
436 | */ | 442 | */ |
437 | static int dyntick_save_progress_counter(struct rcu_data *rdp) | 443 | static int dyntick_save_progress_counter(struct rcu_data *rdp) |
438 | { | 444 | { |
439 | int ret; | 445 | rdp->dynticks_snap = atomic_add_return(0, &rdp->dynticks->dynticks); |
440 | int snap; | 446 | return 0; |
441 | int snap_nmi; | ||
442 | |||
443 | snap = rdp->dynticks->dynticks; | ||
444 | snap_nmi = rdp->dynticks->dynticks_nmi; | ||
445 | smp_mb(); /* Order sampling of snap with end of grace period. */ | ||
446 | rdp->dynticks_snap = snap; | ||
447 | rdp->dynticks_nmi_snap = snap_nmi; | ||
448 | ret = ((snap & 0x1) == 0) && ((snap_nmi & 0x1) == 0); | ||
449 | if (ret) | ||
450 | rdp->dynticks_fqs++; | ||
451 | return ret; | ||
452 | } | 447 | } |
453 | 448 | ||
454 | /* | 449 | /* |
@@ -459,16 +454,11 @@ static int dyntick_save_progress_counter(struct rcu_data *rdp) | |||
459 | */ | 454 | */ |
460 | static int rcu_implicit_dynticks_qs(struct rcu_data *rdp) | 455 | static int rcu_implicit_dynticks_qs(struct rcu_data *rdp) |
461 | { | 456 | { |
462 | long curr; | 457 | unsigned long curr; |
463 | long curr_nmi; | 458 | unsigned long snap; |
464 | long snap; | ||
465 | long snap_nmi; | ||
466 | 459 | ||
467 | curr = rdp->dynticks->dynticks; | 460 | curr = (unsigned long)atomic_add_return(0, &rdp->dynticks->dynticks); |
468 | snap = rdp->dynticks_snap; | 461 | snap = (unsigned long)rdp->dynticks_snap; |
469 | curr_nmi = rdp->dynticks->dynticks_nmi; | ||
470 | snap_nmi = rdp->dynticks_nmi_snap; | ||
471 | smp_mb(); /* force ordering with cpu entering/leaving dynticks. */ | ||
472 | 462 | ||
473 | /* | 463 | /* |
474 | * If the CPU passed through or entered a dynticks idle phase with | 464 | * If the CPU passed through or entered a dynticks idle phase with |
@@ -478,8 +468,7 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp) | |||
478 | * read-side critical section that started before the beginning | 468 | * read-side critical section that started before the beginning |
479 | * of the current RCU grace period. | 469 | * of the current RCU grace period. |
480 | */ | 470 | */ |
481 | if ((curr != snap || (curr & 0x1) == 0) && | 471 | if ((curr & 0x1) == 0 || ULONG_CMP_GE(curr, snap + 2)) { |
482 | (curr_nmi != snap_nmi || (curr_nmi & 0x1) == 0)) { | ||
483 | rdp->dynticks_fqs++; | 472 | rdp->dynticks_fqs++; |
484 | return 1; | 473 | return 1; |
485 | } | 474 | } |
@@ -908,6 +897,12 @@ static void rcu_report_qs_rsp(struct rcu_state *rsp, unsigned long flags) | |||
908 | unsigned long gp_duration; | 897 | unsigned long gp_duration; |
909 | 898 | ||
910 | WARN_ON_ONCE(!rcu_gp_in_progress(rsp)); | 899 | WARN_ON_ONCE(!rcu_gp_in_progress(rsp)); |
900 | |||
901 | /* | ||
902 | * Ensure that all grace-period and pre-grace-period activity | ||
903 | * is seen before the assignment to rsp->completed. | ||
904 | */ | ||
905 | smp_mb(); /* See above block comment. */ | ||
911 | gp_duration = jiffies - rsp->gp_start; | 906 | gp_duration = jiffies - rsp->gp_start; |
912 | if (gp_duration > rsp->gp_max) | 907 | if (gp_duration > rsp->gp_max) |
913 | rsp->gp_max = gp_duration; | 908 | rsp->gp_max = gp_duration; |
@@ -1455,25 +1450,11 @@ __rcu_process_callbacks(struct rcu_state *rsp, struct rcu_data *rdp) | |||
1455 | */ | 1450 | */ |
1456 | static void rcu_process_callbacks(void) | 1451 | static void rcu_process_callbacks(void) |
1457 | { | 1452 | { |
1458 | /* | ||
1459 | * Memory references from any prior RCU read-side critical sections | ||
1460 | * executed by the interrupted code must be seen before any RCU | ||
1461 | * grace-period manipulations below. | ||
1462 | */ | ||
1463 | smp_mb(); /* See above block comment. */ | ||
1464 | |||
1465 | __rcu_process_callbacks(&rcu_sched_state, | 1453 | __rcu_process_callbacks(&rcu_sched_state, |
1466 | &__get_cpu_var(rcu_sched_data)); | 1454 | &__get_cpu_var(rcu_sched_data)); |
1467 | __rcu_process_callbacks(&rcu_bh_state, &__get_cpu_var(rcu_bh_data)); | 1455 | __rcu_process_callbacks(&rcu_bh_state, &__get_cpu_var(rcu_bh_data)); |
1468 | rcu_preempt_process_callbacks(); | 1456 | rcu_preempt_process_callbacks(); |
1469 | 1457 | ||
1470 | /* | ||
1471 | * Memory references from any later RCU read-side critical sections | ||
1472 | * executed by the interrupted code must be seen after any RCU | ||
1473 | * grace-period manipulations above. | ||
1474 | */ | ||
1475 | smp_mb(); /* See above block comment. */ | ||
1476 | |||
1477 | /* If we are last CPU on way to dyntick-idle mode, accelerate it. */ | 1458 | /* If we are last CPU on way to dyntick-idle mode, accelerate it. */ |
1478 | rcu_needs_cpu_flush(); | 1459 | rcu_needs_cpu_flush(); |
1479 | } | 1460 | } |
@@ -1494,7 +1475,7 @@ static void invoke_rcu_cpu_kthread(void) | |||
1494 | local_irq_restore(flags); | 1475 | local_irq_restore(flags); |
1495 | return; | 1476 | return; |
1496 | } | 1477 | } |
1497 | wake_up(&__get_cpu_var(rcu_cpu_wq)); | 1478 | wake_up_process(__this_cpu_read(rcu_cpu_kthread_task)); |
1498 | local_irq_restore(flags); | 1479 | local_irq_restore(flags); |
1499 | } | 1480 | } |
1500 | 1481 | ||
@@ -1544,13 +1525,10 @@ static void rcu_cpu_kthread_setrt(int cpu, int to_rt) | |||
1544 | */ | 1525 | */ |
1545 | static void rcu_cpu_kthread_timer(unsigned long arg) | 1526 | static void rcu_cpu_kthread_timer(unsigned long arg) |
1546 | { | 1527 | { |
1547 | unsigned long flags; | ||
1548 | struct rcu_data *rdp = per_cpu_ptr(rcu_state->rda, arg); | 1528 | struct rcu_data *rdp = per_cpu_ptr(rcu_state->rda, arg); |
1549 | struct rcu_node *rnp = rdp->mynode; | 1529 | struct rcu_node *rnp = rdp->mynode; |
1550 | 1530 | ||
1551 | raw_spin_lock_irqsave(&rnp->lock, flags); | 1531 | atomic_or(rdp->grpmask, &rnp->wakemask); |
1552 | rnp->wakemask |= rdp->grpmask; | ||
1553 | raw_spin_unlock_irqrestore(&rnp->lock, flags); | ||
1554 | invoke_rcu_node_kthread(rnp); | 1532 | invoke_rcu_node_kthread(rnp); |
1555 | } | 1533 | } |
1556 | 1534 | ||
@@ -1617,14 +1595,12 @@ static int rcu_cpu_kthread(void *arg) | |||
1617 | unsigned long flags; | 1595 | unsigned long flags; |
1618 | int spincnt = 0; | 1596 | int spincnt = 0; |
1619 | unsigned int *statusp = &per_cpu(rcu_cpu_kthread_status, cpu); | 1597 | unsigned int *statusp = &per_cpu(rcu_cpu_kthread_status, cpu); |
1620 | wait_queue_head_t *wqp = &per_cpu(rcu_cpu_wq, cpu); | ||
1621 | char work; | 1598 | char work; |
1622 | char *workp = &per_cpu(rcu_cpu_has_work, cpu); | 1599 | char *workp = &per_cpu(rcu_cpu_has_work, cpu); |
1623 | 1600 | ||
1624 | for (;;) { | 1601 | for (;;) { |
1625 | *statusp = RCU_KTHREAD_WAITING; | 1602 | *statusp = RCU_KTHREAD_WAITING; |
1626 | wait_event_interruptible(*wqp, | 1603 | rcu_wait(*workp != 0 || kthread_should_stop()); |
1627 | *workp != 0 || kthread_should_stop()); | ||
1628 | local_bh_disable(); | 1604 | local_bh_disable(); |
1629 | if (rcu_cpu_kthread_should_stop(cpu)) { | 1605 | if (rcu_cpu_kthread_should_stop(cpu)) { |
1630 | local_bh_enable(); | 1606 | local_bh_enable(); |
@@ -1675,7 +1651,6 @@ static int __cpuinit rcu_spawn_one_cpu_kthread(int cpu) | |||
1675 | per_cpu(rcu_cpu_kthread_cpu, cpu) = cpu; | 1651 | per_cpu(rcu_cpu_kthread_cpu, cpu) = cpu; |
1676 | WARN_ON_ONCE(per_cpu(rcu_cpu_kthread_task, cpu) != NULL); | 1652 | WARN_ON_ONCE(per_cpu(rcu_cpu_kthread_task, cpu) != NULL); |
1677 | per_cpu(rcu_cpu_kthread_task, cpu) = t; | 1653 | per_cpu(rcu_cpu_kthread_task, cpu) = t; |
1678 | wake_up_process(t); | ||
1679 | sp.sched_priority = RCU_KTHREAD_PRIO; | 1654 | sp.sched_priority = RCU_KTHREAD_PRIO; |
1680 | sched_setscheduler_nocheck(t, SCHED_FIFO, &sp); | 1655 | sched_setscheduler_nocheck(t, SCHED_FIFO, &sp); |
1681 | return 0; | 1656 | return 0; |
@@ -1698,11 +1673,10 @@ static int rcu_node_kthread(void *arg) | |||
1698 | 1673 | ||
1699 | for (;;) { | 1674 | for (;;) { |
1700 | rnp->node_kthread_status = RCU_KTHREAD_WAITING; | 1675 | rnp->node_kthread_status = RCU_KTHREAD_WAITING; |
1701 | wait_event_interruptible(rnp->node_wq, rnp->wakemask != 0); | 1676 | rcu_wait(atomic_read(&rnp->wakemask) != 0); |
1702 | rnp->node_kthread_status = RCU_KTHREAD_RUNNING; | 1677 | rnp->node_kthread_status = RCU_KTHREAD_RUNNING; |
1703 | raw_spin_lock_irqsave(&rnp->lock, flags); | 1678 | raw_spin_lock_irqsave(&rnp->lock, flags); |
1704 | mask = rnp->wakemask; | 1679 | mask = atomic_xchg(&rnp->wakemask, 0); |
1705 | rnp->wakemask = 0; | ||
1706 | rcu_initiate_boost(rnp, flags); /* releases rnp->lock. */ | 1680 | rcu_initiate_boost(rnp, flags); /* releases rnp->lock. */ |
1707 | for (cpu = rnp->grplo; cpu <= rnp->grphi; cpu++, mask >>= 1) { | 1681 | for (cpu = rnp->grplo; cpu <= rnp->grphi; cpu++, mask >>= 1) { |
1708 | if ((mask & 0x1) == 0) | 1682 | if ((mask & 0x1) == 0) |
@@ -1783,13 +1757,14 @@ static int __cpuinit rcu_spawn_one_node_kthread(struct rcu_state *rsp, | |||
1783 | raw_spin_lock_irqsave(&rnp->lock, flags); | 1757 | raw_spin_lock_irqsave(&rnp->lock, flags); |
1784 | rnp->node_kthread_task = t; | 1758 | rnp->node_kthread_task = t; |
1785 | raw_spin_unlock_irqrestore(&rnp->lock, flags); | 1759 | raw_spin_unlock_irqrestore(&rnp->lock, flags); |
1786 | wake_up_process(t); | ||
1787 | sp.sched_priority = 99; | 1760 | sp.sched_priority = 99; |
1788 | sched_setscheduler_nocheck(t, SCHED_FIFO, &sp); | 1761 | sched_setscheduler_nocheck(t, SCHED_FIFO, &sp); |
1789 | } | 1762 | } |
1790 | return rcu_spawn_one_boost_kthread(rsp, rnp, rnp_index); | 1763 | return rcu_spawn_one_boost_kthread(rsp, rnp, rnp_index); |
1791 | } | 1764 | } |
1792 | 1765 | ||
1766 | static void rcu_wake_one_boost_kthread(struct rcu_node *rnp); | ||
1767 | |||
1793 | /* | 1768 | /* |
1794 | * Spawn all kthreads -- called as soon as the scheduler is running. | 1769 | * Spawn all kthreads -- called as soon as the scheduler is running. |
1795 | */ | 1770 | */ |
@@ -1797,24 +1772,31 @@ static int __init rcu_spawn_kthreads(void) | |||
1797 | { | 1772 | { |
1798 | int cpu; | 1773 | int cpu; |
1799 | struct rcu_node *rnp; | 1774 | struct rcu_node *rnp; |
1775 | struct task_struct *t; | ||
1800 | 1776 | ||
1801 | rcu_kthreads_spawnable = 1; | 1777 | rcu_kthreads_spawnable = 1; |
1802 | for_each_possible_cpu(cpu) { | 1778 | for_each_possible_cpu(cpu) { |
1803 | init_waitqueue_head(&per_cpu(rcu_cpu_wq, cpu)); | ||
1804 | per_cpu(rcu_cpu_has_work, cpu) = 0; | 1779 | per_cpu(rcu_cpu_has_work, cpu) = 0; |
1805 | if (cpu_online(cpu)) | 1780 | if (cpu_online(cpu)) { |
1806 | (void)rcu_spawn_one_cpu_kthread(cpu); | 1781 | (void)rcu_spawn_one_cpu_kthread(cpu); |
1782 | t = per_cpu(rcu_cpu_kthread_task, cpu); | ||
1783 | if (t) | ||
1784 | wake_up_process(t); | ||
1785 | } | ||
1807 | } | 1786 | } |
1808 | rnp = rcu_get_root(rcu_state); | 1787 | rnp = rcu_get_root(rcu_state); |
1809 | init_waitqueue_head(&rnp->node_wq); | ||
1810 | rcu_init_boost_waitqueue(rnp); | ||
1811 | (void)rcu_spawn_one_node_kthread(rcu_state, rnp); | 1788 | (void)rcu_spawn_one_node_kthread(rcu_state, rnp); |
1812 | if (NUM_RCU_NODES > 1) | 1789 | if (rnp->node_kthread_task) |
1790 | wake_up_process(rnp->node_kthread_task); | ||
1791 | if (NUM_RCU_NODES > 1) { | ||
1813 | rcu_for_each_leaf_node(rcu_state, rnp) { | 1792 | rcu_for_each_leaf_node(rcu_state, rnp) { |
1814 | init_waitqueue_head(&rnp->node_wq); | ||
1815 | rcu_init_boost_waitqueue(rnp); | ||
1816 | (void)rcu_spawn_one_node_kthread(rcu_state, rnp); | 1793 | (void)rcu_spawn_one_node_kthread(rcu_state, rnp); |
1794 | t = rnp->node_kthread_task; | ||
1795 | if (t) | ||
1796 | wake_up_process(t); | ||
1797 | rcu_wake_one_boost_kthread(rnp); | ||
1817 | } | 1798 | } |
1799 | } | ||
1818 | return 0; | 1800 | return 0; |
1819 | } | 1801 | } |
1820 | early_initcall(rcu_spawn_kthreads); | 1802 | early_initcall(rcu_spawn_kthreads); |
@@ -2218,14 +2200,14 @@ rcu_init_percpu_data(int cpu, struct rcu_state *rsp, int preemptible) | |||
2218 | raw_spin_unlock_irqrestore(&rsp->onofflock, flags); | 2200 | raw_spin_unlock_irqrestore(&rsp->onofflock, flags); |
2219 | } | 2201 | } |
2220 | 2202 | ||
2221 | static void __cpuinit rcu_online_cpu(int cpu) | 2203 | static void __cpuinit rcu_prepare_cpu(int cpu) |
2222 | { | 2204 | { |
2223 | rcu_init_percpu_data(cpu, &rcu_sched_state, 0); | 2205 | rcu_init_percpu_data(cpu, &rcu_sched_state, 0); |
2224 | rcu_init_percpu_data(cpu, &rcu_bh_state, 0); | 2206 | rcu_init_percpu_data(cpu, &rcu_bh_state, 0); |
2225 | rcu_preempt_init_percpu_data(cpu); | 2207 | rcu_preempt_init_percpu_data(cpu); |
2226 | } | 2208 | } |
2227 | 2209 | ||
2228 | static void __cpuinit rcu_online_kthreads(int cpu) | 2210 | static void __cpuinit rcu_prepare_kthreads(int cpu) |
2229 | { | 2211 | { |
2230 | struct rcu_data *rdp = per_cpu_ptr(rcu_state->rda, cpu); | 2212 | struct rcu_data *rdp = per_cpu_ptr(rcu_state->rda, cpu); |
2231 | struct rcu_node *rnp = rdp->mynode; | 2213 | struct rcu_node *rnp = rdp->mynode; |
@@ -2239,6 +2221,31 @@ static void __cpuinit rcu_online_kthreads(int cpu) | |||
2239 | } | 2221 | } |
2240 | 2222 | ||
2241 | /* | 2223 | /* |
2224 | * kthread_create() creates threads in TASK_UNINTERRUPTIBLE state, | ||
2225 | * but the RCU threads are woken on demand, and if demand is low this | ||
2226 | * could be a while triggering the hung task watchdog. | ||
2227 | * | ||
2228 | * In order to avoid this, poke all tasks once the CPU is fully | ||
2229 | * up and running. | ||
2230 | */ | ||
2231 | static void __cpuinit rcu_online_kthreads(int cpu) | ||
2232 | { | ||
2233 | struct rcu_data *rdp = per_cpu_ptr(rcu_state->rda, cpu); | ||
2234 | struct rcu_node *rnp = rdp->mynode; | ||
2235 | struct task_struct *t; | ||
2236 | |||
2237 | t = per_cpu(rcu_cpu_kthread_task, cpu); | ||
2238 | if (t) | ||
2239 | wake_up_process(t); | ||
2240 | |||
2241 | t = rnp->node_kthread_task; | ||
2242 | if (t) | ||
2243 | wake_up_process(t); | ||
2244 | |||
2245 | rcu_wake_one_boost_kthread(rnp); | ||
2246 | } | ||
2247 | |||
2248 | /* | ||
2242 | * Handle CPU online/offline notification events. | 2249 | * Handle CPU online/offline notification events. |
2243 | */ | 2250 | */ |
2244 | static int __cpuinit rcu_cpu_notify(struct notifier_block *self, | 2251 | static int __cpuinit rcu_cpu_notify(struct notifier_block *self, |
@@ -2251,10 +2258,11 @@ static int __cpuinit rcu_cpu_notify(struct notifier_block *self, | |||
2251 | switch (action) { | 2258 | switch (action) { |
2252 | case CPU_UP_PREPARE: | 2259 | case CPU_UP_PREPARE: |
2253 | case CPU_UP_PREPARE_FROZEN: | 2260 | case CPU_UP_PREPARE_FROZEN: |
2254 | rcu_online_cpu(cpu); | 2261 | rcu_prepare_cpu(cpu); |
2255 | rcu_online_kthreads(cpu); | 2262 | rcu_prepare_kthreads(cpu); |
2256 | break; | 2263 | break; |
2257 | case CPU_ONLINE: | 2264 | case CPU_ONLINE: |
2265 | rcu_online_kthreads(cpu); | ||
2258 | case CPU_DOWN_FAILED: | 2266 | case CPU_DOWN_FAILED: |
2259 | rcu_node_kthread_setaffinity(rnp, -1); | 2267 | rcu_node_kthread_setaffinity(rnp, -1); |
2260 | rcu_cpu_kthread_setrt(cpu, 1); | 2268 | rcu_cpu_kthread_setrt(cpu, 1); |
diff --git a/kernel/rcutree.h b/kernel/rcutree.h index 257664815d5d..7b9a08b4aaea 100644 --- a/kernel/rcutree.h +++ b/kernel/rcutree.h | |||
@@ -84,11 +84,9 @@ | |||
84 | * Dynticks per-CPU state. | 84 | * Dynticks per-CPU state. |
85 | */ | 85 | */ |
86 | struct rcu_dynticks { | 86 | struct rcu_dynticks { |
87 | int dynticks_nesting; /* Track nesting level, sort of. */ | 87 | int dynticks_nesting; /* Track irq/process nesting level. */ |
88 | int dynticks; /* Even value for dynticks-idle, else odd. */ | 88 | int dynticks_nmi_nesting; /* Track NMI nesting level. */ |
89 | int dynticks_nmi; /* Even value for either dynticks-idle or */ | 89 | atomic_t dynticks; /* Even value for dynticks-idle, else odd. */ |
90 | /* not in nmi handler, else odd. So this */ | ||
91 | /* remains even for nmi from irq handler. */ | ||
92 | }; | 90 | }; |
93 | 91 | ||
94 | /* RCU's kthread states for tracing. */ | 92 | /* RCU's kthread states for tracing. */ |
@@ -121,7 +119,9 @@ struct rcu_node { | |||
121 | /* elements that need to drain to allow the */ | 119 | /* elements that need to drain to allow the */ |
122 | /* current expedited grace period to */ | 120 | /* current expedited grace period to */ |
123 | /* complete (only for TREE_PREEMPT_RCU). */ | 121 | /* complete (only for TREE_PREEMPT_RCU). */ |
124 | unsigned long wakemask; /* CPUs whose kthread needs to be awakened. */ | 122 | atomic_t wakemask; /* CPUs whose kthread needs to be awakened. */ |
123 | /* Since this has meaning only for leaf */ | ||
124 | /* rcu_node structures, 32 bits suffices. */ | ||
125 | unsigned long qsmaskinit; | 125 | unsigned long qsmaskinit; |
126 | /* Per-GP initial value for qsmask & expmask. */ | 126 | /* Per-GP initial value for qsmask & expmask. */ |
127 | unsigned long grpmask; /* Mask to apply to parent qsmask. */ | 127 | unsigned long grpmask; /* Mask to apply to parent qsmask. */ |
@@ -159,9 +159,6 @@ struct rcu_node { | |||
159 | struct task_struct *boost_kthread_task; | 159 | struct task_struct *boost_kthread_task; |
160 | /* kthread that takes care of priority */ | 160 | /* kthread that takes care of priority */ |
161 | /* boosting for this rcu_node structure. */ | 161 | /* boosting for this rcu_node structure. */ |
162 | wait_queue_head_t boost_wq; | ||
163 | /* Wait queue on which to park the boost */ | ||
164 | /* kthread. */ | ||
165 | unsigned int boost_kthread_status; | 162 | unsigned int boost_kthread_status; |
166 | /* State of boost_kthread_task for tracing. */ | 163 | /* State of boost_kthread_task for tracing. */ |
167 | unsigned long n_tasks_boosted; | 164 | unsigned long n_tasks_boosted; |
@@ -188,9 +185,6 @@ struct rcu_node { | |||
188 | /* kthread that takes care of this rcu_node */ | 185 | /* kthread that takes care of this rcu_node */ |
189 | /* structure, for example, awakening the */ | 186 | /* structure, for example, awakening the */ |
190 | /* per-CPU kthreads as needed. */ | 187 | /* per-CPU kthreads as needed. */ |
191 | wait_queue_head_t node_wq; | ||
192 | /* Wait queue on which to park the per-node */ | ||
193 | /* kthread. */ | ||
194 | unsigned int node_kthread_status; | 188 | unsigned int node_kthread_status; |
195 | /* State of node_kthread_task for tracing. */ | 189 | /* State of node_kthread_task for tracing. */ |
196 | } ____cacheline_internodealigned_in_smp; | 190 | } ____cacheline_internodealigned_in_smp; |
@@ -284,7 +278,6 @@ struct rcu_data { | |||
284 | /* 3) dynticks interface. */ | 278 | /* 3) dynticks interface. */ |
285 | struct rcu_dynticks *dynticks; /* Shared per-CPU dynticks state. */ | 279 | struct rcu_dynticks *dynticks; /* Shared per-CPU dynticks state. */ |
286 | int dynticks_snap; /* Per-GP tracking for dynticks. */ | 280 | int dynticks_snap; /* Per-GP tracking for dynticks. */ |
287 | int dynticks_nmi_snap; /* Per-GP tracking for dynticks_nmi. */ | ||
288 | #endif /* #ifdef CONFIG_NO_HZ */ | 281 | #endif /* #ifdef CONFIG_NO_HZ */ |
289 | 282 | ||
290 | /* 4) reasons this CPU needed to be kicked by force_quiescent_state */ | 283 | /* 4) reasons this CPU needed to be kicked by force_quiescent_state */ |
@@ -337,6 +330,16 @@ struct rcu_data { | |||
337 | /* scheduling clock irq */ | 330 | /* scheduling clock irq */ |
338 | /* before ratting on them. */ | 331 | /* before ratting on them. */ |
339 | 332 | ||
333 | #define rcu_wait(cond) \ | ||
334 | do { \ | ||
335 | for (;;) { \ | ||
336 | set_current_state(TASK_INTERRUPTIBLE); \ | ||
337 | if (cond) \ | ||
338 | break; \ | ||
339 | schedule(); \ | ||
340 | } \ | ||
341 | __set_current_state(TASK_RUNNING); \ | ||
342 | } while (0) | ||
340 | 343 | ||
341 | /* | 344 | /* |
342 | * RCU global state, including node hierarchy. This hierarchy is | 345 | * RCU global state, including node hierarchy. This hierarchy is |
@@ -446,7 +449,6 @@ static void __cpuinit rcu_preempt_init_percpu_data(int cpu); | |||
446 | static void rcu_preempt_send_cbs_to_online(void); | 449 | static void rcu_preempt_send_cbs_to_online(void); |
447 | static void __init __rcu_init_preempt(void); | 450 | static void __init __rcu_init_preempt(void); |
448 | static void rcu_needs_cpu_flush(void); | 451 | static void rcu_needs_cpu_flush(void); |
449 | static void __init rcu_init_boost_waitqueue(struct rcu_node *rnp); | ||
450 | static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags); | 452 | static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags); |
451 | static void rcu_boost_kthread_setaffinity(struct rcu_node *rnp, | 453 | static void rcu_boost_kthread_setaffinity(struct rcu_node *rnp, |
452 | cpumask_var_t cm); | 454 | cpumask_var_t cm); |
diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h index 3f6559a5f5cd..c8bff3099a89 100644 --- a/kernel/rcutree_plugin.h +++ b/kernel/rcutree_plugin.h | |||
@@ -1196,8 +1196,7 @@ static int rcu_boost_kthread(void *arg) | |||
1196 | 1196 | ||
1197 | for (;;) { | 1197 | for (;;) { |
1198 | rnp->boost_kthread_status = RCU_KTHREAD_WAITING; | 1198 | rnp->boost_kthread_status = RCU_KTHREAD_WAITING; |
1199 | wait_event_interruptible(rnp->boost_wq, rnp->boost_tasks || | 1199 | rcu_wait(rnp->boost_tasks || rnp->exp_tasks); |
1200 | rnp->exp_tasks); | ||
1201 | rnp->boost_kthread_status = RCU_KTHREAD_RUNNING; | 1200 | rnp->boost_kthread_status = RCU_KTHREAD_RUNNING; |
1202 | more2boost = rcu_boost(rnp); | 1201 | more2boost = rcu_boost(rnp); |
1203 | if (more2boost) | 1202 | if (more2boost) |
@@ -1275,14 +1274,6 @@ static void rcu_preempt_boost_start_gp(struct rcu_node *rnp) | |||
1275 | } | 1274 | } |
1276 | 1275 | ||
1277 | /* | 1276 | /* |
1278 | * Initialize the RCU-boost waitqueue. | ||
1279 | */ | ||
1280 | static void __init rcu_init_boost_waitqueue(struct rcu_node *rnp) | ||
1281 | { | ||
1282 | init_waitqueue_head(&rnp->boost_wq); | ||
1283 | } | ||
1284 | |||
1285 | /* | ||
1286 | * Create an RCU-boost kthread for the specified node if one does not | 1277 | * Create an RCU-boost kthread for the specified node if one does not |
1287 | * already exist. We only create this kthread for preemptible RCU. | 1278 | * already exist. We only create this kthread for preemptible RCU. |
1288 | * Returns zero if all is well, a negated errno otherwise. | 1279 | * Returns zero if all is well, a negated errno otherwise. |
@@ -1306,12 +1297,17 @@ static int __cpuinit rcu_spawn_one_boost_kthread(struct rcu_state *rsp, | |||
1306 | raw_spin_lock_irqsave(&rnp->lock, flags); | 1297 | raw_spin_lock_irqsave(&rnp->lock, flags); |
1307 | rnp->boost_kthread_task = t; | 1298 | rnp->boost_kthread_task = t; |
1308 | raw_spin_unlock_irqrestore(&rnp->lock, flags); | 1299 | raw_spin_unlock_irqrestore(&rnp->lock, flags); |
1309 | wake_up_process(t); | ||
1310 | sp.sched_priority = RCU_KTHREAD_PRIO; | 1300 | sp.sched_priority = RCU_KTHREAD_PRIO; |
1311 | sched_setscheduler_nocheck(t, SCHED_FIFO, &sp); | 1301 | sched_setscheduler_nocheck(t, SCHED_FIFO, &sp); |
1312 | return 0; | 1302 | return 0; |
1313 | } | 1303 | } |
1314 | 1304 | ||
1305 | static void __cpuinit rcu_wake_one_boost_kthread(struct rcu_node *rnp) | ||
1306 | { | ||
1307 | if (rnp->boost_kthread_task) | ||
1308 | wake_up_process(rnp->boost_kthread_task); | ||
1309 | } | ||
1310 | |||
1315 | #else /* #ifdef CONFIG_RCU_BOOST */ | 1311 | #else /* #ifdef CONFIG_RCU_BOOST */ |
1316 | 1312 | ||
1317 | static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags) | 1313 | static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags) |
@@ -1328,10 +1324,6 @@ static void rcu_preempt_boost_start_gp(struct rcu_node *rnp) | |||
1328 | { | 1324 | { |
1329 | } | 1325 | } |
1330 | 1326 | ||
1331 | static void __init rcu_init_boost_waitqueue(struct rcu_node *rnp) | ||
1332 | { | ||
1333 | } | ||
1334 | |||
1335 | static int __cpuinit rcu_spawn_one_boost_kthread(struct rcu_state *rsp, | 1327 | static int __cpuinit rcu_spawn_one_boost_kthread(struct rcu_state *rsp, |
1336 | struct rcu_node *rnp, | 1328 | struct rcu_node *rnp, |
1337 | int rnp_index) | 1329 | int rnp_index) |
@@ -1339,6 +1331,10 @@ static int __cpuinit rcu_spawn_one_boost_kthread(struct rcu_state *rsp, | |||
1339 | return 0; | 1331 | return 0; |
1340 | } | 1332 | } |
1341 | 1333 | ||
1334 | static void __cpuinit rcu_wake_one_boost_kthread(struct rcu_node *rnp) | ||
1335 | { | ||
1336 | } | ||
1337 | |||
1342 | #endif /* #else #ifdef CONFIG_RCU_BOOST */ | 1338 | #endif /* #else #ifdef CONFIG_RCU_BOOST */ |
1343 | 1339 | ||
1344 | #ifndef CONFIG_SMP | 1340 | #ifndef CONFIG_SMP |
@@ -1520,7 +1516,6 @@ int rcu_needs_cpu(int cpu) | |||
1520 | { | 1516 | { |
1521 | int c = 0; | 1517 | int c = 0; |
1522 | int snap; | 1518 | int snap; |
1523 | int snap_nmi; | ||
1524 | int thatcpu; | 1519 | int thatcpu; |
1525 | 1520 | ||
1526 | /* Check for being in the holdoff period. */ | 1521 | /* Check for being in the holdoff period. */ |
@@ -1531,10 +1526,10 @@ int rcu_needs_cpu(int cpu) | |||
1531 | for_each_online_cpu(thatcpu) { | 1526 | for_each_online_cpu(thatcpu) { |
1532 | if (thatcpu == cpu) | 1527 | if (thatcpu == cpu) |
1533 | continue; | 1528 | continue; |
1534 | snap = per_cpu(rcu_dynticks, thatcpu).dynticks; | 1529 | snap = atomic_add_return(0, &per_cpu(rcu_dynticks, |
1535 | snap_nmi = per_cpu(rcu_dynticks, thatcpu).dynticks_nmi; | 1530 | thatcpu).dynticks); |
1536 | smp_mb(); /* Order sampling of snap with end of grace period. */ | 1531 | smp_mb(); /* Order sampling of snap with end of grace period. */ |
1537 | if (((snap & 0x1) != 0) || ((snap_nmi & 0x1) != 0)) { | 1532 | if ((snap & 0x1) != 0) { |
1538 | per_cpu(rcu_dyntick_drain, cpu) = 0; | 1533 | per_cpu(rcu_dyntick_drain, cpu) = 0; |
1539 | per_cpu(rcu_dyntick_holdoff, cpu) = jiffies - 1; | 1534 | per_cpu(rcu_dyntick_holdoff, cpu) = jiffies - 1; |
1540 | return rcu_needs_cpu_quick_check(cpu); | 1535 | return rcu_needs_cpu_quick_check(cpu); |
diff --git a/kernel/rcutree_trace.c b/kernel/rcutree_trace.c index aa0fd72b4bc7..9678cc3650f5 100644 --- a/kernel/rcutree_trace.c +++ b/kernel/rcutree_trace.c | |||
@@ -69,10 +69,10 @@ static void print_one_rcu_data(struct seq_file *m, struct rcu_data *rdp) | |||
69 | rdp->passed_quiesc, rdp->passed_quiesc_completed, | 69 | rdp->passed_quiesc, rdp->passed_quiesc_completed, |
70 | rdp->qs_pending); | 70 | rdp->qs_pending); |
71 | #ifdef CONFIG_NO_HZ | 71 | #ifdef CONFIG_NO_HZ |
72 | seq_printf(m, " dt=%d/%d dn=%d df=%lu", | 72 | seq_printf(m, " dt=%d/%d/%d df=%lu", |
73 | rdp->dynticks->dynticks, | 73 | atomic_read(&rdp->dynticks->dynticks), |
74 | rdp->dynticks->dynticks_nesting, | 74 | rdp->dynticks->dynticks_nesting, |
75 | rdp->dynticks->dynticks_nmi, | 75 | rdp->dynticks->dynticks_nmi_nesting, |
76 | rdp->dynticks_fqs); | 76 | rdp->dynticks_fqs); |
77 | #endif /* #ifdef CONFIG_NO_HZ */ | 77 | #endif /* #ifdef CONFIG_NO_HZ */ |
78 | seq_printf(m, " of=%lu ri=%lu", rdp->offline_fqs, rdp->resched_ipi); | 78 | seq_printf(m, " of=%lu ri=%lu", rdp->offline_fqs, rdp->resched_ipi); |
@@ -141,9 +141,9 @@ static void print_one_rcu_data_csv(struct seq_file *m, struct rcu_data *rdp) | |||
141 | rdp->qs_pending); | 141 | rdp->qs_pending); |
142 | #ifdef CONFIG_NO_HZ | 142 | #ifdef CONFIG_NO_HZ |
143 | seq_printf(m, ",%d,%d,%d,%lu", | 143 | seq_printf(m, ",%d,%d,%d,%lu", |
144 | rdp->dynticks->dynticks, | 144 | atomic_read(&rdp->dynticks->dynticks), |
145 | rdp->dynticks->dynticks_nesting, | 145 | rdp->dynticks->dynticks_nesting, |
146 | rdp->dynticks->dynticks_nmi, | 146 | rdp->dynticks->dynticks_nmi_nesting, |
147 | rdp->dynticks_fqs); | 147 | rdp->dynticks_fqs); |
148 | #endif /* #ifdef CONFIG_NO_HZ */ | 148 | #endif /* #ifdef CONFIG_NO_HZ */ |
149 | seq_printf(m, ",%lu,%lu", rdp->offline_fqs, rdp->resched_ipi); | 149 | seq_printf(m, ",%lu,%lu", rdp->offline_fqs, rdp->resched_ipi); |
@@ -167,7 +167,7 @@ static int show_rcudata_csv(struct seq_file *m, void *unused) | |||
167 | { | 167 | { |
168 | seq_puts(m, "\"CPU\",\"Online?\",\"c\",\"g\",\"pq\",\"pqc\",\"pq\","); | 168 | seq_puts(m, "\"CPU\",\"Online?\",\"c\",\"g\",\"pq\",\"pqc\",\"pq\","); |
169 | #ifdef CONFIG_NO_HZ | 169 | #ifdef CONFIG_NO_HZ |
170 | seq_puts(m, "\"dt\",\"dt nesting\",\"dn\",\"df\","); | 170 | seq_puts(m, "\"dt\",\"dt nesting\",\"dt NMI nesting\",\"df\","); |
171 | #endif /* #ifdef CONFIG_NO_HZ */ | 171 | #endif /* #ifdef CONFIG_NO_HZ */ |
172 | seq_puts(m, "\"of\",\"ri\",\"ql\",\"b\",\"ci\",\"co\",\"ca\"\n"); | 172 | seq_puts(m, "\"of\",\"ri\",\"ql\",\"b\",\"ci\",\"co\",\"ca\"\n"); |
173 | #ifdef CONFIG_TREE_PREEMPT_RCU | 173 | #ifdef CONFIG_TREE_PREEMPT_RCU |
diff --git a/kernel/sched.c b/kernel/sched.c index 5e43e9dc65d1..cbb3a0eee58e 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -2573,7 +2573,26 @@ static void ttwu_queue_remote(struct task_struct *p, int cpu) | |||
2573 | if (!next) | 2573 | if (!next) |
2574 | smp_send_reschedule(cpu); | 2574 | smp_send_reschedule(cpu); |
2575 | } | 2575 | } |
2576 | #endif | 2576 | |
2577 | #ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW | ||
2578 | static int ttwu_activate_remote(struct task_struct *p, int wake_flags) | ||
2579 | { | ||
2580 | struct rq *rq; | ||
2581 | int ret = 0; | ||
2582 | |||
2583 | rq = __task_rq_lock(p); | ||
2584 | if (p->on_cpu) { | ||
2585 | ttwu_activate(rq, p, ENQUEUE_WAKEUP); | ||
2586 | ttwu_do_wakeup(rq, p, wake_flags); | ||
2587 | ret = 1; | ||
2588 | } | ||
2589 | __task_rq_unlock(rq); | ||
2590 | |||
2591 | return ret; | ||
2592 | |||
2593 | } | ||
2594 | #endif /* __ARCH_WANT_INTERRUPTS_ON_CTXSW */ | ||
2595 | #endif /* CONFIG_SMP */ | ||
2577 | 2596 | ||
2578 | static void ttwu_queue(struct task_struct *p, int cpu) | 2597 | static void ttwu_queue(struct task_struct *p, int cpu) |
2579 | { | 2598 | { |
@@ -2631,17 +2650,17 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags) | |||
2631 | while (p->on_cpu) { | 2650 | while (p->on_cpu) { |
2632 | #ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW | 2651 | #ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW |
2633 | /* | 2652 | /* |
2634 | * If called from interrupt context we could have landed in the | 2653 | * In case the architecture enables interrupts in |
2635 | * middle of schedule(), in this case we should take care not | 2654 | * context_switch(), we cannot busy wait, since that |
2636 | * to spin on ->on_cpu if p is current, since that would | 2655 | * would lead to deadlocks when an interrupt hits and |
2637 | * deadlock. | 2656 | * tries to wake up @prev. So bail and do a complete |
2657 | * remote wakeup. | ||
2638 | */ | 2658 | */ |
2639 | if (p == current) { | 2659 | if (ttwu_activate_remote(p, wake_flags)) |
2640 | ttwu_queue(p, cpu); | ||
2641 | goto stat; | 2660 | goto stat; |
2642 | } | 2661 | #else |
2643 | #endif | ||
2644 | cpu_relax(); | 2662 | cpu_relax(); |
2663 | #endif | ||
2645 | } | 2664 | } |
2646 | /* | 2665 | /* |
2647 | * Pairs with the smp_wmb() in finish_lock_switch(). | 2666 | * Pairs with the smp_wmb() in finish_lock_switch(). |
@@ -5841,7 +5860,7 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu) | |||
5841 | idle->state = TASK_RUNNING; | 5860 | idle->state = TASK_RUNNING; |
5842 | idle->se.exec_start = sched_clock(); | 5861 | idle->se.exec_start = sched_clock(); |
5843 | 5862 | ||
5844 | cpumask_copy(&idle->cpus_allowed, cpumask_of(cpu)); | 5863 | do_set_cpus_allowed(idle, cpumask_of(cpu)); |
5845 | /* | 5864 | /* |
5846 | * We're having a chicken and egg problem, even though we are | 5865 | * We're having a chicken and egg problem, even though we are |
5847 | * holding rq->lock, the cpu isn't yet set to this cpu so the | 5866 | * holding rq->lock, the cpu isn't yet set to this cpu so the |
@@ -5929,6 +5948,16 @@ static inline void sched_init_granularity(void) | |||
5929 | } | 5948 | } |
5930 | 5949 | ||
5931 | #ifdef CONFIG_SMP | 5950 | #ifdef CONFIG_SMP |
5951 | void do_set_cpus_allowed(struct task_struct *p, const struct cpumask *new_mask) | ||
5952 | { | ||
5953 | if (p->sched_class && p->sched_class->set_cpus_allowed) | ||
5954 | p->sched_class->set_cpus_allowed(p, new_mask); | ||
5955 | else { | ||
5956 | cpumask_copy(&p->cpus_allowed, new_mask); | ||
5957 | p->rt.nr_cpus_allowed = cpumask_weight(new_mask); | ||
5958 | } | ||
5959 | } | ||
5960 | |||
5932 | /* | 5961 | /* |
5933 | * This is how migration works: | 5962 | * This is how migration works: |
5934 | * | 5963 | * |
@@ -5974,12 +6003,7 @@ int set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask) | |||
5974 | goto out; | 6003 | goto out; |
5975 | } | 6004 | } |
5976 | 6005 | ||
5977 | if (p->sched_class->set_cpus_allowed) | 6006 | do_set_cpus_allowed(p, new_mask); |
5978 | p->sched_class->set_cpus_allowed(p, new_mask); | ||
5979 | else { | ||
5980 | cpumask_copy(&p->cpus_allowed, new_mask); | ||
5981 | p->rt.nr_cpus_allowed = cpumask_weight(new_mask); | ||
5982 | } | ||
5983 | 6007 | ||
5984 | /* Can the task run on the task's current CPU? If so, we're done */ | 6008 | /* Can the task run on the task's current CPU? If so, we're done */ |
5985 | if (cpumask_test_cpu(task_cpu(p), new_mask)) | 6009 | if (cpumask_test_cpu(task_cpu(p), new_mask)) |
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index e32a9b70ee9c..433491c2dc8f 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c | |||
@@ -1076,8 +1076,6 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags) | |||
1076 | se->on_rq = 0; | 1076 | se->on_rq = 0; |
1077 | update_cfs_load(cfs_rq, 0); | 1077 | update_cfs_load(cfs_rq, 0); |
1078 | account_entity_dequeue(cfs_rq, se); | 1078 | account_entity_dequeue(cfs_rq, se); |
1079 | update_min_vruntime(cfs_rq); | ||
1080 | update_cfs_shares(cfs_rq); | ||
1081 | 1079 | ||
1082 | /* | 1080 | /* |
1083 | * Normalize the entity after updating the min_vruntime because the | 1081 | * Normalize the entity after updating the min_vruntime because the |
@@ -1086,6 +1084,9 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags) | |||
1086 | */ | 1084 | */ |
1087 | if (!(flags & DEQUEUE_SLEEP)) | 1085 | if (!(flags & DEQUEUE_SLEEP)) |
1088 | se->vruntime -= cfs_rq->min_vruntime; | 1086 | se->vruntime -= cfs_rq->min_vruntime; |
1087 | |||
1088 | update_min_vruntime(cfs_rq); | ||
1089 | update_cfs_shares(cfs_rq); | ||
1089 | } | 1090 | } |
1090 | 1091 | ||
1091 | /* | 1092 | /* |
diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c index 64b2a37c07d0..88725c939e0b 100644 --- a/kernel/sched_rt.c +++ b/kernel/sched_rt.c | |||
@@ -1263,6 +1263,7 @@ static int find_lowest_rq(struct task_struct *task) | |||
1263 | if (!cpumask_test_cpu(this_cpu, lowest_mask)) | 1263 | if (!cpumask_test_cpu(this_cpu, lowest_mask)) |
1264 | this_cpu = -1; /* Skip this_cpu opt if not among lowest */ | 1264 | this_cpu = -1; /* Skip this_cpu opt if not among lowest */ |
1265 | 1265 | ||
1266 | rcu_read_lock(); | ||
1266 | for_each_domain(cpu, sd) { | 1267 | for_each_domain(cpu, sd) { |
1267 | if (sd->flags & SD_WAKE_AFFINE) { | 1268 | if (sd->flags & SD_WAKE_AFFINE) { |
1268 | int best_cpu; | 1269 | int best_cpu; |
@@ -1272,15 +1273,20 @@ static int find_lowest_rq(struct task_struct *task) | |||
1272 | * remote processor. | 1273 | * remote processor. |
1273 | */ | 1274 | */ |
1274 | if (this_cpu != -1 && | 1275 | if (this_cpu != -1 && |
1275 | cpumask_test_cpu(this_cpu, sched_domain_span(sd))) | 1276 | cpumask_test_cpu(this_cpu, sched_domain_span(sd))) { |
1277 | rcu_read_unlock(); | ||
1276 | return this_cpu; | 1278 | return this_cpu; |
1279 | } | ||
1277 | 1280 | ||
1278 | best_cpu = cpumask_first_and(lowest_mask, | 1281 | best_cpu = cpumask_first_and(lowest_mask, |
1279 | sched_domain_span(sd)); | 1282 | sched_domain_span(sd)); |
1280 | if (best_cpu < nr_cpu_ids) | 1283 | if (best_cpu < nr_cpu_ids) { |
1284 | rcu_read_unlock(); | ||
1281 | return best_cpu; | 1285 | return best_cpu; |
1286 | } | ||
1282 | } | 1287 | } |
1283 | } | 1288 | } |
1289 | rcu_read_unlock(); | ||
1284 | 1290 | ||
1285 | /* | 1291 | /* |
1286 | * And finally, if there were no matches within the domains | 1292 | * And finally, if there were no matches within the domains |
diff --git a/kernel/sched_stats.h b/kernel/sched_stats.h index 48ddf431db0e..331e01bcd026 100644 --- a/kernel/sched_stats.h +++ b/kernel/sched_stats.h | |||
@@ -37,7 +37,7 @@ static int show_schedstat(struct seq_file *seq, void *v) | |||
37 | 37 | ||
38 | #ifdef CONFIG_SMP | 38 | #ifdef CONFIG_SMP |
39 | /* domain-specific stats */ | 39 | /* domain-specific stats */ |
40 | preempt_disable(); | 40 | rcu_read_lock(); |
41 | for_each_domain(cpu, sd) { | 41 | for_each_domain(cpu, sd) { |
42 | enum cpu_idle_type itype; | 42 | enum cpu_idle_type itype; |
43 | 43 | ||
@@ -64,7 +64,7 @@ static int show_schedstat(struct seq_file *seq, void *v) | |||
64 | sd->ttwu_wake_remote, sd->ttwu_move_affine, | 64 | sd->ttwu_wake_remote, sd->ttwu_move_affine, |
65 | sd->ttwu_move_balance); | 65 | sd->ttwu_move_balance); |
66 | } | 66 | } |
67 | preempt_enable(); | 67 | rcu_read_unlock(); |
68 | #endif | 68 | #endif |
69 | } | 69 | } |
70 | kfree(mask_str); | 70 | kfree(mask_str); |
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index d017c2c82c44..1ee417fcbfa5 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
@@ -109,12 +109,18 @@ ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip); | |||
109 | static void ftrace_global_list_func(unsigned long ip, | 109 | static void ftrace_global_list_func(unsigned long ip, |
110 | unsigned long parent_ip) | 110 | unsigned long parent_ip) |
111 | { | 111 | { |
112 | struct ftrace_ops *op = rcu_dereference_raw(ftrace_global_list); /*see above*/ | 112 | struct ftrace_ops *op; |
113 | |||
114 | if (unlikely(trace_recursion_test(TRACE_GLOBAL_BIT))) | ||
115 | return; | ||
113 | 116 | ||
117 | trace_recursion_set(TRACE_GLOBAL_BIT); | ||
118 | op = rcu_dereference_raw(ftrace_global_list); /*see above*/ | ||
114 | while (op != &ftrace_list_end) { | 119 | while (op != &ftrace_list_end) { |
115 | op->func(ip, parent_ip); | 120 | op->func(ip, parent_ip); |
116 | op = rcu_dereference_raw(op->next); /*see above*/ | 121 | op = rcu_dereference_raw(op->next); /*see above*/ |
117 | }; | 122 | }; |
123 | trace_recursion_clear(TRACE_GLOBAL_BIT); | ||
118 | } | 124 | } |
119 | 125 | ||
120 | static void ftrace_pid_func(unsigned long ip, unsigned long parent_ip) | 126 | static void ftrace_pid_func(unsigned long ip, unsigned long parent_ip) |
@@ -1638,12 +1644,12 @@ static void ftrace_startup_enable(int command) | |||
1638 | ftrace_run_update_code(command); | 1644 | ftrace_run_update_code(command); |
1639 | } | 1645 | } |
1640 | 1646 | ||
1641 | static void ftrace_startup(struct ftrace_ops *ops, int command) | 1647 | static int ftrace_startup(struct ftrace_ops *ops, int command) |
1642 | { | 1648 | { |
1643 | bool hash_enable = true; | 1649 | bool hash_enable = true; |
1644 | 1650 | ||
1645 | if (unlikely(ftrace_disabled)) | 1651 | if (unlikely(ftrace_disabled)) |
1646 | return; | 1652 | return -ENODEV; |
1647 | 1653 | ||
1648 | ftrace_start_up++; | 1654 | ftrace_start_up++; |
1649 | command |= FTRACE_ENABLE_CALLS; | 1655 | command |= FTRACE_ENABLE_CALLS; |
@@ -1662,6 +1668,8 @@ static void ftrace_startup(struct ftrace_ops *ops, int command) | |||
1662 | ftrace_hash_rec_enable(ops, 1); | 1668 | ftrace_hash_rec_enable(ops, 1); |
1663 | 1669 | ||
1664 | ftrace_startup_enable(command); | 1670 | ftrace_startup_enable(command); |
1671 | |||
1672 | return 0; | ||
1665 | } | 1673 | } |
1666 | 1674 | ||
1667 | static void ftrace_shutdown(struct ftrace_ops *ops, int command) | 1675 | static void ftrace_shutdown(struct ftrace_ops *ops, int command) |
@@ -2501,7 +2509,7 @@ static void __enable_ftrace_function_probe(void) | |||
2501 | 2509 | ||
2502 | ret = __register_ftrace_function(&trace_probe_ops); | 2510 | ret = __register_ftrace_function(&trace_probe_ops); |
2503 | if (!ret) | 2511 | if (!ret) |
2504 | ftrace_startup(&trace_probe_ops, 0); | 2512 | ret = ftrace_startup(&trace_probe_ops, 0); |
2505 | 2513 | ||
2506 | ftrace_probe_registered = 1; | 2514 | ftrace_probe_registered = 1; |
2507 | } | 2515 | } |
@@ -3466,7 +3474,11 @@ device_initcall(ftrace_nodyn_init); | |||
3466 | static inline int ftrace_init_dyn_debugfs(struct dentry *d_tracer) { return 0; } | 3474 | static inline int ftrace_init_dyn_debugfs(struct dentry *d_tracer) { return 0; } |
3467 | static inline void ftrace_startup_enable(int command) { } | 3475 | static inline void ftrace_startup_enable(int command) { } |
3468 | /* Keep as macros so we do not need to define the commands */ | 3476 | /* Keep as macros so we do not need to define the commands */ |
3469 | # define ftrace_startup(ops, command) do { } while (0) | 3477 | # define ftrace_startup(ops, command) \ |
3478 | ({ \ | ||
3479 | (ops)->flags |= FTRACE_OPS_FL_ENABLED; \ | ||
3480 | 0; \ | ||
3481 | }) | ||
3470 | # define ftrace_shutdown(ops, command) do { } while (0) | 3482 | # define ftrace_shutdown(ops, command) do { } while (0) |
3471 | # define ftrace_startup_sysctl() do { } while (0) | 3483 | # define ftrace_startup_sysctl() do { } while (0) |
3472 | # define ftrace_shutdown_sysctl() do { } while (0) | 3484 | # define ftrace_shutdown_sysctl() do { } while (0) |
@@ -3484,6 +3496,10 @@ ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip) | |||
3484 | { | 3496 | { |
3485 | struct ftrace_ops *op; | 3497 | struct ftrace_ops *op; |
3486 | 3498 | ||
3499 | if (unlikely(trace_recursion_test(TRACE_INTERNAL_BIT))) | ||
3500 | return; | ||
3501 | |||
3502 | trace_recursion_set(TRACE_INTERNAL_BIT); | ||
3487 | /* | 3503 | /* |
3488 | * Some of the ops may be dynamically allocated, | 3504 | * Some of the ops may be dynamically allocated, |
3489 | * they must be freed after a synchronize_sched(). | 3505 | * they must be freed after a synchronize_sched(). |
@@ -3496,6 +3512,7 @@ ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip) | |||
3496 | op = rcu_dereference_raw(op->next); | 3512 | op = rcu_dereference_raw(op->next); |
3497 | }; | 3513 | }; |
3498 | preempt_enable_notrace(); | 3514 | preempt_enable_notrace(); |
3515 | trace_recursion_clear(TRACE_INTERNAL_BIT); | ||
3499 | } | 3516 | } |
3500 | 3517 | ||
3501 | static void clear_ftrace_swapper(void) | 3518 | static void clear_ftrace_swapper(void) |
@@ -3799,7 +3816,7 @@ int register_ftrace_function(struct ftrace_ops *ops) | |||
3799 | 3816 | ||
3800 | ret = __register_ftrace_function(ops); | 3817 | ret = __register_ftrace_function(ops); |
3801 | if (!ret) | 3818 | if (!ret) |
3802 | ftrace_startup(ops, 0); | 3819 | ret = ftrace_startup(ops, 0); |
3803 | 3820 | ||
3804 | 3821 | ||
3805 | out_unlock: | 3822 | out_unlock: |
@@ -4045,7 +4062,7 @@ int register_ftrace_graph(trace_func_graph_ret_t retfunc, | |||
4045 | ftrace_graph_return = retfunc; | 4062 | ftrace_graph_return = retfunc; |
4046 | ftrace_graph_entry = entryfunc; | 4063 | ftrace_graph_entry = entryfunc; |
4047 | 4064 | ||
4048 | ftrace_startup(&global_ops, FTRACE_START_FUNC_RET); | 4065 | ret = ftrace_startup(&global_ops, FTRACE_START_FUNC_RET); |
4049 | 4066 | ||
4050 | out: | 4067 | out: |
4051 | mutex_unlock(&ftrace_lock); | 4068 | mutex_unlock(&ftrace_lock); |
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 0ef7b4b2a1f7..b0c7aa407943 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c | |||
@@ -2216,7 +2216,7 @@ static noinline void trace_recursive_fail(void) | |||
2216 | 2216 | ||
2217 | printk_once(KERN_WARNING "Tracing recursion: depth[%ld]:" | 2217 | printk_once(KERN_WARNING "Tracing recursion: depth[%ld]:" |
2218 | "HC[%lu]:SC[%lu]:NMI[%lu]\n", | 2218 | "HC[%lu]:SC[%lu]:NMI[%lu]\n", |
2219 | current->trace_recursion, | 2219 | trace_recursion_buffer(), |
2220 | hardirq_count() >> HARDIRQ_SHIFT, | 2220 | hardirq_count() >> HARDIRQ_SHIFT, |
2221 | softirq_count() >> SOFTIRQ_SHIFT, | 2221 | softirq_count() >> SOFTIRQ_SHIFT, |
2222 | in_nmi()); | 2222 | in_nmi()); |
@@ -2226,9 +2226,9 @@ static noinline void trace_recursive_fail(void) | |||
2226 | 2226 | ||
2227 | static inline int trace_recursive_lock(void) | 2227 | static inline int trace_recursive_lock(void) |
2228 | { | 2228 | { |
2229 | current->trace_recursion++; | 2229 | trace_recursion_inc(); |
2230 | 2230 | ||
2231 | if (likely(current->trace_recursion < TRACE_RECURSIVE_DEPTH)) | 2231 | if (likely(trace_recursion_buffer() < TRACE_RECURSIVE_DEPTH)) |
2232 | return 0; | 2232 | return 0; |
2233 | 2233 | ||
2234 | trace_recursive_fail(); | 2234 | trace_recursive_fail(); |
@@ -2238,9 +2238,9 @@ static inline int trace_recursive_lock(void) | |||
2238 | 2238 | ||
2239 | static inline void trace_recursive_unlock(void) | 2239 | static inline void trace_recursive_unlock(void) |
2240 | { | 2240 | { |
2241 | WARN_ON_ONCE(!current->trace_recursion); | 2241 | WARN_ON_ONCE(!trace_recursion_buffer()); |
2242 | 2242 | ||
2243 | current->trace_recursion--; | 2243 | trace_recursion_dec(); |
2244 | } | 2244 | } |
2245 | 2245 | ||
2246 | #else | 2246 | #else |
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 6b69c4bd306f..229f8591f61d 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h | |||
@@ -784,4 +784,19 @@ extern const char *__stop___trace_bprintk_fmt[]; | |||
784 | FTRACE_ENTRY(call, struct_name, id, PARAMS(tstruct), PARAMS(print)) | 784 | FTRACE_ENTRY(call, struct_name, id, PARAMS(tstruct), PARAMS(print)) |
785 | #include "trace_entries.h" | 785 | #include "trace_entries.h" |
786 | 786 | ||
787 | /* Only current can touch trace_recursion */ | ||
788 | #define trace_recursion_inc() do { (current)->trace_recursion++; } while (0) | ||
789 | #define trace_recursion_dec() do { (current)->trace_recursion--; } while (0) | ||
790 | |||
791 | /* Ring buffer has the 10 LSB bits to count */ | ||
792 | #define trace_recursion_buffer() ((current)->trace_recursion & 0x3ff) | ||
793 | |||
794 | /* for function tracing recursion */ | ||
795 | #define TRACE_INTERNAL_BIT (1<<11) | ||
796 | #define TRACE_GLOBAL_BIT (1<<12) | ||
797 | |||
798 | #define trace_recursion_set(bit) do { (current)->trace_recursion |= (bit); } while (0) | ||
799 | #define trace_recursion_clear(bit) do { (current)->trace_recursion &= ~(bit); } while (0) | ||
800 | #define trace_recursion_test(bit) ((current)->trace_recursion & (bit)) | ||
801 | |||
787 | #endif /* _LINUX_KERNEL_TRACE_H */ | 802 | #endif /* _LINUX_KERNEL_TRACE_H */ |
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 2fe110341359..686ec399f2a8 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c | |||
@@ -1657,7 +1657,12 @@ static struct ftrace_ops trace_ops __initdata = | |||
1657 | 1657 | ||
1658 | static __init void event_trace_self_test_with_function(void) | 1658 | static __init void event_trace_self_test_with_function(void) |
1659 | { | 1659 | { |
1660 | register_ftrace_function(&trace_ops); | 1660 | int ret; |
1661 | ret = register_ftrace_function(&trace_ops); | ||
1662 | if (WARN_ON(ret < 0)) { | ||
1663 | pr_info("Failed to enable function tracer for event tests\n"); | ||
1664 | return; | ||
1665 | } | ||
1661 | pr_info("Running tests again, along with the function tracer\n"); | 1666 | pr_info("Running tests again, along with the function tracer\n"); |
1662 | event_trace_self_tests(); | 1667 | event_trace_self_tests(); |
1663 | unregister_ftrace_function(&trace_ops); | 1668 | unregister_ftrace_function(&trace_ops); |
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c index cf535ccedc86..e37de492a9e1 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c | |||
@@ -353,6 +353,33 @@ ftrace_print_symbols_seq(struct trace_seq *p, unsigned long val, | |||
353 | } | 353 | } |
354 | EXPORT_SYMBOL(ftrace_print_symbols_seq); | 354 | EXPORT_SYMBOL(ftrace_print_symbols_seq); |
355 | 355 | ||
356 | #if BITS_PER_LONG == 32 | ||
357 | const char * | ||
358 | ftrace_print_symbols_seq_u64(struct trace_seq *p, unsigned long long val, | ||
359 | const struct trace_print_flags_u64 *symbol_array) | ||
360 | { | ||
361 | int i; | ||
362 | const char *ret = p->buffer + p->len; | ||
363 | |||
364 | for (i = 0; symbol_array[i].name; i++) { | ||
365 | |||
366 | if (val != symbol_array[i].mask) | ||
367 | continue; | ||
368 | |||
369 | trace_seq_puts(p, symbol_array[i].name); | ||
370 | break; | ||
371 | } | ||
372 | |||
373 | if (!p->len) | ||
374 | trace_seq_printf(p, "0x%llx", val); | ||
375 | |||
376 | trace_seq_putc(p, 0); | ||
377 | |||
378 | return ret; | ||
379 | } | ||
380 | EXPORT_SYMBOL(ftrace_print_symbols_seq_u64); | ||
381 | #endif | ||
382 | |||
356 | const char * | 383 | const char * |
357 | ftrace_print_hex_seq(struct trace_seq *p, const unsigned char *buf, int buf_len) | 384 | ftrace_print_hex_seq(struct trace_seq *p, const unsigned char *buf, int buf_len) |
358 | { | 385 | { |
diff --git a/kernel/watchdog.c b/kernel/watchdog.c index 7daa4b072e9f..3d0c56ad4792 100644 --- a/kernel/watchdog.c +++ b/kernel/watchdog.c | |||
@@ -415,15 +415,13 @@ static void watchdog_nmi_disable(int cpu) { return; } | |||
415 | #endif /* CONFIG_HARDLOCKUP_DETECTOR */ | 415 | #endif /* CONFIG_HARDLOCKUP_DETECTOR */ |
416 | 416 | ||
417 | /* prepare/enable/disable routines */ | 417 | /* prepare/enable/disable routines */ |
418 | static int watchdog_prepare_cpu(int cpu) | 418 | static void watchdog_prepare_cpu(int cpu) |
419 | { | 419 | { |
420 | struct hrtimer *hrtimer = &per_cpu(watchdog_hrtimer, cpu); | 420 | struct hrtimer *hrtimer = &per_cpu(watchdog_hrtimer, cpu); |
421 | 421 | ||
422 | WARN_ON(per_cpu(softlockup_watchdog, cpu)); | 422 | WARN_ON(per_cpu(softlockup_watchdog, cpu)); |
423 | hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | 423 | hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); |
424 | hrtimer->function = watchdog_timer_fn; | 424 | hrtimer->function = watchdog_timer_fn; |
425 | |||
426 | return 0; | ||
427 | } | 425 | } |
428 | 426 | ||
429 | static int watchdog_enable(int cpu) | 427 | static int watchdog_enable(int cpu) |
@@ -542,17 +540,16 @@ static int __cpuinit | |||
542 | cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) | 540 | cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) |
543 | { | 541 | { |
544 | int hotcpu = (unsigned long)hcpu; | 542 | int hotcpu = (unsigned long)hcpu; |
545 | int err = 0; | ||
546 | 543 | ||
547 | switch (action) { | 544 | switch (action) { |
548 | case CPU_UP_PREPARE: | 545 | case CPU_UP_PREPARE: |
549 | case CPU_UP_PREPARE_FROZEN: | 546 | case CPU_UP_PREPARE_FROZEN: |
550 | err = watchdog_prepare_cpu(hotcpu); | 547 | watchdog_prepare_cpu(hotcpu); |
551 | break; | 548 | break; |
552 | case CPU_ONLINE: | 549 | case CPU_ONLINE: |
553 | case CPU_ONLINE_FROZEN: | 550 | case CPU_ONLINE_FROZEN: |
554 | if (watchdog_enabled) | 551 | if (watchdog_enabled) |
555 | err = watchdog_enable(hotcpu); | 552 | watchdog_enable(hotcpu); |
556 | break; | 553 | break; |
557 | #ifdef CONFIG_HOTPLUG_CPU | 554 | #ifdef CONFIG_HOTPLUG_CPU |
558 | case CPU_UP_CANCELED: | 555 | case CPU_UP_CANCELED: |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 28afa4c5333c..dd373c8ee943 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -697,7 +697,7 @@ config DEBUG_BUGVERBOSE | |||
697 | bool "Verbose BUG() reporting (adds 70K)" if DEBUG_KERNEL && EXPERT | 697 | bool "Verbose BUG() reporting (adds 70K)" if DEBUG_KERNEL && EXPERT |
698 | depends on BUG | 698 | depends on BUG |
699 | depends on ARM || AVR32 || M32R || M68K || SPARC32 || SPARC64 || \ | 699 | depends on ARM || AVR32 || M32R || M68K || SPARC32 || SPARC64 || \ |
700 | FRV || SUPERH || GENERIC_BUG || BLACKFIN || MN10300 | 700 | FRV || SUPERH || GENERIC_BUG || BLACKFIN || MN10300 || TILE |
701 | default y | 701 | default y |
702 | help | 702 | help |
703 | Say Y here to make BUG() panics output the file name and line number | 703 | Say Y here to make BUG() panics output the file name and line number |
diff --git a/lib/locking-selftest.c b/lib/locking-selftest.c index 619313ed6c46..507a22fab738 100644 --- a/lib/locking-selftest.c +++ b/lib/locking-selftest.c | |||
@@ -144,7 +144,7 @@ static void init_shared_classes(void) | |||
144 | 144 | ||
145 | #define HARDIRQ_ENTER() \ | 145 | #define HARDIRQ_ENTER() \ |
146 | local_irq_disable(); \ | 146 | local_irq_disable(); \ |
147 | irq_enter(); \ | 147 | __irq_enter(); \ |
148 | WARN_ON(!in_irq()); | 148 | WARN_ON(!in_irq()); |
149 | 149 | ||
150 | #define HARDIRQ_EXIT() \ | 150 | #define HARDIRQ_EXIT() \ |
diff --git a/mm/filemap.c b/mm/filemap.c index bcdc393b6580..d7b10578a64b 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -1982,16 +1982,26 @@ static int __remove_suid(struct dentry *dentry, int kill) | |||
1982 | int file_remove_suid(struct file *file) | 1982 | int file_remove_suid(struct file *file) |
1983 | { | 1983 | { |
1984 | struct dentry *dentry = file->f_path.dentry; | 1984 | struct dentry *dentry = file->f_path.dentry; |
1985 | int killsuid = should_remove_suid(dentry); | 1985 | struct inode *inode = dentry->d_inode; |
1986 | int killpriv = security_inode_need_killpriv(dentry); | 1986 | int killsuid; |
1987 | int killpriv; | ||
1987 | int error = 0; | 1988 | int error = 0; |
1988 | 1989 | ||
1990 | /* Fast path for nothing security related */ | ||
1991 | if (IS_NOSEC(inode)) | ||
1992 | return 0; | ||
1993 | |||
1994 | killsuid = should_remove_suid(dentry); | ||
1995 | killpriv = security_inode_need_killpriv(dentry); | ||
1996 | |||
1989 | if (killpriv < 0) | 1997 | if (killpriv < 0) |
1990 | return killpriv; | 1998 | return killpriv; |
1991 | if (killpriv) | 1999 | if (killpriv) |
1992 | error = security_inode_killpriv(dentry); | 2000 | error = security_inode_killpriv(dentry); |
1993 | if (!error && killsuid) | 2001 | if (!error && killsuid) |
1994 | error = __remove_suid(dentry, killsuid); | 2002 | error = __remove_suid(dentry, killsuid); |
2003 | if (!error) | ||
2004 | inode->i_flags |= S_NOSEC; | ||
1995 | 2005 | ||
1996 | return error; | 2006 | return error; |
1997 | } | 2007 | } |
@@ -2327,7 +2337,7 @@ struct page *grab_cache_page_write_begin(struct address_space *mapping, | |||
2327 | repeat: | 2337 | repeat: |
2328 | page = find_lock_page(mapping, index); | 2338 | page = find_lock_page(mapping, index); |
2329 | if (page) | 2339 | if (page) |
2330 | return page; | 2340 | goto found; |
2331 | 2341 | ||
2332 | page = __page_cache_alloc(mapping_gfp_mask(mapping) & ~gfp_notmask); | 2342 | page = __page_cache_alloc(mapping_gfp_mask(mapping) & ~gfp_notmask); |
2333 | if (!page) | 2343 | if (!page) |
@@ -2340,6 +2350,8 @@ repeat: | |||
2340 | goto repeat; | 2350 | goto repeat; |
2341 | return NULL; | 2351 | return NULL; |
2342 | } | 2352 | } |
2353 | found: | ||
2354 | wait_on_page_writeback(page); | ||
2343 | return page; | 2355 | return page; |
2344 | } | 2356 | } |
2345 | EXPORT_SYMBOL(grab_cache_page_write_begin); | 2357 | EXPORT_SYMBOL(grab_cache_page_write_begin); |
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index f33bb319b73f..6402458fee38 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
@@ -1033,10 +1033,10 @@ static struct page *alloc_huge_page(struct vm_area_struct *vma, | |||
1033 | */ | 1033 | */ |
1034 | chg = vma_needs_reservation(h, vma, addr); | 1034 | chg = vma_needs_reservation(h, vma, addr); |
1035 | if (chg < 0) | 1035 | if (chg < 0) |
1036 | return ERR_PTR(chg); | 1036 | return ERR_PTR(-VM_FAULT_OOM); |
1037 | if (chg) | 1037 | if (chg) |
1038 | if (hugetlb_get_quota(inode->i_mapping, chg)) | 1038 | if (hugetlb_get_quota(inode->i_mapping, chg)) |
1039 | return ERR_PTR(-ENOSPC); | 1039 | return ERR_PTR(-VM_FAULT_SIGBUS); |
1040 | 1040 | ||
1041 | spin_lock(&hugetlb_lock); | 1041 | spin_lock(&hugetlb_lock); |
1042 | page = dequeue_huge_page_vma(h, vma, addr, avoid_reserve); | 1042 | page = dequeue_huge_page_vma(h, vma, addr, avoid_reserve); |
diff --git a/mm/maccess.c b/mm/maccess.c index e2b6f5634e0d..4cee182ab5f3 100644 --- a/mm/maccess.c +++ b/mm/maccess.c | |||
@@ -15,10 +15,10 @@ | |||
15 | * happens, handle that and return -EFAULT. | 15 | * happens, handle that and return -EFAULT. |
16 | */ | 16 | */ |
17 | 17 | ||
18 | long __weak probe_kernel_read(void *dst, void *src, size_t size) | 18 | long __weak probe_kernel_read(void *dst, const void *src, size_t size) |
19 | __attribute__((alias("__probe_kernel_read"))); | 19 | __attribute__((alias("__probe_kernel_read"))); |
20 | 20 | ||
21 | long __probe_kernel_read(void *dst, void *src, size_t size) | 21 | long __probe_kernel_read(void *dst, const void *src, size_t size) |
22 | { | 22 | { |
23 | long ret; | 23 | long ret; |
24 | mm_segment_t old_fs = get_fs(); | 24 | mm_segment_t old_fs = get_fs(); |
@@ -43,10 +43,10 @@ EXPORT_SYMBOL_GPL(probe_kernel_read); | |||
43 | * Safely write to address @dst from the buffer at @src. If a kernel fault | 43 | * Safely write to address @dst from the buffer at @src. If a kernel fault |
44 | * happens, handle that and return -EFAULT. | 44 | * happens, handle that and return -EFAULT. |
45 | */ | 45 | */ |
46 | long __weak probe_kernel_write(void *dst, void *src, size_t size) | 46 | long __weak probe_kernel_write(void *dst, const void *src, size_t size) |
47 | __attribute__((alias("__probe_kernel_write"))); | 47 | __attribute__((alias("__probe_kernel_write"))); |
48 | 48 | ||
49 | long __probe_kernel_write(void *dst, void *src, size_t size) | 49 | long __probe_kernel_write(void *dst, const void *src, size_t size) |
50 | { | 50 | { |
51 | long ret; | 51 | long ret; |
52 | mm_segment_t old_fs = get_fs(); | 52 | mm_segment_t old_fs = get_fs(); |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index a4e1db3f1981..4e8985acdab8 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -2247,10 +2247,6 @@ __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order, | |||
2247 | 2247 | ||
2248 | if (should_fail_alloc_page(gfp_mask, order)) | 2248 | if (should_fail_alloc_page(gfp_mask, order)) |
2249 | return NULL; | 2249 | return NULL; |
2250 | #ifndef CONFIG_ZONE_DMA | ||
2251 | if (WARN_ON_ONCE(gfp_mask & __GFP_DMA)) | ||
2252 | return NULL; | ||
2253 | #endif | ||
2254 | 2250 | ||
2255 | /* | 2251 | /* |
2256 | * Check the zones suitable for the gfp_mask contain at least one | 2252 | * Check the zones suitable for the gfp_mask contain at least one |
@@ -352,6 +352,11 @@ void __init anon_vma_init(void) | |||
352 | * The page might have been remapped to a different anon_vma or the anon_vma | 352 | * The page might have been remapped to a different anon_vma or the anon_vma |
353 | * returned may already be freed (and even reused). | 353 | * returned may already be freed (and even reused). |
354 | * | 354 | * |
355 | * In case it was remapped to a different anon_vma, the new anon_vma will be a | ||
356 | * child of the old anon_vma, and the anon_vma lifetime rules will therefore | ||
357 | * ensure that any anon_vma obtained from the page will still be valid for as | ||
358 | * long as we observe page_mapped() [ hence all those page_mapped() tests ]. | ||
359 | * | ||
355 | * All users of this function must be very careful when walking the anon_vma | 360 | * All users of this function must be very careful when walking the anon_vma |
356 | * chain and verify that the page in question is indeed mapped in it | 361 | * chain and verify that the page in question is indeed mapped in it |
357 | * [ something equivalent to page_mapped_in_vma() ]. | 362 | * [ something equivalent to page_mapped_in_vma() ]. |
@@ -405,6 +410,7 @@ out: | |||
405 | struct anon_vma *page_lock_anon_vma(struct page *page) | 410 | struct anon_vma *page_lock_anon_vma(struct page *page) |
406 | { | 411 | { |
407 | struct anon_vma *anon_vma = NULL; | 412 | struct anon_vma *anon_vma = NULL; |
413 | struct anon_vma *root_anon_vma; | ||
408 | unsigned long anon_mapping; | 414 | unsigned long anon_mapping; |
409 | 415 | ||
410 | rcu_read_lock(); | 416 | rcu_read_lock(); |
@@ -415,13 +421,15 @@ struct anon_vma *page_lock_anon_vma(struct page *page) | |||
415 | goto out; | 421 | goto out; |
416 | 422 | ||
417 | anon_vma = (struct anon_vma *) (anon_mapping - PAGE_MAPPING_ANON); | 423 | anon_vma = (struct anon_vma *) (anon_mapping - PAGE_MAPPING_ANON); |
418 | if (mutex_trylock(&anon_vma->root->mutex)) { | 424 | root_anon_vma = ACCESS_ONCE(anon_vma->root); |
425 | if (mutex_trylock(&root_anon_vma->mutex)) { | ||
419 | /* | 426 | /* |
420 | * If we observe a !0 refcount, then holding the lock ensures | 427 | * If the page is still mapped, then this anon_vma is still |
421 | * the anon_vma will not go away, see __put_anon_vma(). | 428 | * its anon_vma, and holding the mutex ensures that it will |
429 | * not go away, see anon_vma_free(). | ||
422 | */ | 430 | */ |
423 | if (!atomic_read(&anon_vma->refcount)) { | 431 | if (!page_mapped(page)) { |
424 | anon_vma_unlock(anon_vma); | 432 | mutex_unlock(&root_anon_vma->mutex); |
425 | anon_vma = NULL; | 433 | anon_vma = NULL; |
426 | } | 434 | } |
427 | goto out; | 435 | goto out; |
@@ -1014,7 +1022,7 @@ void do_page_add_anon_rmap(struct page *page, | |||
1014 | return; | 1022 | return; |
1015 | 1023 | ||
1016 | VM_BUG_ON(!PageLocked(page)); | 1024 | VM_BUG_ON(!PageLocked(page)); |
1017 | VM_BUG_ON(address < vma->vm_start || address >= vma->vm_end); | 1025 | /* address might be in next vma when migration races vma_adjust */ |
1018 | if (first) | 1026 | if (first) |
1019 | __page_set_anon_rmap(page, vma, address, exclusive); | 1027 | __page_set_anon_rmap(page, vma, address, exclusive); |
1020 | else | 1028 | else |
@@ -1709,7 +1717,7 @@ void hugepage_add_anon_rmap(struct page *page, | |||
1709 | 1717 | ||
1710 | BUG_ON(!PageLocked(page)); | 1718 | BUG_ON(!PageLocked(page)); |
1711 | BUG_ON(!anon_vma); | 1719 | BUG_ON(!anon_vma); |
1712 | BUG_ON(address < vma->vm_start || address >= vma->vm_end); | 1720 | /* address might be in next vma when migration races vma_adjust */ |
1713 | first = atomic_inc_and_test(&page->_mapcount); | 1721 | first = atomic_inc_and_test(&page->_mapcount); |
1714 | if (first) | 1722 | if (first) |
1715 | __hugepage_set_anon_rmap(page, vma, address, 0); | 1723 | __hugepage_set_anon_rmap(page, vma, address, 0); |
diff --git a/mm/shmem.c b/mm/shmem.c index 1acfb2687bfa..d221a1cfd7b1 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -1114,8 +1114,8 @@ static int shmem_writepage(struct page *page, struct writeback_control *wbc) | |||
1114 | delete_from_page_cache(page); | 1114 | delete_from_page_cache(page); |
1115 | shmem_swp_set(info, entry, swap.val); | 1115 | shmem_swp_set(info, entry, swap.val); |
1116 | shmem_swp_unmap(entry); | 1116 | shmem_swp_unmap(entry); |
1117 | spin_unlock(&info->lock); | ||
1118 | swap_shmem_alloc(swap); | 1117 | swap_shmem_alloc(swap); |
1118 | spin_unlock(&info->lock); | ||
1119 | BUG_ON(page_mapped(page)); | 1119 | BUG_ON(page_mapped(page)); |
1120 | swap_writepage(page, wbc); | 1120 | swap_writepage(page, wbc); |
1121 | return 0; | 1121 | return 0; |
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index f247f5bff88d..7ea5cf9ea08a 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
@@ -165,7 +165,7 @@ static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb, | |||
165 | u64_stats_update_begin(&stats->syncp); | 165 | u64_stats_update_begin(&stats->syncp); |
166 | stats->tx_packets++; | 166 | stats->tx_packets++; |
167 | stats->tx_bytes += len; | 167 | stats->tx_bytes += len; |
168 | u64_stats_update_begin(&stats->syncp); | 168 | u64_stats_update_end(&stats->syncp); |
169 | } else { | 169 | } else { |
170 | this_cpu_inc(vlan_dev_info(dev)->vlan_pcpu_stats->tx_dropped); | 170 | this_cpu_inc(vlan_dev_info(dev)->vlan_pcpu_stats->tx_dropped); |
171 | } | 171 | } |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index a86f9ba4f05c..e64a1c2df238 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -906,7 +906,7 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm, bdaddr | |||
906 | if (c->psm == psm) { | 906 | if (c->psm == psm) { |
907 | /* Exact match. */ | 907 | /* Exact match. */ |
908 | if (!bacmp(&bt_sk(sk)->src, src)) { | 908 | if (!bacmp(&bt_sk(sk)->src, src)) { |
909 | read_unlock_bh(&chan_list_lock); | 909 | read_unlock(&chan_list_lock); |
910 | return c; | 910 | return c; |
911 | } | 911 | } |
912 | 912 | ||
diff --git a/net/caif/chnl_net.c b/net/caif/chnl_net.c index 649ebacaf6bc..adbb424403d4 100644 --- a/net/caif/chnl_net.c +++ b/net/caif/chnl_net.c | |||
@@ -139,17 +139,14 @@ static void close_work(struct work_struct *work) | |||
139 | struct chnl_net *dev = NULL; | 139 | struct chnl_net *dev = NULL; |
140 | struct list_head *list_node; | 140 | struct list_head *list_node; |
141 | struct list_head *_tmp; | 141 | struct list_head *_tmp; |
142 | /* May be called with or without RTNL lock held */ | 142 | |
143 | int islocked = rtnl_is_locked(); | 143 | rtnl_lock(); |
144 | if (!islocked) | ||
145 | rtnl_lock(); | ||
146 | list_for_each_safe(list_node, _tmp, &chnl_net_list) { | 144 | list_for_each_safe(list_node, _tmp, &chnl_net_list) { |
147 | dev = list_entry(list_node, struct chnl_net, list_field); | 145 | dev = list_entry(list_node, struct chnl_net, list_field); |
148 | if (dev->state == CAIF_SHUTDOWN) | 146 | if (dev->state == CAIF_SHUTDOWN) |
149 | dev_close(dev->netdev); | 147 | dev_close(dev->netdev); |
150 | } | 148 | } |
151 | if (!islocked) | 149 | rtnl_unlock(); |
152 | rtnl_unlock(); | ||
153 | } | 150 | } |
154 | static DECLARE_WORK(close_worker, close_work); | 151 | static DECLARE_WORK(close_worker, close_work); |
155 | 152 | ||
diff --git a/net/core/dev.c b/net/core/dev.c index c7e305d13b71..939307891e71 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2096,6 +2096,7 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, | |||
2096 | { | 2096 | { |
2097 | const struct net_device_ops *ops = dev->netdev_ops; | 2097 | const struct net_device_ops *ops = dev->netdev_ops; |
2098 | int rc = NETDEV_TX_OK; | 2098 | int rc = NETDEV_TX_OK; |
2099 | unsigned int skb_len; | ||
2099 | 2100 | ||
2100 | if (likely(!skb->next)) { | 2101 | if (likely(!skb->next)) { |
2101 | u32 features; | 2102 | u32 features; |
@@ -2146,8 +2147,9 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, | |||
2146 | } | 2147 | } |
2147 | } | 2148 | } |
2148 | 2149 | ||
2150 | skb_len = skb->len; | ||
2149 | rc = ops->ndo_start_xmit(skb, dev); | 2151 | rc = ops->ndo_start_xmit(skb, dev); |
2150 | trace_net_dev_xmit(skb, rc); | 2152 | trace_net_dev_xmit(skb, rc, dev, skb_len); |
2151 | if (rc == NETDEV_TX_OK) | 2153 | if (rc == NETDEV_TX_OK) |
2152 | txq_trans_update(txq); | 2154 | txq_trans_update(txq); |
2153 | return rc; | 2155 | return rc; |
@@ -2167,8 +2169,9 @@ gso: | |||
2167 | if (dev->priv_flags & IFF_XMIT_DST_RELEASE) | 2169 | if (dev->priv_flags & IFF_XMIT_DST_RELEASE) |
2168 | skb_dst_drop(nskb); | 2170 | skb_dst_drop(nskb); |
2169 | 2171 | ||
2172 | skb_len = nskb->len; | ||
2170 | rc = ops->ndo_start_xmit(nskb, dev); | 2173 | rc = ops->ndo_start_xmit(nskb, dev); |
2171 | trace_net_dev_xmit(nskb, rc); | 2174 | trace_net_dev_xmit(nskb, rc, dev, skb_len); |
2172 | if (unlikely(rc != NETDEV_TX_OK)) { | 2175 | if (unlikely(rc != NETDEV_TX_OK)) { |
2173 | if (rc & ~NETDEV_TX_MASK) | 2176 | if (rc & ~NETDEV_TX_MASK) |
2174 | goto out_kfree_gso_skb; | 2177 | goto out_kfree_gso_skb; |
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index cc1463156cd0..9c1926027a26 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
@@ -465,6 +465,9 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
465 | if (addr_len < sizeof(struct sockaddr_in)) | 465 | if (addr_len < sizeof(struct sockaddr_in)) |
466 | goto out; | 466 | goto out; |
467 | 467 | ||
468 | if (addr->sin_family != AF_INET) | ||
469 | goto out; | ||
470 | |||
468 | chk_addr_ret = inet_addr_type(sock_net(sk), addr->sin_addr.s_addr); | 471 | chk_addr_ret = inet_addr_type(sock_net(sk), addr->sin_addr.s_addr); |
469 | 472 | ||
470 | /* Not specified by any standard per-se, however it breaks too | 473 | /* Not specified by any standard per-se, however it breaks too |
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c index c3118e1cd3bb..ec93335901dd 100644 --- a/net/ipv4/ip_options.c +++ b/net/ipv4/ip_options.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
15 | #include <linux/types.h> | 15 | #include <linux/types.h> |
16 | #include <asm/uaccess.h> | 16 | #include <asm/uaccess.h> |
17 | #include <asm/unaligned.h> | ||
17 | #include <linux/skbuff.h> | 18 | #include <linux/skbuff.h> |
18 | #include <linux/ip.h> | 19 | #include <linux/ip.h> |
19 | #include <linux/icmp.h> | 20 | #include <linux/icmp.h> |
@@ -350,7 +351,7 @@ int ip_options_compile(struct net *net, | |||
350 | goto error; | 351 | goto error; |
351 | } | 352 | } |
352 | if (optptr[2] <= optlen) { | 353 | if (optptr[2] <= optlen) { |
353 | __be32 *timeptr = NULL; | 354 | unsigned char *timeptr = NULL; |
354 | if (optptr[2]+3 > optptr[1]) { | 355 | if (optptr[2]+3 > optptr[1]) { |
355 | pp_ptr = optptr + 2; | 356 | pp_ptr = optptr + 2; |
356 | goto error; | 357 | goto error; |
@@ -359,7 +360,7 @@ int ip_options_compile(struct net *net, | |||
359 | case IPOPT_TS_TSONLY: | 360 | case IPOPT_TS_TSONLY: |
360 | opt->ts = optptr - iph; | 361 | opt->ts = optptr - iph; |
361 | if (skb) | 362 | if (skb) |
362 | timeptr = (__be32*)&optptr[optptr[2]-1]; | 363 | timeptr = &optptr[optptr[2]-1]; |
363 | opt->ts_needtime = 1; | 364 | opt->ts_needtime = 1; |
364 | optptr[2] += 4; | 365 | optptr[2] += 4; |
365 | break; | 366 | break; |
@@ -371,7 +372,7 @@ int ip_options_compile(struct net *net, | |||
371 | opt->ts = optptr - iph; | 372 | opt->ts = optptr - iph; |
372 | if (rt) { | 373 | if (rt) { |
373 | memcpy(&optptr[optptr[2]-1], &rt->rt_spec_dst, 4); | 374 | memcpy(&optptr[optptr[2]-1], &rt->rt_spec_dst, 4); |
374 | timeptr = (__be32*)&optptr[optptr[2]+3]; | 375 | timeptr = &optptr[optptr[2]+3]; |
375 | } | 376 | } |
376 | opt->ts_needaddr = 1; | 377 | opt->ts_needaddr = 1; |
377 | opt->ts_needtime = 1; | 378 | opt->ts_needtime = 1; |
@@ -389,7 +390,7 @@ int ip_options_compile(struct net *net, | |||
389 | if (inet_addr_type(net, addr) == RTN_UNICAST) | 390 | if (inet_addr_type(net, addr) == RTN_UNICAST) |
390 | break; | 391 | break; |
391 | if (skb) | 392 | if (skb) |
392 | timeptr = (__be32*)&optptr[optptr[2]+3]; | 393 | timeptr = &optptr[optptr[2]+3]; |
393 | } | 394 | } |
394 | opt->ts_needtime = 1; | 395 | opt->ts_needtime = 1; |
395 | optptr[2] += 8; | 396 | optptr[2] += 8; |
@@ -403,10 +404,10 @@ int ip_options_compile(struct net *net, | |||
403 | } | 404 | } |
404 | if (timeptr) { | 405 | if (timeptr) { |
405 | struct timespec tv; | 406 | struct timespec tv; |
406 | __be32 midtime; | 407 | u32 midtime; |
407 | getnstimeofday(&tv); | 408 | getnstimeofday(&tv); |
408 | midtime = htonl((tv.tv_sec % 86400) * MSEC_PER_SEC + tv.tv_nsec / NSEC_PER_MSEC); | 409 | midtime = (tv.tv_sec % 86400) * MSEC_PER_SEC + tv.tv_nsec / NSEC_PER_MSEC; |
409 | memcpy(timeptr, &midtime, sizeof(__be32)); | 410 | put_unaligned_be32(midtime, timeptr); |
410 | opt->is_changed = 1; | 411 | opt->is_changed = 1; |
411 | } | 412 | } |
412 | } else { | 413 | } else { |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 4f6b2675e41d..456cccf26b51 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -232,6 +232,9 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, | |||
232 | WARN_ON(!ieee80211_set_channel_type(local, sdata, channel_type)); | 232 | WARN_ON(!ieee80211_set_channel_type(local, sdata, channel_type)); |
233 | } | 233 | } |
234 | 234 | ||
235 | ieee80211_stop_queues_by_reason(&sdata->local->hw, | ||
236 | IEEE80211_QUEUE_STOP_REASON_CSA); | ||
237 | |||
235 | /* channel_type change automatically detected */ | 238 | /* channel_type change automatically detected */ |
236 | ieee80211_hw_config(local, 0); | 239 | ieee80211_hw_config(local, 0); |
237 | 240 | ||
@@ -245,6 +248,9 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, | |||
245 | rcu_read_unlock(); | 248 | rcu_read_unlock(); |
246 | } | 249 | } |
247 | 250 | ||
251 | ieee80211_wake_queues_by_reason(&sdata->local->hw, | ||
252 | IEEE80211_QUEUE_STOP_REASON_CSA); | ||
253 | |||
248 | ht_opmode = le16_to_cpu(hti->operation_mode); | 254 | ht_opmode = le16_to_cpu(hti->operation_mode); |
249 | 255 | ||
250 | /* if bss configuration changed store the new one */ | 256 | /* if bss configuration changed store the new one */ |
@@ -1089,6 +1095,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1089 | local->hw.conf.flags &= ~IEEE80211_CONF_PS; | 1095 | local->hw.conf.flags &= ~IEEE80211_CONF_PS; |
1090 | config_changed |= IEEE80211_CONF_CHANGE_PS; | 1096 | config_changed |= IEEE80211_CONF_CHANGE_PS; |
1091 | } | 1097 | } |
1098 | local->ps_sdata = NULL; | ||
1092 | 1099 | ||
1093 | ieee80211_hw_config(local, config_changed); | 1100 | ieee80211_hw_config(local, config_changed); |
1094 | 1101 | ||
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 27af6723cb5e..58ffa7d069c7 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/if_arp.h> | 15 | #include <linux/if_arp.h> |
16 | #include <linux/rtnetlink.h> | 16 | #include <linux/rtnetlink.h> |
17 | #include <linux/pm_qos_params.h> | 17 | #include <linux/pm_qos_params.h> |
18 | #include <linux/slab.h> | ||
19 | #include <net/sch_generic.h> | 18 | #include <net/sch_generic.h> |
20 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
21 | #include <net/mac80211.h> | 20 | #include <net/mac80211.h> |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 925f715686a5..ba248d93399a 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -798,7 +798,12 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, | |||
798 | getnstimeofday(&ts); | 798 | getnstimeofday(&ts); |
799 | h.h2->tp_sec = ts.tv_sec; | 799 | h.h2->tp_sec = ts.tv_sec; |
800 | h.h2->tp_nsec = ts.tv_nsec; | 800 | h.h2->tp_nsec = ts.tv_nsec; |
801 | h.h2->tp_vlan_tci = vlan_tx_tag_get(skb); | 801 | if (vlan_tx_tag_present(skb)) { |
802 | h.h2->tp_vlan_tci = vlan_tx_tag_get(skb); | ||
803 | status |= TP_STATUS_VLAN_VALID; | ||
804 | } else { | ||
805 | h.h2->tp_vlan_tci = 0; | ||
806 | } | ||
802 | hdrlen = sizeof(*h.h2); | 807 | hdrlen = sizeof(*h.h2); |
803 | break; | 808 | break; |
804 | default: | 809 | default: |
@@ -1725,8 +1730,12 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1725 | aux.tp_snaplen = skb->len; | 1730 | aux.tp_snaplen = skb->len; |
1726 | aux.tp_mac = 0; | 1731 | aux.tp_mac = 0; |
1727 | aux.tp_net = skb_network_offset(skb); | 1732 | aux.tp_net = skb_network_offset(skb); |
1728 | aux.tp_vlan_tci = vlan_tx_tag_get(skb); | 1733 | if (vlan_tx_tag_present(skb)) { |
1729 | 1734 | aux.tp_vlan_tci = vlan_tx_tag_get(skb); | |
1735 | aux.tp_status |= TP_STATUS_VLAN_VALID; | ||
1736 | } else { | ||
1737 | aux.tp_vlan_tci = 0; | ||
1738 | } | ||
1730 | put_cmsg(msg, SOL_PACKET, PACKET_AUXDATA, sizeof(aux), &aux); | 1739 | put_cmsg(msg, SOL_PACKET, PACKET_AUXDATA, sizeof(aux), &aux); |
1731 | } | 1740 | } |
1732 | 1741 | ||
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 525f97c467e9..4a62888f2e43 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
@@ -444,15 +444,7 @@ void sctp_association_free(struct sctp_association *asoc) | |||
444 | 444 | ||
445 | asoc->peer.transport_count = 0; | 445 | asoc->peer.transport_count = 0; |
446 | 446 | ||
447 | /* Free any cached ASCONF_ACK chunk. */ | 447 | sctp_asconf_queue_teardown(asoc); |
448 | sctp_assoc_free_asconf_acks(asoc); | ||
449 | |||
450 | /* Free the ASCONF queue. */ | ||
451 | sctp_assoc_free_asconf_queue(asoc); | ||
452 | |||
453 | /* Free any cached ASCONF chunk. */ | ||
454 | if (asoc->addip_last_asconf) | ||
455 | sctp_chunk_free(asoc->addip_last_asconf); | ||
456 | 448 | ||
457 | /* AUTH - Free the endpoint shared keys */ | 449 | /* AUTH - Free the endpoint shared keys */ |
458 | sctp_auth_destroy_keys(&asoc->endpoint_shared_keys); | 450 | sctp_auth_destroy_keys(&asoc->endpoint_shared_keys); |
@@ -1646,3 +1638,16 @@ struct sctp_chunk *sctp_assoc_lookup_asconf_ack( | |||
1646 | 1638 | ||
1647 | return NULL; | 1639 | return NULL; |
1648 | } | 1640 | } |
1641 | |||
1642 | void sctp_asconf_queue_teardown(struct sctp_association *asoc) | ||
1643 | { | ||
1644 | /* Free any cached ASCONF_ACK chunk. */ | ||
1645 | sctp_assoc_free_asconf_acks(asoc); | ||
1646 | |||
1647 | /* Free the ASCONF queue. */ | ||
1648 | sctp_assoc_free_asconf_queue(asoc); | ||
1649 | |||
1650 | /* Free any cached ASCONF chunk. */ | ||
1651 | if (asoc->addip_last_asconf) | ||
1652 | sctp_chunk_free(asoc->addip_last_asconf); | ||
1653 | } | ||
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index d612ca1ca6c0..534c2e5feb05 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
@@ -1670,6 +1670,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
1670 | case SCTP_CMD_SEND_NEXT_ASCONF: | 1670 | case SCTP_CMD_SEND_NEXT_ASCONF: |
1671 | sctp_cmd_send_asconf(asoc); | 1671 | sctp_cmd_send_asconf(asoc); |
1672 | break; | 1672 | break; |
1673 | case SCTP_CMD_PURGE_ASCONF_QUEUE: | ||
1674 | sctp_asconf_queue_teardown(asoc); | ||
1675 | break; | ||
1673 | default: | 1676 | default: |
1674 | pr_warn("Impossible command: %u, %p\n", | 1677 | pr_warn("Impossible command: %u, %p\n", |
1675 | cmd->verb, cmd->obj.ptr); | 1678 | cmd->verb, cmd->obj.ptr); |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 7f4a4f8368ee..a297283154d5 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -1718,11 +1718,21 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep, | |||
1718 | return SCTP_DISPOSITION_CONSUME; | 1718 | return SCTP_DISPOSITION_CONSUME; |
1719 | } | 1719 | } |
1720 | 1720 | ||
1721 | /* For now, fail any unsent/unacked data. Consider the optional | 1721 | /* For now, stop pending T3-rtx and SACK timers, fail any unsent/unacked |
1722 | * choice of resending of this data. | 1722 | * data. Consider the optional choice of resending of this data. |
1723 | */ | 1723 | */ |
1724 | sctp_add_cmd_sf(commands, SCTP_CMD_T3_RTX_TIMERS_STOP, SCTP_NULL()); | ||
1725 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, | ||
1726 | SCTP_TO(SCTP_EVENT_TIMEOUT_SACK)); | ||
1724 | sctp_add_cmd_sf(commands, SCTP_CMD_PURGE_OUTQUEUE, SCTP_NULL()); | 1727 | sctp_add_cmd_sf(commands, SCTP_CMD_PURGE_OUTQUEUE, SCTP_NULL()); |
1725 | 1728 | ||
1729 | /* Stop pending T4-rto timer, teardown ASCONF queue, ASCONF-ACK queue | ||
1730 | * and ASCONF-ACK cache. | ||
1731 | */ | ||
1732 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, | ||
1733 | SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO)); | ||
1734 | sctp_add_cmd_sf(commands, SCTP_CMD_PURGE_ASCONF_QUEUE, SCTP_NULL()); | ||
1735 | |||
1726 | repl = sctp_make_cookie_ack(new_asoc, chunk); | 1736 | repl = sctp_make_cookie_ack(new_asoc, chunk); |
1727 | if (!repl) | 1737 | if (!repl) |
1728 | goto nomem; | 1738 | goto nomem; |
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 8d83f9d48713..b84d7395535e 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
@@ -13,10 +13,6 @@ | |||
13 | * and need to be refreshed, or when a packet was damaged in transit. | 13 | * and need to be refreshed, or when a packet was damaged in transit. |
14 | * This may be have to be moved to the VFS layer. | 14 | * This may be have to be moved to the VFS layer. |
15 | * | 15 | * |
16 | * NB: BSD uses a more intelligent approach to guessing when a request | ||
17 | * or reply has been lost by keeping the RTO estimate for each procedure. | ||
18 | * We currently make do with a constant timeout value. | ||
19 | * | ||
20 | * Copyright (C) 1992,1993 Rick Sladkey <jrs@world.std.com> | 16 | * Copyright (C) 1992,1993 Rick Sladkey <jrs@world.std.com> |
21 | * Copyright (C) 1995,1996 Olaf Kirch <okir@monad.swb.de> | 17 | * Copyright (C) 1995,1996 Olaf Kirch <okir@monad.swb.de> |
22 | */ | 18 | */ |
@@ -32,7 +28,9 @@ | |||
32 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
33 | #include <linux/utsname.h> | 29 | #include <linux/utsname.h> |
34 | #include <linux/workqueue.h> | 30 | #include <linux/workqueue.h> |
31 | #include <linux/in.h> | ||
35 | #include <linux/in6.h> | 32 | #include <linux/in6.h> |
33 | #include <linux/un.h> | ||
36 | 34 | ||
37 | #include <linux/sunrpc/clnt.h> | 35 | #include <linux/sunrpc/clnt.h> |
38 | #include <linux/sunrpc/rpc_pipe_fs.h> | 36 | #include <linux/sunrpc/rpc_pipe_fs.h> |
@@ -298,22 +296,27 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args) | |||
298 | * up a string representation of the passed-in address. | 296 | * up a string representation of the passed-in address. |
299 | */ | 297 | */ |
300 | if (args->servername == NULL) { | 298 | if (args->servername == NULL) { |
299 | struct sockaddr_un *sun = | ||
300 | (struct sockaddr_un *)args->address; | ||
301 | struct sockaddr_in *sin = | ||
302 | (struct sockaddr_in *)args->address; | ||
303 | struct sockaddr_in6 *sin6 = | ||
304 | (struct sockaddr_in6 *)args->address; | ||
305 | |||
301 | servername[0] = '\0'; | 306 | servername[0] = '\0'; |
302 | switch (args->address->sa_family) { | 307 | switch (args->address->sa_family) { |
303 | case AF_INET: { | 308 | case AF_LOCAL: |
304 | struct sockaddr_in *sin = | 309 | snprintf(servername, sizeof(servername), "%s", |
305 | (struct sockaddr_in *)args->address; | 310 | sun->sun_path); |
311 | break; | ||
312 | case AF_INET: | ||
306 | snprintf(servername, sizeof(servername), "%pI4", | 313 | snprintf(servername, sizeof(servername), "%pI4", |
307 | &sin->sin_addr.s_addr); | 314 | &sin->sin_addr.s_addr); |
308 | break; | 315 | break; |
309 | } | 316 | case AF_INET6: |
310 | case AF_INET6: { | ||
311 | struct sockaddr_in6 *sin = | ||
312 | (struct sockaddr_in6 *)args->address; | ||
313 | snprintf(servername, sizeof(servername), "%pI6", | 317 | snprintf(servername, sizeof(servername), "%pI6", |
314 | &sin->sin6_addr); | 318 | &sin6->sin6_addr); |
315 | break; | 319 | break; |
316 | } | ||
317 | default: | 320 | default: |
318 | /* caller wants default server name, but | 321 | /* caller wants default server name, but |
319 | * address family isn't recognized. */ | 322 | * address family isn't recognized. */ |
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index c652e4cc9fe9..9a80a922c527 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c | |||
@@ -16,6 +16,7 @@ | |||
16 | 16 | ||
17 | #include <linux/types.h> | 17 | #include <linux/types.h> |
18 | #include <linux/socket.h> | 18 | #include <linux/socket.h> |
19 | #include <linux/un.h> | ||
19 | #include <linux/in.h> | 20 | #include <linux/in.h> |
20 | #include <linux/in6.h> | 21 | #include <linux/in6.h> |
21 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
@@ -32,6 +33,8 @@ | |||
32 | # define RPCDBG_FACILITY RPCDBG_BIND | 33 | # define RPCDBG_FACILITY RPCDBG_BIND |
33 | #endif | 34 | #endif |
34 | 35 | ||
36 | #define RPCBIND_SOCK_PATHNAME "/var/run/rpcbind.sock" | ||
37 | |||
35 | #define RPCBIND_PROGRAM (100000u) | 38 | #define RPCBIND_PROGRAM (100000u) |
36 | #define RPCBIND_PORT (111u) | 39 | #define RPCBIND_PORT (111u) |
37 | 40 | ||
@@ -158,20 +161,69 @@ static void rpcb_map_release(void *data) | |||
158 | kfree(map); | 161 | kfree(map); |
159 | } | 162 | } |
160 | 163 | ||
161 | static const struct sockaddr_in rpcb_inaddr_loopback = { | 164 | /* |
162 | .sin_family = AF_INET, | 165 | * Returns zero on success, otherwise a negative errno value |
163 | .sin_addr.s_addr = htonl(INADDR_LOOPBACK), | 166 | * is returned. |
164 | .sin_port = htons(RPCBIND_PORT), | 167 | */ |
165 | }; | 168 | static int rpcb_create_local_unix(void) |
169 | { | ||
170 | static const struct sockaddr_un rpcb_localaddr_rpcbind = { | ||
171 | .sun_family = AF_LOCAL, | ||
172 | .sun_path = RPCBIND_SOCK_PATHNAME, | ||
173 | }; | ||
174 | struct rpc_create_args args = { | ||
175 | .net = &init_net, | ||
176 | .protocol = XPRT_TRANSPORT_LOCAL, | ||
177 | .address = (struct sockaddr *)&rpcb_localaddr_rpcbind, | ||
178 | .addrsize = sizeof(rpcb_localaddr_rpcbind), | ||
179 | .servername = "localhost", | ||
180 | .program = &rpcb_program, | ||
181 | .version = RPCBVERS_2, | ||
182 | .authflavor = RPC_AUTH_NULL, | ||
183 | }; | ||
184 | struct rpc_clnt *clnt, *clnt4; | ||
185 | int result = 0; | ||
186 | |||
187 | /* | ||
188 | * Because we requested an RPC PING at transport creation time, | ||
189 | * this works only if the user space portmapper is rpcbind, and | ||
190 | * it's listening on AF_LOCAL on the named socket. | ||
191 | */ | ||
192 | clnt = rpc_create(&args); | ||
193 | if (IS_ERR(clnt)) { | ||
194 | dprintk("RPC: failed to create AF_LOCAL rpcbind " | ||
195 | "client (errno %ld).\n", PTR_ERR(clnt)); | ||
196 | result = -PTR_ERR(clnt); | ||
197 | goto out; | ||
198 | } | ||
199 | |||
200 | clnt4 = rpc_bind_new_program(clnt, &rpcb_program, RPCBVERS_4); | ||
201 | if (IS_ERR(clnt4)) { | ||
202 | dprintk("RPC: failed to bind second program to " | ||
203 | "rpcbind v4 client (errno %ld).\n", | ||
204 | PTR_ERR(clnt4)); | ||
205 | clnt4 = NULL; | ||
206 | } | ||
207 | |||
208 | /* Protected by rpcb_create_local_mutex */ | ||
209 | rpcb_local_clnt = clnt; | ||
210 | rpcb_local_clnt4 = clnt4; | ||
166 | 211 | ||
167 | static DEFINE_MUTEX(rpcb_create_local_mutex); | 212 | out: |
213 | return result; | ||
214 | } | ||
168 | 215 | ||
169 | /* | 216 | /* |
170 | * Returns zero on success, otherwise a negative errno value | 217 | * Returns zero on success, otherwise a negative errno value |
171 | * is returned. | 218 | * is returned. |
172 | */ | 219 | */ |
173 | static int rpcb_create_local(void) | 220 | static int rpcb_create_local_net(void) |
174 | { | 221 | { |
222 | static const struct sockaddr_in rpcb_inaddr_loopback = { | ||
223 | .sin_family = AF_INET, | ||
224 | .sin_addr.s_addr = htonl(INADDR_LOOPBACK), | ||
225 | .sin_port = htons(RPCBIND_PORT), | ||
226 | }; | ||
175 | struct rpc_create_args args = { | 227 | struct rpc_create_args args = { |
176 | .net = &init_net, | 228 | .net = &init_net, |
177 | .protocol = XPRT_TRANSPORT_TCP, | 229 | .protocol = XPRT_TRANSPORT_TCP, |
@@ -186,13 +238,6 @@ static int rpcb_create_local(void) | |||
186 | struct rpc_clnt *clnt, *clnt4; | 238 | struct rpc_clnt *clnt, *clnt4; |
187 | int result = 0; | 239 | int result = 0; |
188 | 240 | ||
189 | if (rpcb_local_clnt) | ||
190 | return result; | ||
191 | |||
192 | mutex_lock(&rpcb_create_local_mutex); | ||
193 | if (rpcb_local_clnt) | ||
194 | goto out; | ||
195 | |||
196 | clnt = rpc_create(&args); | 241 | clnt = rpc_create(&args); |
197 | if (IS_ERR(clnt)) { | 242 | if (IS_ERR(clnt)) { |
198 | dprintk("RPC: failed to create local rpcbind " | 243 | dprintk("RPC: failed to create local rpcbind " |
@@ -214,10 +259,34 @@ static int rpcb_create_local(void) | |||
214 | clnt4 = NULL; | 259 | clnt4 = NULL; |
215 | } | 260 | } |
216 | 261 | ||
262 | /* Protected by rpcb_create_local_mutex */ | ||
217 | rpcb_local_clnt = clnt; | 263 | rpcb_local_clnt = clnt; |
218 | rpcb_local_clnt4 = clnt4; | 264 | rpcb_local_clnt4 = clnt4; |
219 | 265 | ||
220 | out: | 266 | out: |
267 | return result; | ||
268 | } | ||
269 | |||
270 | /* | ||
271 | * Returns zero on success, otherwise a negative errno value | ||
272 | * is returned. | ||
273 | */ | ||
274 | static int rpcb_create_local(void) | ||
275 | { | ||
276 | static DEFINE_MUTEX(rpcb_create_local_mutex); | ||
277 | int result = 0; | ||
278 | |||
279 | if (rpcb_local_clnt) | ||
280 | return result; | ||
281 | |||
282 | mutex_lock(&rpcb_create_local_mutex); | ||
283 | if (rpcb_local_clnt) | ||
284 | goto out; | ||
285 | |||
286 | if (rpcb_create_local_unix() != 0) | ||
287 | result = rpcb_create_local_net(); | ||
288 | |||
289 | out: | ||
221 | mutex_unlock(&rpcb_create_local_mutex); | 290 | mutex_unlock(&rpcb_create_local_mutex); |
222 | return result; | 291 | return result; |
223 | } | 292 | } |
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 08e05a8ce025..2b90292e9505 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c | |||
@@ -942,6 +942,8 @@ static void svc_unregister(const struct svc_serv *serv) | |||
942 | if (progp->pg_vers[i]->vs_hidden) | 942 | if (progp->pg_vers[i]->vs_hidden) |
943 | continue; | 943 | continue; |
944 | 944 | ||
945 | dprintk("svc: attempting to unregister %sv%u\n", | ||
946 | progp->pg_name, i); | ||
945 | __svc_unregister(progp->pg_prog, i, progp->pg_name); | 947 | __svc_unregister(progp->pg_prog, i, progp->pg_name); |
946 | } | 948 | } |
947 | } | 949 | } |
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index b7d435c3f19e..af04f779ce9f 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
@@ -387,6 +387,33 @@ static int svc_recvfrom(struct svc_rqst *rqstp, struct kvec *iov, int nr, | |||
387 | return len; | 387 | return len; |
388 | } | 388 | } |
389 | 389 | ||
390 | static int svc_partial_recvfrom(struct svc_rqst *rqstp, | ||
391 | struct kvec *iov, int nr, | ||
392 | int buflen, unsigned int base) | ||
393 | { | ||
394 | size_t save_iovlen; | ||
395 | void __user *save_iovbase; | ||
396 | unsigned int i; | ||
397 | int ret; | ||
398 | |||
399 | if (base == 0) | ||
400 | return svc_recvfrom(rqstp, iov, nr, buflen); | ||
401 | |||
402 | for (i = 0; i < nr; i++) { | ||
403 | if (iov[i].iov_len > base) | ||
404 | break; | ||
405 | base -= iov[i].iov_len; | ||
406 | } | ||
407 | save_iovlen = iov[i].iov_len; | ||
408 | save_iovbase = iov[i].iov_base; | ||
409 | iov[i].iov_len -= base; | ||
410 | iov[i].iov_base += base; | ||
411 | ret = svc_recvfrom(rqstp, &iov[i], nr - i, buflen); | ||
412 | iov[i].iov_len = save_iovlen; | ||
413 | iov[i].iov_base = save_iovbase; | ||
414 | return ret; | ||
415 | } | ||
416 | |||
390 | /* | 417 | /* |
391 | * Set socket snd and rcv buffer lengths | 418 | * Set socket snd and rcv buffer lengths |
392 | */ | 419 | */ |
@@ -409,7 +436,6 @@ static void svc_sock_setbufsize(struct socket *sock, unsigned int snd, | |||
409 | lock_sock(sock->sk); | 436 | lock_sock(sock->sk); |
410 | sock->sk->sk_sndbuf = snd * 2; | 437 | sock->sk->sk_sndbuf = snd * 2; |
411 | sock->sk->sk_rcvbuf = rcv * 2; | 438 | sock->sk->sk_rcvbuf = rcv * 2; |
412 | sock->sk->sk_userlocks |= SOCK_SNDBUF_LOCK|SOCK_RCVBUF_LOCK; | ||
413 | sock->sk->sk_write_space(sock->sk); | 439 | sock->sk->sk_write_space(sock->sk); |
414 | release_sock(sock->sk); | 440 | release_sock(sock->sk); |
415 | #endif | 441 | #endif |
@@ -884,6 +910,56 @@ failed: | |||
884 | return NULL; | 910 | return NULL; |
885 | } | 911 | } |
886 | 912 | ||
913 | static unsigned int svc_tcp_restore_pages(struct svc_sock *svsk, struct svc_rqst *rqstp) | ||
914 | { | ||
915 | unsigned int i, len, npages; | ||
916 | |||
917 | if (svsk->sk_tcplen <= sizeof(rpc_fraghdr)) | ||
918 | return 0; | ||
919 | len = svsk->sk_tcplen - sizeof(rpc_fraghdr); | ||
920 | npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; | ||
921 | for (i = 0; i < npages; i++) { | ||
922 | if (rqstp->rq_pages[i] != NULL) | ||
923 | put_page(rqstp->rq_pages[i]); | ||
924 | BUG_ON(svsk->sk_pages[i] == NULL); | ||
925 | rqstp->rq_pages[i] = svsk->sk_pages[i]; | ||
926 | svsk->sk_pages[i] = NULL; | ||
927 | } | ||
928 | rqstp->rq_arg.head[0].iov_base = page_address(rqstp->rq_pages[0]); | ||
929 | return len; | ||
930 | } | ||
931 | |||
932 | static void svc_tcp_save_pages(struct svc_sock *svsk, struct svc_rqst *rqstp) | ||
933 | { | ||
934 | unsigned int i, len, npages; | ||
935 | |||
936 | if (svsk->sk_tcplen <= sizeof(rpc_fraghdr)) | ||
937 | return; | ||
938 | len = svsk->sk_tcplen - sizeof(rpc_fraghdr); | ||
939 | npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; | ||
940 | for (i = 0; i < npages; i++) { | ||
941 | svsk->sk_pages[i] = rqstp->rq_pages[i]; | ||
942 | rqstp->rq_pages[i] = NULL; | ||
943 | } | ||
944 | } | ||
945 | |||
946 | static void svc_tcp_clear_pages(struct svc_sock *svsk) | ||
947 | { | ||
948 | unsigned int i, len, npages; | ||
949 | |||
950 | if (svsk->sk_tcplen <= sizeof(rpc_fraghdr)) | ||
951 | goto out; | ||
952 | len = svsk->sk_tcplen - sizeof(rpc_fraghdr); | ||
953 | npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; | ||
954 | for (i = 0; i < npages; i++) { | ||
955 | BUG_ON(svsk->sk_pages[i] == NULL); | ||
956 | put_page(svsk->sk_pages[i]); | ||
957 | svsk->sk_pages[i] = NULL; | ||
958 | } | ||
959 | out: | ||
960 | svsk->sk_tcplen = 0; | ||
961 | } | ||
962 | |||
887 | /* | 963 | /* |
888 | * Receive data. | 964 | * Receive data. |
889 | * If we haven't gotten the record length yet, get the next four bytes. | 965 | * If we haven't gotten the record length yet, get the next four bytes. |
@@ -893,31 +969,15 @@ failed: | |||
893 | static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp) | 969 | static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp) |
894 | { | 970 | { |
895 | struct svc_serv *serv = svsk->sk_xprt.xpt_server; | 971 | struct svc_serv *serv = svsk->sk_xprt.xpt_server; |
972 | unsigned int want; | ||
896 | int len; | 973 | int len; |
897 | 974 | ||
898 | if (test_and_clear_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags)) | ||
899 | /* sndbuf needs to have room for one request | ||
900 | * per thread, otherwise we can stall even when the | ||
901 | * network isn't a bottleneck. | ||
902 | * | ||
903 | * We count all threads rather than threads in a | ||
904 | * particular pool, which provides an upper bound | ||
905 | * on the number of threads which will access the socket. | ||
906 | * | ||
907 | * rcvbuf just needs to be able to hold a few requests. | ||
908 | * Normally they will be removed from the queue | ||
909 | * as soon a a complete request arrives. | ||
910 | */ | ||
911 | svc_sock_setbufsize(svsk->sk_sock, | ||
912 | (serv->sv_nrthreads+3) * serv->sv_max_mesg, | ||
913 | 3 * serv->sv_max_mesg); | ||
914 | |||
915 | clear_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); | 975 | clear_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); |
916 | 976 | ||
917 | if (svsk->sk_tcplen < sizeof(rpc_fraghdr)) { | 977 | if (svsk->sk_tcplen < sizeof(rpc_fraghdr)) { |
918 | int want = sizeof(rpc_fraghdr) - svsk->sk_tcplen; | ||
919 | struct kvec iov; | 978 | struct kvec iov; |
920 | 979 | ||
980 | want = sizeof(rpc_fraghdr) - svsk->sk_tcplen; | ||
921 | iov.iov_base = ((char *) &svsk->sk_reclen) + svsk->sk_tcplen; | 981 | iov.iov_base = ((char *) &svsk->sk_reclen) + svsk->sk_tcplen; |
922 | iov.iov_len = want; | 982 | iov.iov_len = want; |
923 | if ((len = svc_recvfrom(rqstp, &iov, 1, want)) < 0) | 983 | if ((len = svc_recvfrom(rqstp, &iov, 1, want)) < 0) |
@@ -927,7 +987,7 @@ static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp) | |||
927 | if (len < want) { | 987 | if (len < want) { |
928 | dprintk("svc: short recvfrom while reading record " | 988 | dprintk("svc: short recvfrom while reading record " |
929 | "length (%d of %d)\n", len, want); | 989 | "length (%d of %d)\n", len, want); |
930 | goto err_again; /* record header not complete */ | 990 | return -EAGAIN; |
931 | } | 991 | } |
932 | 992 | ||
933 | svsk->sk_reclen = ntohl(svsk->sk_reclen); | 993 | svsk->sk_reclen = ntohl(svsk->sk_reclen); |
@@ -954,83 +1014,75 @@ static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp) | |||
954 | } | 1014 | } |
955 | } | 1015 | } |
956 | 1016 | ||
957 | /* Check whether enough data is available */ | 1017 | if (svsk->sk_reclen < 8) |
958 | len = svc_recv_available(svsk); | 1018 | goto err_delete; /* client is nuts. */ |
959 | if (len < 0) | ||
960 | goto error; | ||
961 | 1019 | ||
962 | if (len < svsk->sk_reclen) { | ||
963 | dprintk("svc: incomplete TCP record (%d of %d)\n", | ||
964 | len, svsk->sk_reclen); | ||
965 | goto err_again; /* record not complete */ | ||
966 | } | ||
967 | len = svsk->sk_reclen; | 1020 | len = svsk->sk_reclen; |
968 | set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); | ||
969 | 1021 | ||
970 | return len; | 1022 | return len; |
971 | error: | 1023 | error: |
972 | if (len == -EAGAIN) | 1024 | dprintk("RPC: TCP recv_record got %d\n", len); |
973 | dprintk("RPC: TCP recv_record got EAGAIN\n"); | ||
974 | return len; | 1025 | return len; |
975 | err_delete: | 1026 | err_delete: |
976 | set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); | 1027 | set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); |
977 | err_again: | ||
978 | return -EAGAIN; | 1028 | return -EAGAIN; |
979 | } | 1029 | } |
980 | 1030 | ||
981 | static int svc_process_calldir(struct svc_sock *svsk, struct svc_rqst *rqstp, | 1031 | static int receive_cb_reply(struct svc_sock *svsk, struct svc_rqst *rqstp) |
982 | struct rpc_rqst **reqpp, struct kvec *vec) | ||
983 | { | 1032 | { |
1033 | struct rpc_xprt *bc_xprt = svsk->sk_xprt.xpt_bc_xprt; | ||
984 | struct rpc_rqst *req = NULL; | 1034 | struct rpc_rqst *req = NULL; |
985 | u32 *p; | 1035 | struct kvec *src, *dst; |
986 | u32 xid; | 1036 | __be32 *p = (__be32 *)rqstp->rq_arg.head[0].iov_base; |
987 | u32 calldir; | 1037 | __be32 xid; |
988 | int len; | 1038 | __be32 calldir; |
989 | |||
990 | len = svc_recvfrom(rqstp, vec, 1, 8); | ||
991 | if (len < 0) | ||
992 | goto error; | ||
993 | 1039 | ||
994 | p = (u32 *)rqstp->rq_arg.head[0].iov_base; | ||
995 | xid = *p++; | 1040 | xid = *p++; |
996 | calldir = *p; | 1041 | calldir = *p; |
997 | 1042 | ||
998 | if (calldir == 0) { | 1043 | if (bc_xprt) |
999 | /* REQUEST is the most common case */ | 1044 | req = xprt_lookup_rqst(bc_xprt, xid); |
1000 | vec[0] = rqstp->rq_arg.head[0]; | ||
1001 | } else { | ||
1002 | /* REPLY */ | ||
1003 | struct rpc_xprt *bc_xprt = svsk->sk_xprt.xpt_bc_xprt; | ||
1004 | |||
1005 | if (bc_xprt) | ||
1006 | req = xprt_lookup_rqst(bc_xprt, xid); | ||
1007 | |||
1008 | if (!req) { | ||
1009 | printk(KERN_NOTICE | ||
1010 | "%s: Got unrecognized reply: " | ||
1011 | "calldir 0x%x xpt_bc_xprt %p xid %08x\n", | ||
1012 | __func__, ntohl(calldir), | ||
1013 | bc_xprt, xid); | ||
1014 | vec[0] = rqstp->rq_arg.head[0]; | ||
1015 | goto out; | ||
1016 | } | ||
1017 | 1045 | ||
1018 | memcpy(&req->rq_private_buf, &req->rq_rcv_buf, | 1046 | if (!req) { |
1019 | sizeof(struct xdr_buf)); | 1047 | printk(KERN_NOTICE |
1020 | /* copy the xid and call direction */ | 1048 | "%s: Got unrecognized reply: " |
1021 | memcpy(req->rq_private_buf.head[0].iov_base, | 1049 | "calldir 0x%x xpt_bc_xprt %p xid %08x\n", |
1022 | rqstp->rq_arg.head[0].iov_base, 8); | 1050 | __func__, ntohl(calldir), |
1023 | vec[0] = req->rq_private_buf.head[0]; | 1051 | bc_xprt, xid); |
1052 | return -EAGAIN; | ||
1024 | } | 1053 | } |
1025 | out: | 1054 | |
1026 | vec[0].iov_base += 8; | 1055 | memcpy(&req->rq_private_buf, &req->rq_rcv_buf, sizeof(struct xdr_buf)); |
1027 | vec[0].iov_len -= 8; | 1056 | /* |
1028 | len = svsk->sk_reclen - 8; | 1057 | * XXX!: cheating for now! Only copying HEAD. |
1029 | error: | 1058 | * But we know this is good enough for now (in fact, for any |
1030 | *reqpp = req; | 1059 | * callback reply in the forseeable future). |
1031 | return len; | 1060 | */ |
1061 | dst = &req->rq_private_buf.head[0]; | ||
1062 | src = &rqstp->rq_arg.head[0]; | ||
1063 | if (dst->iov_len < src->iov_len) | ||
1064 | return -EAGAIN; /* whatever; just giving up. */ | ||
1065 | memcpy(dst->iov_base, src->iov_base, src->iov_len); | ||
1066 | xprt_complete_rqst(req->rq_task, svsk->sk_reclen); | ||
1067 | rqstp->rq_arg.len = 0; | ||
1068 | return 0; | ||
1032 | } | 1069 | } |
1033 | 1070 | ||
1071 | static int copy_pages_to_kvecs(struct kvec *vec, struct page **pages, int len) | ||
1072 | { | ||
1073 | int i = 0; | ||
1074 | int t = 0; | ||
1075 | |||
1076 | while (t < len) { | ||
1077 | vec[i].iov_base = page_address(pages[i]); | ||
1078 | vec[i].iov_len = PAGE_SIZE; | ||
1079 | i++; | ||
1080 | t += PAGE_SIZE; | ||
1081 | } | ||
1082 | return i; | ||
1083 | } | ||
1084 | |||
1085 | |||
1034 | /* | 1086 | /* |
1035 | * Receive data from a TCP socket. | 1087 | * Receive data from a TCP socket. |
1036 | */ | 1088 | */ |
@@ -1041,8 +1093,10 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp) | |||
1041 | struct svc_serv *serv = svsk->sk_xprt.xpt_server; | 1093 | struct svc_serv *serv = svsk->sk_xprt.xpt_server; |
1042 | int len; | 1094 | int len; |
1043 | struct kvec *vec; | 1095 | struct kvec *vec; |
1044 | int pnum, vlen; | 1096 | unsigned int want, base; |
1045 | struct rpc_rqst *req = NULL; | 1097 | __be32 *p; |
1098 | __be32 calldir; | ||
1099 | int pnum; | ||
1046 | 1100 | ||
1047 | dprintk("svc: tcp_recv %p data %d conn %d close %d\n", | 1101 | dprintk("svc: tcp_recv %p data %d conn %d close %d\n", |
1048 | svsk, test_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags), | 1102 | svsk, test_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags), |
@@ -1053,87 +1107,73 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp) | |||
1053 | if (len < 0) | 1107 | if (len < 0) |
1054 | goto error; | 1108 | goto error; |
1055 | 1109 | ||
1110 | base = svc_tcp_restore_pages(svsk, rqstp); | ||
1111 | want = svsk->sk_reclen - base; | ||
1112 | |||
1056 | vec = rqstp->rq_vec; | 1113 | vec = rqstp->rq_vec; |
1057 | vec[0] = rqstp->rq_arg.head[0]; | ||
1058 | vlen = PAGE_SIZE; | ||
1059 | 1114 | ||
1060 | /* | 1115 | pnum = copy_pages_to_kvecs(&vec[0], &rqstp->rq_pages[0], |
1061 | * We have enough data for the whole tcp record. Let's try and read the | 1116 | svsk->sk_reclen); |
1062 | * first 8 bytes to get the xid and the call direction. We can use this | ||
1063 | * to figure out if this is a call or a reply to a callback. If | ||
1064 | * sk_reclen is < 8 (xid and calldir), then this is a malformed packet. | ||
1065 | * In that case, don't bother with the calldir and just read the data. | ||
1066 | * It will be rejected in svc_process. | ||
1067 | */ | ||
1068 | if (len >= 8) { | ||
1069 | len = svc_process_calldir(svsk, rqstp, &req, vec); | ||
1070 | if (len < 0) | ||
1071 | goto err_again; | ||
1072 | vlen -= 8; | ||
1073 | } | ||
1074 | 1117 | ||
1075 | pnum = 1; | ||
1076 | while (vlen < len) { | ||
1077 | vec[pnum].iov_base = (req) ? | ||
1078 | page_address(req->rq_private_buf.pages[pnum - 1]) : | ||
1079 | page_address(rqstp->rq_pages[pnum]); | ||
1080 | vec[pnum].iov_len = PAGE_SIZE; | ||
1081 | pnum++; | ||
1082 | vlen += PAGE_SIZE; | ||
1083 | } | ||
1084 | rqstp->rq_respages = &rqstp->rq_pages[pnum]; | 1118 | rqstp->rq_respages = &rqstp->rq_pages[pnum]; |
1085 | 1119 | ||
1086 | /* Now receive data */ | 1120 | /* Now receive data */ |
1087 | len = svc_recvfrom(rqstp, vec, pnum, len); | 1121 | len = svc_partial_recvfrom(rqstp, vec, pnum, want, base); |
1088 | if (len < 0) | 1122 | if (len >= 0) |
1089 | goto err_again; | 1123 | svsk->sk_tcplen += len; |
1090 | 1124 | if (len != want) { | |
1091 | /* | 1125 | if (len < 0 && len != -EAGAIN) |
1092 | * Account for the 8 bytes we read earlier | 1126 | goto err_other; |
1093 | */ | 1127 | svc_tcp_save_pages(svsk, rqstp); |
1094 | len += 8; | 1128 | dprintk("svc: incomplete TCP record (%d of %d)\n", |
1095 | 1129 | svsk->sk_tcplen, svsk->sk_reclen); | |
1096 | if (req) { | 1130 | goto err_noclose; |
1097 | xprt_complete_rqst(req->rq_task, len); | ||
1098 | len = 0; | ||
1099 | goto out; | ||
1100 | } | 1131 | } |
1101 | dprintk("svc: TCP complete record (%d bytes)\n", len); | 1132 | |
1102 | rqstp->rq_arg.len = len; | 1133 | rqstp->rq_arg.len = svsk->sk_reclen; |
1103 | rqstp->rq_arg.page_base = 0; | 1134 | rqstp->rq_arg.page_base = 0; |
1104 | if (len <= rqstp->rq_arg.head[0].iov_len) { | 1135 | if (rqstp->rq_arg.len <= rqstp->rq_arg.head[0].iov_len) { |
1105 | rqstp->rq_arg.head[0].iov_len = len; | 1136 | rqstp->rq_arg.head[0].iov_len = rqstp->rq_arg.len; |
1106 | rqstp->rq_arg.page_len = 0; | 1137 | rqstp->rq_arg.page_len = 0; |
1107 | } else { | 1138 | } else |
1108 | rqstp->rq_arg.page_len = len - rqstp->rq_arg.head[0].iov_len; | 1139 | rqstp->rq_arg.page_len = rqstp->rq_arg.len - rqstp->rq_arg.head[0].iov_len; |
1109 | } | ||
1110 | 1140 | ||
1111 | rqstp->rq_xprt_ctxt = NULL; | 1141 | rqstp->rq_xprt_ctxt = NULL; |
1112 | rqstp->rq_prot = IPPROTO_TCP; | 1142 | rqstp->rq_prot = IPPROTO_TCP; |
1113 | 1143 | ||
1114 | out: | 1144 | p = (__be32 *)rqstp->rq_arg.head[0].iov_base; |
1145 | calldir = p[1]; | ||
1146 | if (calldir) | ||
1147 | len = receive_cb_reply(svsk, rqstp); | ||
1148 | |||
1115 | /* Reset TCP read info */ | 1149 | /* Reset TCP read info */ |
1116 | svsk->sk_reclen = 0; | 1150 | svsk->sk_reclen = 0; |
1117 | svsk->sk_tcplen = 0; | 1151 | svsk->sk_tcplen = 0; |
1152 | /* If we have more data, signal svc_xprt_enqueue() to try again */ | ||
1153 | if (svc_recv_available(svsk) > sizeof(rpc_fraghdr)) | ||
1154 | set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); | ||
1155 | |||
1156 | if (len < 0) | ||
1157 | goto error; | ||
1118 | 1158 | ||
1119 | svc_xprt_copy_addrs(rqstp, &svsk->sk_xprt); | 1159 | svc_xprt_copy_addrs(rqstp, &svsk->sk_xprt); |
1120 | if (serv->sv_stats) | 1160 | if (serv->sv_stats) |
1121 | serv->sv_stats->nettcpcnt++; | 1161 | serv->sv_stats->nettcpcnt++; |
1122 | 1162 | ||
1123 | return len; | 1163 | dprintk("svc: TCP complete record (%d bytes)\n", rqstp->rq_arg.len); |
1164 | return rqstp->rq_arg.len; | ||
1124 | 1165 | ||
1125 | err_again: | ||
1126 | if (len == -EAGAIN) { | ||
1127 | dprintk("RPC: TCP recvfrom got EAGAIN\n"); | ||
1128 | return len; | ||
1129 | } | ||
1130 | error: | 1166 | error: |
1131 | if (len != -EAGAIN) { | 1167 | if (len != -EAGAIN) |
1132 | printk(KERN_NOTICE "%s: recvfrom returned errno %d\n", | 1168 | goto err_other; |
1133 | svsk->sk_xprt.xpt_server->sv_name, -len); | 1169 | dprintk("RPC: TCP recvfrom got EAGAIN\n"); |
1134 | set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); | ||
1135 | } | ||
1136 | return -EAGAIN; | 1170 | return -EAGAIN; |
1171 | err_other: | ||
1172 | printk(KERN_NOTICE "%s: recvfrom returned errno %d\n", | ||
1173 | svsk->sk_xprt.xpt_server->sv_name, -len); | ||
1174 | set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); | ||
1175 | err_noclose: | ||
1176 | return -EAGAIN; /* record not complete */ | ||
1137 | } | 1177 | } |
1138 | 1178 | ||
1139 | /* | 1179 | /* |
@@ -1304,18 +1344,10 @@ static void svc_tcp_init(struct svc_sock *svsk, struct svc_serv *serv) | |||
1304 | 1344 | ||
1305 | svsk->sk_reclen = 0; | 1345 | svsk->sk_reclen = 0; |
1306 | svsk->sk_tcplen = 0; | 1346 | svsk->sk_tcplen = 0; |
1347 | memset(&svsk->sk_pages[0], 0, sizeof(svsk->sk_pages)); | ||
1307 | 1348 | ||
1308 | tcp_sk(sk)->nonagle |= TCP_NAGLE_OFF; | 1349 | tcp_sk(sk)->nonagle |= TCP_NAGLE_OFF; |
1309 | 1350 | ||
1310 | /* initialise setting must have enough space to | ||
1311 | * receive and respond to one request. | ||
1312 | * svc_tcp_recvfrom will re-adjust if necessary | ||
1313 | */ | ||
1314 | svc_sock_setbufsize(svsk->sk_sock, | ||
1315 | 3 * svsk->sk_xprt.xpt_server->sv_max_mesg, | ||
1316 | 3 * svsk->sk_xprt.xpt_server->sv_max_mesg); | ||
1317 | |||
1318 | set_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags); | ||
1319 | set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); | 1351 | set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); |
1320 | if (sk->sk_state != TCP_ESTABLISHED) | 1352 | if (sk->sk_state != TCP_ESTABLISHED) |
1321 | set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); | 1353 | set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); |
@@ -1379,8 +1411,14 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv, | |||
1379 | /* Initialize the socket */ | 1411 | /* Initialize the socket */ |
1380 | if (sock->type == SOCK_DGRAM) | 1412 | if (sock->type == SOCK_DGRAM) |
1381 | svc_udp_init(svsk, serv); | 1413 | svc_udp_init(svsk, serv); |
1382 | else | 1414 | else { |
1415 | /* initialise setting must have enough space to | ||
1416 | * receive and respond to one request. | ||
1417 | */ | ||
1418 | svc_sock_setbufsize(svsk->sk_sock, 4 * serv->sv_max_mesg, | ||
1419 | 4 * serv->sv_max_mesg); | ||
1383 | svc_tcp_init(svsk, serv); | 1420 | svc_tcp_init(svsk, serv); |
1421 | } | ||
1384 | 1422 | ||
1385 | dprintk("svc: svc_setup_socket created %p (inet %p)\n", | 1423 | dprintk("svc: svc_setup_socket created %p (inet %p)\n", |
1386 | svsk, svsk->sk_sk); | 1424 | svsk, svsk->sk_sk); |
@@ -1562,8 +1600,10 @@ static void svc_tcp_sock_detach(struct svc_xprt *xprt) | |||
1562 | 1600 | ||
1563 | svc_sock_detach(xprt); | 1601 | svc_sock_detach(xprt); |
1564 | 1602 | ||
1565 | if (!test_bit(XPT_LISTENER, &xprt->xpt_flags)) | 1603 | if (!test_bit(XPT_LISTENER, &xprt->xpt_flags)) { |
1604 | svc_tcp_clear_pages(svsk); | ||
1566 | kernel_sock_shutdown(svsk->sk_sock, SHUT_RDWR); | 1605 | kernel_sock_shutdown(svsk->sk_sock, SHUT_RDWR); |
1606 | } | ||
1567 | } | 1607 | } |
1568 | 1608 | ||
1569 | /* | 1609 | /* |
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index 679cd674b81d..f008c14ad34c 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c | |||
@@ -638,6 +638,25 @@ void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p) | |||
638 | } | 638 | } |
639 | EXPORT_SYMBOL_GPL(xdr_init_decode); | 639 | EXPORT_SYMBOL_GPL(xdr_init_decode); |
640 | 640 | ||
641 | /** | ||
642 | * xdr_init_decode - Initialize an xdr_stream for decoding data. | ||
643 | * @xdr: pointer to xdr_stream struct | ||
644 | * @buf: pointer to XDR buffer from which to decode data | ||
645 | * @pages: list of pages to decode into | ||
646 | * @len: length in bytes of buffer in pages | ||
647 | */ | ||
648 | void xdr_init_decode_pages(struct xdr_stream *xdr, struct xdr_buf *buf, | ||
649 | struct page **pages, unsigned int len) | ||
650 | { | ||
651 | memset(buf, 0, sizeof(*buf)); | ||
652 | buf->pages = pages; | ||
653 | buf->page_len = len; | ||
654 | buf->buflen = len; | ||
655 | buf->len = len; | ||
656 | xdr_init_decode(xdr, buf, NULL); | ||
657 | } | ||
658 | EXPORT_SYMBOL_GPL(xdr_init_decode_pages); | ||
659 | |||
641 | static __be32 * __xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes) | 660 | static __be32 * __xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes) |
642 | { | 661 | { |
643 | __be32 *p = xdr->p; | 662 | __be32 *p = xdr->p; |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index bf005d3c65ef..72abb7358933 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -19,6 +19,7 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/types.h> | 21 | #include <linux/types.h> |
22 | #include <linux/string.h> | ||
22 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
23 | #include <linux/module.h> | 24 | #include <linux/module.h> |
24 | #include <linux/capability.h> | 25 | #include <linux/capability.h> |
@@ -28,6 +29,7 @@ | |||
28 | #include <linux/in.h> | 29 | #include <linux/in.h> |
29 | #include <linux/net.h> | 30 | #include <linux/net.h> |
30 | #include <linux/mm.h> | 31 | #include <linux/mm.h> |
32 | #include <linux/un.h> | ||
31 | #include <linux/udp.h> | 33 | #include <linux/udp.h> |
32 | #include <linux/tcp.h> | 34 | #include <linux/tcp.h> |
33 | #include <linux/sunrpc/clnt.h> | 35 | #include <linux/sunrpc/clnt.h> |
@@ -45,6 +47,9 @@ | |||
45 | #include <net/tcp.h> | 47 | #include <net/tcp.h> |
46 | 48 | ||
47 | #include "sunrpc.h" | 49 | #include "sunrpc.h" |
50 | |||
51 | static void xs_close(struct rpc_xprt *xprt); | ||
52 | |||
48 | /* | 53 | /* |
49 | * xprtsock tunables | 54 | * xprtsock tunables |
50 | */ | 55 | */ |
@@ -261,6 +266,11 @@ static inline struct sockaddr *xs_addr(struct rpc_xprt *xprt) | |||
261 | return (struct sockaddr *) &xprt->addr; | 266 | return (struct sockaddr *) &xprt->addr; |
262 | } | 267 | } |
263 | 268 | ||
269 | static inline struct sockaddr_un *xs_addr_un(struct rpc_xprt *xprt) | ||
270 | { | ||
271 | return (struct sockaddr_un *) &xprt->addr; | ||
272 | } | ||
273 | |||
264 | static inline struct sockaddr_in *xs_addr_in(struct rpc_xprt *xprt) | 274 | static inline struct sockaddr_in *xs_addr_in(struct rpc_xprt *xprt) |
265 | { | 275 | { |
266 | return (struct sockaddr_in *) &xprt->addr; | 276 | return (struct sockaddr_in *) &xprt->addr; |
@@ -276,23 +286,34 @@ static void xs_format_common_peer_addresses(struct rpc_xprt *xprt) | |||
276 | struct sockaddr *sap = xs_addr(xprt); | 286 | struct sockaddr *sap = xs_addr(xprt); |
277 | struct sockaddr_in6 *sin6; | 287 | struct sockaddr_in6 *sin6; |
278 | struct sockaddr_in *sin; | 288 | struct sockaddr_in *sin; |
289 | struct sockaddr_un *sun; | ||
279 | char buf[128]; | 290 | char buf[128]; |
280 | 291 | ||
281 | (void)rpc_ntop(sap, buf, sizeof(buf)); | ||
282 | xprt->address_strings[RPC_DISPLAY_ADDR] = kstrdup(buf, GFP_KERNEL); | ||
283 | |||
284 | switch (sap->sa_family) { | 292 | switch (sap->sa_family) { |
293 | case AF_LOCAL: | ||
294 | sun = xs_addr_un(xprt); | ||
295 | strlcpy(buf, sun->sun_path, sizeof(buf)); | ||
296 | xprt->address_strings[RPC_DISPLAY_ADDR] = | ||
297 | kstrdup(buf, GFP_KERNEL); | ||
298 | break; | ||
285 | case AF_INET: | 299 | case AF_INET: |
300 | (void)rpc_ntop(sap, buf, sizeof(buf)); | ||
301 | xprt->address_strings[RPC_DISPLAY_ADDR] = | ||
302 | kstrdup(buf, GFP_KERNEL); | ||
286 | sin = xs_addr_in(xprt); | 303 | sin = xs_addr_in(xprt); |
287 | snprintf(buf, sizeof(buf), "%08x", ntohl(sin->sin_addr.s_addr)); | 304 | snprintf(buf, sizeof(buf), "%08x", ntohl(sin->sin_addr.s_addr)); |
288 | break; | 305 | break; |
289 | case AF_INET6: | 306 | case AF_INET6: |
307 | (void)rpc_ntop(sap, buf, sizeof(buf)); | ||
308 | xprt->address_strings[RPC_DISPLAY_ADDR] = | ||
309 | kstrdup(buf, GFP_KERNEL); | ||
290 | sin6 = xs_addr_in6(xprt); | 310 | sin6 = xs_addr_in6(xprt); |
291 | snprintf(buf, sizeof(buf), "%pi6", &sin6->sin6_addr); | 311 | snprintf(buf, sizeof(buf), "%pi6", &sin6->sin6_addr); |
292 | break; | 312 | break; |
293 | default: | 313 | default: |
294 | BUG(); | 314 | BUG(); |
295 | } | 315 | } |
316 | |||
296 | xprt->address_strings[RPC_DISPLAY_HEX_ADDR] = kstrdup(buf, GFP_KERNEL); | 317 | xprt->address_strings[RPC_DISPLAY_HEX_ADDR] = kstrdup(buf, GFP_KERNEL); |
297 | } | 318 | } |
298 | 319 | ||
@@ -495,6 +516,70 @@ static int xs_nospace(struct rpc_task *task) | |||
495 | return ret; | 516 | return ret; |
496 | } | 517 | } |
497 | 518 | ||
519 | /* | ||
520 | * Construct a stream transport record marker in @buf. | ||
521 | */ | ||
522 | static inline void xs_encode_stream_record_marker(struct xdr_buf *buf) | ||
523 | { | ||
524 | u32 reclen = buf->len - sizeof(rpc_fraghdr); | ||
525 | rpc_fraghdr *base = buf->head[0].iov_base; | ||
526 | *base = cpu_to_be32(RPC_LAST_STREAM_FRAGMENT | reclen); | ||
527 | } | ||
528 | |||
529 | /** | ||
530 | * xs_local_send_request - write an RPC request to an AF_LOCAL socket | ||
531 | * @task: RPC task that manages the state of an RPC request | ||
532 | * | ||
533 | * Return values: | ||
534 | * 0: The request has been sent | ||
535 | * EAGAIN: The socket was blocked, please call again later to | ||
536 | * complete the request | ||
537 | * ENOTCONN: Caller needs to invoke connect logic then call again | ||
538 | * other: Some other error occured, the request was not sent | ||
539 | */ | ||
540 | static int xs_local_send_request(struct rpc_task *task) | ||
541 | { | ||
542 | struct rpc_rqst *req = task->tk_rqstp; | ||
543 | struct rpc_xprt *xprt = req->rq_xprt; | ||
544 | struct sock_xprt *transport = | ||
545 | container_of(xprt, struct sock_xprt, xprt); | ||
546 | struct xdr_buf *xdr = &req->rq_snd_buf; | ||
547 | int status; | ||
548 | |||
549 | xs_encode_stream_record_marker(&req->rq_snd_buf); | ||
550 | |||
551 | xs_pktdump("packet data:", | ||
552 | req->rq_svec->iov_base, req->rq_svec->iov_len); | ||
553 | |||
554 | status = xs_sendpages(transport->sock, NULL, 0, | ||
555 | xdr, req->rq_bytes_sent); | ||
556 | dprintk("RPC: %s(%u) = %d\n", | ||
557 | __func__, xdr->len - req->rq_bytes_sent, status); | ||
558 | if (likely(status >= 0)) { | ||
559 | req->rq_bytes_sent += status; | ||
560 | req->rq_xmit_bytes_sent += status; | ||
561 | if (likely(req->rq_bytes_sent >= req->rq_slen)) { | ||
562 | req->rq_bytes_sent = 0; | ||
563 | return 0; | ||
564 | } | ||
565 | status = -EAGAIN; | ||
566 | } | ||
567 | |||
568 | switch (status) { | ||
569 | case -EAGAIN: | ||
570 | status = xs_nospace(task); | ||
571 | break; | ||
572 | default: | ||
573 | dprintk("RPC: sendmsg returned unrecognized error %d\n", | ||
574 | -status); | ||
575 | case -EPIPE: | ||
576 | xs_close(xprt); | ||
577 | status = -ENOTCONN; | ||
578 | } | ||
579 | |||
580 | return status; | ||
581 | } | ||
582 | |||
498 | /** | 583 | /** |
499 | * xs_udp_send_request - write an RPC request to a UDP socket | 584 | * xs_udp_send_request - write an RPC request to a UDP socket |
500 | * @task: address of RPC task that manages the state of an RPC request | 585 | * @task: address of RPC task that manages the state of an RPC request |
@@ -574,13 +659,6 @@ static void xs_tcp_shutdown(struct rpc_xprt *xprt) | |||
574 | kernel_sock_shutdown(sock, SHUT_WR); | 659 | kernel_sock_shutdown(sock, SHUT_WR); |
575 | } | 660 | } |
576 | 661 | ||
577 | static inline void xs_encode_tcp_record_marker(struct xdr_buf *buf) | ||
578 | { | ||
579 | u32 reclen = buf->len - sizeof(rpc_fraghdr); | ||
580 | rpc_fraghdr *base = buf->head[0].iov_base; | ||
581 | *base = htonl(RPC_LAST_STREAM_FRAGMENT | reclen); | ||
582 | } | ||
583 | |||
584 | /** | 662 | /** |
585 | * xs_tcp_send_request - write an RPC request to a TCP socket | 663 | * xs_tcp_send_request - write an RPC request to a TCP socket |
586 | * @task: address of RPC task that manages the state of an RPC request | 664 | * @task: address of RPC task that manages the state of an RPC request |
@@ -603,7 +681,7 @@ static int xs_tcp_send_request(struct rpc_task *task) | |||
603 | struct xdr_buf *xdr = &req->rq_snd_buf; | 681 | struct xdr_buf *xdr = &req->rq_snd_buf; |
604 | int status; | 682 | int status; |
605 | 683 | ||
606 | xs_encode_tcp_record_marker(&req->rq_snd_buf); | 684 | xs_encode_stream_record_marker(&req->rq_snd_buf); |
607 | 685 | ||
608 | xs_pktdump("packet data:", | 686 | xs_pktdump("packet data:", |
609 | req->rq_svec->iov_base, | 687 | req->rq_svec->iov_base, |
@@ -785,6 +863,88 @@ static inline struct rpc_xprt *xprt_from_sock(struct sock *sk) | |||
785 | return (struct rpc_xprt *) sk->sk_user_data; | 863 | return (struct rpc_xprt *) sk->sk_user_data; |
786 | } | 864 | } |
787 | 865 | ||
866 | static int xs_local_copy_to_xdr(struct xdr_buf *xdr, struct sk_buff *skb) | ||
867 | { | ||
868 | struct xdr_skb_reader desc = { | ||
869 | .skb = skb, | ||
870 | .offset = sizeof(rpc_fraghdr), | ||
871 | .count = skb->len - sizeof(rpc_fraghdr), | ||
872 | }; | ||
873 | |||
874 | if (xdr_partial_copy_from_skb(xdr, 0, &desc, xdr_skb_read_bits) < 0) | ||
875 | return -1; | ||
876 | if (desc.count) | ||
877 | return -1; | ||
878 | return 0; | ||
879 | } | ||
880 | |||
881 | /** | ||
882 | * xs_local_data_ready - "data ready" callback for AF_LOCAL sockets | ||
883 | * @sk: socket with data to read | ||
884 | * @len: how much data to read | ||
885 | * | ||
886 | * Currently this assumes we can read the whole reply in a single gulp. | ||
887 | */ | ||
888 | static void xs_local_data_ready(struct sock *sk, int len) | ||
889 | { | ||
890 | struct rpc_task *task; | ||
891 | struct rpc_xprt *xprt; | ||
892 | struct rpc_rqst *rovr; | ||
893 | struct sk_buff *skb; | ||
894 | int err, repsize, copied; | ||
895 | u32 _xid; | ||
896 | __be32 *xp; | ||
897 | |||
898 | read_lock_bh(&sk->sk_callback_lock); | ||
899 | dprintk("RPC: %s...\n", __func__); | ||
900 | xprt = xprt_from_sock(sk); | ||
901 | if (xprt == NULL) | ||
902 | goto out; | ||
903 | |||
904 | skb = skb_recv_datagram(sk, 0, 1, &err); | ||
905 | if (skb == NULL) | ||
906 | goto out; | ||
907 | |||
908 | if (xprt->shutdown) | ||
909 | goto dropit; | ||
910 | |||
911 | repsize = skb->len - sizeof(rpc_fraghdr); | ||
912 | if (repsize < 4) { | ||
913 | dprintk("RPC: impossible RPC reply size %d\n", repsize); | ||
914 | goto dropit; | ||
915 | } | ||
916 | |||
917 | /* Copy the XID from the skb... */ | ||
918 | xp = skb_header_pointer(skb, sizeof(rpc_fraghdr), sizeof(_xid), &_xid); | ||
919 | if (xp == NULL) | ||
920 | goto dropit; | ||
921 | |||
922 | /* Look up and lock the request corresponding to the given XID */ | ||
923 | spin_lock(&xprt->transport_lock); | ||
924 | rovr = xprt_lookup_rqst(xprt, *xp); | ||
925 | if (!rovr) | ||
926 | goto out_unlock; | ||
927 | task = rovr->rq_task; | ||
928 | |||
929 | copied = rovr->rq_private_buf.buflen; | ||
930 | if (copied > repsize) | ||
931 | copied = repsize; | ||
932 | |||
933 | if (xs_local_copy_to_xdr(&rovr->rq_private_buf, skb)) { | ||
934 | dprintk("RPC: sk_buff copy failed\n"); | ||
935 | goto out_unlock; | ||
936 | } | ||
937 | |||
938 | xprt_complete_rqst(task, copied); | ||
939 | |||
940 | out_unlock: | ||
941 | spin_unlock(&xprt->transport_lock); | ||
942 | dropit: | ||
943 | skb_free_datagram(sk, skb); | ||
944 | out: | ||
945 | read_unlock_bh(&sk->sk_callback_lock); | ||
946 | } | ||
947 | |||
788 | /** | 948 | /** |
789 | * xs_udp_data_ready - "data ready" callback for UDP sockets | 949 | * xs_udp_data_ready - "data ready" callback for UDP sockets |
790 | * @sk: socket with data to read | 950 | * @sk: socket with data to read |
@@ -1344,7 +1504,6 @@ static void xs_tcp_state_change(struct sock *sk) | |||
1344 | case TCP_CLOSE_WAIT: | 1504 | case TCP_CLOSE_WAIT: |
1345 | /* The server initiated a shutdown of the socket */ | 1505 | /* The server initiated a shutdown of the socket */ |
1346 | xprt_force_disconnect(xprt); | 1506 | xprt_force_disconnect(xprt); |
1347 | case TCP_SYN_SENT: | ||
1348 | xprt->connect_cookie++; | 1507 | xprt->connect_cookie++; |
1349 | case TCP_CLOSING: | 1508 | case TCP_CLOSING: |
1350 | /* | 1509 | /* |
@@ -1571,11 +1730,31 @@ static int xs_bind(struct sock_xprt *transport, struct socket *sock) | |||
1571 | return err; | 1730 | return err; |
1572 | } | 1731 | } |
1573 | 1732 | ||
1733 | /* | ||
1734 | * We don't support autobind on AF_LOCAL sockets | ||
1735 | */ | ||
1736 | static void xs_local_rpcbind(struct rpc_task *task) | ||
1737 | { | ||
1738 | xprt_set_bound(task->tk_xprt); | ||
1739 | } | ||
1740 | |||
1741 | static void xs_local_set_port(struct rpc_xprt *xprt, unsigned short port) | ||
1742 | { | ||
1743 | } | ||
1574 | 1744 | ||
1575 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 1745 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
1576 | static struct lock_class_key xs_key[2]; | 1746 | static struct lock_class_key xs_key[2]; |
1577 | static struct lock_class_key xs_slock_key[2]; | 1747 | static struct lock_class_key xs_slock_key[2]; |
1578 | 1748 | ||
1749 | static inline void xs_reclassify_socketu(struct socket *sock) | ||
1750 | { | ||
1751 | struct sock *sk = sock->sk; | ||
1752 | |||
1753 | BUG_ON(sock_owned_by_user(sk)); | ||
1754 | sock_lock_init_class_and_name(sk, "slock-AF_LOCAL-RPC", | ||
1755 | &xs_slock_key[1], "sk_lock-AF_LOCAL-RPC", &xs_key[1]); | ||
1756 | } | ||
1757 | |||
1579 | static inline void xs_reclassify_socket4(struct socket *sock) | 1758 | static inline void xs_reclassify_socket4(struct socket *sock) |
1580 | { | 1759 | { |
1581 | struct sock *sk = sock->sk; | 1760 | struct sock *sk = sock->sk; |
@@ -1597,6 +1776,9 @@ static inline void xs_reclassify_socket6(struct socket *sock) | |||
1597 | static inline void xs_reclassify_socket(int family, struct socket *sock) | 1776 | static inline void xs_reclassify_socket(int family, struct socket *sock) |
1598 | { | 1777 | { |
1599 | switch (family) { | 1778 | switch (family) { |
1779 | case AF_LOCAL: | ||
1780 | xs_reclassify_socketu(sock); | ||
1781 | break; | ||
1600 | case AF_INET: | 1782 | case AF_INET: |
1601 | xs_reclassify_socket4(sock); | 1783 | xs_reclassify_socket4(sock); |
1602 | break; | 1784 | break; |
@@ -1606,6 +1788,10 @@ static inline void xs_reclassify_socket(int family, struct socket *sock) | |||
1606 | } | 1788 | } |
1607 | } | 1789 | } |
1608 | #else | 1790 | #else |
1791 | static inline void xs_reclassify_socketu(struct socket *sock) | ||
1792 | { | ||
1793 | } | ||
1794 | |||
1609 | static inline void xs_reclassify_socket4(struct socket *sock) | 1795 | static inline void xs_reclassify_socket4(struct socket *sock) |
1610 | { | 1796 | { |
1611 | } | 1797 | } |
@@ -1644,6 +1830,94 @@ out: | |||
1644 | return ERR_PTR(err); | 1830 | return ERR_PTR(err); |
1645 | } | 1831 | } |
1646 | 1832 | ||
1833 | static int xs_local_finish_connecting(struct rpc_xprt *xprt, | ||
1834 | struct socket *sock) | ||
1835 | { | ||
1836 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, | ||
1837 | xprt); | ||
1838 | |||
1839 | if (!transport->inet) { | ||
1840 | struct sock *sk = sock->sk; | ||
1841 | |||
1842 | write_lock_bh(&sk->sk_callback_lock); | ||
1843 | |||
1844 | xs_save_old_callbacks(transport, sk); | ||
1845 | |||
1846 | sk->sk_user_data = xprt; | ||
1847 | sk->sk_data_ready = xs_local_data_ready; | ||
1848 | sk->sk_write_space = xs_udp_write_space; | ||
1849 | sk->sk_error_report = xs_error_report; | ||
1850 | sk->sk_allocation = GFP_ATOMIC; | ||
1851 | |||
1852 | xprt_clear_connected(xprt); | ||
1853 | |||
1854 | /* Reset to new socket */ | ||
1855 | transport->sock = sock; | ||
1856 | transport->inet = sk; | ||
1857 | |||
1858 | write_unlock_bh(&sk->sk_callback_lock); | ||
1859 | } | ||
1860 | |||
1861 | /* Tell the socket layer to start connecting... */ | ||
1862 | xprt->stat.connect_count++; | ||
1863 | xprt->stat.connect_start = jiffies; | ||
1864 | return kernel_connect(sock, xs_addr(xprt), xprt->addrlen, 0); | ||
1865 | } | ||
1866 | |||
1867 | /** | ||
1868 | * xs_local_setup_socket - create AF_LOCAL socket, connect to a local endpoint | ||
1869 | * @xprt: RPC transport to connect | ||
1870 | * @transport: socket transport to connect | ||
1871 | * @create_sock: function to create a socket of the correct type | ||
1872 | * | ||
1873 | * Invoked by a work queue tasklet. | ||
1874 | */ | ||
1875 | static void xs_local_setup_socket(struct work_struct *work) | ||
1876 | { | ||
1877 | struct sock_xprt *transport = | ||
1878 | container_of(work, struct sock_xprt, connect_worker.work); | ||
1879 | struct rpc_xprt *xprt = &transport->xprt; | ||
1880 | struct socket *sock; | ||
1881 | int status = -EIO; | ||
1882 | |||
1883 | if (xprt->shutdown) | ||
1884 | goto out; | ||
1885 | |||
1886 | clear_bit(XPRT_CONNECTION_ABORT, &xprt->state); | ||
1887 | status = __sock_create(xprt->xprt_net, AF_LOCAL, | ||
1888 | SOCK_STREAM, 0, &sock, 1); | ||
1889 | if (status < 0) { | ||
1890 | dprintk("RPC: can't create AF_LOCAL " | ||
1891 | "transport socket (%d).\n", -status); | ||
1892 | goto out; | ||
1893 | } | ||
1894 | xs_reclassify_socketu(sock); | ||
1895 | |||
1896 | dprintk("RPC: worker connecting xprt %p via AF_LOCAL to %s\n", | ||
1897 | xprt, xprt->address_strings[RPC_DISPLAY_ADDR]); | ||
1898 | |||
1899 | status = xs_local_finish_connecting(xprt, sock); | ||
1900 | switch (status) { | ||
1901 | case 0: | ||
1902 | dprintk("RPC: xprt %p connected to %s\n", | ||
1903 | xprt, xprt->address_strings[RPC_DISPLAY_ADDR]); | ||
1904 | xprt_set_connected(xprt); | ||
1905 | break; | ||
1906 | case -ENOENT: | ||
1907 | dprintk("RPC: xprt %p: socket %s does not exist\n", | ||
1908 | xprt, xprt->address_strings[RPC_DISPLAY_ADDR]); | ||
1909 | break; | ||
1910 | default: | ||
1911 | printk(KERN_ERR "%s: unhandled error (%d) connecting to %s\n", | ||
1912 | __func__, -status, | ||
1913 | xprt->address_strings[RPC_DISPLAY_ADDR]); | ||
1914 | } | ||
1915 | |||
1916 | out: | ||
1917 | xprt_clear_connecting(xprt); | ||
1918 | xprt_wake_pending_tasks(xprt, status); | ||
1919 | } | ||
1920 | |||
1647 | static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) | 1921 | static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) |
1648 | { | 1922 | { |
1649 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); | 1923 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); |
@@ -1758,6 +2032,7 @@ static void xs_tcp_reuse_connection(struct sock_xprt *transport) | |||
1758 | static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) | 2032 | static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) |
1759 | { | 2033 | { |
1760 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); | 2034 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); |
2035 | int ret = -ENOTCONN; | ||
1761 | 2036 | ||
1762 | if (!transport->inet) { | 2037 | if (!transport->inet) { |
1763 | struct sock *sk = sock->sk; | 2038 | struct sock *sk = sock->sk; |
@@ -1789,12 +2064,22 @@ static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) | |||
1789 | } | 2064 | } |
1790 | 2065 | ||
1791 | if (!xprt_bound(xprt)) | 2066 | if (!xprt_bound(xprt)) |
1792 | return -ENOTCONN; | 2067 | goto out; |
1793 | 2068 | ||
1794 | /* Tell the socket layer to start connecting... */ | 2069 | /* Tell the socket layer to start connecting... */ |
1795 | xprt->stat.connect_count++; | 2070 | xprt->stat.connect_count++; |
1796 | xprt->stat.connect_start = jiffies; | 2071 | xprt->stat.connect_start = jiffies; |
1797 | return kernel_connect(sock, xs_addr(xprt), xprt->addrlen, O_NONBLOCK); | 2072 | ret = kernel_connect(sock, xs_addr(xprt), xprt->addrlen, O_NONBLOCK); |
2073 | switch (ret) { | ||
2074 | case 0: | ||
2075 | case -EINPROGRESS: | ||
2076 | /* SYN_SENT! */ | ||
2077 | xprt->connect_cookie++; | ||
2078 | if (xprt->reestablish_timeout < XS_TCP_INIT_REEST_TO) | ||
2079 | xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; | ||
2080 | } | ||
2081 | out: | ||
2082 | return ret; | ||
1798 | } | 2083 | } |
1799 | 2084 | ||
1800 | /** | 2085 | /** |
@@ -1917,6 +2202,32 @@ static void xs_connect(struct rpc_task *task) | |||
1917 | } | 2202 | } |
1918 | 2203 | ||
1919 | /** | 2204 | /** |
2205 | * xs_local_print_stats - display AF_LOCAL socket-specifc stats | ||
2206 | * @xprt: rpc_xprt struct containing statistics | ||
2207 | * @seq: output file | ||
2208 | * | ||
2209 | */ | ||
2210 | static void xs_local_print_stats(struct rpc_xprt *xprt, struct seq_file *seq) | ||
2211 | { | ||
2212 | long idle_time = 0; | ||
2213 | |||
2214 | if (xprt_connected(xprt)) | ||
2215 | idle_time = (long)(jiffies - xprt->last_used) / HZ; | ||
2216 | |||
2217 | seq_printf(seq, "\txprt:\tlocal %lu %lu %lu %ld %lu %lu %lu " | ||
2218 | "%llu %llu\n", | ||
2219 | xprt->stat.bind_count, | ||
2220 | xprt->stat.connect_count, | ||
2221 | xprt->stat.connect_time, | ||
2222 | idle_time, | ||
2223 | xprt->stat.sends, | ||
2224 | xprt->stat.recvs, | ||
2225 | xprt->stat.bad_xids, | ||
2226 | xprt->stat.req_u, | ||
2227 | xprt->stat.bklog_u); | ||
2228 | } | ||
2229 | |||
2230 | /** | ||
1920 | * xs_udp_print_stats - display UDP socket-specifc stats | 2231 | * xs_udp_print_stats - display UDP socket-specifc stats |
1921 | * @xprt: rpc_xprt struct containing statistics | 2232 | * @xprt: rpc_xprt struct containing statistics |
1922 | * @seq: output file | 2233 | * @seq: output file |
@@ -2014,10 +2325,7 @@ static int bc_sendto(struct rpc_rqst *req) | |||
2014 | unsigned long headoff; | 2325 | unsigned long headoff; |
2015 | unsigned long tailoff; | 2326 | unsigned long tailoff; |
2016 | 2327 | ||
2017 | /* | 2328 | xs_encode_stream_record_marker(xbufp); |
2018 | * Set up the rpc header and record marker stuff | ||
2019 | */ | ||
2020 | xs_encode_tcp_record_marker(xbufp); | ||
2021 | 2329 | ||
2022 | tailoff = (unsigned long)xbufp->tail[0].iov_base & ~PAGE_MASK; | 2330 | tailoff = (unsigned long)xbufp->tail[0].iov_base & ~PAGE_MASK; |
2023 | headoff = (unsigned long)xbufp->head[0].iov_base & ~PAGE_MASK; | 2331 | headoff = (unsigned long)xbufp->head[0].iov_base & ~PAGE_MASK; |
@@ -2089,6 +2397,21 @@ static void bc_destroy(struct rpc_xprt *xprt) | |||
2089 | { | 2397 | { |
2090 | } | 2398 | } |
2091 | 2399 | ||
2400 | static struct rpc_xprt_ops xs_local_ops = { | ||
2401 | .reserve_xprt = xprt_reserve_xprt, | ||
2402 | .release_xprt = xs_tcp_release_xprt, | ||
2403 | .rpcbind = xs_local_rpcbind, | ||
2404 | .set_port = xs_local_set_port, | ||
2405 | .connect = xs_connect, | ||
2406 | .buf_alloc = rpc_malloc, | ||
2407 | .buf_free = rpc_free, | ||
2408 | .send_request = xs_local_send_request, | ||
2409 | .set_retrans_timeout = xprt_set_retrans_timeout_def, | ||
2410 | .close = xs_close, | ||
2411 | .destroy = xs_destroy, | ||
2412 | .print_stats = xs_local_print_stats, | ||
2413 | }; | ||
2414 | |||
2092 | static struct rpc_xprt_ops xs_udp_ops = { | 2415 | static struct rpc_xprt_ops xs_udp_ops = { |
2093 | .set_buffer_size = xs_udp_set_buffer_size, | 2416 | .set_buffer_size = xs_udp_set_buffer_size, |
2094 | .reserve_xprt = xprt_reserve_xprt_cong, | 2417 | .reserve_xprt = xprt_reserve_xprt_cong, |
@@ -2150,6 +2473,8 @@ static int xs_init_anyaddr(const int family, struct sockaddr *sap) | |||
2150 | }; | 2473 | }; |
2151 | 2474 | ||
2152 | switch (family) { | 2475 | switch (family) { |
2476 | case AF_LOCAL: | ||
2477 | break; | ||
2153 | case AF_INET: | 2478 | case AF_INET: |
2154 | memcpy(sap, &sin, sizeof(sin)); | 2479 | memcpy(sap, &sin, sizeof(sin)); |
2155 | break; | 2480 | break; |
@@ -2197,6 +2522,70 @@ static struct rpc_xprt *xs_setup_xprt(struct xprt_create *args, | |||
2197 | return xprt; | 2522 | return xprt; |
2198 | } | 2523 | } |
2199 | 2524 | ||
2525 | static const struct rpc_timeout xs_local_default_timeout = { | ||
2526 | .to_initval = 10 * HZ, | ||
2527 | .to_maxval = 10 * HZ, | ||
2528 | .to_retries = 2, | ||
2529 | }; | ||
2530 | |||
2531 | /** | ||
2532 | * xs_setup_local - Set up transport to use an AF_LOCAL socket | ||
2533 | * @args: rpc transport creation arguments | ||
2534 | * | ||
2535 | * AF_LOCAL is a "tpi_cots_ord" transport, just like TCP | ||
2536 | */ | ||
2537 | static struct rpc_xprt *xs_setup_local(struct xprt_create *args) | ||
2538 | { | ||
2539 | struct sockaddr_un *sun = (struct sockaddr_un *)args->dstaddr; | ||
2540 | struct sock_xprt *transport; | ||
2541 | struct rpc_xprt *xprt; | ||
2542 | struct rpc_xprt *ret; | ||
2543 | |||
2544 | xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries); | ||
2545 | if (IS_ERR(xprt)) | ||
2546 | return xprt; | ||
2547 | transport = container_of(xprt, struct sock_xprt, xprt); | ||
2548 | |||
2549 | xprt->prot = 0; | ||
2550 | xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32); | ||
2551 | xprt->max_payload = RPC_MAX_FRAGMENT_SIZE; | ||
2552 | |||
2553 | xprt->bind_timeout = XS_BIND_TO; | ||
2554 | xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; | ||
2555 | xprt->idle_timeout = XS_IDLE_DISC_TO; | ||
2556 | |||
2557 | xprt->ops = &xs_local_ops; | ||
2558 | xprt->timeout = &xs_local_default_timeout; | ||
2559 | |||
2560 | switch (sun->sun_family) { | ||
2561 | case AF_LOCAL: | ||
2562 | if (sun->sun_path[0] != '/') { | ||
2563 | dprintk("RPC: bad AF_LOCAL address: %s\n", | ||
2564 | sun->sun_path); | ||
2565 | ret = ERR_PTR(-EINVAL); | ||
2566 | goto out_err; | ||
2567 | } | ||
2568 | xprt_set_bound(xprt); | ||
2569 | INIT_DELAYED_WORK(&transport->connect_worker, | ||
2570 | xs_local_setup_socket); | ||
2571 | xs_format_peer_addresses(xprt, "local", RPCBIND_NETID_LOCAL); | ||
2572 | break; | ||
2573 | default: | ||
2574 | ret = ERR_PTR(-EAFNOSUPPORT); | ||
2575 | goto out_err; | ||
2576 | } | ||
2577 | |||
2578 | dprintk("RPC: set up xprt to %s via AF_LOCAL\n", | ||
2579 | xprt->address_strings[RPC_DISPLAY_ADDR]); | ||
2580 | |||
2581 | if (try_module_get(THIS_MODULE)) | ||
2582 | return xprt; | ||
2583 | ret = ERR_PTR(-EINVAL); | ||
2584 | out_err: | ||
2585 | xprt_free(xprt); | ||
2586 | return ret; | ||
2587 | } | ||
2588 | |||
2200 | static const struct rpc_timeout xs_udp_default_timeout = { | 2589 | static const struct rpc_timeout xs_udp_default_timeout = { |
2201 | .to_initval = 5 * HZ, | 2590 | .to_initval = 5 * HZ, |
2202 | .to_maxval = 30 * HZ, | 2591 | .to_maxval = 30 * HZ, |
@@ -2438,6 +2827,14 @@ out_err: | |||
2438 | return ret; | 2827 | return ret; |
2439 | } | 2828 | } |
2440 | 2829 | ||
2830 | static struct xprt_class xs_local_transport = { | ||
2831 | .list = LIST_HEAD_INIT(xs_local_transport.list), | ||
2832 | .name = "named UNIX socket", | ||
2833 | .owner = THIS_MODULE, | ||
2834 | .ident = XPRT_TRANSPORT_LOCAL, | ||
2835 | .setup = xs_setup_local, | ||
2836 | }; | ||
2837 | |||
2441 | static struct xprt_class xs_udp_transport = { | 2838 | static struct xprt_class xs_udp_transport = { |
2442 | .list = LIST_HEAD_INIT(xs_udp_transport.list), | 2839 | .list = LIST_HEAD_INIT(xs_udp_transport.list), |
2443 | .name = "udp", | 2840 | .name = "udp", |
@@ -2473,6 +2870,7 @@ int init_socket_xprt(void) | |||
2473 | sunrpc_table_header = register_sysctl_table(sunrpc_table); | 2870 | sunrpc_table_header = register_sysctl_table(sunrpc_table); |
2474 | #endif | 2871 | #endif |
2475 | 2872 | ||
2873 | xprt_register_transport(&xs_local_transport); | ||
2476 | xprt_register_transport(&xs_udp_transport); | 2874 | xprt_register_transport(&xs_udp_transport); |
2477 | xprt_register_transport(&xs_tcp_transport); | 2875 | xprt_register_transport(&xs_tcp_transport); |
2478 | xprt_register_transport(&xs_bc_tcp_transport); | 2876 | xprt_register_transport(&xs_bc_tcp_transport); |
@@ -2493,6 +2891,7 @@ void cleanup_socket_xprt(void) | |||
2493 | } | 2891 | } |
2494 | #endif | 2892 | #endif |
2495 | 2893 | ||
2894 | xprt_unregister_transport(&xs_local_transport); | ||
2496 | xprt_unregister_transport(&xs_udp_transport); | 2895 | xprt_unregister_transport(&xs_udp_transport); |
2497 | xprt_unregister_transport(&xs_tcp_transport); | 2896 | xprt_unregister_transport(&xs_tcp_transport); |
2498 | xprt_unregister_transport(&xs_bc_tcp_transport); | 2897 | xprt_unregister_transport(&xs_bc_tcp_transport); |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index ec83f413a7ed..88a565f130a5 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -3406,12 +3406,12 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) | |||
3406 | i = 0; | 3406 | i = 0; |
3407 | if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) { | 3407 | if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) { |
3408 | nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) { | 3408 | nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) { |
3409 | request->ssids[i].ssid_len = nla_len(attr); | ||
3409 | if (request->ssids[i].ssid_len > IEEE80211_MAX_SSID_LEN) { | 3410 | if (request->ssids[i].ssid_len > IEEE80211_MAX_SSID_LEN) { |
3410 | err = -EINVAL; | 3411 | err = -EINVAL; |
3411 | goto out_free; | 3412 | goto out_free; |
3412 | } | 3413 | } |
3413 | memcpy(request->ssids[i].ssid, nla_data(attr), nla_len(attr)); | 3414 | memcpy(request->ssids[i].ssid, nla_data(attr), nla_len(attr)); |
3414 | request->ssids[i].ssid_len = nla_len(attr); | ||
3415 | i++; | 3415 | i++; |
3416 | } | 3416 | } |
3417 | } | 3417 | } |
@@ -3572,6 +3572,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, | |||
3572 | if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) { | 3572 | if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) { |
3573 | nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], | 3573 | nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], |
3574 | tmp) { | 3574 | tmp) { |
3575 | request->ssids[i].ssid_len = nla_len(attr); | ||
3575 | if (request->ssids[i].ssid_len > | 3576 | if (request->ssids[i].ssid_len > |
3576 | IEEE80211_MAX_SSID_LEN) { | 3577 | IEEE80211_MAX_SSID_LEN) { |
3577 | err = -EINVAL; | 3578 | err = -EINVAL; |
@@ -3579,7 +3580,6 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, | |||
3579 | } | 3580 | } |
3580 | memcpy(request->ssids[i].ssid, nla_data(attr), | 3581 | memcpy(request->ssids[i].ssid, nla_data(attr), |
3581 | nla_len(attr)); | 3582 | nla_len(attr)); |
3582 | request->ssids[i].ssid_len = nla_len(attr); | ||
3583 | i++; | 3583 | i++; |
3584 | } | 3584 | } |
3585 | } | 3585 | } |
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 73a441d237b5..7a6c67667d70 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -267,13 +267,35 @@ static bool is_bss(struct cfg80211_bss *a, | |||
267 | return memcmp(ssidie + 2, ssid, ssid_len) == 0; | 267 | return memcmp(ssidie + 2, ssid, ssid_len) == 0; |
268 | } | 268 | } |
269 | 269 | ||
270 | static bool is_mesh_bss(struct cfg80211_bss *a) | ||
271 | { | ||
272 | const u8 *ie; | ||
273 | |||
274 | if (!WLAN_CAPABILITY_IS_STA_BSS(a->capability)) | ||
275 | return false; | ||
276 | |||
277 | ie = cfg80211_find_ie(WLAN_EID_MESH_ID, | ||
278 | a->information_elements, | ||
279 | a->len_information_elements); | ||
280 | if (!ie) | ||
281 | return false; | ||
282 | |||
283 | ie = cfg80211_find_ie(WLAN_EID_MESH_CONFIG, | ||
284 | a->information_elements, | ||
285 | a->len_information_elements); | ||
286 | if (!ie) | ||
287 | return false; | ||
288 | |||
289 | return true; | ||
290 | } | ||
291 | |||
270 | static bool is_mesh(struct cfg80211_bss *a, | 292 | static bool is_mesh(struct cfg80211_bss *a, |
271 | const u8 *meshid, size_t meshidlen, | 293 | const u8 *meshid, size_t meshidlen, |
272 | const u8 *meshcfg) | 294 | const u8 *meshcfg) |
273 | { | 295 | { |
274 | const u8 *ie; | 296 | const u8 *ie; |
275 | 297 | ||
276 | if (!WLAN_CAPABILITY_IS_MBSS(a->capability)) | 298 | if (!WLAN_CAPABILITY_IS_STA_BSS(a->capability)) |
277 | return false; | 299 | return false; |
278 | 300 | ||
279 | ie = cfg80211_find_ie(WLAN_EID_MESH_ID, | 301 | ie = cfg80211_find_ie(WLAN_EID_MESH_ID, |
@@ -311,7 +333,7 @@ static int cmp_bss(struct cfg80211_bss *a, | |||
311 | if (a->channel != b->channel) | 333 | if (a->channel != b->channel) |
312 | return b->channel->center_freq - a->channel->center_freq; | 334 | return b->channel->center_freq - a->channel->center_freq; |
313 | 335 | ||
314 | if (WLAN_CAPABILITY_IS_MBSS(a->capability | b->capability)) { | 336 | if (is_mesh_bss(a) && is_mesh_bss(b)) { |
315 | r = cmp_ies(WLAN_EID_MESH_ID, | 337 | r = cmp_ies(WLAN_EID_MESH_ID, |
316 | a->information_elements, | 338 | a->information_elements, |
317 | a->len_information_elements, | 339 | a->len_information_elements, |
@@ -457,7 +479,6 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev, | |||
457 | struct cfg80211_internal_bss *res) | 479 | struct cfg80211_internal_bss *res) |
458 | { | 480 | { |
459 | struct cfg80211_internal_bss *found = NULL; | 481 | struct cfg80211_internal_bss *found = NULL; |
460 | const u8 *meshid, *meshcfg; | ||
461 | 482 | ||
462 | /* | 483 | /* |
463 | * The reference to "res" is donated to this function. | 484 | * The reference to "res" is donated to this function. |
@@ -470,22 +491,6 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev, | |||
470 | 491 | ||
471 | res->ts = jiffies; | 492 | res->ts = jiffies; |
472 | 493 | ||
473 | if (WLAN_CAPABILITY_IS_MBSS(res->pub.capability)) { | ||
474 | /* must be mesh, verify */ | ||
475 | meshid = cfg80211_find_ie(WLAN_EID_MESH_ID, | ||
476 | res->pub.information_elements, | ||
477 | res->pub.len_information_elements); | ||
478 | meshcfg = cfg80211_find_ie(WLAN_EID_MESH_CONFIG, | ||
479 | res->pub.information_elements, | ||
480 | res->pub.len_information_elements); | ||
481 | if (!meshid || !meshcfg || | ||
482 | meshcfg[1] != sizeof(struct ieee80211_meshconf_ie)) { | ||
483 | /* bogus mesh */ | ||
484 | kref_put(&res->ref, bss_release); | ||
485 | return NULL; | ||
486 | } | ||
487 | } | ||
488 | |||
489 | spin_lock_bh(&dev->bss_lock); | 494 | spin_lock_bh(&dev->bss_lock); |
490 | 495 | ||
491 | found = rb_find_bss(dev, res); | 496 | found = rb_find_bss(dev, res); |
diff --git a/scripts/recordmcount.h b/scripts/recordmcount.h index 4be60364a405..f40a6af6bf40 100644 --- a/scripts/recordmcount.h +++ b/scripts/recordmcount.h | |||
@@ -43,6 +43,7 @@ | |||
43 | #undef ELF_R_INFO | 43 | #undef ELF_R_INFO |
44 | #undef Elf_r_info | 44 | #undef Elf_r_info |
45 | #undef ELF_ST_BIND | 45 | #undef ELF_ST_BIND |
46 | #undef ELF_ST_TYPE | ||
46 | #undef fn_ELF_R_SYM | 47 | #undef fn_ELF_R_SYM |
47 | #undef fn_ELF_R_INFO | 48 | #undef fn_ELF_R_INFO |
48 | #undef uint_t | 49 | #undef uint_t |
@@ -76,6 +77,7 @@ | |||
76 | # define ELF_R_INFO ELF64_R_INFO | 77 | # define ELF_R_INFO ELF64_R_INFO |
77 | # define Elf_r_info Elf64_r_info | 78 | # define Elf_r_info Elf64_r_info |
78 | # define ELF_ST_BIND ELF64_ST_BIND | 79 | # define ELF_ST_BIND ELF64_ST_BIND |
80 | # define ELF_ST_TYPE ELF64_ST_TYPE | ||
79 | # define fn_ELF_R_SYM fn_ELF64_R_SYM | 81 | # define fn_ELF_R_SYM fn_ELF64_R_SYM |
80 | # define fn_ELF_R_INFO fn_ELF64_R_INFO | 82 | # define fn_ELF_R_INFO fn_ELF64_R_INFO |
81 | # define uint_t uint64_t | 83 | # define uint_t uint64_t |
@@ -108,6 +110,7 @@ | |||
108 | # define ELF_R_INFO ELF32_R_INFO | 110 | # define ELF_R_INFO ELF32_R_INFO |
109 | # define Elf_r_info Elf32_r_info | 111 | # define Elf_r_info Elf32_r_info |
110 | # define ELF_ST_BIND ELF32_ST_BIND | 112 | # define ELF_ST_BIND ELF32_ST_BIND |
113 | # define ELF_ST_TYPE ELF32_ST_TYPE | ||
111 | # define fn_ELF_R_SYM fn_ELF32_R_SYM | 114 | # define fn_ELF_R_SYM fn_ELF32_R_SYM |
112 | # define fn_ELF_R_INFO fn_ELF32_R_INFO | 115 | # define fn_ELF_R_INFO fn_ELF32_R_INFO |
113 | # define uint_t uint32_t | 116 | # define uint_t uint32_t |
@@ -427,6 +430,11 @@ static unsigned find_secsym_ndx(unsigned const txtndx, | |||
427 | if (txtndx == w2(symp->st_shndx) | 430 | if (txtndx == w2(symp->st_shndx) |
428 | /* avoid STB_WEAK */ | 431 | /* avoid STB_WEAK */ |
429 | && (STB_LOCAL == st_bind || STB_GLOBAL == st_bind)) { | 432 | && (STB_LOCAL == st_bind || STB_GLOBAL == st_bind)) { |
433 | /* function symbols on ARM have quirks, avoid them */ | ||
434 | if (w2(ehdr->e_machine) == EM_ARM | ||
435 | && ELF_ST_TYPE(symp->st_info) == STT_FUNC) | ||
436 | continue; | ||
437 | |||
430 | *recvalp = _w(symp->st_value); | 438 | *recvalp = _w(symp->st_value); |
431 | return symp - sym0; | 439 | return symp - sym0; |
432 | } | 440 | } |
diff --git a/scripts/tags.sh b/scripts/tags.sh index bd6185d529cf..75c5d24f1993 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh | |||
@@ -132,7 +132,7 @@ exuberant() | |||
132 | --regex-asm='/^ENTRY\(([^)]*)\).*/\1/' \ | 132 | --regex-asm='/^ENTRY\(([^)]*)\).*/\1/' \ |
133 | --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' \ | 133 | --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' \ |
134 | --regex-c++='/^TRACE_EVENT\(([^,)]*).*/trace_\1/' \ | 134 | --regex-c++='/^TRACE_EVENT\(([^,)]*).*/trace_\1/' \ |
135 | --regex-c++='/^DEFINE_EVENT\(([^,)]*).*/trace_\1/' | 135 | --regex-c++='/^DEFINE_EVENT\([^,)]*, *([^,)]*).*/trace_\1/' |
136 | 136 | ||
137 | all_kconfigs | xargs $1 -a \ | 137 | all_kconfigs | xargs $1 -a \ |
138 | --langdef=kconfig --language-force=kconfig \ | 138 | --langdef=kconfig --language-force=kconfig \ |
@@ -152,7 +152,9 @@ emacs() | |||
152 | { | 152 | { |
153 | all_sources | xargs $1 -a \ | 153 | all_sources | xargs $1 -a \ |
154 | --regex='/^ENTRY(\([^)]*\)).*/\1/' \ | 154 | --regex='/^ENTRY(\([^)]*\)).*/\1/' \ |
155 | --regex='/^SYSCALL_DEFINE[0-9]?(\([^,)]*\).*/sys_\1/' | 155 | --regex='/^SYSCALL_DEFINE[0-9]?(\([^,)]*\).*/sys_\1/' \ |
156 | --regex='/^TRACE_EVENT(\([^,)]*\).*/trace_\1/' \ | ||
157 | --regex='/^DEFINE_EVENT([^,)]*, *\([^,)]*\).*/trace_\1/' | ||
156 | 158 | ||
157 | all_kconfigs | xargs $1 -a \ | 159 | all_kconfigs | xargs $1 -a \ |
158 | --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/\3/' | 160 | --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/\3/' |
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index ae3a698415e6..ec1bcecf2cda 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c | |||
@@ -593,7 +593,8 @@ static int apparmor_setprocattr(struct task_struct *task, char *name, | |||
593 | sa.aad.op = OP_SETPROCATTR; | 593 | sa.aad.op = OP_SETPROCATTR; |
594 | sa.aad.info = name; | 594 | sa.aad.info = name; |
595 | sa.aad.error = -EINVAL; | 595 | sa.aad.error = -EINVAL; |
596 | return aa_audit(AUDIT_APPARMOR_DENIED, NULL, GFP_KERNEL, | 596 | return aa_audit(AUDIT_APPARMOR_DENIED, |
597 | __aa_current_profile(), GFP_KERNEL, | ||
597 | &sa, NULL); | 598 | &sa, NULL); |
598 | } | 599 | } |
599 | } else if (strcmp(name, "exec") == 0) { | 600 | } else if (strcmp(name, "exec") == 0) { |
diff --git a/sound/pci/asihpi/hpidspcd.c b/sound/pci/asihpi/hpidspcd.c index fb311d8c05bf..5c6ea113d219 100644 --- a/sound/pci/asihpi/hpidspcd.c +++ b/sound/pci/asihpi/hpidspcd.c | |||
@@ -60,7 +60,7 @@ struct code_header { | |||
60 | HPI_VER_MINOR(HPI_VER) * 100 + HPI_VER_RELEASE(HPI_VER))) | 60 | HPI_VER_MINOR(HPI_VER) * 100 + HPI_VER_RELEASE(HPI_VER))) |
61 | 61 | ||
62 | /***********************************************************************/ | 62 | /***********************************************************************/ |
63 | #include "linux/pci.h" | 63 | #include <linux/pci.h> |
64 | /*-------------------------------------------------------------------*/ | 64 | /*-------------------------------------------------------------------*/ |
65 | short hpi_dsp_code_open(u32 adapter, struct dsp_code *ps_dsp_code, | 65 | short hpi_dsp_code_open(u32 adapter, struct dsp_code *ps_dsp_code, |
66 | u32 *pos_error_code) | 66 | u32 *pos_error_code) |
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index eacd4901a308..a7ec7030cf87 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c | |||
@@ -1234,9 +1234,12 @@ static int __devinit snd_fm801_create(struct snd_card *card, | |||
1234 | sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci)); | 1234 | sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci)); |
1235 | if ((tea575x_tuner & TUNER_TYPE_MASK) > 0 && | 1235 | if ((tea575x_tuner & TUNER_TYPE_MASK) > 0 && |
1236 | (tea575x_tuner & TUNER_TYPE_MASK) < 4) { | 1236 | (tea575x_tuner & TUNER_TYPE_MASK) < 4) { |
1237 | if (snd_tea575x_init(&chip->tea)) | 1237 | if (snd_tea575x_init(&chip->tea)) { |
1238 | snd_printk(KERN_ERR "TEA575x radio not found\n"); | 1238 | snd_printk(KERN_ERR "TEA575x radio not found\n"); |
1239 | } else if ((tea575x_tuner & TUNER_TYPE_MASK) == 0) | 1239 | snd_fm801_free(chip); |
1240 | return -ENODEV; | ||
1241 | } | ||
1242 | } else if ((tea575x_tuner & TUNER_TYPE_MASK) == 0) { | ||
1240 | /* autodetect tuner connection */ | 1243 | /* autodetect tuner connection */ |
1241 | for (tea575x_tuner = 1; tea575x_tuner <= 3; tea575x_tuner++) { | 1244 | for (tea575x_tuner = 1; tea575x_tuner <= 3; tea575x_tuner++) { |
1242 | chip->tea575x_tuner = tea575x_tuner; | 1245 | chip->tea575x_tuner = tea575x_tuner; |
@@ -1246,6 +1249,12 @@ static int __devinit snd_fm801_create(struct snd_card *card, | |||
1246 | break; | 1249 | break; |
1247 | } | 1250 | } |
1248 | } | 1251 | } |
1252 | if (tea575x_tuner == 4) { | ||
1253 | snd_printk(KERN_ERR "TEA575x radio not found\n"); | ||
1254 | snd_fm801_free(chip); | ||
1255 | return -ENODEV; | ||
1256 | } | ||
1257 | } | ||
1249 | strlcpy(chip->tea.card, snd_fm801_tea575x_gpios[(tea575x_tuner & TUNER_TYPE_MASK) - 1].name, sizeof(chip->tea.card)); | 1258 | strlcpy(chip->tea.card, snd_fm801_tea575x_gpios[(tea575x_tuner & TUNER_TYPE_MASK) - 1].name, sizeof(chip->tea.card)); |
1250 | #endif | 1259 | #endif |
1251 | 1260 | ||
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 696ac2590307..d694e9d4921d 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -506,9 +506,11 @@ static void ad198x_power_eapd_write(struct hda_codec *codec, hda_nid_t front, | |||
506 | hda_nid_t hp) | 506 | hda_nid_t hp) |
507 | { | 507 | { |
508 | struct ad198x_spec *spec = codec->spec; | 508 | struct ad198x_spec *spec = codec->spec; |
509 | snd_hda_codec_write(codec, front, 0, AC_VERB_SET_EAPD_BTLENABLE, | 509 | if (snd_hda_query_pin_caps(codec, front) & AC_PINCAP_EAPD) |
510 | snd_hda_codec_write(codec, front, 0, AC_VERB_SET_EAPD_BTLENABLE, | ||
510 | !spec->inv_eapd ? 0x00 : 0x02); | 511 | !spec->inv_eapd ? 0x00 : 0x02); |
511 | snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_EAPD_BTLENABLE, | 512 | if (snd_hda_query_pin_caps(codec, hp) & AC_PINCAP_EAPD) |
513 | snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_EAPD_BTLENABLE, | ||
512 | !spec->inv_eapd ? 0x00 : 0x02); | 514 | !spec->inv_eapd ? 0x00 : 0x02); |
513 | } | 515 | } |
514 | 516 | ||
@@ -524,6 +526,10 @@ static void ad198x_power_eapd(struct hda_codec *codec) | |||
524 | case 0x11d4184a: | 526 | case 0x11d4184a: |
525 | case 0x11d4194a: | 527 | case 0x11d4194a: |
526 | case 0x11d4194b: | 528 | case 0x11d4194b: |
529 | case 0x11d41988: | ||
530 | case 0x11d4198b: | ||
531 | case 0x11d4989a: | ||
532 | case 0x11d4989b: | ||
527 | ad198x_power_eapd_write(codec, 0x12, 0x11); | 533 | ad198x_power_eapd_write(codec, 0x12, 0x11); |
528 | break; | 534 | break; |
529 | case 0x11d41981: | 535 | case 0x11d41981: |
@@ -533,12 +539,6 @@ static void ad198x_power_eapd(struct hda_codec *codec) | |||
533 | case 0x11d41986: | 539 | case 0x11d41986: |
534 | ad198x_power_eapd_write(codec, 0x1b, 0x1a); | 540 | ad198x_power_eapd_write(codec, 0x1b, 0x1a); |
535 | break; | 541 | break; |
536 | case 0x11d41988: | ||
537 | case 0x11d4198b: | ||
538 | case 0x11d4989a: | ||
539 | case 0x11d4989b: | ||
540 | ad198x_power_eapd_write(codec, 0x29, 0x22); | ||
541 | break; | ||
542 | } | 542 | } |
543 | } | 543 | } |
544 | 544 | ||
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c index f8c663dcff02..d68ea532cc7f 100644 --- a/sound/soc/codecs/cx20442.c +++ b/sound/soc/codecs/cx20442.c | |||
@@ -262,14 +262,14 @@ static int v253_hangup(struct tty_struct *tty) | |||
262 | } | 262 | } |
263 | 263 | ||
264 | /* Line discipline .receive_buf() */ | 264 | /* Line discipline .receive_buf() */ |
265 | static unsigned int v253_receive(struct tty_struct *tty, | 265 | static void v253_receive(struct tty_struct *tty, |
266 | const unsigned char *cp, char *fp, int count) | 266 | const unsigned char *cp, char *fp, int count) |
267 | { | 267 | { |
268 | struct snd_soc_codec *codec = tty->disc_data; | 268 | struct snd_soc_codec *codec = tty->disc_data; |
269 | struct cx20442_priv *cx20442; | 269 | struct cx20442_priv *cx20442; |
270 | 270 | ||
271 | if (!codec) | 271 | if (!codec) |
272 | return count; | 272 | return; |
273 | 273 | ||
274 | cx20442 = snd_soc_codec_get_drvdata(codec); | 274 | cx20442 = snd_soc_codec_get_drvdata(codec); |
275 | 275 | ||
@@ -281,8 +281,6 @@ static unsigned int v253_receive(struct tty_struct *tty, | |||
281 | codec->hw_write = (hw_write_t)tty->ops->write; | 281 | codec->hw_write = (hw_write_t)tty->ops->write; |
282 | codec->card->pop_time = 1; | 282 | codec->card->pop_time = 1; |
283 | } | 283 | } |
284 | |||
285 | return count; | ||
286 | } | 284 | } |
287 | 285 | ||
288 | /* Line discipline .write_wakeup() */ | 286 | /* Line discipline .write_wakeup() */ |
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index e55b298c14a0..9e370d14ad88 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c | |||
@@ -215,23 +215,23 @@ static const struct snd_kcontrol_new analogue_snd_controls[] = { | |||
215 | SOC_SINGLE_TLV("IN1L Volume", WM8993_LEFT_LINE_INPUT_1_2_VOLUME, 0, 31, 0, | 215 | SOC_SINGLE_TLV("IN1L Volume", WM8993_LEFT_LINE_INPUT_1_2_VOLUME, 0, 31, 0, |
216 | inpga_tlv), | 216 | inpga_tlv), |
217 | SOC_SINGLE("IN1L Switch", WM8993_LEFT_LINE_INPUT_1_2_VOLUME, 7, 1, 1), | 217 | SOC_SINGLE("IN1L Switch", WM8993_LEFT_LINE_INPUT_1_2_VOLUME, 7, 1, 1), |
218 | SOC_SINGLE("IN1L ZC Switch", WM8993_LEFT_LINE_INPUT_1_2_VOLUME, 7, 1, 0), | 218 | SOC_SINGLE("IN1L ZC Switch", WM8993_LEFT_LINE_INPUT_1_2_VOLUME, 6, 1, 0), |
219 | 219 | ||
220 | SOC_SINGLE_TLV("IN1R Volume", WM8993_RIGHT_LINE_INPUT_1_2_VOLUME, 0, 31, 0, | 220 | SOC_SINGLE_TLV("IN1R Volume", WM8993_RIGHT_LINE_INPUT_1_2_VOLUME, 0, 31, 0, |
221 | inpga_tlv), | 221 | inpga_tlv), |
222 | SOC_SINGLE("IN1R Switch", WM8993_RIGHT_LINE_INPUT_1_2_VOLUME, 7, 1, 1), | 222 | SOC_SINGLE("IN1R Switch", WM8993_RIGHT_LINE_INPUT_1_2_VOLUME, 7, 1, 1), |
223 | SOC_SINGLE("IN1R ZC Switch", WM8993_RIGHT_LINE_INPUT_1_2_VOLUME, 7, 1, 0), | 223 | SOC_SINGLE("IN1R ZC Switch", WM8993_RIGHT_LINE_INPUT_1_2_VOLUME, 6, 1, 0), |
224 | 224 | ||
225 | 225 | ||
226 | SOC_SINGLE_TLV("IN2L Volume", WM8993_LEFT_LINE_INPUT_3_4_VOLUME, 0, 31, 0, | 226 | SOC_SINGLE_TLV("IN2L Volume", WM8993_LEFT_LINE_INPUT_3_4_VOLUME, 0, 31, 0, |
227 | inpga_tlv), | 227 | inpga_tlv), |
228 | SOC_SINGLE("IN2L Switch", WM8993_LEFT_LINE_INPUT_3_4_VOLUME, 7, 1, 1), | 228 | SOC_SINGLE("IN2L Switch", WM8993_LEFT_LINE_INPUT_3_4_VOLUME, 7, 1, 1), |
229 | SOC_SINGLE("IN2L ZC Switch", WM8993_LEFT_LINE_INPUT_3_4_VOLUME, 7, 1, 0), | 229 | SOC_SINGLE("IN2L ZC Switch", WM8993_LEFT_LINE_INPUT_3_4_VOLUME, 6, 1, 0), |
230 | 230 | ||
231 | SOC_SINGLE_TLV("IN2R Volume", WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, 0, 31, 0, | 231 | SOC_SINGLE_TLV("IN2R Volume", WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, 0, 31, 0, |
232 | inpga_tlv), | 232 | inpga_tlv), |
233 | SOC_SINGLE("IN2R Switch", WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, 7, 1, 1), | 233 | SOC_SINGLE("IN2R Switch", WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, 7, 1, 1), |
234 | SOC_SINGLE("IN2R ZC Switch", WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, 7, 1, 0), | 234 | SOC_SINGLE("IN2R ZC Switch", WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, 6, 1, 0), |
235 | 235 | ||
236 | SOC_SINGLE_TLV("MIXINL IN2L Volume", WM8993_INPUT_MIXER3, 7, 1, 0, | 236 | SOC_SINGLE_TLV("MIXINL IN2L Volume", WM8993_INPUT_MIXER3, 7, 1, 0, |
237 | inmix_sw_tlv), | 237 | inmix_sw_tlv), |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 999bb08cdfb1..776e6f418306 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -325,6 +325,7 @@ static int dapm_connect_mixer(struct snd_soc_dapm_context *dapm, | |||
325 | } | 325 | } |
326 | 326 | ||
327 | static int dapm_is_shared_kcontrol(struct snd_soc_dapm_context *dapm, | 327 | static int dapm_is_shared_kcontrol(struct snd_soc_dapm_context *dapm, |
328 | struct snd_soc_dapm_widget *kcontrolw, | ||
328 | const struct snd_kcontrol_new *kcontrol_new, | 329 | const struct snd_kcontrol_new *kcontrol_new, |
329 | struct snd_kcontrol **kcontrol) | 330 | struct snd_kcontrol **kcontrol) |
330 | { | 331 | { |
@@ -334,6 +335,8 @@ static int dapm_is_shared_kcontrol(struct snd_soc_dapm_context *dapm, | |||
334 | *kcontrol = NULL; | 335 | *kcontrol = NULL; |
335 | 336 | ||
336 | list_for_each_entry(w, &dapm->card->widgets, list) { | 337 | list_for_each_entry(w, &dapm->card->widgets, list) { |
338 | if (w == kcontrolw || w->dapm != kcontrolw->dapm) | ||
339 | continue; | ||
337 | for (i = 0; i < w->num_kcontrols; i++) { | 340 | for (i = 0; i < w->num_kcontrols; i++) { |
338 | if (&w->kcontrol_news[i] == kcontrol_new) { | 341 | if (&w->kcontrol_news[i] == kcontrol_new) { |
339 | if (w->kcontrols) | 342 | if (w->kcontrols) |
@@ -468,7 +471,7 @@ static int dapm_new_mux(struct snd_soc_dapm_context *dapm, | |||
468 | return -EINVAL; | 471 | return -EINVAL; |
469 | } | 472 | } |
470 | 473 | ||
471 | shared = dapm_is_shared_kcontrol(dapm, &w->kcontrol_news[0], | 474 | shared = dapm_is_shared_kcontrol(dapm, w, &w->kcontrol_news[0], |
472 | &kcontrol); | 475 | &kcontrol); |
473 | if (kcontrol) { | 476 | if (kcontrol) { |
474 | wlist = kcontrol->private_data; | 477 | wlist = kcontrol->private_data; |
diff --git a/sound/usb/6fire/firmware.c b/sound/usb/6fire/firmware.c index d47beffedb0f..a91719d5918b 100644 --- a/sound/usb/6fire/firmware.c +++ b/sound/usb/6fire/firmware.c | |||
@@ -227,6 +227,7 @@ static int usb6fire_fw_ezusb_upload( | |||
227 | ret = usb6fire_fw_ihex_init(fw, rec); | 227 | ret = usb6fire_fw_ihex_init(fw, rec); |
228 | if (ret < 0) { | 228 | if (ret < 0) { |
229 | kfree(rec); | 229 | kfree(rec); |
230 | release_firmware(fw); | ||
230 | snd_printk(KERN_ERR PREFIX "error validating ezusb " | 231 | snd_printk(KERN_ERR PREFIX "error validating ezusb " |
231 | "firmware %s.\n", fwname); | 232 | "firmware %s.\n", fwname); |
232 | return ret; | 233 | return ret; |
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 2e969cbb393b..090e1930dfdc 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c | |||
@@ -403,7 +403,7 @@ static int snd_usb_cm106_boot_quirk(struct usb_device *dev) | |||
403 | static int snd_usb_cm6206_boot_quirk(struct usb_device *dev) | 403 | static int snd_usb_cm6206_boot_quirk(struct usb_device *dev) |
404 | { | 404 | { |
405 | int err, reg; | 405 | int err, reg; |
406 | int val[] = {0x200c, 0x3000, 0xf800, 0x143f, 0x0000, 0x3000}; | 406 | int val[] = {0x2004, 0x3000, 0xf800, 0x143f, 0x0000, 0x3000}; |
407 | 407 | ||
408 | for (reg = 0; reg < ARRAY_SIZE(val); reg++) { | 408 | for (reg = 0; reg < ARRAY_SIZE(val); reg++) { |
409 | err = snd_usb_cm106_write_int_reg(dev, reg, val[reg]); | 409 | err = snd_usb_cm106_write_int_reg(dev, reg, val[reg]); |
diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 1455413ec7a7..032ba6398a5c 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile | |||
@@ -215,11 +215,13 @@ LIB_FILE=$(OUTPUT)libperf.a | |||
215 | LIB_H += ../../include/linux/perf_event.h | 215 | LIB_H += ../../include/linux/perf_event.h |
216 | LIB_H += ../../include/linux/rbtree.h | 216 | LIB_H += ../../include/linux/rbtree.h |
217 | LIB_H += ../../include/linux/list.h | 217 | LIB_H += ../../include/linux/list.h |
218 | LIB_H += ../../include/linux/const.h | ||
218 | LIB_H += ../../include/linux/hash.h | 219 | LIB_H += ../../include/linux/hash.h |
219 | LIB_H += ../../include/linux/stringify.h | 220 | LIB_H += ../../include/linux/stringify.h |
220 | LIB_H += util/include/linux/bitmap.h | 221 | LIB_H += util/include/linux/bitmap.h |
221 | LIB_H += util/include/linux/bitops.h | 222 | LIB_H += util/include/linux/bitops.h |
222 | LIB_H += util/include/linux/compiler.h | 223 | LIB_H += util/include/linux/compiler.h |
224 | LIB_H += util/include/linux/const.h | ||
223 | LIB_H += util/include/linux/ctype.h | 225 | LIB_H += util/include/linux/ctype.h |
224 | LIB_H += util/include/linux/kernel.h | 226 | LIB_H += util/include/linux/kernel.h |
225 | LIB_H += util/include/linux/list.h | 227 | LIB_H += util/include/linux/list.h |
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index e18eb7ed30ae..7b139e1e7e86 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c | |||
@@ -8,8 +8,6 @@ | |||
8 | #include "builtin.h" | 8 | #include "builtin.h" |
9 | 9 | ||
10 | #include "util/util.h" | 10 | #include "util/util.h" |
11 | |||
12 | #include "util/util.h" | ||
13 | #include "util/color.h" | 11 | #include "util/color.h" |
14 | #include <linux/list.h> | 12 | #include <linux/list.h> |
15 | #include "util/cache.h" | 13 | #include "util/cache.h" |
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 0974f957b8fa..8e2c85798185 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
@@ -823,6 +823,16 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) | |||
823 | 823 | ||
824 | symbol__init(); | 824 | symbol__init(); |
825 | 825 | ||
826 | if (symbol_conf.kptr_restrict) | ||
827 | pr_warning( | ||
828 | "WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n" | ||
829 | "check /proc/sys/kernel/kptr_restrict.\n\n" | ||
830 | "Samples in kernel functions may not be resolved if a suitable vmlinux\n" | ||
831 | "file is not found in the buildid cache or in the vmlinux path.\n\n" | ||
832 | "Samples in kernel modules won't be resolved at all.\n\n" | ||
833 | "If some relocation was applied (e.g. kexec) symbols may be misresolved\n" | ||
834 | "even with a suitable vmlinux or kallsyms file.\n\n"); | ||
835 | |||
826 | if (no_buildid_cache || no_buildid) | 836 | if (no_buildid_cache || no_buildid) |
827 | disable_buildid_cache(); | 837 | disable_buildid_cache(); |
828 | 838 | ||
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 498c6f70a747..287a173523a7 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
@@ -116,6 +116,9 @@ static int process_sample_event(union perf_event *event, | |||
116 | if (al.filtered || (hide_unresolved && al.sym == NULL)) | 116 | if (al.filtered || (hide_unresolved && al.sym == NULL)) |
117 | return 0; | 117 | return 0; |
118 | 118 | ||
119 | if (al.map != NULL) | ||
120 | al.map->dso->hit = 1; | ||
121 | |||
119 | if (perf_session__add_hist_entry(session, &al, sample, evsel)) { | 122 | if (perf_session__add_hist_entry(session, &al, sample, evsel)) { |
120 | pr_debug("problem incrementing symbol period, skipping event\n"); | 123 | pr_debug("problem incrementing symbol period, skipping event\n"); |
121 | return -1; | 124 | return -1; |
@@ -249,6 +252,8 @@ static int __cmd_report(void) | |||
249 | u64 nr_samples; | 252 | u64 nr_samples; |
250 | struct perf_session *session; | 253 | struct perf_session *session; |
251 | struct perf_evsel *pos; | 254 | struct perf_evsel *pos; |
255 | struct map *kernel_map; | ||
256 | struct kmap *kernel_kmap; | ||
252 | const char *help = "For a higher level overview, try: perf report --sort comm,dso"; | 257 | const char *help = "For a higher level overview, try: perf report --sort comm,dso"; |
253 | 258 | ||
254 | signal(SIGINT, sig_handler); | 259 | signal(SIGINT, sig_handler); |
@@ -268,6 +273,24 @@ static int __cmd_report(void) | |||
268 | if (ret) | 273 | if (ret) |
269 | goto out_delete; | 274 | goto out_delete; |
270 | 275 | ||
276 | kernel_map = session->host_machine.vmlinux_maps[MAP__FUNCTION]; | ||
277 | kernel_kmap = map__kmap(kernel_map); | ||
278 | if (kernel_map == NULL || | ||
279 | (kernel_map->dso->hit && | ||
280 | (kernel_kmap->ref_reloc_sym == NULL || | ||
281 | kernel_kmap->ref_reloc_sym->addr == 0))) { | ||
282 | const struct dso *kdso = kernel_map->dso; | ||
283 | |||
284 | ui__warning( | ||
285 | "Kernel address maps (/proc/{kallsyms,modules}) were restricted.\n\n" | ||
286 | "Check /proc/sys/kernel/kptr_restrict before running 'perf record'.\n\n%s\n\n" | ||
287 | "Samples in kernel modules can't be resolved as well.\n\n", | ||
288 | RB_EMPTY_ROOT(&kdso->symbols[MAP__FUNCTION]) ? | ||
289 | "As no suitable kallsyms nor vmlinux was found, kernel samples\n" | ||
290 | "can't be resolved." : | ||
291 | "If some relocation was applied (e.g. kexec) symbols may be misresolved."); | ||
292 | } | ||
293 | |||
271 | if (dump_trace) { | 294 | if (dump_trace) { |
272 | perf_session__fprintf_nr_events(session, stdout); | 295 | perf_session__fprintf_nr_events(session, stdout); |
273 | goto out_delete; | 296 | goto out_delete; |
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 974f6d3f4e53..22747de7234b 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c | |||
@@ -10,7 +10,6 @@ | |||
10 | #include "util/symbol.h" | 10 | #include "util/symbol.h" |
11 | #include "util/thread.h" | 11 | #include "util/thread.h" |
12 | #include "util/trace-event.h" | 12 | #include "util/trace-event.h" |
13 | #include "util/parse-options.h" | ||
14 | #include "util/util.h" | 13 | #include "util/util.h" |
15 | #include "util/evlist.h" | 14 | #include "util/evlist.h" |
16 | #include "util/evsel.h" | 15 | #include "util/evsel.h" |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 2d7934e9de38..f2f3f4937aa2 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -62,8 +62,6 @@ | |||
62 | #include <linux/unistd.h> | 62 | #include <linux/unistd.h> |
63 | #include <linux/types.h> | 63 | #include <linux/types.h> |
64 | 64 | ||
65 | #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) | ||
66 | |||
67 | static struct perf_top top = { | 65 | static struct perf_top top = { |
68 | .count_filter = 5, | 66 | .count_filter = 5, |
69 | .delay_secs = 2, | 67 | .delay_secs = 2, |
@@ -82,6 +80,8 @@ static bool use_tui, use_stdio; | |||
82 | 80 | ||
83 | static int default_interval = 0; | 81 | static int default_interval = 0; |
84 | 82 | ||
83 | static bool kptr_restrict_warned; | ||
84 | static bool vmlinux_warned; | ||
85 | static bool inherit = false; | 85 | static bool inherit = false; |
86 | static int realtime_prio = 0; | 86 | static int realtime_prio = 0; |
87 | static bool group = false; | 87 | static bool group = false; |
@@ -740,7 +740,22 @@ static void perf_event__process_sample(const union perf_event *event, | |||
740 | al.filtered) | 740 | al.filtered) |
741 | return; | 741 | return; |
742 | 742 | ||
743 | if (!kptr_restrict_warned && | ||
744 | symbol_conf.kptr_restrict && | ||
745 | al.cpumode == PERF_RECORD_MISC_KERNEL) { | ||
746 | ui__warning( | ||
747 | "Kernel address maps (/proc/{kallsyms,modules}) are restricted.\n\n" | ||
748 | "Check /proc/sys/kernel/kptr_restrict.\n\n" | ||
749 | "Kernel%s samples will not be resolved.\n", | ||
750 | !RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION]) ? | ||
751 | " modules" : ""); | ||
752 | if (use_browser <= 0) | ||
753 | sleep(5); | ||
754 | kptr_restrict_warned = true; | ||
755 | } | ||
756 | |||
743 | if (al.sym == NULL) { | 757 | if (al.sym == NULL) { |
758 | const char *msg = "Kernel samples will not be resolved.\n"; | ||
744 | /* | 759 | /* |
745 | * As we do lazy loading of symtabs we only will know if the | 760 | * As we do lazy loading of symtabs we only will know if the |
746 | * specified vmlinux file is invalid when we actually have a | 761 | * specified vmlinux file is invalid when we actually have a |
@@ -752,12 +767,20 @@ static void perf_event__process_sample(const union perf_event *event, | |||
752 | * --hide-kernel-symbols, even if the user specifies an | 767 | * --hide-kernel-symbols, even if the user specifies an |
753 | * invalid --vmlinux ;-) | 768 | * invalid --vmlinux ;-) |
754 | */ | 769 | */ |
755 | if (al.map == machine->vmlinux_maps[MAP__FUNCTION] && | 770 | if (!kptr_restrict_warned && !vmlinux_warned && |
771 | al.map == machine->vmlinux_maps[MAP__FUNCTION] && | ||
756 | RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION])) { | 772 | RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION])) { |
757 | ui__warning("The %s file can't be used\n", | 773 | if (symbol_conf.vmlinux_name) { |
758 | symbol_conf.vmlinux_name); | 774 | ui__warning("The %s file can't be used.\n%s", |
759 | exit_browser(0); | 775 | symbol_conf.vmlinux_name, msg); |
760 | exit(1); | 776 | } else { |
777 | ui__warning("A vmlinux file was not found.\n%s", | ||
778 | msg); | ||
779 | } | ||
780 | |||
781 | if (use_browser <= 0) | ||
782 | sleep(5); | ||
783 | vmlinux_warned = true; | ||
761 | } | 784 | } |
762 | 785 | ||
763 | return; | 786 | return; |
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 6635fcd11ca5..0fe9adf76379 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c | |||
@@ -553,9 +553,18 @@ static int perf_event__process_kernel_mmap(union perf_event *event, | |||
553 | goto out_problem; | 553 | goto out_problem; |
554 | 554 | ||
555 | perf_event__set_kernel_mmap_len(event, machine->vmlinux_maps); | 555 | perf_event__set_kernel_mmap_len(event, machine->vmlinux_maps); |
556 | perf_session__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, | 556 | |
557 | symbol_name, | 557 | /* |
558 | event->mmap.pgoff); | 558 | * Avoid using a zero address (kptr_restrict) for the ref reloc |
559 | * symbol. Effectively having zero here means that at record | ||
560 | * time /proc/sys/kernel/kptr_restrict was non zero. | ||
561 | */ | ||
562 | if (event->mmap.pgoff != 0) { | ||
563 | perf_session__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, | ||
564 | symbol_name, | ||
565 | event->mmap.pgoff); | ||
566 | } | ||
567 | |||
559 | if (machine__is_default_guest(machine)) { | 568 | if (machine__is_default_guest(machine)) { |
560 | /* | 569 | /* |
561 | * preload dso of guest kernel and modules | 570 | * preload dso of guest kernel and modules |
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index ee0fe0dffa71..cca29ededb5b 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -35,7 +35,17 @@ struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx) | |||
35 | 35 | ||
36 | int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads) | 36 | int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads) |
37 | { | 37 | { |
38 | int cpu, thread; | ||
38 | evsel->fd = xyarray__new(ncpus, nthreads, sizeof(int)); | 39 | evsel->fd = xyarray__new(ncpus, nthreads, sizeof(int)); |
40 | |||
41 | if (evsel->fd) { | ||
42 | for (cpu = 0; cpu < ncpus; cpu++) { | ||
43 | for (thread = 0; thread < nthreads; thread++) { | ||
44 | FD(evsel, cpu, thread) = -1; | ||
45 | } | ||
46 | } | ||
47 | } | ||
48 | |||
39 | return evsel->fd != NULL ? 0 : -ENOMEM; | 49 | return evsel->fd != NULL ? 0 : -ENOMEM; |
40 | } | 50 | } |
41 | 51 | ||
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 0717bebc7649..afb0849fe530 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
@@ -193,9 +193,13 @@ int build_id_cache__add_s(const char *sbuild_id, const char *debugdir, | |||
193 | *linkname = malloc(size), *targetname; | 193 | *linkname = malloc(size), *targetname; |
194 | int len, err = -1; | 194 | int len, err = -1; |
195 | 195 | ||
196 | if (is_kallsyms) | 196 | if (is_kallsyms) { |
197 | if (symbol_conf.kptr_restrict) { | ||
198 | pr_debug("Not caching a kptr_restrict'ed /proc/kallsyms\n"); | ||
199 | return 0; | ||
200 | } | ||
197 | realname = (char *)name; | 201 | realname = (char *)name; |
198 | else | 202 | } else |
199 | realname = realpath(name, NULL); | 203 | realname = realpath(name, NULL); |
200 | 204 | ||
201 | if (realname == NULL || filename == NULL || linkname == NULL) | 205 | if (realname == NULL || filename == NULL || linkname == NULL) |
diff --git a/tools/perf/util/include/linux/const.h b/tools/perf/util/include/linux/const.h new file mode 100644 index 000000000000..1b476c9ae649 --- /dev/null +++ b/tools/perf/util/include/linux/const.h | |||
@@ -0,0 +1 @@ | |||
#include "../../../../include/linux/const.h" | |||
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 516876dfbe52..eec196329fd9 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -676,9 +676,30 @@ discard_symbol: rb_erase(&pos->rb_node, root); | |||
676 | return count + moved; | 676 | return count + moved; |
677 | } | 677 | } |
678 | 678 | ||
679 | static bool symbol__restricted_filename(const char *filename, | ||
680 | const char *restricted_filename) | ||
681 | { | ||
682 | bool restricted = false; | ||
683 | |||
684 | if (symbol_conf.kptr_restrict) { | ||
685 | char *r = realpath(filename, NULL); | ||
686 | |||
687 | if (r != NULL) { | ||
688 | restricted = strcmp(r, restricted_filename) == 0; | ||
689 | free(r); | ||
690 | return restricted; | ||
691 | } | ||
692 | } | ||
693 | |||
694 | return restricted; | ||
695 | } | ||
696 | |||
679 | int dso__load_kallsyms(struct dso *dso, const char *filename, | 697 | int dso__load_kallsyms(struct dso *dso, const char *filename, |
680 | struct map *map, symbol_filter_t filter) | 698 | struct map *map, symbol_filter_t filter) |
681 | { | 699 | { |
700 | if (symbol__restricted_filename(filename, "/proc/kallsyms")) | ||
701 | return -1; | ||
702 | |||
682 | if (dso__load_all_kallsyms(dso, filename, map) < 0) | 703 | if (dso__load_all_kallsyms(dso, filename, map) < 0) |
683 | return -1; | 704 | return -1; |
684 | 705 | ||
@@ -1790,6 +1811,9 @@ static int machine__create_modules(struct machine *machine) | |||
1790 | modules = path; | 1811 | modules = path; |
1791 | } | 1812 | } |
1792 | 1813 | ||
1814 | if (symbol__restricted_filename(path, "/proc/modules")) | ||
1815 | return -1; | ||
1816 | |||
1793 | file = fopen(modules, "r"); | 1817 | file = fopen(modules, "r"); |
1794 | if (file == NULL) | 1818 | if (file == NULL) |
1795 | return -1; | 1819 | return -1; |
@@ -2239,6 +2263,9 @@ static u64 machine__get_kernel_start_addr(struct machine *machine) | |||
2239 | } | 2263 | } |
2240 | } | 2264 | } |
2241 | 2265 | ||
2266 | if (symbol__restricted_filename(filename, "/proc/kallsyms")) | ||
2267 | return 0; | ||
2268 | |||
2242 | if (kallsyms__parse(filename, &args, symbol__in_kernel) <= 0) | 2269 | if (kallsyms__parse(filename, &args, symbol__in_kernel) <= 0) |
2243 | return 0; | 2270 | return 0; |
2244 | 2271 | ||
@@ -2410,6 +2437,25 @@ static int setup_list(struct strlist **list, const char *list_str, | |||
2410 | return 0; | 2437 | return 0; |
2411 | } | 2438 | } |
2412 | 2439 | ||
2440 | static bool symbol__read_kptr_restrict(void) | ||
2441 | { | ||
2442 | bool value = false; | ||
2443 | |||
2444 | if (geteuid() != 0) { | ||
2445 | FILE *fp = fopen("/proc/sys/kernel/kptr_restrict", "r"); | ||
2446 | if (fp != NULL) { | ||
2447 | char line[8]; | ||
2448 | |||
2449 | if (fgets(line, sizeof(line), fp) != NULL) | ||
2450 | value = atoi(line) != 0; | ||
2451 | |||
2452 | fclose(fp); | ||
2453 | } | ||
2454 | } | ||
2455 | |||
2456 | return value; | ||
2457 | } | ||
2458 | |||
2413 | int symbol__init(void) | 2459 | int symbol__init(void) |
2414 | { | 2460 | { |
2415 | const char *symfs; | 2461 | const char *symfs; |
@@ -2456,6 +2502,8 @@ int symbol__init(void) | |||
2456 | if (symfs != symbol_conf.symfs) | 2502 | if (symfs != symbol_conf.symfs) |
2457 | free((void *)symfs); | 2503 | free((void *)symfs); |
2458 | 2504 | ||
2505 | symbol_conf.kptr_restrict = symbol__read_kptr_restrict(); | ||
2506 | |||
2459 | symbol_conf.initialized = true; | 2507 | symbol_conf.initialized = true; |
2460 | return 0; | 2508 | return 0; |
2461 | 2509 | ||
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 242de0101a86..325ee36a9d29 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
@@ -75,7 +75,8 @@ struct symbol_conf { | |||
75 | use_callchain, | 75 | use_callchain, |
76 | exclude_other, | 76 | exclude_other, |
77 | show_cpu_utilization, | 77 | show_cpu_utilization, |
78 | initialized; | 78 | initialized, |
79 | kptr_restrict; | ||
79 | const char *vmlinux_name, | 80 | const char *vmlinux_name, |
80 | *kallsyms_name, | 81 | *kallsyms_name, |
81 | *source_prefix, | 82 | *source_prefix, |
diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 1fd29b2daa92..cef28e6632b9 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl | |||
@@ -788,7 +788,7 @@ sub wait_for_input | |||
788 | 788 | ||
789 | sub reboot_to { | 789 | sub reboot_to { |
790 | if ($reboot_type eq "grub") { | 790 | if ($reboot_type eq "grub") { |
791 | run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'"; | 791 | run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch && reboot)'"; |
792 | return; | 792 | return; |
793 | } | 793 | } |
794 | 794 | ||
@@ -1480,7 +1480,7 @@ sub process_config_ignore { | |||
1480 | or dodie "Failed to read $config"; | 1480 | or dodie "Failed to read $config"; |
1481 | 1481 | ||
1482 | while (<IN>) { | 1482 | while (<IN>) { |
1483 | if (/^(.*?(CONFIG\S*)(=.*| is not set))/) { | 1483 | if (/^((CONFIG\S*)=.*)/) { |
1484 | $config_ignore{$2} = $1; | 1484 | $config_ignore{$2} = $1; |
1485 | } | 1485 | } |
1486 | } | 1486 | } |
@@ -1638,7 +1638,7 @@ sub run_config_bisect { | |||
1638 | if (!$found) { | 1638 | if (!$found) { |
1639 | # try the other half | 1639 | # try the other half |
1640 | doprint "Top half produced no set configs, trying bottom half\n"; | 1640 | doprint "Top half produced no set configs, trying bottom half\n"; |
1641 | @tophalf = @start_list[$half .. $#start_list]; | 1641 | @tophalf = @start_list[$half + 1 .. $#start_list]; |
1642 | create_config @tophalf; | 1642 | create_config @tophalf; |
1643 | read_current_config \%current_config; | 1643 | read_current_config \%current_config; |
1644 | foreach my $config (@tophalf) { | 1644 | foreach my $config (@tophalf) { |
@@ -1690,7 +1690,7 @@ sub run_config_bisect { | |||
1690 | # remove half the configs we are looking at and see if | 1690 | # remove half the configs we are looking at and see if |
1691 | # they are good. | 1691 | # they are good. |
1692 | $half = int($#start_list / 2); | 1692 | $half = int($#start_list / 2); |
1693 | } while ($half > 0); | 1693 | } while ($#start_list > 0); |
1694 | 1694 | ||
1695 | # we found a single config, try it again unless we are running manually | 1695 | # we found a single config, try it again unless we are running manually |
1696 | 1696 | ||
diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c index df0c6d2c3860..74d3331bdaf9 100644 --- a/tools/virtio/virtio_test.c +++ b/tools/virtio/virtio_test.c | |||
@@ -198,6 +198,14 @@ const struct option longopts[] = { | |||
198 | .val = 'h', | 198 | .val = 'h', |
199 | }, | 199 | }, |
200 | { | 200 | { |
201 | .name = "event-idx", | ||
202 | .val = 'E', | ||
203 | }, | ||
204 | { | ||
205 | .name = "no-event-idx", | ||
206 | .val = 'e', | ||
207 | }, | ||
208 | { | ||
201 | .name = "indirect", | 209 | .name = "indirect", |
202 | .val = 'I', | 210 | .val = 'I', |
203 | }, | 211 | }, |
@@ -211,13 +219,17 @@ const struct option longopts[] = { | |||
211 | 219 | ||
212 | static void help() | 220 | static void help() |
213 | { | 221 | { |
214 | fprintf(stderr, "Usage: virtio_test [--help] [--no-indirect]\n"); | 222 | fprintf(stderr, "Usage: virtio_test [--help]" |
223 | " [--no-indirect]" | ||
224 | " [--no-event-idx]" | ||
225 | "\n"); | ||
215 | } | 226 | } |
216 | 227 | ||
217 | int main(int argc, char **argv) | 228 | int main(int argc, char **argv) |
218 | { | 229 | { |
219 | struct vdev_info dev; | 230 | struct vdev_info dev; |
220 | unsigned long long features = 1ULL << VIRTIO_RING_F_INDIRECT_DESC; | 231 | unsigned long long features = (1ULL << VIRTIO_RING_F_INDIRECT_DESC) | |
232 | (1ULL << VIRTIO_RING_F_EVENT_IDX); | ||
221 | int o; | 233 | int o; |
222 | 234 | ||
223 | for (;;) { | 235 | for (;;) { |
@@ -228,6 +240,9 @@ int main(int argc, char **argv) | |||
228 | case '?': | 240 | case '?': |
229 | help(); | 241 | help(); |
230 | exit(2); | 242 | exit(2); |
243 | case 'e': | ||
244 | features &= ~(1ULL << VIRTIO_RING_F_EVENT_IDX); | ||
245 | break; | ||
231 | case 'h': | 246 | case 'h': |
232 | help(); | 247 | help(); |
233 | goto done; | 248 | goto done; |