From sacadmin Tue Mar 26 11:38:29 2002
Date: Tue, 26 Mar 2002 11:35:25 -0800 (PST)
From: Jerry Gilliam <jg@tethys.eng.sun.com>
Subject: 2002/168 Bus_Config
To: psarc@sac.eng.sun.com
Cc: devfs-dev@devi.eng.sun.com, ted.kim@Sun.COM, frits@eng,
   Larry.M.@Sun.COM, Lee.D.@Sun.COM, eric.taylor@sun.com
MIME-Version: 1.0
Content-Type: TEXT/plain; charset=us-ascii
Content-MD5: g9Tm/KfJxo2q3FBRPi3okQ==
Content-Length: 25854


I am sponsoring this fast-track for myself.
The timer expires on 4/3/2002.

This case is one of the fast-tracks under the
Devfs umbrella case, 2000/190.


#ident "@(#)bus_config.txt	1.6	02/03/13 SMI"


1.1 Introduction
----------------

This is a proposal to add new entry points to the bus_ops nexus
interfaces to permit nexus drivers to take control of the enumeration
and configuration of their children.

The bus_config interfaces provide a critical substructure for
devfs, enabling the participation by nexus drivers in the devfs model
of path-oriented, selective enumeration and configuration of 
self-identifying devices, ie devices not enumerated by firmware or
driver.conf entries.  Bus_config also serves as a vector point for
multi-path (mpxio) configuration of a virtualized device accessible
over multiple physical paths.

Implementing bus_config is optional;  a canonical implementation of
bus_config is provided by the framework.  A nexus implementing bus_config
is not required to implement bus_unconfig, and vice versa.

The bus_ops structure is versioned permitting existing driver binaries
to be supported.  Source changes are not required for recompilation.

The release binding proposed is for a minor release only.


Related cases:

	PSARC 2000/190 Devfs
	PSARC 1999/666 Nexus Child Enumeration
	PSARC 1999/667 SCSI Target Enumeration
	PSARC 1993/687 hot-plugging

This case supersedes PSARC/1999/666 and PSARC/1999/667, neither
of which has been delivered.


1.2 Interface Commitment levels
-------------------------------

	       Interface       |    Level    |     Comments
	------------------------------------------------------------

Nexus driver bus_ops:

	BUSO_REV_5             | Cons. Priv. | dev_ops busops_rev
	bus_config             | Cons. Priv. | bus_op bus_config vector
	bus_unconfig           | Cons. Priv. | bus_op bus_unconfig vector
	ddi_bus_config_op_t    | Cons. Priv. | bus config op type
	BUS_CONFIG_ONE         | Cons. Priv. | configure one device request
	BUS_CONFIG_ALL         | Cons. Priv. | configure all devices request
	BUS_CONFIG_DRIVER      | Cons. Priv. | configure devices bound to
						driver request
	BUS_UNCONFIG_ONE       | Cons. Priv. | unconfigure one device request
	BUS_UNCONFIG_ALL       | Cons. Priv. | unconfigure all devices request
	BUS_UNCONFIG_DRIVER    | Cons. Priv. | unconfigure devices bound to
						driver request

Kernel functions for nexus drivers:

	ndi_busop_bus_config   | Cons. Priv. | canonical bus_config impl.
	ndi_busop_bus_unconfig | Cons. Priv. | canonical bus_unconfig impl.

Flags for driver and kernel functions:

	NDI_DEVI_ONLINE        | Cons. Priv. | transition device to online state
	NDI_DEVI_OFFLINE       | Cons. Priv. | transition device to offline 
state
	NDI_DEVI_REMOVE        | Cons. Priv. | device to be removed from system

SCSI HBA driver transport vectors:

	tran_bus_config        | Cons. Priv. | scsi_hba_tran vector, bus_config
	tran_bus_unconfig      | Cons. Priv. | scsi_hba_tran vector, 
bus_unconfig


2.1 Nexus attach and child enumeration
--------------------------------------

As a work-around for the lack of bus_config support in the framework,
nexus drivers for buses not enumerated by firmware often drive the
enumeration of their children from their own attach(9E).

This is particularly undesirable under devfs with top-down attach.
The bus_config interfaces permit a simpler model where the
nexus attach(9E) need be nothing more than what is required
to attach an instance of the nexus.  The initiation of enumeration
and configuration of children of a nexus instance can begin
after the attach of the nexus instance itself is complete.

Enumeration can still be driven by a nexus's attach(9E), for example
fibrechannel, USB and 1394.  Such drivers enumerate asynchronously,
with synchronization variously implemented in the nexus attach(),
INITCHILD, or an empirical wait in the framework.  Under devfs,
bus_config now serves as the synchronization point of child
attach and asynchronous enumeration.


2.2 Bus_config
----------------

The bus_config operation configures the named device (BUS_CONFIG_ONE)
or all devices under the nexus (BUS_CONFIG_ALL).  The configure operation
first drives the devinfo state to DS_READY state, with the result
that the instance is fully attached.


2.3 BUS_CONFIG_ALL
------------------

