Changeset 8b8c164 in mainline


Ignore:
Timestamp:
2017-10-27T15:22:06Z (7 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
58ac3ec
Parents:
7010861
Message:

libusbhost bus: endpoint→device is now managed by bus implementation

That allows xhci to better isolate responsibilities.

Location:
uspace
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/ehci/ehci_bus.c

    r7010861 r8b8c164  
    114114
    115115
    116 static int ehci_register_ep(bus_t *bus_base, endpoint_t *ep, const usb_endpoint_desc_t *desc)
     116static int ehci_register_ep(bus_t *bus_base, device_t *dev, endpoint_t *ep, const usb_endpoint_desc_t *desc)
    117117{
    118118        ehci_bus_t *bus = (ehci_bus_t *) bus_base;
     
    121121        // TODO utilize desc->usb2
    122122
    123         const int err = bus->parent_ops.register_endpoint(bus_base, ep, desc);
     123        const int err = bus->parent_ops.register_endpoint(bus_base, dev, ep, desc);
    124124        if (err)
    125125                return err;
  • uspace/drv/bus/usb/ohci/ohci_bus.c

    r7010861 r8b8c164  
    115115
    116116
    117 static int ohci_register_ep(bus_t *bus_base, endpoint_t *ep, const usb_endpoint_desc_t *desc)
     117static int ohci_register_ep(bus_t *bus_base, device_t *dev, endpoint_t *ep, const usb_endpoint_desc_t *desc)
    118118{
    119119        ohci_bus_t *bus = (ohci_bus_t *) bus_base;
    120120        ohci_endpoint_t *ohci_ep = ohci_endpoint_get(ep);
    121121
    122         const int err = bus->parent_ops.register_endpoint(bus_base, ep, desc);
     122        const int err = bus->parent_ops.register_endpoint(bus_base, dev, ep, desc);
    123123        if (err)
    124124                return err;
  • uspace/drv/bus/usb/xhci/bus.c

    r7010861 r8b8c164  
    9696        endpoint_add_ref(ep0_base);
    9797
    98         ep0_base->device = &dev->base;
    9998        xhci_endpoint_t *ep0 = xhci_endpoint_get(ep0_base);
    10099
     
    102101                goto err_ep;
    103102
     103        /* Register EP0 */
     104        if ((err = xhci_device_add_endpoint(dev, ep0)))
     105                goto err_prepared;
     106
    104107        /* Address device */
    105108        if ((err = hc_address_device(hc, dev, ep0)))
    106                 goto err_prepared_ep;
    107 
    108         /* Register EP0, passing Temporary reference */
    109         dev->endpoints[0] = ep0;
    110 
    111         return EOK;
    112 
    113 err_prepared_ep:
     109                goto err_added;
     110
     111        /* Temporary reference */
     112        endpoint_del_ref(ep0_base);
     113        return EOK;
     114
     115err_added:
     116        xhci_device_remove_endpoint(ep0);
     117err_prepared:
    114118        xhci_endpoint_free_transfer_ds(ep0);
    115119err_ep:
     120        /* Temporary reference */
    116121        endpoint_del_ref(ep0_base);
    117122err_slot:
     
    251256}
    252257
    253 static int register_endpoint(bus_t *bus_base, endpoint_t *ep, const usb_endpoint_desc_t *desc)
     258static int register_endpoint(bus_t *bus_base, device_t *device, endpoint_t *ep_base, const usb_endpoint_desc_t *desc)
    254259{
    255260        int err;
    256261        xhci_bus_t *bus = bus_to_xhci_bus(bus_base);
    257         assert(bus);
    258 
    259         assert(ep->device);
    260 
    261         xhci_device_t *xhci_dev = xhci_device_get(ep->device);
    262         xhci_endpoint_t *xhci_ep = xhci_endpoint_get(ep);
    263 
    264         if ((err = prepare_endpoint(xhci_ep, desc)))
     262        xhci_endpoint_t *ep = xhci_endpoint_get(ep_base);
     263
     264        xhci_device_t *dev = xhci_device_get(device);
     265
     266        if ((err = prepare_endpoint(ep, desc)))
    265267                return err;
    266268
    267         usb_log_info("Endpoint(%d:%d) registered to XHCI bus.", ep->device->address, ep->endpoint);
    268         return xhci_device_add_endpoint(bus->hc, xhci_dev, xhci_ep);
    269 }
    270 
    271 static int unregister_endpoint(bus_t *bus_base, endpoint_t *ep)
    272 {
     269        if ((err = xhci_device_add_endpoint(dev, ep)))
     270                goto err_prepared;
     271
     272        usb_log_info("Endpoint(%d:%d) registered to XHCI bus.", dev->base.address, ep->base.endpoint);
     273
     274        xhci_ep_ctx_t ep_ctx;
     275        xhci_setup_endpoint_context(ep, &ep_ctx);
     276
     277        if ((err = hc_add_endpoint(bus->hc, dev->slot_id, xhci_endpoint_index(ep), &ep_ctx)))
     278                goto err_added;
     279
     280        return EOK;
     281
     282err_added:
     283        xhci_device_remove_endpoint(ep);
     284err_prepared:
     285        xhci_endpoint_free_transfer_ds(ep);
     286        return err;
     287}
     288
     289static int unregister_endpoint(bus_t *bus_base, endpoint_t *ep_base)
     290{
     291        int err;
    273292        xhci_bus_t *bus = bus_to_xhci_bus(bus_base);
    274         assert(bus);
    275 
    276         usb_log_info("Endpoint(%d:%d) unregistered from XHCI bus.", ep->device->address, ep->endpoint);
    277 
    278         xhci_device_t *xhci_dev = xhci_device_get(ep->device);
    279         xhci_endpoint_t *xhci_ep = xhci_endpoint_get(ep);
    280         const int res = xhci_device_remove_endpoint(bus->hc, xhci_dev, xhci_ep);
    281         if (res != EOK)
    282                 return res;
     293        xhci_endpoint_t *ep = xhci_endpoint_get(ep_base);
     294        xhci_device_t *dev = xhci_device_get(ep_base->device);
     295
     296        usb_log_info("Endpoint(%d:%d) unregistered from XHCI bus.", dev->base.address, ep->base.endpoint);
     297
     298        xhci_device_remove_endpoint(ep);
     299
     300        /* Drop the endpoint. */
     301        if ((err = hc_drop_endpoint(bus->hc, dev->slot_id, xhci_endpoint_index(ep)))) {
     302                usb_log_error("Failed to drop endpoint: %s", str_error(err));
     303        }
     304
     305        /* Tear down TRB ring / PSA. */
     306        /* TODO: Make this method "noexcept" */
     307        if ((err = xhci_endpoint_free_transfer_ds(ep))) {
     308                usb_log_error("Failed to free resources of an endpoint.");
     309        }
    283310
    284311        return EOK;
  • uspace/drv/bus/usb/xhci/endpoint.c

    r7010861 r8b8c164  
    189189{
    190190
    191         usb_log_debug2("Allocating main transfer ring for endpoint " XHCI_EP_FMT, XHCI_EP_ARGS(*xhci_ep));
     191        usb_log_debug2("Allocating main transfer ring for endpoint %u", xhci_ep->base.endpoint);
    192192
    193193        xhci_ep->primary_stream_ctx_array = NULL;
     
    323323}
    324324
    325 int xhci_device_add_endpoint(xhci_hc_t *hc, xhci_device_t *dev, xhci_endpoint_t *ep)
     325int xhci_device_add_endpoint(xhci_device_t *dev, xhci_endpoint_t *ep)
    326326{
    327327        assert(dev);
     
    329329
    330330        /* Offline devices don't create new endpoints other than EP0. */
    331         if (!dev->online) {
     331        if (!dev->online && ep->base.endpoint > 0) {
    332332                return EAGAIN;
    333333        }
     
    335335        const usb_endpoint_t ep_num = ep->base.endpoint;
    336336
    337         assert(&dev->base == ep->base.device);
    338 
    339         // TODO Do not fail hard on runtime conditions
    340         assert(!dev->endpoints[ep_num]);
     337        if (dev->endpoints[ep_num])
     338                return EEXIST;
     339
     340        /* Device reference */
     341        endpoint_add_ref(&ep->base);
     342        ep->base.device = &dev->base;
    341343
    342344        dev->endpoints[ep_num] = ep;
    343345        ++dev->active_endpoint_count;
    344346
    345         if (ep_num == 0) {
    346                 /* EP 0 is initialized while setting up the device,
    347                  * so we must not issue the command now. */
    348                 return EOK;
    349         }
    350 
    351         /* Add endpoint. */
    352         xhci_ep_ctx_t ep_ctx;
    353         xhci_setup_endpoint_context(ep, &ep_ctx);
    354 
    355         return hc_add_endpoint(hc, dev->slot_id, xhci_endpoint_index(ep), &ep_ctx);
    356 }
    357 
    358 int xhci_device_remove_endpoint(xhci_hc_t *hc, xhci_device_t *dev, xhci_endpoint_t *ep)
    359 {
    360         assert(&dev->base == ep->base.device);
     347        return EOK;
     348}
     349
     350void xhci_device_remove_endpoint(xhci_endpoint_t *ep)
     351{
     352        assert(ep);
     353        xhci_device_t *dev = xhci_device_get(ep->base.device);
     354
    361355        assert(dev->endpoints[ep->base.endpoint]);
    362 
    363         int err = ENOMEM;
    364         const usb_endpoint_t ep_num = ep->base.endpoint;
    365356
    366357        dev->endpoints[ep->base.endpoint] = NULL;
    367358        --dev->active_endpoint_count;
    368 
    369         if (ep_num == 0) {
    370                 /* EP 0 is finalized while releasing the device,
    371                  * so we must not issue the command now. */
    372                 return EOK;
    373         }
    374 
    375         /* Drop the endpoint. */
    376         if ((err = hc_drop_endpoint(hc, dev->slot_id, xhci_endpoint_index(ep)))) {
    377                 goto err;
    378         }
    379 
    380         /* Tear down TRB ring / PSA. */
    381         /* FIXME: For some reason, this causes crash at xhci_trb_ring_fini.
    382         if ((err = xhci_endpoint_free_transfer_ds(ep))) {
    383                 goto err_cmd;
    384         }
    385         */
    386 
    387         return EOK;
    388 
    389 err:
    390         dev->endpoints[ep_num] = ep;
    391         ++dev->active_endpoint_count;
    392         return err;
     359        ep->base.device = NULL;
     360
     361        endpoint_del_ref(&ep->base);
    393362}
    394363
  • uspace/drv/bus/usb/xhci/endpoint.h

    r7010861 r8b8c164  
    139139void xhci_setup_endpoint_context(xhci_endpoint_t *, xhci_ep_ctx_t *);
    140140
    141 int xhci_device_add_endpoint(xhci_hc_t *, xhci_device_t *, xhci_endpoint_t *);
    142 int xhci_device_remove_endpoint(xhci_hc_t *, xhci_device_t *, xhci_endpoint_t *);
     141int xhci_device_add_endpoint(xhci_device_t *, xhci_endpoint_t *);
     142void xhci_device_remove_endpoint(xhci_endpoint_t *);
    143143xhci_endpoint_t * xhci_device_get_endpoint(xhci_device_t *, usb_endpoint_t);
    144144
  • uspace/lib/c/generic/loc.c

    r7010861 r8b8c164  
    276276        sysarg_t retval = async_data_write_start(exch, fqsn, str_size(fqsn));
    277277       
    278         loc_exchange_end(exch);
    279278       
    280279        if (retval != EOK) {
    281280                async_forget(req);
     281                loc_exchange_end(exch);
    282282                return retval;
    283283        }
    284284       
    285285        async_wait_for(req, &retval);
     286        loc_exchange_end(exch);
    286287       
    287288        if (retval != EOK) {
  • uspace/lib/usbhost/include/usb/host/bus.h

    r7010861 r8b8c164  
    8484        /* The following operations are protected by a bus guard. */
    8585        endpoint_t *(*create_endpoint)(bus_t *);
    86         int (*register_endpoint)(bus_t *, endpoint_t *, const usb_endpoint_desc_t *);
     86        int (*register_endpoint)(bus_t *, device_t *, endpoint_t *, const usb_endpoint_desc_t *);
    8787        int (*unregister_endpoint)(bus_t *, endpoint_t *);
    8888        endpoint_t *(*find_endpoint)(bus_t *, device_t*, usb_target_t, usb_direction_t);
  • uspace/lib/usbhost/src/bus.c

    r7010861 r8b8c164  
    117117        endpoint_add_ref(ep);
    118118
    119         ep->device = device;
    120         if ((err = bus->ops.register_endpoint(bus, ep, desc)))
     119        if ((err = bus->ops.register_endpoint(bus, device, ep, desc)))
    121120                goto err_ep;
    122121
  • uspace/lib/usbhost/src/ddf_helpers.c

    r7010861 r8b8c164  
    519519        ddf_fun_set_name(dev->fun, "roothub");
    520520
    521         dev->tt = (usb_tt_address_t) {
    522                 .address = -1,
    523                 .port = 0,
    524         };
    525 
    526521        /* Assign an address to the device */
    527522        if ((err = bus_enumerate_device(hcd->bus, hcd, dev))) {
  • uspace/lib/usbhost/src/usb2_bus.c

    r7010861 r8b8c164  
    110110
    111111        /** Reserve address early, we want pretty log messages */
    112         const usb_address_t address = bus_reserve_default_address(bus, dev->speed);
    113         if (address < 0) {
     112        usb_address_t address;
     113        if ((err = bus_request_address(bus, &address, false, dev->speed))) {
    114114                usb_log_error("Failed to reserve new address: %s.",
    115                     str_error(address));
    116                 return address;
     115                    str_error(err));
     116                return err;
    117117        }
    118118        usb_log_debug("Device(%d): Reserved new address.", address);
     
    159159        }
    160160
     161        /* We need to remove ep before we change the address */
     162        if ((err = bus_remove_endpoint(bus, default_ep))) {
     163                usb_log_error("Device(%d): Failed to unregister default target: %s", address, str_error(err));
     164                goto err_address;
     165        }
     166        endpoint_del_ref(default_ep);
     167
    161168        dev->address = address;
    162169
     
    175182                usb_log_error("Device(%d): Failed to register EP0: %s",
    176183                    address, str_error(err));
    177                 goto err_default_control_ep;
    178         }
    179 
    180         err = bus_remove_endpoint(bus, default_ep);
    181         assert(err == EOK);
    182         endpoint_del_ref(default_ep);
    183 
    184         err = bus_release_address(bus, address);
    185         assert(err == EOK);
     184                goto err_address;
     185        }
    186186
    187187        return EOK;
     
    210210        usb_log_debug("Found new %s speed USB device.", usb_str_speed(dev->speed));
    211211
    212         /* Manage TT */
    213         if (dev->hub->speed == USB_SPEED_HIGH && usb_speed_is_11(dev->speed)) {
    214                 /* For LS devices under HS hub */
    215                 /* TODO: How about SS hubs? */
    216                 dev->tt.address = dev->hub->address;
    217                 dev->tt.port = dev->port;
     212        if (dev->hub) {
     213                /* Manage TT */
     214                if (dev->hub->speed == USB_SPEED_HIGH && usb_speed_is_11(dev->speed)) {
     215                        /* For LS devices under HS hub */
     216                        /* TODO: How about SS hubs? */
     217                        dev->tt.address = dev->hub->address;
     218                        dev->tt.port = dev->port;
     219                }
     220                else {
     221                        /* Inherit hub's TT */
     222                        dev->tt = dev->hub->tt;
     223                }
    218224        }
    219225        else {
    220                 /* Inherit hub's TT */
    221                 dev->tt = dev->hub->tt;
     226                dev->tt = (usb_tt_address_t) {
     227                        .address = -1,
     228                        .port = 0,
     229                };
    222230        }
    223231
     
    310318 * @param endpoint USB endpoint number.
    311319 */
    312 static int usb2_bus_register_ep(bus_t *bus_base, endpoint_t *ep, const usb_endpoint_desc_t *desc)
     320static int usb2_bus_register_ep(bus_t *bus_base, device_t *device, endpoint_t *ep, const usb_endpoint_desc_t *desc)
    313321{
    314322        usb2_bus_t *bus = bus_to_usb2_bus(bus_base);
    315323        assert(ep);
    316324
    317         assert(ep->device);
     325        ep->device = device;
    318326
    319327        /* Extract USB2-related information from endpoint_desc */
     
    347355        usb2_bus_t *bus = bus_to_usb2_bus(bus_base);
    348356        assert(ep);
     357
     358        list_remove(&ep->link);
     359        ep->device = NULL;
    349360
    350361        bus->free_bw += ep->bandwidth;
Note: See TracChangeset for help on using the changeset viewer.