Changeset 4ab89e5 in mainline


Ignore:
Timestamp:
2011-04-02T14:32:48Z (13 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a1313b8c
Parents:
857edac
Message:

Compute used bandwidth during reservation

Location:
uspace/lib/usb
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usb/include/usb/host/bandwidth.h

    r857edac r4ab89e5  
    4444#include <usb/usb.h>
    4545
     46#define BANDWIDTH_TOTAL_USB11 12000000
     47#define BANDWIDTH_AVAILABLE_USB11 ((BANDWIDTH_TOTAL_USB11 / 10) * 9)
     48
    4649typedef struct bandwidth {
    4750        hash_table_t reserved;
    4851        fibril_mutex_t guard;
    4952        size_t free;
     53        size_t (*usage_fnc)(usb_speed_t, usb_transfer_type_t, size_t, size_t);
    5054} bandwidth_t;
    5155
    52 int bandwidth_init(bandwidth_t *instance);
     56size_t bandwidth_count_usb11(usb_speed_t speed, usb_transfer_type_t type,
     57    size_t size, size_t max_packet_size);
     58
     59int bandwidth_init(bandwidth_t *instance, size_t bandwidth,
     60    size_t (*usage_fnc)(usb_speed_t, usb_transfer_type_t, size_t, size_t));
    5361
    5462void bandwidth_destroy(bandwidth_t *instance);
  • uspace/lib/usb/src/host/bandwidth.c

    r857edac r4ab89e5  
    5858}
    5959/*----------------------------------------------------------------------------*/
    60 static int trans_compare(unsigned long key[], hash_count_t keys, link_t *item)
     60static int transfer_compare(
     61    unsigned long key[], hash_count_t keys, link_t *item)
    6162{
    6263        assert(item);
     
    6869}
    6970/*----------------------------------------------------------------------------*/
    70 static void dummy(link_t *item) {}
     71static void transfer_remove(link_t *item)
     72{
     73        assert(item);
     74        transfer_status_t *status =
     75            hash_table_get_instance(item, transfer_status_t, link);
     76        assert(status);
     77        free(status);
     78}
    7179/*----------------------------------------------------------------------------*/
    7280hash_table_operations_t op = {
    7381        .hash = transfer_hash,
    74         .compare = trans_compare,
    75         .remove_callback = dummy,
     82        .compare = transfer_compare,
     83        .remove_callback = transfer_remove,
    7684};
    7785/*----------------------------------------------------------------------------*/
    78 int bandwidth_init(bandwidth_t *instance)
     86size_t bandwidth_count_usb11(usb_speed_t speed, usb_transfer_type_t type,
     87    size_t size, size_t max_packet_size)
     88{
     89        const unsigned packet_count =
     90            (size + max_packet_size - 1) / max_packet_size;
     91        /* TODO: It may be that ISO and INT transfers use only one data packet
     92         * per transaction, but I did not find text in UB spec that confirms
     93         * this */
     94        /* NOTE: All data packets will be considered to be max_packet_size */
     95        switch (speed)
     96        {
     97        case USB_SPEED_LOW:
     98                assert(type == USB_TRANSFER_INTERRUPT);
     99                /* Protocol overhead 13B
     100                 * (3 SYNC bytes, 3 PID bytes, 2 Endpoint + CRC bytes, 2
     101                 * CRC bytes, and a 3-byte interpacket delay)
     102                 * see USB spec page 45-46. */
     103                /* Speed penalty 8: low speed is 8-times slower*/
     104                return packet_count * (13 + max_packet_size) * 8;
     105        case USB_SPEED_FULL:
     106                /* Interrupt transfer overhead see above
     107                 * or page 45 of USB spec */
     108                if (type == USB_TRANSFER_INTERRUPT)
     109                        return packet_count * (13 + max_packet_size);
     110
     111                assert(type == USB_TRANSFER_ISOCHRONOUS);
     112                /* Protocol overhead 9B
     113                 * (2 SYNC bytes, 2 PID bytes, 2 Endpoint + CRC bytes, 2 CRC
     114                 * bytes, and a 1-byte interpacket delay)
     115                 * see USB spec page 42 */
     116                return packet_count * (9 + max_packet_size);
     117        default:
     118                return 0;
     119        }
     120}
     121/*----------------------------------------------------------------------------*/
     122int bandwidth_init(bandwidth_t *instance, size_t bandwidth,
     123    size_t (*usage_fnc)(usb_speed_t, usb_transfer_type_t, size_t, size_t))
    79124{
    80125        assert(instance);
    81126        fibril_mutex_initialize(&instance->guard);
     127        instance->free = bandwidth;
     128        instance->usage_fnc = usage_fnc;
    82129        return
    83130            hash_table_create(&instance->reserved, BUCKET_COUNT, MAX_KEYS, &op);
     
    94141    unsigned interval)
    95142{
    96         assert(instance);
    97         transfer_t trans = {
    98                 .address = address,
    99                 .endpoint = endpoint,
    100                 .direction = direction,
    101         };
    102         fibril_mutex_lock(&instance->guard);
     143        if (transfer_type != USB_TRANSFER_ISOCHRONOUS &&
     144            transfer_type != USB_TRANSFER_INTERRUPT) {
     145                return ENOTSUP;
     146        }
     147
     148        assert(instance);
     149        assert(instance->usage_fnc);
     150
     151        transfer_t trans = {
     152                .address = address,
     153                .endpoint = endpoint,
     154                .direction = direction,
     155        };
     156        fibril_mutex_lock(&instance->guard);
     157        const size_t required =
     158            instance->usage_fnc(speed, transfer_type, size, max_packet_size);
     159
     160        if (required > instance->free) {
     161                fibril_mutex_unlock(&instance->guard);
     162                return ENOSPC;
     163        }
     164
    103165        link_t *item =
    104166            hash_table_find(&instance->reserved, (unsigned long*)&trans);
     
    115177
    116178        status->transfer = trans;
    117         status->required = 0;
     179        status->required = required;
    118180        status->used = false;
    119181        link_initialize(&status->link);
     
    121183        hash_table_insert(&instance->reserved,
    122184            (unsigned long*)&status->transfer, &status->link);
     185        instance->free -= required;
    123186        fibril_mutex_unlock(&instance->guard);
    124187        return EOK;
     
    142205                return EINVAL;
    143206        }
     207
     208        transfer_status_t *status =
     209            hash_table_get_instance(item, transfer_status_t, link);
     210
     211        instance->free += status->required;
    144212
    145213        hash_table_remove(&instance->reserved,
Note: See TracChangeset for help on using the changeset viewer.