diff options
| -rw-r--r-- | drivers/char/watchdog/pcwd_pci.c | 239 |
1 files changed, 172 insertions, 67 deletions
diff --git a/drivers/char/watchdog/pcwd_pci.c b/drivers/char/watchdog/pcwd_pci.c index 5a80adbf8032..0b8e493be045 100644 --- a/drivers/char/watchdog/pcwd_pci.c +++ b/drivers/char/watchdog/pcwd_pci.c | |||
| @@ -50,8 +50,8 @@ | |||
| 50 | #include <asm/io.h> /* For inb/outb/... */ | 50 | #include <asm/io.h> /* For inb/outb/... */ |
| 51 | 51 | ||
| 52 | /* Module and version information */ | 52 | /* Module and version information */ |
| 53 | #define WATCHDOG_VERSION "1.01" | 53 | #define WATCHDOG_VERSION "1.02" |
| 54 | #define WATCHDOG_DATE "02 Sep 2005" | 54 | #define WATCHDOG_DATE "03 Sep 2005" |
| 55 | #define WATCHDOG_DRIVER_NAME "PCI-PC Watchdog" | 55 | #define WATCHDOG_DRIVER_NAME "PCI-PC Watchdog" |
| 56 | #define WATCHDOG_NAME "pcwd_pci" | 56 | #define WATCHDOG_NAME "pcwd_pci" |
| 57 | #define PFX WATCHDOG_NAME ": " | 57 | #define PFX WATCHDOG_NAME ": " |
| @@ -70,19 +70,30 @@ | |||
| 70 | * These are the defines that describe the control status bits for the | 70 | * These are the defines that describe the control status bits for the |
| 71 | * PCI-PC Watchdog card. | 71 | * PCI-PC Watchdog card. |
| 72 | */ | 72 | */ |
| 73 | #define WD_PCI_WTRP 0x01 /* Watchdog Trip status */ | 73 | /* Port 1 : Control Status #1 */ |
| 74 | #define WD_PCI_HRBT 0x02 /* Watchdog Heartbeat */ | 74 | #define WD_PCI_WTRP 0x01 /* Watchdog Trip status */ |
| 75 | #define WD_PCI_TTRP 0x04 /* Temperature Trip status */ | 75 | #define WD_PCI_HRBT 0x02 /* Watchdog Heartbeat */ |
| 76 | #define WD_PCI_TTRP 0x04 /* Temperature Trip status */ | ||
| 77 | #define WD_PCI_RL2A 0x08 /* Relay 2 Active */ | ||
| 78 | #define WD_PCI_RL1A 0x10 /* Relay 1 Active */ | ||
| 79 | #define WD_PCI_R2DS 0x40 /* Relay 2 Disable Temperature-trip/reset */ | ||
| 80 | #define WD_PCI_RLY2 0x80 /* Activate Relay 2 on the board */ | ||
| 81 | /* Port 2 : Control Status #2 */ | ||
| 82 | #define WD_PCI_WDIS 0x10 /* Watchdog Disable */ | ||
| 83 | #define WD_PCI_ENTP 0x20 /* Enable Temperature Trip Reset */ | ||
| 84 | #define WD_PCI_WRSP 0x40 /* Watchdog wrote response */ | ||
| 85 | #define WD_PCI_PCMD 0x80 /* PC has sent command */ | ||
| 76 | 86 | ||
| 77 | /* according to documentation max. time to process a command for the pci | 87 | /* according to documentation max. time to process a command for the pci |
| 78 | * watchdog card is 100 ms, so we give it 150 ms to do it's job */ | 88 | * watchdog card is 100 ms, so we give it 150 ms to do it's job */ |
| 79 | #define PCI_COMMAND_TIMEOUT 150 | 89 | #define PCI_COMMAND_TIMEOUT 150 |
| 80 | 90 | ||
| 81 | /* Watchdog's internal commands */ | 91 | /* Watchdog's internal commands */ |
| 82 | #define CMD_GET_STATUS 0x04 | 92 | #define CMD_GET_STATUS 0x04 |
| 83 | #define CMD_GET_FIRMWARE_VERSION 0x08 | 93 | #define CMD_GET_FIRMWARE_VERSION 0x08 |
| 84 | #define CMD_READ_WATCHDOG_TIMEOUT 0x18 | 94 | #define CMD_READ_WATCHDOG_TIMEOUT 0x18 |
| 85 | #define CMD_WRITE_WATCHDOG_TIMEOUT 0x19 | 95 | #define CMD_WRITE_WATCHDOG_TIMEOUT 0x19 |
| 96 | #define CMD_GET_CLEAR_RESET_COUNT 0x84 | ||
| 86 | 97 | ||
| 87 | /* We can only use 1 card due to the /dev/watchdog restriction */ | 98 | /* We can only use 1 card due to the /dev/watchdog restriction */ |
| 88 | static int cards_found; | 99 | static int cards_found; |
| @@ -91,15 +102,22 @@ static int cards_found; | |||
| 91 | static int temp_panic; | 102 | static int temp_panic; |
| 92 | static unsigned long is_active; | 103 | static unsigned long is_active; |
| 93 | static char expect_release; | 104 | static char expect_release; |
| 94 | static struct { | 105 | static struct { /* this is private data for each PCI-PC watchdog card */ |
| 95 | int supports_temp; /* Wether or not the card has a temperature device */ | 106 | int supports_temp; /* Wether or not the card has a temperature device */ |
| 96 | int boot_status; /* The card's boot status */ | 107 | int boot_status; /* The card's boot status */ |
| 97 | unsigned long io_addr; /* The cards I/O address */ | 108 | unsigned long io_addr; /* The cards I/O address */ |
| 98 | spinlock_t io_lock; | 109 | spinlock_t io_lock; /* the lock for io operations */ |
| 99 | struct pci_dev *pdev; | 110 | struct pci_dev *pdev; /* the PCI-device */ |
| 100 | } pcipcwd_private; | 111 | } pcipcwd_private; |
| 101 | 112 | ||
| 102 | /* module parameters */ | 113 | /* module parameters */ |
| 114 | #define QUIET 0 /* Default */ | ||
| 115 | #define VERBOSE 1 /* Verbose */ | ||
| 116 | #define DEBUG 2 /* print fancy stuff too */ | ||
| 117 | static int debug = QUIET; | ||
| 118 | module_param(debug, int, 0); | ||
| 119 | MODULE_PARM_DESC(debug, "Debug level: 0=Quiet, 1=Verbose, 2=Debug (default=0)"); | ||
| 120 | |||
| 103 | #define WATCHDOG_HEARTBEAT 2 /* 2 sec default heartbeat */ | 121 | #define WATCHDOG_HEARTBEAT 2 /* 2 sec default heartbeat */ |
| 104 | static int heartbeat = WATCHDOG_HEARTBEAT; | 122 | static int heartbeat = WATCHDOG_HEARTBEAT; |
| 105 | module_param(heartbeat, int, 0); | 123 | module_param(heartbeat, int, 0); |
| @@ -117,6 +135,10 @@ static int send_command(int cmd, int *msb, int *lsb) | |||
| 117 | { | 135 | { |
| 118 | int got_response, count; | 136 | int got_response, count; |
| 119 | 137 | ||
| 138 | if (debug >= DEBUG) | ||
| 139 | printk(KERN_DEBUG PFX "sending following data cmd=0x%02x msb=0x%02x lsb=0x%02x\n", | ||
| 140 | cmd, *msb, *lsb); | ||
| 141 | |||
| 120 | spin_lock(&pcipcwd_private.io_lock); | 142 | spin_lock(&pcipcwd_private.io_lock); |
| 121 | /* If a command requires data it should be written first. | 143 | /* If a command requires data it should be written first. |
| 122 | * Data for commands with 8 bits of data should be written to port 4. | 144 | * Data for commands with 8 bits of data should be written to port 4. |
| @@ -131,10 +153,19 @@ static int send_command(int cmd, int *msb, int *lsb) | |||
| 131 | /* wait till the pci card processed the command, signaled by | 153 | /* wait till the pci card processed the command, signaled by |
| 132 | * the WRSP bit in port 2 and give it a max. timeout of | 154 | * the WRSP bit in port 2 and give it a max. timeout of |
| 133 | * PCI_COMMAND_TIMEOUT to process */ | 155 | * PCI_COMMAND_TIMEOUT to process */ |
| 134 | got_response = inb_p(pcipcwd_private.io_addr + 2) & 0x40; | 156 | got_response = inb_p(pcipcwd_private.io_addr + 2) & WD_PCI_WRSP; |
| 135 | for (count = 0; (count < PCI_COMMAND_TIMEOUT) && (!got_response); count++) { | 157 | for (count = 0; (count < PCI_COMMAND_TIMEOUT) && (!got_response); count++) { |
| 136 | mdelay(1); | 158 | mdelay(1); |
| 137 | got_response = inb_p(pcipcwd_private.io_addr + 2) & 0x40; | 159 | got_response = inb_p(pcipcwd_private.io_addr + 2) & WD_PCI_WRSP; |
| 160 | } | ||
| 161 | |||
| 162 | if (debug >= DEBUG) { | ||
| 163 | if (got_response) { | ||
| 164 | printk(KERN_DEBUG PFX "time to process command was: %d ms\n", | ||
| 165 | count); | ||
| 166 | } else { | ||
| 167 | printk(KERN_DEBUG PFX "card did not respond on command!\n"); | ||
| 168 | } | ||
| 138 | } | 169 | } |
| 139 | 170 | ||
| 140 | if (got_response) { | 171 | if (got_response) { |
| @@ -144,12 +175,66 @@ static int send_command(int cmd, int *msb, int *lsb) | |||
| 144 | 175 | ||
| 145 | /* clear WRSP bit */ | 176 | /* clear WRSP bit */ |
| 146 | inb_p(pcipcwd_private.io_addr + 6); | 177 | inb_p(pcipcwd_private.io_addr + 6); |
| 178 | |||
| 179 | if (debug >= DEBUG) | ||
| 180 | printk(KERN_DEBUG PFX "received following data for cmd=0x%02x: msb=0x%02x lsb=0x%02x\n", | ||
| 181 | cmd, *msb, *lsb); | ||
| 147 | } | 182 | } |
| 183 | |||
| 148 | spin_unlock(&pcipcwd_private.io_lock); | 184 | spin_unlock(&pcipcwd_private.io_lock); |
| 149 | 185 | ||
| 150 | return got_response; | 186 | return got_response; |
| 151 | } | 187 | } |
| 152 | 188 | ||
| 189 | static inline void pcipcwd_check_temperature_support(void) | ||
| 190 | { | ||
| 191 | if (inb_p(pcipcwd_private.io_addr) != 0xF0) | ||
| 192 | pcipcwd_private.supports_temp = 1; | ||
| 193 | } | ||
| 194 | |||
| 195 | static int pcipcwd_get_option_switches(void) | ||
| 196 | { | ||
| 197 | int option_switches; | ||
| 198 | |||
| 199 | option_switches = inb_p(pcipcwd_private.io_addr + 3); | ||
| 200 | return option_switches; | ||
| 201 | } | ||
| 202 | |||
| 203 | static void pcipcwd_show_card_info(void) | ||
| 204 | { | ||
| 205 | int got_fw_rev, fw_rev_major, fw_rev_minor; | ||
| 206 | char fw_ver_str[20]; /* The cards firmware version */ | ||
| 207 | int option_switches; | ||
| 208 | |||
| 209 | got_fw_rev = send_command(CMD_GET_FIRMWARE_VERSION, &fw_rev_major, &fw_rev_minor); | ||
| 210 | if (got_fw_rev) { | ||
| 211 | sprintf(fw_ver_str, "%u.%02u", fw_rev_major, fw_rev_minor); | ||
| 212 | } else { | ||
| 213 | sprintf(fw_ver_str, "<card no answer>"); | ||
| 214 | } | ||
| 215 | |||
| 216 | /* Get switch settings */ | ||
| 217 | option_switches = pcipcwd_get_option_switches(); | ||
| 218 | |||
| 219 | printk(KERN_INFO PFX "Found card at port 0x%04x (Firmware: %s) %s temp option\n", | ||
| 220 | (int) pcipcwd_private.io_addr, fw_ver_str, | ||
| 221 | (pcipcwd_private.supports_temp ? "with" : "without")); | ||
| 222 | |||
| 223 | printk(KERN_INFO PFX "Option switches (0x%02x): Temperature Reset Enable=%s, Power On Delay=%s\n", | ||
| 224 | option_switches, | ||
| 225 | ((option_switches & 0x10) ? "ON" : "OFF"), | ||
| 226 | ((option_switches & 0x08) ? "ON" : "OFF")); | ||
| 227 | |||
| 228 | if (pcipcwd_private.boot_status & WDIOF_CARDRESET) | ||
| 229 | printk(KERN_INFO PFX "Previous reset was caused by the Watchdog card\n"); | ||
| 230 | |||
| 231 | if (pcipcwd_private.boot_status & WDIOF_OVERHEAT) | ||
| 232 | printk(KERN_INFO PFX "Card sensed a CPU Overheat\n"); | ||
| 233 | |||
| 234 | if (pcipcwd_private.boot_status == 0) | ||
| 235 | printk(KERN_INFO PFX "No previous trip detected - Cold boot or reset\n"); | ||
| 236 | } | ||
| 237 | |||
| 153 | static int pcipcwd_start(void) | 238 | static int pcipcwd_start(void) |
| 154 | { | 239 | { |
| 155 | int stat_reg; | 240 | int stat_reg; |
| @@ -161,11 +246,14 @@ static int pcipcwd_start(void) | |||
| 161 | stat_reg = inb_p(pcipcwd_private.io_addr + 2); | 246 | stat_reg = inb_p(pcipcwd_private.io_addr + 2); |
| 162 | spin_unlock(&pcipcwd_private.io_lock); | 247 | spin_unlock(&pcipcwd_private.io_lock); |
| 163 | 248 | ||
| 164 | if (stat_reg & 0x10) { | 249 | if (stat_reg & WD_PCI_WDIS) { |
| 165 | printk(KERN_ERR PFX "Card timer not enabled\n"); | 250 | printk(KERN_ERR PFX "Card timer not enabled\n"); |
| 166 | return -1; | 251 | return -1; |
| 167 | } | 252 | } |
| 168 | 253 | ||
| 254 | if (debug >= VERBOSE) | ||
| 255 | printk(KERN_DEBUG PFX "Watchdog started\n"); | ||
| 256 | |||
| 169 | return 0; | 257 | return 0; |
| 170 | } | 258 | } |
| 171 | 259 | ||
| @@ -183,18 +271,25 @@ static int pcipcwd_stop(void) | |||
| 183 | stat_reg = inb_p(pcipcwd_private.io_addr + 2); | 271 | stat_reg = inb_p(pcipcwd_private.io_addr + 2); |
| 184 | spin_unlock(&pcipcwd_private.io_lock); | 272 | spin_unlock(&pcipcwd_private.io_lock); |
| 185 | 273 | ||
| 186 | if (!(stat_reg & 0x10)) { | 274 | if (!(stat_reg & WD_PCI_WDIS)) { |
| 187 | printk(KERN_ERR PFX "Card did not acknowledge disable attempt\n"); | 275 | printk(KERN_ERR PFX "Card did not acknowledge disable attempt\n"); |
| 188 | return -1; | 276 | return -1; |
| 189 | } | 277 | } |
| 190 | 278 | ||
| 279 | if (debug >= VERBOSE) | ||
| 280 | printk(KERN_DEBUG PFX "Watchdog stopped\n"); | ||
| 281 | |||
| 191 | return 0; | 282 | return 0; |
| 192 | } | 283 | } |
| 193 | 284 | ||
| 194 | static int pcipcwd_keepalive(void) | 285 | static int pcipcwd_keepalive(void) |
| 195 | { | 286 | { |
| 196 | /* Re-trigger watchdog by writing to port 0 */ | 287 | /* Re-trigger watchdog by writing to port 0 */ |
| 197 | outb_p(0x42, pcipcwd_private.io_addr); | 288 | outb_p(0x42, pcipcwd_private.io_addr); /* send out any data */ |
| 289 | |||
| 290 | if (debug >= DEBUG) | ||
| 291 | printk(KERN_DEBUG PFX "Watchdog keepalive signal send\n"); | ||
| 292 | |||
| 198 | return 0; | 293 | return 0; |
| 199 | } | 294 | } |
| 200 | 295 | ||
| @@ -210,29 +305,64 @@ static int pcipcwd_set_heartbeat(int t) | |||
| 210 | send_command(CMD_WRITE_WATCHDOG_TIMEOUT, &t_msb, &t_lsb); | 305 | send_command(CMD_WRITE_WATCHDOG_TIMEOUT, &t_msb, &t_lsb); |
| 211 | 306 | ||
| 212 | heartbeat = t; | 307 | heartbeat = t; |
| 308 | if (debug >= VERBOSE) | ||
| 309 | printk(KERN_DEBUG PFX "New heartbeat: %d\n", | ||
| 310 | heartbeat); | ||
| 311 | |||
| 213 | return 0; | 312 | return 0; |
| 214 | } | 313 | } |
| 215 | 314 | ||
| 216 | static int pcipcwd_get_status(int *status) | 315 | static int pcipcwd_get_status(int *status) |
| 217 | { | 316 | { |
| 218 | int new_status; | 317 | int control_status; |
| 219 | 318 | ||
| 220 | *status=0; | 319 | *status=0; |
| 221 | new_status = inb_p(pcipcwd_private.io_addr + 1); | 320 | control_status = inb_p(pcipcwd_private.io_addr + 1); |
| 222 | if (new_status & WD_PCI_WTRP) | 321 | if (control_status & WD_PCI_WTRP) |
| 223 | *status |= WDIOF_CARDRESET; | 322 | *status |= WDIOF_CARDRESET; |
| 224 | if (new_status & WD_PCI_TTRP) { | 323 | if (control_status & WD_PCI_TTRP) { |
| 225 | *status |= WDIOF_OVERHEAT; | 324 | *status |= WDIOF_OVERHEAT; |
| 226 | if (temp_panic) | 325 | if (temp_panic) |
| 227 | panic(PFX "Temperature overheat trip!\n"); | 326 | panic(PFX "Temperature overheat trip!\n"); |
| 228 | } | 327 | } |
| 229 | 328 | ||
| 329 | if (debug >= DEBUG) | ||
| 330 | printk(KERN_DEBUG PFX "Control Status #1: 0x%02x\n", | ||
| 331 | control_status); | ||
| 332 | |||
| 230 | return 0; | 333 | return 0; |
| 231 | } | 334 | } |
| 232 | 335 | ||
| 233 | static int pcipcwd_clear_status(void) | 336 | static int pcipcwd_clear_status(void) |
| 234 | { | 337 | { |
| 235 | outb_p(0x01, pcipcwd_private.io_addr + 1); | 338 | int control_status; |
| 339 | int msb; | ||
| 340 | int reset_counter; | ||
| 341 | |||
| 342 | if (debug >= VERBOSE) | ||
| 343 | printk(KERN_INFO PFX "clearing watchdog trip status & LED\n"); | ||
| 344 | |||
| 345 | control_status = inb_p(pcipcwd_private.io_addr + 1); | ||
| 346 | |||
| 347 | if (debug >= DEBUG) { | ||
| 348 | printk(KERN_DEBUG PFX "status was: 0x%02x\n", control_status); | ||
| 349 | printk(KERN_DEBUG PFX "sending: 0x%02x\n", | ||
| 350 | (control_status & WD_PCI_R2DS) | WD_PCI_WTRP); | ||
| 351 | } | ||
| 352 | |||
| 353 | /* clear trip status & LED and keep mode of relay 2 */ | ||
| 354 | outb_p((control_status & WD_PCI_R2DS) | WD_PCI_WTRP, pcipcwd_private.io_addr + 1); | ||
| 355 | |||
| 356 | /* clear reset counter */ | ||
| 357 | msb=0; | ||
| 358 | reset_counter=0xff; | ||
| 359 | send_command(CMD_GET_CLEAR_RESET_COUNT, &msb, &reset_counter); | ||
| 360 | |||
| 361 | if (debug >= DEBUG) { | ||
| 362 | printk(KERN_DEBUG PFX "reset count was: 0x%02x\n", | ||
| 363 | reset_counter); | ||
| 364 | } | ||
| 365 | |||
| 236 | return 0; | 366 | return 0; |
| 237 | } | 367 | } |
| 238 | 368 | ||
| @@ -242,11 +372,18 @@ static int pcipcwd_get_temperature(int *temperature) | |||
| 242 | if (!pcipcwd_private.supports_temp) | 372 | if (!pcipcwd_private.supports_temp) |
| 243 | return -ENODEV; | 373 | return -ENODEV; |
| 244 | 374 | ||
| 375 | *temperature = inb_p(pcipcwd_private.io_addr); | ||
| 376 | |||
| 245 | /* | 377 | /* |
| 246 | * Convert celsius to fahrenheit, since this was | 378 | * Convert celsius to fahrenheit, since this was |
| 247 | * the decided 'standard' for this return value. | 379 | * the decided 'standard' for this return value. |
| 248 | */ | 380 | */ |
| 249 | *temperature = ((inb_p(pcipcwd_private.io_addr)) * 9 / 5) + 32; | 381 | *temperature = (*temperature * 9 / 5) + 32; |
| 382 | |||
| 383 | if (debug >= DEBUG) { | ||
| 384 | printk(KERN_DEBUG PFX "temperature is: %d F\n", | ||
| 385 | *temperature); | ||
| 386 | } | ||
| 250 | 387 | ||
| 251 | return 0; | 388 | return 0; |
| 252 | } | 389 | } |
| @@ -256,7 +393,7 @@ static int pcipcwd_get_temperature(int *temperature) | |||
| 256 | */ | 393 | */ |
| 257 | 394 | ||
| 258 | static ssize_t pcipcwd_write(struct file *file, const char __user *data, | 395 | static ssize_t pcipcwd_write(struct file *file, const char __user *data, |
| 259 | size_t len, loff_t *ppos) | 396 | size_t len, loff_t *ppos) |
| 260 | { | 397 | { |
| 261 | /* See if we got the magic character 'V' and reload the timer */ | 398 | /* See if we got the magic character 'V' and reload the timer */ |
| 262 | if (len) { | 399 | if (len) { |
| @@ -381,8 +518,11 @@ static int pcipcwd_ioctl(struct inode *inode, struct file *file, | |||
| 381 | static int pcipcwd_open(struct inode *inode, struct file *file) | 518 | static int pcipcwd_open(struct inode *inode, struct file *file) |
| 382 | { | 519 | { |
| 383 | /* /dev/watchdog can only be opened once */ | 520 | /* /dev/watchdog can only be opened once */ |
| 384 | if (test_and_set_bit(0, &is_active)) | 521 | if (test_and_set_bit(0, &is_active)) { |
| 522 | if (debug >= VERBOSE) | ||
| 523 | printk(KERN_ERR PFX "Attempt to open already opened device.\n"); | ||
| 385 | return -EBUSY; | 524 | return -EBUSY; |
| 525 | } | ||
| 386 | 526 | ||
| 387 | /* Activate */ | 527 | /* Activate */ |
| 388 | pcipcwd_start(); | 528 | pcipcwd_start(); |
| @@ -492,19 +632,10 @@ static struct notifier_block pcipcwd_notifier = { | |||
| 492 | * Init & exit routines | 632 | * Init & exit routines |
| 493 | */ | 633 | */ |
| 494 | 634 | ||
| 495 | static inline void check_temperature_support(void) | ||
| 496 | { | ||
| 497 | if (inb_p(pcipcwd_private.io_addr) != 0xF0) | ||
| 498 | pcipcwd_private.supports_temp = 1; | ||
| 499 | } | ||
| 500 | |||
| 501 | static int __devinit pcipcwd_card_init(struct pci_dev *pdev, | 635 | static int __devinit pcipcwd_card_init(struct pci_dev *pdev, |
| 502 | const struct pci_device_id *ent) | 636 | const struct pci_device_id *ent) |
| 503 | { | 637 | { |
| 504 | int ret = -EIO; | 638 | int ret = -EIO; |
| 505 | int got_fw_rev, fw_rev_major, fw_rev_minor; | ||
| 506 | char fw_ver_str[20]; | ||
| 507 | char option_switches; | ||
| 508 | 639 | ||
| 509 | cards_found++; | 640 | cards_found++; |
| 510 | if (cards_found == 1) | 641 | if (cards_found == 1) |
| @@ -546,36 +677,10 @@ static int __devinit pcipcwd_card_init(struct pci_dev *pdev, | |||
| 546 | pcipcwd_stop(); | 677 | pcipcwd_stop(); |
| 547 | 678 | ||
| 548 | /* Check whether or not the card supports the temperature device */ | 679 | /* Check whether or not the card supports the temperature device */ |
| 549 | check_temperature_support(); | 680 | pcipcwd_check_temperature_support(); |
| 550 | |||
| 551 | /* Get the Firmware Version */ | ||
| 552 | got_fw_rev = send_command(CMD_GET_FIRMWARE_VERSION, &fw_rev_major, &fw_rev_minor); | ||
| 553 | if (got_fw_rev) { | ||
| 554 | sprintf(fw_ver_str, "%u.%02u", fw_rev_major, fw_rev_minor); | ||
| 555 | } else { | ||
| 556 | sprintf(fw_ver_str, "<card no answer>"); | ||
| 557 | } | ||
| 558 | 681 | ||
| 559 | /* Get switch settings */ | 682 | /* Show info about the card itself */ |
| 560 | option_switches = inb_p(pcipcwd_private.io_addr + 3); | 683 | pcipcwd_show_card_info(); |
| 561 | |||
| 562 | printk(KERN_INFO PFX "Found card at port 0x%04x (Firmware: %s) %s temp option\n", | ||
| 563 | (int) pcipcwd_private.io_addr, fw_ver_str, | ||
| 564 | (pcipcwd_private.supports_temp ? "with" : "without")); | ||
| 565 | |||
| 566 | printk(KERN_INFO PFX "Option switches (0x%02x): Temperature Reset Enable=%s, Power On Delay=%s\n", | ||
| 567 | option_switches, | ||
| 568 | ((option_switches & 0x10) ? "ON" : "OFF"), | ||
| 569 | ((option_switches & 0x08) ? "ON" : "OFF")); | ||
| 570 | |||
| 571 | if (pcipcwd_private.boot_status & WDIOF_CARDRESET) | ||
| 572 | printk(KERN_INFO PFX "Previous reset was caused by the Watchdog card\n"); | ||
| 573 | |||
| 574 | if (pcipcwd_private.boot_status & WDIOF_OVERHEAT) | ||
| 575 | printk(KERN_INFO PFX "Card sensed a CPU Overheat\n"); | ||
| 576 | |||
| 577 | if (pcipcwd_private.boot_status == 0) | ||
| 578 | printk(KERN_INFO PFX "No previous trip detected - Cold boot or reset\n"); | ||
| 579 | 684 | ||
| 580 | /* Check that the heartbeat value is within it's range ; if not reset to the default */ | 685 | /* Check that the heartbeat value is within it's range ; if not reset to the default */ |
| 581 | if (pcipcwd_set_heartbeat(heartbeat)) { | 686 | if (pcipcwd_set_heartbeat(heartbeat)) { |
| @@ -656,7 +761,7 @@ static struct pci_driver pcipcwd_driver = { | |||
| 656 | 761 | ||
| 657 | static int __init pcipcwd_init_module(void) | 762 | static int __init pcipcwd_init_module(void) |
| 658 | { | 763 | { |
| 659 | spin_lock_init (&pcipcwd_private.io_lock); | 764 | spin_lock_init(&pcipcwd_private.io_lock); |
| 660 | 765 | ||
| 661 | return pci_register_driver(&pcipcwd_driver); | 766 | return pci_register_driver(&pcipcwd_driver); |
| 662 | } | 767 | } |