Most uses of BUS_CONFIG_ALL are driven from devfs performing a
VOP_READDIR on a pathname with a /devices prefix.  Devfs uses
BUS_CONFIG_ALL to build a list of a directory's contents by configuring
and attaching each child under that nexus.

BUS_CONFIG_ALL can also be driven by the devctl interfaces to
configure a bus and by the libdevinfo interfaces to build a
snapshot of the device tree.



2.4 BUS_CONFIG_ONE
------------------

Most uses of BUS_CONFIG_ONE are driven by devfs performing a
VOP_LOOKUP of a pathname with a /devices prefix.  Devfs uses
BUS_CONFIG_ONE to resolve each component of a /devices path to
configure and attach that driver's instance.  A failure to attach
will result in ENOENT, a success leaves the device attached, in a
state that may be opened.

BUS_CONFIG_ONE is also used from within the kernel, by startup
to attach the devices required for boot and by the layered driver
interfaces to drive attach of the underlying devices.



2.5 BUS_CONFIG_DRIVER
---------------------

BUS_CONFIG_DRIVER is an optimization to support the add_drv(1M) case.


2.6 ndi_busop_bus_config()
--------------------------

This is the default bus_config implementation provided for drivers
compiled with an older revision of bus_ops or with a NULL bus_config
bus_op.

Devinfo nodes can be created from 3 sources:

	- OBP/boot system nodes
	- driver.conf enumerated nodes
	- ndi_devi_alloc(), called by the node's parent

The default implementation provided by ndi_busop_bus_config()
is sufficient for the bus_config operation for nodes enumerated by the
OBP/boot system and by driver.conf files.

A nexus would need to implement bus_config if its children are allocated
dynamically or if the nexus controls a bus that requires some period of
time for devices to initialize and begin responding to the nexus.

Once a driver has created one or more devinfo nodes via ndi_devi_alloc()
and bound those nodes to a device instance with ndi_devi_bind(),
those nodes are present in the device tree and can be properly
enumerated and configured by ndi_busop_bus_config().  (See the
pshot bus_config code below for an example.)


2.7 Bus_unconfig
----------------

The bus_unconfig operation unconfigures the named device (BUS_UNCONFIG_ONE)
or all devices under the nexus (BUS_UNCONFIG_ALL).  The bus_unconfig
operation drives the devinfo state down the device state model
from DS_READY.  The device may be offlined if requested by the
NDI_DEVI_OFFLINE flag.  The device will be left in DS_INITIALIZED
state unless removal of the device is requested by the NDI_DEVI_REMOVE
flag, in which case the device node is removed from the device tree
and all memory allocated for the node is freed.

Bus_unconfig is driven by modunload, bus_unconfig with NDI_DEVI_OFFLINE
by a devctl offline operation and bus_unconfig with NDI_DEVI_REMOVE
by DR branch removal.

The framework will detach drivers instances which aren't open, but
devfs can reattach such instances by a lookup (BUS_CONFIG_ONE) or
readdir (BUS_CONFIG_ALL).

Bus_unconfig is not driven directly by devfs but by DR and
devctl operations, or removing a driver by using rem_drv(1M).


2.8 BUS_UNCONFIG_DRIVER
------------------------

BUS_UNCONFIG_DRIVER is an optimization to support the rem_drv(1M)
and driver modunload cases.

 
2.9 SCSA HBA Transport Interfaces
---------------------------------

The bus_config and bus_unconfig busops are extended to SCSI HBA
adapter drivers through the addition to the scsi_hba_tran(9S) transport
structure of two new transport vectors, tran_bus_config and
tran_bus_unconfig,

The following new vectors have been added to scsi_hba_tran(9S):

    int (*tran_bus_config)(dev_info_t *parent, uint_t flag,
	ddi_bus_config_op_t op, void *arg, dev_info_t **childp);

    int (*tran_bus_unconfig)(dev_info_t *parent, uint_t flag,
	ddi_bus_config_op_t op, void *arg);


No versioning of the scsi_hba_tran(9S) structure is necessary
as the framework allocates the structure when the HBA driver's
attach(9E) calls scsi_hba_attach_setup(9F).

Once the transport structure is allocated, the tran_bus_config()
or tran_bus_unconfig() vectors may be initialized to point to an
HBA driver function to be called by the system to configure or
unconfigure a device or devices on the bus controlled by that instance
of the HBA driver.

SCSA will provide the default bus_config or bus_unconfig operation
for an HBA driver which leaves the tran_bus_config or tran_bus_unconfig
vector uninitialized.

As discussed in section 2.6, a SCSI HBA driver may need to
override the default tran_bus_{un}config implementation
provided by the system if its children are allocated dynamically
or if the HBA controls a bus that requires some period of
time for devices to initialize and begin responding to the nexus.


2.10 Scope of Project Delivery
------------------------------

The devfs project intends to deliver the following HBA drivers supporting
the bus_config functionality via the SCSA HBA transport vectors:

	ifp - intelligent FC processor driver for ISP2100
	sf  - Solaris Fibre Channel driver
	fp  - Fibre Channel SCSI driver


