Changeset 1e2af6a9 in mainline


Ignore:
Timestamp:
2012-12-22T18:54:51Z (11 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
38b4a25
Parents:
f5f0cfb
Message:

usbhid, kbddev: Reorganize init to avoid data_implant.

File:
1 edited

Legend:

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

    rf5f0cfb r1e2af6a9  
    3434 * USB HID keyboard device structure and API.
    3535 */
    36 
    37 /* XXX Fix this */
    38 #define _DDF_DATA_IMPLANT
    3936
    4037#include <errno.h>
     
    481478/* HID/KBD structure manipulation                                             */
    482479
    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);
     480static int kbd_dev_init(usb_kbd_t *kbd_dev, usb_hid_dev_t *hid_dev)
     481{
     482        assert(kbd_dev);
     483        assert(hid_dev);
     484
     485        /* Default values */
     486        fibril_mutex_initialize(&kbd_dev->repeat_mtx);
     487        kbd_dev->initialized = USB_KBD_STATUS_UNINITIALIZED;
     488
     489        /* Store link to HID device */
     490        kbd_dev->hid_dev = hid_dev;
     491
     492        /* Modifiers and locks */
     493        kbd_dev->mods = DEFAULT_ACTIVE_MODS;
     494
     495        /* Autorepeat */
     496        kbd_dev->repeat.delay_before = DEFAULT_DELAY_BEFORE_FIRST_REPEAT;
     497        kbd_dev->repeat.delay_between = DEFAULT_REPEAT_DELAY;
     498
     499        // TODO: make more general
     500        usb_hid_report_path_t *path = usb_hid_report_path();
     501        if (path == NULL) {
     502                usb_log_error("Failed to create kbd report path.\n");
     503                usb_kbd_destroy(kbd_dev);
     504                return ENOMEM;
     505        }
     506
     507        int ret =
     508            usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0);
     509        if (ret != EOK) {
     510                usb_log_error("Failed to append item to kbd report path.\n");
     511                usb_hid_report_path_free(path);
     512                usb_kbd_destroy(kbd_dev);
     513                return ret;
     514        }
     515
     516        usb_hid_report_path_set_report_id(path, 0);
     517
     518        kbd_dev->key_count =
     519            usb_hid_report_size(&hid_dev->report, 0, USB_HID_REPORT_TYPE_INPUT);
     520
     521        usb_hid_report_path_free(path);
     522
     523        usb_log_debug("Size of the input report: %zu\n", kbd_dev->key_count);
     524
     525        kbd_dev->keys = calloc(kbd_dev->key_count, sizeof(int32_t));
     526        if (kbd_dev->keys == NULL) {
     527                usb_log_error("Failed to allocate key buffer.\n");
     528                usb_kbd_destroy(kbd_dev);
     529                return ENOMEM;
     530        }
     531
     532        kbd_dev->keys_old = calloc(kbd_dev->key_count, sizeof(int32_t));
     533        if (kbd_dev->keys_old == NULL) {
     534                usb_log_error("Failed to allocate old_key buffer.\n");
     535                usb_kbd_destroy(kbd_dev);
     536                return ENOMEM;
     537        }
     538
     539        /* Output report */
     540        kbd_dev->output_size = 0;
     541        kbd_dev->output_buffer = usb_hid_report_output(&hid_dev->report,
     542            &kbd_dev->output_size, 0);
     543        if (kbd_dev->output_buffer == NULL) {
     544                usb_log_error("Error creating output report buffer.\n");
     545                usb_kbd_destroy(kbd_dev);
     546                return ENOMEM;
     547        }
     548
     549        usb_log_debug("Output buffer size: %zu\n", kbd_dev->output_size);
     550
     551        kbd_dev->led_path = usb_hid_report_path();
     552        if (kbd_dev->led_path == NULL) {
     553                usb_log_error("Failed to create kbd led report path.\n");
     554                usb_kbd_destroy(kbd_dev);
     555                return ENOMEM;
     556        }
     557
     558        ret = usb_hid_report_path_append_item(
     559            kbd_dev->led_path, USB_HIDUT_PAGE_LED, 0);
     560        if (ret != EOK) {
     561                usb_log_error("Failed to append to kbd/led report path.\n");
     562                usb_kbd_destroy(kbd_dev);
     563                return ret;
     564        }
     565
     566        kbd_dev->led_output_size = usb_hid_report_size(
     567            &hid_dev->report, 0, USB_HID_REPORT_TYPE_OUTPUT);
     568
     569        usb_log_debug("Output report size (in items): %zu\n",
     570            kbd_dev->led_output_size);
     571
     572        kbd_dev->led_data = calloc(kbd_dev->led_output_size, sizeof(int32_t));
     573        if (kbd_dev->led_data == NULL) {
     574                usb_log_error("Error creating buffer for LED output report.\n");
     575                usb_kbd_destroy(kbd_dev);
     576                return ENOMEM;
     577        }
     578
     579        /* Set LEDs according to initial setup.
     580         * Set Idle rate */
     581        usb_kbd_set_led(hid_dev, kbd_dev);
     582
     583        usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe,
     584            hid_dev->usb_dev->interface_no, IDLE_RATE);
     585
     586
     587        kbd_dev->initialized = USB_KBD_STATUS_INITIALIZED;
     588        usb_log_debug("HID/KBD device structure initialized.\n");
     589
     590        return EOK;
     591}
     592
     593
     594/* API functions                                                              */
     595
     596/**
     597 * Initialization of the USB/HID keyboard structure.
     598 *
     599 * This functions initializes required structures from the device's descriptors.
     600 *
     601 * During initialization, the keyboard is switched into boot protocol, the idle
     602 * rate is set to 0 (infinity), resulting in the keyboard only reporting event
     603 * when a key is pressed or released. Finally, the LED lights are turned on
     604 * according to the default setup of lock keys.
     605 *
     606 * @note By default, the keyboards is initialized with Num Lock turned on and
     607 *       other locks turned off.
     608 *
     609 * @param kbd_dev Keyboard device structure to be initialized.
     610 * @param dev DDF device structure of the keyboard.
     611 *
     612 * @retval EOK if successful.
     613 * @retval EINVAL if some parameter is not given.
     614 * @return Other value inherited from function usbhid_dev_init().
     615 */
     616int usb_kbd_init(usb_hid_dev_t *hid_dev, void **data)
     617{
     618        usb_log_debug("Initializing HID/KBD structure...\n");
     619
     620        if (hid_dev == NULL) {
     621                usb_log_error(
     622                    "Failed to init keyboard structure: no structure given.\n");
     623                return EINVAL;
     624        }
    488625
    489626        /* Create the exposed function. */
    490627        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,
     628        ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev,
    492629            fun_exposed, HID_KBD_FUN_NAME);
    493630        if (fun == NULL) {
     
    496633        }
    497634
     635        usb_kbd_t *kbd_dev = ddf_fun_data_alloc(fun, sizeof(usb_kbd_t));
     636        if (kbd_dev == NULL) {
     637                usb_log_error("Failed to allocate KBD device structure.\n");
     638                ddf_fun_destroy(fun);
     639                return ENOMEM;
     640        }
     641
     642        int ret = kbd_dev_init(kbd_dev, hid_dev);
     643        if (ret != EOK) {
     644                usb_log_error("Failed to initialize KBD device  structure.\n");
     645                ddf_fun_destroy(fun);
     646                return ret;
     647        }
     648
    498649        /* Store the initialized HID device and HID ops
    499650         * to the DDF function. */
    500651        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) {
     652
     653        ret = ddf_fun_bind(fun);
     654        if (ret != EOK) {
    505655                usb_log_error("Could not bind DDF function: %s.\n",
    506                     str_error(rc));
     656                    str_error(ret));
     657                usb_kbd_destroy(kbd_dev);
    507658                ddf_fun_destroy(fun);
    508                 return rc;
     659                return ret;
    509660        }
    510661
     
    514665        usb_log_debug("Adding DDF function to category %s...\n",
    515666            HID_KBD_CLASS_NAME);
    516         rc = ddf_fun_add_to_category(fun, HID_KBD_CATEGORY_NAME);
    517         if (rc != EOK) {
     667        ret = ddf_fun_add_to_category(fun, HID_KBD_CATEGORY_NAME);
     668        if (ret != EOK) {
    518669                usb_log_error(
    519670                    "Could not add DDF function to category %s: %s.\n",
    520                     HID_KBD_CLASS_NAME, str_error(rc));
     671                    HID_KBD_CLASS_NAME, str_error(ret));
     672                usb_kbd_destroy(kbd_dev);
    521673                if (ddf_fun_unbind(fun) == EOK) {
    522674                        ddf_fun_destroy(fun);
     
    526678                            ddf_fun_get_name(fun));
    527679                }
    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);
    684680                return ret;
    685681        }
     
    693689        }
    694690        fibril_add_ready(fid);
     691        kbd_dev->fun = fun;
     692        /* Save the KBD device structure into the HID device structure. */
     693        *data = kbd_dev;
    695694
    696695        return EOK;
Note: See TracChangeset for help on using the changeset viewer.