Changeset eb522e8 in mainline for uspace/srv/devman/main.c


Ignore:
Timestamp:
2011-06-01T08:43:42Z (15 years ago)
Author:
Lubos Slovak <lubos.slovak@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
8d6c1f1
Parents:
9e2e715 (diff), e51a514 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Huuuuuge merge from development - all the work actually :)

File:
1 edited

Legend:

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

    r9e2e715 reb522e8  
    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);
     515}
     516
     517/** Find device path by its handle. */
     518static void devman_get_device_path_by_handle(ipc_callid_t iid,
     519    ipc_call_t *icall)
     520{
     521        devman_handle_t handle = IPC_GET_ARG1(*icall);
     522
     523        fun_node_t *fun = find_fun_node(&device_tree, handle);
     524        if (fun == NULL) {
     525                async_answer_0(iid, ENOMEM);
     526                return;
     527        }
     528
     529        ipc_callid_t data_callid;
     530        size_t data_len;
     531        if (!async_data_read_receive(&data_callid, &data_len)) {
     532                async_answer_0(iid, EINVAL);
     533                return;
     534        }
     535
     536        void *buffer = malloc(data_len);
     537        if (buffer == NULL) {
     538                async_answer_0(data_callid, ENOMEM);
     539                async_answer_0(iid, ENOMEM);
     540                return;
     541        }
     542
     543        size_t sent_length = str_size(fun->pathname);
     544        if (sent_length > data_len) {
     545                sent_length = data_len;
     546        }
     547
     548        async_data_read_finalize(data_callid, fun->pathname, sent_length);
     549        async_answer_0(iid, EOK);
     550
     551        free(buffer);
    385552}
    386553
     
    390557{
    391558        /* Accept connection. */
    392         ipc_answer_0(iid, EOK);
     559        async_answer_0(iid, EOK);
    393560       
    394561        bool cont = true;
     
    397564                ipc_callid_t callid = async_get_call(&call);
    398565               
    399                 switch (IPC_GET_METHOD(call)) {
     566                switch (IPC_GET_IMETHOD(call)) {
    400567                case IPC_M_PHONE_HUNGUP:
    401568                        cont = false;
    402569                        continue;
    403570                case DEVMAN_DEVICE_GET_HANDLE:
    404                         devman_device_get_handle(callid, &call);
     571                        devman_function_get_handle(callid, &call);
     572                        break;
     573                case DEVMAN_DEVICE_GET_HANDLE_BY_CLASS:
     574                        devman_function_get_handle_by_class(callid, &call);
     575                        break;
     576                case DEVMAN_DEVICE_GET_DEVICE_PATH:
     577                        devman_get_device_path_by_handle(callid, &call);
    405578                        break;
    406579                default:
    407                         if (!(callid & IPC_CALLID_NOTIFICATION))
    408                                 ipc_answer_0(callid, ENOENT);
     580                        async_answer_0(callid, ENOENT);
    409581                }
    410582        }
     
    414586    bool drv_to_parent)
    415587{
    416         device_handle_t handle = IPC_GET_ARG2(*icall);
    417        
    418         node_t *dev = find_dev_node(&device_tree, handle);
     588        devman_handle_t handle = IPC_GET_ARG2(*icall);
     589        devman_handle_t fwd_h;
     590        fun_node_t *fun = NULL;
     591        dev_node_t *dev = NULL;
     592       
     593        fun = find_fun_node(&device_tree, handle);
     594        if (fun == NULL)
     595                dev = find_dev_node(&device_tree, handle);
     596        else
     597                dev = fun->dev;
     598
     599        /*
     600         * For a valid function to connect to we need a device. The root
     601         * function, for example, has no device and cannot be connected to.
     602         * This means @c dev needs to be valid regardless whether we are
     603         * connecting to a device or to a function.
     604         */
    419605        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);
     606                log_msg(LVL_ERROR, "IPC forwarding failed - no device or "
     607                    "function with handle %" PRIun " was found.", handle);
     608                async_answer_0(iid, ENOENT);
     609                return;
     610        }
     611
     612        if (fun == NULL && !drv_to_parent) {
     613                log_msg(LVL_ERROR, NAME ": devman_forward error - cannot "
     614                    "connect to handle %" PRIun ", refers to a device.",
     615                    handle);
     616                async_answer_0(iid, ENOENT);
    423617                return;
    424618        }
     
    427621       
    428622        if (drv_to_parent) {
    429                 if (dev->parent != NULL)
    430                         driver = dev->parent->drv;
     623                /* Connect to parent function of a device (or device function). */
     624                if (dev->pfun->dev != NULL)
     625                        driver = dev->pfun->dev->drv;
     626                fwd_h = dev->pfun->handle;
    431627        } else if (dev->state == DEVICE_USABLE) {
     628                /* Connect to the specified function */
    432629                driver = dev->drv;
    433630                assert(driver != NULL);
     631
     632                fwd_h = handle;
    434633        }
    435634       
    436635        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);
     636                log_msg(LVL_ERROR, "IPC forwarding refused - " \
     637                    "the device %" PRIun "(%s) is not in usable state.",
     638                    handle, dev->pfun->pathname);
     639                async_answer_0(iid, ENOENT);
    440640                return;
    441641        }
     
    447647                method = DRIVER_CLIENT;
    448648       
    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);
     649        if (driver->phone < 0) {
     650                log_msg(LVL_ERROR,
     651                    "Could not forward to driver `%s' (phone is %d).",
     652                    driver->name, (int) driver->phone);
     653                async_answer_0(iid, EINVAL);
     654                return;
     655        }
     656
     657        if (fun != NULL) {
     658                log_msg(LVL_DEBUG,
     659                    "Forwarding request for `%s' function to driver `%s'.",
     660                    fun->pathname, driver->name);
     661        } else {
     662                log_msg(LVL_DEBUG,
     663                    "Forwarding request for `%s' device to driver `%s'.",
     664                    dev->pfun->pathname, driver->name);
     665        }
     666
     667        async_forward_fast(iid, driver->phone, method, fwd_h, 0, IPC_FF_NONE);
    460668}
    461669
     
    464672static void devman_connection_devmapper(ipc_callid_t iid, ipc_call_t *icall)
    465673{
    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,
     674        devmap_handle_t devmap_handle = IPC_GET_ARG2(*icall);
     675        fun_node_t *fun;
     676        dev_node_t *dev;
     677
     678        fun = find_devmap_tree_function(&device_tree, devmap_handle);
     679        if (fun == NULL)
     680                fun = find_devmap_class_function(&class_list, devmap_handle);
     681       
     682        if (fun == NULL || fun->dev->drv == NULL) {
     683                async_answer_0(iid, ENOENT);
     684                return;
     685        }
     686       
     687        dev = fun->dev;
     688       
     689        if (dev->state != DEVICE_USABLE || dev->drv->phone < 0) {
     690                async_answer_0(iid, EINVAL);
     691                return;
     692        }
     693       
     694        async_forward_fast(iid, dev->drv->phone, DRIVER_CLIENT, fun->handle, 0,
    486695            IPC_FF_NONE);
     696        log_msg(LVL_DEBUG,
     697            "Forwarding devmapper request for `%s' function to driver `%s'.",
     698            fun->pathname, dev->drv->name);
    487699}
    488700
     
    490702static void devman_connection(ipc_callid_t iid, ipc_call_t *icall)
    491703{
    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        
    510704        /* Select interface. */
    511         switch ((ipcarg_t) (IPC_GET_ARG1(*icall))) {
     705        switch ((sysarg_t) (IPC_GET_ARG1(*icall))) {
    512706        case DEVMAN_DRIVER:
    513707                devman_connection_driver(iid, icall);
     
    520714                devman_forward(iid, icall, false);
    521715                break;
     716        case DEVMAN_CONNECT_FROM_DEVMAP:
     717                /* Someone connected through devmap node. */
     718                devman_connection_devmapper(iid, icall);
     719                break;
    522720        case DEVMAN_CONNECT_TO_PARENTS_DEVICE:
    523721                /* Connect client to selected device. */
     
    526724        default:
    527725                /* No such interface */
    528                 ipc_answer_0(iid, ENOENT);
     726                async_answer_0(iid, ENOENT);
    529727        }
    530728}
     
    533731static bool devman_init(void)
    534732{
    535         printf(NAME ": devman_init - looking for available drivers.\n");
     733        log_msg(LVL_DEBUG, "devman_init - looking for available drivers.");
    536734       
    537735        /* Initialize list of available drivers. */
     
    539737        if (lookup_available_drivers(&drivers_list,
    540738            DRIVER_DEFAULT_STORE) == 0) {
    541                 printf(NAME " no drivers found.");
     739                log_msg(LVL_FATAL, "No drivers found.");
    542740                return false;
    543741        }
    544742
    545         printf(NAME ": devman_init  - list of drivers has been initialized.\n");
     743        log_msg(LVL_DEBUG, "devman_init - list of drivers has been initialized.");
    546744
    547745        /* Create root device node. */
    548746        if (!init_device_tree(&device_tree, &drivers_list)) {
    549                 printf(NAME " failed to initialize device tree.");
     747                log_msg(LVL_FATAL, "Failed to initialize device tree.");
    550748                return false;
    551749        }
     
    568766        printf(NAME ": HelenOS Device Manager\n");
    569767
     768        if (log_init(NAME, LVL_ERROR) != EOK) {
     769                printf(NAME ": Error initializing logging subsystem.\n");
     770                return -1;
     771        }
     772
    570773        if (!devman_init()) {
    571                 printf(NAME ": Error while initializing service\n");
     774                log_msg(LVL_ERROR, "Error while initializing service.");
    572775                return -1;
    573776        }
     
    577780
    578781        /* Register device manager at naming service. */
    579         ipcarg_t phonead;
    580         if (ipc_connect_to_me(PHONE_NS, SERVICE_DEVMAN, 0, 0, &phonead) != 0)
     782        if (service_register(SERVICE_DEVMAN) != EOK) {
     783                log_msg(LVL_ERROR, "Failed registering as a service.");
    581784                return -1;
    582 
    583         printf(NAME ": Accepting connections\n");
     785        }
     786
     787        printf(NAME ": Accepting connections.\n");
    584788        async_manager();
    585789
Note: See TracChangeset for help on using the changeset viewer.