The devfs project intends to deliver the following nexus drivers
supporting bus_config:

	ohci - usba hub support (sparc)
	uhci - usba hub support (intel)

All the above drivers control a bus that requires some period of
time for devices to initialize and report their presence.  Each
driver's bus_config support has been customized to specific each
bus's unique bus reset delay requirement.

Mpxio also uses the bus_config interfaces to configure the multiple
paths to devices, with bus_config managed within the fcp module.


3.1 Future Leverage
-------------------

Devfs provides a top-down, path-based, device enumeration and
attach, where each pathname component is resolved to a device
instance identified by binding information provided by
OBP device nodes and driver.conf specifications, and with
bus_config, by nexus-specific participation.

A natural extension to devfs would be to enable an automounter-like
facility to participate in a pathname component to device instance
mapping via an external nameservice.  This could prove useful in a SAN
environment for example.

A device automounter nameservice query could be initiated by the
traversal of specific pre-configured paths such as /devices/ib or
/devices/san.  With bus_config, a nexus instance could also use the
services of a device-specific nameservice provided by, for example,
a fabric switch device.


4.1 Interface definitions
--------------------------

dev_ops entry points for nexus drivers
--------------------------------------

NAME
    bus_config - configure one or more children of this nexus
    bus_unconfig - unconfigure one or more children of this nexus

SYNOPSIS

    int bus_config(dev_info_t *parent, uint_t flags,
	ddi_bus_config_op_t op, void *arg, dev_info_t **childp);

    int bus_unconfig(dev_info_t *parent, uint_t flags,
	ddi_bus_config_op_t op, void *arg);


PARAMETERS

    parent	A pointer to the dev_info node for this nexus.

    flags	may include:

		NDI_DEVI_ONLINE: device is being brought into online state
		NDI_DEVI_OFFLINE: device is being brought into offline state
		NDI_DEVI_REMOVE: device is being removed from the system

    op		ndi_busop_bus_config:
		    BUS_CONFIG_ONE:	configure one named child
		    BUS_CONFIG_ALL:	configure all children for this nexus
		    BUS_CONFIG_DRIVER:	configure all children binding to named
					driver for this nexus

		ndi_busop_bus_unconfig:
		    BUS_UNCONFIG_ONE:	unconfigure one named child
		    BUS_UNCONFIG_ALL:	unconfigure all children for this nexus
		    BUS_UNCONFIG_DRIVER: unconfigure all children binding to
					 named driver for this nexus

    arg		BUS_CONFIG_ONE or BUS_UNCONFIG_ONE:
		    A pointer to a string containing the device's name and
		    address to configure or unconfigure.

		BUS_CONFIG_DRIVER or BUS_UNCONFIG_DRIVER:
		    The major number of the driver for which all devices
		    are to be configured or unconfigured.

		For other ops, arg is undefined.

    childp	BUS_CONFIG_ONE:
		    A pointer to a dev_info pointer in which the
		    newly configured dev_info must be returned,
		    if successful.  The child dev_info node is
		    'held' with a non-zero reference count against
		    detach to prevent races.

		For other ops, childp is undefined.


DESCRIPTION

    The bus_config and bus_unconfig bus_ops allow a nexus to
    customize the default bus_config/bus_unconfig operations
    as implemented in the I/O framework.

    Most nexus drivers can default to the canonical implementations
    of bus_config/bus_unconfig as provided by ndi_busop_bus_config
    and ndi_busop_bus_unconfig.  The most common requirement
    necessitating a nexus to implement bus_config is that the
    bus controlled by the nexus requires a bus initialization
    operation with a subsequent period of time as devices on
    that bus initialize and can be recognized and configured.
    This can be accomplished by calling ndi_busop_bus_config()
    with a timeout in units of ticks for the bus_config case.

    A driver must pass the flags argument to ndi_busop_bus_config()
    and ndi_busop_bus_unconfig() as the framework may define
    private flags which should be passed through unchanged.
    Similarly, it would be ill-advised for a driver's
    bus_{un}config to attempt a complete private implementation
    without calling ndi_busop_bus_{un}config.

    There is no requirement that a nexus implementing bus_config
    also provide a bus_unconfig implementation or vice versa.

    The nexus instance must be held by ndi_devi_enter() for the
    duration of the bus_config or bus_unconfig operation, to
    serialize changes to that instance's children.


RETURN VALUES

    NDI_SUCCESS
		The requested configure or unconfigure operation
		was successful.  In the case of BUS_CONFIG_ONE,
		a pointer to the attached child dev_info node is
		returned in *childp.

    NDI_FAILURE
		The requested configure or unconfigure operation
		was not successful.

CONTEXT

    bus_config and bus_unconfig are called from kernel or user context.




Kernel functions for Nexus Drivers
----------------------------------

NAME
    ndi_busop_bus_config - configure one or more children of this nexus
    ndi_busop_bus_unconfig - unconfigure one or more children of this nexus


