Changeset 957cfa58 in mainline
- Timestamp:
- 2010-05-26T20:25:43Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- c9f3b45c
- Parents:
- d51ee2b
- Location:
- uspace/srv/devman
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/devman/devman.c
rd51ee2b r957cfa58 39 39 #include "devman.h" 40 40 41 // hash table operations 42 43 static hash_index_t devices_hash(unsigned long key[]) 44 { 45 return key[0] % DEVICE_BUCKETS; 46 } 47 48 static int devman_devices_compare(unsigned long key[], hash_count_t keys, link_t *item) 49 { 50 node_t *dev = hash_table_get_instance(item, node_t, devman_link); 51 return (dev->handle == (device_handle_t) key[0]); 52 } 53 54 static int devmap_devices_compare(unsigned long key[], hash_count_t keys, link_t *item) 55 { 56 node_t *dev = hash_table_get_instance(item, node_t, devmap_link); 57 return (dev->devmap_handle == (dev_handle_t) key[0]); 58 } 59 60 static void devices_remove_callback(link_t *item) 61 { 62 } 63 64 static hash_table_operations_t devman_devices_ops = { 65 .hash = devices_hash, 66 .compare = devman_devices_compare, 67 .remove_callback = devices_remove_callback 68 }; 69 70 static hash_table_operations_t devmap_devices_ops = { 71 .hash = devices_hash, 72 .compare = devmap_devices_compare, 73 .remove_callback = devices_remove_callback 74 }; 75 41 76 /** Allocate and initialize a new driver structure. 42 77 * … … 584 619 printf(NAME ": init_device_tree.\n"); 585 620 586 memset(tree->node_map, 0, MAX_DEV * sizeof(node_t *)); 587 588 atomic_set(&tree->current_handle, 0); 621 tree->current_handle = 0; 622 623 hash_table_create(&tree->devman_devices, DEVICE_BUCKETS, 1, &devman_devices_ops); 624 hash_table_create(&tree->devmap_devices, DEVICE_BUCKETS, 1, &devmap_devices_ops); 625 626 fibril_rwlock_initialize(&tree->rwlock); 589 627 590 628 // create root node and add it to the device tree … … 630 668 /** Insert new device into device tree. 631 669 * 670 * The device tree's rwlock should be already held exclusively when calling this function. 671 * 632 672 * @param tree the device tree. 633 673 * @param node the newly added device node. … … 644 684 node->name = dev_name; 645 685 if (!set_dev_path(node, parent)) { 686 fibril_rwlock_write_unlock(&tree->rwlock); 646 687 return false; 647 688 } 648 689 649 690 // add the node to the handle-to-node map 650 node->handle = atomic_postinc(&tree->current_handle); 651 if (node->handle >= MAX_DEV) { 652 printf(NAME ": failed to add device to device tree, because maximum number of devices was reached.\n"); 653 free(node->pathname); 654 node->pathname = NULL; 655 atomic_postdec(&tree->current_handle); 656 return false; 657 } 658 tree->node_map[node->handle] = node; 691 node->handle = ++tree->current_handle; 692 unsigned long key = node->handle; 693 hash_table_insert(&tree->devman_devices, &key, &node->devman_link); 659 694 660 695 // add the node to the list of its parent's children 661 696 node->parent = parent; 662 697 if (NULL != parent) { 663 fibril_mutex_lock(&parent->children_mutex); 664 list_append(&node->sibling, &parent->children); 665 fibril_mutex_unlock(&parent->children_mutex); 666 } 698 list_append(&node->sibling, &parent->children); 699 } 667 700 return true; 668 701 } … … 678 711 node_t * find_dev_node_by_path(dev_tree_t *tree, char *path) 679 712 { 713 fibril_rwlock_read_lock(&tree->rwlock); 714 680 715 node_t *dev = tree->root_node; 681 716 // relative path to the device from its parent (but with '/' at the beginning) … … 702 737 } 703 738 739 fibril_rwlock_read_unlock(&tree->rwlock); 740 704 741 return dev; 705 742 } … … 708 745 * Find child device node with a specified name. 709 746 * 747 * Device tree rwlock should be held at least for reading. 748 * 710 749 * @param parent the parent device node. 711 750 * @param name the name of the child device node. … … 717 756 node_t *dev; 718 757 link_t *link; 719 720 fibril_mutex_lock(&parent->children_mutex); 758 721 759 link = parent->children.next; 722 760 … … 725 763 726 764 if (0 == str_cmp(name, dev->name)) { 727 fibril_mutex_unlock(&parent->children_mutex);728 765 return dev; 729 766 } … … 731 768 link = link->next; 732 769 } 733 734 fibril_mutex_unlock(&parent->children_mutex); 770 735 771 return NULL; 736 772 } -
uspace/srv/devman/devman.h
rd51ee2b r957cfa58 39 39 #include <str.h> 40 40 #include <adt/list.h> 41 #include <adt/hash_table.h> 41 42 #include <ipc/ipc.h> 42 43 #include <ipc/devman.h> … … 50 51 51 52 #define MATCH_EXT ".ma" 52 #define MAX_DEV25653 #define DEVICE_BUCKETS 256 53 54 54 55 struct node; … … 115 116 /** List of child device nodes. */ 116 117 link_t children; 117 /** Fibril mutex for the list of child device nodes of this node. */118 fibril_mutex_t children_mutex;119 118 /** List of device ids for device-to-driver matching.*/ 120 119 match_id_list_t match_ids; … … 128 127 /** The list of device classes to which this device belongs.*/ 129 128 link_t classes; 129 /** Devmap handle if the device is registered by devmapper. */ 130 dev_handle_t devmap_handle; 131 /** Used by the hash table of devices indexed by devman device handles.*/ 132 link_t devman_link; 133 /** Used by the hash table of devices indexed by devmap device handles.*/ 134 link_t devmap_link; 130 135 }; 136 131 137 132 138 /** Represents device tree. … … 136 142 node_t *root_node; 137 143 /** The next available handle - handles are assigned in a sequential manner.*/ 138 atomic_t current_handle; 139 /** Handle-to-node mapping. */ 140 node_t * node_map[MAX_DEV]; 144 device_handle_t current_handle; 145 /** Synchronize access to the device tree.*/ 146 fibril_rwlock_t rwlock; 147 /** Hash table of all devices indexed by devman handles.*/ 148 hash_table_t devman_devices; 149 /** Hash table of devices registered by devmapper, indexed by devmap handles.*/ 150 hash_table_t devmap_devices; 151 141 152 } dev_tree_t; 142 153 … … 277 288 list_initialize(&res->children); 278 289 list_initialize(&res->match_ids.ids); 279 fibril_mutex_initialize(&res->children_mutex);280 290 281 291 return res; … … 301 311 * Find the device node structure of the device witch has the specified handle. 302 312 * 313 * Device tree's rwlock should be held at least for reading. 314 * 303 315 * @param tree the device tree where we look for the device node. 304 316 * @param handle the handle of the device. 305 317 * @return the device node. 306 318 */ 307 static inline node_t * find_dev_node(dev_tree_t *tree, long handle) 308 { 309 if (handle < MAX_DEV) { 310 return tree->node_map[handle]; 311 } 312 return NULL; 319 static inline node_t * find_dev_node_no_lock(dev_tree_t *tree, device_handle_t handle) 320 { 321 unsigned long key = handle; 322 link_t *link = hash_table_find(&tree->devman_devices, &key); 323 return hash_table_get_instance(link, node_t, devman_link); 324 } 325 326 /** 327 * Find the device node structure of the device witch has the specified handle. 328 * 329 * @param tree the device tree where we look for the device node. 330 * @param handle the handle of the device. 331 * @return the device node. 332 */ 333 static inline node_t * find_dev_node(dev_tree_t *tree, device_handle_t handle) 334 { 335 node_t *node = NULL; 336 337 fibril_rwlock_read_lock(&tree->rwlock); 338 339 node = find_dev_node_no_lock(tree, handle); 340 341 fibril_rwlock_read_unlock(&tree->rwlock); 342 343 return node; 313 344 } 314 345 -
uspace/srv/devman/main.c
rd51ee2b r957cfa58 246 246 static void devman_add_child(ipc_callid_t callid, ipc_call_t *call) 247 247 { 248 // 248 //printf(NAME ": devman_add_child\n"); 249 249 250 250 device_handle_t parent_handle = IPC_GET_ARG1(*call); 251 251 ipcarg_t match_count = IPC_GET_ARG2(*call); 252 253 node_t *parent = find_dev_node(&device_tree, parent_handle); 252 dev_tree_t *tree = &device_tree; 253 254 fibril_rwlock_write_lock(&tree->rwlock); 255 node_t *parent = find_dev_node_no_lock(&device_tree, parent_handle); 254 256 255 257 if (NULL == parent) { 258 fibril_rwlock_write_unlock(&tree->rwlock); 256 259 ipc_answer_0(callid, ENOENT); 257 260 return; … … 261 264 int rc = async_string_receive(&dev_name, DEVMAN_NAME_MAXLEN, NULL); 262 265 if (EOK != rc) { 266 fibril_rwlock_write_unlock(&tree->rwlock); 263 267 ipc_answer_0(callid, rc); 264 268 return; 265 269 } 266 // 270 //printf(NAME ": newly added child device's name is '%s'.\n", dev_name); 267 271 268 272 node_t *node = create_dev_node(); 269 273 if (!insert_dev_node(&device_tree, node, dev_name, parent)) { 274 fibril_rwlock_write_unlock(&tree->rwlock); 270 275 delete_dev_node(node); 271 276 ipc_answer_0(callid, ENOMEM); 272 277 return; 273 278 } 279 fibril_rwlock_write_unlock(&tree->rwlock); 274 280 275 281 printf(NAME ": devman_add_child %s\n", node->pathname); … … 281 287 282 288 // try to find suitable driver and assign it to the device 283 assign_driver(node, &drivers_list); 289 assign_driver(node, &drivers_list); 284 290 } 285 291
Note:
See TracChangeset
for help on using the changeset viewer.