Changes in uspace/srv/devman/devman.c [ca2a18e:7e752b2] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/devman/devman.c
rca2a18e r7e752b2 62 62 } 63 63 64 static int devmap_devices_class_compare(unsigned long key[], hash_count_t keys,65 link_t *item)66 {67 dev_class_info_t *class_info68 = hash_table_get_instance(item, dev_class_info_t, devmap_link);69 assert(class_info != NULL);70 71 return (class_info->devmap_handle == (devmap_handle_t) key[0]);72 }73 74 64 static void devices_remove_callback(link_t *item) 75 65 { … … 85 75 .hash = devices_hash, 86 76 .compare = devmap_devices_compare, 87 .remove_callback = devices_remove_callback88 };89 90 static hash_table_operations_t devmap_devices_class_ops = {91 .hash = devices_hash,92 .compare = devmap_devices_class_compare,93 77 .remove_callback = devices_remove_callback 94 78 }; … … 384 368 printf(NAME ": create_root_node\n"); 385 369 386 fibril_rwlock_write_lock(&tree->rwlock);387 370 node = create_dev_node(); 388 371 if (node != NULL) { … … 394 377 tree->root_node = node; 395 378 } 396 fibril_rwlock_write_unlock(&tree->rwlock);397 379 398 380 return node != NULL; … … 457 439 /** Start a driver 458 440 * 441 * The driver's mutex is assumed to be locked. 442 * 459 443 * @param drv The driver's structure. 460 444 * @return True if the driver's task is successfully spawned, false … … 465 449 int rc; 466 450 467 assert(fibril_mutex_is_locked(&drv->driver_mutex));468 469 451 printf(NAME ": start_driver '%s'\n", drv->name); 470 452 … … 516 498 * @param phone The phone to the driver. 517 499 */ 518 void set_driver_phone(driver_t *driver, sysarg_t phone)500 void set_driver_phone(driver_t *driver, ipcarg_t phone) 519 501 { 520 502 fibril_mutex_lock(&driver->driver_mutex); … … 526 508 /** Notify driver about the devices to which it was assigned. 527 509 * 510 * The driver's mutex must be locked. 511 * 528 512 * @param driver The driver to which the devices are passed. 529 513 */ … … 534 518 int phone; 535 519 536 printf(NAME ": pass_devices_to_driver(`%s')\n", driver->name); 537 538 fibril_mutex_lock(&driver->driver_mutex); 539 540 phone = async_connect_me_to(driver->phone, DRIVER_DEVMAN, 0, 0); 541 542 if (phone < 0) { 543 fibril_mutex_unlock(&driver->driver_mutex); 544 return; 545 } 546 547 /* 548 * Go through devices list as long as there is some device 549 * that has not been passed to the driver. 550 */ 551 link = driver->devices.next; 552 while (link != &driver->devices) { 553 dev = list_get_instance(link, node_t, driver_devices); 554 if (dev->passed_to_driver) { 520 printf(NAME ": pass_devices_to_driver\n"); 521 522 phone = ipc_connect_me_to(driver->phone, DRIVER_DEVMAN, 0, 0); 523 if (phone > 0) { 524 525 link = driver->devices.next; 526 while (link != &driver->devices) { 527 dev = list_get_instance(link, node_t, driver_devices); 528 add_device(phone, driver, dev, tree); 555 529 link = link->next; 556 continue;557 530 } 558 559 /* 560 * We remove the device from the list to allow safe adding 561 * of new devices (no one will touch our item this way). 562 */ 563 list_remove(link); 564 565 /* 566 * Unlock to avoid deadlock when adding device 567 * handled by itself. 568 */ 569 fibril_mutex_unlock(&driver->driver_mutex); 570 571 add_device(phone, driver, dev, tree); 572 573 /* 574 * Lock again as we will work with driver's 575 * structure. 576 */ 577 fibril_mutex_lock(&driver->driver_mutex); 578 579 /* 580 * Insert the device back. 581 * The order is not relevant here so no harm is done 582 * (actually, the order would be preserved in most cases). 583 */ 584 list_append(link, &driver->devices); 585 586 /* 587 * Restart the cycle to go through all devices again. 588 */ 589 link = driver->devices.next; 590 } 591 592 async_hangup(phone); 593 594 /* 595 * Once we passed all devices to the driver, we need to mark the 596 * driver as running. 597 * It is vital to do it here and inside critical section. 598 * 599 * If we would change the state earlier, other devices added to 600 * the driver would be added to the device list and started 601 * immediately and possibly started here as well. 602 */ 603 printf(NAME ": driver %s goes into running state.\n", driver->name); 604 driver->state = DRIVER_RUNNING; 605 606 fibril_mutex_unlock(&driver->driver_mutex); 531 532 ipc_hangup(phone); 533 } 607 534 } 608 535 … … 618 545 void initialize_running_driver(driver_t *driver, dev_tree_t *tree) 619 546 { 620 printf(NAME ": initialize_running_driver (`%s')\n", driver->name); 547 printf(NAME ": initialize_running_driver\n"); 548 fibril_mutex_lock(&driver->driver_mutex); 621 549 622 550 /* … … 625 553 */ 626 554 pass_devices_to_driver(driver, tree); 555 556 /* Change driver's state to running. */ 557 driver->state = DRIVER_RUNNING; 558 559 fibril_mutex_unlock(&driver->driver_mutex); 627 560 } 628 561 … … 688 621 } 689 622 690 devmap_device_register_with_iface(devmap_pathname, 691 &node->devmap_handle, DEVMAN_CONNECT_FROM_DEVMAP); 623 devmap_device_register(devmap_pathname, &node->devmap_handle); 692 624 693 625 tree_add_devmap_device(tree, node); … … 697 629 } 698 630 631 699 632 /** Pass a device to running driver. 700 633 * … … 704 637 void add_device(int phone, driver_t *drv, node_t *node, dev_tree_t *tree) 705 638 { 706 /* 707 * We do not expect to have driver's mutex locked as we do not 708 * access any structures that would affect driver_t. 709 */ 710 printf(NAME ": add_device (driver `%s', device `%s')\n", drv->name, 711 node->name); 712 713 sysarg_t rc; 639 printf(NAME ": add_device\n"); 640 641 ipcarg_t rc; 714 642 ipc_call_t answer; 715 643 716 644 /* Send the device to the driver. */ 717 devman_handle_t parent_handle; 718 if (node->parent) { 719 parent_handle = node->parent->handle; 720 } else { 721 parent_handle = 0; 722 } 723 724 aid_t req = async_send_2(phone, DRIVER_ADD_DEVICE, node->handle, 725 parent_handle, &answer); 645 aid_t req = async_send_1(phone, DRIVER_ADD_DEVICE, node->handle, 646 &answer); 726 647 727 648 /* Send the device's name to the driver. */ … … 731 652 /* TODO handle error */ 732 653 } 733 654 734 655 /* Wait for answer from the driver. */ 735 656 async_wait_for(req, &rc); 736 737 657 switch(rc) { 738 658 case EOK: … … 747 667 } 748 668 749 node->passed_to_driver = true;750 751 669 return; 752 670 } … … 774 692 attach_driver(node, drv); 775 693 776 fibril_mutex_lock(&drv->driver_mutex);777 694 if (drv->state == DRIVER_NOT_STARTED) { 778 695 /* Start the driver. */ 779 696 start_driver(drv); 780 697 } 781 bool is_running = drv->state == DRIVER_RUNNING; 782 fibril_mutex_unlock(&drv->driver_mutex); 783 784 if (is_running) { 698 699 if (drv->state == DRIVER_RUNNING) { 785 700 /* Notify the driver about the new device. */ 786 int phone = async_connect_me_to(drv->phone, DRIVER_DEVMAN, 0, 0);787 if (phone > =0) {701 int phone = ipc_connect_me_to(drv->phone, DRIVER_DEVMAN, 0, 0); 702 if (phone > 0) { 788 703 add_device(phone, drv, node, tree); 789 async_hangup(phone);704 ipc_hangup(phone); 790 705 } 791 706 } … … 861 776 /** Find the device node structure of the device witch has the specified handle. 862 777 * 778 * Device tree's rwlock should be held at least for reading. 779 * 863 780 * @param tree The device tree where we look for the device node. 864 781 * @param handle The handle of the device. … … 868 785 { 869 786 unsigned long key = handle; 870 link_t *link; 871 872 assert(fibril_rwlock_is_locked(&tree->rwlock)); 873 874 link = hash_table_find(&tree->devman_devices, &key); 787 link_t *link = hash_table_find(&tree->devman_devices, &key); 875 788 return hash_table_get_instance(link, node_t, devman_link); 876 789 } … … 928 841 /** Insert new device into device tree. 929 842 * 843 * The device tree's rwlock should be already held exclusively when calling this 844 * function. 845 * 930 846 * @param tree The device tree. 931 847 * @param node The newly added device node. … … 942 858 assert(tree != NULL); 943 859 assert(dev_name != NULL); 944 assert(fibril_rwlock_is_write_locked(&tree->rwlock));945 860 946 861 node->name = dev_name; 947 862 if (!set_dev_path(node, parent)) { 863 fibril_rwlock_write_unlock(&tree->rwlock); 948 864 return false; 949 865 } … … 1061 977 1062 978 info = (dev_class_info_t *) malloc(sizeof(dev_class_info_t)); 1063 if (info != NULL) {979 if (info != NULL) 1064 980 memset(info, 0, sizeof(dev_class_info_t)); 1065 link_initialize(&info->dev_classes);1066 link_initialize(&info->devmap_link);1067 link_initialize(&info->link);1068 }1069 981 1070 982 return info; … … 1171 1083 while (link != &class_list->classes) { 1172 1084 cl = list_get_instance(link, dev_class_t, link); 1173 if (str_cmp(cl->name, class_name) == 0) {1085 if (str_cmp(cl->name, class_name) == 0) 1174 1086 return cl; 1175 }1176 link = link->next;1177 1087 } 1178 1088 … … 1190 1100 fibril_rwlock_initialize(&class_list->rwlock); 1191 1101 hash_table_create(&class_list->devmap_devices, DEVICE_BUCKETS, 1, 1192 &devmap_devices_ class_ops);1102 &devmap_devices_ops); 1193 1103 } 1194 1104 … … 1238 1148 hash_table_insert(&class_list->devmap_devices, &key, &cli->devmap_link); 1239 1149 fibril_rwlock_write_unlock(&class_list->rwlock); 1240 1241 assert(find_devmap_class_device(class_list, cli->devmap_handle) != NULL);1242 1150 } 1243 1151
Note:
See TracChangeset
for help on using the changeset viewer.