Ignore:
File:
1 edited

Legend:

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

    r2a5b62b r5da7199  
    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);
     
    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) {
    244244               
     
    263263                        USB_HID_REPORT_TYPE_OUTPUT);
    264264        }
    265 
     265       
    266266        // TODO: what about the Report ID?
    267267        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,
     
    435435        assert(hid_dev != NULL);
    436436        assert(kbd_dev != NULL);
    437 
     437       
    438438        usb_hid_report_path_t *path = usb_hid_report_path();
    439439        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0);
    440440
    441441        usb_hid_report_path_set_report_id (path, hid_dev->report_id);
    442 
     442       
    443443        // fill in the currently pressed keys
    444 
     444       
    445445        usb_hid_report_field_t *field = usb_hid_report_get_sibling(
    446446            hid_dev->report, NULL, path,
     
    448448            USB_HID_REPORT_TYPE_INPUT);
    449449        unsigned i = 0;
    450 
     450       
    451451        while (field != NULL) {
    452452                usb_log_debug2("FIELD (%p) - VALUE(%d) USAGE(%u)\n",
     
    470470                    USB_HID_REPORT_TYPE_INPUT);
    471471        }
    472 
     472       
    473473        usb_hid_report_path_free(path);
    474 
     474       
    475475        usb_kbd_check_key_changes(hid_dev, kbd_dev);
    476476}
     
    502502
    503503        if (kbd_dev == NULL) {
    504                 usb_log_error("No memory!\n");
     504                usb_log_fatal("No memory!\n");
    505505                return NULL;
    506506        }
    507 
     507       
    508508        kbd_dev->console_sess = NULL;
    509509        kbd_dev->initialized = USB_KBD_STATUS_UNINITIALIZED;
    510 
     510       
    511511        return kbd_dev;
    512512}
     
    514514/*----------------------------------------------------------------------------*/
    515515
    516 static int usb_kbd_create_function(usb_kbd_t *kbd_dev)
    517 {
     516static 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);
    518520        assert(kbd_dev != NULL);
    519         assert(kbd_dev->hid_dev != NULL);
    520         assert(kbd_dev->hid_dev->usb_dev != NULL);
    521 
     521       
    522522        /* Create the exposed function. */
    523523        usb_log_debug("Creating DDF function %s...\n", HID_KBD_FUN_NAME);
    524         ddf_fun_t *fun = ddf_fun_create(kbd_dev->hid_dev->usb_dev->ddf_dev,
    525             fun_exposed, 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);
    526526        if (fun == NULL) {
    527527                usb_log_error("Could not create DDF function node.\n");
    528528                return ENOMEM;
    529529        }
    530 
     530       
    531531        /*
    532532         * Store the initialized HID device and HID ops
     
    540540                usb_log_error("Could not bind DDF function: %s.\n",
    541541                    str_error(rc));
    542                 fun->driver_data = NULL; /* We need this later */
    543542                ddf_fun_destroy(fun);
    544543                return rc;
    545544        }
    546 
     545       
    547546        usb_log_debug("%s function created. Handle: %" PRIun "\n",
    548547            HID_KBD_FUN_NAME, fun->handle);
    549 
     548       
    550549        usb_log_debug("Adding DDF function to category %s...\n",
    551550            HID_KBD_CLASS_NAME);
     
    555554                    "Could not add DDF function to category %s: %s.\n",
    556555                    HID_KBD_CLASS_NAME, str_error(rc));
    557                 fun->driver_data = NULL; /* We need this later */
    558556                ddf_fun_destroy(fun);
    559557                return rc;
    560558        }
    561         kbd_dev->fun = fun;
    562 
     559       
    563560        return EOK;
    564561}
     
    590587{
    591588        usb_log_debug("Initializing HID/KBD structure...\n");
    592 
     589       
    593590        if (hid_dev == NULL) {
    594591                usb_log_error("Failed to init keyboard structure: no structure"
     
    596593                return EINVAL;
    597594        }
    598 
     595       
    599596        usb_kbd_t *kbd_dev = usb_kbd_new();
    600597        if (kbd_dev == NULL) {
     
    606603        /* Store link to HID device */
    607604        kbd_dev->hid_dev = hid_dev;
    608 
     605       
    609606        /*
    610607         * TODO: make more general
     
    612609        usb_hid_report_path_t *path = usb_hid_report_path();
    613610        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0);
    614 
     611       
    615612        usb_hid_report_path_set_report_id(path, 0);
    616 
     613       
    617614        kbd_dev->key_count = usb_hid_report_size(
    618615            hid_dev->report, 0, USB_HID_REPORT_TYPE_INPUT);
    619616        usb_hid_report_path_free(path);
    620 
     617       
    621618        usb_log_debug("Size of the input report: %zu\n", kbd_dev->key_count);
    622 
     619       
    623620        kbd_dev->keys = (int32_t *)calloc(kbd_dev->key_count, sizeof(int32_t));
    624 
     621       
    625622        if (kbd_dev->keys == NULL) {
    626                 usb_log_error("No memory!\n");
     623                usb_log_fatal("No memory!\n");
    627624                free(kbd_dev);
    628625                return ENOMEM;
    629626        }
    630 
     627       
    631628        kbd_dev->keys_old =
    632629                (int32_t *)calloc(kbd_dev->key_count, sizeof(int32_t));
    633 
     630       
    634631        if (kbd_dev->keys_old == NULL) {
    635                 usb_log_error("No memory!\n");
     632                usb_log_fatal("No memory!\n");
    636633                free(kbd_dev->keys);
    637634                free(kbd_dev);
    638635                return ENOMEM;
    639636        }
    640 
     637       
    641638        /*
    642639         * Output report
     
    650647                return ENOMEM;
    651648        }
    652 
     649       
    653650        usb_log_debug("Output buffer size: %zu\n", kbd_dev->output_size);
    654 
     651       
    655652        kbd_dev->led_path = usb_hid_report_path();
    656653        usb_hid_report_path_append_item(
    657654            kbd_dev->led_path, USB_HIDUT_PAGE_LED, 0);
    658 
     655       
    659656        kbd_dev->led_output_size = usb_hid_report_size(hid_dev->report,
    660657            0, USB_HID_REPORT_TYPE_OUTPUT);
    661 
     658       
    662659        usb_log_debug("Output report size (in items): %zu\n",
    663660            kbd_dev->led_output_size);
    664 
     661       
    665662        kbd_dev->led_data = (int32_t *)calloc(
    666663            kbd_dev->led_output_size, sizeof(int32_t));
    667 
     664       
    668665        if (kbd_dev->led_data == NULL) {
    669666                usb_log_warning("Error creating buffer for LED output report."
     
    674671                return ENOMEM;
    675672        }
    676 
     673       
    677674        /*
    678675         * Modifiers and locks
     
    681678        kbd_dev->mods = DEFAULT_ACTIVE_MODS;
    682679        kbd_dev->lock_keys = 0;
    683 
     680       
    684681        /*
    685682         * Autorepeat
     
    689686        kbd_dev->repeat.delay_before = DEFAULT_DELAY_BEFORE_FIRST_REPEAT;
    690687        kbd_dev->repeat.delay_between = DEFAULT_REPEAT_DELAY;
    691 
    692         fibril_mutex_initialize(&kbd_dev->repeat_mtx);
    693 
     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       
    694701        // save the KBD device structure into the HID device structure
    695702        *data = kbd_dev;
    696 
     703       
    697704        // set handler for incoming calls
    698705        kbd_dev->ops.default_handler = default_connection_handler;
    699 
     706       
    700707        /*
    701708         * Set LEDs according to initial setup.
     
    703710         */
    704711        usb_kbd_set_led(hid_dev, kbd_dev);
    705 
     712       
    706713        usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe,
    707714            hid_dev->usb_dev->interface_no, IDLE_RATE);
    708 
     715       
    709716        /*
    710717         * Create new fibril for auto-repeat
     
    716723        }
    717724        fibril_add_ready(fid);
    718 
     725       
    719726        kbd_dev->initialized = USB_KBD_STATUS_INITIALIZED;
    720727        usb_log_debug("HID/KBD device structure initialized.\n");
    721 
     728       
    722729        usb_log_debug("Creating KBD function...\n");
    723         int rc = usb_kbd_create_function(kbd_dev);
     730        int rc = usb_kbd_create_function(hid_dev, kbd_dev);
    724731        if (rc != EOK) {
    725732                usb_kbd_destroy(kbd_dev);
    726733                return rc;
    727734        }
    728 
     735       
    729736        return EOK;
    730737}
     
    738745                return false;
    739746        }
    740 
     747       
    741748        usb_kbd_t *kbd_dev = (usb_kbd_t *)data;
    742749        assert(kbd_dev != NULL);
    743 
     750       
    744751        // TODO: add return value from this function
    745752        usb_kbd_process_data(hid_dev, kbd_dev);
    746 
     753       
    747754        return true;
    748755}
     
    773780                return;
    774781        }
    775 
     782       
    776783        // hangup session to the console
    777784        async_hangup(kbd_dev->console_sess);
    778 
    779         //assert(!fibril_mutex_is_locked((*kbd_dev)->repeat_mtx));
    780         // FIXME - the fibril_mutex_is_locked may not cause
    781         // fibril scheduling
    782         while (fibril_mutex_is_locked(&kbd_dev->repeat_mtx)) {}
    783 
     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       
    784794        // free all buffers
    785         free(kbd_dev->keys);
    786         free(kbd_dev->keys_old);
    787         free(kbd_dev->led_data);
    788 
     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        }
    789804        if (kbd_dev->led_path != NULL) {
    790805                usb_hid_report_path_free(kbd_dev->led_path);
     
    793808                usb_hid_report_output_free(kbd_dev->output_buffer);
    794809        }
    795 
    796         if (ddf_fun_unbind(kbd_dev->fun) != EOK) {
    797                 usb_log_warning("Failed to unbind kbd function.\n");
    798         } else {
    799                 usb_log_debug2("%s unbound.\n", kbd_dev->fun->name);
    800                 kbd_dev->fun->driver_data = NULL;
    801                 ddf_fun_destroy(kbd_dev->fun);
    802         }
    803810}
    804811
     
    810817                return;
    811818        }
    812 
     819       
    813820        if (data != NULL) {
    814                 usb_kbd_t *kbd_dev = data;
     821                usb_kbd_t *kbd_dev = (usb_kbd_t *)data;
    815822                if (usb_kbd_is_initialized(kbd_dev)) {
    816823                        usb_kbd_mark_unusable(kbd_dev);
    817                         /* wait for autorepeat */
    818                         async_usleep(CHECK_DELAY);
     824                } else {
    819825                        usb_kbd_destroy(kbd_dev);
    820826                }
     
    829835            USB_KBD_BOOT_REPORT_DESCRIPTOR,
    830836            USB_KBD_BOOT_REPORT_DESCRIPTOR_SIZE);
    831 
     837       
    832838        if (rc != EOK) {
    833839                usb_log_error("Failed to parse boot report descriptor: %s\n",
     
    835841                return rc;
    836842        }
    837 
     843       
    838844        rc = usbhid_req_set_protocol(&hid_dev->usb_dev->ctrl_pipe,
    839845            hid_dev->usb_dev->interface_no, USB_HID_PROTOCOL_BOOT);
    840 
     846       
    841847        if (rc != EOK) {
    842848                usb_log_warning("Failed to set boot protocol to the device: "
     
    844850                return rc;
    845851        }
    846 
     852       
    847853        return EOK;
    848854}
Note: See TracChangeset for help on using the changeset viewer.