Changeset ba038f4 in mainline for uspace/lib/usb/src


Ignore:
Timestamp:
2011-04-09T22:03:23Z (14 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a19a2d7
Parents:
501e5df
Message:

Don't keep endpoints in two separate structures

Fixes crash "[HelenOS-USB-devel] uhci root hub" email
Move toggle resert testing ugliness to endpoint manager

Location:
uspace/lib/usb/src/host
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usb/src/host/device_keeper.c

    r501e5df rba038f4  
    5454        for (; i < USB_ADDRESS_COUNT; ++i) {
    5555                instance->devices[i].occupied = false;
    56                 instance->devices[i].control_used = 0;
    5756                instance->devices[i].handle = 0;
    5857                instance->devices[i].speed = USB_SPEED_MAX;
    59                 list_initialize(&instance->devices[i].endpoints);
    6058        }
    6159        // TODO: is this hack enough?
    6260        // (it is needed to allow smooth registration at default address)
    6361        instance->devices[0].occupied = true;
    64 }
    65 /*----------------------------------------------------------------------------*/
    66 void usb_device_keeper_add_ep(
    67     usb_device_keeper_t *instance, usb_address_t address, endpoint_t *ep)
    68 {
    69         assert(instance);
    70         fibril_mutex_lock(&instance->guard);
    71         assert(instance->devices[address].occupied);
    72         list_append(&ep->same_device_eps, &instance->devices[address].endpoints);
    73         fibril_mutex_unlock(&instance->guard);
    74 }
    75 /*----------------------------------------------------------------------------*/
    76 void usb_device_keeper_del_ep(
    77     usb_device_keeper_t *instance, usb_address_t address, endpoint_t *ep)
    78 {
    79         assert(instance);
    80         fibril_mutex_lock(&instance->guard);
    81         assert(instance->devices[address].occupied);
    82         list_remove(&ep->same_device_eps);
    83         list_initialize(&ep->same_device_eps);
    84         fibril_mutex_unlock(&instance->guard);
    8562}
    8663/*----------------------------------------------------------------------------*/
     
    11794}
    11895/*----------------------------------------------------------------------------*/
    119 /** Check setup packet data for signs of toggle reset.
    120  *
    121  * @param[in] instance Device keeper structure to use.
    122  * @param[in] target Device to receive setup packet.
    123  * @param[in] data Setup packet data.
    124  *
    125  * Really ugly one.
    126  */
    127 void usb_device_keeper_reset_if_need(
    128     usb_device_keeper_t *instance, usb_target_t target, const uint8_t *data)
    129 {
    130         assert(instance);
    131         fibril_mutex_lock(&instance->guard);
    132         if (target.endpoint > 15 || target.endpoint < 0
    133             || target.address >= USB_ADDRESS_COUNT || target.address < 0
    134             || !instance->devices[target.address].occupied) {
    135                 fibril_mutex_unlock(&instance->guard);
    136                 usb_log_error("Invalid data when checking for toggle reset.\n");
    137                 return;
    138         }
    139 
    140         switch (data[1])
    141         {
    142         case 0x01: /*clear feature*/
    143                 /* recipient is endpoint, value is zero (ENDPOINT_STALL) */
    144                 if (((data[0] & 0xf) == 1) && ((data[2] | data[3]) == 0)) {
    145                         link_t *current =
    146                             instance->devices[target.address].endpoints.next;
    147                         while (current !=
    148                            &instance->devices[target.address].endpoints)
    149                         {
    150                         /* endpoint number is < 16, thus first byte is enough */
    151                                 endpoint_toggle_reset_filtered(
    152                                     current, data[4]);
    153                                 current = current->next;
    154                         }
    155                 }
    156         break;
    157 
    158         case 0x9: /* set configuration */
    159         case 0x11: /* set interface */
    160                 /* target must be device */
    161                 if ((data[0] & 0xf) == 0) {
    162                         link_t *current =
    163                             instance->devices[target.address].endpoints.next;
    164                         while (current !=
    165                            &instance->devices[target.address].endpoints)
    166                         {
    167                                 endpoint_toggle_reset(current);
    168                                 current = current->next;
    169                         }
    170                 }
    171         break;
    172         }
    173         fibril_mutex_unlock(&instance->guard);
    174 }
    17596/*----------------------------------------------------------------------------*/
    17697/** Get a free USB address
  • uspace/lib/usb/src/host/endpoint.c

    r501e5df rba038f4  
    5353        fibril_mutex_initialize(&instance->guard);
    5454        fibril_condvar_initialize(&instance->avail);
    55         link_initialize(&instance->same_device_eps);
    5655        return EOK;
    5756}
     
    6160        assert(instance);
    6261        assert(!instance->active);
    63         list_remove(&instance->same_device_eps);
    6462        free(instance);
    6563}
     
    9795}
    9896/*----------------------------------------------------------------------------*/
    99 void endpoint_toggle_reset(link_t *ep)
     97void endpoint_toggle_reset_filtered(endpoint_t *instance, usb_target_t target)
    10098{
    101         endpoint_t *instance =
    102             list_get_instance(ep, endpoint_t, same_device_eps);
    10399        assert(instance);
    104         instance->toggle = 0;
    105 }
    106 /*----------------------------------------------------------------------------*/
    107 void endpoint_toggle_reset_filtered(link_t *ep, usb_endpoint_t epn)
    108 {
    109         endpoint_t *instance =
    110             list_get_instance(ep, endpoint_t, same_device_eps);
    111         assert(instance);
    112         if (instance->endpoint == epn)
     100        if (instance->address == target.address &&
     101            instance->endpoint == target.endpoint)
    113102                instance->toggle = 0;
    114103}
  • uspace/lib/usb/src/host/usb_endpoint_manager.c

    r501e5df rba038f4  
    3131#include <errno.h>
    3232
     33#include <usb/debug.h>
    3334#include <usb/host/usb_endpoint_manager.h>
    3435
     
    8081        endpoint_destroy(node->ep);
    8182        free(node);
     83}
     84/*----------------------------------------------------------------------------*/
     85static void node_toggle_reset_filtered(link_t *item, void *arg)
     86{
     87        assert(item);
     88        node_t *node = hash_table_get_instance(item, node_t, link);
     89        usb_target_t *target = arg;
     90        endpoint_toggle_reset_filtered(node->ep, *target);
    8291}
    8392/*----------------------------------------------------------------------------*/
     
    230239        return node->ep;
    231240}
     241/*----------------------------------------------------------------------------*/
     242/** Check setup packet data for signs of toggle reset.
     243 *
     244 * @param[in] instance Device keeper structure to use.
     245 * @param[in] target Device to receive setup packet.
     246 * @param[in] data Setup packet data.
     247 *
     248 * Really ugly one.
     249 */
     250void usb_endpoint_manager_reset_if_need(
     251    usb_endpoint_manager_t *instance, usb_target_t target, const uint8_t *data)
     252{
     253        assert(instance);
     254        if (target.endpoint > 15 || target.endpoint < 0
     255            || target.address >= USB11_ADDRESS_MAX || target.address < 0) {
     256                usb_log_error("Invalid data when checking for toggle reset.\n");
     257                return;
     258        }
     259
     260        switch (data[1])
     261        {
     262        case 0x01: /*clear feature*/
     263                /* recipient is endpoint, value is zero (ENDPOINT_STALL) */
     264                if (((data[0] & 0xf) == 1) && ((data[2] | data[3]) == 0)) {
     265                        /* endpoint number is < 16, thus first byte is enough */
     266                        usb_target_t reset_target =
     267                            { .address = target.address, data[4] };
     268                        fibril_mutex_lock(&instance->guard);
     269                        hash_table_apply(&instance->ep_table,
     270                            node_toggle_reset_filtered, &reset_target);
     271                        fibril_mutex_unlock(&instance->guard);
     272                }
     273        break;
     274
     275        case 0x9: /* set configuration */
     276        case 0x11: /* set interface */
     277                /* target must be device */
     278                if ((data[0] & 0xf) == 0) {
     279                        usb_target_t reset_target =
     280                            { .address = target.address, 0 };
     281                        fibril_mutex_lock(&instance->guard);
     282                        hash_table_apply(&instance->ep_table,
     283                            node_toggle_reset_filtered, &reset_target);
     284                        fibril_mutex_unlock(&instance->guard);
     285                }
     286        break;
     287        }
     288}
Note: See TracChangeset for help on using the changeset viewer.