Changes in uspace/drv/bus/usb/usbhid/usbhid.c [2d1ba51:5f6e25e] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/usbhid/usbhid.c
r2d1ba51 r5f6e25e 51 51 #include "subdrivers.h" 52 52 53 /*----------------------------------------------------------------------------*/ 54 53 55 /* Array of endpoints expected on the device, NULL terminated. */ 54 const usb_endpoint_description_t *usb_hid_endpoints[] = {56 usb_endpoint_description_t *usb_hid_endpoints[USB_HID_POLL_EP_COUNT + 1] = { 55 57 &usb_hid_kbd_poll_endpoint_description, 56 58 &usb_hid_mouse_poll_endpoint_description, … … 58 60 NULL 59 61 }; 60 /*----------------------------------------------------------------------------*/ 62 63 static const int USB_HID_MAX_SUBDRIVERS = 10; 64 65 /*----------------------------------------------------------------------------*/ 66 61 67 static int usb_hid_set_boot_kbd_subdriver(usb_hid_dev_t *hid_dev) 62 68 { 63 assert(hid_dev != NULL );64 assert(hid_dev->subdriver_count == 0);65 66 hid_dev->subdrivers = malloc(sizeof(usb_hid_subdriver_t));69 assert(hid_dev != NULL && hid_dev->subdriver_count == 0); 70 71 hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc( 72 sizeof(usb_hid_subdriver_t)); 67 73 if (hid_dev->subdrivers == NULL) { 68 74 return ENOMEM; 69 75 } 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 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 74 95 return EOK; 75 96 } 76 /*----------------------------------------------------------------------------*/ 97 98 /*----------------------------------------------------------------------------*/ 99 77 100 static int usb_hid_set_boot_mouse_subdriver(usb_hid_dev_t *hid_dev) 78 101 { 79 assert(hid_dev != NULL );80 assert(hid_dev->subdriver_count == 0);81 82 hid_dev->subdrivers = malloc(sizeof(usb_hid_subdriver_t));102 assert(hid_dev != NULL && hid_dev->subdriver_count == 0); 103 104 hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc( 105 sizeof(usb_hid_subdriver_t)); 83 106 if (hid_dev->subdrivers == NULL) { 84 107 return ENOMEM; 85 108 } 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 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 90 128 return EOK; 91 129 } 92 /*----------------------------------------------------------------------------*/ 130 131 /*----------------------------------------------------------------------------*/ 132 93 133 static int usb_hid_set_generic_hid_subdriver(usb_hid_dev_t *hid_dev) 94 134 { 95 assert(hid_dev != NULL );96 assert(hid_dev->subdriver_count == 0);97 98 hid_dev->subdrivers = malloc(sizeof(usb_hid_subdriver_t));135 assert(hid_dev != NULL && hid_dev->subdriver_count == 0); 136 137 hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc( 138 sizeof(usb_hid_subdriver_t)); 99 139 if (hid_dev->subdrivers == NULL) { 100 140 return ENOMEM; 101 141 } 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 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 110 162 return EOK; 111 163 } 112 /*----------------------------------------------------------------------------*/ 113 static bool usb_hid_ids_match(const usb_hid_dev_t *hid_dev, 164 165 /*----------------------------------------------------------------------------*/ 166 167 static bool usb_hid_ids_match(usb_hid_dev_t *hid_dev, 114 168 const usb_hid_subdriver_mapping_t *mapping) 115 169 { 116 170 assert(hid_dev != NULL); 117 171 assert(hid_dev->usb_dev != NULL); 118 119 return (hid_dev->usb_dev->descriptors.device.vendor_id 172 173 return (hid_dev->usb_dev->descriptors.device.vendor_id 120 174 == mapping->vendor_id 121 && hid_dev->usb_dev->descriptors.device.product_id 175 && hid_dev->usb_dev->descriptors.device.product_id 122 176 == mapping->product_id); 123 177 } 124 /*----------------------------------------------------------------------------*/ 125 static bool usb_hid_path_matches(usb_hid_dev_t *hid_dev, 178 179 /*----------------------------------------------------------------------------*/ 180 181 static bool usb_hid_path_matches(usb_hid_dev_t *hid_dev, 126 182 const usb_hid_subdriver_mapping_t *mapping) 127 183 { 128 184 assert(hid_dev != NULL); 129 185 assert(mapping != NULL); 130 186 131 187 usb_hid_report_path_t *usage_path = usb_hid_report_path(); 132 188 if (usage_path == NULL) { … … 134 190 return false; 135 191 } 136 137 for (int i = 0; mapping->usage_path[i].usage != 0138 || 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, 192 int i = 0; 193 while (mapping->usage_path[i].usage != 0 194 || mapping->usage_path[i].usage_page != 0) { 195 if (usb_hid_report_path_append_item(usage_path, 196 mapping->usage_path[i].usage_page, 141 197 mapping->usage_path[i].usage) != EOK) { 142 198 usb_log_debug("Failed to append to usage path.\n"); … … 144 200 return false; 145 201 } 146 } 147 202 ++i; 203 } 204 205 assert(hid_dev->report != NULL); 206 148 207 usb_log_debug("Compare flags: %d\n", mapping->compare); 149 208 150 209 bool matches = false; 151 210 uint8_t report_id = mapping->report_id; … … 153 212 do { 154 213 usb_log_debug("Trying report id %u\n", report_id); 214 155 215 if (report_id != 0) { 156 216 usb_hid_report_path_set_report_id(usage_path, … … 158 218 } 159 219 160 const usb_hid_report_field_t *field =161 usb_hid_report_get_sibling(162 &hid_dev->report, NULL, usage_path, mapping->compare,163 164 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 165 225 usb_log_debug("Field: %p\n", field); 166 226 … … 169 229 break; 170 230 } 171 231 172 232 report_id = usb_hid_get_next_report_id( 173 &hid_dev->report, report_id, USB_HID_REPORT_TYPE_INPUT); 233 hid_dev->report, report_id, 234 USB_HID_REPORT_TYPE_INPUT); 174 235 } while (!matches && report_id != 0); 175 236 176 237 usb_hid_report_path_free(usage_path); 177 238 178 239 return matches; 179 240 } 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) { 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) { 188 250 hid_dev->subdriver_count = 0; 189 251 hid_dev->subdrivers = NULL; 190 252 return EOK; 191 253 } 192 193 /* +1 for generic hid subdriver */ 194 hid_dev->subdrivers = calloc((count + 1), sizeof(usb_hid_subdriver_t)); 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)); 195 259 if (hid_dev->subdrivers == NULL) { 196 260 return ENOMEM; 197 261 } 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 */ 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 204 270 hid_dev->subdrivers[count].init = usb_generic_hid_init; 205 271 hid_dev->subdrivers[count].poll = usb_generic_hid_polling_callback; 206 hid_dev->subdrivers[count].deinit = usb_generic_hid_deinit;272 hid_dev->subdrivers[count].deinit = NULL; 207 273 hid_dev->subdrivers[count].poll_end = NULL; 208 274 209 275 hid_dev->subdriver_count = count + 1; 210 276 211 277 return EOK; 212 278 } 213 /*----------------------------------------------------------------------------*/ 279 280 /*----------------------------------------------------------------------------*/ 281 214 282 static int usb_hid_find_subdrivers(usb_hid_dev_t *hid_dev) 215 283 { 216 284 assert(hid_dev != NULL); 217 285 218 286 const usb_hid_subdriver_t *subdrivers[USB_HID_MAX_SUBDRIVERS]; 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. */ 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 225 298 if (mapping->vendor_id >= 0 && mapping->product_id < 0) { 226 usb_log_warning("Mapping[%d]: Missing Product ID for " 227 "Vendor ID %d\n", i, mapping->vendor_id); 299 usb_log_warning("Missing Product ID for Vendor ID %d\n", 300 mapping->vendor_id); 301 return EINVAL; 228 302 } 229 303 if (mapping->product_id >= 0 && mapping->vendor_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) { 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); 238 314 usb_log_debug("Comparing device against vendor ID %u" 239 315 " and product ID %u.\n", mapping->vendor_id, … … 241 317 if (usb_hid_ids_match(hid_dev, mapping)) { 242 318 usb_log_debug("IDs matched.\n"); 243 matched = true;319 ids_matched = true; 244 320 } 245 321 } 246 247 /* Check usage match. */ 322 248 323 if (mapping->usage_path != NULL) { 249 324 usb_log_debug("Comparing device against usage path.\n"); 250 325 if (usb_hid_path_matches(hid_dev, mapping)) { 251 / * Does not matter if IDs were matched. */326 // does not matter if IDs were matched 252 327 matched = true; 253 328 } 254 } 255 329 } else { 330 // matched only if IDs were matched and there is no path 331 matched = ids_matched; 332 } 333 256 334 if (matched) { 257 335 usb_log_debug("Subdriver matched.\n"); 258 336 subdrivers[count++] = &mapping->subdriver; 259 337 } 260 } 261 262 /* We have all subdrivers determined, save them into the hid device */ 338 339 mapping = &usb_hid_subdrivers[++i]; 340 } 341 342 // we have all subdrivers determined, save them into the hid device 263 343 return usb_hid_save_subdrivers(hid_dev, subdrivers, count); 264 344 } 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 /*----------------------------------------------------------------------------*/ 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 293 377 static int usb_hid_init_report(usb_hid_dev_t *hid_dev) 294 378 { 295 assert(hid_dev != NULL );296 379 assert(hid_dev != NULL && hid_dev->report != NULL); 380 297 381 uint8_t report_id = 0; 382 size_t size; 383 298 384 size_t max_size = 0; 299 385 300 386 do { 301 387 usb_log_debug("Getting size of the report.\n"); 302 const size_t size = 303 usb_hid_report_byte_size(&hid_dev->report, report_id, 304 USB_HID_REPORT_TYPE_INPUT); 388 size = usb_hid_report_byte_size(hid_dev->report, report_id, 389 USB_HID_REPORT_TYPE_INPUT); 305 390 usb_log_debug("Report ID: %u, size: %zu\n", report_id, size); 306 391 max_size = (size > max_size) ? size : max_size; 307 392 usb_log_debug("Getting next report ID\n"); 308 report_id = usb_hid_get_next_report_id( &hid_dev->report,393 report_id = usb_hid_get_next_report_id(hid_dev->report, 309 394 report_id, USB_HID_REPORT_TYPE_INPUT); 310 395 } while (report_id != 0); 311 396 312 397 usb_log_debug("Max size of input report: %zu\n", max_size); 313 398 399 hid_dev->max_input_report_size = max_size; 314 400 assert(hid_dev->input_report == NULL); 315 316 hid_dev->input_report = calloc(1,max_size);401 402 hid_dev->input_report = malloc(max_size); 317 403 if (hid_dev->input_report == NULL) { 318 404 return ENOMEM; 319 405 } 320 hid_dev->max_input_report_size = max_size;321 406 memset(hid_dev->input_report, 0, max_size); 407 322 408 return EOK; 323 409 } 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 */ 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 342 438 int usb_hid_init(usb_hid_dev_t *hid_dev, usb_device_t *dev) 343 439 { 344 assert(hid_dev); 345 assert(dev); 346 440 int rc, i; 441 347 442 usb_log_debug("Initializing HID structure...\n"); 348 349 usb_hid_report_init(&hid_dev->report); 350 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 351 456 /* The USB device should already be initialized, save it in structure */ 352 457 hid_dev->usb_dev = dev; 353 hid_dev->poll_pipe_index = -1; 354 355 int rc = usb_hid_check_pipes(hid_dev, dev); 458 459 rc = usb_hid_check_pipes(hid_dev, dev); 356 460 if (rc != EOK) { 357 461 return rc; 358 462 } 359 463 360 464 /* Get the report descriptor and parse it. */ 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. */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 366 470 if (rc == EOK) { 367 usb_hid_find_subdrivers(hid_dev); 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 } 368 481 } else { 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 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 383 489 switch (hid_dev->poll_pipe_index) { 384 490 case USB_HID_KBD_POLL_EP_NO: … … 386 492 rc = usb_kbd_set_boot_protocol(hid_dev); 387 493 if (rc == EOK) { 388 usb_hid_set_boot_kbd_subdriver(hid_dev);494 rc = usb_hid_set_boot_kbd_subdriver(hid_dev); 389 495 } 390 496 break; … … 393 499 rc = usb_mouse_set_boot_protocol(hid_dev); 394 500 if (rc == EOK) { 395 usb_hid_set_boot_mouse_subdriver(hid_dev);501 rc = usb_hid_set_boot_mouse_subdriver(hid_dev); 396 502 } 397 503 break; 398 504 default: 399 assert(hid_dev->poll_pipe_index 505 assert(hid_dev->poll_pipe_index 400 506 == USB_HID_GENERIC_POLL_EP_NO); 507 401 508 usb_log_info("Falling back to generic HID driver.\n"); 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; 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 } 438 537 } else { 439 /* At least one subdriver initialized. */440 538 ok = true; 441 539 } 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 */ 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 451 548 rc = usb_hid_init_report(hid_dev); 452 549 if (rc != EOK) { … … 455 552 } 456 553 } 457 554 555 458 556 return rc; 459 557 } 460 /*----------------------------------------------------------------------------*/ 461 bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer, 558 559 /*----------------------------------------------------------------------------*/ 560 561 bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer, 462 562 size_t buffer_size, void *arg) 463 563 { 564 int i; 565 464 566 if (dev == NULL || arg == NULL || buffer == NULL) { 465 567 usb_log_error("Missing arguments to polling callback.\n"); 466 568 return false; 467 569 } 468 usb_hid_dev_t *hid_dev = arg; 469 570 571 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg; 572 470 573 assert(hid_dev->input_report != NULL); 471 472 574 usb_log_debug("New data [%zu/%zu]: %s\n", buffer_size, 473 575 hid_dev->max_input_report_size, … … 480 582 usb_hid_new_report(hid_dev); 481 583 } 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); 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 486 590 if (rc != EOK) { 487 591 usb_log_warning("Error in usb_hid_parse_report():" 488 592 "%s\n", str_error(rc)); 489 } 490 593 } 594 491 595 bool cont = false; 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 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 500 606 return cont; 501 607 } 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) { 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) { 511 623 if (hid_dev->subdrivers[i].poll_end != NULL) { 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 /*----------------------------------------------------------------------------*/ 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 520 634 void usb_hid_new_report(usb_hid_dev_t *hid_dev) 521 635 { 522 636 ++hid_dev->report_nr; 523 637 } 524 /*----------------------------------------------------------------------------*/ 525 int usb_hid_report_number(const usb_hid_dev_t *hid_dev) 638 639 /*----------------------------------------------------------------------------*/ 640 641 int usb_hid_report_number(usb_hid_dev_t *hid_dev) 526 642 { 527 643 return hid_dev->report_nr; 528 644 } 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 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 536 656 usb_log_debug("Subdrivers: %p, subdriver count: %d\n", 537 657 hid_dev->subdrivers, hid_dev->subdriver_count); 538 539 for (unsigned i = 0; i < hid_dev->subdriver_count; ++i) { 658 659 assert(hid_dev->subdrivers != NULL 660 || hid_dev->subdriver_count == 0); 661 662 for (i = 0; i < hid_dev->subdriver_count; ++i) { 540 663 if (hid_dev->subdrivers[i].deinit != NULL) { 541 664 hid_dev->subdrivers[i].deinit(hid_dev, … … 543 666 } 544 667 } 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 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 } 553 682 } 554 683
Note:
See TracChangeset
for help on using the changeset viewer.