tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

introduce device_is_attached()




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);


Home | Main Index | Thread Index | Old Index