Ignore:
File:
1 edited

Legend:

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

    rc6c389ed r3ad7b1c  
    3636 */
    3737
     38#include <inttypes.h>
    3839#include <assert.h>
    3940#include <ipc/services.h>
     
    4243#include <stdio.h>
    4344#include <errno.h>
     45#include <str_error.h>
    4446#include <bool.h>
    4547#include <fibril_synch.h>
     
    5052#include <sys/stat.h>
    5153#include <ctype.h>
     54#include <io/log.h>
    5255#include <ipc/devman.h>
    5356#include <ipc/driver.h>
     
    7073        driver_t *driver = NULL;
    7174
    72         printf(NAME ": devman_driver_register \n");
     75        log_msg(LVL_DEBUG, "devman_driver_register");
    7376       
    7477        iid = async_get_call(&icall);
    75         if (IPC_GET_METHOD(icall) != DEVMAN_DRIVER_REGISTER) {
    76                 ipc_answer_0(iid, EREFUSED);
     78        if (IPC_GET_IMETHOD(icall) != DEVMAN_DRIVER_REGISTER) {
     79                async_answer_0(iid, EREFUSED);
    7780                return NULL;
    7881        }
     
    8386        int rc = async_data_write_accept((void **) &drv_name, true, 0, 0, 0, 0);
    8487        if (rc != EOK) {
    85                 ipc_answer_0(iid, rc);
     88                async_answer_0(iid, rc);
    8689                return NULL;
    8790        }
    8891
    89         printf(NAME ": the %s driver is trying to register by the service.\n",
     92        log_msg(LVL_DEBUG, "The `%s' driver is trying to register.",
    9093            drv_name);
    9194       
    9295        /* Find driver structure. */
    9396        driver = find_driver(&drivers_list, drv_name);
    94        
    9597        if (driver == NULL) {
    96                 printf(NAME ": no driver named %s was found.\n", drv_name);
     98                log_msg(LVL_ERROR, "No driver named `%s' was found.", drv_name);
    9799                free(drv_name);
    98100                drv_name = NULL;
    99                 ipc_answer_0(iid, ENOENT);
     101                async_answer_0(iid, ENOENT);
    100102                return NULL;
    101103        }
     
    104106        drv_name = NULL;
    105107       
     108        fibril_mutex_lock(&driver->driver_mutex);
     109       
     110        if (driver->phone >= 0) {
     111                /* We already have a connection to the driver. */
     112                log_msg(LVL_ERROR, "Driver '%s' already started.\n",
     113                    driver->name);
     114                fibril_mutex_unlock(&driver->driver_mutex);
     115                async_answer_0(iid, EEXISTS);
     116                return NULL;
     117        }
     118       
     119        switch (driver->state) {
     120        case DRIVER_NOT_STARTED:
     121                /* Somebody started the driver manually. */
     122                log_msg(LVL_NOTE, "Driver '%s' started manually.\n",
     123                    driver->name);
     124                driver->state = DRIVER_STARTING;
     125                break;
     126        case DRIVER_STARTING:
     127                /* The expected case */
     128                break;
     129        case DRIVER_RUNNING:
     130                /* Should not happen since we do not have a connected phone */
     131                assert(false);
     132        }
     133       
    106134        /* Create connection to the driver. */
    107         printf(NAME ":  creating connection to the %s driver.\n", driver->name);
     135        log_msg(LVL_DEBUG, "Creating connection to the `%s' driver.",
     136            driver->name);
    108137        ipc_call_t call;
    109138        ipc_callid_t callid = async_get_call(&call);
    110         if (IPC_GET_METHOD(call) != IPC_M_CONNECT_TO_ME) {
    111                 ipc_answer_0(callid, ENOTSUP);
    112                 ipc_answer_0(iid, ENOTSUP);
     139        if (IPC_GET_IMETHOD(call) != IPC_M_CONNECT_TO_ME) {
     140                fibril_mutex_unlock(&driver->driver_mutex);
     141                async_answer_0(callid, ENOTSUP);
     142                async_answer_0(iid, ENOTSUP);
    113143                return NULL;
    114144        }
    115145       
    116146        /* Remember driver's phone. */
    117         set_driver_phone(driver, IPC_GET_ARG5(call));
    118        
    119         printf(NAME ": the %s driver was successfully registered as running.\n",
     147        driver->phone = IPC_GET_ARG5(call);
     148       
     149        fibril_mutex_unlock(&driver->driver_mutex);
     150       
     151        log_msg(LVL_NOTE,
     152            "The `%s' driver was successfully registered as running.",
    120153            driver->name);
    121154       
    122         ipc_answer_0(callid, EOK);
    123         ipc_answer_0(iid, EOK);
     155        async_answer_0(callid, EOK);
     156        async_answer_0(iid, EOK);
    124157       
    125158        return driver;
     
    140173       
    141174        callid = async_get_call(&call);
    142         if (DEVMAN_ADD_MATCH_ID != IPC_GET_METHOD(call)) {
    143                 printf(NAME ": ERROR: devman_receive_match_id - invalid "
    144                     "protocol.\n");
    145                 ipc_answer_0(callid, EINVAL);
     175        if (DEVMAN_ADD_MATCH_ID != IPC_GET_IMETHOD(call)) {
     176                log_msg(LVL_ERROR,
     177                    "Invalid protocol when trying to receive match id.");
     178                async_answer_0(callid, EINVAL);
    146179                delete_match_id(match_id);
    147180                return EINVAL;
     
    149182       
    150183        if (match_id == NULL) {
    151                 printf(NAME ": ERROR: devman_receive_match_id - failed to "
    152                     "allocate match id.\n");
    153                 ipc_answer_0(callid, ENOMEM);
     184                log_msg(LVL_ERROR, "Failed to allocate match id.");
     185                async_answer_0(callid, ENOMEM);
    154186                return ENOMEM;
    155187        }
    156188       
    157         ipc_answer_0(callid, EOK);
     189        async_answer_0(callid, EOK);
    158190       
    159191        match_id->score = IPC_GET_ARG1(call);
     
    164196        if (rc != EOK) {
    165197                delete_match_id(match_id);
    166                 printf(NAME ": devman_receive_match_id - failed to receive "
    167                     "match id string.\n");
     198                log_msg(LVL_ERROR, "Failed to receive match id string: %s.",
     199                    str_error(rc));
    168200                return rc;
    169201        }
     
    171203        list_append(&match_id->link, &match_ids->ids);
    172204       
    173         printf(NAME ": received match id '%s', score = %d \n",
     205        log_msg(LVL_DEBUG, "Received match id `%s', score %d.",
    174206            match_id->id, match_id->score);
    175207        return rc;
     
    183215 * @return              Zero on success, negative error code otherwise.
    184216 */
    185 static int devman_receive_match_ids(ipcarg_t match_count,
     217static int devman_receive_match_ids(sysarg_t match_count,
    186218    match_id_list_t *match_ids)
    187219{
     
    196228}
    197229
    198 /** Handle child device registration.
     230static int assign_driver_fibril(void *arg)
     231{
     232        dev_node_t *dev_node = (dev_node_t *) arg;
     233        assign_driver(dev_node, &drivers_list, &device_tree);
     234        return EOK;
     235}
     236
     237/** Handle function registration.
    199238 *
    200239 * Child devices are registered by their parent's device driver.
    201240 */
    202 static void devman_add_child(ipc_callid_t callid, ipc_call_t *call)
    203 {
    204         device_handle_t parent_handle = IPC_GET_ARG1(*call);
    205         ipcarg_t match_count = IPC_GET_ARG2(*call);
     241static void devman_add_function(ipc_callid_t callid, ipc_call_t *call)
     242{
     243        fun_type_t ftype = (fun_type_t) IPC_GET_ARG1(*call);
     244        devman_handle_t dev_handle = IPC_GET_ARG2(*call);
     245        sysarg_t match_count = IPC_GET_ARG3(*call);
    206246        dev_tree_t *tree = &device_tree;
    207247       
    208248        fibril_rwlock_write_lock(&tree->rwlock);
    209         node_t *parent = find_dev_node_no_lock(&device_tree, parent_handle);
    210        
    211         if (parent == NULL) {
     249
     250        dev_node_t *dev = NULL;
     251        dev_node_t *pdev = find_dev_node_no_lock(&device_tree, dev_handle);
     252       
     253        if (pdev == NULL) {
    212254                fibril_rwlock_write_unlock(&tree->rwlock);
    213                 ipc_answer_0(callid, ENOENT);
    214                 return;
    215         }
    216        
    217         char *dev_name = NULL;
    218         int rc = async_data_write_accept((void **)&dev_name, true, 0, 0, 0, 0);
     255                async_answer_0(callid, ENOENT);
     256                return;
     257        }
     258       
     259        if (ftype != fun_inner && ftype != fun_exposed) {
     260                /* Unknown function type */
     261                log_msg(LVL_ERROR,
     262                    "Unknown function type %d provided by driver.",
     263                    (int) ftype);
     264
     265                fibril_rwlock_write_unlock(&tree->rwlock);
     266                async_answer_0(callid, EINVAL);
     267                return;
     268        }
     269       
     270        char *fun_name = NULL;
     271        int rc = async_data_write_accept((void **)&fun_name, true, 0, 0, 0, 0);
    219272        if (rc != EOK) {
    220273                fibril_rwlock_write_unlock(&tree->rwlock);
    221                 ipc_answer_0(callid, rc);
    222                 return;
    223         }
    224        
    225         node_t *node = create_dev_node();
    226         if (!insert_dev_node(&device_tree, node, dev_name, parent)) {
     274                async_answer_0(callid, rc);
     275                return;
     276        }
     277       
     278        /* Check that function with same name is not there already. */
     279        if (find_fun_node_in_device(pdev, fun_name) != NULL) {
    227280                fibril_rwlock_write_unlock(&tree->rwlock);
    228                 delete_dev_node(node);
    229                 ipc_answer_0(callid, ENOMEM);
    230                 return;
     281                async_answer_0(callid, EEXISTS);
     282                printf(NAME ": Warning, driver tried to register `%s' twice.\n",
     283                    fun_name);
     284                free(fun_name);
     285                return;
     286        }
     287
     288        fun_node_t *fun = create_fun_node();
     289        if (!insert_fun_node(&device_tree, fun, fun_name, pdev)) {
     290                fibril_rwlock_write_unlock(&tree->rwlock);
     291                delete_fun_node(fun);
     292                async_answer_0(callid, ENOMEM);
     293                return;
     294        }
     295
     296        if (ftype == fun_inner) {
     297                dev = create_dev_node();
     298                if (dev == NULL) {
     299                        fibril_rwlock_write_unlock(&tree->rwlock);
     300                        delete_fun_node(fun);
     301                        async_answer_0(callid, ENOMEM);
     302                        return;
     303                }
     304
     305                insert_dev_node(tree, dev, fun);
    231306        }
    232307
    233308        fibril_rwlock_write_unlock(&tree->rwlock);
    234309       
    235         printf(NAME ": devman_add_child %s\n", node->pathname);
    236        
    237         devman_receive_match_ids(match_count, &node->match_ids);
     310        log_msg(LVL_DEBUG, "devman_add_function(fun=\"%s\")", fun->pathname);
     311       
     312        devman_receive_match_ids(match_count, &fun->match_ids);
     313
     314        if (ftype == fun_inner) {
     315                assert(dev != NULL);
     316                /*
     317                 * Try to find a suitable driver and assign it to the device.  We do
     318                 * not want to block the current fibril that is used for processing
     319                 * incoming calls: we will launch a separate fibril to handle the
     320                 * driver assigning. That is because assign_driver can actually include
     321                 * task spawning which could take some time.
     322                 */
     323                fid_t assign_fibril = fibril_create(assign_driver_fibril, dev);
     324                if (assign_fibril == 0) {
     325                        /*
     326                         * Fallback in case we are out of memory.
     327                         * Probably not needed as we will die soon anyway ;-).
     328                         */
     329                        (void) assign_driver_fibril(fun);
     330                } else {
     331                        fibril_add_ready(assign_fibril);
     332                }
     333        } else {
     334                devmap_register_tree_function(fun, tree);
     335        }
    238336       
    239337        /* Return device handle to parent's driver. */
    240         ipc_answer_1(callid, EOK, node->handle);
    241        
    242         /* Try to find suitable driver and assign it to the device. */
    243         assign_driver(node, &drivers_list, &device_tree);
     338        async_answer_1(callid, EOK, fun->handle);
    244339}
    245340
     
    258353         * handle.
    259354         */
    260         devmap_device_register(devmap_pathname, &cli->devmap_handle);
     355        devmap_device_register_with_iface(devmap_pathname,
     356            &cli->devmap_handle, DEVMAN_CONNECT_FROM_DEVMAP);
    261357       
    262358        /*
     
    264360         * mapper.
    265361         */
    266         class_add_devmap_device(&class_list, cli);
     362        class_add_devmap_function(&class_list, cli);
    267363       
    268364        free(devmap_pathname);
    269365}
    270366
    271 static void devman_add_device_to_class(ipc_callid_t callid, ipc_call_t *call)
    272 {
    273         device_handle_t handle = IPC_GET_ARG1(*call);
     367static void devman_add_function_to_class(ipc_callid_t callid, ipc_call_t *call)
     368{
     369        devman_handle_t handle = IPC_GET_ARG1(*call);
    274370       
    275371        /* Get class name. */
     
    278374            0, 0, 0, 0);
    279375        if (rc != EOK) {
    280                 ipc_answer_0(callid, rc);
     376                async_answer_0(callid, rc);
    281377                return;
    282378        }       
    283379       
    284         node_t *dev = find_dev_node(&device_tree, handle);
    285         if (dev == NULL) {
    286                 ipc_answer_0(callid, ENOENT);
     380        fun_node_t *fun = find_fun_node(&device_tree, handle);
     381        if (fun == NULL) {
     382                async_answer_0(callid, ENOENT);
    287383                return;
    288384        }
    289385       
    290386        dev_class_t *cl = get_dev_class(&class_list, class_name);
    291         dev_class_info_t *class_info = add_device_to_class(dev, cl, NULL);
     387        dev_class_info_t *class_info = add_function_to_class(fun, cl, NULL);
    292388       
    293389        /* Register the device's class alias by devmapper. */
    294390        devmap_register_class_dev(class_info);
    295391       
    296         printf(NAME ": device '%s' added to class '%s', class name '%s' was "
    297             "asigned to it\n", dev->pathname, class_name, class_info->dev_name);
    298        
    299         ipc_answer_0(callid, EOK);
     392        log_msg(LVL_NOTE, "Function `%s' added to class `%s' as `%s'.",
     393            fun->pathname, class_name, class_info->dev_name);
     394
     395        async_answer_0(callid, EOK);
    300396}
    301397
     
    310406       
    311407        initialize_running_driver(driver, &device_tree);
    312         printf(NAME ": the %s driver was successfully initialized. \n",
     408        log_msg(LVL_DEBUG, "The `%s` driver was successfully initialized.",
    313409            driver->name);
    314410        return 0;
     
    319415{
    320416        /* Accept the connection. */
    321         ipc_answer_0(iid, EOK);
     417        async_answer_0(iid, EOK);
    322418       
    323419        driver_t *driver = devman_driver_register();
     
    332428        fid_t fid = fibril_create(init_running_drv, driver);
    333429        if (fid == 0) {
    334                 printf(NAME ": Error creating fibril for the initialization of "
    335                     "the newly registered running driver.\n");
     430                log_msg(LVL_ERROR, "Failed to create initialization fibril " \
     431                    "for driver `%s'.", driver->name);
    336432                return;
    337433        }
     
    344440                callid = async_get_call(&call);
    345441               
    346                 switch (IPC_GET_METHOD(call)) {
     442                switch (IPC_GET_IMETHOD(call)) {
    347443                case IPC_M_PHONE_HUNGUP:
    348444                        cont = false;
    349445                        continue;
    350                 case DEVMAN_ADD_CHILD_DEVICE:
    351                         devman_add_child(callid, &call);
     446                case DEVMAN_ADD_FUNCTION:
     447                        devman_add_function(callid, &call);
    352448                        break;
    353449                case DEVMAN_ADD_DEVICE_TO_CLASS:
    354                         devman_add_device_to_class(callid, &call);
     450                        devman_add_function_to_class(callid, &call);
    355451                        break;
    356452                default:
    357                         ipc_answer_0(callid, EINVAL);
     453                        async_answer_0(callid, EINVAL);
    358454                        break;
    359455                }
     
    363459/** Find handle for the device instance identified by the device's path in the
    364460 * device tree. */
    365 static void devman_device_get_handle(ipc_callid_t iid, ipc_call_t *icall)
     461static void devman_function_get_handle(ipc_callid_t iid, ipc_call_t *icall)
    366462{
    367463        char *pathname;
     
    369465        int rc = async_data_write_accept((void **) &pathname, true, 0, 0, 0, 0);
    370466        if (rc != EOK) {
    371                 ipc_answer_0(iid, rc);
    372                 return;
    373         }
    374        
    375         node_t * dev = find_dev_node_by_path(&device_tree, pathname);
     467                async_answer_0(iid, rc);
     468                return;
     469        }
     470       
     471        fun_node_t *fun = find_fun_node_by_path(&device_tree, pathname);
    376472       
    377473        free(pathname);
    378474
    379         if (dev == NULL) {
    380                 ipc_answer_0(iid, ENOENT);
    381                 return;
    382         }
    383        
    384         ipc_answer_1(iid, EOK, dev->handle);
     475        if (fun == NULL) {
     476                async_answer_0(iid, ENOENT);
     477                return;
     478        }
     479
     480        async_answer_1(iid, EOK, fun->handle);
     481}
     482
     483/** Find handle for the device instance identified by device class name. */
     484static void devman_function_get_handle_by_class(ipc_callid_t iid,
     485    ipc_call_t *icall)
     486{
     487        char *classname;
     488        char *devname;
     489
     490        int rc = async_data_write_accept((void **) &classname, true, 0, 0, 0, 0);
     491        if (rc != EOK) {
     492                async_answer_0(iid, rc);
     493                return;
     494        }
     495        rc = async_data_write_accept((void **) &devname, true, 0, 0, 0, 0);
     496        if (rc != EOK) {
     497                free(classname);
     498                async_answer_0(iid, rc);
     499                return;
     500        }
     501
     502
     503        fun_node_t *fun = find_fun_node_by_class(&class_list,
     504            classname, devname);
     505
     506        free(classname);
     507        free(devname);
     508
     509        if (fun == NULL) {
     510                async_answer_0(iid, ENOENT);
     511                return;
     512        }
     513
     514        async_answer_1(iid, EOK, fun->handle);
    385515}
    386516
     
    390520{
    391521        /* Accept connection. */
    392         ipc_answer_0(iid, EOK);
     522        async_answer_0(iid, EOK);
    393523       
    394524        bool cont = true;
     
    397527                ipc_callid_t callid = async_get_call(&call);
    398528               
    399                 switch (IPC_GET_METHOD(call)) {
     529                switch (IPC_GET_IMETHOD(call)) {
    400530                case IPC_M_PHONE_HUNGUP:
    401531                        cont = false;
    402532                        continue;
    403533                case DEVMAN_DEVICE_GET_HANDLE:
    404                         devman_device_get_handle(callid, &call);
     534                        devman_function_get_handle(callid, &call);
     535                        break;
     536                case DEVMAN_DEVICE_GET_HANDLE_BY_CLASS:
     537                        devman_function_get_handle_by_class(callid, &call);
    405538                        break;
    406539                default:
    407                         if (!(callid & IPC_CALLID_NOTIFICATION))
    408                                 ipc_answer_0(callid, ENOENT);
     540                        async_answer_0(callid, ENOENT);
    409541                }
    410542        }
     
    414546    bool drv_to_parent)
    415547{
    416         device_handle_t handle = IPC_GET_ARG2(*icall);
    417        
    418         node_t *dev = find_dev_node(&device_tree, handle);
     548        devman_handle_t handle = IPC_GET_ARG2(*icall);
     549        devman_handle_t fwd_h;
     550        fun_node_t *fun = NULL;
     551        dev_node_t *dev = NULL;
     552       
     553        fun = find_fun_node(&device_tree, handle);
     554        if (fun == NULL)
     555                dev = find_dev_node(&device_tree, handle);
     556        else
     557                dev = fun->dev;
     558
     559        /*
     560         * For a valid function to connect to we need a device. The root
     561         * function, for example, has no device and cannot be connected to.
     562         * This means @c dev needs to be valid regardless whether we are
     563         * connecting to a device or to a function.
     564         */
    419565        if (dev == NULL) {
    420                 printf(NAME ": devman_forward error - no device with handle %x "
    421                     "was found.\n", handle);
    422                 ipc_answer_0(iid, ENOENT);
     566                log_msg(LVL_ERROR, "IPC forwarding failed - no device or "
     567                    "function with handle %" PRIun " was found.", handle);
     568                async_answer_0(iid, ENOENT);
     569                return;
     570        }
     571
     572        if (fun == NULL && !drv_to_parent) {
     573                log_msg(LVL_ERROR, NAME ": devman_forward error - cannot "
     574                    "connect to handle %" PRIun ", refers to a device.",
     575                    handle);
     576                async_answer_0(iid, ENOENT);
    423577                return;
    424578        }
     
    427581       
    428582        if (drv_to_parent) {
    429                 if (dev->parent != NULL)
    430                         driver = dev->parent->drv;
     583                /* Connect to parent function of a device (or device function). */
     584                if (dev->pfun->dev != NULL)
     585                        driver = dev->pfun->dev->drv;
     586                fwd_h = dev->pfun->handle;
    431587        } else if (dev->state == DEVICE_USABLE) {
     588                /* Connect to the specified function */
    432589                driver = dev->drv;
    433590                assert(driver != NULL);
     591
     592                fwd_h = handle;
    434593        }
    435594       
    436595        if (driver == NULL) {
    437                 printf(NAME ": devman_forward error - the device is not in "
    438                     "usable state.\n", handle);
    439                 ipc_answer_0(iid, ENOENT);
     596                log_msg(LVL_ERROR, "IPC forwarding refused - " \
     597                    "the device %" PRIun " is not in usable state.", handle);
     598                async_answer_0(iid, ENOENT);
    440599                return;
    441600        }
     
    447606                method = DRIVER_CLIENT;
    448607       
    449         if (driver->phone <= 0) {
    450                 printf(NAME ": devman_forward: cound not forward to driver %s ",
    451                     driver->name);
    452                 printf("the driver's phone is %x).\n", driver->phone);
    453                 ipc_answer_0(iid, EINVAL);
    454                 return;
    455         }
    456 
    457         printf(NAME ": devman_forward: forward connection to device %s to "
    458             "driver %s.\n", dev->pathname, driver->name);
    459         ipc_forward_fast(iid, driver->phone, method, dev->handle, 0, IPC_FF_NONE);
     608        if (driver->phone < 0) {
     609                log_msg(LVL_ERROR,
     610                    "Could not forward to driver `%s' (phone is %d).",
     611                    driver->name, (int) driver->phone);
     612                async_answer_0(iid, EINVAL);
     613                return;
     614        }
     615
     616        if (fun != NULL) {
     617                log_msg(LVL_DEBUG,
     618                    "Forwarding request for `%s' function to driver `%s'.",
     619                    fun->pathname, driver->name);
     620        } else {
     621                log_msg(LVL_DEBUG,
     622                    "Forwarding request for `%s' device to driver `%s'.",
     623                    dev->pfun->pathname, driver->name);
     624        }
     625
     626        async_forward_fast(iid, driver->phone, method, fwd_h, 0, IPC_FF_NONE);
    460627}
    461628
     
    464631static void devman_connection_devmapper(ipc_callid_t iid, ipc_call_t *icall)
    465632{
    466         dev_handle_t devmap_handle = IPC_GET_METHOD(*icall);
    467         node_t *dev;
    468 
    469         dev = find_devmap_tree_device(&device_tree, devmap_handle);
    470         if (dev == NULL)
    471                 dev = find_devmap_class_device(&class_list, devmap_handle);
    472        
    473         if (dev == NULL || dev->drv == NULL) {
    474                 ipc_answer_0(iid, ENOENT);
    475                 return;
    476         }
    477        
    478         if (dev->state != DEVICE_USABLE || dev->drv->phone <= 0) {
    479                 ipc_answer_0(iid, EINVAL);
    480                 return;
    481         }
    482        
    483         printf(NAME ": devman_connection_devmapper: forward connection to "
    484             "device %s to driver %s.\n", dev->pathname, dev->drv->name);
    485         ipc_forward_fast(iid, dev->drv->phone, DRIVER_CLIENT, dev->handle, 0,
     633        devmap_handle_t devmap_handle = IPC_GET_ARG2(*icall);
     634        fun_node_t *fun;
     635        dev_node_t *dev;
     636
     637        fun = find_devmap_tree_function(&device_tree, devmap_handle);
     638        if (fun == NULL)
     639                fun = find_devmap_class_function(&class_list, devmap_handle);
     640       
     641        if (fun == NULL || fun->dev->drv == NULL) {
     642                async_answer_0(iid, ENOENT);
     643                return;
     644        }
     645       
     646        dev = fun->dev;
     647       
     648        if (dev->state != DEVICE_USABLE || dev->drv->phone < 0) {
     649                async_answer_0(iid, EINVAL);
     650                return;
     651        }
     652       
     653        async_forward_fast(iid, dev->drv->phone, DRIVER_CLIENT, fun->handle, 0,
    486654            IPC_FF_NONE);
     655        log_msg(LVL_DEBUG,
     656            "Forwarding devmapper request for `%s' function to driver `%s'.",
     657            fun->pathname, dev->drv->name);
    487658}
    488659
     
    490661static void devman_connection(ipc_callid_t iid, ipc_call_t *icall)
    491662{
    492         /*
    493          * Silly hack to enable the device manager to register as a driver by
    494          * the device mapper. If the ipc method is not IPC_M_CONNECT_ME_TO, this
    495          * is not the forwarded connection from naming service, so it must be a
    496          * connection from the devmapper which thinks this is a devmapper-style
    497          * driver. So pretend this is a devmapper-style driver. (This does not
    498          * work for device with handle == IPC_M_CONNECT_ME_TO, because devmapper
    499          * passes device handle to the driver as an ipc method.)
    500          */
    501         if (IPC_GET_METHOD(*icall) != IPC_M_CONNECT_ME_TO)
    502                 devman_connection_devmapper(iid, icall);
    503 
    504         /*
    505          * ipc method is IPC_M_CONNECT_ME_TO, so this is forwarded connection
    506          * from naming service by which we registered as device manager, so be
    507          * device manager.
    508          */
    509        
    510663        /* Select interface. */
    511         switch ((ipcarg_t) (IPC_GET_ARG1(*icall))) {
     664        switch ((sysarg_t) (IPC_GET_ARG1(*icall))) {
    512665        case DEVMAN_DRIVER:
    513666                devman_connection_driver(iid, icall);
     
    520673                devman_forward(iid, icall, false);
    521674                break;
     675        case DEVMAN_CONNECT_FROM_DEVMAP:
     676                /* Someone connected through devmap node. */
     677                devman_connection_devmapper(iid, icall);
     678                break;
    522679        case DEVMAN_CONNECT_TO_PARENTS_DEVICE:
    523680                /* Connect client to selected device. */
     
    526683        default:
    527684                /* No such interface */
    528                 ipc_answer_0(iid, ENOENT);
     685                async_answer_0(iid, ENOENT);
    529686        }
    530687}
     
    533690static bool devman_init(void)
    534691{
    535         printf(NAME ": devman_init - looking for available drivers.\n");
     692        log_msg(LVL_DEBUG, "devman_init - looking for available drivers.");
    536693       
    537694        /* Initialize list of available drivers. */
     
    539696        if (lookup_available_drivers(&drivers_list,
    540697            DRIVER_DEFAULT_STORE) == 0) {
    541                 printf(NAME " no drivers found.");
     698                log_msg(LVL_FATAL, "No drivers found.");
    542699                return false;
    543700        }
    544701
    545         printf(NAME ": devman_init  - list of drivers has been initialized.\n");
     702        log_msg(LVL_DEBUG, "devman_init - list of drivers has been initialized.");
    546703
    547704        /* Create root device node. */
    548705        if (!init_device_tree(&device_tree, &drivers_list)) {
    549                 printf(NAME " failed to initialize device tree.");
     706                log_msg(LVL_FATAL, "Failed to initialize device tree.");
    550707                return false;
    551708        }
     
    568725        printf(NAME ": HelenOS Device Manager\n");
    569726
     727        if (log_init(NAME, LVL_ERROR) != EOK) {
     728                printf(NAME ": Error initializing logging subsystem.\n");
     729                return -1;
     730        }
     731
    570732        if (!devman_init()) {
    571                 printf(NAME ": Error while initializing service\n");
     733                log_msg(LVL_ERROR, "Error while initializing service.");
    572734                return -1;
    573735        }
     
    577739
    578740        /* Register device manager at naming service. */
    579         ipcarg_t phonead;
    580         if (ipc_connect_to_me(PHONE_NS, SERVICE_DEVMAN, 0, 0, &phonead) != 0)
     741        if (service_register(SERVICE_DEVMAN) != EOK) {
     742                log_msg(LVL_ERROR, "Failed registering as a service.");
    581743                return -1;
    582 
    583         printf(NAME ": Accepting connections\n");
     744        }
     745
     746        printf(NAME ": Accepting connections.\n");
    584747        async_manager();
    585748
Note: See TracChangeset for help on using the changeset viewer.