diff options
author | Alexey Dobriyan <adobriyan@gmail.com> | 2007-03-24 08:58:12 -0400 |
---|---|---|
committer | Wim Van Sebroeck <wim@iguana.be> | 2007-03-26 16:26:11 -0400 |
commit | fb8f7ba077b5c665432082ab205bcd2cb01f6a3c (patch) | |
tree | 13a956eb9a1723bd3d5463230acbfc6513f3b034 /drivers/char/watchdog/sbc8360.c | |
parent | 0e94f2ee0d1947ba6c2c00c3e971ff93ce8edec1 (diff) |
[WATCHDOG] Semi-typical watchdog bug re early misc_register()
It seems that some watchdog drivers are doing following mistake:
rv = misc_register();
if (rv < 0)
return rv;
rv = request_region();
if (rv < 0) {
misc_deregister();
return rv;
}
But, right after misc_register() returns, misc device can be opened and
ioctls interacting with hardware issued, and driver can do outb() to
port it doesn't own yet, because request_region() is still pending.
Here is my patch, compile-tested only.
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
Diffstat (limited to 'drivers/char/watchdog/sbc8360.c')
-rw-r--r-- | drivers/char/watchdog/sbc8360.c | 28 |
1 files changed, 14 insertions, 14 deletions
diff --git a/drivers/char/watchdog/sbc8360.c b/drivers/char/watchdog/sbc8360.c index 67ae42685e75..285d85289532 100644 --- a/drivers/char/watchdog/sbc8360.c +++ b/drivers/char/watchdog/sbc8360.c | |||
@@ -333,18 +333,17 @@ static int __init sbc8360_init(void) | |||
333 | int res; | 333 | int res; |
334 | unsigned long int mseconds = 60000; | 334 | unsigned long int mseconds = 60000; |
335 | 335 | ||
336 | spin_lock_init(&sbc8360_lock); | 336 | if (timeout < 0 || timeout > 63) { |
337 | res = misc_register(&sbc8360_miscdev); | 337 | printk(KERN_ERR PFX "Invalid timeout index (must be 0-63).\n"); |
338 | if (res) { | 338 | res = -EINVAL; |
339 | printk(KERN_ERR PFX "failed to register misc device\n"); | 339 | goto out; |
340 | goto out_nomisc; | ||
341 | } | 340 | } |
342 | 341 | ||
343 | if (!request_region(SBC8360_ENABLE, 1, "SBC8360")) { | 342 | if (!request_region(SBC8360_ENABLE, 1, "SBC8360")) { |
344 | printk(KERN_ERR PFX "ENABLE method I/O %X is not available.\n", | 343 | printk(KERN_ERR PFX "ENABLE method I/O %X is not available.\n", |
345 | SBC8360_ENABLE); | 344 | SBC8360_ENABLE); |
346 | res = -EIO; | 345 | res = -EIO; |
347 | goto out_noenablereg; | 346 | goto out; |
348 | } | 347 | } |
349 | if (!request_region(SBC8360_BASETIME, 1, "SBC8360")) { | 348 | if (!request_region(SBC8360_BASETIME, 1, "SBC8360")) { |
350 | printk(KERN_ERR PFX | 349 | printk(KERN_ERR PFX |
@@ -360,10 +359,11 @@ static int __init sbc8360_init(void) | |||
360 | goto out_noreboot; | 359 | goto out_noreboot; |
361 | } | 360 | } |
362 | 361 | ||
363 | if (timeout < 0 || timeout > 63) { | 362 | spin_lock_init(&sbc8360_lock); |
364 | printk(KERN_ERR PFX "Invalid timeout index (must be 0-63).\n"); | 363 | res = misc_register(&sbc8360_miscdev); |
365 | res = -EINVAL; | 364 | if (res) { |
366 | goto out_noreboot; | 365 | printk(KERN_ERR PFX "failed to register misc device\n"); |
366 | goto out_nomisc; | ||
367 | } | 367 | } |
368 | 368 | ||
369 | wd_margin = wd_times[timeout][0]; | 369 | wd_margin = wd_times[timeout][0]; |
@@ -383,13 +383,13 @@ static int __init sbc8360_init(void) | |||
383 | 383 | ||
384 | return 0; | 384 | return 0; |
385 | 385 | ||
386 | out_nomisc: | ||
387 | unregister_reboot_notifier(&sbc8360_notifier); | ||
386 | out_noreboot: | 388 | out_noreboot: |
387 | release_region(SBC8360_ENABLE, 1); | ||
388 | release_region(SBC8360_BASETIME, 1); | 389 | release_region(SBC8360_BASETIME, 1); |
389 | out_noenablereg: | ||
390 | out_nobasetimereg: | 390 | out_nobasetimereg: |
391 | misc_deregister(&sbc8360_miscdev); | 391 | release_region(SBC8360_ENABLE, 1); |
392 | out_nomisc: | 392 | out: |
393 | return res; | 393 | return res; |
394 | } | 394 | } |
395 | 395 | ||