Changeset ce89036b in mainline
- Timestamp:
- 2010-06-01T19:49:48Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- a32defa
- Parents:
- 5159ae9
- Location:
- uspace/srv/devman
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/devman/devman.c
r5159ae9 rce89036b 831 831 { 832 832 dev_class_t *cl; 833 fibril_ mutex_lock(&class_list->classes_mutex);833 fibril_rwlock_write_lock(&class_list->rwlock); 834 834 cl = find_dev_class_no_lock(class_list, class_name); 835 835 if (NULL == cl) { … … 841 841 } 842 842 } 843 fibril_ mutex_unlock(&class_list->classes_mutex);843 fibril_rwlock_write_unlock(&class_list->rwlock); 844 844 return cl; 845 845 } … … 859 859 } 860 860 861 void init_class_list(class_list_t *class_list) 862 { 863 list_initialize(&class_list->classes); 864 fibril_rwlock_initialize(&class_list->rwlock); 865 hash_table_create(&class_list->devmap_devices, DEVICE_BUCKETS, 1, &devmap_devices_ops); 866 } 867 868 869 // devmap devices 870 871 node_t *find_devmap_tree_device(dev_tree_t *tree, dev_handle_t devmap_handle) 872 { 873 node_t *dev = NULL; 874 link_t *link; 875 unsigned long key = (unsigned long)devmap_handle; 876 877 fibril_rwlock_read_lock(&tree->rwlock); 878 link = hash_table_find(&tree->devmap_devices, &key); 879 if (NULL != link) { 880 dev = hash_table_get_instance(link, node_t, devmap_link); 881 } 882 fibril_rwlock_read_unlock(&tree->rwlock); 883 884 return dev; 885 } 886 887 node_t *find_devmap_class_device(class_list_t *classes, dev_handle_t devmap_handle) 888 { 889 node_t *dev = NULL; 890 dev_class_info_t *cli; 891 link_t *link; 892 unsigned long key = (unsigned long)devmap_handle; 893 894 fibril_rwlock_read_lock(&classes->rwlock); 895 link = hash_table_find(&classes->devmap_devices, &key); 896 if (NULL != link) { 897 cli = hash_table_get_instance(link, dev_class_info_t, devmap_link); 898 dev = cli->dev; 899 } 900 fibril_rwlock_read_unlock(&classes->rwlock); 901 902 return dev; 903 } 904 905 861 906 /** @} 862 907 */ -
uspace/srv/devman/devman.h
r5159ae9 rce89036b 52 52 #define MATCH_EXT ".ma" 53 53 #define DEVICE_BUCKETS 256 54 55 #define DEVMAP_CLASS_NAMESPACE "class" 56 #define DEVMAP_DEVICE_NAMESPACE "devices" 57 #define DEVMAP_SEPARATOR "\\" 54 58 55 59 struct node; … … 149 153 /** Hash table of devices registered by devmapper, indexed by devmap handles.*/ 150 154 hash_table_t devmap_devices; 151 152 155 } dev_tree_t; 153 156 … … 183 186 /** The handle of the device by device mapper in the class namespace.*/ 184 187 dev_handle_t devmap_handle; 188 /** Link in the hash table of devices registered by the devmapper using their class names.*/ 189 link_t devmap_link; 185 190 } dev_class_info_t; 186 191 … … 189 194 /** List of classes */ 190 195 link_t classes; 196 /** Hash table of devices registered by devmapper using their class name, indexed by devmap handles.*/ 197 hash_table_t devmap_devices; 191 198 /** Fibril mutex for list of classes. */ 192 fibril_ mutex_t classes_mutex;199 fibril_rwlock_t rwlock; 193 200 } class_list_t; 194 201 … … 404 411 dev_class_info_t * add_device_to_class(node_t *dev, dev_class_t *cl, const char *base_dev_name); 405 412 406 static inline void init_class_list(class_list_t *class_list) 407 { 408 list_initialize(&class_list->classes); 409 fibril_mutex_initialize(&class_list->classes_mutex); 410 } 413 void init_class_list(class_list_t *class_list); 411 414 412 415 dev_class_t * get_dev_class(class_list_t *class_list, char *class_name); … … 418 421 } 419 422 423 424 // devmap devices 425 426 node_t *find_devmap_tree_device(dev_tree_t *tree, dev_handle_t devmap_handle); 427 node_t *find_devmap_class_device(class_list_t *classes, dev_handle_t devmap_handle); 428 420 429 #endif 421 430 -
uspace/srv/devman/main.c
r5159ae9 rce89036b 53 53 #include <ipc/driver.h> 54 54 #include <thread.h> 55 #include <devmap.h> 55 56 56 57 #include "devman.h" … … 61 62 static dev_tree_t device_tree; 62 63 static class_list_t class_list; 63 64 64 65 65 /** … … 239 239 ipc_answer_1(callid, EOK, node->handle); 240 240 241 // try to find suitable driver and assign it to the device 241 // try to find suitable driver and assign it to the device 242 242 assign_driver(node, &drivers_list); 243 243 } 244 244 245 static void devmap_register_class_dev(dev_class_info_t *cli) 246 { 247 // create devmap path and name for the device 248 char *devmap_pathname = NULL; 249 asprintf(&devmap_pathname, "%s/%s%s%s", DEVMAP_CLASS_NAMESPACE, cli->dev_class->name, DEVMAP_SEPARATOR, cli->dev_name); 250 if (NULL == devmap_pathname) { 251 return; 252 } 253 254 // register the device by the device mapper and remember its devmap handle 255 devmap_device_register(devmap_pathname, &cli->devmap_handle); 256 257 free(devmap_pathname); 258 } 259 245 260 static void devman_add_device_to_class(ipc_callid_t callid, ipc_call_t *call) 246 { 261 { 247 262 device_handle_t handle = IPC_GET_ARG1(*call); 248 263 … … 262 277 263 278 dev_class_t *cl = get_dev_class(&class_list, class_name); 264 279 265 280 dev_class_info_t *class_info = add_device_to_class(dev, cl, NULL); 266 281 267 // TODO register the device's class alias by devmapper 282 // register the device's class alias by devmapper 283 devmap_register_class_dev(class_info); 268 284 269 285 printf(NAME ": device '%s' added to class '%s', class name '%s' was asigned to it\n", dev->pathname, class_name, class_info->dev_name); … … 424 440 printf(NAME ": devman_forward: cound not forward to driver %s ", driver->name); 425 441 printf("the driver's phone is %x).\n", driver->phone); 426 return; 427 } 428 printf(NAME ": devman_forward: forward connection to device %s to driver %s.\n", dev->pathname, driver->name); 442 ipc_answer_0(iid, EINVAL); 443 return; 444 } 445 printf(NAME ": devman_forward: forward connection to device %s to driver %s.\n", 446 dev->pathname, driver->name); 429 447 ipc_forward_fast(iid, driver->phone, method, dev->handle, 0, IPC_FF_NONE); 448 } 449 450 /** Function for handling connections from a client forwarded by the device mapper to the device manager. 451 */ 452 static void devman_connection_devmapper(ipc_callid_t iid, ipc_call_t *icall) 453 { 454 dev_handle_t devmap_handle = IPC_GET_METHOD(*icall); 455 node_t *dev = find_devmap_tree_device(&device_tree, devmap_handle); 456 if (NULL == dev) { 457 dev = find_devmap_class_device(&class_list, devmap_handle); 458 } 459 460 if (NULL == dev || NULL == dev->drv) { 461 ipc_answer_0(iid, ENOENT); 462 return; 463 } 464 465 if (DEVICE_USABLE != dev->state || dev->drv->phone <= 0) { 466 ipc_answer_0(iid, EINVAL); 467 return; 468 } 469 470 printf(NAME ": devman_connection_devmapper: forward connection to device %s to driver %s.\n", 471 dev->pathname, dev->drv->name); 472 ipc_forward_fast(iid, dev->drv->phone, DRIVER_CLIENT, dev->handle, 0, IPC_FF_NONE); 430 473 } 431 474 … … 434 477 */ 435 478 static void devman_connection(ipc_callid_t iid, ipc_call_t *icall) 436 { 479 { 480 // Silly hack to enable the device manager to register as a driver by the device mapper. 481 // If the ipc method is not IPC_M_CONNECT_ME_TO, this is not the forwarded connection from naming service, 482 // so it must be a connection from the devmapper which thinks this is a devmapper-style driver. 483 // So pretend this is a devmapper-style driver. 484 // (This does not work for device with handle == IPC_M_CONNECT_ME_TO, 485 // because devmapper passes device handle to the driver as an ipc method.) 486 if (IPC_M_CONNECT_ME_TO != IPC_GET_METHOD(*icall)) { 487 devman_connection_devmapper(iid, icall); 488 } 489 490 // ipc method is IPC_M_CONNECT_ME_TO, so this is forwarded connection from naming service 491 // by which we registered as device manager, so be device manager 492 437 493 // Select interface 438 494 switch ((ipcarg_t) (IPC_GET_ARG1(*icall))) { … … 479 535 init_class_list(&class_list); 480 536 537 // !!! devman_connection ... as the device manager is not a real devmap driver 538 // (it uses a completely different ipc protocol than an ordinary devmap driver) 539 // forwarding a connection from client to the devman by devmapper would not work 540 devmap_driver_register(NAME, devman_connection); 541 481 542 return true; 482 543 }
Note:
See TracChangeset
for help on using the changeset viewer.