diff options
author | Len Brown <len.brown@intel.com> | 2006-01-07 02:05:40 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2006-01-07 02:05:40 -0500 |
commit | add5b5ee992e40c9cd8697ea94c223628be162a7 (patch) | |
tree | 7f3f279f3e6b41e61d7dfaf4d25a5251024a7185 | |
parent | 25da0974601fc8096461f3d3f7ca3aab8e79adfb (diff) | |
parent | 0aec63e67c69545ca757a73a66f5dcf05fa484bf (diff) |
Auto-update from upstream
221 files changed, 3861 insertions, 2254 deletions
diff --git a/.gitignore b/.gitignore index a4b576eb9c00..3f8fb686b59c 100644 --- a/.gitignore +++ b/.gitignore | |||
@@ -10,6 +10,7 @@ | |||
10 | *.a | 10 | *.a |
11 | *.s | 11 | *.s |
12 | *.ko | 12 | *.ko |
13 | *.so | ||
13 | *.mod.c | 14 | *.mod.c |
14 | 15 | ||
15 | # | 16 | # |
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 8ae8dad8e150..9474501dd6cc 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
@@ -71,15 +71,6 @@ Who: Mauro Carvalho Chehab <mchehab@brturbo.com.br> | |||
71 | 71 | ||
72 | --------------------------- | 72 | --------------------------- |
73 | 73 | ||
74 | What: i2c sysfs name change: in1_ref, vid deprecated in favour of cpu0_vid | ||
75 | When: November 2005 | ||
76 | Files: drivers/i2c/chips/adm1025.c, drivers/i2c/chips/adm1026.c | ||
77 | Why: Match the other drivers' name for the same function, duplicate names | ||
78 | will be available until removal of old names. | ||
79 | Who: Grant Coady <gcoady@gmail.com> | ||
80 | |||
81 | --------------------------- | ||
82 | |||
83 | What: remove EXPORT_SYMBOL(panic_timeout) | 74 | What: remove EXPORT_SYMBOL(panic_timeout) |
84 | When: April 2006 | 75 | When: April 2006 |
85 | Files: kernel/panic.c | 76 | Files: kernel/panic.c |
diff --git a/Documentation/hwmon/w83627hf b/Documentation/hwmon/w83627hf index 78f37c2d602e..5d23776e9907 100644 --- a/Documentation/hwmon/w83627hf +++ b/Documentation/hwmon/w83627hf | |||
@@ -54,13 +54,16 @@ If you really want i2c accesses for these Super I/O chips, | |||
54 | use the w83781d driver. However this is not the preferred method | 54 | use the w83781d driver. However this is not the preferred method |
55 | now that this ISA driver has been developed. | 55 | now that this ISA driver has been developed. |
56 | 56 | ||
57 | Technically, the w83627thf does not support a VID reading. However, it's | 57 | The w83627_HF_ uses pins 110-106 as VID0-VID4. The w83627_THF_ uses the |
58 | possible or even likely that your mainboard maker has routed these signals | 58 | same pins as GPIO[0:4]. Technically, the w83627_THF_ does not support a |
59 | to a specific set of general purpose IO pins (the Asus P4C800-E is one such | 59 | VID reading. However the two chips have the identical 128 pin package. So, |
60 | board). The w83627thf driver now interprets these as VID. If the VID on | 60 | it is possible or even likely for a w83627thf to have the VID signals routed |
61 | your board doesn't work, first see doc/vid in the lm_sensors package. If | 61 | to these pins despite their not being labeled for that purpose. Therefore, |
62 | that still doesn't help, email us at lm-sensors@lm-sensors.org. | 62 | the w83627thf driver interprets these as VID. If the VID on your board |
63 | doesn't work, first see doc/vid in the lm_sensors package[1]. If that still | ||
64 | doesn't help, you may just ignore the bogus VID reading with no harm done. | ||
63 | 65 | ||
64 | For further information on this driver see the w83781d driver | 66 | For further information on this driver see the w83781d driver documentation. |
65 | documentation. | 67 | |
68 | [1] http://www2.lm-sensors.nu/~lm78/cvs/browse.cgi/lm_sensors2/doc/vid | ||
66 | 69 | ||
diff --git a/Documentation/i2c/busses/i2c-nforce2 b/Documentation/i2c/busses/i2c-nforce2 index e379e182e64f..d751282d9b2a 100644 --- a/Documentation/i2c/busses/i2c-nforce2 +++ b/Documentation/i2c/busses/i2c-nforce2 | |||
@@ -5,7 +5,8 @@ Supported adapters: | |||
5 | * nForce2 Ultra 400 MCP 10de:0084 | 5 | * nForce2 Ultra 400 MCP 10de:0084 |
6 | * nForce3 Pro150 MCP 10de:00D4 | 6 | * nForce3 Pro150 MCP 10de:00D4 |
7 | * nForce3 250Gb MCP 10de:00E4 | 7 | * nForce3 250Gb MCP 10de:00E4 |
8 | * nForce4 MCP 10de:0052 | 8 | * nForce4 MCP 10de:0052 |
9 | * nForce4 MCP-04 10de:0034 | ||
9 | 10 | ||
10 | Datasheet: not publically available, but seems to be similar to the | 11 | Datasheet: not publically available, but seems to be similar to the |
11 | AMD-8111 SMBus 2.0 adapter. | 12 | AMD-8111 SMBus 2.0 adapter. |
diff --git a/Documentation/i2c/busses/i2c-parport b/Documentation/i2c/busses/i2c-parport index 9f1d0082da18..d9f23c0763f1 100644 --- a/Documentation/i2c/busses/i2c-parport +++ b/Documentation/i2c/busses/i2c-parport | |||
@@ -17,6 +17,7 @@ It currently supports the following devices: | |||
17 | * Velleman K8000 adapter | 17 | * Velleman K8000 adapter |
18 | * ELV adapter | 18 | * ELV adapter |
19 | * Analog Devices evaluation boards (ADM1025, ADM1030, ADM1031, ADM1032) | 19 | * Analog Devices evaluation boards (ADM1025, ADM1030, ADM1031, ADM1032) |
20 | * Barco LPT->DVI (K5800236) adapter | ||
20 | 21 | ||
21 | These devices use different pinout configurations, so you have to tell | 22 | These devices use different pinout configurations, so you have to tell |
22 | the driver what you have, using the type module parameter. There is no | 23 | the driver what you have, using the type module parameter. There is no |
diff --git a/Documentation/i2c/porting-clients b/Documentation/i2c/porting-clients index 184fac2377aa..f03c2a02f806 100644 --- a/Documentation/i2c/porting-clients +++ b/Documentation/i2c/porting-clients | |||
@@ -1,10 +1,13 @@ | |||
1 | Revision 5, 2005-07-29 | 1 | Revision 6, 2005-11-20 |
2 | Jean Delvare <khali@linux-fr.org> | 2 | Jean Delvare <khali@linux-fr.org> |
3 | Greg KH <greg@kroah.com> | 3 | Greg KH <greg@kroah.com> |
4 | 4 | ||
5 | This is a guide on how to convert I2C chip drivers from Linux 2.4 to | 5 | This is a guide on how to convert I2C chip drivers from Linux 2.4 to |
6 | Linux 2.6. I have been using existing drivers (lm75, lm78) as examples. | 6 | Linux 2.6. I have been using existing drivers (lm75, lm78) as examples. |
7 | Then I converted a driver myself (lm83) and updated this document. | 7 | Then I converted a driver myself (lm83) and updated this document. |
8 | Note that this guide is strongly oriented towards hardware monitoring | ||
9 | drivers. Many points are still valid for other type of drivers, but | ||
10 | others may be irrelevant. | ||
8 | 11 | ||
9 | There are two sets of points below. The first set concerns technical | 12 | There are two sets of points below. The first set concerns technical |
10 | changes. The second set concerns coding policy. Both are mandatory. | 13 | changes. The second set concerns coding policy. Both are mandatory. |
@@ -22,16 +25,20 @@ Technical changes: | |||
22 | #include <linux/module.h> | 25 | #include <linux/module.h> |
23 | #include <linux/init.h> | 26 | #include <linux/init.h> |
24 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/jiffies.h> | ||
25 | #include <linux/i2c.h> | 29 | #include <linux/i2c.h> |
30 | #include <linux/i2c-isa.h> /* for ISA drivers */ | ||
26 | #include <linux/hwmon.h> /* for hardware monitoring drivers */ | 31 | #include <linux/hwmon.h> /* for hardware monitoring drivers */ |
27 | #include <linux/hwmon-sysfs.h> | 32 | #include <linux/hwmon-sysfs.h> |
28 | #include <linux/hwmon-vid.h> /* if you need VRM support */ | 33 | #include <linux/hwmon-vid.h> /* if you need VRM support */ |
34 | #include <linux/err.h> /* for class registration */ | ||
29 | #include <asm/io.h> /* if you have I/O operations */ | 35 | #include <asm/io.h> /* if you have I/O operations */ |
30 | Please respect this inclusion order. Some extra headers may be | 36 | Please respect this inclusion order. Some extra headers may be |
31 | required for a given driver (e.g. "lm75.h"). | 37 | required for a given driver (e.g. "lm75.h"). |
32 | 38 | ||
33 | * [Addresses] SENSORS_I2C_END becomes I2C_CLIENT_END, ISA addresses | 39 | * [Addresses] SENSORS_I2C_END becomes I2C_CLIENT_END, ISA addresses |
34 | are no more handled by the i2c core. | 40 | are no more handled by the i2c core. Address ranges are no more |
41 | supported either, define each individual address separately. | ||
35 | SENSORS_INSMOD_<n> becomes I2C_CLIENT_INSMOD_<n>. | 42 | SENSORS_INSMOD_<n> becomes I2C_CLIENT_INSMOD_<n>. |
36 | 43 | ||
37 | * [Client data] Get rid of sysctl_id. Try using standard names for | 44 | * [Client data] Get rid of sysctl_id. Try using standard names for |
@@ -48,23 +55,23 @@ Technical changes: | |||
48 | int kind); | 55 | int kind); |
49 | static void lm75_init_client(struct i2c_client *client); | 56 | static void lm75_init_client(struct i2c_client *client); |
50 | static int lm75_detach_client(struct i2c_client *client); | 57 | static int lm75_detach_client(struct i2c_client *client); |
51 | static void lm75_update_client(struct i2c_client *client); | 58 | static struct lm75_data lm75_update_device(struct device *dev); |
52 | 59 | ||
53 | * [Sysctl] All sysctl stuff is of course gone (defines, ctl_table | 60 | * [Sysctl] All sysctl stuff is of course gone (defines, ctl_table |
54 | and functions). Instead, you have to define show and set functions for | 61 | and functions). Instead, you have to define show and set functions for |
55 | each sysfs file. Only define set for writable values. Take a look at an | 62 | each sysfs file. Only define set for writable values. Take a look at an |
56 | existing 2.6 driver for details (lm78 for example). Don't forget | 63 | existing 2.6 driver for details (it87 for example). Don't forget |
57 | to define the attributes for each file (this is that step that | 64 | to define the attributes for each file (this is that step that |
58 | links callback functions). Use the file names specified in | 65 | links callback functions). Use the file names specified in |
59 | Documentation/i2c/sysfs-interface for the individual files. Also | 66 | Documentation/hwmon/sysfs-interface for the individual files. Also |
60 | convert the units these files read and write to the specified ones. | 67 | convert the units these files read and write to the specified ones. |
61 | If you need to add a new type of file, please discuss it on the | 68 | If you need to add a new type of file, please discuss it on the |
62 | sensors mailing list <lm-sensors@lm-sensors.org> by providing a | 69 | sensors mailing list <lm-sensors@lm-sensors.org> by providing a |
63 | patch to the Documentation/i2c/sysfs-interface file. | 70 | patch to the Documentation/hwmon/sysfs-interface file. |
64 | 71 | ||
65 | * [Attach] For I2C drivers, the attach function should make sure | 72 | * [Attach] For I2C drivers, the attach function should make sure |
66 | that the adapter's class has I2C_CLASS_HWMON, using the | 73 | that the adapter's class has I2C_CLASS_HWMON (or whatever class is |
67 | following construct: | 74 | suitable for your driver), using the following construct: |
68 | if (!(adapter->class & I2C_CLASS_HWMON)) | 75 | if (!(adapter->class & I2C_CLASS_HWMON)) |
69 | return 0; | 76 | return 0; |
70 | ISA-only drivers of course don't need this. | 77 | ISA-only drivers of course don't need this. |
@@ -72,63 +79,72 @@ Technical changes: | |||
72 | 79 | ||
73 | * [Detect] As mentioned earlier, the flags parameter is gone. | 80 | * [Detect] As mentioned earlier, the flags parameter is gone. |
74 | The type_name and client_name strings are replaced by a single | 81 | The type_name and client_name strings are replaced by a single |
75 | name string, which will be filled with a lowercase, short string | 82 | name string, which will be filled with a lowercase, short string. |
76 | (typically the driver name, e.g. "lm75"). | ||
77 | In i2c-only drivers, drop the i2c_is_isa_adapter check, it's | 83 | In i2c-only drivers, drop the i2c_is_isa_adapter check, it's |
78 | useless. Same for isa-only drivers, as the test would always be | 84 | useless. Same for isa-only drivers, as the test would always be |
79 | true. Only hybrid drivers (which are quite rare) still need it. | 85 | true. Only hybrid drivers (which are quite rare) still need it. |
80 | The errorN labels are reduced to the number needed. If that number | 86 | The labels used for error paths are reduced to the number needed. |
81 | is 2 (i2c-only drivers), it is advised that the labels are named | 87 | It is advised that the labels are given descriptive names such as |
82 | exit and exit_free. For i2c+isa drivers, labels should be named | 88 | exit and exit_free. Don't forget to properly set err before |
83 | ERROR0, ERROR1 and ERROR2. Don't forget to properly set err before | ||
84 | jumping to error labels. By the way, labels should be left-aligned. | 89 | jumping to error labels. By the way, labels should be left-aligned. |
85 | Use kzalloc instead of kmalloc. | 90 | Use kzalloc instead of kmalloc. |
86 | Use i2c_set_clientdata to set the client data (as opposed to | 91 | Use i2c_set_clientdata to set the client data (as opposed to |
87 | a direct access to client->data). | 92 | a direct access to client->data). |
88 | Use strlcpy instead of strcpy to copy the client name. | 93 | Use strlcpy instead of strcpy or snprintf to copy the client name. |
89 | Replace the sysctl directory registration by calls to | 94 | Replace the sysctl directory registration by calls to |
90 | device_create_file. Move the driver initialization before any | 95 | device_create_file. Move the driver initialization before any |
91 | sysfs file creation. | 96 | sysfs file creation. |
97 | Register the client with the hwmon class (using hwmon_device_register) | ||
98 | if applicable. | ||
92 | Drop client->id. | 99 | Drop client->id. |
93 | Drop any 24RF08 corruption prevention you find, as this is now done | 100 | Drop any 24RF08 corruption prevention you find, as this is now done |
94 | at the i2c-core level, and doing it twice voids it. | 101 | at the i2c-core level, and doing it twice voids it. |
102 | Don't add I2C_CLIENT_ALLOW_USE to client->flags, it's the default now. | ||
95 | 103 | ||
96 | * [Init] Limits must not be set by the driver (can be done later in | 104 | * [Init] Limits must not be set by the driver (can be done later in |
97 | user-space). Chip should not be reset default (although a module | 105 | user-space). Chip should not be reset default (although a module |
98 | parameter may be used to force is), and initialization should be | 106 | parameter may be used to force it), and initialization should be |
99 | limited to the strictly necessary steps. | 107 | limited to the strictly necessary steps. |
100 | 108 | ||
101 | * [Detach] Get rid of data, remove the call to | 109 | * [Detach] Remove the call to i2c_deregister_entry. Do not log an |
102 | i2c_deregister_entry. Do not log an error message if | 110 | error message if i2c_detach_client fails, as i2c-core will now do |
103 | i2c_detach_client fails, as i2c-core will now do it for you. | 111 | it for you. |
104 | 112 | Unregister from the hwmon class if applicable. | |
105 | * [Update] Don't access client->data directly, use | 113 | |
106 | i2c_get_clientdata(client) instead. | 114 | * [Update] The function prototype changed, it is now |
107 | 115 | passed a device structure, which you have to convert to a client | |
108 | * [Interface] Init function should not print anything. Make sure | 116 | using to_i2c_client(dev). The update function should return a |
109 | there is a MODULE_LICENSE() line, at the bottom of the file | 117 | pointer to the client data. |
110 | (after MODULE_AUTHOR() and MODULE_DESCRIPTION(), in this order). | 118 | Don't access client->data directly, use i2c_get_clientdata(client) |
119 | instead. | ||
120 | Use time_after() instead of direct jiffies comparison. | ||
121 | |||
122 | * [Interface] Make sure there is a MODULE_LICENSE() line, at the bottom | ||
123 | of the file (after MODULE_AUTHOR() and MODULE_DESCRIPTION(), in this | ||
124 | order). | ||
125 | |||
126 | * [Driver] The flags field of the i2c_driver structure is gone. | ||
127 | I2C_DF_NOTIFY is now the default behavior. | ||
128 | The i2c_driver structure has a driver member, which is itself a | ||
129 | structure, those name member should be initialized to a driver name | ||
130 | string. i2c_driver itself has no name member anymore. | ||
111 | 131 | ||
112 | Coding policy: | 132 | Coding policy: |
113 | 133 | ||
114 | * [Copyright] Use (C), not (c), for copyright. | 134 | * [Copyright] Use (C), not (c), for copyright. |
115 | 135 | ||
116 | * [Debug/log] Get rid of #ifdef DEBUG/#endif constructs whenever you | 136 | * [Debug/log] Get rid of #ifdef DEBUG/#endif constructs whenever you |
117 | can. Calls to printk/pr_debug for debugging purposes are replaced | 137 | can. Calls to printk for debugging purposes are replaced by calls to |
118 | by calls to dev_dbg. Here is an example on how to call it (taken | 138 | dev_dbg where possible, else to pr_debug. Here is an example of how |
119 | from lm75_detect): | 139 | to call it (taken from lm75_detect): |
120 | dev_dbg(&client->dev, "Starting lm75 update\n"); | 140 | dev_dbg(&client->dev, "Starting lm75 update\n"); |
121 | Replace other printk calls with the dev_info, dev_err or dev_warn | 141 | Replace other printk calls with the dev_info, dev_err or dev_warn |
122 | function, as appropriate. | 142 | function, as appropriate. |
123 | 143 | ||
124 | * [Constants] Constants defines (registers, conversions, initial | 144 | * [Constants] Constants defines (registers, conversions) should be |
125 | values) should be aligned. This greatly improves readability. | 145 | aligned. This greatly improves readability. |
126 | Same goes for variables declarations. Alignments are achieved by the | 146 | Alignments are achieved by the means of tabs, not spaces. Remember |
127 | means of tabs, not spaces. Remember that tabs are set to 8 in the | 147 | that tabs are set to 8 in the Linux kernel code. |
128 | Linux kernel code. | ||
129 | |||
130 | * [Structure definition] The name field should be standardized. All | ||
131 | lowercase and as simple as the driver name itself (e.g. "lm75"). | ||
132 | 148 | ||
133 | * [Layout] Avoid extra empty lines between comments and what they | 149 | * [Layout] Avoid extra empty lines between comments and what they |
134 | comment. Respect the coding style (see Documentation/CodingStyle), | 150 | comment. Respect the coding style (see Documentation/CodingStyle), |
diff --git a/Documentation/i2c/writing-clients b/Documentation/i2c/writing-clients index d19993cc0604..3a057c8e5507 100644 --- a/Documentation/i2c/writing-clients +++ b/Documentation/i2c/writing-clients | |||
@@ -25,9 +25,9 @@ routines, a client structure specific information like the actual I2C | |||
25 | address. | 25 | address. |
26 | 26 | ||
27 | static struct i2c_driver foo_driver = { | 27 | static struct i2c_driver foo_driver = { |
28 | .owner = THIS_MODULE, | 28 | .driver = { |
29 | .name = "Foo version 2.3 driver", | 29 | .name = "foo", |
30 | .flags = I2C_DF_NOTIFY, | 30 | }, |
31 | .attach_adapter = &foo_attach_adapter, | 31 | .attach_adapter = &foo_attach_adapter, |
32 | .detach_client = &foo_detach_client, | 32 | .detach_client = &foo_detach_client, |
33 | .command = &foo_command /* may be NULL */ | 33 | .command = &foo_command /* may be NULL */ |
@@ -36,10 +36,6 @@ static struct i2c_driver foo_driver = { | |||
36 | The name field must match the driver name, including the case. It must not | 36 | The name field must match the driver name, including the case. It must not |
37 | contain spaces, and may be up to 31 characters long. | 37 | contain spaces, and may be up to 31 characters long. |
38 | 38 | ||
39 | Don't worry about the flags field; just put I2C_DF_NOTIFY into it. This | ||
40 | means that your driver will be notified when new adapters are found. | ||
41 | This is almost always what you want. | ||
42 | |||
43 | All other fields are for call-back functions which will be explained | 39 | All other fields are for call-back functions which will be explained |
44 | below. | 40 | below. |
45 | 41 | ||
@@ -496,17 +492,13 @@ Note that some functions are marked by `__init', and some data structures | |||
496 | by `__init_data'. Hose functions and structures can be removed after | 492 | by `__init_data'. Hose functions and structures can be removed after |
497 | kernel booting (or module loading) is completed. | 493 | kernel booting (or module loading) is completed. |
498 | 494 | ||
495 | |||
499 | Command function | 496 | Command function |
500 | ================ | 497 | ================ |
501 | 498 | ||
502 | A generic ioctl-like function call back is supported. You will seldom | 499 | A generic ioctl-like function call back is supported. You will seldom |
503 | need this. You may even set it to NULL. | 500 | need this, and its use is deprecated anyway, so newer design should not |
504 | 501 | use it. Set it to NULL. | |
505 | /* No commands defined */ | ||
506 | int foo_command(struct i2c_client *client, unsigned int cmd, void *arg) | ||
507 | { | ||
508 | return 0; | ||
509 | } | ||
510 | 502 | ||
511 | 503 | ||
512 | Sending and receiving | 504 | Sending and receiving |
diff --git a/Documentation/kbuild/modules.txt b/Documentation/kbuild/modules.txt index 1c0db652b366..7e77f93634ea 100644 --- a/Documentation/kbuild/modules.txt +++ b/Documentation/kbuild/modules.txt | |||
@@ -18,6 +18,7 @@ In this document you will find information about: | |||
18 | === 5. Include files | 18 | === 5. Include files |
19 | --- 5.1 How to include files from the kernel include dir | 19 | --- 5.1 How to include files from the kernel include dir |
20 | --- 5.2 External modules using an include/ dir | 20 | --- 5.2 External modules using an include/ dir |
21 | --- 5.3 External modules using several directories | ||
21 | === 6. Module installation | 22 | === 6. Module installation |
22 | --- 6.1 INSTALL_MOD_PATH | 23 | --- 6.1 INSTALL_MOD_PATH |
23 | --- 6.2 INSTALL_MOD_DIR | 24 | --- 6.2 INSTALL_MOD_DIR |
@@ -344,6 +345,45 @@ directory and therefore needs to deal with this in their kbuild file. | |||
344 | Note that in the assignment there is no space between -I and the path. | 345 | Note that in the assignment there is no space between -I and the path. |
345 | This is a kbuild limitation: there must be no space present. | 346 | This is a kbuild limitation: there must be no space present. |
346 | 347 | ||
348 | --- 5.3 External modules using several directories | ||
349 | |||
350 | If an external module does not follow the usual kernel style but | ||
351 | decide to spread files over several directories then kbuild can | ||
352 | support this too. | ||
353 | |||
354 | Consider the following example: | ||
355 | |||
356 | | | ||
357 | +- src/complex_main.c | ||
358 | | +- hal/hardwareif.c | ||
359 | | +- hal/include/hardwareif.h | ||
360 | +- include/complex.h | ||
361 | |||
362 | To build a single module named complex.ko we then need the following | ||
363 | kbuild file: | ||
364 | |||
365 | Kbuild: | ||
366 | obj-m := complex.o | ||
367 | complex-y := src/complex_main.o | ||
368 | complex-y += src/hal/hardwareif.o | ||
369 | |||
370 | EXTRA_CFLAGS := -I$(src)/include | ||
371 | EXTRA_CFLAGS += -I$(src)src/hal/include | ||
372 | |||
373 | |||
374 | kbuild knows how to handle .o files located in another directory - | ||
375 | although this is NOT reccommended practice. The syntax is to specify | ||
376 | the directory relative to the directory where the Kbuild file is | ||
377 | located. | ||
378 | |||
379 | To find the .h files we have to explicitly tell kbuild where to look | ||
380 | for the .h files. When kbuild executes current directory is always | ||
381 | the root of the kernel tree (argument to -C) and therefore we have to | ||
382 | tell kbuild how to find the .h files using absolute paths. | ||
383 | $(src) will specify the absolute path to the directory where the | ||
384 | Kbuild file are located when being build as an external module. | ||
385 | Therefore -I$(src)/ is used to point out the directory of the Kbuild | ||
386 | file and any additional path are just appended. | ||
347 | 387 | ||
348 | === 6. Module installation | 388 | === 6. Module installation |
349 | 389 | ||
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 06e362b2d5b8..acb010bb087b 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -910,6 +910,14 @@ running once the system is up. | |||
910 | nfsroot= [NFS] nfs root filesystem for disk-less boxes. | 910 | nfsroot= [NFS] nfs root filesystem for disk-less boxes. |
911 | See Documentation/nfsroot.txt. | 911 | See Documentation/nfsroot.txt. |
912 | 912 | ||
913 | nfs.callback_tcpport= | ||
914 | [NFS] set the TCP port on which the NFSv4 callback | ||
915 | channel should listen. | ||
916 | |||
917 | nfs.idmap_cache_timeout= | ||
918 | [NFS] set the maximum lifetime for idmapper cache | ||
919 | entries. | ||
920 | |||
913 | nmi_watchdog= [KNL,BUGS=IA-32] Debugging features for SMP kernels | 921 | nmi_watchdog= [KNL,BUGS=IA-32] Debugging features for SMP kernels |
914 | 922 | ||
915 | no387 [BUGS=IA-32] Tells the kernel to use the 387 maths | 923 | no387 [BUGS=IA-32] Tells the kernel to use the 387 maths |
diff --git a/MAINTAINERS b/MAINTAINERS index a01b20ef7e8a..7e780906d34c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -696,13 +696,6 @@ M: pc300@cyclades.com | |||
696 | W: http://www.cyclades.com/ | 696 | W: http://www.cyclades.com/ |
697 | S: Supported | 697 | S: Supported |
698 | 698 | ||
699 | DAC960 RAID CONTROLLER DRIVER | ||
700 | P: Dave Olien | ||
701 | M dmo@osdl.org | ||
702 | W: http://www.osdl.org/archive/dmo/DAC960 | ||
703 | L: linux-kernel@vger.kernel.org | ||
704 | S: Maintained | ||
705 | |||
706 | DAMA SLAVE for AX.25 | 699 | DAMA SLAVE for AX.25 |
707 | P: Joerg Reuter | 700 | P: Joerg Reuter |
708 | M: jreuter@yaina.de | 701 | M: jreuter@yaina.de |
@@ -2923,6 +2916,12 @@ W: http://linuxtv.org | |||
2923 | T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git | 2916 | T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git |
2924 | S: Maintained | 2917 | S: Maintained |
2925 | 2918 | ||
2919 | VT8231 HARDWARE MONITOR DRIVER | ||
2920 | P: Roger Lucas | ||
2921 | M: roger@planbit.co.uk | ||
2922 | L: lm-sensors@lm-sensors.org | ||
2923 | S: Maintained | ||
2924 | |||
2926 | W1 DALLAS'S 1-WIRE BUS | 2925 | W1 DALLAS'S 1-WIRE BUS |
2927 | P: Evgeniy Polyakov | 2926 | P: Evgeniy Polyakov |
2928 | M: johnpol@2ka.mipt.ru | 2927 | M: johnpol@2ka.mipt.ru |
diff --git a/arch/arm/mach-pxa/akita-ioexp.c b/arch/arm/mach-pxa/akita-ioexp.c index f6d73cc01f78..1b398742ab56 100644 --- a/arch/arm/mach-pxa/akita-ioexp.c +++ b/arch/arm/mach-pxa/akita-ioexp.c | |||
@@ -124,17 +124,16 @@ static int max7310_detach_client(struct i2c_client *client) | |||
124 | } | 124 | } |
125 | 125 | ||
126 | static struct i2c_driver max7310_i2c_driver = { | 126 | static struct i2c_driver max7310_i2c_driver = { |
127 | .owner = THIS_MODULE, | 127 | .driver = { |
128 | .name = "akita-max7310", | 128 | .name = "akita-max7310", |
129 | }, | ||
129 | .id = I2C_DRIVERID_AKITAIOEXP, | 130 | .id = I2C_DRIVERID_AKITAIOEXP, |
130 | .flags = I2C_DF_NOTIFY, | ||
131 | .attach_adapter = max7310_attach_adapter, | 131 | .attach_adapter = max7310_attach_adapter, |
132 | .detach_client = max7310_detach_client, | 132 | .detach_client = max7310_detach_client, |
133 | }; | 133 | }; |
134 | 134 | ||
135 | static struct i2c_client max7310_template = { | 135 | static struct i2c_client max7310_template = { |
136 | name: "akita-max7310", | 136 | name: "akita-max7310", |
137 | flags: I2C_CLIENT_ALLOW_USE, | ||
138 | driver: &max7310_i2c_driver, | 137 | driver: &max7310_i2c_driver, |
139 | }; | 138 | }; |
140 | 139 | ||
diff --git a/arch/x86_64/ia32/.gitignore b/arch/x86_64/ia32/.gitignore deleted file mode 100644 index 48ab174fe5f1..000000000000 --- a/arch/x86_64/ia32/.gitignore +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | vsyscall*.so | ||
diff --git a/drivers/acorn/char/pcf8583.c b/drivers/acorn/char/pcf8583.c index e26f007a1417..9b49f316ae92 100644 --- a/drivers/acorn/char/pcf8583.c +++ b/drivers/acorn/char/pcf8583.c | |||
@@ -257,9 +257,10 @@ pcf8583_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
257 | } | 257 | } |
258 | 258 | ||
259 | static struct i2c_driver pcf8583_driver = { | 259 | static struct i2c_driver pcf8583_driver = { |
260 | .name = "PCF8583", | 260 | .driver = { |
261 | .name = "PCF8583", | ||
262 | }, | ||
261 | .id = I2C_DRIVERID_PCF8583, | 263 | .id = I2C_DRIVERID_PCF8583, |
262 | .flags = I2C_DF_NOTIFY, | ||
263 | .attach_adapter = pcf8583_probe, | 264 | .attach_adapter = pcf8583_probe, |
264 | .detach_client = pcf8583_detach, | 265 | .detach_client = pcf8583_detach, |
265 | .command = pcf8583_command | 266 | .command = pcf8583_command |
diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c index 78c89a3e7825..c92378121b4c 100644 --- a/drivers/char/mmtimer.c +++ b/drivers/char/mmtimer.c | |||
@@ -1,11 +1,11 @@ | |||
1 | /* | 1 | /* |
2 | * Intel Multimedia Timer device implementation for SGI SN platforms. | 2 | * Timer device implementation for SGI SN platforms. |
3 | * | 3 | * |
4 | * This file is subject to the terms and conditions of the GNU General Public | 4 | * This file is subject to the terms and conditions of the GNU General Public |
5 | * License. See the file "COPYING" in the main directory of this archive | 5 | * License. See the file "COPYING" in the main directory of this archive |
6 | * for more details. | 6 | * for more details. |
7 | * | 7 | * |
8 | * Copyright (c) 2001-2004 Silicon Graphics, Inc. All rights reserved. | 8 | * Copyright (c) 2001-2006 Silicon Graphics, Inc. All rights reserved. |
9 | * | 9 | * |
10 | * This driver exports an API that should be supportable by any HPET or IA-PC | 10 | * This driver exports an API that should be supportable by any HPET or IA-PC |
11 | * multimedia timer. The code below is currently specific to the SGI Altix | 11 | * multimedia timer. The code below is currently specific to the SGI Altix |
@@ -45,7 +45,7 @@ MODULE_LICENSE("GPL"); | |||
45 | /* name of the device, usually in /dev */ | 45 | /* name of the device, usually in /dev */ |
46 | #define MMTIMER_NAME "mmtimer" | 46 | #define MMTIMER_NAME "mmtimer" |
47 | #define MMTIMER_DESC "SGI Altix RTC Timer" | 47 | #define MMTIMER_DESC "SGI Altix RTC Timer" |
48 | #define MMTIMER_VERSION "2.0" | 48 | #define MMTIMER_VERSION "2.1" |
49 | 49 | ||
50 | #define RTC_BITS 55 /* 55 bits for this implementation */ | 50 | #define RTC_BITS 55 /* 55 bits for this implementation */ |
51 | 51 | ||
@@ -227,10 +227,7 @@ typedef struct mmtimer { | |||
227 | struct tasklet_struct tasklet; | 227 | struct tasklet_struct tasklet; |
228 | } mmtimer_t; | 228 | } mmtimer_t; |
229 | 229 | ||
230 | /* | 230 | static mmtimer_t ** timers; |
231 | * Total number of comparators is comparators/node * MAX nodes/running kernel | ||
232 | */ | ||
233 | static mmtimer_t timers[NUM_COMPARATORS*MAX_COMPACT_NODES]; | ||
234 | 231 | ||
235 | /** | 232 | /** |
236 | * mmtimer_ioctl - ioctl interface for /dev/mmtimer | 233 | * mmtimer_ioctl - ioctl interface for /dev/mmtimer |
@@ -441,29 +438,29 @@ static irqreturn_t | |||
441 | mmtimer_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 438 | mmtimer_interrupt(int irq, void *dev_id, struct pt_regs *regs) |
442 | { | 439 | { |
443 | int i; | 440 | int i; |
444 | mmtimer_t *base = timers + cpu_to_node(smp_processor_id()) * | ||
445 | NUM_COMPARATORS; | ||
446 | unsigned long expires = 0; | 441 | unsigned long expires = 0; |
447 | int result = IRQ_NONE; | 442 | int result = IRQ_NONE; |
443 | unsigned indx = cpu_to_node(smp_processor_id()); | ||
448 | 444 | ||
449 | /* | 445 | /* |
450 | * Do this once for each comparison register | 446 | * Do this once for each comparison register |
451 | */ | 447 | */ |
452 | for (i = 0; i < NUM_COMPARATORS; i++) { | 448 | for (i = 0; i < NUM_COMPARATORS; i++) { |
449 | mmtimer_t *base = timers[indx] + i; | ||
453 | /* Make sure this doesn't get reused before tasklet_sched */ | 450 | /* Make sure this doesn't get reused before tasklet_sched */ |
454 | spin_lock(&base[i].lock); | 451 | spin_lock(&base->lock); |
455 | if (base[i].cpu == smp_processor_id()) { | 452 | if (base->cpu == smp_processor_id()) { |
456 | if (base[i].timer) | 453 | if (base->timer) |
457 | expires = base[i].timer->it.mmtimer.expires; | 454 | expires = base->timer->it.mmtimer.expires; |
458 | /* expires test won't work with shared irqs */ | 455 | /* expires test won't work with shared irqs */ |
459 | if ((mmtimer_int_pending(i) > 0) || | 456 | if ((mmtimer_int_pending(i) > 0) || |
460 | (expires && (expires < rtc_time()))) { | 457 | (expires && (expires < rtc_time()))) { |
461 | mmtimer_clr_int_pending(i); | 458 | mmtimer_clr_int_pending(i); |
462 | tasklet_schedule(&base[i].tasklet); | 459 | tasklet_schedule(&base->tasklet); |
463 | result = IRQ_HANDLED; | 460 | result = IRQ_HANDLED; |
464 | } | 461 | } |
465 | } | 462 | } |
466 | spin_unlock(&base[i].lock); | 463 | spin_unlock(&base->lock); |
467 | expires = 0; | 464 | expires = 0; |
468 | } | 465 | } |
469 | return result; | 466 | return result; |
@@ -523,7 +520,7 @@ static int sgi_timer_del(struct k_itimer *timr) | |||
523 | { | 520 | { |
524 | int i = timr->it.mmtimer.clock; | 521 | int i = timr->it.mmtimer.clock; |
525 | cnodeid_t nodeid = timr->it.mmtimer.node; | 522 | cnodeid_t nodeid = timr->it.mmtimer.node; |
526 | mmtimer_t *t = timers + nodeid * NUM_COMPARATORS +i; | 523 | mmtimer_t *t = timers[nodeid] + i; |
527 | unsigned long irqflags; | 524 | unsigned long irqflags; |
528 | 525 | ||
529 | if (i != TIMER_OFF) { | 526 | if (i != TIMER_OFF) { |
@@ -609,11 +606,11 @@ static int sgi_timer_set(struct k_itimer *timr, int flags, | |||
609 | preempt_disable(); | 606 | preempt_disable(); |
610 | 607 | ||
611 | nodeid = cpu_to_node(smp_processor_id()); | 608 | nodeid = cpu_to_node(smp_processor_id()); |
612 | base = timers + nodeid * NUM_COMPARATORS; | ||
613 | retry: | 609 | retry: |
614 | /* Don't use an allocated timer, or a deleted one that's pending */ | 610 | /* Don't use an allocated timer, or a deleted one that's pending */ |
615 | for(i = 0; i< NUM_COMPARATORS; i++) { | 611 | for(i = 0; i< NUM_COMPARATORS; i++) { |
616 | if (!base[i].timer && !base[i].tasklet.state) { | 612 | base = timers[nodeid] + i; |
613 | if (!base->timer && !base->tasklet.state) { | ||
617 | break; | 614 | break; |
618 | } | 615 | } |
619 | } | 616 | } |
@@ -623,14 +620,14 @@ retry: | |||
623 | return -EBUSY; | 620 | return -EBUSY; |
624 | } | 621 | } |
625 | 622 | ||
626 | spin_lock_irqsave(&base[i].lock, irqflags); | 623 | spin_lock_irqsave(&base->lock, irqflags); |
627 | 624 | ||
628 | if (base[i].timer || base[i].tasklet.state != 0) { | 625 | if (base->timer || base->tasklet.state != 0) { |
629 | spin_unlock_irqrestore(&base[i].lock, irqflags); | 626 | spin_unlock_irqrestore(&base->lock, irqflags); |
630 | goto retry; | 627 | goto retry; |
631 | } | 628 | } |
632 | base[i].timer = timr; | 629 | base->timer = timr; |
633 | base[i].cpu = smp_processor_id(); | 630 | base->cpu = smp_processor_id(); |
634 | 631 | ||
635 | timr->it.mmtimer.clock = i; | 632 | timr->it.mmtimer.clock = i; |
636 | timr->it.mmtimer.node = nodeid; | 633 | timr->it.mmtimer.node = nodeid; |
@@ -645,11 +642,11 @@ retry: | |||
645 | } | 642 | } |
646 | } else { | 643 | } else { |
647 | timr->it.mmtimer.expires -= period; | 644 | timr->it.mmtimer.expires -= period; |
648 | if (reschedule_periodic_timer(base+i)) | 645 | if (reschedule_periodic_timer(base)) |
649 | err = -EINVAL; | 646 | err = -EINVAL; |
650 | } | 647 | } |
651 | 648 | ||
652 | spin_unlock_irqrestore(&base[i].lock, irqflags); | 649 | spin_unlock_irqrestore(&base->lock, irqflags); |
653 | 650 | ||
654 | preempt_enable(); | 651 | preempt_enable(); |
655 | 652 | ||
@@ -675,6 +672,7 @@ static struct k_clock sgi_clock = { | |||
675 | static int __init mmtimer_init(void) | 672 | static int __init mmtimer_init(void) |
676 | { | 673 | { |
677 | unsigned i; | 674 | unsigned i; |
675 | cnodeid_t node, maxn = -1; | ||
678 | 676 | ||
679 | if (!ia64_platform_is("sn2")) | 677 | if (!ia64_platform_is("sn2")) |
680 | return -1; | 678 | return -1; |
@@ -691,14 +689,6 @@ static int __init mmtimer_init(void) | |||
691 | mmtimer_femtoperiod = ((unsigned long)1E15 + sn_rtc_cycles_per_second / | 689 | mmtimer_femtoperiod = ((unsigned long)1E15 + sn_rtc_cycles_per_second / |
692 | 2) / sn_rtc_cycles_per_second; | 690 | 2) / sn_rtc_cycles_per_second; |
693 | 691 | ||
694 | for (i=0; i< NUM_COMPARATORS*MAX_COMPACT_NODES; i++) { | ||
695 | spin_lock_init(&timers[i].lock); | ||
696 | timers[i].timer = NULL; | ||
697 | timers[i].cpu = 0; | ||
698 | timers[i].i = i % NUM_COMPARATORS; | ||
699 | tasklet_init(&timers[i].tasklet, mmtimer_tasklet, (unsigned long) (timers+i)); | ||
700 | } | ||
701 | |||
702 | if (request_irq(SGI_MMTIMER_VECTOR, mmtimer_interrupt, SA_PERCPU_IRQ, MMTIMER_NAME, NULL)) { | 692 | if (request_irq(SGI_MMTIMER_VECTOR, mmtimer_interrupt, SA_PERCPU_IRQ, MMTIMER_NAME, NULL)) { |
703 | printk(KERN_WARNING "%s: unable to allocate interrupt.", | 693 | printk(KERN_WARNING "%s: unable to allocate interrupt.", |
704 | MMTIMER_NAME); | 694 | MMTIMER_NAME); |
@@ -712,6 +702,40 @@ static int __init mmtimer_init(void) | |||
712 | return -1; | 702 | return -1; |
713 | } | 703 | } |
714 | 704 | ||
705 | /* Get max numbered node, calculate slots needed */ | ||
706 | for_each_online_node(node) { | ||
707 | maxn = node; | ||
708 | } | ||
709 | maxn++; | ||
710 | |||
711 | /* Allocate list of node ptrs to mmtimer_t's */ | ||
712 | timers = kmalloc(sizeof(mmtimer_t *)*maxn, GFP_KERNEL); | ||
713 | if (timers == NULL) { | ||
714 | printk(KERN_ERR "%s: failed to allocate memory for device\n", | ||
715 | MMTIMER_NAME); | ||
716 | return -1; | ||
717 | } | ||
718 | |||
719 | /* Allocate mmtimer_t's for each online node */ | ||
720 | for_each_online_node(node) { | ||
721 | timers[node] = kmalloc_node(sizeof(mmtimer_t)*NUM_COMPARATORS, GFP_KERNEL, node); | ||
722 | if (timers[node] == NULL) { | ||
723 | printk(KERN_ERR "%s: failed to allocate memory for device\n", | ||
724 | MMTIMER_NAME); | ||
725 | return -1; | ||
726 | } | ||
727 | for (i=0; i< NUM_COMPARATORS; i++) { | ||
728 | mmtimer_t * base = timers[node] + i; | ||
729 | |||
730 | spin_lock_init(&base->lock); | ||
731 | base->timer = NULL; | ||
732 | base->cpu = 0; | ||
733 | base->i = i; | ||
734 | tasklet_init(&base->tasklet, mmtimer_tasklet, | ||
735 | (unsigned long) (base)); | ||
736 | } | ||
737 | } | ||
738 | |||
715 | sgi_clock_period = sgi_clock.res = NSEC_PER_SEC / sn_rtc_cycles_per_second; | 739 | sgi_clock_period = sgi_clock.res = NSEC_PER_SEC / sn_rtc_cycles_per_second; |
716 | register_posix_clock(CLOCK_SGI_CYCLE, &sgi_clock); | 740 | register_posix_clock(CLOCK_SGI_CYCLE, &sgi_clock); |
717 | 741 | ||
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index db358cfa7cbf..c58295914365 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -350,6 +350,18 @@ config SENSORS_VIA686A | |||
350 | This driver can also be built as a module. If so, the module | 350 | This driver can also be built as a module. If so, the module |
351 | will be called via686a. | 351 | will be called via686a. |
352 | 352 | ||
353 | config SENSORS_VT8231 | ||
354 | tristate "VT8231" | ||
355 | depends on HWMON && I2C && PCI && EXPERIMENTAL | ||
356 | select HWMON_VID | ||
357 | select I2C_ISA | ||
358 | help | ||
359 | If you say yes here then you get support for the integrated sensors | ||
360 | in the VIA VT8231 device. | ||
361 | |||
362 | This driver can also be built as a module. If so, the module | ||
363 | will be called vt8231. | ||
364 | |||
353 | config SENSORS_W83781D | 365 | config SENSORS_W83781D |
354 | tristate "Winbond W83781D, W83782D, W83783S, W83627HF, Asus AS99127F" | 366 | tristate "Winbond W83781D, W83782D, W83783S, W83627HF, Asus AS99127F" |
355 | depends on HWMON && I2C | 367 | depends on HWMON && I2C |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index f7d6a2f61ee7..06d4a1d14105 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
@@ -40,6 +40,7 @@ obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o | |||
40 | obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o | 40 | obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o |
41 | obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o | 41 | obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o |
42 | obj-$(CONFIG_SENSORS_VIA686A) += via686a.o | 42 | obj-$(CONFIG_SENSORS_VIA686A) += via686a.o |
43 | obj-$(CONFIG_SENSORS_VT8231) += vt8231.o | ||
43 | obj-$(CONFIG_SENSORS_W83627EHF) += w83627ehf.o | 44 | obj-$(CONFIG_SENSORS_W83627EHF) += w83627ehf.o |
44 | obj-$(CONFIG_SENSORS_W83L785TS) += w83l785ts.o | 45 | obj-$(CONFIG_SENSORS_W83L785TS) += w83l785ts.o |
45 | 46 | ||
diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c index 8102876c7c3f..665612729cb9 100644 --- a/drivers/hwmon/adm1021.c +++ b/drivers/hwmon/adm1021.c | |||
@@ -126,10 +126,10 @@ static int read_only; | |||
126 | 126 | ||
127 | /* This is the driver that will be inserted */ | 127 | /* This is the driver that will be inserted */ |
128 | static struct i2c_driver adm1021_driver = { | 128 | static struct i2c_driver adm1021_driver = { |
129 | .owner = THIS_MODULE, | 129 | .driver = { |
130 | .name = "adm1021", | 130 | .name = "adm1021", |
131 | }, | ||
131 | .id = I2C_DRIVERID_ADM1021, | 132 | .id = I2C_DRIVERID_ADM1021, |
132 | .flags = I2C_DF_NOTIFY, | ||
133 | .attach_adapter = adm1021_attach_adapter, | 133 | .attach_adapter = adm1021_attach_adapter, |
134 | .detach_client = adm1021_detach_client, | 134 | .detach_client = adm1021_detach_client, |
135 | }; | 135 | }; |
diff --git a/drivers/hwmon/adm1025.c b/drivers/hwmon/adm1025.c index 3ec12421694f..9331c56d2ba6 100644 --- a/drivers/hwmon/adm1025.c +++ b/drivers/hwmon/adm1025.c | |||
@@ -118,10 +118,10 @@ static struct adm1025_data *adm1025_update_device(struct device *dev); | |||
118 | */ | 118 | */ |
119 | 119 | ||
120 | static struct i2c_driver adm1025_driver = { | 120 | static struct i2c_driver adm1025_driver = { |
121 | .owner = THIS_MODULE, | 121 | .driver = { |
122 | .name = "adm1025", | 122 | .name = "adm1025", |
123 | }, | ||
123 | .id = I2C_DRIVERID_ADM1025, | 124 | .id = I2C_DRIVERID_ADM1025, |
124 | .flags = I2C_DF_NOTIFY, | ||
125 | .attach_adapter = adm1025_attach_adapter, | 125 | .attach_adapter = adm1025_attach_adapter, |
126 | .detach_client = adm1025_detach_client, | 126 | .detach_client = adm1025_detach_client, |
127 | }; | 127 | }; |
@@ -287,8 +287,6 @@ static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char | |||
287 | struct adm1025_data *data = adm1025_update_device(dev); | 287 | struct adm1025_data *data = adm1025_update_device(dev); |
288 | return sprintf(buf, "%u\n", vid_from_reg(data->vid, data->vrm)); | 288 | return sprintf(buf, "%u\n", vid_from_reg(data->vid, data->vrm)); |
289 | } | 289 | } |
290 | /* in1_ref is deprecated in favour of cpu0_vid, remove after 2005-11-11 */ | ||
291 | static DEVICE_ATTR(in1_ref, S_IRUGO, show_vid, NULL); | ||
292 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); | 290 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); |
293 | 291 | ||
294 | static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf) | 292 | static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf) |
@@ -444,8 +442,6 @@ static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind) | |||
444 | device_create_file(&new_client->dev, &dev_attr_temp1_max); | 442 | device_create_file(&new_client->dev, &dev_attr_temp1_max); |
445 | device_create_file(&new_client->dev, &dev_attr_temp2_max); | 443 | device_create_file(&new_client->dev, &dev_attr_temp2_max); |
446 | device_create_file(&new_client->dev, &dev_attr_alarms); | 444 | device_create_file(&new_client->dev, &dev_attr_alarms); |
447 | /* in1_ref is deprecated, remove after 2005-11-11 */ | ||
448 | device_create_file(&new_client->dev, &dev_attr_in1_ref); | ||
449 | device_create_file(&new_client->dev, &dev_attr_cpu0_vid); | 445 | device_create_file(&new_client->dev, &dev_attr_cpu0_vid); |
450 | device_create_file(&new_client->dev, &dev_attr_vrm); | 446 | device_create_file(&new_client->dev, &dev_attr_vrm); |
451 | 447 | ||
diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index e0f56549d1d8..fefe6e74fd02 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c | |||
@@ -308,9 +308,9 @@ static void adm1026_init_client(struct i2c_client *client); | |||
308 | 308 | ||
309 | 309 | ||
310 | static struct i2c_driver adm1026_driver = { | 310 | static struct i2c_driver adm1026_driver = { |
311 | .owner = THIS_MODULE, | 311 | .driver = { |
312 | .name = "adm1026", | 312 | .name = "adm1026", |
313 | .flags = I2C_DF_NOTIFY, | 313 | }, |
314 | .attach_adapter = adm1026_attach_adapter, | 314 | .attach_adapter = adm1026_attach_adapter, |
315 | .detach_client = adm1026_detach_client, | 315 | .detach_client = adm1026_detach_client, |
316 | }; | 316 | }; |
@@ -1227,8 +1227,6 @@ static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr, c | |||
1227 | struct adm1026_data *data = adm1026_update_device(dev); | 1227 | struct adm1026_data *data = adm1026_update_device(dev); |
1228 | return sprintf(buf,"%d\n", vid_from_reg(data->vid & 0x3f, data->vrm)); | 1228 | return sprintf(buf,"%d\n", vid_from_reg(data->vid & 0x3f, data->vrm)); |
1229 | } | 1229 | } |
1230 | /* vid deprecated in favour of cpu0_vid, remove after 2005-11-11 */ | ||
1231 | static DEVICE_ATTR(vid, S_IRUGO, show_vid_reg, NULL); | ||
1232 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); | 1230 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); |
1233 | 1231 | ||
1234 | static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) | 1232 | static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) |
@@ -1673,8 +1671,6 @@ static int adm1026_detect(struct i2c_adapter *adapter, int address, | |||
1673 | device_create_file(&new_client->dev, &dev_attr_temp1_crit_enable); | 1671 | device_create_file(&new_client->dev, &dev_attr_temp1_crit_enable); |
1674 | device_create_file(&new_client->dev, &dev_attr_temp2_crit_enable); | 1672 | device_create_file(&new_client->dev, &dev_attr_temp2_crit_enable); |
1675 | device_create_file(&new_client->dev, &dev_attr_temp3_crit_enable); | 1673 | device_create_file(&new_client->dev, &dev_attr_temp3_crit_enable); |
1676 | /* vid deprecated in favour of cpu0_vid, remove after 2005-11-11 */ | ||
1677 | device_create_file(&new_client->dev, &dev_attr_vid); | ||
1678 | device_create_file(&new_client->dev, &dev_attr_cpu0_vid); | 1674 | device_create_file(&new_client->dev, &dev_attr_cpu0_vid); |
1679 | device_create_file(&new_client->dev, &dev_attr_vrm); | 1675 | device_create_file(&new_client->dev, &dev_attr_vrm); |
1680 | device_create_file(&new_client->dev, &dev_attr_alarms); | 1676 | device_create_file(&new_client->dev, &dev_attr_alarms); |
diff --git a/drivers/hwmon/adm1031.c b/drivers/hwmon/adm1031.c index 7c545d5eee45..d06397966081 100644 --- a/drivers/hwmon/adm1031.c +++ b/drivers/hwmon/adm1031.c | |||
@@ -105,9 +105,9 @@ static struct adm1031_data *adm1031_update_device(struct device *dev); | |||
105 | 105 | ||
106 | /* This is the driver that will be inserted */ | 106 | /* This is the driver that will be inserted */ |
107 | static struct i2c_driver adm1031_driver = { | 107 | static struct i2c_driver adm1031_driver = { |
108 | .owner = THIS_MODULE, | 108 | .driver = { |
109 | .name = "adm1031", | 109 | .name = "adm1031", |
110 | .flags = I2C_DF_NOTIFY, | 110 | }, |
111 | .attach_adapter = adm1031_attach_adapter, | 111 | .attach_adapter = adm1031_attach_adapter, |
112 | .detach_client = adm1031_detach_client, | 112 | .detach_client = adm1031_detach_client, |
113 | }; | 113 | }; |
diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c index 11dc95f8a17e..5ddc22fea4a3 100644 --- a/drivers/hwmon/adm9240.c +++ b/drivers/hwmon/adm9240.c | |||
@@ -137,10 +137,10 @@ static struct adm9240_data *adm9240_update_device(struct device *dev); | |||
137 | 137 | ||
138 | /* driver data */ | 138 | /* driver data */ |
139 | static struct i2c_driver adm9240_driver = { | 139 | static struct i2c_driver adm9240_driver = { |
140 | .owner = THIS_MODULE, | 140 | .driver = { |
141 | .name = "adm9240", | 141 | .name = "adm9240", |
142 | }, | ||
142 | .id = I2C_DRIVERID_ADM9240, | 143 | .id = I2C_DRIVERID_ADM9240, |
143 | .flags = I2C_DF_NOTIFY, | ||
144 | .attach_adapter = adm9240_attach_adapter, | 144 | .attach_adapter = adm9240_attach_adapter, |
145 | .detach_client = adm9240_detach_client, | 145 | .detach_client = adm9240_detach_client, |
146 | }; | 146 | }; |
diff --git a/drivers/hwmon/asb100.c b/drivers/hwmon/asb100.c index 52c469722a65..ae9de63cf2e0 100644 --- a/drivers/hwmon/asb100.c +++ b/drivers/hwmon/asb100.c | |||
@@ -217,10 +217,10 @@ static struct asb100_data *asb100_update_device(struct device *dev); | |||
217 | static void asb100_init_client(struct i2c_client *client); | 217 | static void asb100_init_client(struct i2c_client *client); |
218 | 218 | ||
219 | static struct i2c_driver asb100_driver = { | 219 | static struct i2c_driver asb100_driver = { |
220 | .owner = THIS_MODULE, | 220 | .driver = { |
221 | .name = "asb100", | 221 | .name = "asb100", |
222 | }, | ||
222 | .id = I2C_DRIVERID_ASB100, | 223 | .id = I2C_DRIVERID_ASB100, |
223 | .flags = I2C_DF_NOTIFY, | ||
224 | .attach_adapter = asb100_attach_adapter, | 224 | .attach_adapter = asb100_attach_adapter, |
225 | .detach_client = asb100_detach_client, | 225 | .detach_client = asb100_detach_client, |
226 | }; | 226 | }; |
diff --git a/drivers/hwmon/atxp1.c b/drivers/hwmon/atxp1.c index 53324f56404e..b0c490073c8e 100644 --- a/drivers/hwmon/atxp1.c +++ b/drivers/hwmon/atxp1.c | |||
@@ -50,9 +50,9 @@ static struct atxp1_data * atxp1_update_device(struct device *dev); | |||
50 | static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind); | 50 | static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind); |
51 | 51 | ||
52 | static struct i2c_driver atxp1_driver = { | 52 | static struct i2c_driver atxp1_driver = { |
53 | .owner = THIS_MODULE, | 53 | .driver = { |
54 | .name = "atxp1", | 54 | .name = "atxp1", |
55 | .flags = I2C_DF_NOTIFY, | 55 | }, |
56 | .attach_adapter = atxp1_attach_adapter, | 56 | .attach_adapter = atxp1_attach_adapter, |
57 | .detach_client = atxp1_detach_client, | 57 | .detach_client = atxp1_detach_client, |
58 | }; | 58 | }; |
diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c index 34f71b7c7f37..203f9c7abb20 100644 --- a/drivers/hwmon/ds1621.c +++ b/drivers/hwmon/ds1621.c | |||
@@ -89,10 +89,10 @@ static struct ds1621_data *ds1621_update_client(struct device *dev); | |||
89 | 89 | ||
90 | /* This is the driver that will be inserted */ | 90 | /* This is the driver that will be inserted */ |
91 | static struct i2c_driver ds1621_driver = { | 91 | static struct i2c_driver ds1621_driver = { |
92 | .owner = THIS_MODULE, | 92 | .driver = { |
93 | .name = "ds1621", | 93 | .name = "ds1621", |
94 | }, | ||
94 | .id = I2C_DRIVERID_DS1621, | 95 | .id = I2C_DRIVERID_DS1621, |
95 | .flags = I2C_DF_NOTIFY, | ||
96 | .attach_adapter = ds1621_attach_adapter, | 96 | .attach_adapter = ds1621_attach_adapter, |
97 | .detach_client = ds1621_detach_client, | 97 | .detach_client = ds1621_detach_client, |
98 | }; | 98 | }; |
diff --git a/drivers/hwmon/fscher.c b/drivers/hwmon/fscher.c index a02e1c34c757..25409181d1eb 100644 --- a/drivers/hwmon/fscher.c +++ b/drivers/hwmon/fscher.c | |||
@@ -118,10 +118,10 @@ static int fscher_write_value(struct i2c_client *client, u8 reg, u8 value); | |||
118 | */ | 118 | */ |
119 | 119 | ||
120 | static struct i2c_driver fscher_driver = { | 120 | static struct i2c_driver fscher_driver = { |
121 | .owner = THIS_MODULE, | 121 | .driver = { |
122 | .name = "fscher", | 122 | .name = "fscher", |
123 | }, | ||
123 | .id = I2C_DRIVERID_FSCHER, | 124 | .id = I2C_DRIVERID_FSCHER, |
124 | .flags = I2C_DF_NOTIFY, | ||
125 | .attach_adapter = fscher_attach_adapter, | 125 | .attach_adapter = fscher_attach_adapter, |
126 | .detach_client = fscher_detach_client, | 126 | .detach_client = fscher_detach_client, |
127 | }; | 127 | }; |
diff --git a/drivers/hwmon/fscpos.c b/drivers/hwmon/fscpos.c index 64e4edc64f8d..6d0146b57020 100644 --- a/drivers/hwmon/fscpos.c +++ b/drivers/hwmon/fscpos.c | |||
@@ -100,10 +100,10 @@ static void reset_fan_alarm(struct i2c_client *client, int nr); | |||
100 | * Driver data (common to all clients) | 100 | * Driver data (common to all clients) |
101 | */ | 101 | */ |
102 | static struct i2c_driver fscpos_driver = { | 102 | static struct i2c_driver fscpos_driver = { |
103 | .owner = THIS_MODULE, | 103 | .driver = { |
104 | .name = "fscpos", | 104 | .name = "fscpos", |
105 | }, | ||
105 | .id = I2C_DRIVERID_FSCPOS, | 106 | .id = I2C_DRIVERID_FSCPOS, |
106 | .flags = I2C_DF_NOTIFY, | ||
107 | .attach_adapter = fscpos_attach_adapter, | 107 | .attach_adapter = fscpos_attach_adapter, |
108 | .detach_client = fscpos_detach_client, | 108 | .detach_client = fscpos_detach_client, |
109 | }; | 109 | }; |
diff --git a/drivers/hwmon/gl518sm.c b/drivers/hwmon/gl518sm.c index 2f178dbe3d87..9e685e3a3bc9 100644 --- a/drivers/hwmon/gl518sm.c +++ b/drivers/hwmon/gl518sm.c | |||
@@ -151,10 +151,10 @@ static struct gl518_data *gl518_update_device(struct device *dev); | |||
151 | 151 | ||
152 | /* This is the driver that will be inserted */ | 152 | /* This is the driver that will be inserted */ |
153 | static struct i2c_driver gl518_driver = { | 153 | static struct i2c_driver gl518_driver = { |
154 | .owner = THIS_MODULE, | 154 | .driver = { |
155 | .name = "gl518sm", | 155 | .name = "gl518sm", |
156 | }, | ||
156 | .id = I2C_DRIVERID_GL518, | 157 | .id = I2C_DRIVERID_GL518, |
157 | .flags = I2C_DF_NOTIFY, | ||
158 | .attach_adapter = gl518_attach_adapter, | 158 | .attach_adapter = gl518_attach_adapter, |
159 | .detach_client = gl518_detach_client, | 159 | .detach_client = gl518_detach_client, |
160 | }; | 160 | }; |
diff --git a/drivers/hwmon/gl520sm.c b/drivers/hwmon/gl520sm.c index c39ba1239426..baee60e44b52 100644 --- a/drivers/hwmon/gl520sm.c +++ b/drivers/hwmon/gl520sm.c | |||
@@ -109,10 +109,10 @@ static struct gl520_data *gl520_update_device(struct device *dev); | |||
109 | 109 | ||
110 | /* Driver data */ | 110 | /* Driver data */ |
111 | static struct i2c_driver gl520_driver = { | 111 | static struct i2c_driver gl520_driver = { |
112 | .owner = THIS_MODULE, | 112 | .driver = { |
113 | .name = "gl520sm", | 113 | .name = "gl520sm", |
114 | }, | ||
114 | .id = I2C_DRIVERID_GL520, | 115 | .id = I2C_DRIVERID_GL520, |
115 | .flags = I2C_DF_NOTIFY, | ||
116 | .attach_adapter = gl520_attach_adapter, | 116 | .attach_adapter = gl520_attach_adapter, |
117 | .detach_client = gl520_detach_client, | 117 | .detach_client = gl520_detach_client, |
118 | }; | 118 | }; |
diff --git a/drivers/hwmon/hwmon-vid.c b/drivers/hwmon/hwmon-vid.c index 312769ad4dab..e497274916ce 100644 --- a/drivers/hwmon/hwmon-vid.c +++ b/drivers/hwmon/hwmon-vid.c | |||
@@ -49,20 +49,22 @@ | |||
49 | . . . . | 49 | . . . . |
50 | 11110 = 0.800 V | 50 | 11110 = 0.800 V |
51 | 11111 = 0.000 V (off) | 51 | 11111 = 0.000 V (off) |
52 | |||
53 | The 17 specification is in fact Intel Mobile Voltage Positioning - | ||
54 | (IMVP-II). You can find more information in the datasheet of Max1718 | ||
55 | http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2452 | ||
56 | |||
52 | */ | 57 | */ |
53 | 58 | ||
54 | /* vrm is the VRM/VRD document version multiplied by 10. | 59 | /* vrm is the VRM/VRD document version multiplied by 10. |
55 | val is the 4-, 5- or 6-bit VID code. | 60 | val is the 4-, 5- or 6-bit VID code. |
56 | Returned value is in mV to avoid floating point in the kernel. */ | 61 | Returned value is in mV to avoid floating point in the kernel. */ |
57 | int vid_from_reg(int val, int vrm) | 62 | int vid_from_reg(int val, u8 vrm) |
58 | { | 63 | { |
59 | int vid; | 64 | int vid; |
60 | 65 | ||
61 | switch(vrm) { | 66 | switch(vrm) { |
62 | 67 | ||
63 | case 0: | ||
64 | return 0; | ||
65 | |||
66 | case 100: /* VRD 10.0 */ | 68 | case 100: /* VRD 10.0 */ |
67 | if((val & 0x1f) == 0x1f) | 69 | if((val & 0x1f) == 0x1f) |
68 | return 0; | 70 | return 0; |
@@ -91,10 +93,16 @@ int vid_from_reg(int val, int vrm) | |||
91 | case 84: /* VRM 8.4 */ | 93 | case 84: /* VRM 8.4 */ |
92 | val &= 0x0f; | 94 | val &= 0x0f; |
93 | /* fall through */ | 95 | /* fall through */ |
94 | default: /* VRM 8.2 */ | 96 | case 82: /* VRM 8.2 */ |
95 | return(val == 0x1f ? 0 : | 97 | return(val == 0x1f ? 0 : |
96 | val & 0x10 ? 5100 - (val) * 100 : | 98 | val & 0x10 ? 5100 - (val) * 100 : |
97 | 2050 - (val) * 50); | 99 | 2050 - (val) * 50); |
100 | case 17: /* Intel IMVP-II */ | ||
101 | return(val & 0x10 ? 975 - (val & 0xF) * 25 : | ||
102 | 1750 - val * 50); | ||
103 | default: /* report 0 for unknown */ | ||
104 | printk(KERN_INFO "hwmon-vid: requested unknown VRM version\n"); | ||
105 | return 0; | ||
98 | } | 106 | } |
99 | } | 107 | } |
100 | 108 | ||
@@ -108,30 +116,36 @@ struct vrm_model { | |||
108 | u8 vendor; | 116 | u8 vendor; |
109 | u8 eff_family; | 117 | u8 eff_family; |
110 | u8 eff_model; | 118 | u8 eff_model; |
111 | int vrm_type; | 119 | u8 eff_stepping; |
120 | u8 vrm_type; | ||
112 | }; | 121 | }; |
113 | 122 | ||
114 | #define ANY 0xFF | 123 | #define ANY 0xFF |
115 | 124 | ||
116 | #ifdef CONFIG_X86 | 125 | #ifdef CONFIG_X86 |
117 | 126 | ||
127 | /* the stepping parameter is highest acceptable stepping for current line */ | ||
128 | |||
118 | static struct vrm_model vrm_models[] = { | 129 | static struct vrm_model vrm_models[] = { |
119 | {X86_VENDOR_AMD, 0x6, ANY, 90}, /* Athlon Duron etc */ | 130 | {X86_VENDOR_AMD, 0x6, ANY, ANY, 90}, /* Athlon Duron etc */ |
120 | {X86_VENDOR_AMD, 0xF, ANY, 24}, /* Athlon 64, Opteron */ | 131 | {X86_VENDOR_AMD, 0xF, ANY, ANY, 24}, /* Athlon 64, Opteron and above VRM 24 */ |
121 | {X86_VENDOR_INTEL, 0x6, 0x9, 85}, /* 0.13um too */ | 132 | {X86_VENDOR_INTEL, 0x6, 0x9, ANY, 85}, /* 0.13um too */ |
122 | {X86_VENDOR_INTEL, 0x6, 0xB, 85}, /* Tualatin */ | 133 | {X86_VENDOR_INTEL, 0x6, 0xB, ANY, 85}, /* Tualatin */ |
123 | {X86_VENDOR_INTEL, 0x6, ANY, 82}, /* any P6 */ | 134 | {X86_VENDOR_INTEL, 0x6, ANY, ANY, 82}, /* any P6 */ |
124 | {X86_VENDOR_INTEL, 0x7, ANY, 0}, /* Itanium */ | 135 | {X86_VENDOR_INTEL, 0x7, ANY, ANY, 0}, /* Itanium */ |
125 | {X86_VENDOR_INTEL, 0xF, 0x0, 90}, /* P4 */ | 136 | {X86_VENDOR_INTEL, 0xF, 0x0, ANY, 90}, /* P4 */ |
126 | {X86_VENDOR_INTEL, 0xF, 0x1, 90}, /* P4 Willamette */ | 137 | {X86_VENDOR_INTEL, 0xF, 0x1, ANY, 90}, /* P4 Willamette */ |
127 | {X86_VENDOR_INTEL, 0xF, 0x2, 90}, /* P4 Northwood */ | 138 | {X86_VENDOR_INTEL, 0xF, 0x2, ANY, 90}, /* P4 Northwood */ |
128 | {X86_VENDOR_INTEL, 0xF, 0x3, 100}, /* P4 Prescott */ | 139 | {X86_VENDOR_INTEL, 0xF, ANY, ANY, 100}, /* Prescott and above assume VRD 10 */ |
129 | {X86_VENDOR_INTEL, 0xF, 0x4, 100}, /* P4 Prescott */ | 140 | {X86_VENDOR_INTEL, 0x10, ANY, ANY, 0}, /* Itanium 2 */ |
130 | {X86_VENDOR_INTEL, 0x10,ANY, 0}, /* Itanium 2 */ | 141 | {X86_VENDOR_CENTAUR, 0x6, 0x7, ANY, 85}, /* Eden ESP/Ezra */ |
131 | {X86_VENDOR_UNKNOWN, ANY, ANY, 0} /* stop here */ | 142 | {X86_VENDOR_CENTAUR, 0x6, 0x8, 0x7, 85}, /* Ezra T */ |
143 | {X86_VENDOR_CENTAUR, 0x6, 0x9, 0x7, 85}, /* Nemiah */ | ||
144 | {X86_VENDOR_CENTAUR, 0x6, 0x9, ANY, 17}, /* C3-M */ | ||
145 | {X86_VENDOR_UNKNOWN, ANY, ANY, ANY, 0} /* stop here */ | ||
132 | }; | 146 | }; |
133 | 147 | ||
134 | static int find_vrm(u8 eff_family, u8 eff_model, u8 vendor) | 148 | static u8 find_vrm(u8 eff_family, u8 eff_model, u8 eff_stepping, u8 vendor) |
135 | { | 149 | { |
136 | int i = 0; | 150 | int i = 0; |
137 | 151 | ||
@@ -139,7 +153,8 @@ static int find_vrm(u8 eff_family, u8 eff_model, u8 vendor) | |||
139 | if (vrm_models[i].vendor==vendor) | 153 | if (vrm_models[i].vendor==vendor) |
140 | if ((vrm_models[i].eff_family==eff_family) | 154 | if ((vrm_models[i].eff_family==eff_family) |
141 | && ((vrm_models[i].eff_model==eff_model) || | 155 | && ((vrm_models[i].eff_model==eff_model) || |
142 | (vrm_models[i].eff_model==ANY))) | 156 | (vrm_models[i].eff_model==ANY)) && |
157 | (eff_stepping <= vrm_models[i].eff_stepping)) | ||
143 | return vrm_models[i].vrm_type; | 158 | return vrm_models[i].vrm_type; |
144 | i++; | 159 | i++; |
145 | } | 160 | } |
@@ -147,12 +162,11 @@ static int find_vrm(u8 eff_family, u8 eff_model, u8 vendor) | |||
147 | return 0; | 162 | return 0; |
148 | } | 163 | } |
149 | 164 | ||
150 | int vid_which_vrm(void) | 165 | u8 vid_which_vrm(void) |
151 | { | 166 | { |
152 | struct cpuinfo_x86 *c = cpu_data; | 167 | struct cpuinfo_x86 *c = cpu_data; |
153 | u32 eax; | 168 | u32 eax; |
154 | u8 eff_family, eff_model; | 169 | u8 eff_family, eff_model, eff_stepping, vrm_ret; |
155 | int vrm_ret; | ||
156 | 170 | ||
157 | if (c->x86 < 6) /* Any CPU with family lower than 6 */ | 171 | if (c->x86 < 6) /* Any CPU with family lower than 6 */ |
158 | return 0; /* doesn't have VID and/or CPUID */ | 172 | return 0; /* doesn't have VID and/or CPUID */ |
@@ -160,20 +174,21 @@ int vid_which_vrm(void) | |||
160 | eax = cpuid_eax(1); | 174 | eax = cpuid_eax(1); |
161 | eff_family = ((eax & 0x00000F00)>>8); | 175 | eff_family = ((eax & 0x00000F00)>>8); |
162 | eff_model = ((eax & 0x000000F0)>>4); | 176 | eff_model = ((eax & 0x000000F0)>>4); |
177 | eff_stepping = eax & 0xF; | ||
163 | if (eff_family == 0xF) { /* use extended model & family */ | 178 | if (eff_family == 0xF) { /* use extended model & family */ |
164 | eff_family += ((eax & 0x00F00000)>>20); | 179 | eff_family += ((eax & 0x00F00000)>>20); |
165 | eff_model += ((eax & 0x000F0000)>>16)<<4; | 180 | eff_model += ((eax & 0x000F0000)>>16)<<4; |
166 | } | 181 | } |
167 | vrm_ret = find_vrm(eff_family,eff_model,c->x86_vendor); | 182 | vrm_ret = find_vrm(eff_family, eff_model, eff_stepping, c->x86_vendor); |
168 | if (vrm_ret == 0) | 183 | if (vrm_ret == 0) |
169 | printk(KERN_INFO "hwmon-vid: Unknown VRM version of your " | 184 | printk(KERN_INFO "hwmon-vid: Unknown VRM version of your " |
170 | "x86 CPU\n"); | 185 | "x86 CPU\n"); |
171 | return vrm_ret; | 186 | return vrm_ret; |
172 | } | 187 | } |
173 | 188 | ||
174 | /* and now something completely different for the non-x86 world */ | 189 | /* and now for something completely different for the non-x86 world */ |
175 | #else | 190 | #else |
176 | int vid_which_vrm(void) | 191 | u8 vid_which_vrm(void) |
177 | { | 192 | { |
178 | printk(KERN_INFO "hwmon-vid: Unknown VRM version of your CPU\n"); | 193 | printk(KERN_INFO "hwmon-vid: Unknown VRM version of your CPU\n"); |
179 | return 0; | 194 | return 0; |
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index a61f5d00f10a..0da7c9c508c3 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
@@ -213,7 +213,7 @@ struct it87_data { | |||
213 | u8 sensor; /* Register value */ | 213 | u8 sensor; /* Register value */ |
214 | u8 fan_div[3]; /* Register encoding, shifted right */ | 214 | u8 fan_div[3]; /* Register encoding, shifted right */ |
215 | u8 vid; /* Register encoding, combined */ | 215 | u8 vid; /* Register encoding, combined */ |
216 | int vrm; | 216 | u8 vrm; |
217 | u32 alarms; /* Register encoding, combined */ | 217 | u32 alarms; /* Register encoding, combined */ |
218 | u8 fan_main_ctrl; /* Register value */ | 218 | u8 fan_main_ctrl; /* Register value */ |
219 | u8 manual_pwm_ctl[3]; /* manual PWM value set by user */ | 219 | u8 manual_pwm_ctl[3]; /* manual PWM value set by user */ |
@@ -234,17 +234,18 @@ static void it87_init_client(struct i2c_client *client, struct it87_data *data); | |||
234 | 234 | ||
235 | 235 | ||
236 | static struct i2c_driver it87_driver = { | 236 | static struct i2c_driver it87_driver = { |
237 | .owner = THIS_MODULE, | 237 | .driver = { |
238 | .name = "it87", | 238 | .name = "it87", |
239 | }, | ||
239 | .id = I2C_DRIVERID_IT87, | 240 | .id = I2C_DRIVERID_IT87, |
240 | .flags = I2C_DF_NOTIFY, | ||
241 | .attach_adapter = it87_attach_adapter, | 241 | .attach_adapter = it87_attach_adapter, |
242 | .detach_client = it87_detach_client, | 242 | .detach_client = it87_detach_client, |
243 | }; | 243 | }; |
244 | 244 | ||
245 | static struct i2c_driver it87_isa_driver = { | 245 | static struct i2c_driver it87_isa_driver = { |
246 | .owner = THIS_MODULE, | 246 | .driver = { |
247 | .name = "it87-isa", | 247 | .name = "it87-isa", |
248 | }, | ||
248 | .attach_adapter = it87_isa_attach_adapter, | 249 | .attach_adapter = it87_isa_attach_adapter, |
249 | .detach_client = it87_detach_client, | 250 | .detach_client = it87_detach_client, |
250 | }; | 251 | }; |
@@ -668,7 +669,7 @@ static ssize_t | |||
668 | show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) | 669 | show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) |
669 | { | 670 | { |
670 | struct it87_data *data = it87_update_device(dev); | 671 | struct it87_data *data = it87_update_device(dev); |
671 | return sprintf(buf, "%ld\n", (long) data->vrm); | 672 | return sprintf(buf, "%u\n", data->vrm); |
672 | } | 673 | } |
673 | static ssize_t | 674 | static ssize_t |
674 | store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 675 | store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
@@ -761,7 +762,8 @@ static int it87_detect(struct i2c_adapter *adapter, int address, int kind) | |||
761 | 762 | ||
762 | /* Reserve the ISA region */ | 763 | /* Reserve the ISA region */ |
763 | if (is_isa) | 764 | if (is_isa) |
764 | if (!request_region(address, IT87_EXTENT, it87_isa_driver.name)) | 765 | if (!request_region(address, IT87_EXTENT, |
766 | it87_isa_driver.driver.name)) | ||
765 | goto ERROR0; | 767 | goto ERROR0; |
766 | 768 | ||
767 | /* For now, we presume we have a valid client. We create the | 769 | /* For now, we presume we have a valid client. We create the |
diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c index 954ec2497249..6b1aa7ef552e 100644 --- a/drivers/hwmon/lm63.c +++ b/drivers/hwmon/lm63.c | |||
@@ -139,9 +139,9 @@ static void lm63_init_client(struct i2c_client *client); | |||
139 | */ | 139 | */ |
140 | 140 | ||
141 | static struct i2c_driver lm63_driver = { | 141 | static struct i2c_driver lm63_driver = { |
142 | .owner = THIS_MODULE, | 142 | .driver = { |
143 | .name = "lm63", | 143 | .name = "lm63", |
144 | .flags = I2C_DF_NOTIFY, | 144 | }, |
145 | .attach_adapter = lm63_attach_adapter, | 145 | .attach_adapter = lm63_attach_adapter, |
146 | .detach_client = lm63_detach_client, | 146 | .detach_client = lm63_detach_client, |
147 | }; | 147 | }; |
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index d70f4c8fc1e6..74ca2c8c61c3 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c | |||
@@ -66,10 +66,10 @@ static struct lm75_data *lm75_update_device(struct device *dev); | |||
66 | 66 | ||
67 | /* This is the driver that will be inserted */ | 67 | /* This is the driver that will be inserted */ |
68 | static struct i2c_driver lm75_driver = { | 68 | static struct i2c_driver lm75_driver = { |
69 | .owner = THIS_MODULE, | 69 | .driver = { |
70 | .name = "lm75", | 70 | .name = "lm75", |
71 | }, | ||
71 | .id = I2C_DRIVERID_LM75, | 72 | .id = I2C_DRIVERID_LM75, |
72 | .flags = I2C_DF_NOTIFY, | ||
73 | .attach_adapter = lm75_attach_adapter, | 73 | .attach_adapter = lm75_attach_adapter, |
74 | .detach_client = lm75_detach_client, | 74 | .detach_client = lm75_detach_client, |
75 | }; | 75 | }; |
diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c index 9380fda7dcd1..a2f420d01fb7 100644 --- a/drivers/hwmon/lm77.c +++ b/drivers/hwmon/lm77.c | |||
@@ -74,9 +74,9 @@ static struct lm77_data *lm77_update_device(struct device *dev); | |||
74 | 74 | ||
75 | /* This is the driver that will be inserted */ | 75 | /* This is the driver that will be inserted */ |
76 | static struct i2c_driver lm77_driver = { | 76 | static struct i2c_driver lm77_driver = { |
77 | .owner = THIS_MODULE, | 77 | .driver = { |
78 | .name = "lm77", | 78 | .name = "lm77", |
79 | .flags = I2C_DF_NOTIFY, | 79 | }, |
80 | .attach_adapter = lm77_attach_adapter, | 80 | .attach_adapter = lm77_attach_adapter, |
81 | .detach_client = lm77_detach_client, | 81 | .detach_client = lm77_detach_client, |
82 | }; | 82 | }; |
diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c index 78cdd506439f..e404001e20da 100644 --- a/drivers/hwmon/lm78.c +++ b/drivers/hwmon/lm78.c | |||
@@ -164,17 +164,18 @@ static void lm78_init_client(struct i2c_client *client); | |||
164 | 164 | ||
165 | 165 | ||
166 | static struct i2c_driver lm78_driver = { | 166 | static struct i2c_driver lm78_driver = { |
167 | .owner = THIS_MODULE, | 167 | .driver = { |
168 | .name = "lm78", | 168 | .name = "lm78", |
169 | }, | ||
169 | .id = I2C_DRIVERID_LM78, | 170 | .id = I2C_DRIVERID_LM78, |
170 | .flags = I2C_DF_NOTIFY, | ||
171 | .attach_adapter = lm78_attach_adapter, | 171 | .attach_adapter = lm78_attach_adapter, |
172 | .detach_client = lm78_detach_client, | 172 | .detach_client = lm78_detach_client, |
173 | }; | 173 | }; |
174 | 174 | ||
175 | static struct i2c_driver lm78_isa_driver = { | 175 | static struct i2c_driver lm78_isa_driver = { |
176 | .owner = THIS_MODULE, | 176 | .driver = { |
177 | .name = "lm78-isa", | 177 | .name = "lm78-isa", |
178 | }, | ||
178 | .attach_adapter = lm78_isa_attach_adapter, | 179 | .attach_adapter = lm78_isa_attach_adapter, |
179 | .detach_client = lm78_detach_client, | 180 | .detach_client = lm78_detach_client, |
180 | }; | 181 | }; |
@@ -497,7 +498,7 @@ static int lm78_detect(struct i2c_adapter *adapter, int address, int kind) | |||
497 | /* Reserve the ISA region */ | 498 | /* Reserve the ISA region */ |
498 | if (is_isa) | 499 | if (is_isa) |
499 | if (!request_region(address, LM78_EXTENT, | 500 | if (!request_region(address, LM78_EXTENT, |
500 | lm78_isa_driver.name)) { | 501 | lm78_isa_driver.driver.name)) { |
501 | err = -EBUSY; | 502 | err = -EBUSY; |
502 | goto ERROR0; | 503 | goto ERROR0; |
503 | } | 504 | } |
diff --git a/drivers/hwmon/lm80.c b/drivers/hwmon/lm80.c index c359fdea211e..c9a7cdea7bd7 100644 --- a/drivers/hwmon/lm80.c +++ b/drivers/hwmon/lm80.c | |||
@@ -143,10 +143,10 @@ static int lm80_write_value(struct i2c_client *client, u8 reg, u8 value); | |||
143 | */ | 143 | */ |
144 | 144 | ||
145 | static struct i2c_driver lm80_driver = { | 145 | static struct i2c_driver lm80_driver = { |
146 | .owner = THIS_MODULE, | 146 | .driver = { |
147 | .name = "lm80", | 147 | .name = "lm80", |
148 | }, | ||
148 | .id = I2C_DRIVERID_LM80, | 149 | .id = I2C_DRIVERID_LM80, |
149 | .flags = I2C_DF_NOTIFY, | ||
150 | .attach_adapter = lm80_attach_adapter, | 150 | .attach_adapter = lm80_attach_adapter, |
151 | .detach_client = lm80_detach_client, | 151 | .detach_client = lm80_detach_client, |
152 | }; | 152 | }; |
diff --git a/drivers/hwmon/lm83.c b/drivers/hwmon/lm83.c index 9a70611a9f69..26dfa9e216c2 100644 --- a/drivers/hwmon/lm83.c +++ b/drivers/hwmon/lm83.c | |||
@@ -124,10 +124,10 @@ static struct lm83_data *lm83_update_device(struct device *dev); | |||
124 | */ | 124 | */ |
125 | 125 | ||
126 | static struct i2c_driver lm83_driver = { | 126 | static struct i2c_driver lm83_driver = { |
127 | .owner = THIS_MODULE, | 127 | .driver = { |
128 | .name = "lm83", | 128 | .name = "lm83", |
129 | }, | ||
129 | .id = I2C_DRIVERID_LM83, | 130 | .id = I2C_DRIVERID_LM83, |
130 | .flags = I2C_DF_NOTIFY, | ||
131 | .attach_adapter = lm83_attach_adapter, | 131 | .attach_adapter = lm83_attach_adapter, |
132 | .detach_client = lm83_detach_client, | 132 | .detach_client = lm83_detach_client, |
133 | }; | 133 | }; |
diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c index d1070ed2bee6..7389a0127547 100644 --- a/drivers/hwmon/lm85.c +++ b/drivers/hwmon/lm85.c | |||
@@ -380,10 +380,10 @@ static void lm85_init_client(struct i2c_client *client); | |||
380 | 380 | ||
381 | 381 | ||
382 | static struct i2c_driver lm85_driver = { | 382 | static struct i2c_driver lm85_driver = { |
383 | .owner = THIS_MODULE, | 383 | .driver = { |
384 | .name = "lm85", | 384 | .name = "lm85", |
385 | }, | ||
385 | .id = I2C_DRIVERID_LM85, | 386 | .id = I2C_DRIVERID_LM85, |
386 | .flags = I2C_DF_NOTIFY, | ||
387 | .attach_adapter = lm85_attach_adapter, | 387 | .attach_adapter = lm85_attach_adapter, |
388 | .detach_client = lm85_detach_client, | 388 | .detach_client = lm85_detach_client, |
389 | }; | 389 | }; |
@@ -443,7 +443,17 @@ show_fan_offset(4); | |||
443 | static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf) | 443 | static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf) |
444 | { | 444 | { |
445 | struct lm85_data *data = lm85_update_device(dev); | 445 | struct lm85_data *data = lm85_update_device(dev); |
446 | return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm)); | 446 | int vid; |
447 | |||
448 | if (data->type == adt7463 && (data->vid & 0x80)) { | ||
449 | /* 6-pin VID (VRM 10) */ | ||
450 | vid = vid_from_reg(data->vid & 0x3f, data->vrm); | ||
451 | } else { | ||
452 | /* 5-pin VID (VRM 9) */ | ||
453 | vid = vid_from_reg(data->vid & 0x1f, data->vrm); | ||
454 | } | ||
455 | |||
456 | return sprintf(buf, "%d\n", vid); | ||
447 | } | 457 | } |
448 | 458 | ||
449 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); | 459 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); |
@@ -1176,17 +1186,14 @@ static int lm85_detect(struct i2c_adapter *adapter, int address, | |||
1176 | device_create_file(&new_client->dev, &dev_attr_in1_input); | 1186 | device_create_file(&new_client->dev, &dev_attr_in1_input); |
1177 | device_create_file(&new_client->dev, &dev_attr_in2_input); | 1187 | device_create_file(&new_client->dev, &dev_attr_in2_input); |
1178 | device_create_file(&new_client->dev, &dev_attr_in3_input); | 1188 | device_create_file(&new_client->dev, &dev_attr_in3_input); |
1179 | device_create_file(&new_client->dev, &dev_attr_in4_input); | ||
1180 | device_create_file(&new_client->dev, &dev_attr_in0_min); | 1189 | device_create_file(&new_client->dev, &dev_attr_in0_min); |
1181 | device_create_file(&new_client->dev, &dev_attr_in1_min); | 1190 | device_create_file(&new_client->dev, &dev_attr_in1_min); |
1182 | device_create_file(&new_client->dev, &dev_attr_in2_min); | 1191 | device_create_file(&new_client->dev, &dev_attr_in2_min); |
1183 | device_create_file(&new_client->dev, &dev_attr_in3_min); | 1192 | device_create_file(&new_client->dev, &dev_attr_in3_min); |
1184 | device_create_file(&new_client->dev, &dev_attr_in4_min); | ||
1185 | device_create_file(&new_client->dev, &dev_attr_in0_max); | 1193 | device_create_file(&new_client->dev, &dev_attr_in0_max); |
1186 | device_create_file(&new_client->dev, &dev_attr_in1_max); | 1194 | device_create_file(&new_client->dev, &dev_attr_in1_max); |
1187 | device_create_file(&new_client->dev, &dev_attr_in2_max); | 1195 | device_create_file(&new_client->dev, &dev_attr_in2_max); |
1188 | device_create_file(&new_client->dev, &dev_attr_in3_max); | 1196 | device_create_file(&new_client->dev, &dev_attr_in3_max); |
1189 | device_create_file(&new_client->dev, &dev_attr_in4_max); | ||
1190 | device_create_file(&new_client->dev, &dev_attr_temp1_input); | 1197 | device_create_file(&new_client->dev, &dev_attr_temp1_input); |
1191 | device_create_file(&new_client->dev, &dev_attr_temp2_input); | 1198 | device_create_file(&new_client->dev, &dev_attr_temp2_input); |
1192 | device_create_file(&new_client->dev, &dev_attr_temp3_input); | 1199 | device_create_file(&new_client->dev, &dev_attr_temp3_input); |
@@ -1224,6 +1231,15 @@ static int lm85_detect(struct i2c_adapter *adapter, int address, | |||
1224 | device_create_file(&new_client->dev, &dev_attr_temp2_auto_temp_crit); | 1231 | device_create_file(&new_client->dev, &dev_attr_temp2_auto_temp_crit); |
1225 | device_create_file(&new_client->dev, &dev_attr_temp3_auto_temp_crit); | 1232 | device_create_file(&new_client->dev, &dev_attr_temp3_auto_temp_crit); |
1226 | 1233 | ||
1234 | /* The ADT7463 has an optional VRM 10 mode where pin 21 is used | ||
1235 | as a sixth digital VID input rather than an analog input. */ | ||
1236 | data->vid = lm85_read_value(new_client, LM85_REG_VID); | ||
1237 | if (!(kind == adt7463 && (data->vid & 0x80))) { | ||
1238 | device_create_file(&new_client->dev, &dev_attr_in4_input); | ||
1239 | device_create_file(&new_client->dev, &dev_attr_in4_min); | ||
1240 | device_create_file(&new_client->dev, &dev_attr_in4_max); | ||
1241 | } | ||
1242 | |||
1227 | return 0; | 1243 | return 0; |
1228 | 1244 | ||
1229 | /* Error out and cleanup code */ | 1245 | /* Error out and cleanup code */ |
@@ -1382,11 +1398,18 @@ static struct lm85_data *lm85_update_device(struct device *dev) | |||
1382 | irrelevant. So it is left in 4*/ | 1398 | irrelevant. So it is left in 4*/ |
1383 | data->adc_scale = (data->type == emc6d102 ) ? 16 : 4; | 1399 | data->adc_scale = (data->type == emc6d102 ) ? 16 : 4; |
1384 | 1400 | ||
1385 | for (i = 0; i <= 4; ++i) { | 1401 | data->vid = lm85_read_value(client, LM85_REG_VID); |
1402 | |||
1403 | for (i = 0; i <= 3; ++i) { | ||
1386 | data->in[i] = | 1404 | data->in[i] = |
1387 | lm85_read_value(client, LM85_REG_IN(i)); | 1405 | lm85_read_value(client, LM85_REG_IN(i)); |
1388 | } | 1406 | } |
1389 | 1407 | ||
1408 | if (!(data->type == adt7463 && (data->vid & 0x80))) { | ||
1409 | data->in[4] = lm85_read_value(client, | ||
1410 | LM85_REG_IN(4)); | ||
1411 | } | ||
1412 | |||
1390 | for (i = 0; i <= 3; ++i) { | 1413 | for (i = 0; i <= 3; ++i) { |
1391 | data->fan[i] = | 1414 | data->fan[i] = |
1392 | lm85_read_value(client, LM85_REG_FAN(i)); | 1415 | lm85_read_value(client, LM85_REG_FAN(i)); |
@@ -1450,13 +1473,20 @@ static struct lm85_data *lm85_update_device(struct device *dev) | |||
1450 | /* Things that don't change often */ | 1473 | /* Things that don't change often */ |
1451 | dev_dbg(&client->dev, "Reading config values\n"); | 1474 | dev_dbg(&client->dev, "Reading config values\n"); |
1452 | 1475 | ||
1453 | for (i = 0; i <= 4; ++i) { | 1476 | for (i = 0; i <= 3; ++i) { |
1454 | data->in_min[i] = | 1477 | data->in_min[i] = |
1455 | lm85_read_value(client, LM85_REG_IN_MIN(i)); | 1478 | lm85_read_value(client, LM85_REG_IN_MIN(i)); |
1456 | data->in_max[i] = | 1479 | data->in_max[i] = |
1457 | lm85_read_value(client, LM85_REG_IN_MAX(i)); | 1480 | lm85_read_value(client, LM85_REG_IN_MAX(i)); |
1458 | } | 1481 | } |
1459 | 1482 | ||
1483 | if (!(data->type == adt7463 && (data->vid & 0x80))) { | ||
1484 | data->in_min[4] = lm85_read_value(client, | ||
1485 | LM85_REG_IN_MIN(4)); | ||
1486 | data->in_max[4] = lm85_read_value(client, | ||
1487 | LM85_REG_IN_MAX(4)); | ||
1488 | } | ||
1489 | |||
1460 | if ( data->type == emc6d100 ) { | 1490 | if ( data->type == emc6d100 ) { |
1461 | for (i = 5; i <= 7; ++i) { | 1491 | for (i = 5; i <= 7; ++i) { |
1462 | data->in_min[i] = | 1492 | data->in_min[i] = |
@@ -1478,8 +1508,6 @@ static struct lm85_data *lm85_update_device(struct device *dev) | |||
1478 | lm85_read_value(client, LM85_REG_TEMP_MAX(i)); | 1508 | lm85_read_value(client, LM85_REG_TEMP_MAX(i)); |
1479 | } | 1509 | } |
1480 | 1510 | ||
1481 | data->vid = lm85_read_value(client, LM85_REG_VID); | ||
1482 | |||
1483 | for (i = 0; i <= 2; ++i) { | 1511 | for (i = 0; i <= 2; ++i) { |
1484 | int val ; | 1512 | int val ; |
1485 | data->autofan[i].config = | 1513 | data->autofan[i].config = |
diff --git a/drivers/hwmon/lm87.c b/drivers/hwmon/lm87.c index eeec18177861..6ba34c302d8d 100644 --- a/drivers/hwmon/lm87.c +++ b/drivers/hwmon/lm87.c | |||
@@ -161,10 +161,10 @@ static struct lm87_data *lm87_update_device(struct device *dev); | |||
161 | */ | 161 | */ |
162 | 162 | ||
163 | static struct i2c_driver lm87_driver = { | 163 | static struct i2c_driver lm87_driver = { |
164 | .owner = THIS_MODULE, | 164 | .driver = { |
165 | .name = "lm87", | 165 | .name = "lm87", |
166 | }, | ||
166 | .id = I2C_DRIVERID_LM87, | 167 | .id = I2C_DRIVERID_LM87, |
167 | .flags = I2C_DF_NOTIFY, | ||
168 | .attach_adapter = lm87_attach_adapter, | 168 | .attach_adapter = lm87_attach_adapter, |
169 | .detach_client = lm87_detach_client, | 169 | .detach_client = lm87_detach_client, |
170 | }; | 170 | }; |
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index 83cf2e1b09f5..5679464447cc 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c | |||
@@ -186,10 +186,10 @@ static struct lm90_data *lm90_update_device(struct device *dev); | |||
186 | */ | 186 | */ |
187 | 187 | ||
188 | static struct i2c_driver lm90_driver = { | 188 | static struct i2c_driver lm90_driver = { |
189 | .owner = THIS_MODULE, | 189 | .driver = { |
190 | .name = "lm90", | 190 | .name = "lm90", |
191 | }, | ||
191 | .id = I2C_DRIVERID_LM90, | 192 | .id = I2C_DRIVERID_LM90, |
192 | .flags = I2C_DF_NOTIFY, | ||
193 | .attach_adapter = lm90_attach_adapter, | 193 | .attach_adapter = lm90_attach_adapter, |
194 | .detach_client = lm90_detach_client, | 194 | .detach_client = lm90_detach_client, |
195 | }; | 195 | }; |
diff --git a/drivers/hwmon/lm92.c b/drivers/hwmon/lm92.c index 7a4b3701ed1a..b0c4cb730a7e 100644 --- a/drivers/hwmon/lm92.c +++ b/drivers/hwmon/lm92.c | |||
@@ -410,10 +410,10 @@ static int lm92_detach_client(struct i2c_client *client) | |||
410 | */ | 410 | */ |
411 | 411 | ||
412 | static struct i2c_driver lm92_driver = { | 412 | static struct i2c_driver lm92_driver = { |
413 | .owner = THIS_MODULE, | 413 | .driver = { |
414 | .name = "lm92", | 414 | .name = "lm92", |
415 | }, | ||
415 | .id = I2C_DRIVERID_LM92, | 416 | .id = I2C_DRIVERID_LM92, |
416 | .flags = I2C_DF_NOTIFY, | ||
417 | .attach_adapter = lm92_attach_adapter, | 417 | .attach_adapter = lm92_attach_adapter, |
418 | .detach_client = lm92_detach_client, | 418 | .detach_client = lm92_detach_client, |
419 | }; | 419 | }; |
diff --git a/drivers/hwmon/max1619.c b/drivers/hwmon/max1619.c index 69e7e125683b..3abe330b22ce 100644 --- a/drivers/hwmon/max1619.c +++ b/drivers/hwmon/max1619.c | |||
@@ -90,9 +90,9 @@ static struct max1619_data *max1619_update_device(struct device *dev); | |||
90 | */ | 90 | */ |
91 | 91 | ||
92 | static struct i2c_driver max1619_driver = { | 92 | static struct i2c_driver max1619_driver = { |
93 | .owner = THIS_MODULE, | 93 | .driver = { |
94 | .name = "max1619", | 94 | .name = "max1619", |
95 | .flags = I2C_DF_NOTIFY, | 95 | }, |
96 | .attach_adapter = max1619_attach_adapter, | 96 | .attach_adapter = max1619_attach_adapter, |
97 | .detach_client = max1619_detach_client, | 97 | .detach_client = max1619_detach_client, |
98 | }; | 98 | }; |
diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c index 17f745a23d04..f161e88e3bb6 100644 --- a/drivers/hwmon/pc87360.c +++ b/drivers/hwmon/pc87360.c | |||
@@ -236,8 +236,9 @@ static struct pc87360_data *pc87360_update_device(struct device *dev); | |||
236 | */ | 236 | */ |
237 | 237 | ||
238 | static struct i2c_driver pc87360_driver = { | 238 | static struct i2c_driver pc87360_driver = { |
239 | .owner = THIS_MODULE, | 239 | .driver = { |
240 | .name = "pc87360", | 240 | .name = "pc87360", |
241 | }, | ||
241 | .attach_adapter = pc87360_detect, | 242 | .attach_adapter = pc87360_detect, |
242 | .detach_client = pc87360_detach_client, | 243 | .detach_client = pc87360_detach_client, |
243 | }; | 244 | }; |
@@ -798,7 +799,7 @@ static int pc87360_detect(struct i2c_adapter *adapter) | |||
798 | for (i = 0; i < 3; i++) { | 799 | for (i = 0; i < 3; i++) { |
799 | if (((data->address[i] = extra_isa[i])) | 800 | if (((data->address[i] = extra_isa[i])) |
800 | && !request_region(extra_isa[i], PC87360_EXTENT, | 801 | && !request_region(extra_isa[i], PC87360_EXTENT, |
801 | pc87360_driver.name)) { | 802 | pc87360_driver.driver.name)) { |
802 | dev_err(&new_client->dev, "Region 0x%x-0x%x already " | 803 | dev_err(&new_client->dev, "Region 0x%x-0x%x already " |
803 | "in use!\n", extra_isa[i], | 804 | "in use!\n", extra_isa[i], |
804 | extra_isa[i]+PC87360_EXTENT-1); | 805 | extra_isa[i]+PC87360_EXTENT-1); |
diff --git a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c index 9c6cadec1087..8be5189d9bd9 100644 --- a/drivers/hwmon/sis5595.c +++ b/drivers/hwmon/sis5595.c | |||
@@ -198,8 +198,9 @@ static struct sis5595_data *sis5595_update_device(struct device *dev); | |||
198 | static void sis5595_init_client(struct i2c_client *client); | 198 | static void sis5595_init_client(struct i2c_client *client); |
199 | 199 | ||
200 | static struct i2c_driver sis5595_driver = { | 200 | static struct i2c_driver sis5595_driver = { |
201 | .owner = THIS_MODULE, | 201 | .driver = { |
202 | .name = "sis5595", | 202 | .name = "sis5595", |
203 | }, | ||
203 | .attach_adapter = sis5595_detect, | 204 | .attach_adapter = sis5595_detect, |
204 | .detach_client = sis5595_detach_client, | 205 | .detach_client = sis5595_detach_client, |
205 | }; | 206 | }; |
@@ -484,7 +485,8 @@ static int sis5595_detect(struct i2c_adapter *adapter) | |||
484 | if (force_addr) | 485 | if (force_addr) |
485 | address = force_addr & ~(SIS5595_EXTENT - 1); | 486 | address = force_addr & ~(SIS5595_EXTENT - 1); |
486 | /* Reserve the ISA region */ | 487 | /* Reserve the ISA region */ |
487 | if (!request_region(address, SIS5595_EXTENT, sis5595_driver.name)) { | 488 | if (!request_region(address, SIS5595_EXTENT, |
489 | sis5595_driver.driver.name)) { | ||
488 | err = -EBUSY; | 490 | err = -EBUSY; |
489 | goto exit; | 491 | goto exit; |
490 | } | 492 | } |
diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c index 2a3e21b5b6b4..8663bbbe97f5 100644 --- a/drivers/hwmon/smsc47b397.c +++ b/drivers/hwmon/smsc47b397.c | |||
@@ -226,8 +226,9 @@ static int smsc47b397_detach_client(struct i2c_client *client) | |||
226 | static int smsc47b397_detect(struct i2c_adapter *adapter); | 226 | static int smsc47b397_detect(struct i2c_adapter *adapter); |
227 | 227 | ||
228 | static struct i2c_driver smsc47b397_driver = { | 228 | static struct i2c_driver smsc47b397_driver = { |
229 | .owner = THIS_MODULE, | 229 | .driver = { |
230 | .name = "smsc47b397", | 230 | .name = "smsc47b397", |
231 | }, | ||
231 | .attach_adapter = smsc47b397_detect, | 232 | .attach_adapter = smsc47b397_detect, |
232 | .detach_client = smsc47b397_detach_client, | 233 | .detach_client = smsc47b397_detach_client, |
233 | }; | 234 | }; |
@@ -238,7 +239,8 @@ static int smsc47b397_detect(struct i2c_adapter *adapter) | |||
238 | struct smsc47b397_data *data; | 239 | struct smsc47b397_data *data; |
239 | int err = 0; | 240 | int err = 0; |
240 | 241 | ||
241 | if (!request_region(address, SMSC_EXTENT, smsc47b397_driver.name)) { | 242 | if (!request_region(address, SMSC_EXTENT, |
243 | smsc47b397_driver.driver.name)) { | ||
242 | dev_err(&adapter->dev, "Region 0x%x already in use!\n", | 244 | dev_err(&adapter->dev, "Region 0x%x already in use!\n", |
243 | address); | 245 | address); |
244 | return -EBUSY; | 246 | return -EBUSY; |
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c index 5905c1af88f2..d1e3ec0fe4df 100644 --- a/drivers/hwmon/smsc47m1.c +++ b/drivers/hwmon/smsc47m1.c | |||
@@ -126,8 +126,9 @@ static struct smsc47m1_data *smsc47m1_update_device(struct device *dev, | |||
126 | 126 | ||
127 | 127 | ||
128 | static struct i2c_driver smsc47m1_driver = { | 128 | static struct i2c_driver smsc47m1_driver = { |
129 | .owner = THIS_MODULE, | 129 | .driver = { |
130 | .name = "smsc47m1", | 130 | .name = "smsc47m1", |
131 | }, | ||
131 | .attach_adapter = smsc47m1_detect, | 132 | .attach_adapter = smsc47m1_detect, |
132 | .detach_client = smsc47m1_detach_client, | 133 | .detach_client = smsc47m1_detach_client, |
133 | }; | 134 | }; |
@@ -394,7 +395,7 @@ static int smsc47m1_detect(struct i2c_adapter *adapter) | |||
394 | int err = 0; | 395 | int err = 0; |
395 | int fan1, fan2, pwm1, pwm2; | 396 | int fan1, fan2, pwm1, pwm2; |
396 | 397 | ||
397 | if (!request_region(address, SMSC_EXTENT, smsc47m1_driver.name)) { | 398 | if (!request_region(address, SMSC_EXTENT, smsc47m1_driver.driver.name)) { |
398 | dev_err(&adapter->dev, "Region 0x%x already in use!\n", address); | 399 | dev_err(&adapter->dev, "Region 0x%x already in use!\n", address); |
399 | return -EBUSY; | 400 | return -EBUSY; |
400 | } | 401 | } |
diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c index 6f696f897176..cb01848729b5 100644 --- a/drivers/hwmon/via686a.c +++ b/drivers/hwmon/via686a.c | |||
@@ -572,8 +572,9 @@ static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | |||
572 | /* The driver. I choose to use type i2c_driver, as at is identical to both | 572 | /* The driver. I choose to use type i2c_driver, as at is identical to both |
573 | smbus_driver and isa_driver, and clients could be of either kind */ | 573 | smbus_driver and isa_driver, and clients could be of either kind */ |
574 | static struct i2c_driver via686a_driver = { | 574 | static struct i2c_driver via686a_driver = { |
575 | .owner = THIS_MODULE, | 575 | .driver = { |
576 | .name = "via686a", | 576 | .name = "via686a", |
577 | }, | ||
577 | .attach_adapter = via686a_detect, | 578 | .attach_adapter = via686a_detect, |
578 | .detach_client = via686a_detach_client, | 579 | .detach_client = via686a_detach_client, |
579 | }; | 580 | }; |
@@ -615,7 +616,8 @@ static int via686a_detect(struct i2c_adapter *adapter) | |||
615 | } | 616 | } |
616 | 617 | ||
617 | /* Reserve the ISA region */ | 618 | /* Reserve the ISA region */ |
618 | if (!request_region(address, VIA686A_EXTENT, via686a_driver.name)) { | 619 | if (!request_region(address, VIA686A_EXTENT, |
620 | via686a_driver.driver.name)) { | ||
619 | dev_err(&adapter->dev, "region 0x%x already in use!\n", | 621 | dev_err(&adapter->dev, "region 0x%x already in use!\n", |
620 | address); | 622 | address); |
621 | return -ENODEV; | 623 | return -ENODEV; |
diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c new file mode 100644 index 000000000000..d00a726d0239 --- /dev/null +++ b/drivers/hwmon/vt8231.c | |||
@@ -0,0 +1,862 @@ | |||
1 | /* | ||
2 | vt8231.c - Part of lm_sensors, Linux kernel modules | ||
3 | for hardware monitoring | ||
4 | |||
5 | Copyright (c) 2005 Roger Lucas <roger@planbit.co.uk> | ||
6 | Copyright (c) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com> | ||
7 | Aaron M. Marsh <amarsh@sdf.lonestar.org> | ||
8 | |||
9 | This program is free software; you can redistribute it and/or modify | ||
10 | it under the terms of the GNU General Public License as published by | ||
11 | the Free Software Foundation; either version 2 of the License, or | ||
12 | (at your option) any later version. | ||
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., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | */ | ||
23 | |||
24 | /* Supports VIA VT8231 South Bridge embedded sensors | ||
25 | */ | ||
26 | |||
27 | #include <linux/module.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/slab.h> | ||
30 | #include <linux/pci.h> | ||
31 | #include <linux/jiffies.h> | ||
32 | #include <linux/i2c.h> | ||
33 | #include <linux/i2c-isa.h> | ||
34 | #include <linux/hwmon.h> | ||
35 | #include <linux/hwmon-sysfs.h> | ||
36 | #include <linux/hwmon-vid.h> | ||
37 | #include <linux/err.h> | ||
38 | #include <asm/io.h> | ||
39 | |||
40 | static int force_addr; | ||
41 | module_param(force_addr, int, 0); | ||
42 | MODULE_PARM_DESC(force_addr, "Initialize the base address of the sensors"); | ||
43 | |||
44 | /* Device address | ||
45 | Note that we can't determine the ISA address until we have initialized | ||
46 | our module */ | ||
47 | static unsigned short isa_address; | ||
48 | |||
49 | #define VT8231_EXTENT 0x80 | ||
50 | #define VT8231_BASE_REG 0x70 | ||
51 | #define VT8231_ENABLE_REG 0x74 | ||
52 | |||
53 | /* The VT8231 registers | ||
54 | |||
55 | The reset value for the input channel configuration is used (Reg 0x4A=0x07) | ||
56 | which sets the selected inputs marked with '*' below if multiple options are | ||
57 | possible: | ||
58 | |||
59 | Voltage Mode Temperature Mode | ||
60 | Sensor Linux Id Linux Id VIA Id | ||
61 | -------- -------- -------- ------ | ||
62 | CPU Diode N/A temp1 0 | ||
63 | UIC1 in0 temp2 * 1 | ||
64 | UIC2 in1 * temp3 2 | ||
65 | UIC3 in2 * temp4 3 | ||
66 | UIC4 in3 * temp5 4 | ||
67 | UIC5 in4 * temp6 5 | ||
68 | 3.3V in5 N/A | ||
69 | |||
70 | Note that the BIOS may set the configuration register to a different value | ||
71 | to match the motherboard configuration. | ||
72 | */ | ||
73 | |||
74 | /* fans numbered 0-1 */ | ||
75 | #define VT8231_REG_FAN_MIN(nr) (0x3b + (nr)) | ||
76 | #define VT8231_REG_FAN(nr) (0x29 + (nr)) | ||
77 | |||
78 | /* Voltage inputs numbered 0-5 */ | ||
79 | |||
80 | static const u8 regvolt[] = { 0x21, 0x22, 0x23, 0x24, 0x25, 0x26 }; | ||
81 | static const u8 regvoltmax[] = { 0x3d, 0x2b, 0x2d, 0x2f, 0x31, 0x33 }; | ||
82 | static const u8 regvoltmin[] = { 0x3e, 0x2c, 0x2e, 0x30, 0x32, 0x34 }; | ||
83 | |||
84 | /* Temperatures are numbered 1-6 according to the Linux kernel specification. | ||
85 | ** | ||
86 | ** In the VIA datasheet, however, the temperatures are numbered from zero. | ||
87 | ** Since it is important that this driver can easily be compared to the VIA | ||
88 | ** datasheet, we will use the VIA numbering within this driver and map the | ||
89 | ** kernel sysfs device name to the VIA number in the sysfs callback. | ||
90 | */ | ||
91 | |||
92 | #define VT8231_REG_TEMP_LOW01 0x49 | ||
93 | #define VT8231_REG_TEMP_LOW25 0x4d | ||
94 | |||
95 | static const u8 regtemp[] = { 0x1f, 0x21, 0x22, 0x23, 0x24, 0x25 }; | ||
96 | static const u8 regtempmax[] = { 0x39, 0x3d, 0x2b, 0x2d, 0x2f, 0x31 }; | ||
97 | static const u8 regtempmin[] = { 0x3a, 0x3e, 0x2c, 0x2e, 0x30, 0x32 }; | ||
98 | |||
99 | #define TEMP_FROM_REG(reg) (((253 * 4 - (reg)) * 550 + 105) / 210) | ||
100 | #define TEMP_MAXMIN_FROM_REG(reg) (((253 - (reg)) * 2200 + 105) / 210) | ||
101 | #define TEMP_MAXMIN_TO_REG(val) (253 - ((val) * 210 + 1100) / 2200) | ||
102 | |||
103 | #define VT8231_REG_CONFIG 0x40 | ||
104 | #define VT8231_REG_ALARM1 0x41 | ||
105 | #define VT8231_REG_ALARM2 0x42 | ||
106 | #define VT8231_REG_FANDIV 0x47 | ||
107 | #define VT8231_REG_UCH_CONFIG 0x4a | ||
108 | #define VT8231_REG_TEMP1_CONFIG 0x4b | ||
109 | #define VT8231_REG_TEMP2_CONFIG 0x4c | ||
110 | |||
111 | /* temps 0-5 as numbered in VIA datasheet - see later for mapping to Linux | ||
112 | ** numbering | ||
113 | */ | ||
114 | #define ISTEMP(i, ch_config) ((i) == 0 ? 1 : \ | ||
115 | ((ch_config) >> ((i)+1)) & 0x01) | ||
116 | /* voltages 0-5 */ | ||
117 | #define ISVOLT(i, ch_config) ((i) == 5 ? 1 : \ | ||
118 | !(((ch_config) >> ((i)+2)) & 0x01)) | ||
119 | |||
120 | #define DIV_FROM_REG(val) (1 << (val)) | ||
121 | |||
122 | /* NB The values returned here are NOT temperatures. The calibration curves | ||
123 | ** for the thermistor curves are board-specific and must go in the | ||
124 | ** sensors.conf file. Temperature sensors are actually ten bits, but the | ||
125 | ** VIA datasheet only considers the 8 MSBs obtained from the regtemp[] | ||
126 | ** register. The temperature value returned should have a magnitude of 3, | ||
127 | ** so we use the VIA scaling as the "true" scaling and use the remaining 2 | ||
128 | ** LSBs as fractional precision. | ||
129 | ** | ||
130 | ** All the on-chip hardware temperature comparisons for the alarms are only | ||
131 | ** 8-bits wide, and compare against the 8 MSBs of the temperature. The bits | ||
132 | ** in the registers VT8231_REG_TEMP_LOW01 and VT8231_REG_TEMP_LOW25 are | ||
133 | ** ignored. | ||
134 | */ | ||
135 | |||
136 | /******** FAN RPM CONVERSIONS ******** | ||
137 | ** This chip saturates back at 0, not at 255 like many the other chips. | ||
138 | ** So, 0 means 0 RPM | ||
139 | */ | ||
140 | static inline u8 FAN_TO_REG(long rpm, int div) | ||
141 | { | ||
142 | if (rpm == 0) | ||
143 | return 0; | ||
144 | return SENSORS_LIMIT(1310720 / (rpm * div), 1, 255); | ||
145 | } | ||
146 | |||
147 | #define FAN_FROM_REG(val, div) ((val) == 0 ? 0 : 1310720 / ((val) * (div))) | ||
148 | |||
149 | struct vt8231_data { | ||
150 | struct i2c_client client; | ||
151 | struct semaphore update_lock; | ||
152 | struct class_device *class_dev; | ||
153 | char valid; /* !=0 if following fields are valid */ | ||
154 | unsigned long last_updated; /* In jiffies */ | ||
155 | |||
156 | u8 in[6]; /* Register value */ | ||
157 | u8 in_max[6]; /* Register value */ | ||
158 | u8 in_min[6]; /* Register value */ | ||
159 | u16 temp[6]; /* Register value 10 bit, right aligned */ | ||
160 | u8 temp_max[6]; /* Register value */ | ||
161 | u8 temp_min[6]; /* Register value */ | ||
162 | u8 fan[2]; /* Register value */ | ||
163 | u8 fan_min[2]; /* Register value */ | ||
164 | u8 fan_div[2]; /* Register encoding, shifted right */ | ||
165 | u16 alarms; /* Register encoding */ | ||
166 | u8 uch_config; | ||
167 | }; | ||
168 | |||
169 | static struct pci_dev *s_bridge; | ||
170 | static int vt8231_detect(struct i2c_adapter *adapter); | ||
171 | static int vt8231_detach_client(struct i2c_client *client); | ||
172 | static struct vt8231_data *vt8231_update_device(struct device *dev); | ||
173 | static void vt8231_init_client(struct i2c_client *client); | ||
174 | |||
175 | static inline int vt8231_read_value(struct i2c_client *client, u8 reg) | ||
176 | { | ||
177 | return inb_p(client->addr + reg); | ||
178 | } | ||
179 | |||
180 | static inline void vt8231_write_value(struct i2c_client *client, u8 reg, | ||
181 | u8 value) | ||
182 | { | ||
183 | outb_p(value, client->addr + reg); | ||
184 | } | ||
185 | |||
186 | /* following are the sysfs callback functions */ | ||
187 | static ssize_t show_in(struct device *dev, struct device_attribute *attr, | ||
188 | char *buf) | ||
189 | { | ||
190 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
191 | int nr = sensor_attr->index; | ||
192 | struct vt8231_data *data = vt8231_update_device(dev); | ||
193 | |||
194 | return sprintf(buf, "%d\n", ((data->in[nr] - 3) * 10000) / 958); | ||
195 | } | ||
196 | |||
197 | static ssize_t show_in_min(struct device *dev, struct device_attribute *attr, | ||
198 | char *buf) | ||
199 | { | ||
200 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
201 | int nr = sensor_attr->index; | ||
202 | struct vt8231_data *data = vt8231_update_device(dev); | ||
203 | |||
204 | return sprintf(buf, "%d\n", ((data->in_min[nr] - 3) * 10000) / 958); | ||
205 | } | ||
206 | |||
207 | static ssize_t show_in_max(struct device *dev, struct device_attribute *attr, | ||
208 | char *buf) | ||
209 | { | ||
210 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
211 | int nr = sensor_attr->index; | ||
212 | struct vt8231_data *data = vt8231_update_device(dev); | ||
213 | |||
214 | return sprintf(buf, "%d\n", (((data->in_max[nr] - 3) * 10000) / 958)); | ||
215 | } | ||
216 | |||
217 | static ssize_t set_in_min(struct device *dev, struct device_attribute *attr, | ||
218 | const char *buf, size_t count) | ||
219 | { | ||
220 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
221 | int nr = sensor_attr->index; | ||
222 | struct i2c_client *client = to_i2c_client(dev); | ||
223 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
224 | unsigned long val = simple_strtoul(buf, NULL, 10); | ||
225 | |||
226 | down(&data->update_lock); | ||
227 | data->in_min[nr] = SENSORS_LIMIT(((val * 958) / 10000) + 3, 0, 255); | ||
228 | vt8231_write_value(client, regvoltmin[nr], data->in_min[nr]); | ||
229 | up(&data->update_lock); | ||
230 | return count; | ||
231 | } | ||
232 | |||
233 | static ssize_t set_in_max(struct device *dev, struct device_attribute *attr, | ||
234 | const char *buf, size_t count) | ||
235 | { | ||
236 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
237 | int nr = sensor_attr->index; | ||
238 | struct i2c_client *client = to_i2c_client(dev); | ||
239 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
240 | unsigned long val = simple_strtoul(buf, NULL, 10); | ||
241 | |||
242 | down(&data->update_lock); | ||
243 | data->in_max[nr] = SENSORS_LIMIT(((val * 958) / 10000) + 3, 0, 255); | ||
244 | vt8231_write_value(client, regvoltmax[nr], data->in_max[nr]); | ||
245 | up(&data->update_lock); | ||
246 | return count; | ||
247 | } | ||
248 | |||
249 | /* Special case for input 5 as this has 3.3V scaling built into the chip */ | ||
250 | static ssize_t show_in5(struct device *dev, struct device_attribute *attr, | ||
251 | char *buf) | ||
252 | { | ||
253 | struct vt8231_data *data = vt8231_update_device(dev); | ||
254 | |||
255 | return sprintf(buf, "%d\n", | ||
256 | (((data->in[5] - 3) * 10000 * 54) / (958 * 34))); | ||
257 | } | ||
258 | |||
259 | static ssize_t show_in5_min(struct device *dev, struct device_attribute *attr, | ||
260 | char *buf) | ||
261 | { | ||
262 | struct vt8231_data *data = vt8231_update_device(dev); | ||
263 | |||
264 | return sprintf(buf, "%d\n", | ||
265 | (((data->in_min[5] - 3) * 10000 * 54) / (958 * 34))); | ||
266 | } | ||
267 | |||
268 | static ssize_t show_in5_max(struct device *dev, struct device_attribute *attr, | ||
269 | char *buf) | ||
270 | { | ||
271 | struct vt8231_data *data = vt8231_update_device(dev); | ||
272 | |||
273 | return sprintf(buf, "%d\n", | ||
274 | (((data->in_max[5] - 3) * 10000 * 54) / (958 * 34))); | ||
275 | } | ||
276 | |||
277 | static ssize_t set_in5_min(struct device *dev, struct device_attribute *attr, | ||
278 | const char *buf, size_t count) | ||
279 | { | ||
280 | struct i2c_client *client = to_i2c_client(dev); | ||
281 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
282 | unsigned long val = simple_strtoul(buf, NULL, 10); | ||
283 | |||
284 | down(&data->update_lock); | ||
285 | data->in_min[5] = SENSORS_LIMIT(((val * 958 * 34) / (10000 * 54)) + 3, | ||
286 | 0, 255); | ||
287 | vt8231_write_value(client, regvoltmin[5], data->in_min[5]); | ||
288 | up(&data->update_lock); | ||
289 | return count; | ||
290 | } | ||
291 | |||
292 | static ssize_t set_in5_max(struct device *dev, struct device_attribute *attr, | ||
293 | const char *buf, size_t count) | ||
294 | { | ||
295 | struct i2c_client *client = to_i2c_client(dev); | ||
296 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
297 | unsigned long val = simple_strtoul(buf, NULL, 10); | ||
298 | |||
299 | down(&data->update_lock); | ||
300 | data->in_max[5] = SENSORS_LIMIT(((val * 958 * 34) / (10000 * 54)) + 3, | ||
301 | 0, 255); | ||
302 | vt8231_write_value(client, regvoltmax[5], data->in_max[5]); | ||
303 | up(&data->update_lock); | ||
304 | return count; | ||
305 | } | ||
306 | |||
307 | #define define_voltage_sysfs(offset) \ | ||
308 | static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \ | ||
309 | show_in, NULL, offset); \ | ||
310 | static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ | ||
311 | show_in_min, set_in_min, offset); \ | ||
312 | static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ | ||
313 | show_in_max, set_in_max, offset) | ||
314 | |||
315 | define_voltage_sysfs(0); | ||
316 | define_voltage_sysfs(1); | ||
317 | define_voltage_sysfs(2); | ||
318 | define_voltage_sysfs(3); | ||
319 | define_voltage_sysfs(4); | ||
320 | |||
321 | static DEVICE_ATTR(in5_input, S_IRUGO, show_in5, NULL); | ||
322 | static DEVICE_ATTR(in5_min, S_IRUGO | S_IWUSR, show_in5_min, set_in5_min); | ||
323 | static DEVICE_ATTR(in5_max, S_IRUGO | S_IWUSR, show_in5_max, set_in5_max); | ||
324 | |||
325 | /* Temperatures */ | ||
326 | static ssize_t show_temp0(struct device *dev, struct device_attribute *attr, | ||
327 | char *buf) | ||
328 | { | ||
329 | struct vt8231_data *data = vt8231_update_device(dev); | ||
330 | return sprintf(buf, "%d\n", data->temp[0] * 250); | ||
331 | } | ||
332 | |||
333 | static ssize_t show_temp0_max(struct device *dev, struct device_attribute *attr, | ||
334 | char *buf) | ||
335 | { | ||
336 | struct vt8231_data *data = vt8231_update_device(dev); | ||
337 | return sprintf(buf, "%d\n", data->temp_max[0] * 1000); | ||
338 | } | ||
339 | |||
340 | static ssize_t show_temp0_min(struct device *dev, struct device_attribute *attr, | ||
341 | char *buf) | ||
342 | { | ||
343 | struct vt8231_data *data = vt8231_update_device(dev); | ||
344 | return sprintf(buf, "%d\n", data->temp_min[0] * 1000); | ||
345 | } | ||
346 | |||
347 | static ssize_t set_temp0_max(struct device *dev, struct device_attribute *attr, | ||
348 | const char *buf, size_t count) | ||
349 | { | ||
350 | struct i2c_client *client = to_i2c_client(dev); | ||
351 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
352 | int val = simple_strtol(buf, NULL, 10); | ||
353 | |||
354 | down(&data->update_lock); | ||
355 | data->temp_max[0] = SENSORS_LIMIT((val + 500) / 1000, 0, 255); | ||
356 | vt8231_write_value(client, regtempmax[0], data->temp_max[0]); | ||
357 | up(&data->update_lock); | ||
358 | return count; | ||
359 | } | ||
360 | static ssize_t set_temp0_min(struct device *dev, struct device_attribute *attr, | ||
361 | const char *buf, size_t count) | ||
362 | { | ||
363 | struct i2c_client *client = to_i2c_client(dev); | ||
364 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
365 | int val = simple_strtol(buf, NULL, 10); | ||
366 | |||
367 | down(&data->update_lock); | ||
368 | data->temp_min[0] = SENSORS_LIMIT((val + 500) / 1000, 0, 255); | ||
369 | vt8231_write_value(client, regtempmin[0], data->temp_min[0]); | ||
370 | up(&data->update_lock); | ||
371 | return count; | ||
372 | } | ||
373 | |||
374 | static ssize_t show_temp(struct device *dev, struct device_attribute *attr, | ||
375 | char *buf) | ||
376 | { | ||
377 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
378 | int nr = sensor_attr->index; | ||
379 | struct vt8231_data *data = vt8231_update_device(dev); | ||
380 | return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[nr])); | ||
381 | } | ||
382 | |||
383 | static ssize_t show_temp_max(struct device *dev, struct device_attribute *attr, | ||
384 | char *buf) | ||
385 | { | ||
386 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
387 | int nr = sensor_attr->index; | ||
388 | struct vt8231_data *data = vt8231_update_device(dev); | ||
389 | return sprintf(buf, "%d\n", TEMP_MAXMIN_FROM_REG(data->temp_max[nr])); | ||
390 | } | ||
391 | |||
392 | static ssize_t show_temp_min(struct device *dev, struct device_attribute *attr, | ||
393 | char *buf) | ||
394 | { | ||
395 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
396 | int nr = sensor_attr->index; | ||
397 | struct vt8231_data *data = vt8231_update_device(dev); | ||
398 | return sprintf(buf, "%d\n", TEMP_MAXMIN_FROM_REG(data->temp_min[nr])); | ||
399 | } | ||
400 | |||
401 | static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, | ||
402 | const char *buf, size_t count) | ||
403 | { | ||
404 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
405 | int nr = sensor_attr->index; | ||
406 | struct i2c_client *client = to_i2c_client(dev); | ||
407 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
408 | int val = simple_strtol(buf, NULL, 10); | ||
409 | |||
410 | down(&data->update_lock); | ||
411 | data->temp_max[nr] = SENSORS_LIMIT(TEMP_MAXMIN_TO_REG(val), 0, 255); | ||
412 | vt8231_write_value(client, regtempmax[nr], data->temp_max[nr]); | ||
413 | up(&data->update_lock); | ||
414 | return count; | ||
415 | } | ||
416 | static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, | ||
417 | const char *buf, size_t count) | ||
418 | { | ||
419 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
420 | int nr = sensor_attr->index; | ||
421 | struct i2c_client *client = to_i2c_client(dev); | ||
422 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
423 | int val = simple_strtol(buf, NULL, 10); | ||
424 | |||
425 | down(&data->update_lock); | ||
426 | data->temp_min[nr] = SENSORS_LIMIT(TEMP_MAXMIN_TO_REG(val), 0, 255); | ||
427 | vt8231_write_value(client, regtempmin[nr], data->temp_min[nr]); | ||
428 | up(&data->update_lock); | ||
429 | return count; | ||
430 | } | ||
431 | |||
432 | /* Note that these map the Linux temperature sensor numbering (1-6) to the VIA | ||
433 | ** temperature sensor numbering (0-5) | ||
434 | */ | ||
435 | #define define_temperature_sysfs(offset) \ | ||
436 | static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ | ||
437 | show_temp, NULL, offset - 1); \ | ||
438 | static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ | ||
439 | show_temp_max, set_temp_max, offset - 1); \ | ||
440 | static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \ | ||
441 | show_temp_min, set_temp_min, offset - 1) | ||
442 | |||
443 | static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp0, NULL); | ||
444 | static DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, show_temp0_max, set_temp0_max); | ||
445 | static DEVICE_ATTR(temp1_min, S_IRUGO | S_IWUSR, show_temp0_min, set_temp0_min); | ||
446 | |||
447 | define_temperature_sysfs(2); | ||
448 | define_temperature_sysfs(3); | ||
449 | define_temperature_sysfs(4); | ||
450 | define_temperature_sysfs(5); | ||
451 | define_temperature_sysfs(6); | ||
452 | |||
453 | #define CFG_INFO_TEMP(id) { &sensor_dev_attr_temp##id##_input.dev_attr, \ | ||
454 | &sensor_dev_attr_temp##id##_min.dev_attr, \ | ||
455 | &sensor_dev_attr_temp##id##_max.dev_attr } | ||
456 | #define CFG_INFO_VOLT(id) { &sensor_dev_attr_in##id##_input.dev_attr, \ | ||
457 | &sensor_dev_attr_in##id##_min.dev_attr, \ | ||
458 | &sensor_dev_attr_in##id##_max.dev_attr } | ||
459 | |||
460 | struct str_device_attr_table { | ||
461 | struct device_attribute *input; | ||
462 | struct device_attribute *min; | ||
463 | struct device_attribute *max; | ||
464 | }; | ||
465 | |||
466 | static struct str_device_attr_table cfg_info_temp[] = { | ||
467 | { &dev_attr_temp1_input, &dev_attr_temp1_min, &dev_attr_temp1_max }, | ||
468 | CFG_INFO_TEMP(2), | ||
469 | CFG_INFO_TEMP(3), | ||
470 | CFG_INFO_TEMP(4), | ||
471 | CFG_INFO_TEMP(5), | ||
472 | CFG_INFO_TEMP(6) | ||
473 | }; | ||
474 | |||
475 | static struct str_device_attr_table cfg_info_volt[] = { | ||
476 | CFG_INFO_VOLT(0), | ||
477 | CFG_INFO_VOLT(1), | ||
478 | CFG_INFO_VOLT(2), | ||
479 | CFG_INFO_VOLT(3), | ||
480 | CFG_INFO_VOLT(4), | ||
481 | { &dev_attr_in5_input, &dev_attr_in5_min, &dev_attr_in5_max } | ||
482 | }; | ||
483 | |||
484 | /* Fans */ | ||
485 | static ssize_t show_fan(struct device *dev, struct device_attribute *attr, | ||
486 | char *buf) | ||
487 | { | ||
488 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
489 | int nr = sensor_attr->index; | ||
490 | struct vt8231_data *data = vt8231_update_device(dev); | ||
491 | return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr], | ||
492 | DIV_FROM_REG(data->fan_div[nr]))); | ||
493 | } | ||
494 | |||
495 | static ssize_t show_fan_min(struct device *dev, struct device_attribute *attr, | ||
496 | char *buf) | ||
497 | { | ||
498 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
499 | int nr = sensor_attr->index; | ||
500 | struct vt8231_data *data = vt8231_update_device(dev); | ||
501 | return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[nr], | ||
502 | DIV_FROM_REG(data->fan_div[nr]))); | ||
503 | } | ||
504 | |||
505 | static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr, | ||
506 | char *buf) | ||
507 | { | ||
508 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
509 | int nr = sensor_attr->index; | ||
510 | struct vt8231_data *data = vt8231_update_device(dev); | ||
511 | return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr])); | ||
512 | } | ||
513 | |||
514 | static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, | ||
515 | const char *buf, size_t count) | ||
516 | { | ||
517 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
518 | int nr = sensor_attr->index; | ||
519 | struct i2c_client *client = to_i2c_client(dev); | ||
520 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
521 | int val = simple_strtoul(buf, NULL, 10); | ||
522 | |||
523 | down(&data->update_lock); | ||
524 | data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); | ||
525 | vt8231_write_value(client, VT8231_REG_FAN_MIN(nr), data->fan_min[nr]); | ||
526 | up(&data->update_lock); | ||
527 | return count; | ||
528 | } | ||
529 | |||
530 | static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, | ||
531 | const char *buf, size_t count) | ||
532 | { | ||
533 | struct i2c_client *client = to_i2c_client(dev); | ||
534 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
535 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
536 | unsigned long val = simple_strtoul(buf, NULL, 10); | ||
537 | int nr = sensor_attr->index; | ||
538 | int old = vt8231_read_value(client, VT8231_REG_FANDIV); | ||
539 | long min = FAN_FROM_REG(data->fan_min[nr], | ||
540 | DIV_FROM_REG(data->fan_div[nr])); | ||
541 | |||
542 | down(&data->update_lock); | ||
543 | switch (val) { | ||
544 | case 1: data->fan_div[nr] = 0; break; | ||
545 | case 2: data->fan_div[nr] = 1; break; | ||
546 | case 4: data->fan_div[nr] = 2; break; | ||
547 | case 8: data->fan_div[nr] = 3; break; | ||
548 | default: | ||
549 | dev_err(&client->dev, "fan_div value %ld not supported." | ||
550 | "Choose one of 1, 2, 4 or 8!\n", val); | ||
551 | up(&data->update_lock); | ||
552 | return -EINVAL; | ||
553 | } | ||
554 | |||
555 | /* Correct the fan minimum speed */ | ||
556 | data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); | ||
557 | vt8231_write_value(client, VT8231_REG_FAN_MIN(nr), data->fan_min[nr]); | ||
558 | |||
559 | old = (old & 0x0f) | (data->fan_div[1] << 6) | (data->fan_div[0] << 4); | ||
560 | vt8231_write_value(client, VT8231_REG_FANDIV, old); | ||
561 | up(&data->update_lock); | ||
562 | return count; | ||
563 | } | ||
564 | |||
565 | |||
566 | #define define_fan_sysfs(offset) \ | ||
567 | static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ | ||
568 | show_fan, NULL, offset - 1); \ | ||
569 | static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \ | ||
570 | show_fan_div, set_fan_div, offset - 1); \ | ||
571 | static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ | ||
572 | show_fan_min, set_fan_min, offset - 1) | ||
573 | |||
574 | define_fan_sysfs(1); | ||
575 | define_fan_sysfs(2); | ||
576 | |||
577 | /* Alarms */ | ||
578 | static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, | ||
579 | char *buf) | ||
580 | { | ||
581 | struct vt8231_data *data = vt8231_update_device(dev); | ||
582 | return sprintf(buf, "%d\n", data->alarms); | ||
583 | } | ||
584 | |||
585 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | ||
586 | |||
587 | static struct i2c_driver vt8231_driver = { | ||
588 | .driver = { | ||
589 | .name = "vt8231", | ||
590 | }, | ||
591 | .attach_adapter = vt8231_detect, | ||
592 | .detach_client = vt8231_detach_client, | ||
593 | }; | ||
594 | |||
595 | static struct pci_device_id vt8231_pci_ids[] = { | ||
596 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) }, | ||
597 | { 0, } | ||
598 | }; | ||
599 | |||
600 | MODULE_DEVICE_TABLE(pci, vt8231_pci_ids); | ||
601 | |||
602 | static int __devinit vt8231_pci_probe(struct pci_dev *dev, | ||
603 | const struct pci_device_id *id); | ||
604 | |||
605 | static struct pci_driver vt8231_pci_driver = { | ||
606 | .name = "vt8231", | ||
607 | .id_table = vt8231_pci_ids, | ||
608 | .probe = vt8231_pci_probe, | ||
609 | }; | ||
610 | |||
611 | int vt8231_detect(struct i2c_adapter *adapter) | ||
612 | { | ||
613 | struct i2c_client *client; | ||
614 | struct vt8231_data *data; | ||
615 | int err = 0, i; | ||
616 | u16 val; | ||
617 | |||
618 | /* 8231 requires multiple of 256 */ | ||
619 | if (force_addr) { | ||
620 | isa_address = force_addr & 0xFF00; | ||
621 | dev_warn(&adapter->dev, "forcing ISA address 0x%04X\n", | ||
622 | isa_address); | ||
623 | if (PCIBIOS_SUCCESSFUL != pci_write_config_word(s_bridge, | ||
624 | VT8231_BASE_REG, isa_address)) | ||
625 | return -ENODEV; | ||
626 | } | ||
627 | |||
628 | if (PCIBIOS_SUCCESSFUL != | ||
629 | pci_read_config_word(s_bridge, VT8231_ENABLE_REG, &val)) | ||
630 | return -ENODEV; | ||
631 | |||
632 | if (!(val & 0x0001)) { | ||
633 | dev_warn(&adapter->dev, "enabling sensors\n"); | ||
634 | if (PCIBIOS_SUCCESSFUL != | ||
635 | pci_write_config_word(s_bridge, VT8231_ENABLE_REG, | ||
636 | val | 0x0001)) | ||
637 | return -ENODEV; | ||
638 | } | ||
639 | |||
640 | /* Reserve the ISA region */ | ||
641 | if (!request_region(isa_address, VT8231_EXTENT, | ||
642 | vt8231_pci_driver.name)) { | ||
643 | dev_err(&adapter->dev, "region 0x%x already in use!\n", | ||
644 | isa_address); | ||
645 | return -ENODEV; | ||
646 | } | ||
647 | |||
648 | if (!(data = kzalloc(sizeof(struct vt8231_data), GFP_KERNEL))) { | ||
649 | err = -ENOMEM; | ||
650 | goto exit_release; | ||
651 | } | ||
652 | |||
653 | client = &data->client; | ||
654 | i2c_set_clientdata(client, data); | ||
655 | client->addr = isa_address; | ||
656 | client->adapter = adapter; | ||
657 | client->driver = &vt8231_driver; | ||
658 | client->dev.parent = &adapter->dev; | ||
659 | |||
660 | /* Fill in the remaining client fields and put into the global list */ | ||
661 | strlcpy(client->name, "vt8231", I2C_NAME_SIZE); | ||
662 | |||
663 | init_MUTEX(&data->update_lock); | ||
664 | |||
665 | /* Tell the I2C layer a new client has arrived */ | ||
666 | if ((err = i2c_attach_client(client))) | ||
667 | goto exit_free; | ||
668 | |||
669 | vt8231_init_client(client); | ||
670 | |||
671 | /* Register sysfs hooks */ | ||
672 | data->class_dev = hwmon_device_register(&client->dev); | ||
673 | if (IS_ERR(data->class_dev)) { | ||
674 | err = PTR_ERR(data->class_dev); | ||
675 | goto exit_detach; | ||
676 | } | ||
677 | |||
678 | /* Must update device information to find out the config field */ | ||
679 | data->uch_config = vt8231_read_value(client, VT8231_REG_UCH_CONFIG); | ||
680 | |||
681 | for (i = 0; i < ARRAY_SIZE(cfg_info_temp); i++) { | ||
682 | if (ISTEMP(i, data->uch_config)) { | ||
683 | device_create_file(&client->dev, | ||
684 | cfg_info_temp[i].input); | ||
685 | device_create_file(&client->dev, cfg_info_temp[i].max); | ||
686 | device_create_file(&client->dev, cfg_info_temp[i].min); | ||
687 | } | ||
688 | } | ||
689 | |||
690 | for (i = 0; i < ARRAY_SIZE(cfg_info_volt); i++) { | ||
691 | if (ISVOLT(i, data->uch_config)) { | ||
692 | device_create_file(&client->dev, | ||
693 | cfg_info_volt[i].input); | ||
694 | device_create_file(&client->dev, cfg_info_volt[i].max); | ||
695 | device_create_file(&client->dev, cfg_info_volt[i].min); | ||
696 | } | ||
697 | } | ||
698 | |||
699 | device_create_file(&client->dev, &sensor_dev_attr_fan1_input.dev_attr); | ||
700 | device_create_file(&client->dev, &sensor_dev_attr_fan2_input.dev_attr); | ||
701 | device_create_file(&client->dev, &sensor_dev_attr_fan1_min.dev_attr); | ||
702 | device_create_file(&client->dev, &sensor_dev_attr_fan2_min.dev_attr); | ||
703 | device_create_file(&client->dev, &sensor_dev_attr_fan1_div.dev_attr); | ||
704 | device_create_file(&client->dev, &sensor_dev_attr_fan2_div.dev_attr); | ||
705 | |||
706 | device_create_file(&client->dev, &dev_attr_alarms); | ||
707 | return 0; | ||
708 | |||
709 | exit_detach: | ||
710 | i2c_detach_client(client); | ||
711 | exit_free: | ||
712 | kfree(data); | ||
713 | exit_release: | ||
714 | release_region(isa_address, VT8231_EXTENT); | ||
715 | return err; | ||
716 | } | ||
717 | |||
718 | static int vt8231_detach_client(struct i2c_client *client) | ||
719 | { | ||
720 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
721 | int err; | ||
722 | |||
723 | hwmon_device_unregister(data->class_dev); | ||
724 | |||
725 | if ((err = i2c_detach_client(client))) { | ||
726 | return err; | ||
727 | } | ||
728 | |||
729 | release_region(client->addr, VT8231_EXTENT); | ||
730 | kfree(data); | ||
731 | |||
732 | return 0; | ||
733 | } | ||
734 | |||
735 | static void vt8231_init_client(struct i2c_client *client) | ||
736 | { | ||
737 | vt8231_write_value(client, VT8231_REG_TEMP1_CONFIG, 0); | ||
738 | vt8231_write_value(client, VT8231_REG_TEMP2_CONFIG, 0); | ||
739 | } | ||
740 | |||
741 | static struct vt8231_data *vt8231_update_device(struct device *dev) | ||
742 | { | ||
743 | struct i2c_client *client = to_i2c_client(dev); | ||
744 | struct vt8231_data *data = i2c_get_clientdata(client); | ||
745 | int i; | ||
746 | u16 low; | ||
747 | |||
748 | down(&data->update_lock); | ||
749 | |||
750 | if (time_after(jiffies, data->last_updated + HZ + HZ / 2) | ||
751 | || !data->valid) { | ||
752 | for (i = 0; i < 6; i++) { | ||
753 | if (ISVOLT(i, data->uch_config)) { | ||
754 | data->in[i] = vt8231_read_value(client, | ||
755 | regvolt[i]); | ||
756 | data->in_min[i] = vt8231_read_value(client, | ||
757 | regvoltmin[i]); | ||
758 | data->in_max[i] = vt8231_read_value(client, | ||
759 | regvoltmax[i]); | ||
760 | } | ||
761 | } | ||
762 | for (i = 0; i < 2; i++) { | ||
763 | data->fan[i] = vt8231_read_value(client, | ||
764 | VT8231_REG_FAN(i)); | ||
765 | data->fan_min[i] = vt8231_read_value(client, | ||
766 | VT8231_REG_FAN_MIN(i)); | ||
767 | } | ||
768 | |||
769 | low = vt8231_read_value(client, VT8231_REG_TEMP_LOW01); | ||
770 | low = (low >> 6) | ((low & 0x30) >> 2) | ||
771 | | (vt8231_read_value(client, VT8231_REG_TEMP_LOW25) << 4); | ||
772 | for (i = 0; i < 6; i++) { | ||
773 | if (ISTEMP(i, data->uch_config)) { | ||
774 | data->temp[i] = (vt8231_read_value(client, | ||
775 | regtemp[i]) << 2) | ||
776 | | ((low >> (2 * i)) & 0x03); | ||
777 | data->temp_max[i] = vt8231_read_value(client, | ||
778 | regtempmax[i]); | ||
779 | data->temp_min[i] = vt8231_read_value(client, | ||
780 | regtempmin[i]); | ||
781 | } | ||
782 | } | ||
783 | |||
784 | i = vt8231_read_value(client, VT8231_REG_FANDIV); | ||
785 | data->fan_div[0] = (i >> 4) & 0x03; | ||
786 | data->fan_div[1] = i >> 6; | ||
787 | data->alarms = vt8231_read_value(client, VT8231_REG_ALARM1) | | ||
788 | (vt8231_read_value(client, VT8231_REG_ALARM2) << 8); | ||
789 | |||
790 | /* Set alarm flags correctly */ | ||
791 | if (!data->fan[0] && data->fan_min[0]) { | ||
792 | data->alarms |= 0x40; | ||
793 | } else if (data->fan[0] && !data->fan_min[0]) { | ||
794 | data->alarms &= ~0x40; | ||
795 | } | ||
796 | |||
797 | if (!data->fan[1] && data->fan_min[1]) { | ||
798 | data->alarms |= 0x80; | ||
799 | } else if (data->fan[1] && !data->fan_min[1]) { | ||
800 | data->alarms &= ~0x80; | ||
801 | } | ||
802 | |||
803 | data->last_updated = jiffies; | ||
804 | data->valid = 1; | ||
805 | } | ||
806 | |||
807 | up(&data->update_lock); | ||
808 | |||
809 | return data; | ||
810 | } | ||
811 | |||
812 | static int __devinit vt8231_pci_probe(struct pci_dev *dev, | ||
813 | const struct pci_device_id *id) | ||
814 | { | ||
815 | u16 val; | ||
816 | |||
817 | if (PCIBIOS_SUCCESSFUL != pci_read_config_word(dev, VT8231_BASE_REG, | ||
818 | &val)) | ||
819 | return -ENODEV; | ||
820 | |||
821 | isa_address = val & ~(VT8231_EXTENT - 1); | ||
822 | if (isa_address == 0 && force_addr == 0) { | ||
823 | dev_err(&dev->dev, "base address not set -\ | ||
824 | upgrade BIOS or use force_addr=0xaddr\n"); | ||
825 | return -ENODEV; | ||
826 | } | ||
827 | |||
828 | s_bridge = pci_dev_get(dev); | ||
829 | |||
830 | if (i2c_isa_add_driver(&vt8231_driver)) { | ||
831 | pci_dev_put(s_bridge); | ||
832 | s_bridge = NULL; | ||
833 | } | ||
834 | |||
835 | /* Always return failure here. This is to allow other drivers to bind | ||
836 | * to this pci device. We don't really want to have control over the | ||
837 | * pci device, we only wanted to read as few register values from it. | ||
838 | */ | ||
839 | return -ENODEV; | ||
840 | } | ||
841 | |||
842 | static int __init sm_vt8231_init(void) | ||
843 | { | ||
844 | return pci_module_init(&vt8231_pci_driver); | ||
845 | } | ||
846 | |||
847 | static void __exit sm_vt8231_exit(void) | ||
848 | { | ||
849 | pci_unregister_driver(&vt8231_pci_driver); | ||
850 | if (s_bridge != NULL) { | ||
851 | i2c_isa_del_driver(&vt8231_driver); | ||
852 | pci_dev_put(s_bridge); | ||
853 | s_bridge = NULL; | ||
854 | } | ||
855 | } | ||
856 | |||
857 | MODULE_AUTHOR("Roger Lucas <roger@planbit.co.uk>"); | ||
858 | MODULE_DESCRIPTION("VT8231 sensors"); | ||
859 | MODULE_LICENSE("GPL"); | ||
860 | |||
861 | module_init(sm_vt8231_init); | ||
862 | module_exit(sm_vt8231_exit); | ||
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index eee22a57e929..12d79f5e4900 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c | |||
@@ -676,7 +676,7 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) | |||
676 | int i, err = 0; | 676 | int i, err = 0; |
677 | 677 | ||
678 | if (!request_region(address + REGION_OFFSET, REGION_LENGTH, | 678 | if (!request_region(address + REGION_OFFSET, REGION_LENGTH, |
679 | w83627ehf_driver.name)) { | 679 | w83627ehf_driver.driver.name)) { |
680 | err = -EBUSY; | 680 | err = -EBUSY; |
681 | goto exit; | 681 | goto exit; |
682 | } | 682 | } |
@@ -785,8 +785,9 @@ static int w83627ehf_detach_client(struct i2c_client *client) | |||
785 | } | 785 | } |
786 | 786 | ||
787 | static struct i2c_driver w83627ehf_driver = { | 787 | static struct i2c_driver w83627ehf_driver = { |
788 | .owner = THIS_MODULE, | 788 | .driver = { |
789 | .name = "w83627ehf", | 789 | .name = "w83627ehf", |
790 | }, | ||
790 | .attach_adapter = w83627ehf_detect, | 791 | .attach_adapter = w83627ehf_detect, |
791 | .detach_client = w83627ehf_detach_client, | 792 | .detach_client = w83627ehf_detach_client, |
792 | }; | 793 | }; |
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c index bbb3dcde146b..7ea441d4da63 100644 --- a/drivers/hwmon/w83627hf.c +++ b/drivers/hwmon/w83627hf.c | |||
@@ -332,8 +332,9 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev); | |||
332 | static void w83627hf_init_client(struct i2c_client *client); | 332 | static void w83627hf_init_client(struct i2c_client *client); |
333 | 333 | ||
334 | static struct i2c_driver w83627hf_driver = { | 334 | static struct i2c_driver w83627hf_driver = { |
335 | .owner = THIS_MODULE, | 335 | .driver = { |
336 | .name = "w83627hf", | 336 | .name = "w83627hf", |
337 | }, | ||
337 | .attach_adapter = w83627hf_detect, | 338 | .attach_adapter = w83627hf_detect, |
338 | .detach_client = w83627hf_detach_client, | 339 | .detach_client = w83627hf_detach_client, |
339 | }; | 340 | }; |
@@ -1009,7 +1010,7 @@ static int w83627hf_detect(struct i2c_adapter *adapter) | |||
1009 | address = force_addr & WINB_ALIGNMENT; | 1010 | address = force_addr & WINB_ALIGNMENT; |
1010 | 1011 | ||
1011 | if (!request_region(address + WINB_REGION_OFFSET, WINB_REGION_SIZE, | 1012 | if (!request_region(address + WINB_REGION_OFFSET, WINB_REGION_SIZE, |
1012 | w83627hf_driver.name)) { | 1013 | w83627hf_driver.driver.name)) { |
1013 | err = -EBUSY; | 1014 | err = -EBUSY; |
1014 | goto ERROR0; | 1015 | goto ERROR0; |
1015 | } | 1016 | } |
@@ -1122,11 +1123,10 @@ static int w83627hf_detect(struct i2c_adapter *adapter) | |||
1122 | if (kind != w83697hf) | 1123 | if (kind != w83697hf) |
1123 | device_create_file_temp(new_client, 3); | 1124 | device_create_file_temp(new_client, 3); |
1124 | 1125 | ||
1125 | if (kind != w83697hf) | 1126 | if (kind != w83697hf && data->vid != 0xff) { |
1126 | device_create_file_vid(new_client); | 1127 | device_create_file_vid(new_client); |
1127 | |||
1128 | if (kind != w83697hf) | ||
1129 | device_create_file_vrm(new_client); | 1128 | device_create_file_vrm(new_client); |
1129 | } | ||
1130 | 1130 | ||
1131 | device_create_file_fan_div(new_client, 1); | 1131 | device_create_file_fan_div(new_client, 1); |
1132 | device_create_file_fan_div(new_client, 2); | 1132 | device_create_file_fan_div(new_client, 2); |
@@ -1232,7 +1232,7 @@ static int w83627thf_read_gpio5(struct i2c_client *client) | |||
1232 | 1232 | ||
1233 | /* Make sure the pins are configured for input | 1233 | /* Make sure the pins are configured for input |
1234 | There must be at least five (VRM 9), and possibly 6 (VRM 10) */ | 1234 | There must be at least five (VRM 9), and possibly 6 (VRM 10) */ |
1235 | sel = superio_inb(W83627THF_GPIO5_IOSR); | 1235 | sel = superio_inb(W83627THF_GPIO5_IOSR) & 0x3f; |
1236 | if ((sel & 0x1f) != 0x1f) { | 1236 | if ((sel & 0x1f) != 0x1f) { |
1237 | dev_dbg(&client->dev, "GPIO5 not configured for VID " | 1237 | dev_dbg(&client->dev, "GPIO5 not configured for VID " |
1238 | "function\n"); | 1238 | "function\n"); |
@@ -1323,19 +1323,18 @@ static void w83627hf_init_client(struct i2c_client *client) | |||
1323 | int hi = w83627hf_read_value(client, W83781D_REG_CHIPID); | 1323 | int hi = w83627hf_read_value(client, W83781D_REG_CHIPID); |
1324 | data->vid = (lo & 0x0f) | ((hi & 0x01) << 4); | 1324 | data->vid = (lo & 0x0f) | ((hi & 0x01) << 4); |
1325 | } else if (w83627thf == data->type) { | 1325 | } else if (w83627thf == data->type) { |
1326 | data->vid = w83627thf_read_gpio5(client) & 0x3f; | 1326 | data->vid = w83627thf_read_gpio5(client); |
1327 | } | 1327 | } |
1328 | 1328 | ||
1329 | /* Read VRM & OVT Config only once */ | 1329 | /* Read VRM & OVT Config only once */ |
1330 | if (w83627thf == data->type || w83637hf == data->type) { | 1330 | if (w83627thf == data->type || w83637hf == data->type) { |
1331 | data->vrm_ovt = | 1331 | data->vrm_ovt = |
1332 | w83627hf_read_value(client, W83627THF_REG_VRM_OVT_CFG); | 1332 | w83627hf_read_value(client, W83627THF_REG_VRM_OVT_CFG); |
1333 | data->vrm = (data->vrm_ovt & 0x01) ? 90 : 82; | ||
1334 | } else { | ||
1335 | /* Convert VID to voltage based on default VRM */ | ||
1336 | data->vrm = vid_which_vrm(); | ||
1337 | } | 1333 | } |
1338 | 1334 | ||
1335 | /* Convert VID to voltage based on VRM */ | ||
1336 | data->vrm = vid_which_vrm(); | ||
1337 | |||
1339 | tmp = w83627hf_read_value(client, W83781D_REG_SCFG1); | 1338 | tmp = w83627hf_read_value(client, W83781D_REG_SCFG1); |
1340 | for (i = 1; i <= 3; i++) { | 1339 | for (i = 1; i <= 3; i++) { |
1341 | if (!(tmp & BIT_SCFG1[i - 1])) { | 1340 | if (!(tmp & BIT_SCFG1[i - 1])) { |
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index ffdb3a03e2b5..557114872f3c 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c | |||
@@ -269,17 +269,18 @@ static struct w83781d_data *w83781d_update_device(struct device *dev); | |||
269 | static void w83781d_init_client(struct i2c_client *client); | 269 | static void w83781d_init_client(struct i2c_client *client); |
270 | 270 | ||
271 | static struct i2c_driver w83781d_driver = { | 271 | static struct i2c_driver w83781d_driver = { |
272 | .owner = THIS_MODULE, | 272 | .driver = { |
273 | .name = "w83781d", | 273 | .name = "w83781d", |
274 | }, | ||
274 | .id = I2C_DRIVERID_W83781D, | 275 | .id = I2C_DRIVERID_W83781D, |
275 | .flags = I2C_DF_NOTIFY, | ||
276 | .attach_adapter = w83781d_attach_adapter, | 276 | .attach_adapter = w83781d_attach_adapter, |
277 | .detach_client = w83781d_detach_client, | 277 | .detach_client = w83781d_detach_client, |
278 | }; | 278 | }; |
279 | 279 | ||
280 | static struct i2c_driver w83781d_isa_driver = { | 280 | static struct i2c_driver w83781d_isa_driver = { |
281 | .owner = THIS_MODULE, | 281 | .driver = { |
282 | .name = "w83781d-isa", | 282 | .name = "w83781d-isa", |
283 | }, | ||
283 | .attach_adapter = w83781d_isa_attach_adapter, | 284 | .attach_adapter = w83781d_isa_attach_adapter, |
284 | .detach_client = w83781d_detach_client, | 285 | .detach_client = w83781d_detach_client, |
285 | }; | 286 | }; |
@@ -1012,7 +1013,7 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1012 | 1013 | ||
1013 | if (is_isa) | 1014 | if (is_isa) |
1014 | if (!request_region(address, W83781D_EXTENT, | 1015 | if (!request_region(address, W83781D_EXTENT, |
1015 | w83781d_isa_driver.name)) { | 1016 | w83781d_isa_driver.driver.name)) { |
1016 | dev_dbg(&adapter->dev, "Request of region " | 1017 | dev_dbg(&adapter->dev, "Request of region " |
1017 | "0x%x-0x%x for w83781d failed\n", address, | 1018 | "0x%x-0x%x for w83781d failed\n", address, |
1018 | address + W83781D_EXTENT - 1); | 1019 | address + W83781D_EXTENT - 1); |
diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c index 1ba072630361..b176bf0c4c7b 100644 --- a/drivers/hwmon/w83792d.c +++ b/drivers/hwmon/w83792d.c | |||
@@ -269,7 +269,6 @@ DIV_TO_REG(long val) | |||
269 | struct w83792d_data { | 269 | struct w83792d_data { |
270 | struct i2c_client client; | 270 | struct i2c_client client; |
271 | struct class_device *class_dev; | 271 | struct class_device *class_dev; |
272 | struct semaphore lock; | ||
273 | enum chips type; | 272 | enum chips type; |
274 | 273 | ||
275 | struct semaphore update_lock; | 274 | struct semaphore update_lock; |
@@ -282,7 +281,7 @@ struct w83792d_data { | |||
282 | u8 in[9]; /* Register value */ | 281 | u8 in[9]; /* Register value */ |
283 | u8 in_max[9]; /* Register value */ | 282 | u8 in_max[9]; /* Register value */ |
284 | u8 in_min[9]; /* Register value */ | 283 | u8 in_min[9]; /* Register value */ |
285 | u8 low_bits[2]; /* Additional resolution to voltage in0-6 */ | 284 | u16 low_bits; /* Additional resolution to voltage in6-0 */ |
286 | u8 fan[7]; /* Register value */ | 285 | u8 fan[7]; /* Register value */ |
287 | u8 fan_min[7]; /* Register value */ | 286 | u8 fan_min[7]; /* Register value */ |
288 | u8 temp1[3]; /* current, over, thyst */ | 287 | u8 temp1[3]; /* current, over, thyst */ |
@@ -317,45 +316,17 @@ static void w83792d_print_debug(struct w83792d_data *data, struct device *dev); | |||
317 | static void w83792d_init_client(struct i2c_client *client); | 316 | static void w83792d_init_client(struct i2c_client *client); |
318 | 317 | ||
319 | static struct i2c_driver w83792d_driver = { | 318 | static struct i2c_driver w83792d_driver = { |
320 | .owner = THIS_MODULE, | 319 | .driver = { |
321 | .name = "w83792d", | 320 | .name = "w83792d", |
322 | .flags = I2C_DF_NOTIFY, | 321 | }, |
323 | .attach_adapter = w83792d_attach_adapter, | 322 | .attach_adapter = w83792d_attach_adapter, |
324 | .detach_client = w83792d_detach_client, | 323 | .detach_client = w83792d_detach_client, |
325 | }; | 324 | }; |
326 | 325 | ||
327 | static long in_count_from_reg(int nr, struct w83792d_data *data) | 326 | static inline long in_count_from_reg(int nr, struct w83792d_data *data) |
328 | { | 327 | { |
329 | u16 vol_count = data->in[nr]; | 328 | /* in7 and in8 do not have low bits, but the formula still works */ |
330 | u16 low_bits = 0; | 329 | return ((data->in[nr] << 2) | ((data->low_bits >> (2 * nr)) & 0x03)); |
331 | vol_count = (vol_count << 2); | ||
332 | switch (nr) | ||
333 | { | ||
334 | case 0: /* vin0 */ | ||
335 | low_bits = (data->low_bits[0]) & 0x03; | ||
336 | break; | ||
337 | case 1: /* vin1 */ | ||
338 | low_bits = ((data->low_bits[0]) & 0x0c) >> 2; | ||
339 | break; | ||
340 | case 2: /* vin2 */ | ||
341 | low_bits = ((data->low_bits[0]) & 0x30) >> 4; | ||
342 | break; | ||
343 | case 3: /* vin3 */ | ||
344 | low_bits = ((data->low_bits[0]) & 0xc0) >> 6; | ||
345 | break; | ||
346 | case 4: /* vin4 */ | ||
347 | low_bits = (data->low_bits[1]) & 0x03; | ||
348 | break; | ||
349 | case 5: /* vin5 */ | ||
350 | low_bits = ((data->low_bits[1]) & 0x0c) >> 2; | ||
351 | break; | ||
352 | case 6: /* vin6 */ | ||
353 | low_bits = ((data->low_bits[1]) & 0x30) >> 4; | ||
354 | default: | ||
355 | break; | ||
356 | } | ||
357 | vol_count = vol_count | low_bits; | ||
358 | return vol_count; | ||
359 | } | 330 | } |
360 | 331 | ||
361 | /* following are the sysfs callback functions */ | 332 | /* following are the sysfs callback functions */ |
@@ -1192,7 +1163,6 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1192 | new_client = &data->client; | 1163 | new_client = &data->client; |
1193 | i2c_set_clientdata(new_client, data); | 1164 | i2c_set_clientdata(new_client, data); |
1194 | new_client->addr = address; | 1165 | new_client->addr = address; |
1195 | init_MUTEX(&data->lock); | ||
1196 | new_client->adapter = adapter; | 1166 | new_client->adapter = adapter; |
1197 | new_client->driver = &w83792d_driver; | 1167 | new_client->driver = &w83792d_driver; |
1198 | new_client->flags = 0; | 1168 | new_client->flags = 0; |
@@ -1243,7 +1213,7 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1243 | goto ERROR1; | 1213 | goto ERROR1; |
1244 | } | 1214 | } |
1245 | val1 = w83792d_read_value(new_client, W83792D_REG_WCHIPID); | 1215 | val1 = w83792d_read_value(new_client, W83792D_REG_WCHIPID); |
1246 | if (val1 == 0x7a && address >= 0x2c) { | 1216 | if (val1 == 0x7a) { |
1247 | kind = w83792d; | 1217 | kind = w83792d; |
1248 | } else { | 1218 | } else { |
1249 | if (kind == 0) | 1219 | if (kind == 0) |
@@ -1416,26 +1386,17 @@ w83792d_detach_client(struct i2c_client *client) | |||
1416 | return 0; | 1386 | return 0; |
1417 | } | 1387 | } |
1418 | 1388 | ||
1419 | /* The SMBus locks itself, usually, but nothing may access the Winbond between | 1389 | /* The SMBus locks itself. The Winbond W83792D chip has a bank register, |
1420 | bank switches. ISA access must always be locked explicitly! | 1390 | but the driver only accesses registers in bank 0, so we don't have |
1421 | We ignore the W83792D BUSY flag at this moment - it could lead to deadlocks, | 1391 | to switch banks and lock access between switches. */ |
1422 | would slow down the W83792D access and should not be necessary. | 1392 | static int w83792d_read_value(struct i2c_client *client, u8 reg) |
1423 | There are some ugly typecasts here, but the good news is - they should | ||
1424 | nowhere else be necessary! */ | ||
1425 | static int | ||
1426 | w83792d_read_value(struct i2c_client *client, u8 reg) | ||
1427 | { | 1393 | { |
1428 | int res=0; | 1394 | return i2c_smbus_read_byte_data(client, reg); |
1429 | res = i2c_smbus_read_byte_data(client, reg); | ||
1430 | |||
1431 | return res; | ||
1432 | } | 1395 | } |
1433 | 1396 | ||
1434 | static int | 1397 | static int w83792d_write_value(struct i2c_client *client, u8 reg, u8 value) |
1435 | w83792d_write_value(struct i2c_client *client, u8 reg, u8 value) | ||
1436 | { | 1398 | { |
1437 | i2c_smbus_write_byte_data(client, reg, value); | 1399 | return i2c_smbus_write_byte_data(client, reg, value); |
1438 | return 0; | ||
1439 | } | 1400 | } |
1440 | 1401 | ||
1441 | static void | 1402 | static void |
@@ -1492,10 +1453,10 @@ static struct w83792d_data *w83792d_update_device(struct device *dev) | |||
1492 | data->in_min[i] = w83792d_read_value(client, | 1453 | data->in_min[i] = w83792d_read_value(client, |
1493 | W83792D_REG_IN_MIN[i]); | 1454 | W83792D_REG_IN_MIN[i]); |
1494 | } | 1455 | } |
1495 | data->low_bits[0] = w83792d_read_value(client, | 1456 | data->low_bits = w83792d_read_value(client, |
1496 | W83792D_REG_LOW_BITS1); | 1457 | W83792D_REG_LOW_BITS1) + |
1497 | data->low_bits[1] = w83792d_read_value(client, | 1458 | (w83792d_read_value(client, |
1498 | W83792D_REG_LOW_BITS2); | 1459 | W83792D_REG_LOW_BITS2) << 8); |
1499 | for (i = 0; i < 7; i++) { | 1460 | for (i = 0; i < 7; i++) { |
1500 | /* Update the Fan measured value and limits */ | 1461 | /* Update the Fan measured value and limits */ |
1501 | data->fan[i] = w83792d_read_value(client, | 1462 | data->fan[i] = w83792d_read_value(client, |
@@ -1506,7 +1467,7 @@ static struct w83792d_data *w83792d_update_device(struct device *dev) | |||
1506 | pwm_array_tmp[i] = w83792d_read_value(client, | 1467 | pwm_array_tmp[i] = w83792d_read_value(client, |
1507 | W83792D_REG_PWM[i]); | 1468 | W83792D_REG_PWM[i]); |
1508 | data->pwm[i] = pwm_array_tmp[i] & 0x0f; | 1469 | data->pwm[i] = pwm_array_tmp[i] & 0x0f; |
1509 | data->pwm_mode[i] = (pwm_array_tmp[i] >> 7) & 0x01; | 1470 | data->pwm_mode[i] = pwm_array_tmp[i] >> 7; |
1510 | } | 1471 | } |
1511 | 1472 | ||
1512 | reg_tmp = w83792d_read_value(client, W83792D_REG_FAN_CFG); | 1473 | reg_tmp = w83792d_read_value(client, W83792D_REG_FAN_CFG); |
@@ -1607,8 +1568,8 @@ static void w83792d_print_debug(struct w83792d_data *data, struct device *dev) | |||
1607 | dev_dbg(dev, "vin[%d] max is: 0x%x\n", i, data->in_max[i]); | 1568 | dev_dbg(dev, "vin[%d] max is: 0x%x\n", i, data->in_max[i]); |
1608 | dev_dbg(dev, "vin[%d] min is: 0x%x\n", i, data->in_min[i]); | 1569 | dev_dbg(dev, "vin[%d] min is: 0x%x\n", i, data->in_min[i]); |
1609 | } | 1570 | } |
1610 | dev_dbg(dev, "Low Bit1 is: 0x%x\n", data->low_bits[0]); | 1571 | dev_dbg(dev, "Low Bit1 is: 0x%x\n", data->low_bits & 0xff); |
1611 | dev_dbg(dev, "Low Bit2 is: 0x%x\n", data->low_bits[1]); | 1572 | dev_dbg(dev, "Low Bit2 is: 0x%x\n", data->low_bits >> 8); |
1612 | dev_dbg(dev, "7 set of Fan Counts and Duty Cycles: =====>\n"); | 1573 | dev_dbg(dev, "7 set of Fan Counts and Duty Cycles: =====>\n"); |
1613 | for (i=0; i<7; i++) { | 1574 | for (i=0; i<7; i++) { |
1614 | dev_dbg(dev, "fan[%d] is: 0x%x\n", i, data->fan[i]); | 1575 | dev_dbg(dev, "fan[%d] is: 0x%x\n", i, data->fan[i]); |
diff --git a/drivers/hwmon/w83l785ts.c b/drivers/hwmon/w83l785ts.c index f495b6378668..f66c0cfdeda7 100644 --- a/drivers/hwmon/w83l785ts.c +++ b/drivers/hwmon/w83l785ts.c | |||
@@ -92,10 +92,10 @@ static struct w83l785ts_data *w83l785ts_update_device(struct device *dev); | |||
92 | */ | 92 | */ |
93 | 93 | ||
94 | static struct i2c_driver w83l785ts_driver = { | 94 | static struct i2c_driver w83l785ts_driver = { |
95 | .owner = THIS_MODULE, | 95 | .driver = { |
96 | .name = "w83l785ts", | 96 | .name = "w83l785ts", |
97 | }, | ||
97 | .id = I2C_DRIVERID_W83L785TS, | 98 | .id = I2C_DRIVERID_W83L785TS, |
98 | .flags = I2C_DF_NOTIFY, | ||
99 | .attach_adapter = w83l785ts_attach_adapter, | 99 | .attach_adapter = w83l785ts_attach_adapter, |
100 | .detach_client = w83l785ts_detach_client, | 100 | .detach_client = w83l785ts_detach_client, |
101 | }; | 101 | }; |
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index ac3eafa8aac0..1c752ddc10e2 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c | |||
@@ -468,8 +468,7 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr, | |||
468 | return -1; | 468 | return -1; |
469 | } | 469 | } |
470 | 470 | ||
471 | if (hwpec) | 471 | outb_p(hwpec, SMBAUXCTL); /* enable/disable hardware PEC */ |
472 | outb_p(1, SMBAUXCTL); /* enable hardware PEC */ | ||
473 | 472 | ||
474 | if(block) | 473 | if(block) |
475 | ret = i801_block_transaction(data, read_write, size, hwpec); | 474 | ret = i801_block_transaction(data, read_write, size, hwpec); |
@@ -478,9 +477,6 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr, | |||
478 | ret = i801_transaction(); | 477 | ret = i801_transaction(); |
479 | } | 478 | } |
480 | 479 | ||
481 | if (hwpec) | ||
482 | outb_p(0, SMBAUXCTL); /* disable hardware PEC */ | ||
483 | |||
484 | if(block) | 480 | if(block) |
485 | return ret; | 481 | return ret; |
486 | if(ret) | 482 | if(ret) |
diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index 1a587253d716..87fae937e666 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c | |||
@@ -725,6 +725,7 @@ static int __devinit iic_probe(struct ocp_device *ocp){ | |||
725 | strcpy(adap->name, "IBM IIC"); | 725 | strcpy(adap->name, "IBM IIC"); |
726 | i2c_set_adapdata(adap, dev); | 726 | i2c_set_adapdata(adap, dev); |
727 | adap->id = I2C_HW_OCP; | 727 | adap->id = I2C_HW_OCP; |
728 | adap->class = I2C_CLASS_HWMON; | ||
728 | adap->algo = &iic_algo; | 729 | adap->algo = &iic_algo; |
729 | adap->client_register = NULL; | 730 | adap->client_register = NULL; |
730 | adap->client_unregister = NULL; | 731 | adap->client_unregister = NULL; |
diff --git a/drivers/i2c/busses/i2c-isa.c b/drivers/i2c/busses/i2c-isa.c index 03672c9ca409..9f2ffef4d812 100644 --- a/drivers/i2c/busses/i2c-isa.c +++ b/drivers/i2c/busses/i2c-isa.c | |||
@@ -92,15 +92,13 @@ int i2c_isa_add_driver(struct i2c_driver *driver) | |||
92 | int res; | 92 | int res; |
93 | 93 | ||
94 | /* Add the driver to the list of i2c drivers in the driver core */ | 94 | /* Add the driver to the list of i2c drivers in the driver core */ |
95 | driver->driver.name = driver->name; | ||
96 | driver->driver.owner = driver->owner; | ||
97 | driver->driver.bus = &i2c_bus_type; | 95 | driver->driver.bus = &i2c_bus_type; |
98 | driver->driver.probe = i2c_isa_device_probe; | 96 | driver->driver.probe = i2c_isa_device_probe; |
99 | driver->driver.remove = i2c_isa_device_remove; | 97 | driver->driver.remove = i2c_isa_device_remove; |
100 | res = driver_register(&driver->driver); | 98 | res = driver_register(&driver->driver); |
101 | if (res) | 99 | if (res) |
102 | return res; | 100 | return res; |
103 | dev_dbg(&isa_adapter.dev, "Driver %s registered\n", driver->name); | 101 | dev_dbg(&isa_adapter.dev, "Driver %s registered\n", driver->driver.name); |
104 | 102 | ||
105 | /* Now look for clients */ | 103 | /* Now look for clients */ |
106 | driver->attach_adapter(&isa_adapter); | 104 | driver->attach_adapter(&isa_adapter); |
@@ -124,14 +122,14 @@ int i2c_isa_del_driver(struct i2c_driver *driver) | |||
124 | if ((res = driver->detach_client(client))) { | 122 | if ((res = driver->detach_client(client))) { |
125 | dev_err(&isa_adapter.dev, "Failed, driver " | 123 | dev_err(&isa_adapter.dev, "Failed, driver " |
126 | "%s not unregistered!\n", | 124 | "%s not unregistered!\n", |
127 | driver->name); | 125 | driver->driver.name); |
128 | return res; | 126 | return res; |
129 | } | 127 | } |
130 | } | 128 | } |
131 | 129 | ||
132 | /* Get the driver off the core list */ | 130 | /* Get the driver off the core list */ |
133 | driver_unregister(&driver->driver); | 131 | driver_unregister(&driver->driver); |
134 | dev_dbg(&isa_adapter.dev, "Driver %s unregistered\n", driver->name); | 132 | dev_dbg(&isa_adapter.dev, "Driver %s unregistered\n", driver->driver.name); |
135 | 133 | ||
136 | return 0; | 134 | return 0; |
137 | } | 135 | } |
@@ -176,7 +174,7 @@ static void __exit i2c_isa_exit(void) | |||
176 | list_for_each_safe(item, _n, &isa_adapter.clients) { | 174 | list_for_each_safe(item, _n, &isa_adapter.clients) { |
177 | client = list_entry(item, struct i2c_client, list); | 175 | client = list_entry(item, struct i2c_client, list); |
178 | dev_err(&isa_adapter.dev, "Driver %s still has an active " | 176 | dev_err(&isa_adapter.dev, "Driver %s still has an active " |
179 | "ISA client at 0x%x\n", client->driver->name, | 177 | "ISA client at 0x%x\n", client->driver->driver.name, |
180 | client->addr); | 178 | client->addr); |
181 | } | 179 | } |
182 | if (client != NULL) | 180 | if (client != NULL) |
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c index 81031eb51056..22781d84f79f 100644 --- a/drivers/i2c/busses/i2c-mv64xxx.c +++ b/drivers/i2c/busses/i2c-mv64xxx.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/i2c/busses/i2c-mv64xxx.c | ||
3 | * | ||
4 | * Driver for the i2c controller on the Marvell line of host bridges for MIPS | 2 | * Driver for the i2c controller on the Marvell line of host bridges for MIPS |
5 | * and PPC (e.g, gt642[46]0, mv643[46]0, mv644[46]0). | 3 | * and PPC (e.g, gt642[46]0, mv643[46]0, mv644[46]0). |
6 | * | 4 | * |
@@ -65,7 +63,6 @@ enum { | |||
65 | MV64XXX_I2C_STATE_WAITING_FOR_ADDR_2_ACK, | 63 | MV64XXX_I2C_STATE_WAITING_FOR_ADDR_2_ACK, |
66 | MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_ACK, | 64 | MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_ACK, |
67 | MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_DATA, | 65 | MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_DATA, |
68 | MV64XXX_I2C_STATE_ABORTING, | ||
69 | }; | 66 | }; |
70 | 67 | ||
71 | /* Driver actions */ | 68 | /* Driver actions */ |
@@ -85,6 +82,7 @@ struct mv64xxx_i2c_data { | |||
85 | int irq; | 82 | int irq; |
86 | u32 state; | 83 | u32 state; |
87 | u32 action; | 84 | u32 action; |
85 | u32 aborting; | ||
88 | u32 cntl_bits; | 86 | u32 cntl_bits; |
89 | void __iomem *reg_base; | 87 | void __iomem *reg_base; |
90 | u32 reg_base_p; | 88 | u32 reg_base_p; |
@@ -122,12 +120,6 @@ mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status) | |||
122 | return; | 120 | return; |
123 | } | 121 | } |
124 | 122 | ||
125 | if (drv_data->state == MV64XXX_I2C_STATE_ABORTING) { | ||
126 | drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP; | ||
127 | drv_data->state = MV64XXX_I2C_STATE_IDLE; | ||
128 | return; | ||
129 | } | ||
130 | |||
131 | /* The status from the ctlr [mostly] tells us what to do next */ | 123 | /* The status from the ctlr [mostly] tells us what to do next */ |
132 | switch (status) { | 124 | switch (status) { |
133 | /* Start condition interrupt */ | 125 | /* Start condition interrupt */ |
@@ -148,14 +140,16 @@ mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status) | |||
148 | /* FALLTHRU */ | 140 | /* FALLTHRU */ |
149 | case MV64XXX_I2C_STATUS_MAST_WR_ADDR_2_ACK: /* 0xd0 */ | 141 | case MV64XXX_I2C_STATUS_MAST_WR_ADDR_2_ACK: /* 0xd0 */ |
150 | case MV64XXX_I2C_STATUS_MAST_WR_ACK: /* 0x28 */ | 142 | case MV64XXX_I2C_STATUS_MAST_WR_ACK: /* 0x28 */ |
151 | if (drv_data->bytes_left > 0) { | 143 | if ((drv_data->bytes_left == 0) |
144 | || (drv_data->aborting | ||
145 | && (drv_data->byte_posn != 0))) { | ||
146 | drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP; | ||
147 | drv_data->state = MV64XXX_I2C_STATE_IDLE; | ||
148 | } else { | ||
152 | drv_data->action = MV64XXX_I2C_ACTION_SEND_DATA; | 149 | drv_data->action = MV64XXX_I2C_ACTION_SEND_DATA; |
153 | drv_data->state = | 150 | drv_data->state = |
154 | MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_ACK; | 151 | MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_ACK; |
155 | drv_data->bytes_left--; | 152 | drv_data->bytes_left--; |
156 | } else { | ||
157 | drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP; | ||
158 | drv_data->state = MV64XXX_I2C_STATE_IDLE; | ||
159 | } | 153 | } |
160 | break; | 154 | break; |
161 | 155 | ||
@@ -184,7 +178,7 @@ mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status) | |||
184 | } | 178 | } |
185 | drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_DATA; | 179 | drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_DATA; |
186 | 180 | ||
187 | if (drv_data->bytes_left == 1) | 181 | if ((drv_data->bytes_left == 1) || drv_data->aborting) |
188 | drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_ACK; | 182 | drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_ACK; |
189 | break; | 183 | break; |
190 | 184 | ||
@@ -320,6 +314,7 @@ mv64xxx_i2c_prepare_for_io(struct mv64xxx_i2c_data *drv_data, | |||
320 | drv_data->msg = msg; | 314 | drv_data->msg = msg; |
321 | drv_data->byte_posn = 0; | 315 | drv_data->byte_posn = 0; |
322 | drv_data->bytes_left = msg->len; | 316 | drv_data->bytes_left = msg->len; |
317 | drv_data->aborting = 0; | ||
323 | drv_data->rc = 0; | 318 | drv_data->rc = 0; |
324 | drv_data->cntl_bits = MV64XXX_I2C_REG_CONTROL_ACK | | 319 | drv_data->cntl_bits = MV64XXX_I2C_REG_CONTROL_ACK | |
325 | MV64XXX_I2C_REG_CONTROL_INTEN | MV64XXX_I2C_REG_CONTROL_TWSIEN; | 320 | MV64XXX_I2C_REG_CONTROL_INTEN | MV64XXX_I2C_REG_CONTROL_TWSIEN; |
@@ -359,17 +354,19 @@ mv64xxx_i2c_wait_for_completion(struct mv64xxx_i2c_data *drv_data) | |||
359 | } | 354 | } |
360 | 355 | ||
361 | if (abort && drv_data->block) { | 356 | if (abort && drv_data->block) { |
362 | drv_data->state = MV64XXX_I2C_STATE_ABORTING; | 357 | drv_data->aborting = 1; |
363 | spin_unlock_irqrestore(&drv_data->lock, flags); | 358 | spin_unlock_irqrestore(&drv_data->lock, flags); |
364 | 359 | ||
365 | time_left = wait_event_timeout(drv_data->waitq, | 360 | time_left = wait_event_timeout(drv_data->waitq, |
366 | !drv_data->block, | 361 | !drv_data->block, |
367 | msecs_to_jiffies(drv_data->adapter.timeout)); | 362 | msecs_to_jiffies(drv_data->adapter.timeout)); |
368 | 363 | ||
369 | if (time_left <= 0) { | 364 | if ((time_left <= 0) && drv_data->block) { |
370 | drv_data->state = MV64XXX_I2C_STATE_IDLE; | 365 | drv_data->state = MV64XXX_I2C_STATE_IDLE; |
371 | dev_err(&drv_data->adapter.dev, | 366 | dev_err(&drv_data->adapter.dev, |
372 | "mv64xxx: I2C bus locked\n"); | 367 | "mv64xxx: I2C bus locked, block: %d, " |
368 | "time_left: %d\n", drv_data->block, | ||
369 | (int)time_left); | ||
373 | } | 370 | } |
374 | } else | 371 | } else |
375 | spin_unlock_irqrestore(&drv_data->lock, flags); | 372 | spin_unlock_irqrestore(&drv_data->lock, flags); |
@@ -510,7 +507,7 @@ mv64xxx_i2c_probe(struct platform_device *pd) | |||
510 | goto exit_kfree; | 507 | goto exit_kfree; |
511 | } | 508 | } |
512 | 509 | ||
513 | strncpy(drv_data->adapter.name, MV64XXX_I2C_CTLR_NAME " adapter", | 510 | strlcpy(drv_data->adapter.name, MV64XXX_I2C_CTLR_NAME " adapter", |
514 | I2C_NAME_SIZE); | 511 | I2C_NAME_SIZE); |
515 | 512 | ||
516 | init_waitqueue_head(&drv_data->waitq); | 513 | init_waitqueue_head(&drv_data->waitq); |
diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c index 4d18e6e5f159..2d80eb26f688 100644 --- a/drivers/i2c/busses/i2c-nforce2.c +++ b/drivers/i2c/busses/i2c-nforce2.c | |||
@@ -30,6 +30,7 @@ | |||
30 | nForce3 Pro150 MCP 00D4 | 30 | nForce3 Pro150 MCP 00D4 |
31 | nForce3 250Gb MCP 00E4 | 31 | nForce3 250Gb MCP 00E4 |
32 | nForce4 MCP 0052 | 32 | nForce4 MCP 0052 |
33 | nForce4 MCP-04 0034 | ||
33 | 34 | ||
34 | This driver supports the 2 SMBuses that are included in the MCP of the | 35 | This driver supports the 2 SMBuses that are included in the MCP of the |
35 | nForce2/3/4 chipsets. | 36 | nForce2/3/4 chipsets. |
@@ -257,6 +258,7 @@ static struct pci_device_id nforce2_ids[] = { | |||
257 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS) }, | 258 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS) }, |
258 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SMBUS) }, | 259 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SMBUS) }, |
259 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE4_SMBUS) }, | 260 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE4_SMBUS) }, |
261 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SMBUS) }, | ||
260 | { 0 } | 262 | { 0 } |
261 | }; | 263 | }; |
262 | 264 | ||
diff --git a/drivers/i2c/busses/i2c-parport.h b/drivers/i2c/busses/i2c-parport.h index f63a53779281..d702e5e0388d 100644 --- a/drivers/i2c/busses/i2c-parport.h +++ b/drivers/i2c/busses/i2c-parport.h | |||
@@ -80,6 +80,14 @@ static struct adapter_parm adapter_parm[] = { | |||
80 | .setscl = { 0x01, DATA, 1 }, | 80 | .setscl = { 0x01, DATA, 1 }, |
81 | .getsda = { 0x10, STAT, 1 }, | 81 | .getsda = { 0x10, STAT, 1 }, |
82 | }, | 82 | }, |
83 | /* type 6: Barco LPT->DVI (K5800236) adapter */ | ||
84 | { | ||
85 | .setsda = { 0x02, DATA, 1 }, | ||
86 | .setscl = { 0x01, DATA, 1 }, | ||
87 | .getsda = { 0x20, STAT, 0 }, | ||
88 | .getscl = { 0x40, STAT, 0 }, | ||
89 | .init = { 0xfc, DATA, 0 }, | ||
90 | }, | ||
83 | }; | 91 | }; |
84 | 92 | ||
85 | static int type; | 93 | static int type; |
@@ -91,4 +99,6 @@ MODULE_PARM_DESC(type, | |||
91 | " 2 = Velleman K8000 adapter\n" | 99 | " 2 = Velleman K8000 adapter\n" |
92 | " 3 = ELV adapter\n" | 100 | " 3 = ELV adapter\n" |
93 | " 4 = ADM1032 evaluation board\n" | 101 | " 4 = ADM1032 evaluation board\n" |
94 | " 5 = ADM1025, ADM1030 and ADM1031 evaluation boards\n"); | 102 | " 5 = ADM1025, ADM1030 and ADM1031 evaluation boards\n" |
103 | " 6 = Barco LPT->DVI (K5800236) adapter\n" | ||
104 | ); | ||
diff --git a/drivers/i2c/chips/ds1337.c b/drivers/i2c/chips/ds1337.c index 02682fb794c8..93d483b8b770 100644 --- a/drivers/i2c/chips/ds1337.c +++ b/drivers/i2c/chips/ds1337.c | |||
@@ -52,9 +52,9 @@ static int ds1337_command(struct i2c_client *client, unsigned int cmd, | |||
52 | * Driver data (common to all clients) | 52 | * Driver data (common to all clients) |
53 | */ | 53 | */ |
54 | static struct i2c_driver ds1337_driver = { | 54 | static struct i2c_driver ds1337_driver = { |
55 | .owner = THIS_MODULE, | 55 | .driver = { |
56 | .name = "ds1337", | 56 | .name = "ds1337", |
57 | .flags = I2C_DF_NOTIFY, | 57 | }, |
58 | .attach_adapter = ds1337_attach_adapter, | 58 | .attach_adapter = ds1337_attach_adapter, |
59 | .detach_client = ds1337_detach_client, | 59 | .detach_client = ds1337_detach_client, |
60 | .command = ds1337_command, | 60 | .command = ds1337_command, |
@@ -337,13 +337,38 @@ exit: | |||
337 | 337 | ||
338 | static void ds1337_init_client(struct i2c_client *client) | 338 | static void ds1337_init_client(struct i2c_client *client) |
339 | { | 339 | { |
340 | s32 val; | 340 | u8 status, control; |
341 | 341 | ||
342 | /* Ensure that device is set in 24-hour mode */ | 342 | /* On some boards, the RTC isn't configured by boot firmware. |
343 | val = i2c_smbus_read_byte_data(client, DS1337_REG_HOUR); | 343 | * Handle that case by starting/configuring the RTC now. |
344 | if ((val >= 0) && (val & (1 << 6))) | 344 | */ |
345 | i2c_smbus_write_byte_data(client, DS1337_REG_HOUR, | 345 | status = i2c_smbus_read_byte_data(client, DS1337_REG_STATUS); |
346 | val & 0x3f); | 346 | control = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL); |
347 | |||
348 | if ((status & 0x80) || (control & 0x80)) { | ||
349 | /* RTC not running */ | ||
350 | u8 buf[16]; | ||
351 | struct i2c_msg msg[1]; | ||
352 | |||
353 | dev_dbg(&client->dev, "%s: RTC not running!\n", __FUNCTION__); | ||
354 | |||
355 | /* Initialize all, including STATUS and CONTROL to zero */ | ||
356 | memset(buf, 0, sizeof(buf)); | ||
357 | msg[0].addr = client->addr; | ||
358 | msg[0].flags = 0; | ||
359 | msg[0].len = sizeof(buf); | ||
360 | msg[0].buf = &buf[0]; | ||
361 | |||
362 | i2c_transfer(client->adapter, msg, 1); | ||
363 | } else { | ||
364 | /* Running: ensure that device is set in 24-hour mode */ | ||
365 | s32 val; | ||
366 | |||
367 | val = i2c_smbus_read_byte_data(client, DS1337_REG_HOUR); | ||
368 | if ((val >= 0) && (val & (1 << 6))) | ||
369 | i2c_smbus_write_byte_data(client, DS1337_REG_HOUR, | ||
370 | val & 0x3f); | ||
371 | } | ||
347 | } | 372 | } |
348 | 373 | ||
349 | static int ds1337_detach_client(struct i2c_client *client) | 374 | static int ds1337_detach_client(struct i2c_client *client) |
diff --git a/drivers/i2c/chips/ds1374.c b/drivers/i2c/chips/ds1374.c index da488b735abf..0710b9da9d54 100644 --- a/drivers/i2c/chips/ds1374.c +++ b/drivers/i2c/chips/ds1374.c | |||
@@ -232,10 +232,10 @@ static int ds1374_detach(struct i2c_client *client) | |||
232 | } | 232 | } |
233 | 233 | ||
234 | static struct i2c_driver ds1374_driver = { | 234 | static struct i2c_driver ds1374_driver = { |
235 | .owner = THIS_MODULE, | 235 | .driver = { |
236 | .name = DS1374_DRV_NAME, | 236 | .name = DS1374_DRV_NAME, |
237 | }, | ||
237 | .id = I2C_DRIVERID_DS1374, | 238 | .id = I2C_DRIVERID_DS1374, |
238 | .flags = I2C_DF_NOTIFY, | ||
239 | .attach_adapter = ds1374_attach, | 239 | .attach_adapter = ds1374_attach, |
240 | .detach_client = ds1374_detach, | 240 | .detach_client = ds1374_detach, |
241 | }; | 241 | }; |
diff --git a/drivers/i2c/chips/eeprom.c b/drivers/i2c/chips/eeprom.c index 4baf573fa04f..41116b7947f6 100644 --- a/drivers/i2c/chips/eeprom.c +++ b/drivers/i2c/chips/eeprom.c | |||
@@ -68,10 +68,10 @@ static int eeprom_detach_client(struct i2c_client *client); | |||
68 | 68 | ||
69 | /* This is the driver that will be inserted */ | 69 | /* This is the driver that will be inserted */ |
70 | static struct i2c_driver eeprom_driver = { | 70 | static struct i2c_driver eeprom_driver = { |
71 | .owner = THIS_MODULE, | 71 | .driver = { |
72 | .name = "eeprom", | 72 | .name = "eeprom", |
73 | }, | ||
73 | .id = I2C_DRIVERID_EEPROM, | 74 | .id = I2C_DRIVERID_EEPROM, |
74 | .flags = I2C_DF_NOTIFY, | ||
75 | .attach_adapter = eeprom_attach_adapter, | 75 | .attach_adapter = eeprom_attach_adapter, |
76 | .detach_client = eeprom_detach_client, | 76 | .detach_client = eeprom_detach_client, |
77 | }; | 77 | }; |
diff --git a/drivers/i2c/chips/isp1301_omap.c b/drivers/i2c/chips/isp1301_omap.c index d2a100d77839..1251c7fc18d5 100644 --- a/drivers/i2c/chips/isp1301_omap.c +++ b/drivers/i2c/chips/isp1301_omap.c | |||
@@ -1632,11 +1632,11 @@ static int isp1301_scan_bus(struct i2c_adapter *bus) | |||
1632 | } | 1632 | } |
1633 | 1633 | ||
1634 | static struct i2c_driver isp1301_driver = { | 1634 | static struct i2c_driver isp1301_driver = { |
1635 | .owner = THIS_MODULE, | 1635 | .driver = { |
1636 | .name = "isp1301_omap", | 1636 | .name = "isp1301_omap", |
1637 | }, | ||
1637 | .id = 1301, /* FIXME "official", i2c-ids.h */ | 1638 | .id = 1301, /* FIXME "official", i2c-ids.h */ |
1638 | .class = I2C_CLASS_HWMON, | 1639 | .class = I2C_CLASS_HWMON, |
1639 | .flags = I2C_DF_NOTIFY, | ||
1640 | .attach_adapter = isp1301_scan_bus, | 1640 | .attach_adapter = isp1301_scan_bus, |
1641 | .detach_client = isp1301_detach_client, | 1641 | .detach_client = isp1301_detach_client, |
1642 | }; | 1642 | }; |
diff --git a/drivers/i2c/chips/m41t00.c b/drivers/i2c/chips/m41t00.c index 3df309ae44a6..2dc3d48375fc 100644 --- a/drivers/i2c/chips/m41t00.c +++ b/drivers/i2c/chips/m41t00.c | |||
@@ -211,10 +211,10 @@ m41t00_detach(struct i2c_client *client) | |||
211 | } | 211 | } |
212 | 212 | ||
213 | static struct i2c_driver m41t00_driver = { | 213 | static struct i2c_driver m41t00_driver = { |
214 | .owner = THIS_MODULE, | 214 | .driver = { |
215 | .name = M41T00_DRV_NAME, | 215 | .name = M41T00_DRV_NAME, |
216 | }, | ||
216 | .id = I2C_DRIVERID_STM41T00, | 217 | .id = I2C_DRIVERID_STM41T00, |
217 | .flags = I2C_DF_NOTIFY, | ||
218 | .attach_adapter = m41t00_attach, | 218 | .attach_adapter = m41t00_attach, |
219 | .detach_client = m41t00_detach, | 219 | .detach_client = m41t00_detach, |
220 | }; | 220 | }; |
diff --git a/drivers/i2c/chips/max6875.c b/drivers/i2c/chips/max6875.c index b376a006883c..6d3ff584155e 100644 --- a/drivers/i2c/chips/max6875.c +++ b/drivers/i2c/chips/max6875.c | |||
@@ -67,9 +67,9 @@ static int max6875_detach_client(struct i2c_client *client); | |||
67 | 67 | ||
68 | /* This is the driver that will be inserted */ | 68 | /* This is the driver that will be inserted */ |
69 | static struct i2c_driver max6875_driver = { | 69 | static struct i2c_driver max6875_driver = { |
70 | .owner = THIS_MODULE, | 70 | .driver = { |
71 | .name = "max6875", | 71 | .name = "max6875", |
72 | .flags = I2C_DF_NOTIFY, | 72 | }, |
73 | .attach_adapter = max6875_attach_adapter, | 73 | .attach_adapter = max6875_attach_adapter, |
74 | .detach_client = max6875_detach_client, | 74 | .detach_client = max6875_detach_client, |
75 | }; | 75 | }; |
diff --git a/drivers/i2c/chips/pca9539.c b/drivers/i2c/chips/pca9539.c index 59a930346229..54b6e6a4beed 100644 --- a/drivers/i2c/chips/pca9539.c +++ b/drivers/i2c/chips/pca9539.c | |||
@@ -38,9 +38,9 @@ static int pca9539_detach_client(struct i2c_client *client); | |||
38 | 38 | ||
39 | /* This is the driver that will be inserted */ | 39 | /* This is the driver that will be inserted */ |
40 | static struct i2c_driver pca9539_driver = { | 40 | static struct i2c_driver pca9539_driver = { |
41 | .owner = THIS_MODULE, | 41 | .driver = { |
42 | .name = "pca9539", | 42 | .name = "pca9539", |
43 | .flags = I2C_DF_NOTIFY, | 43 | }, |
44 | .attach_adapter = pca9539_attach_adapter, | 44 | .attach_adapter = pca9539_attach_adapter, |
45 | .detach_client = pca9539_detach_client, | 45 | .detach_client = pca9539_detach_client, |
46 | }; | 46 | }; |
diff --git a/drivers/i2c/chips/pcf8574.c b/drivers/i2c/chips/pcf8574.c index c323c2de236c..c3e6449c4481 100644 --- a/drivers/i2c/chips/pcf8574.c +++ b/drivers/i2c/chips/pcf8574.c | |||
@@ -65,10 +65,10 @@ static void pcf8574_init_client(struct i2c_client *client); | |||
65 | 65 | ||
66 | /* This is the driver that will be inserted */ | 66 | /* This is the driver that will be inserted */ |
67 | static struct i2c_driver pcf8574_driver = { | 67 | static struct i2c_driver pcf8574_driver = { |
68 | .owner = THIS_MODULE, | 68 | .driver = { |
69 | .name = "pcf8574", | 69 | .name = "pcf8574", |
70 | }, | ||
70 | .id = I2C_DRIVERID_PCF8574, | 71 | .id = I2C_DRIVERID_PCF8574, |
71 | .flags = I2C_DF_NOTIFY, | ||
72 | .attach_adapter = pcf8574_attach_adapter, | 72 | .attach_adapter = pcf8574_attach_adapter, |
73 | .detach_client = pcf8574_detach_client, | 73 | .detach_client = pcf8574_detach_client, |
74 | }; | 74 | }; |
diff --git a/drivers/i2c/chips/pcf8591.c b/drivers/i2c/chips/pcf8591.c index ce420a67560b..36cff09c678d 100644 --- a/drivers/i2c/chips/pcf8591.c +++ b/drivers/i2c/chips/pcf8591.c | |||
@@ -88,10 +88,10 @@ static int pcf8591_read_channel(struct device *dev, int channel); | |||
88 | 88 | ||
89 | /* This is the driver that will be inserted */ | 89 | /* This is the driver that will be inserted */ |
90 | static struct i2c_driver pcf8591_driver = { | 90 | static struct i2c_driver pcf8591_driver = { |
91 | .owner = THIS_MODULE, | 91 | .driver = { |
92 | .name = "pcf8591", | 92 | .name = "pcf8591", |
93 | }, | ||
93 | .id = I2C_DRIVERID_PCF8591, | 94 | .id = I2C_DRIVERID_PCF8591, |
94 | .flags = I2C_DF_NOTIFY, | ||
95 | .attach_adapter = pcf8591_attach_adapter, | 95 | .attach_adapter = pcf8591_attach_adapter, |
96 | .detach_client = pcf8591_detach_client, | 96 | .detach_client = pcf8591_detach_client, |
97 | }; | 97 | }; |
diff --git a/drivers/i2c/chips/rtc8564.c b/drivers/i2c/chips/rtc8564.c index 916cdc1af23c..ceaa6b0bdfd6 100644 --- a/drivers/i2c/chips/rtc8564.c +++ b/drivers/i2c/chips/rtc8564.c | |||
@@ -14,6 +14,7 @@ | |||
14 | */ | 14 | */ |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/bcd.h> | ||
17 | #include <linux/i2c.h> | 18 | #include <linux/i2c.h> |
18 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
19 | #include <linux/string.h> | 20 | #include <linux/string.h> |
@@ -52,9 +53,6 @@ static inline u8 _rtc8564_ctrl2(struct i2c_client *client) | |||
52 | #define CTRL1(c) _rtc8564_ctrl1(c) | 53 | #define CTRL1(c) _rtc8564_ctrl1(c) |
53 | #define CTRL2(c) _rtc8564_ctrl2(c) | 54 | #define CTRL2(c) _rtc8564_ctrl2(c) |
54 | 55 | ||
55 | #define BCD_TO_BIN(val) (((val)&15) + ((val)>>4)*10) | ||
56 | #define BIN_TO_BCD(val) ((((val)/10)<<4) + (val)%10) | ||
57 | |||
58 | static int debug;; | 56 | static int debug;; |
59 | module_param(debug, int, S_IRUGO | S_IWUSR); | 57 | module_param(debug, int, S_IRUGO | S_IWUSR); |
60 | 58 | ||
@@ -157,7 +155,6 @@ static int rtc8564_attach(struct i2c_adapter *adap, int addr, int kind) | |||
157 | 155 | ||
158 | strlcpy(new_client->name, "RTC8564", I2C_NAME_SIZE); | 156 | strlcpy(new_client->name, "RTC8564", I2C_NAME_SIZE); |
159 | i2c_set_clientdata(new_client, d); | 157 | i2c_set_clientdata(new_client, d); |
160 | new_client->flags = I2C_CLIENT_ALLOW_USE; | ||
161 | new_client->addr = addr; | 158 | new_client->addr = addr; |
162 | new_client->adapter = adap; | 159 | new_client->adapter = adap; |
163 | new_client->driver = &rtc8564_driver; | 160 | new_client->driver = &rtc8564_driver; |
@@ -224,16 +221,16 @@ static int rtc8564_get_datetime(struct i2c_client *client, struct rtc_tm *dt) | |||
224 | return ret; | 221 | return ret; |
225 | 222 | ||
226 | /* century stored in minute alarm reg */ | 223 | /* century stored in minute alarm reg */ |
227 | dt->year = BCD_TO_BIN(buf[RTC8564_REG_YEAR]); | 224 | dt->year = BCD2BIN(buf[RTC8564_REG_YEAR]); |
228 | dt->year += 100 * BCD_TO_BIN(buf[RTC8564_REG_AL_MIN] & 0x3f); | 225 | dt->year += 100 * BCD2BIN(buf[RTC8564_REG_AL_MIN] & 0x3f); |
229 | dt->mday = BCD_TO_BIN(buf[RTC8564_REG_DAY] & 0x3f); | 226 | dt->mday = BCD2BIN(buf[RTC8564_REG_DAY] & 0x3f); |
230 | dt->wday = BCD_TO_BIN(buf[RTC8564_REG_WDAY] & 7); | 227 | dt->wday = BCD2BIN(buf[RTC8564_REG_WDAY] & 7); |
231 | dt->mon = BCD_TO_BIN(buf[RTC8564_REG_MON_CENT] & 0x1f); | 228 | dt->mon = BCD2BIN(buf[RTC8564_REG_MON_CENT] & 0x1f); |
232 | 229 | ||
233 | dt->secs = BCD_TO_BIN(buf[RTC8564_REG_SEC] & 0x7f); | 230 | dt->secs = BCD2BIN(buf[RTC8564_REG_SEC] & 0x7f); |
234 | dt->vl = (buf[RTC8564_REG_SEC] & 0x80) == 0x80; | 231 | dt->vl = (buf[RTC8564_REG_SEC] & 0x80) == 0x80; |
235 | dt->mins = BCD_TO_BIN(buf[RTC8564_REG_MIN] & 0x7f); | 232 | dt->mins = BCD2BIN(buf[RTC8564_REG_MIN] & 0x7f); |
236 | dt->hours = BCD_TO_BIN(buf[RTC8564_REG_HR] & 0x3f); | 233 | dt->hours = BCD2BIN(buf[RTC8564_REG_HR] & 0x3f); |
237 | 234 | ||
238 | _DBGRTCTM(2, *dt); | 235 | _DBGRTCTM(2, *dt); |
239 | 236 | ||
@@ -255,18 +252,18 @@ rtc8564_set_datetime(struct i2c_client *client, struct rtc_tm *dt, int datetoo) | |||
255 | 252 | ||
256 | buf[RTC8564_REG_CTRL1] = CTRL1(client) | RTC8564_CTRL1_STOP; | 253 | buf[RTC8564_REG_CTRL1] = CTRL1(client) | RTC8564_CTRL1_STOP; |
257 | buf[RTC8564_REG_CTRL2] = CTRL2(client); | 254 | buf[RTC8564_REG_CTRL2] = CTRL2(client); |
258 | buf[RTC8564_REG_SEC] = BIN_TO_BCD(dt->secs); | 255 | buf[RTC8564_REG_SEC] = BIN2BCD(dt->secs); |
259 | buf[RTC8564_REG_MIN] = BIN_TO_BCD(dt->mins); | 256 | buf[RTC8564_REG_MIN] = BIN2BCD(dt->mins); |
260 | buf[RTC8564_REG_HR] = BIN_TO_BCD(dt->hours); | 257 | buf[RTC8564_REG_HR] = BIN2BCD(dt->hours); |
261 | 258 | ||
262 | if (datetoo) { | 259 | if (datetoo) { |
263 | len += 5; | 260 | len += 5; |
264 | buf[RTC8564_REG_DAY] = BIN_TO_BCD(dt->mday); | 261 | buf[RTC8564_REG_DAY] = BIN2BCD(dt->mday); |
265 | buf[RTC8564_REG_WDAY] = BIN_TO_BCD(dt->wday); | 262 | buf[RTC8564_REG_WDAY] = BIN2BCD(dt->wday); |
266 | buf[RTC8564_REG_MON_CENT] = BIN_TO_BCD(dt->mon) & 0x1f; | 263 | buf[RTC8564_REG_MON_CENT] = BIN2BCD(dt->mon) & 0x1f; |
267 | /* century stored in minute alarm reg */ | 264 | /* century stored in minute alarm reg */ |
268 | buf[RTC8564_REG_YEAR] = BIN_TO_BCD(dt->year % 100); | 265 | buf[RTC8564_REG_YEAR] = BIN2BCD(dt->year % 100); |
269 | buf[RTC8564_REG_AL_MIN] = BIN_TO_BCD(dt->year / 100); | 266 | buf[RTC8564_REG_AL_MIN] = BIN2BCD(dt->year / 100); |
270 | } | 267 | } |
271 | 268 | ||
272 | ret = rtc8564_write(client, 0, buf, len); | 269 | ret = rtc8564_write(client, 0, buf, len); |
@@ -361,10 +358,10 @@ rtc8564_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
361 | } | 358 | } |
362 | 359 | ||
363 | static struct i2c_driver rtc8564_driver = { | 360 | static struct i2c_driver rtc8564_driver = { |
364 | .owner = THIS_MODULE, | 361 | .driver = { |
365 | .name = "RTC8564", | 362 | .name = "RTC8564", |
363 | }, | ||
366 | .id = I2C_DRIVERID_RTC8564, | 364 | .id = I2C_DRIVERID_RTC8564, |
367 | .flags = I2C_DF_NOTIFY, | ||
368 | .attach_adapter = rtc8564_probe, | 365 | .attach_adapter = rtc8564_probe, |
369 | .detach_client = rtc8564_detach, | 366 | .detach_client = rtc8564_detach, |
370 | .command = rtc8564_command | 367 | .command = rtc8564_command |
diff --git a/drivers/i2c/chips/tps65010.c b/drivers/i2c/chips/tps65010.c index 280dd7a45db6..e70b3db69edd 100644 --- a/drivers/i2c/chips/tps65010.c +++ b/drivers/i2c/chips/tps65010.c | |||
@@ -637,9 +637,9 @@ static int __init tps65010_scan_bus(struct i2c_adapter *bus) | |||
637 | } | 637 | } |
638 | 638 | ||
639 | static struct i2c_driver tps65010_driver = { | 639 | static struct i2c_driver tps65010_driver = { |
640 | .owner = THIS_MODULE, | 640 | .driver = { |
641 | .name = "tps65010", | 641 | .name = "tps65010", |
642 | .flags = I2C_DF_NOTIFY, | 642 | }, |
643 | .attach_adapter = tps65010_scan_bus, | 643 | .attach_adapter = tps65010_scan_bus, |
644 | .detach_client = __exit_p(tps65010_detach_client), | 644 | .detach_client = __exit_p(tps65010_detach_client), |
645 | }; | 645 | }; |
diff --git a/drivers/i2c/chips/x1205.c b/drivers/i2c/chips/x1205.c index 7da366cdc18c..245fffa92dbd 100644 --- a/drivers/i2c/chips/x1205.c +++ b/drivers/i2c/chips/x1205.c | |||
@@ -105,9 +105,9 @@ static int x1205_command(struct i2c_client *client, unsigned int cmd, | |||
105 | void *arg); | 105 | void *arg); |
106 | 106 | ||
107 | static struct i2c_driver x1205_driver = { | 107 | static struct i2c_driver x1205_driver = { |
108 | .owner = THIS_MODULE, | 108 | .driver = { |
109 | .name = "x1205", | 109 | .name = "x1205", |
110 | .flags = I2C_DF_NOTIFY, | 110 | }, |
111 | .attach_adapter = &x1205_attach, | 111 | .attach_adapter = &x1205_attach, |
112 | .detach_client = &x1205_detach, | 112 | .detach_client = &x1205_detach, |
113 | }; | 113 | }; |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 82ea1b7ec914..52b77477df57 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -197,7 +197,7 @@ int i2c_add_adapter(struct i2c_adapter *adap) | |||
197 | /* inform drivers of new adapters */ | 197 | /* inform drivers of new adapters */ |
198 | list_for_each(item,&drivers) { | 198 | list_for_each(item,&drivers) { |
199 | driver = list_entry(item, struct i2c_driver, list); | 199 | driver = list_entry(item, struct i2c_driver, list); |
200 | if (driver->flags & I2C_DF_NOTIFY) | 200 | if (driver->attach_adapter) |
201 | /* We ignore the return code; if it fails, too bad */ | 201 | /* We ignore the return code; if it fails, too bad */ |
202 | driver->attach_adapter(adap); | 202 | driver->attach_adapter(adap); |
203 | } | 203 | } |
@@ -235,7 +235,8 @@ int i2c_del_adapter(struct i2c_adapter *adap) | |||
235 | if (driver->detach_adapter) | 235 | if (driver->detach_adapter) |
236 | if ((res = driver->detach_adapter(adap))) { | 236 | if ((res = driver->detach_adapter(adap))) { |
237 | dev_err(&adap->dev, "detach_adapter failed " | 237 | dev_err(&adap->dev, "detach_adapter failed " |
238 | "for driver [%s]\n", driver->name); | 238 | "for driver [%s]\n", |
239 | driver->driver.name); | ||
239 | goto out_unlock; | 240 | goto out_unlock; |
240 | } | 241 | } |
241 | } | 242 | } |
@@ -245,10 +246,6 @@ int i2c_del_adapter(struct i2c_adapter *adap) | |||
245 | list_for_each_safe(item, _n, &adap->clients) { | 246 | list_for_each_safe(item, _n, &adap->clients) { |
246 | client = list_entry(item, struct i2c_client, list); | 247 | client = list_entry(item, struct i2c_client, list); |
247 | 248 | ||
248 | /* detaching devices is unconditional of the set notify | ||
249 | * flag, as _all_ clients that reside on the adapter | ||
250 | * must be deleted, as this would cause invalid states. | ||
251 | */ | ||
252 | if ((res=client->driver->detach_client(client))) { | 249 | if ((res=client->driver->detach_client(client))) { |
253 | dev_err(&adap->dev, "detach_client failed for client " | 250 | dev_err(&adap->dev, "detach_client failed for client " |
254 | "[%s] at address 0x%02x\n", client->name, | 251 | "[%s] at address 0x%02x\n", client->name, |
@@ -286,7 +283,7 @@ int i2c_del_adapter(struct i2c_adapter *adap) | |||
286 | * chips. | 283 | * chips. |
287 | */ | 284 | */ |
288 | 285 | ||
289 | int i2c_add_driver(struct i2c_driver *driver) | 286 | int i2c_register_driver(struct module *owner, struct i2c_driver *driver) |
290 | { | 287 | { |
291 | struct list_head *item; | 288 | struct list_head *item; |
292 | struct i2c_adapter *adapter; | 289 | struct i2c_adapter *adapter; |
@@ -295,8 +292,7 @@ int i2c_add_driver(struct i2c_driver *driver) | |||
295 | down(&core_lists); | 292 | down(&core_lists); |
296 | 293 | ||
297 | /* add the driver to the list of i2c drivers in the driver core */ | 294 | /* add the driver to the list of i2c drivers in the driver core */ |
298 | driver->driver.owner = driver->owner; | 295 | driver->driver.owner = owner; |
299 | driver->driver.name = driver->name; | ||
300 | driver->driver.bus = &i2c_bus_type; | 296 | driver->driver.bus = &i2c_bus_type; |
301 | driver->driver.probe = i2c_device_probe; | 297 | driver->driver.probe = i2c_device_probe; |
302 | driver->driver.remove = i2c_device_remove; | 298 | driver->driver.remove = i2c_device_remove; |
@@ -306,10 +302,10 @@ int i2c_add_driver(struct i2c_driver *driver) | |||
306 | goto out_unlock; | 302 | goto out_unlock; |
307 | 303 | ||
308 | list_add_tail(&driver->list,&drivers); | 304 | list_add_tail(&driver->list,&drivers); |
309 | pr_debug("i2c-core: driver [%s] registered\n", driver->name); | 305 | pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name); |
310 | 306 | ||
311 | /* now look for instances of driver on our adapters */ | 307 | /* now look for instances of driver on our adapters */ |
312 | if (driver->flags & I2C_DF_NOTIFY) { | 308 | if (driver->attach_adapter) { |
313 | list_for_each(item,&adapters) { | 309 | list_for_each(item,&adapters) { |
314 | adapter = list_entry(item, struct i2c_adapter, list); | 310 | adapter = list_entry(item, struct i2c_adapter, list); |
315 | driver->attach_adapter(adapter); | 311 | driver->attach_adapter(adapter); |
@@ -320,6 +316,7 @@ int i2c_add_driver(struct i2c_driver *driver) | |||
320 | up(&core_lists); | 316 | up(&core_lists); |
321 | return res; | 317 | return res; |
322 | } | 318 | } |
319 | EXPORT_SYMBOL(i2c_register_driver); | ||
323 | 320 | ||
324 | int i2c_del_driver(struct i2c_driver *driver) | 321 | int i2c_del_driver(struct i2c_driver *driver) |
325 | { | 322 | { |
@@ -334,17 +331,14 @@ int i2c_del_driver(struct i2c_driver *driver) | |||
334 | /* Have a look at each adapter, if clients of this driver are still | 331 | /* Have a look at each adapter, if clients of this driver are still |
335 | * attached. If so, detach them to be able to kill the driver | 332 | * attached. If so, detach them to be able to kill the driver |
336 | * afterwards. | 333 | * afterwards. |
337 | * | ||
338 | * Removing clients does not depend on the notify flag, else | ||
339 | * invalid operation might (will!) result, when using stale client | ||
340 | * pointers. | ||
341 | */ | 334 | */ |
342 | list_for_each(item1,&adapters) { | 335 | list_for_each(item1,&adapters) { |
343 | adap = list_entry(item1, struct i2c_adapter, list); | 336 | adap = list_entry(item1, struct i2c_adapter, list); |
344 | if (driver->detach_adapter) { | 337 | if (driver->detach_adapter) { |
345 | if ((res = driver->detach_adapter(adap))) { | 338 | if ((res = driver->detach_adapter(adap))) { |
346 | dev_err(&adap->dev, "detach_adapter failed " | 339 | dev_err(&adap->dev, "detach_adapter failed " |
347 | "for driver [%s]\n", driver->name); | 340 | "for driver [%s]\n", |
341 | driver->driver.name); | ||
348 | goto out_unlock; | 342 | goto out_unlock; |
349 | } | 343 | } |
350 | } else { | 344 | } else { |
@@ -368,7 +362,7 @@ int i2c_del_driver(struct i2c_driver *driver) | |||
368 | 362 | ||
369 | driver_unregister(&driver->driver); | 363 | driver_unregister(&driver->driver); |
370 | list_del(&driver->list); | 364 | list_del(&driver->list); |
371 | pr_debug("i2c-core: driver [%s] unregistered\n", driver->name); | 365 | pr_debug("i2c-core: driver [%s] unregistered\n", driver->driver.name); |
372 | 366 | ||
373 | out_unlock: | 367 | out_unlock: |
374 | up(&core_lists); | 368 | up(&core_lists); |
@@ -419,8 +413,7 @@ int i2c_attach_client(struct i2c_client *client) | |||
419 | } | 413 | } |
420 | } | 414 | } |
421 | 415 | ||
422 | if (client->flags & I2C_CLIENT_ALLOW_USE) | 416 | client->usage_count = 0; |
423 | client->usage_count = 0; | ||
424 | 417 | ||
425 | client->dev.parent = &client->adapter->dev; | 418 | client->dev.parent = &client->adapter->dev; |
426 | client->dev.driver = &client->driver->driver; | 419 | client->dev.driver = &client->driver->driver; |
@@ -443,8 +436,7 @@ int i2c_detach_client(struct i2c_client *client) | |||
443 | struct i2c_adapter *adapter = client->adapter; | 436 | struct i2c_adapter *adapter = client->adapter; |
444 | int res = 0; | 437 | int res = 0; |
445 | 438 | ||
446 | if ((client->flags & I2C_CLIENT_ALLOW_USE) | 439 | if (client->usage_count > 0) { |
447 | && (client->usage_count > 0)) { | ||
448 | dev_warn(&client->dev, "Client [%s] still busy, " | 440 | dev_warn(&client->dev, "Client [%s] still busy, " |
449 | "can't detach\n", client->name); | 441 | "can't detach\n", client->name); |
450 | return -EBUSY; | 442 | return -EBUSY; |
@@ -475,10 +467,10 @@ int i2c_detach_client(struct i2c_client *client) | |||
475 | static int i2c_inc_use_client(struct i2c_client *client) | 467 | static int i2c_inc_use_client(struct i2c_client *client) |
476 | { | 468 | { |
477 | 469 | ||
478 | if (!try_module_get(client->driver->owner)) | 470 | if (!try_module_get(client->driver->driver.owner)) |
479 | return -ENODEV; | 471 | return -ENODEV; |
480 | if (!try_module_get(client->adapter->owner)) { | 472 | if (!try_module_get(client->adapter->owner)) { |
481 | module_put(client->driver->owner); | 473 | module_put(client->driver->driver.owner); |
482 | return -ENODEV; | 474 | return -ENODEV; |
483 | } | 475 | } |
484 | 476 | ||
@@ -487,7 +479,7 @@ static int i2c_inc_use_client(struct i2c_client *client) | |||
487 | 479 | ||
488 | static void i2c_dec_use_client(struct i2c_client *client) | 480 | static void i2c_dec_use_client(struct i2c_client *client) |
489 | { | 481 | { |
490 | module_put(client->driver->owner); | 482 | module_put(client->driver->driver.owner); |
491 | module_put(client->adapter->owner); | 483 | module_put(client->adapter->owner); |
492 | } | 484 | } |
493 | 485 | ||
@@ -499,33 +491,20 @@ int i2c_use_client(struct i2c_client *client) | |||
499 | if (ret) | 491 | if (ret) |
500 | return ret; | 492 | return ret; |
501 | 493 | ||
502 | if (client->flags & I2C_CLIENT_ALLOW_USE) { | 494 | client->usage_count++; |
503 | if (client->flags & I2C_CLIENT_ALLOW_MULTIPLE_USE) | ||
504 | client->usage_count++; | ||
505 | else if (client->usage_count > 0) | ||
506 | goto busy; | ||
507 | else | ||
508 | client->usage_count++; | ||
509 | } | ||
510 | 495 | ||
511 | return 0; | 496 | return 0; |
512 | busy: | ||
513 | i2c_dec_use_client(client); | ||
514 | return -EBUSY; | ||
515 | } | 497 | } |
516 | 498 | ||
517 | int i2c_release_client(struct i2c_client *client) | 499 | int i2c_release_client(struct i2c_client *client) |
518 | { | 500 | { |
519 | if(client->flags & I2C_CLIENT_ALLOW_USE) { | 501 | if (!client->usage_count) { |
520 | if(client->usage_count>0) | 502 | pr_debug("i2c-core: %s used one too many times\n", |
521 | client->usage_count--; | 503 | __FUNCTION__); |
522 | else { | 504 | return -EPERM; |
523 | pr_debug("i2c-core: %s used one too many times\n", | ||
524 | __FUNCTION__); | ||
525 | return -EPERM; | ||
526 | } | ||
527 | } | 505 | } |
528 | 506 | ||
507 | client->usage_count--; | ||
529 | i2c_dec_use_client(client); | 508 | i2c_dec_use_client(client); |
530 | 509 | ||
531 | return 0; | 510 | return 0; |
@@ -539,14 +518,14 @@ void i2c_clients_command(struct i2c_adapter *adap, unsigned int cmd, void *arg) | |||
539 | down(&adap->clist_lock); | 518 | down(&adap->clist_lock); |
540 | list_for_each(item,&adap->clients) { | 519 | list_for_each(item,&adap->clients) { |
541 | client = list_entry(item, struct i2c_client, list); | 520 | client = list_entry(item, struct i2c_client, list); |
542 | if (!try_module_get(client->driver->owner)) | 521 | if (!try_module_get(client->driver->driver.owner)) |
543 | continue; | 522 | continue; |
544 | if (NULL != client->driver->command) { | 523 | if (NULL != client->driver->command) { |
545 | up(&adap->clist_lock); | 524 | up(&adap->clist_lock); |
546 | client->driver->command(client,cmd,arg); | 525 | client->driver->command(client,cmd,arg); |
547 | down(&adap->clist_lock); | 526 | down(&adap->clist_lock); |
548 | } | 527 | } |
549 | module_put(client->driver->owner); | 528 | module_put(client->driver->driver.owner); |
550 | } | 529 | } |
551 | up(&adap->clist_lock); | 530 | up(&adap->clist_lock); |
552 | } | 531 | } |
@@ -1147,7 +1126,6 @@ EXPORT_SYMBOL_GPL(i2c_bus_type); | |||
1147 | 1126 | ||
1148 | EXPORT_SYMBOL(i2c_add_adapter); | 1127 | EXPORT_SYMBOL(i2c_add_adapter); |
1149 | EXPORT_SYMBOL(i2c_del_adapter); | 1128 | EXPORT_SYMBOL(i2c_del_adapter); |
1150 | EXPORT_SYMBOL(i2c_add_driver); | ||
1151 | EXPORT_SYMBOL(i2c_del_driver); | 1129 | EXPORT_SYMBOL(i2c_del_driver); |
1152 | EXPORT_SYMBOL(i2c_attach_client); | 1130 | EXPORT_SYMBOL(i2c_attach_client); |
1153 | EXPORT_SYMBOL(i2c_detach_client); | 1131 | EXPORT_SYMBOL(i2c_detach_client); |
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index 8af0bd1424d2..ed7eed388bae 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c | |||
@@ -42,8 +42,7 @@ static struct i2c_client i2cdev_client_template; | |||
42 | struct i2c_dev { | 42 | struct i2c_dev { |
43 | int minor; | 43 | int minor; |
44 | struct i2c_adapter *adap; | 44 | struct i2c_adapter *adap; |
45 | struct class_device class_dev; | 45 | struct class_device *class_dev; |
46 | struct completion released; /* FIXME, we need a class_device_unregister() */ | ||
47 | }; | 46 | }; |
48 | #define to_i2c_dev(d) container_of(d, struct i2c_dev, class_dev) | 47 | #define to_i2c_dev(d) container_of(d, struct i2c_dev, class_dev) |
49 | 48 | ||
@@ -105,7 +104,10 @@ static void return_i2c_dev(struct i2c_dev *i2c_dev) | |||
105 | 104 | ||
106 | static ssize_t show_adapter_name(struct class_device *class_dev, char *buf) | 105 | static ssize_t show_adapter_name(struct class_device *class_dev, char *buf) |
107 | { | 106 | { |
108 | struct i2c_dev *i2c_dev = to_i2c_dev(class_dev); | 107 | struct i2c_dev *i2c_dev = i2c_dev_get_by_minor(MINOR(class_dev->devt)); |
108 | |||
109 | if (!i2c_dev) | ||
110 | return -ENODEV; | ||
109 | return sprintf(buf, "%s\n", i2c_dev->adap->name); | 111 | return sprintf(buf, "%s\n", i2c_dev->adap->name); |
110 | } | 112 | } |
111 | static CLASS_DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL); | 113 | static CLASS_DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL); |
@@ -408,21 +410,12 @@ static struct file_operations i2cdev_fops = { | |||
408 | .release = i2cdev_release, | 410 | .release = i2cdev_release, |
409 | }; | 411 | }; |
410 | 412 | ||
411 | static void release_i2c_dev(struct class_device *dev) | 413 | static struct class *i2c_dev_class; |
412 | { | ||
413 | struct i2c_dev *i2c_dev = to_i2c_dev(dev); | ||
414 | complete(&i2c_dev->released); | ||
415 | } | ||
416 | |||
417 | static struct class i2c_dev_class = { | ||
418 | .name = "i2c-dev", | ||
419 | .release = &release_i2c_dev, | ||
420 | }; | ||
421 | 414 | ||
422 | static int i2cdev_attach_adapter(struct i2c_adapter *adap) | 415 | static int i2cdev_attach_adapter(struct i2c_adapter *adap) |
423 | { | 416 | { |
424 | struct i2c_dev *i2c_dev; | 417 | struct i2c_dev *i2c_dev; |
425 | int retval; | 418 | struct device *dev; |
426 | 419 | ||
427 | i2c_dev = get_free_i2c_dev(adap); | 420 | i2c_dev = get_free_i2c_dev(adap); |
428 | if (IS_ERR(i2c_dev)) | 421 | if (IS_ERR(i2c_dev)) |
@@ -434,21 +427,20 @@ static int i2cdev_attach_adapter(struct i2c_adapter *adap) | |||
434 | /* register this i2c device with the driver core */ | 427 | /* register this i2c device with the driver core */ |
435 | i2c_dev->adap = adap; | 428 | i2c_dev->adap = adap; |
436 | if (adap->dev.parent == &platform_bus) | 429 | if (adap->dev.parent == &platform_bus) |
437 | i2c_dev->class_dev.dev = &adap->dev; | 430 | dev = &adap->dev; |
438 | else | 431 | else |
439 | i2c_dev->class_dev.dev = adap->dev.parent; | 432 | dev = adap->dev.parent; |
440 | i2c_dev->class_dev.class = &i2c_dev_class; | 433 | i2c_dev->class_dev = class_device_create(i2c_dev_class, NULL, |
441 | i2c_dev->class_dev.devt = MKDEV(I2C_MAJOR, i2c_dev->minor); | 434 | MKDEV(I2C_MAJOR, i2c_dev->minor), |
442 | snprintf(i2c_dev->class_dev.class_id, BUS_ID_SIZE, "i2c-%d", i2c_dev->minor); | 435 | dev, "i2c-%d", i2c_dev->minor); |
443 | retval = class_device_register(&i2c_dev->class_dev); | 436 | if (!i2c_dev->class_dev) |
444 | if (retval) | ||
445 | goto error; | 437 | goto error; |
446 | class_device_create_file(&i2c_dev->class_dev, &class_device_attr_name); | 438 | class_device_create_file(i2c_dev->class_dev, &class_device_attr_name); |
447 | return 0; | 439 | return 0; |
448 | error: | 440 | error: |
449 | return_i2c_dev(i2c_dev); | 441 | return_i2c_dev(i2c_dev); |
450 | kfree(i2c_dev); | 442 | kfree(i2c_dev); |
451 | return retval; | 443 | return -ENODEV; |
452 | } | 444 | } |
453 | 445 | ||
454 | static int i2cdev_detach_adapter(struct i2c_adapter *adap) | 446 | static int i2cdev_detach_adapter(struct i2c_adapter *adap) |
@@ -459,10 +451,8 @@ static int i2cdev_detach_adapter(struct i2c_adapter *adap) | |||
459 | if (!i2c_dev) | 451 | if (!i2c_dev) |
460 | return -ENODEV; | 452 | return -ENODEV; |
461 | 453 | ||
462 | init_completion(&i2c_dev->released); | ||
463 | return_i2c_dev(i2c_dev); | 454 | return_i2c_dev(i2c_dev); |
464 | class_device_unregister(&i2c_dev->class_dev); | 455 | class_device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, i2c_dev->minor)); |
465 | wait_for_completion(&i2c_dev->released); | ||
466 | kfree(i2c_dev); | 456 | kfree(i2c_dev); |
467 | 457 | ||
468 | pr_debug("i2c-dev: adapter [%s] unregistered\n", adap->name); | 458 | pr_debug("i2c-dev: adapter [%s] unregistered\n", adap->name); |
@@ -474,21 +464,14 @@ static int i2cdev_detach_client(struct i2c_client *client) | |||
474 | return 0; | 464 | return 0; |
475 | } | 465 | } |
476 | 466 | ||
477 | static int i2cdev_command(struct i2c_client *client, unsigned int cmd, | ||
478 | void *arg) | ||
479 | { | ||
480 | return -1; | ||
481 | } | ||
482 | |||
483 | static struct i2c_driver i2cdev_driver = { | 467 | static struct i2c_driver i2cdev_driver = { |
484 | .owner = THIS_MODULE, | 468 | .driver = { |
485 | .name = "dev_driver", | 469 | .name = "dev_driver", |
470 | }, | ||
486 | .id = I2C_DRIVERID_I2CDEV, | 471 | .id = I2C_DRIVERID_I2CDEV, |
487 | .flags = I2C_DF_NOTIFY, | ||
488 | .attach_adapter = i2cdev_attach_adapter, | 472 | .attach_adapter = i2cdev_attach_adapter, |
489 | .detach_adapter = i2cdev_detach_adapter, | 473 | .detach_adapter = i2cdev_detach_adapter, |
490 | .detach_client = i2cdev_detach_client, | 474 | .detach_client = i2cdev_detach_client, |
491 | .command = i2cdev_command, | ||
492 | }; | 475 | }; |
493 | 476 | ||
494 | static struct i2c_client i2cdev_client_template = { | 477 | static struct i2c_client i2cdev_client_template = { |
@@ -507,8 +490,8 @@ static int __init i2c_dev_init(void) | |||
507 | if (res) | 490 | if (res) |
508 | goto out; | 491 | goto out; |
509 | 492 | ||
510 | res = class_register(&i2c_dev_class); | 493 | i2c_dev_class = class_create(THIS_MODULE, "i2c-dev"); |
511 | if (res) | 494 | if (IS_ERR(i2c_dev_class)) |
512 | goto out_unreg_chrdev; | 495 | goto out_unreg_chrdev; |
513 | 496 | ||
514 | res = i2c_add_driver(&i2cdev_driver); | 497 | res = i2c_add_driver(&i2cdev_driver); |
@@ -518,7 +501,7 @@ static int __init i2c_dev_init(void) | |||
518 | return 0; | 501 | return 0; |
519 | 502 | ||
520 | out_unreg_class: | 503 | out_unreg_class: |
521 | class_unregister(&i2c_dev_class); | 504 | class_destroy(i2c_dev_class); |
522 | out_unreg_chrdev: | 505 | out_unreg_chrdev: |
523 | unregister_chrdev(I2C_MAJOR, "i2c"); | 506 | unregister_chrdev(I2C_MAJOR, "i2c"); |
524 | out: | 507 | out: |
@@ -529,7 +512,7 @@ out: | |||
529 | static void __exit i2c_dev_exit(void) | 512 | static void __exit i2c_dev_exit(void) |
530 | { | 513 | { |
531 | i2c_del_driver(&i2cdev_driver); | 514 | i2c_del_driver(&i2cdev_driver); |
532 | class_unregister(&i2c_dev_class); | 515 | class_destroy(i2c_dev_class); |
533 | unregister_chrdev(I2C_MAJOR,"i2c"); | 516 | unregister_chrdev(I2C_MAJOR,"i2c"); |
534 | } | 517 | } |
535 | 518 | ||
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c index 5e1f5e9653cb..5ebfd1d138da 100644 --- a/drivers/macintosh/therm_adt746x.c +++ b/drivers/macintosh/therm_adt746x.c | |||
@@ -176,9 +176,9 @@ detach_thermostat(struct i2c_adapter *adapter) | |||
176 | } | 176 | } |
177 | 177 | ||
178 | static struct i2c_driver thermostat_driver = { | 178 | static struct i2c_driver thermostat_driver = { |
179 | .owner = THIS_MODULE, | 179 | .driver = { |
180 | .name = "therm_adt746x", | 180 | .name = "therm_adt746x", |
181 | .flags = I2C_DF_NOTIFY, | 181 | }, |
182 | .attach_adapter = attach_thermostat, | 182 | .attach_adapter = attach_thermostat, |
183 | .detach_adapter = detach_thermostat, | 183 | .detach_adapter = detach_thermostat, |
184 | }; | 184 | }; |
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index 435427daed75..8d0958c38b6b 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c | |||
@@ -283,9 +283,9 @@ static int therm_pm72_detach(struct i2c_adapter *adapter); | |||
283 | 283 | ||
284 | static struct i2c_driver therm_pm72_driver = | 284 | static struct i2c_driver therm_pm72_driver = |
285 | { | 285 | { |
286 | .owner = THIS_MODULE, | 286 | .driver = { |
287 | .name = "therm_pm72", | 287 | .name = "therm_pm72", |
288 | .flags = I2C_DF_NOTIFY, | 288 | }, |
289 | .attach_adapter = therm_pm72_attach, | 289 | .attach_adapter = therm_pm72_attach, |
290 | .detach_adapter = therm_pm72_detach, | 290 | .detach_adapter = therm_pm72_detach, |
291 | }; | 291 | }; |
diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c index 6aaa1df1a64e..3d9dd2e166aa 100644 --- a/drivers/macintosh/therm_windtunnel.c +++ b/drivers/macintosh/therm_windtunnel.c | |||
@@ -354,10 +354,10 @@ do_detach( struct i2c_client *client ) | |||
354 | } | 354 | } |
355 | 355 | ||
356 | static struct i2c_driver g4fan_driver = { | 356 | static struct i2c_driver g4fan_driver = { |
357 | .owner = THIS_MODULE, | 357 | .driver = { |
358 | .name = "therm_windtunnel", | 358 | .name = "therm_windtunnel", |
359 | }, | ||
359 | .id = I2C_DRIVERID_G4FAN, | 360 | .id = I2C_DRIVERID_G4FAN, |
360 | .flags = I2C_DF_NOTIFY, | ||
361 | .attach_adapter = do_attach, | 361 | .attach_adapter = do_attach, |
362 | .detach_client = do_detach, | 362 | .detach_client = do_detach, |
363 | }; | 363 | }; |
diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c index c62ed68a3138..57460e46c89f 100644 --- a/drivers/macintosh/windfarm_lm75_sensor.c +++ b/drivers/macintosh/windfarm_lm75_sensor.c | |||
@@ -47,9 +47,9 @@ static int wf_lm75_attach(struct i2c_adapter *adapter); | |||
47 | static int wf_lm75_detach(struct i2c_client *client); | 47 | static int wf_lm75_detach(struct i2c_client *client); |
48 | 48 | ||
49 | static struct i2c_driver wf_lm75_driver = { | 49 | static struct i2c_driver wf_lm75_driver = { |
50 | .owner = THIS_MODULE, | 50 | .driver = { |
51 | .name = "wf_lm75", | 51 | .name = "wf_lm75", |
52 | .flags = I2C_DF_NOTIFY, | 52 | }, |
53 | .attach_adapter = wf_lm75_attach, | 53 | .attach_adapter = wf_lm75_attach, |
54 | .detach_client = wf_lm75_detach, | 54 | .detach_client = wf_lm75_detach, |
55 | }; | 55 | }; |
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c index b996fb59b7e4..1d69bf031fb9 100644 --- a/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/drivers/media/dvb/cinergyT2/cinergyT2.c | |||
@@ -60,7 +60,7 @@ MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); | |||
60 | #define dprintk(level, args...) \ | 60 | #define dprintk(level, args...) \ |
61 | do { \ | 61 | do { \ |
62 | if ((debug & level)) { \ | 62 | if ((debug & level)) { \ |
63 | printk("%s: %s(): ", __stringify(KBUILD_MODNAME), \ | 63 | printk("%s: %s(): ", KBUILD_MODNAME, \ |
64 | __FUNCTION__); \ | 64 | __FUNCTION__); \ |
65 | printk(args); } \ | 65 | printk(args); } \ |
66 | } while (0) | 66 | } while (0) |
diff --git a/drivers/media/dvb/ttpci/budget.h b/drivers/media/dvb/ttpci/budget.h index fdaa3318ad3a..c8d48cfba277 100644 --- a/drivers/media/dvb/ttpci/budget.h +++ b/drivers/media/dvb/ttpci/budget.h | |||
@@ -19,7 +19,7 @@ extern int budget_debug; | |||
19 | #endif | 19 | #endif |
20 | 20 | ||
21 | #define dprintk(level,args...) \ | 21 | #define dprintk(level,args...) \ |
22 | do { if ((budget_debug & level)) { printk("%s: %s(): ",__stringify(KBUILD_MODNAME), __FUNCTION__); printk(args); } } while (0) | 22 | do { if ((budget_debug & level)) { printk("%s: %s(): ", KBUILD_MODNAME, __FUNCTION__); printk(args); } } while (0) |
23 | 23 | ||
24 | struct budget_info { | 24 | struct budget_info { |
25 | char *name; | 25 | char *name; |
diff --git a/drivers/media/video/adv7170.c b/drivers/media/video/adv7170.c index 1ca2b67aedfb..e61003de1d5f 100644 --- a/drivers/media/video/adv7170.c +++ b/drivers/media/video/adv7170.c | |||
@@ -420,7 +420,6 @@ adv7170_detect_client (struct i2c_adapter *adapter, | |||
420 | client->addr = address; | 420 | client->addr = address; |
421 | client->adapter = adapter; | 421 | client->adapter = adapter; |
422 | client->driver = &i2c_driver_adv7170; | 422 | client->driver = &i2c_driver_adv7170; |
423 | client->flags = I2C_CLIENT_ALLOW_USE; | ||
424 | if ((client->addr == I2C_ADV7170 >> 1) || | 423 | if ((client->addr == I2C_ADV7170 >> 1) || |
425 | (client->addr == (I2C_ADV7170 >> 1) + 1)) { | 424 | (client->addr == (I2C_ADV7170 >> 1) + 1)) { |
426 | dname = adv7170_name; | 425 | dname = adv7170_name; |
@@ -498,11 +497,11 @@ adv7170_detach_client (struct i2c_client *client) | |||
498 | /* ----------------------------------------------------------------------- */ | 497 | /* ----------------------------------------------------------------------- */ |
499 | 498 | ||
500 | static struct i2c_driver i2c_driver_adv7170 = { | 499 | static struct i2c_driver i2c_driver_adv7170 = { |
501 | .owner = THIS_MODULE, | 500 | .driver = { |
502 | .name = "adv7170", /* name */ | 501 | .name = "adv7170", /* name */ |
502 | }, | ||
503 | 503 | ||
504 | .id = I2C_DRIVERID_ADV7170, | 504 | .id = I2C_DRIVERID_ADV7170, |
505 | .flags = I2C_DF_NOTIFY, | ||
506 | 505 | ||
507 | .attach_adapter = adv7170_attach_adapter, | 506 | .attach_adapter = adv7170_attach_adapter, |
508 | .detach_client = adv7170_detach_client, | 507 | .detach_client = adv7170_detach_client, |
diff --git a/drivers/media/video/adv7175.c b/drivers/media/video/adv7175.c index 173bca1e0295..6d9536a71ee4 100644 --- a/drivers/media/video/adv7175.c +++ b/drivers/media/video/adv7175.c | |||
@@ -470,7 +470,6 @@ adv7175_detect_client (struct i2c_adapter *adapter, | |||
470 | client->addr = address; | 470 | client->addr = address; |
471 | client->adapter = adapter; | 471 | client->adapter = adapter; |
472 | client->driver = &i2c_driver_adv7175; | 472 | client->driver = &i2c_driver_adv7175; |
473 | client->flags = I2C_CLIENT_ALLOW_USE; | ||
474 | if ((client->addr == I2C_ADV7175 >> 1) || | 473 | if ((client->addr == I2C_ADV7175 >> 1) || |
475 | (client->addr == (I2C_ADV7175 >> 1) + 1)) { | 474 | (client->addr == (I2C_ADV7175 >> 1) + 1)) { |
476 | dname = adv7175_name; | 475 | dname = adv7175_name; |
@@ -548,11 +547,11 @@ adv7175_detach_client (struct i2c_client *client) | |||
548 | /* ----------------------------------------------------------------------- */ | 547 | /* ----------------------------------------------------------------------- */ |
549 | 548 | ||
550 | static struct i2c_driver i2c_driver_adv7175 = { | 549 | static struct i2c_driver i2c_driver_adv7175 = { |
551 | .owner = THIS_MODULE, | 550 | .driver = { |
552 | .name = "adv7175", /* name */ | 551 | .name = "adv7175", /* name */ |
552 | }, | ||
553 | 553 | ||
554 | .id = I2C_DRIVERID_ADV7175, | 554 | .id = I2C_DRIVERID_ADV7175, |
555 | .flags = I2C_DF_NOTIFY, | ||
556 | 555 | ||
557 | .attach_adapter = adv7175_attach_adapter, | 556 | .attach_adapter = adv7175_attach_adapter, |
558 | .detach_client = adv7175_detach_client, | 557 | .detach_client = adv7175_detach_client, |
diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c index 3ee0afca76a7..560b99891753 100644 --- a/drivers/media/video/bt819.c +++ b/drivers/media/video/bt819.c | |||
@@ -535,7 +535,6 @@ bt819_detect_client (struct i2c_adapter *adapter, | |||
535 | client->addr = address; | 535 | client->addr = address; |
536 | client->adapter = adapter; | 536 | client->adapter = adapter; |
537 | client->driver = &i2c_driver_bt819; | 537 | client->driver = &i2c_driver_bt819; |
538 | client->flags = I2C_CLIENT_ALLOW_USE; | ||
539 | 538 | ||
540 | decoder = kmalloc(sizeof(struct bt819), GFP_KERNEL); | 539 | decoder = kmalloc(sizeof(struct bt819), GFP_KERNEL); |
541 | if (decoder == NULL) { | 540 | if (decoder == NULL) { |
@@ -623,11 +622,11 @@ bt819_detach_client (struct i2c_client *client) | |||
623 | /* ----------------------------------------------------------------------- */ | 622 | /* ----------------------------------------------------------------------- */ |
624 | 623 | ||
625 | static struct i2c_driver i2c_driver_bt819 = { | 624 | static struct i2c_driver i2c_driver_bt819 = { |
626 | .owner = THIS_MODULE, | 625 | .driver = { |
627 | .name = "bt819", | 626 | .name = "bt819", |
627 | }, | ||
628 | 628 | ||
629 | .id = I2C_DRIVERID_BT819, | 629 | .id = I2C_DRIVERID_BT819, |
630 | .flags = I2C_DF_NOTIFY, | ||
631 | 630 | ||
632 | .attach_adapter = bt819_attach_adapter, | 631 | .attach_adapter = bt819_attach_adapter, |
633 | .detach_client = bt819_detach_client, | 632 | .detach_client = bt819_detach_client, |
diff --git a/drivers/media/video/bt832.c b/drivers/media/video/bt832.c index 3ca1d768bfd3..1c3ff5f38a6d 100644 --- a/drivers/media/video/bt832.c +++ b/drivers/media/video/bt832.c | |||
@@ -230,10 +230,10 @@ bt832_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
230 | /* ----------------------------------------------------------------------- */ | 230 | /* ----------------------------------------------------------------------- */ |
231 | 231 | ||
232 | static struct i2c_driver driver = { | 232 | static struct i2c_driver driver = { |
233 | .owner = THIS_MODULE, | 233 | .driver = { |
234 | .name = "i2c bt832 driver", | 234 | .name = "i2c bt832 driver", |
235 | }, | ||
235 | .id = -1, /* FIXME */ | 236 | .id = -1, /* FIXME */ |
236 | .flags = I2C_DF_NOTIFY, | ||
237 | .attach_adapter = bt832_probe, | 237 | .attach_adapter = bt832_probe, |
238 | .detach_client = bt832_detach, | 238 | .detach_client = bt832_detach, |
239 | .command = bt832_command, | 239 | .command = bt832_command, |
@@ -241,7 +241,6 @@ static struct i2c_driver driver = { | |||
241 | static struct i2c_client client_template = | 241 | static struct i2c_client client_template = |
242 | { | 242 | { |
243 | .name = "bt832", | 243 | .name = "bt832", |
244 | .flags = I2C_CLIENT_ALLOW_USE, | ||
245 | .driver = &driver, | 244 | .driver = &driver, |
246 | }; | 245 | }; |
247 | 246 | ||
diff --git a/drivers/media/video/bt856.c b/drivers/media/video/bt856.c index 8eb871d0e85b..60508069bbed 100644 --- a/drivers/media/video/bt856.c +++ b/drivers/media/video/bt856.c | |||
@@ -323,7 +323,6 @@ bt856_detect_client (struct i2c_adapter *adapter, | |||
323 | client->addr = address; | 323 | client->addr = address; |
324 | client->adapter = adapter; | 324 | client->adapter = adapter; |
325 | client->driver = &i2c_driver_bt856; | 325 | client->driver = &i2c_driver_bt856; |
326 | client->flags = I2C_CLIENT_ALLOW_USE; | ||
327 | strlcpy(I2C_NAME(client), "bt856", sizeof(I2C_NAME(client))); | 326 | strlcpy(I2C_NAME(client), "bt856", sizeof(I2C_NAME(client))); |
328 | 327 | ||
329 | encoder = kmalloc(sizeof(struct bt856), GFP_KERNEL); | 328 | encoder = kmalloc(sizeof(struct bt856), GFP_KERNEL); |
@@ -405,11 +404,11 @@ bt856_detach_client (struct i2c_client *client) | |||
405 | /* ----------------------------------------------------------------------- */ | 404 | /* ----------------------------------------------------------------------- */ |
406 | 405 | ||
407 | static struct i2c_driver i2c_driver_bt856 = { | 406 | static struct i2c_driver i2c_driver_bt856 = { |
408 | .owner = THIS_MODULE, | 407 | .driver = { |
409 | .name = "bt856", | 408 | .name = "bt856", |
409 | }, | ||
410 | 410 | ||
411 | .id = I2C_DRIVERID_BT856, | 411 | .id = I2C_DRIVERID_BT856, |
412 | .flags = I2C_DF_NOTIFY, | ||
413 | 412 | ||
414 | .attach_adapter = bt856_attach_adapter, | 413 | .attach_adapter = bt856_attach_adapter, |
415 | .detach_client = bt856_detach_client, | 414 | .detach_client = bt856_detach_client, |
diff --git a/drivers/media/video/bttv-i2c.c b/drivers/media/video/bttv-i2c.c index 77619eb131f6..d6418c023d39 100644 --- a/drivers/media/video/bttv-i2c.c +++ b/drivers/media/video/bttv-i2c.c | |||
@@ -300,7 +300,7 @@ static int attach_inform(struct i2c_client *client) | |||
300 | 300 | ||
301 | if (bttv_debug) | 301 | if (bttv_debug) |
302 | printk(KERN_DEBUG "bttv%d: %s i2c attach [addr=0x%x,client=%s]\n", | 302 | printk(KERN_DEBUG "bttv%d: %s i2c attach [addr=0x%x,client=%s]\n", |
303 | btv->c.nr,client->driver->name,client->addr, | 303 | btv->c.nr, client->driver->driver.name, client->addr, |
304 | client->name); | 304 | client->name); |
305 | if (!client->driver->command) | 305 | if (!client->driver->command) |
306 | return 0; | 306 | return 0; |
diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/video/cs53l32a.c index 780b352ec119..643ead1a87ee 100644 --- a/drivers/media/video/cs53l32a.c +++ b/drivers/media/video/cs53l32a.c | |||
@@ -42,15 +42,16 @@ MODULE_PARM_DESC(debug, "Debugging messages\n\t\t\t0=Off (default), 1=On"); | |||
42 | #define cs53l32a_dbg(fmt, arg...) \ | 42 | #define cs53l32a_dbg(fmt, arg...) \ |
43 | do { \ | 43 | do { \ |
44 | if (debug) \ | 44 | if (debug) \ |
45 | printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \ | 45 | printk(KERN_INFO "%s debug %d-%04x: " fmt, \ |
46 | client->driver->driver.name, \ | ||
46 | i2c_adapter_id(client->adapter), client->addr , ## arg); \ | 47 | i2c_adapter_id(client->adapter), client->addr , ## arg); \ |
47 | } while (0) | 48 | } while (0) |
48 | 49 | ||
49 | #define cs53l32a_err(fmt, arg...) do { \ | 50 | #define cs53l32a_err(fmt, arg...) do { \ |
50 | printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \ | 51 | printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \ |
51 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | 52 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) |
52 | #define cs53l32a_info(fmt, arg...) do { \ | 53 | #define cs53l32a_info(fmt, arg...) do { \ |
53 | printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \ | 54 | printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \ |
54 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | 55 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) |
55 | 56 | ||
56 | static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END }; | 57 | static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END }; |
@@ -154,7 +155,6 @@ static int cs53l32a_attach(struct i2c_adapter *adapter, int address, int kind) | |||
154 | client->addr = address; | 155 | client->addr = address; |
155 | client->adapter = adapter; | 156 | client->adapter = adapter; |
156 | client->driver = &i2c_driver; | 157 | client->driver = &i2c_driver; |
157 | client->flags = I2C_CLIENT_ALLOW_USE; | ||
158 | snprintf(client->name, sizeof(client->name) - 1, "cs53l32a"); | 158 | snprintf(client->name, sizeof(client->name) - 1, "cs53l32a"); |
159 | 159 | ||
160 | cs53l32a_info("chip found @ 0x%x (%s)\n", address << 1, adapter->name); | 160 | cs53l32a_info("chip found @ 0x%x (%s)\n", address << 1, adapter->name); |
@@ -216,13 +216,13 @@ static int cs53l32a_detach(struct i2c_client *client) | |||
216 | 216 | ||
217 | /* i2c implementation */ | 217 | /* i2c implementation */ |
218 | static struct i2c_driver i2c_driver = { | 218 | static struct i2c_driver i2c_driver = { |
219 | .name = "cs53l32a", | 219 | .driver = { |
220 | .name = "cs53l32a", | ||
221 | }, | ||
220 | .id = I2C_DRIVERID_CS53L32A, | 222 | .id = I2C_DRIVERID_CS53L32A, |
221 | .flags = I2C_DF_NOTIFY, | ||
222 | .attach_adapter = cs53l32a_probe, | 223 | .attach_adapter = cs53l32a_probe, |
223 | .detach_client = cs53l32a_detach, | 224 | .detach_client = cs53l32a_detach, |
224 | .command = cs53l32a_command, | 225 | .command = cs53l32a_command, |
225 | .owner = THIS_MODULE, | ||
226 | }; | 226 | }; |
227 | 227 | ||
228 | 228 | ||
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index 5b93723a1768..3b09f46dddf6 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c | |||
@@ -773,7 +773,6 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address, | |||
773 | client->addr = address; | 773 | client->addr = address; |
774 | client->adapter = adapter; | 774 | client->adapter = adapter; |
775 | client->driver = &i2c_driver_cx25840; | 775 | client->driver = &i2c_driver_cx25840; |
776 | client->flags = I2C_CLIENT_ALLOW_USE; | ||
777 | snprintf(client->name, sizeof(client->name) - 1, "cx25840"); | 776 | snprintf(client->name, sizeof(client->name) - 1, "cx25840"); |
778 | 777 | ||
779 | cx25840_dbg("detecting cx25840 client on address 0x%x\n", address << 1); | 778 | cx25840_dbg("detecting cx25840 client on address 0x%x\n", address << 1); |
@@ -844,15 +843,15 @@ static int cx25840_detach_client(struct i2c_client *client) | |||
844 | /* ----------------------------------------------------------------------- */ | 843 | /* ----------------------------------------------------------------------- */ |
845 | 844 | ||
846 | static struct i2c_driver i2c_driver_cx25840 = { | 845 | static struct i2c_driver i2c_driver_cx25840 = { |
847 | .name = "cx25840", | 846 | .driver = { |
847 | .name = "cx25840", | ||
848 | }, | ||
848 | 849 | ||
849 | .id = I2C_DRIVERID_CX25840, | 850 | .id = I2C_DRIVERID_CX25840, |
850 | .flags = I2C_DF_NOTIFY, | ||
851 | 851 | ||
852 | .attach_adapter = cx25840_attach_adapter, | 852 | .attach_adapter = cx25840_attach_adapter, |
853 | .detach_client = cx25840_detach_client, | 853 | .detach_client = cx25840_detach_client, |
854 | .command = cx25840_command, | 854 | .command = cx25840_command, |
855 | .owner = THIS_MODULE, | ||
856 | }; | 855 | }; |
857 | 856 | ||
858 | 857 | ||
diff --git a/drivers/media/video/cx25840/cx25840.h b/drivers/media/video/cx25840/cx25840.h index 4932ed1c9b19..40aa59f9c525 100644 --- a/drivers/media/video/cx25840/cx25840.h +++ b/drivers/media/video/cx25840/cx25840.h | |||
@@ -27,15 +27,16 @@ | |||
27 | extern int cx25840_debug; | 27 | extern int cx25840_debug; |
28 | 28 | ||
29 | #define cx25840_dbg(fmt, arg...) do { if (cx25840_debug) \ | 29 | #define cx25840_dbg(fmt, arg...) do { if (cx25840_debug) \ |
30 | printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \ | 30 | printk(KERN_INFO "%s debug %d-%04x: " fmt, \ |
31 | client->driver->driver.name, \ | ||
31 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | 32 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) |
32 | 33 | ||
33 | #define cx25840_err(fmt, arg...) do { \ | 34 | #define cx25840_err(fmt, arg...) do { \ |
34 | printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \ | 35 | printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \ |
35 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | 36 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) |
36 | 37 | ||
37 | #define cx25840_info(fmt, arg...) do { \ | 38 | #define cx25840_info(fmt, arg...) do { \ |
38 | printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \ | 39 | printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \ |
39 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | 40 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) |
40 | 41 | ||
41 | #define CX25840_CID_CARDTYPE (V4L2_CID_PRIVATE_BASE+0) | 42 | #define CX25840_CID_CARDTYPE (V4L2_CID_PRIVATE_BASE+0) |
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c index 9790d412f192..4a8fb161b16a 100644 --- a/drivers/media/video/cx88/cx88-i2c.c +++ b/drivers/media/video/cx88/cx88-i2c.c | |||
@@ -94,7 +94,7 @@ static int attach_inform(struct i2c_client *client) | |||
94 | struct cx88_core *core = i2c_get_adapdata(client->adapter); | 94 | struct cx88_core *core = i2c_get_adapdata(client->adapter); |
95 | 95 | ||
96 | dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n", | 96 | dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n", |
97 | client->driver->name, client->addr, client->name); | 97 | client->driver->driver.name, client->addr, client->name); |
98 | if (!client->driver->command) | 98 | if (!client->driver->command) |
99 | return 0; | 99 | return 0; |
100 | 100 | ||
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c index 7f5603054f02..d14bcf4ceaea 100644 --- a/drivers/media/video/em28xx/em28xx-i2c.c +++ b/drivers/media/video/em28xx/em28xx-i2c.c | |||
@@ -497,7 +497,6 @@ static struct i2c_adapter em28xx_adap_template = { | |||
497 | 497 | ||
498 | static struct i2c_client em28xx_client_template = { | 498 | static struct i2c_client em28xx_client_template = { |
499 | .name = "em28xx internal", | 499 | .name = "em28xx internal", |
500 | .flags = I2C_CLIENT_ALLOW_USE, | ||
501 | }; | 500 | }; |
502 | 501 | ||
503 | /* ----------------------------------------------------------- */ | 502 | /* ----------------------------------------------------------- */ |
diff --git a/drivers/media/video/indycam.c b/drivers/media/video/indycam.c index deeef125eb92..bb5cbecffcc3 100644 --- a/drivers/media/video/indycam.c +++ b/drivers/media/video/indycam.c | |||
@@ -451,10 +451,10 @@ static int indycam_command(struct i2c_client *client, unsigned int cmd, | |||
451 | } | 451 | } |
452 | 452 | ||
453 | static struct i2c_driver i2c_driver_indycam = { | 453 | static struct i2c_driver i2c_driver_indycam = { |
454 | .owner = THIS_MODULE, | 454 | .driver = { |
455 | .name = "indycam", | 455 | .name = "indycam", |
456 | }, | ||
456 | .id = I2C_DRIVERID_INDYCAM, | 457 | .id = I2C_DRIVERID_INDYCAM, |
457 | .flags = I2C_DF_NOTIFY, | ||
458 | .attach_adapter = indycam_probe, | 458 | .attach_adapter = indycam_probe, |
459 | .detach_client = indycam_detach, | 459 | .detach_client = indycam_detach, |
460 | .command = indycam_command, | 460 | .command = indycam_command, |
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index 740e543311af..3cc1d6a6019b 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c | |||
@@ -278,9 +278,10 @@ static int ir_detach(struct i2c_client *client); | |||
278 | static int ir_probe(struct i2c_adapter *adap); | 278 | static int ir_probe(struct i2c_adapter *adap); |
279 | 279 | ||
280 | static struct i2c_driver driver = { | 280 | static struct i2c_driver driver = { |
281 | .name = "ir remote kbd driver", | 281 | .driver = { |
282 | .name = "ir remote kbd driver", | ||
283 | }, | ||
282 | .id = I2C_DRIVERID_INFRARED, | 284 | .id = I2C_DRIVERID_INFRARED, |
283 | .flags = I2C_DF_NOTIFY, | ||
284 | .attach_adapter = ir_probe, | 285 | .attach_adapter = ir_probe, |
285 | .detach_client = ir_detach, | 286 | .detach_client = ir_detach, |
286 | }; | 287 | }; |
diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c index d86f8e92e534..183253e2dd91 100644 --- a/drivers/media/video/msp3400.c +++ b/drivers/media/video/msp3400.c | |||
@@ -59,7 +59,8 @@ | |||
59 | #define msp3400_dbg(fmt, arg...) \ | 59 | #define msp3400_dbg(fmt, arg...) \ |
60 | do { \ | 60 | do { \ |
61 | if (debug) \ | 61 | if (debug) \ |
62 | printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \ | 62 | printk(KERN_INFO "%s debug %d-%04x: " fmt, \ |
63 | client->driver->driver.name, \ | ||
63 | i2c_adapter_id(client->adapter), client->addr , ## arg); \ | 64 | i2c_adapter_id(client->adapter), client->addr , ## arg); \ |
64 | } while (0) | 65 | } while (0) |
65 | 66 | ||
@@ -67,7 +68,8 @@ | |||
67 | #define msp3400_dbg_mediumvol(fmt, arg...) \ | 68 | #define msp3400_dbg_mediumvol(fmt, arg...) \ |
68 | do { \ | 69 | do { \ |
69 | if (debug >= 2) \ | 70 | if (debug >= 2) \ |
70 | printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \ | 71 | printk(KERN_INFO "%s debug %d-%04x: " fmt, \ |
72 | client->driver->driver.name, \ | ||
71 | i2c_adapter_id(client->adapter), client->addr , ## arg); \ | 73 | i2c_adapter_id(client->adapter), client->addr , ## arg); \ |
72 | } while (0) | 74 | } while (0) |
73 | 75 | ||
@@ -75,18 +77,19 @@ | |||
75 | #define msp3400_dbg_highvol(fmt, arg...) \ | 77 | #define msp3400_dbg_highvol(fmt, arg...) \ |
76 | do { \ | 78 | do { \ |
77 | if (debug >= 16) \ | 79 | if (debug >= 16) \ |
78 | printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \ | 80 | printk(KERN_INFO "%s debug %d-%04x: " fmt, \ |
81 | client->driver->driver.name, \ | ||
79 | i2c_adapter_id(client->adapter), client->addr , ## arg); \ | 82 | i2c_adapter_id(client->adapter), client->addr , ## arg); \ |
80 | } while (0) | 83 | } while (0) |
81 | 84 | ||
82 | #define msp3400_err(fmt, arg...) do { \ | 85 | #define msp3400_err(fmt, arg...) do { \ |
83 | printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \ | 86 | printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \ |
84 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | 87 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) |
85 | #define msp3400_warn(fmt, arg...) do { \ | 88 | #define msp3400_warn(fmt, arg...) do { \ |
86 | printk(KERN_WARNING "%s %d-%04x: " fmt, client->driver->name, \ | 89 | printk(KERN_WARNING "%s %d-%04x: " fmt, client->driver->driver.name, \ |
87 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | 90 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) |
88 | #define msp3400_info(fmt, arg...) do { \ | 91 | #define msp3400_info(fmt, arg...) do { \ |
89 | printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \ | 92 | printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \ |
90 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | 93 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) |
91 | 94 | ||
92 | #define OPMODE_AUTO -1 | 95 | #define OPMODE_AUTO -1 |
@@ -1561,14 +1564,12 @@ static int msp_resume(struct device * dev); | |||
1561 | static void msp_wake_thread(struct i2c_client *client); | 1564 | static void msp_wake_thread(struct i2c_client *client); |
1562 | 1565 | ||
1563 | static struct i2c_driver driver = { | 1566 | static struct i2c_driver driver = { |
1564 | .owner = THIS_MODULE, | ||
1565 | .name = "msp3400", | ||
1566 | .id = I2C_DRIVERID_MSP3400, | 1567 | .id = I2C_DRIVERID_MSP3400, |
1567 | .flags = I2C_DF_NOTIFY, | ||
1568 | .attach_adapter = msp_probe, | 1568 | .attach_adapter = msp_probe, |
1569 | .detach_client = msp_detach, | 1569 | .detach_client = msp_detach, |
1570 | .command = msp_command, | 1570 | .command = msp_command, |
1571 | .driver = { | 1571 | .driver = { |
1572 | .name = "i2c msp3400 driver", | ||
1572 | .suspend = msp_suspend, | 1573 | .suspend = msp_suspend, |
1573 | .resume = msp_resume, | 1574 | .resume = msp_resume, |
1574 | }, | 1575 | }, |
@@ -1577,7 +1578,6 @@ static struct i2c_driver driver = { | |||
1577 | static struct i2c_client client_template = | 1578 | static struct i2c_client client_template = |
1578 | { | 1579 | { |
1579 | .name = "(unset)", | 1580 | .name = "(unset)", |
1580 | .flags = I2C_CLIENT_ALLOW_USE, | ||
1581 | .driver = &driver, | 1581 | .driver = &driver, |
1582 | }; | 1582 | }; |
1583 | 1583 | ||
diff --git a/drivers/media/video/ovcamchip/ovcamchip_core.c b/drivers/media/video/ovcamchip/ovcamchip_core.c index 2de34ebf0673..428f1bb75ec3 100644 --- a/drivers/media/video/ovcamchip/ovcamchip_core.c +++ b/drivers/media/video/ovcamchip/ovcamchip_core.c | |||
@@ -410,11 +410,11 @@ static int ovcamchip_command(struct i2c_client *c, unsigned int cmd, void *arg) | |||
410 | /* ----------------------------------------------------------------------- */ | 410 | /* ----------------------------------------------------------------------- */ |
411 | 411 | ||
412 | static struct i2c_driver driver = { | 412 | static struct i2c_driver driver = { |
413 | .owner = THIS_MODULE, | 413 | .driver = { |
414 | .name = "ovcamchip", | 414 | .name = "ovcamchip", |
415 | }, | ||
415 | .id = I2C_DRIVERID_OVCAMCHIP, | 416 | .id = I2C_DRIVERID_OVCAMCHIP, |
416 | .class = I2C_CLASS_CAM_DIGITAL, | 417 | .class = I2C_CLASS_CAM_DIGITAL, |
417 | .flags = I2C_DF_NOTIFY, | ||
418 | .attach_adapter = ovcamchip_attach, | 418 | .attach_adapter = ovcamchip_attach, |
419 | .detach_client = ovcamchip_detach, | 419 | .detach_client = ovcamchip_detach, |
420 | .command = ovcamchip_command, | 420 | .command = ovcamchip_command, |
diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c index b8054da31ffd..0aa9e72f632c 100644 --- a/drivers/media/video/saa5246a.c +++ b/drivers/media/video/saa5246a.c | |||
@@ -151,25 +151,18 @@ static int saa5246a_detach(struct i2c_client *client) | |||
151 | return 0; | 151 | return 0; |
152 | } | 152 | } |
153 | 153 | ||
154 | static int saa5246a_command(struct i2c_client *device, unsigned int cmd, | ||
155 | void *arg) | ||
156 | { | ||
157 | return -EINVAL; | ||
158 | } | ||
159 | |||
160 | /* | 154 | /* |
161 | * I2C interfaces | 155 | * I2C interfaces |
162 | */ | 156 | */ |
163 | 157 | ||
164 | static struct i2c_driver i2c_driver_videotext = | 158 | static struct i2c_driver i2c_driver_videotext = |
165 | { | 159 | { |
166 | .owner = THIS_MODULE, | 160 | .driver = { |
167 | .name = IF_NAME, /* name */ | 161 | .name = IF_NAME, /* name */ |
162 | }, | ||
168 | .id = I2C_DRIVERID_SAA5249, /* in i2c.h */ | 163 | .id = I2C_DRIVERID_SAA5249, /* in i2c.h */ |
169 | .flags = I2C_DF_NOTIFY, | ||
170 | .attach_adapter = saa5246a_probe, | 164 | .attach_adapter = saa5246a_probe, |
171 | .detach_client = saa5246a_detach, | 165 | .detach_client = saa5246a_detach, |
172 | .command = saa5246a_command | ||
173 | }; | 166 | }; |
174 | 167 | ||
175 | static struct i2c_client client_template = { | 168 | static struct i2c_client client_template = { |
diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c index 7ffa2e9a9bf3..a51c7bd96618 100644 --- a/drivers/media/video/saa5249.c +++ b/drivers/media/video/saa5249.c | |||
@@ -226,23 +226,16 @@ static int saa5249_detach(struct i2c_client *client) | |||
226 | return 0; | 226 | return 0; |
227 | } | 227 | } |
228 | 228 | ||
229 | static int saa5249_command(struct i2c_client *device, | ||
230 | unsigned int cmd, void *arg) | ||
231 | { | ||
232 | return -EINVAL; | ||
233 | } | ||
234 | |||
235 | /* new I2C driver support */ | 229 | /* new I2C driver support */ |
236 | 230 | ||
237 | static struct i2c_driver i2c_driver_videotext = | 231 | static struct i2c_driver i2c_driver_videotext = |
238 | { | 232 | { |
239 | .owner = THIS_MODULE, | 233 | .driver = { |
240 | .name = IF_NAME, /* name */ | 234 | .name = IF_NAME, /* name */ |
235 | }, | ||
241 | .id = I2C_DRIVERID_SAA5249, /* in i2c.h */ | 236 | .id = I2C_DRIVERID_SAA5249, /* in i2c.h */ |
242 | .flags = I2C_DF_NOTIFY, | ||
243 | .attach_adapter = saa5249_probe, | 237 | .attach_adapter = saa5249_probe, |
244 | .detach_client = saa5249_detach, | 238 | .detach_client = saa5249_detach, |
245 | .command = saa5249_command | ||
246 | }; | 239 | }; |
247 | 240 | ||
248 | static struct i2c_client client_template = { | 241 | static struct i2c_client client_template = { |
diff --git a/drivers/media/video/saa6588.c b/drivers/media/video/saa6588.c index 923322503e8f..d60a783e0473 100644 --- a/drivers/media/video/saa6588.c +++ b/drivers/media/video/saa6588.c | |||
@@ -495,10 +495,10 @@ static int saa6588_command(struct i2c_client *client, unsigned int cmd, | |||
495 | /* ----------------------------------------------------------------------- */ | 495 | /* ----------------------------------------------------------------------- */ |
496 | 496 | ||
497 | static struct i2c_driver driver = { | 497 | static struct i2c_driver driver = { |
498 | .owner = THIS_MODULE, | 498 | .driver = { |
499 | .name = "i2c saa6588 driver", | 499 | .name = "i2c saa6588 driver", |
500 | }, | ||
500 | .id = -1, /* FIXME */ | 501 | .id = -1, /* FIXME */ |
501 | .flags = I2C_DF_NOTIFY, | ||
502 | .attach_adapter = saa6588_probe, | 502 | .attach_adapter = saa6588_probe, |
503 | .detach_client = saa6588_detach, | 503 | .detach_client = saa6588_detach, |
504 | .command = saa6588_command, | 504 | .command = saa6588_command, |
@@ -506,7 +506,6 @@ static struct i2c_driver driver = { | |||
506 | 506 | ||
507 | static struct i2c_client client_template = { | 507 | static struct i2c_client client_template = { |
508 | .name = "saa6588", | 508 | .name = "saa6588", |
509 | .flags = I2C_CLIENT_ALLOW_USE, | ||
510 | .driver = &driver, | 509 | .driver = &driver, |
511 | }; | 510 | }; |
512 | 511 | ||
diff --git a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c index e116bdbed310..619ff0b7a1ff 100644 --- a/drivers/media/video/saa7110.c +++ b/drivers/media/video/saa7110.c | |||
@@ -501,7 +501,6 @@ saa7110_detect_client (struct i2c_adapter *adapter, | |||
501 | client->addr = address; | 501 | client->addr = address; |
502 | client->adapter = adapter; | 502 | client->adapter = adapter; |
503 | client->driver = &i2c_driver_saa7110; | 503 | client->driver = &i2c_driver_saa7110; |
504 | client->flags = I2C_CLIENT_ALLOW_USE; | ||
505 | strlcpy(I2C_NAME(client), "saa7110", sizeof(I2C_NAME(client))); | 504 | strlcpy(I2C_NAME(client), "saa7110", sizeof(I2C_NAME(client))); |
506 | 505 | ||
507 | decoder = kmalloc(sizeof(struct saa7110), GFP_KERNEL); | 506 | decoder = kmalloc(sizeof(struct saa7110), GFP_KERNEL); |
@@ -587,11 +586,11 @@ saa7110_detach_client (struct i2c_client *client) | |||
587 | /* ----------------------------------------------------------------------- */ | 586 | /* ----------------------------------------------------------------------- */ |
588 | 587 | ||
589 | static struct i2c_driver i2c_driver_saa7110 = { | 588 | static struct i2c_driver i2c_driver_saa7110 = { |
590 | .owner = THIS_MODULE, | 589 | .driver = { |
591 | .name = "saa7110", | 590 | .name = "saa7110", |
591 | }, | ||
592 | 592 | ||
593 | .id = I2C_DRIVERID_SAA7110, | 593 | .id = I2C_DRIVERID_SAA7110, |
594 | .flags = I2C_DF_NOTIFY, | ||
595 | 594 | ||
596 | .attach_adapter = saa7110_attach_adapter, | 595 | .attach_adapter = saa7110_attach_adapter, |
597 | .detach_client = saa7110_detach_client, | 596 | .detach_client = saa7110_detach_client, |
diff --git a/drivers/media/video/saa7111.c b/drivers/media/video/saa7111.c index fe8a5e453969..acaeee592b54 100644 --- a/drivers/media/video/saa7111.c +++ b/drivers/media/video/saa7111.c | |||
@@ -518,7 +518,6 @@ saa7111_detect_client (struct i2c_adapter *adapter, | |||
518 | client->addr = address; | 518 | client->addr = address; |
519 | client->adapter = adapter; | 519 | client->adapter = adapter; |
520 | client->driver = &i2c_driver_saa7111; | 520 | client->driver = &i2c_driver_saa7111; |
521 | client->flags = I2C_CLIENT_ALLOW_USE; | ||
522 | strlcpy(I2C_NAME(client), "saa7111", sizeof(I2C_NAME(client))); | 521 | strlcpy(I2C_NAME(client), "saa7111", sizeof(I2C_NAME(client))); |
523 | 522 | ||
524 | decoder = kmalloc(sizeof(struct saa7111), GFP_KERNEL); | 523 | decoder = kmalloc(sizeof(struct saa7111), GFP_KERNEL); |
@@ -590,11 +589,11 @@ saa7111_detach_client (struct i2c_client *client) | |||
590 | /* ----------------------------------------------------------------------- */ | 589 | /* ----------------------------------------------------------------------- */ |
591 | 590 | ||
592 | static struct i2c_driver i2c_driver_saa7111 = { | 591 | static struct i2c_driver i2c_driver_saa7111 = { |
593 | .owner = THIS_MODULE, | 592 | .driver = { |
594 | .name = "saa7111", | 593 | .name = "saa7111", |
594 | }, | ||
595 | 595 | ||
596 | .id = I2C_DRIVERID_SAA7111A, | 596 | .id = I2C_DRIVERID_SAA7111A, |
597 | .flags = I2C_DF_NOTIFY, | ||
598 | 597 | ||
599 | .attach_adapter = saa7111_attach_adapter, | 598 | .attach_adapter = saa7111_attach_adapter, |
600 | .detach_client = saa7111_detach_client, | 599 | .detach_client = saa7111_detach_client, |
diff --git a/drivers/media/video/saa7114.c b/drivers/media/video/saa7114.c index d9f50e2f7b92..b7ac0122f729 100644 --- a/drivers/media/video/saa7114.c +++ b/drivers/media/video/saa7114.c | |||
@@ -859,7 +859,6 @@ saa7114_detect_client (struct i2c_adapter *adapter, | |||
859 | client->addr = address; | 859 | client->addr = address; |
860 | client->adapter = adapter; | 860 | client->adapter = adapter; |
861 | client->driver = &i2c_driver_saa7114; | 861 | client->driver = &i2c_driver_saa7114; |
862 | client->flags = I2C_CLIENT_ALLOW_USE; | ||
863 | strlcpy(I2C_NAME(client), "saa7114", sizeof(I2C_NAME(client))); | 862 | strlcpy(I2C_NAME(client), "saa7114", sizeof(I2C_NAME(client))); |
864 | 863 | ||
865 | decoder = kmalloc(sizeof(struct saa7114), GFP_KERNEL); | 864 | decoder = kmalloc(sizeof(struct saa7114), GFP_KERNEL); |
@@ -1204,11 +1203,11 @@ saa7114_detach_client (struct i2c_client *client) | |||
1204 | /* ----------------------------------------------------------------------- */ | 1203 | /* ----------------------------------------------------------------------- */ |
1205 | 1204 | ||
1206 | static struct i2c_driver i2c_driver_saa7114 = { | 1205 | static struct i2c_driver i2c_driver_saa7114 = { |
1207 | .owner = THIS_MODULE, | 1206 | .driver = { |
1208 | .name = "saa7114", | 1207 | .name = "saa7114", |
1208 | }, | ||
1209 | 1209 | ||
1210 | .id = I2C_DRIVERID_SAA7114, | 1210 | .id = I2C_DRIVERID_SAA7114, |
1211 | .flags = I2C_DF_NOTIFY, | ||
1212 | 1211 | ||
1213 | .attach_adapter = saa7114_attach_adapter, | 1212 | .attach_adapter = saa7114_attach_adapter, |
1214 | .detach_client = saa7114_detach_client, | 1213 | .detach_client = saa7114_detach_client, |
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c index e717e30d8187..29e28c742cd4 100644 --- a/drivers/media/video/saa7115.c +++ b/drivers/media/video/saa7115.c | |||
@@ -52,15 +52,16 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); | |||
52 | #define saa7115_dbg(fmt,arg...) \ | 52 | #define saa7115_dbg(fmt,arg...) \ |
53 | do { \ | 53 | do { \ |
54 | if (debug) \ | 54 | if (debug) \ |
55 | printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \ | 55 | printk(KERN_INFO "%s debug %d-%04x: " fmt, \ |
56 | client->driver->driver.name, \ | ||
56 | i2c_adapter_id(client->adapter), client->addr , ## arg); \ | 57 | i2c_adapter_id(client->adapter), client->addr , ## arg); \ |
57 | } while (0) | 58 | } while (0) |
58 | 59 | ||
59 | #define saa7115_err(fmt, arg...) do { \ | 60 | #define saa7115_err(fmt, arg...) do { \ |
60 | printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \ | 61 | printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \ |
61 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | 62 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) |
62 | #define saa7115_info(fmt, arg...) do { \ | 63 | #define saa7115_info(fmt, arg...) do { \ |
63 | printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \ | 64 | printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \ |
64 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | 65 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) |
65 | 66 | ||
66 | static unsigned short normal_i2c[] = { 0x42 >> 1, 0x40 >> 1, I2C_CLIENT_END }; | 67 | static unsigned short normal_i2c[] = { 0x42 >> 1, 0x40 >> 1, I2C_CLIENT_END }; |
@@ -1270,7 +1271,6 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind) | |||
1270 | client->addr = address; | 1271 | client->addr = address; |
1271 | client->adapter = adapter; | 1272 | client->adapter = adapter; |
1272 | client->driver = &i2c_driver_saa7115; | 1273 | client->driver = &i2c_driver_saa7115; |
1273 | client->flags = I2C_CLIENT_ALLOW_USE; | ||
1274 | snprintf(client->name, sizeof(client->name) - 1, "saa7115"); | 1274 | snprintf(client->name, sizeof(client->name) - 1, "saa7115"); |
1275 | 1275 | ||
1276 | saa7115_dbg("detecting saa7115 client on address 0x%x\n", address << 1); | 1276 | saa7115_dbg("detecting saa7115 client on address 0x%x\n", address << 1); |
@@ -1354,13 +1354,13 @@ static int saa7115_detach(struct i2c_client *client) | |||
1354 | 1354 | ||
1355 | /* i2c implementation */ | 1355 | /* i2c implementation */ |
1356 | static struct i2c_driver i2c_driver_saa7115 = { | 1356 | static struct i2c_driver i2c_driver_saa7115 = { |
1357 | .name = "saa7115", | 1357 | .driver = { |
1358 | .name = "saa7115", | ||
1359 | }, | ||
1358 | .id = I2C_DRIVERID_SAA711X, | 1360 | .id = I2C_DRIVERID_SAA711X, |
1359 | .flags = I2C_DF_NOTIFY, | ||
1360 | .attach_adapter = saa7115_probe, | 1361 | .attach_adapter = saa7115_probe, |
1361 | .detach_client = saa7115_detach, | 1362 | .detach_client = saa7115_detach, |
1362 | .command = saa7115_command, | 1363 | .command = saa7115_command, |
1363 | .owner = THIS_MODULE, | ||
1364 | }; | 1364 | }; |
1365 | 1365 | ||
1366 | 1366 | ||
diff --git a/drivers/media/video/saa711x.c b/drivers/media/video/saa711x.c index 31f7b950b01c..8008537391b5 100644 --- a/drivers/media/video/saa711x.c +++ b/drivers/media/video/saa711x.c | |||
@@ -494,7 +494,6 @@ saa711x_detect_client (struct i2c_adapter *adapter, | |||
494 | client->addr = address; | 494 | client->addr = address; |
495 | client->adapter = adapter; | 495 | client->adapter = adapter; |
496 | client->driver = &i2c_driver_saa711x; | 496 | client->driver = &i2c_driver_saa711x; |
497 | client->flags = I2C_CLIENT_ALLOW_USE; | ||
498 | strlcpy(I2C_NAME(client), "saa711x", sizeof(I2C_NAME(client))); | 497 | strlcpy(I2C_NAME(client), "saa711x", sizeof(I2C_NAME(client))); |
499 | decoder = kmalloc(sizeof(struct saa711x), GFP_KERNEL); | 498 | decoder = kmalloc(sizeof(struct saa711x), GFP_KERNEL); |
500 | if (decoder == NULL) { | 499 | if (decoder == NULL) { |
@@ -565,11 +564,11 @@ saa711x_detach_client (struct i2c_client *client) | |||
565 | /* ----------------------------------------------------------------------- */ | 564 | /* ----------------------------------------------------------------------- */ |
566 | 565 | ||
567 | static struct i2c_driver i2c_driver_saa711x = { | 566 | static struct i2c_driver i2c_driver_saa711x = { |
568 | .owner = THIS_MODULE, | 567 | .driver = { |
569 | .name = "saa711x", | 568 | .name = "saa711x", |
569 | }, | ||
570 | 570 | ||
571 | .id = I2C_DRIVERID_SAA711X, | 571 | .id = I2C_DRIVERID_SAA711X, |
572 | .flags = I2C_DF_NOTIFY, | ||
573 | 572 | ||
574 | .attach_adapter = saa711x_attach_adapter, | 573 | .attach_adapter = saa711x_attach_adapter, |
575 | .detach_client = saa711x_detach_client, | 574 | .detach_client = saa711x_detach_client, |
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c index c36f014f1fdf..bca6ed0e2752 100644 --- a/drivers/media/video/saa7127.c +++ b/drivers/media/video/saa7127.c | |||
@@ -69,7 +69,8 @@ MODULE_PARM_DESC(test_image, "test_image (0-1)"); | |||
69 | #define saa7127_dbg(fmt, arg...) \ | 69 | #define saa7127_dbg(fmt, arg...) \ |
70 | do { \ | 70 | do { \ |
71 | if (debug >= 1) \ | 71 | if (debug >= 1) \ |
72 | printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \ | 72 | printk(KERN_INFO "%s debug %d-%04x: " fmt, \ |
73 | client->driver->driver.name, \ | ||
73 | i2c_adapter_id(client->adapter), client->addr , ## arg); \ | 74 | i2c_adapter_id(client->adapter), client->addr , ## arg); \ |
74 | } while (0) | 75 | } while (0) |
75 | 76 | ||
@@ -77,15 +78,16 @@ MODULE_PARM_DESC(test_image, "test_image (0-1)"); | |||
77 | #define saa7127_dbg_highvol(fmt, arg...) \ | 78 | #define saa7127_dbg_highvol(fmt, arg...) \ |
78 | do { \ | 79 | do { \ |
79 | if (debug == 2) \ | 80 | if (debug == 2) \ |
80 | printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \ | 81 | printk(KERN_INFO "%s debug %d-%04x: " fmt, \ |
82 | client->driver->driver.name, \ | ||
81 | i2c_adapter_id(client->adapter), client->addr , ## arg); \ | 83 | i2c_adapter_id(client->adapter), client->addr , ## arg); \ |
82 | } while (0) | 84 | } while (0) |
83 | 85 | ||
84 | #define saa7127_err(fmt, arg...) do { \ | 86 | #define saa7127_err(fmt, arg...) do { \ |
85 | printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \ | 87 | printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \ |
86 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | 88 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) |
87 | #define saa7127_info(fmt, arg...) do { \ | 89 | #define saa7127_info(fmt, arg...) do { \ |
88 | printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \ | 90 | printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \ |
89 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | 91 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) |
90 | 92 | ||
91 | static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; | 93 | static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; |
@@ -719,7 +721,6 @@ static int saa7127_attach(struct i2c_adapter *adapter, int address, int kind) | |||
719 | client->addr = address; | 721 | client->addr = address; |
720 | client->adapter = adapter; | 722 | client->adapter = adapter; |
721 | client->driver = &i2c_driver_saa7127; | 723 | client->driver = &i2c_driver_saa7127; |
722 | client->flags = I2C_CLIENT_ALLOW_USE; | ||
723 | snprintf(client->name, sizeof(client->name) - 1, "saa7127"); | 724 | snprintf(client->name, sizeof(client->name) - 1, "saa7127"); |
724 | 725 | ||
725 | saa7127_dbg("detecting saa7127 client on address 0x%x\n", address << 1); | 726 | saa7127_dbg("detecting saa7127 client on address 0x%x\n", address << 1); |
@@ -819,13 +820,13 @@ static int saa7127_detach(struct i2c_client *client) | |||
819 | /* ----------------------------------------------------------------------- */ | 820 | /* ----------------------------------------------------------------------- */ |
820 | 821 | ||
821 | static struct i2c_driver i2c_driver_saa7127 = { | 822 | static struct i2c_driver i2c_driver_saa7127 = { |
822 | .name = "saa7127", | 823 | .driver = { |
824 | .name = "saa7127", | ||
825 | }, | ||
823 | .id = I2C_DRIVERID_SAA7127, | 826 | .id = I2C_DRIVERID_SAA7127, |
824 | .flags = I2C_DF_NOTIFY, | ||
825 | .attach_adapter = saa7127_probe, | 827 | .attach_adapter = saa7127_probe, |
826 | .detach_client = saa7127_detach, | 828 | .detach_client = saa7127_detach, |
827 | .command = saa7127_command, | 829 | .command = saa7127_command, |
828 | .owner = THIS_MODULE, | ||
829 | }; | 830 | }; |
830 | 831 | ||
831 | 832 | ||
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c index a61d24f588f7..4615a982ac64 100644 --- a/drivers/media/video/saa7134/saa6752hs.c +++ b/drivers/media/video/saa7134/saa6752hs.c | |||
@@ -597,10 +597,10 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
597 | /* ----------------------------------------------------------------------- */ | 597 | /* ----------------------------------------------------------------------- */ |
598 | 598 | ||
599 | static struct i2c_driver driver = { | 599 | static struct i2c_driver driver = { |
600 | .owner = THIS_MODULE, | 600 | .driver = { |
601 | .name = "i2c saa6752hs MPEG encoder", | 601 | .name = "i2c saa6752hs MPEG encoder", |
602 | }, | ||
602 | .id = I2C_DRIVERID_SAA6752HS, | 603 | .id = I2C_DRIVERID_SAA6752HS, |
603 | .flags = I2C_DF_NOTIFY, | ||
604 | .attach_adapter = saa6752hs_probe, | 604 | .attach_adapter = saa6752hs_probe, |
605 | .detach_client = saa6752hs_detach, | 605 | .detach_client = saa6752hs_detach, |
606 | .command = saa6752hs_command, | 606 | .command = saa6752hs_command, |
@@ -609,7 +609,6 @@ static struct i2c_driver driver = { | |||
609 | static struct i2c_client client_template = | 609 | static struct i2c_client client_template = |
610 | { | 610 | { |
611 | .name = "saa6752hs", | 611 | .name = "saa6752hs", |
612 | .flags = I2C_CLIENT_ALLOW_USE, | ||
613 | .driver = &driver, | 612 | .driver = &driver, |
614 | }; | 613 | }; |
615 | 614 | ||
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c index df9dd36721e0..1792d03d621d 100644 --- a/drivers/media/video/saa7134/saa7134-i2c.c +++ b/drivers/media/video/saa7134/saa7134-i2c.c | |||
@@ -333,7 +333,7 @@ static int attach_inform(struct i2c_client *client) | |||
333 | struct tuner_setup tun_setup; | 333 | struct tuner_setup tun_setup; |
334 | 334 | ||
335 | d1printk( "%s i2c attach [addr=0x%x,client=%s]\n", | 335 | d1printk( "%s i2c attach [addr=0x%x,client=%s]\n", |
336 | client->driver->name, client->addr, client->name); | 336 | client->driver->driver.name, client->addr, client->name); |
337 | 337 | ||
338 | /* Am I an i2c remote control? */ | 338 | /* Am I an i2c remote control? */ |
339 | 339 | ||
@@ -343,7 +343,7 @@ static int attach_inform(struct i2c_client *client) | |||
343 | { | 343 | { |
344 | struct IR_i2c *ir = i2c_get_clientdata(client); | 344 | struct IR_i2c *ir = i2c_get_clientdata(client); |
345 | d1printk("%s i2c IR detected (%s).\n", | 345 | d1printk("%s i2c IR detected (%s).\n", |
346 | client->driver->name,ir->phys); | 346 | client->driver->driver.name, ir->phys); |
347 | saa7134_set_i2c_ir(dev,ir); | 347 | saa7134_set_i2c_ir(dev,ir); |
348 | break; | 348 | break; |
349 | } | 349 | } |
diff --git a/drivers/media/video/saa7185.c b/drivers/media/video/saa7185.c index 132aa7943c16..f72a9f796209 100644 --- a/drivers/media/video/saa7185.c +++ b/drivers/media/video/saa7185.c | |||
@@ -415,7 +415,6 @@ saa7185_detect_client (struct i2c_adapter *adapter, | |||
415 | client->addr = address; | 415 | client->addr = address; |
416 | client->adapter = adapter; | 416 | client->adapter = adapter; |
417 | client->driver = &i2c_driver_saa7185; | 417 | client->driver = &i2c_driver_saa7185; |
418 | client->flags = I2C_CLIENT_ALLOW_USE; | ||
419 | strlcpy(I2C_NAME(client), "saa7185", sizeof(I2C_NAME(client))); | 418 | strlcpy(I2C_NAME(client), "saa7185", sizeof(I2C_NAME(client))); |
420 | 419 | ||
421 | encoder = kmalloc(sizeof(struct saa7185), GFP_KERNEL); | 420 | encoder = kmalloc(sizeof(struct saa7185), GFP_KERNEL); |
@@ -487,11 +486,11 @@ saa7185_detach_client (struct i2c_client *client) | |||
487 | /* ----------------------------------------------------------------------- */ | 486 | /* ----------------------------------------------------------------------- */ |
488 | 487 | ||
489 | static struct i2c_driver i2c_driver_saa7185 = { | 488 | static struct i2c_driver i2c_driver_saa7185 = { |
490 | .owner = THIS_MODULE, | 489 | .driver = { |
491 | .name = "saa7185", /* name */ | 490 | .name = "saa7185", /* name */ |
491 | }, | ||
492 | 492 | ||
493 | .id = I2C_DRIVERID_SAA7185B, | 493 | .id = I2C_DRIVERID_SAA7185B, |
494 | .flags = I2C_DF_NOTIFY, | ||
495 | 494 | ||
496 | .attach_adapter = saa7185_attach_adapter, | 495 | .attach_adapter = saa7185_attach_adapter, |
497 | .detach_client = saa7185_detach_client, | 496 | .detach_client = saa7185_detach_client, |
diff --git a/drivers/media/video/saa7191.c b/drivers/media/video/saa7191.c index cbca896e8cfa..41f6f05a0436 100644 --- a/drivers/media/video/saa7191.c +++ b/drivers/media/video/saa7191.c | |||
@@ -788,10 +788,10 @@ static int saa7191_command(struct i2c_client *client, unsigned int cmd, | |||
788 | } | 788 | } |
789 | 789 | ||
790 | static struct i2c_driver i2c_driver_saa7191 = { | 790 | static struct i2c_driver i2c_driver_saa7191 = { |
791 | .owner = THIS_MODULE, | 791 | .driver = { |
792 | .name = "saa7191", | 792 | .name = "saa7191", |
793 | }, | ||
793 | .id = I2C_DRIVERID_SAA7191, | 794 | .id = I2C_DRIVERID_SAA7191, |
794 | .flags = I2C_DF_NOTIFY, | ||
795 | .attach_adapter = saa7191_probe, | 795 | .attach_adapter = saa7191_probe, |
796 | .detach_client = saa7191_detach, | 796 | .detach_client = saa7191_detach, |
797 | .command = saa7191_command | 797 | .command = saa7191_command |
diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c index d32737dd2142..549c9929f107 100644 --- a/drivers/media/video/tda7432.c +++ b/drivers/media/video/tda7432.c | |||
@@ -501,10 +501,10 @@ static int tda7432_command(struct i2c_client *client, | |||
501 | } | 501 | } |
502 | 502 | ||
503 | static struct i2c_driver driver = { | 503 | static struct i2c_driver driver = { |
504 | .owner = THIS_MODULE, | 504 | .driver = { |
505 | .name = "i2c tda7432 driver", | 505 | .name = "i2c tda7432 driver", |
506 | }, | ||
506 | .id = I2C_DRIVERID_TDA7432, | 507 | .id = I2C_DRIVERID_TDA7432, |
507 | .flags = I2C_DF_NOTIFY, | ||
508 | .attach_adapter = tda7432_probe, | 508 | .attach_adapter = tda7432_probe, |
509 | .detach_client = tda7432_detach, | 509 | .detach_client = tda7432_detach, |
510 | .command = tda7432_command, | 510 | .command = tda7432_command, |
diff --git a/drivers/media/video/tda9840.c b/drivers/media/video/tda9840.c index 1794686612c6..ed4c04119ccc 100644 --- a/drivers/media/video/tda9840.c +++ b/drivers/media/video/tda9840.c | |||
@@ -34,7 +34,7 @@ static int debug = 0; /* insmod parameter */ | |||
34 | module_param(debug, int, 0644); | 34 | module_param(debug, int, 0644); |
35 | MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); | 35 | MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); |
36 | #define dprintk(args...) \ | 36 | #define dprintk(args...) \ |
37 | do { if (debug) { printk("%s: %s()[%d]: ",__stringify(KBUILD_MODNAME), __FUNCTION__, __LINE__); printk(args); } } while (0) | 37 | do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __FUNCTION__, __LINE__); printk(args); } } while (0) |
38 | 38 | ||
39 | #define SWITCH 0x00 | 39 | #define SWITCH 0x00 |
40 | #define LEVEL_ADJUST 0x02 | 40 | #define LEVEL_ADJUST 0x02 |
@@ -221,10 +221,10 @@ static int detach(struct i2c_client *client) | |||
221 | } | 221 | } |
222 | 222 | ||
223 | static struct i2c_driver driver = { | 223 | static struct i2c_driver driver = { |
224 | .owner = THIS_MODULE, | 224 | .driver = { |
225 | .name = "tda9840", | 225 | .name = "tda9840", |
226 | }, | ||
226 | .id = I2C_DRIVERID_TDA9840, | 227 | .id = I2C_DRIVERID_TDA9840, |
227 | .flags = I2C_DF_NOTIFY, | ||
228 | .attach_adapter = attach, | 228 | .attach_adapter = attach, |
229 | .detach_client = detach, | 229 | .detach_client = detach, |
230 | .command = command, | 230 | .command = command, |
diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c index a5e37dc91f39..9c3ecf7a0fed 100644 --- a/drivers/media/video/tda9875.c +++ b/drivers/media/video/tda9875.c | |||
@@ -372,10 +372,10 @@ static int tda9875_command(struct i2c_client *client, | |||
372 | 372 | ||
373 | 373 | ||
374 | static struct i2c_driver driver = { | 374 | static struct i2c_driver driver = { |
375 | .owner = THIS_MODULE, | 375 | .driver = { |
376 | .name = "i2c tda9875 driver", | 376 | .name = "i2c tda9875 driver", |
377 | }, | ||
377 | .id = I2C_DRIVERID_TDA9875, | 378 | .id = I2C_DRIVERID_TDA9875, |
378 | .flags = I2C_DF_NOTIFY, | ||
379 | .attach_adapter = tda9875_probe, | 379 | .attach_adapter = tda9875_probe, |
380 | .detach_client = tda9875_detach, | 380 | .detach_client = tda9875_detach, |
381 | .command = tda9875_command, | 381 | .command = tda9875_command, |
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c index 2f2414e90e8b..7165a1b9625a 100644 --- a/drivers/media/video/tda9887.c +++ b/drivers/media/video/tda9887.c | |||
@@ -819,14 +819,12 @@ static int tda9887_resume(struct device * dev) | |||
819 | /* ----------------------------------------------------------------------- */ | 819 | /* ----------------------------------------------------------------------- */ |
820 | 820 | ||
821 | static struct i2c_driver driver = { | 821 | static struct i2c_driver driver = { |
822 | .owner = THIS_MODULE, | ||
823 | .name = "i2c tda9887 driver", | ||
824 | .id = -1, /* FIXME */ | 822 | .id = -1, /* FIXME */ |
825 | .flags = I2C_DF_NOTIFY, | ||
826 | .attach_adapter = tda9887_probe, | 823 | .attach_adapter = tda9887_probe, |
827 | .detach_client = tda9887_detach, | 824 | .detach_client = tda9887_detach, |
828 | .command = tda9887_command, | 825 | .command = tda9887_command, |
829 | .driver = { | 826 | .driver = { |
827 | .name = "i2c tda9887 driver", | ||
830 | .suspend = tda9887_suspend, | 828 | .suspend = tda9887_suspend, |
831 | .resume = tda9887_resume, | 829 | .resume = tda9887_resume, |
832 | }, | 830 | }, |
@@ -834,7 +832,6 @@ static struct i2c_driver driver = { | |||
834 | static struct i2c_client client_template = | 832 | static struct i2c_client client_template = |
835 | { | 833 | { |
836 | .name = "tda9887", | 834 | .name = "tda9887", |
837 | .flags = I2C_CLIENT_ALLOW_USE, | ||
838 | .driver = &driver, | 835 | .driver = &driver, |
839 | }; | 836 | }; |
840 | 837 | ||
diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c index ee3688348b66..bb35844e3842 100644 --- a/drivers/media/video/tea6415c.c +++ b/drivers/media/video/tea6415c.c | |||
@@ -36,7 +36,7 @@ static int debug = 0; /* insmod parameter */ | |||
36 | module_param(debug, int, 0644); | 36 | module_param(debug, int, 0644); |
37 | MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); | 37 | MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); |
38 | #define dprintk(args...) \ | 38 | #define dprintk(args...) \ |
39 | do { if (debug) { printk("%s: %s()[%d]: ",__stringify(KBUILD_MODNAME), __FUNCTION__, __LINE__); printk(args); } } while (0) | 39 | do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __FUNCTION__, __LINE__); printk(args); } } while (0) |
40 | 40 | ||
41 | #define TEA6415C_NUM_INPUTS 8 | 41 | #define TEA6415C_NUM_INPUTS 8 |
42 | #define TEA6415C_NUM_OUTPUTS 6 | 42 | #define TEA6415C_NUM_OUTPUTS 6 |
@@ -190,10 +190,10 @@ static int command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
190 | } | 190 | } |
191 | 191 | ||
192 | static struct i2c_driver driver = { | 192 | static struct i2c_driver driver = { |
193 | .owner = THIS_MODULE, | 193 | .driver = { |
194 | .name = "tea6415c", | 194 | .name = "tea6415c", |
195 | }, | ||
195 | .id = I2C_DRIVERID_TEA6415C, | 196 | .id = I2C_DRIVERID_TEA6415C, |
196 | .flags = I2C_DF_NOTIFY, | ||
197 | .attach_adapter = attach, | 197 | .attach_adapter = attach, |
198 | .detach_client = detach, | 198 | .detach_client = detach, |
199 | .command = command, | 199 | .command = command, |
diff --git a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c index 17975c19da5e..c4ba3742f5c7 100644 --- a/drivers/media/video/tea6420.c +++ b/drivers/media/video/tea6420.c | |||
@@ -36,7 +36,7 @@ static int debug = 0; /* insmod parameter */ | |||
36 | module_param(debug, int, 0644); | 36 | module_param(debug, int, 0644); |
37 | MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); | 37 | MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); |
38 | #define dprintk(args...) \ | 38 | #define dprintk(args...) \ |
39 | do { if (debug) { printk("%s: %s()[%d]: ",__stringify(KBUILD_MODNAME), __FUNCTION__, __LINE__); printk(args); } } while (0) | 39 | do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __FUNCTION__, __LINE__); printk(args); } } while (0) |
40 | 40 | ||
41 | /* addresses to scan, found only at 0x4c and/or 0x4d (7-Bit) */ | 41 | /* addresses to scan, found only at 0x4c and/or 0x4d (7-Bit) */ |
42 | static unsigned short normal_i2c[] = { I2C_TEA6420_1, I2C_TEA6420_2, I2C_CLIENT_END }; | 42 | static unsigned short normal_i2c[] = { I2C_TEA6420_1, I2C_TEA6420_2, I2C_CLIENT_END }; |
@@ -167,10 +167,10 @@ static int command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
167 | } | 167 | } |
168 | 168 | ||
169 | static struct i2c_driver driver = { | 169 | static struct i2c_driver driver = { |
170 | .owner = THIS_MODULE, | 170 | .driver = { |
171 | .name = "tea6420", | 171 | .name = "tea6420", |
172 | }, | ||
172 | .id = I2C_DRIVERID_TEA6420, | 173 | .id = I2C_DRIVERID_TEA6420, |
173 | .flags = I2C_DF_NOTIFY, | ||
174 | .attach_adapter = attach, | 174 | .attach_adapter = attach, |
175 | .detach_client = detach, | 175 | .detach_client = detach, |
176 | .command = command, | 176 | .command = command, |
diff --git a/drivers/media/video/tuner-3036.c b/drivers/media/video/tuner-3036.c index 79203595b9c1..d97f66804c37 100644 --- a/drivers/media/video/tuner-3036.c +++ b/drivers/media/video/tuner-3036.c | |||
@@ -175,10 +175,10 @@ tuner_probe(struct i2c_adapter *adap) | |||
175 | static struct i2c_driver | 175 | static struct i2c_driver |
176 | i2c_driver_tuner = | 176 | i2c_driver_tuner = |
177 | { | 177 | { |
178 | .owner = THIS_MODULE, | 178 | .driver = { |
179 | .name = "sab3036", | 179 | .name = "sab3036", |
180 | }, | ||
180 | .id = I2C_DRIVERID_SAB3036, | 181 | .id = I2C_DRIVERID_SAB3036, |
181 | .flags = I2C_DF_NOTIFY, | ||
182 | .attach_adapter = tuner_probe, | 182 | .attach_adapter = tuner_probe, |
183 | .detach_client = tuner_detach, | 183 | .detach_client = tuner_detach, |
184 | .command = tuner_command | 184 | .command = tuner_command |
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index e58abdfcaab8..c13c7b95ef35 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c | |||
@@ -206,7 +206,7 @@ static void set_type(struct i2c_client *c, unsigned int type, | |||
206 | 206 | ||
207 | set_freq(c, t->freq); | 207 | set_freq(c, t->freq); |
208 | tuner_dbg("%s %s I2C addr 0x%02x with type %d used for 0x%02x\n", | 208 | tuner_dbg("%s %s I2C addr 0x%02x with type %d used for 0x%02x\n", |
209 | c->adapter->name, c->driver->name, c->addr << 1, type, | 209 | c->adapter->name, c->driver->driver.name, c->addr << 1, type, |
210 | t->mode_mask); | 210 | t->mode_mask); |
211 | } | 211 | } |
212 | 212 | ||
@@ -742,21 +742,18 @@ static int tuner_resume(struct device *dev) | |||
742 | /* ----------------------------------------------------------------------- */ | 742 | /* ----------------------------------------------------------------------- */ |
743 | 743 | ||
744 | static struct i2c_driver driver = { | 744 | static struct i2c_driver driver = { |
745 | .owner = THIS_MODULE, | ||
746 | .name = "tuner", | ||
747 | .id = I2C_DRIVERID_TUNER, | 745 | .id = I2C_DRIVERID_TUNER, |
748 | .flags = I2C_DF_NOTIFY, | ||
749 | .attach_adapter = tuner_probe, | 746 | .attach_adapter = tuner_probe, |
750 | .detach_client = tuner_detach, | 747 | .detach_client = tuner_detach, |
751 | .command = tuner_command, | 748 | .command = tuner_command, |
752 | .driver = { | 749 | .driver = { |
750 | .name = "tuner", | ||
753 | .suspend = tuner_suspend, | 751 | .suspend = tuner_suspend, |
754 | .resume = tuner_resume, | 752 | .resume = tuner_resume, |
755 | }, | 753 | }, |
756 | }; | 754 | }; |
757 | static struct i2c_client client_template = { | 755 | static struct i2c_client client_template = { |
758 | .name = "(tuner unset)", | 756 | .name = "(tuner unset)", |
759 | .flags = I2C_CLIENT_ALLOW_USE, | ||
760 | .driver = &driver, | 757 | .driver = &driver, |
761 | }; | 758 | }; |
762 | 759 | ||
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c index 5b20e8177cad..0292c5abf14a 100644 --- a/drivers/media/video/tvaudio.c +++ b/drivers/media/video/tvaudio.c | |||
@@ -1702,10 +1702,10 @@ static int chip_command(struct i2c_client *client, | |||
1702 | 1702 | ||
1703 | 1703 | ||
1704 | static struct i2c_driver driver = { | 1704 | static struct i2c_driver driver = { |
1705 | .owner = THIS_MODULE, | 1705 | .driver = { |
1706 | .name = "generic i2c audio driver", | 1706 | .name = "generic i2c audio driver", |
1707 | }, | ||
1707 | .id = I2C_DRIVERID_TVAUDIO, | 1708 | .id = I2C_DRIVERID_TVAUDIO, |
1708 | .flags = I2C_DF_NOTIFY, | ||
1709 | .attach_adapter = chip_probe, | 1709 | .attach_adapter = chip_probe, |
1710 | .detach_client = chip_detach, | 1710 | .detach_client = chip_detach, |
1711 | .command = chip_command, | 1711 | .command = chip_command, |
@@ -1714,7 +1714,6 @@ static struct i2c_driver driver = { | |||
1714 | static struct i2c_client client_template = | 1714 | static struct i2c_client client_template = |
1715 | { | 1715 | { |
1716 | .name = "(unset)", | 1716 | .name = "(unset)", |
1717 | .flags = I2C_CLIENT_ALLOW_USE, | ||
1718 | .driver = &driver, | 1717 | .driver = &driver, |
1719 | }; | 1718 | }; |
1720 | 1719 | ||
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c index 5ac235365dd8..8ac4cb82a459 100644 --- a/drivers/media/video/tveeprom.c +++ b/drivers/media/video/tveeprom.c | |||
@@ -751,7 +751,6 @@ tveeprom_detect_client(struct i2c_adapter *adapter, | |||
751 | client->addr = address; | 751 | client->addr = address; |
752 | client->adapter = adapter; | 752 | client->adapter = adapter; |
753 | client->driver = &i2c_driver_tveeprom; | 753 | client->driver = &i2c_driver_tveeprom; |
754 | client->flags = I2C_CLIENT_ALLOW_USE; | ||
755 | snprintf(client->name, sizeof(client->name), "tveeprom"); | 754 | snprintf(client->name, sizeof(client->name), "tveeprom"); |
756 | i2c_attach_client(client); | 755 | i2c_attach_client(client); |
757 | 756 | ||
@@ -779,10 +778,10 @@ tveeprom_detach_client (struct i2c_client *client) | |||
779 | } | 778 | } |
780 | 779 | ||
781 | static struct i2c_driver i2c_driver_tveeprom = { | 780 | static struct i2c_driver i2c_driver_tveeprom = { |
782 | .owner = THIS_MODULE, | 781 | .driver = { |
783 | .name = "tveeprom", | 782 | .name = "tveeprom", |
783 | }, | ||
784 | .id = I2C_DRIVERID_TVEEPROM, | 784 | .id = I2C_DRIVERID_TVEEPROM, |
785 | .flags = I2C_DF_NOTIFY, | ||
786 | .attach_adapter = tveeprom_attach_adapter, | 785 | .attach_adapter = tveeprom_attach_adapter, |
787 | .detach_client = tveeprom_detach_client, | 786 | .detach_client = tveeprom_detach_client, |
788 | .command = tveeprom_command, | 787 | .command = tveeprom_command, |
diff --git a/drivers/media/video/tvmixer.c b/drivers/media/video/tvmixer.c index 8318bd1aad00..e837f9f7fed6 100644 --- a/drivers/media/video/tvmixer.c +++ b/drivers/media/video/tvmixer.c | |||
@@ -228,16 +228,14 @@ static int tvmixer_release(struct inode *inode, struct file *file) | |||
228 | 228 | ||
229 | static struct i2c_driver driver = { | 229 | static struct i2c_driver driver = { |
230 | #ifdef I2C_PEC | 230 | #ifdef I2C_PEC |
231 | .owner = THIS_MODULE, | 231 | .driver = { |
232 | #endif | 232 | .name = "tv card mixer driver", |
233 | }, | ||
234 | #else | ||
233 | .name = "tv card mixer driver", | 235 | .name = "tv card mixer driver", |
236 | #endif | ||
234 | .id = I2C_DRIVERID_TVMIXER, | 237 | .id = I2C_DRIVERID_TVMIXER, |
235 | #ifdef I2C_DF_DUMMY | ||
236 | .flags = I2C_DF_DUMMY, | ||
237 | #else | ||
238 | .flags = I2C_DF_NOTIFY, | ||
239 | .detach_adapter = tvmixer_adapters, | 238 | .detach_adapter = tvmixer_adapters, |
240 | #endif | ||
241 | .attach_adapter = tvmixer_adapters, | 239 | .attach_adapter = tvmixer_adapters, |
242 | .detach_client = tvmixer_clients, | 240 | .detach_client = tvmixer_clients, |
243 | }; | 241 | }; |
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c index 97431e26d229..a60442ea4f94 100644 --- a/drivers/media/video/tvp5150.c +++ b/drivers/media/video/tvp5150.c | |||
@@ -714,7 +714,6 @@ static struct i2c_driver driver; | |||
714 | 714 | ||
715 | static struct i2c_client client_template = { | 715 | static struct i2c_client client_template = { |
716 | .name = "(unset)", | 716 | .name = "(unset)", |
717 | .flags = I2C_CLIENT_ALLOW_USE, | ||
718 | .driver = &driver, | 717 | .driver = &driver, |
719 | }; | 718 | }; |
720 | 719 | ||
@@ -801,12 +800,12 @@ static int tvp5150_detach_client(struct i2c_client *client) | |||
801 | /* ----------------------------------------------------------------------- */ | 800 | /* ----------------------------------------------------------------------- */ |
802 | 801 | ||
803 | static struct i2c_driver driver = { | 802 | static struct i2c_driver driver = { |
804 | .owner = THIS_MODULE, | 803 | .driver = { |
805 | .name = "tvp5150", | 804 | .name = "tvp5150", |
805 | }, | ||
806 | 806 | ||
807 | /* FIXME */ | 807 | /* FIXME */ |
808 | .id = I2C_DRIVERID_SAA7110, | 808 | .id = I2C_DRIVERID_SAA7110, |
809 | .flags = I2C_DF_NOTIFY, | ||
810 | 809 | ||
811 | .attach_adapter = tvp5150_attach_adapter, | 810 | .attach_adapter = tvp5150_attach_adapter, |
812 | .detach_client = tvp5150_detach_client, | 811 | .detach_client = tvp5150_detach_client, |
diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c index 137b58f2c666..8dcee8b60e21 100644 --- a/drivers/media/video/vpx3220.c +++ b/drivers/media/video/vpx3220.c | |||
@@ -631,7 +631,6 @@ vpx3220_detect_client (struct i2c_adapter *adapter, | |||
631 | client->addr = address; | 631 | client->addr = address; |
632 | client->adapter = adapter; | 632 | client->adapter = adapter; |
633 | client->driver = &vpx3220_i2c_driver; | 633 | client->driver = &vpx3220_i2c_driver; |
634 | client->flags = I2C_CLIENT_ALLOW_USE; | ||
635 | 634 | ||
636 | /* Check for manufacture ID and part number */ | 635 | /* Check for manufacture ID and part number */ |
637 | if (kind < 0) { | 636 | if (kind < 0) { |
@@ -722,11 +721,11 @@ vpx3220_attach_adapter (struct i2c_adapter *adapter) | |||
722 | */ | 721 | */ |
723 | 722 | ||
724 | static struct i2c_driver vpx3220_i2c_driver = { | 723 | static struct i2c_driver vpx3220_i2c_driver = { |
725 | .owner = THIS_MODULE, | 724 | .driver = { |
726 | .name = "vpx3220", | 725 | .name = "vpx3220", |
726 | }, | ||
727 | 727 | ||
728 | .id = I2C_DRIVERID_VPX3220, | 728 | .id = I2C_DRIVERID_VPX3220, |
729 | .flags = I2C_DF_NOTIFY, | ||
730 | 729 | ||
731 | .attach_adapter = vpx3220_attach_adapter, | 730 | .attach_adapter = vpx3220_attach_adapter, |
732 | .detach_client = vpx3220_detach_client, | 731 | .detach_client = vpx3220_detach_client, |
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c index a6936ad74fcf..bbfd55cd9948 100644 --- a/drivers/media/video/wm8775.c +++ b/drivers/media/video/wm8775.c | |||
@@ -40,10 +40,10 @@ MODULE_AUTHOR("Ulf Eklund, Hans Verkuil"); | |||
40 | MODULE_LICENSE("GPL"); | 40 | MODULE_LICENSE("GPL"); |
41 | 41 | ||
42 | #define wm8775_err(fmt, arg...) do { \ | 42 | #define wm8775_err(fmt, arg...) do { \ |
43 | printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \ | 43 | printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \ |
44 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | 44 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) |
45 | #define wm8775_info(fmt, arg...) do { \ | 45 | #define wm8775_info(fmt, arg...) do { \ |
46 | printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \ | 46 | printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \ |
47 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | 47 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) |
48 | 48 | ||
49 | 49 | ||
@@ -168,7 +168,6 @@ static int wm8775_attach(struct i2c_adapter *adapter, int address, int kind) | |||
168 | client->addr = address; | 168 | client->addr = address; |
169 | client->adapter = adapter; | 169 | client->adapter = adapter; |
170 | client->driver = &i2c_driver; | 170 | client->driver = &i2c_driver; |
171 | client->flags = I2C_CLIENT_ALLOW_USE; | ||
172 | snprintf(client->name, sizeof(client->name) - 1, "wm8775"); | 171 | snprintf(client->name, sizeof(client->name) - 1, "wm8775"); |
173 | 172 | ||
174 | wm8775_info("chip found @ 0x%x (%s)\n", address << 1, adapter->name); | 173 | wm8775_info("chip found @ 0x%x (%s)\n", address << 1, adapter->name); |
@@ -233,15 +232,15 @@ static int wm8775_detach(struct i2c_client *client) | |||
233 | 232 | ||
234 | /* i2c implementation */ | 233 | /* i2c implementation */ |
235 | static struct i2c_driver i2c_driver = { | 234 | static struct i2c_driver i2c_driver = { |
236 | .name = "wm8775", | 235 | .driver = { |
236 | .name = "wm8775", | ||
237 | }, | ||
237 | 238 | ||
238 | .id = I2C_DRIVERID_WM8775, | 239 | .id = I2C_DRIVERID_WM8775, |
239 | .flags = I2C_DF_NOTIFY, | ||
240 | 240 | ||
241 | .attach_adapter = wm8775_probe, | 241 | .attach_adapter = wm8775_probe, |
242 | .detach_client = wm8775_detach, | 242 | .detach_client = wm8775_detach, |
243 | .command = wm8775_command, | 243 | .command = wm8775_command, |
244 | .owner = THIS_MODULE, | ||
245 | }; | 244 | }; |
246 | 245 | ||
247 | 246 | ||
diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c index 07bde9acd672..4034f1b45366 100644 --- a/drivers/media/video/zoran_driver.c +++ b/drivers/media/video/zoran_driver.c | |||
@@ -1311,7 +1311,7 @@ zoran_open (struct inode *inode, | |||
1311 | res = -ENODEV; | 1311 | res = -ENODEV; |
1312 | goto open_unlock_and_return; | 1312 | goto open_unlock_and_return; |
1313 | } | 1313 | } |
1314 | if (!try_module_get(zr->decoder->driver->owner)) { | 1314 | if (!try_module_get(zr->decoder->driver->driver.owner)) { |
1315 | dprintk(1, | 1315 | dprintk(1, |
1316 | KERN_ERR | 1316 | KERN_ERR |
1317 | "%s: failed to grab ownership of i2c decoder\n", | 1317 | "%s: failed to grab ownership of i2c decoder\n", |
@@ -1321,13 +1321,13 @@ zoran_open (struct inode *inode, | |||
1321 | goto open_unlock_and_return; | 1321 | goto open_unlock_and_return; |
1322 | } | 1322 | } |
1323 | if (zr->encoder && | 1323 | if (zr->encoder && |
1324 | !try_module_get(zr->encoder->driver->owner)) { | 1324 | !try_module_get(zr->encoder->driver->driver.owner)) { |
1325 | dprintk(1, | 1325 | dprintk(1, |
1326 | KERN_ERR | 1326 | KERN_ERR |
1327 | "%s: failed to grab ownership of i2c encoder\n", | 1327 | "%s: failed to grab ownership of i2c encoder\n", |
1328 | ZR_DEVNAME(zr)); | 1328 | ZR_DEVNAME(zr)); |
1329 | res = -EIO; | 1329 | res = -EIO; |
1330 | module_put(zr->decoder->driver->owner); | 1330 | module_put(zr->decoder->driver->driver.owner); |
1331 | module_put(THIS_MODULE); | 1331 | module_put(THIS_MODULE); |
1332 | goto open_unlock_and_return; | 1332 | goto open_unlock_and_return; |
1333 | } | 1333 | } |
@@ -1393,9 +1393,9 @@ zoran_open (struct inode *inode, | |||
1393 | open_unlock_and_return: | 1393 | open_unlock_and_return: |
1394 | /* if we grabbed locks, release them accordingly */ | 1394 | /* if we grabbed locks, release them accordingly */ |
1395 | if (have_module_locks) { | 1395 | if (have_module_locks) { |
1396 | module_put(zr->decoder->driver->owner); | 1396 | module_put(zr->decoder->driver->driver.owner); |
1397 | if (zr->encoder) { | 1397 | if (zr->encoder) { |
1398 | module_put(zr->encoder->driver->owner); | 1398 | module_put(zr->encoder->driver->driver.owner); |
1399 | } | 1399 | } |
1400 | module_put(THIS_MODULE); | 1400 | module_put(THIS_MODULE); |
1401 | } | 1401 | } |
@@ -1461,9 +1461,9 @@ zoran_close (struct inode *inode, | |||
1461 | kfree(fh); | 1461 | kfree(fh); |
1462 | 1462 | ||
1463 | /* release locks on the i2c modules */ | 1463 | /* release locks on the i2c modules */ |
1464 | module_put(zr->decoder->driver->owner); | 1464 | module_put(zr->decoder->driver->driver.owner); |
1465 | if (zr->encoder) { | 1465 | if (zr->encoder) { |
1466 | module_put(zr->encoder->driver->owner); | 1466 | module_put(zr->encoder->driver->driver.owner); |
1467 | } | 1467 | } |
1468 | module_put(THIS_MODULE); | 1468 | module_put(THIS_MODULE); |
1469 | 1469 | ||
diff --git a/drivers/usb/media/w9968cf.c b/drivers/usb/media/w9968cf.c index 04d69339c054..3605a6f3067b 100644 --- a/drivers/usb/media/w9968cf.c +++ b/drivers/usb/media/w9968cf.c | |||
@@ -1533,12 +1533,12 @@ static int w9968cf_i2c_attach_inform(struct i2c_client* client) | |||
1533 | } | 1533 | } |
1534 | } else { | 1534 | } else { |
1535 | DBG(4, "Rejected client [%s] with driver [%s]", | 1535 | DBG(4, "Rejected client [%s] with driver [%s]", |
1536 | client->name, client->driver->name) | 1536 | client->name, client->driver->driver.name) |
1537 | return -EINVAL; | 1537 | return -EINVAL; |
1538 | } | 1538 | } |
1539 | 1539 | ||
1540 | DBG(5, "I2C attach client [%s] with driver [%s]", | 1540 | DBG(5, "I2C attach client [%s] with driver [%s]", |
1541 | client->name, client->driver->name) | 1541 | client->name, client->driver->driver.name) |
1542 | 1542 | ||
1543 | return 0; | 1543 | return 0; |
1544 | } | 1544 | } |
diff --git a/drivers/video/matrox/matroxfb_maven.c b/drivers/video/matrox/matroxfb_maven.c index ad60bbb16cdf..a1f2c5e8fc88 100644 --- a/drivers/video/matrox/matroxfb_maven.c +++ b/drivers/video/matrox/matroxfb_maven.c | |||
@@ -1288,18 +1288,13 @@ static int maven_detach_client(struct i2c_client* client) { | |||
1288 | return 0; | 1288 | return 0; |
1289 | } | 1289 | } |
1290 | 1290 | ||
1291 | static int maven_command(struct i2c_client* client, unsigned int cmd, void* arg) { | ||
1292 | return -ENOIOCTLCMD; /* or -EINVAL, depends on who will call this */ | ||
1293 | } | ||
1294 | |||
1295 | static struct i2c_driver maven_driver={ | 1291 | static struct i2c_driver maven_driver={ |
1296 | .owner = THIS_MODULE, | 1292 | .driver = { |
1297 | .name = "maven", | 1293 | .name = "maven", |
1294 | }, | ||
1298 | .id = I2C_DRIVERID_MGATVO, | 1295 | .id = I2C_DRIVERID_MGATVO, |
1299 | .flags = I2C_DF_NOTIFY, | ||
1300 | .attach_adapter = maven_attach_adapter, | 1296 | .attach_adapter = maven_attach_adapter, |
1301 | .detach_client = maven_detach_client, | 1297 | .detach_client = maven_detach_client, |
1302 | .command = maven_command, | ||
1303 | }; | 1298 | }; |
1304 | 1299 | ||
1305 | /* ************************** */ | 1300 | /* ************************** */ |
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c index c5a33648e9fd..145524039577 100644 --- a/fs/lockd/clntproc.c +++ b/fs/lockd/clntproc.c | |||
@@ -26,11 +26,12 @@ | |||
26 | static int nlmclnt_test(struct nlm_rqst *, struct file_lock *); | 26 | static int nlmclnt_test(struct nlm_rqst *, struct file_lock *); |
27 | static int nlmclnt_lock(struct nlm_rqst *, struct file_lock *); | 27 | static int nlmclnt_lock(struct nlm_rqst *, struct file_lock *); |
28 | static int nlmclnt_unlock(struct nlm_rqst *, struct file_lock *); | 28 | static int nlmclnt_unlock(struct nlm_rqst *, struct file_lock *); |
29 | static void nlmclnt_unlock_callback(struct rpc_task *); | ||
30 | static void nlmclnt_cancel_callback(struct rpc_task *); | ||
31 | static int nlm_stat_to_errno(u32 stat); | 29 | static int nlm_stat_to_errno(u32 stat); |
32 | static void nlmclnt_locks_init_private(struct file_lock *fl, struct nlm_host *host); | 30 | static void nlmclnt_locks_init_private(struct file_lock *fl, struct nlm_host *host); |
33 | 31 | ||
32 | static const struct rpc_call_ops nlmclnt_unlock_ops; | ||
33 | static const struct rpc_call_ops nlmclnt_cancel_ops; | ||
34 | |||
34 | /* | 35 | /* |
35 | * Cookie counter for NLM requests | 36 | * Cookie counter for NLM requests |
36 | */ | 37 | */ |
@@ -221,8 +222,7 @@ nlmclnt_proc(struct inode *inode, int cmd, struct file_lock *fl) | |||
221 | goto done; | 222 | goto done; |
222 | } | 223 | } |
223 | clnt->cl_softrtry = nfssrv->client->cl_softrtry; | 224 | clnt->cl_softrtry = nfssrv->client->cl_softrtry; |
224 | clnt->cl_intr = nfssrv->client->cl_intr; | 225 | clnt->cl_intr = nfssrv->client->cl_intr; |
225 | clnt->cl_chatty = nfssrv->client->cl_chatty; | ||
226 | } | 226 | } |
227 | 227 | ||
228 | /* Keep the old signal mask */ | 228 | /* Keep the old signal mask */ |
@@ -399,8 +399,7 @@ in_grace_period: | |||
399 | /* | 399 | /* |
400 | * Generic NLM call, async version. | 400 | * Generic NLM call, async version. |
401 | */ | 401 | */ |
402 | int | 402 | int nlmsvc_async_call(struct nlm_rqst *req, u32 proc, const struct rpc_call_ops *tk_ops) |
403 | nlmsvc_async_call(struct nlm_rqst *req, u32 proc, rpc_action callback) | ||
404 | { | 403 | { |
405 | struct nlm_host *host = req->a_host; | 404 | struct nlm_host *host = req->a_host; |
406 | struct rpc_clnt *clnt; | 405 | struct rpc_clnt *clnt; |
@@ -419,13 +418,12 @@ nlmsvc_async_call(struct nlm_rqst *req, u32 proc, rpc_action callback) | |||
419 | msg.rpc_proc = &clnt->cl_procinfo[proc]; | 418 | msg.rpc_proc = &clnt->cl_procinfo[proc]; |
420 | 419 | ||
421 | /* bootstrap and kick off the async RPC call */ | 420 | /* bootstrap and kick off the async RPC call */ |
422 | status = rpc_call_async(clnt, &msg, RPC_TASK_ASYNC, callback, req); | 421 | status = rpc_call_async(clnt, &msg, RPC_TASK_ASYNC, tk_ops, req); |
423 | 422 | ||
424 | return status; | 423 | return status; |
425 | } | 424 | } |
426 | 425 | ||
427 | static int | 426 | static int nlmclnt_async_call(struct nlm_rqst *req, u32 proc, const struct rpc_call_ops *tk_ops) |
428 | nlmclnt_async_call(struct nlm_rqst *req, u32 proc, rpc_action callback) | ||
429 | { | 427 | { |
430 | struct nlm_host *host = req->a_host; | 428 | struct nlm_host *host = req->a_host; |
431 | struct rpc_clnt *clnt; | 429 | struct rpc_clnt *clnt; |
@@ -448,7 +446,7 @@ nlmclnt_async_call(struct nlm_rqst *req, u32 proc, rpc_action callback) | |||
448 | /* Increment host refcount */ | 446 | /* Increment host refcount */ |
449 | nlm_get_host(host); | 447 | nlm_get_host(host); |
450 | /* bootstrap and kick off the async RPC call */ | 448 | /* bootstrap and kick off the async RPC call */ |
451 | status = rpc_call_async(clnt, &msg, RPC_TASK_ASYNC, callback, req); | 449 | status = rpc_call_async(clnt, &msg, RPC_TASK_ASYNC, tk_ops, req); |
452 | if (status < 0) | 450 | if (status < 0) |
453 | nlm_release_host(host); | 451 | nlm_release_host(host); |
454 | return status; | 452 | return status; |
@@ -664,7 +662,7 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl) | |||
664 | 662 | ||
665 | if (req->a_flags & RPC_TASK_ASYNC) { | 663 | if (req->a_flags & RPC_TASK_ASYNC) { |
666 | status = nlmclnt_async_call(req, NLMPROC_UNLOCK, | 664 | status = nlmclnt_async_call(req, NLMPROC_UNLOCK, |
667 | nlmclnt_unlock_callback); | 665 | &nlmclnt_unlock_ops); |
668 | /* Hrmf... Do the unlock early since locks_remove_posix() | 666 | /* Hrmf... Do the unlock early since locks_remove_posix() |
669 | * really expects us to free the lock synchronously */ | 667 | * really expects us to free the lock synchronously */ |
670 | do_vfs_lock(fl); | 668 | do_vfs_lock(fl); |
@@ -692,10 +690,9 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl) | |||
692 | return -ENOLCK; | 690 | return -ENOLCK; |
693 | } | 691 | } |
694 | 692 | ||
695 | static void | 693 | static void nlmclnt_unlock_callback(struct rpc_task *task, void *data) |
696 | nlmclnt_unlock_callback(struct rpc_task *task) | ||
697 | { | 694 | { |
698 | struct nlm_rqst *req = (struct nlm_rqst *) task->tk_calldata; | 695 | struct nlm_rqst *req = data; |
699 | int status = req->a_res.status; | 696 | int status = req->a_res.status; |
700 | 697 | ||
701 | if (RPC_ASSASSINATED(task)) | 698 | if (RPC_ASSASSINATED(task)) |
@@ -722,6 +719,10 @@ die: | |||
722 | rpc_restart_call(task); | 719 | rpc_restart_call(task); |
723 | } | 720 | } |
724 | 721 | ||
722 | static const struct rpc_call_ops nlmclnt_unlock_ops = { | ||
723 | .rpc_call_done = nlmclnt_unlock_callback, | ||
724 | }; | ||
725 | |||
725 | /* | 726 | /* |
726 | * Cancel a blocked lock request. | 727 | * Cancel a blocked lock request. |
727 | * We always use an async RPC call for this in order not to hang a | 728 | * We always use an async RPC call for this in order not to hang a |
@@ -750,8 +751,7 @@ nlmclnt_cancel(struct nlm_host *host, struct file_lock *fl) | |||
750 | 751 | ||
751 | nlmclnt_setlockargs(req, fl); | 752 | nlmclnt_setlockargs(req, fl); |
752 | 753 | ||
753 | status = nlmclnt_async_call(req, NLMPROC_CANCEL, | 754 | status = nlmclnt_async_call(req, NLMPROC_CANCEL, &nlmclnt_cancel_ops); |
754 | nlmclnt_cancel_callback); | ||
755 | if (status < 0) { | 755 | if (status < 0) { |
756 | nlmclnt_release_lockargs(req); | 756 | nlmclnt_release_lockargs(req); |
757 | kfree(req); | 757 | kfree(req); |
@@ -765,10 +765,9 @@ nlmclnt_cancel(struct nlm_host *host, struct file_lock *fl) | |||
765 | return status; | 765 | return status; |
766 | } | 766 | } |
767 | 767 | ||
768 | static void | 768 | static void nlmclnt_cancel_callback(struct rpc_task *task, void *data) |
769 | nlmclnt_cancel_callback(struct rpc_task *task) | ||
770 | { | 769 | { |
771 | struct nlm_rqst *req = (struct nlm_rqst *) task->tk_calldata; | 770 | struct nlm_rqst *req = data; |
772 | 771 | ||
773 | if (RPC_ASSASSINATED(task)) | 772 | if (RPC_ASSASSINATED(task)) |
774 | goto die; | 773 | goto die; |
@@ -807,6 +806,10 @@ retry_cancel: | |||
807 | rpc_delay(task, 30 * HZ); | 806 | rpc_delay(task, 30 * HZ); |
808 | } | 807 | } |
809 | 808 | ||
809 | static const struct rpc_call_ops nlmclnt_cancel_ops = { | ||
810 | .rpc_call_done = nlmclnt_cancel_callback, | ||
811 | }; | ||
812 | |||
810 | /* | 813 | /* |
811 | * Convert an NLM status code to a generic kernel errno | 814 | * Convert an NLM status code to a generic kernel errno |
812 | */ | 815 | */ |
diff --git a/fs/lockd/host.c b/fs/lockd/host.c index c4c8601096e0..82f7a0b1d8ae 100644 --- a/fs/lockd/host.c +++ b/fs/lockd/host.c | |||
@@ -177,7 +177,7 @@ nlm_bind_host(struct nlm_host *host) | |||
177 | if ((clnt = host->h_rpcclnt) != NULL) { | 177 | if ((clnt = host->h_rpcclnt) != NULL) { |
178 | xprt = clnt->cl_xprt; | 178 | xprt = clnt->cl_xprt; |
179 | if (time_after_eq(jiffies, host->h_nextrebind)) { | 179 | if (time_after_eq(jiffies, host->h_nextrebind)) { |
180 | clnt->cl_port = 0; | 180 | rpc_force_rebind(clnt); |
181 | host->h_nextrebind = jiffies + NLM_HOST_REBIND; | 181 | host->h_nextrebind = jiffies + NLM_HOST_REBIND; |
182 | dprintk("lockd: next rebind in %ld jiffies\n", | 182 | dprintk("lockd: next rebind in %ld jiffies\n", |
183 | host->h_nextrebind - jiffies); | 183 | host->h_nextrebind - jiffies); |
@@ -217,7 +217,7 @@ nlm_rebind_host(struct nlm_host *host) | |||
217 | { | 217 | { |
218 | dprintk("lockd: rebind host %s\n", host->h_name); | 218 | dprintk("lockd: rebind host %s\n", host->h_name); |
219 | if (host->h_rpcclnt && time_after_eq(jiffies, host->h_nextrebind)) { | 219 | if (host->h_rpcclnt && time_after_eq(jiffies, host->h_nextrebind)) { |
220 | host->h_rpcclnt->cl_port = 0; | 220 | rpc_force_rebind(host->h_rpcclnt); |
221 | host->h_nextrebind = jiffies + NLM_HOST_REBIND; | 221 | host->h_nextrebind = jiffies + NLM_HOST_REBIND; |
222 | } | 222 | } |
223 | } | 223 | } |
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c index 2d144abe84ad..0edc03e67966 100644 --- a/fs/lockd/mon.c +++ b/fs/lockd/mon.c | |||
@@ -123,7 +123,6 @@ nsm_create(void) | |||
123 | if (IS_ERR(clnt)) | 123 | if (IS_ERR(clnt)) |
124 | goto out_err; | 124 | goto out_err; |
125 | clnt->cl_softrtry = 1; | 125 | clnt->cl_softrtry = 1; |
126 | clnt->cl_chatty = 1; | ||
127 | clnt->cl_oneshot = 1; | 126 | clnt->cl_oneshot = 1; |
128 | return clnt; | 127 | return clnt; |
129 | 128 | ||
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 12a857c29e25..71a30b416d1a 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c | |||
@@ -178,6 +178,8 @@ lockd(struct svc_rqst *rqstp) | |||
178 | 178 | ||
179 | } | 179 | } |
180 | 180 | ||
181 | flush_signals(current); | ||
182 | |||
181 | /* | 183 | /* |
182 | * Check whether there's a new lockd process before | 184 | * Check whether there's a new lockd process before |
183 | * shutting down the hosts and clearing the slot. | 185 | * shutting down the hosts and clearing the slot. |
@@ -192,8 +194,6 @@ lockd(struct svc_rqst *rqstp) | |||
192 | "lockd: new process, skipping host shutdown\n"); | 194 | "lockd: new process, skipping host shutdown\n"); |
193 | wake_up(&lockd_exit); | 195 | wake_up(&lockd_exit); |
194 | 196 | ||
195 | flush_signals(current); | ||
196 | |||
197 | /* Exit the RPC thread */ | 197 | /* Exit the RPC thread */ |
198 | svc_exit_thread(rqstp); | 198 | svc_exit_thread(rqstp); |
199 | 199 | ||
diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c index 489670e21769..4063095d849e 100644 --- a/fs/lockd/svc4proc.c +++ b/fs/lockd/svc4proc.c | |||
@@ -22,7 +22,8 @@ | |||
22 | #define NLMDBG_FACILITY NLMDBG_CLIENT | 22 | #define NLMDBG_FACILITY NLMDBG_CLIENT |
23 | 23 | ||
24 | static u32 nlm4svc_callback(struct svc_rqst *, u32, struct nlm_res *); | 24 | static u32 nlm4svc_callback(struct svc_rqst *, u32, struct nlm_res *); |
25 | static void nlm4svc_callback_exit(struct rpc_task *); | 25 | |
26 | static const struct rpc_call_ops nlm4svc_callback_ops; | ||
26 | 27 | ||
27 | /* | 28 | /* |
28 | * Obtain client and file from arguments | 29 | * Obtain client and file from arguments |
@@ -470,7 +471,6 @@ nlm4svc_proc_granted_res(struct svc_rqst *rqstp, struct nlm_res *argp, | |||
470 | } | 471 | } |
471 | 472 | ||
472 | 473 | ||
473 | |||
474 | /* | 474 | /* |
475 | * This is the generic lockd callback for async RPC calls | 475 | * This is the generic lockd callback for async RPC calls |
476 | */ | 476 | */ |
@@ -494,7 +494,7 @@ nlm4svc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_res *resp) | |||
494 | call->a_host = host; | 494 | call->a_host = host; |
495 | memcpy(&call->a_args, resp, sizeof(*resp)); | 495 | memcpy(&call->a_args, resp, sizeof(*resp)); |
496 | 496 | ||
497 | if (nlmsvc_async_call(call, proc, nlm4svc_callback_exit) < 0) | 497 | if (nlmsvc_async_call(call, proc, &nlm4svc_callback_ops) < 0) |
498 | goto error; | 498 | goto error; |
499 | 499 | ||
500 | return rpc_success; | 500 | return rpc_success; |
@@ -504,10 +504,9 @@ nlm4svc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_res *resp) | |||
504 | return rpc_system_err; | 504 | return rpc_system_err; |
505 | } | 505 | } |
506 | 506 | ||
507 | static void | 507 | static void nlm4svc_callback_exit(struct rpc_task *task, void *data) |
508 | nlm4svc_callback_exit(struct rpc_task *task) | ||
509 | { | 508 | { |
510 | struct nlm_rqst *call = (struct nlm_rqst *) task->tk_calldata; | 509 | struct nlm_rqst *call = data; |
511 | 510 | ||
512 | if (task->tk_status < 0) { | 511 | if (task->tk_status < 0) { |
513 | dprintk("lockd: %4d callback failed (errno = %d)\n", | 512 | dprintk("lockd: %4d callback failed (errno = %d)\n", |
@@ -517,6 +516,10 @@ nlm4svc_callback_exit(struct rpc_task *task) | |||
517 | kfree(call); | 516 | kfree(call); |
518 | } | 517 | } |
519 | 518 | ||
519 | static const struct rpc_call_ops nlm4svc_callback_ops = { | ||
520 | .rpc_call_done = nlm4svc_callback_exit, | ||
521 | }; | ||
522 | |||
520 | /* | 523 | /* |
521 | * NLM Server procedures. | 524 | * NLM Server procedures. |
522 | */ | 525 | */ |
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index 49f959796b66..9cfced65d4a2 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c | |||
@@ -41,7 +41,8 @@ | |||
41 | 41 | ||
42 | static void nlmsvc_insert_block(struct nlm_block *block, unsigned long); | 42 | static void nlmsvc_insert_block(struct nlm_block *block, unsigned long); |
43 | static int nlmsvc_remove_block(struct nlm_block *block); | 43 | static int nlmsvc_remove_block(struct nlm_block *block); |
44 | static void nlmsvc_grant_callback(struct rpc_task *task); | 44 | |
45 | static const struct rpc_call_ops nlmsvc_grant_ops; | ||
45 | 46 | ||
46 | /* | 47 | /* |
47 | * The list of blocked locks to retry | 48 | * The list of blocked locks to retry |
@@ -226,31 +227,27 @@ failed: | |||
226 | * It is the caller's responsibility to check whether the file | 227 | * It is the caller's responsibility to check whether the file |
227 | * can be closed hereafter. | 228 | * can be closed hereafter. |
228 | */ | 229 | */ |
229 | static void | 230 | static int |
230 | nlmsvc_delete_block(struct nlm_block *block, int unlock) | 231 | nlmsvc_delete_block(struct nlm_block *block, int unlock) |
231 | { | 232 | { |
232 | struct file_lock *fl = &block->b_call.a_args.lock.fl; | 233 | struct file_lock *fl = &block->b_call.a_args.lock.fl; |
233 | struct nlm_file *file = block->b_file; | 234 | struct nlm_file *file = block->b_file; |
234 | struct nlm_block **bp; | 235 | struct nlm_block **bp; |
236 | int status = 0; | ||
235 | 237 | ||
236 | dprintk("lockd: deleting block %p...\n", block); | 238 | dprintk("lockd: deleting block %p...\n", block); |
237 | 239 | ||
238 | /* Remove block from list */ | 240 | /* Remove block from list */ |
239 | nlmsvc_remove_block(block); | 241 | nlmsvc_remove_block(block); |
240 | if (fl->fl_next) | 242 | if (unlock) |
241 | posix_unblock_lock(file->f_file, fl); | 243 | status = posix_unblock_lock(file->f_file, fl); |
242 | if (unlock) { | ||
243 | fl->fl_type = F_UNLCK; | ||
244 | posix_lock_file(file->f_file, fl); | ||
245 | block->b_granted = 0; | ||
246 | } | ||
247 | 244 | ||
248 | /* If the block is in the middle of a GRANT callback, | 245 | /* If the block is in the middle of a GRANT callback, |
249 | * don't kill it yet. */ | 246 | * don't kill it yet. */ |
250 | if (block->b_incall) { | 247 | if (block->b_incall) { |
251 | nlmsvc_insert_block(block, NLM_NEVER); | 248 | nlmsvc_insert_block(block, NLM_NEVER); |
252 | block->b_done = 1; | 249 | block->b_done = 1; |
253 | return; | 250 | return status; |
254 | } | 251 | } |
255 | 252 | ||
256 | /* Remove block from file's list of blocks */ | 253 | /* Remove block from file's list of blocks */ |
@@ -265,6 +262,7 @@ nlmsvc_delete_block(struct nlm_block *block, int unlock) | |||
265 | nlm_release_host(block->b_host); | 262 | nlm_release_host(block->b_host); |
266 | nlmclnt_freegrantargs(&block->b_call); | 263 | nlmclnt_freegrantargs(&block->b_call); |
267 | kfree(block); | 264 | kfree(block); |
265 | return status; | ||
268 | } | 266 | } |
269 | 267 | ||
270 | /* | 268 | /* |
@@ -275,6 +273,7 @@ int | |||
275 | nlmsvc_traverse_blocks(struct nlm_host *host, struct nlm_file *file, int action) | 273 | nlmsvc_traverse_blocks(struct nlm_host *host, struct nlm_file *file, int action) |
276 | { | 274 | { |
277 | struct nlm_block *block, *next; | 275 | struct nlm_block *block, *next; |
276 | /* XXX: Will everything get cleaned up if we don't unlock here? */ | ||
278 | 277 | ||
279 | down(&file->f_sema); | 278 | down(&file->f_sema); |
280 | for (block = file->f_blocks; block; block = next) { | 279 | for (block = file->f_blocks; block; block = next) { |
@@ -444,6 +443,7 @@ u32 | |||
444 | nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock) | 443 | nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock) |
445 | { | 444 | { |
446 | struct nlm_block *block; | 445 | struct nlm_block *block; |
446 | int status = 0; | ||
447 | 447 | ||
448 | dprintk("lockd: nlmsvc_cancel(%s/%ld, pi=%d, %Ld-%Ld)\n", | 448 | dprintk("lockd: nlmsvc_cancel(%s/%ld, pi=%d, %Ld-%Ld)\n", |
449 | file->f_file->f_dentry->d_inode->i_sb->s_id, | 449 | file->f_file->f_dentry->d_inode->i_sb->s_id, |
@@ -454,9 +454,9 @@ nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock) | |||
454 | 454 | ||
455 | down(&file->f_sema); | 455 | down(&file->f_sema); |
456 | if ((block = nlmsvc_lookup_block(file, lock, 1)) != NULL) | 456 | if ((block = nlmsvc_lookup_block(file, lock, 1)) != NULL) |
457 | nlmsvc_delete_block(block, 1); | 457 | status = nlmsvc_delete_block(block, 1); |
458 | up(&file->f_sema); | 458 | up(&file->f_sema); |
459 | return nlm_granted; | 459 | return status ? nlm_lck_denied : nlm_granted; |
460 | } | 460 | } |
461 | 461 | ||
462 | /* | 462 | /* |
@@ -562,7 +562,7 @@ callback: | |||
562 | /* Call the client */ | 562 | /* Call the client */ |
563 | nlm_get_host(block->b_call.a_host); | 563 | nlm_get_host(block->b_call.a_host); |
564 | if (nlmsvc_async_call(&block->b_call, NLMPROC_GRANTED_MSG, | 564 | if (nlmsvc_async_call(&block->b_call, NLMPROC_GRANTED_MSG, |
565 | nlmsvc_grant_callback) < 0) | 565 | &nlmsvc_grant_ops) < 0) |
566 | nlm_release_host(block->b_call.a_host); | 566 | nlm_release_host(block->b_call.a_host); |
567 | up(&file->f_sema); | 567 | up(&file->f_sema); |
568 | } | 568 | } |
@@ -575,10 +575,9 @@ callback: | |||
575 | * chain once more in order to have it removed by lockd itself (which can | 575 | * chain once more in order to have it removed by lockd itself (which can |
576 | * then sleep on the file semaphore without disrupting e.g. the nfs client). | 576 | * then sleep on the file semaphore without disrupting e.g. the nfs client). |
577 | */ | 577 | */ |
578 | static void | 578 | static void nlmsvc_grant_callback(struct rpc_task *task, void *data) |
579 | nlmsvc_grant_callback(struct rpc_task *task) | ||
580 | { | 579 | { |
581 | struct nlm_rqst *call = (struct nlm_rqst *) task->tk_calldata; | 580 | struct nlm_rqst *call = data; |
582 | struct nlm_block *block; | 581 | struct nlm_block *block; |
583 | unsigned long timeout; | 582 | unsigned long timeout; |
584 | struct sockaddr_in *peer_addr = RPC_PEERADDR(task->tk_client); | 583 | struct sockaddr_in *peer_addr = RPC_PEERADDR(task->tk_client); |
@@ -614,6 +613,10 @@ nlmsvc_grant_callback(struct rpc_task *task) | |||
614 | nlm_release_host(call->a_host); | 613 | nlm_release_host(call->a_host); |
615 | } | 614 | } |
616 | 615 | ||
616 | static const struct rpc_call_ops nlmsvc_grant_ops = { | ||
617 | .rpc_call_done = nlmsvc_grant_callback, | ||
618 | }; | ||
619 | |||
617 | /* | 620 | /* |
618 | * We received a GRANT_RES callback. Try to find the corresponding | 621 | * We received a GRANT_RES callback. Try to find the corresponding |
619 | * block. | 622 | * block. |
@@ -633,11 +636,12 @@ nlmsvc_grant_reply(struct svc_rqst *rqstp, struct nlm_cookie *cookie, u32 status | |||
633 | 636 | ||
634 | file->f_count++; | 637 | file->f_count++; |
635 | down(&file->f_sema); | 638 | down(&file->f_sema); |
636 | if ((block = nlmsvc_find_block(cookie,&rqstp->rq_addr)) != NULL) { | 639 | block = nlmsvc_find_block(cookie, &rqstp->rq_addr); |
640 | if (block) { | ||
637 | if (status == NLM_LCK_DENIED_GRACE_PERIOD) { | 641 | if (status == NLM_LCK_DENIED_GRACE_PERIOD) { |
638 | /* Try again in a couple of seconds */ | 642 | /* Try again in a couple of seconds */ |
639 | nlmsvc_insert_block(block, 10 * HZ); | 643 | nlmsvc_insert_block(block, 10 * HZ); |
640 | block = NULL; | 644 | up(&file->f_sema); |
641 | } else { | 645 | } else { |
642 | /* Lock is now held by client, or has been rejected. | 646 | /* Lock is now held by client, or has been rejected. |
643 | * In both cases, the block should be removed. */ | 647 | * In both cases, the block should be removed. */ |
@@ -648,8 +652,6 @@ nlmsvc_grant_reply(struct svc_rqst *rqstp, struct nlm_cookie *cookie, u32 status | |||
648 | nlmsvc_delete_block(block, 1); | 652 | nlmsvc_delete_block(block, 1); |
649 | } | 653 | } |
650 | } | 654 | } |
651 | if (!block) | ||
652 | up(&file->f_sema); | ||
653 | nlm_release_file(file); | 655 | nlm_release_file(file); |
654 | } | 656 | } |
655 | 657 | ||
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index 757e344cf200..3bc437e0cf5b 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c | |||
@@ -23,7 +23,8 @@ | |||
23 | #define NLMDBG_FACILITY NLMDBG_CLIENT | 23 | #define NLMDBG_FACILITY NLMDBG_CLIENT |
24 | 24 | ||
25 | static u32 nlmsvc_callback(struct svc_rqst *, u32, struct nlm_res *); | 25 | static u32 nlmsvc_callback(struct svc_rqst *, u32, struct nlm_res *); |
26 | static void nlmsvc_callback_exit(struct rpc_task *); | 26 | |
27 | static const struct rpc_call_ops nlmsvc_callback_ops; | ||
27 | 28 | ||
28 | #ifdef CONFIG_LOCKD_V4 | 29 | #ifdef CONFIG_LOCKD_V4 |
29 | static u32 | 30 | static u32 |
@@ -518,7 +519,7 @@ nlmsvc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_res *resp) | |||
518 | call->a_host = host; | 519 | call->a_host = host; |
519 | memcpy(&call->a_args, resp, sizeof(*resp)); | 520 | memcpy(&call->a_args, resp, sizeof(*resp)); |
520 | 521 | ||
521 | if (nlmsvc_async_call(call, proc, nlmsvc_callback_exit) < 0) | 522 | if (nlmsvc_async_call(call, proc, &nlmsvc_callback_ops) < 0) |
522 | goto error; | 523 | goto error; |
523 | 524 | ||
524 | return rpc_success; | 525 | return rpc_success; |
@@ -528,10 +529,9 @@ nlmsvc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_res *resp) | |||
528 | return rpc_system_err; | 529 | return rpc_system_err; |
529 | } | 530 | } |
530 | 531 | ||
531 | static void | 532 | static void nlmsvc_callback_exit(struct rpc_task *task, void *data) |
532 | nlmsvc_callback_exit(struct rpc_task *task) | ||
533 | { | 533 | { |
534 | struct nlm_rqst *call = (struct nlm_rqst *) task->tk_calldata; | 534 | struct nlm_rqst *call = data; |
535 | 535 | ||
536 | if (task->tk_status < 0) { | 536 | if (task->tk_status < 0) { |
537 | dprintk("lockd: %4d callback failed (errno = %d)\n", | 537 | dprintk("lockd: %4d callback failed (errno = %d)\n", |
@@ -541,6 +541,10 @@ nlmsvc_callback_exit(struct rpc_task *task) | |||
541 | kfree(call); | 541 | kfree(call); |
542 | } | 542 | } |
543 | 543 | ||
544 | static const struct rpc_call_ops nlmsvc_callback_ops = { | ||
545 | .rpc_call_done = nlmsvc_callback_exit, | ||
546 | }; | ||
547 | |||
544 | /* | 548 | /* |
545 | * NLM Server procedures. | 549 | * NLM Server procedures. |
546 | */ | 550 | */ |
diff --git a/fs/lockd/xdr4.c b/fs/lockd/xdr4.c index ae4d6b426c62..fdcf105a5303 100644 --- a/fs/lockd/xdr4.c +++ b/fs/lockd/xdr4.c | |||
@@ -354,7 +354,9 @@ nlm4svc_decode_reboot(struct svc_rqst *rqstp, u32 *p, struct nlm_reboot *argp) | |||
354 | return 0; | 354 | return 0; |
355 | argp->state = ntohl(*p++); | 355 | argp->state = ntohl(*p++); |
356 | /* Preserve the address in network byte order */ | 356 | /* Preserve the address in network byte order */ |
357 | argp->addr = *p++; | 357 | argp->addr = *p++; |
358 | argp->vers = *p++; | ||
359 | argp->proto = *p++; | ||
358 | return xdr_argsize_check(rqstp, p); | 360 | return xdr_argsize_check(rqstp, p); |
359 | } | 361 | } |
360 | 362 | ||
diff --git a/fs/locks.c b/fs/locks.c index 250ef53d25ef..fb32d6218e21 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -1958,22 +1958,18 @@ EXPORT_SYMBOL(posix_block_lock); | |||
1958 | * | 1958 | * |
1959 | * lockd needs to block waiting for locks. | 1959 | * lockd needs to block waiting for locks. |
1960 | */ | 1960 | */ |
1961 | void | 1961 | int |
1962 | posix_unblock_lock(struct file *filp, struct file_lock *waiter) | 1962 | posix_unblock_lock(struct file *filp, struct file_lock *waiter) |
1963 | { | 1963 | { |
1964 | /* | 1964 | int status = 0; |
1965 | * A remote machine may cancel the lock request after it's been | 1965 | |
1966 | * granted locally. If that happens, we need to delete the lock. | ||
1967 | */ | ||
1968 | lock_kernel(); | 1966 | lock_kernel(); |
1969 | if (waiter->fl_next) { | 1967 | if (waiter->fl_next) |
1970 | __locks_delete_block(waiter); | 1968 | __locks_delete_block(waiter); |
1971 | unlock_kernel(); | 1969 | else |
1972 | } else { | 1970 | status = -ENOENT; |
1973 | unlock_kernel(); | 1971 | unlock_kernel(); |
1974 | waiter->fl_type = F_UNLCK; | 1972 | return status; |
1975 | posix_lock_file(filp, waiter); | ||
1976 | } | ||
1977 | } | 1973 | } |
1978 | 1974 | ||
1979 | EXPORT_SYMBOL(posix_unblock_lock); | 1975 | EXPORT_SYMBOL(posix_unblock_lock); |
diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile index 8b3bb715d177..ec61fd56a1a9 100644 --- a/fs/nfs/Makefile +++ b/fs/nfs/Makefile | |||
@@ -13,4 +13,5 @@ nfs-$(CONFIG_NFS_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \ | |||
13 | delegation.o idmap.o \ | 13 | delegation.o idmap.o \ |
14 | callback.o callback_xdr.o callback_proc.o | 14 | callback.o callback_xdr.o callback_proc.o |
15 | nfs-$(CONFIG_NFS_DIRECTIO) += direct.o | 15 | nfs-$(CONFIG_NFS_DIRECTIO) += direct.o |
16 | nfs-$(CONFIG_SYSCTL) += sysctl.o | ||
16 | nfs-objs := $(nfs-y) | 17 | nfs-objs := $(nfs-y) |
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index 30cae3602867..fcd97406a778 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c | |||
@@ -34,6 +34,7 @@ static struct nfs_callback_data nfs_callback_info; | |||
34 | static DECLARE_MUTEX(nfs_callback_sema); | 34 | static DECLARE_MUTEX(nfs_callback_sema); |
35 | static struct svc_program nfs4_callback_program; | 35 | static struct svc_program nfs4_callback_program; |
36 | 36 | ||
37 | unsigned int nfs_callback_set_tcpport; | ||
37 | unsigned short nfs_callback_tcpport; | 38 | unsigned short nfs_callback_tcpport; |
38 | 39 | ||
39 | /* | 40 | /* |
@@ -98,7 +99,7 @@ int nfs_callback_up(void) | |||
98 | if (!serv) | 99 | if (!serv) |
99 | goto out_err; | 100 | goto out_err; |
100 | /* FIXME: We don't want to register this socket with the portmapper */ | 101 | /* FIXME: We don't want to register this socket with the portmapper */ |
101 | ret = svc_makesock(serv, IPPROTO_TCP, 0); | 102 | ret = svc_makesock(serv, IPPROTO_TCP, nfs_callback_set_tcpport); |
102 | if (ret < 0) | 103 | if (ret < 0) |
103 | goto out_destroy; | 104 | goto out_destroy; |
104 | if (!list_empty(&serv->sv_permsocks)) { | 105 | if (!list_empty(&serv->sv_permsocks)) { |
diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h index a0db2d4f9415..b252e7fe53a5 100644 --- a/fs/nfs/callback.h +++ b/fs/nfs/callback.h | |||
@@ -65,6 +65,7 @@ extern unsigned nfs4_callback_recall(struct cb_recallargs *args, void *dummy); | |||
65 | extern int nfs_callback_up(void); | 65 | extern int nfs_callback_up(void); |
66 | extern int nfs_callback_down(void); | 66 | extern int nfs_callback_down(void); |
67 | 67 | ||
68 | extern unsigned int nfs_callback_set_tcpport; | ||
68 | extern unsigned short nfs_callback_tcpport; | 69 | extern unsigned short nfs_callback_tcpport; |
69 | 70 | ||
70 | #endif /* __LINUX_FS_NFS_CALLBACK_H */ | 71 | #endif /* __LINUX_FS_NFS_CALLBACK_H */ |
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index 65f1e19e4d19..462cfceb50c5 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c | |||
@@ -35,7 +35,9 @@ unsigned nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres | |||
35 | if (delegation == NULL || (delegation->type & FMODE_WRITE) == 0) | 35 | if (delegation == NULL || (delegation->type & FMODE_WRITE) == 0) |
36 | goto out_iput; | 36 | goto out_iput; |
37 | res->size = i_size_read(inode); | 37 | res->size = i_size_read(inode); |
38 | res->change_attr = NFS_CHANGE_ATTR(inode); | 38 | res->change_attr = delegation->change_attr; |
39 | if (nfsi->npages != 0) | ||
40 | res->change_attr++; | ||
39 | res->ctime = inode->i_ctime; | 41 | res->ctime = inode->i_ctime; |
40 | res->mtime = inode->i_mtime; | 42 | res->mtime = inode->i_mtime; |
41 | res->bitmap[0] = (FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE) & | 43 | res->bitmap[0] = (FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE) & |
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index 618a327027b3..c6f07c1c71e6 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c | |||
@@ -8,6 +8,7 @@ | |||
8 | */ | 8 | */ |
9 | #include <linux/config.h> | 9 | #include <linux/config.h> |
10 | #include <linux/completion.h> | 10 | #include <linux/completion.h> |
11 | #include <linux/kthread.h> | ||
11 | #include <linux/module.h> | 12 | #include <linux/module.h> |
12 | #include <linux/sched.h> | 13 | #include <linux/sched.h> |
13 | #include <linux/spinlock.h> | 14 | #include <linux/spinlock.h> |
@@ -130,6 +131,7 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct | |||
130 | sizeof(delegation->stateid.data)); | 131 | sizeof(delegation->stateid.data)); |
131 | delegation->type = res->delegation_type; | 132 | delegation->type = res->delegation_type; |
132 | delegation->maxsize = res->maxsize; | 133 | delegation->maxsize = res->maxsize; |
134 | delegation->change_attr = nfsi->change_attr; | ||
133 | delegation->cred = get_rpccred(cred); | 135 | delegation->cred = get_rpccred(cred); |
134 | delegation->inode = inode; | 136 | delegation->inode = inode; |
135 | 137 | ||
@@ -157,8 +159,6 @@ static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation * | |||
157 | { | 159 | { |
158 | int res = 0; | 160 | int res = 0; |
159 | 161 | ||
160 | __nfs_revalidate_inode(NFS_SERVER(inode), inode); | ||
161 | |||
162 | res = nfs4_proc_delegreturn(inode, delegation->cred, &delegation->stateid); | 162 | res = nfs4_proc_delegreturn(inode, delegation->cred, &delegation->stateid); |
163 | nfs_free_delegation(delegation); | 163 | nfs_free_delegation(delegation); |
164 | return res; | 164 | return res; |
@@ -231,6 +231,49 @@ restart: | |||
231 | spin_unlock(&clp->cl_lock); | 231 | spin_unlock(&clp->cl_lock); |
232 | } | 232 | } |
233 | 233 | ||
234 | int nfs_do_expire_all_delegations(void *ptr) | ||
235 | { | ||
236 | struct nfs4_client *clp = ptr; | ||
237 | struct nfs_delegation *delegation; | ||
238 | struct inode *inode; | ||
239 | |||
240 | allow_signal(SIGKILL); | ||
241 | restart: | ||
242 | spin_lock(&clp->cl_lock); | ||
243 | if (test_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) != 0) | ||
244 | goto out; | ||
245 | if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0) | ||
246 | goto out; | ||
247 | list_for_each_entry(delegation, &clp->cl_delegations, super_list) { | ||
248 | inode = igrab(delegation->inode); | ||
249 | if (inode == NULL) | ||
250 | continue; | ||
251 | spin_unlock(&clp->cl_lock); | ||
252 | nfs_inode_return_delegation(inode); | ||
253 | iput(inode); | ||
254 | goto restart; | ||
255 | } | ||
256 | out: | ||
257 | spin_unlock(&clp->cl_lock); | ||
258 | nfs4_put_client(clp); | ||
259 | module_put_and_exit(0); | ||
260 | } | ||
261 | |||
262 | void nfs_expire_all_delegations(struct nfs4_client *clp) | ||
263 | { | ||
264 | struct task_struct *task; | ||
265 | |||
266 | __module_get(THIS_MODULE); | ||
267 | atomic_inc(&clp->cl_count); | ||
268 | task = kthread_run(nfs_do_expire_all_delegations, clp, | ||
269 | "%u.%u.%u.%u-delegreturn", | ||
270 | NIPQUAD(clp->cl_addr)); | ||
271 | if (!IS_ERR(task)) | ||
272 | return; | ||
273 | nfs4_put_client(clp); | ||
274 | module_put(THIS_MODULE); | ||
275 | } | ||
276 | |||
234 | /* | 277 | /* |
235 | * Return all delegations following an NFS4ERR_CB_PATH_DOWN error. | 278 | * Return all delegations following an NFS4ERR_CB_PATH_DOWN error. |
236 | */ | 279 | */ |
diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h index 2fcc30de924b..7a0b2bfce771 100644 --- a/fs/nfs/delegation.h +++ b/fs/nfs/delegation.h | |||
@@ -21,6 +21,7 @@ struct nfs_delegation { | |||
21 | #define NFS_DELEGATION_NEED_RECLAIM 1 | 21 | #define NFS_DELEGATION_NEED_RECLAIM 1 |
22 | long flags; | 22 | long flags; |
23 | loff_t maxsize; | 23 | loff_t maxsize; |
24 | __u64 change_attr; | ||
24 | }; | 25 | }; |
25 | 26 | ||
26 | int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res); | 27 | int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res); |
@@ -30,6 +31,7 @@ int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *s | |||
30 | 31 | ||
31 | struct inode *nfs_delegation_find_inode(struct nfs4_client *clp, const struct nfs_fh *fhandle); | 32 | struct inode *nfs_delegation_find_inode(struct nfs4_client *clp, const struct nfs_fh *fhandle); |
32 | void nfs_return_all_delegations(struct super_block *sb); | 33 | void nfs_return_all_delegations(struct super_block *sb); |
34 | void nfs_expire_all_delegations(struct nfs4_client *clp); | ||
33 | void nfs_handle_cb_pathdown(struct nfs4_client *clp); | 35 | void nfs_handle_cb_pathdown(struct nfs4_client *clp); |
34 | 36 | ||
35 | void nfs_delegation_mark_reclaim(struct nfs4_client *clp); | 37 | void nfs_delegation_mark_reclaim(struct nfs4_client *clp); |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index c0d1a214572c..e9255198f767 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -1550,8 +1550,10 @@ go_ahead: | |||
1550 | } | 1550 | } |
1551 | nfs_inode_return_delegation(old_inode); | 1551 | nfs_inode_return_delegation(old_inode); |
1552 | 1552 | ||
1553 | if (new_inode) | 1553 | if (new_inode != NULL) { |
1554 | nfs_inode_return_delegation(new_inode); | ||
1554 | d_delete(new_dentry); | 1555 | d_delete(new_dentry); |
1556 | } | ||
1555 | 1557 | ||
1556 | nfs_begin_data_update(old_dir); | 1558 | nfs_begin_data_update(old_dir); |
1557 | nfs_begin_data_update(new_dir); | 1559 | nfs_begin_data_update(new_dir); |
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 079228817603..10ae377e68ff 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c | |||
@@ -122,9 +122,10 @@ nfs_free_user_pages(struct page **pages, int npages, int do_dirty) | |||
122 | { | 122 | { |
123 | int i; | 123 | int i; |
124 | for (i = 0; i < npages; i++) { | 124 | for (i = 0; i < npages; i++) { |
125 | if (do_dirty) | 125 | struct page *page = pages[i]; |
126 | set_page_dirty_lock(pages[i]); | 126 | if (do_dirty && !PageCompound(page)) |
127 | page_cache_release(pages[i]); | 127 | set_page_dirty_lock(page); |
128 | page_cache_release(page); | ||
128 | } | 129 | } |
129 | kfree(pages); | 130 | kfree(pages); |
130 | } | 131 | } |
@@ -154,6 +155,7 @@ static struct nfs_direct_req *nfs_direct_read_alloc(size_t nbytes, unsigned int | |||
154 | struct list_head *list; | 155 | struct list_head *list; |
155 | struct nfs_direct_req *dreq; | 156 | struct nfs_direct_req *dreq; |
156 | unsigned int reads = 0; | 157 | unsigned int reads = 0; |
158 | unsigned int rpages = (rsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | ||
157 | 159 | ||
158 | dreq = kmem_cache_alloc(nfs_direct_cachep, SLAB_KERNEL); | 160 | dreq = kmem_cache_alloc(nfs_direct_cachep, SLAB_KERNEL); |
159 | if (!dreq) | 161 | if (!dreq) |
@@ -167,7 +169,7 @@ static struct nfs_direct_req *nfs_direct_read_alloc(size_t nbytes, unsigned int | |||
167 | 169 | ||
168 | list = &dreq->list; | 170 | list = &dreq->list; |
169 | for(;;) { | 171 | for(;;) { |
170 | struct nfs_read_data *data = nfs_readdata_alloc(); | 172 | struct nfs_read_data *data = nfs_readdata_alloc(rpages); |
171 | 173 | ||
172 | if (unlikely(!data)) { | 174 | if (unlikely(!data)) { |
173 | while (!list_empty(list)) { | 175 | while (!list_empty(list)) { |
@@ -268,8 +270,6 @@ static void nfs_direct_read_schedule(struct nfs_direct_req *dreq, | |||
268 | NFS_PROTO(inode)->read_setup(data); | 270 | NFS_PROTO(inode)->read_setup(data); |
269 | 271 | ||
270 | data->task.tk_cookie = (unsigned long) inode; | 272 | data->task.tk_cookie = (unsigned long) inode; |
271 | data->task.tk_calldata = data; | ||
272 | data->task.tk_release = nfs_readdata_release; | ||
273 | data->complete = nfs_direct_read_result; | 273 | data->complete = nfs_direct_read_result; |
274 | 274 | ||
275 | lock_kernel(); | 275 | lock_kernel(); |
@@ -433,7 +433,7 @@ static ssize_t nfs_direct_write_seg(struct inode *inode, | |||
433 | struct nfs_writeverf first_verf; | 433 | struct nfs_writeverf first_verf; |
434 | struct nfs_write_data *wdata; | 434 | struct nfs_write_data *wdata; |
435 | 435 | ||
436 | wdata = nfs_writedata_alloc(); | 436 | wdata = nfs_writedata_alloc(NFS_SERVER(inode)->wpages); |
437 | if (!wdata) | 437 | if (!wdata) |
438 | return -ENOMEM; | 438 | return -ENOMEM; |
439 | 439 | ||
@@ -662,10 +662,10 @@ nfs_file_direct_read(struct kiocb *iocb, char __user *buf, size_t count, loff_t | |||
662 | .iov_len = count, | 662 | .iov_len = count, |
663 | }; | 663 | }; |
664 | 664 | ||
665 | dprintk("nfs: direct read(%s/%s, %lu@%lu)\n", | 665 | dprintk("nfs: direct read(%s/%s, %lu@%Ld)\n", |
666 | file->f_dentry->d_parent->d_name.name, | 666 | file->f_dentry->d_parent->d_name.name, |
667 | file->f_dentry->d_name.name, | 667 | file->f_dentry->d_name.name, |
668 | (unsigned long) count, (unsigned long) pos); | 668 | (unsigned long) count, (long long) pos); |
669 | 669 | ||
670 | if (!is_sync_kiocb(iocb)) | 670 | if (!is_sync_kiocb(iocb)) |
671 | goto out; | 671 | goto out; |
@@ -718,9 +718,7 @@ out: | |||
718 | ssize_t | 718 | ssize_t |
719 | nfs_file_direct_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t pos) | 719 | nfs_file_direct_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t pos) |
720 | { | 720 | { |
721 | ssize_t retval = -EINVAL; | 721 | ssize_t retval; |
722 | loff_t *ppos = &iocb->ki_pos; | ||
723 | unsigned long limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; | ||
724 | struct file *file = iocb->ki_filp; | 722 | struct file *file = iocb->ki_filp; |
725 | struct nfs_open_context *ctx = | 723 | struct nfs_open_context *ctx = |
726 | (struct nfs_open_context *) file->private_data; | 724 | (struct nfs_open_context *) file->private_data; |
@@ -728,35 +726,32 @@ nfs_file_direct_write(struct kiocb *iocb, const char __user *buf, size_t count, | |||
728 | struct inode *inode = mapping->host; | 726 | struct inode *inode = mapping->host; |
729 | struct iovec iov = { | 727 | struct iovec iov = { |
730 | .iov_base = (char __user *)buf, | 728 | .iov_base = (char __user *)buf, |
731 | .iov_len = count, | ||
732 | }; | 729 | }; |
733 | 730 | ||
734 | dfprintk(VFS, "nfs: direct write(%s/%s(%ld), %lu@%lu)\n", | 731 | dfprintk(VFS, "nfs: direct write(%s/%s, %lu@%Ld)\n", |
735 | file->f_dentry->d_parent->d_name.name, | 732 | file->f_dentry->d_parent->d_name.name, |
736 | file->f_dentry->d_name.name, inode->i_ino, | 733 | file->f_dentry->d_name.name, |
737 | (unsigned long) count, (unsigned long) pos); | 734 | (unsigned long) count, (long long) pos); |
738 | 735 | ||
736 | retval = -EINVAL; | ||
739 | if (!is_sync_kiocb(iocb)) | 737 | if (!is_sync_kiocb(iocb)) |
740 | goto out; | 738 | goto out; |
741 | if (count < 0) | 739 | |
742 | goto out; | 740 | retval = generic_write_checks(file, &pos, &count, 0); |
743 | if (pos < 0) | 741 | if (retval) |
744 | goto out; | 742 | goto out; |
745 | retval = -EFAULT; | 743 | |
746 | if (!access_ok(VERIFY_READ, iov.iov_base, iov.iov_len)) | 744 | retval = -EINVAL; |
745 | if ((ssize_t) count < 0) | ||
747 | goto out; | 746 | goto out; |
748 | retval = -EFBIG; | ||
749 | if (limit != RLIM_INFINITY) { | ||
750 | if (pos >= limit) { | ||
751 | send_sig(SIGXFSZ, current, 0); | ||
752 | goto out; | ||
753 | } | ||
754 | if (count > limit - (unsigned long) pos) | ||
755 | count = limit - (unsigned long) pos; | ||
756 | } | ||
757 | retval = 0; | 747 | retval = 0; |
758 | if (!count) | 748 | if (!count) |
759 | goto out; | 749 | goto out; |
750 | iov.iov_len = count, | ||
751 | |||
752 | retval = -EFAULT; | ||
753 | if (!access_ok(VERIFY_READ, iov.iov_base, iov.iov_len)) | ||
754 | goto out; | ||
760 | 755 | ||
761 | retval = nfs_sync_mapping(mapping); | 756 | retval = nfs_sync_mapping(mapping); |
762 | if (retval) | 757 | if (retval) |
@@ -766,7 +761,7 @@ nfs_file_direct_write(struct kiocb *iocb, const char __user *buf, size_t count, | |||
766 | if (mapping->nrpages) | 761 | if (mapping->nrpages) |
767 | invalidate_inode_pages2(mapping); | 762 | invalidate_inode_pages2(mapping); |
768 | if (retval > 0) | 763 | if (retval > 0) |
769 | *ppos = pos + retval; | 764 | iocb->ki_pos = pos + retval; |
770 | 765 | ||
771 | out: | 766 | out: |
772 | return retval; | 767 | return retval; |
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c index ffb8df91dc34..821edd30333b 100644 --- a/fs/nfs/idmap.c +++ b/fs/nfs/idmap.c | |||
@@ -54,7 +54,11 @@ | |||
54 | 54 | ||
55 | #define IDMAP_HASH_SZ 128 | 55 | #define IDMAP_HASH_SZ 128 |
56 | 56 | ||
57 | /* Default cache timeout is 10 minutes */ | ||
58 | unsigned int nfs_idmap_cache_timeout = 600 * HZ; | ||
59 | |||
57 | struct idmap_hashent { | 60 | struct idmap_hashent { |
61 | unsigned long ih_expires; | ||
58 | __u32 ih_id; | 62 | __u32 ih_id; |
59 | int ih_namelen; | 63 | int ih_namelen; |
60 | char ih_name[IDMAP_NAMESZ]; | 64 | char ih_name[IDMAP_NAMESZ]; |
@@ -149,6 +153,8 @@ idmap_lookup_name(struct idmap_hashtable *h, const char *name, size_t len) | |||
149 | 153 | ||
150 | if (he->ih_namelen != len || memcmp(he->ih_name, name, len) != 0) | 154 | if (he->ih_namelen != len || memcmp(he->ih_name, name, len) != 0) |
151 | return NULL; | 155 | return NULL; |
156 | if (time_after(jiffies, he->ih_expires)) | ||
157 | return NULL; | ||
152 | return he; | 158 | return he; |
153 | } | 159 | } |
154 | 160 | ||
@@ -164,6 +170,8 @@ idmap_lookup_id(struct idmap_hashtable *h, __u32 id) | |||
164 | struct idmap_hashent *he = idmap_id_hash(h, id); | 170 | struct idmap_hashent *he = idmap_id_hash(h, id); |
165 | if (he->ih_id != id || he->ih_namelen == 0) | 171 | if (he->ih_id != id || he->ih_namelen == 0) |
166 | return NULL; | 172 | return NULL; |
173 | if (time_after(jiffies, he->ih_expires)) | ||
174 | return NULL; | ||
167 | return he; | 175 | return he; |
168 | } | 176 | } |
169 | 177 | ||
@@ -192,6 +200,7 @@ idmap_update_entry(struct idmap_hashent *he, const char *name, | |||
192 | memcpy(he->ih_name, name, namelen); | 200 | memcpy(he->ih_name, name, namelen); |
193 | he->ih_name[namelen] = '\0'; | 201 | he->ih_name[namelen] = '\0'; |
194 | he->ih_namelen = namelen; | 202 | he->ih_namelen = namelen; |
203 | he->ih_expires = jiffies + nfs_idmap_cache_timeout; | ||
195 | } | 204 | } |
196 | 205 | ||
197 | /* | 206 | /* |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 432f41cd75e6..e7bd0d92600f 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <asm/uaccess.h> | 40 | #include <asm/uaccess.h> |
41 | 41 | ||
42 | #include "nfs4_fs.h" | 42 | #include "nfs4_fs.h" |
43 | #include "callback.h" | ||
43 | #include "delegation.h" | 44 | #include "delegation.h" |
44 | 45 | ||
45 | #define NFSDBG_FACILITY NFSDBG_VFS | 46 | #define NFSDBG_FACILITY NFSDBG_VFS |
@@ -221,10 +222,10 @@ nfs_calc_block_size(u64 tsize) | |||
221 | static inline unsigned long | 222 | static inline unsigned long |
222 | nfs_block_size(unsigned long bsize, unsigned char *nrbitsp) | 223 | nfs_block_size(unsigned long bsize, unsigned char *nrbitsp) |
223 | { | 224 | { |
224 | if (bsize < 1024) | 225 | if (bsize < NFS_MIN_FILE_IO_SIZE) |
225 | bsize = NFS_DEF_FILE_IO_BUFFER_SIZE; | 226 | bsize = NFS_DEF_FILE_IO_SIZE; |
226 | else if (bsize >= NFS_MAX_FILE_IO_BUFFER_SIZE) | 227 | else if (bsize >= NFS_MAX_FILE_IO_SIZE) |
227 | bsize = NFS_MAX_FILE_IO_BUFFER_SIZE; | 228 | bsize = NFS_MAX_FILE_IO_SIZE; |
228 | 229 | ||
229 | return nfs_block_bits(bsize, nrbitsp); | 230 | return nfs_block_bits(bsize, nrbitsp); |
230 | } | 231 | } |
@@ -307,20 +308,15 @@ nfs_sb_init(struct super_block *sb, rpc_authflavor_t authflavor) | |||
307 | max_rpc_payload = nfs_block_size(rpc_max_payload(server->client), NULL); | 308 | max_rpc_payload = nfs_block_size(rpc_max_payload(server->client), NULL); |
308 | if (server->rsize > max_rpc_payload) | 309 | if (server->rsize > max_rpc_payload) |
309 | server->rsize = max_rpc_payload; | 310 | server->rsize = max_rpc_payload; |
310 | if (server->wsize > max_rpc_payload) | 311 | if (server->rsize > NFS_MAX_FILE_IO_SIZE) |
311 | server->wsize = max_rpc_payload; | 312 | server->rsize = NFS_MAX_FILE_IO_SIZE; |
312 | |||
313 | server->rpages = (server->rsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | 313 | server->rpages = (server->rsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; |
314 | if (server->rpages > NFS_READ_MAXIOV) { | ||
315 | server->rpages = NFS_READ_MAXIOV; | ||
316 | server->rsize = server->rpages << PAGE_CACHE_SHIFT; | ||
317 | } | ||
318 | 314 | ||
315 | if (server->wsize > max_rpc_payload) | ||
316 | server->wsize = max_rpc_payload; | ||
317 | if (server->wsize > NFS_MAX_FILE_IO_SIZE) | ||
318 | server->wsize = NFS_MAX_FILE_IO_SIZE; | ||
319 | server->wpages = (server->wsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | 319 | server->wpages = (server->wsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; |
320 | if (server->wpages > NFS_WRITE_MAXIOV) { | ||
321 | server->wpages = NFS_WRITE_MAXIOV; | ||
322 | server->wsize = server->wpages << PAGE_CACHE_SHIFT; | ||
323 | } | ||
324 | 320 | ||
325 | if (sb->s_blocksize == 0) | 321 | if (sb->s_blocksize == 0) |
326 | sb->s_blocksize = nfs_block_bits(server->wsize, | 322 | sb->s_blocksize = nfs_block_bits(server->wsize, |
@@ -417,7 +413,6 @@ nfs_create_client(struct nfs_server *server, const struct nfs_mount_data *data) | |||
417 | 413 | ||
418 | clnt->cl_intr = 1; | 414 | clnt->cl_intr = 1; |
419 | clnt->cl_softrtry = 1; | 415 | clnt->cl_softrtry = 1; |
420 | clnt->cl_chatty = 1; | ||
421 | 416 | ||
422 | return clnt; | 417 | return clnt; |
423 | 418 | ||
@@ -575,11 +570,10 @@ nfs_statfs(struct super_block *sb, struct kstatfs *buf) | |||
575 | buf->f_namelen = server->namelen; | 570 | buf->f_namelen = server->namelen; |
576 | out: | 571 | out: |
577 | unlock_kernel(); | 572 | unlock_kernel(); |
578 | |||
579 | return 0; | 573 | return 0; |
580 | 574 | ||
581 | out_err: | 575 | out_err: |
582 | printk(KERN_WARNING "nfs_statfs: statfs error = %d\n", -error); | 576 | dprintk("%s: statfs error = %d\n", __FUNCTION__, -error); |
583 | buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; | 577 | buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; |
584 | goto out; | 578 | goto out; |
585 | 579 | ||
@@ -958,6 +952,8 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) | |||
958 | int need_atime = NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATIME; | 952 | int need_atime = NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATIME; |
959 | int err; | 953 | int err; |
960 | 954 | ||
955 | /* Flush out writes to the server in order to update c/mtime */ | ||
956 | nfs_sync_inode(inode, 0, 0, FLUSH_WAIT|FLUSH_NOCOMMIT); | ||
961 | if (__IS_FLG(inode, MS_NOATIME)) | 957 | if (__IS_FLG(inode, MS_NOATIME)) |
962 | need_atime = 0; | 958 | need_atime = 0; |
963 | else if (__IS_FLG(inode, MS_NODIRATIME) && S_ISDIR(inode->i_mode)) | 959 | else if (__IS_FLG(inode, MS_NODIRATIME) && S_ISDIR(inode->i_mode)) |
@@ -1252,6 +1248,33 @@ void nfs_end_data_update(struct inode *inode) | |||
1252 | atomic_dec(&nfsi->data_updates); | 1248 | atomic_dec(&nfsi->data_updates); |
1253 | } | 1249 | } |
1254 | 1250 | ||
1251 | static void nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr) | ||
1252 | { | ||
1253 | struct nfs_inode *nfsi = NFS_I(inode); | ||
1254 | |||
1255 | if ((fattr->valid & NFS_ATTR_PRE_CHANGE) != 0 | ||
1256 | && nfsi->change_attr == fattr->pre_change_attr) { | ||
1257 | nfsi->change_attr = fattr->change_attr; | ||
1258 | nfsi->cache_change_attribute = jiffies; | ||
1259 | } | ||
1260 | |||
1261 | /* If we have atomic WCC data, we may update some attributes */ | ||
1262 | if ((fattr->valid & NFS_ATTR_WCC) != 0) { | ||
1263 | if (timespec_equal(&inode->i_ctime, &fattr->pre_ctime)) { | ||
1264 | memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); | ||
1265 | nfsi->cache_change_attribute = jiffies; | ||
1266 | } | ||
1267 | if (timespec_equal(&inode->i_mtime, &fattr->pre_mtime)) { | ||
1268 | memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); | ||
1269 | nfsi->cache_change_attribute = jiffies; | ||
1270 | } | ||
1271 | if (inode->i_size == fattr->pre_size && nfsi->npages == 0) { | ||
1272 | inode->i_size = fattr->size; | ||
1273 | nfsi->cache_change_attribute = jiffies; | ||
1274 | } | ||
1275 | } | ||
1276 | } | ||
1277 | |||
1255 | /** | 1278 | /** |
1256 | * nfs_check_inode_attributes - verify consistency of the inode attribute cache | 1279 | * nfs_check_inode_attributes - verify consistency of the inode attribute cache |
1257 | * @inode - pointer to inode | 1280 | * @inode - pointer to inode |
@@ -1268,22 +1291,20 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat | |||
1268 | int data_unstable; | 1291 | int data_unstable; |
1269 | 1292 | ||
1270 | 1293 | ||
1294 | if ((fattr->valid & NFS_ATTR_FATTR) == 0) | ||
1295 | return 0; | ||
1296 | |||
1271 | /* Are we in the process of updating data on the server? */ | 1297 | /* Are we in the process of updating data on the server? */ |
1272 | data_unstable = nfs_caches_unstable(inode); | 1298 | data_unstable = nfs_caches_unstable(inode); |
1273 | 1299 | ||
1274 | if (fattr->valid & NFS_ATTR_FATTR_V4) { | 1300 | /* Do atomic weak cache consistency updates */ |
1275 | if ((fattr->valid & NFS_ATTR_PRE_CHANGE) != 0 | 1301 | nfs_wcc_update_inode(inode, fattr); |
1276 | && nfsi->change_attr == fattr->pre_change_attr) | ||
1277 | nfsi->change_attr = fattr->change_attr; | ||
1278 | if (nfsi->change_attr != fattr->change_attr) { | ||
1279 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; | ||
1280 | if (!data_unstable) | ||
1281 | nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE; | ||
1282 | } | ||
1283 | } | ||
1284 | 1302 | ||
1285 | if ((fattr->valid & NFS_ATTR_FATTR) == 0) { | 1303 | if ((fattr->valid & NFS_ATTR_FATTR_V4) != 0 && |
1286 | return 0; | 1304 | nfsi->change_attr != fattr->change_attr) { |
1305 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; | ||
1306 | if (!data_unstable) | ||
1307 | nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE; | ||
1287 | } | 1308 | } |
1288 | 1309 | ||
1289 | /* Has the inode gone and changed behind our back? */ | 1310 | /* Has the inode gone and changed behind our back? */ |
@@ -1295,14 +1316,6 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat | |||
1295 | cur_size = i_size_read(inode); | 1316 | cur_size = i_size_read(inode); |
1296 | new_isize = nfs_size_to_loff_t(fattr->size); | 1317 | new_isize = nfs_size_to_loff_t(fattr->size); |
1297 | 1318 | ||
1298 | /* If we have atomic WCC data, we may update some attributes */ | ||
1299 | if ((fattr->valid & NFS_ATTR_WCC) != 0) { | ||
1300 | if (timespec_equal(&inode->i_ctime, &fattr->pre_ctime)) | ||
1301 | memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); | ||
1302 | if (timespec_equal(&inode->i_mtime, &fattr->pre_mtime)) | ||
1303 | memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); | ||
1304 | } | ||
1305 | |||
1306 | /* Verify a few of the more important attributes */ | 1319 | /* Verify a few of the more important attributes */ |
1307 | if (!timespec_equal(&inode->i_mtime, &fattr->mtime)) { | 1320 | if (!timespec_equal(&inode->i_mtime, &fattr->mtime)) { |
1308 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; | 1321 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; |
@@ -1410,14 +1423,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1410 | if ((fattr->valid & NFS_ATTR_FATTR) == 0) | 1423 | if ((fattr->valid & NFS_ATTR_FATTR) == 0) |
1411 | return 0; | 1424 | return 0; |
1412 | 1425 | ||
1413 | if (nfsi->fileid != fattr->fileid) { | 1426 | if (nfsi->fileid != fattr->fileid) |
1414 | printk(KERN_ERR "%s: inode number mismatch\n" | 1427 | goto out_fileid; |
1415 | "expected (%s/0x%Lx), got (%s/0x%Lx)\n", | ||
1416 | __FUNCTION__, | ||
1417 | inode->i_sb->s_id, (long long)nfsi->fileid, | ||
1418 | inode->i_sb->s_id, (long long)fattr->fileid); | ||
1419 | goto out_err; | ||
1420 | } | ||
1421 | 1428 | ||
1422 | /* | 1429 | /* |
1423 | * Make sure the inode's type hasn't changed. | 1430 | * Make sure the inode's type hasn't changed. |
@@ -1436,6 +1443,9 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1436 | if (data_stable) | 1443 | if (data_stable) |
1437 | nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME); | 1444 | nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME); |
1438 | 1445 | ||
1446 | /* Do atomic weak cache consistency updates */ | ||
1447 | nfs_wcc_update_inode(inode, fattr); | ||
1448 | |||
1439 | /* Check if our cached file size is stale */ | 1449 | /* Check if our cached file size is stale */ |
1440 | new_isize = nfs_size_to_loff_t(fattr->size); | 1450 | new_isize = nfs_size_to_loff_t(fattr->size); |
1441 | cur_isize = i_size_read(inode); | 1451 | cur_isize = i_size_read(inode); |
@@ -1539,6 +1549,13 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1539 | */ | 1549 | */ |
1540 | nfs_invalidate_inode(inode); | 1550 | nfs_invalidate_inode(inode); |
1541 | return -ESTALE; | 1551 | return -ESTALE; |
1552 | |||
1553 | out_fileid: | ||
1554 | printk(KERN_ERR "NFS: server %s error: fileid changed\n" | ||
1555 | "fsid %s: expected fileid 0x%Lx, got 0x%Lx\n", | ||
1556 | NFS_SERVER(inode)->hostname, inode->i_sb->s_id, | ||
1557 | (long long)nfsi->fileid, (long long)fattr->fileid); | ||
1558 | goto out_err; | ||
1542 | } | 1559 | } |
1543 | 1560 | ||
1544 | /* | 1561 | /* |
@@ -1820,25 +1837,10 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data, | |||
1820 | } | 1837 | } |
1821 | clnt->cl_intr = 1; | 1838 | clnt->cl_intr = 1; |
1822 | clnt->cl_softrtry = 1; | 1839 | clnt->cl_softrtry = 1; |
1823 | clnt->cl_chatty = 1; | ||
1824 | clp->cl_rpcclient = clnt; | 1840 | clp->cl_rpcclient = clnt; |
1825 | clp->cl_cred = rpcauth_lookupcred(clnt->cl_auth, 0); | ||
1826 | if (IS_ERR(clp->cl_cred)) { | ||
1827 | up_write(&clp->cl_sem); | ||
1828 | err = PTR_ERR(clp->cl_cred); | ||
1829 | clp->cl_cred = NULL; | ||
1830 | goto out_fail; | ||
1831 | } | ||
1832 | memcpy(clp->cl_ipaddr, server->ip_addr, sizeof(clp->cl_ipaddr)); | 1841 | memcpy(clp->cl_ipaddr, server->ip_addr, sizeof(clp->cl_ipaddr)); |
1833 | nfs_idmap_new(clp); | 1842 | nfs_idmap_new(clp); |
1834 | } | 1843 | } |
1835 | if (list_empty(&clp->cl_superblocks)) { | ||
1836 | err = nfs4_init_client(clp); | ||
1837 | if (err != 0) { | ||
1838 | up_write(&clp->cl_sem); | ||
1839 | goto out_fail; | ||
1840 | } | ||
1841 | } | ||
1842 | list_add_tail(&server->nfs4_siblings, &clp->cl_superblocks); | 1844 | list_add_tail(&server->nfs4_siblings, &clp->cl_superblocks); |
1843 | clnt = rpc_clone_client(clp->cl_rpcclient); | 1845 | clnt = rpc_clone_client(clp->cl_rpcclient); |
1844 | if (!IS_ERR(clnt)) | 1846 | if (!IS_ERR(clnt)) |
@@ -2033,6 +2035,35 @@ static struct file_system_type nfs4_fs_type = { | |||
2033 | .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, | 2035 | .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, |
2034 | }; | 2036 | }; |
2035 | 2037 | ||
2038 | static const int nfs_set_port_min = 0; | ||
2039 | static const int nfs_set_port_max = 65535; | ||
2040 | static int param_set_port(const char *val, struct kernel_param *kp) | ||
2041 | { | ||
2042 | char *endp; | ||
2043 | int num = simple_strtol(val, &endp, 0); | ||
2044 | if (endp == val || *endp || num < nfs_set_port_min || num > nfs_set_port_max) | ||
2045 | return -EINVAL; | ||
2046 | *((int *)kp->arg) = num; | ||
2047 | return 0; | ||
2048 | } | ||
2049 | |||
2050 | module_param_call(callback_tcpport, param_set_port, param_get_int, | ||
2051 | &nfs_callback_set_tcpport, 0644); | ||
2052 | |||
2053 | static int param_set_idmap_timeout(const char *val, struct kernel_param *kp) | ||
2054 | { | ||
2055 | char *endp; | ||
2056 | int num = simple_strtol(val, &endp, 0); | ||
2057 | int jif = num * HZ; | ||
2058 | if (endp == val || *endp || num < 0 || jif < num) | ||
2059 | return -EINVAL; | ||
2060 | *((int *)kp->arg) = jif; | ||
2061 | return 0; | ||
2062 | } | ||
2063 | |||
2064 | module_param_call(idmap_cache_timeout, param_set_idmap_timeout, param_get_int, | ||
2065 | &nfs_idmap_cache_timeout, 0644); | ||
2066 | |||
2036 | #define nfs4_init_once(nfsi) \ | 2067 | #define nfs4_init_once(nfsi) \ |
2037 | do { \ | 2068 | do { \ |
2038 | INIT_LIST_HEAD(&(nfsi)->open_states); \ | 2069 | INIT_LIST_HEAD(&(nfsi)->open_states); \ |
@@ -2040,8 +2071,25 @@ static struct file_system_type nfs4_fs_type = { | |||
2040 | nfsi->delegation_state = 0; \ | 2071 | nfsi->delegation_state = 0; \ |
2041 | init_rwsem(&nfsi->rwsem); \ | 2072 | init_rwsem(&nfsi->rwsem); \ |
2042 | } while(0) | 2073 | } while(0) |
2043 | #define register_nfs4fs() register_filesystem(&nfs4_fs_type) | 2074 | |
2044 | #define unregister_nfs4fs() unregister_filesystem(&nfs4_fs_type) | 2075 | static inline int register_nfs4fs(void) |
2076 | { | ||
2077 | int ret; | ||
2078 | |||
2079 | ret = nfs_register_sysctl(); | ||
2080 | if (ret != 0) | ||
2081 | return ret; | ||
2082 | ret = register_filesystem(&nfs4_fs_type); | ||
2083 | if (ret != 0) | ||
2084 | nfs_unregister_sysctl(); | ||
2085 | return ret; | ||
2086 | } | ||
2087 | |||
2088 | static inline void unregister_nfs4fs(void) | ||
2089 | { | ||
2090 | unregister_filesystem(&nfs4_fs_type); | ||
2091 | nfs_unregister_sysctl(); | ||
2092 | } | ||
2045 | #else | 2093 | #else |
2046 | #define nfs4_init_once(nfsi) \ | 2094 | #define nfs4_init_once(nfsi) \ |
2047 | do { } while (0) | 2095 | do { } while (0) |
@@ -2166,11 +2214,11 @@ out: | |||
2166 | #ifdef CONFIG_PROC_FS | 2214 | #ifdef CONFIG_PROC_FS |
2167 | rpc_proc_unregister("nfs"); | 2215 | rpc_proc_unregister("nfs"); |
2168 | #endif | 2216 | #endif |
2169 | nfs_destroy_writepagecache(); | ||
2170 | #ifdef CONFIG_NFS_DIRECTIO | 2217 | #ifdef CONFIG_NFS_DIRECTIO |
2171 | out0: | ||
2172 | nfs_destroy_directcache(); | 2218 | nfs_destroy_directcache(); |
2219 | out0: | ||
2173 | #endif | 2220 | #endif |
2221 | nfs_destroy_writepagecache(); | ||
2174 | out1: | 2222 | out1: |
2175 | nfs_destroy_readpagecache(); | 2223 | nfs_destroy_readpagecache(); |
2176 | out2: | 2224 | out2: |
diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c index 0e82617f2de0..db99b8f678f8 100644 --- a/fs/nfs/mount_clnt.c +++ b/fs/nfs/mount_clnt.c | |||
@@ -82,7 +82,6 @@ mnt_create(char *hostname, struct sockaddr_in *srvaddr, int version, | |||
82 | RPC_AUTH_UNIX); | 82 | RPC_AUTH_UNIX); |
83 | if (!IS_ERR(clnt)) { | 83 | if (!IS_ERR(clnt)) { |
84 | clnt->cl_softrtry = 1; | 84 | clnt->cl_softrtry = 1; |
85 | clnt->cl_chatty = 1; | ||
86 | clnt->cl_oneshot = 1; | 85 | clnt->cl_oneshot = 1; |
87 | clnt->cl_intr = 1; | 86 | clnt->cl_intr = 1; |
88 | } | 87 | } |
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index 59049e864ca7..7fc0560c89c9 100644 --- a/fs/nfs/nfs2xdr.c +++ b/fs/nfs/nfs2xdr.c | |||
@@ -146,23 +146,23 @@ xdr_decode_fattr(u32 *p, struct nfs_fattr *fattr) | |||
146 | return p; | 146 | return p; |
147 | } | 147 | } |
148 | 148 | ||
149 | #define SATTR(p, attr, flag, field) \ | ||
150 | *p++ = (attr->ia_valid & flag) ? htonl(attr->field) : ~(u32) 0 | ||
151 | static inline u32 * | 149 | static inline u32 * |
152 | xdr_encode_sattr(u32 *p, struct iattr *attr) | 150 | xdr_encode_sattr(u32 *p, struct iattr *attr) |
153 | { | 151 | { |
154 | SATTR(p, attr, ATTR_MODE, ia_mode); | 152 | const u32 not_set = __constant_htonl(0xFFFFFFFF); |
155 | SATTR(p, attr, ATTR_UID, ia_uid); | 153 | |
156 | SATTR(p, attr, ATTR_GID, ia_gid); | 154 | *p++ = (attr->ia_valid & ATTR_MODE) ? htonl(attr->ia_mode) : not_set; |
157 | SATTR(p, attr, ATTR_SIZE, ia_size); | 155 | *p++ = (attr->ia_valid & ATTR_UID) ? htonl(attr->ia_uid) : not_set; |
156 | *p++ = (attr->ia_valid & ATTR_GID) ? htonl(attr->ia_gid) : not_set; | ||
157 | *p++ = (attr->ia_valid & ATTR_SIZE) ? htonl(attr->ia_size) : not_set; | ||
158 | 158 | ||
159 | if (attr->ia_valid & ATTR_ATIME_SET) { | 159 | if (attr->ia_valid & ATTR_ATIME_SET) { |
160 | p = xdr_encode_time(p, &attr->ia_atime); | 160 | p = xdr_encode_time(p, &attr->ia_atime); |
161 | } else if (attr->ia_valid & ATTR_ATIME) { | 161 | } else if (attr->ia_valid & ATTR_ATIME) { |
162 | p = xdr_encode_current_server_time(p, &attr->ia_atime); | 162 | p = xdr_encode_current_server_time(p, &attr->ia_atime); |
163 | } else { | 163 | } else { |
164 | *p++ = ~(u32) 0; | 164 | *p++ = not_set; |
165 | *p++ = ~(u32) 0; | 165 | *p++ = not_set; |
166 | } | 166 | } |
167 | 167 | ||
168 | if (attr->ia_valid & ATTR_MTIME_SET) { | 168 | if (attr->ia_valid & ATTR_MTIME_SET) { |
@@ -170,12 +170,11 @@ xdr_encode_sattr(u32 *p, struct iattr *attr) | |||
170 | } else if (attr->ia_valid & ATTR_MTIME) { | 170 | } else if (attr->ia_valid & ATTR_MTIME) { |
171 | p = xdr_encode_current_server_time(p, &attr->ia_mtime); | 171 | p = xdr_encode_current_server_time(p, &attr->ia_mtime); |
172 | } else { | 172 | } else { |
173 | *p++ = ~(u32) 0; | 173 | *p++ = not_set; |
174 | *p++ = ~(u32) 0; | 174 | *p++ = not_set; |
175 | } | 175 | } |
176 | return p; | 176 | return p; |
177 | } | 177 | } |
178 | #undef SATTR | ||
179 | 178 | ||
180 | /* | 179 | /* |
181 | * NFS encode functions | 180 | * NFS encode functions |
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index 92c870d19ccd..ed67567f0556 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c | |||
@@ -68,27 +68,39 @@ nfs3_async_handle_jukebox(struct rpc_task *task) | |||
68 | return 1; | 68 | return 1; |
69 | } | 69 | } |
70 | 70 | ||
71 | /* | ||
72 | * Bare-bones access to getattr: this is for nfs_read_super. | ||
73 | */ | ||
74 | static int | 71 | static int |
75 | nfs3_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, | 72 | do_proc_get_root(struct rpc_clnt *client, struct nfs_fh *fhandle, |
76 | struct nfs_fsinfo *info) | 73 | struct nfs_fsinfo *info) |
77 | { | 74 | { |
78 | int status; | 75 | int status; |
79 | 76 | ||
80 | dprintk("%s: call fsinfo\n", __FUNCTION__); | 77 | dprintk("%s: call fsinfo\n", __FUNCTION__); |
81 | nfs_fattr_init(info->fattr); | 78 | nfs_fattr_init(info->fattr); |
82 | status = rpc_call(server->client_sys, NFS3PROC_FSINFO, fhandle, info, 0); | 79 | status = rpc_call(client, NFS3PROC_FSINFO, fhandle, info, 0); |
83 | dprintk("%s: reply fsinfo: %d\n", __FUNCTION__, status); | 80 | dprintk("%s: reply fsinfo: %d\n", __FUNCTION__, status); |
84 | if (!(info->fattr->valid & NFS_ATTR_FATTR)) { | 81 | if (!(info->fattr->valid & NFS_ATTR_FATTR)) { |
85 | status = rpc_call(server->client_sys, NFS3PROC_GETATTR, fhandle, info->fattr, 0); | 82 | status = rpc_call(client, NFS3PROC_GETATTR, fhandle, info->fattr, 0); |
86 | dprintk("%s: reply getattr: %d\n", __FUNCTION__, status); | 83 | dprintk("%s: reply getattr: %d\n", __FUNCTION__, status); |
87 | } | 84 | } |
88 | return status; | 85 | return status; |
89 | } | 86 | } |
90 | 87 | ||
91 | /* | 88 | /* |
89 | * Bare-bones access to getattr: this is for nfs_read_super. | ||
90 | */ | ||
91 | static int | ||
92 | nfs3_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, | ||
93 | struct nfs_fsinfo *info) | ||
94 | { | ||
95 | int status; | ||
96 | |||
97 | status = do_proc_get_root(server->client, fhandle, info); | ||
98 | if (status && server->client_sys != server->client) | ||
99 | status = do_proc_get_root(server->client_sys, fhandle, info); | ||
100 | return status; | ||
101 | } | ||
102 | |||
103 | /* | ||
92 | * One function for each procedure in the NFS protocol. | 104 | * One function for each procedure in the NFS protocol. |
93 | */ | 105 | */ |
94 | static int | 106 | static int |
@@ -732,19 +744,23 @@ nfs3_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle, | |||
732 | 744 | ||
733 | extern u32 *nfs3_decode_dirent(u32 *, struct nfs_entry *, int); | 745 | extern u32 *nfs3_decode_dirent(u32 *, struct nfs_entry *, int); |
734 | 746 | ||
735 | static void | 747 | static void nfs3_read_done(struct rpc_task *task, void *calldata) |
736 | nfs3_read_done(struct rpc_task *task) | ||
737 | { | 748 | { |
738 | struct nfs_read_data *data = (struct nfs_read_data *) task->tk_calldata; | 749 | struct nfs_read_data *data = calldata; |
739 | 750 | ||
740 | if (nfs3_async_handle_jukebox(task)) | 751 | if (nfs3_async_handle_jukebox(task)) |
741 | return; | 752 | return; |
742 | /* Call back common NFS readpage processing */ | 753 | /* Call back common NFS readpage processing */ |
743 | if (task->tk_status >= 0) | 754 | if (task->tk_status >= 0) |
744 | nfs_refresh_inode(data->inode, &data->fattr); | 755 | nfs_refresh_inode(data->inode, &data->fattr); |
745 | nfs_readpage_result(task); | 756 | nfs_readpage_result(task, calldata); |
746 | } | 757 | } |
747 | 758 | ||
759 | static const struct rpc_call_ops nfs3_read_ops = { | ||
760 | .rpc_call_done = nfs3_read_done, | ||
761 | .rpc_release = nfs_readdata_release, | ||
762 | }; | ||
763 | |||
748 | static void | 764 | static void |
749 | nfs3_proc_read_setup(struct nfs_read_data *data) | 765 | nfs3_proc_read_setup(struct nfs_read_data *data) |
750 | { | 766 | { |
@@ -762,23 +778,26 @@ nfs3_proc_read_setup(struct nfs_read_data *data) | |||
762 | flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0); | 778 | flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0); |
763 | 779 | ||
764 | /* Finalize the task. */ | 780 | /* Finalize the task. */ |
765 | rpc_init_task(task, NFS_CLIENT(inode), nfs3_read_done, flags); | 781 | rpc_init_task(task, NFS_CLIENT(inode), flags, &nfs3_read_ops, data); |
766 | rpc_call_setup(task, &msg, 0); | 782 | rpc_call_setup(task, &msg, 0); |
767 | } | 783 | } |
768 | 784 | ||
769 | static void | 785 | static void nfs3_write_done(struct rpc_task *task, void *calldata) |
770 | nfs3_write_done(struct rpc_task *task) | ||
771 | { | 786 | { |
772 | struct nfs_write_data *data; | 787 | struct nfs_write_data *data = calldata; |
773 | 788 | ||
774 | if (nfs3_async_handle_jukebox(task)) | 789 | if (nfs3_async_handle_jukebox(task)) |
775 | return; | 790 | return; |
776 | data = (struct nfs_write_data *)task->tk_calldata; | ||
777 | if (task->tk_status >= 0) | 791 | if (task->tk_status >= 0) |
778 | nfs_post_op_update_inode(data->inode, data->res.fattr); | 792 | nfs_post_op_update_inode(data->inode, data->res.fattr); |
779 | nfs_writeback_done(task); | 793 | nfs_writeback_done(task, calldata); |
780 | } | 794 | } |
781 | 795 | ||
796 | static const struct rpc_call_ops nfs3_write_ops = { | ||
797 | .rpc_call_done = nfs3_write_done, | ||
798 | .rpc_release = nfs_writedata_release, | ||
799 | }; | ||
800 | |||
782 | static void | 801 | static void |
783 | nfs3_proc_write_setup(struct nfs_write_data *data, int how) | 802 | nfs3_proc_write_setup(struct nfs_write_data *data, int how) |
784 | { | 803 | { |
@@ -806,23 +825,26 @@ nfs3_proc_write_setup(struct nfs_write_data *data, int how) | |||
806 | flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC; | 825 | flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC; |
807 | 826 | ||
808 | /* Finalize the task. */ | 827 | /* Finalize the task. */ |
809 | rpc_init_task(task, NFS_CLIENT(inode), nfs3_write_done, flags); | 828 | rpc_init_task(task, NFS_CLIENT(inode), flags, &nfs3_write_ops, data); |
810 | rpc_call_setup(task, &msg, 0); | 829 | rpc_call_setup(task, &msg, 0); |
811 | } | 830 | } |
812 | 831 | ||
813 | static void | 832 | static void nfs3_commit_done(struct rpc_task *task, void *calldata) |
814 | nfs3_commit_done(struct rpc_task *task) | ||
815 | { | 833 | { |
816 | struct nfs_write_data *data; | 834 | struct nfs_write_data *data = calldata; |
817 | 835 | ||
818 | if (nfs3_async_handle_jukebox(task)) | 836 | if (nfs3_async_handle_jukebox(task)) |
819 | return; | 837 | return; |
820 | data = (struct nfs_write_data *)task->tk_calldata; | ||
821 | if (task->tk_status >= 0) | 838 | if (task->tk_status >= 0) |
822 | nfs_post_op_update_inode(data->inode, data->res.fattr); | 839 | nfs_post_op_update_inode(data->inode, data->res.fattr); |
823 | nfs_commit_done(task); | 840 | nfs_commit_done(task, calldata); |
824 | } | 841 | } |
825 | 842 | ||
843 | static const struct rpc_call_ops nfs3_commit_ops = { | ||
844 | .rpc_call_done = nfs3_commit_done, | ||
845 | .rpc_release = nfs_commit_release, | ||
846 | }; | ||
847 | |||
826 | static void | 848 | static void |
827 | nfs3_proc_commit_setup(struct nfs_write_data *data, int how) | 849 | nfs3_proc_commit_setup(struct nfs_write_data *data, int how) |
828 | { | 850 | { |
@@ -840,7 +862,7 @@ nfs3_proc_commit_setup(struct nfs_write_data *data, int how) | |||
840 | flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC; | 862 | flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC; |
841 | 863 | ||
842 | /* Finalize the task. */ | 864 | /* Finalize the task. */ |
843 | rpc_init_task(task, NFS_CLIENT(inode), nfs3_commit_done, flags); | 865 | rpc_init_task(task, NFS_CLIENT(inode), flags, &nfs3_commit_ops, data); |
844 | rpc_call_setup(task, &msg, 0); | 866 | rpc_call_setup(task, &msg, 0); |
845 | } | 867 | } |
846 | 868 | ||
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index 0498bd36602c..b6c0b5012bce 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c | |||
@@ -182,7 +182,7 @@ xdr_encode_sattr(u32 *p, struct iattr *attr) | |||
182 | { | 182 | { |
183 | if (attr->ia_valid & ATTR_MODE) { | 183 | if (attr->ia_valid & ATTR_MODE) { |
184 | *p++ = xdr_one; | 184 | *p++ = xdr_one; |
185 | *p++ = htonl(attr->ia_mode); | 185 | *p++ = htonl(attr->ia_mode & S_IALLUGO); |
186 | } else { | 186 | } else { |
187 | *p++ = xdr_zero; | 187 | *p++ = xdr_zero; |
188 | } | 188 | } |
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index b7f262dcb6e3..0f5e4e7cddec 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h | |||
@@ -38,7 +38,8 @@ struct idmap; | |||
38 | ((err) != NFSERR_NOFILEHANDLE)) | 38 | ((err) != NFSERR_NOFILEHANDLE)) |
39 | 39 | ||
40 | enum nfs4_client_state { | 40 | enum nfs4_client_state { |
41 | NFS4CLNT_OK = 0, | 41 | NFS4CLNT_STATE_RECOVER = 0, |
42 | NFS4CLNT_LEASE_EXPIRED, | ||
42 | }; | 43 | }; |
43 | 44 | ||
44 | /* | 45 | /* |
@@ -67,7 +68,6 @@ struct nfs4_client { | |||
67 | atomic_t cl_count; | 68 | atomic_t cl_count; |
68 | 69 | ||
69 | struct rpc_clnt * cl_rpcclient; | 70 | struct rpc_clnt * cl_rpcclient; |
70 | struct rpc_cred * cl_cred; | ||
71 | 71 | ||
72 | struct list_head cl_superblocks; /* List of nfs_server structs */ | 72 | struct list_head cl_superblocks; /* List of nfs_server structs */ |
73 | 73 | ||
@@ -76,7 +76,6 @@ struct nfs4_client { | |||
76 | struct work_struct cl_renewd; | 76 | struct work_struct cl_renewd; |
77 | struct work_struct cl_recoverd; | 77 | struct work_struct cl_recoverd; |
78 | 78 | ||
79 | wait_queue_head_t cl_waitq; | ||
80 | struct rpc_wait_queue cl_rpcwaitq; | 79 | struct rpc_wait_queue cl_rpcwaitq; |
81 | 80 | ||
82 | /* used for the setclientid verifier */ | 81 | /* used for the setclientid verifier */ |
@@ -182,8 +181,9 @@ struct nfs4_state { | |||
182 | 181 | ||
183 | nfs4_stateid stateid; | 182 | nfs4_stateid stateid; |
184 | 183 | ||
185 | unsigned int nreaders; | 184 | unsigned int n_rdonly; |
186 | unsigned int nwriters; | 185 | unsigned int n_wronly; |
186 | unsigned int n_rdwr; | ||
187 | int state; /* State on the server (R,W, or RW) */ | 187 | int state; /* State on the server (R,W, or RW) */ |
188 | atomic_t count; | 188 | atomic_t count; |
189 | }; | 189 | }; |
@@ -210,10 +210,10 @@ extern ssize_t nfs4_listxattr(struct dentry *, char *, size_t); | |||
210 | 210 | ||
211 | /* nfs4proc.c */ | 211 | /* nfs4proc.c */ |
212 | extern int nfs4_map_errors(int err); | 212 | extern int nfs4_map_errors(int err); |
213 | extern int nfs4_proc_setclientid(struct nfs4_client *, u32, unsigned short); | 213 | extern int nfs4_proc_setclientid(struct nfs4_client *, u32, unsigned short, struct rpc_cred *); |
214 | extern int nfs4_proc_setclientid_confirm(struct nfs4_client *); | 214 | extern int nfs4_proc_setclientid_confirm(struct nfs4_client *, struct rpc_cred *); |
215 | extern int nfs4_proc_async_renew(struct nfs4_client *); | 215 | extern int nfs4_proc_async_renew(struct nfs4_client *, struct rpc_cred *); |
216 | extern int nfs4_proc_renew(struct nfs4_client *); | 216 | extern int nfs4_proc_renew(struct nfs4_client *, struct rpc_cred *); |
217 | extern int nfs4_do_close(struct inode *inode, struct nfs4_state *state); | 217 | extern int nfs4_do_close(struct inode *inode, struct nfs4_state *state); |
218 | extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *); | 218 | extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *); |
219 | extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *); | 219 | extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *); |
@@ -237,8 +237,8 @@ extern void init_nfsv4_state(struct nfs_server *); | |||
237 | extern void destroy_nfsv4_state(struct nfs_server *); | 237 | extern void destroy_nfsv4_state(struct nfs_server *); |
238 | extern struct nfs4_client *nfs4_get_client(struct in_addr *); | 238 | extern struct nfs4_client *nfs4_get_client(struct in_addr *); |
239 | extern void nfs4_put_client(struct nfs4_client *clp); | 239 | extern void nfs4_put_client(struct nfs4_client *clp); |
240 | extern int nfs4_init_client(struct nfs4_client *clp); | ||
241 | extern struct nfs4_client *nfs4_find_client(struct in_addr *); | 240 | extern struct nfs4_client *nfs4_find_client(struct in_addr *); |
241 | struct rpc_cred *nfs4_get_renew_cred(struct nfs4_client *clp); | ||
242 | extern u32 nfs4_alloc_lockowner_id(struct nfs4_client *); | 242 | extern u32 nfs4_alloc_lockowner_id(struct nfs4_client *); |
243 | 243 | ||
244 | extern struct nfs4_state_owner * nfs4_get_state_owner(struct nfs_server *, struct rpc_cred *); | 244 | extern struct nfs4_state_owner * nfs4_get_state_owner(struct nfs_server *, struct rpc_cred *); |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index f988a9417b13..984ca3454d04 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -57,11 +57,13 @@ | |||
57 | #define NFS4_POLL_RETRY_MIN (1*HZ) | 57 | #define NFS4_POLL_RETRY_MIN (1*HZ) |
58 | #define NFS4_POLL_RETRY_MAX (15*HZ) | 58 | #define NFS4_POLL_RETRY_MAX (15*HZ) |
59 | 59 | ||
60 | static int _nfs4_proc_open_confirm(struct rpc_clnt *clnt, const struct nfs_fh *fh, struct nfs4_state_owner *sp, nfs4_stateid *stateid, struct nfs_seqid *seqid); | 60 | struct nfs4_opendata; |
61 | static int _nfs4_proc_open(struct nfs4_opendata *data); | ||
61 | static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); | 62 | static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); |
62 | static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *); | 63 | static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *); |
63 | static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry); | 64 | static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry); |
64 | static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception); | 65 | static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception); |
66 | static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs4_client *clp); | ||
65 | extern u32 *nfs4_decode_dirent(u32 *p, struct nfs_entry *entry, int plus); | 67 | extern u32 *nfs4_decode_dirent(u32 *p, struct nfs_entry *entry, int plus); |
66 | extern struct rpc_procinfo nfs4_procedures[]; | 68 | extern struct rpc_procinfo nfs4_procedures[]; |
67 | 69 | ||
@@ -173,8 +175,7 @@ static void nfs4_setup_readdir(u64 cookie, u32 *verifier, struct dentry *dentry, | |||
173 | kunmap_atomic(start, KM_USER0); | 175 | kunmap_atomic(start, KM_USER0); |
174 | } | 176 | } |
175 | 177 | ||
176 | static void | 178 | static void renew_lease(const struct nfs_server *server, unsigned long timestamp) |
177 | renew_lease(struct nfs_server *server, unsigned long timestamp) | ||
178 | { | 179 | { |
179 | struct nfs4_client *clp = server->nfs4_state; | 180 | struct nfs4_client *clp = server->nfs4_state; |
180 | spin_lock(&clp->cl_lock); | 181 | spin_lock(&clp->cl_lock); |
@@ -194,21 +195,123 @@ static void update_changeattr(struct inode *inode, struct nfs4_change_info *cinf | |||
194 | spin_unlock(&inode->i_lock); | 195 | spin_unlock(&inode->i_lock); |
195 | } | 196 | } |
196 | 197 | ||
198 | struct nfs4_opendata { | ||
199 | atomic_t count; | ||
200 | struct nfs_openargs o_arg; | ||
201 | struct nfs_openres o_res; | ||
202 | struct nfs_open_confirmargs c_arg; | ||
203 | struct nfs_open_confirmres c_res; | ||
204 | struct nfs_fattr f_attr; | ||
205 | struct nfs_fattr dir_attr; | ||
206 | struct dentry *dentry; | ||
207 | struct dentry *dir; | ||
208 | struct nfs4_state_owner *owner; | ||
209 | struct iattr attrs; | ||
210 | unsigned long timestamp; | ||
211 | int rpc_status; | ||
212 | int cancelled; | ||
213 | }; | ||
214 | |||
215 | static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry, | ||
216 | struct nfs4_state_owner *sp, int flags, | ||
217 | const struct iattr *attrs) | ||
218 | { | ||
219 | struct dentry *parent = dget_parent(dentry); | ||
220 | struct inode *dir = parent->d_inode; | ||
221 | struct nfs_server *server = NFS_SERVER(dir); | ||
222 | struct nfs4_opendata *p; | ||
223 | |||
224 | p = kzalloc(sizeof(*p), GFP_KERNEL); | ||
225 | if (p == NULL) | ||
226 | goto err; | ||
227 | p->o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid); | ||
228 | if (p->o_arg.seqid == NULL) | ||
229 | goto err_free; | ||
230 | atomic_set(&p->count, 1); | ||
231 | p->dentry = dget(dentry); | ||
232 | p->dir = parent; | ||
233 | p->owner = sp; | ||
234 | atomic_inc(&sp->so_count); | ||
235 | p->o_arg.fh = NFS_FH(dir); | ||
236 | p->o_arg.open_flags = flags, | ||
237 | p->o_arg.clientid = server->nfs4_state->cl_clientid; | ||
238 | p->o_arg.id = sp->so_id; | ||
239 | p->o_arg.name = &dentry->d_name; | ||
240 | p->o_arg.server = server; | ||
241 | p->o_arg.bitmask = server->attr_bitmask; | ||
242 | p->o_arg.claim = NFS4_OPEN_CLAIM_NULL; | ||
243 | p->o_res.f_attr = &p->f_attr; | ||
244 | p->o_res.dir_attr = &p->dir_attr; | ||
245 | p->o_res.server = server; | ||
246 | nfs_fattr_init(&p->f_attr); | ||
247 | nfs_fattr_init(&p->dir_attr); | ||
248 | if (flags & O_EXCL) { | ||
249 | u32 *s = (u32 *) p->o_arg.u.verifier.data; | ||
250 | s[0] = jiffies; | ||
251 | s[1] = current->pid; | ||
252 | } else if (flags & O_CREAT) { | ||
253 | p->o_arg.u.attrs = &p->attrs; | ||
254 | memcpy(&p->attrs, attrs, sizeof(p->attrs)); | ||
255 | } | ||
256 | p->c_arg.fh = &p->o_res.fh; | ||
257 | p->c_arg.stateid = &p->o_res.stateid; | ||
258 | p->c_arg.seqid = p->o_arg.seqid; | ||
259 | return p; | ||
260 | err_free: | ||
261 | kfree(p); | ||
262 | err: | ||
263 | dput(parent); | ||
264 | return NULL; | ||
265 | } | ||
266 | |||
267 | static void nfs4_opendata_free(struct nfs4_opendata *p) | ||
268 | { | ||
269 | if (p != NULL && atomic_dec_and_test(&p->count)) { | ||
270 | nfs_free_seqid(p->o_arg.seqid); | ||
271 | nfs4_put_state_owner(p->owner); | ||
272 | dput(p->dir); | ||
273 | dput(p->dentry); | ||
274 | kfree(p); | ||
275 | } | ||
276 | } | ||
277 | |||
197 | /* Helper for asynchronous RPC calls */ | 278 | /* Helper for asynchronous RPC calls */ |
198 | static int nfs4_call_async(struct rpc_clnt *clnt, rpc_action tk_begin, | 279 | static int nfs4_call_async(struct rpc_clnt *clnt, |
199 | rpc_action tk_exit, void *calldata) | 280 | const struct rpc_call_ops *tk_ops, void *calldata) |
200 | { | 281 | { |
201 | struct rpc_task *task; | 282 | struct rpc_task *task; |
202 | 283 | ||
203 | if (!(task = rpc_new_task(clnt, tk_exit, RPC_TASK_ASYNC))) | 284 | if (!(task = rpc_new_task(clnt, RPC_TASK_ASYNC, tk_ops, calldata))) |
204 | return -ENOMEM; | 285 | return -ENOMEM; |
205 | |||
206 | task->tk_calldata = calldata; | ||
207 | task->tk_action = tk_begin; | ||
208 | rpc_execute(task); | 286 | rpc_execute(task); |
209 | return 0; | 287 | return 0; |
210 | } | 288 | } |
211 | 289 | ||
290 | static int nfs4_wait_for_completion_rpc_task(struct rpc_task *task) | ||
291 | { | ||
292 | sigset_t oldset; | ||
293 | int ret; | ||
294 | |||
295 | rpc_clnt_sigmask(task->tk_client, &oldset); | ||
296 | ret = rpc_wait_for_completion_task(task); | ||
297 | rpc_clnt_sigunmask(task->tk_client, &oldset); | ||
298 | return ret; | ||
299 | } | ||
300 | |||
301 | static inline void update_open_stateflags(struct nfs4_state *state, mode_t open_flags) | ||
302 | { | ||
303 | switch (open_flags) { | ||
304 | case FMODE_WRITE: | ||
305 | state->n_wronly++; | ||
306 | break; | ||
307 | case FMODE_READ: | ||
308 | state->n_rdonly++; | ||
309 | break; | ||
310 | case FMODE_READ|FMODE_WRITE: | ||
311 | state->n_rdwr++; | ||
312 | } | ||
313 | } | ||
314 | |||
212 | static void update_open_stateid(struct nfs4_state *state, nfs4_stateid *stateid, int open_flags) | 315 | static void update_open_stateid(struct nfs4_state *state, nfs4_stateid *stateid, int open_flags) |
213 | { | 316 | { |
214 | struct inode *inode = state->inode; | 317 | struct inode *inode = state->inode; |
@@ -218,41 +321,134 @@ static void update_open_stateid(struct nfs4_state *state, nfs4_stateid *stateid, | |||
218 | spin_lock(&state->owner->so_lock); | 321 | spin_lock(&state->owner->so_lock); |
219 | spin_lock(&inode->i_lock); | 322 | spin_lock(&inode->i_lock); |
220 | memcpy(&state->stateid, stateid, sizeof(state->stateid)); | 323 | memcpy(&state->stateid, stateid, sizeof(state->stateid)); |
221 | if ((open_flags & FMODE_WRITE)) | 324 | update_open_stateflags(state, open_flags); |
222 | state->nwriters++; | ||
223 | if (open_flags & FMODE_READ) | ||
224 | state->nreaders++; | ||
225 | nfs4_state_set_mode_locked(state, state->state | open_flags); | 325 | nfs4_state_set_mode_locked(state, state->state | open_flags); |
226 | spin_unlock(&inode->i_lock); | 326 | spin_unlock(&inode->i_lock); |
227 | spin_unlock(&state->owner->so_lock); | 327 | spin_unlock(&state->owner->so_lock); |
228 | } | 328 | } |
229 | 329 | ||
330 | static struct nfs4_state *nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data) | ||
331 | { | ||
332 | struct inode *inode; | ||
333 | struct nfs4_state *state = NULL; | ||
334 | |||
335 | if (!(data->f_attr.valid & NFS_ATTR_FATTR)) | ||
336 | goto out; | ||
337 | inode = nfs_fhget(data->dir->d_sb, &data->o_res.fh, &data->f_attr); | ||
338 | if (inode == NULL) | ||
339 | goto out; | ||
340 | state = nfs4_get_open_state(inode, data->owner); | ||
341 | if (state == NULL) | ||
342 | goto put_inode; | ||
343 | update_open_stateid(state, &data->o_res.stateid, data->o_arg.open_flags); | ||
344 | put_inode: | ||
345 | iput(inode); | ||
346 | out: | ||
347 | return state; | ||
348 | } | ||
349 | |||
350 | static struct nfs_open_context *nfs4_state_find_open_context(struct nfs4_state *state) | ||
351 | { | ||
352 | struct nfs_inode *nfsi = NFS_I(state->inode); | ||
353 | struct nfs_open_context *ctx; | ||
354 | |||
355 | spin_lock(&state->inode->i_lock); | ||
356 | list_for_each_entry(ctx, &nfsi->open_files, list) { | ||
357 | if (ctx->state != state) | ||
358 | continue; | ||
359 | get_nfs_open_context(ctx); | ||
360 | spin_unlock(&state->inode->i_lock); | ||
361 | return ctx; | ||
362 | } | ||
363 | spin_unlock(&state->inode->i_lock); | ||
364 | return ERR_PTR(-ENOENT); | ||
365 | } | ||
366 | |||
367 | static int nfs4_open_recover_helper(struct nfs4_opendata *opendata, mode_t openflags, nfs4_stateid *stateid) | ||
368 | { | ||
369 | int ret; | ||
370 | |||
371 | opendata->o_arg.open_flags = openflags; | ||
372 | ret = _nfs4_proc_open(opendata); | ||
373 | if (ret != 0) | ||
374 | return ret; | ||
375 | memcpy(stateid->data, opendata->o_res.stateid.data, | ||
376 | sizeof(stateid->data)); | ||
377 | return 0; | ||
378 | } | ||
379 | |||
380 | static int nfs4_open_recover(struct nfs4_opendata *opendata, struct nfs4_state *state) | ||
381 | { | ||
382 | nfs4_stateid stateid; | ||
383 | struct nfs4_state *newstate; | ||
384 | int mode = 0; | ||
385 | int delegation = 0; | ||
386 | int ret; | ||
387 | |||
388 | /* memory barrier prior to reading state->n_* */ | ||
389 | smp_rmb(); | ||
390 | if (state->n_rdwr != 0) { | ||
391 | ret = nfs4_open_recover_helper(opendata, FMODE_READ|FMODE_WRITE, &stateid); | ||
392 | if (ret != 0) | ||
393 | return ret; | ||
394 | mode |= FMODE_READ|FMODE_WRITE; | ||
395 | if (opendata->o_res.delegation_type != 0) | ||
396 | delegation = opendata->o_res.delegation_type; | ||
397 | smp_rmb(); | ||
398 | } | ||
399 | if (state->n_wronly != 0) { | ||
400 | ret = nfs4_open_recover_helper(opendata, FMODE_WRITE, &stateid); | ||
401 | if (ret != 0) | ||
402 | return ret; | ||
403 | mode |= FMODE_WRITE; | ||
404 | if (opendata->o_res.delegation_type != 0) | ||
405 | delegation = opendata->o_res.delegation_type; | ||
406 | smp_rmb(); | ||
407 | } | ||
408 | if (state->n_rdonly != 0) { | ||
409 | ret = nfs4_open_recover_helper(opendata, FMODE_READ, &stateid); | ||
410 | if (ret != 0) | ||
411 | return ret; | ||
412 | mode |= FMODE_READ; | ||
413 | } | ||
414 | clear_bit(NFS_DELEGATED_STATE, &state->flags); | ||
415 | if (mode == 0) | ||
416 | return 0; | ||
417 | if (opendata->o_res.delegation_type == 0) | ||
418 | opendata->o_res.delegation_type = delegation; | ||
419 | opendata->o_arg.open_flags |= mode; | ||
420 | newstate = nfs4_opendata_to_nfs4_state(opendata); | ||
421 | if (newstate != NULL) { | ||
422 | if (opendata->o_res.delegation_type != 0) { | ||
423 | struct nfs_inode *nfsi = NFS_I(newstate->inode); | ||
424 | int delegation_flags = 0; | ||
425 | if (nfsi->delegation) | ||
426 | delegation_flags = nfsi->delegation->flags; | ||
427 | if (!(delegation_flags & NFS_DELEGATION_NEED_RECLAIM)) | ||
428 | nfs_inode_set_delegation(newstate->inode, | ||
429 | opendata->owner->so_cred, | ||
430 | &opendata->o_res); | ||
431 | else | ||
432 | nfs_inode_reclaim_delegation(newstate->inode, | ||
433 | opendata->owner->so_cred, | ||
434 | &opendata->o_res); | ||
435 | } | ||
436 | nfs4_close_state(newstate, opendata->o_arg.open_flags); | ||
437 | } | ||
438 | if (newstate != state) | ||
439 | return -ESTALE; | ||
440 | return 0; | ||
441 | } | ||
442 | |||
230 | /* | 443 | /* |
231 | * OPEN_RECLAIM: | 444 | * OPEN_RECLAIM: |
232 | * reclaim state on the server after a reboot. | 445 | * reclaim state on the server after a reboot. |
233 | */ | 446 | */ |
234 | static int _nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *state) | 447 | static int _nfs4_do_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *state, struct dentry *dentry) |
235 | { | 448 | { |
236 | struct inode *inode = state->inode; | 449 | struct nfs_delegation *delegation = NFS_I(state->inode)->delegation; |
237 | struct nfs_server *server = NFS_SERVER(inode); | 450 | struct nfs4_opendata *opendata; |
238 | struct nfs_delegation *delegation = NFS_I(inode)->delegation; | 451 | int delegation_type = 0; |
239 | struct nfs_openargs o_arg = { | ||
240 | .fh = NFS_FH(inode), | ||
241 | .id = sp->so_id, | ||
242 | .open_flags = state->state, | ||
243 | .clientid = server->nfs4_state->cl_clientid, | ||
244 | .claim = NFS4_OPEN_CLAIM_PREVIOUS, | ||
245 | .bitmask = server->attr_bitmask, | ||
246 | }; | ||
247 | struct nfs_openres o_res = { | ||
248 | .server = server, /* Grrr */ | ||
249 | }; | ||
250 | struct rpc_message msg = { | ||
251 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR], | ||
252 | .rpc_argp = &o_arg, | ||
253 | .rpc_resp = &o_res, | ||
254 | .rpc_cred = sp->so_cred, | ||
255 | }; | ||
256 | int status; | 452 | int status; |
257 | 453 | ||
258 | if (delegation != NULL) { | 454 | if (delegation != NULL) { |
@@ -262,38 +458,27 @@ static int _nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *st | |||
262 | set_bit(NFS_DELEGATED_STATE, &state->flags); | 458 | set_bit(NFS_DELEGATED_STATE, &state->flags); |
263 | return 0; | 459 | return 0; |
264 | } | 460 | } |
265 | o_arg.u.delegation_type = delegation->type; | 461 | delegation_type = delegation->type; |
266 | } | 462 | } |
267 | o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid); | 463 | opendata = nfs4_opendata_alloc(dentry, sp, 0, NULL); |
268 | if (o_arg.seqid == NULL) | 464 | if (opendata == NULL) |
269 | return -ENOMEM; | 465 | return -ENOMEM; |
270 | status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR); | 466 | opendata->o_arg.claim = NFS4_OPEN_CLAIM_PREVIOUS; |
271 | /* Confirm the sequence as being established */ | 467 | opendata->o_arg.fh = NFS_FH(state->inode); |
272 | nfs_confirm_seqid(&sp->so_seqid, status); | 468 | nfs_copy_fh(&opendata->o_res.fh, opendata->o_arg.fh); |
273 | nfs_increment_open_seqid(status, o_arg.seqid); | 469 | opendata->o_arg.u.delegation_type = delegation_type; |
274 | if (status == 0) { | 470 | status = nfs4_open_recover(opendata, state); |
275 | memcpy(&state->stateid, &o_res.stateid, sizeof(state->stateid)); | 471 | nfs4_opendata_free(opendata); |
276 | if (o_res.delegation_type != 0) { | ||
277 | nfs_inode_reclaim_delegation(inode, sp->so_cred, &o_res); | ||
278 | /* Did the server issue an immediate delegation recall? */ | ||
279 | if (o_res.do_recall) | ||
280 | nfs_async_inode_return_delegation(inode, &o_res.stateid); | ||
281 | } | ||
282 | } | ||
283 | nfs_free_seqid(o_arg.seqid); | ||
284 | clear_bit(NFS_DELEGATED_STATE, &state->flags); | ||
285 | /* Ensure we update the inode attributes */ | ||
286 | NFS_CACHEINV(inode); | ||
287 | return status; | 472 | return status; |
288 | } | 473 | } |
289 | 474 | ||
290 | static int nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *state) | 475 | static int nfs4_do_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *state, struct dentry *dentry) |
291 | { | 476 | { |
292 | struct nfs_server *server = NFS_SERVER(state->inode); | 477 | struct nfs_server *server = NFS_SERVER(state->inode); |
293 | struct nfs4_exception exception = { }; | 478 | struct nfs4_exception exception = { }; |
294 | int err; | 479 | int err; |
295 | do { | 480 | do { |
296 | err = _nfs4_open_reclaim(sp, state); | 481 | err = _nfs4_do_open_reclaim(sp, state, dentry); |
297 | if (err != -NFS4ERR_DELAY) | 482 | if (err != -NFS4ERR_DELAY) |
298 | break; | 483 | break; |
299 | nfs4_handle_exception(server, err, &exception); | 484 | nfs4_handle_exception(server, err, &exception); |
@@ -301,63 +486,36 @@ static int nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *sta | |||
301 | return err; | 486 | return err; |
302 | } | 487 | } |
303 | 488 | ||
489 | static int nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *state) | ||
490 | { | ||
491 | struct nfs_open_context *ctx; | ||
492 | int ret; | ||
493 | |||
494 | ctx = nfs4_state_find_open_context(state); | ||
495 | if (IS_ERR(ctx)) | ||
496 | return PTR_ERR(ctx); | ||
497 | ret = nfs4_do_open_reclaim(sp, state, ctx->dentry); | ||
498 | put_nfs_open_context(ctx); | ||
499 | return ret; | ||
500 | } | ||
501 | |||
304 | static int _nfs4_open_delegation_recall(struct dentry *dentry, struct nfs4_state *state) | 502 | static int _nfs4_open_delegation_recall(struct dentry *dentry, struct nfs4_state *state) |
305 | { | 503 | { |
306 | struct nfs4_state_owner *sp = state->owner; | 504 | struct nfs4_state_owner *sp = state->owner; |
307 | struct inode *inode = dentry->d_inode; | 505 | struct nfs4_opendata *opendata; |
308 | struct nfs_server *server = NFS_SERVER(inode); | 506 | int ret; |
309 | struct dentry *parent = dget_parent(dentry); | ||
310 | struct nfs_openargs arg = { | ||
311 | .fh = NFS_FH(parent->d_inode), | ||
312 | .clientid = server->nfs4_state->cl_clientid, | ||
313 | .name = &dentry->d_name, | ||
314 | .id = sp->so_id, | ||
315 | .server = server, | ||
316 | .bitmask = server->attr_bitmask, | ||
317 | .claim = NFS4_OPEN_CLAIM_DELEGATE_CUR, | ||
318 | }; | ||
319 | struct nfs_openres res = { | ||
320 | .server = server, | ||
321 | }; | ||
322 | struct rpc_message msg = { | ||
323 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR], | ||
324 | .rpc_argp = &arg, | ||
325 | .rpc_resp = &res, | ||
326 | .rpc_cred = sp->so_cred, | ||
327 | }; | ||
328 | int status = 0; | ||
329 | 507 | ||
330 | if (!test_bit(NFS_DELEGATED_STATE, &state->flags)) | 508 | if (!test_bit(NFS_DELEGATED_STATE, &state->flags)) |
331 | goto out; | 509 | return 0; |
332 | if (state->state == 0) | 510 | opendata = nfs4_opendata_alloc(dentry, sp, 0, NULL); |
333 | goto out; | 511 | if (opendata == NULL) |
334 | arg.seqid = nfs_alloc_seqid(&sp->so_seqid); | 512 | return -ENOMEM; |
335 | status = -ENOMEM; | 513 | opendata->o_arg.claim = NFS4_OPEN_CLAIM_DELEGATE_CUR; |
336 | if (arg.seqid == NULL) | 514 | memcpy(opendata->o_arg.u.delegation.data, state->stateid.data, |
337 | goto out; | 515 | sizeof(opendata->o_arg.u.delegation.data)); |
338 | arg.open_flags = state->state; | 516 | ret = nfs4_open_recover(opendata, state); |
339 | memcpy(arg.u.delegation.data, state->stateid.data, sizeof(arg.u.delegation.data)); | 517 | nfs4_opendata_free(opendata); |
340 | status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR); | 518 | return ret; |
341 | nfs_increment_open_seqid(status, arg.seqid); | ||
342 | if (status != 0) | ||
343 | goto out_free; | ||
344 | if(res.rflags & NFS4_OPEN_RESULT_CONFIRM) { | ||
345 | status = _nfs4_proc_open_confirm(server->client, NFS_FH(inode), | ||
346 | sp, &res.stateid, arg.seqid); | ||
347 | if (status != 0) | ||
348 | goto out_free; | ||
349 | } | ||
350 | nfs_confirm_seqid(&sp->so_seqid, 0); | ||
351 | if (status >= 0) { | ||
352 | memcpy(state->stateid.data, res.stateid.data, | ||
353 | sizeof(state->stateid.data)); | ||
354 | clear_bit(NFS_DELEGATED_STATE, &state->flags); | ||
355 | } | ||
356 | out_free: | ||
357 | nfs_free_seqid(arg.seqid); | ||
358 | out: | ||
359 | dput(parent); | ||
360 | return status; | ||
361 | } | 519 | } |
362 | 520 | ||
363 | int nfs4_open_delegation_recall(struct dentry *dentry, struct nfs4_state *state) | 521 | int nfs4_open_delegation_recall(struct dentry *dentry, struct nfs4_state *state) |
@@ -382,82 +540,202 @@ int nfs4_open_delegation_recall(struct dentry *dentry, struct nfs4_state *state) | |||
382 | return err; | 540 | return err; |
383 | } | 541 | } |
384 | 542 | ||
385 | static int _nfs4_proc_open_confirm(struct rpc_clnt *clnt, const struct nfs_fh *fh, struct nfs4_state_owner *sp, nfs4_stateid *stateid, struct nfs_seqid *seqid) | 543 | static void nfs4_open_confirm_prepare(struct rpc_task *task, void *calldata) |
386 | { | 544 | { |
387 | struct nfs_open_confirmargs arg = { | 545 | struct nfs4_opendata *data = calldata; |
388 | .fh = fh, | 546 | struct rpc_message msg = { |
389 | .seqid = seqid, | 547 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_CONFIRM], |
390 | .stateid = *stateid, | 548 | .rpc_argp = &data->c_arg, |
391 | }; | 549 | .rpc_resp = &data->c_res, |
392 | struct nfs_open_confirmres res; | 550 | .rpc_cred = data->owner->so_cred, |
393 | struct rpc_message msg = { | ||
394 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_CONFIRM], | ||
395 | .rpc_argp = &arg, | ||
396 | .rpc_resp = &res, | ||
397 | .rpc_cred = sp->so_cred, | ||
398 | }; | 551 | }; |
552 | data->timestamp = jiffies; | ||
553 | rpc_call_setup(task, &msg, 0); | ||
554 | } | ||
555 | |||
556 | static void nfs4_open_confirm_done(struct rpc_task *task, void *calldata) | ||
557 | { | ||
558 | struct nfs4_opendata *data = calldata; | ||
559 | |||
560 | data->rpc_status = task->tk_status; | ||
561 | if (RPC_ASSASSINATED(task)) | ||
562 | return; | ||
563 | if (data->rpc_status == 0) { | ||
564 | memcpy(data->o_res.stateid.data, data->c_res.stateid.data, | ||
565 | sizeof(data->o_res.stateid.data)); | ||
566 | renew_lease(data->o_res.server, data->timestamp); | ||
567 | } | ||
568 | nfs_increment_open_seqid(data->rpc_status, data->c_arg.seqid); | ||
569 | nfs_confirm_seqid(&data->owner->so_seqid, data->rpc_status); | ||
570 | } | ||
571 | |||
572 | static void nfs4_open_confirm_release(void *calldata) | ||
573 | { | ||
574 | struct nfs4_opendata *data = calldata; | ||
575 | struct nfs4_state *state = NULL; | ||
576 | |||
577 | /* If this request hasn't been cancelled, do nothing */ | ||
578 | if (data->cancelled == 0) | ||
579 | goto out_free; | ||
580 | /* In case of error, no cleanup! */ | ||
581 | if (data->rpc_status != 0) | ||
582 | goto out_free; | ||
583 | nfs_confirm_seqid(&data->owner->so_seqid, 0); | ||
584 | state = nfs4_opendata_to_nfs4_state(data); | ||
585 | if (state != NULL) | ||
586 | nfs4_close_state(state, data->o_arg.open_flags); | ||
587 | out_free: | ||
588 | nfs4_opendata_free(data); | ||
589 | } | ||
590 | |||
591 | static const struct rpc_call_ops nfs4_open_confirm_ops = { | ||
592 | .rpc_call_prepare = nfs4_open_confirm_prepare, | ||
593 | .rpc_call_done = nfs4_open_confirm_done, | ||
594 | .rpc_release = nfs4_open_confirm_release, | ||
595 | }; | ||
596 | |||
597 | /* | ||
598 | * Note: On error, nfs4_proc_open_confirm will free the struct nfs4_opendata | ||
599 | */ | ||
600 | static int _nfs4_proc_open_confirm(struct nfs4_opendata *data) | ||
601 | { | ||
602 | struct nfs_server *server = NFS_SERVER(data->dir->d_inode); | ||
603 | struct rpc_task *task; | ||
399 | int status; | 604 | int status; |
400 | 605 | ||
401 | status = rpc_call_sync(clnt, &msg, RPC_TASK_NOINTR); | 606 | atomic_inc(&data->count); |
402 | /* Confirm the sequence as being established */ | 607 | task = rpc_run_task(server->client, RPC_TASK_ASYNC, &nfs4_open_confirm_ops, data); |
403 | nfs_confirm_seqid(&sp->so_seqid, status); | 608 | if (IS_ERR(task)) { |
404 | nfs_increment_open_seqid(status, seqid); | 609 | nfs4_opendata_free(data); |
405 | if (status >= 0) | 610 | return PTR_ERR(task); |
406 | memcpy(stateid, &res.stateid, sizeof(*stateid)); | 611 | } |
612 | status = nfs4_wait_for_completion_rpc_task(task); | ||
613 | if (status != 0) { | ||
614 | data->cancelled = 1; | ||
615 | smp_wmb(); | ||
616 | } else | ||
617 | status = data->rpc_status; | ||
618 | rpc_release_task(task); | ||
407 | return status; | 619 | return status; |
408 | } | 620 | } |
409 | 621 | ||
410 | static int _nfs4_proc_open(struct inode *dir, struct nfs4_state_owner *sp, struct nfs_openargs *o_arg, struct nfs_openres *o_res) | 622 | static void nfs4_open_prepare(struct rpc_task *task, void *calldata) |
411 | { | 623 | { |
412 | struct nfs_server *server = NFS_SERVER(dir); | 624 | struct nfs4_opendata *data = calldata; |
625 | struct nfs4_state_owner *sp = data->owner; | ||
413 | struct rpc_message msg = { | 626 | struct rpc_message msg = { |
414 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN], | 627 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN], |
415 | .rpc_argp = o_arg, | 628 | .rpc_argp = &data->o_arg, |
416 | .rpc_resp = o_res, | 629 | .rpc_resp = &data->o_res, |
417 | .rpc_cred = sp->so_cred, | 630 | .rpc_cred = sp->so_cred, |
418 | }; | 631 | }; |
419 | int status; | 632 | |
633 | if (nfs_wait_on_sequence(data->o_arg.seqid, task) != 0) | ||
634 | return; | ||
635 | /* Update sequence id. */ | ||
636 | data->o_arg.id = sp->so_id; | ||
637 | data->o_arg.clientid = sp->so_client->cl_clientid; | ||
638 | if (data->o_arg.claim == NFS4_OPEN_CLAIM_PREVIOUS) | ||
639 | msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR]; | ||
640 | data->timestamp = jiffies; | ||
641 | rpc_call_setup(task, &msg, 0); | ||
642 | } | ||
420 | 643 | ||
421 | /* Update sequence id. The caller must serialize! */ | 644 | static void nfs4_open_done(struct rpc_task *task, void *calldata) |
422 | o_arg->id = sp->so_id; | 645 | { |
423 | o_arg->clientid = sp->so_client->cl_clientid; | 646 | struct nfs4_opendata *data = calldata; |
424 | 647 | ||
425 | status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR); | 648 | data->rpc_status = task->tk_status; |
426 | if (status == 0) { | 649 | if (RPC_ASSASSINATED(task)) |
427 | /* OPEN on anything except a regular file is disallowed in NFSv4 */ | 650 | return; |
428 | switch (o_res->f_attr->mode & S_IFMT) { | 651 | if (task->tk_status == 0) { |
652 | switch (data->o_res.f_attr->mode & S_IFMT) { | ||
429 | case S_IFREG: | 653 | case S_IFREG: |
430 | break; | 654 | break; |
431 | case S_IFLNK: | 655 | case S_IFLNK: |
432 | status = -ELOOP; | 656 | data->rpc_status = -ELOOP; |
433 | break; | 657 | break; |
434 | case S_IFDIR: | 658 | case S_IFDIR: |
435 | status = -EISDIR; | 659 | data->rpc_status = -EISDIR; |
436 | break; | 660 | break; |
437 | default: | 661 | default: |
438 | status = -ENOTDIR; | 662 | data->rpc_status = -ENOTDIR; |
439 | } | 663 | } |
664 | renew_lease(data->o_res.server, data->timestamp); | ||
440 | } | 665 | } |
666 | nfs_increment_open_seqid(data->rpc_status, data->o_arg.seqid); | ||
667 | } | ||
668 | |||
669 | static void nfs4_open_release(void *calldata) | ||
670 | { | ||
671 | struct nfs4_opendata *data = calldata; | ||
672 | struct nfs4_state *state = NULL; | ||
441 | 673 | ||
442 | nfs_increment_open_seqid(status, o_arg->seqid); | 674 | /* If this request hasn't been cancelled, do nothing */ |
675 | if (data->cancelled == 0) | ||
676 | goto out_free; | ||
677 | /* In case of error, no cleanup! */ | ||
678 | if (data->rpc_status != 0) | ||
679 | goto out_free; | ||
680 | /* In case we need an open_confirm, no cleanup! */ | ||
681 | if (data->o_res.rflags & NFS4_OPEN_RESULT_CONFIRM) | ||
682 | goto out_free; | ||
683 | nfs_confirm_seqid(&data->owner->so_seqid, 0); | ||
684 | state = nfs4_opendata_to_nfs4_state(data); | ||
685 | if (state != NULL) | ||
686 | nfs4_close_state(state, data->o_arg.open_flags); | ||
687 | out_free: | ||
688 | nfs4_opendata_free(data); | ||
689 | } | ||
690 | |||
691 | static const struct rpc_call_ops nfs4_open_ops = { | ||
692 | .rpc_call_prepare = nfs4_open_prepare, | ||
693 | .rpc_call_done = nfs4_open_done, | ||
694 | .rpc_release = nfs4_open_release, | ||
695 | }; | ||
696 | |||
697 | /* | ||
698 | * Note: On error, nfs4_proc_open will free the struct nfs4_opendata | ||
699 | */ | ||
700 | static int _nfs4_proc_open(struct nfs4_opendata *data) | ||
701 | { | ||
702 | struct inode *dir = data->dir->d_inode; | ||
703 | struct nfs_server *server = NFS_SERVER(dir); | ||
704 | struct nfs_openargs *o_arg = &data->o_arg; | ||
705 | struct nfs_openres *o_res = &data->o_res; | ||
706 | struct rpc_task *task; | ||
707 | int status; | ||
708 | |||
709 | atomic_inc(&data->count); | ||
710 | task = rpc_run_task(server->client, RPC_TASK_ASYNC, &nfs4_open_ops, data); | ||
711 | if (IS_ERR(task)) { | ||
712 | nfs4_opendata_free(data); | ||
713 | return PTR_ERR(task); | ||
714 | } | ||
715 | status = nfs4_wait_for_completion_rpc_task(task); | ||
716 | if (status != 0) { | ||
717 | data->cancelled = 1; | ||
718 | smp_wmb(); | ||
719 | } else | ||
720 | status = data->rpc_status; | ||
721 | rpc_release_task(task); | ||
443 | if (status != 0) | 722 | if (status != 0) |
444 | goto out; | 723 | return status; |
724 | |||
445 | if (o_arg->open_flags & O_CREAT) { | 725 | if (o_arg->open_flags & O_CREAT) { |
446 | update_changeattr(dir, &o_res->cinfo); | 726 | update_changeattr(dir, &o_res->cinfo); |
447 | nfs_post_op_update_inode(dir, o_res->dir_attr); | 727 | nfs_post_op_update_inode(dir, o_res->dir_attr); |
448 | } else | 728 | } else |
449 | nfs_refresh_inode(dir, o_res->dir_attr); | 729 | nfs_refresh_inode(dir, o_res->dir_attr); |
450 | if(o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) { | 730 | if(o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) { |
451 | status = _nfs4_proc_open_confirm(server->client, &o_res->fh, | 731 | status = _nfs4_proc_open_confirm(data); |
452 | sp, &o_res->stateid, o_arg->seqid); | ||
453 | if (status != 0) | 732 | if (status != 0) |
454 | goto out; | 733 | return status; |
455 | } | 734 | } |
456 | nfs_confirm_seqid(&sp->so_seqid, 0); | 735 | nfs_confirm_seqid(&data->owner->so_seqid, 0); |
457 | if (!(o_res->f_attr->valid & NFS_ATTR_FATTR)) | 736 | if (!(o_res->f_attr->valid & NFS_ATTR_FATTR)) |
458 | status = server->rpc_ops->getattr(server, &o_res->fh, o_res->f_attr); | 737 | return server->rpc_ops->getattr(server, &o_res->fh, o_res->f_attr); |
459 | out: | 738 | return 0; |
460 | return status; | ||
461 | } | 739 | } |
462 | 740 | ||
463 | static int _nfs4_do_access(struct inode *inode, struct rpc_cred *cred, int openflags) | 741 | static int _nfs4_do_access(struct inode *inode, struct rpc_cred *cred, int openflags) |
@@ -488,6 +766,15 @@ out: | |||
488 | return -EACCES; | 766 | return -EACCES; |
489 | } | 767 | } |
490 | 768 | ||
769 | int nfs4_recover_expired_lease(struct nfs_server *server) | ||
770 | { | ||
771 | struct nfs4_client *clp = server->nfs4_state; | ||
772 | |||
773 | if (test_and_clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) | ||
774 | nfs4_schedule_state_recovery(clp); | ||
775 | return nfs4_wait_clnt_recover(server->client, clp); | ||
776 | } | ||
777 | |||
491 | /* | 778 | /* |
492 | * OPEN_EXPIRED: | 779 | * OPEN_EXPIRED: |
493 | * reclaim state on the server after a network partition. | 780 | * reclaim state on the server after a network partition. |
@@ -495,77 +782,31 @@ out: | |||
495 | */ | 782 | */ |
496 | static int _nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *state, struct dentry *dentry) | 783 | static int _nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *state, struct dentry *dentry) |
497 | { | 784 | { |
498 | struct dentry *parent = dget_parent(dentry); | ||
499 | struct inode *dir = parent->d_inode; | ||
500 | struct inode *inode = state->inode; | 785 | struct inode *inode = state->inode; |
501 | struct nfs_server *server = NFS_SERVER(dir); | ||
502 | struct nfs_delegation *delegation = NFS_I(inode)->delegation; | 786 | struct nfs_delegation *delegation = NFS_I(inode)->delegation; |
503 | struct nfs_fattr f_attr, dir_attr; | 787 | struct nfs4_opendata *opendata; |
504 | struct nfs_openargs o_arg = { | 788 | int openflags = state->state & (FMODE_READ|FMODE_WRITE); |
505 | .fh = NFS_FH(dir), | 789 | int ret; |
506 | .open_flags = state->state, | ||
507 | .name = &dentry->d_name, | ||
508 | .bitmask = server->attr_bitmask, | ||
509 | .claim = NFS4_OPEN_CLAIM_NULL, | ||
510 | }; | ||
511 | struct nfs_openres o_res = { | ||
512 | .f_attr = &f_attr, | ||
513 | .dir_attr = &dir_attr, | ||
514 | .server = server, | ||
515 | }; | ||
516 | int status = 0; | ||
517 | 790 | ||
518 | if (delegation != NULL && !(delegation->flags & NFS_DELEGATION_NEED_RECLAIM)) { | 791 | if (delegation != NULL && !(delegation->flags & NFS_DELEGATION_NEED_RECLAIM)) { |
519 | status = _nfs4_do_access(inode, sp->so_cred, state->state); | 792 | ret = _nfs4_do_access(inode, sp->so_cred, openflags); |
520 | if (status < 0) | 793 | if (ret < 0) |
521 | goto out; | 794 | return ret; |
522 | memcpy(&state->stateid, &delegation->stateid, sizeof(state->stateid)); | 795 | memcpy(&state->stateid, &delegation->stateid, sizeof(state->stateid)); |
523 | set_bit(NFS_DELEGATED_STATE, &state->flags); | 796 | set_bit(NFS_DELEGATED_STATE, &state->flags); |
524 | goto out; | 797 | return 0; |
525 | } | 798 | } |
526 | o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid); | 799 | opendata = nfs4_opendata_alloc(dentry, sp, openflags, NULL); |
527 | status = -ENOMEM; | 800 | if (opendata == NULL) |
528 | if (o_arg.seqid == NULL) | 801 | return -ENOMEM; |
529 | goto out; | 802 | ret = nfs4_open_recover(opendata, state); |
530 | nfs_fattr_init(&f_attr); | 803 | if (ret == -ESTALE) { |
531 | nfs_fattr_init(&dir_attr); | 804 | /* Invalidate the state owner so we don't ever use it again */ |
532 | status = _nfs4_proc_open(dir, sp, &o_arg, &o_res); | 805 | nfs4_drop_state_owner(sp); |
533 | if (status != 0) | 806 | d_drop(dentry); |
534 | goto out_nodeleg; | ||
535 | /* Check if files differ */ | ||
536 | if ((f_attr.mode & S_IFMT) != (inode->i_mode & S_IFMT)) | ||
537 | goto out_stale; | ||
538 | /* Has the file handle changed? */ | ||
539 | if (nfs_compare_fh(&o_res.fh, NFS_FH(inode)) != 0) { | ||
540 | /* Verify if the change attributes are the same */ | ||
541 | if (f_attr.change_attr != NFS_I(inode)->change_attr) | ||
542 | goto out_stale; | ||
543 | if (nfs_size_to_loff_t(f_attr.size) != inode->i_size) | ||
544 | goto out_stale; | ||
545 | /* Lets just pretend that this is the same file */ | ||
546 | nfs_copy_fh(NFS_FH(inode), &o_res.fh); | ||
547 | NFS_I(inode)->fileid = f_attr.fileid; | ||
548 | } | ||
549 | memcpy(&state->stateid, &o_res.stateid, sizeof(state->stateid)); | ||
550 | if (o_res.delegation_type != 0) { | ||
551 | if (!(delegation->flags & NFS_DELEGATION_NEED_RECLAIM)) | ||
552 | nfs_inode_set_delegation(inode, sp->so_cred, &o_res); | ||
553 | else | ||
554 | nfs_inode_reclaim_delegation(inode, sp->so_cred, &o_res); | ||
555 | } | 807 | } |
556 | out_nodeleg: | 808 | nfs4_opendata_free(opendata); |
557 | nfs_free_seqid(o_arg.seqid); | 809 | return ret; |
558 | clear_bit(NFS_DELEGATED_STATE, &state->flags); | ||
559 | out: | ||
560 | dput(parent); | ||
561 | return status; | ||
562 | out_stale: | ||
563 | status = -ESTALE; | ||
564 | /* Invalidate the state owner so we don't ever use it again */ | ||
565 | nfs4_drop_state_owner(sp); | ||
566 | d_drop(dentry); | ||
567 | /* Should we be trying to close that stateid? */ | ||
568 | goto out_nodeleg; | ||
569 | } | 810 | } |
570 | 811 | ||
571 | static inline int nfs4_do_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *state, struct dentry *dentry) | 812 | static inline int nfs4_do_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *state, struct dentry *dentry) |
@@ -584,26 +825,19 @@ static inline int nfs4_do_open_expired(struct nfs4_state_owner *sp, struct nfs4_ | |||
584 | 825 | ||
585 | static int nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *state) | 826 | static int nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *state) |
586 | { | 827 | { |
587 | struct nfs_inode *nfsi = NFS_I(state->inode); | ||
588 | struct nfs_open_context *ctx; | 828 | struct nfs_open_context *ctx; |
589 | int status; | 829 | int ret; |
590 | 830 | ||
591 | spin_lock(&state->inode->i_lock); | 831 | ctx = nfs4_state_find_open_context(state); |
592 | list_for_each_entry(ctx, &nfsi->open_files, list) { | 832 | if (IS_ERR(ctx)) |
593 | if (ctx->state != state) | 833 | return PTR_ERR(ctx); |
594 | continue; | 834 | ret = nfs4_do_open_expired(sp, state, ctx->dentry); |
595 | get_nfs_open_context(ctx); | 835 | put_nfs_open_context(ctx); |
596 | spin_unlock(&state->inode->i_lock); | 836 | return ret; |
597 | status = nfs4_do_open_expired(sp, state, ctx->dentry); | ||
598 | put_nfs_open_context(ctx); | ||
599 | return status; | ||
600 | } | ||
601 | spin_unlock(&state->inode->i_lock); | ||
602 | return -ENOENT; | ||
603 | } | 837 | } |
604 | 838 | ||
605 | /* | 839 | /* |
606 | * Returns an nfs4_state + an extra reference to the inode | 840 | * Returns a referenced nfs4_state if there is an open delegation on the file |
607 | */ | 841 | */ |
608 | static int _nfs4_open_delegated(struct inode *inode, int flags, struct rpc_cred *cred, struct nfs4_state **res) | 842 | static int _nfs4_open_delegated(struct inode *inode, int flags, struct rpc_cred *cred, struct nfs4_state **res) |
609 | { | 843 | { |
@@ -616,6 +850,14 @@ static int _nfs4_open_delegated(struct inode *inode, int flags, struct rpc_cred | |||
616 | int open_flags = flags & (FMODE_READ|FMODE_WRITE); | 850 | int open_flags = flags & (FMODE_READ|FMODE_WRITE); |
617 | int err; | 851 | int err; |
618 | 852 | ||
853 | err = -ENOMEM; | ||
854 | if (!(sp = nfs4_get_state_owner(server, cred))) { | ||
855 | dprintk("%s: nfs4_get_state_owner failed!\n", __FUNCTION__); | ||
856 | return err; | ||
857 | } | ||
858 | err = nfs4_recover_expired_lease(server); | ||
859 | if (err != 0) | ||
860 | goto out_put_state_owner; | ||
619 | /* Protect against reboot recovery - NOTE ORDER! */ | 861 | /* Protect against reboot recovery - NOTE ORDER! */ |
620 | down_read(&clp->cl_sem); | 862 | down_read(&clp->cl_sem); |
621 | /* Protect against delegation recall */ | 863 | /* Protect against delegation recall */ |
@@ -625,10 +867,6 @@ static int _nfs4_open_delegated(struct inode *inode, int flags, struct rpc_cred | |||
625 | if (delegation == NULL || (delegation->type & open_flags) != open_flags) | 867 | if (delegation == NULL || (delegation->type & open_flags) != open_flags) |
626 | goto out_err; | 868 | goto out_err; |
627 | err = -ENOMEM; | 869 | err = -ENOMEM; |
628 | if (!(sp = nfs4_get_state_owner(server, cred))) { | ||
629 | dprintk("%s: nfs4_get_state_owner failed!\n", __FUNCTION__); | ||
630 | goto out_err; | ||
631 | } | ||
632 | state = nfs4_get_open_state(inode, sp); | 870 | state = nfs4_get_open_state(inode, sp); |
633 | if (state == NULL) | 871 | if (state == NULL) |
634 | goto out_err; | 872 | goto out_err; |
@@ -636,39 +874,34 @@ static int _nfs4_open_delegated(struct inode *inode, int flags, struct rpc_cred | |||
636 | err = -ENOENT; | 874 | err = -ENOENT; |
637 | if ((state->state & open_flags) == open_flags) { | 875 | if ((state->state & open_flags) == open_flags) { |
638 | spin_lock(&inode->i_lock); | 876 | spin_lock(&inode->i_lock); |
639 | if (open_flags & FMODE_READ) | 877 | update_open_stateflags(state, open_flags); |
640 | state->nreaders++; | ||
641 | if (open_flags & FMODE_WRITE) | ||
642 | state->nwriters++; | ||
643 | spin_unlock(&inode->i_lock); | 878 | spin_unlock(&inode->i_lock); |
644 | goto out_ok; | 879 | goto out_ok; |
645 | } else if (state->state != 0) | 880 | } else if (state->state != 0) |
646 | goto out_err; | 881 | goto out_put_open_state; |
647 | 882 | ||
648 | lock_kernel(); | 883 | lock_kernel(); |
649 | err = _nfs4_do_access(inode, cred, open_flags); | 884 | err = _nfs4_do_access(inode, cred, open_flags); |
650 | unlock_kernel(); | 885 | unlock_kernel(); |
651 | if (err != 0) | 886 | if (err != 0) |
652 | goto out_err; | 887 | goto out_put_open_state; |
653 | set_bit(NFS_DELEGATED_STATE, &state->flags); | 888 | set_bit(NFS_DELEGATED_STATE, &state->flags); |
654 | update_open_stateid(state, &delegation->stateid, open_flags); | 889 | update_open_stateid(state, &delegation->stateid, open_flags); |
655 | out_ok: | 890 | out_ok: |
656 | nfs4_put_state_owner(sp); | 891 | nfs4_put_state_owner(sp); |
657 | up_read(&nfsi->rwsem); | 892 | up_read(&nfsi->rwsem); |
658 | up_read(&clp->cl_sem); | 893 | up_read(&clp->cl_sem); |
659 | igrab(inode); | ||
660 | *res = state; | 894 | *res = state; |
661 | return 0; | 895 | return 0; |
896 | out_put_open_state: | ||
897 | nfs4_put_open_state(state); | ||
662 | out_err: | 898 | out_err: |
663 | if (sp != NULL) { | ||
664 | if (state != NULL) | ||
665 | nfs4_put_open_state(state); | ||
666 | nfs4_put_state_owner(sp); | ||
667 | } | ||
668 | up_read(&nfsi->rwsem); | 899 | up_read(&nfsi->rwsem); |
669 | up_read(&clp->cl_sem); | 900 | up_read(&clp->cl_sem); |
670 | if (err != -EACCES) | 901 | if (err != -EACCES) |
671 | nfs_inode_return_delegation(inode); | 902 | nfs_inode_return_delegation(inode); |
903 | out_put_state_owner: | ||
904 | nfs4_put_state_owner(sp); | ||
672 | return err; | 905 | return err; |
673 | } | 906 | } |
674 | 907 | ||
@@ -689,7 +922,7 @@ static struct nfs4_state *nfs4_open_delegated(struct inode *inode, int flags, st | |||
689 | } | 922 | } |
690 | 923 | ||
691 | /* | 924 | /* |
692 | * Returns an nfs4_state + an referenced inode | 925 | * Returns a referenced nfs4_state |
693 | */ | 926 | */ |
694 | static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, struct iattr *sattr, struct rpc_cred *cred, struct nfs4_state **res) | 927 | static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, struct iattr *sattr, struct rpc_cred *cred, struct nfs4_state **res) |
695 | { | 928 | { |
@@ -697,73 +930,46 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st | |||
697 | struct nfs4_state *state = NULL; | 930 | struct nfs4_state *state = NULL; |
698 | struct nfs_server *server = NFS_SERVER(dir); | 931 | struct nfs_server *server = NFS_SERVER(dir); |
699 | struct nfs4_client *clp = server->nfs4_state; | 932 | struct nfs4_client *clp = server->nfs4_state; |
700 | struct inode *inode = NULL; | 933 | struct nfs4_opendata *opendata; |
701 | int status; | 934 | int status; |
702 | struct nfs_fattr f_attr, dir_attr; | ||
703 | struct nfs_openargs o_arg = { | ||
704 | .fh = NFS_FH(dir), | ||
705 | .open_flags = flags, | ||
706 | .name = &dentry->d_name, | ||
707 | .server = server, | ||
708 | .bitmask = server->attr_bitmask, | ||
709 | .claim = NFS4_OPEN_CLAIM_NULL, | ||
710 | }; | ||
711 | struct nfs_openres o_res = { | ||
712 | .f_attr = &f_attr, | ||
713 | .dir_attr = &dir_attr, | ||
714 | .server = server, | ||
715 | }; | ||
716 | 935 | ||
717 | /* Protect against reboot recovery conflicts */ | 936 | /* Protect against reboot recovery conflicts */ |
718 | down_read(&clp->cl_sem); | ||
719 | status = -ENOMEM; | 937 | status = -ENOMEM; |
720 | if (!(sp = nfs4_get_state_owner(server, cred))) { | 938 | if (!(sp = nfs4_get_state_owner(server, cred))) { |
721 | dprintk("nfs4_do_open: nfs4_get_state_owner failed!\n"); | 939 | dprintk("nfs4_do_open: nfs4_get_state_owner failed!\n"); |
722 | goto out_err; | 940 | goto out_err; |
723 | } | 941 | } |
724 | if (flags & O_EXCL) { | 942 | status = nfs4_recover_expired_lease(server); |
725 | u32 *p = (u32 *) o_arg.u.verifier.data; | 943 | if (status != 0) |
726 | p[0] = jiffies; | 944 | goto err_put_state_owner; |
727 | p[1] = current->pid; | 945 | down_read(&clp->cl_sem); |
728 | } else | 946 | status = -ENOMEM; |
729 | o_arg.u.attrs = sattr; | 947 | opendata = nfs4_opendata_alloc(dentry, sp, flags, sattr); |
730 | /* Serialization for the sequence id */ | 948 | if (opendata == NULL) |
949 | goto err_put_state_owner; | ||
731 | 950 | ||
732 | o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid); | 951 | status = _nfs4_proc_open(opendata); |
733 | if (o_arg.seqid == NULL) | ||
734 | return -ENOMEM; | ||
735 | nfs_fattr_init(&f_attr); | ||
736 | nfs_fattr_init(&dir_attr); | ||
737 | status = _nfs4_proc_open(dir, sp, &o_arg, &o_res); | ||
738 | if (status != 0) | 952 | if (status != 0) |
739 | goto out_err; | 953 | goto err_opendata_free; |
740 | 954 | ||
741 | status = -ENOMEM; | 955 | status = -ENOMEM; |
742 | inode = nfs_fhget(dir->i_sb, &o_res.fh, &f_attr); | 956 | state = nfs4_opendata_to_nfs4_state(opendata); |
743 | if (!inode) | 957 | if (state == NULL) |
744 | goto out_err; | 958 | goto err_opendata_free; |
745 | state = nfs4_get_open_state(inode, sp); | 959 | if (opendata->o_res.delegation_type != 0) |
746 | if (!state) | 960 | nfs_inode_set_delegation(state->inode, cred, &opendata->o_res); |
747 | goto out_err; | 961 | nfs4_opendata_free(opendata); |
748 | update_open_stateid(state, &o_res.stateid, flags); | ||
749 | if (o_res.delegation_type != 0) | ||
750 | nfs_inode_set_delegation(inode, cred, &o_res); | ||
751 | nfs_free_seqid(o_arg.seqid); | ||
752 | nfs4_put_state_owner(sp); | 962 | nfs4_put_state_owner(sp); |
753 | up_read(&clp->cl_sem); | 963 | up_read(&clp->cl_sem); |
754 | *res = state; | 964 | *res = state; |
755 | return 0; | 965 | return 0; |
966 | err_opendata_free: | ||
967 | nfs4_opendata_free(opendata); | ||
968 | err_put_state_owner: | ||
969 | nfs4_put_state_owner(sp); | ||
756 | out_err: | 970 | out_err: |
757 | if (sp != NULL) { | ||
758 | if (state != NULL) | ||
759 | nfs4_put_open_state(state); | ||
760 | nfs_free_seqid(o_arg.seqid); | ||
761 | nfs4_put_state_owner(sp); | ||
762 | } | ||
763 | /* Note: clp->cl_sem must be released before nfs4_put_open_state()! */ | 971 | /* Note: clp->cl_sem must be released before nfs4_put_open_state()! */ |
764 | up_read(&clp->cl_sem); | 972 | up_read(&clp->cl_sem); |
765 | if (inode != NULL) | ||
766 | iput(inode); | ||
767 | *res = NULL; | 973 | *res = NULL; |
768 | return status; | 974 | return status; |
769 | } | 975 | } |
@@ -830,6 +1036,7 @@ static int _nfs4_do_setattr(struct nfs_server *server, struct nfs_fattr *fattr, | |||
830 | .rpc_argp = &arg, | 1036 | .rpc_argp = &arg, |
831 | .rpc_resp = &res, | 1037 | .rpc_resp = &res, |
832 | }; | 1038 | }; |
1039 | unsigned long timestamp = jiffies; | ||
833 | int status; | 1040 | int status; |
834 | 1041 | ||
835 | nfs_fattr_init(fattr); | 1042 | nfs_fattr_init(fattr); |
@@ -841,6 +1048,8 @@ static int _nfs4_do_setattr(struct nfs_server *server, struct nfs_fattr *fattr, | |||
841 | memcpy(&arg.stateid, &zero_stateid, sizeof(arg.stateid)); | 1048 | memcpy(&arg.stateid, &zero_stateid, sizeof(arg.stateid)); |
842 | 1049 | ||
843 | status = rpc_call_sync(server->client, &msg, 0); | 1050 | status = rpc_call_sync(server->client, &msg, 0); |
1051 | if (status == 0 && state != NULL) | ||
1052 | renew_lease(server, timestamp); | ||
844 | return status; | 1053 | return status; |
845 | } | 1054 | } |
846 | 1055 | ||
@@ -865,12 +1074,13 @@ struct nfs4_closedata { | |||
865 | struct nfs_closeargs arg; | 1074 | struct nfs_closeargs arg; |
866 | struct nfs_closeres res; | 1075 | struct nfs_closeres res; |
867 | struct nfs_fattr fattr; | 1076 | struct nfs_fattr fattr; |
1077 | unsigned long timestamp; | ||
868 | }; | 1078 | }; |
869 | 1079 | ||
870 | static void nfs4_free_closedata(struct nfs4_closedata *calldata) | 1080 | static void nfs4_free_closedata(void *data) |
871 | { | 1081 | { |
872 | struct nfs4_state *state = calldata->state; | 1082 | struct nfs4_closedata *calldata = data; |
873 | struct nfs4_state_owner *sp = state->owner; | 1083 | struct nfs4_state_owner *sp = calldata->state->owner; |
874 | 1084 | ||
875 | nfs4_put_open_state(calldata->state); | 1085 | nfs4_put_open_state(calldata->state); |
876 | nfs_free_seqid(calldata->arg.seqid); | 1086 | nfs_free_seqid(calldata->arg.seqid); |
@@ -878,12 +1088,14 @@ static void nfs4_free_closedata(struct nfs4_closedata *calldata) | |||
878 | kfree(calldata); | 1088 | kfree(calldata); |
879 | } | 1089 | } |
880 | 1090 | ||
881 | static void nfs4_close_done(struct rpc_task *task) | 1091 | static void nfs4_close_done(struct rpc_task *task, void *data) |
882 | { | 1092 | { |
883 | struct nfs4_closedata *calldata = (struct nfs4_closedata *)task->tk_calldata; | 1093 | struct nfs4_closedata *calldata = data; |
884 | struct nfs4_state *state = calldata->state; | 1094 | struct nfs4_state *state = calldata->state; |
885 | struct nfs_server *server = NFS_SERVER(calldata->inode); | 1095 | struct nfs_server *server = NFS_SERVER(calldata->inode); |
886 | 1096 | ||
1097 | if (RPC_ASSASSINATED(task)) | ||
1098 | return; | ||
887 | /* hmm. we are done with the inode, and in the process of freeing | 1099 | /* hmm. we are done with the inode, and in the process of freeing |
888 | * the state_owner. we keep this around to process errors | 1100 | * the state_owner. we keep this around to process errors |
889 | */ | 1101 | */ |
@@ -892,6 +1104,7 @@ static void nfs4_close_done(struct rpc_task *task) | |||
892 | case 0: | 1104 | case 0: |
893 | memcpy(&state->stateid, &calldata->res.stateid, | 1105 | memcpy(&state->stateid, &calldata->res.stateid, |
894 | sizeof(state->stateid)); | 1106 | sizeof(state->stateid)); |
1107 | renew_lease(server, calldata->timestamp); | ||
895 | break; | 1108 | break; |
896 | case -NFS4ERR_STALE_STATEID: | 1109 | case -NFS4ERR_STALE_STATEID: |
897 | case -NFS4ERR_EXPIRED: | 1110 | case -NFS4ERR_EXPIRED: |
@@ -904,12 +1117,11 @@ static void nfs4_close_done(struct rpc_task *task) | |||
904 | } | 1117 | } |
905 | } | 1118 | } |
906 | nfs_refresh_inode(calldata->inode, calldata->res.fattr); | 1119 | nfs_refresh_inode(calldata->inode, calldata->res.fattr); |
907 | nfs4_free_closedata(calldata); | ||
908 | } | 1120 | } |
909 | 1121 | ||
910 | static void nfs4_close_begin(struct rpc_task *task) | 1122 | static void nfs4_close_prepare(struct rpc_task *task, void *data) |
911 | { | 1123 | { |
912 | struct nfs4_closedata *calldata = (struct nfs4_closedata *)task->tk_calldata; | 1124 | struct nfs4_closedata *calldata = data; |
913 | struct nfs4_state *state = calldata->state; | 1125 | struct nfs4_state *state = calldata->state; |
914 | struct rpc_message msg = { | 1126 | struct rpc_message msg = { |
915 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLOSE], | 1127 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLOSE], |
@@ -918,10 +1130,8 @@ static void nfs4_close_begin(struct rpc_task *task) | |||
918 | .rpc_cred = state->owner->so_cred, | 1130 | .rpc_cred = state->owner->so_cred, |
919 | }; | 1131 | }; |
920 | int mode = 0, old_mode; | 1132 | int mode = 0, old_mode; |
921 | int status; | ||
922 | 1133 | ||
923 | status = nfs_wait_on_sequence(calldata->arg.seqid, task); | 1134 | if (nfs_wait_on_sequence(calldata->arg.seqid, task) != 0) |
924 | if (status != 0) | ||
925 | return; | 1135 | return; |
926 | /* Recalculate the new open mode in case someone reopened the file | 1136 | /* Recalculate the new open mode in case someone reopened the file |
927 | * while we were waiting in line to be scheduled. | 1137 | * while we were waiting in line to be scheduled. |
@@ -929,26 +1139,34 @@ static void nfs4_close_begin(struct rpc_task *task) | |||
929 | spin_lock(&state->owner->so_lock); | 1139 | spin_lock(&state->owner->so_lock); |
930 | spin_lock(&calldata->inode->i_lock); | 1140 | spin_lock(&calldata->inode->i_lock); |
931 | mode = old_mode = state->state; | 1141 | mode = old_mode = state->state; |
932 | if (state->nreaders == 0) | 1142 | if (state->n_rdwr == 0) { |
933 | mode &= ~FMODE_READ; | 1143 | if (state->n_rdonly == 0) |
934 | if (state->nwriters == 0) | 1144 | mode &= ~FMODE_READ; |
935 | mode &= ~FMODE_WRITE; | 1145 | if (state->n_wronly == 0) |
1146 | mode &= ~FMODE_WRITE; | ||
1147 | } | ||
936 | nfs4_state_set_mode_locked(state, mode); | 1148 | nfs4_state_set_mode_locked(state, mode); |
937 | spin_unlock(&calldata->inode->i_lock); | 1149 | spin_unlock(&calldata->inode->i_lock); |
938 | spin_unlock(&state->owner->so_lock); | 1150 | spin_unlock(&state->owner->so_lock); |
939 | if (mode == old_mode || test_bit(NFS_DELEGATED_STATE, &state->flags)) { | 1151 | if (mode == old_mode || test_bit(NFS_DELEGATED_STATE, &state->flags)) { |
940 | nfs4_free_closedata(calldata); | 1152 | /* Note: exit _without_ calling nfs4_close_done */ |
941 | task->tk_exit = NULL; | 1153 | task->tk_action = NULL; |
942 | rpc_exit(task, 0); | ||
943 | return; | 1154 | return; |
944 | } | 1155 | } |
945 | nfs_fattr_init(calldata->res.fattr); | 1156 | nfs_fattr_init(calldata->res.fattr); |
946 | if (mode != 0) | 1157 | if (mode != 0) |
947 | msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE]; | 1158 | msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE]; |
948 | calldata->arg.open_flags = mode; | 1159 | calldata->arg.open_flags = mode; |
1160 | calldata->timestamp = jiffies; | ||
949 | rpc_call_setup(task, &msg, 0); | 1161 | rpc_call_setup(task, &msg, 0); |
950 | } | 1162 | } |
951 | 1163 | ||
1164 | static const struct rpc_call_ops nfs4_close_ops = { | ||
1165 | .rpc_call_prepare = nfs4_close_prepare, | ||
1166 | .rpc_call_done = nfs4_close_done, | ||
1167 | .rpc_release = nfs4_free_closedata, | ||
1168 | }; | ||
1169 | |||
952 | /* | 1170 | /* |
953 | * It is possible for data to be read/written from a mem-mapped file | 1171 | * It is possible for data to be read/written from a mem-mapped file |
954 | * after the sys_close call (which hits the vfs layer as a flush). | 1172 | * after the sys_close call (which hits the vfs layer as a flush). |
@@ -981,8 +1199,7 @@ int nfs4_do_close(struct inode *inode, struct nfs4_state *state) | |||
981 | calldata->res.fattr = &calldata->fattr; | 1199 | calldata->res.fattr = &calldata->fattr; |
982 | calldata->res.server = server; | 1200 | calldata->res.server = server; |
983 | 1201 | ||
984 | status = nfs4_call_async(server->client, nfs4_close_begin, | 1202 | status = nfs4_call_async(server->client, &nfs4_close_ops, calldata); |
985 | nfs4_close_done, calldata); | ||
986 | if (status == 0) | 1203 | if (status == 0) |
987 | goto out; | 1204 | goto out; |
988 | 1205 | ||
@@ -1034,7 +1251,7 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | |||
1034 | d_add(dentry, NULL); | 1251 | d_add(dentry, NULL); |
1035 | return (struct dentry *)state; | 1252 | return (struct dentry *)state; |
1036 | } | 1253 | } |
1037 | res = d_add_unique(dentry, state->inode); | 1254 | res = d_add_unique(dentry, igrab(state->inode)); |
1038 | if (res != NULL) | 1255 | if (res != NULL) |
1039 | dentry = res; | 1256 | dentry = res; |
1040 | nfs4_intent_set_file(nd, dentry, state); | 1257 | nfs4_intent_set_file(nd, dentry, state); |
@@ -1046,7 +1263,6 @@ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, st | |||
1046 | { | 1263 | { |
1047 | struct rpc_cred *cred; | 1264 | struct rpc_cred *cred; |
1048 | struct nfs4_state *state; | 1265 | struct nfs4_state *state; |
1049 | struct inode *inode; | ||
1050 | 1266 | ||
1051 | cred = rpcauth_lookupcred(NFS_SERVER(dir)->client->cl_auth, 0); | 1267 | cred = rpcauth_lookupcred(NFS_SERVER(dir)->client->cl_auth, 0); |
1052 | if (IS_ERR(cred)) | 1268 | if (IS_ERR(cred)) |
@@ -1070,9 +1286,7 @@ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, st | |||
1070 | } | 1286 | } |
1071 | goto out_drop; | 1287 | goto out_drop; |
1072 | } | 1288 | } |
1073 | inode = state->inode; | 1289 | if (state->inode == dentry->d_inode) { |
1074 | iput(inode); | ||
1075 | if (inode == dentry->d_inode) { | ||
1076 | nfs4_intent_set_file(nd, dentry, state); | 1290 | nfs4_intent_set_file(nd, dentry, state); |
1077 | return 1; | 1291 | return 1; |
1078 | } | 1292 | } |
@@ -1508,11 +1722,13 @@ static int _nfs4_proc_write(struct nfs_write_data *wdata) | |||
1508 | 1722 | ||
1509 | wdata->args.bitmask = server->attr_bitmask; | 1723 | wdata->args.bitmask = server->attr_bitmask; |
1510 | wdata->res.server = server; | 1724 | wdata->res.server = server; |
1725 | wdata->timestamp = jiffies; | ||
1511 | nfs_fattr_init(fattr); | 1726 | nfs_fattr_init(fattr); |
1512 | status = rpc_call_sync(server->client, &msg, rpcflags); | 1727 | status = rpc_call_sync(server->client, &msg, rpcflags); |
1513 | dprintk("NFS reply write: %d\n", status); | 1728 | dprintk("NFS reply write: %d\n", status); |
1514 | if (status < 0) | 1729 | if (status < 0) |
1515 | return status; | 1730 | return status; |
1731 | renew_lease(server, wdata->timestamp); | ||
1516 | nfs_post_op_update_inode(inode, fattr); | 1732 | nfs_post_op_update_inode(inode, fattr); |
1517 | return wdata->res.count; | 1733 | return wdata->res.count; |
1518 | } | 1734 | } |
@@ -1547,8 +1763,11 @@ static int _nfs4_proc_commit(struct nfs_write_data *cdata) | |||
1547 | 1763 | ||
1548 | cdata->args.bitmask = server->attr_bitmask; | 1764 | cdata->args.bitmask = server->attr_bitmask; |
1549 | cdata->res.server = server; | 1765 | cdata->res.server = server; |
1766 | cdata->timestamp = jiffies; | ||
1550 | nfs_fattr_init(fattr); | 1767 | nfs_fattr_init(fattr); |
1551 | status = rpc_call_sync(server->client, &msg, 0); | 1768 | status = rpc_call_sync(server->client, &msg, 0); |
1769 | if (status >= 0) | ||
1770 | renew_lease(server, cdata->timestamp); | ||
1552 | dprintk("NFS reply commit: %d\n", status); | 1771 | dprintk("NFS reply commit: %d\n", status); |
1553 | if (status >= 0) | 1772 | if (status >= 0) |
1554 | nfs_post_op_update_inode(inode, fattr); | 1773 | nfs_post_op_update_inode(inode, fattr); |
@@ -1601,7 +1820,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | |||
1601 | status = PTR_ERR(state); | 1820 | status = PTR_ERR(state); |
1602 | goto out; | 1821 | goto out; |
1603 | } | 1822 | } |
1604 | d_instantiate(dentry, state->inode); | 1823 | d_instantiate(dentry, igrab(state->inode)); |
1605 | if (flags & O_EXCL) { | 1824 | if (flags & O_EXCL) { |
1606 | struct nfs_fattr fattr; | 1825 | struct nfs_fattr fattr; |
1607 | status = nfs4_do_setattr(NFS_SERVER(dir), &fattr, | 1826 | status = nfs4_do_setattr(NFS_SERVER(dir), &fattr, |
@@ -2125,10 +2344,9 @@ static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle, | |||
2125 | return err; | 2344 | return err; |
2126 | } | 2345 | } |
2127 | 2346 | ||
2128 | static void | 2347 | static void nfs4_read_done(struct rpc_task *task, void *calldata) |
2129 | nfs4_read_done(struct rpc_task *task) | ||
2130 | { | 2348 | { |
2131 | struct nfs_read_data *data = (struct nfs_read_data *) task->tk_calldata; | 2349 | struct nfs_read_data *data = calldata; |
2132 | struct inode *inode = data->inode; | 2350 | struct inode *inode = data->inode; |
2133 | 2351 | ||
2134 | if (nfs4_async_handle_error(task, NFS_SERVER(inode)) == -EAGAIN) { | 2352 | if (nfs4_async_handle_error(task, NFS_SERVER(inode)) == -EAGAIN) { |
@@ -2138,9 +2356,14 @@ nfs4_read_done(struct rpc_task *task) | |||
2138 | if (task->tk_status > 0) | 2356 | if (task->tk_status > 0) |
2139 | renew_lease(NFS_SERVER(inode), data->timestamp); | 2357 | renew_lease(NFS_SERVER(inode), data->timestamp); |
2140 | /* Call back common NFS readpage processing */ | 2358 | /* Call back common NFS readpage processing */ |
2141 | nfs_readpage_result(task); | 2359 | nfs_readpage_result(task, calldata); |
2142 | } | 2360 | } |
2143 | 2361 | ||
2362 | static const struct rpc_call_ops nfs4_read_ops = { | ||
2363 | .rpc_call_done = nfs4_read_done, | ||
2364 | .rpc_release = nfs_readdata_release, | ||
2365 | }; | ||
2366 | |||
2144 | static void | 2367 | static void |
2145 | nfs4_proc_read_setup(struct nfs_read_data *data) | 2368 | nfs4_proc_read_setup(struct nfs_read_data *data) |
2146 | { | 2369 | { |
@@ -2160,14 +2383,13 @@ nfs4_proc_read_setup(struct nfs_read_data *data) | |||
2160 | flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0); | 2383 | flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0); |
2161 | 2384 | ||
2162 | /* Finalize the task. */ | 2385 | /* Finalize the task. */ |
2163 | rpc_init_task(task, NFS_CLIENT(inode), nfs4_read_done, flags); | 2386 | rpc_init_task(task, NFS_CLIENT(inode), flags, &nfs4_read_ops, data); |
2164 | rpc_call_setup(task, &msg, 0); | 2387 | rpc_call_setup(task, &msg, 0); |
2165 | } | 2388 | } |
2166 | 2389 | ||
2167 | static void | 2390 | static void nfs4_write_done(struct rpc_task *task, void *calldata) |
2168 | nfs4_write_done(struct rpc_task *task) | ||
2169 | { | 2391 | { |
2170 | struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata; | 2392 | struct nfs_write_data *data = calldata; |
2171 | struct inode *inode = data->inode; | 2393 | struct inode *inode = data->inode; |
2172 | 2394 | ||
2173 | if (nfs4_async_handle_error(task, NFS_SERVER(inode)) == -EAGAIN) { | 2395 | if (nfs4_async_handle_error(task, NFS_SERVER(inode)) == -EAGAIN) { |
@@ -2179,9 +2401,14 @@ nfs4_write_done(struct rpc_task *task) | |||
2179 | nfs_post_op_update_inode(inode, data->res.fattr); | 2401 | nfs_post_op_update_inode(inode, data->res.fattr); |
2180 | } | 2402 | } |
2181 | /* Call back common NFS writeback processing */ | 2403 | /* Call back common NFS writeback processing */ |
2182 | nfs_writeback_done(task); | 2404 | nfs_writeback_done(task, calldata); |
2183 | } | 2405 | } |
2184 | 2406 | ||
2407 | static const struct rpc_call_ops nfs4_write_ops = { | ||
2408 | .rpc_call_done = nfs4_write_done, | ||
2409 | .rpc_release = nfs_writedata_release, | ||
2410 | }; | ||
2411 | |||
2185 | static void | 2412 | static void |
2186 | nfs4_proc_write_setup(struct nfs_write_data *data, int how) | 2413 | nfs4_proc_write_setup(struct nfs_write_data *data, int how) |
2187 | { | 2414 | { |
@@ -2214,14 +2441,13 @@ nfs4_proc_write_setup(struct nfs_write_data *data, int how) | |||
2214 | flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC; | 2441 | flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC; |
2215 | 2442 | ||
2216 | /* Finalize the task. */ | 2443 | /* Finalize the task. */ |
2217 | rpc_init_task(task, NFS_CLIENT(inode), nfs4_write_done, flags); | 2444 | rpc_init_task(task, NFS_CLIENT(inode), flags, &nfs4_write_ops, data); |
2218 | rpc_call_setup(task, &msg, 0); | 2445 | rpc_call_setup(task, &msg, 0); |
2219 | } | 2446 | } |
2220 | 2447 | ||
2221 | static void | 2448 | static void nfs4_commit_done(struct rpc_task *task, void *calldata) |
2222 | nfs4_commit_done(struct rpc_task *task) | ||
2223 | { | 2449 | { |
2224 | struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata; | 2450 | struct nfs_write_data *data = calldata; |
2225 | struct inode *inode = data->inode; | 2451 | struct inode *inode = data->inode; |
2226 | 2452 | ||
2227 | if (nfs4_async_handle_error(task, NFS_SERVER(inode)) == -EAGAIN) { | 2453 | if (nfs4_async_handle_error(task, NFS_SERVER(inode)) == -EAGAIN) { |
@@ -2231,9 +2457,14 @@ nfs4_commit_done(struct rpc_task *task) | |||
2231 | if (task->tk_status >= 0) | 2457 | if (task->tk_status >= 0) |
2232 | nfs_post_op_update_inode(inode, data->res.fattr); | 2458 | nfs_post_op_update_inode(inode, data->res.fattr); |
2233 | /* Call back common NFS writeback processing */ | 2459 | /* Call back common NFS writeback processing */ |
2234 | nfs_commit_done(task); | 2460 | nfs_commit_done(task, calldata); |
2235 | } | 2461 | } |
2236 | 2462 | ||
2463 | static const struct rpc_call_ops nfs4_commit_ops = { | ||
2464 | .rpc_call_done = nfs4_commit_done, | ||
2465 | .rpc_release = nfs_commit_release, | ||
2466 | }; | ||
2467 | |||
2237 | static void | 2468 | static void |
2238 | nfs4_proc_commit_setup(struct nfs_write_data *data, int how) | 2469 | nfs4_proc_commit_setup(struct nfs_write_data *data, int how) |
2239 | { | 2470 | { |
@@ -2255,7 +2486,7 @@ nfs4_proc_commit_setup(struct nfs_write_data *data, int how) | |||
2255 | flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC; | 2486 | flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC; |
2256 | 2487 | ||
2257 | /* Finalize the task. */ | 2488 | /* Finalize the task. */ |
2258 | rpc_init_task(task, NFS_CLIENT(inode), nfs4_commit_done, flags); | 2489 | rpc_init_task(task, NFS_CLIENT(inode), flags, &nfs4_commit_ops, data); |
2259 | rpc_call_setup(task, &msg, 0); | 2490 | rpc_call_setup(task, &msg, 0); |
2260 | } | 2491 | } |
2261 | 2492 | ||
@@ -2263,11 +2494,10 @@ nfs4_proc_commit_setup(struct nfs_write_data *data, int how) | |||
2263 | * nfs4_proc_async_renew(): This is not one of the nfs_rpc_ops; it is a special | 2494 | * nfs4_proc_async_renew(): This is not one of the nfs_rpc_ops; it is a special |
2264 | * standalone procedure for queueing an asynchronous RENEW. | 2495 | * standalone procedure for queueing an asynchronous RENEW. |
2265 | */ | 2496 | */ |
2266 | static void | 2497 | static void nfs4_renew_done(struct rpc_task *task, void *data) |
2267 | renew_done(struct rpc_task *task) | ||
2268 | { | 2498 | { |
2269 | struct nfs4_client *clp = (struct nfs4_client *)task->tk_msg.rpc_argp; | 2499 | struct nfs4_client *clp = (struct nfs4_client *)task->tk_msg.rpc_argp; |
2270 | unsigned long timestamp = (unsigned long)task->tk_calldata; | 2500 | unsigned long timestamp = (unsigned long)data; |
2271 | 2501 | ||
2272 | if (task->tk_status < 0) { | 2502 | if (task->tk_status < 0) { |
2273 | switch (task->tk_status) { | 2503 | switch (task->tk_status) { |
@@ -2284,26 +2514,28 @@ renew_done(struct rpc_task *task) | |||
2284 | spin_unlock(&clp->cl_lock); | 2514 | spin_unlock(&clp->cl_lock); |
2285 | } | 2515 | } |
2286 | 2516 | ||
2287 | int | 2517 | static const struct rpc_call_ops nfs4_renew_ops = { |
2288 | nfs4_proc_async_renew(struct nfs4_client *clp) | 2518 | .rpc_call_done = nfs4_renew_done, |
2519 | }; | ||
2520 | |||
2521 | int nfs4_proc_async_renew(struct nfs4_client *clp, struct rpc_cred *cred) | ||
2289 | { | 2522 | { |
2290 | struct rpc_message msg = { | 2523 | struct rpc_message msg = { |
2291 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENEW], | 2524 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENEW], |
2292 | .rpc_argp = clp, | 2525 | .rpc_argp = clp, |
2293 | .rpc_cred = clp->cl_cred, | 2526 | .rpc_cred = cred, |
2294 | }; | 2527 | }; |
2295 | 2528 | ||
2296 | return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_SOFT, | 2529 | return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_SOFT, |
2297 | renew_done, (void *)jiffies); | 2530 | &nfs4_renew_ops, (void *)jiffies); |
2298 | } | 2531 | } |
2299 | 2532 | ||
2300 | int | 2533 | int nfs4_proc_renew(struct nfs4_client *clp, struct rpc_cred *cred) |
2301 | nfs4_proc_renew(struct nfs4_client *clp) | ||
2302 | { | 2534 | { |
2303 | struct rpc_message msg = { | 2535 | struct rpc_message msg = { |
2304 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENEW], | 2536 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENEW], |
2305 | .rpc_argp = clp, | 2537 | .rpc_argp = clp, |
2306 | .rpc_cred = clp->cl_cred, | 2538 | .rpc_cred = cred, |
2307 | }; | 2539 | }; |
2308 | unsigned long now = jiffies; | 2540 | unsigned long now = jiffies; |
2309 | int status; | 2541 | int status; |
@@ -2519,7 +2751,7 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server) | |||
2519 | case -NFS4ERR_EXPIRED: | 2751 | case -NFS4ERR_EXPIRED: |
2520 | rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL, NULL); | 2752 | rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL, NULL); |
2521 | nfs4_schedule_state_recovery(clp); | 2753 | nfs4_schedule_state_recovery(clp); |
2522 | if (test_bit(NFS4CLNT_OK, &clp->cl_state)) | 2754 | if (test_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) == 0) |
2523 | rpc_wake_up_task(task); | 2755 | rpc_wake_up_task(task); |
2524 | task->tk_status = 0; | 2756 | task->tk_status = 0; |
2525 | return -EAGAIN; | 2757 | return -EAGAIN; |
@@ -2536,25 +2768,25 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server) | |||
2536 | return 0; | 2768 | return 0; |
2537 | } | 2769 | } |
2538 | 2770 | ||
2771 | static int nfs4_wait_bit_interruptible(void *word) | ||
2772 | { | ||
2773 | if (signal_pending(current)) | ||
2774 | return -ERESTARTSYS; | ||
2775 | schedule(); | ||
2776 | return 0; | ||
2777 | } | ||
2778 | |||
2539 | static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs4_client *clp) | 2779 | static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs4_client *clp) |
2540 | { | 2780 | { |
2541 | DEFINE_WAIT(wait); | ||
2542 | sigset_t oldset; | 2781 | sigset_t oldset; |
2543 | int interruptible, res = 0; | 2782 | int res; |
2544 | 2783 | ||
2545 | might_sleep(); | 2784 | might_sleep(); |
2546 | 2785 | ||
2547 | rpc_clnt_sigmask(clnt, &oldset); | 2786 | rpc_clnt_sigmask(clnt, &oldset); |
2548 | interruptible = TASK_UNINTERRUPTIBLE; | 2787 | res = wait_on_bit(&clp->cl_state, NFS4CLNT_STATE_RECOVER, |
2549 | if (clnt->cl_intr) | 2788 | nfs4_wait_bit_interruptible, |
2550 | interruptible = TASK_INTERRUPTIBLE; | 2789 | TASK_INTERRUPTIBLE); |
2551 | prepare_to_wait(&clp->cl_waitq, &wait, interruptible); | ||
2552 | nfs4_schedule_state_recovery(clp); | ||
2553 | if (clnt->cl_intr && signalled()) | ||
2554 | res = -ERESTARTSYS; | ||
2555 | else if (!test_bit(NFS4CLNT_OK, &clp->cl_state)) | ||
2556 | schedule(); | ||
2557 | finish_wait(&clp->cl_waitq, &wait); | ||
2558 | rpc_clnt_sigunmask(clnt, &oldset); | 2790 | rpc_clnt_sigunmask(clnt, &oldset); |
2559 | return res; | 2791 | return res; |
2560 | } | 2792 | } |
@@ -2597,6 +2829,7 @@ int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct | |||
2597 | case -NFS4ERR_STALE_CLIENTID: | 2829 | case -NFS4ERR_STALE_CLIENTID: |
2598 | case -NFS4ERR_STALE_STATEID: | 2830 | case -NFS4ERR_STALE_STATEID: |
2599 | case -NFS4ERR_EXPIRED: | 2831 | case -NFS4ERR_EXPIRED: |
2832 | nfs4_schedule_state_recovery(clp); | ||
2600 | ret = nfs4_wait_clnt_recover(server->client, clp); | 2833 | ret = nfs4_wait_clnt_recover(server->client, clp); |
2601 | if (ret == 0) | 2834 | if (ret == 0) |
2602 | exception->retry = 1; | 2835 | exception->retry = 1; |
@@ -2613,7 +2846,7 @@ int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct | |||
2613 | return nfs4_map_errors(ret); | 2846 | return nfs4_map_errors(ret); |
2614 | } | 2847 | } |
2615 | 2848 | ||
2616 | int nfs4_proc_setclientid(struct nfs4_client *clp, u32 program, unsigned short port) | 2849 | int nfs4_proc_setclientid(struct nfs4_client *clp, u32 program, unsigned short port, struct rpc_cred *cred) |
2617 | { | 2850 | { |
2618 | nfs4_verifier sc_verifier; | 2851 | nfs4_verifier sc_verifier; |
2619 | struct nfs4_setclientid setclientid = { | 2852 | struct nfs4_setclientid setclientid = { |
@@ -2624,7 +2857,7 @@ int nfs4_proc_setclientid(struct nfs4_client *clp, u32 program, unsigned short p | |||
2624 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID], | 2857 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID], |
2625 | .rpc_argp = &setclientid, | 2858 | .rpc_argp = &setclientid, |
2626 | .rpc_resp = clp, | 2859 | .rpc_resp = clp, |
2627 | .rpc_cred = clp->cl_cred, | 2860 | .rpc_cred = cred, |
2628 | }; | 2861 | }; |
2629 | u32 *p; | 2862 | u32 *p; |
2630 | int loop = 0; | 2863 | int loop = 0; |
@@ -2638,7 +2871,7 @@ int nfs4_proc_setclientid(struct nfs4_client *clp, u32 program, unsigned short p | |||
2638 | setclientid.sc_name_len = scnprintf(setclientid.sc_name, | 2871 | setclientid.sc_name_len = scnprintf(setclientid.sc_name, |
2639 | sizeof(setclientid.sc_name), "%s/%u.%u.%u.%u %s %u", | 2872 | sizeof(setclientid.sc_name), "%s/%u.%u.%u.%u %s %u", |
2640 | clp->cl_ipaddr, NIPQUAD(clp->cl_addr.s_addr), | 2873 | clp->cl_ipaddr, NIPQUAD(clp->cl_addr.s_addr), |
2641 | clp->cl_cred->cr_ops->cr_name, | 2874 | cred->cr_ops->cr_name, |
2642 | clp->cl_id_uniquifier); | 2875 | clp->cl_id_uniquifier); |
2643 | setclientid.sc_netid_len = scnprintf(setclientid.sc_netid, | 2876 | setclientid.sc_netid_len = scnprintf(setclientid.sc_netid, |
2644 | sizeof(setclientid.sc_netid), "tcp"); | 2877 | sizeof(setclientid.sc_netid), "tcp"); |
@@ -2661,14 +2894,14 @@ int nfs4_proc_setclientid(struct nfs4_client *clp, u32 program, unsigned short p | |||
2661 | } | 2894 | } |
2662 | 2895 | ||
2663 | int | 2896 | int |
2664 | nfs4_proc_setclientid_confirm(struct nfs4_client *clp) | 2897 | nfs4_proc_setclientid_confirm(struct nfs4_client *clp, struct rpc_cred *cred) |
2665 | { | 2898 | { |
2666 | struct nfs_fsinfo fsinfo; | 2899 | struct nfs_fsinfo fsinfo; |
2667 | struct rpc_message msg = { | 2900 | struct rpc_message msg = { |
2668 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID_CONFIRM], | 2901 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID_CONFIRM], |
2669 | .rpc_argp = clp, | 2902 | .rpc_argp = clp, |
2670 | .rpc_resp = &fsinfo, | 2903 | .rpc_resp = &fsinfo, |
2671 | .rpc_cred = clp->cl_cred, | 2904 | .rpc_cred = cred, |
2672 | }; | 2905 | }; |
2673 | unsigned long now; | 2906 | unsigned long now; |
2674 | int status; | 2907 | int status; |
@@ -2679,24 +2912,92 @@ nfs4_proc_setclientid_confirm(struct nfs4_client *clp) | |||
2679 | spin_lock(&clp->cl_lock); | 2912 | spin_lock(&clp->cl_lock); |
2680 | clp->cl_lease_time = fsinfo.lease_time * HZ; | 2913 | clp->cl_lease_time = fsinfo.lease_time * HZ; |
2681 | clp->cl_last_renewal = now; | 2914 | clp->cl_last_renewal = now; |
2915 | clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); | ||
2682 | spin_unlock(&clp->cl_lock); | 2916 | spin_unlock(&clp->cl_lock); |
2683 | } | 2917 | } |
2684 | return status; | 2918 | return status; |
2685 | } | 2919 | } |
2686 | 2920 | ||
2687 | static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid) | 2921 | struct nfs4_delegreturndata { |
2922 | struct nfs4_delegreturnargs args; | ||
2923 | struct nfs4_delegreturnres res; | ||
2924 | struct nfs_fh fh; | ||
2925 | nfs4_stateid stateid; | ||
2926 | struct rpc_cred *cred; | ||
2927 | unsigned long timestamp; | ||
2928 | struct nfs_fattr fattr; | ||
2929 | int rpc_status; | ||
2930 | }; | ||
2931 | |||
2932 | static void nfs4_delegreturn_prepare(struct rpc_task *task, void *calldata) | ||
2688 | { | 2933 | { |
2689 | struct nfs4_delegreturnargs args = { | 2934 | struct nfs4_delegreturndata *data = calldata; |
2690 | .fhandle = NFS_FH(inode), | ||
2691 | .stateid = stateid, | ||
2692 | }; | ||
2693 | struct rpc_message msg = { | 2935 | struct rpc_message msg = { |
2694 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_DELEGRETURN], | 2936 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_DELEGRETURN], |
2695 | .rpc_argp = &args, | 2937 | .rpc_argp = &data->args, |
2696 | .rpc_cred = cred, | 2938 | .rpc_resp = &data->res, |
2939 | .rpc_cred = data->cred, | ||
2697 | }; | 2940 | }; |
2941 | nfs_fattr_init(data->res.fattr); | ||
2942 | rpc_call_setup(task, &msg, 0); | ||
2943 | } | ||
2698 | 2944 | ||
2699 | return rpc_call_sync(NFS_CLIENT(inode), &msg, 0); | 2945 | static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata) |
2946 | { | ||
2947 | struct nfs4_delegreturndata *data = calldata; | ||
2948 | data->rpc_status = task->tk_status; | ||
2949 | if (data->rpc_status == 0) | ||
2950 | renew_lease(data->res.server, data->timestamp); | ||
2951 | } | ||
2952 | |||
2953 | static void nfs4_delegreturn_release(void *calldata) | ||
2954 | { | ||
2955 | struct nfs4_delegreturndata *data = calldata; | ||
2956 | |||
2957 | put_rpccred(data->cred); | ||
2958 | kfree(calldata); | ||
2959 | } | ||
2960 | |||
2961 | const static struct rpc_call_ops nfs4_delegreturn_ops = { | ||
2962 | .rpc_call_prepare = nfs4_delegreturn_prepare, | ||
2963 | .rpc_call_done = nfs4_delegreturn_done, | ||
2964 | .rpc_release = nfs4_delegreturn_release, | ||
2965 | }; | ||
2966 | |||
2967 | static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid) | ||
2968 | { | ||
2969 | struct nfs4_delegreturndata *data; | ||
2970 | struct nfs_server *server = NFS_SERVER(inode); | ||
2971 | struct rpc_task *task; | ||
2972 | int status; | ||
2973 | |||
2974 | data = kmalloc(sizeof(*data), GFP_KERNEL); | ||
2975 | if (data == NULL) | ||
2976 | return -ENOMEM; | ||
2977 | data->args.fhandle = &data->fh; | ||
2978 | data->args.stateid = &data->stateid; | ||
2979 | data->args.bitmask = server->attr_bitmask; | ||
2980 | nfs_copy_fh(&data->fh, NFS_FH(inode)); | ||
2981 | memcpy(&data->stateid, stateid, sizeof(data->stateid)); | ||
2982 | data->res.fattr = &data->fattr; | ||
2983 | data->res.server = server; | ||
2984 | data->cred = get_rpccred(cred); | ||
2985 | data->timestamp = jiffies; | ||
2986 | data->rpc_status = 0; | ||
2987 | |||
2988 | task = rpc_run_task(NFS_CLIENT(inode), RPC_TASK_ASYNC, &nfs4_delegreturn_ops, data); | ||
2989 | if (IS_ERR(task)) { | ||
2990 | nfs4_delegreturn_release(data); | ||
2991 | return PTR_ERR(task); | ||
2992 | } | ||
2993 | status = nfs4_wait_for_completion_rpc_task(task); | ||
2994 | if (status == 0) { | ||
2995 | status = data->rpc_status; | ||
2996 | if (status == 0) | ||
2997 | nfs_post_op_update_inode(inode, &data->fattr); | ||
2998 | } | ||
2999 | rpc_release_task(task); | ||
3000 | return status; | ||
2700 | } | 3001 | } |
2701 | 3002 | ||
2702 | int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid) | 3003 | int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid) |
@@ -2734,43 +3035,17 @@ nfs4_set_lock_task_retry(unsigned long timeout) | |||
2734 | return timeout; | 3035 | return timeout; |
2735 | } | 3036 | } |
2736 | 3037 | ||
2737 | static inline int | ||
2738 | nfs4_lck_type(int cmd, struct file_lock *request) | ||
2739 | { | ||
2740 | /* set lock type */ | ||
2741 | switch (request->fl_type) { | ||
2742 | case F_RDLCK: | ||
2743 | return IS_SETLKW(cmd) ? NFS4_READW_LT : NFS4_READ_LT; | ||
2744 | case F_WRLCK: | ||
2745 | return IS_SETLKW(cmd) ? NFS4_WRITEW_LT : NFS4_WRITE_LT; | ||
2746 | case F_UNLCK: | ||
2747 | return NFS4_WRITE_LT; | ||
2748 | } | ||
2749 | BUG(); | ||
2750 | return 0; | ||
2751 | } | ||
2752 | |||
2753 | static inline uint64_t | ||
2754 | nfs4_lck_length(struct file_lock *request) | ||
2755 | { | ||
2756 | if (request->fl_end == OFFSET_MAX) | ||
2757 | return ~(uint64_t)0; | ||
2758 | return request->fl_end - request->fl_start + 1; | ||
2759 | } | ||
2760 | |||
2761 | static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *request) | 3038 | static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *request) |
2762 | { | 3039 | { |
2763 | struct inode *inode = state->inode; | 3040 | struct inode *inode = state->inode; |
2764 | struct nfs_server *server = NFS_SERVER(inode); | 3041 | struct nfs_server *server = NFS_SERVER(inode); |
2765 | struct nfs4_client *clp = server->nfs4_state; | 3042 | struct nfs4_client *clp = server->nfs4_state; |
2766 | struct nfs_lockargs arg = { | 3043 | struct nfs_lockt_args arg = { |
2767 | .fh = NFS_FH(inode), | 3044 | .fh = NFS_FH(inode), |
2768 | .type = nfs4_lck_type(cmd, request), | 3045 | .fl = request, |
2769 | .offset = request->fl_start, | ||
2770 | .length = nfs4_lck_length(request), | ||
2771 | }; | 3046 | }; |
2772 | struct nfs_lockres res = { | 3047 | struct nfs_lockt_res res = { |
2773 | .server = server, | 3048 | .denied = request, |
2774 | }; | 3049 | }; |
2775 | struct rpc_message msg = { | 3050 | struct rpc_message msg = { |
2776 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOCKT], | 3051 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOCKT], |
@@ -2778,36 +3053,23 @@ static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock | |||
2778 | .rpc_resp = &res, | 3053 | .rpc_resp = &res, |
2779 | .rpc_cred = state->owner->so_cred, | 3054 | .rpc_cred = state->owner->so_cred, |
2780 | }; | 3055 | }; |
2781 | struct nfs_lowner nlo; | ||
2782 | struct nfs4_lock_state *lsp; | 3056 | struct nfs4_lock_state *lsp; |
2783 | int status; | 3057 | int status; |
2784 | 3058 | ||
2785 | down_read(&clp->cl_sem); | 3059 | down_read(&clp->cl_sem); |
2786 | nlo.clientid = clp->cl_clientid; | 3060 | arg.lock_owner.clientid = clp->cl_clientid; |
2787 | status = nfs4_set_lock_state(state, request); | 3061 | status = nfs4_set_lock_state(state, request); |
2788 | if (status != 0) | 3062 | if (status != 0) |
2789 | goto out; | 3063 | goto out; |
2790 | lsp = request->fl_u.nfs4_fl.owner; | 3064 | lsp = request->fl_u.nfs4_fl.owner; |
2791 | nlo.id = lsp->ls_id; | 3065 | arg.lock_owner.id = lsp->ls_id; |
2792 | arg.u.lockt = &nlo; | ||
2793 | status = rpc_call_sync(server->client, &msg, 0); | 3066 | status = rpc_call_sync(server->client, &msg, 0); |
2794 | if (!status) { | 3067 | switch (status) { |
2795 | request->fl_type = F_UNLCK; | 3068 | case 0: |
2796 | } else if (status == -NFS4ERR_DENIED) { | 3069 | request->fl_type = F_UNLCK; |
2797 | int64_t len, start, end; | 3070 | break; |
2798 | start = res.u.denied.offset; | 3071 | case -NFS4ERR_DENIED: |
2799 | len = res.u.denied.length; | 3072 | status = 0; |
2800 | end = start + len - 1; | ||
2801 | if (end < 0 || len == 0) | ||
2802 | request->fl_end = OFFSET_MAX; | ||
2803 | else | ||
2804 | request->fl_end = (loff_t)end; | ||
2805 | request->fl_start = (loff_t)start; | ||
2806 | request->fl_type = F_WRLCK; | ||
2807 | if (res.u.denied.type & 1) | ||
2808 | request->fl_type = F_RDLCK; | ||
2809 | request->fl_pid = 0; | ||
2810 | status = 0; | ||
2811 | } | 3073 | } |
2812 | out: | 3074 | out: |
2813 | up_read(&clp->cl_sem); | 3075 | up_read(&clp->cl_sem); |
@@ -2847,196 +3109,314 @@ static int do_vfs_lock(struct file *file, struct file_lock *fl) | |||
2847 | } | 3109 | } |
2848 | 3110 | ||
2849 | struct nfs4_unlockdata { | 3111 | struct nfs4_unlockdata { |
2850 | struct nfs_lockargs arg; | 3112 | struct nfs_locku_args arg; |
2851 | struct nfs_locku_opargs luargs; | 3113 | struct nfs_locku_res res; |
2852 | struct nfs_lockres res; | ||
2853 | struct nfs4_lock_state *lsp; | 3114 | struct nfs4_lock_state *lsp; |
2854 | struct nfs_open_context *ctx; | 3115 | struct nfs_open_context *ctx; |
2855 | atomic_t refcount; | 3116 | struct file_lock fl; |
2856 | struct completion completion; | 3117 | const struct nfs_server *server; |
3118 | unsigned long timestamp; | ||
2857 | }; | 3119 | }; |
2858 | 3120 | ||
2859 | static void nfs4_locku_release_calldata(struct nfs4_unlockdata *calldata) | 3121 | static struct nfs4_unlockdata *nfs4_alloc_unlockdata(struct file_lock *fl, |
2860 | { | 3122 | struct nfs_open_context *ctx, |
2861 | if (atomic_dec_and_test(&calldata->refcount)) { | 3123 | struct nfs4_lock_state *lsp, |
2862 | nfs_free_seqid(calldata->luargs.seqid); | 3124 | struct nfs_seqid *seqid) |
2863 | nfs4_put_lock_state(calldata->lsp); | 3125 | { |
2864 | put_nfs_open_context(calldata->ctx); | 3126 | struct nfs4_unlockdata *p; |
2865 | kfree(calldata); | 3127 | struct inode *inode = lsp->ls_state->inode; |
2866 | } | 3128 | |
3129 | p = kmalloc(sizeof(*p), GFP_KERNEL); | ||
3130 | if (p == NULL) | ||
3131 | return NULL; | ||
3132 | p->arg.fh = NFS_FH(inode); | ||
3133 | p->arg.fl = &p->fl; | ||
3134 | p->arg.seqid = seqid; | ||
3135 | p->arg.stateid = &lsp->ls_stateid; | ||
3136 | p->lsp = lsp; | ||
3137 | atomic_inc(&lsp->ls_count); | ||
3138 | /* Ensure we don't close file until we're done freeing locks! */ | ||
3139 | p->ctx = get_nfs_open_context(ctx); | ||
3140 | memcpy(&p->fl, fl, sizeof(p->fl)); | ||
3141 | p->server = NFS_SERVER(inode); | ||
3142 | return p; | ||
2867 | } | 3143 | } |
2868 | 3144 | ||
2869 | static void nfs4_locku_complete(struct nfs4_unlockdata *calldata) | 3145 | static void nfs4_locku_release_calldata(void *data) |
2870 | { | 3146 | { |
2871 | complete(&calldata->completion); | 3147 | struct nfs4_unlockdata *calldata = data; |
2872 | nfs4_locku_release_calldata(calldata); | 3148 | nfs_free_seqid(calldata->arg.seqid); |
3149 | nfs4_put_lock_state(calldata->lsp); | ||
3150 | put_nfs_open_context(calldata->ctx); | ||
3151 | kfree(calldata); | ||
2873 | } | 3152 | } |
2874 | 3153 | ||
2875 | static void nfs4_locku_done(struct rpc_task *task) | 3154 | static void nfs4_locku_done(struct rpc_task *task, void *data) |
2876 | { | 3155 | { |
2877 | struct nfs4_unlockdata *calldata = (struct nfs4_unlockdata *)task->tk_calldata; | 3156 | struct nfs4_unlockdata *calldata = data; |
2878 | 3157 | ||
2879 | nfs_increment_lock_seqid(task->tk_status, calldata->luargs.seqid); | 3158 | if (RPC_ASSASSINATED(task)) |
3159 | return; | ||
3160 | nfs_increment_lock_seqid(task->tk_status, calldata->arg.seqid); | ||
2880 | switch (task->tk_status) { | 3161 | switch (task->tk_status) { |
2881 | case 0: | 3162 | case 0: |
2882 | memcpy(calldata->lsp->ls_stateid.data, | 3163 | memcpy(calldata->lsp->ls_stateid.data, |
2883 | calldata->res.u.stateid.data, | 3164 | calldata->res.stateid.data, |
2884 | sizeof(calldata->lsp->ls_stateid.data)); | 3165 | sizeof(calldata->lsp->ls_stateid.data)); |
3166 | renew_lease(calldata->server, calldata->timestamp); | ||
2885 | break; | 3167 | break; |
2886 | case -NFS4ERR_STALE_STATEID: | 3168 | case -NFS4ERR_STALE_STATEID: |
2887 | case -NFS4ERR_EXPIRED: | 3169 | case -NFS4ERR_EXPIRED: |
2888 | nfs4_schedule_state_recovery(calldata->res.server->nfs4_state); | 3170 | nfs4_schedule_state_recovery(calldata->server->nfs4_state); |
2889 | break; | 3171 | break; |
2890 | default: | 3172 | default: |
2891 | if (nfs4_async_handle_error(task, calldata->res.server) == -EAGAIN) { | 3173 | if (nfs4_async_handle_error(task, calldata->server) == -EAGAIN) { |
2892 | rpc_restart_call(task); | 3174 | rpc_restart_call(task); |
2893 | return; | ||
2894 | } | 3175 | } |
2895 | } | 3176 | } |
2896 | nfs4_locku_complete(calldata); | ||
2897 | } | 3177 | } |
2898 | 3178 | ||
2899 | static void nfs4_locku_begin(struct rpc_task *task) | 3179 | static void nfs4_locku_prepare(struct rpc_task *task, void *data) |
2900 | { | 3180 | { |
2901 | struct nfs4_unlockdata *calldata = (struct nfs4_unlockdata *)task->tk_calldata; | 3181 | struct nfs4_unlockdata *calldata = data; |
2902 | struct rpc_message msg = { | 3182 | struct rpc_message msg = { |
2903 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOCKU], | 3183 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOCKU], |
2904 | .rpc_argp = &calldata->arg, | 3184 | .rpc_argp = &calldata->arg, |
2905 | .rpc_resp = &calldata->res, | 3185 | .rpc_resp = &calldata->res, |
2906 | .rpc_cred = calldata->lsp->ls_state->owner->so_cred, | 3186 | .rpc_cred = calldata->lsp->ls_state->owner->so_cred, |
2907 | }; | 3187 | }; |
2908 | int status; | ||
2909 | 3188 | ||
2910 | status = nfs_wait_on_sequence(calldata->luargs.seqid, task); | 3189 | if (nfs_wait_on_sequence(calldata->arg.seqid, task) != 0) |
2911 | if (status != 0) | ||
2912 | return; | 3190 | return; |
2913 | if ((calldata->lsp->ls_flags & NFS_LOCK_INITIALIZED) == 0) { | 3191 | if ((calldata->lsp->ls_flags & NFS_LOCK_INITIALIZED) == 0) { |
2914 | nfs4_locku_complete(calldata); | 3192 | /* Note: exit _without_ running nfs4_locku_done */ |
2915 | task->tk_exit = NULL; | 3193 | task->tk_action = NULL; |
2916 | rpc_exit(task, 0); | ||
2917 | return; | 3194 | return; |
2918 | } | 3195 | } |
3196 | calldata->timestamp = jiffies; | ||
2919 | rpc_call_setup(task, &msg, 0); | 3197 | rpc_call_setup(task, &msg, 0); |
2920 | } | 3198 | } |
2921 | 3199 | ||
3200 | static const struct rpc_call_ops nfs4_locku_ops = { | ||
3201 | .rpc_call_prepare = nfs4_locku_prepare, | ||
3202 | .rpc_call_done = nfs4_locku_done, | ||
3203 | .rpc_release = nfs4_locku_release_calldata, | ||
3204 | }; | ||
3205 | |||
3206 | static struct rpc_task *nfs4_do_unlck(struct file_lock *fl, | ||
3207 | struct nfs_open_context *ctx, | ||
3208 | struct nfs4_lock_state *lsp, | ||
3209 | struct nfs_seqid *seqid) | ||
3210 | { | ||
3211 | struct nfs4_unlockdata *data; | ||
3212 | struct rpc_task *task; | ||
3213 | |||
3214 | data = nfs4_alloc_unlockdata(fl, ctx, lsp, seqid); | ||
3215 | if (data == NULL) { | ||
3216 | nfs_free_seqid(seqid); | ||
3217 | return ERR_PTR(-ENOMEM); | ||
3218 | } | ||
3219 | |||
3220 | /* Unlock _before_ we do the RPC call */ | ||
3221 | do_vfs_lock(fl->fl_file, fl); | ||
3222 | task = rpc_run_task(NFS_CLIENT(lsp->ls_state->inode), RPC_TASK_ASYNC, &nfs4_locku_ops, data); | ||
3223 | if (IS_ERR(task)) | ||
3224 | nfs4_locku_release_calldata(data); | ||
3225 | return task; | ||
3226 | } | ||
3227 | |||
2922 | static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *request) | 3228 | static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *request) |
2923 | { | 3229 | { |
2924 | struct nfs4_unlockdata *calldata; | 3230 | struct nfs_seqid *seqid; |
2925 | struct inode *inode = state->inode; | ||
2926 | struct nfs_server *server = NFS_SERVER(inode); | ||
2927 | struct nfs4_lock_state *lsp; | 3231 | struct nfs4_lock_state *lsp; |
2928 | int status; | 3232 | struct rpc_task *task; |
3233 | int status = 0; | ||
2929 | 3234 | ||
2930 | /* Is this a delegated lock? */ | 3235 | /* Is this a delegated lock? */ |
2931 | if (test_bit(NFS_DELEGATED_STATE, &state->flags)) | 3236 | if (test_bit(NFS_DELEGATED_STATE, &state->flags)) |
2932 | return do_vfs_lock(request->fl_file, request); | 3237 | goto out_unlock; |
3238 | /* Is this open_owner holding any locks on the server? */ | ||
3239 | if (test_bit(LK_STATE_IN_USE, &state->flags) == 0) | ||
3240 | goto out_unlock; | ||
2933 | 3241 | ||
2934 | status = nfs4_set_lock_state(state, request); | 3242 | status = nfs4_set_lock_state(state, request); |
2935 | if (status != 0) | 3243 | if (status != 0) |
2936 | return status; | 3244 | goto out_unlock; |
2937 | lsp = request->fl_u.nfs4_fl.owner; | 3245 | lsp = request->fl_u.nfs4_fl.owner; |
2938 | /* We might have lost the locks! */ | 3246 | status = -ENOMEM; |
2939 | if ((lsp->ls_flags & NFS_LOCK_INITIALIZED) == 0) | 3247 | seqid = nfs_alloc_seqid(&lsp->ls_seqid); |
2940 | return 0; | 3248 | if (seqid == NULL) |
2941 | calldata = kmalloc(sizeof(*calldata), GFP_KERNEL); | 3249 | goto out_unlock; |
2942 | if (calldata == NULL) | 3250 | task = nfs4_do_unlck(request, request->fl_file->private_data, lsp, seqid); |
2943 | return -ENOMEM; | 3251 | status = PTR_ERR(task); |
2944 | calldata->luargs.seqid = nfs_alloc_seqid(&lsp->ls_seqid); | 3252 | if (IS_ERR(task)) |
2945 | if (calldata->luargs.seqid == NULL) { | 3253 | goto out_unlock; |
2946 | kfree(calldata); | 3254 | status = nfs4_wait_for_completion_rpc_task(task); |
2947 | return -ENOMEM; | 3255 | rpc_release_task(task); |
2948 | } | 3256 | return status; |
2949 | calldata->luargs.stateid = &lsp->ls_stateid; | 3257 | out_unlock: |
2950 | calldata->arg.fh = NFS_FH(inode); | ||
2951 | calldata->arg.type = nfs4_lck_type(cmd, request); | ||
2952 | calldata->arg.offset = request->fl_start; | ||
2953 | calldata->arg.length = nfs4_lck_length(request); | ||
2954 | calldata->arg.u.locku = &calldata->luargs; | ||
2955 | calldata->res.server = server; | ||
2956 | calldata->lsp = lsp; | ||
2957 | atomic_inc(&lsp->ls_count); | ||
2958 | |||
2959 | /* Ensure we don't close file until we're done freeing locks! */ | ||
2960 | calldata->ctx = get_nfs_open_context((struct nfs_open_context*)request->fl_file->private_data); | ||
2961 | |||
2962 | atomic_set(&calldata->refcount, 2); | ||
2963 | init_completion(&calldata->completion); | ||
2964 | |||
2965 | status = nfs4_call_async(NFS_SERVER(inode)->client, nfs4_locku_begin, | ||
2966 | nfs4_locku_done, calldata); | ||
2967 | if (status == 0) | ||
2968 | wait_for_completion_interruptible(&calldata->completion); | ||
2969 | do_vfs_lock(request->fl_file, request); | 3258 | do_vfs_lock(request->fl_file, request); |
2970 | nfs4_locku_release_calldata(calldata); | ||
2971 | return status; | 3259 | return status; |
2972 | } | 3260 | } |
2973 | 3261 | ||
2974 | static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *request, int reclaim) | 3262 | struct nfs4_lockdata { |
3263 | struct nfs_lock_args arg; | ||
3264 | struct nfs_lock_res res; | ||
3265 | struct nfs4_lock_state *lsp; | ||
3266 | struct nfs_open_context *ctx; | ||
3267 | struct file_lock fl; | ||
3268 | unsigned long timestamp; | ||
3269 | int rpc_status; | ||
3270 | int cancelled; | ||
3271 | }; | ||
3272 | |||
3273 | static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl, | ||
3274 | struct nfs_open_context *ctx, struct nfs4_lock_state *lsp) | ||
2975 | { | 3275 | { |
2976 | struct inode *inode = state->inode; | 3276 | struct nfs4_lockdata *p; |
3277 | struct inode *inode = lsp->ls_state->inode; | ||
2977 | struct nfs_server *server = NFS_SERVER(inode); | 3278 | struct nfs_server *server = NFS_SERVER(inode); |
2978 | struct nfs4_lock_state *lsp = request->fl_u.nfs4_fl.owner; | 3279 | |
2979 | struct nfs_lock_opargs largs = { | 3280 | p = kzalloc(sizeof(*p), GFP_KERNEL); |
2980 | .lock_stateid = &lsp->ls_stateid, | 3281 | if (p == NULL) |
2981 | .open_stateid = &state->stateid, | 3282 | return NULL; |
2982 | .lock_owner = { | 3283 | |
2983 | .clientid = server->nfs4_state->cl_clientid, | 3284 | p->arg.fh = NFS_FH(inode); |
2984 | .id = lsp->ls_id, | 3285 | p->arg.fl = &p->fl; |
2985 | }, | 3286 | p->arg.lock_seqid = nfs_alloc_seqid(&lsp->ls_seqid); |
2986 | .reclaim = reclaim, | 3287 | if (p->arg.lock_seqid == NULL) |
2987 | }; | 3288 | goto out_free; |
2988 | struct nfs_lockargs arg = { | 3289 | p->arg.lock_stateid = &lsp->ls_stateid; |
2989 | .fh = NFS_FH(inode), | 3290 | p->arg.lock_owner.clientid = server->nfs4_state->cl_clientid; |
2990 | .type = nfs4_lck_type(cmd, request), | 3291 | p->arg.lock_owner.id = lsp->ls_id; |
2991 | .offset = request->fl_start, | 3292 | p->lsp = lsp; |
2992 | .length = nfs4_lck_length(request), | 3293 | atomic_inc(&lsp->ls_count); |
2993 | .u = { | 3294 | p->ctx = get_nfs_open_context(ctx); |
2994 | .lock = &largs, | 3295 | memcpy(&p->fl, fl, sizeof(p->fl)); |
2995 | }, | 3296 | return p; |
2996 | }; | 3297 | out_free: |
2997 | struct nfs_lockres res = { | 3298 | kfree(p); |
2998 | .server = server, | 3299 | return NULL; |
2999 | }; | 3300 | } |
3301 | |||
3302 | static void nfs4_lock_prepare(struct rpc_task *task, void *calldata) | ||
3303 | { | ||
3304 | struct nfs4_lockdata *data = calldata; | ||
3305 | struct nfs4_state *state = data->lsp->ls_state; | ||
3306 | struct nfs4_state_owner *sp = state->owner; | ||
3000 | struct rpc_message msg = { | 3307 | struct rpc_message msg = { |
3001 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOCK], | 3308 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOCK], |
3002 | .rpc_argp = &arg, | 3309 | .rpc_argp = &data->arg, |
3003 | .rpc_resp = &res, | 3310 | .rpc_resp = &data->res, |
3004 | .rpc_cred = state->owner->so_cred, | 3311 | .rpc_cred = sp->so_cred, |
3005 | }; | 3312 | }; |
3006 | int status = -ENOMEM; | ||
3007 | |||
3008 | largs.lock_seqid = nfs_alloc_seqid(&lsp->ls_seqid); | ||
3009 | if (largs.lock_seqid == NULL) | ||
3010 | return -ENOMEM; | ||
3011 | if (!(lsp->ls_seqid.flags & NFS_SEQID_CONFIRMED)) { | ||
3012 | struct nfs4_state_owner *owner = state->owner; | ||
3013 | 3313 | ||
3014 | largs.open_seqid = nfs_alloc_seqid(&owner->so_seqid); | 3314 | if (nfs_wait_on_sequence(data->arg.lock_seqid, task) != 0) |
3015 | if (largs.open_seqid == NULL) | 3315 | return; |
3316 | dprintk("%s: begin!\n", __FUNCTION__); | ||
3317 | /* Do we need to do an open_to_lock_owner? */ | ||
3318 | if (!(data->arg.lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED)) { | ||
3319 | data->arg.open_seqid = nfs_alloc_seqid(&sp->so_seqid); | ||
3320 | if (data->arg.open_seqid == NULL) { | ||
3321 | data->rpc_status = -ENOMEM; | ||
3322 | task->tk_action = NULL; | ||
3016 | goto out; | 3323 | goto out; |
3017 | largs.new_lock_owner = 1; | ||
3018 | status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR); | ||
3019 | /* increment open seqid on success, and seqid mutating errors */ | ||
3020 | if (largs.new_lock_owner != 0) { | ||
3021 | nfs_increment_open_seqid(status, largs.open_seqid); | ||
3022 | if (status == 0) | ||
3023 | nfs_confirm_seqid(&lsp->ls_seqid, 0); | ||
3024 | } | 3324 | } |
3025 | nfs_free_seqid(largs.open_seqid); | 3325 | data->arg.open_stateid = &state->stateid; |
3026 | } else | 3326 | data->arg.new_lock_owner = 1; |
3027 | status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR); | 3327 | } |
3028 | /* increment lock seqid on success, and seqid mutating errors*/ | 3328 | data->timestamp = jiffies; |
3029 | nfs_increment_lock_seqid(status, largs.lock_seqid); | 3329 | rpc_call_setup(task, &msg, 0); |
3030 | /* save the returned stateid. */ | ||
3031 | if (status == 0) { | ||
3032 | memcpy(lsp->ls_stateid.data, res.u.stateid.data, | ||
3033 | sizeof(lsp->ls_stateid.data)); | ||
3034 | lsp->ls_flags |= NFS_LOCK_INITIALIZED; | ||
3035 | } else if (status == -NFS4ERR_DENIED) | ||
3036 | status = -EAGAIN; | ||
3037 | out: | 3330 | out: |
3038 | nfs_free_seqid(largs.lock_seqid); | 3331 | dprintk("%s: done!, ret = %d\n", __FUNCTION__, data->rpc_status); |
3039 | return status; | 3332 | } |
3333 | |||
3334 | static void nfs4_lock_done(struct rpc_task *task, void *calldata) | ||
3335 | { | ||
3336 | struct nfs4_lockdata *data = calldata; | ||
3337 | |||
3338 | dprintk("%s: begin!\n", __FUNCTION__); | ||
3339 | |||
3340 | data->rpc_status = task->tk_status; | ||
3341 | if (RPC_ASSASSINATED(task)) | ||
3342 | goto out; | ||
3343 | if (data->arg.new_lock_owner != 0) { | ||
3344 | nfs_increment_open_seqid(data->rpc_status, data->arg.open_seqid); | ||
3345 | if (data->rpc_status == 0) | ||
3346 | nfs_confirm_seqid(&data->lsp->ls_seqid, 0); | ||
3347 | else | ||
3348 | goto out; | ||
3349 | } | ||
3350 | if (data->rpc_status == 0) { | ||
3351 | memcpy(data->lsp->ls_stateid.data, data->res.stateid.data, | ||
3352 | sizeof(data->lsp->ls_stateid.data)); | ||
3353 | data->lsp->ls_flags |= NFS_LOCK_INITIALIZED; | ||
3354 | renew_lease(NFS_SERVER(data->ctx->dentry->d_inode), data->timestamp); | ||
3355 | } | ||
3356 | nfs_increment_lock_seqid(data->rpc_status, data->arg.lock_seqid); | ||
3357 | out: | ||
3358 | dprintk("%s: done, ret = %d!\n", __FUNCTION__, data->rpc_status); | ||
3359 | } | ||
3360 | |||
3361 | static void nfs4_lock_release(void *calldata) | ||
3362 | { | ||
3363 | struct nfs4_lockdata *data = calldata; | ||
3364 | |||
3365 | dprintk("%s: begin!\n", __FUNCTION__); | ||
3366 | if (data->arg.open_seqid != NULL) | ||
3367 | nfs_free_seqid(data->arg.open_seqid); | ||
3368 | if (data->cancelled != 0) { | ||
3369 | struct rpc_task *task; | ||
3370 | task = nfs4_do_unlck(&data->fl, data->ctx, data->lsp, | ||
3371 | data->arg.lock_seqid); | ||
3372 | if (!IS_ERR(task)) | ||
3373 | rpc_release_task(task); | ||
3374 | dprintk("%s: cancelling lock!\n", __FUNCTION__); | ||
3375 | } else | ||
3376 | nfs_free_seqid(data->arg.lock_seqid); | ||
3377 | nfs4_put_lock_state(data->lsp); | ||
3378 | put_nfs_open_context(data->ctx); | ||
3379 | kfree(data); | ||
3380 | dprintk("%s: done!\n", __FUNCTION__); | ||
3381 | } | ||
3382 | |||
3383 | static const struct rpc_call_ops nfs4_lock_ops = { | ||
3384 | .rpc_call_prepare = nfs4_lock_prepare, | ||
3385 | .rpc_call_done = nfs4_lock_done, | ||
3386 | .rpc_release = nfs4_lock_release, | ||
3387 | }; | ||
3388 | |||
3389 | static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *fl, int reclaim) | ||
3390 | { | ||
3391 | struct nfs4_lockdata *data; | ||
3392 | struct rpc_task *task; | ||
3393 | int ret; | ||
3394 | |||
3395 | dprintk("%s: begin!\n", __FUNCTION__); | ||
3396 | data = nfs4_alloc_lockdata(fl, fl->fl_file->private_data, | ||
3397 | fl->fl_u.nfs4_fl.owner); | ||
3398 | if (data == NULL) | ||
3399 | return -ENOMEM; | ||
3400 | if (IS_SETLKW(cmd)) | ||
3401 | data->arg.block = 1; | ||
3402 | if (reclaim != 0) | ||
3403 | data->arg.reclaim = 1; | ||
3404 | task = rpc_run_task(NFS_CLIENT(state->inode), RPC_TASK_ASYNC, | ||
3405 | &nfs4_lock_ops, data); | ||
3406 | if (IS_ERR(task)) { | ||
3407 | nfs4_lock_release(data); | ||
3408 | return PTR_ERR(task); | ||
3409 | } | ||
3410 | ret = nfs4_wait_for_completion_rpc_task(task); | ||
3411 | if (ret == 0) { | ||
3412 | ret = data->rpc_status; | ||
3413 | if (ret == -NFS4ERR_DENIED) | ||
3414 | ret = -EAGAIN; | ||
3415 | } else | ||
3416 | data->cancelled = 1; | ||
3417 | rpc_release_task(task); | ||
3418 | dprintk("%s: done, ret = %d!\n", __FUNCTION__, ret); | ||
3419 | return ret; | ||
3040 | } | 3420 | } |
3041 | 3421 | ||
3042 | static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request) | 3422 | static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request) |
diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c index a3001628ad32..5d764d8e6d8a 100644 --- a/fs/nfs/nfs4renewd.c +++ b/fs/nfs/nfs4renewd.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #include <linux/nfs4.h> | 54 | #include <linux/nfs4.h> |
55 | #include <linux/nfs_fs.h> | 55 | #include <linux/nfs_fs.h> |
56 | #include "nfs4_fs.h" | 56 | #include "nfs4_fs.h" |
57 | #include "delegation.h" | ||
57 | 58 | ||
58 | #define NFSDBG_FACILITY NFSDBG_PROC | 59 | #define NFSDBG_FACILITY NFSDBG_PROC |
59 | 60 | ||
@@ -61,6 +62,7 @@ void | |||
61 | nfs4_renew_state(void *data) | 62 | nfs4_renew_state(void *data) |
62 | { | 63 | { |
63 | struct nfs4_client *clp = (struct nfs4_client *)data; | 64 | struct nfs4_client *clp = (struct nfs4_client *)data; |
65 | struct rpc_cred *cred; | ||
64 | long lease, timeout; | 66 | long lease, timeout; |
65 | unsigned long last, now; | 67 | unsigned long last, now; |
66 | 68 | ||
@@ -68,7 +70,7 @@ nfs4_renew_state(void *data) | |||
68 | dprintk("%s: start\n", __FUNCTION__); | 70 | dprintk("%s: start\n", __FUNCTION__); |
69 | /* Are there any active superblocks? */ | 71 | /* Are there any active superblocks? */ |
70 | if (list_empty(&clp->cl_superblocks)) | 72 | if (list_empty(&clp->cl_superblocks)) |
71 | goto out; | 73 | goto out; |
72 | spin_lock(&clp->cl_lock); | 74 | spin_lock(&clp->cl_lock); |
73 | lease = clp->cl_lease_time; | 75 | lease = clp->cl_lease_time; |
74 | last = clp->cl_last_renewal; | 76 | last = clp->cl_last_renewal; |
@@ -76,9 +78,17 @@ nfs4_renew_state(void *data) | |||
76 | timeout = (2 * lease) / 3 + (long)last - (long)now; | 78 | timeout = (2 * lease) / 3 + (long)last - (long)now; |
77 | /* Are we close to a lease timeout? */ | 79 | /* Are we close to a lease timeout? */ |
78 | if (time_after(now, last + lease/3)) { | 80 | if (time_after(now, last + lease/3)) { |
81 | cred = nfs4_get_renew_cred(clp); | ||
82 | if (cred == NULL) { | ||
83 | set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); | ||
84 | spin_unlock(&clp->cl_lock); | ||
85 | nfs_expire_all_delegations(clp); | ||
86 | goto out; | ||
87 | } | ||
79 | spin_unlock(&clp->cl_lock); | 88 | spin_unlock(&clp->cl_lock); |
80 | /* Queue an asynchronous RENEW. */ | 89 | /* Queue an asynchronous RENEW. */ |
81 | nfs4_proc_async_renew(clp); | 90 | nfs4_proc_async_renew(clp, cred); |
91 | put_rpccred(cred); | ||
82 | timeout = (2 * lease) / 3; | 92 | timeout = (2 * lease) / 3; |
83 | spin_lock(&clp->cl_lock); | 93 | spin_lock(&clp->cl_lock); |
84 | } else | 94 | } else |
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 5ef4c57618fe..afad0255e7db 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -43,6 +43,8 @@ | |||
43 | #include <linux/smp_lock.h> | 43 | #include <linux/smp_lock.h> |
44 | #include <linux/nfs_fs.h> | 44 | #include <linux/nfs_fs.h> |
45 | #include <linux/nfs_idmap.h> | 45 | #include <linux/nfs_idmap.h> |
46 | #include <linux/kthread.h> | ||
47 | #include <linux/module.h> | ||
46 | #include <linux/workqueue.h> | 48 | #include <linux/workqueue.h> |
47 | #include <linux/bitops.h> | 49 | #include <linux/bitops.h> |
48 | 50 | ||
@@ -57,8 +59,6 @@ const nfs4_stateid zero_stateid; | |||
57 | static DEFINE_SPINLOCK(state_spinlock); | 59 | static DEFINE_SPINLOCK(state_spinlock); |
58 | static LIST_HEAD(nfs4_clientid_list); | 60 | static LIST_HEAD(nfs4_clientid_list); |
59 | 61 | ||
60 | static void nfs4_recover_state(void *); | ||
61 | |||
62 | void | 62 | void |
63 | init_nfsv4_state(struct nfs_server *server) | 63 | init_nfsv4_state(struct nfs_server *server) |
64 | { | 64 | { |
@@ -91,11 +91,10 @@ nfs4_alloc_client(struct in_addr *addr) | |||
91 | 91 | ||
92 | if (nfs_callback_up() < 0) | 92 | if (nfs_callback_up() < 0) |
93 | return NULL; | 93 | return NULL; |
94 | if ((clp = kmalloc(sizeof(*clp), GFP_KERNEL)) == NULL) { | 94 | if ((clp = kzalloc(sizeof(*clp), GFP_KERNEL)) == NULL) { |
95 | nfs_callback_down(); | 95 | nfs_callback_down(); |
96 | return NULL; | 96 | return NULL; |
97 | } | 97 | } |
98 | memset(clp, 0, sizeof(*clp)); | ||
99 | memcpy(&clp->cl_addr, addr, sizeof(clp->cl_addr)); | 98 | memcpy(&clp->cl_addr, addr, sizeof(clp->cl_addr)); |
100 | init_rwsem(&clp->cl_sem); | 99 | init_rwsem(&clp->cl_sem); |
101 | INIT_LIST_HEAD(&clp->cl_delegations); | 100 | INIT_LIST_HEAD(&clp->cl_delegations); |
@@ -103,14 +102,12 @@ nfs4_alloc_client(struct in_addr *addr) | |||
103 | INIT_LIST_HEAD(&clp->cl_unused); | 102 | INIT_LIST_HEAD(&clp->cl_unused); |
104 | spin_lock_init(&clp->cl_lock); | 103 | spin_lock_init(&clp->cl_lock); |
105 | atomic_set(&clp->cl_count, 1); | 104 | atomic_set(&clp->cl_count, 1); |
106 | INIT_WORK(&clp->cl_recoverd, nfs4_recover_state, clp); | ||
107 | INIT_WORK(&clp->cl_renewd, nfs4_renew_state, clp); | 105 | INIT_WORK(&clp->cl_renewd, nfs4_renew_state, clp); |
108 | INIT_LIST_HEAD(&clp->cl_superblocks); | 106 | INIT_LIST_HEAD(&clp->cl_superblocks); |
109 | init_waitqueue_head(&clp->cl_waitq); | ||
110 | rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS4 client"); | 107 | rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS4 client"); |
111 | clp->cl_rpcclient = ERR_PTR(-EINVAL); | 108 | clp->cl_rpcclient = ERR_PTR(-EINVAL); |
112 | clp->cl_boot_time = CURRENT_TIME; | 109 | clp->cl_boot_time = CURRENT_TIME; |
113 | clp->cl_state = 1 << NFS4CLNT_OK; | 110 | clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED; |
114 | return clp; | 111 | return clp; |
115 | } | 112 | } |
116 | 113 | ||
@@ -127,8 +124,6 @@ nfs4_free_client(struct nfs4_client *clp) | |||
127 | kfree(sp); | 124 | kfree(sp); |
128 | } | 125 | } |
129 | BUG_ON(!list_empty(&clp->cl_state_owners)); | 126 | BUG_ON(!list_empty(&clp->cl_state_owners)); |
130 | if (clp->cl_cred) | ||
131 | put_rpccred(clp->cl_cred); | ||
132 | nfs_idmap_delete(clp); | 127 | nfs_idmap_delete(clp); |
133 | if (!IS_ERR(clp->cl_rpcclient)) | 128 | if (!IS_ERR(clp->cl_rpcclient)) |
134 | rpc_shutdown_client(clp->cl_rpcclient); | 129 | rpc_shutdown_client(clp->cl_rpcclient); |
@@ -193,27 +188,22 @@ nfs4_put_client(struct nfs4_client *clp) | |||
193 | list_del(&clp->cl_servers); | 188 | list_del(&clp->cl_servers); |
194 | spin_unlock(&state_spinlock); | 189 | spin_unlock(&state_spinlock); |
195 | BUG_ON(!list_empty(&clp->cl_superblocks)); | 190 | BUG_ON(!list_empty(&clp->cl_superblocks)); |
196 | wake_up_all(&clp->cl_waitq); | ||
197 | rpc_wake_up(&clp->cl_rpcwaitq); | 191 | rpc_wake_up(&clp->cl_rpcwaitq); |
198 | nfs4_kill_renewd(clp); | 192 | nfs4_kill_renewd(clp); |
199 | nfs4_free_client(clp); | 193 | nfs4_free_client(clp); |
200 | } | 194 | } |
201 | 195 | ||
202 | static int __nfs4_init_client(struct nfs4_client *clp) | 196 | static int nfs4_init_client(struct nfs4_client *clp, struct rpc_cred *cred) |
203 | { | 197 | { |
204 | int status = nfs4_proc_setclientid(clp, NFS4_CALLBACK, nfs_callback_tcpport); | 198 | int status = nfs4_proc_setclientid(clp, NFS4_CALLBACK, |
199 | nfs_callback_tcpport, cred); | ||
205 | if (status == 0) | 200 | if (status == 0) |
206 | status = nfs4_proc_setclientid_confirm(clp); | 201 | status = nfs4_proc_setclientid_confirm(clp, cred); |
207 | if (status == 0) | 202 | if (status == 0) |
208 | nfs4_schedule_state_renewal(clp); | 203 | nfs4_schedule_state_renewal(clp); |
209 | return status; | 204 | return status; |
210 | } | 205 | } |
211 | 206 | ||
212 | int nfs4_init_client(struct nfs4_client *clp) | ||
213 | { | ||
214 | return nfs4_map_errors(__nfs4_init_client(clp)); | ||
215 | } | ||
216 | |||
217 | u32 | 207 | u32 |
218 | nfs4_alloc_lockowner_id(struct nfs4_client *clp) | 208 | nfs4_alloc_lockowner_id(struct nfs4_client *clp) |
219 | { | 209 | { |
@@ -235,6 +225,32 @@ nfs4_client_grab_unused(struct nfs4_client *clp, struct rpc_cred *cred) | |||
235 | return sp; | 225 | return sp; |
236 | } | 226 | } |
237 | 227 | ||
228 | struct rpc_cred *nfs4_get_renew_cred(struct nfs4_client *clp) | ||
229 | { | ||
230 | struct nfs4_state_owner *sp; | ||
231 | struct rpc_cred *cred = NULL; | ||
232 | |||
233 | list_for_each_entry(sp, &clp->cl_state_owners, so_list) { | ||
234 | if (list_empty(&sp->so_states)) | ||
235 | continue; | ||
236 | cred = get_rpccred(sp->so_cred); | ||
237 | break; | ||
238 | } | ||
239 | return cred; | ||
240 | } | ||
241 | |||
242 | struct rpc_cred *nfs4_get_setclientid_cred(struct nfs4_client *clp) | ||
243 | { | ||
244 | struct nfs4_state_owner *sp; | ||
245 | |||
246 | if (!list_empty(&clp->cl_state_owners)) { | ||
247 | sp = list_entry(clp->cl_state_owners.next, | ||
248 | struct nfs4_state_owner, so_list); | ||
249 | return get_rpccred(sp->so_cred); | ||
250 | } | ||
251 | return NULL; | ||
252 | } | ||
253 | |||
238 | static struct nfs4_state_owner * | 254 | static struct nfs4_state_owner * |
239 | nfs4_find_state_owner(struct nfs4_client *clp, struct rpc_cred *cred) | 255 | nfs4_find_state_owner(struct nfs4_client *clp, struct rpc_cred *cred) |
240 | { | 256 | { |
@@ -349,14 +365,9 @@ nfs4_alloc_open_state(void) | |||
349 | { | 365 | { |
350 | struct nfs4_state *state; | 366 | struct nfs4_state *state; |
351 | 367 | ||
352 | state = kmalloc(sizeof(*state), GFP_KERNEL); | 368 | state = kzalloc(sizeof(*state), GFP_KERNEL); |
353 | if (!state) | 369 | if (!state) |
354 | return NULL; | 370 | return NULL; |
355 | state->state = 0; | ||
356 | state->nreaders = 0; | ||
357 | state->nwriters = 0; | ||
358 | state->flags = 0; | ||
359 | memset(state->stateid.data, 0, sizeof(state->stateid.data)); | ||
360 | atomic_set(&state->count, 1); | 371 | atomic_set(&state->count, 1); |
361 | INIT_LIST_HEAD(&state->lock_states); | 372 | INIT_LIST_HEAD(&state->lock_states); |
362 | spin_lock_init(&state->state_lock); | 373 | spin_lock_init(&state->state_lock); |
@@ -475,15 +486,23 @@ void nfs4_close_state(struct nfs4_state *state, mode_t mode) | |||
475 | /* Protect against nfs4_find_state() */ | 486 | /* Protect against nfs4_find_state() */ |
476 | spin_lock(&owner->so_lock); | 487 | spin_lock(&owner->so_lock); |
477 | spin_lock(&inode->i_lock); | 488 | spin_lock(&inode->i_lock); |
478 | if (mode & FMODE_READ) | 489 | switch (mode & (FMODE_READ | FMODE_WRITE)) { |
479 | state->nreaders--; | 490 | case FMODE_READ: |
480 | if (mode & FMODE_WRITE) | 491 | state->n_rdonly--; |
481 | state->nwriters--; | 492 | break; |
493 | case FMODE_WRITE: | ||
494 | state->n_wronly--; | ||
495 | break; | ||
496 | case FMODE_READ|FMODE_WRITE: | ||
497 | state->n_rdwr--; | ||
498 | } | ||
482 | oldstate = newstate = state->state; | 499 | oldstate = newstate = state->state; |
483 | if (state->nreaders == 0) | 500 | if (state->n_rdwr == 0) { |
484 | newstate &= ~FMODE_READ; | 501 | if (state->n_rdonly == 0) |
485 | if (state->nwriters == 0) | 502 | newstate &= ~FMODE_READ; |
486 | newstate &= ~FMODE_WRITE; | 503 | if (state->n_wronly == 0) |
504 | newstate &= ~FMODE_WRITE; | ||
505 | } | ||
487 | if (test_bit(NFS_DELEGATED_STATE, &state->flags)) { | 506 | if (test_bit(NFS_DELEGATED_STATE, &state->flags)) { |
488 | nfs4_state_set_mode_locked(state, newstate); | 507 | nfs4_state_set_mode_locked(state, newstate); |
489 | oldstate = newstate; | 508 | oldstate = newstate; |
@@ -733,45 +752,43 @@ out: | |||
733 | } | 752 | } |
734 | 753 | ||
735 | static int reclaimer(void *); | 754 | static int reclaimer(void *); |
736 | struct reclaimer_args { | 755 | |
737 | struct nfs4_client *clp; | 756 | static inline void nfs4_clear_recover_bit(struct nfs4_client *clp) |
738 | struct completion complete; | 757 | { |
739 | }; | 758 | smp_mb__before_clear_bit(); |
759 | clear_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state); | ||
760 | smp_mb__after_clear_bit(); | ||
761 | wake_up_bit(&clp->cl_state, NFS4CLNT_STATE_RECOVER); | ||
762 | rpc_wake_up(&clp->cl_rpcwaitq); | ||
763 | } | ||
740 | 764 | ||
741 | /* | 765 | /* |
742 | * State recovery routine | 766 | * State recovery routine |
743 | */ | 767 | */ |
744 | void | 768 | static void nfs4_recover_state(struct nfs4_client *clp) |
745 | nfs4_recover_state(void *data) | ||
746 | { | 769 | { |
747 | struct nfs4_client *clp = (struct nfs4_client *)data; | 770 | struct task_struct *task; |
748 | struct reclaimer_args args = { | ||
749 | .clp = clp, | ||
750 | }; | ||
751 | might_sleep(); | ||
752 | |||
753 | init_completion(&args.complete); | ||
754 | 771 | ||
755 | if (kernel_thread(reclaimer, &args, CLONE_KERNEL) < 0) | 772 | __module_get(THIS_MODULE); |
756 | goto out_failed_clear; | 773 | atomic_inc(&clp->cl_count); |
757 | wait_for_completion(&args.complete); | 774 | task = kthread_run(reclaimer, clp, "%u.%u.%u.%u-reclaim", |
758 | return; | 775 | NIPQUAD(clp->cl_addr)); |
759 | out_failed_clear: | 776 | if (!IS_ERR(task)) |
760 | set_bit(NFS4CLNT_OK, &clp->cl_state); | 777 | return; |
761 | wake_up_all(&clp->cl_waitq); | 778 | nfs4_clear_recover_bit(clp); |
762 | rpc_wake_up(&clp->cl_rpcwaitq); | 779 | nfs4_put_client(clp); |
780 | module_put(THIS_MODULE); | ||
763 | } | 781 | } |
764 | 782 | ||
765 | /* | 783 | /* |
766 | * Schedule a state recovery attempt | 784 | * Schedule a state recovery attempt |
767 | */ | 785 | */ |
768 | void | 786 | void nfs4_schedule_state_recovery(struct nfs4_client *clp) |
769 | nfs4_schedule_state_recovery(struct nfs4_client *clp) | ||
770 | { | 787 | { |
771 | if (!clp) | 788 | if (!clp) |
772 | return; | 789 | return; |
773 | if (test_and_clear_bit(NFS4CLNT_OK, &clp->cl_state)) | 790 | if (test_and_set_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) == 0) |
774 | schedule_work(&clp->cl_recoverd); | 791 | nfs4_recover_state(clp); |
775 | } | 792 | } |
776 | 793 | ||
777 | static int nfs4_reclaim_locks(struct nfs4_state_recovery_ops *ops, struct nfs4_state *state) | 794 | static int nfs4_reclaim_locks(struct nfs4_state_recovery_ops *ops, struct nfs4_state *state) |
@@ -887,18 +904,14 @@ static void nfs4_state_mark_reclaim(struct nfs4_client *clp) | |||
887 | 904 | ||
888 | static int reclaimer(void *ptr) | 905 | static int reclaimer(void *ptr) |
889 | { | 906 | { |
890 | struct reclaimer_args *args = (struct reclaimer_args *)ptr; | 907 | struct nfs4_client *clp = ptr; |
891 | struct nfs4_client *clp = args->clp; | ||
892 | struct nfs4_state_owner *sp; | 908 | struct nfs4_state_owner *sp; |
893 | struct nfs4_state_recovery_ops *ops; | 909 | struct nfs4_state_recovery_ops *ops; |
910 | struct rpc_cred *cred; | ||
894 | int status = 0; | 911 | int status = 0; |
895 | 912 | ||
896 | daemonize("%u.%u.%u.%u-reclaim", NIPQUAD(clp->cl_addr)); | ||
897 | allow_signal(SIGKILL); | 913 | allow_signal(SIGKILL); |
898 | 914 | ||
899 | atomic_inc(&clp->cl_count); | ||
900 | complete(&args->complete); | ||
901 | |||
902 | /* Ensure exclusive access to NFSv4 state */ | 915 | /* Ensure exclusive access to NFSv4 state */ |
903 | lock_kernel(); | 916 | lock_kernel(); |
904 | down_write(&clp->cl_sem); | 917 | down_write(&clp->cl_sem); |
@@ -906,20 +919,33 @@ static int reclaimer(void *ptr) | |||
906 | if (list_empty(&clp->cl_superblocks)) | 919 | if (list_empty(&clp->cl_superblocks)) |
907 | goto out; | 920 | goto out; |
908 | restart_loop: | 921 | restart_loop: |
909 | status = nfs4_proc_renew(clp); | 922 | ops = &nfs4_network_partition_recovery_ops; |
910 | switch (status) { | 923 | /* Are there any open files on this volume? */ |
911 | case 0: | 924 | cred = nfs4_get_renew_cred(clp); |
912 | case -NFS4ERR_CB_PATH_DOWN: | 925 | if (cred != NULL) { |
913 | goto out; | 926 | /* Yes there are: try to renew the old lease */ |
914 | case -NFS4ERR_STALE_CLIENTID: | 927 | status = nfs4_proc_renew(clp, cred); |
915 | case -NFS4ERR_LEASE_MOVED: | 928 | switch (status) { |
916 | ops = &nfs4_reboot_recovery_ops; | 929 | case 0: |
917 | break; | 930 | case -NFS4ERR_CB_PATH_DOWN: |
918 | default: | 931 | put_rpccred(cred); |
919 | ops = &nfs4_network_partition_recovery_ops; | 932 | goto out; |
920 | }; | 933 | case -NFS4ERR_STALE_CLIENTID: |
934 | case -NFS4ERR_LEASE_MOVED: | ||
935 | ops = &nfs4_reboot_recovery_ops; | ||
936 | } | ||
937 | } else { | ||
938 | /* "reboot" to ensure we clear all state on the server */ | ||
939 | clp->cl_boot_time = CURRENT_TIME; | ||
940 | cred = nfs4_get_setclientid_cred(clp); | ||
941 | } | ||
942 | /* We're going to have to re-establish a clientid */ | ||
921 | nfs4_state_mark_reclaim(clp); | 943 | nfs4_state_mark_reclaim(clp); |
922 | status = __nfs4_init_client(clp); | 944 | status = -ENOENT; |
945 | if (cred != NULL) { | ||
946 | status = nfs4_init_client(clp, cred); | ||
947 | put_rpccred(cred); | ||
948 | } | ||
923 | if (status) | 949 | if (status) |
924 | goto out_error; | 950 | goto out_error; |
925 | /* Mark all delegations for reclaim */ | 951 | /* Mark all delegations for reclaim */ |
@@ -940,14 +966,13 @@ restart_loop: | |||
940 | } | 966 | } |
941 | nfs_delegation_reap_unclaimed(clp); | 967 | nfs_delegation_reap_unclaimed(clp); |
942 | out: | 968 | out: |
943 | set_bit(NFS4CLNT_OK, &clp->cl_state); | ||
944 | up_write(&clp->cl_sem); | 969 | up_write(&clp->cl_sem); |
945 | unlock_kernel(); | 970 | unlock_kernel(); |
946 | wake_up_all(&clp->cl_waitq); | ||
947 | rpc_wake_up(&clp->cl_rpcwaitq); | ||
948 | if (status == -NFS4ERR_CB_PATH_DOWN) | 971 | if (status == -NFS4ERR_CB_PATH_DOWN) |
949 | nfs_handle_cb_pathdown(clp); | 972 | nfs_handle_cb_pathdown(clp); |
973 | nfs4_clear_recover_bit(clp); | ||
950 | nfs4_put_client(clp); | 974 | nfs4_put_client(clp); |
975 | module_put_and_exit(0); | ||
951 | return 0; | 976 | return 0; |
952 | out_error: | 977 | out_error: |
953 | printk(KERN_WARNING "Error: state recovery failed on NFSv4 server %u.%u.%u.%u with error %d\n", | 978 | printk(KERN_WARNING "Error: state recovery failed on NFSv4 server %u.%u.%u.%u with error %d\n", |
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index fbbace8a30c4..4bbf5ef57785 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -392,9 +392,11 @@ static int nfs_stat_to_errno(int); | |||
392 | decode_getattr_maxsz) | 392 | decode_getattr_maxsz) |
393 | #define NFS4_enc_delegreturn_sz (compound_encode_hdr_maxsz + \ | 393 | #define NFS4_enc_delegreturn_sz (compound_encode_hdr_maxsz + \ |
394 | encode_putfh_maxsz + \ | 394 | encode_putfh_maxsz + \ |
395 | encode_delegreturn_maxsz) | 395 | encode_delegreturn_maxsz + \ |
396 | encode_getattr_maxsz) | ||
396 | #define NFS4_dec_delegreturn_sz (compound_decode_hdr_maxsz + \ | 397 | #define NFS4_dec_delegreturn_sz (compound_decode_hdr_maxsz + \ |
397 | decode_delegreturn_maxsz) | 398 | decode_delegreturn_maxsz + \ |
399 | decode_getattr_maxsz) | ||
398 | #define NFS4_enc_getacl_sz (compound_encode_hdr_maxsz + \ | 400 | #define NFS4_enc_getacl_sz (compound_encode_hdr_maxsz + \ |
399 | encode_putfh_maxsz + \ | 401 | encode_putfh_maxsz + \ |
400 | encode_getattr_maxsz) | 402 | encode_getattr_maxsz) |
@@ -564,7 +566,7 @@ static int encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const s | |||
564 | } | 566 | } |
565 | if (iap->ia_valid & ATTR_MODE) { | 567 | if (iap->ia_valid & ATTR_MODE) { |
566 | bmval1 |= FATTR4_WORD1_MODE; | 568 | bmval1 |= FATTR4_WORD1_MODE; |
567 | WRITE32(iap->ia_mode); | 569 | WRITE32(iap->ia_mode & S_IALLUGO); |
568 | } | 570 | } |
569 | if (iap->ia_valid & ATTR_UID) { | 571 | if (iap->ia_valid & ATTR_UID) { |
570 | bmval1 |= FATTR4_WORD1_OWNER; | 572 | bmval1 |= FATTR4_WORD1_OWNER; |
@@ -742,69 +744,80 @@ static int encode_link(struct xdr_stream *xdr, const struct qstr *name) | |||
742 | return 0; | 744 | return 0; |
743 | } | 745 | } |
744 | 746 | ||
747 | static inline int nfs4_lock_type(struct file_lock *fl, int block) | ||
748 | { | ||
749 | if ((fl->fl_type & (F_RDLCK|F_WRLCK|F_UNLCK)) == F_RDLCK) | ||
750 | return block ? NFS4_READW_LT : NFS4_READ_LT; | ||
751 | return block ? NFS4_WRITEW_LT : NFS4_WRITE_LT; | ||
752 | } | ||
753 | |||
754 | static inline uint64_t nfs4_lock_length(struct file_lock *fl) | ||
755 | { | ||
756 | if (fl->fl_end == OFFSET_MAX) | ||
757 | return ~(uint64_t)0; | ||
758 | return fl->fl_end - fl->fl_start + 1; | ||
759 | } | ||
760 | |||
745 | /* | 761 | /* |
746 | * opcode,type,reclaim,offset,length,new_lock_owner = 32 | 762 | * opcode,type,reclaim,offset,length,new_lock_owner = 32 |
747 | * open_seqid,open_stateid,lock_seqid,lock_owner.clientid, lock_owner.id = 40 | 763 | * open_seqid,open_stateid,lock_seqid,lock_owner.clientid, lock_owner.id = 40 |
748 | */ | 764 | */ |
749 | static int encode_lock(struct xdr_stream *xdr, const struct nfs_lockargs *arg) | 765 | static int encode_lock(struct xdr_stream *xdr, const struct nfs_lock_args *args) |
750 | { | 766 | { |
751 | uint32_t *p; | 767 | uint32_t *p; |
752 | struct nfs_lock_opargs *opargs = arg->u.lock; | ||
753 | 768 | ||
754 | RESERVE_SPACE(32); | 769 | RESERVE_SPACE(32); |
755 | WRITE32(OP_LOCK); | 770 | WRITE32(OP_LOCK); |
756 | WRITE32(arg->type); | 771 | WRITE32(nfs4_lock_type(args->fl, args->block)); |
757 | WRITE32(opargs->reclaim); | 772 | WRITE32(args->reclaim); |
758 | WRITE64(arg->offset); | 773 | WRITE64(args->fl->fl_start); |
759 | WRITE64(arg->length); | 774 | WRITE64(nfs4_lock_length(args->fl)); |
760 | WRITE32(opargs->new_lock_owner); | 775 | WRITE32(args->new_lock_owner); |
761 | if (opargs->new_lock_owner){ | 776 | if (args->new_lock_owner){ |
762 | RESERVE_SPACE(40); | 777 | RESERVE_SPACE(40); |
763 | WRITE32(opargs->open_seqid->sequence->counter); | 778 | WRITE32(args->open_seqid->sequence->counter); |
764 | WRITEMEM(opargs->open_stateid->data, sizeof(opargs->open_stateid->data)); | 779 | WRITEMEM(args->open_stateid->data, sizeof(args->open_stateid->data)); |
765 | WRITE32(opargs->lock_seqid->sequence->counter); | 780 | WRITE32(args->lock_seqid->sequence->counter); |
766 | WRITE64(opargs->lock_owner.clientid); | 781 | WRITE64(args->lock_owner.clientid); |
767 | WRITE32(4); | 782 | WRITE32(4); |
768 | WRITE32(opargs->lock_owner.id); | 783 | WRITE32(args->lock_owner.id); |
769 | } | 784 | } |
770 | else { | 785 | else { |
771 | RESERVE_SPACE(20); | 786 | RESERVE_SPACE(20); |
772 | WRITEMEM(opargs->lock_stateid->data, sizeof(opargs->lock_stateid->data)); | 787 | WRITEMEM(args->lock_stateid->data, sizeof(args->lock_stateid->data)); |
773 | WRITE32(opargs->lock_seqid->sequence->counter); | 788 | WRITE32(args->lock_seqid->sequence->counter); |
774 | } | 789 | } |
775 | 790 | ||
776 | return 0; | 791 | return 0; |
777 | } | 792 | } |
778 | 793 | ||
779 | static int encode_lockt(struct xdr_stream *xdr, const struct nfs_lockargs *arg) | 794 | static int encode_lockt(struct xdr_stream *xdr, const struct nfs_lockt_args *args) |
780 | { | 795 | { |
781 | uint32_t *p; | 796 | uint32_t *p; |
782 | struct nfs_lowner *opargs = arg->u.lockt; | ||
783 | 797 | ||
784 | RESERVE_SPACE(40); | 798 | RESERVE_SPACE(40); |
785 | WRITE32(OP_LOCKT); | 799 | WRITE32(OP_LOCKT); |
786 | WRITE32(arg->type); | 800 | WRITE32(nfs4_lock_type(args->fl, 0)); |
787 | WRITE64(arg->offset); | 801 | WRITE64(args->fl->fl_start); |
788 | WRITE64(arg->length); | 802 | WRITE64(nfs4_lock_length(args->fl)); |
789 | WRITE64(opargs->clientid); | 803 | WRITE64(args->lock_owner.clientid); |
790 | WRITE32(4); | 804 | WRITE32(4); |
791 | WRITE32(opargs->id); | 805 | WRITE32(args->lock_owner.id); |
792 | 806 | ||
793 | return 0; | 807 | return 0; |
794 | } | 808 | } |
795 | 809 | ||
796 | static int encode_locku(struct xdr_stream *xdr, const struct nfs_lockargs *arg) | 810 | static int encode_locku(struct xdr_stream *xdr, const struct nfs_locku_args *args) |
797 | { | 811 | { |
798 | uint32_t *p; | 812 | uint32_t *p; |
799 | struct nfs_locku_opargs *opargs = arg->u.locku; | ||
800 | 813 | ||
801 | RESERVE_SPACE(44); | 814 | RESERVE_SPACE(44); |
802 | WRITE32(OP_LOCKU); | 815 | WRITE32(OP_LOCKU); |
803 | WRITE32(arg->type); | 816 | WRITE32(nfs4_lock_type(args->fl, 0)); |
804 | WRITE32(opargs->seqid->sequence->counter); | 817 | WRITE32(args->seqid->sequence->counter); |
805 | WRITEMEM(opargs->stateid->data, sizeof(opargs->stateid->data)); | 818 | WRITEMEM(args->stateid->data, sizeof(args->stateid->data)); |
806 | WRITE64(arg->offset); | 819 | WRITE64(args->fl->fl_start); |
807 | WRITE64(arg->length); | 820 | WRITE64(nfs4_lock_length(args->fl)); |
808 | 821 | ||
809 | return 0; | 822 | return 0; |
810 | } | 823 | } |
@@ -964,9 +977,9 @@ static int encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_con | |||
964 | { | 977 | { |
965 | uint32_t *p; | 978 | uint32_t *p; |
966 | 979 | ||
967 | RESERVE_SPACE(8+sizeof(arg->stateid.data)); | 980 | RESERVE_SPACE(8+sizeof(arg->stateid->data)); |
968 | WRITE32(OP_OPEN_CONFIRM); | 981 | WRITE32(OP_OPEN_CONFIRM); |
969 | WRITEMEM(arg->stateid.data, sizeof(arg->stateid.data)); | 982 | WRITEMEM(arg->stateid->data, sizeof(arg->stateid->data)); |
970 | WRITE32(arg->seqid->sequence->counter); | 983 | WRITE32(arg->seqid->sequence->counter); |
971 | 984 | ||
972 | return 0; | 985 | return 0; |
@@ -1499,9 +1512,6 @@ static int nfs4_xdr_enc_open(struct rpc_rqst *req, uint32_t *p, struct nfs_opena | |||
1499 | }; | 1512 | }; |
1500 | int status; | 1513 | int status; |
1501 | 1514 | ||
1502 | status = nfs_wait_on_sequence(args->seqid, req->rq_task); | ||
1503 | if (status != 0) | ||
1504 | goto out; | ||
1505 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); | 1515 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); |
1506 | encode_compound_hdr(&xdr, &hdr); | 1516 | encode_compound_hdr(&xdr, &hdr); |
1507 | status = encode_putfh(&xdr, args->fh); | 1517 | status = encode_putfh(&xdr, args->fh); |
@@ -1538,9 +1548,6 @@ static int nfs4_xdr_enc_open_confirm(struct rpc_rqst *req, uint32_t *p, struct n | |||
1538 | }; | 1548 | }; |
1539 | int status; | 1549 | int status; |
1540 | 1550 | ||
1541 | status = nfs_wait_on_sequence(args->seqid, req->rq_task); | ||
1542 | if (status != 0) | ||
1543 | goto out; | ||
1544 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); | 1551 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); |
1545 | encode_compound_hdr(&xdr, &hdr); | 1552 | encode_compound_hdr(&xdr, &hdr); |
1546 | status = encode_putfh(&xdr, args->fh); | 1553 | status = encode_putfh(&xdr, args->fh); |
@@ -1558,19 +1565,19 @@ static int nfs4_xdr_enc_open_noattr(struct rpc_rqst *req, uint32_t *p, struct nf | |||
1558 | { | 1565 | { |
1559 | struct xdr_stream xdr; | 1566 | struct xdr_stream xdr; |
1560 | struct compound_hdr hdr = { | 1567 | struct compound_hdr hdr = { |
1561 | .nops = 2, | 1568 | .nops = 3, |
1562 | }; | 1569 | }; |
1563 | int status; | 1570 | int status; |
1564 | 1571 | ||
1565 | status = nfs_wait_on_sequence(args->seqid, req->rq_task); | ||
1566 | if (status != 0) | ||
1567 | goto out; | ||
1568 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); | 1572 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); |
1569 | encode_compound_hdr(&xdr, &hdr); | 1573 | encode_compound_hdr(&xdr, &hdr); |
1570 | status = encode_putfh(&xdr, args->fh); | 1574 | status = encode_putfh(&xdr, args->fh); |
1571 | if (status) | 1575 | if (status) |
1572 | goto out; | 1576 | goto out; |
1573 | status = encode_open(&xdr, args); | 1577 | status = encode_open(&xdr, args); |
1578 | if (status) | ||
1579 | goto out; | ||
1580 | status = encode_getfattr(&xdr, args->bitmask); | ||
1574 | out: | 1581 | out: |
1575 | return status; | 1582 | return status; |
1576 | } | 1583 | } |
@@ -1602,21 +1609,14 @@ out: | |||
1602 | /* | 1609 | /* |
1603 | * Encode a LOCK request | 1610 | * Encode a LOCK request |
1604 | */ | 1611 | */ |
1605 | static int nfs4_xdr_enc_lock(struct rpc_rqst *req, uint32_t *p, struct nfs_lockargs *args) | 1612 | static int nfs4_xdr_enc_lock(struct rpc_rqst *req, uint32_t *p, struct nfs_lock_args *args) |
1606 | { | 1613 | { |
1607 | struct xdr_stream xdr; | 1614 | struct xdr_stream xdr; |
1608 | struct compound_hdr hdr = { | 1615 | struct compound_hdr hdr = { |
1609 | .nops = 2, | 1616 | .nops = 2, |
1610 | }; | 1617 | }; |
1611 | struct nfs_lock_opargs *opargs = args->u.lock; | ||
1612 | int status; | 1618 | int status; |
1613 | 1619 | ||
1614 | status = nfs_wait_on_sequence(opargs->lock_seqid, req->rq_task); | ||
1615 | if (status != 0) | ||
1616 | goto out; | ||
1617 | /* Do we need to do an open_to_lock_owner? */ | ||
1618 | if (opargs->lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED) | ||
1619 | opargs->new_lock_owner = 0; | ||
1620 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); | 1620 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); |
1621 | encode_compound_hdr(&xdr, &hdr); | 1621 | encode_compound_hdr(&xdr, &hdr); |
1622 | status = encode_putfh(&xdr, args->fh); | 1622 | status = encode_putfh(&xdr, args->fh); |
@@ -1630,7 +1630,7 @@ out: | |||
1630 | /* | 1630 | /* |
1631 | * Encode a LOCKT request | 1631 | * Encode a LOCKT request |
1632 | */ | 1632 | */ |
1633 | static int nfs4_xdr_enc_lockt(struct rpc_rqst *req, uint32_t *p, struct nfs_lockargs *args) | 1633 | static int nfs4_xdr_enc_lockt(struct rpc_rqst *req, uint32_t *p, struct nfs_lockt_args *args) |
1634 | { | 1634 | { |
1635 | struct xdr_stream xdr; | 1635 | struct xdr_stream xdr; |
1636 | struct compound_hdr hdr = { | 1636 | struct compound_hdr hdr = { |
@@ -1651,7 +1651,7 @@ out: | |||
1651 | /* | 1651 | /* |
1652 | * Encode a LOCKU request | 1652 | * Encode a LOCKU request |
1653 | */ | 1653 | */ |
1654 | static int nfs4_xdr_enc_locku(struct rpc_rqst *req, uint32_t *p, struct nfs_lockargs *args) | 1654 | static int nfs4_xdr_enc_locku(struct rpc_rqst *req, uint32_t *p, struct nfs_locku_args *args) |
1655 | { | 1655 | { |
1656 | struct xdr_stream xdr; | 1656 | struct xdr_stream xdr; |
1657 | struct compound_hdr hdr = { | 1657 | struct compound_hdr hdr = { |
@@ -1985,14 +1985,20 @@ static int nfs4_xdr_enc_delegreturn(struct rpc_rqst *req, uint32_t *p, const str | |||
1985 | { | 1985 | { |
1986 | struct xdr_stream xdr; | 1986 | struct xdr_stream xdr; |
1987 | struct compound_hdr hdr = { | 1987 | struct compound_hdr hdr = { |
1988 | .nops = 2, | 1988 | .nops = 3, |
1989 | }; | 1989 | }; |
1990 | int status; | 1990 | int status; |
1991 | 1991 | ||
1992 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); | 1992 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); |
1993 | encode_compound_hdr(&xdr, &hdr); | 1993 | encode_compound_hdr(&xdr, &hdr); |
1994 | if ((status = encode_putfh(&xdr, args->fhandle)) == 0) | 1994 | status = encode_putfh(&xdr, args->fhandle); |
1995 | status = encode_delegreturn(&xdr, args->stateid); | 1995 | if (status != 0) |
1996 | goto out; | ||
1997 | status = encode_delegreturn(&xdr, args->stateid); | ||
1998 | if (status != 0) | ||
1999 | goto out; | ||
2000 | status = encode_getfattr(&xdr, args->bitmask); | ||
2001 | out: | ||
1996 | return status; | 2002 | return status; |
1997 | } | 2003 | } |
1998 | 2004 | ||
@@ -2955,55 +2961,64 @@ static int decode_link(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) | |||
2955 | /* | 2961 | /* |
2956 | * We create the owner, so we know a proper owner.id length is 4. | 2962 | * We create the owner, so we know a proper owner.id length is 4. |
2957 | */ | 2963 | */ |
2958 | static int decode_lock_denied (struct xdr_stream *xdr, struct nfs_lock_denied *denied) | 2964 | static int decode_lock_denied (struct xdr_stream *xdr, struct file_lock *fl) |
2959 | { | 2965 | { |
2966 | uint64_t offset, length, clientid; | ||
2960 | uint32_t *p; | 2967 | uint32_t *p; |
2961 | uint32_t namelen; | 2968 | uint32_t namelen, type; |
2962 | 2969 | ||
2963 | READ_BUF(32); | 2970 | READ_BUF(32); |
2964 | READ64(denied->offset); | 2971 | READ64(offset); |
2965 | READ64(denied->length); | 2972 | READ64(length); |
2966 | READ32(denied->type); | 2973 | READ32(type); |
2967 | READ64(denied->owner.clientid); | 2974 | if (fl != NULL) { |
2975 | fl->fl_start = (loff_t)offset; | ||
2976 | fl->fl_end = fl->fl_start + (loff_t)length - 1; | ||
2977 | if (length == ~(uint64_t)0) | ||
2978 | fl->fl_end = OFFSET_MAX; | ||
2979 | fl->fl_type = F_WRLCK; | ||
2980 | if (type & 1) | ||
2981 | fl->fl_type = F_RDLCK; | ||
2982 | fl->fl_pid = 0; | ||
2983 | } | ||
2984 | READ64(clientid); | ||
2968 | READ32(namelen); | 2985 | READ32(namelen); |
2969 | READ_BUF(namelen); | 2986 | READ_BUF(namelen); |
2970 | if (namelen == 4) | ||
2971 | READ32(denied->owner.id); | ||
2972 | return -NFS4ERR_DENIED; | 2987 | return -NFS4ERR_DENIED; |
2973 | } | 2988 | } |
2974 | 2989 | ||
2975 | static int decode_lock(struct xdr_stream *xdr, struct nfs_lockres *res) | 2990 | static int decode_lock(struct xdr_stream *xdr, struct nfs_lock_res *res) |
2976 | { | 2991 | { |
2977 | uint32_t *p; | 2992 | uint32_t *p; |
2978 | int status; | 2993 | int status; |
2979 | 2994 | ||
2980 | status = decode_op_hdr(xdr, OP_LOCK); | 2995 | status = decode_op_hdr(xdr, OP_LOCK); |
2981 | if (status == 0) { | 2996 | if (status == 0) { |
2982 | READ_BUF(sizeof(res->u.stateid.data)); | 2997 | READ_BUF(sizeof(res->stateid.data)); |
2983 | COPYMEM(res->u.stateid.data, sizeof(res->u.stateid.data)); | 2998 | COPYMEM(res->stateid.data, sizeof(res->stateid.data)); |
2984 | } else if (status == -NFS4ERR_DENIED) | 2999 | } else if (status == -NFS4ERR_DENIED) |
2985 | return decode_lock_denied(xdr, &res->u.denied); | 3000 | return decode_lock_denied(xdr, NULL); |
2986 | return status; | 3001 | return status; |
2987 | } | 3002 | } |
2988 | 3003 | ||
2989 | static int decode_lockt(struct xdr_stream *xdr, struct nfs_lockres *res) | 3004 | static int decode_lockt(struct xdr_stream *xdr, struct nfs_lockt_res *res) |
2990 | { | 3005 | { |
2991 | int status; | 3006 | int status; |
2992 | status = decode_op_hdr(xdr, OP_LOCKT); | 3007 | status = decode_op_hdr(xdr, OP_LOCKT); |
2993 | if (status == -NFS4ERR_DENIED) | 3008 | if (status == -NFS4ERR_DENIED) |
2994 | return decode_lock_denied(xdr, &res->u.denied); | 3009 | return decode_lock_denied(xdr, res->denied); |
2995 | return status; | 3010 | return status; |
2996 | } | 3011 | } |
2997 | 3012 | ||
2998 | static int decode_locku(struct xdr_stream *xdr, struct nfs_lockres *res) | 3013 | static int decode_locku(struct xdr_stream *xdr, struct nfs_locku_res *res) |
2999 | { | 3014 | { |
3000 | uint32_t *p; | 3015 | uint32_t *p; |
3001 | int status; | 3016 | int status; |
3002 | 3017 | ||
3003 | status = decode_op_hdr(xdr, OP_LOCKU); | 3018 | status = decode_op_hdr(xdr, OP_LOCKU); |
3004 | if (status == 0) { | 3019 | if (status == 0) { |
3005 | READ_BUF(sizeof(res->u.stateid.data)); | 3020 | READ_BUF(sizeof(res->stateid.data)); |
3006 | COPYMEM(res->u.stateid.data, sizeof(res->u.stateid.data)); | 3021 | COPYMEM(res->stateid.data, sizeof(res->stateid.data)); |
3007 | } | 3022 | } |
3008 | return status; | 3023 | return status; |
3009 | } | 3024 | } |
@@ -3831,6 +3846,9 @@ static int nfs4_xdr_dec_open_noattr(struct rpc_rqst *rqstp, uint32_t *p, struct | |||
3831 | if (status) | 3846 | if (status) |
3832 | goto out; | 3847 | goto out; |
3833 | status = decode_open(&xdr, res); | 3848 | status = decode_open(&xdr, res); |
3849 | if (status) | ||
3850 | goto out; | ||
3851 | decode_getfattr(&xdr, res->f_attr, res->server); | ||
3834 | out: | 3852 | out: |
3835 | return status; | 3853 | return status; |
3836 | } | 3854 | } |
@@ -3864,7 +3882,7 @@ out: | |||
3864 | /* | 3882 | /* |
3865 | * Decode LOCK response | 3883 | * Decode LOCK response |
3866 | */ | 3884 | */ |
3867 | static int nfs4_xdr_dec_lock(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_lockres *res) | 3885 | static int nfs4_xdr_dec_lock(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_lock_res *res) |
3868 | { | 3886 | { |
3869 | struct xdr_stream xdr; | 3887 | struct xdr_stream xdr; |
3870 | struct compound_hdr hdr; | 3888 | struct compound_hdr hdr; |
@@ -3885,7 +3903,7 @@ out: | |||
3885 | /* | 3903 | /* |
3886 | * Decode LOCKT response | 3904 | * Decode LOCKT response |
3887 | */ | 3905 | */ |
3888 | static int nfs4_xdr_dec_lockt(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_lockres *res) | 3906 | static int nfs4_xdr_dec_lockt(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_lockt_res *res) |
3889 | { | 3907 | { |
3890 | struct xdr_stream xdr; | 3908 | struct xdr_stream xdr; |
3891 | struct compound_hdr hdr; | 3909 | struct compound_hdr hdr; |
@@ -3906,7 +3924,7 @@ out: | |||
3906 | /* | 3924 | /* |
3907 | * Decode LOCKU response | 3925 | * Decode LOCKU response |
3908 | */ | 3926 | */ |
3909 | static int nfs4_xdr_dec_locku(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_lockres *res) | 3927 | static int nfs4_xdr_dec_locku(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_locku_res *res) |
3910 | { | 3928 | { |
3911 | struct xdr_stream xdr; | 3929 | struct xdr_stream xdr; |
3912 | struct compound_hdr hdr; | 3930 | struct compound_hdr hdr; |
@@ -4174,7 +4192,7 @@ static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, uint32_t *p, s | |||
4174 | /* | 4192 | /* |
4175 | * DELEGRETURN request | 4193 | * DELEGRETURN request |
4176 | */ | 4194 | */ |
4177 | static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, uint32_t *p, void *dummy) | 4195 | static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_delegreturnres *res) |
4178 | { | 4196 | { |
4179 | struct xdr_stream xdr; | 4197 | struct xdr_stream xdr; |
4180 | struct compound_hdr hdr; | 4198 | struct compound_hdr hdr; |
@@ -4182,11 +4200,14 @@ static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, uint32_t *p, void *d | |||
4182 | 4200 | ||
4183 | xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); | 4201 | xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); |
4184 | status = decode_compound_hdr(&xdr, &hdr); | 4202 | status = decode_compound_hdr(&xdr, &hdr); |
4185 | if (status == 0) { | 4203 | if (status != 0) |
4186 | status = decode_putfh(&xdr); | 4204 | goto out; |
4187 | if (status == 0) | 4205 | status = decode_putfh(&xdr); |
4188 | status = decode_delegreturn(&xdr); | 4206 | if (status != 0) |
4189 | } | 4207 | goto out; |
4208 | status = decode_delegreturn(&xdr); | ||
4209 | decode_getfattr(&xdr, res->fattr, res->server); | ||
4210 | out: | ||
4190 | return status; | 4211 | return status; |
4191 | } | 4212 | } |
4192 | 4213 | ||
diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c index 1b272a135a31..985cc53b8dd5 100644 --- a/fs/nfs/nfsroot.c +++ b/fs/nfs/nfsroot.c | |||
@@ -296,8 +296,8 @@ static int __init root_nfs_name(char *name) | |||
296 | nfs_port = -1; | 296 | nfs_port = -1; |
297 | nfs_data.version = NFS_MOUNT_VERSION; | 297 | nfs_data.version = NFS_MOUNT_VERSION; |
298 | nfs_data.flags = NFS_MOUNT_NONLM; /* No lockd in nfs root yet */ | 298 | nfs_data.flags = NFS_MOUNT_NONLM; /* No lockd in nfs root yet */ |
299 | nfs_data.rsize = NFS_DEF_FILE_IO_BUFFER_SIZE; | 299 | nfs_data.rsize = NFS_DEF_FILE_IO_SIZE; |
300 | nfs_data.wsize = NFS_DEF_FILE_IO_BUFFER_SIZE; | 300 | nfs_data.wsize = NFS_DEF_FILE_IO_SIZE; |
301 | nfs_data.acregmin = 3; | 301 | nfs_data.acregmin = 3; |
302 | nfs_data.acregmax = 60; | 302 | nfs_data.acregmax = 60; |
303 | nfs_data.acdirmin = 30; | 303 | nfs_data.acdirmin = 30; |
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c index e1e3ca5d746b..f5150d71c03d 100644 --- a/fs/nfs/proc.c +++ b/fs/nfs/proc.c | |||
@@ -111,6 +111,9 @@ nfs_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr, | |||
111 | }; | 111 | }; |
112 | int status; | 112 | int status; |
113 | 113 | ||
114 | /* Mask out the non-modebit related stuff from attr->ia_mode */ | ||
115 | sattr->ia_mode &= S_IALLUGO; | ||
116 | |||
114 | dprintk("NFS call setattr\n"); | 117 | dprintk("NFS call setattr\n"); |
115 | nfs_fattr_init(fattr); | 118 | nfs_fattr_init(fattr); |
116 | status = rpc_call(NFS_CLIENT(inode), NFSPROC_SETATTR, &arg, fattr, 0); | 119 | status = rpc_call(NFS_CLIENT(inode), NFSPROC_SETATTR, &arg, fattr, 0); |
@@ -547,10 +550,9 @@ nfs_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle, | |||
547 | 550 | ||
548 | extern u32 * nfs_decode_dirent(u32 *, struct nfs_entry *, int); | 551 | extern u32 * nfs_decode_dirent(u32 *, struct nfs_entry *, int); |
549 | 552 | ||
550 | static void | 553 | static void nfs_read_done(struct rpc_task *task, void *calldata) |
551 | nfs_read_done(struct rpc_task *task) | ||
552 | { | 554 | { |
553 | struct nfs_read_data *data = (struct nfs_read_data *) task->tk_calldata; | 555 | struct nfs_read_data *data = calldata; |
554 | 556 | ||
555 | if (task->tk_status >= 0) { | 557 | if (task->tk_status >= 0) { |
556 | nfs_refresh_inode(data->inode, data->res.fattr); | 558 | nfs_refresh_inode(data->inode, data->res.fattr); |
@@ -560,9 +562,14 @@ nfs_read_done(struct rpc_task *task) | |||
560 | if (data->args.offset + data->args.count >= data->res.fattr->size) | 562 | if (data->args.offset + data->args.count >= data->res.fattr->size) |
561 | data->res.eof = 1; | 563 | data->res.eof = 1; |
562 | } | 564 | } |
563 | nfs_readpage_result(task); | 565 | nfs_readpage_result(task, calldata); |
564 | } | 566 | } |
565 | 567 | ||
568 | static const struct rpc_call_ops nfs_read_ops = { | ||
569 | .rpc_call_done = nfs_read_done, | ||
570 | .rpc_release = nfs_readdata_release, | ||
571 | }; | ||
572 | |||
566 | static void | 573 | static void |
567 | nfs_proc_read_setup(struct nfs_read_data *data) | 574 | nfs_proc_read_setup(struct nfs_read_data *data) |
568 | { | 575 | { |
@@ -580,20 +587,24 @@ nfs_proc_read_setup(struct nfs_read_data *data) | |||
580 | flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0); | 587 | flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0); |
581 | 588 | ||
582 | /* Finalize the task. */ | 589 | /* Finalize the task. */ |
583 | rpc_init_task(task, NFS_CLIENT(inode), nfs_read_done, flags); | 590 | rpc_init_task(task, NFS_CLIENT(inode), flags, &nfs_read_ops, data); |
584 | rpc_call_setup(task, &msg, 0); | 591 | rpc_call_setup(task, &msg, 0); |
585 | } | 592 | } |
586 | 593 | ||
587 | static void | 594 | static void nfs_write_done(struct rpc_task *task, void *calldata) |
588 | nfs_write_done(struct rpc_task *task) | ||
589 | { | 595 | { |
590 | struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata; | 596 | struct nfs_write_data *data = calldata; |
591 | 597 | ||
592 | if (task->tk_status >= 0) | 598 | if (task->tk_status >= 0) |
593 | nfs_post_op_update_inode(data->inode, data->res.fattr); | 599 | nfs_post_op_update_inode(data->inode, data->res.fattr); |
594 | nfs_writeback_done(task); | 600 | nfs_writeback_done(task, calldata); |
595 | } | 601 | } |
596 | 602 | ||
603 | static const struct rpc_call_ops nfs_write_ops = { | ||
604 | .rpc_call_done = nfs_write_done, | ||
605 | .rpc_release = nfs_writedata_release, | ||
606 | }; | ||
607 | |||
597 | static void | 608 | static void |
598 | nfs_proc_write_setup(struct nfs_write_data *data, int how) | 609 | nfs_proc_write_setup(struct nfs_write_data *data, int how) |
599 | { | 610 | { |
@@ -614,7 +625,7 @@ nfs_proc_write_setup(struct nfs_write_data *data, int how) | |||
614 | flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC; | 625 | flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC; |
615 | 626 | ||
616 | /* Finalize the task. */ | 627 | /* Finalize the task. */ |
617 | rpc_init_task(task, NFS_CLIENT(inode), nfs_write_done, flags); | 628 | rpc_init_task(task, NFS_CLIENT(inode), flags, &nfs_write_ops, data); |
618 | rpc_call_setup(task, &msg, 0); | 629 | rpc_call_setup(task, &msg, 0); |
619 | } | 630 | } |
620 | 631 | ||
diff --git a/fs/nfs/read.c b/fs/nfs/read.c index 5f20eafba8ec..05eb43fadf8e 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c | |||
@@ -42,9 +42,8 @@ mempool_t *nfs_rdata_mempool; | |||
42 | 42 | ||
43 | #define MIN_POOL_READ (32) | 43 | #define MIN_POOL_READ (32) |
44 | 44 | ||
45 | void nfs_readdata_release(struct rpc_task *task) | 45 | void nfs_readdata_release(void *data) |
46 | { | 46 | { |
47 | struct nfs_read_data *data = (struct nfs_read_data *)task->tk_calldata; | ||
48 | nfs_readdata_free(data); | 47 | nfs_readdata_free(data); |
49 | } | 48 | } |
50 | 49 | ||
@@ -84,7 +83,7 @@ static int nfs_readpage_sync(struct nfs_open_context *ctx, struct inode *inode, | |||
84 | int result; | 83 | int result; |
85 | struct nfs_read_data *rdata; | 84 | struct nfs_read_data *rdata; |
86 | 85 | ||
87 | rdata = nfs_readdata_alloc(); | 86 | rdata = nfs_readdata_alloc(1); |
88 | if (!rdata) | 87 | if (!rdata) |
89 | return -ENOMEM; | 88 | return -ENOMEM; |
90 | 89 | ||
@@ -220,9 +219,6 @@ static void nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data, | |||
220 | NFS_PROTO(inode)->read_setup(data); | 219 | NFS_PROTO(inode)->read_setup(data); |
221 | 220 | ||
222 | data->task.tk_cookie = (unsigned long)inode; | 221 | data->task.tk_cookie = (unsigned long)inode; |
223 | data->task.tk_calldata = data; | ||
224 | /* Release requests */ | ||
225 | data->task.tk_release = nfs_readdata_release; | ||
226 | 222 | ||
227 | dprintk("NFS: %4d initiated read call (req %s/%Ld, %u bytes @ offset %Lu)\n", | 223 | dprintk("NFS: %4d initiated read call (req %s/%Ld, %u bytes @ offset %Lu)\n", |
228 | data->task.tk_pid, | 224 | data->task.tk_pid, |
@@ -287,7 +283,7 @@ static int nfs_pagein_multi(struct list_head *head, struct inode *inode) | |||
287 | 283 | ||
288 | nbytes = req->wb_bytes; | 284 | nbytes = req->wb_bytes; |
289 | for(;;) { | 285 | for(;;) { |
290 | data = nfs_readdata_alloc(); | 286 | data = nfs_readdata_alloc(1); |
291 | if (!data) | 287 | if (!data) |
292 | goto out_bad; | 288 | goto out_bad; |
293 | INIT_LIST_HEAD(&data->pages); | 289 | INIT_LIST_HEAD(&data->pages); |
@@ -343,7 +339,7 @@ static int nfs_pagein_one(struct list_head *head, struct inode *inode) | |||
343 | if (NFS_SERVER(inode)->rsize < PAGE_CACHE_SIZE) | 339 | if (NFS_SERVER(inode)->rsize < PAGE_CACHE_SIZE) |
344 | return nfs_pagein_multi(head, inode); | 340 | return nfs_pagein_multi(head, inode); |
345 | 341 | ||
346 | data = nfs_readdata_alloc(); | 342 | data = nfs_readdata_alloc(NFS_SERVER(inode)->rpages); |
347 | if (!data) | 343 | if (!data) |
348 | goto out_bad; | 344 | goto out_bad; |
349 | 345 | ||
@@ -452,9 +448,9 @@ static void nfs_readpage_result_full(struct nfs_read_data *data, int status) | |||
452 | * This is the callback from RPC telling us whether a reply was | 448 | * This is the callback from RPC telling us whether a reply was |
453 | * received or some error occurred (timeout or socket shutdown). | 449 | * received or some error occurred (timeout or socket shutdown). |
454 | */ | 450 | */ |
455 | void nfs_readpage_result(struct rpc_task *task) | 451 | void nfs_readpage_result(struct rpc_task *task, void *calldata) |
456 | { | 452 | { |
457 | struct nfs_read_data *data = (struct nfs_read_data *)task->tk_calldata; | 453 | struct nfs_read_data *data = calldata; |
458 | struct nfs_readargs *argp = &data->args; | 454 | struct nfs_readargs *argp = &data->args; |
459 | struct nfs_readres *resp = &data->res; | 455 | struct nfs_readres *resp = &data->res; |
460 | int status = task->tk_status; | 456 | int status = task->tk_status; |
diff --git a/fs/nfs/sysctl.c b/fs/nfs/sysctl.c new file mode 100644 index 000000000000..4c486eb867ca --- /dev/null +++ b/fs/nfs/sysctl.c | |||
@@ -0,0 +1,84 @@ | |||
1 | /* | ||
2 | * linux/fs/nfs/sysctl.c | ||
3 | * | ||
4 | * Sysctl interface to NFS parameters | ||
5 | */ | ||
6 | #include <linux/config.h> | ||
7 | #include <linux/types.h> | ||
8 | #include <linux/linkage.h> | ||
9 | #include <linux/ctype.h> | ||
10 | #include <linux/fs.h> | ||
11 | #include <linux/sysctl.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/nfs4.h> | ||
14 | #include <linux/nfs_idmap.h> | ||
15 | |||
16 | #include "callback.h" | ||
17 | |||
18 | static const int nfs_set_port_min = 0; | ||
19 | static const int nfs_set_port_max = 65535; | ||
20 | static struct ctl_table_header *nfs_callback_sysctl_table; | ||
21 | /* | ||
22 | * Something that isn't CTL_ANY, CTL_NONE or a value that may clash. | ||
23 | * Use the same values as fs/lockd/svc.c | ||
24 | */ | ||
25 | #define CTL_UNNUMBERED -2 | ||
26 | |||
27 | static ctl_table nfs_cb_sysctls[] = { | ||
28 | #ifdef CONFIG_NFS_V4 | ||
29 | { | ||
30 | .ctl_name = CTL_UNNUMBERED, | ||
31 | .procname = "nfs_callback_tcpport", | ||
32 | .data = &nfs_callback_set_tcpport, | ||
33 | .maxlen = sizeof(int), | ||
34 | .mode = 0644, | ||
35 | .proc_handler = &proc_dointvec_minmax, | ||
36 | .extra1 = (int *)&nfs_set_port_min, | ||
37 | .extra2 = (int *)&nfs_set_port_max, | ||
38 | }, | ||
39 | { | ||
40 | .ctl_name = CTL_UNNUMBERED, | ||
41 | .procname = "idmap_cache_timeout", | ||
42 | .data = &nfs_idmap_cache_timeout, | ||
43 | .maxlen = sizeof(int), | ||
44 | .mode = 0644, | ||
45 | .proc_handler = &proc_dointvec_jiffies, | ||
46 | .strategy = &sysctl_jiffies, | ||
47 | }, | ||
48 | #endif | ||
49 | { .ctl_name = 0 } | ||
50 | }; | ||
51 | |||
52 | static ctl_table nfs_cb_sysctl_dir[] = { | ||
53 | { | ||
54 | .ctl_name = CTL_UNNUMBERED, | ||
55 | .procname = "nfs", | ||
56 | .mode = 0555, | ||
57 | .child = nfs_cb_sysctls, | ||
58 | }, | ||
59 | { .ctl_name = 0 } | ||
60 | }; | ||
61 | |||
62 | static ctl_table nfs_cb_sysctl_root[] = { | ||
63 | { | ||
64 | .ctl_name = CTL_FS, | ||
65 | .procname = "fs", | ||
66 | .mode = 0555, | ||
67 | .child = nfs_cb_sysctl_dir, | ||
68 | }, | ||
69 | { .ctl_name = 0 } | ||
70 | }; | ||
71 | |||
72 | int nfs_register_sysctl(void) | ||
73 | { | ||
74 | nfs_callback_sysctl_table = register_sysctl_table(nfs_cb_sysctl_root, 0); | ||
75 | if (nfs_callback_sysctl_table == NULL) | ||
76 | return -ENOMEM; | ||
77 | return 0; | ||
78 | } | ||
79 | |||
80 | void nfs_unregister_sysctl(void) | ||
81 | { | ||
82 | unregister_sysctl_table(nfs_callback_sysctl_table); | ||
83 | nfs_callback_sysctl_table = NULL; | ||
84 | } | ||
diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c index d639d172d568..a65c7b53d558 100644 --- a/fs/nfs/unlink.c +++ b/fs/nfs/unlink.c | |||
@@ -87,10 +87,9 @@ nfs_copy_dname(struct dentry *dentry, struct nfs_unlinkdata *data) | |||
87 | * We delay initializing RPC info until after the call to dentry_iput() | 87 | * We delay initializing RPC info until after the call to dentry_iput() |
88 | * in order to minimize races against rename(). | 88 | * in order to minimize races against rename(). |
89 | */ | 89 | */ |
90 | static void | 90 | static void nfs_async_unlink_init(struct rpc_task *task, void *calldata) |
91 | nfs_async_unlink_init(struct rpc_task *task) | ||
92 | { | 91 | { |
93 | struct nfs_unlinkdata *data = (struct nfs_unlinkdata *)task->tk_calldata; | 92 | struct nfs_unlinkdata *data = calldata; |
94 | struct dentry *dir = data->dir; | 93 | struct dentry *dir = data->dir; |
95 | struct rpc_message msg = { | 94 | struct rpc_message msg = { |
96 | .rpc_cred = data->cred, | 95 | .rpc_cred = data->cred, |
@@ -116,10 +115,9 @@ nfs_async_unlink_init(struct rpc_task *task) | |||
116 | * | 115 | * |
117 | * Do the directory attribute update. | 116 | * Do the directory attribute update. |
118 | */ | 117 | */ |
119 | static void | 118 | static void nfs_async_unlink_done(struct rpc_task *task, void *calldata) |
120 | nfs_async_unlink_done(struct rpc_task *task) | ||
121 | { | 119 | { |
122 | struct nfs_unlinkdata *data = (struct nfs_unlinkdata *)task->tk_calldata; | 120 | struct nfs_unlinkdata *data = calldata; |
123 | struct dentry *dir = data->dir; | 121 | struct dentry *dir = data->dir; |
124 | struct inode *dir_i; | 122 | struct inode *dir_i; |
125 | 123 | ||
@@ -141,13 +139,18 @@ nfs_async_unlink_done(struct rpc_task *task) | |||
141 | * We need to call nfs_put_unlinkdata as a 'tk_release' task since the | 139 | * We need to call nfs_put_unlinkdata as a 'tk_release' task since the |
142 | * rpc_task would be freed too. | 140 | * rpc_task would be freed too. |
143 | */ | 141 | */ |
144 | static void | 142 | static void nfs_async_unlink_release(void *calldata) |
145 | nfs_async_unlink_release(struct rpc_task *task) | ||
146 | { | 143 | { |
147 | struct nfs_unlinkdata *data = (struct nfs_unlinkdata *)task->tk_calldata; | 144 | struct nfs_unlinkdata *data = calldata; |
148 | nfs_put_unlinkdata(data); | 145 | nfs_put_unlinkdata(data); |
149 | } | 146 | } |
150 | 147 | ||
148 | static const struct rpc_call_ops nfs_unlink_ops = { | ||
149 | .rpc_call_prepare = nfs_async_unlink_init, | ||
150 | .rpc_call_done = nfs_async_unlink_done, | ||
151 | .rpc_release = nfs_async_unlink_release, | ||
152 | }; | ||
153 | |||
151 | /** | 154 | /** |
152 | * nfs_async_unlink - asynchronous unlinking of a file | 155 | * nfs_async_unlink - asynchronous unlinking of a file |
153 | * @dentry: dentry to unlink | 156 | * @dentry: dentry to unlink |
@@ -157,7 +160,6 @@ nfs_async_unlink(struct dentry *dentry) | |||
157 | { | 160 | { |
158 | struct dentry *dir = dentry->d_parent; | 161 | struct dentry *dir = dentry->d_parent; |
159 | struct nfs_unlinkdata *data; | 162 | struct nfs_unlinkdata *data; |
160 | struct rpc_task *task; | ||
161 | struct rpc_clnt *clnt = NFS_CLIENT(dir->d_inode); | 163 | struct rpc_clnt *clnt = NFS_CLIENT(dir->d_inode); |
162 | int status = -ENOMEM; | 164 | int status = -ENOMEM; |
163 | 165 | ||
@@ -178,17 +180,13 @@ nfs_async_unlink(struct dentry *dentry) | |||
178 | nfs_deletes = data; | 180 | nfs_deletes = data; |
179 | data->count = 1; | 181 | data->count = 1; |
180 | 182 | ||
181 | task = &data->task; | 183 | rpc_init_task(&data->task, clnt, RPC_TASK_ASYNC, &nfs_unlink_ops, data); |
182 | rpc_init_task(task, clnt, nfs_async_unlink_done , RPC_TASK_ASYNC); | ||
183 | task->tk_calldata = data; | ||
184 | task->tk_action = nfs_async_unlink_init; | ||
185 | task->tk_release = nfs_async_unlink_release; | ||
186 | 184 | ||
187 | spin_lock(&dentry->d_lock); | 185 | spin_lock(&dentry->d_lock); |
188 | dentry->d_flags |= DCACHE_NFSFS_RENAMED; | 186 | dentry->d_flags |= DCACHE_NFSFS_RENAMED; |
189 | spin_unlock(&dentry->d_lock); | 187 | spin_unlock(&dentry->d_lock); |
190 | 188 | ||
191 | rpc_sleep_on(&nfs_delete_queue, task, NULL, NULL); | 189 | rpc_sleep_on(&nfs_delete_queue, &data->task, NULL, NULL); |
192 | status = 0; | 190 | status = 0; |
193 | out: | 191 | out: |
194 | return status; | 192 | return status; |
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 3107908e5f3f..9449b6835509 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -89,24 +89,38 @@ static mempool_t *nfs_commit_mempool; | |||
89 | 89 | ||
90 | static DECLARE_WAIT_QUEUE_HEAD(nfs_write_congestion); | 90 | static DECLARE_WAIT_QUEUE_HEAD(nfs_write_congestion); |
91 | 91 | ||
92 | static inline struct nfs_write_data *nfs_commit_alloc(void) | 92 | static inline struct nfs_write_data *nfs_commit_alloc(unsigned int pagecount) |
93 | { | 93 | { |
94 | struct nfs_write_data *p = mempool_alloc(nfs_commit_mempool, SLAB_NOFS); | 94 | struct nfs_write_data *p = mempool_alloc(nfs_commit_mempool, SLAB_NOFS); |
95 | |||
95 | if (p) { | 96 | if (p) { |
96 | memset(p, 0, sizeof(*p)); | 97 | memset(p, 0, sizeof(*p)); |
97 | INIT_LIST_HEAD(&p->pages); | 98 | INIT_LIST_HEAD(&p->pages); |
99 | if (pagecount < NFS_PAGEVEC_SIZE) | ||
100 | p->pagevec = &p->page_array[0]; | ||
101 | else { | ||
102 | size_t size = ++pagecount * sizeof(struct page *); | ||
103 | p->pagevec = kmalloc(size, GFP_NOFS); | ||
104 | if (p->pagevec) { | ||
105 | memset(p->pagevec, 0, size); | ||
106 | } else { | ||
107 | mempool_free(p, nfs_commit_mempool); | ||
108 | p = NULL; | ||
109 | } | ||
110 | } | ||
98 | } | 111 | } |
99 | return p; | 112 | return p; |
100 | } | 113 | } |
101 | 114 | ||
102 | static inline void nfs_commit_free(struct nfs_write_data *p) | 115 | static inline void nfs_commit_free(struct nfs_write_data *p) |
103 | { | 116 | { |
117 | if (p && (p->pagevec != &p->page_array[0])) | ||
118 | kfree(p->pagevec); | ||
104 | mempool_free(p, nfs_commit_mempool); | 119 | mempool_free(p, nfs_commit_mempool); |
105 | } | 120 | } |
106 | 121 | ||
107 | static void nfs_writedata_release(struct rpc_task *task) | 122 | void nfs_writedata_release(void *wdata) |
108 | { | 123 | { |
109 | struct nfs_write_data *wdata = (struct nfs_write_data *)task->tk_calldata; | ||
110 | nfs_writedata_free(wdata); | 124 | nfs_writedata_free(wdata); |
111 | } | 125 | } |
112 | 126 | ||
@@ -168,7 +182,7 @@ static int nfs_writepage_sync(struct nfs_open_context *ctx, struct inode *inode, | |||
168 | int result, written = 0; | 182 | int result, written = 0; |
169 | struct nfs_write_data *wdata; | 183 | struct nfs_write_data *wdata; |
170 | 184 | ||
171 | wdata = nfs_writedata_alloc(); | 185 | wdata = nfs_writedata_alloc(1); |
172 | if (!wdata) | 186 | if (!wdata) |
173 | return -ENOMEM; | 187 | return -ENOMEM; |
174 | 188 | ||
@@ -232,19 +246,16 @@ static int nfs_writepage_async(struct nfs_open_context *ctx, | |||
232 | unsigned int offset, unsigned int count) | 246 | unsigned int offset, unsigned int count) |
233 | { | 247 | { |
234 | struct nfs_page *req; | 248 | struct nfs_page *req; |
235 | int status; | ||
236 | 249 | ||
237 | req = nfs_update_request(ctx, inode, page, offset, count); | 250 | req = nfs_update_request(ctx, inode, page, offset, count); |
238 | status = (IS_ERR(req)) ? PTR_ERR(req) : 0; | 251 | if (IS_ERR(req)) |
239 | if (status < 0) | 252 | return PTR_ERR(req); |
240 | goto out; | ||
241 | /* Update file length */ | 253 | /* Update file length */ |
242 | nfs_grow_file(page, offset, count); | 254 | nfs_grow_file(page, offset, count); |
243 | /* Set the PG_uptodate flag? */ | 255 | /* Set the PG_uptodate flag? */ |
244 | nfs_mark_uptodate(page, offset, count); | 256 | nfs_mark_uptodate(page, offset, count); |
245 | nfs_unlock_request(req); | 257 | nfs_unlock_request(req); |
246 | out: | 258 | return 0; |
247 | return status; | ||
248 | } | 259 | } |
249 | 260 | ||
250 | static int wb_priority(struct writeback_control *wbc) | 261 | static int wb_priority(struct writeback_control *wbc) |
@@ -304,11 +315,8 @@ do_it: | |||
304 | lock_kernel(); | 315 | lock_kernel(); |
305 | if (!IS_SYNC(inode) && inode_referenced) { | 316 | if (!IS_SYNC(inode) && inode_referenced) { |
306 | err = nfs_writepage_async(ctx, inode, page, 0, offset); | 317 | err = nfs_writepage_async(ctx, inode, page, 0, offset); |
307 | if (err >= 0) { | 318 | if (!wbc->for_writepages) |
308 | err = 0; | 319 | nfs_flush_inode(inode, 0, 0, wb_priority(wbc)); |
309 | if (wbc->for_reclaim) | ||
310 | nfs_flush_inode(inode, 0, 0, FLUSH_STABLE); | ||
311 | } | ||
312 | } else { | 320 | } else { |
313 | err = nfs_writepage_sync(ctx, inode, page, 0, | 321 | err = nfs_writepage_sync(ctx, inode, page, 0, |
314 | offset, priority); | 322 | offset, priority); |
@@ -877,9 +885,6 @@ static void nfs_write_rpcsetup(struct nfs_page *req, | |||
877 | 885 | ||
878 | data->task.tk_priority = flush_task_priority(how); | 886 | data->task.tk_priority = flush_task_priority(how); |
879 | data->task.tk_cookie = (unsigned long)inode; | 887 | data->task.tk_cookie = (unsigned long)inode; |
880 | data->task.tk_calldata = data; | ||
881 | /* Release requests */ | ||
882 | data->task.tk_release = nfs_writedata_release; | ||
883 | 888 | ||
884 | dprintk("NFS: %4d initiated write call (req %s/%Ld, %u bytes @ offset %Lu)\n", | 889 | dprintk("NFS: %4d initiated write call (req %s/%Ld, %u bytes @ offset %Lu)\n", |
885 | data->task.tk_pid, | 890 | data->task.tk_pid, |
@@ -919,7 +924,7 @@ static int nfs_flush_multi(struct list_head *head, struct inode *inode, int how) | |||
919 | 924 | ||
920 | nbytes = req->wb_bytes; | 925 | nbytes = req->wb_bytes; |
921 | for (;;) { | 926 | for (;;) { |
922 | data = nfs_writedata_alloc(); | 927 | data = nfs_writedata_alloc(1); |
923 | if (!data) | 928 | if (!data) |
924 | goto out_bad; | 929 | goto out_bad; |
925 | list_add(&data->pages, &list); | 930 | list_add(&data->pages, &list); |
@@ -983,7 +988,7 @@ static int nfs_flush_one(struct list_head *head, struct inode *inode, int how) | |||
983 | if (NFS_SERVER(inode)->wsize < PAGE_CACHE_SIZE) | 988 | if (NFS_SERVER(inode)->wsize < PAGE_CACHE_SIZE) |
984 | return nfs_flush_multi(head, inode, how); | 989 | return nfs_flush_multi(head, inode, how); |
985 | 990 | ||
986 | data = nfs_writedata_alloc(); | 991 | data = nfs_writedata_alloc(NFS_SERVER(inode)->wpages); |
987 | if (!data) | 992 | if (!data) |
988 | goto out_bad; | 993 | goto out_bad; |
989 | 994 | ||
@@ -1137,9 +1142,9 @@ static void nfs_writeback_done_full(struct nfs_write_data *data, int status) | |||
1137 | /* | 1142 | /* |
1138 | * This function is called when the WRITE call is complete. | 1143 | * This function is called when the WRITE call is complete. |
1139 | */ | 1144 | */ |
1140 | void nfs_writeback_done(struct rpc_task *task) | 1145 | void nfs_writeback_done(struct rpc_task *task, void *calldata) |
1141 | { | 1146 | { |
1142 | struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata; | 1147 | struct nfs_write_data *data = calldata; |
1143 | struct nfs_writeargs *argp = &data->args; | 1148 | struct nfs_writeargs *argp = &data->args; |
1144 | struct nfs_writeres *resp = &data->res; | 1149 | struct nfs_writeres *resp = &data->res; |
1145 | 1150 | ||
@@ -1206,9 +1211,8 @@ void nfs_writeback_done(struct rpc_task *task) | |||
1206 | 1211 | ||
1207 | 1212 | ||
1208 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) | 1213 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) |
1209 | static void nfs_commit_release(struct rpc_task *task) | 1214 | void nfs_commit_release(void *wdata) |
1210 | { | 1215 | { |
1211 | struct nfs_write_data *wdata = (struct nfs_write_data *)task->tk_calldata; | ||
1212 | nfs_commit_free(wdata); | 1216 | nfs_commit_free(wdata); |
1213 | } | 1217 | } |
1214 | 1218 | ||
@@ -1244,9 +1248,6 @@ static void nfs_commit_rpcsetup(struct list_head *head, | |||
1244 | 1248 | ||
1245 | data->task.tk_priority = flush_task_priority(how); | 1249 | data->task.tk_priority = flush_task_priority(how); |
1246 | data->task.tk_cookie = (unsigned long)inode; | 1250 | data->task.tk_cookie = (unsigned long)inode; |
1247 | data->task.tk_calldata = data; | ||
1248 | /* Release requests */ | ||
1249 | data->task.tk_release = nfs_commit_release; | ||
1250 | 1251 | ||
1251 | dprintk("NFS: %4d initiated commit call\n", data->task.tk_pid); | 1252 | dprintk("NFS: %4d initiated commit call\n", data->task.tk_pid); |
1252 | } | 1253 | } |
@@ -1255,12 +1256,12 @@ static void nfs_commit_rpcsetup(struct list_head *head, | |||
1255 | * Commit dirty pages | 1256 | * Commit dirty pages |
1256 | */ | 1257 | */ |
1257 | static int | 1258 | static int |
1258 | nfs_commit_list(struct list_head *head, int how) | 1259 | nfs_commit_list(struct inode *inode, struct list_head *head, int how) |
1259 | { | 1260 | { |
1260 | struct nfs_write_data *data; | 1261 | struct nfs_write_data *data; |
1261 | struct nfs_page *req; | 1262 | struct nfs_page *req; |
1262 | 1263 | ||
1263 | data = nfs_commit_alloc(); | 1264 | data = nfs_commit_alloc(NFS_SERVER(inode)->wpages); |
1264 | 1265 | ||
1265 | if (!data) | 1266 | if (!data) |
1266 | goto out_bad; | 1267 | goto out_bad; |
@@ -1283,10 +1284,9 @@ nfs_commit_list(struct list_head *head, int how) | |||
1283 | /* | 1284 | /* |
1284 | * COMMIT call returned | 1285 | * COMMIT call returned |
1285 | */ | 1286 | */ |
1286 | void | 1287 | void nfs_commit_done(struct rpc_task *task, void *calldata) |
1287 | nfs_commit_done(struct rpc_task *task) | ||
1288 | { | 1288 | { |
1289 | struct nfs_write_data *data = (struct nfs_write_data *)task->tk_calldata; | 1289 | struct nfs_write_data *data = calldata; |
1290 | struct nfs_page *req; | 1290 | struct nfs_page *req; |
1291 | int res = 0; | 1291 | int res = 0; |
1292 | 1292 | ||
@@ -1366,7 +1366,7 @@ int nfs_commit_inode(struct inode *inode, int how) | |||
1366 | res = nfs_scan_commit(inode, &head, 0, 0); | 1366 | res = nfs_scan_commit(inode, &head, 0, 0); |
1367 | spin_unlock(&nfsi->req_lock); | 1367 | spin_unlock(&nfsi->req_lock); |
1368 | if (res) { | 1368 | if (res) { |
1369 | error = nfs_commit_list(&head, how); | 1369 | error = nfs_commit_list(inode, &head, how); |
1370 | if (error < 0) | 1370 | if (error < 0) |
1371 | return error; | 1371 | return error; |
1372 | } | 1372 | } |
@@ -1377,22 +1377,23 @@ int nfs_commit_inode(struct inode *inode, int how) | |||
1377 | int nfs_sync_inode(struct inode *inode, unsigned long idx_start, | 1377 | int nfs_sync_inode(struct inode *inode, unsigned long idx_start, |
1378 | unsigned int npages, int how) | 1378 | unsigned int npages, int how) |
1379 | { | 1379 | { |
1380 | int error, | 1380 | int nocommit = how & FLUSH_NOCOMMIT; |
1381 | wait; | 1381 | int wait = how & FLUSH_WAIT; |
1382 | int error; | ||
1382 | 1383 | ||
1383 | wait = how & FLUSH_WAIT; | 1384 | how &= ~(FLUSH_WAIT|FLUSH_NOCOMMIT); |
1384 | how &= ~FLUSH_WAIT; | ||
1385 | 1385 | ||
1386 | do { | 1386 | do { |
1387 | error = 0; | 1387 | if (wait) { |
1388 | if (wait) | ||
1389 | error = nfs_wait_on_requests(inode, idx_start, npages); | 1388 | error = nfs_wait_on_requests(inode, idx_start, npages); |
1390 | if (error == 0) | 1389 | if (error != 0) |
1391 | error = nfs_flush_inode(inode, idx_start, npages, how); | 1390 | continue; |
1392 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) | 1391 | } |
1393 | if (error == 0) | 1392 | error = nfs_flush_inode(inode, idx_start, npages, how); |
1393 | if (error != 0) | ||
1394 | continue; | ||
1395 | if (!nocommit) | ||
1394 | error = nfs_commit_inode(inode, how); | 1396 | error = nfs_commit_inode(inode, how); |
1395 | #endif | ||
1396 | } while (error > 0); | 1397 | } while (error > 0); |
1397 | return error; | 1398 | return error; |
1398 | } | 1399 | } |
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index 583c0710e45e..d828662d737d 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c | |||
@@ -53,7 +53,7 @@ | |||
53 | #define NFSPROC4_CB_COMPOUND 1 | 53 | #define NFSPROC4_CB_COMPOUND 1 |
54 | 54 | ||
55 | /* declarations */ | 55 | /* declarations */ |
56 | static void nfs4_cb_null(struct rpc_task *task); | 56 | static const struct rpc_call_ops nfs4_cb_null_ops; |
57 | 57 | ||
58 | /* Index of predefined Linux callback client operations */ | 58 | /* Index of predefined Linux callback client operations */ |
59 | 59 | ||
@@ -431,7 +431,6 @@ nfsd4_probe_callback(struct nfs4_client *clp) | |||
431 | } | 431 | } |
432 | clnt->cl_intr = 0; | 432 | clnt->cl_intr = 0; |
433 | clnt->cl_softrtry = 1; | 433 | clnt->cl_softrtry = 1; |
434 | clnt->cl_chatty = 1; | ||
435 | 434 | ||
436 | /* Kick rpciod, put the call on the wire. */ | 435 | /* Kick rpciod, put the call on the wire. */ |
437 | 436 | ||
@@ -447,7 +446,7 @@ nfsd4_probe_callback(struct nfs4_client *clp) | |||
447 | msg.rpc_cred = nfsd4_lookupcred(clp,0); | 446 | msg.rpc_cred = nfsd4_lookupcred(clp,0); |
448 | if (IS_ERR(msg.rpc_cred)) | 447 | if (IS_ERR(msg.rpc_cred)) |
449 | goto out_rpciod; | 448 | goto out_rpciod; |
450 | status = rpc_call_async(clnt, &msg, RPC_TASK_ASYNC, nfs4_cb_null, NULL); | 449 | status = rpc_call_async(clnt, &msg, RPC_TASK_ASYNC, &nfs4_cb_null_ops, NULL); |
451 | put_rpccred(msg.rpc_cred); | 450 | put_rpccred(msg.rpc_cred); |
452 | 451 | ||
453 | if (status != 0) { | 452 | if (status != 0) { |
@@ -469,7 +468,7 @@ out_err: | |||
469 | } | 468 | } |
470 | 469 | ||
471 | static void | 470 | static void |
472 | nfs4_cb_null(struct rpc_task *task) | 471 | nfs4_cb_null(struct rpc_task *task, void *dummy) |
473 | { | 472 | { |
474 | struct nfs4_client *clp = (struct nfs4_client *)task->tk_msg.rpc_argp; | 473 | struct nfs4_client *clp = (struct nfs4_client *)task->tk_msg.rpc_argp; |
475 | struct nfs4_callback *cb = &clp->cl_callback; | 474 | struct nfs4_callback *cb = &clp->cl_callback; |
@@ -488,6 +487,10 @@ out: | |||
488 | put_nfs4_client(clp); | 487 | put_nfs4_client(clp); |
489 | } | 488 | } |
490 | 489 | ||
490 | static const struct rpc_call_ops nfs4_cb_null_ops = { | ||
491 | .rpc_call_done = nfs4_cb_null, | ||
492 | }; | ||
493 | |||
491 | /* | 494 | /* |
492 | * called with dp->dl_count inc'ed. | 495 | * called with dp->dl_count inc'ed. |
493 | * nfs4_lock_state() may or may not have been called. | 496 | * nfs4_lock_state() may or may not have been called. |
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c index d0915fba155a..7c10c68902ae 100644 --- a/fs/ufs/dir.c +++ b/fs/ufs/dir.c | |||
@@ -491,7 +491,7 @@ int ufs_delete_entry (struct inode * inode, struct ufs_dir_entry * dir, | |||
491 | 491 | ||
492 | UFSD(("ino %u, reclen %u, namlen %u, name %s\n", | 492 | UFSD(("ino %u, reclen %u, namlen %u, name %s\n", |
493 | fs32_to_cpu(sb, de->d_ino), | 493 | fs32_to_cpu(sb, de->d_ino), |
494 | fs16to_cpu(sb, de->d_reclen), | 494 | fs16_to_cpu(sb, de->d_reclen), |
495 | ufs_get_de_namlen(sb, de), de->d_name)) | 495 | ufs_get_de_namlen(sb, de), de->d_name)) |
496 | 496 | ||
497 | while (i < bh->b_size) { | 497 | while (i < bh->b_size) { |
diff --git a/include/linux/filter.h b/include/linux/filter.h index 3ba843c46382..c6cb8f095088 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h | |||
@@ -143,7 +143,7 @@ static inline unsigned int sk_filter_len(struct sk_filter *fp) | |||
143 | struct sk_buff; | 143 | struct sk_buff; |
144 | struct sock; | 144 | struct sock; |
145 | 145 | ||
146 | extern int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen); | 146 | extern unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen); |
147 | extern int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk); | 147 | extern int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk); |
148 | extern int sk_chk_filter(struct sock_filter *filter, int flen); | 148 | extern int sk_chk_filter(struct sock_filter *filter, int flen); |
149 | #endif /* __KERNEL__ */ | 149 | #endif /* __KERNEL__ */ |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 115e72be25d0..2c9c48d65630 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -760,7 +760,7 @@ extern struct file_lock *posix_test_lock(struct file *, struct file_lock *); | |||
760 | extern int posix_lock_file(struct file *, struct file_lock *); | 760 | extern int posix_lock_file(struct file *, struct file_lock *); |
761 | extern int posix_lock_file_wait(struct file *, struct file_lock *); | 761 | extern int posix_lock_file_wait(struct file *, struct file_lock *); |
762 | extern void posix_block_lock(struct file_lock *, struct file_lock *); | 762 | extern void posix_block_lock(struct file_lock *, struct file_lock *); |
763 | extern void posix_unblock_lock(struct file *, struct file_lock *); | 763 | extern int posix_unblock_lock(struct file *, struct file_lock *); |
764 | extern int posix_locks_deadlock(struct file_lock *, struct file_lock *); | 764 | extern int posix_locks_deadlock(struct file_lock *, struct file_lock *); |
765 | extern int flock_lock_file_wait(struct file *filp, struct file_lock *fl); | 765 | extern int flock_lock_file_wait(struct file *filp, struct file_lock *fl); |
766 | extern int __break_lease(struct inode *inode, unsigned int flags); | 766 | extern int __break_lease(struct inode *inode, unsigned int flags); |
diff --git a/include/linux/hwmon-vid.h b/include/linux/hwmon-vid.h index cd4b7a042b86..f346e4d5381c 100644 --- a/include/linux/hwmon-vid.h +++ b/include/linux/hwmon-vid.h | |||
@@ -23,14 +23,14 @@ | |||
23 | #ifndef _LINUX_HWMON_VID_H | 23 | #ifndef _LINUX_HWMON_VID_H |
24 | #define _LINUX_HWMON_VID_H | 24 | #define _LINUX_HWMON_VID_H |
25 | 25 | ||
26 | int vid_from_reg(int val, int vrm); | 26 | int vid_from_reg(int val, u8 vrm); |
27 | int vid_which_vrm(void); | 27 | u8 vid_which_vrm(void); |
28 | 28 | ||
29 | /* vrm is the VRM/VRD document version multiplied by 10. | 29 | /* vrm is the VRM/VRD document version multiplied by 10. |
30 | val is in mV to avoid floating point in the kernel. | 30 | val is in mV to avoid floating point in the kernel. |
31 | Returned value is the 4-, 5- or 6-bit VID code. | 31 | Returned value is the 4-, 5- or 6-bit VID code. |
32 | Note that only VRM 9.x is supported for now. */ | 32 | Note that only VRM 9.x is supported for now. */ |
33 | static inline int vid_to_reg(int val, int vrm) | 33 | static inline int vid_to_reg(int val, u8 vrm) |
34 | { | 34 | { |
35 | switch (vrm) { | 35 | switch (vrm) { |
36 | case 91: /* VRM 9.1 */ | 36 | case 91: /* VRM 9.1 */ |
diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h index 006c81ef4d50..fb46f8d56999 100644 --- a/include/linux/i2c-id.h +++ b/include/linux/i2c-id.h | |||
@@ -25,12 +25,6 @@ | |||
25 | 25 | ||
26 | /* | 26 | /* |
27 | * ---- Driver types ----------------------------------------------------- | 27 | * ---- Driver types ----------------------------------------------------- |
28 | * device id name + number function description, i2c address(es) | ||
29 | * | ||
30 | * Range 1000-1999 range is defined in sensors/sensors.h | ||
31 | * Range 0x100 - 0x1ff is for V4L2 Common Components | ||
32 | * Range 0xf000 - 0xffff is reserved for local experimentation, and should | ||
33 | * never be used in official drivers | ||
34 | */ | 28 | */ |
35 | 29 | ||
36 | #define I2C_DRIVERID_MSP3400 1 | 30 | #define I2C_DRIVERID_MSP3400 1 |
@@ -110,13 +104,7 @@ | |||
110 | #define I2C_DRIVERID_AKITAIOEXP 74 /* IO Expander on Sharp SL-C1000 */ | 104 | #define I2C_DRIVERID_AKITAIOEXP 74 /* IO Expander on Sharp SL-C1000 */ |
111 | #define I2C_DRIVERID_INFRARED 75 /* I2C InfraRed on Video boards */ | 105 | #define I2C_DRIVERID_INFRARED 75 /* I2C InfraRed on Video boards */ |
112 | 106 | ||
113 | #define I2C_DRIVERID_EXP0 0xF0 /* experimental use id's */ | ||
114 | #define I2C_DRIVERID_EXP1 0xF1 | ||
115 | #define I2C_DRIVERID_EXP2 0xF2 | ||
116 | #define I2C_DRIVERID_EXP3 0xF3 | ||
117 | |||
118 | #define I2C_DRIVERID_I2CDEV 900 | 107 | #define I2C_DRIVERID_I2CDEV 900 |
119 | #define I2C_DRIVERID_I2CPROC 901 | ||
120 | #define I2C_DRIVERID_ARP 902 /* SMBus ARP Client */ | 108 | #define I2C_DRIVERID_ARP 902 /* SMBus ARP Client */ |
121 | #define I2C_DRIVERID_ALERT 903 /* SMBus Alert Responder Client */ | 109 | #define I2C_DRIVERID_ALERT 903 /* SMBus Alert Responder Client */ |
122 | 110 | ||
@@ -131,15 +119,12 @@ | |||
131 | #define I2C_DRIVERID_ADM1021 1008 | 119 | #define I2C_DRIVERID_ADM1021 1008 |
132 | #define I2C_DRIVERID_ADM9240 1009 | 120 | #define I2C_DRIVERID_ADM9240 1009 |
133 | #define I2C_DRIVERID_LTC1710 1010 | 121 | #define I2C_DRIVERID_LTC1710 1010 |
134 | #define I2C_DRIVERID_SIS5595 1011 | ||
135 | #define I2C_DRIVERID_ICSPLL 1012 | 122 | #define I2C_DRIVERID_ICSPLL 1012 |
136 | #define I2C_DRIVERID_BT869 1013 | 123 | #define I2C_DRIVERID_BT869 1013 |
137 | #define I2C_DRIVERID_MAXILIFE 1014 | 124 | #define I2C_DRIVERID_MAXILIFE 1014 |
138 | #define I2C_DRIVERID_MATORB 1015 | 125 | #define I2C_DRIVERID_MATORB 1015 |
139 | #define I2C_DRIVERID_GL520 1016 | 126 | #define I2C_DRIVERID_GL520 1016 |
140 | #define I2C_DRIVERID_THMC50 1017 | 127 | #define I2C_DRIVERID_THMC50 1017 |
141 | #define I2C_DRIVERID_DDCMON 1018 | ||
142 | #define I2C_DRIVERID_VIA686A 1019 | ||
143 | #define I2C_DRIVERID_ADM1025 1020 | 128 | #define I2C_DRIVERID_ADM1025 1020 |
144 | #define I2C_DRIVERID_LM87 1021 | 129 | #define I2C_DRIVERID_LM87 1021 |
145 | #define I2C_DRIVERID_PCF8574 1022 | 130 | #define I2C_DRIVERID_PCF8574 1022 |
@@ -151,21 +136,16 @@ | |||
151 | #define I2C_DRIVERID_FSCPOS 1028 | 136 | #define I2C_DRIVERID_FSCPOS 1028 |
152 | #define I2C_DRIVERID_FSCSCY 1029 | 137 | #define I2C_DRIVERID_FSCSCY 1029 |
153 | #define I2C_DRIVERID_PCF8591 1030 | 138 | #define I2C_DRIVERID_PCF8591 1030 |
154 | #define I2C_DRIVERID_SMSC47M1 1031 | ||
155 | #define I2C_DRIVERID_VT1211 1032 | ||
156 | #define I2C_DRIVERID_LM92 1033 | 139 | #define I2C_DRIVERID_LM92 1033 |
157 | #define I2C_DRIVERID_VT8231 1034 | ||
158 | #define I2C_DRIVERID_SMARTBATT 1035 | 140 | #define I2C_DRIVERID_SMARTBATT 1035 |
159 | #define I2C_DRIVERID_BMCSENSORS 1036 | 141 | #define I2C_DRIVERID_BMCSENSORS 1036 |
160 | #define I2C_DRIVERID_FS451 1037 | 142 | #define I2C_DRIVERID_FS451 1037 |
161 | #define I2C_DRIVERID_W83627HF 1038 | ||
162 | #define I2C_DRIVERID_LM85 1039 | 143 | #define I2C_DRIVERID_LM85 1039 |
163 | #define I2C_DRIVERID_LM83 1040 | 144 | #define I2C_DRIVERID_LM83 1040 |
164 | #define I2C_DRIVERID_LM90 1042 | 145 | #define I2C_DRIVERID_LM90 1042 |
165 | #define I2C_DRIVERID_ASB100 1043 | 146 | #define I2C_DRIVERID_ASB100 1043 |
166 | #define I2C_DRIVERID_FSCHER 1046 | 147 | #define I2C_DRIVERID_FSCHER 1046 |
167 | #define I2C_DRIVERID_W83L785TS 1047 | 148 | #define I2C_DRIVERID_W83L785TS 1047 |
168 | #define I2C_DRIVERID_SMSC47B397 1050 | ||
169 | 149 | ||
170 | /* | 150 | /* |
171 | * ---- Adapter types ---------------------------------------------------- | 151 | * ---- Adapter types ---------------------------------------------------- |
diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 5e19a7ba69b2..7863a59bd598 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h | |||
@@ -105,14 +105,14 @@ extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client, | |||
105 | * A driver is capable of handling one or more physical devices present on | 105 | * A driver is capable of handling one or more physical devices present on |
106 | * I2C adapters. This information is used to inform the driver of adapter | 106 | * I2C adapters. This information is used to inform the driver of adapter |
107 | * events. | 107 | * events. |
108 | * | ||
109 | * The driver.owner field should be set to the module owner of this driver. | ||
110 | * The driver.name field should be set to the name of this driver. | ||
108 | */ | 111 | */ |
109 | 112 | ||
110 | struct i2c_driver { | 113 | struct i2c_driver { |
111 | struct module *owner; | ||
112 | char name[32]; | ||
113 | int id; | 114 | int id; |
114 | unsigned int class; | 115 | unsigned int class; |
115 | unsigned int flags; /* div., see below */ | ||
116 | 116 | ||
117 | /* Notifies the driver that a new bus has appeared. This routine | 117 | /* Notifies the driver that a new bus has appeared. This routine |
118 | * can be used by the driver to test if the bus meets its conditions | 118 | * can be used by the driver to test if the bus meets its conditions |
@@ -250,18 +250,7 @@ static inline void i2c_set_adapdata (struct i2c_adapter *dev, void *data) | |||
250 | dev_set_drvdata (&dev->dev, data); | 250 | dev_set_drvdata (&dev->dev, data); |
251 | } | 251 | } |
252 | 252 | ||
253 | /*flags for the driver struct: */ | ||
254 | #define I2C_DF_NOTIFY 0x01 /* notify on bus (de/a)ttaches */ | ||
255 | #if 0 | ||
256 | /* this flag is gone -- there is a (optional) driver->detach_adapter | ||
257 | * callback now which can be used instead */ | ||
258 | # define I2C_DF_DUMMY 0x02 | ||
259 | #endif | ||
260 | |||
261 | /*flags for the client struct: */ | 253 | /*flags for the client struct: */ |
262 | #define I2C_CLIENT_ALLOW_USE 0x01 /* Client allows access */ | ||
263 | #define I2C_CLIENT_ALLOW_MULTIPLE_USE 0x02 /* Allow multiple access-locks */ | ||
264 | /* on an i2c_client */ | ||
265 | #define I2C_CLIENT_PEC 0x04 /* Use Packet Error Checking */ | 254 | #define I2C_CLIENT_PEC 0x04 /* Use Packet Error Checking */ |
266 | #define I2C_CLIENT_TEN 0x10 /* we have a ten bit chip address */ | 255 | #define I2C_CLIENT_TEN 0x10 /* we have a ten bit chip address */ |
267 | /* Must equal I2C_M_TEN below */ | 256 | /* Must equal I2C_M_TEN below */ |
@@ -302,26 +291,20 @@ struct i2c_client_address_data { | |||
302 | extern int i2c_add_adapter(struct i2c_adapter *); | 291 | extern int i2c_add_adapter(struct i2c_adapter *); |
303 | extern int i2c_del_adapter(struct i2c_adapter *); | 292 | extern int i2c_del_adapter(struct i2c_adapter *); |
304 | 293 | ||
305 | extern int i2c_add_driver(struct i2c_driver *); | 294 | extern int i2c_register_driver(struct module *, struct i2c_driver *); |
306 | extern int i2c_del_driver(struct i2c_driver *); | 295 | extern int i2c_del_driver(struct i2c_driver *); |
307 | 296 | ||
297 | static inline int i2c_add_driver(struct i2c_driver *driver) | ||
298 | { | ||
299 | return i2c_register_driver(THIS_MODULE, driver); | ||
300 | } | ||
301 | |||
308 | extern int i2c_attach_client(struct i2c_client *); | 302 | extern int i2c_attach_client(struct i2c_client *); |
309 | extern int i2c_detach_client(struct i2c_client *); | 303 | extern int i2c_detach_client(struct i2c_client *); |
310 | 304 | ||
311 | /* New function: This is to get an i2c_client-struct for controlling the | 305 | /* Should be used to make sure that client-struct is valid and that it |
312 | client either by using i2c_control-function or having the | 306 | is okay to access the i2c-client. |
313 | client-module export functions that can be used with the i2c_client | 307 | returns -ENODEV if client has gone in the meantime */ |
314 | -struct. */ | ||
315 | extern struct i2c_client *i2c_get_client(int driver_id, int adapter_id, | ||
316 | struct i2c_client *prev); | ||
317 | |||
318 | /* Should be used with new function | ||
319 | extern struct i2c_client *i2c_get_client(int,int,struct i2c_client *); | ||
320 | to make sure that client-struct is valid and that it is okay to access | ||
321 | the i2c-client. | ||
322 | returns -EACCES if client doesn't allow use (default) | ||
323 | returns -EBUSY if client doesn't allow multiple use (default) and | ||
324 | usage_count >0 */ | ||
325 | extern int i2c_use_client(struct i2c_client *); | 308 | extern int i2c_use_client(struct i2c_client *); |
326 | extern int i2c_release_client(struct i2c_client *); | 309 | extern int i2c_release_client(struct i2c_client *); |
327 | 310 | ||
diff --git a/include/linux/inet.h b/include/linux/inet.h index 3b5e9fdff872..6c5587af118d 100644 --- a/include/linux/inet.h +++ b/include/linux/inet.h | |||
@@ -45,6 +45,6 @@ | |||
45 | #ifdef __KERNEL__ | 45 | #ifdef __KERNEL__ |
46 | #include <linux/types.h> | 46 | #include <linux/types.h> |
47 | 47 | ||
48 | extern __u32 in_aton(const char *str); | 48 | extern __be32 in_aton(const char *str); |
49 | #endif | 49 | #endif |
50 | #endif /* _LINUX_INET_H */ | 50 | #endif /* _LINUX_INET_H */ |
diff --git a/include/linux/ip.h b/include/linux/ip.h index 9e2eb9a602eb..4b55cf1df732 100644 --- a/include/linux/ip.h +++ b/include/linux/ip.h | |||
@@ -90,14 +90,14 @@ struct iphdr { | |||
90 | #error "Please fix <asm/byteorder.h>" | 90 | #error "Please fix <asm/byteorder.h>" |
91 | #endif | 91 | #endif |
92 | __u8 tos; | 92 | __u8 tos; |
93 | __u16 tot_len; | 93 | __be16 tot_len; |
94 | __u16 id; | 94 | __be16 id; |
95 | __u16 frag_off; | 95 | __be16 frag_off; |
96 | __u8 ttl; | 96 | __u8 ttl; |
97 | __u8 protocol; | 97 | __u8 protocol; |
98 | __u16 check; | 98 | __u16 check; |
99 | __u32 saddr; | 99 | __be32 saddr; |
100 | __u32 daddr; | 100 | __be32 daddr; |
101 | /*The options start here. */ | 101 | /*The options start here. */ |
102 | }; | 102 | }; |
103 | 103 | ||
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h index 16d4e5a08e1d..95c8fea293ba 100644 --- a/include/linux/lockd/lockd.h +++ b/include/linux/lockd/lockd.h | |||
@@ -172,7 +172,7 @@ extern struct nlm_host *nlm_find_client(void); | |||
172 | /* | 172 | /* |
173 | * Server-side lock handling | 173 | * Server-side lock handling |
174 | */ | 174 | */ |
175 | int nlmsvc_async_call(struct nlm_rqst *, u32, rpc_action); | 175 | int nlmsvc_async_call(struct nlm_rqst *, u32, const struct rpc_call_ops *); |
176 | u32 nlmsvc_lock(struct svc_rqst *, struct nlm_file *, | 176 | u32 nlmsvc_lock(struct svc_rqst *, struct nlm_file *, |
177 | struct nlm_lock *, int, struct nlm_cookie *); | 177 | struct nlm_lock *, int, struct nlm_cookie *); |
178 | u32 nlmsvc_unlock(struct nlm_file *, struct nlm_lock *); | 178 | u32 nlmsvc_unlock(struct nlm_file *, struct nlm_lock *); |
diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h index 368ec8e45bd0..b5c98c43779e 100644 --- a/include/linux/moduleparam.h +++ b/include/linux/moduleparam.h | |||
@@ -10,7 +10,7 @@ | |||
10 | #ifdef MODULE | 10 | #ifdef MODULE |
11 | #define MODULE_PARAM_PREFIX /* empty */ | 11 | #define MODULE_PARAM_PREFIX /* empty */ |
12 | #else | 12 | #else |
13 | #define MODULE_PARAM_PREFIX __stringify(KBUILD_MODNAME) "." | 13 | #define MODULE_PARAM_PREFIX KBUILD_MODNAME "." |
14 | #endif | 14 | #endif |
15 | 15 | ||
16 | #ifdef MODULE | 16 | #ifdef MODULE |
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 2516adeccecf..547d649b274e 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h | |||
@@ -38,9 +38,6 @@ | |||
38 | # define NFS_DEBUG | 38 | # define NFS_DEBUG |
39 | #endif | 39 | #endif |
40 | 40 | ||
41 | #define NFS_MAX_FILE_IO_BUFFER_SIZE 32768 | ||
42 | #define NFS_DEF_FILE_IO_BUFFER_SIZE 4096 | ||
43 | |||
44 | /* Default timeout values */ | 41 | /* Default timeout values */ |
45 | #define NFS_MAX_UDP_TIMEOUT (60*HZ) | 42 | #define NFS_MAX_UDP_TIMEOUT (60*HZ) |
46 | #define NFS_MAX_TCP_TIMEOUT (600*HZ) | 43 | #define NFS_MAX_TCP_TIMEOUT (600*HZ) |
@@ -65,6 +62,7 @@ | |||
65 | #define FLUSH_STABLE 4 /* commit to stable storage */ | 62 | #define FLUSH_STABLE 4 /* commit to stable storage */ |
66 | #define FLUSH_LOWPRI 8 /* low priority background flush */ | 63 | #define FLUSH_LOWPRI 8 /* low priority background flush */ |
67 | #define FLUSH_HIGHPRI 16 /* high priority memory reclaim flush */ | 64 | #define FLUSH_HIGHPRI 16 /* high priority memory reclaim flush */ |
65 | #define FLUSH_NOCOMMIT 32 /* Don't send the NFSv3/v4 COMMIT */ | ||
68 | 66 | ||
69 | #ifdef __KERNEL__ | 67 | #ifdef __KERNEL__ |
70 | 68 | ||
@@ -394,6 +392,17 @@ extern int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fh, struct nfs_ | |||
394 | extern struct inode_operations nfs_symlink_inode_operations; | 392 | extern struct inode_operations nfs_symlink_inode_operations; |
395 | 393 | ||
396 | /* | 394 | /* |
395 | * linux/fs/nfs/sysctl.c | ||
396 | */ | ||
397 | #ifdef CONFIG_SYSCTL | ||
398 | extern int nfs_register_sysctl(void); | ||
399 | extern void nfs_unregister_sysctl(void); | ||
400 | #else | ||
401 | #define nfs_register_sysctl() do { } while(0) | ||
402 | #define nfs_unregister_sysctl() do { } while(0) | ||
403 | #endif | ||
404 | |||
405 | /* | ||
397 | * linux/fs/nfs/unlink.c | 406 | * linux/fs/nfs/unlink.c |
398 | */ | 407 | */ |
399 | extern int nfs_async_unlink(struct dentry *); | 408 | extern int nfs_async_unlink(struct dentry *); |
@@ -406,10 +415,12 @@ extern int nfs_writepage(struct page *page, struct writeback_control *wbc); | |||
406 | extern int nfs_writepages(struct address_space *, struct writeback_control *); | 415 | extern int nfs_writepages(struct address_space *, struct writeback_control *); |
407 | extern int nfs_flush_incompatible(struct file *file, struct page *page); | 416 | extern int nfs_flush_incompatible(struct file *file, struct page *page); |
408 | extern int nfs_updatepage(struct file *, struct page *, unsigned int, unsigned int); | 417 | extern int nfs_updatepage(struct file *, struct page *, unsigned int, unsigned int); |
409 | extern void nfs_writeback_done(struct rpc_task *task); | 418 | extern void nfs_writeback_done(struct rpc_task *task, void *data); |
419 | extern void nfs_writedata_release(void *data); | ||
410 | 420 | ||
411 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) | 421 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) |
412 | extern void nfs_commit_done(struct rpc_task *); | 422 | extern void nfs_commit_done(struct rpc_task *, void *data); |
423 | extern void nfs_commit_release(void *data); | ||
413 | #endif | 424 | #endif |
414 | 425 | ||
415 | /* | 426 | /* |
@@ -460,18 +471,33 @@ static inline int nfs_wb_page(struct inode *inode, struct page* page) | |||
460 | */ | 471 | */ |
461 | extern mempool_t *nfs_wdata_mempool; | 472 | extern mempool_t *nfs_wdata_mempool; |
462 | 473 | ||
463 | static inline struct nfs_write_data *nfs_writedata_alloc(void) | 474 | static inline struct nfs_write_data *nfs_writedata_alloc(unsigned int pagecount) |
464 | { | 475 | { |
465 | struct nfs_write_data *p = mempool_alloc(nfs_wdata_mempool, SLAB_NOFS); | 476 | struct nfs_write_data *p = mempool_alloc(nfs_wdata_mempool, SLAB_NOFS); |
477 | |||
466 | if (p) { | 478 | if (p) { |
467 | memset(p, 0, sizeof(*p)); | 479 | memset(p, 0, sizeof(*p)); |
468 | INIT_LIST_HEAD(&p->pages); | 480 | INIT_LIST_HEAD(&p->pages); |
481 | if (pagecount < NFS_PAGEVEC_SIZE) | ||
482 | p->pagevec = &p->page_array[0]; | ||
483 | else { | ||
484 | size_t size = ++pagecount * sizeof(struct page *); | ||
485 | p->pagevec = kmalloc(size, GFP_NOFS); | ||
486 | if (p->pagevec) { | ||
487 | memset(p->pagevec, 0, size); | ||
488 | } else { | ||
489 | mempool_free(p, nfs_wdata_mempool); | ||
490 | p = NULL; | ||
491 | } | ||
492 | } | ||
469 | } | 493 | } |
470 | return p; | 494 | return p; |
471 | } | 495 | } |
472 | 496 | ||
473 | static inline void nfs_writedata_free(struct nfs_write_data *p) | 497 | static inline void nfs_writedata_free(struct nfs_write_data *p) |
474 | { | 498 | { |
499 | if (p && (p->pagevec != &p->page_array[0])) | ||
500 | kfree(p->pagevec); | ||
475 | mempool_free(p, nfs_wdata_mempool); | 501 | mempool_free(p, nfs_wdata_mempool); |
476 | } | 502 | } |
477 | 503 | ||
@@ -481,28 +507,45 @@ static inline void nfs_writedata_free(struct nfs_write_data *p) | |||
481 | extern int nfs_readpage(struct file *, struct page *); | 507 | extern int nfs_readpage(struct file *, struct page *); |
482 | extern int nfs_readpages(struct file *, struct address_space *, | 508 | extern int nfs_readpages(struct file *, struct address_space *, |
483 | struct list_head *, unsigned); | 509 | struct list_head *, unsigned); |
484 | extern void nfs_readpage_result(struct rpc_task *); | 510 | extern void nfs_readpage_result(struct rpc_task *, void *); |
511 | extern void nfs_readdata_release(void *data); | ||
512 | |||
485 | 513 | ||
486 | /* | 514 | /* |
487 | * Allocate and free nfs_read_data structures | 515 | * Allocate and free nfs_read_data structures |
488 | */ | 516 | */ |
489 | extern mempool_t *nfs_rdata_mempool; | 517 | extern mempool_t *nfs_rdata_mempool; |
490 | 518 | ||
491 | static inline struct nfs_read_data *nfs_readdata_alloc(void) | 519 | static inline struct nfs_read_data *nfs_readdata_alloc(unsigned int pagecount) |
492 | { | 520 | { |
493 | struct nfs_read_data *p = mempool_alloc(nfs_rdata_mempool, SLAB_NOFS); | 521 | struct nfs_read_data *p = mempool_alloc(nfs_rdata_mempool, SLAB_NOFS); |
494 | if (p) | 522 | |
523 | if (p) { | ||
495 | memset(p, 0, sizeof(*p)); | 524 | memset(p, 0, sizeof(*p)); |
525 | INIT_LIST_HEAD(&p->pages); | ||
526 | if (pagecount < NFS_PAGEVEC_SIZE) | ||
527 | p->pagevec = &p->page_array[0]; | ||
528 | else { | ||
529 | size_t size = ++pagecount * sizeof(struct page *); | ||
530 | p->pagevec = kmalloc(size, GFP_NOFS); | ||
531 | if (p->pagevec) { | ||
532 | memset(p->pagevec, 0, size); | ||
533 | } else { | ||
534 | mempool_free(p, nfs_rdata_mempool); | ||
535 | p = NULL; | ||
536 | } | ||
537 | } | ||
538 | } | ||
496 | return p; | 539 | return p; |
497 | } | 540 | } |
498 | 541 | ||
499 | static inline void nfs_readdata_free(struct nfs_read_data *p) | 542 | static inline void nfs_readdata_free(struct nfs_read_data *p) |
500 | { | 543 | { |
544 | if (p && (p->pagevec != &p->page_array[0])) | ||
545 | kfree(p->pagevec); | ||
501 | mempool_free(p, nfs_rdata_mempool); | 546 | mempool_free(p, nfs_rdata_mempool); |
502 | } | 547 | } |
503 | 548 | ||
504 | extern void nfs_readdata_release(struct rpc_task *task); | ||
505 | |||
506 | /* | 549 | /* |
507 | * linux/fs/nfs3proc.c | 550 | * linux/fs/nfs3proc.c |
508 | */ | 551 | */ |
diff --git a/include/linux/nfs_idmap.h b/include/linux/nfs_idmap.h index a0f1f25e0ead..102e56094296 100644 --- a/include/linux/nfs_idmap.h +++ b/include/linux/nfs_idmap.h | |||
@@ -71,6 +71,8 @@ int nfs_map_name_to_uid(struct nfs4_client *, const char *, size_t, __u32 *); | |||
71 | int nfs_map_group_to_gid(struct nfs4_client *, const char *, size_t, __u32 *); | 71 | int nfs_map_group_to_gid(struct nfs4_client *, const char *, size_t, __u32 *); |
72 | int nfs_map_uid_to_name(struct nfs4_client *, __u32, char *); | 72 | int nfs_map_uid_to_name(struct nfs4_client *, __u32, char *); |
73 | int nfs_map_gid_to_group(struct nfs4_client *, __u32, char *); | 73 | int nfs_map_gid_to_group(struct nfs4_client *, __u32, char *); |
74 | |||
75 | extern unsigned int nfs_idmap_cache_timeout; | ||
74 | #endif /* __KERNEL__ */ | 76 | #endif /* __KERNEL__ */ |
75 | 77 | ||
76 | #endif /* NFS_IDMAP_H */ | 78 | #endif /* NFS_IDMAP_H */ |
diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h index da2e077b65e2..66e2ed658527 100644 --- a/include/linux/nfs_page.h +++ b/include/linux/nfs_page.h | |||
@@ -79,9 +79,7 @@ extern void nfs_clear_page_writeback(struct nfs_page *req); | |||
79 | static inline int | 79 | static inline int |
80 | nfs_lock_request_dontget(struct nfs_page *req) | 80 | nfs_lock_request_dontget(struct nfs_page *req) |
81 | { | 81 | { |
82 | if (test_and_set_bit(PG_BUSY, &req->wb_flags)) | 82 | return !test_and_set_bit(PG_BUSY, &req->wb_flags); |
83 | return 0; | ||
84 | return 1; | ||
85 | } | 83 | } |
86 | 84 | ||
87 | /* | 85 | /* |
@@ -125,9 +123,7 @@ nfs_list_remove_request(struct nfs_page *req) | |||
125 | static inline int | 123 | static inline int |
126 | nfs_defer_commit(struct nfs_page *req) | 124 | nfs_defer_commit(struct nfs_page *req) |
127 | { | 125 | { |
128 | if (test_and_set_bit(PG_NEED_COMMIT, &req->wb_flags)) | 126 | return !test_and_set_bit(PG_NEED_COMMIT, &req->wb_flags); |
129 | return 0; | ||
130 | return 1; | ||
131 | } | 127 | } |
132 | 128 | ||
133 | static inline void | 129 | static inline void |
@@ -141,9 +137,7 @@ nfs_clear_commit(struct nfs_page *req) | |||
141 | static inline int | 137 | static inline int |
142 | nfs_defer_reschedule(struct nfs_page *req) | 138 | nfs_defer_reschedule(struct nfs_page *req) |
143 | { | 139 | { |
144 | if (test_and_set_bit(PG_NEED_RESCHED, &req->wb_flags)) | 140 | return !test_and_set_bit(PG_NEED_RESCHED, &req->wb_flags); |
145 | return 0; | ||
146 | return 1; | ||
147 | } | 141 | } |
148 | 142 | ||
149 | static inline void | 143 | static inline void |
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 40718669b9c8..6d6f69ec5675 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h | |||
@@ -4,6 +4,16 @@ | |||
4 | #include <linux/sunrpc/xprt.h> | 4 | #include <linux/sunrpc/xprt.h> |
5 | #include <linux/nfsacl.h> | 5 | #include <linux/nfsacl.h> |
6 | 6 | ||
7 | /* | ||
8 | * To change the maximum rsize and wsize supported by the NFS client, adjust | ||
9 | * NFS_MAX_FILE_IO_SIZE. 64KB is a typical maximum, but some servers can | ||
10 | * support a megabyte or more. The default is left at 4096 bytes, which is | ||
11 | * reasonable for NFS over UDP. | ||
12 | */ | ||
13 | #define NFS_MAX_FILE_IO_SIZE (1048576U) | ||
14 | #define NFS_DEF_FILE_IO_SIZE (4096U) | ||
15 | #define NFS_MIN_FILE_IO_SIZE (1024U) | ||
16 | |||
7 | struct nfs4_fsid { | 17 | struct nfs4_fsid { |
8 | __u64 major; | 18 | __u64 major; |
9 | __u64 minor; | 19 | __u64 minor; |
@@ -137,7 +147,7 @@ struct nfs_openres { | |||
137 | */ | 147 | */ |
138 | struct nfs_open_confirmargs { | 148 | struct nfs_open_confirmargs { |
139 | const struct nfs_fh * fh; | 149 | const struct nfs_fh * fh; |
140 | nfs4_stateid stateid; | 150 | nfs4_stateid * stateid; |
141 | struct nfs_seqid * seqid; | 151 | struct nfs_seqid * seqid; |
142 | }; | 152 | }; |
143 | 153 | ||
@@ -165,66 +175,62 @@ struct nfs_closeres { | |||
165 | * * Arguments to the lock,lockt, and locku call. | 175 | * * Arguments to the lock,lockt, and locku call. |
166 | * */ | 176 | * */ |
167 | struct nfs_lowner { | 177 | struct nfs_lowner { |
168 | __u64 clientid; | 178 | __u64 clientid; |
169 | u32 id; | 179 | u32 id; |
170 | }; | 180 | }; |
171 | 181 | ||
172 | struct nfs_lock_opargs { | 182 | struct nfs_lock_args { |
183 | struct nfs_fh * fh; | ||
184 | struct file_lock * fl; | ||
173 | struct nfs_seqid * lock_seqid; | 185 | struct nfs_seqid * lock_seqid; |
174 | nfs4_stateid * lock_stateid; | 186 | nfs4_stateid * lock_stateid; |
175 | struct nfs_seqid * open_seqid; | 187 | struct nfs_seqid * open_seqid; |
176 | nfs4_stateid * open_stateid; | 188 | nfs4_stateid * open_stateid; |
177 | struct nfs_lowner lock_owner; | 189 | struct nfs_lowner lock_owner; |
178 | __u32 reclaim; | 190 | unsigned char block : 1; |
179 | __u32 new_lock_owner; | 191 | unsigned char reclaim : 1; |
192 | unsigned char new_lock_owner : 1; | ||
180 | }; | 193 | }; |
181 | 194 | ||
182 | struct nfs_locku_opargs { | 195 | struct nfs_lock_res { |
196 | nfs4_stateid stateid; | ||
197 | }; | ||
198 | |||
199 | struct nfs_locku_args { | ||
200 | struct nfs_fh * fh; | ||
201 | struct file_lock * fl; | ||
183 | struct nfs_seqid * seqid; | 202 | struct nfs_seqid * seqid; |
184 | nfs4_stateid * stateid; | 203 | nfs4_stateid * stateid; |
185 | }; | 204 | }; |
186 | 205 | ||
187 | struct nfs_lockargs { | 206 | struct nfs_locku_res { |
188 | struct nfs_fh * fh; | 207 | nfs4_stateid stateid; |
189 | __u32 type; | ||
190 | __u64 offset; | ||
191 | __u64 length; | ||
192 | union { | ||
193 | struct nfs_lock_opargs *lock; /* LOCK */ | ||
194 | struct nfs_lowner *lockt; /* LOCKT */ | ||
195 | struct nfs_locku_opargs *locku; /* LOCKU */ | ||
196 | } u; | ||
197 | }; | 208 | }; |
198 | 209 | ||
199 | struct nfs_lock_denied { | 210 | struct nfs_lockt_args { |
200 | __u64 offset; | 211 | struct nfs_fh * fh; |
201 | __u64 length; | 212 | struct file_lock * fl; |
202 | __u32 type; | 213 | struct nfs_lowner lock_owner; |
203 | struct nfs_lowner owner; | ||
204 | }; | 214 | }; |
205 | 215 | ||
206 | struct nfs_lockres { | 216 | struct nfs_lockt_res { |
207 | union { | 217 | struct file_lock * denied; /* LOCK, LOCKT failed */ |
208 | nfs4_stateid stateid;/* LOCK success, LOCKU */ | ||
209 | struct nfs_lock_denied denied; /* LOCK failed, LOCKT success */ | ||
210 | } u; | ||
211 | const struct nfs_server * server; | ||
212 | }; | 218 | }; |
213 | 219 | ||
214 | struct nfs4_delegreturnargs { | 220 | struct nfs4_delegreturnargs { |
215 | const struct nfs_fh *fhandle; | 221 | const struct nfs_fh *fhandle; |
216 | const nfs4_stateid *stateid; | 222 | const nfs4_stateid *stateid; |
223 | const u32 * bitmask; | ||
224 | }; | ||
225 | |||
226 | struct nfs4_delegreturnres { | ||
227 | struct nfs_fattr * fattr; | ||
228 | const struct nfs_server *server; | ||
217 | }; | 229 | }; |
218 | 230 | ||
219 | /* | 231 | /* |
220 | * Arguments to the read call. | 232 | * Arguments to the read call. |
221 | */ | 233 | */ |
222 | |||
223 | #define NFS_READ_MAXIOV (9U) | ||
224 | #if (NFS_READ_MAXIOV > (MAX_IOVEC -2)) | ||
225 | #error "NFS_READ_MAXIOV is too large" | ||
226 | #endif | ||
227 | |||
228 | struct nfs_readargs { | 234 | struct nfs_readargs { |
229 | struct nfs_fh * fh; | 235 | struct nfs_fh * fh; |
230 | struct nfs_open_context *context; | 236 | struct nfs_open_context *context; |
@@ -243,11 +249,6 @@ struct nfs_readres { | |||
243 | /* | 249 | /* |
244 | * Arguments to the write call. | 250 | * Arguments to the write call. |
245 | */ | 251 | */ |
246 | #define NFS_WRITE_MAXIOV (9U) | ||
247 | #if (NFS_WRITE_MAXIOV > (MAX_IOVEC -2)) | ||
248 | #error "NFS_WRITE_MAXIOV is too large" | ||
249 | #endif | ||
250 | |||
251 | struct nfs_writeargs { | 252 | struct nfs_writeargs { |
252 | struct nfs_fh * fh; | 253 | struct nfs_fh * fh; |
253 | struct nfs_open_context *context; | 254 | struct nfs_open_context *context; |
@@ -678,6 +679,8 @@ struct nfs4_server_caps_res { | |||
678 | 679 | ||
679 | struct nfs_page; | 680 | struct nfs_page; |
680 | 681 | ||
682 | #define NFS_PAGEVEC_SIZE (8U) | ||
683 | |||
681 | struct nfs_read_data { | 684 | struct nfs_read_data { |
682 | int flags; | 685 | int flags; |
683 | struct rpc_task task; | 686 | struct rpc_task task; |
@@ -686,13 +689,14 @@ struct nfs_read_data { | |||
686 | struct nfs_fattr fattr; /* fattr storage */ | 689 | struct nfs_fattr fattr; /* fattr storage */ |
687 | struct list_head pages; /* Coalesced read requests */ | 690 | struct list_head pages; /* Coalesced read requests */ |
688 | struct nfs_page *req; /* multi ops per nfs_page */ | 691 | struct nfs_page *req; /* multi ops per nfs_page */ |
689 | struct page *pagevec[NFS_READ_MAXIOV]; | 692 | struct page **pagevec; |
690 | struct nfs_readargs args; | 693 | struct nfs_readargs args; |
691 | struct nfs_readres res; | 694 | struct nfs_readres res; |
692 | #ifdef CONFIG_NFS_V4 | 695 | #ifdef CONFIG_NFS_V4 |
693 | unsigned long timestamp; /* For lease renewal */ | 696 | unsigned long timestamp; /* For lease renewal */ |
694 | #endif | 697 | #endif |
695 | void (*complete) (struct nfs_read_data *, int); | 698 | void (*complete) (struct nfs_read_data *, int); |
699 | struct page *page_array[NFS_PAGEVEC_SIZE + 1]; | ||
696 | }; | 700 | }; |
697 | 701 | ||
698 | struct nfs_write_data { | 702 | struct nfs_write_data { |
@@ -704,13 +708,14 @@ struct nfs_write_data { | |||
704 | struct nfs_writeverf verf; | 708 | struct nfs_writeverf verf; |
705 | struct list_head pages; /* Coalesced requests we wish to flush */ | 709 | struct list_head pages; /* Coalesced requests we wish to flush */ |
706 | struct nfs_page *req; /* multi ops per nfs_page */ | 710 | struct nfs_page *req; /* multi ops per nfs_page */ |
707 | struct page *pagevec[NFS_WRITE_MAXIOV]; | 711 | struct page **pagevec; |
708 | struct nfs_writeargs args; /* argument struct */ | 712 | struct nfs_writeargs args; /* argument struct */ |
709 | struct nfs_writeres res; /* result struct */ | 713 | struct nfs_writeres res; /* result struct */ |
710 | #ifdef CONFIG_NFS_V4 | 714 | #ifdef CONFIG_NFS_V4 |
711 | unsigned long timestamp; /* For lease renewal */ | 715 | unsigned long timestamp; /* For lease renewal */ |
712 | #endif | 716 | #endif |
713 | void (*complete) (struct nfs_write_data *, int); | 717 | void (*complete) (struct nfs_write_data *, int); |
718 | struct page *page_array[NFS_PAGEVEC_SIZE + 1]; | ||
714 | }; | 719 | }; |
715 | 720 | ||
716 | struct nfs_access_entry; | 721 | struct nfs_access_entry; |
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 24db7248301a..a213e999de31 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
@@ -986,6 +986,7 @@ | |||
986 | #define PCI_DEVICE_ID_NVIDIA_TNT_UNKNOWN 0x002a | 986 | #define PCI_DEVICE_ID_NVIDIA_TNT_UNKNOWN 0x002a |
987 | #define PCI_DEVICE_ID_NVIDIA_VTNT2 0x002C | 987 | #define PCI_DEVICE_ID_NVIDIA_VTNT2 0x002C |
988 | #define PCI_DEVICE_ID_NVIDIA_UVTNT2 0x002D | 988 | #define PCI_DEVICE_ID_NVIDIA_UVTNT2 0x002D |
989 | #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SMBUS 0x0034 | ||
989 | #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE 0x0035 | 990 | #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE 0x0035 |
990 | #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA 0x0036 | 991 | #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA 0x0036 |
991 | #define PCI_DEVICE_ID_NVIDIA_NVENET_10 0x0037 | 992 | #define PCI_DEVICE_ID_NVIDIA_NVENET_10 0x0037 |
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index ab151bbb66df..f147e6b84332 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h | |||
@@ -49,7 +49,6 @@ struct rpc_clnt { | |||
49 | 49 | ||
50 | unsigned int cl_softrtry : 1,/* soft timeouts */ | 50 | unsigned int cl_softrtry : 1,/* soft timeouts */ |
51 | cl_intr : 1,/* interruptible */ | 51 | cl_intr : 1,/* interruptible */ |
52 | cl_chatty : 1,/* be verbose */ | ||
53 | cl_autobind : 1,/* use getport() */ | 52 | cl_autobind : 1,/* use getport() */ |
54 | cl_oneshot : 1,/* dispose after use */ | 53 | cl_oneshot : 1,/* dispose after use */ |
55 | cl_dead : 1;/* abandoned */ | 54 | cl_dead : 1;/* abandoned */ |
@@ -126,7 +125,8 @@ int rpc_register(u32, u32, int, unsigned short, int *); | |||
126 | void rpc_call_setup(struct rpc_task *, struct rpc_message *, int); | 125 | void rpc_call_setup(struct rpc_task *, struct rpc_message *, int); |
127 | 126 | ||
128 | int rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, | 127 | int rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, |
129 | int flags, rpc_action callback, void *clntdata); | 128 | int flags, const struct rpc_call_ops *tk_ops, |
129 | void *calldata); | ||
130 | int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg, | 130 | int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg, |
131 | int flags); | 131 | int flags); |
132 | void rpc_restart_call(struct rpc_task *); | 132 | void rpc_restart_call(struct rpc_task *); |
@@ -134,6 +134,7 @@ void rpc_clnt_sigmask(struct rpc_clnt *clnt, sigset_t *oldset); | |||
134 | void rpc_clnt_sigunmask(struct rpc_clnt *clnt, sigset_t *oldset); | 134 | void rpc_clnt_sigunmask(struct rpc_clnt *clnt, sigset_t *oldset); |
135 | void rpc_setbufsize(struct rpc_clnt *, unsigned int, unsigned int); | 135 | void rpc_setbufsize(struct rpc_clnt *, unsigned int, unsigned int); |
136 | size_t rpc_max_payload(struct rpc_clnt *); | 136 | size_t rpc_max_payload(struct rpc_clnt *); |
137 | void rpc_force_rebind(struct rpc_clnt *); | ||
137 | int rpc_ping(struct rpc_clnt *clnt, int flags); | 138 | int rpc_ping(struct rpc_clnt *clnt, int flags); |
138 | 139 | ||
139 | static __inline__ | 140 | static __inline__ |
diff --git a/include/linux/sunrpc/gss_spkm3.h b/include/linux/sunrpc/gss_spkm3.h index 0beb2cf00a84..336e218c2782 100644 --- a/include/linux/sunrpc/gss_spkm3.h +++ b/include/linux/sunrpc/gss_spkm3.h | |||
@@ -48,7 +48,7 @@ u32 spkm3_read_token(struct spkm3_ctx *ctx, struct xdr_netobj *read_token, struc | |||
48 | #define CKSUMTYPE_RSA_MD5 0x0007 | 48 | #define CKSUMTYPE_RSA_MD5 0x0007 |
49 | 49 | ||
50 | s32 make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body, | 50 | s32 make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body, |
51 | struct xdr_netobj *cksum); | 51 | int body_offset, struct xdr_netobj *cksum); |
52 | void asn1_bitstring_len(struct xdr_netobj *in, int *enclen, int *zerobits); | 52 | void asn1_bitstring_len(struct xdr_netobj *in, int *enclen, int *zerobits); |
53 | int decode_asn1_bitstring(struct xdr_netobj *out, char *in, int enclen, | 53 | int decode_asn1_bitstring(struct xdr_netobj *out, char *in, int enclen, |
54 | int explen); | 54 | int explen); |
diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h index 4d77e90d0b30..8b25629accd8 100644 --- a/include/linux/sunrpc/sched.h +++ b/include/linux/sunrpc/sched.h | |||
@@ -27,6 +27,7 @@ struct rpc_message { | |||
27 | struct rpc_cred * rpc_cred; /* Credentials */ | 27 | struct rpc_cred * rpc_cred; /* Credentials */ |
28 | }; | 28 | }; |
29 | 29 | ||
30 | struct rpc_call_ops; | ||
30 | struct rpc_wait_queue; | 31 | struct rpc_wait_queue; |
31 | struct rpc_wait { | 32 | struct rpc_wait { |
32 | struct list_head list; /* wait queue links */ | 33 | struct list_head list; /* wait queue links */ |
@@ -41,6 +42,7 @@ struct rpc_task { | |||
41 | #ifdef RPC_DEBUG | 42 | #ifdef RPC_DEBUG |
42 | unsigned long tk_magic; /* 0xf00baa */ | 43 | unsigned long tk_magic; /* 0xf00baa */ |
43 | #endif | 44 | #endif |
45 | atomic_t tk_count; /* Reference count */ | ||
44 | struct list_head tk_task; /* global list of tasks */ | 46 | struct list_head tk_task; /* global list of tasks */ |
45 | struct rpc_clnt * tk_client; /* RPC client */ | 47 | struct rpc_clnt * tk_client; /* RPC client */ |
46 | struct rpc_rqst * tk_rqstp; /* RPC request */ | 48 | struct rpc_rqst * tk_rqstp; /* RPC request */ |
@@ -50,8 +52,6 @@ struct rpc_task { | |||
50 | * RPC call state | 52 | * RPC call state |
51 | */ | 53 | */ |
52 | struct rpc_message tk_msg; /* RPC call info */ | 54 | struct rpc_message tk_msg; /* RPC call info */ |
53 | __u32 * tk_buffer; /* XDR buffer */ | ||
54 | size_t tk_bufsize; | ||
55 | __u8 tk_garb_retry; | 55 | __u8 tk_garb_retry; |
56 | __u8 tk_cred_retry; | 56 | __u8 tk_cred_retry; |
57 | 57 | ||
@@ -61,13 +61,12 @@ struct rpc_task { | |||
61 | * timeout_fn to be executed by timer bottom half | 61 | * timeout_fn to be executed by timer bottom half |
62 | * callback to be executed after waking up | 62 | * callback to be executed after waking up |
63 | * action next procedure for async tasks | 63 | * action next procedure for async tasks |
64 | * exit exit async task and report to caller | 64 | * tk_ops caller callbacks |
65 | */ | 65 | */ |
66 | void (*tk_timeout_fn)(struct rpc_task *); | 66 | void (*tk_timeout_fn)(struct rpc_task *); |
67 | void (*tk_callback)(struct rpc_task *); | 67 | void (*tk_callback)(struct rpc_task *); |
68 | void (*tk_action)(struct rpc_task *); | 68 | void (*tk_action)(struct rpc_task *); |
69 | void (*tk_exit)(struct rpc_task *); | 69 | const struct rpc_call_ops *tk_ops; |
70 | void (*tk_release)(struct rpc_task *); | ||
71 | void * tk_calldata; | 70 | void * tk_calldata; |
72 | 71 | ||
73 | /* | 72 | /* |
@@ -78,7 +77,6 @@ struct rpc_task { | |||
78 | struct timer_list tk_timer; /* kernel timer */ | 77 | struct timer_list tk_timer; /* kernel timer */ |
79 | unsigned long tk_timeout; /* timeout for rpc_sleep() */ | 78 | unsigned long tk_timeout; /* timeout for rpc_sleep() */ |
80 | unsigned short tk_flags; /* misc flags */ | 79 | unsigned short tk_flags; /* misc flags */ |
81 | unsigned char tk_active : 1;/* Task has been activated */ | ||
82 | unsigned char tk_priority : 2;/* Task priority */ | 80 | unsigned char tk_priority : 2;/* Task priority */ |
83 | unsigned long tk_runstate; /* Task run status */ | 81 | unsigned long tk_runstate; /* Task run status */ |
84 | struct workqueue_struct *tk_workqueue; /* Normally rpciod, but could | 82 | struct workqueue_struct *tk_workqueue; /* Normally rpciod, but could |
@@ -111,6 +109,13 @@ struct rpc_task { | |||
111 | 109 | ||
112 | typedef void (*rpc_action)(struct rpc_task *); | 110 | typedef void (*rpc_action)(struct rpc_task *); |
113 | 111 | ||
112 | struct rpc_call_ops { | ||
113 | void (*rpc_call_prepare)(struct rpc_task *, void *); | ||
114 | void (*rpc_call_done)(struct rpc_task *, void *); | ||
115 | void (*rpc_release)(void *); | ||
116 | }; | ||
117 | |||
118 | |||
114 | /* | 119 | /* |
115 | * RPC task flags | 120 | * RPC task flags |
116 | */ | 121 | */ |
@@ -129,7 +134,6 @@ typedef void (*rpc_action)(struct rpc_task *); | |||
129 | #define RPC_IS_SWAPPER(t) ((t)->tk_flags & RPC_TASK_SWAPPER) | 134 | #define RPC_IS_SWAPPER(t) ((t)->tk_flags & RPC_TASK_SWAPPER) |
130 | #define RPC_DO_ROOTOVERRIDE(t) ((t)->tk_flags & RPC_TASK_ROOTCREDS) | 135 | #define RPC_DO_ROOTOVERRIDE(t) ((t)->tk_flags & RPC_TASK_ROOTCREDS) |
131 | #define RPC_ASSASSINATED(t) ((t)->tk_flags & RPC_TASK_KILLED) | 136 | #define RPC_ASSASSINATED(t) ((t)->tk_flags & RPC_TASK_KILLED) |
132 | #define RPC_IS_ACTIVATED(t) ((t)->tk_active) | ||
133 | #define RPC_DO_CALLBACK(t) ((t)->tk_callback != NULL) | 137 | #define RPC_DO_CALLBACK(t) ((t)->tk_callback != NULL) |
134 | #define RPC_IS_SOFT(t) ((t)->tk_flags & RPC_TASK_SOFT) | 138 | #define RPC_IS_SOFT(t) ((t)->tk_flags & RPC_TASK_SOFT) |
135 | #define RPC_TASK_UNINTERRUPTIBLE(t) ((t)->tk_flags & RPC_TASK_NOINTR) | 139 | #define RPC_TASK_UNINTERRUPTIBLE(t) ((t)->tk_flags & RPC_TASK_NOINTR) |
@@ -138,6 +142,7 @@ typedef void (*rpc_action)(struct rpc_task *); | |||
138 | #define RPC_TASK_QUEUED 1 | 142 | #define RPC_TASK_QUEUED 1 |
139 | #define RPC_TASK_WAKEUP 2 | 143 | #define RPC_TASK_WAKEUP 2 |
140 | #define RPC_TASK_HAS_TIMER 3 | 144 | #define RPC_TASK_HAS_TIMER 3 |
145 | #define RPC_TASK_ACTIVE 4 | ||
141 | 146 | ||
142 | #define RPC_IS_RUNNING(t) (test_bit(RPC_TASK_RUNNING, &(t)->tk_runstate)) | 147 | #define RPC_IS_RUNNING(t) (test_bit(RPC_TASK_RUNNING, &(t)->tk_runstate)) |
143 | #define rpc_set_running(t) (set_bit(RPC_TASK_RUNNING, &(t)->tk_runstate)) | 148 | #define rpc_set_running(t) (set_bit(RPC_TASK_RUNNING, &(t)->tk_runstate)) |
@@ -168,6 +173,15 @@ typedef void (*rpc_action)(struct rpc_task *); | |||
168 | smp_mb__after_clear_bit(); \ | 173 | smp_mb__after_clear_bit(); \ |
169 | } while (0) | 174 | } while (0) |
170 | 175 | ||
176 | #define RPC_IS_ACTIVATED(t) (test_bit(RPC_TASK_ACTIVE, &(t)->tk_runstate)) | ||
177 | #define rpc_set_active(t) (set_bit(RPC_TASK_ACTIVE, &(t)->tk_runstate)) | ||
178 | #define rpc_clear_active(t) \ | ||
179 | do { \ | ||
180 | smp_mb__before_clear_bit(); \ | ||
181 | clear_bit(RPC_TASK_ACTIVE, &(t)->tk_runstate); \ | ||
182 | smp_mb__after_clear_bit(); \ | ||
183 | } while(0) | ||
184 | |||
171 | /* | 185 | /* |
172 | * Task priorities. | 186 | * Task priorities. |
173 | * Note: if you change these, you must also change | 187 | * Note: if you change these, you must also change |
@@ -228,11 +242,16 @@ struct rpc_wait_queue { | |||
228 | /* | 242 | /* |
229 | * Function prototypes | 243 | * Function prototypes |
230 | */ | 244 | */ |
231 | struct rpc_task *rpc_new_task(struct rpc_clnt *, rpc_action, int flags); | 245 | struct rpc_task *rpc_new_task(struct rpc_clnt *, int flags, |
246 | const struct rpc_call_ops *ops, void *data); | ||
247 | struct rpc_task *rpc_run_task(struct rpc_clnt *clnt, int flags, | ||
248 | const struct rpc_call_ops *ops, void *data); | ||
232 | struct rpc_task *rpc_new_child(struct rpc_clnt *, struct rpc_task *parent); | 249 | struct rpc_task *rpc_new_child(struct rpc_clnt *, struct rpc_task *parent); |
233 | void rpc_init_task(struct rpc_task *, struct rpc_clnt *, | 250 | void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, |
234 | rpc_action exitfunc, int flags); | 251 | int flags, const struct rpc_call_ops *ops, |
252 | void *data); | ||
235 | void rpc_release_task(struct rpc_task *); | 253 | void rpc_release_task(struct rpc_task *); |
254 | void rpc_exit_task(struct rpc_task *); | ||
236 | void rpc_killall_tasks(struct rpc_clnt *); | 255 | void rpc_killall_tasks(struct rpc_clnt *); |
237 | int rpc_execute(struct rpc_task *); | 256 | int rpc_execute(struct rpc_task *); |
238 | void rpc_run_child(struct rpc_task *parent, struct rpc_task *child, | 257 | void rpc_run_child(struct rpc_task *parent, struct rpc_task *child, |
@@ -247,9 +266,11 @@ struct rpc_task *rpc_wake_up_next(struct rpc_wait_queue *); | |||
247 | void rpc_wake_up_status(struct rpc_wait_queue *, int); | 266 | void rpc_wake_up_status(struct rpc_wait_queue *, int); |
248 | void rpc_delay(struct rpc_task *, unsigned long); | 267 | void rpc_delay(struct rpc_task *, unsigned long); |
249 | void * rpc_malloc(struct rpc_task *, size_t); | 268 | void * rpc_malloc(struct rpc_task *, size_t); |
269 | void rpc_free(struct rpc_task *); | ||
250 | int rpciod_up(void); | 270 | int rpciod_up(void); |
251 | void rpciod_down(void); | 271 | void rpciod_down(void); |
252 | void rpciod_wake_up(void); | 272 | void rpciod_wake_up(void); |
273 | int __rpc_wait_for_completion_task(struct rpc_task *task, int (*)(void *)); | ||
253 | #ifdef RPC_DEBUG | 274 | #ifdef RPC_DEBUG |
254 | void rpc_show_tasks(void); | 275 | void rpc_show_tasks(void); |
255 | #endif | 276 | #endif |
@@ -259,7 +280,12 @@ void rpc_destroy_mempool(void); | |||
259 | static inline void rpc_exit(struct rpc_task *task, int status) | 280 | static inline void rpc_exit(struct rpc_task *task, int status) |
260 | { | 281 | { |
261 | task->tk_status = status; | 282 | task->tk_status = status; |
262 | task->tk_action = NULL; | 283 | task->tk_action = rpc_exit_task; |
284 | } | ||
285 | |||
286 | static inline int rpc_wait_for_completion_task(struct rpc_task *task) | ||
287 | { | ||
288 | return __rpc_wait_for_completion_task(task, NULL); | ||
263 | } | 289 | } |
264 | 290 | ||
265 | #ifdef RPC_DEBUG | 291 | #ifdef RPC_DEBUG |
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h index 5da968729cf8..84c35d42d250 100644 --- a/include/linux/sunrpc/xdr.h +++ b/include/linux/sunrpc/xdr.h | |||
@@ -91,7 +91,6 @@ struct xdr_buf { | |||
91 | u32 * xdr_encode_opaque_fixed(u32 *p, const void *ptr, unsigned int len); | 91 | u32 * xdr_encode_opaque_fixed(u32 *p, const void *ptr, unsigned int len); |
92 | u32 * xdr_encode_opaque(u32 *p, const void *ptr, unsigned int len); | 92 | u32 * xdr_encode_opaque(u32 *p, const void *ptr, unsigned int len); |
93 | u32 * xdr_encode_string(u32 *p, const char *s); | 93 | u32 * xdr_encode_string(u32 *p, const char *s); |
94 | u32 * xdr_decode_string(u32 *p, char **sp, int *lenp, int maxlen); | ||
95 | u32 * xdr_decode_string_inplace(u32 *p, char **sp, int *lenp, int maxlen); | 94 | u32 * xdr_decode_string_inplace(u32 *p, char **sp, int *lenp, int maxlen); |
96 | u32 * xdr_encode_netobj(u32 *p, const struct xdr_netobj *); | 95 | u32 * xdr_encode_netobj(u32 *p, const struct xdr_netobj *); |
97 | u32 * xdr_decode_netobj(u32 *p, struct xdr_netobj *); | 96 | u32 * xdr_decode_netobj(u32 *p, struct xdr_netobj *); |
@@ -135,11 +134,6 @@ xdr_adjust_iovec(struct kvec *iov, u32 *p) | |||
135 | } | 134 | } |
136 | 135 | ||
137 | /* | 136 | /* |
138 | * Maximum number of iov's we use. | ||
139 | */ | ||
140 | #define MAX_IOVEC (12) | ||
141 | |||
142 | /* | ||
143 | * XDR buffer helper functions | 137 | * XDR buffer helper functions |
144 | */ | 138 | */ |
145 | extern void xdr_shift_buf(struct xdr_buf *, size_t); | 139 | extern void xdr_shift_buf(struct xdr_buf *, size_t); |
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h index 3b8b6e823c70..6ef99b14ff09 100644 --- a/include/linux/sunrpc/xprt.h +++ b/include/linux/sunrpc/xprt.h | |||
@@ -79,21 +79,19 @@ struct rpc_rqst { | |||
79 | void (*rq_release_snd_buf)(struct rpc_rqst *); /* release rq_enc_pages */ | 79 | void (*rq_release_snd_buf)(struct rpc_rqst *); /* release rq_enc_pages */ |
80 | struct list_head rq_list; | 80 | struct list_head rq_list; |
81 | 81 | ||
82 | __u32 * rq_buffer; /* XDR encode buffer */ | ||
83 | size_t rq_bufsize; | ||
84 | |||
82 | struct xdr_buf rq_private_buf; /* The receive buffer | 85 | struct xdr_buf rq_private_buf; /* The receive buffer |
83 | * used in the softirq. | 86 | * used in the softirq. |
84 | */ | 87 | */ |
85 | unsigned long rq_majortimeo; /* major timeout alarm */ | 88 | unsigned long rq_majortimeo; /* major timeout alarm */ |
86 | unsigned long rq_timeout; /* Current timeout value */ | 89 | unsigned long rq_timeout; /* Current timeout value */ |
87 | unsigned int rq_retries; /* # of retries */ | 90 | unsigned int rq_retries; /* # of retries */ |
88 | /* | ||
89 | * For authentication (e.g. auth_des) | ||
90 | */ | ||
91 | u32 rq_creddata[2]; | ||
92 | 91 | ||
93 | /* | 92 | /* |
94 | * Partial send handling | 93 | * Partial send handling |
95 | */ | 94 | */ |
96 | |||
97 | u32 rq_bytes_sent; /* Bytes we have sent */ | 95 | u32 rq_bytes_sent; /* Bytes we have sent */ |
98 | 96 | ||
99 | unsigned long rq_xtime; /* when transmitted */ | 97 | unsigned long rq_xtime; /* when transmitted */ |
@@ -106,7 +104,10 @@ struct rpc_xprt_ops { | |||
106 | void (*set_buffer_size)(struct rpc_xprt *xprt, size_t sndsize, size_t rcvsize); | 104 | void (*set_buffer_size)(struct rpc_xprt *xprt, size_t sndsize, size_t rcvsize); |
107 | int (*reserve_xprt)(struct rpc_task *task); | 105 | int (*reserve_xprt)(struct rpc_task *task); |
108 | void (*release_xprt)(struct rpc_xprt *xprt, struct rpc_task *task); | 106 | void (*release_xprt)(struct rpc_xprt *xprt, struct rpc_task *task); |
107 | void (*set_port)(struct rpc_xprt *xprt, unsigned short port); | ||
109 | void (*connect)(struct rpc_task *task); | 108 | void (*connect)(struct rpc_task *task); |
109 | void * (*buf_alloc)(struct rpc_task *task, size_t size); | ||
110 | void (*buf_free)(struct rpc_task *task); | ||
110 | int (*send_request)(struct rpc_task *task); | 111 | int (*send_request)(struct rpc_task *task); |
111 | void (*set_retrans_timeout)(struct rpc_task *task); | 112 | void (*set_retrans_timeout)(struct rpc_task *task); |
112 | void (*timer)(struct rpc_task *task); | 113 | void (*timer)(struct rpc_task *task); |
@@ -253,6 +254,7 @@ int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to); | |||
253 | #define XPRT_LOCKED (0) | 254 | #define XPRT_LOCKED (0) |
254 | #define XPRT_CONNECTED (1) | 255 | #define XPRT_CONNECTED (1) |
255 | #define XPRT_CONNECTING (2) | 256 | #define XPRT_CONNECTING (2) |
257 | #define XPRT_CLOSE_WAIT (3) | ||
256 | 258 | ||
257 | static inline void xprt_set_connected(struct rpc_xprt *xprt) | 259 | static inline void xprt_set_connected(struct rpc_xprt *xprt) |
258 | { | 260 | { |
diff --git a/include/linux/writeback.h b/include/linux/writeback.h index 64a36ba43b2f..b096159086e8 100644 --- a/include/linux/writeback.h +++ b/include/linux/writeback.h | |||
@@ -53,10 +53,11 @@ struct writeback_control { | |||
53 | loff_t start; | 53 | loff_t start; |
54 | loff_t end; | 54 | loff_t end; |
55 | 55 | ||
56 | unsigned nonblocking:1; /* Don't get stuck on request queues */ | 56 | unsigned nonblocking:1; /* Don't get stuck on request queues */ |
57 | unsigned encountered_congestion:1; /* An output: a queue is full */ | 57 | unsigned encountered_congestion:1; /* An output: a queue is full */ |
58 | unsigned for_kupdate:1; /* A kupdate writeback */ | 58 | unsigned for_kupdate:1; /* A kupdate writeback */ |
59 | unsigned for_reclaim:1; /* Invoked from the page allocator */ | 59 | unsigned for_reclaim:1; /* Invoked from the page allocator */ |
60 | unsigned for_writepages:1; /* This is a writepages() call */ | ||
60 | }; | 61 | }; |
61 | 62 | ||
62 | /* | 63 | /* |
diff --git a/include/media/saa7146.h b/include/media/saa7146.h index e5be2b9b846b..2bc634fcb7bb 100644 --- a/include/media/saa7146.h +++ b/include/media/saa7146.h | |||
@@ -21,14 +21,14 @@ | |||
21 | 21 | ||
22 | extern unsigned int saa7146_debug; | 22 | extern unsigned int saa7146_debug; |
23 | 23 | ||
24 | //#define DEBUG_PROLOG printk("(0x%08x)(0x%08x) %s: %s(): ",(dev==0?-1:(dev->mem==0?-1:saa7146_read(dev,RPS_ADDR0))),(dev==0?-1:(dev->mem==0?-1:saa7146_read(dev,IER))),__stringify(KBUILD_MODNAME),__FUNCTION__) | 24 | //#define DEBUG_PROLOG printk("(0x%08x)(0x%08x) %s: %s(): ",(dev==0?-1:(dev->mem==0?-1:saa7146_read(dev,RPS_ADDR0))),(dev==0?-1:(dev->mem==0?-1:saa7146_read(dev,IER))),KBUILD_MODNAME,__FUNCTION__) |
25 | 25 | ||
26 | #ifndef DEBUG_VARIABLE | 26 | #ifndef DEBUG_VARIABLE |
27 | #define DEBUG_VARIABLE saa7146_debug | 27 | #define DEBUG_VARIABLE saa7146_debug |
28 | #endif | 28 | #endif |
29 | 29 | ||
30 | #define DEBUG_PROLOG printk("%s: %s(): ",__stringify(KBUILD_MODNAME),__FUNCTION__) | 30 | #define DEBUG_PROLOG printk("%s: %s(): ",KBUILD_MODNAME,__FUNCTION__) |
31 | #define INFO(x) { printk("%s: ",__stringify(KBUILD_MODNAME)); printk x; } | 31 | #define INFO(x) { printk("%s: ",KBUILD_MODNAME); printk x; } |
32 | 32 | ||
33 | #define ERR(x) { DEBUG_PROLOG; printk x; } | 33 | #define ERR(x) { DEBUG_PROLOG; printk x; } |
34 | 34 | ||
diff --git a/include/media/tuner.h b/include/media/tuner.h index faa0f8e3091b..b37cde606692 100644 --- a/include/media/tuner.h +++ b/include/media/tuner.h | |||
@@ -218,14 +218,15 @@ extern int default_tuner_init(struct i2c_client *c); | |||
218 | extern int tea5767_autodetection(struct i2c_client *c); | 218 | extern int tea5767_autodetection(struct i2c_client *c); |
219 | 219 | ||
220 | #define tuner_warn(fmt, arg...) do {\ | 220 | #define tuner_warn(fmt, arg...) do {\ |
221 | printk(KERN_WARNING "%s %d-%04x: " fmt, t->i2c.driver->name, \ | 221 | printk(KERN_WARNING "%s %d-%04x: " fmt, t->i2c.driver->driver.name, \ |
222 | t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0) | 222 | t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0) |
223 | #define tuner_info(fmt, arg...) do {\ | 223 | #define tuner_info(fmt, arg...) do {\ |
224 | printk(KERN_INFO "%s %d-%04x: " fmt, t->i2c.driver->name, \ | 224 | printk(KERN_INFO "%s %d-%04x: " fmt, t->i2c.driver->driver.name, \ |
225 | t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0) | 225 | t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0) |
226 | #define tuner_dbg(fmt, arg...) do {\ | 226 | #define tuner_dbg(fmt, arg...) do {\ |
227 | if (tuner_debug) \ | 227 | if (tuner_debug) \ |
228 | printk(KERN_DEBUG "%s %d-%04x: " fmt, t->i2c.driver->name, \ | 228 | printk(KERN_DEBUG "%s %d-%04x: " fmt, \ |
229 | t->i2c.driver->driver.name, \ | ||
229 | t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0) | 230 | t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0) |
230 | 231 | ||
231 | #endif /* __KERNEL__ */ | 232 | #endif /* __KERNEL__ */ |
diff --git a/include/net/sock.h b/include/net/sock.h index 6961700ff3a0..1806e5b61419 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
@@ -856,8 +856,8 @@ static inline int sk_filter(struct sock *sk, struct sk_buff *skb, int needlock) | |||
856 | 856 | ||
857 | filter = sk->sk_filter; | 857 | filter = sk->sk_filter; |
858 | if (filter) { | 858 | if (filter) { |
859 | int pkt_len = sk_run_filter(skb, filter->insns, | 859 | unsigned int pkt_len = sk_run_filter(skb, filter->insns, |
860 | filter->len); | 860 | filter->len); |
861 | if (!pkt_len) | 861 | if (!pkt_len) |
862 | err = -EPERM; | 862 | err = -EPERM; |
863 | else | 863 | else |
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c index cae4f5728997..4c68edff900b 100644 --- a/kernel/posix-cpu-timers.c +++ b/kernel/posix-cpu-timers.c | |||
@@ -238,18 +238,7 @@ static int cpu_clock_sample_group_locked(unsigned int clock_idx, | |||
238 | while ((t = next_thread(t)) != p) { | 238 | while ((t = next_thread(t)) != p) { |
239 | cpu->sched += t->sched_time; | 239 | cpu->sched += t->sched_time; |
240 | } | 240 | } |
241 | if (p->tgid == current->tgid) { | 241 | cpu->sched += sched_ns(p); |
242 | /* | ||
243 | * We're sampling ourselves, so include the | ||
244 | * cycles not yet banked. We still omit | ||
245 | * other threads running on other CPUs, | ||
246 | * so the total can always be behind as | ||
247 | * much as max(nthreads-1,ncpus) * (NSEC_PER_SEC/HZ). | ||
248 | */ | ||
249 | cpu->sched += current_sched_time(current); | ||
250 | } else { | ||
251 | cpu->sched += p->sched_time; | ||
252 | } | ||
253 | break; | 242 | break; |
254 | } | 243 | } |
255 | return 0; | 244 | return 0; |
diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 0166ea15c9ee..5240e426c1f7 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c | |||
@@ -550,11 +550,17 @@ void __init page_writeback_init(void) | |||
550 | 550 | ||
551 | int do_writepages(struct address_space *mapping, struct writeback_control *wbc) | 551 | int do_writepages(struct address_space *mapping, struct writeback_control *wbc) |
552 | { | 552 | { |
553 | int ret; | ||
554 | |||
553 | if (wbc->nr_to_write <= 0) | 555 | if (wbc->nr_to_write <= 0) |
554 | return 0; | 556 | return 0; |
557 | wbc->for_writepages = 1; | ||
555 | if (mapping->a_ops->writepages) | 558 | if (mapping->a_ops->writepages) |
556 | return mapping->a_ops->writepages(mapping, wbc); | 559 | ret = mapping->a_ops->writepages(mapping, wbc); |
557 | return generic_writepages(mapping, wbc); | 560 | else |
561 | ret = generic_writepages(mapping, wbc); | ||
562 | wbc->for_writepages = 0; | ||
563 | return ret; | ||
558 | } | 564 | } |
559 | 565 | ||
560 | /** | 566 | /** |
diff --git a/net/atm/br2684.c b/net/atm/br2684.c index 72f3f7b8de80..bdb4d89730d2 100644 --- a/net/atm/br2684.c +++ b/net/atm/br2684.c | |||
@@ -295,7 +295,7 @@ static inline __be16 br_type_trans(struct sk_buff *skb, struct net_device *dev) | |||
295 | unsigned char *rawp; | 295 | unsigned char *rawp; |
296 | eth = eth_hdr(skb); | 296 | eth = eth_hdr(skb); |
297 | 297 | ||
298 | if (*eth->h_dest & 1) { | 298 | if (is_multicast_ether_addr(eth->h_dest)) { |
299 | if (memcmp(eth->h_dest, dev->broadcast, ETH_ALEN) == 0) | 299 | if (memcmp(eth->h_dest, dev->broadcast, ETH_ALEN) == 0) |
300 | skb->pkt_type = PACKET_BROADCAST; | 300 | skb->pkt_type = PACKET_BROADCAST; |
301 | else | 301 | else |
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index c387852f753a..e3a73cead6b6 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c | |||
@@ -68,7 +68,7 @@ int br_handle_frame_finish(struct sk_buff *skb) | |||
68 | } | 68 | } |
69 | } | 69 | } |
70 | 70 | ||
71 | if (dest[0] & 1) { | 71 | if (is_multicast_ether_addr(dest)) { |
72 | br_flood_forward(br, skb, !passedup); | 72 | br_flood_forward(br, skb, !passedup); |
73 | if (!passedup) | 73 | if (!passedup) |
74 | br_pass_frame_up(br, skb); | 74 | br_pass_frame_up(br, skb); |
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 223f8270daee..7cac3fb9f809 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c | |||
@@ -394,8 +394,9 @@ inhdr_error: | |||
394 | * target in particular. Save the original destination IP | 394 | * target in particular. Save the original destination IP |
395 | * address to be able to detect DNAT afterwards. */ | 395 | * address to be able to detect DNAT afterwards. */ |
396 | static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb, | 396 | static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb, |
397 | const struct net_device *in, const struct net_device *out, | 397 | const struct net_device *in, |
398 | int (*okfn)(struct sk_buff *)) | 398 | const struct net_device *out, |
399 | int (*okfn)(struct sk_buff *)) | ||
399 | { | 400 | { |
400 | struct iphdr *iph; | 401 | struct iphdr *iph; |
401 | __u32 len; | 402 | __u32 len; |
@@ -412,8 +413,10 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb, | |||
412 | goto out; | 413 | goto out; |
413 | 414 | ||
414 | if (skb->protocol == __constant_htons(ETH_P_8021Q)) { | 415 | if (skb->protocol == __constant_htons(ETH_P_8021Q)) { |
416 | u8 *vhdr = skb->data; | ||
415 | skb_pull(skb, VLAN_HLEN); | 417 | skb_pull(skb, VLAN_HLEN); |
416 | (skb)->nh.raw += VLAN_HLEN; | 418 | skb_postpull_rcsum(skb, vhdr, VLAN_HLEN); |
419 | skb->nh.raw += VLAN_HLEN; | ||
417 | } | 420 | } |
418 | return br_nf_pre_routing_ipv6(hook, skb, in, out, okfn); | 421 | return br_nf_pre_routing_ipv6(hook, skb, in, out, okfn); |
419 | } | 422 | } |
@@ -429,8 +432,10 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb, | |||
429 | goto out; | 432 | goto out; |
430 | 433 | ||
431 | if (skb->protocol == __constant_htons(ETH_P_8021Q)) { | 434 | if (skb->protocol == __constant_htons(ETH_P_8021Q)) { |
435 | u8 *vhdr = skb->data; | ||
432 | skb_pull(skb, VLAN_HLEN); | 436 | skb_pull(skb, VLAN_HLEN); |
433 | (skb)->nh.raw += VLAN_HLEN; | 437 | skb_postpull_rcsum(skb, vhdr, VLAN_HLEN); |
438 | skb->nh.raw += VLAN_HLEN; | ||
434 | } | 439 | } |
435 | 440 | ||
436 | if (!pskb_may_pull(skb, sizeof(struct iphdr))) | 441 | if (!pskb_may_pull(skb, sizeof(struct iphdr))) |
diff --git a/net/core/filter.c b/net/core/filter.c index 8964d3445588..9eb9d0017a01 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
@@ -75,7 +75,7 @@ static inline void *load_pointer(struct sk_buff *skb, int k, | |||
75 | * len is the number of filter blocks in the array. | 75 | * len is the number of filter blocks in the array. |
76 | */ | 76 | */ |
77 | 77 | ||
78 | int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen) | 78 | unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen) |
79 | { | 79 | { |
80 | struct sock_filter *fentry; /* We walk down these */ | 80 | struct sock_filter *fentry; /* We walk down these */ |
81 | void *ptr; | 81 | void *ptr; |
@@ -241,9 +241,9 @@ load_b: | |||
241 | A = X; | 241 | A = X; |
242 | continue; | 242 | continue; |
243 | case BPF_RET|BPF_K: | 243 | case BPF_RET|BPF_K: |
244 | return ((unsigned int)fentry->k); | 244 | return fentry->k; |
245 | case BPF_RET|BPF_A: | 245 | case BPF_RET|BPF_A: |
246 | return ((unsigned int)A); | 246 | return A; |
247 | case BPF_ST: | 247 | case BPF_ST: |
248 | mem[fentry->k] = A; | 248 | mem[fentry->k] = A; |
249 | continue; | 249 | continue; |
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 06cad2d63e8a..631056d44b7b 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c | |||
@@ -473,7 +473,6 @@ static char version[] __initdata = VERSION; | |||
473 | 473 | ||
474 | static int pktgen_remove_device(struct pktgen_thread* t, struct pktgen_dev *i); | 474 | static int pktgen_remove_device(struct pktgen_thread* t, struct pktgen_dev *i); |
475 | static int pktgen_add_device(struct pktgen_thread* t, const char* ifname); | 475 | static int pktgen_add_device(struct pktgen_thread* t, const char* ifname); |
476 | static struct pktgen_thread* pktgen_find_thread(const char* name); | ||
477 | static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread* t, const char* ifname); | 476 | static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread* t, const char* ifname); |
478 | static int pktgen_device_event(struct notifier_block *, unsigned long, void *); | 477 | static int pktgen_device_event(struct notifier_block *, unsigned long, void *); |
479 | static void pktgen_run_all_threads(void); | 478 | static void pktgen_run_all_threads(void); |
@@ -2883,7 +2882,7 @@ static int pktgen_add_device(struct pktgen_thread *t, const char* ifname) | |||
2883 | return add_dev_to_thread(t, pkt_dev); | 2882 | return add_dev_to_thread(t, pkt_dev); |
2884 | } | 2883 | } |
2885 | 2884 | ||
2886 | static struct pktgen_thread *pktgen_find_thread(const char* name) | 2885 | static struct pktgen_thread * __init pktgen_find_thread(const char* name) |
2887 | { | 2886 | { |
2888 | struct pktgen_thread *t = NULL; | 2887 | struct pktgen_thread *t = NULL; |
2889 | 2888 | ||
@@ -2900,7 +2899,7 @@ static struct pktgen_thread *pktgen_find_thread(const char* name) | |||
2900 | return t; | 2899 | return t; |
2901 | } | 2900 | } |
2902 | 2901 | ||
2903 | static int pktgen_create_thread(const char* name, int cpu) | 2902 | static int __init pktgen_create_thread(const char* name, int cpu) |
2904 | { | 2903 | { |
2905 | struct pktgen_thread *t = NULL; | 2904 | struct pktgen_thread *t = NULL; |
2906 | struct proc_dir_entry *pe; | 2905 | struct proc_dir_entry *pe; |
diff --git a/net/core/utils.c b/net/core/utils.c index 587eb7787deb..ac1d1fcf8673 100644 --- a/net/core/utils.c +++ b/net/core/utils.c | |||
@@ -162,7 +162,7 @@ EXPORT_SYMBOL(net_srandom); | |||
162 | * is otherwise not dependent on the TCP/IP stack. | 162 | * is otherwise not dependent on the TCP/IP stack. |
163 | */ | 163 | */ |
164 | 164 | ||
165 | __u32 in_aton(const char *str) | 165 | __be32 in_aton(const char *str) |
166 | { | 166 | { |
167 | unsigned long l; | 167 | unsigned long l; |
168 | unsigned int val; | 168 | unsigned int val; |
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index 9f4dbeb59315..9890fd97e538 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c | |||
@@ -163,7 +163,7 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev) | |||
163 | skb_pull(skb,ETH_HLEN); | 163 | skb_pull(skb,ETH_HLEN); |
164 | eth = eth_hdr(skb); | 164 | eth = eth_hdr(skb); |
165 | 165 | ||
166 | if (*eth->h_dest&1) { | 166 | if (is_multicast_ether_addr(eth->h_dest)) { |
167 | if (!compare_ether_addr(eth->h_dest, dev->broadcast)) | 167 | if (!compare_ether_addr(eth->h_dest, dev->broadcast)) |
168 | skb->pkt_type = PACKET_BROADCAST; | 168 | skb->pkt_type = PACKET_BROADCAST; |
169 | else | 169 | else |
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index ce2b70ce4018..2a8adda15e11 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c | |||
@@ -383,7 +383,7 @@ out_nomem: | |||
383 | */ | 383 | */ |
384 | static inline struct ipq *ip_find(struct iphdr *iph, u32 user) | 384 | static inline struct ipq *ip_find(struct iphdr *iph, u32 user) |
385 | { | 385 | { |
386 | __u16 id = iph->id; | 386 | __be16 id = iph->id; |
387 | __u32 saddr = iph->saddr; | 387 | __u32 saddr = iph->saddr; |
388 | __u32 daddr = iph->daddr; | 388 | __u32 daddr = iph->daddr; |
389 | __u8 protocol = iph->protocol; | 389 | __u8 protocol = iph->protocol; |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 71da31818cfc..8b1c9bd0091e 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -418,7 +418,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) | |||
418 | struct sk_buff *skb2; | 418 | struct sk_buff *skb2; |
419 | unsigned int mtu, hlen, left, len, ll_rs; | 419 | unsigned int mtu, hlen, left, len, ll_rs; |
420 | int offset; | 420 | int offset; |
421 | int not_last_frag; | 421 | __be16 not_last_frag; |
422 | struct rtable *rt = (struct rtable*)skb->dst; | 422 | struct rtable *rt = (struct rtable*)skb->dst; |
423 | int err = 0; | 423 | int err = 0; |
424 | 424 | ||
@@ -1180,7 +1180,7 @@ int ip_push_pending_frames(struct sock *sk) | |||
1180 | struct ip_options *opt = NULL; | 1180 | struct ip_options *opt = NULL; |
1181 | struct rtable *rt = inet->cork.rt; | 1181 | struct rtable *rt = inet->cork.rt; |
1182 | struct iphdr *iph; | 1182 | struct iphdr *iph; |
1183 | int df = 0; | 1183 | __be16 df = 0; |
1184 | __u8 ttl; | 1184 | __u8 ttl; |
1185 | int err = 0; | 1185 | int err = 0; |
1186 | 1186 | ||
diff --git a/net/ipv4/ipvs/ip_vs_xmit.c b/net/ipv4/ipvs/ip_vs_xmit.c index 3b87482049cf..52c12e9edbbc 100644 --- a/net/ipv4/ipvs/ip_vs_xmit.c +++ b/net/ipv4/ipvs/ip_vs_xmit.c | |||
@@ -322,7 +322,7 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
322 | struct net_device *tdev; /* Device to other host */ | 322 | struct net_device *tdev; /* Device to other host */ |
323 | struct iphdr *old_iph = skb->nh.iph; | 323 | struct iphdr *old_iph = skb->nh.iph; |
324 | u8 tos = old_iph->tos; | 324 | u8 tos = old_iph->tos; |
325 | u16 df = old_iph->frag_off; | 325 | __be16 df = old_iph->frag_off; |
326 | struct iphdr *iph; /* Our new IP header */ | 326 | struct iphdr *iph; /* Our new IP header */ |
327 | int max_headroom; /* The extra header space needed */ | 327 | int max_headroom; /* The extra header space needed */ |
328 | int mtu; | 328 | int mtu; |
diff --git a/net/ipv4/netfilter/ip_nat_ftp.c b/net/ipv4/netfilter/ip_nat_ftp.c index d83757a70d9f..b8daab3c64af 100644 --- a/net/ipv4/netfilter/ip_nat_ftp.c +++ b/net/ipv4/netfilter/ip_nat_ftp.c | |||
@@ -171,7 +171,7 @@ static int __init init(void) | |||
171 | /* Prior to 2.6.11, we had a ports param. No longer, but don't break users. */ | 171 | /* Prior to 2.6.11, we had a ports param. No longer, but don't break users. */ |
172 | static int warn_set(const char *val, struct kernel_param *kp) | 172 | static int warn_set(const char *val, struct kernel_param *kp) |
173 | { | 173 | { |
174 | printk(KERN_INFO __stringify(KBUILD_MODNAME) | 174 | printk(KERN_INFO KBUILD_MODNAME |
175 | ": kernel >= 2.6.10 only uses 'ports' for conntrack modules\n"); | 175 | ": kernel >= 2.6.10 only uses 'ports' for conntrack modules\n"); |
176 | return 0; | 176 | return 0; |
177 | } | 177 | } |
diff --git a/net/ipv4/netfilter/ip_nat_irc.c b/net/ipv4/netfilter/ip_nat_irc.c index de31942babe3..461c833eaca1 100644 --- a/net/ipv4/netfilter/ip_nat_irc.c +++ b/net/ipv4/netfilter/ip_nat_irc.c | |||
@@ -113,7 +113,7 @@ static int __init init(void) | |||
113 | /* Prior to 2.6.11, we had a ports param. No longer, but don't break users. */ | 113 | /* Prior to 2.6.11, we had a ports param. No longer, but don't break users. */ |
114 | static int warn_set(const char *val, struct kernel_param *kp) | 114 | static int warn_set(const char *val, struct kernel_param *kp) |
115 | { | 115 | { |
116 | printk(KERN_INFO __stringify(KBUILD_MODNAME) | 116 | printk(KERN_INFO KBUILD_MODNAME |
117 | ": kernel >= 2.6.10 only uses 'ports' for conntrack modules\n"); | 117 | ": kernel >= 2.6.10 only uses 'ports' for conntrack modules\n"); |
118 | return 0; | 118 | return 0; |
119 | } | 119 | } |
diff --git a/net/ipv4/netfilter/ipt_helper.c b/net/ipv4/netfilter/ipt_helper.c index bf14e1c7798a..aef649e393af 100644 --- a/net/ipv4/netfilter/ipt_helper.c +++ b/net/ipv4/netfilter/ipt_helper.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/skbuff.h> | 14 | #include <linux/skbuff.h> |
15 | #include <linux/netfilter.h> | 15 | #include <linux/netfilter.h> |
16 | #include <linux/interrupt.h> | ||
16 | #if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) | 17 | #if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) |
17 | #include <linux/netfilter_ipv4/ip_conntrack.h> | 18 | #include <linux/netfilter_ipv4/ip_conntrack.h> |
18 | #include <linux/netfilter_ipv4/ip_conntrack_core.h> | 19 | #include <linux/netfilter_ipv4/ip_conntrack_core.h> |
diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index 5f1f806a0b11..129e2bd36aff 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c | |||
@@ -97,13 +97,17 @@ get_key(const void *p, const void *end, struct crypto_tfm **res) | |||
97 | alg_mode = CRYPTO_TFM_MODE_CBC; | 97 | alg_mode = CRYPTO_TFM_MODE_CBC; |
98 | break; | 98 | break; |
99 | default: | 99 | default: |
100 | dprintk("RPC: get_key: unsupported algorithm %d\n", alg); | 100 | printk("gss_kerberos_mech: unsupported algorithm %d\n", alg); |
101 | goto out_err_free_key; | 101 | goto out_err_free_key; |
102 | } | 102 | } |
103 | if (!(*res = crypto_alloc_tfm(alg_name, alg_mode))) | 103 | if (!(*res = crypto_alloc_tfm(alg_name, alg_mode))) { |
104 | printk("gss_kerberos_mech: unable to initialize crypto algorithm %s\n", alg_name); | ||
104 | goto out_err_free_key; | 105 | goto out_err_free_key; |
105 | if (crypto_cipher_setkey(*res, key.data, key.len)) | 106 | } |
107 | if (crypto_cipher_setkey(*res, key.data, key.len)) { | ||
108 | printk("gss_kerberos_mech: error setting key for crypto algorithm %s\n", alg_name); | ||
106 | goto out_err_free_tfm; | 109 | goto out_err_free_tfm; |
110 | } | ||
107 | 111 | ||
108 | kfree(key.data); | 112 | kfree(key.data); |
109 | return p; | 113 | return p; |
diff --git a/net/sunrpc/auth_gss/gss_spkm3_mech.c b/net/sunrpc/auth_gss/gss_spkm3_mech.c index 39b3edc14694..58400807d4df 100644 --- a/net/sunrpc/auth_gss/gss_spkm3_mech.c +++ b/net/sunrpc/auth_gss/gss_spkm3_mech.c | |||
@@ -111,14 +111,18 @@ get_key(const void *p, const void *end, struct crypto_tfm **res, int *resalg) | |||
111 | setkey = 0; | 111 | setkey = 0; |
112 | break; | 112 | break; |
113 | default: | 113 | default: |
114 | dprintk("RPC: SPKM3 get_key: unsupported algorithm %d", *resalg); | 114 | dprintk("gss_spkm3_mech: unsupported algorithm %d\n", *resalg); |
115 | goto out_err_free_key; | 115 | goto out_err_free_key; |
116 | } | 116 | } |
117 | if (!(*res = crypto_alloc_tfm(alg_name, alg_mode))) | 117 | if (!(*res = crypto_alloc_tfm(alg_name, alg_mode))) { |
118 | printk("gss_spkm3_mech: unable to initialize crypto algorthm %s\n", alg_name); | ||
118 | goto out_err_free_key; | 119 | goto out_err_free_key; |
120 | } | ||
119 | if (setkey) { | 121 | if (setkey) { |
120 | if (crypto_cipher_setkey(*res, key.data, key.len)) | 122 | if (crypto_cipher_setkey(*res, key.data, key.len)) { |
123 | printk("gss_spkm3_mech: error setting key for crypto algorthm %s\n", alg_name); | ||
121 | goto out_err_free_tfm; | 124 | goto out_err_free_tfm; |
125 | } | ||
122 | } | 126 | } |
123 | 127 | ||
124 | if(key.len > 0) | 128 | if(key.len > 0) |
diff --git a/net/sunrpc/auth_gss/gss_spkm3_seal.c b/net/sunrpc/auth_gss/gss_spkm3_seal.c index d1e12b25d6e2..86fbf7c3e39c 100644 --- a/net/sunrpc/auth_gss/gss_spkm3_seal.c +++ b/net/sunrpc/auth_gss/gss_spkm3_seal.c | |||
@@ -59,7 +59,7 @@ spkm3_make_token(struct spkm3_ctx *ctx, | |||
59 | char tokhdrbuf[25]; | 59 | char tokhdrbuf[25]; |
60 | struct xdr_netobj md5cksum = {.len = 0, .data = NULL}; | 60 | struct xdr_netobj md5cksum = {.len = 0, .data = NULL}; |
61 | struct xdr_netobj mic_hdr = {.len = 0, .data = tokhdrbuf}; | 61 | struct xdr_netobj mic_hdr = {.len = 0, .data = tokhdrbuf}; |
62 | int tmsglen, tokenlen = 0; | 62 | int tokenlen = 0; |
63 | unsigned char *ptr; | 63 | unsigned char *ptr; |
64 | s32 now; | 64 | s32 now; |
65 | int ctxelen = 0, ctxzbit = 0; | 65 | int ctxelen = 0, ctxzbit = 0; |
@@ -92,24 +92,23 @@ spkm3_make_token(struct spkm3_ctx *ctx, | |||
92 | } | 92 | } |
93 | 93 | ||
94 | if (toktype == SPKM_MIC_TOK) { | 94 | if (toktype == SPKM_MIC_TOK) { |
95 | tmsglen = 0; | ||
96 | /* Calculate checksum over the mic-header */ | 95 | /* Calculate checksum over the mic-header */ |
97 | asn1_bitstring_len(&ctx->ctx_id, &ctxelen, &ctxzbit); | 96 | asn1_bitstring_len(&ctx->ctx_id, &ctxelen, &ctxzbit); |
98 | spkm3_mic_header(&mic_hdr.data, &mic_hdr.len, ctx->ctx_id.data, | 97 | spkm3_mic_header(&mic_hdr.data, &mic_hdr.len, ctx->ctx_id.data, |
99 | ctxelen, ctxzbit); | 98 | ctxelen, ctxzbit); |
100 | 99 | ||
101 | if (make_checksum(checksum_type, mic_hdr.data, mic_hdr.len, | 100 | if (make_checksum(checksum_type, mic_hdr.data, mic_hdr.len, |
102 | text, &md5cksum)) | 101 | text, 0, &md5cksum)) |
103 | goto out_err; | 102 | goto out_err; |
104 | 103 | ||
105 | asn1_bitstring_len(&md5cksum, &md5elen, &md5zbit); | 104 | asn1_bitstring_len(&md5cksum, &md5elen, &md5zbit); |
106 | tokenlen = 10 + ctxelen + 1 + 2 + md5elen + 1; | 105 | tokenlen = 10 + ctxelen + 1 + md5elen + 1; |
107 | 106 | ||
108 | /* Create token header using generic routines */ | 107 | /* Create token header using generic routines */ |
109 | token->len = g_token_size(&ctx->mech_used, tokenlen + tmsglen); | 108 | token->len = g_token_size(&ctx->mech_used, tokenlen); |
110 | 109 | ||
111 | ptr = token->data; | 110 | ptr = token->data; |
112 | g_make_token_header(&ctx->mech_used, tokenlen + tmsglen, &ptr); | 111 | g_make_token_header(&ctx->mech_used, tokenlen, &ptr); |
113 | 112 | ||
114 | spkm3_make_mic_token(&ptr, tokenlen, &mic_hdr, &md5cksum, md5elen, md5zbit); | 113 | spkm3_make_mic_token(&ptr, tokenlen, &mic_hdr, &md5cksum, md5elen, md5zbit); |
115 | } else if (toktype == SPKM_WRAP_TOK) { /* Not Supported */ | 114 | } else if (toktype == SPKM_WRAP_TOK) { /* Not Supported */ |
diff --git a/net/sunrpc/auth_gss/gss_spkm3_token.c b/net/sunrpc/auth_gss/gss_spkm3_token.c index 1f824578d773..af0d7ce74686 100644 --- a/net/sunrpc/auth_gss/gss_spkm3_token.c +++ b/net/sunrpc/auth_gss/gss_spkm3_token.c | |||
@@ -182,6 +182,7 @@ spkm3_mic_header(unsigned char **hdrbuf, unsigned int *hdrlen, unsigned char *ct | |||
182 | * *tokp points to the beginning of the SPKM_MIC token described | 182 | * *tokp points to the beginning of the SPKM_MIC token described |
183 | * in rfc 2025, section 3.2.1: | 183 | * in rfc 2025, section 3.2.1: |
184 | * | 184 | * |
185 | * toklen is the inner token length | ||
185 | */ | 186 | */ |
186 | void | 187 | void |
187 | spkm3_make_mic_token(unsigned char **tokp, int toklen, struct xdr_netobj *mic_hdr, struct xdr_netobj *md5cksum, int md5elen, int md5zbit) | 188 | spkm3_make_mic_token(unsigned char **tokp, int toklen, struct xdr_netobj *mic_hdr, struct xdr_netobj *md5cksum, int md5elen, int md5zbit) |
@@ -189,7 +190,7 @@ spkm3_make_mic_token(unsigned char **tokp, int toklen, struct xdr_netobj *mic_hd | |||
189 | unsigned char *ict = *tokp; | 190 | unsigned char *ict = *tokp; |
190 | 191 | ||
191 | *(u8 *)ict++ = 0xa4; | 192 | *(u8 *)ict++ = 0xa4; |
192 | *(u8 *)ict++ = toklen - 2; | 193 | *(u8 *)ict++ = toklen; |
193 | memcpy(ict, mic_hdr->data, mic_hdr->len); | 194 | memcpy(ict, mic_hdr->data, mic_hdr->len); |
194 | ict += mic_hdr->len; | 195 | ict += mic_hdr->len; |
195 | 196 | ||
diff --git a/net/sunrpc/auth_gss/gss_spkm3_unseal.c b/net/sunrpc/auth_gss/gss_spkm3_unseal.c index 241d5b30dfcb..96851b0ba1ba 100644 --- a/net/sunrpc/auth_gss/gss_spkm3_unseal.c +++ b/net/sunrpc/auth_gss/gss_spkm3_unseal.c | |||
@@ -95,7 +95,7 @@ spkm3_read_token(struct spkm3_ctx *ctx, | |||
95 | ret = GSS_S_DEFECTIVE_TOKEN; | 95 | ret = GSS_S_DEFECTIVE_TOKEN; |
96 | code = make_checksum(CKSUMTYPE_RSA_MD5, ptr + 2, | 96 | code = make_checksum(CKSUMTYPE_RSA_MD5, ptr + 2, |
97 | mic_hdrlen + 2, | 97 | mic_hdrlen + 2, |
98 | message_buffer, &md5cksum); | 98 | message_buffer, 0, &md5cksum); |
99 | 99 | ||
100 | if (code) | 100 | if (code) |
101 | goto out; | 101 | goto out; |
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 61c3abeaccae..5530ac8c6df9 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
@@ -374,19 +374,23 @@ out: | |||
374 | * Default callback for async RPC calls | 374 | * Default callback for async RPC calls |
375 | */ | 375 | */ |
376 | static void | 376 | static void |
377 | rpc_default_callback(struct rpc_task *task) | 377 | rpc_default_callback(struct rpc_task *task, void *data) |
378 | { | 378 | { |
379 | } | 379 | } |
380 | 380 | ||
381 | static const struct rpc_call_ops rpc_default_ops = { | ||
382 | .rpc_call_done = rpc_default_callback, | ||
383 | }; | ||
384 | |||
381 | /* | 385 | /* |
382 | * Export the signal mask handling for synchronous code that | 386 | * Export the signal mask handling for synchronous code that |
383 | * sleeps on RPC calls | 387 | * sleeps on RPC calls |
384 | */ | 388 | */ |
385 | #define RPC_INTR_SIGNALS (sigmask(SIGINT) | sigmask(SIGQUIT) | sigmask(SIGKILL)) | 389 | #define RPC_INTR_SIGNALS (sigmask(SIGHUP) | sigmask(SIGINT) | sigmask(SIGQUIT) | sigmask(SIGTERM)) |
386 | 390 | ||
387 | static void rpc_save_sigmask(sigset_t *oldset, int intr) | 391 | static void rpc_save_sigmask(sigset_t *oldset, int intr) |
388 | { | 392 | { |
389 | unsigned long sigallow = 0; | 393 | unsigned long sigallow = sigmask(SIGKILL); |
390 | sigset_t sigmask; | 394 | sigset_t sigmask; |
391 | 395 | ||
392 | /* Block all signals except those listed in sigallow */ | 396 | /* Block all signals except those listed in sigallow */ |
@@ -432,7 +436,7 @@ int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg, int flags) | |||
432 | BUG_ON(flags & RPC_TASK_ASYNC); | 436 | BUG_ON(flags & RPC_TASK_ASYNC); |
433 | 437 | ||
434 | status = -ENOMEM; | 438 | status = -ENOMEM; |
435 | task = rpc_new_task(clnt, NULL, flags); | 439 | task = rpc_new_task(clnt, flags, &rpc_default_ops, NULL); |
436 | if (task == NULL) | 440 | if (task == NULL) |
437 | goto out; | 441 | goto out; |
438 | 442 | ||
@@ -442,14 +446,15 @@ int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg, int flags) | |||
442 | rpc_call_setup(task, msg, 0); | 446 | rpc_call_setup(task, msg, 0); |
443 | 447 | ||
444 | /* Set up the call info struct and execute the task */ | 448 | /* Set up the call info struct and execute the task */ |
445 | if (task->tk_status == 0) { | 449 | status = task->tk_status; |
450 | if (status == 0) { | ||
451 | atomic_inc(&task->tk_count); | ||
446 | status = rpc_execute(task); | 452 | status = rpc_execute(task); |
447 | } else { | 453 | if (status == 0) |
448 | status = task->tk_status; | 454 | status = task->tk_status; |
449 | rpc_release_task(task); | ||
450 | } | 455 | } |
451 | |||
452 | rpc_restore_sigmask(&oldset); | 456 | rpc_restore_sigmask(&oldset); |
457 | rpc_release_task(task); | ||
453 | out: | 458 | out: |
454 | return status; | 459 | return status; |
455 | } | 460 | } |
@@ -459,7 +464,7 @@ out: | |||
459 | */ | 464 | */ |
460 | int | 465 | int |
461 | rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags, | 466 | rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags, |
462 | rpc_action callback, void *data) | 467 | const struct rpc_call_ops *tk_ops, void *data) |
463 | { | 468 | { |
464 | struct rpc_task *task; | 469 | struct rpc_task *task; |
465 | sigset_t oldset; | 470 | sigset_t oldset; |
@@ -472,12 +477,9 @@ rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags, | |||
472 | flags |= RPC_TASK_ASYNC; | 477 | flags |= RPC_TASK_ASYNC; |
473 | 478 | ||
474 | /* Create/initialize a new RPC task */ | 479 | /* Create/initialize a new RPC task */ |
475 | if (!callback) | ||
476 | callback = rpc_default_callback; | ||
477 | status = -ENOMEM; | 480 | status = -ENOMEM; |
478 | if (!(task = rpc_new_task(clnt, callback, flags))) | 481 | if (!(task = rpc_new_task(clnt, flags, tk_ops, data))) |
479 | goto out; | 482 | goto out; |
480 | task->tk_calldata = data; | ||
481 | 483 | ||
482 | /* Mask signals on GSS_AUTH upcalls */ | 484 | /* Mask signals on GSS_AUTH upcalls */ |
483 | rpc_task_sigmask(task, &oldset); | 485 | rpc_task_sigmask(task, &oldset); |
@@ -511,7 +513,7 @@ rpc_call_setup(struct rpc_task *task, struct rpc_message *msg, int flags) | |||
511 | if (task->tk_status == 0) | 513 | if (task->tk_status == 0) |
512 | task->tk_action = call_start; | 514 | task->tk_action = call_start; |
513 | else | 515 | else |
514 | task->tk_action = NULL; | 516 | task->tk_action = rpc_exit_task; |
515 | } | 517 | } |
516 | 518 | ||
517 | void | 519 | void |
@@ -536,6 +538,18 @@ size_t rpc_max_payload(struct rpc_clnt *clnt) | |||
536 | } | 538 | } |
537 | EXPORT_SYMBOL(rpc_max_payload); | 539 | EXPORT_SYMBOL(rpc_max_payload); |
538 | 540 | ||
541 | /** | ||
542 | * rpc_force_rebind - force transport to check that remote port is unchanged | ||
543 | * @clnt: client to rebind | ||
544 | * | ||
545 | */ | ||
546 | void rpc_force_rebind(struct rpc_clnt *clnt) | ||
547 | { | ||
548 | if (clnt->cl_autobind) | ||
549 | clnt->cl_port = 0; | ||
550 | } | ||
551 | EXPORT_SYMBOL(rpc_force_rebind); | ||
552 | |||
539 | /* | 553 | /* |
540 | * Restart an (async) RPC call. Usually called from within the | 554 | * Restart an (async) RPC call. Usually called from within the |
541 | * exit handler. | 555 | * exit handler. |
@@ -642,24 +656,26 @@ call_reserveresult(struct rpc_task *task) | |||
642 | 656 | ||
643 | /* | 657 | /* |
644 | * 2. Allocate the buffer. For details, see sched.c:rpc_malloc. | 658 | * 2. Allocate the buffer. For details, see sched.c:rpc_malloc. |
645 | * (Note: buffer memory is freed in rpc_task_release). | 659 | * (Note: buffer memory is freed in xprt_release). |
646 | */ | 660 | */ |
647 | static void | 661 | static void |
648 | call_allocate(struct rpc_task *task) | 662 | call_allocate(struct rpc_task *task) |
649 | { | 663 | { |
664 | struct rpc_rqst *req = task->tk_rqstp; | ||
665 | struct rpc_xprt *xprt = task->tk_xprt; | ||
650 | unsigned int bufsiz; | 666 | unsigned int bufsiz; |
651 | 667 | ||
652 | dprintk("RPC: %4d call_allocate (status %d)\n", | 668 | dprintk("RPC: %4d call_allocate (status %d)\n", |
653 | task->tk_pid, task->tk_status); | 669 | task->tk_pid, task->tk_status); |
654 | task->tk_action = call_bind; | 670 | task->tk_action = call_bind; |
655 | if (task->tk_buffer) | 671 | if (req->rq_buffer) |
656 | return; | 672 | return; |
657 | 673 | ||
658 | /* FIXME: compute buffer requirements more exactly using | 674 | /* FIXME: compute buffer requirements more exactly using |
659 | * auth->au_wslack */ | 675 | * auth->au_wslack */ |
660 | bufsiz = task->tk_msg.rpc_proc->p_bufsiz + RPC_SLACK_SPACE; | 676 | bufsiz = task->tk_msg.rpc_proc->p_bufsiz + RPC_SLACK_SPACE; |
661 | 677 | ||
662 | if (rpc_malloc(task, bufsiz << 1) != NULL) | 678 | if (xprt->ops->buf_alloc(task, bufsiz << 1) != NULL) |
663 | return; | 679 | return; |
664 | printk(KERN_INFO "RPC: buffer allocation failed for task %p\n", task); | 680 | printk(KERN_INFO "RPC: buffer allocation failed for task %p\n", task); |
665 | 681 | ||
@@ -702,14 +718,14 @@ call_encode(struct rpc_task *task) | |||
702 | task->tk_pid, task->tk_status); | 718 | task->tk_pid, task->tk_status); |
703 | 719 | ||
704 | /* Default buffer setup */ | 720 | /* Default buffer setup */ |
705 | bufsiz = task->tk_bufsize >> 1; | 721 | bufsiz = req->rq_bufsize >> 1; |
706 | sndbuf->head[0].iov_base = (void *)task->tk_buffer; | 722 | sndbuf->head[0].iov_base = (void *)req->rq_buffer; |
707 | sndbuf->head[0].iov_len = bufsiz; | 723 | sndbuf->head[0].iov_len = bufsiz; |
708 | sndbuf->tail[0].iov_len = 0; | 724 | sndbuf->tail[0].iov_len = 0; |
709 | sndbuf->page_len = 0; | 725 | sndbuf->page_len = 0; |
710 | sndbuf->len = 0; | 726 | sndbuf->len = 0; |
711 | sndbuf->buflen = bufsiz; | 727 | sndbuf->buflen = bufsiz; |
712 | rcvbuf->head[0].iov_base = (void *)((char *)task->tk_buffer + bufsiz); | 728 | rcvbuf->head[0].iov_base = (void *)((char *)req->rq_buffer + bufsiz); |
713 | rcvbuf->head[0].iov_len = bufsiz; | 729 | rcvbuf->head[0].iov_len = bufsiz; |
714 | rcvbuf->tail[0].iov_len = 0; | 730 | rcvbuf->tail[0].iov_len = 0; |
715 | rcvbuf->page_len = 0; | 731 | rcvbuf->page_len = 0; |
@@ -849,8 +865,7 @@ call_connect_status(struct rpc_task *task) | |||
849 | } | 865 | } |
850 | 866 | ||
851 | /* Something failed: remote service port may have changed */ | 867 | /* Something failed: remote service port may have changed */ |
852 | if (clnt->cl_autobind) | 868 | rpc_force_rebind(clnt); |
853 | clnt->cl_port = 0; | ||
854 | 869 | ||
855 | switch (status) { | 870 | switch (status) { |
856 | case -ENOTCONN: | 871 | case -ENOTCONN: |
@@ -892,7 +907,7 @@ call_transmit(struct rpc_task *task) | |||
892 | if (task->tk_status < 0) | 907 | if (task->tk_status < 0) |
893 | return; | 908 | return; |
894 | if (!task->tk_msg.rpc_proc->p_decode) { | 909 | if (!task->tk_msg.rpc_proc->p_decode) { |
895 | task->tk_action = NULL; | 910 | task->tk_action = rpc_exit_task; |
896 | rpc_wake_up_task(task); | 911 | rpc_wake_up_task(task); |
897 | } | 912 | } |
898 | return; | 913 | return; |
@@ -931,8 +946,7 @@ call_status(struct rpc_task *task) | |||
931 | break; | 946 | break; |
932 | case -ECONNREFUSED: | 947 | case -ECONNREFUSED: |
933 | case -ENOTCONN: | 948 | case -ENOTCONN: |
934 | if (clnt->cl_autobind) | 949 | rpc_force_rebind(clnt); |
935 | clnt->cl_port = 0; | ||
936 | task->tk_action = call_bind; | 950 | task->tk_action = call_bind; |
937 | break; | 951 | break; |
938 | case -EAGAIN: | 952 | case -EAGAIN: |
@@ -943,8 +957,7 @@ call_status(struct rpc_task *task) | |||
943 | rpc_exit(task, status); | 957 | rpc_exit(task, status); |
944 | break; | 958 | break; |
945 | default: | 959 | default: |
946 | if (clnt->cl_chatty) | 960 | printk("%s: RPC call returned error %d\n", |
947 | printk("%s: RPC call returned error %d\n", | ||
948 | clnt->cl_protname, -status); | 961 | clnt->cl_protname, -status); |
949 | rpc_exit(task, status); | 962 | rpc_exit(task, status); |
950 | break; | 963 | break; |
@@ -979,20 +992,18 @@ call_timeout(struct rpc_task *task) | |||
979 | 992 | ||
980 | dprintk("RPC: %4d call_timeout (major)\n", task->tk_pid); | 993 | dprintk("RPC: %4d call_timeout (major)\n", task->tk_pid); |
981 | if (RPC_IS_SOFT(task)) { | 994 | if (RPC_IS_SOFT(task)) { |
982 | if (clnt->cl_chatty) | 995 | printk(KERN_NOTICE "%s: server %s not responding, timed out\n", |
983 | printk(KERN_NOTICE "%s: server %s not responding, timed out\n", | ||
984 | clnt->cl_protname, clnt->cl_server); | 996 | clnt->cl_protname, clnt->cl_server); |
985 | rpc_exit(task, -EIO); | 997 | rpc_exit(task, -EIO); |
986 | return; | 998 | return; |
987 | } | 999 | } |
988 | 1000 | ||
989 | if (clnt->cl_chatty && !(task->tk_flags & RPC_CALL_MAJORSEEN)) { | 1001 | if (!(task->tk_flags & RPC_CALL_MAJORSEEN)) { |
990 | task->tk_flags |= RPC_CALL_MAJORSEEN; | 1002 | task->tk_flags |= RPC_CALL_MAJORSEEN; |
991 | printk(KERN_NOTICE "%s: server %s not responding, still trying\n", | 1003 | printk(KERN_NOTICE "%s: server %s not responding, still trying\n", |
992 | clnt->cl_protname, clnt->cl_server); | 1004 | clnt->cl_protname, clnt->cl_server); |
993 | } | 1005 | } |
994 | if (clnt->cl_autobind) | 1006 | rpc_force_rebind(clnt); |
995 | clnt->cl_port = 0; | ||
996 | 1007 | ||
997 | retry: | 1008 | retry: |
998 | clnt->cl_stats->rpcretrans++; | 1009 | clnt->cl_stats->rpcretrans++; |
@@ -1014,7 +1025,7 @@ call_decode(struct rpc_task *task) | |||
1014 | dprintk("RPC: %4d call_decode (status %d)\n", | 1025 | dprintk("RPC: %4d call_decode (status %d)\n", |
1015 | task->tk_pid, task->tk_status); | 1026 | task->tk_pid, task->tk_status); |
1016 | 1027 | ||
1017 | if (clnt->cl_chatty && (task->tk_flags & RPC_CALL_MAJORSEEN)) { | 1028 | if (task->tk_flags & RPC_CALL_MAJORSEEN) { |
1018 | printk(KERN_NOTICE "%s: server %s OK\n", | 1029 | printk(KERN_NOTICE "%s: server %s OK\n", |
1019 | clnt->cl_protname, clnt->cl_server); | 1030 | clnt->cl_protname, clnt->cl_server); |
1020 | task->tk_flags &= ~RPC_CALL_MAJORSEEN; | 1031 | task->tk_flags &= ~RPC_CALL_MAJORSEEN; |
@@ -1039,13 +1050,14 @@ call_decode(struct rpc_task *task) | |||
1039 | sizeof(req->rq_rcv_buf)) != 0); | 1050 | sizeof(req->rq_rcv_buf)) != 0); |
1040 | 1051 | ||
1041 | /* Verify the RPC header */ | 1052 | /* Verify the RPC header */ |
1042 | if (!(p = call_verify(task))) { | 1053 | p = call_verify(task); |
1043 | if (task->tk_action == NULL) | 1054 | if (IS_ERR(p)) { |
1044 | return; | 1055 | if (p == ERR_PTR(-EAGAIN)) |
1045 | goto out_retry; | 1056 | goto out_retry; |
1057 | return; | ||
1046 | } | 1058 | } |
1047 | 1059 | ||
1048 | task->tk_action = NULL; | 1060 | task->tk_action = rpc_exit_task; |
1049 | 1061 | ||
1050 | if (decode) | 1062 | if (decode) |
1051 | task->tk_status = rpcauth_unwrap_resp(task, decode, req, p, | 1063 | task->tk_status = rpcauth_unwrap_resp(task, decode, req, p, |
@@ -1138,7 +1150,7 @@ call_verify(struct rpc_task *task) | |||
1138 | 1150 | ||
1139 | if ((n = ntohl(*p++)) != RPC_REPLY) { | 1151 | if ((n = ntohl(*p++)) != RPC_REPLY) { |
1140 | printk(KERN_WARNING "call_verify: not an RPC reply: %x\n", n); | 1152 | printk(KERN_WARNING "call_verify: not an RPC reply: %x\n", n); |
1141 | goto out_retry; | 1153 | goto out_garbage; |
1142 | } | 1154 | } |
1143 | if ((n = ntohl(*p++)) != RPC_MSG_ACCEPTED) { | 1155 | if ((n = ntohl(*p++)) != RPC_MSG_ACCEPTED) { |
1144 | if (--len < 0) | 1156 | if (--len < 0) |
@@ -1168,7 +1180,7 @@ call_verify(struct rpc_task *task) | |||
1168 | task->tk_pid); | 1180 | task->tk_pid); |
1169 | rpcauth_invalcred(task); | 1181 | rpcauth_invalcred(task); |
1170 | task->tk_action = call_refresh; | 1182 | task->tk_action = call_refresh; |
1171 | return NULL; | 1183 | goto out_retry; |
1172 | case RPC_AUTH_BADCRED: | 1184 | case RPC_AUTH_BADCRED: |
1173 | case RPC_AUTH_BADVERF: | 1185 | case RPC_AUTH_BADVERF: |
1174 | /* possibly garbled cred/verf? */ | 1186 | /* possibly garbled cred/verf? */ |
@@ -1178,7 +1190,7 @@ call_verify(struct rpc_task *task) | |||
1178 | dprintk("RPC: %4d call_verify: retry garbled creds\n", | 1190 | dprintk("RPC: %4d call_verify: retry garbled creds\n", |
1179 | task->tk_pid); | 1191 | task->tk_pid); |
1180 | task->tk_action = call_bind; | 1192 | task->tk_action = call_bind; |
1181 | return NULL; | 1193 | goto out_retry; |
1182 | case RPC_AUTH_TOOWEAK: | 1194 | case RPC_AUTH_TOOWEAK: |
1183 | printk(KERN_NOTICE "call_verify: server requires stronger " | 1195 | printk(KERN_NOTICE "call_verify: server requires stronger " |
1184 | "authentication.\n"); | 1196 | "authentication.\n"); |
@@ -1193,7 +1205,7 @@ call_verify(struct rpc_task *task) | |||
1193 | } | 1205 | } |
1194 | if (!(p = rpcauth_checkverf(task, p))) { | 1206 | if (!(p = rpcauth_checkverf(task, p))) { |
1195 | printk(KERN_WARNING "call_verify: auth check failed\n"); | 1207 | printk(KERN_WARNING "call_verify: auth check failed\n"); |
1196 | goto out_retry; /* bad verifier, retry */ | 1208 | goto out_garbage; /* bad verifier, retry */ |
1197 | } | 1209 | } |
1198 | len = p - (u32 *)iov->iov_base - 1; | 1210 | len = p - (u32 *)iov->iov_base - 1; |
1199 | if (len < 0) | 1211 | if (len < 0) |
@@ -1230,23 +1242,24 @@ call_verify(struct rpc_task *task) | |||
1230 | /* Also retry */ | 1242 | /* Also retry */ |
1231 | } | 1243 | } |
1232 | 1244 | ||
1233 | out_retry: | 1245 | out_garbage: |
1234 | task->tk_client->cl_stats->rpcgarbage++; | 1246 | task->tk_client->cl_stats->rpcgarbage++; |
1235 | if (task->tk_garb_retry) { | 1247 | if (task->tk_garb_retry) { |
1236 | task->tk_garb_retry--; | 1248 | task->tk_garb_retry--; |
1237 | dprintk("RPC %s: retrying %4d\n", __FUNCTION__, task->tk_pid); | 1249 | dprintk("RPC %s: retrying %4d\n", __FUNCTION__, task->tk_pid); |
1238 | task->tk_action = call_bind; | 1250 | task->tk_action = call_bind; |
1239 | return NULL; | 1251 | out_retry: |
1252 | return ERR_PTR(-EAGAIN); | ||
1240 | } | 1253 | } |
1241 | printk(KERN_WARNING "RPC %s: retry failed, exit EIO\n", __FUNCTION__); | 1254 | printk(KERN_WARNING "RPC %s: retry failed, exit EIO\n", __FUNCTION__); |
1242 | out_eio: | 1255 | out_eio: |
1243 | error = -EIO; | 1256 | error = -EIO; |
1244 | out_err: | 1257 | out_err: |
1245 | rpc_exit(task, error); | 1258 | rpc_exit(task, error); |
1246 | return NULL; | 1259 | return ERR_PTR(error); |
1247 | out_overflow: | 1260 | out_overflow: |
1248 | printk(KERN_WARNING "RPC %s: server reply was truncated.\n", __FUNCTION__); | 1261 | printk(KERN_WARNING "RPC %s: server reply was truncated.\n", __FUNCTION__); |
1249 | goto out_retry; | 1262 | goto out_garbage; |
1250 | } | 1263 | } |
1251 | 1264 | ||
1252 | static int rpcproc_encode_null(void *rqstp, u32 *data, void *obj) | 1265 | static int rpcproc_encode_null(void *rqstp, u32 *data, void *obj) |
diff --git a/net/sunrpc/pmap_clnt.c b/net/sunrpc/pmap_clnt.c index a398575f94b8..8139ce68e915 100644 --- a/net/sunrpc/pmap_clnt.c +++ b/net/sunrpc/pmap_clnt.c | |||
@@ -90,8 +90,7 @@ bailout: | |||
90 | map->pm_binding = 0; | 90 | map->pm_binding = 0; |
91 | rpc_wake_up(&map->pm_bindwait); | 91 | rpc_wake_up(&map->pm_bindwait); |
92 | spin_unlock(&pmap_lock); | 92 | spin_unlock(&pmap_lock); |
93 | task->tk_status = -EIO; | 93 | rpc_exit(task, -EIO); |
94 | task->tk_action = NULL; | ||
95 | } | 94 | } |
96 | 95 | ||
97 | #ifdef CONFIG_ROOT_NFS | 96 | #ifdef CONFIG_ROOT_NFS |
@@ -132,21 +131,22 @@ static void | |||
132 | pmap_getport_done(struct rpc_task *task) | 131 | pmap_getport_done(struct rpc_task *task) |
133 | { | 132 | { |
134 | struct rpc_clnt *clnt = task->tk_client; | 133 | struct rpc_clnt *clnt = task->tk_client; |
134 | struct rpc_xprt *xprt = task->tk_xprt; | ||
135 | struct rpc_portmap *map = clnt->cl_pmap; | 135 | struct rpc_portmap *map = clnt->cl_pmap; |
136 | 136 | ||
137 | dprintk("RPC: %4d pmap_getport_done(status %d, port %d)\n", | 137 | dprintk("RPC: %4d pmap_getport_done(status %d, port %d)\n", |
138 | task->tk_pid, task->tk_status, clnt->cl_port); | 138 | task->tk_pid, task->tk_status, clnt->cl_port); |
139 | |||
140 | xprt->ops->set_port(xprt, 0); | ||
139 | if (task->tk_status < 0) { | 141 | if (task->tk_status < 0) { |
140 | /* Make the calling task exit with an error */ | 142 | /* Make the calling task exit with an error */ |
141 | task->tk_action = NULL; | 143 | task->tk_action = rpc_exit_task; |
142 | } else if (clnt->cl_port == 0) { | 144 | } else if (clnt->cl_port == 0) { |
143 | /* Program not registered */ | 145 | /* Program not registered */ |
144 | task->tk_status = -EACCES; | 146 | rpc_exit(task, -EACCES); |
145 | task->tk_action = NULL; | ||
146 | } else { | 147 | } else { |
147 | /* byte-swap port number first */ | 148 | xprt->ops->set_port(xprt, clnt->cl_port); |
148 | clnt->cl_port = htons(clnt->cl_port); | 149 | clnt->cl_port = htons(clnt->cl_port); |
149 | clnt->cl_xprt->addr.sin_port = clnt->cl_port; | ||
150 | } | 150 | } |
151 | spin_lock(&pmap_lock); | 151 | spin_lock(&pmap_lock); |
152 | map->pm_binding = 0; | 152 | map->pm_binding = 0; |
@@ -207,7 +207,7 @@ pmap_create(char *hostname, struct sockaddr_in *srvaddr, int proto, int privileg | |||
207 | xprt = xprt_create_proto(proto, srvaddr, NULL); | 207 | xprt = xprt_create_proto(proto, srvaddr, NULL); |
208 | if (IS_ERR(xprt)) | 208 | if (IS_ERR(xprt)) |
209 | return (struct rpc_clnt *)xprt; | 209 | return (struct rpc_clnt *)xprt; |
210 | xprt->addr.sin_port = htons(RPC_PMAP_PORT); | 210 | xprt->ops->set_port(xprt, RPC_PMAP_PORT); |
211 | if (!privileged) | 211 | if (!privileged) |
212 | xprt->resvport = 0; | 212 | xprt->resvport = 0; |
213 | 213 | ||
@@ -217,7 +217,6 @@ pmap_create(char *hostname, struct sockaddr_in *srvaddr, int proto, int privileg | |||
217 | RPC_AUTH_UNIX); | 217 | RPC_AUTH_UNIX); |
218 | if (!IS_ERR(clnt)) { | 218 | if (!IS_ERR(clnt)) { |
219 | clnt->cl_softrtry = 1; | 219 | clnt->cl_softrtry = 1; |
220 | clnt->cl_chatty = 1; | ||
221 | clnt->cl_oneshot = 1; | 220 | clnt->cl_oneshot = 1; |
222 | } | 221 | } |
223 | return clnt; | 222 | return clnt; |
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 16a2458f38f7..24cc23af9b95 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
@@ -70,8 +70,11 @@ rpc_timeout_upcall_queue(void *data) | |||
70 | struct inode *inode = &rpci->vfs_inode; | 70 | struct inode *inode = &rpci->vfs_inode; |
71 | 71 | ||
72 | down(&inode->i_sem); | 72 | down(&inode->i_sem); |
73 | if (rpci->ops == NULL) | ||
74 | goto out; | ||
73 | if (rpci->nreaders == 0 && !list_empty(&rpci->pipe)) | 75 | if (rpci->nreaders == 0 && !list_empty(&rpci->pipe)) |
74 | __rpc_purge_upcall(inode, -ETIMEDOUT); | 76 | __rpc_purge_upcall(inode, -ETIMEDOUT); |
77 | out: | ||
75 | up(&inode->i_sem); | 78 | up(&inode->i_sem); |
76 | } | 79 | } |
77 | 80 | ||
@@ -113,8 +116,6 @@ rpc_close_pipes(struct inode *inode) | |||
113 | { | 116 | { |
114 | struct rpc_inode *rpci = RPC_I(inode); | 117 | struct rpc_inode *rpci = RPC_I(inode); |
115 | 118 | ||
116 | cancel_delayed_work(&rpci->queue_timeout); | ||
117 | flush_scheduled_work(); | ||
118 | down(&inode->i_sem); | 119 | down(&inode->i_sem); |
119 | if (rpci->ops != NULL) { | 120 | if (rpci->ops != NULL) { |
120 | rpci->nreaders = 0; | 121 | rpci->nreaders = 0; |
@@ -127,6 +128,8 @@ rpc_close_pipes(struct inode *inode) | |||
127 | } | 128 | } |
128 | rpc_inode_setowner(inode, NULL); | 129 | rpc_inode_setowner(inode, NULL); |
129 | up(&inode->i_sem); | 130 | up(&inode->i_sem); |
131 | cancel_delayed_work(&rpci->queue_timeout); | ||
132 | flush_scheduled_work(); | ||
130 | } | 133 | } |
131 | 134 | ||
132 | static struct inode * | 135 | static struct inode * |
@@ -166,7 +169,7 @@ rpc_pipe_open(struct inode *inode, struct file *filp) | |||
166 | static int | 169 | static int |
167 | rpc_pipe_release(struct inode *inode, struct file *filp) | 170 | rpc_pipe_release(struct inode *inode, struct file *filp) |
168 | { | 171 | { |
169 | struct rpc_inode *rpci = RPC_I(filp->f_dentry->d_inode); | 172 | struct rpc_inode *rpci = RPC_I(inode); |
170 | struct rpc_pipe_msg *msg; | 173 | struct rpc_pipe_msg *msg; |
171 | 174 | ||
172 | down(&inode->i_sem); | 175 | down(&inode->i_sem); |
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index 54e60a657500..7415406aa1ae 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c | |||
@@ -41,8 +41,6 @@ static mempool_t *rpc_buffer_mempool __read_mostly; | |||
41 | 41 | ||
42 | static void __rpc_default_timer(struct rpc_task *task); | 42 | static void __rpc_default_timer(struct rpc_task *task); |
43 | static void rpciod_killall(void); | 43 | static void rpciod_killall(void); |
44 | static void rpc_free(struct rpc_task *task); | ||
45 | |||
46 | static void rpc_async_schedule(void *); | 44 | static void rpc_async_schedule(void *); |
47 | 45 | ||
48 | /* | 46 | /* |
@@ -264,6 +262,35 @@ void rpc_init_wait_queue(struct rpc_wait_queue *queue, const char *qname) | |||
264 | } | 262 | } |
265 | EXPORT_SYMBOL(rpc_init_wait_queue); | 263 | EXPORT_SYMBOL(rpc_init_wait_queue); |
266 | 264 | ||
265 | static int rpc_wait_bit_interruptible(void *word) | ||
266 | { | ||
267 | if (signal_pending(current)) | ||
268 | return -ERESTARTSYS; | ||
269 | schedule(); | ||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | /* | ||
274 | * Mark an RPC call as having completed by clearing the 'active' bit | ||
275 | */ | ||
276 | static inline void rpc_mark_complete_task(struct rpc_task *task) | ||
277 | { | ||
278 | rpc_clear_active(task); | ||
279 | wake_up_bit(&task->tk_runstate, RPC_TASK_ACTIVE); | ||
280 | } | ||
281 | |||
282 | /* | ||
283 | * Allow callers to wait for completion of an RPC call | ||
284 | */ | ||
285 | int __rpc_wait_for_completion_task(struct rpc_task *task, int (*action)(void *)) | ||
286 | { | ||
287 | if (action == NULL) | ||
288 | action = rpc_wait_bit_interruptible; | ||
289 | return wait_on_bit(&task->tk_runstate, RPC_TASK_ACTIVE, | ||
290 | action, TASK_INTERRUPTIBLE); | ||
291 | } | ||
292 | EXPORT_SYMBOL(__rpc_wait_for_completion_task); | ||
293 | |||
267 | /* | 294 | /* |
268 | * Make an RPC task runnable. | 295 | * Make an RPC task runnable. |
269 | * | 296 | * |
@@ -299,10 +326,7 @@ static void rpc_make_runnable(struct rpc_task *task) | |||
299 | static inline void | 326 | static inline void |
300 | rpc_schedule_run(struct rpc_task *task) | 327 | rpc_schedule_run(struct rpc_task *task) |
301 | { | 328 | { |
302 | /* Don't run a child twice! */ | 329 | rpc_set_active(task); |
303 | if (RPC_IS_ACTIVATED(task)) | ||
304 | return; | ||
305 | task->tk_active = 1; | ||
306 | rpc_make_runnable(task); | 330 | rpc_make_runnable(task); |
307 | } | 331 | } |
308 | 332 | ||
@@ -324,8 +348,7 @@ static void __rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task, | |||
324 | } | 348 | } |
325 | 349 | ||
326 | /* Mark the task as being activated if so needed */ | 350 | /* Mark the task as being activated if so needed */ |
327 | if (!RPC_IS_ACTIVATED(task)) | 351 | rpc_set_active(task); |
328 | task->tk_active = 1; | ||
329 | 352 | ||
330 | __rpc_add_wait_queue(q, task); | 353 | __rpc_add_wait_queue(q, task); |
331 | 354 | ||
@@ -555,36 +578,29 @@ __rpc_atrun(struct rpc_task *task) | |||
555 | } | 578 | } |
556 | 579 | ||
557 | /* | 580 | /* |
558 | * Helper that calls task->tk_exit if it exists and then returns | 581 | * Helper to call task->tk_ops->rpc_call_prepare |
559 | * true if we should exit __rpc_execute. | ||
560 | */ | 582 | */ |
561 | static inline int __rpc_do_exit(struct rpc_task *task) | 583 | static void rpc_prepare_task(struct rpc_task *task) |
562 | { | 584 | { |
563 | if (task->tk_exit != NULL) { | 585 | task->tk_ops->rpc_call_prepare(task, task->tk_calldata); |
564 | lock_kernel(); | ||
565 | task->tk_exit(task); | ||
566 | unlock_kernel(); | ||
567 | /* If tk_action is non-null, we should restart the call */ | ||
568 | if (task->tk_action != NULL) { | ||
569 | if (!RPC_ASSASSINATED(task)) { | ||
570 | /* Release RPC slot and buffer memory */ | ||
571 | xprt_release(task); | ||
572 | rpc_free(task); | ||
573 | return 0; | ||
574 | } | ||
575 | printk(KERN_ERR "RPC: dead task tried to walk away.\n"); | ||
576 | } | ||
577 | } | ||
578 | return 1; | ||
579 | } | 586 | } |
580 | 587 | ||
581 | static int rpc_wait_bit_interruptible(void *word) | 588 | /* |
589 | * Helper that calls task->tk_ops->rpc_call_done if it exists | ||
590 | */ | ||
591 | void rpc_exit_task(struct rpc_task *task) | ||
582 | { | 592 | { |
583 | if (signal_pending(current)) | 593 | task->tk_action = NULL; |
584 | return -ERESTARTSYS; | 594 | if (task->tk_ops->rpc_call_done != NULL) { |
585 | schedule(); | 595 | task->tk_ops->rpc_call_done(task, task->tk_calldata); |
586 | return 0; | 596 | if (task->tk_action != NULL) { |
597 | WARN_ON(RPC_ASSASSINATED(task)); | ||
598 | /* Always release the RPC slot and buffer memory */ | ||
599 | xprt_release(task); | ||
600 | } | ||
601 | } | ||
587 | } | 602 | } |
603 | EXPORT_SYMBOL(rpc_exit_task); | ||
588 | 604 | ||
589 | /* | 605 | /* |
590 | * This is the RPC `scheduler' (or rather, the finite state machine). | 606 | * This is the RPC `scheduler' (or rather, the finite state machine). |
@@ -631,12 +647,11 @@ static int __rpc_execute(struct rpc_task *task) | |||
631 | * by someone else. | 647 | * by someone else. |
632 | */ | 648 | */ |
633 | if (!RPC_IS_QUEUED(task)) { | 649 | if (!RPC_IS_QUEUED(task)) { |
634 | if (task->tk_action != NULL) { | 650 | if (task->tk_action == NULL) |
635 | lock_kernel(); | ||
636 | task->tk_action(task); | ||
637 | unlock_kernel(); | ||
638 | } else if (__rpc_do_exit(task)) | ||
639 | break; | 651 | break; |
652 | lock_kernel(); | ||
653 | task->tk_action(task); | ||
654 | unlock_kernel(); | ||
640 | } | 655 | } |
641 | 656 | ||
642 | /* | 657 | /* |
@@ -676,9 +691,9 @@ static int __rpc_execute(struct rpc_task *task) | |||
676 | dprintk("RPC: %4d sync task resuming\n", task->tk_pid); | 691 | dprintk("RPC: %4d sync task resuming\n", task->tk_pid); |
677 | } | 692 | } |
678 | 693 | ||
679 | dprintk("RPC: %4d exit() = %d\n", task->tk_pid, task->tk_status); | 694 | dprintk("RPC: %4d, return %d, status %d\n", task->tk_pid, status, task->tk_status); |
680 | status = task->tk_status; | 695 | /* Wake up anyone who is waiting for task completion */ |
681 | 696 | rpc_mark_complete_task(task); | |
682 | /* Release all resources associated with the task */ | 697 | /* Release all resources associated with the task */ |
683 | rpc_release_task(task); | 698 | rpc_release_task(task); |
684 | return status; | 699 | return status; |
@@ -696,9 +711,7 @@ static int __rpc_execute(struct rpc_task *task) | |||
696 | int | 711 | int |
697 | rpc_execute(struct rpc_task *task) | 712 | rpc_execute(struct rpc_task *task) |
698 | { | 713 | { |
699 | BUG_ON(task->tk_active); | 714 | rpc_set_active(task); |
700 | |||
701 | task->tk_active = 1; | ||
702 | rpc_set_running(task); | 715 | rpc_set_running(task); |
703 | return __rpc_execute(task); | 716 | return __rpc_execute(task); |
704 | } | 717 | } |
@@ -708,17 +721,19 @@ static void rpc_async_schedule(void *arg) | |||
708 | __rpc_execute((struct rpc_task *)arg); | 721 | __rpc_execute((struct rpc_task *)arg); |
709 | } | 722 | } |
710 | 723 | ||
711 | /* | 724 | /** |
712 | * Allocate memory for RPC purposes. | 725 | * rpc_malloc - allocate an RPC buffer |
726 | * @task: RPC task that will use this buffer | ||
727 | * @size: requested byte size | ||
713 | * | 728 | * |
714 | * We try to ensure that some NFS reads and writes can always proceed | 729 | * We try to ensure that some NFS reads and writes can always proceed |
715 | * by using a mempool when allocating 'small' buffers. | 730 | * by using a mempool when allocating 'small' buffers. |
716 | * In order to avoid memory starvation triggering more writebacks of | 731 | * In order to avoid memory starvation triggering more writebacks of |
717 | * NFS requests, we use GFP_NOFS rather than GFP_KERNEL. | 732 | * NFS requests, we use GFP_NOFS rather than GFP_KERNEL. |
718 | */ | 733 | */ |
719 | void * | 734 | void * rpc_malloc(struct rpc_task *task, size_t size) |
720 | rpc_malloc(struct rpc_task *task, size_t size) | ||
721 | { | 735 | { |
736 | struct rpc_rqst *req = task->tk_rqstp; | ||
722 | gfp_t gfp; | 737 | gfp_t gfp; |
723 | 738 | ||
724 | if (task->tk_flags & RPC_TASK_SWAPPER) | 739 | if (task->tk_flags & RPC_TASK_SWAPPER) |
@@ -727,42 +742,52 @@ rpc_malloc(struct rpc_task *task, size_t size) | |||
727 | gfp = GFP_NOFS; | 742 | gfp = GFP_NOFS; |
728 | 743 | ||
729 | if (size > RPC_BUFFER_MAXSIZE) { | 744 | if (size > RPC_BUFFER_MAXSIZE) { |
730 | task->tk_buffer = kmalloc(size, gfp); | 745 | req->rq_buffer = kmalloc(size, gfp); |
731 | if (task->tk_buffer) | 746 | if (req->rq_buffer) |
732 | task->tk_bufsize = size; | 747 | req->rq_bufsize = size; |
733 | } else { | 748 | } else { |
734 | task->tk_buffer = mempool_alloc(rpc_buffer_mempool, gfp); | 749 | req->rq_buffer = mempool_alloc(rpc_buffer_mempool, gfp); |
735 | if (task->tk_buffer) | 750 | if (req->rq_buffer) |
736 | task->tk_bufsize = RPC_BUFFER_MAXSIZE; | 751 | req->rq_bufsize = RPC_BUFFER_MAXSIZE; |
737 | } | 752 | } |
738 | return task->tk_buffer; | 753 | return req->rq_buffer; |
739 | } | 754 | } |
740 | 755 | ||
741 | static void | 756 | /** |
742 | rpc_free(struct rpc_task *task) | 757 | * rpc_free - free buffer allocated via rpc_malloc |
758 | * @task: RPC task with a buffer to be freed | ||
759 | * | ||
760 | */ | ||
761 | void rpc_free(struct rpc_task *task) | ||
743 | { | 762 | { |
744 | if (task->tk_buffer) { | 763 | struct rpc_rqst *req = task->tk_rqstp; |
745 | if (task->tk_bufsize == RPC_BUFFER_MAXSIZE) | 764 | |
746 | mempool_free(task->tk_buffer, rpc_buffer_mempool); | 765 | if (req->rq_buffer) { |
766 | if (req->rq_bufsize == RPC_BUFFER_MAXSIZE) | ||
767 | mempool_free(req->rq_buffer, rpc_buffer_mempool); | ||
747 | else | 768 | else |
748 | kfree(task->tk_buffer); | 769 | kfree(req->rq_buffer); |
749 | task->tk_buffer = NULL; | 770 | req->rq_buffer = NULL; |
750 | task->tk_bufsize = 0; | 771 | req->rq_bufsize = 0; |
751 | } | 772 | } |
752 | } | 773 | } |
753 | 774 | ||
754 | /* | 775 | /* |
755 | * Creation and deletion of RPC task structures | 776 | * Creation and deletion of RPC task structures |
756 | */ | 777 | */ |
757 | void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, rpc_action callback, int flags) | 778 | void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, int flags, const struct rpc_call_ops *tk_ops, void *calldata) |
758 | { | 779 | { |
759 | memset(task, 0, sizeof(*task)); | 780 | memset(task, 0, sizeof(*task)); |
760 | init_timer(&task->tk_timer); | 781 | init_timer(&task->tk_timer); |
761 | task->tk_timer.data = (unsigned long) task; | 782 | task->tk_timer.data = (unsigned long) task; |
762 | task->tk_timer.function = (void (*)(unsigned long)) rpc_run_timer; | 783 | task->tk_timer.function = (void (*)(unsigned long)) rpc_run_timer; |
784 | atomic_set(&task->tk_count, 1); | ||
763 | task->tk_client = clnt; | 785 | task->tk_client = clnt; |
764 | task->tk_flags = flags; | 786 | task->tk_flags = flags; |
765 | task->tk_exit = callback; | 787 | task->tk_ops = tk_ops; |
788 | if (tk_ops->rpc_call_prepare != NULL) | ||
789 | task->tk_action = rpc_prepare_task; | ||
790 | task->tk_calldata = calldata; | ||
766 | 791 | ||
767 | /* Initialize retry counters */ | 792 | /* Initialize retry counters */ |
768 | task->tk_garb_retry = 2; | 793 | task->tk_garb_retry = 2; |
@@ -791,6 +816,8 @@ void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, rpc_action call | |||
791 | list_add_tail(&task->tk_task, &all_tasks); | 816 | list_add_tail(&task->tk_task, &all_tasks); |
792 | spin_unlock(&rpc_sched_lock); | 817 | spin_unlock(&rpc_sched_lock); |
793 | 818 | ||
819 | BUG_ON(task->tk_ops == NULL); | ||
820 | |||
794 | dprintk("RPC: %4d new task procpid %d\n", task->tk_pid, | 821 | dprintk("RPC: %4d new task procpid %d\n", task->tk_pid, |
795 | current->pid); | 822 | current->pid); |
796 | } | 823 | } |
@@ -801,8 +828,7 @@ rpc_alloc_task(void) | |||
801 | return (struct rpc_task *)mempool_alloc(rpc_task_mempool, GFP_NOFS); | 828 | return (struct rpc_task *)mempool_alloc(rpc_task_mempool, GFP_NOFS); |
802 | } | 829 | } |
803 | 830 | ||
804 | static void | 831 | static void rpc_free_task(struct rpc_task *task) |
805 | rpc_default_free_task(struct rpc_task *task) | ||
806 | { | 832 | { |
807 | dprintk("RPC: %4d freeing task\n", task->tk_pid); | 833 | dprintk("RPC: %4d freeing task\n", task->tk_pid); |
808 | mempool_free(task, rpc_task_mempool); | 834 | mempool_free(task, rpc_task_mempool); |
@@ -813,8 +839,7 @@ rpc_default_free_task(struct rpc_task *task) | |||
813 | * clean up after an allocation failure, as the client may | 839 | * clean up after an allocation failure, as the client may |
814 | * have specified "oneshot". | 840 | * have specified "oneshot". |
815 | */ | 841 | */ |
816 | struct rpc_task * | 842 | struct rpc_task *rpc_new_task(struct rpc_clnt *clnt, int flags, const struct rpc_call_ops *tk_ops, void *calldata) |
817 | rpc_new_task(struct rpc_clnt *clnt, rpc_action callback, int flags) | ||
818 | { | 843 | { |
819 | struct rpc_task *task; | 844 | struct rpc_task *task; |
820 | 845 | ||
@@ -822,10 +847,7 @@ rpc_new_task(struct rpc_clnt *clnt, rpc_action callback, int flags) | |||
822 | if (!task) | 847 | if (!task) |
823 | goto cleanup; | 848 | goto cleanup; |
824 | 849 | ||
825 | rpc_init_task(task, clnt, callback, flags); | 850 | rpc_init_task(task, clnt, flags, tk_ops, calldata); |
826 | |||
827 | /* Replace tk_release */ | ||
828 | task->tk_release = rpc_default_free_task; | ||
829 | 851 | ||
830 | dprintk("RPC: %4d allocated task\n", task->tk_pid); | 852 | dprintk("RPC: %4d allocated task\n", task->tk_pid); |
831 | task->tk_flags |= RPC_TASK_DYNAMIC; | 853 | task->tk_flags |= RPC_TASK_DYNAMIC; |
@@ -845,11 +867,15 @@ cleanup: | |||
845 | 867 | ||
846 | void rpc_release_task(struct rpc_task *task) | 868 | void rpc_release_task(struct rpc_task *task) |
847 | { | 869 | { |
848 | dprintk("RPC: %4d release task\n", task->tk_pid); | 870 | const struct rpc_call_ops *tk_ops = task->tk_ops; |
871 | void *calldata = task->tk_calldata; | ||
849 | 872 | ||
850 | #ifdef RPC_DEBUG | 873 | #ifdef RPC_DEBUG |
851 | BUG_ON(task->tk_magic != RPC_TASK_MAGIC_ID); | 874 | BUG_ON(task->tk_magic != RPC_TASK_MAGIC_ID); |
852 | #endif | 875 | #endif |
876 | if (!atomic_dec_and_test(&task->tk_count)) | ||
877 | return; | ||
878 | dprintk("RPC: %4d release task\n", task->tk_pid); | ||
853 | 879 | ||
854 | /* Remove from global task list */ | 880 | /* Remove from global task list */ |
855 | spin_lock(&rpc_sched_lock); | 881 | spin_lock(&rpc_sched_lock); |
@@ -857,7 +883,6 @@ void rpc_release_task(struct rpc_task *task) | |||
857 | spin_unlock(&rpc_sched_lock); | 883 | spin_unlock(&rpc_sched_lock); |
858 | 884 | ||
859 | BUG_ON (RPC_IS_QUEUED(task)); | 885 | BUG_ON (RPC_IS_QUEUED(task)); |
860 | task->tk_active = 0; | ||
861 | 886 | ||
862 | /* Synchronously delete any running timer */ | 887 | /* Synchronously delete any running timer */ |
863 | rpc_delete_timer(task); | 888 | rpc_delete_timer(task); |
@@ -867,7 +892,6 @@ void rpc_release_task(struct rpc_task *task) | |||
867 | xprt_release(task); | 892 | xprt_release(task); |
868 | if (task->tk_msg.rpc_cred) | 893 | if (task->tk_msg.rpc_cred) |
869 | rpcauth_unbindcred(task); | 894 | rpcauth_unbindcred(task); |
870 | rpc_free(task); | ||
871 | if (task->tk_client) { | 895 | if (task->tk_client) { |
872 | rpc_release_client(task->tk_client); | 896 | rpc_release_client(task->tk_client); |
873 | task->tk_client = NULL; | 897 | task->tk_client = NULL; |
@@ -876,11 +900,34 @@ void rpc_release_task(struct rpc_task *task) | |||
876 | #ifdef RPC_DEBUG | 900 | #ifdef RPC_DEBUG |
877 | task->tk_magic = 0; | 901 | task->tk_magic = 0; |
878 | #endif | 902 | #endif |
879 | if (task->tk_release) | 903 | if (task->tk_flags & RPC_TASK_DYNAMIC) |
880 | task->tk_release(task); | 904 | rpc_free_task(task); |
905 | if (tk_ops->rpc_release) | ||
906 | tk_ops->rpc_release(calldata); | ||
881 | } | 907 | } |
882 | 908 | ||
883 | /** | 909 | /** |
910 | * rpc_run_task - Allocate a new RPC task, then run rpc_execute against it | ||
911 | * @clnt - pointer to RPC client | ||
912 | * @flags - RPC flags | ||
913 | * @ops - RPC call ops | ||
914 | * @data - user call data | ||
915 | */ | ||
916 | struct rpc_task *rpc_run_task(struct rpc_clnt *clnt, int flags, | ||
917 | const struct rpc_call_ops *ops, | ||
918 | void *data) | ||
919 | { | ||
920 | struct rpc_task *task; | ||
921 | task = rpc_new_task(clnt, flags, ops, data); | ||
922 | if (task == NULL) | ||
923 | return ERR_PTR(-ENOMEM); | ||
924 | atomic_inc(&task->tk_count); | ||
925 | rpc_execute(task); | ||
926 | return task; | ||
927 | } | ||
928 | EXPORT_SYMBOL(rpc_run_task); | ||
929 | |||
930 | /** | ||
884 | * rpc_find_parent - find the parent of a child task. | 931 | * rpc_find_parent - find the parent of a child task. |
885 | * @child: child task | 932 | * @child: child task |
886 | * | 933 | * |
@@ -890,12 +937,11 @@ void rpc_release_task(struct rpc_task *task) | |||
890 | * | 937 | * |
891 | * Caller must hold childq.lock | 938 | * Caller must hold childq.lock |
892 | */ | 939 | */ |
893 | static inline struct rpc_task *rpc_find_parent(struct rpc_task *child) | 940 | static inline struct rpc_task *rpc_find_parent(struct rpc_task *child, struct rpc_task *parent) |
894 | { | 941 | { |
895 | struct rpc_task *task, *parent; | 942 | struct rpc_task *task; |
896 | struct list_head *le; | 943 | struct list_head *le; |
897 | 944 | ||
898 | parent = (struct rpc_task *) child->tk_calldata; | ||
899 | task_for_each(task, le, &childq.tasks[0]) | 945 | task_for_each(task, le, &childq.tasks[0]) |
900 | if (task == parent) | 946 | if (task == parent) |
901 | return parent; | 947 | return parent; |
@@ -903,18 +949,22 @@ static inline struct rpc_task *rpc_find_parent(struct rpc_task *child) | |||
903 | return NULL; | 949 | return NULL; |
904 | } | 950 | } |
905 | 951 | ||
906 | static void rpc_child_exit(struct rpc_task *child) | 952 | static void rpc_child_exit(struct rpc_task *child, void *calldata) |
907 | { | 953 | { |
908 | struct rpc_task *parent; | 954 | struct rpc_task *parent; |
909 | 955 | ||
910 | spin_lock_bh(&childq.lock); | 956 | spin_lock_bh(&childq.lock); |
911 | if ((parent = rpc_find_parent(child)) != NULL) { | 957 | if ((parent = rpc_find_parent(child, calldata)) != NULL) { |
912 | parent->tk_status = child->tk_status; | 958 | parent->tk_status = child->tk_status; |
913 | __rpc_wake_up_task(parent); | 959 | __rpc_wake_up_task(parent); |
914 | } | 960 | } |
915 | spin_unlock_bh(&childq.lock); | 961 | spin_unlock_bh(&childq.lock); |
916 | } | 962 | } |
917 | 963 | ||
964 | static const struct rpc_call_ops rpc_child_ops = { | ||
965 | .rpc_call_done = rpc_child_exit, | ||
966 | }; | ||
967 | |||
918 | /* | 968 | /* |
919 | * Note: rpc_new_task releases the client after a failure. | 969 | * Note: rpc_new_task releases the client after a failure. |
920 | */ | 970 | */ |
@@ -923,11 +973,9 @@ rpc_new_child(struct rpc_clnt *clnt, struct rpc_task *parent) | |||
923 | { | 973 | { |
924 | struct rpc_task *task; | 974 | struct rpc_task *task; |
925 | 975 | ||
926 | task = rpc_new_task(clnt, NULL, RPC_TASK_ASYNC | RPC_TASK_CHILD); | 976 | task = rpc_new_task(clnt, RPC_TASK_ASYNC | RPC_TASK_CHILD, &rpc_child_ops, parent); |
927 | if (!task) | 977 | if (!task) |
928 | goto fail; | 978 | goto fail; |
929 | task->tk_exit = rpc_child_exit; | ||
930 | task->tk_calldata = parent; | ||
931 | return task; | 979 | return task; |
932 | 980 | ||
933 | fail: | 981 | fail: |
@@ -1063,7 +1111,7 @@ void rpc_show_tasks(void) | |||
1063 | return; | 1111 | return; |
1064 | } | 1112 | } |
1065 | printk("-pid- proc flgs status -client- -prog- --rqstp- -timeout " | 1113 | printk("-pid- proc flgs status -client- -prog- --rqstp- -timeout " |
1066 | "-rpcwait -action- --exit--\n"); | 1114 | "-rpcwait -action- ---ops--\n"); |
1067 | alltask_for_each(t, le, &all_tasks) { | 1115 | alltask_for_each(t, le, &all_tasks) { |
1068 | const char *rpc_waitq = "none"; | 1116 | const char *rpc_waitq = "none"; |
1069 | 1117 | ||
@@ -1078,7 +1126,7 @@ void rpc_show_tasks(void) | |||
1078 | (t->tk_client ? t->tk_client->cl_prog : 0), | 1126 | (t->tk_client ? t->tk_client->cl_prog : 0), |
1079 | t->tk_rqstp, t->tk_timeout, | 1127 | t->tk_rqstp, t->tk_timeout, |
1080 | rpc_waitq, | 1128 | rpc_waitq, |
1081 | t->tk_action, t->tk_exit); | 1129 | t->tk_action, t->tk_ops); |
1082 | } | 1130 | } |
1083 | spin_unlock(&rpc_sched_lock); | 1131 | spin_unlock(&rpc_sched_lock); |
1084 | } | 1132 | } |
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c index a03d4b600c92..9f7373203592 100644 --- a/net/sunrpc/sunrpc_syms.c +++ b/net/sunrpc/sunrpc_syms.c | |||
@@ -30,8 +30,6 @@ EXPORT_SYMBOL(rpc_init_task); | |||
30 | EXPORT_SYMBOL(rpc_sleep_on); | 30 | EXPORT_SYMBOL(rpc_sleep_on); |
31 | EXPORT_SYMBOL(rpc_wake_up_next); | 31 | EXPORT_SYMBOL(rpc_wake_up_next); |
32 | EXPORT_SYMBOL(rpc_wake_up_task); | 32 | EXPORT_SYMBOL(rpc_wake_up_task); |
33 | EXPORT_SYMBOL(rpc_new_child); | ||
34 | EXPORT_SYMBOL(rpc_run_child); | ||
35 | EXPORT_SYMBOL(rpciod_down); | 33 | EXPORT_SYMBOL(rpciod_down); |
36 | EXPORT_SYMBOL(rpciod_up); | 34 | EXPORT_SYMBOL(rpciod_up); |
37 | EXPORT_SYMBOL(rpc_new_task); | 35 | EXPORT_SYMBOL(rpc_new_task); |
@@ -45,7 +43,6 @@ EXPORT_SYMBOL(rpc_clone_client); | |||
45 | EXPORT_SYMBOL(rpc_bind_new_program); | 43 | EXPORT_SYMBOL(rpc_bind_new_program); |
46 | EXPORT_SYMBOL(rpc_destroy_client); | 44 | EXPORT_SYMBOL(rpc_destroy_client); |
47 | EXPORT_SYMBOL(rpc_shutdown_client); | 45 | EXPORT_SYMBOL(rpc_shutdown_client); |
48 | EXPORT_SYMBOL(rpc_release_client); | ||
49 | EXPORT_SYMBOL(rpc_killall_tasks); | 46 | EXPORT_SYMBOL(rpc_killall_tasks); |
50 | EXPORT_SYMBOL(rpc_call_sync); | 47 | EXPORT_SYMBOL(rpc_call_sync); |
51 | EXPORT_SYMBOL(rpc_call_async); | 48 | EXPORT_SYMBOL(rpc_call_async); |
@@ -120,7 +117,6 @@ EXPORT_SYMBOL(unix_domain_find); | |||
120 | 117 | ||
121 | /* Generic XDR */ | 118 | /* Generic XDR */ |
122 | EXPORT_SYMBOL(xdr_encode_string); | 119 | EXPORT_SYMBOL(xdr_encode_string); |
123 | EXPORT_SYMBOL(xdr_decode_string); | ||
124 | EXPORT_SYMBOL(xdr_decode_string_inplace); | 120 | EXPORT_SYMBOL(xdr_decode_string_inplace); |
125 | EXPORT_SYMBOL(xdr_decode_netobj); | 121 | EXPORT_SYMBOL(xdr_decode_netobj); |
126 | EXPORT_SYMBOL(xdr_encode_netobj); | 122 | EXPORT_SYMBOL(xdr_encode_netobj); |
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index aaf08cdd19f0..ca4bfa57e116 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c | |||
@@ -93,27 +93,6 @@ xdr_encode_string(u32 *p, const char *string) | |||
93 | } | 93 | } |
94 | 94 | ||
95 | u32 * | 95 | u32 * |
96 | xdr_decode_string(u32 *p, char **sp, int *lenp, int maxlen) | ||
97 | { | ||
98 | unsigned int len; | ||
99 | char *string; | ||
100 | |||
101 | if ((len = ntohl(*p++)) > maxlen) | ||
102 | return NULL; | ||
103 | if (lenp) | ||
104 | *lenp = len; | ||
105 | if ((len % 4) != 0) { | ||
106 | string = (char *) p; | ||
107 | } else { | ||
108 | string = (char *) (p - 1); | ||
109 | memmove(string, p, len); | ||
110 | } | ||
111 | string[len] = '\0'; | ||
112 | *sp = string; | ||
113 | return p + XDR_QUADLEN(len); | ||
114 | } | ||
115 | |||
116 | u32 * | ||
117 | xdr_decode_string_inplace(u32 *p, char **sp, int *lenp, int maxlen) | 96 | xdr_decode_string_inplace(u32 *p, char **sp, int *lenp, int maxlen) |
118 | { | 97 | { |
119 | unsigned int len; | 98 | unsigned int len; |
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 6dda3860351f..8ff2c8acb223 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c | |||
@@ -119,6 +119,17 @@ out_sleep: | |||
119 | return 0; | 119 | return 0; |
120 | } | 120 | } |
121 | 121 | ||
122 | static void xprt_clear_locked(struct rpc_xprt *xprt) | ||
123 | { | ||
124 | xprt->snd_task = NULL; | ||
125 | if (!test_bit(XPRT_CLOSE_WAIT, &xprt->state) || xprt->shutdown) { | ||
126 | smp_mb__before_clear_bit(); | ||
127 | clear_bit(XPRT_LOCKED, &xprt->state); | ||
128 | smp_mb__after_clear_bit(); | ||
129 | } else | ||
130 | schedule_work(&xprt->task_cleanup); | ||
131 | } | ||
132 | |||
122 | /* | 133 | /* |
123 | * xprt_reserve_xprt_cong - serialize write access to transports | 134 | * xprt_reserve_xprt_cong - serialize write access to transports |
124 | * @task: task that is requesting access to the transport | 135 | * @task: task that is requesting access to the transport |
@@ -145,9 +156,7 @@ int xprt_reserve_xprt_cong(struct rpc_task *task) | |||
145 | } | 156 | } |
146 | return 1; | 157 | return 1; |
147 | } | 158 | } |
148 | smp_mb__before_clear_bit(); | 159 | xprt_clear_locked(xprt); |
149 | clear_bit(XPRT_LOCKED, &xprt->state); | ||
150 | smp_mb__after_clear_bit(); | ||
151 | out_sleep: | 160 | out_sleep: |
152 | dprintk("RPC: %4d failed to lock transport %p\n", task->tk_pid, xprt); | 161 | dprintk("RPC: %4d failed to lock transport %p\n", task->tk_pid, xprt); |
153 | task->tk_timeout = 0; | 162 | task->tk_timeout = 0; |
@@ -193,9 +202,7 @@ static void __xprt_lock_write_next(struct rpc_xprt *xprt) | |||
193 | return; | 202 | return; |
194 | 203 | ||
195 | out_unlock: | 204 | out_unlock: |
196 | smp_mb__before_clear_bit(); | 205 | xprt_clear_locked(xprt); |
197 | clear_bit(XPRT_LOCKED, &xprt->state); | ||
198 | smp_mb__after_clear_bit(); | ||
199 | } | 206 | } |
200 | 207 | ||
201 | static void __xprt_lock_write_next_cong(struct rpc_xprt *xprt) | 208 | static void __xprt_lock_write_next_cong(struct rpc_xprt *xprt) |
@@ -222,9 +229,7 @@ static void __xprt_lock_write_next_cong(struct rpc_xprt *xprt) | |||
222 | return; | 229 | return; |
223 | } | 230 | } |
224 | out_unlock: | 231 | out_unlock: |
225 | smp_mb__before_clear_bit(); | 232 | xprt_clear_locked(xprt); |
226 | clear_bit(XPRT_LOCKED, &xprt->state); | ||
227 | smp_mb__after_clear_bit(); | ||
228 | } | 233 | } |
229 | 234 | ||
230 | /** | 235 | /** |
@@ -237,10 +242,7 @@ out_unlock: | |||
237 | void xprt_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task) | 242 | void xprt_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task) |
238 | { | 243 | { |
239 | if (xprt->snd_task == task) { | 244 | if (xprt->snd_task == task) { |
240 | xprt->snd_task = NULL; | 245 | xprt_clear_locked(xprt); |
241 | smp_mb__before_clear_bit(); | ||
242 | clear_bit(XPRT_LOCKED, &xprt->state); | ||
243 | smp_mb__after_clear_bit(); | ||
244 | __xprt_lock_write_next(xprt); | 246 | __xprt_lock_write_next(xprt); |
245 | } | 247 | } |
246 | } | 248 | } |
@@ -256,10 +258,7 @@ void xprt_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task) | |||
256 | void xprt_release_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task) | 258 | void xprt_release_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task) |
257 | { | 259 | { |
258 | if (xprt->snd_task == task) { | 260 | if (xprt->snd_task == task) { |
259 | xprt->snd_task = NULL; | 261 | xprt_clear_locked(xprt); |
260 | smp_mb__before_clear_bit(); | ||
261 | clear_bit(XPRT_LOCKED, &xprt->state); | ||
262 | smp_mb__after_clear_bit(); | ||
263 | __xprt_lock_write_next_cong(xprt); | 262 | __xprt_lock_write_next_cong(xprt); |
264 | } | 263 | } |
265 | } | 264 | } |
@@ -535,10 +534,6 @@ void xprt_connect(struct rpc_task *task) | |||
535 | dprintk("RPC: %4d xprt_connect xprt %p %s connected\n", task->tk_pid, | 534 | dprintk("RPC: %4d xprt_connect xprt %p %s connected\n", task->tk_pid, |
536 | xprt, (xprt_connected(xprt) ? "is" : "is not")); | 535 | xprt, (xprt_connected(xprt) ? "is" : "is not")); |
537 | 536 | ||
538 | if (xprt->shutdown) { | ||
539 | task->tk_status = -EIO; | ||
540 | return; | ||
541 | } | ||
542 | if (!xprt->addr.sin_port) { | 537 | if (!xprt->addr.sin_port) { |
543 | task->tk_status = -EIO; | 538 | task->tk_status = -EIO; |
544 | return; | 539 | return; |
@@ -687,9 +682,6 @@ int xprt_prepare_transmit(struct rpc_task *task) | |||
687 | 682 | ||
688 | dprintk("RPC: %4d xprt_prepare_transmit\n", task->tk_pid); | 683 | dprintk("RPC: %4d xprt_prepare_transmit\n", task->tk_pid); |
689 | 684 | ||
690 | if (xprt->shutdown) | ||
691 | return -EIO; | ||
692 | |||
693 | spin_lock_bh(&xprt->transport_lock); | 685 | spin_lock_bh(&xprt->transport_lock); |
694 | if (req->rq_received && !req->rq_bytes_sent) { | 686 | if (req->rq_received && !req->rq_bytes_sent) { |
695 | err = req->rq_received; | 687 | err = req->rq_received; |
@@ -814,11 +806,9 @@ void xprt_reserve(struct rpc_task *task) | |||
814 | struct rpc_xprt *xprt = task->tk_xprt; | 806 | struct rpc_xprt *xprt = task->tk_xprt; |
815 | 807 | ||
816 | task->tk_status = -EIO; | 808 | task->tk_status = -EIO; |
817 | if (!xprt->shutdown) { | 809 | spin_lock(&xprt->reserve_lock); |
818 | spin_lock(&xprt->reserve_lock); | 810 | do_xprt_reserve(task); |
819 | do_xprt_reserve(task); | 811 | spin_unlock(&xprt->reserve_lock); |
820 | spin_unlock(&xprt->reserve_lock); | ||
821 | } | ||
822 | } | 812 | } |
823 | 813 | ||
824 | static inline u32 xprt_alloc_xid(struct rpc_xprt *xprt) | 814 | static inline u32 xprt_alloc_xid(struct rpc_xprt *xprt) |
@@ -838,6 +828,8 @@ static void xprt_request_init(struct rpc_task *task, struct rpc_xprt *xprt) | |||
838 | req->rq_timeout = xprt->timeout.to_initval; | 828 | req->rq_timeout = xprt->timeout.to_initval; |
839 | req->rq_task = task; | 829 | req->rq_task = task; |
840 | req->rq_xprt = xprt; | 830 | req->rq_xprt = xprt; |
831 | req->rq_buffer = NULL; | ||
832 | req->rq_bufsize = 0; | ||
841 | req->rq_xid = xprt_alloc_xid(xprt); | 833 | req->rq_xid = xprt_alloc_xid(xprt); |
842 | req->rq_release_snd_buf = NULL; | 834 | req->rq_release_snd_buf = NULL; |
843 | dprintk("RPC: %4d reserved req %p xid %08x\n", task->tk_pid, | 835 | dprintk("RPC: %4d reserved req %p xid %08x\n", task->tk_pid, |
@@ -863,10 +855,11 @@ void xprt_release(struct rpc_task *task) | |||
863 | if (!list_empty(&req->rq_list)) | 855 | if (!list_empty(&req->rq_list)) |
864 | list_del(&req->rq_list); | 856 | list_del(&req->rq_list); |
865 | xprt->last_used = jiffies; | 857 | xprt->last_used = jiffies; |
866 | if (list_empty(&xprt->recv) && !xprt->shutdown) | 858 | if (list_empty(&xprt->recv)) |
867 | mod_timer(&xprt->timer, | 859 | mod_timer(&xprt->timer, |
868 | xprt->last_used + xprt->idle_timeout); | 860 | xprt->last_used + xprt->idle_timeout); |
869 | spin_unlock_bh(&xprt->transport_lock); | 861 | spin_unlock_bh(&xprt->transport_lock); |
862 | xprt->ops->buf_free(task); | ||
870 | task->tk_rqstp = NULL; | 863 | task->tk_rqstp = NULL; |
871 | if (req->rq_release_snd_buf) | 864 | if (req->rq_release_snd_buf) |
872 | req->rq_release_snd_buf(req); | 865 | req->rq_release_snd_buf(req); |
@@ -974,16 +967,6 @@ struct rpc_xprt *xprt_create_proto(int proto, struct sockaddr_in *sap, struct rp | |||
974 | return xprt; | 967 | return xprt; |
975 | } | 968 | } |
976 | 969 | ||
977 | static void xprt_shutdown(struct rpc_xprt *xprt) | ||
978 | { | ||
979 | xprt->shutdown = 1; | ||
980 | rpc_wake_up(&xprt->sending); | ||
981 | rpc_wake_up(&xprt->resend); | ||
982 | xprt_wake_pending_tasks(xprt, -EIO); | ||
983 | rpc_wake_up(&xprt->backlog); | ||
984 | del_timer_sync(&xprt->timer); | ||
985 | } | ||
986 | |||
987 | /** | 970 | /** |
988 | * xprt_destroy - destroy an RPC transport, killing off all requests. | 971 | * xprt_destroy - destroy an RPC transport, killing off all requests. |
989 | * @xprt: transport to destroy | 972 | * @xprt: transport to destroy |
@@ -992,7 +975,8 @@ static void xprt_shutdown(struct rpc_xprt *xprt) | |||
992 | int xprt_destroy(struct rpc_xprt *xprt) | 975 | int xprt_destroy(struct rpc_xprt *xprt) |
993 | { | 976 | { |
994 | dprintk("RPC: destroying transport %p\n", xprt); | 977 | dprintk("RPC: destroying transport %p\n", xprt); |
995 | xprt_shutdown(xprt); | 978 | xprt->shutdown = 1; |
979 | del_timer_sync(&xprt->timer); | ||
996 | xprt->ops->destroy(xprt); | 980 | xprt->ops->destroy(xprt); |
997 | kfree(xprt); | 981 | kfree(xprt); |
998 | 982 | ||
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 77e8800d4127..c458f8d1d6d1 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/udp.h> | 28 | #include <linux/udp.h> |
29 | #include <linux/tcp.h> | 29 | #include <linux/tcp.h> |
30 | #include <linux/sunrpc/clnt.h> | 30 | #include <linux/sunrpc/clnt.h> |
31 | #include <linux/sunrpc/sched.h> | ||
31 | #include <linux/file.h> | 32 | #include <linux/file.h> |
32 | 33 | ||
33 | #include <net/sock.h> | 34 | #include <net/sock.h> |
@@ -424,7 +425,7 @@ static void xs_close(struct rpc_xprt *xprt) | |||
424 | struct sock *sk = xprt->inet; | 425 | struct sock *sk = xprt->inet; |
425 | 426 | ||
426 | if (!sk) | 427 | if (!sk) |
427 | return; | 428 | goto clear_close_wait; |
428 | 429 | ||
429 | dprintk("RPC: xs_close xprt %p\n", xprt); | 430 | dprintk("RPC: xs_close xprt %p\n", xprt); |
430 | 431 | ||
@@ -441,6 +442,10 @@ static void xs_close(struct rpc_xprt *xprt) | |||
441 | sk->sk_no_check = 0; | 442 | sk->sk_no_check = 0; |
442 | 443 | ||
443 | sock_release(sock); | 444 | sock_release(sock); |
445 | clear_close_wait: | ||
446 | smp_mb__before_clear_bit(); | ||
447 | clear_bit(XPRT_CLOSE_WAIT, &xprt->state); | ||
448 | smp_mb__after_clear_bit(); | ||
444 | } | 449 | } |
445 | 450 | ||
446 | /** | 451 | /** |
@@ -800,9 +805,13 @@ static void xs_tcp_state_change(struct sock *sk) | |||
800 | case TCP_SYN_SENT: | 805 | case TCP_SYN_SENT: |
801 | case TCP_SYN_RECV: | 806 | case TCP_SYN_RECV: |
802 | break; | 807 | break; |
808 | case TCP_CLOSE_WAIT: | ||
809 | /* Try to schedule an autoclose RPC calls */ | ||
810 | set_bit(XPRT_CLOSE_WAIT, &xprt->state); | ||
811 | if (test_and_set_bit(XPRT_LOCKED, &xprt->state) == 0) | ||
812 | schedule_work(&xprt->task_cleanup); | ||
803 | default: | 813 | default: |
804 | xprt_disconnect(xprt); | 814 | xprt_disconnect(xprt); |
805 | break; | ||
806 | } | 815 | } |
807 | out: | 816 | out: |
808 | read_unlock(&sk->sk_callback_lock); | 817 | read_unlock(&sk->sk_callback_lock); |
@@ -920,6 +929,18 @@ static void xs_udp_timer(struct rpc_task *task) | |||
920 | xprt_adjust_cwnd(task, -ETIMEDOUT); | 929 | xprt_adjust_cwnd(task, -ETIMEDOUT); |
921 | } | 930 | } |
922 | 931 | ||
932 | /** | ||
933 | * xs_set_port - reset the port number in the remote endpoint address | ||
934 | * @xprt: generic transport | ||
935 | * @port: new port number | ||
936 | * | ||
937 | */ | ||
938 | static void xs_set_port(struct rpc_xprt *xprt, unsigned short port) | ||
939 | { | ||
940 | dprintk("RPC: setting port for xprt %p to %u\n", xprt, port); | ||
941 | xprt->addr.sin_port = htons(port); | ||
942 | } | ||
943 | |||
923 | static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock) | 944 | static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock) |
924 | { | 945 | { |
925 | struct sockaddr_in myaddr = { | 946 | struct sockaddr_in myaddr = { |
@@ -1160,7 +1181,10 @@ static struct rpc_xprt_ops xs_udp_ops = { | |||
1160 | .set_buffer_size = xs_udp_set_buffer_size, | 1181 | .set_buffer_size = xs_udp_set_buffer_size, |
1161 | .reserve_xprt = xprt_reserve_xprt_cong, | 1182 | .reserve_xprt = xprt_reserve_xprt_cong, |
1162 | .release_xprt = xprt_release_xprt_cong, | 1183 | .release_xprt = xprt_release_xprt_cong, |
1184 | .set_port = xs_set_port, | ||
1163 | .connect = xs_connect, | 1185 | .connect = xs_connect, |
1186 | .buf_alloc = rpc_malloc, | ||
1187 | .buf_free = rpc_free, | ||
1164 | .send_request = xs_udp_send_request, | 1188 | .send_request = xs_udp_send_request, |
1165 | .set_retrans_timeout = xprt_set_retrans_timeout_rtt, | 1189 | .set_retrans_timeout = xprt_set_retrans_timeout_rtt, |
1166 | .timer = xs_udp_timer, | 1190 | .timer = xs_udp_timer, |
@@ -1172,7 +1196,10 @@ static struct rpc_xprt_ops xs_udp_ops = { | |||
1172 | static struct rpc_xprt_ops xs_tcp_ops = { | 1196 | static struct rpc_xprt_ops xs_tcp_ops = { |
1173 | .reserve_xprt = xprt_reserve_xprt, | 1197 | .reserve_xprt = xprt_reserve_xprt, |
1174 | .release_xprt = xprt_release_xprt, | 1198 | .release_xprt = xprt_release_xprt, |
1199 | .set_port = xs_set_port, | ||
1175 | .connect = xs_connect, | 1200 | .connect = xs_connect, |
1201 | .buf_alloc = rpc_malloc, | ||
1202 | .buf_free = rpc_free, | ||
1176 | .send_request = xs_tcp_send_request, | 1203 | .send_request = xs_tcp_send_request, |
1177 | .set_retrans_timeout = xprt_set_retrans_timeout_def, | 1204 | .set_retrans_timeout = xprt_set_retrans_timeout_def, |
1178 | .close = xs_close, | 1205 | .close = xs_close, |
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index 16459c7f54b2..bfabaf9cba87 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c | |||
@@ -540,12 +540,7 @@ static struct sock *x25_make_new(struct sock *osk) | |||
540 | sk->sk_state = TCP_ESTABLISHED; | 540 | sk->sk_state = TCP_ESTABLISHED; |
541 | sk->sk_sleep = osk->sk_sleep; | 541 | sk->sk_sleep = osk->sk_sleep; |
542 | sk->sk_backlog_rcv = osk->sk_backlog_rcv; | 542 | sk->sk_backlog_rcv = osk->sk_backlog_rcv; |
543 | 543 | sock_copy_flags(sk, osk); | |
544 | if (sock_flag(osk, SOCK_ZAPPED)) | ||
545 | sock_set_flag(sk, SOCK_ZAPPED); | ||
546 | |||
547 | if (sock_flag(osk, SOCK_DBG)) | ||
548 | sock_set_flag(sk, SOCK_DBG); | ||
549 | 544 | ||
550 | ox25 = x25_sk(osk); | 545 | ox25 = x25_sk(osk); |
551 | x25->t21 = ox25->t21; | 546 | x25->t21 = ox25->t21; |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 92e2b804c606..ac87a09ba83e 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -802,6 +802,7 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr | |||
802 | excl = nlh->nlmsg_type == XFRM_MSG_NEWPOLICY; | 802 | excl = nlh->nlmsg_type == XFRM_MSG_NEWPOLICY; |
803 | err = xfrm_policy_insert(p->dir, xp, excl); | 803 | err = xfrm_policy_insert(p->dir, xp, excl); |
804 | if (err) { | 804 | if (err) { |
805 | security_xfrm_policy_free(xp); | ||
805 | kfree(xp); | 806 | kfree(xp); |
806 | return err; | 807 | return err; |
807 | } | 808 | } |
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 3d7f1ac9e00c..5760e057ecba 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile | |||
@@ -133,8 +133,8 @@ HOSTCFLAGS_zconf.tab.o := -I$(src) | |||
133 | HOSTLOADLIBES_qconf = $(KC_QT_LIBS) -ldl | 133 | HOSTLOADLIBES_qconf = $(KC_QT_LIBS) -ldl |
134 | HOSTCXXFLAGS_qconf.o = $(KC_QT_CFLAGS) -D LKC_DIRECT_LINK | 134 | HOSTCXXFLAGS_qconf.o = $(KC_QT_CFLAGS) -D LKC_DIRECT_LINK |
135 | 135 | ||
136 | HOSTLOADLIBES_gconf = `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --libs` | 136 | HOSTLOADLIBES_gconf = `pkg-config --libs gtk+-2.0 gmodule-2.0 libglade-2.0` |
137 | HOSTCFLAGS_gconf.o = `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --cflags` \ | 137 | HOSTCFLAGS_gconf.o = `pkg-config --cflags gtk+-2.0 gmodule-2.0 libglade-2.0` \ |
138 | -D LKC_DIRECT_LINK | 138 | -D LKC_DIRECT_LINK |
139 | 139 | ||
140 | $(obj)/qconf.o: $(obj)/.tmp_qtcheck | 140 | $(obj)/qconf.o: $(obj)/.tmp_qtcheck |
@@ -193,8 +193,8 @@ ifeq ($(gconf-target),1) | |||
193 | 193 | ||
194 | # GTK needs some extra effort, too... | 194 | # GTK needs some extra effort, too... |
195 | $(obj)/.tmp_gtkcheck: | 195 | $(obj)/.tmp_gtkcheck: |
196 | @if `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --exists`; then \ | 196 | @if `pkg-config --exists gtk+-2.0 gmodule-2.0 libglade-2.0`; then \ |
197 | if `pkg-config gtk+-2.0 --atleast-version=2.0.0`; then \ | 197 | if `pkg-config --atleast-version=2.0.0 gtk+-2.0`; then \ |
198 | touch $@; \ | 198 | touch $@; \ |
199 | else \ | 199 | else \ |
200 | echo "*"; \ | 200 | echo "*"; \ |
diff --git a/scripts/setlocalversion b/scripts/setlocalversion index 7c805c8fccd2..f54dac88cfd1 100644 --- a/scripts/setlocalversion +++ b/scripts/setlocalversion | |||
@@ -1,56 +1,22 @@ | |||
1 | #!/usr/bin/perl | 1 | #!/bin/sh |
2 | # Copyright 2004 - Ryan Anderson <ryan@michonline.com> GPL v2 | 2 | # Print additional version information for non-release trees. |
3 | 3 | ||
4 | use strict; | 4 | usage() { |
5 | use warnings; | 5 | echo "Usage: $0 [srctree]" >&2 |
6 | use Digest::MD5; | 6 | exit 1 |
7 | require 5.006; | ||
8 | |||
9 | if (@ARGV != 1) { | ||
10 | print <<EOT; | ||
11 | Usage: setlocalversion <srctree> | ||
12 | EOT | ||
13 | exit(1); | ||
14 | } | 7 | } |
15 | 8 | ||
16 | my ($srctree) = @ARGV; | 9 | cd "${1:-.}" || usage |
17 | chdir($srctree); | ||
18 | |||
19 | my @LOCALVERSIONS = (); | ||
20 | |||
21 | # We are going to use the following commands to try and determine if this | ||
22 | # repository is at a Version boundary (i.e, 2.6.10 vs 2.6.10 + some patches) We | ||
23 | # currently assume that all meaningful version boundaries are marked by a tag. | ||
24 | # We don't care what the tag is, just that something exists. | ||
25 | |||
26 | # Git/Cogito store the top-of-tree "commit" in .git/HEAD | ||
27 | # A list of known tags sits in .git/refs/tags/ | ||
28 | # | ||
29 | # The simple trick here is to just compare the two of these, and if we get a | ||
30 | # match, return nothing, otherwise, return a subset of the SHA-1 hash in | ||
31 | # .git/HEAD | ||
32 | |||
33 | sub do_git_checks { | ||
34 | open(H,"<.git/HEAD") or return; | ||
35 | my $head = <H>; | ||
36 | chomp $head; | ||
37 | close(H); | ||
38 | 10 | ||
39 | opendir(D,".git/refs/tags") or return; | 11 | # Check for git and a git repo. |
40 | foreach my $tagfile (grep !/^\.{1,2}$/, readdir(D)) { | 12 | if head=`git rev-parse --verify HEAD 2>/dev/null`; then |
41 | open(F,"<.git/refs/tags/" . $tagfile) or return; | 13 | # Do we have an untagged version? |
42 | my $tag = <F>; | 14 | if [ "`git name-rev --tags HEAD`" = "HEAD undefined" ]; then |
43 | chomp $tag; | 15 | printf '%s%s' -g `echo "$head" | cut -c1-8` |
44 | close(F); | 16 | fi |
45 | return if ($tag eq $head); | ||
46 | } | ||
47 | closedir(D); | ||
48 | |||
49 | push @LOCALVERSIONS, "g" . substr($head,0,8); | ||
50 | } | ||
51 | |||
52 | if ( -d ".git") { | ||
53 | do_git_checks(); | ||
54 | } | ||
55 | 17 | ||
56 | printf "-%s\n", join("-",@LOCALVERSIONS) if (scalar @LOCALVERSIONS > 0); | 18 | # Are there uncommitted changes? |
19 | if git diff-files | read dummy; then | ||
20 | printf '%s' -git_dirty | ||
21 | fi | ||
22 | fi | ||
diff --git a/security/capability.c b/security/capability.c index ec18d6075625..f9b35cc0b248 100644 --- a/security/capability.c +++ b/security/capability.c | |||
@@ -49,8 +49,6 @@ static struct security_operations capability_ops = { | |||
49 | .vm_enough_memory = cap_vm_enough_memory, | 49 | .vm_enough_memory = cap_vm_enough_memory, |
50 | }; | 50 | }; |
51 | 51 | ||
52 | #define MY_NAME __stringify(KBUILD_MODNAME) | ||
53 | |||
54 | /* flag to keep track of how we were registered */ | 52 | /* flag to keep track of how we were registered */ |
55 | static int secondary; | 53 | static int secondary; |
56 | 54 | ||
@@ -67,7 +65,7 @@ static int __init capability_init (void) | |||
67 | /* register ourselves with the security framework */ | 65 | /* register ourselves with the security framework */ |
68 | if (register_security (&capability_ops)) { | 66 | if (register_security (&capability_ops)) { |
69 | /* try registering with primary module */ | 67 | /* try registering with primary module */ |
70 | if (mod_reg_security (MY_NAME, &capability_ops)) { | 68 | if (mod_reg_security (KBUILD_MODNAME, &capability_ops)) { |
71 | printk (KERN_INFO "Failure registering capabilities " | 69 | printk (KERN_INFO "Failure registering capabilities " |
72 | "with primary security module.\n"); | 70 | "with primary security module.\n"); |
73 | return -EINVAL; | 71 | return -EINVAL; |
@@ -85,7 +83,7 @@ static void __exit capability_exit (void) | |||
85 | return; | 83 | return; |
86 | /* remove ourselves from the security framework */ | 84 | /* remove ourselves from the security framework */ |
87 | if (secondary) { | 85 | if (secondary) { |
88 | if (mod_unreg_security (MY_NAME, &capability_ops)) | 86 | if (mod_unreg_security (KBUILD_MODNAME, &capability_ops)) |
89 | printk (KERN_INFO "Failure unregistering capabilities " | 87 | printk (KERN_INFO "Failure unregistering capabilities " |
90 | "with primary module.\n"); | 88 | "with primary module.\n"); |
91 | return; | 89 | return; |
diff --git a/security/selinux/include/av_perm_to_string.h b/security/selinux/include/av_perm_to_string.h index 71aeb12f07c8..591e98d9315a 100644 --- a/security/selinux/include/av_perm_to_string.h +++ b/security/selinux/include/av_perm_to_string.h | |||
@@ -238,5 +238,4 @@ | |||
238 | S_(SECCLASS_NSCD, NSCD__SHMEMHOST, "shmemhost") | 238 | S_(SECCLASS_NSCD, NSCD__SHMEMHOST, "shmemhost") |
239 | S_(SECCLASS_ASSOCIATION, ASSOCIATION__SENDTO, "sendto") | 239 | S_(SECCLASS_ASSOCIATION, ASSOCIATION__SENDTO, "sendto") |
240 | S_(SECCLASS_ASSOCIATION, ASSOCIATION__RECVFROM, "recvfrom") | 240 | S_(SECCLASS_ASSOCIATION, ASSOCIATION__RECVFROM, "recvfrom") |
241 | S_(SECCLASS_ASSOCIATION, ASSOCIATION__RELABELFROM, "relabelfrom") | 241 | S_(SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT, "setcontext") |
242 | S_(SECCLASS_ASSOCIATION, ASSOCIATION__RELABELTO, "relabelto") | ||
diff --git a/security/selinux/include/av_permissions.h b/security/selinux/include/av_permissions.h index d1d0996049e3..d7f02edf3930 100644 --- a/security/selinux/include/av_permissions.h +++ b/security/selinux/include/av_permissions.h | |||
@@ -908,8 +908,7 @@ | |||
908 | 908 | ||
909 | #define ASSOCIATION__SENDTO 0x00000001UL | 909 | #define ASSOCIATION__SENDTO 0x00000001UL |
910 | #define ASSOCIATION__RECVFROM 0x00000002UL | 910 | #define ASSOCIATION__RECVFROM 0x00000002UL |
911 | #define ASSOCIATION__RELABELFROM 0x00000004UL | 911 | #define ASSOCIATION__SETCONTEXT 0x00000004UL |
912 | #define ASSOCIATION__RELABELTO 0x00000008UL | ||
913 | 912 | ||
914 | #define NETLINK_KOBJECT_UEVENT_SOCKET__IOCTL 0x00000001UL | 913 | #define NETLINK_KOBJECT_UEVENT_SOCKET__IOCTL 0x00000001UL |
915 | #define NETLINK_KOBJECT_UEVENT_SOCKET__READ 0x00000002UL | 914 | #define NETLINK_KOBJECT_UEVENT_SOCKET__READ 0x00000002UL |
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c index c4d87d4dca7b..5b7776504e4c 100644 --- a/security/selinux/xfrm.c +++ b/security/selinux/xfrm.c | |||
@@ -137,15 +137,9 @@ static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp, struct xfrm_us | |||
137 | * Must be permitted to relabel from default socket type (process type) | 137 | * Must be permitted to relabel from default socket type (process type) |
138 | * to specified context | 138 | * to specified context |
139 | */ | 139 | */ |
140 | rc = avc_has_perm(tsec->sid, tsec->sid, | ||
141 | SECCLASS_ASSOCIATION, | ||
142 | ASSOCIATION__RELABELFROM, NULL); | ||
143 | if (rc) | ||
144 | goto out; | ||
145 | |||
146 | rc = avc_has_perm(tsec->sid, ctx->ctx_sid, | 140 | rc = avc_has_perm(tsec->sid, ctx->ctx_sid, |
147 | SECCLASS_ASSOCIATION, | 141 | SECCLASS_ASSOCIATION, |
148 | ASSOCIATION__RELABELTO, NULL); | 142 | ASSOCIATION__SETCONTEXT, NULL); |
149 | if (rc) | 143 | if (rc) |
150 | goto out; | 144 | goto out; |
151 | 145 | ||
diff --git a/sound/oss/dmasound/dac3550a.c b/sound/oss/dmasound/dac3550a.c index 533895eba0eb..7360d8954d60 100644 --- a/sound/oss/dmasound/dac3550a.c +++ b/sound/oss/dmasound/dac3550a.c | |||
@@ -41,10 +41,10 @@ static int daca_detect_client(struct i2c_adapter *adapter, int address); | |||
41 | static int daca_detach_client(struct i2c_client *client); | 41 | static int daca_detach_client(struct i2c_client *client); |
42 | 42 | ||
43 | struct i2c_driver daca_driver = { | 43 | struct i2c_driver daca_driver = { |
44 | .owner = THIS_MODULE, | 44 | .driver = { |
45 | .name = "DAC3550A driver V " DACA_VERSION, | 45 | .name = "DAC3550A driver V " DACA_VERSION, |
46 | }, | ||
46 | .id = I2C_DRIVERID_DACA, | 47 | .id = I2C_DRIVERID_DACA, |
47 | .flags = I2C_DF_NOTIFY, | ||
48 | .attach_adapter = daca_attach_adapter, | 48 | .attach_adapter = daca_attach_adapter, |
49 | .detach_client = daca_detach_client, | 49 | .detach_client = daca_detach_client, |
50 | }; | 50 | }; |
diff --git a/sound/oss/dmasound/tas_common.c b/sound/oss/dmasound/tas_common.c index d36a1fe2fcf3..81315996c0f1 100644 --- a/sound/oss/dmasound/tas_common.c +++ b/sound/oss/dmasound/tas_common.c | |||
@@ -47,9 +47,9 @@ static int tas_attach_adapter(struct i2c_adapter *); | |||
47 | static int tas_detach_client(struct i2c_client *); | 47 | static int tas_detach_client(struct i2c_client *); |
48 | 48 | ||
49 | struct i2c_driver tas_driver = { | 49 | struct i2c_driver tas_driver = { |
50 | .owner = THIS_MODULE, | 50 | .driver = { |
51 | .name = "tas", | 51 | .name = "tas", |
52 | .flags = I2C_DF_NOTIFY, | 52 | }, |
53 | .attach_adapter = tas_attach_adapter, | 53 | .attach_adapter = tas_attach_adapter, |
54 | .detach_client = tas_detach_client, | 54 | .detach_client = tas_detach_client, |
55 | }; | 55 | }; |
diff --git a/sound/ppc/keywest.c b/sound/ppc/keywest.c index 097fbcfc5d45..6058c2dd1b7f 100644 --- a/sound/ppc/keywest.c +++ b/sound/ppc/keywest.c | |||
@@ -41,9 +41,10 @@ static int keywest_attach_adapter(struct i2c_adapter *adapter); | |||
41 | static int keywest_detach_client(struct i2c_client *client); | 41 | static int keywest_detach_client(struct i2c_client *client); |
42 | 42 | ||
43 | struct i2c_driver keywest_driver = { | 43 | struct i2c_driver keywest_driver = { |
44 | .name = "PMac Keywest Audio", | 44 | .driver = { |
45 | .name = "PMac Keywest Audio", | ||
46 | }, | ||
45 | .id = I2C_DRIVERID_KEYWEST, | 47 | .id = I2C_DRIVERID_KEYWEST, |
46 | .flags = I2C_DF_NOTIFY, | ||
47 | .attach_adapter = &keywest_attach_adapter, | 48 | .attach_adapter = &keywest_attach_adapter, |
48 | .detach_client = &keywest_detach_client, | 49 | .detach_client = &keywest_detach_client, |
49 | }; | 50 | }; |