Changeset c21e6a5 in mainline for uspace/lib/usbhost/src


Ignore:
Timestamp:
2018-02-05T00:54:08Z (7 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
af16ebe
Parents:
65c059f
git-author:
Ondřej Hlavatý <aearsis@…> (2018-02-05 00:27:40)
git-committer:
Ondřej Hlavatý <aearsis@…> (2018-02-05 00:54:08)
Message:

usbhost: prepare buffers for transfers in library

Location:
uspace/lib/usbhost/src
Files:
2 edited

Legend:

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

    r65c059f rc21e6a5  
    7474
    7575        ep->max_transfer_size = ep->max_packet_size * ep->packets_per_uframe;
     76        ep->transfer_buffer_policy = DMA_POLICY_STRICT;
    7677}
    7778
     
    215216 * @param name Communication identifier (for nicer output).
    216217 */
    217 int endpoint_send_batch(endpoint_t *ep, usb_target_t target,
     218errno_t endpoint_send_batch(endpoint_t *ep, usb_target_t target,
    218219    usb_direction_t direction, char *data, size_t size, uint64_t setup_data,
    219220    usbhc_iface_transfer_callback_t on_complete, void *arg, const char *name)
     
    258259
    259260        batch->target = target;
    260         batch->buffer = data;
    261         batch->buffer_size = size;
    262261        batch->setup.packed = setup_data;
    263262        batch->dir = direction;
     263        batch->buffer_size = size;
     264
     265        errno_t err;
     266        if ((err = usb_transfer_batch_prepare_buffer(batch, data))) {
     267                usb_log_warning("Failed to prepare buffer for batch: %s", str_error(err));
     268                usb_transfer_batch_destroy(batch);
     269                return err;
     270        }
     271
    264272        batch->on_complete = on_complete;
    265273        batch->on_complete_data = arg;
  • uspace/lib/usbhost/src/usb_transfer_batch.c

    r65c059f rc21e6a5  
    104104
    105105/**
     106 * Prepare a DMA buffer according to endpoint policy.
     107 *
     108 * If the buffer is suitable to be used directly, it is. Otherwise, a bounce
     109 * buffer is created.
     110 */
     111errno_t usb_transfer_batch_prepare_buffer(
     112    usb_transfer_batch_t *batch, char *buf)
     113{
     114        const dma_policy_t policy = batch->ep->transfer_buffer_policy;
     115
     116        /* Empty transfers do not need a buffer */
     117        if (batch->buffer_size == 0)
     118                return EOK;
     119
     120        if (dma_buffer_check_policy(buf, batch->buffer_size, policy)) {
     121                /* Mark this case with invalid address */
     122                batch->original_buffer = NULL;
     123
     124                /* Fill the buffer with virtual address and lock it for DMA */
     125                return dma_buffer_lock(&batch->dma_buffer, buf, batch->buffer_size);
     126        }
     127        else {
     128                usb_log_debug("Batch(%p): Buffer cannot be used directly, "
     129                    "falling back to bounce buffer!", batch);
     130                const errno_t err = dma_buffer_alloc_policy(&batch->dma_buffer,
     131                    batch->buffer_size, policy);
     132
     133                /* Copy the data out */
     134                if (!err && batch->dir == USB_DIRECTION_OUT)
     135                        memcpy(batch->dma_buffer.virt, buf, batch->buffer_size);
     136
     137                /* Store the buffer to store the data back before finishing */
     138                batch->original_buffer = buf;
     139
     140                return err;
     141        }
     142}
     143
     144/**
    106145 * Finish a transfer batch: call handler, destroy batch, release endpoint.
    107146 *
     
    116155            batch, USB_TRANSFER_BATCH_ARGS(*batch));
    117156
     157        if (batch->error == EOK && batch->buffer_size > 0) {
     158                if (batch->original_buffer == NULL) {
     159                        /* Unlock the buffer for DMA */
     160                        dma_buffer_unlock(&batch->dma_buffer,
     161                            batch->buffer_size);
     162                }
     163                else {
     164                        /* We we're forced to use bounce buffer, copy it back */
     165                        if (batch->dir == USB_DIRECTION_IN)
     166                                memcpy(batch->original_buffer,
     167                                    batch->dma_buffer.virt,
     168                                    batch->transferred_size);
     169
     170                        dma_buffer_free(&batch->dma_buffer);
     171                }
     172        }
     173
    118174        if (batch->on_complete) {
    119175                const int err = batch->on_complete(batch->on_complete_data, batch->error, batch->transferred_size);
    120176                if (err)
    121                         usb_log_warning("batch %p failed to complete: %s",
     177                        usb_log_warning("Batch %p failed to complete: %s",
    122178                            batch, str_error(err));
    123179        }
Note: See TracChangeset for help on using the changeset viewer.