FreeBSD/sys/kern/subr_bus.c
/**
 * @brief Register that a device driver has been deleted from a devclass
 *
 * Register that a device driver has been removed from a devclass.
 * This is called by devclass_delete_driver to accomplish the
 * recursive notification of all the children classes of busclass, as
 * well as busclass.  Each layer will attempt to detach the driver
 * from any devices that are children of the bus's devclass.  The function
 * will return an error if a device fails to detach.
 *
 * We do a full search here of the devclass list at each iteration
 * level to save storing children-lists in the devclass structure.  If
 * we ever move beyond a few dozen devices doing this, we may need to
 * reevaluate...
 *
 * @param busclass	the devclass of the parent bus
 * @param dc		the devclass of the driver being deleted
 * @param driver	the driver being deleted
 */
@brief Register that a device driver has been deleted from a devclass
Register that a device driver has been removed from a devclass.
This is called by devclass_delete_driver to accomplish the
recursive notification of all the children classes of busclass, as
well as busclass.  Each layer will attempt to detach the driver
from any devices that are children of the bus's devclass.  The function
will return an error if a device fails to detach.

We do a full search here of the devclass list at each iteration
level to save storing children-lists in the devclass structure.  If
we ever move beyond a few dozen devices doing this, we may need to
reevaluate

@param busclass      the devclass of the parent bus
@param dc            the devclass of the driver being deleted
@param driver        the driver being deleted
@brief Register that a device driver has been deleted from a devclass Register that a device driver has been removed from a devclass . This is called by devclass_delete_driver to accomplish the recursive notification of all the children classes of busclass as well as busclass . Each layer will attempt to detach the driver from any devices that are children of the bus ' s devclass . The function will return an error if a device fails to detach . We do a full search here of the devclass list at each iteration level to save storing children - lists in the devclass structure . If we ever move beyond a few dozen devices doing this we may need to reevaluate @param busclass the devclass of the parent bus @param dc the devclass of the driver being deleted @param driver the driver being deleted
static int
devclass_driver_deleted(devclass_t busclass, devclass_t dc, driver_t *driver)
{
	devclass_t parent;
	device_t dev;
	int error, i;
	for (i = 0; i < dc->maxunit; i++) {
		if (dc->devices[i]) {
			dev = dc->devices[i];
			if (dev->driver == driver && dev->parent &&
			    dev->parent->devclass == busclass) {
				if ((error = device_detach(dev)) != 0)
					return (error);
				BUS_PROBE_NOMATCH(dev->parent, dev);
				devnomatch(dev);
				dev->flags |= DF_DONENOMATCH;
			}
		}
	}
	if (!(busclass->flags & DC_HAS_CHILDREN))
		return (0);
	parent = busclass;
	TAILQ_FOREACH(busclass, &devclasses, link) {
		if (busclass->parent == parent) {
			error = devclass_driver_deleted(busclass, dc, driver);
			if (error)
				return (error);
		}
	}
	return (0);
}
static int devclass_driver_deleted ( devclass_t busclass , devclass_t dc , driver_t * driver ) { devclass_t parent ; device_t dev ; int error , i ; for ( i = 0 ; i < dc -> maxunit ; i ++ ) { if ( dc -> devices [ i ] ) { dev = dc -> devices [ i ] ; if ( dev -> driver == driver && dev -> parent && dev -> parent -> devclass == busclass ) { if ( ( error = device_detach ( dev ) ) != 0 ) return ( error ) ; BUS_PROBE_NOMATCH ( dev -> parent , dev ) ; devnomatch ( dev ) ; dev -> flags |= DF_DONENOMATCH ; } } } if ( ! ( busclass -> flags & DC_HAS_CHILDREN ) ) return ( 0 ) ; parent = busclass ; TAILQ_FOREACH ( busclass , & devclasses , link ) { if ( busclass -> parent == parent ) { error = devclass_driver_deleted ( busclass , dc , driver ) ; if ( error ) return ( error ) ; } } return ( 0 ) ; }
@brief Register that a device driver has been deleted from a devclass
 Register that a device driver has been removed from a devclass.
@brief Register that a device driver has been deleted from a devclass Register that a device driver has been removed from a devclass .
/*
	 * Disassociate from any devices.  We iterate through all the
	 * devices in the devclass of the driver and detach any which are
	 * using the driver and which have a parent in the devclass which
	 * we are deleting from.
	 *
	 * Note that since a driver can be in multiple devclasses, we
	 * should not detach devices which are not children of devices in
	 * the affected devclass.
	 */ /*
	 * Walk through the children classes.  Since we only keep a
	 * single parent pointer around, we walk the entire list of
	 * devclasses looking for children.  We set the
	 * DC_HAS_CHILDREN flag when a child devclass is created on
	 * the parent, so we only walk the list for those devclasses
	 * that have children.
	 */