SYNOPSIS

    int ndi_busop_bus_config(dev_info_t *parent, uint_t flags,
	ddi_bus_config_op_t op, void *arg, dev_info_t **childp, clock_t 
timeout);

    int ndi_busop_bus_unconfig(dev_info_t *parent, uint_t flags,
	ddi_bus_config_op_t op, void *arg);


PARAMETERS

    parent	A pointer to the dev_info node for this nexus.

    flags	may include:

		NDI_DEVI_ONLINE: device is being brought into online state
		NDI_DEVI_OFFLINE: device is being brought into offline state
		NDI_DEVI_REMOVE: device is being removed from the system

    op		ndi_busop_bus_config:
		    BUS_CONFIG_ONE:	configure one named child
		    BUS_CONFIG_ALL:	configure all children for this nexus
		    BUS_CONFIG_DRIVER:	configure all children binding to named
					driver for this nexus

		ndi_busop_bus_unconfig:
		    BUS_UNCONFIG_ONE:	unconfigure one named child
		    BUS_UNCONFIG_ALL:	unconfigure all children for this nexus
		    BUS_UNCONFIG_DRIVER: unconfigure all children binding to
					 named driver for this nexus

    arg		BUS_CONFIG_ONE or BUS_UNCONFIG_ONE:
		    A pointer to a string containing the device's name and
		    address to configure or unconfigure.

		BUS_CONFIG_DRIVER or BUS_UNCONFIG_DRIVER:
		    The major number of the driver for which all devices
		    are to be configured or unconfigured.

		For other ops, arg must be NULL.


    childp	BUS_CONFIG_ONE:
		    A pointer to a dev_info pointer in which the
		    newly configured dev_info must be returned,
		    if successful.

		For other ops, childp must be NULL.

    timeout	The reset delay time specified for the bus in units
		of clock ticks.  If no bus reset time required, zero.


DESCRIPTION

    BUS_CONFIG_ONE:
    BUS_UNCONFIG_ONE:
	arg is a pointer to a string containing the device name
	and address to be (un)configured.  The device name is in the
	form "name@addr".  Each nexus is responsible for its own
	bus address name space.

    BUS_CONFIG_ALL:
    BUS_UNCONFIG_ALL:
	This is a request to (un)configure all children under
	this nexus.

    BUS_CONFIG_DRIVER:
    BUS_UNCONFIG_DRIVER:
	arg is the major number of the driver for which all children
	under this nexus are to be (un)configured.  This is an
	optimization to handle adding a new driver or removing an
	existing driver via add_drv(1M)/rem_drv(1M).

    A timeout may be specified for ndi_busop_bus_config() if the
    bus controlled by this nexus requires a bus initialization
    operation with a subsequent period of time as devices on
    that bus initialize and can be recognized and configured.


RETURN VALUES

    NDI_SUCCESS
		The requested (un)configure operation was successful.
		In the case of BUS_CONFIG_ONE, a pointer to the attached
		child dev_info node is returned in *childp.

    NDI_FAILURE
		The requested (un)configure operation was not successful.
		

CONTEXT

    ndi_busop_bus_config and ndi_busop_bus_unconfig must be called
    from kernel or user context.


Driver Entry Points for SCSI HBA Drivers
----------------------------------------

NAME
    tran_bus_config - configure one or more devices on this adapter
    tran_bus_unconfig - unconfigure one or more devices on this adapter

SYNOPSIS

    int xx_tran_bus_config(dev_info_t *parent, uint_t flags,
	ddi_bus_config_op_t op, void *arg, dev_info_t **childp);

    int xx_tran_bus_unconfig(dev_info_t *parent, uint_t flags,
	ddi_bus_config_op_t op, void *arg);


PARAMETERS

    parent	A pointer to the dev_info node for this adapter.

    flags	may include:

		NDI_DEVI_ONLINE: device is being brought into online state
		NDI_DEVI_OFFLINE: device is being brought into offline state
		NDI_DEVI_REMOVE: device is being removed from the system

    op		tran_bus_config:
		    BUS_CONFIG_ONE:	configure one named child on this 
adapter
		    BUS_CONFIG_ALL:	configure all children for this adapter
		    BUS_CONFIG_DRIVER:	configure all children binding to named
					driver for this adapter

		tran_bus_unconfig:
		    BUS_UNCONFIG_ONE:	unconfigure one named child
		    BUS_UNCONFIG_ALL:	unconfigure all children for this 
adapter
		    BUS_UNCONFIG_DRIVER: unconfigure all children binding to
					 named driver for this adapter

    arg	        BUS_CONFIG_ONE or BUS_UNCONFIG_ONE:
		    A pointer to a string containing the device's name and
		    address to configure or unconfigure.

		BUS_CONFIG_DRIVER or BUS_UNCONFIG_DRIVER:
		    The major number of the driver for which all devices
		    are to be configured or unconfigured.

		For other ops, arg is undefined.

    childp	BUS_CONFIG_ONE:
		    A pointer to a dev_info pointer in which the
		    newly configured dev_info must be returned,
		    if successful.  The child dev_info node is
		    'held' with a non-zero reference count against
		    detach to prevent races.

		For other ops, childp is undefined.


