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/char/watchdog/pcwd_usb.c (Version 2.6.11.8) and /linux/drivers/char/watchdog/pcwd_usb.c (Version 2.6.25.8)


  1 /*                                                  1 
  2  *      Berkshire USB-PC Watchdog Card Driver     
  3  *                                                
  4  *      (c) Copyright 2004 Wim Van Sebroeck <w    
  5  *                                                
  6  *      Based on source code of the following     
  7  *        Ken Hollis <kenji@bitgate.com>,         
  8  *        Alan Cox <alan@redhat.com>,             
  9  *        Matt Domsch <Matt_Domsch@dell.com>,     
 10  *        Rob Radez <rob@osinvestor.com>,         
 11  *        Greg Kroah-Hartman <greg@kroah.com>     
 12  *                                                
 13  *      This program is free software; you can    
 14  *      modify it under the terms of the GNU G    
 15  *      as published by the Free Software Foun    
 16  *      2 of the License, or (at your option)     
 17  *                                                
 18  *      Neither Wim Van Sebroeck nor Iguana vz    
 19  *      provide warranty for any of this softw    
 20  *      provided "AS-IS" and at no charge.        
 21  *                                                
 22  *      Thanks also to Simon Machell at Berksh    
 23  *      providing the test hardware. More info    
 24  *      http://www.berkprod.com/ or http://www    
 25  */                                               
 26                                                   
 27 #include <linux/config.h>                         
 28 #include <linux/kernel.h>                         
 29 #include <linux/errno.h>                          
 30 #include <linux/init.h>                           
 31 #include <linux/slab.h>                           
 32 #include <linux/module.h>                         
 33 #include <linux/moduleparam.h>                    
 34 #include <linux/types.h>                          
 35 #include <linux/delay.h>                          
 36 #include <linux/miscdevice.h>                     
 37 #include <linux/watchdog.h>                       
 38 #include <linux/notifier.h>                       
 39 #include <linux/reboot.h>                         
 40 #include <linux/fs.h>                             
 41 #include <linux/smp_lock.h>                       
 42 #include <linux/completion.h>                     
 43 #include <asm/uaccess.h>                          
 44 #include <linux/usb.h>                            
 45                                                   
 46                                                   
 47 #ifdef CONFIG_USB_DEBUG                           
 48         static int debug = 1;                     
 49 #else                                             
 50         static int debug;                         
 51 #endif                                            
 52                                                   
 53 /* Use our own dbg macro */                       
 54 #undef dbg                                        
 55 #define dbg(format, arg...) do { if (debug) pr    
 56                                                   
 57                                                   
 58 /* Module and Version Information */              
 59 #define DRIVER_VERSION "1.00"                     
 60 #define DRIVER_DATE "12 Jun 2004"                 
 61 #define DRIVER_AUTHOR "Wim Van Sebroeck <wim@i    
 62 #define DRIVER_DESC "Berkshire USB-PC Watchdog    
 63 #define DRIVER_LICENSE "GPL"                      
 64 #define DRIVER_NAME "pcwd_usb"                    
 65 #define PFX DRIVER_NAME ": "                      
 66                                                   
 67 MODULE_AUTHOR(DRIVER_AUTHOR);                     
 68 MODULE_DESCRIPTION(DRIVER_DESC);                  
 69 MODULE_LICENSE(DRIVER_LICENSE);                   
 70 MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);             
 71 MODULE_ALIAS_MISCDEV(TEMP_MINOR);                 
 72                                                   
 73 /* Module Parameters */                           
 74 module_param(debug, int, 0);                      
 75 MODULE_PARM_DESC(debug, "Debug enabled or not"    
 76                                                   
 77 #define WATCHDOG_HEARTBEAT 2    /* 2 sec defau    
 78 static int heartbeat = WATCHDOG_HEARTBEAT;        
 79 module_param(heartbeat, int, 0);                  
 80 MODULE_PARM_DESC(heartbeat, "Watchdog heartbea    
 81                                                   
 82 #ifdef CONFIG_WATCHDOG_NOWAYOUT                   
 83 static int nowayout = 1;                          
 84 #else                                             
 85 static int nowayout = 0;                          
 86 #endif                                            
 87                                                   
 88 module_param(nowayout, int, 0);                   
 89 MODULE_PARM_DESC(nowayout, "Watchdog cannot be    
 90                                                   
 91 /* The vendor and product id's for the USB-PC     
 92 #define USB_PCWD_VENDOR_ID      0x0c98            
 93 #define USB_PCWD_PRODUCT_ID     0x1140            
 94                                                   
 95 /* table of devices that work with this driver    
 96 static struct usb_device_id usb_pcwd_table []     
 97         { USB_DEVICE(USB_PCWD_VENDOR_ID, USB_P    
 98         { }                                       
 99 };                                                
100 MODULE_DEVICE_TABLE (usb, usb_pcwd_table);        
101                                                   
102 /* according to documentation max. time to pro    
103  * watchdog card is 100 or 200 ms, so we give     
104 #define USB_COMMAND_TIMEOUT     250               
105                                                   
106 /* Watchdog's internal commands */                
107 #define CMD_READ_TEMP                   0x02      
108 #define CMD_TRIGGER                     CMD_RE    
109 #define CMD_GET_STATUS                  0x04      
110 #define CMD_GET_FIRMWARE_VERSION        0x08      
111 #define CMD_GET_DIP_SWITCH_SETTINGS     0x0c      
112 #define CMD_READ_WATCHDOG_TIMEOUT       0x18      
113 #define CMD_WRITE_WATCHDOG_TIMEOUT      0x19      
114 #define CMD_ENABLE_WATCHDOG             0x30      
115 #define CMD_DISABLE_WATCHDOG            CMD_EN    
116                                                   
117 /* Some defines that I like to be somewhere el    
118 #define HID_REQ_SET_REPORT              0x09      
119 #define HID_DT_REPORT                   (USB_T    
120                                                   
121 /* We can only use 1 card due to the /dev/watc    
122 static int cards_found;                           
123                                                   
124 /* some internal variables */                     
125 static unsigned long is_active;                   
126 static char expect_release;                       
127                                                   
128 /* Structure to hold all of our device specifi    
129 struct usb_pcwd_private {                         
130         struct usb_device *     udev;             
131         struct usb_interface *  interface;        
132                                                   
133         unsigned int            interface_numb    
134                                                   
135         unsigned char *         intr_buffer;      
136         dma_addr_t              intr_dma;         
137         size_t                  intr_size;        
138         struct urb *            intr_urb;         
139                                                   
140         unsigned char           cmd_command;      
141         unsigned char           cmd_data_msb;     
142         unsigned char           cmd_data_lsb;     
143         atomic_t                cmd_received;     
144                                                   
145         int                     exists;           
146         struct semaphore        sem;              
147 };                                                
148 static struct usb_pcwd_private *usb_pcwd_devic    
149                                                   
150 /* prevent races between open() and disconnect    
151 static DECLARE_MUTEX (disconnect_sem);            
152                                                   
153 /* local function prototypes */                   
154 static int usb_pcwd_probe       (struct usb_in    
155 static void usb_pcwd_disconnect (struct usb_in    
156                                                   
157 /* usb specific object needed to register this    
158 static struct usb_driver usb_pcwd_driver = {      
159         .owner =        THIS_MODULE,              
160         .name =         DRIVER_NAME,              
161         .probe =        usb_pcwd_probe,           
162         .disconnect =   usb_pcwd_disconnect,      
163         .id_table =     usb_pcwd_table,           
164 };                                                
165                                                   
166                                                   
167 static void usb_pcwd_intr_done(struct urb *urb    
168 {                                                 
169         struct usb_pcwd_private *usb_pcwd = (s    
170         unsigned char *data = usb_pcwd->intr_b    
171         int retval;                               
172                                                   
173         switch (urb->status) {                    
174         case 0:                 /* success */     
175                 break;                            
176         case -ECONNRESET:       /* unlink */      
177         case -ENOENT:                             
178         case -ESHUTDOWN:                          
179                 /* this urb is terminated, cle    
180                 dbg("%s - urb shutting down wi    
181                 return;                           
182         /* -EPIPE:  should clear the halt */      
183         default:                /* error */       
184                 dbg("%s - nonzero urb status r    
185                 goto resubmit;                    
186         }                                         
187                                                   
188         dbg("received following data cmd=0x%02    
189                 data[0], data[1], data[2]);       
190                                                   
191         usb_pcwd->cmd_command  = data[0];         
192         usb_pcwd->cmd_data_msb = data[1];         
193         usb_pcwd->cmd_data_lsb = data[2];         
194                                                   
195         /* notify anyone waiting that the cmd     
196         atomic_set (&usb_pcwd->cmd_received, 1    
197                                                   
198 resubmit:                                         
199         retval = usb_submit_urb (urb, GFP_ATOM    
200         if (retval)                               
201                 printk(KERN_ERR PFX "can't res    
202                         retval);                  
203 }                                                 
204                                                   
205 static int usb_pcwd_send_command(struct usb_pc    
206         unsigned char *msb, unsigned char *lsb    
207 {                                                 
208         int got_response, count;                  
209         unsigned char buf[6];                     
210                                                   
211         /* We will not send any commands if th    
212         if ((!usb_pcwd) || (!usb_pcwd->exists)    
213                 return -1;                        
214                                                   
215         /* The USB PC Watchdog uses a 6 byte r    
216          * only 3 of the six bytes of the repo    
217         buf[0] = cmd;                   /* Byt    
218         buf[1] = *msb;                  /* Byt    
219         buf[2] = *lsb;                  /* Byt    
220         buf[3] = buf[4] = buf[5] = 0;   /* All    
221                                                   
222         dbg("sending following data cmd=0x%02x    
223                 buf[0], buf[1], buf[2]);          
224                                                   
225         atomic_set (&usb_pcwd->cmd_received, 0    
226                                                   
227         if (usb_control_msg(usb_pcwd->udev, us    
228                         HID_REQ_SET_REPORT, HI    
229                         0x0200, usb_pcwd->inte    
230                         HZ) != sizeof(buf)) {     
231                 dbg("usb_pcwd_send_command: er    
232         }                                         
233         /* wait till the usb card processed th    
234          * with a max. timeout of USB_COMMAND_    
235         got_response = 0;                         
236         for (count = 0; (count < USB_COMMAND_T    
237                 mdelay(1);                        
238                 if (atomic_read (&usb_pcwd->cm    
239                         got_response = 1;         
240         }                                         
241                                                   
242         if ((got_response) && (cmd == usb_pcwd    
243                 /* read back response */          
244                 *msb = usb_pcwd->cmd_data_msb;    
245                 *lsb = usb_pcwd->cmd_data_lsb;    
246         }                                         
247                                                   
248         return got_response;                      
249 }                                                 
250                                                   
251 static int usb_pcwd_start(struct usb_pcwd_priv    
252 {                                                 
253         unsigned char msb = 0x00;                 
254         unsigned char lsb = 0x00;                 
255         int retval;                               
256                                                   
257         /* Enable Watchdog */                     
258         retval = usb_pcwd_send_command(usb_pcw    
259                                                   
260         if ((retval == 0) || (lsb == 0)) {        
261                 printk(KERN_ERR PFX "Card did     
262                 return -1;                        
263         }                                         
264                                                   
265         return 0;                                 
266 }                                                 
267                                                   
268 static int usb_pcwd_stop(struct usb_pcwd_priva    
269 {                                                 
270         unsigned char msb = 0xA5;                 
271         unsigned char lsb = 0xC3;                 
272         int retval;                               
273                                                   
274         /* Disable Watchdog */                    
275         retval = usb_pcwd_send_command(usb_pcw    
276                                                   
277         if ((retval == 0) || (lsb != 0)) {        
278                 printk(KERN_ERR PFX "Card did     
279                 return -1;                        
280         }                                         
281                                                   
282         return 0;                                 
283 }                                                 
284                                                   
285 static int usb_pcwd_keepalive(struct usb_pcwd_    
286 {                                                 
287         unsigned char dummy;                      
288                                                   
289         /* Re-trigger Watchdog */                 
290         usb_pcwd_send_command(usb_pcwd, CMD_TR    
291                                                   
292         return 0;                                 
293 }                                                 
294                                                   
295 static int usb_pcwd_set_heartbeat(struct usb_p    
296 {                                                 
297         unsigned char msb = t / 256;              
298         unsigned char lsb = t % 256;              
299                                                   
300         if ((t < 0x0001) || (t > 0xFFFF))         
301                 return -EINVAL;                   
302                                                   
303         /* Write new heartbeat to watchdog */     
304         usb_pcwd_send_command(usb_pcwd, CMD_WR    
305                                                   
306         heartbeat = t;                            
307         return 0;                                 
308 }                                                 
309                                                   
310 static int usb_pcwd_get_temperature(struct usb    
311 {                                                 
312         unsigned char msb, lsb;                   
313                                                   
314         usb_pcwd_send_command(usb_pcwd, CMD_RE    
315                                                   
316         /*                                        
317          * Convert celsius to fahrenheit, sinc    
318          * the decided 'standard' for this ret    
319          */                                       
320         *temperature = (lsb * 9 / 5) + 32;        
321                                                   
322         return 0;                                 
323 }                                                 
324                                                   
325 /*                                                
326  *      /dev/watchdog handling                    
327  */                                               
328                                                   
329 static ssize_t usb_pcwd_write(struct file *fil    
330                               size_t len, loff    
331 {                                                 
332         /* See if we got the magic character '    
333         if (len) {                                
334                 if (!nowayout) {                  
335                         size_t i;                 
336                                                   
337                         /* note: just in case     
338                          * five months ago...     
339                         expect_release = 0;       
340                                                   
341                         /* scan to see whether    
342                         for (i = 0; i != len;     
343                                 char c;           
344                                 if(get_user(c,    
345                                         return    
346                                 if (c == 'V')     
347                                         expect    
348                         }                         
349                 }                                 
350                                                   
351                 /* someone wrote to us, we sho    
352                 usb_pcwd_keepalive(usb_pcwd_de    
353         }                                         
354         return len;                               
355 }                                                 
356                                                   
357 static int usb_pcwd_ioctl(struct inode *inode,    
358                           unsigned int cmd, un    
359 {                                                 
360         void __user *argp = (void __user *)arg    
361         int __user *p = argp;                     
362         static struct watchdog_info ident = {     
363                 .options =              WDIOF_    
364                                         WDIOF_    
365                                         WDIOF_    
366                 .firmware_version =     1,        
367                 .identity =             DRIVER    
368         };                                        
369                                                   
370         switch (cmd) {                            
371                 case WDIOC_GETSUPPORT:            
372                         return copy_to_user(ar    
373                                 sizeof (ident)    
374                                                   
375                 case WDIOC_GETSTATUS:             
376                 case WDIOC_GETBOOTSTATUS:         
377                         return put_user(0, p);    
378                                                   
379                 case WDIOC_GETTEMP:               
380                 {                                 
381                         int temperature;          
382                                                   
383                         if (usb_pcwd_get_tempe    
384                                 return -EFAULT    
385                                                   
386                         return put_user(temper    
387                 }                                 
388                                                   
389                 case WDIOC_KEEPALIVE:             
390                         usb_pcwd_keepalive(usb    
391                         return 0;                 
392                                                   
393                 case WDIOC_SETOPTIONS:            
394                 {                                 
395                         int new_options, retva    
396                                                   
397                         if (get_user (new_opti    
398                                 return -EFAULT    
399                                                   
400                         if (new_options & WDIO    
401                                 usb_pcwd_stop(    
402                                 retval = 0;       
403                         }                         
404                                                   
405                         if (new_options & WDIO    
406                                 usb_pcwd_start    
407                                 retval = 0;       
408                         }                         
409                                                   
410                         return retval;            
411                 }                                 
412                                                   
413                 case WDIOC_SETTIMEOUT:            
414                 {                                 
415                         int new_heartbeat;        
416                                                   
417                         if (get_user(new_heart    
418                                 return -EFAULT    
419                                                   
420                         if (usb_pcwd_set_heart    
421                             return -EINVAL;       
422                                                   
423                         usb_pcwd_keepalive(usb    
424                         /* Fall */                
425                 }                                 
426                                                   
427                 case WDIOC_GETTIMEOUT:            
428                         return put_user(heartb    
429                                                   
430                 default:                          
431                         return -ENOIOCTLCMD;      
432         }                                         
433 }                                                 
434                                                   
435 static int usb_pcwd_open(struct inode *inode,     
436 {                                                 
437         /* /dev/watchdog can only be opened on    
438         if (test_and_set_bit(0, &is_active))      
439                 return -EBUSY;                    
440                                                   
441         /* Activate */                            
442         usb_pcwd_start(usb_pcwd_device);          
443         usb_pcwd_keepalive(usb_pcwd_device);      
444         return nonseekable_open(inode, file);     
445 }                                                 
446                                                   
447 static int usb_pcwd_release(struct inode *inod    
448 {                                                 
449         /*                                        
450          *      Shut off the timer.               
451          */                                       
452         if (expect_release == 42) {               
453                 usb_pcwd_stop(usb_pcwd_device)    
454         } else {                                  
455                 printk(KERN_CRIT PFX "Unexpect    
456                 usb_pcwd_keepalive(usb_pcwd_de    
457         }                                         
458         expect_release = 0;                       
459         clear_bit(0, &is_active);                 
460         return 0;                                 
461 }                                                 
462                                                   
463 /*                                                
464  *      /dev/temperature handling                 
465  */                                               
466                                                   
467 static ssize_t usb_pcwd_temperature_read(struc    
468                                 size_t len, lo    
469 {                                                 
470         int temperature;                          
471                                                   
472         if (usb_pcwd_get_temperature(usb_pcwd_    
473                 return -EFAULT;                   
474                                                   
475         if (copy_to_user(data, &temperature, 1    
476                 return -EFAULT;                   
477                                                   
478         return 1;                                 
479 }                                                 
480                                                   
481 static int usb_pcwd_temperature_open(struct in    
482 {                                                 
483         return nonseekable_open(inode, file);     
484 }                                                 
485                                                   
486 static int usb_pcwd_temperature_release(struct    
487 {                                                 
488         return 0;                                 
489 }                                                 
490                                                   
491 /*                                                
492  *      Notify system                             
493  */                                               
494                                                   
495 static int usb_pcwd_notify_sys(struct notifier    
496 {                                                 
497         if (code==SYS_DOWN || code==SYS_HALT)     
498                 /* Turn the WDT off */            
499                 usb_pcwd_stop(usb_pcwd_device)    
500         }                                         
501                                                   
502         return NOTIFY_DONE;                       
503 }                                                 
504                                                   
505 /*                                                
506  *      Kernel Interfaces                         
507  */                                               
508                                                   
509 static struct file_operations usb_pcwd_fops =     
510         .owner =        THIS_MODULE,              
511         .llseek =       no_llseek,                
512         .write =        usb_pcwd_write,           
513         .ioctl =        usb_pcwd_ioctl,           
514         .open =         usb_pcwd_open,            
515         .release =      usb_pcwd_release,         
516 };                                                
517                                                   
518 static struct miscdevice usb_pcwd_miscdev = {     
519         .minor =        WATCHDOG_MINOR,           
520         .name =         "watchdog",               
521         .fops =         &usb_pcwd_fops,           
522 };                                                
523                                                   
524 static struct file_operations usb_pcwd_tempera    
525         .owner =        THIS_MODULE,              
526         .llseek =       no_llseek,                
527         .read =         usb_pcwd_temperature_r    
528         .open =         usb_pcwd_temperature_o    
529         .release =      usb_pcwd_temperature_r    
530 };                                                
531                                                   
532 static struct miscdevice usb_pcwd_temperature_    
533         .minor =        TEMP_MINOR,               
534         .name =         "temperature",            
535         .fops =         &usb_pcwd_temperature_    
536 };                                                
537                                                   
538 static struct notifier_block usb_pcwd_notifier    
539         .notifier_call =        usb_pcwd_notif    
540 };                                                
541                                                   
542 /**                                               
543  *      usb_pcwd_delete                           
544  */                                               
545 static inline void usb_pcwd_delete (struct usb    
546 {                                                 
547         if (usb_pcwd->intr_urb != NULL)           
548                 usb_free_urb (usb_pcwd->intr_u    
549         if (usb_pcwd->intr_buffer != NULL)        
550                 usb_buffer_free(usb_pcwd->udev    
551                                 usb_pcwd->intr    
552         kfree (usb_pcwd);                         
553 }                                                 
554                                                   
555 /**                                               
556  *      usb_pcwd_probe                            
557  *                                                
558  *      Called by the usb core when a new devi    
559  *      this driver might be interested in.       
560  */                                               
561 static int usb_pcwd_probe(struct usb_interface    
562 {                                                 
563         struct usb_device *udev = interface_to    
564         struct usb_host_interface *iface_desc;    
565         struct usb_endpoint_descriptor *endpoi    
566         struct usb_pcwd_private *usb_pcwd = NU    
567         int pipe, maxp;                           
568         int retval = -ENOMEM;                     
569         int got_fw_rev;                           
570         unsigned char fw_rev_major, fw_rev_min    
571         char fw_ver_str[20];                      
572         unsigned char option_switches, dummy;     
573                                                   
574         cards_found++;                            
575         if (cards_found > 1) {                    
576                 printk(KERN_ERR PFX "This driv    
577                 return -ENODEV;                   
578         }                                         
579                                                   
580         /* get the active interface descriptor    
581         iface_desc = interface->cur_altsetting    
582                                                   
583         /* check out that we have a HID device    
584         if (!(iface_desc->desc.bInterfaceClass    
585                 printk(KERN_ERR PFX "The devic    
586                 return -ENODEV;                   
587         }                                         
588                                                   
589         /* check out the endpoint: it has to b    
590         endpoint = &iface_desc->endpoint[0].de    
591                                                   
592         if (!((endpoint->bEndpointAddress & US    
593              ((endpoint->bmAttributes & USB_EN    
594                                 == USB_ENDPOIN    
595                 /* we didn't find a Interrupt     
596                 printk(KERN_ERR PFX "Couldn't     
597                 return -ENODEV;                   
598         }                                         
599                                                   
600         /* get a handle to the interrupt data     
601         pipe = usb_rcvintpipe(udev, endpoint->    
602         maxp = usb_maxpacket(udev, pipe, usb_p    
603                                                   
604         /* allocate memory for our device and     
605         usb_pcwd = kmalloc (sizeof(struct usb_    
606         if (usb_pcwd == NULL) {                   
607                 printk(KERN_ERR PFX "Out of me    
608                 goto error;                       
609         }                                         
610         memset (usb_pcwd, 0x00, sizeof (*usb_p    
611                                                   
612         usb_pcwd_device = usb_pcwd;               
613                                                   
614         init_MUTEX (&usb_pcwd->sem);              
615         usb_pcwd->udev = udev;                    
616         usb_pcwd->interface = interface;          
617         usb_pcwd->interface_number = iface_des    
618         usb_pcwd->intr_size = (le16_to_cpu(end    
619                                                   
620         /* set up the memory buffer's */          
621         if (!(usb_pcwd->intr_buffer = usb_buff    
622                 printk(KERN_ERR PFX "Out of me    
623                 goto error;                       
624         }                                         
625                                                   
626         /* allocate the urb's */                  
627         usb_pcwd->intr_urb = usb_alloc_urb(0,     
628         if (!usb_pcwd->intr_urb) {                
629                 printk(KERN_ERR PFX "Out of me    
630                 goto error;                       
631         }                                         
632                                                   
633         /* initialise the intr urb's */           
634         usb_fill_int_urb(usb_pcwd->intr_urb, u    
635                         usb_pcwd->intr_buffer,    
636                         usb_pcwd_intr_done, us    
637         usb_pcwd->intr_urb->transfer_dma = usb    
638         usb_pcwd->intr_urb->transfer_flags |=     
639                                                   
640         /* register our interrupt URB with the    
641         if (usb_submit_urb(usb_pcwd->intr_urb,    
642                 printk(KERN_ERR PFX "Problem r    
643                 retval = -EIO; /* failure */      
644                 goto error;                       
645         }                                         
646                                                   
647         /* The device exists and can be commun    
648         usb_pcwd->exists = 1;                     
649                                                   
650         /* disable card */                        
651         usb_pcwd_stop(usb_pcwd);                  
652                                                   
653         /* Get the Firmware Version */            
654         got_fw_rev = usb_pcwd_send_command(usb    
655         if (got_fw_rev) {                         
656                 sprintf(fw_ver_str, "%u.%02u",    
657         } else {                                  
658                 sprintf(fw_ver_str, "<card no     
659         }                                         
660                                                   
661         printk(KERN_INFO PFX "Found card (Firm    
662                 fw_ver_str);                      
663                                                   
664         /* Get switch settings */                 
665         usb_pcwd_send_command(usb_pcwd, CMD_GE    
666                                                   
667         printk(KERN_INFO PFX "Option switches     
668                 option_switches,                  
669                 ((option_switches & 0x10) ? "O    
670                 ((option_switches & 0x08) ? "O    
671                                                   
672         /* Check that the heartbeat value is w    
673         if (usb_pcwd_set_heartbeat(usb_pcwd, h    
674                 usb_pcwd_set_heartbeat(usb_pcw    
675                 printk(KERN_INFO PFX "heartbea    
676                         WATCHDOG_HEARTBEAT);      
677         }                                         
678                                                   
679         retval = register_reboot_notifier(&usb    
680         if (retval != 0) {                        
681                 printk(KERN_ERR PFX "cannot re    
682                         retval);                  
683                 goto error;                       
684         }                                         
685                                                   
686         retval = misc_register(&usb_pcwd_tempe    
687         if (retval != 0) {                        
688                 printk(KERN_ERR PFX "cannot re    
689                         TEMP_MINOR, retval);      
690                 goto err_out_unregister_reboot    
691         }                                         
692                                                   
693         retval = misc_register(&usb_pcwd_miscd    
694         if (retval != 0) {                        
695                 printk(KERN_ERR PFX "cannot re    
696                         WATCHDOG_MINOR, retval    
697                 goto err_out_misc_deregister;     
698         }                                         
699                                                   
700         /* we can register the device now, as     
701         usb_set_intfdata (interface, usb_pcwd)    
702                                                   
703         printk(KERN_INFO PFX "initialized. hea    
704                 heartbeat, nowayout);             
705                                                   
706         return 0;                                 
707                                                   
708 err_out_misc_deregister:                          
709         misc_deregister(&usb_pcwd_temperature_    
710 err_out_unregister_reboot:                        
711         unregister_reboot_notifier(&usb_pcwd_n    
712 error:                                            
713         usb_pcwd_delete (usb_pcwd);               
714         usb_pcwd_device = NULL;                   
715         return retval;                            
716 }                                                 
717                                                   
718                                                   
719 /**                                               
720  *      usb_pcwd_disconnect                       
721  *                                                
722  *      Called by the usb core when the device    
723  *                                                
724  *      This routine guarantees that the drive    
725  *      by clearing dev->udev.                    
726  */                                               
727 static void usb_pcwd_disconnect(struct usb_int    
728 {                                                 
729         struct usb_pcwd_private *usb_pcwd;        
730                                                   
731         /* prevent races with open() */           
732         down (&disconnect_sem);                   
733                                                   
734         usb_pcwd = usb_get_intfdata (interface    
735         usb_set_intfdata (interface, NULL);       
736                                                   
737         down (&usb_pcwd->sem);                    
738                                                   
739         /* Stop the timer before we leave */      
740         if (!nowayout)                            
741                 usb_pcwd_stop(usb_pcwd);          
742                                                   
743         /* We should now stop communicating wi    
744         usb_pcwd->exists = 0;                     
745                                                   
746         /* Deregister */                          
747         misc_deregister(&usb_pcwd_miscdev);       
748         misc_deregister(&usb_pcwd_temperature_    
749         unregister_reboot_notifier(&usb_pcwd_n    
750                                                   
751         up (&usb_pcwd->sem);                      
752                                                   
753         /* Delete the USB PCWD device */          
754         usb_pcwd_delete(usb_pcwd);                
755                                                   
756         cards_found--;                            
757                                                   
758         up (&disconnect_sem);                     
759                                                   
760         printk(KERN_INFO PFX "USB PC Watchdog     
761 }                                                 
762                                                   
763                                                   
764                                                   
765 /**                                               
766  *      usb_pcwd_init                             
767  */                                               
768 static int __init usb_pcwd_init(void)             
769 {                                                 
770         int result;                               
771                                                   
772         /* register this driver with the USB s    
773         result = usb_register(&usb_pcwd_driver    
774         if (result) {                             
775                 printk(KERN_ERR PFX "usb_regis    
776                     result);                      
777                 return result;                    
778         }                                         
779                                                   
780         printk(KERN_INFO PFX DRIVER_DESC " v"     
781         return 0;                                 
782 }                                                 
783                                                   
784                                                   
785 /**                                               
786  *      usb_pcwd_exit                             
787  */                                               
788 static void __exit usb_pcwd_exit(void)            
789 {                                                 
790         /* deregister this driver with the USB    
791         usb_deregister(&usb_pcwd_driver);         
792 }                                                 
793                                                   
794                                                   
795 module_init (usb_pcwd_init);                      
796 module_exit (usb_pcwd_exit);                      
797                                                   
  This page was automatically generated by the LXR engine.