Changeset 02e5e34 in mainline for uspace/srv/devman/drv_conn.c
- Timestamp:
- 2013-09-10T21:27:30Z (11 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- a501e22c
- Parents:
- 181c32f
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/devman/drv_conn.c
r181c32f r02e5e34 36 36 */ 37 37 38 #include <inttypes.h>39 38 #include <assert.h> 40 39 #include <ipc/services.h> … … 48 47 #include <stdlib.h> 49 48 #include <str.h> 50 #include <dirent.h>51 #include <fcntl.h>52 #include <sys/stat.h>53 #include <ctype.h>54 49 #include <io/log.h> 55 50 #include <ipc/devman.h> 56 51 #include <ipc/driver.h> 57 #include <thread.h>58 52 #include <loc.h> 59 53 … … 233 227 } 234 228 235 static int assign_driver_fibril(void *arg)236 {237 dev_node_t *dev_node = (dev_node_t *) arg;238 assign_driver(dev_node, &drivers_list, &device_tree);239 240 /* Delete one reference we got from the caller. */241 dev_del_ref(dev_node);242 return EOK;243 }244 245 static int online_function(fun_node_t *fun)246 {247 dev_node_t *dev;248 249 fibril_rwlock_write_lock(&device_tree.rwlock);250 251 if (fun->state == FUN_ON_LINE) {252 fibril_rwlock_write_unlock(&device_tree.rwlock);253 log_msg(LOG_DEFAULT, LVL_WARN, "Function %s is already on line.",254 fun->pathname);255 return EOK;256 }257 258 if (fun->ftype == fun_inner) {259 dev = create_dev_node();260 if (dev == NULL) {261 fibril_rwlock_write_unlock(&device_tree.rwlock);262 return ENOMEM;263 }264 265 insert_dev_node(&device_tree, dev, fun);266 dev_add_ref(dev);267 }268 269 log_msg(LOG_DEFAULT, LVL_DEBUG, "devman_add_function(fun=\"%s\")", fun->pathname);270 271 if (fun->ftype == fun_inner) {272 dev = fun->child;273 assert(dev != NULL);274 275 /* Give one reference over to assign_driver_fibril(). */276 dev_add_ref(dev);277 278 /*279 * Try to find a suitable driver and assign it to the device. We do280 * not want to block the current fibril that is used for processing281 * incoming calls: we will launch a separate fibril to handle the282 * driver assigning. That is because assign_driver can actually include283 * task spawning which could take some time.284 */285 fid_t assign_fibril = fibril_create(assign_driver_fibril, dev);286 if (assign_fibril == 0) {287 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed to create fibril for "288 "assigning driver.");289 /* XXX Cleanup */290 fibril_rwlock_write_unlock(&device_tree.rwlock);291 return ENOMEM;292 }293 fibril_add_ready(assign_fibril);294 } else295 loc_register_tree_function(fun, &device_tree);296 297 fibril_rwlock_write_unlock(&device_tree.rwlock);298 299 return EOK;300 }301 302 static int offline_function(fun_node_t *fun)303 {304 int rc;305 306 fibril_rwlock_write_lock(&device_tree.rwlock);307 308 if (fun->state == FUN_OFF_LINE) {309 fibril_rwlock_write_unlock(&device_tree.rwlock);310 log_msg(LOG_DEFAULT, LVL_WARN, "Function %s is already off line.",311 fun->pathname);312 return EOK;313 }314 315 if (fun->ftype == fun_inner) {316 log_msg(LOG_DEFAULT, LVL_DEBUG, "Offlining inner function %s.",317 fun->pathname);318 319 if (fun->child != NULL) {320 dev_node_t *dev = fun->child;321 device_state_t dev_state;322 323 dev_add_ref(dev);324 dev_state = dev->state;325 326 fibril_rwlock_write_unlock(&device_tree.rwlock);327 328 /* If device is owned by driver, ask driver to give it up. */329 if (dev_state == DEVICE_USABLE) {330 rc = driver_dev_remove(&device_tree, dev);331 if (rc != EOK) {332 dev_del_ref(dev);333 return ENOTSUP;334 }335 }336 337 /* Verify that driver removed all functions */338 fibril_rwlock_read_lock(&device_tree.rwlock);339 if (!list_empty(&dev->functions)) {340 fibril_rwlock_read_unlock(&device_tree.rwlock);341 dev_del_ref(dev);342 return EIO;343 }344 345 driver_t *driver = dev->drv;346 fibril_rwlock_read_unlock(&device_tree.rwlock);347 348 if (driver)349 detach_driver(&device_tree, dev);350 351 fibril_rwlock_write_lock(&device_tree.rwlock);352 remove_dev_node(&device_tree, dev);353 354 /* Delete ref created when node was inserted */355 dev_del_ref(dev);356 /* Delete ref created by dev_add_ref(dev) above */357 dev_del_ref(dev);358 }359 } else {360 /* Unregister from location service */361 rc = loc_service_unregister(fun->service_id);362 if (rc != EOK) {363 fibril_rwlock_write_unlock(&device_tree.rwlock);364 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed unregistering tree service.");365 return EIO;366 }367 368 fun->service_id = 0;369 }370 371 fun->state = FUN_OFF_LINE;372 fibril_rwlock_write_unlock(&device_tree.rwlock);373 374 return EOK;375 }376 377 229 /** Handle function registration. 378 230 * … … 461 313 devman_receive_match_ids(match_count, &fun->match_ids); 462 314 463 rc = online_function(fun);315 rc = fun_online(fun); 464 316 if (rc != EOK) { 465 317 /* XXX Set some failed state? */ … … 552 404 fibril_rwlock_read_unlock(&device_tree.rwlock); 553 405 554 rc = online_function(fun);406 rc = fun_offline(fun); 555 407 if (rc != EOK) { 556 408 fun_busy_unlock(fun); … … 593 445 fibril_rwlock_write_unlock(&device_tree.rwlock); 594 446 595 rc = offline_function(fun);447 rc = fun_offline(fun); 596 448 if (rc != EOK) { 597 449 fun_busy_unlock(fun);
Note:
See TracChangeset
for help on using the changeset viewer.