Ignore:
File:
1 edited

Legend:

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

    r7ea7db31 rf03d3786  
    317317static void change_console(console_t *cons)
    318318{
    319         if (cons == active_console)
     319        if (cons == active_console) {
    320320                return;
     321        }
    321322       
    322323        fb_pending_flush();
     
    458459                        if (IPC_GET_ARG1(call) == 1) {
    459460                                int newcon = gcons_mouse_btn((bool) IPC_GET_ARG2(call));
    460                                 if (newcon != -1)
     461                                if (newcon != -1) {
    461462                                        change_console(&consoles[newcon]);
     463                                }
    462464                        }
    463465                        retval = 0;
     
    710712}
    711713
    712 static bool console_init(char *input)
    713 {
    714         /* Connect to input device */
    715         int input_fd = open(input, O_RDONLY);
    716         if (input_fd < 0) {
    717                 printf(NAME ": Failed opening %s\n", input);
    718                 return false;
    719         }
    720        
    721         kbd_phone = fd_phone(input_fd);
    722         if (kbd_phone < 0) {
     714static int connect_keyboard(char *path)
     715{
     716        int fd = open(path, O_RDONLY);
     717        if (fd < 0) {
     718                return fd;
     719        }
     720       
     721        int phone = fd_phone(fd);
     722        if (phone < 0) {
    723723                printf(NAME ": Failed to connect to input device\n");
    724                 return false;
     724                return phone;
    725725        }
    726726       
    727727        /* NB: The callback connection is slotted for removal */
    728728        sysarg_t phonehash;
    729         if (ipc_connect_to_me(kbd_phone, SERVICE_CONSOLE, 0, 0, &phonehash) != 0) {
     729        int rc = async_req_3_5(phone, IPC_M_CONNECT_TO_ME, SERVICE_CONSOLE,
     730            0, 0, NULL, NULL, NULL, NULL, &phonehash);
     731        if (rc != EOK) {
    730732                printf(NAME ": Failed to create callback from input device\n");
     733                return rc;
     734        }
     735       
     736        async_new_connection(phonehash, 0, NULL, keyboard_events);
     737
     738        printf(NAME ": we got a hit (new keyboard \"%s\").\n", path);
     739
     740        return phone;
     741}
     742
     743/** Try to connect to given keyboard, bypassing provided libc routines.
     744 *
     745 * @param devmap_path Path to keyboard without /dev prefix.
     746 * @return Phone or error code.
     747 */
     748static int connect_keyboard_bypass(char *devmap_path)
     749{
     750        int devmap_phone = async_connect_me_to_blocking(PHONE_NS,
     751            SERVICE_DEVMAP, DEVMAP_CLIENT, 0);
     752        if (devmap_phone < 0) {
     753                return devmap_phone;
     754        }
     755        ipc_call_t answer;
     756        aid_t req = async_send_2(devmap_phone, DEVMAP_DEVICE_GET_HANDLE,
     757            0, 0,  &answer);
     758
     759        sysarg_t retval = async_data_write_start(devmap_phone,
     760            devmap_path, str_size(devmap_path));
     761        if (retval != EOK) {
     762                async_wait_for(req, NULL);
     763                ipc_hangup(devmap_phone);
     764                return retval;
     765        }
     766
     767        async_wait_for(req, &retval);
     768
     769        if (retval != EOK) {
     770                ipc_hangup(devmap_phone);
     771                return retval;
     772        }
     773
     774        devmap_handle_t handle = (devmap_handle_t) IPC_GET_ARG1(answer);
     775
     776        ipc_hangup(devmap_phone);
     777
     778        int phone = async_connect_me_to(PHONE_NS,
     779            SERVICE_DEVMAP, DEVMAP_CONNECT_TO_DEVICE, handle);
     780        if (phone < 0) {
     781                return phone;
     782        }
     783
     784        /* NB: The callback connection is slotted for removal */
     785        sysarg_t phonehash;
     786        int rc = async_req_3_5(phone, IPC_M_CONNECT_TO_ME, SERVICE_CONSOLE,
     787            0, 0, NULL, NULL, NULL, NULL, &phonehash);
     788        if (rc != EOK) {
     789                printf(NAME ": Failed to create callback from input device\n");
     790                return rc;
     791        }
     792
     793        async_new_connection(phonehash, 0, NULL, keyboard_events);
     794
     795        printf(NAME ": we got a hit (new keyboard \"/dev/%s\").\n",
     796            devmap_path);
     797
     798        return phone;
     799}
     800
     801
     802static int check_new_keyboards(void *arg)
     803{
     804        char *class_name = (char *) arg;
     805
     806        int index = 1;
     807
     808        while (true) {
     809                async_usleep(1 * 500 * 1000);
     810                char *path;
     811                int rc = asprintf(&path, "class/%s\\%d", class_name, index);
     812                if (rc < 0) {
     813                        continue;
     814                }
     815                rc = 0;
     816                rc = connect_keyboard_bypass(path);
     817                if (rc > 0) {
     818                        /* We do not allow unplug. */
     819                        index++;
     820                }
     821
     822                free(path);
     823        }
     824
     825        return EOK;
     826}
     827
     828
     829/** Start a fibril monitoring hot-plugged keyboards.
     830 */
     831static void check_new_keyboards_in_background()
     832{
     833        fid_t fid = fibril_create(check_new_keyboards, (void *)"keyboard");
     834        if (!fid) {
     835                printf(NAME ": failed to create hot-plug-watch fibril.\n");
     836                return;
     837        }
     838        fibril_add_ready(fid);
     839}
     840
     841static bool console_init(char *input)
     842{
     843        /* Connect to input device */
     844        kbd_phone = connect_keyboard(input);
     845        if (kbd_phone < 0) {
    731846                return false;
    732847        }
    733        
    734         async_new_connection(phonehash, 0, NULL, keyboard_events);
    735        
     848
    736849        /* Connect to mouse device */
    737850        mouse_phone = -1;
     
    749862        }
    750863       
     864        sysarg_t phonehash;
    751865        if (ipc_connect_to_me(mouse_phone, SERVICE_CONSOLE, 0, 0, &phonehash) != 0) {
    752866                printf(NAME ": Failed to create callback from mouse device\n");
     
    816930                       
    817931                        if (devmap_device_register(vc, &consoles[i].devmap_handle) != EOK) {
     932                                devmap_hangup_phone(DEVMAP_DRIVER);
    818933                                printf(NAME ": Unable to register device %s\n", vc);
    819934                                return false;
     
    840955        async_set_interrupt_received(interrupt_received);
    841956       
     957        /* Start fibril for checking on hot-plugged keyboards. */
     958        check_new_keyboards_in_background();
     959
    842960        return true;
    843961}
     
    859977        if (!console_init(argv[1]))
    860978                return -1;
    861        
     979
    862980        printf(NAME ": Accepting connections\n");
    863981        async_manager();
Note: See TracChangeset for help on using the changeset viewer.