Changeset a35b458 in mainline for uspace/srv/devman
- Timestamp:
- 2018-03-02T20:10:49Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f1380b7
- Parents:
- 3061bc1
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-02-28 17:38:31)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-03-02 20:10:49)
- Location:
- uspace/srv/devman
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/devman/client_conn.c
r3061bc1 ra35b458 65 65 char *pathname; 66 66 devman_handle_t handle; 67 67 68 68 errno_t rc = async_data_write_accept((void **) &pathname, true, 0, 0, 0, 0); 69 69 if (rc != EOK) { … … 71 71 return; 72 72 } 73 73 74 74 fun_node_t *fun = find_fun_node_by_path(&device_tree, pathname); 75 75 76 76 free(pathname); 77 77 … … 306 306 return; 307 307 } 308 308 309 309 fibril_rwlock_read_lock(&device_tree.rwlock); 310 310 311 311 /* Check function state */ 312 312 if (fun->state == FUN_REMOVED) { … … 319 319 return; 320 320 } 321 321 322 322 size_t sent_length = str_size(fun->pathname); 323 323 if (sent_length > data_len) { … … 337 337 { 338 338 dev_node_t *dev; 339 339 340 340 fibril_rwlock_read_lock(&device_tree.rwlock); 341 341 342 342 dev = find_dev_node_no_lock(&device_tree, IPC_GET_ARG1(*icall)); 343 343 if (dev == NULL || dev->state == DEVICE_REMOVED) { … … 346 346 return; 347 347 } 348 348 349 349 if (dev->pfun == NULL) { 350 350 fibril_rwlock_read_unlock(&device_tree.rwlock); … … 352 352 return; 353 353 } 354 354 355 355 async_answer_1(iid, EOK, dev->pfun->handle); 356 356 357 357 fibril_rwlock_read_unlock(&device_tree.rwlock); 358 358 } … … 364 364 size_t act_size; 365 365 errno_t rc; 366 366 367 367 if (!async_data_read_receive(&callid, &size)) { 368 368 async_answer_0(callid, EREFUSED); … … 370 370 return; 371 371 } 372 372 373 373 fibril_rwlock_read_lock(&device_tree.rwlock); 374 374 375 375 dev_node_t *dev = find_dev_node_no_lock(&device_tree, 376 376 IPC_GET_ARG1(*icall)); … … 381 381 return; 382 382 } 383 383 384 384 devman_handle_t *hdl_buf = (devman_handle_t *) malloc(size); 385 385 if (hdl_buf == NULL) { … … 389 389 return; 390 390 } 391 391 392 392 rc = dev_get_functions(&device_tree, dev, hdl_buf, size, &act_size); 393 393 if (rc != EOK) { … … 397 397 return; 398 398 } 399 400 fibril_rwlock_read_unlock(&device_tree.rwlock); 401 399 400 fibril_rwlock_read_unlock(&device_tree.rwlock); 401 402 402 errno_t retval = async_data_read_finalize(callid, hdl_buf, size); 403 403 free(hdl_buf); 404 404 405 405 async_answer_1(iid, retval, act_size); 406 406 } … … 410 410 { 411 411 fun_node_t *fun; 412 412 413 413 fibril_rwlock_read_lock(&device_tree.rwlock); 414 414 415 415 fun = find_fun_node_no_lock(&device_tree, IPC_GET_ARG1(*icall)); 416 416 if (fun == NULL || fun->state == FUN_REMOVED) { … … 419 419 return; 420 420 } 421 421 422 422 if (fun->child == NULL) { 423 423 fibril_rwlock_read_unlock(&device_tree.rwlock); … … 425 425 return; 426 426 } 427 427 428 428 async_answer_1(iid, EOK, fun->child->handle); 429 429 430 430 fibril_rwlock_read_unlock(&device_tree.rwlock); 431 431 } … … 447 447 return; 448 448 } 449 449 450 450 rc = driver_fun_online(&device_tree, fun); 451 451 fun_del_ref(fun); 452 452 453 453 async_answer_0(iid, rc); 454 454 } … … 472 472 return; 473 473 } 474 474 475 475 rc = driver_fun_offline(&device_tree, fun); 476 476 fun_del_ref(fun); 477 477 478 478 async_answer_0(iid, rc); 479 479 } … … 485 485 486 486 fun = find_loc_tree_function(&device_tree, IPC_GET_ARG1(*icall)); 487 487 488 488 if (fun == NULL) { 489 489 async_answer_0(iid, ENOENT); … … 512 512 size_t act_size; 513 513 errno_t rc; 514 514 515 515 if (!async_data_read_receive(&callid, &size)) { 516 516 async_answer_0(iid, EREFUSED); 517 517 return; 518 518 } 519 519 520 520 devman_handle_t *hdl_buf = (devman_handle_t *) malloc(size); 521 521 if (hdl_buf == NULL) { … … 524 524 return; 525 525 } 526 526 527 527 rc = driver_get_list(&drivers_list, hdl_buf, size, &act_size); 528 528 if (rc != EOK) { … … 531 531 return; 532 532 } 533 533 534 534 errno_t retval = async_data_read_finalize(callid, hdl_buf, size); 535 535 free(hdl_buf); 536 536 537 537 async_answer_1(iid, retval, act_size); 538 538 } … … 544 544 size_t act_size; 545 545 errno_t rc; 546 546 547 547 if (!async_data_read_receive(&callid, &size)) { 548 548 async_answer_0(iid, EREFUSED); 549 549 return; 550 550 } 551 551 552 552 driver_t *drv = driver_find(&drivers_list, IPC_GET_ARG1(*icall)); 553 553 if (drv == NULL) { … … 556 556 return; 557 557 } 558 558 559 559 devman_handle_t *hdl_buf = (devman_handle_t *) malloc(size); 560 560 if (hdl_buf == NULL) { … … 563 563 return; 564 564 } 565 565 566 566 rc = driver_get_devices(drv, hdl_buf, size, &act_size); 567 567 if (rc != EOK) { … … 571 571 return; 572 572 } 573 573 574 574 errno_t retval = async_data_read_finalize(callid, hdl_buf, size); 575 575 free(hdl_buf); 576 576 577 577 async_answer_1(iid, retval, act_size); 578 578 } … … 583 583 { 584 584 char *drvname; 585 585 586 586 errno_t rc = async_data_write_accept((void **) &drvname, true, 0, 0, 0, 0); 587 587 if (rc != EOK) { … … 589 589 return; 590 590 } 591 591 592 592 driver_t *driver = driver_find_by_name(&drivers_list, drvname); 593 593 594 594 free(drvname); 595 595 596 596 if (driver == NULL) { 597 597 async_answer_0(iid, ENOENT); 598 598 return; 599 599 } 600 600 601 601 async_answer_1(iid, EOK, driver->handle); 602 602 } … … 697 697 { 698 698 driver_t *drv; 699 699 700 700 drv = driver_find(&drivers_list, IPC_GET_ARG1(*icall)); 701 701 if (drv == NULL) { … … 703 703 return; 704 704 } 705 705 706 706 async_answer_1(iid, EOK, (sysarg_t) drv->state); 707 707 } … … 712 712 driver_t *drv; 713 713 errno_t rc; 714 714 715 715 drv = driver_find(&drivers_list, IPC_GET_ARG1(*icall)); 716 716 if (drv == NULL) { … … 718 718 return; 719 719 } 720 720 721 721 fibril_mutex_lock(&drv->driver_mutex); 722 722 rc = start_driver(drv) ? EOK : EIO; … … 731 731 driver_t *drv; 732 732 errno_t rc; 733 733 734 734 drv = driver_find(&drivers_list, IPC_GET_ARG1(*icall)); 735 735 if (drv == NULL) { … … 737 737 return; 738 738 } 739 739 740 740 fibril_mutex_lock(&drv->driver_mutex); 741 741 rc = stop_driver(drv); … … 750 750 /* Accept connection. */ 751 751 async_answer_0(iid, EOK); 752 752 753 753 while (true) { 754 754 ipc_call_t call; 755 755 ipc_callid_t callid = async_get_call(&call); 756 756 757 757 if (!IPC_GET_IMETHOD(call)) 758 758 break; 759 759 760 760 switch (IPC_GET_IMETHOD(call)) { 761 761 case DEVMAN_DEVICE_GET_HANDLE: -
uspace/srv/devman/dev.c
r3061bc1 ra35b458 43 43 { 44 44 dev_node_t *dev; 45 45 46 46 dev = calloc(1, sizeof(dev_node_t)); 47 47 if (dev == NULL) 48 48 return NULL; 49 49 50 50 atomic_set(&dev->refcnt, 0); 51 51 list_initialize(&dev->functions); 52 52 link_initialize(&dev->driver_devices); 53 53 54 54 return dev; 55 55 } … … 64 64 assert(dev->pfun == NULL); 65 65 assert(dev->drv == NULL); 66 66 67 67 free(dev); 68 68 } … … 98 98 { 99 99 assert(fibril_rwlock_is_locked(&tree->rwlock)); 100 100 101 101 ht_link_t *link = hash_table_find(&tree->devman_devices, &handle); 102 102 if (link == NULL) 103 103 return NULL; 104 104 105 105 return hash_table_get_inst(link, dev_node_t, devman_dev); 106 106 } … … 115 115 { 116 116 dev_node_t *dev = NULL; 117 117 118 118 fibril_rwlock_read_lock(&tree->rwlock); 119 119 dev = find_dev_node_no_lock(tree, handle); 120 120 if (dev != NULL) 121 121 dev_add_ref(dev); 122 122 123 123 fibril_rwlock_read_unlock(&tree->rwlock); 124 124 125 125 return dev; 126 126 } -
uspace/srv/devman/devman.h
r3061bc1 ra35b458 68 68 /** Handle */ 69 69 devman_handle_t handle; 70 70 71 71 /** 72 72 * Specifies whether the driver has been started and wheter is running … … 74 74 */ 75 75 driver_state_t state; 76 76 77 77 /** Session asociated with this driver. */ 78 78 async_sess_t *sess; … … 85 85 /** List of devices controlled by this driver. */ 86 86 list_t devices; 87 87 88 88 /** 89 89 * Fibril mutex for this driver - driver state, list of devices, session. … … 116 116 /** Reference count */ 117 117 atomic_t refcnt; 118 118 119 119 /** The global unique identifier of the device. */ 120 120 devman_handle_t handle; 121 121 122 122 /** (Parent) function the device is attached to. */ 123 123 fun_node_t *pfun; 124 124 125 125 /** List of device functions. */ 126 126 list_t functions; … … 131 131 /** Link to list of devices owned by driver (driver_t.devices) */ 132 132 link_t driver_devices; 133 133 134 134 /** 135 135 * Used by the hash table of devices indexed by devman device handles. 136 136 */ 137 137 ht_link_t devman_dev; 138 138 139 139 /** 140 140 * Whether this device was already passed to the driver. … … 160 160 /** Locked while performing reconfiguration operations */ 161 161 fibril_mutex_t busy_lock; 162 162 163 163 /** The global unique identifier of the function */ 164 164 devman_handle_t handle; … … 167 167 /** Function type */ 168 168 fun_type_t ftype; 169 169 170 170 /** Full path and name of the device in device hierarchy */ 171 171 char *pathname; 172 172 173 173 /** Device which this function belongs to */ 174 174 dev_node_t *dev; 175 175 176 176 /** Link to list of functions in the device (ddf_dev_t.functions) */ 177 177 link_t dev_functions; 178 178 179 179 /** Child device node (if any attached). */ 180 180 dev_node_t *child; 181 181 /** List of device ids for device-to-driver matching. */ 182 182 match_id_list_t match_ids; 183 183 184 184 /** Service ID if the device function is registered with loc. */ 185 185 service_id_t service_id; 186 186 187 187 /** 188 188 * Used by the hash table of functions indexed by devman device handles. 189 189 */ 190 190 ht_link_t devman_fun; 191 191 192 192 /** 193 193 * Used by the hash table of functions indexed by service IDs. … … 200 200 /** Root device node. */ 201 201 fun_node_t *root_node; 202 202 203 203 /** 204 204 * The next available handle - handles are assigned in a sequential … … 206 206 */ 207 207 devman_handle_t current_handle; 208 208 209 209 /** Synchronize access to the device tree. */ 210 210 fibril_rwlock_t rwlock; 211 211 212 212 /** Hash table of all devices indexed by devman handles. */ 213 213 hash_table_t devman_devices; 214 214 215 215 /** Hash table of all devices indexed by devman handles. */ 216 216 hash_table_t devman_functions; 217 217 218 218 /** 219 219 * Hash table of services registered with location service, indexed by -
uspace/srv/devman/devtree.c
r3061bc1 ra35b458 127 127 fun_node_t *fun; 128 128 dev_node_t *dev; 129 129 130 130 log_msg(LOG_DEFAULT, LVL_DEBUG, "create_root_nodes()"); 131 131 132 132 fibril_rwlock_write_lock(&tree->rwlock); 133 133 134 134 /* 135 135 * Create root function. This is a pseudo function to which … … 138 138 * the parent function. 139 139 */ 140 140 141 141 fun = create_fun_node(); 142 142 if (fun == NULL) { … … 144 144 return false; 145 145 } 146 146 147 147 fun_add_ref(fun); 148 148 insert_fun_node(tree, fun, str_dup(""), NULL); 149 149 150 150 match_id_t *id = create_match_id(); 151 151 id->id = str_dup("root"); … … 153 153 add_match_id(&fun->match_ids, id); 154 154 tree->root_node = fun; 155 155 156 156 /* 157 157 * Create root device node. … … 162 162 return false; 163 163 } 164 164 165 165 dev_add_ref(dev); 166 166 insert_dev_node(tree, dev, fun); 167 167 168 168 fibril_rwlock_write_unlock(&tree->rwlock); 169 169 170 170 return dev != NULL; 171 171 } … … 182 182 { 183 183 log_msg(LOG_DEFAULT, LVL_DEBUG, "init_device_tree()"); 184 184 185 185 tree->current_handle = 0; 186 186 187 187 hash_table_create(&tree->devman_devices, 0, 0, &devman_devices_ops); 188 188 hash_table_create(&tree->devman_functions, 0, 0, &devman_functions_ops); 189 189 hash_table_create(&tree->loc_functions, 0, 0, &loc_devices_ops); 190 190 191 191 fibril_rwlock_initialize(&tree->rwlock); 192 192 193 193 /* Create root function and root device and add them to the device tree. */ 194 194 if (!create_root_nodes(tree)) 195 195 return false; 196 196 197 197 /* Find suitable driver and start it. */ 198 198 dev_node_t *rdev = tree->root_node->child; … … 200 200 bool rc = assign_driver(rdev, drivers_list, tree); 201 201 dev_del_ref(rdev); 202 202 203 203 return rc; 204 204 } … … 216 216 { 217 217 assert(fibril_rwlock_is_write_locked(&tree->rwlock)); 218 218 219 219 log_msg(LOG_DEFAULT, LVL_DEBUG, "insert_dev_node(dev=%p, pfun=%p [\"%s\"])", 220 220 dev, pfun, pfun->pathname); … … 227 227 dev->pfun = pfun; 228 228 pfun->child = dev; 229 229 230 230 return true; 231 231 } … … 239 239 { 240 240 assert(fibril_rwlock_is_write_locked(&tree->rwlock)); 241 241 242 242 log_msg(LOG_DEFAULT, LVL_DEBUG, "remove_dev_node(dev=%p)", dev); 243 243 244 244 /* Remove node from the handle-to-node map. */ 245 245 hash_table_remove(&tree->devman_devices, &dev->handle); 246 246 247 247 /* Unlink from parent function. */ 248 248 dev->pfun->child = NULL; 249 249 dev->pfun = NULL; 250 250 251 251 dev->state = DEVICE_REMOVED; 252 252 } … … 267 267 { 268 268 fun_node_t *pfun; 269 269 270 270 assert(fun_name != NULL); 271 271 assert(fibril_rwlock_is_write_locked(&tree->rwlock)); 272 272 273 273 /* 274 274 * The root function is a special case, it does not belong to any … … 276 276 */ 277 277 pfun = (dev != NULL) ? dev->pfun : NULL; 278 278 279 279 fun->name = fun_name; 280 280 if (!set_fun_path(tree, fun, pfun)) { 281 281 return false; 282 282 } 283 283 284 284 /* Add the node to the handle-to-node map. */ 285 285 fun->handle = ++tree->current_handle; … … 290 290 if (dev != NULL) 291 291 list_append(&fun->dev_functions, &dev->functions); 292 292 293 293 return true; 294 294 } … … 302 302 { 303 303 assert(fibril_rwlock_is_write_locked(&tree->rwlock)); 304 304 305 305 /* Remove the node from the handle-to-node map. */ 306 306 hash_table_remove(&tree->devman_functions, &fun->handle); 307 307 308 308 /* Remove the node from the list of its parent's children. */ 309 309 if (fun->dev != NULL) 310 310 list_remove(&fun->dev_functions); 311 311 312 312 fun->dev = NULL; 313 313 fun->state = FUN_REMOVED; -
uspace/srv/devman/driver.c
r3061bc1 ra35b458 54 54 { 55 55 assert(drv_list != NULL); 56 56 57 57 list_initialize(&drv_list->drivers); 58 58 fibril_mutex_initialize(&drv_list->drivers_mutex); … … 112 112 log_msg(LOG_DEFAULT, LVL_DEBUG, "get_driver_info(base_path=\"%s\", name=\"%s\")", 113 113 base_path, name); 114 114 115 115 assert(base_path != NULL && name != NULL && drv != NULL); 116 116 117 117 bool suc = false; 118 118 char *match_path = NULL; 119 119 size_t name_size = 0; 120 120 121 121 /* Read the list of match ids from the driver's configuration file. */ 122 122 match_path = get_abs_path(base_path, name, MATCH_EXT); 123 123 if (match_path == NULL) 124 124 goto cleanup; 125 125 126 126 if (!read_match_ids(match_path, &drv->match_ids)) 127 127 goto cleanup; 128 128 129 129 /* Allocate and fill driver's name. */ 130 130 name_size = str_size(name) + 1; … … 133 133 goto cleanup; 134 134 str_cpy(drv->name, name_size, name); 135 135 136 136 /* Initialize path with driver's binary. */ 137 137 drv->binary_path = get_abs_path(base_path, name, ""); 138 138 if (drv->binary_path == NULL) 139 139 goto cleanup; 140 140 141 141 /* Check whether the driver's binary exists. */ 142 142 vfs_stat_t s; … … 146 146 goto cleanup; 147 147 } 148 148 149 149 suc = true; 150 150 151 151 cleanup: 152 152 if (!suc) { … … 156 156 init_driver(drv); 157 157 } 158 158 159 159 free(match_path); 160 160 161 161 return suc; 162 162 } … … 171 171 { 172 172 log_msg(LOG_DEFAULT, LVL_DEBUG, "lookup_available_drivers(dir=\"%s\")", dir_path); 173 173 174 174 int drv_cnt = 0; 175 175 DIR *dir = NULL; … … 177 177 178 178 dir = opendir(dir_path); 179 179 180 180 if (dir != NULL) { 181 181 driver_t *drv = create_driver(); … … 190 190 closedir(dir); 191 191 } 192 192 193 193 return drv_cnt; 194 194 } … … 213 213 driver_t *best_drv = NULL; 214 214 int best_score = 0, score = 0; 215 215 216 216 fibril_mutex_lock(&drivers_list->drivers_mutex); 217 217 218 218 list_foreach(drivers_list->drivers, drivers, driver_t, drv) { 219 219 score = get_match_score(drv, node); … … 223 223 } 224 224 } 225 225 226 226 fibril_mutex_unlock(&drivers_list->drivers_mutex); 227 227 228 228 return best_drv; 229 229 } … … 239 239 log_msg(LOG_DEFAULT, LVL_DEBUG, "attach_driver(dev=\"%s\",drv=\"%s\")", 240 240 dev->pfun->pathname, drv->name); 241 241 242 242 fibril_mutex_lock(&drv->driver_mutex); 243 243 fibril_rwlock_write_lock(&tree->rwlock); 244 244 245 245 dev->drv = drv; 246 246 list_append(&dev->driver_devices, &drv->devices); 247 247 248 248 fibril_rwlock_write_unlock(&tree->rwlock); 249 249 fibril_mutex_unlock(&drv->driver_mutex); … … 259 259 { 260 260 driver_t *drv = dev->drv; 261 261 262 262 assert(drv != NULL); 263 263 264 264 log_msg(LOG_DEFAULT, LVL_DEBUG, "detach_driver(dev=\"%s\",drv=\"%s\")", 265 265 dev->pfun->pathname, drv->name); 266 266 267 267 fibril_mutex_lock(&drv->driver_mutex); 268 268 fibril_rwlock_write_lock(&tree->rwlock); 269 269 270 270 dev->drv = NULL; 271 271 list_remove(&dev->driver_devices); 272 272 273 273 fibril_rwlock_write_unlock(&tree->rwlock); 274 274 fibril_mutex_unlock(&drv->driver_mutex); … … 286 286 287 287 assert(fibril_mutex_is_locked(&drv->driver_mutex)); 288 288 289 289 log_msg(LOG_DEFAULT, LVL_DEBUG, "start_driver(drv=\"%s\")", drv->name); 290 290 291 291 rc = task_spawnl(NULL, NULL, drv->binary_path, drv->binary_path, NULL); 292 292 if (rc != EOK) { … … 295 295 return false; 296 296 } 297 297 298 298 drv->state = DRIVER_STARTING; 299 299 return true; … … 310 310 async_exch_t *exch; 311 311 errno_t retval; 312 312 313 313 log_msg(LOG_DEFAULT, LVL_DEBUG, "stop_driver(drv=\"%s\")", drv->name); 314 314 … … 316 316 retval = async_req_0_0(exch, DRIVER_STOP); 317 317 loc_exchange_end(exch); 318 318 319 319 if (retval != EOK) 320 320 return retval; 321 321 322 322 drv->state = DRIVER_NOT_STARTED; 323 323 async_hangup(drv->sess); … … 336 336 { 337 337 driver_t *res = NULL; 338 338 339 339 fibril_mutex_lock(&drv_list->drivers_mutex); 340 340 341 341 list_foreach(drv_list->drivers, drivers, driver_t, drv) { 342 342 if (drv->handle == handle) { … … 345 345 } 346 346 } 347 347 348 348 fibril_mutex_unlock(&drv_list->drivers_mutex); 349 349 350 350 return res; 351 351 } … … 362 362 { 363 363 driver_t *res = NULL; 364 364 365 365 fibril_mutex_lock(&drv_list->drivers_mutex); 366 366 367 367 list_foreach(drv_list->drivers, drivers, driver_t, drv) { 368 368 if (str_cmp(drv->name, drv_name) == 0) { … … 371 371 } 372 372 } 373 373 374 374 fibril_mutex_unlock(&drv_list->drivers_mutex); 375 375 376 376 return res; 377 377 } … … 399 399 dev = list_get_instance(link, dev_node_t, driver_devices); 400 400 fibril_rwlock_write_lock(&tree->rwlock); 401 401 402 402 if (dev->passed_to_driver) { 403 403 fibril_rwlock_write_unlock(&tree->rwlock); … … 461 461 log_msg(LOG_DEFAULT, LVL_DEBUG, "initialize_running_driver(driver=\"%s\")", 462 462 driver->name); 463 463 464 464 /* 465 465 * Pass devices which have been already assigned to the driver to the … … 507 507 { 508 508 assert(drv != NULL); 509 509 510 510 clean_driver(drv); 511 511 free(drv); … … 525 525 assert(drivers_list != NULL); 526 526 assert(tree != NULL); 527 527 528 528 /* 529 529 * Find the driver which is the most suitable for handling this device. … … 535 535 return false; 536 536 } 537 537 538 538 /* Attach the driver to the device. */ 539 539 attach_driver(tree, dev, drv); 540 540 541 541 fibril_mutex_lock(&drv->driver_mutex); 542 542 if (drv->state == DRIVER_NOT_STARTED) { … … 550 550 if (is_running) 551 551 add_device(drv, dev, tree); 552 552 553 553 fibril_mutex_lock(&drv->driver_mutex); 554 554 fibril_mutex_unlock(&drv->driver_mutex); … … 575 575 log_msg(LOG_DEFAULT, LVL_DEBUG, "add_device(drv=\"%s\", dev=\"%s\")", 576 576 drv->name, dev->pfun->name); 577 577 578 578 /* Send the device to the driver. */ 579 579 devman_handle_t parent_handle; … … 583 583 parent_handle = 0; 584 584 } 585 585 586 586 async_exch_t *exch = async_exchange_begin(drv->sess); 587 587 588 588 ipc_call_t answer; 589 589 aid_t req = async_send_2(exch, DRIVER_DEV_ADD, dev->handle, 590 590 parent_handle, &answer); 591 591 592 592 /* Send the device name to the driver. */ 593 593 errno_t rc = async_data_write_start(exch, dev->pfun->name, 594 594 str_size(dev->pfun->name) + 1); 595 595 596 596 async_exchange_end(exch); 597 597 598 598 if (rc != EOK) { 599 599 async_forget(req); … … 614 614 break; 615 615 } 616 616 617 617 dev->passed_to_driver = true; 618 618 } … … 624 624 driver_t *drv; 625 625 devman_handle_t handle; 626 626 627 627 assert(dev != NULL); 628 628 629 629 log_msg(LOG_DEFAULT, LVL_DEBUG, "driver_dev_remove(%p)", dev); 630 630 631 631 fibril_rwlock_read_lock(&tree->rwlock); 632 632 drv = dev->drv; 633 633 handle = dev->handle; 634 634 fibril_rwlock_read_unlock(&tree->rwlock); 635 635 636 636 exch = async_exchange_begin(drv->sess); 637 637 retval = async_req_1_0(exch, DRIVER_DEV_REMOVE, handle); 638 638 async_exchange_end(exch); 639 639 640 640 return retval; 641 641 } … … 647 647 driver_t *drv; 648 648 devman_handle_t handle; 649 649 650 650 assert(dev != NULL); 651 651 652 652 log_msg(LOG_DEFAULT, LVL_DEBUG, "driver_dev_gone(%p)", dev); 653 653 654 654 fibril_rwlock_read_lock(&tree->rwlock); 655 655 drv = dev->drv; 656 656 handle = dev->handle; 657 657 fibril_rwlock_read_unlock(&tree->rwlock); 658 658 659 659 exch = async_exchange_begin(drv->sess); 660 660 retval = async_req_1_0(exch, DRIVER_DEV_GONE, handle); 661 661 async_exchange_end(exch); 662 662 663 663 return retval; 664 664 } … … 670 670 driver_t *drv; 671 671 devman_handle_t handle; 672 672 673 673 log_msg(LOG_DEFAULT, LVL_DEBUG, "driver_fun_online(%p)", fun); 674 674 675 675 fibril_rwlock_read_lock(&tree->rwlock); 676 676 677 677 if (fun->dev == NULL) { 678 678 /* XXX root function? */ … … 680 680 return EINVAL; 681 681 } 682 682 683 683 drv = fun->dev->drv; 684 684 handle = fun->handle; 685 685 fibril_rwlock_read_unlock(&tree->rwlock); 686 686 687 687 exch = async_exchange_begin(drv->sess); 688 688 retval = async_req_1_0(exch, DRIVER_FUN_ONLINE, handle); 689 689 loc_exchange_end(exch); 690 690 691 691 return retval; 692 692 } … … 698 698 driver_t *drv; 699 699 devman_handle_t handle; 700 700 701 701 log_msg(LOG_DEFAULT, LVL_DEBUG, "driver_fun_offline(%p)", fun); 702 702 … … 707 707 return EINVAL; 708 708 } 709 709 710 710 drv = fun->dev->drv; 711 711 handle = fun->handle; 712 712 fibril_rwlock_read_unlock(&tree->rwlock); 713 713 714 714 exch = async_exchange_begin(drv->sess); 715 715 retval = async_req_1_0(exch, DRIVER_FUN_OFFLINE, handle); 716 716 loc_exchange_end(exch); 717 717 718 718 return retval; 719 719 -
uspace/srv/devman/drv_conn.c
r3061bc1 ra35b458 70 70 71 71 log_msg(LOG_DEFAULT, LVL_DEBUG, "devman_driver_register"); 72 72 73 73 /* Get driver name. */ 74 74 errno_t rc = async_data_write_accept((void **) &drv_name, true, 0, 0, 0, 0); … … 80 80 log_msg(LOG_DEFAULT, LVL_DEBUG, "The `%s' driver is trying to register.", 81 81 drv_name); 82 82 83 83 /* Find driver structure. */ 84 84 driver = driver_find_by_name(&drivers_list, drv_name); … … 90 90 return NULL; 91 91 } 92 92 93 93 free(drv_name); 94 94 drv_name = NULL; 95 95 96 96 fibril_mutex_lock(&driver->driver_mutex); 97 97 98 98 if (driver->sess) { 99 99 /* We already have a connection to the driver. */ … … 104 104 return NULL; 105 105 } 106 106 107 107 switch (driver->state) { 108 108 case DRIVER_NOT_STARTED: … … 119 119 assert(false); 120 120 } 121 121 122 122 /* Create connection to the driver. */ 123 123 log_msg(LOG_DEFAULT, LVL_DEBUG, "Creating connection to the `%s' driver.", … … 131 131 /* FIXME: Work around problem with callback sessions */ 132 132 async_sess_args_set(driver->sess, INTERFACE_DDF_DEVMAN, 0, 0); 133 133 134 134 log_msg(LOG_DEFAULT, LVL_NOTE, 135 135 "The `%s' driver was successfully registered as running.", 136 136 driver->name); 137 137 138 138 /* 139 139 * Initialize the driver as running (e.g. pass assigned devices to it) … … 149 149 return NULL; 150 150 } 151 151 152 152 fibril_add_ready(fid); 153 153 fibril_mutex_unlock(&driver->driver_mutex); 154 154 155 155 async_answer_0(callid, EOK); 156 156 return driver; … … 169 169 ipc_call_t call; 170 170 errno_t rc = 0; 171 171 172 172 callid = async_get_call(&call); 173 173 if (DEVMAN_ADD_MATCH_ID != IPC_GET_IMETHOD(call)) { … … 178 178 return EINVAL; 179 179 } 180 180 181 181 if (match_id == NULL) { 182 182 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed to allocate match id."); … … 184 184 return ENOMEM; 185 185 } 186 186 187 187 async_answer_0(callid, EOK); 188 188 189 189 match_id->score = IPC_GET_ARG1(call); 190 190 191 191 char *match_id_str; 192 192 rc = async_data_write_accept((void **) &match_id_str, true, 0, 0, 0, 0); … … 198 198 return rc; 199 199 } 200 200 201 201 list_append(&match_id->link, &match_ids->ids); 202 202 203 203 log_msg(LOG_DEFAULT, LVL_DEBUG, "Received match id `%s', score %d.", 204 204 match_id->id, match_id->score); … … 218 218 errno_t ret = EOK; 219 219 size_t i; 220 220 221 221 for (i = 0; i < match_count; i++) { 222 222 if (EOK != (ret = devman_receive_match_id(match_ids))) … … 236 236 sysarg_t match_count = IPC_GET_ARG3(*call); 237 237 dev_tree_t *tree = &device_tree; 238 238 239 239 dev_node_t *pdev = find_dev_node(&device_tree, dev_handle); 240 240 if (pdev == NULL) { … … 242 242 return; 243 243 } 244 244 245 245 if (ftype != fun_inner && ftype != fun_exposed) { 246 246 /* Unknown function type */ … … 253 253 return; 254 254 } 255 255 256 256 char *fun_name = NULL; 257 257 errno_t rc = async_data_write_accept((void **)&fun_name, true, 0, 0, 0, 0); … … 261 261 return; 262 262 } 263 263 264 264 fibril_rwlock_write_lock(&tree->rwlock); 265 265 266 266 /* Check device state */ 267 267 if (pdev->state == DEVICE_REMOVED) { … … 271 271 return; 272 272 } 273 273 274 274 /* Check that function with same name is not there already. */ 275 275 fun_node_t *tfun = find_fun_node_in_device(tree, pdev, fun_name); … … 284 284 return; 285 285 } 286 286 287 287 fun_node_t *fun = create_fun_node(); 288 288 /* One reference for creation, one for us */ … … 290 290 fun_add_ref(fun); 291 291 fun->ftype = ftype; 292 292 293 293 /* 294 294 * We can lock the function here even when holding the tree because … … 296 296 */ 297 297 fun_busy_lock(fun); 298 298 299 299 if (!insert_fun_node(&device_tree, fun, fun_name, pdev)) { 300 300 fibril_rwlock_write_unlock(&tree->rwlock); … … 306 306 return; 307 307 } 308 308 309 309 fibril_rwlock_write_unlock(&tree->rwlock); 310 310 dev_del_ref(pdev); 311 311 312 312 devman_receive_match_ids(match_count, &fun->match_ids); 313 313 314 314 rc = fun_online(fun); 315 315 if (rc != EOK) { … … 320 320 return; 321 321 } 322 322 323 323 fun_busy_unlock(fun); 324 324 fun_del_ref(fun); 325 325 326 326 /* Return device handle to parent's driver. */ 327 327 async_answer_1(callid, EOK, fun->handle); … … 333 333 category_id_t cat_id; 334 334 errno_t rc; 335 335 336 336 /* Get category name. */ 337 337 char *cat_name; … … 342 342 return; 343 343 } 344 344 345 345 fun_node_t *fun = find_fun_node(&device_tree, handle); 346 346 if (fun == NULL) { … … 348 348 return; 349 349 } 350 350 351 351 fibril_rwlock_read_lock(&device_tree.rwlock); 352 352 353 353 /* Check function state */ 354 354 if (fun->state == FUN_REMOVED) { … … 357 357 return; 358 358 } 359 359 360 360 rc = loc_category_get_id(cat_name, &cat_id, IPC_FLAG_BLOCKING); 361 361 if (rc == EOK) { … … 367 367 "`%s'.", fun->pathname, cat_name); 368 368 } 369 369 370 370 fibril_rwlock_read_unlock(&device_tree.rwlock); 371 371 fun_del_ref(fun); 372 372 373 373 async_answer_0(callid, rc); 374 374 } … … 382 382 fun_node_t *fun; 383 383 errno_t rc; 384 384 385 385 log_msg(LOG_DEFAULT, LVL_DEBUG, "devman_drv_fun_online()"); 386 386 387 387 fun = find_fun_node(&device_tree, IPC_GET_ARG1(*icall)); 388 388 if (fun == NULL) { … … 390 390 return; 391 391 } 392 392 393 393 fun_busy_lock(fun); 394 394 395 395 fibril_rwlock_read_lock(&device_tree.rwlock); 396 396 if (fun->dev == NULL || fun->dev->drv != drv) { … … 402 402 } 403 403 fibril_rwlock_read_unlock(&device_tree.rwlock); 404 404 405 405 rc = fun_online(fun); 406 406 if (rc != EOK) { … … 410 410 return; 411 411 } 412 412 413 413 fun_busy_unlock(fun); 414 414 fun_del_ref(fun); 415 415 416 416 async_answer_0(iid, EOK); 417 417 } … … 432 432 return; 433 433 } 434 434 435 435 fun_busy_lock(fun); 436 436 437 437 fibril_rwlock_write_lock(&device_tree.rwlock); 438 438 if (fun->dev == NULL || fun->dev->drv != drv) { … … 443 443 } 444 444 fibril_rwlock_write_unlock(&device_tree.rwlock); 445 445 446 446 rc = fun_offline(fun); 447 447 if (rc != EOK) { … … 451 451 return; 452 452 } 453 453 454 454 fun_busy_unlock(fun); 455 455 fun_del_ref(fun); … … 463 463 dev_tree_t *tree = &device_tree; 464 464 errno_t rc; 465 465 466 466 fun_node_t *fun = find_fun_node(&device_tree, fun_handle); 467 467 if (fun == NULL) { … … 469 469 return; 470 470 } 471 471 472 472 fun_busy_lock(fun); 473 473 474 474 fibril_rwlock_write_lock(&tree->rwlock); 475 475 476 476 log_msg(LOG_DEFAULT, LVL_DEBUG, "devman_remove_function(fun='%s')", fun->pathname); 477 477 478 478 /* Check function state */ 479 479 if (fun->state == FUN_REMOVED) { … … 484 484 return; 485 485 } 486 486 487 487 if (fun->ftype == fun_inner) { 488 488 /* This is a surprise removal. Handle possible descendants */ … … 491 491 device_state_t dev_state; 492 492 errno_t gone_rc; 493 493 494 494 dev_add_ref(dev); 495 495 dev_state = dev->state; 496 496 497 497 fibril_rwlock_write_unlock(&device_tree.rwlock); 498 498 499 499 /* If device is owned by driver, inform driver it is gone. */ 500 500 if (dev_state == DEVICE_USABLE) … … 502 502 else 503 503 gone_rc = EOK; 504 504 505 505 fibril_rwlock_read_lock(&device_tree.rwlock); 506 506 507 507 /* Verify that driver succeeded and removed all functions */ 508 508 if (gone_rc != EOK || !list_empty(&dev->functions)) { … … 510 510 "functions for device that is gone. " 511 511 "Device node is now defunct."); 512 512 513 513 /* 514 514 * Not much we can do but mark the device … … 526 526 return; 527 527 } 528 528 529 529 driver_t *driver = dev->drv; 530 530 fibril_rwlock_read_unlock(&device_tree.rwlock); 531 531 532 532 if (driver) 533 533 detach_driver(&device_tree, dev); 534 534 535 535 fibril_rwlock_write_lock(&device_tree.rwlock); 536 536 remove_dev_node(&device_tree, dev); 537 537 538 538 /* Delete ref created when node was inserted */ 539 539 dev_del_ref(dev); … … 556 556 } 557 557 } 558 558 559 559 remove_fun_node(&device_tree, fun); 560 560 fibril_rwlock_write_unlock(&tree->rwlock); 561 561 fun_busy_unlock(fun); 562 562 563 563 /* Delete ref added when inserting function into tree */ 564 564 fun_del_ref(fun); 565 565 /* Delete ref added above when looking up function */ 566 566 fun_del_ref(fun); 567 567 568 568 log_msg(LOG_DEFAULT, LVL_DEBUG, "devman_remove_function() succeeded."); 569 569 async_answer_0(callid, EOK); … … 578 578 { 579 579 driver_t *driver = (driver_t *) drv; 580 580 581 581 initialize_running_driver(driver, &device_tree); 582 582 log_msg(LOG_DEFAULT, LVL_DEBUG, "The `%s` driver was successfully initialized.", … … 590 590 client_t *client; 591 591 driver_t *driver = NULL; 592 592 593 593 /* Accept the connection. */ 594 594 async_answer_0(iid, EOK); 595 595 596 596 client = async_get_client_data(); 597 597 if (client == NULL) { … … 599 599 return; 600 600 } 601 601 602 602 while (true) { 603 603 ipc_call_t call; 604 604 ipc_callid_t callid = async_get_call(&call); 605 605 606 606 if (!IPC_GET_IMETHOD(call)) 607 607 break; 608 608 609 609 if (IPC_GET_IMETHOD(call) != DEVMAN_DRIVER_REGISTER) { 610 610 fibril_mutex_lock(&client->mutex); … … 617 617 } 618 618 } 619 619 620 620 switch (IPC_GET_IMETHOD(call)) { 621 621 case DEVMAN_DRIVER_REGISTER: -
uspace/srv/devman/fun.c
r3061bc1 ra35b458 58 58 if (fun == NULL) 59 59 return NULL; 60 60 61 61 fun->state = FUN_INIT; 62 62 atomic_set(&fun->refcnt, 0); … … 64 64 link_initialize(&fun->dev_functions); 65 65 list_initialize(&fun->match_ids.ids); 66 66 67 67 return fun; 68 68 } … … 76 76 assert(fun->dev == NULL); 77 77 assert(fun->child == NULL); 78 78 79 79 clean_match_ids(&fun->match_ids); 80 80 free(fun->name); … … 125 125 { 126 126 fun_node_t *fun; 127 127 128 128 assert(fibril_rwlock_is_locked(&tree->rwlock)); 129 129 130 130 ht_link_t *link = hash_table_find(&tree->devman_functions, &handle); 131 131 if (link == NULL) 132 132 return NULL; 133 133 134 134 fun = hash_table_get_inst(link, fun_node_t, devman_fun); 135 135 136 136 return fun; 137 137 } … … 146 146 { 147 147 fun_node_t *fun = NULL; 148 148 149 149 fibril_rwlock_read_lock(&tree->rwlock); 150 150 151 151 fun = find_fun_node_no_lock(tree, handle); 152 152 if (fun != NULL) 153 153 fun_add_ref(fun); 154 154 155 155 fibril_rwlock_read_unlock(&tree->rwlock); 156 156 157 157 return fun; 158 158 } … … 170 170 assert(fibril_rwlock_is_write_locked(&tree->rwlock)); 171 171 assert(fun->name != NULL); 172 172 173 173 size_t pathsize = (str_size(fun->name) + 1); 174 174 if (parent != NULL) 175 175 pathsize += str_size(parent->pathname) + 1; 176 176 177 177 fun->pathname = (char *) malloc(pathsize); 178 178 if (fun->pathname == NULL) { … … 180 180 return false; 181 181 } 182 182 183 183 if (parent != NULL) { 184 184 str_cpy(fun->pathname, pathsize, parent->pathname); … … 188 188 str_cpy(fun->pathname, pathsize, fun->name); 189 189 } 190 190 191 191 return true; 192 192 } … … 209 209 210 210 fibril_rwlock_read_lock(&tree->rwlock); 211 211 212 212 fun_node_t *fun = tree->root_node; 213 213 fun_add_ref(fun); … … 219 219 char *next_path_elem = NULL; 220 220 bool cont = (rel_path[1] != '\0'); 221 221 222 222 while (cont && fun != NULL) { 223 223 next_path_elem = get_path_elem_end(rel_path + 1); … … 228 228 cont = false; 229 229 } 230 230 231 231 fun_node_t *cfun = find_node_child(tree, fun, rel_path + 1); 232 232 fun_del_ref(fun); 233 233 fun = cfun; 234 234 235 235 if (cont) { 236 236 /* Restore the original path. */ … … 239 239 rel_path = next_path_elem; 240 240 } 241 241 242 242 fibril_rwlock_read_unlock(&tree->rwlock); 243 243 244 244 return fun; 245 245 } … … 299 299 { 300 300 dev_node_t *dev; 301 301 302 302 fibril_rwlock_write_lock(&device_tree.rwlock); 303 303 304 304 if (fun->state == FUN_ON_LINE) { 305 305 fibril_rwlock_write_unlock(&device_tree.rwlock); … … 308 308 return EOK; 309 309 } 310 310 311 311 if (fun->ftype == fun_inner) { 312 312 dev = create_dev_node(); … … 315 315 return ENOMEM; 316 316 } 317 317 318 318 insert_dev_node(&device_tree, dev, fun); 319 319 dev_add_ref(dev); 320 320 } 321 321 322 322 log_msg(LOG_DEFAULT, LVL_DEBUG, "devman_add_function(fun=\"%s\")", fun->pathname); 323 323 324 324 if (fun->ftype == fun_inner) { 325 325 dev = fun->child; 326 326 assert(dev != NULL); 327 327 328 328 /* Give one reference over to assign_driver_fibril(). */ 329 329 dev_add_ref(dev); 330 330 331 331 /* 332 332 * Try to find a suitable driver and assign it to the device. We do … … 347 347 } else 348 348 loc_register_tree_function(fun, &device_tree); 349 349 350 350 fun->state = FUN_ON_LINE; 351 351 fibril_rwlock_write_unlock(&device_tree.rwlock); 352 352 353 353 return EOK; 354 354 } … … 357 357 { 358 358 errno_t rc; 359 359 360 360 fibril_rwlock_write_lock(&device_tree.rwlock); 361 361 362 362 if (fun->state == FUN_OFF_LINE) { 363 363 fibril_rwlock_write_unlock(&device_tree.rwlock); … … 366 366 return EOK; 367 367 } 368 368 369 369 if (fun->ftype == fun_inner) { 370 370 log_msg(LOG_DEFAULT, LVL_DEBUG, "Offlining inner function %s.", 371 371 fun->pathname); 372 372 373 373 if (fun->child != NULL) { 374 374 dev_node_t *dev = fun->child; 375 375 device_state_t dev_state; 376 376 377 377 dev_add_ref(dev); 378 378 dev_state = dev->state; 379 379 380 380 fibril_rwlock_write_unlock(&device_tree.rwlock); 381 381 … … 388 388 } 389 389 } 390 390 391 391 /* Verify that driver removed all functions */ 392 392 fibril_rwlock_read_lock(&device_tree.rwlock); … … 396 396 return EIO; 397 397 } 398 398 399 399 driver_t *driver = dev->drv; 400 400 fibril_rwlock_read_unlock(&device_tree.rwlock); 401 401 402 402 if (driver) 403 403 detach_driver(&device_tree, dev); 404 404 405 405 fibril_rwlock_write_lock(&device_tree.rwlock); 406 406 remove_dev_node(&device_tree, dev); 407 407 408 408 /* Delete ref created when node was inserted */ 409 409 dev_del_ref(dev); … … 419 419 return EIO; 420 420 } 421 421 422 422 fun->service_id = 0; 423 423 } 424 424 425 425 fun->state = FUN_OFF_LINE; 426 426 fibril_rwlock_write_unlock(&device_tree.rwlock); 427 427 428 428 return EOK; 429 429 } -
uspace/srv/devman/loc.c
r3061bc1 ra35b458 43 43 char *loc_pathname = NULL; 44 44 char *loc_name = NULL; 45 45 46 46 assert(fibril_rwlock_is_locked(&tree->rwlock)); 47 47 48 48 asprintf(&loc_name, "%s", fun->pathname); 49 49 if (loc_name == NULL) 50 50 return; 51 51 52 52 replace_char(loc_name, '/', LOC_SEPARATOR); 53 53 54 54 asprintf(&loc_pathname, "%s/%s", LOC_DEVICE_NAMESPACE, 55 55 loc_name); … … 58 58 return; 59 59 } 60 60 61 61 loc_service_register(loc_pathname, &fun->service_id); 62 62 63 63 tree_add_loc_function(tree, fun); 64 64 65 65 free(loc_name); 66 66 free(loc_pathname); … … 77 77 { 78 78 fun_node_t *fun = NULL; 79 79 80 80 fibril_rwlock_read_lock(&tree->rwlock); 81 81 ht_link_t *link = hash_table_find(&tree->loc_functions, &service_id); … … 85 85 } 86 86 fibril_rwlock_read_unlock(&tree->rwlock); 87 87 88 88 return fun; 89 89 } … … 92 92 { 93 93 assert(fibril_rwlock_is_write_locked(&tree->rwlock)); 94 94 95 95 hash_table_insert(&tree->loc_functions, &fun->loc_fun); 96 96 } … … 99 99 { 100 100 assert(fibril_rwlock_is_write_locked(&tree->rwlock)); 101 101 102 102 hash_table_remove(&tree->loc_functions, &fun->service_id); 103 103 } -
uspace/srv/devman/main.c
r3061bc1 ra35b458 71 71 devman_handle_t handle = IPC_GET_ARG2(*icall); 72 72 dev_node_t *dev = NULL; 73 73 74 74 fun_node_t *fun = find_fun_node(&device_tree, handle); 75 75 if (fun == NULL) { … … 77 77 } else { 78 78 fibril_rwlock_read_lock(&device_tree.rwlock); 79 79 80 80 dev = fun->dev; 81 81 if (dev != NULL) 82 82 dev_add_ref(dev); 83 83 84 84 fibril_rwlock_read_unlock(&device_tree.rwlock); 85 85 } 86 86 87 87 /* 88 88 * For a valid function to connect to we need a device. The root … … 97 97 goto cleanup; 98 98 } 99 99 100 100 if (fun == NULL) { 101 101 log_msg(LOG_DEFAULT, LVL_ERROR, NAME ": devman_forward error - cannot " … … 105 105 goto cleanup; 106 106 } 107 107 108 108 fibril_rwlock_read_lock(&device_tree.rwlock); 109 109 110 110 /* Connect to the specified function */ 111 111 driver_t *driver = dev->drv; 112 112 113 113 fibril_rwlock_read_unlock(&device_tree.rwlock); 114 114 115 115 if (driver == NULL) { 116 116 log_msg(LOG_DEFAULT, LVL_ERROR, "IPC forwarding refused - " \ … … 119 119 goto cleanup; 120 120 } 121 121 122 122 if (!driver->sess) { 123 123 log_msg(LOG_DEFAULT, LVL_ERROR, … … 126 126 goto cleanup; 127 127 } 128 128 129 129 if (fun != NULL) { 130 130 log_msg(LOG_DEFAULT, LVL_DEBUG, … … 136 136 dev->pfun->pathname, driver->name); 137 137 } 138 138 139 139 async_exch_t *exch = async_exchange_begin(driver->sess); 140 140 async_forward_fast(iid, exch, INTERFACE_DDF_CLIENT, handle, 0, IPC_FF_NONE); 141 141 async_exchange_end(exch); 142 142 143 143 cleanup: 144 144 if (dev != NULL) 145 145 dev_del_ref(dev); 146 146 147 147 if (fun != NULL) 148 148 fun_del_ref(fun); … … 154 154 devman_handle_t handle = IPC_GET_ARG2(*icall); 155 155 dev_node_t *dev = NULL; 156 156 157 157 fun_node_t *fun = find_fun_node(&device_tree, handle); 158 158 if (fun == NULL) { … … 160 160 } else { 161 161 fibril_rwlock_read_lock(&device_tree.rwlock); 162 162 163 163 dev = fun->dev; 164 164 if (dev != NULL) 165 165 dev_add_ref(dev); 166 166 167 167 fibril_rwlock_read_unlock(&device_tree.rwlock); 168 168 } 169 169 170 170 /* 171 171 * For a valid function to connect to we need a device. The root … … 180 180 goto cleanup; 181 181 } 182 182 183 183 driver_t *driver = NULL; 184 184 185 185 fibril_rwlock_read_lock(&device_tree.rwlock); 186 186 187 187 /* Connect to parent function of a device (or device function). */ 188 188 if (dev->pfun->dev != NULL) 189 189 driver = dev->pfun->dev->drv; 190 190 191 191 devman_handle_t fun_handle = dev->pfun->handle; 192 192 193 193 fibril_rwlock_read_unlock(&device_tree.rwlock); 194 194 195 195 if (driver == NULL) { 196 196 log_msg(LOG_DEFAULT, LVL_ERROR, "IPC forwarding refused - " \ … … 199 199 goto cleanup; 200 200 } 201 201 202 202 if (!driver->sess) { 203 203 log_msg(LOG_DEFAULT, LVL_ERROR, … … 206 206 goto cleanup; 207 207 } 208 208 209 209 if (fun != NULL) { 210 210 log_msg(LOG_DEFAULT, LVL_DEBUG, … … 216 216 dev->pfun->pathname, driver->name); 217 217 } 218 218 219 219 async_exch_t *exch = async_exchange_begin(driver->sess); 220 220 async_forward_fast(iid, exch, INTERFACE_DDF_DRIVER, fun_handle, 0, IPC_FF_NONE); 221 221 async_exchange_end(exch); 222 222 223 223 cleanup: 224 224 if (dev != NULL) 225 225 dev_del_ref(dev); 226 226 227 227 if (fun != NULL) 228 228 fun_del_ref(fun); … … 233 233 iface_t iface = IPC_GET_ARG1(*icall); 234 234 service_id_t service_id = IPC_GET_ARG2(*icall); 235 235 236 236 fun_node_t *fun = find_loc_tree_function(&device_tree, service_id); 237 237 238 238 fibril_rwlock_read_lock(&device_tree.rwlock); 239 239 240 240 if ((fun == NULL) || (fun->dev == NULL) || (fun->dev->drv == NULL)) { 241 241 log_msg(LOG_DEFAULT, LVL_WARN, "devman_forward(): function " … … 245 245 return; 246 246 } 247 247 248 248 dev_node_t *dev = fun->dev; 249 249 driver_t *driver = dev->drv; 250 250 devman_handle_t handle = fun->handle; 251 251 252 252 fibril_rwlock_read_unlock(&device_tree.rwlock); 253 253 254 254 async_exch_t *exch = async_exchange_begin(driver->sess); 255 255 async_forward_fast(iid, exch, iface, handle, 0, IPC_FF_NONE); 256 256 async_exchange_end(exch); 257 257 258 258 log_msg(LOG_DEFAULT, LVL_DEBUG, 259 259 "Forwarding service request for `%s' function to driver `%s'.", 260 260 fun->pathname, driver->name); 261 261 262 262 fun_del_ref(fun); 263 263 } … … 266 266 { 267 267 client_t *client; 268 268 269 269 client = calloc(1, sizeof(client_t)); 270 270 if (client == NULL) 271 271 return NULL; 272 272 273 273 fibril_mutex_initialize(&client->mutex); 274 274 return client; … … 284 284 { 285 285 log_msg(LOG_DEFAULT, LVL_DEBUG, "devman_init - looking for available drivers."); 286 286 287 287 /* Initialize list of available drivers. */ 288 288 init_driver_list(&drivers_list); … … 292 292 return false; 293 293 } 294 294 295 295 log_msg(LOG_DEFAULT, LVL_DEBUG, "devman_init - list of drivers has been initialized."); 296 296 297 297 /* Create root device node. */ 298 298 if (!init_device_tree(&device_tree, &drivers_list)) { … … 300 300 return false; 301 301 } 302 302 303 303 /* 304 304 * Caution: As the device manager is not a real loc … … 309 309 */ 310 310 loc_server_register(NAME); 311 311 312 312 return true; 313 313 } … … 316 316 { 317 317 printf("%s: HelenOS Device Manager\n", NAME); 318 318 319 319 errno_t rc = log_init(NAME); 320 320 if (rc != EOK) { … … 322 322 return rc; 323 323 } 324 324 325 325 /* Set handlers for incoming connections. */ 326 326 async_set_client_data_constructor(devman_client_data_create); 327 327 async_set_client_data_destructor(devman_client_data_destroy); 328 328 329 329 port_id_t port; 330 330 rc = async_create_port(INTERFACE_DDF_DRIVER, … … 334 334 return rc; 335 335 } 336 336 337 337 rc = async_create_port(INTERFACE_DDF_CLIENT, 338 338 devman_connection_client, NULL, &port); … … 341 341 return rc; 342 342 } 343 343 344 344 rc = async_create_port(INTERFACE_DEVMAN_DEVICE, 345 345 devman_connection_device, NULL, &port); … … 348 348 return rc; 349 349 } 350 350 351 351 rc = async_create_port(INTERFACE_DEVMAN_PARENT, 352 352 devman_connection_parent, NULL, &port); … … 355 355 return rc; 356 356 } 357 357 358 358 async_set_fallback_port_handler(devman_forward, NULL); 359 359 360 360 if (!devman_init()) { 361 361 log_msg(LOG_DEFAULT, LVL_ERROR, "Error while initializing service."); 362 362 return -1; 363 363 } 364 364 365 365 /* Register device manager at naming service. */ 366 366 rc = service_register(SERVICE_DEVMAN); … … 369 369 return rc; 370 370 } 371 371 372 372 printf("%s: Accepting connections.\n", NAME); 373 373 task_retval(0); 374 374 async_manager(); 375 375 376 376 /* Never reached. */ 377 377 return 0; -
uspace/srv/devman/match.c
r3061bc1 ra35b458 69 69 link_t *drv_head = &drv->match_ids.ids.head; 70 70 link_t *dev_head = &dev->pfun->match_ids.ids.head; 71 71 72 72 if (list_empty(&drv->match_ids.ids) || 73 73 list_empty(&dev->pfun->match_ids.ids)) { 74 74 return 0; 75 75 } 76 76 77 77 /* 78 78 * Go through all pairs, return the highest score obtained. 79 79 */ 80 80 int highest_score = 0; 81 81 82 82 link_t *drv_link = drv->match_ids.ids.head.next; 83 83 while (drv_link != drv_head) { … … 86 86 match_id_t *drv_id = list_get_instance(drv_link, match_id_t, link); 87 87 match_id_t *dev_id = list_get_instance(dev_link, match_id_t, link); 88 88 89 89 int score = compute_match_score(drv_id, dev_id); 90 90 if (score > highest_score) { … … 94 94 dev_link = dev_link->next; 95 95 } 96 96 97 97 drv_link = drv_link->next; 98 98 } 99 99 100 100 return highest_score; 101 101 } … … 111 111 char *res = NULL; 112 112 size_t len = get_nonspace_len(*buf); 113 113 114 114 if (len > 0) { 115 115 res = malloc(len + 1); … … 119 119 } 120 120 } 121 121 122 122 return res; 123 123 } … … 141 141 char *id = NULL; 142 142 int ids_read = 0; 143 143 144 144 while (true) { 145 145 /* skip spaces */ … … 151 151 continue; 152 152 } 153 153 154 154 /* read score */ 155 155 score = strtoul(buf, &buf, 10); 156 156 157 157 /* skip spaces */ 158 158 if (!skip_spaces(&buf)) 159 159 break; 160 160 161 161 /* read id */ 162 162 id = read_match_id(&buf); 163 163 if (NULL == id) 164 164 break; 165 165 166 166 /* create new match_id structure */ 167 167 match_id_t *mid = create_match_id(); 168 168 mid->id = id; 169 169 mid->score = score; 170 170 171 171 /* add it to the list */ 172 172 add_match_id(ids, mid); 173 173 174 174 ids_read++; 175 175 } 176 176 177 177 return ids_read > 0; 178 178 } … … 194 194 { 195 195 log_msg(LOG_DEFAULT, LVL_DEBUG, "read_match_ids(conf_path=\"%s\")", conf_path); 196 196 197 197 bool suc = false; 198 198 char *buf = NULL; … … 201 201 size_t len = 0; 202 202 vfs_stat_t st; 203 203 204 204 errno_t rc = vfs_lookup_open(conf_path, WALK_REGULAR, MODE_READ, &fd); 205 205 if (rc != EOK) { … … 209 209 } 210 210 opened = true; 211 211 212 212 rc = vfs_stat(fd, &st); 213 213 if (rc != EOK) { … … 222 222 goto cleanup; 223 223 } 224 224 225 225 buf = malloc(len + 1); 226 226 if (buf == NULL) { … … 229 229 goto cleanup; 230 230 } 231 231 232 232 size_t read_bytes; 233 233 rc = vfs_read(fd, (aoff64_t []) {0}, buf, len, &read_bytes); … … 238 238 } 239 239 buf[read_bytes] = 0; 240 240 241 241 suc = parse_match_ids(buf, ids); 242 242 243 243 cleanup: 244 244 free(buf); 245 245 246 246 if (opened) 247 247 vfs_put(fd); 248 248 249 249 return suc; 250 250 } -
uspace/srv/devman/util.c
r3061bc1 ra35b458 41 41 int base_len = str_size(base_path); 42 42 int size = base_len + 2 * str_size(name) + str_size(ext) + 3; 43 43 44 44 res = malloc(size); 45 45 46 46 if (res) { 47 47 str_cpy(res, size, base_path); … … 55 55 str_append(res, size, ext); 56 56 } 57 57 58 58 return res; 59 59 } … … 82 82 { 83 83 size_t len = 0; 84 84 85 85 while(*str != '\0' && !isspace(*str)) { 86 86 len++;
Note:
See TracChangeset
for help on using the changeset viewer.