Ignore:
Timestamp:
2011-12-18T14:02:30Z (12 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
c868e2d
Parents:
3b71e84d (diff), 1761268 (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/mouse/mousedev.c

    r3b71e84d r7aaed09  
    5555#define ARROWS_PER_SINGLE_WHEEL 3
    5656
    57 #define NAME  "mouse"
     57#define NAME "mouse"
    5858
    5959/*----------------------------------------------------------------------------*/
     
    7777
    7878/*----------------------------------------------------------------------------*/
    79 
    80 enum {
    81         USB_MOUSE_BOOT_REPORT_DESCRIPTOR_SIZE = 63
    82 };
    83 
    84 static const uint8_t USB_MOUSE_BOOT_REPORT_DESCRIPTOR[
    85     USB_MOUSE_BOOT_REPORT_DESCRIPTOR_SIZE] = {
     79static const uint8_t USB_MOUSE_BOOT_REPORT_DESCRIPTOR[] = {
    8680        0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
    8781        0x09, 0x02,                    // USAGE (Mouse)
     
    123117    ipc_callid_t icallid, ipc_call_t *icall)
    124118{
    125         usb_mouse_t *mouse_dev = (usb_mouse_t *) fun->driver_data;
     119        usb_mouse_t *mouse_dev = fun->driver_data;
    126120
    127121        if (mouse_dev == NULL) {
    128                 usb_log_debug("default_connection_handler: Missing "
    129                     "parameters.\n");
     122                usb_log_debug("%s: Missing parameters.\n", __FUNCTION__);
    130123                async_answer_0(icallid, EINVAL);
    131124                return;
    132125        }
    133126
    134         usb_log_debug("default_connection_handler: fun->name: %s\n",
    135                       fun->name);
    136         usb_log_debug("default_connection_handler: mouse_sess: %p, "
    137             "wheel_sess: %p\n", mouse_dev->mouse_sess, mouse_dev->wheel_sess);
    138 
    139         async_sess_t **sess_ptr =
    140             (str_cmp(fun->name, HID_MOUSE_FUN_NAME) == 0) ?
     127        usb_log_debug("%s: fun->name: %s\n", __FUNCTION__, fun->name);
     128        usb_log_debug("%s: mouse_sess: %p, wheel_sess: %p\n",
     129            __FUNCTION__, mouse_dev->mouse_sess, mouse_dev->wheel_sess);
     130
     131        async_sess_t **sess_ptr = (fun == mouse_dev->mouse_fun) ?
    141132            &mouse_dev->mouse_sess : &mouse_dev->wheel_sess;
    142133
     
    146137                if (*sess_ptr == NULL) {
    147138                        *sess_ptr = sess;
    148                         usb_log_debug("Console session to mouse set ok (%p).\n",
    149                             sess);
     139                        usb_log_debug("Console session to %s set ok (%p).\n",
     140                            fun->name, sess);
    150141                        async_answer_0(icallid, EOK);
    151142                } else {
    152                         usb_log_debug("default_connection_handler: Console "
    153                             "session to mouse already set.\n");
     143                        usb_log_error("Console session to %s already set.\n",
     144                            fun->name);
    154145                        async_answer_0(icallid, ELIMIT);
    155146                }
    156147        } else {
    157                 usb_log_debug("default_connection_handler: Invalid function.\n");
     148                usb_log_debug("%s: Invalid function.\n", __FUNCTION__);
    158149                async_answer_0(icallid, EINVAL);
    159         }
    160 }
    161 
    162 /*----------------------------------------------------------------------------*/
    163 
    164 static usb_mouse_t *usb_mouse_new(void)
    165 {
    166         usb_mouse_t *mouse = calloc(1, sizeof(usb_mouse_t));
    167         if (mouse == NULL) {
    168                 return NULL;
    169         }
    170         mouse->mouse_sess = NULL;
    171         mouse->wheel_sess = NULL;
    172 
    173         return mouse;
    174 }
    175 
    176 /*----------------------------------------------------------------------------*/
    177 
    178 static void usb_mouse_destroy(usb_mouse_t *mouse_dev)
    179 {
    180         assert(mouse_dev != NULL);
    181 
    182         // hangup session to the console
    183         if (mouse_dev->mouse_sess != NULL)
    184                 async_hangup(mouse_dev->mouse_sess);
    185 
    186         if (mouse_dev->wheel_sess != NULL)
    187                 async_hangup(mouse_dev->wheel_sess);
    188         int ret = ddf_fun_unbind(mouse_dev->mouse_fun);
    189         if (ret != EOK) {
    190                 usb_log_error("Failed to unbind mouse function.\n");
    191         } else {
    192                 ddf_fun_destroy(mouse_dev->mouse_fun);
    193                 /* Prevent double free */
    194                 mouse_dev->wheel_fun->driver_data = NULL;
    195         }
    196 
    197         ret = ddf_fun_unbind(mouse_dev->wheel_fun);
    198         if (ret != EOK) {
    199                 usb_log_error("Failed to unbind wheel function.\n");
    200         } else {
    201                 ddf_fun_destroy(mouse_dev->wheel_fun);
    202150        }
    203151}
     
    215163        }
    216164
    217         int count = ((wheel < 0) ? -wheel : wheel) * ARROWS_PER_SINGLE_WHEEL;
    218         int i;
    219 
    220         for (i = 0; i < count; i++) {
     165        const unsigned count =
     166            ((wheel < 0) ? -wheel : wheel) * ARROWS_PER_SINGLE_WHEEL;
     167        for (unsigned i = 0; i < count; i++) {
    221168                /* Send arrow press and release. */
    222169                usb_log_debug2("Sending key %d to the console\n", key);
     
    267214        }
    268215
    269         int shift_x = get_mouse_axis_move_value(hid_dev->report_id,
     216        const int shift_x = get_mouse_axis_move_value(hid_dev->report_id,
    270217            &hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_X);
    271         int shift_y = get_mouse_axis_move_value(hid_dev->report_id,
     218        const int shift_y = get_mouse_axis_move_value(hid_dev->report_id,
    272219            &hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_Y);
    273         int wheel = get_mouse_axis_move_value(hid_dev->report_id,
     220        const int wheel = get_mouse_axis_move_value(hid_dev->report_id,
    274221            &hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_WHEEL);
    275222
     
    277224                async_exch_t *exch =
    278225                    async_exchange_begin(mouse_dev->mouse_sess);
    279                 async_req_2_0(exch, MOUSEEV_MOVE_EVENT, shift_x, shift_y);
    280                 async_exchange_end(exch);
     226                if (exch != NULL) {
     227                        async_req_2_0(exch, MOUSEEV_MOVE_EVENT, shift_x, shift_y);
     228                        async_exchange_end(exch);
     229                }
    281230        }
    282231
     
    284233                usb_mouse_send_wheel(mouse_dev, wheel);
    285234
    286         /*
    287          * Buttons
    288          */
     235        /* Buttons */
    289236        usb_hid_report_path_t *path = usb_hid_report_path();
    290         usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_BUTTON, 0);
     237        if (path == NULL) {
     238                usb_log_warning("Failed to create USB HID report path.\n");
     239                return true;
     240        }
     241        int ret =
     242           usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_BUTTON, 0);
     243        if (ret != EOK) {
     244                usb_hid_report_path_free(path);
     245                usb_log_warning("Failed to add buttons to report path.\n");
     246                return true;
     247        }
    291248        usb_hid_report_path_set_report_id(path, hid_dev->report_id);
    292249
     
    298255                usb_log_debug2(NAME " VALUE(%X) USAGE(%X)\n", field->value,
    299256                    field->usage);
    300                
    301                 if (mouse_dev->buttons[field->usage - field->usage_minimum] == 0
    302                     && field->value != 0) {
     257                assert(field->usage > field->usage_minimum);
     258                const unsigned index = field->usage - field->usage_minimum;
     259                assert(index < mouse_dev->buttons_count);
     260
     261                if (mouse_dev->buttons[index] == 0 && field->value != 0) {
    303262                        async_exch_t *exch =
    304263                            async_exchange_begin(mouse_dev->mouse_sess);
    305                         async_req_2_0(exch, MOUSEEV_BUTTON_EVENT, field->usage, 1);
    306                         async_exchange_end(exch);
    307                        
    308                         mouse_dev->buttons[field->usage - field->usage_minimum]
    309                             = field->value;
    310                 } else if (mouse_dev->buttons[field->usage - field->usage_minimum] != 0
    311                     && field->value == 0) {
     264                        if (exch != NULL) {
     265                                async_req_2_0(exch, MOUSEEV_BUTTON_EVENT,
     266                                    field->usage, 1);
     267                                async_exchange_end(exch);
     268                                mouse_dev->buttons[index] = field->value;
     269                        }
     270
     271                } else if (mouse_dev->buttons[index] != 0 && field->value == 0) {
    312272                        async_exch_t *exch =
    313273                            async_exchange_begin(mouse_dev->mouse_sess);
    314                         async_req_2_0(exch, MOUSEEV_BUTTON_EVENT, field->usage, 0);
    315                         async_exchange_end(exch);
    316 
    317                         mouse_dev->buttons[field->usage - field->usage_minimum] =
    318                            field->value;
     274                        if (exch != NULL) {
     275                                async_req_2_0(exch, MOUSEEV_BUTTON_EVENT,
     276                                    field->usage, 0);
     277                                async_exchange_end(exch);
     278                                mouse_dev->buttons[index] = field->value;
     279                        }
    319280                }
    320281
     
    329290        return true;
    330291}
    331 
    332 /*----------------------------------------------------------------------------*/
    333 
     292/*----------------------------------------------------------------------------*/
     293#define FUN_UNBIND_DESTROY(fun) \
     294if (fun) { \
     295        if (ddf_fun_unbind((fun)) == EOK) { \
     296                (fun)->driver_data = NULL; \
     297                ddf_fun_destroy((fun)); \
     298        } else { \
     299                usb_log_error("Could not unbind function `%s', it " \
     300                    "will not be destroyed.\n", (fun)->name); \
     301        } \
     302} else (void)0
     303/*----------------------------------------------------------------------------*/
    334304static int usb_mouse_create_function(usb_hid_dev_t *hid_dev, usb_mouse_t *mouse)
    335305{
     
    339309        /* Create the exposed function. */
    340310        usb_log_debug("Creating DDF function %s...\n", HID_MOUSE_FUN_NAME);
    341         ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed, 
     311        ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed,
    342312            HID_MOUSE_FUN_NAME);
    343313        if (fun == NULL) {
    344                 usb_log_error("Could not create DDF function node.\n");
     314                usb_log_error("Could not create DDF function node `%s'.\n",
     315                    HID_MOUSE_FUN_NAME);
    345316                return ENOMEM;
    346317        }
     
    351322        int rc = ddf_fun_bind(fun);
    352323        if (rc != EOK) {
    353                 usb_log_error("Could not bind DDF function: %s.\n",
    354                     str_error(rc));
    355                 return rc;
    356         }
    357 
    358         usb_log_debug("Adding DDF function to category %s...\n",
    359             HID_MOUSE_CATEGORY);
     324                usb_log_error("Could not bind DDF function `%s': %s.\n",
     325                    fun->name, str_error(rc));
     326                fun->driver_data = NULL;
     327                ddf_fun_destroy(fun);
     328                return rc;
     329        }
     330
     331        usb_log_debug("Adding DDF function `%s' to category %s...\n",
     332            fun->name, HID_MOUSE_CATEGORY);
    360333        rc = ddf_fun_add_to_category(fun, HID_MOUSE_CATEGORY);
    361334        if (rc != EOK) {
     
    363336                    "Could not add DDF function to category %s: %s.\n",
    364337                    HID_MOUSE_CATEGORY, str_error(rc));
     338                FUN_UNBIND_DESTROY(fun);
    365339                return rc;
    366340        }
     
    370344         * Special function for acting as keyboard (wheel)
    371345         */
    372         usb_log_debug("Creating DDF function %s...\n", 
     346        usb_log_debug("Creating DDF function %s...\n",
    373347                      HID_MOUSE_WHEEL_FUN_NAME);
    374         fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed, 
     348        fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed,
    375349            HID_MOUSE_WHEEL_FUN_NAME);
    376350        if (fun == NULL) {
    377                 usb_log_error("Could not create DDF function node.\n");
     351                usb_log_error("Could not create DDF function node `%s'.\n",
     352                    HID_MOUSE_WHEEL_FUN_NAME);
     353                FUN_UNBIND_DESTROY(mouse->mouse_fun);
     354                mouse->mouse_fun = NULL;
    378355                return ENOMEM;
    379356        }
     
    388365        rc = ddf_fun_bind(fun);
    389366        if (rc != EOK) {
    390                 usb_log_error("Could not bind DDF function: %s.\n",
    391                     str_error(rc));
     367                usb_log_error("Could not bind DDF function `%s': %s.\n",
     368                    fun->name, str_error(rc));
     369                FUN_UNBIND_DESTROY(mouse->mouse_fun);
     370                mouse->mouse_fun = NULL;
     371
     372                fun->driver_data = NULL;
     373                ddf_fun_destroy(fun);
    392374                return rc;
    393375        }
     
    400382                    "Could not add DDF function to category %s: %s.\n",
    401383                    HID_MOUSE_WHEEL_CATEGORY, str_error(rc));
     384
     385                FUN_UNBIND_DESTROY(mouse->mouse_fun);
     386                mouse->mouse_fun = NULL;
     387                FUN_UNBIND_DESTROY(fun);
    402388                return rc;
    403389        }
     
    448434        return highest_button;
    449435}
    450 
    451 /*----------------------------------------------------------------------------*/
    452 
     436/*----------------------------------------------------------------------------*/
    453437int usb_mouse_init(usb_hid_dev_t *hid_dev, void **data)
    454438{
     
    461445        }
    462446
    463         usb_mouse_t *mouse_dev = usb_mouse_new();
     447        usb_mouse_t *mouse_dev = calloc(1, sizeof(usb_mouse_t));
    464448        if (mouse_dev == NULL) {
    465449                usb_log_error("Error while creating USB/HID Mouse device "
     
    484468        }
    485469
    486 
    487         // save the Mouse device structure into the HID device structure
    488         *data = mouse_dev;
    489 
    490470        // set handler for incoming calls
    491471        mouse_dev->ops.default_handler = default_connection_handler;
    492472
    493473        // TODO: how to know if the device supports the request???
    494         usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe, 
     474        usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe,
    495475            hid_dev->usb_dev->interface_no, IDLE_RATE);
    496476
    497477        int rc = usb_mouse_create_function(hid_dev, mouse_dev);
    498478        if (rc != EOK) {
    499                 usb_mouse_destroy(mouse_dev);
    500                 return rc;
    501         }
     479                free(mouse_dev->buttons);
     480                free(mouse_dev);
     481                return rc;
     482        }
     483
     484        /* Save the Mouse device structure into the HID device structure. */
     485        *data = mouse_dev;
    502486
    503487        return EOK;
    504488}
    505 
    506 /*----------------------------------------------------------------------------*/
    507 
     489/*----------------------------------------------------------------------------*/
    508490bool usb_mouse_polling_callback(usb_hid_dev_t *hid_dev, void *data)
    509491{
    510492        if (hid_dev == NULL || data == NULL) {
    511                 usb_log_error("Missing argument to the mouse polling callback."
    512                     "\n");
     493                usb_log_error(
     494                    "Missing argument to the mouse polling callback.\n");
    513495                return false;
    514496        }
    515497
    516         usb_mouse_t *mouse_dev = (usb_mouse_t *)data;
    517                
     498        usb_mouse_t *mouse_dev = data;
     499
    518500        return usb_mouse_process_report(hid_dev, mouse_dev);
    519501}
    520 
    521 /*----------------------------------------------------------------------------*/
    522 
     502/*----------------------------------------------------------------------------*/
    523503void usb_mouse_deinit(usb_hid_dev_t *hid_dev, void *data)
    524504{
    525         if (data != NULL) {
    526                 usb_mouse_destroy(data);
    527         }
    528 }
    529 
    530 /*----------------------------------------------------------------------------*/
    531 
     505        if (data == NULL)
     506                return;
     507
     508        usb_mouse_t *mouse_dev = data;
     509
     510        /* Hangup session to the console */
     511        if (mouse_dev->mouse_sess != NULL) {
     512                const int ret = async_hangup(mouse_dev->mouse_sess);
     513                if (ret != EOK)
     514                        usb_log_warning("Failed to hang up mouse session: "
     515                            "%p, %s.\n", mouse_dev->mouse_sess, str_error(ret));
     516        }
     517
     518        if (mouse_dev->wheel_sess != NULL) {
     519                const int ret = async_hangup(mouse_dev->wheel_sess);
     520                if (ret != EOK)
     521                        usb_log_warning("Failed to hang up wheel session: "
     522                            "%p, %s.\n", mouse_dev->wheel_sess, str_error(ret));
     523        }
     524
     525        FUN_UNBIND_DESTROY(mouse_dev->mouse_fun);
     526        FUN_UNBIND_DESTROY(mouse_dev->wheel_fun);
     527
     528        free(mouse_dev->buttons);
     529        free(mouse_dev);
     530}
     531/*----------------------------------------------------------------------------*/
    532532int usb_mouse_set_boot_protocol(usb_hid_dev_t *hid_dev)
    533533{
    534534        int rc = usb_hid_parse_report_descriptor(
    535535            &hid_dev->report, USB_MOUSE_BOOT_REPORT_DESCRIPTOR,
    536             USB_MOUSE_BOOT_REPORT_DESCRIPTOR_SIZE);
     536            sizeof(USB_MOUSE_BOOT_REPORT_DESCRIPTOR));
    537537
    538538        if (rc != EOK) {
Note: See TracChangeset for help on using the changeset viewer.