[patch-2.4.0-test8-pre5] bugfixes for rtc driver (fwd)

From: Tigran Aivazian (tigran@veritas.com)
Date: Wed Sep 06 2000 - 15:32:36 EST


sorry, I've done it again...

---------- Forwarded message ----------
Date: Wed, 6 Sep 2000 21:29:20 +0100 (BST)
From: Tigran Aivazian <tigran@veritas.com>
To: Linus Torvalds <torvalds@transmeta.com>
Cc: linux-kernel@vger.rutgers.edu
Subject: [patch-2.4.0-test8-pre5] bugfixes for rtc driver

Hi Linus,

The rtc driver does:

a) not handle failures from misc_register() gracefully

b) not handle failures from create_proc_read_entry() gracefully

c) uses check_region() where request_region() would suffice

The patch below fixes these issues/bugs.

Regards,
Tigran

--- linux/drivers/char/rtc.c Fri Jul 28 09:58:59 2000
+++ work/drivers/char/rtc.c Wed Sep 6 13:20:45 2000
@@ -39,9 +39,10 @@
  * 1.10a Andrea Arcangeli: Alpha updates
  * 1.10b Andrew Morton: SMP lock fix
  * 1.10c Cesar Barros: SMP locking fixes and cleanup
+ * 1.10d Tigran Aivazian: Restructured rtc_init and got rid of check_region
  */
 
-#define RTC_VERSION "1.10c"
+#define RTC_VERSION "1.10d"
 
 #define RTC_IO_EXTENT 0x10 /* Only really two ports, but... */
 
@@ -625,6 +626,15 @@
         struct linux_ebus_device *edev;
 #endif
 
+ if (misc_register(&rtc_dev)) {
+ printk(KERN_ERR "rtc: cannot misc_register on minor=%d\n", RTC_MINOR);
+ return -EBUSY;
+ }
+ if (!create_proc_read_entry("driver/rtc", 0, 0, rtc_read_proc, NULL)) {
+ printk(KERN_ERR "rtc: cannot create file /proc/driver/rtc\n");
+ goto outmisc;
+ }
+
 #ifdef __sparc__
         for_each_ebus(ebus) {
                 for_each_ebusdev(edev, ebus) {
@@ -633,8 +643,8 @@
                         }
                 }
         }
- printk("rtc_init: no PC rtc found\n");
- return -EIO;
+ printk(KERN_ERR "rtc: no PC rtc found\n");
+ goto outproc;
 
 found:
         rtc_port = edev->resource[0].start;
@@ -649,30 +659,26 @@
                  * Standard way for sparc to print irq's is to use
                  * __irq_itoa(). I think for EBus it's ok to use %d.
                  */
- printk("rtc: cannot register IRQ %d\n", rtc_irq);
- return -EIO;
+ printk(KERN_ERR "rtc: cannot register IRQ %d\n", rtc_irq);
+ goto outproc;
         }
 #else
- if (check_region (RTC_PORT (0), RTC_IO_EXTENT))
- {
- printk(KERN_ERR "rtc: I/O port %d is not free.\n", RTC_PORT (0));
- return -EIO;
+ if (!request_region(RTC_PORT (0), RTC_IO_EXTENT, "rtc")) {
+ printk(KERN_ERR "rtc: I/O port %d is not free\n", RTC_PORT (0));
+ goto outproc;
         }
 
 #if RTC_IRQ
- if(request_irq(RTC_IRQ, rtc_interrupt, SA_INTERRUPT, "rtc", NULL))
- {
+ if(request_irq(RTC_IRQ, rtc_interrupt, SA_INTERRUPT, "rtc", NULL)) {
                 /* Yeah right, seeing as irq 8 doesn't even hit the bus. */
- printk(KERN_ERR "rtc: IRQ %d is not free.\n", RTC_IRQ);
- return -EIO;
+ printk(KERN_ERR "rtc: IRQ %d is not free\n", RTC_IRQ);
+ release_region(RTC_PORT (0), RTC_IO_EXTENT);
+ goto outproc;
         }
 #endif
 
- request_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc");
 #endif /* __sparc__ vs. others */
 
- misc_register(&rtc_dev);
- create_proc_read_entry ("driver/rtc", 0, 0, rtc_read_proc, NULL);
 
 #if defined(__alpha__) || defined(__mips__)
         rtc_freq = HZ;
@@ -717,33 +723,38 @@
 #endif
 
         printk(KERN_INFO "Real Time Clock Driver v" RTC_VERSION "\n");
-
         return 0;
+
+outproc:
+ remove_proc_entry("driver/rtc", NULL);
+outmisc:
+ misc_deregister(&rtc_dev);
+ return -EIO;
 }
 
-static void __exit rtc_exit (void)
+static void __exit rtc_exit(void)
 {
         /* interrupts and maybe timer disabled at this point by rtc_release */
         /* FIXME: Maybe??? */
 
         if (rtc_status & RTC_TIMER_ON) {
- spin_lock_irq (&rtc_lock);
+ spin_lock_irq(&rtc_lock);
                 rtc_status &= ~RTC_TIMER_ON;
                 del_timer(&rtc_irq_timer);
- spin_unlock_irq (&rtc_lock);
+ spin_unlock_irq(&rtc_lock);
 
                 printk(KERN_WARNING "rtc_exit(), and timer still running.\n");
         }
 
- remove_proc_entry ("driver/rtc", NULL);
+ remove_proc_entry("driver/rtc", NULL);
         misc_deregister(&rtc_dev);
 
 #ifdef __sparc__
- free_irq (rtc_irq, &rtc_port);
+ free_irq(rtc_irq, &rtc_port);
 #else
- release_region (RTC_PORT (0), RTC_IO_EXTENT);
+ release_region(RTC_PORT (0), RTC_IO_EXTENT);
 #if RTC_IRQ
- free_irq (RTC_IRQ, NULL);
+ free_irq(RTC_IRQ, NULL);
 #endif
 #endif /* __sparc__ */
 }

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Thu Sep 07 2000 - 21:00:27 EST