FreeBSD/sys/kern/subr_bus.c
/**
 * @brief Set the driver of a device
 *
 * @retval 0		success
 * @retval EBUSY	the device already has a driver attached
 * @retval ENOMEM	a memory allocation failure occurred
 */
@brief Set the driver of a device
@retval 0            success
@retval EBUSY        the device already has a driver attached
@retval ENOMEM       a memory allocation failure occurred
@brief Set the driver of a device @retval 0 success @retval EBUSY the device already has a driver attached @retval ENOMEM a memory allocation failure occurred
int
device_set_driver(device_t dev, driver_t *driver)
{
	if (dev->state >= DS_ATTACHED)
		return (EBUSY);
	if (dev->driver == driver)
		return (0);
	if (dev->softc && !(dev->flags & DF_EXTERNALSOFTC)) {
		free(dev->softc, M_BUS_SC);
		dev->softc = NULL;
	}
	device_set_desc(dev, NULL);
	kobj_delete((kobj_t) dev, NULL);
	dev->driver = driver;
	if (driver) {
		kobj_init((kobj_t) dev, (kobj_class_t) driver);
		if (!(dev->flags & DF_EXTERNALSOFTC) && driver->size > 0) {
			dev->softc = malloc(driver->size, M_BUS_SC,
			    M_NOWAIT | M_ZERO);
			if (!dev->softc) {
				kobj_delete((kobj_t) dev, NULL);
				kobj_init((kobj_t) dev, &null_class);
				dev->driver = NULL;
				return (ENOMEM);
			}
		}
	} else {
		kobj_init((kobj_t) dev, &null_class);
	}
	bus_data_generation_update();
	return (0);
}
int device_set_driver ( device_t dev , driver_t * driver ) { if ( dev -> state >= DS_ATTACHED ) return ( EBUSY ) ; if ( dev -> driver == driver ) return ( 0 ) ; if ( dev -> softc && ! ( dev -> flags & DF_EXTERNALSOFTC ) ) { free ( dev -> softc , M_BUS_SC ) ; dev -> softc = NULL ; } device_set_desc ( dev , NULL ) ; kobj_delete ( ( kobj_t ) dev , NULL ) ; dev -> driver = driver ; if ( driver ) { kobj_init ( ( kobj_t ) dev , ( kobj_class_t ) driver ) ; if ( ! ( dev -> flags & DF_EXTERNALSOFTC ) && driver -> size > 0 ) { dev -> softc = malloc ( driver -> size , M_BUS_SC , M_NOWAIT | M_ZERO ) ; if ( ! dev -> softc ) { kobj_delete ( ( kobj_t ) dev , NULL ) ; kobj_init ( ( kobj_t ) dev , & null_class ) ; dev -> driver = NULL ; return ( ENOMEM ) ; } } } else { kobj_init ( ( kobj_t ) dev , & null_class ) ; } bus_data_generation_update ( ) ; return ( 0 ) ; }
@brief Set the driver of a device
 @retval 0            success
 @retval EBUSY        the device already has a driver attached
 @retval ENOMEM       a memory allocation failure occurred
@brief Set the driver of a device @retval 0 success @retval EBUSY the device already has a driver attached @retval ENOMEM a memory allocation failure occurred