DESCRIPTION

    The tran_bus_config() or tran_bus_unconfig() vectors in the
    scsi_hba_tran(9S)  structure  may  be initialized during the
    HBA driver's attach(9E) to point to an HBA driver function to
    be called by the  system  to configure or unconfigure a device
    or devices on the bus controlled by that instance of the HBA driver.

    The tran_bus_config() and tran_bus_unconfig() vectors allow an adapter
    to customize the default bus_config/bus_unconfig operations
    as provided by SCSA.

    Most adapter drivers may default to the canonical implementations
    of bus_config/bus_unconfig provided by SCSA, and need not implement
    tran_bus_config() or tran_bus_unconfig().  The most common requirement
     necessitating a adapter to override the SCSA default implementation
    is that the bus controlled by the adapter requires a bus initialization
    operation with a subsequent period of time as devices on that bus
    initialize and can be recognized and configured.  This can be accomplished
    by calling ndi_busop_bus_config() with a timeout in units of ticks for
    the bus_config case.

    A driver must pass the flags argument to ndi_busop_bus_config() and
    ndi_busop_bus_unconfig() as the framework may define private flags
    which should be passed through unchanged.  Similarly, it would be
    ill-advised for a driver's tran_bus_{un}config() to attempt a
    complete private implementation without calling ndi_busop_bus_{un}config.

    There is no requirement that a adapter implementing tran_bus_config()
    also provide a tran_bus_unconfig() implementation or vice versa.

    The adapter instance must be held by ndi_devi_enter() for the
    duration of the tran_bus_{un}config() operation, to serialize
    changes to that instance's children.


RETURN VALUES

    NDI_SUCCESS
		The requested configure or unconfigure operation
		was successful.  In the case of BUS_CONFIG_ONE,
		a pointer to the attached child dev_info node is
		returned in *childp.

    NDI_FAILURE
		The requested configure or unconfigure operation
		was not successful.

CONTEXT

    tran_bus_config and tran_bus_unconfig are called from kernel
    or user context.



5.1  An example implementation of bus_config
---------------------------------------------

Here is an example of a bus_config implementation in a test driver.
This driver can be used to exercise the i/o framework together with
devfs by configuring an arbitrarily complex device tree.

The pshot driver is rooted at /devices/pshot.  The following commands
illustrate the operation of devfs together with pshot's bus_config.
The first command demonstrates that, like the magician showing there's
nothing up his sleeve, /devices/pshot is empty.  The second command
conjures up a branch of pshot nodes.  Note that pshot's bus_config is
called sequentially by devfs for each node, as part of the pathname
resolution, and that each pshot node is fully configured and
attached before that node's bus_config is called to configure the
next child down the tree.  The final result is a "disk" node configured
at the bottom of the named hierarchy of pshot nodes.

	#
	# ls /devices/pshot
	#
	# ls -ld /devices/pshot/pshot@0/pshot@1
	drwxr-xr-x   2 root     sys          512 Feb  6 15:10
		/devices/pshot/pshot@0/pshot@1
	

No bus_unconfig example is included as the canonical implementation
suffices for pshot.

/*
 * Bus_ops for pshot driver with bus_config
 */
static struct bus_ops pshot_bus_ops = {
        BUSO_REV,                       /* busops_rev */
        nullbusmap,                     /* bus_map */
	...
        pshot_bus_config,               /* bus_config */
        pshot_bus_unconfig              /* bus_unconfig */
};


/*
 * Example bus_config implementation for the pshot test driver
 */
