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/cpu5wdt.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/cpu5wdt.c')
-rw-r--r-- | drivers/char/watchdog/cpu5wdt.c | 14 |
1 files changed, 7 insertions, 7 deletions
diff --git a/drivers/char/watchdog/cpu5wdt.c b/drivers/char/watchdog/cpu5wdt.c index bcd7e36ca0aa..d0d45a8b09f0 100644 --- a/drivers/char/watchdog/cpu5wdt.c +++ b/drivers/char/watchdog/cpu5wdt.c | |||
@@ -220,17 +220,17 @@ static int __devinit cpu5wdt_init(void) | |||
220 | if ( verbose ) | 220 | if ( verbose ) |
221 | printk(KERN_DEBUG PFX "port=0x%x, verbose=%i\n", port, verbose); | 221 | printk(KERN_DEBUG PFX "port=0x%x, verbose=%i\n", port, verbose); |
222 | 222 | ||
223 | if ( (err = misc_register(&cpu5wdt_misc)) < 0 ) { | ||
224 | printk(KERN_ERR PFX "misc_register failed\n"); | ||
225 | goto no_misc; | ||
226 | } | ||
227 | |||
228 | if ( !request_region(port, CPU5WDT_EXTENT, PFX) ) { | 223 | if ( !request_region(port, CPU5WDT_EXTENT, PFX) ) { |
229 | printk(KERN_ERR PFX "request_region failed\n"); | 224 | printk(KERN_ERR PFX "request_region failed\n"); |
230 | err = -EBUSY; | 225 | err = -EBUSY; |
231 | goto no_port; | 226 | goto no_port; |
232 | } | 227 | } |
233 | 228 | ||
229 | if ( (err = misc_register(&cpu5wdt_misc)) < 0 ) { | ||
230 | printk(KERN_ERR PFX "misc_register failed\n"); | ||
231 | goto no_misc; | ||
232 | } | ||
233 | |||
234 | /* watchdog reboot? */ | 234 | /* watchdog reboot? */ |
235 | val = inb(port + CPU5WDT_STATUS_REG); | 235 | val = inb(port + CPU5WDT_STATUS_REG); |
236 | val = (val >> 2) & 1; | 236 | val = (val >> 2) & 1; |
@@ -250,9 +250,9 @@ static int __devinit cpu5wdt_init(void) | |||
250 | 250 | ||
251 | return 0; | 251 | return 0; |
252 | 252 | ||
253 | no_port: | ||
254 | misc_deregister(&cpu5wdt_misc); | ||
255 | no_misc: | 253 | no_misc: |
254 | release_region(port, CPU5WDT_EXTENT); | ||
255 | no_port: | ||
256 | return err; | 256 | return err; |
257 | } | 257 | } |
258 | 258 | ||