Ignore:
Timestamp:
2011-09-18T21:22:59Z (13 years ago)
Author:
Maurizio Lombardi <m.lombardi85@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
dcc44ca1
Parents:
85ff862 (diff), 45a9cf4 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes

File:
1 edited

Legend:

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

    r85ff862 rf1d6866  
    4545static hash_index_t node_hash(unsigned long key[])
    4646{
    47         hash_index_t hash = 0;
    48         unsigned i = 0;
    49         for (;i < MAX_KEYS; ++i) {
    50                 hash ^= key[i];
    51         }
    52         hash %= BUCKET_COUNT;
    53         return hash;
     47        /* USB endpoints use 4 bits, thus ((key[0] << 4) | key[1])
     48         * produces unique value for every address.endpoint pair */
     49        return ((key[0] << 4) | key[1]) % BUCKET_COUNT;
    5450}
    5551/*----------------------------------------------------------------------------*/
     
    6359        switch (keys) {
    6460        case 3:
    65                 match = match && (key[2] == node->ep->direction);
     61                match = match &&
     62                    ((key[2] == node->ep->direction)
     63                    || (node->ep->direction == USB_DIRECTION_BOTH));
    6664        case 2:
    6765                match = match && (key[1] == (unsigned long)node->ep->endpoint);
     
    140138/*----------------------------------------------------------------------------*/
    141139int usb_endpoint_manager_init(usb_endpoint_manager_t *instance,
    142     size_t available_bandwidth)
     140    size_t available_bandwidth,
     141    size_t (*bw_count)(usb_speed_t, usb_transfer_type_t, size_t, size_t))
    143142{
    144143        assert(instance);
    145144        fibril_mutex_initialize(&instance->guard);
    146         fibril_condvar_initialize(&instance->change);
    147145        instance->free_bw = available_bandwidth;
    148         bool ht =
     146        instance->bw_count = bw_count;
     147        const bool ht =
    149148            hash_table_create(&instance->ep_table, BUCKET_COUNT, MAX_KEYS, &op);
    150149        return ht ? EOK : ENOMEM;
     
    159158    endpoint_t *ep, size_t data_size)
    160159{
     160        assert(instance);
     161        assert(instance->bw_count);
    161162        assert(ep);
    162         size_t bw = bandwidth_count_usb11(ep->speed, ep->transfer_type,
     163        const size_t bw = instance->bw_count(ep->speed, ep->transfer_type,
    163164            data_size, ep->max_packet_size);
    164         assert(instance);
     165
     166        fibril_mutex_lock(&instance->guard);
     167
     168        if (bw > instance->free_bw) {
     169                fibril_mutex_unlock(&instance->guard);
     170                return ENOSPC;
     171        }
    165172
    166173        unsigned long key[MAX_KEYS] =
    167174            {ep->address, ep->endpoint, ep->direction};
    168         fibril_mutex_lock(&instance->guard);
    169 
    170         link_t *item =
     175
     176        const link_t *item =
    171177            hash_table_find(&instance->ep_table, key);
    172178        if (item != NULL) {
    173179                fibril_mutex_unlock(&instance->guard);
    174180                return EEXISTS;
    175         }
    176 
    177         if (bw > instance->free_bw) {
    178                 fibril_mutex_unlock(&instance->guard);
    179                 return ENOSPC;
    180181        }
    181182
     
    193194        instance->free_bw -= bw;
    194195        fibril_mutex_unlock(&instance->guard);
    195         fibril_condvar_broadcast(&instance->change);
    196196        return EOK;
    197197}
     
    211211
    212212        node_t *node = hash_table_get_instance(item, node_t, link);
    213         if (node->ep->active)
     213        if (node->ep->active) {
     214                fibril_mutex_unlock(&instance->guard);
    214215                return EBUSY;
     216        }
    215217
    216218        instance->free_bw += node->bw;
     
    218220
    219221        fibril_mutex_unlock(&instance->guard);
    220         fibril_condvar_broadcast(&instance->change);
    221222        return EOK;
    222223}
     
    230231
    231232        fibril_mutex_lock(&instance->guard);
    232         link_t *item = hash_table_find(&instance->ep_table, key);
     233        const link_t *item = hash_table_find(&instance->ep_table, key);
    233234        if (item == NULL) {
    234235                fibril_mutex_unlock(&instance->guard);
    235236                return NULL;
    236237        }
    237         node_t *node = hash_table_get_instance(item, node_t, link);
     238        const node_t *node = hash_table_get_instance(item, node_t, link);
    238239        if (bw)
    239240                *bw = node->bw;
     
    255256{
    256257        assert(instance);
    257         if (target.endpoint > 15 || target.endpoint < 0
    258             || target.address >= USB11_ADDRESS_MAX || target.address < 0) {
     258        if (!usb_target_is_valid(target)) {
    259259                usb_log_error("Invalid data when checking for toggle reset.\n");
    260260                return;
    261261        }
    262262
     263        assert(data);
    263264        switch (data[1])
    264265        {
    265         case 0x01: /*clear feature*/
    266                 /* recipient is endpoint, value is zero (ENDPOINT_STALL) */
     266        case 0x01: /* Clear Feature -- resets only cleared ep */
     267                /* Recipient is endpoint, value is zero (ENDPOINT_STALL) */
    267268                if (((data[0] & 0xf) == 1) && ((data[2] | data[3]) == 0)) {
    268269                        /* endpoint number is < 16, thus first byte is enough */
     
    276277        break;
    277278
    278         case 0x9: /* set configuration */
    279         case 0x11: /* set interface */
    280                 /* target must be device */
     279        case 0x9: /* Set Configuration */
     280        case 0x11: /* Set Interface */
     281                /* Recipient must be device */
    281282                if ((data[0] & 0xf) == 0) {
    282283                        usb_target_t reset_target =
Note: See TracChangeset for help on using the changeset viewer.