static int
pshot_bus_config(dev_info_t *parent, uint_t flags,
    ddi_bus_config_op_t op, void *arg, dev_info_t **childp)
{
	int	rval;
	int	circ;
	char	*devname;
	char	*cname;
	char	*caddr;	

	/*
	 * Hold the nexus across the bus_config
	 */
	ndi_devi_enter(parent, &circ);

	switch (op) {
	case BUS_CONFIG_ONE:
		/*
		 * Configure a device named by 'arg' under this parent.
		 * The device name is in the form "name@addr".  Since
		 * we cannot modify the 'arg' string in place to extract
		 * the name/address, make a copy of it.
		 */
		devnamelen = strlen((char *)arg) + 1;
		devname = kmem_alloc(devnamelen, KM_SLEEP);
		(void) strncpy(devname, (char *)arg, devnamelen);
		i_ddi_parse_name(devname, &cname, &caddr, NULL);

		/*
		 * look up child, it may already have been configured
		 */
		child = ndi_devi_findchild(parent, cname, caddr);
		if (child) {
			rval = NDI_SUCCESS;
		} else {
			/*
			 * Child does not exist.  Allocate a devinfo
			 * node, assign the child's bus address in
			 * the parent's address space and bind the
			 * newly created devinfo node to the driver.
			 * After the new devinfo node is linked as a
			 * child by ndi_devi_bind_driver(), the framework
			 * default bus_config implementation will be able
			 * to find the devinfo node and complete the
			 * bus_config operation.
			 */
			ndi_devi_alloc_sleep(parent, cname,
				DEVI_PSEUDO_NODEID, &child);

			if (ndi_prop_update_string(DDI_DEV_T_NONE, child,
		    	    "bus-addr", caddr) != DDI_PROP_SUCCESS) {
				rval = NDI_FAILURE;
			} else {
				if (ndi_devi_bind_driver(child, 0) !=
				    NDI_SUCCESS) {
					rval = NDI_FAILURE;
				}
			}

			if (rval == NDI_FAILURE) {
				(void) ndi_devi_free(child);
			}
		}

		kmem_free(devname, devnamelen);
		break;

	case BUS_CONFIG_DRIVER:
		/*
		 * Configure all devices under this parent which
		 * bind to the named driver 'arg'.  This is
		 * a no-op for this driver but most drivers
		 * can just let the framework handle this case.
		 */
		rval = NDI_SUCCESS;
		break;

	case BUS_CONFIG_ALL:
		/*
		 * Configure all devices under this parent.
		 * The framework will rediscover and attach
		 * all devinfo nodes created by this driver
		 * to date.
		 */
		rval = NDI_SUCCESS;
		break;

	default:
		rval = NDI_FAILURE;
		break;
	}

	/*
	 * The default framework implementation can take over
	 * if there have been no errors so far.
	 */
	if (rval == NDI_SUCCESS)
		rval = ndi_busop_bus_config(parent, flags, op, arg, childp, 0);

	ndi_devi_exit(parent, circ);

	return (rval);
}


From sacadmin Tue Mar 26 16:35:57 2002
X-Authentication-Warning: opulent.Central.Sun.COM: lD. set sender to Lee.D.@Sun.COM using -f
From: Lee D. <Lee.D.@Sun.COM>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Date: Tue, 26 Mar 2002 17:35:10 -0700
To: Jerry Gilliam <jg@tethys.eng.sun.com>
Cc: psarc@sac.eng.sun.com, devfs-dev@devi.eng.sun.com, ted.kim@Sun.COM,
   frits@eng.sun.com, Larry.M.@Sun.COM, eric.taylor@Sun.COM
Subject: Re: 2002/168 Bus_Config
X-Disclaimer: My opinions are so off the wall that nobody claims them
Content-Length: 2963

Hi Jerry:

See my comments, prefixed by "ld> " ...

----------------------------------------------------------------
I am sponsoring this fast-track for myself.
The timer expires on 4/3/2002.

This case is one of the fast-tracks under the
Devfs umbrella case, 2000/190.


#ident "@(#)bus_config.txt	1.6	02/03/13 SMI"


1.1 Introduction
----------------

This is a proposal to add new entry points to the bus_ops nexus
interfaces to permit nexus drivers to take control of the enumeration
and configuration of their children.

...

2.3 BUS_CONFIG_ALL
------------------

Most uses of BUS_CONFIG_ALL are driven from devfs performing a
VOP_READDIR on a pathname with a /devices prefix.  Devfs uses
BUS_CONFIG_ALL to build a list of a directory's contents by configuring
and attaching each child under that nexus.

BUS_CONFIG_ALL can also be driven by the devctl interfaces to
configure a bus and by the libdevinfo interfaces to build a
snapshot of the device tree.

...

----------------------------------------------------------------

ld> So does this mean that an "ls" in some /dev (or /devices)
ld> directory will cause all devices listed in that directory to be
ld> configured?

ld> Also, why would getting a snapshot using libdevinfo cause all
ld> devices to be configured?

ld> What will this mean, for example, for a Fibre Channel fabric where
ld> we have perhaps hundreds of devices?

----------------------------------------------------------------
...

2.9 SCSA HBA Transport Interfaces
---------------------------------
...

SCSA will provide the default bus_config or bus_unconfig operation
for an HBA driver which leaves the tran_bus_config or tran_bus_unconfig
vector uninitialized.

...
----------------------------------------------------------------

ld> side question: have you prototyped your SCSA changes yet? (I'd
ld> like to look at them when you do)

----------------------------------------------------------------
...

2.10 Scope of Project Delivery
------------------------------

The devfs project intends to deliver the following HBA drivers supporting
the bus_config functionality via the SCSA HBA transport vectors:

	ifp - intelligent FC processor driver for ISP2100
	sf  - Solaris Fibre Channel driver
	fp  - Fibre Channel SCSI driver


The devfs project intends to deliver the following nexus drivers
supporting bus_config:

	ohci - usba hub support (sparc)
	uhci - usba hub support (intel)
...
----------------------------------------------------------------

ld> will this delivery be part of this fast-track, or a future case?

----------------------------------------------------------------
...
Mpxio also uses the bus_config interfaces to configure the multiple
paths to devices, with bus_config managed within the fcp module.
...
----------------------------------------------------------------

So who is making the mpxio changes, and if you, as part of this
fast-track or later?
-- 
-LeeD
			"Try not to crash." -- my wife

