Ignore:
Timestamp:
2011-10-30T19:50:54Z (13 years ago)
Author:
Maurizio Lombardi <m.lombardi85@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
3ce78580, 48902fa
Parents:
4c3ad56 (diff), 45bf63c (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:

Merge mainline changes

File:
1 edited

Legend:

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

    r4c3ad56 r20a3465  
    8888
    8989/** Keyboard polling endpoint description for boot protocol class. */
    90 usb_endpoint_description_t usb_hid_kbd_poll_endpoint_description = {
     90const usb_endpoint_description_t usb_hid_kbd_poll_endpoint_description = {
    9191        .transfer_type = USB_TRANSFER_INTERRUPT,
    9292        .direction = USB_DIRECTION_IN,
     
    174174{
    175175        sysarg_t method = IPC_GET_IMETHOD(*icall);
    176        
     176
    177177        usb_kbd_t *kbd_dev = (usb_kbd_t *) fun->driver_data;
    178178        if (kbd_dev == NULL) {
     
    182182                return;
    183183        }
    184        
     184
    185185        async_sess_t *sess =
    186186            async_callback_receive_start(EXCHANGE_SERIALIZE, icall);
     
    237237
    238238        usb_hid_report_field_t *field = usb_hid_report_get_sibling(
    239             hid_dev->report, NULL, kbd_dev->led_path,
     239            &hid_dev->report, NULL, kbd_dev->led_path,
    240240            USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
    241241            USB_HID_REPORT_TYPE_OUTPUT);
    242        
     242
    243243        while (field != NULL) {
    244                
    245                 if ((field->usage == USB_HID_LED_NUM_LOCK) 
     244
     245                if ((field->usage == USB_HID_LED_NUM_LOCK)
    246246                    && (kbd_dev->mods & KM_NUM_LOCK)){
    247247                        field->value = 1;
    248248                }
    249249
    250                 if ((field->usage == USB_HID_LED_CAPS_LOCK) 
     250                if ((field->usage == USB_HID_LED_CAPS_LOCK)
    251251                    && (kbd_dev->mods & KM_CAPS_LOCK)){
    252252                        field->value = 1;
    253253                }
    254254
    255                 if ((field->usage == USB_HID_LED_SCROLL_LOCK) 
     255                if ((field->usage == USB_HID_LED_SCROLL_LOCK)
    256256                    && (kbd_dev->mods & KM_SCROLL_LOCK)){
    257257                        field->value = 1;
    258258                }
    259                
    260                 field = usb_hid_report_get_sibling(hid_dev->report, field,
    261                     kbd_dev->led_path, 
    262                 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
    263                         USB_HID_REPORT_TYPE_OUTPUT);
    264         }
    265        
     259
     260                field = usb_hid_report_get_sibling(
     261                    &hid_dev->report, field, kbd_dev->led_path,
     262                USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
     263                    USB_HID_REPORT_TYPE_OUTPUT);
     264        }
     265
    266266        // TODO: what about the Report ID?
    267         int rc = usb_hid_report_output_translate(hid_dev->report, 0,
     267        int rc = usb_hid_report_output_translate(&hid_dev->report, 0,
    268268            kbd_dev->output_buffer, kbd_dev->output_size);
    269        
     269
    270270        if (rc != EOK) {
    271271                usb_log_warning("Error translating LED output to output report"
     
    273273                return;
    274274        }
    275        
     275
    276276        usb_log_debug("Output report buffer: %s\n",
    277277            usb_debug_str_buffer(kbd_dev->output_buffer, kbd_dev->output_size,
    278278                0));
    279        
     279
    280280        usbhid_req_set_report(&hid_dev->usb_dev->ctrl_pipe,
    281281            hid_dev->usb_dev->interface_no, USB_HID_REPORT_TYPE_OUTPUT,
     
    300300                return;
    301301        }
    302        
     302
    303303        async_exch_t *exch = async_exchange_begin(kbd_dev->console_sess);
    304304        async_msg_2(exch, KBDEV_EVENT, type, key);
     
    347347        unsigned int key;
    348348        size_t i;
    349        
     349
    350350        /*
    351351         * First of all, check if the kbd have reported phantom state.
     
    362362                return;
    363363        }
    364        
     364
    365365        /*
    366366         * Key releases
     
    382382                }
    383383        }
    384        
     384
    385385        /*
    386386         * Key presses
     
    402402                }
    403403        }
    404        
     404
    405405        memcpy(kbd_dev->keys_old, kbd_dev->keys, kbd_dev->key_count * 4);
    406        
     406
    407407        char key_buffer[512];
    408408        ddf_dump_buffer(key_buffer, 512,
     
    432432static void usb_kbd_process_data(usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev)
    433433{
    434         assert(hid_dev->report != NULL);
    435434        assert(hid_dev != NULL);
    436435        assert(kbd_dev != NULL);
    437        
     436
    438437        usb_hid_report_path_t *path = usb_hid_report_path();
    439438        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0);
    440439
    441440        usb_hid_report_path_set_report_id (path, hid_dev->report_id);
    442        
     441
    443442        // fill in the currently pressed keys
    444        
     443
    445444        usb_hid_report_field_t *field = usb_hid_report_get_sibling(
    446             hid_dev->report, NULL, path,
    447             USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 
     445            &hid_dev->report, NULL, path,
     446            USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
    448447            USB_HID_REPORT_TYPE_INPUT);
    449448        unsigned i = 0;
    450        
     449
    451450        while (field != NULL) {
    452451                usb_log_debug2("FIELD (%p) - VALUE(%d) USAGE(%u)\n",
     
    454453               
    455454                assert(i < kbd_dev->key_count);
    456                
     455
    457456                // save the key usage
    458457                if (field->value != 0) {
     
    463462                }
    464463                usb_log_debug2("Saved %u. key usage %d\n", i, kbd_dev->keys[i]);
    465                
     464
    466465                ++i;
    467                 field = usb_hid_report_get_sibling(hid_dev->report, field, path,
    468                     USB_HID_PATH_COMPARE_END
    469                     | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
     466                field = usb_hid_report_get_sibling(
     467                    &hid_dev->report, field, path, USB_HID_PATH_COMPARE_END
     468                        | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
    470469                    USB_HID_REPORT_TYPE_INPUT);
    471470        }
    472        
     471
    473472        usb_hid_report_path_free(path);
    474        
     473
    475474        usb_kbd_check_key_changes(hid_dev, kbd_dev);
    476475}
     
    502501
    503502        if (kbd_dev == NULL) {
    504                 usb_log_fatal("No memory!\n");
     503                usb_log_error("No memory!\n");
    505504                return NULL;
    506505        }
    507        
     506
    508507        kbd_dev->console_sess = NULL;
    509508        kbd_dev->initialized = USB_KBD_STATUS_UNINITIALIZED;
    510        
     509
    511510        return kbd_dev;
    512511}
     
    514513/*----------------------------------------------------------------------------*/
    515514
    516 static int usb_kbd_create_function(usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev)
    517 {
    518         assert(hid_dev != NULL);
    519         assert(hid_dev->usb_dev != NULL);
     515static int usb_kbd_create_function(usb_kbd_t *kbd_dev)
     516{
    520517        assert(kbd_dev != NULL);
    521        
     518        assert(kbd_dev->hid_dev != NULL);
     519        assert(kbd_dev->hid_dev->usb_dev != NULL);
     520
    522521        /* Create the exposed function. */
    523522        usb_log_debug("Creating DDF function %s...\n", HID_KBD_FUN_NAME);
    524         ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed,
    525             HID_KBD_FUN_NAME);
     523        ddf_fun_t *fun = ddf_fun_create(kbd_dev->hid_dev->usb_dev->ddf_dev,
     524            fun_exposed, HID_KBD_FUN_NAME);
    526525        if (fun == NULL) {
    527526                usb_log_error("Could not create DDF function node.\n");
    528527                return ENOMEM;
    529528        }
    530        
     529
    531530        /*
    532531         * Store the initialized HID device and HID ops
     
    540539                usb_log_error("Could not bind DDF function: %s.\n",
    541540                    str_error(rc));
     541                fun->driver_data = NULL; /* We need this later */
    542542                ddf_fun_destroy(fun);
    543543                return rc;
    544544        }
    545        
     545
    546546        usb_log_debug("%s function created. Handle: %" PRIun "\n",
    547547            HID_KBD_FUN_NAME, fun->handle);
    548        
     548
    549549        usb_log_debug("Adding DDF function to category %s...\n",
    550550            HID_KBD_CLASS_NAME);
     
    554554                    "Could not add DDF function to category %s: %s.\n",
    555555                    HID_KBD_CLASS_NAME, str_error(rc));
     556                fun->driver_data = NULL; /* We need this later */
    556557                ddf_fun_destroy(fun);
    557558                return rc;
    558559        }
    559        
     560        kbd_dev->fun = fun;
     561
    560562        return EOK;
    561563}
     
    587589{
    588590        usb_log_debug("Initializing HID/KBD structure...\n");
    589        
     591
    590592        if (hid_dev == NULL) {
    591593                usb_log_error("Failed to init keyboard structure: no structure"
     
    593595                return EINVAL;
    594596        }
    595        
     597
    596598        usb_kbd_t *kbd_dev = usb_kbd_new();
    597599        if (kbd_dev == NULL) {
     
    603605        /* Store link to HID device */
    604606        kbd_dev->hid_dev = hid_dev;
    605        
     607
    606608        /*
    607609         * TODO: make more general
     
    609611        usb_hid_report_path_t *path = usb_hid_report_path();
    610612        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0);
    611        
     613
    612614        usb_hid_report_path_set_report_id(path, 0);
    613        
     615
    614616        kbd_dev->key_count = usb_hid_report_size(
    615             hid_dev->report, 0, USB_HID_REPORT_TYPE_INPUT);
     617            &hid_dev->report, 0, USB_HID_REPORT_TYPE_INPUT);
    616618        usb_hid_report_path_free(path);
    617        
     619
    618620        usb_log_debug("Size of the input report: %zu\n", kbd_dev->key_count);
    619        
    620         kbd_dev->keys = (int32_t *)calloc(kbd_dev->key_count, sizeof(int32_t));
    621        
     621
     622        kbd_dev->keys = calloc(kbd_dev->key_count, sizeof(int32_t));
     623
    622624        if (kbd_dev->keys == NULL) {
    623                 usb_log_fatal("No memory!\n");
     625                usb_log_error("No memory!\n");
    624626                free(kbd_dev);
    625627                return ENOMEM;
    626628        }
    627        
     629
    628630        kbd_dev->keys_old =
    629631                (int32_t *)calloc(kbd_dev->key_count, sizeof(int32_t));
    630        
     632
    631633        if (kbd_dev->keys_old == NULL) {
    632                 usb_log_fatal("No memory!\n");
     634                usb_log_error("No memory!\n");
    633635                free(kbd_dev->keys);
    634636                free(kbd_dev);
    635637                return ENOMEM;
    636638        }
    637        
     639
    638640        /*
    639641         * Output report
    640642         */
    641643        kbd_dev->output_size = 0;
    642         kbd_dev->output_buffer = usb_hid_report_output(hid_dev->report,
     644        kbd_dev->output_buffer = usb_hid_report_output(&hid_dev->report,
    643645            &kbd_dev->output_size, 0);
    644646        if (kbd_dev->output_buffer == NULL) {
     
    647649                return ENOMEM;
    648650        }
    649        
     651
    650652        usb_log_debug("Output buffer size: %zu\n", kbd_dev->output_size);
    651        
     653
    652654        kbd_dev->led_path = usb_hid_report_path();
    653655        usb_hid_report_path_append_item(
    654656            kbd_dev->led_path, USB_HIDUT_PAGE_LED, 0);
    655        
    656         kbd_dev->led_output_size = usb_hid_report_size(hid_dev->report,
    657             0, USB_HID_REPORT_TYPE_OUTPUT);
    658        
     657
     658        kbd_dev->led_output_size = usb_hid_report_size(
     659            &hid_dev->report, 0, USB_HID_REPORT_TYPE_OUTPUT);
     660
    659661        usb_log_debug("Output report size (in items): %zu\n",
    660662            kbd_dev->led_output_size);
    661        
     663
    662664        kbd_dev->led_data = (int32_t *)calloc(
    663665            kbd_dev->led_output_size, sizeof(int32_t));
    664        
     666
    665667        if (kbd_dev->led_data == NULL) {
    666668                usb_log_warning("Error creating buffer for LED output report."
     
    671673                return ENOMEM;
    672674        }
    673        
     675
    674676        /*
    675677         * Modifiers and locks
     
    678680        kbd_dev->mods = DEFAULT_ACTIVE_MODS;
    679681        kbd_dev->lock_keys = 0;
    680        
     682
    681683        /*
    682684         * Autorepeat
     
    686688        kbd_dev->repeat.delay_before = DEFAULT_DELAY_BEFORE_FIRST_REPEAT;
    687689        kbd_dev->repeat.delay_between = DEFAULT_REPEAT_DELAY;
    688        
    689         kbd_dev->repeat_mtx = (fibril_mutex_t *)(
    690             malloc(sizeof(fibril_mutex_t)));
    691         if (kbd_dev->repeat_mtx == NULL) {
    692                 usb_log_fatal("No memory!\n");
    693                 free(kbd_dev->keys);
    694                 usb_hid_report_output_free(kbd_dev->output_buffer);
    695                 free(kbd_dev);
    696                 return ENOMEM;
    697         }
    698        
    699         fibril_mutex_initialize(kbd_dev->repeat_mtx);
    700        
     690
     691        fibril_mutex_initialize(&kbd_dev->repeat_mtx);
     692
    701693        // save the KBD device structure into the HID device structure
    702694        *data = kbd_dev;
    703        
     695
    704696        // set handler for incoming calls
    705697        kbd_dev->ops.default_handler = default_connection_handler;
    706        
     698
    707699        /*
    708700         * Set LEDs according to initial setup.
     
    710702         */
    711703        usb_kbd_set_led(hid_dev, kbd_dev);
    712        
     704
    713705        usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe,
    714706            hid_dev->usb_dev->interface_no, IDLE_RATE);
    715        
     707
    716708        /*
    717709         * Create new fibril for auto-repeat
     
    723715        }
    724716        fibril_add_ready(fid);
    725        
     717
    726718        kbd_dev->initialized = USB_KBD_STATUS_INITIALIZED;
    727719        usb_log_debug("HID/KBD device structure initialized.\n");
    728        
     720
    729721        usb_log_debug("Creating KBD function...\n");
    730         int rc = usb_kbd_create_function(hid_dev, kbd_dev);
     722        int rc = usb_kbd_create_function(kbd_dev);
    731723        if (rc != EOK) {
    732724                usb_kbd_destroy(kbd_dev);
    733725                return rc;
    734726        }
    735        
     727
    736728        return EOK;
    737729}
     
    745737                return false;
    746738        }
    747        
     739
    748740        usb_kbd_t *kbd_dev = (usb_kbd_t *)data;
    749741        assert(kbd_dev != NULL);
    750        
     742
    751743        // TODO: add return value from this function
    752744        usb_kbd_process_data(hid_dev, kbd_dev);
    753        
     745
    754746        return true;
    755747}
     
    780772                return;
    781773        }
    782        
     774
    783775        // hangup session to the console
    784776        async_hangup(kbd_dev->console_sess);
    785        
    786         if (kbd_dev->repeat_mtx != NULL) {
    787                 //assert(!fibril_mutex_is_locked((*kbd_dev)->repeat_mtx));
    788                 // FIXME - the fibril_mutex_is_locked may not cause
    789                 // fibril scheduling
    790                 while (fibril_mutex_is_locked(kbd_dev->repeat_mtx)) {}
    791                 free(kbd_dev->repeat_mtx);
    792         }
    793        
     777
     778        //assert(!fibril_mutex_is_locked((*kbd_dev)->repeat_mtx));
     779        // FIXME - the fibril_mutex_is_locked may not cause
     780        // fibril scheduling
     781        while (fibril_mutex_is_locked(&kbd_dev->repeat_mtx)) {}
     782
    794783        // free all buffers
    795         if (kbd_dev->keys != NULL) {
    796                 free(kbd_dev->keys);
    797         }
    798         if (kbd_dev->keys_old != NULL) {
    799                 free(kbd_dev->keys_old);
    800         }
    801         if (kbd_dev->led_data != NULL) {
    802                 free(kbd_dev->led_data);
    803         }
     784        free(kbd_dev->keys);
     785        free(kbd_dev->keys_old);
     786        free(kbd_dev->led_data);
     787
    804788        if (kbd_dev->led_path != NULL) {
    805789                usb_hid_report_path_free(kbd_dev->led_path);
     
    808792                usb_hid_report_output_free(kbd_dev->output_buffer);
    809793        }
     794
     795        if (ddf_fun_unbind(kbd_dev->fun) != EOK) {
     796                usb_log_warning("Failed to unbind kbd function.\n");
     797        } else {
     798                usb_log_debug2("%s unbound.\n", kbd_dev->fun->name);
     799                kbd_dev->fun->driver_data = NULL;
     800                ddf_fun_destroy(kbd_dev->fun);
     801        }
    810802}
    811803
     
    817809                return;
    818810        }
    819        
     811
    820812        if (data != NULL) {
    821                 usb_kbd_t *kbd_dev = (usb_kbd_t *)data;
     813                usb_kbd_t *kbd_dev = data;
    822814                if (usb_kbd_is_initialized(kbd_dev)) {
    823815                        usb_kbd_mark_unusable(kbd_dev);
    824                 } else {
     816                        /* wait for autorepeat */
     817                        async_usleep(CHECK_DELAY);
    825818                        usb_kbd_destroy(kbd_dev);
    826819                }
     
    832825int usb_kbd_set_boot_protocol(usb_hid_dev_t *hid_dev)
    833826{
    834         int rc = usb_hid_parse_report_descriptor(hid_dev->report,
    835             USB_KBD_BOOT_REPORT_DESCRIPTOR,
     827        int rc = usb_hid_parse_report_descriptor(
     828            &hid_dev->report, USB_KBD_BOOT_REPORT_DESCRIPTOR,
    836829            USB_KBD_BOOT_REPORT_DESCRIPTOR_SIZE);
    837        
     830
    838831        if (rc != EOK) {
    839832                usb_log_error("Failed to parse boot report descriptor: %s\n",
     
    841834                return rc;
    842835        }
    843        
    844         rc = usbhid_req_set_protocol(&hid_dev->usb_dev->ctrl_pipe, 
     836
     837        rc = usbhid_req_set_protocol(&hid_dev->usb_dev->ctrl_pipe,
    845838            hid_dev->usb_dev->interface_no, USB_HID_PROTOCOL_BOOT);
    846        
     839
    847840        if (rc != EOK) {
    848841                usb_log_warning("Failed to set boot protocol to the device: "
     
    850843                return rc;
    851844        }
    852        
     845
    853846        return EOK;
    854847}
Note: See TracChangeset for help on using the changeset viewer.