Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 16 May 2012 21:07:20 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r235523 - in stable/8/sys: i386/conf kern sys
Message-ID:  <201205162107.q4GL7Klq062084@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201205162107.q4GL7Klq062084>