Changeset ce89036b in mainline


Ignore:
Timestamp:
2010-06-01T19:49:48Z (14 years ago)
Author:
Lenka Trochtova <trochtova.lenka@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a32defa
Parents:
5159ae9
Message:

Add the 'class' namespace to the device mapper. When a driver adds a device to a class, the device is registered with its class specific name by the device mapper in the 'class' namespace.

Location:
uspace/srv/devman
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/devman/devman.c

    r5159ae9 rce89036b  
    831831{
    832832        dev_class_t *cl;
    833         fibril_mutex_lock(&class_list->classes_mutex); 
     833        fibril_rwlock_write_lock(&class_list->rwlock); 
    834834        cl = find_dev_class_no_lock(class_list, class_name);
    835835        if (NULL == cl) {
     
    841841                }               
    842842        }       
    843         fibril_mutex_unlock(&class_list->classes_mutex);
     843        fibril_rwlock_write_unlock(&class_list->rwlock);
    844844        return cl;
    845845}
     
    859859}
    860860
     861void 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
     871node_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
     887node_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
    861906/** @}
    862907 */
  • uspace/srv/devman/devman.h

    r5159ae9 rce89036b  
    5252#define MATCH_EXT ".ma"
    5353#define DEVICE_BUCKETS 256
     54
     55#define DEVMAP_CLASS_NAMESPACE "class"
     56#define DEVMAP_DEVICE_NAMESPACE "devices"
     57#define DEVMAP_SEPARATOR "\\"
    5458
    5559struct node;
     
    149153        /** Hash table of devices registered by devmapper, indexed by devmap handles.*/
    150154        hash_table_t devmap_devices;
    151        
    152155} dev_tree_t;
    153156
     
    183186        /** The handle of the device by device mapper in the class namespace.*/
    184187        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;
    185190} dev_class_info_t;
    186191
     
    189194        /** List of classes */
    190195        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;
    191198        /** Fibril mutex for list of classes. */
    192         fibril_mutex_t classes_mutex;   
     199        fibril_rwlock_t rwlock;
    193200} class_list_t;
    194201
     
    404411dev_class_info_t * add_device_to_class(node_t *dev, dev_class_t *cl, const char *base_dev_name);
    405412
    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 }
     413void init_class_list(class_list_t *class_list);
    411414
    412415dev_class_t * get_dev_class(class_list_t *class_list, char *class_name);
     
    418421}
    419422
     423
     424// devmap devices
     425
     426node_t *find_devmap_tree_device(dev_tree_t *tree, dev_handle_t devmap_handle);
     427node_t *find_devmap_class_device(class_list_t *classes, dev_handle_t devmap_handle);
     428
    420429#endif
    421430
  • uspace/srv/devman/main.c

    r5159ae9 rce89036b  
    5353#include <ipc/driver.h>
    5454#include <thread.h>
     55#include <devmap.h>
    5556
    5657#include "devman.h"
     
    6162static dev_tree_t device_tree;
    6263static class_list_t class_list;
    63 
    6464
    6565/**
     
    239239        ipc_answer_1(callid, EOK, node->handle);
    240240       
    241         // try to find suitable driver and assign it to the device     
     241        // try to find suitable driver and assign it to the device
    242242        assign_driver(node, &drivers_list);     
    243243}
    244244
     245static 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
    245260static void devman_add_device_to_class(ipc_callid_t callid, ipc_call_t *call)
    246 {               
     261{
    247262        device_handle_t handle = IPC_GET_ARG1(*call);
    248263       
     
    262277       
    263278        dev_class_t *cl = get_dev_class(&class_list, class_name);
    264        
     279               
    265280        dev_class_info_t *class_info = add_device_to_class(dev, cl, NULL);
    266281       
    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);
    268284       
    269285        printf(NAME ": device '%s' added to class '%s', class name '%s' was asigned to it\n", dev->pathname, class_name, class_info->dev_name);
     
    424440                printf(NAME ": devman_forward: cound not forward to driver %s ", driver->name);
    425441                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);
    429447        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 */
     452static 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);     
    430473}
    431474
     
    434477 */
    435478static 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       
    437493        // Select interface
    438494        switch ((ipcarg_t) (IPC_GET_ARG1(*icall))) {
     
    479535        init_class_list(&class_list);
    480536       
     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       
    481542        return true;
    482543}
Note: See TracChangeset for help on using the changeset viewer.