Changes in / [cfc3027:bdbb6f6] in mainline


Ignore:
Location:
uspace
Files:
2 added
11 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/tester/Makefile

    rcfc3027 rbdbb6f6  
    4949        loop/loop1.c \
    5050        mm/malloc1.c \
     51        devs/devman1.c \
    5152        hw/misc/virtchar1.c \
    5253        hw/serial/serial1.c
  • uspace/app/tester/tester.c

    rcfc3027 rbdbb6f6  
    6464#include "hw/serial/serial1.def"
    6565#include "hw/misc/virtchar1.def"
     66#include "devs/devman1.def"
    6667        {NULL, NULL, NULL, false}
    6768};
  • uspace/app/tester/tester.h

    rcfc3027 rbdbb6f6  
    8080extern const char *test_serial1(void);
    8181extern const char *test_virtchar1(void);
     82extern const char *test_devman1(void);
    8283
    8384extern test_t tests[];
  • uspace/drv/test1/test1.c

    rcfc3027 rbdbb6f6  
    5959 */
    6060static int register_fun_verbose(ddf_dev_t *parent, const char *message,
    61     const char *name, const char *match_id, int match_score)
     61    const char *name, const char *match_id, int match_score,
     62    int expected_rc)
    6263{
    63         ddf_fun_t *fun;
     64        ddf_fun_t *fun = NULL;
    6465        int rc;
    6566
     
    6970        if (fun == NULL) {
    7071                ddf_msg(LVL_ERROR, "Failed creating function %s\n", name);
    71                 return ENOMEM;
     72                rc = ENOMEM;
     73                goto leave;
    7274        }
    7375
    74         rc = ddf_fun_add_match_id(fun, match_id, match_score);
     76        rc = ddf_fun_add_match_id(fun, str_dup(match_id), match_score);
    7577        if (rc != EOK) {
    7678                ddf_msg(LVL_ERROR, "Failed adding match IDs to function %s\n",
    7779                    name);
    78                 ddf_fun_destroy(fun);
    79                 return rc;
     80                goto leave;
    8081        }
    8182
     
    8485                ddf_msg(LVL_ERROR, "Failed binding function %s: %s\n", name,
    8586                    str_error(rc));
    86                 ddf_fun_destroy(fun);
    87                 return rc;
     87                goto leave;
    8888        }
    8989
    9090        ddf_msg(LVL_NOTE, "Registered child device `%s'\n", name);
    91         return EOK;
     91        rc = EOK;
     92
     93leave:
     94        if (rc != expected_rc) {
     95                fprintf(stderr,
     96                    NAME ": Unexpected error registering function `%s'.\n"
     97                    NAME ":     Expected \"%s\" but got \"%s\".\n",
     98                    name, str_error(expected_rc), str_error(rc));
     99        }
     100
     101        if ((rc != EOK) && (fun != NULL)) {
     102                ddf_fun_destroy(fun);
     103        }
     104
     105        return rc;
    92106}
    93107
     
    135149                ddf_fun_add_to_class(fun_a, "virt-null");
    136150        } else if (str_cmp(dev->name, "test1") == 0) {
    137                 (void) register_fun_verbose(dev, "cloning myself ;-)", "clone",
    138                     "virtual&test1", 10);
     151                (void) register_fun_verbose(dev,
     152                    "cloning myself ;-)", "clone",
     153                    "virtual&test1", 10, EOK);
     154                (void) register_fun_verbose(dev,
     155                    "cloning myself twice ;-)", "clone",
     156                    "virtual&test1", 10, EEXISTS);
    139157        } else if (str_cmp(dev->name, "clone") == 0) {
    140                 (void) register_fun_verbose(dev, "run by the same task", "child",
    141                     "virtual&test1&child", 10);
     158                (void) register_fun_verbose(dev,
     159                    "run by the same task", "child",
     160                    "virtual&test1&child", 10, EOK);
    142161        }
    143162
  • uspace/lib/c/generic/devman.c

    rcfc3027 rbdbb6f6  
    147147                ret = devman_send_match_id(phone, match_id);
    148148                if (ret != EOK) {
    149                         printf("Driver failed to send match id, error %d\n",
    150                             ret);
    151149                        return ret;
    152150                }
     
    195193        }
    196194       
    197         devman_send_match_ids(phone, match_ids);
    198        
    199         async_wait_for(req, &retval);
    200        
    201         async_serialize_end();
    202        
     195        int match_ids_rc = devman_send_match_ids(phone, match_ids);
     196       
     197        async_wait_for(req, &retval);
     198       
     199        async_serialize_end();
     200       
     201        /* Prefer the answer to DEVMAN_ADD_FUNCTION in case of errors. */
     202        if ((match_ids_rc != EOK) && (retval == EOK)) {
     203                retval = match_ids_rc;
     204        }
     205
    203206        if (retval == EOK)
    204207                fun_handle = (int) IPC_GET_ARG1(answer);
     
    326329}
    327330
     331int devman_device_get_handle_by_class(const char *classname,
     332    const char *devname, devman_handle_t *handle, unsigned int flags)
     333{
     334        int phone = devman_get_phone(DEVMAN_CLIENT, flags);
     335
     336        if (phone < 0)
     337                return phone;
     338
     339        async_serialize_start();
     340
     341        ipc_call_t answer;
     342        aid_t req = async_send_1(phone, DEVMAN_DEVICE_GET_HANDLE_BY_CLASS,
     343            flags, &answer);
     344
     345        sysarg_t retval = async_data_write_start(phone, classname,
     346            str_size(classname));
     347        if (retval != EOK) {
     348                async_wait_for(req, NULL);
     349                async_serialize_end();
     350                return retval;
     351        }
     352        retval = async_data_write_start(phone, devname,
     353            str_size(devname));
     354        if (retval != EOK) {
     355                async_wait_for(req, NULL);
     356                async_serialize_end();
     357                return retval;
     358        }
     359
     360        async_wait_for(req, &retval);
     361
     362        async_serialize_end();
     363
     364        if (retval != EOK) {
     365                if (handle != NULL)
     366                        *handle = (devman_handle_t) -1;
     367                return retval;
     368        }
     369
     370        if (handle != NULL)
     371                *handle = (devman_handle_t) IPC_GET_ARG1(answer);
     372
     373        return retval;
     374}
     375
    328376
    329377/** @}
  • uspace/lib/c/include/devman.h

    rcfc3027 rbdbb6f6  
    5353extern int devman_device_get_handle(const char *, devman_handle_t *,
    5454    unsigned int);
     55extern int devman_device_get_handle_by_class(const char *, const char *,
     56    devman_handle_t *, unsigned int);
    5557
    5658extern int devman_add_device_to_class(devman_handle_t, const char *);
  • uspace/lib/c/include/ipc/devman.h

    rcfc3027 rbdbb6f6  
    148148
    149149typedef enum {
    150         DEVMAN_DEVICE_GET_HANDLE = IPC_FIRST_USER_METHOD
     150        DEVMAN_DEVICE_GET_HANDLE = IPC_FIRST_USER_METHOD,
     151        DEVMAN_DEVICE_GET_HANDLE_BY_CLASS
    151152} client_to_devman_t;
    152153
  • uspace/srv/devman/devman.c

    rcfc3027 rbdbb6f6  
    11731173}
    11741174
     1175/** Find function with a specified name belonging to given device.
     1176 *
     1177 * Device tree rwlock should be held at least for reading.
     1178 *
     1179 * @param dev Device the function belongs to.
     1180 * @param name Function name (not path).
     1181 * @return Function node.
     1182 * @retval NULL No function with given name.
     1183 */
     1184fun_node_t *find_fun_node_in_device(dev_node_t *dev, const char *name)
     1185{
     1186        assert(dev != NULL);
     1187        assert(name != NULL);
     1188
     1189        fun_node_t *fun;
     1190        link_t *link;
     1191
     1192        for (link = dev->functions.next;
     1193            link != &dev->functions;
     1194            link = link->next) {
     1195                fun = list_get_instance(link, fun_node_t, dev_functions);
     1196
     1197                if (str_cmp(name, fun->name) == 0)
     1198                        return fun;
     1199        }
     1200
     1201        return NULL;
     1202}
     1203
     1204/** Find function node by its class name and index. */
     1205fun_node_t *find_fun_node_by_class(class_list_t *class_list,
     1206    const char *class_name, const char *dev_name)
     1207{
     1208        assert(class_list != NULL);
     1209        assert(class_name != NULL);
     1210        assert(dev_name != NULL);
     1211
     1212        fibril_rwlock_read_lock(&class_list->rwlock);
     1213
     1214        dev_class_t *cl = find_dev_class_no_lock(class_list, class_name);
     1215        if (cl == NULL) {
     1216                fibril_rwlock_read_unlock(&class_list->rwlock);
     1217                return NULL;
     1218        }
     1219
     1220        dev_class_info_t *dev = find_dev_in_class(cl, dev_name);
     1221        if (dev == NULL) {
     1222                fibril_rwlock_read_unlock(&class_list->rwlock);
     1223                return NULL;
     1224        }
     1225
     1226        fun_node_t *fun = dev->fun;
     1227
     1228        fibril_rwlock_read_unlock(&class_list->rwlock);
     1229
     1230        return fun;
     1231}
     1232
     1233
    11751234/** Find child function node with a specified name.
    11761235 *
     
    11831242fun_node_t *find_node_child(fun_node_t *pfun, const char *name)
    11841243{
    1185         fun_node_t *fun;
    1186         link_t *link;
    1187        
    1188         link = pfun->child->functions.next;
    1189        
    1190         while (link != &pfun->child->functions) {
    1191                 fun = list_get_instance(link, fun_node_t, dev_functions);
    1192                
    1193                 if (str_cmp(name, fun->name) == 0)
    1194                         return fun;
    1195                
    1196                 link = link->next;
    1197         }
    1198        
    1199         return NULL;
     1244        return find_fun_node_in_device(pfun->child, name);
    12001245}
    12011246
     
    13591404}
    13601405
     1406dev_class_info_t *find_dev_in_class(dev_class_t *dev_class, const char *dev_name)
     1407{
     1408        assert(dev_class != NULL);
     1409        assert(dev_name != NULL);
     1410
     1411        link_t *link;
     1412        for (link = dev_class->devices.next;
     1413            link != &dev_class->devices;
     1414            link = link->next) {
     1415                dev_class_info_t *dev = list_get_instance(link,
     1416                    dev_class_info_t, link);
     1417
     1418                if (str_cmp(dev->dev_name, dev_name) == 0) {
     1419                        return dev;
     1420                }
     1421        }
     1422
     1423        return NULL;
     1424}
     1425
    13611426void init_class_list(class_list_t *class_list)
    13621427{
  • uspace/srv/devman/devman.h

    rcfc3027 rbdbb6f6  
    338338extern fun_node_t *find_fun_node(dev_tree_t *tree, devman_handle_t handle);
    339339extern fun_node_t *find_fun_node_by_path(dev_tree_t *, char *);
     340extern fun_node_t *find_fun_node_in_device(dev_node_t *, const char *);
     341extern fun_node_t *find_fun_node_by_class(class_list_t *, const char *, const char *);
    340342
    341343/* Device tree */
     
    359361extern dev_class_t *get_dev_class(class_list_t *, char *);
    360362extern dev_class_t *find_dev_class_no_lock(class_list_t *, const char *);
     363extern dev_class_info_t *find_dev_in_class(dev_class_t *, const char *);
    361364extern void add_dev_class_no_lock(class_list_t *, dev_class_t *);
    362365
  • uspace/srv/devman/main.c

    rcfc3027 rbdbb6f6  
    248248        }
    249249       
     250        /* Check that function with same name is not there already. */
     251        if (find_fun_node_in_device(pdev, fun_name) != NULL) {
     252                fibril_rwlock_write_unlock(&tree->rwlock);
     253                async_answer_0(callid, EEXISTS);
     254                printf(NAME ": Warning, driver tried to register `%s' twice.\n",
     255                    fun_name);
     256                free(fun_name);
     257                return;
     258        }
     259
    250260        fun_node_t *fun = create_fun_node();
    251261        if (!insert_fun_node(&device_tree, fun, fun_name, pdev)) {
     
    443453}
    444454
     455/** Find handle for the device instance identified by device class name. */
     456static void devman_function_get_handle_by_class(ipc_callid_t iid,
     457    ipc_call_t *icall)
     458{
     459        char *classname;
     460        char *devname;
     461
     462        int rc = async_data_write_accept((void **) &classname, true, 0, 0, 0, 0);
     463        if (rc != EOK) {
     464                async_answer_0(iid, rc);
     465                return;
     466        }
     467        rc = async_data_write_accept((void **) &devname, true, 0, 0, 0, 0);
     468        if (rc != EOK) {
     469                free(classname);
     470                async_answer_0(iid, rc);
     471                return;
     472        }
     473
     474
     475        fun_node_t *fun = find_fun_node_by_class(&class_list,
     476            classname, devname);
     477
     478        free(classname);
     479        free(devname);
     480
     481        if (fun == NULL) {
     482                async_answer_0(iid, ENOENT);
     483                return;
     484        }
     485
     486        async_answer_1(iid, EOK, fun->handle);
     487}
     488
    445489
    446490/** Function for handling connections from a client to the device manager. */
     
    461505                case DEVMAN_DEVICE_GET_HANDLE:
    462506                        devman_function_get_handle(callid, &call);
     507                        break;
     508                case DEVMAN_DEVICE_GET_HANDLE_BY_CLASS:
     509                        devman_function_get_handle_by_class(callid, &call);
    463510                        break;
    464511                default:
  • uspace/srv/devmap/devmap.c

    rcfc3027 rbdbb6f6  
    551551        if (devmap_device_find_name(namespace->name, device->name) != NULL) {
    552552                printf("%s: Device '%s/%s' already registered\n", NAME,
    553                     device->namespace->name, device->name);
     553                    namespace->name, device->name);
    554554                devmap_namespace_destroy(namespace);
    555555                fibril_mutex_unlock(&devices_list_mutex);
Note: See TracChangeset for help on using the changeset viewer.