Ignore:
File:
1 edited

Legend:

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

    rd0dd7b5 r9934f7d  
    5656#include <ipc/driver.h>
    5757#include <thread.h>
    58 #include <loc.h>
     58#include <devmap.h>
    5959
    6060#include "devman.h"
     
    6464static driver_list_t drivers_list;
    6565static dev_tree_t device_tree;
     66static class_list_t class_list;
    6667
    6768/** Register running driver. */
     
    278279                return;
    279280        }
    280        
     281
    281282        fun_node_t *fun = create_fun_node();
    282         fun->ftype = ftype;
    283        
    284283        if (!insert_fun_node(&device_tree, fun, fun_name, pdev)) {
    285284                fibril_rwlock_write_unlock(&tree->rwlock);
     
    327326                }
    328327        } else {
    329                 loc_register_tree_function(fun, tree);
     328                devmap_register_tree_function(fun, tree);
    330329        }
    331330       
     
    334333}
    335334
    336 static void devman_add_function_to_cat(ipc_callid_t callid, ipc_call_t *call)
     335static void devmap_register_class_dev(dev_class_info_t *cli)
     336{
     337        /* Create devmap path and name for the device. */
     338        char *devmap_pathname = NULL;
     339
     340        asprintf(&devmap_pathname, "%s/%s%c%s", DEVMAP_CLASS_NAMESPACE,
     341            cli->dev_class->name, DEVMAP_SEPARATOR, cli->dev_name);
     342        if (devmap_pathname == NULL)
     343                return;
     344       
     345        /*
     346         * Register the device by the device mapper and remember its devmap
     347         * handle.
     348         */
     349        devmap_device_register_with_iface(devmap_pathname,
     350            &cli->devmap_handle, DEVMAN_CONNECT_FROM_DEVMAP);
     351       
     352        /*
     353         * Add device to the hash map of class devices registered by device
     354         * mapper.
     355         */
     356        class_add_devmap_function(&class_list, cli);
     357       
     358        free(devmap_pathname);
     359}
     360
     361static void devman_add_function_to_class(ipc_callid_t callid, ipc_call_t *call)
    337362{
    338363        devman_handle_t handle = IPC_GET_ARG1(*call);
    339         category_id_t cat_id;
    340         int rc;
    341        
    342         /* Get category name. */
    343         char *cat_name;
    344         rc = async_data_write_accept((void **) &cat_name, true,
     364       
     365        /* Get class name. */
     366        char *class_name;
     367        int rc = async_data_write_accept((void **) &class_name, true,
    345368            0, 0, 0, 0);
    346369        if (rc != EOK) {
     
    355378        }
    356379       
    357         rc = loc_category_get_id(cat_name, &cat_id, IPC_FLAG_BLOCKING);
    358         if (rc == EOK) {
    359                 loc_service_add_to_cat(fun->service_id, cat_id);
    360         } else {
    361                 log_msg(LVL_ERROR, "Failed adding function `%s' to category "
    362                     "`%s'.", fun->pathname, cat_name);
    363         }
    364        
    365         log_msg(LVL_NOTE, "Function `%s' added to category `%s'.",
    366             fun->pathname, cat_name);
    367 
    368         async_answer_0(callid, EOK);
    369 }
    370 
    371 /** Remove function. */
    372 static void devman_remove_function(ipc_callid_t callid, ipc_call_t *call)
    373 {
    374         devman_handle_t fun_handle = IPC_GET_ARG1(*call);
    375         dev_tree_t *tree = &device_tree;
    376         int rc;
    377        
    378         fibril_rwlock_write_lock(&tree->rwlock);
    379        
    380         fun_node_t *fun = find_fun_node_no_lock(&device_tree, fun_handle);
    381         if (fun == NULL) {
    382                 fibril_rwlock_write_unlock(&tree->rwlock);
    383                 async_answer_0(callid, ENOENT);
    384                 return;
    385         }
    386        
    387         log_msg(LVL_DEBUG, "devman_remove_function(fun='%s')", fun->pathname);
    388        
    389         if (fun->ftype == fun_inner) {
    390                 /* Handle possible descendants */
    391                 /* TODO */
    392                 log_msg(LVL_WARN, "devman_remove_function(): not handling "
    393                     "descendants\n");
    394         } else {
    395                 /* Unregister from location service */
    396                 rc = loc_service_unregister(fun->service_id);
    397                 if (rc != EOK) {
    398                         log_msg(LVL_ERROR, "Failed unregistering tree service.");
    399                         fibril_rwlock_write_unlock(&tree->rwlock);
    400                         async_answer_0(callid, EIO);
    401                         return;
    402                 }
    403         }
    404        
    405         remove_fun_node(&device_tree, fun);
    406         fibril_rwlock_write_unlock(&tree->rwlock);
    407         delete_fun_node(fun);
    408        
    409         log_msg(LVL_DEBUG, "devman_remove_function() succeeded.");
     380        dev_class_t *cl = get_dev_class(&class_list, class_name);
     381        dev_class_info_t *class_info = add_function_to_class(fun, cl, NULL);
     382       
     383        /* Register the device's class alias by devmapper. */
     384        devmap_register_class_dev(class_info);
     385       
     386        log_msg(LVL_NOTE, "Function `%s' added to class `%s' as `%s'.",
     387            fun->pathname, class_name, class_info->dev_name);
     388
    410389        async_answer_0(callid, EOK);
    411390}
     
    460439                        devman_add_function(callid, &call);
    461440                        break;
    462                 case DEVMAN_ADD_DEVICE_TO_CATEGORY:
    463                         devman_add_function_to_cat(callid, &call);
    464                         break;
    465                 case DEVMAN_REMOVE_FUNCTION:
    466                         devman_remove_function(callid, &call);
     441                case DEVMAN_ADD_DEVICE_TO_CLASS:
     442                        devman_add_function_to_class(callid, &call);
    467443                        break;
    468444                default:
     
    497473}
    498474
     475/** Find handle for the device instance identified by device class name. */
     476static void devman_function_get_handle_by_class(ipc_callid_t iid,
     477    ipc_call_t *icall)
     478{
     479        char *classname;
     480        char *devname;
     481
     482        int rc = async_data_write_accept((void **) &classname, true, 0, 0, 0, 0);
     483        if (rc != EOK) {
     484                async_answer_0(iid, rc);
     485                return;
     486        }
     487        rc = async_data_write_accept((void **) &devname, true, 0, 0, 0, 0);
     488        if (rc != EOK) {
     489                free(classname);
     490                async_answer_0(iid, rc);
     491                return;
     492        }
     493
     494
     495        fun_node_t *fun = find_fun_node_by_class(&class_list,
     496            classname, devname);
     497
     498        free(classname);
     499        free(devname);
     500
     501        if (fun == NULL) {
     502                async_answer_0(iid, ENOENT);
     503                return;
     504        }
     505
     506        async_answer_1(iid, EOK, fun->handle);
     507}
     508
    499509/** Find device path by its handle. */
    500510static void devman_get_device_path_by_handle(ipc_callid_t iid,
     
    534544}
    535545
    536 /** Find handle for the function instance identified by its service ID. */
    537 static void devman_fun_sid_to_handle(ipc_callid_t iid, ipc_call_t *icall)
    538 {
    539         fun_node_t *fun;
    540 
    541         fun = find_loc_tree_function(&device_tree, IPC_GET_ARG1(*icall));
    542        
    543         if (fun == NULL) {
    544                 async_answer_0(iid, ENOENT);
    545                 return;
    546         }
    547 
    548         async_answer_1(iid, EOK, fun->handle);
    549 }
    550546
    551547/** Function for handling connections from a client to the device manager. */
     
    566562                        devman_function_get_handle(callid, &call);
    567563                        break;
     564                case DEVMAN_DEVICE_GET_HANDLE_BY_CLASS:
     565                        devman_function_get_handle_by_class(callid, &call);
     566                        break;
    568567                case DEVMAN_DEVICE_GET_DEVICE_PATH:
    569568                        devman_get_device_path_by_handle(callid, &call);
    570                         break;
    571                 case DEVMAN_FUN_SID_TO_HANDLE:
    572                         devman_fun_sid_to_handle(callid, &call);
    573569                        break;
    574570                default:
     
    663659}
    664660
    665 /** Function for handling connections from a client forwarded by the location
    666  * service to the device manager. */
    667 static void devman_connection_loc(ipc_callid_t iid, ipc_call_t *icall)
    668 {
    669         service_id_t service_id = IPC_GET_ARG2(*icall);
     661/** Function for handling connections from a client forwarded by the device
     662 * mapper to the device manager. */
     663static void devman_connection_devmapper(ipc_callid_t iid, ipc_call_t *icall)
     664{
     665        devmap_handle_t devmap_handle = IPC_GET_ARG2(*icall);
    670666        fun_node_t *fun;
    671667        dev_node_t *dev;
    672668
    673         fun = find_loc_tree_function(&device_tree, service_id);
     669        fun = find_devmap_tree_function(&device_tree, devmap_handle);
     670        if (fun == NULL)
     671                fun = find_devmap_class_function(&class_list, devmap_handle);
    674672       
    675673        if (fun == NULL || fun->dev->drv == NULL) {
    676                 log_msg(LVL_WARN, "devman_connection_loc(): function "
    677                     "not found.\n");
    678674                async_answer_0(iid, ENOENT);
    679675                return;
     
    681677       
    682678        dev = fun->dev;
     679       
     680        if ((dev->state != DEVICE_USABLE) || (!dev->drv->sess)) {
     681                async_answer_0(iid, EINVAL);
     682                return;
     683        }
    683684       
    684685        async_exch_t *exch = async_exchange_begin(dev->drv->sess);
     
    688689       
    689690        log_msg(LVL_DEBUG,
    690             "Forwarding loc service request for `%s' function to driver `%s'.",
     691            "Forwarding devmapper request for `%s' function to driver `%s'.",
    691692            fun->pathname, dev->drv->name);
    692693}
     
    707708                devman_forward(iid, icall, false);
    708709                break;
    709         case DEVMAN_CONNECT_FROM_LOC:
    710                 /* Someone connected through loc node. */
    711                 devman_connection_loc(iid, icall);
     710        case DEVMAN_CONNECT_FROM_DEVMAP:
     711                /* Someone connected through devmap node. */
     712                devman_connection_devmapper(iid, icall);
    712713                break;
    713714        case DEVMAN_CONNECT_TO_PARENTS_DEVICE:
     
    742743        }
    743744
     745        init_class_list(&class_list);
     746       
    744747        /*
    745          * !!! devman_connection ... as the device manager is not a real loc
     748         * !!! devman_connection ... as the device manager is not a real devmap
    746749         * driver (it uses a completely different ipc protocol than an ordinary
    747          * loc driver) forwarding a connection from client to the devman by
    748          * location service would not work.
     750         * devmap driver) forwarding a connection from client to the devman by
     751         * devmapper would not work.
    749752         */
    750         loc_server_register(NAME, devman_connection);
     753        devmap_driver_register(NAME, devman_connection);
    751754       
    752755        return true;
     
    757760        printf(NAME ": HelenOS Device Manager\n");
    758761
    759         if (log_init(NAME, LVL_WARN) != EOK) {
     762        if (log_init(NAME, LVL_ERROR) != EOK) {
    760763                printf(NAME ": Error initializing logging subsystem.\n");
    761764                return -1;
Note: See TracChangeset for help on using the changeset viewer.