Changeset 350274a in mainline


Ignore:
Timestamp:
2014-07-19T15:37:46Z (10 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
9bd4615
Parents:
ebc9c2c
Message:

Convert USB HID driver away from DDF_DATA_IMPLANT.

Location:
uspace/drv/bus/usb/usbhid
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/usbhid/generic/hiddev.c

    rebc9c2c r350274a  
    3535 */
    3636
    37 /* XXX Fix this */
    38 #define _DDF_DATA_IMPLANT
    39 
    4037#include <usb/debug.h>
    4138#include <usb/classes/classes.h>
  • uspace/drv/bus/usb/usbhid/kbd/kbddev.c

    rebc9c2c r350274a  
    3434 * USB HID keyboard device structure and API.
    3535 */
    36 
    37 /* XXX Fix this */
    38 #define _DDF_DATA_IMPLANT
    3936
    4037#include <errno.h>
     
    479476}
    480477
    481 /* HID/KBD structure manipulation                                             */
    482 
    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);
     478/* API functions                                                              */
     479
     480/**
     481 * Initialization of the USB/HID keyboard structure.
     482 *
     483 * This functions initializes required structures from the device's descriptors.
     484 *
     485 * During initialization, the keyboard is switched into boot protocol, the idle
     486 * rate is set to 0 (infinity), resulting in the keyboard only reporting event
     487 * when a key is pressed or released. Finally, the LED lights are turned on
     488 * according to the default setup of lock keys.
     489 *
     490 * @note By default, the keyboards is initialized with Num Lock turned on and
     491 *       other locks turned off.
     492 *
     493 * @param kbd_dev Keyboard device structure to be initialized.
     494 * @param dev DDF device structure of the keyboard.
     495 *
     496 * @retval EOK if successful.
     497 * @retval EINVAL if some parameter is not given.
     498 * @return Other value inherited from function usbhid_dev_init().
     499 */
     500int usb_kbd_init(usb_hid_dev_t *hid_dev, void **data)
     501{
     502        ddf_fun_t *fun = NULL;
     503        usb_kbd_t *kbd_dev = NULL;
     504        usb_hid_report_path_t *path = NULL;
     505        bool bound = false;
     506        fid_t fid = 0;
     507        int rc;
     508
     509        usb_log_debug("Initializing HID/KBD structure...\n");
     510
     511        if (hid_dev == NULL) {
     512                usb_log_error(
     513                    "Failed to init keyboard structure: no structure given.\n");
     514                rc = EINVAL;
     515                goto error;
     516        }
    488517
    489518        /* Create the exposed function. */
    490519        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,
    492             fun_exposed, HID_KBD_FUN_NAME);
     520        fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed,
     521            HID_KBD_FUN_NAME);
    493522        if (fun == NULL) {
    494523                usb_log_error("Could not create DDF function node.\n");
    495                 return ENOMEM;
     524                rc = ENOMEM;
     525                goto error;
    496526        }
    497527
     
    499529         * to the DDF function. */
    500530        ddf_fun_set_ops(fun, &kbdops);
    501         ddf_fun_data_implant(fun, kbd_dev);
    502 
    503         int rc = ddf_fun_bind(fun);
     531
     532        kbd_dev = ddf_fun_data_alloc(fun, sizeof(usb_kbd_t));
     533        if (kbd_dev == NULL) {
     534                usb_log_error("Failed to allocate KBD device structure.\n");
     535                rc = ENOMEM;
     536                goto error;
     537        }
     538
     539        kbd_dev->fun = fun;
     540
     541        /* Default values */
     542        fibril_mutex_initialize(&kbd_dev->repeat_mtx);
     543        kbd_dev->initialized = USB_KBD_STATUS_UNINITIALIZED;
     544
     545        /* Store link to HID device */
     546        kbd_dev->hid_dev = hid_dev;
     547
     548        /* Modifiers and locks */
     549        kbd_dev->mods = DEFAULT_ACTIVE_MODS;
     550
     551        /* Autorepeat */
     552        kbd_dev->repeat.delay_before = DEFAULT_DELAY_BEFORE_FIRST_REPEAT;
     553        kbd_dev->repeat.delay_between = DEFAULT_REPEAT_DELAY;
     554
     555        // TODO: make more general
     556        path = usb_hid_report_path();
     557        if (path == NULL) {
     558                usb_log_error("Failed to create kbd report path.\n");
     559                rc = ENOMEM;
     560                goto error;
     561        }
     562
     563        rc = usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0);
     564        if (rc != EOK) {
     565                usb_log_error("Failed to append item to kbd report path.\n");
     566                goto error;
     567        }
     568
     569        usb_hid_report_path_set_report_id(path, 0);
     570
     571        kbd_dev->key_count =
     572            usb_hid_report_size(&hid_dev->report, 0, USB_HID_REPORT_TYPE_INPUT);
     573
     574        usb_hid_report_path_free(path);
     575        path = NULL;
     576
     577        usb_log_debug("Size of the input report: %zu\n", kbd_dev->key_count);
     578
     579        kbd_dev->keys = calloc(kbd_dev->key_count, sizeof(int32_t));
     580        if (kbd_dev->keys == NULL) {
     581                usb_log_error("Failed to allocate key buffer.\n");
     582                rc = ENOMEM;
     583                goto error;
     584        }
     585
     586        kbd_dev->keys_old = calloc(kbd_dev->key_count, sizeof(int32_t));
     587        if (kbd_dev->keys_old == NULL) {
     588                usb_log_error("Failed to allocate old_key buffer.\n");
     589                rc = ENOMEM;
     590                goto error;
     591        }
     592
     593        /* Output report */
     594        kbd_dev->output_size = 0;
     595        kbd_dev->output_buffer = usb_hid_report_output(&hid_dev->report,
     596            &kbd_dev->output_size, 0);
     597        if (kbd_dev->output_buffer == NULL) {
     598                usb_log_error("Error creating output report buffer.\n");
     599                rc = ENOMEM;
     600                goto error;
     601        }
     602
     603        usb_log_debug("Output buffer size: %zu\n", kbd_dev->output_size);
     604
     605        kbd_dev->led_path = usb_hid_report_path();
     606        if (kbd_dev->led_path == NULL) {
     607                usb_log_error("Failed to create kbd led report path.\n");
     608                rc = ENOMEM;
     609                goto error;
     610        }
     611
     612        rc = usb_hid_report_path_append_item(
     613            kbd_dev->led_path, USB_HIDUT_PAGE_LED, 0);
     614        if (rc != EOK) {
     615                usb_log_error("Failed to append to kbd/led report path.\n");
     616                goto error;
     617        }
     618
     619        kbd_dev->led_output_size = usb_hid_report_size(
     620            &hid_dev->report, 0, USB_HID_REPORT_TYPE_OUTPUT);
     621
     622        usb_log_debug("Output report size (in items): %zu\n",
     623            kbd_dev->led_output_size);
     624
     625        kbd_dev->led_data = calloc(kbd_dev->led_output_size, sizeof(int32_t));
     626        if (kbd_dev->led_data == NULL) {
     627                usb_log_error("Error creating buffer for LED output report.\n");
     628                rc = ENOMEM;
     629                goto error;
     630        }
     631
     632        /* Set LEDs according to initial setup.
     633         * Set Idle rate */
     634        usb_kbd_set_led(hid_dev, kbd_dev);
     635
     636        usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe,
     637            hid_dev->usb_dev->interface_no, IDLE_RATE);
     638
     639        /* Create new fibril for auto-repeat. */
     640        fid = fibril_create(usb_kbd_repeat_fibril, kbd_dev);
     641        if (fid == 0) {
     642                usb_log_error("Failed to start fibril for KBD auto-repeat");
     643                rc = ENOMEM;
     644                goto error;
     645        }
     646
     647        kbd_dev->initialized = USB_KBD_STATUS_INITIALIZED;
     648        usb_log_debug("HID/KBD device structure initialized.\n");
     649
     650        rc = ddf_fun_bind(fun);
    504651        if (rc != EOK) {
    505652                usb_log_error("Could not bind DDF function: %s.\n",
    506653                    str_error(rc));
    507                 ddf_fun_destroy(fun);
    508                 return rc;
    509         }
     654                goto error;
     655        }
     656
     657        bound = true;
    510658
    511659        usb_log_debug("%s function created. Handle: %" PRIun "\n",
     
    519667                    "Could not add DDF function to category %s: %s.\n",
    520668                    HID_KBD_CATEGORY, str_error(rc));
    521                 if (ddf_fun_unbind(fun) == EOK) {
    522                         ddf_fun_destroy(fun);
    523                 } else {
    524                         usb_log_error(
    525                             "Failed to unbind `%s', will not destroy.\n",
    526                             ddf_fun_get_name(fun));
    527                 }
    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);
     669                goto error;
     670        }
     671
     672        fibril_add_ready(fid);
    673673
    674674        /* Save the KBD device structure into the HID device structure. */
    675675        *data = kbd_dev;
    676676
    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);
    684                 return ret;
    685         }
    686 
    687         /* Create new fibril for auto-repeat. */
    688         fid_t fid = fibril_create(usb_kbd_repeat_fibril, kbd_dev);
    689         if (fid == 0) {
    690                 usb_log_error("Failed to start fibril for KBD auto-repeat");
    691                 usb_kbd_destroy(kbd_dev);
    692                 return ENOMEM;
    693         }
    694         fibril_add_ready(fid);
    695 
    696677        return EOK;
     678error:
     679        if (bound)
     680                ddf_fun_unbind(fun);
     681        if (fid != 0)
     682                fibril_destroy(fid);
     683        if (kbd_dev != NULL) {
     684                free(kbd_dev->led_data);
     685                if (kbd_dev->led_path != NULL)
     686                        usb_hid_report_path_free(kbd_dev->led_path);
     687                if (kbd_dev->output_buffer != NULL)
     688                        usb_hid_report_output_free(kbd_dev->output_buffer);
     689                free(kbd_dev->keys_old);
     690                free(kbd_dev->keys);
     691        }
     692        if (path != NULL)
     693                usb_hid_report_path_free(path);
     694        if (fun != NULL)
     695                ddf_fun_destroy(fun);
     696        return rc;
    697697}
    698698
     
    749749        usb_hid_report_output_free(kbd_dev->output_buffer);
    750750
    751         if (kbd_dev->fun) {
    752                 if (ddf_fun_unbind(kbd_dev->fun) != EOK) {
    753                         usb_log_warning("Failed to unbind %s.\n",
    754                             ddf_fun_get_name(kbd_dev->fun));
    755                 } else {
    756                         usb_log_debug2("%s unbound.\n",
    757                             ddf_fun_get_name(kbd_dev->fun));
    758                         ddf_fun_destroy(kbd_dev->fun);
    759                 }
    760         }
     751        ddf_fun_unbind(kbd_dev->fun);
     752        ddf_fun_destroy(kbd_dev->fun);
    761753}
    762754
  • uspace/drv/bus/usb/usbhid/mouse/mousedev.c

    rebc9c2c r350274a  
    3434 * USB Mouse driver API.
    3535 */
    36 
    37 /* XXX Fix this */
    38 #define _DDF_DATA_IMPLANT
    3936
    4037#include <usb/debug.h>
     
    249246}
    250247
    251 #define FUN_UNBIND_DESTROY(fun) \
    252 if (fun) { \
    253         if (ddf_fun_unbind((fun)) == EOK) { \
    254                 ddf_fun_destroy((fun)); \
    255         } else { \
    256                 usb_log_error("Could not unbind function `%s', it " \
    257                     "will not be destroyed.\n", ddf_fun_get_name(fun)); \
    258         } \
    259 } else (void)0
    260 
    261 static int usb_mouse_create_function(usb_hid_dev_t *hid_dev, usb_mouse_t *mouse)
    262 {
    263         assert(hid_dev != NULL);
    264         assert(mouse != NULL);
    265 
    266         /* Create the exposed function. */
    267         usb_log_debug("Creating DDF function %s...\n", HID_MOUSE_FUN_NAME);
    268         ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed,
    269             HID_MOUSE_FUN_NAME);
    270         if (fun == NULL) {
    271                 usb_log_error("Could not create DDF function node `%s'.\n",
    272                     HID_MOUSE_FUN_NAME);
    273                 return ENOMEM;
    274         }
    275 
    276         ddf_fun_set_ops(fun, &ops);
    277         ddf_fun_data_implant(fun, mouse);
    278 
    279         int rc = ddf_fun_bind(fun);
    280         if (rc != EOK) {
    281                 usb_log_error("Could not bind DDF function `%s': %s.\n",
    282                     ddf_fun_get_name(fun), str_error(rc));
    283                 ddf_fun_destroy(fun);
    284                 return rc;
    285         }
    286 
    287         usb_log_debug("Adding DDF function `%s' to category %s...\n",
    288             ddf_fun_get_name(fun), HID_MOUSE_CATEGORY);
    289         rc = ddf_fun_add_to_category(fun, HID_MOUSE_CATEGORY);
    290         if (rc != EOK) {
    291                 usb_log_error(
    292                     "Could not add DDF function to category %s: %s.\n",
    293                     HID_MOUSE_CATEGORY, str_error(rc));
    294                 FUN_UNBIND_DESTROY(fun);
    295                 return rc;
    296         }
    297         mouse->mouse_fun = fun;
    298         return EOK;
    299 }
    300 
    301248/** Get highest index of a button mentioned in given report.
    302249 *
     
    341288int usb_mouse_init(usb_hid_dev_t *hid_dev, void **data)
    342289{
     290        ddf_fun_t *fun = NULL;
     291        usb_mouse_t *mouse_dev = NULL;
     292        bool bound = false;
     293        int rc;
     294
    343295        usb_log_debug("Initializing HID/Mouse structure...\n");
    344296
     
    346298                usb_log_error("Failed to init mouse structure: no structure"
    347299                    " given.\n");
    348                 return EINVAL;
    349         }
    350 
    351         usb_mouse_t *mouse_dev = calloc(1, sizeof(usb_mouse_t));
     300                rc = EINVAL;
     301                goto error;
     302        }
     303
     304        /* Create the exposed function. */
     305        usb_log_debug("Creating DDF function %s...\n", HID_MOUSE_FUN_NAME);
     306        fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed,
     307            HID_MOUSE_FUN_NAME);
     308        if (fun == NULL) {
     309                usb_log_error("Could not create DDF function node `%s'.\n",
     310                    HID_MOUSE_FUN_NAME);
     311                rc = ENOMEM;
     312                goto error;
     313        }
     314
     315        ddf_fun_set_ops(fun, &ops);
     316
     317        mouse_dev = ddf_fun_data_alloc(fun, sizeof(usb_mouse_t));
    352318        if (mouse_dev == NULL) {
    353319                usb_log_error("Error while creating USB/HID Mouse device "
    354320                    "structure.\n");
    355                 return ENOMEM;
     321                rc = ENOMEM;
     322                goto error;
    356323        }
    357324
     
    368335        if (mouse_dev->buttons == NULL) {
    369336                usb_log_error(NAME ": out of memory, giving up on device!\n");
    370                 free(mouse_dev);
    371                 return ENOMEM;
     337                rc = ENOMEM;
     338                goto error;
    372339        }
    373340
     
    376343            hid_dev->usb_dev->interface_no, IDLE_RATE);
    377344
    378         int rc = usb_mouse_create_function(hid_dev, mouse_dev);
     345        rc = ddf_fun_bind(fun);
    379346        if (rc != EOK) {
    380                 free(mouse_dev->buttons);
    381                 free(mouse_dev);
    382                 return rc;
    383         }
     347                usb_log_error("Could not bind DDF function `%s': %s.\n",
     348                    ddf_fun_get_name(fun), str_error(rc));
     349                goto error;
     350        }
     351
     352        bound = true;
     353
     354        usb_log_debug("Adding DDF function `%s' to category %s...\n",
     355            ddf_fun_get_name(fun), HID_MOUSE_CATEGORY);
     356        rc = ddf_fun_add_to_category(fun, HID_MOUSE_CATEGORY);
     357        if (rc != EOK) {
     358                usb_log_error("Could not add DDF function to category %s: "
     359                    "%s.\n", HID_MOUSE_CATEGORY, str_error(rc));
     360                goto error;
     361        }
     362
     363        mouse_dev->mouse_fun = fun;
    384364
    385365        /* Save the Mouse device structure into the HID device structure. */
    386366        *data = mouse_dev;
    387 
    388367        return EOK;
     368error:
     369        if (bound)
     370                ddf_fun_unbind(fun);
     371        if (mouse_dev != NULL)
     372                free(mouse_dev->buttons);
     373        if (fun != NULL)
     374                ddf_fun_destroy(fun);
     375        return rc;
    389376}
    390377
     
    417404        }
    418405
    419         FUN_UNBIND_DESTROY(mouse_dev->mouse_fun);
    420 
     406        ddf_fun_unbind(mouse_dev->mouse_fun);
    421407        free(mouse_dev->buttons);
     408        ddf_fun_destroy(mouse_dev->mouse_fun);
    422409}
    423410
Note: See TracChangeset for help on using the changeset viewer.