Changes in uspace/srv/devman/main.c [0418050:6e50466] in mainline
- File:
-
- 1 edited
-
uspace/srv/devman/main.c (modified) (23 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/devman/main.c
r0418050 r6e50466 75 75 iid = async_get_call(&icall); 76 76 if (IPC_GET_IMETHOD(icall) != DEVMAN_DRIVER_REGISTER) { 77 async_answer_0(iid, EREFUSED);77 ipc_answer_0(iid, EREFUSED); 78 78 return NULL; 79 79 } … … 84 84 int rc = async_data_write_accept((void **) &drv_name, true, 0, 0, 0, 0); 85 85 if (rc != EOK) { 86 async_answer_0(iid, rc);86 ipc_answer_0(iid, rc); 87 87 return NULL; 88 88 } … … 98 98 free(drv_name); 99 99 drv_name = NULL; 100 async_answer_0(iid, ENOENT);100 ipc_answer_0(iid, ENOENT); 101 101 return NULL; 102 102 } … … 110 110 ipc_callid_t callid = async_get_call(&call); 111 111 if (IPC_GET_IMETHOD(call) != IPC_M_CONNECT_TO_ME) { 112 async_answer_0(callid, ENOTSUP);113 async_answer_0(iid, ENOTSUP);112 ipc_answer_0(callid, ENOTSUP); 113 ipc_answer_0(iid, ENOTSUP); 114 114 return NULL; 115 115 } … … 121 121 driver->name); 122 122 123 async_answer_0(callid, EOK);124 async_answer_0(iid, EOK);123 ipc_answer_0(callid, EOK); 124 ipc_answer_0(iid, EOK); 125 125 126 126 return driver; … … 144 144 printf(NAME ": ERROR: devman_receive_match_id - invalid " 145 145 "protocol.\n"); 146 async_answer_0(callid, EINVAL);146 ipc_answer_0(callid, EINVAL); 147 147 delete_match_id(match_id); 148 148 return EINVAL; … … 152 152 printf(NAME ": ERROR: devman_receive_match_id - failed to " 153 153 "allocate match id.\n"); 154 async_answer_0(callid, ENOMEM);154 ipc_answer_0(callid, ENOMEM); 155 155 return ENOMEM; 156 156 } 157 157 158 async_answer_0(callid, EOK);158 ipc_answer_0(callid, EOK); 159 159 160 160 match_id->score = IPC_GET_ARG1(call); … … 199 199 static int assign_driver_fibril(void *arg) 200 200 { 201 dev_node_t *dev_node = (dev_node_t *) arg;202 assign_driver( dev_node, &drivers_list, &device_tree);201 node_t *node = (node_t *) arg; 202 assign_driver(node, &drivers_list, &device_tree); 203 203 return EOK; 204 204 } 205 205 206 /** Handle functionregistration.206 /** Handle child device registration. 207 207 * 208 208 * Child devices are registered by their parent's device driver. 209 209 */ 210 static void devman_add_function(ipc_callid_t callid, ipc_call_t *call) 211 { 212 fun_type_t ftype = (fun_type_t) IPC_GET_ARG1(*call); 213 devman_handle_t dev_handle = IPC_GET_ARG2(*call); 214 sysarg_t match_count = IPC_GET_ARG3(*call); 210 static void devman_add_child(ipc_callid_t callid, ipc_call_t *call) 211 { 212 devman_handle_t parent_handle = IPC_GET_ARG1(*call); 213 sysarg_t match_count = IPC_GET_ARG2(*call); 215 214 dev_tree_t *tree = &device_tree; 216 215 217 216 fibril_rwlock_write_lock(&tree->rwlock); 218 219 dev_node_t *dev = NULL; 220 dev_node_t *pdev = find_dev_node_no_lock(&device_tree, dev_handle); 221 222 if (pdev == NULL) { 217 node_t *parent = find_dev_node_no_lock(&device_tree, parent_handle); 218 219 if (parent == NULL) { 223 220 fibril_rwlock_write_unlock(&tree->rwlock); 224 async_answer_0(callid, ENOENT); 225 return; 226 } 227 228 if (ftype != fun_inner && ftype != fun_exposed) { 229 /* Unknown function type */ 230 printf(NAME ": Error, unknown function type provided by driver!\n"); 231 232 fibril_rwlock_write_unlock(&tree->rwlock); 233 async_answer_0(callid, EINVAL); 234 return; 235 } 236 237 char *fun_name = NULL; 238 int rc = async_data_write_accept((void **)&fun_name, true, 0, 0, 0, 0); 221 ipc_answer_0(callid, ENOENT); 222 return; 223 } 224 225 char *dev_name = NULL; 226 int rc = async_data_write_accept((void **)&dev_name, true, 0, 0, 0, 0); 239 227 if (rc != EOK) { 240 228 fibril_rwlock_write_unlock(&tree->rwlock); 241 async_answer_0(callid, rc);242 return; 243 } 244 245 fun_node_t *fun = create_fun_node();246 if (!insert_ fun_node(&device_tree, fun, fun_name, pdev)) {229 ipc_answer_0(callid, rc); 230 return; 231 } 232 233 node_t *node = create_dev_node(); 234 if (!insert_dev_node(&device_tree, node, dev_name, parent)) { 247 235 fibril_rwlock_write_unlock(&tree->rwlock); 248 delete_fun_node(fun); 249 async_answer_0(callid, ENOMEM); 250 return; 251 } 252 253 if (ftype == fun_inner) { 254 dev = create_dev_node(); 255 if (dev == NULL) { 256 fibril_rwlock_write_unlock(&tree->rwlock); 257 delete_fun_node(fun); 258 async_answer_0(callid, ENOMEM); 259 return; 260 } 261 262 insert_dev_node(tree, dev, fun); 236 delete_dev_node(node); 237 ipc_answer_0(callid, ENOMEM); 238 return; 263 239 } 264 240 265 241 fibril_rwlock_write_unlock(&tree->rwlock); 266 242 267 printf(NAME ": devman_add_function %s\n", fun->pathname); 268 269 devman_receive_match_ids(match_count, &fun->match_ids); 270 271 if (ftype == fun_inner) { 272 assert(dev != NULL); 243 printf(NAME ": devman_add_child %s\n", node->pathname); 244 245 devman_receive_match_ids(match_count, &node->match_ids); 246 247 /* 248 * Try to find a suitable driver and assign it to the device. We do 249 * not want to block the current fibril that is used for processing 250 * incoming calls: we will launch a separate fibril to handle the 251 * driver assigning. That is because assign_driver can actually include 252 * task spawning which could take some time. 253 */ 254 fid_t assign_fibril = fibril_create(assign_driver_fibril, node); 255 if (assign_fibril == 0) { 273 256 /* 274 * Try to find a suitable driver and assign it to the device. We do 275 * not want to block the current fibril that is used for processing 276 * incoming calls: we will launch a separate fibril to handle the 277 * driver assigning. That is because assign_driver can actually include 278 * task spawning which could take some time. 257 * Fallback in case we are out of memory. 258 * Probably not needed as we will die soon anyway ;-). 279 259 */ 280 fid_t assign_fibril = fibril_create(assign_driver_fibril, dev); 281 if (assign_fibril == 0) { 282 /* 283 * Fallback in case we are out of memory. 284 * Probably not needed as we will die soon anyway ;-). 285 */ 286 (void) assign_driver_fibril(fun); 287 } else { 288 fibril_add_ready(assign_fibril); 289 } 260 (void) assign_driver_fibril(node); 290 261 } else { 291 devmap_register_tree_function(fun, tree);292 } 293 262 fibril_add_ready(assign_fibril); 263 } 264 294 265 /* Return device handle to parent's driver. */ 295 async_answer_1(callid, EOK, fun->handle);266 ipc_answer_1(callid, EOK, node->handle); 296 267 } 297 268 … … 317 288 * mapper. 318 289 */ 319 class_add_devmap_ function(&class_list, cli);290 class_add_devmap_device(&class_list, cli); 320 291 321 292 free(devmap_pathname); 322 293 } 323 294 324 static void devman_add_ function_to_class(ipc_callid_t callid, ipc_call_t *call)295 static void devman_add_device_to_class(ipc_callid_t callid, ipc_call_t *call) 325 296 { 326 297 devman_handle_t handle = IPC_GET_ARG1(*call); … … 331 302 0, 0, 0, 0); 332 303 if (rc != EOK) { 333 async_answer_0(callid, rc);304 ipc_answer_0(callid, rc); 334 305 return; 335 306 } 336 307 337 fun_node_t *fun = find_fun_node(&device_tree, handle);338 if ( fun== NULL) {339 async_answer_0(callid, ENOENT);308 node_t *dev = find_dev_node(&device_tree, handle); 309 if (dev == NULL) { 310 ipc_answer_0(callid, ENOENT); 340 311 return; 341 312 } 342 313 343 314 dev_class_t *cl = get_dev_class(&class_list, class_name); 344 dev_class_info_t *class_info = add_ function_to_class(fun, cl, NULL);315 dev_class_info_t *class_info = add_device_to_class(dev, cl, NULL); 345 316 346 317 /* Register the device's class alias by devmapper. */ 347 318 devmap_register_class_dev(class_info); 348 319 349 printf(NAME ": function'%s' added to class '%s', class name '%s' was "350 "asigned to it\n", fun->pathname, class_name, class_info->dev_name);351 352 async_answer_0(callid, EOK);320 printf(NAME ": device '%s' added to class '%s', class name '%s' was " 321 "asigned to it\n", dev->pathname, class_name, class_info->dev_name); 322 323 ipc_answer_0(callid, EOK); 353 324 } 354 325 … … 372 343 { 373 344 /* Accept the connection. */ 374 async_answer_0(iid, EOK);345 ipc_answer_0(iid, EOK); 375 346 376 347 driver_t *driver = devman_driver_register(); … … 401 372 cont = false; 402 373 continue; 403 case DEVMAN_ADD_ FUNCTION:404 devman_add_ function(callid, &call);374 case DEVMAN_ADD_CHILD_DEVICE: 375 devman_add_child(callid, &call); 405 376 break; 406 377 case DEVMAN_ADD_DEVICE_TO_CLASS: 407 devman_add_ function_to_class(callid, &call);378 devman_add_device_to_class(callid, &call); 408 379 break; 409 380 default: 410 async_answer_0(callid, EINVAL);381 ipc_answer_0(callid, EINVAL); 411 382 break; 412 383 } … … 416 387 /** Find handle for the device instance identified by the device's path in the 417 388 * device tree. */ 418 static void devman_ function_get_handle(ipc_callid_t iid, ipc_call_t *icall)389 static void devman_device_get_handle(ipc_callid_t iid, ipc_call_t *icall) 419 390 { 420 391 char *pathname; … … 422 393 int rc = async_data_write_accept((void **) &pathname, true, 0, 0, 0, 0); 423 394 if (rc != EOK) { 424 async_answer_0(iid, rc);425 return; 426 } 427 428 fun_node_t *fun = find_fun_node_by_path(&device_tree, pathname);395 ipc_answer_0(iid, rc); 396 return; 397 } 398 399 node_t * dev = find_dev_node_by_path(&device_tree, pathname); 429 400 430 401 free(pathname); 431 402 432 if ( fun== NULL) {433 async_answer_0(iid, ENOENT);434 return; 435 } 436 437 async_answer_1(iid, EOK, fun->handle);403 if (dev == NULL) { 404 ipc_answer_0(iid, ENOENT); 405 return; 406 } 407 408 ipc_answer_1(iid, EOK, dev->handle); 438 409 } 439 410 … … 443 414 { 444 415 /* Accept connection. */ 445 async_answer_0(iid, EOK);416 ipc_answer_0(iid, EOK); 446 417 447 418 bool cont = true; … … 455 426 continue; 456 427 case DEVMAN_DEVICE_GET_HANDLE: 457 devman_ function_get_handle(callid, &call);428 devman_device_get_handle(callid, &call); 458 429 break; 459 430 default: 460 async_answer_0(callid, ENOENT);431 ipc_answer_0(callid, ENOENT); 461 432 } 462 433 } … … 467 438 { 468 439 devman_handle_t handle = IPC_GET_ARG2(*icall); 469 devman_handle_t fwd_h; 470 fun_node_t *fun = NULL; 471 dev_node_t *dev = NULL; 472 473 fun = find_fun_node(&device_tree, handle); 474 if (fun == NULL) 475 dev = find_dev_node(&device_tree, handle); 476 else 477 dev = fun->dev; 478 479 /* 480 * For a valid function to connect to we need a device. The root 481 * function, for example, has no device and cannot be connected to. 482 * This means @c dev needs to be valid regardless whether we are 483 * connecting to a device or to a function. 484 */ 440 441 node_t *dev = find_dev_node(&device_tree, handle); 485 442 if (dev == NULL) { 486 printf(NAME ": devman_forward error - no device or function with " 487 "handle %" PRIun " was found.\n", handle); 488 async_answer_0(iid, ENOENT); 489 return; 490 } 491 492 if (fun == NULL && !drv_to_parent) { 493 printf(NAME ": devman_forward error - cannot connect to " 494 "handle %" PRIun ", refers to a device.\n", handle); 495 async_answer_0(iid, ENOENT); 443 printf(NAME ": devman_forward error - no device with handle %" PRIun 444 " was found.\n", handle); 445 ipc_answer_0(iid, ENOENT); 496 446 return; 497 447 } … … 500 450 501 451 if (drv_to_parent) { 502 /* Connect to parent function of a device (or device function). */ 503 if (dev->pfun->dev != NULL) 504 driver = dev->pfun->dev->drv; 505 fwd_h = dev->pfun->handle; 452 if (dev->parent != NULL) 453 driver = dev->parent->drv; 506 454 } else if (dev->state == DEVICE_USABLE) { 507 /* Connect to the specified function */508 455 driver = dev->drv; 509 456 assert(driver != NULL); 510 511 fwd_h = handle;512 457 } 513 458 … … 515 460 printf(NAME ": devman_forward error - the device is not in %" PRIun 516 461 " usable state.\n", handle); 517 async_answer_0(iid, ENOENT);462 ipc_answer_0(iid, ENOENT); 518 463 return; 519 464 } … … 529 474 driver->name); 530 475 printf("the driver's phone is %" PRIun ").\n", driver->phone); 531 async_answer_0(iid, EINVAL); 532 return; 533 } 534 535 if (fun != NULL) { 536 printf(NAME ": devman_forward: forward connection to function %s to " 537 "driver %s.\n", fun->pathname, driver->name); 538 } else { 539 printf(NAME ": devman_forward: forward connection to device %s to " 540 "driver %s.\n", dev->pfun->pathname, driver->name); 541 } 542 543 async_forward_fast(iid, driver->phone, method, fwd_h, 0, IPC_FF_NONE); 476 ipc_answer_0(iid, EINVAL); 477 return; 478 } 479 480 printf(NAME ": devman_forward: forward connection to device %s to " 481 "driver %s.\n", dev->pathname, driver->name); 482 ipc_forward_fast(iid, driver->phone, method, dev->handle, 0, IPC_FF_NONE); 544 483 } 545 484 … … 549 488 { 550 489 devmap_handle_t devmap_handle = IPC_GET_ARG2(*icall); 551 fun_node_t *fun; 552 dev_node_t *dev; 553 554 fun = find_devmap_tree_function(&device_tree, devmap_handle); 555 if (fun == NULL) 556 fun = find_devmap_class_function(&class_list, devmap_handle); 557 558 if (fun == NULL || fun->dev->drv == NULL) { 559 async_answer_0(iid, ENOENT); 560 return; 561 } 562 563 dev = fun->dev; 490 node_t *dev; 491 492 dev = find_devmap_tree_device(&device_tree, devmap_handle); 493 if (dev == NULL) 494 dev = find_devmap_class_device(&class_list, devmap_handle); 495 496 if (dev == NULL || dev->drv == NULL) { 497 ipc_answer_0(iid, ENOENT); 498 return; 499 } 564 500 565 501 if (dev->state != DEVICE_USABLE || dev->drv->phone <= 0) { 566 async_answer_0(iid, EINVAL);567 return; 568 } 569 570 async_forward_fast(iid, dev->drv->phone, DRIVER_CLIENT, fun->handle, 0,502 ipc_answer_0(iid, EINVAL); 503 return; 504 } 505 506 ipc_forward_fast(iid, dev->drv->phone, DRIVER_CLIENT, dev->handle, 0, 571 507 IPC_FF_NONE); 572 508 printf(NAME ": devman_connection_devmapper: forwarded connection to " 573 "device %s to driver %s.\n", fun->pathname, dev->drv->name);509 "device %s to driver %s.\n", dev->pathname, dev->drv->name); 574 510 } 575 511 … … 599 535 default: 600 536 /* No such interface */ 601 async_answer_0(iid, ENOENT);537 ipc_answer_0(iid, ENOENT); 602 538 } 603 539 } … … 650 586 651 587 /* Register device manager at naming service. */ 652 if (service_register(SERVICE_DEVMAN) != EOK) 588 sysarg_t phonead; 589 if (ipc_connect_to_me(PHONE_NS, SERVICE_DEVMAN, 0, 0, &phonead) != 0) 653 590 return -1; 654 591
Note:
See TracChangeset
for help on using the changeset viewer.
