aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/watchdog/cpu5wdt.c
diff options
context:
space:
mode:
authorAlexey Dobriyan <adobriyan@gmail.com>2007-03-24 08:58:12 -0400
committerWim Van Sebroeck <wim@iguana.be>2007-03-26 16:26:11 -0400
commitfb8f7ba077b5c665432082ab205bcd2cb01f6a3c (patch)
tree13a956eb9a1723bd3d5463230acbfc6513f3b034 /drivers/char/watchdog/cpu5wdt.c
parent0e94f2ee0d1947ba6c2c00c3e971ff93ce8edec1 (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.c14
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
253no_port:
254 misc_deregister(&cpu5wdt_misc);
255no_misc: 253no_misc:
254 release_region(port, CPU5WDT_EXTENT);
255no_port:
256 return err; 256 return err;
257} 257}
258 258