Changes in uspace/drv/bus/usb/usbhid/usbhid.c [5f6e25e:2d1ba51] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/usbhid/usbhid.c
r5f6e25e r2d1ba51 51 51 #include "subdrivers.h" 52 52 53 /*----------------------------------------------------------------------------*/54 55 53 /* Array of endpoints expected on the device, NULL terminated. */ 56 usb_endpoint_description_t *usb_hid_endpoints[USB_HID_POLL_EP_COUNT + 1] = {54 const usb_endpoint_description_t *usb_hid_endpoints[] = { 57 55 &usb_hid_kbd_poll_endpoint_description, 58 56 &usb_hid_mouse_poll_endpoint_description, … … 60 58 NULL 61 59 }; 62 63 static const int USB_HID_MAX_SUBDRIVERS = 10; 64 65 /*----------------------------------------------------------------------------*/ 66 60 /*----------------------------------------------------------------------------*/ 67 61 static int usb_hid_set_boot_kbd_subdriver(usb_hid_dev_t *hid_dev) 68 62 { 69 assert(hid_dev != NULL && hid_dev->subdriver_count == 0);70 71 hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc( 72 63 assert(hid_dev != NULL); 64 assert(hid_dev->subdriver_count == 0); 65 66 hid_dev->subdrivers = malloc(sizeof(usb_hid_subdriver_t)); 73 67 if (hid_dev->subdrivers == NULL) { 74 68 return ENOMEM; 75 69 } 76 77 assert(hid_dev->subdriver_count >= 0); 78 79 // set the init callback 80 hid_dev->subdrivers[hid_dev->subdriver_count].init = usb_kbd_init; 81 82 // set the polling callback 83 hid_dev->subdrivers[hid_dev->subdriver_count].poll = 84 usb_kbd_polling_callback; 85 86 // set the polling ended callback 87 hid_dev->subdrivers[hid_dev->subdriver_count].poll_end = NULL; 88 89 // set the deinit callback 90 hid_dev->subdrivers[hid_dev->subdriver_count].deinit = usb_kbd_deinit; 91 92 // set subdriver count 93 ++hid_dev->subdriver_count; 94 70 hid_dev->subdriver_count = 1; 71 // TODO 0 should be keyboard, but find a better way 72 hid_dev->subdrivers[0] = usb_hid_subdrivers[0].subdriver; 73 95 74 return EOK; 96 75 } 97 98 /*----------------------------------------------------------------------------*/ 99 76 /*----------------------------------------------------------------------------*/ 100 77 static int usb_hid_set_boot_mouse_subdriver(usb_hid_dev_t *hid_dev) 101 78 { 102 assert(hid_dev != NULL && hid_dev->subdriver_count == 0);103 104 hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc( 105 79 assert(hid_dev != NULL); 80 assert(hid_dev->subdriver_count == 0); 81 82 hid_dev->subdrivers = malloc(sizeof(usb_hid_subdriver_t)); 106 83 if (hid_dev->subdrivers == NULL) { 107 84 return ENOMEM; 108 85 } 109 110 assert(hid_dev->subdriver_count >= 0); 111 112 // set the init callback 113 hid_dev->subdrivers[hid_dev->subdriver_count].init = usb_mouse_init; 114 115 // set the polling callback 116 hid_dev->subdrivers[hid_dev->subdriver_count].poll = 117 usb_mouse_polling_callback; 118 119 // set the polling ended callback 120 hid_dev->subdrivers[hid_dev->subdriver_count].poll_end = NULL; 121 122 // set the deinit callback 123 hid_dev->subdrivers[hid_dev->subdriver_count].deinit = usb_mouse_deinit; 124 125 // set subdriver count 126 ++hid_dev->subdriver_count; 127 86 hid_dev->subdriver_count = 1; 87 // TODO 2 should be mouse, but find a better way 88 hid_dev->subdrivers[0] = usb_hid_subdrivers[2].subdriver; 89 128 90 return EOK; 129 91 } 130 131 /*----------------------------------------------------------------------------*/ 132 92 /*----------------------------------------------------------------------------*/ 133 93 static int usb_hid_set_generic_hid_subdriver(usb_hid_dev_t *hid_dev) 134 94 { 135 assert(hid_dev != NULL && hid_dev->subdriver_count == 0);136 137 hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc( 138 95 assert(hid_dev != NULL); 96 assert(hid_dev->subdriver_count == 0); 97 98 hid_dev->subdrivers = malloc(sizeof(usb_hid_subdriver_t)); 139 99 if (hid_dev->subdrivers == NULL) { 140 100 return ENOMEM; 141 101 } 142 143 assert(hid_dev->subdriver_count >= 0); 144 145 // set the init callback 146 hid_dev->subdrivers[hid_dev->subdriver_count].init = 147 usb_generic_hid_init; 148 149 // set the polling callback 150 hid_dev->subdrivers[hid_dev->subdriver_count].poll = 151 usb_generic_hid_polling_callback; 152 153 // set the polling ended callback 154 hid_dev->subdrivers[hid_dev->subdriver_count].poll_end = NULL; 155 156 // set the deinit callback 157 hid_dev->subdrivers[hid_dev->subdriver_count].deinit = NULL; 158 159 // set subdriver count 160 ++hid_dev->subdriver_count; 161 102 hid_dev->subdriver_count = 1; 103 104 /* Set generic hid subdriver routines */ 105 hid_dev->subdrivers[0].init = usb_generic_hid_init; 106 hid_dev->subdrivers[0].poll = usb_generic_hid_polling_callback; 107 hid_dev->subdrivers[0].poll_end = NULL; 108 hid_dev->subdrivers[0].deinit = usb_generic_hid_deinit; 109 162 110 return EOK; 163 111 } 164 165 /*----------------------------------------------------------------------------*/ 166 167 static bool usb_hid_ids_match(usb_hid_dev_t *hid_dev, 112 /*----------------------------------------------------------------------------*/ 113 static bool usb_hid_ids_match(const usb_hid_dev_t *hid_dev, 168 114 const usb_hid_subdriver_mapping_t *mapping) 169 115 { 170 116 assert(hid_dev != NULL); 171 117 assert(hid_dev->usb_dev != NULL); 172 173 return (hid_dev->usb_dev->descriptors.device.vendor_id 118 119 return (hid_dev->usb_dev->descriptors.device.vendor_id 174 120 == mapping->vendor_id 175 && hid_dev->usb_dev->descriptors.device.product_id 121 && hid_dev->usb_dev->descriptors.device.product_id 176 122 == mapping->product_id); 177 123 } 178 179 /*----------------------------------------------------------------------------*/ 180 181 static bool usb_hid_path_matches(usb_hid_dev_t *hid_dev, 124 /*----------------------------------------------------------------------------*/ 125 static bool usb_hid_path_matches(usb_hid_dev_t *hid_dev, 182 126 const usb_hid_subdriver_mapping_t *mapping) 183 127 { 184 128 assert(hid_dev != NULL); 185 129 assert(mapping != NULL); 186 130 187 131 usb_hid_report_path_t *usage_path = usb_hid_report_path(); 188 132 if (usage_path == NULL) { … … 190 134 return false; 191 135 } 192 int i = 0; 193 while (mapping->usage_path[i].usage != 0194 || mapping->usage_path[i].usage_page != 0 ) {195 if (usb_hid_report_path_append_item(usage_path, 196 mapping->usage_path[i].usage_page, 136 137 for (int i = 0; mapping->usage_path[i].usage != 0 138 || mapping->usage_path[i].usage_page != 0; ++i) { 139 if (usb_hid_report_path_append_item(usage_path, 140 mapping->usage_path[i].usage_page, 197 141 mapping->usage_path[i].usage) != EOK) { 198 142 usb_log_debug("Failed to append to usage path.\n"); … … 200 144 return false; 201 145 } 202 ++i; 203 } 204 205 assert(hid_dev->report != NULL); 206 146 } 147 207 148 usb_log_debug("Compare flags: %d\n", mapping->compare); 208 149 209 150 bool matches = false; 210 151 uint8_t report_id = mapping->report_id; … … 212 153 do { 213 154 usb_log_debug("Trying report id %u\n", report_id); 214 215 155 if (report_id != 0) { 216 156 usb_hid_report_path_set_report_id(usage_path, … … 218 158 } 219 159 220 usb_hid_report_field_t *field = usb_hid_report_get_sibling(221 hid_dev->report,222 NULL, usage_path, mapping->compare,223 USB_HID_REPORT_TYPE_INPUT);224 160 const usb_hid_report_field_t *field = 161 usb_hid_report_get_sibling( 162 &hid_dev->report, NULL, usage_path, mapping->compare, 163 USB_HID_REPORT_TYPE_INPUT); 164 225 165 usb_log_debug("Field: %p\n", field); 226 166 … … 229 169 break; 230 170 } 231 171 232 172 report_id = usb_hid_get_next_report_id( 233 hid_dev->report, report_id, 234 USB_HID_REPORT_TYPE_INPUT); 173 &hid_dev->report, report_id, USB_HID_REPORT_TYPE_INPUT); 235 174 } while (!matches && report_id != 0); 236 175 237 176 usb_hid_report_path_free(usage_path); 238 177 239 178 return matches; 240 179 } 241 242 /*----------------------------------------------------------------------------*/ 243 244 static int usb_hid_save_subdrivers(usb_hid_dev_t *hid_dev, 245 const usb_hid_subdriver_t **subdrivers, int count) 246 { 247 int i; 248 249 if (count <= 0) { 180 /*----------------------------------------------------------------------------*/ 181 static int usb_hid_save_subdrivers(usb_hid_dev_t *hid_dev, 182 const usb_hid_subdriver_t **subdrivers, unsigned count) 183 { 184 assert(hid_dev); 185 assert(subdrivers); 186 187 if (count == 0) { 250 188 hid_dev->subdriver_count = 0; 251 189 hid_dev->subdrivers = NULL; 252 190 return EOK; 253 191 } 254 255 // add one generic HID subdriver per device 256 257 hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc((count + 1) * 258 sizeof(usb_hid_subdriver_t)); 192 193 /* +1 for generic hid subdriver */ 194 hid_dev->subdrivers = calloc((count + 1), sizeof(usb_hid_subdriver_t)); 259 195 if (hid_dev->subdrivers == NULL) { 260 196 return ENOMEM; 261 197 } 262 263 for (i = 0; i < count; ++i) { 264 hid_dev->subdrivers[i].init = subdrivers[i]->init; 265 hid_dev->subdrivers[i].deinit = subdrivers[i]->deinit; 266 hid_dev->subdrivers[i].poll = subdrivers[i]->poll; 267 hid_dev->subdrivers[i].poll_end = subdrivers[i]->poll_end; 268 } 269 198 199 for (unsigned i = 0; i < count; ++i) { 200 hid_dev->subdrivers[i] = *subdrivers[i]; 201 } 202 203 /* Add one generic HID subdriver per device */ 270 204 hid_dev->subdrivers[count].init = usb_generic_hid_init; 271 205 hid_dev->subdrivers[count].poll = usb_generic_hid_polling_callback; 272 hid_dev->subdrivers[count].deinit = NULL;206 hid_dev->subdrivers[count].deinit = usb_generic_hid_deinit; 273 207 hid_dev->subdrivers[count].poll_end = NULL; 274 208 275 209 hid_dev->subdriver_count = count + 1; 276 210 277 211 return EOK; 278 212 } 279 280 /*----------------------------------------------------------------------------*/ 281 213 /*----------------------------------------------------------------------------*/ 282 214 static int usb_hid_find_subdrivers(usb_hid_dev_t *hid_dev) 283 215 { 284 216 assert(hid_dev != NULL); 285 217 286 218 const usb_hid_subdriver_t *subdrivers[USB_HID_MAX_SUBDRIVERS]; 287 288 int i = 0, count = 0; 289 const usb_hid_subdriver_mapping_t *mapping = &usb_hid_subdrivers[i]; 290 291 bool ids_matched; 292 bool matched; 293 294 while (count < USB_HID_MAX_SUBDRIVERS && 295 (mapping->usage_path != NULL 296 || mapping->vendor_id >= 0 || mapping->product_id >= 0)) { 297 // check the vendor & product ID 219 unsigned count = 0; 220 221 for (unsigned i = 0; i < USB_HID_MAX_SUBDRIVERS; ++i) { 222 const usb_hid_subdriver_mapping_t *mapping = 223 &usb_hid_subdrivers[i]; 224 /* Check the vendor & product ID. */ 298 225 if (mapping->vendor_id >= 0 && mapping->product_id < 0) { 299 usb_log_warning("Missing Product ID for Vendor ID %d\n", 300 mapping->vendor_id); 301 return EINVAL; 226 usb_log_warning("Mapping[%d]: Missing Product ID for " 227 "Vendor ID %d\n", i, mapping->vendor_id); 302 228 } 303 229 if (mapping->product_id >= 0 && mapping->vendor_id < 0) { 304 usb_log_warning("Missing Vendor ID for Product ID %d\n", 305 mapping->product_id); 306 return EINVAL; 307 } 308 309 ids_matched = false; 310 matched = false; 311 312 if (mapping->vendor_id >= 0) { 313 assert(mapping->product_id >= 0); 230 usb_log_warning("Mapping[%d]: Missing Vendor ID for " 231 "Product ID %d\n", i, mapping->product_id); 232 } 233 234 bool matched = false; 235 236 /* Check ID match. */ 237 if (mapping->vendor_id >= 0 && mapping->product_id >= 0) { 314 238 usb_log_debug("Comparing device against vendor ID %u" 315 239 " and product ID %u.\n", mapping->vendor_id, … … 317 241 if (usb_hid_ids_match(hid_dev, mapping)) { 318 242 usb_log_debug("IDs matched.\n"); 319 ids_matched = true;243 matched = true; 320 244 } 321 245 } 322 246 247 /* Check usage match. */ 323 248 if (mapping->usage_path != NULL) { 324 249 usb_log_debug("Comparing device against usage path.\n"); 325 250 if (usb_hid_path_matches(hid_dev, mapping)) { 326 / / does not matter if IDs were matched251 /* Does not matter if IDs were matched. */ 327 252 matched = true; 328 253 } 329 } else { 330 // matched only if IDs were matched and there is no path 331 matched = ids_matched; 332 } 333 254 } 255 334 256 if (matched) { 335 257 usb_log_debug("Subdriver matched.\n"); 336 258 subdrivers[count++] = &mapping->subdriver; 337 259 } 338 339 mapping = &usb_hid_subdrivers[++i]; 340 } 341 342 // we have all subdrivers determined, save them into the hid device 260 } 261 262 /* We have all subdrivers determined, save them into the hid device */ 343 263 return usb_hid_save_subdrivers(hid_dev, subdrivers, count); 344 264 } 345 346 /*----------------------------------------------------------------------------*/ 347 348 static int usb_hid_check_pipes(usb_hid_dev_t *hid_dev, usb_device_t *dev) 349 { 350 assert(hid_dev != NULL && dev != NULL); 351 352 int rc = EOK; 353 354 if (dev->pipes[USB_HID_KBD_POLL_EP_NO].present) { 355 usb_log_debug("Found keyboard endpoint.\n"); 356 // save the pipe index 357 hid_dev->poll_pipe_index = USB_HID_KBD_POLL_EP_NO; 358 } else if (dev->pipes[USB_HID_MOUSE_POLL_EP_NO].present) { 359 usb_log_debug("Found mouse endpoint.\n"); 360 // save the pipe index 361 hid_dev->poll_pipe_index = USB_HID_MOUSE_POLL_EP_NO; 362 } else if (dev->pipes[USB_HID_GENERIC_POLL_EP_NO].present) { 363 usb_log_debug("Found generic HID endpoint.\n"); 364 // save the pipe index 365 hid_dev->poll_pipe_index = USB_HID_GENERIC_POLL_EP_NO; 366 } else { 367 usb_log_error("None of supported endpoints found - probably" 368 " not a supported device.\n"); 369 rc = ENOTSUP; 370 } 371 372 return rc; 373 } 374 375 /*----------------------------------------------------------------------------*/ 376 265 /*----------------------------------------------------------------------------*/ 266 static int usb_hid_check_pipes(usb_hid_dev_t *hid_dev, const usb_device_t *dev) 267 { 268 assert(hid_dev); 269 assert(dev); 270 271 static const struct { 272 unsigned ep_number; 273 const char* description; 274 } endpoints[] = { 275 {USB_HID_KBD_POLL_EP_NO, "Keyboard endpoint"}, 276 {USB_HID_MOUSE_POLL_EP_NO, "Mouse endpoint"}, 277 {USB_HID_GENERIC_POLL_EP_NO, "Generic HID endpoint"}, 278 }; 279 280 for (unsigned i = 0; i < sizeof(endpoints)/sizeof(endpoints[0]); ++i) { 281 if (endpoints[i].ep_number >= dev->pipes_count) { 282 return EINVAL; 283 } 284 if (dev->pipes[endpoints[i].ep_number].present) { 285 usb_log_debug("Found: %s.\n", endpoints[i].description); 286 hid_dev->poll_pipe_index = endpoints[i].ep_number; 287 return EOK; 288 } 289 } 290 return ENOTSUP; 291 } 292 /*----------------------------------------------------------------------------*/ 377 293 static int usb_hid_init_report(usb_hid_dev_t *hid_dev) 378 294 { 379 assert(hid_dev != NULL && hid_dev->report != NULL);380 295 assert(hid_dev != NULL); 296 381 297 uint8_t report_id = 0; 382 size_t size;383 384 298 size_t max_size = 0; 385 299 386 300 do { 387 301 usb_log_debug("Getting size of the report.\n"); 388 size = usb_hid_report_byte_size(hid_dev->report, report_id, 389 USB_HID_REPORT_TYPE_INPUT); 302 const size_t size = 303 usb_hid_report_byte_size(&hid_dev->report, report_id, 304 USB_HID_REPORT_TYPE_INPUT); 390 305 usb_log_debug("Report ID: %u, size: %zu\n", report_id, size); 391 306 max_size = (size > max_size) ? size : max_size; 392 307 usb_log_debug("Getting next report ID\n"); 393 report_id = usb_hid_get_next_report_id( hid_dev->report,308 report_id = usb_hid_get_next_report_id(&hid_dev->report, 394 309 report_id, USB_HID_REPORT_TYPE_INPUT); 395 310 } while (report_id != 0); 396 311 397 312 usb_log_debug("Max size of input report: %zu\n", max_size); 398 399 hid_dev->max_input_report_size = max_size; 313 400 314 assert(hid_dev->input_report == NULL); 401 402 hid_dev->input_report = malloc(max_size);315 316 hid_dev->input_report = calloc(1, max_size); 403 317 if (hid_dev->input_report == NULL) { 404 318 return ENOMEM; 405 319 } 406 memset(hid_dev->input_report, 0, max_size);407 320 hid_dev->max_input_report_size = max_size; 321 408 322 return EOK; 409 323 } 410 411 /*----------------------------------------------------------------------------*/ 412 413 usb_hid_dev_t *usb_hid_new(void) 414 { 415 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)calloc(1, 416 sizeof(usb_hid_dev_t)); 417 418 if (hid_dev == NULL) { 419 usb_log_fatal("No memory!\n"); 420 return NULL; 421 } 422 423 hid_dev->report = (usb_hid_report_t *)(malloc(sizeof( 424 usb_hid_report_t))); 425 if (hid_dev->report == NULL) { 426 usb_log_fatal("No memory!\n"); 427 free(hid_dev); 428 return NULL; 429 } 430 431 hid_dev->poll_pipe_index = -1; 432 433 return hid_dev; 434 } 435 436 /*----------------------------------------------------------------------------*/ 437 324 /*----------------------------------------------------------------------------*/ 325 /* 326 * This functions initializes required structures from the device's descriptors 327 * and starts new fibril for polling the keyboard for events and another one for 328 * handling auto-repeat of keys. 329 * 330 * During initialization, the keyboard is switched into boot protocol, the idle 331 * rate is set to 0 (infinity), resulting in the keyboard only reporting event 332 * when a key is pressed or released. Finally, the LED lights are turned on 333 * according to the default setup of lock keys. 334 * 335 * @note By default, the keyboards is initialized with Num Lock turned on and 336 * other locks turned off. 337 * 338 * @param hid_dev Device to initialize, non-NULL. 339 * @param dev USB device, non-NULL. 340 * @return Error code. 341 */ 438 342 int usb_hid_init(usb_hid_dev_t *hid_dev, usb_device_t *dev) 439 343 { 440 int rc, i; 441 344 assert(hid_dev); 345 assert(dev); 346 442 347 usb_log_debug("Initializing HID structure...\n"); 443 444 if (hid_dev == NULL) { 445 usb_log_error("Failed to init HID structure: no structure given" 446 ".\n"); 447 return EINVAL; 448 } 449 450 if (dev == NULL) { 451 usb_log_error("Failed to init HID structure: no USB device" 452 " given.\n"); 453 return EINVAL; 454 } 455 348 349 usb_hid_report_init(&hid_dev->report); 350 456 351 /* The USB device should already be initialized, save it in structure */ 457 352 hid_dev->usb_dev = dev; 458 459 rc = usb_hid_check_pipes(hid_dev, dev); 353 hid_dev->poll_pipe_index = -1; 354 355 int rc = usb_hid_check_pipes(hid_dev, dev); 460 356 if (rc != EOK) { 461 357 return rc; 462 358 } 463 359 464 360 /* Get the report descriptor and parse it. */ 465 rc = usb_hid_process_report_descriptor( hid_dev->usb_dev,466 hid_dev-> report, &hid_dev->report_desc, &hid_dev->report_desc_size);467 468 bool fallback = false; 469 361 rc = usb_hid_process_report_descriptor( 362 hid_dev->usb_dev, &hid_dev->report, &hid_dev->report_desc, 363 &hid_dev->report_desc_size); 364 365 /* If report parsing went well, find subdrivers. */ 470 366 if (rc == EOK) { 471 // try to find subdrivers that may want to handle this device 472 rc = usb_hid_find_subdrivers(hid_dev); 473 if (rc != EOK || hid_dev->subdriver_count == 0) { 474 // try to fall back to the boot protocol if available 475 usb_log_info("No subdrivers found to handle this" 476 " device.\n"); 477 fallback = true; 478 assert(hid_dev->subdrivers == NULL); 479 assert(hid_dev->subdriver_count == 0); 480 } 367 usb_hid_find_subdrivers(hid_dev); 481 368 } else { 482 usb_log_error("Failed to parse Report descriptor.\n"); 483 // try to fall back to the boot protocol if available 484 fallback = true; 485 } 486 487 if (fallback) { 488 // fall back to boot protocol 369 usb_log_error("Failed to parse report descriptor: fallback.\n"); 370 hid_dev->subdrivers = NULL; 371 hid_dev->subdriver_count = 0; 372 } 373 374 usb_log_debug("Subdriver count(before trying boot protocol): %d\n", 375 hid_dev->subdriver_count); 376 377 /* No subdrivers, fall back to the boot protocol if available. */ 378 if (hid_dev->subdriver_count == 0) { 379 assert(hid_dev->subdrivers == NULL); 380 usb_log_info("No subdrivers found to handle device, trying " 381 "boot protocol.\n"); 382 489 383 switch (hid_dev->poll_pipe_index) { 490 384 case USB_HID_KBD_POLL_EP_NO: … … 492 386 rc = usb_kbd_set_boot_protocol(hid_dev); 493 387 if (rc == EOK) { 494 rc =usb_hid_set_boot_kbd_subdriver(hid_dev);388 usb_hid_set_boot_kbd_subdriver(hid_dev); 495 389 } 496 390 break; … … 499 393 rc = usb_mouse_set_boot_protocol(hid_dev); 500 394 if (rc == EOK) { 501 rc =usb_hid_set_boot_mouse_subdriver(hid_dev);395 usb_hid_set_boot_mouse_subdriver(hid_dev); 502 396 } 503 397 break; 504 398 default: 505 assert(hid_dev->poll_pipe_index 399 assert(hid_dev->poll_pipe_index 506 400 == USB_HID_GENERIC_POLL_EP_NO); 507 508 401 usb_log_info("Falling back to generic HID driver.\n"); 509 rc = usb_hid_set_generic_hid_subdriver(hid_dev); 510 } 511 } 512 513 if (rc != EOK) { 514 usb_log_error("No subdriver for handling this device could be" 515 " initialized: %s.\n", str_error(rc)); 516 usb_log_debug("Subdriver count: %d\n", 517 hid_dev->subdriver_count); 518 519 } else { 520 bool ok = false; 521 522 usb_log_debug("Subdriver count: %d\n", 523 hid_dev->subdriver_count); 524 525 for (i = 0; i < hid_dev->subdriver_count; ++i) { 526 if (hid_dev->subdrivers[i].init != NULL) { 527 usb_log_debug("Initializing subdriver %d.\n",i); 528 rc = hid_dev->subdrivers[i].init(hid_dev, 529 &hid_dev->subdrivers[i].data); 530 if (rc != EOK) { 531 usb_log_warning("Failed to initialize" 532 " HID subdriver structure.\n"); 533 } else { 534 // at least one subdriver initialized 535 ok = true; 536 } 402 usb_hid_set_generic_hid_subdriver(hid_dev); 403 } 404 } 405 406 usb_log_debug("Subdriver count(after trying boot protocol): %d\n", 407 hid_dev->subdriver_count); 408 409 /* Still no subdrivers? */ 410 if (hid_dev->subdriver_count == 0) { 411 assert(hid_dev->subdrivers == NULL); 412 usb_log_error( 413 "No subdriver for handling this device could be found.\n"); 414 return ENOTSUP; 415 } 416 417 /* 418 * 1) subdriver vytvori vlastnu ddf_fun, vlastne ddf_dev_ops, ktore da 419 * do nej. 420 * 2) do tych ops do .interfaces[DEV_IFACE_USBHID (asi)] priradi 421 * vyplnenu strukturu usbhid_iface_t. 422 * 3) klientska aplikacia - musi si rucne vytvorit telefon 423 * (devman_device_connect() - cesta k zariadeniu (/hw/pci0/...) az 424 * k tej fcii. 425 * pouzit usb/classes/hid/iface.h - prvy int je telefon 426 */ 427 bool ok = false; 428 for (unsigned i = 0; i < hid_dev->subdriver_count; ++i) { 429 if (hid_dev->subdrivers[i].init != NULL) { 430 usb_log_debug("Initializing subdriver %d.\n",i); 431 const int pret = hid_dev->subdrivers[i].init(hid_dev, 432 &hid_dev->subdrivers[i].data); 433 if (pret != EOK) { 434 usb_log_warning("Failed to initialize" 435 " HID subdriver structure: %s.\n", 436 str_error(pret)); 437 rc = pret; 537 438 } else { 439 /* At least one subdriver initialized. */ 538 440 ok = true; 539 441 } 540 } 541 542 rc = (ok) ? EOK : -1; // what error to report 543 } 544 545 546 if (rc == EOK) { 547 // save max input report size and allocate space for the report 442 } else { 443 /* Does not need initialization. */ 444 ok = true; 445 } 446 } 447 448 if (ok) { 449 /* Save max input report size and 450 * allocate space for the report */ 548 451 rc = usb_hid_init_report(hid_dev); 549 452 if (rc != EOK) { … … 552 455 } 553 456 } 554 555 457 556 458 return rc; 557 459 } 558 559 /*----------------------------------------------------------------------------*/ 560 561 bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer, 460 /*----------------------------------------------------------------------------*/ 461 bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer, 562 462 size_t buffer_size, void *arg) 563 463 { 564 int i;565 566 464 if (dev == NULL || arg == NULL || buffer == NULL) { 567 465 usb_log_error("Missing arguments to polling callback.\n"); 568 466 return false; 569 467 } 570 571 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg; 572 468 usb_hid_dev_t *hid_dev = arg; 469 573 470 assert(hid_dev->input_report != NULL); 471 574 472 usb_log_debug("New data [%zu/%zu]: %s\n", buffer_size, 575 473 hid_dev->max_input_report_size, … … 582 480 usb_hid_new_report(hid_dev); 583 481 } 584 585 // parse the input report 586 587 int rc = usb_hid_parse_report(hid_dev->report, buffer, buffer_size, 588 &hid_dev->report_id); 589 482 483 /* Parse the input report */ 484 const int rc = usb_hid_parse_report( 485 &hid_dev->report, buffer, buffer_size, &hid_dev->report_id); 590 486 if (rc != EOK) { 591 487 usb_log_warning("Error in usb_hid_parse_report():" 592 488 "%s\n", str_error(rc)); 593 } 594 489 } 490 595 491 bool cont = false; 596 597 // continue if at least one of the subdrivers want to continue 598 for (i = 0; i < hid_dev->subdriver_count; ++i) { 599 if (hid_dev->subdrivers[i].poll != NULL 600 && hid_dev->subdrivers[i].poll(hid_dev, 601 hid_dev->subdrivers[i].data)) { 602 cont = true; 603 } 604 } 605 492 /* Continue if at least one of the subdrivers want to continue */ 493 for (unsigned i = 0; i < hid_dev->subdriver_count; ++i) { 494 if (hid_dev->subdrivers[i].poll != NULL) { 495 cont = cont || hid_dev->subdrivers[i].poll( 496 hid_dev, hid_dev->subdrivers[i].data); 497 } 498 } 499 606 500 return cont; 607 501 } 608 609 /*----------------------------------------------------------------------------*/ 610 611 void usb_hid_polling_ended_callback(usb_device_t *dev, bool reason, 612 void *arg) 613 { 614 int i; 615 616 if (dev == NULL || arg == NULL) { 617 return; 618 } 619 620 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg; 621 622 for (i = 0; i < hid_dev->subdriver_count; ++i) { 502 /*----------------------------------------------------------------------------*/ 503 void usb_hid_polling_ended_callback(usb_device_t *dev, bool reason, void *arg) 504 { 505 assert(dev); 506 assert(arg); 507 508 usb_hid_dev_t *hid_dev = arg; 509 510 for (unsigned i = 0; i < hid_dev->subdriver_count; ++i) { 623 511 if (hid_dev->subdrivers[i].poll_end != NULL) { 624 hid_dev->subdrivers[i].poll_end(hid_dev, 625 hid_dev->subdrivers[i].data, reason); 626 } 627 } 628 629 usb_hid_destroy(hid_dev); 630 } 631 632 /*----------------------------------------------------------------------------*/ 633 512 hid_dev->subdrivers[i].poll_end( 513 hid_dev, hid_dev->subdrivers[i].data, reason); 514 } 515 } 516 517 hid_dev->running = false; 518 } 519 /*----------------------------------------------------------------------------*/ 634 520 void usb_hid_new_report(usb_hid_dev_t *hid_dev) 635 521 { 636 522 ++hid_dev->report_nr; 637 523 } 638 639 /*----------------------------------------------------------------------------*/ 640 641 int usb_hid_report_number(usb_hid_dev_t *hid_dev) 524 /*----------------------------------------------------------------------------*/ 525 int usb_hid_report_number(const usb_hid_dev_t *hid_dev) 642 526 { 643 527 return hid_dev->report_nr; 644 528 } 645 646 /*----------------------------------------------------------------------------*/ 647 648 void usb_hid_destroy(usb_hid_dev_t *hid_dev) 649 { 650 int i; 651 652 if (hid_dev == NULL) { 653 return; 654 } 655 529 /*----------------------------------------------------------------------------*/ 530 void usb_hid_deinit(usb_hid_dev_t *hid_dev) 531 { 532 assert(hid_dev); 533 assert(hid_dev->subdrivers != NULL || hid_dev->subdriver_count == 0); 534 535 656 536 usb_log_debug("Subdrivers: %p, subdriver count: %d\n", 657 537 hid_dev->subdrivers, hid_dev->subdriver_count); 658 659 assert(hid_dev->subdrivers != NULL 660 || hid_dev->subdriver_count == 0); 661 662 for (i = 0; i < hid_dev->subdriver_count; ++i) { 538 539 for (unsigned i = 0; i < hid_dev->subdriver_count; ++i) { 663 540 if (hid_dev->subdrivers[i].deinit != NULL) { 664 541 hid_dev->subdrivers[i].deinit(hid_dev, … … 666 543 } 667 544 } 668 669 // free the subdrivers info 670 if (hid_dev->subdrivers != NULL) { 671 free(hid_dev->subdrivers); 672 } 673 674 // destroy the parser 675 if (hid_dev->report != NULL) { 676 usb_hid_free_report(hid_dev->report); 677 } 678 679 if (hid_dev->report_desc != NULL) { 680 free(hid_dev->report_desc); 681 } 545 546 /* Free allocated structures */ 547 free(hid_dev->subdrivers); 548 free(hid_dev->report_desc); 549 550 /* Destroy the parser */ 551 usb_hid_report_deinit(&hid_dev->report); 552 682 553 } 683 554
Note:
See TracChangeset
for help on using the changeset viewer.