Re: newbus flaw

From: Doug Rabson (dfr_at_nlsystems.com)
Date: 05/11/04

  • Next message: Poul-Henning Kamp: "Re: newbus flaw"
    To: Dag-Erling Smørgrav <des@des.no>
    Date: Tue, 11 May 2004 16:07:50 +0100
    
    

    On Tue, 2004-05-11 at 15:39, Dag-Erling Smørgrav wrote:
    > I've found what I believe is a serious flaw in newbus.
    >
    > When a driver that has a DEVICE_IDENTIFY method is loaded, the
    > identify method is called. If it finds supported hardware, it uses
    > BUS_ADD_CHILD to notify the parent bus of the presence of that
    > hardware. At some later point, during a bus rescan, the attach
    > routine is called for each device that was identified in this manner.
    >
    > When the driver is unloaded, the device is detached, but it remains on
    > the bus's list of child devices. The next time the module is loaded,
    > its DEVICE_IDENTIFY method is called again, and incorrectly adds a
    > second child device to the bus, because it does not know that one
    > already exists.
    >
    > There is no way for DEVICE_IDENTIFY to check if a matching child
    > already exists on the bus, or for the module's event handler to unlist
    > the child when unloading.
    >
    > The first time you load the module, you get foo0; the second time, you
    > get foo0 *and* foo1 referencing the same physical device; the third
    > time, you get foo0, foo1, and foo2, etc.
    >
    > I've also seen something similar happen when multiple ndis drivers are
    > loaded; the first one re-attaches to the hardware when the second one
    > is loaded.

    This is a known problem. The 'right' solution is to add a new static
    method to the device interface which is the opposite of IDENTIFY (e.g.
    UNIDENTIFY). One way to get around the problem is to do something like:

    void foo_identify(driver_t *driver, device_t parent)
    {
            device_t child;
            child = device_find_child(parent, "foo", 0);
            if (!child)
                    BUS_ADD_CHILD(parent, 0, "foo", 0);
    }

    Alternatively, you can add a module handler:

    static device_t foo;

    void foo_identify(driver_t *driver, device_t parent)
    {
            foo = BUS_ADD_CHILD(parent, 0, "foo", -1);
    }

    ...

    int foo_module_handler(struct module *mod, int what, void *arg)
    {
            if (what == MOD_UNLOAD && foo)
                    device_delete_child(device_get_parent(foo), foo);
    }

    ...

    DRIVER_MODULE(foo, bar, foo_driver, foo_devclass, foo_module_handler,
    0);

    _______________________________________________
    freebsd-arch@freebsd.org mailing list
    http://lists.freebsd.org/mailman/listinfo/freebsd-arch
    To unsubscribe, send any mail to "freebsd-arch-unsubscribe@freebsd.org"


  • Next message: Poul-Henning Kamp: "Re: newbus flaw"

    Relevant Pages

    • newbus flaw
      ... At some later point, during a bus rescan, the attach ... When the driver is unloaded, the device is detached, but it remains on ... the bus's list of child devices. ... The first time you load the module, you get foo0; ...
      (freebsd-arch)
    • Re: WDF Bus Drivers, Hal Calls and Removing Resources
      ... Who owns the source code of driver for child devices? ... You cannot assign resources to your child devices using ... information from the bus. ...
      (microsoft.public.development.device.drivers)
    • Re: newbus flaw
      ... > the bus's list of child devices. ... > already exists on the bus, or for the module's event handler to unlist ... For example, in my adv717xa driver, part of the zoran driver, I do the ...
      (freebsd-arch)
    • [origin tree SLAB corruption] BUG kmalloc-64: Poison overwritten, INFO: Allocated in bdi_alloc_w
      ... Bus #0 is PCI ... Performance Counters: AMD PMU driver. ... initcall migration_init+0x0/0x69 returned 0 after 3255 usecs ... calling spawn_ksoftirqd+0x0/0x69 @ 1 ...
      (Linux-Kernel)
    • [origin tree boot crash] Re: [GIT PATCH] TTY patches for 2.6.31-git
      ... # Power management and ACPI options ... # Bus options (PCI etc.) ... # You can enable one or both FireWire driver stacks. ...
      (Linux-Kernel)