Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 6b2930b in mainline


Ignore:
Timestamp:
2017-10-28T21:47:39Z (3 years ago)
Author:
Petr Manek <petr.manek@…>
Branches:
master
Children:
62f8025
Parents:
a3044b4
Message:

Issuing deconfigure / configure commands when offlining / onlining a device.

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

Legend:

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

    ra3044b4 r6b2930b  
    188188        xhci_device_t *xhci_dev = xhci_device_get(dev);
    189189
    190         /* If the device is still attached, end DDF drivers gracefully. */
    191         if (!xhci_dev->detached) {
    192                 if ((err = ddf_fun_offline(dev->fun))) {
    193                         usb_log_warning("Failed to offline DDF function of device '%s': %s",
    194                             ddf_fun_get_name(dev->fun), str_error(err));
    195                 }
    196         }
    197 
    198190        /* Block creation of new endpoints and transfers. */
    199191        usb_log_debug2("Device '%s' going offline.", ddf_fun_get_name(dev->fun));
     
    227219        }
    228220
    229         /* Deconfigure device if it's still attached. */
    230         if (!xhci_dev->detached) {
    231                 if ((err = hc_deconfigure_device(hc, xhci_dev->slot_id))) {
    232                         usb_log_warning("Failed to deconfigure device '%s': %s",
    233                             ddf_fun_get_name(dev->fun), str_error(err));
    234                 }
    235         }
    236 
    237221        /* Unregister remaining endpoints. */
    238222        for (unsigned i = 0; i < ARRAY_SIZE(xhci_dev->endpoints); ++i) {
     
    256240        bus->devices_by_slot[xhci_dev->slot_id] = NULL;
    257241
     242        /* Destroy DDF device. */
     243        /* XXX: Not a good idea, this method should not destroy devices. */
     244        hcd_ddf_device_destroy(dev);
     245
    258246        return EOK;
    259247}
     
    301289        assert(dev);
    302290
    303         // TODO: Prepare the device for use. Reset? Configure?
     291        /* Transition the device from the Addressed to the Configured state. */
     292        if ((err = hc_configure_device(hc, dev->slot_id))) {
     293                usb_log_warning("Failed to configure device %d.", dev_base->address);
     294        }
     295
     296        /* Block creation of new endpoints and transfers. */
     297        usb_log_debug2("Device '%s' going online.", ddf_fun_get_name(dev_base->fun));
     298        fibril_mutex_lock(&dev_base->guard);
     299        dev->online = true;
     300        fibril_mutex_unlock(&dev_base->guard);
    304301
    305302        if ((err = ddf_fun_online(dev_base->fun))) {
     
    328325        }
    329326
    330         // TODO: We want to keep the device addressed. Deconfigure?
     327        /* Block creation of new endpoints and transfers. */
     328        usb_log_debug2("Device '%s' going offline.", ddf_fun_get_name(dev_base->fun));
     329        fibril_mutex_lock(&dev_base->guard);
     330        dev->online = false;
     331        fibril_mutex_unlock(&dev_base->guard);
     332
     333        /* We will need the endpoint array later for DS deallocation. */
     334        xhci_endpoint_t *endpoints[ARRAY_SIZE(dev->endpoints)];
     335        memcpy(endpoints, dev->endpoints, sizeof(dev->endpoints));
     336
     337        /* Remove all endpoints except zero. */
     338        for (unsigned i = 1; i < ARRAY_SIZE(endpoints); ++i) {
     339                if (!endpoints[i])
     340                        continue;
     341
     342                /* FIXME: Asserting here that the endpoint is not active. If not, EBUSY? */
     343
     344                xhci_device_remove_endpoint(endpoints[i]);
     345        }
     346
     347        /* Issue one HC command to simultaneously drop all endpoints except zero. */
     348        if ((err = hc_deconfigure_device(hc, dev->slot_id))) {
     349                usb_log_warning("Failed to deconfigure device %d.", dev_base->address);
     350        }
     351
     352        /* Tear down TRB ring / PSA. */
     353        /* TODO: Make this method "noexcept" */
     354        for (unsigned i = 1; i < ARRAY_SIZE(endpoints); ++i) {
     355                if (!endpoints[i])
     356                        continue;
     357
     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                }
     361        }
     362
     363        /* FIXME: What happens to unregistered endpoints now? Destroy them? */
    331364
    332365        return EOK;
  • uspace/drv/bus/usb/xhci/endpoint.h

    ra3044b4 r6b2930b  
    125125        /** True if the device can add new endpoints and schedule transfers. */
    126126        volatile bool online;
    127 
    128         /** True if the device has been physically detached from the socket. */
    129         volatile bool detached;
    130127} xhci_device_t;
    131128
  • uspace/drv/bus/usb/xhci/rh.c

    ra3044b4 r6b2930b  
    188188
    189189        /* Mark the device as detached. */
    190         fibril_mutex_lock(&dev->base.guard);
    191         dev->detached = true;
    192         fibril_mutex_unlock(&dev->base.guard);
    193 
    194190        fibril_mutex_lock(&rh->device.base.guard);
    195191        list_remove(&dev->base.link);
     
    202198                    ddf_fun_get_name(dev->base.fun), str_error(err));
    203199        }
    204 
    205         /* Destroy DDF device. */
    206         hcd_ddf_device_destroy(&dev->base);
    207 
    208         /* TODO: Figure out what was forgotten and free that as well. */
    209200
    210201        return EOK;
Note: See TracChangeset for help on using the changeset viewer.