Changes in / [1d2a1a9:0cc32f2] in mainline


Ignore:
Files:
4 deleted
41 edited

Legend:

Unmodified
Added
Removed
  • boot/Makefile.common

    r1d2a1a9 r0cc32f2  
    150150        $(USPACE_PATH)/app/kill/kill \
    151151        $(USPACE_PATH)/app/killall/killall \
     152        $(USPACE_PATH)/app/locinfo/locinfo \
    152153        $(USPACE_PATH)/app/mkfat/mkfat \
    153154        $(USPACE_PATH)/app/lsusb/lsusb \
  • uspace/Makefile

    r1d2a1a9 r0cc32f2  
    4444        app/killall \
    4545        app/klog \
     46        app/locinfo \
    4647        app/lsusb \
    4748        app/mkfat \
  • uspace/app/lsusb/main.c

    r1d2a1a9 r0cc32f2  
    5050
    5151#define MAX_USB_ADDRESS USB11_ADDRESS_MAX
    52 #define MAX_FAILED_ATTEMPTS 10
    5352#define MAX_PATH_LENGTH 1024
    5453
    55 static void print_found_hc(size_t class_index, const char *path)
     54static void print_found_hc(service_id_t sid, const char *path)
    5655{
    57         // printf(NAME ": host controller %zu is `%s'.\n", class_index, path);
    58         printf("Bus %02zu: %s\n", class_index, path);
     56        printf("Bus %" PRIun ": %s\n", sid, path);
    5957}
    6058static void print_found_dev(usb_address_t addr, const char *path)
    6159{
    62         // printf(NAME ":     device with address %d is `%s'.\n", addr, path);
    6360        printf("  Device %02d: %s\n", addr, path);
    6461}
     
    9592int main(int argc, char *argv[])
    9693{
    97         size_t class_index = 0;
    98         size_t failed_attempts = 0;
     94        category_id_t usbhc_cat;
     95        service_id_t *svcs;
     96        size_t count;
     97        size_t i;
     98        int rc;
    9999
    100         while (failed_attempts < MAX_FAILED_ATTEMPTS) {
    101                 class_index++;
     100        rc = loc_category_get_id(USB_HC_CATEGORY, &usbhc_cat, 0);
     101        if (rc != EOK) {
     102                printf(NAME ": Error resolving category '%s'",
     103                    USB_HC_CATEGORY);
     104                return 1;
     105        }
     106
     107        rc = loc_category_get_svcs(usbhc_cat, &svcs, &count);
     108        if (rc != EOK) {
     109                printf(NAME ": Error getting list of host controllers.\n");
     110                return 1;
     111        }
     112
     113        for (i = 0; i < count; i++) {
    102114                devman_handle_t hc_handle = 0;
    103                 int rc = usb_ddf_get_hc_handle_by_class(class_index, &hc_handle);
     115                int rc = usb_ddf_get_hc_handle_by_sid(svcs[i], &hc_handle);
    104116                if (rc != EOK) {
    105                         failed_attempts++;
     117                        printf(NAME ": Error resolving handle of HC with SID %"
     118                            PRIun ", skipping.\n", svcs[i]);
    106119                        continue;
    107120                }
     
    109122                rc = devman_get_device_path(hc_handle, path, MAX_PATH_LENGTH);
    110123                if (rc != EOK) {
     124                        printf(NAME ": Error resolving path of HC with SID %"
     125                            PRIun ", skipping.\n", svcs[i]);
    111126                        continue;
    112127                }
    113                 print_found_hc(class_index, path);
     128                print_found_hc(svcs[i], path);
    114129                print_hc_devices(hc_handle);
    115130        }
     131
     132        free(svcs);
    116133
    117134        return 0;
  • uspace/app/tester/Makefile

    r1d2a1a9 r0cc32f2  
    5656        mm/malloc3.c \
    5757        mm/mapping1.c \
    58         devs/devman1.c \
    59         devs/devman2.c \
    6058        hw/misc/virtchar1.c \
    6159        hw/serial/serial1.c \
  • uspace/app/tester/hw/misc/virtchar1.c

    r1d2a1a9 r0cc32f2  
    4949
    5050#define DEVICE_PATH_NORMAL "/loc/devices/\\virt\\null\\a"
    51 #define DEVICE_PATH_CLASSES "/loc/class/virt-null\\1"
    5251#define BUFFER_SIZE 64
    5352
     
    105104        }
    106105
    107         res = test_virtchar1_internal(DEVICE_PATH_CLASSES);
    108         if (res != NULL) {
    109                 return res;
    110         }
    111 
    112106        return NULL;
    113107}
  • uspace/app/tester/tester.c

    r1d2a1a9 r0cc32f2  
    6868#include "hw/misc/virtchar1.def"
    6969#include "libext2/libext2_1.def"
    70 #include "devs/devman1.def"
    71 #include "devs/devman2.def"
    7270        {NULL, NULL, NULL, false}
    7371};
  • uspace/drv/bus/usb/ehci/main.c

    r1d2a1a9 r0cc32f2  
    101101            "Failed to bind EHCI function: %s.\n",
    102102            str_error(ret));
    103         ret = ddf_fun_add_to_class(hc_fun, USB_HC_DDF_CLASS_NAME);
     103        ret = ddf_fun_add_to_category(hc_fun, USB_HC_CATEGORY);
    104104        CHECK_RET_RETURN(ret,
    105105            "Failed to add EHCI to HC class: %s.\n",
  • uspace/drv/bus/usb/ohci/ohci.c

    r1d2a1a9 r0cc32f2  
    244244            "Failed to bind OHCI device function: %s.\n", str_error(ret));
    245245
    246         ret = ddf_fun_add_to_class(instance->hc_fun, USB_HC_DDF_CLASS_NAME);
     246        ret = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY);
    247247        CHECK_RET_FINI_RETURN(ret,
    248248            "Failed to add OHCI to HC class: %s.\n", str_error(ret));
  • uspace/drv/bus/usb/uhci/uhci.c

    r1d2a1a9 r0cc32f2  
    267267            str_error(ret));
    268268
    269         ret = ddf_fun_add_to_class(instance->hc_fun, USB_HC_DDF_CLASS_NAME);
     269        ret = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY);
    270270        CHECK_RET_FINI_RETURN(ret,
    271271            "Failed to add UHCI to HC class: %s.\n", str_error(ret));
  • uspace/drv/bus/usb/usbhid/kbd/kbddev.c

    r1d2a1a9 r0cc32f2  
    102102
    103103const char *HID_KBD_FUN_NAME = "keyboard";
    104 const char *HID_KBD_CLASS_NAME = "keyboard";
     104const char *HID_KBD_CATEGORY_NAME = "keyboard";
    105105
    106106static void usb_kbd_set_led(usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev);
     
    551551            HID_KBD_FUN_NAME, fun->handle);
    552552       
    553         usb_log_debug("Adding DDF function to class %s...\n",
     553        usb_log_debug("Adding DDF function to category %s...\n",
    554554            HID_KBD_CLASS_NAME);
    555         rc = ddf_fun_add_to_class(fun, HID_KBD_CLASS_NAME);
     555        rc = ddf_fun_add_to_category(fun, HID_KBD_CATEGORY_NAME);
    556556        if (rc != EOK) {
    557557                usb_log_error(
    558                     "Could not add DDF function to class %s: %s.\n",
     558                    "Could not add DDF function to category %s: %s.\n",
    559559                    HID_KBD_CLASS_NAME, str_error(rc));
    560560                ddf_fun_destroy(fun);
  • uspace/drv/bus/usb/usbhid/mouse/mousedev.c

    r1d2a1a9 r0cc32f2  
    7474const char *HID_MOUSE_FUN_NAME = "mouse";
    7575const char *HID_MOUSE_WHEEL_FUN_NAME = "mouse-wheel";
    76 const char *HID_MOUSE_CLASS_NAME = "mouse";
    77 const char *HID_MOUSE_WHEEL_CLASS_NAME = "keyboard";
     76const char *HID_MOUSE_CATEGORY = "mouse";
     77const char *HID_MOUSE_WHEEL_CATEGORY = "keyboard";
    7878
    7979/** Default idle rate for mouses. */
     
    345345        }
    346346       
    347         usb_log_debug("Adding DDF function to class %s...\n",
    348             HID_MOUSE_CLASS_NAME);
    349         rc = ddf_fun_add_to_class(fun, HID_MOUSE_CLASS_NAME);
     347        usb_log_debug("Adding DDF function to category %s...\n",
     348            HID_MOUSE_CATEGORY);
     349        rc = ddf_fun_add_to_category(fun, HID_MOUSE_CATEGORY);
    350350        if (rc != EOK) {
    351351                usb_log_error(
    352                     "Could not add DDF function to class %s: %s.\n",
    353                     HID_MOUSE_CLASS_NAME, str_error(rc));
     352                    "Could not add DDF function to category %s: %s.\n",
     353                    HID_MOUSE_CATEGORY, str_error(rc));
    354354                ddf_fun_destroy(fun);
    355355                return rc;
     
    383383        }
    384384       
    385         usb_log_debug("Adding DDF function to class %s...\n",
    386             HID_MOUSE_WHEEL_CLASS_NAME);
    387         rc = ddf_fun_add_to_class(fun, HID_MOUSE_WHEEL_CLASS_NAME);
     385        usb_log_debug("Adding DDF function to category %s...\n",
     386            HID_MOUSE_WHEEL_CATEGORY);
     387        rc = ddf_fun_add_to_category(fun, HID_MOUSE_WHEEL_CATEGORY);
    388388        if (rc != EOK) {
    389389                usb_log_error(
    390                     "Could not add DDF function to class %s: %s.\n",
    391                     HID_MOUSE_WHEEL_CLASS_NAME, str_error(rc));
     390                    "Could not add DDF function to category %s: %s.\n",
     391                    HID_MOUSE_WHEEL_CATEGORY, str_error(rc));
    392392                ddf_fun_destroy(fun);
    393393                return rc;
  • uspace/drv/bus/usb/usbhid/mouse/mousedev.h

    r1d2a1a9 r0cc32f2  
    5959
    6060const char *HID_MOUSE_FUN_NAME;
    61 const char *HID_MOUSE_CLASS_NAME;
     61const char *HID_MOUSE_CATEGORY;
    6262
    6363/*----------------------------------------------------------------------------*/
  • uspace/drv/bus/usb/usbhid/multimedia/multimedia.c

    r1d2a1a9 r0cc32f2  
    205205        }
    206206       
    207         usb_log_debug("%s function created (jandle: %" PRIun ").\n",
     207        usb_log_debug("%s function created (handle: %" PRIun ").\n",
    208208            NAME, fun->handle);
    209209       
    210         rc = ddf_fun_add_to_class(fun, "keyboard");
     210        rc = ddf_fun_add_to_category(fun, "keyboard");
    211211        if (rc != EOK) {
    212212                usb_log_error(
    213                     "Could not add DDF function to class 'keyboard': %s.\n",
     213                    "Could not add DDF function to category 'keyboard': %s.\n",
    214214                    str_error(rc));
    215215                // TODO: Can / should I destroy the DDF function?
  • uspace/drv/bus/usb/usbhub/usbhub.c

    r1d2a1a9 r0cc32f2  
    131131        opResult = ddf_fun_bind(hub_fun);
    132132        assert(opResult == EOK);
    133         opResult = ddf_fun_add_to_class(hub_fun, "hub");
     133        opResult = ddf_fun_add_to_category(hub_fun, "hub");
    134134        assert(opResult == EOK);
    135135
  • uspace/drv/bus/usb/usbmouse/init.c

    r1d2a1a9 r0cc32f2  
    116116       
    117117        /* Add the function to mouse class. */
    118         rc = ddf_fun_add_to_class(mouse->mouse_fun, "mouse");
     118        rc = ddf_fun_add_to_category(mouse->mouse_fun, "mouse");
    119119        if (rc != EOK)
    120120                goto leave;
  • uspace/drv/bus/usb/vhc/main.c

    r1d2a1a9 r0cc32f2  
    104104        }
    105105
    106         rc = ddf_fun_add_to_class(hc, USB_HC_DDF_CLASS_NAME);
     106        rc = ddf_fun_add_to_category(hc, USB_HC_CATEGORY);
    107107        if (rc != EOK) {
    108108                usb_log_fatal("Failed to add function to HC class: %s.\n",
  • uspace/drv/char/ns8250/ns8250.c

    r1d2a1a9 r0cc32f2  
    781781        ns->fun = fun;
    782782       
    783         ddf_fun_add_to_class(fun, "serial");
     783        ddf_fun_add_to_category(fun, "serial");
    784784       
    785785        ddf_msg(LVL_NOTE, "Device %s successfully initialized.",
  • uspace/drv/test/test1/test1.c

    r1d2a1a9 r0cc32f2  
    143143        }
    144144
    145         ddf_fun_add_to_class(fun_a, "virtual");
     145        ddf_fun_add_to_category(fun_a, "virtual");
    146146
    147147        if (str_cmp(dev->name, "null") == 0) {
    148148                fun_a->ops = &char_device_ops;
    149                 ddf_fun_add_to_class(fun_a, "virt-null");
     149                ddf_fun_add_to_category(fun_a, "virt-null");
    150150        } else if (str_cmp(dev->name, "test1") == 0) {
    151151                (void) register_fun_verbose(dev,
  • uspace/drv/test/test2/test2.c

    r1d2a1a9 r0cc32f2  
    123123        }
    124124
    125         ddf_fun_add_to_class(fun_a, "virtual");
     125        ddf_fun_add_to_category(fun_a, "virtual");
    126126
    127127        return EOK;
  • uspace/drv/test/test3/test3.c

    r1d2a1a9 r0cc32f2  
    5050};
    5151
    52 static int register_fun_and_add_to_class(ddf_dev_t *parent,
     52static int register_fun_and_add_to_category(ddf_dev_t *parent,
    5353     const char *base_name, size_t index, const char *class_name)
    5454{
     
    7777        }
    7878       
    79         ddf_fun_add_to_class(fun, class_name);
     79        ddf_fun_add_to_category(fun, class_name);
    8080
    8181        ddf_msg(LVL_NOTE, "Registered exposed function `%s'.", fun_name);
     
    100100        size_t i;
    101101        for (i = 0; i < 20; i++) {
    102                 rc = register_fun_and_add_to_class(dev,
     102                rc = register_fun_and_add_to_category(dev,
    103103                    "test3_", i, "test3");
    104104                if (rc != EOK) {
  • uspace/lib/c/generic/devman.c

    r1d2a1a9 r0cc32f2  
    271271}
    272272
    273 int devman_add_device_to_class(devman_handle_t devman_handle,
    274     const char *class_name)
     273int devman_add_device_to_category(devman_handle_t devman_handle,
     274    const char *cat_name)
    275275{
    276276        async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_DRIVER);
    277277       
    278278        ipc_call_t answer;
    279         aid_t req = async_send_1(exch, DEVMAN_ADD_DEVICE_TO_CLASS,
     279        aid_t req = async_send_1(exch, DEVMAN_ADD_DEVICE_TO_CATEGORY,
    280280            devman_handle, &answer);
    281         sysarg_t retval = async_data_write_start(exch, class_name,
    282             str_size(class_name));
     281        sysarg_t retval = async_data_write_start(exch, cat_name,
     282            str_size(cat_name));
    283283       
    284284        devman_exchange_end(exch);
     
    333333                exch = devman_exchange_begin(DEVMAN_CLIENT);
    334334                if (exch == NULL)
    335                         return errno;
     335                        return ENOMEM;
    336336        }
    337337       
     
    364364}
    365365
    366 int devman_device_get_handle_by_class(const char *classname,
    367     const char *devname, devman_handle_t *handle, unsigned int flags)
    368 {
    369         async_exch_t *exch;
    370        
    371         if (flags & IPC_FLAG_BLOCKING)
    372                 exch = devman_exchange_begin_blocking(DEVMAN_CLIENT);
    373         else {
    374                 exch = devman_exchange_begin(DEVMAN_CLIENT);
    375                 if (exch == NULL)
    376                         return errno;
    377         }
    378        
    379         ipc_call_t answer;
    380         aid_t req = async_send_1(exch, DEVMAN_DEVICE_GET_HANDLE_BY_CLASS,
    381             flags, &answer);
    382         sysarg_t retval = async_data_write_start(exch, classname,
    383             str_size(classname));
    384        
    385         if (retval != EOK) {
    386                 devman_exchange_end(exch);
    387                 async_wait_for(req, NULL);
    388                 return retval;
    389         }
    390        
    391         retval = async_data_write_start(exch, devname,
    392             str_size(devname));
    393        
    394         devman_exchange_end(exch);
    395        
    396         if (retval != EOK) {
    397                 async_wait_for(req, NULL);
    398                 return retval;
    399         }
    400        
    401         async_wait_for(req, &retval);
    402        
    403         if (retval != EOK) {
    404                 if (handle != NULL)
    405                         *handle = (devman_handle_t) -1;
    406                
    407                 return retval;
    408         }
    409        
    410         if (handle != NULL)
    411                 *handle = (devman_handle_t) IPC_GET_ARG1(answer);
    412        
    413         return retval;
    414 }
    415 
    416366int devman_get_device_path(devman_handle_t handle, char *path, size_t path_size)
    417367{
    418368        async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT);
    419369        if (exch == NULL)
    420                 return errno;
     370                return ENOMEM;
    421371       
    422372        ipc_call_t answer;
     
    463413}
    464414
     415int devman_fun_sid_to_handle(service_id_t sid, devman_handle_t *handle)
     416{
     417        async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT);
     418        if (exch == NULL)
     419                return ENOMEM;
     420       
     421        sysarg_t retval = async_req_1_1(exch, DEVMAN_FUN_SID_TO_HANDLE,
     422            sid, handle);
     423       
     424        devman_exchange_end(exch);
     425        return (int) retval;
     426}
     427
    465428/** @}
    466429 */
  • uspace/lib/c/generic/loc.c

    r1d2a1a9 r0cc32f2  
    4545static FIBRIL_MUTEX_INITIALIZE(loc_consumer_mutex);
    4646
     47static FIBRIL_MUTEX_INITIALIZE(loc_callback_mutex);
     48static bool loc_callback_created = false;
     49
    4750static async_sess_t *loc_supp_block_sess = NULL;
    4851static async_sess_t *loc_cons_block_sess = NULL;
     
    5154static async_sess_t *loc_consumer_sess = NULL;
    5255
     56static loc_cat_change_cb_t cat_change_cb = NULL;
     57
     58static void loc_cb_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
     59{
     60        loc_cat_change_cb_t cb_fun;
     61       
     62        while (true) {
     63                ipc_call_t call;
     64                ipc_callid_t callid = async_get_call(&call);
     65               
     66                if (!IPC_GET_IMETHOD(call)) {
     67                        /* TODO: Handle hangup */
     68                        return;
     69                }
     70               
     71                int retval;
     72               
     73                switch (IPC_GET_IMETHOD(call)) {
     74                case LOC_EVENT_CAT_CHANGE:
     75                        fibril_mutex_lock(&loc_callback_mutex);
     76                        cb_fun = cat_change_cb;
     77                        if (cb_fun != NULL) {
     78                                (*cb_fun)();
     79                        }
     80                        fibril_mutex_unlock(&loc_callback_mutex);
     81                        retval = 0;
     82                        break;
     83                default:
     84                        retval = ENOTSUP;
     85                }
     86               
     87                async_answer_0(callid, retval);
     88        }
     89}
     90
     91
    5392static void clone_session(fibril_mutex_t *mtx, async_sess_t *src,
    5493    async_sess_t **dst)
     
    6099       
    61100        fibril_mutex_unlock(mtx);
     101}
     102
     103static int loc_callback_create(void)
     104{
     105        async_exch_t *exch;
     106        sysarg_t retval;
     107        int rc = EOK;
     108
     109        fibril_mutex_lock(&loc_callback_mutex);
     110       
     111        if (!loc_callback_created) {
     112                exch = loc_exchange_begin_blocking(LOC_PORT_CONSUMER);
     113               
     114                ipc_call_t answer;
     115                aid_t req = async_send_0(exch, LOC_CALLBACK_CREATE, &answer);
     116                async_connect_to_me(exch, 0, 0, 0, loc_cb_conn, NULL);
     117                loc_exchange_end(exch);
     118               
     119                async_wait_for(req, &retval);
     120                if (rc != EOK)
     121                        goto done;
     122               
     123                if (retval != EOK) {
     124                        rc = retval;
     125                        goto done;
     126                }
     127               
     128                loc_callback_created = true;
     129        }
     130       
     131        rc = EOK;
     132done:
     133        fibril_mutex_unlock(&loc_callback_mutex);
     134        return rc;
    62135}
    63136
     
    291364}
    292365
    293 /** Get service name.
    294  *
    295  * Provided ID of a service, return its name.
    296  *
    297  * @param svc_id        Service ID
     366/** Get object name.
     367 *
     368 * Provided ID of an object, return its name.
     369 *
     370 * @param method        IPC method
     371 * @param id            Object ID
    298372 * @param name          Place to store pointer to new string. Caller should
    299373 *                      free it using free().
    300374 * @return              EOK on success or negative error code
    301375 */
    302 int loc_service_get_name(service_id_t svc_id, char **name)
     376static int loc_get_name_internal(sysarg_t method, sysarg_t id, char **name)
    303377{
    304378        async_exch_t *exch;
     
    312386       
    313387        ipc_call_t answer;
    314         aid_t req = async_send_1(exch, LOC_SERVICE_GET_NAME, svc_id, &answer);
     388        aid_t req = async_send_1(exch, method, id, &answer);
    315389        aid_t dreq = async_data_read(exch, name_buf, LOC_NAME_MAXLEN,
    316390            &dreply);
     
    341415}
    342416
     417/** Get category name.
     418 *
     419 * Provided ID of a service, return its name.
     420 *
     421 * @param cat_id        Category ID
     422 * @param name          Place to store pointer to new string. Caller should
     423 *                      free it using free().
     424 * @return              EOK on success or negative error code
     425 */
     426int loc_category_get_name(category_id_t cat_id, char **name)
     427{
     428        return loc_get_name_internal(LOC_CATEGORY_GET_NAME, cat_id, name);
     429}
     430
     431/** Get service name.
     432 *
     433 * Provided ID of a service, return its name.
     434 *
     435 * @param svc_id        Service ID
     436 * @param name          Place to store pointer to new string. Caller should
     437 *                      free it using free().
     438 * @return              EOK on success or negative error code
     439 */
     440int loc_service_get_name(service_id_t svc_id, char **name)
     441{
     442        return loc_get_name_internal(LOC_SERVICE_GET_NAME, svc_id, name);
     443}
    343444
    344445int loc_namespace_get_id(const char *name, service_id_t *handle,
     
    749850            data, count);
    750851}
     852
     853int loc_register_cat_change_cb(loc_cat_change_cb_t cb_fun)
     854{
     855        if (loc_callback_create() != EOK)
     856                return EIO;
     857
     858        cat_change_cb = cb_fun;
     859        return EOK;
     860}
  • uspace/lib/c/include/devman.h

    r1d2a1a9 r0cc32f2  
    3838
    3939#include <ipc/devman.h>
     40#include <ipc/loc.h>
    4041#include <async.h>
    4142#include <bool.h>
     
    5657extern int devman_device_get_handle(const char *, devman_handle_t *,
    5758    unsigned int);
    58 extern int devman_device_get_handle_by_class(const char *, const char *,
    59     devman_handle_t *, unsigned int);
    6059extern int devman_get_device_path(devman_handle_t, char *, size_t);
    6160
    62 extern int devman_add_device_to_class(devman_handle_t, const char *);
     61extern int devman_add_device_to_category(devman_handle_t, const char *);
     62extern int devman_fun_sid_to_handle(service_id_t, devman_handle_t *);
    6363
    6464#endif
  • uspace/lib/c/include/ipc/devman.h

    r1d2a1a9 r0cc32f2  
    138138        DEVMAN_ADD_FUNCTION,
    139139        DEVMAN_ADD_MATCH_ID,
    140         DEVMAN_ADD_DEVICE_TO_CLASS
     140        DEVMAN_ADD_DEVICE_TO_CATEGORY
    141141
    142142} driver_to_devman_t;
     
    149149typedef enum {
    150150        DEVMAN_DEVICE_GET_HANDLE = IPC_FIRST_USER_METHOD,
    151         DEVMAN_DEVICE_GET_HANDLE_BY_CLASS,
    152         DEVMAN_DEVICE_GET_DEVICE_PATH
     151        DEVMAN_DEVICE_GET_DEVICE_PATH,
     152        DEVMAN_FUN_SID_TO_HANDLE
    153153} client_to_devman_t;
    154154
  • uspace/lib/c/include/ipc/loc.h

    r1d2a1a9 r0cc32f2  
    5757        LOC_SERVICE_GET_NAME,
    5858        LOC_NAMESPACE_GET_ID,
     59        LOC_CALLBACK_CREATE,
    5960        LOC_CATEGORY_GET_ID,
     61        LOC_CATEGORY_GET_NAME,
    6062        LOC_CATEGORY_GET_SVCS,
    6163        LOC_ID_PROBE,
     
    6870        LOC_GET_SERVICES
    6971} loc_request_t;
     72
     73typedef enum {
     74        LOC_EVENT_CAT_CHANGE = IPC_FIRST_USER_METHOD
     75} loc_event_t;
    7076
    7177/** Ports provided by location service.
  • uspace/lib/c/include/loc.h

    r1d2a1a9 r0cc32f2  
    4040#include <bool.h>
    4141
     42typedef void (*loc_cat_change_cb_t)(void);
     43
    4244extern async_exch_t *loc_exchange_begin_blocking(loc_interface_t);
    4345extern async_exch_t *loc_exchange_begin(loc_interface_t);
     
    7375extern size_t loc_get_services(service_id_t, loc_sdesc_t **);
    7476extern int loc_get_categories(category_id_t **, size_t *);
     77extern int loc_register_cat_change_cb(loc_cat_change_cb_t);
    7578
    7679
  • uspace/lib/drv/generic/driver.c

    r1d2a1a9 r0cc32f2  
    635635}
    636636
    637 /** Add exposed function to class.
     637/** Add exposed function to category.
    638638 *
    639639 * Must only be called when the function is bound.
    640640 */
    641 int ddf_fun_add_to_class(ddf_fun_t *fun, const char *class_name)
     641int ddf_fun_add_to_category(ddf_fun_t *fun, const char *cat_name)
    642642{
    643643        assert(fun->bound == true);
    644644        assert(fun->ftype == fun_exposed);
    645645       
    646         return devman_add_device_to_class(fun->handle, class_name);
     646        return devman_add_device_to_category(fun->handle, cat_name);
    647647}
    648648
  • uspace/lib/drv/include/ddf/driver.h

    r1d2a1a9 r0cc32f2  
    151151extern int ddf_fun_add_match_id(ddf_fun_t *, const char *, int);
    152152
    153 extern int ddf_fun_add_to_class(ddf_fun_t *, const char *);
     153extern int ddf_fun_add_to_category(ddf_fun_t *, const char *);
    154154
    155155#endif
  • uspace/lib/posix/pwd.c

    r1d2a1a9 r0cc32f2  
    5151
    5252/**
     53 * Retrieve next broken-down entry from the user database.
     54 *
    5355 * Since HelenOS doesn't have user accounts, this always returns
    5456 * the same made-up entry.
    5557 *
    56  * @return
     58 * @return Next user database entry or NULL if not possible. Since HelenOS
     59 *     doesn't have user accounts, this always returns the same made-up entry.
    5760 */
    5861struct posix_passwd *posix_getpwent(void)
     
    6770
    6871/**
    69  * "Rewind the user list".
     72 * Rewind the user list.
    7073 */
    7174void posix_setpwent(void)
     
    8689 *
    8790 * @param name Name of the entry.
    88  * @return
     91 * @return Either found entry or NULL if no such entry exists.
    8992 */
    9093struct posix_passwd *posix_getpwnam(const char *name)
     
    103106 *
    104107 * @param name Name of the entry.
    105  * @param pwd
    106  * @param buffer
    107  * @param bufsize
    108  * @param result
    109  * @return
     108 * @param pwd Original structure.
     109 * @param buffer Buffer for the strings referenced from the result structure.
     110 * @param bufsize Length of the buffer.
     111 * @param result Where to store updated structure.
     112 * @return Zero on success (either found or not found, but without an error),
     113 *     non-zero error number if error occured.
    110114 */
    111115int posix_getpwnam_r(const char *name, struct posix_passwd *pwd,
     
    129133 *
    130134 * @param uid UID of the entry.
    131  * @return
     135 * @return Either found entry or NULL if no such entry exists.
    132136 */
    133137struct posix_passwd *posix_getpwuid(posix_uid_t uid)
     
    144148 *
    145149 * @param uid UID of the entry.
    146  * @param pwd
    147  * @param buffer
    148  * @param bufsize
    149  * @param result
    150  * @return
     150 * @param pwd Original structure.
     151 * @param buffer Buffer for the strings referenced from the result structure.
     152 * @param bufsize Length of the buffer.
     153 * @param result Where to store updated structure.
     154 * @return Zero on success (either found or not found, but without an error),
     155 *     non-zero error number if error occured.
    151156 */
    152157int posix_getpwuid_r(posix_uid_t uid, struct posix_passwd *pwd,
  • uspace/lib/posix/string.c

    r1d2a1a9 r0cc32f2  
    4848
    4949/**
    50  * Decides whether s2 is a prefix of s1.
    51  *
    52  * @param s1 String in which to look for a prefix.
    53  * @param s2 Prefix string to look for.
    54  * @return True if s2 is a prefix of s1, false otherwise.
    55  */
    56 static bool begins_with(const char *s1, const char *s2)
    57 {
    58         while (*s1 == *s2 && *s2 != '\0') {
    59                 s1++;
    60                 s2++;
    61         }
    62        
    63         /* true if the end was reached */
    64         return *s2 == '\0';
    65 }
    66 
    67 /**
    6850 * The same as strpbrk, except it returns pointer to the nul terminator
    6951 * if no occurence is found.
     
    471453
    472454/**
    473  * Find a substring.
     455 * Find a substring. Uses Knuth-Morris-Pratt algorithm.
    474456 *
    475457 * @param s1 String in which to look for a substring.
     
    478460 *     not found.
    479461 */
    480 char *posix_strstr(const char *s1, const char *s2)
    481 {
    482         assert(s1 != NULL);
    483         assert(s2 != NULL);
    484 
    485         /* special case - needle is an empty string */
    486         if (*s2 == '\0') {
    487                 return (char *) s1;
    488         }
    489 
    490         // TODO: use faster algorithm
    491         /* check for prefix from every position - quadratic complexity */
    492         while (*s1 != '\0') {
    493                 if (begins_with(s1, s2)) {
    494                         return (char *) s1;
    495                 }
     462char *posix_strstr(const char *haystack, const char *needle)
     463{
     464        assert(haystack != NULL);
     465        assert(needle != NULL);
     466       
     467        /* Special case - needle is an empty string. */
     468        if (needle[0] == '\0') {
     469                return (char *) haystack;
     470        }
     471       
     472        /* Preprocess needle. */
     473        size_t nlen = posix_strlen(needle);
     474        size_t prefix_table[nlen + 1];
     475       
     476        {
     477                size_t i = 0;
     478                ssize_t j = -1;
    496479               
    497                 s1++;
     480                prefix_table[i] = j;
     481               
     482                while (i < nlen) {
     483                        while (j >= 0 && needle[i] != needle[j]) {
     484                                j = prefix_table[j];
     485                        }
     486                        i++; j++;
     487                        prefix_table[i] = j;
     488                }
     489        }
     490       
     491        /* Search needle using the precomputed table. */
     492        size_t npos = 0;
     493       
     494        for (size_t hpos = 0; haystack[hpos] != '\0'; ++hpos) {
     495                while (npos != 0 && haystack[hpos] != needle[npos]) {
     496                        npos = prefix_table[npos];
     497                }
     498               
     499                if (haystack[hpos] == needle[npos]) {
     500                        npos++;
     501                       
     502                        if (npos == nlen) {
     503                                return (char *) (haystack + hpos - nlen + 1);
     504                        }
     505                }
    498506        }
    499507       
  • uspace/lib/posix/string.h

    r1d2a1a9 r0cc32f2  
    8686extern size_t posix_strcspn(const char *s1, const char *s2);
    8787extern size_t posix_strspn(const char *s1, const char *s2);
    88 extern char *posix_strstr(const char *s1, const char *s2);
     88extern char *posix_strstr(const char *haystack, const char *needle);
    8989
    9090/* Collation Functions */
  • uspace/lib/usb/include/usb/hc.h

    r1d2a1a9 r0cc32f2  
    3838#include <sys/types.h>
    3939#include <ipc/devman.h>
     40#include <ipc/loc.h>
    4041#include <ddf/driver.h>
    4142#include <bool.h>
     
    6869    devman_handle_t *);
    6970
    70 int usb_ddf_get_hc_handle_by_class(size_t, devman_handle_t *);
     71int usb_ddf_get_hc_handle_by_sid(service_id_t, devman_handle_t *);
    7172
    7273
  • uspace/lib/usb/include/usb/usb.h

    r1d2a1a9 r0cc32f2  
    174174} usb_packet_id;
    175175
    176 /** Class name for USB host controllers. */
    177 #define USB_HC_DDF_CLASS_NAME "usbhc"
     176/** Category for USB host controllers. */
     177#define USB_HC_CATEGORY "usbhc"
    178178
    179179#endif
  • uspace/lib/usb/src/hc.c

    r1d2a1a9 r0cc32f2  
    201201/** Get host controller handle by its class index.
    202202 *
    203  * @param class_index Class index for the host controller.
     203 * @param sid Service ID of the HC function.
    204204 * @param hc_handle Where to store the HC handle
    205205 *      (can be NULL for existence test only).
    206206 * @return Error code.
    207207 */
    208 int usb_ddf_get_hc_handle_by_class(size_t class_index,
    209     devman_handle_t *hc_handle)
    210 {
    211         char *class_index_str;
    212         devman_handle_t hc_handle_tmp;
     208int usb_ddf_get_hc_handle_by_sid(service_id_t sid, devman_handle_t *hc_handle)
     209{
     210        devman_handle_t handle;
    213211        int rc;
    214 
    215         rc = asprintf(&class_index_str, "%zu", class_index);
    216         if (rc < 0) {
    217                 return ENOMEM;
    218         }
    219         rc = devman_device_get_handle_by_class("usbhc", class_index_str,
    220             &hc_handle_tmp, 0);
    221         free(class_index_str);
    222         if (rc != EOK) {
    223                 return rc;
    224         }
    225 
    226         if (hc_handle != NULL) {
    227                 *hc_handle = hc_handle_tmp;
    228         }
    229 
    230         return EOK;
     212       
     213        rc = devman_fun_sid_to_handle(sid, &handle);
     214        if (hc_handle != NULL)
     215                *hc_handle = handle;
     216       
     217        return rc;
    231218}
    232219
  • uspace/lib/usb/src/resolve.c

    r1d2a1a9 r0cc32f2  
    4646    devman_handle_t *out_hc_handle, usb_address_t *out_device_address)
    4747{
    48         size_t class_index;
     48        uint64_t sid;
    4949        size_t address;
    5050        int rc;
    5151        char *ptr;
    5252
    53         rc = str_size_t(path, &ptr, 10, false, &class_index);
     53        rc = str_uint64(path, &ptr, 10, false, &sid);
    5454        if (rc != EOK) {
    5555                return false;
     
    6464                return false;
    6565        }
    66         rc = usb_ddf_get_hc_handle_by_class(class_index, out_hc_handle);
     66        rc = usb_ddf_get_hc_handle_by_sid(sid, out_hc_handle);
    6767        if (rc != EOK) {
    6868                return false;
  • uspace/srv/devman/devman.c

    r1d2a1a9 r0cc32f2  
    7373}
    7474
    75 static int loc_devices_class_compare(unsigned long key[], hash_count_t keys,
    76     link_t *item)
    77 {
    78         dev_class_info_t *class_info
    79             = hash_table_get_instance(item, dev_class_info_t, loc_link);
    80         assert(class_info != NULL);
    81 
    82         return (class_info->service_id == (service_id_t) key[0]);
    83 }
    84 
    8575static void devices_remove_callback(link_t *item)
    8676{
     
    10292        .hash = devices_hash,
    10393        .compare = loc_functions_compare,
    104         .remove_callback = devices_remove_callback
    105 };
    106 
    107 static hash_table_operations_t loc_devices_class_ops = {
    108         .hash = devices_hash,
    109         .compare = loc_devices_class_compare,
    11094        .remove_callback = devices_remove_callback
    11195};
     
    950934                link_initialize(&res->dev_functions);
    951935                list_initialize(&res->match_ids.ids);
    952                 list_initialize(&res->classes);
    953936                link_initialize(&res->devman_fun);
    954937                link_initialize(&res->loc_fun);
     
    11931176}
    11941177
    1195 /** Find function node by its class name and index. */
    1196 fun_node_t *find_fun_node_by_class(class_list_t *class_list,
    1197     const char *class_name, const char *dev_name)
    1198 {
    1199         assert(class_list != NULL);
    1200         assert(class_name != NULL);
    1201         assert(dev_name != NULL);
    1202 
    1203         fibril_rwlock_read_lock(&class_list->rwlock);
    1204 
    1205         dev_class_t *cl = find_dev_class_no_lock(class_list, class_name);
    1206         if (cl == NULL) {
    1207                 fibril_rwlock_read_unlock(&class_list->rwlock);
    1208                 return NULL;
    1209         }
    1210 
    1211         dev_class_info_t *dev = find_dev_in_class(cl, dev_name);
    1212         if (dev == NULL) {
    1213                 fibril_rwlock_read_unlock(&class_list->rwlock);
    1214                 return NULL;
    1215         }
    1216 
    1217         fun_node_t *fun = dev->fun;
    1218 
    1219         fibril_rwlock_read_unlock(&class_list->rwlock);
    1220 
    1221         return fun;
    1222 }
    1223 
    1224 
    12251178/** Find child function node with a specified name.
    12261179 *
     
    12351188        return find_fun_node_in_device(pfun->child, name);
    12361189}
    1237 
    1238 /* Device classes */
    1239 
    1240 /** Create device class.
    1241  *
    1242  * @return      Device class.
    1243  */
    1244 dev_class_t *create_dev_class(void)
    1245 {
    1246         dev_class_t *cl;
    1247        
    1248         cl = (dev_class_t *) malloc(sizeof(dev_class_t));
    1249         if (cl != NULL) {
    1250                 memset(cl, 0, sizeof(dev_class_t));
    1251                 list_initialize(&cl->devices);
    1252                 fibril_mutex_initialize(&cl->mutex);
    1253         }
    1254        
    1255         return cl;
    1256 }
    1257 
    1258 /** Create device class info.
    1259  *
    1260  * @return              Device class info.
    1261  */
    1262 dev_class_info_t *create_dev_class_info(void)
    1263 {
    1264         dev_class_info_t *info;
    1265        
    1266         info = (dev_class_info_t *) malloc(sizeof(dev_class_info_t));
    1267         if (info != NULL) {
    1268                 memset(info, 0, sizeof(dev_class_info_t));
    1269                 link_initialize(&info->dev_classes);
    1270                 link_initialize(&info->loc_link);
    1271                 link_initialize(&info->link);
    1272         }
    1273        
    1274         return info;
    1275 }
    1276 
    1277 size_t get_new_class_dev_idx(dev_class_t *cl)
    1278 {
    1279         size_t dev_idx;
    1280        
    1281         fibril_mutex_lock(&cl->mutex);
    1282         dev_idx = ++cl->curr_dev_idx;
    1283         fibril_mutex_unlock(&cl->mutex);
    1284        
    1285         return dev_idx;
    1286 }
    1287 
    1288 
    1289 /** Create unique device name within the class.
    1290  *
    1291  * @param cl            The class.
    1292  * @param base_dev_name Contains the base name for the device if it was
    1293  *                      specified by the driver when it registered the device by
    1294  *                      the class; NULL if driver specified no base name.
    1295  * @return              The unique name for the device within the class.
    1296  */
    1297 char *create_dev_name_for_class(dev_class_t *cl, const char *base_dev_name)
    1298 {
    1299         char *dev_name;
    1300         const char *base_name;
    1301        
    1302         if (base_dev_name != NULL)
    1303                 base_name = base_dev_name;
    1304         else
    1305                 base_name = cl->base_dev_name;
    1306        
    1307         size_t idx = get_new_class_dev_idx(cl);
    1308         asprintf(&dev_name, "%s%zu", base_name, idx);
    1309        
    1310         return dev_name;
    1311 }
    1312 
    1313 /** Add the device function to the class.
    1314  *
    1315  * The device may be added to multiple classes and a class may contain multiple
    1316  * devices. The class and the device are associated with each other by the
    1317  * dev_class_info_t structure.
    1318  *
    1319  * @param dev           The device.
    1320  * @param class         The class.
    1321  * @param base_dev_name The base name of the device within the class if
    1322  *                      specified by the driver, NULL otherwise.
    1323  * @return              dev_class_info_t structure which associates the device
    1324  *                      with the class.
    1325  */
    1326 dev_class_info_t *add_function_to_class(fun_node_t *fun, dev_class_t *cl,
    1327     const char *base_dev_name)
    1328 {
    1329         dev_class_info_t *info;
    1330 
    1331         assert(fun != NULL);
    1332         assert(cl != NULL);
    1333 
    1334         info = create_dev_class_info();
    1335 
    1336        
    1337         if (info != NULL) {
    1338                 info->dev_class = cl;
    1339                 info->fun = fun;
    1340                
    1341                 /* Add the device to the class. */
    1342                 fibril_mutex_lock(&cl->mutex);
    1343                 list_append(&info->link, &cl->devices);
    1344                 fibril_mutex_unlock(&cl->mutex);
    1345                
    1346                 /* Add the class to the device. */
    1347                 list_append(&info->dev_classes, &fun->classes);
    1348                
    1349                 /* Create unique name for the device within the class. */
    1350                 info->dev_name = create_dev_name_for_class(cl, base_dev_name);
    1351         }
    1352        
    1353         return info;
    1354 }
    1355 
    1356 dev_class_t *get_dev_class(class_list_t *class_list, char *class_name)
    1357 {
    1358         dev_class_t *cl;
    1359        
    1360         fibril_rwlock_write_lock(&class_list->rwlock);
    1361         cl = find_dev_class_no_lock(class_list, class_name);
    1362         if (cl == NULL) {
    1363                 cl = create_dev_class();
    1364                 if (cl != NULL) {
    1365                         cl->name = class_name;
    1366                         cl->base_dev_name = "";
    1367                         add_dev_class_no_lock(class_list, cl);
    1368                 }
    1369         }
    1370 
    1371         fibril_rwlock_write_unlock(&class_list->rwlock);
    1372         return cl;
    1373 }
    1374 
    1375 dev_class_t *find_dev_class_no_lock(class_list_t *class_list,
    1376     const char *class_name)
    1377 {
    1378         dev_class_t *cl;
    1379        
    1380         list_foreach(class_list->classes, link) {
    1381                 cl = list_get_instance(link, dev_class_t, link);
    1382                 if (str_cmp(cl->name, class_name) == 0) {
    1383                         return cl;
    1384                 }
    1385         }
    1386        
    1387         return NULL;
    1388 }
    1389 
    1390 void add_dev_class_no_lock(class_list_t *class_list, dev_class_t *cl)
    1391 {
    1392         list_append(&cl->link, &class_list->classes);
    1393 }
    1394 
    1395 dev_class_info_t *find_dev_in_class(dev_class_t *dev_class, const char *dev_name)
    1396 {
    1397         assert(dev_class != NULL);
    1398         assert(dev_name != NULL);
    1399 
    1400         list_foreach(dev_class->devices, link) {
    1401                 dev_class_info_t *dev = list_get_instance(link,
    1402                     dev_class_info_t, link);
    1403 
    1404                 if (str_cmp(dev->dev_name, dev_name) == 0) {
    1405                         return dev;
    1406                 }
    1407         }
    1408 
    1409         return NULL;
    1410 }
    1411 
    1412 void init_class_list(class_list_t *class_list)
    1413 {
    1414         list_initialize(&class_list->classes);
    1415         fibril_rwlock_initialize(&class_list->rwlock);
    1416         hash_table_create(&class_list->loc_functions, DEVICE_BUCKETS, 1,
    1417             &loc_devices_class_ops);
    1418 }
    1419 
    14201190
    14211191/* loc devices */
     
    14361206}
    14371207
    1438 fun_node_t *find_loc_class_function(class_list_t *classes,
    1439     service_id_t service_id)
    1440 {
    1441         fun_node_t *fun = NULL;
    1442         dev_class_info_t *cli;
    1443         link_t *link;
    1444         unsigned long key = (unsigned long)service_id;
    1445        
    1446         fibril_rwlock_read_lock(&classes->rwlock);
    1447         link = hash_table_find(&classes->loc_functions, &key);
    1448         if (link != NULL) {
    1449                 cli = hash_table_get_instance(link, dev_class_info_t,
    1450                     loc_link);
    1451                 fun = cli->fun;
    1452         }
    1453         fibril_rwlock_read_unlock(&classes->rwlock);
    1454        
    1455         return fun;
    1456 }
    1457 
    1458 void class_add_loc_function(class_list_t *class_list, dev_class_info_t *cli)
    1459 {
    1460         unsigned long key = (unsigned long) cli->service_id;
    1461        
    1462         fibril_rwlock_write_lock(&class_list->rwlock);
    1463         hash_table_insert(&class_list->loc_functions, &key, &cli->loc_link);
    1464         fibril_rwlock_write_unlock(&class_list->rwlock);
    1465 
    1466         assert(find_loc_class_function(class_list, cli->service_id) != NULL);
    1467 }
    1468 
    14691208void tree_add_loc_function(dev_tree_t *tree, fun_node_t *fun)
    14701209{
  • uspace/srv/devman/devman.h

    r1d2a1a9 r0cc32f2  
    5353#define DEVICE_BUCKETS 256
    5454
    55 #define LOC_CLASS_NAMESPACE "class"
    5655#define LOC_DEVICE_NAMESPACE "devices"
    5756#define LOC_SEPARATOR '\\'
     
    170169        match_id_list_t match_ids;
    171170       
    172         /** List of device classes to which this device function belongs. */
    173         list_t classes;
    174171        /** Service ID if the device function is registered with loc. */
    175172        service_id_t service_id;
     
    213210        hash_table_t loc_functions;
    214211} dev_tree_t;
    215 
    216 typedef struct dev_class {
    217         /** The name of the class. */
    218         const char *name;
    219        
    220         /**
    221          * Pointer to the previous and next class in the list of registered
    222          * classes.
    223          */
    224         link_t link;
    225        
    226         /**
    227          * List of dev_class_info structures - one for each device registered by
    228          * this class.
    229          */
    230         list_t devices;
    231        
    232         /**
    233          * Default base name for the device within the class, might be overrided
    234          * by the driver.
    235          */
    236         const char *base_dev_name;
    237        
    238         /** Unique numerical identifier of the newly added device. */
    239         size_t curr_dev_idx;
    240         /** Synchronize access to the list of devices in this class. */
    241         fibril_mutex_t mutex;
    242 } dev_class_t;
    243 
    244 /**
    245  * Provides n-to-m mapping between function nodes and classes - each function
    246  * can register in an arbitrary number of classes and each class can contain
    247  * an arbitrary number of device functions.
    248  */
    249 typedef struct dev_class_info {
    250         /** The class. */
    251         dev_class_t *dev_class;
    252         /** The device. */
    253         fun_node_t *fun;
    254        
    255         /**
    256          * Pointer to the previous and next class info in the list of devices
    257          * registered by the class.
    258          */
    259         link_t link;
    260        
    261         /**
    262          * Pointer to the previous and next class info in the list of classes
    263          * by which the device is registered.
    264          */
    265         link_t dev_classes;
    266        
    267         /** The name of the device function within the class. */
    268         char *dev_name;
    269         /** Service ID in the class namespace. */
    270         service_id_t service_id;
    271        
    272         /**
    273          * Link to hash table of services registered with location service using
    274          * their class names.
    275          */
    276         link_t loc_link;
    277 } dev_class_info_t;
    278 
    279 /** The list of device classes. */
    280 typedef struct class_list {
    281         /** List of classes. */
    282         list_t classes;
    283        
    284         /**
    285          * Hash table of services registered with location service using their
    286          * class name, indexed by service IDs.
    287          */
    288         hash_table_t loc_functions;
    289        
    290         /** Fibril mutex for list of classes. */
    291         fibril_rwlock_t rwlock;
    292 } class_list_t;
    293212
    294213/* Match ids and scores */
     
    339258extern fun_node_t *find_fun_node_by_path(dev_tree_t *, char *);
    340259extern fun_node_t *find_fun_node_in_device(dev_node_t *, const char *);
    341 extern fun_node_t *find_fun_node_by_class(class_list_t *, const char *, const char *);
    342260
    343261/* Device tree */
     
    348266extern bool insert_fun_node(dev_tree_t *, fun_node_t *, char *, dev_node_t *);
    349267
    350 /* Device classes */
    351 
    352 extern dev_class_t *create_dev_class(void);
    353 extern dev_class_info_t *create_dev_class_info(void);
    354 extern size_t get_new_class_dev_idx(dev_class_t *);
    355 extern char *create_dev_name_for_class(dev_class_t *, const char *);
    356 extern dev_class_info_t *add_function_to_class(fun_node_t *, dev_class_t *,
    357     const char *);
    358 
    359 extern void init_class_list(class_list_t *);
    360 
    361 extern dev_class_t *get_dev_class(class_list_t *, char *);
    362 extern dev_class_t *find_dev_class_no_lock(class_list_t *, const char *);
    363 extern dev_class_info_t *find_dev_in_class(dev_class_t *, const char *);
    364 extern void add_dev_class_no_lock(class_list_t *, dev_class_t *);
    365 
    366268/* Loc services */
    367269
     
    369271
    370272extern fun_node_t *find_loc_tree_function(dev_tree_t *, service_id_t);
    371 extern fun_node_t *find_loc_class_function(class_list_t *, service_id_t);
    372 
    373 extern void class_add_loc_function(class_list_t *, dev_class_info_t *);
     273
    374274extern void tree_add_loc_function(dev_tree_t *, fun_node_t *);
    375275
  • uspace/srv/devman/main.c

    r1d2a1a9 r0cc32f2  
    6464static driver_list_t drivers_list;
    6565static dev_tree_t device_tree;
    66 static class_list_t class_list;
    6766
    6867/** Register running driver. */
     
    333332}
    334333
    335 static 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 
    361 static void devman_add_function_to_class(ipc_callid_t callid, ipc_call_t *call)
     334static void devman_add_function_to_cat(ipc_callid_t callid, ipc_call_t *call)
    362335{
    363336        devman_handle_t handle = IPC_GET_ARG1(*call);
     
    365338        int rc;
    366339       
    367         /* Get class name. */
    368         char *class_name;
    369         rc = async_data_write_accept((void **) &class_name, true,
     340        /* Get category name. */
     341        char *cat_name;
     342        rc = async_data_write_accept((void **) &cat_name, true,
    370343            0, 0, 0, 0);
    371344        if (rc != EOK) {
     
    380353        }
    381354       
    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);
     355        rc = loc_category_get_id(cat_name, &cat_id, IPC_FLAG_BLOCKING);
    389356        if (rc == EOK) {
    390357                loc_service_add_to_cat(fun->service_id, cat_id);
    391358        } else {
    392359                log_msg(LVL_ERROR, "Failed adding function `%s' to category "
    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);
     360                    "`%s'.", fun->pathname, cat_name);
     361        }
     362       
     363        log_msg(LVL_NOTE, "Function `%s' added to category `%s'.",
     364            fun->pathname, cat_name);
    398365
    399366        async_answer_0(callid, EOK);
     
    449416                        devman_add_function(callid, &call);
    450417                        break;
    451                 case DEVMAN_ADD_DEVICE_TO_CLASS:
    452                         devman_add_function_to_class(callid, &call);
     418                case DEVMAN_ADD_DEVICE_TO_CATEGORY:
     419                        devman_add_function_to_cat(callid, &call);
    453420                        break;
    454421                default:
     
    483450}
    484451
    485 /** Find handle for the device instance identified by device class name. */
    486 static 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 
    519452/** Find device path by its handle. */
    520453static void devman_get_device_path_by_handle(ipc_callid_t iid,
     
    554487}
    555488
     489/** Find handle for the function instance identified by its service ID. */
     490static 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}
    556503
    557504/** Function for handling connections from a client to the device manager. */
     
    572519                        devman_function_get_handle(callid, &call);
    573520                        break;
    574                 case DEVMAN_DEVICE_GET_HANDLE_BY_CLASS:
    575                         devman_function_get_handle_by_class(callid, &call);
    576                         break;
    577521                case DEVMAN_DEVICE_GET_DEVICE_PATH:
    578522                        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);
    579526                        break;
    580527                default:
     
    678625
    679626        fun = find_loc_tree_function(&device_tree, service_id);
    680         if (fun == NULL)
    681                 fun = find_loc_class_function(&class_list, service_id);
    682627       
    683628        if (fun == NULL || fun->dev->drv == NULL) {
     629                log_msg(LVL_WARN, "devman_connection_loc(): function "
     630                    "not found.\n");
    684631                async_answer_0(iid, ENOENT);
    685632                return;
     
    687634       
    688635        dev = fun->dev;
    689        
    690         if ((dev->state != DEVICE_USABLE) || (!dev->drv->sess)) {
    691                 async_answer_0(iid, EINVAL);
    692                 return;
    693         }
    694636       
    695637        async_exch_t *exch = async_exchange_begin(dev->drv->sess);
     
    753695        }
    754696
    755         init_class_list(&class_list);
    756        
    757697        /*
    758698         * !!! devman_connection ... as the device manager is not a real loc
  • uspace/srv/hid/input/generic/input.c

    r1d2a1a9 r0cc32f2  
    6666#include <abi/ipc/methods.h>
    6767
    68 /* In microseconds */
    69 #define DISCOVERY_POLL_INTERVAL  (10 * 1000 * 1000)
    70 
    7168#define NUM_LAYOUTS  3
    7269
     
    497494}
    498495
    499 /** Periodically check for new input devices.
    500  *
    501  * Looks under /loc/class/keyboard and /loc/class/mouse.
    502  *
    503  * @param arg Ignored
    504  *
    505  */
    506 static int dev_discovery_fibril(void *arg)
    507 {
    508         category_id_t keyboard_cat, mouse_cat;
     496static int dev_check_new_kbdevs(void)
     497{
     498        category_id_t keyboard_cat;
    509499        service_id_t *svcs;
    510500        size_t count, i;
     
    518508        }
    519509       
     510        /*
     511         * Check for new keyboard devices
     512         */
     513        rc = loc_category_get_svcs(keyboard_cat, &svcs, &count);
     514        if (rc != EOK) {
     515                printf("%s: Failed getting list of keyboard devices.\n",
     516                    NAME);
     517                return EIO;
     518        }
     519
     520        for (i = 0; i < count; i++) {
     521                already_known = false;
     522               
     523                /* Determine whether we already know this device. */
     524                list_foreach(kbd_devs, kdev_link) {
     525                        kbd_dev_t *kdev = list_get_instance(kdev_link,
     526                            kbd_dev_t, kbd_devs);
     527                        if (kdev->svc_id == svcs[i]) {
     528                                already_known = true;
     529                                break;
     530                        }
     531                }
     532               
     533                if (!already_known) {
     534                        kbd_dev_t *kdev;
     535                        if (kbd_add_kbdev(svcs[i], &kdev) == EOK) {
     536                                printf("%s: Connected keyboard device '%s'\n",
     537                                    NAME, kdev->svc_name);
     538                        }
     539                }
     540        }
     541       
     542        free(svcs);
     543       
     544        /* XXX Handle device removal */
     545       
     546        return EOK;
     547}
     548
     549static int dev_check_new_mousedevs(void)
     550{
     551        category_id_t mouse_cat;
     552        service_id_t *svcs;
     553        size_t count, i;
     554        bool already_known;
     555        int rc;
     556       
    520557        rc = loc_category_get_id("mouse", &mouse_cat, IPC_FLAG_BLOCKING);
    521558        if (rc != EOK) {
     
    524561        }
    525562       
    526         while (true) {
    527                 async_usleep(DISCOVERY_POLL_INTERVAL);
    528                
    529                 /*
    530                  * Check for new keyboard devices
    531                  */
    532                 rc = loc_category_get_svcs(keyboard_cat, &svcs, &count);
    533                 if (rc != EOK) {
    534                         printf("%s: Failed getting list of keyboard devices.\n",
    535                             NAME);
    536                         continue;
    537                 }
    538 
    539                 for (i = 0; i < count; i++) {
    540                         already_known = false;
    541                        
    542                         /* Determine whether we already know this device. */
    543                         list_foreach(kbd_devs, kdev_link) {
    544                                 kbd_dev_t *kdev = list_get_instance(kdev_link,
    545                                     kbd_dev_t, kbd_devs);
    546                                 if (kdev->svc_id == svcs[i]) {
    547                                         already_known = true;
    548                                         break;
    549                                 }
    550                         }
    551 
    552                         if (!already_known) {
    553                                 kbd_dev_t *kdev;
    554                                 if (kbd_add_kbdev(svcs[i], &kdev) == EOK) {
    555                                         printf("%s: Connected keyboard device '%s'\n",
    556                                             NAME, kdev->svc_name);
    557                                 }
     563        /*
     564         * Check for new mouse devices
     565         */
     566        rc = loc_category_get_svcs(mouse_cat, &svcs, &count);
     567        if (rc != EOK) {
     568                printf("%s: Failed getting list of mouse devices.\n",
     569                    NAME);
     570                return EIO;
     571        }
     572       
     573        for (i = 0; i < count; i++) {
     574                already_known = false;
     575               
     576                /* Determine whether we already know this device. */
     577                list_foreach(mouse_devs, mdev_link) {
     578                        mouse_dev_t *mdev = list_get_instance(mdev_link,
     579                            mouse_dev_t, mouse_devs);
     580                        if (mdev->svc_id == svcs[i]) {
     581                                already_known = true;
     582                                break;
    558583                        }
    559584                }
    560585               
    561                 /* XXX Handle device removal */
    562                
    563                 /*
    564                  * Check for new mouse devices
    565                  */
    566                 rc = loc_category_get_svcs(mouse_cat, &svcs, &count);
    567                 if (rc != EOK) {
    568                         printf("%s: Failed getting list of mouse devices.\n",
    569                             NAME);
    570                         continue;
    571                 }
    572 
    573                 for (i = 0; i < count; i++) {
    574                         already_known = false;
    575                        
    576                         /* Determine whether we already know this device. */
    577                         list_foreach(mouse_devs, mdev_link) {
    578                                 mouse_dev_t *mdev = list_get_instance(mdev_link,
    579                                     mouse_dev_t, mouse_devs);
    580                                 if (mdev->svc_id == svcs[i]) {
    581                                         already_known = true;
    582                                         break;
    583                                 }
    584                         }
    585 
    586                         if (!already_known) {
    587                                 mouse_dev_t *mdev;
    588                                 if (mouse_add_mousedev(svcs[i], &mdev) == EOK) {
    589                                         printf("%s: Connected mouse device '%s'\n",
    590                                             NAME, mdev->svc_name);
    591                                 }
     586                if (!already_known) {
     587                        mouse_dev_t *mdev;
     588                        if (mouse_add_mousedev(svcs[i], &mdev) == EOK) {
     589                                printf("%s: Connected mouse device '%s'\n",
     590                                    NAME, mdev->svc_name);
    592591                        }
    593592                }
    594                
    595                 /* XXX Handle device removal */
    596         }
     593        }
     594       
     595        free(svcs);
     596       
     597        /* XXX Handle device removal */
    597598       
    598599        return EOK;
    599600}
    600601
    601 /** Start a fibril for discovering new devices. */
    602 static void input_start_dev_discovery(void)
    603 {
    604         fid_t fid = fibril_create(dev_discovery_fibril, NULL);
    605         if (!fid) {
    606                 printf("%s: Failed to create device discovery fibril.\n",
    607                     NAME);
    608                 return;
    609         }
    610        
    611         fibril_add_ready(fid);
     602static int dev_check_new(void)
     603{
     604        int rc;
     605       
     606        rc = dev_check_new_kbdevs();
     607        if (rc != EOK)
     608                return rc;
     609       
     610        rc = dev_check_new_mousedevs();
     611        if (rc != EOK)
     612                return rc;
     613
     614        return EOK;
     615}
     616
     617static void cat_change_cb(void)
     618{
     619        dev_check_new();
     620}
     621
     622/** Start listening for new devices. */
     623static int input_start_dev_discovery(void)
     624{
     625        int rc;
     626
     627        rc = loc_register_cat_change_cb(cat_change_cb);
     628        if (rc != EOK) {
     629                printf("%s: Failed registering callback for device discovery. "
     630                    "(%d)\n", NAME, rc);
     631                return rc;
     632        }
     633
     634        return dev_check_new();
    612635}
    613636
  • uspace/srv/loc/loc.c

    r1d2a1a9 r0cc32f2  
    8484/** Service directory ogranized by categories (yellow pages) */
    8585static categ_dir_t cdir;
     86
     87static FIBRIL_MUTEX_INITIALIZE(callback_sess_mutex);
     88static async_sess_t *callback_sess = NULL;
    8689
    8790service_id_t loc_create_id(void)
     
    533536}
    534537
     538static void loc_category_get_name(ipc_callid_t iid, ipc_call_t *icall)
     539{
     540        ipc_callid_t callid;
     541        size_t size;
     542        size_t act_size;
     543        category_t *cat;
     544       
     545        if (!async_data_read_receive(&callid, &size)) {
     546                async_answer_0(callid, EREFUSED);
     547                async_answer_0(iid, EREFUSED);
     548                return;
     549        }
     550       
     551        fibril_mutex_lock(&cdir.mutex);
     552       
     553        cat = category_get(&cdir, IPC_GET_ARG1(*icall));
     554        if (cat == NULL) {
     555                fibril_mutex_unlock(&cdir.mutex);
     556                async_answer_0(callid, ENOENT);
     557                async_answer_0(iid, ENOENT);
     558                return;
     559        }
     560       
     561        act_size = str_size(cat->name);
     562        if (act_size > size) {
     563                fibril_mutex_unlock(&cdir.mutex);
     564                async_answer_0(callid, EOVERFLOW);
     565                async_answer_0(iid, EOVERFLOW);
     566                return;
     567        }
     568       
     569        sysarg_t retval = async_data_read_finalize(callid, cat->name,
     570            min(size, act_size));
     571       
     572        fibril_mutex_unlock(&cdir.mutex);
     573       
     574        async_answer_0(iid, retval);
     575}
     576
    535577static void loc_service_get_name(ipc_callid_t iid, ipc_call_t *icall)
    536578{
     
    571613        async_answer_0(iid, retval);
    572614}
    573 
    574615
    575616/** Connect client to the service.
     
    728769 *
    729770 */
     771static void loc_callback_create(ipc_callid_t iid, ipc_call_t *icall)
     772{
     773        async_sess_t *cb_sess = async_callback_receive(EXCHANGE_SERIALIZE);
     774        if (cb_sess == NULL) {
     775                async_answer_0(iid, ENOMEM);
     776                return;
     777        }
     778       
     779        fibril_mutex_lock(&callback_sess_mutex);
     780        if (callback_sess != NULL) {
     781                fibril_mutex_unlock(&callback_sess_mutex);
     782                async_answer_0(iid, EEXIST);
     783                return;
     784        }
     785       
     786        callback_sess = cb_sess;
     787        fibril_mutex_unlock(&callback_sess_mutex);
     788       
     789        async_answer_0(iid, EOK);
     790}
     791
     792void loc_category_change_event(void)
     793{
     794        fibril_mutex_lock(&callback_sess_mutex);
     795
     796        if (callback_sess != NULL) {
     797                async_exch_t *exch = async_exchange_begin(callback_sess);
     798                async_msg_0(exch, LOC_EVENT_CAT_CHANGE);
     799                async_exchange_end(exch);
     800        }
     801
     802        fibril_mutex_unlock(&callback_sess_mutex);
     803}
     804
     805/** Find ID for category specified by name.
     806 *
     807 * On success, answer will contain EOK int retval and service ID in arg1.
     808 * On failure, error code will be sent in retval.
     809 *
     810 */
    730811static void loc_category_get_id(ipc_callid_t iid, ipc_call_t *icall)
    731812{
     
    11291210
    11301211        async_answer_0(iid, retval);
     1212
     1213        loc_category_change_event();
    11311214}
    11321215
     
    11561239
    11571240        cat = category_new("serial");
     1241        categ_dir_add_cat(&cdir, cat);
     1242
     1243        cat = category_new("usbhc");
    11581244        categ_dir_add_cat(&cdir, cat);
    11591245
     
    12441330                        loc_namespace_get_id(callid, &call);
    12451331                        break;
     1332                case LOC_CALLBACK_CREATE:
     1333                        loc_callback_create(callid, &call);
     1334                        break;
    12461335                case LOC_CATEGORY_GET_ID:
    12471336                        loc_category_get_id(callid, &call);
     1337                        break;
     1338                case LOC_CATEGORY_GET_NAME:
     1339                        loc_category_get_name(callid, &call);
    12481340                        break;
    12491341                case LOC_CATEGORY_GET_SVCS:
  • uspace/srv/loc/loc.h

    r1d2a1a9 r0cc32f2  
    102102
    103103extern service_id_t loc_create_id(void);
     104extern void loc_category_change_event(void);
    104105
    105106#endif
Note: See TracChangeset for help on using the changeset viewer.