Changes in uspace/srv/fs/devfs/devfs_ops.c [efcebe1:cfd630af] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/devfs/devfs_ops.c
refcebe1 rcfd630af 59 59 typedef struct { 60 60 devmap_handle_t handle; 61 async_sess_t *sess; /**< If NULL, the structure is incomplete. */61 int phone; /**< When < 0, the structure is incomplete. */ 62 62 size_t refcount; 63 63 link_t link; 64 fibril_condvar_t cv; 64 fibril_condvar_t cv; /**< Broadcast when completed. */ 65 65 } device_t; 66 66 … … 232 232 }; 233 233 link_t *lnk; 234 234 235 235 fibril_mutex_lock(&devices_mutex); 236 236 restart: … … 244 244 245 245 dev->handle = node->handle; 246 247 /* Mark as incomplete */ 248 dev->sess = NULL; 246 dev->phone = -1; /* mark as incomplete */ 249 247 dev->refcount = 1; 250 248 fibril_condvar_initialize(&dev->cv); 251 249 252 250 /* 253 251 * Insert the incomplete device structure so that other … … 256 254 */ 257 255 hash_table_insert(&devices, key, &dev->link); 258 256 259 257 /* 260 258 * Drop the mutex to allow recursive devfs requests. 261 259 */ 262 260 fibril_mutex_unlock(&devices_mutex); 263 264 async_sess_t *sess = devmap_device_connect(EXCHANGE_SERIALIZE, 265 node->handle, 0); 266 261 262 int phone = devmap_device_connect(node->handle, 0); 263 267 264 fibril_mutex_lock(&devices_mutex); 268 265 269 266 /* 270 267 * Notify possible waiters about this device structure … … 272 269 */ 273 270 fibril_condvar_broadcast(&dev->cv); 274 275 if ( !sess) {271 272 if (phone < 0) { 276 273 /* 277 274 * Connecting failed, need to remove the … … 280 277 hash_table_remove(&devices, key, DEVICES_KEYS); 281 278 fibril_mutex_unlock(&devices_mutex); 282 279 283 280 return ENOENT; 284 281 } 285 282 286 /* Set the correct session. */287 dev-> sess = sess;283 /* Set the correct phone. */ 284 dev->phone = phone; 288 285 } else { 289 286 device_t *dev = hash_table_get_instance(lnk, device_t, link); 290 291 if ( !dev->sess) {287 288 if (dev->phone < 0) { 292 289 /* 293 290 * Wait until the device structure is completed … … 401 398 402 399 return 1; 400 } 401 402 static char devfs_plb_get_char(unsigned pos) 403 { 404 return devfs_reg.plb_ro[pos % PLB_SIZE]; 403 405 } 404 406 … … 442 444 .size_get = devfs_size_get, 443 445 .lnkcnt_get = devfs_lnkcnt_get, 446 .plb_get_char = devfs_plb_get_char, 444 447 .is_directory = devfs_is_directory, 445 448 .is_file = devfs_is_file, … … 456 459 } 457 460 458 static int devfs_mounted(devmap_handle_t devmap_handle, const char *opts, 459 fs_index_t *index, aoff64_t *size, unsigned *lnkcnt) 460 { 461 *index = 0; 462 *size = 0; 463 *lnkcnt = 0; 464 return EOK; 465 } 466 467 static int devfs_unmounted(devmap_handle_t devmap_handle) 468 { 469 return ENOTSUP; 470 } 471 472 static int 473 devfs_read(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos, 474 size_t *rbytes) 475 { 461 void devfs_mounted(ipc_callid_t rid, ipc_call_t *request) 462 { 463 char *opts; 464 465 /* Accept the mount options */ 466 sysarg_t retval = async_data_write_accept((void **) &opts, true, 0, 0, 467 0, NULL); 468 if (retval != EOK) { 469 async_answer_0(rid, retval); 470 return; 471 } 472 473 free(opts); 474 async_answer_3(rid, EOK, 0, 0, 0); 475 } 476 477 void devfs_mount(ipc_callid_t rid, ipc_call_t *request) 478 { 479 libfs_mount(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request); 480 } 481 482 void devfs_unmounted(ipc_callid_t rid, ipc_call_t *request) 483 { 484 async_answer_0(rid, ENOTSUP); 485 } 486 487 void devfs_unmount(ipc_callid_t rid, ipc_call_t *request) 488 { 489 libfs_unmount(&devfs_libfs_ops, rid, request); 490 } 491 492 void devfs_lookup(ipc_callid_t rid, ipc_call_t *request) 493 { 494 libfs_lookup(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request); 495 } 496 497 void devfs_open_node(ipc_callid_t rid, ipc_call_t *request) 498 { 499 libfs_open_node(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request); 500 } 501 502 void devfs_stat(ipc_callid_t rid, ipc_call_t *request) 503 { 504 libfs_stat(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request); 505 } 506 507 void devfs_read(ipc_callid_t rid, ipc_call_t *request) 508 { 509 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 510 aoff64_t pos = 511 (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request)); 512 476 513 if (index == 0) { 477 514 ipc_callid_t callid; … … 479 516 if (!async_data_read_receive(&callid, &size)) { 480 517 async_answer_0(callid, EINVAL); 481 return EINVAL; 518 async_answer_0(rid, EINVAL); 519 return; 482 520 } 483 521 … … 499 537 async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); 500 538 free(desc); 501 *rbytes = 1;502 return EOK;539 async_answer_1(rid, EOK, 1); 540 return; 503 541 } 504 542 … … 514 552 async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); 515 553 free(desc); 516 *rbytes = 1;517 return EOK;554 async_answer_1(rid, EOK, 1); 555 return; 518 556 } 519 557 … … 522 560 523 561 async_answer_0(callid, ENOENT); 524 return ENOENT; 562 async_answer_1(rid, ENOENT, 0); 563 return; 525 564 } 526 565 … … 533 572 if (!async_data_read_receive(&callid, &size)) { 534 573 async_answer_0(callid, EINVAL); 535 return EINVAL; 574 async_answer_0(rid, EINVAL); 575 return; 536 576 } 537 577 … … 542 582 async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); 543 583 free(desc); 544 *rbytes = 1;545 return EOK;584 async_answer_1(rid, EOK, 1); 585 return; 546 586 } 547 587 548 588 free(desc); 549 589 async_answer_0(callid, ENOENT); 550 return ENOENT; 590 async_answer_1(rid, ENOENT, 0); 591 return; 551 592 } 552 593 … … 562 603 if (lnk == NULL) { 563 604 fibril_mutex_unlock(&devices_mutex); 564 return ENOENT; 605 async_answer_0(rid, ENOENT); 606 return; 565 607 } 566 608 567 609 device_t *dev = hash_table_get_instance(lnk, device_t, link); 568 assert(dev-> sess);610 assert(dev->phone >= 0); 569 611 570 612 ipc_callid_t callid; … … 572 614 fibril_mutex_unlock(&devices_mutex); 573 615 async_answer_0(callid, EINVAL); 574 return EINVAL; 616 async_answer_0(rid, EINVAL); 617 return; 575 618 } 576 619 577 620 /* Make a request at the driver */ 578 async_exch_t *exch = async_exchange_begin(dev->sess);579 580 621 ipc_call_t answer; 581 aid_t msg = async_send_4(exch, VFS_OUT_READ, devmap_handle, 582 index, LOWER32(pos), UPPER32(pos), &answer); 622 aid_t msg = async_send_3(dev->phone, IPC_GET_IMETHOD(*request), 623 IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), 624 IPC_GET_ARG3(*request), &answer); 583 625 584 626 /* Forward the IPC_M_DATA_READ request to the driver */ 585 async_forward_fast(callid, exch, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 586 587 async_exchange_end(exch); 588 627 async_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 589 628 fibril_mutex_unlock(&devices_mutex); 590 629 … … 592 631 sysarg_t rc; 593 632 async_wait_for(msg, &rc); 594 595 *rbytes = IPC_GET_ARG1(answer); 596 return rc; 597 } 598 599 return ENOENT; 600 } 601 602 static int 603 devfs_write(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos, 604 size_t *wbytes, aoff64_t *nsize) 605 { 606 if (index == 0) 607 return ENOTSUP; 633 size_t bytes = IPC_GET_ARG1(answer); 634 635 /* Driver reply is the final result of the whole operation */ 636 async_answer_1(rid, rc, bytes); 637 return; 638 } 639 640 async_answer_0(rid, ENOENT); 641 } 642 643 void devfs_write(ipc_callid_t rid, ipc_call_t *request) 644 { 645 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 646 if (index == 0) { 647 async_answer_0(rid, ENOTSUP); 648 return; 649 } 608 650 609 651 devmap_handle_type_t type = devmap_handle_probe(index); … … 611 653 if (type == DEV_HANDLE_NAMESPACE) { 612 654 /* Namespace directory */ 613 return ENOTSUP; 655 async_answer_0(rid, ENOTSUP); 656 return; 614 657 } 615 658 … … 624 667 if (lnk == NULL) { 625 668 fibril_mutex_unlock(&devices_mutex); 626 return ENOENT; 669 async_answer_0(rid, ENOENT); 670 return; 627 671 } 628 672 629 673 device_t *dev = hash_table_get_instance(lnk, device_t, link); 630 assert(dev-> sess);674 assert(dev->phone >= 0); 631 675 632 676 ipc_callid_t callid; … … 634 678 fibril_mutex_unlock(&devices_mutex); 635 679 async_answer_0(callid, EINVAL); 636 return EINVAL; 680 async_answer_0(rid, EINVAL); 681 return; 637 682 } 638 683 639 684 /* Make a request at the driver */ 640 async_exch_t *exch = async_exchange_begin(dev->sess);641 642 685 ipc_call_t answer; 643 aid_t msg = async_send_4(exch, VFS_OUT_WRITE, devmap_handle, 644 index, LOWER32(pos), UPPER32(pos), &answer); 686 aid_t msg = async_send_3(dev->phone, IPC_GET_IMETHOD(*request), 687 IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), 688 IPC_GET_ARG3(*request), &answer); 645 689 646 690 /* Forward the IPC_M_DATA_WRITE request to the driver */ 647 async_forward_fast(callid, exch, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 648 649 async_exchange_end(exch); 691 async_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 650 692 651 693 fibril_mutex_unlock(&devices_mutex); … … 654 696 sysarg_t rc; 655 697 async_wait_for(msg, &rc); 656 657 *wbytes = IPC_GET_ARG1(answer); 658 *nsize = 0; 659 return rc; 660 } 661 662 return ENOENT; 663 } 664 665 static int 666 devfs_truncate(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t size) 667 { 668 return ENOTSUP; 669 } 670 671 static int devfs_close(devmap_handle_t devmap_handle, fs_index_t index) 672 { 673 if (index == 0) 674 return EOK; 698 size_t bytes = IPC_GET_ARG1(answer); 699 700 /* Driver reply is the final result of the whole operation */ 701 async_answer_1(rid, rc, bytes); 702 return; 703 } 704 705 async_answer_0(rid, ENOENT); 706 } 707 708 void devfs_truncate(ipc_callid_t rid, ipc_call_t *request) 709 { 710 async_answer_0(rid, ENOTSUP); 711 } 712 713 void devfs_close(ipc_callid_t rid, ipc_call_t *request) 714 { 715 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 716 717 if (index == 0) { 718 async_answer_0(rid, EOK); 719 return; 720 } 675 721 676 722 devmap_handle_type_t type = devmap_handle_probe(index); … … 678 724 if (type == DEV_HANDLE_NAMESPACE) { 679 725 /* Namespace directory */ 680 return EOK; 726 async_answer_0(rid, EOK); 727 return; 681 728 } 682 729 … … 690 737 if (lnk == NULL) { 691 738 fibril_mutex_unlock(&devices_mutex); 692 return ENOENT; 739 async_answer_0(rid, ENOENT); 740 return; 693 741 } 694 742 695 743 device_t *dev = hash_table_get_instance(lnk, device_t, link); 696 assert(dev-> sess);744 assert(dev->phone >= 0); 697 745 dev->refcount--; 698 746 699 747 if (dev->refcount == 0) { 700 async_hangup(dev-> sess);748 async_hangup(dev->phone); 701 749 hash_table_remove(&devices, key, DEVICES_KEYS); 702 750 } … … 704 752 fibril_mutex_unlock(&devices_mutex); 705 753 706 return EOK; 707 } 708 709 return ENOENT; 710 } 711 712 static int devfs_sync(devmap_handle_t devmap_handle, fs_index_t index) 713 { 714 if (index == 0) 715 return EOK; 754 async_answer_0(rid, EOK); 755 return; 756 } 757 758 async_answer_0(rid, ENOENT); 759 } 760 761 void devfs_sync(ipc_callid_t rid, ipc_call_t *request) 762 { 763 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 764 765 if (index == 0) { 766 async_answer_0(rid, EOK); 767 return; 768 } 716 769 717 770 devmap_handle_type_t type = devmap_handle_probe(index); … … 719 772 if (type == DEV_HANDLE_NAMESPACE) { 720 773 /* Namespace directory */ 721 return EOK; 774 async_answer_0(rid, EOK); 775 return; 722 776 } 723 777 … … 731 785 if (lnk == NULL) { 732 786 fibril_mutex_unlock(&devices_mutex); 733 return ENOENT; 787 async_answer_0(rid, ENOENT); 788 return; 734 789 } 735 790 736 791 device_t *dev = hash_table_get_instance(lnk, device_t, link); 737 assert(dev-> sess);792 assert(dev->phone >= 0); 738 793 739 794 /* Make a request at the driver */ 740 async_exch_t *exch = async_exchange_begin(dev->sess);741 742 795 ipc_call_t answer; 743 aid_t msg = async_send_2(exch, VFS_OUT_SYNC, devmap_handle, 744 index, &answer); 745 746 async_exchange_end(exch); 796 aid_t msg = async_send_2(dev->phone, IPC_GET_IMETHOD(*request), 797 IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), &answer); 747 798 748 799 fibril_mutex_unlock(&devices_mutex); … … 752 803 async_wait_for(msg, &rc); 753 804 754 return rc; 755 } 756 757 return ENOENT; 758 } 759 760 static int devfs_destroy(devmap_handle_t devmap_handle, fs_index_t index) 761 { 762 return ENOTSUP; 763 } 764 765 vfs_out_ops_t devfs_ops = { 766 .mounted = devfs_mounted, 767 .unmounted = devfs_unmounted, 768 .read = devfs_read, 769 .write = devfs_write, 770 .truncate = devfs_truncate, 771 .close = devfs_close, 772 .destroy = devfs_destroy, 773 .sync = devfs_sync, 774 }; 805 /* Driver reply is the final result of the whole operation */ 806 async_answer_0(rid, rc); 807 return; 808 } 809 810 async_answer_0(rid, ENOENT); 811 } 812 813 void devfs_destroy(ipc_callid_t rid, ipc_call_t *request) 814 { 815 async_answer_0(rid, ENOTSUP); 816 } 775 817 776 818 /**
Note:
See TracChangeset
for help on using the changeset viewer.