HelenOS sources

root/uspace/lib/usb/include/usb/dma_buffer.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. dma_policy_chunk_mask
  2. dma_buffer_phys_base
  3. dma_buffer_is_set

/*
 * Copyright (c) 2018 Ondrej Hlavaty
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 * - The name of the author may not be used to endorse or promote products
 *   derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
/** @addtogroup libusb
 * @{
 */
/** @file
 * @brief USB host controller library: DMA buffer helpers
 *
 * Simplifies handling of buffers accessible to hardware. Defines properties of
 * such buffer, which can be communicated through IPC to allow higher layers to
 * allocate a buffer that is ready to be passed to HW right away (after being
 * shared through IPC).
 *
 * Currently, it is possible to allocate either completely contiguous buffers
 * (with dma_map_anonymous) or arbitrary memory (with as_area_create). Shall the
 * kernel be updated, this is a subject of major optimization of memory usage.
 * The other way to do it without the kernel is building an userspace IO vector
 * in a similar way how QEMU does it.
 *
 * The structures themselves are defined in usbhc_iface, because they need to be
 * passed through IPC.
 */
#ifndef LIB_USB_DMA_BUFFER
#define LIB_USB_DMA_BUFFER

#include <as.h>
#include <bitops.h>
#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include <usbhc_iface.h>

/**
 * The DMA policy describes properties of the buffer. It is used in two
 * different contexts. Either it represents requirements, which shall be
 * satisfied to avoid copying the buffer to a more strict one. Or, it is the
 * actual property of the buffer, which can be more strict than requested. It
 * always holds that more bits set means more restrictive policy, and that by
 * computing a bitwise OR one gets the restriction that holds for both.
 *
 * The high bits of a DMA policy represent a physical contiguity. If bit i is
 * set, it means that chunks of a size 2^(i+1) are contiguous in memory. It
 * shall never happen that bit i > j is set when j is not.
 *
 * The previous applies for i >= PAGE_WIDTH. Lower bits are used as bit flags.
 */
#define DMA_POLICY_FLAGS_MASK           (PAGE_SIZE - 1)
#define DMA_POLICY_CHUNK_SIZE_MASK      (~DMA_POLICY_FLAGS_MASK)

#define DMA_POLICY_4GiB (1<<0)          /**< Must use only 32-bit addresses */

#define DMA_POLICY_STRICT               (-1UL)
#define DMA_POLICY_DEFAULT              DMA_POLICY_STRICT

extern dma_policy_t dma_policy_create(unsigned, size_t);

/**
 * Get mask which defines bits of offset in chunk.
 */
static inline size_t dma_policy_chunk_mask(const dma_policy_t policy)
{
        return policy | DMA_POLICY_FLAGS_MASK;
}

extern errno_t dma_buffer_alloc(dma_buffer_t *db, size_t size);
extern errno_t dma_buffer_alloc_policy(dma_buffer_t *, size_t, dma_policy_t);
extern void dma_buffer_free(dma_buffer_t *);

extern uintptr_t dma_buffer_phys(const dma_buffer_t *, const void *);

static inline uintptr_t dma_buffer_phys_base(const dma_buffer_t *db)
{
        return dma_buffer_phys(db, db->virt);
}

extern errno_t dma_buffer_lock(dma_buffer_t *, void *, size_t);
extern void dma_buffer_unlock(dma_buffer_t *, size_t);

extern void dma_buffer_acquire(dma_buffer_t *);
extern void dma_buffer_release(dma_buffer_t *);

static inline bool dma_buffer_is_set(const dma_buffer_t *db)
{
        return !!db->virt;
}

#endif
/**
 * @}
 */

/* [<][>][^][v][top][bottom][index][help] */
HelenOS homepage, sources at GitHub