diff options
30 files changed, 658 insertions, 253 deletions
diff --git a/Documentation/cpu-hotplug.txt b/Documentation/cpu-hotplug.txt index a99d7031cdf9..45d5a217484f 100644 --- a/Documentation/cpu-hotplug.txt +++ b/Documentation/cpu-hotplug.txt | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | 2 | ||
| 3 | Maintainers: | 3 | Maintainers: |
| 4 | CPU Hotplug Core: | 4 | CPU Hotplug Core: |
| 5 | Rusty Russell <rusty@rustycorp.com.au> | 5 | Rusty Russell <rusty@rustcorp.com.au> |
| 6 | Srivatsa Vaddagiri <vatsa@in.ibm.com> | 6 | Srivatsa Vaddagiri <vatsa@in.ibm.com> |
| 7 | i386: | 7 | i386: |
| 8 | Zwane Mwaikambo <zwane@arm.linux.org.uk> | 8 | Zwane Mwaikambo <zwane@arm.linux.org.uk> |
diff --git a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c index 68142df76608..0c46e398cd8f 100644 --- a/arch/um/drivers/hostaudio_kern.c +++ b/arch/um/drivers/hostaudio_kern.c | |||
| @@ -187,7 +187,9 @@ static int hostaudio_open(struct inode *inode, struct file *file) | |||
| 187 | int ret; | 187 | int ret; |
| 188 | 188 | ||
| 189 | #ifdef DEBUG | 189 | #ifdef DEBUG |
| 190 | kparam_block_sysfs_write(dsp); | ||
| 190 | printk(KERN_DEBUG "hostaudio: open called (host: %s)\n", dsp); | 191 | printk(KERN_DEBUG "hostaudio: open called (host: %s)\n", dsp); |
| 192 | kparam_unblock_sysfs_write(dsp); | ||
| 191 | #endif | 193 | #endif |
| 192 | 194 | ||
| 193 | state = kmalloc(sizeof(struct hostaudio_state), GFP_KERNEL); | 195 | state = kmalloc(sizeof(struct hostaudio_state), GFP_KERNEL); |
| @@ -199,9 +201,11 @@ static int hostaudio_open(struct inode *inode, struct file *file) | |||
| 199 | if (file->f_mode & FMODE_WRITE) | 201 | if (file->f_mode & FMODE_WRITE) |
| 200 | w = 1; | 202 | w = 1; |
| 201 | 203 | ||
| 204 | kparam_block_sysfs_write(dsp); | ||
| 202 | lock_kernel(); | 205 | lock_kernel(); |
| 203 | ret = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0); | 206 | ret = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0); |
| 204 | unlock_kernel(); | 207 | unlock_kernel(); |
| 208 | kparam_unblock_sysfs_write(dsp); | ||
| 205 | 209 | ||
| 206 | if (ret < 0) { | 210 | if (ret < 0) { |
| 207 | kfree(state); | 211 | kfree(state); |
| @@ -258,13 +262,17 @@ static int hostmixer_open_mixdev(struct inode *inode, struct file *file) | |||
| 258 | if (file->f_mode & FMODE_WRITE) | 262 | if (file->f_mode & FMODE_WRITE) |
| 259 | w = 1; | 263 | w = 1; |
| 260 | 264 | ||
| 265 | kparam_block_sysfs_write(mixer); | ||
| 261 | lock_kernel(); | 266 | lock_kernel(); |
| 262 | ret = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0); | 267 | ret = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0); |
| 263 | unlock_kernel(); | 268 | unlock_kernel(); |
| 269 | kparam_unblock_sysfs_write(mixer); | ||
| 264 | 270 | ||
| 265 | if (ret < 0) { | 271 | if (ret < 0) { |
| 272 | kparam_block_sysfs_write(dsp); | ||
| 266 | printk(KERN_ERR "hostaudio_open_mixdev failed to open '%s', " | 273 | printk(KERN_ERR "hostaudio_open_mixdev failed to open '%s', " |
| 267 | "err = %d\n", dsp, -ret); | 274 | "err = %d\n", dsp, -ret); |
| 275 | kparam_unblock_sysfs_write(dsp); | ||
| 268 | kfree(state); | 276 | kfree(state); |
| 269 | return ret; | 277 | return ret; |
| 270 | } | 278 | } |
| @@ -320,8 +328,10 @@ MODULE_LICENSE("GPL"); | |||
| 320 | 328 | ||
| 321 | static int __init hostaudio_init_module(void) | 329 | static int __init hostaudio_init_module(void) |
| 322 | { | 330 | { |
| 331 | __kernel_param_lock(); | ||
| 323 | printk(KERN_INFO "UML Audio Relay (host dsp = %s, host mixer = %s)\n", | 332 | printk(KERN_INFO "UML Audio Relay (host dsp = %s, host mixer = %s)\n", |
| 324 | dsp, mixer); | 333 | dsp, mixer); |
| 334 | __kernel_param_unlock(); | ||
| 325 | 335 | ||
| 326 | module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1); | 336 | module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1); |
| 327 | if (module_data.dev_audio < 0) { | 337 | if (module_data.dev_audio < 0) { |
diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c index 146135e7a6a1..295dbfa2db9c 100644 --- a/drivers/acpi/debug.c +++ b/drivers/acpi/debug.c | |||
| @@ -96,7 +96,8 @@ static const struct acpi_dlevel acpi_debug_levels[] = { | |||
| 96 | /* -------------------------------------------------------------------------- | 96 | /* -------------------------------------------------------------------------- |
| 97 | FS Interface (/sys) | 97 | FS Interface (/sys) |
| 98 | -------------------------------------------------------------------------- */ | 98 | -------------------------------------------------------------------------- */ |
| 99 | static int param_get_debug_layer(char *buffer, struct kernel_param *kp) { | 99 | static int param_get_debug_layer(char *buffer, const struct kernel_param *kp) |
| 100 | { | ||
| 100 | int result = 0; | 101 | int result = 0; |
| 101 | int i; | 102 | int i; |
| 102 | 103 | ||
| @@ -118,7 +119,8 @@ static int param_get_debug_layer(char *buffer, struct kernel_param *kp) { | |||
| 118 | return result; | 119 | return result; |
| 119 | } | 120 | } |
| 120 | 121 | ||
| 121 | static int param_get_debug_level(char *buffer, struct kernel_param *kp) { | 122 | static int param_get_debug_level(char *buffer, const struct kernel_param *kp) |
| 123 | { | ||
| 122 | int result = 0; | 124 | int result = 0; |
| 123 | int i; | 125 | int i; |
| 124 | 126 | ||
| @@ -137,8 +139,18 @@ static int param_get_debug_level(char *buffer, struct kernel_param *kp) { | |||
| 137 | return result; | 139 | return result; |
| 138 | } | 140 | } |
| 139 | 141 | ||
| 140 | module_param_call(debug_layer, param_set_uint, param_get_debug_layer, &acpi_dbg_layer, 0644); | 142 | static struct kernel_param_ops acpi_debug_layer_ops = { |
| 141 | module_param_call(debug_level, param_set_uint, param_get_debug_level, &acpi_dbg_level, 0644); | 143 | .set = param_set_uint, |
| 144 | .get = param_get_debug_layer, | ||
| 145 | }; | ||
| 146 | |||
| 147 | static struct kernel_param_ops acpi_debug_level_ops = { | ||
| 148 | .set = param_set_uint, | ||
| 149 | .get = param_get_debug_level, | ||
| 150 | }; | ||
| 151 | |||
| 152 | module_param_cb(debug_layer, &acpi_debug_layer_ops, &acpi_dbg_layer, 0644); | ||
| 153 | module_param_cb(debug_level, &acpi_debug_level_ops, &acpi_dbg_level, 0644); | ||
| 142 | 154 | ||
| 143 | static char trace_method_name[6]; | 155 | static char trace_method_name[6]; |
| 144 | module_param_string(trace_method_name, trace_method_name, 6, 0644); | 156 | module_param_string(trace_method_name, trace_method_name, 6, 0644); |
| @@ -147,7 +159,7 @@ module_param(trace_debug_layer, uint, 0644); | |||
| 147 | static unsigned int trace_debug_level; | 159 | static unsigned int trace_debug_level; |
| 148 | module_param(trace_debug_level, uint, 0644); | 160 | module_param(trace_debug_level, uint, 0644); |
| 149 | 161 | ||
| 150 | static int param_set_trace_state(const char *val, struct kernel_param *kp) | 162 | static int param_set_trace_state(const char *val, const struct kernel_param *kp) |
| 151 | { | 163 | { |
| 152 | int result = 0; | 164 | int result = 0; |
| 153 | 165 | ||
| @@ -181,7 +193,7 @@ exit: | |||
| 181 | return result; | 193 | return result; |
| 182 | } | 194 | } |
| 183 | 195 | ||
| 184 | static int param_get_trace_state(char *buffer, struct kernel_param *kp) | 196 | static int param_get_trace_state(char *buffer, const struct kernel_param *kp) |
| 185 | { | 197 | { |
| 186 | if (!acpi_gbl_trace_method_name) | 198 | if (!acpi_gbl_trace_method_name) |
| 187 | return sprintf(buffer, "disable"); | 199 | return sprintf(buffer, "disable"); |
| @@ -194,8 +206,12 @@ static int param_get_trace_state(char *buffer, struct kernel_param *kp) | |||
| 194 | return 0; | 206 | return 0; |
| 195 | } | 207 | } |
| 196 | 208 | ||
| 197 | module_param_call(trace_state, param_set_trace_state, param_get_trace_state, | 209 | static struct kernel_param_ops param_ops_trace_state = { |
| 198 | NULL, 0644); | 210 | .set = param_set_trace_state, |
| 211 | .get = param_get_trace_state, | ||
| 212 | }; | ||
| 213 | |||
| 214 | module_param_cb(trace_state, ¶m_ops_trace_state, NULL, 0644); | ||
| 199 | 215 | ||
| 200 | /* -------------------------------------------------------------------------- | 216 | /* -------------------------------------------------------------------------- |
| 201 | DebugFS Interface | 217 | DebugFS Interface |
diff --git a/drivers/char/hvc_iucv.c b/drivers/char/hvc_iucv.c index 5a80ad68ef22..7b01bc609de3 100644 --- a/drivers/char/hvc_iucv.c +++ b/drivers/char/hvc_iucv.c | |||
| @@ -1149,7 +1149,7 @@ out_err: | |||
| 1149 | * Note: If it is called early in the boot process, @val is stored and | 1149 | * Note: If it is called early in the boot process, @val is stored and |
| 1150 | * parsed later in hvc_iucv_init(). | 1150 | * parsed later in hvc_iucv_init(). |
| 1151 | */ | 1151 | */ |
| 1152 | static int param_set_vmidfilter(const char *val, struct kernel_param *kp) | 1152 | static int param_set_vmidfilter(const char *val, const struct kernel_param *kp) |
| 1153 | { | 1153 | { |
| 1154 | int rc; | 1154 | int rc; |
| 1155 | 1155 | ||
| @@ -1176,7 +1176,7 @@ static int param_set_vmidfilter(const char *val, struct kernel_param *kp) | |||
| 1176 | * The function stores the filter as a comma-separated list of z/VM user IDs | 1176 | * The function stores the filter as a comma-separated list of z/VM user IDs |
| 1177 | * in @buffer. Typically, sysfs routines call this function for attr show. | 1177 | * in @buffer. Typically, sysfs routines call this function for attr show. |
| 1178 | */ | 1178 | */ |
| 1179 | static int param_get_vmidfilter(char *buffer, struct kernel_param *kp) | 1179 | static int param_get_vmidfilter(char *buffer, const struct kernel_param *kp) |
| 1180 | { | 1180 | { |
| 1181 | int rc; | 1181 | int rc; |
| 1182 | size_t index, len; | 1182 | size_t index, len; |
| @@ -1203,6 +1203,11 @@ static int param_get_vmidfilter(char *buffer, struct kernel_param *kp) | |||
| 1203 | 1203 | ||
| 1204 | #define param_check_vmidfilter(name, p) __param_check(name, p, void) | 1204 | #define param_check_vmidfilter(name, p) __param_check(name, p, void) |
| 1205 | 1205 | ||
| 1206 | static struct kernel_param_ops param_ops_vmidfilter = { | ||
| 1207 | .set = param_set_vmidfilter, | ||
| 1208 | .get = param_get_vmidfilter, | ||
| 1209 | }; | ||
| 1210 | |||
| 1206 | /** | 1211 | /** |
| 1207 | * hvc_iucv_init() - z/VM IUCV HVC device driver initialization | 1212 | * hvc_iucv_init() - z/VM IUCV HVC device driver initialization |
| 1208 | */ | 1213 | */ |
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index 82bcdb262a3a..654d566ca57c 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c | |||
| @@ -196,7 +196,7 @@ static void ipmi_unregister_watchdog(int ipmi_intf); | |||
| 196 | */ | 196 | */ |
| 197 | static int start_now; | 197 | static int start_now; |
| 198 | 198 | ||
| 199 | static int set_param_int(const char *val, struct kernel_param *kp) | 199 | static int set_param_timeout(const char *val, const struct kernel_param *kp) |
| 200 | { | 200 | { |
| 201 | char *endp; | 201 | char *endp; |
| 202 | int l; | 202 | int l; |
| @@ -215,10 +215,11 @@ static int set_param_int(const char *val, struct kernel_param *kp) | |||
| 215 | return rv; | 215 | return rv; |
| 216 | } | 216 | } |
| 217 | 217 | ||
| 218 | static int get_param_int(char *buffer, struct kernel_param *kp) | 218 | static struct kernel_param_ops param_ops_timeout = { |
| 219 | { | 219 | .set = set_param_timeout, |
| 220 | return sprintf(buffer, "%i", *((int *)kp->arg)); | 220 | .get = param_get_int, |
| 221 | } | 221 | }; |
| 222 | #define param_check_timeout param_check_int | ||
| 222 | 223 | ||
| 223 | typedef int (*action_fn)(const char *intval, char *outval); | 224 | typedef int (*action_fn)(const char *intval, char *outval); |
| 224 | 225 | ||
| @@ -227,7 +228,7 @@ static int preaction_op(const char *inval, char *outval); | |||
| 227 | static int preop_op(const char *inval, char *outval); | 228 | static int preop_op(const char *inval, char *outval); |
| 228 | static void check_parms(void); | 229 | static void check_parms(void); |
| 229 | 230 | ||
| 230 | static int set_param_str(const char *val, struct kernel_param *kp) | 231 | static int set_param_str(const char *val, const struct kernel_param *kp) |
| 231 | { | 232 | { |
| 232 | action_fn fn = (action_fn) kp->arg; | 233 | action_fn fn = (action_fn) kp->arg; |
| 233 | int rv = 0; | 234 | int rv = 0; |
| @@ -251,7 +252,7 @@ static int set_param_str(const char *val, struct kernel_param *kp) | |||
| 251 | return rv; | 252 | return rv; |
| 252 | } | 253 | } |
| 253 | 254 | ||
| 254 | static int get_param_str(char *buffer, struct kernel_param *kp) | 255 | static int get_param_str(char *buffer, const struct kernel_param *kp) |
| 255 | { | 256 | { |
| 256 | action_fn fn = (action_fn) kp->arg; | 257 | action_fn fn = (action_fn) kp->arg; |
| 257 | int rv; | 258 | int rv; |
| @@ -263,7 +264,7 @@ static int get_param_str(char *buffer, struct kernel_param *kp) | |||
| 263 | } | 264 | } |
| 264 | 265 | ||
| 265 | 266 | ||
| 266 | static int set_param_wdog_ifnum(const char *val, struct kernel_param *kp) | 267 | static int set_param_wdog_ifnum(const char *val, const struct kernel_param *kp) |
| 267 | { | 268 | { |
| 268 | int rv = param_set_int(val, kp); | 269 | int rv = param_set_int(val, kp); |
| 269 | if (rv) | 270 | if (rv) |
| @@ -276,27 +277,38 @@ static int set_param_wdog_ifnum(const char *val, struct kernel_param *kp) | |||
| 276 | return 0; | 277 | return 0; |
| 277 | } | 278 | } |
| 278 | 279 | ||
| 279 | module_param_call(ifnum_to_use, set_param_wdog_ifnum, get_param_int, | 280 | static struct kernel_param_ops param_ops_wdog_ifnum = { |
| 280 | &ifnum_to_use, 0644); | 281 | .set = set_param_wdog_ifnum, |
| 282 | .get = param_get_int, | ||
| 283 | }; | ||
| 284 | |||
| 285 | #define param_check_wdog_ifnum param_check_int | ||
| 286 | |||
| 287 | static struct kernel_param_ops param_ops_str = { | ||
| 288 | .set = set_param_str, | ||
| 289 | .get = get_param_str, | ||
| 290 | }; | ||
| 291 | |||
| 292 | module_param(ifnum_to_use, wdog_ifnum, 0644); | ||
| 281 | MODULE_PARM_DESC(ifnum_to_use, "The interface number to use for the watchdog " | 293 | MODULE_PARM_DESC(ifnum_to_use, "The interface number to use for the watchdog " |
| 282 | "timer. Setting to -1 defaults to the first registered " | 294 | "timer. Setting to -1 defaults to the first registered " |
| 283 | "interface"); | 295 | "interface"); |
| 284 | 296 | ||
| 285 | module_param_call(timeout, set_param_int, get_param_int, &timeout, 0644); | 297 | module_param(timeout, timeout, 0644); |
| 286 | MODULE_PARM_DESC(timeout, "Timeout value in seconds."); | 298 | MODULE_PARM_DESC(timeout, "Timeout value in seconds."); |
| 287 | 299 | ||
| 288 | module_param_call(pretimeout, set_param_int, get_param_int, &pretimeout, 0644); | 300 | module_param(pretimeout, timeout, 0644); |
| 289 | MODULE_PARM_DESC(pretimeout, "Pretimeout value in seconds."); | 301 | MODULE_PARM_DESC(pretimeout, "Pretimeout value in seconds."); |
| 290 | 302 | ||
| 291 | module_param_call(action, set_param_str, get_param_str, action_op, 0644); | 303 | module_param_cb(action, ¶m_ops_str, action_op, 0644); |
| 292 | MODULE_PARM_DESC(action, "Timeout action. One of: " | 304 | MODULE_PARM_DESC(action, "Timeout action. One of: " |
| 293 | "reset, none, power_cycle, power_off."); | 305 | "reset, none, power_cycle, power_off."); |
| 294 | 306 | ||
| 295 | module_param_call(preaction, set_param_str, get_param_str, preaction_op, 0644); | 307 | module_param_cb(preaction, ¶m_ops_str, preaction_op, 0644); |
| 296 | MODULE_PARM_DESC(preaction, "Pretimeout action. One of: " | 308 | MODULE_PARM_DESC(preaction, "Pretimeout action. One of: " |
| 297 | "pre_none, pre_smi, pre_nmi, pre_int."); | 309 | "pre_none, pre_smi, pre_nmi, pre_int."); |
| 298 | 310 | ||
| 299 | module_param_call(preop, set_param_str, get_param_str, preop_op, 0644); | 311 | module_param_cb(preop, ¶m_ops_str, preop_op, 0644); |
| 300 | MODULE_PARM_DESC(preop, "Pretimeout driver operation. One of: " | 312 | MODULE_PARM_DESC(preop, "Pretimeout driver operation. One of: " |
| 301 | "preop_none, preop_panic, preop_give_data."); | 313 | "preop_none, preop_panic, preop_give_data."); |
| 302 | 314 | ||
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 3cb9c4e056ff..fa896210ed7b 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c | |||
| @@ -177,7 +177,7 @@ EXPORT_SYMBOL_GPL(ide_pci_clk); | |||
| 177 | module_param_named(pci_clock, ide_pci_clk, int, 0); | 177 | module_param_named(pci_clock, ide_pci_clk, int, 0); |
| 178 | MODULE_PARM_DESC(pci_clock, "PCI bus clock frequency (in MHz)"); | 178 | MODULE_PARM_DESC(pci_clock, "PCI bus clock frequency (in MHz)"); |
| 179 | 179 | ||
| 180 | static int ide_set_dev_param_mask(const char *s, struct kernel_param *kp) | 180 | static int ide_set_dev_param_mask(const char *s, const struct kernel_param *kp) |
| 181 | { | 181 | { |
| 182 | int a, b, i, j = 1; | 182 | int a, b, i, j = 1; |
| 183 | unsigned int *dev_param_mask = (unsigned int *)kp->arg; | 183 | unsigned int *dev_param_mask = (unsigned int *)kp->arg; |
| @@ -200,34 +200,40 @@ static int ide_set_dev_param_mask(const char *s, struct kernel_param *kp) | |||
| 200 | return 0; | 200 | return 0; |
| 201 | } | 201 | } |
| 202 | 202 | ||
| 203 | static struct kernel_param_ops param_ops_ide_dev_mask = { | ||
| 204 | .set = ide_set_dev_param_mask | ||
| 205 | }; | ||
| 206 | |||
| 207 | #define param_check_ide_dev_mask(name, p) param_check_uint(name, p) | ||
| 208 | |||
| 203 | static unsigned int ide_nodma; | 209 | static unsigned int ide_nodma; |
| 204 | 210 | ||
| 205 | module_param_call(nodma, ide_set_dev_param_mask, NULL, &ide_nodma, 0); | 211 | module_param_named(nodma, ide_nodma, ide_dev_mask, 0); |
| 206 | MODULE_PARM_DESC(nodma, "disallow DMA for a device"); | 212 | MODULE_PARM_DESC(nodma, "disallow DMA for a device"); |
| 207 | 213 | ||
| 208 | static unsigned int ide_noflush; | 214 | static unsigned int ide_noflush; |
| 209 | 215 | ||
| 210 | module_param_call(noflush, ide_set_dev_param_mask, NULL, &ide_noflush, 0); | 216 | module_param_named(noflush, ide_noflush, ide_dev_mask, 0); |
| 211 | MODULE_PARM_DESC(noflush, "disable flush requests for a device"); | 217 | MODULE_PARM_DESC(noflush, "disable flush requests for a device"); |
| 212 | 218 | ||
| 213 | static unsigned int ide_nohpa; | 219 | static unsigned int ide_nohpa; |
| 214 | 220 | ||
| 215 | module_param_call(nohpa, ide_set_dev_param_mask, NULL, &ide_nohpa, 0); | 221 | module_param_named(nohpa, ide_nohpa, ide_dev_mask, 0); |
| 216 | MODULE_PARM_DESC(nohpa, "disable Host Protected Area for a device"); | 222 | MODULE_PARM_DESC(nohpa, "disable Host Protected Area for a device"); |
| 217 | 223 | ||
| 218 | static unsigned int ide_noprobe; | 224 | static unsigned int ide_noprobe; |
| 219 | 225 | ||
| 220 | module_param_call(noprobe, ide_set_dev_param_mask, NULL, &ide_noprobe, 0); | 226 | module_param_named(noprobe, ide_noprobe, ide_dev_mask, 0); |
| 221 | MODULE_PARM_DESC(noprobe, "skip probing for a device"); | 227 | MODULE_PARM_DESC(noprobe, "skip probing for a device"); |
| 222 | 228 | ||
| 223 | static unsigned int ide_nowerr; | 229 | static unsigned int ide_nowerr; |
| 224 | 230 | ||
| 225 | module_param_call(nowerr, ide_set_dev_param_mask, NULL, &ide_nowerr, 0); | 231 | module_param_named(nowerr, ide_nowerr, ide_dev_mask, 0); |
| 226 | MODULE_PARM_DESC(nowerr, "ignore the ATA_DF bit for a device"); | 232 | MODULE_PARM_DESC(nowerr, "ignore the ATA_DF bit for a device"); |
| 227 | 233 | ||
| 228 | static unsigned int ide_cdroms; | 234 | static unsigned int ide_cdroms; |
| 229 | 235 | ||
| 230 | module_param_call(cdrom, ide_set_dev_param_mask, NULL, &ide_cdroms, 0); | 236 | module_param_named(cdrom, ide_cdroms, ide_dev_mask, 0); |
| 231 | MODULE_PARM_DESC(cdrom, "force device as a CD-ROM"); | 237 | MODULE_PARM_DESC(cdrom, "force device as a CD-ROM"); |
| 232 | 238 | ||
| 233 | struct chs_geom { | 239 | struct chs_geom { |
diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c index e148749b5851..23257652b8e8 100644 --- a/drivers/input/misc/ati_remote2.c +++ b/drivers/input/misc/ati_remote2.c | |||
| @@ -38,7 +38,8 @@ enum { | |||
| 38 | }; | 38 | }; |
| 39 | 39 | ||
| 40 | static int ati_remote2_set_mask(const char *val, | 40 | static int ati_remote2_set_mask(const char *val, |
| 41 | struct kernel_param *kp, unsigned int max) | 41 | const struct kernel_param *kp, |
| 42 | unsigned int max) | ||
| 42 | { | 43 | { |
| 43 | unsigned long mask; | 44 | unsigned long mask; |
| 44 | int ret; | 45 | int ret; |
| @@ -59,28 +60,31 @@ static int ati_remote2_set_mask(const char *val, | |||
| 59 | } | 60 | } |
| 60 | 61 | ||
| 61 | static int ati_remote2_set_channel_mask(const char *val, | 62 | static int ati_remote2_set_channel_mask(const char *val, |
| 62 | struct kernel_param *kp) | 63 | const struct kernel_param *kp) |
| 63 | { | 64 | { |
| 64 | pr_debug("%s()\n", __func__); | 65 | pr_debug("%s()\n", __func__); |
| 65 | 66 | ||
| 66 | return ati_remote2_set_mask(val, kp, ATI_REMOTE2_MAX_CHANNEL_MASK); | 67 | return ati_remote2_set_mask(val, kp, ATI_REMOTE2_MAX_CHANNEL_MASK); |
| 67 | } | 68 | } |
| 68 | 69 | ||
| 69 | static int ati_remote2_get_channel_mask(char *buffer, struct kernel_param *kp) | 70 | static int ati_remote2_get_channel_mask(char *buffer, |
| 71 | const struct kernel_param *kp) | ||
| 70 | { | 72 | { |
| 71 | pr_debug("%s()\n", __func__); | 73 | pr_debug("%s()\n", __func__); |
| 72 | 74 | ||
| 73 | return sprintf(buffer, "0x%04x", *(unsigned int *)kp->arg); | 75 | return sprintf(buffer, "0x%04x", *(unsigned int *)kp->arg); |
| 74 | } | 76 | } |
| 75 | 77 | ||
| 76 | static int ati_remote2_set_mode_mask(const char *val, struct kernel_param *kp) | 78 | static int ati_remote2_set_mode_mask(const char *val, |
| 79 | const struct kernel_param *kp) | ||
| 77 | { | 80 | { |
| 78 | pr_debug("%s()\n", __func__); | 81 | pr_debug("%s()\n", __func__); |
| 79 | 82 | ||
| 80 | return ati_remote2_set_mask(val, kp, ATI_REMOTE2_MAX_MODE_MASK); | 83 | return ati_remote2_set_mask(val, kp, ATI_REMOTE2_MAX_MODE_MASK); |
| 81 | } | 84 | } |
| 82 | 85 | ||
| 83 | static int ati_remote2_get_mode_mask(char *buffer, struct kernel_param *kp) | 86 | static int ati_remote2_get_mode_mask(char *buffer, |
| 87 | const struct kernel_param *kp) | ||
| 84 | { | 88 | { |
| 85 | pr_debug("%s()\n", __func__); | 89 | pr_debug("%s()\n", __func__); |
| 86 | 90 | ||
| @@ -89,15 +93,19 @@ static int ati_remote2_get_mode_mask(char *buffer, struct kernel_param *kp) | |||
| 89 | 93 | ||
| 90 | static unsigned int channel_mask = ATI_REMOTE2_MAX_CHANNEL_MASK; | 94 | static unsigned int channel_mask = ATI_REMOTE2_MAX_CHANNEL_MASK; |
| 91 | #define param_check_channel_mask(name, p) __param_check(name, p, unsigned int) | 95 | #define param_check_channel_mask(name, p) __param_check(name, p, unsigned int) |
| 92 | #define param_set_channel_mask ati_remote2_set_channel_mask | 96 | static struct kernel_param_ops param_ops_channel_mask = { |
| 93 | #define param_get_channel_mask ati_remote2_get_channel_mask | 97 | .set = ati_remote2_set_channel_mask, |
| 98 | .get = ati_remote2_get_channel_mask, | ||
| 99 | }; | ||
| 94 | module_param(channel_mask, channel_mask, 0644); | 100 | module_param(channel_mask, channel_mask, 0644); |
| 95 | MODULE_PARM_DESC(channel_mask, "Bitmask of channels to accept <15:Channel16>...<1:Channel2><0:Channel1>"); | 101 | MODULE_PARM_DESC(channel_mask, "Bitmask of channels to accept <15:Channel16>...<1:Channel2><0:Channel1>"); |
| 96 | 102 | ||
| 97 | static unsigned int mode_mask = ATI_REMOTE2_MAX_MODE_MASK; | 103 | static unsigned int mode_mask = ATI_REMOTE2_MAX_MODE_MASK; |
| 98 | #define param_check_mode_mask(name, p) __param_check(name, p, unsigned int) | 104 | #define param_check_mode_mask(name, p) __param_check(name, p, unsigned int) |
| 99 | #define param_set_mode_mask ati_remote2_set_mode_mask | 105 | static struct kernel_param_ops param_ops_mode_mask = { |
| 100 | #define param_get_mode_mask ati_remote2_get_mode_mask | 106 | .set = ati_remote2_set_mode_mask, |
| 107 | .get = ati_remote2_get_mode_mask, | ||
| 108 | }; | ||
| 101 | module_param(mode_mask, mode_mask, 0644); | 109 | module_param(mode_mask, mode_mask, 0644); |
| 102 | MODULE_PARM_DESC(mode_mask, "Bitmask of modes to accept <4:PC><3:AUX4><2:AUX3><1:AUX2><0:AUX1>"); | 110 | MODULE_PARM_DESC(mode_mask, "Bitmask of modes to accept <4:PC><3:AUX4><2:AUX3><1:AUX2><0:AUX1>"); |
| 103 | 111 | ||
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 979c50215282..73a7af2542a8 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
| @@ -39,11 +39,13 @@ MODULE_DESCRIPTION(DRIVER_DESC); | |||
| 39 | MODULE_LICENSE("GPL"); | 39 | MODULE_LICENSE("GPL"); |
| 40 | 40 | ||
| 41 | static unsigned int psmouse_max_proto = PSMOUSE_AUTO; | 41 | static unsigned int psmouse_max_proto = PSMOUSE_AUTO; |
| 42 | static int psmouse_set_maxproto(const char *val, struct kernel_param *kp); | 42 | static int psmouse_set_maxproto(const char *val, const struct kernel_param *); |
| 43 | static int psmouse_get_maxproto(char *buffer, struct kernel_param *kp); | 43 | static int psmouse_get_maxproto(char *buffer, const struct kernel_param *kp); |
| 44 | static struct kernel_param_ops param_ops_proto_abbrev = { | ||
| 45 | .set = psmouse_set_maxproto, | ||
| 46 | .get = psmouse_get_maxproto, | ||
| 47 | }; | ||
| 44 | #define param_check_proto_abbrev(name, p) __param_check(name, p, unsigned int) | 48 | #define param_check_proto_abbrev(name, p) __param_check(name, p, unsigned int) |
| 45 | #define param_set_proto_abbrev psmouse_set_maxproto | ||
| 46 | #define param_get_proto_abbrev psmouse_get_maxproto | ||
| 47 | module_param_named(proto, psmouse_max_proto, proto_abbrev, 0644); | 49 | module_param_named(proto, psmouse_max_proto, proto_abbrev, 0644); |
| 48 | MODULE_PARM_DESC(proto, "Highest protocol extension to probe (bare, imps, exps, any). Useful for KVM switches."); | 50 | MODULE_PARM_DESC(proto, "Highest protocol extension to probe (bare, imps, exps, any). Useful for KVM switches."); |
| 49 | 51 | ||
| @@ -1679,7 +1681,7 @@ static ssize_t psmouse_attr_set_resolution(struct psmouse *psmouse, void *data, | |||
| 1679 | } | 1681 | } |
| 1680 | 1682 | ||
| 1681 | 1683 | ||
| 1682 | static int psmouse_set_maxproto(const char *val, struct kernel_param *kp) | 1684 | static int psmouse_set_maxproto(const char *val, const struct kernel_param *kp) |
| 1683 | { | 1685 | { |
| 1684 | const struct psmouse_protocol *proto; | 1686 | const struct psmouse_protocol *proto; |
| 1685 | 1687 | ||
| @@ -1696,7 +1698,7 @@ static int psmouse_set_maxproto(const char *val, struct kernel_param *kp) | |||
| 1696 | return 0; | 1698 | return 0; |
| 1697 | } | 1699 | } |
| 1698 | 1700 | ||
| 1699 | static int psmouse_get_maxproto(char *buffer, struct kernel_param *kp) | 1701 | static int psmouse_get_maxproto(char *buffer, const struct kernel_param *kp) |
| 1700 | { | 1702 | { |
| 1701 | int type = *((unsigned int *)kp->arg); | 1703 | int type = *((unsigned int *)kp->arg); |
| 1702 | 1704 | ||
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index c54674c482c7..b8f1719d7c02 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c | |||
| @@ -110,8 +110,7 @@ MODULE_PARM_DESC(mpt_debug_level, " debug level - refer to mptdebug.h \ | |||
| 110 | 110 | ||
| 111 | int mpt_fwfault_debug; | 111 | int mpt_fwfault_debug; |
| 112 | EXPORT_SYMBOL(mpt_fwfault_debug); | 112 | EXPORT_SYMBOL(mpt_fwfault_debug); |
| 113 | module_param_call(mpt_fwfault_debug, param_set_int, param_get_int, | 113 | module_param(mpt_fwfault_debug, int, 0600); |
| 114 | &mpt_fwfault_debug, 0600); | ||
| 115 | MODULE_PARM_DESC(mpt_fwfault_debug, "Enable detection of Firmware fault" | 114 | MODULE_PARM_DESC(mpt_fwfault_debug, "Enable detection of Firmware fault" |
| 116 | " and halt Firmware on fault - (default=0)"); | 115 | " and halt Firmware on fault - (default=0)"); |
| 117 | 116 | ||
diff --git a/drivers/misc/lkdtm.c b/drivers/misc/lkdtm.c index 5bfb2a2041b8..ef34de7a8026 100644 --- a/drivers/misc/lkdtm.c +++ b/drivers/misc/lkdtm.c | |||
| @@ -124,9 +124,9 @@ static int count = DEFAULT_COUNT; | |||
| 124 | module_param(recur_count, int, 0644); | 124 | module_param(recur_count, int, 0644); |
| 125 | MODULE_PARM_DESC(recur_count, " Recursion level for the stack overflow test, "\ | 125 | MODULE_PARM_DESC(recur_count, " Recursion level for the stack overflow test, "\ |
| 126 | "default is 10"); | 126 | "default is 10"); |
| 127 | module_param(cpoint_name, charp, 0644); | 127 | module_param(cpoint_name, charp, 0444); |
| 128 | MODULE_PARM_DESC(cpoint_name, " Crash Point, where kernel is to be crashed"); | 128 | MODULE_PARM_DESC(cpoint_name, " Crash Point, where kernel is to be crashed"); |
| 129 | module_param(cpoint_type, charp, 0644); | 129 | module_param(cpoint_type, charp, 0444); |
| 130 | MODULE_PARM_DESC(cpoint_type, " Crash Point Type, action to be taken on "\ | 130 | MODULE_PARM_DESC(cpoint_type, " Crash Point Type, action to be taken on "\ |
| 131 | "hitting the crash point"); | 131 | "hitting the crash point"); |
| 132 | module_param(cpoint_count, int, 0644); | 132 | module_param(cpoint_count, int, 0644); |
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index d771d1650d60..fb2c0927d3cc 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c | |||
| @@ -239,6 +239,7 @@ struct myri10ge_priv { | |||
| 239 | int watchdog_resets; | 239 | int watchdog_resets; |
| 240 | int watchdog_pause; | 240 | int watchdog_pause; |
| 241 | int pause; | 241 | int pause; |
| 242 | bool fw_name_allocated; | ||
| 242 | char *fw_name; | 243 | char *fw_name; |
| 243 | char eeprom_strings[MYRI10GE_EEPROM_STRINGS_SIZE]; | 244 | char eeprom_strings[MYRI10GE_EEPROM_STRINGS_SIZE]; |
| 244 | char *product_code_string; | 245 | char *product_code_string; |
| @@ -271,6 +272,7 @@ MODULE_FIRMWARE("myri10ge_eth_z8e.dat"); | |||
| 271 | MODULE_FIRMWARE("myri10ge_rss_ethp_z8e.dat"); | 272 | MODULE_FIRMWARE("myri10ge_rss_ethp_z8e.dat"); |
| 272 | MODULE_FIRMWARE("myri10ge_rss_eth_z8e.dat"); | 273 | MODULE_FIRMWARE("myri10ge_rss_eth_z8e.dat"); |
| 273 | 274 | ||
| 275 | /* Careful: must be accessed under kparam_block_sysfs_write */ | ||
| 274 | static char *myri10ge_fw_name = NULL; | 276 | static char *myri10ge_fw_name = NULL; |
| 275 | module_param(myri10ge_fw_name, charp, S_IRUGO | S_IWUSR); | 277 | module_param(myri10ge_fw_name, charp, S_IRUGO | S_IWUSR); |
| 276 | MODULE_PARM_DESC(myri10ge_fw_name, "Firmware image name"); | 278 | MODULE_PARM_DESC(myri10ge_fw_name, "Firmware image name"); |
| @@ -376,6 +378,14 @@ static inline void put_be32(__be32 val, __be32 __iomem * p) | |||
| 376 | 378 | ||
| 377 | static struct net_device_stats *myri10ge_get_stats(struct net_device *dev); | 379 | static struct net_device_stats *myri10ge_get_stats(struct net_device *dev); |
| 378 | 380 | ||
| 381 | static void set_fw_name(struct myri10ge_priv *mgp, char *name, bool allocated) | ||
| 382 | { | ||
| 383 | if (mgp->fw_name_allocated) | ||
| 384 | kfree(mgp->fw_name); | ||
| 385 | mgp->fw_name = name; | ||
| 386 | mgp->fw_name_allocated = allocated; | ||
| 387 | } | ||
| 388 | |||
| 379 | static int | 389 | static int |
| 380 | myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd, | 390 | myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd, |
| 381 | struct myri10ge_cmd *data, int atomic) | 391 | struct myri10ge_cmd *data, int atomic) |
| @@ -747,7 +757,7 @@ static int myri10ge_load_firmware(struct myri10ge_priv *mgp, int adopt) | |||
| 747 | dev_warn(&mgp->pdev->dev, "via hotplug\n"); | 757 | dev_warn(&mgp->pdev->dev, "via hotplug\n"); |
| 748 | } | 758 | } |
| 749 | 759 | ||
| 750 | mgp->fw_name = "adopted"; | 760 | set_fw_name(mgp, "adopted", false); |
| 751 | mgp->tx_boundary = 2048; | 761 | mgp->tx_boundary = 2048; |
| 752 | myri10ge_dummy_rdma(mgp, 1); | 762 | myri10ge_dummy_rdma(mgp, 1); |
| 753 | status = myri10ge_get_firmware_capabilities(mgp); | 763 | status = myri10ge_get_firmware_capabilities(mgp); |
| @@ -3233,7 +3243,7 @@ static void myri10ge_firmware_probe(struct myri10ge_priv *mgp) | |||
| 3233 | * load the optimized firmware (which assumes aligned PCIe | 3243 | * load the optimized firmware (which assumes aligned PCIe |
| 3234 | * completions) in order to see if it works on this host. | 3244 | * completions) in order to see if it works on this host. |
| 3235 | */ | 3245 | */ |
| 3236 | mgp->fw_name = myri10ge_fw_aligned; | 3246 | set_fw_name(mgp, myri10ge_fw_aligned, false); |
| 3237 | status = myri10ge_load_firmware(mgp, 1); | 3247 | status = myri10ge_load_firmware(mgp, 1); |
| 3238 | if (status != 0) { | 3248 | if (status != 0) { |
| 3239 | goto abort; | 3249 | goto abort; |
| @@ -3261,7 +3271,7 @@ static void myri10ge_firmware_probe(struct myri10ge_priv *mgp) | |||
| 3261 | abort: | 3271 | abort: |
| 3262 | /* fall back to using the unaligned firmware */ | 3272 | /* fall back to using the unaligned firmware */ |
| 3263 | mgp->tx_boundary = 2048; | 3273 | mgp->tx_boundary = 2048; |
| 3264 | mgp->fw_name = myri10ge_fw_unaligned; | 3274 | set_fw_name(mgp, myri10ge_fw_unaligned, false); |
| 3265 | 3275 | ||
| 3266 | } | 3276 | } |
| 3267 | 3277 | ||
| @@ -3284,7 +3294,7 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp) | |||
| 3284 | dev_info(&mgp->pdev->dev, "PCIE x%d Link\n", | 3294 | dev_info(&mgp->pdev->dev, "PCIE x%d Link\n", |
| 3285 | link_width); | 3295 | link_width); |
| 3286 | mgp->tx_boundary = 4096; | 3296 | mgp->tx_boundary = 4096; |
| 3287 | mgp->fw_name = myri10ge_fw_aligned; | 3297 | set_fw_name(mgp, myri10ge_fw_aligned, false); |
| 3288 | } else { | 3298 | } else { |
| 3289 | myri10ge_firmware_probe(mgp); | 3299 | myri10ge_firmware_probe(mgp); |
| 3290 | } | 3300 | } |
| @@ -3293,22 +3303,29 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp) | |||
| 3293 | dev_info(&mgp->pdev->dev, | 3303 | dev_info(&mgp->pdev->dev, |
| 3294 | "Assuming aligned completions (forced)\n"); | 3304 | "Assuming aligned completions (forced)\n"); |
| 3295 | mgp->tx_boundary = 4096; | 3305 | mgp->tx_boundary = 4096; |
| 3296 | mgp->fw_name = myri10ge_fw_aligned; | 3306 | set_fw_name(mgp, myri10ge_fw_aligned, false); |
| 3297 | } else { | 3307 | } else { |
| 3298 | dev_info(&mgp->pdev->dev, | 3308 | dev_info(&mgp->pdev->dev, |
| 3299 | "Assuming unaligned completions (forced)\n"); | 3309 | "Assuming unaligned completions (forced)\n"); |
| 3300 | mgp->tx_boundary = 2048; | 3310 | mgp->tx_boundary = 2048; |
| 3301 | mgp->fw_name = myri10ge_fw_unaligned; | 3311 | set_fw_name(mgp, myri10ge_fw_unaligned, false); |
| 3302 | } | 3312 | } |
| 3303 | } | 3313 | } |
| 3314 | |||
| 3315 | kparam_block_sysfs_write(myri10ge_fw_name); | ||
| 3304 | if (myri10ge_fw_name != NULL) { | 3316 | if (myri10ge_fw_name != NULL) { |
| 3305 | overridden = 1; | 3317 | char *fw_name = kstrdup(myri10ge_fw_name, GFP_KERNEL); |
| 3306 | mgp->fw_name = myri10ge_fw_name; | 3318 | if (fw_name) { |
| 3319 | overridden = 1; | ||
| 3320 | set_fw_name(mgp, fw_name, true); | ||
| 3321 | } | ||
| 3307 | } | 3322 | } |
| 3323 | kparam_unblock_sysfs_write(myri10ge_fw_name); | ||
| 3324 | |||
| 3308 | if (mgp->board_number < MYRI10GE_MAX_BOARDS && | 3325 | if (mgp->board_number < MYRI10GE_MAX_BOARDS && |
| 3309 | myri10ge_fw_names[mgp->board_number] != NULL && | 3326 | myri10ge_fw_names[mgp->board_number] != NULL && |
| 3310 | strlen(myri10ge_fw_names[mgp->board_number])) { | 3327 | strlen(myri10ge_fw_names[mgp->board_number])) { |
| 3311 | mgp->fw_name = myri10ge_fw_names[mgp->board_number]; | 3328 | set_fw_name(mgp, myri10ge_fw_names[mgp->board_number], false); |
| 3312 | overridden = 1; | 3329 | overridden = 1; |
| 3313 | } | 3330 | } |
| 3314 | if (overridden) | 3331 | if (overridden) |
| @@ -3660,6 +3677,7 @@ static void myri10ge_probe_slices(struct myri10ge_priv *mgp) | |||
| 3660 | struct myri10ge_cmd cmd; | 3677 | struct myri10ge_cmd cmd; |
| 3661 | struct pci_dev *pdev = mgp->pdev; | 3678 | struct pci_dev *pdev = mgp->pdev; |
| 3662 | char *old_fw; | 3679 | char *old_fw; |
| 3680 | bool old_allocated; | ||
| 3663 | int i, status, ncpus, msix_cap; | 3681 | int i, status, ncpus, msix_cap; |
| 3664 | 3682 | ||
| 3665 | mgp->num_slices = 1; | 3683 | mgp->num_slices = 1; |
| @@ -3672,17 +3690,23 @@ static void myri10ge_probe_slices(struct myri10ge_priv *mgp) | |||
| 3672 | 3690 | ||
| 3673 | /* try to load the slice aware rss firmware */ | 3691 | /* try to load the slice aware rss firmware */ |
| 3674 | old_fw = mgp->fw_name; | 3692 | old_fw = mgp->fw_name; |
| 3693 | old_allocated = mgp->fw_name_allocated; | ||
| 3694 | /* don't free old_fw if we override it. */ | ||
| 3695 | mgp->fw_name_allocated = false; | ||
| 3696 | |||
| 3675 | if (myri10ge_fw_name != NULL) { | 3697 | if (myri10ge_fw_name != NULL) { |
| 3676 | dev_info(&mgp->pdev->dev, "overriding rss firmware to %s\n", | 3698 | dev_info(&mgp->pdev->dev, "overriding rss firmware to %s\n", |
| 3677 | myri10ge_fw_name); | 3699 | myri10ge_fw_name); |
| 3678 | mgp->fw_name = myri10ge_fw_name; | 3700 | set_fw_name(mgp, myri10ge_fw_name, false); |
| 3679 | } else if (old_fw == myri10ge_fw_aligned) | 3701 | } else if (old_fw == myri10ge_fw_aligned) |
| 3680 | mgp->fw_name = myri10ge_fw_rss_aligned; | 3702 | set_fw_name(mgp, myri10ge_fw_rss_aligned, false); |
| 3681 | else | 3703 | else |
| 3682 | mgp->fw_name = myri10ge_fw_rss_unaligned; | 3704 | set_fw_name(mgp, myri10ge_fw_rss_unaligned, false); |
| 3683 | status = myri10ge_load_firmware(mgp, 0); | 3705 | status = myri10ge_load_firmware(mgp, 0); |
| 3684 | if (status != 0) { | 3706 | if (status != 0) { |
| 3685 | dev_info(&pdev->dev, "Rss firmware not found\n"); | 3707 | dev_info(&pdev->dev, "Rss firmware not found\n"); |
| 3708 | if (old_allocated) | ||
| 3709 | kfree(old_fw); | ||
| 3686 | return; | 3710 | return; |
| 3687 | } | 3711 | } |
| 3688 | 3712 | ||
| @@ -3747,6 +3771,8 @@ static void myri10ge_probe_slices(struct myri10ge_priv *mgp) | |||
| 3747 | mgp->num_slices); | 3771 | mgp->num_slices); |
| 3748 | if (status == 0) { | 3772 | if (status == 0) { |
| 3749 | pci_disable_msix(pdev); | 3773 | pci_disable_msix(pdev); |
| 3774 | if (old_allocated) | ||
| 3775 | kfree(old_fw); | ||
| 3750 | return; | 3776 | return; |
| 3751 | } | 3777 | } |
| 3752 | if (status > 0) | 3778 | if (status > 0) |
| @@ -3763,7 +3789,7 @@ disable_msix: | |||
| 3763 | 3789 | ||
| 3764 | abort_with_fw: | 3790 | abort_with_fw: |
| 3765 | mgp->num_slices = 1; | 3791 | mgp->num_slices = 1; |
| 3766 | mgp->fw_name = old_fw; | 3792 | set_fw_name(mgp, old_fw, old_allocated); |
| 3767 | myri10ge_load_firmware(mgp, 0); | 3793 | myri10ge_load_firmware(mgp, 0); |
| 3768 | } | 3794 | } |
| 3769 | 3795 | ||
| @@ -3993,6 +4019,7 @@ abort_with_enabled: | |||
| 3993 | pci_disable_device(pdev); | 4019 | pci_disable_device(pdev); |
| 3994 | 4020 | ||
| 3995 | abort_with_netdev: | 4021 | abort_with_netdev: |
| 4022 | set_fw_name(mgp, NULL, false); | ||
| 3996 | free_netdev(netdev); | 4023 | free_netdev(netdev); |
| 3997 | return status; | 4024 | return status; |
| 3998 | } | 4025 | } |
| @@ -4037,6 +4064,7 @@ static void myri10ge_remove(struct pci_dev *pdev) | |||
| 4037 | dma_free_coherent(&pdev->dev, sizeof(*mgp->cmd), | 4064 | dma_free_coherent(&pdev->dev, sizeof(*mgp->cmd), |
| 4038 | mgp->cmd, mgp->cmd_bus); | 4065 | mgp->cmd, mgp->cmd_bus); |
| 4039 | 4066 | ||
| 4067 | set_fw_name(mgp, NULL, false); | ||
| 4040 | free_netdev(netdev); | 4068 | free_netdev(netdev); |
| 4041 | pci_disable_device(pdev); | 4069 | pci_disable_device(pdev); |
| 4042 | pci_set_drvdata(pdev, NULL); | 4070 | pci_set_drvdata(pdev, NULL); |
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index 6e71346a7550..ba854c70ab94 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c | |||
| @@ -125,6 +125,8 @@ struct if_sdio_card { | |||
| 125 | 125 | ||
| 126 | const char *helper; | 126 | const char *helper; |
| 127 | const char *firmware; | 127 | const char *firmware; |
| 128 | bool helper_allocated; | ||
| 129 | bool firmware_allocated; | ||
| 128 | 130 | ||
| 129 | u8 buffer[65536]; | 131 | u8 buffer[65536]; |
| 130 | 132 | ||
| @@ -984,16 +986,34 @@ static int if_sdio_probe(struct sdio_func *func, | |||
| 984 | card->helper = if_sdio_models[i].helper; | 986 | card->helper = if_sdio_models[i].helper; |
| 985 | card->firmware = if_sdio_models[i].firmware; | 987 | card->firmware = if_sdio_models[i].firmware; |
| 986 | 988 | ||
| 989 | kparam_block_sysfs_write(helper_name); | ||
| 987 | if (lbs_helper_name) { | 990 | if (lbs_helper_name) { |
| 991 | char *helper = kstrdup(lbs_helper_name, GFP_KERNEL); | ||
| 992 | if (!helper) { | ||
| 993 | kparam_unblock_sysfs_write(helper_name); | ||
| 994 | ret = -ENOMEM; | ||
| 995 | goto free; | ||
| 996 | } | ||
| 988 | lbs_deb_sdio("overriding helper firmware: %s\n", | 997 | lbs_deb_sdio("overriding helper firmware: %s\n", |
| 989 | lbs_helper_name); | 998 | lbs_helper_name); |
| 990 | card->helper = lbs_helper_name; | 999 | card->helper = helper; |
| 1000 | card->helper_allocated = true; | ||
| 991 | } | 1001 | } |
| 1002 | kparam_unblock_sysfs_write(helper_name); | ||
| 992 | 1003 | ||
| 1004 | kparam_block_sysfs_write(fw_name); | ||
| 993 | if (lbs_fw_name) { | 1005 | if (lbs_fw_name) { |
| 1006 | char *fw_name = kstrdup(lbs_fw_name, GFP_KERNEL); | ||
| 1007 | if (!fw_name) { | ||
| 1008 | kparam_unblock_sysfs_write(fw_name); | ||
| 1009 | ret = -ENOMEM; | ||
| 1010 | goto free; | ||
| 1011 | } | ||
| 994 | lbs_deb_sdio("overriding firmware: %s\n", lbs_fw_name); | 1012 | lbs_deb_sdio("overriding firmware: %s\n", lbs_fw_name); |
| 995 | card->firmware = lbs_fw_name; | 1013 | card->firmware = fw_name; |
| 1014 | card->firmware_allocated = true; | ||
| 996 | } | 1015 | } |
| 1016 | kparam_unblock_sysfs_write(fw_name); | ||
| 997 | 1017 | ||
| 998 | sdio_claim_host(func); | 1018 | sdio_claim_host(func); |
| 999 | 1019 | ||
| @@ -1127,6 +1147,10 @@ free: | |||
| 1127 | kfree(packet); | 1147 | kfree(packet); |
| 1128 | } | 1148 | } |
| 1129 | 1149 | ||
| 1150 | if (card->helper_allocated) | ||
| 1151 | kfree(card->helper); | ||
| 1152 | if (card->firmware_allocated) | ||
| 1153 | kfree(card->firmware); | ||
| 1130 | kfree(card); | 1154 | kfree(card); |
| 1131 | 1155 | ||
| 1132 | goto out; | 1156 | goto out; |
| @@ -1177,6 +1201,10 @@ static void if_sdio_remove(struct sdio_func *func) | |||
| 1177 | kfree(packet); | 1201 | kfree(packet); |
| 1178 | } | 1202 | } |
| 1179 | 1203 | ||
| 1204 | if (card->helper_allocated) | ||
| 1205 | kfree(card->helper); | ||
| 1206 | if (card->firmware_allocated) | ||
| 1207 | kfree(card->firmware); | ||
| 1180 | kfree(card); | 1208 | kfree(card); |
| 1181 | 1209 | ||
| 1182 | lbs_deb_leave(LBS_DEB_SDIO); | 1210 | lbs_deb_leave(LBS_DEB_SDIO); |
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c index 07ece9d26c63..3ff61063671a 100644 --- a/drivers/net/wireless/libertas/if_usb.c +++ b/drivers/net/wireless/libertas/if_usb.c | |||
| @@ -289,10 +289,13 @@ static int if_usb_probe(struct usb_interface *intf, | |||
| 289 | } | 289 | } |
| 290 | 290 | ||
| 291 | /* Upload firmware */ | 291 | /* Upload firmware */ |
| 292 | kparam_block_sysfs_write(fw_name); | ||
| 292 | if (__if_usb_prog_firmware(cardp, lbs_fw_name, BOOT_CMD_FW_BY_USB)) { | 293 | if (__if_usb_prog_firmware(cardp, lbs_fw_name, BOOT_CMD_FW_BY_USB)) { |
| 294 | kparam_unblock_sysfs_write(fw_name); | ||
| 293 | lbs_deb_usbd(&udev->dev, "FW upload failed\n"); | 295 | lbs_deb_usbd(&udev->dev, "FW upload failed\n"); |
| 294 | goto err_prog_firmware; | 296 | goto err_prog_firmware; |
| 295 | } | 297 | } |
| 298 | kparam_unblock_sysfs_write(fw_name); | ||
| 296 | 299 | ||
| 297 | if (!(priv = lbs_add_card(cardp, &udev->dev))) | 300 | if (!(priv = lbs_add_card(cardp, &udev->dev))) |
| 298 | goto err_prog_firmware; | 301 | goto err_prog_firmware; |
diff --git a/drivers/net/wireless/libertas_tf/if_usb.c b/drivers/net/wireless/libertas_tf/if_usb.c index b172f5d87a3b..41a4f214ade1 100644 --- a/drivers/net/wireless/libertas_tf/if_usb.c +++ b/drivers/net/wireless/libertas_tf/if_usb.c | |||
| @@ -811,12 +811,15 @@ static int if_usb_prog_firmware(struct if_usb_card *cardp) | |||
| 811 | 811 | ||
| 812 | lbtf_deb_enter(LBTF_DEB_USB); | 812 | lbtf_deb_enter(LBTF_DEB_USB); |
| 813 | 813 | ||
| 814 | kparam_block_sysfs_write(fw_name); | ||
| 814 | ret = request_firmware(&cardp->fw, lbtf_fw_name, &cardp->udev->dev); | 815 | ret = request_firmware(&cardp->fw, lbtf_fw_name, &cardp->udev->dev); |
| 815 | if (ret < 0) { | 816 | if (ret < 0) { |
| 816 | pr_err("request_firmware() failed with %#x\n", ret); | 817 | pr_err("request_firmware() failed with %#x\n", ret); |
| 817 | pr_err("firmware %s not found\n", lbtf_fw_name); | 818 | pr_err("firmware %s not found\n", lbtf_fw_name); |
| 819 | kparam_unblock_sysfs_write(fw_name); | ||
| 818 | goto done; | 820 | goto done; |
| 819 | } | 821 | } |
| 822 | kparam_unblock_sysfs_write(fw_name); | ||
| 820 | 823 | ||
| 821 | if (check_fwfile_format(cardp->fw->data, cardp->fw->size)) | 824 | if (check_fwfile_format(cardp->fw->data, cardp->fw->size)) |
| 822 | goto release_fw; | 825 | goto release_fw; |
diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c index 915a29d6c7ad..ca04cc9d332f 100644 --- a/drivers/scsi/bfa/bfad.c +++ b/drivers/scsi/bfa/bfad.c | |||
| @@ -788,6 +788,7 @@ bfad_drv_init(struct bfad_s *bfad) | |||
| 788 | memset(&driver_info, 0, sizeof(driver_info)); | 788 | memset(&driver_info, 0, sizeof(driver_info)); |
| 789 | strncpy(driver_info.version, BFAD_DRIVER_VERSION, | 789 | strncpy(driver_info.version, BFAD_DRIVER_VERSION, |
| 790 | sizeof(driver_info.version) - 1); | 790 | sizeof(driver_info.version) - 1); |
| 791 | __kernel_param_lock(); | ||
| 791 | if (host_name) | 792 | if (host_name) |
| 792 | strncpy(driver_info.host_machine_name, host_name, | 793 | strncpy(driver_info.host_machine_name, host_name, |
| 793 | sizeof(driver_info.host_machine_name) - 1); | 794 | sizeof(driver_info.host_machine_name) - 1); |
| @@ -797,6 +798,7 @@ bfad_drv_init(struct bfad_s *bfad) | |||
| 797 | if (os_patch) | 798 | if (os_patch) |
| 798 | strncpy(driver_info.host_os_patch, os_patch, | 799 | strncpy(driver_info.host_os_patch, os_patch, |
| 799 | sizeof(driver_info.host_os_patch) - 1); | 800 | sizeof(driver_info.host_os_patch) - 1); |
| 801 | __kernel_param_unlock(); | ||
| 800 | 802 | ||
| 801 | strncpy(driver_info.os_device_name, bfad->pci_name, | 803 | strncpy(driver_info.os_device_name, bfad->pci_name, |
| 802 | sizeof(driver_info.os_device_name - 1)); | 804 | sizeof(driver_info.os_device_name - 1)); |
diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index 49ab9fa9ffa7..ed7457bc24ea 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c | |||
| @@ -61,7 +61,7 @@ static struct pci_device_id rtl8180_pci_id_tbl[] __devinitdata = { | |||
| 61 | }; | 61 | }; |
| 62 | 62 | ||
| 63 | 63 | ||
| 64 | static char *ifname = "wlan%d"; | 64 | static char ifname[IFNAMSIZ] = "wlan%d"; |
| 65 | static int hwseqnum = 0; | 65 | static int hwseqnum = 0; |
| 66 | static int hwwep = 0; | 66 | static int hwwep = 0; |
| 67 | static int channels = 0x3fff; | 67 | static int channels = 0x3fff; |
| @@ -72,7 +72,7 @@ MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>"); | |||
| 72 | MODULE_DESCRIPTION("Linux driver for Realtek RTL8180 / RTL8185 WiFi cards"); | 72 | MODULE_DESCRIPTION("Linux driver for Realtek RTL8180 / RTL8185 WiFi cards"); |
| 73 | 73 | ||
| 74 | 74 | ||
| 75 | module_param(ifname, charp, S_IRUGO|S_IWUSR); | 75 | module_param_string(ifname, ifname, sizeof(ifname), S_IRUGO|S_IWUSR); |
| 76 | module_param(hwseqnum, int, S_IRUGO|S_IWUSR); | 76 | module_param(hwseqnum, int, S_IRUGO|S_IWUSR); |
| 77 | module_param(hwwep, int, S_IRUGO|S_IWUSR); | 77 | module_param(hwwep, int, S_IRUGO|S_IWUSR); |
| 78 | module_param(channels, int, S_IRUGO|S_IWUSR); | 78 | module_param(channels, int, S_IRUGO|S_IWUSR); |
| @@ -3609,7 +3609,7 @@ static int __devinit rtl8180_pci_probe(struct pci_dev *pdev, | |||
| 3609 | 3609 | ||
| 3610 | if (dev_alloc_name(dev, ifname) < 0) { | 3610 | if (dev_alloc_name(dev, ifname) < 0) { |
| 3611 | DMESG("Oops: devname already taken! Trying wlan%%d...\n"); | 3611 | DMESG("Oops: devname already taken! Trying wlan%%d...\n"); |
| 3612 | ifname = "wlan%d"; | 3612 | strcpy(ifname, "wlan%d"); |
| 3613 | dev_alloc_name(dev, ifname); | 3613 | dev_alloc_name(dev, ifname); |
| 3614 | } | 3614 | } |
| 3615 | 3615 | ||
diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 4cd071adf84b..17a806f9ee77 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c | |||
| @@ -112,7 +112,7 @@ static const struct pci_device_id rtl8192_pci_id_tbl[] __devinitdata = { | |||
| 112 | {} | 112 | {} |
| 113 | }; | 113 | }; |
| 114 | 114 | ||
| 115 | static char* ifname = "wlan%d"; | 115 | static char ifname[IFNAMSIZ] = "wlan%d"; |
| 116 | static int hwwep = 1; //default use hw. set 0 to use software security | 116 | static int hwwep = 1; //default use hw. set 0 to use software security |
| 117 | static int channels = 0x3fff; | 117 | static int channels = 0x3fff; |
| 118 | 118 | ||
| @@ -123,7 +123,7 @@ MODULE_DEVICE_TABLE(pci, rtl8192_pci_id_tbl); | |||
| 123 | MODULE_DESCRIPTION("Linux driver for Realtek RTL819x WiFi cards"); | 123 | MODULE_DESCRIPTION("Linux driver for Realtek RTL819x WiFi cards"); |
| 124 | 124 | ||
| 125 | 125 | ||
| 126 | module_param(ifname, charp, S_IRUGO|S_IWUSR ); | 126 | module_param_string(ifname, ifname, sizeof(ifname), S_IRUGO|S_IWUSR); |
| 127 | //module_param(hwseqnum,int, S_IRUGO|S_IWUSR); | 127 | //module_param(hwseqnum,int, S_IRUGO|S_IWUSR); |
| 128 | module_param(hwwep,int, S_IRUGO|S_IWUSR); | 128 | module_param(hwwep,int, S_IRUGO|S_IWUSR); |
| 129 | module_param(channels,int, S_IRUGO|S_IWUSR); | 129 | module_param(channels,int, S_IRUGO|S_IWUSR); |
| @@ -6446,7 +6446,7 @@ static int __devinit rtl8192_pci_probe(struct pci_dev *pdev, | |||
| 6446 | 6446 | ||
| 6447 | if (dev_alloc_name(dev, ifname) < 0){ | 6447 | if (dev_alloc_name(dev, ifname) < 0){ |
| 6448 | RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n"); | 6448 | RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n"); |
| 6449 | ifname = "wlan%d"; | 6449 | strcpy(ifname, "wlan%d"); |
| 6450 | dev_alloc_name(dev, ifname); | 6450 | dev_alloc_name(dev, ifname); |
| 6451 | } | 6451 | } |
| 6452 | 6452 | ||
diff --git a/drivers/staging/rtl8192su/r8192U_core.c b/drivers/staging/rtl8192su/r8192U_core.c index 6970c97713d8..df5b52baf893 100644 --- a/drivers/staging/rtl8192su/r8192U_core.c +++ b/drivers/staging/rtl8192su/r8192U_core.c | |||
| @@ -144,13 +144,13 @@ MODULE_VERSION("V 1.1"); | |||
| 144 | MODULE_DEVICE_TABLE(usb, rtl8192_usb_id_tbl); | 144 | MODULE_DEVICE_TABLE(usb, rtl8192_usb_id_tbl); |
| 145 | MODULE_DESCRIPTION("Linux driver for Realtek RTL8192 USB WiFi cards"); | 145 | MODULE_DESCRIPTION("Linux driver for Realtek RTL8192 USB WiFi cards"); |
| 146 | 146 | ||
| 147 | static char* ifname = "wlan%d"; | 147 | static char ifname[IFNAMSIZ] = "wlan%d"; |
| 148 | static int hwwep = 1; //default use hw. set 0 to use software security | 148 | static int hwwep = 1; //default use hw. set 0 to use software security |
| 149 | static int channels = 0x3fff; | 149 | static int channels = 0x3fff; |
| 150 | 150 | ||
| 151 | 151 | ||
| 152 | 152 | ||
| 153 | module_param(ifname, charp, S_IRUGO|S_IWUSR ); | 153 | module_param_string(ifname, ifname, sizeof(ifname), S_IRUGO|S_IWUSR); |
| 154 | //module_param(hwseqnum,int, S_IRUGO|S_IWUSR); | 154 | //module_param(hwseqnum,int, S_IRUGO|S_IWUSR); |
| 155 | module_param(hwwep,int, S_IRUGO|S_IWUSR); | 155 | module_param(hwwep,int, S_IRUGO|S_IWUSR); |
| 156 | module_param(channels,int, S_IRUGO|S_IWUSR); | 156 | module_param(channels,int, S_IRUGO|S_IWUSR); |
| @@ -7406,7 +7406,7 @@ static int __devinit rtl8192_usb_probe(struct usb_interface *intf, | |||
| 7406 | 7406 | ||
| 7407 | if (dev_alloc_name(dev, ifname) < 0){ | 7407 | if (dev_alloc_name(dev, ifname) < 0){ |
| 7408 | RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n"); | 7408 | RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n"); |
| 7409 | ifname = "wlan%d"; | 7409 | strcpy(ifname, "wlan%d"); |
| 7410 | dev_alloc_name(dev, ifname); | 7410 | dev_alloc_name(dev, ifname); |
| 7411 | } | 7411 | } |
| 7412 | 7412 | ||
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index 5b3f555e01c9..ea071a5b6eee 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c | |||
| @@ -1577,6 +1577,7 @@ static void cmvs_file_name(struct uea_softc *sc, char *const cmv_name, int ver) | |||
| 1577 | char file_arr[] = "CMVxy.bin"; | 1577 | char file_arr[] = "CMVxy.bin"; |
| 1578 | char *file; | 1578 | char *file; |
| 1579 | 1579 | ||
| 1580 | kparam_block_sysfs_write(cmv_file); | ||
| 1580 | /* set proper name corresponding modem version and line type */ | 1581 | /* set proper name corresponding modem version and line type */ |
| 1581 | if (cmv_file[sc->modem_index] == NULL) { | 1582 | if (cmv_file[sc->modem_index] == NULL) { |
| 1582 | if (UEA_CHIP_VERSION(sc) == ADI930) | 1583 | if (UEA_CHIP_VERSION(sc) == ADI930) |
| @@ -1595,6 +1596,7 @@ static void cmvs_file_name(struct uea_softc *sc, char *const cmv_name, int ver) | |||
| 1595 | strlcat(cmv_name, file, UEA_FW_NAME_MAX); | 1596 | strlcat(cmv_name, file, UEA_FW_NAME_MAX); |
| 1596 | if (ver == 2) | 1597 | if (ver == 2) |
| 1597 | strlcat(cmv_name, ".v2", UEA_FW_NAME_MAX); | 1598 | strlcat(cmv_name, ".v2", UEA_FW_NAME_MAX); |
| 1599 | kparam_unblock_sysfs_write(cmv_file); | ||
| 1598 | } | 1600 | } |
| 1599 | 1601 | ||
| 1600 | static int request_cmvs_old(struct uea_softc *sc, | 1602 | static int request_cmvs_old(struct uea_softc *sc, |
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c index 7b8839ebf3c4..52ec0959d462 100644 --- a/drivers/video/uvesafb.c +++ b/drivers/video/uvesafb.c | |||
| @@ -1977,8 +1977,7 @@ static void __devexit uvesafb_exit(void) | |||
| 1977 | 1977 | ||
| 1978 | module_exit(uvesafb_exit); | 1978 | module_exit(uvesafb_exit); |
| 1979 | 1979 | ||
| 1980 | #define param_get_scroll NULL | 1980 | static int param_set_scroll(const char *val, const struct kernel_param *kp) |
| 1981 | static int param_set_scroll(const char *val, struct kernel_param *kp) | ||
| 1982 | { | 1981 | { |
| 1983 | ypan = 0; | 1982 | ypan = 0; |
| 1984 | 1983 | ||
| @@ -1993,7 +1992,9 @@ static int param_set_scroll(const char *val, struct kernel_param *kp) | |||
| 1993 | 1992 | ||
| 1994 | return 0; | 1993 | return 0; |
| 1995 | } | 1994 | } |
| 1996 | 1995 | static struct kernel_param_ops param_ops_scroll = { | |
| 1996 | .set = param_set_scroll, | ||
| 1997 | }; | ||
| 1997 | #define param_check_scroll(name, p) __param_check(name, p, void) | 1998 | #define param_check_scroll(name, p) __param_check(name, p, void) |
| 1998 | 1999 | ||
| 1999 | module_param_named(scroll, ypan, scroll, 0); | 2000 | module_param_named(scroll, ypan, scroll, 0); |
diff --git a/drivers/video/vt8623fb.c b/drivers/video/vt8623fb.c index d31dc96f838a..85d76ec4c63e 100644 --- a/drivers/video/vt8623fb.c +++ b/drivers/video/vt8623fb.c | |||
| @@ -726,7 +726,9 @@ static int __devinit vt8623_pci_probe(struct pci_dev *dev, const struct pci_devi | |||
| 726 | 726 | ||
| 727 | /* Prepare startup mode */ | 727 | /* Prepare startup mode */ |
| 728 | 728 | ||
| 729 | kparam_block_sysfs_write(mode_option); | ||
| 729 | rc = fb_find_mode(&(info->var), info, mode_option, NULL, 0, NULL, 8); | 730 | rc = fb_find_mode(&(info->var), info, mode_option, NULL, 0, NULL, 8); |
| 731 | kparam_unblock_sysfs_write(mode_option); | ||
| 730 | if (! ((rc == 1) || (rc == 2))) { | 732 | if (! ((rc == 1) || (rc == 2))) { |
| 731 | rc = -EINVAL; | 733 | rc = -EINVAL; |
| 732 | dev_err(info->device, "mode %s not found\n", mode_option); | 734 | dev_err(info->device, "mode %s not found\n", mode_option); |
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index 36dfdae95123..e17b49e2eabd 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c | |||
| @@ -45,7 +45,7 @@ unsigned short nfs_callback_tcpport; | |||
| 45 | unsigned short nfs_callback_tcpport6; | 45 | unsigned short nfs_callback_tcpport6; |
| 46 | #define NFS_CALLBACK_MAXPORTNR (65535U) | 46 | #define NFS_CALLBACK_MAXPORTNR (65535U) |
| 47 | 47 | ||
| 48 | static int param_set_portnr(const char *val, struct kernel_param *kp) | 48 | static int param_set_portnr(const char *val, const struct kernel_param *kp) |
| 49 | { | 49 | { |
| 50 | unsigned long num; | 50 | unsigned long num; |
| 51 | int ret; | 51 | int ret; |
| @@ -58,11 +58,10 @@ static int param_set_portnr(const char *val, struct kernel_param *kp) | |||
| 58 | *((unsigned int *)kp->arg) = num; | 58 | *((unsigned int *)kp->arg) = num; |
| 59 | return 0; | 59 | return 0; |
| 60 | } | 60 | } |
| 61 | 61 | static struct kernel_param_ops param_ops_portnr = { | |
| 62 | static int param_get_portnr(char *buffer, struct kernel_param *kp) | 62 | .set = param_set_portnr, |
| 63 | { | 63 | .get = param_get_uint, |
| 64 | return param_get_uint(buffer, kp); | 64 | }; |
| 65 | } | ||
| 66 | #define param_check_portnr(name, p) __param_check(name, p, unsigned int); | 65 | #define param_check_portnr(name, p) __param_check(name, p, unsigned int); |
| 67 | 66 | ||
| 68 | module_param_named(callback_tcpport, nfs_callback_set_tcpport, portnr, 0644); | 67 | module_param_named(callback_tcpport, nfs_callback_set_tcpport, portnr, 0644); |
diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h index 82a9124f7d75..9d2f1837b3d8 100644 --- a/include/linux/moduleparam.h +++ b/include/linux/moduleparam.h | |||
| @@ -31,20 +31,23 @@ static const char __module_cat(name,__LINE__)[] \ | |||
| 31 | 31 | ||
| 32 | struct kernel_param; | 32 | struct kernel_param; |
| 33 | 33 | ||
| 34 | /* Returns 0, or -errno. arg is in kp->arg. */ | 34 | struct kernel_param_ops { |
| 35 | typedef int (*param_set_fn)(const char *val, struct kernel_param *kp); | 35 | /* Returns 0, or -errno. arg is in kp->arg. */ |
| 36 | /* Returns length written or -errno. Buffer is 4k (ie. be short!) */ | 36 | int (*set)(const char *val, const struct kernel_param *kp); |
| 37 | typedef int (*param_get_fn)(char *buffer, struct kernel_param *kp); | 37 | /* Returns length written or -errno. Buffer is 4k (ie. be short!) */ |
| 38 | int (*get)(char *buffer, const struct kernel_param *kp); | ||
| 39 | /* Optional function to free kp->arg when module unloaded. */ | ||
| 40 | void (*free)(void *arg); | ||
| 41 | }; | ||
| 38 | 42 | ||
| 39 | /* Flag bits for kernel_param.flags */ | 43 | /* Flag bits for kernel_param.flags */ |
| 40 | #define KPARAM_ISBOOL 2 | 44 | #define KPARAM_ISBOOL 2 |
| 41 | 45 | ||
| 42 | struct kernel_param { | 46 | struct kernel_param { |
| 43 | const char *name; | 47 | const char *name; |
| 48 | const struct kernel_param_ops *ops; | ||
| 44 | u16 perm; | 49 | u16 perm; |
| 45 | u16 flags; | 50 | u16 flags; |
| 46 | param_set_fn set; | ||
| 47 | param_get_fn get; | ||
| 48 | union { | 51 | union { |
| 49 | void *arg; | 52 | void *arg; |
| 50 | const struct kparam_string *str; | 53 | const struct kparam_string *str; |
| @@ -63,12 +66,67 @@ struct kparam_array | |||
| 63 | { | 66 | { |
| 64 | unsigned int max; | 67 | unsigned int max; |
| 65 | unsigned int *num; | 68 | unsigned int *num; |
| 66 | param_set_fn set; | 69 | const struct kernel_param_ops *ops; |
| 67 | param_get_fn get; | ||
| 68 | unsigned int elemsize; | 70 | unsigned int elemsize; |
| 69 | void *elem; | 71 | void *elem; |
| 70 | }; | 72 | }; |
| 71 | 73 | ||
| 74 | /** | ||
| 75 | * module_param - typesafe helper for a module/cmdline parameter | ||
| 76 | * @value: the variable to alter, and exposed parameter name. | ||
| 77 | * @type: the type of the parameter | ||
| 78 | * @perm: visibility in sysfs. | ||
| 79 | * | ||
| 80 | * @value becomes the module parameter, or (prefixed by KBUILD_MODNAME and a | ||
| 81 | * ".") the kernel commandline parameter. Note that - is changed to _, so | ||
| 82 | * the user can use "foo-bar=1" even for variable "foo_bar". | ||
| 83 | * | ||
| 84 | * @perm is 0 if the the variable is not to appear in sysfs, or 0444 | ||
| 85 | * for world-readable, 0644 for root-writable, etc. Note that if it | ||
| 86 | * is writable, you may need to use kparam_block_sysfs_write() around | ||
| 87 | * accesses (esp. charp, which can be kfreed when it changes). | ||
| 88 | * | ||
| 89 | * The @type is simply pasted to refer to a param_ops_##type and a | ||
| 90 | * param_check_##type: for convenience many standard types are provided but | ||
| 91 | * you can create your own by defining those variables. | ||
| 92 | * | ||
| 93 | * Standard types are: | ||
| 94 | * byte, short, ushort, int, uint, long, ulong | ||
| 95 | * charp: a character pointer | ||
| 96 | * bool: a bool, values 0/1, y/n, Y/N. | ||
| 97 | * invbool: the above, only sense-reversed (N = true). | ||
| 98 | */ | ||
| 99 | #define module_param(name, type, perm) \ | ||
| 100 | module_param_named(name, name, type, perm) | ||
| 101 | |||
| 102 | /** | ||
| 103 | * module_param_named - typesafe helper for a renamed module/cmdline parameter | ||
| 104 | * @name: a valid C identifier which is the parameter name. | ||
| 105 | * @value: the actual lvalue to alter. | ||
| 106 | * @type: the type of the parameter | ||
| 107 | * @perm: visibility in sysfs. | ||
| 108 | * | ||
| 109 | * Usually it's a good idea to have variable names and user-exposed names the | ||
| 110 | * same, but that's harder if the variable must be non-static or is inside a | ||
| 111 | * structure. This allows exposure under a different name. | ||
| 112 | */ | ||
| 113 | #define module_param_named(name, value, type, perm) \ | ||
| 114 | param_check_##type(name, &(value)); \ | ||
| 115 | module_param_cb(name, ¶m_ops_##type, &value, perm); \ | ||
| 116 | __MODULE_PARM_TYPE(name, #type) | ||
| 117 | |||
| 118 | /** | ||
| 119 | * module_param_cb - general callback for a module/cmdline parameter | ||
| 120 | * @name: a valid C identifier which is the parameter name. | ||
| 121 | * @ops: the set & get operations for this parameter. | ||
| 122 | * @perm: visibility in sysfs. | ||
| 123 | * | ||
| 124 | * The ops can have NULL set or get functions. | ||
| 125 | */ | ||
| 126 | #define module_param_cb(name, ops, arg, perm) \ | ||
| 127 | __module_param_call(MODULE_PARAM_PREFIX, \ | ||
| 128 | name, ops, arg, __same_type((arg), bool *), perm) | ||
| 129 | |||
| 72 | /* On alpha, ia64 and ppc64 relocations to global data cannot go into | 130 | /* On alpha, ia64 and ppc64 relocations to global data cannot go into |
| 73 | read-only sections (which is part of respective UNIX ABI on these | 131 | read-only sections (which is part of respective UNIX ABI on these |
| 74 | platforms). So 'const' makes no sense and even causes compile failures | 132 | platforms). So 'const' makes no sense and even causes compile failures |
| @@ -80,10 +138,8 @@ struct kparam_array | |||
| 80 | #endif | 138 | #endif |
| 81 | 139 | ||
| 82 | /* This is the fundamental function for registering boot/module | 140 | /* This is the fundamental function for registering boot/module |
| 83 | parameters. perm sets the visibility in sysfs: 000 means it's | 141 | parameters. */ |
| 84 | not there, read bits mean it's readable, write bits mean it's | 142 | #define __module_param_call(prefix, name, ops, arg, isbool, perm) \ |
| 85 | writable. */ | ||
| 86 | #define __module_param_call(prefix, name, set, get, arg, isbool, perm) \ | ||
| 87 | /* Default value instead of permissions? */ \ | 143 | /* Default value instead of permissions? */ \ |
| 88 | static int __param_perm_check_##name __attribute__((unused)) = \ | 144 | static int __param_perm_check_##name __attribute__((unused)) = \ |
| 89 | BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2)) \ | 145 | BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2)) \ |
| @@ -92,31 +148,87 @@ struct kparam_array | |||
| 92 | static struct kernel_param __moduleparam_const __param_##name \ | 148 | static struct kernel_param __moduleparam_const __param_##name \ |
| 93 | __used \ | 149 | __used \ |
| 94 | __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \ | 150 | __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \ |
| 95 | = { __param_str_##name, perm, isbool ? KPARAM_ISBOOL : 0, \ | 151 | = { __param_str_##name, ops, perm, isbool ? KPARAM_ISBOOL : 0, \ |
| 96 | set, get, { arg } } | 152 | { arg } } |
| 153 | |||
| 154 | /* Obsolete - use module_param_cb() */ | ||
| 155 | #define module_param_call(name, set, get, arg, perm) \ | ||
| 156 | static struct kernel_param_ops __param_ops_##name = \ | ||
| 157 | { (void *)set, (void *)get }; \ | ||
| 158 | __module_param_call(MODULE_PARAM_PREFIX, \ | ||
| 159 | name, &__param_ops_##name, arg, \ | ||
| 160 | __same_type(arg, bool *), \ | ||
| 161 | (perm) + sizeof(__check_old_set_param(set))*0) | ||
| 162 | |||
| 163 | /* We don't get oldget: it's often a new-style param_get_uint, etc. */ | ||
| 164 | static inline int | ||
| 165 | __check_old_set_param(int (*oldset)(const char *, struct kernel_param *)) | ||
| 166 | { | ||
| 167 | return 0; | ||
| 168 | } | ||
| 97 | 169 | ||
| 98 | #define module_param_call(name, set, get, arg, perm) \ | 170 | /** |
| 99 | __module_param_call(MODULE_PARAM_PREFIX, \ | 171 | * kparam_block_sysfs_write - make sure a parameter isn't written via sysfs. |
| 100 | name, set, get, arg, \ | 172 | * @name: the name of the parameter |
| 101 | __same_type(*(arg), bool), perm) | 173 | * |
| 174 | * There's no point blocking write on a paramter that isn't writable via sysfs! | ||
| 175 | */ | ||
| 176 | #define kparam_block_sysfs_write(name) \ | ||
| 177 | do { \ | ||
| 178 | BUG_ON(!(__param_##name.perm & 0222)); \ | ||
| 179 | __kernel_param_lock(); \ | ||
| 180 | } while (0) | ||
| 102 | 181 | ||
| 103 | /* Helper functions: type is byte, short, ushort, int, uint, long, | 182 | /** |
| 104 | ulong, charp, bool or invbool, or XXX if you define param_get_XXX, | 183 | * kparam_unblock_sysfs_write - allows sysfs to write to a parameter again. |
| 105 | param_set_XXX and param_check_XXX. */ | 184 | * @name: the name of the parameter |
| 106 | #define module_param_named(name, value, type, perm) \ | 185 | */ |
| 107 | param_check_##type(name, &(value)); \ | 186 | #define kparam_unblock_sysfs_write(name) \ |
| 108 | module_param_call(name, param_set_##type, param_get_##type, &value, perm); \ | 187 | do { \ |
| 109 | __MODULE_PARM_TYPE(name, #type) | 188 | BUG_ON(!(__param_##name.perm & 0222)); \ |
| 189 | __kernel_param_unlock(); \ | ||
| 190 | } while (0) | ||
| 110 | 191 | ||
| 111 | #define module_param(name, type, perm) \ | 192 | /** |
| 112 | module_param_named(name, name, type, perm) | 193 | * kparam_block_sysfs_read - make sure a parameter isn't read via sysfs. |
| 194 | * @name: the name of the parameter | ||
| 195 | * | ||
| 196 | * This also blocks sysfs writes. | ||
| 197 | */ | ||
| 198 | #define kparam_block_sysfs_read(name) \ | ||
| 199 | do { \ | ||
| 200 | BUG_ON(!(__param_##name.perm & 0444)); \ | ||
| 201 | __kernel_param_lock(); \ | ||
| 202 | } while (0) | ||
| 203 | |||
| 204 | /** | ||
| 205 | * kparam_unblock_sysfs_read - allows sysfs to read a parameter again. | ||
| 206 | * @name: the name of the parameter | ||
| 207 | */ | ||
| 208 | #define kparam_unblock_sysfs_read(name) \ | ||
| 209 | do { \ | ||
| 210 | BUG_ON(!(__param_##name.perm & 0444)); \ | ||
| 211 | __kernel_param_unlock(); \ | ||
| 212 | } while (0) | ||
| 213 | |||
| 214 | #ifdef CONFIG_SYSFS | ||
| 215 | extern void __kernel_param_lock(void); | ||
| 216 | extern void __kernel_param_unlock(void); | ||
| 217 | #else | ||
| 218 | static inline void __kernel_param_lock(void) | ||
| 219 | { | ||
| 220 | } | ||
| 221 | static inline void __kernel_param_unlock(void) | ||
| 222 | { | ||
| 223 | } | ||
| 224 | #endif | ||
| 113 | 225 | ||
| 114 | #ifndef MODULE | 226 | #ifndef MODULE |
| 115 | /** | 227 | /** |
| 116 | * core_param - define a historical core kernel parameter. | 228 | * core_param - define a historical core kernel parameter. |
| 117 | * @name: the name of the cmdline and sysfs parameter (often the same as var) | 229 | * @name: the name of the cmdline and sysfs parameter (often the same as var) |
| 118 | * @var: the variable | 230 | * @var: the variable |
| 119 | * @type: the type (for param_set_##type and param_get_##type) | 231 | * @type: the type of the parameter |
| 120 | * @perm: visibility in sysfs | 232 | * @perm: visibility in sysfs |
| 121 | * | 233 | * |
| 122 | * core_param is just like module_param(), but cannot be modular and | 234 | * core_param is just like module_param(), but cannot be modular and |
| @@ -126,23 +238,32 @@ struct kparam_array | |||
| 126 | */ | 238 | */ |
| 127 | #define core_param(name, var, type, perm) \ | 239 | #define core_param(name, var, type, perm) \ |
| 128 | param_check_##type(name, &(var)); \ | 240 | param_check_##type(name, &(var)); \ |
| 129 | __module_param_call("", name, param_set_##type, param_get_##type, \ | 241 | __module_param_call("", name, ¶m_ops_##type, \ |
| 130 | &var, __same_type(var, bool), perm) | 242 | &var, __same_type(var, bool), perm) |
| 131 | #endif /* !MODULE */ | 243 | #endif /* !MODULE */ |
| 132 | 244 | ||
| 133 | /* Actually copy string: maxlen param is usually sizeof(string). */ | 245 | /** |
| 246 | * module_param_string - a char array parameter | ||
| 247 | * @name: the name of the parameter | ||
| 248 | * @string: the string variable | ||
| 249 | * @len: the maximum length of the string, incl. terminator | ||
| 250 | * @perm: visibility in sysfs. | ||
| 251 | * | ||
| 252 | * This actually copies the string when it's set (unlike type charp). | ||
| 253 | * @len is usually just sizeof(string). | ||
| 254 | */ | ||
| 134 | #define module_param_string(name, string, len, perm) \ | 255 | #define module_param_string(name, string, len, perm) \ |
| 135 | static const struct kparam_string __param_string_##name \ | 256 | static const struct kparam_string __param_string_##name \ |
| 136 | = { len, string }; \ | 257 | = { len, string }; \ |
| 137 | __module_param_call(MODULE_PARAM_PREFIX, name, \ | 258 | __module_param_call(MODULE_PARAM_PREFIX, name, \ |
| 138 | param_set_copystring, param_get_string, \ | 259 | ¶m_ops_string, \ |
| 139 | .str = &__param_string_##name, 0, perm); \ | 260 | .str = &__param_string_##name, 0, perm); \ |
| 140 | __MODULE_PARM_TYPE(name, "string") | 261 | __MODULE_PARM_TYPE(name, "string") |
| 141 | 262 | ||
| 142 | /* Called on module insert or kernel boot */ | 263 | /* Called on module insert or kernel boot */ |
| 143 | extern int parse_args(const char *name, | 264 | extern int parse_args(const char *name, |
| 144 | char *args, | 265 | char *args, |
| 145 | struct kernel_param *params, | 266 | const struct kernel_param *params, |
| 146 | unsigned num, | 267 | unsigned num, |
| 147 | int (*unknown)(char *param, char *val)); | 268 | int (*unknown)(char *param, char *val)); |
| 148 | 269 | ||
| @@ -162,72 +283,105 @@ static inline void destroy_params(const struct kernel_param *params, | |||
| 162 | #define __param_check(name, p, type) \ | 283 | #define __param_check(name, p, type) \ |
| 163 | static inline type *__check_##name(void) { return(p); } | 284 | static inline type *__check_##name(void) { return(p); } |
| 164 | 285 | ||
| 165 | extern int param_set_byte(const char *val, struct kernel_param *kp); | 286 | extern struct kernel_param_ops param_ops_byte; |
| 166 | extern int param_get_byte(char *buffer, struct kernel_param *kp); | 287 | extern int param_set_byte(const char *val, const struct kernel_param *kp); |
| 288 | extern int param_get_byte(char *buffer, const struct kernel_param *kp); | ||
| 167 | #define param_check_byte(name, p) __param_check(name, p, unsigned char) | 289 | #define param_check_byte(name, p) __param_check(name, p, unsigned char) |
| 168 | 290 | ||
| 169 | extern int param_set_short(const char *val, struct kernel_param *kp); | 291 | extern struct kernel_param_ops param_ops_short; |
| 170 | extern int param_get_short(char *buffer, struct kernel_param *kp); | 292 | extern int param_set_short(const char *val, const struct kernel_param *kp); |
| 293 | extern int param_get_short(char *buffer, const struct kernel_param *kp); | ||
| 171 | #define param_check_short(name, p) __param_check(name, p, short) | 294 | #define param_check_short(name, p) __param_check(name, p, short) |
| 172 | 295 | ||
| 173 | extern int param_set_ushort(const char *val, struct kernel_param *kp); | 296 | extern struct kernel_param_ops param_ops_ushort; |
| 174 | extern int param_get_ushort(char *buffer, struct kernel_param *kp); | 297 | extern int param_set_ushort(const char *val, const struct kernel_param *kp); |
| 298 | extern int param_get_ushort(char *buffer, const struct kernel_param *kp); | ||
| 175 | #define param_check_ushort(name, p) __param_check(name, p, unsigned short) | 299 | #define param_check_ushort(name, p) __param_check(name, p, unsigned short) |
| 176 | 300 | ||
| 177 | extern int param_set_int(const char *val, struct kernel_param *kp); | 301 | extern struct kernel_param_ops param_ops_int; |
| 178 | extern int param_get_int(char *buffer, struct kernel_param *kp); | 302 | extern int param_set_int(const char *val, const struct kernel_param *kp); |
| 303 | extern int param_get_int(char *buffer, const struct kernel_param *kp); | ||
| 179 | #define param_check_int(name, p) __param_check(name, p, int) | 304 | #define param_check_int(name, p) __param_check(name, p, int) |
| 180 | 305 | ||
| 181 | extern int param_set_uint(const char *val, struct kernel_param *kp); | 306 | extern struct kernel_param_ops param_ops_uint; |
| 182 | extern int param_get_uint(char *buffer, struct kernel_param *kp); | 307 | extern int param_set_uint(const char *val, const struct kernel_param *kp); |
| 308 | extern int param_get_uint(char *buffer, const struct kernel_param *kp); | ||
| 183 | #define param_check_uint(name, p) __param_check(name, p, unsigned int) | 309 | #define param_check_uint(name, p) __param_check(name, p, unsigned int) |
| 184 | 310 | ||
| 185 | extern int param_set_long(const char *val, struct kernel_param *kp); | 311 | extern struct kernel_param_ops param_ops_long; |
| 186 | extern int param_get_long(char *buffer, struct kernel_param *kp); | 312 | extern int param_set_long(const char *val, const struct kernel_param *kp); |
| 313 | extern int param_get_long(char *buffer, const struct kernel_param *kp); | ||
| 187 | #define param_check_long(name, p) __param_check(name, p, long) | 314 | #define param_check_long(name, p) __param_check(name, p, long) |
| 188 | 315 | ||
| 189 | extern int param_set_ulong(const char *val, struct kernel_param *kp); | 316 | extern struct kernel_param_ops param_ops_ulong; |
| 190 | extern int param_get_ulong(char *buffer, struct kernel_param *kp); | 317 | extern int param_set_ulong(const char *val, const struct kernel_param *kp); |
| 318 | extern int param_get_ulong(char *buffer, const struct kernel_param *kp); | ||
| 191 | #define param_check_ulong(name, p) __param_check(name, p, unsigned long) | 319 | #define param_check_ulong(name, p) __param_check(name, p, unsigned long) |
| 192 | 320 | ||
| 193 | extern int param_set_charp(const char *val, struct kernel_param *kp); | 321 | extern struct kernel_param_ops param_ops_charp; |
| 194 | extern int param_get_charp(char *buffer, struct kernel_param *kp); | 322 | extern int param_set_charp(const char *val, const struct kernel_param *kp); |
| 323 | extern int param_get_charp(char *buffer, const struct kernel_param *kp); | ||
| 195 | #define param_check_charp(name, p) __param_check(name, p, char *) | 324 | #define param_check_charp(name, p) __param_check(name, p, char *) |
| 196 | 325 | ||
| 197 | /* For historical reasons "bool" parameters can be (unsigned) "int". */ | 326 | /* For historical reasons "bool" parameters can be (unsigned) "int". */ |
| 198 | extern int param_set_bool(const char *val, struct kernel_param *kp); | 327 | extern struct kernel_param_ops param_ops_bool; |
| 199 | extern int param_get_bool(char *buffer, struct kernel_param *kp); | 328 | extern int param_set_bool(const char *val, const struct kernel_param *kp); |
| 329 | extern int param_get_bool(char *buffer, const struct kernel_param *kp); | ||
| 200 | #define param_check_bool(name, p) \ | 330 | #define param_check_bool(name, p) \ |
| 201 | static inline void __check_##name(void) \ | 331 | static inline void __check_##name(void) \ |
| 202 | { \ | 332 | { \ |
| 203 | BUILD_BUG_ON(!__same_type(*(p), bool) && \ | 333 | BUILD_BUG_ON(!__same_type((p), bool *) && \ |
| 204 | !__same_type(*(p), unsigned int) && \ | 334 | !__same_type((p), unsigned int *) && \ |
| 205 | !__same_type(*(p), int)); \ | 335 | !__same_type((p), int *)); \ |
| 206 | } | 336 | } |
| 207 | 337 | ||
| 208 | extern int param_set_invbool(const char *val, struct kernel_param *kp); | 338 | extern struct kernel_param_ops param_ops_invbool; |
| 209 | extern int param_get_invbool(char *buffer, struct kernel_param *kp); | 339 | extern int param_set_invbool(const char *val, const struct kernel_param *kp); |
| 340 | extern int param_get_invbool(char *buffer, const struct kernel_param *kp); | ||
| 210 | #define param_check_invbool(name, p) __param_check(name, p, bool) | 341 | #define param_check_invbool(name, p) __param_check(name, p, bool) |
| 211 | 342 | ||
| 212 | /* Comma-separated array: *nump is set to number they actually specified. */ | 343 | /** |
| 344 | * module_param_array - a parameter which is an array of some type | ||
| 345 | * @name: the name of the array variable | ||
| 346 | * @type: the type, as per module_param() | ||
| 347 | * @nump: optional pointer filled in with the number written | ||
| 348 | * @perm: visibility in sysfs | ||
| 349 | * | ||
| 350 | * Input and output are as comma-separated values. Commas inside values | ||
| 351 | * don't work properly (eg. an array of charp). | ||
| 352 | * | ||
| 353 | * ARRAY_SIZE(@name) is used to determine the number of elements in the | ||
| 354 | * array, so the definition must be visible. | ||
| 355 | */ | ||
| 356 | #define module_param_array(name, type, nump, perm) \ | ||
| 357 | module_param_array_named(name, name, type, nump, perm) | ||
| 358 | |||
| 359 | /** | ||
| 360 | * module_param_array_named - renamed parameter which is an array of some type | ||
| 361 | * @name: a valid C identifier which is the parameter name | ||
| 362 | * @array: the name of the array variable | ||
| 363 | * @type: the type, as per module_param() | ||
| 364 | * @nump: optional pointer filled in with the number written | ||
| 365 | * @perm: visibility in sysfs | ||
| 366 | * | ||
| 367 | * This exposes a different name than the actual variable name. See | ||
| 368 | * module_param_named() for why this might be necessary. | ||
| 369 | */ | ||
| 213 | #define module_param_array_named(name, array, type, nump, perm) \ | 370 | #define module_param_array_named(name, array, type, nump, perm) \ |
| 214 | static const struct kparam_array __param_arr_##name \ | 371 | static const struct kparam_array __param_arr_##name \ |
| 215 | = { ARRAY_SIZE(array), nump, param_set_##type, param_get_##type,\ | 372 | = { ARRAY_SIZE(array), nump, ¶m_ops_##type, \ |
| 216 | sizeof(array[0]), array }; \ | 373 | sizeof(array[0]), array }; \ |
| 217 | __module_param_call(MODULE_PARAM_PREFIX, name, \ | 374 | __module_param_call(MODULE_PARAM_PREFIX, name, \ |
| 218 | param_array_set, param_array_get, \ | 375 | ¶m_array_ops, \ |
| 219 | .arr = &__param_arr_##name, \ | 376 | .arr = &__param_arr_##name, \ |
| 220 | __same_type(array[0], bool), perm); \ | 377 | __same_type(array[0], bool), perm); \ |
| 221 | __MODULE_PARM_TYPE(name, "array of " #type) | 378 | __MODULE_PARM_TYPE(name, "array of " #type) |
| 222 | 379 | ||
| 223 | #define module_param_array(name, type, nump, perm) \ | 380 | extern struct kernel_param_ops param_array_ops; |
| 224 | module_param_array_named(name, name, type, nump, perm) | ||
| 225 | |||
| 226 | extern int param_array_set(const char *val, struct kernel_param *kp); | ||
| 227 | extern int param_array_get(char *buffer, struct kernel_param *kp); | ||
| 228 | 381 | ||
| 229 | extern int param_set_copystring(const char *val, struct kernel_param *kp); | 382 | extern struct kernel_param_ops param_ops_string; |
| 230 | extern int param_get_string(char *buffer, struct kernel_param *kp); | 383 | extern int param_set_copystring(const char *val, const struct kernel_param *); |
| 384 | extern int param_get_string(char *buffer, const struct kernel_param *kp); | ||
| 231 | 385 | ||
| 232 | /* for exporting parameters in /sys/parameters */ | 386 | /* for exporting parameters in /sys/parameters */ |
| 233 | 387 | ||
| @@ -235,13 +389,13 @@ struct module; | |||
| 235 | 389 | ||
| 236 | #if defined(CONFIG_SYSFS) && defined(CONFIG_MODULES) | 390 | #if defined(CONFIG_SYSFS) && defined(CONFIG_MODULES) |
| 237 | extern int module_param_sysfs_setup(struct module *mod, | 391 | extern int module_param_sysfs_setup(struct module *mod, |
| 238 | struct kernel_param *kparam, | 392 | const struct kernel_param *kparam, |
| 239 | unsigned int num_params); | 393 | unsigned int num_params); |
| 240 | 394 | ||
| 241 | extern void module_param_sysfs_remove(struct module *mod); | 395 | extern void module_param_sysfs_remove(struct module *mod); |
| 242 | #else | 396 | #else |
| 243 | static inline int module_param_sysfs_setup(struct module *mod, | 397 | static inline int module_param_sysfs_setup(struct module *mod, |
| 244 | struct kernel_param *kparam, | 398 | const struct kernel_param *kparam, |
| 245 | unsigned int num_params) | 399 | unsigned int num_params) |
| 246 | { | 400 | { |
| 247 | return 0; | 401 | return 0; |
diff --git a/init/main.c b/init/main.c index 86cbfd085b01..22d61cb06f98 100644 --- a/init/main.c +++ b/init/main.c | |||
| @@ -201,11 +201,11 @@ static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, }; | |||
| 201 | char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, }; | 201 | char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, }; |
| 202 | static const char *panic_later, *panic_param; | 202 | static const char *panic_later, *panic_param; |
| 203 | 203 | ||
| 204 | extern struct obs_kernel_param __setup_start[], __setup_end[]; | 204 | extern const struct obs_kernel_param __setup_start[], __setup_end[]; |
| 205 | 205 | ||
| 206 | static int __init obsolete_checksetup(char *line) | 206 | static int __init obsolete_checksetup(char *line) |
| 207 | { | 207 | { |
| 208 | struct obs_kernel_param *p; | 208 | const struct obs_kernel_param *p; |
| 209 | int had_early_param = 0; | 209 | int had_early_param = 0; |
| 210 | 210 | ||
| 211 | p = __setup_start; | 211 | p = __setup_start; |
| @@ -458,7 +458,7 @@ static noinline void __init_refok rest_init(void) | |||
| 458 | /* Check for early params. */ | 458 | /* Check for early params. */ |
| 459 | static int __init do_early_param(char *param, char *val) | 459 | static int __init do_early_param(char *param, char *val) |
| 460 | { | 460 | { |
| 461 | struct obs_kernel_param *p; | 461 | const struct obs_kernel_param *p; |
| 462 | 462 | ||
| 463 | for (p = __setup_start; p < __setup_end; p++) { | 463 | for (p = __setup_start; p < __setup_end; p++) { |
| 464 | if ((p->early && strcmp(param, p->str) == 0) || | 464 | if ((p->early && strcmp(param, p->str) == 0) || |
| @@ -536,7 +536,7 @@ static void __init mm_init(void) | |||
| 536 | asmlinkage void __init start_kernel(void) | 536 | asmlinkage void __init start_kernel(void) |
| 537 | { | 537 | { |
| 538 | char * command_line; | 538 | char * command_line; |
| 539 | extern struct kernel_param __start___param[], __stop___param[]; | 539 | extern const struct kernel_param __start___param[], __stop___param[]; |
| 540 | 540 | ||
| 541 | smp_setup_processor_id(); | 541 | smp_setup_processor_id(); |
| 542 | 542 | ||
diff --git a/kernel/params.c b/kernel/params.c index 0b30ecd53a52..08107d181758 100644 --- a/kernel/params.c +++ b/kernel/params.c | |||
| @@ -31,6 +31,42 @@ | |||
| 31 | #define DEBUGP(fmt, a...) | 31 | #define DEBUGP(fmt, a...) |
| 32 | #endif | 32 | #endif |
| 33 | 33 | ||
| 34 | /* Protects all parameters, and incidentally kmalloced_param list. */ | ||
| 35 | static DEFINE_MUTEX(param_lock); | ||
| 36 | |||
| 37 | /* This just allows us to keep track of which parameters are kmalloced. */ | ||
| 38 | struct kmalloced_param { | ||
| 39 | struct list_head list; | ||
| 40 | char val[]; | ||
| 41 | }; | ||
| 42 | static LIST_HEAD(kmalloced_params); | ||
| 43 | |||
| 44 | static void *kmalloc_parameter(unsigned int size) | ||
| 45 | { | ||
| 46 | struct kmalloced_param *p; | ||
| 47 | |||
| 48 | p = kmalloc(sizeof(*p) + size, GFP_KERNEL); | ||
| 49 | if (!p) | ||
| 50 | return NULL; | ||
| 51 | |||
| 52 | list_add(&p->list, &kmalloced_params); | ||
| 53 | return p->val; | ||
| 54 | } | ||
| 55 | |||
| 56 | /* Does nothing if parameter wasn't kmalloced above. */ | ||
| 57 | static void maybe_kfree_parameter(void *param) | ||
| 58 | { | ||
| 59 | struct kmalloced_param *p; | ||
| 60 | |||
| 61 | list_for_each_entry(p, &kmalloced_params, list) { | ||
| 62 | if (p->val == param) { | ||
| 63 | list_del(&p->list); | ||
| 64 | kfree(p); | ||
| 65 | break; | ||
| 66 | } | ||
| 67 | } | ||
| 68 | } | ||
| 69 | |||
| 34 | static inline char dash2underscore(char c) | 70 | static inline char dash2underscore(char c) |
| 35 | { | 71 | { |
| 36 | if (c == '-') | 72 | if (c == '-') |
| @@ -49,18 +85,25 @@ static inline int parameq(const char *input, const char *paramname) | |||
| 49 | 85 | ||
| 50 | static int parse_one(char *param, | 86 | static int parse_one(char *param, |
| 51 | char *val, | 87 | char *val, |
| 52 | struct kernel_param *params, | 88 | const struct kernel_param *params, |
| 53 | unsigned num_params, | 89 | unsigned num_params, |
| 54 | int (*handle_unknown)(char *param, char *val)) | 90 | int (*handle_unknown)(char *param, char *val)) |
| 55 | { | 91 | { |
| 56 | unsigned int i; | 92 | unsigned int i; |
| 93 | int err; | ||
| 57 | 94 | ||
| 58 | /* Find parameter */ | 95 | /* Find parameter */ |
| 59 | for (i = 0; i < num_params; i++) { | 96 | for (i = 0; i < num_params; i++) { |
| 60 | if (parameq(param, params[i].name)) { | 97 | if (parameq(param, params[i].name)) { |
| 98 | /* Noone handled NULL, so do it here. */ | ||
| 99 | if (!val && params[i].ops->set != param_set_bool) | ||
| 100 | return -EINVAL; | ||
| 61 | DEBUGP("They are equal! Calling %p\n", | 101 | DEBUGP("They are equal! Calling %p\n", |
| 62 | params[i].set); | 102 | params[i].ops->set); |
| 63 | return params[i].set(val, ¶ms[i]); | 103 | mutex_lock(¶m_lock); |
| 104 | err = params[i].ops->set(val, ¶ms[i]); | ||
| 105 | mutex_unlock(¶m_lock); | ||
| 106 | return err; | ||
| 64 | } | 107 | } |
| 65 | } | 108 | } |
| 66 | 109 | ||
| @@ -128,7 +171,7 @@ static char *next_arg(char *args, char **param, char **val) | |||
| 128 | /* Args looks like "foo=bar,bar2 baz=fuz wiz". */ | 171 | /* Args looks like "foo=bar,bar2 baz=fuz wiz". */ |
| 129 | int parse_args(const char *name, | 172 | int parse_args(const char *name, |
| 130 | char *args, | 173 | char *args, |
| 131 | struct kernel_param *params, | 174 | const struct kernel_param *params, |
| 132 | unsigned num, | 175 | unsigned num, |
| 133 | int (*unknown)(char *param, char *val)) | 176 | int (*unknown)(char *param, char *val)) |
| 134 | { | 177 | { |
| @@ -176,22 +219,29 @@ int parse_args(const char *name, | |||
| 176 | 219 | ||
| 177 | /* Lazy bastard, eh? */ | 220 | /* Lazy bastard, eh? */ |
| 178 | #define STANDARD_PARAM_DEF(name, type, format, tmptype, strtolfn) \ | 221 | #define STANDARD_PARAM_DEF(name, type, format, tmptype, strtolfn) \ |
| 179 | int param_set_##name(const char *val, struct kernel_param *kp) \ | 222 | int param_set_##name(const char *val, const struct kernel_param *kp) \ |
| 180 | { \ | 223 | { \ |
| 181 | tmptype l; \ | 224 | tmptype l; \ |
| 182 | int ret; \ | 225 | int ret; \ |
| 183 | \ | 226 | \ |
| 184 | if (!val) return -EINVAL; \ | ||
| 185 | ret = strtolfn(val, 0, &l); \ | 227 | ret = strtolfn(val, 0, &l); \ |
| 186 | if (ret == -EINVAL || ((type)l != l)) \ | 228 | if (ret == -EINVAL || ((type)l != l)) \ |
| 187 | return -EINVAL; \ | 229 | return -EINVAL; \ |
| 188 | *((type *)kp->arg) = l; \ | 230 | *((type *)kp->arg) = l; \ |
| 189 | return 0; \ | 231 | return 0; \ |
| 190 | } \ | 232 | } \ |
| 191 | int param_get_##name(char *buffer, struct kernel_param *kp) \ | 233 | int param_get_##name(char *buffer, const struct kernel_param *kp) \ |
| 192 | { \ | 234 | { \ |
| 193 | return sprintf(buffer, format, *((type *)kp->arg)); \ | 235 | return sprintf(buffer, format, *((type *)kp->arg)); \ |
| 194 | } | 236 | } \ |
| 237 | struct kernel_param_ops param_ops_##name = { \ | ||
| 238 | .set = param_set_##name, \ | ||
| 239 | .get = param_get_##name, \ | ||
| 240 | }; \ | ||
| 241 | EXPORT_SYMBOL(param_set_##name); \ | ||
| 242 | EXPORT_SYMBOL(param_get_##name); \ | ||
| 243 | EXPORT_SYMBOL(param_ops_##name) | ||
| 244 | |||
| 195 | 245 | ||
| 196 | STANDARD_PARAM_DEF(byte, unsigned char, "%c", unsigned long, strict_strtoul); | 246 | STANDARD_PARAM_DEF(byte, unsigned char, "%c", unsigned long, strict_strtoul); |
| 197 | STANDARD_PARAM_DEF(short, short, "%hi", long, strict_strtol); | 247 | STANDARD_PARAM_DEF(short, short, "%hi", long, strict_strtol); |
| @@ -201,39 +251,50 @@ STANDARD_PARAM_DEF(uint, unsigned int, "%u", unsigned long, strict_strtoul); | |||
| 201 | STANDARD_PARAM_DEF(long, long, "%li", long, strict_strtol); | 251 | STANDARD_PARAM_DEF(long, long, "%li", long, strict_strtol); |
| 202 | STANDARD_PARAM_DEF(ulong, unsigned long, "%lu", unsigned long, strict_strtoul); | 252 | STANDARD_PARAM_DEF(ulong, unsigned long, "%lu", unsigned long, strict_strtoul); |
| 203 | 253 | ||
| 204 | int param_set_charp(const char *val, struct kernel_param *kp) | 254 | int param_set_charp(const char *val, const struct kernel_param *kp) |
| 205 | { | 255 | { |
| 206 | if (!val) { | ||
| 207 | printk(KERN_ERR "%s: string parameter expected\n", | ||
| 208 | kp->name); | ||
| 209 | return -EINVAL; | ||
| 210 | } | ||
| 211 | |||
| 212 | if (strlen(val) > 1024) { | 256 | if (strlen(val) > 1024) { |
| 213 | printk(KERN_ERR "%s: string parameter too long\n", | 257 | printk(KERN_ERR "%s: string parameter too long\n", |
| 214 | kp->name); | 258 | kp->name); |
| 215 | return -ENOSPC; | 259 | return -ENOSPC; |
| 216 | } | 260 | } |
| 217 | 261 | ||
| 218 | /* This is a hack. We can't need to strdup in early boot, and we | 262 | maybe_kfree_parameter(*(char **)kp->arg); |
| 263 | |||
| 264 | /* This is a hack. We can't kmalloc in early boot, and we | ||
| 219 | * don't need to; this mangled commandline is preserved. */ | 265 | * don't need to; this mangled commandline is preserved. */ |
| 220 | if (slab_is_available()) { | 266 | if (slab_is_available()) { |
| 221 | *(char **)kp->arg = kstrdup(val, GFP_KERNEL); | 267 | *(char **)kp->arg = kmalloc_parameter(strlen(val)+1); |
| 222 | if (!*(char **)kp->arg) | 268 | if (!*(char **)kp->arg) |
| 223 | return -ENOMEM; | 269 | return -ENOMEM; |
| 270 | strcpy(*(char **)kp->arg, val); | ||
| 224 | } else | 271 | } else |
| 225 | *(const char **)kp->arg = val; | 272 | *(const char **)kp->arg = val; |
| 226 | 273 | ||
| 227 | return 0; | 274 | return 0; |
| 228 | } | 275 | } |
| 276 | EXPORT_SYMBOL(param_set_charp); | ||
| 229 | 277 | ||
| 230 | int param_get_charp(char *buffer, struct kernel_param *kp) | 278 | int param_get_charp(char *buffer, const struct kernel_param *kp) |
| 231 | { | 279 | { |
| 232 | return sprintf(buffer, "%s", *((char **)kp->arg)); | 280 | return sprintf(buffer, "%s", *((char **)kp->arg)); |
| 233 | } | 281 | } |
| 282 | EXPORT_SYMBOL(param_get_charp); | ||
| 283 | |||
| 284 | static void param_free_charp(void *arg) | ||
| 285 | { | ||
| 286 | maybe_kfree_parameter(*((char **)arg)); | ||
| 287 | } | ||
| 288 | |||
| 289 | struct kernel_param_ops param_ops_charp = { | ||
| 290 | .set = param_set_charp, | ||
| 291 | .get = param_get_charp, | ||
| 292 | .free = param_free_charp, | ||
| 293 | }; | ||
| 294 | EXPORT_SYMBOL(param_ops_charp); | ||
| 234 | 295 | ||
| 235 | /* Actually could be a bool or an int, for historical reasons. */ | 296 | /* Actually could be a bool or an int, for historical reasons. */ |
| 236 | int param_set_bool(const char *val, struct kernel_param *kp) | 297 | int param_set_bool(const char *val, const struct kernel_param *kp) |
| 237 | { | 298 | { |
| 238 | bool v; | 299 | bool v; |
| 239 | 300 | ||
| @@ -258,8 +319,9 @@ int param_set_bool(const char *val, struct kernel_param *kp) | |||
| 258 | *(int *)kp->arg = v; | 319 | *(int *)kp->arg = v; |
| 259 | return 0; | 320 | return 0; |
| 260 | } | 321 | } |
| 322 | EXPORT_SYMBOL(param_set_bool); | ||
| 261 | 323 | ||
| 262 | int param_get_bool(char *buffer, struct kernel_param *kp) | 324 | int param_get_bool(char *buffer, const struct kernel_param *kp) |
| 263 | { | 325 | { |
| 264 | bool val; | 326 | bool val; |
| 265 | if (kp->flags & KPARAM_ISBOOL) | 327 | if (kp->flags & KPARAM_ISBOOL) |
| @@ -270,9 +332,16 @@ int param_get_bool(char *buffer, struct kernel_param *kp) | |||
| 270 | /* Y and N chosen as being relatively non-coder friendly */ | 332 | /* Y and N chosen as being relatively non-coder friendly */ |
| 271 | return sprintf(buffer, "%c", val ? 'Y' : 'N'); | 333 | return sprintf(buffer, "%c", val ? 'Y' : 'N'); |
| 272 | } | 334 | } |
| 335 | EXPORT_SYMBOL(param_get_bool); | ||
| 336 | |||
| 337 | struct kernel_param_ops param_ops_bool = { | ||
| 338 | .set = param_set_bool, | ||
| 339 | .get = param_get_bool, | ||
| 340 | }; | ||
| 341 | EXPORT_SYMBOL(param_ops_bool); | ||
| 273 | 342 | ||
| 274 | /* This one must be bool. */ | 343 | /* This one must be bool. */ |
| 275 | int param_set_invbool(const char *val, struct kernel_param *kp) | 344 | int param_set_invbool(const char *val, const struct kernel_param *kp) |
| 276 | { | 345 | { |
| 277 | int ret; | 346 | int ret; |
| 278 | bool boolval; | 347 | bool boolval; |
| @@ -285,18 +354,26 @@ int param_set_invbool(const char *val, struct kernel_param *kp) | |||
| 285 | *(bool *)kp->arg = !boolval; | 354 | *(bool *)kp->arg = !boolval; |
| 286 | return ret; | 355 | return ret; |
| 287 | } | 356 | } |
| 357 | EXPORT_SYMBOL(param_set_invbool); | ||
| 288 | 358 | ||
| 289 | int param_get_invbool(char *buffer, struct kernel_param *kp) | 359 | int param_get_invbool(char *buffer, const struct kernel_param *kp) |
| 290 | { | 360 | { |
| 291 | return sprintf(buffer, "%c", (*(bool *)kp->arg) ? 'N' : 'Y'); | 361 | return sprintf(buffer, "%c", (*(bool *)kp->arg) ? 'N' : 'Y'); |
| 292 | } | 362 | } |
| 363 | EXPORT_SYMBOL(param_get_invbool); | ||
| 364 | |||
| 365 | struct kernel_param_ops param_ops_invbool = { | ||
| 366 | .set = param_set_invbool, | ||
| 367 | .get = param_get_invbool, | ||
| 368 | }; | ||
| 369 | EXPORT_SYMBOL(param_ops_invbool); | ||
| 293 | 370 | ||
| 294 | /* We break the rule and mangle the string. */ | 371 | /* We break the rule and mangle the string. */ |
| 295 | static int param_array(const char *name, | 372 | static int param_array(const char *name, |
| 296 | const char *val, | 373 | const char *val, |
| 297 | unsigned int min, unsigned int max, | 374 | unsigned int min, unsigned int max, |
| 298 | void *elem, int elemsize, | 375 | void *elem, int elemsize, |
| 299 | int (*set)(const char *, struct kernel_param *kp), | 376 | int (*set)(const char *, const struct kernel_param *kp), |
| 300 | u16 flags, | 377 | u16 flags, |
| 301 | unsigned int *num) | 378 | unsigned int *num) |
| 302 | { | 379 | { |
| @@ -309,12 +386,6 @@ static int param_array(const char *name, | |||
| 309 | kp.arg = elem; | 386 | kp.arg = elem; |
| 310 | kp.flags = flags; | 387 | kp.flags = flags; |
| 311 | 388 | ||
| 312 | /* No equals sign? */ | ||
| 313 | if (!val) { | ||
| 314 | printk(KERN_ERR "%s: expects arguments\n", name); | ||
| 315 | return -EINVAL; | ||
| 316 | } | ||
| 317 | |||
| 318 | *num = 0; | 389 | *num = 0; |
| 319 | /* We expect a comma-separated list of values. */ | 390 | /* We expect a comma-separated list of values. */ |
| 320 | do { | 391 | do { |
| @@ -330,6 +401,7 @@ static int param_array(const char *name, | |||
| 330 | /* nul-terminate and parse */ | 401 | /* nul-terminate and parse */ |
| 331 | save = val[len]; | 402 | save = val[len]; |
| 332 | ((char *)val)[len] = '\0'; | 403 | ((char *)val)[len] = '\0'; |
| 404 | BUG_ON(!mutex_is_locked(¶m_lock)); | ||
| 333 | ret = set(val, &kp); | 405 | ret = set(val, &kp); |
| 334 | 406 | ||
| 335 | if (ret != 0) | 407 | if (ret != 0) |
| @@ -347,17 +419,17 @@ static int param_array(const char *name, | |||
| 347 | return 0; | 419 | return 0; |
| 348 | } | 420 | } |
| 349 | 421 | ||
| 350 | int param_array_set(const char *val, struct kernel_param *kp) | 422 | static int param_array_set(const char *val, const struct kernel_param *kp) |
| 351 | { | 423 | { |
| 352 | const struct kparam_array *arr = kp->arr; | 424 | const struct kparam_array *arr = kp->arr; |
| 353 | unsigned int temp_num; | 425 | unsigned int temp_num; |
| 354 | 426 | ||
| 355 | return param_array(kp->name, val, 1, arr->max, arr->elem, | 427 | return param_array(kp->name, val, 1, arr->max, arr->elem, |
| 356 | arr->elemsize, arr->set, kp->flags, | 428 | arr->elemsize, arr->ops->set, kp->flags, |
| 357 | arr->num ?: &temp_num); | 429 | arr->num ?: &temp_num); |
| 358 | } | 430 | } |
| 359 | 431 | ||
| 360 | int param_array_get(char *buffer, struct kernel_param *kp) | 432 | static int param_array_get(char *buffer, const struct kernel_param *kp) |
| 361 | { | 433 | { |
| 362 | int i, off, ret; | 434 | int i, off, ret; |
| 363 | const struct kparam_array *arr = kp->arr; | 435 | const struct kparam_array *arr = kp->arr; |
| @@ -368,7 +440,8 @@ int param_array_get(char *buffer, struct kernel_param *kp) | |||
| 368 | if (i) | 440 | if (i) |
| 369 | buffer[off++] = ','; | 441 | buffer[off++] = ','; |
| 370 | p.arg = arr->elem + arr->elemsize * i; | 442 | p.arg = arr->elem + arr->elemsize * i; |
| 371 | ret = arr->get(buffer + off, &p); | 443 | BUG_ON(!mutex_is_locked(¶m_lock)); |
| 444 | ret = arr->ops->get(buffer + off, &p); | ||
| 372 | if (ret < 0) | 445 | if (ret < 0) |
| 373 | return ret; | 446 | return ret; |
| 374 | off += ret; | 447 | off += ret; |
| @@ -377,14 +450,27 @@ int param_array_get(char *buffer, struct kernel_param *kp) | |||
| 377 | return off; | 450 | return off; |
| 378 | } | 451 | } |
| 379 | 452 | ||
| 380 | int param_set_copystring(const char *val, struct kernel_param *kp) | 453 | static void param_array_free(void *arg) |
| 454 | { | ||
| 455 | unsigned int i; | ||
| 456 | const struct kparam_array *arr = arg; | ||
| 457 | |||
| 458 | if (arr->ops->free) | ||
| 459 | for (i = 0; i < (arr->num ? *arr->num : arr->max); i++) | ||
| 460 | arr->ops->free(arr->elem + arr->elemsize * i); | ||
| 461 | } | ||
| 462 | |||
| 463 | struct kernel_param_ops param_array_ops = { | ||
| 464 | .set = param_array_set, | ||
| 465 | .get = param_array_get, | ||
| 466 | .free = param_array_free, | ||
| 467 | }; | ||
| 468 | EXPORT_SYMBOL(param_array_ops); | ||
| 469 | |||
| 470 | int param_set_copystring(const char *val, const struct kernel_param *kp) | ||
| 381 | { | 471 | { |
| 382 | const struct kparam_string *kps = kp->str; | 472 | const struct kparam_string *kps = kp->str; |
| 383 | 473 | ||
| 384 | if (!val) { | ||
| 385 | printk(KERN_ERR "%s: missing param set value\n", kp->name); | ||
| 386 | return -EINVAL; | ||
| 387 | } | ||
| 388 | if (strlen(val)+1 > kps->maxlen) { | 474 | if (strlen(val)+1 > kps->maxlen) { |
| 389 | printk(KERN_ERR "%s: string doesn't fit in %u chars.\n", | 475 | printk(KERN_ERR "%s: string doesn't fit in %u chars.\n", |
| 390 | kp->name, kps->maxlen-1); | 476 | kp->name, kps->maxlen-1); |
| @@ -393,12 +479,20 @@ int param_set_copystring(const char *val, struct kernel_param *kp) | |||
| 393 | strcpy(kps->string, val); | 479 | strcpy(kps->string, val); |
| 394 | return 0; | 480 | return 0; |
| 395 | } | 481 | } |
| 482 | EXPORT_SYMBOL(param_set_copystring); | ||
| 396 | 483 | ||
| 397 | int param_get_string(char *buffer, struct kernel_param *kp) | 484 | int param_get_string(char *buffer, const struct kernel_param *kp) |
| 398 | { | 485 | { |
| 399 | const struct kparam_string *kps = kp->str; | 486 | const struct kparam_string *kps = kp->str; |
| 400 | return strlcpy(buffer, kps->string, kps->maxlen); | 487 | return strlcpy(buffer, kps->string, kps->maxlen); |
| 401 | } | 488 | } |
| 489 | EXPORT_SYMBOL(param_get_string); | ||
| 490 | |||
| 491 | struct kernel_param_ops param_ops_string = { | ||
| 492 | .set = param_set_copystring, | ||
| 493 | .get = param_get_string, | ||
| 494 | }; | ||
| 495 | EXPORT_SYMBOL(param_ops_string); | ||
| 402 | 496 | ||
| 403 | /* sysfs output in /sys/modules/XYZ/parameters/ */ | 497 | /* sysfs output in /sys/modules/XYZ/parameters/ */ |
| 404 | #define to_module_attr(n) container_of(n, struct module_attribute, attr) | 498 | #define to_module_attr(n) container_of(n, struct module_attribute, attr) |
| @@ -409,7 +503,7 @@ extern struct kernel_param __start___param[], __stop___param[]; | |||
| 409 | struct param_attribute | 503 | struct param_attribute |
| 410 | { | 504 | { |
| 411 | struct module_attribute mattr; | 505 | struct module_attribute mattr; |
| 412 | struct kernel_param *param; | 506 | const struct kernel_param *param; |
| 413 | }; | 507 | }; |
| 414 | 508 | ||
| 415 | struct module_param_attrs | 509 | struct module_param_attrs |
| @@ -428,10 +522,12 @@ static ssize_t param_attr_show(struct module_attribute *mattr, | |||
| 428 | int count; | 522 | int count; |
| 429 | struct param_attribute *attribute = to_param_attr(mattr); | 523 | struct param_attribute *attribute = to_param_attr(mattr); |
| 430 | 524 | ||
| 431 | if (!attribute->param->get) | 525 | if (!attribute->param->ops->get) |
| 432 | return -EPERM; | 526 | return -EPERM; |
| 433 | 527 | ||
| 434 | count = attribute->param->get(buf, attribute->param); | 528 | mutex_lock(¶m_lock); |
| 529 | count = attribute->param->ops->get(buf, attribute->param); | ||
| 530 | mutex_unlock(¶m_lock); | ||
| 435 | if (count > 0) { | 531 | if (count > 0) { |
| 436 | strcat(buf, "\n"); | 532 | strcat(buf, "\n"); |
| 437 | ++count; | 533 | ++count; |
| @@ -447,10 +543,12 @@ static ssize_t param_attr_store(struct module_attribute *mattr, | |||
| 447 | int err; | 543 | int err; |
| 448 | struct param_attribute *attribute = to_param_attr(mattr); | 544 | struct param_attribute *attribute = to_param_attr(mattr); |
| 449 | 545 | ||
| 450 | if (!attribute->param->set) | 546 | if (!attribute->param->ops->set) |
| 451 | return -EPERM; | 547 | return -EPERM; |
| 452 | 548 | ||
| 453 | err = attribute->param->set(buf, attribute->param); | 549 | mutex_lock(¶m_lock); |
| 550 | err = attribute->param->ops->set(buf, attribute->param); | ||
| 551 | mutex_unlock(¶m_lock); | ||
| 454 | if (!err) | 552 | if (!err) |
| 455 | return len; | 553 | return len; |
| 456 | return err; | 554 | return err; |
| @@ -464,6 +562,18 @@ static ssize_t param_attr_store(struct module_attribute *mattr, | |||
| 464 | #endif | 562 | #endif |
| 465 | 563 | ||
| 466 | #ifdef CONFIG_SYSFS | 564 | #ifdef CONFIG_SYSFS |
| 565 | void __kernel_param_lock(void) | ||
| 566 | { | ||
| 567 | mutex_lock(¶m_lock); | ||
| 568 | } | ||
| 569 | EXPORT_SYMBOL(__kernel_param_lock); | ||
| 570 | |||
| 571 | void __kernel_param_unlock(void) | ||
| 572 | { | ||
| 573 | mutex_unlock(¶m_lock); | ||
| 574 | } | ||
| 575 | EXPORT_SYMBOL(__kernel_param_unlock); | ||
| 576 | |||
| 467 | /* | 577 | /* |
| 468 | * add_sysfs_param - add a parameter to sysfs | 578 | * add_sysfs_param - add a parameter to sysfs |
| 469 | * @mk: struct module_kobject | 579 | * @mk: struct module_kobject |
| @@ -475,7 +585,7 @@ static ssize_t param_attr_store(struct module_attribute *mattr, | |||
| 475 | * if there's an error. | 585 | * if there's an error. |
| 476 | */ | 586 | */ |
| 477 | static __modinit int add_sysfs_param(struct module_kobject *mk, | 587 | static __modinit int add_sysfs_param(struct module_kobject *mk, |
| 478 | struct kernel_param *kp, | 588 | const struct kernel_param *kp, |
| 479 | const char *name) | 589 | const char *name) |
| 480 | { | 590 | { |
| 481 | struct module_param_attrs *new; | 591 | struct module_param_attrs *new; |
| @@ -557,7 +667,7 @@ static void free_module_param_attrs(struct module_kobject *mk) | |||
| 557 | * /sys/module/[mod->name]/parameters/ | 667 | * /sys/module/[mod->name]/parameters/ |
| 558 | */ | 668 | */ |
| 559 | int module_param_sysfs_setup(struct module *mod, | 669 | int module_param_sysfs_setup(struct module *mod, |
| 560 | struct kernel_param *kparam, | 670 | const struct kernel_param *kparam, |
| 561 | unsigned int num_params) | 671 | unsigned int num_params) |
| 562 | { | 672 | { |
| 563 | int i, err; | 673 | int i, err; |
| @@ -602,7 +712,11 @@ void module_param_sysfs_remove(struct module *mod) | |||
| 602 | 712 | ||
| 603 | void destroy_params(const struct kernel_param *params, unsigned num) | 713 | void destroy_params(const struct kernel_param *params, unsigned num) |
| 604 | { | 714 | { |
| 605 | /* FIXME: This should free kmalloced charp parameters. It doesn't. */ | 715 | unsigned int i; |
| 716 | |||
| 717 | for (i = 0; i < num; i++) | ||
| 718 | if (params[i].ops->free) | ||
| 719 | params[i].ops->free(params[i].arg); | ||
| 606 | } | 720 | } |
| 607 | 721 | ||
| 608 | static void __init kernel_add_sysfs_param(const char *name, | 722 | static void __init kernel_add_sysfs_param(const char *name, |
| @@ -768,28 +882,3 @@ static int __init param_sysfs_init(void) | |||
| 768 | subsys_initcall(param_sysfs_init); | 882 | subsys_initcall(param_sysfs_init); |
| 769 | 883 | ||
| 770 | #endif /* CONFIG_SYSFS */ | 884 | #endif /* CONFIG_SYSFS */ |
| 771 | |||
| 772 | EXPORT_SYMBOL(param_set_byte); | ||
| 773 | EXPORT_SYMBOL(param_get_byte); | ||
| 774 | EXPORT_SYMBOL(param_set_short); | ||
| 775 | EXPORT_SYMBOL(param_get_short); | ||
| 776 | EXPORT_SYMBOL(param_set_ushort); | ||
| 777 | EXPORT_SYMBOL(param_get_ushort); | ||
| 778 | EXPORT_SYMBOL(param_set_int); | ||
| 779 | EXPORT_SYMBOL(param_get_int); | ||
| 780 | EXPORT_SYMBOL(param_set_uint); | ||
| 781 | EXPORT_SYMBOL(param_get_uint); | ||
| 782 | EXPORT_SYMBOL(param_set_long); | ||
| 783 | EXPORT_SYMBOL(param_get_long); | ||
| 784 | EXPORT_SYMBOL(param_set_ulong); | ||
| 785 | EXPORT_SYMBOL(param_get_ulong); | ||
| 786 | EXPORT_SYMBOL(param_set_charp); | ||
| 787 | EXPORT_SYMBOL(param_get_charp); | ||
| 788 | EXPORT_SYMBOL(param_set_bool); | ||
| 789 | EXPORT_SYMBOL(param_get_bool); | ||
| 790 | EXPORT_SYMBOL(param_set_invbool); | ||
| 791 | EXPORT_SYMBOL(param_get_invbool); | ||
| 792 | EXPORT_SYMBOL(param_array_set); | ||
| 793 | EXPORT_SYMBOL(param_array_get); | ||
| 794 | EXPORT_SYMBOL(param_set_copystring); | ||
| 795 | EXPORT_SYMBOL(param_get_string); | ||
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index 6d0bd198af19..be04d46110fe 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c | |||
| @@ -103,6 +103,7 @@ ieee80211_rate_control_ops_get(const char *name) | |||
| 103 | struct rate_control_ops *ops; | 103 | struct rate_control_ops *ops; |
| 104 | const char *alg_name; | 104 | const char *alg_name; |
| 105 | 105 | ||
| 106 | kparam_block_sysfs_write(ieee80211_default_rc_algo); | ||
| 106 | if (!name) | 107 | if (!name) |
| 107 | alg_name = ieee80211_default_rc_algo; | 108 | alg_name = ieee80211_default_rc_algo; |
| 108 | else | 109 | else |
| @@ -120,6 +121,7 @@ ieee80211_rate_control_ops_get(const char *name) | |||
| 120 | /* try built-in one if specific alg requested but not found */ | 121 | /* try built-in one if specific alg requested but not found */ |
| 121 | if (!ops && strlen(CONFIG_MAC80211_RC_DEFAULT)) | 122 | if (!ops && strlen(CONFIG_MAC80211_RC_DEFAULT)) |
| 122 | ops = ieee80211_try_rate_control_ops_get(CONFIG_MAC80211_RC_DEFAULT); | 123 | ops = ieee80211_try_rate_control_ops_get(CONFIG_MAC80211_RC_DEFAULT); |
| 124 | kparam_unblock_sysfs_write(ieee80211_default_rc_algo); | ||
| 123 | 125 | ||
| 124 | return ops; | 126 | return ops; |
| 125 | } | 127 | } |
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index 880d0de3f50f..36cb66022a27 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c | |||
| @@ -39,7 +39,7 @@ static LIST_HEAD(cred_unused); | |||
| 39 | static unsigned long number_cred_unused; | 39 | static unsigned long number_cred_unused; |
| 40 | 40 | ||
| 41 | #define MAX_HASHTABLE_BITS (10) | 41 | #define MAX_HASHTABLE_BITS (10) |
| 42 | static int param_set_hashtbl_sz(const char *val, struct kernel_param *kp) | 42 | static int param_set_hashtbl_sz(const char *val, const struct kernel_param *kp) |
| 43 | { | 43 | { |
| 44 | unsigned long num; | 44 | unsigned long num; |
| 45 | unsigned int nbits; | 45 | unsigned int nbits; |
| @@ -61,7 +61,7 @@ out_inval: | |||
| 61 | return -EINVAL; | 61 | return -EINVAL; |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | static int param_get_hashtbl_sz(char *buffer, struct kernel_param *kp) | 64 | static int param_get_hashtbl_sz(char *buffer, const struct kernel_param *kp) |
| 65 | { | 65 | { |
| 66 | unsigned int nbits; | 66 | unsigned int nbits; |
| 67 | 67 | ||
| @@ -71,6 +71,11 @@ static int param_get_hashtbl_sz(char *buffer, struct kernel_param *kp) | |||
| 71 | 71 | ||
| 72 | #define param_check_hashtbl_sz(name, p) __param_check(name, p, unsigned int); | 72 | #define param_check_hashtbl_sz(name, p) __param_check(name, p, unsigned int); |
| 73 | 73 | ||
| 74 | static struct kernel_param_ops param_ops_hashtbl_sz = { | ||
| 75 | .set = param_set_hashtbl_sz, | ||
| 76 | .get = param_get_hashtbl_sz, | ||
| 77 | }; | ||
| 78 | |||
| 74 | module_param_named(auth_hashtable_size, auth_hashbits, hashtbl_sz, 0644); | 79 | module_param_named(auth_hashtable_size, auth_hashbits, hashtbl_sz, 0644); |
| 75 | MODULE_PARM_DESC(auth_hashtable_size, "RPC credential cache hashtable size"); | 80 | MODULE_PARM_DESC(auth_hashtable_size, "RPC credential cache hashtable size"); |
| 76 | 81 | ||
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 7ca65c7005ea..49a62f0c4b87 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
| @@ -2577,7 +2577,8 @@ void cleanup_socket_xprt(void) | |||
| 2577 | xprt_unregister_transport(&xs_bc_tcp_transport); | 2577 | xprt_unregister_transport(&xs_bc_tcp_transport); |
| 2578 | } | 2578 | } |
| 2579 | 2579 | ||
| 2580 | static int param_set_uint_minmax(const char *val, struct kernel_param *kp, | 2580 | static int param_set_uint_minmax(const char *val, |
| 2581 | const struct kernel_param *kp, | ||
| 2581 | unsigned int min, unsigned int max) | 2582 | unsigned int min, unsigned int max) |
| 2582 | { | 2583 | { |
| 2583 | unsigned long num; | 2584 | unsigned long num; |
| @@ -2592,34 +2593,37 @@ static int param_set_uint_minmax(const char *val, struct kernel_param *kp, | |||
| 2592 | return 0; | 2593 | return 0; |
| 2593 | } | 2594 | } |
| 2594 | 2595 | ||
| 2595 | static int param_set_portnr(const char *val, struct kernel_param *kp) | 2596 | static int param_set_portnr(const char *val, const struct kernel_param *kp) |
| 2596 | { | 2597 | { |
| 2597 | return param_set_uint_minmax(val, kp, | 2598 | return param_set_uint_minmax(val, kp, |
| 2598 | RPC_MIN_RESVPORT, | 2599 | RPC_MIN_RESVPORT, |
| 2599 | RPC_MAX_RESVPORT); | 2600 | RPC_MAX_RESVPORT); |
| 2600 | } | 2601 | } |
| 2601 | 2602 | ||
| 2602 | static int param_get_portnr(char *buffer, struct kernel_param *kp) | 2603 | static struct kernel_param_ops param_ops_portnr = { |
| 2603 | { | 2604 | .set = param_set_portnr, |
| 2604 | return param_get_uint(buffer, kp); | 2605 | .get = param_get_uint, |
| 2605 | } | 2606 | }; |
| 2607 | |||
| 2606 | #define param_check_portnr(name, p) \ | 2608 | #define param_check_portnr(name, p) \ |
| 2607 | __param_check(name, p, unsigned int); | 2609 | __param_check(name, p, unsigned int); |
| 2608 | 2610 | ||
| 2609 | module_param_named(min_resvport, xprt_min_resvport, portnr, 0644); | 2611 | module_param_named(min_resvport, xprt_min_resvport, portnr, 0644); |
| 2610 | module_param_named(max_resvport, xprt_max_resvport, portnr, 0644); | 2612 | module_param_named(max_resvport, xprt_max_resvport, portnr, 0644); |
| 2611 | 2613 | ||
| 2612 | static int param_set_slot_table_size(const char *val, struct kernel_param *kp) | 2614 | static int param_set_slot_table_size(const char *val, |
| 2615 | const struct kernel_param *kp) | ||
| 2613 | { | 2616 | { |
| 2614 | return param_set_uint_minmax(val, kp, | 2617 | return param_set_uint_minmax(val, kp, |
| 2615 | RPC_MIN_SLOT_TABLE, | 2618 | RPC_MIN_SLOT_TABLE, |
| 2616 | RPC_MAX_SLOT_TABLE); | 2619 | RPC_MAX_SLOT_TABLE); |
| 2617 | } | 2620 | } |
| 2618 | 2621 | ||
| 2619 | static int param_get_slot_table_size(char *buffer, struct kernel_param *kp) | 2622 | static struct kernel_param_ops param_ops_slot_table_size = { |
| 2620 | { | 2623 | .set = param_set_slot_table_size, |
| 2621 | return param_get_uint(buffer, kp); | 2624 | .get = param_get_uint, |
| 2622 | } | 2625 | }; |
| 2626 | |||
| 2623 | #define param_check_slot_table_size(name, p) \ | 2627 | #define param_check_slot_table_size(name, p) \ |
| 2624 | __param_check(name, p, unsigned int); | 2628 | __param_check(name, p, unsigned int); |
| 2625 | 2629 | ||
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 253c107b9a99..1ec7158b6c1f 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c | |||
| @@ -1035,6 +1035,13 @@ static const struct sectioncheck *section_mismatch( | |||
| 1035 | * fromsec = .data* | 1035 | * fromsec = .data* |
| 1036 | * atsym =__param* | 1036 | * atsym =__param* |
| 1037 | * | 1037 | * |
| 1038 | * Pattern 1a: | ||
| 1039 | * module_param_call() ops can refer to __init set function if permissions=0 | ||
| 1040 | * The pattern is identified by: | ||
| 1041 | * tosec = .init.text | ||
| 1042 | * fromsec = .data* | ||
| 1043 | * atsym = __param_ops_* | ||
| 1044 | * | ||
| 1038 | * Pattern 2: | 1045 | * Pattern 2: |
| 1039 | * Many drivers utilise a *driver container with references to | 1046 | * Many drivers utilise a *driver container with references to |
| 1040 | * add, remove, probe functions etc. | 1047 | * add, remove, probe functions etc. |
| @@ -1069,6 +1076,12 @@ static int secref_whitelist(const struct sectioncheck *mismatch, | |||
| 1069 | (strncmp(fromsym, "__param", strlen("__param")) == 0)) | 1076 | (strncmp(fromsym, "__param", strlen("__param")) == 0)) |
| 1070 | return 0; | 1077 | return 0; |
| 1071 | 1078 | ||
| 1079 | /* Check for pattern 1a */ | ||
| 1080 | if (strcmp(tosec, ".init.text") == 0 && | ||
| 1081 | match(fromsec, data_sections) && | ||
| 1082 | (strncmp(fromsym, "__param_ops_", strlen("__param_ops_")) == 0)) | ||
| 1083 | return 0; | ||
| 1084 | |||
| 1072 | /* Check for pattern 2 */ | 1085 | /* Check for pattern 2 */ |
| 1073 | if (match(tosec, init_exit_sections) && | 1086 | if (match(tosec, init_exit_sections) && |
| 1074 | match(fromsec, data_sections) && | 1087 | match(fromsec, data_sections) && |
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 8db33a8b50c4..d5666d3cc21b 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c | |||
| @@ -667,17 +667,29 @@ static struct security_operations apparmor_ops = { | |||
| 667 | * AppArmor sysfs module parameters | 667 | * AppArmor sysfs module parameters |
| 668 | */ | 668 | */ |
| 669 | 669 | ||
| 670 | static int param_set_aabool(const char *val, struct kernel_param *kp); | 670 | static int param_set_aabool(const char *val, const struct kernel_param *kp); |
| 671 | static int param_get_aabool(char *buffer, struct kernel_param *kp); | 671 | static int param_get_aabool(char *buffer, const struct kernel_param *kp); |
| 672 | #define param_check_aabool(name, p) __param_check(name, p, int) | 672 | #define param_check_aabool(name, p) __param_check(name, p, int) |
| 673 | static struct kernel_param_ops param_ops_aabool = { | ||
| 674 | .set = param_set_aabool, | ||
| 675 | .get = param_get_aabool | ||
| 676 | }; | ||
| 673 | 677 | ||
| 674 | static int param_set_aauint(const char *val, struct kernel_param *kp); | 678 | static int param_set_aauint(const char *val, const struct kernel_param *kp); |
| 675 | static int param_get_aauint(char *buffer, struct kernel_param *kp); | 679 | static int param_get_aauint(char *buffer, const struct kernel_param *kp); |
| 676 | #define param_check_aauint(name, p) __param_check(name, p, int) | 680 | #define param_check_aauint(name, p) __param_check(name, p, int) |
| 681 | static struct kernel_param_ops param_ops_aauint = { | ||
| 682 | .set = param_set_aauint, | ||
| 683 | .get = param_get_aauint | ||
| 684 | }; | ||
| 677 | 685 | ||
| 678 | static int param_set_aalockpolicy(const char *val, struct kernel_param *kp); | 686 | static int param_set_aalockpolicy(const char *val, const struct kernel_param *kp); |
| 679 | static int param_get_aalockpolicy(char *buffer, struct kernel_param *kp); | 687 | static int param_get_aalockpolicy(char *buffer, const struct kernel_param *kp); |
| 680 | #define param_check_aalockpolicy(name, p) __param_check(name, p, int) | 688 | #define param_check_aalockpolicy(name, p) __param_check(name, p, int) |
| 689 | static struct kernel_param_ops param_ops_aalockpolicy = { | ||
| 690 | .set = param_set_aalockpolicy, | ||
| 691 | .get = param_get_aalockpolicy | ||
| 692 | }; | ||
| 681 | 693 | ||
| 682 | static int param_set_audit(const char *val, struct kernel_param *kp); | 694 | static int param_set_audit(const char *val, struct kernel_param *kp); |
| 683 | static int param_get_audit(char *buffer, struct kernel_param *kp); | 695 | static int param_get_audit(char *buffer, struct kernel_param *kp); |
| @@ -751,7 +763,7 @@ static int __init apparmor_enabled_setup(char *str) | |||
| 751 | __setup("apparmor=", apparmor_enabled_setup); | 763 | __setup("apparmor=", apparmor_enabled_setup); |
| 752 | 764 | ||
| 753 | /* set global flag turning off the ability to load policy */ | 765 | /* set global flag turning off the ability to load policy */ |
| 754 | static int param_set_aalockpolicy(const char *val, struct kernel_param *kp) | 766 | static int param_set_aalockpolicy(const char *val, const struct kernel_param *kp) |
| 755 | { | 767 | { |
| 756 | if (!capable(CAP_MAC_ADMIN)) | 768 | if (!capable(CAP_MAC_ADMIN)) |
| 757 | return -EPERM; | 769 | return -EPERM; |
| @@ -760,35 +772,35 @@ static int param_set_aalockpolicy(const char *val, struct kernel_param *kp) | |||
| 760 | return param_set_bool(val, kp); | 772 | return param_set_bool(val, kp); |
| 761 | } | 773 | } |
| 762 | 774 | ||
| 763 | static int param_get_aalockpolicy(char *buffer, struct kernel_param *kp) | 775 | static int param_get_aalockpolicy(char *buffer, const struct kernel_param *kp) |
| 764 | { | 776 | { |
| 765 | if (!capable(CAP_MAC_ADMIN)) | 777 | if (!capable(CAP_MAC_ADMIN)) |
| 766 | return -EPERM; | 778 | return -EPERM; |
| 767 | return param_get_bool(buffer, kp); | 779 | return param_get_bool(buffer, kp); |
| 768 | } | 780 | } |
| 769 | 781 | ||
| 770 | static int param_set_aabool(const char *val, struct kernel_param *kp) | 782 | static int param_set_aabool(const char *val, const struct kernel_param *kp) |
| 771 | { | 783 | { |
| 772 | if (!capable(CAP_MAC_ADMIN)) | 784 | if (!capable(CAP_MAC_ADMIN)) |
| 773 | return -EPERM; | 785 | return -EPERM; |
| 774 | return param_set_bool(val, kp); | 786 | return param_set_bool(val, kp); |
| 775 | } | 787 | } |
| 776 | 788 | ||
| 777 | static int param_get_aabool(char *buffer, struct kernel_param *kp) | 789 | static int param_get_aabool(char *buffer, const struct kernel_param *kp) |
| 778 | { | 790 | { |
| 779 | if (!capable(CAP_MAC_ADMIN)) | 791 | if (!capable(CAP_MAC_ADMIN)) |
| 780 | return -EPERM; | 792 | return -EPERM; |
| 781 | return param_get_bool(buffer, kp); | 793 | return param_get_bool(buffer, kp); |
| 782 | } | 794 | } |
| 783 | 795 | ||
| 784 | static int param_set_aauint(const char *val, struct kernel_param *kp) | 796 | static int param_set_aauint(const char *val, const struct kernel_param *kp) |
| 785 | { | 797 | { |
| 786 | if (!capable(CAP_MAC_ADMIN)) | 798 | if (!capable(CAP_MAC_ADMIN)) |
| 787 | return -EPERM; | 799 | return -EPERM; |
| 788 | return param_set_uint(val, kp); | 800 | return param_set_uint(val, kp); |
| 789 | } | 801 | } |
| 790 | 802 | ||
| 791 | static int param_get_aauint(char *buffer, struct kernel_param *kp) | 803 | static int param_get_aauint(char *buffer, const struct kernel_param *kp) |
| 792 | { | 804 | { |
| 793 | if (!capable(CAP_MAC_ADMIN)) | 805 | if (!capable(CAP_MAC_ADMIN)) |
| 794 | return -EPERM; | 806 | return -EPERM; |
