Ignore:
File:
1 edited

Legend:

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

    rf527f58 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/**
Note: See TracChangeset for help on using the changeset viewer.