Changeset 8e423a2d in mainline for uspace/lib/usb/src/hcdhubd.c


Ignore:
Timestamp:
2010-11-26T21:51:36Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
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.
Message:

Merge with vojtechhorky/

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usb/src/hcdhubd.c

    rda55d5b r8e423a2d  
    414414 * @return Error code.
    415415 */
    416 int usb_hcd_add_root_hub(usb_hc_device_t *dev) {
     416int 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. */
     433struct 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. */
     440static int fibril_add_child_device(void *arg)
     441{
     442        struct child_device_info *child_info
     443            = (struct child_device_info *) arg;
    417444        int rc;
    418445
    419         /*
    420          * Announce presence of child device.
    421          */
    422         device_t *hub = NULL;
     446        device_t *child = create_device();
    423447        match_id_t *match_id = NULL;
    424448
    425         hub = create_device();
    426         if (hub == NULL) {
     449        if (child == NULL) {
    427450                rc = ENOMEM;
    428451                goto failure;
    429452        }
    430         hub->name = USB_HUB_DEVICE_NAME;
     453        child->name = child_info->name;
    431454
    432455        match_id = create_match_id();
     
    435458                goto failure;
    436459        }
    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);
    451466        if (rc != EOK) {
    452467                goto failure;
    453468        }
    454469
    455         printf("%s: registered root hub\n", dev->generic->name);
     470        goto leave;
     471
     472failure:
     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
     483leave:
     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 */
     498int 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
    456514        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;
    466515}
    467516
Note: See TracChangeset for help on using the changeset viewer.