Ignore:
Timestamp:
2011-04-07T20:22:40Z (13 years ago)
Author:
Lubos Slovak <lubos.slovak@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
fee6381
Parents:
61257f4 (diff), a82889e (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:

Changes from development

File:
1 edited

Legend:

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

    r61257f4 rf8e8738  
    5454        for (; i < USB_ADDRESS_COUNT; ++i) {
    5555                instance->devices[i].occupied = false;
    56                 instance->devices[i].control_used = false;
     56                instance->devices[i].control_used = 0;
    5757                instance->devices[i].handle = 0;
    58                 instance->devices[i].toggle_status[0] = 0;
    59                 instance->devices[i].toggle_status[1] = 0;
    60         }
     58                list_initialize(&instance->devices[i].endpoints);
     59        }
     60}
     61/*----------------------------------------------------------------------------*/
     62void usb_device_keeper_add_ep(
     63    usb_device_keeper_t *instance, usb_address_t address, endpoint_t *ep)
     64{
     65        assert(instance);
     66        fibril_mutex_lock(&instance->guard);
     67        assert(instance->devices[address].occupied);
     68        list_append(&ep->same_device_eps, &instance->devices[address].endpoints);
     69        fibril_mutex_unlock(&instance->guard);
    6170}
    6271/*----------------------------------------------------------------------------*/
     
    6675 * @param[in] speed Speed of the device requesting default address.
    6776 */
    68 void usb_device_keeper_reserve_default_address(usb_device_keeper_t *instance,
    69     usb_speed_t speed)
     77void usb_device_keeper_reserve_default_address(
     78    usb_device_keeper_t *instance, usb_speed_t speed)
    7079{
    7180        assert(instance);
     
    101110 * Really ugly one.
    102111 */
    103 void usb_device_keeper_reset_if_need(usb_device_keeper_t *instance,
    104     usb_target_t target, const uint8_t *data)
     112void usb_device_keeper_reset_if_need(
     113    usb_device_keeper_t *instance, usb_target_t target, const uint8_t *data)
    105114{
    106115        assert(instance);
     
    119128                /* recipient is endpoint, value is zero (ENDPOINT_STALL) */
    120129                if (((data[0] & 0xf) == 1) && ((data[2] | data[3]) == 0)) {
     130                        link_t *current =
     131                            instance->devices[target.address].endpoints.next;
     132                        while (current !=
     133                           &instance->devices[target.address].endpoints)
     134                        {
    121135                        /* endpoint number is < 16, thus first byte is enough */
    122                         instance->devices[target.address].toggle_status[0] &=
    123                             ~(1 << data[4]);
    124                         instance->devices[target.address].toggle_status[1] &=
    125                             ~(1 << data[4]);
     136                                endpoint_toggle_reset_filtered(
     137                                    current, data[4]);
     138                                current = current->next;
     139                        }
    126140                }
    127141        break;
     
    131145                /* target must be device */
    132146                if ((data[0] & 0xf) == 0) {
    133                         instance->devices[target.address].toggle_status[0] = 0;
    134                         instance->devices[target.address].toggle_status[1] = 0;
     147                        link_t *current =
     148                            instance->devices[target.address].endpoints.next;
     149                        while (current !=
     150                           &instance->devices[target.address].endpoints)
     151                        {
     152                                endpoint_toggle_reset(current);
     153                                current = current->next;
     154                        }
    135155                }
    136156        break;
    137157        }
    138158        fibril_mutex_unlock(&instance->guard);
    139 }
    140 /*----------------------------------------------------------------------------*/
    141 /** Get current value of endpoint toggle.
    142  *
    143  * @param[in] instance Device keeper structure to use.
    144  * @param[in] target Device and endpoint used.
    145  * @return Error code
    146  */
    147 int usb_device_keeper_get_toggle(usb_device_keeper_t *instance,
    148     usb_target_t target, usb_direction_t direction)
    149 {
    150         assert(instance);
    151         /* only control pipes are bi-directional and those do not need toggle */
    152         if (direction == USB_DIRECTION_BOTH)
    153                 return ENOENT;
    154         int ret;
    155         fibril_mutex_lock(&instance->guard);
    156         if (target.endpoint > 15 || target.endpoint < 0
    157             || target.address >= USB_ADDRESS_COUNT || target.address < 0
    158             || !instance->devices[target.address].occupied) {
    159                 usb_log_error("Invalid data when asking for toggle value.\n");
    160                 ret = EINVAL;
    161         } else {
    162                 ret = (instance->devices[target.address].toggle_status[direction]
    163                         >> target.endpoint) & 1;
    164         }
    165         fibril_mutex_unlock(&instance->guard);
    166         return ret;
    167 }
    168 /*----------------------------------------------------------------------------*/
    169 /** Set current value of endpoint toggle.
    170  *
    171  * @param[in] instance Device keeper structure to use.
    172  * @param[in] target Device and endpoint used.
    173  * @param[in] toggle Toggle value.
    174  * @return Error code.
    175  */
    176 int usb_device_keeper_set_toggle(usb_device_keeper_t *instance,
    177     usb_target_t target, usb_direction_t direction, bool toggle)
    178 {
    179         assert(instance);
    180         /* only control pipes are bi-directional and those do not need toggle */
    181         if (direction == USB_DIRECTION_BOTH)
    182                 return ENOENT;
    183         int ret;
    184         fibril_mutex_lock(&instance->guard);
    185         if (target.endpoint > 15 || target.endpoint < 0
    186             || target.address >= USB_ADDRESS_COUNT || target.address < 0
    187             || !instance->devices[target.address].occupied) {
    188                 usb_log_error("Invalid data when setting toggle value.\n");
    189                 ret = EINVAL;
    190         } else {
    191                 if (toggle) {
    192                         instance->devices[target.address].toggle_status[direction]
    193                             |= (1 << target.endpoint);
    194                 } else {
    195                         instance->devices[target.address].toggle_status[direction]
    196                             &= ~(1 << target.endpoint);
    197                 }
    198                 ret = EOK;
    199         }
    200         fibril_mutex_unlock(&instance->guard);
    201         return ret;
    202159}
    203160/*----------------------------------------------------------------------------*/
     
    208165 * @return Free address, or error code.
    209166 */
    210 usb_address_t device_keeper_get_free_address(usb_device_keeper_t *instance,
    211     usb_speed_t speed)
     167usb_address_t device_keeper_get_free_address(
     168    usb_device_keeper_t *instance, usb_speed_t speed)
    212169{
    213170        assert(instance);
     
    229186        instance->devices[new_address].occupied = true;
    230187        instance->devices[new_address].speed = speed;
    231         instance->devices[new_address].toggle_status[0] = 0;
    232         instance->devices[new_address].toggle_status[1] = 0;
    233188        instance->last_address = new_address;
    234189        fibril_mutex_unlock(&instance->guard);
     
    259214 * @param[in] address Device address
    260215 */
    261 void usb_device_keeper_release(usb_device_keeper_t *instance,
    262     usb_address_t address)
     216void usb_device_keeper_release(
     217    usb_device_keeper_t *instance, usb_address_t address)
    263218{
    264219        assert(instance);
     
    278233 * @return USB Address, or error code.
    279234 */
    280 usb_address_t usb_device_keeper_find(usb_device_keeper_t *instance,
    281     devman_handle_t handle)
     235usb_address_t usb_device_keeper_find(
     236    usb_device_keeper_t *instance, devman_handle_t handle)
    282237{
    283238        assert(instance);
     
    301256 * @return USB speed.
    302257 */
    303 usb_speed_t usb_device_keeper_get_speed(usb_device_keeper_t *instance,
    304     usb_address_t address)
     258usb_speed_t usb_device_keeper_get_speed(
     259    usb_device_keeper_t *instance, usb_address_t address)
    305260{
    306261        assert(instance);
     
    310265}
    311266/*----------------------------------------------------------------------------*/
    312 void usb_device_keeper_use_control(usb_device_keeper_t *instance,
    313     usb_address_t address)
    314 {
    315         assert(instance);
    316         fibril_mutex_lock(&instance->guard);
    317         while (instance->devices[address].control_used) {
     267void usb_device_keeper_use_control(
     268    usb_device_keeper_t *instance, usb_target_t target)
     269{
     270        assert(instance);
     271        const uint16_t ep = 1 << target.endpoint;
     272        fibril_mutex_lock(&instance->guard);
     273        while (instance->devices[target.address].control_used & ep) {
    318274                fibril_condvar_wait(&instance->change, &instance->guard);
    319275        }
    320         instance->devices[address].control_used = true;
    321         fibril_mutex_unlock(&instance->guard);
    322 }
    323 /*----------------------------------------------------------------------------*/
    324 void usb_device_keeper_release_control(usb_device_keeper_t *instance,
    325     usb_address_t address)
    326 {
    327         assert(instance);
    328         fibril_mutex_lock(&instance->guard);
    329         instance->devices[address].control_used = false;
     276        instance->devices[target.address].control_used |= ep;
     277        fibril_mutex_unlock(&instance->guard);
     278}
     279/*----------------------------------------------------------------------------*/
     280void usb_device_keeper_release_control(
     281    usb_device_keeper_t *instance, usb_target_t target)
     282{
     283        assert(instance);
     284        const uint16_t ep = 1 << target.endpoint;
     285        fibril_mutex_lock(&instance->guard);
     286        assert((instance->devices[target.address].control_used & ep) != 0);
     287        instance->devices[target.address].control_used &= ~ep;
    330288        fibril_mutex_unlock(&instance->guard);
    331289        fibril_condvar_signal(&instance->change);
Note: See TracChangeset for help on using the changeset viewer.