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

Changeset 56257ba in mainline


Ignore:
Timestamp:
2018-01-07T01:01:42Z (4 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master
Children:
63431db
Parents:
9efad54
git-author:
Ondřej Hlavatý <aearsis@…> (2018-01-07 01:01:41)
git-committer:
Ondřej Hlavatý <aearsis@…> (2018-01-07 01:01:42)
Message:

usbhost: manage endpoints by library + get/set_toggle → reset_toggle

That simplifies things A LOT. Now you can find endpoints for device in
an array inside device. This array is managed automatically in
register/unregister endpoint. HC drivers still needs to write to it when
setting up/tearing down the device.

Sorry for these two changes being in one commit, but splitting them
would be simply more work for no benefit.

Location:
uspace
Files:
18 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/vuhid/virthid.h

    r9efad54 r56257ba  
    4040#include <fibril_synch.h>
    4141
    42 #define VUHID_ENDPOINT_MAX USB11_ENDPOINT_MAX
     42#define VUHID_ENDPOINT_MAX USB_ENDPOINT_MAX
    4343#define VUHID_INTERFACE_MAX 8
    4444
  • uspace/drv/bus/usb/ehci/ehci_bus.c

    r9efad54 r56257ba  
    4848 * @param[in] toggle new value of toggle bit
    4949 */
    50 static void ehci_ep_toggle_set(endpoint_t *ep, bool toggle)
     50static void ehci_ep_toggle_reset(endpoint_t *ep)
    5151{
    5252        ehci_endpoint_t *instance = ehci_endpoint_get(ep);
    53         assert(instance);
    54         assert(instance->qh);
    55         ep->toggle = toggle;
    5653        if (qh_toggle_from_td(instance->qh))
    57                 usb_log_warning("EP(%p): Setting toggle bit for transfer "
    58                     "directed EP", instance);
    59         qh_toggle_set(instance->qh, toggle);
     54                usb_log_warning("EP(%p): Resetting toggle bit for transfer directed EP", instance);
     55        qh_toggle_set(instance->qh, 0);
     56        ep->toggle = 0;
    6057}
    6158
    62 /** Callback to get value of toggle bit.
    63  *
    64  * @param[in] hcd_ep hcd endpoint structure
    65  * @return Current value of toggle bit.
    66  */
    67 static bool ehci_ep_toggle_get(endpoint_t *ep)
    68 {
    69         ehci_endpoint_t *instance = ehci_endpoint_get(ep);
    70         assert(instance);
    71         assert(instance->qh);
    72 
    73         if (qh_toggle_from_td(instance->qh))
    74                 usb_log_warning("EP(%p): Reading useless toggle bit", instance);
    75         return qh_toggle_get(instance->qh);
    76 }
    7759
    7860/** Creates new hcd endpoint representation.
     
    166148        .endpoint_register = ehci_register_ep,
    167149        .endpoint_unregister = ehci_unregister_ep,
    168         .endpoint_set_toggle = ehci_ep_toggle_set,
    169         .endpoint_get_toggle = ehci_ep_toggle_get,
     150        .endpoint_toggle_reset = ehci_ep_toggle_reset,
    170151        .endpoint_count_bw = bandwidth_count_usb11,
    171152        .batch_create = ehci_create_batch,
  • uspace/drv/bus/usb/ohci/ohci_bus.c

    r9efad54 r56257ba  
    4343#include "hc.h"
    4444
    45 /** Callback to set toggle on ED.
     45/** Callback to reset toggle on ED.
    4646 *
    4747 * @param[in] hcd_ep hcd endpoint structure
    4848 * @param[in] toggle new value of toggle bit
    4949 */
    50 static void ohci_ep_toggle_set(endpoint_t *ep, bool toggle)
     50static void ohci_ep_toggle_reset(endpoint_t *ep)
    5151{
    5252        ohci_endpoint_t *instance = ohci_endpoint_get(ep);
    5353        assert(instance);
    5454        assert(instance->ed);
    55         ep->toggle = toggle;
    56         ed_toggle_set(instance->ed, toggle);
    57 }
    58 
    59 /** Callback to get value of toggle bit.
    60  *
    61  * @param[in] hcd_ep hcd endpoint structure
    62  * @return Current value of toggle bit.
    63  */
    64 static bool ohci_ep_toggle_get(endpoint_t *ep)
    65 {
    66         ohci_endpoint_t *instance = ohci_endpoint_get(ep);
    67         assert(instance);
    68         assert(instance->ed);
    69         return ed_toggle_get(instance->ed);
     55        ep->toggle = 0;
     56        ed_toggle_set(instance->ed, 0);
    7057}
    7158
     
    166153        .endpoint_unregister = ohci_unregister_ep,
    167154        .endpoint_count_bw = bandwidth_count_usb11,
    168         .endpoint_set_toggle = ohci_ep_toggle_set,
    169         .endpoint_get_toggle = ohci_ep_toggle_get,
     155        .endpoint_toggle_reset = ohci_ep_toggle_reset,
    170156        .batch_create = ohci_create_batch,
    171157        .batch_destroy = ohci_destroy_batch,
  • uspace/drv/bus/usb/uhci/uhci_batch.c

    r9efad54 r56257ba  
    178178                        td_print_status(&uhci_batch->tds[i]);
    179179
    180                         endpoint_toggle_set(batch->ep,
    181                             td_toggle(&uhci_batch->tds[i]));
     180                        batch->ep->toggle = td_toggle(&uhci_batch->tds[i]);
    182181                        if (i > 0)
    183182                                goto substract_ret;
     
    195194
    196195        fibril_mutex_lock(&batch->ep->guard);
    197         usb_transfer_batch_reset_toggle(batch);
    198196        endpoint_deactivate_locked(batch->ep);
    199197        fibril_mutex_unlock(&batch->ep->guard);
     
    236234        const size_t mps = uhci_batch->base.ep->max_packet_size;
    237235
    238         int toggle = endpoint_toggle_get(uhci_batch->base.ep);
     236        int toggle = uhci_batch->base.ep->toggle;
    239237        assert(toggle == 0 || toggle == 1);
    240238
     
    260258        }
    261259        td_set_ioc(&uhci_batch->tds[td - 1]);
    262         endpoint_toggle_set(uhci_batch->base.ep, toggle);
     260        uhci_batch->base.ep->toggle = toggle;
    263261        usb_log_debug2(
    264262            "Batch %p %s %s " USB_TRANSFER_BATCH_FMT " initialized.\n", \
  • uspace/drv/bus/usb/xhci/bus.c

    r9efad54 r56257ba  
    7777                goto err_slot;
    7878
    79         /* Temporary reference */
     79        /* Bus reference */
    8080        endpoint_add_ref(ep0_base);
     81        dev->base.endpoints[0] = ep0_base;
    8182
    8283        xhci_endpoint_t *ep0 = xhci_endpoint_get(ep0_base);
    8384
    8485        if ((err = xhci_endpoint_alloc_transfer_ds(ep0)))
    85                 goto err_ep;
    86 
    87         /* Register EP0 */
    88         if ((err = xhci_device_add_endpoint(dev, ep0)))
    89                 goto err_prepared;
     86                goto err_added;
    9087
    9188        /* Address device */
    9289        if ((err = hc_address_device(bus->hc, dev, ep0)))
    93                 goto err_added;
    94 
    95         /* Temporary reference */
    96         endpoint_del_ref(ep0_base);
    97         return EOK;
    98 
    99 err_added:
    100         xhci_device_remove_endpoint(ep0);
     90                goto err_prepared;
     91
     92        return EOK;
     93
    10194err_prepared:
    10295        xhci_endpoint_free_transfer_ds(ep0);
    103 err_ep:
    104         /* Temporary reference */
     96err_added:
     97        /* Bus reference */
    10598        endpoint_del_ref(ep0_base);
     99        dev->base.endpoints[0] = NULL;
    106100err_slot:
    107101        hc_disable_slot(bus->hc, dev);
     
    123117                return err;
    124118
    125         xhci_endpoint_t *ep0 = dev->endpoints[0];
     119        xhci_endpoint_t *ep0 = xhci_device_get_endpoint(dev, 0);
    126120        assert(ep0);
    127121
     
    218212        /* Abort running transfers. */
    219213        usb_log_debug2("Aborting all active transfers to device " XHCI_DEV_FMT ".", XHCI_DEV_ARGS(*xhci_dev));
    220         for (size_t i = 0; i < ARRAY_SIZE(xhci_dev->endpoints); ++i) {
    221                 xhci_endpoint_t *ep = xhci_dev->endpoints[i];
     214        for (usb_endpoint_t i = 0; i < USB_ENDPOINT_MAX; ++i) {
     215                xhci_endpoint_t *ep = xhci_device_get_endpoint(xhci_dev, i);
    222216                if (!ep)
    223217                        continue;
     
    244238
    245239        /* Unregister remaining endpoints, freeing memory. */
    246         for (unsigned i = 0; i < ARRAY_SIZE(xhci_dev->endpoints); ++i) {
    247                 if (!xhci_dev->endpoints[i])
     240        for (usb_endpoint_t i = 0; i < USB_ENDPOINT_MAX; ++i) {
     241                if (!dev->endpoints[i])
    248242                        continue;
    249243
    250                 if ((err = endpoint_unregister(&xhci_dev->endpoints[i]->base))) {
     244                if ((err = endpoint_unregister(dev->endpoints[i]))) {
    251245                        usb_log_warning("Failed to unregister endpoint " XHCI_EP_FMT ": %s",
    252                             XHCI_EP_ARGS(*xhci_dev->endpoints[i]), str_error(err));
     246                            XHCI_EP_ARGS(*xhci_device_get_endpoint(xhci_dev, i)), str_error(err));
    253247                }
    254248        }
     
    332326
    333327        /* 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 
     328        endpoint_t *endpoints[USB_ENDPOINT_MAX];
     329        memcpy(endpoints, dev->base.endpoints, sizeof(endpoints));
     330
     331        for (usb_endpoint_t i = 1; i < USB_ENDPOINT_MAX; ++i) {
    342332                /* FIXME: Asserting here that the endpoint is not active. If not, EBUSY? */
    343 
    344                 xhci_device_remove_endpoint(endpoints[i]);
     333                dev->base.endpoints[i] = NULL;
    345334        }
    346335
     
    356345                        continue;
    357346
    358                 xhci_endpoint_free_transfer_ds(endpoints[i]);
    359         }
    360 
    361         /* FIXME: What happens to unregistered endpoints now? Destroy them? */
     347                xhci_endpoint_free_transfer_ds(xhci_endpoint_get(endpoints[i]));
     348                /* Bus reference */
     349                endpoint_del_ref(endpoints[i]);
     350        }
    362351
    363352        return EOK;
     
    397386                return err;
    398387
    399         if ((err = xhci_device_add_endpoint(dev, ep)))
    400                 goto err_prepared;
    401 
    402388        usb_log_info("Endpoint " XHCI_EP_FMT " registered to XHCI bus.", XHCI_EP_ARGS(*ep));
    403389
     
    406392
    407393        if ((err = hc_add_endpoint(bus->hc, dev->slot_id, xhci_endpoint_index(ep), &ep_ctx)))
    408                 goto err_added;
    409 
    410         return EOK;
    411 
    412 err_added:
    413         xhci_device_remove_endpoint(ep);
     394                goto err_prepared;
     395
     396        return EOK;
     397
    414398err_prepared:
    415399        xhci_endpoint_free_transfer_ds(ep);
     
    425409
    426410        usb_log_info("Endpoint " XHCI_EP_FMT " unregistered from XHCI bus.", XHCI_EP_ARGS(*ep));
    427 
    428         xhci_device_remove_endpoint(ep);
    429411
    430412        /* If device slot is still available, drop the endpoint. */
     
    444426}
    445427
    446 static endpoint_t* device_find_endpoint(device_t *dev_base, usb_target_t target, usb_direction_t direction)
    447 {
    448         xhci_device_t *dev = xhci_device_get(dev_base);
    449 
    450         xhci_endpoint_t *ep = xhci_device_get_endpoint(dev, target.endpoint);
    451         if (!ep)
    452                 return NULL;
    453 
    454         return &ep->base;
    455 }
    456 
    457 static int reset_toggle(bus_t *bus_base, usb_target_t target, toggle_reset_mode_t mode)
    458 {
    459         // TODO: Implement me!
    460         return ENOTSUP;
    461 }
    462 
    463 /* Endpoint ops, optional (have generic fallback) */
    464 static bool endpoint_get_toggle(endpoint_t *ep)
    465 {
    466         // TODO: Implement me!
    467         return ENOTSUP;
    468 }
    469 
    470 static void endpoint_set_toggle(endpoint_t *ep, bool toggle)
    471 {
    472         // TODO: Implement me!
    473 }
    474 
    475428static int reserve_default_address(bus_t *bus_base, usb_speed_t speed)
    476429{
     
    510463        BIND_OP(reserve_default_address)
    511464        BIND_OP(release_default_address)
    512         BIND_OP(reset_toggle)
    513465
    514466        BIND_OP(device_enumerate)
     
    516468        BIND_OP(device_online)
    517469        BIND_OP(device_offline)
    518         BIND_OP(device_find_endpoint)
    519470
    520471        BIND_OP(endpoint_create)
     
    522473        BIND_OP(endpoint_register)
    523474        BIND_OP(endpoint_unregister)
    524         BIND_OP(endpoint_get_toggle)
    525         BIND_OP(endpoint_set_toggle)
    526475
    527476        BIND_OP(batch_create)
  • uspace/drv/bus/usb/xhci/endpoint.c

    r9efad54 r56257ba  
    469469}
    470470
    471 /** Add a new XHCI endpoint to a device. The device must be online unless
    472  * the added endpoint is number 0.
    473  * @param[in] dev XHCI device, to which to add the endpoint
    474  * @param[in] ep XHCI endpoint to add.
    475  *
    476  * @return Error code.
    477  */
    478 int xhci_device_add_endpoint(xhci_device_t *dev, xhci_endpoint_t *ep)
    479 {
    480         assert(dev);
    481         assert(ep);
    482 
    483         /* Offline devices don't create new endpoints other than EP0. */
    484         if (!dev->base.online && ep->base.endpoint > 0) {
    485                 return EAGAIN;
    486         }
    487 
    488         const usb_endpoint_t ep_num = ep->base.endpoint;
    489 
    490         if (dev->endpoints[ep_num])
    491                 return EEXIST;
    492 
    493         /* Device reference */
    494         endpoint_add_ref(&ep->base);
    495         ep->base.device = &dev->base;
    496         dev->endpoints[ep_num] = ep;
    497 
    498         return EOK;
    499 }
    500 
    501 /** Remove XHCI endpoint from a device.
    502  * @param[in] ep XHCI endpoint to remove.
    503  */
    504 void xhci_device_remove_endpoint(xhci_endpoint_t *ep)
    505 {
    506         assert(ep);
    507         xhci_device_t *dev = xhci_device_get(ep->base.device);
    508 
    509         assert(dev->endpoints[ep->base.endpoint]);
    510         dev->endpoints[ep->base.endpoint] = NULL;
    511         ep->base.device = NULL;
    512 }
    513 
    514471/** Retrieve XHCI endpoint from a device by the endpoint number.
    515472 * @param[in] dev XHCI device to query.
     
    520477xhci_endpoint_t *xhci_device_get_endpoint(xhci_device_t *dev, usb_endpoint_t ep)
    521478{
    522         return dev->endpoints[ep];
     479        return xhci_endpoint_get(dev->base.endpoints[ep]);
    523480}
    524481
  • uspace/drv/bus/usb/xhci/endpoint.h

    r9efad54 r56257ba  
    139139        dma_buffer_t dev_ctx;
    140140
    141         /** All endpoints of the device. Dropped ones are NULL */
    142         xhci_endpoint_t *endpoints[XHCI_EP_COUNT];
    143 
    144141        /** Flag indicating whether the device is USB3 (it's USB2 otherwise). */
    145142        bool usb3;
     
    161158void xhci_setup_endpoint_context(xhci_endpoint_t *, xhci_ep_ctx_t *);
    162159
    163 int xhci_device_add_endpoint(xhci_device_t *, xhci_endpoint_t *);
    164 void xhci_device_remove_endpoint(xhci_endpoint_t *);
    165160xhci_endpoint_t * xhci_device_get_endpoint(xhci_device_t *, usb_endpoint_t);
    166161
  • uspace/drv/bus/usb/xhci/transfers.c

    r9efad54 r56257ba  
    513513        }
    514514
    515         usb_transfer_batch_reset_toggle(batch);
    516515        endpoint_deactivate_locked(&ep->base);
    517516        fibril_mutex_unlock(&ep->base.guard);
  • uspace/lib/usb/include/usb/usb.h

    r9efad54 r56257ba  
    103103#define USB_ENDPOINT_DEFAULT_CONTROL 0
    104104
    105 /** Maximum endpoint number in USB 1.1. */
    106 #define USB11_ENDPOINT_MAX 16
     105/** Maximum endpoint number in USB */
     106#define USB_ENDPOINT_MAX 16
    107107
    108108/** Check USB endpoint for allowed values.
     
    116116{
    117117        return (ep >= USB_ENDPOINT_DEFAULT_CONTROL) &&
    118             (ep < USB11_ENDPOINT_MAX);
     118            (ep < USB_ENDPOINT_MAX);
    119119}
    120120
  • uspace/lib/usbhost/include/usb/host/bus.h

    r9efad54 r56257ba  
    7676        usb_speed_t speed;
    7777        usb_address_t address;
     78        endpoint_t *endpoints [USB_ENDPOINT_MAX];
    7879
    7980        /* Managing bus */
     
    101102        int (*reserve_default_address)(bus_t *, usb_speed_t);
    102103        int (*release_default_address)(bus_t *);
    103         int (*reset_toggle)(bus_t *, usb_target_t, toggle_reset_mode_t);
    104104
    105105        /* Operations on device */
     
    108108        int (*device_online)(device_t *);                       /**< Optional */
    109109        int (*device_offline)(device_t *);                      /**< Optional */
    110         endpoint_t *(*device_find_endpoint)(device_t*, usb_target_t, usb_direction_t);
    111110        endpoint_t *(*endpoint_create)(device_t *, const usb_endpoint_descriptors_t *);
    112111
     
    115114        int (*endpoint_unregister)(endpoint_t *);
    116115        void (*endpoint_destroy)(endpoint_t *);                 /**< Optional */
    117         bool (*endpoint_get_toggle)(endpoint_t *);              /**< Optional */
    118         void (*endpoint_set_toggle)(endpoint_t *, bool);        /**< Optional */
    119         ssize_t (*endpoint_count_bw) (endpoint_t *, size_t);
     116        void (*endpoint_toggle_reset)(endpoint_t *);            /**< Optional */
     117        ssize_t (*endpoint_count_bw) (endpoint_t *, size_t);    /**< Optional */
    120118        usb_transfer_batch_t *(*batch_create)(endpoint_t *);    /**< Optional */
    121119
     
    164162
    165163int bus_endpoint_add(device_t *, const usb_endpoint_descriptors_t *, endpoint_t **);
    166 endpoint_t *bus_find_endpoint(device_t *, usb_target_t, usb_direction_t);
     164endpoint_t *bus_find_endpoint(device_t *, usb_endpoint_t);
    167165int bus_endpoint_remove(endpoint_t *);
    168166
     
    170168int bus_release_default_address(bus_t *);
    171169
    172 int bus_reset_toggle(bus_t *, usb_target_t, bool);
    173 
    174170#endif
    175171/**
  • uspace/lib/usbhost/include/usb/host/endpoint.h

    r9efad54 r56257ba  
    6262        /** Reserved bandwidth. */
    6363        size_t bandwidth;
    64         /** Value of the toggle bit. */
     64        /** Value of the toggle bit. Untouched by the library. */
    6565        unsigned toggle:1;
    6666        /** The currently active transfer batch. Write using methods, read under guard. */
     
    107107void endpoint_abort(endpoint_t *);
    108108
    109 /* Manage the toggle bit */
    110 extern int endpoint_toggle_get(endpoint_t *);
    111 extern void endpoint_toggle_set(endpoint_t *, bool);
    112 
    113109/* Calculate bandwidth */
    114110ssize_t endpoint_count_bw(endpoint_t *, size_t);
  • uspace/lib/usbhost/include/usb/host/usb2_bus.h

    r9efad54 r56257ba  
    5050        bus_t base;                     /**< Inheritance - keep this first */
    5151
    52         /* Device bookkeeping */
    53         struct {
    54                 usb_speed_t speed;      /**< Device speed */
    55                 bool occupied;          /**< The address is in use. */
    56                 // TODO: This can be stored in usb2_bus-specific device_t
    57                 list_t endpoint_list;   /**< Store endpoint_t instances */
    58         } devices[USB_ADDRESS_COUNT];
     52        /** The speed which reserved default address. Invalid unless reserved. */
     53        usb_speed_t default_address_speed;
     54
     55        /** Map of occupied addresses */
     56        bool address_occupied [USB_ADDRESS_COUNT];
     57        /** The last reserved address */
     58        usb_address_t last_address;
    5959
    6060        /** Size of the bandwidth pool */
    6161        size_t free_bw;
    62         /** The last reserved address */
    63         usb_address_t last_address;
    6462} usb2_bus_t;
    6563
  • uspace/lib/usbhost/include/usb/host/usb_transfer_batch.h

    r9efad54 r56257ba  
    111111void usb_transfer_batch_init(usb_transfer_batch_t *, endpoint_t *);
    112112
    113 /** Call after status is known, but before releasing endpoint */
    114 int usb_transfer_batch_reset_toggle(usb_transfer_batch_t *);
    115 
    116113/** Batch finalization. */
    117114void usb_transfer_batch_abort(usb_transfer_batch_t *);
  • uspace/lib/usbhost/src/bus.c

    r9efad54 r56257ba  
    9999
    100100        const bus_ops_t *ops = BUS_OPS_LOOKUP(dev->bus->ops, device_remove);
    101 
    102101        if (!ops)
    103102                return ENOTSUP;
     
    162161
    163162        fibril_mutex_lock(&bus->guard);
    164         err = register_ops->endpoint_register(ep);
    165         fibril_mutex_unlock(&bus->guard);
     163        if (!device->online && ep->endpoint != 0) {
     164                err = EAGAIN;
     165        } else if (device->endpoints[ep->endpoint] != NULL) {
     166                err = EEXIST;
     167        } else {
     168                err = register_ops->endpoint_register(ep);
     169                if (!err)
     170                        device->endpoints[ep->endpoint] = ep;
     171        }
     172        fibril_mutex_unlock(&bus->guard);
     173        if (err) {
     174                endpoint_del_ref(ep);
     175                return err;
     176        }
    166177
    167178        if (out_ep) {
     
    171182        }
    172183
    173         return err;
     184        return EOK;
    174185}
    175186
    176187/** Searches for an endpoint. Returns a reference.
    177188 */
    178 endpoint_t *bus_find_endpoint(device_t *device, usb_target_t endpoint, usb_direction_t dir)
     189endpoint_t *bus_find_endpoint(device_t *device, usb_endpoint_t endpoint)
    179190{
    180191        assert(device);
     
    182193        bus_t *bus = device->bus;
    183194
    184         const bus_ops_t *ops = BUS_OPS_LOOKUP(bus->ops, device_find_endpoint);
    185         if (!ops)
    186                 return NULL;
    187 
    188         fibril_mutex_lock(&bus->guard);
    189         endpoint_t *ep = ops->device_find_endpoint(device, endpoint, dir);
     195        fibril_mutex_lock(&bus->guard);
     196        endpoint_t *ep = device->endpoints[endpoint];
    190197        if (ep) {
    191198                /* Exporting reference */
    192199                endpoint_add_ref(ep);
    193200        }
    194 
    195201        fibril_mutex_unlock(&bus->guard);
    196202        return ep;
     
    201207        assert(ep);
    202208        assert(ep->device);
    203         assert(ep->device->bus);
    204         assert(ep->device->bus->ops);
    205209
    206210        bus_t *bus = endpoint_get_bus(ep);
     
    218222        fibril_mutex_lock(&bus->guard);
    219223        const int r = ops->endpoint_unregister(ep);
     224        if (!r)
     225                ep->device->endpoints[ep->endpoint] = NULL;
    220226        fibril_mutex_unlock(&bus->guard);
    221227
     
    253259        fibril_mutex_lock(&bus->guard);
    254260        const int r = ops->release_default_address(bus);
    255         fibril_mutex_unlock(&bus->guard);
    256         return r;
    257 }
    258 
    259 int bus_reset_toggle(bus_t *bus, usb_target_t target, bool all)
    260 {
    261         assert(bus);
    262 
    263         const bus_ops_t *ops = BUS_OPS_LOOKUP(bus->ops, reset_toggle);
    264         if (!ops)
    265                 return ENOTSUP;
    266 
    267         fibril_mutex_lock(&bus->guard);
    268         const int r = ops->reset_toggle(bus, target, all);
    269261        fibril_mutex_unlock(&bus->guard);
    270262        return r;
     
    288280
    289281        /* Temporary reference */
    290         endpoint_t *ep = bus_find_endpoint(device, target, direction);
     282        endpoint_t *ep = bus_find_endpoint(device, target.endpoint);
    291283        if (ep == NULL) {
    292284                usb_log_error("Endpoint(%d:%d) not registered for %s.\n",
  • uspace/lib/usbhost/src/ddf_helpers.c

    r9efad54 r56257ba  
    106106        assert(dev);
    107107
    108         const usb_target_t target = {{
    109                 .address = dev->address,
    110                 .endpoint = endpoint_desc->endpoint_no
    111         }};
    112 
    113         endpoint_t *ep = bus_find_endpoint(dev, target, endpoint_desc->direction);
     108        endpoint_t *ep = bus_find_endpoint(dev, endpoint_desc->endpoint_no);
    114109        if (!ep)
    115110                return ENOENT;
  • uspace/lib/usbhost/src/endpoint.c

    r9efad54 r56257ba  
    108108}
    109109
     110static void endpoint_toggle_reset(endpoint_t *ep, toggle_reset_mode_t mode);
     111
    110112/** Mark the endpoint as active and block access for further fibrils.
    111113 * @param ep endpoint_t structure.
     
    132134
    133135        if (ep->active_batch && ep->active_batch->error == EOK)
    134                 usb_transfer_batch_reset_toggle(ep->active_batch);
     136                endpoint_toggle_reset(ep, ep->active_batch->toggle_reset_mode);
    135137
    136138        ep->active_batch = NULL;
     
    155157}
    156158
    157 /** Get the value of toggle bit. Either uses the toggle_get op, or just returns
    158  * the value of the toggle.
    159  * @param ep endpoint_t structure.
    160  */
    161 int endpoint_toggle_get(endpoint_t *ep)
    162 {
    163         assert(ep);
    164 
    165         const bus_ops_t *ops = BUS_OPS_LOOKUP(get_bus_ops(ep), endpoint_get_toggle);
    166         return ops
    167             ? ops->endpoint_get_toggle(ep)
    168             : ep->toggle;
    169 }
    170 
    171 /** Set the value of toggle bit. Either uses the toggle_set op, or just sets
    172  * the toggle inside.
    173  * @param ep endpoint_t structure.
    174  */
    175 void endpoint_toggle_set(endpoint_t *ep, bool toggle)
    176 {
    177         assert(ep);
    178 
    179         const bus_ops_t *ops = BUS_OPS_LOOKUP(get_bus_ops(ep), endpoint_set_toggle);
    180         if (ops) {
    181                 ops->endpoint_set_toggle(ep, toggle);
    182         }
    183         else {
    184                 ep->toggle = toggle;
     159static void endpoint_toggle_reset(endpoint_t *ep, toggle_reset_mode_t mode)
     160{
     161        assert(ep);
     162
     163        if (mode == RESET_NONE)
     164                return;
     165
     166        const bus_ops_t *ops = BUS_OPS_LOOKUP(get_bus_ops(ep), endpoint_toggle_reset);
     167        if (!ops)
     168                return;
     169
     170        device_t *dev = ep->device;
     171
     172        if (mode == RESET_ALL) {
     173                for (usb_endpoint_t i = 0; i < USB_ENDPOINT_MAX; ++i) {
     174                        if (dev->endpoints[i])
     175                                ops->endpoint_toggle_reset(dev->endpoints[i]);
     176                }
     177        } else {
     178                ops->endpoint_toggle_reset(ep);
    185179        }
    186180}
  • uspace/lib/usbhost/src/usb2_bus.c

    r9efad54 r56257ba  
    5757}
    5858
    59 /** Get list that holds endpoints for given address.
    60  * @param bus usb2_bus structure, non-null.
    61  * @param addr USB address, must be >= 0.
    62  * @return Pointer to the appropriate list.
    63  */
    64 static list_t * get_list(usb2_bus_t *bus, usb_address_t addr)
    65 {
    66         assert(bus);
    67         assert(addr >= 0);
    68         return &bus->devices[addr % ARRAY_SIZE(bus->devices)].endpoint_list;
    69 }
    70 
    71 /** Get speed assigned to USB address.
    72  *
    73  * @param[in] bus Device manager structure to use.
    74  * @param[in] address Address the caller wants to find.
    75  * @param[out] speed Assigned speed.
    76  * @return Error code.
    77  */
    78 static int get_speed(usb2_bus_t *bus, usb_address_t address, usb_speed_t *speed)
    79 {
    80         if (!usb_address_is_valid(address))
    81                 return EINVAL;
    82 
    83         if (!bus->devices[address].occupied)
    84                 return ENOENT;
    85 
    86         if (speed)
    87                 *speed = bus->devices[address].speed;
    88 
    89         return EOK;
    90 }
    91 
    9259/** Get a free USB address
    9360 *
     
    10471                if (new_address == bus->last_address)
    10572                        return ENOSPC;
    106         } while (bus->devices[new_address].occupied);
     73        } while (bus->address_occupied[new_address]);
    10774
    10875        assert(new_address != USB_ADDRESS_DEFAULT);
     
    12592                return EINVAL;
    12693
    127         const int ret = bus->devices[address].occupied ? EOK : ENOENT;
    128         bus->devices[address].occupied = false;
    129 
    130         list_t *list = get_list(bus, address);
    131         for (link_t *link = list_first(list); link != NULL; ) {
    132                 endpoint_t *ep = list_get_instance(link, endpoint_t, link);
    133                 link = list_next(link, list);
    134 
    135                 assert(ep->device->address == address);
    136                 list_remove(&ep->link);
    137 
    138                 usb_log_warning("Endpoint %d:%d %s was left behind, removing.\n",
    139                     address, ep->endpoint, usb_str_direction(ep->direction));
    140 
    141                 /* Drop bus reference */
    142                 endpoint_del_ref(ep);
    143         }
    144 
     94        const int ret = bus->address_occupied[address] ? EOK : ENOENT;
     95        bus->address_occupied[address] = false;
    14596        return ret;
    14697}
     
    153104 * @note Default address is only available in strict mode.
    154105 */
    155 static int request_address(usb2_bus_t *bus, usb_address_t *addr, bool strict, usb_speed_t speed)
     106static int request_address(usb2_bus_t *bus, usb_address_t *addr, bool strict)
    156107{
    157108        int err;
     
    168119                        return err;
    169120        }
    170         else if (bus->devices[*addr].occupied) {
     121        else if (bus->address_occupied[*addr]) {
    171122                if (strict) {
    172123                        return ENOENT;
     
    177128
    178129        assert(usb_address_is_valid(*addr));
    179         assert(bus->devices[*addr].occupied == false);
     130        assert(bus->address_occupied[*addr] == false);
    180131        assert(*addr != USB_ADDRESS_DEFAULT || strict);
    181132
    182         bus->devices[*addr].occupied = true;
    183         bus->devices[*addr].speed = speed;
     133        bus->address_occupied[*addr] = true;
    184134
    185135        return EOK;
     
    202152        /** Reserve address early, we want pretty log messages */
    203153        usb_address_t address = USB_ADDRESS_DEFAULT;
    204         if ((err = request_address(bus, &address, false, dev->speed))) {
     154        if ((err = request_address(bus, &address, false))) {
    205155                usb_log_error("Failed to reserve new address: %s.",
    206156                    str_error(err));
     
    281231         * default address.
    282232         */
    283         if ((err = get_speed(bus, USB_ADDRESS_DEFAULT, &dev->speed))) {
    284                 usb_log_error("Failed to verify speed: %s.", str_error(err));
    285                 return err;
    286         }
     233        dev->speed = bus->default_address_speed;
    287234        usb_log_debug("Found new %s speed USB device.", usb_str_speed(dev->speed));
    288235
     
    313260}
    314261
    315 /** Find endpoint.
    316  * @param bus usb_bus structure, non-null.
    317  * @param target Endpoint address.
    318  * @param direction Communication direction.
    319  * @return Pointer to endpoint_t structure representing given communication
    320  * target, NULL if there is no such endpoint registered.
    321  * @note Assumes that the internal mutex is locked.
    322  */
    323 static endpoint_t *usb2_bus_find_ep(device_t *device, usb_target_t target, usb_direction_t direction)
    324 {
    325         usb2_bus_t *bus = bus_to_usb2_bus(device->bus);
    326 
    327         assert(device->address == target.address);
    328 
    329         list_foreach(*get_list(bus, target.address), link, endpoint_t, ep) {
    330                 if (((direction == ep->direction)
    331                        || (ep->direction == USB_DIRECTION_BOTH)
    332                        || (direction == USB_DIRECTION_BOTH))
    333                     && (target.endpoint == ep->endpoint))
    334                         return ep;
    335         }
    336         return NULL;
    337 }
    338 
    339262static endpoint_t *usb2_bus_create_ep(device_t *dev, const usb_endpoint_descriptors_t *desc)
    340263{
     
    347270}
    348271
    349 static usb_target_t usb2_ep_to_target(endpoint_t *ep)
    350 {
    351         assert(ep);
    352         assert(ep->device);
    353 
    354         return (usb_target_t) {{
    355                 .address = ep->device->address,
    356                 .endpoint = ep->endpoint,
    357         }};
    358 }
    359 
    360272/** Register an endpoint to the bus. Reserves bandwidth.
    361273 * @param bus usb_bus structure, non-null.
     
    368280        assert(ep);
    369281
    370         /* Check for existence */
    371         if (usb2_bus_find_ep(ep->device, usb2_ep_to_target(ep), ep->direction))
    372                 return EEXIST;
    373 
    374282        /* Check for available bandwidth */
    375283        if (ep->bandwidth > bus->free_bw)
    376284                return ENOSPC;
    377285
    378         endpoint_add_ref(ep);
    379         list_append(&ep->link, get_list(bus, ep->device->address));
    380286        bus->free_bw -= ep->bandwidth;
    381287
     
    390296        assert(ep);
    391297
    392         list_remove(&ep->link);
    393 
    394298        bus->free_bw += ep->bandwidth;
    395         endpoint_del_ref(ep);
    396 
    397         return EOK;
    398 }
    399 
    400 static int usb2_bus_reset_toggle(bus_t *bus_base, usb_target_t target, toggle_reset_mode_t mode)
    401 {
    402         usb2_bus_t *bus = bus_to_usb2_bus(bus_base);
    403 
    404         if (!usb_target_is_valid(target))
    405                 return EINVAL;
    406 
    407         if (mode == RESET_NONE)
    408                 return EOK;
    409 
    410         int ret = ENOENT;
    411 
    412         list_foreach(*get_list(bus, target.address), link, endpoint_t, ep) {
    413                 assert(ep->device->address == target.address);
    414 
    415                 if (mode == RESET_ALL || ep->endpoint == target.endpoint) {
    416                         endpoint_toggle_set(ep, 0);
    417                         ret = EOK;
    418                 }
    419         }
    420         return ret;
     299
     300        return EOK;
    421301}
    422302
     
    425305        usb2_bus_t *bus = bus_to_usb2_bus(bus_base);
    426306        usb_address_t addr = USB_ADDRESS_DEFAULT;
    427         return request_address(bus, &addr, true, speed);
     307        const int err = request_address(bus, &addr, true);
     308        if (err)
     309                return err;
     310        bus->default_address_speed = speed;
     311        return EOK;
    428312}
    429313
     
    437321        .reserve_default_address = usb2_bus_register_default_address,
    438322        .release_default_address = usb2_bus_release_default_address,
    439         .reset_toggle = usb2_bus_reset_toggle,
    440323        .device_enumerate = usb2_bus_device_enumerate,
    441         .device_find_endpoint = usb2_bus_find_ep,
    442324        .endpoint_create = usb2_bus_create_ep,
    443325        .endpoint_register = usb2_bus_register_ep,
     
    460342
    461343        bus->free_bw = available_bandwidth;
    462         bus->last_address = 0;
    463         for (unsigned i = 0; i < ARRAY_SIZE(bus->devices); ++i) {
    464                 list_initialize(&bus->devices[i].endpoint_list);
    465                 bus->devices[i].speed = USB_SPEED_MAX;
    466                 bus->devices[i].occupied = false;
    467         }
     344
    468345        return EOK;
    469346}
  • uspace/lib/usbhost/src/usb_transfer_batch.c

    r9efad54 r56257ba  
    7171}
    7272
    73 /** Resolve resetting toggle.
    74  *
    75  * @param[in] batch Batch structure to use.
    76  */
    77 int usb_transfer_batch_reset_toggle(usb_transfer_batch_t *batch)
    78 {
    79         assert(batch);
    80 
    81         if (batch->error != EOK || batch->toggle_reset_mode == RESET_NONE)
    82                 return EOK;
    83 
    84         usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT " resets %s",
    85             batch, USB_TRANSFER_BATCH_ARGS(*batch),
    86             batch->toggle_reset_mode == RESET_ALL ? "all EPs toggle" : "EP toggle");
    87 
    88         return bus_reset_toggle(endpoint_get_bus(batch->ep), batch->target, batch->toggle_reset_mode);
    89 }
    90 
    9173/** Destroy the batch.
    9274 *
Note: See TracChangeset for help on using the changeset viewer.