Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
packets-buffer.c
Go to the documentation of this file.
1 /*
2  * helpers for managing a buffer for many packets
3  *
4  * Copyright (c) Clemens Ladisch <[email protected]>
5  * Licensed under the terms of the GNU General Public License, version 2.
6  */
7 
8 #include <linux/firewire.h>
9 #include <linux/export.h>
10 #include <linux/slab.h>
11 #include "packets-buffer.h"
12 
22  unsigned int count, unsigned int packet_size,
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(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 error;
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 }
65 
72  struct fw_unit *unit)
73 {
74  fw_iso_buffer_destroy(&b->iso_buffer, fw_parent_device(unit)->card);
75  kfree(b->packets);
76 }