Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]

Diff markup

Differences between /linux/drivers/watchdog/hpwdt.c (Version 2.6.31.13) and /linux/drivers/watchdog/hpwdt.c (Version 2.6.11.8)


  1 /*                                                  1 
  2  *      HP WatchDog Driver                        
  3  *      based on                                  
  4  *                                                
  5  *      SoftDog 0.05:   A Software Watchdog De    
  6  *                                                
  7  *      (c) Copyright 2007 Hewlett-Packard Dev    
  8  *      Thomas Mingarelli <thomas.mingarelli@h    
  9  *                                                
 10  *      This program is free software; you can    
 11  *      modify it under the terms of the GNU G    
 12  *      version 2 as published by the Free Sof    
 13  *                                                
 14  */                                               
 15                                                   
 16 #include <linux/device.h>                         
 17 #include <linux/fs.h>                             
 18 #include <linux/init.h>                           
 19 #include <linux/interrupt.h>                      
 20 #include <linux/io.h>                             
 21 #include <linux/irq.h>                            
 22 #include <linux/nmi.h>                            
 23 #include <linux/kernel.h>                         
 24 #include <linux/miscdevice.h>                     
 25 #include <linux/mm.h>                             
 26 #include <linux/module.h>                         
 27 #include <linux/kdebug.h>                         
 28 #include <linux/moduleparam.h>                    
 29 #include <linux/notifier.h>                       
 30 #include <linux/pci.h>                            
 31 #include <linux/pci_ids.h>                        
 32 #include <linux/reboot.h>                         
 33 #include <linux/sched.h>                          
 34 #include <linux/timer.h>                          
 35 #include <linux/types.h>                          
 36 #include <linux/uaccess.h>                        
 37 #include <linux/watchdog.h>                       
 38 #include <linux/dmi.h>                            
 39 #include <linux/efi.h>                            
 40 #include <linux/string.h>                         
 41 #include <linux/bootmem.h>                        
 42 #include <linux/slab.h>                           
 43 #include <asm/desc.h>                             
 44 #include <asm/cacheflush.h>                       
 45                                                   
 46 #define PCI_BIOS32_SD_VALUE             0x5F32    
 47 #define CRU_BIOS_SIGNATURE_VALUE        0x5552    
 48 #define PCI_BIOS32_PARAGRAPH_LEN        16        
 49 #define PCI_ROM_BASE1                   0x000F    
 50 #define ROM_SIZE                        0x1000    
 51 #define HPWDT_VERSION                   "1.1.1    
 52                                                   
 53 struct bios32_service_dir {                       
 54         u32 signature;                            
 55         u32 entry_point;                          
 56         u8 revision;                              
 57         u8 length;                                
 58         u8 checksum;                              
 59         u8 reserved[5];                           
 60 };                                                
 61                                                   
 62 /* type 212 */                                    
 63 struct smbios_cru64_info {                        
 64         u8 type;                                  
 65         u8 byte_length;                           
 66         u16 handle;                               
 67         u32 signature;                            
 68         u64 physical_address;                     
 69         u32 double_length;                        
 70         u32 double_offset;                        
 71 };                                                
 72 #define SMBIOS_CRU64_INFORMATION        212       
 73                                                   
 74 struct cmn_registers {                            
 75         union {                                   
 76                 struct {                          
 77                         u8 ral;                   
 78                         u8 rah;                   
 79                         u16 rea2;                 
 80                 };                                
 81                 u32 reax;                         
 82         } u1;                                     
 83         union {                                   
 84                 struct {                          
 85                         u8 rbl;                   
 86                         u8 rbh;                   
 87                         u8 reb2l;                 
 88                         u8 reb2h;                 
 89                 };                                
 90                 u32 rebx;                         
 91         } u2;                                     
 92         union {                                   
 93                 struct {                          
 94                         u8 rcl;                   
 95                         u8 rch;                   
 96                         u16 rec2;                 
 97                 };                                
 98                 u32 recx;                         
 99         } u3;                                     
100         union {                                   
101                 struct {                          
102                         u8 rdl;                   
103                         u8 rdh;                   
104                         u16 red2;                 
105                 };                                
106                 u32 redx;                         
107         } u4;                                     
108                                                   
109         u32 resi;                                 
110         u32 redi;                                 
111         u16 rds;                                  
112         u16 res;                                  
113         u32 reflags;                              
114 }  __attribute__((packed));                       
115                                                   
116 #define DEFAULT_MARGIN  30                        
117 static unsigned int soft_margin = DEFAULT_MARG    
118 static unsigned int reload;                       
119 static int nowayout = WATCHDOG_NOWAYOUT;          
120 static char expect_release;                       
121 static unsigned long hpwdt_is_open;               
122 static unsigned int allow_kdump;                  
123 static unsigned int hpwdt_nmi_sourcing;           
124 static unsigned int priority;           /* hpw    
125                                                   
126 static void __iomem *pci_mem_addr;                
127 static unsigned long __iomem *hpwdt_timer_reg;    
128 static unsigned long __iomem *hpwdt_timer_con;    
129                                                   
130 static DEFINE_SPINLOCK(rom_lock);                 
131                                                   
132 static void *cru_rom_addr;                        
133                                                   
134 static struct cmn_registers cmn_regs;             
135                                                   
136 static struct pci_device_id hpwdt_devices[] =     
137         { PCI_DEVICE(PCI_VENDOR_ID_COMPAQ, 0xB    
138         { PCI_DEVICE(PCI_VENDOR_ID_HP, 0x3306)    
139         {0},                    /* terminate l    
140 };                                                
141 MODULE_DEVICE_TABLE(pci, hpwdt_devices);          
142                                                   
143 extern asmlinkage void asminline_call(struct c    
144                                                   
145                                                   
146 #ifndef CONFIG_X86_64                             
147 /* --32 Bit Bios------------------------------    
148                                                   
149 #define HPWDT_ARCH      32                        
150                                                   
151 asm(".text                          \n\t"         
152     ".align 4                       \n"           
153     "asminline_call:                \n\t"         
154     "pushl       %ebp               \n\t"         
155     "movl        %esp, %ebp         \n\t"         
156     "pusha                          \n\t"         
157     "pushf                          \n\t"         
158     "push        %es                \n\t"         
159     "push        %ds                \n\t"         
160     "pop         %es                \n\t"         
161     "movl        8(%ebp),%eax       \n\t"         
162     "movl        4(%eax),%ebx       \n\t"         
163     "movl        8(%eax),%ecx       \n\t"         
164     "movl        12(%eax),%edx      \n\t"         
165     "movl        16(%eax),%esi      \n\t"         
166     "movl        20(%eax),%edi      \n\t"         
167     "movl        (%eax),%eax        \n\t"         
168     "push        %cs                \n\t"         
169     "call        *12(%ebp)          \n\t"         
170     "pushf                          \n\t"         
171     "pushl       %eax               \n\t"         
172     "movl        8(%ebp),%eax       \n\t"         
173     "movl        %ebx,4(%eax)       \n\t"         
174     "movl        %ecx,8(%eax)       \n\t"         
175     "movl        %edx,12(%eax)      \n\t"         
176     "movl        %esi,16(%eax)      \n\t"         
177     "movl        %edi,20(%eax)      \n\t"         
178     "movw        %ds,24(%eax)       \n\t"         
179     "movw        %es,26(%eax)       \n\t"         
180     "popl        %ebx               \n\t"         
181     "movl        %ebx,(%eax)        \n\t"         
182     "popl        %ebx               \n\t"         
183     "movl        %ebx,28(%eax)      \n\t"         
184     "pop         %es                \n\t"         
185     "popf                           \n\t"         
186     "popa                           \n\t"         
187     "leave                          \n\t"         
188     "ret                            \n\t"         
189     ".previous");                                 
190                                                   
191                                                   
192 /*                                                
193  *      cru_detect                                
194  *                                                
195  *      Routine Description:                      
196  *      This function uses the 32-bit BIOS Ser    
197  *      search for a $CRU record.                 
198  *                                                
199  *      Return Value:                             
200  *      0        :  SUCCESS                       
201  *      <0       :  FAILURE                       
202  */                                               
203 static int __devinit cru_detect(unsigned long     
204         unsigned long map_offset)                 
205 {                                                 
206         void *bios32_map;                         
207         unsigned long *bios32_entrypoint;         
208         unsigned long cru_physical_address;       
209         unsigned long cru_length;                 
210         unsigned long physical_bios_base = 0;     
211         unsigned long physical_bios_offset = 0    
212         int retval = -ENODEV;                     
213                                                   
214         bios32_map = ioremap(map_entry, (2 * P    
215                                                   
216         if (bios32_map == NULL)                   
217                 return -ENODEV;                   
218                                                   
219         bios32_entrypoint = bios32_map + map_o    
220                                                   
221         cmn_regs.u1.reax = CRU_BIOS_SIGNATURE_    
222                                                   
223         asminline_call(&cmn_regs, bios32_entry    
224                                                   
225         if (cmn_regs.u1.ral != 0) {               
226                 printk(KERN_WARNING               
227                         "hpwdt: Call succeeded    
228                         cmn_regs.u1.ral);         
229         } else {                                  
230                 physical_bios_base = cmn_regs.    
231                 physical_bios_offset = cmn_reg    
232                 cru_length = cmn_regs.u3.recx;    
233                 cru_physical_address =            
234                         physical_bios_base + p    
235                                                   
236                 /* If the values look OK, then    
237                 if ((physical_bios_base + phys    
238                         cru_rom_addr =            
239                                 ioremap(cru_ph    
240                         if (cru_rom_addr)         
241                                 retval = 0;       
242                 }                                 
243                                                   
244                 printk(KERN_DEBUG "hpwdt: CRU     
245                         physical_bios_base);      
246                 printk(KERN_DEBUG "hpwdt: CRU     
247                         physical_bios_offset);    
248                 printk(KERN_DEBUG "hpwdt: CRU     
249                         cru_length);              
250                 printk(KERN_DEBUG "hpwdt: CRU     
251                         (unsigned int)&cru_rom    
252         }                                         
253         iounmap(bios32_map);                      
254         return retval;                            
255 }                                                 
256                                                   
257 /*                                                
258  *      bios_checksum                             
259  */                                               
260 static int __devinit bios_checksum(const char     
261 {                                                 
262         char sum = 0;                             
263         int i;                                    
264                                                   
265         /*                                        
266          * calculate checksum of size bytes. T    
267          * to zero if we have a valid header.     
268          */                                       
269         for (i = 0; i < len; i++)                 
270                 sum += ptr[i];                    
271                                                   
272         return ((sum == 0) && (len > 0));         
273 }                                                 
274                                                   
275 /*                                                
276  *      bios32_present                            
277  *                                                
278  *      Routine Description:                      
279  *      This function finds the 32-bit BIOS Se    
280  *                                                
281  *      Return Value:                             
282  *      0        :  SUCCESS                       
283  *      <0       :  FAILURE                       
284  */                                               
285 static int __devinit bios32_present(const char    
286 {                                                 
287         struct bios32_service_dir *bios_32_ptr    
288         int length;                               
289         unsigned long map_entry, map_offset;      
290                                                   
291         bios_32_ptr = (struct bios32_service_d    
292                                                   
293         /*                                        
294          * Search for signature by checking eq    
295          * instead of calling another routine     
296          */                                       
297         if (bios_32_ptr->signature == PCI_BIOS    
298                 length = bios_32_ptr->length *    
299                 if (bios_checksum(p, length))     
300                         /*                        
301                          * According to the sp    
302                          * first 4KB-aligned a    
303                          * listed in the heade    
304                          * is guaranteed to oc    
305                          */                       
306                         map_entry = bios_32_pt    
307                         map_offset = bios_32_p    
308                                                   
309                         return cru_detect(map_    
310                 }                                 
311         }                                         
312         return -ENODEV;                           
313 }                                                 
314                                                   
315 static int __devinit detect_cru_service(void)     
316 {                                                 
317         char __iomem *p, *q;                      
318         int rc = -1;                              
319                                                   
320         /*                                        
321          * Search from 0x0f0000 through 0x0fff    
322          */                                       
323         p = ioremap(PCI_ROM_BASE1, ROM_SIZE);     
324         if (p == NULL)                            
325                 return -ENOMEM;                   
326                                                   
327         for (q = p; q < p + ROM_SIZE; q += 16)    
328                 rc = bios32_present(q);           
329                 if (!rc)                          
330                         break;                    
331         }                                         
332         iounmap(p);                               
333         return rc;                                
334 }                                                 
335                                                   
336 #else                                             
337 /* --64 Bit Bios------------------------------    
338                                                   
339 #define HPWDT_ARCH      64                        
340                                                   
341 asm(".text                      \n\t"             
342     ".align 4                   \n"               
343     "asminline_call:            \n\t"             
344     "pushq      %rbp            \n\t"             
345     "movq       %rsp, %rbp      \n\t"             
346     "pushq      %rax            \n\t"             
347     "pushq      %rbx            \n\t"             
348     "pushq      %rdx            \n\t"             
349     "pushq      %r12            \n\t"             
350     "pushq      %r9             \n\t"             
351     "movq       %rsi, %r12      \n\t"             
352     "movq       %rdi, %r9       \n\t"             
353     "movl       4(%r9),%ebx     \n\t"             
354     "movl       8(%r9),%ecx     \n\t"             
355     "movl       12(%r9),%edx    \n\t"             
356     "movl       16(%r9),%esi    \n\t"             
357     "movl       20(%r9),%edi    \n\t"             
358     "movl       (%r9),%eax      \n\t"             
359     "call       *%r12           \n\t"             
360     "pushfq                     \n\t"             
361     "popq        %r12           \n\t"             
362     "movl       %eax, (%r9)     \n\t"             
363     "movl       %ebx, 4(%r9)    \n\t"             
364     "movl       %ecx, 8(%r9)    \n\t"             
365     "movl       %edx, 12(%r9)   \n\t"             
366     "movl       %esi, 16(%r9)   \n\t"             
367     "movl       %edi, 20(%r9)   \n\t"             
368     "movq       %r12, %rax      \n\t"             
369     "movl       %eax, 28(%r9)   \n\t"             
370     "popq       %r9             \n\t"             
371     "popq       %r12            \n\t"             
372     "popq       %rdx            \n\t"             
373     "popq       %rbx            \n\t"             
374     "popq       %rax            \n\t"             
375     "leave                      \n\t"             
376     "ret                        \n\t"             
377     ".previous");                                 
378                                                   
379 /*                                                
380  *      dmi_find_cru                              
381  *                                                
382  *      Routine Description:                      
383  *      This function checks whether or not a     
384  *      the 64bit CRU info or not                 
385  */                                               
386 static void __devinit dmi_find_cru(const struc    
387 {                                                 
388         struct smbios_cru64_info *smbios_cru64    
389         unsigned long cru_physical_address;       
390                                                   
391         if (dm->type == SMBIOS_CRU64_INFORMATI    
392                 smbios_cru64_ptr = (struct smb    
393                 if (smbios_cru64_ptr->signatur    
394                         cru_physical_address =    
395                                 smbios_cru64_p    
396                                 smbios_cru64_p    
397                         cru_rom_addr = ioremap    
398                                 smbios_cru64_p    
399                         set_memory_x((unsigned    
400                                 smbios_cru64_p    
401                 }                                 
402         }                                         
403 }                                                 
404                                                   
405 static int __devinit detect_cru_service(void)     
406 {                                                 
407         cru_rom_addr = NULL;                      
408                                                   
409         dmi_walk(dmi_find_cru, NULL);             
410                                                   
411         /* if cru_rom_addr has been set then w    
412         return ((cru_rom_addr != NULL) ? 0 : -    
413 }                                                 
414                                                   
415 /* -------------------------------------------    
416                                                   
417 #endif                                            
418                                                   
419 /*                                                
420  *      Watchdog operations                       
421  */                                               
422 static void hpwdt_start(void)                     
423 {                                                 
424         reload = (soft_margin * 1000) / 128;      
425         iowrite16(reload, hpwdt_timer_reg);       
426         iowrite16(0x85, hpwdt_timer_con);         
427 }                                                 
428                                                   
429 static void hpwdt_stop(void)                      
430 {                                                 
431         unsigned long data;                       
432                                                   
433         data = ioread16(hpwdt_timer_con);         
434         data &= 0xFE;                             
435         iowrite16(data, hpwdt_timer_con);         
436 }                                                 
437                                                   
438 static void hpwdt_ping(void)                      
439 {                                                 
440         iowrite16(reload, hpwdt_timer_reg);       
441 }                                                 
442                                                   
443 static int hpwdt_change_timer(int new_margin)     
444 {                                                 
445         /* Arbitrary, can't find the card's li    
446         if (new_margin < 30 || new_margin > 60    
447                 printk(KERN_WARNING               
448                         "hpwdt: New value pass    
449                         new_margin);              
450                 return -EINVAL;                   
451         }                                         
452                                                   
453         soft_margin = new_margin;                 
454         printk(KERN_DEBUG                         
455                 "hpwdt: New timer passed in is    
456                 new_margin);                      
457         reload = (soft_margin * 1000) / 128;      
458                                                   
459         return 0;                                 
460 }                                                 
461                                                   
462 /*                                                
463  *      NMI Handler                               
464  */                                               
465 static int hpwdt_pretimeout(struct notifier_bl    
466                                 void *data)       
467 {                                                 
468         unsigned long rom_pl;                     
469         static int die_nmi_called;                
470                                                   
471         if (ulReason != DIE_NMI && ulReason !=    
472                 return NOTIFY_OK;                 
473                                                   
474         if (hpwdt_nmi_sourcing) {                 
475                 spin_lock_irqsave(&rom_lock, r    
476                 if (!die_nmi_called)              
477                         asminline_call(&cmn_re    
478                 die_nmi_called = 1;               
479                 spin_unlock_irqrestore(&rom_lo    
480                 if (cmn_regs.u1.ral == 0) {       
481                         printk(KERN_WARNING "h    
482                                 "but unable to    
483                 } else {                          
484                         if (allow_kdump)          
485                                 hpwdt_stop();     
486                         panic("An NMI occurred    
487                                 "Management Lo    
488                 }                                 
489         }                                         
490         return NOTIFY_OK;                         
491 }                                                 
492                                                   
493 /*                                                
494  *      /dev/watchdog handling                    
495  */                                               
496 static int hpwdt_open(struct inode *inode, str    
497 {                                                 
498         /* /dev/watchdog can only be opened on    
499         if (test_and_set_bit(0, &hpwdt_is_open    
500                 return -EBUSY;                    
501                                                   
502         /* Start the watchdog */                  
503         hpwdt_start();                            
504         hpwdt_ping();                             
505                                                   
506         return nonseekable_open(inode, file);     
507 }                                                 
508                                                   
509 static int hpwdt_release(struct inode *inode,     
510 {                                                 
511         /* Stop the watchdog */                   
512         if (expect_release == 42) {               
513                 hpwdt_stop();                     
514         } else {                                  
515                 printk(KERN_CRIT                  
516                         "hpwdt: Unexpected clo    
517                 hpwdt_ping();                     
518         }                                         
519                                                   
520         expect_release = 0;                       
521                                                   
522         /* /dev/watchdog is being closed, make    
523         clear_bit(0, &hpwdt_is_open);             
524                                                   
525         return 0;                                 
526 }                                                 
527                                                   
528 static ssize_t hpwdt_write(struct file *file,     
529         size_t len, loff_t *ppos)                 
530 {                                                 
531         /* See if we got the magic character '    
532         if (len) {                                
533                 if (!nowayout) {                  
534                         size_t i;                 
535                                                   
536                         /* note: just in case     
537                          * five months ago...     
538                         expect_release = 0;       
539                                                   
540                         /* scan to see whether    
541                         for (i = 0; i != len;     
542                                 char c;           
543                                 if (get_user(c    
544                                         return    
545                                 if (c == 'V')     
546                                         expect    
547                         }                         
548                 }                                 
549                                                   
550                 /* someone wrote to us, we sho    
551                 hpwdt_ping();                     
552         }                                         
553                                                   
554         return len;                               
555 }                                                 
556                                                   
557 static struct watchdog_info ident = {             
558         .options = WDIOF_SETTIMEOUT |             
559                    WDIOF_KEEPALIVEPING |          
560                    WDIOF_MAGICCLOSE,              
561         .identity = "HP iLO2 HW Watchdog Timer    
562 };                                                
563                                                   
564 static long hpwdt_ioctl(struct file *file, uns    
565         unsigned long arg)                        
566 {                                                 
567         void __user *argp = (void __user *)arg    
568         int __user *p = argp;                     
569         int new_margin;                           
570         int ret = -ENOTTY;                        
571                                                   
572         switch (cmd) {                            
573         case WDIOC_GETSUPPORT:                    
574                 ret = 0;                          
575                 if (copy_to_user(argp, &ident,    
576                         ret = -EFAULT;            
577                 break;                            
578                                                   
579         case WDIOC_GETSTATUS:                     
580         case WDIOC_GETBOOTSTATUS:                 
581                 ret = put_user(0, p);             
582                 break;                            
583                                                   
584         case WDIOC_KEEPALIVE:                     
585                 hpwdt_ping();                     
586                 ret = 0;                          
587                 break;                            
588                                                   
589         case WDIOC_SETTIMEOUT:                    
590                 ret = get_user(new_margin, p);    
591                 if (ret)                          
592                         break;                    
593                                                   
594                 ret = hpwdt_change_timer(new_m    
595                 if (ret)                          
596                         break;                    
597                                                   
598                 hpwdt_ping();                     
599                 /* Fall */                        
600         case WDIOC_GETTIMEOUT:                    
601                 ret = put_user(soft_margin, p)    
602                 break;                            
603         }                                         
604         return ret;                               
605 }                                                 
606                                                   
607 /*                                                
608  *      Kernel interfaces                         
609  */                                               
610 static const struct file_operations hpwdt_fops    
611         .owner = THIS_MODULE,                     
612         .llseek = no_llseek,                      
613         .write = hpwdt_write,                     
614         .unlocked_ioctl = hpwdt_ioctl,            
615         .open = hpwdt_open,                       
616         .release = hpwdt_release,                 
617 };                                                
618                                                   
619 static struct miscdevice hpwdt_miscdev = {        
620         .minor = WATCHDOG_MINOR,                  
621         .name = "watchdog",                       
622         .fops = &hpwdt_fops,                      
623 };                                                
624                                                   
625 static struct notifier_block die_notifier = {     
626         .notifier_call = hpwdt_pretimeout,        
627         .priority = 0,                            
628 };                                                
629                                                   
630 /*                                                
631  *      Init & Exit                               
632  */                                               
633                                                   
634 #ifdef ARCH_HAS_NMI_WATCHDOG                      
635 static void __devinit hpwdt_check_nmi_sourcing    
636 {                                                 
637         /*                                        
638          * If nmi_watchdog is turned off then     
639          * our nmi sourcing capability.           
640          */                                       
641         if (!nmi_watchdog_active())               
642                 hpwdt_nmi_sourcing = 1;           
643         else                                      
644                 dev_warn(&dev->dev, "NMI sourc    
645                         "functionality you mus    
646                         "and load the hpwdt dr    
647 }                                                 
648 #else                                             
649 static void __devinit hpwdt_check_nmi_sourcing    
650 {                                                 
651         dev_warn(&dev->dev, "NMI sourcing is d    
652                 "Your kernel does not support     
653 }                                                 
654 #endif                                            
655                                                   
656 static int __devinit hpwdt_init_one(struct pci    
657                                         const     
658 {                                                 
659         int retval;                               
660                                                   
661         /*                                        
662          * Check if we can do NMI sourcing or     
663          */                                       
664         hpwdt_check_nmi_sourcing(dev);            
665                                                   
666         /*                                        
667          * First let's find out if we are on a    
668          * not run on a legacy ASM box.           
669          * So we only support the G5 ProLiant     
670          */                                       
671         if (dev->subsystem_vendor != PCI_VENDO    
672                 dev_warn(&dev->dev,               
673                         "This server does not     
674                 return -ENODEV;                   
675         }                                         
676                                                   
677         if (pci_enable_device(dev)) {             
678                 dev_warn(&dev->dev,               
679                         "Not possible to enabl    
680                         ent->vendor, ent->devi    
681                 return -ENODEV;                   
682         }                                         
683                                                   
684         pci_mem_addr = pci_iomap(dev, 1, 0x80)    
685         if (!pci_mem_addr) {                      
686                 dev_warn(&dev->dev,               
687                         "Unable to detect the     
688                 retval = -ENOMEM;                 
689                 goto error_pci_iomap;             
690         }                                         
691         hpwdt_timer_reg = pci_mem_addr + 0x70;    
692         hpwdt_timer_con = pci_mem_addr + 0x72;    
693                                                   
694         /* Make sure that we have a valid soft    
695         if (hpwdt_change_timer(soft_margin))      
696                 hpwdt_change_timer(DEFAULT_MAR    
697                                                   
698         /*                                        
699          * We need to map the ROM to get the C    
700          * For 32 bit Operating Systems we nee    
701          * BIOS Service Directory                 
702          * For 64 bit Operating Systems we get    
703          */                                       
704         retval = detect_cru_service();            
705         if (retval < 0) {                         
706                 dev_warn(&dev->dev,               
707                         "Unable to detect the     
708                         HPWDT_ARCH);              
709                 goto error_get_cru;               
710         }                                         
711                                                   
712         /*                                        
713          * We know this is the only CRU call w    
714          * few instructions as possible once t    
715          */                                       
716         cmn_regs.u1.rah = 0x0D;                   
717         cmn_regs.u1.ral = 0x02;                   
718                                                   
719         /*                                        
720          * If the priority is set to 1, then w    
721          * die notify list to handle a critica    
722          * be last so other users of the NMI s    
723          */                                       
724         if (priority)                             
725                 die_notifier.priority = 0x7FFF    
726                                                   
727         retval = register_die_notifier(&die_no    
728         if (retval != 0) {                        
729                 dev_warn(&dev->dev,               
730                         "Unable to register a     
731                         retval);                  
732                 goto error_die_notifier;          
733         }                                         
734                                                   
735         retval = misc_register(&hpwdt_miscdev)    
736         if (retval < 0) {                         
737                 dev_warn(&dev->dev,               
738                         "Unable to register mi    
739                         WATCHDOG_MINOR, retval    
740                 goto error_misc_register;         
741         }                                         
742                                                   
743         printk(KERN_INFO                          
744                 "hp Watchdog Timer Driver: %s"    
745                 ", timer margin: %d seconds (n    
746                 ", allow kernel dump: %s (defa    
747                 ", priority: %s (default = 0/L    
748                 HPWDT_VERSION, soft_margin, no    
749                 (allow_kdump == 0) ? "OFF" : "    
750                 (priority == 0) ? "LAST" : "FI    
751                                                   
752         return 0;                                 
753                                                   
754 error_misc_register:                              
755         unregister_die_notifier(&die_notifier)    
756 error_die_notifier:                               
757         if (cru_rom_addr)                         
758                 iounmap(cru_rom_addr);            
759 error_get_cru:                                    
760         pci_iounmap(dev, pci_mem_addr);           
761 error_pci_iomap:                                  
762         pci_disable_device(dev);                  
763         return retval;                            
764 }                                                 
765                                                   
766 static void __devexit hpwdt_exit(struct pci_de    
767 {                                                 
768         if (!nowayout)                            
769                 hpwdt_stop();                     
770                                                   
771         misc_deregister(&hpwdt_miscdev);          
772         unregister_die_notifier(&die_notifier)    
773                                                   
774         if (cru_rom_addr)                         
775                 iounmap(cru_rom_addr);            
776         pci_iounmap(dev, pci_mem_addr);           
777         pci_disable_device(dev);                  
778 }                                                 
779                                                   
780 static struct pci_driver hpwdt_driver = {         
781         .name = "hpwdt",                          
782         .id_table = hpwdt_devices,                
783         .probe = hpwdt_init_one,                  
784         .remove = __devexit_p(hpwdt_exit),        
785 };                                                
786                                                   
787 static void __exit hpwdt_cleanup(void)            
788 {                                                 
789         pci_unregister_driver(&hpwdt_driver);     
790 }                                                 
791                                                   
792 static int __init hpwdt_init(void)                
793 {                                                 
794         return pci_register_driver(&hpwdt_driv    
795 }                                                 
796                                                   
797 MODULE_AUTHOR("Tom Mingarelli");                  
798 MODULE_DESCRIPTION("hp watchdog driver");         
799 MODULE_LICENSE("GPL");                            
800 MODULE_VERSION(HPWDT_VERSION);                    
801 MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);             
802                                                   
803 module_param(soft_margin, int, 0);                
804 MODULE_PARM_DESC(soft_margin, "Watchdog timeou    
805                                                   
806 module_param(allow_kdump, int, 0);                
807 MODULE_PARM_DESC(allow_kdump, "Start a kernel     
808                                                   
809 module_param(nowayout, int, 0);                   
810 MODULE_PARM_DESC(nowayout, "Watchdog cannot be    
811                 __MODULE_STRING(WATCHDOG_NOWAY    
812                                                   
813 module_param(priority, int, 0);                   
814 MODULE_PARM_DESC(priority, "The hpwdt driver h    
815                 " (default = 0/Last)\n");         
816                                                   
817 module_init(hpwdt_init);                          
818 module_exit(hpwdt_cleanup);                       
819                                                   
  This page was automatically generated by the LXR engine.