Changeset 97ab321 in mainline


Ignore:
Timestamp:
2011-04-07T09:53:12Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
d41f301
Parents:
c4e0b47 (diff), 41c1f7b (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 development/ changes

Location:
uspace
Files:
7 added
17 edited
2 moved

Legend:

Unmodified
Added
Removed
  • uspace/drv/ohci/batch.c

    rc4e0b47 r97ab321  
    7373        CHECK_NULL_DISPOSE_RETURN(instance,
    7474            "Failed to allocate batch instance.\n");
    75         usb_transfer_batch_init(instance, target, transfer_type, speed, max_packet_size,
    76             buffer, NULL, buffer_size, NULL, setup_size, func_in,
    77             func_out, arg, fun, NULL);
     75        usb_transfer_batch_init(instance, target, transfer_type, speed,
     76            max_packet_size, buffer, NULL, buffer_size, NULL, setup_size,
     77            func_in, func_out, arg, fun, NULL, NULL);
    7878
    7979        if (buffer_size > 0) {
  • uspace/drv/ohci/hc.c

    rc4e0b47 r97ab321  
    9292        instance->ddf_instance = fun;
    9393        usb_device_keeper_init(&instance->manager);
    94         ret = bandwidth_init(&instance->bandwidth, BANDWIDTH_AVAILABLE_USB11,
    95             bandwidth_count_usb11);
    96         CHECK_RET_RETURN(ret, "Failed to initialize bandwidth allocator: %s.\n",
     94        ret = usb_endpoint_manager_init(&instance->ep_manager,
     95            BANDWIDTH_AVAILABLE_USB11);
     96        CHECK_RET_RETURN(ret, "Failed to initialize endpoint manager: %s.\n",
    9797            ret, str_error(ret));
    9898
     
    183183         * maintain reset for at least the time specified in USB spec (50 ms)*/
    184184        async_usleep(50000);
     185
     186        /* turn off legacy emulation */
     187        volatile uint32_t *ohci_emulation_reg =
     188            (uint32_t*)((char*)instance->registers + 0x100);
     189        usb_log_info("OHCI legacy register status %p: %x.\n",
     190                ohci_emulation_reg, *ohci_emulation_reg);
     191        *ohci_emulation_reg = 0;
     192
    185193}
    186194/*----------------------------------------------------------------------------*/
  • uspace/drv/ohci/hc.h

    rc4e0b47 r97ab321  
    4242#include <usb/usb.h>
    4343#include <usb/host/device_keeper.h>
    44 #include <usb/host/bandwidth.h>
     44#include <usb/host/usb_endpoint_manager.h>
    4545#include <usbhc_iface.h>
    4646
     
    4848#include "ohci_regs.h"
    4949#include "root_hub.h"
     50#include "hw_struct/hcca.h"
    5051
    5152typedef struct hc {
     
    5556        ddf_fun_t *ddf_instance;
    5657        usb_device_keeper_t manager;
    57         bandwidth_t bandwidth;
     58        usb_endpoint_manager_t ep_manager;
    5859        fid_t interrupt_emulator;
    5960} hc_t;
  • uspace/drv/ohci/iface.c

    rc4e0b47 r97ab321  
    162162            address, endpoint, usb_str_transfer_type(transfer_type),
    163163            usb_str_speed(speed), direction, size, max_packet_size, interval);
    164         return bandwidth_reserve(&hc->bandwidth, address, endpoint, direction,
    165             speed, transfer_type, max_packet_size, size, interval);
     164        // TODO use real endpoint here!
     165        return usb_endpoint_manager_register_ep(&hc->ep_manager,NULL, 0);
    166166}
    167167/*----------------------------------------------------------------------------*/
     
    183183        usb_log_debug("Unregister endpoint %d:%d %d.\n",
    184184            address, endpoint, direction);
    185         return bandwidth_release(&hc->bandwidth, address, endpoint, direction);
    186 
    187         return ENOTSUP;
     185        return usb_endpoint_manager_unregister_ep(&hc->ep_manager, address,
     186            endpoint, direction);
    188187}
    189188/*----------------------------------------------------------------------------*/
  • uspace/drv/uhci-hcd/batch.c

    rc4e0b47 r97ab321  
    4949        td_t *tds;
    5050        size_t transfers;
    51         usb_device_keeper_t *manager;
    5251} uhci_batch_t;
    5352
     
    7372 * @param[in] func_out function to call on outbound transaction completion
    7473 * @param[in] arg additional parameter to func_in or func_out
    75  * @param[in] manager Pointer to toggle management structure.
     74 * @param[in] ep Pointer to endpoint toggle management structure.
    7675 * @return Valid pointer if all substructures were successfully created,
    7776 * NULL otherwise.
     
    8685    char* setup_buffer, size_t setup_size,
    8786    usbhc_iface_transfer_in_callback_t func_in,
    88     usbhc_iface_transfer_out_callback_t func_out, void *arg,
    89     usb_device_keeper_t *manager
     87    usbhc_iface_transfer_out_callback_t func_out, void *arg, endpoint_t *ep
    9088    )
    9189{
     
    105103        CHECK_NULL_DISPOSE_RETURN(instance,
    106104            "Failed to allocate batch instance.\n");
    107         usb_transfer_batch_init(instance, target, transfer_type, speed, max_packet_size,
     105        usb_transfer_batch_init(instance, target,
     106            transfer_type, speed, max_packet_size,
    108107            buffer, NULL, buffer_size, NULL, setup_size, func_in,
    109             func_out, arg, fun, NULL);
     108            func_out, arg, fun, ep, NULL);
    110109
    111110
     
    114113            "Failed to allocate batch instance.\n");
    115114        bzero(data, sizeof(uhci_batch_t));
    116         data->manager = manager;
    117115        instance->private_data = data;
    118116
     
    180178                            instance, i, data->tds[i].status);
    181179                        td_print_status(&data->tds[i]);
    182 
    183                         usb_device_keeper_set_toggle(data->manager,
    184                             instance->target, instance->direction,
    185                             td_toggle(&data->tds[i]));
     180                        if (instance->ep != NULL)
     181                                endpoint_toggle_set(instance->ep,
     182                                    td_toggle(&data->tds[i]));
    186183                        if (i > 0)
    187184                                goto substract_ret;
     
    310307
    311308        const bool low_speed = instance->speed == USB_SPEED_LOW;
    312         int toggle = usb_device_keeper_get_toggle(
    313             data->manager, instance->target, instance->direction);
     309        int toggle = endpoint_toggle_get(instance->ep);
    314310        assert(toggle == 0 || toggle == 1);
    315311
     
    342338        }
    343339        td_set_ioc(&data->tds[transfer - 1]);
    344         usb_device_keeper_set_toggle(data->manager, instance->target,
    345             instance->direction, toggle);
     340        endpoint_toggle_set(instance->ep, toggle);
    346341}
    347342/*----------------------------------------------------------------------------*/
  • uspace/drv/uhci-hcd/batch.h

    rc4e0b47 r97ab321  
    3535#define DRV_UHCI_BATCH_H
    3636
    37 #include <adt/list.h>
    38 
    3937#include <usbhc_iface.h>
    4038#include <usb/usb.h>
    4139#include <usb/host/device_keeper.h>
     40#include <usb/host/endpoint.h>
    4241#include <usb/host/batch.h>
    4342
     
    5756    usbhc_iface_transfer_out_callback_t func_out,
    5857                void *arg,
    59                 usb_device_keeper_t *manager
     58                endpoint_t *ep
    6059                );
    6160
  • uspace/drv/uhci-hcd/hc.c

    rc4e0b47 r97ab321  
    6666static int hc_interrupt_emulator(void *arg);
    6767static int hc_debug_checker(void *arg);
    68 
     68#if 0
    6969static bool usb_is_allowed(
    7070    bool low_speed, usb_transfer_type_t transfer, size_t size);
     71#endif
    7172/*----------------------------------------------------------------------------*/
    7273/** Initialize UHCI hcd driver structure
     
    239240        usb_log_debug("Initialized device manager.\n");
    240241
    241         ret = bandwidth_init(&instance->bandwidth, BANDWIDTH_AVAILABLE_USB11,
    242             bandwidth_count_usb11);
     242        ret =
     243            usb_endpoint_manager_init(&instance->ep_manager,
     244                BANDWIDTH_AVAILABLE_USB11);
    243245        assert(ret == EOK);
    244246
     
    326328        assert(instance);
    327329        assert(batch);
    328         const int low_speed = (batch->speed == USB_SPEED_LOW);
    329         if (!usb_is_allowed(
    330             low_speed, batch->transfer_type, batch->max_packet_size)) {
    331                 usb_log_error("Invalid USB transfer specified %s %d %zu.\n",
    332                     usb_str_speed(batch->speed), batch->transfer_type,
    333                     batch->max_packet_size);
    334                 return ENOTSUP;
    335         }
    336         /* Check available bandwidth */
    337         if (batch->transfer_type == USB_TRANSFER_INTERRUPT ||
    338             batch->transfer_type == USB_TRANSFER_ISOCHRONOUS) {
    339                 int ret =
    340                     bandwidth_use(&instance->bandwidth, batch->target.address,
    341                     batch->target.endpoint, batch->direction);
    342                 if (ret != EOK) {
    343                         usb_log_warning("Failed(%d) to use reserved bw: %s.\n",
    344                             ret, str_error(ret));
    345                 }
    346         }
    347330
    348331        transfer_list_t *list =
     
    398381                        case USB_TRANSFER_INTERRUPT:
    399382                        case USB_TRANSFER_ISOCHRONOUS: {
     383/*
    400384                                int ret = bandwidth_free(&instance->bandwidth,
    401385                                    batch->target.address,
     
    406390                                            "reserved bw: %s.\n", ret,
    407391                                            str_error(ret));
     392*/
    408393                                }
    409394                        default:
     
    529514 * @return True if transaction is allowed by USB specs, false otherwise
    530515 */
     516#if 0
    531517bool usb_is_allowed(
    532518    bool low_speed, usb_transfer_type_t transfer, size_t size)
     
    546532        return false;
    547533}
     534#endif
    548535/**
    549536 * @}
  • uspace/drv/uhci-hcd/hc.h

    rc4e0b47 r97ab321  
    4343#include <usbhc_iface.h>
    4444#include <usb/host/device_keeper.h>
    45 #include <usb/host/bandwidth.h>
     45#include <usb/host/usb_endpoint_manager.h>
    4646
    4747#include "batch.h"
     
    8585typedef struct hc {
    8686        usb_device_keeper_t manager;
    87         bandwidth_t bandwidth;
     87        usb_endpoint_manager_t ep_manager;
    8888
    8989        regs_t *registers;
  • uspace/drv/uhci-hcd/hw_struct/queue_head.h

    rc4e0b47 r97ab321  
    3939
    4040#include "link_pointer.h"
    41 #include "utils/malloc32.h"
    4241
    4342typedef struct queue_head {
  • uspace/drv/uhci-hcd/iface.c

    rc4e0b47 r97ab321  
    3636
    3737#include <usb/debug.h>
     38#include <usb/host/endpoint.h>
    3839
    3940#include "iface.h"
     
    5455        usb_device_keeper_reserve_default_address(&hc->manager, speed);
    5556        return EOK;
     57#if 0
     58        endpoint_t *ep = malloc(sizeof(endpoint_t));
     59        if (ep == NULL)
     60                return ENOMEM;
     61        const size_t max_packet_size = speed == USB_SPEED_LOW ? 8 : 64;
     62        endpoint_init(ep, USB_TRANSFER_CONTROL, speed, max_packet_size);
     63        int ret;
     64try_retgister:
     65        ret = usb_endpoint_manager_register_ep(&hc->ep_manager,
     66            USB_ADDRESS_DEFAULT, 0, USB_DIRECTION_BOTH, ep, endpoint_destroy, 0);
     67        if (ret == EEXISTS) {
     68                async_usleep(1000);
     69                goto try_retgister;
     70        }
     71        if (ret != EOK) {
     72                endpoint_destroy(ep);
     73        }
     74        return ret;
     75#endif
    5676}
    5777/*----------------------------------------------------------------------------*/
     
    6787        assert(hc);
    6888        usb_log_debug("Default address release.\n");
     89//      return usb_endpoint_manager_unregister_ep(&hc->ep_manager,
     90//          USB_ADDRESS_DEFAULT, 0, USB_DIRECTION_BOTH);
    6991        usb_device_keeper_release_default_address(&hc->manager);
    7092        return EOK;
     
    137159        const usb_speed_t speed =
    138160            usb_device_keeper_get_speed(&hc->manager, address);
    139         size_t size = max_packet_size;
     161        const size_t size =
     162            (transfer_type == USB_TRANSFER_INTERRUPT
     163            || transfer_type == USB_TRANSFER_ISOCHRONOUS) ?
     164            max_packet_size : 0;
     165        int ret;
     166
     167        endpoint_t *ep = malloc(sizeof(endpoint_t));
     168        if (ep == NULL)
     169                return ENOMEM;
     170        ret = endpoint_init(ep, address, endpoint, direction,
     171            transfer_type, speed, max_packet_size);
     172        if (ret != EOK) {
     173                free(ep);
     174                return ret;
     175        }
    140176
    141177        usb_log_debug("Register endpoint %d:%d %s %s(%d) %zu(%zu) %u.\n",
    142178            address, endpoint, usb_str_transfer_type(transfer_type),
    143179            usb_str_speed(speed), direction, size, max_packet_size, interval);
    144         return bandwidth_reserve(&hc->bandwidth, address, endpoint, direction,
    145             speed, transfer_type, max_packet_size, size, interval);
     180
     181        ret = usb_endpoint_manager_register_ep(&hc->ep_manager, ep, size);
     182        if (ret != EOK) {
     183                endpoint_destroy(ep);
     184        } else {
     185                usb_device_keeper_add_ep(&hc->manager, address, ep);
     186        }
     187        return ret;
    146188}
    147189/*----------------------------------------------------------------------------*/
     
    154196        usb_log_debug("Unregister endpoint %d:%d %d.\n",
    155197            address, endpoint, direction);
    156         return bandwidth_release(&hc->bandwidth, address, endpoint, direction);
     198        return usb_endpoint_manager_unregister_ep(&hc->ep_manager, address,
     199            endpoint, direction);
    157200}
    158201/*----------------------------------------------------------------------------*/
     
    175218        hc_t *hc = fun_to_hc(fun);
    176219        assert(hc);
    177         usb_speed_t speed =
    178             usb_device_keeper_get_speed(&hc->manager, target.address);
    179220
    180221        usb_log_debug("Interrupt OUT %d:%d %zu(%zu).\n",
    181222            target.address, target.endpoint, size, max_packet_size);
    182223
     224        size_t res_bw;
     225        endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager,
     226            target.address, target.endpoint, USB_DIRECTION_OUT, &res_bw);
     227        if (ep == NULL) {
     228                usb_log_error("Endpoint(%d:%d) not registered for INT OUT.\n",
     229                        target.address, target.endpoint);
     230                return ENOENT;
     231        }
     232        const size_t bw = bandwidth_count_usb11(ep->speed, ep->transfer_type,
     233            size, ep->max_packet_size);
     234        if (res_bw < bw)
     235        {
     236                usb_log_error("Endpoint(%d:%d) INT IN needs %zu bw "
     237                    "but only %zu is reserved.\n",
     238                    target.address, target.endpoint, bw, res_bw);
     239                return ENOENT;
     240        }
     241        assert(ep->speed ==
     242            usb_device_keeper_get_speed(&hc->manager, target.address));
     243        assert(ep->max_packet_size == max_packet_size);
     244        assert(ep->transfer_type == USB_TRANSFER_INTERRUPT);
     245
    183246        usb_transfer_batch_t *batch =
    184             batch_get(fun, target, USB_TRANSFER_INTERRUPT, max_packet_size,
    185                 speed, data, size, NULL, 0, NULL, callback, arg, &hc->manager);
     247            batch_get(fun, target, ep->transfer_type, ep->max_packet_size,
     248                ep->speed, data, size, NULL, 0, NULL, callback, arg, ep);
    186249        if (!batch)
    187250                return ENOMEM;
     
    212275        hc_t *hc = fun_to_hc(fun);
    213276        assert(hc);
    214         usb_speed_t speed =
    215             usb_device_keeper_get_speed(&hc->manager, target.address);
     277
    216278        usb_log_debug("Interrupt IN %d:%d %zu(%zu).\n",
    217279            target.address, target.endpoint, size, max_packet_size);
    218280
     281        size_t res_bw;
     282        endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager,
     283            target.address, target.endpoint, USB_DIRECTION_IN, &res_bw);
     284        if (ep == NULL) {
     285                usb_log_error("Endpoint(%d:%d) not registered for INT IN.\n",
     286                    target.address, target.endpoint);
     287                return ENOENT;
     288        }
     289        const size_t bw = bandwidth_count_usb11(ep->speed, ep->transfer_type,
     290            size, ep->max_packet_size);
     291        if (res_bw < bw)
     292        {
     293                usb_log_error("Endpoint(%d:%d) INT IN needs %zu bw "
     294                    "but only %zu bw is reserved.\n",
     295                    target.address, target.endpoint, bw, res_bw);
     296                return ENOENT;
     297        }
     298
     299        assert(ep->speed ==
     300            usb_device_keeper_get_speed(&hc->manager, target.address));
     301        assert(ep->max_packet_size == max_packet_size);
     302        assert(ep->transfer_type == USB_TRANSFER_INTERRUPT);
     303
    219304        usb_transfer_batch_t *batch =
    220             batch_get(fun, target, USB_TRANSFER_INTERRUPT, max_packet_size,
    221                 speed, data, size, NULL, 0, callback, NULL, arg, &hc->manager);
     305            batch_get(fun, target, ep->transfer_type, ep->max_packet_size,
     306                ep->speed, data, size, NULL, 0, callback, NULL, arg, ep);
    222307        if (!batch)
    223308                return ENOMEM;
     
    248333        hc_t *hc = fun_to_hc(fun);
    249334        assert(hc);
    250         usb_speed_t speed =
    251             usb_device_keeper_get_speed(&hc->manager, target.address);
    252335
    253336        usb_log_debug("Bulk OUT %d:%d %zu(%zu).\n",
    254337            target.address, target.endpoint, size, max_packet_size);
    255338
     339        endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager,
     340            target.address, target.endpoint, USB_DIRECTION_OUT, NULL);
     341        if (ep == NULL) {
     342                usb_log_error("Endpoint(%d:%d) not registered for BULK OUT.\n",
     343                        target.address, target.endpoint);
     344                return ENOENT;
     345        }
     346        assert(ep->speed ==
     347            usb_device_keeper_get_speed(&hc->manager, target.address));
     348        assert(ep->max_packet_size == max_packet_size);
     349        assert(ep->transfer_type == USB_TRANSFER_BULK);
     350
    256351        usb_transfer_batch_t *batch =
    257             batch_get(fun, target, USB_TRANSFER_BULK, max_packet_size, speed,
    258                 data, size, NULL, 0, NULL, callback, arg, &hc->manager);
     352            batch_get(fun, target, ep->transfer_type, ep->max_packet_size,
     353                ep->speed, data, size, NULL, 0, NULL, callback, arg, ep);
    259354        if (!batch)
    260355                return ENOMEM;
     
    285380        hc_t *hc = fun_to_hc(fun);
    286381        assert(hc);
    287         usb_speed_t speed =
    288             usb_device_keeper_get_speed(&hc->manager, target.address);
    289382        usb_log_debug("Bulk IN %d:%d %zu(%zu).\n",
    290383            target.address, target.endpoint, size, max_packet_size);
    291384
     385        endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager,
     386            target.address, target.endpoint, USB_DIRECTION_IN, NULL);
     387        if (ep == NULL) {
     388                usb_log_error("Endpoint(%d:%d) not registered for BULK IN.\n",
     389                        target.address, target.endpoint);
     390                return ENOENT;
     391        }
     392        assert(ep->speed ==
     393            usb_device_keeper_get_speed(&hc->manager, target.address));
     394        assert(ep->max_packet_size == max_packet_size);
     395        assert(ep->transfer_type == USB_TRANSFER_BULK);
     396
    292397        usb_transfer_batch_t *batch =
    293             batch_get(fun, target, USB_TRANSFER_BULK, max_packet_size, speed,
    294                 data, size, NULL, 0, callback, NULL, arg, &hc->manager);
     398            batch_get(fun, target, ep->transfer_type, ep->max_packet_size,
     399                ep->speed, data, size, NULL, 0, callback, NULL, arg, ep);
    295400        if (!batch)
    296401                return ENOMEM;
     
    328433        usb_log_debug("Control WRITE (%d) %d:%d %zu(%zu).\n",
    329434            speed, target.address, target.endpoint, size, max_packet_size);
     435        endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager,
     436            target.address, target.endpoint, USB_DIRECTION_BOTH, NULL);
     437        if (ep == NULL) {
     438                usb_log_warning("Endpoint(%d:%d) not registered for CONTROL.\n",
     439                        target.address, target.endpoint);
     440        }
    330441
    331442        if (setup_size != 8)
     
    334445        usb_transfer_batch_t *batch =
    335446            batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size, speed,
    336                 data, size, setup_data, setup_size, NULL, callback, arg,
    337                 &hc->manager);
     447                data, size, setup_data, setup_size, NULL, callback, arg, ep);
    338448        if (!batch)
    339449                return ENOMEM;
     
    373483        usb_log_debug("Control READ(%d) %d:%d %zu(%zu).\n",
    374484            speed, target.address, target.endpoint, size, max_packet_size);
     485        endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager,
     486            target.address, target.endpoint, USB_DIRECTION_BOTH, NULL);
     487        if (ep == NULL) {
     488                usb_log_warning("Endpoint(%d:%d) not registered for CONTROL.\n",
     489                        target.address, target.endpoint);
     490        }
    375491        usb_transfer_batch_t *batch =
    376492            batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size, speed,
    377                 data, size, setup_data, setup_size, callback, NULL, arg,
    378                 &hc->manager);
     493                data, size, setup_data, setup_size, callback, NULL, arg, ep);
    379494        if (!batch)
    380495                return ENOMEM;
  • uspace/drv/uhci-hcd/transfer_list.h

    rc4e0b47 r97ab321  
    3939#include "batch.h"
    4040#include "hw_struct/queue_head.h"
     41#include "utils/malloc32.h"
    4142
    4243typedef struct transfer_list
  • uspace/drv/uhci-hcd/utils/malloc32.h

    rc4e0b47 r97ab321  
    3636
    3737#include <assert.h>
     38#include <errno.h>
    3839#include <malloc.h>
    3940#include <mem.h>
  • uspace/lib/usb/Makefile

    rc4e0b47 r97ab321  
    5454        src/host/device_keeper.c \
    5555        src/host/batch.c \
    56         src/host/bandwidth.c
     56        src/host/endpoint.c \
     57        src/host/usb_endpoint_manager.c
    5758
    5859include $(USPACE_PREFIX)/Makefile.common
  • uspace/lib/usb/include/usb/host/batch.h

    rc4e0b47 r97ab321  
    3939#include <usbhc_iface.h>
    4040#include <usb/usb.h>
     41#include <usb/host/endpoint.h>
    4142
    4243typedef struct usb_transfer_batch usb_transfer_batch_t;
     
    6061        ddf_fun_t *fun;
    6162        void *arg;
     63        endpoint_t *ep;
    6264        void *private_data;
    6365};
     
    7880    void *arg,
    7981    ddf_fun_t *fun,
     82                endpoint_t *ep,
    8083    void *private_data
    8184);
  • uspace/lib/usb/include/usb/host/device_keeper.h

    rc4e0b47 r97ab321  
    4040#ifndef LIBUSB_HOST_DEVICE_KEEPER_H
    4141#define LIBUSB_HOST_DEVICE_KEEPER_H
     42
     43#include <adt/list.h>
    4244#include <devman.h>
    4345#include <fibril_synch.h>
    4446#include <usb/usb.h>
     47#include <usb/host/endpoint.h>
    4548
    4649/** Number of USB address for array dimensions. */
     
    5154        usb_speed_t speed;
    5255        bool occupied;
     56        link_t endpoints;
    5357        uint16_t control_used;
    54         uint16_t toggle_status[2];
    5558        devman_handle_t handle;
    5659};
     
    6871void usb_device_keeper_init(usb_device_keeper_t *instance);
    6972
    70 void usb_device_keeper_reserve_default_address(usb_device_keeper_t *instance,
    71     usb_speed_t speed);
     73void usb_device_keeper_add_ep(
     74    usb_device_keeper_t *instance, usb_address_t address, endpoint_t *ep);
     75
     76void usb_device_keeper_reserve_default_address(
     77    usb_device_keeper_t *instance, usb_speed_t speed);
    7278
    7379void usb_device_keeper_release_default_address(usb_device_keeper_t *instance);
    7480
    7581void usb_device_keeper_reset_if_need(usb_device_keeper_t *instance,
    76     usb_target_t target,
    77     const uint8_t *setup_data);
    78 
    79 int usb_device_keeper_get_toggle(usb_device_keeper_t *instance,
    80     usb_target_t target, usb_direction_t direction);
    81 
    82 int usb_device_keeper_set_toggle(usb_device_keeper_t *instance,
    83     usb_target_t target, usb_direction_t direction, bool toggle);
     82    usb_target_t target, const uint8_t *setup_data);
    8483
    8584usb_address_t device_keeper_get_free_address(usb_device_keeper_t *instance,
  • uspace/lib/usb/include/usb/host/usb_endpoint_manager.h

    rc4e0b47 r97ab321  
    3737 * This structure shall simplify the management.
    3838 */
    39 #ifndef LIBUSB_HOST_BANDWIDTH_H
    40 #define LIBUSB_HOST_BANDWIDTH_H
     39#ifndef LIBUSB_HOST_USB_ENDPOINT_MANAGER_H
     40#define LIBUSB_HOST_YSB_ENDPOINT_MANAGER_H
    4141
    4242#include <adt/hash_table.h>
    4343#include <fibril_synch.h>
    4444#include <usb/usb.h>
     45#include <usb/host/endpoint.h>
    4546
    4647#define BANDWIDTH_TOTAL_USB11 12000000
    4748#define BANDWIDTH_AVAILABLE_USB11 ((BANDWIDTH_TOTAL_USB11 / 10) * 9)
    4849
    49 typedef struct bandwidth {
    50         hash_table_t reserved;
     50typedef struct usb_endpoint_manager {
     51        hash_table_t ep_table;
    5152        fibril_mutex_t guard;
    52         size_t free;
    53         size_t (*usage_fnc)(usb_speed_t, usb_transfer_type_t, size_t, size_t);
    54 } bandwidth_t;
     53        fibril_condvar_t change;
     54        size_t free_bw;
     55} usb_endpoint_manager_t;
    5556
    5657size_t bandwidth_count_usb11(usb_speed_t speed, usb_transfer_type_t type,
    5758    size_t size, size_t max_packet_size);
    5859
    59 int bandwidth_init(bandwidth_t *instance, size_t bandwidth,
    60     size_t (*usage_fnc)(usb_speed_t, usb_transfer_type_t, size_t, size_t));
     60int usb_endpoint_manager_init(usb_endpoint_manager_t *instance,
     61    size_t available_bandwidth);
    6162
    62 void bandwidth_destroy(bandwidth_t *instance);
     63void usb_endpoint_manager_destroy(usb_endpoint_manager_t *instance);
    6364
    64 int bandwidth_reserve(bandwidth_t *instance, usb_address_t address,
    65     usb_endpoint_t endpoint, usb_direction_t direction, usb_speed_t speed,
    66     usb_transfer_type_t transfer_type, size_t max_packet_size, size_t size,
    67     unsigned interval);
     65int usb_endpoint_manager_register_ep(usb_endpoint_manager_t *instance,
     66    endpoint_t *ep, size_t data_size);
    6867
    69 int bandwidth_release(bandwidth_t *instance, usb_address_t address,
    70     usb_endpoint_t endpoint, usb_direction_t direction);
     68int usb_endpoint_manager_register_ep_wait(usb_endpoint_manager_t *instance,
     69    usb_address_t address, usb_endpoint_t ep, usb_direction_t direction,
     70    void *data, void (*data_remove_callback)(void* data, void* arg), void *arg,
     71    size_t bw);
    7172
    72 int bandwidth_use(bandwidth_t *instance, usb_address_t address,
    73     usb_endpoint_t endpoint, usb_direction_t direction);
     73int usb_endpoint_manager_unregister_ep(usb_endpoint_manager_t *instance,
     74    usb_address_t address, usb_endpoint_t ep, usb_direction_t direction);
    7475
    75 int bandwidth_free(bandwidth_t *instance, usb_address_t address,
    76     usb_endpoint_t endpoint, usb_direction_t direction);
     76endpoint_t * usb_endpoint_manager_get_ep(usb_endpoint_manager_t *instance,
     77    usb_address_t address, usb_endpoint_t ep, usb_direction_t direction,
     78    size_t *bw);
    7779
    7880#endif
     
    8082 * @}
    8183 */
     84
  • uspace/lib/usb/src/host/batch.c

    rc4e0b47 r97ab321  
    5454    void *arg,
    5555    ddf_fun_t *fun,
     56                endpoint_t *ep,
    5657    void *private_data
    5758    )
     
    7778        instance->next_step = NULL;
    7879        instance->error = EOK;
    79 
     80        instance->ep = ep;
    8081}
    8182/*----------------------------------------------------------------------------*/
  • uspace/lib/usb/src/host/device_keeper.c

    rc4e0b47 r97ab321  
    5656                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_target_t target)
     267void usb_device_keeper_use_control(
     268    usb_device_keeper_t *instance, usb_target_t target)
    314269{
    315270        assert(instance);
     
    323278}
    324279/*----------------------------------------------------------------------------*/
    325 void usb_device_keeper_release_control(usb_device_keeper_t *instance,
    326     usb_target_t target)
     280void usb_device_keeper_release_control(
     281    usb_device_keeper_t *instance, usb_target_t target)
    327282{
    328283        assert(instance);
  • uspace/lib/usb/src/host/usb_endpoint_manager.c

    rc4e0b47 r97ab321  
    11/*
    22 * Copyright (c) 2011 Jan Vesely
    3  * All rights reserved.
     3 * All rights eps.
    44 *
    55 * Redistribution and use in source and binary forms, with or without
     
    2727 */
    2828
     29#include <bool.h>
    2930#include <assert.h>
    3031#include <errno.h>
    31 #include <usb/host/bandwidth.h>
    32 
     32
     33#include <usb/host/usb_endpoint_manager.h>
     34
     35#define BUCKET_COUNT 7
     36
     37#define MAX_KEYS (3)
    3338typedef struct {
    34         usb_address_t address;
    35         usb_endpoint_t endpoint;
    36         usb_direction_t direction;
    37 } __attribute__((aligned (sizeof(unsigned long)))) transfer_t;
    38 /*----------------------------------------------------------------------------*/
    39 typedef struct {
    40         transfer_t transfer;
    4139        link_t link;
    42         bool used;
    43         size_t required;
    44 } transfer_status_t;
    45 /*----------------------------------------------------------------------------*/
    46 #define BUCKET_COUNT 7
    47 #define MAX_KEYS (sizeof(transfer_t) / sizeof(unsigned long))
    48 /*----------------------------------------------------------------------------*/
    49 static hash_index_t transfer_hash(unsigned long key[])
     40        size_t bw;
     41        endpoint_t *ep;
     42} node_t;
     43/*----------------------------------------------------------------------------*/
     44static hash_index_t node_hash(unsigned long key[])
    5045{
    5146        hash_index_t hash = 0;
     
    5853}
    5954/*----------------------------------------------------------------------------*/
    60 static int transfer_compare(
    61     unsigned long key[], hash_count_t keys, link_t *item)
     55static int node_compare(unsigned long key[], hash_count_t keys, link_t *item)
    6256{
    6357        assert(item);
    64         transfer_status_t *status =
    65             hash_table_get_instance(item, transfer_status_t, link);
    66         const size_t bytes =
    67             keys < MAX_KEYS ? keys * sizeof(unsigned long) : sizeof(transfer_t);
    68         return bcmp(key, &status->transfer, bytes);
    69 }
    70 /*----------------------------------------------------------------------------*/
    71 static void transfer_remove(link_t *item)
     58        node_t *node = hash_table_get_instance(item, node_t, link);
     59        assert(node);
     60        assert(node->ep);
     61        bool match = true;
     62        switch (keys) {
     63        case 3:
     64                match = match && (key[2] == node->ep->direction);
     65        case 2:
     66                match = match && (key[1] == (unsigned long)node->ep->endpoint);
     67        case 1:
     68                match = match && (key[0] == (unsigned long)node->ep->address);
     69                break;
     70        default:
     71                match = false;
     72        }
     73        return match;
     74}
     75/*----------------------------------------------------------------------------*/
     76static void node_remove(link_t *item)
    7277{
    7378        assert(item);
    74         transfer_status_t *status =
    75             hash_table_get_instance(item, transfer_status_t, link);
    76         assert(status);
    77         free(status);
    78 }
    79 /*----------------------------------------------------------------------------*/
    80 hash_table_operations_t op = {
    81         .hash = transfer_hash,
    82         .compare = transfer_compare,
    83         .remove_callback = transfer_remove,
     79        node_t *node = hash_table_get_instance(item, node_t, link);
     80        endpoint_destroy(node->ep);
     81        free(node);
     82}
     83/*----------------------------------------------------------------------------*/
     84static hash_table_operations_t op = {
     85        .hash = node_hash,
     86        .compare = node_compare,
     87        .remove_callback = node_remove,
    8488};
    8589/*----------------------------------------------------------------------------*/
     
    120124}
    121125/*----------------------------------------------------------------------------*/
    122 int bandwidth_init(bandwidth_t *instance, size_t bandwidth,
    123     size_t (*usage_fnc)(usb_speed_t, usb_transfer_type_t, size_t, size_t))
     126int usb_endpoint_manager_init(usb_endpoint_manager_t *instance,
     127    size_t available_bandwidth)
    124128{
    125129        assert(instance);
    126130        fibril_mutex_initialize(&instance->guard);
    127         instance->free = bandwidth;
    128         instance->usage_fnc = usage_fnc;
     131        fibril_condvar_initialize(&instance->change);
     132        instance->free_bw = available_bandwidth;
    129133        bool ht =
    130             hash_table_create(&instance->reserved, BUCKET_COUNT, MAX_KEYS, &op);
     134            hash_table_create(&instance->ep_table, BUCKET_COUNT, MAX_KEYS, &op);
    131135        return ht ? EOK : ENOMEM;
    132136}
    133137/*----------------------------------------------------------------------------*/
    134 void bandwidth_destroy(bandwidth_t *instance)
    135 {
    136         hash_table_destroy(&instance->reserved);
    137 }
    138 /*----------------------------------------------------------------------------*/
    139 int bandwidth_reserve(bandwidth_t *instance, usb_address_t address,
    140     usb_endpoint_t endpoint, usb_direction_t direction, usb_speed_t speed,
    141     usb_transfer_type_t transfer_type, size_t max_packet_size, size_t size,
    142     unsigned interval)
    143 {
    144         if (transfer_type != USB_TRANSFER_ISOCHRONOUS &&
    145             transfer_type != USB_TRANSFER_INTERRUPT) {
    146                 return ENOTSUP;
    147         }
    148 
    149         assert(instance);
    150         assert(instance->usage_fnc);
    151 
    152         transfer_t trans = {
    153                 .address = address,
    154                 .endpoint = endpoint,
    155                 .direction = direction,
    156         };
     138void usb_endpoint_manager_destroy(usb_endpoint_manager_t *instance)
     139{
     140        hash_table_destroy(&instance->ep_table);
     141}
     142/*----------------------------------------------------------------------------*/
     143int usb_endpoint_manager_register_ep(usb_endpoint_manager_t *instance,
     144    endpoint_t *ep, size_t data_size)
     145{
     146        assert(ep);
     147        size_t bw = bandwidth_count_usb11(ep->speed, ep->transfer_type,
     148            data_size, ep->max_packet_size);
     149        assert(instance);
     150
     151        unsigned long key[MAX_KEYS] =
     152            {ep->address, ep->endpoint, ep->direction};
    157153        fibril_mutex_lock(&instance->guard);
    158         const size_t required =
    159             instance->usage_fnc(speed, transfer_type, size, max_packet_size);
    160 
    161         if (required > instance->free) {
     154
     155        link_t *item =
     156            hash_table_find(&instance->ep_table, key);
     157        if (item != NULL) {
     158                fibril_mutex_unlock(&instance->guard);
     159                return EEXISTS;
     160        }
     161
     162        if (bw > instance->free_bw) {
    162163                fibril_mutex_unlock(&instance->guard);
    163164                return ENOSPC;
    164165        }
    165166
    166         link_t *item =
    167             hash_table_find(&instance->reserved, (unsigned long*)&trans);
    168         if (item != NULL) {
    169                 fibril_mutex_unlock(&instance->guard);
    170                 return EEXISTS;
    171         }
    172 
    173         transfer_status_t *status = malloc(sizeof(transfer_status_t));
    174         if (status == NULL) {
     167        node_t *node = malloc(sizeof(node_t));
     168        if (node == NULL) {
    175169                fibril_mutex_unlock(&instance->guard);
    176170                return ENOMEM;
    177171        }
    178172
    179         status->transfer = trans;
    180         status->required = required;
    181         status->used = false;
    182         link_initialize(&status->link);
    183 
    184         hash_table_insert(&instance->reserved,
    185             (unsigned long*)&status->transfer, &status->link);
    186         instance->free -= required;
     173        node->bw = bw;
     174        node->ep = ep;
     175        link_initialize(&node->link);
     176
     177        hash_table_insert(&instance->ep_table, key, &node->link);
     178        instance->free_bw -= bw;
    187179        fibril_mutex_unlock(&instance->guard);
     180        fibril_condvar_broadcast(&instance->change);
    188181        return EOK;
    189         /* TODO: compute bandwidth used */
    190 }
    191 /*----------------------------------------------------------------------------*/
    192 int bandwidth_release(bandwidth_t *instance, usb_address_t address,
    193     usb_endpoint_t endpoint, usb_direction_t direction)
    194 {
    195         assert(instance);
    196         transfer_t trans = {
    197                 .address = address,
    198                 .endpoint = endpoint,
    199                 .direction = direction,
    200         };
     182}
     183/*----------------------------------------------------------------------------*/
     184int usb_endpoint_manager_unregister_ep(usb_endpoint_manager_t *instance,
     185    usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction)
     186{
     187        assert(instance);
     188        unsigned long key[MAX_KEYS] = {address, endpoint, direction};
     189
    201190        fibril_mutex_lock(&instance->guard);
    202         link_t *item =
    203             hash_table_find(&instance->reserved, (unsigned long*)&trans);
     191        link_t *item = hash_table_find(&instance->ep_table, key);
    204192        if (item == NULL) {
    205193                fibril_mutex_unlock(&instance->guard);
     
    207195        }
    208196
    209         transfer_status_t *status =
    210             hash_table_get_instance(item, transfer_status_t, link);
    211 
    212         instance->free += status->required;
    213 
    214         hash_table_remove(&instance->reserved,
    215             (unsigned long*)&trans, MAX_KEYS);
     197        node_t *node = hash_table_get_instance(item, node_t, link);
     198        instance->free_bw += node->bw;
     199        hash_table_remove(&instance->ep_table, key, MAX_KEYS);
    216200
    217201        fibril_mutex_unlock(&instance->guard);
     202        fibril_condvar_broadcast(&instance->change);
    218203        return EOK;
    219         /* TODO: compute bandwidth freed */
    220 }
    221 /*----------------------------------------------------------------------------*/
    222 int bandwidth_use(bandwidth_t *instance, usb_address_t address,
    223     usb_endpoint_t endpoint, usb_direction_t direction)
    224 {
    225         assert(instance);
    226         transfer_t trans = {
    227                 .address = address,
    228                 .endpoint = endpoint,
    229                 .direction = direction,
    230         };
     204}
     205/*----------------------------------------------------------------------------*/
     206endpoint_t * usb_endpoint_manager_get_ep(usb_endpoint_manager_t *instance,
     207    usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction,
     208    size_t *bw)
     209{
     210        assert(instance);
     211        unsigned long key[MAX_KEYS] = {address, endpoint, direction};
     212
    231213        fibril_mutex_lock(&instance->guard);
    232         link_t *item =
    233             hash_table_find(&instance->reserved, (unsigned long*)&trans);
    234         int ret = EOK;
    235         if (item != NULL) {
    236                 transfer_status_t *status =
    237                     hash_table_get_instance(item, transfer_status_t, link);
    238                 assert(status);
    239                 if (status->used) {
    240                         ret = EINPROGRESS;
    241                 }
    242                 status->used = true;
    243         } else {
    244                 ret = EINVAL;
    245         }
     214        link_t *item = hash_table_find(&instance->ep_table, key);
     215        if (item == NULL) {
     216                fibril_mutex_unlock(&instance->guard);
     217                return NULL;
     218        }
     219        node_t *node = hash_table_get_instance(item, node_t, link);
     220        if (bw)
     221                *bw = node->bw;
     222
    246223        fibril_mutex_unlock(&instance->guard);
    247         return ret;
    248 }
    249 /*----------------------------------------------------------------------------*/
    250 int bandwidth_free(bandwidth_t *instance, usb_address_t address,
    251     usb_endpoint_t endpoint, usb_direction_t direction)
    252 {
    253         assert(instance);
    254         transfer_t trans = {
    255                 .address = address,
    256                 .endpoint = endpoint,
    257                 .direction = direction,
    258         };
    259         fibril_mutex_lock(&instance->guard);
    260         link_t *item =
    261             hash_table_find(&instance->reserved, (unsigned long*)&trans);
    262         int ret = EOK;
    263         if (item != NULL) {
    264                 transfer_status_t *status =
    265                     hash_table_get_instance(item, transfer_status_t, link);
    266                 assert(status);
    267                 if (!status->used) {
    268                         ret = ENOENT;
    269                 }
    270                 status->used = false;
    271         } else {
    272                 ret = EINVAL;
    273         }
    274         fibril_mutex_unlock(&instance->guard);
    275         return ret;
    276 }
     224        return node->ep;
     225}
Note: See TracChangeset for help on using the changeset viewer.