packets-buffer.c 2.0 KB

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