Ignore:
File:
1 edited

Legend:

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

    rde2c901 rb927375  
    7575        iid = async_get_call(&icall);
    7676        if (IPC_GET_IMETHOD(icall) != DEVMAN_DRIVER_REGISTER) {
    77                 ipc_answer_0(iid, EREFUSED);
     77                async_answer_0(iid, EREFUSED);
    7878                return NULL;
    7979        }
     
    8484        int rc = async_data_write_accept((void **) &drv_name, true, 0, 0, 0, 0);
    8585        if (rc != EOK) {
    86                 ipc_answer_0(iid, rc);
     86                async_answer_0(iid, rc);
    8787                return NULL;
    8888        }
     
    9898                free(drv_name);
    9999                drv_name = NULL;
    100                 ipc_answer_0(iid, ENOENT);
     100                async_answer_0(iid, ENOENT);
    101101                return NULL;
    102102        }
     
    110110        ipc_callid_t callid = async_get_call(&call);
    111111        if (IPC_GET_IMETHOD(call) != IPC_M_CONNECT_TO_ME) {
    112                 ipc_answer_0(callid, ENOTSUP);
    113                 ipc_answer_0(iid, ENOTSUP);
     112                async_answer_0(callid, ENOTSUP);
     113                async_answer_0(iid, ENOTSUP);
    114114                return NULL;
    115115        }
     
    121121            driver->name);
    122122       
    123         ipc_answer_0(callid, EOK);
    124         ipc_answer_0(iid, EOK);
     123        async_answer_0(callid, EOK);
     124        async_answer_0(iid, EOK);
    125125       
    126126        return driver;
     
    144144                printf(NAME ": ERROR: devman_receive_match_id - invalid "
    145145                    "protocol.\n");
    146                 ipc_answer_0(callid, EINVAL);
     146                async_answer_0(callid, EINVAL);
    147147                delete_match_id(match_id);
    148148                return EINVAL;
     
    152152                printf(NAME ": ERROR: devman_receive_match_id - failed to "
    153153                    "allocate match id.\n");
    154                 ipc_answer_0(callid, ENOMEM);
     154                async_answer_0(callid, ENOMEM);
    155155                return ENOMEM;
    156156        }
    157157       
    158         ipc_answer_0(callid, EOK);
     158        async_answer_0(callid, EOK);
    159159       
    160160        match_id->score = IPC_GET_ARG1(call);
     
    199199static int assign_driver_fibril(void *arg)
    200200{
    201         node_t *node = (node_t *) arg;
    202         assign_driver(node, &drivers_list, &device_tree);
     201        dev_node_t *dev_node = (dev_node_t *) arg;
     202        assign_driver(dev_node, &drivers_list, &device_tree);
    203203        return EOK;
    204204}
    205205
    206 /** Handle child device registration.
     206/** Handle function registration.
    207207 *
    208208 * Child devices are registered by their parent's device driver.
    209209 */
    210 static void devman_add_child(ipc_callid_t callid, ipc_call_t *call)
    211 {
    212         devman_handle_t parent_handle = IPC_GET_ARG1(*call);
    213         sysarg_t match_count = IPC_GET_ARG2(*call);
     210static void devman_add_function(ipc_callid_t callid, ipc_call_t *call)
     211{
     212        fun_type_t ftype = (fun_type_t) IPC_GET_ARG1(*call);
     213        devman_handle_t dev_handle = IPC_GET_ARG2(*call);
     214        sysarg_t match_count = IPC_GET_ARG3(*call);
    214215        dev_tree_t *tree = &device_tree;
    215216       
    216217        fibril_rwlock_write_lock(&tree->rwlock);
    217         node_t *parent = find_dev_node_no_lock(&device_tree, parent_handle);
    218        
    219         if (parent == NULL) {
     218
     219        dev_node_t *dev = NULL;
     220        dev_node_t *pdev = find_dev_node_no_lock(&device_tree, dev_handle);
     221       
     222        if (pdev == NULL) {
    220223                fibril_rwlock_write_unlock(&tree->rwlock);
    221                 ipc_answer_0(callid, ENOENT);
    222                 return;
    223         }
    224        
    225         char *dev_name = NULL;
    226         int rc = async_data_write_accept((void **)&dev_name, true, 0, 0, 0, 0);
     224                async_answer_0(callid, ENOENT);
     225                return;
     226        }
     227       
     228        if (ftype != fun_inner && ftype != fun_exposed) {
     229                /* Unknown function type */
     230                printf(NAME ": Error, unknown function type provided by driver!\n");
     231
     232                fibril_rwlock_write_unlock(&tree->rwlock);
     233                async_answer_0(callid, EINVAL);
     234                return;
     235        }
     236       
     237        char *fun_name = NULL;
     238        int rc = async_data_write_accept((void **)&fun_name, true, 0, 0, 0, 0);
    227239        if (rc != EOK) {
    228240                fibril_rwlock_write_unlock(&tree->rwlock);
    229                 ipc_answer_0(callid, rc);
    230                 return;
    231         }
    232        
    233         node_t *node = create_dev_node();
    234         if (!insert_dev_node(&device_tree, node, dev_name, parent)) {
     241                async_answer_0(callid, rc);
     242                return;
     243        }
     244       
     245        fun_node_t *fun = create_fun_node();
     246        if (!insert_fun_node(&device_tree, fun, fun_name, pdev)) {
    235247                fibril_rwlock_write_unlock(&tree->rwlock);
    236                 delete_dev_node(node);
    237                 ipc_answer_0(callid, ENOMEM);
    238                 return;
     248                delete_fun_node(fun);
     249                async_answer_0(callid, ENOMEM);
     250                return;
     251        }
     252
     253        if (ftype == fun_inner) {
     254                dev = create_dev_node();
     255                if (dev == NULL) {
     256                        fibril_rwlock_write_unlock(&tree->rwlock);
     257                        delete_fun_node(fun);
     258                        async_answer_0(callid, ENOMEM);
     259                        return;
     260                }
     261
     262                insert_dev_node(tree, dev, fun);
    239263        }
    240264
    241265        fibril_rwlock_write_unlock(&tree->rwlock);
    242266       
    243         printf(NAME ": devman_add_child %s\n", node->pathname);
    244        
    245         devman_receive_match_ids(match_count, &node->match_ids);
    246 
    247         /*
    248          * Try to find a suitable driver and assign it to the device.  We do
    249          * not want to block the current fibril that is used for processing
    250          * incoming calls: we will launch a separate fibril to handle the
    251          * driver assigning. That is because assign_driver can actually include
    252          * task spawning which could take some time.
    253          */
    254         fid_t assign_fibril = fibril_create(assign_driver_fibril, node);
    255         if (assign_fibril == 0) {
     267        printf(NAME ": devman_add_function %s\n", fun->pathname);
     268       
     269        devman_receive_match_ids(match_count, &fun->match_ids);
     270
     271        if (ftype == fun_inner) {
     272                assert(dev != NULL);
    256273                /*
    257                  * Fallback in case we are out of memory.
    258                  * Probably not needed as we will die soon anyway ;-).
     274                 * Try to find a suitable driver and assign it to the device.  We do
     275                 * not want to block the current fibril that is used for processing
     276                 * incoming calls: we will launch a separate fibril to handle the
     277                 * driver assigning. That is because assign_driver can actually include
     278                 * task spawning which could take some time.
    259279                 */
    260                 (void) assign_driver_fibril(node);
     280                fid_t assign_fibril = fibril_create(assign_driver_fibril, dev);
     281                if (assign_fibril == 0) {
     282                        /*
     283                         * Fallback in case we are out of memory.
     284                         * Probably not needed as we will die soon anyway ;-).
     285                         */
     286                        (void) assign_driver_fibril(fun);
     287                } else {
     288                        fibril_add_ready(assign_fibril);
     289                }
    261290        } else {
    262                 fibril_add_ready(assign_fibril);
    263         }
    264 
     291                devmap_register_tree_function(fun, tree);
     292        }
     293       
    265294        /* Return device handle to parent's driver. */
    266         ipc_answer_1(callid, EOK, node->handle);
     295        async_answer_1(callid, EOK, fun->handle);
    267296}
    268297
     
    288317         * mapper.
    289318         */
    290         class_add_devmap_device(&class_list, cli);
     319        class_add_devmap_function(&class_list, cli);
    291320       
    292321        free(devmap_pathname);
    293322}
    294323
    295 static void devman_add_device_to_class(ipc_callid_t callid, ipc_call_t *call)
     324static void devman_add_function_to_class(ipc_callid_t callid, ipc_call_t *call)
    296325{
    297326        devman_handle_t handle = IPC_GET_ARG1(*call);
     
    302331            0, 0, 0, 0);
    303332        if (rc != EOK) {
    304                 ipc_answer_0(callid, rc);
     333                async_answer_0(callid, rc);
    305334                return;
    306335        }       
    307336       
    308         node_t *dev = find_dev_node(&device_tree, handle);
    309         if (dev == NULL) {
    310                 ipc_answer_0(callid, ENOENT);
     337        fun_node_t *fun = find_fun_node(&device_tree, handle);
     338        if (fun == NULL) {
     339                async_answer_0(callid, ENOENT);
    311340                return;
    312341        }
    313342       
    314343        dev_class_t *cl = get_dev_class(&class_list, class_name);
    315         dev_class_info_t *class_info = add_device_to_class(dev, cl, NULL);
     344        dev_class_info_t *class_info = add_function_to_class(fun, cl, NULL);
    316345       
    317346        /* Register the device's class alias by devmapper. */
    318347        devmap_register_class_dev(class_info);
    319348       
    320         printf(NAME ": device '%s' added to class '%s', class name '%s' was "
    321             "asigned to it\n", dev->pathname, class_name, class_info->dev_name);
    322 
    323         ipc_answer_0(callid, EOK);
     349        printf(NAME ": function'%s' added to class '%s', class name '%s' was "
     350            "asigned to it\n", fun->pathname, class_name, class_info->dev_name);
     351
     352        async_answer_0(callid, EOK);
    324353}
    325354
     
    343372{
    344373        /* Accept the connection. */
    345         ipc_answer_0(iid, EOK);
     374        async_answer_0(iid, EOK);
    346375       
    347376        driver_t *driver = devman_driver_register();
     
    372401                        cont = false;
    373402                        continue;
    374                 case DEVMAN_ADD_CHILD_DEVICE:
    375                         devman_add_child(callid, &call);
     403                case DEVMAN_ADD_FUNCTION:
     404                        devman_add_function(callid, &call);
    376405                        break;
    377406                case DEVMAN_ADD_DEVICE_TO_CLASS:
    378                         devman_add_device_to_class(callid, &call);
     407                        devman_add_function_to_class(callid, &call);
    379408                        break;
    380409                default:
    381                         ipc_answer_0(callid, EINVAL);
     410                        async_answer_0(callid, EINVAL);
    382411                        break;
    383412                }
     
    387416/** Find handle for the device instance identified by the device's path in the
    388417 * device tree. */
    389 static void devman_device_get_handle(ipc_callid_t iid, ipc_call_t *icall)
     418static void devman_function_get_handle(ipc_callid_t iid, ipc_call_t *icall)
    390419{
    391420        char *pathname;
     
    393422        int rc = async_data_write_accept((void **) &pathname, true, 0, 0, 0, 0);
    394423        if (rc != EOK) {
    395                 ipc_answer_0(iid, rc);
    396                 return;
    397         }
    398        
    399         node_t * dev = find_dev_node_by_path(&device_tree, pathname);
     424                async_answer_0(iid, rc);
     425                return;
     426        }
     427       
     428        fun_node_t *fun = find_fun_node_by_path(&device_tree, pathname);
    400429       
    401430        free(pathname);
    402431
    403         if (dev == NULL) {
    404                 ipc_answer_0(iid, ENOENT);
    405                 return;
    406         }
    407        
    408         ipc_answer_1(iid, EOK, dev->handle);
     432        if (fun == NULL) {
     433                async_answer_0(iid, ENOENT);
     434                return;
     435        }
     436
     437        async_answer_1(iid, EOK, fun->handle);
    409438}
    410439
     
    414443{
    415444        /* Accept connection. */
    416         ipc_answer_0(iid, EOK);
     445        async_answer_0(iid, EOK);
    417446       
    418447        bool cont = true;
     
    426455                        continue;
    427456                case DEVMAN_DEVICE_GET_HANDLE:
    428                         devman_device_get_handle(callid, &call);
     457                        devman_function_get_handle(callid, &call);
    429458                        break;
    430459                default:
    431                         ipc_answer_0(callid, ENOENT);
     460                        async_answer_0(callid, ENOENT);
    432461                }
    433462        }
     
    438467{
    439468        devman_handle_t handle = IPC_GET_ARG2(*icall);
    440        
    441         node_t *dev = find_dev_node(&device_tree, handle);
    442         if (dev == NULL) {
    443                 printf(NAME ": devman_forward error - no device with handle %" PRIun
    444                     " was found.\n", handle);
    445                 ipc_answer_0(iid, ENOENT);
     469        devman_handle_t fwd_h;
     470        fun_node_t *fun = NULL;
     471        dev_node_t *dev = NULL;
     472       
     473        fun = find_fun_node(&device_tree, handle);
     474        if (fun == NULL)
     475                dev = find_dev_node(&device_tree, handle);
     476        else
     477                dev = fun->dev;
     478
     479        if (fun == NULL && dev == NULL) {
     480                printf(NAME ": devman_forward error - no device or function with "
     481                    "handle %" PRIun " was found.\n", handle);
     482                async_answer_0(iid, ENOENT);
     483                return;
     484        }
     485
     486        if (fun == NULL && !drv_to_parent) {
     487                printf(NAME ": devman_forward error - cannot connect to "
     488                    "handle %" PRIun ", refers to a device.\n", handle);
     489                async_answer_0(iid, ENOENT);
    446490                return;
    447491        }
     
    450494       
    451495        if (drv_to_parent) {
    452                 if (dev->parent != NULL)
    453                         driver = dev->parent->drv;
     496                /* Connect to parent function of a device (or device function). */
     497                if (dev->pfun->dev != NULL)
     498                        driver = dev->pfun->dev->drv;
     499                fwd_h = dev->pfun->handle;
    454500        } else if (dev->state == DEVICE_USABLE) {
     501                /* Connect to the specified function */
    455502                driver = dev->drv;
    456503                assert(driver != NULL);
     504
     505                fwd_h = handle;
    457506        }
    458507       
    459508        if (driver == NULL) {
    460                 printf(NAME ": devman_forward error - the device %" PRIun \
    461                     " (%s) is not in usable state.\n",
    462                     handle, dev->pathname);
    463                 ipc_answer_0(iid, ENOENT);
     509                printf(NAME ": devman_forward error - the device is not in %" PRIun
     510                    " usable state.\n", handle);
     511                async_answer_0(iid, ENOENT);
    464512                return;
    465513        }
     
    475523                    driver->name);
    476524                printf("the driver's phone is %" PRIun ").\n", driver->phone);
    477                 ipc_answer_0(iid, EINVAL);
    478                 return;
    479         }
    480 
    481         printf(NAME ": devman_forward: forward connection to device %s to "
    482             "driver %s.\n", dev->pathname, driver->name);
    483         ipc_forward_fast(iid, driver->phone, method, dev->handle, 0, IPC_FF_NONE);
     525                async_answer_0(iid, EINVAL);
     526                return;
     527        }
     528
     529        if (fun != NULL) {
     530                printf(NAME ": devman_forward: forward connection to function %s to "
     531                    "driver %s.\n", fun->pathname, driver->name);
     532        } else {
     533                printf(NAME ": devman_forward: forward connection to device %s to "
     534                    "driver %s.\n", dev->pfun->pathname, driver->name);
     535        }
     536
     537        async_forward_fast(iid, driver->phone, method, fwd_h, 0, IPC_FF_NONE);
    484538}
    485539
     
    489543{
    490544        devmap_handle_t devmap_handle = IPC_GET_ARG2(*icall);
    491         node_t *dev;
    492 
    493         dev = find_devmap_tree_device(&device_tree, devmap_handle);
    494         if (dev == NULL)
    495                 dev = find_devmap_class_device(&class_list, devmap_handle);
    496        
    497         if (dev == NULL || dev->drv == NULL) {
    498                 ipc_answer_0(iid, ENOENT);
    499                 return;
    500         }
     545        fun_node_t *fun;
     546        dev_node_t *dev;
     547
     548        fun = find_devmap_tree_function(&device_tree, devmap_handle);
     549        if (fun == NULL)
     550                fun = find_devmap_class_function(&class_list, devmap_handle);
     551       
     552        if (fun == NULL || fun->dev->drv == NULL) {
     553                async_answer_0(iid, ENOENT);
     554                return;
     555        }
     556       
     557        dev = fun->dev;
    501558       
    502559        if (dev->state != DEVICE_USABLE || dev->drv->phone <= 0) {
    503                 ipc_answer_0(iid, EINVAL);
    504                 return;
    505         }
    506        
    507         ipc_forward_fast(iid, dev->drv->phone, DRIVER_CLIENT, dev->handle, 0,
     560                async_answer_0(iid, EINVAL);
     561                return;
     562        }
     563       
     564        async_forward_fast(iid, dev->drv->phone, DRIVER_CLIENT, fun->handle, 0,
    508565            IPC_FF_NONE);
    509566        printf(NAME ": devman_connection_devmapper: forwarded connection to "
    510             "device %s to driver %s.\n", dev->pathname, dev->drv->name);
     567            "device %s to driver %s.\n", fun->pathname, dev->drv->name);
    511568}
    512569
     
    536593        default:
    537594                /* No such interface */
    538                 ipc_answer_0(iid, ENOENT);
     595                async_answer_0(iid, ENOENT);
    539596        }
    540597}
     
    587644
    588645        /* Register device manager at naming service. */
    589         sysarg_t phonead;
    590         if (ipc_connect_to_me(PHONE_NS, SERVICE_DEVMAN, 0, 0, &phonead) != 0)
     646        if (service_register(SERVICE_DEVMAN) != EOK)
    591647                return -1;
    592648
Note: See TracChangeset for help on using the changeset viewer.