Ignore:
Timestamp:
2013-07-27T07:49:45Z (12 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
3aac088
Parents:
2838486
Message:

libusbhost: Remove usb_device_manager.

Functions merged to usb_endpoint_manager.

File:
1 edited

Legend:

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

    r2838486 r423c749  
    3636#include <assert.h>
    3737#include <errno.h>
     38#include <macros.h>
    3839
    3940#include <usb/debug.h>
     
    7172        assert(instance);
    7273        assert(addr >= 0);
    73         return &instance->endpoint_lists[addr % ENDPOINT_LIST_COUNT];
     74        return &instance->devices[addr % ARRAY_SIZE(instance->devices)].endpoint_list;
    7475}
    7576
     
    9697        }
    9798        return NULL;
     99}
     100
     101/** Get a free USB address
     102 *
     103 * @param[in] instance Device manager structure to use.
     104 * @return Free address, or error code.
     105 */
     106static usb_address_t usb_endpoint_manager_get_free_address(
     107    usb_endpoint_manager_t *instance)
     108{
     109
     110        usb_address_t new_address = instance->last_address;
     111        do {
     112                new_address = (new_address + 1) % USB_ADDRESS_COUNT;
     113                if (new_address == USB_ADDRESS_DEFAULT)
     114                        new_address = 1;
     115                if (new_address == instance->last_address)
     116                        return ENOSPC;
     117        } while (instance->devices[new_address].occupied);
     118
     119        assert(new_address != USB_ADDRESS_DEFAULT);
     120        instance->last_address = new_address;
     121
     122        return new_address;
    98123}
    99124
     
    156181 */
    157182int usb_endpoint_manager_init(usb_endpoint_manager_t *instance,
    158     size_t available_bandwidth, bw_count_func_t bw_count)
     183    size_t available_bandwidth, bw_count_func_t bw_count, usb_speed_t max_speed)
    159184{
    160185        assert(instance);
     
    162187        instance->free_bw = available_bandwidth;
    163188        instance->bw_count = bw_count;
    164         for (unsigned i = 0; i < ENDPOINT_LIST_COUNT; ++i) {
    165                 list_initialize(&instance->endpoint_lists[i]);
     189        instance->last_address = 1;
     190        instance->max_speed = max_speed;
     191        for (unsigned i = 0; i < ARRAY_SIZE(instance->devices); ++i) {
     192                list_initialize(&instance->devices[i].endpoint_list);
     193                instance->devices[i].speed = USB_SPEED_MAX;
     194                instance->devices[i].occupied = false;
    166195        }
    167196        return EOK;
     
    386415        fibril_mutex_unlock(&instance->guard);
    387416}
     417
     418/** Request USB address.
     419 * @param instance usb_device_manager
     420 * @param address Pointer to requested address value, place to store new address
     421 * @parma strict Fail if the requested address is not available.
     422 * @return Error code.
     423 * @note Default address is only available in strict mode.
     424 */
     425int usb_endpoint_manager_request_address(usb_endpoint_manager_t *instance,
     426    usb_address_t *address, bool strict, usb_speed_t speed)
     427{
     428        assert(instance);
     429        assert(address);
     430        if (speed > instance->max_speed)
     431                return ENOTSUP;
     432
     433        if (!usb_address_is_valid(*address))
     434                return EINVAL;
     435
     436        usb_address_t addr = *address;
     437
     438        fibril_mutex_lock(&instance->guard);
     439        /* Only grant default address to strict requests */
     440        if ((addr == USB_ADDRESS_DEFAULT) && !strict) {
     441                addr = usb_endpoint_manager_get_free_address(instance);
     442        }
     443
     444        if (instance->devices[addr].occupied) {
     445                if (strict) {
     446                        fibril_mutex_unlock(&instance->guard);
     447                        return ENOENT;
     448                }
     449                addr = usb_endpoint_manager_get_free_address(instance);
     450        }
     451        if (usb_address_is_valid(addr)) {
     452                assert(instance->devices[addr].occupied == false);
     453                assert(addr != USB_ADDRESS_DEFAULT || strict);
     454
     455                instance->devices[addr].occupied = true;
     456                instance->devices[addr].speed = speed;
     457                *address = addr;
     458                addr = 0;
     459        }
     460
     461        fibril_mutex_unlock(&instance->guard);
     462        return addr;
     463}
     464
     465/** Release used USB address.
     466 *
     467 * @param[in] instance Device manager structure to use.
     468 * @param[in] address Device address
     469 * @return Error code.
     470 */
     471int usb_endpoint_manager_release_address(
     472    usb_endpoint_manager_t *instance, usb_address_t address)
     473{
     474        assert(instance);
     475        if (!usb_address_is_valid(address))
     476                return EINVAL;
     477
     478        fibril_mutex_lock(&instance->guard);
     479
     480        const int rc = instance->devices[address].occupied ? EOK : ENOENT;
     481        instance->devices[address].occupied = false;
     482
     483        fibril_mutex_unlock(&instance->guard);
     484        return rc;
     485}
     486
     487/** Get speed assigned to USB address.
     488 *
     489 * @param[in] instance Device manager structure to use.
     490 * @param[in] address Address the caller wants to find.
     491 * @param[out] speed Assigned speed.
     492 * @return Error code.
     493 */
     494int usb_endpoint_manager_get_info_by_address(usb_endpoint_manager_t *instance,
     495    usb_address_t address, usb_speed_t *speed)
     496{
     497        assert(instance);
     498        if (!usb_address_is_valid(address)) {
     499                return EINVAL;
     500        }
     501
     502        fibril_mutex_lock(&instance->guard);
     503
     504        const int rc = instance->devices[address].occupied ? EOK : ENOENT;
     505        if (speed && instance->devices[address].occupied) {
     506                *speed = instance->devices[address].speed;
     507        }
     508
     509        fibril_mutex_unlock(&instance->guard);
     510        return rc;
     511}
    388512/**
    389513 * @}
Note: See TracChangeset for help on using the changeset viewer.