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/machzwd.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/machzwd.c')
-rw-r--r-- | drivers/char/watchdog/machzwd.c | 18 |
1 files changed, 9 insertions, 9 deletions
diff --git a/drivers/char/watchdog/machzwd.c b/drivers/char/watchdog/machzwd.c index 76c7fa37fa6c..a0d27160c80e 100644 --- a/drivers/char/watchdog/machzwd.c +++ b/drivers/char/watchdog/machzwd.c | |||
@@ -440,13 +440,6 @@ static int __init zf_init(void) | |||
440 | spin_lock_init(&zf_lock); | 440 | spin_lock_init(&zf_lock); |
441 | spin_lock_init(&zf_port_lock); | 441 | spin_lock_init(&zf_port_lock); |
442 | 442 | ||
443 | ret = misc_register(&zf_miscdev); | ||
444 | if (ret){ | ||
445 | printk(KERN_ERR "can't misc_register on minor=%d\n", | ||
446 | WATCHDOG_MINOR); | ||
447 | goto out; | ||
448 | } | ||
449 | |||
450 | if(!request_region(ZF_IOBASE, 3, "MachZ ZFL WDT")){ | 443 | if(!request_region(ZF_IOBASE, 3, "MachZ ZFL WDT")){ |
451 | printk(KERN_ERR "cannot reserve I/O ports at %d\n", | 444 | printk(KERN_ERR "cannot reserve I/O ports at %d\n", |
452 | ZF_IOBASE); | 445 | ZF_IOBASE); |
@@ -461,16 +454,23 @@ static int __init zf_init(void) | |||
461 | goto no_reboot; | 454 | goto no_reboot; |
462 | } | 455 | } |
463 | 456 | ||
457 | ret = misc_register(&zf_miscdev); | ||
458 | if (ret){ | ||
459 | printk(KERN_ERR "can't misc_register on minor=%d\n", | ||
460 | WATCHDOG_MINOR); | ||
461 | goto no_misc; | ||
462 | } | ||
463 | |||
464 | zf_set_status(0); | 464 | zf_set_status(0); |
465 | zf_set_control(0); | 465 | zf_set_control(0); |
466 | 466 | ||
467 | return 0; | 467 | return 0; |
468 | 468 | ||
469 | no_misc: | ||
470 | unregister_reboot_notifier(&zf_notifier); | ||
469 | no_reboot: | 471 | no_reboot: |
470 | release_region(ZF_IOBASE, 3); | 472 | release_region(ZF_IOBASE, 3); |
471 | no_region: | 473 | no_region: |
472 | misc_deregister(&zf_miscdev); | ||
473 | out: | ||
474 | return ret; | 474 | return ret; |
475 | } | 475 | } |
476 | 476 | ||