From sacadmin Wed Mar 27 09:23:10 2002
Date: Wed, 27 Mar 2002 09:20:05 -0800 (PST)
From: Jerry Gilliam <jg@tethys.eng.sun.com>
Subject: Re: 2002/168 Bus_Config
To: Lee.D.@Sun.COM
Cc: psarc@sac.eng.sun.com, devfs-dev@devi.eng.sun.com, ted.kim@Sun.COM,
   frits@eng.sun.com, Larry.M.@Sun.COM, eric.taylor@Sun.COM
MIME-Version: 1.0
Content-Type: TEXT/plain; charset=us-ascii
Content-MD5: yXfVjoDkeIltoq6jPu3Wog==
Content-Length: 3370


From: Lee D. <Lee.D.@Sun.COM>

> 
> ld> So does this mean that an "ls" in some /dev (or /devices)
> ld> directory will cause all devices listed in that directory to be
> ld> configured?
>

Yes, that is what it means, within /devices only.  Equivalently,
an open or stat of a /dev link will cause the associated /device
node to be configured.


> 
> ld> Also, why would getting a snapshot using libdevinfo cause all
> ld> devices to be configured?
> 

Generating a snapshot of the full device is something that libdevinfo
has never guaranteed but generally most consumers of libdevinfo
have assumed that's the case.  Devfs could certainly make it more
obvious that not all devices in the system, only enumerated and
attached devices, are being returned in the snapshot.  From the
perspective of an app wishing to explore all devices attached
to the machine, not returning a snapshot reflecting the entire
device tree is broken.  Anyway, the relevance to this case is that
use of the devinfo DINFOFORCE flag to build a snapshot for the entire
device tree is, under devfs, implemented with a tie-in to bus_config,
a BUS_CONFIG_ALL performed down the entire device tree.  After all,
we can't very well put into the snapshot what isn't in the device
tree.  ;)


> ld> What will this mean, for example, for a Fibre Channel fabric where
> ld> we have perhaps hundreds of devices?
> 

Basically, the driver is in charge through bus_config.  The
general expectation we have is that BUS_CONFIG_ONE will of
course enumerate and attach the requested device, but that
BUS_CONFIG_ALL (the readdir case) may only result in devices
previously enumerated and attached through BUS_CONFIG_ONE
to be re-enumerated and attached.  Thus a BUS_CONFIG_ALL
could only explore a subset of the full device space provided
through a fabric.  Or, if the number of devices provided
through a fabric is bounded to some reasonable maximum
with some finite explorable address space, the driver could
simply enumerate and attach all devices.



> 
> ld> side question: have you prototyped your SCSA changes yet? (I'd
> ld> like to look at them when you do)
> 

Yes, the project gate is in /net/missoula.eng/export/on10-devfs-gate.
bfu archives, cscope files are available.  Also see http://missoula.eng.


> 
> 2.10 Scope of Project Delivery
> ------------------------------
> 
> The devfs project intends to deliver the following HBA drivers supporting
> the bus_config functionality via the SCSA HBA transport vectors:
> 
> 	ifp - intelligent FC processor driver for ISP2100
> 	sf  - Solaris Fibre Channel driver
> 	fp  - Fibre Channel SCSI driver
> 
> 
> The devfs project intends to deliver the following nexus drivers
> supporting bus_config:
> 
> 	ohci - usba hub support (sparc)
> 	uhci - usba hub support (intel)
> ...
> ----------------------------------------------------------------
> 
> ld> will this delivery be part of this fast-track, or a future case?
> 

The devfs project intends to deliver everything discussed in this
case (with the exception of section 3.1 Future Leverage of course).


> 
> So who is making the mpxio changes, and if you, as part of this
> fast-track or later?
>

We've already done the work, no additional fast-track is
necessary as it is nothing more than an implementation of the
interfaces in this proposal.

Hope this help answer your questions!


-jg


From sacadmin Wed Mar 27 10:35:59 2002
Date: Wed, 27 Mar 2002 11:36:08 -0700
From: Larry M. <Larry.M.@Sun.COM>
X-Accept-Language: en
MIME-Version: 1.0
To: Jerry Gilliam <jg@tethys.eng.sun.com>
CC: psarc@sac.eng.sun.com, devfs-dev@devi.eng.sun.com, ted.kim@Sun.COM,
   frits@eng.sun.com, Lee.D.@Sun.COM, eric.taylor@Sun.COM
Subject: Re: 2002/168 Bus_Config
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Length: 994

Jerry,
Here's a couple comments.
-Larry

Jerry Gilliam wrote:

>
> 2.10 Scope of Project Delivery
> ------------------------------
>
> The devfs project intends to deliver the following HBA drivers supporting
> the bus_config functionality via the SCSA HBA transport vectors:

This is 'tran_bus_config' for SCSI HBAs.

>
>
>         ifp - intelligent FC processor driver for ISP2100
>         sf  - Solaris Fibre Channel driver
>         fp  - Fibre Channel SCSI driver

