Changeset 02e5e34 in mainline
- 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
- Location:
- uspace/srv/devman
- Files:
-
- 3 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); -
uspace/srv/devman/fun.c
r181c32f r02e5e34 33 33 #include <errno.h> 34 34 #include <io/log.h> 35 35 #include <loc.h> 36 37 #include "dev.h" 36 38 #include "devman.h" 39 #include "devtree.h" 40 #include "driver.h" 37 41 #include "fun.h" 42 #include "main.h" 43 #include "loc.h" 38 44 39 45 static fun_node_t *find_node_child(dev_tree_t *, fun_node_t *, const char *); … … 280 286 } 281 287 288 static int assign_driver_fibril(void *arg) 289 { 290 dev_node_t *dev_node = (dev_node_t *) arg; 291 assign_driver(dev_node, &drivers_list, &device_tree); 292 293 /* Delete one reference we got from the caller. */ 294 dev_del_ref(dev_node); 295 return EOK; 296 } 297 298 int fun_online(fun_node_t *fun) 299 { 300 dev_node_t *dev; 301 302 fibril_rwlock_write_lock(&device_tree.rwlock); 303 304 if (fun->state == FUN_ON_LINE) { 305 fibril_rwlock_write_unlock(&device_tree.rwlock); 306 log_msg(LOG_DEFAULT, LVL_WARN, "Function %s is already on line.", 307 fun->pathname); 308 return EOK; 309 } 310 311 if (fun->ftype == fun_inner) { 312 dev = create_dev_node(); 313 if (dev == NULL) { 314 fibril_rwlock_write_unlock(&device_tree.rwlock); 315 return ENOMEM; 316 } 317 318 insert_dev_node(&device_tree, dev, fun); 319 dev_add_ref(dev); 320 } 321 322 log_msg(LOG_DEFAULT, LVL_DEBUG, "devman_add_function(fun=\"%s\")", fun->pathname); 323 324 if (fun->ftype == fun_inner) { 325 dev = fun->child; 326 assert(dev != NULL); 327 328 /* Give one reference over to assign_driver_fibril(). */ 329 dev_add_ref(dev); 330 331 /* 332 * Try to find a suitable driver and assign it to the device. We do 333 * not want to block the current fibril that is used for processing 334 * incoming calls: we will launch a separate fibril to handle the 335 * driver assigning. That is because assign_driver can actually include 336 * task spawning which could take some time. 337 */ 338 fid_t assign_fibril = fibril_create(assign_driver_fibril, dev); 339 if (assign_fibril == 0) { 340 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed to create fibril for " 341 "assigning driver."); 342 /* XXX Cleanup */ 343 fibril_rwlock_write_unlock(&device_tree.rwlock); 344 return ENOMEM; 345 } 346 fibril_add_ready(assign_fibril); 347 } else 348 loc_register_tree_function(fun, &device_tree); 349 350 fibril_rwlock_write_unlock(&device_tree.rwlock); 351 352 return EOK; 353 } 354 355 int fun_offline(fun_node_t *fun) 356 { 357 int rc; 358 359 fibril_rwlock_write_lock(&device_tree.rwlock); 360 361 if (fun->state == FUN_OFF_LINE) { 362 fibril_rwlock_write_unlock(&device_tree.rwlock); 363 log_msg(LOG_DEFAULT, LVL_WARN, "Function %s is already off line.", 364 fun->pathname); 365 return EOK; 366 } 367 368 if (fun->ftype == fun_inner) { 369 log_msg(LOG_DEFAULT, LVL_DEBUG, "Offlining inner function %s.", 370 fun->pathname); 371 372 if (fun->child != NULL) { 373 dev_node_t *dev = fun->child; 374 device_state_t dev_state; 375 376 dev_add_ref(dev); 377 dev_state = dev->state; 378 379 fibril_rwlock_write_unlock(&device_tree.rwlock); 380 381 /* If device is owned by driver, ask driver to give it up. */ 382 if (dev_state == DEVICE_USABLE) { 383 rc = driver_dev_remove(&device_tree, dev); 384 if (rc != EOK) { 385 dev_del_ref(dev); 386 return ENOTSUP; 387 } 388 } 389 390 /* Verify that driver removed all functions */ 391 fibril_rwlock_read_lock(&device_tree.rwlock); 392 if (!list_empty(&dev->functions)) { 393 fibril_rwlock_read_unlock(&device_tree.rwlock); 394 dev_del_ref(dev); 395 return EIO; 396 } 397 398 driver_t *driver = dev->drv; 399 fibril_rwlock_read_unlock(&device_tree.rwlock); 400 401 if (driver) 402 detach_driver(&device_tree, dev); 403 404 fibril_rwlock_write_lock(&device_tree.rwlock); 405 remove_dev_node(&device_tree, dev); 406 407 /* Delete ref created when node was inserted */ 408 dev_del_ref(dev); 409 /* Delete ref created by dev_add_ref(dev) above */ 410 dev_del_ref(dev); 411 } 412 } else { 413 /* Unregister from location service */ 414 rc = loc_service_unregister(fun->service_id); 415 if (rc != EOK) { 416 fibril_rwlock_write_unlock(&device_tree.rwlock); 417 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed unregistering tree service."); 418 return EIO; 419 } 420 421 fun->service_id = 0; 422 } 423 424 fun->state = FUN_OFF_LINE; 425 fibril_rwlock_write_unlock(&device_tree.rwlock); 426 427 return EOK; 428 } 429 282 430 /** @} 283 431 */ -
uspace/srv/devman/fun.h
r181c32f r02e5e34 49 49 const char *); 50 50 extern bool set_fun_path(dev_tree_t *, fun_node_t *, fun_node_t *); 51 extern int fun_online(fun_node_t *); 52 extern int fun_offline(fun_node_t *); 51 53 52 54 #endif
Note:
See TracChangeset
for help on using the changeset viewer.