Changes in uspace/srv/fs/devfs/devfs_ops.c [19f857a:cfd630af] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/devfs/devfs_ops.c
r19f857a rcfd630af 36 36 */ 37 37 38 #include <ipc/ipc.h>39 38 #include <macros.h> 40 39 #include <bool.h> … … 54 53 typedef struct { 55 54 devmap_handle_type_t type; 56 dev _handle_t handle;55 devmap_handle_t handle; 57 56 } devfs_node_t; 58 57 59 58 /** Opened devices structure */ 60 59 typedef struct { 61 dev _handle_t handle;62 int phone; 60 devmap_handle_t handle; 61 int phone; /**< When < 0, the structure is incomplete. */ 63 62 size_t refcount; 64 63 link_t link; 64 fibril_condvar_t cv; /**< Broadcast when completed. */ 65 65 } device_t; 66 66 … … 84 84 { 85 85 device_t *dev = hash_table_get_instance(item, device_t, link); 86 return (dev->handle == (dev _handle_t) key[DEVICES_KEY_HANDLE]);86 return (dev->handle == (devmap_handle_t) key[DEVICES_KEY_HANDLE]); 87 87 } 88 88 … … 99 99 100 100 static int devfs_node_get_internal(fs_node_t **rfn, devmap_handle_type_t type, 101 dev _handle_t handle)101 devmap_handle_t handle) 102 102 { 103 103 devfs_node_t *node = (devfs_node_t *) malloc(sizeof(devfs_node_t)); … … 122 122 } 123 123 124 static int devfs_root_get(fs_node_t **rfn, dev _handle_t dev_handle)124 static int devfs_root_get(fs_node_t **rfn, devmap_handle_t devmap_handle) 125 125 { 126 126 return devfs_node_get_internal(rfn, DEV_HANDLE_NONE, 0); … … 130 130 { 131 131 devfs_node_t *node = (devfs_node_t *) pfn->data; 132 int ret; 132 133 133 134 if (node->handle == 0) { … … 145 146 146 147 if (str_cmp(devs[pos].name, component) == 0) { 148 ret = devfs_node_get_internal(rfn, DEV_HANDLE_NAMESPACE, devs[pos].handle); 147 149 free(devs); 148 return devfs_node_get_internal(rfn, DEV_HANDLE_NAMESPACE, devs[pos].handle);150 return ret; 149 151 } 150 152 } … … 154 156 155 157 /* Search root namespace */ 156 dev _handle_t namespace;158 devmap_handle_t namespace; 157 159 if (devmap_namespace_get_handle("", &namespace, 0) == EOK) { 158 160 count = devmap_get_devices(namespace, &devs); … … 162 164 for (pos = 0; pos < count; pos++) { 163 165 if (str_cmp(devs[pos].name, component) == 0) { 166 ret = devfs_node_get_internal(rfn, DEV_HANDLE_DEVICE, devs[pos].handle); 164 167 free(devs); 165 return devfs_node_get_internal(rfn, DEV_HANDLE_DEVICE, devs[pos].handle);168 return ret; 166 169 } 167 170 } … … 184 187 for (pos = 0; pos < count; pos++) { 185 188 if (str_cmp(devs[pos].name, component) == 0) { 189 ret = devfs_node_get_internal(rfn, DEV_HANDLE_DEVICE, devs[pos].handle); 186 190 free(devs); 187 return devfs_node_get_internal(rfn, DEV_HANDLE_DEVICE, devs[pos].handle);191 return ret; 188 192 } 189 193 } … … 200 204 } 201 205 202 static int devfs_node_get(fs_node_t **rfn, dev _handle_t dev_handle, fs_index_t index)206 static int devfs_node_get(fs_node_t **rfn, devmap_handle_t devmap_handle, fs_index_t index) 203 207 { 204 208 return devfs_node_get_internal(rfn, devmap_handle_probe(index), index); … … 227 231 [DEVICES_KEY_HANDLE] = (unsigned long) node->handle 228 232 }; 229 233 link_t *lnk; 234 230 235 fibril_mutex_lock(&devices_mutex); 231 link_t *lnk = hash_table_find(&devices, key); 236 restart: 237 lnk = hash_table_find(&devices, key); 232 238 if (lnk == NULL) { 233 239 device_t *dev = (device_t *) malloc(sizeof(device_t)); … … 237 243 } 238 244 245 dev->handle = node->handle; 246 dev->phone = -1; /* mark as incomplete */ 247 dev->refcount = 1; 248 fibril_condvar_initialize(&dev->cv); 249 250 /* 251 * Insert the incomplete device structure so that other 252 * fibrils will not race with us when we drop the mutex 253 * below. 254 */ 255 hash_table_insert(&devices, key, &dev->link); 256 257 /* 258 * Drop the mutex to allow recursive devfs requests. 259 */ 260 fibril_mutex_unlock(&devices_mutex); 261 239 262 int phone = devmap_device_connect(node->handle, 0); 263 264 fibril_mutex_lock(&devices_mutex); 265 266 /* 267 * Notify possible waiters about this device structure 268 * being completed (or destroyed). 269 */ 270 fibril_condvar_broadcast(&dev->cv); 271 240 272 if (phone < 0) { 273 /* 274 * Connecting failed, need to remove the 275 * entry and free the device structure. 276 */ 277 hash_table_remove(&devices, key, DEVICES_KEYS); 241 278 fibril_mutex_unlock(&devices_mutex); 242 free(dev); 279 243 280 return ENOENT; 244 281 } 245 282 246 dev->handle = node->handle;283 /* Set the correct phone. */ 247 284 dev->phone = phone; 248 dev->refcount = 1;249 250 hash_table_insert(&devices, key, &dev->link);251 285 } else { 252 286 device_t *dev = hash_table_get_instance(lnk, device_t, link); 287 288 if (dev->phone < 0) { 289 /* 290 * Wait until the device structure is completed 291 * and start from the beginning as the device 292 * structure might have entirely disappeared 293 * while we were not holding the mutex in 294 * fibril_condvar_wait(). 295 */ 296 fibril_condvar_wait(&dev->cv, &devices_mutex); 297 goto restart; 298 } 299 253 300 dev->refcount++; 254 301 } … … 269 316 } 270 317 271 static int devfs_create_node(fs_node_t **rfn, dev _handle_t dev_handle, int lflag)318 static int devfs_create_node(fs_node_t **rfn, devmap_handle_t devmap_handle, int lflag) 272 319 { 273 320 assert((lflag & L_FILE) ^ (lflag & L_DIRECTORY)); … … 304 351 305 352 /* Root namespace */ 306 dev _handle_t namespace;353 devmap_handle_t namespace; 307 354 if (devmap_namespace_get_handle("", &namespace, 0) == EOK) { 308 355 count = devmap_count_devices(namespace); … … 372 419 } 373 420 374 static dev _handle_t devfs_device_get(fs_node_t *fn)421 static devmap_handle_t devfs_device_get(fs_node_t *fn) 375 422 { 376 423 devfs_node_t *node = (devfs_node_t *) fn->data; … … 409 456 return false; 410 457 411 if (devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING) < 0)412 return false;413 414 458 return true; 415 459 } … … 420 464 421 465 /* Accept the mount options */ 422 ipcarg_t retval = async_data_write_accept((void **) &opts, true, 0, 0,466 sysarg_t retval = async_data_write_accept((void **) &opts, true, 0, 0, 423 467 0, NULL); 424 468 if (retval != EOK) { 425 ipc_answer_0(rid, retval);469 async_answer_0(rid, retval); 426 470 return; 427 471 } 428 472 429 473 free(opts); 430 ipc_answer_3(rid, EOK, 0, 0, 0);474 async_answer_3(rid, EOK, 0, 0, 0); 431 475 } 432 476 … … 438 482 void devfs_unmounted(ipc_callid_t rid, ipc_call_t *request) 439 483 { 440 ipc_answer_0(rid, ENOTSUP);484 async_answer_0(rid, ENOTSUP); 441 485 } 442 486 … … 471 515 size_t size; 472 516 if (!async_data_read_receive(&callid, &size)) { 473 ipc_answer_0(callid, EINVAL);474 ipc_answer_0(rid, EINVAL);517 async_answer_0(callid, EINVAL); 518 async_answer_0(rid, EINVAL); 475 519 return; 476 520 } … … 493 537 async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); 494 538 free(desc); 495 ipc_answer_1(rid, EOK, 1);539 async_answer_1(rid, EOK, 1); 496 540 return; 497 541 } … … 501 545 502 546 /* Search root namespace */ 503 dev _handle_t namespace;547 devmap_handle_t namespace; 504 548 if (devmap_namespace_get_handle("", &namespace, 0) == EOK) { 505 549 count = devmap_get_devices(namespace, &desc); … … 508 552 async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); 509 553 free(desc); 510 ipc_answer_1(rid, EOK, 1);554 async_answer_1(rid, EOK, 1); 511 555 return; 512 556 } … … 515 559 } 516 560 517 ipc_answer_0(callid, ENOENT);518 ipc_answer_1(rid, ENOENT, 0);561 async_answer_0(callid, ENOENT); 562 async_answer_1(rid, ENOENT, 0); 519 563 return; 520 564 } … … 527 571 size_t size; 528 572 if (!async_data_read_receive(&callid, &size)) { 529 ipc_answer_0(callid, EINVAL);530 ipc_answer_0(rid, EINVAL);573 async_answer_0(callid, EINVAL); 574 async_answer_0(rid, EINVAL); 531 575 return; 532 576 } … … 538 582 async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); 539 583 free(desc); 540 ipc_answer_1(rid, EOK, 1);584 async_answer_1(rid, EOK, 1); 541 585 return; 542 586 } 543 587 544 588 free(desc); 545 ipc_answer_0(callid, ENOENT);546 ipc_answer_1(rid, ENOENT, 0);589 async_answer_0(callid, ENOENT); 590 async_answer_1(rid, ENOENT, 0); 547 591 return; 548 592 } … … 559 603 if (lnk == NULL) { 560 604 fibril_mutex_unlock(&devices_mutex); 561 ipc_answer_0(rid, ENOENT);605 async_answer_0(rid, ENOENT); 562 606 return; 563 607 } 564 608 565 609 device_t *dev = hash_table_get_instance(lnk, device_t, link); 610 assert(dev->phone >= 0); 566 611 567 612 ipc_callid_t callid; 568 613 if (!async_data_read_receive(&callid, NULL)) { 569 614 fibril_mutex_unlock(&devices_mutex); 570 ipc_answer_0(callid, EINVAL);571 ipc_answer_0(rid, EINVAL);615 async_answer_0(callid, EINVAL); 616 async_answer_0(rid, EINVAL); 572 617 return; 573 618 } … … 575 620 /* Make a request at the driver */ 576 621 ipc_call_t answer; 577 aid_t msg = async_send_3(dev->phone, IPC_GET_ METHOD(*request),622 aid_t msg = async_send_3(dev->phone, IPC_GET_IMETHOD(*request), 578 623 IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), 579 624 IPC_GET_ARG3(*request), &answer); 580 625 581 626 /* Forward the IPC_M_DATA_READ request to the driver */ 582 ipc_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);627 async_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 583 628 fibril_mutex_unlock(&devices_mutex); 584 629 585 630 /* Wait for reply from the driver. */ 586 ipcarg_t rc;631 sysarg_t rc; 587 632 async_wait_for(msg, &rc); 588 633 size_t bytes = IPC_GET_ARG1(answer); 589 634 590 635 /* Driver reply is the final result of the whole operation */ 591 ipc_answer_1(rid, rc, bytes);592 return; 593 } 594 595 ipc_answer_0(rid, ENOENT);636 async_answer_1(rid, rc, bytes); 637 return; 638 } 639 640 async_answer_0(rid, ENOENT); 596 641 } 597 642 … … 600 645 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 601 646 if (index == 0) { 602 ipc_answer_0(rid, ENOTSUP);647 async_answer_0(rid, ENOTSUP); 603 648 return; 604 649 } … … 608 653 if (type == DEV_HANDLE_NAMESPACE) { 609 654 /* Namespace directory */ 610 ipc_answer_0(rid, ENOTSUP);655 async_answer_0(rid, ENOTSUP); 611 656 return; 612 657 } … … 622 667 if (lnk == NULL) { 623 668 fibril_mutex_unlock(&devices_mutex); 624 ipc_answer_0(rid, ENOENT);669 async_answer_0(rid, ENOENT); 625 670 return; 626 671 } 627 672 628 673 device_t *dev = hash_table_get_instance(lnk, device_t, link); 674 assert(dev->phone >= 0); 629 675 630 676 ipc_callid_t callid; 631 677 if (!async_data_write_receive(&callid, NULL)) { 632 678 fibril_mutex_unlock(&devices_mutex); 633 ipc_answer_0(callid, EINVAL);634 ipc_answer_0(rid, EINVAL);679 async_answer_0(callid, EINVAL); 680 async_answer_0(rid, EINVAL); 635 681 return; 636 682 } … … 638 684 /* Make a request at the driver */ 639 685 ipc_call_t answer; 640 aid_t msg = async_send_3(dev->phone, IPC_GET_ METHOD(*request),686 aid_t msg = async_send_3(dev->phone, IPC_GET_IMETHOD(*request), 641 687 IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), 642 688 IPC_GET_ARG3(*request), &answer); 643 689 644 690 /* Forward the IPC_M_DATA_WRITE request to the driver */ 645 ipc_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);691 async_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 646 692 647 693 fibril_mutex_unlock(&devices_mutex); 648 694 649 695 /* Wait for reply from the driver. */ 650 ipcarg_t rc;696 sysarg_t rc; 651 697 async_wait_for(msg, &rc); 652 698 size_t bytes = IPC_GET_ARG1(answer); 653 699 654 700 /* Driver reply is the final result of the whole operation */ 655 ipc_answer_1(rid, rc, bytes);656 return; 657 } 658 659 ipc_answer_0(rid, ENOENT);701 async_answer_1(rid, rc, bytes); 702 return; 703 } 704 705 async_answer_0(rid, ENOENT); 660 706 } 661 707 662 708 void devfs_truncate(ipc_callid_t rid, ipc_call_t *request) 663 709 { 664 ipc_answer_0(rid, ENOTSUP);710 async_answer_0(rid, ENOTSUP); 665 711 } 666 712 … … 670 716 671 717 if (index == 0) { 672 ipc_answer_0(rid, EOK);718 async_answer_0(rid, EOK); 673 719 return; 674 720 } … … 678 724 if (type == DEV_HANDLE_NAMESPACE) { 679 725 /* Namespace directory */ 680 ipc_answer_0(rid, EOK);726 async_answer_0(rid, EOK); 681 727 return; 682 728 } … … 691 737 if (lnk == NULL) { 692 738 fibril_mutex_unlock(&devices_mutex); 693 ipc_answer_0(rid, ENOENT);739 async_answer_0(rid, ENOENT); 694 740 return; 695 741 } 696 742 697 743 device_t *dev = hash_table_get_instance(lnk, device_t, link); 744 assert(dev->phone >= 0); 698 745 dev->refcount--; 699 746 700 747 if (dev->refcount == 0) { 701 ipc_hangup(dev->phone);748 async_hangup(dev->phone); 702 749 hash_table_remove(&devices, key, DEVICES_KEYS); 703 750 } … … 705 752 fibril_mutex_unlock(&devices_mutex); 706 753 707 ipc_answer_0(rid, EOK);708 return; 709 } 710 711 ipc_answer_0(rid, ENOENT);754 async_answer_0(rid, EOK); 755 return; 756 } 757 758 async_answer_0(rid, ENOENT); 712 759 } 713 760 … … 717 764 718 765 if (index == 0) { 719 ipc_answer_0(rid, EOK);766 async_answer_0(rid, EOK); 720 767 return; 721 768 } … … 725 772 if (type == DEV_HANDLE_NAMESPACE) { 726 773 /* Namespace directory */ 727 ipc_answer_0(rid, EOK);774 async_answer_0(rid, EOK); 728 775 return; 729 776 } … … 738 785 if (lnk == NULL) { 739 786 fibril_mutex_unlock(&devices_mutex); 740 ipc_answer_0(rid, ENOENT);787 async_answer_0(rid, ENOENT); 741 788 return; 742 789 } 743 790 744 791 device_t *dev = hash_table_get_instance(lnk, device_t, link); 792 assert(dev->phone >= 0); 745 793 746 794 /* Make a request at the driver */ 747 795 ipc_call_t answer; 748 aid_t msg = async_send_2(dev->phone, IPC_GET_ METHOD(*request),796 aid_t msg = async_send_2(dev->phone, IPC_GET_IMETHOD(*request), 749 797 IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), &answer); 750 798 … … 752 800 753 801 /* Wait for reply from the driver */ 754 ipcarg_t rc;802 sysarg_t rc; 755 803 async_wait_for(msg, &rc); 756 804 757 805 /* Driver reply is the final result of the whole operation */ 758 ipc_answer_0(rid, rc);759 return; 760 } 761 762 ipc_answer_0(rid, ENOENT);806 async_answer_0(rid, rc); 807 return; 808 } 809 810 async_answer_0(rid, ENOENT); 763 811 } 764 812 765 813 void devfs_destroy(ipc_callid_t rid, ipc_call_t *request) 766 814 { 767 ipc_answer_0(rid, ENOTSUP);815 async_answer_0(rid, ENOTSUP); 768 816 } 769 817
Note:
See TracChangeset
for help on using the changeset viewer.