[patch] misc netdrivers

From: Andrew Morton (andrewm@uow.edu.au)
Date: Sat Jun 17 2000 - 07:31:33 EST


Alan,

This is the result of going through about half the net drivers (the most
important half). Reviewing and fixing the following:

- timer deletion safety
   (This does not imply these drivers are now SMP safe. Some aren't)

- MOD_INC_USE_COUNT races in open().

- Resource leaks.

  Lots of drivers like to leak resources if a later resource
  allocation fails.

- Failure to check resource allocation failures

- Failure to warn on resource allocation failures.

To avoid adding lots of new printk's (in fact a few have been removed) I
have created a couple of new API functions:

request_irq_warn()
request_region_warn()/request_mem_region_warn().

These are wrappers around the existing allocation functions which simply
blurt a message if it failed. The request_region_warn() function is
kinda nice because it tells you where the conflict occurred. eg:

kernel: eth1: request for region 0xa800-0xa87f failed
kernel: Conflicts with 3Com Corporation 3c905B 100BaseTX [Cyclone]
(0xa800-0xa87f)

The patch which adds these functions is attached here.

The patch against the following drivers:

drivers/net/via-rhine.c
drivers/net/de4x5.c
drivers/net/pcnet32.c
drivers/net/3c501.c
drivers/net/3c503.c
drivers/net/3c505.c
drivers/net/3c507.c
drivers/net/3c509.c
drivers/net/3c515.c
drivers/net/3c527.c
drivers/net/eql.c
drivers/net/ne.c
drivers/net/sis900.c
drivers/net/yellowfin.c
drivers/net/cs89x0.c

is a little long, so it's at
http://www.uow.edu.au/~andrewm/drivers-net-1.patch - this patch uses the
*_warn() functions, so if they're not liked I'll have to redo it :(

Patches against ppp_deflate.c, pppoe.c, tlan.c, rtl8129.c, rrunner.c,
epic100.c, eepro100.c, 8139too.c, and acenic.c have been sent to the
maintainers. None of these use the new *_warn() functions.

--- linux-2.4.0-test1-ac19/include/linux/ioport.h Wed Mar 1 10:28:46 2000
+++ linux-akpm/include/linux/ioport.h Fri Jun 16 21:40:13 2000
@@ -91,8 +91,11 @@
 /* Convenience shorthand with allocation */
 #define request_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name))
 #define request_mem_region(start,n,name) __request_region(&iomem_resource, (start), (n), (name))
+#define request_region_warn(start,n,name) __request_region_warn(&ioport_resource, (start), (n), (name))
+#define request_mem_region_warn(start,n,name) __request_region_warn(&iomem_resource, (start), (n), (name))
 
 extern struct resource * __request_region(struct resource *, unsigned long start, unsigned long n, const char *name);
+extern struct resource * __request_region_warn(struct resource *, unsigned long start, unsigned long n, const char *name);
 
 /* Compatibility cruft */
 #define check_region(start,n) __check_region(&ioport_resource, (start), (n))
--- linux-2.4.0-test1-ac19/kernel/resource.c Wed Mar 1 10:28:46 2000
+++ linux-akpm/kernel/resource.c Fri Jun 16 21:40:13 2000
@@ -249,6 +249,36 @@
         return res;
 }
 
+/*
+ * The same as the above, only print out a user-friendly message
+ */
+struct resource * __request_region_warn(struct resource *parent,
+ unsigned long start, unsigned long n, const char *name)
+{
+ struct resource *ret = __request_region(parent, start, n, name);
+ if (ret == NULL) {
+ struct resource *conflict, tmp;
+
+ tmp.start = start;
+ tmp.end = start + n - 1;
+ write_lock(&resource_lock);
+ conflict = __request_resource(parent, &tmp);
+ if (!conflict) /* Can't happen? */
+ __release_resource(&tmp);
+ write_unlock(&resource_lock);
+
+ printk(KERN_ERR "%s: request for region 0x%lx-0x%lx failed\n",
+ name, start, start + n - 1);
+ if (conflict == NULL) {
+ printk(KERN_ERR "Cannot find conflicting resource!!\n");
+ } else {
+ printk(KERN_ERR "Conflicts with %s (0x%lx-0x%lx)\n",
+ conflict->name, conflict->start, conflict->end);
+ }
+ }
+ return ret;
+}
+
 int __check_region(struct resource *parent, unsigned long start, unsigned long n)
 {
         struct resource * res;
@@ -289,6 +319,24 @@
                 p = &res->sibling;
         }
         printk("Trying to free nonexistent resource <%04lx-%04lx>\n", start, end);
+}
+
+/*
+ * Like request_irq(), but tell the user what happened
+ */
+int request_irq_warn( unsigned int irq,
+ void (*handler)(int, void *, struct pt_regs *),
+ unsigned long irqflags,
+ const char * devname,
+ void *dev_id)
+{
+ int ret = request_irq(irq, handler, irqflags, devname, dev_id);
+
+ if (ret != 0) {
+ printk(KERN_ERR "%s: failed to allocate IRQ %d. Error: %d\n",
+ devname, irq, -ret);
+ }
+ return ret;
 }
 
 /*
--- linux-2.4.0-test1-ac19/include/linux/sched.h Fri Jun 16 00:43:30 2000
+++ linux-akpm/include/linux/sched.h Fri Jun 16 21:40:13 2000
@@ -582,6 +582,9 @@
 extern int request_irq(unsigned int,
                        void (*handler)(int, void *, struct pt_regs *),
                        unsigned long, const char *, void *);
+extern int request_irq_warn(unsigned int,
+ void (*handler)(int, void *, struct pt_regs *),
+ unsigned long, const char *, void *);
 extern void free_irq(unsigned int, void *);
 
 /*
--- linux-2.4.0-test1-ac19/kernel/ksyms.c Fri Jun 16 00:43:30 2000
+++ linux-akpm/kernel/ksyms.c Sat Jun 17 22:04:58 2000
@@ -349,6 +349,7 @@
 EXPORT_SYMBOL(add_timer);
 EXPORT_SYMBOL(del_timer);
 EXPORT_SYMBOL(request_irq);
+EXPORT_SYMBOL(request_irq_warn);
 EXPORT_SYMBOL(free_irq);
 
 /* The notion of irq probe/assignment is foreign to S/390 */
@@ -411,6 +412,7 @@
 EXPORT_SYMBOL(allocate_resource);
 EXPORT_SYMBOL(check_resource);
 EXPORT_SYMBOL(__request_region);
+EXPORT_SYMBOL(__request_region_warn);
 EXPORT_SYMBOL(__check_region);
 EXPORT_SYMBOL(__release_region);
 EXPORT_SYMBOL(ioport_resource);

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



This archive was generated by hypermail 2b29 : Fri Jun 23 2000 - 21:00:14 EST