From owner-svn-src-head@FreeBSD.ORG Wed Apr 11 20:57:42 2012 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 13623106566B; Wed, 11 Apr 2012 20:57:42 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id E8CD58FC14; Wed, 11 Apr 2012 20:57:41 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q3BKvfmR095443; Wed, 11 Apr 2012 20:57:41 GMT (envelope-from jhb@svn.freebsd.org) Received: (from jhb@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q3BKvfoA095440; Wed, 11 Apr 2012 20:57:41 GMT (envelope-from jhb@svn.freebsd.org) Message-Id: <201204112057.q3BKvfoA095440@svn.freebsd.org> From: John Baldwin Date: Wed, 11 Apr 2012 20:57:41 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r234152 - in head/sys: kern sys X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 11 Apr 2012 20:57:42 -0000 Author: jhb Date: Wed Apr 11 20:57:41 2012 New Revision: 234152 URL: http://svn.freebsd.org/changeset/base/234152 Log: 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(). Reviewed by: kib MFC after: 1 week 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 Wed Apr 11 20:55:21 2012 (r234151) +++ head/sys/kern/subr_bus.c Wed Apr 11 20:57:41 2012 (r234152) @@ -2472,12 +2472,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; } /** @@ -2486,14 +2487,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; } } @@ -2729,6 +2732,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); @@ -2736,11 +2740,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: head/sys/sys/bus.h ============================================================================== --- head/sys/sys/bus.h Wed Apr 11 20:55:21 2012 (r234151) +++ head/sys/sys/bus.h Wed Apr 11 20:57:41 2012 (r234152) @@ -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;