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


Ignore:
Timestamp:
2018-02-12T10:11:47Z (6 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
5fe3f954
Parents:
2f762a7
git-author:
Ondřej Hlavatý <aearsis@…> (2018-02-05 03:28:50)
git-committer:
Ondřej Hlavatý <aearsis@…> (2018-02-12 10:11:47)
Message:

usb: rethinking DMA buffers

File:
1 edited

Legend:

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

    r2f762a7 r1d758fc  
    4646#include <str_error.h>
    4747#include <usb/debug.h>
     48#include <usb/dma_buffer.h>
    4849
    4950#include "endpoint.h"
     
    389390                endpoint_init(ep, device, desc);
    390391        }
     392
     393        assert((ep->required_transfer_buffer_policy & ~ep->transfer_buffer_policy) == 0);
    391394
    392395        /* Bus reference */
     
    557560
    558561/**
    559  * Initiate a transfer on the bus. Finds the target endpoint, creates
    560  * a transfer batch and schedules it.
    561  *
    562  * @param device Device for which to send the batch
    563  * @param target The target of the transfer.
    564  * @param direction A direction of the transfer.
    565  * @param data A pointer to the data buffer.
    566  * @param size Size of the data buffer.
    567  * @param setup_data Data to use in the setup stage (Control communication type)
    568  * @param on_complete Callback which is called after the batch is complete
    569  * @param arg Callback parameter.
    570  * @param name Communication identifier (for nicer output).
     562 * Assert some conditions on transfer request. As the request is an entity of
     563 * HC driver only, we can force these conditions harder. Invalid values from
     564 * devices shall be caught on DDF interface already.
     565 */
     566static void check_request(const transfer_request_t *request)
     567{
     568        assert(usb_target_is_valid(&request->target));
     569        assert(request->dir != USB_DIRECTION_BOTH);
     570        /* Non-zero offset => size is non-zero */
     571        assert(request->offset == 0 || request->size != 0);
     572        /* Non-zero size => buffer is set */
     573        assert(request->size == 0 || dma_buffer_is_set(&request->buffer));
     574        /* Non-null arg => callback is set */
     575        assert(request->arg == NULL || request->on_complete != NULL);
     576        assert(request->name);
     577}
     578
     579/**
     580 * Initiate a transfer with given device.
     581 *
    571582 * @return Error code.
    572583 */
    573 int bus_device_send_batch(device_t *device, usb_target_t target,
    574     usb_direction_t direction, char *data, size_t size, uint64_t setup_data,
    575     usbhc_iface_transfer_callback_t on_complete, void *arg, const char *name)
    576 {
    577         assert(device->address == target.address);
     584int bus_issue_transfer(device_t *device, const transfer_request_t *request)
     585{
     586        assert(device);
     587        assert(request);
     588
     589        check_request(request);
     590        assert(device->address == request->target.address);
    578591
    579592        /* Temporary reference */
    580         endpoint_t *ep = bus_find_endpoint(device, target.endpoint, direction);
     593        endpoint_t *ep = bus_find_endpoint(device, request->target.endpoint, request->dir);
    581594        if (ep == NULL) {
    582595                usb_log_error("Endpoint(%d:%d) not registered for %s.",
    583                     device->address, target.endpoint, name);
     596                    device->address, request->target.endpoint, request->name);
    584597                return ENOENT;
    585598        }
     
    587600        assert(ep->device == device);
    588601
    589         /*
    590          * This method is already callable from HC only, so we can force these
    591          * conditions harder.
    592          * Invalid values from devices shall be caught on DDF interface already.
    593          */
    594         assert(usb_target_is_valid(&target));
    595         assert(direction != USB_DIRECTION_BOTH);
    596         assert(size == 0 || data != NULL);
    597         assert(arg == NULL || on_complete != NULL);
    598         assert(name);
    599 
    600         const int err = endpoint_send_batch(ep, target, direction,
    601             data, size, setup_data, on_complete, arg, name);
     602        const int err = endpoint_send_batch(ep, request);
    602603
    603604        /* Temporary reference */
     
    650651    const char *name, size_t *transferred_size)
    651652{
     653        int err;
    652654        sync_data_t sd = { .done = false };
    653655        fibril_mutex_initialize(&sd.done_mtx);
    654656        fibril_condvar_initialize(&sd.done_cv);
    655657
    656         const int ret = bus_device_send_batch(device, target, direction,
    657             data, size, setup_data, sync_transfer_complete, &sd, name);
    658         if (ret != EOK)
    659                 return ret;
     658        transfer_request_t request = {
     659                .target = target,
     660                .dir = direction,
     661                .offset = ((uintptr_t) data) % PAGE_SIZE,
     662                .size = size,
     663                .setup = setup_data,
     664                .on_complete = sync_transfer_complete,
     665                .arg = &sd,
     666                .name = name,
     667        };
     668
     669        if (data &&
     670            (err = dma_buffer_lock(&request.buffer, data - request.offset, size)))
     671                return err;
     672
     673        if ((err = bus_issue_transfer(device, &request))) {
     674                dma_buffer_unlock(&request.buffer, size);
     675                return err;
     676        }
    660677
    661678        /*
     
    668685        fibril_mutex_unlock(&sd.done_mtx);
    669686
     687        dma_buffer_unlock(&request.buffer, size);
     688
    670689        if (transferred_size)
    671690                *transferred_size = sd.transferred_size;
Note: See TracChangeset for help on using the changeset viewer.