It looks like the bus_config code was added to fcp and not fp. This makes sense to
me (FCP = FC SCSI ULP &  SCSA HBA).
>$ pwd
>/net/missoula.eng/export/on10-devfs-gate/usr/src/uts/sun/io/fibre-channel/ulp
>$ cd ..
>$ grep 'bus_config' */*.c
>ulp/fcp.c:static int ssfcp_scsi_bus_config(dev_info_t *parent, uint_t flag,
>ulp/fcp.c:    ddi_bus_config_op_t op, void *arg, dev_info_t **childp);
>ulp/fcp.c:    ddi_bus_config_op_t op, void *arg);
...
>ulp/fcp.c:      tran->tran_bus_config           = ssfcp_scsi_bus_config;





From sacadmin Wed Mar 27 12:44:12 2002
Date: Wed, 27 Mar 2002 12:41:08 -0800 (PST)
From: Jerry Gilliam <jg@tethys.eng.sun.com>
Subject: Re: 2002/168 Bus_Config
To: Larry.M.@Sun.COM
Cc: psarc@sac.eng.sun.com, devfs-dev@devi.eng.sun.com, ted.kim@Sun.COM,
   frits@eng.sun.com, Lee.D.@Sun.COM, eric.taylor@Sun.COM
MIME-Version: 1.0
Content-Type: TEXT/plain; charset=us-ascii
Content-MD5: hl0kHT3aiRYZ4fTDxOrZ2A==
Content-Length: 1320



> 
> >
> > 2.10 Scope of Project Delivery
> > ------------------------------
> >
> > The devfs project intends to deliver the following HBA drivers supporting
> > the bus_config functionality via the SCSA HBA transport vectors:
> 
> This is 'tran_bus_config' for SCSI HBAs.
>

Yes, that's right.  I was using the term 'bus_config' in the generic
sense, meaning that the devfs project intends to convert these drivers
to support the set of interfaces described in this proposal, as
appropriate per driver.


> >
> >
> >         ifp - intelligent FC processor driver for ISP2100
> >         sf  - Solaris Fibre Channel driver
> >         fp  - Fibre Channel SCSI driver
> 
> It looks like the bus_config code was added to fcp and not fp. This makes 
sense to
> me (FCP = FC SCSI ULP &  SCSA HBA).
> >$ pwd
> >/net/missoula.eng/export/on10-devfs-gate/usr/src/uts/sun/io/fibre-channel/ulp
> >$ cd ..
> >$ grep 'bus_config' */*.c
> >ulp/fcp.c:static int ssfcp_scsi_bus_config(dev_info_t *parent, uint_t flag,
> >ulp/fcp.c:    ddi_bus_config_op_t op, void *arg, dev_info_t **childp);
> >ulp/fcp.c:    ddi_bus_config_op_t op, void *arg);
> ...
> >ulp/fcp.c:      tran->tran_bus_config           = ssfcp_scsi_bus_config;
> 

Yes, you're right, it actually is the fcp driver that is modified
to support tran_bus_config.


-jg


From sacadmin Wed Mar 27 13:07:30 2002
Date: Wed, 27 Mar 2002 13:05:32 -0800 (PST)
From: Shudong Z. <sZ.@billybob.eng.sun.com>
Subject: Re: 2002/168 Bus_Config
To: Larry.M.@sun.com, jg@tethys.eng.sun.com
Cc: psarc@sac.eng.sun.com, devfs-dev@devi.eng.sun.com, ted.kim@sun.com,
   frits@eng.sun.com, Lee.D.@sun.com, eric.taylor@sun.com
MIME-Version: 1.0
Content-Type: TEXT/plain; charset=us-ascii
Content-MD5: hXN/Y7gRKrSj0P1gm3MmVw==
Content-Length: 594


> > >
> > >         ifp - intelligent FC processor driver for ISP2100
> > >         sf  - Solaris Fibre Channel driver
> > >         fp  - Fibre Channel SCSI driver
> > 
> > It looks like the bus_config code was added to fcp and not fp. This makes 
> sense to
> > me (FCP = FC SCSI ULP &  SCSA HBA).
> 
> Yes, you're right, it actually is the fcp driver that is modified
> to support tran_bus_config.
> 

However, the bus_ops belong to the fp driver, not the fcp driver.
The latter is a pseudo leaf driver. It's like scsi HBA driver's
bus_ops is implemented in the misc/scsi module.

Shudong


From sacadmin Wed Apr  3 11:03:13 2002
Date: Wed, 3 Apr 2002 11:00:00 -0800 (PST)
From: Jerry Gilliam <jg@tethys.eng.sun.com>
Subject: Re: 2002/168 Bus_Config
To: psarc@sac.eng.sun.com, devfs-dev@devi.eng.sun.com
Cc: ted.kim@sun.com, frits@eng.sun.com, Lee.D.@sun.com,
   eric.taylor@sun.com
MIME-Version: 1.0
Content-Type: TEXT/plain; charset=us-ascii
Content-MD5: b0aVFmj6hUCt7XUiH0guSg==
Content-Length: 107


This case was approved during ARC business today and I've
updated the case files accordingly.


thx,
-jg


