Changes in uspace/lib/c/generic/devman.c [e6211f8:1a5b252] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/devman.c
re6211f8 r1a5b252 1 1 /* 2 2 * Copyright (c) 2007 Josef Cejka 3 * Copyright (c) 20 09Jiri Svoboda3 * Copyright (c) 2011 Jiri Svoboda 4 4 * Copyright (c) 2010 Lenka Trochtova 5 5 * All rights reserved. … … 35 35 */ 36 36 37 #include <adt/list.h> 37 38 #include <str.h> 38 39 #include <ipc/services.h> … … 88 89 if (devman_driver_block_sess == NULL) 89 90 devman_driver_block_sess = 90 service_connect_blocking(EXCHANGE_ SERIALIZE,91 service_connect_blocking(EXCHANGE_PARALLEL, 91 92 SERVICE_DEVMAN, DEVMAN_DRIVER, 0); 92 93 } … … 137 138 if (devman_driver_sess == NULL) 138 139 devman_driver_sess = 139 service_connect(EXCHANGE_ SERIALIZE, SERVICE_DEVMAN,140 service_connect(EXCHANGE_PARALLEL, SERVICE_DEVMAN, 140 141 DEVMAN_DRIVER, 0); 141 142 … … 194 195 195 196 exch = devman_exchange_begin(DEVMAN_DRIVER); 196 async_connect_to_me(exch, 0, 0, 0, NULL);197 async_connect_to_me(exch, 0, 0, 0, conn, NULL); 197 198 devman_exchange_end(exch); 198 199 … … 231 232 } 232 233 233 link_t *link = match_ids->ids.next;234 234 match_id_t *match_id = NULL; 235 235 236 while (link != &match_ids->ids) {236 list_foreach(match_ids->ids, link) { 237 237 match_id = list_get_instance(link, match_id_t, link); 238 238 … … 255 255 return retval; 256 256 } 257 258 link = link->next;259 257 } 260 258 … … 273 271 } 274 272 275 int devman_add_device_to_c lass(devman_handle_t devman_handle,276 const char *c lass_name)273 int devman_add_device_to_category(devman_handle_t devman_handle, 274 const char *cat_name) 277 275 { 278 276 async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_DRIVER); 279 277 280 278 ipc_call_t answer; 281 aid_t req = async_send_1(exch, DEVMAN_ADD_DEVICE_TO_C LASS,279 aid_t req = async_send_1(exch, DEVMAN_ADD_DEVICE_TO_CATEGORY, 282 280 devman_handle, &answer); 283 sysarg_t retval = async_data_write_start(exch, c lass_name,284 str_size(c lass_name));281 sysarg_t retval = async_data_write_start(exch, cat_name, 282 str_size(cat_name)); 285 283 286 284 devman_exchange_end(exch); … … 310 308 } 311 309 310 /** Remove function from device. 311 * 312 * Request devman to remove function owned by this driver task. 313 * @param funh Devman handle of the function 314 * 315 * @return EOK on success or negative error code. 316 */ 317 int devman_remove_function(devman_handle_t funh) 318 { 319 async_exch_t *exch; 320 sysarg_t retval; 321 322 exch = devman_exchange_begin_blocking(DEVMAN_DRIVER); 323 retval = async_req_1_0(exch, DEVMAN_REMOVE_FUNCTION, (sysarg_t) funh); 324 devman_exchange_end(exch); 325 326 return (int) retval; 327 } 328 329 int devman_drv_fun_online(devman_handle_t funh) 330 { 331 async_exch_t *exch = devman_exchange_begin(DEVMAN_DRIVER); 332 if (exch == NULL) 333 return ENOMEM; 334 335 sysarg_t retval = async_req_1_0(exch, DEVMAN_DRV_FUN_ONLINE, funh); 336 337 devman_exchange_end(exch); 338 return (int) retval; 339 } 340 341 int devman_drv_fun_offline(devman_handle_t funh) 342 { 343 async_exch_t *exch = devman_exchange_begin(DEVMAN_DRIVER); 344 if (exch == NULL) 345 return ENOMEM; 346 347 sysarg_t retval = async_req_1_0(exch, DEVMAN_DRV_FUN_OFFLINE, funh); 348 349 devman_exchange_end(exch); 350 return (int) retval; 351 } 352 312 353 async_sess_t *devman_parent_device_connect(exch_mgmt_t mgmt, 313 354 devman_handle_t handle, unsigned int flags) … … 325 366 } 326 367 327 int devman_ device_get_handle(const char *pathname, devman_handle_t *handle,368 int devman_fun_get_handle(const char *pathname, devman_handle_t *handle, 328 369 unsigned int flags) 329 370 { … … 335 376 exch = devman_exchange_begin(DEVMAN_CLIENT); 336 377 if (exch == NULL) 337 return errno;378 return ENOMEM; 338 379 } 339 380 … … 366 407 } 367 408 368 int devman_device_get_handle_by_class(const char *classname,369 const char *devname, devman_handle_t *handle, unsigned int flags)409 static int devman_get_str_internal(sysarg_t method, sysarg_t arg1, char *buf, 410 size_t buf_size) 370 411 { 371 412 async_exch_t *exch; 372 373 if (flags & IPC_FLAG_BLOCKING) 374 exch = devman_exchange_begin_blocking(DEVMAN_CLIENT); 375 else { 376 exch = devman_exchange_begin(DEVMAN_CLIENT); 377 if (exch == NULL) 378 return errno; 379 } 413 ipc_call_t dreply; 414 size_t act_size; 415 sysarg_t dretval; 416 417 exch = devman_exchange_begin_blocking(LOC_PORT_CONSUMER); 380 418 381 419 ipc_call_t answer; 382 aid_t req = async_send_1(exch, DEVMAN_DEVICE_GET_HANDLE_BY_CLASS,383 flags, &answer);384 sysarg_t retval = async_data_write_start(exch, classname,385 str_size(classname));386 387 if (retval != EOK) {388 devman_exchange_end(exch);420 aid_t req = async_send_1(exch, method, arg1, &answer); 421 aid_t dreq = async_data_read(exch, buf, buf_size - 1, &dreply); 422 async_wait_for(dreq, &dretval); 423 424 devman_exchange_end(exch); 425 426 if (dretval != EOK) { 389 427 async_wait_for(req, NULL); 390 return retval; 391 } 392 393 retval = async_data_write_start(exch, devname, 394 str_size(devname)); 395 396 devman_exchange_end(exch); 397 398 if (retval != EOK) { 399 async_wait_for(req, NULL); 400 return retval; 401 } 402 428 return dretval; 429 } 430 431 sysarg_t retval; 403 432 async_wait_for(req, &retval); 404 433 405 if (retval != EOK) { 406 if (handle != NULL) 407 *handle = (devman_handle_t) -1; 408 409 return retval; 410 } 411 412 if (handle != NULL) 413 *handle = (devman_handle_t) IPC_GET_ARG1(answer); 414 415 return retval; 416 } 417 418 int devman_get_device_path(devman_handle_t handle, char *path, size_t path_size) 434 if (retval != EOK) 435 return retval; 436 437 act_size = IPC_GET_ARG2(dreply); 438 assert(act_size <= buf_size - 1); 439 buf[act_size] = '\0'; 440 441 return EOK; 442 } 443 444 int devman_fun_get_path(devman_handle_t handle, char *buf, size_t buf_size) 445 { 446 return devman_get_str_internal(DEVMAN_FUN_GET_PATH, handle, buf, 447 buf_size); 448 } 449 450 int devman_fun_get_name(devman_handle_t handle, char *buf, size_t buf_size) 451 { 452 return devman_get_str_internal(DEVMAN_FUN_GET_NAME, handle, buf, 453 buf_size); 454 } 455 456 int devman_fun_online(devman_handle_t funh) 419 457 { 420 458 async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT); 421 459 if (exch == NULL) 422 return errno; 423 460 return ENOMEM; 461 462 sysarg_t retval = async_req_1_0(exch, DEVMAN_FUN_ONLINE, funh); 463 464 devman_exchange_end(exch); 465 return (int) retval; 466 } 467 468 int devman_fun_offline(devman_handle_t funh) 469 { 470 async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT); 471 if (exch == NULL) 472 return ENOMEM; 473 474 sysarg_t retval = async_req_1_0(exch, DEVMAN_FUN_OFFLINE, funh); 475 476 devman_exchange_end(exch); 477 return (int) retval; 478 } 479 480 static int devman_get_handles_once(sysarg_t method, sysarg_t arg1, 481 devman_handle_t *handle_buf, size_t buf_size, size_t *act_size) 482 { 483 async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_CLIENT); 484 424 485 ipc_call_t answer; 425 aid_t req = async_send_1(exch, DEVMAN_DEVICE_GET_DEVICE_PATH, 426 handle, &answer); 427 428 ipc_call_t data_request_call; 429 aid_t data_request = async_data_read(exch, path, path_size, 430 &data_request_call); 431 432 devman_exchange_end(exch); 433 434 if (data_request == 0) { 486 aid_t req = async_send_1(exch, method, arg1, &answer); 487 int rc = async_data_read_start(exch, handle_buf, buf_size); 488 489 devman_exchange_end(exch); 490 491 if (rc != EOK) { 435 492 async_wait_for(req, NULL); 436 return ENOMEM; 437 } 438 439 sysarg_t data_request_rc; 440 async_wait_for(data_request, &data_request_rc); 441 442 sysarg_t opening_request_rc; 443 async_wait_for(req, &opening_request_rc); 444 445 if (data_request_rc != EOK) { 446 /* Prefer the return code of the opening request. */ 447 if (opening_request_rc != EOK) 448 return (int) opening_request_rc; 449 else 450 return (int) data_request_rc; 451 } 452 453 if (opening_request_rc != EOK) 454 return (int) opening_request_rc; 455 456 /* To be on the safe-side. */ 457 path[path_size - 1] = 0; 458 size_t transferred_size = IPC_GET_ARG2(data_request_call); 459 if (transferred_size >= path_size) 460 return ELIMIT; 461 462 /* Terminate the string (trailing 0 not send over IPC). */ 463 path[transferred_size] = 0; 493 return rc; 494 } 495 496 sysarg_t retval; 497 async_wait_for(req, &retval); 498 499 if (retval != EOK) { 500 return retval; 501 } 502 503 *act_size = IPC_GET_ARG1(answer); 464 504 return EOK; 465 505 } 466 506 507 /** Get list of handles. 508 * 509 * Returns an allocated array of handles. 510 * 511 * @param method IPC method 512 * @param arg1 IPC argument 1 513 * @param data Place to store pointer to array of handles 514 * @param count Place to store number of handles 515 * @return EOK on success or negative error code 516 */ 517 static int devman_get_handles_internal(sysarg_t method, sysarg_t arg1, 518 devman_handle_t **data, size_t *count) 519 { 520 devman_handle_t *handles; 521 size_t act_size; 522 size_t alloc_size; 523 int rc; 524 525 *data = NULL; 526 act_size = 0; /* silence warning */ 527 528 rc = devman_get_handles_once(method, arg1, NULL, 0, 529 &act_size); 530 if (rc != EOK) 531 return rc; 532 533 alloc_size = act_size; 534 handles = malloc(alloc_size); 535 if (handles == NULL) 536 return ENOMEM; 537 538 while (true) { 539 rc = devman_get_handles_once(method, arg1, handles, alloc_size, 540 &act_size); 541 if (rc != EOK) 542 return rc; 543 544 if (act_size <= alloc_size) 545 break; 546 547 alloc_size *= 2; 548 free(handles); 549 550 handles = malloc(alloc_size); 551 if (handles == NULL) 552 return ENOMEM; 553 } 554 555 *count = act_size / sizeof(devman_handle_t); 556 *data = handles; 557 return EOK; 558 } 559 560 int devman_fun_get_child(devman_handle_t funh, devman_handle_t *devh) 561 { 562 async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT); 563 if (exch == NULL) 564 return ENOMEM; 565 566 sysarg_t retval = async_req_1_1(exch, DEVMAN_FUN_GET_CHILD, 567 funh, devh); 568 569 devman_exchange_end(exch); 570 return (int) retval; 571 } 572 573 int devman_dev_get_functions(devman_handle_t devh, devman_handle_t **funcs, 574 size_t *count) 575 { 576 return devman_get_handles_internal(DEVMAN_DEV_GET_FUNCTIONS, 577 devh, funcs, count); 578 } 579 580 int devman_fun_sid_to_handle(service_id_t sid, devman_handle_t *handle) 581 { 582 async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT); 583 if (exch == NULL) 584 return ENOMEM; 585 586 sysarg_t retval = async_req_1_1(exch, DEVMAN_FUN_SID_TO_HANDLE, 587 sid, handle); 588 589 devman_exchange_end(exch); 590 return (int) retval; 591 } 592 467 593 /** @} 468 594 */
Note:
See TracChangeset
for help on using the changeset viewer.