Author: jhb
Date: Wed May 16 21:06:56 2012
New Revision: 235522
URL: http://svn.freebsd.org/changeset/base/235522

Log:
  MFC 234152:
  Allow device_busy() and device_unbusy() to be invoked while a device is
  being attached.  This is implemented by adding a new DS_ATTACHING state
  while a device's DEVICE_ATTACH() method is being invoked.  A driver is
  required to not fail an attach of a busy device.  The device's state will
  be promoted to DS_BUSY rather than DS_ACTIVE() if the device was marked
  busy during DEVICE_ATTACH()

Modified:
  stable/9/sys/kern/subr_bus.c
  stable/9/sys/sys/bus.h
Directory Properties:
  stable/9/sys/   (props changed)
  stable/9/sys/amd64/include/xen/   (props changed)
  stable/9/sys/boot/   (props changed)
  stable/9/sys/boot/i386/efi/   (props changed)
  stable/9/sys/boot/ia64/efi/   (props changed)
  stable/9/sys/boot/ia64/ski/   (props changed)
  stable/9/sys/boot/powerpc/boot1.chrp/   (props changed)
  stable/9/sys/boot/powerpc/ofw/   (props changed)
  stable/9/sys/cddl/contrib/opensolaris/   (props changed)
  stable/9/sys/conf/   (props changed)
  stable/9/sys/contrib/dev/acpica/   (props changed)
  stable/9/sys/contrib/octeon-sdk/   (props changed)
  stable/9/sys/contrib/pf/   (props changed)
  stable/9/sys/contrib/x86emu/   (props changed)
  stable/9/sys/fs/   (props changed)
  stable/9/sys/fs/ntfs/   (props changed)
  stable/9/sys/i386/conf/XENHVM   (props changed)
  stable/9/sys/kern/subr_witness.c   (props changed)

Modified: stable/9/sys/kern/subr_bus.c
==============================================================================
--- stable/9/sys/kern/subr_bus.c        Wed May 16 20:33:29 2012        
(r235521)
+++ stable/9/sys/kern/subr_bus.c        Wed May 16 21:06:56 2012        
(r235522)
@@ -2466,12 +2466,13 @@ device_disable(device_t dev)
 void
 device_busy(device_t dev)
 {
-       if (dev->state < DS_ATTACHED)
+       if (dev->state < DS_ATTACHING)
                panic("device_busy: called for unattached device");
        if (dev->busy == 0 && dev->parent)
                device_busy(dev->parent);
        dev->busy++;
-       dev->state = DS_BUSY;
+       if (dev->state == DS_ATTACHED)
+               dev->state = DS_BUSY;
 }
 
 /**
@@ -2480,14 +2481,16 @@ device_busy(device_t dev)
 void
 device_unbusy(device_t dev)
 {
-       if (dev->state != DS_BUSY)
+       if (dev->busy != 0 && dev->state != DS_BUSY &&
+           dev->state != DS_ATTACHING)
                panic("device_unbusy: called for non-busy device %s",
                    device_get_nameunit(dev));
        dev->busy--;
        if (dev->busy == 0) {
                if (dev->parent)
                        device_unbusy(dev->parent);
-               dev->state = DS_ATTACHED;
+               if (dev->state == DS_BUSY)
+                       dev->state = DS_ATTACHED;
        }
 }
 
@@ -2723,6 +2726,7 @@ device_attach(device_t dev)
        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) {
                printf("device_attach: %s%d attach returned %d\n",
                    dev->driver->name, dev->unit, error);
@@ -2730,11 +2734,15 @@ device_attach(device_t dev)
                        devclass_delete_device(dev->devclass, dev);
                (void)device_set_driver(dev, NULL);
                device_sysctl_fini(dev);
+               KASSERT(dev->busy == 0, ("attach failed but busy"));
                dev->state = DS_NOTPRESENT;
                return (error);
        }
        device_sysctl_update(dev);
-       dev->state = DS_ATTACHED;
+       if (dev->busy)
+               dev->state = DS_BUSY;
+       else
+               dev->state = DS_ATTACHED;
        dev->flags &= ~DF_DONENOMATCH;
        devadded(dev);
        return (0);

Modified: stable/9/sys/sys/bus.h
==============================================================================
--- stable/9/sys/sys/bus.h      Wed May 16 20:33:29 2012        (r235521)
+++ stable/9/sys/sys/bus.h      Wed May 16 21:06:56 2012        (r235522)
@@ -52,6 +52,7 @@ struct u_businfo {
 typedef enum device_state {
        DS_NOTPRESENT = 10,             /**< @brief not probed or probe failed 
*/
        DS_ALIVE = 20,                  /**< @brief probe succeeded */
+       DS_ATTACHING = 25,              /**< @brief currently attaching */
        DS_ATTACHED = 30,               /**< @brief attach method called */
        DS_BUSY = 40                    /**< @brief device is open */
 } device_state_t;
_______________________________________________
svn-src-stable-9@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-stable-9
To unsubscribe, send any mail to "svn-src-stable-9-unsubscr...@freebsd.org"

Reply via email to