Hi,
I want to introduce a new function to sys/devices.h: bool device_is_attached(device_t parent, cfdata_t cf); The purpose is for bus drivers who wants to attach children and ensure that only one instance of it will attach. 'parent' is the bus driver and 'cf' is the child device as passed to the submatch callback via config_search_loc(). The return value is true if the child is already attached. I implemented a reference usage of it in amdnb_misc.c to ensure that amdtemp only attaches once on rescan. Any comments to the patch? Christoph
Index: sys/sys/device.h =================================================================== RCS file: /cvsroot/src/sys/sys/device.h,v retrieving revision 1.140 diff -u -p -r1.140 device.h --- sys/sys/device.h 13 Nov 2011 22:05:58 -0000 1.140 +++ sys/sys/device.h 16 Apr 2012 16:38:11 -0000 @@ -528,6 +528,9 @@ void device_active_deregister(device_t, bool device_is_a(device_t, const char *); +bool device_is_attached(device_t, cfdata_t); + + device_t device_find_by_xname(const char *); device_t device_find_by_driver_unit(const char *, int); Index: sys/kern/subr_device.c =================================================================== RCS file: /cvsroot/src/sys/kern/subr_device.c,v retrieving revision 1.2 diff -u -p -r1.2 subr_device.c --- sys/kern/subr_device.c 31 Jan 2010 15:10:12 -0000 1.2 +++ sys/kern/subr_device.c 16 Apr 2012 16:38:11 -0000 @@ -176,3 +176,32 @@ device_is_a(device_t dev, const char *dn return strcmp(dev->dv_cfdriver->cd_name, dname) == 0; } + +/* + * device_is_attached: + * + * Returns true if a driver already attached to a device. + * Useful for bus drivers to figure if driver already attached + * to prevent drivers attaching twice. + */ +bool +device_is_attached(device_t parent, cfdata_t cf) +{ + device_t dev; + deviter_t di; + bool attached = false; + + for (dev = deviter_first(&di, DEVITER_F_LEAVES_FIRST); dev != NULL; + dev = deviter_next(&di)) + { + if (device_parent(dev) != parent) + continue; + if (device_is_a(dev, cf->cf_name)) { + attached = true; + break; + } + } + deviter_release(&di); + + return attached; +} Index: sys/arch/x86/pci/amdnb_misc.c =================================================================== RCS file: /cvsroot/src/sys/arch/x86/pci/amdnb_misc.c,v retrieving revision 1.2 diff -u -p -r1.2 amdnb_misc.c --- sys/arch/x86/pci/amdnb_misc.c 16 Apr 2012 16:07:24 -0000 1.2 +++ sys/arch/x86/pci/amdnb_misc.c 16 Apr 2012 16:38:11 -0000 @@ -78,38 +78,13 @@ amdnb_misc_match(device_t parent, cfdata static int amdnb_misc_search(device_t parent, cfdata_t cf, const int *locs, void *aux) { - device_t dev; - deviter_t di; - bool attach; - if (!config_match(parent, cf, aux)) return 0; - attach = true; - /* Figure out if found child 'cf' is already attached. * No need to attach it twice. */ - - /* XXX: I only want to iterate over the children of *this* device. - * Can we introduce a - * deviter_first_child(&di, parent, DEVITER_F_LEAVES_ONLY) - * or even better, can we introduce a query function that returns - * if a child is already attached? - */ - for (dev = deviter_first(&di, DEVITER_F_LEAVES_FIRST); dev != NULL; - dev = deviter_next(&di)) - { - if (device_parent(dev) != parent) - continue; - if (device_is_a(dev, cf->cf_name)) { - attach = false; - break; - } - } - deviter_release(&di); - - if (!attach) + if (device_is_attached(parent, cf)) return 0; config_attach_loc(parent, cf, locs, aux, NULL);