root/sound/firewire/packets-buffer.c

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

DEFINITIONS

This source file includes following definitions.
  1. iso_packets_buffer_init
  2. iso_packets_buffer_destroy

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * helpers for managing a buffer for many packets
   4  *
   5  * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
   6  */
   7 
   8 #include <linux/firewire.h>
   9 #include <linux/export.h>
  10 #include <linux/slab.h>
  11 #include "packets-buffer.h"
  12 
  13 /**
  14  * iso_packets_buffer_init - allocates the memory for packets
  15  * @b: the buffer structure to initialize
  16  * @unit: the device at the other end of the stream
  17  * @count: the number of packets
  18  * @packet_size: the (maximum) size of a packet, in bytes
  19  * @direction: %DMA_TO_DEVICE or %DMA_FROM_DEVICE
  20  */
  21 int iso_packets_buffer_init(struct iso_packets_buffer *b, struct fw_unit *unit,
  22                             unsigned int count, unsigned int packet_size,
  23                             enum dma_data_direction direction)
  24 {
  25         unsigned int packets_per_page, pages;
  26         unsigned int i, page_index, offset_in_page;
  27         void *p;
  28         int err;
  29 
  30         b->packets = kmalloc_array(count, sizeof(*b->packets), GFP_KERNEL);
  31         if (!b->packets) {
  32                 err = -ENOMEM;
  33                 goto error;
  34         }
  35 
  36         packet_size = L1_CACHE_ALIGN(packet_size);
  37         packets_per_page = PAGE_SIZE / packet_size;
  38         if (WARN_ON(!packets_per_page)) {
  39                 err = -EINVAL;
  40                 goto err_packets;
  41         }
  42         pages = DIV_ROUND_UP(count, packets_per_page);
  43 
  44         err = fw_iso_buffer_init(&b->iso_buffer, fw_parent_device(unit)->card,
  45                                  pages, direction);
  46         if (err < 0)
  47                 goto err_packets;
  48 
  49         for (i = 0; i < count; ++i) {
  50                 page_index = i / packets_per_page;
  51                 p = page_address(b->iso_buffer.pages[page_index]);
  52                 offset_in_page = (i % packets_per_page) * packet_size;
  53                 b->packets[i].buffer = p + offset_in_page;
  54                 b->packets[i].offset = page_index * PAGE_SIZE + offset_in_page;
  55         }
  56 
  57         return 0;
  58 
  59 err_packets:
  60         kfree(b->packets);
  61 error:
  62         return err;
  63 }
  64 EXPORT_SYMBOL(iso_packets_buffer_init);
  65 
  66 /**
  67  * iso_packets_buffer_destroy - frees packet buffer resources
  68  * @b: the buffer structure to free
  69  * @unit: the device at the other end of the stream
  70  */
  71 void iso_packets_buffer_destroy(struct iso_packets_buffer *b,
  72                                 struct fw_unit *unit)
  73 {
  74         fw_iso_buffer_destroy(&b->iso_buffer, fw_parent_device(unit)->card);
  75         kfree(b->packets);
  76 }
  77 EXPORT_SYMBOL(iso_packets_buffer_destroy);

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