diff options
394 files changed, 9506 insertions, 3166 deletions
diff --git a/Documentation/acpi/apei/einj.txt b/Documentation/acpi/apei/einj.txt new file mode 100644 index 000000000000..dfab71848dc8 --- /dev/null +++ b/Documentation/acpi/apei/einj.txt | |||
@@ -0,0 +1,59 @@ | |||
1 | APEI Error INJection | ||
2 | ~~~~~~~~~~~~~~~~~~~~ | ||
3 | |||
4 | EINJ provides a hardware error injection mechanism | ||
5 | It is very useful for debugging and testing of other APEI and RAS features. | ||
6 | |||
7 | To use EINJ, make sure the following are enabled in your kernel | ||
8 | configuration: | ||
9 | |||
10 | CONFIG_DEBUG_FS | ||
11 | CONFIG_ACPI_APEI | ||
12 | CONFIG_ACPI_APEI_EINJ | ||
13 | |||
14 | The user interface of EINJ is debug file system, under the | ||
15 | directory apei/einj. The following files are provided. | ||
16 | |||
17 | - available_error_type | ||
18 | Reading this file returns the error injection capability of the | ||
19 | platform, that is, which error types are supported. The error type | ||
20 | definition is as follow, the left field is the error type value, the | ||
21 | right field is error description. | ||
22 | |||
23 | 0x00000001 Processor Correctable | ||
24 | 0x00000002 Processor Uncorrectable non-fatal | ||
25 | 0x00000004 Processor Uncorrectable fatal | ||
26 | 0x00000008 Memory Correctable | ||
27 | 0x00000010 Memory Uncorrectable non-fatal | ||
28 | 0x00000020 Memory Uncorrectable fatal | ||
29 | 0x00000040 PCI Express Correctable | ||
30 | 0x00000080 PCI Express Uncorrectable fatal | ||
31 | 0x00000100 PCI Express Uncorrectable non-fatal | ||
32 | 0x00000200 Platform Correctable | ||
33 | 0x00000400 Platform Uncorrectable non-fatal | ||
34 | 0x00000800 Platform Uncorrectable fatal | ||
35 | |||
36 | The format of file contents are as above, except there are only the | ||
37 | available error type lines. | ||
38 | |||
39 | - error_type | ||
40 | This file is used to set the error type value. The error type value | ||
41 | is defined in "available_error_type" description. | ||
42 | |||
43 | - error_inject | ||
44 | Write any integer to this file to trigger the error | ||
45 | injection. Before this, please specify all necessary error | ||
46 | parameters. | ||
47 | |||
48 | - param1 | ||
49 | This file is used to set the first error parameter value. Effect of | ||
50 | parameter depends on error_type specified. For memory error, this is | ||
51 | physical memory address. | ||
52 | |||
53 | - param2 | ||
54 | This file is used to set the second error parameter value. Effect of | ||
55 | parameter depends on error_type specified. For memory error, this is | ||
56 | physical memory address mask. | ||
57 | |||
58 | For more information about EINJ, please refer to ACPI specification | ||
59 | version 4.0, section 17.5. | ||
diff --git a/Documentation/arm/Samsung-S3C24XX/GPIO.txt b/Documentation/arm/Samsung-S3C24XX/GPIO.txt index 2af2cf39915f..816d6071669e 100644 --- a/Documentation/arm/Samsung-S3C24XX/GPIO.txt +++ b/Documentation/arm/Samsung-S3C24XX/GPIO.txt | |||
@@ -12,6 +12,8 @@ Introduction | |||
12 | of the s3c2410 GPIO system, please read the Samsung provided | 12 | of the s3c2410 GPIO system, please read the Samsung provided |
13 | data-sheet/users manual to find out the complete list. | 13 | data-sheet/users manual to find out the complete list. |
14 | 14 | ||
15 | See Documentation/arm/Samsung/GPIO.txt for the core implemetation. | ||
16 | |||
15 | 17 | ||
16 | GPIOLIB | 18 | GPIOLIB |
17 | ------- | 19 | ------- |
@@ -24,8 +26,60 @@ GPIOLIB | |||
24 | listed below will be removed (they may be marked as __deprecated | 26 | listed below will be removed (they may be marked as __deprecated |
25 | in the near future). | 27 | in the near future). |
26 | 28 | ||
27 | - s3c2410_gpio_getpin | 29 | The following functions now either have a s3c_ specific variant |
28 | - s3c2410_gpio_setpin | 30 | or are merged into gpiolib. See the definitions in |
31 | arch/arm/plat-samsung/include/plat/gpio-cfg.h: | ||
32 | |||
33 | s3c2410_gpio_setpin() gpio_set_value() or gpio_direction_output() | ||
34 | s3c2410_gpio_getpin() gpio_get_value() or gpio_direction_input() | ||
35 | s3c2410_gpio_getirq() gpio_to_irq() | ||
36 | s3c2410_gpio_cfgpin() s3c_gpio_cfgpin() | ||
37 | s3c2410_gpio_getcfg() s3c_gpio_getcfg() | ||
38 | s3c2410_gpio_pullup() s3c_gpio_setpull() | ||
39 | |||
40 | |||
41 | GPIOLIB conversion | ||
42 | ------------------ | ||
43 | |||
44 | If you need to convert your board or driver to use gpiolib from the exiting | ||
45 | s3c2410 api, then here are some notes on the process. | ||
46 | |||
47 | 1) If your board is exclusively using an GPIO, say to control peripheral | ||
48 | power, then it will require to claim the gpio with gpio_request() before | ||
49 | it can use it. | ||
50 | |||
51 | It is recommended to check the return value, with at least WARN_ON() | ||
52 | during initialisation. | ||
53 | |||
54 | 2) The s3c2410_gpio_cfgpin() can be directly replaced with s3c_gpio_cfgpin() | ||
55 | as they have the same arguments, and can either take the pin specific | ||
56 | values, or the more generic special-function-number arguments. | ||
57 | |||
58 | 3) s3c2410_gpio_pullup() changs have the problem that whilst the | ||
59 | s3c2410_gpio_pullup(x, 1) can be easily translated to the | ||
60 | s3c_gpio_setpull(x, S3C_GPIO_PULL_NONE), the s3c2410_gpio_pullup(x, 0) | ||
61 | are not so easy. | ||
62 | |||
63 | The s3c2410_gpio_pullup(x, 0) case enables the pull-up (or in the case | ||
64 | of some of the devices, a pull-down) and as such the new API distinguishes | ||
65 | between the UP and DOWN case. There is currently no 'just turn on' setting | ||
66 | which may be required if this becomes a problem. | ||
67 | |||
68 | 4) s3c2410_gpio_setpin() can be replaced by gpio_set_value(), the old call | ||
69 | does not implicitly configure the relevant gpio to output. The gpio | ||
70 | direction should be changed before using gpio_set_value(). | ||
71 | |||
72 | 5) s3c2410_gpio_getpin() is replaceable by gpio_get_value() if the pin | ||
73 | has been set to input. It is currently unknown what the behaviour is | ||
74 | when using gpio_get_value() on an output pin (s3c2410_gpio_getpin | ||
75 | would return the value the pin is supposed to be outputting). | ||
76 | |||
77 | 6) s3c2410_gpio_getirq() should be directly replacable with the | ||
78 | gpio_to_irq() call. | ||
79 | |||
80 | The s3c2410_gpio and gpio_ calls have always operated on the same gpio | ||
81 | numberspace, so there is no problem with converting the gpio numbering | ||
82 | between the calls. | ||
29 | 83 | ||
30 | 84 | ||
31 | Headers | 85 | Headers |
@@ -54,6 +108,11 @@ PIN Numbers | |||
54 | eg S3C2410_GPA(0) or S3C2410_GPF(1). These defines are used to tell | 108 | eg S3C2410_GPA(0) or S3C2410_GPF(1). These defines are used to tell |
55 | the GPIO functions which pin is to be used. | 109 | the GPIO functions which pin is to be used. |
56 | 110 | ||
111 | With the conversion to gpiolib, there is no longer a direct conversion | ||
112 | from gpio pin number to register base address as in earlier kernels. This | ||
113 | is due to the number space required for newer SoCs where the later | ||
114 | GPIOs are not contiguous. | ||
115 | |||
57 | 116 | ||
58 | Configuring a pin | 117 | Configuring a pin |
59 | ----------------- | 118 | ----------------- |
@@ -71,6 +130,8 @@ Configuring a pin | |||
71 | which would turn GPA(0) into the lowest Address line A0, and set | 130 | which would turn GPA(0) into the lowest Address line A0, and set |
72 | GPE(8) to be connected to the SDIO/MMC controller's SDDAT1 line. | 131 | GPE(8) to be connected to the SDIO/MMC controller's SDDAT1 line. |
73 | 132 | ||
133 | The s3c_gpio_cfgpin() call is a functional replacement for this call. | ||
134 | |||
74 | 135 | ||
75 | Reading the current configuration | 136 | Reading the current configuration |
76 | --------------------------------- | 137 | --------------------------------- |
@@ -82,6 +143,9 @@ Reading the current configuration | |||
82 | The return value will be from the same set of values which can be | 143 | The return value will be from the same set of values which can be |
83 | passed to s3c2410_gpio_cfgpin(). | 144 | passed to s3c2410_gpio_cfgpin(). |
84 | 145 | ||
146 | The s3c_gpio_getcfg() call should be a functional replacement for | ||
147 | this call. | ||
148 | |||
85 | 149 | ||
86 | Configuring a pull-up resistor | 150 | Configuring a pull-up resistor |
87 | ------------------------------ | 151 | ------------------------------ |
@@ -95,6 +159,10 @@ Configuring a pull-up resistor | |||
95 | Where the to value is zero to set the pull-up off, and 1 to enable | 159 | Where the to value is zero to set the pull-up off, and 1 to enable |
96 | the specified pull-up. Any other values are currently undefined. | 160 | the specified pull-up. Any other values are currently undefined. |
97 | 161 | ||
162 | The s3c_gpio_setpull() offers similar functionality, but with the | ||
163 | ability to encode whether the pull is up or down. Currently there | ||
164 | is no 'just on' state, so up or down must be selected. | ||
165 | |||
98 | 166 | ||
99 | Getting the state of a PIN | 167 | Getting the state of a PIN |
100 | -------------------------- | 168 | -------------------------- |
@@ -106,6 +174,9 @@ Getting the state of a PIN | |||
106 | This will return either zero or non-zero. Do not count on this | 174 | This will return either zero or non-zero. Do not count on this |
107 | function returning 1 if the pin is set. | 175 | function returning 1 if the pin is set. |
108 | 176 | ||
177 | This call is now implemented by the relevant gpiolib calls, convert | ||
178 | your board or driver to use gpiolib. | ||
179 | |||
109 | 180 | ||
110 | Setting the state of a PIN | 181 | Setting the state of a PIN |
111 | -------------------------- | 182 | -------------------------- |
@@ -117,6 +188,9 @@ Setting the state of a PIN | |||
117 | Which sets the given pin to the value. Use 0 to write 0, and 1 to | 188 | Which sets the given pin to the value. Use 0 to write 0, and 1 to |
118 | set the output to 1. | 189 | set the output to 1. |
119 | 190 | ||
191 | This call is now implemented by the relevant gpiolib calls, convert | ||
192 | your board or driver to use gpiolib. | ||
193 | |||
120 | 194 | ||
121 | Getting the IRQ number associated with a PIN | 195 | Getting the IRQ number associated with a PIN |
122 | -------------------------------------------- | 196 | -------------------------------------------- |
@@ -128,6 +202,9 @@ Getting the IRQ number associated with a PIN | |||
128 | 202 | ||
129 | Note, not all pins have an IRQ. | 203 | Note, not all pins have an IRQ. |
130 | 204 | ||
205 | This call is now implemented by the relevant gpiolib calls, convert | ||
206 | your board or driver to use gpiolib. | ||
207 | |||
131 | 208 | ||
132 | Authour | 209 | Authour |
133 | ------- | 210 | ------- |
diff --git a/Documentation/arm/Samsung-S3C24XX/Overview.txt b/Documentation/arm/Samsung-S3C24XX/Overview.txt index 081892df4fda..c12bfc1a00c9 100644 --- a/Documentation/arm/Samsung-S3C24XX/Overview.txt +++ b/Documentation/arm/Samsung-S3C24XX/Overview.txt | |||
@@ -8,10 +8,16 @@ Introduction | |||
8 | 8 | ||
9 | The Samsung S3C24XX range of ARM9 System-on-Chip CPUs are supported | 9 | The Samsung S3C24XX range of ARM9 System-on-Chip CPUs are supported |
10 | by the 's3c2410' architecture of ARM Linux. Currently the S3C2410, | 10 | by the 's3c2410' architecture of ARM Linux. Currently the S3C2410, |
11 | S3C2412, S3C2413, S3C2440, S3C2442 and S3C2443 devices are supported. | 11 | S3C2412, S3C2413, S3C2416 S3C2440, S3C2442, S3C2443 and S3C2450 devices |
12 | are supported. | ||
12 | 13 | ||
13 | Support for the S3C2400 and S3C24A0 series are in progress. | 14 | Support for the S3C2400 and S3C24A0 series are in progress. |
14 | 15 | ||
16 | The S3C2416 and S3C2450 devices are very similar and S3C2450 support is | ||
17 | included under the arch/arm/mach-s3c2416 directory. Note, whilst core | ||
18 | support for these SoCs is in, work on some of the extra peripherals | ||
19 | and extra interrupts is still ongoing. | ||
20 | |||
15 | 21 | ||
16 | Configuration | 22 | Configuration |
17 | ------------- | 23 | ------------- |
@@ -209,6 +215,13 @@ GPIO | |||
209 | Newer kernels carry GPIOLIB, and support is being moved towards | 215 | Newer kernels carry GPIOLIB, and support is being moved towards |
210 | this with some of the older support in line to be removed. | 216 | this with some of the older support in line to be removed. |
211 | 217 | ||
218 | As of v2.6.34, the move towards using gpiolib support is almost | ||
219 | complete, and very little of the old calls are left. | ||
220 | |||
221 | See Documentation/arm/Samsung-S3C24XX/GPIO.txt for the S3C24XX specific | ||
222 | support and Documentation/arm/Samsung/GPIO.txt for the core Samsung | ||
223 | implementation. | ||
224 | |||
212 | 225 | ||
213 | Clock Management | 226 | Clock Management |
214 | ---------------- | 227 | ---------------- |
diff --git a/Documentation/arm/Samsung/GPIO.txt b/Documentation/arm/Samsung/GPIO.txt new file mode 100644 index 000000000000..05850c62abeb --- /dev/null +++ b/Documentation/arm/Samsung/GPIO.txt | |||
@@ -0,0 +1,42 @@ | |||
1 | Samsung GPIO implementation | ||
2 | =========================== | ||
3 | |||
4 | Introduction | ||
5 | ------------ | ||
6 | |||
7 | This outlines the Samsung GPIO implementation and the architecture | ||
8 | specfic calls provided alongisde the drivers/gpio core. | ||
9 | |||
10 | |||
11 | S3C24XX (Legacy) | ||
12 | ---------------- | ||
13 | |||
14 | See Documentation/arm/Samsung-S3C24XX/GPIO.txt for more information | ||
15 | about these devices. Their implementation is being brought into line | ||
16 | with the core samsung implementation described in this document. | ||
17 | |||
18 | |||
19 | GPIOLIB integration | ||
20 | ------------------- | ||
21 | |||
22 | The gpio implementation uses gpiolib as much as possible, only providing | ||
23 | specific calls for the items that require Samsung specific handling, such | ||
24 | as pin special-function or pull resistor control. | ||
25 | |||
26 | GPIO numbering is synchronised between the Samsung and gpiolib system. | ||
27 | |||
28 | |||
29 | PIN configuration | ||
30 | ----------------- | ||
31 | |||
32 | Pin configuration is specific to the Samsung architecutre, with each SoC | ||
33 | registering the necessary information for the core gpio configuration | ||
34 | implementation to configure pins as necessary. | ||
35 | |||
36 | The s3c_gpio_cfgpin() and s3c_gpio_setpull() provide the means for a | ||
37 | driver or machine to change gpio configuration. | ||
38 | |||
39 | See arch/arm/plat-samsung/include/plat/gpio-cfg.h for more information | ||
40 | on these functions. | ||
41 | |||
42 | |||
diff --git a/Documentation/arm/Samsung/Overview.txt b/Documentation/arm/Samsung/Overview.txt index 7cced1fea9c3..c3094ea51aa7 100644 --- a/Documentation/arm/Samsung/Overview.txt +++ b/Documentation/arm/Samsung/Overview.txt | |||
@@ -13,9 +13,10 @@ Introduction | |||
13 | 13 | ||
14 | - S3C24XX: See Documentation/arm/Samsung-S3C24XX/Overview.txt for full list | 14 | - S3C24XX: See Documentation/arm/Samsung-S3C24XX/Overview.txt for full list |
15 | - S3C64XX: S3C6400 and S3C6410 | 15 | - S3C64XX: S3C6400 and S3C6410 |
16 | - S5PC6440 | 16 | - S5P6440 |
17 | 17 | - S5P6442 | |
18 | S5PC100 and S5PC110 support is currently being merged | 18 | - S5PC100 |
19 | - S5PC110 / S5PV210 | ||
19 | 20 | ||
20 | 21 | ||
21 | S3C24XX Systems | 22 | S3C24XX Systems |
@@ -35,7 +36,10 @@ Configuration | |||
35 | unifying all the SoCs into one kernel. | 36 | unifying all the SoCs into one kernel. |
36 | 37 | ||
37 | s5p6440_defconfig - S5P6440 specific default configuration | 38 | s5p6440_defconfig - S5P6440 specific default configuration |
39 | s5p6442_defconfig - S5P6442 specific default configuration | ||
38 | s5pc100_defconfig - S5PC100 specific default configuration | 40 | s5pc100_defconfig - S5PC100 specific default configuration |
41 | s5pc110_defconfig - S5PC110 specific default configuration | ||
42 | s5pv210_defconfig - S5PV210 specific default configuration | ||
39 | 43 | ||
40 | 44 | ||
41 | Layout | 45 | Layout |
@@ -50,18 +54,27 @@ Layout | |||
50 | specific information. It contains the base clock, GPIO and device definitions | 54 | specific information. It contains the base clock, GPIO and device definitions |
51 | to get the system running. | 55 | to get the system running. |
52 | 56 | ||
53 | plat-s3c is the s3c24xx/s3c64xx platform directory, although it is currently | ||
54 | involved in other builds this will be phased out once the relevant code is | ||
55 | moved elsewhere. | ||
56 | |||
57 | plat-s3c24xx is for s3c24xx specific builds, see the S3C24XX docs. | 57 | plat-s3c24xx is for s3c24xx specific builds, see the S3C24XX docs. |
58 | 58 | ||
59 | plat-s3c64xx is for the s3c64xx specific bits, see the S3C24XX docs. | 59 | plat-s5p is for s5p specific builds, and contains common support for the |
60 | S5P specific systems. Not all S5Ps use all the features in this directory | ||
61 | due to differences in the hardware. | ||
62 | |||
63 | |||
64 | Layout changes | ||
65 | -------------- | ||
66 | |||
67 | The old plat-s3c and plat-s5pc1xx directories have been removed, with | ||
68 | support moved to either plat-samsung or plat-s5p as necessary. These moves | ||
69 | where to simplify the include and dependency issues involved with having | ||
70 | so many different platform directories. | ||
60 | 71 | ||
61 | plat-s5p is for s5p specific builds, more to be added. | 72 | It was decided to remove plat-s5pc1xx as some of the support was already |
73 | in plat-s5p or plat-samsung, with the S5PC110 support added with S5PV210 | ||
74 | the only user was the S5PC100. The S5PC100 specific items where moved to | ||
75 | arch/arm/mach-s5pc100. | ||
62 | 76 | ||
63 | 77 | ||
64 | [ to finish ] | ||
65 | 78 | ||
66 | 79 | ||
67 | Port Contributors | 80 | Port Contributors |
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index 61c98f03baa1..96d4293607ec 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking | |||
@@ -380,7 +380,7 @@ prototypes: | |||
380 | int (*open) (struct inode *, struct file *); | 380 | int (*open) (struct inode *, struct file *); |
381 | int (*flush) (struct file *); | 381 | int (*flush) (struct file *); |
382 | int (*release) (struct inode *, struct file *); | 382 | int (*release) (struct inode *, struct file *); |
383 | int (*fsync) (struct file *, struct dentry *, int datasync); | 383 | int (*fsync) (struct file *, int datasync); |
384 | int (*aio_fsync) (struct kiocb *, int datasync); | 384 | int (*aio_fsync) (struct kiocb *, int datasync); |
385 | int (*fasync) (int, struct file *, int); | 385 | int (*fasync) (int, struct file *, int); |
386 | int (*lock) (struct file *, int, struct file_lock *); | 386 | int (*lock) (struct file *, int, struct file_lock *); |
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index b66858538df5..94677e7dcb13 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt | |||
@@ -401,11 +401,16 @@ otherwise noted. | |||
401 | started might not be in the page cache at the end of the | 401 | started might not be in the page cache at the end of the |
402 | walk). | 402 | walk). |
403 | 403 | ||
404 | truncate: called by the VFS to change the size of a file. The | 404 | truncate: Deprecated. This will not be called if ->setsize is defined. |
405 | Called by the VFS to change the size of a file. The | ||
405 | i_size field of the inode is set to the desired size by the | 406 | i_size field of the inode is set to the desired size by the |
406 | VFS before this method is called. This method is called by | 407 | VFS before this method is called. This method is called by |
407 | the truncate(2) system call and related functionality. | 408 | the truncate(2) system call and related functionality. |
408 | 409 | ||
410 | Note: ->truncate and vmtruncate are deprecated. Do not add new | ||
411 | instances/calls of these. Filesystems should be converted to do their | ||
412 | truncate sequence via ->setattr(). | ||
413 | |||
409 | permission: called by the VFS to check for access rights on a POSIX-like | 414 | permission: called by the VFS to check for access rights on a POSIX-like |
410 | filesystem. | 415 | filesystem. |
411 | 416 | ||
@@ -729,7 +734,7 @@ struct file_operations { | |||
729 | int (*open) (struct inode *, struct file *); | 734 | int (*open) (struct inode *, struct file *); |
730 | int (*flush) (struct file *); | 735 | int (*flush) (struct file *); |
731 | int (*release) (struct inode *, struct file *); | 736 | int (*release) (struct inode *, struct file *); |
732 | int (*fsync) (struct file *, struct dentry *, int datasync); | 737 | int (*fsync) (struct file *, int datasync); |
733 | int (*aio_fsync) (struct kiocb *, int datasync); | 738 | int (*aio_fsync) (struct kiocb *, int datasync); |
734 | int (*fasync) (int, struct file *, int); | 739 | int (*fasync) (int, struct file *, int); |
735 | int (*lock) (struct file *, int, struct file_lock *); | 740 | int (*lock) (struct file *, int, struct file_lock *); |
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index b56ea860da21..1808f1157f30 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -145,11 +145,10 @@ and is between 256 and 4096 characters. It is defined in the file | |||
145 | 145 | ||
146 | acpi= [HW,ACPI,X86] | 146 | acpi= [HW,ACPI,X86] |
147 | Advanced Configuration and Power Interface | 147 | Advanced Configuration and Power Interface |
148 | Format: { force | off | ht | strict | noirq | rsdt } | 148 | Format: { force | off | strict | noirq | rsdt } |
149 | force -- enable ACPI if default was off | 149 | force -- enable ACPI if default was off |
150 | off -- disable ACPI if default was on | 150 | off -- disable ACPI if default was on |
151 | noirq -- do not use ACPI for IRQ routing | 151 | noirq -- do not use ACPI for IRQ routing |
152 | ht -- run only enough ACPI to enable Hyper Threading | ||
153 | strict -- Be less tolerant of platforms that are not | 152 | strict -- Be less tolerant of platforms that are not |
154 | strictly ACPI specification compliant. | 153 | strictly ACPI specification compliant. |
155 | rsdt -- prefer RSDT over (default) XSDT | 154 | rsdt -- prefer RSDT over (default) XSDT |
@@ -758,6 +757,10 @@ and is between 256 and 4096 characters. It is defined in the file | |||
758 | Default value is 0. | 757 | Default value is 0. |
759 | Value can be changed at runtime via /selinux/enforce. | 758 | Value can be changed at runtime via /selinux/enforce. |
760 | 759 | ||
760 | erst_disable [ACPI] | ||
761 | Disable Error Record Serialization Table (ERST) | ||
762 | support. | ||
763 | |||
761 | ether= [HW,NET] Ethernet cards parameters | 764 | ether= [HW,NET] Ethernet cards parameters |
762 | This option is obsoleted by the "netdev=" option, which | 765 | This option is obsoleted by the "netdev=" option, which |
763 | has equivalent usage. See its documentation for details. | 766 | has equivalent usage. See its documentation for details. |
@@ -852,6 +855,11 @@ and is between 256 and 4096 characters. It is defined in the file | |||
852 | hd= [EIDE] (E)IDE hard drive subsystem geometry | 855 | hd= [EIDE] (E)IDE hard drive subsystem geometry |
853 | Format: <cyl>,<head>,<sect> | 856 | Format: <cyl>,<head>,<sect> |
854 | 857 | ||
858 | hest_disable [ACPI] | ||
859 | Disable Hardware Error Source Table (HEST) support; | ||
860 | corresponding firmware-first mode error processing | ||
861 | logic will be disabled. | ||
862 | |||
855 | highmem=nn[KMG] [KNL,BOOT] forces the highmem zone to have an exact | 863 | highmem=nn[KMG] [KNL,BOOT] forces the highmem zone to have an exact |
856 | size of <nn>. This works even on boxes that have no | 864 | size of <nn>. This works even on boxes that have no |
857 | highmem otherwise. This also works to reduce highmem | 865 | highmem otherwise. This also works to reduce highmem |
@@ -1252,6 +1260,8 @@ and is between 256 and 4096 characters. It is defined in the file | |||
1252 | * nohrst, nosrst, norst: suppress hard, soft | 1260 | * nohrst, nosrst, norst: suppress hard, soft |
1253 | and both resets. | 1261 | and both resets. |
1254 | 1262 | ||
1263 | * dump_id: dump IDENTIFY data. | ||
1264 | |||
1255 | If there are multiple matching configurations changing | 1265 | If there are multiple matching configurations changing |
1256 | the same attribute, the last one is used. | 1266 | the same attribute, the last one is used. |
1257 | 1267 | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 33047a605438..13608bd2e791 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -2887,6 +2887,13 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git | |||
2887 | S: Maintained | 2887 | S: Maintained |
2888 | F: drivers/input/ | 2888 | F: drivers/input/ |
2889 | 2889 | ||
2890 | INTEL IDLE DRIVER | ||
2891 | M: Len Brown <lenb@kernel.org> | ||
2892 | L: linux-pm@lists.linux-foundation.org | ||
2893 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-idle-2.6.git | ||
2894 | S: Supported | ||
2895 | F: drivers/idle/intel_idle.c | ||
2896 | |||
2890 | INTEL FRAMEBUFFER DRIVER (excluding 810 and 815) | 2897 | INTEL FRAMEBUFFER DRIVER (excluding 810 and 815) |
2891 | M: Maik Broemme <mbroemme@plusserver.de> | 2898 | M: Maik Broemme <mbroemme@plusserver.de> |
2892 | L: linux-fbdev@vger.kernel.org | 2899 | L: linux-fbdev@vger.kernel.org |
diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig index 43af89c027d9..44cea2ddd22b 100644 --- a/arch/arm/configs/s3c2410_defconfig +++ b/arch/arm/configs/s3c2410_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.34 | 3 | # Linux kernel version: 2.6.34 |
4 | # Wed May 26 19:04:29 2010 | 4 | # Fri May 28 19:15:48 2010 |
5 | # | 5 | # |
6 | CONFIG_ARM=y | 6 | CONFIG_ARM=y |
7 | CONFIG_HAVE_PWM=y | 7 | CONFIG_HAVE_PWM=y |
@@ -250,12 +250,15 @@ CONFIG_S3C_BOOT_UART_FORCE_FIFO=y | |||
250 | CONFIG_S3C_LOWLEVEL_UART_PORT=0 | 250 | CONFIG_S3C_LOWLEVEL_UART_PORT=0 |
251 | CONFIG_SAMSUNG_CLKSRC=y | 251 | CONFIG_SAMSUNG_CLKSRC=y |
252 | CONFIG_S3C_GPIO_CFG_S3C24XX=y | 252 | CONFIG_S3C_GPIO_CFG_S3C24XX=y |
253 | CONFIG_S3C_GPIO_PULL_UPDOWN=y | ||
253 | CONFIG_S3C_GPIO_PULL_UP=y | 254 | CONFIG_S3C_GPIO_PULL_UP=y |
254 | CONFIG_SAMSUNG_GPIO_EXTRA=0 | 255 | CONFIG_SAMSUNG_GPIO_EXTRA=0 |
255 | CONFIG_S3C_GPIO_SPACE=0 | 256 | CONFIG_S3C_GPIO_SPACE=0 |
256 | CONFIG_S3C_ADC=y | 257 | CONFIG_S3C_ADC=y |
257 | CONFIG_S3C_DEV_HSMMC=y | 258 | CONFIG_S3C_DEV_HSMMC=y |
259 | CONFIG_S3C_DEV_HSMMC1=y | ||
258 | CONFIG_S3C_DEV_HWMON=y | 260 | CONFIG_S3C_DEV_HWMON=y |
261 | CONFIG_S3C_DEV_FB=y | ||
259 | CONFIG_S3C_DEV_USB_HOST=y | 262 | CONFIG_S3C_DEV_USB_HOST=y |
260 | CONFIG_S3C_DEV_WDT=y | 263 | CONFIG_S3C_DEV_WDT=y |
261 | CONFIG_S3C_DEV_NAND=y | 264 | CONFIG_S3C_DEV_NAND=y |
@@ -322,11 +325,13 @@ CONFIG_MACH_SMDK2413=y | |||
322 | CONFIG_MACH_S3C2413=y | 325 | CONFIG_MACH_S3C2413=y |
323 | CONFIG_MACH_SMDK2412=y | 326 | CONFIG_MACH_SMDK2412=y |
324 | CONFIG_MACH_VSTMS=y | 327 | CONFIG_MACH_VSTMS=y |
328 | CONFIG_CPU_S3C2416=y | ||
329 | CONFIG_S3C2416_DMA=y | ||
325 | 330 | ||
326 | # | 331 | # |
327 | # S3C2416 Machines | 332 | # S3C2416 Machines |
328 | # | 333 | # |
329 | # CONFIG_MACH_SMDK2416 is not set | 334 | CONFIG_MACH_SMDK2416=y |
330 | CONFIG_CPU_S3C2440=y | 335 | CONFIG_CPU_S3C2440=y |
331 | CONFIG_CPU_S3C2442=y | 336 | CONFIG_CPU_S3C2442=y |
332 | CONFIG_CPU_S3C244X=y | 337 | CONFIG_CPU_S3C244X=y |
@@ -338,9 +343,9 @@ CONFIG_S3C2440_DMA=y | |||
338 | # S3C2440 and S3C2442 Machines | 343 | # S3C2440 and S3C2442 Machines |
339 | # | 344 | # |
340 | CONFIG_MACH_ANUBIS=y | 345 | CONFIG_MACH_ANUBIS=y |
341 | # CONFIG_MACH_NEO1973_GTA02 is not set | 346 | CONFIG_MACH_NEO1973_GTA02=y |
342 | CONFIG_MACH_OSIRIS=y | 347 | CONFIG_MACH_OSIRIS=y |
343 | # CONFIG_MACH_OSIRIS_DVS is not set | 348 | CONFIG_MACH_OSIRIS_DVS=m |
344 | CONFIG_MACH_RX3715=y | 349 | CONFIG_MACH_RX3715=y |
345 | CONFIG_ARCH_S3C2440=y | 350 | CONFIG_ARCH_S3C2440=y |
346 | CONFIG_MACH_NEXCODER_2440=y | 351 | CONFIG_MACH_NEXCODER_2440=y |
@@ -348,7 +353,7 @@ CONFIG_SMDK2440_CPU2440=y | |||
348 | CONFIG_SMDK2440_CPU2442=y | 353 | CONFIG_SMDK2440_CPU2442=y |
349 | CONFIG_MACH_AT2440EVB=y | 354 | CONFIG_MACH_AT2440EVB=y |
350 | CONFIG_MACH_MINI2440=y | 355 | CONFIG_MACH_MINI2440=y |
351 | # CONFIG_MACH_RX1950 is not set | 356 | CONFIG_MACH_RX1950=y |
352 | CONFIG_CPU_S3C2443=y | 357 | CONFIG_CPU_S3C2443=y |
353 | CONFIG_S3C2443_DMA=y | 358 | CONFIG_S3C2443_DMA=y |
354 | 359 | ||
@@ -1302,6 +1307,7 @@ CONFIG_INPUT_POWERMATE=m | |||
1302 | CONFIG_INPUT_YEALINK=m | 1307 | CONFIG_INPUT_YEALINK=m |
1303 | CONFIG_INPUT_CM109=m | 1308 | CONFIG_INPUT_CM109=m |
1304 | CONFIG_INPUT_UINPUT=m | 1309 | CONFIG_INPUT_UINPUT=m |
1310 | # CONFIG_INPUT_PCF50633_PMU is not set | ||
1305 | # CONFIG_INPUT_PCF8574 is not set | 1311 | # CONFIG_INPUT_PCF8574 is not set |
1306 | CONFIG_INPUT_GPIO_ROTARY_ENCODER=m | 1312 | CONFIG_INPUT_GPIO_ROTARY_ENCODER=m |
1307 | 1313 | ||
@@ -1490,7 +1496,16 @@ CONFIG_GPIOLIB=y | |||
1490 | # AC97 GPIO expanders: | 1496 | # AC97 GPIO expanders: |
1491 | # | 1497 | # |
1492 | # CONFIG_W1 is not set | 1498 | # CONFIG_W1 is not set |
1493 | # CONFIG_POWER_SUPPLY is not set | 1499 | CONFIG_POWER_SUPPLY=y |
1500 | # CONFIG_POWER_SUPPLY_DEBUG is not set | ||
1501 | # CONFIG_PDA_POWER is not set | ||
1502 | # CONFIG_APM_POWER is not set | ||
1503 | # CONFIG_TEST_POWER is not set | ||
1504 | # CONFIG_BATTERY_DS2760 is not set | ||
1505 | # CONFIG_BATTERY_DS2782 is not set | ||
1506 | # CONFIG_BATTERY_BQ27x00 is not set | ||
1507 | # CONFIG_BATTERY_MAX17040 is not set | ||
1508 | # CONFIG_CHARGER_PCF50633 is not set | ||
1494 | CONFIG_HWMON=y | 1509 | CONFIG_HWMON=y |
1495 | CONFIG_HWMON_VID=m | 1510 | CONFIG_HWMON_VID=m |
1496 | # CONFIG_HWMON_DEBUG_CHIP is not set | 1511 | # CONFIG_HWMON_DEBUG_CHIP is not set |
@@ -1607,7 +1622,7 @@ CONFIG_MFD_SM501=y | |||
1607 | # CONFIG_HTC_PASIC3 is not set | 1622 | # CONFIG_HTC_PASIC3 is not set |
1608 | # CONFIG_HTC_I2CPLD is not set | 1623 | # CONFIG_HTC_I2CPLD is not set |
1609 | # CONFIG_UCB1400_CORE is not set | 1624 | # CONFIG_UCB1400_CORE is not set |
1610 | # CONFIG_TPS65010 is not set | 1625 | CONFIG_TPS65010=m |
1611 | # CONFIG_TWL4030_CORE is not set | 1626 | # CONFIG_TWL4030_CORE is not set |
1612 | # CONFIG_MFD_TMIO is not set | 1627 | # CONFIG_MFD_TMIO is not set |
1613 | # CONFIG_MFD_T7L66XB is not set | 1628 | # CONFIG_MFD_T7L66XB is not set |
@@ -1620,8 +1635,10 @@ CONFIG_MFD_SM501=y | |||
1620 | # CONFIG_MFD_WM831X is not set | 1635 | # CONFIG_MFD_WM831X is not set |
1621 | # CONFIG_MFD_WM8350_I2C is not set | 1636 | # CONFIG_MFD_WM8350_I2C is not set |
1622 | # CONFIG_MFD_WM8994 is not set | 1637 | # CONFIG_MFD_WM8994 is not set |
1623 | # CONFIG_MFD_PCF50633 is not set | 1638 | CONFIG_MFD_PCF50633=y |
1624 | # CONFIG_MFD_MC13783 is not set | 1639 | # CONFIG_MFD_MC13783 is not set |
1640 | # CONFIG_PCF50633_ADC is not set | ||
1641 | CONFIG_PCF50633_GPIO=y | ||
1625 | # CONFIG_AB3100_CORE is not set | 1642 | # CONFIG_AB3100_CORE is not set |
1626 | # CONFIG_EZX_PCAP is not set | 1643 | # CONFIG_EZX_PCAP is not set |
1627 | # CONFIG_AB4500_CORE is not set | 1644 | # CONFIG_AB4500_CORE is not set |
@@ -1737,6 +1754,7 @@ CONFIG_SND_S3C24XX_SOC_I2S=y | |||
1737 | CONFIG_SND_S3C_I2SV2_SOC=m | 1754 | CONFIG_SND_S3C_I2SV2_SOC=m |
1738 | CONFIG_SND_S3C2412_SOC_I2S=m | 1755 | CONFIG_SND_S3C2412_SOC_I2S=m |
1739 | CONFIG_SND_S3C_SOC_AC97=m | 1756 | CONFIG_SND_S3C_SOC_AC97=m |
1757 | # CONFIG_SND_S3C24XX_SOC_NEO1973_GTA02_WM8753 is not set | ||
1740 | CONFIG_SND_S3C24XX_SOC_JIVE_WM8750=m | 1758 | CONFIG_SND_S3C24XX_SOC_JIVE_WM8750=m |
1741 | CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710=m | 1759 | CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710=m |
1742 | CONFIG_SND_S3C24XX_SOC_LN2440SBC_ALC650=m | 1760 | CONFIG_SND_S3C24XX_SOC_LN2440SBC_ALC650=m |
@@ -2045,6 +2063,7 @@ CONFIG_RTC_INTF_DEV=y | |||
2045 | # CONFIG_RTC_DRV_BQ4802 is not set | 2063 | # CONFIG_RTC_DRV_BQ4802 is not set |
2046 | # CONFIG_RTC_DRV_RP5C01 is not set | 2064 | # CONFIG_RTC_DRV_RP5C01 is not set |
2047 | # CONFIG_RTC_DRV_V3020 is not set | 2065 | # CONFIG_RTC_DRV_V3020 is not set |
2066 | # CONFIG_RTC_DRV_PCF50633 is not set | ||
2048 | 2067 | ||
2049 | # | 2068 | # |
2050 | # on-CPU RTC drivers | 2069 | # on-CPU RTC drivers |
diff --git a/arch/arm/configs/s3c6400_defconfig b/arch/arm/configs/s3c6400_defconfig index 7d8b4cf3858c..2b642386f030 100644 --- a/arch/arm/configs/s3c6400_defconfig +++ b/arch/arm/configs/s3c6400_defconfig | |||
@@ -1,9 +1,10 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.34 | 3 | # Linux kernel version: 2.6.34 |
4 | # Wed May 26 19:04:30 2010 | 4 | # Fri May 28 19:05:39 2010 |
5 | # | 5 | # |
6 | CONFIG_ARM=y | 6 | CONFIG_ARM=y |
7 | CONFIG_HAVE_PWM=y | ||
7 | CONFIG_SYS_SUPPORTS_APM_EMULATION=y | 8 | CONFIG_SYS_SUPPORTS_APM_EMULATION=y |
8 | CONFIG_GENERIC_GPIO=y | 9 | CONFIG_GENERIC_GPIO=y |
9 | CONFIG_GENERIC_TIME=y | 10 | CONFIG_GENERIC_TIME=y |
@@ -253,12 +254,15 @@ CONFIG_S3C_GPIO_TRACK=y | |||
253 | # CONFIG_S3C_ADC is not set | 254 | # CONFIG_S3C_ADC is not set |
254 | CONFIG_S3C_DEV_HSMMC=y | 255 | CONFIG_S3C_DEV_HSMMC=y |
255 | CONFIG_S3C_DEV_HSMMC1=y | 256 | CONFIG_S3C_DEV_HSMMC1=y |
257 | CONFIG_S3C_DEV_HSMMC2=y | ||
258 | CONFIG_S3C_DEV_HWMON=y | ||
256 | CONFIG_S3C_DEV_I2C1=y | 259 | CONFIG_S3C_DEV_I2C1=y |
257 | CONFIG_S3C_DEV_FB=y | 260 | CONFIG_S3C_DEV_FB=y |
258 | CONFIG_S3C_DEV_USB_HOST=y | 261 | CONFIG_S3C_DEV_USB_HOST=y |
259 | CONFIG_S3C_DEV_USB_HSOTG=y | 262 | CONFIG_S3C_DEV_USB_HSOTG=y |
260 | CONFIG_S3C_DEV_WDT=y | 263 | CONFIG_S3C_DEV_WDT=y |
261 | CONFIG_S3C_DEV_NAND=y | 264 | CONFIG_S3C_DEV_NAND=y |
265 | CONFIG_S3C_DEV_RTC=y | ||
262 | CONFIG_SAMSUNG_DEV_ADC=y | 266 | CONFIG_SAMSUNG_DEV_ADC=y |
263 | CONFIG_SAMSUNG_DEV_TS=y | 267 | CONFIG_SAMSUNG_DEV_TS=y |
264 | CONFIG_S3C_DMA=y | 268 | CONFIG_S3C_DMA=y |
@@ -271,6 +275,7 @@ CONFIG_S3C_DMA=y | |||
271 | # CONFIG_SAMSUNG_PM_CHECK is not set | 275 | # CONFIG_SAMSUNG_PM_CHECK is not set |
272 | CONFIG_SAMSUNG_WAKEMASK=y | 276 | CONFIG_SAMSUNG_WAKEMASK=y |
273 | CONFIG_PLAT_S3C64XX=y | 277 | CONFIG_PLAT_S3C64XX=y |
278 | CONFIG_CPU_S3C6400=y | ||
274 | CONFIG_CPU_S3C6410=y | 279 | CONFIG_CPU_S3C6410=y |
275 | CONFIG_S3C64XX_DMA=y | 280 | CONFIG_S3C64XX_DMA=y |
276 | CONFIG_S3C64XX_SETUP_SDHCI=y | 281 | CONFIG_S3C64XX_SETUP_SDHCI=y |
@@ -278,17 +283,18 @@ CONFIG_S3C64XX_SETUP_I2C0=y | |||
278 | CONFIG_S3C64XX_SETUP_I2C1=y | 283 | CONFIG_S3C64XX_SETUP_I2C1=y |
279 | CONFIG_S3C64XX_SETUP_FB_24BPP=y | 284 | CONFIG_S3C64XX_SETUP_FB_24BPP=y |
280 | CONFIG_S3C64XX_SETUP_SDHCI_GPIO=y | 285 | CONFIG_S3C64XX_SETUP_SDHCI_GPIO=y |
281 | # CONFIG_MACH_SMDK6400 is not set | 286 | CONFIG_MACH_SMDK6400=y |
282 | # CONFIG_MACH_ANW6410 is not set | 287 | CONFIG_MACH_ANW6410=y |
283 | CONFIG_MACH_SMDK6410=y | 288 | CONFIG_MACH_SMDK6410=y |
284 | CONFIG_SMDK6410_SD_CH0=y | 289 | CONFIG_SMDK6410_SD_CH0=y |
285 | # CONFIG_SMDK6410_SD_CH1 is not set | 290 | # CONFIG_SMDK6410_SD_CH1 is not set |
286 | # CONFIG_SMDK6410_WM1190_EV1 is not set | 291 | # CONFIG_SMDK6410_WM1190_EV1 is not set |
287 | # CONFIG_SMDK6410_WM1192_EV1 is not set | 292 | # CONFIG_SMDK6410_WM1192_EV1 is not set |
288 | # CONFIG_MACH_NCP is not set | 293 | CONFIG_MACH_NCP=y |
289 | # CONFIG_MACH_HMT is not set | 294 | CONFIG_MACH_HMT=y |
290 | # CONFIG_MACH_SMARTQ5 is not set | 295 | CONFIG_MACH_SMARTQ=y |
291 | # CONFIG_MACH_SMARTQ7 is not set | 296 | CONFIG_MACH_SMARTQ5=y |
297 | CONFIG_MACH_SMARTQ7=y | ||
292 | 298 | ||
293 | # | 299 | # |
294 | # Processor Type | 300 | # Processor Type |
@@ -475,6 +481,9 @@ CONFIG_MTD_CFI_I2=y | |||
475 | # | 481 | # |
476 | # Self-contained MTD device drivers | 482 | # Self-contained MTD device drivers |
477 | # | 483 | # |
484 | # CONFIG_MTD_DATAFLASH is not set | ||
485 | # CONFIG_MTD_M25P80 is not set | ||
486 | # CONFIG_MTD_SST25L is not set | ||
478 | # CONFIG_MTD_SLRAM is not set | 487 | # CONFIG_MTD_SLRAM is not set |
479 | # CONFIG_MTD_PHRAM is not set | 488 | # CONFIG_MTD_PHRAM is not set |
480 | # CONFIG_MTD_MTDRAM is not set | 489 | # CONFIG_MTD_MTDRAM is not set |
@@ -501,6 +510,7 @@ CONFIG_MTD_NAND_S3C2410=y | |||
501 | # CONFIG_MTD_NAND_S3C2410_CLKSTOP is not set | 510 | # CONFIG_MTD_NAND_S3C2410_CLKSTOP is not set |
502 | # CONFIG_MTD_NAND_DISKONCHIP is not set | 511 | # CONFIG_MTD_NAND_DISKONCHIP is not set |
503 | # CONFIG_MTD_NAND_PLATFORM is not set | 512 | # CONFIG_MTD_NAND_PLATFORM is not set |
513 | # CONFIG_MTD_ALAUDA is not set | ||
504 | # CONFIG_MTD_ONENAND is not set | 514 | # CONFIG_MTD_ONENAND is not set |
505 | 515 | ||
506 | # | 516 | # |
@@ -521,6 +531,7 @@ CONFIG_BLK_DEV_LOOP=y | |||
521 | # | 531 | # |
522 | # DRBD disabled because PROC_FS, INET or CONNECTOR not selected | 532 | # DRBD disabled because PROC_FS, INET or CONNECTOR not selected |
523 | # | 533 | # |
534 | # CONFIG_BLK_DEV_UB is not set | ||
524 | CONFIG_BLK_DEV_RAM=y | 535 | CONFIG_BLK_DEV_RAM=y |
525 | CONFIG_BLK_DEV_RAM_COUNT=16 | 536 | CONFIG_BLK_DEV_RAM_COUNT=16 |
526 | CONFIG_BLK_DEV_RAM_SIZE=4096 | 537 | CONFIG_BLK_DEV_RAM_SIZE=4096 |
@@ -534,12 +545,14 @@ CONFIG_MISC_DEVICES=y | |||
534 | # CONFIG_ISL29003 is not set | 545 | # CONFIG_ISL29003 is not set |
535 | # CONFIG_SENSORS_TSL2550 is not set | 546 | # CONFIG_SENSORS_TSL2550 is not set |
536 | # CONFIG_DS1682 is not set | 547 | # CONFIG_DS1682 is not set |
548 | # CONFIG_TI_DAC7512 is not set | ||
537 | # CONFIG_C2PORT is not set | 549 | # CONFIG_C2PORT is not set |
538 | 550 | ||
539 | # | 551 | # |
540 | # EEPROM support | 552 | # EEPROM support |
541 | # | 553 | # |
542 | CONFIG_EEPROM_AT24=y | 554 | CONFIG_EEPROM_AT24=y |
555 | # CONFIG_EEPROM_AT25 is not set | ||
543 | # CONFIG_EEPROM_LEGACY is not set | 556 | # CONFIG_EEPROM_LEGACY is not set |
544 | # CONFIG_EEPROM_MAX6875 is not set | 557 | # CONFIG_EEPROM_MAX6875 is not set |
545 | # CONFIG_EEPROM_93CX6 is not set | 558 | # CONFIG_EEPROM_93CX6 is not set |
@@ -654,6 +667,7 @@ CONFIG_SERIAL_SAMSUNG_UARTS=4 | |||
654 | # CONFIG_SERIAL_SAMSUNG_DEBUG is not set | 667 | # CONFIG_SERIAL_SAMSUNG_DEBUG is not set |
655 | CONFIG_SERIAL_SAMSUNG_CONSOLE=y | 668 | CONFIG_SERIAL_SAMSUNG_CONSOLE=y |
656 | CONFIG_SERIAL_S3C6400=y | 669 | CONFIG_SERIAL_S3C6400=y |
670 | # CONFIG_SERIAL_MAX3100 is not set | ||
657 | CONFIG_SERIAL_CORE=y | 671 | CONFIG_SERIAL_CORE=y |
658 | CONFIG_SERIAL_CORE_CONSOLE=y | 672 | CONFIG_SERIAL_CORE_CONSOLE=y |
659 | # CONFIG_SERIAL_TIMBERDALE is not set | 673 | # CONFIG_SERIAL_TIMBERDALE is not set |
@@ -694,6 +708,7 @@ CONFIG_I2C_S3C2410=y | |||
694 | # | 708 | # |
695 | # CONFIG_I2C_PARPORT_LIGHT is not set | 709 | # CONFIG_I2C_PARPORT_LIGHT is not set |
696 | # CONFIG_I2C_TAOS_EVM is not set | 710 | # CONFIG_I2C_TAOS_EVM is not set |
711 | # CONFIG_I2C_TINY_USB is not set | ||
697 | 712 | ||
698 | # | 713 | # |
699 | # Other I2C/SMBus bus drivers | 714 | # Other I2C/SMBus bus drivers |
@@ -703,7 +718,24 @@ CONFIG_I2C_S3C2410=y | |||
703 | # CONFIG_I2C_DEBUG_CORE is not set | 718 | # CONFIG_I2C_DEBUG_CORE is not set |
704 | # CONFIG_I2C_DEBUG_ALGO is not set | 719 | # CONFIG_I2C_DEBUG_ALGO is not set |
705 | # CONFIG_I2C_DEBUG_BUS is not set | 720 | # CONFIG_I2C_DEBUG_BUS is not set |
706 | # CONFIG_SPI is not set | 721 | CONFIG_SPI=y |
722 | # CONFIG_SPI_DEBUG is not set | ||
723 | CONFIG_SPI_MASTER=y | ||
724 | |||
725 | # | ||
726 | # SPI Master Controller Drivers | ||
727 | # | ||
728 | CONFIG_SPI_BITBANG=m | ||
729 | CONFIG_SPI_GPIO=m | ||
730 | CONFIG_SPI_S3C64XX=m | ||
731 | # CONFIG_SPI_XILINX is not set | ||
732 | # CONFIG_SPI_DESIGNWARE is not set | ||
733 | |||
734 | # | ||
735 | # SPI Protocol Masters | ||
736 | # | ||
737 | # CONFIG_SPI_SPIDEV is not set | ||
738 | # CONFIG_SPI_TLE62X0 is not set | ||
707 | 739 | ||
708 | # | 740 | # |
709 | # PPS support | 741 | # PPS support |
@@ -735,6 +767,9 @@ CONFIG_GPIOLIB=y | |||
735 | # | 767 | # |
736 | # SPI GPIO expanders: | 768 | # SPI GPIO expanders: |
737 | # | 769 | # |
770 | # CONFIG_GPIO_MAX7301 is not set | ||
771 | # CONFIG_GPIO_MCP23S08 is not set | ||
772 | # CONFIG_GPIO_MC33880 is not set | ||
738 | 773 | ||
739 | # | 774 | # |
740 | # AC97 GPIO expanders: | 775 | # AC97 GPIO expanders: |
@@ -750,6 +785,7 @@ CONFIG_HWMON=y | |||
750 | # | 785 | # |
751 | # CONFIG_SENSORS_AD7414 is not set | 786 | # CONFIG_SENSORS_AD7414 is not set |
752 | # CONFIG_SENSORS_AD7418 is not set | 787 | # CONFIG_SENSORS_AD7418 is not set |
788 | # CONFIG_SENSORS_ADCXX is not set | ||
753 | # CONFIG_SENSORS_ADM1021 is not set | 789 | # CONFIG_SENSORS_ADM1021 is not set |
754 | # CONFIG_SENSORS_ADM1025 is not set | 790 | # CONFIG_SENSORS_ADM1025 is not set |
755 | # CONFIG_SENSORS_ADM1026 is not set | 791 | # CONFIG_SENSORS_ADM1026 is not set |
@@ -771,6 +807,7 @@ CONFIG_HWMON=y | |||
771 | # CONFIG_SENSORS_GL520SM is not set | 807 | # CONFIG_SENSORS_GL520SM is not set |
772 | # CONFIG_SENSORS_IT87 is not set | 808 | # CONFIG_SENSORS_IT87 is not set |
773 | # CONFIG_SENSORS_LM63 is not set | 809 | # CONFIG_SENSORS_LM63 is not set |
810 | # CONFIG_SENSORS_LM70 is not set | ||
774 | # CONFIG_SENSORS_LM73 is not set | 811 | # CONFIG_SENSORS_LM73 is not set |
775 | # CONFIG_SENSORS_LM75 is not set | 812 | # CONFIG_SENSORS_LM75 is not set |
776 | # CONFIG_SENSORS_LM77 is not set | 813 | # CONFIG_SENSORS_LM77 is not set |
@@ -785,6 +822,7 @@ CONFIG_HWMON=y | |||
785 | # CONFIG_SENSORS_LTC4215 is not set | 822 | # CONFIG_SENSORS_LTC4215 is not set |
786 | # CONFIG_SENSORS_LTC4245 is not set | 823 | # CONFIG_SENSORS_LTC4245 is not set |
787 | # CONFIG_SENSORS_LM95241 is not set | 824 | # CONFIG_SENSORS_LM95241 is not set |
825 | # CONFIG_SENSORS_MAX1111 is not set | ||
788 | # CONFIG_SENSORS_MAX1619 is not set | 826 | # CONFIG_SENSORS_MAX1619 is not set |
789 | # CONFIG_SENSORS_MAX6650 is not set | 827 | # CONFIG_SENSORS_MAX6650 is not set |
790 | # CONFIG_SENSORS_PC87360 is not set | 828 | # CONFIG_SENSORS_PC87360 is not set |
@@ -796,6 +834,7 @@ CONFIG_HWMON=y | |||
796 | # CONFIG_SENSORS_SMSC47M192 is not set | 834 | # CONFIG_SENSORS_SMSC47M192 is not set |
797 | # CONFIG_SENSORS_SMSC47B397 is not set | 835 | # CONFIG_SENSORS_SMSC47B397 is not set |
798 | # CONFIG_SENSORS_ADS7828 is not set | 836 | # CONFIG_SENSORS_ADS7828 is not set |
837 | # CONFIG_SENSORS_ADS7871 is not set | ||
799 | # CONFIG_SENSORS_AMC6821 is not set | 838 | # CONFIG_SENSORS_AMC6821 is not set |
800 | # CONFIG_SENSORS_THMC50 is not set | 839 | # CONFIG_SENSORS_THMC50 is not set |
801 | # CONFIG_SENSORS_TMP401 is not set | 840 | # CONFIG_SENSORS_TMP401 is not set |
@@ -809,6 +848,7 @@ CONFIG_HWMON=y | |||
809 | # CONFIG_SENSORS_W83L786NG is not set | 848 | # CONFIG_SENSORS_W83L786NG is not set |
810 | # CONFIG_SENSORS_W83627HF is not set | 849 | # CONFIG_SENSORS_W83627HF is not set |
811 | # CONFIG_SENSORS_W83627EHF is not set | 850 | # CONFIG_SENSORS_W83627EHF is not set |
851 | # CONFIG_SENSORS_LIS3_SPI is not set | ||
812 | # CONFIG_SENSORS_LIS3_I2C is not set | 852 | # CONFIG_SENSORS_LIS3_I2C is not set |
813 | # CONFIG_THERMAL is not set | 853 | # CONFIG_THERMAL is not set |
814 | # CONFIG_WATCHDOG is not set | 854 | # CONFIG_WATCHDOG is not set |
@@ -845,7 +885,10 @@ CONFIG_SSB_POSSIBLE=y | |||
845 | # CONFIG_MFD_WM8350_I2C is not set | 885 | # CONFIG_MFD_WM8350_I2C is not set |
846 | # CONFIG_MFD_WM8994 is not set | 886 | # CONFIG_MFD_WM8994 is not set |
847 | # CONFIG_MFD_PCF50633 is not set | 887 | # CONFIG_MFD_PCF50633 is not set |
888 | # CONFIG_MFD_MC13783 is not set | ||
848 | # CONFIG_AB3100_CORE is not set | 889 | # CONFIG_AB3100_CORE is not set |
890 | # CONFIG_EZX_PCAP is not set | ||
891 | # CONFIG_AB4500_CORE is not set | ||
849 | # CONFIG_REGULATOR is not set | 892 | # CONFIG_REGULATOR is not set |
850 | # CONFIG_MEDIA_SUPPORT is not set | 893 | # CONFIG_MEDIA_SUPPORT is not set |
851 | 894 | ||
@@ -854,8 +897,47 @@ CONFIG_SSB_POSSIBLE=y | |||
854 | # | 897 | # |
855 | # CONFIG_VGASTATE is not set | 898 | # CONFIG_VGASTATE is not set |
856 | # CONFIG_VIDEO_OUTPUT_CONTROL is not set | 899 | # CONFIG_VIDEO_OUTPUT_CONTROL is not set |
857 | # CONFIG_FB is not set | 900 | CONFIG_FB=y |
858 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set | 901 | # CONFIG_FIRMWARE_EDID is not set |
902 | # CONFIG_FB_DDC is not set | ||
903 | # CONFIG_FB_BOOT_VESA_SUPPORT is not set | ||
904 | CONFIG_FB_CFB_FILLRECT=y | ||
905 | CONFIG_FB_CFB_COPYAREA=y | ||
906 | CONFIG_FB_CFB_IMAGEBLIT=y | ||
907 | # CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set | ||
908 | # CONFIG_FB_SYS_FILLRECT is not set | ||
909 | # CONFIG_FB_SYS_COPYAREA is not set | ||
910 | # CONFIG_FB_SYS_IMAGEBLIT is not set | ||
911 | # CONFIG_FB_FOREIGN_ENDIAN is not set | ||
912 | # CONFIG_FB_SYS_FOPS is not set | ||
913 | # CONFIG_FB_SVGALIB is not set | ||
914 | # CONFIG_FB_MACMODES is not set | ||
915 | # CONFIG_FB_BACKLIGHT is not set | ||
916 | # CONFIG_FB_MODE_HELPERS is not set | ||
917 | # CONFIG_FB_TILEBLITTING is not set | ||
918 | |||
919 | # | ||
920 | # Frame buffer hardware drivers | ||
921 | # | ||
922 | # CONFIG_FB_S1D13XXX is not set | ||
923 | CONFIG_FB_S3C=y | ||
924 | # CONFIG_FB_S3C_DEBUG_REGWRITE is not set | ||
925 | # CONFIG_FB_VIRTUAL is not set | ||
926 | # CONFIG_FB_METRONOME is not set | ||
927 | # CONFIG_FB_MB862XX is not set | ||
928 | # CONFIG_FB_BROADSHEET is not set | ||
929 | CONFIG_BACKLIGHT_LCD_SUPPORT=y | ||
930 | CONFIG_LCD_CLASS_DEVICE=y | ||
931 | # CONFIG_LCD_L4F00242T03 is not set | ||
932 | # CONFIG_LCD_LMS283GF05 is not set | ||
933 | CONFIG_LCD_LTV350QV=y | ||
934 | # CONFIG_LCD_ILI9320 is not set | ||
935 | # CONFIG_LCD_TDO24M is not set | ||
936 | # CONFIG_LCD_VGG2432A4 is not set | ||
937 | # CONFIG_LCD_PLATFORM is not set | ||
938 | CONFIG_BACKLIGHT_CLASS_DEVICE=y | ||
939 | CONFIG_BACKLIGHT_GENERIC=y | ||
940 | CONFIG_BACKLIGHT_PWM=y | ||
859 | 941 | ||
860 | # | 942 | # |
861 | # Display device support | 943 | # Display device support |
@@ -867,6 +949,8 @@ CONFIG_SSB_POSSIBLE=y | |||
867 | # | 949 | # |
868 | # CONFIG_VGA_CONSOLE is not set | 950 | # CONFIG_VGA_CONSOLE is not set |
869 | CONFIG_DUMMY_CONSOLE=y | 951 | CONFIG_DUMMY_CONSOLE=y |
952 | # CONFIG_FRAMEBUFFER_CONSOLE is not set | ||
953 | # CONFIG_LOGO is not set | ||
870 | CONFIG_SOUND=y | 954 | CONFIG_SOUND=y |
871 | CONFIG_SOUND_OSS_CORE=y | 955 | CONFIG_SOUND_OSS_CORE=y |
872 | CONFIG_SOUND_OSS_CORE_PRECLAIM=y | 956 | CONFIG_SOUND_OSS_CORE_PRECLAIM=y |
@@ -895,6 +979,11 @@ CONFIG_SND_DRIVERS=y | |||
895 | # CONFIG_SND_SERIAL_U16550 is not set | 979 | # CONFIG_SND_SERIAL_U16550 is not set |
896 | # CONFIG_SND_MPU401 is not set | 980 | # CONFIG_SND_MPU401 is not set |
897 | CONFIG_SND_ARM=y | 981 | CONFIG_SND_ARM=y |
982 | CONFIG_SND_SPI=y | ||
983 | CONFIG_SND_USB=y | ||
984 | # CONFIG_SND_USB_AUDIO is not set | ||
985 | # CONFIG_SND_USB_UA101 is not set | ||
986 | # CONFIG_SND_USB_CAIAQ is not set | ||
898 | CONFIG_SND_SOC=m | 987 | CONFIG_SND_SOC=m |
899 | CONFIG_SND_SOC_AC97_BUS=y | 988 | CONFIG_SND_SOC_AC97_BUS=y |
900 | CONFIG_SND_S3C24XX_SOC=m | 989 | CONFIG_SND_S3C24XX_SOC=m |
@@ -909,29 +998,197 @@ CONFIG_AC97_BUS=m | |||
909 | CONFIG_HID_SUPPORT=y | 998 | CONFIG_HID_SUPPORT=y |
910 | CONFIG_HID=y | 999 | CONFIG_HID=y |
911 | # CONFIG_HIDRAW is not set | 1000 | # CONFIG_HIDRAW is not set |
1001 | |||
1002 | # | ||
1003 | # USB Input Devices | ||
1004 | # | ||
1005 | CONFIG_USB_HID=y | ||
912 | # CONFIG_HID_PID is not set | 1006 | # CONFIG_HID_PID is not set |
1007 | # CONFIG_USB_HIDDEV is not set | ||
913 | 1008 | ||
914 | # | 1009 | # |
915 | # Special HID drivers | 1010 | # Special HID drivers |
916 | # | 1011 | # |
1012 | # CONFIG_HID_3M_PCT is not set | ||
1013 | CONFIG_HID_A4TECH=y | ||
1014 | CONFIG_HID_APPLE=y | ||
1015 | CONFIG_HID_BELKIN=y | ||
1016 | # CONFIG_HID_CANDO is not set | ||
1017 | CONFIG_HID_CHERRY=y | ||
1018 | CONFIG_HID_CHICONY=y | ||
1019 | # CONFIG_HID_PRODIKEYS is not set | ||
1020 | CONFIG_HID_CYPRESS=y | ||
1021 | # CONFIG_HID_DRAGONRISE is not set | ||
1022 | # CONFIG_HID_EGALAX is not set | ||
1023 | CONFIG_HID_EZKEY=y | ||
1024 | CONFIG_HID_KYE=y | ||
1025 | # CONFIG_HID_GYRATION is not set | ||
1026 | # CONFIG_HID_TWINHAN is not set | ||
1027 | CONFIG_HID_KENSINGTON=y | ||
1028 | CONFIG_HID_LOGITECH=y | ||
1029 | # CONFIG_LOGITECH_FF is not set | ||
1030 | # CONFIG_LOGIRUMBLEPAD2_FF is not set | ||
1031 | # CONFIG_LOGIG940_FF is not set | ||
1032 | CONFIG_HID_MICROSOFT=y | ||
1033 | # CONFIG_HID_MOSART is not set | ||
1034 | CONFIG_HID_MONTEREY=y | ||
1035 | # CONFIG_HID_NTRIG is not set | ||
1036 | # CONFIG_HID_ORTEK is not set | ||
1037 | # CONFIG_HID_PANTHERLORD is not set | ||
1038 | # CONFIG_HID_PETALYNX is not set | ||
1039 | # CONFIG_HID_PICOLCD is not set | ||
1040 | # CONFIG_HID_QUANTA is not set | ||
1041 | # CONFIG_HID_ROCCAT_KONE is not set | ||
1042 | # CONFIG_HID_SAMSUNG is not set | ||
1043 | # CONFIG_HID_SONY is not set | ||
1044 | # CONFIG_HID_STANTUM is not set | ||
1045 | # CONFIG_HID_SUNPLUS is not set | ||
1046 | # CONFIG_HID_GREENASIA is not set | ||
1047 | # CONFIG_HID_SMARTJOYPLUS is not set | ||
1048 | # CONFIG_HID_TOPSEED is not set | ||
1049 | # CONFIG_HID_THRUSTMASTER is not set | ||
1050 | # CONFIG_HID_ZEROPLUS is not set | ||
1051 | # CONFIG_HID_ZYDACRON is not set | ||
917 | CONFIG_USB_SUPPORT=y | 1052 | CONFIG_USB_SUPPORT=y |
918 | CONFIG_USB_ARCH_HAS_HCD=y | 1053 | CONFIG_USB_ARCH_HAS_HCD=y |
919 | CONFIG_USB_ARCH_HAS_OHCI=y | 1054 | CONFIG_USB_ARCH_HAS_OHCI=y |
920 | # CONFIG_USB_ARCH_HAS_EHCI is not set | 1055 | # CONFIG_USB_ARCH_HAS_EHCI is not set |
921 | # CONFIG_USB is not set | 1056 | CONFIG_USB=y |
1057 | # CONFIG_USB_DEBUG is not set | ||
1058 | CONFIG_USB_ANNOUNCE_NEW_DEVICES=y | ||
922 | 1059 | ||
923 | # | 1060 | # |
924 | # Enable Host or Gadget support to see Inventra options | 1061 | # Miscellaneous USB options |
925 | # | 1062 | # |
1063 | CONFIG_USB_DEVICEFS=y | ||
1064 | CONFIG_USB_DEVICE_CLASS=y | ||
1065 | # CONFIG_USB_DYNAMIC_MINORS is not set | ||
1066 | # CONFIG_USB_MON is not set | ||
1067 | # CONFIG_USB_WUSB is not set | ||
1068 | # CONFIG_USB_WUSB_CBAF is not set | ||
1069 | |||
1070 | # | ||
1071 | # USB Host Controller Drivers | ||
1072 | # | ||
1073 | # CONFIG_USB_C67X00_HCD is not set | ||
1074 | # CONFIG_USB_OXU210HP_HCD is not set | ||
1075 | # CONFIG_USB_ISP116X_HCD is not set | ||
1076 | # CONFIG_USB_ISP1760_HCD is not set | ||
1077 | # CONFIG_USB_ISP1362_HCD is not set | ||
1078 | CONFIG_USB_OHCI_HCD=y | ||
1079 | # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set | ||
1080 | # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set | ||
1081 | CONFIG_USB_OHCI_LITTLE_ENDIAN=y | ||
1082 | # CONFIG_USB_SL811_HCD is not set | ||
1083 | # CONFIG_USB_R8A66597_HCD is not set | ||
1084 | # CONFIG_USB_HWA_HCD is not set | ||
1085 | # CONFIG_USB_MUSB_HDRC is not set | ||
1086 | |||
1087 | # | ||
1088 | # USB Device Class drivers | ||
1089 | # | ||
1090 | CONFIG_USB_ACM=m | ||
1091 | CONFIG_USB_PRINTER=m | ||
1092 | # CONFIG_USB_WDM is not set | ||
1093 | # CONFIG_USB_TMC is not set | ||
926 | 1094 | ||
927 | # | 1095 | # |
928 | # NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may | 1096 | # NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may |
929 | # | 1097 | # |
1098 | |||
1099 | # | ||
1100 | # also be needed; see USB_STORAGE Help for more info | ||
1101 | # | ||
1102 | # CONFIG_USB_LIBUSUAL is not set | ||
1103 | |||
1104 | # | ||
1105 | # USB Imaging devices | ||
1106 | # | ||
1107 | # CONFIG_USB_MDC800 is not set | ||
1108 | |||
1109 | # | ||
1110 | # USB port drivers | ||
1111 | # | ||
1112 | CONFIG_USB_SERIAL=m | ||
1113 | # CONFIG_USB_EZUSB is not set | ||
1114 | CONFIG_USB_SERIAL_GENERIC=y | ||
1115 | # CONFIG_USB_SERIAL_AIRCABLE is not set | ||
1116 | # CONFIG_USB_SERIAL_ARK3116 is not set | ||
1117 | # CONFIG_USB_SERIAL_BELKIN is not set | ||
1118 | # CONFIG_USB_SERIAL_CH341 is not set | ||
1119 | # CONFIG_USB_SERIAL_WHITEHEAT is not set | ||
1120 | # CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set | ||
1121 | # CONFIG_USB_SERIAL_CP210X is not set | ||
1122 | # CONFIG_USB_SERIAL_CYPRESS_M8 is not set | ||
1123 | CONFIG_USB_SERIAL_EMPEG=m | ||
1124 | CONFIG_USB_SERIAL_FTDI_SIO=m | ||
1125 | # CONFIG_USB_SERIAL_FUNSOFT is not set | ||
1126 | # CONFIG_USB_SERIAL_VISOR is not set | ||
1127 | # CONFIG_USB_SERIAL_IPAQ is not set | ||
1128 | # CONFIG_USB_SERIAL_IR is not set | ||
1129 | # CONFIG_USB_SERIAL_EDGEPORT is not set | ||
1130 | # CONFIG_USB_SERIAL_EDGEPORT_TI is not set | ||
1131 | # CONFIG_USB_SERIAL_GARMIN is not set | ||
1132 | # CONFIG_USB_SERIAL_IPW is not set | ||
1133 | # CONFIG_USB_SERIAL_IUU is not set | ||
1134 | # CONFIG_USB_SERIAL_KEYSPAN_PDA is not set | ||
1135 | # CONFIG_USB_SERIAL_KEYSPAN is not set | ||
1136 | # CONFIG_USB_SERIAL_KLSI is not set | ||
1137 | # CONFIG_USB_SERIAL_KOBIL_SCT is not set | ||
1138 | # CONFIG_USB_SERIAL_MCT_U232 is not set | ||
1139 | # CONFIG_USB_SERIAL_MOS7720 is not set | ||
1140 | # CONFIG_USB_SERIAL_MOS7840 is not set | ||
1141 | # CONFIG_USB_SERIAL_MOTOROLA is not set | ||
1142 | # CONFIG_USB_SERIAL_NAVMAN is not set | ||
1143 | CONFIG_USB_SERIAL_PL2303=m | ||
1144 | # CONFIG_USB_SERIAL_OTI6858 is not set | ||
1145 | # CONFIG_USB_SERIAL_QCAUX is not set | ||
1146 | # CONFIG_USB_SERIAL_QUALCOMM is not set | ||
1147 | # CONFIG_USB_SERIAL_SPCP8X5 is not set | ||
1148 | # CONFIG_USB_SERIAL_HP4X is not set | ||
1149 | # CONFIG_USB_SERIAL_SAFE is not set | ||
1150 | # CONFIG_USB_SERIAL_SIEMENS_MPI is not set | ||
1151 | # CONFIG_USB_SERIAL_SIERRAWIRELESS is not set | ||
1152 | # CONFIG_USB_SERIAL_SYMBOL is not set | ||
1153 | # CONFIG_USB_SERIAL_TI is not set | ||
1154 | # CONFIG_USB_SERIAL_CYBERJACK is not set | ||
1155 | # CONFIG_USB_SERIAL_XIRCOM is not set | ||
1156 | # CONFIG_USB_SERIAL_OPTION is not set | ||
1157 | # CONFIG_USB_SERIAL_OMNINET is not set | ||
1158 | # CONFIG_USB_SERIAL_OPTICON is not set | ||
1159 | # CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set | ||
1160 | # CONFIG_USB_SERIAL_ZIO is not set | ||
1161 | # CONFIG_USB_SERIAL_DEBUG is not set | ||
1162 | |||
1163 | # | ||
1164 | # USB Miscellaneous drivers | ||
1165 | # | ||
1166 | # CONFIG_USB_EMI62 is not set | ||
1167 | # CONFIG_USB_EMI26 is not set | ||
1168 | # CONFIG_USB_ADUTUX is not set | ||
1169 | # CONFIG_USB_SEVSEG is not set | ||
1170 | # CONFIG_USB_RIO500 is not set | ||
1171 | # CONFIG_USB_LEGOTOWER is not set | ||
1172 | # CONFIG_USB_LCD is not set | ||
1173 | # CONFIG_USB_LED is not set | ||
1174 | # CONFIG_USB_CYPRESS_CY7C63 is not set | ||
1175 | # CONFIG_USB_CYTHERM is not set | ||
1176 | # CONFIG_USB_IDMOUSE is not set | ||
1177 | # CONFIG_USB_FTDI_ELAN is not set | ||
1178 | # CONFIG_USB_APPLEDISPLAY is not set | ||
1179 | # CONFIG_USB_LD is not set | ||
1180 | # CONFIG_USB_TRANCEVIBRATOR is not set | ||
1181 | # CONFIG_USB_IOWARRIOR is not set | ||
1182 | # CONFIG_USB_TEST is not set | ||
1183 | # CONFIG_USB_ISIGHTFW is not set | ||
930 | # CONFIG_USB_GADGET is not set | 1184 | # CONFIG_USB_GADGET is not set |
931 | 1185 | ||
932 | # | 1186 | # |
933 | # OTG and related infrastructure | 1187 | # OTG and related infrastructure |
934 | # | 1188 | # |
1189 | # CONFIG_USB_GPIO_VBUS is not set | ||
1190 | # CONFIG_USB_ULPI is not set | ||
1191 | # CONFIG_NOP_USB_XCEIV is not set | ||
935 | CONFIG_MMC=y | 1192 | CONFIG_MMC=y |
936 | CONFIG_MMC_DEBUG=y | 1193 | CONFIG_MMC_DEBUG=y |
937 | CONFIG_MMC_UNSAFE_RESUME=y | 1194 | CONFIG_MMC_UNSAFE_RESUME=y |
@@ -951,11 +1208,77 @@ CONFIG_MMC_SDHCI=y | |||
951 | # CONFIG_MMC_SDHCI_PLTFM is not set | 1208 | # CONFIG_MMC_SDHCI_PLTFM is not set |
952 | CONFIG_MMC_SDHCI_S3C=y | 1209 | CONFIG_MMC_SDHCI_S3C=y |
953 | # CONFIG_MMC_SDHCI_S3C_DMA is not set | 1210 | # CONFIG_MMC_SDHCI_S3C_DMA is not set |
1211 | # CONFIG_MMC_SPI is not set | ||
954 | # CONFIG_MEMSTICK is not set | 1212 | # CONFIG_MEMSTICK is not set |
955 | # CONFIG_NEW_LEDS is not set | 1213 | # CONFIG_NEW_LEDS is not set |
956 | # CONFIG_ACCESSIBILITY is not set | 1214 | # CONFIG_ACCESSIBILITY is not set |
957 | CONFIG_RTC_LIB=y | 1215 | CONFIG_RTC_LIB=y |
958 | # CONFIG_RTC_CLASS is not set | 1216 | CONFIG_RTC_CLASS=y |
1217 | CONFIG_RTC_HCTOSYS=y | ||
1218 | CONFIG_RTC_HCTOSYS_DEVICE="rtc0" | ||
1219 | # CONFIG_RTC_DEBUG is not set | ||
1220 | |||
1221 | # | ||
1222 | # RTC interfaces | ||
1223 | # | ||
1224 | CONFIG_RTC_INTF_SYSFS=y | ||
1225 | CONFIG_RTC_INTF_PROC=y | ||
1226 | CONFIG_RTC_INTF_DEV=y | ||
1227 | # CONFIG_RTC_INTF_DEV_UIE_EMUL is not set | ||
1228 | # CONFIG_RTC_DRV_TEST is not set | ||
1229 | |||
1230 | # | ||
1231 | # I2C RTC drivers | ||
1232 | # | ||
1233 | # CONFIG_RTC_DRV_DS1307 is not set | ||
1234 | # CONFIG_RTC_DRV_DS1374 is not set | ||
1235 | # CONFIG_RTC_DRV_DS1672 is not set | ||
1236 | # CONFIG_RTC_DRV_MAX6900 is not set | ||
1237 | # CONFIG_RTC_DRV_RS5C372 is not set | ||
1238 | # CONFIG_RTC_DRV_ISL1208 is not set | ||
1239 | # CONFIG_RTC_DRV_X1205 is not set | ||
1240 | # CONFIG_RTC_DRV_PCF8563 is not set | ||
1241 | # CONFIG_RTC_DRV_PCF8583 is not set | ||
1242 | # CONFIG_RTC_DRV_M41T80 is not set | ||
1243 | # CONFIG_RTC_DRV_BQ32K is not set | ||
1244 | # CONFIG_RTC_DRV_S35390A is not set | ||
1245 | # CONFIG_RTC_DRV_FM3130 is not set | ||
1246 | # CONFIG_RTC_DRV_RX8581 is not set | ||
1247 | # CONFIG_RTC_DRV_RX8025 is not set | ||
1248 | |||
1249 | # | ||
1250 | # SPI RTC drivers | ||
1251 | # | ||
1252 | # CONFIG_RTC_DRV_M41T94 is not set | ||
1253 | # CONFIG_RTC_DRV_DS1305 is not set | ||
1254 | # CONFIG_RTC_DRV_DS1390 is not set | ||
1255 | # CONFIG_RTC_DRV_MAX6902 is not set | ||
1256 | # CONFIG_RTC_DRV_R9701 is not set | ||
1257 | # CONFIG_RTC_DRV_RS5C348 is not set | ||
1258 | # CONFIG_RTC_DRV_DS3234 is not set | ||
1259 | # CONFIG_RTC_DRV_PCF2123 is not set | ||
1260 | |||
1261 | # | ||
1262 | # Platform RTC drivers | ||
1263 | # | ||
1264 | # CONFIG_RTC_DRV_CMOS is not set | ||
1265 | # CONFIG_RTC_DRV_DS1286 is not set | ||
1266 | # CONFIG_RTC_DRV_DS1511 is not set | ||
1267 | # CONFIG_RTC_DRV_DS1553 is not set | ||
1268 | # CONFIG_RTC_DRV_DS1742 is not set | ||
1269 | # CONFIG_RTC_DRV_STK17TA8 is not set | ||
1270 | # CONFIG_RTC_DRV_M48T86 is not set | ||
1271 | # CONFIG_RTC_DRV_M48T35 is not set | ||
1272 | # CONFIG_RTC_DRV_M48T59 is not set | ||
1273 | # CONFIG_RTC_DRV_MSM6242 is not set | ||
1274 | # CONFIG_RTC_DRV_BQ4802 is not set | ||
1275 | # CONFIG_RTC_DRV_RP5C01 is not set | ||
1276 | # CONFIG_RTC_DRV_V3020 is not set | ||
1277 | |||
1278 | # | ||
1279 | # on-CPU RTC drivers | ||
1280 | # | ||
1281 | CONFIG_RTC_DRV_S3C=y | ||
959 | # CONFIG_DMADEVICES is not set | 1282 | # CONFIG_DMADEVICES is not set |
960 | # CONFIG_AUXDISPLAY is not set | 1283 | # CONFIG_AUXDISPLAY is not set |
961 | # CONFIG_UIO is not set | 1284 | # CONFIG_UIO is not set |
@@ -1052,7 +1375,46 @@ CONFIG_ROMFS_ON_BLOCK=y | |||
1052 | # | 1375 | # |
1053 | # CONFIG_PARTITION_ADVANCED is not set | 1376 | # CONFIG_PARTITION_ADVANCED is not set |
1054 | CONFIG_MSDOS_PARTITION=y | 1377 | CONFIG_MSDOS_PARTITION=y |
1055 | # CONFIG_NLS is not set | 1378 | CONFIG_NLS=y |
1379 | CONFIG_NLS_DEFAULT="iso8859-1" | ||
1380 | # CONFIG_NLS_CODEPAGE_437 is not set | ||
1381 | # CONFIG_NLS_CODEPAGE_737 is not set | ||
1382 | # CONFIG_NLS_CODEPAGE_775 is not set | ||
1383 | # CONFIG_NLS_CODEPAGE_850 is not set | ||
1384 | # CONFIG_NLS_CODEPAGE_852 is not set | ||
1385 | # CONFIG_NLS_CODEPAGE_855 is not set | ||
1386 | # CONFIG_NLS_CODEPAGE_857 is not set | ||
1387 | # CONFIG_NLS_CODEPAGE_860 is not set | ||
1388 | # CONFIG_NLS_CODEPAGE_861 is not set | ||
1389 | # CONFIG_NLS_CODEPAGE_862 is not set | ||
1390 | # CONFIG_NLS_CODEPAGE_863 is not set | ||
1391 | # CONFIG_NLS_CODEPAGE_864 is not set | ||
1392 | # CONFIG_NLS_CODEPAGE_865 is not set | ||
1393 | # CONFIG_NLS_CODEPAGE_866 is not set | ||
1394 | # CONFIG_NLS_CODEPAGE_869 is not set | ||
1395 | # CONFIG_NLS_CODEPAGE_936 is not set | ||
1396 | # CONFIG_NLS_CODEPAGE_950 is not set | ||
1397 | # CONFIG_NLS_CODEPAGE_932 is not set | ||
1398 | # CONFIG_NLS_CODEPAGE_949 is not set | ||
1399 | # CONFIG_NLS_CODEPAGE_874 is not set | ||
1400 | # CONFIG_NLS_ISO8859_8 is not set | ||
1401 | # CONFIG_NLS_CODEPAGE_1250 is not set | ||
1402 | # CONFIG_NLS_CODEPAGE_1251 is not set | ||
1403 | # CONFIG_NLS_ASCII is not set | ||
1404 | # CONFIG_NLS_ISO8859_1 is not set | ||
1405 | # CONFIG_NLS_ISO8859_2 is not set | ||
1406 | # CONFIG_NLS_ISO8859_3 is not set | ||
1407 | # CONFIG_NLS_ISO8859_4 is not set | ||
1408 | # CONFIG_NLS_ISO8859_5 is not set | ||
1409 | # CONFIG_NLS_ISO8859_6 is not set | ||
1410 | # CONFIG_NLS_ISO8859_7 is not set | ||
1411 | # CONFIG_NLS_ISO8859_9 is not set | ||
1412 | # CONFIG_NLS_ISO8859_13 is not set | ||
1413 | # CONFIG_NLS_ISO8859_14 is not set | ||
1414 | # CONFIG_NLS_ISO8859_15 is not set | ||
1415 | # CONFIG_NLS_KOI8_R is not set | ||
1416 | # CONFIG_NLS_KOI8_U is not set | ||
1417 | # CONFIG_NLS_UTF8 is not set | ||
1056 | 1418 | ||
1057 | # | 1419 | # |
1058 | # Kernel hacking | 1420 | # Kernel hacking |
diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c index 7a4138beb665..fbd85a9b7bbf 100644 --- a/arch/arm/mach-s3c64xx/clock.c +++ b/arch/arm/mach-s3c64xx/clock.c | |||
@@ -259,6 +259,12 @@ static struct clk init_clocks[] = { | |||
259 | .enable = s3c64xx_hclk_ctrl, | 259 | .enable = s3c64xx_hclk_ctrl, |
260 | .ctrlbit = S3C_CLKCON_HCLK_HSMMC2, | 260 | .ctrlbit = S3C_CLKCON_HCLK_HSMMC2, |
261 | }, { | 261 | }, { |
262 | .name = "otg", | ||
263 | .id = -1, | ||
264 | .parent = &clk_h, | ||
265 | .enable = s3c64xx_hclk_ctrl, | ||
266 | .ctrlbit = S3C_CLKCON_HCLK_USB, | ||
267 | }, { | ||
262 | .name = "timers", | 268 | .name = "timers", |
263 | .id = -1, | 269 | .id = -1, |
264 | .parent = &clk_p, | 270 | .parent = &clk_p, |
diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c index 1b2c9890e8b4..6544855af2f1 100644 --- a/arch/arm/mach-ux500/clock.c +++ b/arch/arm/mach-ux500/clock.c | |||
@@ -411,7 +411,7 @@ static struct clk_lookup u8500_common_clks[] = { | |||
411 | CLK(apetraceclk, "apetrace", NULL), | 411 | CLK(apetraceclk, "apetrace", NULL), |
412 | CLK(mcdeclk, "mcde", NULL), | 412 | CLK(mcdeclk, "mcde", NULL), |
413 | CLK(ipi2clk, "ipi2", NULL), | 413 | CLK(ipi2clk, "ipi2", NULL), |
414 | CLK(dmaclk, "dma40", NULL), | 414 | CLK(dmaclk, "dma40.0", NULL), |
415 | CLK(b2r2clk, "b2r2", NULL), | 415 | CLK(b2r2clk, "b2r2", NULL), |
416 | CLK(tvclk, "tv", NULL), | 416 | CLK(tvclk, "tv", NULL), |
417 | }; | 417 | }; |
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index d04299f3b6b5..f21c444edd99 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c | |||
@@ -32,6 +32,7 @@ static struct platform_device *platform_devs[] __initdata = { | |||
32 | &u8500_gpio_devs[6], | 32 | &u8500_gpio_devs[6], |
33 | &u8500_gpio_devs[7], | 33 | &u8500_gpio_devs[7], |
34 | &u8500_gpio_devs[8], | 34 | &u8500_gpio_devs[8], |
35 | &u8500_dma40_device, | ||
35 | }; | 36 | }; |
36 | 37 | ||
37 | /* minimum static i/o mapping required to boot U8500 platforms */ | 38 | /* minimum static i/o mapping required to boot U8500 platforms */ |
@@ -71,6 +72,9 @@ void __init u8500_init_devices(void) | |||
71 | { | 72 | { |
72 | ux500_init_devices(); | 73 | ux500_init_devices(); |
73 | 74 | ||
75 | if (cpu_is_u8500ed()) | ||
76 | dma40_u8500ed_fixup(); | ||
77 | |||
74 | /* Register the platform devices */ | 78 | /* Register the platform devices */ |
75 | platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); | 79 | platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); |
76 | 80 | ||
diff --git a/arch/arm/mach-ux500/devices-db8500.c b/arch/arm/mach-ux500/devices-db8500.c index 20334236afce..822903421943 100644 --- a/arch/arm/mach-ux500/devices-db8500.c +++ b/arch/arm/mach-ux500/devices-db8500.c | |||
@@ -12,9 +12,13 @@ | |||
12 | #include <linux/gpio.h> | 12 | #include <linux/gpio.h> |
13 | #include <linux/amba/bus.h> | 13 | #include <linux/amba/bus.h> |
14 | 14 | ||
15 | #include <plat/ste_dma40.h> | ||
16 | |||
15 | #include <mach/hardware.h> | 17 | #include <mach/hardware.h> |
16 | #include <mach/setup.h> | 18 | #include <mach/setup.h> |
17 | 19 | ||
20 | #include "ste-dma40-db8500.h" | ||
21 | |||
18 | static struct nmk_gpio_platform_data u8500_gpio_data[] = { | 22 | static struct nmk_gpio_platform_data u8500_gpio_data[] = { |
19 | GPIO_DATA("GPIO-0-31", 0), | 23 | GPIO_DATA("GPIO-0-31", 0), |
20 | GPIO_DATA("GPIO-32-63", 32), /* 37..63 not routed to pin */ | 24 | GPIO_DATA("GPIO-32-63", 32), /* 37..63 not routed to pin */ |
@@ -105,3 +109,108 @@ struct platform_device u8500_i2c4_device = { | |||
105 | .resource = u8500_i2c4_resources, | 109 | .resource = u8500_i2c4_resources, |
106 | .num_resources = ARRAY_SIZE(u8500_i2c4_resources), | 110 | .num_resources = ARRAY_SIZE(u8500_i2c4_resources), |
107 | }; | 111 | }; |
112 | |||
113 | static struct resource dma40_resources[] = { | ||
114 | [0] = { | ||
115 | .start = U8500_DMA_BASE, | ||
116 | .end = U8500_DMA_BASE + SZ_4K - 1, | ||
117 | .flags = IORESOURCE_MEM, | ||
118 | .name = "base", | ||
119 | }, | ||
120 | [1] = { | ||
121 | .start = U8500_DMA_LCPA_BASE, | ||
122 | .end = U8500_DMA_LCPA_BASE + SZ_4K - 1, | ||
123 | .flags = IORESOURCE_MEM, | ||
124 | .name = "lcpa", | ||
125 | }, | ||
126 | [2] = { | ||
127 | .start = U8500_DMA_LCLA_BASE, | ||
128 | .end = U8500_DMA_LCLA_BASE + 16 * 1024 - 1, | ||
129 | .flags = IORESOURCE_MEM, | ||
130 | .name = "lcla", | ||
131 | }, | ||
132 | [3] = { | ||
133 | .start = IRQ_DMA, | ||
134 | .end = IRQ_DMA, | ||
135 | .flags = IORESOURCE_IRQ} | ||
136 | }; | ||
137 | |||
138 | /* Default configuration for physcial memcpy */ | ||
139 | struct stedma40_chan_cfg dma40_memcpy_conf_phy = { | ||
140 | .channel_type = (STEDMA40_CHANNEL_IN_PHY_MODE | | ||
141 | STEDMA40_LOW_PRIORITY_CHANNEL | | ||
142 | STEDMA40_PCHAN_BASIC_MODE), | ||
143 | .dir = STEDMA40_MEM_TO_MEM, | ||
144 | |||
145 | .src_info.endianess = STEDMA40_LITTLE_ENDIAN, | ||
146 | .src_info.data_width = STEDMA40_BYTE_WIDTH, | ||
147 | .src_info.psize = STEDMA40_PSIZE_PHY_1, | ||
148 | |||
149 | .dst_info.endianess = STEDMA40_LITTLE_ENDIAN, | ||
150 | .dst_info.data_width = STEDMA40_BYTE_WIDTH, | ||
151 | .dst_info.psize = STEDMA40_PSIZE_PHY_1, | ||
152 | |||
153 | }; | ||
154 | /* Default configuration for logical memcpy */ | ||
155 | struct stedma40_chan_cfg dma40_memcpy_conf_log = { | ||
156 | .channel_type = (STEDMA40_CHANNEL_IN_LOG_MODE | | ||
157 | STEDMA40_LOW_PRIORITY_CHANNEL | | ||
158 | STEDMA40_LCHAN_SRC_LOG_DST_LOG | | ||
159 | STEDMA40_NO_TIM_FOR_LINK), | ||
160 | .dir = STEDMA40_MEM_TO_MEM, | ||
161 | |||
162 | .src_info.endianess = STEDMA40_LITTLE_ENDIAN, | ||
163 | .src_info.data_width = STEDMA40_BYTE_WIDTH, | ||
164 | .src_info.psize = STEDMA40_PSIZE_LOG_1, | ||
165 | |||
166 | .dst_info.endianess = STEDMA40_LITTLE_ENDIAN, | ||
167 | .dst_info.data_width = STEDMA40_BYTE_WIDTH, | ||
168 | .dst_info.psize = STEDMA40_PSIZE_LOG_1, | ||
169 | |||
170 | }; | ||
171 | |||
172 | /* | ||
173 | * Mapping between destination event lines and physical device address. | ||
174 | * The event line is tied to a device and therefor the address is constant. | ||
175 | */ | ||
176 | static const dma_addr_t dma40_tx_map[STEDMA40_NR_DEV]; | ||
177 | |||
178 | /* Mapping between source event lines and physical device address */ | ||
179 | static const dma_addr_t dma40_rx_map[STEDMA40_NR_DEV]; | ||
180 | |||
181 | /* Reserved event lines for memcpy only */ | ||
182 | static int dma40_memcpy_event[] = { | ||
183 | STEDMA40_MEMCPY_TX_1, | ||
184 | STEDMA40_MEMCPY_TX_2, | ||
185 | STEDMA40_MEMCPY_TX_3, | ||
186 | STEDMA40_MEMCPY_TX_4, | ||
187 | }; | ||
188 | |||
189 | static struct stedma40_platform_data dma40_plat_data = { | ||
190 | .dev_len = STEDMA40_NR_DEV, | ||
191 | .dev_rx = dma40_rx_map, | ||
192 | .dev_tx = dma40_tx_map, | ||
193 | .memcpy = dma40_memcpy_event, | ||
194 | .memcpy_len = ARRAY_SIZE(dma40_memcpy_event), | ||
195 | .memcpy_conf_phy = &dma40_memcpy_conf_phy, | ||
196 | .memcpy_conf_log = &dma40_memcpy_conf_log, | ||
197 | .llis_per_log = 8, | ||
198 | }; | ||
199 | |||
200 | struct platform_device u8500_dma40_device = { | ||
201 | .dev = { | ||
202 | .platform_data = &dma40_plat_data, | ||
203 | }, | ||
204 | .name = "dma40", | ||
205 | .id = 0, | ||
206 | .num_resources = ARRAY_SIZE(dma40_resources), | ||
207 | .resource = dma40_resources | ||
208 | }; | ||
209 | |||
210 | void dma40_u8500ed_fixup(void) | ||
211 | { | ||
212 | dma40_plat_data.memcpy = NULL; | ||
213 | dma40_plat_data.memcpy_len = 0; | ||
214 | dma40_resources[0].start = U8500_DMA_BASE_ED; | ||
215 | dma40_resources[0].end = U8500_DMA_BASE_ED + SZ_4K - 1; | ||
216 | } | ||
diff --git a/arch/arm/mach-ux500/include/mach/db8500-regs.h b/arch/arm/mach-ux500/include/mach/db8500-regs.h index 9169e1e382a3..85fc6a80b386 100644 --- a/arch/arm/mach-ux500/include/mach/db8500-regs.h +++ b/arch/arm/mach-ux500/include/mach/db8500-regs.h | |||
@@ -7,6 +7,18 @@ | |||
7 | #ifndef __MACH_DB8500_REGS_H | 7 | #ifndef __MACH_DB8500_REGS_H |
8 | #define __MACH_DB8500_REGS_H | 8 | #define __MACH_DB8500_REGS_H |
9 | 9 | ||
10 | /* Base address and bank offsets for ESRAM */ | ||
11 | #define U8500_ESRAM_BASE 0x40000000 | ||
12 | #define U8500_ESRAM_BANK_SIZE 0x00020000 | ||
13 | #define U8500_ESRAM_BANK0 U8500_ESRAM_BASE | ||
14 | #define U8500_ESRAM_BANK1 (U8500_ESRAM_BASE + U8500_ESRAM_BANK_SIZE) | ||
15 | #define U8500_ESRAM_BANK2 (U8500_ESRAM_BANK1 + U8500_ESRAM_BANK_SIZE) | ||
16 | #define U8500_ESRAM_BANK3 (U8500_ESRAM_BANK2 + U8500_ESRAM_BANK_SIZE) | ||
17 | #define U8500_ESRAM_BANK4 (U8500_ESRAM_BANK3 + U8500_ESRAM_BANK_SIZE) | ||
18 | /* Use bank 4 for DMA LCLA and LCPA */ | ||
19 | #define U8500_DMA_LCLA_BASE U8500_ESRAM_BANK4 | ||
20 | #define U8500_DMA_LCPA_BASE (U8500_ESRAM_BANK4 + 0x4000) | ||
21 | |||
10 | #define U8500_PER3_BASE 0x80000000 | 22 | #define U8500_PER3_BASE 0x80000000 |
11 | #define U8500_STM_BASE 0x80100000 | 23 | #define U8500_STM_BASE 0x80100000 |
12 | #define U8500_STM_REG_BASE (U8500_STM_BASE + 0xF000) | 24 | #define U8500_STM_REG_BASE (U8500_STM_BASE + 0xF000) |
diff --git a/arch/arm/mach-ux500/include/mach/devices.h b/arch/arm/mach-ux500/include/mach/devices.h index 0422af00a56e..c2b2f2574947 100644 --- a/arch/arm/mach-ux500/include/mach/devices.h +++ b/arch/arm/mach-ux500/include/mach/devices.h | |||
@@ -25,5 +25,8 @@ extern struct platform_device ux500_i2c3_device; | |||
25 | 25 | ||
26 | extern struct platform_device u8500_i2c0_device; | 26 | extern struct platform_device u8500_i2c0_device; |
27 | extern struct platform_device u8500_i2c4_device; | 27 | extern struct platform_device u8500_i2c4_device; |
28 | extern struct platform_device u8500_dma40_device; | ||
29 | |||
30 | void dma40_u8500ed_fixup(void); | ||
28 | 31 | ||
29 | #endif | 32 | #endif |
diff --git a/arch/arm/mach-ux500/ste-dma40-db8500.h b/arch/arm/mach-ux500/ste-dma40-db8500.h new file mode 100644 index 000000000000..e7016278dfa9 --- /dev/null +++ b/arch/arm/mach-ux500/ste-dma40-db8500.h | |||
@@ -0,0 +1,154 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-ux500/ste_dma40_db8500.h | ||
3 | * DB8500-SoC-specific configuration for DMA40 | ||
4 | * | ||
5 | * Copyright (C) ST-Ericsson 2007-2010 | ||
6 | * License terms: GNU General Public License (GPL) version 2 | ||
7 | * Author: Per Friden <per.friden@stericsson.com> | ||
8 | * Author: Jonas Aaberg <jonas.aberg@stericsson.com> | ||
9 | */ | ||
10 | #ifndef STE_DMA40_DB8500_H | ||
11 | #define STE_DMA40_DB8500_H | ||
12 | |||
13 | #define STEDMA40_NR_DEV 64 | ||
14 | |||
15 | enum dma_src_dev_type { | ||
16 | STEDMA40_DEV_SPI0_RX = 0, | ||
17 | STEDMA40_DEV_SD_MMC0_RX = 1, | ||
18 | STEDMA40_DEV_SD_MMC1_RX = 2, | ||
19 | STEDMA40_DEV_SD_MMC2_RX = 3, | ||
20 | STEDMA40_DEV_I2C1_RX = 4, | ||
21 | STEDMA40_DEV_I2C3_RX = 5, | ||
22 | STEDMA40_DEV_I2C2_RX = 6, | ||
23 | STEDMA40_DEV_I2C4_RX = 7, /* Only on V1 */ | ||
24 | STEDMA40_DEV_SSP0_RX = 8, | ||
25 | STEDMA40_DEV_SSP1_RX = 9, | ||
26 | STEDMA40_DEV_MCDE_RX = 10, | ||
27 | STEDMA40_DEV_UART2_RX = 11, | ||
28 | STEDMA40_DEV_UART1_RX = 12, | ||
29 | STEDMA40_DEV_UART0_RX = 13, | ||
30 | STEDMA40_DEV_MSP2_RX = 14, | ||
31 | STEDMA40_DEV_I2C0_RX = 15, | ||
32 | STEDMA40_DEV_USB_OTG_IEP_8 = 16, | ||
33 | STEDMA40_DEV_USB_OTG_IEP_1_9 = 17, | ||
34 | STEDMA40_DEV_USB_OTG_IEP_2_10 = 18, | ||
35 | STEDMA40_DEV_USB_OTG_IEP_3_11 = 19, | ||
36 | STEDMA40_DEV_SLIM0_CH0_RX_HSI_RX_CH0 = 20, | ||
37 | STEDMA40_DEV_SLIM0_CH1_RX_HSI_RX_CH1 = 21, | ||
38 | STEDMA40_DEV_SLIM0_CH2_RX_HSI_RX_CH2 = 22, | ||
39 | STEDMA40_DEV_SLIM0_CH3_RX_HSI_RX_CH3 = 23, | ||
40 | STEDMA40_DEV_SRC_SXA0_RX_TX = 24, | ||
41 | STEDMA40_DEV_SRC_SXA1_RX_TX = 25, | ||
42 | STEDMA40_DEV_SRC_SXA2_RX_TX = 26, | ||
43 | STEDMA40_DEV_SRC_SXA3_RX_TX = 27, | ||
44 | STEDMA40_DEV_SD_MM2_RX = 28, | ||
45 | STEDMA40_DEV_SD_MM0_RX = 29, | ||
46 | STEDMA40_DEV_MSP1_RX = 30, | ||
47 | /* | ||
48 | * This channel is either SlimBus or MSP, | ||
49 | * never both at the same time. | ||
50 | */ | ||
51 | STEDMA40_SLIM0_CH0_RX = 31, | ||
52 | STEDMA40_DEV_MSP0_RX = 31, | ||
53 | STEDMA40_DEV_SD_MM1_RX = 32, | ||
54 | STEDMA40_DEV_SPI2_RX = 33, | ||
55 | STEDMA40_DEV_I2C3_RX2 = 34, | ||
56 | STEDMA40_DEV_SPI1_RX = 35, | ||
57 | STEDMA40_DEV_USB_OTG_IEP_4_12 = 36, | ||
58 | STEDMA40_DEV_USB_OTG_IEP_5_13 = 37, | ||
59 | STEDMA40_DEV_USB_OTG_IEP_6_14 = 38, | ||
60 | STEDMA40_DEV_USB_OTG_IEP_7_15 = 39, | ||
61 | STEDMA40_DEV_SPI3_RX = 40, | ||
62 | STEDMA40_DEV_SD_MM3_RX = 41, | ||
63 | STEDMA40_DEV_SD_MM4_RX = 42, | ||
64 | STEDMA40_DEV_SD_MM5_RX = 43, | ||
65 | STEDMA40_DEV_SRC_SXA4_RX_TX = 44, | ||
66 | STEDMA40_DEV_SRC_SXA5_RX_TX = 45, | ||
67 | STEDMA40_DEV_SRC_SXA6_RX_TX = 46, | ||
68 | STEDMA40_DEV_SRC_SXA7_RX_TX = 47, | ||
69 | STEDMA40_DEV_CAC1_RX = 48, | ||
70 | /* RX channels 49 and 50 are unused */ | ||
71 | STEDMA40_DEV_MSHC_RX = 51, | ||
72 | STEDMA40_DEV_SLIM1_CH0_RX_HSI_RX_CH4 = 52, | ||
73 | STEDMA40_DEV_SLIM1_CH1_RX_HSI_RX_CH5 = 53, | ||
74 | STEDMA40_DEV_SLIM1_CH2_RX_HSI_RX_CH6 = 54, | ||
75 | STEDMA40_DEV_SLIM1_CH3_RX_HSI_RX_CH7 = 55, | ||
76 | /* RX channels 56 thru 60 are unused */ | ||
77 | STEDMA40_DEV_CAC0_RX = 61, | ||
78 | /* RX channels 62 and 63 are unused */ | ||
79 | }; | ||
80 | |||
81 | enum dma_dest_dev_type { | ||
82 | STEDMA40_DEV_SPI0_TX = 0, | ||
83 | STEDMA40_DEV_SD_MMC0_TX = 1, | ||
84 | STEDMA40_DEV_SD_MMC1_TX = 2, | ||
85 | STEDMA40_DEV_SD_MMC2_TX = 3, | ||
86 | STEDMA40_DEV_I2C1_TX = 4, | ||
87 | STEDMA40_DEV_I2C3_TX = 5, | ||
88 | STEDMA40_DEV_I2C2_TX = 6, | ||
89 | STEDMA50_DEV_I2C4_TX = 7, /* Only on V1 */ | ||
90 | STEDMA40_DEV_SSP0_TX = 8, | ||
91 | STEDMA40_DEV_SSP1_TX = 9, | ||
92 | /* TX channel 10 is unused */ | ||
93 | STEDMA40_DEV_UART2_TX = 11, | ||
94 | STEDMA40_DEV_UART1_TX = 12, | ||
95 | STEDMA40_DEV_UART0_TX= 13, | ||
96 | STEDMA40_DEV_MSP2_TX = 14, | ||
97 | STEDMA40_DEV_I2C0_TX = 15, | ||
98 | STEDMA40_DEV_USB_OTG_OEP_8 = 16, | ||
99 | STEDMA40_DEV_USB_OTG_OEP_1_9 = 17, | ||
100 | STEDMA40_DEV_USB_OTG_OEP_2_10= 18, | ||
101 | STEDMA40_DEV_USB_OTG_OEP_3_11 = 19, | ||
102 | STEDMA40_DEV_SLIM0_CH0_TX_HSI_TX_CH0 = 20, | ||
103 | STEDMA40_DEV_SLIM0_CH1_TX_HSI_TX_CH1 = 21, | ||
104 | STEDMA40_DEV_SLIM0_CH2_TX_HSI_TX_CH2 = 22, | ||
105 | STEDMA40_DEV_SLIM0_CH3_TX_HSI_TX_CH3 = 23, | ||
106 | STEDMA40_DEV_DST_SXA0_RX_TX = 24, | ||
107 | STEDMA40_DEV_DST_SXA1_RX_TX = 25, | ||
108 | STEDMA40_DEV_DST_SXA2_RX_TX = 26, | ||
109 | STEDMA40_DEV_DST_SXA3_RX_TX = 27, | ||
110 | STEDMA40_DEV_SD_MM2_TX = 28, | ||
111 | STEDMA40_DEV_SD_MM0_TX = 29, | ||
112 | STEDMA40_DEV_MSP1_TX = 30, | ||
113 | /* | ||
114 | * This channel is either SlimBus or MSP, | ||
115 | * never both at the same time. | ||
116 | */ | ||
117 | STEDMA40_SLIM0_CH0_TX = 31, | ||
118 | STEDMA40_DEV_MSP0_TX = 31, | ||
119 | STEDMA40_DEV_SD_MM1_TX = 32, | ||
120 | STEDMA40_DEV_SPI2_TX = 33, | ||
121 | /* Secondary I2C3 channel */ | ||
122 | STEDMA40_DEV_I2C3_TX2 = 34, | ||
123 | STEDMA40_DEV_SPI1_TX = 35, | ||
124 | STEDMA40_DEV_USB_OTG_OEP_4_12 = 36, | ||
125 | STEDMA40_DEV_USB_OTG_OEP_5_13 = 37, | ||
126 | STEDMA40_DEV_USB_OTG_OEP_6_14 = 38, | ||
127 | STEDMA40_DEV_USB_OTG_OEP_7_15 = 39, | ||
128 | STEDMA40_DEV_SPI3_TX = 40, | ||
129 | STEDMA40_DEV_SD_MM3_TX = 41, | ||
130 | STEDMA40_DEV_SD_MM4_TX = 42, | ||
131 | STEDMA40_DEV_SD_MM5_TX = 43, | ||
132 | STEDMA40_DEV_DST_SXA4_RX_TX = 44, | ||
133 | STEDMA40_DEV_DST_SXA5_RX_TX = 45, | ||
134 | STEDMA40_DEV_DST_SXA6_RX_TX = 46, | ||
135 | STEDMA40_DEV_DST_SXA7_RX_TX = 47, | ||
136 | STEDMA40_DEV_CAC1_TX = 48, | ||
137 | STEDMA40_DEV_CAC1_TX_HAC1_TX = 49, | ||
138 | STEDMA40_DEV_HAC1_TX = 50, | ||
139 | STEDMA40_MEMXCPY_TX_0 = 51, | ||
140 | STEDMA40_DEV_SLIM1_CH0_TX_HSI_TX_CH4 = 52, | ||
141 | STEDMA40_DEV_SLIM1_CH1_TX_HSI_TX_CH5 = 53, | ||
142 | STEDMA40_DEV_SLIM1_CH2_TX_HSI_TX_CH6 = 54, | ||
143 | STEDMA40_DEV_SLIM1_CH3_TX_HSI_TX_CH7 = 55, | ||
144 | STEDMA40_MEMCPY_TX_1 = 56, | ||
145 | STEDMA40_MEMCPY_TX_2 = 57, | ||
146 | STEDMA40_MEMCPY_TX_3 = 58, | ||
147 | STEDMA40_MEMCPY_TX_4 = 59, | ||
148 | STEDMA40_MEMCPY_TX_5 = 60, | ||
149 | STEDMA40_DEV_CAC0_TX = 61, | ||
150 | STEDMA40_DEV_CAC0_TX_HAC0_TX = 62, | ||
151 | STEDMA40_DEV_HAC0_TX = 63, | ||
152 | }; | ||
153 | |||
154 | #endif | ||
diff --git a/arch/arm/plat-s5p/clock.c b/arch/arm/plat-s5p/clock.c index 24a931fd8d3b..b5e255265f20 100644 --- a/arch/arm/plat-s5p/clock.c +++ b/arch/arm/plat-s5p/clock.c | |||
@@ -148,6 +148,7 @@ static struct clk *s5p_clks[] __initdata = { | |||
148 | &clk_fout_vpll, | 148 | &clk_fout_vpll, |
149 | &clk_arm, | 149 | &clk_arm, |
150 | &clk_vpll, | 150 | &clk_vpll, |
151 | &clk_xusbxti, | ||
151 | }; | 152 | }; |
152 | 153 | ||
153 | void __init s5p_register_clocks(unsigned long xtal_freq) | 154 | void __init s5p_register_clocks(unsigned long xtal_freq) |
diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg.h b/arch/arm/plat-samsung/include/plat/gpio-cfg.h index 34efdd2b032c..db4112c6f2be 100644 --- a/arch/arm/plat-samsung/include/plat/gpio-cfg.h +++ b/arch/arm/plat-samsung/include/plat/gpio-cfg.h | |||
@@ -43,6 +43,11 @@ struct s3c_gpio_chip; | |||
43 | * layouts. Provide an point to vector control routine and provide any | 43 | * layouts. Provide an point to vector control routine and provide any |
44 | * per-bank configuration information that other systems such as the | 44 | * per-bank configuration information that other systems such as the |
45 | * external interrupt code will need. | 45 | * external interrupt code will need. |
46 | * | ||
47 | * @sa s3c_gpio_cfgpin | ||
48 | * @sa s3c_gpio_getcfg | ||
49 | * @sa s3c_gpio_setpull | ||
50 | * @sa s3c_gpio_getpull | ||
46 | */ | 51 | */ |
47 | struct s3c_gpio_cfg { | 52 | struct s3c_gpio_cfg { |
48 | unsigned int cfg_eint; | 53 | unsigned int cfg_eint; |
@@ -70,11 +75,25 @@ struct s3c_gpio_cfg { | |||
70 | /** | 75 | /** |
71 | * s3c_gpio_cfgpin() - Change the GPIO function of a pin. | 76 | * s3c_gpio_cfgpin() - Change the GPIO function of a pin. |
72 | * @pin pin The pin number to configure. | 77 | * @pin pin The pin number to configure. |
73 | * @pin to The configuration for the pin's function. | 78 | * @to to The configuration for the pin's function. |
74 | * | 79 | * |
75 | * Configure which function is actually connected to the external | 80 | * Configure which function is actually connected to the external |
76 | * pin, such as an gpio input, output or some form of special function | 81 | * pin, such as an gpio input, output or some form of special function |
77 | * connected to an internal peripheral block. | 82 | * connected to an internal peripheral block. |
83 | * | ||
84 | * The @to parameter can be one of the generic S3C_GPIO_INPUT, S3C_GPIO_OUTPUT | ||
85 | * or S3C_GPIO_SFN() to indicate one of the possible values that the helper | ||
86 | * will then generate the correct bit mask and shift for the configuration. | ||
87 | * | ||
88 | * If a bank of GPIOs all needs to be set to special-function 2, then | ||
89 | * the following code will work: | ||
90 | * | ||
91 | * for (gpio = start; gpio < end; gpio++) | ||
92 | * s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); | ||
93 | * | ||
94 | * The @to parameter can also be a specific value already shifted to the | ||
95 | * correct position in the control register, although these are discouraged | ||
96 | * in newer kernels and are only being kept for compatibility. | ||
78 | */ | 97 | */ |
79 | extern int s3c_gpio_cfgpin(unsigned int pin, unsigned int to); | 98 | extern int s3c_gpio_cfgpin(unsigned int pin, unsigned int to); |
80 | 99 | ||
@@ -108,6 +127,8 @@ extern unsigned s3c_gpio_getcfg(unsigned int pin); | |||
108 | * This function sets the state of the pull-{up,down} resistor for the | 127 | * This function sets the state of the pull-{up,down} resistor for the |
109 | * specified pin. It will return 0 if successfull, or a negative error | 128 | * specified pin. It will return 0 if successfull, or a negative error |
110 | * code if the pin cannot support the requested pull setting. | 129 | * code if the pin cannot support the requested pull setting. |
130 | * | ||
131 | * @pull is one of S3C_GPIO_PULL_NONE, S3C_GPIO_PULL_DOWN or S3C_GPIO_PULL_UP. | ||
111 | */ | 132 | */ |
112 | extern int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull); | 133 | extern int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull); |
113 | 134 | ||
diff --git a/arch/frv/include/asm/cache.h b/arch/frv/include/asm/cache.h index 7dc0f0f85b7c..2797163b8f4f 100644 --- a/arch/frv/include/asm/cache.h +++ b/arch/frv/include/asm/cache.h | |||
@@ -17,8 +17,6 @@ | |||
17 | #define L1_CACHE_SHIFT (CONFIG_FRV_L1_CACHE_SHIFT) | 17 | #define L1_CACHE_SHIFT (CONFIG_FRV_L1_CACHE_SHIFT) |
18 | #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) | 18 | #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) |
19 | 19 | ||
20 | #define ARCH_KMALLOC_MINALIGN L1_CACHE_BYTES | ||
21 | |||
22 | #define __cacheline_aligned __attribute__((aligned(L1_CACHE_BYTES))) | 20 | #define __cacheline_aligned __attribute__((aligned(L1_CACHE_BYTES))) |
23 | #define ____cacheline_aligned __attribute__((aligned(L1_CACHE_BYTES))) | 21 | #define ____cacheline_aligned __attribute__((aligned(L1_CACHE_BYTES))) |
24 | 22 | ||
diff --git a/arch/frv/include/asm/mem-layout.h b/arch/frv/include/asm/mem-layout.h index 2947764fc0e0..ccae981876fa 100644 --- a/arch/frv/include/asm/mem-layout.h +++ b/arch/frv/include/asm/mem-layout.h | |||
@@ -35,8 +35,8 @@ | |||
35 | * the slab must be aligned such that load- and store-double instructions don't | 35 | * the slab must be aligned such that load- and store-double instructions don't |
36 | * fault if used | 36 | * fault if used |
37 | */ | 37 | */ |
38 | #define ARCH_KMALLOC_MINALIGN 8 | 38 | #define ARCH_KMALLOC_MINALIGN L1_CACHE_BYTES |
39 | #define ARCH_SLAB_MINALIGN 8 | 39 | #define ARCH_SLAB_MINALIGN L1_CACHE_BYTES |
40 | 40 | ||
41 | /*****************************************************************************/ | 41 | /*****************************************************************************/ |
42 | /* | 42 | /* |
diff --git a/arch/ia64/include/asm/acpi.h b/arch/ia64/include/asm/acpi.h index 21adbd7f90f8..837dc82a013e 100644 --- a/arch/ia64/include/asm/acpi.h +++ b/arch/ia64/include/asm/acpi.h | |||
@@ -94,7 +94,6 @@ ia64_acpi_release_global_lock (unsigned int *lock) | |||
94 | #define acpi_noirq 0 /* ACPI always enabled on IA64 */ | 94 | #define acpi_noirq 0 /* ACPI always enabled on IA64 */ |
95 | #define acpi_pci_disabled 0 /* ACPI PCI always enabled on IA64 */ | 95 | #define acpi_pci_disabled 0 /* ACPI PCI always enabled on IA64 */ |
96 | #define acpi_strict 1 /* no ACPI spec workarounds on IA64 */ | 96 | #define acpi_strict 1 /* no ACPI spec workarounds on IA64 */ |
97 | #define acpi_ht 0 /* no HT-only mode on IA64 */ | ||
98 | #endif | 97 | #endif |
99 | #define acpi_processor_cstate_check(x) (x) /* no idle limits on IA64 :) */ | 98 | #define acpi_processor_cstate_check(x) (x) /* no idle limits on IA64 :) */ |
100 | static inline void disable_acpi(void) { } | 99 | static inline void disable_acpi(void) { } |
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index 518e876a410d..6a1380e90f87 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c | |||
@@ -390,11 +390,13 @@ smp_callin (void) | |||
390 | 390 | ||
391 | fix_b0_for_bsp(); | 391 | fix_b0_for_bsp(); |
392 | 392 | ||
393 | #ifdef CONFIG_NUMA | ||
393 | /* | 394 | /* |
394 | * numa_node_id() works after this. | 395 | * numa_node_id() works after this. |
395 | */ | 396 | */ |
396 | set_numa_node(cpu_to_node_map[cpuid]); | 397 | set_numa_node(cpu_to_node_map[cpuid]); |
397 | set_numa_mem(local_memory_node(cpu_to_node_map[cpuid])); | 398 | set_numa_mem(local_memory_node(cpu_to_node_map[cpuid])); |
399 | #endif | ||
398 | 400 | ||
399 | ipi_call_lock_irq(); | 401 | ipi_call_lock_irq(); |
400 | spin_lock(&vector_lock); | 402 | spin_lock(&vector_lock); |
@@ -638,7 +640,9 @@ void __devinit smp_prepare_boot_cpu(void) | |||
638 | { | 640 | { |
639 | cpu_set(smp_processor_id(), cpu_online_map); | 641 | cpu_set(smp_processor_id(), cpu_online_map); |
640 | cpu_set(smp_processor_id(), cpu_callin_map); | 642 | cpu_set(smp_processor_id(), cpu_callin_map); |
643 | #ifdef CONFIG_NUMA | ||
641 | set_numa_node(cpu_to_node_map[smp_processor_id()]); | 644 | set_numa_node(cpu_to_node_map[smp_processor_id()]); |
645 | #endif | ||
642 | per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; | 646 | per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; |
643 | paravirt_post_smp_prepare_boot_cpu(); | 647 | paravirt_post_smp_prepare_boot_cpu(); |
644 | } | 648 | } |
diff --git a/arch/ia64/mm/numa.c b/arch/ia64/mm/numa.c index 3efea7d0a351..2437718bd6b1 100644 --- a/arch/ia64/mm/numa.c +++ b/arch/ia64/mm/numa.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/bootmem.h> | 18 | #include <linux/bootmem.h> |
19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
20 | #include <linux/random.h> | ||
20 | #include <asm/mmzone.h> | 21 | #include <asm/mmzone.h> |
21 | #include <asm/numa.h> | 22 | #include <asm/numa.h> |
22 | 23 | ||
@@ -50,6 +51,22 @@ paddr_to_nid(unsigned long paddr) | |||
50 | return (i < num_node_memblks) ? node_memblk[i].nid : (num_node_memblks ? -1 : 0); | 51 | return (i < num_node_memblks) ? node_memblk[i].nid : (num_node_memblks ? -1 : 0); |
51 | } | 52 | } |
52 | 53 | ||
54 | /* | ||
55 | * Return the bit number of a random bit set in the nodemask. | ||
56 | * (returns -1 if nodemask is empty) | ||
57 | */ | ||
58 | int __node_random(const nodemask_t *maskp) | ||
59 | { | ||
60 | int w, bit = -1; | ||
61 | |||
62 | w = nodes_weight(*maskp); | ||
63 | if (w) | ||
64 | bit = bitmap_ord_to_pos(maskp->bits, | ||
65 | get_random_int() % w, MAX_NUMNODES); | ||
66 | return bit; | ||
67 | } | ||
68 | EXPORT_SYMBOL(__node_random); | ||
69 | |||
53 | #if defined(CONFIG_SPARSEMEM) && defined(CONFIG_NUMA) | 70 | #if defined(CONFIG_SPARSEMEM) && defined(CONFIG_NUMA) |
54 | /* | 71 | /* |
55 | * Because of holes evaluate on section limits. | 72 | * Because of holes evaluate on section limits. |
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 64aff520b899..aa2533ae7e9e 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c | |||
@@ -335,8 +335,11 @@ pcibios_setup_root_windows(struct pci_bus *bus, struct pci_controller *ctrl) | |||
335 | } | 335 | } |
336 | 336 | ||
337 | struct pci_bus * __devinit | 337 | struct pci_bus * __devinit |
338 | pci_acpi_scan_root(struct acpi_device *device, int domain, int bus) | 338 | pci_acpi_scan_root(struct acpi_pci_root *root) |
339 | { | 339 | { |
340 | struct acpi_device *device = root->device; | ||
341 | int domain = root->segment; | ||
342 | int bus = root->secondary.start; | ||
340 | struct pci_controller *controller; | 343 | struct pci_controller *controller; |
341 | unsigned int windows = 0; | 344 | unsigned int windows = 0; |
342 | struct pci_bus *pbus; | 345 | struct pci_bus *pbus; |
diff --git a/arch/parisc/include/asm/cacheflush.h b/arch/parisc/include/asm/cacheflush.h index 477277739da5..4556d820128a 100644 --- a/arch/parisc/include/asm/cacheflush.h +++ b/arch/parisc/include/asm/cacheflush.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #define _PARISC_CACHEFLUSH_H | 2 | #define _PARISC_CACHEFLUSH_H |
3 | 3 | ||
4 | #include <linux/mm.h> | 4 | #include <linux/mm.h> |
5 | #include <linux/uaccess.h> | ||
5 | 6 | ||
6 | /* The usual comment is "Caches aren't brain-dead on the <architecture>". | 7 | /* The usual comment is "Caches aren't brain-dead on the <architecture>". |
7 | * Unfortunately, that doesn't apply to PA-RISC. */ | 8 | * Unfortunately, that doesn't apply to PA-RISC. */ |
@@ -125,11 +126,20 @@ static inline void *kmap(struct page *page) | |||
125 | 126 | ||
126 | #define kunmap(page) kunmap_parisc(page_address(page)) | 127 | #define kunmap(page) kunmap_parisc(page_address(page)) |
127 | 128 | ||
128 | #define kmap_atomic(page, idx) page_address(page) | 129 | static inline void *kmap_atomic(struct page *page, enum km_type idx) |
130 | { | ||
131 | pagefault_disable(); | ||
132 | return page_address(page); | ||
133 | } | ||
129 | 134 | ||
130 | #define kunmap_atomic(addr, idx) kunmap_parisc(addr) | 135 | static inline void kunmap_atomic(void *addr, enum km_type idx) |
136 | { | ||
137 | kunmap_parisc(addr); | ||
138 | pagefault_enable(); | ||
139 | } | ||
131 | 140 | ||
132 | #define kmap_atomic_pfn(pfn, idx) page_address(pfn_to_page(pfn)) | 141 | #define kmap_atomic_prot(page, idx, prot) kmap_atomic(page, idx) |
142 | #define kmap_atomic_pfn(pfn, idx) kmap_atomic(pfn_to_page(pfn), (idx)) | ||
133 | #define kmap_atomic_to_page(ptr) virt_to_page(ptr) | 143 | #define kmap_atomic_to_page(ptr) virt_to_page(ptr) |
134 | #endif | 144 | #endif |
135 | 145 | ||
diff --git a/arch/parisc/kernel/asm-offsets.c b/arch/parisc/kernel/asm-offsets.c index ec787b411e9a..dcd55103a4bb 100644 --- a/arch/parisc/kernel/asm-offsets.c +++ b/arch/parisc/kernel/asm-offsets.c | |||
@@ -45,8 +45,12 @@ | |||
45 | #else | 45 | #else |
46 | #define FRAME_SIZE 64 | 46 | #define FRAME_SIZE 64 |
47 | #endif | 47 | #endif |
48 | #define FRAME_ALIGN 64 | ||
48 | 49 | ||
49 | #define align(x,y) (((x)+FRAME_SIZE+(y)-1) - (((x)+(y)-1)%(y))) | 50 | /* Add FRAME_SIZE to the size x and align it to y. All definitions |
51 | * that use align_frame will include space for a frame. | ||
52 | */ | ||
53 | #define align_frame(x,y) (((x)+FRAME_SIZE+(y)-1) - (((x)+(y)-1)%(y))) | ||
50 | 54 | ||
51 | int main(void) | 55 | int main(void) |
52 | { | 56 | { |
@@ -146,7 +150,8 @@ int main(void) | |||
146 | DEFINE(TASK_PT_IOR, offsetof(struct task_struct, thread.regs.ior)); | 150 | DEFINE(TASK_PT_IOR, offsetof(struct task_struct, thread.regs.ior)); |
147 | BLANK(); | 151 | BLANK(); |
148 | DEFINE(TASK_SZ, sizeof(struct task_struct)); | 152 | DEFINE(TASK_SZ, sizeof(struct task_struct)); |
149 | DEFINE(TASK_SZ_ALGN, align(sizeof(struct task_struct), 64)); | 153 | /* TASK_SZ_ALGN includes space for a stack frame. */ |
154 | DEFINE(TASK_SZ_ALGN, align_frame(sizeof(struct task_struct), FRAME_ALIGN)); | ||
150 | BLANK(); | 155 | BLANK(); |
151 | DEFINE(PT_PSW, offsetof(struct pt_regs, gr[ 0])); | 156 | DEFINE(PT_PSW, offsetof(struct pt_regs, gr[ 0])); |
152 | DEFINE(PT_GR1, offsetof(struct pt_regs, gr[ 1])); | 157 | DEFINE(PT_GR1, offsetof(struct pt_regs, gr[ 1])); |
@@ -233,7 +238,8 @@ int main(void) | |||
233 | DEFINE(PT_ISR, offsetof(struct pt_regs, isr)); | 238 | DEFINE(PT_ISR, offsetof(struct pt_regs, isr)); |
234 | DEFINE(PT_IOR, offsetof(struct pt_regs, ior)); | 239 | DEFINE(PT_IOR, offsetof(struct pt_regs, ior)); |
235 | DEFINE(PT_SIZE, sizeof(struct pt_regs)); | 240 | DEFINE(PT_SIZE, sizeof(struct pt_regs)); |
236 | DEFINE(PT_SZ_ALGN, align(sizeof(struct pt_regs), 64)); | 241 | /* PT_SZ_ALGN includes space for a stack frame. */ |
242 | DEFINE(PT_SZ_ALGN, align_frame(sizeof(struct pt_regs), FRAME_ALIGN)); | ||
237 | BLANK(); | 243 | BLANK(); |
238 | DEFINE(TI_TASK, offsetof(struct thread_info, task)); | 244 | DEFINE(TI_TASK, offsetof(struct thread_info, task)); |
239 | DEFINE(TI_EXEC_DOMAIN, offsetof(struct thread_info, exec_domain)); | 245 | DEFINE(TI_EXEC_DOMAIN, offsetof(struct thread_info, exec_domain)); |
@@ -242,7 +248,8 @@ int main(void) | |||
242 | DEFINE(TI_SEGMENT, offsetof(struct thread_info, addr_limit)); | 248 | DEFINE(TI_SEGMENT, offsetof(struct thread_info, addr_limit)); |
243 | DEFINE(TI_PRE_COUNT, offsetof(struct thread_info, preempt_count)); | 249 | DEFINE(TI_PRE_COUNT, offsetof(struct thread_info, preempt_count)); |
244 | DEFINE(THREAD_SZ, sizeof(struct thread_info)); | 250 | DEFINE(THREAD_SZ, sizeof(struct thread_info)); |
245 | DEFINE(THREAD_SZ_ALGN, align(sizeof(struct thread_info), 64)); | 251 | /* THREAD_SZ_ALGN includes space for a stack frame. */ |
252 | DEFINE(THREAD_SZ_ALGN, align_frame(sizeof(struct thread_info), FRAME_ALIGN)); | ||
246 | BLANK(); | 253 | BLANK(); |
247 | DEFINE(ICACHE_BASE, offsetof(struct pdc_cache_info, ic_base)); | 254 | DEFINE(ICACHE_BASE, offsetof(struct pdc_cache_info, ic_base)); |
248 | DEFINE(ICACHE_STRIDE, offsetof(struct pdc_cache_info, ic_stride)); | 255 | DEFINE(ICACHE_STRIDE, offsetof(struct pdc_cache_info, ic_stride)); |
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index 3a44f7f704fa..6337adef30f6 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S | |||
@@ -364,32 +364,6 @@ | |||
364 | .align 32 | 364 | .align 32 |
365 | .endm | 365 | .endm |
366 | 366 | ||
367 | /* The following are simple 32 vs 64 bit instruction | ||
368 | * abstractions for the macros */ | ||
369 | .macro EXTR reg1,start,length,reg2 | ||
370 | #ifdef CONFIG_64BIT | ||
371 | extrd,u \reg1,32+(\start),\length,\reg2 | ||
372 | #else | ||
373 | extrw,u \reg1,\start,\length,\reg2 | ||
374 | #endif | ||
375 | .endm | ||
376 | |||
377 | .macro DEP reg1,start,length,reg2 | ||
378 | #ifdef CONFIG_64BIT | ||
379 | depd \reg1,32+(\start),\length,\reg2 | ||
380 | #else | ||
381 | depw \reg1,\start,\length,\reg2 | ||
382 | #endif | ||
383 | .endm | ||
384 | |||
385 | .macro DEPI val,start,length,reg | ||
386 | #ifdef CONFIG_64BIT | ||
387 | depdi \val,32+(\start),\length,\reg | ||
388 | #else | ||
389 | depwi \val,\start,\length,\reg | ||
390 | #endif | ||
391 | .endm | ||
392 | |||
393 | /* In LP64, the space contains part of the upper 32 bits of the | 367 | /* In LP64, the space contains part of the upper 32 bits of the |
394 | * fault. We have to extract this and place it in the va, | 368 | * fault. We have to extract this and place it in the va, |
395 | * zeroing the corresponding bits in the space register */ | 369 | * zeroing the corresponding bits in the space register */ |
@@ -442,19 +416,19 @@ | |||
442 | */ | 416 | */ |
443 | .macro L2_ptep pmd,pte,index,va,fault | 417 | .macro L2_ptep pmd,pte,index,va,fault |
444 | #if PT_NLEVELS == 3 | 418 | #if PT_NLEVELS == 3 |
445 | EXTR \va,31-ASM_PMD_SHIFT,ASM_BITS_PER_PMD,\index | 419 | extru \va,31-ASM_PMD_SHIFT,ASM_BITS_PER_PMD,\index |
446 | #else | 420 | #else |
447 | EXTR \va,31-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index | 421 | extru \va,31-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index |
448 | #endif | 422 | #endif |
449 | DEP %r0,31,PAGE_SHIFT,\pmd /* clear offset */ | 423 | dep %r0,31,PAGE_SHIFT,\pmd /* clear offset */ |
450 | copy %r0,\pte | 424 | copy %r0,\pte |
451 | ldw,s \index(\pmd),\pmd | 425 | ldw,s \index(\pmd),\pmd |
452 | bb,>=,n \pmd,_PxD_PRESENT_BIT,\fault | 426 | bb,>=,n \pmd,_PxD_PRESENT_BIT,\fault |
453 | DEP %r0,31,PxD_FLAG_SHIFT,\pmd /* clear flags */ | 427 | dep %r0,31,PxD_FLAG_SHIFT,\pmd /* clear flags */ |
454 | copy \pmd,%r9 | 428 | copy \pmd,%r9 |
455 | SHLREG %r9,PxD_VALUE_SHIFT,\pmd | 429 | SHLREG %r9,PxD_VALUE_SHIFT,\pmd |
456 | EXTR \va,31-PAGE_SHIFT,ASM_BITS_PER_PTE,\index | 430 | extru \va,31-PAGE_SHIFT,ASM_BITS_PER_PTE,\index |
457 | DEP %r0,31,PAGE_SHIFT,\pmd /* clear offset */ | 431 | dep %r0,31,PAGE_SHIFT,\pmd /* clear offset */ |
458 | shladd \index,BITS_PER_PTE_ENTRY,\pmd,\pmd | 432 | shladd \index,BITS_PER_PTE_ENTRY,\pmd,\pmd |
459 | LDREG %r0(\pmd),\pte /* pmd is now pte */ | 433 | LDREG %r0(\pmd),\pte /* pmd is now pte */ |
460 | bb,>=,n \pte,_PAGE_PRESENT_BIT,\fault | 434 | bb,>=,n \pte,_PAGE_PRESENT_BIT,\fault |
@@ -605,7 +579,7 @@ | |||
605 | depdi 0,31,32,\tmp | 579 | depdi 0,31,32,\tmp |
606 | #endif | 580 | #endif |
607 | copy \va,\tmp1 | 581 | copy \va,\tmp1 |
608 | DEPI 0,31,23,\tmp1 | 582 | depi 0,31,23,\tmp1 |
609 | cmpb,COND(<>),n \tmp,\tmp1,\fault | 583 | cmpb,COND(<>),n \tmp,\tmp1,\fault |
610 | ldi (_PAGE_DIRTY|_PAGE_WRITE|_PAGE_READ),\prot | 584 | ldi (_PAGE_DIRTY|_PAGE_WRITE|_PAGE_READ),\prot |
611 | depd,z \prot,8,7,\prot | 585 | depd,z \prot,8,7,\prot |
@@ -997,13 +971,6 @@ intr_restore: | |||
997 | 971 | ||
998 | rfi | 972 | rfi |
999 | nop | 973 | nop |
1000 | nop | ||
1001 | nop | ||
1002 | nop | ||
1003 | nop | ||
1004 | nop | ||
1005 | nop | ||
1006 | nop | ||
1007 | 974 | ||
1008 | #ifndef CONFIG_PREEMPT | 975 | #ifndef CONFIG_PREEMPT |
1009 | # define intr_do_preempt intr_restore | 976 | # define intr_do_preempt intr_restore |
@@ -2076,9 +2043,10 @@ syscall_restore: | |||
2076 | LDREG TASK_PT_GR31(%r1),%r31 /* restore syscall rp */ | 2043 | LDREG TASK_PT_GR31(%r1),%r31 /* restore syscall rp */ |
2077 | 2044 | ||
2078 | /* NOTE: We use rsm/ssm pair to make this operation atomic */ | 2045 | /* NOTE: We use rsm/ssm pair to make this operation atomic */ |
2046 | LDREG TASK_PT_GR30(%r1),%r1 /* Get user sp */ | ||
2079 | rsm PSW_SM_I, %r0 | 2047 | rsm PSW_SM_I, %r0 |
2080 | LDREG TASK_PT_GR30(%r1),%r30 /* restore user sp */ | 2048 | copy %r1,%r30 /* Restore user sp */ |
2081 | mfsp %sr3,%r1 /* Get users space id */ | 2049 | mfsp %sr3,%r1 /* Get user space id */ |
2082 | mtsp %r1,%sr7 /* Restore sr7 */ | 2050 | mtsp %r1,%sr7 /* Restore sr7 */ |
2083 | ssm PSW_SM_I, %r0 | 2051 | ssm PSW_SM_I, %r0 |
2084 | 2052 | ||
diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index f5f96021caa0..68e75ce838d6 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S | |||
@@ -47,18 +47,17 @@ ENTRY(linux_gateway_page) | |||
47 | KILL_INSN | 47 | KILL_INSN |
48 | .endr | 48 | .endr |
49 | 49 | ||
50 | /* ADDRESS 0xb0 to 0xb4, lws uses 1 insns for entry */ | 50 | /* ADDRESS 0xb0 to 0xb8, lws uses two insns for entry */ |
51 | /* Light-weight-syscall entry must always be located at 0xb0 */ | 51 | /* Light-weight-syscall entry must always be located at 0xb0 */ |
52 | /* WARNING: Keep this number updated with table size changes */ | 52 | /* WARNING: Keep this number updated with table size changes */ |
53 | #define __NR_lws_entries (2) | 53 | #define __NR_lws_entries (2) |
54 | 54 | ||
55 | lws_entry: | 55 | lws_entry: |
56 | /* Unconditional branch to lws_start, located on the | 56 | gate lws_start, %r0 /* increase privilege */ |
57 | same gateway page */ | 57 | depi 3, 31, 2, %r31 /* Ensure we return into user mode. */ |
58 | b,n lws_start | ||
59 | 58 | ||
60 | /* Fill from 0xb4 to 0xe0 */ | 59 | /* Fill from 0xb8 to 0xe0 */ |
61 | .rept 11 | 60 | .rept 10 |
62 | KILL_INSN | 61 | KILL_INSN |
63 | .endr | 62 | .endr |
64 | 63 | ||
@@ -423,9 +422,6 @@ tracesys_sigexit: | |||
423 | 422 | ||
424 | *********************************************************/ | 423 | *********************************************************/ |
425 | lws_start: | 424 | lws_start: |
426 | /* Gate and ensure we return to userspace */ | ||
427 | gate .+8, %r0 | ||
428 | depi 3, 31, 2, %r31 /* Ensure we return to userspace */ | ||
429 | 425 | ||
430 | #ifdef CONFIG_64BIT | 426 | #ifdef CONFIG_64BIT |
431 | /* FIXME: If we are a 64-bit kernel just | 427 | /* FIXME: If we are a 64-bit kernel just |
@@ -442,7 +438,7 @@ lws_start: | |||
442 | #endif | 438 | #endif |
443 | 439 | ||
444 | /* Is the lws entry number valid? */ | 440 | /* Is the lws entry number valid? */ |
445 | comiclr,>>= __NR_lws_entries, %r20, %r0 | 441 | comiclr,>> __NR_lws_entries, %r20, %r0 |
446 | b,n lws_exit_nosys | 442 | b,n lws_exit_nosys |
447 | 443 | ||
448 | /* WARNING: Trashing sr2 and sr3 */ | 444 | /* WARNING: Trashing sr2 and sr3 */ |
@@ -473,7 +469,7 @@ lws_exit: | |||
473 | /* now reset the lowest bit of sp if it was set */ | 469 | /* now reset the lowest bit of sp if it was set */ |
474 | xor %r30,%r1,%r30 | 470 | xor %r30,%r1,%r30 |
475 | #endif | 471 | #endif |
476 | be,n 0(%sr3, %r31) | 472 | be,n 0(%sr7, %r31) |
477 | 473 | ||
478 | 474 | ||
479 | 475 | ||
@@ -529,7 +525,6 @@ lws_compare_and_swap32: | |||
529 | #endif | 525 | #endif |
530 | 526 | ||
531 | lws_compare_and_swap: | 527 | lws_compare_and_swap: |
532 | #ifdef CONFIG_SMP | ||
533 | /* Load start of lock table */ | 528 | /* Load start of lock table */ |
534 | ldil L%lws_lock_start, %r20 | 529 | ldil L%lws_lock_start, %r20 |
535 | ldo R%lws_lock_start(%r20), %r28 | 530 | ldo R%lws_lock_start(%r20), %r28 |
@@ -572,8 +567,6 @@ cas_wouldblock: | |||
572 | ldo 2(%r0), %r28 /* 2nd case */ | 567 | ldo 2(%r0), %r28 /* 2nd case */ |
573 | b lws_exit /* Contended... */ | 568 | b lws_exit /* Contended... */ |
574 | ldo -EAGAIN(%r0), %r21 /* Spin in userspace */ | 569 | ldo -EAGAIN(%r0), %r21 /* Spin in userspace */ |
575 | #endif | ||
576 | /* CONFIG_SMP */ | ||
577 | 570 | ||
578 | /* | 571 | /* |
579 | prev = *addr; | 572 | prev = *addr; |
@@ -601,13 +594,11 @@ cas_action: | |||
601 | 1: ldw 0(%sr3,%r26), %r28 | 594 | 1: ldw 0(%sr3,%r26), %r28 |
602 | sub,<> %r28, %r25, %r0 | 595 | sub,<> %r28, %r25, %r0 |
603 | 2: stw %r24, 0(%sr3,%r26) | 596 | 2: stw %r24, 0(%sr3,%r26) |
604 | #ifdef CONFIG_SMP | ||
605 | /* Free lock */ | 597 | /* Free lock */ |
606 | stw %r20, 0(%sr2,%r20) | 598 | stw %r20, 0(%sr2,%r20) |
607 | # if ENABLE_LWS_DEBUG | 599 | #if ENABLE_LWS_DEBUG |
608 | /* Clear thread register indicator */ | 600 | /* Clear thread register indicator */ |
609 | stw %r0, 4(%sr2,%r20) | 601 | stw %r0, 4(%sr2,%r20) |
610 | # endif | ||
611 | #endif | 602 | #endif |
612 | /* Return to userspace, set no error */ | 603 | /* Return to userspace, set no error */ |
613 | b lws_exit | 604 | b lws_exit |
@@ -615,12 +606,10 @@ cas_action: | |||
615 | 606 | ||
616 | 3: | 607 | 3: |
617 | /* Error occured on load or store */ | 608 | /* Error occured on load or store */ |
618 | #ifdef CONFIG_SMP | ||
619 | /* Free lock */ | 609 | /* Free lock */ |
620 | stw %r20, 0(%sr2,%r20) | 610 | stw %r20, 0(%sr2,%r20) |
621 | # if ENABLE_LWS_DEBUG | 611 | #if ENABLE_LWS_DEBUG |
622 | stw %r0, 4(%sr2,%r20) | 612 | stw %r0, 4(%sr2,%r20) |
623 | # endif | ||
624 | #endif | 613 | #endif |
625 | b lws_exit | 614 | b lws_exit |
626 | ldo -EFAULT(%r0),%r21 /* set errno */ | 615 | ldo -EFAULT(%r0),%r21 /* set errno */ |
@@ -672,7 +661,6 @@ ENTRY(sys_call_table64) | |||
672 | END(sys_call_table64) | 661 | END(sys_call_table64) |
673 | #endif | 662 | #endif |
674 | 663 | ||
675 | #ifdef CONFIG_SMP | ||
676 | /* | 664 | /* |
677 | All light-weight-syscall atomic operations | 665 | All light-weight-syscall atomic operations |
678 | will use this set of locks | 666 | will use this set of locks |
@@ -694,8 +682,6 @@ ENTRY(lws_lock_start) | |||
694 | .endr | 682 | .endr |
695 | END(lws_lock_start) | 683 | END(lws_lock_start) |
696 | .previous | 684 | .previous |
697 | #endif | ||
698 | /* CONFIG_SMP for lws_lock_start */ | ||
699 | 685 | ||
700 | .end | 686 | .end |
701 | 687 | ||
diff --git a/arch/parisc/math-emu/decode_exc.c b/arch/parisc/math-emu/decode_exc.c index 3ca1c6149218..27a7492ddb0d 100644 --- a/arch/parisc/math-emu/decode_exc.c +++ b/arch/parisc/math-emu/decode_exc.c | |||
@@ -342,6 +342,7 @@ decode_fpu(unsigned int Fpu_register[], unsigned int trap_counts[]) | |||
342 | return SIGNALCODE(SIGFPE, FPE_FLTINV); | 342 | return SIGNALCODE(SIGFPE, FPE_FLTINV); |
343 | case DIVISIONBYZEROEXCEPTION: | 343 | case DIVISIONBYZEROEXCEPTION: |
344 | update_trap_counts(Fpu_register, aflags, bflags, trap_counts); | 344 | update_trap_counts(Fpu_register, aflags, bflags, trap_counts); |
345 | Clear_excp_register(exception_index); | ||
345 | return SIGNALCODE(SIGFPE, FPE_FLTDIV); | 346 | return SIGNALCODE(SIGFPE, FPE_FLTDIV); |
346 | case INEXACTEXCEPTION: | 347 | case INEXACTEXCEPTION: |
347 | update_trap_counts(Fpu_register, aflags, bflags, trap_counts); | 348 | update_trap_counts(Fpu_register, aflags, bflags, trap_counts); |
diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c index c6afbfc95770..18162ce4261e 100644 --- a/arch/parisc/mm/fault.c +++ b/arch/parisc/mm/fault.c | |||
@@ -264,8 +264,7 @@ no_context: | |||
264 | 264 | ||
265 | out_of_memory: | 265 | out_of_memory: |
266 | up_read(&mm->mmap_sem); | 266 | up_read(&mm->mmap_sem); |
267 | printk(KERN_CRIT "VM: killing process %s\n", current->comm); | 267 | if (!user_mode(regs)) |
268 | if (user_mode(regs)) | 268 | goto no_context; |
269 | do_group_exit(SIGKILL); | 269 | pagefault_out_of_memory(); |
270 | goto no_context; | ||
271 | } | 270 | } |
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 5c2808252516..1a40da92154c 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c | |||
@@ -1849,8 +1849,7 @@ out: | |||
1849 | return ret; | 1849 | return ret; |
1850 | } | 1850 | } |
1851 | 1851 | ||
1852 | static int spufs_mfc_fsync(struct file *file, struct dentry *dentry, | 1852 | static int spufs_mfc_fsync(struct file *file, int datasync) |
1853 | int datasync) | ||
1854 | { | 1853 | { |
1855 | return spufs_mfc_flush(file, NULL); | 1854 | return spufs_mfc_flush(file, NULL); |
1856 | } | 1855 | } |
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index fc1b1c42b1dc..e5e5f823d687 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c | |||
@@ -251,7 +251,7 @@ const struct file_operations spufs_context_fops = { | |||
251 | .llseek = dcache_dir_lseek, | 251 | .llseek = dcache_dir_lseek, |
252 | .read = generic_read_dir, | 252 | .read = generic_read_dir, |
253 | .readdir = dcache_readdir, | 253 | .readdir = dcache_readdir, |
254 | .fsync = simple_sync_file, | 254 | .fsync = noop_fsync, |
255 | }; | 255 | }; |
256 | EXPORT_SYMBOL_GPL(spufs_context_fops); | 256 | EXPORT_SYMBOL_GPL(spufs_context_fops); |
257 | 257 | ||
diff --git a/arch/powerpc/platforms/pseries/hvCall_inst.c b/arch/powerpc/platforms/pseries/hvCall_inst.c index 1fefae76e295..e19ff021e711 100644 --- a/arch/powerpc/platforms/pseries/hvCall_inst.c +++ b/arch/powerpc/platforms/pseries/hvCall_inst.c | |||
@@ -102,7 +102,7 @@ static const struct file_operations hcall_inst_seq_fops = { | |||
102 | #define CPU_NAME_BUF_SIZE 32 | 102 | #define CPU_NAME_BUF_SIZE 32 |
103 | 103 | ||
104 | 104 | ||
105 | static void probe_hcall_entry(unsigned long opcode, unsigned long *args) | 105 | static void probe_hcall_entry(void *ignored, unsigned long opcode, unsigned long *args) |
106 | { | 106 | { |
107 | struct hcall_stats *h; | 107 | struct hcall_stats *h; |
108 | 108 | ||
@@ -114,7 +114,7 @@ static void probe_hcall_entry(unsigned long opcode, unsigned long *args) | |||
114 | h->purr_start = mfspr(SPRN_PURR); | 114 | h->purr_start = mfspr(SPRN_PURR); |
115 | } | 115 | } |
116 | 116 | ||
117 | static void probe_hcall_exit(unsigned long opcode, unsigned long retval, | 117 | static void probe_hcall_exit(void *ignored, unsigned long opcode, unsigned long retval, |
118 | unsigned long *retbuf) | 118 | unsigned long *retbuf) |
119 | { | 119 | { |
120 | struct hcall_stats *h; | 120 | struct hcall_stats *h; |
@@ -140,11 +140,11 @@ static int __init hcall_inst_init(void) | |||
140 | if (!firmware_has_feature(FW_FEATURE_LPAR)) | 140 | if (!firmware_has_feature(FW_FEATURE_LPAR)) |
141 | return 0; | 141 | return 0; |
142 | 142 | ||
143 | if (register_trace_hcall_entry(probe_hcall_entry)) | 143 | if (register_trace_hcall_entry(probe_hcall_entry, NULL)) |
144 | return -EINVAL; | 144 | return -EINVAL; |
145 | 145 | ||
146 | if (register_trace_hcall_exit(probe_hcall_exit)) { | 146 | if (register_trace_hcall_exit(probe_hcall_exit, NULL)) { |
147 | unregister_trace_hcall_entry(probe_hcall_entry); | 147 | unregister_trace_hcall_entry(probe_hcall_entry, NULL); |
148 | return -EINVAL; | 148 | return -EINVAL; |
149 | } | 149 | } |
150 | 150 | ||
diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index 56f462cf22d2..aa2c39d968fc 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h | |||
@@ -85,7 +85,6 @@ extern int acpi_ioapic; | |||
85 | extern int acpi_noirq; | 85 | extern int acpi_noirq; |
86 | extern int acpi_strict; | 86 | extern int acpi_strict; |
87 | extern int acpi_disabled; | 87 | extern int acpi_disabled; |
88 | extern int acpi_ht; | ||
89 | extern int acpi_pci_disabled; | 88 | extern int acpi_pci_disabled; |
90 | extern int acpi_skip_timer_override; | 89 | extern int acpi_skip_timer_override; |
91 | extern int acpi_use_timer_override; | 90 | extern int acpi_use_timer_override; |
@@ -97,7 +96,6 @@ void acpi_pic_sci_set_trigger(unsigned int, u16); | |||
97 | static inline void disable_acpi(void) | 96 | static inline void disable_acpi(void) |
98 | { | 97 | { |
99 | acpi_disabled = 1; | 98 | acpi_disabled = 1; |
100 | acpi_ht = 0; | ||
101 | acpi_pci_disabled = 1; | 99 | acpi_pci_disabled = 1; |
102 | acpi_noirq = 1; | 100 | acpi_noirq = 1; |
103 | } | 101 | } |
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index dca9c545f44e..468145914389 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h | |||
@@ -332,6 +332,7 @@ static __always_inline __pure bool __static_cpu_has(u8 bit) | |||
332 | #endif | 332 | #endif |
333 | } | 333 | } |
334 | 334 | ||
335 | #if __GNUC__ >= 4 | ||
335 | #define static_cpu_has(bit) \ | 336 | #define static_cpu_has(bit) \ |
336 | ( \ | 337 | ( \ |
337 | __builtin_constant_p(boot_cpu_has(bit)) ? \ | 338 | __builtin_constant_p(boot_cpu_has(bit)) ? \ |
@@ -340,6 +341,12 @@ static __always_inline __pure bool __static_cpu_has(u8 bit) | |||
340 | __static_cpu_has(bit) : \ | 341 | __static_cpu_has(bit) : \ |
341 | boot_cpu_has(bit) \ | 342 | boot_cpu_has(bit) \ |
342 | ) | 343 | ) |
344 | #else | ||
345 | /* | ||
346 | * gcc 3.x is too stupid to do the static test; fall back to dynamic. | ||
347 | */ | ||
348 | #define static_cpu_has(bit) boot_cpu_has(bit) | ||
349 | #endif | ||
343 | 350 | ||
344 | #endif /* defined(__KERNEL__) && !defined(__ASSEMBLY__) */ | 351 | #endif /* defined(__KERNEL__) && !defined(__ASSEMBLY__) */ |
345 | 352 | ||
diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h index 6c3fdd631ed3..f32a4301c4d4 100644 --- a/arch/x86/include/asm/mce.h +++ b/arch/x86/include/asm/mce.h | |||
@@ -225,5 +225,13 @@ extern void mcheck_intel_therm_init(void); | |||
225 | static inline void mcheck_intel_therm_init(void) { } | 225 | static inline void mcheck_intel_therm_init(void) { } |
226 | #endif | 226 | #endif |
227 | 227 | ||
228 | /* | ||
229 | * Used by APEI to report memory error via /dev/mcelog | ||
230 | */ | ||
231 | |||
232 | struct cper_sec_mem_err; | ||
233 | extern void apei_mce_report_mem_error(int corrected, | ||
234 | struct cper_sec_mem_err *mem_err); | ||
235 | |||
228 | #endif /* __KERNEL__ */ | 236 | #endif /* __KERNEL__ */ |
229 | #endif /* _ASM_X86_MCE_H */ | 237 | #endif /* _ASM_X86_MCE_H */ |
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index 62ba9400cc43..f0b6e5dbc5a0 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h | |||
@@ -239,8 +239,8 @@ static inline struct thread_info *current_thread_info(void) | |||
239 | #define TS_USEDFPU 0x0001 /* FPU was used by this task | 239 | #define TS_USEDFPU 0x0001 /* FPU was used by this task |
240 | this quantum (SMP) */ | 240 | this quantum (SMP) */ |
241 | #define TS_COMPAT 0x0002 /* 32bit syscall active (64BIT)*/ | 241 | #define TS_COMPAT 0x0002 /* 32bit syscall active (64BIT)*/ |
242 | #define TS_POLLING 0x0004 /* true if in idle loop | 242 | #define TS_POLLING 0x0004 /* idle task polling need_resched, |
243 | and not sleeping */ | 243 | skip sending interrupt */ |
244 | #define TS_RESTORE_SIGMASK 0x0008 /* restore signal mask in do_signal() */ | 244 | #define TS_RESTORE_SIGMASK 0x0008 /* restore signal mask in do_signal() */ |
245 | 245 | ||
246 | #define tsk_is_polling(t) (task_thread_info(t)->status & TS_POLLING) | 246 | #define tsk_is_polling(t) (task_thread_info(t)->status & TS_POLLING) |
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 488be461a380..60cc4058ed5f 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c | |||
@@ -63,7 +63,6 @@ EXPORT_SYMBOL(acpi_disabled); | |||
63 | int acpi_noirq; /* skip ACPI IRQ initialization */ | 63 | int acpi_noirq; /* skip ACPI IRQ initialization */ |
64 | int acpi_pci_disabled; /* skip ACPI PCI scan and IRQ initialization */ | 64 | int acpi_pci_disabled; /* skip ACPI PCI scan and IRQ initialization */ |
65 | EXPORT_SYMBOL(acpi_pci_disabled); | 65 | EXPORT_SYMBOL(acpi_pci_disabled); |
66 | int acpi_ht __initdata = 1; /* enable HT */ | ||
67 | 66 | ||
68 | int acpi_lapic; | 67 | int acpi_lapic; |
69 | int acpi_ioapic; | 68 | int acpi_ioapic; |
@@ -1501,9 +1500,8 @@ void __init acpi_boot_table_init(void) | |||
1501 | 1500 | ||
1502 | /* | 1501 | /* |
1503 | * If acpi_disabled, bail out | 1502 | * If acpi_disabled, bail out |
1504 | * One exception: acpi=ht continues far enough to enumerate LAPICs | ||
1505 | */ | 1503 | */ |
1506 | if (acpi_disabled && !acpi_ht) | 1504 | if (acpi_disabled) |
1507 | return; | 1505 | return; |
1508 | 1506 | ||
1509 | /* | 1507 | /* |
@@ -1534,9 +1532,8 @@ int __init early_acpi_boot_init(void) | |||
1534 | { | 1532 | { |
1535 | /* | 1533 | /* |
1536 | * If acpi_disabled, bail out | 1534 | * If acpi_disabled, bail out |
1537 | * One exception: acpi=ht continues far enough to enumerate LAPICs | ||
1538 | */ | 1535 | */ |
1539 | if (acpi_disabled && !acpi_ht) | 1536 | if (acpi_disabled) |
1540 | return 1; | 1537 | return 1; |
1541 | 1538 | ||
1542 | /* | 1539 | /* |
@@ -1554,9 +1551,8 @@ int __init acpi_boot_init(void) | |||
1554 | 1551 | ||
1555 | /* | 1552 | /* |
1556 | * If acpi_disabled, bail out | 1553 | * If acpi_disabled, bail out |
1557 | * One exception: acpi=ht continues far enough to enumerate LAPICs | ||
1558 | */ | 1554 | */ |
1559 | if (acpi_disabled && !acpi_ht) | 1555 | if (acpi_disabled) |
1560 | return 1; | 1556 | return 1; |
1561 | 1557 | ||
1562 | acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf); | 1558 | acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf); |
@@ -1591,21 +1587,12 @@ static int __init parse_acpi(char *arg) | |||
1591 | /* acpi=force to over-ride black-list */ | 1587 | /* acpi=force to over-ride black-list */ |
1592 | else if (strcmp(arg, "force") == 0) { | 1588 | else if (strcmp(arg, "force") == 0) { |
1593 | acpi_force = 1; | 1589 | acpi_force = 1; |
1594 | acpi_ht = 1; | ||
1595 | acpi_disabled = 0; | 1590 | acpi_disabled = 0; |
1596 | } | 1591 | } |
1597 | /* acpi=strict disables out-of-spec workarounds */ | 1592 | /* acpi=strict disables out-of-spec workarounds */ |
1598 | else if (strcmp(arg, "strict") == 0) { | 1593 | else if (strcmp(arg, "strict") == 0) { |
1599 | acpi_strict = 1; | 1594 | acpi_strict = 1; |
1600 | } | 1595 | } |
1601 | /* Limit ACPI just to boot-time to enable HT */ | ||
1602 | else if (strcmp(arg, "ht") == 0) { | ||
1603 | if (!acpi_force) { | ||
1604 | printk(KERN_WARNING "acpi=ht will be removed in Linux-2.6.35\n"); | ||
1605 | disable_acpi(); | ||
1606 | } | ||
1607 | acpi_ht = 1; | ||
1608 | } | ||
1609 | /* acpi=rsdt use RSDT instead of XSDT */ | 1596 | /* acpi=rsdt use RSDT instead of XSDT */ |
1610 | else if (strcmp(arg, "rsdt") == 0) { | 1597 | else if (strcmp(arg, "rsdt") == 0) { |
1611 | acpi_rsdt_forced = 1; | 1598 | acpi_rsdt_forced = 1; |
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c index f9961034e557..82e508677b91 100644 --- a/arch/x86/kernel/acpi/sleep.c +++ b/arch/x86/kernel/acpi/sleep.c | |||
@@ -162,8 +162,6 @@ static int __init acpi_sleep_setup(char *str) | |||
162 | #endif | 162 | #endif |
163 | if (strncmp(str, "old_ordering", 12) == 0) | 163 | if (strncmp(str, "old_ordering", 12) == 0) |
164 | acpi_old_suspend_ordering(); | 164 | acpi_old_suspend_ordering(); |
165 | if (strncmp(str, "sci_force_enable", 16) == 0) | ||
166 | acpi_set_sci_en_on_resume(); | ||
167 | str = strchr(str, ','); | 165 | str = strchr(str, ','); |
168 | if (str != NULL) | 166 | if (str != NULL) |
169 | str += strspn(str, ", \t"); | 167 | str += strspn(str, ", \t"); |
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index e5a4a1e01618..c02cc692985c 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #include <asm/smp.h> | 51 | #include <asm/smp.h> |
52 | #include <asm/mce.h> | 52 | #include <asm/mce.h> |
53 | #include <asm/kvm_para.h> | 53 | #include <asm/kvm_para.h> |
54 | #include <asm/tsc.h> | ||
54 | 55 | ||
55 | unsigned int num_processors; | 56 | unsigned int num_processors; |
56 | 57 | ||
@@ -1151,8 +1152,13 @@ static void __cpuinit lapic_setup_esr(void) | |||
1151 | */ | 1152 | */ |
1152 | void __cpuinit setup_local_APIC(void) | 1153 | void __cpuinit setup_local_APIC(void) |
1153 | { | 1154 | { |
1154 | unsigned int value; | 1155 | unsigned int value, queued; |
1155 | int i, j; | 1156 | int i, j, acked = 0; |
1157 | unsigned long long tsc = 0, ntsc; | ||
1158 | long long max_loops = cpu_khz; | ||
1159 | |||
1160 | if (cpu_has_tsc) | ||
1161 | rdtscll(tsc); | ||
1156 | 1162 | ||
1157 | if (disable_apic) { | 1163 | if (disable_apic) { |
1158 | arch_disable_smp_support(); | 1164 | arch_disable_smp_support(); |
@@ -1204,13 +1210,32 @@ void __cpuinit setup_local_APIC(void) | |||
1204 | * the interrupt. Hence a vector might get locked. It was noticed | 1210 | * the interrupt. Hence a vector might get locked. It was noticed |
1205 | * for timer irq (vector 0x31). Issue an extra EOI to clear ISR. | 1211 | * for timer irq (vector 0x31). Issue an extra EOI to clear ISR. |
1206 | */ | 1212 | */ |
1207 | for (i = APIC_ISR_NR - 1; i >= 0; i--) { | 1213 | do { |
1208 | value = apic_read(APIC_ISR + i*0x10); | 1214 | queued = 0; |
1209 | for (j = 31; j >= 0; j--) { | 1215 | for (i = APIC_ISR_NR - 1; i >= 0; i--) |
1210 | if (value & (1<<j)) | 1216 | queued |= apic_read(APIC_IRR + i*0x10); |
1211 | ack_APIC_irq(); | 1217 | |
1218 | for (i = APIC_ISR_NR - 1; i >= 0; i--) { | ||
1219 | value = apic_read(APIC_ISR + i*0x10); | ||
1220 | for (j = 31; j >= 0; j--) { | ||
1221 | if (value & (1<<j)) { | ||
1222 | ack_APIC_irq(); | ||
1223 | acked++; | ||
1224 | } | ||
1225 | } | ||
1212 | } | 1226 | } |
1213 | } | 1227 | if (acked > 256) { |
1228 | printk(KERN_ERR "LAPIC pending interrupts after %d EOI\n", | ||
1229 | acked); | ||
1230 | break; | ||
1231 | } | ||
1232 | if (cpu_has_tsc) { | ||
1233 | rdtscll(ntsc); | ||
1234 | max_loops = (cpu_khz << 10) - (ntsc - tsc); | ||
1235 | } else | ||
1236 | max_loops--; | ||
1237 | } while (queued && max_loops > 0); | ||
1238 | WARN_ON(max_loops <= 0); | ||
1214 | 1239 | ||
1215 | /* | 1240 | /* |
1216 | * Now that we are all set up, enable the APIC | 1241 | * Now that we are all set up, enable the APIC |
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c index 6f3dc8fbbfdc..7ec2123838e6 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c | |||
@@ -1497,8 +1497,8 @@ static struct cpufreq_driver cpufreq_amd64_driver = { | |||
1497 | * simply keep the boost-disable flag in sync with the current global | 1497 | * simply keep the boost-disable flag in sync with the current global |
1498 | * state. | 1498 | * state. |
1499 | */ | 1499 | */ |
1500 | static int __cpuinit cpb_notify(struct notifier_block *nb, unsigned long action, | 1500 | static int cpb_notify(struct notifier_block *nb, unsigned long action, |
1501 | void *hcpu) | 1501 | void *hcpu) |
1502 | { | 1502 | { |
1503 | unsigned cpu = (long)hcpu; | 1503 | unsigned cpu = (long)hcpu; |
1504 | u32 lo, hi; | 1504 | u32 lo, hi; |
@@ -1528,7 +1528,7 @@ static int __cpuinit cpb_notify(struct notifier_block *nb, unsigned long action, | |||
1528 | return NOTIFY_OK; | 1528 | return NOTIFY_OK; |
1529 | } | 1529 | } |
1530 | 1530 | ||
1531 | static struct notifier_block __cpuinitdata cpb_nb = { | 1531 | static struct notifier_block cpb_nb = { |
1532 | .notifier_call = cpb_notify, | 1532 | .notifier_call = cpb_notify, |
1533 | }; | 1533 | }; |
1534 | 1534 | ||
diff --git a/arch/x86/kernel/cpu/mcheck/Makefile b/arch/x86/kernel/cpu/mcheck/Makefile index 4ac6d48fe11b..bb34b03af252 100644 --- a/arch/x86/kernel/cpu/mcheck/Makefile +++ b/arch/x86/kernel/cpu/mcheck/Makefile | |||
@@ -7,3 +7,5 @@ obj-$(CONFIG_X86_MCE_THRESHOLD) += threshold.o | |||
7 | obj-$(CONFIG_X86_MCE_INJECT) += mce-inject.o | 7 | obj-$(CONFIG_X86_MCE_INJECT) += mce-inject.o |
8 | 8 | ||
9 | obj-$(CONFIG_X86_THERMAL_VECTOR) += therm_throt.o | 9 | obj-$(CONFIG_X86_THERMAL_VECTOR) += therm_throt.o |
10 | |||
11 | obj-$(CONFIG_ACPI_APEI) += mce-apei.o | ||
diff --git a/arch/x86/kernel/cpu/mcheck/mce-apei.c b/arch/x86/kernel/cpu/mcheck/mce-apei.c new file mode 100644 index 000000000000..745b54f9be89 --- /dev/null +++ b/arch/x86/kernel/cpu/mcheck/mce-apei.c | |||
@@ -0,0 +1,138 @@ | |||
1 | /* | ||
2 | * Bridge between MCE and APEI | ||
3 | * | ||
4 | * On some machine, corrected memory errors are reported via APEI | ||
5 | * generic hardware error source (GHES) instead of corrected Machine | ||
6 | * Check. These corrected memory errors can be reported to user space | ||
7 | * through /dev/mcelog via faking a corrected Machine Check, so that | ||
8 | * the error memory page can be offlined by /sbin/mcelog if the error | ||
9 | * count for one page is beyond the threshold. | ||
10 | * | ||
11 | * For fatal MCE, save MCE record into persistent storage via ERST, so | ||
12 | * that the MCE record can be logged after reboot via ERST. | ||
13 | * | ||
14 | * Copyright 2010 Intel Corp. | ||
15 | * Author: Huang Ying <ying.huang@intel.com> | ||
16 | * | ||
17 | * This program is free software; you can redistribute it and/or | ||
18 | * modify it under the terms of the GNU General Public License version | ||
19 | * 2 as published by the Free Software Foundation. | ||
20 | * | ||
21 | * This program is distributed in the hope that it will be useful, | ||
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
24 | * GNU General Public License for more details. | ||
25 | * | ||
26 | * You should have received a copy of the GNU General Public License | ||
27 | * along with this program; if not, write to the Free Software | ||
28 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
29 | */ | ||
30 | |||
31 | #include <linux/kernel.h> | ||
32 | #include <linux/acpi.h> | ||
33 | #include <linux/cper.h> | ||
34 | #include <acpi/apei.h> | ||
35 | #include <asm/mce.h> | ||
36 | |||
37 | #include "mce-internal.h" | ||
38 | |||
39 | void apei_mce_report_mem_error(int corrected, struct cper_sec_mem_err *mem_err) | ||
40 | { | ||
41 | struct mce m; | ||
42 | |||
43 | /* Only corrected MC is reported */ | ||
44 | if (!corrected) | ||
45 | return; | ||
46 | |||
47 | mce_setup(&m); | ||
48 | m.bank = 1; | ||
49 | /* Fake a memory read corrected error with unknown channel */ | ||
50 | m.status = MCI_STATUS_VAL | MCI_STATUS_EN | MCI_STATUS_ADDRV | 0x9f; | ||
51 | m.addr = mem_err->physical_addr; | ||
52 | mce_log(&m); | ||
53 | mce_notify_irq(); | ||
54 | } | ||
55 | EXPORT_SYMBOL_GPL(apei_mce_report_mem_error); | ||
56 | |||
57 | #define CPER_CREATOR_MCE \ | ||
58 | UUID_LE(0x75a574e3, 0x5052, 0x4b29, 0x8a, 0x8e, 0xbe, 0x2c, \ | ||
59 | 0x64, 0x90, 0xb8, 0x9d) | ||
60 | #define CPER_SECTION_TYPE_MCE \ | ||
61 | UUID_LE(0xfe08ffbe, 0x95e4, 0x4be7, 0xbc, 0x73, 0x40, 0x96, \ | ||
62 | 0x04, 0x4a, 0x38, 0xfc) | ||
63 | |||
64 | /* | ||
65 | * CPER specification (in UEFI specification 2.3 appendix N) requires | ||
66 | * byte-packed. | ||
67 | */ | ||
68 | struct cper_mce_record { | ||
69 | struct cper_record_header hdr; | ||
70 | struct cper_section_descriptor sec_hdr; | ||
71 | struct mce mce; | ||
72 | } __packed; | ||
73 | |||
74 | int apei_write_mce(struct mce *m) | ||
75 | { | ||
76 | struct cper_mce_record rcd; | ||
77 | |||
78 | memset(&rcd, 0, sizeof(rcd)); | ||
79 | memcpy(rcd.hdr.signature, CPER_SIG_RECORD, CPER_SIG_SIZE); | ||
80 | rcd.hdr.revision = CPER_RECORD_REV; | ||
81 | rcd.hdr.signature_end = CPER_SIG_END; | ||
82 | rcd.hdr.section_count = 1; | ||
83 | rcd.hdr.error_severity = CPER_SER_FATAL; | ||
84 | /* timestamp, platform_id, partition_id are all invalid */ | ||
85 | rcd.hdr.validation_bits = 0; | ||
86 | rcd.hdr.record_length = sizeof(rcd); | ||
87 | rcd.hdr.creator_id = CPER_CREATOR_MCE; | ||
88 | rcd.hdr.notification_type = CPER_NOTIFY_MCE; | ||
89 | rcd.hdr.record_id = cper_next_record_id(); | ||
90 | rcd.hdr.flags = CPER_HW_ERROR_FLAGS_PREVERR; | ||
91 | |||
92 | rcd.sec_hdr.section_offset = (void *)&rcd.mce - (void *)&rcd; | ||
93 | rcd.sec_hdr.section_length = sizeof(rcd.mce); | ||
94 | rcd.sec_hdr.revision = CPER_SEC_REV; | ||
95 | /* fru_id and fru_text is invalid */ | ||
96 | rcd.sec_hdr.validation_bits = 0; | ||
97 | rcd.sec_hdr.flags = CPER_SEC_PRIMARY; | ||
98 | rcd.sec_hdr.section_type = CPER_SECTION_TYPE_MCE; | ||
99 | rcd.sec_hdr.section_severity = CPER_SER_FATAL; | ||
100 | |||
101 | memcpy(&rcd.mce, m, sizeof(*m)); | ||
102 | |||
103 | return erst_write(&rcd.hdr); | ||
104 | } | ||
105 | |||
106 | ssize_t apei_read_mce(struct mce *m, u64 *record_id) | ||
107 | { | ||
108 | struct cper_mce_record rcd; | ||
109 | ssize_t len; | ||
110 | |||
111 | len = erst_read_next(&rcd.hdr, sizeof(rcd)); | ||
112 | if (len <= 0) | ||
113 | return len; | ||
114 | /* Can not skip other records in storage via ERST unless clear them */ | ||
115 | else if (len != sizeof(rcd) || | ||
116 | uuid_le_cmp(rcd.hdr.creator_id, CPER_CREATOR_MCE)) { | ||
117 | if (printk_ratelimit()) | ||
118 | pr_warning( | ||
119 | "MCE-APEI: Can not skip the unknown record in ERST"); | ||
120 | return -EIO; | ||
121 | } | ||
122 | |||
123 | memcpy(m, &rcd.mce, sizeof(*m)); | ||
124 | *record_id = rcd.hdr.record_id; | ||
125 | |||
126 | return sizeof(*m); | ||
127 | } | ||
128 | |||
129 | /* Check whether there is record in ERST */ | ||
130 | int apei_check_mce(void) | ||
131 | { | ||
132 | return erst_get_record_count(); | ||
133 | } | ||
134 | |||
135 | int apei_clear_mce(u64 record_id) | ||
136 | { | ||
137 | return erst_clear(record_id); | ||
138 | } | ||
diff --git a/arch/x86/kernel/cpu/mcheck/mce-internal.h b/arch/x86/kernel/cpu/mcheck/mce-internal.h index 32996f9fab67..fefcc69ee8b5 100644 --- a/arch/x86/kernel/cpu/mcheck/mce-internal.h +++ b/arch/x86/kernel/cpu/mcheck/mce-internal.h | |||
@@ -28,3 +28,26 @@ extern int mce_ser; | |||
28 | 28 | ||
29 | extern struct mce_bank *mce_banks; | 29 | extern struct mce_bank *mce_banks; |
30 | 30 | ||
31 | #ifdef CONFIG_ACPI_APEI | ||
32 | int apei_write_mce(struct mce *m); | ||
33 | ssize_t apei_read_mce(struct mce *m, u64 *record_id); | ||
34 | int apei_check_mce(void); | ||
35 | int apei_clear_mce(u64 record_id); | ||
36 | #else | ||
37 | static inline int apei_write_mce(struct mce *m) | ||
38 | { | ||
39 | return -EINVAL; | ||
40 | } | ||
41 | static inline ssize_t apei_read_mce(struct mce *m, u64 *record_id) | ||
42 | { | ||
43 | return 0; | ||
44 | } | ||
45 | static inline int apei_check_mce(void) | ||
46 | { | ||
47 | return 0; | ||
48 | } | ||
49 | static inline int apei_clear_mce(u64 record_id) | ||
50 | { | ||
51 | return -EINVAL; | ||
52 | } | ||
53 | #endif | ||
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 7a355ddcc64b..707165dbc203 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c | |||
@@ -264,7 +264,7 @@ static void wait_for_panic(void) | |||
264 | 264 | ||
265 | static void mce_panic(char *msg, struct mce *final, char *exp) | 265 | static void mce_panic(char *msg, struct mce *final, char *exp) |
266 | { | 266 | { |
267 | int i; | 267 | int i, apei_err = 0; |
268 | 268 | ||
269 | if (!fake_panic) { | 269 | if (!fake_panic) { |
270 | /* | 270 | /* |
@@ -287,8 +287,11 @@ static void mce_panic(char *msg, struct mce *final, char *exp) | |||
287 | struct mce *m = &mcelog.entry[i]; | 287 | struct mce *m = &mcelog.entry[i]; |
288 | if (!(m->status & MCI_STATUS_VAL)) | 288 | if (!(m->status & MCI_STATUS_VAL)) |
289 | continue; | 289 | continue; |
290 | if (!(m->status & MCI_STATUS_UC)) | 290 | if (!(m->status & MCI_STATUS_UC)) { |
291 | print_mce(m); | 291 | print_mce(m); |
292 | if (!apei_err) | ||
293 | apei_err = apei_write_mce(m); | ||
294 | } | ||
292 | } | 295 | } |
293 | /* Now print uncorrected but with the final one last */ | 296 | /* Now print uncorrected but with the final one last */ |
294 | for (i = 0; i < MCE_LOG_LEN; i++) { | 297 | for (i = 0; i < MCE_LOG_LEN; i++) { |
@@ -297,11 +300,17 @@ static void mce_panic(char *msg, struct mce *final, char *exp) | |||
297 | continue; | 300 | continue; |
298 | if (!(m->status & MCI_STATUS_UC)) | 301 | if (!(m->status & MCI_STATUS_UC)) |
299 | continue; | 302 | continue; |
300 | if (!final || memcmp(m, final, sizeof(struct mce))) | 303 | if (!final || memcmp(m, final, sizeof(struct mce))) { |
301 | print_mce(m); | 304 | print_mce(m); |
305 | if (!apei_err) | ||
306 | apei_err = apei_write_mce(m); | ||
307 | } | ||
302 | } | 308 | } |
303 | if (final) | 309 | if (final) { |
304 | print_mce(final); | 310 | print_mce(final); |
311 | if (!apei_err) | ||
312 | apei_err = apei_write_mce(final); | ||
313 | } | ||
305 | if (cpu_missing) | 314 | if (cpu_missing) |
306 | printk(KERN_EMERG "Some CPUs didn't answer in synchronization\n"); | 315 | printk(KERN_EMERG "Some CPUs didn't answer in synchronization\n"); |
307 | print_mce_tail(); | 316 | print_mce_tail(); |
@@ -1493,6 +1502,43 @@ static void collect_tscs(void *data) | |||
1493 | rdtscll(cpu_tsc[smp_processor_id()]); | 1502 | rdtscll(cpu_tsc[smp_processor_id()]); |
1494 | } | 1503 | } |
1495 | 1504 | ||
1505 | static int mce_apei_read_done; | ||
1506 | |||
1507 | /* Collect MCE record of previous boot in persistent storage via APEI ERST. */ | ||
1508 | static int __mce_read_apei(char __user **ubuf, size_t usize) | ||
1509 | { | ||
1510 | int rc; | ||
1511 | u64 record_id; | ||
1512 | struct mce m; | ||
1513 | |||
1514 | if (usize < sizeof(struct mce)) | ||
1515 | return -EINVAL; | ||
1516 | |||
1517 | rc = apei_read_mce(&m, &record_id); | ||
1518 | /* Error or no more MCE record */ | ||
1519 | if (rc <= 0) { | ||
1520 | mce_apei_read_done = 1; | ||
1521 | return rc; | ||
1522 | } | ||
1523 | rc = -EFAULT; | ||
1524 | if (copy_to_user(*ubuf, &m, sizeof(struct mce))) | ||
1525 | return rc; | ||
1526 | /* | ||
1527 | * In fact, we should have cleared the record after that has | ||
1528 | * been flushed to the disk or sent to network in | ||
1529 | * /sbin/mcelog, but we have no interface to support that now, | ||
1530 | * so just clear it to avoid duplication. | ||
1531 | */ | ||
1532 | rc = apei_clear_mce(record_id); | ||
1533 | if (rc) { | ||
1534 | mce_apei_read_done = 1; | ||
1535 | return rc; | ||
1536 | } | ||
1537 | *ubuf += sizeof(struct mce); | ||
1538 | |||
1539 | return 0; | ||
1540 | } | ||
1541 | |||
1496 | static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize, | 1542 | static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize, |
1497 | loff_t *off) | 1543 | loff_t *off) |
1498 | { | 1544 | { |
@@ -1506,15 +1552,19 @@ static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize, | |||
1506 | return -ENOMEM; | 1552 | return -ENOMEM; |
1507 | 1553 | ||
1508 | mutex_lock(&mce_read_mutex); | 1554 | mutex_lock(&mce_read_mutex); |
1555 | |||
1556 | if (!mce_apei_read_done) { | ||
1557 | err = __mce_read_apei(&buf, usize); | ||
1558 | if (err || buf != ubuf) | ||
1559 | goto out; | ||
1560 | } | ||
1561 | |||
1509 | next = rcu_dereference_check_mce(mcelog.next); | 1562 | next = rcu_dereference_check_mce(mcelog.next); |
1510 | 1563 | ||
1511 | /* Only supports full reads right now */ | 1564 | /* Only supports full reads right now */ |
1512 | if (*off != 0 || usize < MCE_LOG_LEN*sizeof(struct mce)) { | 1565 | err = -EINVAL; |
1513 | mutex_unlock(&mce_read_mutex); | 1566 | if (*off != 0 || usize < MCE_LOG_LEN*sizeof(struct mce)) |
1514 | kfree(cpu_tsc); | 1567 | goto out; |
1515 | |||
1516 | return -EINVAL; | ||
1517 | } | ||
1518 | 1568 | ||
1519 | err = 0; | 1569 | err = 0; |
1520 | prev = 0; | 1570 | prev = 0; |
@@ -1562,10 +1612,15 @@ timeout: | |||
1562 | memset(&mcelog.entry[i], 0, sizeof(struct mce)); | 1612 | memset(&mcelog.entry[i], 0, sizeof(struct mce)); |
1563 | } | 1613 | } |
1564 | } | 1614 | } |
1615 | |||
1616 | if (err) | ||
1617 | err = -EFAULT; | ||
1618 | |||
1619 | out: | ||
1565 | mutex_unlock(&mce_read_mutex); | 1620 | mutex_unlock(&mce_read_mutex); |
1566 | kfree(cpu_tsc); | 1621 | kfree(cpu_tsc); |
1567 | 1622 | ||
1568 | return err ? -EFAULT : buf - ubuf; | 1623 | return err ? err : buf - ubuf; |
1569 | } | 1624 | } |
1570 | 1625 | ||
1571 | static unsigned int mce_poll(struct file *file, poll_table *wait) | 1626 | static unsigned int mce_poll(struct file *file, poll_table *wait) |
@@ -1573,6 +1628,8 @@ static unsigned int mce_poll(struct file *file, poll_table *wait) | |||
1573 | poll_wait(file, &mce_wait, wait); | 1628 | poll_wait(file, &mce_wait, wait); |
1574 | if (rcu_dereference_check_mce(mcelog.next)) | 1629 | if (rcu_dereference_check_mce(mcelog.next)) |
1575 | return POLLIN | POLLRDNORM; | 1630 | return POLLIN | POLLRDNORM; |
1631 | if (!mce_apei_read_done && apei_check_mce()) | ||
1632 | return POLLIN | POLLRDNORM; | ||
1576 | return 0; | 1633 | return 0; |
1577 | } | 1634 | } |
1578 | 1635 | ||
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index e8029896309a..b4ae4acbd031 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
@@ -676,6 +676,17 @@ static struct dmi_system_id __initdata bad_bios_dmi_table[] = { | |||
676 | DMI_MATCH(DMI_BOARD_NAME, "DG45FC"), | 676 | DMI_MATCH(DMI_BOARD_NAME, "DG45FC"), |
677 | }, | 677 | }, |
678 | }, | 678 | }, |
679 | /* | ||
680 | * The Dell Inspiron Mini 1012 has DMI_BIOS_VENDOR = "Dell Inc.", so | ||
681 | * match on the product name. | ||
682 | */ | ||
683 | { | ||
684 | .callback = dmi_low_memory_corruption, | ||
685 | .ident = "Phoenix BIOS", | ||
686 | .matches = { | ||
687 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1012"), | ||
688 | }, | ||
689 | }, | ||
679 | #endif | 690 | #endif |
680 | {} | 691 | {} |
681 | }; | 692 | }; |
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 763d815e27a0..37462f1ddba5 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
@@ -1215,9 +1215,17 @@ __init void prefill_possible_map(void) | |||
1215 | if (!num_processors) | 1215 | if (!num_processors) |
1216 | num_processors = 1; | 1216 | num_processors = 1; |
1217 | 1217 | ||
1218 | if (setup_possible_cpus == -1) | 1218 | i = setup_max_cpus ?: 1; |
1219 | possible = num_processors + disabled_cpus; | 1219 | if (setup_possible_cpus == -1) { |
1220 | else | 1220 | possible = num_processors; |
1221 | #ifdef CONFIG_HOTPLUG_CPU | ||
1222 | if (setup_max_cpus) | ||
1223 | possible += disabled_cpus; | ||
1224 | #else | ||
1225 | if (possible > i) | ||
1226 | possible = i; | ||
1227 | #endif | ||
1228 | } else | ||
1221 | possible = setup_possible_cpus; | 1229 | possible = setup_possible_cpus; |
1222 | 1230 | ||
1223 | total_cpus = max_t(int, possible, num_processors + disabled_cpus); | 1231 | total_cpus = max_t(int, possible, num_processors + disabled_cpus); |
@@ -1230,11 +1238,23 @@ __init void prefill_possible_map(void) | |||
1230 | possible = nr_cpu_ids; | 1238 | possible = nr_cpu_ids; |
1231 | } | 1239 | } |
1232 | 1240 | ||
1241 | #ifdef CONFIG_HOTPLUG_CPU | ||
1242 | if (!setup_max_cpus) | ||
1243 | #endif | ||
1244 | if (possible > i) { | ||
1245 | printk(KERN_WARNING | ||
1246 | "%d Processors exceeds max_cpus limit of %u\n", | ||
1247 | possible, setup_max_cpus); | ||
1248 | possible = i; | ||
1249 | } | ||
1250 | |||
1233 | printk(KERN_INFO "SMP: Allowing %d CPUs, %d hotplug CPUs\n", | 1251 | printk(KERN_INFO "SMP: Allowing %d CPUs, %d hotplug CPUs\n", |
1234 | possible, max_t(int, possible - num_processors, 0)); | 1252 | possible, max_t(int, possible - num_processors, 0)); |
1235 | 1253 | ||
1236 | for (i = 0; i < possible; i++) | 1254 | for (i = 0; i < possible; i++) |
1237 | set_cpu_possible(i, true); | 1255 | set_cpu_possible(i, true); |
1256 | for (; i < NR_CPUS; i++) | ||
1257 | set_cpu_possible(i, false); | ||
1238 | 1258 | ||
1239 | nr_cpu_ids = possible; | 1259 | nr_cpu_ids = possible; |
1240 | } | 1260 | } |
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index 2bdf628066bd..9257510b4836 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c | |||
@@ -1390,7 +1390,6 @@ __init void lguest_init(void) | |||
1390 | #endif | 1390 | #endif |
1391 | #ifdef CONFIG_ACPI | 1391 | #ifdef CONFIG_ACPI |
1392 | acpi_disabled = 1; | 1392 | acpi_disabled = 1; |
1393 | acpi_ht = 0; | ||
1394 | #endif | 1393 | #endif |
1395 | 1394 | ||
1396 | /* | 1395 | /* |
diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c index 10c27bb1e95f..550df481accd 100644 --- a/arch/x86/mm/numa.c +++ b/arch/x86/mm/numa.c | |||
@@ -2,7 +2,6 @@ | |||
2 | #include <linux/topology.h> | 2 | #include <linux/topology.h> |
3 | #include <linux/module.h> | 3 | #include <linux/module.h> |
4 | #include <linux/bootmem.h> | 4 | #include <linux/bootmem.h> |
5 | #include <linux/random.h> | ||
6 | 5 | ||
7 | #ifdef CONFIG_DEBUG_PER_CPU_MAPS | 6 | #ifdef CONFIG_DEBUG_PER_CPU_MAPS |
8 | # define DBG(x...) printk(KERN_DEBUG x) | 7 | # define DBG(x...) printk(KERN_DEBUG x) |
@@ -66,19 +65,3 @@ const struct cpumask *cpumask_of_node(int node) | |||
66 | } | 65 | } |
67 | EXPORT_SYMBOL(cpumask_of_node); | 66 | EXPORT_SYMBOL(cpumask_of_node); |
68 | #endif | 67 | #endif |
69 | |||
70 | /* | ||
71 | * Return the bit number of a random bit set in the nodemask. | ||
72 | * (returns -1 if nodemask is empty) | ||
73 | */ | ||
74 | int __node_random(const nodemask_t *maskp) | ||
75 | { | ||
76 | int w, bit = -1; | ||
77 | |||
78 | w = nodes_weight(*maskp); | ||
79 | if (w) | ||
80 | bit = bitmap_ord_to_pos(maskp->bits, | ||
81 | get_random_int() % w, MAX_NUMNODES); | ||
82 | return bit; | ||
83 | } | ||
84 | EXPORT_SYMBOL(__node_random); | ||
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index bbe5502ee1cb..acc15b23b743 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c | |||
@@ -336,6 +336,7 @@ int free_memtype(u64 start, u64 end) | |||
336 | { | 336 | { |
337 | int err = -EINVAL; | 337 | int err = -EINVAL; |
338 | int is_range_ram; | 338 | int is_range_ram; |
339 | struct memtype *entry; | ||
339 | 340 | ||
340 | if (!pat_enabled) | 341 | if (!pat_enabled) |
341 | return 0; | 342 | return 0; |
@@ -355,17 +356,20 @@ int free_memtype(u64 start, u64 end) | |||
355 | } | 356 | } |
356 | 357 | ||
357 | spin_lock(&memtype_lock); | 358 | spin_lock(&memtype_lock); |
358 | err = rbt_memtype_erase(start, end); | 359 | entry = rbt_memtype_erase(start, end); |
359 | spin_unlock(&memtype_lock); | 360 | spin_unlock(&memtype_lock); |
360 | 361 | ||
361 | if (err) { | 362 | if (!entry) { |
362 | printk(KERN_INFO "%s:%d freeing invalid memtype %Lx-%Lx\n", | 363 | printk(KERN_INFO "%s:%d freeing invalid memtype %Lx-%Lx\n", |
363 | current->comm, current->pid, start, end); | 364 | current->comm, current->pid, start, end); |
365 | return -EINVAL; | ||
364 | } | 366 | } |
365 | 367 | ||
368 | kfree(entry); | ||
369 | |||
366 | dprintk("free_memtype request 0x%Lx-0x%Lx\n", start, end); | 370 | dprintk("free_memtype request 0x%Lx-0x%Lx\n", start, end); |
367 | 371 | ||
368 | return err; | 372 | return 0; |
369 | } | 373 | } |
370 | 374 | ||
371 | 375 | ||
diff --git a/arch/x86/mm/pat_internal.h b/arch/x86/mm/pat_internal.h index 4f39eefa3e61..77e5ba153fac 100644 --- a/arch/x86/mm/pat_internal.h +++ b/arch/x86/mm/pat_internal.h | |||
@@ -28,15 +28,15 @@ static inline char *cattr_name(unsigned long flags) | |||
28 | #ifdef CONFIG_X86_PAT | 28 | #ifdef CONFIG_X86_PAT |
29 | extern int rbt_memtype_check_insert(struct memtype *new, | 29 | extern int rbt_memtype_check_insert(struct memtype *new, |
30 | unsigned long *new_type); | 30 | unsigned long *new_type); |
31 | extern int rbt_memtype_erase(u64 start, u64 end); | 31 | extern struct memtype *rbt_memtype_erase(u64 start, u64 end); |
32 | extern struct memtype *rbt_memtype_lookup(u64 addr); | 32 | extern struct memtype *rbt_memtype_lookup(u64 addr); |
33 | extern int rbt_memtype_copy_nth_element(struct memtype *out, loff_t pos); | 33 | extern int rbt_memtype_copy_nth_element(struct memtype *out, loff_t pos); |
34 | #else | 34 | #else |
35 | static inline int rbt_memtype_check_insert(struct memtype *new, | 35 | static inline int rbt_memtype_check_insert(struct memtype *new, |
36 | unsigned long *new_type) | 36 | unsigned long *new_type) |
37 | { return 0; } | 37 | { return 0; } |
38 | static inline int rbt_memtype_erase(u64 start, u64 end) | 38 | static inline struct memtype *rbt_memtype_erase(u64 start, u64 end) |
39 | { return 0; } | 39 | { return NULL; } |
40 | static inline struct memtype *rbt_memtype_lookup(u64 addr) | 40 | static inline struct memtype *rbt_memtype_lookup(u64 addr) |
41 | { return NULL; } | 41 | { return NULL; } |
42 | static inline int rbt_memtype_copy_nth_element(struct memtype *out, loff_t pos) | 42 | static inline int rbt_memtype_copy_nth_element(struct memtype *out, loff_t pos) |
diff --git a/arch/x86/mm/pat_rbtree.c b/arch/x86/mm/pat_rbtree.c index 07de4cb8cc30..f537087bb740 100644 --- a/arch/x86/mm/pat_rbtree.c +++ b/arch/x86/mm/pat_rbtree.c | |||
@@ -231,16 +231,17 @@ int rbt_memtype_check_insert(struct memtype *new, unsigned long *ret_type) | |||
231 | return err; | 231 | return err; |
232 | } | 232 | } |
233 | 233 | ||
234 | int rbt_memtype_erase(u64 start, u64 end) | 234 | struct memtype *rbt_memtype_erase(u64 start, u64 end) |
235 | { | 235 | { |
236 | struct memtype *data; | 236 | struct memtype *data; |
237 | 237 | ||
238 | data = memtype_rb_exact_match(&memtype_rbroot, start, end); | 238 | data = memtype_rb_exact_match(&memtype_rbroot, start, end); |
239 | if (!data) | 239 | if (!data) |
240 | return -EINVAL; | 240 | goto out; |
241 | 241 | ||
242 | rb_erase(&data->rb, &memtype_rbroot); | 242 | rb_erase(&data->rb, &memtype_rbroot); |
243 | return 0; | 243 | out: |
244 | return data; | ||
244 | } | 245 | } |
245 | 246 | ||
246 | struct memtype *rbt_memtype_lookup(u64 addr) | 247 | struct memtype *rbt_memtype_lookup(u64 addr) |
diff --git a/arch/x86/mm/pgtable_32.c b/arch/x86/mm/pgtable_32.c index 792854003ed3..cac718499256 100644 --- a/arch/x86/mm/pgtable_32.c +++ b/arch/x86/mm/pgtable_32.c | |||
@@ -9,7 +9,6 @@ | |||
9 | #include <linux/pagemap.h> | 9 | #include <linux/pagemap.h> |
10 | #include <linux/spinlock.h> | 10 | #include <linux/spinlock.h> |
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/quicklist.h> | ||
13 | 12 | ||
14 | #include <asm/system.h> | 13 | #include <asm/system.h> |
15 | #include <asm/pgtable.h> | 14 | #include <asm/pgtable.h> |
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 31930fd30ea9..2ec04c424a62 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c | |||
@@ -207,10 +207,9 @@ get_current_resources(struct acpi_device *device, int busnum, | |||
207 | if (!info.res) | 207 | if (!info.res) |
208 | goto res_alloc_fail; | 208 | goto res_alloc_fail; |
209 | 209 | ||
210 | info.name = kmalloc(16, GFP_KERNEL); | 210 | info.name = kasprintf(GFP_KERNEL, "PCI Bus %04x:%02x", domain, busnum); |
211 | if (!info.name) | 211 | if (!info.name) |
212 | goto name_alloc_fail; | 212 | goto name_alloc_fail; |
213 | sprintf(info.name, "PCI Bus %04x:%02x", domain, busnum); | ||
214 | 213 | ||
215 | info.res_num = 0; | 214 | info.res_num = 0; |
216 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, setup_resource, | 215 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, setup_resource, |
@@ -224,8 +223,11 @@ res_alloc_fail: | |||
224 | return; | 223 | return; |
225 | } | 224 | } |
226 | 225 | ||
227 | struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int domain, int busnum) | 226 | struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) |
228 | { | 227 | { |
228 | struct acpi_device *device = root->device; | ||
229 | int domain = root->segment; | ||
230 | int busnum = root->secondary.start; | ||
229 | struct pci_bus *bus; | 231 | struct pci_bus *bus; |
230 | struct pci_sysdata *sd; | 232 | struct pci_sysdata *sd; |
231 | int node; | 233 | int node; |
diff --git a/drivers/Makefile b/drivers/Makefile index f42a03029b7c..91874e048552 100644 --- a/drivers/Makefile +++ b/drivers/Makefile | |||
@@ -10,6 +10,7 @@ obj-$(CONFIG_PCI) += pci/ | |||
10 | obj-$(CONFIG_PARISC) += parisc/ | 10 | obj-$(CONFIG_PARISC) += parisc/ |
11 | obj-$(CONFIG_RAPIDIO) += rapidio/ | 11 | obj-$(CONFIG_RAPIDIO) += rapidio/ |
12 | obj-y += video/ | 12 | obj-y += video/ |
13 | obj-y += idle/ | ||
13 | obj-$(CONFIG_ACPI) += acpi/ | 14 | obj-$(CONFIG_ACPI) += acpi/ |
14 | obj-$(CONFIG_SFI) += sfi/ | 15 | obj-$(CONFIG_SFI) += sfi/ |
15 | # PnP must come after ACPI since it will eventually need to check if acpi | 16 | # PnP must come after ACPI since it will eventually need to check if acpi |
@@ -91,7 +92,6 @@ obj-$(CONFIG_EISA) += eisa/ | |||
91 | obj-y += lguest/ | 92 | obj-y += lguest/ |
92 | obj-$(CONFIG_CPU_FREQ) += cpufreq/ | 93 | obj-$(CONFIG_CPU_FREQ) += cpufreq/ |
93 | obj-$(CONFIG_CPU_IDLE) += cpuidle/ | 94 | obj-$(CONFIG_CPU_IDLE) += cpuidle/ |
94 | obj-y += idle/ | ||
95 | obj-$(CONFIG_MMC) += mmc/ | 95 | obj-$(CONFIG_MMC) += mmc/ |
96 | obj-$(CONFIG_MEMSTICK) += memstick/ | 96 | obj-$(CONFIG_MEMSTICK) += memstick/ |
97 | obj-$(CONFIG_NEW_LEDS) += leds/ | 97 | obj-$(CONFIG_NEW_LEDS) += leds/ |
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 93d2c7971df6..746411518802 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -360,4 +360,13 @@ config ACPI_SBS | |||
360 | To compile this driver as a module, choose M here: | 360 | To compile this driver as a module, choose M here: |
361 | the modules will be called sbs and sbshc. | 361 | the modules will be called sbs and sbshc. |
362 | 362 | ||
363 | config ACPI_HED | ||
364 | tristate "Hardware Error Device" | ||
365 | help | ||
366 | This driver supports the Hardware Error Device (PNP0C33), | ||
367 | which is used to report some hardware errors notified via | ||
368 | SCI, mainly the corrected errors. | ||
369 | |||
370 | source "drivers/acpi/apei/Kconfig" | ||
371 | |||
363 | endif # ACPI | 372 | endif # ACPI |
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index a8d8998dd5c5..6ee33169e1dc 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
@@ -19,7 +19,7 @@ obj-y += acpi.o \ | |||
19 | 19 | ||
20 | # All the builtin files are in the "acpi." module_param namespace. | 20 | # All the builtin files are in the "acpi." module_param namespace. |
21 | acpi-y += osl.o utils.o reboot.o | 21 | acpi-y += osl.o utils.o reboot.o |
22 | acpi-y += hest.o | 22 | acpi-y += atomicio.o |
23 | 23 | ||
24 | # sleep related files | 24 | # sleep related files |
25 | acpi-y += wakeup.o | 25 | acpi-y += wakeup.o |
@@ -59,6 +59,7 @@ obj-$(CONFIG_ACPI_BATTERY) += battery.o | |||
59 | obj-$(CONFIG_ACPI_SBS) += sbshc.o | 59 | obj-$(CONFIG_ACPI_SBS) += sbshc.o |
60 | obj-$(CONFIG_ACPI_SBS) += sbs.o | 60 | obj-$(CONFIG_ACPI_SBS) += sbs.o |
61 | obj-$(CONFIG_ACPI_POWER_METER) += power_meter.o | 61 | obj-$(CONFIG_ACPI_POWER_METER) += power_meter.o |
62 | obj-$(CONFIG_ACPI_HED) += hed.o | ||
62 | 63 | ||
63 | # processor has its own "processor." module_param namespace | 64 | # processor has its own "processor." module_param namespace |
64 | processor-y := processor_driver.o processor_throttling.o | 65 | processor-y := processor_driver.o processor_throttling.o |
@@ -66,3 +67,5 @@ processor-y += processor_idle.o processor_thermal.o | |||
66 | processor-$(CONFIG_CPU_FREQ) += processor_perflib.o | 67 | processor-$(CONFIG_CPU_FREQ) += processor_perflib.o |
67 | 68 | ||
68 | obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o | 69 | obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o |
70 | |||
71 | obj-$(CONFIG_ACPI_APEI) += apei/ | ||
diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index 62122134693b..d269a8f3329c 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c | |||
@@ -43,6 +43,10 @@ static DEFINE_MUTEX(isolated_cpus_lock); | |||
43 | #define CPUID5_ECX_EXTENSIONS_SUPPORTED (0x1) | 43 | #define CPUID5_ECX_EXTENSIONS_SUPPORTED (0x1) |
44 | #define CPUID5_ECX_INTERRUPT_BREAK (0x2) | 44 | #define CPUID5_ECX_INTERRUPT_BREAK (0x2) |
45 | static unsigned long power_saving_mwait_eax; | 45 | static unsigned long power_saving_mwait_eax; |
46 | |||
47 | static unsigned char tsc_detected_unstable; | ||
48 | static unsigned char tsc_marked_unstable; | ||
49 | |||
46 | static void power_saving_mwait_init(void) | 50 | static void power_saving_mwait_init(void) |
47 | { | 51 | { |
48 | unsigned int eax, ebx, ecx, edx; | 52 | unsigned int eax, ebx, ecx, edx; |
@@ -87,8 +91,8 @@ static void power_saving_mwait_init(void) | |||
87 | 91 | ||
88 | /*FALL THROUGH*/ | 92 | /*FALL THROUGH*/ |
89 | default: | 93 | default: |
90 | /* TSC could halt in idle, so notify users */ | 94 | /* TSC could halt in idle */ |
91 | mark_tsc_unstable("TSC halts in idle"); | 95 | tsc_detected_unstable = 1; |
92 | } | 96 | } |
93 | #endif | 97 | #endif |
94 | } | 98 | } |
@@ -168,16 +172,14 @@ static int power_saving_thread(void *data) | |||
168 | 172 | ||
169 | do_sleep = 0; | 173 | do_sleep = 0; |
170 | 174 | ||
171 | current_thread_info()->status &= ~TS_POLLING; | ||
172 | /* | ||
173 | * TS_POLLING-cleared state must be visible before we test | ||
174 | * NEED_RESCHED: | ||
175 | */ | ||
176 | smp_mb(); | ||
177 | |||
178 | expire_time = jiffies + HZ * (100 - idle_pct) / 100; | 175 | expire_time = jiffies + HZ * (100 - idle_pct) / 100; |
179 | 176 | ||
180 | while (!need_resched()) { | 177 | while (!need_resched()) { |
178 | if (tsc_detected_unstable && !tsc_marked_unstable) { | ||
179 | /* TSC could halt in idle, so notify users */ | ||
180 | mark_tsc_unstable("TSC halts in idle"); | ||
181 | tsc_marked_unstable = 1; | ||
182 | } | ||
181 | local_irq_disable(); | 183 | local_irq_disable(); |
182 | cpu = smp_processor_id(); | 184 | cpu = smp_processor_id(); |
183 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, | 185 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, |
@@ -200,8 +202,6 @@ static int power_saving_thread(void *data) | |||
200 | } | 202 | } |
201 | } | 203 | } |
202 | 204 | ||
203 | current_thread_info()->status |= TS_POLLING; | ||
204 | |||
205 | /* | 205 | /* |
206 | * current sched_rt has threshold for rt task running time. | 206 | * current sched_rt has threshold for rt task running time. |
207 | * When a rt task uses 95% CPU time, the rt thread will be | 207 | * When a rt task uses 95% CPU time, the rt thread will be |
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index 7c7bbb4d402c..d5a5efc043bf 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c | |||
@@ -69,7 +69,7 @@ acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
69 | 69 | ||
70 | acpi_status acpi_enable(void) | 70 | acpi_status acpi_enable(void) |
71 | { | 71 | { |
72 | acpi_status status = AE_OK; | 72 | acpi_status status; |
73 | 73 | ||
74 | ACPI_FUNCTION_TRACE(acpi_enable); | 74 | ACPI_FUNCTION_TRACE(acpi_enable); |
75 | 75 | ||
@@ -84,21 +84,30 @@ acpi_status acpi_enable(void) | |||
84 | if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) { | 84 | if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) { |
85 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, | 85 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, |
86 | "System is already in ACPI mode\n")); | 86 | "System is already in ACPI mode\n")); |
87 | } else { | 87 | return_ACPI_STATUS(AE_OK); |
88 | /* Transition to ACPI mode */ | 88 | } |
89 | 89 | ||
90 | status = acpi_hw_set_mode(ACPI_SYS_MODE_ACPI); | 90 | /* Transition to ACPI mode */ |
91 | if (ACPI_FAILURE(status)) { | ||
92 | ACPI_ERROR((AE_INFO, | ||
93 | "Could not transition to ACPI mode")); | ||
94 | return_ACPI_STATUS(status); | ||
95 | } | ||
96 | 91 | ||
97 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, | 92 | status = acpi_hw_set_mode(ACPI_SYS_MODE_ACPI); |
98 | "Transition to ACPI mode successful\n")); | 93 | if (ACPI_FAILURE(status)) { |
94 | ACPI_ERROR((AE_INFO, | ||
95 | "Could not transition to ACPI mode")); | ||
96 | return_ACPI_STATUS(status); | ||
99 | } | 97 | } |
100 | 98 | ||
101 | return_ACPI_STATUS(status); | 99 | /* Sanity check that transition succeeded */ |
100 | |||
101 | if (acpi_hw_get_mode() != ACPI_SYS_MODE_ACPI) { | ||
102 | ACPI_ERROR((AE_INFO, | ||
103 | "Hardware did not enter ACPI mode")); | ||
104 | return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); | ||
105 | } | ||
106 | |||
107 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, | ||
108 | "Transition to ACPI mode successful\n")); | ||
109 | |||
110 | return_ACPI_STATUS(AE_OK); | ||
102 | } | 111 | } |
103 | 112 | ||
104 | ACPI_EXPORT_SYMBOL(acpi_enable) | 113 | ACPI_EXPORT_SYMBOL(acpi_enable) |
diff --git a/drivers/acpi/acpica/hwacpi.c b/drivers/acpi/acpica/hwacpi.c index 679a112a7d26..b44274a0b62c 100644 --- a/drivers/acpi/acpica/hwacpi.c +++ b/drivers/acpi/acpica/hwacpi.c | |||
@@ -63,7 +63,6 @@ acpi_status acpi_hw_set_mode(u32 mode) | |||
63 | { | 63 | { |
64 | 64 | ||
65 | acpi_status status; | 65 | acpi_status status; |
66 | u32 retry; | ||
67 | 66 | ||
68 | ACPI_FUNCTION_TRACE(hw_set_mode); | 67 | ACPI_FUNCTION_TRACE(hw_set_mode); |
69 | 68 | ||
@@ -125,24 +124,7 @@ acpi_status acpi_hw_set_mode(u32 mode) | |||
125 | return_ACPI_STATUS(status); | 124 | return_ACPI_STATUS(status); |
126 | } | 125 | } |
127 | 126 | ||
128 | /* | 127 | return_ACPI_STATUS(AE_OK); |
129 | * Some hardware takes a LONG time to switch modes. Give them 3 sec to | ||
130 | * do so, but allow faster systems to proceed more quickly. | ||
131 | */ | ||
132 | retry = 3000; | ||
133 | while (retry) { | ||
134 | if (acpi_hw_get_mode() == mode) { | ||
135 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
136 | "Mode %X successfully enabled\n", | ||
137 | mode)); | ||
138 | return_ACPI_STATUS(AE_OK); | ||
139 | } | ||
140 | acpi_os_stall(1000); | ||
141 | retry--; | ||
142 | } | ||
143 | |||
144 | ACPI_ERROR((AE_INFO, "Hardware did not change modes")); | ||
145 | return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); | ||
146 | } | 128 | } |
147 | 129 | ||
148 | /******************************************************************************* | 130 | /******************************************************************************* |
diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig new file mode 100644 index 000000000000..f8c668f27b5a --- /dev/null +++ b/drivers/acpi/apei/Kconfig | |||
@@ -0,0 +1,30 @@ | |||
1 | config ACPI_APEI | ||
2 | bool "ACPI Platform Error Interface (APEI)" | ||
3 | depends on X86 | ||
4 | help | ||
5 | APEI allows to report errors (for example from the chipset) | ||
6 | to the operating system. This improves NMI handling | ||
7 | especially. In addition it supports error serialization and | ||
8 | error injection. | ||
9 | |||
10 | config ACPI_APEI_GHES | ||
11 | tristate "APEI Generic Hardware Error Source" | ||
12 | depends on ACPI_APEI && X86 | ||
13 | select ACPI_HED | ||
14 | help | ||
15 | Generic Hardware Error Source provides a way to report | ||
16 | platform hardware errors (such as that from chipset). It | ||
17 | works in so called "Firmware First" mode, that is, hardware | ||
18 | errors are reported to firmware firstly, then reported to | ||
19 | Linux by firmware. This way, some non-standard hardware | ||
20 | error registers or non-standard hardware link can be checked | ||
21 | by firmware to produce more valuable hardware error | ||
22 | information for Linux. | ||
23 | |||
24 | config ACPI_APEI_EINJ | ||
25 | tristate "APEI Error INJection (EINJ)" | ||
26 | depends on ACPI_APEI && DEBUG_FS | ||
27 | help | ||
28 | EINJ provides a hardware error injection mechanism, it is | ||
29 | mainly used for debugging and testing the other parts of | ||
30 | APEI and some other RAS features. | ||
diff --git a/drivers/acpi/apei/Makefile b/drivers/acpi/apei/Makefile new file mode 100644 index 000000000000..b13b03a17789 --- /dev/null +++ b/drivers/acpi/apei/Makefile | |||
@@ -0,0 +1,5 @@ | |||
1 | obj-$(CONFIG_ACPI_APEI) += apei.o | ||
2 | obj-$(CONFIG_ACPI_APEI_GHES) += ghes.o | ||
3 | obj-$(CONFIG_ACPI_APEI_EINJ) += einj.o | ||
4 | |||
5 | apei-y := apei-base.o hest.o cper.o erst.o | ||
diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c new file mode 100644 index 000000000000..db3946e9c66b --- /dev/null +++ b/drivers/acpi/apei/apei-base.c | |||
@@ -0,0 +1,593 @@ | |||
1 | /* | ||
2 | * apei-base.c - ACPI Platform Error Interface (APEI) supporting | ||
3 | * infrastructure | ||
4 | * | ||
5 | * APEI allows to report errors (for example from the chipset) to the | ||
6 | * the operating system. This improves NMI handling especially. In | ||
7 | * addition it supports error serialization and error injection. | ||
8 | * | ||
9 | * For more information about APEI, please refer to ACPI Specification | ||
10 | * version 4.0, chapter 17. | ||
11 | * | ||
12 | * This file has Common functions used by more than one APEI table, | ||
13 | * including framework of interpreter for ERST and EINJ; resource | ||
14 | * management for APEI registers. | ||
15 | * | ||
16 | * Copyright (C) 2009, Intel Corp. | ||
17 | * Author: Huang Ying <ying.huang@intel.com> | ||
18 | * | ||
19 | * This program is free software; you can redistribute it and/or | ||
20 | * modify it under the terms of the GNU General Public License version | ||
21 | * 2 as published by the Free Software Foundation. | ||
22 | * | ||
23 | * This program is distributed in the hope that it will be useful, | ||
24 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
25 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
26 | * GNU General Public License for more details. | ||
27 | * | ||
28 | * You should have received a copy of the GNU General Public License | ||
29 | * along with this program; if not, write to the Free Software | ||
30 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
31 | */ | ||
32 | |||
33 | #include <linux/kernel.h> | ||
34 | #include <linux/module.h> | ||
35 | #include <linux/init.h> | ||
36 | #include <linux/acpi.h> | ||
37 | #include <linux/io.h> | ||
38 | #include <linux/kref.h> | ||
39 | #include <linux/rculist.h> | ||
40 | #include <linux/interrupt.h> | ||
41 | #include <linux/debugfs.h> | ||
42 | #include <acpi/atomicio.h> | ||
43 | |||
44 | #include "apei-internal.h" | ||
45 | |||
46 | #define APEI_PFX "APEI: " | ||
47 | |||
48 | /* | ||
49 | * APEI ERST (Error Record Serialization Table) and EINJ (Error | ||
50 | * INJection) interpreter framework. | ||
51 | */ | ||
52 | |||
53 | #define APEI_EXEC_PRESERVE_REGISTER 0x1 | ||
54 | |||
55 | void apei_exec_ctx_init(struct apei_exec_context *ctx, | ||
56 | struct apei_exec_ins_type *ins_table, | ||
57 | u32 instructions, | ||
58 | struct acpi_whea_header *action_table, | ||
59 | u32 entries) | ||
60 | { | ||
61 | ctx->ins_table = ins_table; | ||
62 | ctx->instructions = instructions; | ||
63 | ctx->action_table = action_table; | ||
64 | ctx->entries = entries; | ||
65 | } | ||
66 | EXPORT_SYMBOL_GPL(apei_exec_ctx_init); | ||
67 | |||
68 | int __apei_exec_read_register(struct acpi_whea_header *entry, u64 *val) | ||
69 | { | ||
70 | int rc; | ||
71 | |||
72 | rc = acpi_atomic_read(val, &entry->register_region); | ||
73 | if (rc) | ||
74 | return rc; | ||
75 | *val >>= entry->register_region.bit_offset; | ||
76 | *val &= entry->mask; | ||
77 | |||
78 | return 0; | ||
79 | } | ||
80 | |||
81 | int apei_exec_read_register(struct apei_exec_context *ctx, | ||
82 | struct acpi_whea_header *entry) | ||
83 | { | ||
84 | int rc; | ||
85 | u64 val = 0; | ||
86 | |||
87 | rc = __apei_exec_read_register(entry, &val); | ||
88 | if (rc) | ||
89 | return rc; | ||
90 | ctx->value = val; | ||
91 | |||
92 | return 0; | ||
93 | } | ||
94 | EXPORT_SYMBOL_GPL(apei_exec_read_register); | ||
95 | |||
96 | int apei_exec_read_register_value(struct apei_exec_context *ctx, | ||
97 | struct acpi_whea_header *entry) | ||
98 | { | ||
99 | int rc; | ||
100 | |||
101 | rc = apei_exec_read_register(ctx, entry); | ||
102 | if (rc) | ||
103 | return rc; | ||
104 | ctx->value = (ctx->value == entry->value); | ||
105 | |||
106 | return 0; | ||
107 | } | ||
108 | EXPORT_SYMBOL_GPL(apei_exec_read_register_value); | ||
109 | |||
110 | int __apei_exec_write_register(struct acpi_whea_header *entry, u64 val) | ||
111 | { | ||
112 | int rc; | ||
113 | |||
114 | val &= entry->mask; | ||
115 | val <<= entry->register_region.bit_offset; | ||
116 | if (entry->flags & APEI_EXEC_PRESERVE_REGISTER) { | ||
117 | u64 valr = 0; | ||
118 | rc = acpi_atomic_read(&valr, &entry->register_region); | ||
119 | if (rc) | ||
120 | return rc; | ||
121 | valr &= ~(entry->mask << entry->register_region.bit_offset); | ||
122 | val |= valr; | ||
123 | } | ||
124 | rc = acpi_atomic_write(val, &entry->register_region); | ||
125 | |||
126 | return rc; | ||
127 | } | ||
128 | |||
129 | int apei_exec_write_register(struct apei_exec_context *ctx, | ||
130 | struct acpi_whea_header *entry) | ||
131 | { | ||
132 | return __apei_exec_write_register(entry, ctx->value); | ||
133 | } | ||
134 | EXPORT_SYMBOL_GPL(apei_exec_write_register); | ||
135 | |||
136 | int apei_exec_write_register_value(struct apei_exec_context *ctx, | ||
137 | struct acpi_whea_header *entry) | ||
138 | { | ||
139 | int rc; | ||
140 | |||
141 | ctx->value = entry->value; | ||
142 | rc = apei_exec_write_register(ctx, entry); | ||
143 | |||
144 | return rc; | ||
145 | } | ||
146 | EXPORT_SYMBOL_GPL(apei_exec_write_register_value); | ||
147 | |||
148 | int apei_exec_noop(struct apei_exec_context *ctx, | ||
149 | struct acpi_whea_header *entry) | ||
150 | { | ||
151 | return 0; | ||
152 | } | ||
153 | EXPORT_SYMBOL_GPL(apei_exec_noop); | ||
154 | |||
155 | /* | ||
156 | * Interpret the specified action. Go through whole action table, | ||
157 | * execute all instructions belong to the action. | ||
158 | */ | ||
159 | int apei_exec_run(struct apei_exec_context *ctx, u8 action) | ||
160 | { | ||
161 | int rc; | ||
162 | u32 i, ip; | ||
163 | struct acpi_whea_header *entry; | ||
164 | apei_exec_ins_func_t run; | ||
165 | |||
166 | ctx->ip = 0; | ||
167 | |||
168 | /* | ||
169 | * "ip" is the instruction pointer of current instruction, | ||
170 | * "ctx->ip" specifies the next instruction to executed, | ||
171 | * instruction "run" function may change the "ctx->ip" to | ||
172 | * implement "goto" semantics. | ||
173 | */ | ||
174 | rewind: | ||
175 | ip = 0; | ||
176 | for (i = 0; i < ctx->entries; i++) { | ||
177 | entry = &ctx->action_table[i]; | ||
178 | if (entry->action != action) | ||
179 | continue; | ||
180 | if (ip == ctx->ip) { | ||
181 | if (entry->instruction >= ctx->instructions || | ||
182 | !ctx->ins_table[entry->instruction].run) { | ||
183 | pr_warning(FW_WARN APEI_PFX | ||
184 | "Invalid action table, unknown instruction type: %d\n", | ||
185 | entry->instruction); | ||
186 | return -EINVAL; | ||
187 | } | ||
188 | run = ctx->ins_table[entry->instruction].run; | ||
189 | rc = run(ctx, entry); | ||
190 | if (rc < 0) | ||
191 | return rc; | ||
192 | else if (rc != APEI_EXEC_SET_IP) | ||
193 | ctx->ip++; | ||
194 | } | ||
195 | ip++; | ||
196 | if (ctx->ip < ip) | ||
197 | goto rewind; | ||
198 | } | ||
199 | |||
200 | return 0; | ||
201 | } | ||
202 | EXPORT_SYMBOL_GPL(apei_exec_run); | ||
203 | |||
204 | typedef int (*apei_exec_entry_func_t)(struct apei_exec_context *ctx, | ||
205 | struct acpi_whea_header *entry, | ||
206 | void *data); | ||
207 | |||
208 | static int apei_exec_for_each_entry(struct apei_exec_context *ctx, | ||
209 | apei_exec_entry_func_t func, | ||
210 | void *data, | ||
211 | int *end) | ||
212 | { | ||
213 | u8 ins; | ||
214 | int i, rc; | ||
215 | struct acpi_whea_header *entry; | ||
216 | struct apei_exec_ins_type *ins_table = ctx->ins_table; | ||
217 | |||
218 | for (i = 0; i < ctx->entries; i++) { | ||
219 | entry = ctx->action_table + i; | ||
220 | ins = entry->instruction; | ||
221 | if (end) | ||
222 | *end = i; | ||
223 | if (ins >= ctx->instructions || !ins_table[ins].run) { | ||
224 | pr_warning(FW_WARN APEI_PFX | ||
225 | "Invalid action table, unknown instruction type: %d\n", | ||
226 | ins); | ||
227 | return -EINVAL; | ||
228 | } | ||
229 | rc = func(ctx, entry, data); | ||
230 | if (rc) | ||
231 | return rc; | ||
232 | } | ||
233 | |||
234 | return 0; | ||
235 | } | ||
236 | |||
237 | static int pre_map_gar_callback(struct apei_exec_context *ctx, | ||
238 | struct acpi_whea_header *entry, | ||
239 | void *data) | ||
240 | { | ||
241 | u8 ins = entry->instruction; | ||
242 | |||
243 | if (ctx->ins_table[ins].flags & APEI_EXEC_INS_ACCESS_REGISTER) | ||
244 | return acpi_pre_map_gar(&entry->register_region); | ||
245 | |||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | /* | ||
250 | * Pre-map all GARs in action table to make it possible to access them | ||
251 | * in NMI handler. | ||
252 | */ | ||
253 | int apei_exec_pre_map_gars(struct apei_exec_context *ctx) | ||
254 | { | ||
255 | int rc, end; | ||
256 | |||
257 | rc = apei_exec_for_each_entry(ctx, pre_map_gar_callback, | ||
258 | NULL, &end); | ||
259 | if (rc) { | ||
260 | struct apei_exec_context ctx_unmap; | ||
261 | memcpy(&ctx_unmap, ctx, sizeof(*ctx)); | ||
262 | ctx_unmap.entries = end; | ||
263 | apei_exec_post_unmap_gars(&ctx_unmap); | ||
264 | } | ||
265 | |||
266 | return rc; | ||
267 | } | ||
268 | EXPORT_SYMBOL_GPL(apei_exec_pre_map_gars); | ||
269 | |||
270 | static int post_unmap_gar_callback(struct apei_exec_context *ctx, | ||
271 | struct acpi_whea_header *entry, | ||
272 | void *data) | ||
273 | { | ||
274 | u8 ins = entry->instruction; | ||
275 | |||
276 | if (ctx->ins_table[ins].flags & APEI_EXEC_INS_ACCESS_REGISTER) | ||
277 | acpi_post_unmap_gar(&entry->register_region); | ||
278 | |||
279 | return 0; | ||
280 | } | ||
281 | |||
282 | /* Post-unmap all GAR in action table. */ | ||
283 | int apei_exec_post_unmap_gars(struct apei_exec_context *ctx) | ||
284 | { | ||
285 | return apei_exec_for_each_entry(ctx, post_unmap_gar_callback, | ||
286 | NULL, NULL); | ||
287 | } | ||
288 | EXPORT_SYMBOL_GPL(apei_exec_post_unmap_gars); | ||
289 | |||
290 | /* | ||
291 | * Resource management for GARs in APEI | ||
292 | */ | ||
293 | struct apei_res { | ||
294 | struct list_head list; | ||
295 | unsigned long start; | ||
296 | unsigned long end; | ||
297 | }; | ||
298 | |||
299 | /* Collect all resources requested, to avoid conflict */ | ||
300 | struct apei_resources apei_resources_all = { | ||
301 | .iomem = LIST_HEAD_INIT(apei_resources_all.iomem), | ||
302 | .ioport = LIST_HEAD_INIT(apei_resources_all.ioport), | ||
303 | }; | ||
304 | |||
305 | static int apei_res_add(struct list_head *res_list, | ||
306 | unsigned long start, unsigned long size) | ||
307 | { | ||
308 | struct apei_res *res, *resn, *res_ins = NULL; | ||
309 | unsigned long end = start + size; | ||
310 | |||
311 | if (end <= start) | ||
312 | return 0; | ||
313 | repeat: | ||
314 | list_for_each_entry_safe(res, resn, res_list, list) { | ||
315 | if (res->start > end || res->end < start) | ||
316 | continue; | ||
317 | else if (end <= res->end && start >= res->start) { | ||
318 | kfree(res_ins); | ||
319 | return 0; | ||
320 | } | ||
321 | list_del(&res->list); | ||
322 | res->start = start = min(res->start, start); | ||
323 | res->end = end = max(res->end, end); | ||
324 | kfree(res_ins); | ||
325 | res_ins = res; | ||
326 | goto repeat; | ||
327 | } | ||
328 | |||
329 | if (res_ins) | ||
330 | list_add(&res_ins->list, res_list); | ||
331 | else { | ||
332 | res_ins = kmalloc(sizeof(*res), GFP_KERNEL); | ||
333 | if (!res_ins) | ||
334 | return -ENOMEM; | ||
335 | res_ins->start = start; | ||
336 | res_ins->end = end; | ||
337 | list_add(&res_ins->list, res_list); | ||
338 | } | ||
339 | |||
340 | return 0; | ||
341 | } | ||
342 | |||
343 | static int apei_res_sub(struct list_head *res_list1, | ||
344 | struct list_head *res_list2) | ||
345 | { | ||
346 | struct apei_res *res1, *resn1, *res2, *res; | ||
347 | res1 = list_entry(res_list1->next, struct apei_res, list); | ||
348 | resn1 = list_entry(res1->list.next, struct apei_res, list); | ||
349 | while (&res1->list != res_list1) { | ||
350 | list_for_each_entry(res2, res_list2, list) { | ||
351 | if (res1->start >= res2->end || | ||
352 | res1->end <= res2->start) | ||
353 | continue; | ||
354 | else if (res1->end <= res2->end && | ||
355 | res1->start >= res2->start) { | ||
356 | list_del(&res1->list); | ||
357 | kfree(res1); | ||
358 | break; | ||
359 | } else if (res1->end > res2->end && | ||
360 | res1->start < res2->start) { | ||
361 | res = kmalloc(sizeof(*res), GFP_KERNEL); | ||
362 | if (!res) | ||
363 | return -ENOMEM; | ||
364 | res->start = res2->end; | ||
365 | res->end = res1->end; | ||
366 | res1->end = res2->start; | ||
367 | list_add(&res->list, &res1->list); | ||
368 | resn1 = res; | ||
369 | } else { | ||
370 | if (res1->start < res2->start) | ||
371 | res1->end = res2->start; | ||
372 | else | ||
373 | res1->start = res2->end; | ||
374 | } | ||
375 | } | ||
376 | res1 = resn1; | ||
377 | resn1 = list_entry(resn1->list.next, struct apei_res, list); | ||
378 | } | ||
379 | |||
380 | return 0; | ||
381 | } | ||
382 | |||
383 | static void apei_res_clean(struct list_head *res_list) | ||
384 | { | ||
385 | struct apei_res *res, *resn; | ||
386 | |||
387 | list_for_each_entry_safe(res, resn, res_list, list) { | ||
388 | list_del(&res->list); | ||
389 | kfree(res); | ||
390 | } | ||
391 | } | ||
392 | |||
393 | void apei_resources_fini(struct apei_resources *resources) | ||
394 | { | ||
395 | apei_res_clean(&resources->iomem); | ||
396 | apei_res_clean(&resources->ioport); | ||
397 | } | ||
398 | EXPORT_SYMBOL_GPL(apei_resources_fini); | ||
399 | |||
400 | static int apei_resources_merge(struct apei_resources *resources1, | ||
401 | struct apei_resources *resources2) | ||
402 | { | ||
403 | int rc; | ||
404 | struct apei_res *res; | ||
405 | |||
406 | list_for_each_entry(res, &resources2->iomem, list) { | ||
407 | rc = apei_res_add(&resources1->iomem, res->start, | ||
408 | res->end - res->start); | ||
409 | if (rc) | ||
410 | return rc; | ||
411 | } | ||
412 | list_for_each_entry(res, &resources2->ioport, list) { | ||
413 | rc = apei_res_add(&resources1->ioport, res->start, | ||
414 | res->end - res->start); | ||
415 | if (rc) | ||
416 | return rc; | ||
417 | } | ||
418 | |||
419 | return 0; | ||
420 | } | ||
421 | |||
422 | /* | ||
423 | * EINJ has two groups of GARs (EINJ table entry and trigger table | ||
424 | * entry), so common resources are subtracted from the trigger table | ||
425 | * resources before the second requesting. | ||
426 | */ | ||
427 | int apei_resources_sub(struct apei_resources *resources1, | ||
428 | struct apei_resources *resources2) | ||
429 | { | ||
430 | int rc; | ||
431 | |||
432 | rc = apei_res_sub(&resources1->iomem, &resources2->iomem); | ||
433 | if (rc) | ||
434 | return rc; | ||
435 | return apei_res_sub(&resources1->ioport, &resources2->ioport); | ||
436 | } | ||
437 | EXPORT_SYMBOL_GPL(apei_resources_sub); | ||
438 | |||
439 | /* | ||
440 | * IO memory/port rersource management mechanism is used to check | ||
441 | * whether memory/port area used by GARs conflicts with normal memory | ||
442 | * or IO memory/port of devices. | ||
443 | */ | ||
444 | int apei_resources_request(struct apei_resources *resources, | ||
445 | const char *desc) | ||
446 | { | ||
447 | struct apei_res *res, *res_bak; | ||
448 | struct resource *r; | ||
449 | |||
450 | apei_resources_sub(resources, &apei_resources_all); | ||
451 | |||
452 | list_for_each_entry(res, &resources->iomem, list) { | ||
453 | r = request_mem_region(res->start, res->end - res->start, | ||
454 | desc); | ||
455 | if (!r) { | ||
456 | pr_err(APEI_PFX | ||
457 | "Can not request iomem region <%016llx-%016llx> for GARs.\n", | ||
458 | (unsigned long long)res->start, | ||
459 | (unsigned long long)res->end); | ||
460 | res_bak = res; | ||
461 | goto err_unmap_iomem; | ||
462 | } | ||
463 | } | ||
464 | |||
465 | list_for_each_entry(res, &resources->ioport, list) { | ||
466 | r = request_region(res->start, res->end - res->start, desc); | ||
467 | if (!r) { | ||
468 | pr_err(APEI_PFX | ||
469 | "Can not request ioport region <%016llx-%016llx> for GARs.\n", | ||
470 | (unsigned long long)res->start, | ||
471 | (unsigned long long)res->end); | ||
472 | res_bak = res; | ||
473 | goto err_unmap_ioport; | ||
474 | } | ||
475 | } | ||
476 | |||
477 | apei_resources_merge(&apei_resources_all, resources); | ||
478 | |||
479 | return 0; | ||
480 | err_unmap_ioport: | ||
481 | list_for_each_entry(res, &resources->ioport, list) { | ||
482 | if (res == res_bak) | ||
483 | break; | ||
484 | release_mem_region(res->start, res->end - res->start); | ||
485 | } | ||
486 | res_bak = NULL; | ||
487 | err_unmap_iomem: | ||
488 | list_for_each_entry(res, &resources->iomem, list) { | ||
489 | if (res == res_bak) | ||
490 | break; | ||
491 | release_region(res->start, res->end - res->start); | ||
492 | } | ||
493 | return -EINVAL; | ||
494 | } | ||
495 | EXPORT_SYMBOL_GPL(apei_resources_request); | ||
496 | |||
497 | void apei_resources_release(struct apei_resources *resources) | ||
498 | { | ||
499 | struct apei_res *res; | ||
500 | |||
501 | list_for_each_entry(res, &resources->iomem, list) | ||
502 | release_mem_region(res->start, res->end - res->start); | ||
503 | list_for_each_entry(res, &resources->ioport, list) | ||
504 | release_region(res->start, res->end - res->start); | ||
505 | |||
506 | apei_resources_sub(&apei_resources_all, resources); | ||
507 | } | ||
508 | EXPORT_SYMBOL_GPL(apei_resources_release); | ||
509 | |||
510 | static int apei_check_gar(struct acpi_generic_address *reg, u64 *paddr) | ||
511 | { | ||
512 | u32 width, space_id; | ||
513 | |||
514 | width = reg->bit_width; | ||
515 | space_id = reg->space_id; | ||
516 | /* Handle possible alignment issues */ | ||
517 | memcpy(paddr, ®->address, sizeof(*paddr)); | ||
518 | if (!*paddr) { | ||
519 | pr_warning(FW_BUG APEI_PFX | ||
520 | "Invalid physical address in GAR [0x%llx/%u/%u]\n", | ||
521 | *paddr, width, space_id); | ||
522 | return -EINVAL; | ||
523 | } | ||
524 | |||
525 | if ((width != 8) && (width != 16) && (width != 32) && (width != 64)) { | ||
526 | pr_warning(FW_BUG APEI_PFX | ||
527 | "Invalid bit width in GAR [0x%llx/%u/%u]\n", | ||
528 | *paddr, width, space_id); | ||
529 | return -EINVAL; | ||
530 | } | ||
531 | |||
532 | if (space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY && | ||
533 | space_id != ACPI_ADR_SPACE_SYSTEM_IO) { | ||
534 | pr_warning(FW_BUG APEI_PFX | ||
535 | "Invalid address space type in GAR [0x%llx/%u/%u]\n", | ||
536 | *paddr, width, space_id); | ||
537 | return -EINVAL; | ||
538 | } | ||
539 | |||
540 | return 0; | ||
541 | } | ||
542 | |||
543 | static int collect_res_callback(struct apei_exec_context *ctx, | ||
544 | struct acpi_whea_header *entry, | ||
545 | void *data) | ||
546 | { | ||
547 | struct apei_resources *resources = data; | ||
548 | struct acpi_generic_address *reg = &entry->register_region; | ||
549 | u8 ins = entry->instruction; | ||
550 | u64 paddr; | ||
551 | int rc; | ||
552 | |||
553 | if (!(ctx->ins_table[ins].flags & APEI_EXEC_INS_ACCESS_REGISTER)) | ||
554 | return 0; | ||
555 | |||
556 | rc = apei_check_gar(reg, &paddr); | ||
557 | if (rc) | ||
558 | return rc; | ||
559 | |||
560 | switch (reg->space_id) { | ||
561 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: | ||
562 | return apei_res_add(&resources->iomem, paddr, | ||
563 | reg->bit_width / 8); | ||
564 | case ACPI_ADR_SPACE_SYSTEM_IO: | ||
565 | return apei_res_add(&resources->ioport, paddr, | ||
566 | reg->bit_width / 8); | ||
567 | default: | ||
568 | return -EINVAL; | ||
569 | } | ||
570 | } | ||
571 | |||
572 | /* | ||
573 | * Same register may be used by multiple instructions in GARs, so | ||
574 | * resources are collected before requesting. | ||
575 | */ | ||
576 | int apei_exec_collect_resources(struct apei_exec_context *ctx, | ||
577 | struct apei_resources *resources) | ||
578 | { | ||
579 | return apei_exec_for_each_entry(ctx, collect_res_callback, | ||
580 | resources, NULL); | ||
581 | } | ||
582 | EXPORT_SYMBOL_GPL(apei_exec_collect_resources); | ||
583 | |||
584 | struct dentry *apei_get_debugfs_dir(void) | ||
585 | { | ||
586 | static struct dentry *dapei; | ||
587 | |||
588 | if (!dapei) | ||
589 | dapei = debugfs_create_dir("apei", NULL); | ||
590 | |||
591 | return dapei; | ||
592 | } | ||
593 | EXPORT_SYMBOL_GPL(apei_get_debugfs_dir); | ||
diff --git a/drivers/acpi/apei/apei-internal.h b/drivers/acpi/apei/apei-internal.h new file mode 100644 index 000000000000..18df1e940276 --- /dev/null +++ b/drivers/acpi/apei/apei-internal.h | |||
@@ -0,0 +1,114 @@ | |||
1 | /* | ||
2 | * apei-internal.h - ACPI Platform Error Interface internal | ||
3 | * definations. | ||
4 | */ | ||
5 | |||
6 | #ifndef APEI_INTERNAL_H | ||
7 | #define APEI_INTERNAL_H | ||
8 | |||
9 | #include <linux/cper.h> | ||
10 | |||
11 | struct apei_exec_context; | ||
12 | |||
13 | typedef int (*apei_exec_ins_func_t)(struct apei_exec_context *ctx, | ||
14 | struct acpi_whea_header *entry); | ||
15 | |||
16 | #define APEI_EXEC_INS_ACCESS_REGISTER 0x0001 | ||
17 | |||
18 | struct apei_exec_ins_type { | ||
19 | u32 flags; | ||
20 | apei_exec_ins_func_t run; | ||
21 | }; | ||
22 | |||
23 | struct apei_exec_context { | ||
24 | u32 ip; | ||
25 | u64 value; | ||
26 | u64 var1; | ||
27 | u64 var2; | ||
28 | u64 src_base; | ||
29 | u64 dst_base; | ||
30 | struct apei_exec_ins_type *ins_table; | ||
31 | u32 instructions; | ||
32 | struct acpi_whea_header *action_table; | ||
33 | u32 entries; | ||
34 | }; | ||
35 | |||
36 | void apei_exec_ctx_init(struct apei_exec_context *ctx, | ||
37 | struct apei_exec_ins_type *ins_table, | ||
38 | u32 instructions, | ||
39 | struct acpi_whea_header *action_table, | ||
40 | u32 entries); | ||
41 | |||
42 | static inline void apei_exec_ctx_set_input(struct apei_exec_context *ctx, | ||
43 | u64 input) | ||
44 | { | ||
45 | ctx->value = input; | ||
46 | } | ||
47 | |||
48 | static inline u64 apei_exec_ctx_get_output(struct apei_exec_context *ctx) | ||
49 | { | ||
50 | return ctx->value; | ||
51 | } | ||
52 | |||
53 | int apei_exec_run(struct apei_exec_context *ctx, u8 action); | ||
54 | |||
55 | /* Common instruction implementation */ | ||
56 | |||
57 | /* IP has been set in instruction function */ | ||
58 | #define APEI_EXEC_SET_IP 1 | ||
59 | |||
60 | int __apei_exec_read_register(struct acpi_whea_header *entry, u64 *val); | ||
61 | int __apei_exec_write_register(struct acpi_whea_header *entry, u64 val); | ||
62 | int apei_exec_read_register(struct apei_exec_context *ctx, | ||
63 | struct acpi_whea_header *entry); | ||
64 | int apei_exec_read_register_value(struct apei_exec_context *ctx, | ||
65 | struct acpi_whea_header *entry); | ||
66 | int apei_exec_write_register(struct apei_exec_context *ctx, | ||
67 | struct acpi_whea_header *entry); | ||
68 | int apei_exec_write_register_value(struct apei_exec_context *ctx, | ||
69 | struct acpi_whea_header *entry); | ||
70 | int apei_exec_noop(struct apei_exec_context *ctx, | ||
71 | struct acpi_whea_header *entry); | ||
72 | int apei_exec_pre_map_gars(struct apei_exec_context *ctx); | ||
73 | int apei_exec_post_unmap_gars(struct apei_exec_context *ctx); | ||
74 | |||
75 | struct apei_resources { | ||
76 | struct list_head iomem; | ||
77 | struct list_head ioport; | ||
78 | }; | ||
79 | |||
80 | static inline void apei_resources_init(struct apei_resources *resources) | ||
81 | { | ||
82 | INIT_LIST_HEAD(&resources->iomem); | ||
83 | INIT_LIST_HEAD(&resources->ioport); | ||
84 | } | ||
85 | |||
86 | void apei_resources_fini(struct apei_resources *resources); | ||
87 | int apei_resources_sub(struct apei_resources *resources1, | ||
88 | struct apei_resources *resources2); | ||
89 | int apei_resources_request(struct apei_resources *resources, | ||
90 | const char *desc); | ||
91 | void apei_resources_release(struct apei_resources *resources); | ||
92 | int apei_exec_collect_resources(struct apei_exec_context *ctx, | ||
93 | struct apei_resources *resources); | ||
94 | |||
95 | struct dentry; | ||
96 | struct dentry *apei_get_debugfs_dir(void); | ||
97 | |||
98 | #define apei_estatus_for_each_section(estatus, section) \ | ||
99 | for (section = (struct acpi_hest_generic_data *)(estatus + 1); \ | ||
100 | (void *)section - (void *)estatus < estatus->data_length; \ | ||
101 | section = (void *)(section+1) + section->error_data_length) | ||
102 | |||
103 | static inline u32 apei_estatus_len(struct acpi_hest_generic_status *estatus) | ||
104 | { | ||
105 | if (estatus->raw_data_length) | ||
106 | return estatus->raw_data_offset + \ | ||
107 | estatus->raw_data_length; | ||
108 | else | ||
109 | return sizeof(*estatus) + estatus->data_length; | ||
110 | } | ||
111 | |||
112 | int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus); | ||
113 | int apei_estatus_check(const struct acpi_hest_generic_status *estatus); | ||
114 | #endif | ||
diff --git a/drivers/acpi/apei/cper.c b/drivers/acpi/apei/cper.c new file mode 100644 index 000000000000..f4cf2fc4c8c1 --- /dev/null +++ b/drivers/acpi/apei/cper.c | |||
@@ -0,0 +1,84 @@ | |||
1 | /* | ||
2 | * UEFI Common Platform Error Record (CPER) support | ||
3 | * | ||
4 | * Copyright (C) 2010, Intel Corp. | ||
5 | * Author: Huang Ying <ying.huang@intel.com> | ||
6 | * | ||
7 | * CPER is the format used to describe platform hardware error by | ||
8 | * various APEI tables, such as ERST, BERT and HEST etc. | ||
9 | * | ||
10 | * For more information about CPER, please refer to Appendix N of UEFI | ||
11 | * Specification version 2.3. | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License version | ||
15 | * 2 as published by the Free Software Foundation. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; if not, write to the Free Software | ||
24 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
25 | */ | ||
26 | |||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <linux/time.h> | ||
30 | #include <linux/cper.h> | ||
31 | #include <linux/acpi.h> | ||
32 | |||
33 | /* | ||
34 | * CPER record ID need to be unique even after reboot, because record | ||
35 | * ID is used as index for ERST storage, while CPER records from | ||
36 | * multiple boot may co-exist in ERST. | ||
37 | */ | ||
38 | u64 cper_next_record_id(void) | ||
39 | { | ||
40 | static atomic64_t seq; | ||
41 | |||
42 | if (!atomic64_read(&seq)) | ||
43 | atomic64_set(&seq, ((u64)get_seconds()) << 32); | ||
44 | |||
45 | return atomic64_inc_return(&seq); | ||
46 | } | ||
47 | EXPORT_SYMBOL_GPL(cper_next_record_id); | ||
48 | |||
49 | int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus) | ||
50 | { | ||
51 | if (estatus->data_length && | ||
52 | estatus->data_length < sizeof(struct acpi_hest_generic_data)) | ||
53 | return -EINVAL; | ||
54 | if (estatus->raw_data_length && | ||
55 | estatus->raw_data_offset < sizeof(*estatus) + estatus->data_length) | ||
56 | return -EINVAL; | ||
57 | |||
58 | return 0; | ||
59 | } | ||
60 | EXPORT_SYMBOL_GPL(apei_estatus_check_header); | ||
61 | |||
62 | int apei_estatus_check(const struct acpi_hest_generic_status *estatus) | ||
63 | { | ||
64 | struct acpi_hest_generic_data *gdata; | ||
65 | unsigned int data_len, gedata_len; | ||
66 | int rc; | ||
67 | |||
68 | rc = apei_estatus_check_header(estatus); | ||
69 | if (rc) | ||
70 | return rc; | ||
71 | data_len = estatus->data_length; | ||
72 | gdata = (struct acpi_hest_generic_data *)(estatus + 1); | ||
73 | while (data_len > sizeof(*gdata)) { | ||
74 | gedata_len = gdata->error_data_length; | ||
75 | if (gedata_len > data_len - sizeof(*gdata)) | ||
76 | return -EINVAL; | ||
77 | data_len -= gedata_len + sizeof(*gdata); | ||
78 | } | ||
79 | if (data_len) | ||
80 | return -EINVAL; | ||
81 | |||
82 | return 0; | ||
83 | } | ||
84 | EXPORT_SYMBOL_GPL(apei_estatus_check); | ||
diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c new file mode 100644 index 000000000000..465c885938ee --- /dev/null +++ b/drivers/acpi/apei/einj.c | |||
@@ -0,0 +1,548 @@ | |||
1 | /* | ||
2 | * APEI Error INJection support | ||
3 | * | ||
4 | * EINJ provides a hardware error injection mechanism, this is useful | ||
5 | * for debugging and testing of other APEI and RAS features. | ||
6 | * | ||
7 | * For more information about EINJ, please refer to ACPI Specification | ||
8 | * version 4.0, section 17.5. | ||
9 | * | ||
10 | * Copyright 2009-2010 Intel Corp. | ||
11 | * Author: Huang Ying <ying.huang@intel.com> | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License version | ||
15 | * 2 as published by the Free Software Foundation. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; if not, write to the Free Software | ||
24 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
25 | */ | ||
26 | |||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <linux/init.h> | ||
30 | #include <linux/io.h> | ||
31 | #include <linux/debugfs.h> | ||
32 | #include <linux/seq_file.h> | ||
33 | #include <linux/nmi.h> | ||
34 | #include <linux/delay.h> | ||
35 | #include <acpi/acpi.h> | ||
36 | |||
37 | #include "apei-internal.h" | ||
38 | |||
39 | #define EINJ_PFX "EINJ: " | ||
40 | |||
41 | #define SPIN_UNIT 100 /* 100ns */ | ||
42 | /* Firmware should respond within 1 miliseconds */ | ||
43 | #define FIRMWARE_TIMEOUT (1 * NSEC_PER_MSEC) | ||
44 | |||
45 | /* | ||
46 | * Some BIOSes allow parameters to the SET_ERROR_TYPE entries in the | ||
47 | * EINJ table through an unpublished extension. Use with caution as | ||
48 | * most will ignore the parameter and make their own choice of address | ||
49 | * for error injection. | ||
50 | */ | ||
51 | struct einj_parameter { | ||
52 | u64 type; | ||
53 | u64 reserved1; | ||
54 | u64 reserved2; | ||
55 | u64 param1; | ||
56 | u64 param2; | ||
57 | }; | ||
58 | |||
59 | #define EINJ_OP_BUSY 0x1 | ||
60 | #define EINJ_STATUS_SUCCESS 0x0 | ||
61 | #define EINJ_STATUS_FAIL 0x1 | ||
62 | #define EINJ_STATUS_INVAL 0x2 | ||
63 | |||
64 | #define EINJ_TAB_ENTRY(tab) \ | ||
65 | ((struct acpi_whea_header *)((char *)(tab) + \ | ||
66 | sizeof(struct acpi_table_einj))) | ||
67 | |||
68 | static struct acpi_table_einj *einj_tab; | ||
69 | |||
70 | static struct apei_resources einj_resources; | ||
71 | |||
72 | static struct apei_exec_ins_type einj_ins_type[] = { | ||
73 | [ACPI_EINJ_READ_REGISTER] = { | ||
74 | .flags = APEI_EXEC_INS_ACCESS_REGISTER, | ||
75 | .run = apei_exec_read_register, | ||
76 | }, | ||
77 | [ACPI_EINJ_READ_REGISTER_VALUE] = { | ||
78 | .flags = APEI_EXEC_INS_ACCESS_REGISTER, | ||
79 | .run = apei_exec_read_register_value, | ||
80 | }, | ||
81 | [ACPI_EINJ_WRITE_REGISTER] = { | ||
82 | .flags = APEI_EXEC_INS_ACCESS_REGISTER, | ||
83 | .run = apei_exec_write_register, | ||
84 | }, | ||
85 | [ACPI_EINJ_WRITE_REGISTER_VALUE] = { | ||
86 | .flags = APEI_EXEC_INS_ACCESS_REGISTER, | ||
87 | .run = apei_exec_write_register_value, | ||
88 | }, | ||
89 | [ACPI_EINJ_NOOP] = { | ||
90 | .flags = 0, | ||
91 | .run = apei_exec_noop, | ||
92 | }, | ||
93 | }; | ||
94 | |||
95 | /* | ||
96 | * Prevent EINJ interpreter to run simultaneously, because the | ||
97 | * corresponding firmware implementation may not work properly when | ||
98 | * invoked simultaneously. | ||
99 | */ | ||
100 | static DEFINE_MUTEX(einj_mutex); | ||
101 | |||
102 | static struct einj_parameter *einj_param; | ||
103 | |||
104 | static void einj_exec_ctx_init(struct apei_exec_context *ctx) | ||
105 | { | ||
106 | apei_exec_ctx_init(ctx, einj_ins_type, ARRAY_SIZE(einj_ins_type), | ||
107 | EINJ_TAB_ENTRY(einj_tab), einj_tab->entries); | ||
108 | } | ||
109 | |||
110 | static int __einj_get_available_error_type(u32 *type) | ||
111 | { | ||
112 | struct apei_exec_context ctx; | ||
113 | int rc; | ||
114 | |||
115 | einj_exec_ctx_init(&ctx); | ||
116 | rc = apei_exec_run(&ctx, ACPI_EINJ_GET_ERROR_TYPE); | ||
117 | if (rc) | ||
118 | return rc; | ||
119 | *type = apei_exec_ctx_get_output(&ctx); | ||
120 | |||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | /* Get error injection capabilities of the platform */ | ||
125 | static int einj_get_available_error_type(u32 *type) | ||
126 | { | ||
127 | int rc; | ||
128 | |||
129 | mutex_lock(&einj_mutex); | ||
130 | rc = __einj_get_available_error_type(type); | ||
131 | mutex_unlock(&einj_mutex); | ||
132 | |||
133 | return rc; | ||
134 | } | ||
135 | |||
136 | static int einj_timedout(u64 *t) | ||
137 | { | ||
138 | if ((s64)*t < SPIN_UNIT) { | ||
139 | pr_warning(FW_WARN EINJ_PFX | ||
140 | "Firmware does not respond in time\n"); | ||
141 | return 1; | ||
142 | } | ||
143 | *t -= SPIN_UNIT; | ||
144 | ndelay(SPIN_UNIT); | ||
145 | touch_nmi_watchdog(); | ||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | static u64 einj_get_parameter_address(void) | ||
150 | { | ||
151 | int i; | ||
152 | u64 paddr = 0; | ||
153 | struct acpi_whea_header *entry; | ||
154 | |||
155 | entry = EINJ_TAB_ENTRY(einj_tab); | ||
156 | for (i = 0; i < einj_tab->entries; i++) { | ||
157 | if (entry->action == ACPI_EINJ_SET_ERROR_TYPE && | ||
158 | entry->instruction == ACPI_EINJ_WRITE_REGISTER && | ||
159 | entry->register_region.space_id == | ||
160 | ACPI_ADR_SPACE_SYSTEM_MEMORY) | ||
161 | memcpy(&paddr, &entry->register_region.address, | ||
162 | sizeof(paddr)); | ||
163 | entry++; | ||
164 | } | ||
165 | |||
166 | return paddr; | ||
167 | } | ||
168 | |||
169 | /* do sanity check to trigger table */ | ||
170 | static int einj_check_trigger_header(struct acpi_einj_trigger *trigger_tab) | ||
171 | { | ||
172 | if (trigger_tab->header_size != sizeof(struct acpi_einj_trigger)) | ||
173 | return -EINVAL; | ||
174 | if (trigger_tab->table_size > PAGE_SIZE || | ||
175 | trigger_tab->table_size <= trigger_tab->header_size) | ||
176 | return -EINVAL; | ||
177 | if (trigger_tab->entry_count != | ||
178 | (trigger_tab->table_size - trigger_tab->header_size) / | ||
179 | sizeof(struct acpi_einj_entry)) | ||
180 | return -EINVAL; | ||
181 | |||
182 | return 0; | ||
183 | } | ||
184 | |||
185 | /* Execute instructions in trigger error action table */ | ||
186 | static int __einj_error_trigger(u64 trigger_paddr) | ||
187 | { | ||
188 | struct acpi_einj_trigger *trigger_tab = NULL; | ||
189 | struct apei_exec_context trigger_ctx; | ||
190 | struct apei_resources trigger_resources; | ||
191 | struct acpi_whea_header *trigger_entry; | ||
192 | struct resource *r; | ||
193 | u32 table_size; | ||
194 | int rc = -EIO; | ||
195 | |||
196 | r = request_mem_region(trigger_paddr, sizeof(*trigger_tab), | ||
197 | "APEI EINJ Trigger Table"); | ||
198 | if (!r) { | ||
199 | pr_err(EINJ_PFX | ||
200 | "Can not request iomem region <%016llx-%016llx> for Trigger table.\n", | ||
201 | (unsigned long long)trigger_paddr, | ||
202 | (unsigned long long)trigger_paddr+sizeof(*trigger_tab)); | ||
203 | goto out; | ||
204 | } | ||
205 | trigger_tab = ioremap_cache(trigger_paddr, sizeof(*trigger_tab)); | ||
206 | if (!trigger_tab) { | ||
207 | pr_err(EINJ_PFX "Failed to map trigger table!\n"); | ||
208 | goto out_rel_header; | ||
209 | } | ||
210 | rc = einj_check_trigger_header(trigger_tab); | ||
211 | if (rc) { | ||
212 | pr_warning(FW_BUG EINJ_PFX | ||
213 | "The trigger error action table is invalid\n"); | ||
214 | goto out_rel_header; | ||
215 | } | ||
216 | rc = -EIO; | ||
217 | table_size = trigger_tab->table_size; | ||
218 | r = request_mem_region(trigger_paddr + sizeof(*trigger_tab), | ||
219 | table_size - sizeof(*trigger_tab), | ||
220 | "APEI EINJ Trigger Table"); | ||
221 | if (!r) { | ||
222 | pr_err(EINJ_PFX | ||
223 | "Can not request iomem region <%016llx-%016llx> for Trigger Table Entry.\n", | ||
224 | (unsigned long long)trigger_paddr+sizeof(*trigger_tab), | ||
225 | (unsigned long long)trigger_paddr + table_size); | ||
226 | goto out_rel_header; | ||
227 | } | ||
228 | iounmap(trigger_tab); | ||
229 | trigger_tab = ioremap_cache(trigger_paddr, table_size); | ||
230 | if (!trigger_tab) { | ||
231 | pr_err(EINJ_PFX "Failed to map trigger table!\n"); | ||
232 | goto out_rel_entry; | ||
233 | } | ||
234 | trigger_entry = (struct acpi_whea_header *) | ||
235 | ((char *)trigger_tab + sizeof(struct acpi_einj_trigger)); | ||
236 | apei_resources_init(&trigger_resources); | ||
237 | apei_exec_ctx_init(&trigger_ctx, einj_ins_type, | ||
238 | ARRAY_SIZE(einj_ins_type), | ||
239 | trigger_entry, trigger_tab->entry_count); | ||
240 | rc = apei_exec_collect_resources(&trigger_ctx, &trigger_resources); | ||
241 | if (rc) | ||
242 | goto out_fini; | ||
243 | rc = apei_resources_sub(&trigger_resources, &einj_resources); | ||
244 | if (rc) | ||
245 | goto out_fini; | ||
246 | rc = apei_resources_request(&trigger_resources, "APEI EINJ Trigger"); | ||
247 | if (rc) | ||
248 | goto out_fini; | ||
249 | rc = apei_exec_pre_map_gars(&trigger_ctx); | ||
250 | if (rc) | ||
251 | goto out_release; | ||
252 | |||
253 | rc = apei_exec_run(&trigger_ctx, ACPI_EINJ_TRIGGER_ERROR); | ||
254 | |||
255 | apei_exec_post_unmap_gars(&trigger_ctx); | ||
256 | out_release: | ||
257 | apei_resources_release(&trigger_resources); | ||
258 | out_fini: | ||
259 | apei_resources_fini(&trigger_resources); | ||
260 | out_rel_entry: | ||
261 | release_mem_region(trigger_paddr + sizeof(*trigger_tab), | ||
262 | table_size - sizeof(*trigger_tab)); | ||
263 | out_rel_header: | ||
264 | release_mem_region(trigger_paddr, sizeof(*trigger_tab)); | ||
265 | out: | ||
266 | if (trigger_tab) | ||
267 | iounmap(trigger_tab); | ||
268 | |||
269 | return rc; | ||
270 | } | ||
271 | |||
272 | static int __einj_error_inject(u32 type, u64 param1, u64 param2) | ||
273 | { | ||
274 | struct apei_exec_context ctx; | ||
275 | u64 val, trigger_paddr, timeout = FIRMWARE_TIMEOUT; | ||
276 | int rc; | ||
277 | |||
278 | einj_exec_ctx_init(&ctx); | ||
279 | |||
280 | rc = apei_exec_run(&ctx, ACPI_EINJ_BEGIN_OPERATION); | ||
281 | if (rc) | ||
282 | return rc; | ||
283 | apei_exec_ctx_set_input(&ctx, type); | ||
284 | rc = apei_exec_run(&ctx, ACPI_EINJ_SET_ERROR_TYPE); | ||
285 | if (rc) | ||
286 | return rc; | ||
287 | if (einj_param) { | ||
288 | writeq(param1, &einj_param->param1); | ||
289 | writeq(param2, &einj_param->param2); | ||
290 | } | ||
291 | rc = apei_exec_run(&ctx, ACPI_EINJ_EXECUTE_OPERATION); | ||
292 | if (rc) | ||
293 | return rc; | ||
294 | for (;;) { | ||
295 | rc = apei_exec_run(&ctx, ACPI_EINJ_CHECK_BUSY_STATUS); | ||
296 | if (rc) | ||
297 | return rc; | ||
298 | val = apei_exec_ctx_get_output(&ctx); | ||
299 | if (!(val & EINJ_OP_BUSY)) | ||
300 | break; | ||
301 | if (einj_timedout(&timeout)) | ||
302 | return -EIO; | ||
303 | } | ||
304 | rc = apei_exec_run(&ctx, ACPI_EINJ_GET_COMMAND_STATUS); | ||
305 | if (rc) | ||
306 | return rc; | ||
307 | val = apei_exec_ctx_get_output(&ctx); | ||
308 | if (val != EINJ_STATUS_SUCCESS) | ||
309 | return -EBUSY; | ||
310 | |||
311 | rc = apei_exec_run(&ctx, ACPI_EINJ_GET_TRIGGER_TABLE); | ||
312 | if (rc) | ||
313 | return rc; | ||
314 | trigger_paddr = apei_exec_ctx_get_output(&ctx); | ||
315 | rc = __einj_error_trigger(trigger_paddr); | ||
316 | if (rc) | ||
317 | return rc; | ||
318 | rc = apei_exec_run(&ctx, ACPI_EINJ_END_OPERATION); | ||
319 | |||
320 | return rc; | ||
321 | } | ||
322 | |||
323 | /* Inject the specified hardware error */ | ||
324 | static int einj_error_inject(u32 type, u64 param1, u64 param2) | ||
325 | { | ||
326 | int rc; | ||
327 | |||
328 | mutex_lock(&einj_mutex); | ||
329 | rc = __einj_error_inject(type, param1, param2); | ||
330 | mutex_unlock(&einj_mutex); | ||
331 | |||
332 | return rc; | ||
333 | } | ||
334 | |||
335 | static u32 error_type; | ||
336 | static u64 error_param1; | ||
337 | static u64 error_param2; | ||
338 | static struct dentry *einj_debug_dir; | ||
339 | |||
340 | static int available_error_type_show(struct seq_file *m, void *v) | ||
341 | { | ||
342 | int rc; | ||
343 | u32 available_error_type = 0; | ||
344 | |||
345 | rc = einj_get_available_error_type(&available_error_type); | ||
346 | if (rc) | ||
347 | return rc; | ||
348 | if (available_error_type & 0x0001) | ||
349 | seq_printf(m, "0x00000001\tProcessor Correctable\n"); | ||
350 | if (available_error_type & 0x0002) | ||
351 | seq_printf(m, "0x00000002\tProcessor Uncorrectable non-fatal\n"); | ||
352 | if (available_error_type & 0x0004) | ||
353 | seq_printf(m, "0x00000004\tProcessor Uncorrectable fatal\n"); | ||
354 | if (available_error_type & 0x0008) | ||
355 | seq_printf(m, "0x00000008\tMemory Correctable\n"); | ||
356 | if (available_error_type & 0x0010) | ||
357 | seq_printf(m, "0x00000010\tMemory Uncorrectable non-fatal\n"); | ||
358 | if (available_error_type & 0x0020) | ||
359 | seq_printf(m, "0x00000020\tMemory Uncorrectable fatal\n"); | ||
360 | if (available_error_type & 0x0040) | ||
361 | seq_printf(m, "0x00000040\tPCI Express Correctable\n"); | ||
362 | if (available_error_type & 0x0080) | ||
363 | seq_printf(m, "0x00000080\tPCI Express Uncorrectable non-fatal\n"); | ||
364 | if (available_error_type & 0x0100) | ||
365 | seq_printf(m, "0x00000100\tPCI Express Uncorrectable fatal\n"); | ||
366 | if (available_error_type & 0x0200) | ||
367 | seq_printf(m, "0x00000200\tPlatform Correctable\n"); | ||
368 | if (available_error_type & 0x0400) | ||
369 | seq_printf(m, "0x00000400\tPlatform Uncorrectable non-fatal\n"); | ||
370 | if (available_error_type & 0x0800) | ||
371 | seq_printf(m, "0x00000800\tPlatform Uncorrectable fatal\n"); | ||
372 | |||
373 | return 0; | ||
374 | } | ||
375 | |||
376 | static int available_error_type_open(struct inode *inode, struct file *file) | ||
377 | { | ||
378 | return single_open(file, available_error_type_show, NULL); | ||
379 | } | ||
380 | |||
381 | static const struct file_operations available_error_type_fops = { | ||
382 | .open = available_error_type_open, | ||
383 | .read = seq_read, | ||
384 | .llseek = seq_lseek, | ||
385 | .release = single_release, | ||
386 | }; | ||
387 | |||
388 | static int error_type_get(void *data, u64 *val) | ||
389 | { | ||
390 | *val = error_type; | ||
391 | |||
392 | return 0; | ||
393 | } | ||
394 | |||
395 | static int error_type_set(void *data, u64 val) | ||
396 | { | ||
397 | int rc; | ||
398 | u32 available_error_type = 0; | ||
399 | |||
400 | /* Only one error type can be specified */ | ||
401 | if (val & (val - 1)) | ||
402 | return -EINVAL; | ||
403 | rc = einj_get_available_error_type(&available_error_type); | ||
404 | if (rc) | ||
405 | return rc; | ||
406 | if (!(val & available_error_type)) | ||
407 | return -EINVAL; | ||
408 | error_type = val; | ||
409 | |||
410 | return 0; | ||
411 | } | ||
412 | |||
413 | DEFINE_SIMPLE_ATTRIBUTE(error_type_fops, error_type_get, | ||
414 | error_type_set, "0x%llx\n"); | ||
415 | |||
416 | static int error_inject_set(void *data, u64 val) | ||
417 | { | ||
418 | if (!error_type) | ||
419 | return -EINVAL; | ||
420 | |||
421 | return einj_error_inject(error_type, error_param1, error_param2); | ||
422 | } | ||
423 | |||
424 | DEFINE_SIMPLE_ATTRIBUTE(error_inject_fops, NULL, | ||
425 | error_inject_set, "%llu\n"); | ||
426 | |||
427 | static int einj_check_table(struct acpi_table_einj *einj_tab) | ||
428 | { | ||
429 | if (einj_tab->header_length != sizeof(struct acpi_table_einj)) | ||
430 | return -EINVAL; | ||
431 | if (einj_tab->header.length < sizeof(struct acpi_table_einj)) | ||
432 | return -EINVAL; | ||
433 | if (einj_tab->entries != | ||
434 | (einj_tab->header.length - sizeof(struct acpi_table_einj)) / | ||
435 | sizeof(struct acpi_einj_entry)) | ||
436 | return -EINVAL; | ||
437 | |||
438 | return 0; | ||
439 | } | ||
440 | |||
441 | static int __init einj_init(void) | ||
442 | { | ||
443 | int rc; | ||
444 | u64 param_paddr; | ||
445 | acpi_status status; | ||
446 | struct dentry *fentry; | ||
447 | struct apei_exec_context ctx; | ||
448 | |||
449 | if (acpi_disabled) | ||
450 | return -ENODEV; | ||
451 | |||
452 | status = acpi_get_table(ACPI_SIG_EINJ, 0, | ||
453 | (struct acpi_table_header **)&einj_tab); | ||
454 | if (status == AE_NOT_FOUND) { | ||
455 | pr_info(EINJ_PFX "Table is not found!\n"); | ||
456 | return -ENODEV; | ||
457 | } else if (ACPI_FAILURE(status)) { | ||
458 | const char *msg = acpi_format_exception(status); | ||
459 | pr_err(EINJ_PFX "Failed to get table, %s\n", msg); | ||
460 | return -EINVAL; | ||
461 | } | ||
462 | |||
463 | rc = einj_check_table(einj_tab); | ||
464 | if (rc) { | ||
465 | pr_warning(FW_BUG EINJ_PFX "EINJ table is invalid\n"); | ||
466 | return -EINVAL; | ||
467 | } | ||
468 | |||
469 | rc = -ENOMEM; | ||
470 | einj_debug_dir = debugfs_create_dir("einj", apei_get_debugfs_dir()); | ||
471 | if (!einj_debug_dir) | ||
472 | goto err_cleanup; | ||
473 | fentry = debugfs_create_file("available_error_type", S_IRUSR, | ||
474 | einj_debug_dir, NULL, | ||
475 | &available_error_type_fops); | ||
476 | if (!fentry) | ||
477 | goto err_cleanup; | ||
478 | fentry = debugfs_create_file("error_type", S_IRUSR | S_IWUSR, | ||
479 | einj_debug_dir, NULL, &error_type_fops); | ||
480 | if (!fentry) | ||
481 | goto err_cleanup; | ||
482 | fentry = debugfs_create_x64("param1", S_IRUSR | S_IWUSR, | ||
483 | einj_debug_dir, &error_param1); | ||
484 | if (!fentry) | ||
485 | goto err_cleanup; | ||
486 | fentry = debugfs_create_x64("param2", S_IRUSR | S_IWUSR, | ||
487 | einj_debug_dir, &error_param2); | ||
488 | if (!fentry) | ||
489 | goto err_cleanup; | ||
490 | fentry = debugfs_create_file("error_inject", S_IWUSR, | ||
491 | einj_debug_dir, NULL, &error_inject_fops); | ||
492 | if (!fentry) | ||
493 | goto err_cleanup; | ||
494 | |||
495 | apei_resources_init(&einj_resources); | ||
496 | einj_exec_ctx_init(&ctx); | ||
497 | rc = apei_exec_collect_resources(&ctx, &einj_resources); | ||
498 | if (rc) | ||
499 | goto err_fini; | ||
500 | rc = apei_resources_request(&einj_resources, "APEI EINJ"); | ||
501 | if (rc) | ||
502 | goto err_fini; | ||
503 | rc = apei_exec_pre_map_gars(&ctx); | ||
504 | if (rc) | ||
505 | goto err_release; | ||
506 | param_paddr = einj_get_parameter_address(); | ||
507 | if (param_paddr) { | ||
508 | einj_param = ioremap(param_paddr, sizeof(*einj_param)); | ||
509 | rc = -ENOMEM; | ||
510 | if (!einj_param) | ||
511 | goto err_unmap; | ||
512 | } | ||
513 | |||
514 | pr_info(EINJ_PFX "Error INJection is initialized.\n"); | ||
515 | |||
516 | return 0; | ||
517 | |||
518 | err_unmap: | ||
519 | apei_exec_post_unmap_gars(&ctx); | ||
520 | err_release: | ||
521 | apei_resources_release(&einj_resources); | ||
522 | err_fini: | ||
523 | apei_resources_fini(&einj_resources); | ||
524 | err_cleanup: | ||
525 | debugfs_remove_recursive(einj_debug_dir); | ||
526 | |||
527 | return rc; | ||
528 | } | ||
529 | |||
530 | static void __exit einj_exit(void) | ||
531 | { | ||
532 | struct apei_exec_context ctx; | ||
533 | |||
534 | if (einj_param) | ||
535 | iounmap(einj_param); | ||
536 | einj_exec_ctx_init(&ctx); | ||
537 | apei_exec_post_unmap_gars(&ctx); | ||
538 | apei_resources_release(&einj_resources); | ||
539 | apei_resources_fini(&einj_resources); | ||
540 | debugfs_remove_recursive(einj_debug_dir); | ||
541 | } | ||
542 | |||
543 | module_init(einj_init); | ||
544 | module_exit(einj_exit); | ||
545 | |||
546 | MODULE_AUTHOR("Huang Ying"); | ||
547 | MODULE_DESCRIPTION("APEI Error INJection support"); | ||
548 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c new file mode 100644 index 000000000000..2ebc39115507 --- /dev/null +++ b/drivers/acpi/apei/erst.c | |||
@@ -0,0 +1,855 @@ | |||
1 | /* | ||
2 | * APEI Error Record Serialization Table support | ||
3 | * | ||
4 | * ERST is a way provided by APEI to save and retrieve hardware error | ||
5 | * infomation to and from a persistent store. | ||
6 | * | ||
7 | * For more information about ERST, please refer to ACPI Specification | ||
8 | * version 4.0, section 17.4. | ||
9 | * | ||
10 | * Copyright 2010 Intel Corp. | ||
11 | * Author: Huang Ying <ying.huang@intel.com> | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License version | ||
15 | * 2 as published by the Free Software Foundation. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; if not, write to the Free Software | ||
24 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
25 | */ | ||
26 | |||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <linux/init.h> | ||
30 | #include <linux/delay.h> | ||
31 | #include <linux/io.h> | ||
32 | #include <linux/acpi.h> | ||
33 | #include <linux/uaccess.h> | ||
34 | #include <linux/cper.h> | ||
35 | #include <linux/nmi.h> | ||
36 | #include <acpi/apei.h> | ||
37 | |||
38 | #include "apei-internal.h" | ||
39 | |||
40 | #define ERST_PFX "ERST: " | ||
41 | |||
42 | /* ERST command status */ | ||
43 | #define ERST_STATUS_SUCCESS 0x0 | ||
44 | #define ERST_STATUS_NOT_ENOUGH_SPACE 0x1 | ||
45 | #define ERST_STATUS_HARDWARE_NOT_AVAILABLE 0x2 | ||
46 | #define ERST_STATUS_FAILED 0x3 | ||
47 | #define ERST_STATUS_RECORD_STORE_EMPTY 0x4 | ||
48 | #define ERST_STATUS_RECORD_NOT_FOUND 0x5 | ||
49 | |||
50 | #define ERST_TAB_ENTRY(tab) \ | ||
51 | ((struct acpi_whea_header *)((char *)(tab) + \ | ||
52 | sizeof(struct acpi_table_erst))) | ||
53 | |||
54 | #define SPIN_UNIT 100 /* 100ns */ | ||
55 | /* Firmware should respond within 1 miliseconds */ | ||
56 | #define FIRMWARE_TIMEOUT (1 * NSEC_PER_MSEC) | ||
57 | #define FIRMWARE_MAX_STALL 50 /* 50us */ | ||
58 | |||
59 | int erst_disable; | ||
60 | EXPORT_SYMBOL_GPL(erst_disable); | ||
61 | |||
62 | static struct acpi_table_erst *erst_tab; | ||
63 | |||
64 | /* ERST Error Log Address Range atrributes */ | ||
65 | #define ERST_RANGE_RESERVED 0x0001 | ||
66 | #define ERST_RANGE_NVRAM 0x0002 | ||
67 | #define ERST_RANGE_SLOW 0x0004 | ||
68 | |||
69 | /* | ||
70 | * ERST Error Log Address Range, used as buffer for reading/writing | ||
71 | * error records. | ||
72 | */ | ||
73 | static struct erst_erange { | ||
74 | u64 base; | ||
75 | u64 size; | ||
76 | void __iomem *vaddr; | ||
77 | u32 attr; | ||
78 | } erst_erange; | ||
79 | |||
80 | /* | ||
81 | * Prevent ERST interpreter to run simultaneously, because the | ||
82 | * corresponding firmware implementation may not work properly when | ||
83 | * invoked simultaneously. | ||
84 | * | ||
85 | * It is used to provide exclusive accessing for ERST Error Log | ||
86 | * Address Range too. | ||
87 | */ | ||
88 | static DEFINE_SPINLOCK(erst_lock); | ||
89 | |||
90 | static inline int erst_errno(int command_status) | ||
91 | { | ||
92 | switch (command_status) { | ||
93 | case ERST_STATUS_SUCCESS: | ||
94 | return 0; | ||
95 | case ERST_STATUS_HARDWARE_NOT_AVAILABLE: | ||
96 | return -ENODEV; | ||
97 | case ERST_STATUS_NOT_ENOUGH_SPACE: | ||
98 | return -ENOSPC; | ||
99 | case ERST_STATUS_RECORD_STORE_EMPTY: | ||
100 | case ERST_STATUS_RECORD_NOT_FOUND: | ||
101 | return -ENOENT; | ||
102 | default: | ||
103 | return -EINVAL; | ||
104 | } | ||
105 | } | ||
106 | |||
107 | static int erst_timedout(u64 *t, u64 spin_unit) | ||
108 | { | ||
109 | if ((s64)*t < spin_unit) { | ||
110 | pr_warning(FW_WARN ERST_PFX | ||
111 | "Firmware does not respond in time\n"); | ||
112 | return 1; | ||
113 | } | ||
114 | *t -= spin_unit; | ||
115 | ndelay(spin_unit); | ||
116 | touch_nmi_watchdog(); | ||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | static int erst_exec_load_var1(struct apei_exec_context *ctx, | ||
121 | struct acpi_whea_header *entry) | ||
122 | { | ||
123 | return __apei_exec_read_register(entry, &ctx->var1); | ||
124 | } | ||
125 | |||
126 | static int erst_exec_load_var2(struct apei_exec_context *ctx, | ||
127 | struct acpi_whea_header *entry) | ||
128 | { | ||
129 | return __apei_exec_read_register(entry, &ctx->var2); | ||
130 | } | ||
131 | |||
132 | static int erst_exec_store_var1(struct apei_exec_context *ctx, | ||
133 | struct acpi_whea_header *entry) | ||
134 | { | ||
135 | return __apei_exec_write_register(entry, ctx->var1); | ||
136 | } | ||
137 | |||
138 | static int erst_exec_add(struct apei_exec_context *ctx, | ||
139 | struct acpi_whea_header *entry) | ||
140 | { | ||
141 | ctx->var1 += ctx->var2; | ||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | static int erst_exec_subtract(struct apei_exec_context *ctx, | ||
146 | struct acpi_whea_header *entry) | ||
147 | { | ||
148 | ctx->var1 -= ctx->var2; | ||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | static int erst_exec_add_value(struct apei_exec_context *ctx, | ||
153 | struct acpi_whea_header *entry) | ||
154 | { | ||
155 | int rc; | ||
156 | u64 val; | ||
157 | |||
158 | rc = __apei_exec_read_register(entry, &val); | ||
159 | if (rc) | ||
160 | return rc; | ||
161 | val += ctx->value; | ||
162 | rc = __apei_exec_write_register(entry, val); | ||
163 | return rc; | ||
164 | } | ||
165 | |||
166 | static int erst_exec_subtract_value(struct apei_exec_context *ctx, | ||
167 | struct acpi_whea_header *entry) | ||
168 | { | ||
169 | int rc; | ||
170 | u64 val; | ||
171 | |||
172 | rc = __apei_exec_read_register(entry, &val); | ||
173 | if (rc) | ||
174 | return rc; | ||
175 | val -= ctx->value; | ||
176 | rc = __apei_exec_write_register(entry, val); | ||
177 | return rc; | ||
178 | } | ||
179 | |||
180 | static int erst_exec_stall(struct apei_exec_context *ctx, | ||
181 | struct acpi_whea_header *entry) | ||
182 | { | ||
183 | u64 stall_time; | ||
184 | |||
185 | if (ctx->value > FIRMWARE_MAX_STALL) { | ||
186 | if (!in_nmi()) | ||
187 | pr_warning(FW_WARN ERST_PFX | ||
188 | "Too long stall time for stall instruction: %llx.\n", | ||
189 | ctx->value); | ||
190 | stall_time = FIRMWARE_MAX_STALL; | ||
191 | } else | ||
192 | stall_time = ctx->value; | ||
193 | udelay(stall_time); | ||
194 | return 0; | ||
195 | } | ||
196 | |||
197 | static int erst_exec_stall_while_true(struct apei_exec_context *ctx, | ||
198 | struct acpi_whea_header *entry) | ||
199 | { | ||
200 | int rc; | ||
201 | u64 val; | ||
202 | u64 timeout = FIRMWARE_TIMEOUT; | ||
203 | u64 stall_time; | ||
204 | |||
205 | if (ctx->var1 > FIRMWARE_MAX_STALL) { | ||
206 | if (!in_nmi()) | ||
207 | pr_warning(FW_WARN ERST_PFX | ||
208 | "Too long stall time for stall while true instruction: %llx.\n", | ||
209 | ctx->var1); | ||
210 | stall_time = FIRMWARE_MAX_STALL; | ||
211 | } else | ||
212 | stall_time = ctx->var1; | ||
213 | |||
214 | for (;;) { | ||
215 | rc = __apei_exec_read_register(entry, &val); | ||
216 | if (rc) | ||
217 | return rc; | ||
218 | if (val != ctx->value) | ||
219 | break; | ||
220 | if (erst_timedout(&timeout, stall_time * NSEC_PER_USEC)) | ||
221 | return -EIO; | ||
222 | } | ||
223 | return 0; | ||
224 | } | ||
225 | |||
226 | static int erst_exec_skip_next_instruction_if_true( | ||
227 | struct apei_exec_context *ctx, | ||
228 | struct acpi_whea_header *entry) | ||
229 | { | ||
230 | int rc; | ||
231 | u64 val; | ||
232 | |||
233 | rc = __apei_exec_read_register(entry, &val); | ||
234 | if (rc) | ||
235 | return rc; | ||
236 | if (val == ctx->value) { | ||
237 | ctx->ip += 2; | ||
238 | return APEI_EXEC_SET_IP; | ||
239 | } | ||
240 | |||
241 | return 0; | ||
242 | } | ||
243 | |||
244 | static int erst_exec_goto(struct apei_exec_context *ctx, | ||
245 | struct acpi_whea_header *entry) | ||
246 | { | ||
247 | ctx->ip = ctx->value; | ||
248 | return APEI_EXEC_SET_IP; | ||
249 | } | ||
250 | |||
251 | static int erst_exec_set_src_address_base(struct apei_exec_context *ctx, | ||
252 | struct acpi_whea_header *entry) | ||
253 | { | ||
254 | return __apei_exec_read_register(entry, &ctx->src_base); | ||
255 | } | ||
256 | |||
257 | static int erst_exec_set_dst_address_base(struct apei_exec_context *ctx, | ||
258 | struct acpi_whea_header *entry) | ||
259 | { | ||
260 | return __apei_exec_read_register(entry, &ctx->dst_base); | ||
261 | } | ||
262 | |||
263 | static int erst_exec_move_data(struct apei_exec_context *ctx, | ||
264 | struct acpi_whea_header *entry) | ||
265 | { | ||
266 | int rc; | ||
267 | u64 offset; | ||
268 | |||
269 | rc = __apei_exec_read_register(entry, &offset); | ||
270 | if (rc) | ||
271 | return rc; | ||
272 | memmove((void *)ctx->dst_base + offset, | ||
273 | (void *)ctx->src_base + offset, | ||
274 | ctx->var2); | ||
275 | |||
276 | return 0; | ||
277 | } | ||
278 | |||
279 | static struct apei_exec_ins_type erst_ins_type[] = { | ||
280 | [ACPI_ERST_READ_REGISTER] = { | ||
281 | .flags = APEI_EXEC_INS_ACCESS_REGISTER, | ||
282 | .run = apei_exec_read_register, | ||
283 | }, | ||
284 | [ACPI_ERST_READ_REGISTER_VALUE] = { | ||
285 | .flags = APEI_EXEC_INS_ACCESS_REGISTER, | ||
286 | .run = apei_exec_read_register_value, | ||
287 | }, | ||
288 | [ACPI_ERST_WRITE_REGISTER] = { | ||
289 | .flags = APEI_EXEC_INS_ACCESS_REGISTER, | ||
290 | .run = apei_exec_write_register, | ||
291 | }, | ||
292 | [ACPI_ERST_WRITE_REGISTER_VALUE] = { | ||
293 | .flags = APEI_EXEC_INS_ACCESS_REGISTER, | ||
294 | .run = apei_exec_write_register_value, | ||
295 | }, | ||
296 | [ACPI_ERST_NOOP] = { | ||
297 | .flags = 0, | ||
298 | .run = apei_exec_noop, | ||
299 | }, | ||
300 | [ACPI_ERST_LOAD_VAR1] = { | ||
301 | .flags = APEI_EXEC_INS_ACCESS_REGISTER, | ||
302 | .run = erst_exec_load_var1, | ||
303 | }, | ||
304 | [ACPI_ERST_LOAD_VAR2] = { | ||
305 | .flags = APEI_EXEC_INS_ACCESS_REGISTER, | ||
306 | .run = erst_exec_load_var2, | ||
307 | }, | ||
308 | [ACPI_ERST_STORE_VAR1] = { | ||
309 | .flags = APEI_EXEC_INS_ACCESS_REGISTER, | ||
310 | .run = erst_exec_store_var1, | ||
311 | }, | ||
312 | [ACPI_ERST_ADD] = { | ||
313 | .flags = 0, | ||
314 | .run = erst_exec_add, | ||
315 | }, | ||
316 | [ACPI_ERST_SUBTRACT] = { | ||
317 | .flags = 0, | ||
318 | .run = erst_exec_subtract, | ||
319 | }, | ||
320 | [ACPI_ERST_ADD_VALUE] = { | ||
321 | .flags = APEI_EXEC_INS_ACCESS_REGISTER, | ||
322 | .run = erst_exec_add_value, | ||
323 | }, | ||
324 | [ACPI_ERST_SUBTRACT_VALUE] = { | ||
325 | .flags = APEI_EXEC_INS_ACCESS_REGISTER, | ||
326 | .run = erst_exec_subtract_value, | ||
327 | }, | ||
328 | [ACPI_ERST_STALL] = { | ||
329 | .flags = 0, | ||
330 | .run = erst_exec_stall, | ||
331 | }, | ||
332 | [ACPI_ERST_STALL_WHILE_TRUE] = { | ||
333 | .flags = APEI_EXEC_INS_ACCESS_REGISTER, | ||
334 | .run = erst_exec_stall_while_true, | ||
335 | }, | ||
336 | [ACPI_ERST_SKIP_NEXT_IF_TRUE] = { | ||
337 | .flags = APEI_EXEC_INS_ACCESS_REGISTER, | ||
338 | .run = erst_exec_skip_next_instruction_if_true, | ||
339 | }, | ||
340 | [ACPI_ERST_GOTO] = { | ||
341 | .flags = 0, | ||
342 | .run = erst_exec_goto, | ||
343 | }, | ||
344 | [ACPI_ERST_SET_SRC_ADDRESS_BASE] = { | ||
345 | .flags = APEI_EXEC_INS_ACCESS_REGISTER, | ||
346 | .run = erst_exec_set_src_address_base, | ||
347 | }, | ||
348 | [ACPI_ERST_SET_DST_ADDRESS_BASE] = { | ||
349 | .flags = APEI_EXEC_INS_ACCESS_REGISTER, | ||
350 | .run = erst_exec_set_dst_address_base, | ||
351 | }, | ||
352 | [ACPI_ERST_MOVE_DATA] = { | ||
353 | .flags = APEI_EXEC_INS_ACCESS_REGISTER, | ||
354 | .run = erst_exec_move_data, | ||
355 | }, | ||
356 | }; | ||
357 | |||
358 | static inline void erst_exec_ctx_init(struct apei_exec_context *ctx) | ||
359 | { | ||
360 | apei_exec_ctx_init(ctx, erst_ins_type, ARRAY_SIZE(erst_ins_type), | ||
361 | ERST_TAB_ENTRY(erst_tab), erst_tab->entries); | ||
362 | } | ||
363 | |||
364 | static int erst_get_erange(struct erst_erange *range) | ||
365 | { | ||
366 | struct apei_exec_context ctx; | ||
367 | int rc; | ||
368 | |||
369 | erst_exec_ctx_init(&ctx); | ||
370 | rc = apei_exec_run(&ctx, ACPI_ERST_GET_ERROR_RANGE); | ||
371 | if (rc) | ||
372 | return rc; | ||
373 | range->base = apei_exec_ctx_get_output(&ctx); | ||
374 | rc = apei_exec_run(&ctx, ACPI_ERST_GET_ERROR_LENGTH); | ||
375 | if (rc) | ||
376 | return rc; | ||
377 | range->size = apei_exec_ctx_get_output(&ctx); | ||
378 | rc = apei_exec_run(&ctx, ACPI_ERST_GET_ERROR_ATTRIBUTES); | ||
379 | if (rc) | ||
380 | return rc; | ||
381 | range->attr = apei_exec_ctx_get_output(&ctx); | ||
382 | |||
383 | return 0; | ||
384 | } | ||
385 | |||
386 | static ssize_t __erst_get_record_count(void) | ||
387 | { | ||
388 | struct apei_exec_context ctx; | ||
389 | int rc; | ||
390 | |||
391 | erst_exec_ctx_init(&ctx); | ||
392 | rc = apei_exec_run(&ctx, ACPI_ERST_GET_RECORD_COUNT); | ||
393 | if (rc) | ||
394 | return rc; | ||
395 | return apei_exec_ctx_get_output(&ctx); | ||
396 | } | ||
397 | |||
398 | ssize_t erst_get_record_count(void) | ||
399 | { | ||
400 | ssize_t count; | ||
401 | unsigned long flags; | ||
402 | |||
403 | if (erst_disable) | ||
404 | return -ENODEV; | ||
405 | |||
406 | spin_lock_irqsave(&erst_lock, flags); | ||
407 | count = __erst_get_record_count(); | ||
408 | spin_unlock_irqrestore(&erst_lock, flags); | ||
409 | |||
410 | return count; | ||
411 | } | ||
412 | EXPORT_SYMBOL_GPL(erst_get_record_count); | ||
413 | |||
414 | static int __erst_get_next_record_id(u64 *record_id) | ||
415 | { | ||
416 | struct apei_exec_context ctx; | ||
417 | int rc; | ||
418 | |||
419 | erst_exec_ctx_init(&ctx); | ||
420 | rc = apei_exec_run(&ctx, ACPI_ERST_GET_RECORD_ID); | ||
421 | if (rc) | ||
422 | return rc; | ||
423 | *record_id = apei_exec_ctx_get_output(&ctx); | ||
424 | |||
425 | return 0; | ||
426 | } | ||
427 | |||
428 | /* | ||
429 | * Get the record ID of an existing error record on the persistent | ||
430 | * storage. If there is no error record on the persistent storage, the | ||
431 | * returned record_id is APEI_ERST_INVALID_RECORD_ID. | ||
432 | */ | ||
433 | int erst_get_next_record_id(u64 *record_id) | ||
434 | { | ||
435 | int rc; | ||
436 | unsigned long flags; | ||
437 | |||
438 | if (erst_disable) | ||
439 | return -ENODEV; | ||
440 | |||
441 | spin_lock_irqsave(&erst_lock, flags); | ||
442 | rc = __erst_get_next_record_id(record_id); | ||
443 | spin_unlock_irqrestore(&erst_lock, flags); | ||
444 | |||
445 | return rc; | ||
446 | } | ||
447 | EXPORT_SYMBOL_GPL(erst_get_next_record_id); | ||
448 | |||
449 | static int __erst_write_to_storage(u64 offset) | ||
450 | { | ||
451 | struct apei_exec_context ctx; | ||
452 | u64 timeout = FIRMWARE_TIMEOUT; | ||
453 | u64 val; | ||
454 | int rc; | ||
455 | |||
456 | erst_exec_ctx_init(&ctx); | ||
457 | rc = apei_exec_run(&ctx, ACPI_ERST_BEGIN_WRITE); | ||
458 | if (rc) | ||
459 | return rc; | ||
460 | apei_exec_ctx_set_input(&ctx, offset); | ||
461 | rc = apei_exec_run(&ctx, ACPI_ERST_SET_RECORD_OFFSET); | ||
462 | if (rc) | ||
463 | return rc; | ||
464 | rc = apei_exec_run(&ctx, ACPI_ERST_EXECUTE_OPERATION); | ||
465 | if (rc) | ||
466 | return rc; | ||
467 | for (;;) { | ||
468 | rc = apei_exec_run(&ctx, ACPI_ERST_CHECK_BUSY_STATUS); | ||
469 | if (rc) | ||
470 | return rc; | ||
471 | val = apei_exec_ctx_get_output(&ctx); | ||
472 | if (!val) | ||
473 | break; | ||
474 | if (erst_timedout(&timeout, SPIN_UNIT)) | ||
475 | return -EIO; | ||
476 | } | ||
477 | rc = apei_exec_run(&ctx, ACPI_ERST_GET_COMMAND_STATUS); | ||
478 | if (rc) | ||
479 | return rc; | ||
480 | val = apei_exec_ctx_get_output(&ctx); | ||
481 | rc = apei_exec_run(&ctx, ACPI_ERST_END); | ||
482 | if (rc) | ||
483 | return rc; | ||
484 | |||
485 | return erst_errno(val); | ||
486 | } | ||
487 | |||
488 | static int __erst_read_from_storage(u64 record_id, u64 offset) | ||
489 | { | ||
490 | struct apei_exec_context ctx; | ||
491 | u64 timeout = FIRMWARE_TIMEOUT; | ||
492 | u64 val; | ||
493 | int rc; | ||
494 | |||
495 | erst_exec_ctx_init(&ctx); | ||
496 | rc = apei_exec_run(&ctx, ACPI_ERST_BEGIN_READ); | ||
497 | if (rc) | ||
498 | return rc; | ||
499 | apei_exec_ctx_set_input(&ctx, offset); | ||
500 | rc = apei_exec_run(&ctx, ACPI_ERST_SET_RECORD_OFFSET); | ||
501 | if (rc) | ||
502 | return rc; | ||
503 | apei_exec_ctx_set_input(&ctx, record_id); | ||
504 | rc = apei_exec_run(&ctx, ACPI_ERST_SET_RECORD_ID); | ||
505 | if (rc) | ||
506 | return rc; | ||
507 | rc = apei_exec_run(&ctx, ACPI_ERST_EXECUTE_OPERATION); | ||
508 | if (rc) | ||
509 | return rc; | ||
510 | for (;;) { | ||
511 | rc = apei_exec_run(&ctx, ACPI_ERST_CHECK_BUSY_STATUS); | ||
512 | if (rc) | ||
513 | return rc; | ||
514 | val = apei_exec_ctx_get_output(&ctx); | ||
515 | if (!val) | ||
516 | break; | ||
517 | if (erst_timedout(&timeout, SPIN_UNIT)) | ||
518 | return -EIO; | ||
519 | }; | ||
520 | rc = apei_exec_run(&ctx, ACPI_ERST_GET_COMMAND_STATUS); | ||
521 | if (rc) | ||
522 | return rc; | ||
523 | val = apei_exec_ctx_get_output(&ctx); | ||
524 | rc = apei_exec_run(&ctx, ACPI_ERST_END); | ||
525 | if (rc) | ||
526 | return rc; | ||
527 | |||
528 | return erst_errno(val); | ||
529 | } | ||
530 | |||
531 | static int __erst_clear_from_storage(u64 record_id) | ||
532 | { | ||
533 | struct apei_exec_context ctx; | ||
534 | u64 timeout = FIRMWARE_TIMEOUT; | ||
535 | u64 val; | ||
536 | int rc; | ||
537 | |||
538 | erst_exec_ctx_init(&ctx); | ||
539 | rc = apei_exec_run(&ctx, ACPI_ERST_BEGIN_CLEAR); | ||
540 | if (rc) | ||
541 | return rc; | ||
542 | apei_exec_ctx_set_input(&ctx, record_id); | ||
543 | rc = apei_exec_run(&ctx, ACPI_ERST_SET_RECORD_ID); | ||
544 | if (rc) | ||
545 | return rc; | ||
546 | rc = apei_exec_run(&ctx, ACPI_ERST_EXECUTE_OPERATION); | ||
547 | if (rc) | ||
548 | return rc; | ||
549 | for (;;) { | ||
550 | rc = apei_exec_run(&ctx, ACPI_ERST_CHECK_BUSY_STATUS); | ||
551 | if (rc) | ||
552 | return rc; | ||
553 | val = apei_exec_ctx_get_output(&ctx); | ||
554 | if (!val) | ||
555 | break; | ||
556 | if (erst_timedout(&timeout, SPIN_UNIT)) | ||
557 | return -EIO; | ||
558 | } | ||
559 | rc = apei_exec_run(&ctx, ACPI_ERST_GET_COMMAND_STATUS); | ||
560 | if (rc) | ||
561 | return rc; | ||
562 | val = apei_exec_ctx_get_output(&ctx); | ||
563 | rc = apei_exec_run(&ctx, ACPI_ERST_END); | ||
564 | if (rc) | ||
565 | return rc; | ||
566 | |||
567 | return erst_errno(val); | ||
568 | } | ||
569 | |||
570 | /* NVRAM ERST Error Log Address Range is not supported yet */ | ||
571 | static void pr_unimpl_nvram(void) | ||
572 | { | ||
573 | if (printk_ratelimit()) | ||
574 | pr_warning(ERST_PFX | ||
575 | "NVRAM ERST Log Address Range is not implemented yet\n"); | ||
576 | } | ||
577 | |||
578 | static int __erst_write_to_nvram(const struct cper_record_header *record) | ||
579 | { | ||
580 | /* do not print message, because printk is not safe for NMI */ | ||
581 | return -ENOSYS; | ||
582 | } | ||
583 | |||
584 | static int __erst_read_to_erange_from_nvram(u64 record_id, u64 *offset) | ||
585 | { | ||
586 | pr_unimpl_nvram(); | ||
587 | return -ENOSYS; | ||
588 | } | ||
589 | |||
590 | static int __erst_clear_from_nvram(u64 record_id) | ||
591 | { | ||
592 | pr_unimpl_nvram(); | ||
593 | return -ENOSYS; | ||
594 | } | ||
595 | |||
596 | int erst_write(const struct cper_record_header *record) | ||
597 | { | ||
598 | int rc; | ||
599 | unsigned long flags; | ||
600 | struct cper_record_header *rcd_erange; | ||
601 | |||
602 | if (erst_disable) | ||
603 | return -ENODEV; | ||
604 | |||
605 | if (memcmp(record->signature, CPER_SIG_RECORD, CPER_SIG_SIZE)) | ||
606 | return -EINVAL; | ||
607 | |||
608 | if (erst_erange.attr & ERST_RANGE_NVRAM) { | ||
609 | if (!spin_trylock_irqsave(&erst_lock, flags)) | ||
610 | return -EBUSY; | ||
611 | rc = __erst_write_to_nvram(record); | ||
612 | spin_unlock_irqrestore(&erst_lock, flags); | ||
613 | return rc; | ||
614 | } | ||
615 | |||
616 | if (record->record_length > erst_erange.size) | ||
617 | return -EINVAL; | ||
618 | |||
619 | if (!spin_trylock_irqsave(&erst_lock, flags)) | ||
620 | return -EBUSY; | ||
621 | memcpy(erst_erange.vaddr, record, record->record_length); | ||
622 | rcd_erange = erst_erange.vaddr; | ||
623 | /* signature for serialization system */ | ||
624 | memcpy(&rcd_erange->persistence_information, "ER", 2); | ||
625 | |||
626 | rc = __erst_write_to_storage(0); | ||
627 | spin_unlock_irqrestore(&erst_lock, flags); | ||
628 | |||
629 | return rc; | ||
630 | } | ||
631 | EXPORT_SYMBOL_GPL(erst_write); | ||
632 | |||
633 | static int __erst_read_to_erange(u64 record_id, u64 *offset) | ||
634 | { | ||
635 | int rc; | ||
636 | |||
637 | if (erst_erange.attr & ERST_RANGE_NVRAM) | ||
638 | return __erst_read_to_erange_from_nvram( | ||
639 | record_id, offset); | ||
640 | |||
641 | rc = __erst_read_from_storage(record_id, 0); | ||
642 | if (rc) | ||
643 | return rc; | ||
644 | *offset = 0; | ||
645 | |||
646 | return 0; | ||
647 | } | ||
648 | |||
649 | static ssize_t __erst_read(u64 record_id, struct cper_record_header *record, | ||
650 | size_t buflen) | ||
651 | { | ||
652 | int rc; | ||
653 | u64 offset, len = 0; | ||
654 | struct cper_record_header *rcd_tmp; | ||
655 | |||
656 | rc = __erst_read_to_erange(record_id, &offset); | ||
657 | if (rc) | ||
658 | return rc; | ||
659 | rcd_tmp = erst_erange.vaddr + offset; | ||
660 | len = rcd_tmp->record_length; | ||
661 | if (len <= buflen) | ||
662 | memcpy(record, rcd_tmp, len); | ||
663 | |||
664 | return len; | ||
665 | } | ||
666 | |||
667 | /* | ||
668 | * If return value > buflen, the buffer size is not big enough, | ||
669 | * else if return value < 0, something goes wrong, | ||
670 | * else everything is OK, and return value is record length | ||
671 | */ | ||
672 | ssize_t erst_read(u64 record_id, struct cper_record_header *record, | ||
673 | size_t buflen) | ||
674 | { | ||
675 | ssize_t len; | ||
676 | unsigned long flags; | ||
677 | |||
678 | if (erst_disable) | ||
679 | return -ENODEV; | ||
680 | |||
681 | spin_lock_irqsave(&erst_lock, flags); | ||
682 | len = __erst_read(record_id, record, buflen); | ||
683 | spin_unlock_irqrestore(&erst_lock, flags); | ||
684 | return len; | ||
685 | } | ||
686 | EXPORT_SYMBOL_GPL(erst_read); | ||
687 | |||
688 | /* | ||
689 | * If return value > buflen, the buffer size is not big enough, | ||
690 | * else if return value = 0, there is no more record to read, | ||
691 | * else if return value < 0, something goes wrong, | ||
692 | * else everything is OK, and return value is record length | ||
693 | */ | ||
694 | ssize_t erst_read_next(struct cper_record_header *record, size_t buflen) | ||
695 | { | ||
696 | int rc; | ||
697 | ssize_t len; | ||
698 | unsigned long flags; | ||
699 | u64 record_id; | ||
700 | |||
701 | if (erst_disable) | ||
702 | return -ENODEV; | ||
703 | |||
704 | spin_lock_irqsave(&erst_lock, flags); | ||
705 | rc = __erst_get_next_record_id(&record_id); | ||
706 | if (rc) { | ||
707 | spin_unlock_irqrestore(&erst_lock, flags); | ||
708 | return rc; | ||
709 | } | ||
710 | /* no more record */ | ||
711 | if (record_id == APEI_ERST_INVALID_RECORD_ID) { | ||
712 | spin_unlock_irqrestore(&erst_lock, flags); | ||
713 | return 0; | ||
714 | } | ||
715 | |||
716 | len = __erst_read(record_id, record, buflen); | ||
717 | spin_unlock_irqrestore(&erst_lock, flags); | ||
718 | |||
719 | return len; | ||
720 | } | ||
721 | EXPORT_SYMBOL_GPL(erst_read_next); | ||
722 | |||
723 | int erst_clear(u64 record_id) | ||
724 | { | ||
725 | int rc; | ||
726 | unsigned long flags; | ||
727 | |||
728 | if (erst_disable) | ||
729 | return -ENODEV; | ||
730 | |||
731 | spin_lock_irqsave(&erst_lock, flags); | ||
732 | if (erst_erange.attr & ERST_RANGE_NVRAM) | ||
733 | rc = __erst_clear_from_nvram(record_id); | ||
734 | else | ||
735 | rc = __erst_clear_from_storage(record_id); | ||
736 | spin_unlock_irqrestore(&erst_lock, flags); | ||
737 | |||
738 | return rc; | ||
739 | } | ||
740 | EXPORT_SYMBOL_GPL(erst_clear); | ||
741 | |||
742 | static int __init setup_erst_disable(char *str) | ||
743 | { | ||
744 | erst_disable = 1; | ||
745 | return 0; | ||
746 | } | ||
747 | |||
748 | __setup("erst_disable", setup_erst_disable); | ||
749 | |||
750 | static int erst_check_table(struct acpi_table_erst *erst_tab) | ||
751 | { | ||
752 | if (erst_tab->header_length != sizeof(struct acpi_table_erst)) | ||
753 | return -EINVAL; | ||
754 | if (erst_tab->header.length < sizeof(struct acpi_table_erst)) | ||
755 | return -EINVAL; | ||
756 | if (erst_tab->entries != | ||
757 | (erst_tab->header.length - sizeof(struct acpi_table_erst)) / | ||
758 | sizeof(struct acpi_erst_entry)) | ||
759 | return -EINVAL; | ||
760 | |||
761 | return 0; | ||
762 | } | ||
763 | |||
764 | static int __init erst_init(void) | ||
765 | { | ||
766 | int rc = 0; | ||
767 | acpi_status status; | ||
768 | struct apei_exec_context ctx; | ||
769 | struct apei_resources erst_resources; | ||
770 | struct resource *r; | ||
771 | |||
772 | if (acpi_disabled) | ||
773 | goto err; | ||
774 | |||
775 | if (erst_disable) { | ||
776 | pr_info(ERST_PFX | ||
777 | "Error Record Serialization Table (ERST) support is disabled.\n"); | ||
778 | goto err; | ||
779 | } | ||
780 | |||
781 | status = acpi_get_table(ACPI_SIG_ERST, 0, | ||
782 | (struct acpi_table_header **)&erst_tab); | ||
783 | if (status == AE_NOT_FOUND) { | ||
784 | pr_err(ERST_PFX "Table is not found!\n"); | ||
785 | goto err; | ||
786 | } else if (ACPI_FAILURE(status)) { | ||
787 | const char *msg = acpi_format_exception(status); | ||
788 | pr_err(ERST_PFX "Failed to get table, %s\n", msg); | ||
789 | rc = -EINVAL; | ||
790 | goto err; | ||
791 | } | ||
792 | |||
793 | rc = erst_check_table(erst_tab); | ||
794 | if (rc) { | ||
795 | pr_err(FW_BUG ERST_PFX "ERST table is invalid\n"); | ||
796 | goto err; | ||
797 | } | ||
798 | |||
799 | apei_resources_init(&erst_resources); | ||
800 | erst_exec_ctx_init(&ctx); | ||
801 | rc = apei_exec_collect_resources(&ctx, &erst_resources); | ||
802 | if (rc) | ||
803 | goto err_fini; | ||
804 | rc = apei_resources_request(&erst_resources, "APEI ERST"); | ||
805 | if (rc) | ||
806 | goto err_fini; | ||
807 | rc = apei_exec_pre_map_gars(&ctx); | ||
808 | if (rc) | ||
809 | goto err_release; | ||
810 | rc = erst_get_erange(&erst_erange); | ||
811 | if (rc) { | ||
812 | if (rc == -ENODEV) | ||
813 | pr_info(ERST_PFX | ||
814 | "The corresponding hardware device or firmware implementation " | ||
815 | "is not available.\n"); | ||
816 | else | ||
817 | pr_err(ERST_PFX | ||
818 | "Failed to get Error Log Address Range.\n"); | ||
819 | goto err_unmap_reg; | ||
820 | } | ||
821 | |||
822 | r = request_mem_region(erst_erange.base, erst_erange.size, "APEI ERST"); | ||
823 | if (!r) { | ||
824 | pr_err(ERST_PFX | ||
825 | "Can not request iomem region <0x%16llx-0x%16llx> for ERST.\n", | ||
826 | (unsigned long long)erst_erange.base, | ||
827 | (unsigned long long)erst_erange.base + erst_erange.size); | ||
828 | rc = -EIO; | ||
829 | goto err_unmap_reg; | ||
830 | } | ||
831 | rc = -ENOMEM; | ||
832 | erst_erange.vaddr = ioremap_cache(erst_erange.base, | ||
833 | erst_erange.size); | ||
834 | if (!erst_erange.vaddr) | ||
835 | goto err_release_erange; | ||
836 | |||
837 | pr_info(ERST_PFX | ||
838 | "Error Record Serialization Table (ERST) support is initialized.\n"); | ||
839 | |||
840 | return 0; | ||
841 | |||
842 | err_release_erange: | ||
843 | release_mem_region(erst_erange.base, erst_erange.size); | ||
844 | err_unmap_reg: | ||
845 | apei_exec_post_unmap_gars(&ctx); | ||
846 | err_release: | ||
847 | apei_resources_release(&erst_resources); | ||
848 | err_fini: | ||
849 | apei_resources_fini(&erst_resources); | ||
850 | err: | ||
851 | erst_disable = 1; | ||
852 | return rc; | ||
853 | } | ||
854 | |||
855 | device_initcall(erst_init); | ||
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c new file mode 100644 index 000000000000..fd0cc016a099 --- /dev/null +++ b/drivers/acpi/apei/ghes.c | |||
@@ -0,0 +1,427 @@ | |||
1 | /* | ||
2 | * APEI Generic Hardware Error Source support | ||
3 | * | ||
4 | * Generic Hardware Error Source provides a way to report platform | ||
5 | * hardware errors (such as that from chipset). It works in so called | ||
6 | * "Firmware First" mode, that is, hardware errors are reported to | ||
7 | * firmware firstly, then reported to Linux by firmware. This way, | ||
8 | * some non-standard hardware error registers or non-standard hardware | ||
9 | * link can be checked by firmware to produce more hardware error | ||
10 | * information for Linux. | ||
11 | * | ||
12 | * For more information about Generic Hardware Error Source, please | ||
13 | * refer to ACPI Specification version 4.0, section 17.3.2.6 | ||
14 | * | ||
15 | * Now, only SCI notification type and memory errors are | ||
16 | * supported. More notification type and hardware error type will be | ||
17 | * added later. | ||
18 | * | ||
19 | * Copyright 2010 Intel Corp. | ||
20 | * Author: Huang Ying <ying.huang@intel.com> | ||
21 | * | ||
22 | * This program is free software; you can redistribute it and/or | ||
23 | * modify it under the terms of the GNU General Public License version | ||
24 | * 2 as published by the Free Software Foundation; | ||
25 | * | ||
26 | * This program is distributed in the hope that it will be useful, | ||
27 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
28 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
29 | * GNU General Public License for more details. | ||
30 | * | ||
31 | * You should have received a copy of the GNU General Public License | ||
32 | * along with this program; if not, write to the Free Software | ||
33 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
34 | */ | ||
35 | |||
36 | #include <linux/kernel.h> | ||
37 | #include <linux/module.h> | ||
38 | #include <linux/init.h> | ||
39 | #include <linux/acpi.h> | ||
40 | #include <linux/io.h> | ||
41 | #include <linux/interrupt.h> | ||
42 | #include <linux/cper.h> | ||
43 | #include <linux/kdebug.h> | ||
44 | #include <acpi/apei.h> | ||
45 | #include <acpi/atomicio.h> | ||
46 | #include <acpi/hed.h> | ||
47 | #include <asm/mce.h> | ||
48 | |||
49 | #include "apei-internal.h" | ||
50 | |||
51 | #define GHES_PFX "GHES: " | ||
52 | |||
53 | #define GHES_ESTATUS_MAX_SIZE 65536 | ||
54 | |||
55 | /* | ||
56 | * One struct ghes is created for each generic hardware error | ||
57 | * source. | ||
58 | * | ||
59 | * It provides the context for APEI hardware error timer/IRQ/SCI/NMI | ||
60 | * handler. Handler for one generic hardware error source is only | ||
61 | * triggered after the previous one is done. So handler can uses | ||
62 | * struct ghes without locking. | ||
63 | * | ||
64 | * estatus: memory buffer for error status block, allocated during | ||
65 | * HEST parsing. | ||
66 | */ | ||
67 | #define GHES_TO_CLEAR 0x0001 | ||
68 | |||
69 | struct ghes { | ||
70 | struct acpi_hest_generic *generic; | ||
71 | struct acpi_hest_generic_status *estatus; | ||
72 | struct list_head list; | ||
73 | u64 buffer_paddr; | ||
74 | unsigned long flags; | ||
75 | }; | ||
76 | |||
77 | /* | ||
78 | * Error source lists, one list for each notification method. The | ||
79 | * members in lists are struct ghes. | ||
80 | * | ||
81 | * The list members are only added in HEST parsing and deleted during | ||
82 | * module_exit, that is, single-threaded. So no lock is needed for | ||
83 | * that. | ||
84 | * | ||
85 | * But the mutual exclusion is needed between members adding/deleting | ||
86 | * and timer/IRQ/SCI/NMI handler, which may traverse the list. RCU is | ||
87 | * used for that. | ||
88 | */ | ||
89 | static LIST_HEAD(ghes_sci); | ||
90 | |||
91 | static struct ghes *ghes_new(struct acpi_hest_generic *generic) | ||
92 | { | ||
93 | struct ghes *ghes; | ||
94 | unsigned int error_block_length; | ||
95 | int rc; | ||
96 | |||
97 | ghes = kzalloc(sizeof(*ghes), GFP_KERNEL); | ||
98 | if (!ghes) | ||
99 | return ERR_PTR(-ENOMEM); | ||
100 | ghes->generic = generic; | ||
101 | INIT_LIST_HEAD(&ghes->list); | ||
102 | rc = acpi_pre_map_gar(&generic->error_status_address); | ||
103 | if (rc) | ||
104 | goto err_free; | ||
105 | error_block_length = generic->error_block_length; | ||
106 | if (error_block_length > GHES_ESTATUS_MAX_SIZE) { | ||
107 | pr_warning(FW_WARN GHES_PFX | ||
108 | "Error status block length is too long: %u for " | ||
109 | "generic hardware error source: %d.\n", | ||
110 | error_block_length, generic->header.source_id); | ||
111 | error_block_length = GHES_ESTATUS_MAX_SIZE; | ||
112 | } | ||
113 | ghes->estatus = kmalloc(error_block_length, GFP_KERNEL); | ||
114 | if (!ghes->estatus) { | ||
115 | rc = -ENOMEM; | ||
116 | goto err_unmap; | ||
117 | } | ||
118 | |||
119 | return ghes; | ||
120 | |||
121 | err_unmap: | ||
122 | acpi_post_unmap_gar(&generic->error_status_address); | ||
123 | err_free: | ||
124 | kfree(ghes); | ||
125 | return ERR_PTR(rc); | ||
126 | } | ||
127 | |||
128 | static void ghes_fini(struct ghes *ghes) | ||
129 | { | ||
130 | kfree(ghes->estatus); | ||
131 | acpi_post_unmap_gar(&ghes->generic->error_status_address); | ||
132 | } | ||
133 | |||
134 | enum { | ||
135 | GHES_SER_NO = 0x0, | ||
136 | GHES_SER_CORRECTED = 0x1, | ||
137 | GHES_SER_RECOVERABLE = 0x2, | ||
138 | GHES_SER_PANIC = 0x3, | ||
139 | }; | ||
140 | |||
141 | static inline int ghes_severity(int severity) | ||
142 | { | ||
143 | switch (severity) { | ||
144 | case CPER_SER_INFORMATIONAL: | ||
145 | return GHES_SER_NO; | ||
146 | case CPER_SER_CORRECTED: | ||
147 | return GHES_SER_CORRECTED; | ||
148 | case CPER_SER_RECOVERABLE: | ||
149 | return GHES_SER_RECOVERABLE; | ||
150 | case CPER_SER_FATAL: | ||
151 | return GHES_SER_PANIC; | ||
152 | default: | ||
153 | /* Unkown, go panic */ | ||
154 | return GHES_SER_PANIC; | ||
155 | } | ||
156 | } | ||
157 | |||
158 | /* SCI handler run in work queue, so ioremap can be used here */ | ||
159 | static int ghes_copy_tofrom_phys(void *buffer, u64 paddr, u32 len, | ||
160 | int from_phys) | ||
161 | { | ||
162 | void *vaddr; | ||
163 | |||
164 | vaddr = ioremap_cache(paddr, len); | ||
165 | if (!vaddr) | ||
166 | return -ENOMEM; | ||
167 | if (from_phys) | ||
168 | memcpy(buffer, vaddr, len); | ||
169 | else | ||
170 | memcpy(vaddr, buffer, len); | ||
171 | iounmap(vaddr); | ||
172 | |||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | static int ghes_read_estatus(struct ghes *ghes, int silent) | ||
177 | { | ||
178 | struct acpi_hest_generic *g = ghes->generic; | ||
179 | u64 buf_paddr; | ||
180 | u32 len; | ||
181 | int rc; | ||
182 | |||
183 | rc = acpi_atomic_read(&buf_paddr, &g->error_status_address); | ||
184 | if (rc) { | ||
185 | if (!silent && printk_ratelimit()) | ||
186 | pr_warning(FW_WARN GHES_PFX | ||
187 | "Failed to read error status block address for hardware error source: %d.\n", | ||
188 | g->header.source_id); | ||
189 | return -EIO; | ||
190 | } | ||
191 | if (!buf_paddr) | ||
192 | return -ENOENT; | ||
193 | |||
194 | rc = ghes_copy_tofrom_phys(ghes->estatus, buf_paddr, | ||
195 | sizeof(*ghes->estatus), 1); | ||
196 | if (rc) | ||
197 | return rc; | ||
198 | if (!ghes->estatus->block_status) | ||
199 | return -ENOENT; | ||
200 | |||
201 | ghes->buffer_paddr = buf_paddr; | ||
202 | ghes->flags |= GHES_TO_CLEAR; | ||
203 | |||
204 | rc = -EIO; | ||
205 | len = apei_estatus_len(ghes->estatus); | ||
206 | if (len < sizeof(*ghes->estatus)) | ||
207 | goto err_read_block; | ||
208 | if (len > ghes->generic->error_block_length) | ||
209 | goto err_read_block; | ||
210 | if (apei_estatus_check_header(ghes->estatus)) | ||
211 | goto err_read_block; | ||
212 | rc = ghes_copy_tofrom_phys(ghes->estatus + 1, | ||
213 | buf_paddr + sizeof(*ghes->estatus), | ||
214 | len - sizeof(*ghes->estatus), 1); | ||
215 | if (rc) | ||
216 | return rc; | ||
217 | if (apei_estatus_check(ghes->estatus)) | ||
218 | goto err_read_block; | ||
219 | rc = 0; | ||
220 | |||
221 | err_read_block: | ||
222 | if (rc && !silent) | ||
223 | pr_warning(FW_WARN GHES_PFX | ||
224 | "Failed to read error status block!\n"); | ||
225 | return rc; | ||
226 | } | ||
227 | |||
228 | static void ghes_clear_estatus(struct ghes *ghes) | ||
229 | { | ||
230 | ghes->estatus->block_status = 0; | ||
231 | if (!(ghes->flags & GHES_TO_CLEAR)) | ||
232 | return; | ||
233 | ghes_copy_tofrom_phys(ghes->estatus, ghes->buffer_paddr, | ||
234 | sizeof(ghes->estatus->block_status), 0); | ||
235 | ghes->flags &= ~GHES_TO_CLEAR; | ||
236 | } | ||
237 | |||
238 | static void ghes_do_proc(struct ghes *ghes) | ||
239 | { | ||
240 | int ser, processed = 0; | ||
241 | struct acpi_hest_generic_data *gdata; | ||
242 | |||
243 | ser = ghes_severity(ghes->estatus->error_severity); | ||
244 | apei_estatus_for_each_section(ghes->estatus, gdata) { | ||
245 | #ifdef CONFIG_X86_MCE | ||
246 | if (!uuid_le_cmp(*(uuid_le *)gdata->section_type, | ||
247 | CPER_SEC_PLATFORM_MEM)) { | ||
248 | apei_mce_report_mem_error( | ||
249 | ser == GHES_SER_CORRECTED, | ||
250 | (struct cper_sec_mem_err *)(gdata+1)); | ||
251 | processed = 1; | ||
252 | } | ||
253 | #endif | ||
254 | } | ||
255 | |||
256 | if (!processed && printk_ratelimit()) | ||
257 | pr_warning(GHES_PFX | ||
258 | "Unknown error record from generic hardware error source: %d\n", | ||
259 | ghes->generic->header.source_id); | ||
260 | } | ||
261 | |||
262 | static int ghes_proc(struct ghes *ghes) | ||
263 | { | ||
264 | int rc; | ||
265 | |||
266 | rc = ghes_read_estatus(ghes, 0); | ||
267 | if (rc) | ||
268 | goto out; | ||
269 | ghes_do_proc(ghes); | ||
270 | |||
271 | out: | ||
272 | ghes_clear_estatus(ghes); | ||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | static int ghes_notify_sci(struct notifier_block *this, | ||
277 | unsigned long event, void *data) | ||
278 | { | ||
279 | struct ghes *ghes; | ||
280 | int ret = NOTIFY_DONE; | ||
281 | |||
282 | rcu_read_lock(); | ||
283 | list_for_each_entry_rcu(ghes, &ghes_sci, list) { | ||
284 | if (!ghes_proc(ghes)) | ||
285 | ret = NOTIFY_OK; | ||
286 | } | ||
287 | rcu_read_unlock(); | ||
288 | |||
289 | return ret; | ||
290 | } | ||
291 | |||
292 | static struct notifier_block ghes_notifier_sci = { | ||
293 | .notifier_call = ghes_notify_sci, | ||
294 | }; | ||
295 | |||
296 | static int hest_ghes_parse(struct acpi_hest_header *hest_hdr, void *data) | ||
297 | { | ||
298 | struct acpi_hest_generic *generic; | ||
299 | struct ghes *ghes = NULL; | ||
300 | int rc = 0; | ||
301 | |||
302 | if (hest_hdr->type != ACPI_HEST_TYPE_GENERIC_ERROR) | ||
303 | return 0; | ||
304 | |||
305 | generic = (struct acpi_hest_generic *)hest_hdr; | ||
306 | if (!generic->enabled) | ||
307 | return 0; | ||
308 | |||
309 | if (generic->error_block_length < | ||
310 | sizeof(struct acpi_hest_generic_status)) { | ||
311 | pr_warning(FW_BUG GHES_PFX | ||
312 | "Invalid error block length: %u for generic hardware error source: %d\n", | ||
313 | generic->error_block_length, | ||
314 | generic->header.source_id); | ||
315 | goto err; | ||
316 | } | ||
317 | if (generic->records_to_preallocate == 0) { | ||
318 | pr_warning(FW_BUG GHES_PFX | ||
319 | "Invalid records to preallocate: %u for generic hardware error source: %d\n", | ||
320 | generic->records_to_preallocate, | ||
321 | generic->header.source_id); | ||
322 | goto err; | ||
323 | } | ||
324 | ghes = ghes_new(generic); | ||
325 | if (IS_ERR(ghes)) { | ||
326 | rc = PTR_ERR(ghes); | ||
327 | ghes = NULL; | ||
328 | goto err; | ||
329 | } | ||
330 | switch (generic->notify.type) { | ||
331 | case ACPI_HEST_NOTIFY_POLLED: | ||
332 | pr_warning(GHES_PFX | ||
333 | "Generic hardware error source: %d notified via POLL is not supported!\n", | ||
334 | generic->header.source_id); | ||
335 | break; | ||
336 | case ACPI_HEST_NOTIFY_EXTERNAL: | ||
337 | case ACPI_HEST_NOTIFY_LOCAL: | ||
338 | pr_warning(GHES_PFX | ||
339 | "Generic hardware error source: %d notified via IRQ is not supported!\n", | ||
340 | generic->header.source_id); | ||
341 | break; | ||
342 | case ACPI_HEST_NOTIFY_SCI: | ||
343 | if (list_empty(&ghes_sci)) | ||
344 | register_acpi_hed_notifier(&ghes_notifier_sci); | ||
345 | list_add_rcu(&ghes->list, &ghes_sci); | ||
346 | break; | ||
347 | case ACPI_HEST_NOTIFY_NMI: | ||
348 | pr_warning(GHES_PFX | ||
349 | "Generic hardware error source: %d notified via NMI is not supported!\n", | ||
350 | generic->header.source_id); | ||
351 | break; | ||
352 | default: | ||
353 | pr_warning(FW_WARN GHES_PFX | ||
354 | "Unknown notification type: %u for generic hardware error source: %d\n", | ||
355 | generic->notify.type, generic->header.source_id); | ||
356 | break; | ||
357 | } | ||
358 | |||
359 | return 0; | ||
360 | err: | ||
361 | if (ghes) | ||
362 | ghes_fini(ghes); | ||
363 | return rc; | ||
364 | } | ||
365 | |||
366 | static void ghes_cleanup(void) | ||
367 | { | ||
368 | struct ghes *ghes, *nghes; | ||
369 | |||
370 | if (!list_empty(&ghes_sci)) | ||
371 | unregister_acpi_hed_notifier(&ghes_notifier_sci); | ||
372 | |||
373 | synchronize_rcu(); | ||
374 | |||
375 | list_for_each_entry_safe(ghes, nghes, &ghes_sci, list) { | ||
376 | list_del(&ghes->list); | ||
377 | ghes_fini(ghes); | ||
378 | kfree(ghes); | ||
379 | } | ||
380 | } | ||
381 | |||
382 | static int __init ghes_init(void) | ||
383 | { | ||
384 | int rc; | ||
385 | |||
386 | if (acpi_disabled) | ||
387 | return -ENODEV; | ||
388 | |||
389 | if (hest_disable) { | ||
390 | pr_info(GHES_PFX "HEST is not enabled!\n"); | ||
391 | return -EINVAL; | ||
392 | } | ||
393 | |||
394 | rc = apei_hest_parse(hest_ghes_parse, NULL); | ||
395 | if (rc) { | ||
396 | pr_err(GHES_PFX | ||
397 | "Error during parsing HEST generic hardware error sources.\n"); | ||
398 | goto err_cleanup; | ||
399 | } | ||
400 | |||
401 | if (list_empty(&ghes_sci)) { | ||
402 | pr_info(GHES_PFX | ||
403 | "No functional generic hardware error sources.\n"); | ||
404 | rc = -ENODEV; | ||
405 | goto err_cleanup; | ||
406 | } | ||
407 | |||
408 | pr_info(GHES_PFX | ||
409 | "Generic Hardware Error Source support is initialized.\n"); | ||
410 | |||
411 | return 0; | ||
412 | err_cleanup: | ||
413 | ghes_cleanup(); | ||
414 | return rc; | ||
415 | } | ||
416 | |||
417 | static void __exit ghes_exit(void) | ||
418 | { | ||
419 | ghes_cleanup(); | ||
420 | } | ||
421 | |||
422 | module_init(ghes_init); | ||
423 | module_exit(ghes_exit); | ||
424 | |||
425 | MODULE_AUTHOR("Huang Ying"); | ||
426 | MODULE_DESCRIPTION("APEI Generic Hardware Error Source support"); | ||
427 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c new file mode 100644 index 000000000000..e7f40d362cb3 --- /dev/null +++ b/drivers/acpi/apei/hest.c | |||
@@ -0,0 +1,173 @@ | |||
1 | /* | ||
2 | * APEI Hardware Error Souce Table support | ||
3 | * | ||
4 | * HEST describes error sources in detail; communicates operational | ||
5 | * parameters (i.e. severity levels, masking bits, and threshold | ||
6 | * values) to Linux as necessary. It also allows the BIOS to report | ||
7 | * non-standard error sources to Linux (for example, chipset-specific | ||
8 | * error registers). | ||
9 | * | ||
10 | * For more information about HEST, please refer to ACPI Specification | ||
11 | * version 4.0, section 17.3.2. | ||
12 | * | ||
13 | * Copyright 2009 Intel Corp. | ||
14 | * Author: Huang Ying <ying.huang@intel.com> | ||
15 | * | ||
16 | * This program is free software; you can redistribute it and/or | ||
17 | * modify it under the terms of the GNU General Public License version | ||
18 | * 2 as published by the Free Software Foundation; | ||
19 | * | ||
20 | * This program is distributed in the hope that it will be useful, | ||
21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
23 | * GNU General Public License for more details. | ||
24 | * | ||
25 | * You should have received a copy of the GNU General Public License | ||
26 | * along with this program; if not, write to the Free Software | ||
27 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
28 | */ | ||
29 | |||
30 | #include <linux/kernel.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/init.h> | ||
33 | #include <linux/acpi.h> | ||
34 | #include <linux/kdebug.h> | ||
35 | #include <linux/highmem.h> | ||
36 | #include <linux/io.h> | ||
37 | #include <acpi/apei.h> | ||
38 | |||
39 | #include "apei-internal.h" | ||
40 | |||
41 | #define HEST_PFX "HEST: " | ||
42 | |||
43 | int hest_disable; | ||
44 | EXPORT_SYMBOL_GPL(hest_disable); | ||
45 | |||
46 | /* HEST table parsing */ | ||
47 | |||
48 | static struct acpi_table_hest *hest_tab; | ||
49 | |||
50 | static int hest_void_parse(struct acpi_hest_header *hest_hdr, void *data) | ||
51 | { | ||
52 | return 0; | ||
53 | } | ||
54 | |||
55 | static int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = { | ||
56 | [ACPI_HEST_TYPE_IA32_CHECK] = -1, /* need further calculation */ | ||
57 | [ACPI_HEST_TYPE_IA32_CORRECTED_CHECK] = -1, | ||
58 | [ACPI_HEST_TYPE_IA32_NMI] = sizeof(struct acpi_hest_ia_nmi), | ||
59 | [ACPI_HEST_TYPE_AER_ROOT_PORT] = sizeof(struct acpi_hest_aer_root), | ||
60 | [ACPI_HEST_TYPE_AER_ENDPOINT] = sizeof(struct acpi_hest_aer), | ||
61 | [ACPI_HEST_TYPE_AER_BRIDGE] = sizeof(struct acpi_hest_aer_bridge), | ||
62 | [ACPI_HEST_TYPE_GENERIC_ERROR] = sizeof(struct acpi_hest_generic), | ||
63 | }; | ||
64 | |||
65 | static int hest_esrc_len(struct acpi_hest_header *hest_hdr) | ||
66 | { | ||
67 | u16 hest_type = hest_hdr->type; | ||
68 | int len; | ||
69 | |||
70 | if (hest_type >= ACPI_HEST_TYPE_RESERVED) | ||
71 | return 0; | ||
72 | |||
73 | len = hest_esrc_len_tab[hest_type]; | ||
74 | |||
75 | if (hest_type == ACPI_HEST_TYPE_IA32_CORRECTED_CHECK) { | ||
76 | struct acpi_hest_ia_corrected *cmc; | ||
77 | cmc = (struct acpi_hest_ia_corrected *)hest_hdr; | ||
78 | len = sizeof(*cmc) + cmc->num_hardware_banks * | ||
79 | sizeof(struct acpi_hest_ia_error_bank); | ||
80 | } else if (hest_type == ACPI_HEST_TYPE_IA32_CHECK) { | ||
81 | struct acpi_hest_ia_machine_check *mc; | ||
82 | mc = (struct acpi_hest_ia_machine_check *)hest_hdr; | ||
83 | len = sizeof(*mc) + mc->num_hardware_banks * | ||
84 | sizeof(struct acpi_hest_ia_error_bank); | ||
85 | } | ||
86 | BUG_ON(len == -1); | ||
87 | |||
88 | return len; | ||
89 | }; | ||
90 | |||
91 | int apei_hest_parse(apei_hest_func_t func, void *data) | ||
92 | { | ||
93 | struct acpi_hest_header *hest_hdr; | ||
94 | int i, rc, len; | ||
95 | |||
96 | if (hest_disable) | ||
97 | return -EINVAL; | ||
98 | |||
99 | hest_hdr = (struct acpi_hest_header *)(hest_tab + 1); | ||
100 | for (i = 0; i < hest_tab->error_source_count; i++) { | ||
101 | len = hest_esrc_len(hest_hdr); | ||
102 | if (!len) { | ||
103 | pr_warning(FW_WARN HEST_PFX | ||
104 | "Unknown or unused hardware error source " | ||
105 | "type: %d for hardware error source: %d.\n", | ||
106 | hest_hdr->type, hest_hdr->source_id); | ||
107 | return -EINVAL; | ||
108 | } | ||
109 | if ((void *)hest_hdr + len > | ||
110 | (void *)hest_tab + hest_tab->header.length) { | ||
111 | pr_warning(FW_BUG HEST_PFX | ||
112 | "Table contents overflow for hardware error source: %d.\n", | ||
113 | hest_hdr->source_id); | ||
114 | return -EINVAL; | ||
115 | } | ||
116 | |||
117 | rc = func(hest_hdr, data); | ||
118 | if (rc) | ||
119 | return rc; | ||
120 | |||
121 | hest_hdr = (void *)hest_hdr + len; | ||
122 | } | ||
123 | |||
124 | return 0; | ||
125 | } | ||
126 | EXPORT_SYMBOL_GPL(apei_hest_parse); | ||
127 | |||
128 | static int __init setup_hest_disable(char *str) | ||
129 | { | ||
130 | hest_disable = 1; | ||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | __setup("hest_disable", setup_hest_disable); | ||
135 | |||
136 | static int __init hest_init(void) | ||
137 | { | ||
138 | acpi_status status; | ||
139 | int rc = -ENODEV; | ||
140 | |||
141 | if (acpi_disabled) | ||
142 | goto err; | ||
143 | |||
144 | if (hest_disable) { | ||
145 | pr_info(HEST_PFX "HEST tabling parsing is disabled.\n"); | ||
146 | goto err; | ||
147 | } | ||
148 | |||
149 | status = acpi_get_table(ACPI_SIG_HEST, 0, | ||
150 | (struct acpi_table_header **)&hest_tab); | ||
151 | if (status == AE_NOT_FOUND) { | ||
152 | pr_info(HEST_PFX "Table is not found!\n"); | ||
153 | goto err; | ||
154 | } else if (ACPI_FAILURE(status)) { | ||
155 | const char *msg = acpi_format_exception(status); | ||
156 | pr_err(HEST_PFX "Failed to get table, %s\n", msg); | ||
157 | rc = -EINVAL; | ||
158 | goto err; | ||
159 | } | ||
160 | |||
161 | rc = apei_hest_parse(hest_void_parse, NULL); | ||
162 | if (rc) | ||
163 | goto err; | ||
164 | |||
165 | pr_info(HEST_PFX "HEST table parsing is initialized.\n"); | ||
166 | |||
167 | return 0; | ||
168 | err: | ||
169 | hest_disable = 1; | ||
170 | return rc; | ||
171 | } | ||
172 | |||
173 | subsys_initcall(hest_init); | ||
diff --git a/drivers/acpi/atomicio.c b/drivers/acpi/atomicio.c new file mode 100644 index 000000000000..814b19249616 --- /dev/null +++ b/drivers/acpi/atomicio.c | |||
@@ -0,0 +1,360 @@ | |||
1 | /* | ||
2 | * atomicio.c - ACPI IO memory pre-mapping/post-unmapping, then | ||
3 | * accessing in atomic context. | ||
4 | * | ||
5 | * This is used for NMI handler to access IO memory area, because | ||
6 | * ioremap/iounmap can not be used in NMI handler. The IO memory area | ||
7 | * is pre-mapped in process context and accessed in NMI handler. | ||
8 | * | ||
9 | * Copyright (C) 2009-2010, Intel Corp. | ||
10 | * Author: Huang Ying <ying.huang@intel.com> | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License version | ||
14 | * 2 as published by the Free Software Foundation. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
24 | */ | ||
25 | |||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/module.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/acpi.h> | ||
30 | #include <linux/io.h> | ||
31 | #include <linux/kref.h> | ||
32 | #include <linux/rculist.h> | ||
33 | #include <linux/interrupt.h> | ||
34 | #include <acpi/atomicio.h> | ||
35 | |||
36 | #define ACPI_PFX "ACPI: " | ||
37 | |||
38 | static LIST_HEAD(acpi_iomaps); | ||
39 | /* | ||
40 | * Used for mutual exclusion between writers of acpi_iomaps list, for | ||
41 | * synchronization between readers and writer, RCU is used. | ||
42 | */ | ||
43 | static DEFINE_SPINLOCK(acpi_iomaps_lock); | ||
44 | |||
45 | struct acpi_iomap { | ||
46 | struct list_head list; | ||
47 | void __iomem *vaddr; | ||
48 | unsigned long size; | ||
49 | phys_addr_t paddr; | ||
50 | struct kref ref; | ||
51 | }; | ||
52 | |||
53 | /* acpi_iomaps_lock or RCU read lock must be held before calling */ | ||
54 | static struct acpi_iomap *__acpi_find_iomap(phys_addr_t paddr, | ||
55 | unsigned long size) | ||
56 | { | ||
57 | struct acpi_iomap *map; | ||
58 | |||
59 | list_for_each_entry_rcu(map, &acpi_iomaps, list) { | ||
60 | if (map->paddr + map->size >= paddr + size && | ||
61 | map->paddr <= paddr) | ||
62 | return map; | ||
63 | } | ||
64 | return NULL; | ||
65 | } | ||
66 | |||
67 | /* | ||
68 | * Atomic "ioremap" used by NMI handler, if the specified IO memory | ||
69 | * area is not pre-mapped, NULL will be returned. | ||
70 | * | ||
71 | * acpi_iomaps_lock or RCU read lock must be held before calling | ||
72 | */ | ||
73 | static void __iomem *__acpi_ioremap_fast(phys_addr_t paddr, | ||
74 | unsigned long size) | ||
75 | { | ||
76 | struct acpi_iomap *map; | ||
77 | |||
78 | map = __acpi_find_iomap(paddr, size); | ||
79 | if (map) | ||
80 | return map->vaddr + (paddr - map->paddr); | ||
81 | else | ||
82 | return NULL; | ||
83 | } | ||
84 | |||
85 | /* acpi_iomaps_lock must be held before calling */ | ||
86 | static void __iomem *__acpi_try_ioremap(phys_addr_t paddr, | ||
87 | unsigned long size) | ||
88 | { | ||
89 | struct acpi_iomap *map; | ||
90 | |||
91 | map = __acpi_find_iomap(paddr, size); | ||
92 | if (map) { | ||
93 | kref_get(&map->ref); | ||
94 | return map->vaddr + (paddr - map->paddr); | ||
95 | } else | ||
96 | return NULL; | ||
97 | } | ||
98 | |||
99 | /* | ||
100 | * Used to pre-map the specified IO memory area. First try to find | ||
101 | * whether the area is already pre-mapped, if it is, increase the | ||
102 | * reference count (in __acpi_try_ioremap) and return; otherwise, do | ||
103 | * the real ioremap, and add the mapping into acpi_iomaps list. | ||
104 | */ | ||
105 | static void __iomem *acpi_pre_map(phys_addr_t paddr, | ||
106 | unsigned long size) | ||
107 | { | ||
108 | void __iomem *vaddr; | ||
109 | struct acpi_iomap *map; | ||
110 | unsigned long pg_sz, flags; | ||
111 | phys_addr_t pg_off; | ||
112 | |||
113 | spin_lock_irqsave(&acpi_iomaps_lock, flags); | ||
114 | vaddr = __acpi_try_ioremap(paddr, size); | ||
115 | spin_unlock_irqrestore(&acpi_iomaps_lock, flags); | ||
116 | if (vaddr) | ||
117 | return vaddr; | ||
118 | |||
119 | pg_off = paddr & PAGE_MASK; | ||
120 | pg_sz = ((paddr + size + PAGE_SIZE - 1) & PAGE_MASK) - pg_off; | ||
121 | vaddr = ioremap(pg_off, pg_sz); | ||
122 | if (!vaddr) | ||
123 | return NULL; | ||
124 | map = kmalloc(sizeof(*map), GFP_KERNEL); | ||
125 | if (!map) | ||
126 | goto err_unmap; | ||
127 | INIT_LIST_HEAD(&map->list); | ||
128 | map->paddr = pg_off; | ||
129 | map->size = pg_sz; | ||
130 | map->vaddr = vaddr; | ||
131 | kref_init(&map->ref); | ||
132 | |||
133 | spin_lock_irqsave(&acpi_iomaps_lock, flags); | ||
134 | vaddr = __acpi_try_ioremap(paddr, size); | ||
135 | if (vaddr) { | ||
136 | spin_unlock_irqrestore(&acpi_iomaps_lock, flags); | ||
137 | iounmap(map->vaddr); | ||
138 | kfree(map); | ||
139 | return vaddr; | ||
140 | } | ||
141 | list_add_tail_rcu(&map->list, &acpi_iomaps); | ||
142 | spin_unlock_irqrestore(&acpi_iomaps_lock, flags); | ||
143 | |||
144 | return vaddr + (paddr - pg_off); | ||
145 | err_unmap: | ||
146 | iounmap(vaddr); | ||
147 | return NULL; | ||
148 | } | ||
149 | |||
150 | /* acpi_iomaps_lock must be held before calling */ | ||
151 | static void __acpi_kref_del_iomap(struct kref *ref) | ||
152 | { | ||
153 | struct acpi_iomap *map; | ||
154 | |||
155 | map = container_of(ref, struct acpi_iomap, ref); | ||
156 | list_del_rcu(&map->list); | ||
157 | } | ||
158 | |||
159 | /* | ||
160 | * Used to post-unmap the specified IO memory area. The iounmap is | ||
161 | * done only if the reference count goes zero. | ||
162 | */ | ||
163 | static void acpi_post_unmap(phys_addr_t paddr, unsigned long size) | ||
164 | { | ||
165 | struct acpi_iomap *map; | ||
166 | unsigned long flags; | ||
167 | int del; | ||
168 | |||
169 | spin_lock_irqsave(&acpi_iomaps_lock, flags); | ||
170 | map = __acpi_find_iomap(paddr, size); | ||
171 | BUG_ON(!map); | ||
172 | del = kref_put(&map->ref, __acpi_kref_del_iomap); | ||
173 | spin_unlock_irqrestore(&acpi_iomaps_lock, flags); | ||
174 | |||
175 | if (!del) | ||
176 | return; | ||
177 | |||
178 | synchronize_rcu(); | ||
179 | iounmap(map->vaddr); | ||
180 | kfree(map); | ||
181 | } | ||
182 | |||
183 | /* In NMI handler, should set silent = 1 */ | ||
184 | static int acpi_check_gar(struct acpi_generic_address *reg, | ||
185 | u64 *paddr, int silent) | ||
186 | { | ||
187 | u32 width, space_id; | ||
188 | |||
189 | width = reg->bit_width; | ||
190 | space_id = reg->space_id; | ||
191 | /* Handle possible alignment issues */ | ||
192 | memcpy(paddr, ®->address, sizeof(*paddr)); | ||
193 | if (!*paddr) { | ||
194 | if (!silent) | ||
195 | pr_warning(FW_BUG ACPI_PFX | ||
196 | "Invalid physical address in GAR [0x%llx/%u/%u]\n", | ||
197 | *paddr, width, space_id); | ||
198 | return -EINVAL; | ||
199 | } | ||
200 | |||
201 | if ((width != 8) && (width != 16) && (width != 32) && (width != 64)) { | ||
202 | if (!silent) | ||
203 | pr_warning(FW_BUG ACPI_PFX | ||
204 | "Invalid bit width in GAR [0x%llx/%u/%u]\n", | ||
205 | *paddr, width, space_id); | ||
206 | return -EINVAL; | ||
207 | } | ||
208 | |||
209 | if (space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY && | ||
210 | space_id != ACPI_ADR_SPACE_SYSTEM_IO) { | ||
211 | if (!silent) | ||
212 | pr_warning(FW_BUG ACPI_PFX | ||
213 | "Invalid address space type in GAR [0x%llx/%u/%u]\n", | ||
214 | *paddr, width, space_id); | ||
215 | return -EINVAL; | ||
216 | } | ||
217 | |||
218 | return 0; | ||
219 | } | ||
220 | |||
221 | /* Pre-map, working on GAR */ | ||
222 | int acpi_pre_map_gar(struct acpi_generic_address *reg) | ||
223 | { | ||
224 | u64 paddr; | ||
225 | void __iomem *vaddr; | ||
226 | int rc; | ||
227 | |||
228 | if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) | ||
229 | return 0; | ||
230 | |||
231 | rc = acpi_check_gar(reg, &paddr, 0); | ||
232 | if (rc) | ||
233 | return rc; | ||
234 | |||
235 | vaddr = acpi_pre_map(paddr, reg->bit_width / 8); | ||
236 | if (!vaddr) | ||
237 | return -EIO; | ||
238 | |||
239 | return 0; | ||
240 | } | ||
241 | EXPORT_SYMBOL_GPL(acpi_pre_map_gar); | ||
242 | |||
243 | /* Post-unmap, working on GAR */ | ||
244 | int acpi_post_unmap_gar(struct acpi_generic_address *reg) | ||
245 | { | ||
246 | u64 paddr; | ||
247 | int rc; | ||
248 | |||
249 | if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) | ||
250 | return 0; | ||
251 | |||
252 | rc = acpi_check_gar(reg, &paddr, 0); | ||
253 | if (rc) | ||
254 | return rc; | ||
255 | |||
256 | acpi_post_unmap(paddr, reg->bit_width / 8); | ||
257 | |||
258 | return 0; | ||
259 | } | ||
260 | EXPORT_SYMBOL_GPL(acpi_post_unmap_gar); | ||
261 | |||
262 | /* | ||
263 | * Can be used in atomic (including NMI) or process context. RCU read | ||
264 | * lock can only be released after the IO memory area accessing. | ||
265 | */ | ||
266 | static int acpi_atomic_read_mem(u64 paddr, u64 *val, u32 width) | ||
267 | { | ||
268 | void __iomem *addr; | ||
269 | |||
270 | rcu_read_lock(); | ||
271 | addr = __acpi_ioremap_fast(paddr, width); | ||
272 | switch (width) { | ||
273 | case 8: | ||
274 | *val = readb(addr); | ||
275 | break; | ||
276 | case 16: | ||
277 | *val = readw(addr); | ||
278 | break; | ||
279 | case 32: | ||
280 | *val = readl(addr); | ||
281 | break; | ||
282 | case 64: | ||
283 | *val = readq(addr); | ||
284 | break; | ||
285 | default: | ||
286 | return -EINVAL; | ||
287 | } | ||
288 | rcu_read_unlock(); | ||
289 | |||
290 | return 0; | ||
291 | } | ||
292 | |||
293 | static int acpi_atomic_write_mem(u64 paddr, u64 val, u32 width) | ||
294 | { | ||
295 | void __iomem *addr; | ||
296 | |||
297 | rcu_read_lock(); | ||
298 | addr = __acpi_ioremap_fast(paddr, width); | ||
299 | switch (width) { | ||
300 | case 8: | ||
301 | writeb(val, addr); | ||
302 | break; | ||
303 | case 16: | ||
304 | writew(val, addr); | ||
305 | break; | ||
306 | case 32: | ||
307 | writel(val, addr); | ||
308 | break; | ||
309 | case 64: | ||
310 | writeq(val, addr); | ||
311 | break; | ||
312 | default: | ||
313 | return -EINVAL; | ||
314 | } | ||
315 | rcu_read_unlock(); | ||
316 | |||
317 | return 0; | ||
318 | } | ||
319 | |||
320 | /* GAR accessing in atomic (including NMI) or process context */ | ||
321 | int acpi_atomic_read(u64 *val, struct acpi_generic_address *reg) | ||
322 | { | ||
323 | u64 paddr; | ||
324 | int rc; | ||
325 | |||
326 | rc = acpi_check_gar(reg, &paddr, 1); | ||
327 | if (rc) | ||
328 | return rc; | ||
329 | |||
330 | *val = 0; | ||
331 | switch (reg->space_id) { | ||
332 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: | ||
333 | return acpi_atomic_read_mem(paddr, val, reg->bit_width); | ||
334 | case ACPI_ADR_SPACE_SYSTEM_IO: | ||
335 | return acpi_os_read_port(paddr, (u32 *)val, reg->bit_width); | ||
336 | default: | ||
337 | return -EINVAL; | ||
338 | } | ||
339 | } | ||
340 | EXPORT_SYMBOL_GPL(acpi_atomic_read); | ||
341 | |||
342 | int acpi_atomic_write(u64 val, struct acpi_generic_address *reg) | ||
343 | { | ||
344 | u64 paddr; | ||
345 | int rc; | ||
346 | |||
347 | rc = acpi_check_gar(reg, &paddr, 1); | ||
348 | if (rc) | ||
349 | return rc; | ||
350 | |||
351 | switch (reg->space_id) { | ||
352 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: | ||
353 | return acpi_atomic_write_mem(paddr, val, reg->bit_width); | ||
354 | case ACPI_ADR_SPACE_SYSTEM_IO: | ||
355 | return acpi_os_write_port(paddr, val, reg->bit_width); | ||
356 | default: | ||
357 | return -EINVAL; | ||
358 | } | ||
359 | } | ||
360 | EXPORT_SYMBOL_GPL(acpi_atomic_write); | ||
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index f2234db85da0..e61d4f8e62a5 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -1027,10 +1027,9 @@ int __init acpi_ec_ecdt_probe(void) | |||
1027 | /* Don't trust ECDT, which comes from ASUSTek */ | 1027 | /* Don't trust ECDT, which comes from ASUSTek */ |
1028 | if (!EC_FLAGS_VALIDATE_ECDT) | 1028 | if (!EC_FLAGS_VALIDATE_ECDT) |
1029 | goto install; | 1029 | goto install; |
1030 | saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); | 1030 | saved_ec = kmemdup(boot_ec, sizeof(struct acpi_ec), GFP_KERNEL); |
1031 | if (!saved_ec) | 1031 | if (!saved_ec) |
1032 | return -ENOMEM; | 1032 | return -ENOMEM; |
1033 | memcpy(saved_ec, boot_ec, sizeof(struct acpi_ec)); | ||
1034 | /* fall through */ | 1033 | /* fall through */ |
1035 | } | 1034 | } |
1036 | 1035 | ||
diff --git a/drivers/acpi/hed.c b/drivers/acpi/hed.c new file mode 100644 index 000000000000..d0c1967f7597 --- /dev/null +++ b/drivers/acpi/hed.c | |||
@@ -0,0 +1,112 @@ | |||
1 | /* | ||
2 | * ACPI Hardware Error Device (PNP0C33) Driver | ||
3 | * | ||
4 | * Copyright (C) 2010, Intel Corp. | ||
5 | * Author: Huang Ying <ying.huang@intel.com> | ||
6 | * | ||
7 | * ACPI Hardware Error Device is used to report some hardware errors | ||
8 | * notified via SCI, mainly the corrected errors. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or | ||
11 | * modify it under the terms of the GNU General Public License version | ||
12 | * 2 as published by the Free Software Foundation; | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | */ | ||
23 | |||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/init.h> | ||
27 | #include <linux/acpi.h> | ||
28 | #include <acpi/acpi_bus.h> | ||
29 | #include <acpi/acpi_drivers.h> | ||
30 | #include <acpi/hed.h> | ||
31 | |||
32 | static struct acpi_device_id acpi_hed_ids[] = { | ||
33 | {"PNP0C33", 0}, | ||
34 | {"", 0}, | ||
35 | }; | ||
36 | MODULE_DEVICE_TABLE(acpi, acpi_hed_ids); | ||
37 | |||
38 | static acpi_handle hed_handle; | ||
39 | |||
40 | static BLOCKING_NOTIFIER_HEAD(acpi_hed_notify_list); | ||
41 | |||
42 | int register_acpi_hed_notifier(struct notifier_block *nb) | ||
43 | { | ||
44 | return blocking_notifier_chain_register(&acpi_hed_notify_list, nb); | ||
45 | } | ||
46 | EXPORT_SYMBOL_GPL(register_acpi_hed_notifier); | ||
47 | |||
48 | void unregister_acpi_hed_notifier(struct notifier_block *nb) | ||
49 | { | ||
50 | blocking_notifier_chain_unregister(&acpi_hed_notify_list, nb); | ||
51 | } | ||
52 | EXPORT_SYMBOL_GPL(unregister_acpi_hed_notifier); | ||
53 | |||
54 | /* | ||
55 | * SCI to report hardware error is forwarded to the listeners of HED, | ||
56 | * it is used by HEST Generic Hardware Error Source with notify type | ||
57 | * SCI. | ||
58 | */ | ||
59 | static void acpi_hed_notify(struct acpi_device *device, u32 event) | ||
60 | { | ||
61 | blocking_notifier_call_chain(&acpi_hed_notify_list, 0, NULL); | ||
62 | } | ||
63 | |||
64 | static int __devinit acpi_hed_add(struct acpi_device *device) | ||
65 | { | ||
66 | /* Only one hardware error device */ | ||
67 | if (hed_handle) | ||
68 | return -EINVAL; | ||
69 | hed_handle = device->handle; | ||
70 | return 0; | ||
71 | } | ||
72 | |||
73 | static int __devexit acpi_hed_remove(struct acpi_device *device, int type) | ||
74 | { | ||
75 | hed_handle = NULL; | ||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | static struct acpi_driver acpi_hed_driver = { | ||
80 | .name = "hardware_error_device", | ||
81 | .class = "hardware_error", | ||
82 | .ids = acpi_hed_ids, | ||
83 | .ops = { | ||
84 | .add = acpi_hed_add, | ||
85 | .remove = acpi_hed_remove, | ||
86 | .notify = acpi_hed_notify, | ||
87 | }, | ||
88 | }; | ||
89 | |||
90 | static int __init acpi_hed_init(void) | ||
91 | { | ||
92 | if (acpi_disabled) | ||
93 | return -ENODEV; | ||
94 | |||
95 | if (acpi_bus_register_driver(&acpi_hed_driver) < 0) | ||
96 | return -ENODEV; | ||
97 | |||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | static void __exit acpi_hed_exit(void) | ||
102 | { | ||
103 | acpi_bus_unregister_driver(&acpi_hed_driver); | ||
104 | } | ||
105 | |||
106 | module_init(acpi_hed_init); | ||
107 | module_exit(acpi_hed_exit); | ||
108 | |||
109 | ACPI_MODULE_NAME("hed"); | ||
110 | MODULE_AUTHOR("Huang Ying"); | ||
111 | MODULE_DESCRIPTION("ACPI Hardware Error Device Driver"); | ||
112 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/acpi/hest.c b/drivers/acpi/hest.c deleted file mode 100644 index 1c527a192872..000000000000 --- a/drivers/acpi/hest.c +++ /dev/null | |||
@@ -1,139 +0,0 @@ | |||
1 | #include <linux/acpi.h> | ||
2 | #include <linux/pci.h> | ||
3 | |||
4 | #define PREFIX "ACPI: " | ||
5 | |||
6 | static inline unsigned long parse_acpi_hest_ia_machine_check(struct acpi_hest_ia_machine_check *p) | ||
7 | { | ||
8 | return sizeof(*p) + | ||
9 | (sizeof(struct acpi_hest_ia_error_bank) * p->num_hardware_banks); | ||
10 | } | ||
11 | |||
12 | static inline unsigned long parse_acpi_hest_ia_corrected(struct acpi_hest_ia_corrected *p) | ||
13 | { | ||
14 | return sizeof(*p) + | ||
15 | (sizeof(struct acpi_hest_ia_error_bank) * p->num_hardware_banks); | ||
16 | } | ||
17 | |||
18 | static inline unsigned long parse_acpi_hest_ia_nmi(struct acpi_hest_ia_nmi *p) | ||
19 | { | ||
20 | return sizeof(*p); | ||
21 | } | ||
22 | |||
23 | static inline unsigned long parse_acpi_hest_generic(struct acpi_hest_generic *p) | ||
24 | { | ||
25 | return sizeof(*p); | ||
26 | } | ||
27 | |||
28 | static inline unsigned int hest_match_pci(struct acpi_hest_aer_common *p, struct pci_dev *pci) | ||
29 | { | ||
30 | return (0 == pci_domain_nr(pci->bus) && | ||
31 | p->bus == pci->bus->number && | ||
32 | p->device == PCI_SLOT(pci->devfn) && | ||
33 | p->function == PCI_FUNC(pci->devfn)); | ||
34 | } | ||
35 | |||
36 | static unsigned long parse_acpi_hest_aer(void *hdr, int type, struct pci_dev *pci, int *firmware_first) | ||
37 | { | ||
38 | struct acpi_hest_aer_common *p = hdr + sizeof(struct acpi_hest_header); | ||
39 | unsigned long rc=0; | ||
40 | u8 pcie_type = 0; | ||
41 | u8 bridge = 0; | ||
42 | switch (type) { | ||
43 | case ACPI_HEST_TYPE_AER_ROOT_PORT: | ||
44 | rc = sizeof(struct acpi_hest_aer_root); | ||
45 | pcie_type = PCI_EXP_TYPE_ROOT_PORT; | ||
46 | break; | ||
47 | case ACPI_HEST_TYPE_AER_ENDPOINT: | ||
48 | rc = sizeof(struct acpi_hest_aer); | ||
49 | pcie_type = PCI_EXP_TYPE_ENDPOINT; | ||
50 | break; | ||
51 | case ACPI_HEST_TYPE_AER_BRIDGE: | ||
52 | rc = sizeof(struct acpi_hest_aer_bridge); | ||
53 | if ((pci->class >> 16) == PCI_BASE_CLASS_BRIDGE) | ||
54 | bridge = 1; | ||
55 | break; | ||
56 | } | ||
57 | |||
58 | if (p->flags & ACPI_HEST_GLOBAL) { | ||
59 | if ((pci->is_pcie && (pci->pcie_type == pcie_type)) || bridge) | ||
60 | *firmware_first = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST); | ||
61 | } | ||
62 | else | ||
63 | if (hest_match_pci(p, pci)) | ||
64 | *firmware_first = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST); | ||
65 | return rc; | ||
66 | } | ||
67 | |||
68 | static int acpi_hest_firmware_first(struct acpi_table_header *stdheader, struct pci_dev *pci) | ||
69 | { | ||
70 | struct acpi_table_hest *hest = (struct acpi_table_hest *)stdheader; | ||
71 | void *p = (void *)hest + sizeof(*hest); /* defined by the ACPI 4.0 spec */ | ||
72 | struct acpi_hest_header *hdr = p; | ||
73 | |||
74 | int i; | ||
75 | int firmware_first = 0; | ||
76 | static unsigned char printed_unused = 0; | ||
77 | static unsigned char printed_reserved = 0; | ||
78 | |||
79 | for (i=0, hdr=p; p < (((void *)hest) + hest->header.length) && i < hest->error_source_count; i++) { | ||
80 | switch (hdr->type) { | ||
81 | case ACPI_HEST_TYPE_IA32_CHECK: | ||
82 | p += parse_acpi_hest_ia_machine_check(p); | ||
83 | break; | ||
84 | case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: | ||
85 | p += parse_acpi_hest_ia_corrected(p); | ||
86 | break; | ||
87 | case ACPI_HEST_TYPE_IA32_NMI: | ||
88 | p += parse_acpi_hest_ia_nmi(p); | ||
89 | break; | ||
90 | /* These three should never appear */ | ||
91 | case ACPI_HEST_TYPE_NOT_USED3: | ||
92 | case ACPI_HEST_TYPE_NOT_USED4: | ||
93 | case ACPI_HEST_TYPE_NOT_USED5: | ||
94 | if (!printed_unused) { | ||
95 | printk(KERN_DEBUG PREFIX | ||
96 | "HEST Error Source list contains an obsolete type (%d).\n", hdr->type); | ||
97 | printed_unused = 1; | ||
98 | } | ||
99 | break; | ||
100 | case ACPI_HEST_TYPE_AER_ROOT_PORT: | ||
101 | case ACPI_HEST_TYPE_AER_ENDPOINT: | ||
102 | case ACPI_HEST_TYPE_AER_BRIDGE: | ||
103 | p += parse_acpi_hest_aer(p, hdr->type, pci, &firmware_first); | ||
104 | break; | ||
105 | case ACPI_HEST_TYPE_GENERIC_ERROR: | ||
106 | p += parse_acpi_hest_generic(p); | ||
107 | break; | ||
108 | /* These should never appear either */ | ||
109 | case ACPI_HEST_TYPE_RESERVED: | ||
110 | default: | ||
111 | if (!printed_reserved) { | ||
112 | printk(KERN_DEBUG PREFIX | ||
113 | "HEST Error Source list contains a reserved type (%d).\n", hdr->type); | ||
114 | printed_reserved = 1; | ||
115 | } | ||
116 | break; | ||
117 | } | ||
118 | } | ||
119 | return firmware_first; | ||
120 | } | ||
121 | |||
122 | int acpi_hest_firmware_first_pci(struct pci_dev *pci) | ||
123 | { | ||
124 | acpi_status status = AE_NOT_FOUND; | ||
125 | struct acpi_table_header *hest = NULL; | ||
126 | |||
127 | if (acpi_disabled) | ||
128 | return 0; | ||
129 | |||
130 | status = acpi_get_table(ACPI_SIG_HEST, 1, &hest); | ||
131 | |||
132 | if (ACPI_SUCCESS(status)) { | ||
133 | if (acpi_hest_firmware_first(hest, pci)) { | ||
134 | return 1; | ||
135 | } | ||
136 | } | ||
137 | return 0; | ||
138 | } | ||
139 | EXPORT_SYMBOL_GPL(acpi_hest_firmware_first_pci); | ||
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index aefce33f2a09..4eac59393edc 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -120,7 +120,8 @@ acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus) | |||
120 | struct acpi_pci_root *root; | 120 | struct acpi_pci_root *root; |
121 | 121 | ||
122 | list_for_each_entry(root, &acpi_pci_roots, node) | 122 | list_for_each_entry(root, &acpi_pci_roots, node) |
123 | if ((root->segment == (u16) seg) && (root->bus_nr == (u16) bus)) | 123 | if ((root->segment == (u16) seg) && |
124 | (root->secondary.start == (u16) bus)) | ||
124 | return root->device->handle; | 125 | return root->device->handle; |
125 | return NULL; | 126 | return NULL; |
126 | } | 127 | } |
@@ -154,7 +155,7 @@ EXPORT_SYMBOL_GPL(acpi_is_root_bridge); | |||
154 | static acpi_status | 155 | static acpi_status |
155 | get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) | 156 | get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) |
156 | { | 157 | { |
157 | int *busnr = data; | 158 | struct resource *res = data; |
158 | struct acpi_resource_address64 address; | 159 | struct acpi_resource_address64 address; |
159 | 160 | ||
160 | if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 && | 161 | if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 && |
@@ -164,28 +165,27 @@ get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) | |||
164 | 165 | ||
165 | acpi_resource_to_address64(resource, &address); | 166 | acpi_resource_to_address64(resource, &address); |
166 | if ((address.address_length > 0) && | 167 | if ((address.address_length > 0) && |
167 | (address.resource_type == ACPI_BUS_NUMBER_RANGE)) | 168 | (address.resource_type == ACPI_BUS_NUMBER_RANGE)) { |
168 | *busnr = address.minimum; | 169 | res->start = address.minimum; |
170 | res->end = address.minimum + address.address_length - 1; | ||
171 | } | ||
169 | 172 | ||
170 | return AE_OK; | 173 | return AE_OK; |
171 | } | 174 | } |
172 | 175 | ||
173 | static acpi_status try_get_root_bridge_busnr(acpi_handle handle, | 176 | static acpi_status try_get_root_bridge_busnr(acpi_handle handle, |
174 | unsigned long long *bus) | 177 | struct resource *res) |
175 | { | 178 | { |
176 | acpi_status status; | 179 | acpi_status status; |
177 | int busnum; | ||
178 | 180 | ||
179 | busnum = -1; | 181 | res->start = -1; |
180 | status = | 182 | status = |
181 | acpi_walk_resources(handle, METHOD_NAME__CRS, | 183 | acpi_walk_resources(handle, METHOD_NAME__CRS, |
182 | get_root_bridge_busnr_callback, &busnum); | 184 | get_root_bridge_busnr_callback, res); |
183 | if (ACPI_FAILURE(status)) | 185 | if (ACPI_FAILURE(status)) |
184 | return status; | 186 | return status; |
185 | /* Check if we really get a bus number from _CRS */ | 187 | if (res->start == -1) |
186 | if (busnum == -1) | ||
187 | return AE_ERROR; | 188 | return AE_ERROR; |
188 | *bus = busnum; | ||
189 | return AE_OK; | 189 | return AE_OK; |
190 | } | 190 | } |
191 | 191 | ||
@@ -429,34 +429,47 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
429 | struct acpi_device *child; | 429 | struct acpi_device *child; |
430 | u32 flags, base_flags; | 430 | u32 flags, base_flags; |
431 | 431 | ||
432 | root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); | ||
433 | if (!root) | ||
434 | return -ENOMEM; | ||
435 | |||
432 | segment = 0; | 436 | segment = 0; |
433 | status = acpi_evaluate_integer(device->handle, METHOD_NAME__SEG, NULL, | 437 | status = acpi_evaluate_integer(device->handle, METHOD_NAME__SEG, NULL, |
434 | &segment); | 438 | &segment); |
435 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | 439 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { |
436 | printk(KERN_ERR PREFIX "can't evaluate _SEG\n"); | 440 | printk(KERN_ERR PREFIX "can't evaluate _SEG\n"); |
437 | return -ENODEV; | 441 | result = -ENODEV; |
442 | goto end; | ||
438 | } | 443 | } |
439 | 444 | ||
440 | /* Check _CRS first, then _BBN. If no _BBN, default to zero. */ | 445 | /* Check _CRS first, then _BBN. If no _BBN, default to zero. */ |
441 | bus = 0; | 446 | root->secondary.flags = IORESOURCE_BUS; |
442 | status = try_get_root_bridge_busnr(device->handle, &bus); | 447 | status = try_get_root_bridge_busnr(device->handle, &root->secondary); |
443 | if (ACPI_FAILURE(status)) { | 448 | if (ACPI_FAILURE(status)) { |
449 | /* | ||
450 | * We need both the start and end of the downstream bus range | ||
451 | * to interpret _CBA (MMCONFIG base address), so it really is | ||
452 | * supposed to be in _CRS. If we don't find it there, all we | ||
453 | * can do is assume [_BBN-0xFF] or [0-0xFF]. | ||
454 | */ | ||
455 | root->secondary.end = 0xFF; | ||
456 | printk(KERN_WARNING FW_BUG PREFIX | ||
457 | "no secondary bus range in _CRS\n"); | ||
444 | status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN, NULL, &bus); | 458 | status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN, NULL, &bus); |
445 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | 459 | if (ACPI_SUCCESS(status)) |
446 | printk(KERN_ERR PREFIX | 460 | root->secondary.start = bus; |
447 | "no bus number in _CRS and can't evaluate _BBN\n"); | 461 | else if (status == AE_NOT_FOUND) |
448 | return -ENODEV; | 462 | root->secondary.start = 0; |
463 | else { | ||
464 | printk(KERN_ERR PREFIX "can't evaluate _BBN\n"); | ||
465 | result = -ENODEV; | ||
466 | goto end; | ||
449 | } | 467 | } |
450 | } | 468 | } |
451 | 469 | ||
452 | root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); | ||
453 | if (!root) | ||
454 | return -ENOMEM; | ||
455 | |||
456 | INIT_LIST_HEAD(&root->node); | 470 | INIT_LIST_HEAD(&root->node); |
457 | root->device = device; | 471 | root->device = device; |
458 | root->segment = segment & 0xFFFF; | 472 | root->segment = segment & 0xFFFF; |
459 | root->bus_nr = bus & 0xFF; | ||
460 | strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME); | 473 | strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME); |
461 | strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); | 474 | strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); |
462 | device->driver_data = root; | 475 | device->driver_data = root; |
@@ -475,9 +488,9 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
475 | /* TBD: Locking */ | 488 | /* TBD: Locking */ |
476 | list_add_tail(&root->node, &acpi_pci_roots); | 489 | list_add_tail(&root->node, &acpi_pci_roots); |
477 | 490 | ||
478 | printk(KERN_INFO PREFIX "%s [%s] (%04x:%02x)\n", | 491 | printk(KERN_INFO PREFIX "%s [%s] (domain %04x %pR)\n", |
479 | acpi_device_name(device), acpi_device_bid(device), | 492 | acpi_device_name(device), acpi_device_bid(device), |
480 | root->segment, root->bus_nr); | 493 | root->segment, &root->secondary); |
481 | 494 | ||
482 | /* | 495 | /* |
483 | * Scan the Root Bridge | 496 | * Scan the Root Bridge |
@@ -486,11 +499,11 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
486 | * PCI namespace does not get created until this call is made (and | 499 | * PCI namespace does not get created until this call is made (and |
487 | * thus the root bridge's pci_dev does not exist). | 500 | * thus the root bridge's pci_dev does not exist). |
488 | */ | 501 | */ |
489 | root->bus = pci_acpi_scan_root(device, segment, bus); | 502 | root->bus = pci_acpi_scan_root(root); |
490 | if (!root->bus) { | 503 | if (!root->bus) { |
491 | printk(KERN_ERR PREFIX | 504 | printk(KERN_ERR PREFIX |
492 | "Bus %04x:%02x not present in PCI namespace\n", | 505 | "Bus %04x:%02x not present in PCI namespace\n", |
493 | root->segment, root->bus_nr); | 506 | root->segment, (unsigned int)root->secondary.start); |
494 | result = -ENODEV; | 507 | result = -ENODEV; |
495 | goto end; | 508 | goto end; |
496 | } | 509 | } |
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 5675d9747e87..b1034a9ada4e 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c | |||
@@ -616,7 +616,8 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) | |||
616 | acpi_processor_get_limit_info(pr); | 616 | acpi_processor_get_limit_info(pr); |
617 | 617 | ||
618 | 618 | ||
619 | acpi_processor_power_init(pr, device); | 619 | if (cpuidle_get_driver() == &acpi_idle_driver) |
620 | acpi_processor_power_init(pr, device); | ||
620 | 621 | ||
621 | pr->cdev = thermal_cooling_device_register("Processor", device, | 622 | pr->cdev = thermal_cooling_device_register("Processor", device, |
622 | &processor_cooling_ops); | 623 | &processor_cooling_ops); |
@@ -920,9 +921,14 @@ static int __init acpi_processor_init(void) | |||
920 | if (!acpi_processor_dir) | 921 | if (!acpi_processor_dir) |
921 | return -ENOMEM; | 922 | return -ENOMEM; |
922 | #endif | 923 | #endif |
923 | result = cpuidle_register_driver(&acpi_idle_driver); | 924 | |
924 | if (result < 0) | 925 | if (!cpuidle_register_driver(&acpi_idle_driver)) { |
925 | goto out_proc; | 926 | printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n", |
927 | acpi_idle_driver.name); | ||
928 | } else { | ||
929 | printk(KERN_DEBUG "ACPI: acpi_idle yielding to %s", | ||
930 | cpuidle_get_driver()->name); | ||
931 | } | ||
926 | 932 | ||
927 | result = acpi_bus_register_driver(&acpi_processor_driver); | 933 | result = acpi_bus_register_driver(&acpi_processor_driver); |
928 | if (result < 0) | 934 | if (result < 0) |
@@ -941,7 +947,6 @@ static int __init acpi_processor_init(void) | |||
941 | out_cpuidle: | 947 | out_cpuidle: |
942 | cpuidle_unregister_driver(&acpi_idle_driver); | 948 | cpuidle_unregister_driver(&acpi_idle_driver); |
943 | 949 | ||
944 | out_proc: | ||
945 | #ifdef CONFIG_ACPI_PROCFS | 950 | #ifdef CONFIG_ACPI_PROCFS |
946 | remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); | 951 | remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); |
947 | #endif | 952 | #endif |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index c3817e1f32c7..2e8c27d48f2b 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -727,19 +727,9 @@ static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset) | |||
727 | break; | 727 | break; |
728 | } | 728 | } |
729 | 729 | ||
730 | if (pr->power.states[i].promotion.state) | 730 | seq_puts(seq, "promotion[--] "); |
731 | seq_printf(seq, "promotion[C%zd] ", | 731 | |
732 | (pr->power.states[i].promotion.state - | 732 | seq_puts(seq, "demotion[--] "); |
733 | pr->power.states)); | ||
734 | else | ||
735 | seq_puts(seq, "promotion[--] "); | ||
736 | |||
737 | if (pr->power.states[i].demotion.state) | ||
738 | seq_printf(seq, "demotion[C%zd] ", | ||
739 | (pr->power.states[i].demotion.state - | ||
740 | pr->power.states)); | ||
741 | else | ||
742 | seq_puts(seq, "demotion[--] "); | ||
743 | 733 | ||
744 | seq_printf(seq, "latency[%03d] usage[%08d] duration[%020llu]\n", | 734 | seq_printf(seq, "latency[%03d] usage[%08d] duration[%020llu]\n", |
745 | pr->power.states[i].latency, | 735 | pr->power.states[i].latency, |
@@ -869,6 +859,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, | |||
869 | struct acpi_processor *pr; | 859 | struct acpi_processor *pr; |
870 | struct acpi_processor_cx *cx = cpuidle_get_statedata(state); | 860 | struct acpi_processor_cx *cx = cpuidle_get_statedata(state); |
871 | ktime_t kt1, kt2; | 861 | ktime_t kt1, kt2; |
862 | s64 idle_time_ns; | ||
872 | s64 idle_time; | 863 | s64 idle_time; |
873 | s64 sleep_ticks = 0; | 864 | s64 sleep_ticks = 0; |
874 | 865 | ||
@@ -881,6 +872,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, | |||
881 | return(acpi_idle_enter_c1(dev, state)); | 872 | return(acpi_idle_enter_c1(dev, state)); |
882 | 873 | ||
883 | local_irq_disable(); | 874 | local_irq_disable(); |
875 | |||
884 | if (cx->entry_method != ACPI_CSTATE_FFH) { | 876 | if (cx->entry_method != ACPI_CSTATE_FFH) { |
885 | current_thread_info()->status &= ~TS_POLLING; | 877 | current_thread_info()->status &= ~TS_POLLING; |
886 | /* | 878 | /* |
@@ -888,12 +880,12 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, | |||
888 | * NEED_RESCHED: | 880 | * NEED_RESCHED: |
889 | */ | 881 | */ |
890 | smp_mb(); | 882 | smp_mb(); |
891 | } | ||
892 | 883 | ||
893 | if (unlikely(need_resched())) { | 884 | if (unlikely(need_resched())) { |
894 | current_thread_info()->status |= TS_POLLING; | 885 | current_thread_info()->status |= TS_POLLING; |
895 | local_irq_enable(); | 886 | local_irq_enable(); |
896 | return 0; | 887 | return 0; |
888 | } | ||
897 | } | 889 | } |
898 | 890 | ||
899 | /* | 891 | /* |
@@ -910,15 +902,18 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, | |||
910 | sched_clock_idle_sleep_event(); | 902 | sched_clock_idle_sleep_event(); |
911 | acpi_idle_do_entry(cx); | 903 | acpi_idle_do_entry(cx); |
912 | kt2 = ktime_get_real(); | 904 | kt2 = ktime_get_real(); |
913 | idle_time = ktime_to_us(ktime_sub(kt2, kt1)); | 905 | idle_time_ns = ktime_to_ns(ktime_sub(kt2, kt1)); |
906 | idle_time = idle_time_ns; | ||
907 | do_div(idle_time, NSEC_PER_USEC); | ||
914 | 908 | ||
915 | sleep_ticks = us_to_pm_timer_ticks(idle_time); | 909 | sleep_ticks = us_to_pm_timer_ticks(idle_time); |
916 | 910 | ||
917 | /* Tell the scheduler how much we idled: */ | 911 | /* Tell the scheduler how much we idled: */ |
918 | sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); | 912 | sched_clock_idle_wakeup_event(idle_time_ns); |
919 | 913 | ||
920 | local_irq_enable(); | 914 | local_irq_enable(); |
921 | current_thread_info()->status |= TS_POLLING; | 915 | if (cx->entry_method != ACPI_CSTATE_FFH) |
916 | current_thread_info()->status |= TS_POLLING; | ||
922 | 917 | ||
923 | cx->usage++; | 918 | cx->usage++; |
924 | 919 | ||
@@ -943,6 +938,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
943 | struct acpi_processor *pr; | 938 | struct acpi_processor *pr; |
944 | struct acpi_processor_cx *cx = cpuidle_get_statedata(state); | 939 | struct acpi_processor_cx *cx = cpuidle_get_statedata(state); |
945 | ktime_t kt1, kt2; | 940 | ktime_t kt1, kt2; |
941 | s64 idle_time_ns; | ||
946 | s64 idle_time; | 942 | s64 idle_time; |
947 | s64 sleep_ticks = 0; | 943 | s64 sleep_ticks = 0; |
948 | 944 | ||
@@ -968,6 +964,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
968 | } | 964 | } |
969 | 965 | ||
970 | local_irq_disable(); | 966 | local_irq_disable(); |
967 | |||
971 | if (cx->entry_method != ACPI_CSTATE_FFH) { | 968 | if (cx->entry_method != ACPI_CSTATE_FFH) { |
972 | current_thread_info()->status &= ~TS_POLLING; | 969 | current_thread_info()->status &= ~TS_POLLING; |
973 | /* | 970 | /* |
@@ -975,12 +972,12 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
975 | * NEED_RESCHED: | 972 | * NEED_RESCHED: |
976 | */ | 973 | */ |
977 | smp_mb(); | 974 | smp_mb(); |
978 | } | ||
979 | 975 | ||
980 | if (unlikely(need_resched())) { | 976 | if (unlikely(need_resched())) { |
981 | current_thread_info()->status |= TS_POLLING; | 977 | current_thread_info()->status |= TS_POLLING; |
982 | local_irq_enable(); | 978 | local_irq_enable(); |
983 | return 0; | 979 | return 0; |
980 | } | ||
984 | } | 981 | } |
985 | 982 | ||
986 | acpi_unlazy_tlb(smp_processor_id()); | 983 | acpi_unlazy_tlb(smp_processor_id()); |
@@ -1025,14 +1022,17 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
1025 | spin_unlock(&c3_lock); | 1022 | spin_unlock(&c3_lock); |
1026 | } | 1023 | } |
1027 | kt2 = ktime_get_real(); | 1024 | kt2 = ktime_get_real(); |
1028 | idle_time = ktime_to_us(ktime_sub(kt2, kt1)); | 1025 | idle_time_ns = ktime_to_us(ktime_sub(kt2, kt1)); |
1026 | idle_time = idle_time_ns; | ||
1027 | do_div(idle_time, NSEC_PER_USEC); | ||
1029 | 1028 | ||
1030 | sleep_ticks = us_to_pm_timer_ticks(idle_time); | 1029 | sleep_ticks = us_to_pm_timer_ticks(idle_time); |
1031 | /* Tell the scheduler how much we idled: */ | 1030 | /* Tell the scheduler how much we idled: */ |
1032 | sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); | 1031 | sched_clock_idle_wakeup_event(idle_time_ns); |
1033 | 1032 | ||
1034 | local_irq_enable(); | 1033 | local_irq_enable(); |
1035 | current_thread_info()->status |= TS_POLLING; | 1034 | if (cx->entry_method != ACPI_CSTATE_FFH) |
1035 | current_thread_info()->status |= TS_POLLING; | ||
1036 | 1036 | ||
1037 | cx->usage++; | 1037 | cx->usage++; |
1038 | 1038 | ||
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index baa76bbf244a..4ab2275b4461 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -80,22 +80,6 @@ static int acpi_sleep_prepare(u32 acpi_state) | |||
80 | 80 | ||
81 | #ifdef CONFIG_ACPI_SLEEP | 81 | #ifdef CONFIG_ACPI_SLEEP |
82 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; | 82 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; |
83 | /* | ||
84 | * According to the ACPI specification the BIOS should make sure that ACPI is | ||
85 | * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still, | ||
86 | * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI | ||
87 | * on such systems during resume. Unfortunately that doesn't help in | ||
88 | * particularly pathological cases in which SCI_EN has to be set directly on | ||
89 | * resume, although the specification states very clearly that this flag is | ||
90 | * owned by the hardware. The set_sci_en_on_resume variable will be set in such | ||
91 | * cases. | ||
92 | */ | ||
93 | static bool set_sci_en_on_resume; | ||
94 | |||
95 | void __init acpi_set_sci_en_on_resume(void) | ||
96 | { | ||
97 | set_sci_en_on_resume = true; | ||
98 | } | ||
99 | 83 | ||
100 | /* | 84 | /* |
101 | * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the | 85 | * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the |
@@ -253,11 +237,8 @@ static int acpi_suspend_enter(suspend_state_t pm_state) | |||
253 | break; | 237 | break; |
254 | } | 238 | } |
255 | 239 | ||
256 | /* If ACPI is not enabled by the BIOS, we need to enable it here. */ | 240 | /* This violates the spec but is required for bug compatibility. */ |
257 | if (set_sci_en_on_resume) | 241 | acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1); |
258 | acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1); | ||
259 | else | ||
260 | acpi_enable(); | ||
261 | 242 | ||
262 | /* Reprogram control registers and execute _BFS */ | 243 | /* Reprogram control registers and execute _BFS */ |
263 | acpi_leave_sleep_state_prep(acpi_state); | 244 | acpi_leave_sleep_state_prep(acpi_state); |
@@ -346,12 +327,6 @@ static int __init init_old_suspend_ordering(const struct dmi_system_id *d) | |||
346 | return 0; | 327 | return 0; |
347 | } | 328 | } |
348 | 329 | ||
349 | static int __init init_set_sci_en_on_resume(const struct dmi_system_id *d) | ||
350 | { | ||
351 | set_sci_en_on_resume = true; | ||
352 | return 0; | ||
353 | } | ||
354 | |||
355 | static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | 330 | static struct dmi_system_id __initdata acpisleep_dmi_table[] = { |
356 | { | 331 | { |
357 | .callback = init_old_suspend_ordering, | 332 | .callback = init_old_suspend_ordering, |
@@ -370,22 +345,6 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | |||
370 | }, | 345 | }, |
371 | }, | 346 | }, |
372 | { | 347 | { |
373 | .callback = init_set_sci_en_on_resume, | ||
374 | .ident = "Apple MacBook 1,1", | ||
375 | .matches = { | ||
376 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."), | ||
377 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBook1,1"), | ||
378 | }, | ||
379 | }, | ||
380 | { | ||
381 | .callback = init_set_sci_en_on_resume, | ||
382 | .ident = "Apple MacMini 1,1", | ||
383 | .matches = { | ||
384 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."), | ||
385 | DMI_MATCH(DMI_PRODUCT_NAME, "Macmini1,1"), | ||
386 | }, | ||
387 | }, | ||
388 | { | ||
389 | .callback = init_old_suspend_ordering, | 348 | .callback = init_old_suspend_ordering, |
390 | .ident = "Asus Pundit P1-AH2 (M2N8L motherboard)", | 349 | .ident = "Asus Pundit P1-AH2 (M2N8L motherboard)", |
391 | .matches = { | 350 | .matches = { |
@@ -394,94 +353,6 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | |||
394 | }, | 353 | }, |
395 | }, | 354 | }, |
396 | { | 355 | { |
397 | .callback = init_set_sci_en_on_resume, | ||
398 | .ident = "Toshiba Satellite L300", | ||
399 | .matches = { | ||
400 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
401 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite L300"), | ||
402 | }, | ||
403 | }, | ||
404 | { | ||
405 | .callback = init_set_sci_en_on_resume, | ||
406 | .ident = "Hewlett-Packard HP G7000 Notebook PC", | ||
407 | .matches = { | ||
408 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
409 | DMI_MATCH(DMI_PRODUCT_NAME, "HP G7000 Notebook PC"), | ||
410 | }, | ||
411 | }, | ||
412 | { | ||
413 | .callback = init_set_sci_en_on_resume, | ||
414 | .ident = "Hewlett-Packard HP Pavilion dv3 Notebook PC", | ||
415 | .matches = { | ||
416 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
417 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv3 Notebook PC"), | ||
418 | }, | ||
419 | }, | ||
420 | { | ||
421 | .callback = init_set_sci_en_on_resume, | ||
422 | .ident = "Hewlett-Packard Pavilion dv4", | ||
423 | .matches = { | ||
424 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
425 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4"), | ||
426 | }, | ||
427 | }, | ||
428 | { | ||
429 | .callback = init_set_sci_en_on_resume, | ||
430 | .ident = "Hewlett-Packard Pavilion dv7", | ||
431 | .matches = { | ||
432 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
433 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv7"), | ||
434 | }, | ||
435 | }, | ||
436 | { | ||
437 | .callback = init_set_sci_en_on_resume, | ||
438 | .ident = "Hewlett-Packard Compaq Presario C700 Notebook PC", | ||
439 | .matches = { | ||
440 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
441 | DMI_MATCH(DMI_PRODUCT_NAME, "Compaq Presario C700 Notebook PC"), | ||
442 | }, | ||
443 | }, | ||
444 | { | ||
445 | .callback = init_set_sci_en_on_resume, | ||
446 | .ident = "Hewlett-Packard Compaq Presario CQ40 Notebook PC", | ||
447 | .matches = { | ||
448 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
449 | DMI_MATCH(DMI_PRODUCT_NAME, "Compaq Presario CQ40 Notebook PC"), | ||
450 | }, | ||
451 | }, | ||
452 | { | ||
453 | .callback = init_set_sci_en_on_resume, | ||
454 | .ident = "Lenovo ThinkPad T410", | ||
455 | .matches = { | ||
456 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
457 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T410"), | ||
458 | }, | ||
459 | }, | ||
460 | { | ||
461 | .callback = init_set_sci_en_on_resume, | ||
462 | .ident = "Lenovo ThinkPad T510", | ||
463 | .matches = { | ||
464 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
465 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T510"), | ||
466 | }, | ||
467 | }, | ||
468 | { | ||
469 | .callback = init_set_sci_en_on_resume, | ||
470 | .ident = "Lenovo ThinkPad W510", | ||
471 | .matches = { | ||
472 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
473 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad W510"), | ||
474 | }, | ||
475 | }, | ||
476 | { | ||
477 | .callback = init_set_sci_en_on_resume, | ||
478 | .ident = "Lenovo ThinkPad X201[s]", | ||
479 | .matches = { | ||
480 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
481 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X201"), | ||
482 | }, | ||
483 | }, | ||
484 | { | ||
485 | .callback = init_old_suspend_ordering, | 356 | .callback = init_old_suspend_ordering, |
486 | .ident = "Panasonic CF51-2L", | 357 | .ident = "Panasonic CF51-2L", |
487 | .matches = { | 358 | .matches = { |
@@ -490,30 +361,6 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | |||
490 | DMI_MATCH(DMI_BOARD_NAME, "CF51-2L"), | 361 | DMI_MATCH(DMI_BOARD_NAME, "CF51-2L"), |
491 | }, | 362 | }, |
492 | }, | 363 | }, |
493 | { | ||
494 | .callback = init_set_sci_en_on_resume, | ||
495 | .ident = "Dell Studio 1558", | ||
496 | .matches = { | ||
497 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
498 | DMI_MATCH(DMI_PRODUCT_NAME, "Studio 1558"), | ||
499 | }, | ||
500 | }, | ||
501 | { | ||
502 | .callback = init_set_sci_en_on_resume, | ||
503 | .ident = "Dell Studio 1557", | ||
504 | .matches = { | ||
505 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
506 | DMI_MATCH(DMI_PRODUCT_NAME, "Studio 1557"), | ||
507 | }, | ||
508 | }, | ||
509 | { | ||
510 | .callback = init_set_sci_en_on_resume, | ||
511 | .ident = "Dell Studio 1555", | ||
512 | .matches = { | ||
513 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
514 | DMI_MATCH(DMI_PRODUCT_NAME, "Studio 1555"), | ||
515 | }, | ||
516 | }, | ||
517 | {}, | 364 | {}, |
518 | }; | 365 | }; |
519 | #endif /* CONFIG_SUSPEND */ | 366 | #endif /* CONFIG_SUSPEND */ |
diff --git a/drivers/acpi/sleep.h b/drivers/acpi/sleep.h index 8a8f3b3382a6..25b8bd149284 100644 --- a/drivers/acpi/sleep.h +++ b/drivers/acpi/sleep.h | |||
@@ -1,6 +1,6 @@ | |||
1 | 1 | ||
2 | extern u8 sleep_states[]; | 2 | extern u8 sleep_states[]; |
3 | extern int acpi_suspend (u32 state); | 3 | extern int acpi_suspend(u32 state); |
4 | 4 | ||
5 | extern void acpi_enable_wakeup_device_prep(u8 sleep_state); | 5 | extern void acpi_enable_wakeup_device_prep(u8 sleep_state); |
6 | extern void acpi_enable_wakeup_device(u8 sleep_state); | 6 | extern void acpi_enable_wakeup_device(u8 sleep_state); |
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index 8a0ed2800e63..f336bca7c450 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c | |||
@@ -213,7 +213,7 @@ acpi_table_parse_entries(char *id, | |||
213 | unsigned long table_end; | 213 | unsigned long table_end; |
214 | acpi_size tbl_size; | 214 | acpi_size tbl_size; |
215 | 215 | ||
216 | if (acpi_disabled && !acpi_ht) | 216 | if (acpi_disabled) |
217 | return -ENODEV; | 217 | return -ENODEV; |
218 | 218 | ||
219 | if (!handler) | 219 | if (!handler) |
@@ -280,7 +280,7 @@ int __init acpi_table_parse(char *id, acpi_table_handler handler) | |||
280 | struct acpi_table_header *table = NULL; | 280 | struct acpi_table_header *table = NULL; |
281 | acpi_size tbl_size; | 281 | acpi_size tbl_size; |
282 | 282 | ||
283 | if (acpi_disabled && !acpi_ht) | 283 | if (acpi_disabled) |
284 | return -ENODEV; | 284 | return -ENODEV; |
285 | 285 | ||
286 | if (!handler) | 286 | if (!handler) |
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index a0c93b321482..9865d46f49a8 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <acpi/acpi_bus.h> | 45 | #include <acpi/acpi_bus.h> |
46 | #include <acpi/acpi_drivers.h> | 46 | #include <acpi/acpi_drivers.h> |
47 | #include <linux/suspend.h> | 47 | #include <linux/suspend.h> |
48 | #include <acpi/video.h> | ||
48 | 49 | ||
49 | #define PREFIX "ACPI: " | 50 | #define PREFIX "ACPI: " |
50 | 51 | ||
@@ -65,11 +66,6 @@ | |||
65 | 66 | ||
66 | #define MAX_NAME_LEN 20 | 67 | #define MAX_NAME_LEN 20 |
67 | 68 | ||
68 | #define ACPI_VIDEO_DISPLAY_CRT 1 | ||
69 | #define ACPI_VIDEO_DISPLAY_TV 2 | ||
70 | #define ACPI_VIDEO_DISPLAY_DVI 3 | ||
71 | #define ACPI_VIDEO_DISPLAY_LCD 4 | ||
72 | |||
73 | #define _COMPONENT ACPI_VIDEO_COMPONENT | 69 | #define _COMPONENT ACPI_VIDEO_COMPONENT |
74 | ACPI_MODULE_NAME("video"); | 70 | ACPI_MODULE_NAME("video"); |
75 | 71 | ||
@@ -1007,11 +1003,11 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
1007 | result = acpi_video_init_brightness(device); | 1003 | result = acpi_video_init_brightness(device); |
1008 | if (result) | 1004 | if (result) |
1009 | return; | 1005 | return; |
1010 | name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); | 1006 | name = kasprintf(GFP_KERNEL, "acpi_video%d", count); |
1011 | if (!name) | 1007 | if (!name) |
1012 | return; | 1008 | return; |
1009 | count++; | ||
1013 | 1010 | ||
1014 | sprintf(name, "acpi_video%d", count++); | ||
1015 | memset(&props, 0, sizeof(struct backlight_properties)); | 1011 | memset(&props, 0, sizeof(struct backlight_properties)); |
1016 | props.max_brightness = device->brightness->count - 3; | 1012 | props.max_brightness = device->brightness->count - 3; |
1017 | device->backlight = backlight_device_register(name, NULL, device, | 1013 | device->backlight = backlight_device_register(name, NULL, device, |
@@ -1067,10 +1063,10 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
1067 | if (device->cap._DCS && device->cap._DSS) { | 1063 | if (device->cap._DCS && device->cap._DSS) { |
1068 | static int count; | 1064 | static int count; |
1069 | char *name; | 1065 | char *name; |
1070 | name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); | 1066 | name = kasprintf(GFP_KERNEL, "acpi_video%d", count); |
1071 | if (!name) | 1067 | if (!name) |
1072 | return; | 1068 | return; |
1073 | sprintf(name, "acpi_video%d", count++); | 1069 | count++; |
1074 | device->output_dev = video_output_register(name, | 1070 | device->output_dev = video_output_register(name, |
1075 | NULL, device, &acpi_output_properties); | 1071 | NULL, device, &acpi_output_properties); |
1076 | kfree(name); | 1072 | kfree(name); |
@@ -1748,11 +1744,27 @@ acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id | |||
1748 | } | 1744 | } |
1749 | 1745 | ||
1750 | static int | 1746 | static int |
1747 | acpi_video_get_device_type(struct acpi_video_bus *video, | ||
1748 | unsigned long device_id) | ||
1749 | { | ||
1750 | struct acpi_video_enumerated_device *ids; | ||
1751 | int i; | ||
1752 | |||
1753 | for (i = 0; i < video->attached_count; i++) { | ||
1754 | ids = &video->attached_array[i]; | ||
1755 | if ((ids->value.int_val & 0xffff) == device_id) | ||
1756 | return ids->value.int_val; | ||
1757 | } | ||
1758 | |||
1759 | return 0; | ||
1760 | } | ||
1761 | |||
1762 | static int | ||
1751 | acpi_video_bus_get_one_device(struct acpi_device *device, | 1763 | acpi_video_bus_get_one_device(struct acpi_device *device, |
1752 | struct acpi_video_bus *video) | 1764 | struct acpi_video_bus *video) |
1753 | { | 1765 | { |
1754 | unsigned long long device_id; | 1766 | unsigned long long device_id; |
1755 | int status; | 1767 | int status, device_type; |
1756 | struct acpi_video_device *data; | 1768 | struct acpi_video_device *data; |
1757 | struct acpi_video_device_attrib* attribute; | 1769 | struct acpi_video_device_attrib* attribute; |
1758 | 1770 | ||
@@ -1797,8 +1809,25 @@ acpi_video_bus_get_one_device(struct acpi_device *device, | |||
1797 | } | 1809 | } |
1798 | if(attribute->bios_can_detect) | 1810 | if(attribute->bios_can_detect) |
1799 | data->flags.bios = 1; | 1811 | data->flags.bios = 1; |
1800 | } else | 1812 | } else { |
1801 | data->flags.unknown = 1; | 1813 | /* Check for legacy IDs */ |
1814 | device_type = acpi_video_get_device_type(video, | ||
1815 | device_id); | ||
1816 | /* Ignore bits 16 and 18-20 */ | ||
1817 | switch (device_type & 0xffe2ffff) { | ||
1818 | case ACPI_VIDEO_DISPLAY_LEGACY_MONITOR: | ||
1819 | data->flags.crt = 1; | ||
1820 | break; | ||
1821 | case ACPI_VIDEO_DISPLAY_LEGACY_PANEL: | ||
1822 | data->flags.lcd = 1; | ||
1823 | break; | ||
1824 | case ACPI_VIDEO_DISPLAY_LEGACY_TV: | ||
1825 | data->flags.tvout = 1; | ||
1826 | break; | ||
1827 | default: | ||
1828 | data->flags.unknown = 1; | ||
1829 | } | ||
1830 | } | ||
1802 | 1831 | ||
1803 | acpi_video_device_bind(video, data); | 1832 | acpi_video_device_bind(video, data); |
1804 | acpi_video_device_find_cap(data); | 1833 | acpi_video_device_find_cap(data); |
@@ -2032,6 +2061,71 @@ out: | |||
2032 | return result; | 2061 | return result; |
2033 | } | 2062 | } |
2034 | 2063 | ||
2064 | int acpi_video_get_edid(struct acpi_device *device, int type, int device_id, | ||
2065 | void **edid) | ||
2066 | { | ||
2067 | struct acpi_video_bus *video; | ||
2068 | struct acpi_video_device *video_device; | ||
2069 | union acpi_object *buffer = NULL; | ||
2070 | acpi_status status; | ||
2071 | int i, length; | ||
2072 | |||
2073 | if (!device || !acpi_driver_data(device)) | ||
2074 | return -EINVAL; | ||
2075 | |||
2076 | video = acpi_driver_data(device); | ||
2077 | |||
2078 | for (i = 0; i < video->attached_count; i++) { | ||
2079 | video_device = video->attached_array[i].bind_info; | ||
2080 | length = 256; | ||
2081 | |||
2082 | if (!video_device) | ||
2083 | continue; | ||
2084 | |||
2085 | if (type) { | ||
2086 | switch (type) { | ||
2087 | case ACPI_VIDEO_DISPLAY_CRT: | ||
2088 | if (!video_device->flags.crt) | ||
2089 | continue; | ||
2090 | break; | ||
2091 | case ACPI_VIDEO_DISPLAY_TV: | ||
2092 | if (!video_device->flags.tvout) | ||
2093 | continue; | ||
2094 | break; | ||
2095 | case ACPI_VIDEO_DISPLAY_DVI: | ||
2096 | if (!video_device->flags.dvi) | ||
2097 | continue; | ||
2098 | break; | ||
2099 | case ACPI_VIDEO_DISPLAY_LCD: | ||
2100 | if (!video_device->flags.lcd) | ||
2101 | continue; | ||
2102 | break; | ||
2103 | } | ||
2104 | } else if (video_device->device_id != device_id) { | ||
2105 | continue; | ||
2106 | } | ||
2107 | |||
2108 | status = acpi_video_device_EDID(video_device, &buffer, length); | ||
2109 | |||
2110 | if (ACPI_FAILURE(status) || !buffer || | ||
2111 | buffer->type != ACPI_TYPE_BUFFER) { | ||
2112 | length = 128; | ||
2113 | status = acpi_video_device_EDID(video_device, &buffer, | ||
2114 | length); | ||
2115 | if (ACPI_FAILURE(status) || !buffer || | ||
2116 | buffer->type != ACPI_TYPE_BUFFER) { | ||
2117 | continue; | ||
2118 | } | ||
2119 | } | ||
2120 | |||
2121 | *edid = buffer->buffer.pointer; | ||
2122 | return length; | ||
2123 | } | ||
2124 | |||
2125 | return -ENODEV; | ||
2126 | } | ||
2127 | EXPORT_SYMBOL(acpi_video_get_edid); | ||
2128 | |||
2035 | static int | 2129 | static int |
2036 | acpi_video_bus_get_devices(struct acpi_video_bus *video, | 2130 | acpi_video_bus_get_devices(struct acpi_video_bus *video, |
2037 | struct acpi_device *device) | 2131 | struct acpi_device *device) |
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index fc2f26b9b407..c5fef01b3c95 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c | |||
@@ -250,7 +250,7 @@ static int __init acpi_backlight(char *str) | |||
250 | ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR; | 250 | ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR; |
251 | if (!strcmp("video", str)) | 251 | if (!strcmp("video", str)) |
252 | acpi_video_support |= | 252 | acpi_video_support |= |
253 | ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO; | 253 | ACPI_VIDEO_BACKLIGHT_FORCE_VIDEO; |
254 | } | 254 | } |
255 | return 1; | 255 | return 1; |
256 | } | 256 | } |
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index e68541f662b9..73f883333a0d 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig | |||
@@ -57,6 +57,8 @@ config SATA_PMP | |||
57 | This option adds support for SATA Port Multipliers | 57 | This option adds support for SATA Port Multipliers |
58 | (the SATA version of an ethernet hub, or SAS expander). | 58 | (the SATA version of an ethernet hub, or SAS expander). |
59 | 59 | ||
60 | comment "Controllers with non-SFF native interface" | ||
61 | |||
60 | config SATA_AHCI | 62 | config SATA_AHCI |
61 | tristate "AHCI SATA support" | 63 | tristate "AHCI SATA support" |
62 | depends on PCI | 64 | depends on PCI |
@@ -73,11 +75,12 @@ config SATA_AHCI_PLATFORM | |||
73 | 75 | ||
74 | If unsure, say N. | 76 | If unsure, say N. |
75 | 77 | ||
76 | config SATA_SIL24 | 78 | config SATA_FSL |
77 | tristate "Silicon Image 3124/3132 SATA support" | 79 | tristate "Freescale 3.0Gbps SATA support" |
78 | depends on PCI | 80 | depends on FSL_SOC |
79 | help | 81 | help |
80 | This option enables support for Silicon Image 3124/3132 Serial ATA. | 82 | This option enables support for Freescale 3.0Gbps SATA controller. |
83 | It can be found on MPC837x and MPC8315. | ||
81 | 84 | ||
82 | If unsure, say N. | 85 | If unsure, say N. |
83 | 86 | ||
@@ -87,12 +90,11 @@ config SATA_INIC162X | |||
87 | help | 90 | help |
88 | This option enables support for Initio 162x Serial ATA. | 91 | This option enables support for Initio 162x Serial ATA. |
89 | 92 | ||
90 | config SATA_FSL | 93 | config SATA_SIL24 |
91 | tristate "Freescale 3.0Gbps SATA support" | 94 | tristate "Silicon Image 3124/3132 SATA support" |
92 | depends on FSL_SOC | 95 | depends on PCI |
93 | help | 96 | help |
94 | This option enables support for Freescale 3.0Gbps SATA controller. | 97 | This option enables support for Silicon Image 3124/3132 Serial ATA. |
95 | It can be found on MPC837x and MPC8315. | ||
96 | 98 | ||
97 | If unsure, say N. | 99 | If unsure, say N. |
98 | 100 | ||
@@ -116,15 +118,65 @@ config ATA_SFF | |||
116 | 118 | ||
117 | if ATA_SFF | 119 | if ATA_SFF |
118 | 120 | ||
119 | config SATA_SVW | 121 | comment "SFF controllers with custom DMA interface" |
120 | tristate "ServerWorks Frodo / Apple K2 SATA support" | 122 | |
123 | config PDC_ADMA | ||
124 | tristate "Pacific Digital ADMA support" | ||
121 | depends on PCI | 125 | depends on PCI |
122 | help | 126 | help |
123 | This option enables support for Broadcom/Serverworks/Apple K2 | 127 | This option enables support for Pacific Digital ADMA controllers |
124 | SATA support. | 128 | |
129 | If unsure, say N. | ||
130 | |||
131 | config PATA_MPC52xx | ||
132 | tristate "Freescale MPC52xx SoC internal IDE" | ||
133 | depends on PPC_MPC52xx && PPC_BESTCOMM | ||
134 | select PPC_BESTCOMM_ATA | ||
135 | help | ||
136 | This option enables support for integrated IDE controller | ||
137 | of the Freescale MPC52xx SoC. | ||
138 | |||
139 | If unsure, say N. | ||
140 | |||
141 | config PATA_OCTEON_CF | ||
142 | tristate "OCTEON Boot Bus Compact Flash support" | ||
143 | depends on CPU_CAVIUM_OCTEON | ||
144 | help | ||
145 | This option enables a polled compact flash driver for use with | ||
146 | compact flash cards attached to the OCTEON boot bus. | ||
147 | |||
148 | If unsure, say N. | ||
149 | |||
150 | config SATA_QSTOR | ||
151 | tristate "Pacific Digital SATA QStor support" | ||
152 | depends on PCI | ||
153 | help | ||
154 | This option enables support for Pacific Digital Serial ATA QStor. | ||
155 | |||
156 | If unsure, say N. | ||
157 | |||
158 | config SATA_SX4 | ||
159 | tristate "Promise SATA SX4 support (Experimental)" | ||
160 | depends on PCI && EXPERIMENTAL | ||
161 | help | ||
162 | This option enables support for Promise Serial ATA SX4. | ||
125 | 163 | ||
126 | If unsure, say N. | 164 | If unsure, say N. |
127 | 165 | ||
166 | config ATA_BMDMA | ||
167 | bool "ATA BMDMA support" | ||
168 | default y | ||
169 | help | ||
170 | This option adds support for SFF ATA controllers with BMDMA | ||
171 | capability. BMDMA stands for bus-master DMA and the | ||
172 | de-facto DMA interface for SFF controllers. | ||
173 | |||
174 | If unuser, say Y. | ||
175 | |||
176 | if ATA_BMDMA | ||
177 | |||
178 | comment "SATA SFF controllers with BMDMA" | ||
179 | |||
128 | config ATA_PIIX | 180 | config ATA_PIIX |
129 | tristate "Intel ESB, ICH, PIIX3, PIIX4 PATA/SATA support" | 181 | tristate "Intel ESB, ICH, PIIX3, PIIX4 PATA/SATA support" |
130 | depends on PCI | 182 | depends on PCI |
@@ -152,22 +204,6 @@ config SATA_NV | |||
152 | 204 | ||
153 | If unsure, say N. | 205 | If unsure, say N. |
154 | 206 | ||
155 | config PDC_ADMA | ||
156 | tristate "Pacific Digital ADMA support" | ||
157 | depends on PCI | ||
158 | help | ||
159 | This option enables support for Pacific Digital ADMA controllers | ||
160 | |||
161 | If unsure, say N. | ||
162 | |||
163 | config SATA_QSTOR | ||
164 | tristate "Pacific Digital SATA QStor support" | ||
165 | depends on PCI | ||
166 | help | ||
167 | This option enables support for Pacific Digital Serial ATA QStor. | ||
168 | |||
169 | If unsure, say N. | ||
170 | |||
171 | config SATA_PROMISE | 207 | config SATA_PROMISE |
172 | tristate "Promise SATA TX2/TX4 support" | 208 | tristate "Promise SATA TX2/TX4 support" |
173 | depends on PCI | 209 | depends on PCI |
@@ -176,14 +212,6 @@ config SATA_PROMISE | |||
176 | 212 | ||
177 | If unsure, say N. | 213 | If unsure, say N. |
178 | 214 | ||
179 | config SATA_SX4 | ||
180 | tristate "Promise SATA SX4 support (Experimental)" | ||
181 | depends on PCI && EXPERIMENTAL | ||
182 | help | ||
183 | This option enables support for Promise Serial ATA SX4. | ||
184 | |||
185 | If unsure, say N. | ||
186 | |||
187 | config SATA_SIL | 215 | config SATA_SIL |
188 | tristate "Silicon Image SATA support" | 216 | tristate "Silicon Image SATA support" |
189 | depends on PCI | 217 | depends on PCI |
@@ -203,6 +231,15 @@ config SATA_SIS | |||
203 | enable the PATA_SIS driver in the config. | 231 | enable the PATA_SIS driver in the config. |
204 | If unsure, say N. | 232 | If unsure, say N. |
205 | 233 | ||
234 | config SATA_SVW | ||
235 | tristate "ServerWorks Frodo / Apple K2 SATA support" | ||
236 | depends on PCI | ||
237 | help | ||
238 | This option enables support for Broadcom/Serverworks/Apple K2 | ||
239 | SATA support. | ||
240 | |||
241 | If unsure, say N. | ||
242 | |||
206 | config SATA_ULI | 243 | config SATA_ULI |
207 | tristate "ULi Electronics SATA support" | 244 | tristate "ULi Electronics SATA support" |
208 | depends on PCI | 245 | depends on PCI |
@@ -227,14 +264,7 @@ config SATA_VITESSE | |||
227 | 264 | ||
228 | If unsure, say N. | 265 | If unsure, say N. |
229 | 266 | ||
230 | config PATA_ACPI | 267 | comment "PATA SFF controllers with BMDMA" |
231 | tristate "ACPI firmware driver for PATA" | ||
232 | depends on ATA_ACPI | ||
233 | help | ||
234 | This option enables an ACPI method driver which drives | ||
235 | motherboard PATA controller interfaces through the ACPI | ||
236 | firmware in the BIOS. This driver can sometimes handle | ||
237 | otherwise unsupported hardware. | ||
238 | 268 | ||
239 | config PATA_ALI | 269 | config PATA_ALI |
240 | tristate "ALi PATA support" | 270 | tristate "ALi PATA support" |
@@ -262,40 +292,30 @@ config PATA_ARTOP | |||
262 | 292 | ||
263 | If unsure, say N. | 293 | If unsure, say N. |
264 | 294 | ||
265 | config PATA_ATP867X | 295 | config PATA_ATIIXP |
266 | tristate "ARTOP/Acard ATP867X PATA support" | 296 | tristate "ATI PATA support" |
267 | depends on PCI | 297 | depends on PCI |
268 | help | 298 | help |
269 | This option enables support for ARTOP/Acard ATP867X PATA | 299 | This option enables support for the ATI ATA interfaces |
270 | controllers. | 300 | found on the many ATI chipsets. |
271 | |||
272 | If unsure, say N. | ||
273 | |||
274 | config PATA_AT32 | ||
275 | tristate "Atmel AVR32 PATA support (Experimental)" | ||
276 | depends on AVR32 && PLATFORM_AT32AP && EXPERIMENTAL | ||
277 | help | ||
278 | This option enables support for the IDE devices on the | ||
279 | Atmel AT32AP platform. | ||
280 | 301 | ||
281 | If unsure, say N. | 302 | If unsure, say N. |
282 | 303 | ||
283 | config PATA_ATIIXP | 304 | config PATA_ATP867X |
284 | tristate "ATI PATA support" | 305 | tristate "ARTOP/Acard ATP867X PATA support" |
285 | depends on PCI | 306 | depends on PCI |
286 | help | 307 | help |
287 | This option enables support for the ATI ATA interfaces | 308 | This option enables support for ARTOP/Acard ATP867X PATA |
288 | found on the many ATI chipsets. | 309 | controllers. |
289 | 310 | ||
290 | If unsure, say N. | 311 | If unsure, say N. |
291 | 312 | ||
292 | config PATA_CMD640_PCI | 313 | config PATA_BF54X |
293 | tristate "CMD640 PCI PATA support (Experimental)" | 314 | tristate "Blackfin 54x ATAPI support" |
294 | depends on PCI && EXPERIMENTAL | 315 | depends on BF542 || BF548 || BF549 |
295 | help | 316 | help |
296 | This option enables support for the CMD640 PCI IDE | 317 | This option enables support for the built-in ATAPI controller on |
297 | interface chip. Only the primary channel is currently | 318 | Blackfin 54x family chips. |
298 | supported. | ||
299 | 319 | ||
300 | If unsure, say N. | 320 | If unsure, say N. |
301 | 321 | ||
@@ -362,15 +382,6 @@ config PATA_EFAR | |||
362 | 382 | ||
363 | If unsure, say N. | 383 | If unsure, say N. |
364 | 384 | ||
365 | config ATA_GENERIC | ||
366 | tristate "Generic ATA support" | ||
367 | depends on PCI | ||
368 | help | ||
369 | This option enables support for generic BIOS configured | ||
370 | ATA controllers via the new ATA layer | ||
371 | |||
372 | If unsure, say N. | ||
373 | |||
374 | config PATA_HPT366 | 385 | config PATA_HPT366 |
375 | tristate "HPT 366/368 PATA support" | 386 | tristate "HPT 366/368 PATA support" |
376 | depends on PCI | 387 | depends on PCI |
@@ -415,12 +426,20 @@ config PATA_HPT3X3_DMA | |||
415 | controllers. Enable with care as there are still some | 426 | controllers. Enable with care as there are still some |
416 | problems with DMA on this chipset. | 427 | problems with DMA on this chipset. |
417 | 428 | ||
418 | config PATA_ISAPNP | 429 | config PATA_ICSIDE |
419 | tristate "ISA Plug and Play PATA support" | 430 | tristate "Acorn ICS PATA support" |
420 | depends on ISAPNP | 431 | depends on ARM && ARCH_ACORN |
421 | help | 432 | help |
422 | This option enables support for ISA plug & play ATA | 433 | On Acorn systems, say Y here if you wish to use the ICS PATA |
423 | controllers such as those found on old soundcards. | 434 | interface card. This is not required for ICS partition support. |
435 | If you are unsure, say N to this. | ||
436 | |||
437 | config PATA_IT8213 | ||
438 | tristate "IT8213 PATA support (Experimental)" | ||
439 | depends on PCI && EXPERIMENTAL | ||
440 | help | ||
441 | This option enables support for the ITE 821 PATA | ||
442 | controllers via the new ATA layer. | ||
424 | 443 | ||
425 | If unsure, say N. | 444 | If unsure, say N. |
426 | 445 | ||
@@ -434,15 +453,6 @@ config PATA_IT821X | |||
434 | 453 | ||
435 | If unsure, say N. | 454 | If unsure, say N. |
436 | 455 | ||
437 | config PATA_IT8213 | ||
438 | tristate "IT8213 PATA support (Experimental)" | ||
439 | depends on PCI && EXPERIMENTAL | ||
440 | help | ||
441 | This option enables support for the ITE 821 PATA | ||
442 | controllers via the new ATA layer. | ||
443 | |||
444 | If unsure, say N. | ||
445 | |||
446 | config PATA_JMICRON | 456 | config PATA_JMICRON |
447 | tristate "JMicron PATA support" | 457 | tristate "JMicron PATA support" |
448 | depends on PCI | 458 | depends on PCI |
@@ -452,23 +462,14 @@ config PATA_JMICRON | |||
452 | 462 | ||
453 | If unsure, say N. | 463 | If unsure, say N. |
454 | 464 | ||
455 | config PATA_LEGACY | 465 | config PATA_MACIO |
456 | tristate "Legacy ISA PATA support (Experimental)" | 466 | tristate "Apple PowerMac/PowerBook internal 'MacIO' IDE" |
457 | depends on (ISA || PCI) && EXPERIMENTAL | 467 | depends on PPC_PMAC |
458 | help | ||
459 | This option enables support for ISA/VLB/PCI bus legacy PATA | ||
460 | ports and allows them to be accessed via the new ATA layer. | ||
461 | |||
462 | If unsure, say N. | ||
463 | |||
464 | config PATA_TRIFLEX | ||
465 | tristate "Compaq Triflex PATA support" | ||
466 | depends on PCI | ||
467 | help | 468 | help |
468 | Enable support for the Compaq 'Triflex' IDE controller as found | 469 | Most IDE capable PowerMacs have IDE busses driven by a variant |
469 | on many Compaq Pentium-Pro systems, via the new ATA layer. | 470 | of this controller which is part of the Apple chipset used on |
470 | 471 | most PowerMac models. Some models have multiple busses using | |
471 | If unsure, say N. | 472 | different chipsets, though generally, MacIO is one of them. |
472 | 473 | ||
473 | config PATA_MARVELL | 474 | config PATA_MARVELL |
474 | tristate "Marvell PATA support via legacy mode" | 475 | tristate "Marvell PATA support via legacy mode" |
@@ -481,32 +482,6 @@ config PATA_MARVELL | |||
481 | 482 | ||
482 | If unsure, say N. | 483 | If unsure, say N. |
483 | 484 | ||
484 | config PATA_MPC52xx | ||
485 | tristate "Freescale MPC52xx SoC internal IDE" | ||
486 | depends on PPC_MPC52xx && PPC_BESTCOMM | ||
487 | select PPC_BESTCOMM_ATA | ||
488 | help | ||
489 | This option enables support for integrated IDE controller | ||
490 | of the Freescale MPC52xx SoC. | ||
491 | |||
492 | If unsure, say N. | ||
493 | |||
494 | config PATA_MPIIX | ||
495 | tristate "Intel PATA MPIIX support" | ||
496 | depends on PCI | ||
497 | help | ||
498 | This option enables support for MPIIX PATA support. | ||
499 | |||
500 | If unsure, say N. | ||
501 | |||
502 | config PATA_OLDPIIX | ||
503 | tristate "Intel PATA old PIIX support" | ||
504 | depends on PCI | ||
505 | help | ||
506 | This option enables support for early PIIX PATA support. | ||
507 | |||
508 | If unsure, say N. | ||
509 | |||
510 | config PATA_NETCELL | 485 | config PATA_NETCELL |
511 | tristate "NETCELL Revolution RAID support" | 486 | tristate "NETCELL Revolution RAID support" |
512 | depends on PCI | 487 | depends on PCI |
@@ -525,15 +500,6 @@ config PATA_NINJA32 | |||
525 | 500 | ||
526 | If unsure, say N. | 501 | If unsure, say N. |
527 | 502 | ||
528 | config PATA_NS87410 | ||
529 | tristate "Nat Semi NS87410 PATA support" | ||
530 | depends on PCI | ||
531 | help | ||
532 | This option enables support for the National Semiconductor | ||
533 | NS87410 PCI-IDE controller. | ||
534 | |||
535 | If unsure, say N. | ||
536 | |||
537 | config PATA_NS87415 | 503 | config PATA_NS87415 |
538 | tristate "Nat Semi NS87415 PATA support" | 504 | tristate "Nat Semi NS87415 PATA support" |
539 | depends on PCI | 505 | depends on PCI |
@@ -543,12 +509,11 @@ config PATA_NS87415 | |||
543 | 509 | ||
544 | If unsure, say N. | 510 | If unsure, say N. |
545 | 511 | ||
546 | config PATA_OPTI | 512 | config PATA_OLDPIIX |
547 | tristate "OPTI621/6215 PATA support (Very Experimental)" | 513 | tristate "Intel PATA old PIIX support" |
548 | depends on PCI && EXPERIMENTAL | 514 | depends on PCI |
549 | help | 515 | help |
550 | This option enables full PIO support for the early Opti ATA | 516 | This option enables support for early PIIX PATA support. |
551 | controllers found on some old motherboards. | ||
552 | 517 | ||
553 | If unsure, say N. | 518 | If unsure, say N. |
554 | 519 | ||
@@ -562,24 +527,6 @@ config PATA_OPTIDMA | |||
562 | 527 | ||
563 | If unsure, say N. | 528 | If unsure, say N. |
564 | 529 | ||
565 | config PATA_PALMLD | ||
566 | tristate "Palm LifeDrive PATA support" | ||
567 | depends on MACH_PALMLD | ||
568 | help | ||
569 | This option enables support for Palm LifeDrive's internal ATA | ||
570 | port via the new ATA layer. | ||
571 | |||
572 | If unsure, say N. | ||
573 | |||
574 | config PATA_PCMCIA | ||
575 | tristate "PCMCIA PATA support" | ||
576 | depends on PCMCIA | ||
577 | help | ||
578 | This option enables support for PCMCIA ATA interfaces, including | ||
579 | compact flash card adapters via the new ATA layer. | ||
580 | |||
581 | If unsure, say N. | ||
582 | |||
583 | config PATA_PDC2027X | 530 | config PATA_PDC2027X |
584 | tristate "Promise PATA 2027x support" | 531 | tristate "Promise PATA 2027x support" |
585 | depends on PCI | 532 | depends on PCI |
@@ -597,12 +544,6 @@ config PATA_PDC_OLD | |||
597 | 544 | ||
598 | If unsure, say N. | 545 | If unsure, say N. |
599 | 546 | ||
600 | config PATA_QDI | ||
601 | tristate "QDI VLB PATA support" | ||
602 | depends on ISA | ||
603 | help | ||
604 | Support for QDI 6500 and 6580 PATA controllers on VESA local bus. | ||
605 | |||
606 | config PATA_RADISYS | 547 | config PATA_RADISYS |
607 | tristate "RADISYS 82600 PATA support (Experimental)" | 548 | tristate "RADISYS 82600 PATA support (Experimental)" |
608 | depends on PCI && EXPERIMENTAL | 549 | depends on PCI && EXPERIMENTAL |
@@ -612,15 +553,6 @@ config PATA_RADISYS | |||
612 | 553 | ||
613 | If unsure, say N. | 554 | If unsure, say N. |
614 | 555 | ||
615 | config PATA_RB532 | ||
616 | tristate "RouterBoard 532 PATA CompactFlash support" | ||
617 | depends on MIKROTIK_RB532 | ||
618 | help | ||
619 | This option enables support for the RouterBoard 532 | ||
620 | PATA CompactFlash controller. | ||
621 | |||
622 | If unsure, say N. | ||
623 | |||
624 | config PATA_RDC | 556 | config PATA_RDC |
625 | tristate "RDC PATA support" | 557 | tristate "RDC PATA support" |
626 | depends on PCI | 558 | depends on PCI |
@@ -631,21 +563,30 @@ config PATA_RDC | |||
631 | 563 | ||
632 | If unsure, say N. | 564 | If unsure, say N. |
633 | 565 | ||
634 | config PATA_RZ1000 | 566 | config PATA_SC1200 |
635 | tristate "PC Tech RZ1000 PATA support" | 567 | tristate "SC1200 PATA support" |
636 | depends on PCI | 568 | depends on PCI |
637 | help | 569 | help |
638 | This option enables basic support for the PC Tech RZ1000/1 | 570 | This option enables support for the NatSemi/AMD SC1200 SoC |
639 | PATA controllers via the new ATA layer | 571 | companion chip used with the Geode processor family. |
640 | 572 | ||
641 | If unsure, say N. | 573 | If unsure, say N. |
642 | 574 | ||
643 | config PATA_SC1200 | 575 | config PATA_SCC |
644 | tristate "SC1200 PATA support" | 576 | tristate "Toshiba's Cell Reference Set IDE support" |
577 | depends on PCI && PPC_CELLEB | ||
578 | help | ||
579 | This option enables support for the built-in IDE controller on | ||
580 | Toshiba Cell Reference Board. | ||
581 | |||
582 | If unsure, say N. | ||
583 | |||
584 | config PATA_SCH | ||
585 | tristate "Intel SCH PATA support" | ||
645 | depends on PCI | 586 | depends on PCI |
646 | help | 587 | help |
647 | This option enables support for the NatSemi/AMD SC1200 SoC | 588 | This option enables support for Intel SCH PATA on the Intel |
648 | companion chip used with the Geode processor family. | 589 | SCH (US15W, US15L, UL11L) series host controllers. |
649 | 590 | ||
650 | If unsure, say N. | 591 | If unsure, say N. |
651 | 592 | ||
@@ -683,6 +624,15 @@ config PATA_TOSHIBA | |||
683 | 624 | ||
684 | If unsure, say N. | 625 | If unsure, say N. |
685 | 626 | ||
627 | config PATA_TRIFLEX | ||
628 | tristate "Compaq Triflex PATA support" | ||
629 | depends on PCI | ||
630 | help | ||
631 | Enable support for the Compaq 'Triflex' IDE controller as found | ||
632 | on many Compaq Pentium-Pro systems, via the new ATA layer. | ||
633 | |||
634 | If unsure, say N. | ||
635 | |||
686 | config PATA_VIA | 636 | config PATA_VIA |
687 | tristate "VIA PATA support" | 637 | tristate "VIA PATA support" |
688 | depends on PCI | 638 | depends on PCI |
@@ -701,12 +651,99 @@ config PATA_WINBOND | |||
701 | 651 | ||
702 | If unsure, say N. | 652 | If unsure, say N. |
703 | 653 | ||
704 | config PATA_WINBOND_VLB | 654 | endif # ATA_BMDMA |
705 | tristate "Winbond W83759A VLB PATA support (Experimental)" | 655 | |
706 | depends on ISA && EXPERIMENTAL | 656 | comment "PIO-only SFF controllers" |
657 | |||
658 | config PATA_AT32 | ||
659 | tristate "Atmel AVR32 PATA support (Experimental)" | ||
660 | depends on AVR32 && PLATFORM_AT32AP && EXPERIMENTAL | ||
707 | help | 661 | help |
708 | Support for the Winbond W83759A controller on Vesa Local Bus | 662 | This option enables support for the IDE devices on the |
709 | systems. | 663 | Atmel AT32AP platform. |
664 | |||
665 | If unsure, say N. | ||
666 | |||
667 | config PATA_AT91 | ||
668 | tristate "PATA support for AT91SAM9260" | ||
669 | depends on ARM && ARCH_AT91 | ||
670 | help | ||
671 | This option enables support for IDE devices on the Atmel AT91SAM9260 SoC. | ||
672 | |||
673 | If unsure, say N. | ||
674 | |||
675 | config PATA_CMD640_PCI | ||
676 | tristate "CMD640 PCI PATA support (Experimental)" | ||
677 | depends on PCI && EXPERIMENTAL | ||
678 | help | ||
679 | This option enables support for the CMD640 PCI IDE | ||
680 | interface chip. Only the primary channel is currently | ||
681 | supported. | ||
682 | |||
683 | If unsure, say N. | ||
684 | |||
685 | config PATA_ISAPNP | ||
686 | tristate "ISA Plug and Play PATA support" | ||
687 | depends on ISAPNP | ||
688 | help | ||
689 | This option enables support for ISA plug & play ATA | ||
690 | controllers such as those found on old soundcards. | ||
691 | |||
692 | If unsure, say N. | ||
693 | |||
694 | config PATA_IXP4XX_CF | ||
695 | tristate "IXP4XX Compact Flash support" | ||
696 | depends on ARCH_IXP4XX | ||
697 | help | ||
698 | This option enables support for a Compact Flash connected on | ||
699 | the ixp4xx expansion bus. This driver had been written for | ||
700 | Loft/Avila boards in mind but can work with others. | ||
701 | |||
702 | If unsure, say N. | ||
703 | |||
704 | config PATA_MPIIX | ||
705 | tristate "Intel PATA MPIIX support" | ||
706 | depends on PCI | ||
707 | help | ||
708 | This option enables support for MPIIX PATA support. | ||
709 | |||
710 | If unsure, say N. | ||
711 | |||
712 | config PATA_NS87410 | ||
713 | tristate "Nat Semi NS87410 PATA support" | ||
714 | depends on PCI | ||
715 | help | ||
716 | This option enables support for the National Semiconductor | ||
717 | NS87410 PCI-IDE controller. | ||
718 | |||
719 | If unsure, say N. | ||
720 | |||
721 | config PATA_OPTI | ||
722 | tristate "OPTI621/6215 PATA support (Very Experimental)" | ||
723 | depends on PCI && EXPERIMENTAL | ||
724 | help | ||
725 | This option enables full PIO support for the early Opti ATA | ||
726 | controllers found on some old motherboards. | ||
727 | |||
728 | If unsure, say N. | ||
729 | |||
730 | config PATA_PALMLD | ||
731 | tristate "Palm LifeDrive PATA support" | ||
732 | depends on MACH_PALMLD | ||
733 | help | ||
734 | This option enables support for Palm LifeDrive's internal ATA | ||
735 | port via the new ATA layer. | ||
736 | |||
737 | If unsure, say N. | ||
738 | |||
739 | config PATA_PCMCIA | ||
740 | tristate "PCMCIA PATA support" | ||
741 | depends on PCMCIA | ||
742 | help | ||
743 | This option enables support for PCMCIA ATA interfaces, including | ||
744 | compact flash card adapters via the new ATA layer. | ||
745 | |||
746 | If unsure, say N. | ||
710 | 747 | ||
711 | config HAVE_PATA_PLATFORM | 748 | config HAVE_PATA_PLATFORM |
712 | bool | 749 | bool |
@@ -725,14 +762,6 @@ config PATA_PLATFORM | |||
725 | 762 | ||
726 | If unsure, say N. | 763 | If unsure, say N. |
727 | 764 | ||
728 | config PATA_AT91 | ||
729 | tristate "PATA support for AT91SAM9260" | ||
730 | depends on ARM && ARCH_AT91 | ||
731 | help | ||
732 | This option enables support for IDE devices on the Atmel AT91SAM9260 SoC. | ||
733 | |||
734 | If unsure, say N. | ||
735 | |||
736 | config PATA_OF_PLATFORM | 765 | config PATA_OF_PLATFORM |
737 | tristate "OpenFirmware platform device PATA support" | 766 | tristate "OpenFirmware platform device PATA support" |
738 | depends on PATA_PLATFORM && PPC_OF | 767 | depends on PATA_PLATFORM && PPC_OF |
@@ -743,69 +772,65 @@ config PATA_OF_PLATFORM | |||
743 | 772 | ||
744 | If unsure, say N. | 773 | If unsure, say N. |
745 | 774 | ||
746 | config PATA_ICSIDE | 775 | config PATA_QDI |
747 | tristate "Acorn ICS PATA support" | 776 | tristate "QDI VLB PATA support" |
748 | depends on ARM && ARCH_ACORN | 777 | depends on ISA |
749 | help | 778 | help |
750 | On Acorn systems, say Y here if you wish to use the ICS PATA | 779 | Support for QDI 6500 and 6580 PATA controllers on VESA local bus. |
751 | interface card. This is not required for ICS partition support. | ||
752 | If you are unsure, say N to this. | ||
753 | 780 | ||
754 | config PATA_IXP4XX_CF | 781 | config PATA_RB532 |
755 | tristate "IXP4XX Compact Flash support" | 782 | tristate "RouterBoard 532 PATA CompactFlash support" |
756 | depends on ARCH_IXP4XX | 783 | depends on MIKROTIK_RB532 |
757 | help | 784 | help |
758 | This option enables support for a Compact Flash connected on | 785 | This option enables support for the RouterBoard 532 |
759 | the ixp4xx expansion bus. This driver had been written for | 786 | PATA CompactFlash controller. |
760 | Loft/Avila boards in mind but can work with others. | ||
761 | 787 | ||
762 | If unsure, say N. | 788 | If unsure, say N. |
763 | 789 | ||
764 | config PATA_OCTEON_CF | 790 | config PATA_RZ1000 |
765 | tristate "OCTEON Boot Bus Compact Flash support" | 791 | tristate "PC Tech RZ1000 PATA support" |
766 | depends on CPU_CAVIUM_OCTEON | 792 | depends on PCI |
767 | help | 793 | help |
768 | This option enables a polled compact flash driver for use with | 794 | This option enables basic support for the PC Tech RZ1000/1 |
769 | compact flash cards attached to the OCTEON boot bus. | 795 | PATA controllers via the new ATA layer |
770 | 796 | ||
771 | If unsure, say N. | 797 | If unsure, say N. |
772 | 798 | ||
773 | config PATA_SCC | 799 | config PATA_WINBOND_VLB |
774 | tristate "Toshiba's Cell Reference Set IDE support" | 800 | tristate "Winbond W83759A VLB PATA support (Experimental)" |
775 | depends on PCI && PPC_CELLEB | 801 | depends on ISA && EXPERIMENTAL |
776 | help | 802 | help |
777 | This option enables support for the built-in IDE controller on | 803 | Support for the Winbond W83759A controller on Vesa Local Bus |
778 | Toshiba Cell Reference Board. | 804 | systems. |
779 | 805 | ||
780 | If unsure, say N. | 806 | comment "Generic fallback / legacy drivers" |
781 | 807 | ||
782 | config PATA_SCH | 808 | config PATA_ACPI |
783 | tristate "Intel SCH PATA support" | 809 | tristate "ACPI firmware driver for PATA" |
784 | depends on PCI | 810 | depends on ATA_ACPI && ATA_BMDMA |
785 | help | 811 | help |
786 | This option enables support for Intel SCH PATA on the Intel | 812 | This option enables an ACPI method driver which drives |
787 | SCH (US15W, US15L, UL11L) series host controllers. | 813 | motherboard PATA controller interfaces through the ACPI |
788 | 814 | firmware in the BIOS. This driver can sometimes handle | |
789 | If unsure, say N. | 815 | otherwise unsupported hardware. |
790 | 816 | ||
791 | config PATA_BF54X | 817 | config ATA_GENERIC |
792 | tristate "Blackfin 54x ATAPI support" | 818 | tristate "Generic ATA support" |
793 | depends on BF542 || BF548 || BF549 | 819 | depends on PCI && ATA_BMDMA |
794 | help | 820 | help |
795 | This option enables support for the built-in ATAPI controller on | 821 | This option enables support for generic BIOS configured |
796 | Blackfin 54x family chips. | 822 | ATA controllers via the new ATA layer |
797 | 823 | ||
798 | If unsure, say N. | 824 | If unsure, say N. |
799 | 825 | ||
800 | config PATA_MACIO | 826 | config PATA_LEGACY |
801 | tristate "Apple PowerMac/PowerBook internal 'MacIO' IDE" | 827 | tristate "Legacy ISA PATA support (Experimental)" |
802 | depends on PPC_PMAC | 828 | depends on (ISA || PCI) && EXPERIMENTAL |
803 | help | 829 | help |
804 | Most IDE capable PowerMacs have IDE busses driven by a variant | 830 | This option enables support for ISA/VLB/PCI bus legacy PATA |
805 | of this controller which is part of the Apple chipset used on | 831 | ports and allows them to be accessed via the new ATA layer. |
806 | most PowerMac models. Some models have multiple busses using | ||
807 | different chipsets, though generally, MacIO is one of them. | ||
808 | 832 | ||
833 | If unsure, say N. | ||
809 | 834 | ||
810 | endif # ATA_SFF | 835 | endif # ATA_SFF |
811 | endif # ATA | 836 | endif # ATA |
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index d0a93c4ad3ec..7ef89d73df63 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile | |||
@@ -1,33 +1,39 @@ | |||
1 | 1 | ||
2 | obj-$(CONFIG_ATA) += libata.o | 2 | obj-$(CONFIG_ATA) += libata.o |
3 | 3 | ||
4 | # non-SFF interface | ||
4 | obj-$(CONFIG_SATA_AHCI) += ahci.o libahci.o | 5 | obj-$(CONFIG_SATA_AHCI) += ahci.o libahci.o |
5 | obj-$(CONFIG_SATA_AHCI_PLATFORM) += ahci_platform.o libahci.o | 6 | obj-$(CONFIG_SATA_AHCI_PLATFORM) += ahci_platform.o libahci.o |
6 | obj-$(CONFIG_SATA_SVW) += sata_svw.o | 7 | obj-$(CONFIG_SATA_FSL) += sata_fsl.o |
8 | obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o | ||
9 | obj-$(CONFIG_SATA_SIL24) += sata_sil24.o | ||
10 | |||
11 | # SFF w/ custom DMA | ||
12 | obj-$(CONFIG_PDC_ADMA) += pdc_adma.o | ||
13 | obj-$(CONFIG_PATA_MPC52xx) += pata_mpc52xx.o | ||
14 | obj-$(CONFIG_PATA_OCTEON_CF) += pata_octeon_cf.o | ||
15 | obj-$(CONFIG_SATA_QSTOR) += sata_qstor.o | ||
16 | obj-$(CONFIG_SATA_SX4) += sata_sx4.o | ||
17 | |||
18 | # SFF SATA w/ BMDMA | ||
7 | obj-$(CONFIG_ATA_PIIX) += ata_piix.o | 19 | obj-$(CONFIG_ATA_PIIX) += ata_piix.o |
20 | obj-$(CONFIG_SATA_MV) += sata_mv.o | ||
21 | obj-$(CONFIG_SATA_NV) += sata_nv.o | ||
8 | obj-$(CONFIG_SATA_PROMISE) += sata_promise.o | 22 | obj-$(CONFIG_SATA_PROMISE) += sata_promise.o |
9 | obj-$(CONFIG_SATA_QSTOR) += sata_qstor.o | ||
10 | obj-$(CONFIG_SATA_SIL) += sata_sil.o | 23 | obj-$(CONFIG_SATA_SIL) += sata_sil.o |
11 | obj-$(CONFIG_SATA_SIL24) += sata_sil24.o | ||
12 | obj-$(CONFIG_SATA_VIA) += sata_via.o | ||
13 | obj-$(CONFIG_SATA_VITESSE) += sata_vsc.o | ||
14 | obj-$(CONFIG_SATA_SIS) += sata_sis.o | 24 | obj-$(CONFIG_SATA_SIS) += sata_sis.o |
15 | obj-$(CONFIG_SATA_SX4) += sata_sx4.o | 25 | obj-$(CONFIG_SATA_SVW) += sata_svw.o |
16 | obj-$(CONFIG_SATA_NV) += sata_nv.o | ||
17 | obj-$(CONFIG_SATA_ULI) += sata_uli.o | 26 | obj-$(CONFIG_SATA_ULI) += sata_uli.o |
18 | obj-$(CONFIG_SATA_MV) += sata_mv.o | 27 | obj-$(CONFIG_SATA_VIA) += sata_via.o |
19 | obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o | 28 | obj-$(CONFIG_SATA_VITESSE) += sata_vsc.o |
20 | obj-$(CONFIG_PDC_ADMA) += pdc_adma.o | ||
21 | obj-$(CONFIG_SATA_FSL) += sata_fsl.o | ||
22 | obj-$(CONFIG_PATA_MACIO) += pata_macio.o | ||
23 | 29 | ||
30 | # SFF PATA w/ BMDMA | ||
24 | obj-$(CONFIG_PATA_ALI) += pata_ali.o | 31 | obj-$(CONFIG_PATA_ALI) += pata_ali.o |
25 | obj-$(CONFIG_PATA_AMD) += pata_amd.o | 32 | obj-$(CONFIG_PATA_AMD) += pata_amd.o |
26 | obj-$(CONFIG_PATA_ARTOP) += pata_artop.o | 33 | obj-$(CONFIG_PATA_ARTOP) += pata_artop.o |
27 | obj-$(CONFIG_PATA_ATP867X) += pata_atp867x.o | ||
28 | obj-$(CONFIG_PATA_AT32) += pata_at32.o | ||
29 | obj-$(CONFIG_PATA_ATIIXP) += pata_atiixp.o | 34 | obj-$(CONFIG_PATA_ATIIXP) += pata_atiixp.o |
30 | obj-$(CONFIG_PATA_CMD640_PCI) += pata_cmd640.o | 35 | obj-$(CONFIG_PATA_ATP867X) += pata_atp867x.o |
36 | obj-$(CONFIG_PATA_BF54X) += pata_bf54x.o | ||
31 | obj-$(CONFIG_PATA_CMD64X) += pata_cmd64x.o | 37 | obj-$(CONFIG_PATA_CMD64X) += pata_cmd64x.o |
32 | obj-$(CONFIG_PATA_CS5520) += pata_cs5520.o | 38 | obj-$(CONFIG_PATA_CS5520) += pata_cs5520.o |
33 | obj-$(CONFIG_PATA_CS5530) += pata_cs5530.o | 39 | obj-$(CONFIG_PATA_CS5530) += pata_cs5530.o |
@@ -39,47 +45,50 @@ obj-$(CONFIG_PATA_HPT366) += pata_hpt366.o | |||
39 | obj-$(CONFIG_PATA_HPT37X) += pata_hpt37x.o | 45 | obj-$(CONFIG_PATA_HPT37X) += pata_hpt37x.o |
40 | obj-$(CONFIG_PATA_HPT3X2N) += pata_hpt3x2n.o | 46 | obj-$(CONFIG_PATA_HPT3X2N) += pata_hpt3x2n.o |
41 | obj-$(CONFIG_PATA_HPT3X3) += pata_hpt3x3.o | 47 | obj-$(CONFIG_PATA_HPT3X3) += pata_hpt3x3.o |
42 | obj-$(CONFIG_PATA_ISAPNP) += pata_isapnp.o | 48 | obj-$(CONFIG_PATA_ICSIDE) += pata_icside.o |
43 | obj-$(CONFIG_PATA_IT821X) += pata_it821x.o | ||
44 | obj-$(CONFIG_PATA_IT8213) += pata_it8213.o | 49 | obj-$(CONFIG_PATA_IT8213) += pata_it8213.o |
50 | obj-$(CONFIG_PATA_IT821X) += pata_it821x.o | ||
45 | obj-$(CONFIG_PATA_JMICRON) += pata_jmicron.o | 51 | obj-$(CONFIG_PATA_JMICRON) += pata_jmicron.o |
52 | obj-$(CONFIG_PATA_MACIO) += pata_macio.o | ||
53 | obj-$(CONFIG_PATA_MARVELL) += pata_marvell.o | ||
46 | obj-$(CONFIG_PATA_NETCELL) += pata_netcell.o | 54 | obj-$(CONFIG_PATA_NETCELL) += pata_netcell.o |
47 | obj-$(CONFIG_PATA_NINJA32) += pata_ninja32.o | 55 | obj-$(CONFIG_PATA_NINJA32) += pata_ninja32.o |
48 | obj-$(CONFIG_PATA_NS87410) += pata_ns87410.o | ||
49 | obj-$(CONFIG_PATA_NS87415) += pata_ns87415.o | 56 | obj-$(CONFIG_PATA_NS87415) += pata_ns87415.o |
50 | obj-$(CONFIG_PATA_OPTI) += pata_opti.o | ||
51 | obj-$(CONFIG_PATA_OPTIDMA) += pata_optidma.o | ||
52 | obj-$(CONFIG_PATA_MPC52xx) += pata_mpc52xx.o | ||
53 | obj-$(CONFIG_PATA_MARVELL) += pata_marvell.o | ||
54 | obj-$(CONFIG_PATA_MPIIX) += pata_mpiix.o | ||
55 | obj-$(CONFIG_PATA_OLDPIIX) += pata_oldpiix.o | 57 | obj-$(CONFIG_PATA_OLDPIIX) += pata_oldpiix.o |
56 | obj-$(CONFIG_PATA_PALMLD) += pata_palmld.o | 58 | obj-$(CONFIG_PATA_OPTIDMA) += pata_optidma.o |
57 | obj-$(CONFIG_PATA_PCMCIA) += pata_pcmcia.o | ||
58 | obj-$(CONFIG_PATA_PDC2027X) += pata_pdc2027x.o | 59 | obj-$(CONFIG_PATA_PDC2027X) += pata_pdc2027x.o |
59 | obj-$(CONFIG_PATA_PDC_OLD) += pata_pdc202xx_old.o | 60 | obj-$(CONFIG_PATA_PDC_OLD) += pata_pdc202xx_old.o |
60 | obj-$(CONFIG_PATA_QDI) += pata_qdi.o | ||
61 | obj-$(CONFIG_PATA_RADISYS) += pata_radisys.o | 61 | obj-$(CONFIG_PATA_RADISYS) += pata_radisys.o |
62 | obj-$(CONFIG_PATA_RB532) += pata_rb532_cf.o | ||
63 | obj-$(CONFIG_PATA_RDC) += pata_rdc.o | 62 | obj-$(CONFIG_PATA_RDC) += pata_rdc.o |
64 | obj-$(CONFIG_PATA_RZ1000) += pata_rz1000.o | ||
65 | obj-$(CONFIG_PATA_SC1200) += pata_sc1200.o | 63 | obj-$(CONFIG_PATA_SC1200) += pata_sc1200.o |
64 | obj-$(CONFIG_PATA_SCC) += pata_scc.o | ||
65 | obj-$(CONFIG_PATA_SCH) += pata_sch.o | ||
66 | obj-$(CONFIG_PATA_SERVERWORKS) += pata_serverworks.o | 66 | obj-$(CONFIG_PATA_SERVERWORKS) += pata_serverworks.o |
67 | obj-$(CONFIG_PATA_SIL680) += pata_sil680.o | 67 | obj-$(CONFIG_PATA_SIL680) += pata_sil680.o |
68 | obj-$(CONFIG_PATA_SIS) += pata_sis.o | ||
68 | obj-$(CONFIG_PATA_TOSHIBA) += pata_piccolo.o | 69 | obj-$(CONFIG_PATA_TOSHIBA) += pata_piccolo.o |
70 | obj-$(CONFIG_PATA_TRIFLEX) += pata_triflex.o | ||
69 | obj-$(CONFIG_PATA_VIA) += pata_via.o | 71 | obj-$(CONFIG_PATA_VIA) += pata_via.o |
70 | obj-$(CONFIG_PATA_WINBOND) += pata_sl82c105.o | 72 | obj-$(CONFIG_PATA_WINBOND) += pata_sl82c105.o |
71 | obj-$(CONFIG_PATA_WINBOND_VLB) += pata_winbond.o | 73 | |
72 | obj-$(CONFIG_PATA_SIS) += pata_sis.o | 74 | # SFF PIO only |
73 | obj-$(CONFIG_PATA_TRIFLEX) += pata_triflex.o | 75 | obj-$(CONFIG_PATA_AT32) += pata_at32.o |
76 | obj-$(CONFIG_PATA_AT91) += pata_at91.o | ||
77 | obj-$(CONFIG_PATA_CMD640_PCI) += pata_cmd640.o | ||
78 | obj-$(CONFIG_PATA_ISAPNP) += pata_isapnp.o | ||
74 | obj-$(CONFIG_PATA_IXP4XX_CF) += pata_ixp4xx_cf.o | 79 | obj-$(CONFIG_PATA_IXP4XX_CF) += pata_ixp4xx_cf.o |
75 | obj-$(CONFIG_PATA_SCC) += pata_scc.o | 80 | obj-$(CONFIG_PATA_MPIIX) += pata_mpiix.o |
76 | obj-$(CONFIG_PATA_SCH) += pata_sch.o | 81 | obj-$(CONFIG_PATA_NS87410) += pata_ns87410.o |
77 | obj-$(CONFIG_PATA_BF54X) += pata_bf54x.o | 82 | obj-$(CONFIG_PATA_OPTI) += pata_opti.o |
78 | obj-$(CONFIG_PATA_OCTEON_CF) += pata_octeon_cf.o | 83 | obj-$(CONFIG_PATA_PCMCIA) += pata_pcmcia.o |
84 | obj-$(CONFIG_PATA_PALMLD) += pata_palmld.o | ||
79 | obj-$(CONFIG_PATA_PLATFORM) += pata_platform.o | 85 | obj-$(CONFIG_PATA_PLATFORM) += pata_platform.o |
80 | obj-$(CONFIG_PATA_AT91) += pata_at91.o | ||
81 | obj-$(CONFIG_PATA_OF_PLATFORM) += pata_of_platform.o | 86 | obj-$(CONFIG_PATA_OF_PLATFORM) += pata_of_platform.o |
82 | obj-$(CONFIG_PATA_ICSIDE) += pata_icside.o | 87 | obj-$(CONFIG_PATA_QDI) += pata_qdi.o |
88 | obj-$(CONFIG_PATA_RB532) += pata_rb532_cf.o | ||
89 | obj-$(CONFIG_PATA_RZ1000) += pata_rz1000.o | ||
90 | obj-$(CONFIG_PATA_WINBOND_VLB) += pata_winbond.o | ||
91 | |||
83 | # Should be last but two libata driver | 92 | # Should be last but two libata driver |
84 | obj-$(CONFIG_PATA_ACPI) += pata_acpi.o | 93 | obj-$(CONFIG_PATA_ACPI) += pata_acpi.o |
85 | # Should be last but one libata driver | 94 | # Should be last but one libata driver |
diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c index 33fb614f9784..573158a9668d 100644 --- a/drivers/ata/ata_generic.c +++ b/drivers/ata/ata_generic.c | |||
@@ -155,7 +155,7 @@ static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id | |||
155 | return rc; | 155 | return rc; |
156 | pcim_pin_device(dev); | 156 | pcim_pin_device(dev); |
157 | } | 157 | } |
158 | return ata_pci_sff_init_one(dev, ppi, &generic_sht, NULL, 0); | 158 | return ata_pci_bmdma_init_one(dev, ppi, &generic_sht, NULL, 0); |
159 | } | 159 | } |
160 | 160 | ||
161 | static struct pci_device_id ata_generic[] = { | 161 | static struct pci_device_id ata_generic[] = { |
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index ec52fc618763..7409f98d2ae6 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c | |||
@@ -1589,7 +1589,7 @@ static int __devinit piix_init_one(struct pci_dev *pdev, | |||
1589 | hpriv->map = piix_init_sata_map(pdev, port_info, | 1589 | hpriv->map = piix_init_sata_map(pdev, port_info, |
1590 | piix_map_db_table[ent->driver_data]); | 1590 | piix_map_db_table[ent->driver_data]); |
1591 | 1591 | ||
1592 | rc = ata_pci_sff_prepare_host(pdev, ppi, &host); | 1592 | rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host); |
1593 | if (rc) | 1593 | if (rc) |
1594 | return rc; | 1594 | return rc; |
1595 | host->private_data = hpriv; | 1595 | host->private_data = hpriv; |
@@ -1626,7 +1626,7 @@ static int __devinit piix_init_one(struct pci_dev *pdev, | |||
1626 | host->flags |= ATA_HOST_PARALLEL_SCAN; | 1626 | host->flags |= ATA_HOST_PARALLEL_SCAN; |
1627 | 1627 | ||
1628 | pci_set_master(pdev); | 1628 | pci_set_master(pdev); |
1629 | return ata_pci_sff_activate_host(host, ata_sff_interrupt, &piix_sht); | 1629 | return ata_pci_sff_activate_host(host, ata_bmdma_interrupt, &piix_sht); |
1630 | } | 1630 | } |
1631 | 1631 | ||
1632 | static void piix_remove_one(struct pci_dev *pdev) | 1632 | static void piix_remove_one(struct pci_dev *pdev) |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index c47373f01f89..06b7e49e039c 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -160,6 +160,10 @@ int libata_allow_tpm = 0; | |||
160 | module_param_named(allow_tpm, libata_allow_tpm, int, 0444); | 160 | module_param_named(allow_tpm, libata_allow_tpm, int, 0444); |
161 | MODULE_PARM_DESC(allow_tpm, "Permit the use of TPM commands (0=off [default], 1=on)"); | 161 | MODULE_PARM_DESC(allow_tpm, "Permit the use of TPM commands (0=off [default], 1=on)"); |
162 | 162 | ||
163 | static int atapi_an; | ||
164 | module_param(atapi_an, int, 0444); | ||
165 | MODULE_PARM_DESC(atapi_an, "Enable ATAPI AN media presence notification (0=0ff [default], 1=on)"); | ||
166 | |||
163 | MODULE_AUTHOR("Jeff Garzik"); | 167 | MODULE_AUTHOR("Jeff Garzik"); |
164 | MODULE_DESCRIPTION("Library module for ATA devices"); | 168 | MODULE_DESCRIPTION("Library module for ATA devices"); |
165 | MODULE_LICENSE("GPL"); | 169 | MODULE_LICENSE("GPL"); |
@@ -2122,6 +2126,14 @@ retry: | |||
2122 | goto err_out; | 2126 | goto err_out; |
2123 | } | 2127 | } |
2124 | 2128 | ||
2129 | if (dev->horkage & ATA_HORKAGE_DUMP_ID) { | ||
2130 | ata_dev_printk(dev, KERN_DEBUG, "dumping IDENTIFY data, " | ||
2131 | "class=%d may_fallback=%d tried_spinup=%d\n", | ||
2132 | class, may_fallback, tried_spinup); | ||
2133 | print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, | ||
2134 | 16, 2, id, ATA_ID_WORDS * sizeof(*id), true); | ||
2135 | } | ||
2136 | |||
2125 | /* Falling back doesn't make sense if ID data was read | 2137 | /* Falling back doesn't make sense if ID data was read |
2126 | * successfully at least once. | 2138 | * successfully at least once. |
2127 | */ | 2139 | */ |
@@ -2510,7 +2522,8 @@ int ata_dev_configure(struct ata_device *dev) | |||
2510 | * to enable ATAPI AN to discern between PHY status | 2522 | * to enable ATAPI AN to discern between PHY status |
2511 | * changed notifications and ATAPI ANs. | 2523 | * changed notifications and ATAPI ANs. |
2512 | */ | 2524 | */ |
2513 | if ((ap->flags & ATA_FLAG_AN) && ata_id_has_atapi_AN(id) && | 2525 | if (atapi_an && |
2526 | (ap->flags & ATA_FLAG_AN) && ata_id_has_atapi_AN(id) && | ||
2514 | (!sata_pmp_attached(ap) || | 2527 | (!sata_pmp_attached(ap) || |
2515 | sata_scr_read(&ap->link, SCR_NOTIFICATION, &sntf) == 0)) { | 2528 | sata_scr_read(&ap->link, SCR_NOTIFICATION, &sntf) == 0)) { |
2516 | unsigned int err_mask; | 2529 | unsigned int err_mask; |
@@ -6372,6 +6385,7 @@ static int __init ata_parse_force_one(char **cur, | |||
6372 | { "3.0Gbps", .spd_limit = 2 }, | 6385 | { "3.0Gbps", .spd_limit = 2 }, |
6373 | { "noncq", .horkage_on = ATA_HORKAGE_NONCQ }, | 6386 | { "noncq", .horkage_on = ATA_HORKAGE_NONCQ }, |
6374 | { "ncq", .horkage_off = ATA_HORKAGE_NONCQ }, | 6387 | { "ncq", .horkage_off = ATA_HORKAGE_NONCQ }, |
6388 | { "dump_id", .horkage_on = ATA_HORKAGE_DUMP_ID }, | ||
6375 | { "pio0", .xfer_mask = 1 << (ATA_SHIFT_PIO + 0) }, | 6389 | { "pio0", .xfer_mask = 1 << (ATA_SHIFT_PIO + 0) }, |
6376 | { "pio1", .xfer_mask = 1 << (ATA_SHIFT_PIO + 1) }, | 6390 | { "pio1", .xfer_mask = 1 << (ATA_SHIFT_PIO + 1) }, |
6377 | { "pio2", .xfer_mask = 1 << (ATA_SHIFT_PIO + 2) }, | 6391 | { "pio2", .xfer_mask = 1 << (ATA_SHIFT_PIO + 2) }, |
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 19ddf924944f..efa4a18cfb9d 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
@@ -63,7 +63,6 @@ const struct ata_port_operations ata_sff_port_ops = { | |||
63 | .sff_tf_read = ata_sff_tf_read, | 63 | .sff_tf_read = ata_sff_tf_read, |
64 | .sff_exec_command = ata_sff_exec_command, | 64 | .sff_exec_command = ata_sff_exec_command, |
65 | .sff_data_xfer = ata_sff_data_xfer, | 65 | .sff_data_xfer = ata_sff_data_xfer, |
66 | .sff_irq_clear = ata_sff_irq_clear, | ||
67 | .sff_drain_fifo = ata_sff_drain_fifo, | 66 | .sff_drain_fifo = ata_sff_drain_fifo, |
68 | 67 | ||
69 | .lost_interrupt = ata_sff_lost_interrupt, | 68 | .lost_interrupt = ata_sff_lost_interrupt, |
@@ -395,33 +394,12 @@ void ata_sff_irq_on(struct ata_port *ap) | |||
395 | ata_sff_set_devctl(ap, ap->ctl); | 394 | ata_sff_set_devctl(ap, ap->ctl); |
396 | ata_wait_idle(ap); | 395 | ata_wait_idle(ap); |
397 | 396 | ||
398 | ap->ops->sff_irq_clear(ap); | 397 | if (ap->ops->sff_irq_clear) |
398 | ap->ops->sff_irq_clear(ap); | ||
399 | } | 399 | } |
400 | EXPORT_SYMBOL_GPL(ata_sff_irq_on); | 400 | EXPORT_SYMBOL_GPL(ata_sff_irq_on); |
401 | 401 | ||
402 | /** | 402 | /** |
403 | * ata_sff_irq_clear - Clear PCI IDE BMDMA interrupt. | ||
404 | * @ap: Port associated with this ATA transaction. | ||
405 | * | ||
406 | * Clear interrupt and error flags in DMA status register. | ||
407 | * | ||
408 | * May be used as the irq_clear() entry in ata_port_operations. | ||
409 | * | ||
410 | * LOCKING: | ||
411 | * spin_lock_irqsave(host lock) | ||
412 | */ | ||
413 | void ata_sff_irq_clear(struct ata_port *ap) | ||
414 | { | ||
415 | void __iomem *mmio = ap->ioaddr.bmdma_addr; | ||
416 | |||
417 | if (!mmio) | ||
418 | return; | ||
419 | |||
420 | iowrite8(ioread8(mmio + ATA_DMA_STATUS), mmio + ATA_DMA_STATUS); | ||
421 | } | ||
422 | EXPORT_SYMBOL_GPL(ata_sff_irq_clear); | ||
423 | |||
424 | /** | ||
425 | * ata_sff_tf_load - send taskfile registers to host controller | 403 | * ata_sff_tf_load - send taskfile registers to host controller |
426 | * @ap: Port to which output is sent | 404 | * @ap: Port to which output is sent |
427 | * @tf: ATA taskfile register set | 405 | * @tf: ATA taskfile register set |
@@ -820,11 +798,15 @@ static void atapi_send_cdb(struct ata_port *ap, struct ata_queued_cmd *qc) | |||
820 | case ATAPI_PROT_NODATA: | 798 | case ATAPI_PROT_NODATA: |
821 | ap->hsm_task_state = HSM_ST_LAST; | 799 | ap->hsm_task_state = HSM_ST_LAST; |
822 | break; | 800 | break; |
801 | #ifdef CONFIG_ATA_BMDMA | ||
823 | case ATAPI_PROT_DMA: | 802 | case ATAPI_PROT_DMA: |
824 | ap->hsm_task_state = HSM_ST_LAST; | 803 | ap->hsm_task_state = HSM_ST_LAST; |
825 | /* initiate bmdma */ | 804 | /* initiate bmdma */ |
826 | ap->ops->bmdma_start(qc); | 805 | ap->ops->bmdma_start(qc); |
827 | break; | 806 | break; |
807 | #endif /* CONFIG_ATA_BMDMA */ | ||
808 | default: | ||
809 | BUG(); | ||
828 | } | 810 | } |
829 | } | 811 | } |
830 | 812 | ||
@@ -1491,27 +1473,27 @@ bool ata_sff_qc_fill_rtf(struct ata_queued_cmd *qc) | |||
1491 | } | 1473 | } |
1492 | EXPORT_SYMBOL_GPL(ata_sff_qc_fill_rtf); | 1474 | EXPORT_SYMBOL_GPL(ata_sff_qc_fill_rtf); |
1493 | 1475 | ||
1494 | /** | 1476 | static unsigned int ata_sff_idle_irq(struct ata_port *ap) |
1495 | * ata_sff_host_intr - Handle host interrupt for given (port, task) | ||
1496 | * @ap: Port on which interrupt arrived (possibly...) | ||
1497 | * @qc: Taskfile currently active in engine | ||
1498 | * | ||
1499 | * Handle host interrupt for given queued command. Currently, | ||
1500 | * only DMA interrupts are handled. All other commands are | ||
1501 | * handled via polling with interrupts disabled (nIEN bit). | ||
1502 | * | ||
1503 | * LOCKING: | ||
1504 | * spin_lock_irqsave(host lock) | ||
1505 | * | ||
1506 | * RETURNS: | ||
1507 | * One if interrupt was handled, zero if not (shared irq). | ||
1508 | */ | ||
1509 | unsigned int ata_sff_host_intr(struct ata_port *ap, | ||
1510 | struct ata_queued_cmd *qc) | ||
1511 | { | 1477 | { |
1512 | struct ata_eh_info *ehi = &ap->link.eh_info; | 1478 | ap->stats.idle_irq++; |
1513 | u8 status, host_stat = 0; | 1479 | |
1514 | bool bmdma_stopped = false; | 1480 | #ifdef ATA_IRQ_TRAP |
1481 | if ((ap->stats.idle_irq % 1000) == 0) { | ||
1482 | ap->ops->sff_check_status(ap); | ||
1483 | if (ap->ops->sff_irq_clear) | ||
1484 | ap->ops->sff_irq_clear(ap); | ||
1485 | ata_port_printk(ap, KERN_WARNING, "irq trap\n"); | ||
1486 | return 1; | ||
1487 | } | ||
1488 | #endif | ||
1489 | return 0; /* irq not handled */ | ||
1490 | } | ||
1491 | |||
1492 | static unsigned int __ata_sff_port_intr(struct ata_port *ap, | ||
1493 | struct ata_queued_cmd *qc, | ||
1494 | bool hsmv_on_idle) | ||
1495 | { | ||
1496 | u8 status; | ||
1515 | 1497 | ||
1516 | VPRINTK("ata%u: protocol %d task_state %d\n", | 1498 | VPRINTK("ata%u: protocol %d task_state %d\n", |
1517 | ap->print_id, qc->tf.protocol, ap->hsm_task_state); | 1499 | ap->print_id, qc->tf.protocol, ap->hsm_task_state); |
@@ -1528,90 +1510,56 @@ unsigned int ata_sff_host_intr(struct ata_port *ap, | |||
1528 | * need to check ata_is_atapi(qc->tf.protocol) again. | 1510 | * need to check ata_is_atapi(qc->tf.protocol) again. |
1529 | */ | 1511 | */ |
1530 | if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) | 1512 | if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) |
1531 | goto idle_irq; | 1513 | return ata_sff_idle_irq(ap); |
1532 | break; | ||
1533 | case HSM_ST_LAST: | ||
1534 | if (qc->tf.protocol == ATA_PROT_DMA || | ||
1535 | qc->tf.protocol == ATAPI_PROT_DMA) { | ||
1536 | /* check status of DMA engine */ | ||
1537 | host_stat = ap->ops->bmdma_status(ap); | ||
1538 | VPRINTK("ata%u: host_stat 0x%X\n", | ||
1539 | ap->print_id, host_stat); | ||
1540 | |||
1541 | /* if it's not our irq... */ | ||
1542 | if (!(host_stat & ATA_DMA_INTR)) | ||
1543 | goto idle_irq; | ||
1544 | |||
1545 | /* before we do anything else, clear DMA-Start bit */ | ||
1546 | ap->ops->bmdma_stop(qc); | ||
1547 | bmdma_stopped = true; | ||
1548 | |||
1549 | if (unlikely(host_stat & ATA_DMA_ERR)) { | ||
1550 | /* error when transfering data to/from memory */ | ||
1551 | qc->err_mask |= AC_ERR_HOST_BUS; | ||
1552 | ap->hsm_task_state = HSM_ST_ERR; | ||
1553 | } | ||
1554 | } | ||
1555 | break; | 1514 | break; |
1556 | case HSM_ST: | 1515 | case HSM_ST: |
1516 | case HSM_ST_LAST: | ||
1557 | break; | 1517 | break; |
1558 | default: | 1518 | default: |
1559 | goto idle_irq; | 1519 | return ata_sff_idle_irq(ap); |
1560 | } | 1520 | } |
1561 | 1521 | ||
1562 | |||
1563 | /* check main status, clearing INTRQ if needed */ | 1522 | /* check main status, clearing INTRQ if needed */ |
1564 | status = ata_sff_irq_status(ap); | 1523 | status = ata_sff_irq_status(ap); |
1565 | if (status & ATA_BUSY) { | 1524 | if (status & ATA_BUSY) { |
1566 | if (bmdma_stopped) { | 1525 | if (hsmv_on_idle) { |
1567 | /* BMDMA engine is already stopped, we're screwed */ | 1526 | /* BMDMA engine is already stopped, we're screwed */ |
1568 | qc->err_mask |= AC_ERR_HSM; | 1527 | qc->err_mask |= AC_ERR_HSM; |
1569 | ap->hsm_task_state = HSM_ST_ERR; | 1528 | ap->hsm_task_state = HSM_ST_ERR; |
1570 | } else | 1529 | } else |
1571 | goto idle_irq; | 1530 | return ata_sff_idle_irq(ap); |
1572 | } | 1531 | } |
1573 | 1532 | ||
1574 | /* clear irq events */ | 1533 | /* clear irq events */ |
1575 | ap->ops->sff_irq_clear(ap); | 1534 | if (ap->ops->sff_irq_clear) |
1535 | ap->ops->sff_irq_clear(ap); | ||
1576 | 1536 | ||
1577 | ata_sff_hsm_move(ap, qc, status, 0); | 1537 | ata_sff_hsm_move(ap, qc, status, 0); |
1578 | 1538 | ||
1579 | if (unlikely(qc->err_mask) && (qc->tf.protocol == ATA_PROT_DMA || | ||
1580 | qc->tf.protocol == ATAPI_PROT_DMA)) | ||
1581 | ata_ehi_push_desc(ehi, "BMDMA stat 0x%x", host_stat); | ||
1582 | |||
1583 | return 1; /* irq handled */ | 1539 | return 1; /* irq handled */ |
1584 | |||
1585 | idle_irq: | ||
1586 | ap->stats.idle_irq++; | ||
1587 | |||
1588 | #ifdef ATA_IRQ_TRAP | ||
1589 | if ((ap->stats.idle_irq % 1000) == 0) { | ||
1590 | ap->ops->sff_check_status(ap); | ||
1591 | ap->ops->sff_irq_clear(ap); | ||
1592 | ata_port_printk(ap, KERN_WARNING, "irq trap\n"); | ||
1593 | return 1; | ||
1594 | } | ||
1595 | #endif | ||
1596 | return 0; /* irq not handled */ | ||
1597 | } | 1540 | } |
1598 | EXPORT_SYMBOL_GPL(ata_sff_host_intr); | ||
1599 | 1541 | ||
1600 | /** | 1542 | /** |
1601 | * ata_sff_interrupt - Default ATA host interrupt handler | 1543 | * ata_sff_port_intr - Handle SFF port interrupt |
1602 | * @irq: irq line (unused) | 1544 | * @ap: Port on which interrupt arrived (possibly...) |
1603 | * @dev_instance: pointer to our ata_host information structure | 1545 | * @qc: Taskfile currently active in engine |
1604 | * | 1546 | * |
1605 | * Default interrupt handler for PCI IDE devices. Calls | 1547 | * Handle port interrupt for given queued command. |
1606 | * ata_sff_host_intr() for each port that is not disabled. | ||
1607 | * | 1548 | * |
1608 | * LOCKING: | 1549 | * LOCKING: |
1609 | * Obtains host lock during operation. | 1550 | * spin_lock_irqsave(host lock) |
1610 | * | 1551 | * |
1611 | * RETURNS: | 1552 | * RETURNS: |
1612 | * IRQ_NONE or IRQ_HANDLED. | 1553 | * One if interrupt was handled, zero if not (shared irq). |
1613 | */ | 1554 | */ |
1614 | irqreturn_t ata_sff_interrupt(int irq, void *dev_instance) | 1555 | unsigned int ata_sff_port_intr(struct ata_port *ap, struct ata_queued_cmd *qc) |
1556 | { | ||
1557 | return __ata_sff_port_intr(ap, qc, false); | ||
1558 | } | ||
1559 | EXPORT_SYMBOL_GPL(ata_sff_port_intr); | ||
1560 | |||
1561 | static inline irqreturn_t __ata_sff_interrupt(int irq, void *dev_instance, | ||
1562 | unsigned int (*port_intr)(struct ata_port *, struct ata_queued_cmd *)) | ||
1615 | { | 1563 | { |
1616 | struct ata_host *host = dev_instance; | 1564 | struct ata_host *host = dev_instance; |
1617 | bool retried = false; | 1565 | bool retried = false; |
@@ -1631,7 +1579,7 @@ retry: | |||
1631 | qc = ata_qc_from_tag(ap, ap->link.active_tag); | 1579 | qc = ata_qc_from_tag(ap, ap->link.active_tag); |
1632 | if (qc) { | 1580 | if (qc) { |
1633 | if (!(qc->tf.flags & ATA_TFLAG_POLLING)) | 1581 | if (!(qc->tf.flags & ATA_TFLAG_POLLING)) |
1634 | handled |= ata_sff_host_intr(ap, qc); | 1582 | handled |= port_intr(ap, qc); |
1635 | else | 1583 | else |
1636 | polling |= 1 << i; | 1584 | polling |= 1 << i; |
1637 | } else | 1585 | } else |
@@ -1658,7 +1606,8 @@ retry: | |||
1658 | 1606 | ||
1659 | if (idle & (1 << i)) { | 1607 | if (idle & (1 << i)) { |
1660 | ap->ops->sff_check_status(ap); | 1608 | ap->ops->sff_check_status(ap); |
1661 | ap->ops->sff_irq_clear(ap); | 1609 | if (ap->ops->sff_irq_clear) |
1610 | ap->ops->sff_irq_clear(ap); | ||
1662 | } else { | 1611 | } else { |
1663 | /* clear INTRQ and check if BUSY cleared */ | 1612 | /* clear INTRQ and check if BUSY cleared */ |
1664 | if (!(ap->ops->sff_check_status(ap) & ATA_BUSY)) | 1613 | if (!(ap->ops->sff_check_status(ap) & ATA_BUSY)) |
@@ -1680,6 +1629,25 @@ retry: | |||
1680 | 1629 | ||
1681 | return IRQ_RETVAL(handled); | 1630 | return IRQ_RETVAL(handled); |
1682 | } | 1631 | } |
1632 | |||
1633 | /** | ||
1634 | * ata_sff_interrupt - Default SFF ATA host interrupt handler | ||
1635 | * @irq: irq line (unused) | ||
1636 | * @dev_instance: pointer to our ata_host information structure | ||
1637 | * | ||
1638 | * Default interrupt handler for PCI IDE devices. Calls | ||
1639 | * ata_sff_port_intr() for each port that is not disabled. | ||
1640 | * | ||
1641 | * LOCKING: | ||
1642 | * Obtains host lock during operation. | ||
1643 | * | ||
1644 | * RETURNS: | ||
1645 | * IRQ_NONE or IRQ_HANDLED. | ||
1646 | */ | ||
1647 | irqreturn_t ata_sff_interrupt(int irq, void *dev_instance) | ||
1648 | { | ||
1649 | return __ata_sff_interrupt(irq, dev_instance, ata_sff_port_intr); | ||
1650 | } | ||
1683 | EXPORT_SYMBOL_GPL(ata_sff_interrupt); | 1651 | EXPORT_SYMBOL_GPL(ata_sff_interrupt); |
1684 | 1652 | ||
1685 | /** | 1653 | /** |
@@ -1717,7 +1685,7 @@ void ata_sff_lost_interrupt(struct ata_port *ap) | |||
1717 | status); | 1685 | status); |
1718 | /* Run the host interrupt logic as if the interrupt had not been | 1686 | /* Run the host interrupt logic as if the interrupt had not been |
1719 | lost */ | 1687 | lost */ |
1720 | ata_sff_host_intr(ap, qc); | 1688 | ata_sff_port_intr(ap, qc); |
1721 | } | 1689 | } |
1722 | EXPORT_SYMBOL_GPL(ata_sff_lost_interrupt); | 1690 | EXPORT_SYMBOL_GPL(ata_sff_lost_interrupt); |
1723 | 1691 | ||
@@ -1744,7 +1712,8 @@ void ata_sff_freeze(struct ata_port *ap) | |||
1744 | */ | 1712 | */ |
1745 | ap->ops->sff_check_status(ap); | 1713 | ap->ops->sff_check_status(ap); |
1746 | 1714 | ||
1747 | ap->ops->sff_irq_clear(ap); | 1715 | if (ap->ops->sff_irq_clear) |
1716 | ap->ops->sff_irq_clear(ap); | ||
1748 | } | 1717 | } |
1749 | EXPORT_SYMBOL_GPL(ata_sff_freeze); | 1718 | EXPORT_SYMBOL_GPL(ata_sff_freeze); |
1750 | 1719 | ||
@@ -1761,7 +1730,8 @@ void ata_sff_thaw(struct ata_port *ap) | |||
1761 | { | 1730 | { |
1762 | /* clear & re-enable interrupts */ | 1731 | /* clear & re-enable interrupts */ |
1763 | ap->ops->sff_check_status(ap); | 1732 | ap->ops->sff_check_status(ap); |
1764 | ap->ops->sff_irq_clear(ap); | 1733 | if (ap->ops->sff_irq_clear) |
1734 | ap->ops->sff_irq_clear(ap); | ||
1765 | ata_sff_irq_on(ap); | 1735 | ata_sff_irq_on(ap); |
1766 | } | 1736 | } |
1767 | EXPORT_SYMBOL_GPL(ata_sff_thaw); | 1737 | EXPORT_SYMBOL_GPL(ata_sff_thaw); |
@@ -2349,13 +2319,13 @@ int ata_pci_sff_init_host(struct ata_host *host) | |||
2349 | EXPORT_SYMBOL_GPL(ata_pci_sff_init_host); | 2319 | EXPORT_SYMBOL_GPL(ata_pci_sff_init_host); |
2350 | 2320 | ||
2351 | /** | 2321 | /** |
2352 | * ata_pci_sff_prepare_host - helper to prepare native PCI ATA host | 2322 | * ata_pci_sff_prepare_host - helper to prepare PCI PIO-only SFF ATA host |
2353 | * @pdev: target PCI device | 2323 | * @pdev: target PCI device |
2354 | * @ppi: array of port_info, must be enough for two ports | 2324 | * @ppi: array of port_info, must be enough for two ports |
2355 | * @r_host: out argument for the initialized ATA host | 2325 | * @r_host: out argument for the initialized ATA host |
2356 | * | 2326 | * |
2357 | * Helper to allocate ATA host for @pdev, acquire all native PCI | 2327 | * Helper to allocate PIO-only SFF ATA host for @pdev, acquire |
2358 | * resources and initialize it accordingly in one go. | 2328 | * all PCI resources and initialize it accordingly in one go. |
2359 | * | 2329 | * |
2360 | * LOCKING: | 2330 | * LOCKING: |
2361 | * Inherited from calling layer (may sleep). | 2331 | * Inherited from calling layer (may sleep). |
@@ -2385,9 +2355,6 @@ int ata_pci_sff_prepare_host(struct pci_dev *pdev, | |||
2385 | if (rc) | 2355 | if (rc) |
2386 | goto err_out; | 2356 | goto err_out; |
2387 | 2357 | ||
2388 | /* init DMA related stuff */ | ||
2389 | ata_pci_bmdma_init(host); | ||
2390 | |||
2391 | devres_remove_group(&pdev->dev, NULL); | 2358 | devres_remove_group(&pdev->dev, NULL); |
2392 | *r_host = host; | 2359 | *r_host = host; |
2393 | return 0; | 2360 | return 0; |
@@ -2492,8 +2459,21 @@ out: | |||
2492 | } | 2459 | } |
2493 | EXPORT_SYMBOL_GPL(ata_pci_sff_activate_host); | 2460 | EXPORT_SYMBOL_GPL(ata_pci_sff_activate_host); |
2494 | 2461 | ||
2462 | static const struct ata_port_info *ata_sff_find_valid_pi( | ||
2463 | const struct ata_port_info * const *ppi) | ||
2464 | { | ||
2465 | int i; | ||
2466 | |||
2467 | /* look up the first valid port_info */ | ||
2468 | for (i = 0; i < 2 && ppi[i]; i++) | ||
2469 | if (ppi[i]->port_ops != &ata_dummy_port_ops) | ||
2470 | return ppi[i]; | ||
2471 | |||
2472 | return NULL; | ||
2473 | } | ||
2474 | |||
2495 | /** | 2475 | /** |
2496 | * ata_pci_sff_init_one - Initialize/register PCI IDE host controller | 2476 | * ata_pci_sff_init_one - Initialize/register PIO-only PCI IDE controller |
2497 | * @pdev: Controller to be initialized | 2477 | * @pdev: Controller to be initialized |
2498 | * @ppi: array of port_info, must be enough for two ports | 2478 | * @ppi: array of port_info, must be enough for two ports |
2499 | * @sht: scsi_host_template to use when registering the host | 2479 | * @sht: scsi_host_template to use when registering the host |
@@ -2502,11 +2482,7 @@ EXPORT_SYMBOL_GPL(ata_pci_sff_activate_host); | |||
2502 | * | 2482 | * |
2503 | * This is a helper function which can be called from a driver's | 2483 | * This is a helper function which can be called from a driver's |
2504 | * xxx_init_one() probe function if the hardware uses traditional | 2484 | * xxx_init_one() probe function if the hardware uses traditional |
2505 | * IDE taskfile registers. | 2485 | * IDE taskfile registers and is PIO only. |
2506 | * | ||
2507 | * This function calls pci_enable_device(), reserves its register | ||
2508 | * regions, sets the dma mask, enables bus master mode, and calls | ||
2509 | * ata_device_add() | ||
2510 | * | 2486 | * |
2511 | * ASSUMPTION: | 2487 | * ASSUMPTION: |
2512 | * Nobody makes a single channel controller that appears solely as | 2488 | * Nobody makes a single channel controller that appears solely as |
@@ -2523,20 +2499,13 @@ int ata_pci_sff_init_one(struct pci_dev *pdev, | |||
2523 | struct scsi_host_template *sht, void *host_priv, int hflag) | 2499 | struct scsi_host_template *sht, void *host_priv, int hflag) |
2524 | { | 2500 | { |
2525 | struct device *dev = &pdev->dev; | 2501 | struct device *dev = &pdev->dev; |
2526 | const struct ata_port_info *pi = NULL; | 2502 | const struct ata_port_info *pi; |
2527 | struct ata_host *host = NULL; | 2503 | struct ata_host *host = NULL; |
2528 | int i, rc; | 2504 | int rc; |
2529 | 2505 | ||
2530 | DPRINTK("ENTER\n"); | 2506 | DPRINTK("ENTER\n"); |
2531 | 2507 | ||
2532 | /* look up the first valid port_info */ | 2508 | pi = ata_sff_find_valid_pi(ppi); |
2533 | for (i = 0; i < 2 && ppi[i]; i++) { | ||
2534 | if (ppi[i]->port_ops != &ata_dummy_port_ops) { | ||
2535 | pi = ppi[i]; | ||
2536 | break; | ||
2537 | } | ||
2538 | } | ||
2539 | |||
2540 | if (!pi) { | 2509 | if (!pi) { |
2541 | dev_printk(KERN_ERR, &pdev->dev, | 2510 | dev_printk(KERN_ERR, &pdev->dev, |
2542 | "no valid port_info specified\n"); | 2511 | "no valid port_info specified\n"); |
@@ -2557,7 +2526,6 @@ int ata_pci_sff_init_one(struct pci_dev *pdev, | |||
2557 | host->private_data = host_priv; | 2526 | host->private_data = host_priv; |
2558 | host->flags |= hflag; | 2527 | host->flags |= hflag; |
2559 | 2528 | ||
2560 | pci_set_master(pdev); | ||
2561 | rc = ata_pci_sff_activate_host(host, ata_sff_interrupt, sht); | 2529 | rc = ata_pci_sff_activate_host(host, ata_sff_interrupt, sht); |
2562 | out: | 2530 | out: |
2563 | if (rc == 0) | 2531 | if (rc == 0) |
@@ -2571,6 +2539,12 @@ EXPORT_SYMBOL_GPL(ata_pci_sff_init_one); | |||
2571 | 2539 | ||
2572 | #endif /* CONFIG_PCI */ | 2540 | #endif /* CONFIG_PCI */ |
2573 | 2541 | ||
2542 | /* | ||
2543 | * BMDMA support | ||
2544 | */ | ||
2545 | |||
2546 | #ifdef CONFIG_ATA_BMDMA | ||
2547 | |||
2574 | const struct ata_port_operations ata_bmdma_port_ops = { | 2548 | const struct ata_port_operations ata_bmdma_port_ops = { |
2575 | .inherits = &ata_sff_port_ops, | 2549 | .inherits = &ata_sff_port_ops, |
2576 | 2550 | ||
@@ -2580,6 +2554,7 @@ const struct ata_port_operations ata_bmdma_port_ops = { | |||
2580 | .qc_prep = ata_bmdma_qc_prep, | 2554 | .qc_prep = ata_bmdma_qc_prep, |
2581 | .qc_issue = ata_bmdma_qc_issue, | 2555 | .qc_issue = ata_bmdma_qc_issue, |
2582 | 2556 | ||
2557 | .sff_irq_clear = ata_bmdma_irq_clear, | ||
2583 | .bmdma_setup = ata_bmdma_setup, | 2558 | .bmdma_setup = ata_bmdma_setup, |
2584 | .bmdma_start = ata_bmdma_start, | 2559 | .bmdma_start = ata_bmdma_start, |
2585 | .bmdma_stop = ata_bmdma_stop, | 2560 | .bmdma_stop = ata_bmdma_stop, |
@@ -2804,6 +2779,75 @@ unsigned int ata_bmdma_qc_issue(struct ata_queued_cmd *qc) | |||
2804 | EXPORT_SYMBOL_GPL(ata_bmdma_qc_issue); | 2779 | EXPORT_SYMBOL_GPL(ata_bmdma_qc_issue); |
2805 | 2780 | ||
2806 | /** | 2781 | /** |
2782 | * ata_bmdma_port_intr - Handle BMDMA port interrupt | ||
2783 | * @ap: Port on which interrupt arrived (possibly...) | ||
2784 | * @qc: Taskfile currently active in engine | ||
2785 | * | ||
2786 | * Handle port interrupt for given queued command. | ||
2787 | * | ||
2788 | * LOCKING: | ||
2789 | * spin_lock_irqsave(host lock) | ||
2790 | * | ||
2791 | * RETURNS: | ||
2792 | * One if interrupt was handled, zero if not (shared irq). | ||
2793 | */ | ||
2794 | unsigned int ata_bmdma_port_intr(struct ata_port *ap, struct ata_queued_cmd *qc) | ||
2795 | { | ||
2796 | struct ata_eh_info *ehi = &ap->link.eh_info; | ||
2797 | u8 host_stat = 0; | ||
2798 | bool bmdma_stopped = false; | ||
2799 | unsigned int handled; | ||
2800 | |||
2801 | if (ap->hsm_task_state == HSM_ST_LAST && ata_is_dma(qc->tf.protocol)) { | ||
2802 | /* check status of DMA engine */ | ||
2803 | host_stat = ap->ops->bmdma_status(ap); | ||
2804 | VPRINTK("ata%u: host_stat 0x%X\n", ap->print_id, host_stat); | ||
2805 | |||
2806 | /* if it's not our irq... */ | ||
2807 | if (!(host_stat & ATA_DMA_INTR)) | ||
2808 | return ata_sff_idle_irq(ap); | ||
2809 | |||
2810 | /* before we do anything else, clear DMA-Start bit */ | ||
2811 | ap->ops->bmdma_stop(qc); | ||
2812 | bmdma_stopped = true; | ||
2813 | |||
2814 | if (unlikely(host_stat & ATA_DMA_ERR)) { | ||
2815 | /* error when transfering data to/from memory */ | ||
2816 | qc->err_mask |= AC_ERR_HOST_BUS; | ||
2817 | ap->hsm_task_state = HSM_ST_ERR; | ||
2818 | } | ||
2819 | } | ||
2820 | |||
2821 | handled = __ata_sff_port_intr(ap, qc, bmdma_stopped); | ||
2822 | |||
2823 | if (unlikely(qc->err_mask) && ata_is_dma(qc->tf.protocol)) | ||
2824 | ata_ehi_push_desc(ehi, "BMDMA stat 0x%x", host_stat); | ||
2825 | |||
2826 | return handled; | ||
2827 | } | ||
2828 | EXPORT_SYMBOL_GPL(ata_bmdma_port_intr); | ||
2829 | |||
2830 | /** | ||
2831 | * ata_bmdma_interrupt - Default BMDMA ATA host interrupt handler | ||
2832 | * @irq: irq line (unused) | ||
2833 | * @dev_instance: pointer to our ata_host information structure | ||
2834 | * | ||
2835 | * Default interrupt handler for PCI IDE devices. Calls | ||
2836 | * ata_bmdma_port_intr() for each port that is not disabled. | ||
2837 | * | ||
2838 | * LOCKING: | ||
2839 | * Obtains host lock during operation. | ||
2840 | * | ||
2841 | * RETURNS: | ||
2842 | * IRQ_NONE or IRQ_HANDLED. | ||
2843 | */ | ||
2844 | irqreturn_t ata_bmdma_interrupt(int irq, void *dev_instance) | ||
2845 | { | ||
2846 | return __ata_sff_interrupt(irq, dev_instance, ata_bmdma_port_intr); | ||
2847 | } | ||
2848 | EXPORT_SYMBOL_GPL(ata_bmdma_interrupt); | ||
2849 | |||
2850 | /** | ||
2807 | * ata_bmdma_error_handler - Stock error handler for BMDMA controller | 2851 | * ata_bmdma_error_handler - Stock error handler for BMDMA controller |
2808 | * @ap: port to handle error for | 2852 | * @ap: port to handle error for |
2809 | * | 2853 | * |
@@ -2848,7 +2892,8 @@ void ata_bmdma_error_handler(struct ata_port *ap) | |||
2848 | /* if we're gonna thaw, make sure IRQ is clear */ | 2892 | /* if we're gonna thaw, make sure IRQ is clear */ |
2849 | if (thaw) { | 2893 | if (thaw) { |
2850 | ap->ops->sff_check_status(ap); | 2894 | ap->ops->sff_check_status(ap); |
2851 | ap->ops->sff_irq_clear(ap); | 2895 | if (ap->ops->sff_irq_clear) |
2896 | ap->ops->sff_irq_clear(ap); | ||
2852 | } | 2897 | } |
2853 | } | 2898 | } |
2854 | 2899 | ||
@@ -2882,6 +2927,28 @@ void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc) | |||
2882 | EXPORT_SYMBOL_GPL(ata_bmdma_post_internal_cmd); | 2927 | EXPORT_SYMBOL_GPL(ata_bmdma_post_internal_cmd); |
2883 | 2928 | ||
2884 | /** | 2929 | /** |
2930 | * ata_bmdma_irq_clear - Clear PCI IDE BMDMA interrupt. | ||
2931 | * @ap: Port associated with this ATA transaction. | ||
2932 | * | ||
2933 | * Clear interrupt and error flags in DMA status register. | ||
2934 | * | ||
2935 | * May be used as the irq_clear() entry in ata_port_operations. | ||
2936 | * | ||
2937 | * LOCKING: | ||
2938 | * spin_lock_irqsave(host lock) | ||
2939 | */ | ||
2940 | void ata_bmdma_irq_clear(struct ata_port *ap) | ||
2941 | { | ||
2942 | void __iomem *mmio = ap->ioaddr.bmdma_addr; | ||
2943 | |||
2944 | if (!mmio) | ||
2945 | return; | ||
2946 | |||
2947 | iowrite8(ioread8(mmio + ATA_DMA_STATUS), mmio + ATA_DMA_STATUS); | ||
2948 | } | ||
2949 | EXPORT_SYMBOL_GPL(ata_bmdma_irq_clear); | ||
2950 | |||
2951 | /** | ||
2885 | * ata_bmdma_setup - Set up PCI IDE BMDMA transaction | 2952 | * ata_bmdma_setup - Set up PCI IDE BMDMA transaction |
2886 | * @qc: Info associated with this ATA transaction. | 2953 | * @qc: Info associated with this ATA transaction. |
2887 | * | 2954 | * |
@@ -3137,7 +3204,100 @@ void ata_pci_bmdma_init(struct ata_host *host) | |||
3137 | } | 3204 | } |
3138 | EXPORT_SYMBOL_GPL(ata_pci_bmdma_init); | 3205 | EXPORT_SYMBOL_GPL(ata_pci_bmdma_init); |
3139 | 3206 | ||
3207 | /** | ||
3208 | * ata_pci_bmdma_prepare_host - helper to prepare PCI BMDMA ATA host | ||
3209 | * @pdev: target PCI device | ||
3210 | * @ppi: array of port_info, must be enough for two ports | ||
3211 | * @r_host: out argument for the initialized ATA host | ||
3212 | * | ||
3213 | * Helper to allocate BMDMA ATA host for @pdev, acquire all PCI | ||
3214 | * resources and initialize it accordingly in one go. | ||
3215 | * | ||
3216 | * LOCKING: | ||
3217 | * Inherited from calling layer (may sleep). | ||
3218 | * | ||
3219 | * RETURNS: | ||
3220 | * 0 on success, -errno otherwise. | ||
3221 | */ | ||
3222 | int ata_pci_bmdma_prepare_host(struct pci_dev *pdev, | ||
3223 | const struct ata_port_info * const * ppi, | ||
3224 | struct ata_host **r_host) | ||
3225 | { | ||
3226 | int rc; | ||
3227 | |||
3228 | rc = ata_pci_sff_prepare_host(pdev, ppi, r_host); | ||
3229 | if (rc) | ||
3230 | return rc; | ||
3231 | |||
3232 | ata_pci_bmdma_init(*r_host); | ||
3233 | return 0; | ||
3234 | } | ||
3235 | EXPORT_SYMBOL_GPL(ata_pci_bmdma_prepare_host); | ||
3236 | |||
3237 | /** | ||
3238 | * ata_pci_bmdma_init_one - Initialize/register BMDMA PCI IDE controller | ||
3239 | * @pdev: Controller to be initialized | ||
3240 | * @ppi: array of port_info, must be enough for two ports | ||
3241 | * @sht: scsi_host_template to use when registering the host | ||
3242 | * @host_priv: host private_data | ||
3243 | * @hflags: host flags | ||
3244 | * | ||
3245 | * This function is similar to ata_pci_sff_init_one() but also | ||
3246 | * takes care of BMDMA initialization. | ||
3247 | * | ||
3248 | * LOCKING: | ||
3249 | * Inherited from PCI layer (may sleep). | ||
3250 | * | ||
3251 | * RETURNS: | ||
3252 | * Zero on success, negative on errno-based value on error. | ||
3253 | */ | ||
3254 | int ata_pci_bmdma_init_one(struct pci_dev *pdev, | ||
3255 | const struct ata_port_info * const * ppi, | ||
3256 | struct scsi_host_template *sht, void *host_priv, | ||
3257 | int hflags) | ||
3258 | { | ||
3259 | struct device *dev = &pdev->dev; | ||
3260 | const struct ata_port_info *pi; | ||
3261 | struct ata_host *host = NULL; | ||
3262 | int rc; | ||
3263 | |||
3264 | DPRINTK("ENTER\n"); | ||
3265 | |||
3266 | pi = ata_sff_find_valid_pi(ppi); | ||
3267 | if (!pi) { | ||
3268 | dev_printk(KERN_ERR, &pdev->dev, | ||
3269 | "no valid port_info specified\n"); | ||
3270 | return -EINVAL; | ||
3271 | } | ||
3272 | |||
3273 | if (!devres_open_group(dev, NULL, GFP_KERNEL)) | ||
3274 | return -ENOMEM; | ||
3275 | |||
3276 | rc = pcim_enable_device(pdev); | ||
3277 | if (rc) | ||
3278 | goto out; | ||
3279 | |||
3280 | /* prepare and activate BMDMA host */ | ||
3281 | rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host); | ||
3282 | if (rc) | ||
3283 | goto out; | ||
3284 | host->private_data = host_priv; | ||
3285 | host->flags |= hflags; | ||
3286 | |||
3287 | pci_set_master(pdev); | ||
3288 | rc = ata_pci_sff_activate_host(host, ata_bmdma_interrupt, sht); | ||
3289 | out: | ||
3290 | if (rc == 0) | ||
3291 | devres_remove_group(&pdev->dev, NULL); | ||
3292 | else | ||
3293 | devres_release_group(&pdev->dev, NULL); | ||
3294 | |||
3295 | return rc; | ||
3296 | } | ||
3297 | EXPORT_SYMBOL_GPL(ata_pci_bmdma_init_one); | ||
3298 | |||
3140 | #endif /* CONFIG_PCI */ | 3299 | #endif /* CONFIG_PCI */ |
3300 | #endif /* CONFIG_ATA_BMDMA */ | ||
3141 | 3301 | ||
3142 | /** | 3302 | /** |
3143 | * ata_sff_port_init - Initialize SFF/BMDMA ATA port | 3303 | * ata_sff_port_init - Initialize SFF/BMDMA ATA port |
diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c index 066b9f301ed5..c8d47034d5e9 100644 --- a/drivers/ata/pata_acpi.c +++ b/drivers/ata/pata_acpi.c | |||
@@ -260,7 +260,7 @@ static int pacpi_init_one (struct pci_dev *pdev, const struct pci_device_id *id) | |||
260 | return rc; | 260 | return rc; |
261 | pcim_pin_device(pdev); | 261 | pcim_pin_device(pdev); |
262 | } | 262 | } |
263 | return ata_pci_sff_init_one(pdev, ppi, &pacpi_sht, NULL, 0); | 263 | return ata_pci_bmdma_init_one(pdev, ppi, &pacpi_sht, NULL, 0); |
264 | } | 264 | } |
265 | 265 | ||
266 | static const struct pci_device_id pacpi_pci_tbl[] = { | 266 | static const struct pci_device_id pacpi_pci_tbl[] = { |
diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c index f306e10c748d..794ec6e3275d 100644 --- a/drivers/ata/pata_ali.c +++ b/drivers/ata/pata_ali.c | |||
@@ -583,7 +583,10 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
583 | ppi[0] = &info_20_udma; | 583 | ppi[0] = &info_20_udma; |
584 | } | 584 | } |
585 | 585 | ||
586 | return ata_pci_sff_init_one(pdev, ppi, &ali_sht, NULL, 0); | 586 | if (!ppi[0]->mwdma_mask && !ppi[0]->udma_mask) |
587 | return ata_pci_sff_init_one(pdev, ppi, &ali_sht, NULL, 0); | ||
588 | else | ||
589 | return ata_pci_bmdma_init_one(pdev, ppi, &ali_sht, NULL, 0); | ||
587 | } | 590 | } |
588 | 591 | ||
589 | #ifdef CONFIG_PM | 592 | #ifdef CONFIG_PM |
diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c index d95eca9c547e..620a07cabe31 100644 --- a/drivers/ata/pata_amd.c +++ b/drivers/ata/pata_amd.c | |||
@@ -574,7 +574,7 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
574 | } | 574 | } |
575 | 575 | ||
576 | /* And fire it up */ | 576 | /* And fire it up */ |
577 | return ata_pci_sff_init_one(pdev, ppi, &amd_sht, hpriv, 0); | 577 | return ata_pci_bmdma_init_one(pdev, ppi, &amd_sht, hpriv, 0); |
578 | } | 578 | } |
579 | 579 | ||
580 | #ifdef CONFIG_PM | 580 | #ifdef CONFIG_PM |
diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c index 4d066d6c30fa..ba43f0f8c880 100644 --- a/drivers/ata/pata_artop.c +++ b/drivers/ata/pata_artop.c | |||
@@ -421,7 +421,7 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id) | |||
421 | 421 | ||
422 | BUG_ON(ppi[0] == NULL); | 422 | BUG_ON(ppi[0] == NULL); |
423 | 423 | ||
424 | return ata_pci_sff_init_one(pdev, ppi, &artop_sht, NULL, 0); | 424 | return ata_pci_bmdma_init_one(pdev, ppi, &artop_sht, NULL, 0); |
425 | } | 425 | } |
426 | 426 | ||
427 | static const struct pci_device_id artop_pci_tbl[] = { | 427 | static const struct pci_device_id artop_pci_tbl[] = { |
diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c index 44d88b380ddd..43755616dc5a 100644 --- a/drivers/ata/pata_atiixp.c +++ b/drivers/ata/pata_atiixp.c | |||
@@ -246,8 +246,8 @@ static int atiixp_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
246 | if (!pci_test_config_bits(pdev, &atiixp_enable_bits[i])) | 246 | if (!pci_test_config_bits(pdev, &atiixp_enable_bits[i])) |
247 | ppi[i] = &ata_dummy_port_info; | 247 | ppi[i] = &ata_dummy_port_info; |
248 | 248 | ||
249 | return ata_pci_sff_init_one(pdev, ppi, &atiixp_sht, NULL, | 249 | return ata_pci_bmdma_init_one(pdev, ppi, &atiixp_sht, NULL, |
250 | ATA_HOST_PARALLEL_SCAN); | 250 | ATA_HOST_PARALLEL_SCAN); |
251 | } | 251 | } |
252 | 252 | ||
253 | static const struct pci_device_id atiixp[] = { | 253 | static const struct pci_device_id atiixp[] = { |
diff --git a/drivers/ata/pata_atp867x.c b/drivers/ata/pata_atp867x.c index bb6e0746e07d..95295935dd95 100644 --- a/drivers/ata/pata_atp867x.c +++ b/drivers/ata/pata_atp867x.c | |||
@@ -525,7 +525,7 @@ static int atp867x_init_one(struct pci_dev *pdev, | |||
525 | 525 | ||
526 | pci_set_master(pdev); | 526 | pci_set_master(pdev); |
527 | 527 | ||
528 | rc = ata_host_activate(host, pdev->irq, ata_sff_interrupt, | 528 | rc = ata_host_activate(host, pdev->irq, ata_bmdma_interrupt, |
529 | IRQF_SHARED, &atp867x_sht); | 529 | IRQF_SHARED, &atp867x_sht); |
530 | if (rc) | 530 | if (rc) |
531 | dev_printk(KERN_ERR, &pdev->dev, "failed to activate host\n"); | 531 | dev_printk(KERN_ERR, &pdev->dev, "failed to activate host\n"); |
diff --git a/drivers/ata/pata_bf54x.c b/drivers/ata/pata_bf54x.c index 6422cfd13d0d..9cae65de750e 100644 --- a/drivers/ata/pata_bf54x.c +++ b/drivers/ata/pata_bf54x.c | |||
@@ -1214,7 +1214,7 @@ static unsigned int bfin_data_xfer(struct ata_device *dev, unsigned char *buf, | |||
1214 | * bfin_irq_clear - Clear ATAPI interrupt. | 1214 | * bfin_irq_clear - Clear ATAPI interrupt. |
1215 | * @ap: Port associated with this ATA transaction. | 1215 | * @ap: Port associated with this ATA transaction. |
1216 | * | 1216 | * |
1217 | * Note: Original code is ata_sff_irq_clear(). | 1217 | * Note: Original code is ata_bmdma_irq_clear(). |
1218 | */ | 1218 | */ |
1219 | 1219 | ||
1220 | static void bfin_irq_clear(struct ata_port *ap) | 1220 | static void bfin_irq_clear(struct ata_port *ap) |
diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c index 4c81a71b8877..9f5da1c7454b 100644 --- a/drivers/ata/pata_cmd64x.c +++ b/drivers/ata/pata_cmd64x.c | |||
@@ -367,7 +367,7 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
367 | pci_write_config_byte(pdev, UDIDETCR0, 0xF0); | 367 | pci_write_config_byte(pdev, UDIDETCR0, 0xF0); |
368 | #endif | 368 | #endif |
369 | 369 | ||
370 | return ata_pci_sff_init_one(pdev, ppi, &cmd64x_sht, NULL, 0); | 370 | return ata_pci_bmdma_init_one(pdev, ppi, &cmd64x_sht, NULL, 0); |
371 | } | 371 | } |
372 | 372 | ||
373 | #ifdef CONFIG_PM | 373 | #ifdef CONFIG_PM |
diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c index 17c5f346ff01..030952f1f97c 100644 --- a/drivers/ata/pata_cs5520.c +++ b/drivers/ata/pata_cs5520.c | |||
@@ -221,7 +221,7 @@ static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_devi | |||
221 | continue; | 221 | continue; |
222 | 222 | ||
223 | rc = devm_request_irq(&pdev->dev, irq[ap->port_no], | 223 | rc = devm_request_irq(&pdev->dev, irq[ap->port_no], |
224 | ata_sff_interrupt, 0, DRV_NAME, host); | 224 | ata_bmdma_interrupt, 0, DRV_NAME, host); |
225 | if (rc) | 225 | if (rc) |
226 | return rc; | 226 | return rc; |
227 | 227 | ||
diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c index e809a4233a81..f792330f0d8e 100644 --- a/drivers/ata/pata_cs5530.c +++ b/drivers/ata/pata_cs5530.c | |||
@@ -324,7 +324,7 @@ static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
324 | ppi[1] = &info_palmax_secondary; | 324 | ppi[1] = &info_palmax_secondary; |
325 | 325 | ||
326 | /* Now kick off ATA set up */ | 326 | /* Now kick off ATA set up */ |
327 | return ata_pci_sff_init_one(pdev, ppi, &cs5530_sht, NULL, 0); | 327 | return ata_pci_bmdma_init_one(pdev, ppi, &cs5530_sht, NULL, 0); |
328 | } | 328 | } |
329 | 329 | ||
330 | #ifdef CONFIG_PM | 330 | #ifdef CONFIG_PM |
diff --git a/drivers/ata/pata_cs5535.c b/drivers/ata/pata_cs5535.c index a02e6459fdcc..03a93186aa19 100644 --- a/drivers/ata/pata_cs5535.c +++ b/drivers/ata/pata_cs5535.c | |||
@@ -198,7 +198,7 @@ static int cs5535_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
198 | rdmsr(ATAC_CH0D1_PIO, timings, dummy); | 198 | rdmsr(ATAC_CH0D1_PIO, timings, dummy); |
199 | if (CS5535_BAD_PIO(timings)) | 199 | if (CS5535_BAD_PIO(timings)) |
200 | wrmsr(ATAC_CH0D1_PIO, 0xF7F4F7F4UL, 0); | 200 | wrmsr(ATAC_CH0D1_PIO, 0xF7F4F7F4UL, 0); |
201 | return ata_pci_sff_init_one(dev, ppi, &cs5535_sht, NULL, 0); | 201 | return ata_pci_bmdma_init_one(dev, ppi, &cs5535_sht, NULL, 0); |
202 | } | 202 | } |
203 | 203 | ||
204 | static const struct pci_device_id cs5535[] = { | 204 | static const struct pci_device_id cs5535[] = { |
diff --git a/drivers/ata/pata_cs5536.c b/drivers/ata/pata_cs5536.c index 914ae3506ff5..21ee23f89e88 100644 --- a/drivers/ata/pata_cs5536.c +++ b/drivers/ata/pata_cs5536.c | |||
@@ -260,7 +260,7 @@ static int cs5536_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
260 | return -ENODEV; | 260 | return -ENODEV; |
261 | } | 261 | } |
262 | 262 | ||
263 | return ata_pci_sff_init_one(dev, ppi, &cs5536_sht, NULL, 0); | 263 | return ata_pci_bmdma_init_one(dev, ppi, &cs5536_sht, NULL, 0); |
264 | } | 264 | } |
265 | 265 | ||
266 | static const struct pci_device_id cs5536[] = { | 266 | static const struct pci_device_id cs5536[] = { |
diff --git a/drivers/ata/pata_cypress.c b/drivers/ata/pata_cypress.c index 0fcc096b8dac..6d915b063d93 100644 --- a/drivers/ata/pata_cypress.c +++ b/drivers/ata/pata_cypress.c | |||
@@ -138,7 +138,7 @@ static int cy82c693_init_one(struct pci_dev *pdev, const struct pci_device_id *i | |||
138 | if (PCI_FUNC(pdev->devfn) != 1) | 138 | if (PCI_FUNC(pdev->devfn) != 1) |
139 | return -ENODEV; | 139 | return -ENODEV; |
140 | 140 | ||
141 | return ata_pci_sff_init_one(pdev, ppi, &cy82c693_sht, NULL, 0); | 141 | return ata_pci_bmdma_init_one(pdev, ppi, &cy82c693_sht, NULL, 0); |
142 | } | 142 | } |
143 | 143 | ||
144 | static const struct pci_device_id cy82c693[] = { | 144 | static const struct pci_device_id cy82c693[] = { |
diff --git a/drivers/ata/pata_efar.c b/drivers/ata/pata_efar.c index 3bac0e079691..a08834758ea2 100644 --- a/drivers/ata/pata_efar.c +++ b/drivers/ata/pata_efar.c | |||
@@ -277,8 +277,8 @@ static int efar_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
277 | dev_printk(KERN_DEBUG, &pdev->dev, | 277 | dev_printk(KERN_DEBUG, &pdev->dev, |
278 | "version " DRV_VERSION "\n"); | 278 | "version " DRV_VERSION "\n"); |
279 | 279 | ||
280 | return ata_pci_sff_init_one(pdev, ppi, &efar_sht, NULL, | 280 | return ata_pci_bmdma_init_one(pdev, ppi, &efar_sht, NULL, |
281 | ATA_HOST_PARALLEL_SCAN); | 281 | ATA_HOST_PARALLEL_SCAN); |
282 | } | 282 | } |
283 | 283 | ||
284 | static const struct pci_device_id efar_pci_tbl[] = { | 284 | static const struct pci_device_id efar_pci_tbl[] = { |
diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c index 8580eb3cd54d..7688868557b9 100644 --- a/drivers/ata/pata_hpt366.c +++ b/drivers/ata/pata_hpt366.c | |||
@@ -361,7 +361,7 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
361 | break; | 361 | break; |
362 | } | 362 | } |
363 | /* Now kick off ATA set up */ | 363 | /* Now kick off ATA set up */ |
364 | return ata_pci_sff_init_one(dev, ppi, &hpt36x_sht, hpriv, 0); | 364 | return ata_pci_bmdma_init_one(dev, ppi, &hpt36x_sht, hpriv, 0); |
365 | } | 365 | } |
366 | 366 | ||
367 | #ifdef CONFIG_PM | 367 | #ifdef CONFIG_PM |
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index 98b498b6907c..9ae4c0830577 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c | |||
@@ -987,7 +987,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
987 | } | 987 | } |
988 | 988 | ||
989 | /* Now kick off ATA set up */ | 989 | /* Now kick off ATA set up */ |
990 | return ata_pci_sff_init_one(dev, ppi, &hpt37x_sht, private_data, 0); | 990 | return ata_pci_bmdma_init_one(dev, ppi, &hpt37x_sht, private_data, 0); |
991 | } | 991 | } |
992 | 992 | ||
993 | static const struct pci_device_id hpt37x[] = { | 993 | static const struct pci_device_id hpt37x[] = { |
diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index 8b95aeba0e74..32f3463216b8 100644 --- a/drivers/ata/pata_hpt3x2n.c +++ b/drivers/ata/pata_hpt3x2n.c | |||
@@ -548,7 +548,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
548 | outb(inb(iobase + 0x9c) | 0x04, iobase + 0x9c); | 548 | outb(inb(iobase + 0x9c) | 0x04, iobase + 0x9c); |
549 | 549 | ||
550 | /* Now kick off ATA set up */ | 550 | /* Now kick off ATA set up */ |
551 | return ata_pci_sff_init_one(dev, ppi, &hpt3x2n_sht, hpriv, 0); | 551 | return ata_pci_bmdma_init_one(dev, ppi, &hpt3x2n_sht, hpriv, 0); |
552 | } | 552 | } |
553 | 553 | ||
554 | static const struct pci_device_id hpt3x2n[] = { | 554 | static const struct pci_device_id hpt3x2n[] = { |
diff --git a/drivers/ata/pata_hpt3x3.c b/drivers/ata/pata_hpt3x3.c index 727a81ce4c9f..b63d5e2d4628 100644 --- a/drivers/ata/pata_hpt3x3.c +++ b/drivers/ata/pata_hpt3x3.c | |||
@@ -248,7 +248,7 @@ static int hpt3x3_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
248 | ata_port_pbar_desc(ap, 4, offset_cmd[i], "cmd"); | 248 | ata_port_pbar_desc(ap, 4, offset_cmd[i], "cmd"); |
249 | } | 249 | } |
250 | pci_set_master(pdev); | 250 | pci_set_master(pdev); |
251 | return ata_host_activate(host, pdev->irq, ata_sff_interrupt, | 251 | return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt, |
252 | IRQF_SHARED, &hpt3x3_sht); | 252 | IRQF_SHARED, &hpt3x3_sht); |
253 | } | 253 | } |
254 | 254 | ||
diff --git a/drivers/ata/pata_icside.c b/drivers/ata/pata_icside.c index b56e8f722d20..9f2889fe43b2 100644 --- a/drivers/ata/pata_icside.c +++ b/drivers/ata/pata_icside.c | |||
@@ -470,7 +470,7 @@ static int __devinit pata_icside_add_ports(struct pata_icside_info *info) | |||
470 | pata_icside_setup_ioaddr(ap, info->base, info, info->port[i]); | 470 | pata_icside_setup_ioaddr(ap, info->base, info, info->port[i]); |
471 | } | 471 | } |
472 | 472 | ||
473 | return ata_host_activate(host, ec->irq, ata_sff_interrupt, 0, | 473 | return ata_host_activate(host, ec->irq, ata_bmdma_interrupt, 0, |
474 | &pata_icside_sht); | 474 | &pata_icside_sht); |
475 | } | 475 | } |
476 | 476 | ||
diff --git a/drivers/ata/pata_it8213.c b/drivers/ata/pata_it8213.c index f971f0de88e6..4d142a2ab8fd 100644 --- a/drivers/ata/pata_it8213.c +++ b/drivers/ata/pata_it8213.c | |||
@@ -273,7 +273,7 @@ static int it8213_init_one (struct pci_dev *pdev, const struct pci_device_id *en | |||
273 | dev_printk(KERN_DEBUG, &pdev->dev, | 273 | dev_printk(KERN_DEBUG, &pdev->dev, |
274 | "version " DRV_VERSION "\n"); | 274 | "version " DRV_VERSION "\n"); |
275 | 275 | ||
276 | return ata_pci_sff_init_one(pdev, ppi, &it8213_sht, NULL, 0); | 276 | return ata_pci_bmdma_init_one(pdev, ppi, &it8213_sht, NULL, 0); |
277 | } | 277 | } |
278 | 278 | ||
279 | static const struct pci_device_id it8213_pci_tbl[] = { | 279 | static const struct pci_device_id it8213_pci_tbl[] = { |
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c index 2bd2b002d14a..bf88f71a21f4 100644 --- a/drivers/ata/pata_it821x.c +++ b/drivers/ata/pata_it821x.c | |||
@@ -933,7 +933,7 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
933 | else | 933 | else |
934 | ppi[0] = &info_smart; | 934 | ppi[0] = &info_smart; |
935 | } | 935 | } |
936 | return ata_pci_sff_init_one(pdev, ppi, &it821x_sht, NULL, 0); | 936 | return ata_pci_bmdma_init_one(pdev, ppi, &it821x_sht, NULL, 0); |
937 | } | 937 | } |
938 | 938 | ||
939 | #ifdef CONFIG_PM | 939 | #ifdef CONFIG_PM |
diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c index 565e01e6ac7c..cb3babbb7035 100644 --- a/drivers/ata/pata_jmicron.c +++ b/drivers/ata/pata_jmicron.c | |||
@@ -144,7 +144,7 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i | |||
144 | }; | 144 | }; |
145 | const struct ata_port_info *ppi[] = { &info, NULL }; | 145 | const struct ata_port_info *ppi[] = { &info, NULL }; |
146 | 146 | ||
147 | return ata_pci_sff_init_one(pdev, ppi, &jmicron_sht, NULL, 0); | 147 | return ata_pci_bmdma_init_one(pdev, ppi, &jmicron_sht, NULL, 0); |
148 | } | 148 | } |
149 | 149 | ||
150 | static const struct pci_device_id jmicron_pci_tbl[] = { | 150 | static const struct pci_device_id jmicron_pci_tbl[] = { |
diff --git a/drivers/ata/pata_macio.c b/drivers/ata/pata_macio.c index b5b48e703cb7..76640ac76888 100644 --- a/drivers/ata/pata_macio.c +++ b/drivers/ata/pata_macio.c | |||
@@ -1110,7 +1110,7 @@ static int __devinit pata_macio_common_init(struct pata_macio_priv *priv, | |||
1110 | 1110 | ||
1111 | /* Start it up */ | 1111 | /* Start it up */ |
1112 | priv->irq = irq; | 1112 | priv->irq = irq; |
1113 | return ata_host_activate(priv->host, irq, ata_sff_interrupt, 0, | 1113 | return ata_host_activate(priv->host, irq, ata_bmdma_interrupt, 0, |
1114 | &pata_macio_sht); | 1114 | &pata_macio_sht); |
1115 | } | 1115 | } |
1116 | 1116 | ||
diff --git a/drivers/ata/pata_marvell.c b/drivers/ata/pata_marvell.c index e8ca02e5a71d..dd38083dcbeb 100644 --- a/drivers/ata/pata_marvell.c +++ b/drivers/ata/pata_marvell.c | |||
@@ -153,7 +153,7 @@ static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *i | |||
153 | return -ENODEV; | 153 | return -ENODEV; |
154 | } | 154 | } |
155 | #endif | 155 | #endif |
156 | return ata_pci_sff_init_one(pdev, ppi, &marvell_sht, NULL, 0); | 156 | return ata_pci_bmdma_init_one(pdev, ppi, &marvell_sht, NULL, 0); |
157 | } | 157 | } |
158 | 158 | ||
159 | static const struct pci_device_id marvell_pci_tbl[] = { | 159 | static const struct pci_device_id marvell_pci_tbl[] = { |
diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c index 36afe2c1c747..f087ab55b1df 100644 --- a/drivers/ata/pata_mpc52xx.c +++ b/drivers/ata/pata_mpc52xx.c | |||
@@ -659,7 +659,7 @@ mpc52xx_ata_init_one(struct device *dev, struct mpc52xx_ata_priv *priv, | |||
659 | ata_port_desc(ap, "ata_regs 0x%lx", raw_ata_regs); | 659 | ata_port_desc(ap, "ata_regs 0x%lx", raw_ata_regs); |
660 | 660 | ||
661 | /* activate host */ | 661 | /* activate host */ |
662 | return ata_host_activate(host, priv->ata_irq, ata_sff_interrupt, 0, | 662 | return ata_host_activate(host, priv->ata_irq, ata_bmdma_interrupt, 0, |
663 | &mpc52xx_ata_sht); | 663 | &mpc52xx_ata_sht); |
664 | } | 664 | } |
665 | 665 | ||
diff --git a/drivers/ata/pata_netcell.c b/drivers/ata/pata_netcell.c index 94f979a7f4f7..3eb921c746a1 100644 --- a/drivers/ata/pata_netcell.c +++ b/drivers/ata/pata_netcell.c | |||
@@ -82,7 +82,7 @@ static int netcell_init_one (struct pci_dev *pdev, const struct pci_device_id *e | |||
82 | ata_pci_bmdma_clear_simplex(pdev); | 82 | ata_pci_bmdma_clear_simplex(pdev); |
83 | 83 | ||
84 | /* And let the library code do the work */ | 84 | /* And let the library code do the work */ |
85 | return ata_pci_sff_init_one(pdev, port_info, &netcell_sht, NULL, 0); | 85 | return ata_pci_bmdma_init_one(pdev, port_info, &netcell_sht, NULL, 0); |
86 | } | 86 | } |
87 | 87 | ||
88 | static const struct pci_device_id netcell_pci_tbl[] = { | 88 | static const struct pci_device_id netcell_pci_tbl[] = { |
diff --git a/drivers/ata/pata_ninja32.c b/drivers/ata/pata_ninja32.c index dd53a66b19e3..cc50bd09aa26 100644 --- a/drivers/ata/pata_ninja32.c +++ b/drivers/ata/pata_ninja32.c | |||
@@ -149,7 +149,7 @@ static int ninja32_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
149 | 149 | ||
150 | ninja32_program(base); | 150 | ninja32_program(base); |
151 | /* FIXME: Should we disable them at remove ? */ | 151 | /* FIXME: Should we disable them at remove ? */ |
152 | return ata_host_activate(host, dev->irq, ata_sff_interrupt, | 152 | return ata_host_activate(host, dev->irq, ata_bmdma_interrupt, |
153 | IRQF_SHARED, &ninja32_sht); | 153 | IRQF_SHARED, &ninja32_sht); |
154 | } | 154 | } |
155 | 155 | ||
diff --git a/drivers/ata/pata_ns87415.c b/drivers/ata/pata_ns87415.c index fdbba2d76d3e..605f198f958c 100644 --- a/drivers/ata/pata_ns87415.c +++ b/drivers/ata/pata_ns87415.c | |||
@@ -380,7 +380,7 @@ static int ns87415_init_one (struct pci_dev *pdev, const struct pci_device_id *e | |||
380 | 380 | ||
381 | ns87415_fixup(pdev); | 381 | ns87415_fixup(pdev); |
382 | 382 | ||
383 | return ata_pci_sff_init_one(pdev, ppi, &ns87415_sht, NULL, 0); | 383 | return ata_pci_bmdma_init_one(pdev, ppi, &ns87415_sht, NULL, 0); |
384 | } | 384 | } |
385 | 385 | ||
386 | static const struct pci_device_id ns87415_pci_tbl[] = { | 386 | static const struct pci_device_id ns87415_pci_tbl[] = { |
diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c index 3001109352ea..06ddd91ffeda 100644 --- a/drivers/ata/pata_octeon_cf.c +++ b/drivers/ata/pata_octeon_cf.c | |||
@@ -750,20 +750,6 @@ static void octeon_cf_dev_config(struct ata_device *dev) | |||
750 | } | 750 | } |
751 | 751 | ||
752 | /* | 752 | /* |
753 | * Trap if driver tries to do standard bmdma commands. They are not | ||
754 | * supported. | ||
755 | */ | ||
756 | static void unreachable_qc(struct ata_queued_cmd *qc) | ||
757 | { | ||
758 | BUG(); | ||
759 | } | ||
760 | |||
761 | static u8 unreachable_port(struct ata_port *ap) | ||
762 | { | ||
763 | BUG(); | ||
764 | } | ||
765 | |||
766 | /* | ||
767 | * We don't do ATAPI DMA so return 0. | 753 | * We don't do ATAPI DMA so return 0. |
768 | */ | 754 | */ |
769 | static int octeon_cf_check_atapi_dma(struct ata_queued_cmd *qc) | 755 | static int octeon_cf_check_atapi_dma(struct ata_queued_cmd *qc) |
@@ -804,10 +790,6 @@ static struct ata_port_operations octeon_cf_ops = { | |||
804 | .sff_dev_select = octeon_cf_dev_select, | 790 | .sff_dev_select = octeon_cf_dev_select, |
805 | .sff_irq_on = octeon_cf_irq_on, | 791 | .sff_irq_on = octeon_cf_irq_on, |
806 | .sff_irq_clear = octeon_cf_irq_clear, | 792 | .sff_irq_clear = octeon_cf_irq_clear, |
807 | .bmdma_setup = unreachable_qc, | ||
808 | .bmdma_start = unreachable_qc, | ||
809 | .bmdma_stop = unreachable_qc, | ||
810 | .bmdma_status = unreachable_port, | ||
811 | .cable_detect = ata_cable_40wire, | 793 | .cable_detect = ata_cable_40wire, |
812 | .set_piomode = octeon_cf_set_piomode, | 794 | .set_piomode = octeon_cf_set_piomode, |
813 | .set_dmamode = octeon_cf_set_dmamode, | 795 | .set_dmamode = octeon_cf_set_dmamode, |
diff --git a/drivers/ata/pata_oldpiix.c b/drivers/ata/pata_oldpiix.c index 988ef2627be3..b811c1636204 100644 --- a/drivers/ata/pata_oldpiix.c +++ b/drivers/ata/pata_oldpiix.c | |||
@@ -248,7 +248,7 @@ static int oldpiix_init_one (struct pci_dev *pdev, const struct pci_device_id *e | |||
248 | dev_printk(KERN_DEBUG, &pdev->dev, | 248 | dev_printk(KERN_DEBUG, &pdev->dev, |
249 | "version " DRV_VERSION "\n"); | 249 | "version " DRV_VERSION "\n"); |
250 | 250 | ||
251 | return ata_pci_sff_init_one(pdev, ppi, &oldpiix_sht, NULL, 0); | 251 | return ata_pci_bmdma_init_one(pdev, ppi, &oldpiix_sht, NULL, 0); |
252 | } | 252 | } |
253 | 253 | ||
254 | static const struct pci_device_id oldpiix_pci_tbl[] = { | 254 | static const struct pci_device_id oldpiix_pci_tbl[] = { |
diff --git a/drivers/ata/pata_optidma.c b/drivers/ata/pata_optidma.c index 76b7d12b1e8d..0852cd07de08 100644 --- a/drivers/ata/pata_optidma.c +++ b/drivers/ata/pata_optidma.c | |||
@@ -429,7 +429,7 @@ static int optidma_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
429 | if (optiplus_with_udma(dev)) | 429 | if (optiplus_with_udma(dev)) |
430 | ppi[0] = &info_82c700_udma; | 430 | ppi[0] = &info_82c700_udma; |
431 | 431 | ||
432 | return ata_pci_sff_init_one(dev, ppi, &optidma_sht, NULL, 0); | 432 | return ata_pci_bmdma_init_one(dev, ppi, &optidma_sht, NULL, 0); |
433 | } | 433 | } |
434 | 434 | ||
435 | static const struct pci_device_id optidma[] = { | 435 | static const struct pci_device_id optidma[] = { |
diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c index 09f1f22c0307..b18351122525 100644 --- a/drivers/ata/pata_pdc2027x.c +++ b/drivers/ata/pata_pdc2027x.c | |||
@@ -754,7 +754,7 @@ static int __devinit pdc2027x_init_one(struct pci_dev *pdev, const struct pci_de | |||
754 | return -EIO; | 754 | return -EIO; |
755 | 755 | ||
756 | pci_set_master(pdev); | 756 | pci_set_master(pdev); |
757 | return ata_host_activate(host, pdev->irq, ata_sff_interrupt, | 757 | return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt, |
758 | IRQF_SHARED, &pdc2027x_sht); | 758 | IRQF_SHARED, &pdc2027x_sht); |
759 | } | 759 | } |
760 | 760 | ||
diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c index fa1e2f3bc0fd..c39f213e1bbc 100644 --- a/drivers/ata/pata_pdc202xx_old.c +++ b/drivers/ata/pata_pdc202xx_old.c | |||
@@ -337,7 +337,7 @@ static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id | |||
337 | return -ENODEV; | 337 | return -ENODEV; |
338 | } | 338 | } |
339 | } | 339 | } |
340 | return ata_pci_sff_init_one(dev, ppi, &pdc202xx_sht, NULL, 0); | 340 | return ata_pci_bmdma_init_one(dev, ppi, &pdc202xx_sht, NULL, 0); |
341 | } | 341 | } |
342 | 342 | ||
343 | static const struct pci_device_id pdc202xx[] = { | 343 | static const struct pci_device_id pdc202xx[] = { |
diff --git a/drivers/ata/pata_piccolo.c b/drivers/ata/pata_piccolo.c index 981615414849..cb01bf9496fe 100644 --- a/drivers/ata/pata_piccolo.c +++ b/drivers/ata/pata_piccolo.c | |||
@@ -95,7 +95,7 @@ static int ata_tosh_init_one(struct pci_dev *dev, const struct pci_device_id *id | |||
95 | }; | 95 | }; |
96 | const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info }; | 96 | const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info }; |
97 | /* Just one port for the moment */ | 97 | /* Just one port for the moment */ |
98 | return ata_pci_sff_init_one(dev, ppi, &tosh_sht, NULL, 0); | 98 | return ata_pci_bmdma_init_one(dev, ppi, &tosh_sht, NULL, 0); |
99 | } | 99 | } |
100 | 100 | ||
101 | static struct pci_device_id ata_tosh[] = { | 101 | static struct pci_device_id ata_tosh[] = { |
diff --git a/drivers/ata/pata_radisys.c b/drivers/ata/pata_radisys.c index a5fa388e5398..8574b31f1773 100644 --- a/drivers/ata/pata_radisys.c +++ b/drivers/ata/pata_radisys.c | |||
@@ -227,7 +227,7 @@ static int radisys_init_one (struct pci_dev *pdev, const struct pci_device_id *e | |||
227 | dev_printk(KERN_DEBUG, &pdev->dev, | 227 | dev_printk(KERN_DEBUG, &pdev->dev, |
228 | "version " DRV_VERSION "\n"); | 228 | "version " DRV_VERSION "\n"); |
229 | 229 | ||
230 | return ata_pci_sff_init_one(pdev, ppi, &radisys_sht, NULL, 0); | 230 | return ata_pci_bmdma_init_one(pdev, ppi, &radisys_sht, NULL, 0); |
231 | } | 231 | } |
232 | 232 | ||
233 | static const struct pci_device_id radisys_pci_tbl[] = { | 233 | static const struct pci_device_id radisys_pci_tbl[] = { |
diff --git a/drivers/ata/pata_rdc.c b/drivers/ata/pata_rdc.c index 37092cfd7bc6..5fbe9b166c69 100644 --- a/drivers/ata/pata_rdc.c +++ b/drivers/ata/pata_rdc.c | |||
@@ -344,7 +344,7 @@ static int __devinit rdc_init_one(struct pci_dev *pdev, | |||
344 | */ | 344 | */ |
345 | pci_read_config_dword(pdev, 0x54, &hpriv->saved_iocfg); | 345 | pci_read_config_dword(pdev, 0x54, &hpriv->saved_iocfg); |
346 | 346 | ||
347 | rc = ata_pci_sff_prepare_host(pdev, ppi, &host); | 347 | rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host); |
348 | if (rc) | 348 | if (rc) |
349 | return rc; | 349 | return rc; |
350 | host->private_data = hpriv; | 350 | host->private_data = hpriv; |
@@ -354,7 +354,7 @@ static int __devinit rdc_init_one(struct pci_dev *pdev, | |||
354 | host->flags |= ATA_HOST_PARALLEL_SCAN; | 354 | host->flags |= ATA_HOST_PARALLEL_SCAN; |
355 | 355 | ||
356 | pci_set_master(pdev); | 356 | pci_set_master(pdev); |
357 | return ata_pci_sff_activate_host(host, ata_sff_interrupt, &rdc_sht); | 357 | return ata_pci_sff_activate_host(host, ata_bmdma_interrupt, &rdc_sht); |
358 | } | 358 | } |
359 | 359 | ||
360 | static void rdc_remove_one(struct pci_dev *pdev) | 360 | static void rdc_remove_one(struct pci_dev *pdev) |
diff --git a/drivers/ata/pata_sc1200.c b/drivers/ata/pata_sc1200.c index 6b5b63a2fd8e..e2c18257adff 100644 --- a/drivers/ata/pata_sc1200.c +++ b/drivers/ata/pata_sc1200.c | |||
@@ -237,7 +237,7 @@ static int sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
237 | }; | 237 | }; |
238 | const struct ata_port_info *ppi[] = { &info, NULL }; | 238 | const struct ata_port_info *ppi[] = { &info, NULL }; |
239 | 239 | ||
240 | return ata_pci_sff_init_one(dev, ppi, &sc1200_sht, NULL, 0); | 240 | return ata_pci_bmdma_init_one(dev, ppi, &sc1200_sht, NULL, 0); |
241 | } | 241 | } |
242 | 242 | ||
243 | static const struct pci_device_id sc1200[] = { | 243 | static const struct pci_device_id sc1200[] = { |
diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c index 6f6193b707cb..d9db3f8d60ef 100644 --- a/drivers/ata/pata_scc.c +++ b/drivers/ata/pata_scc.c | |||
@@ -875,7 +875,7 @@ static void scc_postreset(struct ata_link *link, unsigned int *classes) | |||
875 | * scc_irq_clear - Clear PCI IDE BMDMA interrupt. | 875 | * scc_irq_clear - Clear PCI IDE BMDMA interrupt. |
876 | * @ap: Port associated with this ATA transaction. | 876 | * @ap: Port associated with this ATA transaction. |
877 | * | 877 | * |
878 | * Note: Original code is ata_sff_irq_clear(). | 878 | * Note: Original code is ata_bmdma_irq_clear(). |
879 | */ | 879 | */ |
880 | 880 | ||
881 | static void scc_irq_clear (struct ata_port *ap) | 881 | static void scc_irq_clear (struct ata_port *ap) |
@@ -1105,7 +1105,7 @@ static int scc_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1105 | if (rc) | 1105 | if (rc) |
1106 | return rc; | 1106 | return rc; |
1107 | 1107 | ||
1108 | return ata_host_activate(host, pdev->irq, ata_sff_interrupt, | 1108 | return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt, |
1109 | IRQF_SHARED, &scc_sht); | 1109 | IRQF_SHARED, &scc_sht); |
1110 | } | 1110 | } |
1111 | 1111 | ||
diff --git a/drivers/ata/pata_sch.c b/drivers/ata/pata_sch.c index 86b3d0133c7c..e97b32f03a6e 100644 --- a/drivers/ata/pata_sch.c +++ b/drivers/ata/pata_sch.c | |||
@@ -179,7 +179,7 @@ static int __devinit sch_init_one(struct pci_dev *pdev, | |||
179 | dev_printk(KERN_DEBUG, &pdev->dev, | 179 | dev_printk(KERN_DEBUG, &pdev->dev, |
180 | "version " DRV_VERSION "\n"); | 180 | "version " DRV_VERSION "\n"); |
181 | 181 | ||
182 | return ata_pci_sff_init_one(pdev, ppi, &sch_sht, NULL, 0); | 182 | return ata_pci_bmdma_init_one(pdev, ppi, &sch_sht, NULL, 0); |
183 | } | 183 | } |
184 | 184 | ||
185 | static int __init sch_init(void) | 185 | static int __init sch_init(void) |
diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c index 43ea389df2b3..86dd714e3e1d 100644 --- a/drivers/ata/pata_serverworks.c +++ b/drivers/ata/pata_serverworks.c | |||
@@ -460,7 +460,7 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id | |||
460 | if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE) | 460 | if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE) |
461 | ata_pci_bmdma_clear_simplex(pdev); | 461 | ata_pci_bmdma_clear_simplex(pdev); |
462 | 462 | ||
463 | return ata_pci_sff_init_one(pdev, ppi, &serverworks_sht, NULL, 0); | 463 | return ata_pci_bmdma_init_one(pdev, ppi, &serverworks_sht, NULL, 0); |
464 | } | 464 | } |
465 | 465 | ||
466 | #ifdef CONFIG_PM | 466 | #ifdef CONFIG_PM |
diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c index 43faf106f647..d3190d7ec304 100644 --- a/drivers/ata/pata_sil680.c +++ b/drivers/ata/pata_sil680.c | |||
@@ -374,11 +374,11 @@ static int __devinit sil680_init_one(struct pci_dev *pdev, | |||
374 | ata_sff_std_ports(&host->ports[1]->ioaddr); | 374 | ata_sff_std_ports(&host->ports[1]->ioaddr); |
375 | 375 | ||
376 | /* Register & activate */ | 376 | /* Register & activate */ |
377 | return ata_host_activate(host, pdev->irq, ata_sff_interrupt, | 377 | return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt, |
378 | IRQF_SHARED, &sil680_sht); | 378 | IRQF_SHARED, &sil680_sht); |
379 | 379 | ||
380 | use_ioports: | 380 | use_ioports: |
381 | return ata_pci_sff_init_one(pdev, ppi, &sil680_sht, NULL, 0); | 381 | return ata_pci_bmdma_init_one(pdev, ppi, &sil680_sht, NULL, 0); |
382 | } | 382 | } |
383 | 383 | ||
384 | #ifdef CONFIG_PM | 384 | #ifdef CONFIG_PM |
diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c index b6708032f321..60cea13cccce 100644 --- a/drivers/ata/pata_sis.c +++ b/drivers/ata/pata_sis.c | |||
@@ -826,7 +826,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
826 | 826 | ||
827 | sis_fixup(pdev, chipset); | 827 | sis_fixup(pdev, chipset); |
828 | 828 | ||
829 | return ata_pci_sff_init_one(pdev, ppi, &sis_sht, chipset, 0); | 829 | return ata_pci_bmdma_init_one(pdev, ppi, &sis_sht, chipset, 0); |
830 | } | 830 | } |
831 | 831 | ||
832 | #ifdef CONFIG_PM | 832 | #ifdef CONFIG_PM |
diff --git a/drivers/ata/pata_sl82c105.c b/drivers/ata/pata_sl82c105.c index 733b042a7469..98548f640c8e 100644 --- a/drivers/ata/pata_sl82c105.c +++ b/drivers/ata/pata_sl82c105.c | |||
@@ -316,7 +316,7 @@ static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id | |||
316 | val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16; | 316 | val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16; |
317 | pci_write_config_dword(dev, 0x40, val); | 317 | pci_write_config_dword(dev, 0x40, val); |
318 | 318 | ||
319 | return ata_pci_sff_init_one(dev, ppi, &sl82c105_sht, NULL, 0); | 319 | return ata_pci_bmdma_init_one(dev, ppi, &sl82c105_sht, NULL, 0); |
320 | } | 320 | } |
321 | 321 | ||
322 | static const struct pci_device_id sl82c105[] = { | 322 | static const struct pci_device_id sl82c105[] = { |
diff --git a/drivers/ata/pata_triflex.c b/drivers/ata/pata_triflex.c index 48f50600ed2a..0d1f89e571dd 100644 --- a/drivers/ata/pata_triflex.c +++ b/drivers/ata/pata_triflex.c | |||
@@ -201,7 +201,7 @@ static int triflex_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
201 | if (!printed_version++) | 201 | if (!printed_version++) |
202 | dev_printk(KERN_DEBUG, &dev->dev, "version " DRV_VERSION "\n"); | 202 | dev_printk(KERN_DEBUG, &dev->dev, "version " DRV_VERSION "\n"); |
203 | 203 | ||
204 | return ata_pci_sff_init_one(dev, ppi, &triflex_sht, NULL, 0); | 204 | return ata_pci_bmdma_init_one(dev, ppi, &triflex_sht, NULL, 0); |
205 | } | 205 | } |
206 | 206 | ||
207 | static const struct pci_device_id triflex[] = { | 207 | static const struct pci_device_id triflex[] = { |
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index 7e3e0a5598b7..5e659885de16 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c | |||
@@ -627,7 +627,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
627 | } | 627 | } |
628 | 628 | ||
629 | /* We have established the device type, now fire it up */ | 629 | /* We have established the device type, now fire it up */ |
630 | return ata_pci_sff_init_one(pdev, ppi, &via_sht, (void *)config, 0); | 630 | return ata_pci_bmdma_init_one(pdev, ppi, &via_sht, (void *)config, 0); |
631 | } | 631 | } |
632 | 632 | ||
633 | #ifdef CONFIG_PM | 633 | #ifdef CONFIG_PM |
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index f3471bc949d3..a476cd99b95d 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -675,8 +675,6 @@ static struct ata_port_operations mv5_ops = { | |||
675 | .freeze = mv_eh_freeze, | 675 | .freeze = mv_eh_freeze, |
676 | .thaw = mv_eh_thaw, | 676 | .thaw = mv_eh_thaw, |
677 | .hardreset = mv_hardreset, | 677 | .hardreset = mv_hardreset, |
678 | .error_handler = ata_std_error_handler, /* avoid SFF EH */ | ||
679 | .post_internal_cmd = ATA_OP_NULL, | ||
680 | 678 | ||
681 | .scr_read = mv5_scr_read, | 679 | .scr_read = mv5_scr_read, |
682 | .scr_write = mv5_scr_write, | 680 | .scr_write = mv5_scr_write, |
@@ -2813,7 +2811,7 @@ static void mv_port_intr(struct ata_port *ap, u32 port_cause) | |||
2813 | } else if (!edma_was_enabled) { | 2811 | } else if (!edma_was_enabled) { |
2814 | struct ata_queued_cmd *qc = mv_get_active_qc(ap); | 2812 | struct ata_queued_cmd *qc = mv_get_active_qc(ap); |
2815 | if (qc) | 2813 | if (qc) |
2816 | ata_sff_host_intr(ap, qc); | 2814 | ata_bmdma_port_intr(ap, qc); |
2817 | else | 2815 | else |
2818 | mv_unexpected_intr(ap, edma_was_enabled); | 2816 | mv_unexpected_intr(ap, edma_was_enabled); |
2819 | } | 2817 | } |
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index baa8f0d2c86f..6fd114784116 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c | |||
@@ -920,7 +920,7 @@ static int nv_host_intr(struct ata_port *ap, u8 irq_stat) | |||
920 | } | 920 | } |
921 | 921 | ||
922 | /* handle interrupt */ | 922 | /* handle interrupt */ |
923 | return ata_sff_host_intr(ap, qc); | 923 | return ata_bmdma_port_intr(ap, qc); |
924 | } | 924 | } |
925 | 925 | ||
926 | static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance) | 926 | static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance) |
@@ -1100,7 +1100,7 @@ static void nv_adma_irq_clear(struct ata_port *ap) | |||
1100 | u32 notifier_clears[2]; | 1100 | u32 notifier_clears[2]; |
1101 | 1101 | ||
1102 | if (pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE) { | 1102 | if (pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE) { |
1103 | ata_sff_irq_clear(ap); | 1103 | ata_bmdma_irq_clear(ap); |
1104 | return; | 1104 | return; |
1105 | } | 1105 | } |
1106 | 1106 | ||
@@ -1505,7 +1505,7 @@ static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance) | |||
1505 | 1505 | ||
1506 | qc = ata_qc_from_tag(ap, ap->link.active_tag); | 1506 | qc = ata_qc_from_tag(ap, ap->link.active_tag); |
1507 | if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) { | 1507 | if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) { |
1508 | handled += ata_sff_host_intr(ap, qc); | 1508 | handled += ata_bmdma_port_intr(ap, qc); |
1509 | } else { | 1509 | } else { |
1510 | /* | 1510 | /* |
1511 | * No request pending? Clear interrupt status | 1511 | * No request pending? Clear interrupt status |
@@ -2430,7 +2430,7 @@ static int nv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2430 | 2430 | ||
2431 | ppi[0] = &nv_port_info[type]; | 2431 | ppi[0] = &nv_port_info[type]; |
2432 | ipriv = ppi[0]->private_data; | 2432 | ipriv = ppi[0]->private_data; |
2433 | rc = ata_pci_sff_prepare_host(pdev, ppi, &host); | 2433 | rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host); |
2434 | if (rc) | 2434 | if (rc) |
2435 | return rc; | 2435 | return rc; |
2436 | 2436 | ||
diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c index d533b3d20ca1..daeebf19a6a9 100644 --- a/drivers/ata/sata_qstor.c +++ b/drivers/ata/sata_qstor.c | |||
@@ -120,8 +120,6 @@ static void qs_host_stop(struct ata_host *host); | |||
120 | static void qs_qc_prep(struct ata_queued_cmd *qc); | 120 | static void qs_qc_prep(struct ata_queued_cmd *qc); |
121 | static unsigned int qs_qc_issue(struct ata_queued_cmd *qc); | 121 | static unsigned int qs_qc_issue(struct ata_queued_cmd *qc); |
122 | static int qs_check_atapi_dma(struct ata_queued_cmd *qc); | 122 | static int qs_check_atapi_dma(struct ata_queued_cmd *qc); |
123 | static void qs_bmdma_stop(struct ata_queued_cmd *qc); | ||
124 | static u8 qs_bmdma_status(struct ata_port *ap); | ||
125 | static void qs_freeze(struct ata_port *ap); | 123 | static void qs_freeze(struct ata_port *ap); |
126 | static void qs_thaw(struct ata_port *ap); | 124 | static void qs_thaw(struct ata_port *ap); |
127 | static int qs_prereset(struct ata_link *link, unsigned long deadline); | 125 | static int qs_prereset(struct ata_link *link, unsigned long deadline); |
@@ -137,8 +135,6 @@ static struct ata_port_operations qs_ata_ops = { | |||
137 | .inherits = &ata_sff_port_ops, | 135 | .inherits = &ata_sff_port_ops, |
138 | 136 | ||
139 | .check_atapi_dma = qs_check_atapi_dma, | 137 | .check_atapi_dma = qs_check_atapi_dma, |
140 | .bmdma_stop = qs_bmdma_stop, | ||
141 | .bmdma_status = qs_bmdma_status, | ||
142 | .qc_prep = qs_qc_prep, | 138 | .qc_prep = qs_qc_prep, |
143 | .qc_issue = qs_qc_issue, | 139 | .qc_issue = qs_qc_issue, |
144 | 140 | ||
@@ -190,16 +186,6 @@ static int qs_check_atapi_dma(struct ata_queued_cmd *qc) | |||
190 | return 1; /* ATAPI DMA not supported */ | 186 | return 1; /* ATAPI DMA not supported */ |
191 | } | 187 | } |
192 | 188 | ||
193 | static void qs_bmdma_stop(struct ata_queued_cmd *qc) | ||
194 | { | ||
195 | /* nothing */ | ||
196 | } | ||
197 | |||
198 | static u8 qs_bmdma_status(struct ata_port *ap) | ||
199 | { | ||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | static inline void qs_enter_reg_mode(struct ata_port *ap) | 189 | static inline void qs_enter_reg_mode(struct ata_port *ap) |
204 | { | 190 | { |
205 | u8 __iomem *chan = qs_mmio_base(ap->host) + (ap->port_no * 0x4000); | 191 | u8 __iomem *chan = qs_mmio_base(ap->host) + (ap->port_no * 0x4000); |
@@ -454,7 +440,7 @@ static inline unsigned int qs_intr_mmio(struct ata_host *host) | |||
454 | if (!pp || pp->state != qs_state_mmio) | 440 | if (!pp || pp->state != qs_state_mmio) |
455 | continue; | 441 | continue; |
456 | if (!(qc->tf.flags & ATA_TFLAG_POLLING)) | 442 | if (!(qc->tf.flags & ATA_TFLAG_POLLING)) |
457 | handled |= ata_sff_host_intr(ap, qc); | 443 | handled |= ata_sff_port_intr(ap, qc); |
458 | } | 444 | } |
459 | return handled; | 445 | return handled; |
460 | } | 446 | } |
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c index 2dda312b6b9a..3a4f84219719 100644 --- a/drivers/ata/sata_sil.c +++ b/drivers/ata/sata_sil.c | |||
@@ -503,7 +503,7 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2) | |||
503 | goto err_hsm; | 503 | goto err_hsm; |
504 | 504 | ||
505 | /* ack bmdma irq events */ | 505 | /* ack bmdma irq events */ |
506 | ata_sff_irq_clear(ap); | 506 | ata_bmdma_irq_clear(ap); |
507 | 507 | ||
508 | /* kick HSM in the ass */ | 508 | /* kick HSM in the ass */ |
509 | ata_sff_hsm_move(ap, qc, status, 0); | 509 | ata_sff_hsm_move(ap, qc, status, 0); |
@@ -584,7 +584,7 @@ static void sil_thaw(struct ata_port *ap) | |||
584 | 584 | ||
585 | /* clear IRQ */ | 585 | /* clear IRQ */ |
586 | ap->ops->sff_check_status(ap); | 586 | ap->ops->sff_check_status(ap); |
587 | ata_sff_irq_clear(ap); | 587 | ata_bmdma_irq_clear(ap); |
588 | 588 | ||
589 | /* turn on SATA IRQ if supported */ | 589 | /* turn on SATA IRQ if supported */ |
590 | if (!(ap->flags & SIL_FLAG_NO_SATA_IRQ)) | 590 | if (!(ap->flags & SIL_FLAG_NO_SATA_IRQ)) |
diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c index f8a91bfd66a8..2bfe3ae03976 100644 --- a/drivers/ata/sata_sis.c +++ b/drivers/ata/sata_sis.c | |||
@@ -279,7 +279,7 @@ static int sis_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
279 | break; | 279 | break; |
280 | } | 280 | } |
281 | 281 | ||
282 | rc = ata_pci_sff_prepare_host(pdev, ppi, &host); | 282 | rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host); |
283 | if (rc) | 283 | if (rc) |
284 | return rc; | 284 | return rc; |
285 | 285 | ||
@@ -308,7 +308,7 @@ static int sis_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
308 | 308 | ||
309 | pci_set_master(pdev); | 309 | pci_set_master(pdev); |
310 | pci_intx(pdev, 1); | 310 | pci_intx(pdev, 1); |
311 | return ata_host_activate(host, pdev->irq, ata_sff_interrupt, | 311 | return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt, |
312 | IRQF_SHARED, &sis_sht); | 312 | IRQF_SHARED, &sis_sht); |
313 | } | 313 | } |
314 | 314 | ||
diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c index 101fd6a19829..7d9db4aaf07e 100644 --- a/drivers/ata/sata_svw.c +++ b/drivers/ata/sata_svw.c | |||
@@ -502,7 +502,7 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en | |||
502 | writel(0x0, mmio_base + K2_SATA_SIM_OFFSET); | 502 | writel(0x0, mmio_base + K2_SATA_SIM_OFFSET); |
503 | 503 | ||
504 | pci_set_master(pdev); | 504 | pci_set_master(pdev); |
505 | return ata_host_activate(host, pdev->irq, ata_sff_interrupt, | 505 | return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt, |
506 | IRQF_SHARED, &k2_sata_sht); | 506 | IRQF_SHARED, &k2_sata_sht); |
507 | } | 507 | } |
508 | 508 | ||
diff --git a/drivers/ata/sata_uli.c b/drivers/ata/sata_uli.c index d8dac17dc2c8..b8578c32d344 100644 --- a/drivers/ata/sata_uli.c +++ b/drivers/ata/sata_uli.c | |||
@@ -242,7 +242,7 @@ static int uli_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
242 | 242 | ||
243 | pci_set_master(pdev); | 243 | pci_set_master(pdev); |
244 | pci_intx(pdev, 1); | 244 | pci_intx(pdev, 1); |
245 | return ata_host_activate(host, pdev->irq, ata_sff_interrupt, | 245 | return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt, |
246 | IRQF_SHARED, &uli_sht); | 246 | IRQF_SHARED, &uli_sht); |
247 | } | 247 | } |
248 | 248 | ||
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index 08f65492cc81..101d8c219caf 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c | |||
@@ -308,7 +308,7 @@ static void svia_noop_freeze(struct ata_port *ap) | |||
308 | * certain way. Leave it alone and just clear pending IRQ. | 308 | * certain way. Leave it alone and just clear pending IRQ. |
309 | */ | 309 | */ |
310 | ap->ops->sff_check_status(ap); | 310 | ap->ops->sff_check_status(ap); |
311 | ata_sff_irq_clear(ap); | 311 | ata_bmdma_irq_clear(ap); |
312 | } | 312 | } |
313 | 313 | ||
314 | /** | 314 | /** |
@@ -463,7 +463,7 @@ static int vt6420_prepare_host(struct pci_dev *pdev, struct ata_host **r_host) | |||
463 | struct ata_host *host; | 463 | struct ata_host *host; |
464 | int rc; | 464 | int rc; |
465 | 465 | ||
466 | rc = ata_pci_sff_prepare_host(pdev, ppi, &host); | 466 | rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host); |
467 | if (rc) | 467 | if (rc) |
468 | return rc; | 468 | return rc; |
469 | *r_host = host; | 469 | *r_host = host; |
@@ -520,7 +520,7 @@ static int vt8251_prepare_host(struct pci_dev *pdev, struct ata_host **r_host) | |||
520 | struct ata_host *host; | 520 | struct ata_host *host; |
521 | int i, rc; | 521 | int i, rc; |
522 | 522 | ||
523 | rc = ata_pci_sff_prepare_host(pdev, ppi, &host); | 523 | rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host); |
524 | if (rc) | 524 | if (rc) |
525 | return rc; | 525 | return rc; |
526 | *r_host = host; | 526 | *r_host = host; |
@@ -628,7 +628,7 @@ static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
628 | svia_configure(pdev); | 628 | svia_configure(pdev); |
629 | 629 | ||
630 | pci_set_master(pdev); | 630 | pci_set_master(pdev); |
631 | return ata_host_activate(host, pdev->irq, ata_sff_interrupt, | 631 | return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt, |
632 | IRQF_SHARED, &svia_sht); | 632 | IRQF_SHARED, &svia_sht); |
633 | } | 633 | } |
634 | 634 | ||
diff --git a/drivers/ata/sata_vsc.c b/drivers/ata/sata_vsc.c index 2107952ebff1..b777176ff494 100644 --- a/drivers/ata/sata_vsc.c +++ b/drivers/ata/sata_vsc.c | |||
@@ -245,7 +245,7 @@ static void vsc_port_intr(u8 port_status, struct ata_port *ap) | |||
245 | 245 | ||
246 | qc = ata_qc_from_tag(ap, ap->link.active_tag); | 246 | qc = ata_qc_from_tag(ap, ap->link.active_tag); |
247 | if (qc && likely(!(qc->tf.flags & ATA_TFLAG_POLLING))) | 247 | if (qc && likely(!(qc->tf.flags & ATA_TFLAG_POLLING))) |
248 | handled = ata_sff_host_intr(ap, qc); | 248 | handled = ata_bmdma_port_intr(ap, qc); |
249 | 249 | ||
250 | /* We received an interrupt during a polled command, | 250 | /* We received an interrupt during a polled command, |
251 | * or some other spurious condition. Interrupt reporting | 251 | * or some other spurious condition. Interrupt reporting |
diff --git a/drivers/char/ps3flash.c b/drivers/char/ps3flash.c index 606048b72bcf..85c004a518ee 100644 --- a/drivers/char/ps3flash.c +++ b/drivers/char/ps3flash.c | |||
@@ -305,8 +305,7 @@ static int ps3flash_flush(struct file *file, fl_owner_t id) | |||
305 | return ps3flash_writeback(ps3flash_dev); | 305 | return ps3flash_writeback(ps3flash_dev); |
306 | } | 306 | } |
307 | 307 | ||
308 | static int ps3flash_fsync(struct file *file, struct dentry *dentry, | 308 | static int ps3flash_fsync(struct file *file, int datasync) |
309 | int datasync) | ||
310 | { | 309 | { |
311 | return ps3flash_writeback(ps3flash_dev); | 310 | return ps3flash_writeback(ps3flash_dev); |
312 | } | 311 | } |
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 12fdd3987a36..199488576a05 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c | |||
@@ -156,7 +156,7 @@ int cpuidle_enable_device(struct cpuidle_device *dev) | |||
156 | 156 | ||
157 | if (dev->enabled) | 157 | if (dev->enabled) |
158 | return 0; | 158 | return 0; |
159 | if (!cpuidle_curr_driver || !cpuidle_curr_governor) | 159 | if (!cpuidle_get_driver() || !cpuidle_curr_governor) |
160 | return -EIO; | 160 | return -EIO; |
161 | if (!dev->state_count) | 161 | if (!dev->state_count) |
162 | return -EINVAL; | 162 | return -EINVAL; |
@@ -207,7 +207,7 @@ void cpuidle_disable_device(struct cpuidle_device *dev) | |||
207 | { | 207 | { |
208 | if (!dev->enabled) | 208 | if (!dev->enabled) |
209 | return; | 209 | return; |
210 | if (!cpuidle_curr_driver || !cpuidle_curr_governor) | 210 | if (!cpuidle_get_driver() || !cpuidle_curr_governor) |
211 | return; | 211 | return; |
212 | 212 | ||
213 | dev->enabled = 0; | 213 | dev->enabled = 0; |
@@ -271,10 +271,11 @@ static int __cpuidle_register_device(struct cpuidle_device *dev) | |||
271 | { | 271 | { |
272 | int ret; | 272 | int ret; |
273 | struct sys_device *sys_dev = get_cpu_sysdev((unsigned long)dev->cpu); | 273 | struct sys_device *sys_dev = get_cpu_sysdev((unsigned long)dev->cpu); |
274 | struct cpuidle_driver *cpuidle_driver = cpuidle_get_driver(); | ||
274 | 275 | ||
275 | if (!sys_dev) | 276 | if (!sys_dev) |
276 | return -EINVAL; | 277 | return -EINVAL; |
277 | if (!try_module_get(cpuidle_curr_driver->owner)) | 278 | if (!try_module_get(cpuidle_driver->owner)) |
278 | return -EINVAL; | 279 | return -EINVAL; |
279 | 280 | ||
280 | init_completion(&dev->kobj_unregister); | 281 | init_completion(&dev->kobj_unregister); |
@@ -284,7 +285,7 @@ static int __cpuidle_register_device(struct cpuidle_device *dev) | |||
284 | per_cpu(cpuidle_devices, dev->cpu) = dev; | 285 | per_cpu(cpuidle_devices, dev->cpu) = dev; |
285 | list_add(&dev->device_list, &cpuidle_detected_devices); | 286 | list_add(&dev->device_list, &cpuidle_detected_devices); |
286 | if ((ret = cpuidle_add_sysfs(sys_dev))) { | 287 | if ((ret = cpuidle_add_sysfs(sys_dev))) { |
287 | module_put(cpuidle_curr_driver->owner); | 288 | module_put(cpuidle_driver->owner); |
288 | return ret; | 289 | return ret; |
289 | } | 290 | } |
290 | 291 | ||
@@ -325,6 +326,7 @@ EXPORT_SYMBOL_GPL(cpuidle_register_device); | |||
325 | void cpuidle_unregister_device(struct cpuidle_device *dev) | 326 | void cpuidle_unregister_device(struct cpuidle_device *dev) |
326 | { | 327 | { |
327 | struct sys_device *sys_dev = get_cpu_sysdev((unsigned long)dev->cpu); | 328 | struct sys_device *sys_dev = get_cpu_sysdev((unsigned long)dev->cpu); |
329 | struct cpuidle_driver *cpuidle_driver = cpuidle_get_driver(); | ||
328 | 330 | ||
329 | if (dev->registered == 0) | 331 | if (dev->registered == 0) |
330 | return; | 332 | return; |
@@ -340,7 +342,7 @@ void cpuidle_unregister_device(struct cpuidle_device *dev) | |||
340 | 342 | ||
341 | cpuidle_resume_and_unlock(); | 343 | cpuidle_resume_and_unlock(); |
342 | 344 | ||
343 | module_put(cpuidle_curr_driver->owner); | 345 | module_put(cpuidle_driver->owner); |
344 | } | 346 | } |
345 | 347 | ||
346 | EXPORT_SYMBOL_GPL(cpuidle_unregister_device); | 348 | EXPORT_SYMBOL_GPL(cpuidle_unregister_device); |
diff --git a/drivers/cpuidle/cpuidle.h b/drivers/cpuidle/cpuidle.h index 9476ba33ee2c..33e50d556f17 100644 --- a/drivers/cpuidle/cpuidle.h +++ b/drivers/cpuidle/cpuidle.h | |||
@@ -9,7 +9,6 @@ | |||
9 | 9 | ||
10 | /* For internal use only */ | 10 | /* For internal use only */ |
11 | extern struct cpuidle_governor *cpuidle_curr_governor; | 11 | extern struct cpuidle_governor *cpuidle_curr_governor; |
12 | extern struct cpuidle_driver *cpuidle_curr_driver; | ||
13 | extern struct list_head cpuidle_governors; | 12 | extern struct list_head cpuidle_governors; |
14 | extern struct list_head cpuidle_detected_devices; | 13 | extern struct list_head cpuidle_detected_devices; |
15 | extern struct mutex cpuidle_lock; | 14 | extern struct mutex cpuidle_lock; |
diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c index 2257004fe33d..fd1601e3d125 100644 --- a/drivers/cpuidle/driver.c +++ b/drivers/cpuidle/driver.c | |||
@@ -14,7 +14,7 @@ | |||
14 | 14 | ||
15 | #include "cpuidle.h" | 15 | #include "cpuidle.h" |
16 | 16 | ||
17 | struct cpuidle_driver *cpuidle_curr_driver; | 17 | static struct cpuidle_driver *cpuidle_curr_driver; |
18 | DEFINE_SPINLOCK(cpuidle_driver_lock); | 18 | DEFINE_SPINLOCK(cpuidle_driver_lock); |
19 | 19 | ||
20 | /** | 20 | /** |
@@ -40,13 +40,25 @@ int cpuidle_register_driver(struct cpuidle_driver *drv) | |||
40 | EXPORT_SYMBOL_GPL(cpuidle_register_driver); | 40 | EXPORT_SYMBOL_GPL(cpuidle_register_driver); |
41 | 41 | ||
42 | /** | 42 | /** |
43 | * cpuidle_get_driver - return the current driver | ||
44 | */ | ||
45 | struct cpuidle_driver *cpuidle_get_driver(void) | ||
46 | { | ||
47 | return cpuidle_curr_driver; | ||
48 | } | ||
49 | EXPORT_SYMBOL_GPL(cpuidle_get_driver); | ||
50 | |||
51 | /** | ||
43 | * cpuidle_unregister_driver - unregisters a driver | 52 | * cpuidle_unregister_driver - unregisters a driver |
44 | * @drv: the driver | 53 | * @drv: the driver |
45 | */ | 54 | */ |
46 | void cpuidle_unregister_driver(struct cpuidle_driver *drv) | 55 | void cpuidle_unregister_driver(struct cpuidle_driver *drv) |
47 | { | 56 | { |
48 | if (!drv) | 57 | if (drv != cpuidle_curr_driver) { |
58 | WARN(1, "invalid cpuidle_unregister_driver(%s)\n", | ||
59 | drv->name); | ||
49 | return; | 60 | return; |
61 | } | ||
50 | 62 | ||
51 | spin_lock(&cpuidle_driver_lock); | 63 | spin_lock(&cpuidle_driver_lock); |
52 | cpuidle_curr_driver = NULL; | 64 | cpuidle_curr_driver = NULL; |
diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c index 0ba9c8b8ee74..0310ffaec9df 100644 --- a/drivers/cpuidle/sysfs.c +++ b/drivers/cpuidle/sysfs.c | |||
@@ -47,10 +47,11 @@ static ssize_t show_current_driver(struct sysdev_class *class, | |||
47 | char *buf) | 47 | char *buf) |
48 | { | 48 | { |
49 | ssize_t ret; | 49 | ssize_t ret; |
50 | struct cpuidle_driver *cpuidle_driver = cpuidle_get_driver(); | ||
50 | 51 | ||
51 | spin_lock(&cpuidle_driver_lock); | 52 | spin_lock(&cpuidle_driver_lock); |
52 | if (cpuidle_curr_driver) | 53 | if (cpuidle_driver) |
53 | ret = sprintf(buf, "%s\n", cpuidle_curr_driver->name); | 54 | ret = sprintf(buf, "%s\n", cpuidle_driver->name); |
54 | else | 55 | else |
55 | ret = sprintf(buf, "none\n"); | 56 | ret = sprintf(buf, "none\n"); |
56 | spin_unlock(&cpuidle_driver_lock); | 57 | spin_unlock(&cpuidle_driver_lock); |
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 1b8877922fb0..9e01e96fee94 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig | |||
@@ -166,6 +166,15 @@ config TIMB_DMA | |||
166 | config ARCH_HAS_ASYNC_TX_FIND_CHANNEL | 166 | config ARCH_HAS_ASYNC_TX_FIND_CHANNEL |
167 | bool | 167 | bool |
168 | 168 | ||
169 | config PL330_DMA | ||
170 | tristate "DMA API Driver for PL330" | ||
171 | select DMA_ENGINE | ||
172 | depends on PL330 | ||
173 | help | ||
174 | Select if your platform has one or more PL330 DMACs. | ||
175 | You need to provide platform specific settings via | ||
176 | platform_data for a dma-pl330 device. | ||
177 | |||
169 | config DMA_ENGINE | 178 | config DMA_ENGINE |
170 | bool | 179 | bool |
171 | 180 | ||
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index 20881426c1ac..0fe5ebbfda5d 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile | |||
@@ -22,3 +22,4 @@ obj-$(CONFIG_COH901318) += coh901318.o coh901318_lli.o | |||
22 | obj-$(CONFIG_AMCC_PPC440SPE_ADMA) += ppc4xx/ | 22 | obj-$(CONFIG_AMCC_PPC440SPE_ADMA) += ppc4xx/ |
23 | obj-$(CONFIG_TIMB_DMA) += timb_dma.o | 23 | obj-$(CONFIG_TIMB_DMA) += timb_dma.o |
24 | obj-$(CONFIG_STE_DMA40) += ste_dma40.o ste_dma40_ll.o | 24 | obj-$(CONFIG_STE_DMA40) += ste_dma40.o ste_dma40_ll.o |
25 | obj-$(CONFIG_PL330_DMA) += pl330.o | ||
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c new file mode 100644 index 000000000000..7c50f6dfd3f4 --- /dev/null +++ b/drivers/dma/pl330.c | |||
@@ -0,0 +1,866 @@ | |||
1 | /* linux/drivers/dma/pl330.c | ||
2 | * | ||
3 | * Copyright (C) 2010 Samsung Electronics Co. Ltd. | ||
4 | * Jaswinder Singh <jassi.brar@samsung.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/io.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/slab.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/dmaengine.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/amba/bus.h> | ||
19 | #include <linux/amba/pl330.h> | ||
20 | |||
21 | #define NR_DEFAULT_DESC 16 | ||
22 | |||
23 | enum desc_status { | ||
24 | /* In the DMAC pool */ | ||
25 | FREE, | ||
26 | /* | ||
27 | * Allocted to some channel during prep_xxx | ||
28 | * Also may be sitting on the work_list. | ||
29 | */ | ||
30 | PREP, | ||
31 | /* | ||
32 | * Sitting on the work_list and already submitted | ||
33 | * to the PL330 core. Not more than two descriptors | ||
34 | * of a channel can be BUSY at any time. | ||
35 | */ | ||
36 | BUSY, | ||
37 | /* | ||
38 | * Sitting on the channel work_list but xfer done | ||
39 | * by PL330 core | ||
40 | */ | ||
41 | DONE, | ||
42 | }; | ||
43 | |||
44 | struct dma_pl330_chan { | ||
45 | /* Schedule desc completion */ | ||
46 | struct tasklet_struct task; | ||
47 | |||
48 | /* DMA-Engine Channel */ | ||
49 | struct dma_chan chan; | ||
50 | |||
51 | /* Last completed cookie */ | ||
52 | dma_cookie_t completed; | ||
53 | |||
54 | /* List of to be xfered descriptors */ | ||
55 | struct list_head work_list; | ||
56 | |||
57 | /* Pointer to the DMAC that manages this channel, | ||
58 | * NULL if the channel is available to be acquired. | ||
59 | * As the parent, this DMAC also provides descriptors | ||
60 | * to the channel. | ||
61 | */ | ||
62 | struct dma_pl330_dmac *dmac; | ||
63 | |||
64 | /* To protect channel manipulation */ | ||
65 | spinlock_t lock; | ||
66 | |||
67 | /* Token of a hardware channel thread of PL330 DMAC | ||
68 | * NULL if the channel is available to be acquired. | ||
69 | */ | ||
70 | void *pl330_chid; | ||
71 | }; | ||
72 | |||
73 | struct dma_pl330_dmac { | ||
74 | struct pl330_info pif; | ||
75 | |||
76 | /* DMA-Engine Device */ | ||
77 | struct dma_device ddma; | ||
78 | |||
79 | /* Pool of descriptors available for the DMAC's channels */ | ||
80 | struct list_head desc_pool; | ||
81 | /* To protect desc_pool manipulation */ | ||
82 | spinlock_t pool_lock; | ||
83 | |||
84 | /* Peripheral channels connected to this DMAC */ | ||
85 | struct dma_pl330_chan peripherals[0]; /* keep at end */ | ||
86 | }; | ||
87 | |||
88 | struct dma_pl330_desc { | ||
89 | /* To attach to a queue as child */ | ||
90 | struct list_head node; | ||
91 | |||
92 | /* Descriptor for the DMA Engine API */ | ||
93 | struct dma_async_tx_descriptor txd; | ||
94 | |||
95 | /* Xfer for PL330 core */ | ||
96 | struct pl330_xfer px; | ||
97 | |||
98 | struct pl330_reqcfg rqcfg; | ||
99 | struct pl330_req req; | ||
100 | |||
101 | enum desc_status status; | ||
102 | |||
103 | /* The channel which currently holds this desc */ | ||
104 | struct dma_pl330_chan *pchan; | ||
105 | }; | ||
106 | |||
107 | static inline struct dma_pl330_chan * | ||
108 | to_pchan(struct dma_chan *ch) | ||
109 | { | ||
110 | if (!ch) | ||
111 | return NULL; | ||
112 | |||
113 | return container_of(ch, struct dma_pl330_chan, chan); | ||
114 | } | ||
115 | |||
116 | static inline struct dma_pl330_desc * | ||
117 | to_desc(struct dma_async_tx_descriptor *tx) | ||
118 | { | ||
119 | return container_of(tx, struct dma_pl330_desc, txd); | ||
120 | } | ||
121 | |||
122 | static inline void free_desc_list(struct list_head *list) | ||
123 | { | ||
124 | struct dma_pl330_dmac *pdmac; | ||
125 | struct dma_pl330_desc *desc; | ||
126 | struct dma_pl330_chan *pch; | ||
127 | unsigned long flags; | ||
128 | |||
129 | if (list_empty(list)) | ||
130 | return; | ||
131 | |||
132 | /* Finish off the work list */ | ||
133 | list_for_each_entry(desc, list, node) { | ||
134 | dma_async_tx_callback callback; | ||
135 | void *param; | ||
136 | |||
137 | /* All desc in a list belong to same channel */ | ||
138 | pch = desc->pchan; | ||
139 | callback = desc->txd.callback; | ||
140 | param = desc->txd.callback_param; | ||
141 | |||
142 | if (callback) | ||
143 | callback(param); | ||
144 | |||
145 | desc->pchan = NULL; | ||
146 | } | ||
147 | |||
148 | pdmac = pch->dmac; | ||
149 | |||
150 | spin_lock_irqsave(&pdmac->pool_lock, flags); | ||
151 | list_splice_tail_init(list, &pdmac->desc_pool); | ||
152 | spin_unlock_irqrestore(&pdmac->pool_lock, flags); | ||
153 | } | ||
154 | |||
155 | static inline void fill_queue(struct dma_pl330_chan *pch) | ||
156 | { | ||
157 | struct dma_pl330_desc *desc; | ||
158 | int ret; | ||
159 | |||
160 | list_for_each_entry(desc, &pch->work_list, node) { | ||
161 | |||
162 | /* If already submitted */ | ||
163 | if (desc->status == BUSY) | ||
164 | break; | ||
165 | |||
166 | ret = pl330_submit_req(pch->pl330_chid, | ||
167 | &desc->req); | ||
168 | if (!ret) { | ||
169 | desc->status = BUSY; | ||
170 | break; | ||
171 | } else if (ret == -EAGAIN) { | ||
172 | /* QFull or DMAC Dying */ | ||
173 | break; | ||
174 | } else { | ||
175 | /* Unacceptable request */ | ||
176 | desc->status = DONE; | ||
177 | dev_err(pch->dmac->pif.dev, "%s:%d Bad Desc(%d)\n", | ||
178 | __func__, __LINE__, desc->txd.cookie); | ||
179 | tasklet_schedule(&pch->task); | ||
180 | } | ||
181 | } | ||
182 | } | ||
183 | |||
184 | static void pl330_tasklet(unsigned long data) | ||
185 | { | ||
186 | struct dma_pl330_chan *pch = (struct dma_pl330_chan *)data; | ||
187 | struct dma_pl330_desc *desc, *_dt; | ||
188 | unsigned long flags; | ||
189 | LIST_HEAD(list); | ||
190 | |||
191 | spin_lock_irqsave(&pch->lock, flags); | ||
192 | |||
193 | /* Pick up ripe tomatoes */ | ||
194 | list_for_each_entry_safe(desc, _dt, &pch->work_list, node) | ||
195 | if (desc->status == DONE) { | ||
196 | pch->completed = desc->txd.cookie; | ||
197 | list_move_tail(&desc->node, &list); | ||
198 | } | ||
199 | |||
200 | /* Try to submit a req imm. next to the last completed cookie */ | ||
201 | fill_queue(pch); | ||
202 | |||
203 | /* Make sure the PL330 Channel thread is active */ | ||
204 | pl330_chan_ctrl(pch->pl330_chid, PL330_OP_START); | ||
205 | |||
206 | spin_unlock_irqrestore(&pch->lock, flags); | ||
207 | |||
208 | free_desc_list(&list); | ||
209 | } | ||
210 | |||
211 | static void dma_pl330_rqcb(void *token, enum pl330_op_err err) | ||
212 | { | ||
213 | struct dma_pl330_desc *desc = token; | ||
214 | struct dma_pl330_chan *pch = desc->pchan; | ||
215 | unsigned long flags; | ||
216 | |||
217 | /* If desc aborted */ | ||
218 | if (!pch) | ||
219 | return; | ||
220 | |||
221 | spin_lock_irqsave(&pch->lock, flags); | ||
222 | |||
223 | desc->status = DONE; | ||
224 | |||
225 | spin_unlock_irqrestore(&pch->lock, flags); | ||
226 | |||
227 | tasklet_schedule(&pch->task); | ||
228 | } | ||
229 | |||
230 | static int pl330_alloc_chan_resources(struct dma_chan *chan) | ||
231 | { | ||
232 | struct dma_pl330_chan *pch = to_pchan(chan); | ||
233 | struct dma_pl330_dmac *pdmac = pch->dmac; | ||
234 | unsigned long flags; | ||
235 | |||
236 | spin_lock_irqsave(&pch->lock, flags); | ||
237 | |||
238 | pch->completed = chan->cookie = 1; | ||
239 | |||
240 | pch->pl330_chid = pl330_request_channel(&pdmac->pif); | ||
241 | if (!pch->pl330_chid) { | ||
242 | spin_unlock_irqrestore(&pch->lock, flags); | ||
243 | return 0; | ||
244 | } | ||
245 | |||
246 | tasklet_init(&pch->task, pl330_tasklet, (unsigned long) pch); | ||
247 | |||
248 | spin_unlock_irqrestore(&pch->lock, flags); | ||
249 | |||
250 | return 1; | ||
251 | } | ||
252 | |||
253 | static int pl330_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, unsigned long arg) | ||
254 | { | ||
255 | struct dma_pl330_chan *pch = to_pchan(chan); | ||
256 | struct dma_pl330_desc *desc; | ||
257 | unsigned long flags; | ||
258 | |||
259 | /* Only supports DMA_TERMINATE_ALL */ | ||
260 | if (cmd != DMA_TERMINATE_ALL) | ||
261 | return -ENXIO; | ||
262 | |||
263 | spin_lock_irqsave(&pch->lock, flags); | ||
264 | |||
265 | /* FLUSH the PL330 Channel thread */ | ||
266 | pl330_chan_ctrl(pch->pl330_chid, PL330_OP_FLUSH); | ||
267 | |||
268 | /* Mark all desc done */ | ||
269 | list_for_each_entry(desc, &pch->work_list, node) | ||
270 | desc->status = DONE; | ||
271 | |||
272 | spin_unlock_irqrestore(&pch->lock, flags); | ||
273 | |||
274 | pl330_tasklet((unsigned long) pch); | ||
275 | |||
276 | return 0; | ||
277 | } | ||
278 | |||
279 | static void pl330_free_chan_resources(struct dma_chan *chan) | ||
280 | { | ||
281 | struct dma_pl330_chan *pch = to_pchan(chan); | ||
282 | unsigned long flags; | ||
283 | |||
284 | spin_lock_irqsave(&pch->lock, flags); | ||
285 | |||
286 | tasklet_kill(&pch->task); | ||
287 | |||
288 | pl330_release_channel(pch->pl330_chid); | ||
289 | pch->pl330_chid = NULL; | ||
290 | |||
291 | spin_unlock_irqrestore(&pch->lock, flags); | ||
292 | } | ||
293 | |||
294 | static enum dma_status | ||
295 | pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie, | ||
296 | struct dma_tx_state *txstate) | ||
297 | { | ||
298 | struct dma_pl330_chan *pch = to_pchan(chan); | ||
299 | dma_cookie_t last_done, last_used; | ||
300 | int ret; | ||
301 | |||
302 | last_done = pch->completed; | ||
303 | last_used = chan->cookie; | ||
304 | |||
305 | ret = dma_async_is_complete(cookie, last_done, last_used); | ||
306 | |||
307 | dma_set_tx_state(txstate, last_done, last_used, 0); | ||
308 | |||
309 | return ret; | ||
310 | } | ||
311 | |||
312 | static void pl330_issue_pending(struct dma_chan *chan) | ||
313 | { | ||
314 | pl330_tasklet((unsigned long) to_pchan(chan)); | ||
315 | } | ||
316 | |||
317 | /* | ||
318 | * We returned the last one of the circular list of descriptor(s) | ||
319 | * from prep_xxx, so the argument to submit corresponds to the last | ||
320 | * descriptor of the list. | ||
321 | */ | ||
322 | static dma_cookie_t pl330_tx_submit(struct dma_async_tx_descriptor *tx) | ||
323 | { | ||
324 | struct dma_pl330_desc *desc, *last = to_desc(tx); | ||
325 | struct dma_pl330_chan *pch = to_pchan(tx->chan); | ||
326 | dma_cookie_t cookie; | ||
327 | unsigned long flags; | ||
328 | |||
329 | spin_lock_irqsave(&pch->lock, flags); | ||
330 | |||
331 | /* Assign cookies to all nodes */ | ||
332 | cookie = tx->chan->cookie; | ||
333 | |||
334 | while (!list_empty(&last->node)) { | ||
335 | desc = list_entry(last->node.next, struct dma_pl330_desc, node); | ||
336 | |||
337 | if (++cookie < 0) | ||
338 | cookie = 1; | ||
339 | desc->txd.cookie = cookie; | ||
340 | |||
341 | list_move_tail(&desc->node, &pch->work_list); | ||
342 | } | ||
343 | |||
344 | if (++cookie < 0) | ||
345 | cookie = 1; | ||
346 | last->txd.cookie = cookie; | ||
347 | |||
348 | list_add_tail(&last->node, &pch->work_list); | ||
349 | |||
350 | tx->chan->cookie = cookie; | ||
351 | |||
352 | spin_unlock_irqrestore(&pch->lock, flags); | ||
353 | |||
354 | return cookie; | ||
355 | } | ||
356 | |||
357 | static inline void _init_desc(struct dma_pl330_desc *desc) | ||
358 | { | ||
359 | desc->pchan = NULL; | ||
360 | desc->req.x = &desc->px; | ||
361 | desc->req.token = desc; | ||
362 | desc->rqcfg.swap = SWAP_NO; | ||
363 | desc->rqcfg.privileged = 0; | ||
364 | desc->rqcfg.insnaccess = 0; | ||
365 | desc->rqcfg.scctl = SCCTRL0; | ||
366 | desc->rqcfg.dcctl = DCCTRL0; | ||
367 | desc->req.cfg = &desc->rqcfg; | ||
368 | desc->req.xfer_cb = dma_pl330_rqcb; | ||
369 | desc->txd.tx_submit = pl330_tx_submit; | ||
370 | |||
371 | INIT_LIST_HEAD(&desc->node); | ||
372 | } | ||
373 | |||
374 | /* Returns the number of descriptors added to the DMAC pool */ | ||
375 | int add_desc(struct dma_pl330_dmac *pdmac, gfp_t flg, int count) | ||
376 | { | ||
377 | struct dma_pl330_desc *desc; | ||
378 | unsigned long flags; | ||
379 | int i; | ||
380 | |||
381 | if (!pdmac) | ||
382 | return 0; | ||
383 | |||
384 | desc = kmalloc(count * sizeof(*desc), flg); | ||
385 | if (!desc) | ||
386 | return 0; | ||
387 | |||
388 | spin_lock_irqsave(&pdmac->pool_lock, flags); | ||
389 | |||
390 | for (i = 0; i < count; i++) { | ||
391 | _init_desc(&desc[i]); | ||
392 | list_add_tail(&desc[i].node, &pdmac->desc_pool); | ||
393 | } | ||
394 | |||
395 | spin_unlock_irqrestore(&pdmac->pool_lock, flags); | ||
396 | |||
397 | return count; | ||
398 | } | ||
399 | |||
400 | static struct dma_pl330_desc * | ||
401 | pluck_desc(struct dma_pl330_dmac *pdmac) | ||
402 | { | ||
403 | struct dma_pl330_desc *desc = NULL; | ||
404 | unsigned long flags; | ||
405 | |||
406 | if (!pdmac) | ||
407 | return NULL; | ||
408 | |||
409 | spin_lock_irqsave(&pdmac->pool_lock, flags); | ||
410 | |||
411 | if (!list_empty(&pdmac->desc_pool)) { | ||
412 | desc = list_entry(pdmac->desc_pool.next, | ||
413 | struct dma_pl330_desc, node); | ||
414 | |||
415 | list_del_init(&desc->node); | ||
416 | |||
417 | desc->status = PREP; | ||
418 | desc->txd.callback = NULL; | ||
419 | } | ||
420 | |||
421 | spin_unlock_irqrestore(&pdmac->pool_lock, flags); | ||
422 | |||
423 | return desc; | ||
424 | } | ||
425 | |||
426 | static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch) | ||
427 | { | ||
428 | struct dma_pl330_dmac *pdmac = pch->dmac; | ||
429 | struct dma_pl330_peri *peri = pch->chan.private; | ||
430 | struct dma_pl330_desc *desc; | ||
431 | |||
432 | /* Pluck one desc from the pool of DMAC */ | ||
433 | desc = pluck_desc(pdmac); | ||
434 | |||
435 | /* If the DMAC pool is empty, alloc new */ | ||
436 | if (!desc) { | ||
437 | if (!add_desc(pdmac, GFP_ATOMIC, 1)) | ||
438 | return NULL; | ||
439 | |||
440 | /* Try again */ | ||
441 | desc = pluck_desc(pdmac); | ||
442 | if (!desc) { | ||
443 | dev_err(pch->dmac->pif.dev, | ||
444 | "%s:%d ALERT!\n", __func__, __LINE__); | ||
445 | return NULL; | ||
446 | } | ||
447 | } | ||
448 | |||
449 | /* Initialize the descriptor */ | ||
450 | desc->pchan = pch; | ||
451 | desc->txd.cookie = 0; | ||
452 | async_tx_ack(&desc->txd); | ||
453 | |||
454 | desc->req.rqtype = peri->rqtype; | ||
455 | desc->req.peri = peri->peri_id; | ||
456 | |||
457 | dma_async_tx_descriptor_init(&desc->txd, &pch->chan); | ||
458 | |||
459 | return desc; | ||
460 | } | ||
461 | |||
462 | static inline void fill_px(struct pl330_xfer *px, | ||
463 | dma_addr_t dst, dma_addr_t src, size_t len) | ||
464 | { | ||
465 | px->next = NULL; | ||
466 | px->bytes = len; | ||
467 | px->dst_addr = dst; | ||
468 | px->src_addr = src; | ||
469 | } | ||
470 | |||
471 | static struct dma_pl330_desc * | ||
472 | __pl330_prep_dma_memcpy(struct dma_pl330_chan *pch, dma_addr_t dst, | ||
473 | dma_addr_t src, size_t len) | ||
474 | { | ||
475 | struct dma_pl330_desc *desc = pl330_get_desc(pch); | ||
476 | |||
477 | if (!desc) { | ||
478 | dev_err(pch->dmac->pif.dev, "%s:%d Unable to fetch desc\n", | ||
479 | __func__, __LINE__); | ||
480 | return NULL; | ||
481 | } | ||
482 | |||
483 | /* | ||
484 | * Ideally we should lookout for reqs bigger than | ||
485 | * those that can be programmed with 256 bytes of | ||
486 | * MC buffer, but considering a req size is seldom | ||
487 | * going to be word-unaligned and more than 200MB, | ||
488 | * we take it easy. | ||
489 | * Also, should the limit is reached we'd rather | ||
490 | * have the platform increase MC buffer size than | ||
491 | * complicating this API driver. | ||
492 | */ | ||
493 | fill_px(&desc->px, dst, src, len); | ||
494 | |||
495 | return desc; | ||
496 | } | ||
497 | |||
498 | /* Call after fixing burst size */ | ||
499 | static inline int get_burst_len(struct dma_pl330_desc *desc, size_t len) | ||
500 | { | ||
501 | struct dma_pl330_chan *pch = desc->pchan; | ||
502 | struct pl330_info *pi = &pch->dmac->pif; | ||
503 | int burst_len; | ||
504 | |||
505 | burst_len = pi->pcfg.data_bus_width / 8; | ||
506 | burst_len *= pi->pcfg.data_buf_dep; | ||
507 | burst_len >>= desc->rqcfg.brst_size; | ||
508 | |||
509 | /* src/dst_burst_len can't be more than 16 */ | ||
510 | if (burst_len > 16) | ||
511 | burst_len = 16; | ||
512 | |||
513 | while (burst_len > 1) { | ||
514 | if (!(len % (burst_len << desc->rqcfg.brst_size))) | ||
515 | break; | ||
516 | burst_len--; | ||
517 | } | ||
518 | |||
519 | return burst_len; | ||
520 | } | ||
521 | |||
522 | static struct dma_async_tx_descriptor * | ||
523 | pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst, | ||
524 | dma_addr_t src, size_t len, unsigned long flags) | ||
525 | { | ||
526 | struct dma_pl330_desc *desc; | ||
527 | struct dma_pl330_chan *pch = to_pchan(chan); | ||
528 | struct dma_pl330_peri *peri = chan->private; | ||
529 | struct pl330_info *pi; | ||
530 | int burst; | ||
531 | |||
532 | if (unlikely(!pch || !len || !peri)) | ||
533 | return NULL; | ||
534 | |||
535 | if (peri->rqtype != MEMTOMEM) | ||
536 | return NULL; | ||
537 | |||
538 | pi = &pch->dmac->pif; | ||
539 | |||
540 | desc = __pl330_prep_dma_memcpy(pch, dst, src, len); | ||
541 | if (!desc) | ||
542 | return NULL; | ||
543 | |||
544 | desc->rqcfg.src_inc = 1; | ||
545 | desc->rqcfg.dst_inc = 1; | ||
546 | |||
547 | /* Select max possible burst size */ | ||
548 | burst = pi->pcfg.data_bus_width / 8; | ||
549 | |||
550 | while (burst > 1) { | ||
551 | if (!(len % burst)) | ||
552 | break; | ||
553 | burst /= 2; | ||
554 | } | ||
555 | |||
556 | desc->rqcfg.brst_size = 0; | ||
557 | while (burst != (1 << desc->rqcfg.brst_size)) | ||
558 | desc->rqcfg.brst_size++; | ||
559 | |||
560 | desc->rqcfg.brst_len = get_burst_len(desc, len); | ||
561 | |||
562 | desc->txd.flags = flags; | ||
563 | |||
564 | return &desc->txd; | ||
565 | } | ||
566 | |||
567 | static struct dma_async_tx_descriptor * | ||
568 | pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | ||
569 | unsigned int sg_len, enum dma_data_direction direction, | ||
570 | unsigned long flg) | ||
571 | { | ||
572 | struct dma_pl330_desc *first, *desc = NULL; | ||
573 | struct dma_pl330_chan *pch = to_pchan(chan); | ||
574 | struct dma_pl330_peri *peri = chan->private; | ||
575 | struct scatterlist *sg; | ||
576 | unsigned long flags; | ||
577 | int i, burst_size; | ||
578 | dma_addr_t addr; | ||
579 | |||
580 | if (unlikely(!pch || !sgl || !sg_len)) | ||
581 | return NULL; | ||
582 | |||
583 | /* Make sure the direction is consistent */ | ||
584 | if ((direction == DMA_TO_DEVICE && | ||
585 | peri->rqtype != MEMTODEV) || | ||
586 | (direction == DMA_FROM_DEVICE && | ||
587 | peri->rqtype != DEVTOMEM)) { | ||
588 | dev_err(pch->dmac->pif.dev, "%s:%d Invalid Direction\n", | ||
589 | __func__, __LINE__); | ||
590 | return NULL; | ||
591 | } | ||
592 | |||
593 | addr = peri->fifo_addr; | ||
594 | burst_size = peri->burst_sz; | ||
595 | |||
596 | first = NULL; | ||
597 | |||
598 | for_each_sg(sgl, sg, sg_len, i) { | ||
599 | |||
600 | desc = pl330_get_desc(pch); | ||
601 | if (!desc) { | ||
602 | struct dma_pl330_dmac *pdmac = pch->dmac; | ||
603 | |||
604 | dev_err(pch->dmac->pif.dev, | ||
605 | "%s:%d Unable to fetch desc\n", | ||
606 | __func__, __LINE__); | ||
607 | if (!first) | ||
608 | return NULL; | ||
609 | |||
610 | spin_lock_irqsave(&pdmac->pool_lock, flags); | ||
611 | |||
612 | while (!list_empty(&first->node)) { | ||
613 | desc = list_entry(first->node.next, | ||
614 | struct dma_pl330_desc, node); | ||
615 | list_move_tail(&desc->node, &pdmac->desc_pool); | ||
616 | } | ||
617 | |||
618 | list_move_tail(&first->node, &pdmac->desc_pool); | ||
619 | |||
620 | spin_unlock_irqrestore(&pdmac->pool_lock, flags); | ||
621 | |||
622 | return NULL; | ||
623 | } | ||
624 | |||
625 | if (!first) | ||
626 | first = desc; | ||
627 | else | ||
628 | list_add_tail(&desc->node, &first->node); | ||
629 | |||
630 | if (direction == DMA_TO_DEVICE) { | ||
631 | desc->rqcfg.src_inc = 1; | ||
632 | desc->rqcfg.dst_inc = 0; | ||
633 | fill_px(&desc->px, | ||
634 | addr, sg_dma_address(sg), sg_dma_len(sg)); | ||
635 | } else { | ||
636 | desc->rqcfg.src_inc = 0; | ||
637 | desc->rqcfg.dst_inc = 1; | ||
638 | fill_px(&desc->px, | ||
639 | sg_dma_address(sg), addr, sg_dma_len(sg)); | ||
640 | } | ||
641 | |||
642 | desc->rqcfg.brst_size = burst_size; | ||
643 | desc->rqcfg.brst_len = 1; | ||
644 | } | ||
645 | |||
646 | /* Return the last desc in the chain */ | ||
647 | desc->txd.flags = flg; | ||
648 | return &desc->txd; | ||
649 | } | ||
650 | |||
651 | static irqreturn_t pl330_irq_handler(int irq, void *data) | ||
652 | { | ||
653 | if (pl330_update(data)) | ||
654 | return IRQ_HANDLED; | ||
655 | else | ||
656 | return IRQ_NONE; | ||
657 | } | ||
658 | |||
659 | static int __devinit | ||
660 | pl330_probe(struct amba_device *adev, struct amba_id *id) | ||
661 | { | ||
662 | struct dma_pl330_platdata *pdat; | ||
663 | struct dma_pl330_dmac *pdmac; | ||
664 | struct dma_pl330_chan *pch; | ||
665 | struct pl330_info *pi; | ||
666 | struct dma_device *pd; | ||
667 | struct resource *res; | ||
668 | int i, ret, irq; | ||
669 | |||
670 | pdat = adev->dev.platform_data; | ||
671 | |||
672 | if (!pdat || !pdat->nr_valid_peri) { | ||
673 | dev_err(&adev->dev, "platform data missing\n"); | ||
674 | return -ENODEV; | ||
675 | } | ||
676 | |||
677 | /* Allocate a new DMAC and its Channels */ | ||
678 | pdmac = kzalloc(pdat->nr_valid_peri * sizeof(*pch) | ||
679 | + sizeof(*pdmac), GFP_KERNEL); | ||
680 | if (!pdmac) { | ||
681 | dev_err(&adev->dev, "unable to allocate mem\n"); | ||
682 | return -ENOMEM; | ||
683 | } | ||
684 | |||
685 | pi = &pdmac->pif; | ||
686 | pi->dev = &adev->dev; | ||
687 | pi->pl330_data = NULL; | ||
688 | pi->mcbufsz = pdat->mcbuf_sz; | ||
689 | |||
690 | res = &adev->res; | ||
691 | request_mem_region(res->start, resource_size(res), "dma-pl330"); | ||
692 | |||
693 | pi->base = ioremap(res->start, resource_size(res)); | ||
694 | if (!pi->base) { | ||
695 | ret = -ENXIO; | ||
696 | goto probe_err1; | ||
697 | } | ||
698 | |||
699 | irq = adev->irq[0]; | ||
700 | ret = request_irq(irq, pl330_irq_handler, 0, | ||
701 | dev_name(&adev->dev), pi); | ||
702 | if (ret) | ||
703 | goto probe_err2; | ||
704 | |||
705 | ret = pl330_add(pi); | ||
706 | if (ret) | ||
707 | goto probe_err3; | ||
708 | |||
709 | INIT_LIST_HEAD(&pdmac->desc_pool); | ||
710 | spin_lock_init(&pdmac->pool_lock); | ||
711 | |||
712 | /* Create a descriptor pool of default size */ | ||
713 | if (!add_desc(pdmac, GFP_KERNEL, NR_DEFAULT_DESC)) | ||
714 | dev_warn(&adev->dev, "unable to allocate desc\n"); | ||
715 | |||
716 | pd = &pdmac->ddma; | ||
717 | INIT_LIST_HEAD(&pd->channels); | ||
718 | |||
719 | /* Initialize channel parameters */ | ||
720 | for (i = 0; i < pdat->nr_valid_peri; i++) { | ||
721 | struct dma_pl330_peri *peri = &pdat->peri[i]; | ||
722 | pch = &pdmac->peripherals[i]; | ||
723 | |||
724 | switch (peri->rqtype) { | ||
725 | case MEMTOMEM: | ||
726 | dma_cap_set(DMA_MEMCPY, pd->cap_mask); | ||
727 | break; | ||
728 | case MEMTODEV: | ||
729 | case DEVTOMEM: | ||
730 | dma_cap_set(DMA_SLAVE, pd->cap_mask); | ||
731 | break; | ||
732 | default: | ||
733 | dev_err(&adev->dev, "DEVTODEV Not Supported\n"); | ||
734 | continue; | ||
735 | } | ||
736 | |||
737 | INIT_LIST_HEAD(&pch->work_list); | ||
738 | spin_lock_init(&pch->lock); | ||
739 | pch->pl330_chid = NULL; | ||
740 | pch->chan.private = peri; | ||
741 | pch->chan.device = pd; | ||
742 | pch->chan.chan_id = i; | ||
743 | pch->dmac = pdmac; | ||
744 | |||
745 | /* Add the channel to the DMAC list */ | ||
746 | pd->chancnt++; | ||
747 | list_add_tail(&pch->chan.device_node, &pd->channels); | ||
748 | } | ||
749 | |||
750 | pd->dev = &adev->dev; | ||
751 | |||
752 | pd->device_alloc_chan_resources = pl330_alloc_chan_resources; | ||
753 | pd->device_free_chan_resources = pl330_free_chan_resources; | ||
754 | pd->device_prep_dma_memcpy = pl330_prep_dma_memcpy; | ||
755 | pd->device_tx_status = pl330_tx_status; | ||
756 | pd->device_prep_slave_sg = pl330_prep_slave_sg; | ||
757 | pd->device_control = pl330_control; | ||
758 | pd->device_issue_pending = pl330_issue_pending; | ||
759 | |||
760 | ret = dma_async_device_register(pd); | ||
761 | if (ret) { | ||
762 | dev_err(&adev->dev, "unable to register DMAC\n"); | ||
763 | goto probe_err4; | ||
764 | } | ||
765 | |||
766 | amba_set_drvdata(adev, pdmac); | ||
767 | |||
768 | dev_info(&adev->dev, | ||
769 | "Loaded driver for PL330 DMAC-%d\n", adev->periphid); | ||
770 | dev_info(&adev->dev, | ||
771 | "\tDBUFF-%ux%ubytes Num_Chans-%u Num_Peri-%u Num_Events-%u\n", | ||
772 | pi->pcfg.data_buf_dep, | ||
773 | pi->pcfg.data_bus_width / 8, pi->pcfg.num_chan, | ||
774 | pi->pcfg.num_peri, pi->pcfg.num_events); | ||
775 | |||
776 | return 0; | ||
777 | |||
778 | probe_err4: | ||
779 | pl330_del(pi); | ||
780 | probe_err3: | ||
781 | free_irq(irq, pi); | ||
782 | probe_err2: | ||
783 | iounmap(pi->base); | ||
784 | probe_err1: | ||
785 | release_mem_region(res->start, resource_size(res)); | ||
786 | kfree(pdmac); | ||
787 | |||
788 | return ret; | ||
789 | } | ||
790 | |||
791 | static int __devexit pl330_remove(struct amba_device *adev) | ||
792 | { | ||
793 | struct dma_pl330_dmac *pdmac = amba_get_drvdata(adev); | ||
794 | struct dma_pl330_chan *pch, *_p; | ||
795 | struct pl330_info *pi; | ||
796 | struct resource *res; | ||
797 | int irq; | ||
798 | |||
799 | if (!pdmac) | ||
800 | return 0; | ||
801 | |||
802 | amba_set_drvdata(adev, NULL); | ||
803 | |||
804 | /* Idle the DMAC */ | ||
805 | list_for_each_entry_safe(pch, _p, &pdmac->ddma.channels, | ||
806 | chan.device_node) { | ||
807 | |||
808 | /* Remove the channel */ | ||
809 | list_del(&pch->chan.device_node); | ||
810 | |||
811 | /* Flush the channel */ | ||
812 | pl330_control(&pch->chan, DMA_TERMINATE_ALL, 0); | ||
813 | pl330_free_chan_resources(&pch->chan); | ||
814 | } | ||
815 | |||
816 | pi = &pdmac->pif; | ||
817 | |||
818 | pl330_del(pi); | ||
819 | |||
820 | irq = adev->irq[0]; | ||
821 | free_irq(irq, pi); | ||
822 | |||
823 | iounmap(pi->base); | ||
824 | |||
825 | res = &adev->res; | ||
826 | release_mem_region(res->start, resource_size(res)); | ||
827 | |||
828 | kfree(pdmac); | ||
829 | |||
830 | return 0; | ||
831 | } | ||
832 | |||
833 | static struct amba_id pl330_ids[] = { | ||
834 | { | ||
835 | .id = 0x00041330, | ||
836 | .mask = 0x000fffff, | ||
837 | }, | ||
838 | { 0, 0 }, | ||
839 | }; | ||
840 | |||
841 | static struct amba_driver pl330_driver = { | ||
842 | .drv = { | ||
843 | .owner = THIS_MODULE, | ||
844 | .name = "dma-pl330", | ||
845 | }, | ||
846 | .id_table = pl330_ids, | ||
847 | .probe = pl330_probe, | ||
848 | .remove = pl330_remove, | ||
849 | }; | ||
850 | |||
851 | static int __init pl330_init(void) | ||
852 | { | ||
853 | return amba_driver_register(&pl330_driver); | ||
854 | } | ||
855 | module_init(pl330_init); | ||
856 | |||
857 | static void __exit pl330_exit(void) | ||
858 | { | ||
859 | amba_driver_unregister(&pl330_driver); | ||
860 | return; | ||
861 | } | ||
862 | module_exit(pl330_exit); | ||
863 | |||
864 | MODULE_AUTHOR("Jaswinder Singh <jassi.brar@samsung.com>"); | ||
865 | MODULE_DESCRIPTION("API Driver for PL330 DMAC"); | ||
866 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c index cc5316dcf580..b3ba44c0a818 100644 --- a/drivers/gpu/drm/radeon/radeon_state.c +++ b/drivers/gpu/drm/radeon/radeon_state.c | |||
@@ -900,9 +900,10 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev, | |||
900 | flags |= RADEON_FRONT; | 900 | flags |= RADEON_FRONT; |
901 | } | 901 | } |
902 | if (flags & (RADEON_DEPTH|RADEON_STENCIL)) { | 902 | if (flags & (RADEON_DEPTH|RADEON_STENCIL)) { |
903 | if (!dev_priv->have_z_offset) | 903 | if (!dev_priv->have_z_offset) { |
904 | printk_once(KERN_ERR "radeon: illegal depth clear request. Buggy mesa detected - please update.\n"); | 904 | printk_once(KERN_ERR "radeon: illegal depth clear request. Buggy mesa detected - please update.\n"); |
905 | flags &= ~(RADEON_DEPTH | RADEON_STENCIL); | 905 | flags &= ~(RADEON_DEPTH | RADEON_STENCIL); |
906 | } | ||
906 | } | 907 | } |
907 | 908 | ||
908 | if (flags & (RADEON_FRONT | RADEON_BACK)) { | 909 | if (flags & (RADEON_FRONT | RADEON_BACK)) { |
diff --git a/drivers/idle/Kconfig b/drivers/idle/Kconfig index f15e90a453d1..fb5c5186d4aa 100644 --- a/drivers/idle/Kconfig +++ b/drivers/idle/Kconfig | |||
@@ -1,3 +1,14 @@ | |||
1 | config INTEL_IDLE | ||
2 | tristate "Cpuidle Driver for Intel Processors" | ||
3 | depends on CPU_IDLE | ||
4 | depends on X86 | ||
5 | depends on CPU_SUP_INTEL | ||
6 | depends on EXPERIMENTAL | ||
7 | help | ||
8 | Enable intel_idle, a cpuidle driver that includes knowledge of | ||
9 | native Intel hardware idle features. The acpi_idle driver | ||
10 | can be configured at the same time, in order to handle | ||
11 | processors intel_idle does not support. | ||
1 | 12 | ||
2 | menu "Memory power savings" | 13 | menu "Memory power savings" |
3 | depends on X86_64 | 14 | depends on X86_64 |
diff --git a/drivers/idle/Makefile b/drivers/idle/Makefile index 5f68fc377e21..23d295cf10f2 100644 --- a/drivers/idle/Makefile +++ b/drivers/idle/Makefile | |||
@@ -1,2 +1,3 @@ | |||
1 | obj-$(CONFIG_I7300_IDLE) += i7300_idle.o | 1 | obj-$(CONFIG_I7300_IDLE) += i7300_idle.o |
2 | obj-$(CONFIG_INTEL_IDLE) += intel_idle.o | ||
2 | 3 | ||
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c new file mode 100755 index 000000000000..54f0fb4cd5d2 --- /dev/null +++ b/drivers/idle/intel_idle.c | |||
@@ -0,0 +1,461 @@ | |||
1 | /* | ||
2 | * intel_idle.c - native hardware idle loop for modern Intel processors | ||
3 | * | ||
4 | * Copyright (c) 2010, Intel Corporation. | ||
5 | * Len Brown <len.brown@intel.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms and conditions of the GNU General Public License, | ||
9 | * version 2, as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
14 | * more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along with | ||
17 | * this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | |||
21 | /* | ||
22 | * intel_idle is a cpuidle driver that loads on specific Intel processors | ||
23 | * in lieu of the legacy ACPI processor_idle driver. The intent is to | ||
24 | * make Linux more efficient on these processors, as intel_idle knows | ||
25 | * more than ACPI, as well as make Linux more immune to ACPI BIOS bugs. | ||
26 | */ | ||
27 | |||
28 | /* | ||
29 | * Design Assumptions | ||
30 | * | ||
31 | * All CPUs have same idle states as boot CPU | ||
32 | * | ||
33 | * Chipset BM_STS (bus master status) bit is a NOP | ||
34 | * for preventing entry into deep C-stats | ||
35 | */ | ||
36 | |||
37 | /* | ||
38 | * Known limitations | ||
39 | * | ||
40 | * The driver currently initializes for_each_online_cpu() upon modprobe. | ||
41 | * It it unaware of subsequent processors hot-added to the system. | ||
42 | * This means that if you boot with maxcpus=n and later online | ||
43 | * processors above n, those processors will use C1 only. | ||
44 | * | ||
45 | * ACPI has a .suspend hack to turn off deep c-statees during suspend | ||
46 | * to avoid complications with the lapic timer workaround. | ||
47 | * Have not seen issues with suspend, but may need same workaround here. | ||
48 | * | ||
49 | * There is currently no kernel-based automatic probing/loading mechanism | ||
50 | * if the driver is built as a module. | ||
51 | */ | ||
52 | |||
53 | /* un-comment DEBUG to enable pr_debug() statements */ | ||
54 | #define DEBUG | ||
55 | |||
56 | #include <linux/kernel.h> | ||
57 | #include <linux/cpuidle.h> | ||
58 | #include <linux/clockchips.h> | ||
59 | #include <linux/hrtimer.h> /* ktime_get_real() */ | ||
60 | #include <trace/events/power.h> | ||
61 | #include <linux/sched.h> | ||
62 | |||
63 | #define INTEL_IDLE_VERSION "0.4" | ||
64 | #define PREFIX "intel_idle: " | ||
65 | |||
66 | #define MWAIT_SUBSTATE_MASK (0xf) | ||
67 | #define MWAIT_CSTATE_MASK (0xf) | ||
68 | #define MWAIT_SUBSTATE_SIZE (4) | ||
69 | #define MWAIT_MAX_NUM_CSTATES 8 | ||
70 | #define CPUID_MWAIT_LEAF (5) | ||
71 | #define CPUID5_ECX_EXTENSIONS_SUPPORTED (0x1) | ||
72 | #define CPUID5_ECX_INTERRUPT_BREAK (0x2) | ||
73 | |||
74 | static struct cpuidle_driver intel_idle_driver = { | ||
75 | .name = "intel_idle", | ||
76 | .owner = THIS_MODULE, | ||
77 | }; | ||
78 | /* intel_idle.max_cstate=0 disables driver */ | ||
79 | static int max_cstate = MWAIT_MAX_NUM_CSTATES - 1; | ||
80 | static int power_policy = 7; /* 0 = max perf; 15 = max powersave */ | ||
81 | |||
82 | static unsigned int substates; | ||
83 | static int (*choose_substate)(int); | ||
84 | |||
85 | /* Reliable LAPIC Timer States, bit 1 for C1 etc. */ | ||
86 | static unsigned int lapic_timer_reliable_states; | ||
87 | |||
88 | static struct cpuidle_device *intel_idle_cpuidle_devices; | ||
89 | static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state); | ||
90 | |||
91 | static struct cpuidle_state *cpuidle_state_table; | ||
92 | |||
93 | /* | ||
94 | * States are indexed by the cstate number, | ||
95 | * which is also the index into the MWAIT hint array. | ||
96 | * Thus C0 is a dummy. | ||
97 | */ | ||
98 | static struct cpuidle_state nehalem_cstates[MWAIT_MAX_NUM_CSTATES] = { | ||
99 | { /* MWAIT C0 */ }, | ||
100 | { /* MWAIT C1 */ | ||
101 | .name = "NHM-C1", | ||
102 | .desc = "MWAIT 0x00", | ||
103 | .driver_data = (void *) 0x00, | ||
104 | .flags = CPUIDLE_FLAG_TIME_VALID, | ||
105 | .exit_latency = 3, | ||
106 | .power_usage = 1000, | ||
107 | .target_residency = 6, | ||
108 | .enter = &intel_idle }, | ||
109 | { /* MWAIT C2 */ | ||
110 | .name = "NHM-C3", | ||
111 | .desc = "MWAIT 0x10", | ||
112 | .driver_data = (void *) 0x10, | ||
113 | .flags = CPUIDLE_FLAG_TIME_VALID, | ||
114 | .exit_latency = 20, | ||
115 | .power_usage = 500, | ||
116 | .target_residency = 80, | ||
117 | .enter = &intel_idle }, | ||
118 | { /* MWAIT C3 */ | ||
119 | .name = "NHM-C6", | ||
120 | .desc = "MWAIT 0x20", | ||
121 | .driver_data = (void *) 0x20, | ||
122 | .flags = CPUIDLE_FLAG_TIME_VALID, | ||
123 | .exit_latency = 200, | ||
124 | .power_usage = 350, | ||
125 | .target_residency = 800, | ||
126 | .enter = &intel_idle }, | ||
127 | }; | ||
128 | |||
129 | static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = { | ||
130 | { /* MWAIT C0 */ }, | ||
131 | { /* MWAIT C1 */ | ||
132 | .name = "ATM-C1", | ||
133 | .desc = "MWAIT 0x00", | ||
134 | .driver_data = (void *) 0x00, | ||
135 | .flags = CPUIDLE_FLAG_TIME_VALID, | ||
136 | .exit_latency = 1, | ||
137 | .power_usage = 1000, | ||
138 | .target_residency = 4, | ||
139 | .enter = &intel_idle }, | ||
140 | { /* MWAIT C2 */ | ||
141 | .name = "ATM-C2", | ||
142 | .desc = "MWAIT 0x10", | ||
143 | .driver_data = (void *) 0x10, | ||
144 | .flags = CPUIDLE_FLAG_TIME_VALID, | ||
145 | .exit_latency = 20, | ||
146 | .power_usage = 500, | ||
147 | .target_residency = 80, | ||
148 | .enter = &intel_idle }, | ||
149 | { /* MWAIT C3 */ }, | ||
150 | { /* MWAIT C4 */ | ||
151 | .name = "ATM-C4", | ||
152 | .desc = "MWAIT 0x30", | ||
153 | .driver_data = (void *) 0x30, | ||
154 | .flags = CPUIDLE_FLAG_TIME_VALID, | ||
155 | .exit_latency = 100, | ||
156 | .power_usage = 250, | ||
157 | .target_residency = 400, | ||
158 | .enter = &intel_idle }, | ||
159 | { /* MWAIT C5 */ }, | ||
160 | { /* MWAIT C6 */ | ||
161 | .name = "ATM-C6", | ||
162 | .desc = "MWAIT 0x40", | ||
163 | .driver_data = (void *) 0x40, | ||
164 | .flags = CPUIDLE_FLAG_TIME_VALID, | ||
165 | .exit_latency = 200, | ||
166 | .power_usage = 150, | ||
167 | .target_residency = 800, | ||
168 | .enter = NULL }, /* disabled */ | ||
169 | }; | ||
170 | |||
171 | /* | ||
172 | * choose_tunable_substate() | ||
173 | * | ||
174 | * Run-time decision on which C-state substate to invoke | ||
175 | * If power_policy = 0, choose shallowest substate (0) | ||
176 | * If power_policy = 15, choose deepest substate | ||
177 | * If power_policy = middle, choose middle substate etc. | ||
178 | */ | ||
179 | static int choose_tunable_substate(int cstate) | ||
180 | { | ||
181 | unsigned int num_substates; | ||
182 | unsigned int substate_choice; | ||
183 | |||
184 | power_policy &= 0xF; /* valid range: 0-15 */ | ||
185 | cstate &= 7; /* valid range: 0-7 */ | ||
186 | |||
187 | num_substates = (substates >> ((cstate) * 4)) & MWAIT_SUBSTATE_MASK; | ||
188 | |||
189 | if (num_substates <= 1) | ||
190 | return 0; | ||
191 | |||
192 | substate_choice = ((power_policy + (power_policy + 1) * | ||
193 | (num_substates - 1)) / 16); | ||
194 | |||
195 | return substate_choice; | ||
196 | } | ||
197 | |||
198 | /* | ||
199 | * choose_zero_substate() | ||
200 | */ | ||
201 | static int choose_zero_substate(int cstate) | ||
202 | { | ||
203 | return 0; | ||
204 | } | ||
205 | |||
206 | /** | ||
207 | * intel_idle | ||
208 | * @dev: cpuidle_device | ||
209 | * @state: cpuidle state | ||
210 | * | ||
211 | */ | ||
212 | static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state) | ||
213 | { | ||
214 | unsigned long ecx = 1; /* break on interrupt flag */ | ||
215 | unsigned long eax = (unsigned long)cpuidle_get_statedata(state); | ||
216 | unsigned int cstate; | ||
217 | ktime_t kt_before, kt_after; | ||
218 | s64 usec_delta; | ||
219 | int cpu = smp_processor_id(); | ||
220 | |||
221 | cstate = (((eax) >> MWAIT_SUBSTATE_SIZE) & MWAIT_CSTATE_MASK) + 1; | ||
222 | |||
223 | eax = eax + (choose_substate)(cstate); | ||
224 | |||
225 | local_irq_disable(); | ||
226 | |||
227 | if (!(lapic_timer_reliable_states & (1 << (cstate)))) | ||
228 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu); | ||
229 | |||
230 | kt_before = ktime_get_real(); | ||
231 | |||
232 | stop_critical_timings(); | ||
233 | #ifndef MODULE | ||
234 | trace_power_start(POWER_CSTATE, (eax >> 4) + 1); | ||
235 | #endif | ||
236 | if (!need_resched()) { | ||
237 | |||
238 | __monitor((void *)¤t_thread_info()->flags, 0, 0); | ||
239 | smp_mb(); | ||
240 | if (!need_resched()) | ||
241 | __mwait(eax, ecx); | ||
242 | } | ||
243 | |||
244 | start_critical_timings(); | ||
245 | |||
246 | kt_after = ktime_get_real(); | ||
247 | usec_delta = ktime_to_us(ktime_sub(kt_after, kt_before)); | ||
248 | |||
249 | local_irq_enable(); | ||
250 | |||
251 | if (!(lapic_timer_reliable_states & (1 << (cstate)))) | ||
252 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu); | ||
253 | |||
254 | return usec_delta; | ||
255 | } | ||
256 | |||
257 | /* | ||
258 | * intel_idle_probe() | ||
259 | */ | ||
260 | static int intel_idle_probe(void) | ||
261 | { | ||
262 | unsigned int eax, ebx, ecx, edx; | ||
263 | |||
264 | if (max_cstate == 0) { | ||
265 | pr_debug(PREFIX "disabled\n"); | ||
266 | return -EPERM; | ||
267 | } | ||
268 | |||
269 | if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) | ||
270 | return -ENODEV; | ||
271 | |||
272 | if (!boot_cpu_has(X86_FEATURE_MWAIT)) | ||
273 | return -ENODEV; | ||
274 | |||
275 | if (boot_cpu_data.cpuid_level < CPUID_MWAIT_LEAF) | ||
276 | return -ENODEV; | ||
277 | |||
278 | cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &edx); | ||
279 | |||
280 | if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) || | ||
281 | !(ecx & CPUID5_ECX_INTERRUPT_BREAK)) | ||
282 | return -ENODEV; | ||
283 | #ifdef DEBUG | ||
284 | if (substates == 0) /* can over-ride via modparam */ | ||
285 | #endif | ||
286 | substates = edx; | ||
287 | |||
288 | pr_debug(PREFIX "MWAIT substates: 0x%x\n", substates); | ||
289 | |||
290 | if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */ | ||
291 | lapic_timer_reliable_states = 0xFFFFFFFF; | ||
292 | |||
293 | if (boot_cpu_data.x86 != 6) /* family 6 */ | ||
294 | return -ENODEV; | ||
295 | |||
296 | switch (boot_cpu_data.x86_model) { | ||
297 | |||
298 | case 0x1A: /* Core i7, Xeon 5500 series */ | ||
299 | case 0x1E: /* Core i7 and i5 Processor - Lynnfield Jasper Forest */ | ||
300 | case 0x1F: /* Core i7 and i5 Processor - Nehalem */ | ||
301 | case 0x2E: /* Nehalem-EX Xeon */ | ||
302 | lapic_timer_reliable_states = (1 << 1); /* C1 */ | ||
303 | |||
304 | case 0x25: /* Westmere */ | ||
305 | case 0x2C: /* Westmere */ | ||
306 | cpuidle_state_table = nehalem_cstates; | ||
307 | choose_substate = choose_tunable_substate; | ||
308 | break; | ||
309 | |||
310 | case 0x1C: /* 28 - Atom Processor */ | ||
311 | lapic_timer_reliable_states = (1 << 2) | (1 << 1); /* C2, C1 */ | ||
312 | cpuidle_state_table = atom_cstates; | ||
313 | choose_substate = choose_zero_substate; | ||
314 | break; | ||
315 | #ifdef FUTURE_USE | ||
316 | case 0x17: /* 23 - Core 2 Duo */ | ||
317 | lapic_timer_reliable_states = (1 << 2) | (1 << 1); /* C2, C1 */ | ||
318 | #endif | ||
319 | |||
320 | default: | ||
321 | pr_debug(PREFIX "does not run on family %d model %d\n", | ||
322 | boot_cpu_data.x86, boot_cpu_data.x86_model); | ||
323 | return -ENODEV; | ||
324 | } | ||
325 | |||
326 | pr_debug(PREFIX "v" INTEL_IDLE_VERSION | ||
327 | " model 0x%X\n", boot_cpu_data.x86_model); | ||
328 | |||
329 | pr_debug(PREFIX "lapic_timer_reliable_states 0x%x\n", | ||
330 | lapic_timer_reliable_states); | ||
331 | return 0; | ||
332 | } | ||
333 | |||
334 | /* | ||
335 | * intel_idle_cpuidle_devices_uninit() | ||
336 | * unregister, free cpuidle_devices | ||
337 | */ | ||
338 | static void intel_idle_cpuidle_devices_uninit(void) | ||
339 | { | ||
340 | int i; | ||
341 | struct cpuidle_device *dev; | ||
342 | |||
343 | for_each_online_cpu(i) { | ||
344 | dev = per_cpu_ptr(intel_idle_cpuidle_devices, i); | ||
345 | cpuidle_unregister_device(dev); | ||
346 | } | ||
347 | |||
348 | free_percpu(intel_idle_cpuidle_devices); | ||
349 | return; | ||
350 | } | ||
351 | /* | ||
352 | * intel_idle_cpuidle_devices_init() | ||
353 | * allocate, initialize, register cpuidle_devices | ||
354 | */ | ||
355 | static int intel_idle_cpuidle_devices_init(void) | ||
356 | { | ||
357 | int i, cstate; | ||
358 | struct cpuidle_device *dev; | ||
359 | |||
360 | intel_idle_cpuidle_devices = alloc_percpu(struct cpuidle_device); | ||
361 | if (intel_idle_cpuidle_devices == NULL) | ||
362 | return -ENOMEM; | ||
363 | |||
364 | for_each_online_cpu(i) { | ||
365 | dev = per_cpu_ptr(intel_idle_cpuidle_devices, i); | ||
366 | |||
367 | dev->state_count = 1; | ||
368 | |||
369 | for (cstate = 1; cstate < MWAIT_MAX_NUM_CSTATES; ++cstate) { | ||
370 | int num_substates; | ||
371 | |||
372 | if (cstate > max_cstate) { | ||
373 | printk(PREFIX "max_cstate %d reached\n", | ||
374 | max_cstate); | ||
375 | break; | ||
376 | } | ||
377 | |||
378 | /* does the state exist in CPUID.MWAIT? */ | ||
379 | num_substates = (substates >> ((cstate) * 4)) | ||
380 | & MWAIT_SUBSTATE_MASK; | ||
381 | if (num_substates == 0) | ||
382 | continue; | ||
383 | /* is the state not enabled? */ | ||
384 | if (cpuidle_state_table[cstate].enter == NULL) { | ||
385 | /* does the driver not know about the state? */ | ||
386 | if (*cpuidle_state_table[cstate].name == '\0') | ||
387 | pr_debug(PREFIX "unaware of model 0x%x" | ||
388 | " MWAIT %d please" | ||
389 | " contact lenb@kernel.org", | ||
390 | boot_cpu_data.x86_model, cstate); | ||
391 | continue; | ||
392 | } | ||
393 | |||
394 | if ((cstate > 2) && | ||
395 | !boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) | ||
396 | mark_tsc_unstable("TSC halts in idle" | ||
397 | " states deeper than C2"); | ||
398 | |||
399 | dev->states[dev->state_count] = /* structure copy */ | ||
400 | cpuidle_state_table[cstate]; | ||
401 | |||
402 | dev->state_count += 1; | ||
403 | } | ||
404 | |||
405 | dev->cpu = i; | ||
406 | if (cpuidle_register_device(dev)) { | ||
407 | pr_debug(PREFIX "cpuidle_register_device %d failed!\n", | ||
408 | i); | ||
409 | intel_idle_cpuidle_devices_uninit(); | ||
410 | return -EIO; | ||
411 | } | ||
412 | } | ||
413 | |||
414 | return 0; | ||
415 | } | ||
416 | |||
417 | |||
418 | static int __init intel_idle_init(void) | ||
419 | { | ||
420 | int retval; | ||
421 | |||
422 | retval = intel_idle_probe(); | ||
423 | if (retval) | ||
424 | return retval; | ||
425 | |||
426 | retval = cpuidle_register_driver(&intel_idle_driver); | ||
427 | if (retval) { | ||
428 | printk(KERN_DEBUG PREFIX "intel_idle yielding to %s", | ||
429 | cpuidle_get_driver()->name); | ||
430 | return retval; | ||
431 | } | ||
432 | |||
433 | retval = intel_idle_cpuidle_devices_init(); | ||
434 | if (retval) { | ||
435 | cpuidle_unregister_driver(&intel_idle_driver); | ||
436 | return retval; | ||
437 | } | ||
438 | |||
439 | return 0; | ||
440 | } | ||
441 | |||
442 | static void __exit intel_idle_exit(void) | ||
443 | { | ||
444 | intel_idle_cpuidle_devices_uninit(); | ||
445 | cpuidle_unregister_driver(&intel_idle_driver); | ||
446 | |||
447 | return; | ||
448 | } | ||
449 | |||
450 | module_init(intel_idle_init); | ||
451 | module_exit(intel_idle_exit); | ||
452 | |||
453 | module_param(power_policy, int, 0644); | ||
454 | module_param(max_cstate, int, 0444); | ||
455 | #ifdef DEBUG | ||
456 | module_param(substates, int, 0444); | ||
457 | #endif | ||
458 | |||
459 | MODULE_AUTHOR("Len Brown <len.brown@intel.com>"); | ||
460 | MODULE_DESCRIPTION("Cpuidle driver for Intel Hardware v" INTEL_IDLE_VERSION); | ||
461 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c index 46474842cfe9..08f948df8fa9 100644 --- a/drivers/infiniband/core/ucm.c +++ b/drivers/infiniband/core/ucm.c | |||
@@ -706,14 +706,9 @@ static int ib_ucm_alloc_data(const void **dest, u64 src, u32 len) | |||
706 | if (!len) | 706 | if (!len) |
707 | return 0; | 707 | return 0; |
708 | 708 | ||
709 | data = kmalloc(len, GFP_KERNEL); | 709 | data = memdup_user((void __user *)(unsigned long)src, len); |
710 | if (!data) | 710 | if (IS_ERR(data)) |
711 | return -ENOMEM; | 711 | return PTR_ERR(data); |
712 | |||
713 | if (copy_from_user(data, (void __user *)(unsigned long)src, len)) { | ||
714 | kfree(data); | ||
715 | return -EFAULT; | ||
716 | } | ||
717 | 712 | ||
718 | *dest = data; | 713 | *dest = data; |
719 | return 0; | 714 | return 0; |
diff --git a/drivers/infiniband/hw/qib/qib_fs.c b/drivers/infiniband/hw/qib/qib_fs.c index 755470440ef1..edef8527eb34 100644 --- a/drivers/infiniband/hw/qib/qib_fs.c +++ b/drivers/infiniband/hw/qib/qib_fs.c | |||
@@ -144,10 +144,11 @@ static ssize_t dev_counters_read(struct file *file, char __user *buf, | |||
144 | size_t count, loff_t *ppos) | 144 | size_t count, loff_t *ppos) |
145 | { | 145 | { |
146 | u64 *counters; | 146 | u64 *counters; |
147 | size_t avail; | ||
147 | struct qib_devdata *dd = private2dd(file); | 148 | struct qib_devdata *dd = private2dd(file); |
148 | 149 | ||
149 | return simple_read_from_buffer(buf, count, ppos, counters, | 150 | avail = dd->f_read_cntrs(dd, *ppos, NULL, &counters); |
150 | dd->f_read_cntrs(dd, *ppos, NULL, &counters)); | 151 | return simple_read_from_buffer(buf, count, ppos, counters, avail); |
151 | } | 152 | } |
152 | 153 | ||
153 | /* read the per-device counters */ | 154 | /* read the per-device counters */ |
@@ -155,10 +156,11 @@ static ssize_t dev_names_read(struct file *file, char __user *buf, | |||
155 | size_t count, loff_t *ppos) | 156 | size_t count, loff_t *ppos) |
156 | { | 157 | { |
157 | char *names; | 158 | char *names; |
159 | size_t avail; | ||
158 | struct qib_devdata *dd = private2dd(file); | 160 | struct qib_devdata *dd = private2dd(file); |
159 | 161 | ||
160 | return simple_read_from_buffer(buf, count, ppos, names, | 162 | avail = dd->f_read_cntrs(dd, *ppos, &names, NULL); |
161 | dd->f_read_cntrs(dd, *ppos, &names, NULL)); | 163 | return simple_read_from_buffer(buf, count, ppos, names, avail); |
162 | } | 164 | } |
163 | 165 | ||
164 | static const struct file_operations cntr_ops[] = { | 166 | static const struct file_operations cntr_ops[] = { |
@@ -176,10 +178,11 @@ static ssize_t portnames_read(struct file *file, char __user *buf, | |||
176 | size_t count, loff_t *ppos) | 178 | size_t count, loff_t *ppos) |
177 | { | 179 | { |
178 | char *names; | 180 | char *names; |
181 | size_t avail; | ||
179 | struct qib_devdata *dd = private2dd(file); | 182 | struct qib_devdata *dd = private2dd(file); |
180 | 183 | ||
181 | return simple_read_from_buffer(buf, count, ppos, names, | 184 | avail = dd->f_read_portcntrs(dd, *ppos, 0, &names, NULL); |
182 | dd->f_read_portcntrs(dd, *ppos, 0, &names, NULL)); | 185 | return simple_read_from_buffer(buf, count, ppos, names, avail); |
183 | } | 186 | } |
184 | 187 | ||
185 | /* read the per-port counters for port 1 (pidx 0) */ | 188 | /* read the per-port counters for port 1 (pidx 0) */ |
@@ -187,10 +190,11 @@ static ssize_t portcntrs_1_read(struct file *file, char __user *buf, | |||
187 | size_t count, loff_t *ppos) | 190 | size_t count, loff_t *ppos) |
188 | { | 191 | { |
189 | u64 *counters; | 192 | u64 *counters; |
193 | size_t avail; | ||
190 | struct qib_devdata *dd = private2dd(file); | 194 | struct qib_devdata *dd = private2dd(file); |
191 | 195 | ||
192 | return simple_read_from_buffer(buf, count, ppos, counters, | 196 | avail = dd->f_read_portcntrs(dd, *ppos, 0, NULL, &counters); |
193 | dd->f_read_portcntrs(dd, *ppos, 0, NULL, &counters)); | 197 | return simple_read_from_buffer(buf, count, ppos, counters, avail); |
194 | } | 198 | } |
195 | 199 | ||
196 | /* read the per-port counters for port 2 (pidx 1) */ | 200 | /* read the per-port counters for port 2 (pidx 1) */ |
@@ -198,10 +202,11 @@ static ssize_t portcntrs_2_read(struct file *file, char __user *buf, | |||
198 | size_t count, loff_t *ppos) | 202 | size_t count, loff_t *ppos) |
199 | { | 203 | { |
200 | u64 *counters; | 204 | u64 *counters; |
205 | size_t avail; | ||
201 | struct qib_devdata *dd = private2dd(file); | 206 | struct qib_devdata *dd = private2dd(file); |
202 | 207 | ||
203 | return simple_read_from_buffer(buf, count, ppos, counters, | 208 | avail = dd->f_read_portcntrs(dd, *ppos, 1, NULL, &counters); |
204 | dd->f_read_portcntrs(dd, *ppos, 1, NULL, &counters)); | 209 | return simple_read_from_buffer(buf, count, ppos, counters, avail); |
205 | } | 210 | } |
206 | 211 | ||
207 | static const struct file_operations portcntr_ops[] = { | 212 | static const struct file_operations portcntr_ops[] = { |
diff --git a/drivers/infiniband/hw/qib/qib_iba6120.c b/drivers/infiniband/hw/qib/qib_iba6120.c index 7b6549fd429b..1eadadc13da8 100644 --- a/drivers/infiniband/hw/qib/qib_iba6120.c +++ b/drivers/infiniband/hw/qib/qib_iba6120.c | |||
@@ -3475,14 +3475,6 @@ struct qib_devdata *qib_init_iba6120_funcs(struct pci_dev *pdev, | |||
3475 | struct qib_devdata *dd; | 3475 | struct qib_devdata *dd; |
3476 | int ret; | 3476 | int ret; |
3477 | 3477 | ||
3478 | #ifndef CONFIG_PCI_MSI | ||
3479 | qib_early_err(&pdev->dev, "QLogic PCIE device 0x%x cannot " | ||
3480 | "work if CONFIG_PCI_MSI is not enabled\n", | ||
3481 | ent->device); | ||
3482 | dd = ERR_PTR(-ENODEV); | ||
3483 | goto bail; | ||
3484 | #endif | ||
3485 | |||
3486 | dd = qib_alloc_devdata(pdev, sizeof(struct qib_pportdata) + | 3478 | dd = qib_alloc_devdata(pdev, sizeof(struct qib_pportdata) + |
3487 | sizeof(struct qib_chip_specific)); | 3479 | sizeof(struct qib_chip_specific)); |
3488 | if (IS_ERR(dd)) | 3480 | if (IS_ERR(dd)) |
@@ -3554,10 +3546,6 @@ struct qib_devdata *qib_init_iba6120_funcs(struct pci_dev *pdev, | |||
3554 | if (qib_mini_init) | 3546 | if (qib_mini_init) |
3555 | goto bail; | 3547 | goto bail; |
3556 | 3548 | ||
3557 | #ifndef CONFIG_PCI_MSI | ||
3558 | qib_dev_err(dd, "PCI_MSI not configured, NO interrupts\n"); | ||
3559 | #endif | ||
3560 | |||
3561 | if (qib_pcie_params(dd, 8, NULL, NULL)) | 3549 | if (qib_pcie_params(dd, 8, NULL, NULL)) |
3562 | qib_dev_err(dd, "Failed to setup PCIe or interrupts; " | 3550 | qib_dev_err(dd, "Failed to setup PCIe or interrupts; " |
3563 | "continuing anyway\n"); | 3551 | "continuing anyway\n"); |
diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c index 2c24eab35b54..503992d9c5ce 100644 --- a/drivers/infiniband/hw/qib/qib_iba7322.c +++ b/drivers/infiniband/hw/qib/qib_iba7322.c | |||
@@ -42,9 +42,6 @@ | |||
42 | #include <linux/jiffies.h> | 42 | #include <linux/jiffies.h> |
43 | #include <rdma/ib_verbs.h> | 43 | #include <rdma/ib_verbs.h> |
44 | #include <rdma/ib_smi.h> | 44 | #include <rdma/ib_smi.h> |
45 | #if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) | ||
46 | #include <linux/dca.h> | ||
47 | #endif | ||
48 | 45 | ||
49 | #include "qib.h" | 46 | #include "qib.h" |
50 | #include "qib_7322_regs.h" | 47 | #include "qib_7322_regs.h" |
@@ -114,40 +111,18 @@ static ushort qib_singleport; | |||
114 | module_param_named(singleport, qib_singleport, ushort, S_IRUGO); | 111 | module_param_named(singleport, qib_singleport, ushort, S_IRUGO); |
115 | MODULE_PARM_DESC(singleport, "Use only IB port 1; more per-port buffer space"); | 112 | MODULE_PARM_DESC(singleport, "Use only IB port 1; more per-port buffer space"); |
116 | 113 | ||
117 | |||
118 | /* | ||
119 | * Setup QMH7342 receive and transmit parameters, necessary because | ||
120 | * each bay, Mez connector, and IB port need different tuning, beyond | ||
121 | * what the switch and HCA can do automatically. | ||
122 | * It's expected to be done by cat'ing files to the modules file, | ||
123 | * rather than setting up as a module parameter. | ||
124 | * It's a "write-only" file, returns 0 when read back. | ||
125 | * The unit, port, bay (if given), and values MUST be done as a single write. | ||
126 | * The unit, port, and bay must precede the values to be effective. | ||
127 | */ | ||
128 | static int setup_qmh_params(const char *, struct kernel_param *); | ||
129 | static unsigned dummy_qmh_params; | ||
130 | module_param_call(qmh_serdes_setup, setup_qmh_params, param_get_uint, | ||
131 | &dummy_qmh_params, S_IWUSR | S_IRUGO); | ||
132 | |||
133 | /* similarly for QME7342, but it's simpler */ | ||
134 | static int setup_qme_params(const char *, struct kernel_param *); | ||
135 | static unsigned dummy_qme_params; | ||
136 | module_param_call(qme_serdes_setup, setup_qme_params, param_get_uint, | ||
137 | &dummy_qme_params, S_IWUSR | S_IRUGO); | ||
138 | |||
139 | #define MAX_ATTEN_LEN 64 /* plenty for any real system */ | 114 | #define MAX_ATTEN_LEN 64 /* plenty for any real system */ |
140 | /* for read back, default index is ~5m copper cable */ | 115 | /* for read back, default index is ~5m copper cable */ |
141 | static char cable_atten_list[MAX_ATTEN_LEN] = "10"; | 116 | static char txselect_list[MAX_ATTEN_LEN] = "10"; |
142 | static struct kparam_string kp_cable_atten = { | 117 | static struct kparam_string kp_txselect = { |
143 | .string = cable_atten_list, | 118 | .string = txselect_list, |
144 | .maxlen = MAX_ATTEN_LEN | 119 | .maxlen = MAX_ATTEN_LEN |
145 | }; | 120 | }; |
146 | static int setup_cable_atten(const char *, struct kernel_param *); | 121 | static int setup_txselect(const char *, struct kernel_param *); |
147 | module_param_call(cable_atten, setup_cable_atten, param_get_string, | 122 | module_param_call(txselect, setup_txselect, param_get_string, |
148 | &kp_cable_atten, S_IWUSR | S_IRUGO); | 123 | &kp_txselect, S_IWUSR | S_IRUGO); |
149 | MODULE_PARM_DESC(cable_atten, \ | 124 | MODULE_PARM_DESC(txselect, \ |
150 | "cable attenuation indices for cables with invalid EEPROM"); | 125 | "Tx serdes indices (for no QSFP or invalid QSFP data)"); |
151 | 126 | ||
152 | #define BOARD_QME7342 5 | 127 | #define BOARD_QME7342 5 |
153 | #define BOARD_QMH7342 6 | 128 | #define BOARD_QMH7342 6 |
@@ -540,12 +515,6 @@ struct qib_chip_specific { | |||
540 | u32 lastbuf_for_pio; | 515 | u32 lastbuf_for_pio; |
541 | u32 stay_in_freeze; | 516 | u32 stay_in_freeze; |
542 | u32 recovery_ports_initted; | 517 | u32 recovery_ports_initted; |
543 | #if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) | ||
544 | u32 dca_ctrl; | ||
545 | int rhdr_cpu[18]; | ||
546 | int sdma_cpu[2]; | ||
547 | u64 dca_rcvhdr_ctrl[5]; /* B, C, D, E, F */ | ||
548 | #endif | ||
549 | struct msix_entry *msix_entries; | 518 | struct msix_entry *msix_entries; |
550 | void **msix_arg; | 519 | void **msix_arg; |
551 | unsigned long *sendchkenable; | 520 | unsigned long *sendchkenable; |
@@ -574,11 +543,12 @@ struct vendor_txdds_ent { | |||
574 | static void write_tx_serdes_param(struct qib_pportdata *, struct txdds_ent *); | 543 | static void write_tx_serdes_param(struct qib_pportdata *, struct txdds_ent *); |
575 | 544 | ||
576 | #define TXDDS_TABLE_SZ 16 /* number of entries per speed in onchip table */ | 545 | #define TXDDS_TABLE_SZ 16 /* number of entries per speed in onchip table */ |
546 | #define TXDDS_EXTRA_SZ 11 /* number of extra tx settings entries */ | ||
577 | #define SERDES_CHANS 4 /* yes, it's obvious, but one less magic number */ | 547 | #define SERDES_CHANS 4 /* yes, it's obvious, but one less magic number */ |
578 | 548 | ||
579 | #define H1_FORCE_VAL 8 | 549 | #define H1_FORCE_VAL 8 |
580 | #define H1_FORCE_QME 1 /* may be overridden via setup_qme_params() */ | 550 | #define H1_FORCE_QME 1 /* may be overridden via setup_txselect() */ |
581 | #define H1_FORCE_QMH 7 /* may be overridden via setup_qmh_params() */ | 551 | #define H1_FORCE_QMH 7 /* may be overridden via setup_txselect() */ |
582 | 552 | ||
583 | /* The static and dynamic registers are paired, and the pairs indexed by spd */ | 553 | /* The static and dynamic registers are paired, and the pairs indexed by spd */ |
584 | #define krp_static_adapt_dis(spd) (KREG_IBPORT_IDX(ADAPT_DISABLE_STATIC_SDR) \ | 554 | #define krp_static_adapt_dis(spd) (KREG_IBPORT_IDX(ADAPT_DISABLE_STATIC_SDR) \ |
@@ -590,15 +560,6 @@ static void write_tx_serdes_param(struct qib_pportdata *, struct txdds_ent *); | |||
590 | #define QDR_STATIC_ADAPT_INIT 0xffffffffffULL /* up, disable H0,H1-8, LE */ | 560 | #define QDR_STATIC_ADAPT_INIT 0xffffffffffULL /* up, disable H0,H1-8, LE */ |
591 | #define QDR_STATIC_ADAPT_INIT_R1 0xf0ffffffffULL /* r1 up, disable H0,H1-8 */ | 561 | #define QDR_STATIC_ADAPT_INIT_R1 0xf0ffffffffULL /* r1 up, disable H0,H1-8 */ |
592 | 562 | ||
593 | static const struct txdds_ent qmh_sdr_txdds = { 11, 0, 5, 6 }; | ||
594 | static const struct txdds_ent qmh_ddr_txdds = { 7, 0, 2, 8 }; | ||
595 | static const struct txdds_ent qmh_qdr_txdds = { 0, 1, 3, 10 }; | ||
596 | |||
597 | /* this is used for unknown mez cards also */ | ||
598 | static const struct txdds_ent qme_sdr_txdds = { 11, 0, 4, 4 }; | ||
599 | static const struct txdds_ent qme_ddr_txdds = { 7, 0, 2, 7 }; | ||
600 | static const struct txdds_ent qme_qdr_txdds = { 0, 1, 12, 11 }; | ||
601 | |||
602 | struct qib_chippport_specific { | 563 | struct qib_chippport_specific { |
603 | u64 __iomem *kpregbase; | 564 | u64 __iomem *kpregbase; |
604 | u64 __iomem *cpregbase; | 565 | u64 __iomem *cpregbase; |
@@ -637,12 +598,8 @@ struct qib_chippport_specific { | |||
637 | * Per-bay per-channel rcv QMH H1 values and Tx values for QDR. | 598 | * Per-bay per-channel rcv QMH H1 values and Tx values for QDR. |
638 | * entry zero is unused, to simplify indexing | 599 | * entry zero is unused, to simplify indexing |
639 | */ | 600 | */ |
640 | u16 h1_val; | 601 | u8 h1_val; |
641 | u8 amp[SERDES_CHANS]; | 602 | u8 no_eep; /* txselect table index to use if no qsfp info */ |
642 | u8 pre[SERDES_CHANS]; | ||
643 | u8 mainv[SERDES_CHANS]; | ||
644 | u8 post[SERDES_CHANS]; | ||
645 | u8 no_eep; /* attenuation index to use if no qsfp info */ | ||
646 | u8 ipg_tries; | 603 | u8 ipg_tries; |
647 | u8 ibmalfusesnap; | 604 | u8 ibmalfusesnap; |
648 | struct qib_qsfp_data qsfp_data; | 605 | struct qib_qsfp_data qsfp_data; |
@@ -676,52 +633,6 @@ static struct { | |||
676 | SYM_LSB(IntStatus, SDmaCleanupDone_1), 2 }, | 633 | SYM_LSB(IntStatus, SDmaCleanupDone_1), 2 }, |
677 | }; | 634 | }; |
678 | 635 | ||
679 | #if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) | ||
680 | static const struct dca_reg_map { | ||
681 | int shadow_inx; | ||
682 | int lsb; | ||
683 | u64 mask; | ||
684 | u16 regno; | ||
685 | } dca_rcvhdr_reg_map[] = { | ||
686 | { 0, SYM_LSB(DCACtrlB, RcvHdrq0DCAOPH), | ||
687 | ~SYM_MASK(DCACtrlB, RcvHdrq0DCAOPH) , KREG_IDX(DCACtrlB) }, | ||
688 | { 0, SYM_LSB(DCACtrlB, RcvHdrq1DCAOPH), | ||
689 | ~SYM_MASK(DCACtrlB, RcvHdrq1DCAOPH) , KREG_IDX(DCACtrlB) }, | ||
690 | { 0, SYM_LSB(DCACtrlB, RcvHdrq2DCAOPH), | ||
691 | ~SYM_MASK(DCACtrlB, RcvHdrq2DCAOPH) , KREG_IDX(DCACtrlB) }, | ||
692 | { 0, SYM_LSB(DCACtrlB, RcvHdrq3DCAOPH), | ||
693 | ~SYM_MASK(DCACtrlB, RcvHdrq3DCAOPH) , KREG_IDX(DCACtrlB) }, | ||
694 | { 1, SYM_LSB(DCACtrlC, RcvHdrq4DCAOPH), | ||
695 | ~SYM_MASK(DCACtrlC, RcvHdrq4DCAOPH) , KREG_IDX(DCACtrlC) }, | ||
696 | { 1, SYM_LSB(DCACtrlC, RcvHdrq5DCAOPH), | ||
697 | ~SYM_MASK(DCACtrlC, RcvHdrq5DCAOPH) , KREG_IDX(DCACtrlC) }, | ||
698 | { 1, SYM_LSB(DCACtrlC, RcvHdrq6DCAOPH), | ||
699 | ~SYM_MASK(DCACtrlC, RcvHdrq6DCAOPH) , KREG_IDX(DCACtrlC) }, | ||
700 | { 1, SYM_LSB(DCACtrlC, RcvHdrq7DCAOPH), | ||
701 | ~SYM_MASK(DCACtrlC, RcvHdrq7DCAOPH) , KREG_IDX(DCACtrlC) }, | ||
702 | { 2, SYM_LSB(DCACtrlD, RcvHdrq8DCAOPH), | ||
703 | ~SYM_MASK(DCACtrlD, RcvHdrq8DCAOPH) , KREG_IDX(DCACtrlD) }, | ||
704 | { 2, SYM_LSB(DCACtrlD, RcvHdrq9DCAOPH), | ||
705 | ~SYM_MASK(DCACtrlD, RcvHdrq9DCAOPH) , KREG_IDX(DCACtrlD) }, | ||
706 | { 2, SYM_LSB(DCACtrlD, RcvHdrq10DCAOPH), | ||
707 | ~SYM_MASK(DCACtrlD, RcvHdrq10DCAOPH) , KREG_IDX(DCACtrlD) }, | ||
708 | { 2, SYM_LSB(DCACtrlD, RcvHdrq11DCAOPH), | ||
709 | ~SYM_MASK(DCACtrlD, RcvHdrq11DCAOPH) , KREG_IDX(DCACtrlD) }, | ||
710 | { 3, SYM_LSB(DCACtrlE, RcvHdrq12DCAOPH), | ||
711 | ~SYM_MASK(DCACtrlE, RcvHdrq12DCAOPH) , KREG_IDX(DCACtrlE) }, | ||
712 | { 3, SYM_LSB(DCACtrlE, RcvHdrq13DCAOPH), | ||
713 | ~SYM_MASK(DCACtrlE, RcvHdrq13DCAOPH) , KREG_IDX(DCACtrlE) }, | ||
714 | { 3, SYM_LSB(DCACtrlE, RcvHdrq14DCAOPH), | ||
715 | ~SYM_MASK(DCACtrlE, RcvHdrq14DCAOPH) , KREG_IDX(DCACtrlE) }, | ||
716 | { 3, SYM_LSB(DCACtrlE, RcvHdrq15DCAOPH), | ||
717 | ~SYM_MASK(DCACtrlE, RcvHdrq15DCAOPH) , KREG_IDX(DCACtrlE) }, | ||
718 | { 4, SYM_LSB(DCACtrlF, RcvHdrq16DCAOPH), | ||
719 | ~SYM_MASK(DCACtrlF, RcvHdrq16DCAOPH) , KREG_IDX(DCACtrlF) }, | ||
720 | { 4, SYM_LSB(DCACtrlF, RcvHdrq17DCAOPH), | ||
721 | ~SYM_MASK(DCACtrlF, RcvHdrq17DCAOPH) , KREG_IDX(DCACtrlF) }, | ||
722 | }; | ||
723 | #endif | ||
724 | |||
725 | /* ibcctrl bits */ | 636 | /* ibcctrl bits */ |
726 | #define QLOGIC_IB_IBCC_LINKINITCMD_DISABLE 1 | 637 | #define QLOGIC_IB_IBCC_LINKINITCMD_DISABLE 1 |
727 | /* cycle through TS1/TS2 till OK */ | 638 | /* cycle through TS1/TS2 till OK */ |
@@ -2572,95 +2483,6 @@ static void qib_setup_7322_setextled(struct qib_pportdata *ppd, u32 on) | |||
2572 | qib_write_kreg_port(ppd, krp_rcvpktledcnt, ledblink); | 2483 | qib_write_kreg_port(ppd, krp_rcvpktledcnt, ledblink); |
2573 | } | 2484 | } |
2574 | 2485 | ||
2575 | #if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) | ||
2576 | static void qib_update_rhdrq_dca(struct qib_ctxtdata *rcd) | ||
2577 | { | ||
2578 | struct qib_devdata *dd = rcd->dd; | ||
2579 | struct qib_chip_specific *cspec = dd->cspec; | ||
2580 | int cpu = get_cpu(); | ||
2581 | |||
2582 | if (cspec->rhdr_cpu[rcd->ctxt] != cpu) { | ||
2583 | const struct dca_reg_map *rmp; | ||
2584 | |||
2585 | cspec->rhdr_cpu[rcd->ctxt] = cpu; | ||
2586 | rmp = &dca_rcvhdr_reg_map[rcd->ctxt]; | ||
2587 | cspec->dca_rcvhdr_ctrl[rmp->shadow_inx] &= rmp->mask; | ||
2588 | cspec->dca_rcvhdr_ctrl[rmp->shadow_inx] |= | ||
2589 | (u64) dca3_get_tag(&dd->pcidev->dev, cpu) << rmp->lsb; | ||
2590 | qib_write_kreg(dd, rmp->regno, | ||
2591 | cspec->dca_rcvhdr_ctrl[rmp->shadow_inx]); | ||
2592 | cspec->dca_ctrl |= SYM_MASK(DCACtrlA, RcvHdrqDCAEnable); | ||
2593 | qib_write_kreg(dd, KREG_IDX(DCACtrlA), cspec->dca_ctrl); | ||
2594 | } | ||
2595 | put_cpu(); | ||
2596 | } | ||
2597 | |||
2598 | static void qib_update_sdma_dca(struct qib_pportdata *ppd) | ||
2599 | { | ||
2600 | struct qib_devdata *dd = ppd->dd; | ||
2601 | struct qib_chip_specific *cspec = dd->cspec; | ||
2602 | int cpu = get_cpu(); | ||
2603 | unsigned pidx = ppd->port - 1; | ||
2604 | |||
2605 | if (cspec->sdma_cpu[pidx] != cpu) { | ||
2606 | cspec->sdma_cpu[pidx] = cpu; | ||
2607 | cspec->dca_rcvhdr_ctrl[4] &= ~(ppd->hw_pidx ? | ||
2608 | SYM_MASK(DCACtrlF, SendDma1DCAOPH) : | ||
2609 | SYM_MASK(DCACtrlF, SendDma0DCAOPH)); | ||
2610 | cspec->dca_rcvhdr_ctrl[4] |= | ||
2611 | (u64) dca3_get_tag(&dd->pcidev->dev, cpu) << | ||
2612 | (ppd->hw_pidx ? | ||
2613 | SYM_LSB(DCACtrlF, SendDma1DCAOPH) : | ||
2614 | SYM_LSB(DCACtrlF, SendDma0DCAOPH)); | ||
2615 | qib_write_kreg(dd, KREG_IDX(DCACtrlF), | ||
2616 | cspec->dca_rcvhdr_ctrl[4]); | ||
2617 | cspec->dca_ctrl |= ppd->hw_pidx ? | ||
2618 | SYM_MASK(DCACtrlA, SendDMAHead1DCAEnable) : | ||
2619 | SYM_MASK(DCACtrlA, SendDMAHead0DCAEnable); | ||
2620 | qib_write_kreg(dd, KREG_IDX(DCACtrlA), cspec->dca_ctrl); | ||
2621 | } | ||
2622 | put_cpu(); | ||
2623 | } | ||
2624 | |||
2625 | static void qib_setup_dca(struct qib_devdata *dd) | ||
2626 | { | ||
2627 | struct qib_chip_specific *cspec = dd->cspec; | ||
2628 | int i; | ||
2629 | |||
2630 | for (i = 0; i < ARRAY_SIZE(cspec->rhdr_cpu); i++) | ||
2631 | cspec->rhdr_cpu[i] = -1; | ||
2632 | for (i = 0; i < ARRAY_SIZE(cspec->sdma_cpu); i++) | ||
2633 | cspec->sdma_cpu[i] = -1; | ||
2634 | cspec->dca_rcvhdr_ctrl[0] = | ||
2635 | (1ULL << SYM_LSB(DCACtrlB, RcvHdrq0DCAXfrCnt)) | | ||
2636 | (1ULL << SYM_LSB(DCACtrlB, RcvHdrq1DCAXfrCnt)) | | ||
2637 | (1ULL << SYM_LSB(DCACtrlB, RcvHdrq2DCAXfrCnt)) | | ||
2638 | (1ULL << SYM_LSB(DCACtrlB, RcvHdrq3DCAXfrCnt)); | ||
2639 | cspec->dca_rcvhdr_ctrl[1] = | ||
2640 | (1ULL << SYM_LSB(DCACtrlC, RcvHdrq4DCAXfrCnt)) | | ||
2641 | (1ULL << SYM_LSB(DCACtrlC, RcvHdrq5DCAXfrCnt)) | | ||
2642 | (1ULL << SYM_LSB(DCACtrlC, RcvHdrq6DCAXfrCnt)) | | ||
2643 | (1ULL << SYM_LSB(DCACtrlC, RcvHdrq7DCAXfrCnt)); | ||
2644 | cspec->dca_rcvhdr_ctrl[2] = | ||
2645 | (1ULL << SYM_LSB(DCACtrlD, RcvHdrq8DCAXfrCnt)) | | ||
2646 | (1ULL << SYM_LSB(DCACtrlD, RcvHdrq9DCAXfrCnt)) | | ||
2647 | (1ULL << SYM_LSB(DCACtrlD, RcvHdrq10DCAXfrCnt)) | | ||
2648 | (1ULL << SYM_LSB(DCACtrlD, RcvHdrq11DCAXfrCnt)); | ||
2649 | cspec->dca_rcvhdr_ctrl[3] = | ||
2650 | (1ULL << SYM_LSB(DCACtrlE, RcvHdrq12DCAXfrCnt)) | | ||
2651 | (1ULL << SYM_LSB(DCACtrlE, RcvHdrq13DCAXfrCnt)) | | ||
2652 | (1ULL << SYM_LSB(DCACtrlE, RcvHdrq14DCAXfrCnt)) | | ||
2653 | (1ULL << SYM_LSB(DCACtrlE, RcvHdrq15DCAXfrCnt)); | ||
2654 | cspec->dca_rcvhdr_ctrl[4] = | ||
2655 | (1ULL << SYM_LSB(DCACtrlF, RcvHdrq16DCAXfrCnt)) | | ||
2656 | (1ULL << SYM_LSB(DCACtrlF, RcvHdrq17DCAXfrCnt)); | ||
2657 | for (i = 0; i < ARRAY_SIZE(cspec->sdma_cpu); i++) | ||
2658 | qib_write_kreg(dd, KREG_IDX(DCACtrlB) + i, | ||
2659 | cspec->dca_rcvhdr_ctrl[i]); | ||
2660 | } | ||
2661 | |||
2662 | #endif | ||
2663 | |||
2664 | /* | 2486 | /* |
2665 | * Disable MSIx interrupt if enabled, call generic MSIx code | 2487 | * Disable MSIx interrupt if enabled, call generic MSIx code |
2666 | * to cleanup, and clear pending MSIx interrupts. | 2488 | * to cleanup, and clear pending MSIx interrupts. |
@@ -2701,15 +2523,6 @@ static void qib_setup_7322_cleanup(struct qib_devdata *dd) | |||
2701 | { | 2523 | { |
2702 | int i; | 2524 | int i; |
2703 | 2525 | ||
2704 | #if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) | ||
2705 | if (dd->flags & QIB_DCA_ENABLED) { | ||
2706 | dca_remove_requester(&dd->pcidev->dev); | ||
2707 | dd->flags &= ~QIB_DCA_ENABLED; | ||
2708 | dd->cspec->dca_ctrl = 0; | ||
2709 | qib_write_kreg(dd, KREG_IDX(DCACtrlA), dd->cspec->dca_ctrl); | ||
2710 | } | ||
2711 | #endif | ||
2712 | |||
2713 | qib_7322_free_irq(dd); | 2526 | qib_7322_free_irq(dd); |
2714 | kfree(dd->cspec->cntrs); | 2527 | kfree(dd->cspec->cntrs); |
2715 | kfree(dd->cspec->sendchkenable); | 2528 | kfree(dd->cspec->sendchkenable); |
@@ -3017,11 +2830,6 @@ static irqreturn_t qib_7322pintr(int irq, void *data) | |||
3017 | if (dd->int_counter != (u32) -1) | 2830 | if (dd->int_counter != (u32) -1) |
3018 | dd->int_counter++; | 2831 | dd->int_counter++; |
3019 | 2832 | ||
3020 | #if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) | ||
3021 | if (dd->flags & QIB_DCA_ENABLED) | ||
3022 | qib_update_rhdrq_dca(rcd); | ||
3023 | #endif | ||
3024 | |||
3025 | /* Clear the interrupt bit we expect to be set. */ | 2833 | /* Clear the interrupt bit we expect to be set. */ |
3026 | qib_write_kreg(dd, kr_intclear, ((1ULL << QIB_I_RCVAVAIL_LSB) | | 2834 | qib_write_kreg(dd, kr_intclear, ((1ULL << QIB_I_RCVAVAIL_LSB) | |
3027 | (1ULL << QIB_I_RCVURG_LSB)) << rcd->ctxt); | 2835 | (1ULL << QIB_I_RCVURG_LSB)) << rcd->ctxt); |
@@ -3085,11 +2893,6 @@ static irqreturn_t sdma_intr(int irq, void *data) | |||
3085 | if (dd->int_counter != (u32) -1) | 2893 | if (dd->int_counter != (u32) -1) |
3086 | dd->int_counter++; | 2894 | dd->int_counter++; |
3087 | 2895 | ||
3088 | #if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) | ||
3089 | if (dd->flags & QIB_DCA_ENABLED) | ||
3090 | qib_update_sdma_dca(ppd); | ||
3091 | #endif | ||
3092 | |||
3093 | /* Clear the interrupt bit we expect to be set. */ | 2896 | /* Clear the interrupt bit we expect to be set. */ |
3094 | qib_write_kreg(dd, kr_intclear, ppd->hw_pidx ? | 2897 | qib_write_kreg(dd, kr_intclear, ppd->hw_pidx ? |
3095 | INT_MASK_P(SDma, 1) : INT_MASK_P(SDma, 0)); | 2898 | INT_MASK_P(SDma, 1) : INT_MASK_P(SDma, 0)); |
@@ -3119,11 +2922,6 @@ static irqreturn_t sdma_idle_intr(int irq, void *data) | |||
3119 | if (dd->int_counter != (u32) -1) | 2922 | if (dd->int_counter != (u32) -1) |
3120 | dd->int_counter++; | 2923 | dd->int_counter++; |
3121 | 2924 | ||
3122 | #if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) | ||
3123 | if (dd->flags & QIB_DCA_ENABLED) | ||
3124 | qib_update_sdma_dca(ppd); | ||
3125 | #endif | ||
3126 | |||
3127 | /* Clear the interrupt bit we expect to be set. */ | 2925 | /* Clear the interrupt bit we expect to be set. */ |
3128 | qib_write_kreg(dd, kr_intclear, ppd->hw_pidx ? | 2926 | qib_write_kreg(dd, kr_intclear, ppd->hw_pidx ? |
3129 | INT_MASK_P(SDmaIdle, 1) : INT_MASK_P(SDmaIdle, 0)); | 2927 | INT_MASK_P(SDmaIdle, 1) : INT_MASK_P(SDmaIdle, 0)); |
@@ -3153,11 +2951,6 @@ static irqreturn_t sdma_progress_intr(int irq, void *data) | |||
3153 | if (dd->int_counter != (u32) -1) | 2951 | if (dd->int_counter != (u32) -1) |
3154 | dd->int_counter++; | 2952 | dd->int_counter++; |
3155 | 2953 | ||
3156 | #if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) | ||
3157 | if (dd->flags & QIB_DCA_ENABLED) | ||
3158 | qib_update_sdma_dca(ppd); | ||
3159 | #endif | ||
3160 | |||
3161 | /* Clear the interrupt bit we expect to be set. */ | 2954 | /* Clear the interrupt bit we expect to be set. */ |
3162 | qib_write_kreg(dd, kr_intclear, ppd->hw_pidx ? | 2955 | qib_write_kreg(dd, kr_intclear, ppd->hw_pidx ? |
3163 | INT_MASK_P(SDmaProgress, 1) : | 2956 | INT_MASK_P(SDmaProgress, 1) : |
@@ -3188,11 +2981,6 @@ static irqreturn_t sdma_cleanup_intr(int irq, void *data) | |||
3188 | if (dd->int_counter != (u32) -1) | 2981 | if (dd->int_counter != (u32) -1) |
3189 | dd->int_counter++; | 2982 | dd->int_counter++; |
3190 | 2983 | ||
3191 | #if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) | ||
3192 | if (dd->flags & QIB_DCA_ENABLED) | ||
3193 | qib_update_sdma_dca(ppd); | ||
3194 | #endif | ||
3195 | |||
3196 | /* Clear the interrupt bit we expect to be set. */ | 2984 | /* Clear the interrupt bit we expect to be set. */ |
3197 | qib_write_kreg(dd, kr_intclear, ppd->hw_pidx ? | 2985 | qib_write_kreg(dd, kr_intclear, ppd->hw_pidx ? |
3198 | INT_MASK_PM(SDmaCleanupDone, 1) : | 2986 | INT_MASK_PM(SDmaCleanupDone, 1) : |
@@ -4299,10 +4087,6 @@ static void rcvctrl_7322_mod(struct qib_pportdata *ppd, unsigned int op, | |||
4299 | qib_write_kreg_ctxt(dd, krc_rcvhdraddr, ctxt, | 4087 | qib_write_kreg_ctxt(dd, krc_rcvhdraddr, ctxt, |
4300 | rcd->rcvhdrq_phys); | 4088 | rcd->rcvhdrq_phys); |
4301 | rcd->seq_cnt = 1; | 4089 | rcd->seq_cnt = 1; |
4302 | #if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) | ||
4303 | if (dd->flags & QIB_DCA_ENABLED) | ||
4304 | qib_update_rhdrq_dca(rcd); | ||
4305 | #endif | ||
4306 | } | 4090 | } |
4307 | if (op & QIB_RCVCTRL_CTXT_DIS) | 4091 | if (op & QIB_RCVCTRL_CTXT_DIS) |
4308 | ppd->p_rcvctrl &= | 4092 | ppd->p_rcvctrl &= |
@@ -5360,7 +5144,13 @@ static int qib_7322_ib_updown(struct qib_pportdata *ppd, int ibup, u64 ibcs) | |||
5360 | QIBL_IB_AUTONEG_INPROG))) | 5144 | QIBL_IB_AUTONEG_INPROG))) |
5361 | set_7322_ibspeed_fast(ppd, ppd->link_speed_enabled); | 5145 | set_7322_ibspeed_fast(ppd, ppd->link_speed_enabled); |
5362 | if (!(ppd->lflags & QIBL_IB_AUTONEG_INPROG)) { | 5146 | if (!(ppd->lflags & QIBL_IB_AUTONEG_INPROG)) { |
5147 | /* unlock the Tx settings, speed may change */ | ||
5148 | qib_write_kreg_port(ppd, krp_tx_deemph_override, | ||
5149 | SYM_MASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, | ||
5150 | reset_tx_deemphasis_override)); | ||
5363 | qib_cancel_sends(ppd); | 5151 | qib_cancel_sends(ppd); |
5152 | /* on link down, ensure sane pcs state */ | ||
5153 | qib_7322_mini_pcs_reset(ppd); | ||
5364 | spin_lock_irqsave(&ppd->sdma_lock, flags); | 5154 | spin_lock_irqsave(&ppd->sdma_lock, flags); |
5365 | if (__qib_sdma_running(ppd)) | 5155 | if (__qib_sdma_running(ppd)) |
5366 | __qib_sdma_process_event(ppd, | 5156 | __qib_sdma_process_event(ppd, |
@@ -5766,26 +5556,28 @@ static void qib_init_7322_qsfp(struct qib_pportdata *ppd) | |||
5766 | } | 5556 | } |
5767 | 5557 | ||
5768 | /* | 5558 | /* |
5769 | * called at device initialization time, and also if the cable_atten | 5559 | * called at device initialization time, and also if the txselect |
5770 | * module parameter is changed. This is used for cables that don't | 5560 | * module parameter is changed. This is used for cables that don't |
5771 | * have valid QSFP EEPROMs (not present, or attenuation is zero). | 5561 | * have valid QSFP EEPROMs (not present, or attenuation is zero). |
5772 | * We initialize to the default, then if there is a specific | 5562 | * We initialize to the default, then if there is a specific |
5773 | * unit,port match, we use that. | 5563 | * unit,port match, we use that (and set it immediately, for the |
5564 | * current speed, if the link is at INIT or better). | ||
5774 | * String format is "default# unit#,port#=# ... u,p=#", separators must | 5565 | * String format is "default# unit#,port#=# ... u,p=#", separators must |
5775 | * be a SPACE character. A newline terminates. | 5566 | * be a SPACE character. A newline terminates. The u,p=# tuples may |
5567 | * optionally have "u,p=#,#", where the final # is the H1 value | ||
5776 | * The last specific match is used (actually, all are used, but last | 5568 | * The last specific match is used (actually, all are used, but last |
5777 | * one is the one that winds up set); if none at all, fall back on default. | 5569 | * one is the one that winds up set); if none at all, fall back on default. |
5778 | */ | 5570 | */ |
5779 | static void set_no_qsfp_atten(struct qib_devdata *dd, int change) | 5571 | static void set_no_qsfp_atten(struct qib_devdata *dd, int change) |
5780 | { | 5572 | { |
5781 | char *nxt, *str; | 5573 | char *nxt, *str; |
5782 | int pidx, unit, port, deflt; | 5574 | u32 pidx, unit, port, deflt, h1; |
5783 | unsigned long val; | 5575 | unsigned long val; |
5784 | int any = 0; | 5576 | int any = 0, seth1; |
5785 | 5577 | ||
5786 | str = cable_atten_list; | 5578 | str = txselect_list; |
5787 | 5579 | ||
5788 | /* default number is validated in setup_cable_atten() */ | 5580 | /* default number is validated in setup_txselect() */ |
5789 | deflt = simple_strtoul(str, &nxt, 0); | 5581 | deflt = simple_strtoul(str, &nxt, 0); |
5790 | for (pidx = 0; pidx < dd->num_pports; ++pidx) | 5582 | for (pidx = 0; pidx < dd->num_pports; ++pidx) |
5791 | dd->pport[pidx].cpspec->no_eep = deflt; | 5583 | dd->pport[pidx].cpspec->no_eep = deflt; |
@@ -5812,16 +5604,28 @@ static void set_no_qsfp_atten(struct qib_devdata *dd, int change) | |||
5812 | ; | 5604 | ; |
5813 | continue; | 5605 | continue; |
5814 | } | 5606 | } |
5815 | if (val >= TXDDS_TABLE_SZ) | 5607 | if (val >= TXDDS_TABLE_SZ + TXDDS_EXTRA_SZ) |
5816 | continue; | 5608 | continue; |
5609 | seth1 = 0; | ||
5610 | h1 = 0; /* gcc thinks it might be used uninitted */ | ||
5611 | if (*nxt == ',' && nxt[1]) { | ||
5612 | str = ++nxt; | ||
5613 | h1 = (u32)simple_strtoul(str, &nxt, 0); | ||
5614 | if (nxt == str) | ||
5615 | while (*nxt && *nxt++ != ' ') /* skip */ | ||
5616 | ; | ||
5617 | else | ||
5618 | seth1 = 1; | ||
5619 | } | ||
5817 | for (pidx = 0; dd->unit == unit && pidx < dd->num_pports; | 5620 | for (pidx = 0; dd->unit == unit && pidx < dd->num_pports; |
5818 | ++pidx) { | 5621 | ++pidx) { |
5819 | if (dd->pport[pidx].port != port || | 5622 | struct qib_pportdata *ppd = &dd->pport[pidx]; |
5820 | !dd->pport[pidx].link_speed_supported) | 5623 | |
5624 | if (ppd->port != port || !ppd->link_speed_supported) | ||
5821 | continue; | 5625 | continue; |
5822 | dd->pport[pidx].cpspec->no_eep = val; | 5626 | ppd->cpspec->no_eep = val; |
5823 | /* now change the IBC and serdes, overriding generic */ | 5627 | /* now change the IBC and serdes, overriding generic */ |
5824 | init_txdds_table(&dd->pport[pidx], 1); | 5628 | init_txdds_table(ppd, 1); |
5825 | any++; | 5629 | any++; |
5826 | } | 5630 | } |
5827 | if (*nxt == '\n') | 5631 | if (*nxt == '\n') |
@@ -5832,35 +5636,35 @@ static void set_no_qsfp_atten(struct qib_devdata *dd, int change) | |||
5832 | * Change the IBC and serdes, but since it's | 5636 | * Change the IBC and serdes, but since it's |
5833 | * general, don't override specific settings. | 5637 | * general, don't override specific settings. |
5834 | */ | 5638 | */ |
5835 | for (pidx = 0; pidx < dd->num_pports; ++pidx) { | 5639 | for (pidx = 0; pidx < dd->num_pports; ++pidx) |
5836 | if (!dd->pport[pidx].link_speed_supported) | 5640 | if (dd->pport[pidx].link_speed_supported) |
5837 | continue; | 5641 | init_txdds_table(&dd->pport[pidx], 0); |
5838 | init_txdds_table(&dd->pport[pidx], 0); | ||
5839 | } | ||
5840 | } | 5642 | } |
5841 | } | 5643 | } |
5842 | 5644 | ||
5843 | /* handle the cable_atten parameter changing */ | 5645 | /* handle the txselect parameter changing */ |
5844 | static int setup_cable_atten(const char *str, struct kernel_param *kp) | 5646 | static int setup_txselect(const char *str, struct kernel_param *kp) |
5845 | { | 5647 | { |
5846 | struct qib_devdata *dd; | 5648 | struct qib_devdata *dd; |
5847 | unsigned long val; | 5649 | unsigned long val; |
5848 | char *n; | 5650 | char *n; |
5849 | if (strlen(str) >= MAX_ATTEN_LEN) { | 5651 | if (strlen(str) >= MAX_ATTEN_LEN) { |
5850 | printk(KERN_INFO QIB_DRV_NAME " cable_atten_values string " | 5652 | printk(KERN_INFO QIB_DRV_NAME " txselect_values string " |
5851 | "too long\n"); | 5653 | "too long\n"); |
5852 | return -ENOSPC; | 5654 | return -ENOSPC; |
5853 | } | 5655 | } |
5854 | val = simple_strtoul(str, &n, 0); | 5656 | val = simple_strtoul(str, &n, 0); |
5855 | if (n == str || val >= TXDDS_TABLE_SZ) { | 5657 | if (n == str || val >= (TXDDS_TABLE_SZ + TXDDS_EXTRA_SZ)) { |
5856 | printk(KERN_INFO QIB_DRV_NAME | 5658 | printk(KERN_INFO QIB_DRV_NAME |
5857 | "cable_atten_values must start with a number\n"); | 5659 | "txselect_values must start with a number < %d\n", |
5660 | TXDDS_TABLE_SZ + TXDDS_EXTRA_SZ); | ||
5858 | return -EINVAL; | 5661 | return -EINVAL; |
5859 | } | 5662 | } |
5860 | strcpy(cable_atten_list, str); | 5663 | strcpy(txselect_list, str); |
5861 | 5664 | ||
5862 | list_for_each_entry(dd, &qib_dev_list, list) | 5665 | list_for_each_entry(dd, &qib_dev_list, list) |
5863 | set_no_qsfp_atten(dd, 1); | 5666 | if (dd->deviceid == PCI_DEVICE_ID_QLOGIC_IB_7322) |
5667 | set_no_qsfp_atten(dd, 1); | ||
5864 | return 0; | 5668 | return 0; |
5865 | } | 5669 | } |
5866 | 5670 | ||
@@ -6261,28 +6065,17 @@ static int qib_init_7322_variables(struct qib_devdata *dd) | |||
6261 | * in adapter-specific routines. | 6065 | * in adapter-specific routines. |
6262 | */ | 6066 | */ |
6263 | if (!(ppd->dd->flags & QIB_HAS_QSFP)) { | 6067 | if (!(ppd->dd->flags & QIB_HAS_QSFP)) { |
6264 | int i; | ||
6265 | const struct txdds_ent *txdds; | ||
6266 | |||
6267 | if (!IS_QMH(ppd->dd) && !IS_QME(ppd->dd)) | 6068 | if (!IS_QMH(ppd->dd) && !IS_QME(ppd->dd)) |
6268 | qib_devinfo(ppd->dd->pcidev, "IB%u:%u: " | 6069 | qib_devinfo(ppd->dd->pcidev, "IB%u:%u: " |
6269 | "Unknown mezzanine card type\n", | 6070 | "Unknown mezzanine card type\n", |
6270 | ppd->dd->unit, ppd->port); | 6071 | dd->unit, ppd->port); |
6271 | txdds = IS_QMH(ppd->dd) ? &qmh_qdr_txdds : | 6072 | cp->h1_val = IS_QMH(dd) ? H1_FORCE_QMH : H1_FORCE_QME; |
6272 | &qme_qdr_txdds; | ||
6273 | |||
6274 | /* | 6073 | /* |
6275 | * set values in case link comes up | 6074 | * Choose center value as default tx serdes setting |
6276 | * before table is written to driver. | 6075 | * until changed through module parameter. |
6277 | */ | 6076 | */ |
6278 | cp->h1_val = IS_QMH(ppd->dd) ? H1_FORCE_QMH : | 6077 | ppd->cpspec->no_eep = IS_QMH(dd) ? |
6279 | H1_FORCE_QME; | 6078 | TXDDS_TABLE_SZ + 2 : TXDDS_TABLE_SZ + 4; |
6280 | for (i = 0; i < SERDES_CHANS; i++) { | ||
6281 | cp->amp[i] = txdds->amp; | ||
6282 | cp->pre[i] = txdds->pre; | ||
6283 | cp->mainv[i] = txdds->main; | ||
6284 | cp->post[i] = txdds->post; | ||
6285 | } | ||
6286 | } else | 6079 | } else |
6287 | cp->h1_val = H1_FORCE_VAL; | 6080 | cp->h1_val = H1_FORCE_VAL; |
6288 | 6081 | ||
@@ -6299,8 +6092,7 @@ static int qib_init_7322_variables(struct qib_devdata *dd) | |||
6299 | 6092 | ||
6300 | dd->rcvhdrentsize = QIB_RCVHDR_ENTSIZE; | 6093 | dd->rcvhdrentsize = QIB_RCVHDR_ENTSIZE; |
6301 | dd->rcvhdrsize = QIB_DFLT_RCVHDRSIZE; | 6094 | dd->rcvhdrsize = QIB_DFLT_RCVHDRSIZE; |
6302 | dd->rhf_offset = | 6095 | dd->rhf_offset = dd->rcvhdrentsize - sizeof(u64) / sizeof(u32); |
6303 | dd->rcvhdrentsize - sizeof(u64) / sizeof(u32); | ||
6304 | 6096 | ||
6305 | /* we always allocate at least 2048 bytes for eager buffers */ | 6097 | /* we always allocate at least 2048 bytes for eager buffers */ |
6306 | dd->rcvegrbufsize = max(mtu, 2048); | 6098 | dd->rcvegrbufsize = max(mtu, 2048); |
@@ -6919,13 +6711,6 @@ struct qib_devdata *qib_init_iba7322_funcs(struct pci_dev *pdev, | |||
6919 | /* clear diagctrl register, in case diags were running and crashed */ | 6711 | /* clear diagctrl register, in case diags were running and crashed */ |
6920 | qib_write_kreg(dd, kr_hwdiagctrl, 0); | 6712 | qib_write_kreg(dd, kr_hwdiagctrl, 0); |
6921 | 6713 | ||
6922 | #if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) | ||
6923 | ret = dca_add_requester(&pdev->dev); | ||
6924 | if (!ret) { | ||
6925 | dd->flags |= QIB_DCA_ENABLED; | ||
6926 | qib_setup_dca(dd); | ||
6927 | } | ||
6928 | #endif | ||
6929 | goto bail; | 6714 | goto bail; |
6930 | 6715 | ||
6931 | bail_cleanup: | 6716 | bail_cleanup: |
@@ -7111,8 +6896,8 @@ static const struct txdds_ent txdds_ddr[TXDDS_TABLE_SZ] = { | |||
7111 | static const struct txdds_ent txdds_qdr[TXDDS_TABLE_SZ] = { | 6896 | static const struct txdds_ent txdds_qdr[TXDDS_TABLE_SZ] = { |
7112 | /* amp, pre, main, post */ | 6897 | /* amp, pre, main, post */ |
7113 | { 2, 2, 15, 6 }, /* Loopback */ | 6898 | { 2, 2, 15, 6 }, /* Loopback */ |
7114 | { 0, 1, 0, 7 }, /* 2 dB */ | 6899 | { 0, 1, 0, 7 }, /* 2 dB (also QMH7342) */ |
7115 | { 0, 1, 0, 9 }, /* 3 dB */ | 6900 | { 0, 1, 0, 9 }, /* 3 dB (also QMH7342) */ |
7116 | { 0, 1, 0, 11 }, /* 4 dB */ | 6901 | { 0, 1, 0, 11 }, /* 4 dB */ |
7117 | { 0, 1, 0, 13 }, /* 5 dB */ | 6902 | { 0, 1, 0, 13 }, /* 5 dB */ |
7118 | { 0, 1, 0, 15 }, /* 6 dB */ | 6903 | { 0, 1, 0, 15 }, /* 6 dB */ |
@@ -7128,6 +6913,57 @@ static const struct txdds_ent txdds_qdr[TXDDS_TABLE_SZ] = { | |||
7128 | { 0, 2, 9, 15 }, /* 16 dB */ | 6913 | { 0, 2, 9, 15 }, /* 16 dB */ |
7129 | }; | 6914 | }; |
7130 | 6915 | ||
6916 | /* | ||
6917 | * extra entries for use with txselect, for indices >= TXDDS_TABLE_SZ. | ||
6918 | * These are mostly used for mez cards going through connectors | ||
6919 | * and backplane traces, but can be used to add other "unusual" | ||
6920 | * table values as well. | ||
6921 | */ | ||
6922 | static const struct txdds_ent txdds_extra_sdr[TXDDS_EXTRA_SZ] = { | ||
6923 | /* amp, pre, main, post */ | ||
6924 | { 0, 0, 0, 1 }, /* QMH7342 backplane settings */ | ||
6925 | { 0, 0, 0, 1 }, /* QMH7342 backplane settings */ | ||
6926 | { 0, 0, 0, 2 }, /* QMH7342 backplane settings */ | ||
6927 | { 0, 0, 0, 2 }, /* QMH7342 backplane settings */ | ||
6928 | { 0, 0, 0, 11 }, /* QME7342 backplane settings */ | ||
6929 | { 0, 0, 0, 11 }, /* QME7342 backplane settings */ | ||
6930 | { 0, 0, 0, 11 }, /* QME7342 backplane settings */ | ||
6931 | { 0, 0, 0, 11 }, /* QME7342 backplane settings */ | ||
6932 | { 0, 0, 0, 11 }, /* QME7342 backplane settings */ | ||
6933 | { 0, 0, 0, 11 }, /* QME7342 backplane settings */ | ||
6934 | { 0, 0, 0, 11 }, /* QME7342 backplane settings */ | ||
6935 | }; | ||
6936 | |||
6937 | static const struct txdds_ent txdds_extra_ddr[TXDDS_EXTRA_SZ] = { | ||
6938 | /* amp, pre, main, post */ | ||
6939 | { 0, 0, 0, 7 }, /* QMH7342 backplane settings */ | ||
6940 | { 0, 0, 0, 7 }, /* QMH7342 backplane settings */ | ||
6941 | { 0, 0, 0, 8 }, /* QMH7342 backplane settings */ | ||
6942 | { 0, 0, 0, 8 }, /* QMH7342 backplane settings */ | ||
6943 | { 0, 0, 0, 13 }, /* QME7342 backplane settings */ | ||
6944 | { 0, 0, 0, 13 }, /* QME7342 backplane settings */ | ||
6945 | { 0, 0, 0, 13 }, /* QME7342 backplane settings */ | ||
6946 | { 0, 0, 0, 13 }, /* QME7342 backplane settings */ | ||
6947 | { 0, 0, 0, 13 }, /* QME7342 backplane settings */ | ||
6948 | { 0, 0, 0, 13 }, /* QME7342 backplane settings */ | ||
6949 | { 0, 0, 0, 13 }, /* QME7342 backplane settings */ | ||
6950 | }; | ||
6951 | |||
6952 | static const struct txdds_ent txdds_extra_qdr[TXDDS_EXTRA_SZ] = { | ||
6953 | /* amp, pre, main, post */ | ||
6954 | { 0, 1, 0, 4 }, /* QMH7342 backplane settings */ | ||
6955 | { 0, 1, 0, 5 }, /* QMH7342 backplane settings */ | ||
6956 | { 0, 1, 0, 6 }, /* QMH7342 backplane settings */ | ||
6957 | { 0, 1, 0, 8 }, /* QMH7342 backplane settings */ | ||
6958 | { 0, 1, 12, 10 }, /* QME7342 backplane setting */ | ||
6959 | { 0, 1, 12, 11 }, /* QME7342 backplane setting */ | ||
6960 | { 0, 1, 12, 12 }, /* QME7342 backplane setting */ | ||
6961 | { 0, 1, 12, 14 }, /* QME7342 backplane setting */ | ||
6962 | { 0, 1, 12, 6 }, /* QME7342 backplane setting */ | ||
6963 | { 0, 1, 12, 7 }, /* QME7342 backplane setting */ | ||
6964 | { 0, 1, 12, 8 }, /* QME7342 backplane setting */ | ||
6965 | }; | ||
6966 | |||
7131 | static const struct txdds_ent *get_atten_table(const struct txdds_ent *txdds, | 6967 | static const struct txdds_ent *get_atten_table(const struct txdds_ent *txdds, |
7132 | unsigned atten) | 6968 | unsigned atten) |
7133 | { | 6969 | { |
@@ -7145,7 +6981,7 @@ static const struct txdds_ent *get_atten_table(const struct txdds_ent *txdds, | |||
7145 | } | 6981 | } |
7146 | 6982 | ||
7147 | /* | 6983 | /* |
7148 | * if override is set, the module parameter cable_atten has a value | 6984 | * if override is set, the module parameter txselect has a value |
7149 | * for this specific port, so use it, rather than our normal mechanism. | 6985 | * for this specific port, so use it, rather than our normal mechanism. |
7150 | */ | 6986 | */ |
7151 | static void find_best_ent(struct qib_pportdata *ppd, | 6987 | static void find_best_ent(struct qib_pportdata *ppd, |
@@ -7184,15 +7020,28 @@ static void find_best_ent(struct qib_pportdata *ppd, | |||
7184 | *ddr_dds = get_atten_table(txdds_ddr, qd->atten[0]); | 7020 | *ddr_dds = get_atten_table(txdds_ddr, qd->atten[0]); |
7185 | *qdr_dds = get_atten_table(txdds_qdr, qd->atten[1]); | 7021 | *qdr_dds = get_atten_table(txdds_qdr, qd->atten[1]); |
7186 | return; | 7022 | return; |
7187 | } else { | 7023 | } else if (ppd->cpspec->no_eep < TXDDS_TABLE_SZ) { |
7188 | /* | 7024 | /* |
7189 | * If we have no (or incomplete) data from the cable | 7025 | * If we have no (or incomplete) data from the cable |
7190 | * EEPROM, or no QSFP, use the module parameter value | 7026 | * EEPROM, or no QSFP, or override is set, use the |
7191 | * to index into the attentuation table. | 7027 | * module parameter value to index into the attentuation |
7028 | * table. | ||
7192 | */ | 7029 | */ |
7193 | *sdr_dds = &txdds_sdr[ppd->cpspec->no_eep]; | 7030 | idx = ppd->cpspec->no_eep; |
7194 | *ddr_dds = &txdds_ddr[ppd->cpspec->no_eep]; | 7031 | *sdr_dds = &txdds_sdr[idx]; |
7195 | *qdr_dds = &txdds_qdr[ppd->cpspec->no_eep]; | 7032 | *ddr_dds = &txdds_ddr[idx]; |
7033 | *qdr_dds = &txdds_qdr[idx]; | ||
7034 | } else if (ppd->cpspec->no_eep < (TXDDS_TABLE_SZ + TXDDS_EXTRA_SZ)) { | ||
7035 | /* similar to above, but index into the "extra" table. */ | ||
7036 | idx = ppd->cpspec->no_eep - TXDDS_TABLE_SZ; | ||
7037 | *sdr_dds = &txdds_extra_sdr[idx]; | ||
7038 | *ddr_dds = &txdds_extra_ddr[idx]; | ||
7039 | *qdr_dds = &txdds_extra_qdr[idx]; | ||
7040 | } else { | ||
7041 | /* this shouldn't happen, it's range checked */ | ||
7042 | *sdr_dds = txdds_sdr + qib_long_atten; | ||
7043 | *ddr_dds = txdds_ddr + qib_long_atten; | ||
7044 | *qdr_dds = txdds_qdr + qib_long_atten; | ||
7196 | } | 7045 | } |
7197 | } | 7046 | } |
7198 | 7047 | ||
@@ -7203,33 +7052,24 @@ static void init_txdds_table(struct qib_pportdata *ppd, int override) | |||
7203 | int idx; | 7052 | int idx; |
7204 | int single_ent = 0; | 7053 | int single_ent = 0; |
7205 | 7054 | ||
7206 | if (IS_QMH(ppd->dd)) { | 7055 | find_best_ent(ppd, &sdr_dds, &ddr_dds, &qdr_dds, override); |
7207 | /* normally will be overridden, via setup_qmh() */ | 7056 | |
7208 | sdr_dds = &qmh_sdr_txdds; | 7057 | /* for mez cards or override, use the selected value for all entries */ |
7209 | ddr_dds = &qmh_ddr_txdds; | 7058 | if (!(ppd->dd->flags & QIB_HAS_QSFP) || override) |
7210 | qdr_dds = &qmh_qdr_txdds; | ||
7211 | single_ent = 1; | ||
7212 | } else if (IS_QME(ppd->dd)) { | ||
7213 | sdr_dds = &qme_sdr_txdds; | ||
7214 | ddr_dds = &qme_ddr_txdds; | ||
7215 | qdr_dds = &qme_qdr_txdds; | ||
7216 | single_ent = 1; | 7059 | single_ent = 1; |
7217 | } else | ||
7218 | find_best_ent(ppd, &sdr_dds, &ddr_dds, &qdr_dds, override); | ||
7219 | 7060 | ||
7220 | /* Fill in the first entry with the best entry found. */ | 7061 | /* Fill in the first entry with the best entry found. */ |
7221 | set_txdds(ppd, 0, sdr_dds); | 7062 | set_txdds(ppd, 0, sdr_dds); |
7222 | set_txdds(ppd, TXDDS_TABLE_SZ, ddr_dds); | 7063 | set_txdds(ppd, TXDDS_TABLE_SZ, ddr_dds); |
7223 | set_txdds(ppd, 2 * TXDDS_TABLE_SZ, qdr_dds); | 7064 | set_txdds(ppd, 2 * TXDDS_TABLE_SZ, qdr_dds); |
7224 | 7065 | if (ppd->lflags & (QIBL_LINKINIT | QIBL_LINKARMED | | |
7225 | /* | 7066 | QIBL_LINKACTIVE)) { |
7226 | * for our current speed, also write that value into the | 7067 | dds = (struct txdds_ent *)(ppd->link_speed_active == |
7227 | * tx serdes registers. | 7068 | QIB_IB_QDR ? qdr_dds : |
7228 | */ | 7069 | (ppd->link_speed_active == |
7229 | dds = (struct txdds_ent *)(ppd->link_speed_active == QIB_IB_QDR ? | 7070 | QIB_IB_DDR ? ddr_dds : sdr_dds)); |
7230 | qdr_dds : (ppd->link_speed_active == | 7071 | write_tx_serdes_param(ppd, dds); |
7231 | QIB_IB_DDR ? ddr_dds : sdr_dds)); | 7072 | } |
7232 | write_tx_serdes_param(ppd, dds); | ||
7233 | 7073 | ||
7234 | /* Fill in the remaining entries with the default table values. */ | 7074 | /* Fill in the remaining entries with the default table values. */ |
7235 | for (idx = 1; idx < ARRAY_SIZE(txdds_sdr); ++idx) { | 7075 | for (idx = 1; idx < ARRAY_SIZE(txdds_sdr); ++idx) { |
@@ -7352,6 +7192,11 @@ static int serdes_7322_init(struct qib_pportdata *ppd) | |||
7352 | */ | 7192 | */ |
7353 | init_txdds_table(ppd, 0); | 7193 | init_txdds_table(ppd, 0); |
7354 | 7194 | ||
7195 | /* ensure no tx overrides from earlier driver loads */ | ||
7196 | qib_write_kreg_port(ppd, krp_tx_deemph_override, | ||
7197 | SYM_MASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, | ||
7198 | reset_tx_deemphasis_override)); | ||
7199 | |||
7355 | /* Patch some SerDes defaults to "Better for IB" */ | 7200 | /* Patch some SerDes defaults to "Better for IB" */ |
7356 | /* Timing Loop Bandwidth: cdr_timing[11:9] = 0 */ | 7201 | /* Timing Loop Bandwidth: cdr_timing[11:9] = 0 */ |
7357 | ibsd_wr_allchans(ppd, 2, 0, BMASK(11, 9)); | 7202 | ibsd_wr_allchans(ppd, 2, 0, BMASK(11, 9)); |
@@ -7421,7 +7266,7 @@ static int serdes_7322_init(struct qib_pportdata *ppd) | |||
7421 | QDR_STATIC_ADAPT_DOWN_R1 : QDR_STATIC_ADAPT_DOWN); | 7266 | QDR_STATIC_ADAPT_DOWN_R1 : QDR_STATIC_ADAPT_DOWN); |
7422 | ppd->cpspec->qdr_dfe_on = 1; | 7267 | ppd->cpspec->qdr_dfe_on = 1; |
7423 | 7268 | ||
7424 | /* (FLoop LOS gate: PPM filter enabled */ | 7269 | /* FLoop LOS gate: PPM filter enabled */ |
7425 | ibsd_wr_allchans(ppd, 38, 0 << 10, 1 << 10); | 7270 | ibsd_wr_allchans(ppd, 38, 0 << 10, 1 << 10); |
7426 | 7271 | ||
7427 | /* rx offset center enabled */ | 7272 | /* rx offset center enabled */ |
@@ -7486,68 +7331,39 @@ static void write_tx_serdes_param(struct qib_pportdata *ppd, | |||
7486 | SYM_MASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, txc0_ena) | | 7331 | SYM_MASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, txc0_ena) | |
7487 | SYM_MASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, txcp1_ena) | | 7332 | SYM_MASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, txcp1_ena) | |
7488 | SYM_MASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, txcn1_ena)); | 7333 | SYM_MASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, txcn1_ena)); |
7489 | deemph |= 1ULL << SYM_LSB(IBSD_TX_DEEMPHASIS_OVERRIDE_0, | 7334 | |
7490 | tx_override_deemphasis_select); | 7335 | deemph |= SYM_MASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, |
7491 | deemph |= txdds->amp << SYM_LSB(IBSD_TX_DEEMPHASIS_OVERRIDE_0, | 7336 | tx_override_deemphasis_select); |
7492 | txampcntl_d2a); | 7337 | deemph |= (txdds->amp & SYM_RMASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, |
7493 | deemph |= txdds->main << SYM_LSB(IBSD_TX_DEEMPHASIS_OVERRIDE_0, | 7338 | txampcntl_d2a)) << SYM_LSB(IBSD_TX_DEEMPHASIS_OVERRIDE_0, |
7494 | txc0_ena); | 7339 | txampcntl_d2a); |
7495 | deemph |= txdds->post << SYM_LSB(IBSD_TX_DEEMPHASIS_OVERRIDE_0, | 7340 | deemph |= (txdds->main & SYM_RMASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, |
7496 | txcp1_ena); | 7341 | txc0_ena)) << SYM_LSB(IBSD_TX_DEEMPHASIS_OVERRIDE_0, |
7497 | deemph |= txdds->pre << SYM_LSB(IBSD_TX_DEEMPHASIS_OVERRIDE_0, | 7342 | txc0_ena); |
7343 | deemph |= (txdds->post & SYM_RMASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, | ||
7344 | txcp1_ena)) << SYM_LSB(IBSD_TX_DEEMPHASIS_OVERRIDE_0, | ||
7345 | txcp1_ena); | ||
7346 | deemph |= (txdds->pre & SYM_RMASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, | ||
7347 | txcn1_ena)) << SYM_LSB(IBSD_TX_DEEMPHASIS_OVERRIDE_0, | ||
7498 | txcn1_ena); | 7348 | txcn1_ena); |
7499 | qib_write_kreg_port(ppd, krp_tx_deemph_override, deemph); | 7349 | qib_write_kreg_port(ppd, krp_tx_deemph_override, deemph); |
7500 | } | 7350 | } |
7501 | 7351 | ||
7502 | /* | 7352 | /* |
7503 | * set per-bay, per channel parameters. For now, we ignore | 7353 | * Set the parameters for mez cards on link bounce, so they are |
7504 | * do_tx, and always set tx parameters, and set them with the same value | 7354 | * always exactly what was requested. Similar logic to init_txdds |
7505 | * for all channels, using the channel 0 value. We may switch to | 7355 | * but does just the serdes. |
7506 | * per-channel settings in the future, and that method only needs | ||
7507 | * to be done once. | ||
7508 | * Because this also writes the IBC txdds table with a single set | ||
7509 | * of values, it should be called only for cases where we want to completely | ||
7510 | * force a specific setting, typically only for mez cards. | ||
7511 | */ | 7356 | */ |
7512 | static void adj_tx_serdes(struct qib_pportdata *ppd) | 7357 | static void adj_tx_serdes(struct qib_pportdata *ppd) |
7513 | { | 7358 | { |
7514 | struct txdds_ent txdds; | 7359 | const struct txdds_ent *sdr_dds, *ddr_dds, *qdr_dds; |
7515 | int i; | 7360 | struct txdds_ent *dds; |
7516 | u8 *amp, *pre, *mainv, *post; | ||
7517 | |||
7518 | /* | ||
7519 | * Because we use TX_DEEMPHASIS_OVERRIDE, we need to | ||
7520 | * always do tx side, just like H1, since it is cleared | ||
7521 | * by link down | ||
7522 | */ | ||
7523 | amp = ppd->cpspec->amp; | ||
7524 | pre = ppd->cpspec->pre; | ||
7525 | mainv = ppd->cpspec->mainv; | ||
7526 | post = ppd->cpspec->post; | ||
7527 | |||
7528 | amp[0] &= SYM_RMASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, | ||
7529 | txampcntl_d2a); | ||
7530 | mainv[0] &= SYM_RMASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, | ||
7531 | txc0_ena); | ||
7532 | post[0] &= SYM_RMASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, | ||
7533 | txcp1_ena); | ||
7534 | pre[0] &= SYM_RMASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, | ||
7535 | txcn1_ena); | ||
7536 | |||
7537 | /* | ||
7538 | * Use the channel zero values, only, for now, for | ||
7539 | * all channels | ||
7540 | */ | ||
7541 | txdds.amp = amp[0]; | ||
7542 | txdds.pre = pre[0]; | ||
7543 | txdds.main = mainv[0]; | ||
7544 | txdds.post = post[0]; | ||
7545 | |||
7546 | /* write the QDR table for IBC use, as backup for link down */ | ||
7547 | for (i = 0; i < ARRAY_SIZE(txdds_qdr); ++i) | ||
7548 | set_txdds(ppd, i + 32, &txdds); | ||
7549 | 7361 | ||
7550 | write_tx_serdes_param(ppd, &txdds); | 7362 | find_best_ent(ppd, &sdr_dds, &ddr_dds, &qdr_dds, 1); |
7363 | dds = (struct txdds_ent *)(ppd->link_speed_active == QIB_IB_QDR ? | ||
7364 | qdr_dds : (ppd->link_speed_active == QIB_IB_DDR ? | ||
7365 | ddr_dds : sdr_dds)); | ||
7366 | write_tx_serdes_param(ppd, dds); | ||
7551 | } | 7367 | } |
7552 | 7368 | ||
7553 | /* set QDR forced value for H1, if needed */ | 7369 | /* set QDR forced value for H1, if needed */ |
@@ -7567,235 +7383,6 @@ static void force_h1(struct qib_pportdata *ppd) | |||
7567 | } | 7383 | } |
7568 | } | 7384 | } |
7569 | 7385 | ||
7570 | /* | ||
7571 | * Parse the parameters for the QMH7342, to get rx and tx serdes | ||
7572 | * settings for that Bay, for both possible mez connectors (PCIe bus) | ||
7573 | * and IB link (one link on mez1, two possible on mez2). | ||
7574 | * | ||
7575 | * Data is comma or white space separated. | ||
7576 | * | ||
7577 | * A set of data has 7 groups, rx and tx groups have SERDES_CHANS values, | ||
7578 | * one per IB lane (serdes channel). | ||
7579 | * The groups are Bay, bus# H1 rcv, and amp, pre, post, main Tx values (QDR). | ||
7580 | * The Bay # is used only for debugging currently. | ||
7581 | * H1 values are set whenever the link goes down, or is at cfg_test or | ||
7582 | * cfg_wait_enh. Tx values are programmed once, when this routine is called | ||
7583 | * (and with default values at chip initialization). Values are any base, in | ||
7584 | * strtoul style, and values are seperated by comma, or any white space | ||
7585 | * (space, tab, newline). | ||
7586 | * | ||
7587 | * An example set might look like this (white space vs | ||
7588 | * comma used for human ease of reading) | ||
7589 | * The ordering is a set of Bay# Bus# H1, amp, pre, post, and main for mez1 IB1, | ||
7590 | * repeat for mez2 IB1, then mez2 IB2. | ||
7591 | * | ||
7592 | * B B H1:0 amp:0 pre:0 post: 0 main:0 | ||
7593 | * a u H1: 1 amp: 1 pre: 1 post: 1 main: 1 | ||
7594 | * y s H1: 2 amp: 2 pre: 2 post: 2 main: 2 | ||
7595 | * H1: 4 amp: 3 pre: 3 post: 3 main: 3 | ||
7596 | * 1 3 8,6,5,6 0,0,0,0 1,1,1,1 10,10,10,10 3,3,3,3 | ||
7597 | * 1 6 7,6,6,7 0,0,0,0 1,1,1,1 10,10,10,10 3,3,3,3 | ||
7598 | * 1 6 9,7,7,8 0,0,0,0 1,1,1,1 10,10,10,10 3,3,3,3 | ||
7599 | */ | ||
7600 | #define N_QMH_FIELDS 22 | ||
7601 | static int setup_qmh_params(const char *str, struct kernel_param *kp) | ||
7602 | { | ||
7603 | char *abuf, *v, *nv, *nvp; | ||
7604 | struct qib_devdata *dd; | ||
7605 | struct qib_pportdata *ppd; | ||
7606 | u32 mez, vlen, nf, port, bay; | ||
7607 | int ret = 0, found = 0; | ||
7608 | |||
7609 | vlen = strlen(str) + 1; | ||
7610 | abuf = kmalloc(vlen, GFP_KERNEL); | ||
7611 | if (!abuf) { | ||
7612 | printk(KERN_INFO QIB_DRV_NAME | ||
7613 | " Unable to allocate QMH param buffer; ignoring\n"); | ||
7614 | return 0; | ||
7615 | } | ||
7616 | memcpy(abuf, str, vlen); | ||
7617 | v = abuf; | ||
7618 | |||
7619 | /* these 3 are because gcc can't know they are set before used */ | ||
7620 | port = 1; | ||
7621 | mez = 1; /* used only for debugging */ | ||
7622 | bay = 0; /* used only for debugging */ | ||
7623 | ppd = NULL; | ||
7624 | for (nf = 0; (nv = strsep(&v, ", \t\n\r")) && | ||
7625 | nf < (N_QMH_FIELDS * 3);) { | ||
7626 | u32 val; | ||
7627 | |||
7628 | if (!*nv) | ||
7629 | /* allow for multiple separators */ | ||
7630 | continue; | ||
7631 | |||
7632 | val = simple_strtoul(nv, &nvp, 0); | ||
7633 | if (nv == nvp) { | ||
7634 | printk(KERN_INFO QIB_DRV_NAME | ||
7635 | " Bay%u, mez%u IB%u non-numeric value (%s) " | ||
7636 | "field #%u, ignoring rest\n", bay, mez, | ||
7637 | port, nv, nf % (N_QMH_FIELDS * 3)); | ||
7638 | ret = -EINVAL; | ||
7639 | goto bail; | ||
7640 | } | ||
7641 | if (!(nf % N_QMH_FIELDS)) { | ||
7642 | ppd = NULL; | ||
7643 | bay = val; | ||
7644 | if (!bay || bay > 16) { | ||
7645 | printk(KERN_INFO QIB_DRV_NAME | ||
7646 | " Invalid bay # %u, field %u, " | ||
7647 | "ignoring rest\n", bay, nf); | ||
7648 | ret = -EINVAL; | ||
7649 | goto bail; | ||
7650 | } | ||
7651 | } else if ((nf % N_QMH_FIELDS) == 1) { | ||
7652 | u32 bus = val; | ||
7653 | if (nf == 1) { | ||
7654 | mez = 1; | ||
7655 | port = 1; | ||
7656 | } else if (nf == (N_QMH_FIELDS + 1)) { | ||
7657 | mez = 2; | ||
7658 | port = 1; | ||
7659 | } else { | ||
7660 | mez = 2; | ||
7661 | port = 2; | ||
7662 | } | ||
7663 | list_for_each_entry(dd, &qib_dev_list, list) { | ||
7664 | if (dd->deviceid != PCI_DEVICE_ID_QLOGIC_IB_7322 | ||
7665 | || !IS_QMH(dd)) | ||
7666 | continue; /* only for QMH cards */ | ||
7667 | if (dd->pcidev->bus->number == bus) { | ||
7668 | found++; | ||
7669 | ppd = &dd->pport[port - 1]; | ||
7670 | } | ||
7671 | } | ||
7672 | } else if (ppd) { | ||
7673 | u32 parm = (nf % N_QMH_FIELDS) - 2; | ||
7674 | if (parm < SERDES_CHANS && !(parm % SERDES_CHANS)) | ||
7675 | ppd->cpspec->h1_val = val; | ||
7676 | else if (parm < (2 * SERDES_CHANS)) | ||
7677 | ppd->cpspec->amp[parm % SERDES_CHANS] = val; | ||
7678 | else if (parm < (3 * SERDES_CHANS)) | ||
7679 | ppd->cpspec->pre[parm % SERDES_CHANS] = val; | ||
7680 | else if (parm < (4 * SERDES_CHANS)) | ||
7681 | ppd->cpspec->post[parm % SERDES_CHANS] = val; | ||
7682 | else { | ||
7683 | ppd->cpspec->mainv[parm % SERDES_CHANS] = val; | ||
7684 | /* At the end of a port, set params */ | ||
7685 | if (parm == ((5 * SERDES_CHANS) - 1)) | ||
7686 | adj_tx_serdes(ppd); | ||
7687 | } | ||
7688 | } | ||
7689 | nf++; | ||
7690 | } | ||
7691 | if (!found) { | ||
7692 | printk(KERN_ERR QIB_DRV_NAME | ||
7693 | ": No match found for qmh_serdes_setup parameter\n"); | ||
7694 | ret = -EINVAL; | ||
7695 | } | ||
7696 | bail: | ||
7697 | kfree(abuf); | ||
7698 | return ret; | ||
7699 | } | ||
7700 | |||
7701 | /* | ||
7702 | * Similarly for QME7342, but the format is simpler, values are the | ||
7703 | * same for all mez card positions in a blade (2 or 4 per blade), but | ||
7704 | * are different for some blades vs others, and we don't need to | ||
7705 | * specify different parameters for different serdes channels or different | ||
7706 | * IB ports. | ||
7707 | * Format is: h1 amp,pre,post,main | ||
7708 | * Alternate format (so ports can be different): Pport# h1 amp,pre,post,main | ||
7709 | */ | ||
7710 | #define N_QME_FIELDS 5 | ||
7711 | static int setup_qme_params(const char *str, struct kernel_param *kp) | ||
7712 | { | ||
7713 | char *abuf, *v, *nv, *nvp; | ||
7714 | struct qib_devdata *dd; | ||
7715 | u32 vlen, nf, port = 0; | ||
7716 | u8 h1, tx[4]; /* amp, pre, post, main */ | ||
7717 | int ret = -EINVAL; | ||
7718 | char *seplist; | ||
7719 | |||
7720 | vlen = strlen(str) + 1; | ||
7721 | abuf = kmalloc(vlen, GFP_KERNEL); | ||
7722 | if (!abuf) { | ||
7723 | printk(KERN_INFO QIB_DRV_NAME | ||
7724 | " Unable to allocate QME param buffer; ignoring\n"); | ||
7725 | return 0; | ||
7726 | } | ||
7727 | strncpy(abuf, str, vlen); | ||
7728 | |||
7729 | v = abuf; | ||
7730 | seplist = " \t"; | ||
7731 | h1 = H1_FORCE_QME; /* gcc can't figure out always set before used */ | ||
7732 | |||
7733 | for (nf = 0; (nv = strsep(&v, seplist)); ) { | ||
7734 | u32 val; | ||
7735 | |||
7736 | if (!*nv) | ||
7737 | /* allow for multiple separators */ | ||
7738 | continue; | ||
7739 | |||
7740 | if (!nf && *nv == 'P') { | ||
7741 | /* alternate format with port */ | ||
7742 | val = simple_strtoul(++nv, &nvp, 0); | ||
7743 | if (nv == nvp || port >= NUM_IB_PORTS) { | ||
7744 | printk(KERN_INFO QIB_DRV_NAME | ||
7745 | " %s: non-numeric port value (%s) " | ||
7746 | "ignoring rest\n", __func__, nv); | ||
7747 | goto done; | ||
7748 | } | ||
7749 | port = val; | ||
7750 | continue; /* without incrementing nf */ | ||
7751 | } | ||
7752 | val = simple_strtoul(nv, &nvp, 0); | ||
7753 | if (nv == nvp) { | ||
7754 | printk(KERN_INFO QIB_DRV_NAME | ||
7755 | " %s: non-numeric value (%s) " | ||
7756 | "field #%u, ignoring rest\n", __func__, | ||
7757 | nv, nf); | ||
7758 | goto done; | ||
7759 | } | ||
7760 | if (!nf) { | ||
7761 | h1 = val; | ||
7762 | seplist = ","; | ||
7763 | } else | ||
7764 | tx[nf - 1] = val; | ||
7765 | if (++nf == N_QME_FIELDS) { | ||
7766 | list_for_each_entry(dd, &qib_dev_list, list) { | ||
7767 | int pidx, i; | ||
7768 | if (dd->deviceid != PCI_DEVICE_ID_QLOGIC_IB_7322 | ||
7769 | || !IS_QME(dd)) | ||
7770 | continue; /* only for QME cards */ | ||
7771 | for (pidx = 0; pidx < dd->num_pports; ++pidx) { | ||
7772 | struct qib_pportdata *ppd; | ||
7773 | ppd = &dd->pport[pidx]; | ||
7774 | if ((port && ppd->port != port) || | ||
7775 | !ppd->link_speed_supported) | ||
7776 | continue; | ||
7777 | ppd->cpspec->h1_val = h1; | ||
7778 | for (i = 0; i < SERDES_CHANS; i++) { | ||
7779 | ppd->cpspec->amp[i] = tx[0]; | ||
7780 | ppd->cpspec->pre[i] = tx[1]; | ||
7781 | ppd->cpspec->post[i] = tx[2]; | ||
7782 | ppd->cpspec->mainv[i] = tx[3]; | ||
7783 | } | ||
7784 | adj_tx_serdes(ppd); | ||
7785 | } | ||
7786 | } | ||
7787 | ret = 0; | ||
7788 | goto done; | ||
7789 | } | ||
7790 | } | ||
7791 | printk(KERN_INFO QIB_DRV_NAME | ||
7792 | " %s: Only %u of %u fields provided, skipping\n", | ||
7793 | __func__, nf, N_QME_FIELDS); | ||
7794 | done: | ||
7795 | kfree(abuf); | ||
7796 | return ret; | ||
7797 | } | ||
7798 | |||
7799 | #define SJA_EN SYM_MASK(SPC_JTAG_ACCESS_REG, SPC_JTAG_ACCESS_EN) | 7386 | #define SJA_EN SYM_MASK(SPC_JTAG_ACCESS_REG, SPC_JTAG_ACCESS_EN) |
7800 | #define BISTEN_LSB SYM_LSB(SPC_JTAG_ACCESS_REG, bist_en) | 7387 | #define BISTEN_LSB SYM_LSB(SPC_JTAG_ACCESS_REG, bist_en) |
7801 | 7388 | ||
diff --git a/drivers/infiniband/hw/qib/qib_init.c b/drivers/infiniband/hw/qib/qib_init.c index c0139c07e97e..9b40f345ac3f 100644 --- a/drivers/infiniband/hw/qib/qib_init.c +++ b/drivers/infiniband/hw/qib/qib_init.c | |||
@@ -1237,7 +1237,13 @@ static int __devinit qib_init_one(struct pci_dev *pdev, | |||
1237 | */ | 1237 | */ |
1238 | switch (ent->device) { | 1238 | switch (ent->device) { |
1239 | case PCI_DEVICE_ID_QLOGIC_IB_6120: | 1239 | case PCI_DEVICE_ID_QLOGIC_IB_6120: |
1240 | #ifdef CONFIG_PCI_MSI | ||
1240 | dd = qib_init_iba6120_funcs(pdev, ent); | 1241 | dd = qib_init_iba6120_funcs(pdev, ent); |
1242 | #else | ||
1243 | qib_early_err(&pdev->dev, "QLogic PCIE device 0x%x cannot " | ||
1244 | "work if CONFIG_PCI_MSI is not enabled\n", | ||
1245 | ent->device); | ||
1246 | #endif | ||
1241 | break; | 1247 | break; |
1242 | 1248 | ||
1243 | case PCI_DEVICE_ID_QLOGIC_IB_7220: | 1249 | case PCI_DEVICE_ID_QLOGIC_IB_7220: |
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index f98d17a7108b..81bf25e67ce1 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig | |||
@@ -21,7 +21,7 @@ comment "LED drivers" | |||
21 | 21 | ||
22 | config LEDS_88PM860X | 22 | config LEDS_88PM860X |
23 | tristate "LED Support for Marvell 88PM860x PMIC" | 23 | tristate "LED Support for Marvell 88PM860x PMIC" |
24 | depends on LEDS_CLASS && MFD_88PM860X | 24 | depends on MFD_88PM860X |
25 | help | 25 | help |
26 | This option enables support for on-chip LED drivers found on Marvell | 26 | This option enables support for on-chip LED drivers found on Marvell |
27 | Semiconductor 88PM8606 PMIC. | 27 | Semiconductor 88PM8606 PMIC. |
@@ -69,8 +69,8 @@ config LEDS_NET48XX | |||
69 | 69 | ||
70 | config LEDS_NET5501 | 70 | config LEDS_NET5501 |
71 | tristate "LED Support for Soekris net5501 series Error LED" | 71 | tristate "LED Support for Soekris net5501 series Error LED" |
72 | depends on LEDS_CLASS && LEDS_TRIGGERS | 72 | depends on LEDS_TRIGGERS |
73 | depends on LEDS_GPIO_PLATFORM && GPIO_CS5535 | 73 | depends on X86 && LEDS_GPIO_PLATFORM && GPIO_CS5535 |
74 | select LEDS_TRIGGER_DEFAULT_ON | 74 | select LEDS_TRIGGER_DEFAULT_ON |
75 | default n | 75 | default n |
76 | help | 76 | help |
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index 26843dd6b859..cc22eeefa10b 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c | |||
@@ -250,7 +250,6 @@ static int __devinit of_gpio_leds_probe(struct of_device *ofdev, | |||
250 | led.gpio = of_get_gpio_flags(child, 0, &flags); | 250 | led.gpio = of_get_gpio_flags(child, 0, &flags); |
251 | led.active_low = flags & OF_GPIO_ACTIVE_LOW; | 251 | led.active_low = flags & OF_GPIO_ACTIVE_LOW; |
252 | led.name = of_get_property(child, "label", NULL) ? : child->name; | 252 | led.name = of_get_property(child, "label", NULL) ? : child->name; |
253 | led.blinking = 0; | ||
254 | led.default_trigger = | 253 | led.default_trigger = |
255 | of_get_property(child, "linux,default-trigger", NULL); | 254 | of_get_property(child, "linux,default-trigger", NULL); |
256 | state = of_get_property(child, "default-state", NULL); | 255 | state = of_get_property(child, "default-state", NULL); |
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index 72ebb3f06b86..4dfa6b90c21c 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c | |||
@@ -189,8 +189,7 @@ static loff_t vol_cdev_llseek(struct file *file, loff_t offset, int origin) | |||
189 | return new_offset; | 189 | return new_offset; |
190 | } | 190 | } |
191 | 191 | ||
192 | static int vol_cdev_fsync(struct file *file, struct dentry *dentry, | 192 | static int vol_cdev_fsync(struct file *file, int datasync) |
193 | int datasync) | ||
194 | { | 193 | { |
195 | struct ubi_volume_desc *desc = file->private_data; | 194 | struct ubi_volume_desc *desc = file->private_data; |
196 | struct ubi_device *ubi = desc->vol->ubi; | 195 | struct ubi_device *ubi = desc->vol->ubi; |
diff --git a/drivers/net/3c507.c b/drivers/net/3c507.c index 82eaf65d2d85..ea9b7a098c9b 100644 --- a/drivers/net/3c507.c +++ b/drivers/net/3c507.c | |||
@@ -551,8 +551,7 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id) | |||
551 | void __iomem *shmem; | 551 | void __iomem *shmem; |
552 | 552 | ||
553 | if (dev == NULL) { | 553 | if (dev == NULL) { |
554 | pr_err("%s: net_interrupt(): irq %d for unknown device.\n", | 554 | pr_err("net_interrupt(): irq %d for unknown device.\n", irq); |
555 | dev->name, irq); | ||
556 | return IRQ_NONE; | 555 | return IRQ_NONE; |
557 | } | 556 | } |
558 | 557 | ||
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index c911bfb55b19..9d11dbf5e4da 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c | |||
@@ -294,7 +294,7 @@ int be_cmd_POST(struct be_adapter *adapter) | |||
294 | } else { | 294 | } else { |
295 | return 0; | 295 | return 0; |
296 | } | 296 | } |
297 | } while (timeout < 20); | 297 | } while (timeout < 40); |
298 | 298 | ||
299 | dev_err(&adapter->pdev->dev, "POST timeout; stage=0x%x\n", stage); | 299 | dev_err(&adapter->pdev->dev, "POST timeout; stage=0x%x\n", stage); |
300 | return -1; | 300 | return -1; |
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index aa065c71ddd8..54b14272f333 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c | |||
@@ -1861,7 +1861,7 @@ static int be_setup(struct be_adapter *adapter) | |||
1861 | goto if_destroy; | 1861 | goto if_destroy; |
1862 | } | 1862 | } |
1863 | vf++; | 1863 | vf++; |
1864 | } while (vf < num_vfs); | 1864 | } |
1865 | } else if (!be_physfn(adapter)) { | 1865 | } else if (!be_physfn(adapter)) { |
1866 | status = be_cmd_mac_addr_query(adapter, mac, | 1866 | status = be_cmd_mac_addr_query(adapter, mac, |
1867 | MAC_ADDRESS_TYPE_NETWORK, false, adapter->if_handle); | 1867 | MAC_ADDRESS_TYPE_NETWORK, false, adapter->if_handle); |
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index be90d3598bca..fe925663d39a 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c | |||
@@ -3367,13 +3367,9 @@ static int cnic_cm_shutdown(struct cnic_dev *dev) | |||
3367 | 3367 | ||
3368 | static void cnic_init_context(struct cnic_dev *dev, u32 cid) | 3368 | static void cnic_init_context(struct cnic_dev *dev, u32 cid) |
3369 | { | 3369 | { |
3370 | struct cnic_local *cp = dev->cnic_priv; | ||
3371 | u32 cid_addr; | 3370 | u32 cid_addr; |
3372 | int i; | 3371 | int i; |
3373 | 3372 | ||
3374 | if (CHIP_NUM(cp) == CHIP_NUM_5709) | ||
3375 | return; | ||
3376 | |||
3377 | cid_addr = GET_CID_ADDR(cid); | 3373 | cid_addr = GET_CID_ADDR(cid); |
3378 | 3374 | ||
3379 | for (i = 0; i < CTX_SIZE; i += 4) | 3375 | for (i = 0; i < CTX_SIZE; i += 4) |
@@ -3530,14 +3526,11 @@ static void cnic_init_bnx2_tx_ring(struct cnic_dev *dev) | |||
3530 | 3526 | ||
3531 | sb_id = cp->status_blk_num; | 3527 | sb_id = cp->status_blk_num; |
3532 | tx_cid = 20; | 3528 | tx_cid = 20; |
3533 | cnic_init_context(dev, tx_cid); | ||
3534 | cnic_init_context(dev, tx_cid + 1); | ||
3535 | cp->tx_cons_ptr = &s_blk->status_tx_quick_consumer_index2; | 3529 | cp->tx_cons_ptr = &s_blk->status_tx_quick_consumer_index2; |
3536 | if (ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX) { | 3530 | if (ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX) { |
3537 | struct status_block_msix *sblk = cp->status_blk.bnx2; | 3531 | struct status_block_msix *sblk = cp->status_blk.bnx2; |
3538 | 3532 | ||
3539 | tx_cid = TX_TSS_CID + sb_id - 1; | 3533 | tx_cid = TX_TSS_CID + sb_id - 1; |
3540 | cnic_init_context(dev, tx_cid); | ||
3541 | CNIC_WR(dev, BNX2_TSCH_TSS_CFG, (sb_id << 24) | | 3534 | CNIC_WR(dev, BNX2_TSCH_TSS_CFG, (sb_id << 24) | |
3542 | (TX_TSS_CID << 7)); | 3535 | (TX_TSS_CID << 7)); |
3543 | cp->tx_cons_ptr = &sblk->status_tx_quick_consumer_index; | 3536 | cp->tx_cons_ptr = &sblk->status_tx_quick_consumer_index; |
@@ -3556,6 +3549,9 @@ static void cnic_init_bnx2_tx_ring(struct cnic_dev *dev) | |||
3556 | offset2 = BNX2_L2CTX_TBDR_BHADDR_HI_XI; | 3549 | offset2 = BNX2_L2CTX_TBDR_BHADDR_HI_XI; |
3557 | offset3 = BNX2_L2CTX_TBDR_BHADDR_LO_XI; | 3550 | offset3 = BNX2_L2CTX_TBDR_BHADDR_LO_XI; |
3558 | } else { | 3551 | } else { |
3552 | cnic_init_context(dev, tx_cid); | ||
3553 | cnic_init_context(dev, tx_cid + 1); | ||
3554 | |||
3559 | offset0 = BNX2_L2CTX_TYPE; | 3555 | offset0 = BNX2_L2CTX_TYPE; |
3560 | offset1 = BNX2_L2CTX_CMD_TYPE; | 3556 | offset1 = BNX2_L2CTX_CMD_TYPE; |
3561 | offset2 = BNX2_L2CTX_TBDR_BHADDR_HI; | 3557 | offset2 = BNX2_L2CTX_TBDR_BHADDR_HI; |
diff --git a/drivers/net/cnic_if.h b/drivers/net/cnic_if.h index 110c62072e6f..0c55177db046 100644 --- a/drivers/net/cnic_if.h +++ b/drivers/net/cnic_if.h | |||
@@ -12,8 +12,8 @@ | |||
12 | #ifndef CNIC_IF_H | 12 | #ifndef CNIC_IF_H |
13 | #define CNIC_IF_H | 13 | #define CNIC_IF_H |
14 | 14 | ||
15 | #define CNIC_MODULE_VERSION "2.1.1" | 15 | #define CNIC_MODULE_VERSION "2.1.2" |
16 | #define CNIC_MODULE_RELDATE "Feb 22, 2010" | 16 | #define CNIC_MODULE_RELDATE "May 26, 2010" |
17 | 17 | ||
18 | #define CNIC_ULP_RDMA 0 | 18 | #define CNIC_ULP_RDMA 0 |
19 | #define CNIC_ULP_ISCSI 1 | 19 | #define CNIC_ULP_ISCSI 1 |
diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 326465ffbb23..ddf7a86cd466 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c | |||
@@ -681,6 +681,8 @@ static int fec_enet_mii_probe(struct net_device *dev) | |||
681 | struct phy_device *phy_dev = NULL; | 681 | struct phy_device *phy_dev = NULL; |
682 | int phy_addr; | 682 | int phy_addr; |
683 | 683 | ||
684 | fep->phy_dev = NULL; | ||
685 | |||
684 | /* find the first phy */ | 686 | /* find the first phy */ |
685 | for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { | 687 | for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { |
686 | if (fep->mii_bus->phy_map[phy_addr]) { | 688 | if (fep->mii_bus->phy_map[phy_addr]) { |
@@ -711,6 +713,11 @@ static int fec_enet_mii_probe(struct net_device *dev) | |||
711 | fep->link = 0; | 713 | fep->link = 0; |
712 | fep->full_duplex = 0; | 714 | fep->full_duplex = 0; |
713 | 715 | ||
716 | printk(KERN_INFO "%s: Freescale FEC PHY driver [%s] " | ||
717 | "(mii_bus:phy_addr=%s, irq=%d)\n", dev->name, | ||
718 | fep->phy_dev->drv->name, dev_name(&fep->phy_dev->dev), | ||
719 | fep->phy_dev->irq); | ||
720 | |||
714 | return 0; | 721 | return 0; |
715 | } | 722 | } |
716 | 723 | ||
@@ -756,13 +763,8 @@ static int fec_enet_mii_init(struct platform_device *pdev) | |||
756 | if (mdiobus_register(fep->mii_bus)) | 763 | if (mdiobus_register(fep->mii_bus)) |
757 | goto err_out_free_mdio_irq; | 764 | goto err_out_free_mdio_irq; |
758 | 765 | ||
759 | if (fec_enet_mii_probe(dev) != 0) | ||
760 | goto err_out_unregister_bus; | ||
761 | |||
762 | return 0; | 766 | return 0; |
763 | 767 | ||
764 | err_out_unregister_bus: | ||
765 | mdiobus_unregister(fep->mii_bus); | ||
766 | err_out_free_mdio_irq: | 768 | err_out_free_mdio_irq: |
767 | kfree(fep->mii_bus->irq); | 769 | kfree(fep->mii_bus->irq); |
768 | err_out_free_mdiobus: | 770 | err_out_free_mdiobus: |
@@ -915,7 +917,12 @@ fec_enet_open(struct net_device *dev) | |||
915 | if (ret) | 917 | if (ret) |
916 | return ret; | 918 | return ret; |
917 | 919 | ||
918 | /* schedule a link state check */ | 920 | /* Probe and connect to PHY when open the interface */ |
921 | ret = fec_enet_mii_probe(dev); | ||
922 | if (ret) { | ||
923 | fec_enet_free_buffers(dev); | ||
924 | return ret; | ||
925 | } | ||
919 | phy_start(fep->phy_dev); | 926 | phy_start(fep->phy_dev); |
920 | netif_start_queue(dev); | 927 | netif_start_queue(dev); |
921 | fep->opened = 1; | 928 | fep->opened = 1; |
@@ -929,10 +936,12 @@ fec_enet_close(struct net_device *dev) | |||
929 | 936 | ||
930 | /* Don't know what to do yet. */ | 937 | /* Don't know what to do yet. */ |
931 | fep->opened = 0; | 938 | fep->opened = 0; |
932 | phy_stop(fep->phy_dev); | ||
933 | netif_stop_queue(dev); | 939 | netif_stop_queue(dev); |
934 | fec_stop(dev); | 940 | fec_stop(dev); |
935 | 941 | ||
942 | if (fep->phy_dev) | ||
943 | phy_disconnect(fep->phy_dev); | ||
944 | |||
936 | fec_enet_free_buffers(dev); | 945 | fec_enet_free_buffers(dev); |
937 | 946 | ||
938 | return 0; | 947 | return 0; |
@@ -1316,11 +1325,6 @@ fec_probe(struct platform_device *pdev) | |||
1316 | if (ret) | 1325 | if (ret) |
1317 | goto failed_register; | 1326 | goto failed_register; |
1318 | 1327 | ||
1319 | printk(KERN_INFO "%s: Freescale FEC PHY driver [%s] " | ||
1320 | "(mii_bus:phy_addr=%s, irq=%d)\n", ndev->name, | ||
1321 | fep->phy_dev->drv->name, dev_name(&fep->phy_dev->dev), | ||
1322 | fep->phy_dev->irq); | ||
1323 | |||
1324 | return 0; | 1328 | return 0; |
1325 | 1329 | ||
1326 | failed_register: | 1330 | failed_register: |
diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c index 694132e04af6..4e7d1d0a2340 100644 --- a/drivers/net/hamradio/yam.c +++ b/drivers/net/hamradio/yam.c | |||
@@ -1151,8 +1151,7 @@ static int __init yam_init_driver(void) | |||
1151 | dev = alloc_netdev(sizeof(struct yam_port), name, | 1151 | dev = alloc_netdev(sizeof(struct yam_port), name, |
1152 | yam_setup); | 1152 | yam_setup); |
1153 | if (!dev) { | 1153 | if (!dev) { |
1154 | printk(KERN_ERR "yam: cannot allocate net device %s\n", | 1154 | pr_err("yam: cannot allocate net device\n"); |
1155 | dev->name); | ||
1156 | err = -ENOMEM; | 1155 | err = -ENOMEM; |
1157 | goto error; | 1156 | goto error; |
1158 | } | 1157 | } |
diff --git a/drivers/net/ll_temac.h b/drivers/net/ll_temac.h index c03358434acb..522abe2ff25a 100644 --- a/drivers/net/ll_temac.h +++ b/drivers/net/ll_temac.h | |||
@@ -295,6 +295,10 @@ This option defaults to enabled (set) */ | |||
295 | 295 | ||
296 | #define MULTICAST_CAM_TABLE_NUM 4 | 296 | #define MULTICAST_CAM_TABLE_NUM 4 |
297 | 297 | ||
298 | /* TEMAC Synthesis features */ | ||
299 | #define TEMAC_FEATURE_RX_CSUM (1 << 0) | ||
300 | #define TEMAC_FEATURE_TX_CSUM (1 << 1) | ||
301 | |||
298 | /* TX/RX CURDESC_PTR points to first descriptor */ | 302 | /* TX/RX CURDESC_PTR points to first descriptor */ |
299 | /* TX/RX TAILDESC_PTR points to last descriptor in linked list */ | 303 | /* TX/RX TAILDESC_PTR points to last descriptor in linked list */ |
300 | 304 | ||
@@ -353,6 +357,7 @@ struct temac_local { | |||
353 | struct mutex indirect_mutex; | 357 | struct mutex indirect_mutex; |
354 | u32 options; /* Current options word */ | 358 | u32 options; /* Current options word */ |
355 | int last_link; | 359 | int last_link; |
360 | unsigned int temac_features; | ||
356 | 361 | ||
357 | /* Buffer descriptors */ | 362 | /* Buffer descriptors */ |
358 | struct cdmac_bd *tx_bd_v; | 363 | struct cdmac_bd *tx_bd_v; |
diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c index fa7620e28404..52dcc8495647 100644 --- a/drivers/net/ll_temac_main.c +++ b/drivers/net/ll_temac_main.c | |||
@@ -245,7 +245,7 @@ static int temac_dma_bd_init(struct net_device *ndev) | |||
245 | CHNL_CTRL_IRQ_COAL_EN); | 245 | CHNL_CTRL_IRQ_COAL_EN); |
246 | /* 0x10220483 */ | 246 | /* 0x10220483 */ |
247 | /* 0x00100483 */ | 247 | /* 0x00100483 */ |
248 | lp->dma_out(lp, RX_CHNL_CTRL, 0xff010000 | | 248 | lp->dma_out(lp, RX_CHNL_CTRL, 0xff070000 | |
249 | CHNL_CTRL_IRQ_EN | | 249 | CHNL_CTRL_IRQ_EN | |
250 | CHNL_CTRL_IRQ_DLY_EN | | 250 | CHNL_CTRL_IRQ_DLY_EN | |
251 | CHNL_CTRL_IRQ_COAL_EN | | 251 | CHNL_CTRL_IRQ_COAL_EN | |
@@ -574,6 +574,10 @@ static void temac_start_xmit_done(struct net_device *ndev) | |||
574 | if (cur_p->app4) | 574 | if (cur_p->app4) |
575 | dev_kfree_skb_irq((struct sk_buff *)cur_p->app4); | 575 | dev_kfree_skb_irq((struct sk_buff *)cur_p->app4); |
576 | cur_p->app0 = 0; | 576 | cur_p->app0 = 0; |
577 | cur_p->app1 = 0; | ||
578 | cur_p->app2 = 0; | ||
579 | cur_p->app3 = 0; | ||
580 | cur_p->app4 = 0; | ||
577 | 581 | ||
578 | ndev->stats.tx_packets++; | 582 | ndev->stats.tx_packets++; |
579 | ndev->stats.tx_bytes += cur_p->len; | 583 | ndev->stats.tx_bytes += cur_p->len; |
@@ -589,6 +593,29 @@ static void temac_start_xmit_done(struct net_device *ndev) | |||
589 | netif_wake_queue(ndev); | 593 | netif_wake_queue(ndev); |
590 | } | 594 | } |
591 | 595 | ||
596 | static inline int temac_check_tx_bd_space(struct temac_local *lp, int num_frag) | ||
597 | { | ||
598 | struct cdmac_bd *cur_p; | ||
599 | int tail; | ||
600 | |||
601 | tail = lp->tx_bd_tail; | ||
602 | cur_p = &lp->tx_bd_v[tail]; | ||
603 | |||
604 | do { | ||
605 | if (cur_p->app0) | ||
606 | return NETDEV_TX_BUSY; | ||
607 | |||
608 | tail++; | ||
609 | if (tail >= TX_BD_NUM) | ||
610 | tail = 0; | ||
611 | |||
612 | cur_p = &lp->tx_bd_v[tail]; | ||
613 | num_frag--; | ||
614 | } while (num_frag >= 0); | ||
615 | |||
616 | return 0; | ||
617 | } | ||
618 | |||
592 | static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) | 619 | static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) |
593 | { | 620 | { |
594 | struct temac_local *lp = netdev_priv(ndev); | 621 | struct temac_local *lp = netdev_priv(ndev); |
@@ -603,7 +630,7 @@ static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
603 | start_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail; | 630 | start_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail; |
604 | cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; | 631 | cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; |
605 | 632 | ||
606 | if (cur_p->app0 & STS_CTRL_APP0_CMPLT) { | 633 | if (temac_check_tx_bd_space(lp, num_frag)) { |
607 | if (!netif_queue_stopped(ndev)) { | 634 | if (!netif_queue_stopped(ndev)) { |
608 | netif_stop_queue(ndev); | 635 | netif_stop_queue(ndev); |
609 | return NETDEV_TX_BUSY; | 636 | return NETDEV_TX_BUSY; |
@@ -613,29 +640,14 @@ static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
613 | 640 | ||
614 | cur_p->app0 = 0; | 641 | cur_p->app0 = 0; |
615 | if (skb->ip_summed == CHECKSUM_PARTIAL) { | 642 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
616 | const struct iphdr *ip = ip_hdr(skb); | 643 | unsigned int csum_start_off = skb_transport_offset(skb); |
617 | int length = 0, start = 0, insert = 0; | 644 | unsigned int csum_index_off = csum_start_off + skb->csum_offset; |
618 | 645 | ||
619 | switch (ip->protocol) { | 646 | cur_p->app0 |= 1; /* TX Checksum Enabled */ |
620 | case IPPROTO_TCP: | 647 | cur_p->app1 = (csum_start_off << 16) | csum_index_off; |
621 | start = sizeof(struct iphdr) + ETH_HLEN; | 648 | cur_p->app2 = 0; /* initial checksum seed */ |
622 | insert = sizeof(struct iphdr) + ETH_HLEN + 16; | ||
623 | length = ip->tot_len - sizeof(struct iphdr); | ||
624 | break; | ||
625 | case IPPROTO_UDP: | ||
626 | start = sizeof(struct iphdr) + ETH_HLEN; | ||
627 | insert = sizeof(struct iphdr) + ETH_HLEN + 6; | ||
628 | length = ip->tot_len - sizeof(struct iphdr); | ||
629 | break; | ||
630 | default: | ||
631 | break; | ||
632 | } | ||
633 | cur_p->app1 = ((start << 16) | insert); | ||
634 | cur_p->app2 = csum_tcpudp_magic(ip->saddr, ip->daddr, | ||
635 | length, ip->protocol, 0); | ||
636 | skb->data[insert] = 0; | ||
637 | skb->data[insert + 1] = 0; | ||
638 | } | 649 | } |
650 | |||
639 | cur_p->app0 |= STS_CTRL_APP0_SOP; | 651 | cur_p->app0 |= STS_CTRL_APP0_SOP; |
640 | cur_p->len = skb_headlen(skb); | 652 | cur_p->len = skb_headlen(skb); |
641 | cur_p->phys = dma_map_single(ndev->dev.parent, skb->data, skb->len, | 653 | cur_p->phys = dma_map_single(ndev->dev.parent, skb->data, skb->len, |
@@ -699,6 +711,15 @@ static void ll_temac_recv(struct net_device *ndev) | |||
699 | skb->protocol = eth_type_trans(skb, ndev); | 711 | skb->protocol = eth_type_trans(skb, ndev); |
700 | skb->ip_summed = CHECKSUM_NONE; | 712 | skb->ip_summed = CHECKSUM_NONE; |
701 | 713 | ||
714 | /* if we're doing rx csum offload, set it up */ | ||
715 | if (((lp->temac_features & TEMAC_FEATURE_RX_CSUM) != 0) && | ||
716 | (skb->protocol == __constant_htons(ETH_P_IP)) && | ||
717 | (skb->len > 64)) { | ||
718 | |||
719 | skb->csum = cur_p->app3 & 0xFFFF; | ||
720 | skb->ip_summed = CHECKSUM_COMPLETE; | ||
721 | } | ||
722 | |||
702 | netif_rx(skb); | 723 | netif_rx(skb); |
703 | 724 | ||
704 | ndev->stats.rx_packets++; | 725 | ndev->stats.rx_packets++; |
@@ -883,6 +904,7 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match) | |||
883 | struct temac_local *lp; | 904 | struct temac_local *lp; |
884 | struct net_device *ndev; | 905 | struct net_device *ndev; |
885 | const void *addr; | 906 | const void *addr; |
907 | __be32 *p; | ||
886 | int size, rc = 0; | 908 | int size, rc = 0; |
887 | 909 | ||
888 | /* Init network device structure */ | 910 | /* Init network device structure */ |
@@ -926,6 +948,18 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match) | |||
926 | goto nodev; | 948 | goto nodev; |
927 | } | 949 | } |
928 | 950 | ||
951 | /* Setup checksum offload, but default to off if not specified */ | ||
952 | lp->temac_features = 0; | ||
953 | p = (__be32 *)of_get_property(op->dev.of_node, "xlnx,txcsum", NULL); | ||
954 | if (p && be32_to_cpu(*p)) { | ||
955 | lp->temac_features |= TEMAC_FEATURE_TX_CSUM; | ||
956 | /* Can checksum TCP/UDP over IPv4. */ | ||
957 | ndev->features |= NETIF_F_IP_CSUM; | ||
958 | } | ||
959 | p = (__be32 *)of_get_property(op->dev.of_node, "xlnx,rxcsum", NULL); | ||
960 | if (p && be32_to_cpu(*p)) | ||
961 | lp->temac_features |= TEMAC_FEATURE_RX_CSUM; | ||
962 | |||
929 | /* Find the DMA node, map the DMA registers, and decode the DMA IRQs */ | 963 | /* Find the DMA node, map the DMA registers, and decode the DMA IRQs */ |
930 | np = of_parse_phandle(op->dev.of_node, "llink-connected", 0); | 964 | np = of_parse_phandle(op->dev.of_node, "llink-connected", 0); |
931 | if (!np) { | 965 | if (!np) { |
@@ -950,7 +984,7 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match) | |||
950 | 984 | ||
951 | lp->rx_irq = irq_of_parse_and_map(np, 0); | 985 | lp->rx_irq = irq_of_parse_and_map(np, 0); |
952 | lp->tx_irq = irq_of_parse_and_map(np, 1); | 986 | lp->tx_irq = irq_of_parse_and_map(np, 1); |
953 | if (!lp->rx_irq || !lp->tx_irq) { | 987 | if ((lp->rx_irq == NO_IRQ) || (lp->tx_irq == NO_IRQ)) { |
954 | dev_err(&op->dev, "could not determine irqs\n"); | 988 | dev_err(&op->dev, "could not determine irqs\n"); |
955 | rc = -ENOMEM; | 989 | rc = -ENOMEM; |
956 | goto nodev; | 990 | goto nodev; |
diff --git a/drivers/pci/pcie/aer/aerdrv.h b/drivers/pci/pcie/aer/aerdrv.h index 7aaae2d2bd67..80c11d131499 100644 --- a/drivers/pci/pcie/aer/aerdrv.h +++ b/drivers/pci/pcie/aer/aerdrv.h | |||
@@ -130,4 +130,21 @@ static inline int aer_osc_setup(struct pcie_device *pciedev) | |||
130 | } | 130 | } |
131 | #endif | 131 | #endif |
132 | 132 | ||
133 | #ifdef CONFIG_ACPI_APEI | ||
134 | extern int pcie_aer_get_firmware_first(struct pci_dev *pci_dev); | ||
135 | #else | ||
136 | static inline int pcie_aer_get_firmware_first(struct pci_dev *pci_dev) | ||
137 | { | ||
138 | if (pci_dev->__aer_firmware_first_valid) | ||
139 | return pci_dev->__aer_firmware_first; | ||
140 | return 0; | ||
141 | } | ||
142 | #endif | ||
143 | |||
144 | static inline void pcie_aer_force_firmware_first(struct pci_dev *pci_dev, | ||
145 | int enable) | ||
146 | { | ||
147 | pci_dev->__aer_firmware_first = !!enable; | ||
148 | pci_dev->__aer_firmware_first_valid = 1; | ||
149 | } | ||
133 | #endif /* _AERDRV_H_ */ | 150 | #endif /* _AERDRV_H_ */ |
diff --git a/drivers/pci/pcie/aer/aerdrv_acpi.c b/drivers/pci/pcie/aer/aerdrv_acpi.c index 04814087658d..f278d7b0d95d 100644 --- a/drivers/pci/pcie/aer/aerdrv_acpi.c +++ b/drivers/pci/pcie/aer/aerdrv_acpi.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/acpi.h> | 16 | #include <linux/acpi.h> |
17 | #include <linux/pci-acpi.h> | 17 | #include <linux/pci-acpi.h> |
18 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
19 | #include <acpi/apei.h> | ||
19 | #include "aerdrv.h" | 20 | #include "aerdrv.h" |
20 | 21 | ||
21 | /** | 22 | /** |
@@ -53,3 +54,79 @@ int aer_osc_setup(struct pcie_device *pciedev) | |||
53 | 54 | ||
54 | return 0; | 55 | return 0; |
55 | } | 56 | } |
57 | |||
58 | #ifdef CONFIG_ACPI_APEI | ||
59 | static inline int hest_match_pci(struct acpi_hest_aer_common *p, | ||
60 | struct pci_dev *pci) | ||
61 | { | ||
62 | return (0 == pci_domain_nr(pci->bus) && | ||
63 | p->bus == pci->bus->number && | ||
64 | p->device == PCI_SLOT(pci->devfn) && | ||
65 | p->function == PCI_FUNC(pci->devfn)); | ||
66 | } | ||
67 | |||
68 | struct aer_hest_parse_info { | ||
69 | struct pci_dev *pci_dev; | ||
70 | int firmware_first; | ||
71 | }; | ||
72 | |||
73 | static int aer_hest_parse(struct acpi_hest_header *hest_hdr, void *data) | ||
74 | { | ||
75 | struct aer_hest_parse_info *info = data; | ||
76 | struct acpi_hest_aer_common *p; | ||
77 | u8 pcie_type = 0; | ||
78 | u8 bridge = 0; | ||
79 | int ff = 0; | ||
80 | |||
81 | switch (hest_hdr->type) { | ||
82 | case ACPI_HEST_TYPE_AER_ROOT_PORT: | ||
83 | pcie_type = PCI_EXP_TYPE_ROOT_PORT; | ||
84 | break; | ||
85 | case ACPI_HEST_TYPE_AER_ENDPOINT: | ||
86 | pcie_type = PCI_EXP_TYPE_ENDPOINT; | ||
87 | break; | ||
88 | case ACPI_HEST_TYPE_AER_BRIDGE: | ||
89 | if ((info->pci_dev->class >> 16) == PCI_BASE_CLASS_BRIDGE) | ||
90 | bridge = 1; | ||
91 | break; | ||
92 | default: | ||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | p = (struct acpi_hest_aer_common *)(hest_hdr + 1); | ||
97 | if (p->flags & ACPI_HEST_GLOBAL) { | ||
98 | if ((info->pci_dev->is_pcie && | ||
99 | info->pci_dev->pcie_type == pcie_type) || bridge) | ||
100 | ff = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST); | ||
101 | } else | ||
102 | if (hest_match_pci(p, info->pci_dev)) | ||
103 | ff = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST); | ||
104 | info->firmware_first = ff; | ||
105 | |||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | static void aer_set_firmware_first(struct pci_dev *pci_dev) | ||
110 | { | ||
111 | int rc; | ||
112 | struct aer_hest_parse_info info = { | ||
113 | .pci_dev = pci_dev, | ||
114 | .firmware_first = 0, | ||
115 | }; | ||
116 | |||
117 | rc = apei_hest_parse(aer_hest_parse, &info); | ||
118 | |||
119 | if (rc) | ||
120 | pci_dev->__aer_firmware_first = 0; | ||
121 | else | ||
122 | pci_dev->__aer_firmware_first = info.firmware_first; | ||
123 | pci_dev->__aer_firmware_first_valid = 1; | ||
124 | } | ||
125 | |||
126 | int pcie_aer_get_firmware_first(struct pci_dev *dev) | ||
127 | { | ||
128 | if (!dev->__aer_firmware_first_valid) | ||
129 | aer_set_firmware_first(dev); | ||
130 | return dev->__aer_firmware_first; | ||
131 | } | ||
132 | #endif | ||
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index df2d686fe3dd..8af4f619bba2 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c | |||
@@ -36,7 +36,7 @@ int pci_enable_pcie_error_reporting(struct pci_dev *dev) | |||
36 | u16 reg16 = 0; | 36 | u16 reg16 = 0; |
37 | int pos; | 37 | int pos; |
38 | 38 | ||
39 | if (dev->aer_firmware_first) | 39 | if (pcie_aer_get_firmware_first(dev)) |
40 | return -EIO; | 40 | return -EIO; |
41 | 41 | ||
42 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); | 42 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); |
@@ -63,7 +63,7 @@ int pci_disable_pcie_error_reporting(struct pci_dev *dev) | |||
63 | u16 reg16 = 0; | 63 | u16 reg16 = 0; |
64 | int pos; | 64 | int pos; |
65 | 65 | ||
66 | if (dev->aer_firmware_first) | 66 | if (pcie_aer_get_firmware_first(dev)) |
67 | return -EIO; | 67 | return -EIO; |
68 | 68 | ||
69 | pos = pci_pcie_cap(dev); | 69 | pos = pci_pcie_cap(dev); |
@@ -771,7 +771,7 @@ void aer_isr(struct work_struct *work) | |||
771 | */ | 771 | */ |
772 | int aer_init(struct pcie_device *dev) | 772 | int aer_init(struct pcie_device *dev) |
773 | { | 773 | { |
774 | if (dev->port->aer_firmware_first) { | 774 | if (pcie_aer_get_firmware_first(dev->port)) { |
775 | dev_printk(KERN_DEBUG, &dev->device, | 775 | dev_printk(KERN_DEBUG, &dev->device, |
776 | "PCIe errors handled by platform firmware.\n"); | 776 | "PCIe errors handled by platform firmware.\n"); |
777 | goto out; | 777 | goto out; |
@@ -785,7 +785,7 @@ out: | |||
785 | if (forceload) { | 785 | if (forceload) { |
786 | dev_printk(KERN_DEBUG, &dev->device, | 786 | dev_printk(KERN_DEBUG, &dev->device, |
787 | "aerdrv forceload requested.\n"); | 787 | "aerdrv forceload requested.\n"); |
788 | dev->port->aer_firmware_first = 0; | 788 | pcie_aer_force_firmware_first(dev->port, 0); |
789 | return 0; | 789 | return 0; |
790 | } | 790 | } |
791 | return -ENXIO; | 791 | return -ENXIO; |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index c82548afcd5c..f4adba2d1dd3 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -10,7 +10,6 @@ | |||
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/cpumask.h> | 11 | #include <linux/cpumask.h> |
12 | #include <linux/pci-aspm.h> | 12 | #include <linux/pci-aspm.h> |
13 | #include <acpi/acpi_hest.h> | ||
14 | #include "pci.h" | 13 | #include "pci.h" |
15 | 14 | ||
16 | #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ | 15 | #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ |
@@ -904,12 +903,6 @@ void set_pcie_hotplug_bridge(struct pci_dev *pdev) | |||
904 | pdev->is_hotplug_bridge = 1; | 903 | pdev->is_hotplug_bridge = 1; |
905 | } | 904 | } |
906 | 905 | ||
907 | static void set_pci_aer_firmware_first(struct pci_dev *pdev) | ||
908 | { | ||
909 | if (acpi_hest_firmware_first_pci(pdev)) | ||
910 | pdev->aer_firmware_first = 1; | ||
911 | } | ||
912 | |||
913 | #define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED) | 906 | #define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED) |
914 | 907 | ||
915 | /** | 908 | /** |
@@ -939,7 +932,6 @@ int pci_setup_device(struct pci_dev *dev) | |||
939 | dev->multifunction = !!(hdr_type & 0x80); | 932 | dev->multifunction = !!(hdr_type & 0x80); |
940 | dev->error_state = pci_channel_io_normal; | 933 | dev->error_state = pci_channel_io_normal; |
941 | set_pcie_port_type(dev); | 934 | set_pcie_port_type(dev); |
942 | set_pci_aer_firmware_first(dev); | ||
943 | 935 | ||
944 | list_for_each_entry(slot, &dev->bus->slots, list) | 936 | list_for_each_entry(slot, &dev->bus->slots, list) |
945 | if (PCI_SLOT(dev->devfn) == slot->number) | 937 | if (PCI_SLOT(dev->devfn) == slot->number) |
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c index 566432106cc5..8070e074c739 100644 --- a/drivers/rapidio/rio-scan.c +++ b/drivers/rapidio/rio-scan.c | |||
@@ -1124,7 +1124,7 @@ static void rio_update_route_tables(struct rio_mport *port) | |||
1124 | 1124 | ||
1125 | /** | 1125 | /** |
1126 | * rio_init_em - Initializes RIO Error Management (for switches) | 1126 | * rio_init_em - Initializes RIO Error Management (for switches) |
1127 | * @port: Master port associated with the RIO network | 1127 | * @rdev: RIO device |
1128 | * | 1128 | * |
1129 | * For each enumerated switch, call device-specific error management | 1129 | * For each enumerated switch, call device-specific error management |
1130 | * initialization routine (if supplied by the switch driver). | 1130 | * initialization routine (if supplied by the switch driver). |
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c index 777e099a3d8f..08fa453af974 100644 --- a/drivers/rapidio/rio.c +++ b/drivers/rapidio/rio.c | |||
@@ -338,7 +338,7 @@ int rio_release_outb_dbell(struct rio_dev *rdev, struct resource *res) | |||
338 | 338 | ||
339 | /** | 339 | /** |
340 | * rio_request_inb_pwrite - request inbound port-write message service | 340 | * rio_request_inb_pwrite - request inbound port-write message service |
341 | * @mport: RIO device to which register inbound port-write callback routine | 341 | * @rdev: RIO device to which register inbound port-write callback routine |
342 | * @pwcback: Callback routine to execute when port-write is received | 342 | * @pwcback: Callback routine to execute when port-write is received |
343 | * | 343 | * |
344 | * Binds a port-write callback function to the RapidIO device. | 344 | * Binds a port-write callback function to the RapidIO device. |
@@ -385,7 +385,10 @@ EXPORT_SYMBOL_GPL(rio_release_inb_pwrite); | |||
385 | /** | 385 | /** |
386 | * rio_mport_get_physefb - Helper function that returns register offset | 386 | * rio_mport_get_physefb - Helper function that returns register offset |
387 | * for Physical Layer Extended Features Block. | 387 | * for Physical Layer Extended Features Block. |
388 | * @rdev: RIO device | 388 | * @port: Master port to issue transaction |
389 | * @local: Indicate a local master port or remote device access | ||
390 | * @destid: Destination ID of the device | ||
391 | * @hopcount: Number of switch hops to the device | ||
389 | */ | 392 | */ |
390 | u32 | 393 | u32 |
391 | rio_mport_get_physefb(struct rio_mport *port, int local, | 394 | rio_mport_get_physefb(struct rio_mport *port, int local, |
@@ -430,7 +433,7 @@ rio_mport_get_physefb(struct rio_mport *port, int local, | |||
430 | 433 | ||
431 | /** | 434 | /** |
432 | * rio_get_comptag - Begin or continue searching for a RIO device by component tag | 435 | * rio_get_comptag - Begin or continue searching for a RIO device by component tag |
433 | * @comp_tag: RIO component tad to match | 436 | * @comp_tag: RIO component tag to match |
434 | * @from: Previous RIO device found in search, or %NULL for new search | 437 | * @from: Previous RIO device found in search, or %NULL for new search |
435 | * | 438 | * |
436 | * Iterates through the list of known RIO devices. If a RIO device is | 439 | * Iterates through the list of known RIO devices. If a RIO device is |
@@ -835,7 +838,6 @@ int rio_std_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount, | |||
835 | * rio_std_route_clr_table - Clear swotch route table using standard registers | 838 | * rio_std_route_clr_table - Clear swotch route table using standard registers |
836 | * defined in RIO specification rev.1.3. | 839 | * defined in RIO specification rev.1.3. |
837 | * @mport: Master port to issue transaction | 840 | * @mport: Master port to issue transaction |
838 | * @local: Indicate a local master port or remote device access | ||
839 | * @destid: Destination ID of the device | 841 | * @destid: Destination ID of the device |
840 | * @hopcount: Number of switch hops to the device | 842 | * @hopcount: Number of switch hops to the device |
841 | * @table: routing table ID (global or port-specific) | 843 | * @table: routing table ID (global or port-specific) |
diff --git a/drivers/serial/s5pv210.c b/drivers/serial/s5pv210.c index 8dc03837617b..4a789e5361a4 100644 --- a/drivers/serial/s5pv210.c +++ b/drivers/serial/s5pv210.c | |||
@@ -119,7 +119,7 @@ static int s5p_serial_probe(struct platform_device *pdev) | |||
119 | return s3c24xx_serial_probe(pdev, s5p_uart_inf[pdev->id]); | 119 | return s3c24xx_serial_probe(pdev, s5p_uart_inf[pdev->id]); |
120 | } | 120 | } |
121 | 121 | ||
122 | static struct platform_driver s5p_serial_drv = { | 122 | static struct platform_driver s5p_serial_driver = { |
123 | .probe = s5p_serial_probe, | 123 | .probe = s5p_serial_probe, |
124 | .remove = __devexit_p(s3c24xx_serial_remove), | 124 | .remove = __devexit_p(s3c24xx_serial_remove), |
125 | .driver = { | 125 | .driver = { |
@@ -130,19 +130,19 @@ static struct platform_driver s5p_serial_drv = { | |||
130 | 130 | ||
131 | static int __init s5pv210_serial_console_init(void) | 131 | static int __init s5pv210_serial_console_init(void) |
132 | { | 132 | { |
133 | return s3c24xx_serial_initconsole(&s5p_serial_drv, s5p_uart_inf); | 133 | return s3c24xx_serial_initconsole(&s5p_serial_driver, s5p_uart_inf); |
134 | } | 134 | } |
135 | 135 | ||
136 | console_initcall(s5pv210_serial_console_init); | 136 | console_initcall(s5pv210_serial_console_init); |
137 | 137 | ||
138 | static int __init s5p_serial_init(void) | 138 | static int __init s5p_serial_init(void) |
139 | { | 139 | { |
140 | return s3c24xx_serial_init(&s5p_serial_drv, *s5p_uart_inf); | 140 | return s3c24xx_serial_init(&s5p_serial_driver, *s5p_uart_inf); |
141 | } | 141 | } |
142 | 142 | ||
143 | static void __exit s5p_serial_exit(void) | 143 | static void __exit s5p_serial_exit(void) |
144 | { | 144 | { |
145 | platform_driver_unregister(&s5p_serial_drv); | 145 | platform_driver_unregister(&s5p_serial_driver); |
146 | } | 146 | } |
147 | 147 | ||
148 | module_init(s5p_serial_init); | 148 | module_init(s5p_serial_init); |
diff --git a/drivers/staging/pohmelfs/inode.c b/drivers/staging/pohmelfs/inode.c index 9286e863b0e7..643b413d9f0f 100644 --- a/drivers/staging/pohmelfs/inode.c +++ b/drivers/staging/pohmelfs/inode.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/statfs.h> | 30 | #include <linux/statfs.h> |
31 | #include <linux/writeback.h> | 31 | #include <linux/writeback.h> |
32 | #include <linux/quotaops.h> | ||
33 | 32 | ||
34 | #include "netfs.h" | 33 | #include "netfs.h" |
35 | 34 | ||
@@ -880,7 +879,7 @@ static struct inode *pohmelfs_alloc_inode(struct super_block *sb) | |||
880 | /* | 879 | /* |
881 | * We want fsync() to work on POHMELFS. | 880 | * We want fsync() to work on POHMELFS. |
882 | */ | 881 | */ |
883 | static int pohmelfs_fsync(struct file *file, struct dentry *dentry, int datasync) | 882 | static int pohmelfs_fsync(struct file *file, int datasync) |
884 | { | 883 | { |
885 | struct inode *inode = file->f_mapping->host; | 884 | struct inode *inode = file->f_mapping->host; |
886 | struct writeback_control wbc = { | 885 | struct writeback_control wbc = { |
@@ -969,13 +968,6 @@ int pohmelfs_setattr_raw(struct inode *inode, struct iattr *attr) | |||
969 | goto err_out_exit; | 968 | goto err_out_exit; |
970 | } | 969 | } |
971 | 970 | ||
972 | if ((attr->ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || | ||
973 | (attr->ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) { | ||
974 | err = dquot_transfer(inode, attr); | ||
975 | if (err) | ||
976 | goto err_out_exit; | ||
977 | } | ||
978 | |||
979 | err = inode_setattr(inode, attr); | 971 | err = inode_setattr(inode, attr); |
980 | if (err) { | 972 | if (err) { |
981 | dprintk("%s: ino: %llu, failed to set the attributes.\n", __func__, POHMELFS_I(inode)->ino); | 973 | dprintk("%s: ino: %llu, failed to set the attributes.\n", __func__, POHMELFS_I(inode)->ino); |
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index 6b8bf8c781c4..43abf55d8c60 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c | |||
@@ -794,7 +794,7 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
794 | } | 794 | } |
795 | 795 | ||
796 | static int | 796 | static int |
797 | printer_fsync(struct file *fd, struct dentry *dentry, int datasync) | 797 | printer_fsync(struct file *fd, int datasync) |
798 | { | 798 | { |
799 | struct printer_dev *dev = fd->private_data; | 799 | struct printer_dev *dev = fd->private_data; |
800 | unsigned long flags; | 800 | unsigned long flags; |
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index aa88911c9504..0f41c9195e9b 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c | |||
@@ -593,17 +593,17 @@ static long vhost_net_ioctl(struct file *f, unsigned int ioctl, | |||
593 | int r; | 593 | int r; |
594 | switch (ioctl) { | 594 | switch (ioctl) { |
595 | case VHOST_NET_SET_BACKEND: | 595 | case VHOST_NET_SET_BACKEND: |
596 | r = copy_from_user(&backend, argp, sizeof backend); | 596 | if (copy_from_user(&backend, argp, sizeof backend)) |
597 | if (r < 0) | 597 | return -EFAULT; |
598 | return r; | ||
599 | return vhost_net_set_backend(n, backend.index, backend.fd); | 598 | return vhost_net_set_backend(n, backend.index, backend.fd); |
600 | case VHOST_GET_FEATURES: | 599 | case VHOST_GET_FEATURES: |
601 | features = VHOST_FEATURES; | 600 | features = VHOST_FEATURES; |
602 | return copy_to_user(featurep, &features, sizeof features); | 601 | if (copy_to_user(featurep, &features, sizeof features)) |
602 | return -EFAULT; | ||
603 | return 0; | ||
603 | case VHOST_SET_FEATURES: | 604 | case VHOST_SET_FEATURES: |
604 | r = copy_from_user(&features, featurep, sizeof features); | 605 | if (copy_from_user(&features, featurep, sizeof features)) |
605 | if (r < 0) | 606 | return -EFAULT; |
606 | return r; | ||
607 | if (features & ~VHOST_FEATURES) | 607 | if (features & ~VHOST_FEATURES) |
608 | return -EOPNOTSUPP; | 608 | return -EOPNOTSUPP; |
609 | return vhost_net_set_features(n, features); | 609 | return vhost_net_set_features(n, features); |
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index c6fb8e968f21..3b83382e06eb 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c | |||
@@ -320,10 +320,8 @@ static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m) | |||
320 | { | 320 | { |
321 | struct vhost_memory mem, *newmem, *oldmem; | 321 | struct vhost_memory mem, *newmem, *oldmem; |
322 | unsigned long size = offsetof(struct vhost_memory, regions); | 322 | unsigned long size = offsetof(struct vhost_memory, regions); |
323 | long r; | 323 | if (copy_from_user(&mem, m, size)) |
324 | r = copy_from_user(&mem, m, size); | 324 | return -EFAULT; |
325 | if (r) | ||
326 | return r; | ||
327 | if (mem.padding) | 325 | if (mem.padding) |
328 | return -EOPNOTSUPP; | 326 | return -EOPNOTSUPP; |
329 | if (mem.nregions > VHOST_MEMORY_MAX_NREGIONS) | 327 | if (mem.nregions > VHOST_MEMORY_MAX_NREGIONS) |
@@ -333,15 +331,16 @@ static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m) | |||
333 | return -ENOMEM; | 331 | return -ENOMEM; |
334 | 332 | ||
335 | memcpy(newmem, &mem, size); | 333 | memcpy(newmem, &mem, size); |
336 | r = copy_from_user(newmem->regions, m->regions, | 334 | if (copy_from_user(newmem->regions, m->regions, |
337 | mem.nregions * sizeof *m->regions); | 335 | mem.nregions * sizeof *m->regions)) { |
338 | if (r) { | ||
339 | kfree(newmem); | 336 | kfree(newmem); |
340 | return r; | 337 | return -EFAULT; |
341 | } | 338 | } |
342 | 339 | ||
343 | if (!memory_access_ok(d, newmem, vhost_has_feature(d, VHOST_F_LOG_ALL))) | 340 | if (!memory_access_ok(d, newmem, vhost_has_feature(d, VHOST_F_LOG_ALL))) { |
341 | kfree(newmem); | ||
344 | return -EFAULT; | 342 | return -EFAULT; |
343 | } | ||
345 | oldmem = d->memory; | 344 | oldmem = d->memory; |
346 | rcu_assign_pointer(d->memory, newmem); | 345 | rcu_assign_pointer(d->memory, newmem); |
347 | synchronize_rcu(); | 346 | synchronize_rcu(); |
@@ -374,7 +373,7 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp) | |||
374 | r = get_user(idx, idxp); | 373 | r = get_user(idx, idxp); |
375 | if (r < 0) | 374 | if (r < 0) |
376 | return r; | 375 | return r; |
377 | if (idx > d->nvqs) | 376 | if (idx >= d->nvqs) |
378 | return -ENOBUFS; | 377 | return -ENOBUFS; |
379 | 378 | ||
380 | vq = d->vqs + idx; | 379 | vq = d->vqs + idx; |
@@ -389,9 +388,10 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp) | |||
389 | r = -EBUSY; | 388 | r = -EBUSY; |
390 | break; | 389 | break; |
391 | } | 390 | } |
392 | r = copy_from_user(&s, argp, sizeof s); | 391 | if (copy_from_user(&s, argp, sizeof s)) { |
393 | if (r < 0) | 392 | r = -EFAULT; |
394 | break; | 393 | break; |
394 | } | ||
395 | if (!s.num || s.num > 0xffff || (s.num & (s.num - 1))) { | 395 | if (!s.num || s.num > 0xffff || (s.num & (s.num - 1))) { |
396 | r = -EINVAL; | 396 | r = -EINVAL; |
397 | break; | 397 | break; |
@@ -405,9 +405,10 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp) | |||
405 | r = -EBUSY; | 405 | r = -EBUSY; |
406 | break; | 406 | break; |
407 | } | 407 | } |
408 | r = copy_from_user(&s, argp, sizeof s); | 408 | if (copy_from_user(&s, argp, sizeof s)) { |
409 | if (r < 0) | 409 | r = -EFAULT; |
410 | break; | 410 | break; |
411 | } | ||
411 | if (s.num > 0xffff) { | 412 | if (s.num > 0xffff) { |
412 | r = -EINVAL; | 413 | r = -EINVAL; |
413 | break; | 414 | break; |
@@ -419,12 +420,14 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp) | |||
419 | case VHOST_GET_VRING_BASE: | 420 | case VHOST_GET_VRING_BASE: |
420 | s.index = idx; | 421 | s.index = idx; |
421 | s.num = vq->last_avail_idx; | 422 | s.num = vq->last_avail_idx; |
422 | r = copy_to_user(argp, &s, sizeof s); | 423 | if (copy_to_user(argp, &s, sizeof s)) |
424 | r = -EFAULT; | ||
423 | break; | 425 | break; |
424 | case VHOST_SET_VRING_ADDR: | 426 | case VHOST_SET_VRING_ADDR: |
425 | r = copy_from_user(&a, argp, sizeof a); | 427 | if (copy_from_user(&a, argp, sizeof a)) { |
426 | if (r < 0) | 428 | r = -EFAULT; |
427 | break; | 429 | break; |
430 | } | ||
428 | if (a.flags & ~(0x1 << VHOST_VRING_F_LOG)) { | 431 | if (a.flags & ~(0x1 << VHOST_VRING_F_LOG)) { |
429 | r = -EOPNOTSUPP; | 432 | r = -EOPNOTSUPP; |
430 | break; | 433 | break; |
@@ -477,9 +480,10 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp) | |||
477 | vq->used = (void __user *)(unsigned long)a.used_user_addr; | 480 | vq->used = (void __user *)(unsigned long)a.used_user_addr; |
478 | break; | 481 | break; |
479 | case VHOST_SET_VRING_KICK: | 482 | case VHOST_SET_VRING_KICK: |
480 | r = copy_from_user(&f, argp, sizeof f); | 483 | if (copy_from_user(&f, argp, sizeof f)) { |
481 | if (r < 0) | 484 | r = -EFAULT; |
482 | break; | 485 | break; |
486 | } | ||
483 | eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd); | 487 | eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd); |
484 | if (IS_ERR(eventfp)) { | 488 | if (IS_ERR(eventfp)) { |
485 | r = PTR_ERR(eventfp); | 489 | r = PTR_ERR(eventfp); |
@@ -492,9 +496,10 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp) | |||
492 | filep = eventfp; | 496 | filep = eventfp; |
493 | break; | 497 | break; |
494 | case VHOST_SET_VRING_CALL: | 498 | case VHOST_SET_VRING_CALL: |
495 | r = copy_from_user(&f, argp, sizeof f); | 499 | if (copy_from_user(&f, argp, sizeof f)) { |
496 | if (r < 0) | 500 | r = -EFAULT; |
497 | break; | 501 | break; |
502 | } | ||
498 | eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd); | 503 | eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd); |
499 | if (IS_ERR(eventfp)) { | 504 | if (IS_ERR(eventfp)) { |
500 | r = PTR_ERR(eventfp); | 505 | r = PTR_ERR(eventfp); |
@@ -510,9 +515,10 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp) | |||
510 | filep = eventfp; | 515 | filep = eventfp; |
511 | break; | 516 | break; |
512 | case VHOST_SET_VRING_ERR: | 517 | case VHOST_SET_VRING_ERR: |
513 | r = copy_from_user(&f, argp, sizeof f); | 518 | if (copy_from_user(&f, argp, sizeof f)) { |
514 | if (r < 0) | 519 | r = -EFAULT; |
515 | break; | 520 | break; |
521 | } | ||
516 | eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd); | 522 | eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd); |
517 | if (IS_ERR(eventfp)) { | 523 | if (IS_ERR(eventfp)) { |
518 | r = PTR_ERR(eventfp); | 524 | r = PTR_ERR(eventfp); |
@@ -575,9 +581,10 @@ long vhost_dev_ioctl(struct vhost_dev *d, unsigned int ioctl, unsigned long arg) | |||
575 | r = vhost_set_memory(d, argp); | 581 | r = vhost_set_memory(d, argp); |
576 | break; | 582 | break; |
577 | case VHOST_SET_LOG_BASE: | 583 | case VHOST_SET_LOG_BASE: |
578 | r = copy_from_user(&p, argp, sizeof p); | 584 | if (copy_from_user(&p, argp, sizeof p)) { |
579 | if (r < 0) | 585 | r = -EFAULT; |
580 | break; | 586 | break; |
587 | } | ||
581 | if ((u64)(unsigned long)p != p) { | 588 | if ((u64)(unsigned long)p != p) { |
582 | r = -EFAULT; | 589 | r = -EFAULT; |
583 | break; | 590 | break; |
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c index 1105a591dcc1..073c9b408cf7 100644 --- a/drivers/video/fb_defio.c +++ b/drivers/video/fb_defio.c | |||
@@ -66,7 +66,7 @@ static int fb_deferred_io_fault(struct vm_area_struct *vma, | |||
66 | return 0; | 66 | return 0; |
67 | } | 67 | } |
68 | 68 | ||
69 | int fb_deferred_io_fsync(struct file *file, struct dentry *dentry, int datasync) | 69 | int fb_deferred_io_fsync(struct file *file, int datasync) |
70 | { | 70 | { |
71 | struct fb_info *info = file->private_data; | 71 | struct fb_info *info = file->private_data; |
72 | 72 | ||
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index 25b300e1c9d7..2bedc6c94fc2 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c | |||
@@ -257,15 +257,13 @@ v9fs_file_write(struct file *filp, const char __user * data, | |||
257 | return total; | 257 | return total; |
258 | } | 258 | } |
259 | 259 | ||
260 | static int v9fs_file_fsync(struct file *filp, struct dentry *dentry, | 260 | static int v9fs_file_fsync(struct file *filp, int datasync) |
261 | int datasync) | ||
262 | { | 261 | { |
263 | struct p9_fid *fid; | 262 | struct p9_fid *fid; |
264 | struct p9_wstat wstat; | 263 | struct p9_wstat wstat; |
265 | int retval; | 264 | int retval; |
266 | 265 | ||
267 | P9_DPRINTK(P9_DEBUG_VFS, "filp %p dentry %p datasync %x\n", filp, | 266 | P9_DPRINTK(P9_DEBUG_VFS, "filp %p datasync %x\n", filp, datasync); |
268 | dentry, datasync); | ||
269 | 267 | ||
270 | fid = filp->private_data; | 268 | fid = filp->private_data; |
271 | v9fs_blank_wstat(&wstat); | 269 | v9fs_blank_wstat(&wstat); |
diff --git a/fs/adfs/dir.c b/fs/adfs/dir.c index 23aa52f548a0..f4287e4de744 100644 --- a/fs/adfs/dir.c +++ b/fs/adfs/dir.c | |||
@@ -197,7 +197,7 @@ const struct file_operations adfs_dir_operations = { | |||
197 | .read = generic_read_dir, | 197 | .read = generic_read_dir, |
198 | .llseek = generic_file_llseek, | 198 | .llseek = generic_file_llseek, |
199 | .readdir = adfs_readdir, | 199 | .readdir = adfs_readdir, |
200 | .fsync = simple_fsync, | 200 | .fsync = generic_file_fsync, |
201 | }; | 201 | }; |
202 | 202 | ||
203 | static int | 203 | static int |
diff --git a/fs/adfs/file.c b/fs/adfs/file.c index 005ea34d1758..a36da5382b40 100644 --- a/fs/adfs/file.c +++ b/fs/adfs/file.c | |||
@@ -26,7 +26,7 @@ const struct file_operations adfs_file_operations = { | |||
26 | .read = do_sync_read, | 26 | .read = do_sync_read, |
27 | .aio_read = generic_file_aio_read, | 27 | .aio_read = generic_file_aio_read, |
28 | .mmap = generic_file_mmap, | 28 | .mmap = generic_file_mmap, |
29 | .fsync = simple_fsync, | 29 | .fsync = generic_file_fsync, |
30 | .write = do_sync_write, | 30 | .write = do_sync_write, |
31 | .aio_write = generic_file_aio_write, | 31 | .aio_write = generic_file_aio_write, |
32 | .splice_read = generic_file_splice_read, | 32 | .splice_read = generic_file_splice_read, |
diff --git a/fs/adfs/inode.c b/fs/adfs/inode.c index 0f5e30978135..6f850b06ab62 100644 --- a/fs/adfs/inode.c +++ b/fs/adfs/inode.c | |||
@@ -322,8 +322,9 @@ adfs_notify_change(struct dentry *dentry, struct iattr *attr) | |||
322 | if (error) | 322 | if (error) |
323 | goto out; | 323 | goto out; |
324 | 324 | ||
325 | /* XXX: this is missing some actual on-disk truncation.. */ | ||
325 | if (ia_valid & ATTR_SIZE) | 326 | if (ia_valid & ATTR_SIZE) |
326 | error = vmtruncate(inode, attr->ia_size); | 327 | error = simple_setsize(inode, attr->ia_size); |
327 | 328 | ||
328 | if (error) | 329 | if (error) |
329 | goto out; | 330 | goto out; |
diff --git a/fs/affs/affs.h b/fs/affs/affs.h index 861dae68ac12..f05b6155ccc8 100644 --- a/fs/affs/affs.h +++ b/fs/affs/affs.h | |||
@@ -183,7 +183,7 @@ extern int affs_add_entry(struct inode *dir, struct inode *inode, struct dent | |||
183 | 183 | ||
184 | void affs_free_prealloc(struct inode *inode); | 184 | void affs_free_prealloc(struct inode *inode); |
185 | extern void affs_truncate(struct inode *); | 185 | extern void affs_truncate(struct inode *); |
186 | int affs_file_fsync(struct file *, struct dentry *, int); | 186 | int affs_file_fsync(struct file *, int); |
187 | 187 | ||
188 | /* dir.c */ | 188 | /* dir.c */ |
189 | 189 | ||
diff --git a/fs/affs/file.c b/fs/affs/file.c index 184e55c1c9ba..322710c3eedf 100644 --- a/fs/affs/file.c +++ b/fs/affs/file.c | |||
@@ -916,9 +916,9 @@ affs_truncate(struct inode *inode) | |||
916 | affs_free_prealloc(inode); | 916 | affs_free_prealloc(inode); |
917 | } | 917 | } |
918 | 918 | ||
919 | int affs_file_fsync(struct file *filp, struct dentry *dentry, int datasync) | 919 | int affs_file_fsync(struct file *filp, int datasync) |
920 | { | 920 | { |
921 | struct inode * inode = dentry->d_inode; | 921 | struct inode *inode = filp->f_mapping->host; |
922 | int ret, err; | 922 | int ret, err; |
923 | 923 | ||
924 | ret = write_inode_now(inode, 0); | 924 | ret = write_inode_now(inode, 0); |
diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 807f284cc75e..5f679b77ce24 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h | |||
@@ -740,7 +740,7 @@ extern void afs_pages_written_back(struct afs_vnode *, struct afs_call *); | |||
740 | extern ssize_t afs_file_write(struct kiocb *, const struct iovec *, | 740 | extern ssize_t afs_file_write(struct kiocb *, const struct iovec *, |
741 | unsigned long, loff_t); | 741 | unsigned long, loff_t); |
742 | extern int afs_writeback_all(struct afs_vnode *); | 742 | extern int afs_writeback_all(struct afs_vnode *); |
743 | extern int afs_fsync(struct file *, struct dentry *, int); | 743 | extern int afs_fsync(struct file *, int); |
744 | 744 | ||
745 | 745 | ||
746 | /*****************************************************************************/ | 746 | /*****************************************************************************/ |
diff --git a/fs/afs/write.c b/fs/afs/write.c index 3bed54a294d4..3dab9e9948d0 100644 --- a/fs/afs/write.c +++ b/fs/afs/write.c | |||
@@ -701,8 +701,9 @@ int afs_writeback_all(struct afs_vnode *vnode) | |||
701 | * - the return status from this call provides a reliable indication of | 701 | * - the return status from this call provides a reliable indication of |
702 | * whether any write errors occurred for this process. | 702 | * whether any write errors occurred for this process. |
703 | */ | 703 | */ |
704 | int afs_fsync(struct file *file, struct dentry *dentry, int datasync) | 704 | int afs_fsync(struct file *file, int datasync) |
705 | { | 705 | { |
706 | struct dentry *dentry = file->f_path.dentry; | ||
706 | struct afs_writeback *wb, *xwb; | 707 | struct afs_writeback *wb, *xwb; |
707 | struct afs_vnode *vnode = AFS_FS_I(dentry->d_inode); | 708 | struct afs_vnode *vnode = AFS_FS_I(dentry->d_inode); |
708 | int ret; | 709 | int ret; |
@@ -527,7 +527,7 @@ static void aio_fput_routine(struct work_struct *data) | |||
527 | 527 | ||
528 | /* Complete the fput(s) */ | 528 | /* Complete the fput(s) */ |
529 | if (req->ki_filp != NULL) | 529 | if (req->ki_filp != NULL) |
530 | __fput(req->ki_filp); | 530 | fput(req->ki_filp); |
531 | 531 | ||
532 | /* Link the iocb into the context's free list */ | 532 | /* Link the iocb into the context's free list */ |
533 | spin_lock_irq(&ctx->ctx_lock); | 533 | spin_lock_irq(&ctx->ctx_lock); |
@@ -560,11 +560,11 @@ static int __aio_put_req(struct kioctx *ctx, struct kiocb *req) | |||
560 | 560 | ||
561 | /* | 561 | /* |
562 | * Try to optimize the aio and eventfd file* puts, by avoiding to | 562 | * Try to optimize the aio and eventfd file* puts, by avoiding to |
563 | * schedule work in case it is not __fput() time. In normal cases, | 563 | * schedule work in case it is not final fput() time. In normal cases, |
564 | * we would not be holding the last reference to the file*, so | 564 | * we would not be holding the last reference to the file*, so |
565 | * this function will be executed w/out any aio kthread wakeup. | 565 | * this function will be executed w/out any aio kthread wakeup. |
566 | */ | 566 | */ |
567 | if (unlikely(atomic_long_dec_and_test(&req->ki_filp->f_count))) { | 567 | if (unlikely(!fput_atomic(req->ki_filp))) { |
568 | get_ioctx(ctx); | 568 | get_ioctx(ctx); |
569 | spin_lock(&fput_lock); | 569 | spin_lock(&fput_lock); |
570 | list_add(&req->ki_list, &fput_head); | 570 | list_add(&req->ki_list, &fput_head); |
diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c index 9bd4b3876c99..e4b75d6eda83 100644 --- a/fs/anon_inodes.c +++ b/fs/anon_inodes.c | |||
@@ -205,7 +205,7 @@ static struct inode *anon_inode_mkinode(void) | |||
205 | * that it already _is_ on the dirty list. | 205 | * that it already _is_ on the dirty list. |
206 | */ | 206 | */ |
207 | inode->i_state = I_DIRTY; | 207 | inode->i_state = I_DIRTY; |
208 | inode->i_mode = S_IFREG | S_IRUSR | S_IWUSR; | 208 | inode->i_mode = S_IRUSR | S_IWUSR; |
209 | inode->i_uid = current_fsuid(); | 209 | inode->i_uid = current_fsuid(); |
210 | inode->i_gid = current_fsgid(); | 210 | inode->i_gid = current_fsgid(); |
211 | inode->i_flags |= S_PRIVATE; | 211 | inode->i_flags |= S_PRIVATE; |
@@ -67,14 +67,14 @@ EXPORT_SYMBOL(inode_change_ok); | |||
67 | * @offset: the new size to assign to the inode | 67 | * @offset: the new size to assign to the inode |
68 | * @Returns: 0 on success, -ve errno on failure | 68 | * @Returns: 0 on success, -ve errno on failure |
69 | * | 69 | * |
70 | * inode_newsize_ok must be called with i_mutex held. | ||
71 | * | ||
70 | * inode_newsize_ok will check filesystem limits and ulimits to check that the | 72 | * inode_newsize_ok will check filesystem limits and ulimits to check that the |
71 | * new inode size is within limits. inode_newsize_ok will also send SIGXFSZ | 73 | * new inode size is within limits. inode_newsize_ok will also send SIGXFSZ |
72 | * when necessary. Caller must not proceed with inode size change if failure is | 74 | * when necessary. Caller must not proceed with inode size change if failure is |
73 | * returned. @inode must be a file (not directory), with appropriate | 75 | * returned. @inode must be a file (not directory), with appropriate |
74 | * permissions to allow truncate (inode_newsize_ok does NOT check these | 76 | * permissions to allow truncate (inode_newsize_ok does NOT check these |
75 | * conditions). | 77 | * conditions). |
76 | * | ||
77 | * inode_newsize_ok must be called with i_mutex held. | ||
78 | */ | 78 | */ |
79 | int inode_newsize_ok(const struct inode *inode, loff_t offset) | 79 | int inode_newsize_ok(const struct inode *inode, loff_t offset) |
80 | { | 80 | { |
@@ -104,17 +104,25 @@ out_big: | |||
104 | } | 104 | } |
105 | EXPORT_SYMBOL(inode_newsize_ok); | 105 | EXPORT_SYMBOL(inode_newsize_ok); |
106 | 106 | ||
107 | int inode_setattr(struct inode * inode, struct iattr * attr) | 107 | /** |
108 | * generic_setattr - copy simple metadata updates into the generic inode | ||
109 | * @inode: the inode to be updated | ||
110 | * @attr: the new attributes | ||
111 | * | ||
112 | * generic_setattr must be called with i_mutex held. | ||
113 | * | ||
114 | * generic_setattr updates the inode's metadata with that specified | ||
115 | * in attr. Noticably missing is inode size update, which is more complex | ||
116 | * as it requires pagecache updates. See simple_setsize. | ||
117 | * | ||
118 | * The inode is not marked as dirty after this operation. The rationale is | ||
119 | * that for "simple" filesystems, the struct inode is the inode storage. | ||
120 | * The caller is free to mark the inode dirty afterwards if needed. | ||
121 | */ | ||
122 | void generic_setattr(struct inode *inode, const struct iattr *attr) | ||
108 | { | 123 | { |
109 | unsigned int ia_valid = attr->ia_valid; | 124 | unsigned int ia_valid = attr->ia_valid; |
110 | 125 | ||
111 | if (ia_valid & ATTR_SIZE && | ||
112 | attr->ia_size != i_size_read(inode)) { | ||
113 | int error = vmtruncate(inode, attr->ia_size); | ||
114 | if (error) | ||
115 | return error; | ||
116 | } | ||
117 | |||
118 | if (ia_valid & ATTR_UID) | 126 | if (ia_valid & ATTR_UID) |
119 | inode->i_uid = attr->ia_uid; | 127 | inode->i_uid = attr->ia_uid; |
120 | if (ia_valid & ATTR_GID) | 128 | if (ia_valid & ATTR_GID) |
@@ -135,6 +143,28 @@ int inode_setattr(struct inode * inode, struct iattr * attr) | |||
135 | mode &= ~S_ISGID; | 143 | mode &= ~S_ISGID; |
136 | inode->i_mode = mode; | 144 | inode->i_mode = mode; |
137 | } | 145 | } |
146 | } | ||
147 | EXPORT_SYMBOL(generic_setattr); | ||
148 | |||
149 | /* | ||
150 | * note this function is deprecated, the new truncate sequence should be | ||
151 | * used instead -- see eg. simple_setsize, generic_setattr. | ||
152 | */ | ||
153 | int inode_setattr(struct inode *inode, const struct iattr *attr) | ||
154 | { | ||
155 | unsigned int ia_valid = attr->ia_valid; | ||
156 | |||
157 | if (ia_valid & ATTR_SIZE && | ||
158 | attr->ia_size != i_size_read(inode)) { | ||
159 | int error; | ||
160 | |||
161 | error = vmtruncate(inode, attr->ia_size); | ||
162 | if (error) | ||
163 | return error; | ||
164 | } | ||
165 | |||
166 | generic_setattr(inode, attr); | ||
167 | |||
138 | mark_inode_dirty(inode); | 168 | mark_inode_dirty(inode); |
139 | 169 | ||
140 | return 0; | 170 | return 0; |
diff --git a/fs/bad_inode.c b/fs/bad_inode.c index a05287a23f62..52e59bf4aa5f 100644 --- a/fs/bad_inode.c +++ b/fs/bad_inode.c | |||
@@ -93,8 +93,7 @@ static int bad_file_release(struct inode *inode, struct file *filp) | |||
93 | return -EIO; | 93 | return -EIO; |
94 | } | 94 | } |
95 | 95 | ||
96 | static int bad_file_fsync(struct file *file, struct dentry *dentry, | 96 | static int bad_file_fsync(struct file *file, int datasync) |
97 | int datasync) | ||
98 | { | 97 | { |
99 | return -EIO; | 98 | return -EIO; |
100 | } | 99 | } |
diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c index 8f73841fc974..d967e052b779 100644 --- a/fs/bfs/dir.c +++ b/fs/bfs/dir.c | |||
@@ -78,7 +78,7 @@ static int bfs_readdir(struct file *f, void *dirent, filldir_t filldir) | |||
78 | const struct file_operations bfs_dir_operations = { | 78 | const struct file_operations bfs_dir_operations = { |
79 | .read = generic_read_dir, | 79 | .read = generic_read_dir, |
80 | .readdir = bfs_readdir, | 80 | .readdir = bfs_readdir, |
81 | .fsync = simple_fsync, | 81 | .fsync = generic_file_fsync, |
82 | .llseek = generic_file_llseek, | 82 | .llseek = generic_file_llseek, |
83 | }; | 83 | }; |
84 | 84 | ||
diff --git a/fs/block_dev.c b/fs/block_dev.c index 26e5f5026620..7346c96308a5 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -172,8 +172,9 @@ blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, | |||
172 | struct file *file = iocb->ki_filp; | 172 | struct file *file = iocb->ki_filp; |
173 | struct inode *inode = file->f_mapping->host; | 173 | struct inode *inode = file->f_mapping->host; |
174 | 174 | ||
175 | return blockdev_direct_IO_no_locking(rw, iocb, inode, I_BDEV(inode), | 175 | return blockdev_direct_IO_no_locking_newtrunc(rw, iocb, inode, |
176 | iov, offset, nr_segs, blkdev_get_blocks, NULL); | 176 | I_BDEV(inode), iov, offset, nr_segs, |
177 | blkdev_get_blocks, NULL); | ||
177 | } | 178 | } |
178 | 179 | ||
179 | int __sync_blockdev(struct block_device *bdev, int wait) | 180 | int __sync_blockdev(struct block_device *bdev, int wait) |
@@ -309,8 +310,8 @@ static int blkdev_write_begin(struct file *file, struct address_space *mapping, | |||
309 | struct page **pagep, void **fsdata) | 310 | struct page **pagep, void **fsdata) |
310 | { | 311 | { |
311 | *pagep = NULL; | 312 | *pagep = NULL; |
312 | return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, | 313 | return block_write_begin_newtrunc(file, mapping, pos, len, flags, |
313 | blkdev_get_block); | 314 | pagep, fsdata, blkdev_get_block); |
314 | } | 315 | } |
315 | 316 | ||
316 | static int blkdev_write_end(struct file *file, struct address_space *mapping, | 317 | static int blkdev_write_end(struct file *file, struct address_space *mapping, |
@@ -358,12 +359,7 @@ static loff_t block_llseek(struct file *file, loff_t offset, int origin) | |||
358 | return retval; | 359 | return retval; |
359 | } | 360 | } |
360 | 361 | ||
361 | /* | 362 | int blkdev_fsync(struct file *filp, int datasync) |
362 | * Filp is never NULL; the only case when ->fsync() is called with | ||
363 | * NULL first argument is nfsd_sync_dir() and that's not a directory. | ||
364 | */ | ||
365 | |||
366 | int blkdev_fsync(struct file *filp, struct dentry *dentry, int datasync) | ||
367 | { | 363 | { |
368 | struct inode *bd_inode = filp->f_mapping->host; | 364 | struct inode *bd_inode = filp->f_mapping->host; |
369 | struct block_device *bdev = I_BDEV(bd_inode); | 365 | struct block_device *bdev = I_BDEV(bd_inode); |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index e9bf86415e86..29c20092847e 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -2434,7 +2434,7 @@ void btrfs_update_iflags(struct inode *inode); | |||
2434 | void btrfs_inherit_iflags(struct inode *inode, struct inode *dir); | 2434 | void btrfs_inherit_iflags(struct inode *inode, struct inode *dir); |
2435 | 2435 | ||
2436 | /* file.c */ | 2436 | /* file.c */ |
2437 | int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync); | 2437 | int btrfs_sync_file(struct file *file, int datasync); |
2438 | int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, | 2438 | int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, |
2439 | int skip_pinned); | 2439 | int skip_pinned); |
2440 | int btrfs_check_file(struct btrfs_root *root, struct inode *inode); | 2440 | int btrfs_check_file(struct btrfs_root *root, struct inode *inode); |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 79437c5eeb1e..787b50a16a14 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -1101,8 +1101,9 @@ int btrfs_release_file(struct inode *inode, struct file *filp) | |||
1101 | * important optimization for directories because holding the mutex prevents | 1101 | * important optimization for directories because holding the mutex prevents |
1102 | * new operations on the dir while we write to disk. | 1102 | * new operations on the dir while we write to disk. |
1103 | */ | 1103 | */ |
1104 | int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) | 1104 | int btrfs_sync_file(struct file *file, int datasync) |
1105 | { | 1105 | { |
1106 | struct dentry *dentry = file->f_path.dentry; | ||
1106 | struct inode *inode = dentry->d_inode; | 1107 | struct inode *inode = dentry->d_inode; |
1107 | struct btrfs_root *root = BTRFS_I(inode)->root; | 1108 | struct btrfs_root *root = BTRFS_I(inode)->root; |
1108 | int ret = 0; | 1109 | int ret = 0; |
diff --git a/fs/buffer.c b/fs/buffer.c index e8aa7081d25c..d54812b198e9 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -1949,14 +1949,11 @@ static int __block_commit_write(struct inode *inode, struct page *page, | |||
1949 | } | 1949 | } |
1950 | 1950 | ||
1951 | /* | 1951 | /* |
1952 | * block_write_begin takes care of the basic task of block allocation and | 1952 | * Filesystems implementing the new truncate sequence should use the |
1953 | * bringing partial write blocks uptodate first. | 1953 | * _newtrunc postfix variant which won't incorrectly call vmtruncate. |
1954 | * | 1954 | * The filesystem needs to handle block truncation upon failure. |
1955 | * If *pagep is not NULL, then block_write_begin uses the locked page | ||
1956 | * at *pagep rather than allocating its own. In this case, the page will | ||
1957 | * not be unlocked or deallocated on failure. | ||
1958 | */ | 1955 | */ |
1959 | int block_write_begin(struct file *file, struct address_space *mapping, | 1956 | int block_write_begin_newtrunc(struct file *file, struct address_space *mapping, |
1960 | loff_t pos, unsigned len, unsigned flags, | 1957 | loff_t pos, unsigned len, unsigned flags, |
1961 | struct page **pagep, void **fsdata, | 1958 | struct page **pagep, void **fsdata, |
1962 | get_block_t *get_block) | 1959 | get_block_t *get_block) |
@@ -1992,20 +1989,50 @@ int block_write_begin(struct file *file, struct address_space *mapping, | |||
1992 | unlock_page(page); | 1989 | unlock_page(page); |
1993 | page_cache_release(page); | 1990 | page_cache_release(page); |
1994 | *pagep = NULL; | 1991 | *pagep = NULL; |
1995 | |||
1996 | /* | ||
1997 | * prepare_write() may have instantiated a few blocks | ||
1998 | * outside i_size. Trim these off again. Don't need | ||
1999 | * i_size_read because we hold i_mutex. | ||
2000 | */ | ||
2001 | if (pos + len > inode->i_size) | ||
2002 | vmtruncate(inode, inode->i_size); | ||
2003 | } | 1992 | } |
2004 | } | 1993 | } |
2005 | 1994 | ||
2006 | out: | 1995 | out: |
2007 | return status; | 1996 | return status; |
2008 | } | 1997 | } |
1998 | EXPORT_SYMBOL(block_write_begin_newtrunc); | ||
1999 | |||
2000 | /* | ||
2001 | * block_write_begin takes care of the basic task of block allocation and | ||
2002 | * bringing partial write blocks uptodate first. | ||
2003 | * | ||
2004 | * If *pagep is not NULL, then block_write_begin uses the locked page | ||
2005 | * at *pagep rather than allocating its own. In this case, the page will | ||
2006 | * not be unlocked or deallocated on failure. | ||
2007 | */ | ||
2008 | int block_write_begin(struct file *file, struct address_space *mapping, | ||
2009 | loff_t pos, unsigned len, unsigned flags, | ||
2010 | struct page **pagep, void **fsdata, | ||
2011 | get_block_t *get_block) | ||
2012 | { | ||
2013 | int ret; | ||
2014 | |||
2015 | ret = block_write_begin_newtrunc(file, mapping, pos, len, flags, | ||
2016 | pagep, fsdata, get_block); | ||
2017 | |||
2018 | /* | ||
2019 | * prepare_write() may have instantiated a few blocks | ||
2020 | * outside i_size. Trim these off again. Don't need | ||
2021 | * i_size_read because we hold i_mutex. | ||
2022 | * | ||
2023 | * Filesystems which pass down their own page also cannot | ||
2024 | * call into vmtruncate here because it would lead to lock | ||
2025 | * inversion problems (*pagep is locked). This is a further | ||
2026 | * example of where the old truncate sequence is inadequate. | ||
2027 | */ | ||
2028 | if (unlikely(ret) && *pagep == NULL) { | ||
2029 | loff_t isize = mapping->host->i_size; | ||
2030 | if (pos + len > isize) | ||
2031 | vmtruncate(mapping->host, isize); | ||
2032 | } | ||
2033 | |||
2034 | return ret; | ||
2035 | } | ||
2009 | EXPORT_SYMBOL(block_write_begin); | 2036 | EXPORT_SYMBOL(block_write_begin); |
2010 | 2037 | ||
2011 | int block_write_end(struct file *file, struct address_space *mapping, | 2038 | int block_write_end(struct file *file, struct address_space *mapping, |
@@ -2324,7 +2351,7 @@ out: | |||
2324 | * For moronic filesystems that do not allow holes in file. | 2351 | * For moronic filesystems that do not allow holes in file. |
2325 | * We may have to extend the file. | 2352 | * We may have to extend the file. |
2326 | */ | 2353 | */ |
2327 | int cont_write_begin(struct file *file, struct address_space *mapping, | 2354 | int cont_write_begin_newtrunc(struct file *file, struct address_space *mapping, |
2328 | loff_t pos, unsigned len, unsigned flags, | 2355 | loff_t pos, unsigned len, unsigned flags, |
2329 | struct page **pagep, void **fsdata, | 2356 | struct page **pagep, void **fsdata, |
2330 | get_block_t *get_block, loff_t *bytes) | 2357 | get_block_t *get_block, loff_t *bytes) |
@@ -2345,11 +2372,30 @@ int cont_write_begin(struct file *file, struct address_space *mapping, | |||
2345 | } | 2372 | } |
2346 | 2373 | ||
2347 | *pagep = NULL; | 2374 | *pagep = NULL; |
2348 | err = block_write_begin(file, mapping, pos, len, | 2375 | err = block_write_begin_newtrunc(file, mapping, pos, len, |
2349 | flags, pagep, fsdata, get_block); | 2376 | flags, pagep, fsdata, get_block); |
2350 | out: | 2377 | out: |
2351 | return err; | 2378 | return err; |
2352 | } | 2379 | } |
2380 | EXPORT_SYMBOL(cont_write_begin_newtrunc); | ||
2381 | |||
2382 | int cont_write_begin(struct file *file, struct address_space *mapping, | ||
2383 | loff_t pos, unsigned len, unsigned flags, | ||
2384 | struct page **pagep, void **fsdata, | ||
2385 | get_block_t *get_block, loff_t *bytes) | ||
2386 | { | ||
2387 | int ret; | ||
2388 | |||
2389 | ret = cont_write_begin_newtrunc(file, mapping, pos, len, flags, | ||
2390 | pagep, fsdata, get_block, bytes); | ||
2391 | if (unlikely(ret)) { | ||
2392 | loff_t isize = mapping->host->i_size; | ||
2393 | if (pos + len > isize) | ||
2394 | vmtruncate(mapping->host, isize); | ||
2395 | } | ||
2396 | |||
2397 | return ret; | ||
2398 | } | ||
2353 | EXPORT_SYMBOL(cont_write_begin); | 2399 | EXPORT_SYMBOL(cont_write_begin); |
2354 | 2400 | ||
2355 | int block_prepare_write(struct page *page, unsigned from, unsigned to, | 2401 | int block_prepare_write(struct page *page, unsigned from, unsigned to, |
@@ -2381,7 +2427,7 @@ EXPORT_SYMBOL(block_commit_write); | |||
2381 | * | 2427 | * |
2382 | * We are not allowed to take the i_mutex here so we have to play games to | 2428 | * We are not allowed to take the i_mutex here so we have to play games to |
2383 | * protect against truncate races as the page could now be beyond EOF. Because | 2429 | * protect against truncate races as the page could now be beyond EOF. Because |
2384 | * vmtruncate() writes the inode size before removing pages, once we have the | 2430 | * truncate writes the inode size before removing pages, once we have the |
2385 | * page lock we can determine safely if the page is beyond EOF. If it is not | 2431 | * page lock we can determine safely if the page is beyond EOF. If it is not |
2386 | * beyond EOF, then the page is guaranteed safe against truncation until we | 2432 | * beyond EOF, then the page is guaranteed safe against truncation until we |
2387 | * unlock the page. | 2433 | * unlock the page. |
@@ -2464,10 +2510,11 @@ static void attach_nobh_buffers(struct page *page, struct buffer_head *head) | |||
2464 | } | 2510 | } |
2465 | 2511 | ||
2466 | /* | 2512 | /* |
2467 | * On entry, the page is fully not uptodate. | 2513 | * Filesystems implementing the new truncate sequence should use the |
2468 | * On exit the page is fully uptodate in the areas outside (from,to) | 2514 | * _newtrunc postfix variant which won't incorrectly call vmtruncate. |
2515 | * The filesystem needs to handle block truncation upon failure. | ||
2469 | */ | 2516 | */ |
2470 | int nobh_write_begin(struct file *file, struct address_space *mapping, | 2517 | int nobh_write_begin_newtrunc(struct file *file, struct address_space *mapping, |
2471 | loff_t pos, unsigned len, unsigned flags, | 2518 | loff_t pos, unsigned len, unsigned flags, |
2472 | struct page **pagep, void **fsdata, | 2519 | struct page **pagep, void **fsdata, |
2473 | get_block_t *get_block) | 2520 | get_block_t *get_block) |
@@ -2500,8 +2547,8 @@ int nobh_write_begin(struct file *file, struct address_space *mapping, | |||
2500 | unlock_page(page); | 2547 | unlock_page(page); |
2501 | page_cache_release(page); | 2548 | page_cache_release(page); |
2502 | *pagep = NULL; | 2549 | *pagep = NULL; |
2503 | return block_write_begin(file, mapping, pos, len, flags, pagep, | 2550 | return block_write_begin_newtrunc(file, mapping, pos, len, |
2504 | fsdata, get_block); | 2551 | flags, pagep, fsdata, get_block); |
2505 | } | 2552 | } |
2506 | 2553 | ||
2507 | if (PageMappedToDisk(page)) | 2554 | if (PageMappedToDisk(page)) |
@@ -2605,8 +2652,34 @@ out_release: | |||
2605 | page_cache_release(page); | 2652 | page_cache_release(page); |
2606 | *pagep = NULL; | 2653 | *pagep = NULL; |
2607 | 2654 | ||
2608 | if (pos + len > inode->i_size) | 2655 | return ret; |
2609 | vmtruncate(inode, inode->i_size); | 2656 | } |
2657 | EXPORT_SYMBOL(nobh_write_begin_newtrunc); | ||
2658 | |||
2659 | /* | ||
2660 | * On entry, the page is fully not uptodate. | ||
2661 | * On exit the page is fully uptodate in the areas outside (from,to) | ||
2662 | */ | ||
2663 | int nobh_write_begin(struct file *file, struct address_space *mapping, | ||
2664 | loff_t pos, unsigned len, unsigned flags, | ||
2665 | struct page **pagep, void **fsdata, | ||
2666 | get_block_t *get_block) | ||
2667 | { | ||
2668 | int ret; | ||
2669 | |||
2670 | ret = nobh_write_begin_newtrunc(file, mapping, pos, len, flags, | ||
2671 | pagep, fsdata, get_block); | ||
2672 | |||
2673 | /* | ||
2674 | * prepare_write() may have instantiated a few blocks | ||
2675 | * outside i_size. Trim these off again. Don't need | ||
2676 | * i_size_read because we hold i_mutex. | ||
2677 | */ | ||
2678 | if (unlikely(ret)) { | ||
2679 | loff_t isize = mapping->host->i_size; | ||
2680 | if (pos + len > isize) | ||
2681 | vmtruncate(mapping->host, isize); | ||
2682 | } | ||
2610 | 2683 | ||
2611 | return ret; | 2684 | return ret; |
2612 | } | 2685 | } |
diff --git a/fs/ceph/auth.c b/fs/ceph/auth.c index 9f46de2ba7a7..89490beaf537 100644 --- a/fs/ceph/auth.c +++ b/fs/ceph/auth.c | |||
@@ -1,7 +1,6 @@ | |||
1 | #include "ceph_debug.h" | 1 | #include "ceph_debug.h" |
2 | 2 | ||
3 | #include <linux/module.h> | 3 | #include <linux/module.h> |
4 | #include <linux/slab.h> | ||
5 | #include <linux/err.h> | 4 | #include <linux/err.h> |
6 | #include <linux/slab.h> | 5 | #include <linux/slab.h> |
7 | 6 | ||
@@ -217,8 +216,8 @@ int ceph_handle_auth_reply(struct ceph_auth_client *ac, | |||
217 | if (ac->protocol != protocol) { | 216 | if (ac->protocol != protocol) { |
218 | ret = ceph_auth_init_protocol(ac, protocol); | 217 | ret = ceph_auth_init_protocol(ac, protocol); |
219 | if (ret) { | 218 | if (ret) { |
220 | pr_err("error %d on auth method %s init\n", | 219 | pr_err("error %d on auth protocol %d init\n", |
221 | ret, ac->ops->name); | 220 | ret, protocol); |
222 | goto out; | 221 | goto out; |
223 | } | 222 | } |
224 | } | 223 | } |
@@ -247,7 +246,7 @@ int ceph_build_auth(struct ceph_auth_client *ac, | |||
247 | if (!ac->protocol) | 246 | if (!ac->protocol) |
248 | return ceph_auth_build_hello(ac, msg_buf, msg_len); | 247 | return ceph_auth_build_hello(ac, msg_buf, msg_len); |
249 | BUG_ON(!ac->ops); | 248 | BUG_ON(!ac->ops); |
250 | if (!ac->ops->is_authenticated(ac)) | 249 | if (ac->ops->should_authenticate(ac)) |
251 | return ceph_build_auth_request(ac, msg_buf, msg_len); | 250 | return ceph_build_auth_request(ac, msg_buf, msg_len); |
252 | return 0; | 251 | return 0; |
253 | } | 252 | } |
diff --git a/fs/ceph/auth.h b/fs/ceph/auth.h index 4429a707c021..d38a2fb4a137 100644 --- a/fs/ceph/auth.h +++ b/fs/ceph/auth.h | |||
@@ -24,6 +24,12 @@ struct ceph_auth_client_ops { | |||
24 | int (*is_authenticated)(struct ceph_auth_client *ac); | 24 | int (*is_authenticated)(struct ceph_auth_client *ac); |
25 | 25 | ||
26 | /* | 26 | /* |
27 | * true if we should (re)authenticate, e.g., when our tickets | ||
28 | * are getting old and crusty. | ||
29 | */ | ||
30 | int (*should_authenticate)(struct ceph_auth_client *ac); | ||
31 | |||
32 | /* | ||
27 | * build requests and process replies during monitor | 33 | * build requests and process replies during monitor |
28 | * handshake. if handle_reply returns -EAGAIN, we build | 34 | * handshake. if handle_reply returns -EAGAIN, we build |
29 | * another request. | 35 | * another request. |
diff --git a/fs/ceph/auth_none.c b/fs/ceph/auth_none.c index 24407c119291..ad1dc21286c7 100644 --- a/fs/ceph/auth_none.c +++ b/fs/ceph/auth_none.c | |||
@@ -31,6 +31,13 @@ static int is_authenticated(struct ceph_auth_client *ac) | |||
31 | return !xi->starting; | 31 | return !xi->starting; |
32 | } | 32 | } |
33 | 33 | ||
34 | static int should_authenticate(struct ceph_auth_client *ac) | ||
35 | { | ||
36 | struct ceph_auth_none_info *xi = ac->private; | ||
37 | |||
38 | return xi->starting; | ||
39 | } | ||
40 | |||
34 | /* | 41 | /* |
35 | * the generic auth code decode the global_id, and we carry no actual | 42 | * the generic auth code decode the global_id, and we carry no actual |
36 | * authenticate state, so nothing happens here. | 43 | * authenticate state, so nothing happens here. |
@@ -98,6 +105,7 @@ static const struct ceph_auth_client_ops ceph_auth_none_ops = { | |||
98 | .reset = reset, | 105 | .reset = reset, |
99 | .destroy = destroy, | 106 | .destroy = destroy, |
100 | .is_authenticated = is_authenticated, | 107 | .is_authenticated = is_authenticated, |
108 | .should_authenticate = should_authenticate, | ||
101 | .handle_reply = handle_reply, | 109 | .handle_reply = handle_reply, |
102 | .create_authorizer = ceph_auth_none_create_authorizer, | 110 | .create_authorizer = ceph_auth_none_create_authorizer, |
103 | .destroy_authorizer = ceph_auth_none_destroy_authorizer, | 111 | .destroy_authorizer = ceph_auth_none_destroy_authorizer, |
diff --git a/fs/ceph/auth_x.c b/fs/ceph/auth_x.c index 7b206231566d..83d4d2785ffe 100644 --- a/fs/ceph/auth_x.c +++ b/fs/ceph/auth_x.c | |||
@@ -27,6 +27,17 @@ static int ceph_x_is_authenticated(struct ceph_auth_client *ac) | |||
27 | return (ac->want_keys & xi->have_keys) == ac->want_keys; | 27 | return (ac->want_keys & xi->have_keys) == ac->want_keys; |
28 | } | 28 | } |
29 | 29 | ||
30 | static int ceph_x_should_authenticate(struct ceph_auth_client *ac) | ||
31 | { | ||
32 | struct ceph_x_info *xi = ac->private; | ||
33 | int need; | ||
34 | |||
35 | ceph_x_validate_tickets(ac, &need); | ||
36 | dout("ceph_x_should_authenticate want=%d need=%d have=%d\n", | ||
37 | ac->want_keys, need, xi->have_keys); | ||
38 | return need != 0; | ||
39 | } | ||
40 | |||
30 | static int ceph_x_encrypt_buflen(int ilen) | 41 | static int ceph_x_encrypt_buflen(int ilen) |
31 | { | 42 | { |
32 | return sizeof(struct ceph_x_encrypt_header) + ilen + 16 + | 43 | return sizeof(struct ceph_x_encrypt_header) + ilen + 16 + |
@@ -620,6 +631,7 @@ static void ceph_x_invalidate_authorizer(struct ceph_auth_client *ac, | |||
620 | static const struct ceph_auth_client_ops ceph_x_ops = { | 631 | static const struct ceph_auth_client_ops ceph_x_ops = { |
621 | .name = "x", | 632 | .name = "x", |
622 | .is_authenticated = ceph_x_is_authenticated, | 633 | .is_authenticated = ceph_x_is_authenticated, |
634 | .should_authenticate = ceph_x_should_authenticate, | ||
623 | .build_request = ceph_x_build_request, | 635 | .build_request = ceph_x_build_request, |
624 | .handle_reply = ceph_x_handle_reply, | 636 | .handle_reply = ceph_x_handle_reply, |
625 | .create_authorizer = ceph_x_create_authorizer, | 637 | .create_authorizer = ceph_x_create_authorizer, |
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 0dd0b81e64f7..ae3e3a306445 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c | |||
@@ -1776,9 +1776,9 @@ out: | |||
1776 | spin_unlock(&ci->i_unsafe_lock); | 1776 | spin_unlock(&ci->i_unsafe_lock); |
1777 | } | 1777 | } |
1778 | 1778 | ||
1779 | int ceph_fsync(struct file *file, struct dentry *dentry, int datasync) | 1779 | int ceph_fsync(struct file *file, int datasync) |
1780 | { | 1780 | { |
1781 | struct inode *inode = dentry->d_inode; | 1781 | struct inode *inode = file->f_mapping->host; |
1782 | struct ceph_inode_info *ci = ceph_inode(inode); | 1782 | struct ceph_inode_info *ci = ceph_inode(inode); |
1783 | unsigned flush_tid; | 1783 | unsigned flush_tid; |
1784 | int ret; | 1784 | int ret; |
diff --git a/fs/ceph/ceph_fs.h b/fs/ceph/ceph_fs.h index 3b9eeed097b3..2fa992eaf7da 100644 --- a/fs/ceph/ceph_fs.h +++ b/fs/ceph/ceph_fs.h | |||
@@ -265,16 +265,17 @@ extern const char *ceph_mds_state_name(int s); | |||
265 | * - they also define the lock ordering by the MDS | 265 | * - they also define the lock ordering by the MDS |
266 | * - a few of these are internal to the mds | 266 | * - a few of these are internal to the mds |
267 | */ | 267 | */ |
268 | #define CEPH_LOCK_DN 1 | 268 | #define CEPH_LOCK_DVERSION 1 |
269 | #define CEPH_LOCK_ISNAP 2 | 269 | #define CEPH_LOCK_DN 2 |
270 | #define CEPH_LOCK_IVERSION 4 /* mds internal */ | 270 | #define CEPH_LOCK_ISNAP 16 |
271 | #define CEPH_LOCK_IFILE 8 /* mds internal */ | 271 | #define CEPH_LOCK_IVERSION 32 /* mds internal */ |
272 | #define CEPH_LOCK_IAUTH 32 | 272 | #define CEPH_LOCK_IFILE 64 |
273 | #define CEPH_LOCK_ILINK 64 | 273 | #define CEPH_LOCK_IAUTH 128 |
274 | #define CEPH_LOCK_IDFT 128 /* dir frag tree */ | 274 | #define CEPH_LOCK_ILINK 256 |
275 | #define CEPH_LOCK_INEST 256 /* mds internal */ | 275 | #define CEPH_LOCK_IDFT 512 /* dir frag tree */ |
276 | #define CEPH_LOCK_IXATTR 512 | 276 | #define CEPH_LOCK_INEST 1024 /* mds internal */ |
277 | #define CEPH_LOCK_INO 2048 /* immutable inode bits; not a lock */ | 277 | #define CEPH_LOCK_IXATTR 2048 |
278 | #define CEPH_LOCK_INO 8192 /* immutable inode bits; not a lock */ | ||
278 | 279 | ||
279 | /* client_session ops */ | 280 | /* client_session ops */ |
280 | enum { | 281 | enum { |
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 4fd30900eff7..f85719310db2 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
@@ -587,7 +587,7 @@ static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry, | |||
587 | CEPH_MDS_OP_LOOKUPSNAP : CEPH_MDS_OP_LOOKUP; | 587 | CEPH_MDS_OP_LOOKUPSNAP : CEPH_MDS_OP_LOOKUP; |
588 | req = ceph_mdsc_create_request(mdsc, op, USE_ANY_MDS); | 588 | req = ceph_mdsc_create_request(mdsc, op, USE_ANY_MDS); |
589 | if (IS_ERR(req)) | 589 | if (IS_ERR(req)) |
590 | return ERR_PTR(PTR_ERR(req)); | 590 | return ERR_CAST(req); |
591 | req->r_dentry = dget(dentry); | 591 | req->r_dentry = dget(dentry); |
592 | req->r_num_caps = 2; | 592 | req->r_num_caps = 2; |
593 | /* we only need inode linkage */ | 593 | /* we only need inode linkage */ |
@@ -1107,10 +1107,9 @@ static ssize_t ceph_read_dir(struct file *file, char __user *buf, size_t size, | |||
1107 | * an fsync() on a dir will wait for any uncommitted directory | 1107 | * an fsync() on a dir will wait for any uncommitted directory |
1108 | * operations to commit. | 1108 | * operations to commit. |
1109 | */ | 1109 | */ |
1110 | static int ceph_dir_fsync(struct file *file, struct dentry *dentry, | 1110 | static int ceph_dir_fsync(struct file *file, int datasync) |
1111 | int datasync) | ||
1112 | { | 1111 | { |
1113 | struct inode *inode = dentry->d_inode; | 1112 | struct inode *inode = file->f_path.dentry->d_inode; |
1114 | struct ceph_inode_info *ci = ceph_inode(inode); | 1113 | struct ceph_inode_info *ci = ceph_inode(inode); |
1115 | struct list_head *head = &ci->i_unsafe_dirops; | 1114 | struct list_head *head = &ci->i_unsafe_dirops; |
1116 | struct ceph_mds_request *req; | 1115 | struct ceph_mds_request *req; |
diff --git a/fs/ceph/export.c b/fs/ceph/export.c index 17447644d675..4480cb1c63e7 100644 --- a/fs/ceph/export.c +++ b/fs/ceph/export.c | |||
@@ -133,7 +133,7 @@ static struct dentry *__cfh_to_dentry(struct super_block *sb, | |||
133 | req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LOOKUPHASH, | 133 | req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LOOKUPHASH, |
134 | USE_ANY_MDS); | 134 | USE_ANY_MDS); |
135 | if (IS_ERR(req)) | 135 | if (IS_ERR(req)) |
136 | return ERR_PTR(PTR_ERR(req)); | 136 | return ERR_CAST(req); |
137 | 137 | ||
138 | req->r_ino1 = vino; | 138 | req->r_ino1 = vino; |
139 | req->r_ino2.ino = cfh->parent_ino; | 139 | req->r_ino2.ino = cfh->parent_ino; |
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 6512b6701b9e..6251a1574b94 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c | |||
@@ -230,7 +230,7 @@ struct dentry *ceph_lookup_open(struct inode *dir, struct dentry *dentry, | |||
230 | /* do the open */ | 230 | /* do the open */ |
231 | req = prepare_open_request(dir->i_sb, flags, mode); | 231 | req = prepare_open_request(dir->i_sb, flags, mode); |
232 | if (IS_ERR(req)) | 232 | if (IS_ERR(req)) |
233 | return ERR_PTR(PTR_ERR(req)); | 233 | return ERR_CAST(req); |
234 | req->r_dentry = dget(dentry); | 234 | req->r_dentry = dget(dentry); |
235 | req->r_num_caps = 2; | 235 | req->r_num_caps = 2; |
236 | if (flags & O_CREAT) { | 236 | if (flags & O_CREAT) { |
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index a81b8b662c7b..226f5a50d362 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c | |||
@@ -69,7 +69,7 @@ struct inode *ceph_get_snapdir(struct inode *parent) | |||
69 | 69 | ||
70 | BUG_ON(!S_ISDIR(parent->i_mode)); | 70 | BUG_ON(!S_ISDIR(parent->i_mode)); |
71 | if (IS_ERR(inode)) | 71 | if (IS_ERR(inode)) |
72 | return ERR_PTR(PTR_ERR(inode)); | 72 | return inode; |
73 | inode->i_mode = parent->i_mode; | 73 | inode->i_mode = parent->i_mode; |
74 | inode->i_uid = parent->i_uid; | 74 | inode->i_uid = parent->i_uid; |
75 | inode->i_gid = parent->i_gid; | 75 | inode->i_gid = parent->i_gid; |
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 885aa5710cfd..b49f12822cbc 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c | |||
@@ -1768,12 +1768,12 @@ int ceph_mdsc_do_request(struct ceph_mds_client *mdsc, | |||
1768 | mutex_unlock(&mdsc->mutex); | 1768 | mutex_unlock(&mdsc->mutex); |
1769 | dout("do_request waiting\n"); | 1769 | dout("do_request waiting\n"); |
1770 | if (req->r_timeout) { | 1770 | if (req->r_timeout) { |
1771 | err = (long)wait_for_completion_interruptible_timeout( | 1771 | err = (long)wait_for_completion_killable_timeout( |
1772 | &req->r_completion, req->r_timeout); | 1772 | &req->r_completion, req->r_timeout); |
1773 | if (err == 0) | 1773 | if (err == 0) |
1774 | err = -EIO; | 1774 | err = -EIO; |
1775 | } else { | 1775 | } else { |
1776 | err = wait_for_completion_interruptible(&req->r_completion); | 1776 | err = wait_for_completion_killable(&req->r_completion); |
1777 | } | 1777 | } |
1778 | dout("do_request waited, got %d\n", err); | 1778 | dout("do_request waited, got %d\n", err); |
1779 | mutex_lock(&mdsc->mutex); | 1779 | mutex_lock(&mdsc->mutex); |
@@ -2014,16 +2014,21 @@ static void handle_forward(struct ceph_mds_client *mdsc, | |||
2014 | mutex_lock(&mdsc->mutex); | 2014 | mutex_lock(&mdsc->mutex); |
2015 | req = __lookup_request(mdsc, tid); | 2015 | req = __lookup_request(mdsc, tid); |
2016 | if (!req) { | 2016 | if (!req) { |
2017 | dout("forward %llu to mds%d - req dne\n", tid, next_mds); | 2017 | dout("forward tid %llu to mds%d - req dne\n", tid, next_mds); |
2018 | goto out; /* dup reply? */ | 2018 | goto out; /* dup reply? */ |
2019 | } | 2019 | } |
2020 | 2020 | ||
2021 | if (fwd_seq <= req->r_num_fwd) { | 2021 | if (req->r_aborted) { |
2022 | dout("forward %llu to mds%d - old seq %d <= %d\n", | 2022 | dout("forward tid %llu aborted, unregistering\n", tid); |
2023 | __unregister_request(mdsc, req); | ||
2024 | } else if (fwd_seq <= req->r_num_fwd) { | ||
2025 | dout("forward tid %llu to mds%d - old seq %d <= %d\n", | ||
2023 | tid, next_mds, req->r_num_fwd, fwd_seq); | 2026 | tid, next_mds, req->r_num_fwd, fwd_seq); |
2024 | } else { | 2027 | } else { |
2025 | /* resend. forward race not possible; mds would drop */ | 2028 | /* resend. forward race not possible; mds would drop */ |
2026 | dout("forward %llu to mds%d (we resend)\n", tid, next_mds); | 2029 | dout("forward tid %llu to mds%d (we resend)\n", tid, next_mds); |
2030 | BUG_ON(req->r_err); | ||
2031 | BUG_ON(req->r_got_result); | ||
2027 | req->r_num_fwd = fwd_seq; | 2032 | req->r_num_fwd = fwd_seq; |
2028 | req->r_resend_mds = next_mds; | 2033 | req->r_resend_mds = next_mds; |
2029 | put_request_session(req); | 2034 | put_request_session(req); |
@@ -2541,7 +2546,7 @@ void ceph_mdsc_lease_send_msg(struct ceph_mds_session *session, | |||
2541 | return; | 2546 | return; |
2542 | lease = msg->front.iov_base; | 2547 | lease = msg->front.iov_base; |
2543 | lease->action = action; | 2548 | lease->action = action; |
2544 | lease->mask = cpu_to_le16(CEPH_LOCK_DN); | 2549 | lease->mask = cpu_to_le16(1); |
2545 | lease->ino = cpu_to_le64(ceph_vino(inode).ino); | 2550 | lease->ino = cpu_to_le64(ceph_vino(inode).ino); |
2546 | lease->first = lease->last = cpu_to_le64(ceph_vino(inode).snap); | 2551 | lease->first = lease->last = cpu_to_le64(ceph_vino(inode).snap); |
2547 | lease->seq = cpu_to_le32(seq); | 2552 | lease->seq = cpu_to_le32(seq); |
@@ -2571,7 +2576,7 @@ void ceph_mdsc_lease_release(struct ceph_mds_client *mdsc, struct inode *inode, | |||
2571 | 2576 | ||
2572 | BUG_ON(inode == NULL); | 2577 | BUG_ON(inode == NULL); |
2573 | BUG_ON(dentry == NULL); | 2578 | BUG_ON(dentry == NULL); |
2574 | BUG_ON(mask != CEPH_LOCK_DN); | 2579 | BUG_ON(mask == 0); |
2575 | 2580 | ||
2576 | /* is dentry lease valid? */ | 2581 | /* is dentry lease valid? */ |
2577 | spin_lock(&dentry->d_lock); | 2582 | spin_lock(&dentry->d_lock); |
diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index 60b74839ebec..64b8b1f7863d 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c | |||
@@ -120,6 +120,12 @@ void ceph_msgr_exit(void) | |||
120 | destroy_workqueue(ceph_msgr_wq); | 120 | destroy_workqueue(ceph_msgr_wq); |
121 | } | 121 | } |
122 | 122 | ||
123 | void ceph_msgr_flush() | ||
124 | { | ||
125 | flush_workqueue(ceph_msgr_wq); | ||
126 | } | ||
127 | |||
128 | |||
123 | /* | 129 | /* |
124 | * socket callback functions | 130 | * socket callback functions |
125 | */ | 131 | */ |
diff --git a/fs/ceph/messenger.h b/fs/ceph/messenger.h index 00a9430b1ffc..76fbc957bc13 100644 --- a/fs/ceph/messenger.h +++ b/fs/ceph/messenger.h | |||
@@ -213,6 +213,7 @@ extern int ceph_parse_ips(const char *c, const char *end, | |||
213 | 213 | ||
214 | extern int ceph_msgr_init(void); | 214 | extern int ceph_msgr_init(void); |
215 | extern void ceph_msgr_exit(void); | 215 | extern void ceph_msgr_exit(void); |
216 | extern void ceph_msgr_flush(void); | ||
216 | 217 | ||
217 | extern struct ceph_messenger *ceph_messenger_create( | 218 | extern struct ceph_messenger *ceph_messenger_create( |
218 | struct ceph_entity_addr *myaddr); | 219 | struct ceph_entity_addr *myaddr); |
diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c index f6510a476e7e..21c62e9b7d1d 100644 --- a/fs/ceph/mon_client.c +++ b/fs/ceph/mon_client.c | |||
@@ -704,8 +704,11 @@ static void handle_auth_reply(struct ceph_mon_client *monc, | |||
704 | struct ceph_msg *msg) | 704 | struct ceph_msg *msg) |
705 | { | 705 | { |
706 | int ret; | 706 | int ret; |
707 | int was_auth = 0; | ||
707 | 708 | ||
708 | mutex_lock(&monc->mutex); | 709 | mutex_lock(&monc->mutex); |
710 | if (monc->auth->ops) | ||
711 | was_auth = monc->auth->ops->is_authenticated(monc->auth); | ||
709 | monc->pending_auth = 0; | 712 | monc->pending_auth = 0; |
710 | ret = ceph_handle_auth_reply(monc->auth, msg->front.iov_base, | 713 | ret = ceph_handle_auth_reply(monc->auth, msg->front.iov_base, |
711 | msg->front.iov_len, | 714 | msg->front.iov_len, |
@@ -716,7 +719,7 @@ static void handle_auth_reply(struct ceph_mon_client *monc, | |||
716 | wake_up(&monc->client->auth_wq); | 719 | wake_up(&monc->client->auth_wq); |
717 | } else if (ret > 0) { | 720 | } else if (ret > 0) { |
718 | __send_prepared_auth_request(monc, ret); | 721 | __send_prepared_auth_request(monc, ret); |
719 | } else if (monc->auth->ops->is_authenticated(monc->auth)) { | 722 | } else if (!was_auth && monc->auth->ops->is_authenticated(monc->auth)) { |
720 | dout("authenticated, starting session\n"); | 723 | dout("authenticated, starting session\n"); |
721 | 724 | ||
722 | monc->client->msgr->inst.name.type = CEPH_ENTITY_TYPE_CLIENT; | 725 | monc->client->msgr->inst.name.type = CEPH_ENTITY_TYPE_CLIENT; |
diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index afa7bb3895c4..d25b4add85b4 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c | |||
@@ -361,8 +361,13 @@ static void put_osd(struct ceph_osd *osd) | |||
361 | { | 361 | { |
362 | dout("put_osd %p %d -> %d\n", osd, atomic_read(&osd->o_ref), | 362 | dout("put_osd %p %d -> %d\n", osd, atomic_read(&osd->o_ref), |
363 | atomic_read(&osd->o_ref) - 1); | 363 | atomic_read(&osd->o_ref) - 1); |
364 | if (atomic_dec_and_test(&osd->o_ref)) | 364 | if (atomic_dec_and_test(&osd->o_ref)) { |
365 | struct ceph_auth_client *ac = osd->o_osdc->client->monc.auth; | ||
366 | |||
367 | if (osd->o_authorizer) | ||
368 | ac->ops->destroy_authorizer(ac, osd->o_authorizer); | ||
365 | kfree(osd); | 369 | kfree(osd); |
370 | } | ||
366 | } | 371 | } |
367 | 372 | ||
368 | /* | 373 | /* |
diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c index cfdd8f4388b7..ddc656fb5c05 100644 --- a/fs/ceph/osdmap.c +++ b/fs/ceph/osdmap.c | |||
@@ -706,7 +706,7 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, | |||
706 | len, *p, end); | 706 | len, *p, end); |
707 | newcrush = crush_decode(*p, min(*p+len, end)); | 707 | newcrush = crush_decode(*p, min(*p+len, end)); |
708 | if (IS_ERR(newcrush)) | 708 | if (IS_ERR(newcrush)) |
709 | return ERR_PTR(PTR_ERR(newcrush)); | 709 | return ERR_CAST(newcrush); |
710 | } | 710 | } |
711 | 711 | ||
712 | /* new flags? */ | 712 | /* new flags? */ |
diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 7c663d9b9f81..4e0bee240b9d 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c | |||
@@ -669,9 +669,17 @@ static void ceph_destroy_client(struct ceph_client *client) | |||
669 | 669 | ||
670 | /* unmount */ | 670 | /* unmount */ |
671 | ceph_mdsc_stop(&client->mdsc); | 671 | ceph_mdsc_stop(&client->mdsc); |
672 | ceph_monc_stop(&client->monc); | ||
673 | ceph_osdc_stop(&client->osdc); | 672 | ceph_osdc_stop(&client->osdc); |
674 | 673 | ||
674 | /* | ||
675 | * make sure mds and osd connections close out before destroying | ||
676 | * the auth module, which is needed to free those connections' | ||
677 | * ceph_authorizers. | ||
678 | */ | ||
679 | ceph_msgr_flush(); | ||
680 | |||
681 | ceph_monc_stop(&client->monc); | ||
682 | |||
675 | ceph_adjust_min_caps(-client->min_caps); | 683 | ceph_adjust_min_caps(-client->min_caps); |
676 | 684 | ||
677 | ceph_debugfs_client_cleanup(client); | 685 | ceph_debugfs_client_cleanup(client); |
@@ -738,7 +746,7 @@ static struct dentry *open_root_dentry(struct ceph_client *client, | |||
738 | dout("open_root_inode opening '%s'\n", path); | 746 | dout("open_root_inode opening '%s'\n", path); |
739 | req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_GETATTR, USE_ANY_MDS); | 747 | req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_GETATTR, USE_ANY_MDS); |
740 | if (IS_ERR(req)) | 748 | if (IS_ERR(req)) |
741 | return ERR_PTR(PTR_ERR(req)); | 749 | return ERR_CAST(req); |
742 | req->r_path1 = kstrdup(path, GFP_NOFS); | 750 | req->r_path1 = kstrdup(path, GFP_NOFS); |
743 | req->r_ino1.ino = CEPH_INO_ROOT; | 751 | req->r_ino1.ino = CEPH_INO_ROOT; |
744 | req->r_ino1.snap = CEPH_NOSNAP; | 752 | req->r_ino1.snap = CEPH_NOSNAP; |
diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 3725c9ee9d08..10a4a406e887 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h | |||
@@ -10,7 +10,6 @@ | |||
10 | #include <linux/fs.h> | 10 | #include <linux/fs.h> |
11 | #include <linux/mempool.h> | 11 | #include <linux/mempool.h> |
12 | #include <linux/pagemap.h> | 12 | #include <linux/pagemap.h> |
13 | #include <linux/slab.h> | ||
14 | #include <linux/wait.h> | 13 | #include <linux/wait.h> |
15 | #include <linux/writeback.h> | 14 | #include <linux/writeback.h> |
16 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
@@ -811,7 +810,7 @@ extern void ceph_put_cap(struct ceph_cap *cap); | |||
811 | 810 | ||
812 | extern void ceph_queue_caps_release(struct inode *inode); | 811 | extern void ceph_queue_caps_release(struct inode *inode); |
813 | extern int ceph_write_inode(struct inode *inode, struct writeback_control *wbc); | 812 | extern int ceph_write_inode(struct inode *inode, struct writeback_control *wbc); |
814 | extern int ceph_fsync(struct file *file, struct dentry *dentry, int datasync); | 813 | extern int ceph_fsync(struct file *file, int datasync); |
815 | extern void ceph_kick_flushing_caps(struct ceph_mds_client *mdsc, | 814 | extern void ceph_kick_flushing_caps(struct ceph_mds_client *mdsc, |
816 | struct ceph_mds_session *session); | 815 | struct ceph_mds_session *session); |
817 | extern int ceph_get_cap_mds(struct inode *inode); | 816 | extern int ceph_get_cap_mds(struct inode *inode); |
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 0242ff9cbf41..a7eb65c84b1c 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h | |||
@@ -84,7 +84,7 @@ extern ssize_t cifs_user_read(struct file *file, char __user *read_data, | |||
84 | extern ssize_t cifs_user_write(struct file *file, const char __user *write_data, | 84 | extern ssize_t cifs_user_write(struct file *file, const char __user *write_data, |
85 | size_t write_size, loff_t *poffset); | 85 | size_t write_size, loff_t *poffset); |
86 | extern int cifs_lock(struct file *, int, struct file_lock *); | 86 | extern int cifs_lock(struct file *, int, struct file_lock *); |
87 | extern int cifs_fsync(struct file *, struct dentry *, int); | 87 | extern int cifs_fsync(struct file *, int); |
88 | extern int cifs_flush(struct file *, fl_owner_t id); | 88 | extern int cifs_flush(struct file *, fl_owner_t id); |
89 | extern int cifs_file_mmap(struct file * , struct vm_area_struct *); | 89 | extern int cifs_file_mmap(struct file * , struct vm_area_struct *); |
90 | extern const struct file_operations cifs_dir_ops; | 90 | extern const struct file_operations cifs_dir_ops; |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index a83541ec9713..f1ff785b2292 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -1676,7 +1676,7 @@ static int cifs_write_end(struct file *file, struct address_space *mapping, | |||
1676 | return rc; | 1676 | return rc; |
1677 | } | 1677 | } |
1678 | 1678 | ||
1679 | int cifs_fsync(struct file *file, struct dentry *dentry, int datasync) | 1679 | int cifs_fsync(struct file *file, int datasync) |
1680 | { | 1680 | { |
1681 | int xid; | 1681 | int xid; |
1682 | int rc = 0; | 1682 | int rc = 0; |
@@ -1688,7 +1688,7 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync) | |||
1688 | xid = GetXid(); | 1688 | xid = GetXid(); |
1689 | 1689 | ||
1690 | cFYI(1, "Sync file - name: %s datasync: 0x%x", | 1690 | cFYI(1, "Sync file - name: %s datasync: 0x%x", |
1691 | dentry->d_name.name, datasync); | 1691 | file->f_path.dentry->d_name.name, datasync); |
1692 | 1692 | ||
1693 | rc = filemap_write_and_wait(inode->i_mapping); | 1693 | rc = filemap_write_and_wait(inode->i_mapping); |
1694 | if (rc == 0) { | 1694 | if (rc == 0) { |
diff --git a/fs/coda/coda_int.h b/fs/coda/coda_int.h index d99860a33890..6b443ff43a19 100644 --- a/fs/coda/coda_int.h +++ b/fs/coda/coda_int.h | |||
@@ -11,8 +11,7 @@ extern int coda_fake_statfs; | |||
11 | 11 | ||
12 | void coda_destroy_inodecache(void); | 12 | void coda_destroy_inodecache(void); |
13 | int coda_init_inodecache(void); | 13 | int coda_init_inodecache(void); |
14 | int coda_fsync(struct file *coda_file, struct dentry *coda_dentry, | 14 | int coda_fsync(struct file *coda_file, int datasync); |
15 | int datasync); | ||
16 | void coda_sysctl_init(void); | 15 | void coda_sysctl_init(void); |
17 | void coda_sysctl_clean(void); | 16 | void coda_sysctl_clean(void); |
18 | 17 | ||
diff --git a/fs/coda/file.c b/fs/coda/file.c index 7196077b1688..ad3cd2abeeb4 100644 --- a/fs/coda/file.c +++ b/fs/coda/file.c | |||
@@ -202,10 +202,10 @@ int coda_release(struct inode *coda_inode, struct file *coda_file) | |||
202 | return 0; | 202 | return 0; |
203 | } | 203 | } |
204 | 204 | ||
205 | int coda_fsync(struct file *coda_file, struct dentry *coda_dentry, int datasync) | 205 | int coda_fsync(struct file *coda_file, int datasync) |
206 | { | 206 | { |
207 | struct file *host_file; | 207 | struct file *host_file; |
208 | struct inode *coda_inode = coda_dentry->d_inode; | 208 | struct inode *coda_inode = coda_file->f_path.dentry->d_inode; |
209 | struct coda_file_info *cfi; | 209 | struct coda_file_info *cfi; |
210 | int err = 0; | 210 | int err = 0; |
211 | 211 | ||
diff --git a/fs/configfs/inode.c b/fs/configfs/inode.c index c8af2d91174b..41645142b88b 100644 --- a/fs/configfs/inode.c +++ b/fs/configfs/inode.c | |||
@@ -72,16 +72,11 @@ int configfs_setattr(struct dentry * dentry, struct iattr * iattr) | |||
72 | if (!sd) | 72 | if (!sd) |
73 | return -EINVAL; | 73 | return -EINVAL; |
74 | 74 | ||
75 | sd_iattr = sd->s_iattr; | 75 | error = simple_setattr(dentry, iattr); |
76 | |||
77 | error = inode_change_ok(inode, iattr); | ||
78 | if (error) | ||
79 | return error; | ||
80 | |||
81 | error = inode_setattr(inode, iattr); | ||
82 | if (error) | 76 | if (error) |
83 | return error; | 77 | return error; |
84 | 78 | ||
79 | sd_iattr = sd->s_iattr; | ||
85 | if (!sd_iattr) { | 80 | if (!sd_iattr) { |
86 | /* setting attributes for the first time, allocate now */ | 81 | /* setting attributes for the first time, allocate now */ |
87 | sd_iattr = kzalloc(sizeof(struct iattr), GFP_KERNEL); | 82 | sd_iattr = kzalloc(sizeof(struct iattr), GFP_KERNEL); |
diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c index 4d74fc72c195..0210898458b2 100644 --- a/fs/debugfs/file.c +++ b/fs/debugfs/file.c | |||
@@ -277,8 +277,10 @@ DEFINE_SIMPLE_ATTRIBUTE(fops_x32, debugfs_u32_get, debugfs_u32_set, "0x%08llx\n" | |||
277 | DEFINE_SIMPLE_ATTRIBUTE(fops_x32_ro, debugfs_u32_get, NULL, "0x%08llx\n"); | 277 | DEFINE_SIMPLE_ATTRIBUTE(fops_x32_ro, debugfs_u32_get, NULL, "0x%08llx\n"); |
278 | DEFINE_SIMPLE_ATTRIBUTE(fops_x32_wo, NULL, debugfs_u32_set, "0x%08llx\n"); | 278 | DEFINE_SIMPLE_ATTRIBUTE(fops_x32_wo, NULL, debugfs_u32_set, "0x%08llx\n"); |
279 | 279 | ||
280 | DEFINE_SIMPLE_ATTRIBUTE(fops_x64, debugfs_u64_get, debugfs_u64_set, "0x%016llx\n"); | ||
281 | |||
280 | /* | 282 | /* |
281 | * debugfs_create_x{8,16,32} - create a debugfs file that is used to read and write an unsigned {8,16,32}-bit value | 283 | * debugfs_create_x{8,16,32,64} - create a debugfs file that is used to read and write an unsigned {8,16,32,64}-bit value |
282 | * | 284 | * |
283 | * These functions are exactly the same as the above functions (but use a hex | 285 | * These functions are exactly the same as the above functions (but use a hex |
284 | * output for the decimal challenged). For details look at the above unsigned | 286 | * output for the decimal challenged). For details look at the above unsigned |
@@ -357,6 +359,23 @@ struct dentry *debugfs_create_x32(const char *name, mode_t mode, | |||
357 | } | 359 | } |
358 | EXPORT_SYMBOL_GPL(debugfs_create_x32); | 360 | EXPORT_SYMBOL_GPL(debugfs_create_x32); |
359 | 361 | ||
362 | /** | ||
363 | * debugfs_create_x64 - create a debugfs file that is used to read and write an unsigned 64-bit value | ||
364 | * @name: a pointer to a string containing the name of the file to create. | ||
365 | * @mode: the permission that the file should have | ||
366 | * @parent: a pointer to the parent dentry for this file. This should be a | ||
367 | * directory dentry if set. If this parameter is %NULL, then the | ||
368 | * file will be created in the root of the debugfs filesystem. | ||
369 | * @value: a pointer to the variable that the file should read to and write | ||
370 | * from. | ||
371 | */ | ||
372 | struct dentry *debugfs_create_x64(const char *name, mode_t mode, | ||
373 | struct dentry *parent, u64 *value) | ||
374 | { | ||
375 | return debugfs_create_file(name, mode, parent, value, &fops_x64); | ||
376 | } | ||
377 | EXPORT_SYMBOL_GPL(debugfs_create_x64); | ||
378 | |||
360 | 379 | ||
361 | static int debugfs_size_t_set(void *data, u64 val) | 380 | static int debugfs_size_t_set(void *data, u64 val) |
362 | { | 381 | { |
diff --git a/fs/direct-io.c b/fs/direct-io.c index da111aacb46e..7600aacf531d 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c | |||
@@ -1134,27 +1134,8 @@ direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode, | |||
1134 | return ret; | 1134 | return ret; |
1135 | } | 1135 | } |
1136 | 1136 | ||
1137 | /* | ||
1138 | * This is a library function for use by filesystem drivers. | ||
1139 | * | ||
1140 | * The locking rules are governed by the flags parameter: | ||
1141 | * - if the flags value contains DIO_LOCKING we use a fancy locking | ||
1142 | * scheme for dumb filesystems. | ||
1143 | * For writes this function is called under i_mutex and returns with | ||
1144 | * i_mutex held, for reads, i_mutex is not held on entry, but it is | ||
1145 | * taken and dropped again before returning. | ||
1146 | * For reads and writes i_alloc_sem is taken in shared mode and released | ||
1147 | * on I/O completion (which may happen asynchronously after returning to | ||
1148 | * the caller). | ||
1149 | * | ||
1150 | * - if the flags value does NOT contain DIO_LOCKING we don't use any | ||
1151 | * internal locking but rather rely on the filesystem to synchronize | ||
1152 | * direct I/O reads/writes versus each other and truncate. | ||
1153 | * For reads and writes both i_mutex and i_alloc_sem are not held on | ||
1154 | * entry and are never taken. | ||
1155 | */ | ||
1156 | ssize_t | 1137 | ssize_t |
1157 | __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, | 1138 | __blockdev_direct_IO_newtrunc(int rw, struct kiocb *iocb, struct inode *inode, |
1158 | struct block_device *bdev, const struct iovec *iov, loff_t offset, | 1139 | struct block_device *bdev, const struct iovec *iov, loff_t offset, |
1159 | unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io, | 1140 | unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io, |
1160 | dio_submit_t submit_io, int flags) | 1141 | dio_submit_t submit_io, int flags) |
@@ -1247,9 +1228,46 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, | |||
1247 | nr_segs, blkbits, get_block, end_io, | 1228 | nr_segs, blkbits, get_block, end_io, |
1248 | submit_io, dio); | 1229 | submit_io, dio); |
1249 | 1230 | ||
1231 | out: | ||
1232 | return retval; | ||
1233 | } | ||
1234 | EXPORT_SYMBOL(__blockdev_direct_IO_newtrunc); | ||
1235 | |||
1236 | /* | ||
1237 | * This is a library function for use by filesystem drivers. | ||
1238 | * | ||
1239 | * The locking rules are governed by the flags parameter: | ||
1240 | * - if the flags value contains DIO_LOCKING we use a fancy locking | ||
1241 | * scheme for dumb filesystems. | ||
1242 | * For writes this function is called under i_mutex and returns with | ||
1243 | * i_mutex held, for reads, i_mutex is not held on entry, but it is | ||
1244 | * taken and dropped again before returning. | ||
1245 | * For reads and writes i_alloc_sem is taken in shared mode and released | ||
1246 | * on I/O completion (which may happen asynchronously after returning to | ||
1247 | * the caller). | ||
1248 | * | ||
1249 | * - if the flags value does NOT contain DIO_LOCKING we don't use any | ||
1250 | * internal locking but rather rely on the filesystem to synchronize | ||
1251 | * direct I/O reads/writes versus each other and truncate. | ||
1252 | * For reads and writes both i_mutex and i_alloc_sem are not held on | ||
1253 | * entry and are never taken. | ||
1254 | */ | ||
1255 | ssize_t | ||
1256 | __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, | ||
1257 | struct block_device *bdev, const struct iovec *iov, loff_t offset, | ||
1258 | unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io, | ||
1259 | dio_submit_t submit_io, int flags) | ||
1260 | { | ||
1261 | ssize_t retval; | ||
1262 | |||
1263 | retval = __blockdev_direct_IO_newtrunc(rw, iocb, inode, bdev, iov, | ||
1264 | offset, nr_segs, get_block, end_io, submit_io, flags); | ||
1250 | /* | 1265 | /* |
1251 | * In case of error extending write may have instantiated a few | 1266 | * In case of error extending write may have instantiated a few |
1252 | * blocks outside i_size. Trim these off again for DIO_LOCKING. | 1267 | * blocks outside i_size. Trim these off again for DIO_LOCKING. |
1268 | * NOTE: DIO_NO_LOCK/DIO_OWN_LOCK callers have to handle this in | ||
1269 | * their own manner. This is a further example of where the old | ||
1270 | * truncate sequence is inadequate. | ||
1253 | * | 1271 | * |
1254 | * NOTE: filesystems with their own locking have to handle this | 1272 | * NOTE: filesystems with their own locking have to handle this |
1255 | * on their own. | 1273 | * on their own. |
@@ -1257,12 +1275,13 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, | |||
1257 | if (flags & DIO_LOCKING) { | 1275 | if (flags & DIO_LOCKING) { |
1258 | if (unlikely((rw & WRITE) && retval < 0)) { | 1276 | if (unlikely((rw & WRITE) && retval < 0)) { |
1259 | loff_t isize = i_size_read(inode); | 1277 | loff_t isize = i_size_read(inode); |
1278 | loff_t end = offset + iov_length(iov, nr_segs); | ||
1279 | |||
1260 | if (end > isize) | 1280 | if (end > isize) |
1261 | vmtruncate(inode, isize); | 1281 | vmtruncate(inode, isize); |
1262 | } | 1282 | } |
1263 | } | 1283 | } |
1264 | 1284 | ||
1265 | out: | ||
1266 | return retval; | 1285 | return retval; |
1267 | } | 1286 | } |
1268 | EXPORT_SYMBOL(__blockdev_direct_IO); | 1287 | EXPORT_SYMBOL(__blockdev_direct_IO); |
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index 3bdddbcc785f..e8fcf4e2ed7d 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c | |||
@@ -274,7 +274,7 @@ static int ecryptfs_release(struct inode *inode, struct file *file) | |||
274 | } | 274 | } |
275 | 275 | ||
276 | static int | 276 | static int |
277 | ecryptfs_fsync(struct file *file, struct dentry *dentry, int datasync) | 277 | ecryptfs_fsync(struct file *file, int datasync) |
278 | { | 278 | { |
279 | return vfs_fsync(ecryptfs_file_to_lower(file), datasync); | 279 | return vfs_fsync(ecryptfs_file_to_lower(file), datasync); |
280 | } | 280 | } |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 65dee2f336ae..31ef5252f0fe 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -805,7 +805,7 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, | |||
805 | - (ia->ia_size & ~PAGE_CACHE_MASK)); | 805 | - (ia->ia_size & ~PAGE_CACHE_MASK)); |
806 | 806 | ||
807 | if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { | 807 | if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { |
808 | rc = vmtruncate(inode, ia->ia_size); | 808 | rc = simple_setsize(inode, ia->ia_size); |
809 | if (rc) | 809 | if (rc) |
810 | goto out; | 810 | goto out; |
811 | lower_ia->ia_size = ia->ia_size; | 811 | lower_ia->ia_size = ia->ia_size; |
@@ -830,7 +830,7 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, | |||
830 | goto out; | 830 | goto out; |
831 | } | 831 | } |
832 | } | 832 | } |
833 | vmtruncate(inode, ia->ia_size); | 833 | simple_setsize(inode, ia->ia_size); |
834 | rc = ecryptfs_write_inode_size_to_metadata(inode); | 834 | rc = ecryptfs_write_inode_size_to_metadata(inode); |
835 | if (rc) { | 835 | if (rc) { |
836 | printk(KERN_ERR "Problem with " | 836 | printk(KERN_ERR "Problem with " |
diff --git a/fs/exofs/file.c b/fs/exofs/file.c index 839b9dc1e70f..fef6899be397 100644 --- a/fs/exofs/file.c +++ b/fs/exofs/file.c | |||
@@ -40,12 +40,11 @@ static int exofs_release_file(struct inode *inode, struct file *filp) | |||
40 | return 0; | 40 | return 0; |
41 | } | 41 | } |
42 | 42 | ||
43 | static int exofs_file_fsync(struct file *filp, struct dentry *dentry, | 43 | static int exofs_file_fsync(struct file *filp, int datasync) |
44 | int datasync) | ||
45 | { | 44 | { |
46 | int ret; | 45 | int ret; |
47 | struct address_space *mapping = filp->f_mapping; | 46 | struct address_space *mapping = filp->f_mapping; |
48 | struct inode *inode = dentry->d_inode; | 47 | struct inode *inode = mapping->host; |
49 | struct super_block *sb; | 48 | struct super_block *sb; |
50 | 49 | ||
51 | ret = filemap_write_and_wait(mapping); | 50 | ret = filemap_write_and_wait(mapping); |
@@ -66,7 +65,7 @@ static int exofs_file_fsync(struct file *filp, struct dentry *dentry, | |||
66 | 65 | ||
67 | static int exofs_flush(struct file *file, fl_owner_t id) | 66 | static int exofs_flush(struct file *file, fl_owner_t id) |
68 | { | 67 | { |
69 | exofs_file_fsync(file, file->f_path.dentry, 1); | 68 | exofs_file_fsync(file, 1); |
70 | /* TODO: Flush the OSD target */ | 69 | /* TODO: Flush the OSD target */ |
71 | return 0; | 70 | return 0; |
72 | } | 71 | } |
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h index 0b038e47ad2f..52b34f1d2738 100644 --- a/fs/ext2/ext2.h +++ b/fs/ext2/ext2.h | |||
@@ -122,7 +122,6 @@ extern int ext2_write_inode (struct inode *, struct writeback_control *); | |||
122 | extern void ext2_delete_inode (struct inode *); | 122 | extern void ext2_delete_inode (struct inode *); |
123 | extern int ext2_sync_inode (struct inode *); | 123 | extern int ext2_sync_inode (struct inode *); |
124 | extern int ext2_get_block(struct inode *, sector_t, struct buffer_head *, int); | 124 | extern int ext2_get_block(struct inode *, sector_t, struct buffer_head *, int); |
125 | extern void ext2_truncate (struct inode *); | ||
126 | extern int ext2_setattr (struct dentry *, struct iattr *); | 125 | extern int ext2_setattr (struct dentry *, struct iattr *); |
127 | extern void ext2_set_inode_flags(struct inode *inode); | 126 | extern void ext2_set_inode_flags(struct inode *inode); |
128 | extern void ext2_get_inode_flags(struct ext2_inode_info *); | 127 | extern void ext2_get_inode_flags(struct ext2_inode_info *); |
@@ -155,7 +154,7 @@ extern void ext2_write_super (struct super_block *); | |||
155 | extern const struct file_operations ext2_dir_operations; | 154 | extern const struct file_operations ext2_dir_operations; |
156 | 155 | ||
157 | /* file.c */ | 156 | /* file.c */ |
158 | extern int ext2_fsync(struct file *file, struct dentry *dentry, int datasync); | 157 | extern int ext2_fsync(struct file *file, int datasync); |
159 | extern const struct inode_operations ext2_file_inode_operations; | 158 | extern const struct inode_operations ext2_file_inode_operations; |
160 | extern const struct file_operations ext2_file_operations; | 159 | extern const struct file_operations ext2_file_operations; |
161 | extern const struct file_operations ext2_xip_file_operations; | 160 | extern const struct file_operations ext2_xip_file_operations; |
diff --git a/fs/ext2/file.c b/fs/ext2/file.c index 5d198d0697fb..49eec9456c5b 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c | |||
@@ -40,13 +40,13 @@ static int ext2_release_file (struct inode * inode, struct file * filp) | |||
40 | return 0; | 40 | return 0; |
41 | } | 41 | } |
42 | 42 | ||
43 | int ext2_fsync(struct file *file, struct dentry *dentry, int datasync) | 43 | int ext2_fsync(struct file *file, int datasync) |
44 | { | 44 | { |
45 | int ret; | 45 | int ret; |
46 | struct super_block *sb = dentry->d_inode->i_sb; | 46 | struct super_block *sb = file->f_mapping->host->i_sb; |
47 | struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping; | 47 | struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping; |
48 | 48 | ||
49 | ret = simple_fsync(file, dentry, datasync); | 49 | ret = generic_file_fsync(file, datasync); |
50 | if (ret == -EIO || test_and_clear_bit(AS_EIO, &mapping->flags)) { | 50 | if (ret == -EIO || test_and_clear_bit(AS_EIO, &mapping->flags)) { |
51 | /* We don't really know where the IO error happened... */ | 51 | /* We don't really know where the IO error happened... */ |
52 | ext2_error(sb, __func__, | 52 | ext2_error(sb, __func__, |
@@ -95,7 +95,6 @@ const struct file_operations ext2_xip_file_operations = { | |||
95 | #endif | 95 | #endif |
96 | 96 | ||
97 | const struct inode_operations ext2_file_inode_operations = { | 97 | const struct inode_operations ext2_file_inode_operations = { |
98 | .truncate = ext2_truncate, | ||
99 | #ifdef CONFIG_EXT2_FS_XATTR | 98 | #ifdef CONFIG_EXT2_FS_XATTR |
100 | .setxattr = generic_setxattr, | 99 | .setxattr = generic_setxattr, |
101 | .getxattr = generic_getxattr, | 100 | .getxattr = generic_getxattr, |
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 527c46d9bc1f..19214435b752 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c | |||
@@ -54,6 +54,18 @@ static inline int ext2_inode_is_fast_symlink(struct inode *inode) | |||
54 | inode->i_blocks - ea_blocks == 0); | 54 | inode->i_blocks - ea_blocks == 0); |
55 | } | 55 | } |
56 | 56 | ||
57 | static void ext2_truncate_blocks(struct inode *inode, loff_t offset); | ||
58 | |||
59 | static void ext2_write_failed(struct address_space *mapping, loff_t to) | ||
60 | { | ||
61 | struct inode *inode = mapping->host; | ||
62 | |||
63 | if (to > inode->i_size) { | ||
64 | truncate_pagecache(inode, to, inode->i_size); | ||
65 | ext2_truncate_blocks(inode, inode->i_size); | ||
66 | } | ||
67 | } | ||
68 | |||
57 | /* | 69 | /* |
58 | * Called at the last iput() if i_nlink is zero. | 70 | * Called at the last iput() if i_nlink is zero. |
59 | */ | 71 | */ |
@@ -71,7 +83,7 @@ void ext2_delete_inode (struct inode * inode) | |||
71 | 83 | ||
72 | inode->i_size = 0; | 84 | inode->i_size = 0; |
73 | if (inode->i_blocks) | 85 | if (inode->i_blocks) |
74 | ext2_truncate (inode); | 86 | ext2_truncate_blocks(inode, 0); |
75 | ext2_free_inode (inode); | 87 | ext2_free_inode (inode); |
76 | 88 | ||
77 | return; | 89 | return; |
@@ -757,8 +769,8 @@ int __ext2_write_begin(struct file *file, struct address_space *mapping, | |||
757 | loff_t pos, unsigned len, unsigned flags, | 769 | loff_t pos, unsigned len, unsigned flags, |
758 | struct page **pagep, void **fsdata) | 770 | struct page **pagep, void **fsdata) |
759 | { | 771 | { |
760 | return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, | 772 | return block_write_begin_newtrunc(file, mapping, pos, len, flags, |
761 | ext2_get_block); | 773 | pagep, fsdata, ext2_get_block); |
762 | } | 774 | } |
763 | 775 | ||
764 | static int | 776 | static int |
@@ -766,8 +778,25 @@ ext2_write_begin(struct file *file, struct address_space *mapping, | |||
766 | loff_t pos, unsigned len, unsigned flags, | 778 | loff_t pos, unsigned len, unsigned flags, |
767 | struct page **pagep, void **fsdata) | 779 | struct page **pagep, void **fsdata) |
768 | { | 780 | { |
781 | int ret; | ||
782 | |||
769 | *pagep = NULL; | 783 | *pagep = NULL; |
770 | return __ext2_write_begin(file, mapping, pos, len, flags, pagep,fsdata); | 784 | ret = __ext2_write_begin(file, mapping, pos, len, flags, pagep, fsdata); |
785 | if (ret < 0) | ||
786 | ext2_write_failed(mapping, pos + len); | ||
787 | return ret; | ||
788 | } | ||
789 | |||
790 | static int ext2_write_end(struct file *file, struct address_space *mapping, | ||
791 | loff_t pos, unsigned len, unsigned copied, | ||
792 | struct page *page, void *fsdata) | ||
793 | { | ||
794 | int ret; | ||
795 | |||
796 | ret = generic_write_end(file, mapping, pos, len, copied, page, fsdata); | ||
797 | if (ret < len) | ||
798 | ext2_write_failed(mapping, pos + len); | ||
799 | return ret; | ||
771 | } | 800 | } |
772 | 801 | ||
773 | static int | 802 | static int |
@@ -775,13 +804,18 @@ ext2_nobh_write_begin(struct file *file, struct address_space *mapping, | |||
775 | loff_t pos, unsigned len, unsigned flags, | 804 | loff_t pos, unsigned len, unsigned flags, |
776 | struct page **pagep, void **fsdata) | 805 | struct page **pagep, void **fsdata) |
777 | { | 806 | { |
807 | int ret; | ||
808 | |||
778 | /* | 809 | /* |
779 | * Dir-in-pagecache still uses ext2_write_begin. Would have to rework | 810 | * Dir-in-pagecache still uses ext2_write_begin. Would have to rework |
780 | * directory handling code to pass around offsets rather than struct | 811 | * directory handling code to pass around offsets rather than struct |
781 | * pages in order to make this work easily. | 812 | * pages in order to make this work easily. |
782 | */ | 813 | */ |
783 | return nobh_write_begin(file, mapping, pos, len, flags, pagep, fsdata, | 814 | ret = nobh_write_begin_newtrunc(file, mapping, pos, len, flags, pagep, |
784 | ext2_get_block); | 815 | fsdata, ext2_get_block); |
816 | if (ret < 0) | ||
817 | ext2_write_failed(mapping, pos + len); | ||
818 | return ret; | ||
785 | } | 819 | } |
786 | 820 | ||
787 | static int ext2_nobh_writepage(struct page *page, | 821 | static int ext2_nobh_writepage(struct page *page, |
@@ -800,10 +834,15 @@ ext2_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, | |||
800 | loff_t offset, unsigned long nr_segs) | 834 | loff_t offset, unsigned long nr_segs) |
801 | { | 835 | { |
802 | struct file *file = iocb->ki_filp; | 836 | struct file *file = iocb->ki_filp; |
803 | struct inode *inode = file->f_mapping->host; | 837 | struct address_space *mapping = file->f_mapping; |
804 | 838 | struct inode *inode = mapping->host; | |
805 | return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, | 839 | ssize_t ret; |
806 | offset, nr_segs, ext2_get_block, NULL); | 840 | |
841 | ret = blockdev_direct_IO_newtrunc(rw, iocb, inode, inode->i_sb->s_bdev, | ||
842 | iov, offset, nr_segs, ext2_get_block, NULL); | ||
843 | if (ret < 0 && (rw & WRITE)) | ||
844 | ext2_write_failed(mapping, offset + iov_length(iov, nr_segs)); | ||
845 | return ret; | ||
807 | } | 846 | } |
808 | 847 | ||
809 | static int | 848 | static int |
@@ -818,7 +857,7 @@ const struct address_space_operations ext2_aops = { | |||
818 | .writepage = ext2_writepage, | 857 | .writepage = ext2_writepage, |
819 | .sync_page = block_sync_page, | 858 | .sync_page = block_sync_page, |
820 | .write_begin = ext2_write_begin, | 859 | .write_begin = ext2_write_begin, |
821 | .write_end = generic_write_end, | 860 | .write_end = ext2_write_end, |
822 | .bmap = ext2_bmap, | 861 | .bmap = ext2_bmap, |
823 | .direct_IO = ext2_direct_IO, | 862 | .direct_IO = ext2_direct_IO, |
824 | .writepages = ext2_writepages, | 863 | .writepages = ext2_writepages, |
@@ -1027,7 +1066,7 @@ static void ext2_free_branches(struct inode *inode, __le32 *p, __le32 *q, int de | |||
1027 | ext2_free_data(inode, p, q); | 1066 | ext2_free_data(inode, p, q); |
1028 | } | 1067 | } |
1029 | 1068 | ||
1030 | void ext2_truncate(struct inode *inode) | 1069 | static void __ext2_truncate_blocks(struct inode *inode, loff_t offset) |
1031 | { | 1070 | { |
1032 | __le32 *i_data = EXT2_I(inode)->i_data; | 1071 | __le32 *i_data = EXT2_I(inode)->i_data; |
1033 | struct ext2_inode_info *ei = EXT2_I(inode); | 1072 | struct ext2_inode_info *ei = EXT2_I(inode); |
@@ -1039,27 +1078,8 @@ void ext2_truncate(struct inode *inode) | |||
1039 | int n; | 1078 | int n; |
1040 | long iblock; | 1079 | long iblock; |
1041 | unsigned blocksize; | 1080 | unsigned blocksize; |
1042 | |||
1043 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || | ||
1044 | S_ISLNK(inode->i_mode))) | ||
1045 | return; | ||
1046 | if (ext2_inode_is_fast_symlink(inode)) | ||
1047 | return; | ||
1048 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) | ||
1049 | return; | ||
1050 | |||
1051 | blocksize = inode->i_sb->s_blocksize; | 1081 | blocksize = inode->i_sb->s_blocksize; |
1052 | iblock = (inode->i_size + blocksize-1) | 1082 | iblock = (offset + blocksize-1) >> EXT2_BLOCK_SIZE_BITS(inode->i_sb); |
1053 | >> EXT2_BLOCK_SIZE_BITS(inode->i_sb); | ||
1054 | |||
1055 | if (mapping_is_xip(inode->i_mapping)) | ||
1056 | xip_truncate_page(inode->i_mapping, inode->i_size); | ||
1057 | else if (test_opt(inode->i_sb, NOBH)) | ||
1058 | nobh_truncate_page(inode->i_mapping, | ||
1059 | inode->i_size, ext2_get_block); | ||
1060 | else | ||
1061 | block_truncate_page(inode->i_mapping, | ||
1062 | inode->i_size, ext2_get_block); | ||
1063 | 1083 | ||
1064 | n = ext2_block_to_path(inode, iblock, offsets, NULL); | 1084 | n = ext2_block_to_path(inode, iblock, offsets, NULL); |
1065 | if (n == 0) | 1085 | if (n == 0) |
@@ -1127,6 +1147,62 @@ do_indirects: | |||
1127 | ext2_discard_reservation(inode); | 1147 | ext2_discard_reservation(inode); |
1128 | 1148 | ||
1129 | mutex_unlock(&ei->truncate_mutex); | 1149 | mutex_unlock(&ei->truncate_mutex); |
1150 | } | ||
1151 | |||
1152 | static void ext2_truncate_blocks(struct inode *inode, loff_t offset) | ||
1153 | { | ||
1154 | /* | ||
1155 | * XXX: it seems like a bug here that we don't allow | ||
1156 | * IS_APPEND inode to have blocks-past-i_size trimmed off. | ||
1157 | * review and fix this. | ||
1158 | * | ||
1159 | * Also would be nice to be able to handle IO errors and such, | ||
1160 | * but that's probably too much to ask. | ||
1161 | */ | ||
1162 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || | ||
1163 | S_ISLNK(inode->i_mode))) | ||
1164 | return; | ||
1165 | if (ext2_inode_is_fast_symlink(inode)) | ||
1166 | return; | ||
1167 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) | ||
1168 | return; | ||
1169 | __ext2_truncate_blocks(inode, offset); | ||
1170 | } | ||
1171 | |||
1172 | int ext2_setsize(struct inode *inode, loff_t newsize) | ||
1173 | { | ||
1174 | loff_t oldsize; | ||
1175 | int error; | ||
1176 | |||
1177 | error = inode_newsize_ok(inode, newsize); | ||
1178 | if (error) | ||
1179 | return error; | ||
1180 | |||
1181 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || | ||
1182 | S_ISLNK(inode->i_mode))) | ||
1183 | return -EINVAL; | ||
1184 | if (ext2_inode_is_fast_symlink(inode)) | ||
1185 | return -EINVAL; | ||
1186 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) | ||
1187 | return -EPERM; | ||
1188 | |||
1189 | if (mapping_is_xip(inode->i_mapping)) | ||
1190 | error = xip_truncate_page(inode->i_mapping, newsize); | ||
1191 | else if (test_opt(inode->i_sb, NOBH)) | ||
1192 | error = nobh_truncate_page(inode->i_mapping, | ||
1193 | newsize, ext2_get_block); | ||
1194 | else | ||
1195 | error = block_truncate_page(inode->i_mapping, | ||
1196 | newsize, ext2_get_block); | ||
1197 | if (error) | ||
1198 | return error; | ||
1199 | |||
1200 | oldsize = inode->i_size; | ||
1201 | i_size_write(inode, newsize); | ||
1202 | truncate_pagecache(inode, oldsize, newsize); | ||
1203 | |||
1204 | __ext2_truncate_blocks(inode, newsize); | ||
1205 | |||
1130 | inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; | 1206 | inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; |
1131 | if (inode_needs_sync(inode)) { | 1207 | if (inode_needs_sync(inode)) { |
1132 | sync_mapping_buffers(inode->i_mapping); | 1208 | sync_mapping_buffers(inode->i_mapping); |
@@ -1134,6 +1210,8 @@ do_indirects: | |||
1134 | } else { | 1210 | } else { |
1135 | mark_inode_dirty(inode); | 1211 | mark_inode_dirty(inode); |
1136 | } | 1212 | } |
1213 | |||
1214 | return 0; | ||
1137 | } | 1215 | } |
1138 | 1216 | ||
1139 | static struct ext2_inode *ext2_get_inode(struct super_block *sb, ino_t ino, | 1217 | static struct ext2_inode *ext2_get_inode(struct super_block *sb, ino_t ino, |
@@ -1474,8 +1552,15 @@ int ext2_setattr(struct dentry *dentry, struct iattr *iattr) | |||
1474 | if (error) | 1552 | if (error) |
1475 | return error; | 1553 | return error; |
1476 | } | 1554 | } |
1477 | error = inode_setattr(inode, iattr); | 1555 | if (iattr->ia_valid & ATTR_SIZE) { |
1478 | if (!error && (iattr->ia_valid & ATTR_MODE)) | 1556 | error = ext2_setsize(inode, iattr->ia_size); |
1557 | if (error) | ||
1558 | return error; | ||
1559 | } | ||
1560 | generic_setattr(inode, iattr); | ||
1561 | if (iattr->ia_valid & ATTR_MODE) | ||
1479 | error = ext2_acl_chmod(inode); | 1562 | error = ext2_acl_chmod(inode); |
1563 | mark_inode_dirty(inode); | ||
1564 | |||
1480 | return error; | 1565 | return error; |
1481 | } | 1566 | } |
diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 71e9eb1fa696..7ff43f4a59cd 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c | |||
@@ -119,6 +119,8 @@ static void ext2_put_super (struct super_block * sb) | |||
119 | int i; | 119 | int i; |
120 | struct ext2_sb_info *sbi = EXT2_SB(sb); | 120 | struct ext2_sb_info *sbi = EXT2_SB(sb); |
121 | 121 | ||
122 | dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); | ||
123 | |||
122 | if (sb->s_dirt) | 124 | if (sb->s_dirt) |
123 | ext2_write_super(sb); | 125 | ext2_write_super(sb); |
124 | 126 | ||
@@ -1063,6 +1065,12 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) | |||
1063 | sb->s_op = &ext2_sops; | 1065 | sb->s_op = &ext2_sops; |
1064 | sb->s_export_op = &ext2_export_ops; | 1066 | sb->s_export_op = &ext2_export_ops; |
1065 | sb->s_xattr = ext2_xattr_handlers; | 1067 | sb->s_xattr = ext2_xattr_handlers; |
1068 | |||
1069 | #ifdef CONFIG_QUOTA | ||
1070 | sb->dq_op = &dquot_operations; | ||
1071 | sb->s_qcop = &dquot_quotactl_ops; | ||
1072 | #endif | ||
1073 | |||
1066 | root = ext2_iget(sb, EXT2_ROOT_INO); | 1074 | root = ext2_iget(sb, EXT2_ROOT_INO); |
1067 | if (IS_ERR(root)) { | 1075 | if (IS_ERR(root)) { |
1068 | ret = PTR_ERR(root); | 1076 | ret = PTR_ERR(root); |
@@ -1241,6 +1249,7 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data) | |||
1241 | spin_unlock(&sbi->s_lock); | 1249 | spin_unlock(&sbi->s_lock); |
1242 | return 0; | 1250 | return 0; |
1243 | } | 1251 | } |
1252 | |||
1244 | /* | 1253 | /* |
1245 | * OK, we are remounting a valid rw partition rdonly, so set | 1254 | * OK, we are remounting a valid rw partition rdonly, so set |
1246 | * the rdonly flag and then mark the partition as valid again. | 1255 | * the rdonly flag and then mark the partition as valid again. |
@@ -1248,6 +1257,13 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data) | |||
1248 | es->s_state = cpu_to_le16(sbi->s_mount_state); | 1257 | es->s_state = cpu_to_le16(sbi->s_mount_state); |
1249 | es->s_mtime = cpu_to_le32(get_seconds()); | 1258 | es->s_mtime = cpu_to_le32(get_seconds()); |
1250 | spin_unlock(&sbi->s_lock); | 1259 | spin_unlock(&sbi->s_lock); |
1260 | |||
1261 | err = dquot_suspend(sb, -1); | ||
1262 | if (err < 0) { | ||
1263 | spin_lock(&sbi->s_lock); | ||
1264 | goto restore_opts; | ||
1265 | } | ||
1266 | |||
1251 | ext2_sync_super(sb, es, 1); | 1267 | ext2_sync_super(sb, es, 1); |
1252 | } else { | 1268 | } else { |
1253 | __le32 ret = EXT2_HAS_RO_COMPAT_FEATURE(sb, | 1269 | __le32 ret = EXT2_HAS_RO_COMPAT_FEATURE(sb, |
@@ -1269,8 +1285,12 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data) | |||
1269 | if (!ext2_setup_super (sb, es, 0)) | 1285 | if (!ext2_setup_super (sb, es, 0)) |
1270 | sb->s_flags &= ~MS_RDONLY; | 1286 | sb->s_flags &= ~MS_RDONLY; |
1271 | spin_unlock(&sbi->s_lock); | 1287 | spin_unlock(&sbi->s_lock); |
1288 | |||
1272 | ext2_write_super(sb); | 1289 | ext2_write_super(sb); |
1290 | |||
1291 | dquot_resume(sb, -1); | ||
1273 | } | 1292 | } |
1293 | |||
1274 | return 0; | 1294 | return 0; |
1275 | restore_opts: | 1295 | restore_opts: |
1276 | sbi->s_mount_opt = old_opts.s_mount_opt; | 1296 | sbi->s_mount_opt = old_opts.s_mount_opt; |
diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c index 373fa90c796a..e2e72c367cf6 100644 --- a/fs/ext3/dir.c +++ b/fs/ext3/dir.c | |||
@@ -297,7 +297,7 @@ static void free_rb_tree_fname(struct rb_root *root) | |||
297 | kfree (old); | 297 | kfree (old); |
298 | } | 298 | } |
299 | if (!parent) | 299 | if (!parent) |
300 | root->rb_node = NULL; | 300 | *root = RB_ROOT; |
301 | else if (parent->rb_left == n) | 301 | else if (parent->rb_left == n) |
302 | parent->rb_left = NULL; | 302 | parent->rb_left = NULL; |
303 | else if (parent->rb_right == n) | 303 | else if (parent->rb_right == n) |
diff --git a/fs/ext3/fsync.c b/fs/ext3/fsync.c index fcf7487734b6..d7e9f74dc3a6 100644 --- a/fs/ext3/fsync.c +++ b/fs/ext3/fsync.c | |||
@@ -43,9 +43,9 @@ | |||
43 | * inode to disk. | 43 | * inode to disk. |
44 | */ | 44 | */ |
45 | 45 | ||
46 | int ext3_sync_file(struct file * file, struct dentry *dentry, int datasync) | 46 | int ext3_sync_file(struct file *file, int datasync) |
47 | { | 47 | { |
48 | struct inode *inode = dentry->d_inode; | 48 | struct inode *inode = file->f_mapping->host; |
49 | struct ext3_inode_info *ei = EXT3_I(inode); | 49 | struct ext3_inode_info *ei = EXT3_I(inode); |
50 | journal_t *journal = EXT3_SB(inode->i_sb)->s_journal; | 50 | journal_t *journal = EXT3_SB(inode->i_sb)->s_journal; |
51 | int ret, needs_barrier = 0; | 51 | int ret, needs_barrier = 0; |
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 0fc1293d0e96..6c953bb255e7 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -410,6 +410,8 @@ static void ext3_put_super (struct super_block * sb) | |||
410 | struct ext3_super_block *es = sbi->s_es; | 410 | struct ext3_super_block *es = sbi->s_es; |
411 | int i, err; | 411 | int i, err; |
412 | 412 | ||
413 | dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); | ||
414 | |||
413 | lock_kernel(); | 415 | lock_kernel(); |
414 | 416 | ||
415 | ext3_xattr_put_super(sb); | 417 | ext3_xattr_put_super(sb); |
@@ -748,7 +750,7 @@ static int ext3_release_dquot(struct dquot *dquot); | |||
748 | static int ext3_mark_dquot_dirty(struct dquot *dquot); | 750 | static int ext3_mark_dquot_dirty(struct dquot *dquot); |
749 | static int ext3_write_info(struct super_block *sb, int type); | 751 | static int ext3_write_info(struct super_block *sb, int type); |
750 | static int ext3_quota_on(struct super_block *sb, int type, int format_id, | 752 | static int ext3_quota_on(struct super_block *sb, int type, int format_id, |
751 | char *path, int remount); | 753 | char *path); |
752 | static int ext3_quota_on_mount(struct super_block *sb, int type); | 754 | static int ext3_quota_on_mount(struct super_block *sb, int type); |
753 | static ssize_t ext3_quota_read(struct super_block *sb, int type, char *data, | 755 | static ssize_t ext3_quota_read(struct super_block *sb, int type, char *data, |
754 | size_t len, loff_t off); | 756 | size_t len, loff_t off); |
@@ -767,12 +769,12 @@ static const struct dquot_operations ext3_quota_operations = { | |||
767 | 769 | ||
768 | static const struct quotactl_ops ext3_qctl_operations = { | 770 | static const struct quotactl_ops ext3_qctl_operations = { |
769 | .quota_on = ext3_quota_on, | 771 | .quota_on = ext3_quota_on, |
770 | .quota_off = vfs_quota_off, | 772 | .quota_off = dquot_quota_off, |
771 | .quota_sync = vfs_quota_sync, | 773 | .quota_sync = dquot_quota_sync, |
772 | .get_info = vfs_get_dqinfo, | 774 | .get_info = dquot_get_dqinfo, |
773 | .set_info = vfs_set_dqinfo, | 775 | .set_info = dquot_set_dqinfo, |
774 | .get_dqblk = vfs_get_dqblk, | 776 | .get_dqblk = dquot_get_dqblk, |
775 | .set_dqblk = vfs_set_dqblk | 777 | .set_dqblk = dquot_set_dqblk |
776 | }; | 778 | }; |
777 | #endif | 779 | #endif |
778 | 780 | ||
@@ -1527,7 +1529,7 @@ static void ext3_orphan_cleanup (struct super_block * sb, | |||
1527 | /* Turn quotas off */ | 1529 | /* Turn quotas off */ |
1528 | for (i = 0; i < MAXQUOTAS; i++) { | 1530 | for (i = 0; i < MAXQUOTAS; i++) { |
1529 | if (sb_dqopt(sb)->files[i]) | 1531 | if (sb_dqopt(sb)->files[i]) |
1530 | vfs_quota_off(sb, i, 0); | 1532 | dquot_quota_off(sb, i); |
1531 | } | 1533 | } |
1532 | #endif | 1534 | #endif |
1533 | sb->s_flags = s_flags; /* Restore MS_RDONLY status */ | 1535 | sb->s_flags = s_flags; /* Restore MS_RDONLY status */ |
@@ -2551,6 +2553,7 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data) | |||
2551 | ext3_fsblk_t n_blocks_count = 0; | 2553 | ext3_fsblk_t n_blocks_count = 0; |
2552 | unsigned long old_sb_flags; | 2554 | unsigned long old_sb_flags; |
2553 | struct ext3_mount_options old_opts; | 2555 | struct ext3_mount_options old_opts; |
2556 | int enable_quota = 0; | ||
2554 | int err; | 2557 | int err; |
2555 | #ifdef CONFIG_QUOTA | 2558 | #ifdef CONFIG_QUOTA |
2556 | int i; | 2559 | int i; |
@@ -2597,6 +2600,10 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data) | |||
2597 | } | 2600 | } |
2598 | 2601 | ||
2599 | if (*flags & MS_RDONLY) { | 2602 | if (*flags & MS_RDONLY) { |
2603 | err = dquot_suspend(sb, -1); | ||
2604 | if (err < 0) | ||
2605 | goto restore_opts; | ||
2606 | |||
2600 | /* | 2607 | /* |
2601 | * First of all, the unconditional stuff we have to do | 2608 | * First of all, the unconditional stuff we have to do |
2602 | * to disable replay of the journal when we next remount | 2609 | * to disable replay of the journal when we next remount |
@@ -2651,6 +2658,7 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data) | |||
2651 | goto restore_opts; | 2658 | goto restore_opts; |
2652 | if (!ext3_setup_super (sb, es, 0)) | 2659 | if (!ext3_setup_super (sb, es, 0)) |
2653 | sb->s_flags &= ~MS_RDONLY; | 2660 | sb->s_flags &= ~MS_RDONLY; |
2661 | enable_quota = 1; | ||
2654 | } | 2662 | } |
2655 | } | 2663 | } |
2656 | #ifdef CONFIG_QUOTA | 2664 | #ifdef CONFIG_QUOTA |
@@ -2662,6 +2670,9 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data) | |||
2662 | #endif | 2670 | #endif |
2663 | unlock_super(sb); | 2671 | unlock_super(sb); |
2664 | unlock_kernel(); | 2672 | unlock_kernel(); |
2673 | |||
2674 | if (enable_quota) | ||
2675 | dquot_resume(sb, -1); | ||
2665 | return 0; | 2676 | return 0; |
2666 | restore_opts: | 2677 | restore_opts: |
2667 | sb->s_flags = old_sb_flags; | 2678 | sb->s_flags = old_sb_flags; |
@@ -2851,24 +2862,21 @@ static int ext3_write_info(struct super_block *sb, int type) | |||
2851 | */ | 2862 | */ |
2852 | static int ext3_quota_on_mount(struct super_block *sb, int type) | 2863 | static int ext3_quota_on_mount(struct super_block *sb, int type) |
2853 | { | 2864 | { |
2854 | return vfs_quota_on_mount(sb, EXT3_SB(sb)->s_qf_names[type], | 2865 | return dquot_quota_on_mount(sb, EXT3_SB(sb)->s_qf_names[type], |
2855 | EXT3_SB(sb)->s_jquota_fmt, type); | 2866 | EXT3_SB(sb)->s_jquota_fmt, type); |
2856 | } | 2867 | } |
2857 | 2868 | ||
2858 | /* | 2869 | /* |
2859 | * Standard function to be called on quota_on | 2870 | * Standard function to be called on quota_on |
2860 | */ | 2871 | */ |
2861 | static int ext3_quota_on(struct super_block *sb, int type, int format_id, | 2872 | static int ext3_quota_on(struct super_block *sb, int type, int format_id, |
2862 | char *name, int remount) | 2873 | char *name) |
2863 | { | 2874 | { |
2864 | int err; | 2875 | int err; |
2865 | struct path path; | 2876 | struct path path; |
2866 | 2877 | ||
2867 | if (!test_opt(sb, QUOTA)) | 2878 | if (!test_opt(sb, QUOTA)) |
2868 | return -EINVAL; | 2879 | return -EINVAL; |
2869 | /* When remounting, no checks are needed and in fact, name is NULL */ | ||
2870 | if (remount) | ||
2871 | return vfs_quota_on(sb, type, format_id, name, remount); | ||
2872 | 2880 | ||
2873 | err = kern_path(name, LOOKUP_FOLLOW, &path); | 2881 | err = kern_path(name, LOOKUP_FOLLOW, &path); |
2874 | if (err) | 2882 | if (err) |
@@ -2906,7 +2914,7 @@ static int ext3_quota_on(struct super_block *sb, int type, int format_id, | |||
2906 | } | 2914 | } |
2907 | } | 2915 | } |
2908 | 2916 | ||
2909 | err = vfs_quota_on_path(sb, type, format_id, &path); | 2917 | err = dquot_quota_on_path(sb, type, format_id, &path); |
2910 | path_put(&path); | 2918 | path_put(&path); |
2911 | return err; | 2919 | return err; |
2912 | } | 2920 | } |
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 60bd31026e7c..19a4de57128a 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
@@ -1519,7 +1519,7 @@ extern int ext4_htree_store_dirent(struct file *dir_file, __u32 hash, | |||
1519 | extern void ext4_htree_free_dir_info(struct dir_private_info *p); | 1519 | extern void ext4_htree_free_dir_info(struct dir_private_info *p); |
1520 | 1520 | ||
1521 | /* fsync.c */ | 1521 | /* fsync.c */ |
1522 | extern int ext4_sync_file(struct file *, struct dentry *, int); | 1522 | extern int ext4_sync_file(struct file *, int); |
1523 | 1523 | ||
1524 | /* hash.c */ | 1524 | /* hash.c */ |
1525 | extern int ext4fs_dirhash(const char *name, int len, struct | 1525 | extern int ext4fs_dirhash(const char *name, int len, struct |
diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c index b6a74f991bf4..592adf2e546e 100644 --- a/fs/ext4/fsync.c +++ b/fs/ext4/fsync.c | |||
@@ -71,9 +71,9 @@ static void ext4_sync_parent(struct inode *inode) | |||
71 | * i_mutex lock is held when entering and exiting this function | 71 | * i_mutex lock is held when entering and exiting this function |
72 | */ | 72 | */ |
73 | 73 | ||
74 | int ext4_sync_file(struct file *file, struct dentry *dentry, int datasync) | 74 | int ext4_sync_file(struct file *file, int datasync) |
75 | { | 75 | { |
76 | struct inode *inode = dentry->d_inode; | 76 | struct inode *inode = file->f_mapping->host; |
77 | struct ext4_inode_info *ei = EXT4_I(inode); | 77 | struct ext4_inode_info *ei = EXT4_I(inode); |
78 | journal_t *journal = EXT4_SB(inode->i_sb)->s_journal; | 78 | journal_t *journal = EXT4_SB(inode->i_sb)->s_journal; |
79 | int ret; | 79 | int ret; |
@@ -81,7 +81,7 @@ int ext4_sync_file(struct file *file, struct dentry *dentry, int datasync) | |||
81 | 81 | ||
82 | J_ASSERT(ext4_journal_current_handle() == NULL); | 82 | J_ASSERT(ext4_journal_current_handle() == NULL); |
83 | 83 | ||
84 | trace_ext4_sync_file(file, dentry, datasync); | 84 | trace_ext4_sync_file(file, datasync); |
85 | 85 | ||
86 | if (inode->i_sb->s_flags & MS_RDONLY) | 86 | if (inode->i_sb->s_flags & MS_RDONLY) |
87 | return 0; | 87 | return 0; |
@@ -91,7 +91,7 @@ int ext4_sync_file(struct file *file, struct dentry *dentry, int datasync) | |||
91 | return ret; | 91 | return ret; |
92 | 92 | ||
93 | if (!journal) { | 93 | if (!journal) { |
94 | ret = simple_fsync(file, dentry, datasync); | 94 | ret = generic_file_fsync(file, datasync); |
95 | if (!ret && !list_empty(&inode->i_dentry)) | 95 | if (!ret && !list_empty(&inode->i_dentry)) |
96 | ext4_sync_parent(inode); | 96 | ext4_sync_parent(inode); |
97 | return ret; | 97 | return ret; |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 49d88c0597c4..4e8983a9811b 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -646,6 +646,8 @@ static void ext4_put_super(struct super_block *sb) | |||
646 | struct ext4_super_block *es = sbi->s_es; | 646 | struct ext4_super_block *es = sbi->s_es; |
647 | int i, err; | 647 | int i, err; |
648 | 648 | ||
649 | dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); | ||
650 | |||
649 | flush_workqueue(sbi->dio_unwritten_wq); | 651 | flush_workqueue(sbi->dio_unwritten_wq); |
650 | destroy_workqueue(sbi->dio_unwritten_wq); | 652 | destroy_workqueue(sbi->dio_unwritten_wq); |
651 | 653 | ||
@@ -1062,7 +1064,7 @@ static int ext4_release_dquot(struct dquot *dquot); | |||
1062 | static int ext4_mark_dquot_dirty(struct dquot *dquot); | 1064 | static int ext4_mark_dquot_dirty(struct dquot *dquot); |
1063 | static int ext4_write_info(struct super_block *sb, int type); | 1065 | static int ext4_write_info(struct super_block *sb, int type); |
1064 | static int ext4_quota_on(struct super_block *sb, int type, int format_id, | 1066 | static int ext4_quota_on(struct super_block *sb, int type, int format_id, |
1065 | char *path, int remount); | 1067 | char *path); |
1066 | static int ext4_quota_on_mount(struct super_block *sb, int type); | 1068 | static int ext4_quota_on_mount(struct super_block *sb, int type); |
1067 | static ssize_t ext4_quota_read(struct super_block *sb, int type, char *data, | 1069 | static ssize_t ext4_quota_read(struct super_block *sb, int type, char *data, |
1068 | size_t len, loff_t off); | 1070 | size_t len, loff_t off); |
@@ -1084,12 +1086,12 @@ static const struct dquot_operations ext4_quota_operations = { | |||
1084 | 1086 | ||
1085 | static const struct quotactl_ops ext4_qctl_operations = { | 1087 | static const struct quotactl_ops ext4_qctl_operations = { |
1086 | .quota_on = ext4_quota_on, | 1088 | .quota_on = ext4_quota_on, |
1087 | .quota_off = vfs_quota_off, | 1089 | .quota_off = dquot_quota_off, |
1088 | .quota_sync = vfs_quota_sync, | 1090 | .quota_sync = dquot_quota_sync, |
1089 | .get_info = vfs_get_dqinfo, | 1091 | .get_info = dquot_get_dqinfo, |
1090 | .set_info = vfs_set_dqinfo, | 1092 | .set_info = dquot_set_dqinfo, |
1091 | .get_dqblk = vfs_get_dqblk, | 1093 | .get_dqblk = dquot_get_dqblk, |
1092 | .set_dqblk = vfs_set_dqblk | 1094 | .set_dqblk = dquot_set_dqblk |
1093 | }; | 1095 | }; |
1094 | #endif | 1096 | #endif |
1095 | 1097 | ||
@@ -2054,7 +2056,7 @@ static void ext4_orphan_cleanup(struct super_block *sb, | |||
2054 | /* Turn quotas off */ | 2056 | /* Turn quotas off */ |
2055 | for (i = 0; i < MAXQUOTAS; i++) { | 2057 | for (i = 0; i < MAXQUOTAS; i++) { |
2056 | if (sb_dqopt(sb)->files[i]) | 2058 | if (sb_dqopt(sb)->files[i]) |
2057 | vfs_quota_off(sb, i, 0); | 2059 | dquot_quota_off(sb, i); |
2058 | } | 2060 | } |
2059 | #endif | 2061 | #endif |
2060 | sb->s_flags = s_flags; /* Restore MS_RDONLY status */ | 2062 | sb->s_flags = s_flags; /* Restore MS_RDONLY status */ |
@@ -3576,6 +3578,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) | |||
3576 | ext4_fsblk_t n_blocks_count = 0; | 3578 | ext4_fsblk_t n_blocks_count = 0; |
3577 | unsigned long old_sb_flags; | 3579 | unsigned long old_sb_flags; |
3578 | struct ext4_mount_options old_opts; | 3580 | struct ext4_mount_options old_opts; |
3581 | int enable_quota = 0; | ||
3579 | ext4_group_t g; | 3582 | ext4_group_t g; |
3580 | unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO; | 3583 | unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO; |
3581 | int err; | 3584 | int err; |
@@ -3633,6 +3636,10 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) | |||
3633 | } | 3636 | } |
3634 | 3637 | ||
3635 | if (*flags & MS_RDONLY) { | 3638 | if (*flags & MS_RDONLY) { |
3639 | err = dquot_suspend(sb, -1); | ||
3640 | if (err < 0) | ||
3641 | goto restore_opts; | ||
3642 | |||
3636 | /* | 3643 | /* |
3637 | * First of all, the unconditional stuff we have to do | 3644 | * First of all, the unconditional stuff we have to do |
3638 | * to disable replay of the journal when we next remount | 3645 | * to disable replay of the journal when we next remount |
@@ -3701,6 +3708,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) | |||
3701 | goto restore_opts; | 3708 | goto restore_opts; |
3702 | if (!ext4_setup_super(sb, es, 0)) | 3709 | if (!ext4_setup_super(sb, es, 0)) |
3703 | sb->s_flags &= ~MS_RDONLY; | 3710 | sb->s_flags &= ~MS_RDONLY; |
3711 | enable_quota = 1; | ||
3704 | } | 3712 | } |
3705 | } | 3713 | } |
3706 | ext4_setup_system_zone(sb); | 3714 | ext4_setup_system_zone(sb); |
@@ -3716,6 +3724,8 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) | |||
3716 | #endif | 3724 | #endif |
3717 | unlock_super(sb); | 3725 | unlock_super(sb); |
3718 | unlock_kernel(); | 3726 | unlock_kernel(); |
3727 | if (enable_quota) | ||
3728 | dquot_resume(sb, -1); | ||
3719 | 3729 | ||
3720 | ext4_msg(sb, KERN_INFO, "re-mounted. Opts: %s", orig_data); | 3730 | ext4_msg(sb, KERN_INFO, "re-mounted. Opts: %s", orig_data); |
3721 | kfree(orig_data); | 3731 | kfree(orig_data); |
@@ -3913,24 +3923,21 @@ static int ext4_write_info(struct super_block *sb, int type) | |||
3913 | */ | 3923 | */ |
3914 | static int ext4_quota_on_mount(struct super_block *sb, int type) | 3924 | static int ext4_quota_on_mount(struct super_block *sb, int type) |
3915 | { | 3925 | { |
3916 | return vfs_quota_on_mount(sb, EXT4_SB(sb)->s_qf_names[type], | 3926 | return dquot_quota_on_mount(sb, EXT4_SB(sb)->s_qf_names[type], |
3917 | EXT4_SB(sb)->s_jquota_fmt, type); | 3927 | EXT4_SB(sb)->s_jquota_fmt, type); |
3918 | } | 3928 | } |
3919 | 3929 | ||
3920 | /* | 3930 | /* |
3921 | * Standard function to be called on quota_on | 3931 | * Standard function to be called on quota_on |
3922 | */ | 3932 | */ |
3923 | static int ext4_quota_on(struct super_block *sb, int type, int format_id, | 3933 | static int ext4_quota_on(struct super_block *sb, int type, int format_id, |
3924 | char *name, int remount) | 3934 | char *name) |
3925 | { | 3935 | { |
3926 | int err; | 3936 | int err; |
3927 | struct path path; | 3937 | struct path path; |
3928 | 3938 | ||
3929 | if (!test_opt(sb, QUOTA)) | 3939 | if (!test_opt(sb, QUOTA)) |
3930 | return -EINVAL; | 3940 | return -EINVAL; |
3931 | /* When remounting, no checks are needed and in fact, name is NULL */ | ||
3932 | if (remount) | ||
3933 | return vfs_quota_on(sb, type, format_id, name, remount); | ||
3934 | 3941 | ||
3935 | err = kern_path(name, LOOKUP_FOLLOW, &path); | 3942 | err = kern_path(name, LOOKUP_FOLLOW, &path); |
3936 | if (err) | 3943 | if (err) |
@@ -3969,7 +3976,7 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id, | |||
3969 | } | 3976 | } |
3970 | } | 3977 | } |
3971 | 3978 | ||
3972 | err = vfs_quota_on_path(sb, type, format_id, &path); | 3979 | err = dquot_quota_on_path(sb, type, format_id, &path); |
3973 | path_put(&path); | 3980 | path_put(&path); |
3974 | return err; | 3981 | return err; |
3975 | } | 3982 | } |
diff --git a/fs/fat/fat.h b/fs/fat/fat.h index 53dba57b49a1..27ac25725954 100644 --- a/fs/fat/fat.h +++ b/fs/fat/fat.h | |||
@@ -306,11 +306,11 @@ extern long fat_generic_ioctl(struct file *filp, unsigned int cmd, | |||
306 | extern const struct file_operations fat_file_operations; | 306 | extern const struct file_operations fat_file_operations; |
307 | extern const struct inode_operations fat_file_inode_operations; | 307 | extern const struct inode_operations fat_file_inode_operations; |
308 | extern int fat_setattr(struct dentry * dentry, struct iattr * attr); | 308 | extern int fat_setattr(struct dentry * dentry, struct iattr * attr); |
309 | extern void fat_truncate(struct inode *inode); | 309 | extern int fat_setsize(struct inode *inode, loff_t offset); |
310 | extern void fat_truncate_blocks(struct inode *inode, loff_t offset); | ||
310 | extern int fat_getattr(struct vfsmount *mnt, struct dentry *dentry, | 311 | extern int fat_getattr(struct vfsmount *mnt, struct dentry *dentry, |
311 | struct kstat *stat); | 312 | struct kstat *stat); |
312 | extern int fat_file_fsync(struct file *file, struct dentry *dentry, | 313 | extern int fat_file_fsync(struct file *file, int datasync); |
313 | int datasync); | ||
314 | 314 | ||
315 | /* fat/inode.c */ | 315 | /* fat/inode.c */ |
316 | extern void fat_attach(struct inode *inode, loff_t i_pos); | 316 | extern void fat_attach(struct inode *inode, loff_t i_pos); |
diff --git a/fs/fat/file.c b/fs/fat/file.c index a14c2f6a489e..990dfae022e5 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c | |||
@@ -149,12 +149,12 @@ static int fat_file_release(struct inode *inode, struct file *filp) | |||
149 | return 0; | 149 | return 0; |
150 | } | 150 | } |
151 | 151 | ||
152 | int fat_file_fsync(struct file *filp, struct dentry *dentry, int datasync) | 152 | int fat_file_fsync(struct file *filp, int datasync) |
153 | { | 153 | { |
154 | struct inode *inode = dentry->d_inode; | 154 | struct inode *inode = filp->f_mapping->host; |
155 | int res, err; | 155 | int res, err; |
156 | 156 | ||
157 | res = simple_fsync(filp, dentry, datasync); | 157 | res = generic_file_fsync(filp, datasync); |
158 | err = sync_mapping_buffers(MSDOS_SB(inode->i_sb)->fat_inode->i_mapping); | 158 | err = sync_mapping_buffers(MSDOS_SB(inode->i_sb)->fat_inode->i_mapping); |
159 | 159 | ||
160 | return res ? res : err; | 160 | return res ? res : err; |
@@ -283,7 +283,7 @@ static int fat_free(struct inode *inode, int skip) | |||
283 | return fat_free_clusters(inode, free_start); | 283 | return fat_free_clusters(inode, free_start); |
284 | } | 284 | } |
285 | 285 | ||
286 | void fat_truncate(struct inode *inode) | 286 | void fat_truncate_blocks(struct inode *inode, loff_t offset) |
287 | { | 287 | { |
288 | struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); | 288 | struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); |
289 | const unsigned int cluster_size = sbi->cluster_size; | 289 | const unsigned int cluster_size = sbi->cluster_size; |
@@ -293,10 +293,10 @@ void fat_truncate(struct inode *inode) | |||
293 | * This protects against truncating a file bigger than it was then | 293 | * This protects against truncating a file bigger than it was then |
294 | * trying to write into the hole. | 294 | * trying to write into the hole. |
295 | */ | 295 | */ |
296 | if (MSDOS_I(inode)->mmu_private > inode->i_size) | 296 | if (MSDOS_I(inode)->mmu_private > offset) |
297 | MSDOS_I(inode)->mmu_private = inode->i_size; | 297 | MSDOS_I(inode)->mmu_private = offset; |
298 | 298 | ||
299 | nr_clusters = (inode->i_size + (cluster_size - 1)) >> sbi->cluster_bits; | 299 | nr_clusters = (offset + (cluster_size - 1)) >> sbi->cluster_bits; |
300 | 300 | ||
301 | fat_free(inode, nr_clusters); | 301 | fat_free(inode, nr_clusters); |
302 | fat_flush_inodes(inode->i_sb, inode, NULL); | 302 | fat_flush_inodes(inode->i_sb, inode, NULL); |
@@ -364,6 +364,18 @@ static int fat_allow_set_time(struct msdos_sb_info *sbi, struct inode *inode) | |||
364 | return 0; | 364 | return 0; |
365 | } | 365 | } |
366 | 366 | ||
367 | int fat_setsize(struct inode *inode, loff_t offset) | ||
368 | { | ||
369 | int error; | ||
370 | |||
371 | error = simple_setsize(inode, offset); | ||
372 | if (error) | ||
373 | return error; | ||
374 | fat_truncate_blocks(inode, offset); | ||
375 | |||
376 | return error; | ||
377 | } | ||
378 | |||
367 | #define TIMES_SET_FLAGS (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET) | 379 | #define TIMES_SET_FLAGS (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET) |
368 | /* valid file mode bits */ | 380 | /* valid file mode bits */ |
369 | #define FAT_VALID_MODE (S_IFREG | S_IFDIR | S_IRWXUGO) | 381 | #define FAT_VALID_MODE (S_IFREG | S_IFDIR | S_IRWXUGO) |
@@ -378,7 +390,8 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr) | |||
378 | /* | 390 | /* |
379 | * Expand the file. Since inode_setattr() updates ->i_size | 391 | * Expand the file. Since inode_setattr() updates ->i_size |
380 | * before calling the ->truncate(), but FAT needs to fill the | 392 | * before calling the ->truncate(), but FAT needs to fill the |
381 | * hole before it. | 393 | * hole before it. XXX: this is no longer true with new truncate |
394 | * sequence. | ||
382 | */ | 395 | */ |
383 | if (attr->ia_valid & ATTR_SIZE) { | 396 | if (attr->ia_valid & ATTR_SIZE) { |
384 | if (attr->ia_size > inode->i_size) { | 397 | if (attr->ia_size > inode->i_size) { |
@@ -427,15 +440,20 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr) | |||
427 | attr->ia_valid &= ~ATTR_MODE; | 440 | attr->ia_valid &= ~ATTR_MODE; |
428 | } | 441 | } |
429 | 442 | ||
430 | if (attr->ia_valid) | 443 | if (attr->ia_valid & ATTR_SIZE) { |
431 | error = inode_setattr(inode, attr); | 444 | error = fat_setsize(inode, attr->ia_size); |
445 | if (error) | ||
446 | goto out; | ||
447 | } | ||
448 | |||
449 | generic_setattr(inode, attr); | ||
450 | mark_inode_dirty(inode); | ||
432 | out: | 451 | out: |
433 | return error; | 452 | return error; |
434 | } | 453 | } |
435 | EXPORT_SYMBOL_GPL(fat_setattr); | 454 | EXPORT_SYMBOL_GPL(fat_setattr); |
436 | 455 | ||
437 | const struct inode_operations fat_file_inode_operations = { | 456 | const struct inode_operations fat_file_inode_operations = { |
438 | .truncate = fat_truncate, | ||
439 | .setattr = fat_setattr, | 457 | .setattr = fat_setattr, |
440 | .getattr = fat_getattr, | 458 | .getattr = fat_getattr, |
441 | }; | 459 | }; |
diff --git a/fs/fat/inode.c b/fs/fat/inode.c index ed33904926ee..7bf45aee56d7 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c | |||
@@ -142,14 +142,29 @@ static int fat_readpages(struct file *file, struct address_space *mapping, | |||
142 | return mpage_readpages(mapping, pages, nr_pages, fat_get_block); | 142 | return mpage_readpages(mapping, pages, nr_pages, fat_get_block); |
143 | } | 143 | } |
144 | 144 | ||
145 | static void fat_write_failed(struct address_space *mapping, loff_t to) | ||
146 | { | ||
147 | struct inode *inode = mapping->host; | ||
148 | |||
149 | if (to > inode->i_size) { | ||
150 | truncate_pagecache(inode, to, inode->i_size); | ||
151 | fat_truncate_blocks(inode, inode->i_size); | ||
152 | } | ||
153 | } | ||
154 | |||
145 | static int fat_write_begin(struct file *file, struct address_space *mapping, | 155 | static int fat_write_begin(struct file *file, struct address_space *mapping, |
146 | loff_t pos, unsigned len, unsigned flags, | 156 | loff_t pos, unsigned len, unsigned flags, |
147 | struct page **pagep, void **fsdata) | 157 | struct page **pagep, void **fsdata) |
148 | { | 158 | { |
159 | int err; | ||
160 | |||
149 | *pagep = NULL; | 161 | *pagep = NULL; |
150 | return cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata, | 162 | err = cont_write_begin_newtrunc(file, mapping, pos, len, flags, |
151 | fat_get_block, | 163 | pagep, fsdata, fat_get_block, |
152 | &MSDOS_I(mapping->host)->mmu_private); | 164 | &MSDOS_I(mapping->host)->mmu_private); |
165 | if (err < 0) | ||
166 | fat_write_failed(mapping, pos + len); | ||
167 | return err; | ||
153 | } | 168 | } |
154 | 169 | ||
155 | static int fat_write_end(struct file *file, struct address_space *mapping, | 170 | static int fat_write_end(struct file *file, struct address_space *mapping, |
@@ -159,6 +174,8 @@ static int fat_write_end(struct file *file, struct address_space *mapping, | |||
159 | struct inode *inode = mapping->host; | 174 | struct inode *inode = mapping->host; |
160 | int err; | 175 | int err; |
161 | err = generic_write_end(file, mapping, pos, len, copied, pagep, fsdata); | 176 | err = generic_write_end(file, mapping, pos, len, copied, pagep, fsdata); |
177 | if (err < len) | ||
178 | fat_write_failed(mapping, pos + len); | ||
162 | if (!(err < 0) && !(MSDOS_I(inode)->i_attrs & ATTR_ARCH)) { | 179 | if (!(err < 0) && !(MSDOS_I(inode)->i_attrs & ATTR_ARCH)) { |
163 | inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; | 180 | inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; |
164 | MSDOS_I(inode)->i_attrs |= ATTR_ARCH; | 181 | MSDOS_I(inode)->i_attrs |= ATTR_ARCH; |
@@ -172,7 +189,9 @@ static ssize_t fat_direct_IO(int rw, struct kiocb *iocb, | |||
172 | loff_t offset, unsigned long nr_segs) | 189 | loff_t offset, unsigned long nr_segs) |
173 | { | 190 | { |
174 | struct file *file = iocb->ki_filp; | 191 | struct file *file = iocb->ki_filp; |
175 | struct inode *inode = file->f_mapping->host; | 192 | struct address_space *mapping = file->f_mapping; |
193 | struct inode *inode = mapping->host; | ||
194 | ssize_t ret; | ||
176 | 195 | ||
177 | if (rw == WRITE) { | 196 | if (rw == WRITE) { |
178 | /* | 197 | /* |
@@ -193,8 +212,12 @@ static ssize_t fat_direct_IO(int rw, struct kiocb *iocb, | |||
193 | * FAT need to use the DIO_LOCKING for avoiding the race | 212 | * FAT need to use the DIO_LOCKING for avoiding the race |
194 | * condition of fat_get_block() and ->truncate(). | 213 | * condition of fat_get_block() and ->truncate(). |
195 | */ | 214 | */ |
196 | return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, | 215 | ret = blockdev_direct_IO_newtrunc(rw, iocb, inode, inode->i_sb->s_bdev, |
197 | offset, nr_segs, fat_get_block, NULL); | 216 | iov, offset, nr_segs, fat_get_block, NULL); |
217 | if (ret < 0 && (rw & WRITE)) | ||
218 | fat_write_failed(mapping, offset + iov_length(iov, nr_segs)); | ||
219 | |||
220 | return ret; | ||
198 | } | 221 | } |
199 | 222 | ||
200 | static sector_t _fat_bmap(struct address_space *mapping, sector_t block) | 223 | static sector_t _fat_bmap(struct address_space *mapping, sector_t block) |
@@ -429,7 +452,7 @@ static void fat_delete_inode(struct inode *inode) | |||
429 | { | 452 | { |
430 | truncate_inode_pages(&inode->i_data, 0); | 453 | truncate_inode_pages(&inode->i_data, 0); |
431 | inode->i_size = 0; | 454 | inode->i_size = 0; |
432 | fat_truncate(inode); | 455 | fat_truncate_blocks(inode, 0); |
433 | clear_inode(inode); | 456 | clear_inode(inode); |
434 | } | 457 | } |
435 | 458 | ||
diff --git a/fs/file_table.c b/fs/file_table.c index 32d12b78bac8..5c7d10ead4ad 100644 --- a/fs/file_table.c +++ b/fs/file_table.c | |||
@@ -194,14 +194,6 @@ struct file *alloc_file(struct path *path, fmode_t mode, | |||
194 | } | 194 | } |
195 | EXPORT_SYMBOL(alloc_file); | 195 | EXPORT_SYMBOL(alloc_file); |
196 | 196 | ||
197 | void fput(struct file *file) | ||
198 | { | ||
199 | if (atomic_long_dec_and_test(&file->f_count)) | ||
200 | __fput(file); | ||
201 | } | ||
202 | |||
203 | EXPORT_SYMBOL(fput); | ||
204 | |||
205 | /** | 197 | /** |
206 | * drop_file_write_access - give up ability to write to a file | 198 | * drop_file_write_access - give up ability to write to a file |
207 | * @file: the file to which we will stop writing | 199 | * @file: the file to which we will stop writing |
@@ -227,10 +219,9 @@ void drop_file_write_access(struct file *file) | |||
227 | } | 219 | } |
228 | EXPORT_SYMBOL_GPL(drop_file_write_access); | 220 | EXPORT_SYMBOL_GPL(drop_file_write_access); |
229 | 221 | ||
230 | /* __fput is called from task context when aio completion releases the last | 222 | /* the real guts of fput() - releasing the last reference to file |
231 | * last use of a struct file *. Do not use otherwise. | ||
232 | */ | 223 | */ |
233 | void __fput(struct file *file) | 224 | static void __fput(struct file *file) |
234 | { | 225 | { |
235 | struct dentry *dentry = file->f_path.dentry; | 226 | struct dentry *dentry = file->f_path.dentry; |
236 | struct vfsmount *mnt = file->f_path.mnt; | 227 | struct vfsmount *mnt = file->f_path.mnt; |
@@ -268,6 +259,14 @@ void __fput(struct file *file) | |||
268 | mntput(mnt); | 259 | mntput(mnt); |
269 | } | 260 | } |
270 | 261 | ||
262 | void fput(struct file *file) | ||
263 | { | ||
264 | if (atomic_long_dec_and_test(&file->f_count)) | ||
265 | __fput(file); | ||
266 | } | ||
267 | |||
268 | EXPORT_SYMBOL(fput); | ||
269 | |||
271 | struct file *fget(unsigned int fd) | 270 | struct file *fget(unsigned int fd) |
272 | { | 271 | { |
273 | struct file *file; | 272 | struct file *file; |
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 4787ae6c5c1c..3cdc5f78a406 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -1156,10 +1156,9 @@ static int fuse_dir_release(struct inode *inode, struct file *file) | |||
1156 | return 0; | 1156 | return 0; |
1157 | } | 1157 | } |
1158 | 1158 | ||
1159 | static int fuse_dir_fsync(struct file *file, struct dentry *de, int datasync) | 1159 | static int fuse_dir_fsync(struct file *file, int datasync) |
1160 | { | 1160 | { |
1161 | /* nfsd can call this with no file */ | 1161 | return fuse_fsync_common(file, datasync, 1); |
1162 | return file ? fuse_fsync_common(file, de, datasync, 1) : 0; | ||
1163 | } | 1162 | } |
1164 | 1163 | ||
1165 | static bool update_mtime(unsigned ivalid) | 1164 | static bool update_mtime(unsigned ivalid) |
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index a9f5e137f1d3..b5fd6f9905e4 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
@@ -351,10 +351,9 @@ static void fuse_sync_writes(struct inode *inode) | |||
351 | fuse_release_nowrite(inode); | 351 | fuse_release_nowrite(inode); |
352 | } | 352 | } |
353 | 353 | ||
354 | int fuse_fsync_common(struct file *file, struct dentry *de, int datasync, | 354 | int fuse_fsync_common(struct file *file, int datasync, int isdir) |
355 | int isdir) | ||
356 | { | 355 | { |
357 | struct inode *inode = de->d_inode; | 356 | struct inode *inode = file->f_mapping->host; |
358 | struct fuse_conn *fc = get_fuse_conn(inode); | 357 | struct fuse_conn *fc = get_fuse_conn(inode); |
359 | struct fuse_file *ff = file->private_data; | 358 | struct fuse_file *ff = file->private_data; |
360 | struct fuse_req *req; | 359 | struct fuse_req *req; |
@@ -403,9 +402,9 @@ int fuse_fsync_common(struct file *file, struct dentry *de, int datasync, | |||
403 | return err; | 402 | return err; |
404 | } | 403 | } |
405 | 404 | ||
406 | static int fuse_fsync(struct file *file, struct dentry *de, int datasync) | 405 | static int fuse_fsync(struct file *file, int datasync) |
407 | { | 406 | { |
408 | return fuse_fsync_common(file, de, datasync, 0); | 407 | return fuse_fsync_common(file, datasync, 0); |
409 | } | 408 | } |
410 | 409 | ||
411 | void fuse_read_fill(struct fuse_req *req, struct file *file, loff_t pos, | 410 | void fuse_read_fill(struct fuse_req *req, struct file *file, loff_t pos, |
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 01cc462ff45d..2c0d14a86779 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h | |||
@@ -568,8 +568,7 @@ void fuse_release_common(struct file *file, int opcode); | |||
568 | /** | 568 | /** |
569 | * Send FSYNC or FSYNCDIR request | 569 | * Send FSYNC or FSYNCDIR request |
570 | */ | 570 | */ |
571 | int fuse_fsync_common(struct file *file, struct dentry *de, int datasync, | 571 | int fuse_fsync_common(struct file *file, int datasync, int isdir); |
572 | int isdir); | ||
573 | 572 | ||
574 | /** | 573 | /** |
575 | * Notify poll wakeup | 574 | * Notify poll wakeup |
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index a739a0a48067..9f8b52500d63 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c | |||
@@ -700,8 +700,14 @@ out: | |||
700 | return 0; | 700 | return 0; |
701 | 701 | ||
702 | page_cache_release(page); | 702 | page_cache_release(page); |
703 | |||
704 | /* | ||
705 | * XXX(hch): the call below should probably be replaced with | ||
706 | * a call to the gfs2-specific truncate blocks helper to actually | ||
707 | * release disk blocks.. | ||
708 | */ | ||
703 | if (pos + len > ip->i_inode.i_size) | 709 | if (pos + len > ip->i_inode.i_size) |
704 | vmtruncate(&ip->i_inode, ip->i_inode.i_size); | 710 | simple_setsize(&ip->i_inode, ip->i_inode.i_size); |
705 | out_endtrans: | 711 | out_endtrans: |
706 | gfs2_trans_end(sdp); | 712 | gfs2_trans_end(sdp); |
707 | out_trans_fail: | 713 | out_trans_fail: |
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index b20bfcc9fa2d..ed9a94f0ef15 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c | |||
@@ -554,9 +554,9 @@ static int gfs2_close(struct inode *inode, struct file *file) | |||
554 | * Returns: errno | 554 | * Returns: errno |
555 | */ | 555 | */ |
556 | 556 | ||
557 | static int gfs2_fsync(struct file *file, struct dentry *dentry, int datasync) | 557 | static int gfs2_fsync(struct file *file, int datasync) |
558 | { | 558 | { |
559 | struct inode *inode = dentry->d_inode; | 559 | struct inode *inode = file->f_mapping->host; |
560 | int sync_state = inode->i_state & (I_DIRTY_SYNC|I_DIRTY_DATASYNC); | 560 | int sync_state = inode->i_state & (I_DIRTY_SYNC|I_DIRTY_DATASYNC); |
561 | int ret = 0; | 561 | int ret = 0; |
562 | 562 | ||
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c index 4e64352d49de..98cdd05f3316 100644 --- a/fs/gfs2/ops_inode.c +++ b/fs/gfs2/ops_inode.c | |||
@@ -1071,6 +1071,9 @@ int gfs2_permission(struct inode *inode, int mask) | |||
1071 | return error; | 1071 | return error; |
1072 | } | 1072 | } |
1073 | 1073 | ||
1074 | /* | ||
1075 | * XXX: should be changed to have proper ordering by opencoding simple_setsize | ||
1076 | */ | ||
1074 | static int setattr_size(struct inode *inode, struct iattr *attr) | 1077 | static int setattr_size(struct inode *inode, struct iattr *attr) |
1075 | { | 1078 | { |
1076 | struct gfs2_inode *ip = GFS2_I(inode); | 1079 | struct gfs2_inode *ip = GFS2_I(inode); |
@@ -1081,7 +1084,7 @@ static int setattr_size(struct inode *inode, struct iattr *attr) | |||
1081 | error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks); | 1084 | error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks); |
1082 | if (error) | 1085 | if (error) |
1083 | return error; | 1086 | return error; |
1084 | error = vmtruncate(inode, attr->ia_size); | 1087 | error = simple_setsize(inode, attr->ia_size); |
1085 | gfs2_trans_end(sdp); | 1088 | gfs2_trans_end(sdp); |
1086 | if (error) | 1089 | if (error) |
1087 | return error; | 1090 | return error; |
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index 3a029d8f4cf1..87ac1891a185 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c | |||
@@ -411,9 +411,9 @@ int hostfs_file_open(struct inode *ino, struct file *file) | |||
411 | return 0; | 411 | return 0; |
412 | } | 412 | } |
413 | 413 | ||
414 | int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync) | 414 | int hostfs_fsync(struct file *file, int datasync) |
415 | { | 415 | { |
416 | return fsync_file(HOSTFS_I(dentry->d_inode)->fd, datasync); | 416 | return fsync_file(HOSTFS_I(file->f_mapping->host)->fd, datasync); |
417 | } | 417 | } |
418 | 418 | ||
419 | static const struct file_operations hostfs_file_fops = { | 419 | static const struct file_operations hostfs_file_fops = { |
diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c index 3efabff00367..a9ae9bfa752f 100644 --- a/fs/hpfs/file.c +++ b/fs/hpfs/file.c | |||
@@ -19,9 +19,9 @@ static int hpfs_file_release(struct inode *inode, struct file *file) | |||
19 | return 0; | 19 | return 0; |
20 | } | 20 | } |
21 | 21 | ||
22 | int hpfs_file_fsync(struct file *file, struct dentry *dentry, int datasync) | 22 | int hpfs_file_fsync(struct file *file, int datasync) |
23 | { | 23 | { |
24 | /*return file_fsync(file, dentry);*/ | 24 | /*return file_fsync(file, datasync);*/ |
25 | return 0; /* Don't fsync :-) */ | 25 | return 0; /* Don't fsync :-) */ |
26 | } | 26 | } |
27 | 27 | ||
diff --git a/fs/hpfs/hpfs_fn.h b/fs/hpfs/hpfs_fn.h index 97bf738cd5d6..75f9d4324851 100644 --- a/fs/hpfs/hpfs_fn.h +++ b/fs/hpfs/hpfs_fn.h | |||
@@ -268,7 +268,7 @@ void hpfs_set_ea(struct inode *, struct fnode *, const char *, | |||
268 | 268 | ||
269 | /* file.c */ | 269 | /* file.c */ |
270 | 270 | ||
271 | int hpfs_file_fsync(struct file *, struct dentry *, int); | 271 | int hpfs_file_fsync(struct file *, int); |
272 | extern const struct file_operations hpfs_file_ops; | 272 | extern const struct file_operations hpfs_file_ops; |
273 | extern const struct inode_operations hpfs_file_iops; | 273 | extern const struct inode_operations hpfs_file_iops; |
274 | extern const struct address_space_operations hpfs_aops; | 274 | extern const struct address_space_operations hpfs_aops; |
diff --git a/fs/hppfs/hppfs.c b/fs/hppfs/hppfs.c index 2e4dfa8593da..826c3f9d29ac 100644 --- a/fs/hppfs/hppfs.c +++ b/fs/hppfs/hppfs.c | |||
@@ -587,7 +587,7 @@ static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir) | |||
587 | return err; | 587 | return err; |
588 | } | 588 | } |
589 | 589 | ||
590 | static int hppfs_fsync(struct file *file, struct dentry *dentry, int datasync) | 590 | static int hppfs_fsync(struct file *file, int datasync) |
591 | { | 591 | { |
592 | return 0; | 592 | return 0; |
593 | } | 593 | } |
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index a0bbd3d1b41a..a4e9a7ec3691 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c | |||
@@ -688,7 +688,7 @@ static void init_once(void *foo) | |||
688 | const struct file_operations hugetlbfs_file_operations = { | 688 | const struct file_operations hugetlbfs_file_operations = { |
689 | .read = hugetlbfs_read, | 689 | .read = hugetlbfs_read, |
690 | .mmap = hugetlbfs_file_mmap, | 690 | .mmap = hugetlbfs_file_mmap, |
691 | .fsync = simple_sync_file, | 691 | .fsync = noop_fsync, |
692 | .get_unmapped_area = hugetlb_get_unmapped_area, | 692 | .get_unmapped_area = hugetlb_get_unmapped_area, |
693 | }; | 693 | }; |
694 | 694 | ||
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c index e7291c161a19..813497024437 100644 --- a/fs/jffs2/file.c +++ b/fs/jffs2/file.c | |||
@@ -26,9 +26,9 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, | |||
26 | struct page **pagep, void **fsdata); | 26 | struct page **pagep, void **fsdata); |
27 | static int jffs2_readpage (struct file *filp, struct page *pg); | 27 | static int jffs2_readpage (struct file *filp, struct page *pg); |
28 | 28 | ||
29 | int jffs2_fsync(struct file *filp, struct dentry *dentry, int datasync) | 29 | int jffs2_fsync(struct file *filp, int datasync) |
30 | { | 30 | { |
31 | struct inode *inode = dentry->d_inode; | 31 | struct inode *inode = filp->f_mapping->host; |
32 | struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); | 32 | struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); |
33 | 33 | ||
34 | /* Trigger GC to flush any pending writes for this inode */ | 34 | /* Trigger GC to flush any pending writes for this inode */ |
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c index 86e0821fc989..8bc2c80ab159 100644 --- a/fs/jffs2/fs.c +++ b/fs/jffs2/fs.c | |||
@@ -169,13 +169,13 @@ int jffs2_do_setattr (struct inode *inode, struct iattr *iattr) | |||
169 | mutex_unlock(&f->sem); | 169 | mutex_unlock(&f->sem); |
170 | jffs2_complete_reservation(c); | 170 | jffs2_complete_reservation(c); |
171 | 171 | ||
172 | /* We have to do the vmtruncate() without f->sem held, since | 172 | /* We have to do the simple_setsize() without f->sem held, since |
173 | some pages may be locked and waiting for it in readpage(). | 173 | some pages may be locked and waiting for it in readpage(). |
174 | We are protected from a simultaneous write() extending i_size | 174 | We are protected from a simultaneous write() extending i_size |
175 | back past iattr->ia_size, because do_truncate() holds the | 175 | back past iattr->ia_size, because do_truncate() holds the |
176 | generic inode semaphore. */ | 176 | generic inode semaphore. */ |
177 | if (ivalid & ATTR_SIZE && inode->i_size > iattr->ia_size) { | 177 | if (ivalid & ATTR_SIZE && inode->i_size > iattr->ia_size) { |
178 | vmtruncate(inode, iattr->ia_size); | 178 | simple_setsize(inode, iattr->ia_size); |
179 | inode->i_blocks = (inode->i_size + 511) >> 9; | 179 | inode->i_blocks = (inode->i_size + 511) >> 9; |
180 | } | 180 | } |
181 | 181 | ||
diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h index 035a767f958b..4791aacf3084 100644 --- a/fs/jffs2/os-linux.h +++ b/fs/jffs2/os-linux.h | |||
@@ -158,7 +158,7 @@ extern const struct inode_operations jffs2_dir_inode_operations; | |||
158 | extern const struct file_operations jffs2_file_operations; | 158 | extern const struct file_operations jffs2_file_operations; |
159 | extern const struct inode_operations jffs2_file_inode_operations; | 159 | extern const struct inode_operations jffs2_file_inode_operations; |
160 | extern const struct address_space_operations jffs2_file_address_operations; | 160 | extern const struct address_space_operations jffs2_file_address_operations; |
161 | int jffs2_fsync(struct file *, struct dentry *, int); | 161 | int jffs2_fsync(struct file *, int); |
162 | int jffs2_do_readpage_unlock (struct inode *inode, struct page *pg); | 162 | int jffs2_do_readpage_unlock (struct inode *inode, struct page *pg); |
163 | 163 | ||
164 | /* ioctl.c */ | 164 | /* ioctl.c */ |
diff --git a/fs/jfs/file.c b/fs/jfs/file.c index 85d9ec659225..127263cc8657 100644 --- a/fs/jfs/file.c +++ b/fs/jfs/file.c | |||
@@ -27,9 +27,9 @@ | |||
27 | #include "jfs_acl.h" | 27 | #include "jfs_acl.h" |
28 | #include "jfs_debug.h" | 28 | #include "jfs_debug.h" |
29 | 29 | ||
30 | int jfs_fsync(struct file *file, struct dentry *dentry, int datasync) | 30 | int jfs_fsync(struct file *file, int datasync) |
31 | { | 31 | { |
32 | struct inode *inode = dentry->d_inode; | 32 | struct inode *inode = file->f_mapping->host; |
33 | int rc = 0; | 33 | int rc = 0; |
34 | 34 | ||
35 | if (!(inode->i_state & I_DIRTY) || | 35 | if (!(inode->i_state & I_DIRTY) || |
diff --git a/fs/jfs/jfs_inode.h b/fs/jfs/jfs_inode.h index 9e6bda30a6e8..11042b1f44b5 100644 --- a/fs/jfs/jfs_inode.h +++ b/fs/jfs/jfs_inode.h | |||
@@ -21,7 +21,7 @@ | |||
21 | struct fid; | 21 | struct fid; |
22 | 22 | ||
23 | extern struct inode *ialloc(struct inode *, umode_t); | 23 | extern struct inode *ialloc(struct inode *, umode_t); |
24 | extern int jfs_fsync(struct file *, struct dentry *, int); | 24 | extern int jfs_fsync(struct file *, int); |
25 | extern long jfs_ioctl(struct file *, unsigned int, unsigned long); | 25 | extern long jfs_ioctl(struct file *, unsigned int, unsigned long); |
26 | extern long jfs_compat_ioctl(struct file *, unsigned int, unsigned long); | 26 | extern long jfs_compat_ioctl(struct file *, unsigned int, unsigned long); |
27 | extern struct inode *jfs_iget(struct super_block *, unsigned long); | 27 | extern struct inode *jfs_iget(struct super_block *, unsigned long); |
diff --git a/fs/jfs/super.c b/fs/jfs/super.c index b66832ac33ac..b38f96bef829 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c | |||
@@ -179,6 +179,8 @@ static void jfs_put_super(struct super_block *sb) | |||
179 | 179 | ||
180 | jfs_info("In jfs_put_super"); | 180 | jfs_info("In jfs_put_super"); |
181 | 181 | ||
182 | dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); | ||
183 | |||
182 | lock_kernel(); | 184 | lock_kernel(); |
183 | 185 | ||
184 | rc = jfs_umount(sb); | 186 | rc = jfs_umount(sb); |
@@ -396,10 +398,20 @@ static int jfs_remount(struct super_block *sb, int *flags, char *data) | |||
396 | 398 | ||
397 | JFS_SBI(sb)->flag = flag; | 399 | JFS_SBI(sb)->flag = flag; |
398 | ret = jfs_mount_rw(sb, 1); | 400 | ret = jfs_mount_rw(sb, 1); |
401 | |||
402 | /* mark the fs r/w for quota activity */ | ||
403 | sb->s_flags &= ~MS_RDONLY; | ||
404 | |||
399 | unlock_kernel(); | 405 | unlock_kernel(); |
406 | dquot_resume(sb, -1); | ||
400 | return ret; | 407 | return ret; |
401 | } | 408 | } |
402 | if ((!(sb->s_flags & MS_RDONLY)) && (*flags & MS_RDONLY)) { | 409 | if ((!(sb->s_flags & MS_RDONLY)) && (*flags & MS_RDONLY)) { |
410 | rc = dquot_suspend(sb, -1); | ||
411 | if (rc < 0) { | ||
412 | unlock_kernel(); | ||
413 | return rc; | ||
414 | } | ||
403 | rc = jfs_umount_rw(sb); | 415 | rc = jfs_umount_rw(sb); |
404 | JFS_SBI(sb)->flag = flag; | 416 | JFS_SBI(sb)->flag = flag; |
405 | unlock_kernel(); | 417 | unlock_kernel(); |
@@ -469,6 +481,10 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent) | |||
469 | */ | 481 | */ |
470 | sb->s_op = &jfs_super_operations; | 482 | sb->s_op = &jfs_super_operations; |
471 | sb->s_export_op = &jfs_export_operations; | 483 | sb->s_export_op = &jfs_export_operations; |
484 | #ifdef CONFIG_QUOTA | ||
485 | sb->dq_op = &dquot_operations; | ||
486 | sb->s_qcop = &dquot_quotactl_ops; | ||
487 | #endif | ||
472 | 488 | ||
473 | /* | 489 | /* |
474 | * Initialize direct-mapping inode/address-space | 490 | * Initialize direct-mapping inode/address-space |
diff --git a/fs/libfs.c b/fs/libfs.c index 232bea425b09..09e1016eb774 100644 --- a/fs/libfs.c +++ b/fs/libfs.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/slab.h> | 8 | #include <linux/slab.h> |
9 | #include <linux/mount.h> | 9 | #include <linux/mount.h> |
10 | #include <linux/vfs.h> | 10 | #include <linux/vfs.h> |
11 | #include <linux/quotaops.h> | ||
11 | #include <linux/mutex.h> | 12 | #include <linux/mutex.h> |
12 | #include <linux/exportfs.h> | 13 | #include <linux/exportfs.h> |
13 | #include <linux/writeback.h> | 14 | #include <linux/writeback.h> |
@@ -58,11 +59,6 @@ struct dentry *simple_lookup(struct inode *dir, struct dentry *dentry, struct na | |||
58 | return NULL; | 59 | return NULL; |
59 | } | 60 | } |
60 | 61 | ||
61 | int simple_sync_file(struct file * file, struct dentry *dentry, int datasync) | ||
62 | { | ||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | int dcache_dir_open(struct inode *inode, struct file *file) | 62 | int dcache_dir_open(struct inode *inode, struct file *file) |
67 | { | 63 | { |
68 | static struct qstr cursor_name = {.len = 1, .name = "."}; | 64 | static struct qstr cursor_name = {.len = 1, .name = "."}; |
@@ -190,7 +186,7 @@ const struct file_operations simple_dir_operations = { | |||
190 | .llseek = dcache_dir_lseek, | 186 | .llseek = dcache_dir_lseek, |
191 | .read = generic_read_dir, | 187 | .read = generic_read_dir, |
192 | .readdir = dcache_readdir, | 188 | .readdir = dcache_readdir, |
193 | .fsync = simple_sync_file, | 189 | .fsync = noop_fsync, |
194 | }; | 190 | }; |
195 | 191 | ||
196 | const struct inode_operations simple_dir_inode_operations = { | 192 | const struct inode_operations simple_dir_inode_operations = { |
@@ -330,6 +326,81 @@ int simple_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
330 | return 0; | 326 | return 0; |
331 | } | 327 | } |
332 | 328 | ||
329 | /** | ||
330 | * simple_setsize - handle core mm and vfs requirements for file size change | ||
331 | * @inode: inode | ||
332 | * @newsize: new file size | ||
333 | * | ||
334 | * Returns 0 on success, -error on failure. | ||
335 | * | ||
336 | * simple_setsize must be called with inode_mutex held. | ||
337 | * | ||
338 | * simple_setsize will check that the requested new size is OK (see | ||
339 | * inode_newsize_ok), and then will perform the necessary i_size update | ||
340 | * and pagecache truncation (if necessary). It will be typically be called | ||
341 | * from the filesystem's setattr function when ATTR_SIZE is passed in. | ||
342 | * | ||
343 | * The inode itself must have correct permissions and attributes to allow | ||
344 | * i_size to be changed, this function then just checks that the new size | ||
345 | * requested is valid. | ||
346 | * | ||
347 | * In the case of simple in-memory filesystems with inodes stored solely | ||
348 | * in the inode cache, and file data in the pagecache, nothing more needs | ||
349 | * to be done to satisfy a truncate request. Filesystems with on-disk | ||
350 | * blocks for example will need to free them in the case of truncate, in | ||
351 | * that case it may be easier not to use simple_setsize (but each of its | ||
352 | * components will likely be required at some point to update pagecache | ||
353 | * and inode etc). | ||
354 | */ | ||
355 | int simple_setsize(struct inode *inode, loff_t newsize) | ||
356 | { | ||
357 | loff_t oldsize; | ||
358 | int error; | ||
359 | |||
360 | error = inode_newsize_ok(inode, newsize); | ||
361 | if (error) | ||
362 | return error; | ||
363 | |||
364 | oldsize = inode->i_size; | ||
365 | i_size_write(inode, newsize); | ||
366 | truncate_pagecache(inode, oldsize, newsize); | ||
367 | |||
368 | return error; | ||
369 | } | ||
370 | EXPORT_SYMBOL(simple_setsize); | ||
371 | |||
372 | /** | ||
373 | * simple_setattr - setattr for simple in-memory filesystem | ||
374 | * @dentry: dentry | ||
375 | * @iattr: iattr structure | ||
376 | * | ||
377 | * Returns 0 on success, -error on failure. | ||
378 | * | ||
379 | * simple_setattr implements setattr for an in-memory filesystem which | ||
380 | * does not store its own file data or metadata (eg. uses the page cache | ||
381 | * and inode cache as its data store). | ||
382 | */ | ||
383 | int simple_setattr(struct dentry *dentry, struct iattr *iattr) | ||
384 | { | ||
385 | struct inode *inode = dentry->d_inode; | ||
386 | int error; | ||
387 | |||
388 | error = inode_change_ok(inode, iattr); | ||
389 | if (error) | ||
390 | return error; | ||
391 | |||
392 | if (iattr->ia_valid & ATTR_SIZE) { | ||
393 | error = simple_setsize(inode, iattr->ia_size); | ||
394 | if (error) | ||
395 | return error; | ||
396 | } | ||
397 | |||
398 | generic_setattr(inode, iattr); | ||
399 | |||
400 | return error; | ||
401 | } | ||
402 | EXPORT_SYMBOL(simple_setattr); | ||
403 | |||
333 | int simple_readpage(struct file *file, struct page *page) | 404 | int simple_readpage(struct file *file, struct page *page) |
334 | { | 405 | { |
335 | clear_highpage(page); | 406 | clear_highpage(page); |
@@ -851,13 +922,22 @@ struct dentry *generic_fh_to_parent(struct super_block *sb, struct fid *fid, | |||
851 | } | 922 | } |
852 | EXPORT_SYMBOL_GPL(generic_fh_to_parent); | 923 | EXPORT_SYMBOL_GPL(generic_fh_to_parent); |
853 | 924 | ||
854 | int simple_fsync(struct file *file, struct dentry *dentry, int datasync) | 925 | /** |
926 | * generic_file_fsync - generic fsync implementation for simple filesystems | ||
927 | * @file: file to synchronize | ||
928 | * @datasync: only synchronize essential metadata if true | ||
929 | * | ||
930 | * This is a generic implementation of the fsync method for simple | ||
931 | * filesystems which track all non-inode metadata in the buffers list | ||
932 | * hanging off the address_space structure. | ||
933 | */ | ||
934 | int generic_file_fsync(struct file *file, int datasync) | ||
855 | { | 935 | { |
856 | struct writeback_control wbc = { | 936 | struct writeback_control wbc = { |
857 | .sync_mode = WB_SYNC_ALL, | 937 | .sync_mode = WB_SYNC_ALL, |
858 | .nr_to_write = 0, /* metadata-only; caller takes care of data */ | 938 | .nr_to_write = 0, /* metadata-only; caller takes care of data */ |
859 | }; | 939 | }; |
860 | struct inode *inode = dentry->d_inode; | 940 | struct inode *inode = file->f_mapping->host; |
861 | int err; | 941 | int err; |
862 | int ret; | 942 | int ret; |
863 | 943 | ||
@@ -872,7 +952,15 @@ int simple_fsync(struct file *file, struct dentry *dentry, int datasync) | |||
872 | ret = err; | 952 | ret = err; |
873 | return ret; | 953 | return ret; |
874 | } | 954 | } |
875 | EXPORT_SYMBOL(simple_fsync); | 955 | EXPORT_SYMBOL(generic_file_fsync); |
956 | |||
957 | /* | ||
958 | * No-op implementation of ->fsync for in-memory filesystems. | ||
959 | */ | ||
960 | int noop_fsync(struct file *file, int datasync) | ||
961 | { | ||
962 | return 0; | ||
963 | } | ||
876 | 964 | ||
877 | EXPORT_SYMBOL(dcache_dir_close); | 965 | EXPORT_SYMBOL(dcache_dir_close); |
878 | EXPORT_SYMBOL(dcache_dir_lseek); | 966 | EXPORT_SYMBOL(dcache_dir_lseek); |
@@ -895,7 +983,7 @@ EXPORT_SYMBOL(simple_release_fs); | |||
895 | EXPORT_SYMBOL(simple_rename); | 983 | EXPORT_SYMBOL(simple_rename); |
896 | EXPORT_SYMBOL(simple_rmdir); | 984 | EXPORT_SYMBOL(simple_rmdir); |
897 | EXPORT_SYMBOL(simple_statfs); | 985 | EXPORT_SYMBOL(simple_statfs); |
898 | EXPORT_SYMBOL(simple_sync_file); | 986 | EXPORT_SYMBOL(noop_fsync); |
899 | EXPORT_SYMBOL(simple_unlink); | 987 | EXPORT_SYMBOL(simple_unlink); |
900 | EXPORT_SYMBOL(simple_read_from_buffer); | 988 | EXPORT_SYMBOL(simple_read_from_buffer); |
901 | EXPORT_SYMBOL(simple_write_to_buffer); | 989 | EXPORT_SYMBOL(simple_write_to_buffer); |
diff --git a/fs/logfs/file.c b/fs/logfs/file.c index 0de524071870..abe1cafbd4c2 100644 --- a/fs/logfs/file.c +++ b/fs/logfs/file.c | |||
@@ -219,9 +219,9 @@ int logfs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
219 | } | 219 | } |
220 | } | 220 | } |
221 | 221 | ||
222 | int logfs_fsync(struct file *file, struct dentry *dentry, int datasync) | 222 | int logfs_fsync(struct file *file, int datasync) |
223 | { | 223 | { |
224 | struct super_block *sb = dentry->d_inode->i_sb; | 224 | struct super_block *sb = file->f_mapping->host->i_sb; |
225 | 225 | ||
226 | logfs_write_anchor(sb); | 226 | logfs_write_anchor(sb); |
227 | return 0; | 227 | return 0; |
diff --git a/fs/logfs/logfs.h b/fs/logfs/logfs.h index 1a9db84f8d8f..c838c4d72111 100644 --- a/fs/logfs/logfs.h +++ b/fs/logfs/logfs.h | |||
@@ -506,7 +506,7 @@ extern const struct address_space_operations logfs_reg_aops; | |||
506 | int logfs_readpage(struct file *file, struct page *page); | 506 | int logfs_readpage(struct file *file, struct page *page); |
507 | int logfs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 507 | int logfs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, |
508 | unsigned long arg); | 508 | unsigned long arg); |
509 | int logfs_fsync(struct file *file, struct dentry *dentry, int datasync); | 509 | int logfs_fsync(struct file *file, int datasync); |
510 | 510 | ||
511 | /* gc.c */ | 511 | /* gc.c */ |
512 | u32 get_best_cand(struct super_block *sb, struct candidate_list *list, u32 *ec); | 512 | u32 get_best_cand(struct super_block *sb, struct candidate_list *list, u32 *ec); |
diff --git a/fs/minix/dir.c b/fs/minix/dir.c index 6198731d7fcd..91969589131c 100644 --- a/fs/minix/dir.c +++ b/fs/minix/dir.c | |||
@@ -22,7 +22,7 @@ const struct file_operations minix_dir_operations = { | |||
22 | .llseek = generic_file_llseek, | 22 | .llseek = generic_file_llseek, |
23 | .read = generic_read_dir, | 23 | .read = generic_read_dir, |
24 | .readdir = minix_readdir, | 24 | .readdir = minix_readdir, |
25 | .fsync = simple_fsync, | 25 | .fsync = generic_file_fsync, |
26 | }; | 26 | }; |
27 | 27 | ||
28 | static inline void dir_put_page(struct page *page) | 28 | static inline void dir_put_page(struct page *page) |
@@ -72,11 +72,8 @@ static struct page * dir_get_page(struct inode *dir, unsigned long n) | |||
72 | { | 72 | { |
73 | struct address_space *mapping = dir->i_mapping; | 73 | struct address_space *mapping = dir->i_mapping; |
74 | struct page *page = read_mapping_page(mapping, n, NULL); | 74 | struct page *page = read_mapping_page(mapping, n, NULL); |
75 | if (!IS_ERR(page)) { | 75 | if (!IS_ERR(page)) |
76 | kmap(page); | 76 | kmap(page); |
77 | if (!PageUptodate(page)) | ||
78 | goto fail; | ||
79 | } | ||
80 | return page; | 77 | return page; |
81 | 78 | ||
82 | fail: | 79 | fail: |
diff --git a/fs/minix/file.c b/fs/minix/file.c index 3eec3e607a87..d5320ff23faf 100644 --- a/fs/minix/file.c +++ b/fs/minix/file.c | |||
@@ -19,7 +19,7 @@ const struct file_operations minix_file_operations = { | |||
19 | .write = do_sync_write, | 19 | .write = do_sync_write, |
20 | .aio_write = generic_file_aio_write, | 20 | .aio_write = generic_file_aio_write, |
21 | .mmap = generic_file_mmap, | 21 | .mmap = generic_file_mmap, |
22 | .fsync = simple_fsync, | 22 | .fsync = generic_file_fsync, |
23 | .splice_read = generic_file_splice_read, | 23 | .splice_read = generic_file_splice_read, |
24 | }; | 24 | }; |
25 | 25 | ||
diff --git a/fs/minix/itree_v2.c b/fs/minix/itree_v2.c index f23010969369..13487ad16894 100644 --- a/fs/minix/itree_v2.c +++ b/fs/minix/itree_v2.c | |||
@@ -20,6 +20,9 @@ static inline block_t *i_data(struct inode *inode) | |||
20 | return (block_t *)minix_i(inode)->u.i2_data; | 20 | return (block_t *)minix_i(inode)->u.i2_data; |
21 | } | 21 | } |
22 | 22 | ||
23 | #define DIRCOUNT 7 | ||
24 | #define INDIRCOUNT(sb) (1 << ((sb)->s_blocksize_bits - 2)) | ||
25 | |||
23 | static int block_to_path(struct inode * inode, long block, int offsets[DEPTH]) | 26 | static int block_to_path(struct inode * inode, long block, int offsets[DEPTH]) |
24 | { | 27 | { |
25 | int n = 0; | 28 | int n = 0; |
@@ -34,21 +37,21 @@ static int block_to_path(struct inode * inode, long block, int offsets[DEPTH]) | |||
34 | printk("MINIX-fs: block_to_path: " | 37 | printk("MINIX-fs: block_to_path: " |
35 | "block %ld too big on dev %s\n", | 38 | "block %ld too big on dev %s\n", |
36 | block, bdevname(sb->s_bdev, b)); | 39 | block, bdevname(sb->s_bdev, b)); |
37 | } else if (block < 7) { | 40 | } else if (block < DIRCOUNT) { |
38 | offsets[n++] = block; | 41 | offsets[n++] = block; |
39 | } else if ((block -= 7) < 256) { | 42 | } else if ((block -= DIRCOUNT) < INDIRCOUNT(sb)) { |
40 | offsets[n++] = 7; | 43 | offsets[n++] = DIRCOUNT; |
41 | offsets[n++] = block; | 44 | offsets[n++] = block; |
42 | } else if ((block -= 256) < 256*256) { | 45 | } else if ((block -= INDIRCOUNT(sb)) < INDIRCOUNT(sb) * INDIRCOUNT(sb)) { |
43 | offsets[n++] = 8; | 46 | offsets[n++] = DIRCOUNT + 1; |
44 | offsets[n++] = block>>8; | 47 | offsets[n++] = block / INDIRCOUNT(sb); |
45 | offsets[n++] = block & 255; | 48 | offsets[n++] = block % INDIRCOUNT(sb); |
46 | } else { | 49 | } else { |
47 | block -= 256*256; | 50 | block -= INDIRCOUNT(sb) * INDIRCOUNT(sb); |
48 | offsets[n++] = 9; | 51 | offsets[n++] = DIRCOUNT + 2; |
49 | offsets[n++] = block>>16; | 52 | offsets[n++] = (block / INDIRCOUNT(sb)) / INDIRCOUNT(sb); |
50 | offsets[n++] = (block>>8) & 255; | 53 | offsets[n++] = (block / INDIRCOUNT(sb)) % INDIRCOUNT(sb); |
51 | offsets[n++] = block & 255; | 54 | offsets[n++] = block % INDIRCOUNT(sb); |
52 | } | 55 | } |
53 | return n; | 56 | return n; |
54 | } | 57 | } |
diff --git a/fs/namei.c b/fs/namei.c index 48e1f60520ea..868d0cb9d473 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -1621,6 +1621,7 @@ static struct file *do_last(struct nameidata *nd, struct path *path, | |||
1621 | case LAST_DOTDOT: | 1621 | case LAST_DOTDOT: |
1622 | follow_dotdot(nd); | 1622 | follow_dotdot(nd); |
1623 | dir = nd->path.dentry; | 1623 | dir = nd->path.dentry; |
1624 | case LAST_DOT: | ||
1624 | if (nd->path.mnt->mnt_sb->s_type->fs_flags & FS_REVAL_DOT) { | 1625 | if (nd->path.mnt->mnt_sb->s_type->fs_flags & FS_REVAL_DOT) { |
1625 | if (!dir->d_op->d_revalidate(dir, nd)) { | 1626 | if (!dir->d_op->d_revalidate(dir, nd)) { |
1626 | error = -ESTALE; | 1627 | error = -ESTALE; |
@@ -1628,7 +1629,6 @@ static struct file *do_last(struct nameidata *nd, struct path *path, | |||
1628 | } | 1629 | } |
1629 | } | 1630 | } |
1630 | /* fallthrough */ | 1631 | /* fallthrough */ |
1631 | case LAST_DOT: | ||
1632 | case LAST_ROOT: | 1632 | case LAST_ROOT: |
1633 | if (open_flag & O_CREAT) | 1633 | if (open_flag & O_CREAT) |
1634 | goto exit; | 1634 | goto exit; |
diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c index b93870892892..3639cc5cbdae 100644 --- a/fs/ncpfs/file.c +++ b/fs/ncpfs/file.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include <linux/ncp_fs.h> | 22 | #include <linux/ncp_fs.h> |
23 | #include "ncplib_kernel.h" | 23 | #include "ncplib_kernel.h" |
24 | 24 | ||
25 | static int ncp_fsync(struct file *file, struct dentry *dentry, int datasync) | 25 | static int ncp_fsync(struct file *file, int datasync) |
26 | { | 26 | { |
27 | return 0; | 27 | return 0; |
28 | } | 28 | } |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index db64854b7b09..782b431ef91c 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -53,7 +53,7 @@ static int nfs_link(struct dentry *, struct inode *, struct dentry *); | |||
53 | static int nfs_mknod(struct inode *, struct dentry *, int, dev_t); | 53 | static int nfs_mknod(struct inode *, struct dentry *, int, dev_t); |
54 | static int nfs_rename(struct inode *, struct dentry *, | 54 | static int nfs_rename(struct inode *, struct dentry *, |
55 | struct inode *, struct dentry *); | 55 | struct inode *, struct dentry *); |
56 | static int nfs_fsync_dir(struct file *, struct dentry *, int); | 56 | static int nfs_fsync_dir(struct file *, int); |
57 | static loff_t nfs_llseek_dir(struct file *, loff_t, int); | 57 | static loff_t nfs_llseek_dir(struct file *, loff_t, int); |
58 | 58 | ||
59 | const struct file_operations nfs_dir_operations = { | 59 | const struct file_operations nfs_dir_operations = { |
@@ -641,8 +641,10 @@ out: | |||
641 | * All directory operations under NFS are synchronous, so fsync() | 641 | * All directory operations under NFS are synchronous, so fsync() |
642 | * is a dummy operation. | 642 | * is a dummy operation. |
643 | */ | 643 | */ |
644 | static int nfs_fsync_dir(struct file *filp, struct dentry *dentry, int datasync) | 644 | static int nfs_fsync_dir(struct file *filp, int datasync) |
645 | { | 645 | { |
646 | struct dentry *dentry = filp->f_path.dentry; | ||
647 | |||
646 | dfprintk(FILE, "NFS: fsync dir(%s/%s) datasync %d\n", | 648 | dfprintk(FILE, "NFS: fsync dir(%s/%s) datasync %d\n", |
647 | dentry->d_parent->d_name.name, dentry->d_name.name, | 649 | dentry->d_parent->d_name.name, dentry->d_name.name, |
648 | datasync); | 650 | datasync); |
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index cac96bcc91e4..36a5e74f51b4 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c | |||
@@ -53,7 +53,7 @@ static ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe, | |||
53 | static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov, | 53 | static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov, |
54 | unsigned long nr_segs, loff_t pos); | 54 | unsigned long nr_segs, loff_t pos); |
55 | static int nfs_file_flush(struct file *, fl_owner_t id); | 55 | static int nfs_file_flush(struct file *, fl_owner_t id); |
56 | static int nfs_file_fsync(struct file *, struct dentry *dentry, int datasync); | 56 | static int nfs_file_fsync(struct file *, int datasync); |
57 | static int nfs_check_flags(int flags); | 57 | static int nfs_check_flags(int flags); |
58 | static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl); | 58 | static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl); |
59 | static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl); | 59 | static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl); |
@@ -322,8 +322,9 @@ nfs_file_mmap(struct file * file, struct vm_area_struct * vma) | |||
322 | * whether any write errors occurred for this process. | 322 | * whether any write errors occurred for this process. |
323 | */ | 323 | */ |
324 | static int | 324 | static int |
325 | nfs_file_fsync(struct file *file, struct dentry *dentry, int datasync) | 325 | nfs_file_fsync(struct file *file, int datasync) |
326 | { | 326 | { |
327 | struct dentry *dentry = file->f_path.dentry; | ||
327 | struct nfs_open_context *ctx = nfs_file_open_context(file); | 328 | struct nfs_open_context *ctx = nfs_file_open_context(file); |
328 | struct inode *inode = dentry->d_inode; | 329 | struct inode *inode = dentry->d_inode; |
329 | 330 | ||
diff --git a/fs/nilfs2/file.c b/fs/nilfs2/file.c index 30292df443ce..c9a30d7ff6fc 100644 --- a/fs/nilfs2/file.c +++ b/fs/nilfs2/file.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include "nilfs.h" | 27 | #include "nilfs.h" |
28 | #include "segment.h" | 28 | #include "segment.h" |
29 | 29 | ||
30 | int nilfs_sync_file(struct file *file, struct dentry *dentry, int datasync) | 30 | int nilfs_sync_file(struct file *file, int datasync) |
31 | { | 31 | { |
32 | /* | 32 | /* |
33 | * Called from fsync() system call | 33 | * Called from fsync() system call |
@@ -37,7 +37,7 @@ int nilfs_sync_file(struct file *file, struct dentry *dentry, int datasync) | |||
37 | * This function should be implemented when the writeback function | 37 | * This function should be implemented when the writeback function |
38 | * will be implemented. | 38 | * will be implemented. |
39 | */ | 39 | */ |
40 | struct inode *inode = dentry->d_inode; | 40 | struct inode *inode = file->f_mapping->host; |
41 | int err; | 41 | int err; |
42 | 42 | ||
43 | if (!nilfs_inode_dirty(inode)) | 43 | if (!nilfs_inode_dirty(inode)) |
diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h index 8723e5bfd071..47d6d7928122 100644 --- a/fs/nilfs2/nilfs.h +++ b/fs/nilfs2/nilfs.h | |||
@@ -228,7 +228,7 @@ extern void nilfs_set_link(struct inode *, struct nilfs_dir_entry *, | |||
228 | struct page *, struct inode *); | 228 | struct page *, struct inode *); |
229 | 229 | ||
230 | /* file.c */ | 230 | /* file.c */ |
231 | extern int nilfs_sync_file(struct file *, struct dentry *, int); | 231 | extern int nilfs_sync_file(struct file *, int); |
232 | 232 | ||
233 | /* ioctl.c */ | 233 | /* ioctl.c */ |
234 | long nilfs_ioctl(struct file *, unsigned int, unsigned long); | 234 | long nilfs_ioctl(struct file *, unsigned int, unsigned long); |
diff --git a/fs/ntfs/dir.c b/fs/ntfs/dir.c index fe44d3feee4a..0f48e7c5d9e1 100644 --- a/fs/ntfs/dir.c +++ b/fs/ntfs/dir.c | |||
@@ -1527,10 +1527,9 @@ static int ntfs_dir_open(struct inode *vi, struct file *filp) | |||
1527 | * this problem for now. We do write the $BITMAP attribute if it is present | 1527 | * this problem for now. We do write the $BITMAP attribute if it is present |
1528 | * which is the important one for a directory so things are not too bad. | 1528 | * which is the important one for a directory so things are not too bad. |
1529 | */ | 1529 | */ |
1530 | static int ntfs_dir_fsync(struct file *filp, struct dentry *dentry, | 1530 | static int ntfs_dir_fsync(struct file *filp, int datasync) |
1531 | int datasync) | ||
1532 | { | 1531 | { |
1533 | struct inode *bmp_vi, *vi = dentry->d_inode; | 1532 | struct inode *bmp_vi, *vi = filp->f_mapping->host; |
1534 | int err, ret; | 1533 | int err, ret; |
1535 | ntfs_attr na; | 1534 | ntfs_attr na; |
1536 | 1535 | ||
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c index a1924a0d2ab0..113ebd9f25a4 100644 --- a/fs/ntfs/file.c +++ b/fs/ntfs/file.c | |||
@@ -2133,7 +2133,6 @@ static ssize_t ntfs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
2133 | /** | 2133 | /** |
2134 | * ntfs_file_fsync - sync a file to disk | 2134 | * ntfs_file_fsync - sync a file to disk |
2135 | * @filp: file to be synced | 2135 | * @filp: file to be synced |
2136 | * @dentry: dentry describing the file to sync | ||
2137 | * @datasync: if non-zero only flush user data and not metadata | 2136 | * @datasync: if non-zero only flush user data and not metadata |
2138 | * | 2137 | * |
2139 | * Data integrity sync of a file to disk. Used for fsync, fdatasync, and msync | 2138 | * Data integrity sync of a file to disk. Used for fsync, fdatasync, and msync |
@@ -2149,19 +2148,15 @@ static ssize_t ntfs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
2149 | * Also, if @datasync is true, we do not wait on the inode to be written out | 2148 | * Also, if @datasync is true, we do not wait on the inode to be written out |
2150 | * but we always wait on the page cache pages to be written out. | 2149 | * but we always wait on the page cache pages to be written out. |
2151 | * | 2150 | * |
2152 | * Note: In the past @filp could be NULL so we ignore it as we don't need it | ||
2153 | * anyway. | ||
2154 | * | ||
2155 | * Locking: Caller must hold i_mutex on the inode. | 2151 | * Locking: Caller must hold i_mutex on the inode. |
2156 | * | 2152 | * |
2157 | * TODO: We should probably also write all attribute/index inodes associated | 2153 | * TODO: We should probably also write all attribute/index inodes associated |
2158 | * with this inode but since we have no simple way of getting to them we ignore | 2154 | * with this inode but since we have no simple way of getting to them we ignore |
2159 | * this problem for now. | 2155 | * this problem for now. |
2160 | */ | 2156 | */ |
2161 | static int ntfs_file_fsync(struct file *filp, struct dentry *dentry, | 2157 | static int ntfs_file_fsync(struct file *filp, int datasync) |
2162 | int datasync) | ||
2163 | { | 2158 | { |
2164 | struct inode *vi = dentry->d_inode; | 2159 | struct inode *vi = filp->f_mapping->host; |
2165 | int err, ret = 0; | 2160 | int err, ret = 0; |
2166 | 2161 | ||
2167 | ntfs_debug("Entering for inode 0x%lx.", vi->i_ino); | 2162 | ntfs_debug("Entering for inode 0x%lx.", vi->i_ino); |
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 97e54b9e654b..6a13ea64c447 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -175,13 +175,12 @@ static int ocfs2_dir_release(struct inode *inode, struct file *file) | |||
175 | return 0; | 175 | return 0; |
176 | } | 176 | } |
177 | 177 | ||
178 | static int ocfs2_sync_file(struct file *file, | 178 | static int ocfs2_sync_file(struct file *file, int datasync) |
179 | struct dentry *dentry, | ||
180 | int datasync) | ||
181 | { | 179 | { |
182 | int err = 0; | 180 | int err = 0; |
183 | journal_t *journal; | 181 | journal_t *journal; |
184 | struct inode *inode = dentry->d_inode; | 182 | struct dentry *dentry = file->f_path.dentry; |
183 | struct inode *inode = file->f_mapping->host; | ||
185 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 184 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
186 | 185 | ||
187 | mlog_entry("(0x%p, 0x%p, %d, '%.*s')\n", file, dentry, datasync, | 186 | mlog_entry("(0x%p, 0x%p, %d, '%.*s')\n", file, dentry, datasync, |
@@ -1053,7 +1052,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) | |||
1053 | } | 1052 | } |
1054 | 1053 | ||
1055 | /* | 1054 | /* |
1056 | * This will intentionally not wind up calling vmtruncate(), | 1055 | * This will intentionally not wind up calling simple_setsize(), |
1057 | * since all the work for a size change has been done above. | 1056 | * since all the work for a size change has been done above. |
1058 | * Otherwise, we could get into problems with truncate as | 1057 | * Otherwise, we could get into problems with truncate as |
1059 | * ip_alloc_sem is used there to protect against i_size | 1058 | * ip_alloc_sem is used there to protect against i_size |
@@ -2119,9 +2118,13 @@ relock: | |||
2119 | * direct write may have instantiated a few | 2118 | * direct write may have instantiated a few |
2120 | * blocks outside i_size. Trim these off again. | 2119 | * blocks outside i_size. Trim these off again. |
2121 | * Don't need i_size_read because we hold i_mutex. | 2120 | * Don't need i_size_read because we hold i_mutex. |
2121 | * | ||
2122 | * XXX(hch): this looks buggy because ocfs2 did not | ||
2123 | * actually implement ->truncate. Take a look at | ||
2124 | * the new truncate sequence and update this accordingly | ||
2122 | */ | 2125 | */ |
2123 | if (*ppos + count > inode->i_size) | 2126 | if (*ppos + count > inode->i_size) |
2124 | vmtruncate(inode, inode->i_size); | 2127 | simple_setsize(inode, inode->i_size); |
2125 | ret = written; | 2128 | ret = written; |
2126 | goto out_dio; | 2129 | goto out_dio; |
2127 | } | 2130 | } |
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 2c26ce251cb3..0eaa929a4dbf 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c | |||
@@ -879,13 +879,15 @@ static int ocfs2_susp_quotas(struct ocfs2_super *osb, int unsuspend) | |||
879 | if (!OCFS2_HAS_RO_COMPAT_FEATURE(sb, feature[type])) | 879 | if (!OCFS2_HAS_RO_COMPAT_FEATURE(sb, feature[type])) |
880 | continue; | 880 | continue; |
881 | if (unsuspend) | 881 | if (unsuspend) |
882 | status = vfs_quota_enable( | 882 | status = dquot_resume(sb, type); |
883 | sb_dqopt(sb)->files[type], | 883 | else { |
884 | type, QFMT_OCFS2, | 884 | struct ocfs2_mem_dqinfo *oinfo; |
885 | DQUOT_SUSPENDED); | 885 | |
886 | else | 886 | /* Cancel periodic syncing before suspending */ |
887 | status = vfs_quota_disable(sb, type, | 887 | oinfo = sb_dqinfo(sb, type)->dqi_priv; |
888 | DQUOT_SUSPENDED); | 888 | cancel_delayed_work_sync(&oinfo->dqi_sync_work); |
889 | status = dquot_suspend(sb, type); | ||
890 | } | ||
889 | if (status < 0) | 891 | if (status < 0) |
890 | break; | 892 | break; |
891 | } | 893 | } |
@@ -916,8 +918,8 @@ static int ocfs2_enable_quotas(struct ocfs2_super *osb) | |||
916 | status = -ENOENT; | 918 | status = -ENOENT; |
917 | goto out_quota_off; | 919 | goto out_quota_off; |
918 | } | 920 | } |
919 | status = vfs_quota_enable(inode[type], type, QFMT_OCFS2, | 921 | status = dquot_enable(inode[type], type, QFMT_OCFS2, |
920 | DQUOT_USAGE_ENABLED); | 922 | DQUOT_USAGE_ENABLED); |
921 | if (status < 0) | 923 | if (status < 0) |
922 | goto out_quota_off; | 924 | goto out_quota_off; |
923 | } | 925 | } |
@@ -952,8 +954,8 @@ static void ocfs2_disable_quotas(struct ocfs2_super *osb) | |||
952 | /* Turn off quotas. This will remove all dquot structures from | 954 | /* Turn off quotas. This will remove all dquot structures from |
953 | * memory and so they will be automatically synced to global | 955 | * memory and so they will be automatically synced to global |
954 | * quota files */ | 956 | * quota files */ |
955 | vfs_quota_disable(sb, type, DQUOT_USAGE_ENABLED | | 957 | dquot_disable(sb, type, DQUOT_USAGE_ENABLED | |
956 | DQUOT_LIMITS_ENABLED); | 958 | DQUOT_LIMITS_ENABLED); |
957 | if (!inode) | 959 | if (!inode) |
958 | continue; | 960 | continue; |
959 | iput(inode); | 961 | iput(inode); |
@@ -962,7 +964,7 @@ static void ocfs2_disable_quotas(struct ocfs2_super *osb) | |||
962 | 964 | ||
963 | /* Handle quota on quotactl */ | 965 | /* Handle quota on quotactl */ |
964 | static int ocfs2_quota_on(struct super_block *sb, int type, int format_id, | 966 | static int ocfs2_quota_on(struct super_block *sb, int type, int format_id, |
965 | char *path, int remount) | 967 | char *path) |
966 | { | 968 | { |
967 | unsigned int feature[MAXQUOTAS] = { OCFS2_FEATURE_RO_COMPAT_USRQUOTA, | 969 | unsigned int feature[MAXQUOTAS] = { OCFS2_FEATURE_RO_COMPAT_USRQUOTA, |
968 | OCFS2_FEATURE_RO_COMPAT_GRPQUOTA}; | 970 | OCFS2_FEATURE_RO_COMPAT_GRPQUOTA}; |
@@ -970,30 +972,24 @@ static int ocfs2_quota_on(struct super_block *sb, int type, int format_id, | |||
970 | if (!OCFS2_HAS_RO_COMPAT_FEATURE(sb, feature[type])) | 972 | if (!OCFS2_HAS_RO_COMPAT_FEATURE(sb, feature[type])) |
971 | return -EINVAL; | 973 | return -EINVAL; |
972 | 974 | ||
973 | if (remount) | 975 | return dquot_enable(sb_dqopt(sb)->files[type], type, |
974 | return 0; /* Just ignore it has been handled in | 976 | format_id, DQUOT_LIMITS_ENABLED); |
975 | * ocfs2_remount() */ | ||
976 | return vfs_quota_enable(sb_dqopt(sb)->files[type], type, | ||
977 | format_id, DQUOT_LIMITS_ENABLED); | ||
978 | } | 977 | } |
979 | 978 | ||
980 | /* Handle quota off quotactl */ | 979 | /* Handle quota off quotactl */ |
981 | static int ocfs2_quota_off(struct super_block *sb, int type, int remount) | 980 | static int ocfs2_quota_off(struct super_block *sb, int type) |
982 | { | 981 | { |
983 | if (remount) | 982 | return dquot_disable(sb, type, DQUOT_LIMITS_ENABLED); |
984 | return 0; /* Ignore now and handle later in | ||
985 | * ocfs2_remount() */ | ||
986 | return vfs_quota_disable(sb, type, DQUOT_LIMITS_ENABLED); | ||
987 | } | 983 | } |
988 | 984 | ||
989 | static const struct quotactl_ops ocfs2_quotactl_ops = { | 985 | static const struct quotactl_ops ocfs2_quotactl_ops = { |
990 | .quota_on = ocfs2_quota_on, | 986 | .quota_on = ocfs2_quota_on, |
991 | .quota_off = ocfs2_quota_off, | 987 | .quota_off = ocfs2_quota_off, |
992 | .quota_sync = vfs_quota_sync, | 988 | .quota_sync = dquot_quota_sync, |
993 | .get_info = vfs_get_dqinfo, | 989 | .get_info = dquot_get_dqinfo, |
994 | .set_info = vfs_set_dqinfo, | 990 | .set_info = dquot_set_dqinfo, |
995 | .get_dqblk = vfs_get_dqblk, | 991 | .get_dqblk = dquot_get_dqblk, |
996 | .set_dqblk = vfs_set_dqblk, | 992 | .set_dqblk = dquot_set_dqblk, |
997 | }; | 993 | }; |
998 | 994 | ||
999 | static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) | 995 | static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) |
diff --git a/fs/omfs/file.c b/fs/omfs/file.c index 399487c09364..6e7a3291bbe8 100644 --- a/fs/omfs/file.c +++ b/fs/omfs/file.c | |||
@@ -329,7 +329,7 @@ const struct file_operations omfs_file_operations = { | |||
329 | .aio_read = generic_file_aio_read, | 329 | .aio_read = generic_file_aio_read, |
330 | .aio_write = generic_file_aio_write, | 330 | .aio_write = generic_file_aio_write, |
331 | .mmap = generic_file_mmap, | 331 | .mmap = generic_file_mmap, |
332 | .fsync = simple_fsync, | 332 | .fsync = generic_file_fsync, |
333 | .splice_read = generic_file_splice_read, | 333 | .splice_read = generic_file_splice_read, |
334 | }; | 334 | }; |
335 | 335 | ||
@@ -1169,14 +1169,18 @@ long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg) | |||
1169 | 1169 | ||
1170 | switch (cmd) { | 1170 | switch (cmd) { |
1171 | case F_SETPIPE_SZ: | 1171 | case F_SETPIPE_SZ: |
1172 | if (!capable(CAP_SYS_ADMIN) && arg > pipe_max_pages) | 1172 | if (!capable(CAP_SYS_ADMIN) && arg > pipe_max_pages) { |
1173 | return -EINVAL; | 1173 | ret = -EINVAL; |
1174 | goto out; | ||
1175 | } | ||
1174 | /* | 1176 | /* |
1175 | * The pipe needs to be at least 2 pages large to | 1177 | * The pipe needs to be at least 2 pages large to |
1176 | * guarantee POSIX behaviour. | 1178 | * guarantee POSIX behaviour. |
1177 | */ | 1179 | */ |
1178 | if (arg < 2) | 1180 | if (arg < 2) { |
1179 | return -EINVAL; | 1181 | ret = -EINVAL; |
1182 | goto out; | ||
1183 | } | ||
1180 | ret = pipe_set_size(pipe, arg); | 1184 | ret = pipe_set_size(pipe, arg); |
1181 | break; | 1185 | break; |
1182 | case F_GETPIPE_SZ: | 1186 | case F_GETPIPE_SZ: |
@@ -1187,6 +1191,7 @@ long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg) | |||
1187 | break; | 1191 | break; |
1188 | } | 1192 | } |
1189 | 1193 | ||
1194 | out: | ||
1190 | mutex_unlock(&pipe->inode->i_mutex); | 1195 | mutex_unlock(&pipe->inode->i_mutex); |
1191 | return ret; | 1196 | return ret; |
1192 | } | 1197 | } |
diff --git a/fs/qnx4/dir.c b/fs/qnx4/dir.c index 3d3fd4692133..6e8fc62b40a8 100644 --- a/fs/qnx4/dir.c +++ b/fs/qnx4/dir.c | |||
@@ -80,7 +80,7 @@ const struct file_operations qnx4_dir_operations = | |||
80 | .llseek = generic_file_llseek, | 80 | .llseek = generic_file_llseek, |
81 | .read = generic_read_dir, | 81 | .read = generic_read_dir, |
82 | .readdir = qnx4_readdir, | 82 | .readdir = qnx4_readdir, |
83 | .fsync = simple_fsync, | 83 | .fsync = generic_file_fsync, |
84 | }; | 84 | }; |
85 | 85 | ||
86 | const struct inode_operations qnx4_dir_inode_operations = | 86 | const struct inode_operations qnx4_dir_inode_operations = |
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 1ad8bf076cfc..12c233da1b6b 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c | |||
@@ -228,10 +228,6 @@ static struct hlist_head *dquot_hash; | |||
228 | 228 | ||
229 | struct dqstats dqstats; | 229 | struct dqstats dqstats; |
230 | EXPORT_SYMBOL(dqstats); | 230 | EXPORT_SYMBOL(dqstats); |
231 | #ifdef CONFIG_SMP | ||
232 | struct dqstats *dqstats_pcpu; | ||
233 | EXPORT_SYMBOL(dqstats_pcpu); | ||
234 | #endif | ||
235 | 231 | ||
236 | static qsize_t inode_get_rsv_space(struct inode *inode); | 232 | static qsize_t inode_get_rsv_space(struct inode *inode); |
237 | static void __dquot_initialize(struct inode *inode, int type); | 233 | static void __dquot_initialize(struct inode *inode, int type); |
@@ -584,7 +580,7 @@ out: | |||
584 | } | 580 | } |
585 | EXPORT_SYMBOL(dquot_scan_active); | 581 | EXPORT_SYMBOL(dquot_scan_active); |
586 | 582 | ||
587 | int vfs_quota_sync(struct super_block *sb, int type, int wait) | 583 | int dquot_quota_sync(struct super_block *sb, int type, int wait) |
588 | { | 584 | { |
589 | struct list_head *dirty; | 585 | struct list_head *dirty; |
590 | struct dquot *dquot; | 586 | struct dquot *dquot; |
@@ -656,7 +652,7 @@ int vfs_quota_sync(struct super_block *sb, int type, int wait) | |||
656 | 652 | ||
657 | return 0; | 653 | return 0; |
658 | } | 654 | } |
659 | EXPORT_SYMBOL(vfs_quota_sync); | 655 | EXPORT_SYMBOL(dquot_quota_sync); |
660 | 656 | ||
661 | /* Free unused dquots from cache */ | 657 | /* Free unused dquots from cache */ |
662 | static void prune_dqcache(int count) | 658 | static void prune_dqcache(int count) |
@@ -676,27 +672,10 @@ static void prune_dqcache(int count) | |||
676 | } | 672 | } |
677 | } | 673 | } |
678 | 674 | ||
679 | static int dqstats_read(unsigned int type) | ||
680 | { | ||
681 | int count = 0; | ||
682 | #ifdef CONFIG_SMP | ||
683 | int cpu; | ||
684 | for_each_possible_cpu(cpu) | ||
685 | count += per_cpu_ptr(dqstats_pcpu, cpu)->stat[type]; | ||
686 | /* Statistics reading is racy, but absolute accuracy isn't required */ | ||
687 | if (count < 0) | ||
688 | count = 0; | ||
689 | #else | ||
690 | count = dqstats.stat[type]; | ||
691 | #endif | ||
692 | return count; | ||
693 | } | ||
694 | |||
695 | /* | 675 | /* |
696 | * This is called from kswapd when we think we need some | 676 | * This is called from kswapd when we think we need some |
697 | * more memory | 677 | * more memory |
698 | */ | 678 | */ |
699 | |||
700 | static int shrink_dqcache_memory(int nr, gfp_t gfp_mask) | 679 | static int shrink_dqcache_memory(int nr, gfp_t gfp_mask) |
701 | { | 680 | { |
702 | if (nr) { | 681 | if (nr) { |
@@ -704,7 +683,9 @@ static int shrink_dqcache_memory(int nr, gfp_t gfp_mask) | |||
704 | prune_dqcache(nr); | 683 | prune_dqcache(nr); |
705 | spin_unlock(&dq_list_lock); | 684 | spin_unlock(&dq_list_lock); |
706 | } | 685 | } |
707 | return (dqstats_read(DQST_FREE_DQUOTS)/100) * sysctl_vfs_cache_pressure; | 686 | return ((unsigned) |
687 | percpu_counter_read_positive(&dqstats.counter[DQST_FREE_DQUOTS]) | ||
688 | /100) * sysctl_vfs_cache_pressure; | ||
708 | } | 689 | } |
709 | 690 | ||
710 | static struct shrinker dqcache_shrinker = { | 691 | static struct shrinker dqcache_shrinker = { |
@@ -1815,7 +1796,7 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) | |||
1815 | if (iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) | 1796 | if (iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) |
1816 | transfer_to[USRQUOTA] = dqget(sb, iattr->ia_uid, USRQUOTA); | 1797 | transfer_to[USRQUOTA] = dqget(sb, iattr->ia_uid, USRQUOTA); |
1817 | if (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid) | 1798 | if (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid) |
1818 | transfer_to[GRPQUOTA] = dqget(sb, iattr->ia_uid, GRPQUOTA); | 1799 | transfer_to[GRPQUOTA] = dqget(sb, iattr->ia_gid, GRPQUOTA); |
1819 | 1800 | ||
1820 | ret = __dquot_transfer(inode, transfer_to); | 1801 | ret = __dquot_transfer(inode, transfer_to); |
1821 | dqput_all(transfer_to); | 1802 | dqput_all(transfer_to); |
@@ -1850,6 +1831,7 @@ const struct dquot_operations dquot_operations = { | |||
1850 | .alloc_dquot = dquot_alloc, | 1831 | .alloc_dquot = dquot_alloc, |
1851 | .destroy_dquot = dquot_destroy, | 1832 | .destroy_dquot = dquot_destroy, |
1852 | }; | 1833 | }; |
1834 | EXPORT_SYMBOL(dquot_operations); | ||
1853 | 1835 | ||
1854 | /* | 1836 | /* |
1855 | * Generic helper for ->open on filesystems supporting disk quotas. | 1837 | * Generic helper for ->open on filesystems supporting disk quotas. |
@@ -1868,7 +1850,7 @@ EXPORT_SYMBOL(dquot_file_open); | |||
1868 | /* | 1850 | /* |
1869 | * Turn quota off on a device. type == -1 ==> quotaoff for all types (umount) | 1851 | * Turn quota off on a device. type == -1 ==> quotaoff for all types (umount) |
1870 | */ | 1852 | */ |
1871 | int vfs_quota_disable(struct super_block *sb, int type, unsigned int flags) | 1853 | int dquot_disable(struct super_block *sb, int type, unsigned int flags) |
1872 | { | 1854 | { |
1873 | int cnt, ret = 0; | 1855 | int cnt, ret = 0; |
1874 | struct quota_info *dqopt = sb_dqopt(sb); | 1856 | struct quota_info *dqopt = sb_dqopt(sb); |
@@ -1998,14 +1980,15 @@ put_inodes: | |||
1998 | } | 1980 | } |
1999 | return ret; | 1981 | return ret; |
2000 | } | 1982 | } |
2001 | EXPORT_SYMBOL(vfs_quota_disable); | 1983 | EXPORT_SYMBOL(dquot_disable); |
2002 | 1984 | ||
2003 | int vfs_quota_off(struct super_block *sb, int type, int remount) | 1985 | int dquot_quota_off(struct super_block *sb, int type) |
2004 | { | 1986 | { |
2005 | return vfs_quota_disable(sb, type, remount ? DQUOT_SUSPENDED : | 1987 | return dquot_disable(sb, type, |
2006 | (DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED)); | 1988 | DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); |
2007 | } | 1989 | } |
2008 | EXPORT_SYMBOL(vfs_quota_off); | 1990 | EXPORT_SYMBOL(dquot_quota_off); |
1991 | |||
2009 | /* | 1992 | /* |
2010 | * Turn quotas on on a device | 1993 | * Turn quotas on on a device |
2011 | */ | 1994 | */ |
@@ -2123,36 +2106,43 @@ out_fmt: | |||
2123 | } | 2106 | } |
2124 | 2107 | ||
2125 | /* Reenable quotas on remount RW */ | 2108 | /* Reenable quotas on remount RW */ |
2126 | static int vfs_quota_on_remount(struct super_block *sb, int type) | 2109 | int dquot_resume(struct super_block *sb, int type) |
2127 | { | 2110 | { |
2128 | struct quota_info *dqopt = sb_dqopt(sb); | 2111 | struct quota_info *dqopt = sb_dqopt(sb); |
2129 | struct inode *inode; | 2112 | struct inode *inode; |
2130 | int ret; | 2113 | int ret = 0, cnt; |
2131 | unsigned int flags; | 2114 | unsigned int flags; |
2132 | 2115 | ||
2133 | mutex_lock(&dqopt->dqonoff_mutex); | 2116 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
2134 | if (!sb_has_quota_suspended(sb, type)) { | 2117 | if (type != -1 && cnt != type) |
2118 | continue; | ||
2119 | |||
2120 | mutex_lock(&dqopt->dqonoff_mutex); | ||
2121 | if (!sb_has_quota_suspended(sb, cnt)) { | ||
2122 | mutex_unlock(&dqopt->dqonoff_mutex); | ||
2123 | continue; | ||
2124 | } | ||
2125 | inode = dqopt->files[cnt]; | ||
2126 | dqopt->files[cnt] = NULL; | ||
2127 | spin_lock(&dq_state_lock); | ||
2128 | flags = dqopt->flags & dquot_state_flag(DQUOT_USAGE_ENABLED | | ||
2129 | DQUOT_LIMITS_ENABLED, | ||
2130 | cnt); | ||
2131 | dqopt->flags &= ~dquot_state_flag(DQUOT_STATE_FLAGS, cnt); | ||
2132 | spin_unlock(&dq_state_lock); | ||
2135 | mutex_unlock(&dqopt->dqonoff_mutex); | 2133 | mutex_unlock(&dqopt->dqonoff_mutex); |
2136 | return 0; | ||
2137 | } | ||
2138 | inode = dqopt->files[type]; | ||
2139 | dqopt->files[type] = NULL; | ||
2140 | spin_lock(&dq_state_lock); | ||
2141 | flags = dqopt->flags & dquot_state_flag(DQUOT_USAGE_ENABLED | | ||
2142 | DQUOT_LIMITS_ENABLED, type); | ||
2143 | dqopt->flags &= ~dquot_state_flag(DQUOT_STATE_FLAGS, type); | ||
2144 | spin_unlock(&dq_state_lock); | ||
2145 | mutex_unlock(&dqopt->dqonoff_mutex); | ||
2146 | 2134 | ||
2147 | flags = dquot_generic_flag(flags, type); | 2135 | flags = dquot_generic_flag(flags, cnt); |
2148 | ret = vfs_load_quota_inode(inode, type, dqopt->info[type].dqi_fmt_id, | 2136 | ret = vfs_load_quota_inode(inode, cnt, |
2149 | flags); | 2137 | dqopt->info[cnt].dqi_fmt_id, flags); |
2150 | iput(inode); | 2138 | iput(inode); |
2139 | } | ||
2151 | 2140 | ||
2152 | return ret; | 2141 | return ret; |
2153 | } | 2142 | } |
2143 | EXPORT_SYMBOL(dquot_resume); | ||
2154 | 2144 | ||
2155 | int vfs_quota_on_path(struct super_block *sb, int type, int format_id, | 2145 | int dquot_quota_on_path(struct super_block *sb, int type, int format_id, |
2156 | struct path *path) | 2146 | struct path *path) |
2157 | { | 2147 | { |
2158 | int error = security_quota_on(path->dentry); | 2148 | int error = security_quota_on(path->dentry); |
@@ -2167,40 +2157,36 @@ int vfs_quota_on_path(struct super_block *sb, int type, int format_id, | |||
2167 | DQUOT_LIMITS_ENABLED); | 2157 | DQUOT_LIMITS_ENABLED); |
2168 | return error; | 2158 | return error; |
2169 | } | 2159 | } |
2170 | EXPORT_SYMBOL(vfs_quota_on_path); | 2160 | EXPORT_SYMBOL(dquot_quota_on_path); |
2171 | 2161 | ||
2172 | int vfs_quota_on(struct super_block *sb, int type, int format_id, char *name, | 2162 | int dquot_quota_on(struct super_block *sb, int type, int format_id, char *name) |
2173 | int remount) | ||
2174 | { | 2163 | { |
2175 | struct path path; | 2164 | struct path path; |
2176 | int error; | 2165 | int error; |
2177 | 2166 | ||
2178 | if (remount) | ||
2179 | return vfs_quota_on_remount(sb, type); | ||
2180 | |||
2181 | error = kern_path(name, LOOKUP_FOLLOW, &path); | 2167 | error = kern_path(name, LOOKUP_FOLLOW, &path); |
2182 | if (!error) { | 2168 | if (!error) { |
2183 | error = vfs_quota_on_path(sb, type, format_id, &path); | 2169 | error = dquot_quota_on_path(sb, type, format_id, &path); |
2184 | path_put(&path); | 2170 | path_put(&path); |
2185 | } | 2171 | } |
2186 | return error; | 2172 | return error; |
2187 | } | 2173 | } |
2188 | EXPORT_SYMBOL(vfs_quota_on); | 2174 | EXPORT_SYMBOL(dquot_quota_on); |
2189 | 2175 | ||
2190 | /* | 2176 | /* |
2191 | * More powerful function for turning on quotas allowing setting | 2177 | * More powerful function for turning on quotas allowing setting |
2192 | * of individual quota flags | 2178 | * of individual quota flags |
2193 | */ | 2179 | */ |
2194 | int vfs_quota_enable(struct inode *inode, int type, int format_id, | 2180 | int dquot_enable(struct inode *inode, int type, int format_id, |
2195 | unsigned int flags) | 2181 | unsigned int flags) |
2196 | { | 2182 | { |
2197 | int ret = 0; | 2183 | int ret = 0; |
2198 | struct super_block *sb = inode->i_sb; | 2184 | struct super_block *sb = inode->i_sb; |
2199 | struct quota_info *dqopt = sb_dqopt(sb); | 2185 | struct quota_info *dqopt = sb_dqopt(sb); |
2200 | 2186 | ||
2201 | /* Just unsuspend quotas? */ | 2187 | /* Just unsuspend quotas? */ |
2202 | if (flags & DQUOT_SUSPENDED) | 2188 | BUG_ON(flags & DQUOT_SUSPENDED); |
2203 | return vfs_quota_on_remount(sb, type); | 2189 | |
2204 | if (!flags) | 2190 | if (!flags) |
2205 | return 0; | 2191 | return 0; |
2206 | /* Just updating flags needed? */ | 2192 | /* Just updating flags needed? */ |
@@ -2232,13 +2218,13 @@ out_lock: | |||
2232 | load_quota: | 2218 | load_quota: |
2233 | return vfs_load_quota_inode(inode, type, format_id, flags); | 2219 | return vfs_load_quota_inode(inode, type, format_id, flags); |
2234 | } | 2220 | } |
2235 | EXPORT_SYMBOL(vfs_quota_enable); | 2221 | EXPORT_SYMBOL(dquot_enable); |
2236 | 2222 | ||
2237 | /* | 2223 | /* |
2238 | * This function is used when filesystem needs to initialize quotas | 2224 | * This function is used when filesystem needs to initialize quotas |
2239 | * during mount time. | 2225 | * during mount time. |
2240 | */ | 2226 | */ |
2241 | int vfs_quota_on_mount(struct super_block *sb, char *qf_name, | 2227 | int dquot_quota_on_mount(struct super_block *sb, char *qf_name, |
2242 | int format_id, int type) | 2228 | int format_id, int type) |
2243 | { | 2229 | { |
2244 | struct dentry *dentry; | 2230 | struct dentry *dentry; |
@@ -2264,24 +2250,7 @@ out: | |||
2264 | dput(dentry); | 2250 | dput(dentry); |
2265 | return error; | 2251 | return error; |
2266 | } | 2252 | } |
2267 | EXPORT_SYMBOL(vfs_quota_on_mount); | 2253 | EXPORT_SYMBOL(dquot_quota_on_mount); |
2268 | |||
2269 | /* Wrapper to turn on quotas when remounting rw */ | ||
2270 | int vfs_dq_quota_on_remount(struct super_block *sb) | ||
2271 | { | ||
2272 | int cnt; | ||
2273 | int ret = 0, err; | ||
2274 | |||
2275 | if (!sb->s_qcop || !sb->s_qcop->quota_on) | ||
2276 | return -ENOSYS; | ||
2277 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | ||
2278 | err = sb->s_qcop->quota_on(sb, cnt, 0, NULL, 1); | ||
2279 | if (err < 0 && !ret) | ||
2280 | ret = err; | ||
2281 | } | ||
2282 | return ret; | ||
2283 | } | ||
2284 | EXPORT_SYMBOL(vfs_dq_quota_on_remount); | ||
2285 | 2254 | ||
2286 | static inline qsize_t qbtos(qsize_t blocks) | 2255 | static inline qsize_t qbtos(qsize_t blocks) |
2287 | { | 2256 | { |
@@ -2316,8 +2285,8 @@ static void do_get_dqblk(struct dquot *dquot, struct fs_disk_quota *di) | |||
2316 | spin_unlock(&dq_data_lock); | 2285 | spin_unlock(&dq_data_lock); |
2317 | } | 2286 | } |
2318 | 2287 | ||
2319 | int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, | 2288 | int dquot_get_dqblk(struct super_block *sb, int type, qid_t id, |
2320 | struct fs_disk_quota *di) | 2289 | struct fs_disk_quota *di) |
2321 | { | 2290 | { |
2322 | struct dquot *dquot; | 2291 | struct dquot *dquot; |
2323 | 2292 | ||
@@ -2329,7 +2298,7 @@ int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, | |||
2329 | 2298 | ||
2330 | return 0; | 2299 | return 0; |
2331 | } | 2300 | } |
2332 | EXPORT_SYMBOL(vfs_get_dqblk); | 2301 | EXPORT_SYMBOL(dquot_get_dqblk); |
2333 | 2302 | ||
2334 | #define VFS_FS_DQ_MASK \ | 2303 | #define VFS_FS_DQ_MASK \ |
2335 | (FS_DQ_BCOUNT | FS_DQ_BSOFT | FS_DQ_BHARD | \ | 2304 | (FS_DQ_BCOUNT | FS_DQ_BSOFT | FS_DQ_BHARD | \ |
@@ -2428,7 +2397,7 @@ static int do_set_dqblk(struct dquot *dquot, struct fs_disk_quota *di) | |||
2428 | return 0; | 2397 | return 0; |
2429 | } | 2398 | } |
2430 | 2399 | ||
2431 | int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, | 2400 | int dquot_set_dqblk(struct super_block *sb, int type, qid_t id, |
2432 | struct fs_disk_quota *di) | 2401 | struct fs_disk_quota *di) |
2433 | { | 2402 | { |
2434 | struct dquot *dquot; | 2403 | struct dquot *dquot; |
@@ -2444,10 +2413,10 @@ int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, | |||
2444 | out: | 2413 | out: |
2445 | return rc; | 2414 | return rc; |
2446 | } | 2415 | } |
2447 | EXPORT_SYMBOL(vfs_set_dqblk); | 2416 | EXPORT_SYMBOL(dquot_set_dqblk); |
2448 | 2417 | ||
2449 | /* Generic routine for getting common part of quota file information */ | 2418 | /* Generic routine for getting common part of quota file information */ |
2450 | int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) | 2419 | int dquot_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) |
2451 | { | 2420 | { |
2452 | struct mem_dqinfo *mi; | 2421 | struct mem_dqinfo *mi; |
2453 | 2422 | ||
@@ -2466,10 +2435,10 @@ int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) | |||
2466 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); | 2435 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); |
2467 | return 0; | 2436 | return 0; |
2468 | } | 2437 | } |
2469 | EXPORT_SYMBOL(vfs_get_dqinfo); | 2438 | EXPORT_SYMBOL(dquot_get_dqinfo); |
2470 | 2439 | ||
2471 | /* Generic routine for setting common part of quota file information */ | 2440 | /* Generic routine for setting common part of quota file information */ |
2472 | int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) | 2441 | int dquot_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) |
2473 | { | 2442 | { |
2474 | struct mem_dqinfo *mi; | 2443 | struct mem_dqinfo *mi; |
2475 | int err = 0; | 2444 | int err = 0; |
@@ -2496,27 +2465,27 @@ out: | |||
2496 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); | 2465 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); |
2497 | return err; | 2466 | return err; |
2498 | } | 2467 | } |
2499 | EXPORT_SYMBOL(vfs_set_dqinfo); | 2468 | EXPORT_SYMBOL(dquot_set_dqinfo); |
2500 | 2469 | ||
2501 | const struct quotactl_ops vfs_quotactl_ops = { | 2470 | const struct quotactl_ops dquot_quotactl_ops = { |
2502 | .quota_on = vfs_quota_on, | 2471 | .quota_on = dquot_quota_on, |
2503 | .quota_off = vfs_quota_off, | 2472 | .quota_off = dquot_quota_off, |
2504 | .quota_sync = vfs_quota_sync, | 2473 | .quota_sync = dquot_quota_sync, |
2505 | .get_info = vfs_get_dqinfo, | 2474 | .get_info = dquot_get_dqinfo, |
2506 | .set_info = vfs_set_dqinfo, | 2475 | .set_info = dquot_set_dqinfo, |
2507 | .get_dqblk = vfs_get_dqblk, | 2476 | .get_dqblk = dquot_get_dqblk, |
2508 | .set_dqblk = vfs_set_dqblk | 2477 | .set_dqblk = dquot_set_dqblk |
2509 | }; | 2478 | }; |
2510 | 2479 | EXPORT_SYMBOL(dquot_quotactl_ops); | |
2511 | 2480 | ||
2512 | static int do_proc_dqstats(struct ctl_table *table, int write, | 2481 | static int do_proc_dqstats(struct ctl_table *table, int write, |
2513 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2482 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2514 | { | 2483 | { |
2515 | #ifdef CONFIG_SMP | ||
2516 | /* Update global table */ | ||
2517 | unsigned int type = (int *)table->data - dqstats.stat; | 2484 | unsigned int type = (int *)table->data - dqstats.stat; |
2518 | dqstats.stat[type] = dqstats_read(type); | 2485 | |
2519 | #endif | 2486 | /* Update global table */ |
2487 | dqstats.stat[type] = | ||
2488 | percpu_counter_sum_positive(&dqstats.counter[type]); | ||
2520 | return proc_dointvec(table, write, buffer, lenp, ppos); | 2489 | return proc_dointvec(table, write, buffer, lenp, ppos); |
2521 | } | 2490 | } |
2522 | 2491 | ||
@@ -2609,7 +2578,7 @@ static ctl_table sys_table[] = { | |||
2609 | 2578 | ||
2610 | static int __init dquot_init(void) | 2579 | static int __init dquot_init(void) |
2611 | { | 2580 | { |
2612 | int i; | 2581 | int i, ret; |
2613 | unsigned long nr_hash, order; | 2582 | unsigned long nr_hash, order; |
2614 | 2583 | ||
2615 | printk(KERN_NOTICE "VFS: Disk quotas %s\n", __DQUOT_VERSION__); | 2584 | printk(KERN_NOTICE "VFS: Disk quotas %s\n", __DQUOT_VERSION__); |
@@ -2627,12 +2596,11 @@ static int __init dquot_init(void) | |||
2627 | if (!dquot_hash) | 2596 | if (!dquot_hash) |
2628 | panic("Cannot create dquot hash table"); | 2597 | panic("Cannot create dquot hash table"); |
2629 | 2598 | ||
2630 | #ifdef CONFIG_SMP | 2599 | for (i = 0; i < _DQST_DQSTAT_LAST; i++) { |
2631 | dqstats_pcpu = alloc_percpu(struct dqstats); | 2600 | ret = percpu_counter_init(&dqstats.counter[i], 0); |
2632 | if (!dqstats_pcpu) | 2601 | if (ret) |
2633 | panic("Cannot create dquot stats table"); | 2602 | panic("Cannot create dquot stat counters"); |
2634 | #endif | 2603 | } |
2635 | memset(&dqstats, 0, sizeof(struct dqstats)); | ||
2636 | 2604 | ||
2637 | /* Find power-of-two hlist_heads which can fit into allocation */ | 2605 | /* Find power-of-two hlist_heads which can fit into allocation */ |
2638 | nr_hash = (1UL << order) * PAGE_SIZE / sizeof(struct hlist_head); | 2606 | nr_hash = (1UL << order) * PAGE_SIZE / sizeof(struct hlist_head); |
diff --git a/fs/quota/quota.c b/fs/quota/quota.c index ce3dfd066f59..b299961e1edb 100644 --- a/fs/quota/quota.c +++ b/fs/quota/quota.c | |||
@@ -73,7 +73,7 @@ static int quota_quotaon(struct super_block *sb, int type, int cmd, qid_t id, | |||
73 | if (IS_ERR(pathname)) | 73 | if (IS_ERR(pathname)) |
74 | return PTR_ERR(pathname); | 74 | return PTR_ERR(pathname); |
75 | if (sb->s_qcop->quota_on) | 75 | if (sb->s_qcop->quota_on) |
76 | ret = sb->s_qcop->quota_on(sb, type, id, pathname, 0); | 76 | ret = sb->s_qcop->quota_on(sb, type, id, pathname); |
77 | putname(pathname); | 77 | putname(pathname); |
78 | return ret; | 78 | return ret; |
79 | } | 79 | } |
@@ -260,7 +260,7 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, | |||
260 | case Q_QUOTAOFF: | 260 | case Q_QUOTAOFF: |
261 | if (!sb->s_qcop->quota_off) | 261 | if (!sb->s_qcop->quota_off) |
262 | return -ENOSYS; | 262 | return -ENOSYS; |
263 | return sb->s_qcop->quota_off(sb, type, 0); | 263 | return sb->s_qcop->quota_off(sb, type); |
264 | case Q_GETFMT: | 264 | case Q_GETFMT: |
265 | return quota_getfmt(sb, type, addr); | 265 | return quota_getfmt(sb, type, addr); |
266 | case Q_GETINFO: | 266 | case Q_GETINFO: |
diff --git a/fs/ramfs/file-mmu.c b/fs/ramfs/file-mmu.c index 78f613cb9c76..4884ac5ae9be 100644 --- a/fs/ramfs/file-mmu.c +++ b/fs/ramfs/file-mmu.c | |||
@@ -43,12 +43,13 @@ const struct file_operations ramfs_file_operations = { | |||
43 | .write = do_sync_write, | 43 | .write = do_sync_write, |
44 | .aio_write = generic_file_aio_write, | 44 | .aio_write = generic_file_aio_write, |
45 | .mmap = generic_file_mmap, | 45 | .mmap = generic_file_mmap, |
46 | .fsync = simple_sync_file, | 46 | .fsync = noop_fsync, |
47 | .splice_read = generic_file_splice_read, | 47 | .splice_read = generic_file_splice_read, |
48 | .splice_write = generic_file_splice_write, | 48 | .splice_write = generic_file_splice_write, |
49 | .llseek = generic_file_llseek, | 49 | .llseek = generic_file_llseek, |
50 | }; | 50 | }; |
51 | 51 | ||
52 | const struct inode_operations ramfs_file_inode_operations = { | 52 | const struct inode_operations ramfs_file_inode_operations = { |
53 | .setattr = simple_setattr, | ||
53 | .getattr = simple_getattr, | 54 | .getattr = simple_getattr, |
54 | }; | 55 | }; |
diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c index 5ea4ad81a429..d532c20fc179 100644 --- a/fs/ramfs/file-nommu.c +++ b/fs/ramfs/file-nommu.c | |||
@@ -42,7 +42,7 @@ const struct file_operations ramfs_file_operations = { | |||
42 | .aio_read = generic_file_aio_read, | 42 | .aio_read = generic_file_aio_read, |
43 | .write = do_sync_write, | 43 | .write = do_sync_write, |
44 | .aio_write = generic_file_aio_write, | 44 | .aio_write = generic_file_aio_write, |
45 | .fsync = simple_sync_file, | 45 | .fsync = noop_fsync, |
46 | .splice_read = generic_file_splice_read, | 46 | .splice_read = generic_file_splice_read, |
47 | .splice_write = generic_file_splice_write, | 47 | .splice_write = generic_file_splice_write, |
48 | .llseek = generic_file_llseek, | 48 | .llseek = generic_file_llseek, |
@@ -146,7 +146,7 @@ static int ramfs_nommu_resize(struct inode *inode, loff_t newsize, loff_t size) | |||
146 | return ret; | 146 | return ret; |
147 | } | 147 | } |
148 | 148 | ||
149 | ret = vmtruncate(inode, newsize); | 149 | ret = simple_setsize(inode, newsize); |
150 | 150 | ||
151 | return ret; | 151 | return ret; |
152 | } | 152 | } |
@@ -169,7 +169,8 @@ static int ramfs_nommu_setattr(struct dentry *dentry, struct iattr *ia) | |||
169 | 169 | ||
170 | /* pick out size-changing events */ | 170 | /* pick out size-changing events */ |
171 | if (ia->ia_valid & ATTR_SIZE) { | 171 | if (ia->ia_valid & ATTR_SIZE) { |
172 | loff_t size = i_size_read(inode); | 172 | loff_t size = inode->i_size; |
173 | |||
173 | if (ia->ia_size != size) { | 174 | if (ia->ia_size != size) { |
174 | ret = ramfs_nommu_resize(inode, ia->ia_size, size); | 175 | ret = ramfs_nommu_resize(inode, ia->ia_size, size); |
175 | if (ret < 0 || ia->ia_valid == ATTR_SIZE) | 176 | if (ret < 0 || ia->ia_valid == ATTR_SIZE) |
@@ -182,7 +183,7 @@ static int ramfs_nommu_setattr(struct dentry *dentry, struct iattr *ia) | |||
182 | } | 183 | } |
183 | } | 184 | } |
184 | 185 | ||
185 | ret = inode_setattr(inode, ia); | 186 | generic_setattr(inode, ia); |
186 | out: | 187 | out: |
187 | ia->ia_valid = old_ia_valid; | 188 | ia->ia_valid = old_ia_valid; |
188 | return ret; | 189 | return ret; |
diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c index 4455fbe269a3..198dabf1b2bb 100644 --- a/fs/reiserfs/dir.c +++ b/fs/reiserfs/dir.c | |||
@@ -14,8 +14,7 @@ | |||
14 | extern const struct reiserfs_key MIN_KEY; | 14 | extern const struct reiserfs_key MIN_KEY; |
15 | 15 | ||
16 | static int reiserfs_readdir(struct file *, void *, filldir_t); | 16 | static int reiserfs_readdir(struct file *, void *, filldir_t); |
17 | static int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry, | 17 | static int reiserfs_dir_fsync(struct file *filp, int datasync); |
18 | int datasync); | ||
19 | 18 | ||
20 | const struct file_operations reiserfs_dir_operations = { | 19 | const struct file_operations reiserfs_dir_operations = { |
21 | .llseek = generic_file_llseek, | 20 | .llseek = generic_file_llseek, |
@@ -28,10 +27,9 @@ const struct file_operations reiserfs_dir_operations = { | |||
28 | #endif | 27 | #endif |
29 | }; | 28 | }; |
30 | 29 | ||
31 | static int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry, | 30 | static int reiserfs_dir_fsync(struct file *filp, int datasync) |
32 | int datasync) | ||
33 | { | 31 | { |
34 | struct inode *inode = dentry->d_inode; | 32 | struct inode *inode = filp->f_mapping->host; |
35 | int err; | 33 | int err; |
36 | reiserfs_write_lock(inode->i_sb); | 34 | reiserfs_write_lock(inode->i_sb); |
37 | err = reiserfs_commit_for_inode(inode); | 35 | err = reiserfs_commit_for_inode(inode); |
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index 9977df9f3a54..b82cdd8a45dd 100644 --- a/fs/reiserfs/file.c +++ b/fs/reiserfs/file.c | |||
@@ -134,10 +134,9 @@ static void reiserfs_vfs_truncate_file(struct inode *inode) | |||
134 | * be removed... | 134 | * be removed... |
135 | */ | 135 | */ |
136 | 136 | ||
137 | static int reiserfs_sync_file(struct file *filp, | 137 | static int reiserfs_sync_file(struct file *filp, int datasync) |
138 | struct dentry *dentry, int datasync) | ||
139 | { | 138 | { |
140 | struct inode *inode = dentry->d_inode; | 139 | struct inode *inode = filp->f_mapping->host; |
141 | int err; | 140 | int err; |
142 | int barrier_done; | 141 | int barrier_done; |
143 | 142 | ||
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 59125fb36d42..9822fa15118b 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
@@ -158,6 +158,7 @@ static int finish_unfinished(struct super_block *s) | |||
158 | #ifdef CONFIG_QUOTA | 158 | #ifdef CONFIG_QUOTA |
159 | int i; | 159 | int i; |
160 | int ms_active_set; | 160 | int ms_active_set; |
161 | int quota_enabled[MAXQUOTAS]; | ||
161 | #endif | 162 | #endif |
162 | 163 | ||
163 | /* compose key to look for "save" links */ | 164 | /* compose key to look for "save" links */ |
@@ -179,8 +180,15 @@ static int finish_unfinished(struct super_block *s) | |||
179 | } | 180 | } |
180 | /* Turn on quotas so that they are updated correctly */ | 181 | /* Turn on quotas so that they are updated correctly */ |
181 | for (i = 0; i < MAXQUOTAS; i++) { | 182 | for (i = 0; i < MAXQUOTAS; i++) { |
183 | quota_enabled[i] = 1; | ||
182 | if (REISERFS_SB(s)->s_qf_names[i]) { | 184 | if (REISERFS_SB(s)->s_qf_names[i]) { |
183 | int ret = reiserfs_quota_on_mount(s, i); | 185 | int ret; |
186 | |||
187 | if (sb_has_quota_active(s, i)) { | ||
188 | quota_enabled[i] = 0; | ||
189 | continue; | ||
190 | } | ||
191 | ret = reiserfs_quota_on_mount(s, i); | ||
184 | if (ret < 0) | 192 | if (ret < 0) |
185 | reiserfs_warning(s, "reiserfs-2500", | 193 | reiserfs_warning(s, "reiserfs-2500", |
186 | "cannot turn on journaled " | 194 | "cannot turn on journaled " |
@@ -304,8 +312,8 @@ static int finish_unfinished(struct super_block *s) | |||
304 | #ifdef CONFIG_QUOTA | 312 | #ifdef CONFIG_QUOTA |
305 | /* Turn quotas off */ | 313 | /* Turn quotas off */ |
306 | for (i = 0; i < MAXQUOTAS; i++) { | 314 | for (i = 0; i < MAXQUOTAS; i++) { |
307 | if (sb_dqopt(s)->files[i]) | 315 | if (sb_dqopt(s)->files[i] && quota_enabled[i]) |
308 | vfs_quota_off(s, i, 0); | 316 | dquot_quota_off(s, i); |
309 | } | 317 | } |
310 | if (ms_active_set) | 318 | if (ms_active_set) |
311 | /* Restore the flag back */ | 319 | /* Restore the flag back */ |
@@ -466,6 +474,8 @@ static void reiserfs_put_super(struct super_block *s) | |||
466 | struct reiserfs_transaction_handle th; | 474 | struct reiserfs_transaction_handle th; |
467 | th.t_trans_id = 0; | 475 | th.t_trans_id = 0; |
468 | 476 | ||
477 | dquot_disable(s, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); | ||
478 | |||
469 | reiserfs_write_lock(s); | 479 | reiserfs_write_lock(s); |
470 | 480 | ||
471 | if (s->s_dirt) | 481 | if (s->s_dirt) |
@@ -620,7 +630,7 @@ static int reiserfs_acquire_dquot(struct dquot *); | |||
620 | static int reiserfs_release_dquot(struct dquot *); | 630 | static int reiserfs_release_dquot(struct dquot *); |
621 | static int reiserfs_mark_dquot_dirty(struct dquot *); | 631 | static int reiserfs_mark_dquot_dirty(struct dquot *); |
622 | static int reiserfs_write_info(struct super_block *, int); | 632 | static int reiserfs_write_info(struct super_block *, int); |
623 | static int reiserfs_quota_on(struct super_block *, int, int, char *, int); | 633 | static int reiserfs_quota_on(struct super_block *, int, int, char *); |
624 | 634 | ||
625 | static const struct dquot_operations reiserfs_quota_operations = { | 635 | static const struct dquot_operations reiserfs_quota_operations = { |
626 | .write_dquot = reiserfs_write_dquot, | 636 | .write_dquot = reiserfs_write_dquot, |
@@ -634,12 +644,12 @@ static const struct dquot_operations reiserfs_quota_operations = { | |||
634 | 644 | ||
635 | static const struct quotactl_ops reiserfs_qctl_operations = { | 645 | static const struct quotactl_ops reiserfs_qctl_operations = { |
636 | .quota_on = reiserfs_quota_on, | 646 | .quota_on = reiserfs_quota_on, |
637 | .quota_off = vfs_quota_off, | 647 | .quota_off = dquot_quota_off, |
638 | .quota_sync = vfs_quota_sync, | 648 | .quota_sync = dquot_quota_sync, |
639 | .get_info = vfs_get_dqinfo, | 649 | .get_info = dquot_get_dqinfo, |
640 | .set_info = vfs_set_dqinfo, | 650 | .set_info = dquot_set_dqinfo, |
641 | .get_dqblk = vfs_get_dqblk, | 651 | .get_dqblk = dquot_get_dqblk, |
642 | .set_dqblk = vfs_set_dqblk, | 652 | .set_dqblk = dquot_set_dqblk, |
643 | }; | 653 | }; |
644 | #endif | 654 | #endif |
645 | 655 | ||
@@ -1242,6 +1252,11 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) | |||
1242 | if (s->s_flags & MS_RDONLY) | 1252 | if (s->s_flags & MS_RDONLY) |
1243 | /* it is read-only already */ | 1253 | /* it is read-only already */ |
1244 | goto out_ok; | 1254 | goto out_ok; |
1255 | |||
1256 | err = dquot_suspend(s, -1); | ||
1257 | if (err < 0) | ||
1258 | goto out_err; | ||
1259 | |||
1245 | /* try to remount file system with read-only permissions */ | 1260 | /* try to remount file system with read-only permissions */ |
1246 | if (sb_umount_state(rs) == REISERFS_VALID_FS | 1261 | if (sb_umount_state(rs) == REISERFS_VALID_FS |
1247 | || REISERFS_SB(s)->s_mount_state != REISERFS_VALID_FS) { | 1262 | || REISERFS_SB(s)->s_mount_state != REISERFS_VALID_FS) { |
@@ -1295,6 +1310,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) | |||
1295 | s->s_dirt = 0; | 1310 | s->s_dirt = 0; |
1296 | 1311 | ||
1297 | if (!(*mount_flags & MS_RDONLY)) { | 1312 | if (!(*mount_flags & MS_RDONLY)) { |
1313 | dquot_resume(s, -1); | ||
1298 | finish_unfinished(s); | 1314 | finish_unfinished(s); |
1299 | reiserfs_xattr_init(s, *mount_flags); | 1315 | reiserfs_xattr_init(s, *mount_flags); |
1300 | } | 1316 | } |
@@ -2022,15 +2038,15 @@ static int reiserfs_write_info(struct super_block *sb, int type) | |||
2022 | */ | 2038 | */ |
2023 | static int reiserfs_quota_on_mount(struct super_block *sb, int type) | 2039 | static int reiserfs_quota_on_mount(struct super_block *sb, int type) |
2024 | { | 2040 | { |
2025 | return vfs_quota_on_mount(sb, REISERFS_SB(sb)->s_qf_names[type], | 2041 | return dquot_quota_on_mount(sb, REISERFS_SB(sb)->s_qf_names[type], |
2026 | REISERFS_SB(sb)->s_jquota_fmt, type); | 2042 | REISERFS_SB(sb)->s_jquota_fmt, type); |
2027 | } | 2043 | } |
2028 | 2044 | ||
2029 | /* | 2045 | /* |
2030 | * Standard function to be called on quota_on | 2046 | * Standard function to be called on quota_on |
2031 | */ | 2047 | */ |
2032 | static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, | 2048 | static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, |
2033 | char *name, int remount) | 2049 | char *name) |
2034 | { | 2050 | { |
2035 | int err; | 2051 | int err; |
2036 | struct path path; | 2052 | struct path path; |
@@ -2039,9 +2055,7 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, | |||
2039 | 2055 | ||
2040 | if (!(REISERFS_SB(sb)->s_mount_opt & (1 << REISERFS_QUOTA))) | 2056 | if (!(REISERFS_SB(sb)->s_mount_opt & (1 << REISERFS_QUOTA))) |
2041 | return -EINVAL; | 2057 | return -EINVAL; |
2042 | /* No more checks needed? Path and format_id are bogus anyway... */ | 2058 | |
2043 | if (remount) | ||
2044 | return vfs_quota_on(sb, type, format_id, name, 1); | ||
2045 | err = kern_path(name, LOOKUP_FOLLOW, &path); | 2059 | err = kern_path(name, LOOKUP_FOLLOW, &path); |
2046 | if (err) | 2060 | if (err) |
2047 | return err; | 2061 | return err; |
@@ -2085,7 +2099,7 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, | |||
2085 | if (err) | 2099 | if (err) |
2086 | goto out; | 2100 | goto out; |
2087 | } | 2101 | } |
2088 | err = vfs_quota_on_path(sb, type, format_id, &path); | 2102 | err = dquot_quota_on_path(sb, type, format_id, &path); |
2089 | out: | 2103 | out: |
2090 | path_put(&path); | 2104 | path_put(&path); |
2091 | return err; | 2105 | return err; |
diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c index 84ecf0e43f91..8e187a0f94bb 100644 --- a/fs/smbfs/file.c +++ b/fs/smbfs/file.c | |||
@@ -28,8 +28,9 @@ | |||
28 | #include "proto.h" | 28 | #include "proto.h" |
29 | 29 | ||
30 | static int | 30 | static int |
31 | smb_fsync(struct file *file, struct dentry * dentry, int datasync) | 31 | smb_fsync(struct file *file, int datasync) |
32 | { | 32 | { |
33 | struct dentry *dentry = file->f_path.dentry; | ||
33 | struct smb_sb_info *server = server_from_dentry(dentry); | 34 | struct smb_sb_info *server = server_from_dentry(dentry); |
34 | int result; | 35 | int result; |
35 | 36 | ||
diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c index dfa1d67f8fca..9551cb6f7fe4 100644 --- a/fs/smbfs/inode.c +++ b/fs/smbfs/inode.c | |||
@@ -714,7 +714,7 @@ smb_notify_change(struct dentry *dentry, struct iattr *attr) | |||
714 | error = server->ops->truncate(inode, attr->ia_size); | 714 | error = server->ops->truncate(inode, attr->ia_size); |
715 | if (error) | 715 | if (error) |
716 | goto out; | 716 | goto out; |
717 | error = vmtruncate(inode, attr->ia_size); | 717 | error = simple_setsize(inode, attr->ia_size); |
718 | if (error) | 718 | if (error) |
719 | goto out; | 719 | goto out; |
720 | refresh = 1; | 720 | refresh = 1; |
diff --git a/fs/super.c b/fs/super.c index 69688b15f1fa..5c35bc7a499e 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/acct.h> | 25 | #include <linux/acct.h> |
26 | #include <linux/blkdev.h> | 26 | #include <linux/blkdev.h> |
27 | #include <linux/quotaops.h> | ||
28 | #include <linux/mount.h> | 27 | #include <linux/mount.h> |
29 | #include <linux/security.h> | 28 | #include <linux/security.h> |
30 | #include <linux/writeback.h> /* for the emergency remount stuff */ | 29 | #include <linux/writeback.h> /* for the emergency remount stuff */ |
@@ -94,8 +93,6 @@ static struct super_block *alloc_super(struct file_system_type *type) | |||
94 | init_rwsem(&s->s_dquot.dqptr_sem); | 93 | init_rwsem(&s->s_dquot.dqptr_sem); |
95 | init_waitqueue_head(&s->s_wait_unfrozen); | 94 | init_waitqueue_head(&s->s_wait_unfrozen); |
96 | s->s_maxbytes = MAX_NON_LFS; | 95 | s->s_maxbytes = MAX_NON_LFS; |
97 | s->dq_op = sb_dquot_ops; | ||
98 | s->s_qcop = sb_quotactl_ops; | ||
99 | s->s_op = &default_op; | 96 | s->s_op = &default_op; |
100 | s->s_time_gran = 1000000000; | 97 | s->s_time_gran = 1000000000; |
101 | } | 98 | } |
@@ -160,7 +157,6 @@ void deactivate_locked_super(struct super_block *s) | |||
160 | { | 157 | { |
161 | struct file_system_type *fs = s->s_type; | 158 | struct file_system_type *fs = s->s_type; |
162 | if (atomic_dec_and_test(&s->s_active)) { | 159 | if (atomic_dec_and_test(&s->s_active)) { |
163 | vfs_dq_off(s, 0); | ||
164 | fs->kill_sb(s); | 160 | fs->kill_sb(s); |
165 | put_filesystem(fs); | 161 | put_filesystem(fs); |
166 | put_super(s); | 162 | put_super(s); |
@@ -524,7 +520,7 @@ rescan: | |||
524 | int do_remount_sb(struct super_block *sb, int flags, void *data, int force) | 520 | int do_remount_sb(struct super_block *sb, int flags, void *data, int force) |
525 | { | 521 | { |
526 | int retval; | 522 | int retval; |
527 | int remount_rw, remount_ro; | 523 | int remount_ro; |
528 | 524 | ||
529 | if (sb->s_frozen != SB_UNFROZEN) | 525 | if (sb->s_frozen != SB_UNFROZEN) |
530 | return -EBUSY; | 526 | return -EBUSY; |
@@ -540,7 +536,6 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force) | |||
540 | sync_filesystem(sb); | 536 | sync_filesystem(sb); |
541 | 537 | ||
542 | remount_ro = (flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY); | 538 | remount_ro = (flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY); |
543 | remount_rw = !(flags & MS_RDONLY) && (sb->s_flags & MS_RDONLY); | ||
544 | 539 | ||
545 | /* If we are remounting RDONLY and current sb is read/write, | 540 | /* If we are remounting RDONLY and current sb is read/write, |
546 | make sure there are no rw files opened */ | 541 | make sure there are no rw files opened */ |
@@ -549,9 +544,6 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force) | |||
549 | mark_files_ro(sb); | 544 | mark_files_ro(sb); |
550 | else if (!fs_may_remount_ro(sb)) | 545 | else if (!fs_may_remount_ro(sb)) |
551 | return -EBUSY; | 546 | return -EBUSY; |
552 | retval = vfs_dq_off(sb, 1); | ||
553 | if (retval < 0 && retval != -ENOSYS) | ||
554 | return -EBUSY; | ||
555 | } | 547 | } |
556 | 548 | ||
557 | if (sb->s_op->remount_fs) { | 549 | if (sb->s_op->remount_fs) { |
@@ -560,8 +552,7 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force) | |||
560 | return retval; | 552 | return retval; |
561 | } | 553 | } |
562 | sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK); | 554 | sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK); |
563 | if (remount_rw) | 555 | |
564 | vfs_dq_quota_on_remount(sb); | ||
565 | /* | 556 | /* |
566 | * Some filesystems modify their metadata via some other path than the | 557 | * Some filesystems modify their metadata via some other path than the |
567 | * bdev buffer cache (eg. use a private mapping, or directories in | 558 | * bdev buffer cache (eg. use a private mapping, or directories in |
@@ -946,8 +937,8 @@ out: | |||
946 | EXPORT_SYMBOL_GPL(vfs_kern_mount); | 937 | EXPORT_SYMBOL_GPL(vfs_kern_mount); |
947 | 938 | ||
948 | /** | 939 | /** |
949 | * freeze_super -- lock the filesystem and force it into a consistent state | 940 | * freeze_super - lock the filesystem and force it into a consistent state |
950 | * @super: the super to lock | 941 | * @sb: the super to lock |
951 | * | 942 | * |
952 | * Syncs the super to make sure the filesystem is consistent and calls the fs's | 943 | * Syncs the super to make sure the filesystem is consistent and calls the fs's |
953 | * freeze_fs. Subsequent calls to this without first thawing the fs will return | 944 | * freeze_fs. Subsequent calls to this without first thawing the fs will return |
@@ -130,12 +130,10 @@ void emergency_sync(void) | |||
130 | 130 | ||
131 | /* | 131 | /* |
132 | * Generic function to fsync a file. | 132 | * Generic function to fsync a file. |
133 | * | ||
134 | * filp may be NULL if called via the msync of a vma. | ||
135 | */ | 133 | */ |
136 | int file_fsync(struct file *filp, struct dentry *dentry, int datasync) | 134 | int file_fsync(struct file *filp, int datasync) |
137 | { | 135 | { |
138 | struct inode * inode = dentry->d_inode; | 136 | struct inode *inode = filp->f_mapping->host; |
139 | struct super_block * sb; | 137 | struct super_block * sb; |
140 | int ret, err; | 138 | int ret, err; |
141 | 139 | ||
@@ -183,7 +181,7 @@ int vfs_fsync_range(struct file *file, loff_t start, loff_t end, int datasync) | |||
183 | * livelocks in fsync_buffers_list(). | 181 | * livelocks in fsync_buffers_list(). |
184 | */ | 182 | */ |
185 | mutex_lock(&mapping->host->i_mutex); | 183 | mutex_lock(&mapping->host->i_mutex); |
186 | err = file->f_op->fsync(file, file->f_path.dentry, datasync); | 184 | err = file->f_op->fsync(file, datasync); |
187 | if (!ret) | 185 | if (!ret) |
188 | ret = err; | 186 | ret = err; |
189 | mutex_unlock(&mapping->host->i_mutex); | 187 | mutex_unlock(&mapping->host->i_mutex); |
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c index bbd77e95cf7f..bde1a4c3679a 100644 --- a/fs/sysfs/inode.c +++ b/fs/sysfs/inode.c | |||
@@ -117,13 +117,11 @@ int sysfs_setattr(struct dentry *dentry, struct iattr *iattr) | |||
117 | if (error) | 117 | if (error) |
118 | goto out; | 118 | goto out; |
119 | 119 | ||
120 | iattr->ia_valid &= ~ATTR_SIZE; /* ignore size changes */ | 120 | /* this ignores size changes */ |
121 | 121 | generic_setattr(inode, iattr); | |
122 | error = inode_setattr(inode, iattr); | ||
123 | if (error) | ||
124 | goto out; | ||
125 | 122 | ||
126 | error = sysfs_sd_setattr(sd, iattr); | 123 | error = sysfs_sd_setattr(sd, iattr); |
124 | |||
127 | out: | 125 | out: |
128 | mutex_unlock(&sysfs_mutex); | 126 | mutex_unlock(&sysfs_mutex); |
129 | return error; | 127 | return error; |
diff --git a/fs/sysv/dir.c b/fs/sysv/dir.c index 1dabed286b4c..79941e4964a4 100644 --- a/fs/sysv/dir.c +++ b/fs/sysv/dir.c | |||
@@ -24,7 +24,7 @@ const struct file_operations sysv_dir_operations = { | |||
24 | .llseek = generic_file_llseek, | 24 | .llseek = generic_file_llseek, |
25 | .read = generic_read_dir, | 25 | .read = generic_read_dir, |
26 | .readdir = sysv_readdir, | 26 | .readdir = sysv_readdir, |
27 | .fsync = simple_fsync, | 27 | .fsync = generic_file_fsync, |
28 | }; | 28 | }; |
29 | 29 | ||
30 | static inline void dir_put_page(struct page *page) | 30 | static inline void dir_put_page(struct page *page) |
diff --git a/fs/sysv/file.c b/fs/sysv/file.c index 96340c01f4a7..750cc22349bd 100644 --- a/fs/sysv/file.c +++ b/fs/sysv/file.c | |||
@@ -26,7 +26,7 @@ const struct file_operations sysv_file_operations = { | |||
26 | .write = do_sync_write, | 26 | .write = do_sync_write, |
27 | .aio_write = generic_file_aio_write, | 27 | .aio_write = generic_file_aio_write, |
28 | .mmap = generic_file_mmap, | 28 | .mmap = generic_file_mmap, |
29 | .fsync = simple_fsync, | 29 | .fsync = generic_file_fsync, |
30 | .splice_read = generic_file_splice_read, | 30 | .splice_read = generic_file_splice_read, |
31 | }; | 31 | }; |
32 | 32 | ||
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c index 4573734d723d..d4a5380b5669 100644 --- a/fs/sysv/inode.c +++ b/fs/sysv/inode.c | |||
@@ -43,6 +43,7 @@ static int sysv_sync_fs(struct super_block *sb, int wait) | |||
43 | * then attach current time stamp. | 43 | * then attach current time stamp. |
44 | * But if the filesystem was marked clean, keep it clean. | 44 | * But if the filesystem was marked clean, keep it clean. |
45 | */ | 45 | */ |
46 | sb->s_dirt = 0; | ||
46 | old_time = fs32_to_cpu(sbi, *sbi->s_sb_time); | 47 | old_time = fs32_to_cpu(sbi, *sbi->s_sb_time); |
47 | if (sbi->s_type == FSTYPE_SYSV4) { | 48 | if (sbi->s_type == FSTYPE_SYSV4) { |
48 | if (*sbi->s_sb_state == cpu_to_fs32(sbi, 0x7c269d38 - old_time)) | 49 | if (*sbi->s_sb_state == cpu_to_fs32(sbi, 0x7c269d38 - old_time)) |
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c index 5692cf72b807..12f445cee9f7 100644 --- a/fs/ubifs/file.c +++ b/fs/ubifs/file.c | |||
@@ -967,12 +967,15 @@ static int do_writepage(struct page *page, int len) | |||
967 | * the page locked, and it locks @ui_mutex. However, write-back does take inode | 967 | * the page locked, and it locks @ui_mutex. However, write-back does take inode |
968 | * @i_mutex, which means other VFS operations may be run on this inode at the | 968 | * @i_mutex, which means other VFS operations may be run on this inode at the |
969 | * same time. And the problematic one is truncation to smaller size, from where | 969 | * same time. And the problematic one is truncation to smaller size, from where |
970 | * we have to call 'vmtruncate()', which first changes @inode->i_size, then | 970 | * we have to call 'simple_setsize()', which first changes @inode->i_size, then |
971 | * drops the truncated pages. And while dropping the pages, it takes the page | 971 | * drops the truncated pages. And while dropping the pages, it takes the page |
972 | * lock. This means that 'do_truncation()' cannot call 'vmtruncate()' with | 972 | * lock. This means that 'do_truncation()' cannot call 'simple_setsize()' with |
973 | * @ui_mutex locked, because it would deadlock with 'ubifs_writepage()'. This | 973 | * @ui_mutex locked, because it would deadlock with 'ubifs_writepage()'. This |
974 | * means that @inode->i_size is changed while @ui_mutex is unlocked. | 974 | * means that @inode->i_size is changed while @ui_mutex is unlocked. |
975 | * | 975 | * |
976 | * XXX: with the new truncate the above is not true anymore, the simple_setsize | ||
977 | * calls can be replaced with the individual components. | ||
978 | * | ||
976 | * But in 'ubifs_writepage()' we have to guarantee that we do not write beyond | 979 | * But in 'ubifs_writepage()' we have to guarantee that we do not write beyond |
977 | * inode size. How do we do this if @inode->i_size may became smaller while we | 980 | * inode size. How do we do this if @inode->i_size may became smaller while we |
978 | * are in the middle of 'ubifs_writepage()'? The UBIFS solution is the | 981 | * are in the middle of 'ubifs_writepage()'? The UBIFS solution is the |
@@ -1125,7 +1128,7 @@ static int do_truncation(struct ubifs_info *c, struct inode *inode, | |||
1125 | budgeted = 0; | 1128 | budgeted = 0; |
1126 | } | 1129 | } |
1127 | 1130 | ||
1128 | err = vmtruncate(inode, new_size); | 1131 | err = simple_setsize(inode, new_size); |
1129 | if (err) | 1132 | if (err) |
1130 | goto out_budg; | 1133 | goto out_budg; |
1131 | 1134 | ||
@@ -1214,7 +1217,7 @@ static int do_setattr(struct ubifs_info *c, struct inode *inode, | |||
1214 | 1217 | ||
1215 | if (attr->ia_valid & ATTR_SIZE) { | 1218 | if (attr->ia_valid & ATTR_SIZE) { |
1216 | dbg_gen("size %lld -> %lld", inode->i_size, new_size); | 1219 | dbg_gen("size %lld -> %lld", inode->i_size, new_size); |
1217 | err = vmtruncate(inode, new_size); | 1220 | err = simple_setsize(inode, new_size); |
1218 | if (err) | 1221 | if (err) |
1219 | goto out; | 1222 | goto out; |
1220 | } | 1223 | } |
@@ -1223,7 +1226,7 @@ static int do_setattr(struct ubifs_info *c, struct inode *inode, | |||
1223 | if (attr->ia_valid & ATTR_SIZE) { | 1226 | if (attr->ia_valid & ATTR_SIZE) { |
1224 | /* Truncation changes inode [mc]time */ | 1227 | /* Truncation changes inode [mc]time */ |
1225 | inode->i_mtime = inode->i_ctime = ubifs_current_time(inode); | 1228 | inode->i_mtime = inode->i_ctime = ubifs_current_time(inode); |
1226 | /* 'vmtruncate()' changed @i_size, update @ui_size */ | 1229 | /* 'simple_setsize()' changed @i_size, update @ui_size */ |
1227 | ui->ui_size = inode->i_size; | 1230 | ui->ui_size = inode->i_size; |
1228 | } | 1231 | } |
1229 | 1232 | ||
@@ -1304,9 +1307,9 @@ static void *ubifs_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
1304 | return NULL; | 1307 | return NULL; |
1305 | } | 1308 | } |
1306 | 1309 | ||
1307 | int ubifs_fsync(struct file *file, struct dentry *dentry, int datasync) | 1310 | int ubifs_fsync(struct file *file, int datasync) |
1308 | { | 1311 | { |
1309 | struct inode *inode = dentry->d_inode; | 1312 | struct inode *inode = file->f_mapping->host; |
1310 | struct ubifs_info *c = inode->i_sb->s_fs_info; | 1313 | struct ubifs_info *c = inode->i_sb->s_fs_info; |
1311 | int err; | 1314 | int err; |
1312 | 1315 | ||
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index bd2542dad014..2eef553d50c8 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h | |||
@@ -379,7 +379,7 @@ struct ubifs_gced_idx_leb { | |||
379 | * The @ui_size is a "shadow" variable for @inode->i_size and UBIFS uses | 379 | * The @ui_size is a "shadow" variable for @inode->i_size and UBIFS uses |
380 | * @ui_size instead of @inode->i_size. The reason for this is that UBIFS cannot | 380 | * @ui_size instead of @inode->i_size. The reason for this is that UBIFS cannot |
381 | * make sure @inode->i_size is always changed under @ui_mutex, because it | 381 | * make sure @inode->i_size is always changed under @ui_mutex, because it |
382 | * cannot call 'vmtruncate()' with @ui_mutex locked, because it would deadlock | 382 | * cannot call 'simple_setsize()' with @ui_mutex locked, because it would deadlock |
383 | * with 'ubifs_writepage()' (see file.c). All the other inode fields are | 383 | * with 'ubifs_writepage()' (see file.c). All the other inode fields are |
384 | * changed under @ui_mutex, so they do not need "shadow" fields. Note, one | 384 | * changed under @ui_mutex, so they do not need "shadow" fields. Note, one |
385 | * could consider to rework locking and base it on "shadow" fields. | 385 | * could consider to rework locking and base it on "shadow" fields. |
@@ -1678,7 +1678,7 @@ const struct ubifs_lprops *ubifs_fast_find_frdi_idx(struct ubifs_info *c); | |||
1678 | int ubifs_calc_dark(const struct ubifs_info *c, int spc); | 1678 | int ubifs_calc_dark(const struct ubifs_info *c, int spc); |
1679 | 1679 | ||
1680 | /* file.c */ | 1680 | /* file.c */ |
1681 | int ubifs_fsync(struct file *file, struct dentry *dentry, int datasync); | 1681 | int ubifs_fsync(struct file *file, int datasync); |
1682 | int ubifs_setattr(struct dentry *dentry, struct iattr *attr); | 1682 | int ubifs_setattr(struct dentry *dentry, struct iattr *attr); |
1683 | 1683 | ||
1684 | /* dir.c */ | 1684 | /* dir.c */ |
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c index 9a9378b4eb5a..b608efaa4cee 100644 --- a/fs/udf/balloc.c +++ b/fs/udf/balloc.c | |||
@@ -21,7 +21,6 @@ | |||
21 | 21 | ||
22 | #include "udfdecl.h" | 22 | #include "udfdecl.h" |
23 | 23 | ||
24 | #include <linux/quotaops.h> | ||
25 | #include <linux/buffer_head.h> | 24 | #include <linux/buffer_head.h> |
26 | #include <linux/bitops.h> | 25 | #include <linux/bitops.h> |
27 | 26 | ||
@@ -159,8 +158,6 @@ static void udf_bitmap_free_blocks(struct super_block *sb, | |||
159 | udf_debug("byte=%2x\n", | 158 | udf_debug("byte=%2x\n", |
160 | ((char *)bh->b_data)[(bit + i) >> 3]); | 159 | ((char *)bh->b_data)[(bit + i) >> 3]); |
161 | } else { | 160 | } else { |
162 | if (inode) | ||
163 | dquot_free_block(inode, 1); | ||
164 | udf_add_free_space(sb, sbi->s_partition, 1); | 161 | udf_add_free_space(sb, sbi->s_partition, 1); |
165 | } | 162 | } |
166 | } | 163 | } |
@@ -210,15 +207,8 @@ static int udf_bitmap_prealloc_blocks(struct super_block *sb, | |||
210 | bit = block % (sb->s_blocksize << 3); | 207 | bit = block % (sb->s_blocksize << 3); |
211 | 208 | ||
212 | while (bit < (sb->s_blocksize << 3) && block_count > 0) { | 209 | while (bit < (sb->s_blocksize << 3) && block_count > 0) { |
213 | if (!udf_test_bit(bit, bh->b_data)) | 210 | if (!udf_clear_bit(bit, bh->b_data)) |
214 | goto out; | 211 | goto out; |
215 | else if (dquot_prealloc_block(inode, 1)) | ||
216 | goto out; | ||
217 | else if (!udf_clear_bit(bit, bh->b_data)) { | ||
218 | udf_debug("bit already cleared for block %d\n", bit); | ||
219 | dquot_free_block(inode, 1); | ||
220 | goto out; | ||
221 | } | ||
222 | block_count--; | 212 | block_count--; |
223 | alloc_count++; | 213 | alloc_count++; |
224 | bit++; | 214 | bit++; |
@@ -338,20 +328,6 @@ search_back: | |||
338 | } | 328 | } |
339 | 329 | ||
340 | got_block: | 330 | got_block: |
341 | |||
342 | /* | ||
343 | * Check quota for allocation of this block. | ||
344 | */ | ||
345 | if (inode) { | ||
346 | int ret = dquot_alloc_block(inode, 1); | ||
347 | |||
348 | if (ret) { | ||
349 | mutex_unlock(&sbi->s_alloc_mutex); | ||
350 | *err = ret; | ||
351 | return 0; | ||
352 | } | ||
353 | } | ||
354 | |||
355 | newblock = bit + (block_group << (sb->s_blocksize_bits + 3)) - | 331 | newblock = bit + (block_group << (sb->s_blocksize_bits + 3)) - |
356 | (sizeof(struct spaceBitmapDesc) << 3); | 332 | (sizeof(struct spaceBitmapDesc) << 3); |
357 | 333 | ||
@@ -401,10 +377,6 @@ static void udf_table_free_blocks(struct super_block *sb, | |||
401 | } | 377 | } |
402 | 378 | ||
403 | iinfo = UDF_I(table); | 379 | iinfo = UDF_I(table); |
404 | /* We do this up front - There are some error conditions that | ||
405 | could occure, but.. oh well */ | ||
406 | if (inode) | ||
407 | dquot_free_block(inode, count); | ||
408 | udf_add_free_space(sb, sbi->s_partition, count); | 380 | udf_add_free_space(sb, sbi->s_partition, count); |
409 | 381 | ||
410 | start = bloc->logicalBlockNum + offset; | 382 | start = bloc->logicalBlockNum + offset; |
@@ -649,10 +621,7 @@ static int udf_table_prealloc_blocks(struct super_block *sb, | |||
649 | epos.offset -= adsize; | 621 | epos.offset -= adsize; |
650 | 622 | ||
651 | alloc_count = (elen >> sb->s_blocksize_bits); | 623 | alloc_count = (elen >> sb->s_blocksize_bits); |
652 | if (inode && dquot_prealloc_block(inode, | 624 | if (alloc_count > block_count) { |
653 | alloc_count > block_count ? block_count : alloc_count)) | ||
654 | alloc_count = 0; | ||
655 | else if (alloc_count > block_count) { | ||
656 | alloc_count = block_count; | 625 | alloc_count = block_count; |
657 | eloc.logicalBlockNum += alloc_count; | 626 | eloc.logicalBlockNum += alloc_count; |
658 | elen -= (alloc_count << sb->s_blocksize_bits); | 627 | elen -= (alloc_count << sb->s_blocksize_bits); |
@@ -752,14 +721,6 @@ static int udf_table_new_block(struct super_block *sb, | |||
752 | newblock = goal_eloc.logicalBlockNum; | 721 | newblock = goal_eloc.logicalBlockNum; |
753 | goal_eloc.logicalBlockNum++; | 722 | goal_eloc.logicalBlockNum++; |
754 | goal_elen -= sb->s_blocksize; | 723 | goal_elen -= sb->s_blocksize; |
755 | if (inode) { | ||
756 | *err = dquot_alloc_block(inode, 1); | ||
757 | if (*err) { | ||
758 | brelse(goal_epos.bh); | ||
759 | mutex_unlock(&sbi->s_alloc_mutex); | ||
760 | return 0; | ||
761 | } | ||
762 | } | ||
763 | 724 | ||
764 | if (goal_elen) | 725 | if (goal_elen) |
765 | udf_write_aext(table, &goal_epos, &goal_eloc, goal_elen, 1); | 726 | udf_write_aext(table, &goal_epos, &goal_eloc, goal_elen, 1); |
diff --git a/fs/udf/dir.c b/fs/udf/dir.c index 1660c81ffa3d..51552bf50225 100644 --- a/fs/udf/dir.c +++ b/fs/udf/dir.c | |||
@@ -211,5 +211,5 @@ const struct file_operations udf_dir_operations = { | |||
211 | .read = generic_read_dir, | 211 | .read = generic_read_dir, |
212 | .readdir = udf_readdir, | 212 | .readdir = udf_readdir, |
213 | .unlocked_ioctl = udf_ioctl, | 213 | .unlocked_ioctl = udf_ioctl, |
214 | .fsync = simple_fsync, | 214 | .fsync = generic_file_fsync, |
215 | }; | 215 | }; |
diff --git a/fs/udf/file.c b/fs/udf/file.c index baae3a723946..94e06d6bddbd 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/errno.h> | 34 | #include <linux/errno.h> |
35 | #include <linux/smp_lock.h> | 35 | #include <linux/smp_lock.h> |
36 | #include <linux/pagemap.h> | 36 | #include <linux/pagemap.h> |
37 | #include <linux/quotaops.h> | ||
38 | #include <linux/buffer_head.h> | 37 | #include <linux/buffer_head.h> |
39 | #include <linux/aio.h> | 38 | #include <linux/aio.h> |
40 | #include <linux/smp_lock.h> | 39 | #include <linux/smp_lock.h> |
@@ -219,39 +218,16 @@ const struct file_operations udf_file_operations = { | |||
219 | .read = do_sync_read, | 218 | .read = do_sync_read, |
220 | .aio_read = generic_file_aio_read, | 219 | .aio_read = generic_file_aio_read, |
221 | .unlocked_ioctl = udf_ioctl, | 220 | .unlocked_ioctl = udf_ioctl, |
222 | .open = dquot_file_open, | 221 | .open = generic_file_open, |
223 | .mmap = generic_file_mmap, | 222 | .mmap = generic_file_mmap, |
224 | .write = do_sync_write, | 223 | .write = do_sync_write, |
225 | .aio_write = udf_file_aio_write, | 224 | .aio_write = udf_file_aio_write, |
226 | .release = udf_release_file, | 225 | .release = udf_release_file, |
227 | .fsync = simple_fsync, | 226 | .fsync = generic_file_fsync, |
228 | .splice_read = generic_file_splice_read, | 227 | .splice_read = generic_file_splice_read, |
229 | .llseek = generic_file_llseek, | 228 | .llseek = generic_file_llseek, |
230 | }; | 229 | }; |
231 | 230 | ||
232 | int udf_setattr(struct dentry *dentry, struct iattr *iattr) | ||
233 | { | ||
234 | struct inode *inode = dentry->d_inode; | ||
235 | int error; | ||
236 | |||
237 | error = inode_change_ok(inode, iattr); | ||
238 | if (error) | ||
239 | return error; | ||
240 | |||
241 | if (is_quota_modification(inode, iattr)) | ||
242 | dquot_initialize(inode); | ||
243 | |||
244 | if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) || | ||
245 | (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) { | ||
246 | error = dquot_transfer(inode, iattr); | ||
247 | if (error) | ||
248 | return error; | ||
249 | } | ||
250 | |||
251 | return inode_setattr(inode, iattr); | ||
252 | } | ||
253 | |||
254 | const struct inode_operations udf_file_inode_operations = { | 231 | const struct inode_operations udf_file_inode_operations = { |
255 | .truncate = udf_truncate, | 232 | .truncate = udf_truncate, |
256 | .setattr = udf_setattr, | ||
257 | }; | 233 | }; |
diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c index 2b5586c7f02a..18cd7111185d 100644 --- a/fs/udf/ialloc.c +++ b/fs/udf/ialloc.c | |||
@@ -20,7 +20,6 @@ | |||
20 | 20 | ||
21 | #include "udfdecl.h" | 21 | #include "udfdecl.h" |
22 | #include <linux/fs.h> | 22 | #include <linux/fs.h> |
23 | #include <linux/quotaops.h> | ||
24 | #include <linux/sched.h> | 23 | #include <linux/sched.h> |
25 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
26 | 25 | ||
@@ -32,13 +31,6 @@ void udf_free_inode(struct inode *inode) | |||
32 | struct super_block *sb = inode->i_sb; | 31 | struct super_block *sb = inode->i_sb; |
33 | struct udf_sb_info *sbi = UDF_SB(sb); | 32 | struct udf_sb_info *sbi = UDF_SB(sb); |
34 | 33 | ||
35 | /* | ||
36 | * Note: we must free any quota before locking the superblock, | ||
37 | * as writing the quota to disk may need the lock as well. | ||
38 | */ | ||
39 | dquot_free_inode(inode); | ||
40 | dquot_drop(inode); | ||
41 | |||
42 | clear_inode(inode); | 34 | clear_inode(inode); |
43 | 35 | ||
44 | mutex_lock(&sbi->s_alloc_mutex); | 36 | mutex_lock(&sbi->s_alloc_mutex); |
@@ -61,7 +53,7 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err) | |||
61 | struct super_block *sb = dir->i_sb; | 53 | struct super_block *sb = dir->i_sb; |
62 | struct udf_sb_info *sbi = UDF_SB(sb); | 54 | struct udf_sb_info *sbi = UDF_SB(sb); |
63 | struct inode *inode; | 55 | struct inode *inode; |
64 | int block, ret; | 56 | int block; |
65 | uint32_t start = UDF_I(dir)->i_location.logicalBlockNum; | 57 | uint32_t start = UDF_I(dir)->i_location.logicalBlockNum; |
66 | struct udf_inode_info *iinfo; | 58 | struct udf_inode_info *iinfo; |
67 | struct udf_inode_info *dinfo = UDF_I(dir); | 59 | struct udf_inode_info *dinfo = UDF_I(dir); |
@@ -146,17 +138,6 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err) | |||
146 | insert_inode_hash(inode); | 138 | insert_inode_hash(inode); |
147 | mark_inode_dirty(inode); | 139 | mark_inode_dirty(inode); |
148 | 140 | ||
149 | dquot_initialize(inode); | ||
150 | ret = dquot_alloc_inode(inode); | ||
151 | if (ret) { | ||
152 | dquot_drop(inode); | ||
153 | inode->i_flags |= S_NOQUOTA; | ||
154 | inode->i_nlink = 0; | ||
155 | iput(inode); | ||
156 | *err = ret; | ||
157 | return NULL; | ||
158 | } | ||
159 | |||
160 | *err = 0; | 141 | *err = 0; |
161 | return inode; | 142 | return inode; |
162 | } | 143 | } |
diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 8a3fbd177cab..124852bcf6fe 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <linux/pagemap.h> | 36 | #include <linux/pagemap.h> |
37 | #include <linux/buffer_head.h> | 37 | #include <linux/buffer_head.h> |
38 | #include <linux/writeback.h> | 38 | #include <linux/writeback.h> |
39 | #include <linux/quotaops.h> | ||
40 | #include <linux/slab.h> | 39 | #include <linux/slab.h> |
41 | #include <linux/crc-itu-t.h> | 40 | #include <linux/crc-itu-t.h> |
42 | 41 | ||
@@ -71,9 +70,6 @@ static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int); | |||
71 | 70 | ||
72 | void udf_delete_inode(struct inode *inode) | 71 | void udf_delete_inode(struct inode *inode) |
73 | { | 72 | { |
74 | if (!is_bad_inode(inode)) | ||
75 | dquot_initialize(inode); | ||
76 | |||
77 | truncate_inode_pages(&inode->i_data, 0); | 73 | truncate_inode_pages(&inode->i_data, 0); |
78 | 74 | ||
79 | if (is_bad_inode(inode)) | 75 | if (is_bad_inode(inode)) |
@@ -113,7 +109,6 @@ void udf_clear_inode(struct inode *inode) | |||
113 | (unsigned long long)iinfo->i_lenExtents); | 109 | (unsigned long long)iinfo->i_lenExtents); |
114 | } | 110 | } |
115 | 111 | ||
116 | dquot_drop(inode); | ||
117 | kfree(iinfo->i_ext.i_data); | 112 | kfree(iinfo->i_ext.i_data); |
118 | iinfo->i_ext.i_data = NULL; | 113 | iinfo->i_ext.i_data = NULL; |
119 | } | 114 | } |
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 585f733615dc..bf5fc674193c 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/errno.h> | 27 | #include <linux/errno.h> |
28 | #include <linux/mm.h> | 28 | #include <linux/mm.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/quotaops.h> | ||
31 | #include <linux/smp_lock.h> | 30 | #include <linux/smp_lock.h> |
32 | #include <linux/buffer_head.h> | 31 | #include <linux/buffer_head.h> |
33 | #include <linux/sched.h> | 32 | #include <linux/sched.h> |
@@ -563,8 +562,6 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode, | |||
563 | int err; | 562 | int err; |
564 | struct udf_inode_info *iinfo; | 563 | struct udf_inode_info *iinfo; |
565 | 564 | ||
566 | dquot_initialize(dir); | ||
567 | |||
568 | lock_kernel(); | 565 | lock_kernel(); |
569 | inode = udf_new_inode(dir, mode, &err); | 566 | inode = udf_new_inode(dir, mode, &err); |
570 | if (!inode) { | 567 | if (!inode) { |
@@ -617,8 +614,6 @@ static int udf_mknod(struct inode *dir, struct dentry *dentry, int mode, | |||
617 | if (!old_valid_dev(rdev)) | 614 | if (!old_valid_dev(rdev)) |
618 | return -EINVAL; | 615 | return -EINVAL; |
619 | 616 | ||
620 | dquot_initialize(dir); | ||
621 | |||
622 | lock_kernel(); | 617 | lock_kernel(); |
623 | err = -EIO; | 618 | err = -EIO; |
624 | inode = udf_new_inode(dir, mode, &err); | 619 | inode = udf_new_inode(dir, mode, &err); |
@@ -664,8 +659,6 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
664 | struct udf_inode_info *dinfo = UDF_I(dir); | 659 | struct udf_inode_info *dinfo = UDF_I(dir); |
665 | struct udf_inode_info *iinfo; | 660 | struct udf_inode_info *iinfo; |
666 | 661 | ||
667 | dquot_initialize(dir); | ||
668 | |||
669 | lock_kernel(); | 662 | lock_kernel(); |
670 | err = -EMLINK; | 663 | err = -EMLINK; |
671 | if (dir->i_nlink >= (256 << sizeof(dir->i_nlink)) - 1) | 664 | if (dir->i_nlink >= (256 << sizeof(dir->i_nlink)) - 1) |
@@ -800,8 +793,6 @@ static int udf_rmdir(struct inode *dir, struct dentry *dentry) | |||
800 | struct fileIdentDesc *fi, cfi; | 793 | struct fileIdentDesc *fi, cfi; |
801 | struct kernel_lb_addr tloc; | 794 | struct kernel_lb_addr tloc; |
802 | 795 | ||
803 | dquot_initialize(dir); | ||
804 | |||
805 | retval = -ENOENT; | 796 | retval = -ENOENT; |
806 | lock_kernel(); | 797 | lock_kernel(); |
807 | fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); | 798 | fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); |
@@ -848,8 +839,6 @@ static int udf_unlink(struct inode *dir, struct dentry *dentry) | |||
848 | struct fileIdentDesc cfi; | 839 | struct fileIdentDesc cfi; |
849 | struct kernel_lb_addr tloc; | 840 | struct kernel_lb_addr tloc; |
850 | 841 | ||
851 | dquot_initialize(dir); | ||
852 | |||
853 | retval = -ENOENT; | 842 | retval = -ENOENT; |
854 | lock_kernel(); | 843 | lock_kernel(); |
855 | fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); | 844 | fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); |
@@ -904,8 +893,6 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
904 | struct buffer_head *bh; | 893 | struct buffer_head *bh; |
905 | struct udf_inode_info *iinfo; | 894 | struct udf_inode_info *iinfo; |
906 | 895 | ||
907 | dquot_initialize(dir); | ||
908 | |||
909 | lock_kernel(); | 896 | lock_kernel(); |
910 | inode = udf_new_inode(dir, S_IFLNK | S_IRWXUGO, &err); | 897 | inode = udf_new_inode(dir, S_IFLNK | S_IRWXUGO, &err); |
911 | if (!inode) | 898 | if (!inode) |
@@ -1075,8 +1062,6 @@ static int udf_link(struct dentry *old_dentry, struct inode *dir, | |||
1075 | int err; | 1062 | int err; |
1076 | struct buffer_head *bh; | 1063 | struct buffer_head *bh; |
1077 | 1064 | ||
1078 | dquot_initialize(dir); | ||
1079 | |||
1080 | lock_kernel(); | 1065 | lock_kernel(); |
1081 | if (inode->i_nlink >= (256 << sizeof(inode->i_nlink)) - 1) { | 1066 | if (inode->i_nlink >= (256 << sizeof(inode->i_nlink)) - 1) { |
1082 | unlock_kernel(); | 1067 | unlock_kernel(); |
@@ -1139,9 +1124,6 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1139 | struct kernel_lb_addr tloc; | 1124 | struct kernel_lb_addr tloc; |
1140 | struct udf_inode_info *old_iinfo = UDF_I(old_inode); | 1125 | struct udf_inode_info *old_iinfo = UDF_I(old_inode); |
1141 | 1126 | ||
1142 | dquot_initialize(old_dir); | ||
1143 | dquot_initialize(new_dir); | ||
1144 | |||
1145 | lock_kernel(); | 1127 | lock_kernel(); |
1146 | ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi); | 1128 | ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi); |
1147 | if (ofi) { | 1129 | if (ofi) { |
@@ -1387,7 +1369,6 @@ const struct export_operations udf_export_ops = { | |||
1387 | const struct inode_operations udf_dir_inode_operations = { | 1369 | const struct inode_operations udf_dir_inode_operations = { |
1388 | .lookup = udf_lookup, | 1370 | .lookup = udf_lookup, |
1389 | .create = udf_create, | 1371 | .create = udf_create, |
1390 | .setattr = udf_setattr, | ||
1391 | .link = udf_link, | 1372 | .link = udf_link, |
1392 | .unlink = udf_unlink, | 1373 | .unlink = udf_unlink, |
1393 | .symlink = udf_symlink, | 1374 | .symlink = udf_symlink, |
@@ -1400,5 +1381,4 @@ const struct inode_operations udf_symlink_inode_operations = { | |||
1400 | .readlink = generic_readlink, | 1381 | .readlink = generic_readlink, |
1401 | .follow_link = page_follow_link_light, | 1382 | .follow_link = page_follow_link_light, |
1402 | .put_link = page_put_link, | 1383 | .put_link = page_put_link, |
1403 | .setattr = udf_setattr, | ||
1404 | }; | 1384 | }; |
diff --git a/fs/udf/super.c b/fs/udf/super.c index 1e4543cbcd27..612d1e2e285a 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
@@ -557,6 +557,7 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options) | |||
557 | { | 557 | { |
558 | struct udf_options uopt; | 558 | struct udf_options uopt; |
559 | struct udf_sb_info *sbi = UDF_SB(sb); | 559 | struct udf_sb_info *sbi = UDF_SB(sb); |
560 | int error = 0; | ||
560 | 561 | ||
561 | uopt.flags = sbi->s_flags; | 562 | uopt.flags = sbi->s_flags; |
562 | uopt.uid = sbi->s_uid; | 563 | uopt.uid = sbi->s_uid; |
@@ -582,17 +583,17 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options) | |||
582 | *flags |= MS_RDONLY; | 583 | *flags |= MS_RDONLY; |
583 | } | 584 | } |
584 | 585 | ||
585 | if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) { | 586 | if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) |
586 | unlock_kernel(); | 587 | goto out_unlock; |
587 | return 0; | 588 | |
588 | } | ||
589 | if (*flags & MS_RDONLY) | 589 | if (*flags & MS_RDONLY) |
590 | udf_close_lvid(sb); | 590 | udf_close_lvid(sb); |
591 | else | 591 | else |
592 | udf_open_lvid(sb); | 592 | udf_open_lvid(sb); |
593 | 593 | ||
594 | out_unlock: | ||
594 | unlock_kernel(); | 595 | unlock_kernel(); |
595 | return 0; | 596 | return error; |
596 | } | 597 | } |
597 | 598 | ||
598 | /* Check Volume Structure Descriptors (ECMA 167 2/9.1) */ | 599 | /* Check Volume Structure Descriptors (ECMA 167 2/9.1) */ |
@@ -1939,7 +1940,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
1939 | /* Fill in the rest of the superblock */ | 1940 | /* Fill in the rest of the superblock */ |
1940 | sb->s_op = &udf_sb_ops; | 1941 | sb->s_op = &udf_sb_ops; |
1941 | sb->s_export_op = &udf_export_ops; | 1942 | sb->s_export_op = &udf_export_ops; |
1942 | sb->dq_op = NULL; | 1943 | |
1943 | sb->s_dirt = 0; | 1944 | sb->s_dirt = 0; |
1944 | sb->s_magic = UDF_SUPER_MAGIC; | 1945 | sb->s_magic = UDF_SUPER_MAGIC; |
1945 | sb->s_time_gran = 1000; | 1946 | sb->s_time_gran = 1000; |
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index 9079ff7d6255..2bac0354891f 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h | |||
@@ -131,7 +131,6 @@ extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *, | |||
131 | 131 | ||
132 | /* file.c */ | 132 | /* file.c */ |
133 | extern long udf_ioctl(struct file *, unsigned int, unsigned long); | 133 | extern long udf_ioctl(struct file *, unsigned int, unsigned long); |
134 | extern int udf_setattr(struct dentry *dentry, struct iattr *iattr); | ||
135 | /* inode.c */ | 134 | /* inode.c */ |
136 | extern struct inode *udf_iget(struct super_block *, struct kernel_lb_addr *); | 135 | extern struct inode *udf_iget(struct super_block *, struct kernel_lb_addr *); |
137 | extern int udf_sync_inode(struct inode *); | 136 | extern int udf_sync_inode(struct inode *); |
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c index 5cfa4d85ccf2..048484fb10d2 100644 --- a/fs/ufs/balloc.c +++ b/fs/ufs/balloc.c | |||
@@ -12,7 +12,6 @@ | |||
12 | #include <linux/stat.h> | 12 | #include <linux/stat.h> |
13 | #include <linux/time.h> | 13 | #include <linux/time.h> |
14 | #include <linux/string.h> | 14 | #include <linux/string.h> |
15 | #include <linux/quotaops.h> | ||
16 | #include <linux/buffer_head.h> | 15 | #include <linux/buffer_head.h> |
17 | #include <linux/capability.h> | 16 | #include <linux/capability.h> |
18 | #include <linux/bitops.h> | 17 | #include <linux/bitops.h> |
@@ -85,9 +84,6 @@ void ufs_free_fragments(struct inode *inode, u64 fragment, unsigned count) | |||
85 | "bit already cleared for fragment %u", i); | 84 | "bit already cleared for fragment %u", i); |
86 | } | 85 | } |
87 | 86 | ||
88 | dquot_free_block(inode, count); | ||
89 | |||
90 | |||
91 | fs32_add(sb, &ucg->cg_cs.cs_nffree, count); | 87 | fs32_add(sb, &ucg->cg_cs.cs_nffree, count); |
92 | uspi->cs_total.cs_nffree += count; | 88 | uspi->cs_total.cs_nffree += count; |
93 | fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, count); | 89 | fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, count); |
@@ -195,7 +191,6 @@ do_more: | |||
195 | ubh_setblock(UCPI_UBH(ucpi), ucpi->c_freeoff, blkno); | 191 | ubh_setblock(UCPI_UBH(ucpi), ucpi->c_freeoff, blkno); |
196 | if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD) | 192 | if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD) |
197 | ufs_clusteracct (sb, ucpi, blkno, 1); | 193 | ufs_clusteracct (sb, ucpi, blkno, 1); |
198 | dquot_free_block(inode, uspi->s_fpb); | ||
199 | 194 | ||
200 | fs32_add(sb, &ucg->cg_cs.cs_nbfree, 1); | 195 | fs32_add(sb, &ucg->cg_cs.cs_nbfree, 1); |
201 | uspi->cs_total.cs_nbfree++; | 196 | uspi->cs_total.cs_nbfree++; |
@@ -511,7 +506,6 @@ static u64 ufs_add_fragments(struct inode *inode, u64 fragment, | |||
511 | struct ufs_cg_private_info * ucpi; | 506 | struct ufs_cg_private_info * ucpi; |
512 | struct ufs_cylinder_group * ucg; | 507 | struct ufs_cylinder_group * ucg; |
513 | unsigned cgno, fragno, fragoff, count, fragsize, i; | 508 | unsigned cgno, fragno, fragoff, count, fragsize, i; |
514 | int ret; | ||
515 | 509 | ||
516 | UFSD("ENTER, fragment %llu, oldcount %u, newcount %u\n", | 510 | UFSD("ENTER, fragment %llu, oldcount %u, newcount %u\n", |
517 | (unsigned long long)fragment, oldcount, newcount); | 511 | (unsigned long long)fragment, oldcount, newcount); |
@@ -557,11 +551,6 @@ static u64 ufs_add_fragments(struct inode *inode, u64 fragment, | |||
557 | fs32_add(sb, &ucg->cg_frsum[fragsize - count], 1); | 551 | fs32_add(sb, &ucg->cg_frsum[fragsize - count], 1); |
558 | for (i = oldcount; i < newcount; i++) | 552 | for (i = oldcount; i < newcount; i++) |
559 | ubh_clrbit (UCPI_UBH(ucpi), ucpi->c_freeoff, fragno + i); | 553 | ubh_clrbit (UCPI_UBH(ucpi), ucpi->c_freeoff, fragno + i); |
560 | ret = dquot_alloc_block(inode, count); | ||
561 | if (ret) { | ||
562 | *err = ret; | ||
563 | return 0; | ||
564 | } | ||
565 | 554 | ||
566 | fs32_sub(sb, &ucg->cg_cs.cs_nffree, count); | 555 | fs32_sub(sb, &ucg->cg_cs.cs_nffree, count); |
567 | fs32_sub(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, count); | 556 | fs32_sub(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, count); |
@@ -598,7 +587,6 @@ static u64 ufs_alloc_fragments(struct inode *inode, unsigned cgno, | |||
598 | struct ufs_cylinder_group * ucg; | 587 | struct ufs_cylinder_group * ucg; |
599 | unsigned oldcg, i, j, k, allocsize; | 588 | unsigned oldcg, i, j, k, allocsize; |
600 | u64 result; | 589 | u64 result; |
601 | int ret; | ||
602 | 590 | ||
603 | UFSD("ENTER, ino %lu, cgno %u, goal %llu, count %u\n", | 591 | UFSD("ENTER, ino %lu, cgno %u, goal %llu, count %u\n", |
604 | inode->i_ino, cgno, (unsigned long long)goal, count); | 592 | inode->i_ino, cgno, (unsigned long long)goal, count); |
@@ -667,7 +655,6 @@ cg_found: | |||
667 | for (i = count; i < uspi->s_fpb; i++) | 655 | for (i = count; i < uspi->s_fpb; i++) |
668 | ubh_setbit (UCPI_UBH(ucpi), ucpi->c_freeoff, goal + i); | 656 | ubh_setbit (UCPI_UBH(ucpi), ucpi->c_freeoff, goal + i); |
669 | i = uspi->s_fpb - count; | 657 | i = uspi->s_fpb - count; |
670 | dquot_free_block(inode, i); | ||
671 | 658 | ||
672 | fs32_add(sb, &ucg->cg_cs.cs_nffree, i); | 659 | fs32_add(sb, &ucg->cg_cs.cs_nffree, i); |
673 | uspi->cs_total.cs_nffree += i; | 660 | uspi->cs_total.cs_nffree += i; |
@@ -679,11 +666,6 @@ cg_found: | |||
679 | result = ufs_bitmap_search (sb, ucpi, goal, allocsize); | 666 | result = ufs_bitmap_search (sb, ucpi, goal, allocsize); |
680 | if (result == INVBLOCK) | 667 | if (result == INVBLOCK) |
681 | return 0; | 668 | return 0; |
682 | ret = dquot_alloc_block(inode, count); | ||
683 | if (ret) { | ||
684 | *err = ret; | ||
685 | return 0; | ||
686 | } | ||
687 | for (i = 0; i < count; i++) | 669 | for (i = 0; i < count; i++) |
688 | ubh_clrbit (UCPI_UBH(ucpi), ucpi->c_freeoff, result + i); | 670 | ubh_clrbit (UCPI_UBH(ucpi), ucpi->c_freeoff, result + i); |
689 | 671 | ||
@@ -718,7 +700,6 @@ static u64 ufs_alloccg_block(struct inode *inode, | |||
718 | struct ufs_super_block_first * usb1; | 700 | struct ufs_super_block_first * usb1; |
719 | struct ufs_cylinder_group * ucg; | 701 | struct ufs_cylinder_group * ucg; |
720 | u64 result, blkno; | 702 | u64 result, blkno; |
721 | int ret; | ||
722 | 703 | ||
723 | UFSD("ENTER, goal %llu\n", (unsigned long long)goal); | 704 | UFSD("ENTER, goal %llu\n", (unsigned long long)goal); |
724 | 705 | ||
@@ -752,11 +733,6 @@ gotit: | |||
752 | ubh_clrblock (UCPI_UBH(ucpi), ucpi->c_freeoff, blkno); | 733 | ubh_clrblock (UCPI_UBH(ucpi), ucpi->c_freeoff, blkno); |
753 | if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD) | 734 | if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD) |
754 | ufs_clusteracct (sb, ucpi, blkno, -1); | 735 | ufs_clusteracct (sb, ucpi, blkno, -1); |
755 | ret = dquot_alloc_block(inode, uspi->s_fpb); | ||
756 | if (ret) { | ||
757 | *err = ret; | ||
758 | return INVBLOCK; | ||
759 | } | ||
760 | 736 | ||
761 | fs32_sub(sb, &ucg->cg_cs.cs_nbfree, 1); | 737 | fs32_sub(sb, &ucg->cg_cs.cs_nbfree, 1); |
762 | uspi->cs_total.cs_nbfree--; | 738 | uspi->cs_total.cs_nbfree--; |
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c index 317a0d444f6b..ec784756dc65 100644 --- a/fs/ufs/dir.c +++ b/fs/ufs/dir.c | |||
@@ -666,6 +666,6 @@ not_empty: | |||
666 | const struct file_operations ufs_dir_operations = { | 666 | const struct file_operations ufs_dir_operations = { |
667 | .read = generic_read_dir, | 667 | .read = generic_read_dir, |
668 | .readdir = ufs_readdir, | 668 | .readdir = ufs_readdir, |
669 | .fsync = simple_fsync, | 669 | .fsync = generic_file_fsync, |
670 | .llseek = generic_file_llseek, | 670 | .llseek = generic_file_llseek, |
671 | }; | 671 | }; |
diff --git a/fs/ufs/file.c b/fs/ufs/file.c index a8962cecde5b..33afa20d4509 100644 --- a/fs/ufs/file.c +++ b/fs/ufs/file.c | |||
@@ -24,7 +24,6 @@ | |||
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/fs.h> | 26 | #include <linux/fs.h> |
27 | #include <linux/quotaops.h> | ||
28 | 27 | ||
29 | #include "ufs_fs.h" | 28 | #include "ufs_fs.h" |
30 | #include "ufs.h" | 29 | #include "ufs.h" |
@@ -41,7 +40,7 @@ const struct file_operations ufs_file_operations = { | |||
41 | .write = do_sync_write, | 40 | .write = do_sync_write, |
42 | .aio_write = generic_file_aio_write, | 41 | .aio_write = generic_file_aio_write, |
43 | .mmap = generic_file_mmap, | 42 | .mmap = generic_file_mmap, |
44 | .open = dquot_file_open, | 43 | .open = generic_file_open, |
45 | .fsync = simple_fsync, | 44 | .fsync = generic_file_fsync, |
46 | .splice_read = generic_file_splice_read, | 45 | .splice_read = generic_file_splice_read, |
47 | }; | 46 | }; |
diff --git a/fs/ufs/ialloc.c b/fs/ufs/ialloc.c index 3a959d55084d..594480e537d2 100644 --- a/fs/ufs/ialloc.c +++ b/fs/ufs/ialloc.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/time.h> | 27 | #include <linux/time.h> |
28 | #include <linux/stat.h> | 28 | #include <linux/stat.h> |
29 | #include <linux/string.h> | 29 | #include <linux/string.h> |
30 | #include <linux/quotaops.h> | ||
31 | #include <linux/buffer_head.h> | 30 | #include <linux/buffer_head.h> |
32 | #include <linux/sched.h> | 31 | #include <linux/sched.h> |
33 | #include <linux/bitops.h> | 32 | #include <linux/bitops.h> |
@@ -95,9 +94,6 @@ void ufs_free_inode (struct inode * inode) | |||
95 | 94 | ||
96 | is_directory = S_ISDIR(inode->i_mode); | 95 | is_directory = S_ISDIR(inode->i_mode); |
97 | 96 | ||
98 | dquot_free_inode(inode); | ||
99 | dquot_drop(inode); | ||
100 | |||
101 | clear_inode (inode); | 97 | clear_inode (inode); |
102 | 98 | ||
103 | if (ubh_isclr (UCPI_UBH(ucpi), ucpi->c_iusedoff, bit)) | 99 | if (ubh_isclr (UCPI_UBH(ucpi), ucpi->c_iusedoff, bit)) |
@@ -347,21 +343,12 @@ cg_found: | |||
347 | 343 | ||
348 | unlock_super (sb); | 344 | unlock_super (sb); |
349 | 345 | ||
350 | dquot_initialize(inode); | ||
351 | err = dquot_alloc_inode(inode); | ||
352 | if (err) { | ||
353 | dquot_drop(inode); | ||
354 | goto fail_without_unlock; | ||
355 | } | ||
356 | |||
357 | UFSD("allocating inode %lu\n", inode->i_ino); | 346 | UFSD("allocating inode %lu\n", inode->i_ino); |
358 | UFSD("EXIT\n"); | 347 | UFSD("EXIT\n"); |
359 | return inode; | 348 | return inode; |
360 | 349 | ||
361 | fail_remove_inode: | 350 | fail_remove_inode: |
362 | unlock_super(sb); | 351 | unlock_super(sb); |
363 | fail_without_unlock: | ||
364 | inode->i_flags |= S_NOQUOTA; | ||
365 | inode->i_nlink = 0; | 352 | inode->i_nlink = 0; |
366 | iput(inode); | 353 | iput(inode); |
367 | UFSD("EXIT (FAILED): err %d\n", err); | 354 | UFSD("EXIT (FAILED): err %d\n", err); |
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index cffa756f1047..73fe773aa034 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c | |||
@@ -37,7 +37,6 @@ | |||
37 | #include <linux/smp_lock.h> | 37 | #include <linux/smp_lock.h> |
38 | #include <linux/buffer_head.h> | 38 | #include <linux/buffer_head.h> |
39 | #include <linux/writeback.h> | 39 | #include <linux/writeback.h> |
40 | #include <linux/quotaops.h> | ||
41 | 40 | ||
42 | #include "ufs_fs.h" | 41 | #include "ufs_fs.h" |
43 | #include "ufs.h" | 42 | #include "ufs.h" |
@@ -910,9 +909,6 @@ void ufs_delete_inode (struct inode * inode) | |||
910 | { | 909 | { |
911 | loff_t old_i_size; | 910 | loff_t old_i_size; |
912 | 911 | ||
913 | if (!is_bad_inode(inode)) | ||
914 | dquot_initialize(inode); | ||
915 | |||
916 | truncate_inode_pages(&inode->i_data, 0); | 912 | truncate_inode_pages(&inode->i_data, 0); |
917 | if (is_bad_inode(inode)) | 913 | if (is_bad_inode(inode)) |
918 | goto no_delete; | 914 | goto no_delete; |
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c index eabc02eb1294..b056f02b1fb3 100644 --- a/fs/ufs/namei.c +++ b/fs/ufs/namei.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/time.h> | 30 | #include <linux/time.h> |
31 | #include <linux/fs.h> | 31 | #include <linux/fs.h> |
32 | #include <linux/smp_lock.h> | 32 | #include <linux/smp_lock.h> |
33 | #include <linux/quotaops.h> | ||
34 | 33 | ||
35 | #include "ufs_fs.h" | 34 | #include "ufs_fs.h" |
36 | #include "ufs.h" | 35 | #include "ufs.h" |
@@ -86,8 +85,6 @@ static int ufs_create (struct inode * dir, struct dentry * dentry, int mode, | |||
86 | 85 | ||
87 | UFSD("BEGIN\n"); | 86 | UFSD("BEGIN\n"); |
88 | 87 | ||
89 | dquot_initialize(dir); | ||
90 | |||
91 | inode = ufs_new_inode(dir, mode); | 88 | inode = ufs_new_inode(dir, mode); |
92 | err = PTR_ERR(inode); | 89 | err = PTR_ERR(inode); |
93 | 90 | ||
@@ -112,8 +109,6 @@ static int ufs_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_t | |||
112 | if (!old_valid_dev(rdev)) | 109 | if (!old_valid_dev(rdev)) |
113 | return -EINVAL; | 110 | return -EINVAL; |
114 | 111 | ||
115 | dquot_initialize(dir); | ||
116 | |||
117 | inode = ufs_new_inode(dir, mode); | 112 | inode = ufs_new_inode(dir, mode); |
118 | err = PTR_ERR(inode); | 113 | err = PTR_ERR(inode); |
119 | if (!IS_ERR(inode)) { | 114 | if (!IS_ERR(inode)) { |
@@ -138,8 +133,6 @@ static int ufs_symlink (struct inode * dir, struct dentry * dentry, | |||
138 | if (l > sb->s_blocksize) | 133 | if (l > sb->s_blocksize) |
139 | goto out_notlocked; | 134 | goto out_notlocked; |
140 | 135 | ||
141 | dquot_initialize(dir); | ||
142 | |||
143 | lock_kernel(); | 136 | lock_kernel(); |
144 | inode = ufs_new_inode(dir, S_IFLNK | S_IRWXUGO); | 137 | inode = ufs_new_inode(dir, S_IFLNK | S_IRWXUGO); |
145 | err = PTR_ERR(inode); | 138 | err = PTR_ERR(inode); |
@@ -185,8 +178,6 @@ static int ufs_link (struct dentry * old_dentry, struct inode * dir, | |||
185 | return -EMLINK; | 178 | return -EMLINK; |
186 | } | 179 | } |
187 | 180 | ||
188 | dquot_initialize(dir); | ||
189 | |||
190 | inode->i_ctime = CURRENT_TIME_SEC; | 181 | inode->i_ctime = CURRENT_TIME_SEC; |
191 | inode_inc_link_count(inode); | 182 | inode_inc_link_count(inode); |
192 | atomic_inc(&inode->i_count); | 183 | atomic_inc(&inode->i_count); |
@@ -204,8 +195,6 @@ static int ufs_mkdir(struct inode * dir, struct dentry * dentry, int mode) | |||
204 | if (dir->i_nlink >= UFS_LINK_MAX) | 195 | if (dir->i_nlink >= UFS_LINK_MAX) |
205 | goto out; | 196 | goto out; |
206 | 197 | ||
207 | dquot_initialize(dir); | ||
208 | |||
209 | lock_kernel(); | 198 | lock_kernel(); |
210 | inode_inc_link_count(dir); | 199 | inode_inc_link_count(dir); |
211 | 200 | ||
@@ -250,8 +239,6 @@ static int ufs_unlink(struct inode *dir, struct dentry *dentry) | |||
250 | struct page *page; | 239 | struct page *page; |
251 | int err = -ENOENT; | 240 | int err = -ENOENT; |
252 | 241 | ||
253 | dquot_initialize(dir); | ||
254 | |||
255 | de = ufs_find_entry(dir, &dentry->d_name, &page); | 242 | de = ufs_find_entry(dir, &dentry->d_name, &page); |
256 | if (!de) | 243 | if (!de) |
257 | goto out; | 244 | goto out; |
@@ -296,9 +283,6 @@ static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
296 | struct ufs_dir_entry *old_de; | 283 | struct ufs_dir_entry *old_de; |
297 | int err = -ENOENT; | 284 | int err = -ENOENT; |
298 | 285 | ||
299 | dquot_initialize(old_dir); | ||
300 | dquot_initialize(new_dir); | ||
301 | |||
302 | old_de = ufs_find_entry(old_dir, &old_dentry->d_name, &old_page); | 286 | old_de = ufs_find_entry(old_dir, &old_dentry->d_name, &old_page); |
303 | if (!old_de) | 287 | if (!old_de) |
304 | goto out; | 288 | goto out; |
diff --git a/fs/ufs/super.c b/fs/ufs/super.c index ad9bc1ebd3a6..3ec5a9eb6efb 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c | |||
@@ -77,7 +77,6 @@ | |||
77 | 77 | ||
78 | #include <linux/errno.h> | 78 | #include <linux/errno.h> |
79 | #include <linux/fs.h> | 79 | #include <linux/fs.h> |
80 | #include <linux/quotaops.h> | ||
81 | #include <linux/slab.h> | 80 | #include <linux/slab.h> |
82 | #include <linux/time.h> | 81 | #include <linux/time.h> |
83 | #include <linux/stat.h> | 82 | #include <linux/stat.h> |
@@ -1047,7 +1046,7 @@ magic_found: | |||
1047 | */ | 1046 | */ |
1048 | sb->s_op = &ufs_super_ops; | 1047 | sb->s_op = &ufs_super_ops; |
1049 | sb->s_export_op = &ufs_export_ops; | 1048 | sb->s_export_op = &ufs_export_ops; |
1050 | sb->dq_op = NULL; /***/ | 1049 | |
1051 | sb->s_magic = fs32_to_cpu(sb, usb3->fs_magic); | 1050 | sb->s_magic = fs32_to_cpu(sb, usb3->fs_magic); |
1052 | 1051 | ||
1053 | uspi->s_sblkno = fs32_to_cpu(sb, usb1->fs_sblkno); | 1052 | uspi->s_sblkno = fs32_to_cpu(sb, usb1->fs_sblkno); |
@@ -1437,126 +1436,19 @@ static void destroy_inodecache(void) | |||
1437 | kmem_cache_destroy(ufs_inode_cachep); | 1436 | kmem_cache_destroy(ufs_inode_cachep); |
1438 | } | 1437 | } |
1439 | 1438 | ||
1440 | static void ufs_clear_inode(struct inode *inode) | ||
1441 | { | ||
1442 | dquot_drop(inode); | ||
1443 | } | ||
1444 | |||
1445 | #ifdef CONFIG_QUOTA | ||
1446 | static ssize_t ufs_quota_read(struct super_block *, int, char *,size_t, loff_t); | ||
1447 | static ssize_t ufs_quota_write(struct super_block *, int, const char *, size_t, loff_t); | ||
1448 | #endif | ||
1449 | |||
1450 | static const struct super_operations ufs_super_ops = { | 1439 | static const struct super_operations ufs_super_ops = { |
1451 | .alloc_inode = ufs_alloc_inode, | 1440 | .alloc_inode = ufs_alloc_inode, |
1452 | .destroy_inode = ufs_destroy_inode, | 1441 | .destroy_inode = ufs_destroy_inode, |
1453 | .write_inode = ufs_write_inode, | 1442 | .write_inode = ufs_write_inode, |
1454 | .delete_inode = ufs_delete_inode, | 1443 | .delete_inode = ufs_delete_inode, |
1455 | .clear_inode = ufs_clear_inode, | ||
1456 | .put_super = ufs_put_super, | 1444 | .put_super = ufs_put_super, |
1457 | .write_super = ufs_write_super, | 1445 | .write_super = ufs_write_super, |
1458 | .sync_fs = ufs_sync_fs, | 1446 | .sync_fs = ufs_sync_fs, |
1459 | .statfs = ufs_statfs, | 1447 | .statfs = ufs_statfs, |
1460 | .remount_fs = ufs_remount, | 1448 | .remount_fs = ufs_remount, |
1461 | .show_options = ufs_show_options, | 1449 | .show_options = ufs_show_options, |
1462 | #ifdef CONFIG_QUOTA | ||
1463 | .quota_read = ufs_quota_read, | ||
1464 | .quota_write = ufs_quota_write, | ||
1465 | #endif | ||
1466 | }; | 1450 | }; |
1467 | 1451 | ||
1468 | #ifdef CONFIG_QUOTA | ||
1469 | |||
1470 | /* Read data from quotafile - avoid pagecache and such because we cannot afford | ||
1471 | * acquiring the locks... As quota files are never truncated and quota code | ||
1472 | * itself serializes the operations (and noone else should touch the files) | ||
1473 | * we don't have to be afraid of races */ | ||
1474 | static ssize_t ufs_quota_read(struct super_block *sb, int type, char *data, | ||
1475 | size_t len, loff_t off) | ||
1476 | { | ||
1477 | struct inode *inode = sb_dqopt(sb)->files[type]; | ||
1478 | sector_t blk = off >> sb->s_blocksize_bits; | ||
1479 | int err = 0; | ||
1480 | int offset = off & (sb->s_blocksize - 1); | ||
1481 | int tocopy; | ||
1482 | size_t toread; | ||
1483 | struct buffer_head *bh; | ||
1484 | loff_t i_size = i_size_read(inode); | ||
1485 | |||
1486 | if (off > i_size) | ||
1487 | return 0; | ||
1488 | if (off+len > i_size) | ||
1489 | len = i_size-off; | ||
1490 | toread = len; | ||
1491 | while (toread > 0) { | ||
1492 | tocopy = sb->s_blocksize - offset < toread ? | ||
1493 | sb->s_blocksize - offset : toread; | ||
1494 | |||
1495 | bh = ufs_bread(inode, blk, 0, &err); | ||
1496 | if (err) | ||
1497 | return err; | ||
1498 | if (!bh) /* A hole? */ | ||
1499 | memset(data, 0, tocopy); | ||
1500 | else { | ||
1501 | memcpy(data, bh->b_data+offset, tocopy); | ||
1502 | brelse(bh); | ||
1503 | } | ||
1504 | offset = 0; | ||
1505 | toread -= tocopy; | ||
1506 | data += tocopy; | ||
1507 | blk++; | ||
1508 | } | ||
1509 | return len; | ||
1510 | } | ||
1511 | |||
1512 | /* Write to quotafile */ | ||
1513 | static ssize_t ufs_quota_write(struct super_block *sb, int type, | ||
1514 | const char *data, size_t len, loff_t off) | ||
1515 | { | ||
1516 | struct inode *inode = sb_dqopt(sb)->files[type]; | ||
1517 | sector_t blk = off >> sb->s_blocksize_bits; | ||
1518 | int err = 0; | ||
1519 | int offset = off & (sb->s_blocksize - 1); | ||
1520 | int tocopy; | ||
1521 | size_t towrite = len; | ||
1522 | struct buffer_head *bh; | ||
1523 | |||
1524 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA); | ||
1525 | while (towrite > 0) { | ||
1526 | tocopy = sb->s_blocksize - offset < towrite ? | ||
1527 | sb->s_blocksize - offset : towrite; | ||
1528 | |||
1529 | bh = ufs_bread(inode, blk, 1, &err); | ||
1530 | if (!bh) | ||
1531 | goto out; | ||
1532 | lock_buffer(bh); | ||
1533 | memcpy(bh->b_data+offset, data, tocopy); | ||
1534 | flush_dcache_page(bh->b_page); | ||
1535 | set_buffer_uptodate(bh); | ||
1536 | mark_buffer_dirty(bh); | ||
1537 | unlock_buffer(bh); | ||
1538 | brelse(bh); | ||
1539 | offset = 0; | ||
1540 | towrite -= tocopy; | ||
1541 | data += tocopy; | ||
1542 | blk++; | ||
1543 | } | ||
1544 | out: | ||
1545 | if (len == towrite) { | ||
1546 | mutex_unlock(&inode->i_mutex); | ||
1547 | return err; | ||
1548 | } | ||
1549 | if (inode->i_size < off+len-towrite) | ||
1550 | i_size_write(inode, off+len-towrite); | ||
1551 | inode->i_version++; | ||
1552 | inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; | ||
1553 | mark_inode_dirty(inode); | ||
1554 | mutex_unlock(&inode->i_mutex); | ||
1555 | return len - towrite; | ||
1556 | } | ||
1557 | |||
1558 | #endif | ||
1559 | |||
1560 | static int ufs_get_sb(struct file_system_type *fs_type, | 1452 | static int ufs_get_sb(struct file_system_type *fs_type, |
1561 | int flags, const char *dev_name, void *data, struct vfsmount *mnt) | 1453 | int flags, const char *dev_name, void *data, struct vfsmount *mnt) |
1562 | { | 1454 | { |
diff --git a/fs/ufs/truncate.c b/fs/ufs/truncate.c index f294c44577dc..589e01a465ba 100644 --- a/fs/ufs/truncate.c +++ b/fs/ufs/truncate.c | |||
@@ -44,7 +44,6 @@ | |||
44 | #include <linux/buffer_head.h> | 44 | #include <linux/buffer_head.h> |
45 | #include <linux/blkdev.h> | 45 | #include <linux/blkdev.h> |
46 | #include <linux/sched.h> | 46 | #include <linux/sched.h> |
47 | #include <linux/quotaops.h> | ||
48 | 47 | ||
49 | #include "ufs_fs.h" | 48 | #include "ufs_fs.h" |
50 | #include "ufs.h" | 49 | #include "ufs.h" |
@@ -501,12 +500,10 @@ out: | |||
501 | return err; | 500 | return err; |
502 | } | 501 | } |
503 | 502 | ||
504 | |||
505 | /* | 503 | /* |
506 | * We don't define our `inode->i_op->truncate', and call it here, | 504 | * TODO: |
507 | * because of: | 505 | * - truncate case should use proper ordering instead of using |
508 | * - there is no way to know old size | 506 | * simple_setsize |
509 | * - there is no way inform user about error, if it happens in `truncate' | ||
510 | */ | 507 | */ |
511 | int ufs_setattr(struct dentry *dentry, struct iattr *attr) | 508 | int ufs_setattr(struct dentry *dentry, struct iattr *attr) |
512 | { | 509 | { |
@@ -518,19 +515,10 @@ int ufs_setattr(struct dentry *dentry, struct iattr *attr) | |||
518 | if (error) | 515 | if (error) |
519 | return error; | 516 | return error; |
520 | 517 | ||
521 | if (is_quota_modification(inode, attr)) | ||
522 | dquot_initialize(inode); | ||
523 | |||
524 | if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || | ||
525 | (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) { | ||
526 | error = dquot_transfer(inode, attr); | ||
527 | if (error) | ||
528 | return error; | ||
529 | } | ||
530 | if (ia_valid & ATTR_SIZE && attr->ia_size != inode->i_size) { | 518 | if (ia_valid & ATTR_SIZE && attr->ia_size != inode->i_size) { |
531 | loff_t old_i_size = inode->i_size; | 519 | loff_t old_i_size = inode->i_size; |
532 | 520 | ||
533 | error = vmtruncate(inode, attr->ia_size); | 521 | error = simple_setsize(inode, attr->ia_size); |
534 | if (error) | 522 | if (error) |
535 | return error; | 523 | return error; |
536 | error = ufs_truncate(inode, old_i_size); | 524 | error = ufs_truncate(inode, old_i_size); |
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index d8fb1b5d6cb5..257a56b127cf 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c | |||
@@ -100,10 +100,10 @@ xfs_iozero( | |||
100 | STATIC int | 100 | STATIC int |
101 | xfs_file_fsync( | 101 | xfs_file_fsync( |
102 | struct file *file, | 102 | struct file *file, |
103 | struct dentry *dentry, | ||
104 | int datasync) | 103 | int datasync) |
105 | { | 104 | { |
106 | struct xfs_inode *ip = XFS_I(dentry->d_inode); | 105 | struct inode *inode = file->f_mapping->host; |
106 | struct xfs_inode *ip = XFS_I(inode); | ||
107 | struct xfs_trans *tp; | 107 | struct xfs_trans *tp; |
108 | int error = 0; | 108 | int error = 0; |
109 | int log_flushed = 0; | 109 | int log_flushed = 0; |
@@ -140,8 +140,8 @@ xfs_file_fsync( | |||
140 | * might gets cleared when the inode gets written out via the AIL | 140 | * might gets cleared when the inode gets written out via the AIL |
141 | * or xfs_iflush_cluster. | 141 | * or xfs_iflush_cluster. |
142 | */ | 142 | */ |
143 | if (((dentry->d_inode->i_state & I_DIRTY_DATASYNC) || | 143 | if (((inode->i_state & I_DIRTY_DATASYNC) || |
144 | ((dentry->d_inode->i_state & I_DIRTY_SYNC) && !datasync)) && | 144 | ((inode->i_state & I_DIRTY_SYNC) && !datasync)) && |
145 | ip->i_update_core) { | 145 | ip->i_update_core) { |
146 | /* | 146 | /* |
147 | * Kick off a transaction to log the inode core to get the | 147 | * Kick off a transaction to log the inode core to get the |
@@ -868,7 +868,7 @@ write_retry: | |||
868 | mutex_lock(&inode->i_mutex); | 868 | mutex_lock(&inode->i_mutex); |
869 | xfs_ilock(ip, iolock); | 869 | xfs_ilock(ip, iolock); |
870 | 870 | ||
871 | error2 = -xfs_file_fsync(file, file->f_path.dentry, | 871 | error2 = -xfs_file_fsync(file, |
872 | (file->f_flags & __O_SYNC) ? 0 : 1); | 872 | (file->f_flags & __O_SYNC) ? 0 : 1); |
873 | if (!error) | 873 | if (!error) |
874 | error = error2; | 874 | error = error2; |
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 7bf83ddf82e0..baacd98e7cc6 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h | |||
@@ -373,7 +373,7 @@ struct acpi_pci_root { | |||
373 | struct acpi_pci_id id; | 373 | struct acpi_pci_id id; |
374 | struct pci_bus *bus; | 374 | struct pci_bus *bus; |
375 | u16 segment; | 375 | u16 segment; |
376 | u8 bus_nr; | 376 | struct resource secondary; /* downstream bus range */ |
377 | 377 | ||
378 | u32 osc_support_set; /* _OSC state of support bits */ | 378 | u32 osc_support_set; /* _OSC state of support bits */ |
379 | u32 osc_control_set; /* _OSC state of control bits */ | 379 | u32 osc_control_set; /* _OSC state of control bits */ |
diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h index 4f7b44866b76..23d78b4d088b 100644 --- a/include/acpi/acpi_drivers.h +++ b/include/acpi/acpi_drivers.h | |||
@@ -104,8 +104,7 @@ int acpi_pci_bind_root(struct acpi_device *device); | |||
104 | 104 | ||
105 | /* Arch-defined function to add a bus to the system */ | 105 | /* Arch-defined function to add a bus to the system */ |
106 | 106 | ||
107 | struct pci_bus *pci_acpi_scan_root(struct acpi_device *device, int domain, | 107 | struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root); |
108 | int bus); | ||
109 | void pci_acpi_crs_quirks(void); | 108 | void pci_acpi_crs_quirks(void); |
110 | 109 | ||
111 | /* -------------------------------------------------------------------------- | 110 | /* -------------------------------------------------------------------------- |
diff --git a/include/acpi/acpi_hest.h b/include/acpi/acpi_hest.h deleted file mode 100644 index 63194d03cb2d..000000000000 --- a/include/acpi/acpi_hest.h +++ /dev/null | |||
@@ -1,12 +0,0 @@ | |||
1 | #ifndef __ACPI_HEST_H | ||
2 | #define __ACPI_HEST_H | ||
3 | |||
4 | #include <linux/pci.h> | ||
5 | |||
6 | #ifdef CONFIG_ACPI | ||
7 | extern int acpi_hest_firmware_first_pci(struct pci_dev *pci); | ||
8 | #else | ||
9 | static inline int acpi_hest_firmware_first_pci(struct pci_dev *pci) { return 0; } | ||
10 | #endif | ||
11 | |||
12 | #endif | ||
diff --git a/include/acpi/apei.h b/include/acpi/apei.h new file mode 100644 index 000000000000..b3365025ff8d --- /dev/null +++ b/include/acpi/apei.h | |||
@@ -0,0 +1,34 @@ | |||
1 | /* | ||
2 | * apei.h - ACPI Platform Error Interface | ||
3 | */ | ||
4 | |||
5 | #ifndef ACPI_APEI_H | ||
6 | #define ACPI_APEI_H | ||
7 | |||
8 | #include <linux/acpi.h> | ||
9 | #include <linux/cper.h> | ||
10 | #include <asm/ioctls.h> | ||
11 | |||
12 | #define APEI_ERST_INVALID_RECORD_ID 0xffffffffffffffffULL | ||
13 | |||
14 | #define APEI_ERST_CLEAR_RECORD _IOW('E', 1, u64) | ||
15 | #define APEI_ERST_GET_RECORD_COUNT _IOR('E', 2, u32) | ||
16 | |||
17 | #ifdef __KERNEL__ | ||
18 | |||
19 | extern int hest_disable; | ||
20 | extern int erst_disable; | ||
21 | |||
22 | typedef int (*apei_hest_func_t)(struct acpi_hest_header *hest_hdr, void *data); | ||
23 | int apei_hest_parse(apei_hest_func_t func, void *data); | ||
24 | |||
25 | int erst_write(const struct cper_record_header *record); | ||
26 | ssize_t erst_get_record_count(void); | ||
27 | int erst_get_next_record_id(u64 *record_id); | ||
28 | ssize_t erst_read(u64 record_id, struct cper_record_header *record, | ||
29 | size_t buflen); | ||
30 | ssize_t erst_read_next(struct cper_record_header *record, size_t buflen); | ||
31 | int erst_clear(u64 record_id); | ||
32 | |||
33 | #endif | ||
34 | #endif | ||
diff --git a/include/acpi/atomicio.h b/include/acpi/atomicio.h new file mode 100644 index 000000000000..8b9fb4b0b9ce --- /dev/null +++ b/include/acpi/atomicio.h | |||
@@ -0,0 +1,10 @@ | |||
1 | #ifndef ACPI_ATOMIC_IO_H | ||
2 | #define ACPI_ATOMIC_IO_H | ||
3 | |||
4 | int acpi_pre_map_gar(struct acpi_generic_address *reg); | ||
5 | int acpi_post_unmap_gar(struct acpi_generic_address *reg); | ||
6 | |||
7 | int acpi_atomic_read(u64 *val, struct acpi_generic_address *reg); | ||
8 | int acpi_atomic_write(u64 val, struct acpi_generic_address *reg); | ||
9 | |||
10 | #endif | ||
diff --git a/include/acpi/hed.h b/include/acpi/hed.h new file mode 100644 index 000000000000..46e1249b70cc --- /dev/null +++ b/include/acpi/hed.h | |||
@@ -0,0 +1,18 @@ | |||
1 | /* | ||
2 | * hed.h - ACPI Hardware Error Device | ||
3 | * | ||
4 | * Copyright (C) 2009, Intel Corp. | ||
5 | * Author: Huang Ying <ying.huang@intel.com> | ||
6 | * | ||
7 | * This file is released under the GPLv2. | ||
8 | */ | ||
9 | |||
10 | #ifndef ACPI_HED_H | ||
11 | #define ACPI_HED_H | ||
12 | |||
13 | #include <linux/notifier.h> | ||
14 | |||
15 | int register_acpi_hed_notifier(struct notifier_block *nb); | ||
16 | void unregister_acpi_hed_notifier(struct notifier_block *nb); | ||
17 | |||
18 | #endif | ||
diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 86825ddbe14e..da565a48240e 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h | |||
@@ -52,17 +52,6 @@ struct acpi_power_register { | |||
52 | u64 address; | 52 | u64 address; |
53 | } __attribute__ ((packed)); | 53 | } __attribute__ ((packed)); |
54 | 54 | ||
55 | struct acpi_processor_cx_policy { | ||
56 | u32 count; | ||
57 | struct acpi_processor_cx *state; | ||
58 | struct { | ||
59 | u32 time; | ||
60 | u32 ticks; | ||
61 | u32 count; | ||
62 | u32 bm; | ||
63 | } threshold; | ||
64 | }; | ||
65 | |||
66 | struct acpi_processor_cx { | 55 | struct acpi_processor_cx { |
67 | u8 valid; | 56 | u8 valid; |
68 | u8 type; | 57 | u8 type; |
@@ -74,8 +63,6 @@ struct acpi_processor_cx { | |||
74 | u32 power; | 63 | u32 power; |
75 | u32 usage; | 64 | u32 usage; |
76 | u64 time; | 65 | u64 time; |
77 | struct acpi_processor_cx_policy promotion; | ||
78 | struct acpi_processor_cx_policy demotion; | ||
79 | char desc[ACPI_CX_DESC_LEN]; | 66 | char desc[ACPI_CX_DESC_LEN]; |
80 | }; | 67 | }; |
81 | 68 | ||
diff --git a/include/acpi/video.h b/include/acpi/video.h index cf7be3dd157b..551793c9b6e8 100644 --- a/include/acpi/video.h +++ b/include/acpi/video.h | |||
@@ -1,12 +1,28 @@ | |||
1 | #ifndef __ACPI_VIDEO_H | 1 | #ifndef __ACPI_VIDEO_H |
2 | #define __ACPI_VIDEO_H | 2 | #define __ACPI_VIDEO_H |
3 | 3 | ||
4 | #define ACPI_VIDEO_DISPLAY_CRT 1 | ||
5 | #define ACPI_VIDEO_DISPLAY_TV 2 | ||
6 | #define ACPI_VIDEO_DISPLAY_DVI 3 | ||
7 | #define ACPI_VIDEO_DISPLAY_LCD 4 | ||
8 | |||
9 | #define ACPI_VIDEO_DISPLAY_LEGACY_MONITOR 0x0100 | ||
10 | #define ACPI_VIDEO_DISPLAY_LEGACY_PANEL 0x0110 | ||
11 | #define ACPI_VIDEO_DISPLAY_LEGACY_TV 0x0200 | ||
12 | |||
4 | #if (defined CONFIG_ACPI_VIDEO || defined CONFIG_ACPI_VIDEO_MODULE) | 13 | #if (defined CONFIG_ACPI_VIDEO || defined CONFIG_ACPI_VIDEO_MODULE) |
5 | extern int acpi_video_register(void); | 14 | extern int acpi_video_register(void); |
6 | extern void acpi_video_unregister(void); | 15 | extern void acpi_video_unregister(void); |
16 | extern int acpi_video_get_edid(struct acpi_device *device, int type, | ||
17 | int device_id, void **edid); | ||
7 | #else | 18 | #else |
8 | static inline int acpi_video_register(void) { return 0; } | 19 | static inline int acpi_video_register(void) { return 0; } |
9 | static inline void acpi_video_unregister(void) { return; } | 20 | static inline void acpi_video_unregister(void) { return; } |
21 | static inline int acpi_video_get_edid(struct acpi_device *device, int type, | ||
22 | int device_id, void **edid) | ||
23 | { | ||
24 | return -ENODEV; | ||
25 | } | ||
10 | #endif | 26 | #endif |
11 | 27 | ||
12 | #endif | 28 | #endif |
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 2c60f1f70b38..224a38c960d4 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -254,7 +254,6 @@ int acpi_resources_are_enforced(void); | |||
254 | void __init acpi_no_s4_hw_signature(void); | 254 | void __init acpi_no_s4_hw_signature(void); |
255 | void __init acpi_old_suspend_ordering(void); | 255 | void __init acpi_old_suspend_ordering(void); |
256 | void __init acpi_s4_no_nvs(void); | 256 | void __init acpi_s4_no_nvs(void); |
257 | void __init acpi_set_sci_en_on_resume(void); | ||
258 | #endif /* CONFIG_PM_SLEEP */ | 257 | #endif /* CONFIG_PM_SLEEP */ |
259 | 258 | ||
260 | struct acpi_osc_context { | 259 | struct acpi_osc_context { |
diff --git a/include/linux/amba/pl330.h b/include/linux/amba/pl330.h new file mode 100644 index 000000000000..cbee7de7dd36 --- /dev/null +++ b/include/linux/amba/pl330.h | |||
@@ -0,0 +1,45 @@ | |||
1 | /* linux/include/linux/amba/pl330.h | ||
2 | * | ||
3 | * Copyright (C) 2010 Samsung Electronics Co. Ltd. | ||
4 | * Jaswinder Singh <jassi.brar@samsung.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #ifndef __AMBA_PL330_H_ | ||
13 | #define __AMBA_PL330_H_ | ||
14 | |||
15 | #include <asm/hardware/pl330.h> | ||
16 | |||
17 | struct dma_pl330_peri { | ||
18 | /* | ||
19 | * Peri_Req i/f of the DMAC that is | ||
20 | * peripheral could be reached from. | ||
21 | */ | ||
22 | u8 peri_id; /* {0, 31} */ | ||
23 | enum pl330_reqtype rqtype; | ||
24 | |||
25 | /* For M->D and D->M Channels */ | ||
26 | int burst_sz; /* in power of 2 */ | ||
27 | dma_addr_t fifo_addr; | ||
28 | }; | ||
29 | |||
30 | struct dma_pl330_platdata { | ||
31 | /* | ||
32 | * Number of valid peripherals connected to DMAC. | ||
33 | * This may be different from the value read from | ||
34 | * CR0, as the PL330 implementation might have 'holes' | ||
35 | * in the peri list or the peri could also be reached | ||
36 | * from another DMAC which the platform prefers. | ||
37 | */ | ||
38 | u8 nr_valid_peri; | ||
39 | /* Array of valid peripherals */ | ||
40 | struct dma_pl330_peri *peri; | ||
41 | /* Bytes to allocate for MC buffer */ | ||
42 | unsigned mcbuf_sz; | ||
43 | }; | ||
44 | |||
45 | #endif /* __AMBA_PL330_H_ */ | ||
diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h index 6fb2720882fc..daf8c480c786 100644 --- a/include/linux/bitmap.h +++ b/include/linux/bitmap.h | |||
@@ -141,7 +141,6 @@ extern int bitmap_find_free_region(unsigned long *bitmap, int bits, int order); | |||
141 | extern void bitmap_release_region(unsigned long *bitmap, int pos, int order); | 141 | extern void bitmap_release_region(unsigned long *bitmap, int pos, int order); |
142 | extern int bitmap_allocate_region(unsigned long *bitmap, int pos, int order); | 142 | extern int bitmap_allocate_region(unsigned long *bitmap, int pos, int order); |
143 | extern void bitmap_copy_le(void *dst, const unsigned long *src, int nbits); | 143 | extern void bitmap_copy_le(void *dst, const unsigned long *src, int nbits); |
144 | extern int bitmap_ord_to_pos(const unsigned long *bitmap, int n, int bits); | ||
145 | 144 | ||
146 | #define BITMAP_LAST_WORD_MASK(nbits) \ | 145 | #define BITMAP_LAST_WORD_MASK(nbits) \ |
147 | ( \ | 146 | ( \ |
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h index 16ed0284d780..1b9ba193b789 100644 --- a/include/linux/buffer_head.h +++ b/include/linux/buffer_head.h | |||
@@ -203,6 +203,9 @@ int block_write_full_page_endio(struct page *page, get_block_t *get_block, | |||
203 | int block_read_full_page(struct page*, get_block_t*); | 203 | int block_read_full_page(struct page*, get_block_t*); |
204 | int block_is_partially_uptodate(struct page *page, read_descriptor_t *desc, | 204 | int block_is_partially_uptodate(struct page *page, read_descriptor_t *desc, |
205 | unsigned long from); | 205 | unsigned long from); |
206 | int block_write_begin_newtrunc(struct file *, struct address_space *, | ||
207 | loff_t, unsigned, unsigned, | ||
208 | struct page **, void **, get_block_t*); | ||
206 | int block_write_begin(struct file *, struct address_space *, | 209 | int block_write_begin(struct file *, struct address_space *, |
207 | loff_t, unsigned, unsigned, | 210 | loff_t, unsigned, unsigned, |
208 | struct page **, void **, get_block_t*); | 211 | struct page **, void **, get_block_t*); |
@@ -214,6 +217,9 @@ int generic_write_end(struct file *, struct address_space *, | |||
214 | struct page *, void *); | 217 | struct page *, void *); |
215 | void page_zero_new_buffers(struct page *page, unsigned from, unsigned to); | 218 | void page_zero_new_buffers(struct page *page, unsigned from, unsigned to); |
216 | int block_prepare_write(struct page*, unsigned, unsigned, get_block_t*); | 219 | int block_prepare_write(struct page*, unsigned, unsigned, get_block_t*); |
220 | int cont_write_begin_newtrunc(struct file *, struct address_space *, loff_t, | ||
221 | unsigned, unsigned, struct page **, void **, | ||
222 | get_block_t *, loff_t *); | ||
217 | int cont_write_begin(struct file *, struct address_space *, loff_t, | 223 | int cont_write_begin(struct file *, struct address_space *, loff_t, |
218 | unsigned, unsigned, struct page **, void **, | 224 | unsigned, unsigned, struct page **, void **, |
219 | get_block_t *, loff_t *); | 225 | get_block_t *, loff_t *); |
@@ -224,7 +230,10 @@ int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, | |||
224 | void block_sync_page(struct page *); | 230 | void block_sync_page(struct page *); |
225 | sector_t generic_block_bmap(struct address_space *, sector_t, get_block_t *); | 231 | sector_t generic_block_bmap(struct address_space *, sector_t, get_block_t *); |
226 | int block_truncate_page(struct address_space *, loff_t, get_block_t *); | 232 | int block_truncate_page(struct address_space *, loff_t, get_block_t *); |
227 | int file_fsync(struct file *, struct dentry *, int); | 233 | int file_fsync(struct file *, int); |
234 | int nobh_write_begin_newtrunc(struct file *, struct address_space *, | ||
235 | loff_t, unsigned, unsigned, | ||
236 | struct page **, void **, get_block_t*); | ||
228 | int nobh_write_begin(struct file *, struct address_space *, | 237 | int nobh_write_begin(struct file *, struct address_space *, |
229 | loff_t, unsigned, unsigned, | 238 | loff_t, unsigned, unsigned, |
230 | struct page **, void **, get_block_t*); | 239 | struct page **, void **, get_block_t*); |
diff --git a/include/linux/completion.h b/include/linux/completion.h index 4a6b604ef7e4..51e3145196f6 100644 --- a/include/linux/completion.h +++ b/include/linux/completion.h | |||
@@ -83,6 +83,8 @@ extern unsigned long wait_for_completion_timeout(struct completion *x, | |||
83 | unsigned long timeout); | 83 | unsigned long timeout); |
84 | extern unsigned long wait_for_completion_interruptible_timeout( | 84 | extern unsigned long wait_for_completion_interruptible_timeout( |
85 | struct completion *x, unsigned long timeout); | 85 | struct completion *x, unsigned long timeout); |
86 | extern unsigned long wait_for_completion_killable_timeout( | ||
87 | struct completion *x, unsigned long timeout); | ||
86 | extern bool try_wait_for_completion(struct completion *x); | 88 | extern bool try_wait_for_completion(struct completion *x); |
87 | extern bool completion_done(struct completion *x); | 89 | extern bool completion_done(struct completion *x); |
88 | 90 | ||
diff --git a/include/linux/cper.h b/include/linux/cper.h new file mode 100644 index 000000000000..4b38f905b705 --- /dev/null +++ b/include/linux/cper.h | |||
@@ -0,0 +1,314 @@ | |||
1 | /* | ||
2 | * UEFI Common Platform Error Record | ||
3 | * | ||
4 | * Copyright (C) 2010, Intel Corp. | ||
5 | * Author: Huang Ying <ying.huang@intel.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License version | ||
9 | * 2 as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #ifndef LINUX_CPER_H | ||
22 | #define LINUX_CPER_H | ||
23 | |||
24 | #include <linux/uuid.h> | ||
25 | |||
26 | /* CPER record signature and the size */ | ||
27 | #define CPER_SIG_RECORD "CPER" | ||
28 | #define CPER_SIG_SIZE 4 | ||
29 | /* Used in signature_end field in struct cper_record_header */ | ||
30 | #define CPER_SIG_END 0xffffffff | ||
31 | |||
32 | /* | ||
33 | * CPER record header revision, used in revision field in struct | ||
34 | * cper_record_header | ||
35 | */ | ||
36 | #define CPER_RECORD_REV 0x0100 | ||
37 | |||
38 | /* | ||
39 | * Severity difinition for error_severity in struct cper_record_header | ||
40 | * and section_severity in struct cper_section_descriptor | ||
41 | */ | ||
42 | #define CPER_SER_RECOVERABLE 0x0 | ||
43 | #define CPER_SER_FATAL 0x1 | ||
44 | #define CPER_SER_CORRECTED 0x2 | ||
45 | #define CPER_SER_INFORMATIONAL 0x3 | ||
46 | |||
47 | /* | ||
48 | * Validation bits difinition for validation_bits in struct | ||
49 | * cper_record_header. If set, corresponding fields in struct | ||
50 | * cper_record_header contain valid information. | ||
51 | * | ||
52 | * corresponds platform_id | ||
53 | */ | ||
54 | #define CPER_VALID_PLATFORM_ID 0x0001 | ||
55 | /* corresponds timestamp */ | ||
56 | #define CPER_VALID_TIMESTAMP 0x0002 | ||
57 | /* corresponds partition_id */ | ||
58 | #define CPER_VALID_PARTITION_ID 0x0004 | ||
59 | |||
60 | /* | ||
61 | * Notification type used to generate error record, used in | ||
62 | * notification_type in struct cper_record_header | ||
63 | * | ||
64 | * Corrected Machine Check | ||
65 | */ | ||
66 | #define CPER_NOTIFY_CMC \ | ||
67 | UUID_LE(0x2DCE8BB1, 0xBDD7, 0x450e, 0xB9, 0xAD, 0x9C, 0xF4, \ | ||
68 | 0xEB, 0xD4, 0xF8, 0x90) | ||
69 | /* Corrected Platform Error */ | ||
70 | #define CPER_NOTIFY_CPE \ | ||
71 | UUID_LE(0x4E292F96, 0xD843, 0x4a55, 0xA8, 0xC2, 0xD4, 0x81, \ | ||
72 | 0xF2, 0x7E, 0xBE, 0xEE) | ||
73 | /* Machine Check Exception */ | ||
74 | #define CPER_NOTIFY_MCE \ | ||
75 | UUID_LE(0xE8F56FFE, 0x919C, 0x4cc5, 0xBA, 0x88, 0x65, 0xAB, \ | ||
76 | 0xE1, 0x49, 0x13, 0xBB) | ||
77 | /* PCI Express Error */ | ||
78 | #define CPER_NOTIFY_PCIE \ | ||
79 | UUID_LE(0xCF93C01F, 0x1A16, 0x4dfc, 0xB8, 0xBC, 0x9C, 0x4D, \ | ||
80 | 0xAF, 0x67, 0xC1, 0x04) | ||
81 | /* INIT Record (for IPF) */ | ||
82 | #define CPER_NOTIFY_INIT \ | ||
83 | UUID_LE(0xCC5263E8, 0x9308, 0x454a, 0x89, 0xD0, 0x34, 0x0B, \ | ||
84 | 0xD3, 0x9B, 0xC9, 0x8E) | ||
85 | /* Non-Maskable Interrupt */ | ||
86 | #define CPER_NOTIFY_NMI \ | ||
87 | UUID_LE(0x5BAD89FF, 0xB7E6, 0x42c9, 0x81, 0x4A, 0xCF, 0x24, \ | ||
88 | 0x85, 0xD6, 0xE9, 0x8A) | ||
89 | /* BOOT Error Record */ | ||
90 | #define CPER_NOTIFY_BOOT \ | ||
91 | UUID_LE(0x3D61A466, 0xAB40, 0x409a, 0xA6, 0x98, 0xF3, 0x62, \ | ||
92 | 0xD4, 0x64, 0xB3, 0x8F) | ||
93 | /* DMA Remapping Error */ | ||
94 | #define CPER_NOTIFY_DMAR \ | ||
95 | UUID_LE(0x667DD791, 0xC6B3, 0x4c27, 0x8A, 0x6B, 0x0F, 0x8E, \ | ||
96 | 0x72, 0x2D, 0xEB, 0x41) | ||
97 | |||
98 | /* | ||
99 | * Flags bits definitions for flags in struct cper_record_header | ||
100 | * If set, the error has been recovered | ||
101 | */ | ||
102 | #define CPER_HW_ERROR_FLAGS_RECOVERED 0x1 | ||
103 | /* If set, the error is for previous boot */ | ||
104 | #define CPER_HW_ERROR_FLAGS_PREVERR 0x2 | ||
105 | /* If set, the error is injected for testing */ | ||
106 | #define CPER_HW_ERROR_FLAGS_SIMULATED 0x4 | ||
107 | |||
108 | /* | ||
109 | * CPER section header revision, used in revision field in struct | ||
110 | * cper_section_descriptor | ||
111 | */ | ||
112 | #define CPER_SEC_REV 0x0100 | ||
113 | |||
114 | /* | ||
115 | * Validation bits difinition for validation_bits in struct | ||
116 | * cper_section_descriptor. If set, corresponding fields in struct | ||
117 | * cper_section_descriptor contain valid information. | ||
118 | * | ||
119 | * corresponds fru_id | ||
120 | */ | ||
121 | #define CPER_SEC_VALID_FRU_ID 0x1 | ||
122 | /* corresponds fru_text */ | ||
123 | #define CPER_SEC_VALID_FRU_TEXT 0x2 | ||
124 | |||
125 | /* | ||
126 | * Flags bits definitions for flags in struct cper_section_descriptor | ||
127 | * | ||
128 | * If set, the section is associated with the error condition | ||
129 | * directly, and should be focused on | ||
130 | */ | ||
131 | #define CPER_SEC_PRIMARY 0x0001 | ||
132 | /* | ||
133 | * If set, the error was not contained within the processor or memory | ||
134 | * hierarchy and the error may have propagated to persistent storage | ||
135 | * or network | ||
136 | */ | ||
137 | #define CPER_SEC_CONTAINMENT_WARNING 0x0002 | ||
138 | /* If set, the component must be re-initialized or re-enabled prior to use */ | ||
139 | #define CPER_SEC_RESET 0x0004 | ||
140 | /* If set, Linux may choose to discontinue use of the resource */ | ||
141 | #define CPER_SEC_ERROR_THRESHOLD_EXCEEDED 0x0008 | ||
142 | /* | ||
143 | * If set, resource could not be queried for error information due to | ||
144 | * conflicts with other system software or resources. Some fields of | ||
145 | * the section will be invalid | ||
146 | */ | ||
147 | #define CPER_SEC_RESOURCE_NOT_ACCESSIBLE 0x0010 | ||
148 | /* | ||
149 | * If set, action has been taken to ensure error containment (such as | ||
150 | * poisoning data), but the error has not been fully corrected and the | ||
151 | * data has not been consumed. Linux may choose to take further | ||
152 | * corrective action before the data is consumed | ||
153 | */ | ||
154 | #define CPER_SEC_LATENT_ERROR 0x0020 | ||
155 | |||
156 | /* | ||
157 | * Section type definitions, used in section_type field in struct | ||
158 | * cper_section_descriptor | ||
159 | * | ||
160 | * Processor Generic | ||
161 | */ | ||
162 | #define CPER_SEC_PROC_GENERIC \ | ||
163 | UUID_LE(0x9876CCAD, 0x47B4, 0x4bdb, 0xB6, 0x5E, 0x16, 0xF1, \ | ||
164 | 0x93, 0xC4, 0xF3, 0xDB) | ||
165 | /* Processor Specific: X86/X86_64 */ | ||
166 | #define CPER_SEC_PROC_IA \ | ||
167 | UUID_LE(0xDC3EA0B0, 0xA144, 0x4797, 0xB9, 0x5B, 0x53, 0xFA, \ | ||
168 | 0x24, 0x2B, 0x6E, 0x1D) | ||
169 | /* Processor Specific: IA64 */ | ||
170 | #define CPER_SEC_PROC_IPF \ | ||
171 | UUID_LE(0xE429FAF1, 0x3CB7, 0x11D4, 0x0B, 0xCA, 0x07, 0x00, \ | ||
172 | 0x80, 0xC7, 0x3C, 0x88, 0x81) | ||
173 | /* Platform Memory */ | ||
174 | #define CPER_SEC_PLATFORM_MEM \ | ||
175 | UUID_LE(0xA5BC1114, 0x6F64, 0x4EDE, 0xB8, 0x63, 0x3E, 0x83, \ | ||
176 | 0xED, 0x7C, 0x83, 0xB1) | ||
177 | #define CPER_SEC_PCIE \ | ||
178 | UUID_LE(0xD995E954, 0xBBC1, 0x430F, 0xAD, 0x91, 0xB4, 0x4D, \ | ||
179 | 0xCB, 0x3C, 0x6F, 0x35) | ||
180 | /* Firmware Error Record Reference */ | ||
181 | #define CPER_SEC_FW_ERR_REC_REF \ | ||
182 | UUID_LE(0x81212A96, 0x09ED, 0x4996, 0x94, 0x71, 0x8D, 0x72, \ | ||
183 | 0x9C, 0x8E, 0x69, 0xED) | ||
184 | /* PCI/PCI-X Bus */ | ||
185 | #define CPER_SEC_PCI_X_BUS \ | ||
186 | UUID_LE(0xC5753963, 0x3B84, 0x4095, 0xBF, 0x78, 0xED, 0xDA, \ | ||
187 | 0xD3, 0xF9, 0xC9, 0xDD) | ||
188 | /* PCI Component/Device */ | ||
189 | #define CPER_SEC_PCI_DEV \ | ||
190 | UUID_LE(0xEB5E4685, 0xCA66, 0x4769, 0xB6, 0xA2, 0x26, 0x06, \ | ||
191 | 0x8B, 0x00, 0x13, 0x26) | ||
192 | #define CPER_SEC_DMAR_GENERIC \ | ||
193 | UUID_LE(0x5B51FEF7, 0xC79D, 0x4434, 0x8F, 0x1B, 0xAA, 0x62, \ | ||
194 | 0xDE, 0x3E, 0x2C, 0x64) | ||
195 | /* Intel VT for Directed I/O specific DMAr */ | ||
196 | #define CPER_SEC_DMAR_VT \ | ||
197 | UUID_LE(0x71761D37, 0x32B2, 0x45cd, 0xA7, 0xD0, 0xB0, 0xFE, \ | ||
198 | 0xDD, 0x93, 0xE8, 0xCF) | ||
199 | /* IOMMU specific DMAr */ | ||
200 | #define CPER_SEC_DMAR_IOMMU \ | ||
201 | UUID_LE(0x036F84E1, 0x7F37, 0x428c, 0xA7, 0x9E, 0x57, 0x5F, \ | ||
202 | 0xDF, 0xAA, 0x84, 0xEC) | ||
203 | |||
204 | /* | ||
205 | * All tables and structs must be byte-packed to match CPER | ||
206 | * specification, since the tables are provided by the system BIOS | ||
207 | */ | ||
208 | #pragma pack(1) | ||
209 | |||
210 | struct cper_record_header { | ||
211 | char signature[CPER_SIG_SIZE]; /* must be CPER_SIG_RECORD */ | ||
212 | __u16 revision; /* must be CPER_RECORD_REV */ | ||
213 | __u32 signature_end; /* must be CPER_SIG_END */ | ||
214 | __u16 section_count; | ||
215 | __u32 error_severity; | ||
216 | __u32 validation_bits; | ||
217 | __u32 record_length; | ||
218 | __u64 timestamp; | ||
219 | uuid_le platform_id; | ||
220 | uuid_le partition_id; | ||
221 | uuid_le creator_id; | ||
222 | uuid_le notification_type; | ||
223 | __u64 record_id; | ||
224 | __u32 flags; | ||
225 | __u64 persistence_information; | ||
226 | __u8 reserved[12]; /* must be zero */ | ||
227 | }; | ||
228 | |||
229 | struct cper_section_descriptor { | ||
230 | __u32 section_offset; /* Offset in bytes of the | ||
231 | * section body from the base | ||
232 | * of the record header */ | ||
233 | __u32 section_length; | ||
234 | __u16 revision; /* must be CPER_RECORD_REV */ | ||
235 | __u8 validation_bits; | ||
236 | __u8 reserved; /* must be zero */ | ||
237 | __u32 flags; | ||
238 | uuid_le section_type; | ||
239 | uuid_le fru_id; | ||
240 | __u32 section_severity; | ||
241 | __u8 fru_text[20]; | ||
242 | }; | ||
243 | |||
244 | /* Generic Processor Error Section */ | ||
245 | struct cper_sec_proc_generic { | ||
246 | __u64 validation_bits; | ||
247 | __u8 proc_type; | ||
248 | __u8 proc_isa; | ||
249 | __u8 proc_error_type; | ||
250 | __u8 operation; | ||
251 | __u8 flags; | ||
252 | __u8 level; | ||
253 | __u16 reserved; | ||
254 | __u64 cpu_version; | ||
255 | char cpu_brand[128]; | ||
256 | __u64 proc_id; | ||
257 | __u64 target_addr; | ||
258 | __u64 requestor_id; | ||
259 | __u64 responder_id; | ||
260 | __u64 ip; | ||
261 | }; | ||
262 | |||
263 | /* IA32/X64 Processor Error Section */ | ||
264 | struct cper_sec_proc_ia { | ||
265 | __u64 validation_bits; | ||
266 | __u8 lapic_id; | ||
267 | __u8 cpuid[48]; | ||
268 | }; | ||
269 | |||
270 | /* IA32/X64 Processor Error Infomation Structure */ | ||
271 | struct cper_ia_err_info { | ||
272 | uuid_le err_type; | ||
273 | __u64 validation_bits; | ||
274 | __u64 check_info; | ||
275 | __u64 target_id; | ||
276 | __u64 requestor_id; | ||
277 | __u64 responder_id; | ||
278 | __u64 ip; | ||
279 | }; | ||
280 | |||
281 | /* IA32/X64 Processor Context Information Structure */ | ||
282 | struct cper_ia_proc_ctx { | ||
283 | __u16 reg_ctx_type; | ||
284 | __u16 reg_arr_size; | ||
285 | __u32 msr_addr; | ||
286 | __u64 mm_reg_addr; | ||
287 | }; | ||
288 | |||
289 | /* Memory Error Section */ | ||
290 | struct cper_sec_mem_err { | ||
291 | __u64 validation_bits; | ||
292 | __u64 error_status; | ||
293 | __u64 physical_addr; | ||
294 | __u64 physical_addr_mask; | ||
295 | __u16 node; | ||
296 | __u16 card; | ||
297 | __u16 module; | ||
298 | __u16 bank; | ||
299 | __u16 device; | ||
300 | __u16 row; | ||
301 | __u16 column; | ||
302 | __u16 bit_pos; | ||
303 | __u64 requestor_id; | ||
304 | __u64 responder_id; | ||
305 | __u64 target_id; | ||
306 | __u8 error_type; | ||
307 | }; | ||
308 | |||
309 | /* Reset to default packing */ | ||
310 | #pragma pack() | ||
311 | |||
312 | u64 cper_next_record_id(void); | ||
313 | |||
314 | #endif | ||
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index dcf77fa826b5..55215cce5005 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h | |||
@@ -125,6 +125,7 @@ struct cpuidle_driver { | |||
125 | #ifdef CONFIG_CPU_IDLE | 125 | #ifdef CONFIG_CPU_IDLE |
126 | 126 | ||
127 | extern int cpuidle_register_driver(struct cpuidle_driver *drv); | 127 | extern int cpuidle_register_driver(struct cpuidle_driver *drv); |
128 | struct cpuidle_driver *cpuidle_get_driver(void); | ||
128 | extern void cpuidle_unregister_driver(struct cpuidle_driver *drv); | 129 | extern void cpuidle_unregister_driver(struct cpuidle_driver *drv); |
129 | extern int cpuidle_register_device(struct cpuidle_device *dev); | 130 | extern int cpuidle_register_device(struct cpuidle_device *dev); |
130 | extern void cpuidle_unregister_device(struct cpuidle_device *dev); | 131 | extern void cpuidle_unregister_device(struct cpuidle_device *dev); |
@@ -137,16 +138,17 @@ extern void cpuidle_disable_device(struct cpuidle_device *dev); | |||
137 | #else | 138 | #else |
138 | 139 | ||
139 | static inline int cpuidle_register_driver(struct cpuidle_driver *drv) | 140 | static inline int cpuidle_register_driver(struct cpuidle_driver *drv) |
140 | {return 0;} | 141 | {return -ENODEV; } |
142 | static inline struct cpuidle_driver *cpuidle_get_driver(void) {return NULL; } | ||
141 | static inline void cpuidle_unregister_driver(struct cpuidle_driver *drv) { } | 143 | static inline void cpuidle_unregister_driver(struct cpuidle_driver *drv) { } |
142 | static inline int cpuidle_register_device(struct cpuidle_device *dev) | 144 | static inline int cpuidle_register_device(struct cpuidle_device *dev) |
143 | {return 0;} | 145 | {return -ENODEV; } |
144 | static inline void cpuidle_unregister_device(struct cpuidle_device *dev) { } | 146 | static inline void cpuidle_unregister_device(struct cpuidle_device *dev) { } |
145 | 147 | ||
146 | static inline void cpuidle_pause_and_lock(void) { } | 148 | static inline void cpuidle_pause_and_lock(void) { } |
147 | static inline void cpuidle_resume_and_unlock(void) { } | 149 | static inline void cpuidle_resume_and_unlock(void) { } |
148 | static inline int cpuidle_enable_device(struct cpuidle_device *dev) | 150 | static inline int cpuidle_enable_device(struct cpuidle_device *dev) |
149 | {return 0;} | 151 | {return -ENODEV; } |
150 | static inline void cpuidle_disable_device(struct cpuidle_device *dev) { } | 152 | static inline void cpuidle_disable_device(struct cpuidle_device *dev) { } |
151 | 153 | ||
152 | #endif | 154 | #endif |
diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h index fc1b930f246c..e7d9b20ddc5b 100644 --- a/include/linux/debugfs.h +++ b/include/linux/debugfs.h | |||
@@ -63,6 +63,8 @@ struct dentry *debugfs_create_x16(const char *name, mode_t mode, | |||
63 | struct dentry *parent, u16 *value); | 63 | struct dentry *parent, u16 *value); |
64 | struct dentry *debugfs_create_x32(const char *name, mode_t mode, | 64 | struct dentry *debugfs_create_x32(const char *name, mode_t mode, |
65 | struct dentry *parent, u32 *value); | 65 | struct dentry *parent, u32 *value); |
66 | struct dentry *debugfs_create_x64(const char *name, mode_t mode, | ||
67 | struct dentry *parent, u64 *value); | ||
66 | struct dentry *debugfs_create_size_t(const char *name, mode_t mode, | 68 | struct dentry *debugfs_create_size_t(const char *name, mode_t mode, |
67 | struct dentry *parent, size_t *value); | 69 | struct dentry *parent, size_t *value); |
68 | struct dentry *debugfs_create_bool(const char *name, mode_t mode, | 70 | struct dentry *debugfs_create_bool(const char *name, mode_t mode, |
diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h index 5f494b465097..7fc62d4550b2 100644 --- a/include/linux/ext3_fs.h +++ b/include/linux/ext3_fs.h | |||
@@ -868,7 +868,7 @@ extern int ext3_htree_store_dirent(struct file *dir_file, __u32 hash, | |||
868 | extern void ext3_htree_free_dir_info(struct dir_private_info *p); | 868 | extern void ext3_htree_free_dir_info(struct dir_private_info *p); |
869 | 869 | ||
870 | /* fsync.c */ | 870 | /* fsync.c */ |
871 | extern int ext3_sync_file (struct file *, struct dentry *, int); | 871 | extern int ext3_sync_file(struct file *, int); |
872 | 872 | ||
873 | /* hash.c */ | 873 | /* hash.c */ |
874 | extern int ext3fs_dirhash(const char *name, int len, struct | 874 | extern int ext3fs_dirhash(const char *name, int len, struct |
diff --git a/include/linux/fb.h b/include/linux/fb.h index f3793ebc241c..907ace3a64c8 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h | |||
@@ -4,8 +4,6 @@ | |||
4 | #include <linux/types.h> | 4 | #include <linux/types.h> |
5 | #include <linux/i2c.h> | 5 | #include <linux/i2c.h> |
6 | 6 | ||
7 | struct dentry; | ||
8 | |||
9 | /* Definitions of frame buffers */ | 7 | /* Definitions of frame buffers */ |
10 | 8 | ||
11 | #define FB_MAX 32 /* sufficient for now */ | 9 | #define FB_MAX 32 /* sufficient for now */ |
@@ -1017,8 +1015,7 @@ extern void fb_deferred_io_open(struct fb_info *info, | |||
1017 | struct inode *inode, | 1015 | struct inode *inode, |
1018 | struct file *file); | 1016 | struct file *file); |
1019 | extern void fb_deferred_io_cleanup(struct fb_info *info); | 1017 | extern void fb_deferred_io_cleanup(struct fb_info *info); |
1020 | extern int fb_deferred_io_fsync(struct file *file, struct dentry *dentry, | 1018 | extern int fb_deferred_io_fsync(struct file *file, int datasync); |
1021 | int datasync); | ||
1022 | 1019 | ||
1023 | static inline bool fb_be_math(struct fb_info *info) | 1020 | static inline bool fb_be_math(struct fb_info *info) |
1024 | { | 1021 | { |
diff --git a/include/linux/file.h b/include/linux/file.h index 5555508fd517..b1e12970f617 100644 --- a/include/linux/file.h +++ b/include/linux/file.h | |||
@@ -11,7 +11,6 @@ | |||
11 | 11 | ||
12 | struct file; | 12 | struct file; |
13 | 13 | ||
14 | extern void __fput(struct file *); | ||
15 | extern void fput(struct file *); | 14 | extern void fput(struct file *); |
16 | extern void drop_file_write_access(struct file *file); | 15 | extern void drop_file_write_access(struct file *file); |
17 | 16 | ||
diff --git a/include/linux/fs.h b/include/linux/fs.h index 85e823adcd4a..3428393942a6 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -954,6 +954,7 @@ extern spinlock_t files_lock; | |||
954 | #define file_list_unlock() spin_unlock(&files_lock); | 954 | #define file_list_unlock() spin_unlock(&files_lock); |
955 | 955 | ||
956 | #define get_file(x) atomic_long_inc(&(x)->f_count) | 956 | #define get_file(x) atomic_long_inc(&(x)->f_count) |
957 | #define fput_atomic(x) atomic_long_add_unless(&(x)->f_count, -1, 1) | ||
957 | #define file_count(x) atomic_long_read(&(x)->f_count) | 958 | #define file_count(x) atomic_long_read(&(x)->f_count) |
958 | 959 | ||
959 | #ifdef CONFIG_DEBUG_WRITECOUNT | 960 | #ifdef CONFIG_DEBUG_WRITECOUNT |
@@ -1497,7 +1498,7 @@ struct file_operations { | |||
1497 | int (*open) (struct inode *, struct file *); | 1498 | int (*open) (struct inode *, struct file *); |
1498 | int (*flush) (struct file *, fl_owner_t id); | 1499 | int (*flush) (struct file *, fl_owner_t id); |
1499 | int (*release) (struct inode *, struct file *); | 1500 | int (*release) (struct inode *, struct file *); |
1500 | int (*fsync) (struct file *, struct dentry *, int datasync); | 1501 | int (*fsync) (struct file *, int datasync); |
1501 | int (*aio_fsync) (struct kiocb *, int datasync); | 1502 | int (*aio_fsync) (struct kiocb *, int datasync); |
1502 | int (*fasync) (int, struct file *, int); | 1503 | int (*fasync) (int, struct file *, int); |
1503 | int (*lock) (struct file *, int, struct file_lock *); | 1504 | int (*lock) (struct file *, int, struct file_lock *); |
@@ -2212,7 +2213,7 @@ extern int generic_segment_checks(const struct iovec *iov, | |||
2212 | /* fs/block_dev.c */ | 2213 | /* fs/block_dev.c */ |
2213 | extern ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov, | 2214 | extern ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov, |
2214 | unsigned long nr_segs, loff_t pos); | 2215 | unsigned long nr_segs, loff_t pos); |
2215 | extern int blkdev_fsync(struct file *filp, struct dentry *dentry, int datasync); | 2216 | extern int blkdev_fsync(struct file *filp, int datasync); |
2216 | 2217 | ||
2217 | /* fs/splice.c */ | 2218 | /* fs/splice.c */ |
2218 | extern ssize_t generic_file_splice_read(struct file *, loff_t *, | 2219 | extern ssize_t generic_file_splice_read(struct file *, loff_t *, |
@@ -2256,6 +2257,10 @@ typedef void (dio_submit_t)(int rw, struct bio *bio, struct inode *inode, | |||
2256 | loff_t file_offset); | 2257 | loff_t file_offset); |
2257 | void dio_end_io(struct bio *bio, int error); | 2258 | void dio_end_io(struct bio *bio, int error); |
2258 | 2259 | ||
2260 | ssize_t __blockdev_direct_IO_newtrunc(int rw, struct kiocb *iocb, struct inode *inode, | ||
2261 | struct block_device *bdev, const struct iovec *iov, loff_t offset, | ||
2262 | unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io, | ||
2263 | dio_submit_t submit_io, int lock_type); | ||
2259 | ssize_t __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, | 2264 | ssize_t __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, |
2260 | struct block_device *bdev, const struct iovec *iov, loff_t offset, | 2265 | struct block_device *bdev, const struct iovec *iov, loff_t offset, |
2261 | unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io, | 2266 | unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io, |
@@ -2269,6 +2274,24 @@ enum { | |||
2269 | DIO_SKIP_HOLES = 0x02, | 2274 | DIO_SKIP_HOLES = 0x02, |
2270 | }; | 2275 | }; |
2271 | 2276 | ||
2277 | static inline ssize_t blockdev_direct_IO_newtrunc(int rw, struct kiocb *iocb, | ||
2278 | struct inode *inode, struct block_device *bdev, const struct iovec *iov, | ||
2279 | loff_t offset, unsigned long nr_segs, get_block_t get_block, | ||
2280 | dio_iodone_t end_io) | ||
2281 | { | ||
2282 | return __blockdev_direct_IO_newtrunc(rw, iocb, inode, bdev, iov, offset, | ||
2283 | nr_segs, get_block, end_io, NULL, | ||
2284 | DIO_LOCKING | DIO_SKIP_HOLES); | ||
2285 | } | ||
2286 | |||
2287 | static inline ssize_t blockdev_direct_IO_no_locking_newtrunc(int rw, struct kiocb *iocb, | ||
2288 | struct inode *inode, struct block_device *bdev, const struct iovec *iov, | ||
2289 | loff_t offset, unsigned long nr_segs, get_block_t get_block, | ||
2290 | dio_iodone_t end_io) | ||
2291 | { | ||
2292 | return __blockdev_direct_IO_newtrunc(rw, iocb, inode, bdev, iov, offset, | ||
2293 | nr_segs, get_block, end_io, NULL, 0); | ||
2294 | } | ||
2272 | static inline ssize_t blockdev_direct_IO(int rw, struct kiocb *iocb, | 2295 | static inline ssize_t blockdev_direct_IO(int rw, struct kiocb *iocb, |
2273 | struct inode *inode, struct block_device *bdev, const struct iovec *iov, | 2296 | struct inode *inode, struct block_device *bdev, const struct iovec *iov, |
2274 | loff_t offset, unsigned long nr_segs, get_block_t get_block, | 2297 | loff_t offset, unsigned long nr_segs, get_block_t get_block, |
@@ -2341,13 +2364,15 @@ extern int dcache_dir_open(struct inode *, struct file *); | |||
2341 | extern int dcache_dir_close(struct inode *, struct file *); | 2364 | extern int dcache_dir_close(struct inode *, struct file *); |
2342 | extern loff_t dcache_dir_lseek(struct file *, loff_t, int); | 2365 | extern loff_t dcache_dir_lseek(struct file *, loff_t, int); |
2343 | extern int dcache_readdir(struct file *, void *, filldir_t); | 2366 | extern int dcache_readdir(struct file *, void *, filldir_t); |
2367 | extern int simple_setattr(struct dentry *, struct iattr *); | ||
2344 | extern int simple_getattr(struct vfsmount *, struct dentry *, struct kstat *); | 2368 | extern int simple_getattr(struct vfsmount *, struct dentry *, struct kstat *); |
2345 | extern int simple_statfs(struct dentry *, struct kstatfs *); | 2369 | extern int simple_statfs(struct dentry *, struct kstatfs *); |
2346 | extern int simple_link(struct dentry *, struct inode *, struct dentry *); | 2370 | extern int simple_link(struct dentry *, struct inode *, struct dentry *); |
2347 | extern int simple_unlink(struct inode *, struct dentry *); | 2371 | extern int simple_unlink(struct inode *, struct dentry *); |
2348 | extern int simple_rmdir(struct inode *, struct dentry *); | 2372 | extern int simple_rmdir(struct inode *, struct dentry *); |
2349 | extern int simple_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); | 2373 | extern int simple_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); |
2350 | extern int simple_sync_file(struct file *, struct dentry *, int); | 2374 | extern int simple_setsize(struct inode *, loff_t); |
2375 | extern int noop_fsync(struct file *, int); | ||
2351 | extern int simple_empty(struct dentry *); | 2376 | extern int simple_empty(struct dentry *); |
2352 | extern int simple_readpage(struct file *file, struct page *page); | 2377 | extern int simple_readpage(struct file *file, struct page *page); |
2353 | extern int simple_write_begin(struct file *file, struct address_space *mapping, | 2378 | extern int simple_write_begin(struct file *file, struct address_space *mapping, |
@@ -2372,7 +2397,7 @@ extern ssize_t simple_read_from_buffer(void __user *to, size_t count, | |||
2372 | extern ssize_t simple_write_to_buffer(void *to, size_t available, loff_t *ppos, | 2397 | extern ssize_t simple_write_to_buffer(void *to, size_t available, loff_t *ppos, |
2373 | const void __user *from, size_t count); | 2398 | const void __user *from, size_t count); |
2374 | 2399 | ||
2375 | extern int simple_fsync(struct file *, struct dentry *, int); | 2400 | extern int generic_file_fsync(struct file *, int); |
2376 | 2401 | ||
2377 | #ifdef CONFIG_MIGRATION | 2402 | #ifdef CONFIG_MIGRATION |
2378 | extern int buffer_migrate_page(struct address_space *, | 2403 | extern int buffer_migrate_page(struct address_space *, |
@@ -2383,7 +2408,8 @@ extern int buffer_migrate_page(struct address_space *, | |||
2383 | 2408 | ||
2384 | extern int inode_change_ok(const struct inode *, struct iattr *); | 2409 | extern int inode_change_ok(const struct inode *, struct iattr *); |
2385 | extern int inode_newsize_ok(const struct inode *, loff_t offset); | 2410 | extern int inode_newsize_ok(const struct inode *, loff_t offset); |
2386 | extern int __must_check inode_setattr(struct inode *, struct iattr *); | 2411 | extern int __must_check inode_setattr(struct inode *, const struct iattr *); |
2412 | extern void generic_setattr(struct inode *inode, const struct iattr *attr); | ||
2387 | 2413 | ||
2388 | extern void file_update_time(struct file *file); | 2414 | extern void file_update_time(struct file *file); |
2389 | 2415 | ||
diff --git a/include/linux/libata.h b/include/linux/libata.h index ee84e7e12039..3bad2701bfa6 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -386,6 +386,7 @@ enum { | |||
386 | ATA_HORKAGE_1_5_GBPS = (1 << 13), /* force 1.5 Gbps */ | 386 | ATA_HORKAGE_1_5_GBPS = (1 << 13), /* force 1.5 Gbps */ |
387 | ATA_HORKAGE_NOSETXFER = (1 << 14), /* skip SETXFER, SATA only */ | 387 | ATA_HORKAGE_NOSETXFER = (1 << 14), /* skip SETXFER, SATA only */ |
388 | ATA_HORKAGE_BROKEN_FPDMA_AA = (1 << 15), /* skip AA */ | 388 | ATA_HORKAGE_BROKEN_FPDMA_AA = (1 << 15), /* skip AA */ |
389 | ATA_HORKAGE_DUMP_ID = (1 << 16), /* dump IDENTIFY data */ | ||
389 | 390 | ||
390 | /* DMA mask for user DMA control: User visible values; DO NOT | 391 | /* DMA mask for user DMA control: User visible values; DO NOT |
391 | renumber */ | 392 | renumber */ |
@@ -513,7 +514,9 @@ struct ata_ioports { | |||
513 | void __iomem *command_addr; | 514 | void __iomem *command_addr; |
514 | void __iomem *altstatus_addr; | 515 | void __iomem *altstatus_addr; |
515 | void __iomem *ctl_addr; | 516 | void __iomem *ctl_addr; |
517 | #ifdef CONFIG_ATA_BMDMA | ||
516 | void __iomem *bmdma_addr; | 518 | void __iomem *bmdma_addr; |
519 | #endif /* CONFIG_ATA_BMDMA */ | ||
517 | void __iomem *scr_addr; | 520 | void __iomem *scr_addr; |
518 | }; | 521 | }; |
519 | #endif /* CONFIG_ATA_SFF */ | 522 | #endif /* CONFIG_ATA_SFF */ |
@@ -721,8 +724,10 @@ struct ata_port { | |||
721 | u8 ctl; /* cache of ATA control register */ | 724 | u8 ctl; /* cache of ATA control register */ |
722 | u8 last_ctl; /* Cache last written value */ | 725 | u8 last_ctl; /* Cache last written value */ |
723 | struct delayed_work sff_pio_task; | 726 | struct delayed_work sff_pio_task; |
727 | #ifdef CONFIG_ATA_BMDMA | ||
724 | struct ata_bmdma_prd *bmdma_prd; /* BMDMA SG list */ | 728 | struct ata_bmdma_prd *bmdma_prd; /* BMDMA SG list */ |
725 | dma_addr_t bmdma_prd_dma; /* and its DMA mapping */ | 729 | dma_addr_t bmdma_prd_dma; /* and its DMA mapping */ |
730 | #endif /* CONFIG_ATA_BMDMA */ | ||
726 | #endif /* CONFIG_ATA_SFF */ | 731 | #endif /* CONFIG_ATA_SFF */ |
727 | 732 | ||
728 | unsigned int pio_mask; | 733 | unsigned int pio_mask; |
@@ -856,10 +861,12 @@ struct ata_port_operations { | |||
856 | void (*sff_irq_clear)(struct ata_port *); | 861 | void (*sff_irq_clear)(struct ata_port *); |
857 | void (*sff_drain_fifo)(struct ata_queued_cmd *qc); | 862 | void (*sff_drain_fifo)(struct ata_queued_cmd *qc); |
858 | 863 | ||
864 | #ifdef CONFIG_ATA_BMDMA | ||
859 | void (*bmdma_setup)(struct ata_queued_cmd *qc); | 865 | void (*bmdma_setup)(struct ata_queued_cmd *qc); |
860 | void (*bmdma_start)(struct ata_queued_cmd *qc); | 866 | void (*bmdma_start)(struct ata_queued_cmd *qc); |
861 | void (*bmdma_stop)(struct ata_queued_cmd *qc); | 867 | void (*bmdma_stop)(struct ata_queued_cmd *qc); |
862 | u8 (*bmdma_status)(struct ata_port *ap); | 868 | u8 (*bmdma_status)(struct ata_port *ap); |
869 | #endif /* CONFIG_ATA_BMDMA */ | ||
863 | #endif /* CONFIG_ATA_SFF */ | 870 | #endif /* CONFIG_ATA_SFF */ |
864 | 871 | ||
865 | ssize_t (*em_show)(struct ata_port *ap, char *buf); | 872 | ssize_t (*em_show)(struct ata_port *ap, char *buf); |
@@ -1555,7 +1562,6 @@ extern void sata_pmp_error_handler(struct ata_port *ap); | |||
1555 | #ifdef CONFIG_ATA_SFF | 1562 | #ifdef CONFIG_ATA_SFF |
1556 | 1563 | ||
1557 | extern const struct ata_port_operations ata_sff_port_ops; | 1564 | extern const struct ata_port_operations ata_sff_port_ops; |
1558 | extern const struct ata_port_operations ata_bmdma_port_ops; | ||
1559 | extern const struct ata_port_operations ata_bmdma32_port_ops; | 1565 | extern const struct ata_port_operations ata_bmdma32_port_ops; |
1560 | 1566 | ||
1561 | /* PIO only, sg_tablesize and dma_boundary limits can be removed */ | 1567 | /* PIO only, sg_tablesize and dma_boundary limits can be removed */ |
@@ -1564,11 +1570,6 @@ extern const struct ata_port_operations ata_bmdma32_port_ops; | |||
1564 | .sg_tablesize = LIBATA_MAX_PRD, \ | 1570 | .sg_tablesize = LIBATA_MAX_PRD, \ |
1565 | .dma_boundary = ATA_DMA_BOUNDARY | 1571 | .dma_boundary = ATA_DMA_BOUNDARY |
1566 | 1572 | ||
1567 | #define ATA_BMDMA_SHT(drv_name) \ | ||
1568 | ATA_BASE_SHT(drv_name), \ | ||
1569 | .sg_tablesize = LIBATA_MAX_PRD, \ | ||
1570 | .dma_boundary = ATA_DMA_BOUNDARY | ||
1571 | |||
1572 | extern void ata_sff_dev_select(struct ata_port *ap, unsigned int device); | 1573 | extern void ata_sff_dev_select(struct ata_port *ap, unsigned int device); |
1573 | extern u8 ata_sff_check_status(struct ata_port *ap); | 1574 | extern u8 ata_sff_check_status(struct ata_port *ap); |
1574 | extern void ata_sff_pause(struct ata_port *ap); | 1575 | extern void ata_sff_pause(struct ata_port *ap); |
@@ -1593,7 +1594,7 @@ extern int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc, | |||
1593 | extern void ata_sff_queue_pio_task(struct ata_port *ap, unsigned long delay); | 1594 | extern void ata_sff_queue_pio_task(struct ata_port *ap, unsigned long delay); |
1594 | extern unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc); | 1595 | extern unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc); |
1595 | extern bool ata_sff_qc_fill_rtf(struct ata_queued_cmd *qc); | 1596 | extern bool ata_sff_qc_fill_rtf(struct ata_queued_cmd *qc); |
1596 | extern unsigned int ata_sff_host_intr(struct ata_port *ap, | 1597 | extern unsigned int ata_sff_port_intr(struct ata_port *ap, |
1597 | struct ata_queued_cmd *qc); | 1598 | struct ata_queued_cmd *qc); |
1598 | extern irqreturn_t ata_sff_interrupt(int irq, void *dev_instance); | 1599 | extern irqreturn_t ata_sff_interrupt(int irq, void *dev_instance); |
1599 | extern void ata_sff_lost_interrupt(struct ata_port *ap); | 1600 | extern void ata_sff_lost_interrupt(struct ata_port *ap); |
@@ -1625,11 +1626,24 @@ extern int ata_pci_sff_init_one(struct pci_dev *pdev, | |||
1625 | struct scsi_host_template *sht, void *host_priv, int hflags); | 1626 | struct scsi_host_template *sht, void *host_priv, int hflags); |
1626 | #endif /* CONFIG_PCI */ | 1627 | #endif /* CONFIG_PCI */ |
1627 | 1628 | ||
1629 | #ifdef CONFIG_ATA_BMDMA | ||
1630 | |||
1631 | extern const struct ata_port_operations ata_bmdma_port_ops; | ||
1632 | |||
1633 | #define ATA_BMDMA_SHT(drv_name) \ | ||
1634 | ATA_BASE_SHT(drv_name), \ | ||
1635 | .sg_tablesize = LIBATA_MAX_PRD, \ | ||
1636 | .dma_boundary = ATA_DMA_BOUNDARY | ||
1637 | |||
1628 | extern void ata_bmdma_qc_prep(struct ata_queued_cmd *qc); | 1638 | extern void ata_bmdma_qc_prep(struct ata_queued_cmd *qc); |
1629 | extern unsigned int ata_bmdma_qc_issue(struct ata_queued_cmd *qc); | 1639 | extern unsigned int ata_bmdma_qc_issue(struct ata_queued_cmd *qc); |
1630 | extern void ata_bmdma_dumb_qc_prep(struct ata_queued_cmd *qc); | 1640 | extern void ata_bmdma_dumb_qc_prep(struct ata_queued_cmd *qc); |
1641 | extern unsigned int ata_bmdma_port_intr(struct ata_port *ap, | ||
1642 | struct ata_queued_cmd *qc); | ||
1643 | extern irqreturn_t ata_bmdma_interrupt(int irq, void *dev_instance); | ||
1631 | extern void ata_bmdma_error_handler(struct ata_port *ap); | 1644 | extern void ata_bmdma_error_handler(struct ata_port *ap); |
1632 | extern void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc); | 1645 | extern void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc); |
1646 | extern void ata_bmdma_irq_clear(struct ata_port *ap); | ||
1633 | extern void ata_bmdma_setup(struct ata_queued_cmd *qc); | 1647 | extern void ata_bmdma_setup(struct ata_queued_cmd *qc); |
1634 | extern void ata_bmdma_start(struct ata_queued_cmd *qc); | 1648 | extern void ata_bmdma_start(struct ata_queued_cmd *qc); |
1635 | extern void ata_bmdma_stop(struct ata_queued_cmd *qc); | 1649 | extern void ata_bmdma_stop(struct ata_queued_cmd *qc); |
@@ -1640,7 +1654,15 @@ extern int ata_bmdma_port_start32(struct ata_port *ap); | |||
1640 | #ifdef CONFIG_PCI | 1654 | #ifdef CONFIG_PCI |
1641 | extern int ata_pci_bmdma_clear_simplex(struct pci_dev *pdev); | 1655 | extern int ata_pci_bmdma_clear_simplex(struct pci_dev *pdev); |
1642 | extern void ata_pci_bmdma_init(struct ata_host *host); | 1656 | extern void ata_pci_bmdma_init(struct ata_host *host); |
1657 | extern int ata_pci_bmdma_prepare_host(struct pci_dev *pdev, | ||
1658 | const struct ata_port_info * const * ppi, | ||
1659 | struct ata_host **r_host); | ||
1660 | extern int ata_pci_bmdma_init_one(struct pci_dev *pdev, | ||
1661 | const struct ata_port_info * const * ppi, | ||
1662 | struct scsi_host_template *sht, | ||
1663 | void *host_priv, int hflags); | ||
1643 | #endif /* CONFIG_PCI */ | 1664 | #endif /* CONFIG_PCI */ |
1665 | #endif /* CONFIG_ATA_BMDMA */ | ||
1644 | 1666 | ||
1645 | /** | 1667 | /** |
1646 | * ata_sff_busy_wait - Wait for a port status register | 1668 | * ata_sff_busy_wait - Wait for a port status register |
diff --git a/include/linux/nodemask.h b/include/linux/nodemask.h index 8a8f1d09c133..dba35e413371 100644 --- a/include/linux/nodemask.h +++ b/include/linux/nodemask.h | |||
@@ -66,8 +66,6 @@ | |||
66 | * int num_online_nodes() Number of online Nodes | 66 | * int num_online_nodes() Number of online Nodes |
67 | * int num_possible_nodes() Number of all possible Nodes | 67 | * int num_possible_nodes() Number of all possible Nodes |
68 | * | 68 | * |
69 | * int node_random(mask) Random node with set bit in mask | ||
70 | * | ||
71 | * int node_online(node) Is some node online? | 69 | * int node_online(node) Is some node online? |
72 | * int node_possible(node) Is some node possible? | 70 | * int node_possible(node) Is some node possible? |
73 | * | 71 | * |
@@ -432,10 +430,6 @@ static inline void node_set_offline(int nid) | |||
432 | node_clear_state(nid, N_ONLINE); | 430 | node_clear_state(nid, N_ONLINE); |
433 | nr_online_nodes = num_node_state(N_ONLINE); | 431 | nr_online_nodes = num_node_state(N_ONLINE); |
434 | } | 432 | } |
435 | |||
436 | #define node_random(mask) __node_random(&(mask)) | ||
437 | extern int __node_random(const nodemask_t *maskp); | ||
438 | |||
439 | #else | 433 | #else |
440 | 434 | ||
441 | static inline int node_state(int node, enum node_states state) | 435 | static inline int node_state(int node, enum node_states state) |
@@ -466,8 +460,6 @@ static inline int num_node_state(enum node_states state) | |||
466 | 460 | ||
467 | #define node_set_online(node) node_set_state((node), N_ONLINE) | 461 | #define node_set_online(node) node_set_state((node), N_ONLINE) |
468 | #define node_set_offline(node) node_clear_state((node), N_ONLINE) | 462 | #define node_set_offline(node) node_clear_state((node), N_ONLINE) |
469 | |||
470 | static inline int node_random(const nodemask_t mask) { return 0; } | ||
471 | #endif | 463 | #endif |
472 | 464 | ||
473 | #define node_online_map node_states[N_ONLINE] | 465 | #define node_online_map node_states[N_ONLINE] |
diff --git a/include/linux/pci.h b/include/linux/pci.h index a327322a33ab..6a471aba3b07 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -311,7 +311,8 @@ struct pci_dev { | |||
311 | unsigned int is_virtfn:1; | 311 | unsigned int is_virtfn:1; |
312 | unsigned int reset_fn:1; | 312 | unsigned int reset_fn:1; |
313 | unsigned int is_hotplug_bridge:1; | 313 | unsigned int is_hotplug_bridge:1; |
314 | unsigned int aer_firmware_first:1; | 314 | unsigned int __aer_firmware_first_valid:1; |
315 | unsigned int __aer_firmware_first:1; | ||
315 | pci_dev_flags_t dev_flags; | 316 | pci_dev_flags_t dev_flags; |
316 | atomic_t enable_cnt; /* pci_enable_device has been called */ | 317 | atomic_t enable_cnt; /* pci_enable_device has been called */ |
317 | 318 | ||
diff --git a/include/linux/quota.h b/include/linux/quota.h index 7126a15467f1..94c1f03b50eb 100644 --- a/include/linux/quota.h +++ b/include/linux/quota.h | |||
@@ -174,8 +174,7 @@ enum { | |||
174 | #include <linux/rwsem.h> | 174 | #include <linux/rwsem.h> |
175 | #include <linux/spinlock.h> | 175 | #include <linux/spinlock.h> |
176 | #include <linux/wait.h> | 176 | #include <linux/wait.h> |
177 | #include <linux/percpu.h> | 177 | #include <linux/percpu_counter.h> |
178 | #include <linux/smp.h> | ||
179 | 178 | ||
180 | #include <linux/dqblk_xfs.h> | 179 | #include <linux/dqblk_xfs.h> |
181 | #include <linux/dqblk_v1.h> | 180 | #include <linux/dqblk_v1.h> |
@@ -254,6 +253,7 @@ enum { | |||
254 | 253 | ||
255 | struct dqstats { | 254 | struct dqstats { |
256 | int stat[_DQST_DQSTAT_LAST]; | 255 | int stat[_DQST_DQSTAT_LAST]; |
256 | struct percpu_counter counter[_DQST_DQSTAT_LAST]; | ||
257 | }; | 257 | }; |
258 | 258 | ||
259 | extern struct dqstats *dqstats_pcpu; | 259 | extern struct dqstats *dqstats_pcpu; |
@@ -261,20 +261,12 @@ extern struct dqstats dqstats; | |||
261 | 261 | ||
262 | static inline void dqstats_inc(unsigned int type) | 262 | static inline void dqstats_inc(unsigned int type) |
263 | { | 263 | { |
264 | #ifdef CONFIG_SMP | 264 | percpu_counter_inc(&dqstats.counter[type]); |
265 | per_cpu_ptr(dqstats_pcpu, smp_processor_id())->stat[type]++; | ||
266 | #else | ||
267 | dqstats.stat[type]++; | ||
268 | #endif | ||
269 | } | 265 | } |
270 | 266 | ||
271 | static inline void dqstats_dec(unsigned int type) | 267 | static inline void dqstats_dec(unsigned int type) |
272 | { | 268 | { |
273 | #ifdef CONFIG_SMP | 269 | percpu_counter_dec(&dqstats.counter[type]); |
274 | per_cpu_ptr(dqstats_pcpu, smp_processor_id())->stat[type]--; | ||
275 | #else | ||
276 | dqstats.stat[type]--; | ||
277 | #endif | ||
278 | } | 270 | } |
279 | 271 | ||
280 | #define DQ_MOD_B 0 /* dquot modified since read */ | 272 | #define DQ_MOD_B 0 /* dquot modified since read */ |
@@ -332,8 +324,8 @@ struct dquot_operations { | |||
332 | 324 | ||
333 | /* Operations handling requests from userspace */ | 325 | /* Operations handling requests from userspace */ |
334 | struct quotactl_ops { | 326 | struct quotactl_ops { |
335 | int (*quota_on)(struct super_block *, int, int, char *, int); | 327 | int (*quota_on)(struct super_block *, int, int, char *); |
336 | int (*quota_off)(struct super_block *, int, int); | 328 | int (*quota_off)(struct super_block *, int); |
337 | int (*quota_sync)(struct super_block *, int, int); | 329 | int (*quota_sync)(struct super_block *, int, int); |
338 | int (*get_info)(struct super_block *, int, struct if_dqinfo *); | 330 | int (*get_info)(struct super_block *, int, struct if_dqinfo *); |
339 | int (*set_info)(struct super_block *, int, struct if_dqinfo *); | 331 | int (*set_info)(struct super_block *, int, struct if_dqinfo *); |
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index e38ae53f3529..aa36793b48bd 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h | |||
@@ -53,6 +53,14 @@ int dquot_alloc_inode(const struct inode *inode); | |||
53 | int dquot_claim_space_nodirty(struct inode *inode, qsize_t number); | 53 | int dquot_claim_space_nodirty(struct inode *inode, qsize_t number); |
54 | void dquot_free_inode(const struct inode *inode); | 54 | void dquot_free_inode(const struct inode *inode); |
55 | 55 | ||
56 | int dquot_disable(struct super_block *sb, int type, unsigned int flags); | ||
57 | /* Suspend quotas on remount RO */ | ||
58 | static inline int dquot_suspend(struct super_block *sb, int type) | ||
59 | { | ||
60 | return dquot_disable(sb, type, DQUOT_SUSPENDED); | ||
61 | } | ||
62 | int dquot_resume(struct super_block *sb, int type); | ||
63 | |||
56 | int dquot_commit(struct dquot *dquot); | 64 | int dquot_commit(struct dquot *dquot); |
57 | int dquot_acquire(struct dquot *dquot); | 65 | int dquot_acquire(struct dquot *dquot); |
58 | int dquot_release(struct dquot *dquot); | 66 | int dquot_release(struct dquot *dquot); |
@@ -61,27 +69,25 @@ int dquot_mark_dquot_dirty(struct dquot *dquot); | |||
61 | 69 | ||
62 | int dquot_file_open(struct inode *inode, struct file *file); | 70 | int dquot_file_open(struct inode *inode, struct file *file); |
63 | 71 | ||
64 | int vfs_quota_on(struct super_block *sb, int type, int format_id, | 72 | int dquot_quota_on(struct super_block *sb, int type, int format_id, |
65 | char *path, int remount); | 73 | char *path); |
66 | int vfs_quota_enable(struct inode *inode, int type, int format_id, | 74 | int dquot_enable(struct inode *inode, int type, int format_id, |
67 | unsigned int flags); | 75 | unsigned int flags); |
68 | int vfs_quota_on_path(struct super_block *sb, int type, int format_id, | 76 | int dquot_quota_on_path(struct super_block *sb, int type, int format_id, |
69 | struct path *path); | 77 | struct path *path); |
70 | int vfs_quota_on_mount(struct super_block *sb, char *qf_name, | 78 | int dquot_quota_on_mount(struct super_block *sb, char *qf_name, |
71 | int format_id, int type); | 79 | int format_id, int type); |
72 | int vfs_quota_off(struct super_block *sb, int type, int remount); | 80 | int dquot_quota_off(struct super_block *sb, int type); |
73 | int vfs_quota_disable(struct super_block *sb, int type, unsigned int flags); | 81 | int dquot_quota_sync(struct super_block *sb, int type, int wait); |
74 | int vfs_quota_sync(struct super_block *sb, int type, int wait); | 82 | int dquot_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); |
75 | int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); | 83 | int dquot_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); |
76 | int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); | 84 | int dquot_get_dqblk(struct super_block *sb, int type, qid_t id, |
77 | int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, | ||
78 | struct fs_disk_quota *di); | 85 | struct fs_disk_quota *di); |
79 | int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, | 86 | int dquot_set_dqblk(struct super_block *sb, int type, qid_t id, |
80 | struct fs_disk_quota *di); | 87 | struct fs_disk_quota *di); |
81 | 88 | ||
82 | int __dquot_transfer(struct inode *inode, struct dquot **transfer_to); | 89 | int __dquot_transfer(struct inode *inode, struct dquot **transfer_to); |
83 | int dquot_transfer(struct inode *inode, struct iattr *iattr); | 90 | int dquot_transfer(struct inode *inode, struct iattr *iattr); |
84 | int vfs_dq_quota_on_remount(struct super_block *sb); | ||
85 | 91 | ||
86 | static inline struct mem_dqinfo *sb_dqinfo(struct super_block *sb, int type) | 92 | static inline struct mem_dqinfo *sb_dqinfo(struct super_block *sb, int type) |
87 | { | 93 | { |
@@ -148,20 +154,7 @@ static inline unsigned sb_any_quota_active(struct super_block *sb) | |||
148 | * Operations supported for diskquotas. | 154 | * Operations supported for diskquotas. |
149 | */ | 155 | */ |
150 | extern const struct dquot_operations dquot_operations; | 156 | extern const struct dquot_operations dquot_operations; |
151 | extern const struct quotactl_ops vfs_quotactl_ops; | 157 | extern const struct quotactl_ops dquot_quotactl_ops; |
152 | |||
153 | #define sb_dquot_ops (&dquot_operations) | ||
154 | #define sb_quotactl_ops (&vfs_quotactl_ops) | ||
155 | |||
156 | /* Cannot be called inside a transaction */ | ||
157 | static inline int vfs_dq_off(struct super_block *sb, int remount) | ||
158 | { | ||
159 | int ret = -ENOSYS; | ||
160 | |||
161 | if (sb->s_qcop && sb->s_qcop->quota_off) | ||
162 | ret = sb->s_qcop->quota_off(sb, -1, remount); | ||
163 | return ret; | ||
164 | } | ||
165 | 158 | ||
166 | #else | 159 | #else |
167 | 160 | ||
@@ -206,12 +199,6 @@ static inline int sb_any_quota_active(struct super_block *sb) | |||
206 | return 0; | 199 | return 0; |
207 | } | 200 | } |
208 | 201 | ||
209 | /* | ||
210 | * NO-OP when quota not configured. | ||
211 | */ | ||
212 | #define sb_dquot_ops (NULL) | ||
213 | #define sb_quotactl_ops (NULL) | ||
214 | |||
215 | static inline void dquot_initialize(struct inode *inode) | 202 | static inline void dquot_initialize(struct inode *inode) |
216 | { | 203 | { |
217 | } | 204 | } |
@@ -229,16 +216,6 @@ static inline void dquot_free_inode(const struct inode *inode) | |||
229 | { | 216 | { |
230 | } | 217 | } |
231 | 218 | ||
232 | static inline int vfs_dq_off(struct super_block *sb, int remount) | ||
233 | { | ||
234 | return 0; | ||
235 | } | ||
236 | |||
237 | static inline int vfs_dq_quota_on_remount(struct super_block *sb) | ||
238 | { | ||
239 | return 0; | ||
240 | } | ||
241 | |||
242 | static inline int dquot_transfer(struct inode *inode, struct iattr *iattr) | 219 | static inline int dquot_transfer(struct inode *inode, struct iattr *iattr) |
243 | { | 220 | { |
244 | return 0; | 221 | return 0; |
@@ -265,6 +242,22 @@ static inline int dquot_claim_space_nodirty(struct inode *inode, qsize_t number) | |||
265 | return 0; | 242 | return 0; |
266 | } | 243 | } |
267 | 244 | ||
245 | static inline int dquot_disable(struct super_block *sb, int type, | ||
246 | unsigned int flags) | ||
247 | { | ||
248 | return 0; | ||
249 | } | ||
250 | |||
251 | static inline int dquot_suspend(struct super_block *sb, int type) | ||
252 | { | ||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | static inline int dquot_resume(struct super_block *sb, int type) | ||
257 | { | ||
258 | return 0; | ||
259 | } | ||
260 | |||
268 | #define dquot_file_open generic_file_open | 261 | #define dquot_file_open generic_file_open |
269 | 262 | ||
270 | #endif /* CONFIG_QUOTA */ | 263 | #endif /* CONFIG_QUOTA */ |
diff --git a/include/linux/rio.h b/include/linux/rio.h index 19b5f227096e..bd6eb0ed34a7 100644 --- a/include/linux/rio.h +++ b/include/linux/rio.h | |||
@@ -88,11 +88,15 @@ union rio_pw_msg; | |||
88 | * @swpinfo: Switch port info | 88 | * @swpinfo: Switch port info |
89 | * @src_ops: Source operation capabilities | 89 | * @src_ops: Source operation capabilities |
90 | * @dst_ops: Destination operation capabilities | 90 | * @dst_ops: Destination operation capabilities |
91 | * @comp_tag: RIO component tag | ||
92 | * @phys_efptr: RIO device extended features pointer | ||
93 | * @em_efptr: RIO Error Management features pointer | ||
91 | * @dma_mask: Mask of bits of RIO address this device implements | 94 | * @dma_mask: Mask of bits of RIO address this device implements |
92 | * @rswitch: Pointer to &struct rio_switch if valid for this device | 95 | * @rswitch: Pointer to &struct rio_switch if valid for this device |
93 | * @driver: Driver claiming this device | 96 | * @driver: Driver claiming this device |
94 | * @dev: Device model device | 97 | * @dev: Device model device |
95 | * @riores: RIO resources this device owns | 98 | * @riores: RIO resources this device owns |
99 | * @pwcback: port-write callback function for this device | ||
96 | * @destid: Network destination ID | 100 | * @destid: Network destination ID |
97 | */ | 101 | */ |
98 | struct rio_dev { | 102 | struct rio_dev { |
@@ -222,6 +226,8 @@ struct rio_net { | |||
222 | * @add_entry: Callback for switch-specific route add function | 226 | * @add_entry: Callback for switch-specific route add function |
223 | * @get_entry: Callback for switch-specific route get function | 227 | * @get_entry: Callback for switch-specific route get function |
224 | * @clr_table: Callback for switch-specific clear route table function | 228 | * @clr_table: Callback for switch-specific clear route table function |
229 | * @set_domain: Callback for switch-specific domain setting function | ||
230 | * @get_domain: Callback for switch-specific domain get function | ||
225 | * @em_init: Callback for switch-specific error management initialization function | 231 | * @em_init: Callback for switch-specific error management initialization function |
226 | * @em_handle: Callback for switch-specific error management handler function | 232 | * @em_handle: Callback for switch-specific error management handler function |
227 | */ | 233 | */ |
diff --git a/include/linux/usb/audio-v2.h b/include/linux/usb/audio-v2.h index 2389f93a28b5..92f1d99f0f17 100644 --- a/include/linux/usb/audio-v2.h +++ b/include/linux/usb/audio-v2.h | |||
@@ -105,6 +105,22 @@ struct uac_as_header_descriptor_v2 { | |||
105 | __u8 iChannelNames; | 105 | __u8 iChannelNames; |
106 | } __attribute__((packed)); | 106 | } __attribute__((packed)); |
107 | 107 | ||
108 | /* 4.10.1.2 Class-Specific AS Isochronous Audio Data Endpoint Descriptor */ | ||
109 | |||
110 | struct uac2_iso_endpoint_descriptor { | ||
111 | __u8 bLength; /* in bytes: 8 */ | ||
112 | __u8 bDescriptorType; /* USB_DT_CS_ENDPOINT */ | ||
113 | __u8 bDescriptorSubtype; /* EP_GENERAL */ | ||
114 | __u8 bmAttributes; | ||
115 | __u8 bmControls; | ||
116 | __u8 bLockDelayUnits; | ||
117 | __le16 wLockDelay; | ||
118 | } __attribute__((packed)); | ||
119 | |||
120 | #define UAC2_CONTROL_PITCH (3 << 0) | ||
121 | #define UAC2_CONTROL_DATA_OVERRUN (3 << 2) | ||
122 | #define UAC2_CONTROL_DATA_UNDERRUN (3 << 4) | ||
123 | |||
108 | /* 6.1 Interrupt Data Message */ | 124 | /* 6.1 Interrupt Data Message */ |
109 | 125 | ||
110 | #define UAC2_INTERRUPT_DATA_MSG_VENDOR (1 << 0) | 126 | #define UAC2_INTERRUPT_DATA_MSG_VENDOR (1 << 0) |
diff --git a/include/linux/uuid.h b/include/linux/uuid.h new file mode 100644 index 000000000000..5b7efbfcee4e --- /dev/null +++ b/include/linux/uuid.h | |||
@@ -0,0 +1,70 @@ | |||
1 | /* | ||
2 | * UUID/GUID definition | ||
3 | * | ||
4 | * Copyright (C) 2010, Intel Corp. | ||
5 | * Huang Ying <ying.huang@intel.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License version | ||
9 | * 2 as published by the Free Software Foundation; | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #ifndef _LINUX_UUID_H_ | ||
22 | #define _LINUX_UUID_H_ | ||
23 | |||
24 | #include <linux/types.h> | ||
25 | #include <linux/string.h> | ||
26 | |||
27 | typedef struct { | ||
28 | __u8 b[16]; | ||
29 | } uuid_le; | ||
30 | |||
31 | typedef struct { | ||
32 | __u8 b[16]; | ||
33 | } uuid_be; | ||
34 | |||
35 | #define UUID_LE(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \ | ||
36 | ((uuid_le) \ | ||
37 | {{ (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \ | ||
38 | (b) & 0xff, ((b) >> 8) & 0xff, \ | ||
39 | (c) & 0xff, ((c) >> 8) & 0xff, \ | ||
40 | (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }}) | ||
41 | |||
42 | #define UUID_BE(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \ | ||
43 | ((uuid_be) \ | ||
44 | {{ ((a) >> 24) & 0xff, ((a) >> 16) & 0xff, ((a) >> 8) & 0xff, (a) & 0xff, \ | ||
45 | ((b) >> 8) & 0xff, (b) & 0xff, \ | ||
46 | ((c) >> 8) & 0xff, (c) & 0xff, \ | ||
47 | (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }}) | ||
48 | |||
49 | #define NULL_UUID_LE \ | ||
50 | UUID_LE(0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, \ | ||
51 | 0x00, 0x00, 0x00, 0x00) | ||
52 | |||
53 | #define NULL_UUID_BE \ | ||
54 | UUID_BE(0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, \ | ||
55 | 0x00, 0x00, 0x00, 0x00) | ||
56 | |||
57 | static inline int uuid_le_cmp(const uuid_le u1, const uuid_le u2) | ||
58 | { | ||
59 | return memcmp(&u1, &u2, sizeof(uuid_le)); | ||
60 | } | ||
61 | |||
62 | static inline int uuid_be_cmp(const uuid_be u1, const uuid_be u2) | ||
63 | { | ||
64 | return memcmp(&u1, &u2, sizeof(uuid_be)); | ||
65 | } | ||
66 | |||
67 | extern void uuid_le_gen(uuid_le *u); | ||
68 | extern void uuid_be_gen(uuid_be *u); | ||
69 | |||
70 | #endif | ||
diff --git a/include/net/cls_cgroup.h b/include/net/cls_cgroup.h index 6cf44866cecd..726cc3536409 100644 --- a/include/net/cls_cgroup.h +++ b/include/net/cls_cgroup.h | |||
@@ -39,7 +39,7 @@ extern int net_cls_subsys_id; | |||
39 | static inline u32 task_cls_classid(struct task_struct *p) | 39 | static inline u32 task_cls_classid(struct task_struct *p) |
40 | { | 40 | { |
41 | int id; | 41 | int id; |
42 | u32 classid; | 42 | u32 classid = 0; |
43 | 43 | ||
44 | if (in_interrupt()) | 44 | if (in_interrupt()) |
45 | return 0; | 45 | return 0; |
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 6173c619913a..4b860116e096 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h | |||
@@ -876,7 +876,7 @@ struct sctp_transport { | |||
876 | 876 | ||
877 | /* Reference counting. */ | 877 | /* Reference counting. */ |
878 | atomic_t refcnt; | 878 | atomic_t refcnt; |
879 | int dead:1, | 879 | __u32 dead:1, |
880 | /* RTO-Pending : A flag used to track if one of the DATA | 880 | /* RTO-Pending : A flag used to track if one of the DATA |
881 | * chunks sent to this address is currently being | 881 | * chunks sent to this address is currently being |
882 | * used to compute a RTT. If this flag is 0, | 882 | * used to compute a RTT. If this flag is 0, |
diff --git a/include/net/sock.h b/include/net/sock.h index d2a71b04a5ae..ca241ea14875 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
@@ -1026,15 +1026,23 @@ extern void release_sock(struct sock *sk); | |||
1026 | SINGLE_DEPTH_NESTING) | 1026 | SINGLE_DEPTH_NESTING) |
1027 | #define bh_unlock_sock(__sk) spin_unlock(&((__sk)->sk_lock.slock)) | 1027 | #define bh_unlock_sock(__sk) spin_unlock(&((__sk)->sk_lock.slock)) |
1028 | 1028 | ||
1029 | static inline void lock_sock_bh(struct sock *sk) | 1029 | extern bool lock_sock_fast(struct sock *sk); |
1030 | /** | ||
1031 | * unlock_sock_fast - complement of lock_sock_fast | ||
1032 | * @sk: socket | ||
1033 | * @slow: slow mode | ||
1034 | * | ||
1035 | * fast unlock socket for user context. | ||
1036 | * If slow mode is on, we call regular release_sock() | ||
1037 | */ | ||
1038 | static inline void unlock_sock_fast(struct sock *sk, bool slow) | ||
1030 | { | 1039 | { |
1031 | spin_lock_bh(&sk->sk_lock.slock); | 1040 | if (slow) |
1041 | release_sock(sk); | ||
1042 | else | ||
1043 | spin_unlock_bh(&sk->sk_lock.slock); | ||
1032 | } | 1044 | } |
1033 | 1045 | ||
1034 | static inline void unlock_sock_bh(struct sock *sk) | ||
1035 | { | ||
1036 | spin_unlock_bh(&sk->sk_lock.slock); | ||
1037 | } | ||
1038 | 1046 | ||
1039 | extern struct sock *sk_alloc(struct net *net, int family, | 1047 | extern struct sock *sk_alloc(struct net *net, int family, |
1040 | gfp_t priority, | 1048 | gfp_t priority, |
diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h index 5d60ad4ebf78..f5b1ba90e952 100644 --- a/include/trace/events/ext4.h +++ b/include/trace/events/ext4.h | |||
@@ -606,9 +606,9 @@ TRACE_EVENT(ext4_free_blocks, | |||
606 | ); | 606 | ); |
607 | 607 | ||
608 | TRACE_EVENT(ext4_sync_file, | 608 | TRACE_EVENT(ext4_sync_file, |
609 | TP_PROTO(struct file *file, struct dentry *dentry, int datasync), | 609 | TP_PROTO(struct file *file, int datasync), |
610 | 610 | ||
611 | TP_ARGS(file, dentry, datasync), | 611 | TP_ARGS(file, datasync), |
612 | 612 | ||
613 | TP_STRUCT__entry( | 613 | TP_STRUCT__entry( |
614 | __field( dev_t, dev ) | 614 | __field( dev_t, dev ) |
@@ -618,6 +618,8 @@ TRACE_EVENT(ext4_sync_file, | |||
618 | ), | 618 | ), |
619 | 619 | ||
620 | TP_fast_assign( | 620 | TP_fast_assign( |
621 | struct dentry *dentry = file->f_path.dentry; | ||
622 | |||
621 | __entry->dev = dentry->d_inode->i_sb->s_dev; | 623 | __entry->dev = dentry->d_inode->i_sb->s_dev; |
622 | __entry->ino = dentry->d_inode->i_ino; | 624 | __entry->ino = dentry->d_inode->i_ino; |
623 | __entry->datasync = datasync; | 625 | __entry->datasync = datasync; |
@@ -273,16 +273,13 @@ static int shm_release(struct inode *ino, struct file *file) | |||
273 | return 0; | 273 | return 0; |
274 | } | 274 | } |
275 | 275 | ||
276 | static int shm_fsync(struct file *file, struct dentry *dentry, int datasync) | 276 | static int shm_fsync(struct file *file, int datasync) |
277 | { | 277 | { |
278 | int (*fsync) (struct file *, struct dentry *, int datasync); | ||
279 | struct shm_file_data *sfd = shm_file_data(file); | 278 | struct shm_file_data *sfd = shm_file_data(file); |
280 | int ret = -EINVAL; | ||
281 | 279 | ||
282 | fsync = sfd->file->f_op->fsync; | 280 | if (!sfd->file->f_op->fsync) |
283 | if (fsync) | 281 | return -EINVAL; |
284 | ret = fsync(sfd->file, sfd->file->f_path.dentry, datasync); | 282 | return sfd->file->f_op->fsync(sfd->file, datasync); |
285 | return ret; | ||
286 | } | 283 | } |
287 | 284 | ||
288 | static unsigned long shm_get_unmapped_area(struct file *file, | 285 | static unsigned long shm_get_unmapped_area(struct file *file, |
diff --git a/kernel/cpu.c b/kernel/cpu.c index 3097382eb44a..8b92539b4754 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c | |||
@@ -394,7 +394,7 @@ static cpumask_var_t frozen_cpus; | |||
394 | 394 | ||
395 | int disable_nonboot_cpus(void) | 395 | int disable_nonboot_cpus(void) |
396 | { | 396 | { |
397 | int cpu, first_cpu, error; | 397 | int cpu, first_cpu, error = 0; |
398 | 398 | ||
399 | cpu_maps_update_begin(); | 399 | cpu_maps_update_begin(); |
400 | first_cpu = cpumask_first(cpu_online_mask); | 400 | first_cpu = cpumask_first(cpu_online_mask); |
diff --git a/kernel/fork.c b/kernel/fork.c index bf9fef6d1bfe..b6cce14ba047 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -1086,10 +1086,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1086 | } | 1086 | } |
1087 | mpol_fix_fork_child_flag(p); | 1087 | mpol_fix_fork_child_flag(p); |
1088 | #endif | 1088 | #endif |
1089 | #ifdef CONFIG_CPUSETS | ||
1090 | p->cpuset_mem_spread_rotor = node_random(p->mems_allowed); | ||
1091 | p->cpuset_slab_spread_rotor = node_random(p->mems_allowed); | ||
1092 | #endif | ||
1093 | #ifdef CONFIG_TRACE_IRQFLAGS | 1089 | #ifdef CONFIG_TRACE_IRQFLAGS |
1094 | p->irq_events = 0; | 1090 | p->irq_events = 0; |
1095 | #ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW | 1091 | #ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW |
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index b9b134b35088..5c69e996bd0f 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c | |||
@@ -89,7 +89,7 @@ static void hrtimer_get_softirq_time(struct hrtimer_cpu_base *base) | |||
89 | 89 | ||
90 | do { | 90 | do { |
91 | seq = read_seqbegin(&xtime_lock); | 91 | seq = read_seqbegin(&xtime_lock); |
92 | xts = current_kernel_time(); | 92 | xts = __current_kernel_time(); |
93 | tom = wall_to_monotonic; | 93 | tom = wall_to_monotonic; |
94 | } while (read_seqretry(&xtime_lock, seq)); | 94 | } while (read_seqretry(&xtime_lock, seq)); |
95 | 95 | ||
diff --git a/kernel/perf_event.c b/kernel/perf_event.c index e099650cd249..bd7ce8ca5bb9 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c | |||
@@ -4999,8 +4999,8 @@ SYSCALL_DEFINE5(perf_event_open, | |||
4999 | struct perf_event_context *ctx; | 4999 | struct perf_event_context *ctx; |
5000 | struct file *event_file = NULL; | 5000 | struct file *event_file = NULL; |
5001 | struct file *group_file = NULL; | 5001 | struct file *group_file = NULL; |
5002 | int event_fd; | ||
5002 | int fput_needed = 0; | 5003 | int fput_needed = 0; |
5003 | int fput_needed2 = 0; | ||
5004 | int err; | 5004 | int err; |
5005 | 5005 | ||
5006 | /* for future expandability... */ | 5006 | /* for future expandability... */ |
@@ -5021,12 +5021,18 @@ SYSCALL_DEFINE5(perf_event_open, | |||
5021 | return -EINVAL; | 5021 | return -EINVAL; |
5022 | } | 5022 | } |
5023 | 5023 | ||
5024 | event_fd = get_unused_fd_flags(O_RDWR); | ||
5025 | if (event_fd < 0) | ||
5026 | return event_fd; | ||
5027 | |||
5024 | /* | 5028 | /* |
5025 | * Get the target context (task or percpu): | 5029 | * Get the target context (task or percpu): |
5026 | */ | 5030 | */ |
5027 | ctx = find_get_context(pid, cpu); | 5031 | ctx = find_get_context(pid, cpu); |
5028 | if (IS_ERR(ctx)) | 5032 | if (IS_ERR(ctx)) { |
5029 | return PTR_ERR(ctx); | 5033 | err = PTR_ERR(ctx); |
5034 | goto err_fd; | ||
5035 | } | ||
5030 | 5036 | ||
5031 | /* | 5037 | /* |
5032 | * Look up the group leader (we will attach this event to it): | 5038 | * Look up the group leader (we will attach this event to it): |
@@ -5066,13 +5072,11 @@ SYSCALL_DEFINE5(perf_event_open, | |||
5066 | if (IS_ERR(event)) | 5072 | if (IS_ERR(event)) |
5067 | goto err_put_context; | 5073 | goto err_put_context; |
5068 | 5074 | ||
5069 | err = anon_inode_getfd("[perf_event]", &perf_fops, event, O_RDWR); | 5075 | event_file = anon_inode_getfile("[perf_event]", &perf_fops, event, O_RDWR); |
5070 | if (err < 0) | 5076 | if (IS_ERR(event_file)) { |
5071 | goto err_free_put_context; | 5077 | err = PTR_ERR(event_file); |
5072 | |||
5073 | event_file = fget_light(err, &fput_needed2); | ||
5074 | if (!event_file) | ||
5075 | goto err_free_put_context; | 5078 | goto err_free_put_context; |
5079 | } | ||
5076 | 5080 | ||
5077 | if (flags & PERF_FLAG_FD_OUTPUT) { | 5081 | if (flags & PERF_FLAG_FD_OUTPUT) { |
5078 | err = perf_event_set_output(event, group_fd); | 5082 | err = perf_event_set_output(event, group_fd); |
@@ -5093,19 +5097,19 @@ SYSCALL_DEFINE5(perf_event_open, | |||
5093 | list_add_tail(&event->owner_entry, ¤t->perf_event_list); | 5097 | list_add_tail(&event->owner_entry, ¤t->perf_event_list); |
5094 | mutex_unlock(¤t->perf_event_mutex); | 5098 | mutex_unlock(¤t->perf_event_mutex); |
5095 | 5099 | ||
5096 | err_fput_free_put_context: | 5100 | fput_light(group_file, fput_needed); |
5097 | fput_light(event_file, fput_needed2); | 5101 | fd_install(event_fd, event_file); |
5102 | return event_fd; | ||
5098 | 5103 | ||
5104 | err_fput_free_put_context: | ||
5105 | fput(event_file); | ||
5099 | err_free_put_context: | 5106 | err_free_put_context: |
5100 | if (err < 0) | 5107 | free_event(event); |
5101 | free_event(event); | ||
5102 | |||
5103 | err_put_context: | 5108 | err_put_context: |
5104 | if (err < 0) | ||
5105 | put_ctx(ctx); | ||
5106 | |||
5107 | fput_light(group_file, fput_needed); | 5109 | fput_light(group_file, fput_needed); |
5108 | 5110 | put_ctx(ctx); | |
5111 | err_fd: | ||
5112 | put_unused_fd(event_fd); | ||
5109 | return err; | 5113 | return err; |
5110 | } | 5114 | } |
5111 | 5115 | ||
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c index 00d1fda58ab6..ad723420acc3 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c | |||
@@ -559,14 +559,7 @@ SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock, | |||
559 | new_timer->it_id = (timer_t) new_timer_id; | 559 | new_timer->it_id = (timer_t) new_timer_id; |
560 | new_timer->it_clock = which_clock; | 560 | new_timer->it_clock = which_clock; |
561 | new_timer->it_overrun = -1; | 561 | new_timer->it_overrun = -1; |
562 | error = CLOCK_DISPATCH(which_clock, timer_create, (new_timer)); | ||
563 | if (error) | ||
564 | goto out; | ||
565 | 562 | ||
566 | /* | ||
567 | * return the timer_id now. The next step is hard to | ||
568 | * back out if there is an error. | ||
569 | */ | ||
570 | if (copy_to_user(created_timer_id, | 563 | if (copy_to_user(created_timer_id, |
571 | &new_timer_id, sizeof (new_timer_id))) { | 564 | &new_timer_id, sizeof (new_timer_id))) { |
572 | error = -EFAULT; | 565 | error = -EFAULT; |
@@ -597,6 +590,10 @@ SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock, | |||
597 | new_timer->sigq->info.si_tid = new_timer->it_id; | 590 | new_timer->sigq->info.si_tid = new_timer->it_id; |
598 | new_timer->sigq->info.si_code = SI_TIMER; | 591 | new_timer->sigq->info.si_code = SI_TIMER; |
599 | 592 | ||
593 | error = CLOCK_DISPATCH(which_clock, timer_create, (new_timer)); | ||
594 | if (error) | ||
595 | goto out; | ||
596 | |||
600 | spin_lock_irq(¤t->sighand->siglock); | 597 | spin_lock_irq(¤t->sighand->siglock); |
601 | new_timer->it_signal = current->signal; | 598 | new_timer->it_signal = current->signal; |
602 | list_add(&new_timer->list, ¤t->signal->posix_timers); | 599 | list_add(&new_timer->list, ¤t->signal->posix_timers); |
diff --git a/kernel/sched.c b/kernel/sched.c index 15b93f617fd7..d48408142503 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -4054,6 +4054,23 @@ int __sched wait_for_completion_killable(struct completion *x) | |||
4054 | EXPORT_SYMBOL(wait_for_completion_killable); | 4054 | EXPORT_SYMBOL(wait_for_completion_killable); |
4055 | 4055 | ||
4056 | /** | 4056 | /** |
4057 | * wait_for_completion_killable_timeout: - waits for completion of a task (w/(to,killable)) | ||
4058 | * @x: holds the state of this particular completion | ||
4059 | * @timeout: timeout value in jiffies | ||
4060 | * | ||
4061 | * This waits for either a completion of a specific task to be | ||
4062 | * signaled or for a specified timeout to expire. It can be | ||
4063 | * interrupted by a kill signal. The timeout is in jiffies. | ||
4064 | */ | ||
4065 | unsigned long __sched | ||
4066 | wait_for_completion_killable_timeout(struct completion *x, | ||
4067 | unsigned long timeout) | ||
4068 | { | ||
4069 | return wait_for_common(x, timeout, TASK_KILLABLE); | ||
4070 | } | ||
4071 | EXPORT_SYMBOL(wait_for_completion_killable_timeout); | ||
4072 | |||
4073 | /** | ||
4057 | * try_wait_for_completion - try to decrement a completion without blocking | 4074 | * try_wait_for_completion - try to decrement a completion without blocking |
4058 | * @x: completion structure | 4075 | * @x: completion structure |
4059 | * | 4076 | * |
diff --git a/kernel/timer.c b/kernel/timer.c index e3b8c697bde4..2454172a80d3 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
@@ -752,11 +752,15 @@ unsigned long apply_slack(struct timer_list *timer, unsigned long expires) | |||
752 | 752 | ||
753 | expires_limit = expires; | 753 | expires_limit = expires; |
754 | 754 | ||
755 | if (timer->slack > -1) | 755 | if (timer->slack >= 0) { |
756 | expires_limit = expires + timer->slack; | 756 | expires_limit = expires + timer->slack; |
757 | else if (time_after(expires, jiffies)) /* auto slack: use 0.4% */ | 757 | } else { |
758 | expires_limit = expires + (expires - jiffies)/256; | 758 | unsigned long now = jiffies; |
759 | 759 | ||
760 | /* No slack, if already expired else auto slack 0.4% */ | ||
761 | if (time_after(expires, now)) | ||
762 | expires_limit = expires + (expires - now)/256; | ||
763 | } | ||
760 | mask = expires ^ expires_limit; | 764 | mask = expires ^ expires_limit; |
761 | if (mask == 0) | 765 | if (mask == 0) |
762 | return expires; | 766 | return expires; |
diff --git a/lib/Makefile b/lib/Makefile index c8567a59d316..3f1062cbbff4 100644 --- a/lib/Makefile +++ b/lib/Makefile | |||
@@ -21,7 +21,7 @@ lib-y += kobject.o kref.o klist.o | |||
21 | 21 | ||
22 | obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \ | 22 | obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \ |
23 | bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \ | 23 | bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \ |
24 | string_helpers.o gcd.o lcm.o list_sort.o | 24 | string_helpers.o gcd.o lcm.o list_sort.o uuid.o |
25 | 25 | ||
26 | ifeq ($(CONFIG_DEBUG_KOBJECT),y) | 26 | ifeq ($(CONFIG_DEBUG_KOBJECT),y) |
27 | CFLAGS_kobject.o += -DDEBUG | 27 | CFLAGS_kobject.o += -DDEBUG |
diff --git a/lib/atomic64_test.c b/lib/atomic64_test.c index 65e482caf5e9..9087d71537dd 100644 --- a/lib/atomic64_test.c +++ b/lib/atomic64_test.c | |||
@@ -9,6 +9,7 @@ | |||
9 | * (at your option) any later version. | 9 | * (at your option) any later version. |
10 | */ | 10 | */ |
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
12 | #include <linux/kernel.h> | ||
12 | #include <asm/atomic.h> | 13 | #include <asm/atomic.h> |
13 | 14 | ||
14 | #define INIT(c) do { atomic64_set(&v, c); r = c; } while (0) | 15 | #define INIT(c) do { atomic64_set(&v, c); r = c; } while (0) |
diff --git a/lib/bitmap.c b/lib/bitmap.c index d7137e7e06e8..ffb78c916ccd 100644 --- a/lib/bitmap.c +++ b/lib/bitmap.c | |||
@@ -672,7 +672,7 @@ static int bitmap_pos_to_ord(const unsigned long *buf, int pos, int bits) | |||
672 | * | 672 | * |
673 | * The bit positions 0 through @bits are valid positions in @buf. | 673 | * The bit positions 0 through @bits are valid positions in @buf. |
674 | */ | 674 | */ |
675 | int bitmap_ord_to_pos(const unsigned long *buf, int ord, int bits) | 675 | static int bitmap_ord_to_pos(const unsigned long *buf, int ord, int bits) |
676 | { | 676 | { |
677 | int pos = 0; | 677 | int pos = 0; |
678 | 678 | ||
diff --git a/lib/uuid.c b/lib/uuid.c new file mode 100644 index 000000000000..8fadd7cef46c --- /dev/null +++ b/lib/uuid.c | |||
@@ -0,0 +1,53 @@ | |||
1 | /* | ||
2 | * Unified UUID/GUID definition | ||
3 | * | ||
4 | * Copyright (C) 2009, Intel Corp. | ||
5 | * Huang Ying <ying.huang@intel.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License version | ||
9 | * 2 as published by the Free Software Foundation; | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/uuid.h> | ||
24 | #include <linux/random.h> | ||
25 | |||
26 | static void __uuid_gen_common(__u8 b[16]) | ||
27 | { | ||
28 | int i; | ||
29 | u32 r; | ||
30 | |||
31 | for (i = 0; i < 4; i++) { | ||
32 | r = random32(); | ||
33 | memcpy(b + i * 4, &r, 4); | ||
34 | } | ||
35 | /* reversion 0b10 */ | ||
36 | b[8] = (b[8] & 0x3F) | 0x80; | ||
37 | } | ||
38 | |||
39 | void uuid_le_gen(uuid_le *lu) | ||
40 | { | ||
41 | __uuid_gen_common(lu->b); | ||
42 | /* version 4 : random generation */ | ||
43 | lu->b[7] = (lu->b[7] & 0x0F) | 0x40; | ||
44 | } | ||
45 | EXPORT_SYMBOL_GPL(uuid_le_gen); | ||
46 | |||
47 | void uuid_be_gen(uuid_be *bu) | ||
48 | { | ||
49 | __uuid_gen_common(bu->b); | ||
50 | /* version 4 : random generation */ | ||
51 | bu->b[6] = (bu->b[6] & 0x0F) | 0x40; | ||
52 | } | ||
53 | EXPORT_SYMBOL_GPL(uuid_be_gen); | ||
diff --git a/mm/shmem.c b/mm/shmem.c index 855eaf5b8d5b..7e5030ae18ff 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -727,10 +727,11 @@ done2: | |||
727 | if (inode->i_mapping->nrpages && (info->flags & SHMEM_PAGEIN)) { | 727 | if (inode->i_mapping->nrpages && (info->flags & SHMEM_PAGEIN)) { |
728 | /* | 728 | /* |
729 | * Call truncate_inode_pages again: racing shmem_unuse_inode | 729 | * Call truncate_inode_pages again: racing shmem_unuse_inode |
730 | * may have swizzled a page in from swap since vmtruncate or | 730 | * may have swizzled a page in from swap since |
731 | * generic_delete_inode did it, before we lowered next_index. | 731 | * truncate_pagecache or generic_delete_inode did it, before we |
732 | * Also, though shmem_getpage checks i_size before adding to | 732 | * lowered next_index. Also, though shmem_getpage checks |
733 | * cache, no recheck after: so fix the narrow window there too. | 733 | * i_size before adding to cache, no recheck after: so fix the |
734 | * narrow window there too. | ||
734 | * | 735 | * |
735 | * Recalling truncate_inode_pages_range and unmap_mapping_range | 736 | * Recalling truncate_inode_pages_range and unmap_mapping_range |
736 | * every time for punch_hole (which never got a chance to clear | 737 | * every time for punch_hole (which never got a chance to clear |
@@ -760,19 +761,16 @@ done2: | |||
760 | } | 761 | } |
761 | } | 762 | } |
762 | 763 | ||
763 | static void shmem_truncate(struct inode *inode) | ||
764 | { | ||
765 | shmem_truncate_range(inode, inode->i_size, (loff_t)-1); | ||
766 | } | ||
767 | |||
768 | static int shmem_notify_change(struct dentry *dentry, struct iattr *attr) | 764 | static int shmem_notify_change(struct dentry *dentry, struct iattr *attr) |
769 | { | 765 | { |
770 | struct inode *inode = dentry->d_inode; | 766 | struct inode *inode = dentry->d_inode; |
771 | struct page *page = NULL; | ||
772 | int error; | 767 | int error; |
773 | 768 | ||
774 | if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)) { | 769 | if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)) { |
775 | if (attr->ia_size < inode->i_size) { | 770 | loff_t newsize = attr->ia_size; |
771 | struct page *page = NULL; | ||
772 | |||
773 | if (newsize < inode->i_size) { | ||
776 | /* | 774 | /* |
777 | * If truncating down to a partial page, then | 775 | * If truncating down to a partial page, then |
778 | * if that page is already allocated, hold it | 776 | * if that page is already allocated, hold it |
@@ -780,9 +778,9 @@ static int shmem_notify_change(struct dentry *dentry, struct iattr *attr) | |||
780 | * truncate_partial_page cannnot miss it were | 778 | * truncate_partial_page cannnot miss it were |
781 | * it assigned to swap. | 779 | * it assigned to swap. |
782 | */ | 780 | */ |
783 | if (attr->ia_size & (PAGE_CACHE_SIZE-1)) { | 781 | if (newsize & (PAGE_CACHE_SIZE-1)) { |
784 | (void) shmem_getpage(inode, | 782 | (void) shmem_getpage(inode, |
785 | attr->ia_size>>PAGE_CACHE_SHIFT, | 783 | newsize >> PAGE_CACHE_SHIFT, |
786 | &page, SGP_READ, NULL); | 784 | &page, SGP_READ, NULL); |
787 | if (page) | 785 | if (page) |
788 | unlock_page(page); | 786 | unlock_page(page); |
@@ -794,24 +792,29 @@ static int shmem_notify_change(struct dentry *dentry, struct iattr *attr) | |||
794 | * if it's being fully truncated to zero-length: the | 792 | * if it's being fully truncated to zero-length: the |
795 | * nrpages check is efficient enough in that case. | 793 | * nrpages check is efficient enough in that case. |
796 | */ | 794 | */ |
797 | if (attr->ia_size) { | 795 | if (newsize) { |
798 | struct shmem_inode_info *info = SHMEM_I(inode); | 796 | struct shmem_inode_info *info = SHMEM_I(inode); |
799 | spin_lock(&info->lock); | 797 | spin_lock(&info->lock); |
800 | info->flags &= ~SHMEM_PAGEIN; | 798 | info->flags &= ~SHMEM_PAGEIN; |
801 | spin_unlock(&info->lock); | 799 | spin_unlock(&info->lock); |
802 | } | 800 | } |
803 | } | 801 | } |
802 | |||
803 | error = simple_setsize(inode, newsize); | ||
804 | if (page) | ||
805 | page_cache_release(page); | ||
806 | if (error) | ||
807 | return error; | ||
808 | shmem_truncate_range(inode, newsize, (loff_t)-1); | ||
804 | } | 809 | } |
805 | 810 | ||
806 | error = inode_change_ok(inode, attr); | 811 | error = inode_change_ok(inode, attr); |
807 | if (!error) | 812 | if (!error) |
808 | error = inode_setattr(inode, attr); | 813 | generic_setattr(inode, attr); |
809 | #ifdef CONFIG_TMPFS_POSIX_ACL | 814 | #ifdef CONFIG_TMPFS_POSIX_ACL |
810 | if (!error && (attr->ia_valid & ATTR_MODE)) | 815 | if (!error && (attr->ia_valid & ATTR_MODE)) |
811 | error = generic_acl_chmod(inode); | 816 | error = generic_acl_chmod(inode); |
812 | #endif | 817 | #endif |
813 | if (page) | ||
814 | page_cache_release(page); | ||
815 | return error; | 818 | return error; |
816 | } | 819 | } |
817 | 820 | ||
@@ -819,11 +822,11 @@ static void shmem_delete_inode(struct inode *inode) | |||
819 | { | 822 | { |
820 | struct shmem_inode_info *info = SHMEM_I(inode); | 823 | struct shmem_inode_info *info = SHMEM_I(inode); |
821 | 824 | ||
822 | if (inode->i_op->truncate == shmem_truncate) { | 825 | if (inode->i_mapping->a_ops == &shmem_aops) { |
823 | truncate_inode_pages(inode->i_mapping, 0); | 826 | truncate_inode_pages(inode->i_mapping, 0); |
824 | shmem_unacct_size(info->flags, inode->i_size); | 827 | shmem_unacct_size(info->flags, inode->i_size); |
825 | inode->i_size = 0; | 828 | inode->i_size = 0; |
826 | shmem_truncate(inode); | 829 | shmem_truncate_range(inode, 0, (loff_t)-1); |
827 | if (!list_empty(&info->swaplist)) { | 830 | if (!list_empty(&info->swaplist)) { |
828 | mutex_lock(&shmem_swaplist_mutex); | 831 | mutex_lock(&shmem_swaplist_mutex); |
829 | list_del_init(&info->swaplist); | 832 | list_del_init(&info->swaplist); |
@@ -2022,7 +2025,6 @@ static const struct inode_operations shmem_symlink_inline_operations = { | |||
2022 | }; | 2025 | }; |
2023 | 2026 | ||
2024 | static const struct inode_operations shmem_symlink_inode_operations = { | 2027 | static const struct inode_operations shmem_symlink_inode_operations = { |
2025 | .truncate = shmem_truncate, | ||
2026 | .readlink = generic_readlink, | 2028 | .readlink = generic_readlink, |
2027 | .follow_link = shmem_follow_link, | 2029 | .follow_link = shmem_follow_link, |
2028 | .put_link = shmem_put_link, | 2030 | .put_link = shmem_put_link, |
@@ -2433,14 +2435,13 @@ static const struct file_operations shmem_file_operations = { | |||
2433 | .write = do_sync_write, | 2435 | .write = do_sync_write, |
2434 | .aio_read = shmem_file_aio_read, | 2436 | .aio_read = shmem_file_aio_read, |
2435 | .aio_write = generic_file_aio_write, | 2437 | .aio_write = generic_file_aio_write, |
2436 | .fsync = simple_sync_file, | 2438 | .fsync = noop_fsync, |
2437 | .splice_read = generic_file_splice_read, | 2439 | .splice_read = generic_file_splice_read, |
2438 | .splice_write = generic_file_splice_write, | 2440 | .splice_write = generic_file_splice_write, |
2439 | #endif | 2441 | #endif |
2440 | }; | 2442 | }; |
2441 | 2443 | ||
2442 | static const struct inode_operations shmem_inode_operations = { | 2444 | static const struct inode_operations shmem_inode_operations = { |
2443 | .truncate = shmem_truncate, | ||
2444 | .setattr = shmem_notify_change, | 2445 | .setattr = shmem_notify_change, |
2445 | .truncate_range = shmem_truncate_range, | 2446 | .truncate_range = shmem_truncate_range, |
2446 | #ifdef CONFIG_TMPFS_POSIX_ACL | 2447 | #ifdef CONFIG_TMPFS_POSIX_ACL |
diff --git a/mm/truncate.c b/mm/truncate.c index f42675a3615d..937571b8b233 100644 --- a/mm/truncate.c +++ b/mm/truncate.c | |||
@@ -548,18 +548,18 @@ EXPORT_SYMBOL(truncate_pagecache); | |||
548 | * NOTE! We have to be ready to update the memory sharing | 548 | * NOTE! We have to be ready to update the memory sharing |
549 | * between the file and the memory map for a potential last | 549 | * between the file and the memory map for a potential last |
550 | * incomplete page. Ugly, but necessary. | 550 | * incomplete page. Ugly, but necessary. |
551 | * | ||
552 | * This function is deprecated and simple_setsize or truncate_pagecache | ||
553 | * should be used instead. | ||
551 | */ | 554 | */ |
552 | int vmtruncate(struct inode *inode, loff_t offset) | 555 | int vmtruncate(struct inode *inode, loff_t offset) |
553 | { | 556 | { |
554 | loff_t oldsize; | ||
555 | int error; | 557 | int error; |
556 | 558 | ||
557 | error = inode_newsize_ok(inode, offset); | 559 | error = simple_setsize(inode, offset); |
558 | if (error) | 560 | if (error) |
559 | return error; | 561 | return error; |
560 | oldsize = inode->i_size; | 562 | |
561 | i_size_write(inode, offset); | ||
562 | truncate_pagecache(inode, oldsize, offset); | ||
563 | if (inode->i_op->truncate) | 563 | if (inode->i_op->truncate) |
564 | inode->i_op->truncate(inode); | 564 | inode->i_op->truncate(inode); |
565 | 565 | ||
diff --git a/net/core/datagram.c b/net/core/datagram.c index e0097531417a..f5b6f43a4c2e 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c | |||
@@ -229,15 +229,17 @@ EXPORT_SYMBOL(skb_free_datagram); | |||
229 | 229 | ||
230 | void skb_free_datagram_locked(struct sock *sk, struct sk_buff *skb) | 230 | void skb_free_datagram_locked(struct sock *sk, struct sk_buff *skb) |
231 | { | 231 | { |
232 | bool slow; | ||
233 | |||
232 | if (likely(atomic_read(&skb->users) == 1)) | 234 | if (likely(atomic_read(&skb->users) == 1)) |
233 | smp_rmb(); | 235 | smp_rmb(); |
234 | else if (likely(!atomic_dec_and_test(&skb->users))) | 236 | else if (likely(!atomic_dec_and_test(&skb->users))) |
235 | return; | 237 | return; |
236 | 238 | ||
237 | lock_sock_bh(sk); | 239 | slow = lock_sock_fast(sk); |
238 | skb_orphan(skb); | 240 | skb_orphan(skb); |
239 | sk_mem_reclaim_partial(sk); | 241 | sk_mem_reclaim_partial(sk); |
240 | unlock_sock_bh(sk); | 242 | unlock_sock_fast(sk, slow); |
241 | 243 | ||
242 | /* skb is now orphaned, can be freed outside of locked section */ | 244 | /* skb is now orphaned, can be freed outside of locked section */ |
243 | __kfree_skb(skb); | 245 | __kfree_skb(skb); |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index bff37908bd55..6ba1c0eece03 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -934,6 +934,7 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb) | |||
934 | kfree_skb(buff); | 934 | kfree_skb(buff); |
935 | NEIGH_CACHE_STAT_INC(neigh->tbl, unres_discards); | 935 | NEIGH_CACHE_STAT_INC(neigh->tbl, unres_discards); |
936 | } | 936 | } |
937 | skb_dst_force(skb); | ||
937 | __skb_queue_tail(&neigh->arp_queue, skb); | 938 | __skb_queue_tail(&neigh->arp_queue, skb); |
938 | } | 939 | } |
939 | rc = 1; | 940 | rc = 1; |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 7ab86f3a1ea4..1a2af24e9e3d 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -650,11 +650,12 @@ static inline int rtnl_vfinfo_size(const struct net_device *dev) | |||
650 | if (dev->dev.parent && dev_is_pci(dev->dev.parent)) { | 650 | if (dev->dev.parent && dev_is_pci(dev->dev.parent)) { |
651 | 651 | ||
652 | int num_vfs = dev_num_vf(dev->dev.parent); | 652 | int num_vfs = dev_num_vf(dev->dev.parent); |
653 | size_t size = nlmsg_total_size(sizeof(struct nlattr)); | 653 | size_t size = nla_total_size(sizeof(struct nlattr)); |
654 | size += nlmsg_total_size(num_vfs * sizeof(struct nlattr)); | 654 | size += nla_total_size(num_vfs * sizeof(struct nlattr)); |
655 | size += num_vfs * (sizeof(struct ifla_vf_mac) + | 655 | size += num_vfs * |
656 | sizeof(struct ifla_vf_vlan) + | 656 | (nla_total_size(sizeof(struct ifla_vf_mac)) + |
657 | sizeof(struct ifla_vf_tx_rate)); | 657 | nla_total_size(sizeof(struct ifla_vf_vlan)) + |
658 | nla_total_size(sizeof(struct ifla_vf_tx_rate))); | ||
658 | return size; | 659 | return size; |
659 | } else | 660 | } else |
660 | return 0; | 661 | return 0; |
@@ -722,14 +723,13 @@ static int rtnl_vf_ports_fill(struct sk_buff *skb, struct net_device *dev) | |||
722 | 723 | ||
723 | for (vf = 0; vf < dev_num_vf(dev->dev.parent); vf++) { | 724 | for (vf = 0; vf < dev_num_vf(dev->dev.parent); vf++) { |
724 | vf_port = nla_nest_start(skb, IFLA_VF_PORT); | 725 | vf_port = nla_nest_start(skb, IFLA_VF_PORT); |
725 | if (!vf_port) { | 726 | if (!vf_port) |
726 | nla_nest_cancel(skb, vf_ports); | 727 | goto nla_put_failure; |
727 | return -EMSGSIZE; | ||
728 | } | ||
729 | NLA_PUT_U32(skb, IFLA_PORT_VF, vf); | 728 | NLA_PUT_U32(skb, IFLA_PORT_VF, vf); |
730 | err = dev->netdev_ops->ndo_get_vf_port(dev, vf, skb); | 729 | err = dev->netdev_ops->ndo_get_vf_port(dev, vf, skb); |
730 | if (err == -EMSGSIZE) | ||
731 | goto nla_put_failure; | ||
731 | if (err) { | 732 | if (err) { |
732 | nla_put_failure: | ||
733 | nla_nest_cancel(skb, vf_port); | 733 | nla_nest_cancel(skb, vf_port); |
734 | continue; | 734 | continue; |
735 | } | 735 | } |
@@ -739,6 +739,10 @@ nla_put_failure: | |||
739 | nla_nest_end(skb, vf_ports); | 739 | nla_nest_end(skb, vf_ports); |
740 | 740 | ||
741 | return 0; | 741 | return 0; |
742 | |||
743 | nla_put_failure: | ||
744 | nla_nest_cancel(skb, vf_ports); | ||
745 | return -EMSGSIZE; | ||
742 | } | 746 | } |
743 | 747 | ||
744 | static int rtnl_port_self_fill(struct sk_buff *skb, struct net_device *dev) | 748 | static int rtnl_port_self_fill(struct sk_buff *skb, struct net_device *dev) |
@@ -753,7 +757,7 @@ static int rtnl_port_self_fill(struct sk_buff *skb, struct net_device *dev) | |||
753 | err = dev->netdev_ops->ndo_get_vf_port(dev, PORT_SELF_VF, skb); | 757 | err = dev->netdev_ops->ndo_get_vf_port(dev, PORT_SELF_VF, skb); |
754 | if (err) { | 758 | if (err) { |
755 | nla_nest_cancel(skb, port_self); | 759 | nla_nest_cancel(skb, port_self); |
756 | return err; | 760 | return (err == -EMSGSIZE) ? err : 0; |
757 | } | 761 | } |
758 | 762 | ||
759 | nla_nest_end(skb, port_self); | 763 | nla_nest_end(skb, port_self); |
diff --git a/net/core/sock.c b/net/core/sock.c index 37fe9b6adade..2cf7f9f7e775 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -2007,6 +2007,39 @@ void release_sock(struct sock *sk) | |||
2007 | } | 2007 | } |
2008 | EXPORT_SYMBOL(release_sock); | 2008 | EXPORT_SYMBOL(release_sock); |
2009 | 2009 | ||
2010 | /** | ||
2011 | * lock_sock_fast - fast version of lock_sock | ||
2012 | * @sk: socket | ||
2013 | * | ||
2014 | * This version should be used for very small section, where process wont block | ||
2015 | * return false if fast path is taken | ||
2016 | * sk_lock.slock locked, owned = 0, BH disabled | ||
2017 | * return true if slow path is taken | ||
2018 | * sk_lock.slock unlocked, owned = 1, BH enabled | ||
2019 | */ | ||
2020 | bool lock_sock_fast(struct sock *sk) | ||
2021 | { | ||
2022 | might_sleep(); | ||
2023 | spin_lock_bh(&sk->sk_lock.slock); | ||
2024 | |||
2025 | if (!sk->sk_lock.owned) | ||
2026 | /* | ||
2027 | * Note : We must disable BH | ||
2028 | */ | ||
2029 | return false; | ||
2030 | |||
2031 | __lock_sock(sk); | ||
2032 | sk->sk_lock.owned = 1; | ||
2033 | spin_unlock(&sk->sk_lock.slock); | ||
2034 | /* | ||
2035 | * The sk_lock has mutex_lock() semantics here: | ||
2036 | */ | ||
2037 | mutex_acquire(&sk->sk_lock.dep_map, 0, 0, _RET_IP_); | ||
2038 | local_bh_enable(); | ||
2039 | return true; | ||
2040 | } | ||
2041 | EXPORT_SYMBOL(lock_sock_fast); | ||
2042 | |||
2010 | int sock_get_timestamp(struct sock *sk, struct timeval __user *userstamp) | 2043 | int sock_get_timestamp(struct sock *sk, struct timeval __user *userstamp) |
2011 | { | 2044 | { |
2012 | struct timeval tv; | 2045 | struct timeval tv; |
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 45889103b3e2..856123fe32f9 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -1911,7 +1911,7 @@ static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, | |||
1911 | struct rtattr *mp_head; | 1911 | struct rtattr *mp_head; |
1912 | 1912 | ||
1913 | /* If cache is unresolved, don't try to parse IIF and OIF */ | 1913 | /* If cache is unresolved, don't try to parse IIF and OIF */ |
1914 | if (c->mfc_parent > MAXVIFS) | 1914 | if (c->mfc_parent >= MAXVIFS) |
1915 | return -ENOENT; | 1915 | return -ENOENT; |
1916 | 1916 | ||
1917 | if (VIF_EXISTS(mrt, c->mfc_parent)) | 1917 | if (VIF_EXISTS(mrt, c->mfc_parent)) |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index baeec29fe0f1..58585748bdac 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -1063,10 +1063,11 @@ static unsigned int first_packet_length(struct sock *sk) | |||
1063 | spin_unlock_bh(&rcvq->lock); | 1063 | spin_unlock_bh(&rcvq->lock); |
1064 | 1064 | ||
1065 | if (!skb_queue_empty(&list_kill)) { | 1065 | if (!skb_queue_empty(&list_kill)) { |
1066 | lock_sock_bh(sk); | 1066 | bool slow = lock_sock_fast(sk); |
1067 | |||
1067 | __skb_queue_purge(&list_kill); | 1068 | __skb_queue_purge(&list_kill); |
1068 | sk_mem_reclaim_partial(sk); | 1069 | sk_mem_reclaim_partial(sk); |
1069 | unlock_sock_bh(sk); | 1070 | unlock_sock_fast(sk, slow); |
1070 | } | 1071 | } |
1071 | return res; | 1072 | return res; |
1072 | } | 1073 | } |
@@ -1123,6 +1124,7 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
1123 | int peeked; | 1124 | int peeked; |
1124 | int err; | 1125 | int err; |
1125 | int is_udplite = IS_UDPLITE(sk); | 1126 | int is_udplite = IS_UDPLITE(sk); |
1127 | bool slow; | ||
1126 | 1128 | ||
1127 | /* | 1129 | /* |
1128 | * Check any passed addresses | 1130 | * Check any passed addresses |
@@ -1197,10 +1199,10 @@ out: | |||
1197 | return err; | 1199 | return err; |
1198 | 1200 | ||
1199 | csum_copy_err: | 1201 | csum_copy_err: |
1200 | lock_sock_bh(sk); | 1202 | slow = lock_sock_fast(sk); |
1201 | if (!skb_kill_datagram(sk, skb, flags)) | 1203 | if (!skb_kill_datagram(sk, skb, flags)) |
1202 | UDP_INC_STATS_USER(sock_net(sk), UDP_MIB_INERRORS, is_udplite); | 1204 | UDP_INC_STATS_USER(sock_net(sk), UDP_MIB_INERRORS, is_udplite); |
1203 | unlock_sock_bh(sk); | 1205 | unlock_sock_fast(sk, slow); |
1204 | 1206 | ||
1205 | if (noblock) | 1207 | if (noblock) |
1206 | return -EAGAIN; | 1208 | return -EAGAIN; |
@@ -1625,9 +1627,9 @@ int udp_rcv(struct sk_buff *skb) | |||
1625 | 1627 | ||
1626 | void udp_destroy_sock(struct sock *sk) | 1628 | void udp_destroy_sock(struct sock *sk) |
1627 | { | 1629 | { |
1628 | lock_sock_bh(sk); | 1630 | bool slow = lock_sock_fast(sk); |
1629 | udp_flush_pending_frames(sk); | 1631 | udp_flush_pending_frames(sk); |
1630 | unlock_sock_bh(sk); | 1632 | unlock_sock_fast(sk, slow); |
1631 | } | 1633 | } |
1632 | 1634 | ||
1633 | /* | 1635 | /* |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index cd963f64e27c..89425af0684c 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -507,7 +507,7 @@ int ip6_forward(struct sk_buff *skb) | |||
507 | if (mtu < IPV6_MIN_MTU) | 507 | if (mtu < IPV6_MIN_MTU) |
508 | mtu = IPV6_MIN_MTU; | 508 | mtu = IPV6_MIN_MTU; |
509 | 509 | ||
510 | if (skb->len > mtu) { | 510 | if (skb->len > mtu && !skb_is_gso(skb)) { |
511 | /* Again, force OUTPUT device used as source address */ | 511 | /* Again, force OUTPUT device used as source address */ |
512 | skb->dev = dst->dev; | 512 | skb->dev = dst->dev; |
513 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); | 513 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); |
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index bd9e7d3e9c8e..073071f2b75b 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
@@ -2017,7 +2017,7 @@ static int __ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb, | |||
2017 | struct rtattr *mp_head; | 2017 | struct rtattr *mp_head; |
2018 | 2018 | ||
2019 | /* If cache is unresolved, don't try to parse IIF and OIF */ | 2019 | /* If cache is unresolved, don't try to parse IIF and OIF */ |
2020 | if (c->mf6c_parent > MAXMIFS) | 2020 | if (c->mf6c_parent >= MAXMIFS) |
2021 | return -ENOENT; | 2021 | return -ENOENT; |
2022 | 2022 | ||
2023 | if (MIF_EXISTS(mrt, c->mf6c_parent)) | 2023 | if (MIF_EXISTS(mrt, c->mf6c_parent)) |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 3d7a2c0b836a..87be58673b55 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -328,6 +328,7 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk, | |||
328 | int err; | 328 | int err; |
329 | int is_udplite = IS_UDPLITE(sk); | 329 | int is_udplite = IS_UDPLITE(sk); |
330 | int is_udp4; | 330 | int is_udp4; |
331 | bool slow; | ||
331 | 332 | ||
332 | if (addr_len) | 333 | if (addr_len) |
333 | *addr_len=sizeof(struct sockaddr_in6); | 334 | *addr_len=sizeof(struct sockaddr_in6); |
@@ -424,7 +425,7 @@ out: | |||
424 | return err; | 425 | return err; |
425 | 426 | ||
426 | csum_copy_err: | 427 | csum_copy_err: |
427 | lock_sock_bh(sk); | 428 | slow = lock_sock_fast(sk); |
428 | if (!skb_kill_datagram(sk, skb, flags)) { | 429 | if (!skb_kill_datagram(sk, skb, flags)) { |
429 | if (is_udp4) | 430 | if (is_udp4) |
430 | UDP_INC_STATS_USER(sock_net(sk), | 431 | UDP_INC_STATS_USER(sock_net(sk), |
@@ -433,7 +434,7 @@ csum_copy_err: | |||
433 | UDP6_INC_STATS_USER(sock_net(sk), | 434 | UDP6_INC_STATS_USER(sock_net(sk), |
434 | UDP_MIB_INERRORS, is_udplite); | 435 | UDP_MIB_INERRORS, is_udplite); |
435 | } | 436 | } |
436 | unlock_sock_bh(sk); | 437 | unlock_sock_fast(sk, slow); |
437 | 438 | ||
438 | if (flags & MSG_DONTWAIT) | 439 | if (flags & MSG_DONTWAIT) |
439 | return -EAGAIN; | 440 | return -EAGAIN; |
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index c8b4599a752e..9637e45744fa 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c | |||
@@ -1619,7 +1619,7 @@ static void iucv_callback_rx(struct iucv_path *path, struct iucv_message *msg) | |||
1619 | save_message: | 1619 | save_message: |
1620 | save_msg = kzalloc(sizeof(struct sock_msg_q), GFP_ATOMIC | GFP_DMA); | 1620 | save_msg = kzalloc(sizeof(struct sock_msg_q), GFP_ATOMIC | GFP_DMA); |
1621 | if (!save_msg) | 1621 | if (!save_msg) |
1622 | return; | 1622 | goto out_unlock; |
1623 | save_msg->path = path; | 1623 | save_msg->path = path; |
1624 | save_msg->msg = *msg; | 1624 | save_msg->msg = *msg; |
1625 | 1625 | ||
diff --git a/net/netfilter/xt_TEE.c b/net/netfilter/xt_TEE.c index d7920d9f49e9..859d9fd429c8 100644 --- a/net/netfilter/xt_TEE.c +++ b/net/netfilter/xt_TEE.c | |||
@@ -76,7 +76,7 @@ tee_tg_route4(struct sk_buff *skb, const struct xt_tee_tginfo *info) | |||
76 | if (ip_route_output_key(net, &rt, &fl) != 0) | 76 | if (ip_route_output_key(net, &rt, &fl) != 0) |
77 | return false; | 77 | return false; |
78 | 78 | ||
79 | dst_release(skb_dst(skb)); | 79 | skb_dst_drop(skb); |
80 | skb_dst_set(skb, &rt->u.dst); | 80 | skb_dst_set(skb, &rt->u.dst); |
81 | skb->dev = rt->u.dst.dev; | 81 | skb->dev = rt->u.dst.dev; |
82 | skb->protocol = htons(ETH_P_IP); | 82 | skb->protocol = htons(ETH_P_IP); |
@@ -157,7 +157,7 @@ tee_tg_route6(struct sk_buff *skb, const struct xt_tee_tginfo *info) | |||
157 | if (dst == NULL) | 157 | if (dst == NULL) |
158 | return false; | 158 | return false; |
159 | 159 | ||
160 | dst_release(skb_dst(skb)); | 160 | skb_dst_drop(skb); |
161 | skb_dst_set(skb, dst); | 161 | skb_dst_set(skb, dst); |
162 | skb->dev = dst->dev; | 162 | skb->dev = dst->dev; |
163 | skb->protocol = htons(ETH_P_IPV6); | 163 | skb->protocol = htons(ETH_P_IPV6); |
diff --git a/sound/mips/au1x00.c b/sound/mips/au1x00.c index 3e763d6a5d67..446cf9748664 100644 --- a/sound/mips/au1x00.c +++ b/sound/mips/au1x00.c | |||
@@ -516,6 +516,7 @@ get the interrupt driven case to work efficiently */ | |||
516 | break; | 516 | break; |
517 | if (i == 0x5000) { | 517 | if (i == 0x5000) { |
518 | printk(KERN_ERR "au1000 AC97: AC97 command read timeout\n"); | 518 | printk(KERN_ERR "au1000 AC97: AC97 command read timeout\n"); |
519 | spin_unlock(&au1000->ac97_lock); | ||
519 | return 0; | 520 | return 0; |
520 | } | 521 | } |
521 | 522 | ||
diff --git a/sound/oss/dmasound/dmasound_atari.c b/sound/oss/dmasound/dmasound_atari.c index 1f4774123064..13c214466d3b 100644 --- a/sound/oss/dmasound/dmasound_atari.c +++ b/sound/oss/dmasound/dmasound_atari.c | |||
@@ -1277,7 +1277,7 @@ static irqreturn_t AtaInterrupt(int irq, void *dummy) | |||
1277 | * (almost) like on the TT. | 1277 | * (almost) like on the TT. |
1278 | */ | 1278 | */ |
1279 | write_sq_ignore_int = 0; | 1279 | write_sq_ignore_int = 0; |
1280 | return IRQ_HANDLED; | 1280 | goto out; |
1281 | } | 1281 | } |
1282 | 1282 | ||
1283 | if (!write_sq.active) { | 1283 | if (!write_sq.active) { |
@@ -1285,7 +1285,7 @@ static irqreturn_t AtaInterrupt(int irq, void *dummy) | |||
1285 | * the sq variables, so better don't do anything here. | 1285 | * the sq variables, so better don't do anything here. |
1286 | */ | 1286 | */ |
1287 | WAKE_UP(write_sq.sync_queue); | 1287 | WAKE_UP(write_sq.sync_queue); |
1288 | return IRQ_HANDLED; | 1288 | goto out; |
1289 | } | 1289 | } |
1290 | 1290 | ||
1291 | /* Probably ;) one frame is finished. Well, in fact it may be that a | 1291 | /* Probably ;) one frame is finished. Well, in fact it may be that a |
@@ -1322,6 +1322,7 @@ static irqreturn_t AtaInterrupt(int irq, void *dummy) | |||
1322 | /* We are not playing after AtaPlay(), so there | 1322 | /* We are not playing after AtaPlay(), so there |
1323 | is nothing to play any more. Wake up a process | 1323 | is nothing to play any more. Wake up a process |
1324 | waiting for audio output to drain. */ | 1324 | waiting for audio output to drain. */ |
1325 | out: | ||
1325 | spin_unlock(&dmasound.lock); | 1326 | spin_unlock(&dmasound.lock); |
1326 | return IRQ_HANDLED; | 1327 | return IRQ_HANDLED; |
1327 | } | 1328 | } |
diff --git a/sound/pci/asihpi/hpi.h b/sound/pci/asihpi/hpi.h index 99400de6c075..0173bbe62b67 100644 --- a/sound/pci/asihpi/hpi.h +++ b/sound/pci/asihpi/hpi.h | |||
@@ -50,7 +50,7 @@ i.e 3.05.02 is a development version | |||
50 | #define HPI_VER_RELEASE(v) ((int)(v & 0xFF)) | 50 | #define HPI_VER_RELEASE(v) ((int)(v & 0xFF)) |
51 | 51 | ||
52 | /* Use single digits for versions less that 10 to avoid octal. */ | 52 | /* Use single digits for versions less that 10 to avoid octal. */ |
53 | #define HPI_VER HPI_VERSION_CONSTRUCTOR(4L, 3, 18) | 53 | #define HPI_VER HPI_VERSION_CONSTRUCTOR(4L, 3, 25) |
54 | 54 | ||
55 | /* Library version as documented in hpi-api-versions.txt */ | 55 | /* Library version as documented in hpi-api-versions.txt */ |
56 | #define HPI_LIB_VER HPI_VERSION_CONSTRUCTOR(9, 0, 0) | 56 | #define HPI_LIB_VER HPI_VERSION_CONSTRUCTOR(9, 0, 0) |
@@ -1632,6 +1632,12 @@ u16 hpi_tuner_get_hd_radio_sdk_version(const struct hpi_hsubsys *ph_subsys, | |||
1632 | u16 hpi_tuner_get_hd_radio_signal_quality(const struct hpi_hsubsys *ph_subsys, | 1632 | u16 hpi_tuner_get_hd_radio_signal_quality(const struct hpi_hsubsys *ph_subsys, |
1633 | u32 h_control, u32 *pquality); | 1633 | u32 h_control, u32 *pquality); |
1634 | 1634 | ||
1635 | u16 hpi_tuner_get_hd_radio_signal_blend(const struct hpi_hsubsys *ph_subsys, | ||
1636 | u32 h_control, u32 *pblend); | ||
1637 | |||
1638 | u16 hpi_tuner_set_hd_radio_signal_blend(const struct hpi_hsubsys *ph_subsys, | ||
1639 | u32 h_control, const u32 blend); | ||
1640 | |||
1635 | /****************************/ | 1641 | /****************************/ |
1636 | /* PADs control */ | 1642 | /* PADs control */ |
1637 | /****************************/ | 1643 | /****************************/ |
diff --git a/sound/pci/asihpi/hpi6000.c b/sound/pci/asihpi/hpi6000.c index 839ecb2e4b64..12dab5e4892c 100644 --- a/sound/pci/asihpi/hpi6000.c +++ b/sound/pci/asihpi/hpi6000.c | |||
@@ -691,9 +691,6 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao, | |||
691 | case 0x6200: | 691 | case 0x6200: |
692 | boot_load_family = HPI_ADAPTER_FAMILY_ASI(0x6200); | 692 | boot_load_family = HPI_ADAPTER_FAMILY_ASI(0x6200); |
693 | break; | 693 | break; |
694 | case 0x8800: | ||
695 | boot_load_family = HPI_ADAPTER_FAMILY_ASI(0x8800); | ||
696 | break; | ||
697 | default: | 694 | default: |
698 | return HPI6000_ERROR_UNHANDLED_SUBSYS_ID; | 695 | return HPI6000_ERROR_UNHANDLED_SUBSYS_ID; |
699 | } | 696 | } |
@@ -1775,7 +1772,6 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm, | |||
1775 | u16 error = 0; | 1772 | u16 error = 0; |
1776 | u16 dsp_index = 0; | 1773 | u16 dsp_index = 0; |
1777 | u16 num_dsp = ((struct hpi_hw_obj *)pao->priv)->num_dsp; | 1774 | u16 num_dsp = ((struct hpi_hw_obj *)pao->priv)->num_dsp; |
1778 | hpios_dsplock_lock(pao); | ||
1779 | 1775 | ||
1780 | if (num_dsp < 2) | 1776 | if (num_dsp < 2) |
1781 | dsp_index = 0; | 1777 | dsp_index = 0; |
@@ -1796,6 +1792,8 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm, | |||
1796 | } | 1792 | } |
1797 | } | 1793 | } |
1798 | } | 1794 | } |
1795 | |||
1796 | hpios_dsplock_lock(pao); | ||
1799 | error = hpi6000_message_response_sequence(pao, dsp_index, phm, phr); | 1797 | error = hpi6000_message_response_sequence(pao, dsp_index, phm, phr); |
1800 | 1798 | ||
1801 | /* maybe an error response */ | 1799 | /* maybe an error response */ |
diff --git a/sound/pci/asihpi/hpi6205.c b/sound/pci/asihpi/hpi6205.c index 5e88c1fc2b9e..e89991ea3543 100644 --- a/sound/pci/asihpi/hpi6205.c +++ b/sound/pci/asihpi/hpi6205.c | |||
@@ -966,23 +966,16 @@ static void outstream_write(struct hpi_adapter_obj *pao, | |||
966 | status = &interface->outstream_host_buffer_status[phm->obj_index]; | 966 | status = &interface->outstream_host_buffer_status[phm->obj_index]; |
967 | 967 | ||
968 | if (phw->flag_outstream_just_reset[phm->obj_index]) { | 968 | if (phw->flag_outstream_just_reset[phm->obj_index]) { |
969 | /* Format can only change after reset. Must tell DSP. */ | ||
970 | u16 function = phm->function; | ||
971 | phw->flag_outstream_just_reset[phm->obj_index] = 0; | ||
972 | phm->function = HPI_OSTREAM_SET_FORMAT; | ||
973 | hw_message(pao, phm, phr); /* send the format to the DSP */ | ||
974 | phm->function = function; | ||
975 | if (phr->error) | ||
976 | return; | ||
977 | } | ||
978 | #if 1 | ||
979 | if (phw->flag_outstream_just_reset[phm->obj_index]) { | ||
980 | /* First OutStremWrite() call following reset will write data to the | 969 | /* First OutStremWrite() call following reset will write data to the |
981 | adapter's buffers, reducing delay before stream can start | 970 | adapter's buffers, reducing delay before stream can start. The DSP |
971 | takes care of setting the stream data format using format information | ||
972 | embedded in phm. | ||
982 | */ | 973 | */ |
983 | int partial_write = 0; | 974 | int partial_write = 0; |
984 | unsigned int original_size = 0; | 975 | unsigned int original_size = 0; |
985 | 976 | ||
977 | phw->flag_outstream_just_reset[phm->obj_index] = 0; | ||
978 | |||
986 | /* Send the first buffer to the DSP the old way. */ | 979 | /* Send the first buffer to the DSP the old way. */ |
987 | /* Limit size of first transfer - */ | 980 | /* Limit size of first transfer - */ |
988 | /* expect that this will not usually be triggered. */ | 981 | /* expect that this will not usually be triggered. */ |
@@ -1012,7 +1005,6 @@ static void outstream_write(struct hpi_adapter_obj *pao, | |||
1012 | original_size - HPI6205_SIZEOF_DATA; | 1005 | original_size - HPI6205_SIZEOF_DATA; |
1013 | phm->u.d.u.data.pb_data += HPI6205_SIZEOF_DATA; | 1006 | phm->u.d.u.data.pb_data += HPI6205_SIZEOF_DATA; |
1014 | } | 1007 | } |
1015 | #endif | ||
1016 | 1008 | ||
1017 | space_available = outstream_get_space_available(status); | 1009 | space_available = outstream_get_space_available(status); |
1018 | if (space_available < (long)phm->u.d.u.data.data_size) { | 1010 | if (space_available < (long)phm->u.d.u.data.data_size) { |
@@ -1369,6 +1361,9 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao, | |||
1369 | case HPI_ADAPTER_FAMILY_ASI(0x6500): | 1361 | case HPI_ADAPTER_FAMILY_ASI(0x6500): |
1370 | firmware_id = HPI_ADAPTER_FAMILY_ASI(0x6600); | 1362 | firmware_id = HPI_ADAPTER_FAMILY_ASI(0x6600); |
1371 | break; | 1363 | break; |
1364 | case HPI_ADAPTER_FAMILY_ASI(0x8800): | ||
1365 | firmware_id = HPI_ADAPTER_FAMILY_ASI(0x8900); | ||
1366 | break; | ||
1372 | } | 1367 | } |
1373 | boot_code_id[1] = firmware_id; | 1368 | boot_code_id[1] = firmware_id; |
1374 | 1369 | ||
diff --git a/sound/pci/asihpi/hpi_internal.h b/sound/pci/asihpi/hpi_internal.h index f1cd6f1a0d44..fdd0ce02aa68 100644 --- a/sound/pci/asihpi/hpi_internal.h +++ b/sound/pci/asihpi/hpi_internal.h | |||
@@ -232,6 +232,8 @@ enum HPI_BUSES { | |||
232 | #define HPI_TUNER_HDRADIO_SDK_VERSION HPI_CTL_ATTR(TUNER, 13) | 232 | #define HPI_TUNER_HDRADIO_SDK_VERSION HPI_CTL_ATTR(TUNER, 13) |
233 | /** HD Radio DSP firmware version. */ | 233 | /** HD Radio DSP firmware version. */ |
234 | #define HPI_TUNER_HDRADIO_DSP_VERSION HPI_CTL_ATTR(TUNER, 14) | 234 | #define HPI_TUNER_HDRADIO_DSP_VERSION HPI_CTL_ATTR(TUNER, 14) |
235 | /** HD Radio signal blend (force analog, or automatic). */ | ||
236 | #define HPI_TUNER_HDRADIO_BLEND HPI_CTL_ATTR(TUNER, 15) | ||
235 | 237 | ||
236 | /** \} */ | 238 | /** \} */ |
237 | 239 | ||
@@ -478,8 +480,10 @@ Threshold is a -ve number in units of dB/100, | |||
478 | 480 | ||
479 | /** First 2 hex digits define the adapter family */ | 481 | /** First 2 hex digits define the adapter family */ |
480 | #define HPI_ADAPTER_FAMILY_MASK 0xff00 | 482 | #define HPI_ADAPTER_FAMILY_MASK 0xff00 |
483 | #define HPI_MODULE_FAMILY_MASK 0xfff0 | ||
481 | 484 | ||
482 | #define HPI_ADAPTER_FAMILY_ASI(f) (f & HPI_ADAPTER_FAMILY_MASK) | 485 | #define HPI_ADAPTER_FAMILY_ASI(f) (f & HPI_ADAPTER_FAMILY_MASK) |
486 | #define HPI_MODULE_FAMILY_ASI(f) (f & HPI_MODULE_FAMILY_MASK) | ||
483 | #define HPI_ADAPTER_ASI(f) (f) | 487 | #define HPI_ADAPTER_ASI(f) (f) |
484 | 488 | ||
485 | /******************************************* message types */ | 489 | /******************************************* message types */ |
@@ -970,6 +974,7 @@ struct hpi_control_union_msg { | |||
970 | u32 mode; | 974 | u32 mode; |
971 | u32 value; | 975 | u32 value; |
972 | } mode; | 976 | } mode; |
977 | u32 blend; | ||
973 | } tuner; | 978 | } tuner; |
974 | } u; | 979 | } u; |
975 | }; | 980 | }; |
diff --git a/sound/pci/asihpi/hpicmn.c b/sound/pci/asihpi/hpicmn.c index 565102cae4f8..fcd64539d9ef 100644 --- a/sound/pci/asihpi/hpicmn.c +++ b/sound/pci/asihpi/hpicmn.c | |||
@@ -347,20 +347,15 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache, | |||
347 | found = 0; | 347 | found = 0; |
348 | break; | 348 | break; |
349 | case HPI_CONTROL_TUNER: | 349 | case HPI_CONTROL_TUNER: |
350 | { | 350 | if (phm->u.c.attribute == HPI_TUNER_FREQ) |
351 | struct hpi_control_cache_single *pCT = | 351 | phr->u.c.param1 = pC->u.t.freq_ink_hz; |
352 | (struct hpi_control_cache_single *)pI; | 352 | else if (phm->u.c.attribute == HPI_TUNER_BAND) |
353 | if (phm->u.c.attribute == HPI_TUNER_FREQ) | 353 | phr->u.c.param1 = pC->u.t.band; |
354 | phr->u.c.param1 = pCT->u.t.freq_ink_hz; | 354 | else if ((phm->u.c.attribute == HPI_TUNER_LEVEL) |
355 | else if (phm->u.c.attribute == HPI_TUNER_BAND) | 355 | && (phm->u.c.param1 == HPI_TUNER_LEVEL_AVERAGE)) |
356 | phr->u.c.param1 = pCT->u.t.band; | 356 | phr->u.c.param1 = pC->u.t.level; |
357 | else if ((phm->u.c.attribute == HPI_TUNER_LEVEL) | 357 | else |
358 | && (phm->u.c.param1 == | 358 | found = 0; |
359 | HPI_TUNER_LEVEL_AVERAGE)) | ||
360 | phr->u.c.param1 = pCT->u.t.level; | ||
361 | else | ||
362 | found = 0; | ||
363 | } | ||
364 | break; | 359 | break; |
365 | case HPI_CONTROL_AESEBU_RECEIVER: | 360 | case HPI_CONTROL_AESEBU_RECEIVER: |
366 | if (phm->u.c.attribute == HPI_AESEBURX_ERRORSTATUS) | 361 | if (phm->u.c.attribute == HPI_AESEBURX_ERRORSTATUS) |
@@ -503,6 +498,9 @@ void hpi_sync_control_cache(struct hpi_control_cache *p_cache, | |||
503 | struct hpi_control_cache_single *pC; | 498 | struct hpi_control_cache_single *pC; |
504 | struct hpi_control_cache_info *pI; | 499 | struct hpi_control_cache_info *pI; |
505 | 500 | ||
501 | if (phr->error) | ||
502 | return; | ||
503 | |||
506 | if (!find_control(phm, p_cache, &pI, &control_index)) | 504 | if (!find_control(phm, p_cache, &pI, &control_index)) |
507 | return; | 505 | return; |
508 | 506 | ||
@@ -520,8 +518,6 @@ void hpi_sync_control_cache(struct hpi_control_cache *p_cache, | |||
520 | break; | 518 | break; |
521 | case HPI_CONTROL_MULTIPLEXER: | 519 | case HPI_CONTROL_MULTIPLEXER: |
522 | /* mux does not return its setting on Set command. */ | 520 | /* mux does not return its setting on Set command. */ |
523 | if (phr->error) | ||
524 | return; | ||
525 | if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) { | 521 | if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) { |
526 | pC->u.x.source_node_type = (u16)phm->u.c.param1; | 522 | pC->u.x.source_node_type = (u16)phm->u.c.param1; |
527 | pC->u.x.source_node_index = (u16)phm->u.c.param2; | 523 | pC->u.x.source_node_index = (u16)phm->u.c.param2; |
@@ -529,8 +525,6 @@ void hpi_sync_control_cache(struct hpi_control_cache *p_cache, | |||
529 | break; | 525 | break; |
530 | case HPI_CONTROL_CHANNEL_MODE: | 526 | case HPI_CONTROL_CHANNEL_MODE: |
531 | /* mode does not return its setting on Set command. */ | 527 | /* mode does not return its setting on Set command. */ |
532 | if (phr->error) | ||
533 | return; | ||
534 | if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE) | 528 | if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE) |
535 | pC->u.m.mode = (u16)phm->u.c.param1; | 529 | pC->u.m.mode = (u16)phm->u.c.param1; |
536 | break; | 530 | break; |
@@ -545,20 +539,14 @@ void hpi_sync_control_cache(struct hpi_control_cache *p_cache, | |||
545 | pC->u.phantom_power.state = (u16)phm->u.c.param1; | 539 | pC->u.phantom_power.state = (u16)phm->u.c.param1; |
546 | break; | 540 | break; |
547 | case HPI_CONTROL_AESEBU_TRANSMITTER: | 541 | case HPI_CONTROL_AESEBU_TRANSMITTER: |
548 | if (phr->error) | ||
549 | return; | ||
550 | if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT) | 542 | if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT) |
551 | pC->u.aes3tx.format = phm->u.c.param1; | 543 | pC->u.aes3tx.format = phm->u.c.param1; |
552 | break; | 544 | break; |
553 | case HPI_CONTROL_AESEBU_RECEIVER: | 545 | case HPI_CONTROL_AESEBU_RECEIVER: |
554 | if (phr->error) | ||
555 | return; | ||
556 | if (phm->u.c.attribute == HPI_AESEBURX_FORMAT) | 546 | if (phm->u.c.attribute == HPI_AESEBURX_FORMAT) |
557 | pC->u.aes3rx.source = phm->u.c.param1; | 547 | pC->u.aes3rx.source = phm->u.c.param1; |
558 | break; | 548 | break; |
559 | case HPI_CONTROL_SAMPLECLOCK: | 549 | case HPI_CONTROL_SAMPLECLOCK: |
560 | if (phr->error) | ||
561 | return; | ||
562 | if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE) | 550 | if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE) |
563 | pC->u.clk.source = (u16)phm->u.c.param1; | 551 | pC->u.clk.source = (u16)phm->u.c.param1; |
564 | else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX) | 552 | else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX) |
@@ -590,7 +578,7 @@ struct hpi_control_cache *hpi_alloc_control_cache(const u32 | |||
590 | 578 | ||
591 | void hpi_free_control_cache(struct hpi_control_cache *p_cache) | 579 | void hpi_free_control_cache(struct hpi_control_cache *p_cache) |
592 | { | 580 | { |
593 | if ((p_cache->init) && (p_cache->p_info)) { | 581 | if (p_cache->init) { |
594 | kfree(p_cache->p_info); | 582 | kfree(p_cache->p_info); |
595 | p_cache->p_info = NULL; | 583 | p_cache->p_info = NULL; |
596 | p_cache->init = 0; | 584 | p_cache->init = 0; |
diff --git a/sound/pci/asihpi/hpifunc.c b/sound/pci/asihpi/hpifunc.c index eda26b312324..298eef3e20e9 100644 --- a/sound/pci/asihpi/hpifunc.c +++ b/sound/pci/asihpi/hpifunc.c | |||
@@ -2946,6 +2946,20 @@ u16 hpi_tuner_get_hd_radio_signal_quality(const struct hpi_hsubsys *ph_subsys, | |||
2946 | HPI_TUNER_HDRADIO_SIGNAL_QUALITY, 0, 0, pquality, NULL); | 2946 | HPI_TUNER_HDRADIO_SIGNAL_QUALITY, 0, 0, pquality, NULL); |
2947 | } | 2947 | } |
2948 | 2948 | ||
2949 | u16 hpi_tuner_get_hd_radio_signal_blend(const struct hpi_hsubsys *ph_subsys, | ||
2950 | u32 h_control, u32 *pblend) | ||
2951 | { | ||
2952 | return hpi_control_param_get(ph_subsys, h_control, | ||
2953 | HPI_TUNER_HDRADIO_BLEND, 0, 0, pblend, NULL); | ||
2954 | } | ||
2955 | |||
2956 | u16 hpi_tuner_set_hd_radio_signal_blend(const struct hpi_hsubsys *ph_subsys, | ||
2957 | u32 h_control, const u32 blend) | ||
2958 | { | ||
2959 | return hpi_control_param_set(ph_subsys, h_control, | ||
2960 | HPI_TUNER_HDRADIO_BLEND, blend, 0); | ||
2961 | } | ||
2962 | |||
2949 | u16 hpi_tuner_getRDS(const struct hpi_hsubsys *ph_subsys, u32 h_control, | 2963 | u16 hpi_tuner_getRDS(const struct hpi_hsubsys *ph_subsys, u32 h_control, |
2950 | char *p_data) | 2964 | char *p_data) |
2951 | { | 2965 | { |
@@ -3266,8 +3280,7 @@ u16 hpi_entity_find_next(struct hpi_entity *container_entity, | |||
3266 | 3280 | ||
3267 | void hpi_entity_free(struct hpi_entity *entity) | 3281 | void hpi_entity_free(struct hpi_entity *entity) |
3268 | { | 3282 | { |
3269 | if (entity != NULL) | 3283 | kfree(entity); |
3270 | kfree(entity); | ||
3271 | } | 3284 | } |
3272 | 3285 | ||
3273 | static u16 hpi_entity_alloc_and_copy(struct hpi_entity *src, | 3286 | static u16 hpi_entity_alloc_and_copy(struct hpi_entity *src, |
diff --git a/sound/pci/asihpi/hpios.c b/sound/pci/asihpi/hpios.c index de615cfdb950..742ee12a9e17 100644 --- a/sound/pci/asihpi/hpios.c +++ b/sound/pci/asihpi/hpios.c | |||
@@ -89,26 +89,3 @@ u16 hpios_locked_mem_free(struct consistent_dma_area *p_mem_area) | |||
89 | void hpios_locked_mem_free_all(void) | 89 | void hpios_locked_mem_free_all(void) |
90 | { | 90 | { |
91 | } | 91 | } |
92 | |||
93 | void __iomem *hpios_map_io(struct pci_dev *pci_dev, int idx, | ||
94 | unsigned int length) | ||
95 | { | ||
96 | HPI_DEBUG_LOG(DEBUG, "mapping %d %s %08llx-%08llx %04llx len 0x%x\n", | ||
97 | idx, pci_dev->resource[idx].name, | ||
98 | (unsigned long long)pci_resource_start(pci_dev, idx), | ||
99 | (unsigned long long)pci_resource_end(pci_dev, idx), | ||
100 | (unsigned long long)pci_resource_flags(pci_dev, idx), length); | ||
101 | |||
102 | if (!(pci_resource_flags(pci_dev, idx) & IORESOURCE_MEM)) { | ||
103 | HPI_DEBUG_LOG(ERROR, "not an io memory resource\n"); | ||
104 | return NULL; | ||
105 | } | ||
106 | |||
107 | if (length > pci_resource_len(pci_dev, idx)) { | ||
108 | HPI_DEBUG_LOG(ERROR, "resource too small for requested %d \n", | ||
109 | length); | ||
110 | return NULL; | ||
111 | } | ||
112 | |||
113 | return ioremap(pci_resource_start(pci_dev, idx), length); | ||
114 | } | ||
diff --git a/sound/pci/asihpi/hpios.h b/sound/pci/asihpi/hpios.h index a62c3f1e5f09..370f39b43f85 100644 --- a/sound/pci/asihpi/hpios.h +++ b/sound/pci/asihpi/hpios.h | |||
@@ -166,13 +166,4 @@ struct hpi_adapter { | |||
166 | void __iomem *ap_remapped_mem_base[HPI_MAX_ADAPTER_MEM_SPACES]; | 166 | void __iomem *ap_remapped_mem_base[HPI_MAX_ADAPTER_MEM_SPACES]; |
167 | }; | 167 | }; |
168 | 168 | ||
169 | static inline void hpios_unmap_io(void __iomem *addr, | ||
170 | unsigned long size) | ||
171 | { | ||
172 | iounmap(addr); | ||
173 | } | ||
174 | |||
175 | void __iomem *hpios_map_io(struct pci_dev *pci_dev, int idx, | ||
176 | unsigned int length); | ||
177 | |||
178 | #endif | 169 | #endif |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 77e22c2a8caa..dc79564fea30 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -2288,8 +2288,10 @@ static struct snd_pci_quirk position_fix_list[] __devinitdata = { | |||
2288 | SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB), | 2288 | SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB), |
2289 | SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB), | 2289 | SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB), |
2290 | SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), | 2290 | SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), |
2291 | SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB), | ||
2291 | SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB), | 2292 | SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB), |
2292 | SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba A100-259", POS_FIX_LPIB), | 2293 | SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba A100-259", POS_FIX_LPIB), |
2294 | SND_PCI_QUIRK(0x1297, 0x3166, "Shuttle", POS_FIX_LPIB), | ||
2293 | SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB), | 2295 | SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB), |
2294 | SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB), | 2296 | SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB), |
2295 | SND_PCI_QUIRK(0x1565, 0x820f, "Biostar Microtech", POS_FIX_LPIB), | 2297 | SND_PCI_QUIRK(0x1565, 0x820f, "Biostar Microtech", POS_FIX_LPIB), |
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index e863649d31f5..2bf2cb5da956 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -2975,6 +2975,8 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { | |||
2975 | SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5), | 2975 | SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5), |
2976 | SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5), | 2976 | SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5), |
2977 | SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD), | 2977 | SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD), |
2978 | SND_PCI_QUIRK(0x17aa, 0x21b3, "Thinkpad Edge 13 (197)", CXT5066_IDEAPAD), | ||
2979 | SND_PCI_QUIRK(0x17aa, 0x21b4, "Thinkpad Edge", CXT5066_IDEAPAD), | ||
2978 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD), | 2980 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD), |
2979 | SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD), | 2981 | SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD), |
2980 | {} | 2982 | {} |
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index 8ae20208e7be..0221ca79b3ae 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c | |||
@@ -426,8 +426,8 @@ static const struct soc_enum wm8350_enum[] = { | |||
426 | SOC_ENUM_SINGLE(WM8350_INPUT_MIXER_VOLUME, 15, 2, wm8350_lr), | 426 | SOC_ENUM_SINGLE(WM8350_INPUT_MIXER_VOLUME, 15, 2, wm8350_lr), |
427 | }; | 427 | }; |
428 | 428 | ||
429 | static DECLARE_TLV_DB_LINEAR(pre_amp_tlv, -1200, 3525); | 429 | static DECLARE_TLV_DB_SCALE(pre_amp_tlv, -1200, 3525, 0); |
430 | static DECLARE_TLV_DB_LINEAR(out_pga_tlv, -5700, 600); | 430 | static DECLARE_TLV_DB_SCALE(out_pga_tlv, -5700, 600, 0); |
431 | static DECLARE_TLV_DB_SCALE(dac_pcm_tlv, -7163, 36, 1); | 431 | static DECLARE_TLV_DB_SCALE(dac_pcm_tlv, -7163, 36, 1); |
432 | static DECLARE_TLV_DB_SCALE(adc_pcm_tlv, -12700, 50, 1); | 432 | static DECLARE_TLV_DB_SCALE(adc_pcm_tlv, -12700, 50, 1); |
433 | static DECLARE_TLV_DB_SCALE(out_mix_tlv, -1500, 300, 1); | 433 | static DECLARE_TLV_DB_SCALE(out_mix_tlv, -1500, 300, 1); |
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c index 7f5d080536a0..8f294066b0ed 100644 --- a/sound/soc/codecs/wm8400.c +++ b/sound/soc/codecs/wm8400.c | |||
@@ -107,21 +107,21 @@ static void wm8400_codec_reset(struct snd_soc_codec *codec) | |||
107 | wm8400_reset_codec_reg_cache(wm8400->wm8400); | 107 | wm8400_reset_codec_reg_cache(wm8400->wm8400); |
108 | } | 108 | } |
109 | 109 | ||
110 | static const DECLARE_TLV_DB_LINEAR(rec_mix_tlv, -1500, 600); | 110 | static const DECLARE_TLV_DB_SCALE(rec_mix_tlv, -1500, 600, 0); |
111 | 111 | ||
112 | static const DECLARE_TLV_DB_LINEAR(in_pga_tlv, -1650, 3000); | 112 | static const DECLARE_TLV_DB_SCALE(in_pga_tlv, -1650, 3000, 0); |
113 | 113 | ||
114 | static const DECLARE_TLV_DB_LINEAR(out_mix_tlv, -2100, 0); | 114 | static const DECLARE_TLV_DB_SCALE(out_mix_tlv, -2100, 0, 0); |
115 | 115 | ||
116 | static const DECLARE_TLV_DB_LINEAR(out_pga_tlv, -7300, 600); | 116 | static const DECLARE_TLV_DB_SCALE(out_pga_tlv, -7300, 600, 0); |
117 | 117 | ||
118 | static const DECLARE_TLV_DB_LINEAR(out_omix_tlv, -600, 0); | 118 | static const DECLARE_TLV_DB_SCALE(out_omix_tlv, -600, 0, 0); |
119 | 119 | ||
120 | static const DECLARE_TLV_DB_LINEAR(out_dac_tlv, -7163, 0); | 120 | static const DECLARE_TLV_DB_SCALE(out_dac_tlv, -7163, 0, 0); |
121 | 121 | ||
122 | static const DECLARE_TLV_DB_LINEAR(in_adc_tlv, -7163, 1763); | 122 | static const DECLARE_TLV_DB_SCALE(in_adc_tlv, -7163, 1763, 0); |
123 | 123 | ||
124 | static const DECLARE_TLV_DB_LINEAR(out_sidetone_tlv, -3600, 0); | 124 | static const DECLARE_TLV_DB_SCALE(out_sidetone_tlv, -3600, 0, 0); |
125 | 125 | ||
126 | static int wm8400_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol, | 126 | static int wm8400_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol, |
127 | struct snd_ctl_elem_value *ucontrol) | 127 | struct snd_ctl_elem_value *ucontrol) |
@@ -440,7 +440,7 @@ static int outmixer_event (struct snd_soc_dapm_widget *w, | |||
440 | /* INMIX dB values */ | 440 | /* INMIX dB values */ |
441 | static const unsigned int in_mix_tlv[] = { | 441 | static const unsigned int in_mix_tlv[] = { |
442 | TLV_DB_RANGE_HEAD(1), | 442 | TLV_DB_RANGE_HEAD(1), |
443 | 0,7, TLV_DB_LINEAR_ITEM(-1200, 600), | 443 | 0,7, TLV_DB_SCALE_ITEM(-1200, 600, 0), |
444 | }; | 444 | }; |
445 | 445 | ||
446 | /* Left In PGA Connections */ | 446 | /* Left In PGA Connections */ |
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c index 7b536d923ea9..c018772cc430 100644 --- a/sound/soc/codecs/wm8990.c +++ b/sound/soc/codecs/wm8990.c | |||
@@ -111,21 +111,21 @@ static const u16 wm8990_reg[] = { | |||
111 | 111 | ||
112 | #define wm8990_reset(c) snd_soc_write(c, WM8990_RESET, 0) | 112 | #define wm8990_reset(c) snd_soc_write(c, WM8990_RESET, 0) |
113 | 113 | ||
114 | static const DECLARE_TLV_DB_LINEAR(rec_mix_tlv, -1500, 600); | 114 | static const DECLARE_TLV_DB_SCALE(rec_mix_tlv, -1500, 600, 0); |
115 | 115 | ||
116 | static const DECLARE_TLV_DB_LINEAR(in_pga_tlv, -1650, 3000); | 116 | static const DECLARE_TLV_DB_SCALE(in_pga_tlv, -1650, 3000, 0); |
117 | 117 | ||
118 | static const DECLARE_TLV_DB_LINEAR(out_mix_tlv, 0, -2100); | 118 | static const DECLARE_TLV_DB_SCALE(out_mix_tlv, 0, -2100, 0); |
119 | 119 | ||
120 | static const DECLARE_TLV_DB_LINEAR(out_pga_tlv, -7300, 600); | 120 | static const DECLARE_TLV_DB_SCALE(out_pga_tlv, -7300, 600, 0); |
121 | 121 | ||
122 | static const DECLARE_TLV_DB_LINEAR(out_omix_tlv, -600, 0); | 122 | static const DECLARE_TLV_DB_SCALE(out_omix_tlv, -600, 0, 0); |
123 | 123 | ||
124 | static const DECLARE_TLV_DB_LINEAR(out_dac_tlv, -7163, 0); | 124 | static const DECLARE_TLV_DB_SCALE(out_dac_tlv, -7163, 0, 0); |
125 | 125 | ||
126 | static const DECLARE_TLV_DB_LINEAR(in_adc_tlv, -7163, 1763); | 126 | static const DECLARE_TLV_DB_SCALE(in_adc_tlv, -7163, 1763, 0); |
127 | 127 | ||
128 | static const DECLARE_TLV_DB_LINEAR(out_sidetone_tlv, -3600, 0); | 128 | static const DECLARE_TLV_DB_SCALE(out_sidetone_tlv, -3600, 0, 0); |
129 | 129 | ||
130 | static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol, | 130 | static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol, |
131 | struct snd_ctl_elem_value *ucontrol) | 131 | struct snd_ctl_elem_value *ucontrol) |
@@ -451,7 +451,7 @@ static int outmixer_event(struct snd_soc_dapm_widget *w, | |||
451 | /* INMIX dB values */ | 451 | /* INMIX dB values */ |
452 | static const unsigned int in_mix_tlv[] = { | 452 | static const unsigned int in_mix_tlv[] = { |
453 | TLV_DB_RANGE_HEAD(1), | 453 | TLV_DB_RANGE_HEAD(1), |
454 | 0, 7, TLV_DB_LINEAR_ITEM(-1200, 600), | 454 | 0, 7, TLV_DB_SCALE_ITEM(-1200, 600, 0), |
455 | }; | 455 | }; |
456 | 456 | ||
457 | /* Left In PGA Connections */ | 457 | /* Left In PGA Connections */ |
diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c index 2b31ac673ea4..05f19c9284f4 100644 --- a/sound/soc/imx/imx-pcm-dma-mx2.c +++ b/sound/soc/imx/imx-pcm-dma-mx2.c | |||
@@ -73,7 +73,8 @@ static void snd_imx_dma_err_callback(int channel, void *data, int err) | |||
73 | { | 73 | { |
74 | struct snd_pcm_substream *substream = data; | 74 | struct snd_pcm_substream *substream = data; |
75 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 75 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
76 | struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data; | 76 | struct imx_pcm_dma_params *dma_params = |
77 | snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); | ||
77 | struct snd_pcm_runtime *runtime = substream->runtime; | 78 | struct snd_pcm_runtime *runtime = substream->runtime; |
78 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; | 79 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; |
79 | int ret; | 80 | int ret; |
@@ -102,7 +103,7 @@ static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream) | |||
102 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; | 103 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; |
103 | int ret; | 104 | int ret; |
104 | 105 | ||
105 | dma_params = snd_soc_get_dma_data(rtd->dai->cpu_dai, substream); | 106 | dma_params = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); |
106 | 107 | ||
107 | iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH); | 108 | iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH); |
108 | if (iprtd->dma < 0) { | 109 | if (iprtd->dma < 0) { |
@@ -212,7 +213,7 @@ static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream) | |||
212 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; | 213 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; |
213 | int err; | 214 | int err; |
214 | 215 | ||
215 | dma_params = snd_soc_get_dma_data(rtd->dai->cpu_dai, substream); | 216 | dma_params = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); |
216 | 217 | ||
217 | iprtd->substream = substream; | 218 | iprtd->substream = substream; |
218 | iprtd->buf = (unsigned int *)substream->dma_buffer.area; | 219 | iprtd->buf = (unsigned int *)substream->dma_buffer.area; |
diff --git a/sound/soc/sh/siu_dai.c b/sound/soc/sh/siu_dai.c index d86ee1bfc03a..eeed5edd722b 100644 --- a/sound/soc/sh/siu_dai.c +++ b/sound/soc/sh/siu_dai.c | |||
@@ -588,6 +588,8 @@ static int siu_dai_prepare(struct snd_pcm_substream *substream, | |||
588 | ret = siu_dai_spbstart(port_info); | 588 | ret = siu_dai_spbstart(port_info); |
589 | if (ret < 0) | 589 | if (ret < 0) |
590 | goto fail; | 590 | goto fail; |
591 | } else { | ||
592 | ret = 0; | ||
591 | } | 593 | } |
592 | 594 | ||
593 | port_info->play_cap |= self; | 595 | port_info->play_cap |= self; |
diff --git a/sound/usb/caiaq/control.c b/sound/usb/caiaq/control.c index 36ed703a7416..91c804cd2782 100644 --- a/sound/usb/caiaq/control.c +++ b/sound/usb/caiaq/control.c | |||
@@ -42,21 +42,12 @@ static int control_info(struct snd_kcontrol *kcontrol, | |||
42 | 42 | ||
43 | switch (dev->chip.usb_id) { | 43 | switch (dev->chip.usb_id) { |
44 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ): | 44 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ): |
45 | if (pos == 0) { | ||
46 | /* current input mode of A8DJ */ | ||
47 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
48 | uinfo->value.integer.min = 0; | ||
49 | uinfo->value.integer.max = 2; | ||
50 | return 0; | ||
51 | } | ||
52 | break; | ||
53 | |||
54 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ): | 45 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ): |
55 | if (pos == 0) { | 46 | if (pos == 0) { |
56 | /* current input mode of A4DJ */ | 47 | /* current input mode of A8DJ and A4DJ */ |
57 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | 48 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
58 | uinfo->value.integer.min = 0; | 49 | uinfo->value.integer.min = 0; |
59 | uinfo->value.integer.max = 1; | 50 | uinfo->value.integer.max = 2; |
60 | return 0; | 51 | return 0; |
61 | } | 52 | } |
62 | break; | 53 | break; |
@@ -86,14 +77,6 @@ static int control_get(struct snd_kcontrol *kcontrol, | |||
86 | struct snd_usb_caiaqdev *dev = caiaqdev(chip->card); | 77 | struct snd_usb_caiaqdev *dev = caiaqdev(chip->card); |
87 | int pos = kcontrol->private_value; | 78 | int pos = kcontrol->private_value; |
88 | 79 | ||
89 | if (dev->chip.usb_id == | ||
90 | USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ)) { | ||
91 | /* A4DJ has only one control */ | ||
92 | /* do not expose hardware input mode 0 */ | ||
93 | ucontrol->value.integer.value[0] = dev->control_state[0] - 1; | ||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | if (pos & CNT_INTVAL) | 80 | if (pos & CNT_INTVAL) |
98 | ucontrol->value.integer.value[0] | 81 | ucontrol->value.integer.value[0] |
99 | = dev->control_state[pos & ~CNT_INTVAL]; | 82 | = dev->control_state[pos & ~CNT_INTVAL]; |
@@ -112,20 +95,9 @@ static int control_put(struct snd_kcontrol *kcontrol, | |||
112 | int pos = kcontrol->private_value; | 95 | int pos = kcontrol->private_value; |
113 | unsigned char cmd = EP1_CMD_WRITE_IO; | 96 | unsigned char cmd = EP1_CMD_WRITE_IO; |
114 | 97 | ||
115 | switch (dev->chip.usb_id) { | 98 | if (dev->chip.usb_id == |
116 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ): { | 99 | USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1)) |
117 | /* A4DJ has only one control */ | ||
118 | /* do not expose hardware input mode 0 */ | ||
119 | dev->control_state[0] = ucontrol->value.integer.value[0] + 1; | ||
120 | snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO, | ||
121 | dev->control_state, sizeof(dev->control_state)); | ||
122 | return 1; | ||
123 | } | ||
124 | |||
125 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): | ||
126 | cmd = EP1_CMD_DIMM_LEDS; | 100 | cmd = EP1_CMD_DIMM_LEDS; |
127 | break; | ||
128 | } | ||
129 | 101 | ||
130 | if (pos & CNT_INTVAL) { | 102 | if (pos & CNT_INTVAL) { |
131 | dev->control_state[pos & ~CNT_INTVAL] | 103 | dev->control_state[pos & ~CNT_INTVAL] |
diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c index 805271827675..cdfb856bddd2 100644 --- a/sound/usb/caiaq/device.c +++ b/sound/usb/caiaq/device.c | |||
@@ -36,7 +36,7 @@ | |||
36 | #include "input.h" | 36 | #include "input.h" |
37 | 37 | ||
38 | MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); | 38 | MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); |
39 | MODULE_DESCRIPTION("caiaq USB audio, version 1.3.20"); | 39 | MODULE_DESCRIPTION("caiaq USB audio, version 1.3.21"); |
40 | MODULE_LICENSE("GPL"); | 40 | MODULE_LICENSE("GPL"); |
41 | MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2}," | 41 | MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2}," |
42 | "{Native Instruments, RigKontrol3}," | 42 | "{Native Instruments, RigKontrol3}," |
@@ -320,12 +320,6 @@ static void __devinit setup_card(struct snd_usb_caiaqdev *dev) | |||
320 | } | 320 | } |
321 | 321 | ||
322 | break; | 322 | break; |
323 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ): | ||
324 | /* Audio 4 DJ - default input mode to phono */ | ||
325 | dev->control_state[0] = 2; | ||
326 | snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO, | ||
327 | dev->control_state, 1); | ||
328 | break; | ||
329 | } | 323 | } |
330 | 324 | ||
331 | if (dev->spec.num_analog_audio_out + | 325 | if (dev->spec.num_analog_audio_out + |
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index ef07a6d0dd5f..28ee1ce3971a 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c | |||
@@ -149,6 +149,47 @@ int snd_usb_add_audio_endpoint(struct snd_usb_audio *chip, int stream, struct au | |||
149 | return 0; | 149 | return 0; |
150 | } | 150 | } |
151 | 151 | ||
152 | static int parse_uac_endpoint_attributes(struct snd_usb_audio *chip, | ||
153 | struct usb_host_interface *alts, | ||
154 | int protocol, int iface_no) | ||
155 | { | ||
156 | /* parsed with a v1 header here. that's ok as we only look at the | ||
157 | * header first which is the same for both versions */ | ||
158 | struct uac_iso_endpoint_descriptor *csep; | ||
159 | struct usb_interface_descriptor *altsd = get_iface_desc(alts); | ||
160 | int attributes = 0; | ||
161 | |||
162 | csep = snd_usb_find_desc(alts->endpoint[0].extra, alts->endpoint[0].extralen, NULL, USB_DT_CS_ENDPOINT); | ||
163 | |||
164 | /* Creamware Noah has this descriptor after the 2nd endpoint */ | ||
165 | if (!csep && altsd->bNumEndpoints >= 2) | ||
166 | csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT); | ||
167 | |||
168 | if (!csep || csep->bLength < 7 || | ||
169 | csep->bDescriptorSubtype != UAC_EP_GENERAL) { | ||
170 | snd_printk(KERN_WARNING "%d:%u:%d : no or invalid" | ||
171 | " class specific endpoint descriptor\n", | ||
172 | chip->dev->devnum, iface_no, | ||
173 | altsd->bAlternateSetting); | ||
174 | return 0; | ||
175 | } | ||
176 | |||
177 | if (protocol == UAC_VERSION_1) { | ||
178 | attributes = csep->bmAttributes; | ||
179 | } else { | ||
180 | struct uac2_iso_endpoint_descriptor *csep2 = | ||
181 | (struct uac2_iso_endpoint_descriptor *) csep; | ||
182 | |||
183 | attributes = csep->bmAttributes & UAC_EP_CS_ATTR_FILL_MAX; | ||
184 | |||
185 | /* emulate the endpoint attributes of a v1 device */ | ||
186 | if (csep2->bmControls & UAC2_CONTROL_PITCH) | ||
187 | attributes |= UAC_EP_CS_ATTR_PITCH_CONTROL; | ||
188 | } | ||
189 | |||
190 | return attributes; | ||
191 | } | ||
192 | |||
152 | int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | 193 | int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) |
153 | { | 194 | { |
154 | struct usb_device *dev; | 195 | struct usb_device *dev; |
@@ -158,8 +199,8 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
158 | int i, altno, err, stream; | 199 | int i, altno, err, stream; |
159 | int format = 0, num_channels = 0; | 200 | int format = 0, num_channels = 0; |
160 | struct audioformat *fp = NULL; | 201 | struct audioformat *fp = NULL; |
161 | unsigned char *fmt, *csep; | ||
162 | int num, protocol; | 202 | int num, protocol; |
203 | struct uac_format_type_i_continuous_descriptor *fmt; | ||
163 | 204 | ||
164 | dev = chip->dev; | 205 | dev = chip->dev; |
165 | 206 | ||
@@ -256,8 +297,8 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
256 | dev->devnum, iface_no, altno); | 297 | dev->devnum, iface_no, altno); |
257 | continue; | 298 | continue; |
258 | } | 299 | } |
259 | if (((protocol == UAC_VERSION_1) && (fmt[0] < 8)) || | 300 | if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8)) || |
260 | ((protocol == UAC_VERSION_2) && (fmt[0] != 6))) { | 301 | ((protocol == UAC_VERSION_2) && (fmt->bLength != 6))) { |
261 | snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n", | 302 | snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n", |
262 | dev->devnum, iface_no, altno); | 303 | dev->devnum, iface_no, altno); |
263 | continue; | 304 | continue; |
@@ -268,7 +309,9 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
268 | * with the previous one, except for a larger packet size, but | 309 | * with the previous one, except for a larger packet size, but |
269 | * is actually a mislabeled two-channel setting; ignore it. | 310 | * is actually a mislabeled two-channel setting; ignore it. |
270 | */ | 311 | */ |
271 | if (fmt[4] == 1 && fmt[5] == 2 && altno == 2 && num == 3 && | 312 | if (fmt->bNrChannels == 1 && |
313 | fmt->bSubframeSize == 2 && | ||
314 | altno == 2 && num == 3 && | ||
272 | fp && fp->altsetting == 1 && fp->channels == 1 && | 315 | fp && fp->altsetting == 1 && fp->channels == 1 && |
273 | fp->formats == SNDRV_PCM_FMTBIT_S16_LE && | 316 | fp->formats == SNDRV_PCM_FMTBIT_S16_LE && |
274 | protocol == UAC_VERSION_1 && | 317 | protocol == UAC_VERSION_1 && |
@@ -276,17 +319,6 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
276 | fp->maxpacksize * 2) | 319 | fp->maxpacksize * 2) |
277 | continue; | 320 | continue; |
278 | 321 | ||
279 | csep = snd_usb_find_desc(alts->endpoint[0].extra, alts->endpoint[0].extralen, NULL, USB_DT_CS_ENDPOINT); | ||
280 | /* Creamware Noah has this descriptor after the 2nd endpoint */ | ||
281 | if (!csep && altsd->bNumEndpoints >= 2) | ||
282 | csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT); | ||
283 | if (!csep || csep[0] < 7 || csep[2] != UAC_EP_GENERAL) { | ||
284 | snd_printk(KERN_WARNING "%d:%u:%d : no or invalid" | ||
285 | " class specific endpoint descriptor\n", | ||
286 | dev->devnum, iface_no, altno); | ||
287 | csep = NULL; | ||
288 | } | ||
289 | |||
290 | fp = kzalloc(sizeof(*fp), GFP_KERNEL); | 322 | fp = kzalloc(sizeof(*fp), GFP_KERNEL); |
291 | if (! fp) { | 323 | if (! fp) { |
292 | snd_printk(KERN_ERR "cannot malloc\n"); | 324 | snd_printk(KERN_ERR "cannot malloc\n"); |
@@ -305,7 +337,7 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
305 | if (snd_usb_get_speed(dev) == USB_SPEED_HIGH) | 337 | if (snd_usb_get_speed(dev) == USB_SPEED_HIGH) |
306 | fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1) | 338 | fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1) |
307 | * (fp->maxpacksize & 0x7ff); | 339 | * (fp->maxpacksize & 0x7ff); |
308 | fp->attributes = csep ? csep[3] : 0; | 340 | fp->attributes = parse_uac_endpoint_attributes(chip, alts, protocol, iface_no); |
309 | 341 | ||
310 | /* some quirks for attributes here */ | 342 | /* some quirks for attributes here */ |
311 | 343 | ||
diff --git a/sound/usb/format.c b/sound/usb/format.c index b87cf87c4e7b..fe29d61de19b 100644 --- a/sound/usb/format.c +++ b/sound/usb/format.c | |||
@@ -278,12 +278,11 @@ err: | |||
278 | * parse the format type I and III descriptors | 278 | * parse the format type I and III descriptors |
279 | */ | 279 | */ |
280 | static int parse_audio_format_i(struct snd_usb_audio *chip, | 280 | static int parse_audio_format_i(struct snd_usb_audio *chip, |
281 | struct audioformat *fp, | 281 | struct audioformat *fp, int format, |
282 | int format, void *_fmt, | 282 | struct uac_format_type_i_continuous_descriptor *fmt, |
283 | struct usb_host_interface *iface) | 283 | struct usb_host_interface *iface) |
284 | { | 284 | { |
285 | struct usb_interface_descriptor *altsd = get_iface_desc(iface); | 285 | struct usb_interface_descriptor *altsd = get_iface_desc(iface); |
286 | struct uac_format_type_i_discrete_descriptor *fmt = _fmt; | ||
287 | int protocol = altsd->bInterfaceProtocol; | 286 | int protocol = altsd->bInterfaceProtocol; |
288 | int pcm_format, ret; | 287 | int pcm_format, ret; |
289 | 288 | ||
@@ -320,7 +319,7 @@ static int parse_audio_format_i(struct snd_usb_audio *chip, | |||
320 | switch (protocol) { | 319 | switch (protocol) { |
321 | case UAC_VERSION_1: | 320 | case UAC_VERSION_1: |
322 | fp->channels = fmt->bNrChannels; | 321 | fp->channels = fmt->bNrChannels; |
323 | ret = parse_audio_format_rates_v1(chip, fp, _fmt, 7); | 322 | ret = parse_audio_format_rates_v1(chip, fp, (unsigned char *) fmt, 7); |
324 | break; | 323 | break; |
325 | case UAC_VERSION_2: | 324 | case UAC_VERSION_2: |
326 | /* fp->channels is already set in this case */ | 325 | /* fp->channels is already set in this case */ |
@@ -392,12 +391,12 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip, | |||
392 | } | 391 | } |
393 | 392 | ||
394 | int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp, | 393 | int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp, |
395 | int format, unsigned char *fmt, int stream, | 394 | int format, struct uac_format_type_i_continuous_descriptor *fmt, |
396 | struct usb_host_interface *iface) | 395 | int stream, struct usb_host_interface *iface) |
397 | { | 396 | { |
398 | int err; | 397 | int err; |
399 | 398 | ||
400 | switch (fmt[3]) { | 399 | switch (fmt->bFormatType) { |
401 | case UAC_FORMAT_TYPE_I: | 400 | case UAC_FORMAT_TYPE_I: |
402 | case UAC_FORMAT_TYPE_III: | 401 | case UAC_FORMAT_TYPE_III: |
403 | err = parse_audio_format_i(chip, fp, format, fmt, iface); | 402 | err = parse_audio_format_i(chip, fp, format, fmt, iface); |
@@ -407,10 +406,11 @@ int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *f | |||
407 | break; | 406 | break; |
408 | default: | 407 | default: |
409 | snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n", | 408 | snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n", |
410 | chip->dev->devnum, fp->iface, fp->altsetting, fmt[3]); | 409 | chip->dev->devnum, fp->iface, fp->altsetting, |
411 | return -1; | 410 | fmt->bFormatType); |
411 | return -ENOTSUPP; | ||
412 | } | 412 | } |
413 | fp->fmt_type = fmt[3]; | 413 | fp->fmt_type = fmt->bFormatType; |
414 | if (err < 0) | 414 | if (err < 0) |
415 | return err; | 415 | return err; |
416 | #if 1 | 416 | #if 1 |
@@ -421,10 +421,10 @@ int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *f | |||
421 | if (chip->usb_id == USB_ID(0x041e, 0x3000) || | 421 | if (chip->usb_id == USB_ID(0x041e, 0x3000) || |
422 | chip->usb_id == USB_ID(0x041e, 0x3020) || | 422 | chip->usb_id == USB_ID(0x041e, 0x3020) || |
423 | chip->usb_id == USB_ID(0x041e, 0x3061)) { | 423 | chip->usb_id == USB_ID(0x041e, 0x3061)) { |
424 | if (fmt[3] == UAC_FORMAT_TYPE_I && | 424 | if (fmt->bFormatType == UAC_FORMAT_TYPE_I && |
425 | fp->rates != SNDRV_PCM_RATE_48000 && | 425 | fp->rates != SNDRV_PCM_RATE_48000 && |
426 | fp->rates != SNDRV_PCM_RATE_96000) | 426 | fp->rates != SNDRV_PCM_RATE_96000) |
427 | return -1; | 427 | return -ENOTSUPP; |
428 | } | 428 | } |
429 | #endif | 429 | #endif |
430 | return 0; | 430 | return 0; |
diff --git a/sound/usb/format.h b/sound/usb/format.h index 8298c4e8ddfa..387924f0af85 100644 --- a/sound/usb/format.h +++ b/sound/usb/format.h | |||
@@ -1,8 +1,9 @@ | |||
1 | #ifndef __USBAUDIO_FORMAT_H | 1 | #ifndef __USBAUDIO_FORMAT_H |
2 | #define __USBAUDIO_FORMAT_H | 2 | #define __USBAUDIO_FORMAT_H |
3 | 3 | ||
4 | int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp, | 4 | int snd_usb_parse_audio_format(struct snd_usb_audio *chip, |
5 | int format, unsigned char *fmt, int stream, | 5 | struct audioformat *fp, int format, |
6 | struct usb_host_interface *iface); | 6 | struct uac_format_type_i_continuous_descriptor *fmt, |
7 | int stream, struct usb_host_interface *iface); | ||
7 | 8 | ||
8 | #endif /* __USBAUDIO_FORMAT_H */ | 9 | #endif /* __USBAUDIO_FORMAT_H */ |
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 97dd17655104..03ce971e0027 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c | |||
@@ -1126,7 +1126,7 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void | |||
1126 | } else { | 1126 | } else { |
1127 | struct uac2_feature_unit_descriptor *ftr = _ftr; | 1127 | struct uac2_feature_unit_descriptor *ftr = _ftr; |
1128 | csize = 4; | 1128 | csize = 4; |
1129 | channels = (hdr->bLength - 6) / 4; | 1129 | channels = (hdr->bLength - 6) / 4 - 1; |
1130 | bmaControls = ftr->bmaControls; | 1130 | bmaControls = ftr->bmaControls; |
1131 | } | 1131 | } |
1132 | 1132 | ||
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index 2bf0d77d1768..056587de7be4 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c | |||
@@ -120,10 +120,6 @@ static int init_pitch_v1(struct snd_usb_audio *chip, int iface, | |||
120 | 120 | ||
121 | ep = get_endpoint(alts, 0)->bEndpointAddress; | 121 | ep = get_endpoint(alts, 0)->bEndpointAddress; |
122 | 122 | ||
123 | /* if endpoint doesn't have pitch control, bail out */ | ||
124 | if (!(fmt->attributes & UAC_EP_CS_ATTR_PITCH_CONTROL)) | ||
125 | return 0; | ||
126 | |||
127 | data[0] = 1; | 123 | data[0] = 1; |
128 | if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR, | 124 | if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR, |
129 | USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, | 125 | USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, |
@@ -137,8 +133,32 @@ static int init_pitch_v1(struct snd_usb_audio *chip, int iface, | |||
137 | return 0; | 133 | return 0; |
138 | } | 134 | } |
139 | 135 | ||
136 | static int init_pitch_v2(struct snd_usb_audio *chip, int iface, | ||
137 | struct usb_host_interface *alts, | ||
138 | struct audioformat *fmt) | ||
139 | { | ||
140 | struct usb_device *dev = chip->dev; | ||
141 | unsigned char data[1]; | ||
142 | unsigned int ep; | ||
143 | int err; | ||
144 | |||
145 | ep = get_endpoint(alts, 0)->bEndpointAddress; | ||
146 | |||
147 | data[0] = 1; | ||
148 | if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR, | ||
149 | USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT, | ||
150 | UAC2_EP_CS_PITCH << 8, 0, | ||
151 | data, sizeof(data), 1000)) < 0) { | ||
152 | snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH (v2)\n", | ||
153 | dev->devnum, iface, fmt->altsetting); | ||
154 | return err; | ||
155 | } | ||
156 | |||
157 | return 0; | ||
158 | } | ||
159 | |||
140 | /* | 160 | /* |
141 | * initialize the picth control and sample rate | 161 | * initialize the pitch control and sample rate |
142 | */ | 162 | */ |
143 | int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface, | 163 | int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface, |
144 | struct usb_host_interface *alts, | 164 | struct usb_host_interface *alts, |
@@ -146,13 +166,16 @@ int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface, | |||
146 | { | 166 | { |
147 | struct usb_interface_descriptor *altsd = get_iface_desc(alts); | 167 | struct usb_interface_descriptor *altsd = get_iface_desc(alts); |
148 | 168 | ||
169 | /* if endpoint doesn't have pitch control, bail out */ | ||
170 | if (!(fmt->attributes & UAC_EP_CS_ATTR_PITCH_CONTROL)) | ||
171 | return 0; | ||
172 | |||
149 | switch (altsd->bInterfaceProtocol) { | 173 | switch (altsd->bInterfaceProtocol) { |
150 | case UAC_VERSION_1: | 174 | case UAC_VERSION_1: |
151 | return init_pitch_v1(chip, iface, alts, fmt); | 175 | return init_pitch_v1(chip, iface, alts, fmt); |
152 | 176 | ||
153 | case UAC_VERSION_2: | 177 | case UAC_VERSION_2: |
154 | /* not implemented yet */ | 178 | return init_pitch_v2(chip, iface, alts, fmt); |
155 | return 0; | ||
156 | } | 179 | } |
157 | 180 | ||
158 | return -EINVAL; | 181 | return -EINVAL; |