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/eurotechwdt.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/eurotechwdt.c')
-rw-r--r-- | drivers/char/watchdog/eurotechwdt.c | 22 |
1 files changed, 11 insertions, 11 deletions
diff --git a/drivers/char/watchdog/eurotechwdt.c b/drivers/char/watchdog/eurotechwdt.c index f70387f01b2b..b070324e27a6 100644 --- a/drivers/char/watchdog/eurotechwdt.c +++ b/drivers/char/watchdog/eurotechwdt.c | |||
@@ -413,17 +413,10 @@ static int __init eurwdt_init(void) | |||
413 | { | 413 | { |
414 | int ret; | 414 | int ret; |
415 | 415 | ||
416 | ret = misc_register(&eurwdt_miscdev); | ||
417 | if (ret) { | ||
418 | printk(KERN_ERR "eurwdt: can't misc_register on minor=%d\n", | ||
419 | WATCHDOG_MINOR); | ||
420 | goto out; | ||
421 | } | ||
422 | |||
423 | ret = request_irq(irq, eurwdt_interrupt, IRQF_DISABLED, "eurwdt", NULL); | 416 | ret = request_irq(irq, eurwdt_interrupt, IRQF_DISABLED, "eurwdt", NULL); |
424 | if(ret) { | 417 | if(ret) { |
425 | printk(KERN_ERR "eurwdt: IRQ %d is not free.\n", irq); | 418 | printk(KERN_ERR "eurwdt: IRQ %d is not free.\n", irq); |
426 | goto outmisc; | 419 | goto out; |
427 | } | 420 | } |
428 | 421 | ||
429 | if (!request_region(io, 2, "eurwdt")) { | 422 | if (!request_region(io, 2, "eurwdt")) { |
@@ -438,6 +431,13 @@ static int __init eurwdt_init(void) | |||
438 | goto outreg; | 431 | goto outreg; |
439 | } | 432 | } |
440 | 433 | ||
434 | ret = misc_register(&eurwdt_miscdev); | ||
435 | if (ret) { | ||
436 | printk(KERN_ERR "eurwdt: can't misc_register on minor=%d\n", | ||
437 | WATCHDOG_MINOR); | ||
438 | goto outreboot; | ||
439 | } | ||
440 | |||
441 | eurwdt_unlock_chip(); | 441 | eurwdt_unlock_chip(); |
442 | 442 | ||
443 | ret = 0; | 443 | ret = 0; |
@@ -448,14 +448,14 @@ static int __init eurwdt_init(void) | |||
448 | out: | 448 | out: |
449 | return ret; | 449 | return ret; |
450 | 450 | ||
451 | outreboot: | ||
452 | unregister_reboot_notifier(&eurwdt_notifier); | ||
453 | |||
451 | outreg: | 454 | outreg: |
452 | release_region(io, 2); | 455 | release_region(io, 2); |
453 | 456 | ||
454 | outirq: | 457 | outirq: |
455 | free_irq(irq, NULL); | 458 | free_irq(irq, NULL); |
456 | |||
457 | outmisc: | ||
458 | misc_deregister(&eurwdt_miscdev); | ||
459 | goto out; | 459 | goto out; |
460 | } | 460 | } |
461 | 461 | ||