[patch] misc netdrivers

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

  • Next message: Steve Dodd: "Re: loop device deadlocks"

    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 : Sat Jun 17 2000 - 08:33:55 EDT