Changeset 41924f30 in mainline for uspace/lib/usbhost/src


Ignore:
Timestamp:
2017-10-12T14:07:27Z (8 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a5976973
Parents:
7e74911
Message:

WIP usbhost refactoring

This commit replaces callbacks with more systematic virtual-like inheritance-like solution. Currently breaks build of HelenOS, but both xhci and usbhost are buildable. More refactoring follows…

Location:
uspace/lib/usbhost/src
Files:
3 added
1 deleted
3 edited

Legend:

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

    r7e74911 r41924f30  
    469469
    470470        /* This checks whether the default address is reserved and gets speed */
    471         int ret = usb_bus_get_speed(&hcd->bus, USB_ADDRESS_DEFAULT, &speed);
     471        int ret = bus_get_speed(hcd->bus, USB_ADDRESS_DEFAULT, &speed);
    472472        if (ret != EOK) {
    473473                usb_log_error("Failed to verify speed: %s.", str_error(ret));
     
    623623        assert(hcd);
    624624
    625         hcd_reserve_default_address(hcd, hcd->bus.max_speed);
     625        hcd_reserve_default_address(hcd, USB_SPEED_MAX);
    626626        const int ret = hcd_ddf_new_device(device, NULL, 0);
    627627        hcd_release_default_address(hcd);
     
    639639 * This function does all the ddf work for hc driver.
    640640 */
    641 int hcd_ddf_setup_hc(ddf_dev_t *device, usb_speed_t max_speed,
    642     size_t bw, bw_count_func_t bw_count)
     641int hcd_ddf_setup_hc(ddf_dev_t *device)
    643642{
    644643        assert(device);
     
    650649        }
    651650        instance->root_hub = NULL;
    652         hcd_init(&instance->hcd, max_speed, bw, bw_count);
     651        hcd_init(&instance->hcd);
    653652
    654653        int ret = ENOMEM;
     
    851850{
    852851        assert(driver);
    853         static const struct { size_t bw; bw_count_func_t bw_count; }bw[] = {
    854             [USB_SPEED_FULL] = { .bw = BANDWIDTH_AVAILABLE_USB11,
    855                                  .bw_count = bandwidth_count_usb11 },
    856             [USB_SPEED_HIGH] = { .bw = BANDWIDTH_AVAILABLE_USB11,
    857                                  .bw_count = bandwidth_count_usb11 },
    858             [USB_SPEED_SUPER] = { .bw = BANDWIDTH_AVAILABLE_USB11,
    859                                  .bw_count = bandwidth_count_usb11 },
    860         };
    861852
    862853        int ret = EOK;
    863         const usb_speed_t speed = driver->hc_speed;
    864         if (speed >= ARRAY_SIZE(bw) || bw[speed].bw == 0) {
    865                 usb_log_error("Driver `%s' reported unsupported speed: %s",
    866                     driver->name, usb_str_speed(speed));
    867                 return ENOTSUP;
    868         }
    869854
    870855        hw_res_list_parsed_t hw_res;
     
    877862        }
    878863
    879         ret = hcd_ddf_setup_hc(device, speed, bw[speed].bw, bw[speed].bw_count);
     864        ret = hcd_ddf_setup_hc(device);
    880865        if (ret != EOK) {
    881866                usb_log_error("Failed to setup generic HCD.\n");
  • uspace/lib/usbhost/src/endpoint.c

    r7e74911 r41924f30  
    11/*
    22 * Copyright (c) 2011 Jan Vesely
     3 * Copyright (c) 2017 Ondrej Hlavaty <aearsis@eideo.cz>
    34 * All rights reserved.
    45 *
     
    3536
    3637#include <usb/host/endpoint.h>
     38#include <usb/host/bus.h>
    3739
    3840#include <assert.h>
     41#include <atomic.h>
     42#include <mem.h>
    3943#include <stdlib.h>
    40 #include <atomic.h>
    4144
    42 /** Allocate ad initialize endpoint_t structure.
    43  * @param address USB address.
    44  * @param endpoint USB endpoint number.
    45  * @param direction Communication direction.
    46  * @param type USB transfer type.
    47  * @param speed Communication speed.
    48  * @param max_packet_size Maximum size of data packets.
    49  * @param bw Required bandwidth.
    50  * @return Pointer to initialized endpoint_t structure, NULL on failure.
     45/** Initialize provided endpoint structure.
    5146 */
    52 endpoint_t * endpoint_create(usb_address_t address, usb_endpoint_t endpoint,
    53     usb_direction_t direction, usb_transfer_type_t type, usb_speed_t speed,
    54     size_t max_packet_size, unsigned packets, size_t bw,
    55     usb_address_t tt_address, unsigned tt_p)
     47void endpoint_init(endpoint_t *ep, bus_t *bus)
    5648{
    57         endpoint_t *instance = malloc(sizeof(endpoint_t));
    58         if (instance) {
    59                 atomic_set(&instance->refcnt, 0);
    60                 instance->address = address;
    61                 instance->endpoint = endpoint;
    62                 instance->direction = direction;
    63                 instance->transfer_type = type;
    64                 instance->speed = speed;
    65                 instance->max_packet_size = max_packet_size;
    66                 instance->packets = packets;
    67                 instance->bandwidth = bw;
    68                 instance->toggle = 0;
    69                 instance->active = false;
    70                 instance->tt.address = tt_address;
    71                 instance->tt.port = tt_p;
    72                 instance->hc_data.data = NULL;
    73                 instance->hc_data.toggle_get = NULL;
    74                 instance->hc_data.toggle_set = NULL;
    75                 link_initialize(&instance->link);
    76                 fibril_mutex_initialize(&instance->guard);
    77                 fibril_condvar_initialize(&instance->avail);
    78         }
    79         return instance;
     49        memset(ep, 0, sizeof(endpoint_t));
     50
     51        ep->bus = bus;
     52        atomic_set(&ep->refcnt, 0);
     53        link_initialize(&ep->link);
     54        fibril_mutex_initialize(&ep->guard);
     55        fibril_condvar_initialize(&ep->avail);
    8056}
    8157
    82 /** Properly dispose of endpoint_t structure.
    83  * @param instance endpoint_t structure.
    84  */
    85 void endpoint_destroy(endpoint_t *instance)
     58void endpoint_add_ref(endpoint_t *ep)
    8659{
    87         assert(instance);
    88         assert(!instance->active);
    89         assert(instance->hc_data.data == NULL);
    90         free(instance);
     60        atomic_inc(&ep->refcnt);
    9161}
    9262
    93 void endpoint_add_ref(endpoint_t *instance)
     63void endpoint_del_ref(endpoint_t *ep)
    9464{
    95         atomic_inc(&instance->refcnt);
    96 }
     65        if (atomic_predec(&ep->refcnt) == 0) {
     66                if (ep->bus->ops.destroy_endpoint) {
     67                        ep->bus->ops.destroy_endpoint(ep);
     68                }
     69                else {
     70                        assert(!ep->active);
    9771
    98 void endpoint_del_ref(endpoint_t *instance)
    99 {
    100         if (atomic_predec(&instance->refcnt) == 0)
    101                 endpoint_destroy(instance);
    102 }
    103 
    104 /** Set device specific data and hooks.
    105  * @param instance endpoint_t structure.
    106  * @param data device specific data.
    107  * @param toggle_get Hook to call when retrieving value of toggle bit.
    108  * @param toggle_set Hook to call when setting the value of toggle bit.
    109  */
    110 void endpoint_set_hc_data(endpoint_t *instance,
    111     void *data, int (*toggle_get)(void *), void (*toggle_set)(void *, int))
    112 {
    113         assert(instance);
    114         fibril_mutex_lock(&instance->guard);
    115         instance->hc_data.data = data;
    116         instance->hc_data.toggle_get = toggle_get;
    117         instance->hc_data.toggle_set = toggle_set;
    118         fibril_mutex_unlock(&instance->guard);
    119 }
    120 
    121 /** Clear device specific data and hooks.
    122  * @param instance endpoint_t structure.
    123  * @note This function does not free memory pointed to by data pointer.
    124  */
    125 void endpoint_clear_hc_data(endpoint_t *instance)
    126 {
    127         assert(instance);
    128         endpoint_set_hc_data(instance, NULL, NULL, NULL);
     72                        /* Assume mostly the eps will be allocated by malloc. */
     73                        free(ep);
     74                }
     75        }
    12976}
    13077
    13178/** Mark the endpoint as active and block access for further fibrils.
    132  * @param instance endpoint_t structure.
     79 * @param ep endpoint_t structure.
    13380 */
    134 void endpoint_use(endpoint_t *instance)
     81void endpoint_use(endpoint_t *ep)
    13582{
    136         assert(instance);
     83        assert(ep);
    13784        /* Add reference for active endpoint. */
    138         endpoint_add_ref(instance);
    139         fibril_mutex_lock(&instance->guard);
    140         while (instance->active)
    141                 fibril_condvar_wait(&instance->avail, &instance->guard);
    142         instance->active = true;
    143         fibril_mutex_unlock(&instance->guard);
     85        endpoint_add_ref(ep);
     86        fibril_mutex_lock(&ep->guard);
     87        while (ep->active)
     88                fibril_condvar_wait(&ep->avail, &ep->guard);
     89        ep->active = true;
     90        fibril_mutex_unlock(&ep->guard);
    14491}
    14592
    14693/** Mark the endpoint as inactive and allow access for further fibrils.
    147  * @param instance endpoint_t structure.
     94 * @param ep endpoint_t structure.
    14895 */
    149 void endpoint_release(endpoint_t *instance)
     96void endpoint_release(endpoint_t *ep)
    15097{
    151         assert(instance);
    152         fibril_mutex_lock(&instance->guard);
    153         instance->active = false;
    154         fibril_mutex_unlock(&instance->guard);
    155         fibril_condvar_signal(&instance->avail);
     98        assert(ep);
     99        fibril_mutex_lock(&ep->guard);
     100        ep->active = false;
     101        fibril_mutex_unlock(&ep->guard);
     102        fibril_condvar_signal(&ep->avail);
    156103        /* Drop reference for active endpoint. */
    157         endpoint_del_ref(instance);
     104        endpoint_del_ref(ep);
    158105}
    159106
    160 /** Get the value of toggle bit.
    161  * @param instance endpoint_t structure.
    162  * @note Will use provided hook.
     107/** Get the value of toggle bit. Either uses the toggle_get op, or just returns
     108 * the value of the toggle.
     109 * @param ep endpoint_t structure.
    163110 */
    164 int endpoint_toggle_get(endpoint_t *instance)
     111int endpoint_toggle_get(endpoint_t *ep)
    165112{
    166         assert(instance);
    167         fibril_mutex_lock(&instance->guard);
    168         if (instance->hc_data.toggle_get)
    169                 instance->toggle =
    170                     instance->hc_data.toggle_get(instance->hc_data.data);
    171         const int ret = instance->toggle;
    172         fibril_mutex_unlock(&instance->guard);
     113        assert(ep);
     114        fibril_mutex_lock(&ep->guard);
     115        const int ret = ep->bus->ops.endpoint_get_toggle
     116            ? ep->bus->ops.endpoint_get_toggle(ep)
     117            : ep->toggle;
     118        fibril_mutex_unlock(&ep->guard);
    173119        return ret;
    174120}
    175121
    176 /** Set the value of toggle bit.
    177  * @param instance endpoint_t structure.
    178  * @note Will use provided hook.
     122/** Set the value of toggle bit. Either uses the toggle_set op, or just sets
     123 * the toggle inside.
     124 * @param ep endpoint_t structure.
    179125 */
    180 void endpoint_toggle_set(endpoint_t *instance, int toggle)
     126void endpoint_toggle_set(endpoint_t *ep, unsigned toggle)
    181127{
    182         assert(instance);
     128        assert(ep);
    183129        assert(toggle == 0 || toggle == 1);
    184         fibril_mutex_lock(&instance->guard);
    185         instance->toggle = toggle;
    186         if (instance->hc_data.toggle_set)
    187                 instance->hc_data.toggle_set(instance->hc_data.data, toggle);
    188         fibril_mutex_unlock(&instance->guard);
     130        fibril_mutex_lock(&ep->guard);
     131        if (ep->bus->ops.endpoint_set_toggle) {
     132                ep->bus->ops.endpoint_set_toggle(ep, toggle);
     133        }
     134        else {
     135                ep->toggle = toggle;
     136        }
     137        fibril_mutex_unlock(&ep->guard);
    189138}
     139
    190140
    191141/**
  • uspace/lib/usbhost/src/hcd.c

    r7e74911 r41924f30  
    4444#include "hcd.h"
    4545
    46 /** Calls ep_add_hook upon endpoint registration.
     46
     47/*[>* Calls ep_add_hook upon endpoint registration.
    4748 * @param ep Endpoint to be registered.
    4849 * @param arg hcd_t in disguise.
    4950 * @return Error code.
    50  */
     51 * OH TODO: remove
     52 <]
    5153static int register_helper(endpoint_t *ep, void *arg)
    5254{
     
    5961}
    6062
    61 /** Calls ep_remove_hook upon endpoint removal.
     63[>* Calls ep_remove_hook upon endpoint removal.
    6264 * @param ep Endpoint to be unregistered.
    6365 * @param arg hcd_t in disguise.
    64  */
     66 * OH TODO: remove
     67 <]
    6568static void unregister_helper(endpoint_t *ep, void *arg)
    6669{
     
    7275}
    7376
    74 /** Calls ep_remove_hook upon endpoint removal. Prints warning.
     77[>* Calls ep_remove_hook upon endpoint removal. Prints warning.
    7578 *  * @param ep Endpoint to be unregistered.
    7679 *   * @param arg hcd_t in disguise.
    77  *    */
     80 * OH TODO: remove
     81 *    <]
    7882static void unregister_helper_warn(endpoint_t *ep, void *arg)
    7983{
    8084        assert(ep);
    8185        usb_log_warning("Endpoint %d:%d %s was left behind, removing.\n",
    82             ep->address, ep->endpoint, usb_str_direction(ep->direction));
     86            ep->target.address, ep->target.endpoint, usb_str_direction(ep->direction));
    8387        unregister_helper(ep, arg);
    8488}
    85 
     89*/
    8690
    8791/** Initialize hcd_t structure.
     
    9397 * @param bw_count Bandwidth compute function, passed to endpoint manager.
    9498 */
    95 void hcd_init(hcd_t *hcd, usb_speed_t max_speed, size_t bandwidth,
    96     bw_count_func_t bw_count)
    97 {
    98         assert(hcd);
    99         usb_bus_init(&hcd->bus, bandwidth, bw_count, max_speed);
    100 
    101         hcd_set_implementation(hcd, NULL, NULL);
     99void hcd_init(hcd_t *hcd) {
     100        assert(hcd);
     101
     102        hcd_set_implementation(hcd, NULL, NULL, NULL);
    102103}
    103104
     
    106107        assert(hcd);
    107108        usb_address_t address = 0;
    108         const int ret = usb_bus_request_address(
    109             &hcd->bus, &address, false, speed);
     109        const int ret = bus_request_address(hcd->bus, &address, false, speed);
    110110        if (ret != EOK)
    111111                return ret;
     
    116116{
    117117        assert(hcd);
    118         return usb_bus_remove_address(&hcd->bus, address,
    119             unregister_helper_warn, hcd);
     118        return bus_release_address(hcd->bus, address);
     119        // OH TODO removed helper
    120120}
    121121
     
    124124        assert(hcd);
    125125        usb_address_t address = 0;
    126         return usb_bus_request_address(&hcd->bus, &address, true, speed);
     126        return bus_request_address(hcd->bus, &address, true, speed);
    127127}
    128128
     
    132132{
    133133        assert(hcd);
    134         return usb_bus_add_ep(&hcd->bus, target.address,
    135             target.endpoint, dir, type, max_packet_size, packets, size,
    136             register_helper, hcd, tt_address, tt_port);
     134
     135        /* Temporary reference */
     136        endpoint_t *ep = bus_create_endpoint(hcd->bus);
     137        if (!ep)
     138                return ENOMEM;
     139
     140        ep->target = target;
     141        ep->direction = dir;
     142        ep->transfer_type = type;
     143        ep->max_packet_size = max_packet_size;
     144        ep->packets = packets;
     145
     146        ep->tt.address = tt_address;
     147        ep->tt.port = tt_port;
     148
     149        const int err = bus_register_endpoint(hcd->bus, ep);
     150
     151        /* drop Temporary reference */
     152        endpoint_del_ref(ep);
     153
     154        return err;
    137155}
    138156
     
    140158{
    141159        assert(hcd);
    142         return usb_bus_remove_ep(&hcd->bus, target.address,
    143             target.endpoint, dir, unregister_helper, hcd);
     160        endpoint_t *ep = bus_find_endpoint(hcd->bus, target, dir);
     161        if (!ep)
     162                return ENOENT;
     163
     164        return bus_release_endpoint(hcd->bus, ep);
     165        // OH TODO removed helper
    144166}
    145167
     
    159181                usb_log_debug2("Reseting toggle on %d:%d.\n",
    160182                    toggle->target.address, toggle->target.endpoint);
    161                 usb_bus_reset_toggle(&toggle->hcd->bus,
     183                bus_reset_toggle(toggle->hcd->bus,
    162184                    toggle->target, toggle->target.endpoint == 0);
    163185        }
     
    185207        assert(hcd);
    186208
    187         endpoint_t *ep = usb_bus_find_ep(&hcd->bus,
    188             target.address, target.endpoint, direction);
     209        endpoint_t *ep = bus_find_endpoint(hcd->bus, target, direction);
    189210        if (ep == NULL) {
    190211                usb_log_error("Endpoint(%d:%d) not registered for %s.\n",
     
    196217            name, target.address, target.endpoint, size, ep->max_packet_size);
    197218
    198         const size_t bw = bandwidth_count_usb11(
    199             ep->speed, ep->transfer_type, size, ep->max_packet_size);
     219        const size_t bw = bus_count_bw(ep, size);
    200220        /* Check if we have enough bandwidth reserved */
    201221        if (ep->bandwidth < bw) {
    202222                usb_log_error("Endpoint(%d:%d) %s needs %zu bw "
    203223                    "but only %zu is reserved.\n",
    204                     ep->address, ep->endpoint, name, bw, ep->bandwidth);
     224                    ep->target.address, ep->target.endpoint, name, bw, ep->bandwidth);
    205225                return ENOSPC;
    206226        }
Note: See TracChangeset for help on using the changeset viewer.