Changeset 9620a54 in mainline


Ignore:
Timestamp:
2017-10-29T10:51:59Z (6 years ago)
Author:
Petr Manek <petr.manek@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
d33dc780
Parents:
62f8025
Message:

Small changes. Temporarily fixed no device problem for endpoint logging. Added similar macro for device logging. Changed log messages to adopt these macros. TRB rings can be freed again. Made ring finalizers noexcept. Upon detach, the entire slot is disabled prior to unregistering endpoints in order to prevent invalid HC commands. Removed active endpoints count from XHCI device. Device context is freed in HC, so DCBAA is not touched from anywhere else.

Location:
uspace/drv/bus/usb/xhci
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/xhci/bus.c

    r62f8025 r9620a54  
    121121        endpoint_del_ref(ep0_base);
    122122err_slot:
    123         hc_disable_slot(hc, dev->slot_id);
     123        hc_disable_slot(hc, dev);
    124124        return err;
    125125}
     
    189189
    190190        /* Block creation of new endpoints and transfers. */
    191         usb_log_debug2("Device '%s' going offline.", ddf_fun_get_name(dev->fun));
     191        usb_log_debug2("Device " XHCI_DEV_FMT " going offline.", XHCI_DEV_ARGS(*xhci_dev));
    192192        fibril_mutex_lock(&dev->guard);
    193193        xhci_dev->online = false;
     
    195195
    196196        /* Abort running transfers. */
    197         usb_log_debug2("Aborting all active transfers to '%s'.", ddf_fun_get_name(dev->fun));
     197        usb_log_debug2("Aborting all active transfers to device " XHCI_DEV_FMT ".", XHCI_DEV_ARGS(*xhci_dev));
    198198        for (size_t i = 0; i < ARRAY_SIZE(xhci_dev->endpoints); ++i) {
    199199                xhci_endpoint_t *ep = xhci_dev->endpoints[i];
     
    203203                /* FIXME: This is racy. */
    204204                if ((err = xhci_transfer_abort(&ep->active_transfer))) {
    205                         usb_log_warning("Failed to abort active %s transfer to "
    206                             " endpoint %d of detached device '%s': %s",
    207                             usb_str_transfer_type(ep->base.transfer_type),
    208                             ep->base.endpoint, ddf_fun_get_name(dev->fun),
     205                        usb_log_warning("Failed to abort active transfer to "
     206                            " endpoint " XHCI_EP_FMT ": %s", XHCI_EP_ARGS(*ep),
    209207                            str_error(err));
    210208                }
     
    215213        /* Make DDF (and all drivers) forget about the device. */
    216214        if ((err = ddf_fun_unbind(dev->fun))) {
    217                 usb_log_warning("Failed to unbind DDF function of device '%s': %s",
    218                     ddf_fun_get_name(dev->fun), str_error(err));
    219         }
    220 
    221         /* Unregister remaining endpoints. */
     215                usb_log_warning("Failed to unbind DDF function of device " XHCI_DEV_FMT ": %s",
     216                    XHCI_DEV_ARGS(*xhci_dev), str_error(err));
     217        }
     218
     219        /* Disable the slot, dropping all endpoints. */
     220        const uint32_t slot_id = xhci_dev->slot_id;
     221        if ((err = hc_disable_slot(hc, xhci_dev))) {
     222                usb_log_warning("Failed to disable slot of device " XHCI_DEV_FMT ": %s",
     223                    XHCI_DEV_ARGS(*xhci_dev), str_error(err));
     224        }
     225
     226        bus->devices_by_slot[slot_id] = NULL;
     227
     228        /* Unregister remaining endpoints, freeing memory. */
    222229        for (unsigned i = 0; i < ARRAY_SIZE(xhci_dev->endpoints); ++i) {
    223230                if (!xhci_dev->endpoints[i])
     
    225232
    226233                if ((err = unregister_endpoint(&bus->base, &xhci_dev->endpoints[i]->base))) {
    227                         usb_log_warning("Failed to unregister EP (%u:%u): %s", dev->address, i, str_error(err));
     234                        usb_log_warning("Failed to unregister endpoint " XHCI_EP_FMT ": %s",
     235                            XHCI_EP_ARGS(*xhci_dev->endpoints[i]), str_error(err));
    228236                }
    229237        }
    230 
    231         // XXX: Ugly here. Move to device_destroy at endpoint.c?
    232         if ((err = hc_disable_slot(hc, xhci_dev->slot_id))) {
    233                 usb_log_warning("Failed to disable slot %d for device '%s': %s",
    234                     xhci_dev->slot_id, ddf_fun_get_name(dev->fun), str_error(err));
    235         }
    236 
    237         free32(xhci_dev->dev_ctx);
    238         hc->dcbaa[xhci_dev->slot_id] = 0;
    239 
    240         bus->devices_by_slot[xhci_dev->slot_id] = NULL;
    241238
    242239        /* Destroy DDF device. */
     
    291288        /* Transition the device from the Addressed to the Configured state. */
    292289        if ((err = hc_configure_device(hc, dev->slot_id))) {
    293                 usb_log_warning("Failed to configure device %d.", dev_base->address);
     290                usb_log_warning("Failed to configure device " XHCI_DEV_FMT ".", XHCI_DEV_ARGS(*dev));
    294291        }
    295292
    296293        /* Block creation of new endpoints and transfers. */
    297         usb_log_debug2("Device '%s' going online.", ddf_fun_get_name(dev_base->fun));
     294        usb_log_debug2("Device " XHCI_DEV_FMT " going online.", XHCI_DEV_ARGS(*dev));
    298295        fibril_mutex_lock(&dev_base->guard);
    299296        dev->online = true;
     
    326323
    327324        /* Block creation of new endpoints and transfers. */
    328         usb_log_debug2("Device '%s' going offline.", ddf_fun_get_name(dev_base->fun));
     325        usb_log_debug2("Device " XHCI_DEV_FMT " going offline.", XHCI_DEV_ARGS(*dev));
    329326        fibril_mutex_lock(&dev_base->guard);
    330327        dev->online = false;
     
    347344        /* Issue one HC command to simultaneously drop all endpoints except zero. */
    348345        if ((err = hc_deconfigure_device(hc, dev->slot_id))) {
    349                 usb_log_warning("Failed to deconfigure device %d.", dev_base->address);
     346                usb_log_warning("Failed to deconfigure device " XHCI_DEV_FMT ".",
     347                    XHCI_DEV_ARGS(*dev));
    350348        }
    351349
    352350        /* Tear down TRB ring / PSA. */
    353         /* TODO: Make this method "noexcept" */
    354351        for (unsigned i = 1; i < ARRAY_SIZE(endpoints); ++i) {
    355352                if (!endpoints[i])
    356353                        continue;
    357354
    358                 if ((err = xhci_endpoint_free_transfer_ds(endpoints[i]))) {
    359                         usb_log_warning("Failed to free resources of EP (%u:%u): %s", dev_base->address, i, str_error(err));
    360                 }
     355                xhci_endpoint_free_transfer_ds(endpoints[i]);
    361356        }
    362357
     
    404399                goto err_prepared;
    405400
    406         usb_log_info("Endpoint(%d:%d) registered to XHCI bus.", dev->base.address, ep->base.endpoint);
     401        usb_log_info("Endpoint " XHCI_EP_FMT " registered to XHCI bus.", XHCI_EP_ARGS(*ep));
    407402
    408403        xhci_ep_ctx_t ep_ctx;
     
    428423        xhci_device_t *dev = xhci_device_get(ep_base->device);
    429424
    430         usb_log_info("Endpoint(%d:%d) unregistered from XHCI bus.", dev->base.address, ep->base.endpoint);
     425        usb_log_info("Endpoint " XHCI_EP_FMT " unregistered from XHCI bus.", XHCI_EP_ARGS(*ep));
    431426
    432427        xhci_device_remove_endpoint(ep);
    433428
    434         /* Drop the endpoint. */
    435         if ((err = hc_drop_endpoint(bus->hc, dev->slot_id, xhci_endpoint_index(ep)))) {
    436                 usb_log_error("Failed to drop endpoint: %s", str_error(err));
     429        /* If device slot is still available, drop the endpoint. */
     430        if (dev->slot_id) {
     431                if ((err = hc_drop_endpoint(bus->hc, dev->slot_id, xhci_endpoint_index(ep)))) {
     432                        usb_log_error("Failed to drop endpoint " XHCI_EP_FMT ": %s", XHCI_EP_ARGS(*ep), str_error(err));
     433                }
     434        } else {
     435                usb_log_debug("Not going to drop endpoint " XHCI_EP_FMT " because"
     436                    " the slot has already been disabled.", XHCI_EP_ARGS(*ep));
    437437        }
    438438
    439439        /* Tear down TRB ring / PSA. */
    440         /* TODO: Make this method "noexcept" */
    441         if ((err = xhci_endpoint_free_transfer_ds(ep))) {
    442                 usb_log_error("Failed to free resources of an endpoint.");
    443         }
     440        xhci_endpoint_free_transfer_ds(ep);
    444441
    445442        return EOK;
  • uspace/drv/bus/usb/xhci/endpoint.c

    r62f8025 r9620a54  
    188188int xhci_endpoint_alloc_transfer_ds(xhci_endpoint_t *xhci_ep)
    189189{
    190 
    191         usb_log_debug2("Allocating main transfer ring for endpoint %u", xhci_ep->base.endpoint);
     190        /* Can't use XHCI_EP_FMT because the endpoint may not have device. */
     191        usb_log_debug2("Allocating main transfer ring for endpoint " XHCI_EP_FMT, XHCI_EP_ARGS(*xhci_ep));
    192192
    193193        xhci_ep->primary_stream_ctx_array = NULL;
     
    201201}
    202202
    203 int xhci_endpoint_free_transfer_ds(xhci_endpoint_t *xhci_ep)
    204 {
    205         /* FIXME: For some reason (possibly memory corruption), this crashes. */
    206         return EOK;
    207 
     203void xhci_endpoint_free_transfer_ds(xhci_endpoint_t *xhci_ep)
     204{
    208205        if (endpoint_using_streams(xhci_ep)) {
    209                 usb_log_debug2("Freeing primary stream context array for endpoint " XHCI_EP_FMT, XHCI_EP_ARGS(*xhci_ep));
     206                usb_log_debug2("Freeing primary stream context array of endpoint " XHCI_EP_FMT, XHCI_EP_ARGS(*xhci_ep));
    210207
    211208                // maybe check if LSA, then skip?
     
    223220                free32(xhci_ep->primary_stream_ctx_array);
    224221        } else {
    225                 usb_log_debug2("Freeing main transfer ring for endpoint " XHCI_EP_FMT, XHCI_EP_ARGS(*xhci_ep));
    226 
    227                 int err;
    228                 if ((err = xhci_trb_ring_fini(&xhci_ep->ring))) {
    229                         return err;
    230                 }
    231         }
    232 
    233         return EOK;
     222                usb_log_debug2("Freeing main transfer ring of endpoint " XHCI_EP_FMT, XHCI_EP_ARGS(*xhci_ep));
     223
     224                xhci_trb_ring_fini(&xhci_ep->ring);
     225        }
    234226}
    235227
     
    344336        endpoint_add_ref(&ep->base);
    345337        ep->base.device = &dev->base;
    346 
    347338        dev->endpoints[ep_num] = ep;
    348         ++dev->active_endpoint_count;
    349339
    350340        return EOK;
     
    357347
    358348        assert(dev->endpoints[ep->base.endpoint]);
    359 
    360349        dev->endpoints[ep->base.endpoint] = NULL;
    361         --dev->active_endpoint_count;
    362350        ep->base.device = NULL;
    363351
  • uspace/drv/bus/usb/xhci/endpoint.h

    r62f8025 r9620a54  
    9191
    9292#define XHCI_EP_FMT  "(%d:%d %s)"
     93/* FIXME: "Device -1" messes up log messages, figure out a better way. */
    9394#define XHCI_EP_ARGS(ep)                \
    94         ((ep).base.device->address),    \
     95        ((ep).base.device ? (ep).base.device->address : -1),    \
    9596        ((ep).base.endpoint),           \
    9697        (usb_str_transfer_type((ep).base.transfer_type))
     
    114115        xhci_device_ctx_t *dev_ctx;
    115116
    116         /** All endpoints of the device. Inactive ones are NULL */
     117        /** All endpoints of the device. Dropped ones are NULL */
    117118        xhci_endpoint_t *endpoints[XHCI_EP_COUNT];
    118 
    119         /** Number of non-NULL endpoints. Reference count of sorts. */
    120         uint8_t active_endpoint_count;
    121119
    122120        /** Flag indicating whether the device is USB3 (it's USB2 otherwise). */
     
    127125} xhci_device_t;
    128126
     127#define XHCI_DEV_FMT  "(%s, slot %d)"
     128#define XHCI_DEV_ARGS(dev)               ddf_fun_get_name((dev).base.fun), (dev).slot_id
     129
    129130int xhci_endpoint_init(xhci_endpoint_t *, xhci_bus_t *);
    130131void xhci_endpoint_fini(xhci_endpoint_t *);
    131132int xhci_endpoint_alloc_transfer_ds(xhci_endpoint_t *);
    132 int xhci_endpoint_free_transfer_ds(xhci_endpoint_t *);
     133void xhci_endpoint_free_transfer_ds(xhci_endpoint_t *);
    133134
    134135int xhci_endpoint_request_streams(xhci_hc_t *, xhci_device_t *, xhci_endpoint_t *, unsigned);
  • uspace/drv/bus/usb/xhci/hc.c

    r62f8025 r9620a54  
    617617}
    618618
    619 int hc_disable_slot(xhci_hc_t *hc, uint32_t slot_id)
    620 {
     619int hc_disable_slot(xhci_hc_t *hc, xhci_device_t *dev)
     620{
     621        int err;
    621622        assert(hc);
    622         return xhci_cmd_sync_inline(hc, DISABLE_SLOT, .slot_id = slot_id);
     623
     624        if ((err = xhci_cmd_sync_inline(hc, DISABLE_SLOT, .slot_id = dev->slot_id))) {
     625                return err;
     626        }
     627
     628        /* Free the device context. */
     629        hc->dcbaa[dev->slot_id] = 0;
     630        if (dev->dev_ctx) {
     631                free32(dev->dev_ctx);
     632                dev->dev_ctx = NULL;
     633        }
     634
     635        /* Mark the slot as invalid. */
     636        dev->slot_id = 0;
     637
     638        return EOK;
    623639}
    624640
     
    654670         * we have to rely on reverse mapping on others. */
    655671        if (!hc->speed_to_psiv[dev->base.speed]) {
    656                 usb_log_error("Device reported an usb speed that cannot be mapped to HC port speed.");
     672                usb_log_error("Device reported an USB speed that cannot be mapped to HC port speed.");
    657673                return EINVAL;
    658674        }
  • uspace/drv/bus/usb/xhci/hc.h

    r62f8025 r9620a54  
    102102int hc_ring_doorbell(xhci_hc_t *, unsigned, unsigned);
    103103int hc_enable_slot(xhci_hc_t *, uint32_t *);
    104 int hc_disable_slot(xhci_hc_t *, uint32_t);
     104int hc_disable_slot(xhci_hc_t *, xhci_device_t *);
    105105int hc_address_device(xhci_hc_t *, xhci_device_t *, xhci_endpoint_t *);
    106106int hc_configure_device(xhci_hc_t *, uint32_t);
  • uspace/drv/bus/usb/xhci/rh.c

    r62f8025 r9620a54  
    119119
    120120        if ((err = ddf_fun_bind(dev->fun))) {
    121                 usb_log_error("Device(%d): Failed to register: %s.", dev->address, str_error(err));
     121                usb_log_error("Failed to register device " XHCI_DEV_FMT " DDF function: %s.",
     122                    XHCI_DEV_ARGS(*xhci_dev), str_error(err));
    122123                goto err_usb_dev;
    123124        }
     
    185186        }
    186187
    187         usb_log_info("Device '%s' at port %u has been disconnected.", ddf_fun_get_name(dev->base.fun), port_id);
     188        usb_log_info("Device " XHCI_DEV_FMT " at port %u has been disconnected.",
     189            XHCI_DEV_ARGS(*dev), port_id);
    188190
    189191        /* Mark the device as detached. */
     
    195197        /* Remove device from XHCI bus. */
    196198        if ((err = xhci_bus_remove_device(&rh->hc->bus, rh->hc, &dev->base))) {
    197                 usb_log_warning("Failed to remove device '%s' from XHCI bus: %s",
    198                     ddf_fun_get_name(dev->base.fun), str_error(err));
     199                usb_log_warning("Failed to remove device " XHCI_DEV_FMT " from XHCI bus: %s",
     200                    XHCI_DEV_ARGS(*dev), str_error(err));
    199201        }
    200202
  • uspace/drv/bus/usb/xhci/transfers.c

    r62f8025 r9620a54  
    265265        xhci_device_t *dev = hc->bus.devices_by_slot[slot_id];
    266266        if (!dev) {
    267                 usb_log_error("Transfer event on unknown device slot %u!", slot_id);
     267                usb_log_error("Transfer event on disabled slot %u", slot_id);
    268268                return ENOENT;
    269269        }
     
    272272        xhci_endpoint_t *ep = xhci_device_get_endpoint(dev, ep_num);
    273273        if (!ep) {
    274                 usb_log_error("Transfer event on unknown endpoint num %u, device slot %u!", ep_num, slot_id);
     274                usb_log_error("Transfer event on dropped endpoint %u of device "
     275                    XHCI_DEV_FMT, ep_num, XHCI_DEV_ARGS(*dev));
    275276                return ENOENT;
    276277        }
     
    322323        // FIXME: find a better way to check if the ring is not initialized
    323324        if (!xhci_ep->ring.segment_count) {
    324                 usb_log_error("Ring not initialized for endpoint num %u!", xhci_ep->base.endpoint);
     325                usb_log_error("Ring not initialized for endpoint " XHCI_EP_FMT,
     326                    XHCI_EP_ARGS(*xhci_ep));
    325327                return EINVAL;
    326328        }
  • uspace/drv/bus/usb/xhci/trb_ring.c

    r62f8025 r9620a54  
    121121}
    122122
    123 int xhci_trb_ring_fini(xhci_trb_ring_t *ring)
     123void xhci_trb_ring_fini(xhci_trb_ring_t *ring)
    124124{
    125125        assert(ring);
     
    129129                dmamem_unmap_anonymous(segment);
    130130        }
    131 
    132         return EOK;
    133131}
    134132
     
    292290}
    293291
    294 int xhci_event_ring_fini(xhci_event_ring_t *ring)
     292void xhci_event_ring_fini(xhci_event_ring_t *ring)
    295293{
    296294        list_foreach_safe(ring->segments, cur, next) {
     
    301299        if (ring->erst)
    302300                free32(ring->erst);
    303 
    304         return EOK;
    305301}
    306302
  • uspace/drv/bus/usb/xhci/trb_ring.h

    r62f8025 r9620a54  
    7474
    7575int xhci_trb_ring_init(xhci_trb_ring_t *);
    76 int xhci_trb_ring_fini(xhci_trb_ring_t *);
     76void xhci_trb_ring_fini(xhci_trb_ring_t *);
    7777int xhci_trb_ring_enqueue(xhci_trb_ring_t *, xhci_trb_t *, uintptr_t *);
    7878int xhci_trb_ring_enqueue_multiple(xhci_trb_ring_t *, xhci_trb_t *, size_t, uintptr_t *);
     
    112112
    113113int xhci_event_ring_init(xhci_event_ring_t *);
    114 int xhci_event_ring_fini(xhci_event_ring_t *);
     114void xhci_event_ring_fini(xhci_event_ring_t *);
    115115int xhci_event_ring_dequeue(xhci_event_ring_t *, xhci_trb_t *);
    116116
Note: See TracChangeset for help on using the changeset viewer.