Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/usbhid/kbd/kbddev.c

    r56fd7cf r8e10ef4  
    3434 * USB HID keyboard device structure and API.
    3535 */
    36 
    37 /* XXX Fix this */
    38 #define _DDF_DATA_IMPLANT
    3936
    4037#include <errno.h>
     
    264261
    265262        if (rc != EOK) {
    266                 usb_log_warning("Error translating LED output to output report"
    267                     ".\n");
     263                usb_log_warning("Could not translate LED output to output"
     264                    "report.\n");
    268265                return;
    269266        }
     
    273270                0));
    274271
    275         rc = usbhid_req_set_report(&hid_dev->usb_dev->ctrl_pipe,
    276             hid_dev->usb_dev->interface_no, USB_HID_REPORT_TYPE_OUTPUT,
     272        rc = usbhid_req_set_report(
     273            usb_device_get_default_pipe(hid_dev->usb_dev),
     274            usb_device_get_iface_number(hid_dev->usb_dev),
     275            USB_HID_REPORT_TYPE_OUTPUT,
    277276            kbd_dev->output_buffer, kbd_dev->output_size);
    278277        if (rc != EOK) {
     
    481480/* HID/KBD structure manipulation                                             */
    482481
    483 static int usb_kbd_create_function(usb_kbd_t *kbd_dev)
    484 {
    485         assert(kbd_dev != NULL);
    486         assert(kbd_dev->hid_dev != NULL);
    487         assert(kbd_dev->hid_dev->usb_dev != NULL);
     482static int kbd_dev_init(usb_kbd_t *kbd_dev, usb_hid_dev_t *hid_dev)
     483{
     484        assert(kbd_dev);
     485        assert(hid_dev);
     486
     487        /* Default values */
     488        fibril_mutex_initialize(&kbd_dev->repeat_mtx);
     489        kbd_dev->initialized = USB_KBD_STATUS_UNINITIALIZED;
     490
     491        /* Store link to HID device */
     492        kbd_dev->hid_dev = hid_dev;
     493
     494        /* Modifiers and locks */
     495        kbd_dev->mods = DEFAULT_ACTIVE_MODS;
     496
     497        /* Autorepeat */
     498        kbd_dev->repeat.delay_before = DEFAULT_DELAY_BEFORE_FIRST_REPEAT;
     499        kbd_dev->repeat.delay_between = DEFAULT_REPEAT_DELAY;
     500
     501        // TODO: make more general
     502        usb_hid_report_path_t *path = usb_hid_report_path();
     503        if (path == NULL) {
     504                usb_log_error("Failed to create kbd report path.\n");
     505                usb_kbd_destroy(kbd_dev);
     506                return ENOMEM;
     507        }
     508
     509        int ret =
     510            usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0);
     511        if (ret != EOK) {
     512                usb_log_error("Failed to append item to kbd report path.\n");
     513                usb_hid_report_path_free(path);
     514                usb_kbd_destroy(kbd_dev);
     515                return ret;
     516        }
     517
     518        usb_hid_report_path_set_report_id(path, 0);
     519
     520        kbd_dev->key_count =
     521            usb_hid_report_size(&hid_dev->report, 0, USB_HID_REPORT_TYPE_INPUT);
     522
     523        usb_hid_report_path_free(path);
     524
     525        usb_log_debug("Size of the input report: %zu\n", kbd_dev->key_count);
     526
     527        kbd_dev->keys = calloc(kbd_dev->key_count, sizeof(int32_t));
     528        if (kbd_dev->keys == NULL) {
     529                usb_log_error("Failed to allocate key buffer.\n");
     530                usb_kbd_destroy(kbd_dev);
     531                return ENOMEM;
     532        }
     533
     534        kbd_dev->keys_old = calloc(kbd_dev->key_count, sizeof(int32_t));
     535        if (kbd_dev->keys_old == NULL) {
     536                usb_log_error("Failed to allocate old_key buffer.\n");
     537                usb_kbd_destroy(kbd_dev);
     538                return ENOMEM;
     539        }
     540
     541        /* Output report */
     542        kbd_dev->output_size = 0;
     543        kbd_dev->output_buffer = usb_hid_report_output(&hid_dev->report,
     544            &kbd_dev->output_size, 0);
     545        if (kbd_dev->output_buffer == NULL) {
     546                usb_log_error("Error creating output report buffer.\n");
     547                usb_kbd_destroy(kbd_dev);
     548                return ENOMEM;
     549        }
     550
     551        usb_log_debug("Output buffer size: %zu\n", kbd_dev->output_size);
     552
     553        kbd_dev->led_path = usb_hid_report_path();
     554        if (kbd_dev->led_path == NULL) {
     555                usb_log_error("Failed to create kbd led report path.\n");
     556                usb_kbd_destroy(kbd_dev);
     557                return ENOMEM;
     558        }
     559
     560        ret = usb_hid_report_path_append_item(
     561            kbd_dev->led_path, USB_HIDUT_PAGE_LED, 0);
     562        if (ret != EOK) {
     563                usb_log_error("Failed to append to kbd/led report path.\n");
     564                usb_kbd_destroy(kbd_dev);
     565                return ret;
     566        }
     567
     568        kbd_dev->led_output_size = usb_hid_report_size(
     569            &hid_dev->report, 0, USB_HID_REPORT_TYPE_OUTPUT);
     570
     571        usb_log_debug("Output report size (in items): %zu\n",
     572            kbd_dev->led_output_size);
     573
     574        kbd_dev->led_data = calloc(kbd_dev->led_output_size, sizeof(int32_t));
     575        if (kbd_dev->led_data == NULL) {
     576                usb_log_error("Error creating buffer for LED output report.\n");
     577                usb_kbd_destroy(kbd_dev);
     578                return ENOMEM;
     579        }
     580
     581        /* Set LEDs according to initial setup.
     582         * Set Idle rate */
     583        usb_kbd_set_led(hid_dev, kbd_dev);
     584
     585        usbhid_req_set_idle(usb_device_get_default_pipe(hid_dev->usb_dev),
     586            usb_device_get_iface_number(hid_dev->usb_dev), IDLE_RATE);
     587
     588
     589        kbd_dev->initialized = USB_KBD_STATUS_INITIALIZED;
     590        usb_log_debug("HID/KBD device structure initialized.\n");
     591
     592        return EOK;
     593}
     594
     595
     596/* API functions                                                              */
     597
     598/**
     599 * Initialization of the USB/HID keyboard structure.
     600 *
     601 * This functions initializes required structures from the device's descriptors.
     602 *
     603 * During initialization, the keyboard is switched into boot protocol, the idle
     604 * rate is set to 0 (infinity), resulting in the keyboard only reporting event
     605 * when a key is pressed or released. Finally, the LED lights are turned on
     606 * according to the default setup of lock keys.
     607 *
     608 * @note By default, the keyboards is initialized with Num Lock turned on and
     609 *       other locks turned off.
     610 *
     611 * @param kbd_dev Keyboard device structure to be initialized.
     612 * @param dev DDF device structure of the keyboard.
     613 *
     614 * @retval EOK if successful.
     615 * @retval EINVAL if some parameter is not given.
     616 * @return Other value inherited from function usbhid_dev_init().
     617 */
     618int usb_kbd_init(usb_hid_dev_t *hid_dev, void **data)
     619{
     620        usb_log_debug("Initializing HID/KBD structure...\n");
     621
     622        if (hid_dev == NULL) {
     623                usb_log_error(
     624                    "Failed to init keyboard structure: no structure given.\n");
     625                return EINVAL;
     626        }
    488627
    489628        /* Create the exposed function. */
    490629        usb_log_debug("Creating DDF function %s...\n", HID_KBD_FUN_NAME);
    491         ddf_fun_t *fun = ddf_fun_create(kbd_dev->hid_dev->usb_dev->ddf_dev,
     630        ddf_fun_t *fun = usb_device_ddf_fun_create(hid_dev->usb_dev,
    492631            fun_exposed, HID_KBD_FUN_NAME);
    493632        if (fun == NULL) {
     
    496635        }
    497636
     637        usb_kbd_t *kbd_dev = ddf_fun_data_alloc(fun, sizeof(usb_kbd_t));
     638        if (kbd_dev == NULL) {
     639                usb_log_error("Failed to allocate KBD device structure.\n");
     640                ddf_fun_destroy(fun);
     641                return ENOMEM;
     642        }
     643
     644        int ret = kbd_dev_init(kbd_dev, hid_dev);
     645        if (ret != EOK) {
     646                usb_log_error("Failed to initialize KBD device  structure.\n");
     647                ddf_fun_destroy(fun);
     648                return ret;
     649        }
     650
    498651        /* Store the initialized HID device and HID ops
    499652         * to the DDF function. */
    500653        ddf_fun_set_ops(fun, &kbdops);
    501         ddf_fun_data_implant(fun, kbd_dev);
    502 
    503         int rc = ddf_fun_bind(fun);
    504         if (rc != EOK) {
     654
     655        ret = ddf_fun_bind(fun);
     656        if (ret != EOK) {
    505657                usb_log_error("Could not bind DDF function: %s.\n",
    506                     str_error(rc));
     658                    str_error(ret));
     659                usb_kbd_destroy(kbd_dev);
    507660                ddf_fun_destroy(fun);
    508                 return rc;
     661                return ret;
    509662        }
    510663
     
    514667        usb_log_debug("Adding DDF function to category %s...\n",
    515668            HID_KBD_CLASS_NAME);
    516         rc = ddf_fun_add_to_category(fun, HID_KBD_CATEGORY_NAME);
    517         if (rc != EOK) {
     669        ret = ddf_fun_add_to_category(fun, HID_KBD_CATEGORY_NAME);
     670        if (ret != EOK) {
    518671                usb_log_error(
    519672                    "Could not add DDF function to category %s: %s.\n",
    520                     HID_KBD_CLASS_NAME, str_error(rc));
     673                    HID_KBD_CLASS_NAME, str_error(ret));
     674                usb_kbd_destroy(kbd_dev);
    521675                if (ddf_fun_unbind(fun) == EOK) {
    522676                        ddf_fun_destroy(fun);
     
    526680                            ddf_fun_get_name(fun));
    527681                }
    528                 return rc;
    529         }
    530         kbd_dev->fun = fun;
    531 
    532         return EOK;
    533 }
    534 
    535 /* API functions                                                              */
    536 
    537 /**
    538  * Initialization of the USB/HID keyboard structure.
    539  *
    540  * This functions initializes required structures from the device's descriptors.
    541  *
    542  * During initialization, the keyboard is switched into boot protocol, the idle
    543  * rate is set to 0 (infinity), resulting in the keyboard only reporting event
    544  * when a key is pressed or released. Finally, the LED lights are turned on
    545  * according to the default setup of lock keys.
    546  *
    547  * @note By default, the keyboards is initialized with Num Lock turned on and
    548  *       other locks turned off.
    549  *
    550  * @param kbd_dev Keyboard device structure to be initialized.
    551  * @param dev DDF device structure of the keyboard.
    552  *
    553  * @retval EOK if successful.
    554  * @retval EINVAL if some parameter is not given.
    555  * @return Other value inherited from function usbhid_dev_init().
    556  */
    557 int usb_kbd_init(usb_hid_dev_t *hid_dev, void **data)
    558 {
    559         usb_log_debug("Initializing HID/KBD structure...\n");
    560 
    561         if (hid_dev == NULL) {
    562                 usb_log_error(
    563                     "Failed to init keyboard structure: no structure given.\n");
    564                 return EINVAL;
    565         }
    566 
    567         usb_kbd_t *kbd_dev = calloc(1, sizeof(usb_kbd_t));
    568         if (kbd_dev == NULL) {
    569                 usb_log_error("Failed to allocate KBD device structure.\n");
    570                 return ENOMEM;
    571         }
    572         /* Default values */
    573         fibril_mutex_initialize(&kbd_dev->repeat_mtx);
    574         kbd_dev->initialized = USB_KBD_STATUS_UNINITIALIZED;
    575 
    576         /* Store link to HID device */
    577         kbd_dev->hid_dev = hid_dev;
    578 
    579         /* Modifiers and locks */
    580         kbd_dev->mods = DEFAULT_ACTIVE_MODS;
    581 
    582         /* Autorepeat */
    583         kbd_dev->repeat.delay_before = DEFAULT_DELAY_BEFORE_FIRST_REPEAT;
    584         kbd_dev->repeat.delay_between = DEFAULT_REPEAT_DELAY;
    585 
    586 
    587         // TODO: make more general
    588         usb_hid_report_path_t *path = usb_hid_report_path();
    589         if (path == NULL) {
    590                 usb_log_error("Failed to create kbd report path.\n");
    591                 usb_kbd_destroy(kbd_dev);
    592                 return ENOMEM;
    593         }
    594 
    595         int ret =
    596             usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0);
    597         if (ret != EOK) {
    598                 usb_log_error("Failed to append item to kbd report path.\n");
    599                 usb_hid_report_path_free(path);
    600                 usb_kbd_destroy(kbd_dev);
    601                 return ret;
    602         }
    603 
    604         usb_hid_report_path_set_report_id(path, 0);
    605 
    606         kbd_dev->key_count =
    607             usb_hid_report_size(&hid_dev->report, 0, USB_HID_REPORT_TYPE_INPUT);
    608 
    609         usb_hid_report_path_free(path);
    610 
    611         usb_log_debug("Size of the input report: %zu\n", kbd_dev->key_count);
    612 
    613         kbd_dev->keys = calloc(kbd_dev->key_count, sizeof(int32_t));
    614         if (kbd_dev->keys == NULL) {
    615                 usb_log_error("Failed to allocate key buffer.\n");
    616                 usb_kbd_destroy(kbd_dev);
    617                 return ENOMEM;
    618         }
    619 
    620         kbd_dev->keys_old = calloc(kbd_dev->key_count, sizeof(int32_t));
    621         if (kbd_dev->keys_old == NULL) {
    622                 usb_log_error("Failed to allocate old_key buffer.\n");
    623                 usb_kbd_destroy(kbd_dev);
    624                 return ENOMEM;
    625         }
    626 
    627         /* Output report */
    628         kbd_dev->output_size = 0;
    629         kbd_dev->output_buffer = usb_hid_report_output(&hid_dev->report,
    630             &kbd_dev->output_size, 0);
    631         if (kbd_dev->output_buffer == NULL) {
    632                 usb_log_error("Error creating output report buffer.\n");
    633                 usb_kbd_destroy(kbd_dev);
    634                 return ENOMEM;
    635         }
    636 
    637         usb_log_debug("Output buffer size: %zu\n", kbd_dev->output_size);
    638 
    639         kbd_dev->led_path = usb_hid_report_path();
    640         if (kbd_dev->led_path == NULL) {
    641                 usb_log_error("Failed to create kbd led report path.\n");
    642                 usb_kbd_destroy(kbd_dev);
    643                 return ENOMEM;
    644         }
    645 
    646         ret = usb_hid_report_path_append_item(
    647             kbd_dev->led_path, USB_HIDUT_PAGE_LED, 0);
    648         if (ret != EOK) {
    649                 usb_log_error("Failed to append to kbd/led report path.\n");
    650                 usb_kbd_destroy(kbd_dev);
    651                 return ret;
    652         }
    653 
    654         kbd_dev->led_output_size = usb_hid_report_size(
    655             &hid_dev->report, 0, USB_HID_REPORT_TYPE_OUTPUT);
    656 
    657         usb_log_debug("Output report size (in items): %zu\n",
    658             kbd_dev->led_output_size);
    659 
    660         kbd_dev->led_data = calloc(kbd_dev->led_output_size, sizeof(int32_t));
    661         if (kbd_dev->led_data == NULL) {
    662                 usb_log_error("Error creating buffer for LED output report.\n");
    663                 usb_kbd_destroy(kbd_dev);
    664                 return ENOMEM;
    665         }
    666 
    667         /* Set LEDs according to initial setup.
    668          * Set Idle rate */
    669         usb_kbd_set_led(hid_dev, kbd_dev);
    670 
    671         usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe,
    672             hid_dev->usb_dev->interface_no, IDLE_RATE);
    673 
    674         /* Save the KBD device structure into the HID device structure. */
    675         *data = kbd_dev;
    676 
    677         kbd_dev->initialized = USB_KBD_STATUS_INITIALIZED;
    678         usb_log_debug("HID/KBD device structure initialized.\n");
    679 
    680         usb_log_debug("Creating KBD function...\n");
    681         ret = usb_kbd_create_function(kbd_dev);
    682         if (ret != EOK) {
    683                 usb_kbd_destroy(kbd_dev);
    684682                return ret;
    685683        }
     
    693691        }
    694692        fibril_add_ready(fid);
     693        kbd_dev->fun = fun;
     694        /* Save the KBD device structure into the HID device structure. */
     695        *data = kbd_dev;
    695696
    696697        return EOK;
     
    787788        }
    788789
    789         rc = usbhid_req_set_protocol(&hid_dev->usb_dev->ctrl_pipe,
    790             hid_dev->usb_dev->interface_no, USB_HID_PROTOCOL_BOOT);
     790        rc = usbhid_req_set_protocol(
     791            usb_device_get_default_pipe(hid_dev->usb_dev),
     792            usb_device_get_iface_number(hid_dev->usb_dev),
     793            USB_HID_PROTOCOL_BOOT);
    791794
    792795        if (rc != EOK) {
Note: See TracChangeset for help on using the changeset viewer.