Changeset 6832245 in mainline for uspace/lib/usbhost


Ignore:
Timestamp:
2017-12-14T23:01:57Z (8 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
837d53d
Parents:
bd05140
git-author:
Ondřej Hlavatý <aearsis@…> (2017-12-14 23:01:54)
git-committer:
Ondřej Hlavatý <aearsis@…> (2017-12-14 23:01:57)
Message:

usbhost bus: refactor the bus ops

This way, method names better represent the entity it is working with.
Their semantics was shifted a bit.

Regarding the tree of structures:

bus ← device ← endpoint ← batch

Previously, devices were kept in DDF function nodes, and endpoints had
pointer to the bus and device. Now, devices have pointer to bus,
endpoints don't.

Pointer to hcd_t in bus is WIP, and will be removed.

Location:
uspace/lib/usbhost
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usbhost/include/usb/host/bandwidth.h

    rbd05140 r6832245  
    5151typedef struct endpoint endpoint_t;
    5252
    53 extern size_t bandwidth_count_usb11(endpoint_t *, size_t);
     53extern ssize_t bandwidth_count_usb11(endpoint_t *, size_t);
    5454
    55 extern size_t bandwidth_count_usb20(endpoint_t *, size_t);
     55extern ssize_t bandwidth_count_usb20(endpoint_t *, size_t);
    5656
    5757#endif
  • uspace/lib/usbhost/include/usb/host/bus.h

    rbd05140 r6832245  
    7777        usb_address_t address;
    7878
     79        /* Managing bus */
     80        bus_t *bus;
     81
    7982        /* This structure is meant to be extended by overriding. */
    8083} device_t;
    8184
    82 typedef struct {
    83         int (*enumerate_device)(bus_t *, hcd_t *, device_t *);
    84         int (*remove_device)(bus_t *, hcd_t *, device_t *);
     85typedef struct bus_ops bus_ops_t;
    8586
    86         int (*online_device)(bus_t *, hcd_t *, device_t *);                     /**< Optional */
    87         int (*offline_device)(bus_t *, hcd_t *, device_t *);                    /**< Optional */
     87/**
     88 * Operations structure serving as an interface of hc driver for the library
     89 * (and the rest of the system).
     90 */
     91struct bus_ops {
     92        /* Undefined operations will be delegated to parent ops */
     93        const bus_ops_t *parent;
    8894
    89         /* The following operations are protected by a bus guard. */
    90         endpoint_t *(*create_endpoint)(bus_t *);
    91         int (*register_endpoint)(bus_t *, device_t *, endpoint_t *, const usb_endpoint_desc_t *);
    92         int (*unregister_endpoint)(bus_t *, endpoint_t *);
    93         endpoint_t *(*find_endpoint)(bus_t *, device_t*, usb_target_t, usb_direction_t);
    94         void (*destroy_endpoint)(endpoint_t *);                 /**< Optional */
     95        /* Global operations on the bus */
     96        int (*reserve_default_address)(bus_t *, usb_speed_t);
     97        int (*release_default_address)(bus_t *);
     98        int (*reset_toggle)(bus_t *, usb_target_t, toggle_reset_mode_t);
     99
     100        /* Operations on device */
     101        int (*device_enumerate)(device_t *);
     102        int (*device_remove)(device_t *);
     103        int (*device_online)(device_t *);                       /**< Optional */
     104        int (*device_offline)(device_t *);                      /**< Optional */
     105        endpoint_t *(*device_find_endpoint)(device_t*, usb_target_t, usb_direction_t);
     106        endpoint_t *(*endpoint_create)(device_t *, const usb_endpoint_desc_t *);
     107
     108        /* Operations on endpoint */
     109        int (*endpoint_register)(endpoint_t *);
     110        int (*endpoint_unregister)(endpoint_t *);
     111        void (*endpoint_destroy)(endpoint_t *);                 /**< Optional */
    95112        bool (*endpoint_get_toggle)(endpoint_t *);              /**< Optional */
    96113        void (*endpoint_set_toggle)(endpoint_t *, bool);        /**< Optional */
     114        ssize_t (*endpoint_count_bw) (endpoint_t *, size_t);
     115        usb_transfer_batch_t *(*batch_create)(endpoint_t *);    /**< Optional */
    97116
    98         int (*reserve_default_address)(bus_t *, usb_speed_t);
    99         int (*release_default_address)(bus_t *);
     117        /* Operations on batch */
     118        void (*batch_destroy)(usb_transfer_batch_t *);  /**< Optional */
     119};
    100120
    101         int (*reset_toggle)(bus_t *, usb_target_t, toggle_reset_mode_t);
    102 
    103         size_t (*count_bw) (endpoint_t *, size_t);
    104 
    105         usb_transfer_batch_t *(*create_batch)(bus_t *, endpoint_t *); /**< Optional */
    106         void (*destroy_batch)(usb_transfer_batch_t *);  /**< Optional */
    107 } bus_ops_t;
     121/**
     122 * Use this macro to lookup virtual function.
     123 */
     124#define BUS_OPS_LOOKUP(start, fn) ({ bus_ops_t const * ops = (start); while (ops && ops->fn == NULL) ops = ops->parent; ops; })
    108125
    109126/** Endpoint management structure */
     
    112129        fibril_mutex_t guard;
    113130
     131        /* TODO: get rid of this one. */
     132        hcd_t *hcd;
     133
    114134        size_t device_size;
    115135
    116136        /* Do not call directly, ops are synchronized. */
    117         bus_ops_t ops;
     137        const bus_ops_t *ops;
    118138
    119139        /* This structure is meant to be extended by overriding. */
    120140} bus_t;
    121141
    122 void bus_init(bus_t *, size_t);
    123 int device_init(device_t *);
     142void bus_init(bus_t *, hcd_t *, size_t);
     143int bus_device_init(device_t *, bus_t *);
    124144
    125 int device_set_default_name(device_t *);
     145int bus_device_set_default_name(device_t *);
    126146
    127 int bus_enumerate_device(bus_t *, hcd_t *, device_t *);
    128 int bus_remove_device(bus_t *, hcd_t *, device_t *);
     147int bus_device_enumerate(device_t *);
     148int bus_device_remove(device_t *);
    129149
    130 int bus_online_device(bus_t *, hcd_t *, device_t *);
    131 int bus_offline_device(bus_t *, hcd_t *, device_t *);
     150int bus_device_online(device_t *);
     151int bus_device_offline(device_t *);
    132152
    133 int bus_add_endpoint(bus_t *, device_t *, const usb_endpoint_desc_t *, endpoint_t **);
    134 endpoint_t *bus_find_endpoint(bus_t *, device_t *, usb_target_t, usb_direction_t);
    135 int bus_remove_endpoint(bus_t *, endpoint_t *);
    136 
    137 size_t bus_count_bw(endpoint_t *, size_t);
     153int bus_endpoint_add(device_t *, const usb_endpoint_desc_t *, endpoint_t **);
     154endpoint_t *bus_find_endpoint(device_t *, usb_target_t, usb_direction_t);
     155int bus_endpoint_remove(endpoint_t *);
    138156
    139157int bus_reserve_default_address(bus_t *, usb_speed_t);
  • uspace/lib/usbhost/include/usb/host/ddf_helpers.h

    rbd05140 r6832245  
    8181int hcd_setup_virtual_root_hub(hcd_t *, ddf_dev_t *);
    8282
    83 device_t *hcd_ddf_device_create(ddf_dev_t *, size_t);
     83device_t *hcd_ddf_device_create(ddf_dev_t *, bus_t *);
    8484void hcd_ddf_device_destroy(device_t *);
    85 int hcd_ddf_device_explore(hcd_t *, device_t *);
     85int hcd_ddf_device_explore(device_t *);
    8686int hcd_ddf_device_online(ddf_fun_t *);
    8787int hcd_ddf_device_offline(ddf_fun_t *);
  • uspace/lib/usbhost/include/usb/host/endpoint.h

    rbd05140 r6832245  
    4545#include <stdbool.h>
    4646#include <usb/usb.h>
     47#include <usb/host/bus.h>
    4748
    4849typedef struct bus bus_t;
     
    5455        /** Part of linked list. */
    5556        link_t link;
    56         /** Managing bus */
    57         bus_t *bus;
     57        /** USB device */
     58        device_t *device;
    5859        /** Reference count. */
    5960        atomic_t refcnt;
    60         /** USB device */
    61         device_t *device;
    6261        /** Enpoint number */
    6362        usb_endpoint_t endpoint;
     
    8483} endpoint_t;
    8584
    86 extern void endpoint_init(endpoint_t *, bus_t *);
     85extern void endpoint_init(endpoint_t *, device_t *, const usb_endpoint_desc_t *);
    8786
    8887extern void endpoint_add_ref(endpoint_t *);
     
    103102void endpoint_abort(endpoint_t *);
    104103
     104/* Manage the toggle bit */
    105105extern int endpoint_toggle_get(endpoint_t *);
    106106extern void endpoint_toggle_set(endpoint_t *, bool);
     107
     108/* Calculate bandwidth */
     109ssize_t endpoint_count_bw(endpoint_t *, size_t);
     110
     111static inline bus_t *endpoint_get_bus(endpoint_t *ep)
     112{
     113        return ep->device->bus;
     114}
    107115
    108116/** list_get_instance wrapper.
  • uspace/lib/usbhost/include/usb/host/usb2_bus.h

    rbd05140 r6832245  
    4646typedef struct endpoint endpoint_t;
    4747
    48 typedef size_t (*count_bw_func_t)(endpoint_t *, size_t);
    49 
    5048/** Endpoint management structure */
    5149typedef struct usb2_bus {
     
    6664} usb2_bus_t;
    6765
    68 extern int usb2_bus_init(usb2_bus_t *, size_t, count_bw_func_t);
     66extern const bus_ops_t usb2_bus_ops;
     67
     68extern int usb2_bus_init(usb2_bus_t *, hcd_t *, size_t);
    6969
    7070#endif
  • uspace/lib/usbhost/src/bandwidth.c

    rbd05140 r6832245  
    4848 * @param max_packet_size Maximum bytes in one packet.
    4949 */
    50 size_t bandwidth_count_usb11(endpoint_t *ep, size_t size)
     50ssize_t bandwidth_count_usb11(endpoint_t *ep, size_t size)
    5151{
    5252        assert(ep);
     
    102102 * @param max_packet_size Maximum bytes in one packet.
    103103 */
    104 size_t bandwidth_count_usb20(endpoint_t *ep, size_t size)
     104ssize_t bandwidth_count_usb20(endpoint_t *ep, size_t size)
    105105{
    106106        assert(ep);
  • uspace/lib/usbhost/src/bus.c

    rbd05140 r6832245  
    4646 * Initializes the bus structure.
    4747 */
    48 void bus_init(bus_t *bus, size_t device_size)
    49 {
    50         assert(bus);
     48void bus_init(bus_t *bus, hcd_t *hcd, size_t device_size)
     49{
     50        assert(bus);
     51        assert(hcd);
    5152        assert(device_size >= sizeof(device_t));
    5253        memset(bus, 0, sizeof(bus_t));
    5354
    5455        fibril_mutex_initialize(&bus->guard);
     56        bus->hcd = hcd;
    5557        bus->device_size = device_size;
    5658}
    5759
    58 int device_init(device_t *dev)
    59 {
     60int bus_device_init(device_t *dev, bus_t *bus)
     61{
     62        assert(bus);
     63        assert(bus->hcd);
     64
    6065        memset(dev, 0, sizeof(*dev));
     66
     67        dev->bus = bus;
    6168
    6269        link_initialize(&dev->link);
     
    6774}
    6875
    69 int device_set_default_name(device_t *dev)
     76int bus_device_set_default_name(device_t *dev)
    7077{
    7178        assert(dev);
     
    7986}
    8087
    81 int bus_enumerate_device(bus_t *bus, hcd_t *hcd, device_t *dev)
    82 {
    83         assert(bus);
    84         assert(hcd);
    85         assert(dev);
    86 
    87         if (!bus->ops.enumerate_device)
    88                 return ENOTSUP;
    89 
    90         return bus->ops.enumerate_device(bus, hcd, dev);
    91 }
    92 
    93 int bus_remove_device(bus_t *bus, hcd_t *hcd, device_t *dev)
    94 {
    95         assert(bus);
    96         assert(dev);
    97 
    98         if (!bus->ops.remove_device)
    99                 return ENOTSUP;
    100 
    101         return bus->ops.remove_device(bus, hcd, dev);
    102 }
    103 
    104 int bus_online_device(bus_t *bus, hcd_t *hcd, device_t *dev)
    105 {
    106         assert(bus);
    107         assert(hcd);
    108         assert(dev);
    109 
    110         if (!bus->ops.online_device)
    111                 return ENOTSUP;
    112 
    113         return bus->ops.online_device(bus, hcd, dev);
    114 }
    115 
    116 int bus_offline_device(bus_t *bus, hcd_t *hcd, device_t *dev)
    117 {
    118         assert(bus);
    119         assert(hcd);
    120         assert(dev);
    121 
    122         if (!bus->ops.offline_device)
    123                 return ENOTSUP;
    124 
    125         return bus->ops.offline_device(bus, hcd, dev);
    126 }
    127 
    128 int bus_add_endpoint(bus_t *bus, device_t *device, const usb_endpoint_desc_t *desc, endpoint_t **out_ep)
    129 {
    130         assert(bus);
     88int bus_device_enumerate(device_t *dev)
     89{
     90        assert(dev);
     91
     92        const bus_ops_t *ops = BUS_OPS_LOOKUP(dev->bus->ops, device_enumerate);
     93        if (!ops)
     94                return ENOTSUP;
     95
     96        return ops->device_enumerate(dev);
     97}
     98
     99int bus_device_remove(device_t *dev)
     100{
     101        assert(dev);
     102
     103        const bus_ops_t *ops = BUS_OPS_LOOKUP(dev->bus->ops, device_remove);
     104
     105        if (!ops)
     106                return ENOTSUP;
     107
     108        return ops->device_remove(dev);
     109}
     110
     111int bus_device_online(device_t *dev)
     112{
     113        assert(dev);
     114
     115        const bus_ops_t *ops = BUS_OPS_LOOKUP(dev->bus->ops, device_online);
     116        if (!ops)
     117                return ENOTSUP;
     118
     119        return ops->device_online(dev);
     120}
     121
     122int bus_device_offline(device_t *dev)
     123{
     124        assert(dev);
     125
     126        const bus_ops_t *ops = BUS_OPS_LOOKUP(dev->bus->ops, device_offline);
     127        if (!ops)
     128                return ENOTSUP;
     129
     130        return ops->device_offline(dev);
     131}
     132
     133int bus_endpoint_add(device_t *device, const usb_endpoint_desc_t *desc, endpoint_t **out_ep)
     134{
     135        int err;
    131136        assert(device);
     137
     138        bus_t *bus = device->bus;
    132139
    133140        if (desc->max_packet_size == 0 || desc->packets == 0) {
     
    136143        }
    137144
    138         fibril_mutex_lock(&bus->guard);
    139 
    140         int err = ENOMEM;
    141         endpoint_t *ep = bus->ops.create_endpoint(bus);
     145        const bus_ops_t *create_ops = BUS_OPS_LOOKUP(bus->ops, endpoint_create);
     146        const bus_ops_t *register_ops = BUS_OPS_LOOKUP(bus->ops, endpoint_register);
     147        if (!create_ops || !register_ops)
     148                return ENOTSUP;
     149
     150        endpoint_t *ep = create_ops->endpoint_create(device, desc);
    142151        if (!ep)
    143                 goto err;
    144 
    145         /* Bus reference */
     152                return ENOMEM;
     153
     154        /* Temporary reference */
    146155        endpoint_add_ref(ep);
    147156
    148         if ((err = bus->ops.register_endpoint(bus, device, ep, desc)))
    149                 goto err_ep;
     157        fibril_mutex_lock(&bus->guard);
     158        err = register_ops->endpoint_register(ep);
     159        fibril_mutex_unlock(&bus->guard);
    150160
    151161        if (out_ep) {
     162                /* Exporting reference */
    152163                endpoint_add_ref(ep);
    153164                *out_ep = ep;
    154165        }
    155166
    156         fibril_mutex_unlock(&bus->guard);
    157         return EOK;
    158 
    159 err_ep:
     167        /* Temporary reference */
    160168        endpoint_del_ref(ep);
    161 err:
    162         fibril_mutex_unlock(&bus->guard);
    163169        return err;
    164170}
     
    166172/** Searches for an endpoint. Returns a reference.
    167173 */
    168 endpoint_t *bus_find_endpoint(bus_t *bus, device_t *device, usb_target_t endpoint, usb_direction_t dir)
    169 {
    170         assert(bus);
    171 
    172         fibril_mutex_lock(&bus->guard);
    173         endpoint_t *ep = bus->ops.find_endpoint(bus, device, endpoint, dir);
     174endpoint_t *bus_find_endpoint(device_t *device, usb_target_t endpoint, usb_direction_t dir)
     175{
     176        assert(device);
     177
     178        bus_t *bus = device->bus;
     179
     180        const bus_ops_t *ops = BUS_OPS_LOOKUP(bus->ops, device_find_endpoint);
     181        if (!ops)
     182                return NULL;
     183
     184        fibril_mutex_lock(&bus->guard);
     185        endpoint_t *ep = ops->device_find_endpoint(device, endpoint, dir);
    174186        if (ep) {
    175187                /* Exporting reference */
     
    181193}
    182194
    183 int bus_remove_endpoint(bus_t *bus, endpoint_t *ep)
    184 {
    185         assert(bus);
     195int bus_endpoint_remove(endpoint_t *ep)
     196{
    186197        assert(ep);
    187198
    188         fibril_mutex_lock(&bus->guard);
    189         const int r = bus->ops.unregister_endpoint(bus, ep);
     199        bus_t *bus = endpoint_get_bus(ep);
     200
     201        const bus_ops_t *ops = BUS_OPS_LOOKUP(ep->device->bus->ops, endpoint_unregister);
     202        if (!ops)
     203                return ENOTSUP;
     204
     205        fibril_mutex_lock(&bus->guard);
     206        const int r = ops->endpoint_unregister(ep);
    190207        fibril_mutex_unlock(&bus->guard);
    191208
     
    203220        assert(bus);
    204221
    205         if (!bus->ops.reserve_default_address)
    206                 return ENOTSUP;
    207 
    208         fibril_mutex_lock(&bus->guard);
    209         const int r = bus->ops.reserve_default_address(bus, speed);
     222        const bus_ops_t *ops = BUS_OPS_LOOKUP(bus->ops, reserve_default_address);
     223        if (!ops)
     224                return ENOTSUP;
     225
     226        fibril_mutex_lock(&bus->guard);
     227        const int r = ops->reserve_default_address(bus, speed);
    210228        fibril_mutex_unlock(&bus->guard);
    211229        return r;
     
    216234        assert(bus);
    217235
    218         /* If this op is not set, allow everything */
    219         if (!bus->ops.release_default_address)
    220                 return ENOTSUP;
    221 
    222         fibril_mutex_lock(&bus->guard);
    223         const int r = bus->ops.release_default_address(bus);
     236        const bus_ops_t *ops = BUS_OPS_LOOKUP(bus->ops, release_default_address);
     237        if (!ops)
     238                return ENOTSUP;
     239
     240        fibril_mutex_lock(&bus->guard);
     241        const int r = ops->release_default_address(bus);
    224242        fibril_mutex_unlock(&bus->guard);
    225243        return r;
     
    230248        assert(bus);
    231249
    232         if (!bus->ops.reset_toggle)
    233                 return ENOTSUP;
    234 
    235         fibril_mutex_lock(&bus->guard);
    236         const int r = bus->ops.reset_toggle(bus, target, all);
     250        const bus_ops_t *ops = BUS_OPS_LOOKUP(bus->ops, reset_toggle);
     251        if (!ops)
     252                return ENOTSUP;
     253
     254        fibril_mutex_lock(&bus->guard);
     255        const int r = ops->reset_toggle(bus, target, all);
    237256        fibril_mutex_unlock(&bus->guard);
    238257        return r;
    239 }
    240 
    241 size_t bus_count_bw(endpoint_t *ep, size_t size)
    242 {
    243         assert(ep);
    244 
    245         fibril_mutex_lock(&ep->guard);
    246         const size_t bw = ep->bus->ops.count_bw(ep, size);
    247         fibril_mutex_unlock(&ep->guard);
    248         return bw;
    249258}
    250259
  • uspace/lib/usbhost/src/ddf_helpers.c

    rbd05140 r6832245  
    101101                endpoint_desc->max_packet_size, endpoint_desc->usb2.polling_interval);
    102102
    103         return bus_add_endpoint(hcd->bus, dev, endpoint_desc, NULL);
     103        return bus_endpoint_add(dev, endpoint_desc, NULL);
    104104}
    105105
     
    128128                usb_str_direction(endpoint_desc->direction));
    129129
    130         endpoint_t *ep = bus_find_endpoint(hcd->bus, dev, target, endpoint_desc->direction);
     130        endpoint_t *ep = bus_find_endpoint(dev, target, endpoint_desc->direction);
    131131        if (!ep)
    132132                return ENOENT;
    133133
    134         return bus_remove_endpoint(hcd->bus, ep);
     134        return bus_endpoint_remove(ep);
    135135}
    136136
     
    362362                const int ret = ddf_fun_unbind(victim->fun);
    363363                if (ret == EOK) {
    364                         bus_remove_device(hcd->bus, hcd, victim);
     364                        bus_device_remove(victim);
    365365                        ddf_fun_destroy(victim->fun);
    366366                } else {
     
    374374}
    375375
    376 device_t *hcd_ddf_device_create(ddf_dev_t *hc, size_t device_size)
     376device_t *hcd_ddf_device_create(ddf_dev_t *hc, bus_t *bus)
    377377{
    378378        /* Create DDF function for the new device */
     
    384384
    385385        /* Create USB device node for the new device */
    386         device_t *dev = ddf_fun_data_alloc(fun, device_size);
     386        device_t *dev = ddf_fun_data_alloc(fun, bus->device_size);
    387387        if (!dev) {
    388388                ddf_fun_destroy(fun);
     
    390390        }
    391391
    392         device_init(dev);
     392        bus_device_init(dev, bus);
    393393        dev->fun = fun;
    394394        return dev;
     
    402402}
    403403
    404 int hcd_ddf_device_explore(hcd_t *hcd, device_t *device)
     404int hcd_ddf_device_explore(device_t *device)
    405405{
    406406        int err;
     
    421421        usb_log_debug("Device(%d): Requesting full device descriptor.",
    422422            device->address);
    423         ssize_t got = hcd_send_batch_sync(hcd, device, control_ep, USB_DIRECTION_IN,
     423        ssize_t got = hcd_send_batch_sync(device->bus->hcd, device, control_ep, USB_DIRECTION_IN,
    424424            (char *) &desc, sizeof(desc), *(uint64_t *)&get_device_desc,
    425425            "read device descriptor");
     
    458458        usb_log_info("Device(%d): Requested to be brought online.", dev->address);
    459459
    460         return bus_online_device(hcd->bus, hcd, dev);
     460        return bus_device_online(dev);
    461461}
    462462
     
    472472        usb_log_info("Device(%d): Requested to be taken offline.", dev->address);
    473473
    474         return bus_offline_device(hcd->bus, hcd, dev);
     474        return bus_device_offline(dev);
    475475}
    476476
     
    483483        assert(hc);
    484484
    485         device_t *dev = hcd_ddf_device_create(hc, hcd->bus->device_size);
     485        device_t *dev = hcd_ddf_device_create(hc, hcd->bus);
    486486        if (!dev) {
    487487                usb_log_error("Failed to create USB device function.");
     
    492492        dev->port = port;
    493493
    494         if ((err = bus_enumerate_device(hcd->bus, hcd, dev))) {
     494        if ((err = bus_device_enumerate(dev))) {
    495495                usb_log_error("Failed to initialize USB dev memory structures.");
    496496                return err;
     
    501501         */
    502502        if (!ddf_fun_get_name(dev->fun)) {
    503                 device_set_default_name(dev);
     503                bus_device_set_default_name(dev);
    504504        }
    505505
     
    538538        }
    539539
    540         device_t *dev = hcd_ddf_device_create(hc, hcd->bus->device_size);
     540        device_t *dev = hcd_ddf_device_create(hc, hcd->bus);
    541541        if (!dev) {
    542542                usb_log_error("Failed to create function for the root hub.");
     
    547547
    548548        /* Assign an address to the device */
    549         if ((err = bus_enumerate_device(hcd->bus, hcd, dev))) {
     549        if ((err = bus_device_enumerate(dev))) {
    550550                usb_log_error("Failed to enumerate roothub device: %s", str_error(err));
    551551                goto err_usb_dev;
  • uspace/lib/usbhost/src/endpoint.c

    rbd05140 r6832245  
    4747/** Initialize provided endpoint structure.
    4848 */
    49 void endpoint_init(endpoint_t *ep, bus_t *bus)
     49void endpoint_init(endpoint_t *ep, device_t *dev, const usb_endpoint_desc_t *desc)
    5050{
    5151        memset(ep, 0, sizeof(endpoint_t));
    5252
    53         ep->bus = bus;
     53        assert(dev);
     54        ep->device = dev;
     55
    5456        atomic_set(&ep->refcnt, 0);
    5557        link_initialize(&ep->link);
    5658        fibril_mutex_initialize(&ep->guard);
    5759        fibril_condvar_initialize(&ep->avail);
     60
     61        ep->endpoint = desc->endpoint_no;
     62        ep->direction = desc->direction;
     63        ep->transfer_type = desc->transfer_type;
     64        ep->max_packet_size = desc->max_packet_size;
     65        ep->packets = desc->packets;
     66
     67        ep->bandwidth = endpoint_count_bw(ep, desc->max_packet_size);
     68}
     69
     70static inline const bus_ops_t *get_bus_ops(endpoint_t *ep)
     71{
     72        return ep->device->bus->ops;
    5873}
    5974
     
    6378}
    6479
     80static inline void endpoint_destroy(endpoint_t *ep)
     81{
     82        const bus_ops_t *ops = BUS_OPS_LOOKUP(get_bus_ops(ep), endpoint_destroy);
     83        if (ops) {
     84                ops->endpoint_destroy(ep);
     85        } else {
     86                assert(ep->active_batch == NULL);
     87
     88                /* Assume mostly the eps will be allocated by malloc. */
     89                free(ep);
     90        }
     91}
     92
    6593void endpoint_del_ref(endpoint_t *ep)
    6694{
    6795        if (atomic_predec(&ep->refcnt) == 0) {
    68                 if (ep->bus->ops.destroy_endpoint) {
    69                         ep->bus->ops.destroy_endpoint(ep);
    70                 }
    71                 else {
    72                         assert(ep->active_batch == NULL);
    73 
    74                         /* Assume mostly the eps will be allocated by malloc. */
    75                         free(ep);
    76                 }
     96                endpoint_destroy(ep);
    7797        }
    7898}
     
    133153        assert(ep);
    134154
    135         return ep->bus->ops.endpoint_get_toggle
    136             ? ep->bus->ops.endpoint_get_toggle(ep)
     155        const bus_ops_t *ops = BUS_OPS_LOOKUP(get_bus_ops(ep), endpoint_get_toggle);
     156        return ops
     157            ? ops->endpoint_get_toggle(ep)
    137158            : ep->toggle;
    138159}
     
    146167        assert(ep);
    147168
    148         if (ep->bus->ops.endpoint_set_toggle) {
    149                 ep->bus->ops.endpoint_set_toggle(ep, toggle);
     169        const bus_ops_t *ops = BUS_OPS_LOOKUP(get_bus_ops(ep), endpoint_set_toggle);
     170        if (ops) {
     171                ops->endpoint_set_toggle(ep, toggle);
    150172        }
    151173        else {
     
    154176}
    155177
     178ssize_t endpoint_count_bw(endpoint_t *ep, size_t packet_size)
     179{
     180        assert(ep);
     181
     182        const bus_ops_t *ops = BUS_OPS_LOOKUP(get_bus_ops(ep), endpoint_count_bw);
     183        if (!ops)
     184                return 0;
     185
     186        return ops->endpoint_count_bw(ep, packet_size);
     187}
     188
    156189/**
    157190 * @}
  • uspace/lib/usbhost/src/hcd.c

    rbd05140 r6832245  
    208208        }
    209209
    210         endpoint_t *ep = bus_find_endpoint(hcd->bus, device, target, direction);
     210        endpoint_t *ep = bus_find_endpoint(device, target, direction);
    211211        if (ep == NULL) {
    212212                usb_log_error("Endpoint(%d:%d) not registered for %s.\n",
     
    216216
    217217        // TODO cut here aka provide helper to call with instance of endpoint_t in hand
     218        assert(ep->device == device);
    218219
    219220        usb_log_debug2("%s %d:%d %zu(%zu).\n",
    220221            name, target.address, target.endpoint, size, ep->max_packet_size);
    221222
    222         const size_t bw = bus_count_bw(ep, size);
     223        const size_t bw = endpoint_count_bw(ep, size);
    223224        /* Check if we have enough bandwidth reserved */
    224225        if (ep->bandwidth < bw) {
  • uspace/lib/usbhost/src/usb2_bus.c

    rbd05140 r6832245  
    200200}};
    201201
    202 static int address_device(usb2_bus_t *bus, hcd_t *hcd, device_t *dev)
     202static int address_device(device_t *dev)
    203203{
    204204        int err;
     205
     206        usb2_bus_t *bus = (usb2_bus_t *) dev->bus;
     207        hcd_t *hcd = (hcd_t *) bus->base.hcd;
    205208
    206209        /* The default address is currently reserved for this device */
     
    220223
    221224        endpoint_t *default_ep;
    222         err = bus_add_endpoint(&bus->base, dev, &usb2_default_control_ep, &default_ep);
     225        err = bus_endpoint_add(dev, &usb2_default_control_ep, &default_ep);
    223226        if (err != EOK) {
    224227                usb_log_error("Device(%d): Failed to add default target: %s.",
     
    244247
    245248        /* We need to remove ep before we change the address */
    246         if ((err = bus_remove_endpoint(&bus->base, default_ep))) {
     249        if ((err = bus_endpoint_remove(default_ep))) {
    247250                usb_log_error("Device(%d): Failed to unregister default target: %s", address, str_error(err));
    248251                goto err_address;
     
    262265        /* Register EP on the new address */
    263266        usb_log_debug("Device(%d): Registering control EP.", address);
    264         err = bus_add_endpoint(&bus->base, dev, &control_ep, NULL);
     267        err = bus_endpoint_add(dev, &control_ep, NULL);
    265268        if (err != EOK) {
    266269                usb_log_error("Device(%d): Failed to register EP0: %s",
     
    272275
    273276err_default_control_ep:
    274         bus_remove_endpoint(&bus->base, default_ep);
     277        bus_endpoint_remove(default_ep);
    275278        endpoint_del_ref(default_ep);
    276279err_address:
     
    281284/** Enumerate a new USB device
    282285 */
    283 static int usb2_bus_enumerate_device(bus_t *bus_base, hcd_t *hcd, device_t *dev)
     286static int usb2_bus_device_enumerate(device_t *dev)
    284287{
    285288        int err;
    286         usb2_bus_t *bus = bus_to_usb2_bus(bus_base);
     289        usb2_bus_t *bus = bus_to_usb2_bus(dev->bus);
    287290
    288291        /* The speed of the new device was reported by the hub when reserving
     
    306309
    307310        /* Assign an address to the device */
    308         if ((err = address_device(bus, hcd, dev))) {
     311        if ((err = address_device(dev))) {
    309312                usb_log_error("Failed to setup address of the new device: %s", str_error(err));
    310313                return err;
     
    312315
    313316        /* Read the device descriptor, derive the match ids */
    314         if ((err = hcd_ddf_device_explore(hcd, dev))) {
     317        if ((err = hcd_ddf_device_explore(dev))) {
    315318                usb_log_error("Device(%d): Failed to explore device: %s", dev->address, str_error(err));
    316319                release_address(bus, dev->address);
     
    329332 * @note Assumes that the internal mutex is locked.
    330333 */
    331 static endpoint_t *usb2_bus_find_ep(bus_t *bus_base, device_t *device, usb_target_t target, usb_direction_t direction)
    332 {
    333         usb2_bus_t *bus = bus_to_usb2_bus(bus_base);
     334static endpoint_t *usb2_bus_find_ep(device_t *device, usb_target_t target, usb_direction_t direction)
     335{
     336        usb2_bus_t *bus = bus_to_usb2_bus(device->bus);
    334337
    335338        assert(device->address == target.address);
     
    345348}
    346349
    347 static endpoint_t *usb2_bus_create_ep(bus_t *bus)
     350static endpoint_t *usb2_bus_create_ep(device_t *dev, const usb_endpoint_desc_t *desc)
    348351{
    349352        endpoint_t *ep = malloc(sizeof(endpoint_t));
     
    351354                return NULL;
    352355
    353         endpoint_init(ep, bus);
     356        endpoint_init(ep, dev, desc);
    354357        return ep;
    355358}
     
    370373 * @param endpoint USB endpoint number.
    371374 */
    372 static int usb2_bus_register_ep(bus_t *bus_base, device_t *device, endpoint_t *ep, const usb_endpoint_desc_t *desc)
    373 {
    374         usb2_bus_t *bus = bus_to_usb2_bus(bus_base);
     375static int usb2_bus_register_ep(endpoint_t *ep)
     376{
     377        usb2_bus_t *bus = bus_to_usb2_bus(ep->device->bus);
     378        assert(fibril_mutex_is_locked(&bus->base.guard));
    375379        assert(ep);
    376380
    377         ep->device = device;
    378 
    379         /* Extract USB2-related information from endpoint_desc */
    380         ep->endpoint = desc->endpoint_no;
    381         ep->direction = desc->direction;
    382         ep->transfer_type = desc->transfer_type;
    383         ep->max_packet_size = desc->max_packet_size;
    384         ep->packets = desc->packets;
    385 
    386         ep->bandwidth = bus_base->ops.count_bw(ep, desc->max_packet_size);
    387 
    388381        /* Check for existence */
    389         if (usb2_bus_find_ep(bus_base, ep->device, usb2_ep_to_target(ep), ep->direction))
     382        if (usb2_bus_find_ep(ep->device, usb2_ep_to_target(ep), ep->direction))
    390383                return EEXIST;
    391384
     
    394387                return ENOSPC;
    395388
     389        endpoint_add_ref(ep);
    396390        list_append(&ep->link, get_list(bus, ep->device->address));
    397391        bus->free_bw -= ep->bandwidth;
     
    400394}
    401395
    402 
    403396/** Release bandwidth reserved by the given endpoint.
    404397 */
    405 static int usb2_bus_unregister_ep(bus_t *bus_base, endpoint_t *ep)
    406 {
    407         usb2_bus_t *bus = bus_to_usb2_bus(bus_base);
     398static int usb2_bus_unregister_ep(endpoint_t *ep)
     399{
     400        usb2_bus_t *bus = bus_to_usb2_bus(ep->device->bus);
    408401        assert(ep);
    409402
    410403        list_remove(&ep->link);
    411         ep->device = NULL;
    412404
    413405        bus->free_bw += ep->bandwidth;
     406        endpoint_del_ref(ep);
    414407
    415408        return EOK;
     
    452445}
    453446
    454 static const bus_ops_t usb2_bus_ops = {
     447const bus_ops_t usb2_bus_ops = {
    455448        .reserve_default_address = usb2_bus_register_default_address,
    456449        .release_default_address = usb2_bus_release_default_address,
    457         .enumerate_device = usb2_bus_enumerate_device,
    458         .create_endpoint = usb2_bus_create_ep,
    459         .find_endpoint = usb2_bus_find_ep,
    460         .unregister_endpoint = usb2_bus_unregister_ep,
    461         .register_endpoint = usb2_bus_register_ep,
    462450        .reset_toggle = usb2_bus_reset_toggle,
     451        .device_enumerate = usb2_bus_device_enumerate,
     452        .device_find_endpoint = usb2_bus_find_ep,
     453        .endpoint_create= usb2_bus_create_ep,
     454        .endpoint_register= usb2_bus_register_ep,
     455        .endpoint_unregister= usb2_bus_unregister_ep,
    463456};
    464457
     
    470463 * @return Error code.
    471464 */
    472 int usb2_bus_init(usb2_bus_t *bus, size_t available_bandwidth, count_bw_func_t count_bw)
     465int usb2_bus_init(usb2_bus_t *bus, hcd_t *hcd, size_t available_bandwidth)
    473466{
    474467        assert(bus);
    475468
    476         bus_init(&bus->base, sizeof(device_t));
    477 
    478         bus->base.ops = usb2_bus_ops;
    479         bus->base.ops.count_bw = count_bw;
     469        bus_init(&bus->base, hcd, sizeof(device_t));
     470        bus->base.ops = &usb2_bus_ops;
    480471
    481472        bus->free_bw = available_bandwidth;
  • uspace/lib/usbhost/src/usb_transfer_batch.c

    rbd05140 r6832245  
    4949{
    5050        assert(ep);
    51         assert(ep->bus);
    5251
    53         usb_transfer_batch_t *batch;
    54         if (ep->bus->ops.create_batch)
    55                 batch = ep->bus->ops.create_batch(ep->bus, ep);
    56         else
    57                 batch = calloc(1, sizeof(usb_transfer_batch_t));
     52        bus_t *bus = endpoint_get_bus(ep);
     53        const bus_ops_t *ops = BUS_OPS_LOOKUP(bus->ops, batch_create);
    5854
    59         return batch;
     55        if (!ops) {
     56                usb_transfer_batch_t *batch = calloc(1, sizeof(usb_transfer_batch_t));
     57                usb_transfer_batch_init(batch, ep);
     58                return batch;
     59        }
     60
     61        return ops->batch_create(ep);
    6062}
    6163
     
    6466void usb_transfer_batch_init(usb_transfer_batch_t *batch, endpoint_t *ep)
    6567{
     68        assert(ep);
     69        endpoint_add_ref(ep);
    6670        batch->ep = ep;
    6771}
     
    8286            batch->toggle_reset_mode == RESET_ALL ? "all EPs toggle" : "EP toggle");
    8387
    84         return bus_reset_toggle(batch->ep->bus, batch->target, batch->toggle_reset_mode);
     88        return bus_reset_toggle(endpoint_get_bus(batch->ep), batch->target, batch->toggle_reset_mode);
    8589}
    8690
     
    9397        assert(batch);
    9498        assert(batch->ep);
    95         assert(batch->ep->bus);
    9699
    97         bus_t *bus = batch->ep->bus;
    98         if (bus->ops.destroy_batch) {
     100        bus_t *bus = endpoint_get_bus(batch->ep);
     101        const bus_ops_t *ops = BUS_OPS_LOOKUP(bus->ops, batch_destroy);
     102
     103        endpoint_del_ref(batch->ep);
     104
     105        if (ops) {
    99106                usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT " destroying.\n",
    100107                    batch, USB_TRANSFER_BATCH_ARGS(*batch));
    101                 bus->ops.destroy_batch(batch);
     108                ops->batch_destroy(batch);
    102109        }
    103110        else {
Note: See TracChangeset for help on using the changeset viewer.