svn commit: r235523 - in stable/8/sys: i386/conf kern sys

John Baldwin jhb at FreeBSD.org
Wed May 16 21:07:20 UTC 2012


Author: jhb
Date: Wed May 16 21:07:19 2012
New Revision: 235523
URL: http://svn.freebsd.org/changeset/base/235523

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/8/sys/kern/subr_bus.c
  stable/8/sys/sys/bus.h
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/boot/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/e1000/   (props changed)
  stable/8/sys/i386/conf/XENHVM   (props changed)

Modified: stable/8/sys/kern/subr_bus.c
==============================================================================
--- stable/8/sys/kern/subr_bus.c	Wed May 16 21:06:56 2012	(r235522)
+++ stable/8/sys/kern/subr_bus.c	Wed May 16 21:07:19 2012	(r235523)
@@ -2469,12 +2469,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;
 }
 
 /**
@@ -2483,14 +2484,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;
 	}
 }
 
@@ -2726,6 +2729,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);
@@ -2733,11 +2737,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/8/sys/sys/bus.h
==============================================================================
--- stable/8/sys/sys/bus.h	Wed May 16 21:06:56 2012	(r235522)
+++ stable/8/sys/sys/bus.h	Wed May 16 21:07:19 2012	(r235523)
@@ -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;


More information about the svn-src-stable-8 mailing list