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


Ignore:
Files:
4 added
41 edited

Legend:

Unmodified
Added
Removed
  • boot/Makefile.common

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

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

    r0cc32f2 r1d2a1a9  
    5050
    5151#define MAX_USB_ADDRESS USB11_ADDRESS_MAX
     52#define MAX_FAILED_ATTEMPTS 10
    5253#define MAX_PATH_LENGTH 1024
    5354
    54 static void print_found_hc(service_id_t sid, const char *path)
     55static void print_found_hc(size_t class_index, const char *path)
    5556{
    56         printf("Bus %" PRIun ": %s\n", sid, path);
     57        // printf(NAME ": host controller %zu is `%s'.\n", class_index, path);
     58        printf("Bus %02zu: %s\n", class_index, path);
    5759}
    5860static void print_found_dev(usb_address_t addr, const char *path)
    5961{
     62        // printf(NAME ":     device with address %d is `%s'.\n", addr, path);
    6063        printf("  Device %02d: %s\n", addr, path);
    6164}
     
    9295int main(int argc, char *argv[])
    9396{
    94         category_id_t usbhc_cat;
    95         service_id_t *svcs;
    96         size_t count;
    97         size_t i;
    98         int rc;
     97        size_t class_index = 0;
     98        size_t failed_attempts = 0;
    9999
    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++) {
     100        while (failed_attempts < MAX_FAILED_ATTEMPTS) {
     101                class_index++;
    114102                devman_handle_t hc_handle = 0;
    115                 int rc = usb_ddf_get_hc_handle_by_sid(svcs[i], &hc_handle);
     103                int rc = usb_ddf_get_hc_handle_by_class(class_index, &hc_handle);
    116104                if (rc != EOK) {
    117                         printf(NAME ": Error resolving handle of HC with SID %"
    118                             PRIun ", skipping.\n", svcs[i]);
     105                        failed_attempts++;
    119106                        continue;
    120107                }
     
    122109                rc = devman_get_device_path(hc_handle, path, MAX_PATH_LENGTH);
    123110                if (rc != EOK) {
    124                         printf(NAME ": Error resolving path of HC with SID %"
    125                             PRIun ", skipping.\n", svcs[i]);
    126111                        continue;
    127112                }
    128                 print_found_hc(svcs[i], path);
     113                print_found_hc(class_index, path);
    129114                print_hc_devices(hc_handle);
    130115        }
    131 
    132         free(svcs);
    133116
    134117        return 0;
  • uspace/app/tester/Makefile

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

    r0cc32f2 r1d2a1a9  
    4949
    5050#define DEVICE_PATH_NORMAL "/loc/devices/\\virt\\null\\a"
     51#define DEVICE_PATH_CLASSES "/loc/class/virt-null\\1"
    5152#define BUFFER_SIZE 64
    5253
     
    104105        }
    105106
     107        res = test_virtchar1_internal(DEVICE_PATH_CLASSES);
     108        if (res != NULL) {
     109                return res;
     110        }
     111
    106112        return NULL;
    107113}
  • uspace/app/tester/tester.c

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

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

    r0cc32f2 r1d2a1a9  
    244244            "Failed to bind OHCI device function: %s.\n", str_error(ret));
    245245
    246         ret = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY);
     246        ret = ddf_fun_add_to_class(instance->hc_fun, USB_HC_DDF_CLASS_NAME);
    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

    r0cc32f2 r1d2a1a9  
    267267            str_error(ret));
    268268
    269         ret = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY);
     269        ret = ddf_fun_add_to_class(instance->hc_fun, USB_HC_DDF_CLASS_NAME);
    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

    r0cc32f2 r1d2a1a9  
    102102
    103103const char *HID_KBD_FUN_NAME = "keyboard";
    104 const char *HID_KBD_CATEGORY_NAME = "keyboard";
     104const char *HID_KBD_CLASS_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 category %s...\n",
     553        usb_log_debug("Adding DDF function to class %s...\n",
    554554            HID_KBD_CLASS_NAME);
    555         rc = ddf_fun_add_to_category(fun, HID_KBD_CATEGORY_NAME);
     555        rc = ddf_fun_add_to_class(fun, HID_KBD_CLASS_NAME);
    556556        if (rc != EOK) {
    557557                usb_log_error(
    558                     "Could not add DDF function to category %s: %s.\n",
     558                    "Could not add DDF function to class %s: %s.\n",
    559559                    HID_KBD_CLASS_NAME, str_error(rc));
    560560                ddf_fun_destroy(fun);
  • uspace/drv/bus/usb/usbhid/mouse/mousedev.c

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

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

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

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

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

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

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

    r0cc32f2 r1d2a1a9  
    143143        }
    144144
    145         ddf_fun_add_to_category(fun_a, "virtual");
     145        ddf_fun_add_to_class(fun_a, "virtual");
    146146
    147147        if (str_cmp(dev->name, "null") == 0) {
    148148                fun_a->ops = &char_device_ops;
    149                 ddf_fun_add_to_category(fun_a, "virt-null");
     149                ddf_fun_add_to_class(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

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

    r0cc32f2 r1d2a1a9  
    5050};
    5151
    52 static int register_fun_and_add_to_category(ddf_dev_t *parent,
     52static int register_fun_and_add_to_class(ddf_dev_t *parent,
    5353     const char *base_name, size_t index, const char *class_name)
    5454{
     
    7777        }
    7878       
    79         ddf_fun_add_to_category(fun, class_name);
     79        ddf_fun_add_to_class(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_category(dev,
     102                rc = register_fun_and_add_to_class(dev,
    103103                    "test3_", i, "test3");
    104104                if (rc != EOK) {
  • uspace/lib/c/generic/devman.c

    r0cc32f2 r1d2a1a9  
    271271}
    272272
    273 int devman_add_device_to_category(devman_handle_t devman_handle,
    274     const char *cat_name)
     273int devman_add_device_to_class(devman_handle_t devman_handle,
     274    const char *class_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_CATEGORY,
     279        aid_t req = async_send_1(exch, DEVMAN_ADD_DEVICE_TO_CLASS,
    280280            devman_handle, &answer);
    281         sysarg_t retval = async_data_write_start(exch, cat_name,
    282             str_size(cat_name));
     281        sysarg_t retval = async_data_write_start(exch, class_name,
     282            str_size(class_name));
    283283       
    284284        devman_exchange_end(exch);
     
    333333                exch = devman_exchange_begin(DEVMAN_CLIENT);
    334334                if (exch == NULL)
    335                         return ENOMEM;
     335                        return errno;
    336336        }
    337337       
     
    364364}
    365365
     366int 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
    366416int devman_get_device_path(devman_handle_t handle, char *path, size_t path_size)
    367417{
    368418        async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT);
    369419        if (exch == NULL)
    370                 return ENOMEM;
     420                return errno;
    371421       
    372422        ipc_call_t answer;
     
    413463}
    414464
    415 int 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 
    428465/** @}
    429466 */
  • uspace/lib/c/generic/loc.c

    r0cc32f2 r1d2a1a9  
    4545static FIBRIL_MUTEX_INITIALIZE(loc_consumer_mutex);
    4646
    47 static FIBRIL_MUTEX_INITIALIZE(loc_callback_mutex);
    48 static bool loc_callback_created = false;
    49 
    5047static async_sess_t *loc_supp_block_sess = NULL;
    5148static async_sess_t *loc_cons_block_sess = NULL;
     
    5451static async_sess_t *loc_consumer_sess = NULL;
    5552
    56 static loc_cat_change_cb_t cat_change_cb = NULL;
    57 
    58 static 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 
    9253static void clone_session(fibril_mutex_t *mtx, async_sess_t *src,
    9354    async_sess_t **dst)
     
    9960       
    10061        fibril_mutex_unlock(mtx);
    101 }
    102 
    103 static 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;
    132 done:
    133         fibril_mutex_unlock(&loc_callback_mutex);
    134         return rc;
    13562}
    13663
     
    364291}
    365292
    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
     293/** Get service name.
     294 *
     295 * Provided ID of a service, return its name.
     296 *
     297 * @param svc_id        Service ID
    372298 * @param name          Place to store pointer to new string. Caller should
    373299 *                      free it using free().
    374300 * @return              EOK on success or negative error code
    375301 */
    376 static int loc_get_name_internal(sysarg_t method, sysarg_t id, char **name)
     302int loc_service_get_name(service_id_t svc_id, char **name)
    377303{
    378304        async_exch_t *exch;
     
    386312       
    387313        ipc_call_t answer;
    388         aid_t req = async_send_1(exch, method, id, &answer);
     314        aid_t req = async_send_1(exch, LOC_SERVICE_GET_NAME, svc_id, &answer);
    389315        aid_t dreq = async_data_read(exch, name_buf, LOC_NAME_MAXLEN,
    390316            &dreply);
     
    415341}
    416342
    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  */
    426 int 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  */
    440 int 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 }
    444343
    445344int loc_namespace_get_id(const char *name, service_id_t *handle,
     
    850749            data, count);
    851750}
    852 
    853 int 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

    r0cc32f2 r1d2a1a9  
    3838
    3939#include <ipc/devman.h>
    40 #include <ipc/loc.h>
    4140#include <async.h>
    4241#include <bool.h>
     
    5756extern int devman_device_get_handle(const char *, devman_handle_t *,
    5857    unsigned int);
     58extern int devman_device_get_handle_by_class(const char *, const char *,
     59    devman_handle_t *, unsigned int);
    5960extern int devman_get_device_path(devman_handle_t, char *, size_t);
    6061
    61 extern int devman_add_device_to_category(devman_handle_t, const char *);
    62 extern int devman_fun_sid_to_handle(service_id_t, devman_handle_t *);
     62extern int devman_add_device_to_class(devman_handle_t, const char *);
    6363
    6464#endif
  • uspace/lib/c/include/ipc/devman.h

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

    r0cc32f2 r1d2a1a9  
    5757        LOC_SERVICE_GET_NAME,
    5858        LOC_NAMESPACE_GET_ID,
    59         LOC_CALLBACK_CREATE,
    6059        LOC_CATEGORY_GET_ID,
    61         LOC_CATEGORY_GET_NAME,
    6260        LOC_CATEGORY_GET_SVCS,
    6361        LOC_ID_PROBE,
     
    7068        LOC_GET_SERVICES
    7169} loc_request_t;
    72 
    73 typedef enum {
    74         LOC_EVENT_CAT_CHANGE = IPC_FIRST_USER_METHOD
    75 } loc_event_t;
    7670
    7771/** Ports provided by location service.
  • uspace/lib/c/include/loc.h

    r0cc32f2 r1d2a1a9  
    4040#include <bool.h>
    4141
    42 typedef void (*loc_cat_change_cb_t)(void);
    43 
    4442extern async_exch_t *loc_exchange_begin_blocking(loc_interface_t);
    4543extern async_exch_t *loc_exchange_begin(loc_interface_t);
     
    7573extern size_t loc_get_services(service_id_t, loc_sdesc_t **);
    7674extern int loc_get_categories(category_id_t **, size_t *);
    77 extern int loc_register_cat_change_cb(loc_cat_change_cb_t);
    7875
    7976
  • uspace/lib/drv/generic/driver.c

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

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

    r0cc32f2 r1d2a1a9  
    5151
    5252/**
    53  * Retrieve next broken-down entry from the user database.
    54  *
    5553 * Since HelenOS doesn't have user accounts, this always returns
    5654 * the same made-up entry.
    5755 *
    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.
     56 * @return
    6057 */
    6158struct posix_passwd *posix_getpwent(void)
     
    7067
    7168/**
    72  * Rewind the user list.
     69 * "Rewind the user list".
    7370 */
    7471void posix_setpwent(void)
     
    8986 *
    9087 * @param name Name of the entry.
    91  * @return Either found entry or NULL if no such entry exists.
     88 * @return
    9289 */
    9390struct posix_passwd *posix_getpwnam(const char *name)
     
    106103 *
    107104 * @param name Name of the entry.
    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.
     105 * @param pwd
     106 * @param buffer
     107 * @param bufsize
     108 * @param result
     109 * @return
    114110 */
    115111int posix_getpwnam_r(const char *name, struct posix_passwd *pwd,
     
    133129 *
    134130 * @param uid UID of the entry.
    135  * @return Either found entry or NULL if no such entry exists.
     131 * @return
    136132 */
    137133struct posix_passwd *posix_getpwuid(posix_uid_t uid)
     
    148144 *
    149145 * @param uid UID of the entry.
    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.
     146 * @param pwd
     147 * @param buffer
     148 * @param bufsize
     149 * @param result
     150 * @return
    156151 */
    157152int posix_getpwuid_r(posix_uid_t uid, struct posix_passwd *pwd,
  • uspace/lib/posix/string.c

    r0cc32f2 r1d2a1a9  
    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 */
     56static 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/**
    5068 * The same as strpbrk, except it returns pointer to the nul terminator
    5169 * if no occurence is found.
     
    453471
    454472/**
    455  * Find a substring. Uses Knuth-Morris-Pratt algorithm.
     473 * Find a substring.
    456474 *
    457475 * @param s1 String in which to look for a substring.
     
    460478 *     not found.
    461479 */
    462 char *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;
     480char *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                }
    479496               
    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                 }
     497                s1++;
    506498        }
    507499       
  • uspace/lib/posix/string.h

    r0cc32f2 r1d2a1a9  
    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 *haystack, const char *needle);
     88extern char *posix_strstr(const char *s1, const char *s2);
    8989
    9090/* Collation Functions */
  • uspace/lib/usb/include/usb/hc.h

    r0cc32f2 r1d2a1a9  
    3838#include <sys/types.h>
    3939#include <ipc/devman.h>
    40 #include <ipc/loc.h>
    4140#include <ddf/driver.h>
    4241#include <bool.h>
     
    6968    devman_handle_t *);
    7069
    71 int usb_ddf_get_hc_handle_by_sid(service_id_t, devman_handle_t *);
     70int usb_ddf_get_hc_handle_by_class(size_t, devman_handle_t *);
    7271
    7372
  • uspace/lib/usb/include/usb/usb.h

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

    r0cc32f2 r1d2a1a9  
    201201/** Get host controller handle by its class index.
    202202 *
    203  * @param sid Service ID of the HC function.
     203 * @param class_index Class index for the host controller.
    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_sid(service_id_t sid, devman_handle_t *hc_handle)
    209 {
    210         devman_handle_t handle;
     208int 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;
    211213        int rc;
    212        
    213         rc = devman_fun_sid_to_handle(sid, &handle);
    214         if (hc_handle != NULL)
    215                 *hc_handle = handle;
    216        
    217         return 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;
    218231}
    219232
  • uspace/lib/usb/src/resolve.c

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

    r0cc32f2 r1d2a1a9  
    7373}
    7474
     75static 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
    7585static void devices_remove_callback(link_t *item)
    7686{
     
    92102        .hash = devices_hash,
    93103        .compare = loc_functions_compare,
     104        .remove_callback = devices_remove_callback
     105};
     106
     107static hash_table_operations_t loc_devices_class_ops = {
     108        .hash = devices_hash,
     109        .compare = loc_devices_class_compare,
    94110        .remove_callback = devices_remove_callback
    95111};
     
    934950                link_initialize(&res->dev_functions);
    935951                list_initialize(&res->match_ids.ids);
     952                list_initialize(&res->classes);
    936953                link_initialize(&res->devman_fun);
    937954                link_initialize(&res->loc_fun);
     
    11761193}
    11771194
     1195/** Find function node by its class name and index. */
     1196fun_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
    11781225/** Find child function node with a specified name.
    11791226 *
     
    11881235        return find_fun_node_in_device(pfun->child, name);
    11891236}
     1237
     1238/* Device classes */
     1239
     1240/** Create device class.
     1241 *
     1242 * @return      Device class.
     1243 */
     1244dev_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 */
     1262dev_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
     1277size_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 */
     1297char *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 */
     1326dev_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
     1356dev_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
     1375dev_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
     1390void 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
     1395dev_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
     1412void 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
    11901420
    11911421/* loc devices */
     
    12061436}
    12071437
     1438fun_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
     1458void 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
    12081469void tree_add_loc_function(dev_tree_t *tree, fun_node_t *fun)
    12091470{
  • uspace/srv/devman/devman.h

    r0cc32f2 r1d2a1a9  
    5353#define DEVICE_BUCKETS 256
    5454
     55#define LOC_CLASS_NAMESPACE "class"
    5556#define LOC_DEVICE_NAMESPACE "devices"
    5657#define LOC_SEPARATOR '\\'
     
    169170        match_id_list_t match_ids;
    170171       
     172        /** List of device classes to which this device function belongs. */
     173        list_t classes;
    171174        /** Service ID if the device function is registered with loc. */
    172175        service_id_t service_id;
     
    210213        hash_table_t loc_functions;
    211214} dev_tree_t;
     215
     216typedef 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 */
     249typedef 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. */
     280typedef 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;
    212293
    213294/* Match ids and scores */
     
    258339extern fun_node_t *find_fun_node_by_path(dev_tree_t *, char *);
    259340extern 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 *);
    260342
    261343/* Device tree */
     
    266348extern bool insert_fun_node(dev_tree_t *, fun_node_t *, char *, dev_node_t *);
    267349
     350/* Device classes */
     351
     352extern dev_class_t *create_dev_class(void);
     353extern dev_class_info_t *create_dev_class_info(void);
     354extern size_t get_new_class_dev_idx(dev_class_t *);
     355extern char *create_dev_name_for_class(dev_class_t *, const char *);
     356extern dev_class_info_t *add_function_to_class(fun_node_t *, dev_class_t *,
     357    const char *);
     358
     359extern void init_class_list(class_list_t *);
     360
     361extern dev_class_t *get_dev_class(class_list_t *, char *);
     362extern 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 *);
     364extern void add_dev_class_no_lock(class_list_t *, dev_class_t *);
     365
    268366/* Loc services */
    269367
     
    271369
    272370extern fun_node_t *find_loc_tree_function(dev_tree_t *, service_id_t);
    273 
     371extern fun_node_t *find_loc_class_function(class_list_t *, service_id_t);
     372
     373extern void class_add_loc_function(class_list_t *, dev_class_info_t *);
    274374extern void tree_add_loc_function(dev_tree_t *, fun_node_t *);
    275375
  • uspace/srv/devman/main.c

    r0cc32f2 r1d2a1a9  
    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
  • uspace/srv/hid/input/generic/input.c

    r0cc32f2 r1d2a1a9  
    6666#include <abi/ipc/methods.h>
    6767
     68/* In microseconds */
     69#define DISCOVERY_POLL_INTERVAL  (10 * 1000 * 1000)
     70
    6871#define NUM_LAYOUTS  3
    6972
     
    494497}
    495498
    496 static int dev_check_new_kbdevs(void)
    497 {
    498         category_id_t keyboard_cat;
     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 */
     506static int dev_discovery_fibril(void *arg)
     507{
     508        category_id_t keyboard_cat, mouse_cat;
    499509        service_id_t *svcs;
    500510        size_t count, i;
     
    508518        }
    509519       
    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 
    549 static 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        
    557520        rc = loc_category_get_id("mouse", &mouse_cat, IPC_FLAG_BLOCKING);
    558521        if (rc != EOK) {
     
    561524        }
    562525       
    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;
     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                                }
    583558                        }
    584559                }
    585560               
    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);
     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                                }
    591592                        }
    592593                }
    593         }
    594        
    595         free(svcs);
    596        
    597         /* XXX Handle device removal */
     594               
     595                /* XXX Handle device removal */
     596        }
    598597       
    599598        return EOK;
    600599}
    601600
    602 static 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 
    617 static void cat_change_cb(void)
    618 {
    619         dev_check_new();
    620 }
    621 
    622 /** Start listening for new devices. */
    623 static 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();
     601/** Start a fibril for discovering new devices. */
     602static 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);
    635612}
    636613
  • uspace/srv/loc/loc.c

    r0cc32f2 r1d2a1a9  
    8484/** Service directory ogranized by categories (yellow pages) */
    8585static categ_dir_t cdir;
    86 
    87 static FIBRIL_MUTEX_INITIALIZE(callback_sess_mutex);
    88 static async_sess_t *callback_sess = NULL;
    8986
    9087service_id_t loc_create_id(void)
     
    536533}
    537534
    538 static 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 
    577535static void loc_service_get_name(ipc_callid_t iid, ipc_call_t *icall)
    578536{
     
    613571        async_answer_0(iid, retval);
    614572}
     573
    615574
    616575/** Connect client to the service.
     
    769728 *
    770729 */
    771 static 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 
    792 void 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  */
    811730static void loc_category_get_id(ipc_callid_t iid, ipc_call_t *icall)
    812731{
     
    12101129
    12111130        async_answer_0(iid, retval);
    1212 
    1213         loc_category_change_event();
    12141131}
    12151132
     
    12391156
    12401157        cat = category_new("serial");
    1241         categ_dir_add_cat(&cdir, cat);
    1242 
    1243         cat = category_new("usbhc");
    12441158        categ_dir_add_cat(&cdir, cat);
    12451159
     
    13301244                        loc_namespace_get_id(callid, &call);
    13311245                        break;
    1332                 case LOC_CALLBACK_CREATE:
    1333                         loc_callback_create(callid, &call);
    1334                         break;
    13351246                case LOC_CATEGORY_GET_ID:
    13361247                        loc_category_get_id(callid, &call);
    1337                         break;
    1338                 case LOC_CATEGORY_GET_NAME:
    1339                         loc_category_get_name(callid, &call);
    13401248                        break;
    13411249                case LOC_CATEGORY_GET_SVCS:
  • uspace/srv/loc/loc.h

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