Changeset 925a21e in mainline for uspace/srv/hid/input/generic/input.c


Ignore:
Timestamp:
2011-09-24T14:20:29Z (13 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
5bf76c1
Parents:
867e2555 (diff), 1ab4aca (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/hid/input/generic/input.c

    r867e2555 r925a21e  
    3838
    3939#include <adt/list.h>
     40#include <bool.h>
    4041#include <ipc/services.h>
    4142#include <ipc/input.h>
     
    4647#include <stdio.h>
    4748#include <ns.h>
    48 #include <ns_obsolete.h>
    4949#include <async.h>
    50 #include <async_obsolete.h>
    5150#include <errno.h>
    5251#include <adt/fifo.h>
    5352#include <io/console.h>
    5453#include <io/keycode.h>
    55 #include <devmap.h>
     54#include <loc.h>
    5655#include <input.h>
    5756#include <kbd.h>
     
    6261#include <mouse.h>
    6362
    64 // FIXME: remove this header
    65 #include <kernel/ipc/ipc_methods.h>
    66 
    67 /* In microseconds */
    68 #define DISCOVERY_POLL_INTERVAL  (10 * 1000 * 1000)
    69 
    7063#define NUM_LAYOUTS  3
    7164
     
    7972static void kbd_devs_reclaim(void);
    8073
    81 int client_phone = -1;
     74async_sess_t *client_sess = NULL;
    8275
    8376/** List of keyboard devices */
     
    8881
    8982bool irc_service = false;
    90 int irc_phone = -1;
     83async_sess_t *irc_sess = NULL;
    9184
    9285void kbd_push_data(kbd_dev_t *kdev, sysarg_t data)
     
    172165       
    173166        ev.c = layout_parse_ev(kdev->active_layout, &ev);
    174         async_obsolete_msg_4(client_phone, INPUT_EVENT_KEY, ev.type, ev.key,
    175             ev.mods, ev.c);
     167       
     168        async_exch_t *exch = async_exchange_begin(client_sess);
     169        async_msg_4(exch, INPUT_EVENT_KEY, ev.type, ev.key, ev.mods, ev.c);
     170        async_exchange_end(exch);
    176171}
    177172
     
    179174void mouse_push_event_move(mouse_dev_t *mdev, int dx, int dy)
    180175{
    181         async_obsolete_msg_2(client_phone, INPUT_EVENT_MOVE, dx, dy);
     176        async_exch_t *exch = async_exchange_begin(client_sess);
     177        async_msg_2(exch, INPUT_EVENT_MOVE, dx, dy);
     178        async_exchange_end(exch);
    182179}
    183180
     
    185182void mouse_push_event_button(mouse_dev_t *mdev, int bnum, int press)
    186183{
    187         async_obsolete_msg_2(client_phone, INPUT_EVENT_BUTTON, bnum, press);
     184        async_exch_t *exch = async_exchange_begin(client_sess);
     185        async_msg_2(exch, INPUT_EVENT_BUTTON, bnum, press);
     186        async_exchange_end(exch);
    188187}
    189188
    190189static void client_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    191190{
    192         ipc_callid_t callid;
    193         ipc_call_t call;
    194         int retval;
    195        
    196191        async_answer_0(iid, EOK);
    197192       
    198193        while (true) {
    199                 callid = async_get_call(&call);
     194                ipc_call_t call;
     195                ipc_callid_t callid = async_get_call(&call);
    200196               
    201197                if (!IPC_GET_IMETHOD(call)) {
    202                         if (client_phone != -1) {
    203                                 async_obsolete_hangup(client_phone);
    204                                 client_phone = -1;
     198                        if (client_sess != NULL) {
     199                                async_hangup(client_sess);
     200                                client_sess = NULL;
    205201                        }
    206202                       
     
    209205                }
    210206               
    211                 switch (IPC_GET_IMETHOD(call)) {
    212                 case IPC_M_CONNECT_TO_ME:
    213                         if (client_phone != -1) {
    214                                 retval = ELIMIT;
     207                async_sess_t *sess =
     208                    async_callback_receive_start(EXCHANGE_SERIALIZE, &call);
     209                if (sess != NULL) {
     210                        if (client_sess == NULL) {
     211                                client_sess = sess;
     212                                async_answer_0(callid, EOK);
     213                        } else
     214                                async_answer_0(callid, ELIMIT);
     215                } else {
     216                        switch (IPC_GET_IMETHOD(call)) {
     217                        case INPUT_YIELD:
     218                                kbd_devs_yield();
     219                                async_answer_0(callid, EOK);
    215220                                break;
     221                        case INPUT_RECLAIM:
     222                                kbd_devs_reclaim();
     223                                async_answer_0(callid, EOK);
     224                                break;
     225                        default:
     226                                async_answer_0(callid, EINVAL);
    216227                        }
    217                         client_phone = IPC_GET_ARG5(call);
    218                         retval = 0;
    219                         break;
    220                 case INPUT_YIELD:
    221                         kbd_devs_yield();
    222                         retval = 0;
    223                         break;
    224                 case INPUT_RECLAIM:
    225                         kbd_devs_reclaim();
    226                         retval = 0;
    227                         break;
    228                 default:
    229                         retval = EINVAL;
    230228                }
    231                
    232                 async_answer_0(callid, retval);
    233229        }
    234230}
     
    275271        kdev->port_ops = port;
    276272        kdev->ctl_ops = ctl;
    277         kdev->dev_path = NULL;
     273        kdev->svc_id = 0;
    278274       
    279275        /* Initialize port driver. */
     
    303299        mdev->port_ops = port;
    304300        mdev->proto_ops = proto;
    305         mdev->dev_path = NULL;
     301        mdev->svc_id = 0;
    306302       
    307303        /* Initialize port driver. */
     
    324320/** Add new kbdev device.
    325321 *
    326  * @param dev_path Filesystem path to the device (/dev/class/...)
     322 * @param service_id    Service ID of the keyboard device
    327323 *
    328324 */
    329 static int kbd_add_kbdev(const char *dev_path)
     325static int kbd_add_kbdev(service_id_t service_id, kbd_dev_t **kdevp)
    330326{
    331327        kbd_dev_t *kdev = kbd_dev_new();
     
    333329                return -1;
    334330       
    335         kdev->dev_path = dev_path;
     331        kdev->svc_id = service_id;
    336332        kdev->port_ops = NULL;
    337333        kdev->ctl_ops = &kbdev_ctl;
    338334       
     335        int rc = loc_service_get_name(service_id, &kdev->svc_name);
     336        if (rc != EOK) {
     337                kdev->svc_name = NULL;
     338                goto fail;
     339        }
     340       
    339341        /* Initialize controller driver. */
    340342        if ((*kdev->ctl_ops->init)(kdev) != 0) {
     
    343345       
    344346        list_append(&kdev->kbd_devs, &kbd_devs);
     347        *kdevp = kdev;
    345348        return EOK;
    346349       
    347350fail:
     351        if (kdev->svc_name != NULL)
     352                free(kdev->svc_name);
    348353        free(kdev);
    349354        return -1;
     
    352357/** Add new mousedev device.
    353358 *
    354  * @param dev_path Filesystem path to the device (/dev/class/...)
     359 * @param service_id    Service ID of the mouse device
    355360 *
    356361 */
    357 static int mouse_add_mousedev(const char *dev_path)
     362static int mouse_add_mousedev(service_id_t service_id, mouse_dev_t **mdevp)
    358363{
    359364        mouse_dev_t *mdev = mouse_dev_new();
     
    361366                return -1;
    362367       
    363         mdev->dev_path = dev_path;
     368        mdev->svc_id = service_id;
    364369        mdev->port_ops = NULL;
    365370        mdev->proto_ops = &mousedev_proto;
    366371       
     372        int rc = loc_service_get_name(service_id, &mdev->svc_name);
     373        if (rc != EOK) {
     374                mdev->svc_name = NULL;
     375                goto fail;
     376        }
     377       
    367378        /* Initialize controller driver. */
    368379        if ((*mdev->proto_ops->init)(mdev) != 0) {
     
    371382       
    372383        list_append(&mdev->mouse_devs, &mouse_devs);
     384        *mdevp = mdev;
    373385        return EOK;
    374386       
     
    480492}
    481493
    482 /** Periodically check for new input devices.
    483  *
    484  * Looks under /dev/class/keyboard and /dev/class/mouse.
    485  *
    486  * @param arg Ignored
    487  *
    488  */
    489 static int dev_discovery_fibril(void *arg)
    490 {
    491         char *dev_path;
    492         size_t kbd_id = 1;
    493         size_t mouse_id = 1;
     494static int dev_check_new_kbdevs(void)
     495{
     496        category_id_t keyboard_cat;
     497        service_id_t *svcs;
     498        size_t count, i;
     499        bool already_known;
    494500        int rc;
    495501       
    496         while (true) {
    497                 async_usleep(DISCOVERY_POLL_INTERVAL);
    498                
    499                 /*
    500                  * Check for new keyboard device
    501                  */
    502                 rc = asprintf(&dev_path, "/dev/class/keyboard\\%zu", kbd_id);
    503                 if (rc < 0)
    504                         continue;
    505                
    506                 if (kbd_add_kbdev(dev_path) == EOK) {
    507                         printf("%s: Connected keyboard device '%s'\n",
    508                             NAME, dev_path);
    509                        
    510                         /* XXX Handle device removal */
    511                         ++kbd_id;
     502        rc = loc_category_get_id("keyboard", &keyboard_cat, IPC_FLAG_BLOCKING);
     503        if (rc != EOK) {
     504                printf("%s: Failed resolving category 'keyboard'.\n", NAME);
     505                return ENOENT;
     506        }
     507       
     508        /*
     509         * Check for new keyboard devices
     510         */
     511        rc = loc_category_get_svcs(keyboard_cat, &svcs, &count);
     512        if (rc != EOK) {
     513                printf("%s: Failed getting list of keyboard devices.\n",
     514                    NAME);
     515                return EIO;
     516        }
     517
     518        for (i = 0; i < count; i++) {
     519                already_known = false;
     520               
     521                /* Determine whether we already know this device. */
     522                list_foreach(kbd_devs, kdev_link) {
     523                        kbd_dev_t *kdev = list_get_instance(kdev_link,
     524                            kbd_dev_t, kbd_devs);
     525                        if (kdev->svc_id == svcs[i]) {
     526                                already_known = true;
     527                                break;
     528                        }
    512529                }
    513530               
    514                 free(dev_path);
    515                
    516                 /*
    517                  * Check for new mouse device
    518                  */
    519                 rc = asprintf(&dev_path, "/dev/class/mouse\\%zu", mouse_id);
    520                 if (rc < 0)
    521                         continue;
    522                
    523                 if (mouse_add_mousedev(dev_path) == EOK) {
    524                         printf("%s: Connected mouse device '%s'\n",
    525                             NAME, dev_path);
    526                        
    527                         /* XXX Handle device removal */
    528                         ++mouse_id;
     531                if (!already_known) {
     532                        kbd_dev_t *kdev;
     533                        if (kbd_add_kbdev(svcs[i], &kdev) == EOK) {
     534                                printf("%s: Connected keyboard device '%s'\n",
     535                                    NAME, kdev->svc_name);
     536                        }
    529537                }
    530                
    531                 free(dev_path);
    532         }
     538        }
     539       
     540        free(svcs);
     541       
     542        /* XXX Handle device removal */
    533543       
    534544        return EOK;
    535545}
    536546
    537 /** Start a fibril for discovering new devices. */
    538 static void input_start_dev_discovery(void)
    539 {
    540         fid_t fid = fibril_create(dev_discovery_fibril, NULL);
    541         if (!fid) {
    542                 printf("%s: Failed to create device discovery fibril.\n",
     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       
     555        rc = loc_category_get_id("mouse", &mouse_cat, IPC_FLAG_BLOCKING);
     556        if (rc != EOK) {
     557                printf("%s: Failed resolving category 'mouse'.\n", NAME);
     558                return ENOENT;
     559        }
     560       
     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",
    543567                    NAME);
    544                 return;
    545         }
    546        
    547         fibril_add_ready(fid);
     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;
     581                        }
     582                }
     583               
     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);
     589                        }
     590                }
     591        }
     592       
     593        free(svcs);
     594       
     595        /* XXX Handle device removal */
     596       
     597        return EOK;
     598}
     599
     600static int dev_check_new(void)
     601{
     602        int rc;
     603       
     604        rc = dev_check_new_kbdevs();
     605        if (rc != EOK)
     606                return rc;
     607       
     608        rc = dev_check_new_mousedevs();
     609        if (rc != EOK)
     610                return rc;
     611
     612        return EOK;
     613}
     614
     615static void cat_change_cb(void)
     616{
     617        dev_check_new();
     618}
     619
     620/** Start listening for new devices. */
     621static int input_start_dev_discovery(void)
     622{
     623        int rc;
     624
     625        rc = loc_register_cat_change_cb(cat_change_cb);
     626        if (rc != EOK) {
     627                printf("%s: Failed registering callback for device discovery. "
     628                    "(%d)\n", NAME, rc);
     629                return rc;
     630        }
     631
     632        return dev_check_new();
    548633}
    549634
     
    561646       
    562647        if (irc_service) {
    563                 while (irc_phone < 0)
    564                         irc_phone = service_obsolete_connect_blocking(SERVICE_IRC, 0, 0);
     648                while (irc_sess == NULL)
     649                        irc_sess = service_connect_blocking(EXCHANGE_SERIALIZE,
     650                            SERVICE_IRC, 0, 0);
    565651        }
    566652       
     
    572658       
    573659        /* Register driver */
    574         int rc = devmap_driver_register(NAME, client_connection);
     660        int rc = loc_server_register(NAME, client_connection);
    575661        if (rc < 0) {
    576                 printf("%s: Unable to register driver (%d)\n", NAME, rc);
     662                printf("%s: Unable to register server (%d)\n", NAME, rc);
    577663                return -1;
    578664        }
    579665       
    580         char kbd[DEVMAP_NAME_MAXLEN + 1];
    581         snprintf(kbd, DEVMAP_NAME_MAXLEN, "%s/%s", NAMESPACE, NAME);
    582        
    583         devmap_handle_t devmap_handle;
    584         if (devmap_device_register(kbd, &devmap_handle) != EOK) {
    585                 printf("%s: Unable to register device %s\n", NAME, kbd);
     666        char kbd[LOC_NAME_MAXLEN + 1];
     667        snprintf(kbd, LOC_NAME_MAXLEN, "%s/%s", NAMESPACE, NAME);
     668       
     669        service_id_t service_id;
     670        if (loc_service_register(kbd, &service_id) != EOK) {
     671                printf("%s: Unable to register service %s\n", NAME, kbd);
    586672                return -1;
    587673        }
Note: See TracChangeset for help on using the changeset viewer.