Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge master.kernel.org:/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog

+239 -223
+232 -218
drivers/char/watchdog/pcwd.c
··· 49 49 * More info available at http://www.berkprod.com/ or http://www.pcwatchdog.com/ 50 50 */ 51 51 52 - #include <linux/module.h> 53 - #include <linux/moduleparam.h> 54 - #include <linux/types.h> 55 - #include <linux/timer.h> 56 - #include <linux/jiffies.h> 57 - #include <linux/config.h> 58 - #include <linux/wait.h> 59 - #include <linux/slab.h> 60 - #include <linux/ioport.h> 61 - #include <linux/delay.h> 62 - #include <linux/fs.h> 63 - #include <linux/miscdevice.h> 64 - #include <linux/watchdog.h> 65 - #include <linux/notifier.h> 66 - #include <linux/init.h> 67 - #include <linux/spinlock.h> 68 - #include <linux/reboot.h> 52 + #include <linux/config.h> /* For CONFIG_WATCHDOG_NOWAYOUT/... */ 53 + #include <linux/module.h> /* For module specific items */ 54 + #include <linux/moduleparam.h> /* For new moduleparam's */ 55 + #include <linux/types.h> /* For standard types (like size_t) */ 56 + #include <linux/errno.h> /* For the -ENODEV/... values */ 57 + #include <linux/kernel.h> /* For printk/panic/... */ 58 + #include <linux/delay.h> /* For mdelay function */ 59 + #include <linux/timer.h> /* For timer related operations */ 60 + #include <linux/jiffies.h> /* For jiffies stuff */ 61 + #include <linux/miscdevice.h> /* For MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR) */ 62 + #include <linux/watchdog.h> /* For the watchdog specific items */ 63 + #include <linux/notifier.h> /* For notifier support */ 64 + #include <linux/reboot.h> /* For reboot_notifier stuff */ 65 + #include <linux/init.h> /* For __init/__exit/... */ 66 + #include <linux/fs.h> /* For file operations */ 67 + #include <linux/ioport.h> /* For io-port access */ 68 + #include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ 69 69 #include <linux/sched.h> /* TASK_INTERRUPTIBLE, set_current_state() and friends */ 70 - #include <asm/uaccess.h> 71 - #include <asm/io.h> 70 + #include <linux/slab.h> /* For kmalloc */ 72 71 73 - #define WD_VER "1.16 (06/12/2004)" 74 - #define PFX "pcwd: " 72 + #include <asm/uaccess.h> /* For copy_to_user/put_user/... */ 73 + #include <asm/io.h> /* For inb/outb/... */ 74 + 75 + /* Module and version information */ 76 + #define WATCHDOG_VERSION "1.16" 77 + #define WATCHDOG_DATE "03 Jan 2006" 78 + #define WATCHDOG_DRIVER_NAME "ISA-PC Watchdog" 79 + #define WATCHDOG_NAME "pcwd" 80 + #define PFX WATCHDOG_NAME ": " 81 + #define DRIVER_VERSION WATCHDOG_DRIVER_NAME " driver, v" WATCHDOG_VERSION " (" WATCHDOG_DATE ")\n" 82 + #define WD_VER WATCHDOG_VERSION " (" WATCHDOG_DATE ")" 75 83 76 84 /* 77 85 * It should be noted that PCWD_REVISION_B was removed because A and B ··· 93 85 94 86 /* 95 87 * These are the defines that describe the control status bits for the 96 - * PC Watchdog card, revision A. 97 - */ 88 + * PCI-PC Watchdog card. 89 + */ 90 + /* Port 1 : Control Status #1 for the PC Watchdog card, revision A. */ 98 91 #define WD_WDRST 0x01 /* Previously reset state */ 99 92 #define WD_T110 0x02 /* Temperature overheat sense */ 100 93 #define WD_HRTBT 0x04 /* Heartbeat sense */ 101 94 #define WD_RLY2 0x08 /* External relay triggered */ 102 95 #define WD_SRLY2 0x80 /* Software external relay triggered */ 103 - 104 - /* 105 - * These are the defines that describe the control status bits for the 106 - * PC Watchdog card, revision C. 107 - */ 96 + /* Port 1 : Control Status #1 for the PC Watchdog card, revision C. */ 108 97 #define WD_REVC_WTRP 0x01 /* Watchdog Trip status */ 109 98 #define WD_REVC_HRBT 0x02 /* Watchdog Heartbeat */ 110 99 #define WD_REVC_TTRP 0x04 /* Temperature Trip status */ 100 + /* Port 2 : Control Status #2 */ 101 + #define WD_WDIS 0x10 /* Watchdog Disabled */ 102 + #define WD_ENTP 0x20 /* Watchdog Enable Temperature Trip */ 103 + #define WD_SSEL 0x40 /* Watchdog Switch Select (1:SW1 <-> 0:SW2) */ 104 + #define WD_WCMD 0x80 /* Watchdog Command Mode */ 111 105 112 106 /* max. time we give an ISA watchdog card to process a command */ 113 107 /* 500ms for each 4 bit response (according to spec.) */ 114 108 #define ISA_COMMAND_TIMEOUT 1000 115 109 116 110 /* Watchdog's internal commands */ 117 - #define CMD_ISA_IDLE 0x00 118 - #define CMD_ISA_VERSION_INTEGER 0x01 119 - #define CMD_ISA_VERSION_TENTH 0x02 120 - #define CMD_ISA_VERSION_HUNDRETH 0x03 121 - #define CMD_ISA_VERSION_MINOR 0x04 122 - #define CMD_ISA_SWITCH_SETTINGS 0x05 123 - #define CMD_ISA_DELAY_TIME_2SECS 0x0A 124 - #define CMD_ISA_DELAY_TIME_4SECS 0x0B 125 - #define CMD_ISA_DELAY_TIME_8SECS 0x0C 111 + #define CMD_ISA_IDLE 0x00 112 + #define CMD_ISA_VERSION_INTEGER 0x01 113 + #define CMD_ISA_VERSION_TENTH 0x02 114 + #define CMD_ISA_VERSION_HUNDRETH 0x03 115 + #define CMD_ISA_VERSION_MINOR 0x04 116 + #define CMD_ISA_SWITCH_SETTINGS 0x05 117 + #define CMD_ISA_DELAY_TIME_2SECS 0x0A 118 + #define CMD_ISA_DELAY_TIME_4SECS 0x0B 119 + #define CMD_ISA_DELAY_TIME_8SECS 0x0C 126 120 127 121 /* 128 122 * We are using an kernel timer to do the pinging of the watchdog ··· 140 130 /* internal variables */ 141 131 static atomic_t open_allowed = ATOMIC_INIT(1); 142 132 static char expect_close; 143 - static struct timer_list timer; 144 - static unsigned long next_heartbeat; 145 133 static int temp_panic; 146 - static int revision; /* The card's revision */ 147 - static int supports_temp; /* Wether or not the card has a temperature device */ 148 - static int command_mode; /* Wether or not the card is in command mode */ 149 - static int initial_status; /* The card's boot status */ 150 - static int current_readport; /* The cards I/O address */ 151 - static spinlock_t io_lock; 134 + static struct { /* this is private data for each ISA-PC watchdog card */ 135 + int revision; /* The card's revision */ 136 + int supports_temp; /* Wether or not the card has a temperature device */ 137 + int command_mode; /* Wether or not the card is in command mode */ 138 + int boot_status; /* The card's boot status */ 139 + int io_addr; /* The cards I/O address */ 140 + spinlock_t io_lock; /* the lock for io operations */ 141 + struct timer_list timer; /* The timer that pings the watchdog */ 142 + unsigned long next_heartbeat; /* the next_heartbeat for the timer */ 143 + } pcwd_private; 152 144 153 145 /* module parameters */ 154 146 #define WATCHDOG_HEARTBEAT 60 /* 60 sec default heartbeat */ ··· 173 161 int port0, last_port0; /* Double read for stabilising */ 174 162 175 163 /* The WCMD bit must be 1 and the command is only 4 bits in size */ 176 - control_status = (cmd & 0x0F) | 0x80; 177 - outb_p(control_status, current_readport + 2); 164 + control_status = (cmd & 0x0F) | WD_WCMD; 165 + outb_p(control_status, pcwd_private.io_addr + 2); 178 166 udelay(ISA_COMMAND_TIMEOUT); 179 167 180 - port0 = inb_p(current_readport); 168 + port0 = inb_p(pcwd_private.io_addr); 181 169 for (i = 0; i < 25; ++i) { 182 170 last_port0 = port0; 183 - port0 = inb_p(current_readport); 171 + port0 = inb_p(pcwd_private.io_addr); 184 172 185 173 if (port0 == last_port0) 186 174 break; /* Data is stable */ ··· 196 184 int i, found=0, count=0; 197 185 198 186 /* Set the card into command mode */ 199 - spin_lock(&io_lock); 187 + spin_lock(&pcwd_private.io_lock); 200 188 while ((!found) && (count < 3)) { 201 189 i = send_isa_command(CMD_ISA_IDLE); 202 190 ··· 204 192 found = 1; 205 193 else if (i == 0xF3) { 206 194 /* Card does not like what we've done to it */ 207 - outb_p(0x00, current_readport + 2); 195 + outb_p(0x00, pcwd_private.io_addr + 2); 208 196 udelay(1200); /* Spec says wait 1ms */ 209 - outb_p(0x00, current_readport + 2); 197 + outb_p(0x00, pcwd_private.io_addr + 2); 210 198 udelay(ISA_COMMAND_TIMEOUT); 211 199 } 212 200 count++; 213 201 } 214 - spin_unlock(&io_lock); 215 - command_mode = found; 202 + spin_unlock(&pcwd_private.io_lock); 203 + pcwd_private.command_mode = found; 216 204 217 205 return(found); 218 206 } ··· 220 208 static void unset_command_mode(void) 221 209 { 222 210 /* Set the card into normal mode */ 223 - spin_lock(&io_lock); 224 - outb_p(0x00, current_readport + 2); 211 + spin_lock(&pcwd_private.io_lock); 212 + outb_p(0x00, pcwd_private.io_addr + 2); 225 213 udelay(ISA_COMMAND_TIMEOUT); 226 - spin_unlock(&io_lock); 214 + spin_unlock(&pcwd_private.io_lock); 227 215 228 - command_mode = 0; 216 + pcwd_private.command_mode = 0; 217 + } 218 + 219 + static inline void pcwd_check_temperature_support(void) 220 + { 221 + if (inb(pcwd_private.io_addr) != 0xF0) 222 + pcwd_private.supports_temp = 1; 223 + } 224 + 225 + static inline char *get_firmware(void) 226 + { 227 + int one, ten, hund, minor; 228 + char *ret; 229 + 230 + ret = kmalloc(6, GFP_KERNEL); 231 + if(ret == NULL) 232 + return NULL; 233 + 234 + if (set_command_mode()) { 235 + one = send_isa_command(CMD_ISA_VERSION_INTEGER); 236 + ten = send_isa_command(CMD_ISA_VERSION_TENTH); 237 + hund = send_isa_command(CMD_ISA_VERSION_HUNDRETH); 238 + minor = send_isa_command(CMD_ISA_VERSION_MINOR); 239 + sprintf(ret, "%c.%c%c%c", one, ten, hund, minor); 240 + } 241 + else 242 + sprintf(ret, "ERROR"); 243 + 244 + unset_command_mode(); 245 + return(ret); 246 + } 247 + 248 + static inline int pcwd_get_option_switches(void) 249 + { 250 + int option_switches=0; 251 + 252 + if (set_command_mode()) { 253 + /* Get switch settings */ 254 + option_switches = send_isa_command(CMD_ISA_SWITCH_SETTINGS); 255 + } 256 + 257 + unset_command_mode(); 258 + return(option_switches); 259 + } 260 + 261 + static void pcwd_show_card_info(void) 262 + { 263 + char *firmware; 264 + int option_switches; 265 + 266 + /* Get some extra info from the hardware (in command/debug/diag mode) */ 267 + if (pcwd_private.revision == PCWD_REVISION_A) 268 + printk(KERN_INFO PFX "ISA-PC Watchdog (REV.A) detected at port 0x%04x\n", pcwd_private.io_addr); 269 + else if (pcwd_private.revision == PCWD_REVISION_C) { 270 + firmware = get_firmware(); 271 + printk(KERN_INFO PFX "ISA-PC Watchdog (REV.C) detected at port 0x%04x (Firmware version: %s)\n", 272 + pcwd_private.io_addr, firmware); 273 + kfree(firmware); 274 + option_switches = pcwd_get_option_switches(); 275 + printk(KERN_INFO PFX "Option switches (0x%02x): Temperature Reset Enable=%s, Power On Delay=%s\n", 276 + option_switches, 277 + ((option_switches & 0x10) ? "ON" : "OFF"), 278 + ((option_switches & 0x08) ? "ON" : "OFF")); 279 + 280 + /* Reprogram internal heartbeat to 2 seconds */ 281 + if (set_command_mode()) { 282 + send_isa_command(CMD_ISA_DELAY_TIME_2SECS); 283 + unset_command_mode(); 284 + } 285 + } 286 + 287 + if (pcwd_private.supports_temp) 288 + printk(KERN_INFO PFX "Temperature Option Detected\n"); 289 + 290 + if (pcwd_private.boot_status & WDIOF_CARDRESET) 291 + printk(KERN_INFO PFX "Previous reboot was caused by the card\n"); 292 + 293 + if (pcwd_private.boot_status & WDIOF_OVERHEAT) { 294 + printk(KERN_EMERG PFX "Card senses a CPU Overheat. Panicking!\n"); 295 + printk(KERN_EMERG PFX "CPU Overheat\n"); 296 + } 297 + 298 + if (pcwd_private.boot_status == 0) 299 + printk(KERN_INFO PFX "No previous trip detected - Cold boot or reset\n"); 229 300 } 230 301 231 302 static void pcwd_timer_ping(unsigned long data) ··· 317 222 318 223 /* If we got a heartbeat pulse within the WDT_INTERVAL 319 224 * we agree to ping the WDT */ 320 - if(time_before(jiffies, next_heartbeat)) { 225 + if(time_before(jiffies, pcwd_private.next_heartbeat)) { 321 226 /* Ping the watchdog */ 322 - spin_lock(&io_lock); 323 - if (revision == PCWD_REVISION_A) { 227 + spin_lock(&pcwd_private.io_lock); 228 + if (pcwd_private.revision == PCWD_REVISION_A) { 324 229 /* Rev A cards are reset by setting the WD_WDRST bit in register 1 */ 325 - wdrst_stat = inb_p(current_readport); 230 + wdrst_stat = inb_p(pcwd_private.io_addr); 326 231 wdrst_stat &= 0x0F; 327 232 wdrst_stat |= WD_WDRST; 328 233 329 - outb_p(wdrst_stat, current_readport + 1); 234 + outb_p(wdrst_stat, pcwd_private.io_addr + 1); 330 235 } else { 331 236 /* Re-trigger watchdog by writing to port 0 */ 332 - outb_p(0x00, current_readport); 237 + outb_p(0x00, pcwd_private.io_addr); 333 238 } 334 239 335 240 /* Re-set the timer interval */ 336 - mod_timer(&timer, jiffies + WDT_INTERVAL); 241 + mod_timer(&pcwd_private.timer, jiffies + WDT_INTERVAL); 337 242 338 - spin_unlock(&io_lock); 243 + spin_unlock(&pcwd_private.io_lock); 339 244 } else { 340 245 printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); 341 246 } ··· 345 250 { 346 251 int stat_reg; 347 252 348 - next_heartbeat = jiffies + (heartbeat * HZ); 253 + pcwd_private.next_heartbeat = jiffies + (heartbeat * HZ); 349 254 350 255 /* Start the timer */ 351 - mod_timer(&timer, jiffies + WDT_INTERVAL); 256 + mod_timer(&pcwd_private.timer, jiffies + WDT_INTERVAL); 352 257 353 258 /* Enable the port */ 354 - if (revision == PCWD_REVISION_C) { 355 - spin_lock(&io_lock); 356 - outb_p(0x00, current_readport + 3); 259 + if (pcwd_private.revision == PCWD_REVISION_C) { 260 + spin_lock(&pcwd_private.io_lock); 261 + outb_p(0x00, pcwd_private.io_addr + 3); 357 262 udelay(ISA_COMMAND_TIMEOUT); 358 - stat_reg = inb_p(current_readport + 2); 359 - spin_unlock(&io_lock); 360 - if (stat_reg & 0x10) { 263 + stat_reg = inb_p(pcwd_private.io_addr + 2); 264 + spin_unlock(&pcwd_private.io_lock); 265 + if (stat_reg & WD_WDIS) { 361 266 printk(KERN_INFO PFX "Could not start watchdog\n"); 362 267 return -EIO; 363 268 } ··· 370 275 int stat_reg; 371 276 372 277 /* Stop the timer */ 373 - del_timer(&timer); 278 + del_timer(&pcwd_private.timer); 374 279 375 280 /* Disable the board */ 376 - if (revision == PCWD_REVISION_C) { 377 - spin_lock(&io_lock); 378 - outb_p(0xA5, current_readport + 3); 281 + if (pcwd_private.revision == PCWD_REVISION_C) { 282 + spin_lock(&pcwd_private.io_lock); 283 + outb_p(0xA5, pcwd_private.io_addr + 3); 379 284 udelay(ISA_COMMAND_TIMEOUT); 380 - outb_p(0xA5, current_readport + 3); 285 + outb_p(0xA5, pcwd_private.io_addr + 3); 381 286 udelay(ISA_COMMAND_TIMEOUT); 382 - stat_reg = inb_p(current_readport + 2); 383 - spin_unlock(&io_lock); 384 - if ((stat_reg & 0x10) == 0) { 287 + stat_reg = inb_p(pcwd_private.io_addr + 2); 288 + spin_unlock(&pcwd_private.io_lock); 289 + if ((stat_reg & WD_WDIS) == 0) { 385 290 printk(KERN_INFO PFX "Could not stop watchdog\n"); 386 291 return -EIO; 387 292 } ··· 392 297 static int pcwd_keepalive(void) 393 298 { 394 299 /* user land ping */ 395 - next_heartbeat = jiffies + (heartbeat * HZ); 300 + pcwd_private.next_heartbeat = jiffies + (heartbeat * HZ); 396 301 return 0; 397 302 } 398 303 ··· 410 315 int card_status; 411 316 412 317 *status=0; 413 - spin_lock(&io_lock); 414 - if (revision == PCWD_REVISION_A) 318 + spin_lock(&pcwd_private.io_lock); 319 + if (pcwd_private.revision == PCWD_REVISION_A) 415 320 /* Rev A cards return status information from 416 321 * the base register, which is used for the 417 322 * temperature in other cards. */ 418 - card_status = inb(current_readport); 323 + card_status = inb(pcwd_private.io_addr); 419 324 else { 420 325 /* Rev C cards return card status in the base 421 326 * address + 1 register. And use different bits 422 327 * to indicate a card initiated reset, and an 423 328 * over-temperature condition. And the reboot 424 329 * status can be reset. */ 425 - card_status = inb(current_readport + 1); 330 + card_status = inb(pcwd_private.io_addr + 1); 426 331 } 427 - spin_unlock(&io_lock); 332 + spin_unlock(&pcwd_private.io_lock); 428 333 429 - if (revision == PCWD_REVISION_A) { 334 + if (pcwd_private.revision == PCWD_REVISION_A) { 430 335 if (card_status & WD_WDRST) 431 336 *status |= WDIOF_CARDRESET; 432 337 ··· 455 360 456 361 static int pcwd_clear_status(void) 457 362 { 458 - if (revision == PCWD_REVISION_C) { 459 - spin_lock(&io_lock); 460 - outb_p(0x00, current_readport + 1); /* clear reset status */ 461 - spin_unlock(&io_lock); 363 + if (pcwd_private.revision == PCWD_REVISION_C) { 364 + spin_lock(&pcwd_private.io_lock); 365 + outb_p(0x00, pcwd_private.io_addr + 1); /* clear reset status */ 366 + spin_unlock(&pcwd_private.io_lock); 462 367 } 463 368 return 0; 464 369 } ··· 466 371 static int pcwd_get_temperature(int *temperature) 467 372 { 468 373 /* check that port 0 gives temperature info and no command results */ 469 - if (command_mode) 374 + if (pcwd_private.command_mode) 470 375 return -1; 471 376 472 377 *temperature = 0; 473 - if (!supports_temp) 378 + if (!pcwd_private.supports_temp) 474 379 return -ENODEV; 475 380 476 381 /* 477 382 * Convert celsius to fahrenheit, since this was 478 383 * the decided 'standard' for this return value. 479 384 */ 480 - spin_lock(&io_lock); 481 - *temperature = ((inb(current_readport)) * 9 / 5) + 32; 482 - spin_unlock(&io_lock); 385 + spin_lock(&pcwd_private.io_lock); 386 + *temperature = ((inb(pcwd_private.io_addr)) * 9 / 5) + 32; 387 + spin_unlock(&pcwd_private.io_lock); 483 388 484 389 return 0; 485 390 } ··· 520 425 return put_user(status, argp); 521 426 522 427 case WDIOC_GETBOOTSTATUS: 523 - return put_user(initial_status, argp); 428 + return put_user(pcwd_private.boot_status, argp); 524 429 525 430 case WDIOC_GETTEMP: 526 431 if (pcwd_get_temperature(&temperature)) ··· 529 434 return put_user(temperature, argp); 530 435 531 436 case WDIOC_SETOPTIONS: 532 - if (revision == PCWD_REVISION_C) 437 + if (pcwd_private.revision == PCWD_REVISION_C) 533 438 { 534 439 if(copy_from_user(&rv, argp, sizeof(int))) 535 440 return -EFAULT; ··· 645 550 646 551 static int pcwd_temp_open(struct inode *inode, struct file *file) 647 552 { 648 - if (!supports_temp) 553 + if (!pcwd_private.supports_temp) 649 554 return -ENODEV; 650 555 651 556 return nonseekable_open(inode, file); ··· 711 616 * Init & exit routines 712 617 */ 713 618 714 - static inline void get_support(void) 715 - { 716 - if (inb(current_readport) != 0xF0) 717 - supports_temp = 1; 718 - } 719 - 720 619 static inline int get_revision(void) 721 620 { 722 621 int r = PCWD_REVISION_C; 723 622 724 - spin_lock(&io_lock); 623 + spin_lock(&pcwd_private.io_lock); 725 624 /* REV A cards use only 2 io ports; test 726 625 * presumes a floating bus reads as 0xff. */ 727 - if ((inb(current_readport + 2) == 0xFF) || 728 - (inb(current_readport + 3) == 0xFF)) 626 + if ((inb(pcwd_private.io_addr + 2) == 0xFF) || 627 + (inb(pcwd_private.io_addr + 3) == 0xFF)) 729 628 r=PCWD_REVISION_A; 730 - spin_unlock(&io_lock); 629 + spin_unlock(&pcwd_private.io_lock); 731 630 732 631 return r; 733 - } 734 - 735 - static inline char *get_firmware(void) 736 - { 737 - int one, ten, hund, minor; 738 - char *ret; 739 - 740 - ret = kmalloc(6, GFP_KERNEL); 741 - if(ret == NULL) 742 - return NULL; 743 - 744 - if (set_command_mode()) { 745 - one = send_isa_command(CMD_ISA_VERSION_INTEGER); 746 - ten = send_isa_command(CMD_ISA_VERSION_TENTH); 747 - hund = send_isa_command(CMD_ISA_VERSION_HUNDRETH); 748 - minor = send_isa_command(CMD_ISA_VERSION_MINOR); 749 - sprintf(ret, "%c.%c%c%c", one, ten, hund, minor); 750 - } 751 - else 752 - sprintf(ret, "ERROR"); 753 - 754 - unset_command_mode(); 755 - return(ret); 756 - } 757 - 758 - static inline int get_option_switches(void) 759 - { 760 - int rv=0; 761 - 762 - if (set_command_mode()) { 763 - /* Get switch settings */ 764 - rv = send_isa_command(CMD_ISA_SWITCH_SETTINGS); 765 - } 766 - 767 - unset_command_mode(); 768 - return(rv); 769 632 } 770 633 771 634 static int __devinit pcwatchdog_init(int base_addr) 772 635 { 773 636 int ret; 774 - char *firmware; 775 - int option_switches; 776 637 777 638 cards_found++; 778 639 if (cards_found == 1) ··· 743 692 printk(KERN_ERR PFX "No I/O-Address for card detected\n"); 744 693 return -ENODEV; 745 694 } 746 - current_readport = base_addr; 695 + pcwd_private.io_addr = base_addr; 747 696 748 697 /* Check card's revision */ 749 - revision = get_revision(); 698 + pcwd_private.revision = get_revision(); 750 699 751 - if (!request_region(current_readport, (revision == PCWD_REVISION_A) ? 2 : 4, "PCWD")) { 700 + if (!request_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4, "PCWD")) { 752 701 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", 753 - current_readport); 754 - current_readport = 0x0000; 702 + pcwd_private.io_addr); 703 + pcwd_private.io_addr = 0x0000; 755 704 return -EIO; 756 705 } 757 706 758 707 /* Initial variables */ 759 - supports_temp = 0; 708 + pcwd_private.supports_temp = 0; 760 709 temp_panic = 0; 761 - initial_status = 0x0000; 710 + pcwd_private.boot_status = 0x0000; 762 711 763 712 /* get the boot_status */ 764 - pcwd_get_status(&initial_status); 713 + pcwd_get_status(&pcwd_private.boot_status); 765 714 766 715 /* clear the "card caused reboot" flag */ 767 716 pcwd_clear_status(); 768 717 769 - init_timer(&timer); 770 - timer.function = pcwd_timer_ping; 771 - timer.data = 0; 718 + init_timer(&pcwd_private.timer); 719 + pcwd_private.timer.function = pcwd_timer_ping; 720 + pcwd_private.timer.data = 0; 772 721 773 722 /* Disable the board */ 774 723 pcwd_stop(); 775 724 776 725 /* Check whether or not the card supports the temperature device */ 777 - get_support(); 726 + pcwd_check_temperature_support(); 778 727 779 - /* Get some extra info from the hardware (in command/debug/diag mode) */ 780 - if (revision == PCWD_REVISION_A) 781 - printk(KERN_INFO PFX "ISA-PC Watchdog (REV.A) detected at port 0x%04x\n", current_readport); 782 - else if (revision == PCWD_REVISION_C) { 783 - firmware = get_firmware(); 784 - printk(KERN_INFO PFX "ISA-PC Watchdog (REV.C) detected at port 0x%04x (Firmware version: %s)\n", 785 - current_readport, firmware); 786 - kfree(firmware); 787 - option_switches = get_option_switches(); 788 - printk(KERN_INFO PFX "Option switches (0x%02x): Temperature Reset Enable=%s, Power On Delay=%s\n", 789 - option_switches, 790 - ((option_switches & 0x10) ? "ON" : "OFF"), 791 - ((option_switches & 0x08) ? "ON" : "OFF")); 792 - 793 - /* Reprogram internal heartbeat to 2 seconds */ 794 - if (set_command_mode()) { 795 - send_isa_command(CMD_ISA_DELAY_TIME_2SECS); 796 - unset_command_mode(); 797 - } 798 - } else { 799 - /* Should NEVER happen, unless get_revision() fails. */ 800 - printk(KERN_INFO PFX "Unable to get revision\n"); 801 - release_region(current_readport, (revision == PCWD_REVISION_A) ? 2 : 4); 802 - current_readport = 0x0000; 803 - return -1; 804 - } 805 - 806 - if (supports_temp) 807 - printk(KERN_INFO PFX "Temperature Option Detected\n"); 808 - 809 - if (initial_status & WDIOF_CARDRESET) 810 - printk(KERN_INFO PFX "Previous reboot was caused by the card\n"); 811 - 812 - if (initial_status & WDIOF_OVERHEAT) { 813 - printk(KERN_EMERG PFX "Card senses a CPU Overheat. Panicking!\n"); 814 - printk(KERN_EMERG PFX "CPU Overheat\n"); 815 - } 816 - 817 - if (initial_status == 0) 818 - printk(KERN_INFO PFX "No previous trip detected - Cold boot or reset\n"); 728 + /* Show info about the card itself */ 729 + pcwd_show_card_info(); 819 730 820 731 /* Check that the heartbeat value is within it's range ; if not reset to the default */ 821 - if (pcwd_set_heartbeat(heartbeat)) { 822 - pcwd_set_heartbeat(WATCHDOG_HEARTBEAT); 823 - printk(KERN_INFO PFX "heartbeat value must be 2<=heartbeat<=7200, using %d\n", 824 - WATCHDOG_HEARTBEAT); 732 + if (pcwd_set_heartbeat(heartbeat)) { 733 + pcwd_set_heartbeat(WATCHDOG_HEARTBEAT); 734 + printk(KERN_INFO PFX "heartbeat value must be 2<=heartbeat<=7200, using %d\n", 735 + WATCHDOG_HEARTBEAT); 825 736 } 826 737 827 738 ret = register_reboot_notifier(&pcwd_notifier); 828 739 if (ret) { 829 740 printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 830 741 ret); 831 - release_region(current_readport, (revision == PCWD_REVISION_A) ? 2 : 4); 832 - current_readport = 0x0000; 742 + release_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4); 743 + pcwd_private.io_addr = 0x0000; 833 744 return ret; 834 745 } 835 746 836 - if (supports_temp) { 747 + if (pcwd_private.supports_temp) { 837 748 ret = misc_register(&temp_miscdev); 838 749 if (ret) { 839 750 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 840 751 TEMP_MINOR, ret); 841 752 unregister_reboot_notifier(&pcwd_notifier); 842 - release_region(current_readport, (revision == PCWD_REVISION_A) ? 2 : 4); 843 - current_readport = 0x0000; 753 + release_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4); 754 + pcwd_private.io_addr = 0x0000; 844 755 return ret; 845 756 } 846 757 } ··· 811 798 if (ret) { 812 799 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 813 800 WATCHDOG_MINOR, ret); 814 - if (supports_temp) 801 + if (pcwd_private.supports_temp) 815 802 misc_deregister(&temp_miscdev); 816 803 unregister_reboot_notifier(&pcwd_notifier); 817 - release_region(current_readport, (revision == PCWD_REVISION_A) ? 2 : 4); 818 - current_readport = 0x0000; 804 + release_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4); 805 + pcwd_private.io_addr = 0x0000; 819 806 return ret; 820 807 } 821 808 ··· 833 820 834 821 /* Deregister */ 835 822 misc_deregister(&pcwd_miscdev); 836 - if (supports_temp) 823 + if (pcwd_private.supports_temp) 837 824 misc_deregister(&temp_miscdev); 838 825 unregister_reboot_notifier(&pcwd_notifier); 839 - release_region(current_readport, (revision == PCWD_REVISION_A) ? 2 : 4); 840 - current_readport = 0x0000; 826 + release_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4); 827 + pcwd_private.io_addr = 0x0000; 828 + cards_found--; 841 829 } 842 830 843 831 /* ··· 901 887 { 902 888 int i, found = 0; 903 889 904 - spin_lock_init(&io_lock); 890 + spin_lock_init(&pcwd_private.io_lock); 905 891 906 892 for (i = 0; pcwd_ioports[i] != 0; i++) { 907 893 if (pcwd_checkcard(pcwd_ioports[i])) { ··· 920 906 921 907 static void __exit pcwd_cleanup_module(void) 922 908 { 923 - if (current_readport) 909 + if (pcwd_private.io_addr) 924 910 pcwatchdog_exit(); 925 911 return; 926 912 }
+7 -5
drivers/char/watchdog/sa1100_wdt.c
··· 93 93 { 94 94 int ret = -ENOIOCTLCMD; 95 95 int time; 96 + void __user *argp = (void __user *)arg; 97 + int __user *p = argp; 96 98 97 99 switch (cmd) { 98 100 case WDIOC_GETSUPPORT: 99 - ret = copy_to_user((struct watchdog_info __user *)arg, &ident, 101 + ret = copy_to_user(argp, &ident, 100 102 sizeof(ident)) ? -EFAULT : 0; 101 103 break; 102 104 103 105 case WDIOC_GETSTATUS: 104 - ret = put_user(0, (int __user *)arg); 106 + ret = put_user(0, p); 105 107 break; 106 108 107 109 case WDIOC_GETBOOTSTATUS: 108 - ret = put_user(boot_status, (int __user *)arg); 110 + ret = put_user(boot_status, p); 109 111 break; 110 112 111 113 case WDIOC_SETTIMEOUT: 112 - ret = get_user(time, (int __user *)arg); 114 + ret = get_user(time, p); 113 115 if (ret) 114 116 break; 115 117 ··· 125 123 /*fall through*/ 126 124 127 125 case WDIOC_GETTIMEOUT: 128 - ret = put_user(pre_margin / OSCR_FREQ, (int __user *)arg); 126 + ret = put_user(pre_margin / OSCR_FREQ, p); 129 127 break; 130 128 131 129 case WDIOC_KEEPALIVE: