0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/firewire.h>
0009 #include <linux/export.h>
0010 #include <linux/slab.h>
0011 #include "packets-buffer.h"
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 int iso_packets_buffer_init(struct iso_packets_buffer *b, struct fw_unit *unit,
0022 unsigned int count, unsigned int packet_size,
0023 enum dma_data_direction direction)
0024 {
0025 unsigned int packets_per_page, pages;
0026 unsigned int i, page_index, offset_in_page;
0027 void *p;
0028 int err;
0029
0030 b->packets = kmalloc_array(count, sizeof(*b->packets), GFP_KERNEL);
0031 if (!b->packets) {
0032 err = -ENOMEM;
0033 goto error;
0034 }
0035
0036 packet_size = L1_CACHE_ALIGN(packet_size);
0037 packets_per_page = PAGE_SIZE / packet_size;
0038 if (WARN_ON(!packets_per_page)) {
0039 err = -EINVAL;
0040 goto err_packets;
0041 }
0042 pages = DIV_ROUND_UP(count, packets_per_page);
0043
0044 err = fw_iso_buffer_init(&b->iso_buffer, fw_parent_device(unit)->card,
0045 pages, direction);
0046 if (err < 0)
0047 goto err_packets;
0048
0049 for (i = 0; i < count; ++i) {
0050 page_index = i / packets_per_page;
0051 p = page_address(b->iso_buffer.pages[page_index]);
0052 offset_in_page = (i % packets_per_page) * packet_size;
0053 b->packets[i].buffer = p + offset_in_page;
0054 b->packets[i].offset = page_index * PAGE_SIZE + offset_in_page;
0055 }
0056
0057 return 0;
0058
0059 err_packets:
0060 kfree(b->packets);
0061 error:
0062 return err;
0063 }
0064 EXPORT_SYMBOL(iso_packets_buffer_init);
0065
0066
0067
0068
0069
0070
0071 void iso_packets_buffer_destroy(struct iso_packets_buffer *b,
0072 struct fw_unit *unit)
0073 {
0074 fw_iso_buffer_destroy(&b->iso_buffer, fw_parent_device(unit)->card);
0075 kfree(b->packets);
0076 }
0077 EXPORT_SYMBOL(iso_packets_buffer_destroy);