Changeset 867b375 in mainline for uspace/lib/usbhost/src/ddf_helpers.c


Ignore:
Timestamp:
2017-10-15T02:04:10Z (8 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
20eaa82
Parents:
d7869d7e
Message:

hcd_ddf_new_device refactoring

This long function is now split into parts. Instead of passing dozens of arguments, it now creates the usb_dev_t right away, and uses that to pass it along. The address_device part is now modifiable by drivers.

There is still a work to be done. The biggest problem I see is in the addressing - currently, there is usb_address_t, and for high speed transaction translating there is another address. For (near) future extensibility, we should pass address as a structure. Or even better, make a way how to reference a device, maybe in a similar way how we work with endpoints.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usbhost/src/ddf_helpers.c

    rd7869d7e r867b375  
    6363        list_t devices;
    6464        fibril_mutex_t guard;
    65         ddf_fun_t *fun;
    6665        usb_address_t address;
    6766        usb_speed_t speed;
    68         usb_address_t tt_address;
    69         unsigned port;
     67        usb_tt_address_t tt;
     68
     69        /* This must be set iff the usb_dev is managed by ddf_fun. */
     70        ddf_fun_t *fun;
    7071} usb_dev_t;
    7172
     
    7374        ddf_fun_t *ctl_fun;
    7475        hcd_t hcd;
    75         usb_dev_t *root_hub;
    7676} hc_dev_t;
    7777
     
    9292
    9393
    94 static int hcd_ddf_new_device(ddf_dev_t *device, usb_dev_t *hub, unsigned port);
     94static int hcd_ddf_new_device(hcd_t *hcd, ddf_dev_t *hc, usb_dev_t *hub_dev, unsigned port);
    9595static int hcd_ddf_remove_device(ddf_dev_t *device, usb_dev_t *hub, unsigned port);
    9696
     
    127127
    128128        return hcd_add_ep(hcd, target, direction, transfer_type,
    129             max_packet_size, packets, size, dev->tt_address, dev->port);
     129            max_packet_size, packets, size, dev->tt);
    130130}
    131131
     
    180180{
    181181        assert(fun);
    182         ddf_dev_t *ddf_dev = ddf_fun_get_dev(fun);
    183         usb_dev_t *dev = ddf_fun_data_get(fun);
    184         assert(ddf_dev);
    185         assert(dev);
     182        ddf_dev_t *hc = ddf_fun_get_dev(fun);
     183        assert(hc);
     184        hcd_t *hcd = dev_to_hcd(hc);
     185        assert(hcd);
     186        usb_dev_t *hub = ddf_fun_data_get(fun);
     187        assert(hub);
     188
    186189        usb_log_debug("Hub %d reported a new USB device on port: %u\n",
    187             dev->address, port);
    188         return hcd_ddf_new_device(ddf_dev, dev, port);
     190            hub->address, port);
     191        return hcd_ddf_new_device(hcd, hc, hub, port);
    189192}
    190193
     
    291294
    292295/* DDF HELPERS */
    293 
    294 #define GET_DEVICE_DESC(size) \
    295 { \
    296         .request_type = SETUP_REQUEST_TYPE_DEVICE_TO_HOST \
    297             | (USB_REQUEST_TYPE_STANDARD << 5) \
    298             | USB_REQUEST_RECIPIENT_DEVICE, \
    299         .request = USB_DEVREQ_GET_DESCRIPTOR, \
    300         .value = uint16_host2usb(USB_DESCTYPE_DEVICE << 8), \
    301         .index = uint16_host2usb(0), \
    302         .length = uint16_host2usb(size), \
    303 };
    304 
    305 #define SET_ADDRESS(address) \
    306 { \
    307         .request_type = SETUP_REQUEST_TYPE_HOST_TO_DEVICE \
    308             | (USB_REQUEST_TYPE_STANDARD << 5) \
    309             | USB_REQUEST_RECIPIENT_DEVICE, \
    310         .request = USB_DEVREQ_SET_ADDRESS, \
    311         .value = uint16_host2usb(address), \
    312         .index = uint16_host2usb(0), \
    313         .length = uint16_host2usb(0), \
    314 };
    315 
    316 static int hcd_ddf_add_device(ddf_dev_t *parent, usb_dev_t *hub_dev,
    317     unsigned port, usb_address_t address, usb_speed_t speed, const char *name,
    318     const match_id_list_t *mids)
    319 {
    320         assert(parent);
    321 
    322         char default_name[10] = { 0 }; /* usbxyz-ss */
    323         if (!name) {
    324                 snprintf(default_name, sizeof(default_name) - 1,
    325                     "usb%u-%cs", address, usb_str_speed(speed)[0]);
    326                 name = default_name;
    327         }
    328 
    329         ddf_fun_t *fun = ddf_fun_create(parent, fun_inner, name);
    330         if (!fun)
    331                 return ENOMEM;
    332         usb_dev_t *info = ddf_fun_data_alloc(fun, sizeof(usb_dev_t));
    333         if (!info) {
    334                 ddf_fun_destroy(fun);
    335                 return ENOMEM;
    336         }
    337         info->address = address;
    338         info->speed = speed;
    339         info->fun = fun;
    340         info->port = port;
    341         info->tt_address = hub_dev ? hub_dev->tt_address : -1;
    342         link_initialize(&info->link);
    343         list_initialize(&info->devices);
    344         fibril_mutex_initialize(&info->guard);
    345 
    346         if (hub_dev && hub_dev->speed == USB_SPEED_HIGH && usb_speed_is_11(speed))
    347                 info->tt_address = hub_dev->address;
    348 
    349         ddf_fun_set_ops(fun, &usb_ops);
    350         list_foreach(mids->ids, link, const match_id_t, mid) {
    351                 ddf_fun_add_match_id(fun, mid->id, mid->score);
    352         }
    353 
    354         int ret = ddf_fun_bind(fun);
    355         if (ret != EOK) {
    356                 ddf_fun_destroy(fun);
    357                 return ret;
    358         }
    359 
    360         if (hub_dev) {
    361                 fibril_mutex_lock(&hub_dev->guard);
    362                 list_append(&info->link, &hub_dev->devices);
    363                 fibril_mutex_unlock(&hub_dev->guard);
    364         } else {
    365                 hc_dev_t *hc_dev = dev_to_hc_dev(parent);
    366                 assert(hc_dev->root_hub == NULL);
    367                 hc_dev->root_hub = info;
    368         }
    369         return EOK;
    370 }
    371296
    372297#define ADD_MATCHID_OR_RETURN(list, sc, str, ...) \
     
    416341
    417342        return EOK;
    418 
    419343}
    420344
     
    435359
    436360        list_foreach(hub->devices, link, usb_dev_t, it) {
    437                 if (it->port == port) {
     361                if (it->tt.port == port) {
    438362                        victim = it;
    439363                        break;
     
    441365        }
    442366        if (victim) {
    443                 assert(victim->port == port);
     367                assert(victim->fun);
     368                assert(victim->tt.port == port);
    444369                list_remove(&victim->link);
    445370                fibril_mutex_unlock(&hub->guard);
     
    459384}
    460385
    461 static int hcd_ddf_new_device(ddf_dev_t *device, usb_dev_t *hub, unsigned port)
    462 {
    463         assert(device);
    464 
    465         hcd_t *hcd = dev_to_hcd(device);
    466         assert(hcd);
    467 
    468         usb_speed_t speed = USB_SPEED_MAX;
    469 
    470         /* This checks whether the default address is reserved and gets speed */
    471         int ret = bus_get_speed(hcd->bus, USB_ADDRESS_DEFAULT, &speed);
    472         if (ret != EOK) {
    473                 usb_log_error("Failed to verify speed: %s.", str_error(ret));
    474                 return ret;
    475         }
    476 
    477         usb_log_debug("Found new %s speed USB device.", usb_str_speed(speed));
     386#define GET_DEVICE_DESC(size) \
     387{ \
     388        .request_type = SETUP_REQUEST_TYPE_DEVICE_TO_HOST \
     389            | (USB_REQUEST_TYPE_STANDARD << 5) \
     390            | USB_REQUEST_RECIPIENT_DEVICE, \
     391        .request = USB_DEVREQ_GET_DESCRIPTOR, \
     392        .value = uint16_host2usb(USB_DESCTYPE_DEVICE << 8), \
     393        .index = uint16_host2usb(0), \
     394        .length = uint16_host2usb(size), \
     395};
     396
     397#define SET_ADDRESS(address) \
     398{ \
     399        .request_type = SETUP_REQUEST_TYPE_HOST_TO_DEVICE \
     400            | (USB_REQUEST_TYPE_STANDARD << 5) \
     401            | USB_REQUEST_RECIPIENT_DEVICE, \
     402        .request = USB_DEVREQ_SET_ADDRESS, \
     403        .value = uint16_host2usb(address), \
     404        .index = uint16_host2usb(0), \
     405        .length = uint16_host2usb(0), \
     406};
     407
     408static int hcd_usb2_address_device(hcd_t *hcd, usb_speed_t speed,
     409    usb_tt_address_t tt, usb_address_t *out_address)
     410{
     411        int err;
    478412
    479413        static const usb_target_t default_target = {{
     
    482416        }};
    483417
     418        /** Reserve address early, we want pretty log messages */
    484419        const usb_address_t address = hcd_request_address(hcd, speed);
    485420        if (address < 0) {
     
    488423                return address;
    489424        }
    490 
    491         usb_log_debug("Reserved new address: %d\n", address);
    492 
    493         const usb_target_t target = {{
    494                 .address = address,
    495                 .endpoint = 0,
    496         }};
    497 
    498         const usb_address_t tt_address = hub ? hub->tt_address : -1;
     425        usb_log_debug("Device(%d): Reserved new address.", address);
    499426
    500427        /* Add default pipe on default address */
    501         usb_log_debug("Device(%d): Adding default target(0:0)\n", address);
    502         ret = hcd_add_ep(hcd,
     428        usb_log_debug("Device(%d): Adding default target (0:0)", address);
     429        err = hcd_add_ep(hcd,
    503430            default_target, USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL,
    504             CTRL_PIPE_MIN_PACKET_SIZE, CTRL_PIPE_MIN_PACKET_SIZE, 1,
    505             tt_address, port);
    506         if (ret != EOK) {
     431            CTRL_PIPE_MIN_PACKET_SIZE, CTRL_PIPE_MIN_PACKET_SIZE, 1, tt);
     432        if (err != EOK) {
    507433                usb_log_error("Device(%d): Failed to add default target: %s.",
    508                     address, str_error(ret));
    509                 hcd_release_address(hcd, address);
    510                 return ret;
     434                    address, str_error(err));
     435                goto err_address;
    511436        }
    512437
     
    516441            GET_DEVICE_DESC(CTRL_PIPE_MIN_PACKET_SIZE);
    517442
    518         // TODO CALLBACKS
    519443        usb_log_debug("Device(%d): Requesting first 8B of device descriptor.",
    520444            address);
     
    524448
    525449        if (got != CTRL_PIPE_MIN_PACKET_SIZE) {
    526                 ret = got < 0 ? got : EOVERFLOW;
     450                err = got < 0 ? got : EOVERFLOW;
    527451                usb_log_error("Device(%d): Failed to get 8B of dev descr: %s.",
    528                     address, str_error(ret));
    529                 hcd_remove_ep(hcd, default_target, USB_DIRECTION_BOTH);
    530                 hcd_release_address(hcd, address);
    531                 return ret;
    532         }
     452                    address, str_error(err));
     453                goto err_default_target;
     454        }
     455
     456        /* Set new address */
     457        const usb_device_request_setup_packet_t set_address = SET_ADDRESS(address);
     458
     459        usb_log_debug("Device(%d): Setting USB address.", address);
     460        err = hcd_send_batch_sync(hcd, default_target, USB_DIRECTION_OUT,
     461            NULL, 0, *(uint64_t *)&set_address, "set address");
     462        if (err != 0) {
     463                usb_log_error("Device(%d): Failed to set new address: %s.",
     464                    address, str_error(got));
     465                goto err_default_target;
     466        }
     467
     468        *out_address = address;
     469
     470        usb_target_t control_ep = {
     471                .address = address,
     472                .endpoint = 0
     473        };
    533474
    534475        /* Register EP on the new address */
    535476        usb_log_debug("Device(%d): Registering control EP.", address);
    536         ret = hcd_add_ep(hcd, target, USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL,
     477        err = hcd_add_ep(hcd, control_ep, USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL,
    537478            ED_MPS_PACKET_SIZE_GET(uint16_usb2host(desc.max_packet_size)),
    538479            ED_MPS_TRANS_OPPORTUNITIES_GET(uint16_usb2host(desc.max_packet_size)),
    539             ED_MPS_PACKET_SIZE_GET(uint16_usb2host(desc.max_packet_size)),
    540             tt_address, port);
    541         if (ret != EOK) {
     480            ED_MPS_PACKET_SIZE_GET(uint16_usb2host(desc.max_packet_size)), tt);
     481        if (err != EOK) {
    542482                usb_log_error("Device(%d): Failed to register EP0: %s",
    543                     address, str_error(ret));
    544                 hcd_remove_ep(hcd, default_target, USB_DIRECTION_BOTH);
    545                 hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH);
    546                 hcd_release_address(hcd, address);
    547                 return ret;
    548         }
    549 
    550         /* Set new address */
    551         const usb_device_request_setup_packet_t set_address =
    552             SET_ADDRESS(target.address);
    553 
    554         usb_log_debug("Device(%d): Setting USB address.", address);
    555         got = hcd_send_batch_sync(hcd, default_target, USB_DIRECTION_OUT,
    556             NULL, 0, *(uint64_t *)&set_address, "set address");
    557 
    558         usb_log_debug("Device(%d): Removing default (0:0) EP.", address);
     483                    address, str_error(err));
     484                goto err_default_target;
     485        }
     486
    559487        hcd_remove_ep(hcd, default_target, USB_DIRECTION_BOTH);
    560 
    561         if (got != 0) {
    562                 usb_log_error("Device(%d): Failed to set new address: %s.",
    563                     address, str_error(got));
    564                 hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH);
    565                 hcd_release_address(hcd, address);
    566                 return got;
    567         }
     488        return EOK;
     489
     490
     491err_default_target:
     492        hcd_remove_ep(hcd, default_target, USB_DIRECTION_BOTH);
     493err_address:
     494        hcd_release_address(hcd, address);
     495        return err;
     496}
     497
     498static int usb_dev_init(usb_dev_t *usb_dev, usb_speed_t speed)
     499{
     500        memset(usb_dev, 0, sizeof(*usb_dev));
     501
     502        link_initialize(&usb_dev->link);
     503        list_initialize(&usb_dev->devices);
     504        fibril_mutex_initialize(&usb_dev->guard);
     505
     506        usb_dev->speed = speed;
     507
     508        return EOK;
     509}
     510
     511static usb_dev_t *usb_dev_create(ddf_dev_t *hc, usb_speed_t speed)
     512{
     513        /* Create DDF function for the new device */
     514        ddf_fun_t *fun = ddf_fun_create(hc, fun_inner, NULL);
     515        if (!fun)
     516                return NULL;
     517
     518        ddf_fun_set_ops(fun, &usb_ops);
     519
     520        /* Create USB device node for the new device */
     521        usb_dev_t *usb_dev = ddf_fun_data_alloc(fun, sizeof(usb_dev_t));
     522        if (!usb_dev) {
     523                ddf_fun_destroy(fun);
     524                return NULL;
     525        }
     526
     527        usb_dev_init(usb_dev, speed);
     528        usb_dev->fun = fun;
     529        return usb_dev;
     530}
     531
     532static void usb_dev_destroy(usb_dev_t *dev)
     533{
     534        assert(dev);
     535        assert(dev->fun);
     536        ddf_fun_destroy(dev->fun);
     537}
     538
     539static int usb_dev_set_default_name(usb_dev_t *usb_dev)
     540{
     541        assert(usb_dev);
     542
     543        char buf[10] = { 0 }; /* usbxyz-ss */
     544        snprintf(buf, sizeof(buf) - 1, "usb%u-%cs",
     545            usb_dev->address, usb_str_speed(usb_dev->speed)[0]);
     546
     547        return ddf_fun_set_name(usb_dev->fun, buf);
     548}
     549
     550static int usb_dev_explore(hcd_t *hcd, usb_dev_t *usb_dev)
     551{
     552        int err;
     553        match_id_list_t mids;
     554        usb_standard_device_descriptor_t desc = { 0 };
     555
     556        init_match_ids(&mids);
     557
     558        usb_target_t control_ep = {
     559                .address = usb_dev->address,
     560                .endpoint = 0
     561        };
    568562
    569563        /* Get std device descriptor */
     
    572566
    573567        usb_log_debug("Device(%d): Requesting full device descriptor.",
    574             address);
    575         got = hcd_send_batch_sync(hcd, target, USB_DIRECTION_IN,
     568            usb_dev->address);
     569        ssize_t got = hcd_send_batch_sync(hcd, control_ep, USB_DIRECTION_IN,
    576570            &desc, sizeof(desc), *(uint64_t *)&get_device_desc,
    577571            "read device descriptor");
    578         if (ret != EOK) {
     572        if (got < 0) {
     573                err = got < 0 ? got : EOVERFLOW;
    579574                usb_log_error("Device(%d): Failed to set get dev descriptor: %s",
    580                     address, str_error(ret));
    581                 hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH);
    582                 hcd_release_address(hcd, target.address);
    583                 return ret;
     575                    usb_dev->address, str_error(err));
     576                goto out;
    584577        }
    585578
    586579        /* Create match ids from the device descriptor */
    587         match_id_list_t mids;
    588         init_match_ids(&mids);
    589 
    590         usb_log_debug("Device(%d): Creating match IDs.", address);
    591         ret = create_match_ids(&mids, &desc);
    592         if (ret != EOK) {
    593                 usb_log_error("Device(%d): Failed to create match ids: %s",
    594                     address, str_error(ret));
    595                 hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH);
    596                 hcd_release_address(hcd, target.address);
    597                 return ret;
    598         }
    599 
    600         /* Register device */
    601         usb_log_debug("Device(%d): Registering DDF device.", address);
    602         ret = hcd_ddf_add_device(device, hub, port, address, speed, NULL, &mids);
     580        usb_log_debug("Device(%d): Creating match IDs.", usb_dev->address);
     581        if ((err = create_match_ids(&mids, &desc))) {
     582                usb_log_error("Device(%d): Failed to create match ids: %s", usb_dev->address, str_error(err));
     583                goto out;
     584        }
     585
     586        list_foreach(mids.ids, link, const match_id_t, mid) {
     587                ddf_fun_add_match_id(usb_dev->fun, mid->id, mid->score);
     588        }
     589
     590out:
    603591        clean_match_ids(&mids);
    604         if (ret != EOK) {
    605                 usb_log_error("Device(%d): Failed to register: %s.",
    606                     address, str_error(ret));
    607                 hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH);
    608                 hcd_release_address(hcd, target.address);
    609         }
    610 
    611         return ret;
     592        return err;
     593}
     594
     595static int hcd_address_device(hcd_t *hcd, usb_dev_t *usb_dev)
     596{
     597        if (hcd->ops.address_device)
     598                return hcd->ops.address_device(hcd, usb_dev->speed, usb_dev->tt, &usb_dev->address);
     599        else
     600                return hcd_usb2_address_device(hcd, usb_dev->speed, usb_dev->tt, &usb_dev->address);
     601}
     602
     603static int hcd_ddf_new_device(hcd_t *hcd, ddf_dev_t *hc, usb_dev_t *hub_dev, unsigned port)
     604{
     605        int err;
     606        assert(hcd);
     607        assert(hub_dev);
     608        assert(hc);
     609
     610        usb_speed_t speed = USB_SPEED_MAX;
     611        /* The speed of the new device was reported by the hub when reserving
     612         * default address.
     613         */
     614        if ((err = bus_get_speed(hcd->bus, USB_ADDRESS_DEFAULT, &speed))) {
     615                usb_log_error("Failed to verify speed: %s.", str_error(err));
     616                return err;
     617        }
     618        usb_log_debug("Found new %s speed USB device.", usb_str_speed(speed));
     619
     620        usb_dev_t *usb_dev = usb_dev_create(hc, speed);
     621        if (!usb_dev) {
     622                usb_log_error("Failed to create USB device function.");
     623                return err;
     624        }
     625
     626        /* For devices under HS hub */
     627        /* TODO: How about SS hubs? */
     628        if (hub_dev->speed == USB_SPEED_HIGH && usb_speed_is_11(speed)) {
     629                usb_dev->tt.address = hub_dev->address;
     630        }
     631        else {
     632                /* Inherit hub's TT */
     633                usb_dev->tt.address = hub_dev->tt.address;
     634        }
     635        usb_dev->tt.port = port;
     636
     637        /* Assign an address to the device */
     638        if ((err = hcd_address_device(hcd, usb_dev))) {
     639                usb_log_error("Failed to setup address of the new device: %s", str_error(err));
     640                goto err_usb_dev;
     641        }
     642
     643        /* Read the device descriptor, derive the match ids */
     644        if ((err = usb_dev_explore(hcd, usb_dev))) {
     645                usb_log_error("Device(%d): Failed to explore device: %s", usb_dev->address, str_error(err));
     646                goto err_usb_dev;
     647        }
     648
     649        /* If the driver didn't name the device when addressing/exploring,
     650         * do it insome generic way.
     651         */
     652        if (!ddf_fun_get_name(usb_dev->fun)) {
     653                usb_dev_set_default_name(usb_dev);
     654        }
     655
     656        if ((err = ddf_fun_bind(usb_dev->fun))) {
     657                usb_log_error("Device(%d): Failed to register: %s.", usb_dev->address, str_error(err));
     658                goto err_usb_dev;
     659        }
     660
     661        fibril_mutex_lock(&hub_dev->guard);
     662        list_append(&usb_dev->link, &hub_dev->devices);
     663        fibril_mutex_unlock(&hub_dev->guard);
     664
     665        return EOK;
     666
     667err_usb_dev:
     668        usb_dev_destroy(usb_dev);
     669        return err;
    612670}
    613671
     
    617675 * @return Error code
    618676 */
    619 int hcd_setup_virtual_root_hub(ddf_dev_t *device)
    620 {
    621         assert(device);
    622         hcd_t *hcd = dev_to_hcd(device);
     677int hcd_setup_virtual_root_hub(hcd_t *hcd, ddf_dev_t *hc)
     678{
     679        int err;
     680
     681        assert(hc);
    623682        assert(hcd);
    624683
    625         hcd_reserve_default_address(hcd, USB_SPEED_MAX);
    626         const int ret = hcd_ddf_new_device(device, NULL, 0);
     684        if ((err = hcd_reserve_default_address(hcd, USB_SPEED_MAX))) {
     685                usb_log_error("Failed to reserve default address for roothub setup: %s", str_error(err));
     686                return err;
     687        }
     688
     689        usb_dev_t *usb_dev = usb_dev_create(hc, USB_SPEED_MAX);
     690        if (!usb_dev) {
     691                usb_log_error("Failed to create function for the root hub.");
     692                goto err_default_address;
     693        }
     694
     695        usb_dev->tt.address = -1;
     696        usb_dev->tt.port = 0;
     697
     698        /* Assign an address to the device */
     699        if ((err = hcd_address_device(hcd, usb_dev))) {
     700                usb_log_error("Failed to setup roothub address: %s", str_error(err));
     701                goto err_usb_dev;
     702        }
     703
     704        /* Read the device descriptor, derive the match ids */
     705        if ((err = usb_dev_explore(hcd, usb_dev))) {
     706                usb_log_error("Failed to explore roothub: %s", str_error(err));
     707                goto err_usb_dev;
     708        }
     709
     710        ddf_fun_set_name(usb_dev->fun, "roothub");
     711
     712        if ((err = ddf_fun_bind(usb_dev->fun))) {
     713                usb_log_error("Failed to register roothub: %s.", str_error(err));
     714                goto err_usb_dev;
     715        }
     716
    627717        hcd_release_default_address(hcd);
    628         return ret;
     718        return EOK;
     719
     720err_usb_dev:
     721        usb_dev_destroy(usb_dev);
     722err_default_address:
     723        hcd_release_default_address(hcd);
     724        return err;
    629725}
    630726
     
    648744                return ENOMEM;
    649745        }
    650         instance->root_hub = NULL;
    651746        hcd_init(&instance->hcd);
    652747
     
    9201015         */
    9211016        if (driver->setup_root_hub)
    922                 ret = driver->setup_root_hub(device);
     1017                ret = driver->setup_root_hub(hcd, device);
    9231018        if (ret != EOK) {
    9241019                usb_log_error("Failed to setup HC root hub: %s.\n",
     
    9471042        return ret;
    9481043}
     1044
     1045struct hcd_roothub {
     1046        hcd_t *hcd;
     1047        ddf_dev_t *hc_dev;
     1048        usb_dev_t rh_usb;
     1049};
     1050
     1051hcd_roothub_t *hcd_roothub_create(hcd_t *hcd, ddf_dev_t *dev, usb_speed_t speed)
     1052{
     1053        hcd_roothub_t *rh = malloc(sizeof(*rh));
     1054
     1055        rh->hcd = hcd;
     1056        rh->hc_dev = dev;
     1057        usb_dev_init(&rh->rh_usb, speed);
     1058
     1059        rh->rh_usb.tt.address = -1;
     1060        return rh;
     1061}
     1062
     1063int hcd_roothub_new_device(hcd_roothub_t *rh, unsigned port) {
     1064        return hcd_ddf_new_device(rh->hcd, rh->hc_dev, &rh->rh_usb, port);
     1065}
    9491066/**
    9501067 * @}
Note: See TracChangeset for help on using the changeset viewer.