Ignore:
File:
1 edited

Legend:

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

    r1dc4a5e rcc574511  
    6464static driver_list_t drivers_list;
    6565static dev_tree_t device_tree;
     66static class_list_t class_list;
    6667
    6768/** Register running driver. */
     
    332333}
    333334
    334 static void devman_add_function_to_cat(ipc_callid_t callid, ipc_call_t *call)
     335static void loc_register_class_dev(dev_class_info_t *cli)
     336{
     337        /* Create loc path and name for the service. */
     338        char *loc_pathname = NULL;
     339
     340        asprintf(&loc_pathname, "%s/%s%c%s", LOC_CLASS_NAMESPACE,
     341            cli->dev_class->name, LOC_SEPARATOR, cli->dev_name);
     342        if (loc_pathname == NULL)
     343                return;
     344       
     345        /*
     346         * Register the device with location service and remember its
     347         * service ID.
     348         */
     349        loc_service_register_with_iface(loc_pathname,
     350            &cli->service_id, DEVMAN_CONNECT_FROM_LOC);
     351       
     352        /*
     353         * Add device to the hash map of class devices registered with
     354         * location service.
     355         */
     356        class_add_loc_function(&class_list, cli);
     357       
     358        free(loc_pathname);
     359}
     360
     361static void devman_add_function_to_class(ipc_callid_t callid, ipc_call_t *call)
    335362{
    336363        devman_handle_t handle = IPC_GET_ARG1(*call);
     
    338365        int rc;
    339366       
    340         /* Get category name. */
    341         char *cat_name;
    342         rc = async_data_write_accept((void **) &cat_name, true,
     367        /* Get class name. */
     368        char *class_name;
     369        rc = async_data_write_accept((void **) &class_name, true,
    343370            0, 0, 0, 0);
    344371        if (rc != EOK) {
     
    353380        }
    354381       
    355         rc = loc_category_get_id(cat_name, &cat_id, IPC_FLAG_BLOCKING);
     382        dev_class_t *cl = get_dev_class(&class_list, class_name);
     383        dev_class_info_t *class_info = add_function_to_class(fun, cl, NULL);
     384       
     385        /* Register the device's class alias with location service. */
     386        loc_register_class_dev(class_info);
     387       
     388        rc = loc_category_get_id(class_name, &cat_id, IPC_FLAG_BLOCKING);
    356389        if (rc == EOK) {
    357390                loc_service_add_to_cat(fun->service_id, cat_id);
    358391        } else {
    359392                log_msg(LVL_ERROR, "Failed adding function `%s' to category "
    360                     "`%s'.", fun->pathname, cat_name);
    361         }
    362        
    363         log_msg(LVL_NOTE, "Function `%s' added to category `%s'.",
    364             fun->pathname, cat_name);
     393                    "`%s'.", fun->pathname, class_name);
     394        }
     395       
     396        log_msg(LVL_NOTE, "Function `%s' added to class `%s' as `%s'.",
     397            fun->pathname, class_name, class_info->dev_name);
    365398
    366399        async_answer_0(callid, EOK);
     
    416449                        devman_add_function(callid, &call);
    417450                        break;
    418                 case DEVMAN_ADD_DEVICE_TO_CATEGORY:
    419                         devman_add_function_to_cat(callid, &call);
     451                case DEVMAN_ADD_DEVICE_TO_CLASS:
     452                        devman_add_function_to_class(callid, &call);
    420453                        break;
    421454                default:
     
    450483}
    451484
     485/** Find handle for the device instance identified by device class name. */
     486static void devman_function_get_handle_by_class(ipc_callid_t iid,
     487    ipc_call_t *icall)
     488{
     489        char *classname;
     490        char *devname;
     491
     492        int rc = async_data_write_accept((void **) &classname, true, 0, 0, 0, 0);
     493        if (rc != EOK) {
     494                async_answer_0(iid, rc);
     495                return;
     496        }
     497        rc = async_data_write_accept((void **) &devname, true, 0, 0, 0, 0);
     498        if (rc != EOK) {
     499                free(classname);
     500                async_answer_0(iid, rc);
     501                return;
     502        }
     503
     504
     505        fun_node_t *fun = find_fun_node_by_class(&class_list,
     506            classname, devname);
     507
     508        free(classname);
     509        free(devname);
     510
     511        if (fun == NULL) {
     512                async_answer_0(iid, ENOENT);
     513                return;
     514        }
     515
     516        async_answer_1(iid, EOK, fun->handle);
     517}
     518
    452519/** Find device path by its handle. */
    453520static void devman_get_device_path_by_handle(ipc_callid_t iid,
     
    487554}
    488555
    489 /** Find handle for the function instance identified by its service ID. */
    490 static void devman_fun_sid_to_handle(ipc_callid_t iid, ipc_call_t *icall)
    491 {
    492         fun_node_t *fun;
    493 
    494         fun = find_loc_tree_function(&device_tree, IPC_GET_ARG1(*icall));
    495        
    496         if (fun == NULL) {
    497                 async_answer_0(iid, ENOENT);
    498                 return;
    499         }
    500 
    501         async_answer_1(iid, EOK, fun->handle);
    502 }
    503556
    504557/** Function for handling connections from a client to the device manager. */
     
    519572                        devman_function_get_handle(callid, &call);
    520573                        break;
     574                case DEVMAN_DEVICE_GET_HANDLE_BY_CLASS:
     575                        devman_function_get_handle_by_class(callid, &call);
     576                        break;
    521577                case DEVMAN_DEVICE_GET_DEVICE_PATH:
    522578                        devman_get_device_path_by_handle(callid, &call);
    523                         break;
    524                 case DEVMAN_FUN_SID_TO_HANDLE:
    525                         devman_fun_sid_to_handle(callid, &call);
    526579                        break;
    527580                default:
     
    625678
    626679        fun = find_loc_tree_function(&device_tree, service_id);
     680        if (fun == NULL)
     681                fun = find_loc_class_function(&class_list, service_id);
    627682       
    628683        if (fun == NULL || fun->dev->drv == NULL) {
    629                 log_msg(LVL_WARN, "devman_connection_loc(): function "
    630                     "not found.\n");
    631684                async_answer_0(iid, ENOENT);
    632685                return;
     
    634687       
    635688        dev = fun->dev;
     689       
     690        if ((dev->state != DEVICE_USABLE) || (!dev->drv->sess)) {
     691                async_answer_0(iid, EINVAL);
     692                return;
     693        }
    636694       
    637695        async_exch_t *exch = async_exchange_begin(dev->drv->sess);
     
    695753        }
    696754
     755        init_class_list(&class_list);
     756       
    697757        /*
    698758         * !!! devman_connection ... as the device manager is not a real loc
Note: See TracChangeset for help on using the changeset viewer.