Changeset 07b9cbae in mainline
- Timestamp:
- 2011-11-09T14:26:29Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f317490
- Parents:
- 90df90c
- Location:
- uspace/drv/bus/usb/usbhid
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/usbhid/subdrivers.c
r90df90c r07b9cbae 98 98 } 99 99 }, 100 {NULL, -1, 0, -1, -1, {NULL, NULL, NULL, NULL, NULL}}101 100 }; 102 101 103 const int USB_HID_MAX_SUBDRIVERS =102 const size_t USB_HID_MAX_SUBDRIVERS = 104 103 sizeof(usb_hid_subdrivers) / sizeof(usb_hid_subdrivers[0]); 105 104 -
uspace/drv/bus/usb/usbhid/subdrivers.h
r90df90c r07b9cbae 84 84 85 85 extern const usb_hid_subdriver_mapping_t usb_hid_subdrivers[]; 86 extern const int USB_HID_MAX_SUBDRIVERS;86 extern const size_t USB_HID_MAX_SUBDRIVERS; 87 87 88 88 /*----------------------------------------------------------------------------*/ -
uspace/drv/bus/usb/usbhid/usbhid.c
r90df90c r07b9cbae 60 60 NULL 61 61 }; 62 63 /*----------------------------------------------------------------------------*/ 64 62 /*----------------------------------------------------------------------------*/ 65 63 static int usb_hid_set_boot_kbd_subdriver(usb_hid_dev_t *hid_dev) 66 64 { … … 78 76 return EOK; 79 77 } 80 81 /*----------------------------------------------------------------------------*/ 82 78 /*----------------------------------------------------------------------------*/ 83 79 static int usb_hid_set_boot_mouse_subdriver(usb_hid_dev_t *hid_dev) 84 80 { … … 96 92 return EOK; 97 93 } 98 99 /*----------------------------------------------------------------------------*/ 100 94 /*----------------------------------------------------------------------------*/ 101 95 static int usb_hid_set_generic_hid_subdriver(usb_hid_dev_t *hid_dev) 102 96 { 103 assert(hid_dev != NULL && hid_dev->subdriver_count == 0); 97 assert(hid_dev != NULL); 98 assert(hid_dev->subdriver_count == 0); 104 99 105 100 hid_dev->subdrivers = malloc(sizeof(usb_hid_subdriver_t)); … … 117 112 return EOK; 118 113 } 119 120 /*----------------------------------------------------------------------------*/ 121 114 /*----------------------------------------------------------------------------*/ 122 115 static bool usb_hid_ids_match(const usb_hid_dev_t *hid_dev, 123 116 const usb_hid_subdriver_mapping_t *mapping) … … 131 124 == mapping->product_id); 132 125 } 133 134 /*----------------------------------------------------------------------------*/ 135 126 /*----------------------------------------------------------------------------*/ 136 127 static bool usb_hid_path_matches(usb_hid_dev_t *hid_dev, 137 128 const usb_hid_subdriver_mapping_t *mapping) … … 145 136 return false; 146 137 } 147 int i = 0; 148 while (mapping->usage_path[i].usage != 0149 || mapping->usage_path[i].usage_page != 0 ) {138 139 for (int i = 0; mapping->usage_path[i].usage != 0 140 || mapping->usage_path[i].usage_page != 0; ++i) { 150 141 if (usb_hid_report_path_append_item(usage_path, 151 142 mapping->usage_path[i].usage_page, … … 155 146 return false; 156 147 } 157 ++i;158 148 } 159 149 … … 165 155 do { 166 156 usb_log_debug("Trying report id %u\n", report_id); 167 168 157 if (report_id != 0) { 169 158 usb_hid_report_path_set_report_id(usage_path, … … 171 160 } 172 161 173 usb_hid_report_field_t *field = usb_hid_report_get_sibling( 174 &hid_dev->report, NULL, usage_path, mapping->compare, 175 USB_HID_REPORT_TYPE_INPUT); 162 const usb_hid_report_field_t *field = 163 usb_hid_report_get_sibling( 164 &hid_dev->report, NULL, usage_path, mapping->compare, 165 USB_HID_REPORT_TYPE_INPUT); 176 166 177 167 usb_log_debug("Field: %p\n", field); … … 190 180 return matches; 191 181 } 192 193 /*----------------------------------------------------------------------------*/ 194 182 /*----------------------------------------------------------------------------*/ 195 183 static int usb_hid_save_subdrivers(usb_hid_dev_t *hid_dev, 196 const usb_hid_subdriver_t **subdrivers, int count) 197 { 198 int i; 199 200 if (count <= 0) { 184 const usb_hid_subdriver_t **subdrivers, unsigned count) 185 { 186 assert(hid_dev); 187 assert(subdrivers); 188 189 if (count == 0) { 201 190 hid_dev->subdriver_count = 0; 202 191 hid_dev->subdrivers = NULL; … … 210 199 } 211 200 212 for (i = 0; i < count; ++i) { 213 hid_dev->subdrivers[i].init = subdrivers[i]->init; 214 hid_dev->subdrivers[i].deinit = subdrivers[i]->deinit; 215 hid_dev->subdrivers[i].poll = subdrivers[i]->poll; 216 hid_dev->subdrivers[i].poll_end = subdrivers[i]->poll_end; 201 for (unsigned i = 0; i < count; ++i) { 202 hid_dev->subdrivers[i] = *subdrivers[i]; 217 203 } 218 204 … … 227 213 return EOK; 228 214 } 229 230 /*----------------------------------------------------------------------------*/ 231 215 /*----------------------------------------------------------------------------*/ 232 216 static int usb_hid_find_subdrivers(usb_hid_dev_t *hid_dev) 233 217 { … … 235 219 236 220 const usb_hid_subdriver_t *subdrivers[USB_HID_MAX_SUBDRIVERS]; 237 238 int i = 0, count = 0; 239 const usb_hid_subdriver_mapping_t *mapping = &usb_hid_subdrivers[i]; 240 241 bool ids_matched; 242 bool matched; 243 244 while (count < USB_HID_MAX_SUBDRIVERS && 245 (mapping->usage_path != NULL 246 || mapping->vendor_id >= 0 || mapping->product_id >= 0)) { 247 // check the vendor & product ID 221 unsigned count = 0; 222 223 for (unsigned i = 0; i < USB_HID_MAX_SUBDRIVERS; ++i) { 224 const usb_hid_subdriver_mapping_t *mapping = 225 &usb_hid_subdrivers[i]; 226 /* Check the vendor & product ID. */ 248 227 if (mapping->vendor_id >= 0 && mapping->product_id < 0) { 249 usb_log_warning("Missing Product ID for Vendor ID %d\n", 250 mapping->vendor_id); 251 return EINVAL; 228 usb_log_warning("Mapping[%d]: Missing Product ID for " 229 "Vendor ID %d\n", i, mapping->vendor_id); 252 230 } 253 231 if (mapping->product_id >= 0 && mapping->vendor_id < 0) { 254 usb_log_warning("Missing Vendor ID for Product ID %d\n", 255 mapping->product_id); 256 return EINVAL; 257 } 258 259 ids_matched = false; 260 matched = false; 261 262 if (mapping->vendor_id >= 0) { 263 assert(mapping->product_id >= 0); 232 usb_log_warning("Mapping[%d]: Missing Vendor ID for " 233 "Product ID %d\n", i, mapping->product_id); 234 } 235 236 bool matched = false; 237 238 /* Check ID match. */ 239 if (mapping->vendor_id >= 0 && mapping->product_id >= 0) { 264 240 usb_log_debug("Comparing device against vendor ID %u" 265 241 " and product ID %u.\n", mapping->vendor_id, … … 267 243 if (usb_hid_ids_match(hid_dev, mapping)) { 268 244 usb_log_debug("IDs matched.\n"); 269 ids_matched = true;245 matched = true; 270 246 } 271 247 } 272 248 249 /* Check usage match. */ 273 250 if (mapping->usage_path != NULL) { 274 251 usb_log_debug("Comparing device against usage path.\n"); … … 277 254 matched = true; 278 255 } 279 } else {280 // matched only if IDs were matched and there is no path281 matched = ids_matched;282 256 } 283 257 … … 286 260 subdrivers[count++] = &mapping->subdriver; 287 261 } 288 289 mapping = &usb_hid_subdrivers[++i];290 262 } 291 263 292 264 /* We have all subdrivers determined, save them into the hid device */ 293 // TODO Do we really need this complicated stuff if there is294 // max_subdrivers limitation?295 265 return usb_hid_save_subdrivers(hid_dev, subdrivers, count); 296 266 } … … 322 292 return ENOTSUP; 323 293 } 324 325 /*----------------------------------------------------------------------------*/ 326 294 /*----------------------------------------------------------------------------*/ 327 295 static int usb_hid_init_report(usb_hid_dev_t *hid_dev) 328 296 { … … 394 362 395 363 /* Get the report descriptor and parse it. */ 396 rc = usb_hid_process_report_descriptor(hid_dev->usb_dev, 397 &hid_dev->report, &hid_dev->report_desc, &hid_dev->report_desc_size); 364 rc = usb_hid_process_report_descriptor( 365 hid_dev->usb_dev, &hid_dev->report, &hid_dev->report_desc, 366 &hid_dev->report_desc_size); 367 368 /* If report parsing went well, find subdrivers. */ 369 if (rc == EOK) { 370 usb_hid_find_subdrivers(hid_dev); 371 } else { 372 usb_log_error("Failed to parse report descriptor: fallback.\n"); 373 hid_dev->subdrivers = NULL; 374 hid_dev->subdriver_count = 0; 375 } 376 377 usb_log_debug("Subdriver count(before trying boot protocol): %d\n", 378 hid_dev->subdriver_count); 379 380 /* No subdrivers, fall back to the boot protocol if available. */ 381 if (hid_dev->subdriver_count == 0) { 382 assert(hid_dev->subdrivers == NULL); 383 usb_log_info("No subdrivers found to handle device, trying " 384 "boot protocol.\n"); 385 386 switch (hid_dev->poll_pipe_index) { 387 case USB_HID_KBD_POLL_EP_NO: 388 usb_log_info("Falling back to kbd boot protocol.\n"); 389 rc = usb_kbd_set_boot_protocol(hid_dev); 390 if (rc == EOK) { 391 usb_hid_set_boot_kbd_subdriver(hid_dev); 392 } 393 break; 394 case USB_HID_MOUSE_POLL_EP_NO: 395 usb_log_info("Falling back to mouse boot protocol.\n"); 396 rc = usb_mouse_set_boot_protocol(hid_dev); 397 if (rc == EOK) { 398 usb_hid_set_boot_mouse_subdriver(hid_dev); 399 } 400 break; 401 default: 402 assert(hid_dev->poll_pipe_index 403 == USB_HID_GENERIC_POLL_EP_NO); 404 usb_log_info("Falling back to generic HID driver.\n"); 405 usb_hid_set_generic_hid_subdriver(hid_dev); 406 } 407 } 408 409 usb_log_debug("Subdriver count(after trying boot protocol): %d\n", 410 hid_dev->subdriver_count); 411 412 /* Still no subdrivers? */ 413 if (hid_dev->subdriver_count == 0) { 414 assert(hid_dev->subdrivers == NULL); 415 usb_log_error( 416 "No subdriver for handling this device could be found.\n"); 417 return ENOTSUP; 418 } 398 419 399 420 /* … … 407 428 * pouzit usb/classes/hid/iface.h - prvy int je telefon 408 429 */ 409 410 bool fallback = false; 411 412 if (rc == EOK) { 413 // try to find subdrivers that may want to handle this device 414 rc = usb_hid_find_subdrivers(hid_dev); 415 if (rc != EOK || hid_dev->subdriver_count == 0) { 416 // try to fall back to the boot protocol if available 417 usb_log_info("No subdrivers found to handle this" 418 " device.\n"); 419 fallback = true; 420 assert(hid_dev->subdrivers == NULL); 421 assert(hid_dev->subdriver_count == 0); 422 } 423 } else { 424 usb_log_error("Failed to parse Report descriptor.\n"); 425 // try to fall back to the boot protocol if available 426 fallback = true; 427 } 428 429 if (fallback) { 430 // fall back to boot protocol 431 switch (hid_dev->poll_pipe_index) { 432 case USB_HID_KBD_POLL_EP_NO: 433 usb_log_info("Falling back to kbd boot protocol.\n"); 434 rc = usb_kbd_set_boot_protocol(hid_dev); 435 if (rc == EOK) { 436 rc = usb_hid_set_boot_kbd_subdriver(hid_dev); 437 } 438 break; 439 case USB_HID_MOUSE_POLL_EP_NO: 440 usb_log_info("Falling back to mouse boot protocol.\n"); 441 rc = usb_mouse_set_boot_protocol(hid_dev); 442 if (rc == EOK) { 443 rc = usb_hid_set_boot_mouse_subdriver(hid_dev); 444 } 445 break; 446 default: 447 assert(hid_dev->poll_pipe_index 448 == USB_HID_GENERIC_POLL_EP_NO); 449 450 usb_log_info("Falling back to generic HID driver.\n"); 451 rc = usb_hid_set_generic_hid_subdriver(hid_dev); 452 } 453 } 454 455 if (rc != EOK) { 456 usb_log_error("No subdriver for handling this device could be" 457 " initialized: %s.\n", str_error(rc)); 458 usb_log_debug("Subdriver count: %d\n", 459 hid_dev->subdriver_count); 460 } else { 461 bool ok = false; 462 463 usb_log_debug("Subdriver count: %d\n", 464 hid_dev->subdriver_count); 465 466 for (int i = 0; i < hid_dev->subdriver_count; ++i) { 467 if (hid_dev->subdrivers[i].init != NULL) { 468 usb_log_debug("Initializing subdriver %d.\n",i); 469 rc = hid_dev->subdrivers[i].init(hid_dev, 470 &hid_dev->subdrivers[i].data); 471 if (rc != EOK) { 472 usb_log_warning("Failed to initialize" 473 " HID subdriver structure.\n"); 474 } else { 475 // at least one subdriver initialized 476 ok = true; 477 } 430 bool ok = false; 431 for (int i = 0; i < hid_dev->subdriver_count; ++i) { 432 if (hid_dev->subdrivers[i].init != NULL) { 433 usb_log_debug("Initializing subdriver %d.\n",i); 434 const int pret = hid_dev->subdrivers[i].init(hid_dev, 435 &hid_dev->subdrivers[i].data); 436 if (pret != EOK) { 437 usb_log_warning("Failed to initialize" 438 " HID subdriver structure: %s.\n", 439 str_error(pret)); 440 rc = pret; 478 441 } else { 442 /* At least one subdriver initialized. */ 479 443 ok = true; 480 444 } 481 } 482 483 rc = (ok) ? EOK : -1; // what error to report 484 } 485 486 487 if (rc == EOK) { 488 // save max input report size and allocate space for the report 445 } else { 446 /* Does not need initialization. */ 447 ok = true; 448 } 449 } 450 451 if (ok) { 452 /* Save max input report size and 453 * allocate space for the report */ 489 454 rc = usb_hid_init_report(hid_dev); 490 455 if (rc != EOK) { … … 496 461 return rc; 497 462 } 498 499 /*----------------------------------------------------------------------------*/ 500 463 /*----------------------------------------------------------------------------*/ 501 464 bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer, 502 465 size_t buffer_size, void *arg)
Note:
See TracChangeset
for help on using the changeset viewer.