Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/virtio/virtio.c

    r1e472ee r417aaafb  
    3939#include <libarch/barrier.h>
    4040
    41 /** Allocate DMA buffers
    42  *
    43  * @param buffers[in]  Number of buffers to allocate.
    44  * @param size[in]     Size of each buffer.
    45  * @param write[in]    True if the buffers are writable by the driver, false
    46  *                     otherwise.
    47  * @param buf[out]     Output array holding virtual addresses of the allocated
    48  *                     buffers.
    49  * @param buf_p[out]   Output array holding physical addresses of the allocated
    50  *                     buffers.
    51  *
    52  * The buffers can be deallocated by virtio_net_teardown_bufs().
    53  *
    54  * @return  EOK on success or error code.
    55  */
    56 errno_t virtio_setup_dma_bufs(unsigned int buffers, size_t size,
    57     bool write, void *buf[], uintptr_t buf_p[])
    58 {
    59         /*
    60          * Allocate all buffers at once in one large chunk.
    61          */
    62         void *virt = AS_AREA_ANY;
    63         uintptr_t phys;
    64         errno_t rc = dmamem_map_anonymous(buffers * size, 0,
    65             write ? AS_AREA_WRITE : AS_AREA_READ, 0, &phys, &virt);
    66         if (rc != EOK)
    67                 return rc;
    68 
    69         ddf_msg(LVL_NOTE, "DMA buffers: %p-%p", virt, virt + buffers * size);
    70 
    71         /*
    72          * Calculate addresses of the individual buffers for easy access.
    73          */
    74         for (unsigned i = 0; i < buffers; i++) {
    75                 buf[i] = virt + i * size;
    76                 buf_p[i] = phys + i * size;
    77         }
    78 
    79         return EOK;
    80 }
    81 
    82 /** Deallocate DMA buffers
    83  *
    84  * @param buf[in]  Array holding the virtual addresses of the DMA buffers
    85  *                 previously allocated by virtio_net_setup_bufs().
    86  */
    87 extern void virtio_teardown_dma_bufs(void *buf[])
    88 {
    89         if (buf[0]) {
    90                 dmamem_unmap_anonymous(buf[0]);
    91                 buf[0] = NULL;
    92         }
    93 }
    94 
    9541void virtio_virtq_desc_set(virtio_dev_t *vdev, uint16_t num, uint16_t descno,
    9642    uint64_t addr, uint32_t len, uint16_t flags, uint16_t next)
     
    11157        return pio_read_le16(&d->next);
    11258}
    113 
    114 /** Create free descriptor list from the unused VIRTIO descriptors
    115  *
    116  * @param vdev[in]   VIRTIO device for which the free list will be created.
    117  * @param num[in]    Index of the virtqueue for which the free list will be
    118  *                   created.
    119  * @param size[in]   Number of descriptors on the free list. The free list will
    120  *                   contain descriptors starting from 0 to \a size - 1.
    121  * @param head[out]  Variable that will hold the VIRTIO descriptor at the head
    122  *                   of the free list.
    123  */
    124 void virtio_create_desc_free_list(virtio_dev_t *vdev, uint16_t num,
    125     uint16_t size, uint16_t *head)
    126 {
    127         for (unsigned i = 0; i < size; i++) {
    128                 virtio_virtq_desc_set(vdev, num, i, 0, 0,
    129                     VIRTQ_DESC_F_NEXT, (i + 1 == size) ? -1U : i + 1);
    130         }
    131         *head = 0;
    132 }
    133 
    134 /** Allocate a descriptor from the free list
    135  *
    136  * @param vdev[in]      VIRTIO device with the free list.
    137  * @param num[in]       Index of the virtqueue with free list.
    138  * @param head[in,out]  Head of the free list.
    139  *
    140  * @return  Allocated descriptor or 0xFFFF if the list is empty.
    141  */
    142 uint16_t virtio_alloc_desc(virtio_dev_t *vdev, uint16_t num, uint16_t *head)
    143 {
    144         virtq_t *q = &vdev->queues[num];
    145         fibril_mutex_lock(&q->lock);
    146         uint16_t descno = *head;
    147         if (descno != (uint16_t) -1U)
    148                 *head = virtio_virtq_desc_get_next(vdev, num, descno);
    149         fibril_mutex_unlock(&q->lock);
    150         return descno;
    151 }
    152 
    153 /** Free a descriptor into the free list
    154  *
    155  * @param vdev[in]      VIRTIO device with the free list.
    156  * @param num[in]       Index of the virtqueue with free list.
    157  * @param head[in,out]  Head of the free list.
    158  * @param descno[in]    The freed descriptor.
    159  */
    160 void virtio_free_desc(virtio_dev_t *vdev, uint16_t num, uint16_t *head,
    161     uint16_t descno)
    162 {
    163         virtq_t *q = &vdev->queues[num];
    164         fibril_mutex_lock(&q->lock);
    165         virtio_virtq_desc_set(vdev, num, descno, 0, 0, VIRTQ_DESC_F_NEXT,
    166             *head);
    167         *head = descno;
    168         fibril_mutex_unlock(&q->lock);
    169 }
    170 
    17159
    17260void virtio_virtq_produce_available(virtio_dev_t *vdev, uint16_t num,
Note: See TracChangeset for help on using the changeset viewer.