File indexing completed on 2025-05-11 08:24:16
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 #include <stdlib.h>
0030
0031 #include <drvmgr/drvmgr.h>
0032 #include <drvmgr/drvmgr_list.h>
0033 #include "drvmgr_internal.h"
0034
0035
0036
0037
0038
0039
0040 int drvmgr_children_unregister(struct drvmgr_bus *bus)
0041 {
0042 int err;
0043
0044 while (bus->children != NULL) {
0045 err = drvmgr_dev_unregister(bus->children);
0046 if (err != DRVMGR_OK) {
0047
0048 bus->children->error = err;
0049 return err;
0050 }
0051 }
0052
0053 return DRVMGR_OK;
0054 }
0055
0056
0057
0058
0059
0060
0061
0062 int drvmgr_bus_unregister(struct drvmgr_bus *bus)
0063 {
0064 struct drvmgr *mgr = &drvmgr;
0065 struct drvmgr_list *list;
0066
0067 if (bus->ops->remove == NULL)
0068 return DRVMGR_ENOSYS;
0069
0070
0071 bus->error = bus->ops->remove(bus);
0072 if (bus->error != DRVMGR_OK)
0073 return bus->error;
0074
0075 if (bus->children != NULL)
0076 return DRVMGR_FAIL;
0077
0078 bus->dev->bus = NULL;
0079
0080 DRVMGR_LOCK_WRITE();
0081
0082
0083 if (bus->state & BUS_STATE_LIST_INACTIVE)
0084 list = &mgr->buses_inactive;
0085 else
0086 list = &mgr->buses[bus->level];
0087 drvmgr_list_remove(list, bus);
0088
0089 DRVMGR_UNLOCK();
0090
0091
0092 free(bus);
0093
0094 return DRVMGR_OK;
0095 }
0096
0097
0098 int drvmgr_dev_drv_separate(struct drvmgr_dev *dev)
0099 {
0100 struct drvmgr *mgr = &drvmgr;
0101 struct drvmgr_dev *subdev, **pprev;
0102 int rc;
0103
0104
0105
0106
0107
0108 if (dev->bus) {
0109 rc = drvmgr_bus_unregister(dev->bus);
0110 if (rc != DRVMGR_OK)
0111 return rc;
0112 }
0113
0114 if (dev->drv == NULL)
0115 return DRVMGR_OK;
0116
0117
0118
0119
0120 if (!dev->drv->ops->remove) {
0121
0122
0123
0124 return DRVMGR_ENOSYS;
0125 }
0126 dev->error = dev->drv->ops->remove(dev);
0127 if (dev->error != DRVMGR_OK)
0128 return DRVMGR_FAIL;
0129
0130 DRVMGR_LOCK_WRITE();
0131
0132
0133 pprev = &dev->drv->dev;
0134 subdev = dev->drv->dev;
0135 while (subdev != dev) {
0136 pprev = &subdev->next_in_drv;
0137 subdev = subdev->next_in_drv;
0138 }
0139 *pprev = subdev->next_in_drv;
0140 dev->drv->dev_cnt--;
0141
0142
0143 drvmgr_list_remove(&mgr->devices[dev->level], dev);
0144 dev->level = 0;
0145 dev->state &= ~(DEV_STATE_UNITED|DEV_STATE_INIT_DONE);
0146 dev->state |= DEV_STATE_LIST_INACTIVE;
0147 drvmgr_list_add_tail(&mgr->devices_inactive, dev);
0148
0149 DRVMGR_UNLOCK();
0150
0151
0152
0153
0154 if (dev->drv->dev_priv_size && dev->priv) {
0155 free(dev->priv);
0156 dev->priv = NULL;
0157 }
0158 dev->drv = NULL;
0159
0160 return DRVMGR_OK;
0161 }
0162
0163
0164
0165
0166
0167
0168
0169 int drvmgr_dev_unregister(struct drvmgr_dev *dev)
0170 {
0171 struct drvmgr *mgr = &drvmgr;
0172 struct drvmgr_dev *subdev, **pprev;
0173 int err;
0174
0175
0176
0177
0178
0179 err = drvmgr_dev_drv_separate(dev);
0180 if (err != DRVMGR_OK)
0181 return err;
0182
0183 DRVMGR_LOCK_WRITE();
0184
0185
0186 drvmgr_list_remove(&mgr->devices_inactive, dev);
0187
0188
0189 pprev = &dev->parent->children;
0190 subdev = dev->parent->children;
0191 while (subdev != dev) {
0192 pprev = &subdev->next_in_bus;
0193 subdev = subdev->next_in_bus;
0194 }
0195 *pprev = subdev->next_in_bus;
0196 dev->parent->dev_cnt--;
0197
0198 DRVMGR_UNLOCK();
0199
0200
0201 free(dev);
0202
0203 return DRVMGR_OK;
0204 }