diff options
169 files changed, 7556 insertions, 2488 deletions
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/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/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/MAINTAINERS b/MAINTAINERS index 2e94220898d7..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 |
@@ -3033,9 +3029,8 @@ S: Maintained | |||
3033 | F: drivers/net/wireless/hostap/ | 3029 | F: drivers/net/wireless/hostap/ |
3034 | 3030 | ||
3035 | HP COMPAQ TC1100 TABLET WMI EXTRAS DRIVER | 3031 | HP COMPAQ TC1100 TABLET WMI EXTRAS DRIVER |
3036 | M: Carlos Corbacho <carlos@strangeworlds.co.uk> | ||
3037 | L: platform-driver-x86@vger.kernel.org | 3032 | L: platform-driver-x86@vger.kernel.org |
3038 | S: Odd Fixes | 3033 | S: Orphan |
3039 | F: drivers/platform/x86/tc1100-wmi.c | 3034 | F: drivers/platform/x86/tc1100-wmi.c |
3040 | 3035 | ||
3041 | 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 |
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/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/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/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/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/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/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 53f02f5d8cce..22a073d7fbff 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -902,7 +902,7 @@ static void vgetcpu_set_mode(void) | |||
902 | void __init identify_boot_cpu(void) | 902 | void __init identify_boot_cpu(void) |
903 | { | 903 | { |
904 | identify_cpu(&boot_cpu_data); | 904 | identify_cpu(&boot_cpu_data); |
905 | init_c1e_mask(); | 905 | init_amd_e400_c1e_mask(); |
906 | #ifdef CONFIG_X86_32 | 906 | #ifdef CONFIG_X86_32 |
907 | sysenter_setup(); | 907 | sysenter_setup(); |
908 | enable_sep_cpu(); | 908 | enable_sep_cpu(); |
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 88a90a977f8e..426a5b66f7e4 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/smpboot.c b/arch/x86/kernel/smpboot.c index a3c430bdfb60..eefd96765e79 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 */ |
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/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/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/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/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/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/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/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/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/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/ubifs/shrinker.c b/fs/ubifs/shrinker.c index 46961c003236..ca953a945029 100644 --- a/fs/ubifs/shrinker.c +++ b/fs/ubifs/shrinker.c | |||
@@ -277,8 +277,9 @@ 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 | ||
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index 93d1412a06f0..a70d7b4ffb25 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h | |||
@@ -1614,7 +1614,7 @@ int ubifs_tnc_start_commit(struct ubifs_info *c, struct ubifs_zbranch *zroot); | |||
1614 | int ubifs_tnc_end_commit(struct ubifs_info *c); | 1614 | int ubifs_tnc_end_commit(struct ubifs_info *c); |
1615 | 1615 | ||
1616 | /* shrinker.c */ | 1616 | /* shrinker.c */ |
1617 | int ubifs_shrinker(struct shrinker *shrink, int nr_to_scan, gfp_t gfp_mask); | 1617 | int ubifs_shrinker(struct shrinker *shrink, struct shrink_control *sc); |
1618 | 1618 | ||
1619 | /* commit.c */ | 1619 | /* commit.c */ |
1620 | int ubifs_bg_thread(void *info); | 1620 | int ubifs_bg_thread(void *info); |
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/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/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/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/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/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 bcddd0138105..2a8621c4be1e 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -2194,7 +2194,6 @@ static inline void mmdrop(struct mm_struct * mm) | |||
2194 | if (unlikely(atomic_dec_and_test(&mm->mm_count))) | 2194 | if (unlikely(atomic_dec_and_test(&mm->mm_count))) |
2195 | __mmdrop(mm); | 2195 | __mmdrop(mm); |
2196 | } | 2196 | } |
2197 | extern int mm_init_cpumask(struct mm_struct *mm, struct mm_struct *oldmm); | ||
2198 | 2197 | ||
2199 | /* mmput gets rid of the mappings and all user-space */ | 2198 | /* mmput gets rid of the mappings and all user-space */ |
2200 | 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/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/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/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 | ||
@@ -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() ]. |
@@ -421,7 +426,7 @@ struct anon_vma *page_lock_anon_vma(struct page *page) | |||
421 | /* | 426 | /* |
422 | * If the page is still mapped, then this anon_vma is still | 427 | * If the page is still mapped, then this anon_vma is still |
423 | * its anon_vma, and holding the mutex ensures that it will | 428 | * its anon_vma, and holding the mutex ensures that it will |
424 | * not go away, see __put_anon_vma(). | 429 | * not go away, see anon_vma_free(). |
425 | */ | 430 | */ |
426 | if (!page_mapped(page)) { | 431 | if (!page_mapped(page)) { |
427 | mutex_unlock(&root_anon_vma->mutex); | 432 | mutex_unlock(&root_anon_vma->mutex); |
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); |