Changes in uspace/srv/devman/drv_conn.c [5a6cc679:a35b458] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/devman/drv_conn.c
r5a6cc679 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:
Note:
See TracChangeset
for help on using the changeset viewer.