Ignore:
File:
1 edited

Legend:

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

    rce2a1c2 ra0c05e7  
    6767        /** IPC session to the console device (for sending key events). */
    6868        async_sess_t *console_sess;
    69         /** DDF function */
    70         ddf_fun_t *fun;
    7169} usb_multimedia_t;
    7270
    7371
    7472/*----------------------------------------------------------------------------*/
    75 /** 
     73/**
    7674 * Default handler for IPC methods not handled by DDF.
    7775 *
     
    8886{
    8987        usb_log_debug(NAME " default_connection_handler()\n");
    90 
    91         usb_multimedia_t *multim_dev = (usb_multimedia_t *)fun->driver_data;
    92 
    93         if (multim_dev == NULL) {
     88        if (fun == NULL || fun->driver_data == NULL) {
    9489                async_answer_0(icallid, EINVAL);
    9590                return;
    9691        }
     92
     93        usb_multimedia_t *multim_dev = fun->driver_data;
    9794
    9895        async_sess_t *sess =
     
    109106                async_answer_0(icallid, EINVAL);
    110107}
    111 
    112 /*----------------------------------------------------------------------------*/
    113 
     108/*----------------------------------------------------------------------------*/
    114109static ddf_dev_ops_t multimedia_ops = {
    115110        .default_handler = default_connection_handler
    116111};
    117 
    118112/*----------------------------------------------------------------------------*/
    119113/**
     
    127121 *       sends also these keys to application (otherwise it cannot use those
    128122 *       keys at all).
    129  * 
    130  * @param hid_dev 
    131  * @param lgtch_dev
    132  * @param type Type of the event (press / release). Recognized values: 
     123 *
     124 * @param hid_dev
     125 * @param multim_dev
     126 * @param type Type of the event (press / release). Recognized values:
    133127 *             KEY_PRESS, KEY_RELEASE
    134128 * @param key Key code of the key according to HID Usage Tables.
    135129 */
    136 static void usb_multimedia_push_ev(usb_hid_dev_t *hid_dev,
     130static void usb_multimedia_push_ev(
    137131    usb_multimedia_t *multim_dev, int type, unsigned int key)
    138132{
    139         assert(hid_dev != NULL);
    140133        assert(multim_dev != NULL);
    141134
    142         kbd_event_t ev;
    143 
    144         ev.type = type;
    145         ev.key = key;
    146         ev.mods = 0;
    147         ev.c = 0;
     135        const kbd_event_t ev = {
     136                .type = type,
     137                .key = key,
     138                .mods = 0,
     139                .c = 0,
     140        };
    148141
    149142        usb_log_debug2(NAME " Sending key %d to the console\n", ev.key);
     
    155148
    156149        async_exch_t *exch = async_exchange_begin(multim_dev->console_sess);
    157         async_msg_4(exch, KBDEV_EVENT, ev.type, ev.key, ev.mods, ev.c);
    158         async_exchange_end(exch);
    159 }
    160 
    161 /*----------------------------------------------------------------------------*/
    162 
     150        if (exch != NULL) {
     151                async_msg_4(exch, KBDEV_EVENT, ev.type, ev.key, ev.mods, ev.c);
     152                async_exchange_end(exch);
     153        } else {
     154                usb_log_warning("Failed to send multimedia key.\n");
     155        }
     156}
     157/*----------------------------------------------------------------------------*/
    163158int usb_multimedia_init(struct usb_hid_dev *hid_dev, void **data)
    164159{
    165160        if (hid_dev == NULL || hid_dev->usb_dev == NULL) {
    166                 return EINVAL; /*! @todo Other return code? */
     161                return EINVAL;
    167162        }
    168163
     
    187182
    188183        multim_dev->console_sess = NULL;
    189         multim_dev->fun = fun;
    190184
    191185        //todo Autorepeat?
     
    199193        }
    200194
    201         usb_log_debug("%s function created (handle: %" PRIun ").\n",
    202             NAME, fun->handle);
     195        usb_log_debug(NAME " function created (handle: %" PRIun ").\n",
     196            fun->handle);
    203197
    204198        rc = ddf_fun_add_to_category(fun, "keyboard");
     
    207201                    "Could not add DDF function to category 'keyboard': %s.\n",
    208202                    str_error(rc));
    209                 ddf_fun_destroy(fun);
     203                if (ddf_fun_unbind(fun) != EOK) {
     204                        usb_log_error("Failed to unbind %s, won't destroy.\n",
     205                            fun->name);
     206                } else {
     207                        ddf_fun_destroy(fun);
     208                }
    210209                return rc;
    211210        }
    212211
    213212        /* Save the KBD device structure into the HID device structure. */
    214         *data = multim_dev;
     213        *data = fun;
    215214
    216215        usb_log_debug(NAME " HID/multimedia structure initialized.\n");
    217216        return EOK;
    218217}
    219 
    220 /*----------------------------------------------------------------------------*/
    221 
     218/*----------------------------------------------------------------------------*/
    222219void usb_multimedia_deinit(struct usb_hid_dev *hid_dev, void *data)
    223220{
    224         if (hid_dev == NULL) {
    225                 return;
    226         }
    227 
    228         if (data != NULL) {
    229                 usb_multimedia_t *multim_dev = (usb_multimedia_t *)data;
    230                 // hangup session to the console
    231                 async_hangup(multim_dev->console_sess);
    232                 const int ret = ddf_fun_unbind(multim_dev->fun);
    233                 if (ret != EOK) {
    234                         usb_log_error("Failed to unbind multim function.\n");
     221        ddf_fun_t *fun = data;
     222        if (fun != NULL && fun->driver_data != NULL) {
     223                usb_multimedia_t *multim_dev = fun->driver_data;
     224                /* Hangup session to the console */
     225                if (multim_dev->console_sess)
     226                        async_hangup(multim_dev->console_sess);
     227                if (ddf_fun_unbind(fun) != EOK) {
     228                        usb_log_error("Failed to unbind %s, won't destroy.\n",
     229                            fun->name);
    235230                } else {
    236                         usb_log_debug2("%s unbound.\n", multim_dev->fun->name);
    237                         ddf_fun_destroy(multim_dev->fun);
     231                        usb_log_debug2("%s unbound.\n", fun->name);
     232                        /* This frees multim_dev too as it was stored in
     233                         * fun->data */
     234                        ddf_fun_destroy(fun);
    238235                }
    239         }
    240 }
    241 
    242 /*----------------------------------------------------------------------------*/
    243 
     236        } else {
     237                usb_log_error(
     238                    "Failed to deinit multimedia subdriver, data missing.\n");
     239        }
     240}
     241/*----------------------------------------------------------------------------*/
    244242bool usb_multimedia_polling_callback(struct usb_hid_dev *hid_dev, void *data)
    245243{
    246244        // TODO: checks
    247         if (hid_dev == NULL || data == NULL) {
     245        ddf_fun_t *fun = data;
     246        if (hid_dev == NULL || fun == NULL || fun->driver_data == NULL) {
    248247                return false;
    249248        }
    250249
    251         usb_multimedia_t *multim_dev = (usb_multimedia_t *)data;
     250        usb_multimedia_t *multim_dev = fun->driver_data;
    252251
    253252        usb_hid_report_path_t *path = usb_hid_report_path();
    254         usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0);
     253        if (path == NULL)
     254                return true; /* This might be a temporary failure. */
     255
     256        int ret =
     257            usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0);
     258        if (ret != EOK) {
     259                usb_hid_report_path_free(path);
     260                return true; /* This might be a temporary failure. */
     261        }
    255262
    256263        usb_hid_report_path_set_report_id(path, hid_dev->report_id);
     
    261268            USB_HID_REPORT_TYPE_INPUT);
    262269
    263         /*! @todo Is this iterating OK if done multiple times?
    264          *  @todo The parsing is not OK
    265          */
     270        //FIXME Is this iterating OK if done multiple times?
     271        //FIXME The parsing is not OK. (what's wrong?)
    266272        while (field != NULL) {
    267                 if(field->value != 0) {
    268                         usb_log_debug(NAME " KEY VALUE(%X) USAGE(%X)\n", 
     273                if (field->value != 0) {
     274                        usb_log_debug(NAME " KEY VALUE(%X) USAGE(%X)\n",
    269275                            field->value, field->usage);
    270                         unsigned int key =
     276                        const unsigned key =
    271277                            usb_multimedia_map_usage(field->usage);
    272                         const char *key_str = 
     278                        const char *key_str =
    273279                            usbhid_multimedia_usage_to_str(field->usage);
    274280                        usb_log_info("Pressed key: %s\n", key_str);
    275                         usb_multimedia_push_ev(hid_dev, multim_dev, KEY_PRESS,
    276                                                key);
     281                        usb_multimedia_push_ev(multim_dev, KEY_PRESS, key);
    277282                }
    278283
    279284                field = usb_hid_report_get_sibling(
    280285                    &hid_dev->report, field, path, USB_HID_PATH_COMPARE_END
    281                     | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 
     286                    | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
    282287                    USB_HID_REPORT_TYPE_INPUT);
    283288        }
     
    287292        return true;
    288293}
    289 
    290294/**
    291295 * @}
Note: See TracChangeset for help on using the changeset viewer.