Changes in uspace/drv/bus/usb/usbhid/mouse/mousedev.c [e3c78efc:4093b14] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/usbhid/mouse/mousedev.c
re3c78efc r4093b14 55 55 #define ARROWS_PER_SINGLE_WHEEL 3 56 56 57 #define NAME "mouse"58 59 /*----------------------------------------------------------------------------*/ 60 61 constusb_endpoint_description_t usb_hid_mouse_poll_endpoint_description = {57 #define NAME "mouse" 58 59 /*----------------------------------------------------------------------------*/ 60 61 usb_endpoint_description_t usb_hid_mouse_poll_endpoint_description = { 62 62 .transfer_type = USB_TRANSFER_INTERRUPT, 63 63 .direction = USB_DIRECTION_IN, … … 77 77 78 78 /*----------------------------------------------------------------------------*/ 79 static const uint8_t USB_MOUSE_BOOT_REPORT_DESCRIPTOR[] = { 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] = { 80 86 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 81 87 0x09, 0x02, // USAGE (Mouse) … … 117 123 ipc_callid_t icallid, ipc_call_t *icall) 118 124 { 119 usb_mouse_t *mouse_dev = fun->driver_data;120 125 usb_mouse_t *mouse_dev = (usb_mouse_t *) fun->driver_data; 126 121 127 if (mouse_dev == NULL) { 122 usb_log_debug("%s: Missing parameters.\n", __FUNCTION__); 128 usb_log_debug("default_connection_handler: Missing " 129 "parameters.\n"); 123 130 async_answer_0(icallid, EINVAL); 124 131 return; 125 132 } 126 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) ? 133 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) ? 132 141 &mouse_dev->mouse_sess : &mouse_dev->wheel_sess; 133 142 134 143 async_sess_t *sess = 135 144 async_callback_receive_start(EXCHANGE_SERIALIZE, icall); … … 137 146 if (*sess_ptr == NULL) { 138 147 *sess_ptr = sess; 139 usb_log_debug("Console session to %sset ok (%p).\n",140 fun->name,sess);148 usb_log_debug("Console session to mouse set ok (%p).\n", 149 sess); 141 150 async_answer_0(icallid, EOK); 142 151 } else { 143 usb_log_ error("Console session to %s already set.\n",144 fun->name);152 usb_log_debug("default_connection_handler: Console " 153 "session to mouse already set.\n"); 145 154 async_answer_0(icallid, ELIMIT); 146 155 } 147 156 } else { 148 usb_log_debug(" %s: Invalid function.\n", __FUNCTION__);157 usb_log_debug("default_connection_handler: Invalid function.\n"); 149 158 async_answer_0(icallid, EINVAL); 150 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); 151 188 } 152 189 … … 162 199 return; 163 200 } 164 165 const unsigned count = 166 ((wheel < 0) ? -wheel : wheel) * ARROWS_PER_SINGLE_WHEEL; 167 for (unsigned i = 0; i < count; i++) { 201 202 int count = ((wheel < 0) ? -wheel : wheel) * ARROWS_PER_SINGLE_WHEEL; 203 int i; 204 205 for (i = 0; i < count; i++) { 168 206 /* Send arrow press and release. */ 169 207 usb_log_debug2("Sending key %d to the console\n", key); … … 208 246 { 209 247 assert(mouse_dev != NULL); 210 248 211 249 if (mouse_dev->mouse_sess == NULL) { 212 250 usb_log_warning(NAME " No console session.\n"); … … 214 252 } 215 253 216 constint shift_x = get_mouse_axis_move_value(hid_dev->report_id,217 &hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_X);218 constint shift_y = get_mouse_axis_move_value(hid_dev->report_id,219 &hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_Y);220 constint wheel = get_mouse_axis_move_value(hid_dev->report_id,221 &hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_WHEEL);254 int shift_x = get_mouse_axis_move_value(hid_dev->report_id, 255 hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_X); 256 int shift_y = get_mouse_axis_move_value(hid_dev->report_id, 257 hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_Y); 258 int wheel = get_mouse_axis_move_value(hid_dev->report_id, 259 hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_WHEEL); 222 260 223 261 if ((shift_x != 0) || (shift_y != 0)) { 224 async_exch_t *exch = 225 async_exchange_begin(mouse_dev->mouse_sess); 226 if (exch != NULL) { 227 async_req_2_0(exch, MOUSEEV_MOVE_EVENT, shift_x, shift_y); 228 async_exchange_end(exch); 229 } 230 } 231 262 async_exch_t *exch = async_exchange_begin(mouse_dev->mouse_sess); 263 async_req_2_0(exch, MOUSEEV_MOVE_EVENT, shift_x, shift_y); 264 async_exchange_end(exch); 265 } 266 232 267 if (wheel != 0) 233 268 usb_mouse_send_wheel(mouse_dev, wheel); 234 235 /* Buttons */ 269 270 /* 271 * Buttons 272 */ 236 273 usb_hid_report_path_t *path = usb_hid_report_path(); 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 } 274 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_BUTTON, 0); 248 275 usb_hid_report_path_set_report_id(path, hid_dev->report_id); 249 276 250 277 usb_hid_report_field_t *field = usb_hid_report_get_sibling( 251 &hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END 252 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, USB_HID_REPORT_TYPE_INPUT); 278 hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END 279 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 280 USB_HID_REPORT_TYPE_INPUT); 253 281 254 282 while (field != NULL) { 255 283 usb_log_debug2(NAME " VALUE(%X) USAGE(%X)\n", field->value, 256 284 field->usage); 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) { 285 286 if (mouse_dev->buttons[field->usage - field->usage_minimum] == 0 287 && field->value != 0) { 262 288 async_exch_t *exch = 263 289 async_exchange_begin(mouse_dev->mouse_sess); 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) { 290 async_req_2_0(exch, MOUSEEV_BUTTON_EVENT, field->usage, 1); 291 async_exchange_end(exch); 292 293 mouse_dev->buttons[field->usage - field->usage_minimum] 294 = field->value; 295 } else if (mouse_dev->buttons[field->usage - field->usage_minimum] != 0 296 && field->value == 0) { 272 297 async_exch_t *exch = 273 298 async_exchange_begin(mouse_dev->mouse_sess); 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 } 299 async_req_2_0(exch, MOUSEEV_BUTTON_EVENT, field->usage, 0); 300 async_exchange_end(exch); 301 302 mouse_dev->buttons[field->usage - field->usage_minimum] = 303 field->value; 280 304 } 281 305 282 306 field = usb_hid_report_get_sibling( 283 &hid_dev->report, field, path, USB_HID_PATH_COMPARE_END284 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 307 hid_dev->report, field, path, USB_HID_PATH_COMPARE_END 308 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 285 309 USB_HID_REPORT_TYPE_INPUT); 286 310 } 287 311 288 312 usb_hid_report_path_free(path); 289 313 290 314 return true; 291 315 } 292 /*----------------------------------------------------------------------------*/ 293 #define FUN_UNBIND_DESTROY(fun) \ 294 if (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 /*----------------------------------------------------------------------------*/ 316 317 /*----------------------------------------------------------------------------*/ 318 304 319 static int usb_mouse_create_function(usb_hid_dev_t *hid_dev, usb_mouse_t *mouse) 305 320 { 306 321 assert(hid_dev != NULL); 307 322 assert(mouse != NULL); 308 323 309 324 /* Create the exposed function. */ 310 325 usb_log_debug("Creating DDF function %s...\n", HID_MOUSE_FUN_NAME); 311 ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed, 326 ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed, 312 327 HID_MOUSE_FUN_NAME); 313 328 if (fun == NULL) { 314 usb_log_error("Could not create DDF function node `%s'.\n", 315 HID_MOUSE_FUN_NAME); 329 usb_log_error("Could not create DDF function node.\n"); 316 330 return ENOMEM; 317 331 } 318 332 319 333 fun->ops = &mouse->ops; 320 334 fun->driver_data = mouse; … … 322 336 int rc = ddf_fun_bind(fun); 323 337 if (rc != EOK) { 324 usb_log_error("Could not bind DDF function `%s': %s.\n", 325 fun->name, str_error(rc)); 326 fun->driver_data = NULL; 338 usb_log_error("Could not bind DDF function: %s.\n", 339 str_error(rc)); 327 340 ddf_fun_destroy(fun); 328 341 return rc; 329 342 } 330 331 usb_log_debug("Adding DDF function `%s' to category %s...\n",332 fun->name,HID_MOUSE_CATEGORY);343 344 usb_log_debug("Adding DDF function to category %s...\n", 345 HID_MOUSE_CATEGORY); 333 346 rc = ddf_fun_add_to_category(fun, HID_MOUSE_CATEGORY); 334 347 if (rc != EOK) { … … 336 349 "Could not add DDF function to category %s: %s.\n", 337 350 HID_MOUSE_CATEGORY, str_error(rc)); 338 FUN_UNBIND_DESTROY(fun); 339 return rc; 340 } 341 mouse->mouse_fun = fun; 342 351 ddf_fun_destroy(fun); 352 return rc; 353 } 354 343 355 /* 344 356 * Special function for acting as keyboard (wheel) 345 357 */ 346 usb_log_debug("Creating DDF function %s...\n", 358 usb_log_debug("Creating DDF function %s...\n", 347 359 HID_MOUSE_WHEEL_FUN_NAME); 348 fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed, 360 fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed, 349 361 HID_MOUSE_WHEEL_FUN_NAME); 350 362 if (fun == NULL) { 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; 363 usb_log_error("Could not create DDF function node.\n"); 355 364 return ENOMEM; 356 365 } 357 366 358 367 /* 359 368 * Store the initialized HID device and HID ops … … 365 374 rc = ddf_fun_bind(fun); 366 375 if (rc != EOK) { 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; 376 usb_log_error("Could not bind DDF function: %s.\n", 377 str_error(rc)); 373 378 ddf_fun_destroy(fun); 374 379 return rc; 375 380 } 376 381 377 382 usb_log_debug("Adding DDF function to category %s...\n", 378 383 HID_MOUSE_WHEEL_CATEGORY); … … 382 387 "Could not add DDF function to category %s: %s.\n", 383 388 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); 388 return rc; 389 } 390 mouse->wheel_fun = fun; 391 389 ddf_fun_destroy(fun); 390 return rc; 391 } 392 392 393 return EOK; 393 394 } … … 434 435 return highest_button; 435 436 } 436 /*----------------------------------------------------------------------------*/ 437 438 /*----------------------------------------------------------------------------*/ 439 437 440 int usb_mouse_init(usb_hid_dev_t *hid_dev, void **data) 438 441 { 439 442 usb_log_debug("Initializing HID/Mouse structure...\n"); 440 443 441 444 if (hid_dev == NULL) { 442 445 usb_log_error("Failed to init keyboard structure: no structure" … … 444 447 return EINVAL; 445 448 } 446 447 usb_mouse_t *mouse_dev = calloc(1, sizeof(usb_mouse_t));449 450 usb_mouse_t *mouse_dev = usb_mouse_new(); 448 451 if (mouse_dev == NULL) { 449 452 usb_log_error("Error while creating USB/HID Mouse device " … … 451 454 return ENOMEM; 452 455 } 453 456 454 457 // FIXME: This may not be optimal since stupid hardware vendor may 455 458 // use buttons 1, 2, 3 and 6000 and we would allocate array of … … 458 461 // that the current solution is good enough. 459 462 /* Adding 1 because we will be accessing buttons[highest]. */ 460 mouse_dev->buttons_count = 1 + usb_mouse_get_highest_button(461 &hid_dev->report, hid_dev->report_id);463 mouse_dev->buttons_count = usb_mouse_get_highest_button(hid_dev->report, 464 hid_dev->report_id) + 1; 462 465 mouse_dev->buttons = calloc(mouse_dev->buttons_count, sizeof(int32_t)); 463 466 464 467 if (mouse_dev->buttons == NULL) { 465 468 usb_log_error(NAME ": out of memory, giving up on device!\n"); … … 468 471 } 469 472 473 474 // save the Mouse device structure into the HID device structure 475 *data = mouse_dev; 476 470 477 // set handler for incoming calls 471 478 mouse_dev->ops.default_handler = default_connection_handler; 472 479 473 480 // TODO: how to know if the device supports the request??? 474 usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe, 481 usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe, 475 482 hid_dev->usb_dev->interface_no, IDLE_RATE); 476 483 477 484 int rc = usb_mouse_create_function(hid_dev, mouse_dev); 478 485 if (rc != EOK) { 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; 486 486 usb_mouse_destroy(mouse_dev); 487 return rc; 488 } 489 487 490 return EOK; 488 491 } 489 /*----------------------------------------------------------------------------*/ 492 493 /*----------------------------------------------------------------------------*/ 494 490 495 bool usb_mouse_polling_callback(usb_hid_dev_t *hid_dev, void *data) 491 496 { 492 497 if (hid_dev == NULL || data == NULL) { 493 usb_log_error( 494 " Missing argument to the mouse polling callback.\n");498 usb_log_error("Missing argument to the mouse polling callback." 499 "\n"); 495 500 return false; 496 501 } 497 498 usb_mouse_t *mouse_dev = data;499 502 503 usb_mouse_t *mouse_dev = (usb_mouse_t *)data; 504 500 505 return usb_mouse_process_report(hid_dev, mouse_dev); 501 506 } 502 /*----------------------------------------------------------------------------*/ 507 508 /*----------------------------------------------------------------------------*/ 509 503 510 void usb_mouse_deinit(usb_hid_dev_t *hid_dev, void *data) 504 511 { 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 /*----------------------------------------------------------------------------*/ 512 if (data != NULL) { 513 usb_mouse_destroy((usb_mouse_t *)data); 514 } 515 } 516 517 /*----------------------------------------------------------------------------*/ 518 532 519 int usb_mouse_set_boot_protocol(usb_hid_dev_t *hid_dev) 533 520 { 534 int rc = usb_hid_parse_report_descriptor( 535 &hid_dev->report, USB_MOUSE_BOOT_REPORT_DESCRIPTOR,536 sizeof(USB_MOUSE_BOOT_REPORT_DESCRIPTOR));537 521 int rc = usb_hid_parse_report_descriptor(hid_dev->report, 522 USB_MOUSE_BOOT_REPORT_DESCRIPTOR, 523 USB_MOUSE_BOOT_REPORT_DESCRIPTOR_SIZE); 524 538 525 if (rc != EOK) { 539 526 usb_log_error("Failed to parse boot report descriptor: %s\n", … … 541 528 return rc; 542 529 } 543 544 rc = usbhid_req_set_protocol(&hid_dev->usb_dev->ctrl_pipe, 530 531 rc = usbhid_req_set_protocol(&hid_dev->usb_dev->ctrl_pipe, 545 532 hid_dev->usb_dev->interface_no, USB_HID_PROTOCOL_BOOT); 546 533 547 534 if (rc != EOK) { 548 535 usb_log_warning("Failed to set boot protocol to the device: " … … 550 537 return rc; 551 538 } 552 539 553 540 return EOK; 554 541 }
Note:
See TracChangeset
for help on using the changeset viewer.