Changeset a6afb4c in mainline for uspace/lib/usbhost/src/bus.c


Ignore:
Timestamp:
2018-01-23T14:02:35Z (7 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
4db49344
Parents:
e7e1fd3
git-author:
Ondřej Hlavatý <aearsis@…> (2018-01-23 13:35:50)
git-committer:
Ondřej Hlavatý <aearsis@…> (2018-01-23 14:02:35)
Message:

usbhost: check validity of arguments, cleanup

File:
1 edited

Legend:

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

    re7e1fd3 ra6afb4c  
    4242#include <errno.h>
    4343#include <mem.h>
     44#include <macros.h>
    4445#include <stdio.h>
    4546#include <str_error.h>
     
    345346 * For different arguments, the result is stable but not defined.
    346347 */
    347 static int bus_endpoint_index(usb_endpoint_t ep, usb_direction_t dir)
     348static size_t bus_endpoint_index(usb_endpoint_t ep, usb_direction_t dir)
    348349{
    349350        return 2 * ep + (dir == USB_DIRECTION_OUT);
     
    384385        endpoint_add_ref(ep);
    385386
     387        const size_t idx = bus_endpoint_index(ep->endpoint, ep->direction);
     388        if (idx >= ARRAY_SIZE(device->endpoints)) {
     389                usb_log_warning("Invalid endpoint description (ep no %u out of "
     390                    "bounds)", ep->endpoint);
     391                goto drop;
     392        }
     393
    386394        if (ep->max_transfer_size == 0) {
    387395                usb_log_warning("Invalid endpoint description (mps %zu, "
    388396                        "%u packets)", ep->max_packet_size, ep->packets_per_uframe);
    389                 /* Bus reference */
    390                 endpoint_del_ref(ep);
    391                 return EINVAL;
     397                goto drop;
    392398        }
    393399
     
    397403            usb_str_direction(ep->direction),
    398404            ep->max_transfer_size);
    399 
    400         const int idx = bus_endpoint_index(ep->endpoint, ep->direction);
    401405
    402406        fibril_mutex_lock(&device->guard);
     
    423427
    424428        return EOK;
     429drop:
     430        /* Bus reference */
     431        endpoint_del_ref(ep);
     432        return EINVAL;
    425433}
    426434
     
    428436 * Search for an endpoint. Returns a reference.
    429437 */
    430 endpoint_t *bus_find_endpoint(device_t *device, usb_endpoint_t endpoint, usb_direction_t dir)
     438endpoint_t *bus_find_endpoint(device_t *device, usb_endpoint_t endpoint,
     439    usb_direction_t dir)
    431440{
    432441        assert(device);
    433442
    434         const int idx = bus_endpoint_index(endpoint, dir);
    435         const int ctrl_idx = bus_endpoint_index(endpoint, USB_DIRECTION_BOTH);
     443        const size_t idx = bus_endpoint_index(endpoint, dir);
     444        const size_t ctrl_idx = bus_endpoint_index(endpoint, USB_DIRECTION_BOTH);
     445
     446        endpoint_t *ep = NULL;
    436447
    437448        fibril_mutex_lock(&device->guard);
    438         endpoint_t *ep = device->endpoints[idx];
     449        if (idx < ARRAY_SIZE(device->endpoints))
     450                ep = device->endpoints[idx];
    439451        /*
    440452         * If the endpoint was not found, it's still possible it is a control
    441453         * endpoint having direction BOTH.
    442454         */
    443         if (!ep) {
     455        if (!ep && ctrl_idx < ARRAY_SIZE(device->endpoints)) {
    444456                ep = device->endpoints[ctrl_idx];
    445457                if (ep && ep->transfer_type != USB_TRANSFER_CONTROL)
     
    478490            ep->max_transfer_size);
    479491
    480         const int idx = bus_endpoint_index(ep->endpoint, ep->direction);
     492        const size_t idx = bus_endpoint_index(ep->endpoint, ep->direction);
     493
     494        if (idx >= ARRAY_SIZE(device->endpoints))
     495                return EINVAL;
    481496
    482497        fibril_mutex_lock(&device->guard);
     
    495510
    496511/**
    497  * Reserve the default address on the bus. Also, report the speed of the device
    498  * that is listening on the default address.
    499  *
    500  * The speed is then used for devices enumerated while the address is reserved.
     512 * Reserve the default address on the bus for the specified device (hub).
    501513 */
    502514int bus_reserve_default_address(bus_t *bus, device_t *dev)
     
    564576        assert(ep->device == device);
    565577
    566         const int err = endpoint_send_batch(ep, target, direction, data, size, setup_data,
    567             on_complete, arg, name);
     578        /*
     579         * This method is already callable from HC only, so we can force these
     580         * conditions harder.
     581         * Invalid values from devices shall be caught on DDF interface already.
     582         */
     583        assert(usb_target_is_valid(&target));
     584        assert(usb_direction_is_valid(direction));
     585        assert(direction != USB_DIRECTION_BOTH);
     586        assert(size == 0 || data != NULL);
     587        assert(arg == NULL || on_complete != NULL);
     588        assert(name);
     589
     590        const int err = endpoint_send_batch(ep, target, direction,
     591            data, size, setup_data, on_complete, arg, name);
    568592
    569593        /* Temporary reference */
     
    573597}
    574598
     599/**
     600 * A structure to pass data from the completion callback to the caller.
     601 */
    575602typedef struct {
    576603        fibril_mutex_t done_mtx;
    577604        fibril_condvar_t done_cv;
    578         unsigned done;
     605        bool done;
    579606
    580607        size_t transferred_size;
     
    592619        d->error = error;
    593620        fibril_mutex_lock(&d->done_mtx);
    594         d->done = 1;
     621        d->done = true;
    595622        fibril_condvar_broadcast(&d->done_cv);
    596623        fibril_mutex_unlock(&d->done_mtx);
     
    599626
    600627/**
    601  * Issue a transfer on the bus, wait for result.
     628 * Issue a transfer on the bus, wait for the result.
    602629 *
    603630 * @param device Device for which to send the batch
     
    613640    const char *name)
    614641{
    615         sync_data_t sd = { .done = 0 };
     642        sync_data_t sd = { .done = false };
    616643        fibril_mutex_initialize(&sd.done_mtx);
    617644        fibril_condvar_initialize(&sd.done_cv);
    618645
    619646        const int ret = bus_device_send_batch(device, target, direction,
    620             data, size, setup_data,
    621             sync_transfer_complete, &sd, name);
     647            data, size, setup_data, sync_transfer_complete, &sd, name);
    622648        if (ret != EOK)
    623649                return ret;
    624650
     651        /*
     652         * Note: There are requests that are completed synchronously. It is not
     653         *       therefore possible to just lock the mutex before and wait.
     654         */
    625655        fibril_mutex_lock(&sd.done_mtx);
    626         while (!sd.done) {
     656        while (!sd.done)
    627657                fibril_condvar_wait(&sd.done_cv, &sd.done_mtx);
    628         }
    629658        fibril_mutex_unlock(&sd.done_mtx);
    630659
Note: See TracChangeset for help on using the changeset viewer.