Changeset 3b5d1535 in mainline for uspace/srv/devman/main.c
- Timestamp:
- 2011-02-23T10:28:21Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- eb48f61
- Parents:
- e936e8e (diff), eb1a2f4 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/devman/main.c
re936e8e r3b5d1535 199 199 static int assign_driver_fibril(void *arg) 200 200 { 201 node_t *node = (node_t *) arg;202 assign_driver( node, &drivers_list, &device_tree);201 dev_node_t *dev_node = (dev_node_t *) arg; 202 assign_driver(dev_node, &drivers_list, &device_tree); 203 203 return EOK; 204 204 } 205 205 206 /** Handle child deviceregistration.206 /** Handle function registration. 207 207 * 208 208 * Child devices are registered by their parent's device driver. 209 209 */ 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); 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); 214 215 dev_tree_t *tree = &device_tree; 215 216 216 217 fibril_rwlock_write_lock(&tree->rwlock); 217 node_t *parent = find_dev_node_no_lock(&device_tree, parent_handle); 218 219 if (parent == NULL) { 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) { 220 223 fibril_rwlock_write_unlock(&tree->rwlock); 221 224 async_answer_0(callid, ENOENT); … … 223 226 } 224 227 225 char *dev_name = NULL; 226 int rc = async_data_write_accept((void **)&dev_name, true, 0, 0, 0, 0); 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); 227 239 if (rc != EOK) { 228 240 fibril_rwlock_write_unlock(&tree->rwlock); … … 231 243 } 232 244 233 node_t *node = create_dev_node();234 if (!insert_ dev_node(&device_tree, node, dev_name, parent)) {245 fun_node_t *fun = create_fun_node(); 246 if (!insert_fun_node(&device_tree, fun, fun_name, pdev)) { 235 247 fibril_rwlock_write_unlock(&tree->rwlock); 236 delete_ dev_node(node);248 delete_fun_node(fun); 237 249 async_answer_0(callid, ENOMEM); 238 250 return; 239 251 } 240 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); 263 } 264 241 265 fibril_rwlock_write_unlock(&tree->rwlock); 242 266 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) { 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); 256 273 /* 257 * Fallback in case we are out of memory. 258 * Probably not needed as we will die soon anyway ;-). 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. 259 279 */ 260 (void) assign_driver_fibril(node); 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 } 261 290 } else { 262 fibril_add_ready(assign_fibril);263 } 264 291 devmap_register_tree_function(fun, tree); 292 } 293 265 294 /* Return device handle to parent's driver. */ 266 async_answer_1(callid, EOK, node->handle);295 async_answer_1(callid, EOK, fun->handle); 267 296 } 268 297 … … 288 317 * mapper. 289 318 */ 290 class_add_devmap_ device(&class_list, cli);319 class_add_devmap_function(&class_list, cli); 291 320 292 321 free(devmap_pathname); 293 322 } 294 323 295 static void devman_add_ device_to_class(ipc_callid_t callid, ipc_call_t *call)324 static void devman_add_function_to_class(ipc_callid_t callid, ipc_call_t *call) 296 325 { 297 326 devman_handle_t handle = IPC_GET_ARG1(*call); … … 306 335 } 307 336 308 node_t *dev = find_dev_node(&device_tree, handle);309 if ( dev== NULL) {337 fun_node_t *fun = find_fun_node(&device_tree, handle); 338 if (fun == NULL) { 310 339 async_answer_0(callid, ENOENT); 311 340 return; … … 313 342 314 343 dev_class_t *cl = get_dev_class(&class_list, class_name); 315 dev_class_info_t *class_info = add_ device_to_class(dev, cl, NULL);344 dev_class_info_t *class_info = add_function_to_class(fun, cl, NULL); 316 345 317 346 /* Register the device's class alias by devmapper. */ 318 347 devmap_register_class_dev(class_info); 319 348 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);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); 322 351 323 352 async_answer_0(callid, EOK); … … 372 401 cont = false; 373 402 continue; 374 case DEVMAN_ADD_ CHILD_DEVICE:375 devman_add_ child(callid, &call);403 case DEVMAN_ADD_FUNCTION: 404 devman_add_function(callid, &call); 376 405 break; 377 406 case DEVMAN_ADD_DEVICE_TO_CLASS: 378 devman_add_ device_to_class(callid, &call);407 devman_add_function_to_class(callid, &call); 379 408 break; 380 409 default: … … 387 416 /** Find handle for the device instance identified by the device's path in the 388 417 * device tree. */ 389 static void devman_ device_get_handle(ipc_callid_t iid, ipc_call_t *icall)418 static void devman_function_get_handle(ipc_callid_t iid, ipc_call_t *icall) 390 419 { 391 420 char *pathname; … … 397 426 } 398 427 399 node_t * dev = find_dev_node_by_path(&device_tree, pathname);428 fun_node_t *fun = find_fun_node_by_path(&device_tree, pathname); 400 429 401 430 free(pathname); 402 431 403 if ( dev== NULL) {432 if (fun == NULL) { 404 433 async_answer_0(iid, ENOENT); 405 434 return; 406 435 } 407 408 async_answer_1(iid, EOK, dev->handle);436 437 async_answer_1(iid, EOK, fun->handle); 409 438 } 410 439 … … 426 455 continue; 427 456 case DEVMAN_DEVICE_GET_HANDLE: 428 devman_ device_get_handle(callid, &call);457 devman_function_get_handle(callid, &call); 429 458 break; 430 459 default: … … 438 467 { 439 468 devman_handle_t handle = IPC_GET_ARG2(*icall); 440 441 node_t *dev = find_dev_node(&device_tree, handle); 442 if (dev == NULL) { 443 printf(NAME ": devman_forward error - no device with handle %" PRIun 444 " was found.\n", handle); 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 if (fun == NULL && dev == NULL) { 480 printf(NAME ": devman_forward error - no device or function with " 481 "handle %" PRIun " was found.\n", handle); 445 482 async_answer_0(iid, ENOENT); 446 483 return; 447 484 } 485 486 if (fun == NULL && !drv_to_parent) { 487 printf(NAME ": devman_forward error - cannot connect to " 488 "handle %" PRIun ", refers to a device.\n", handle); 489 async_answer_0(iid, ENOENT); 490 return; 491 } 448 492 449 493 driver_t *driver = NULL; 450 494 451 495 if (drv_to_parent) { 452 if (dev->parent != NULL) 453 driver = dev->parent->drv; 496 /* Connect to parent function of a device (or device function). */ 497 if (dev->pfun->dev != NULL) 498 driver = dev->pfun->dev->drv; 499 fwd_h = dev->pfun->handle; 454 500 } else if (dev->state == DEVICE_USABLE) { 501 /* Connect to the specified function */ 455 502 driver = dev->drv; 456 503 assert(driver != NULL); 504 505 fwd_h = handle; 457 506 } 458 507 … … 460 509 printf(NAME ": devman_forward error - the device %" PRIun \ 461 510 " (%s) is not in usable state.\n", 462 handle, dev->p athname);511 handle, dev->pfun->pathname); 463 512 async_answer_0(iid, ENOENT); 464 513 return; … … 479 528 } 480 529 481 printf(NAME ": devman_forward: forward connection to device %s to " 482 "driver %s.\n", dev->pathname, driver->name); 483 async_forward_fast(iid, driver->phone, method, dev->handle, 0, IPC_FF_NONE); 530 if (fun != NULL) { 531 printf(NAME ": devman_forward: forward connection to function %s to " 532 "driver %s.\n", fun->pathname, driver->name); 533 } else { 534 printf(NAME ": devman_forward: forward connection to device %s to " 535 "driver %s.\n", dev->pfun->pathname, driver->name); 536 } 537 538 async_forward_fast(iid, driver->phone, method, fwd_h, 0, IPC_FF_NONE); 484 539 } 485 540 … … 489 544 { 490 545 devmap_handle_t devmap_handle = IPC_GET_ARG2(*icall); 491 node_t *dev; 492 493 dev = find_devmap_tree_device(&device_tree, devmap_handle); 494 if (dev == NULL) 495 dev = find_devmap_class_device(&class_list, devmap_handle); 496 497 if (dev == NULL || dev->drv == NULL) { 546 fun_node_t *fun; 547 dev_node_t *dev; 548 549 fun = find_devmap_tree_function(&device_tree, devmap_handle); 550 if (fun == NULL) 551 fun = find_devmap_class_function(&class_list, devmap_handle); 552 553 if (fun == NULL || fun->dev->drv == NULL) { 498 554 async_answer_0(iid, ENOENT); 499 555 return; 500 556 } 557 558 dev = fun->dev; 501 559 502 560 if (dev->state != DEVICE_USABLE || dev->drv->phone <= 0) { … … 505 563 } 506 564 507 async_forward_fast(iid, dev->drv->phone, DRIVER_CLIENT, dev->handle, 0,565 async_forward_fast(iid, dev->drv->phone, DRIVER_CLIENT, fun->handle, 0, 508 566 IPC_FF_NONE); 509 567 printf(NAME ": devman_connection_devmapper: forwarded connection to " 510 "device %s to driver %s.\n", dev->pathname, dev->drv->name);568 "device %s to driver %s.\n", fun->pathname, dev->drv->name); 511 569 } 512 570
Note:
See TracChangeset
for help on using the changeset viewer.