Author: attilio
Date: Thu Sep  3 13:40:41 2009
New Revision: 196779
URL: http://svn.freebsd.org/changeset/base/196779

Log:
  Add intermediate states for attaching and detaching that will be
  reused by the enhached newbus locking once it is checked in.
  This change can be easilly MFCed to STABLE_8 at the appropriate moment.
  
  Reviewed by:  jhb, scottl
  Tested by:    Giovanni Trematerra <giovanni dot trematerra at gmail dot com>

Modified:
  head/sys/kern/subr_bus.c
  head/sys/sys/bus.h

Modified: head/sys/kern/subr_bus.c
==============================================================================
--- head/sys/kern/subr_bus.c    Thu Sep  3 12:41:00 2009        (r196778)
+++ head/sys/kern/subr_bus.c    Thu Sep  3 13:40:41 2009        (r196779)
@@ -2625,10 +2625,16 @@ device_attach(device_t dev)
 {
        int error;
 
+       if (dev->state >= DS_ATTACHING)
+               return (0);
        device_sysctl_init(dev);
        if (!device_is_quiet(dev))
                device_print_child(dev->parent, dev);
+       dev->state = DS_ATTACHING;
        if ((error = DEVICE_ATTACH(dev)) != 0) {
+               KASSERT(dev->state == DS_ATTACHING,
+                   ("%s: %p device state must not been changing", __func__,
+                   dev));
                printf("device_attach: %s%d attach returned %d\n",
                    dev->driver->name, dev->unit, error);
                /* Unset the class; set in device_probe_child */
@@ -2639,6 +2645,8 @@ device_attach(device_t dev)
                dev->state = DS_NOTPRESENT;
                return (error);
        }
+       KASSERT(dev->state == DS_ATTACHING,
+           ("%s: %p device state must not been changing", __func__, dev));
        device_sysctl_update(dev);
        dev->state = DS_ATTACHED;
        devadded(dev);
@@ -2674,8 +2682,16 @@ device_detach(device_t dev)
        if (dev->state != DS_ATTACHED)
                return (0);
 
-       if ((error = DEVICE_DETACH(dev)) != 0)
+       dev->state = DS_DETACHING;
+       if ((error = DEVICE_DETACH(dev)) != 0) {
+               KASSERT(dev->state == DS_DETACHING,
+                   ("%s: %p device state must not been changing", __func__,
+                   dev));
+               dev->state = DS_ATTACHED;
                return (error);
+       }
+       KASSERT(dev->state == DS_DETACHING,
+           ("%s: %p device state must not been changing", __func__, dev));
        devremoved(dev);
        if (!device_is_quiet(dev))
                device_printf(dev, "detached\n");
@@ -2730,7 +2746,7 @@ device_quiesce(device_t dev)
 int
 device_shutdown(device_t dev)
 {
-       if (dev->state < DS_ATTACHED)
+       if (dev->state < DS_ATTACHED || dev->state == DS_DETACHING)
                return (0);
        return (DEVICE_SHUTDOWN(dev));
 }

Modified: head/sys/sys/bus.h
==============================================================================
--- head/sys/sys/bus.h  Thu Sep  3 12:41:00 2009        (r196778)
+++ head/sys/sys/bus.h  Thu Sep  3 13:40:41 2009        (r196779)
@@ -52,8 +52,11 @@ struct u_businfo {
 typedef enum device_state {
        DS_NOTPRESENT,                  /**< @brief not probed or probe failed 
*/
        DS_ALIVE,                       /**< @brief probe succeeded */
+       DS_ATTACHING,                   /**< @brief attaching is in progress */
        DS_ATTACHED,                    /**< @brief attach method called */
-       DS_BUSY                         /**< @brief device is open */
+       DS_BUSY,                        /**< @brief device is open */
+       DS_DETACHING                    /**< @brief detaching is in progress */
+
 } device_state_t;
 
 /**
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to