Changeset 8e423a2d in mainline for uspace/lib/usb/src/hcdhubd.c
- Timestamp:
- 2010-11-26T21:51:36Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- ef75332
- Parents:
- da55d5b (diff), 08f747e (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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/src/hcdhubd.c
rda55d5b r8e423a2d 414 414 * @return Error code. 415 415 */ 416 int usb_hcd_add_root_hub(usb_hc_device_t *dev) { 416 int usb_hcd_add_root_hub(usb_hc_device_t *dev) 417 { 418 char *id; 419 int rc = asprintf(&id, "usb&hc=%s&hub", dev->generic->name); 420 if (rc <= 0) { 421 return rc; 422 } 423 424 rc = usb_hc_add_child_device(dev->generic, USB_HUB_DEVICE_NAME, id); 425 if (rc != EOK) { 426 free(id); 427 } 428 429 return rc; 430 } 431 432 /** Info about child device. */ 433 struct child_device_info { 434 device_t *parent; 435 const char *name; 436 const char *match_id; 437 }; 438 439 /** Adds a child device fibril worker. */ 440 static int fibril_add_child_device(void *arg) 441 { 442 struct child_device_info *child_info 443 = (struct child_device_info *) arg; 417 444 int rc; 418 445 419 /* 420 * Announce presence of child device. 421 */ 422 device_t *hub = NULL; 446 device_t *child = create_device(); 423 447 match_id_t *match_id = NULL; 424 448 425 hub = create_device(); 426 if (hub == NULL) { 449 if (child == NULL) { 427 450 rc = ENOMEM; 428 451 goto failure; 429 452 } 430 hub->name = USB_HUB_DEVICE_NAME;453 child->name = child_info->name; 431 454 432 455 match_id = create_match_id(); … … 435 458 goto failure; 436 459 } 437 438 char *id; 439 rc = asprintf(&id, "usb&hc=%s&hub", dev->generic->name); 440 if (rc <= 0) { 441 rc = ENOMEM; 442 goto failure; 443 } 444 445 match_id->id = id; 446 match_id->score = 30; 447 448 add_match_id(&hub->match_ids, match_id); 449 450 rc = child_device_register(hub, dev->generic); 460 match_id->id = child_info->match_id; 461 match_id->score = 10; 462 printf("adding child device with match \"%s\"\n", match_id->id); 463 add_match_id(&child->match_ids, match_id); 464 465 rc = child_device_register(child, child_info->parent); 451 466 if (rc != EOK) { 452 467 goto failure; 453 468 } 454 469 455 printf("%s: registered root hub\n", dev->generic->name); 470 goto leave; 471 472 failure: 473 if (child != NULL) { 474 child->name = NULL; 475 delete_device(child); 476 } 477 478 if (match_id != NULL) { 479 match_id->id = NULL; 480 delete_match_id(match_id); 481 } 482 483 leave: 484 free(arg); 485 return rc; 486 } 487 488 /** Adds a child. 489 * Due to deadlock in devman when parent registers child that oughts to be 490 * driven by the same task, the child adding is done in separate fibril. 491 * Not optimal, but it works. 492 * 493 * @param parent Parent device. 494 * @param name Device name. 495 * @param match_id Match id. 496 * @return Error code. 497 */ 498 int usb_hc_add_child_device(device_t *parent, const char *name, 499 const char *match_id) 500 { 501 struct child_device_info *child_info 502 = malloc(sizeof(struct child_device_info)); 503 504 child_info->parent = parent; 505 child_info->name = name; 506 child_info->match_id = match_id; 507 508 fid_t fibril = fibril_create(fibril_add_child_device, child_info); 509 if (!fibril) { 510 return ENOMEM; 511 } 512 fibril_add_ready(fibril); 513 456 514 return EOK; 457 458 failure:459 if (hub != NULL) {460 hub->name = NULL;461 delete_device(hub);462 }463 delete_match_id(match_id);464 465 return rc;466 515 } 467 516
Note:
See TracChangeset
for help on using the changeset viewer.