Ignore:
Timestamp:
2018-02-05T00:54:08Z (6 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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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.