Changeset 0f31e2b in mainline for uspace/srv/hid/console/console.c


Ignore:
Timestamp:
2011-03-03T12:44:33Z (13 years ago)
Author:
Lubos Slovak <lubos.slovak@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
d3594362
Parents:
1c6c4092 (diff), 2c22f1f7 (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:

Merged development changes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/hid/console/console.c

    r1c6c4092 r0f31e2b  
    4141#include <ipc/ns.h>
    4242#include <errno.h>
     43#include <str_error.h>
    4344#include <ipc/console.h>
    4445#include <unistd.h>
     
    6465#define NAME       "console"
    6566#define NAMESPACE  "term"
     67/** Interval for checking for new keyboard (1/4s). */
     68#define HOTPLUG_WATCH_INTERVAL (1000 * 250)
    6669
    6770/** Phone to the keyboard driver. */
     
    712715}
    713716
    714 static int connect_keyboard(char *path)
     717static int connect_keyboard_or_mouse(const char *devname,
     718    async_client_conn_t handler, const char *path)
    715719{
    716720        int fd = open(path, O_RDONLY);
     
    725729        }
    726730       
    727         /* NB: The callback connection is slotted for removal */
    728         sysarg_t phonehash;
    729         sysarg_t taskhash;
    730         int rc = async_req_3_5(phone, IPC_M_CONNECT_TO_ME, SERVICE_CONSOLE,
    731             0, 0, NULL, NULL, NULL, &taskhash, &phonehash);
     731        int rc = async_connect_to_me(phone, SERVICE_CONSOLE, 0, 0, handler);
    732732        if (rc != EOK) {
    733                 printf(NAME ": Failed to create callback from input device\n");
     733                printf(NAME ": " \
     734                    "Failed to create callback from input device: %s.\n",
     735                    str_error(rc));
    734736                return rc;
    735737        }
    736738       
    737         async_new_connection(taskhash, phonehash, 0, NULL, keyboard_events);
    738 
    739         printf(NAME ": we got a hit (new keyboard \"%s\").\n", path);
     739        printf(NAME ": found %s \"%s\".\n", devname, path);
    740740
    741741        return phone;
    742742}
    743743
    744 /** Try to connect to given keyboard, bypassing provided libc routines.
     744static int connect_keyboard(const char *path)
     745{
     746        return connect_keyboard_or_mouse("keyboard", keyboard_events, path);
     747}
     748
     749static int connect_mouse(const char *path)
     750{
     751        return connect_keyboard_or_mouse("mouse", mouse_events, path);
     752}
     753
     754struct hid_class_info {
     755        char *classname;
     756        int (*connection_func)(const char *);
     757};
     758
     759/** Periodically check for new keyboards in /dev/class/.
    745760 *
    746  * @param devmap_path Path to keyboard without /dev prefix.
    747  * @return Phone or error code.
     761 * @param arg Class name.
     762 * @return This function should never exit.
    748763 */
    749 static int connect_keyboard_bypass(char *devmap_path)
    750 {
    751         int devmap_phone = async_connect_me_to_blocking(PHONE_NS,
    752             SERVICE_DEVMAP, DEVMAP_CLIENT, 0);
    753         if (devmap_phone < 0) {
    754                 return devmap_phone;
    755         }
    756         ipc_call_t answer;
    757         aid_t req = async_send_2(devmap_phone, DEVMAP_DEVICE_GET_HANDLE,
    758             0, 0,  &answer);
    759 
    760         sysarg_t retval = async_data_write_start(devmap_phone,
    761             devmap_path, str_size(devmap_path));
    762         if (retval != EOK) {
    763                 async_wait_for(req, NULL);
    764                 async_hangup(devmap_phone);
    765                 return retval;
    766         }
    767 
    768         async_wait_for(req, &retval);
    769 
    770         if (retval != EOK) {
    771                 async_hangup(devmap_phone);
    772                 return retval;
    773         }
    774 
    775         devmap_handle_t handle = (devmap_handle_t) IPC_GET_ARG1(answer);
    776 
    777         async_hangup(devmap_phone);
    778 
    779         int phone = async_connect_me_to(PHONE_NS,
    780             SERVICE_DEVMAP, DEVMAP_CONNECT_TO_DEVICE, handle);
    781         if (phone < 0) {
    782                 return phone;
    783         }
    784 
    785         /* NB: The callback connection is slotted for removal */
    786         sysarg_t phonehash;
    787         sysarg_t taskhash;
    788         int rc = async_req_3_5(phone, IPC_M_CONNECT_TO_ME, SERVICE_CONSOLE,
    789             0, 0, NULL, NULL, NULL, &taskhash, &phonehash);
    790         if (rc != EOK) {
    791                 printf(NAME ": Failed to create callback from input device\n");
    792                 return rc;
    793         }
    794 
    795         async_new_connection(taskhash, phonehash, 0, NULL, keyboard_events);
    796 
    797         printf(NAME ": we got a hit (new keyboard \"/dev/%s\").\n",
    798             devmap_path);
    799 
    800         return phone;
    801 }
    802 
    803 
    804 static int check_new_keyboards(void *arg)
    805 {
    806         char *class_name = (char *) arg;
    807 
    808         int index = 1;
     764static int check_new_device_fibril(void *arg)
     765{
     766        struct hid_class_info *dev_info = arg;
     767
     768        size_t index = 1;
    809769
    810770        while (true) {
    811                 async_usleep(1 * 500 * 1000);
     771                async_usleep(HOTPLUG_WATCH_INTERVAL);
    812772                char *path;
    813                 int rc = asprintf(&path, "class/%s\\%d", class_name, index);
     773                int rc = asprintf(&path, "/dev/class/%s\\%zu",
     774                    dev_info->classname, index);
    814775                if (rc < 0) {
    815776                        continue;
    816777                }
    817778                rc = 0;
    818                 rc = connect_keyboard_bypass(path);
     779                rc = dev_info->connection_func(path);
    819780                if (rc > 0) {
    820781                        /* We do not allow unplug. */
     
    831792/** Start a fibril monitoring hot-plugged keyboards.
    832793 */
    833 static void check_new_keyboards_in_background()
    834 {
    835         fid_t fid = fibril_create(check_new_keyboards, (void *)"keyboard");
     794static void check_new_devices_in_background(int (*connection_func)(const char *),
     795    const char *classname)
     796{
     797        struct hid_class_info *dev_info = malloc(sizeof(struct hid_class_info));
     798        if (dev_info == NULL) {
     799                printf(NAME ": " \
     800                    "out of memory, will not start hot-plug-watch fibril.\n");
     801                return;
     802        }
     803        int rc;
     804
     805        rc = asprintf(&dev_info->classname, "%s", classname);
     806        if (rc < 0) {
     807                printf(NAME ": failed to format classname: %s.\n",
     808                    str_error(rc));
     809                return;
     810        }
     811        dev_info->connection_func = connection_func;
     812
     813        fid_t fid = fibril_create(check_new_device_fibril, (void *)dev_info);
    836814        if (!fid) {
    837                 printf(NAME ": failed to create hot-plug-watch fibril.\n");
     815                printf(NAME
     816                    ": failed to create hot-plug-watch fibril for %s.\n",
     817                    classname);
    838818                return;
    839819        }
     
    849829        }
    850830
    851         /* Connect to mouse device */
    852         mouse_phone = -1;
    853         int mouse_fd = open("/dev/hid_in/mouse", O_RDONLY);
    854        
    855         if (mouse_fd < 0) {
    856                 printf(NAME ": Notice - failed opening %s\n", "/dev/hid_in/mouse");
    857                 goto skip_mouse;
    858         }
    859        
    860         mouse_phone = fd_phone(mouse_fd);
     831        mouse_phone = connect_mouse("/dev/hid_in/mouse");
    861832        if (mouse_phone < 0) {
    862                 printf(NAME ": Failed to connect to mouse device\n");
    863                 goto skip_mouse;
    864         }
    865        
    866         if (async_connect_to_me(mouse_phone, SERVICE_CONSOLE, 0, 0, mouse_events)
    867             != 0) {
    868                 printf(NAME ": Failed to create callback from mouse device\n");
    869                 mouse_phone = -1;
    870                 goto skip_mouse;
    871         }
    872        
    873 skip_mouse:
     833                printf(NAME ": Failed to connect to mouse device: %s.\n",
     834                    str_error(mouse_phone));
     835        }
    874836       
    875837        /* Connect to framebuffer driver */
     
    955917       
    956918        /* Start fibril for checking on hot-plugged keyboards. */
    957         check_new_keyboards_in_background();
     919        check_new_devices_in_background(connect_keyboard, "keyboard");
     920        check_new_devices_in_background(connect_mouse, "mouse");
    958921
    959922        return true;
Note: See TracChangeset for help on using the changeset viewer.