* @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 */
| 2789 | * @retval ENOMEM a memory allocation failure occurred |
| 2790 | */ |
| 2791 | int |
| 2792 | device_set_driver(device_t dev, driver_t *driver) |
| 2793 | { |
| 2794 | int domain; |
| 2795 | struct domainset *policy; |
| 2796 | |
| 2797 | if (dev->state >= DS_ATTACHED) |
| 2798 | return (EBUSY); |
| 2799 | |
| 2800 | if (dev->driver == driver) |
| 2801 | return (0); |
| 2802 | |
| 2803 | if (dev->softc && !(dev->flags & DF_EXTERNALSOFTC)) { |
| 2804 | free(dev->softc, M_BUS_SC); |
| 2805 | dev->softc = NULL; |
| 2806 | } |
| 2807 | device_set_desc(dev, NULL); |
| 2808 | kobj_delete((kobj_t) dev, NULL); |
| 2809 | dev->driver = driver; |
| 2810 | if (driver) { |
| 2811 | kobj_init((kobj_t) dev, (kobj_class_t) driver); |
| 2812 | if (!(dev->flags & DF_EXTERNALSOFTC) && driver->size > 0) { |
| 2813 | if (bus_get_domain(dev, &domain) == 0) |
| 2814 | policy = DOMAINSET_PREF(domain); |
| 2815 | else |
| 2816 | policy = DOMAINSET_RR(); |
| 2817 | dev->softc = malloc_domainset(driver->size, M_BUS_SC, |
| 2818 | policy, M_NOWAIT | M_ZERO); |
| 2819 | if (!dev->softc) { |
| 2820 | kobj_delete((kobj_t) dev, NULL); |
| 2821 | kobj_init((kobj_t) dev, &null_class); |
| 2822 | dev->driver = NULL; |
| 2823 | return (ENOMEM); |
| 2824 | } |
| 2825 | } |
| 2826 | } else { |
| 2827 | kobj_init((kobj_t) dev, &null_class); |
| 2828 | } |
| 2829 | |
| 2830 | bus_data_generation_update(); |
| 2831 | return (0); |
| 2832 | } |
| 2833 | |
| 2834 | /** |
| 2835 | * @brief Probe a device, and return this status. |
no test coverage detected