Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 12f9f0d0 in mainline


Ignore:
Timestamp:
2011-08-17T13:39:53Z (10 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master
Children:
e280857
Parents:
45058baa
Message:

Notifications on changes in loc categories. Limitations:

  • cannot specify single category to watch
  • max one task can register notifications with loc service
  • max one user callback function can be registered with C library

Remove devman tests as they are not applicable anymore.

Location:
uspace
Files:
4 deleted
10 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/tester/Makefile

    r45058baa r12f9f0d0  
    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

    r45058baa r12f9f0d0  
    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

    r45058baa r12f9f0d0  
    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/lib/c/generic/loc.c

    r45058baa r12f9f0d0  
    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
     
    749822            data, count);
    750823}
     824
     825int loc_register_cat_change_cb(loc_cat_change_cb_t cb_fun)
     826{
     827        if (loc_callback_create() != EOK)
     828                return EIO;
     829
     830        cat_change_cb = cb_fun;
     831        return EOK;
     832}
  • uspace/lib/c/include/ipc/loc.h

    r45058baa r12f9f0d0  
    5757        LOC_SERVICE_GET_NAME,
    5858        LOC_NAMESPACE_GET_ID,
     59        LOC_CALLBACK_CREATE,
    5960        LOC_CATEGORY_GET_ID,
    6061        LOC_CATEGORY_GET_SVCS,
     
    6869        LOC_GET_SERVICES
    6970} loc_request_t;
     71
     72typedef enum {
     73        LOC_EVENT_CAT_CHANGE = IPC_FIRST_USER_METHOD
     74} loc_event_t;
    7075
    7176/** Ports provided by location service.
  • uspace/lib/c/include/loc.h

    r45058baa r12f9f0d0  
    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/srv/devman/main.c

    r45058baa r12f9f0d0  
    682682       
    683683        if (fun == NULL || fun->dev->drv == NULL) {
     684                log_msg(LVL_WARN, "devman_connection_loc(): function "
     685                    "not found.\n");
    684686                async_answer_0(iid, ENOENT);
    685687                return;
     
    687689       
    688690        dev = fun->dev;
    689        
    690         if ((dev->state != DEVICE_USABLE) || (!dev->drv->sess)) {
    691                 async_answer_0(iid, EINVAL);
    692                 return;
    693         }
    694691       
    695692        async_exch_t *exch = async_exchange_begin(dev->drv->sess);
  • uspace/srv/hid/input/generic/input.c

    r45058baa r12f9f0d0  
    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        /* XXX Handle device removal */
     543       
     544        return EOK;
     545}
     546
     547static int dev_check_new_mousedevs(void)
     548{
     549        category_id_t mouse_cat;
     550        service_id_t *svcs;
     551        size_t count, i;
     552        bool already_known;
     553        int rc;
     554       
    520555        rc = loc_category_get_id("mouse", &mouse_cat, IPC_FLAG_BLOCKING);
    521556        if (rc != EOK) {
     
    524559        }
    525560       
    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                                 }
     561        /*
     562         * Check for new mouse devices
     563         */
     564        rc = loc_category_get_svcs(mouse_cat, &svcs, &count);
     565        if (rc != EOK) {
     566                printf("%s: Failed getting list of mouse devices.\n",
     567                    NAME);
     568                return EIO;
     569        }
     570       
     571        for (i = 0; i < count; i++) {
     572                already_known = false;
     573               
     574                /* Determine whether we already know this device. */
     575                list_foreach(mouse_devs, mdev_link) {
     576                        mouse_dev_t *mdev = list_get_instance(mdev_link,
     577                            mouse_dev_t, mouse_devs);
     578                        if (mdev->svc_id == svcs[i]) {
     579                                already_known = true;
     580                                break;
    558581                        }
    559582                }
    560583               
    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                                 }
     584                if (!already_known) {
     585                        mouse_dev_t *mdev;
     586                        if (mouse_add_mousedev(svcs[i], &mdev) == EOK) {
     587                                printf("%s: Connected mouse device '%s'\n",
     588                                    NAME, mdev->svc_name);
    592589                        }
    593590                }
    594                
    595                 /* XXX Handle device removal */
    596         }
     591        }
     592       
     593        /* XXX Handle device removal */
    597594       
    598595        return EOK;
    599596}
    600597
    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);
     598static int dev_check_new(void)
     599{
     600        int rc;
     601       
     602        rc = dev_check_new_kbdevs();
     603        if (rc != EOK)
     604                return rc;
     605       
     606        rc = dev_check_new_mousedevs();
     607        if (rc != EOK)
     608                return rc;
     609
     610        return EOK;
     611}
     612
     613static void cat_change_cb(void)
     614{
     615        dev_check_new();
     616}
     617
     618/** Start listening for new devices. */
     619static int input_start_dev_discovery(void)
     620{
     621        int rc;
     622
     623        rc = loc_register_cat_change_cb(cat_change_cb);
     624        if (rc != EOK) {
     625                printf("%s: Failed registering callback for device discovery. "
     626                    "(%d)\n", NAME, rc);
     627                return rc;
     628        }
     629
     630        return dev_check_new();
    612631}
    613632
  • uspace/srv/loc/loc.c

    r45058baa r12f9f0d0  
    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)
     
    728731 *
    729732 */
     733static void loc_callback_create(ipc_callid_t iid, ipc_call_t *icall)
     734{
     735        async_sess_t *cb_sess = async_callback_receive(EXCHANGE_SERIALIZE);
     736        if (cb_sess == NULL) {
     737                async_answer_0(iid, ENOMEM);
     738                return;
     739        }
     740       
     741        fibril_mutex_lock(&callback_sess_mutex);
     742        if (callback_sess != NULL) {
     743                fibril_mutex_unlock(&callback_sess_mutex);
     744                async_answer_0(iid, EEXIST);
     745                return;
     746        }
     747       
     748        callback_sess = cb_sess;
     749        fibril_mutex_unlock(&callback_sess_mutex);
     750       
     751        async_answer_0(iid, EOK);
     752}
     753
     754void loc_category_change_event(void)
     755{
     756        fibril_mutex_lock(&callback_sess_mutex);
     757
     758        if (callback_sess != NULL) {
     759                async_exch_t *exch = async_exchange_begin(callback_sess);
     760                async_msg_0(exch, LOC_EVENT_CAT_CHANGE);
     761                async_exchange_end(exch);
     762        }
     763
     764        fibril_mutex_unlock(&callback_sess_mutex);
     765}
     766
     767/** Find ID for category specified by name.
     768 *
     769 * On success, answer will contain EOK int retval and service ID in arg1.
     770 * On failure, error code will be sent in retval.
     771 *
     772 */
    730773static void loc_category_get_id(ipc_callid_t iid, ipc_call_t *icall)
    731774{
     
    11291172
    11301173        async_answer_0(iid, retval);
     1174
     1175        loc_category_change_event();
    11311176}
    11321177
     
    12431288                case LOC_NAMESPACE_GET_ID:
    12441289                        loc_namespace_get_id(callid, &call);
     1290                        break;
     1291                case LOC_CALLBACK_CREATE:
     1292                        loc_callback_create(callid, &call);
    12451293                        break;
    12461294                case LOC_CATEGORY_GET_ID:
  • uspace/srv/loc/loc.h

    r45058baa r12f9f0d0  
    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.