You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

iobuf.h 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. #ifndef _GPXE_IOBUF_H
  2. #define _GPXE_IOBUF_H
  3. /** @file
  4. *
  5. * I/O buffers
  6. *
  7. */
  8. #include <stdint.h>
  9. #include <assert.h>
  10. #include <gpxe/list.h>
  11. /**
  12. * I/O buffer alignment
  13. *
  14. * I/O buffers allocated via alloc_iob() are guaranteed to be
  15. * physically aligned to this boundary. Some cards cannot DMA across
  16. * a 4kB boundary. With a standard Ethernet MTU, aligning to a 2kB
  17. * boundary is sufficient to guarantee no 4kB boundary crossings. For
  18. * a jumbo Ethernet MTU, a packet may be larger than 4kB anyway.
  19. */
  20. #define IOB_ALIGN 2048
  21. /**
  22. * Minimum I/O buffer length
  23. *
  24. * alloc_iob() will round up the allocated length to this size if
  25. * necessary. This is used on behalf of hardware that is not capable
  26. * of auto-padding.
  27. */
  28. #define IOB_ZLEN 64
  29. /**
  30. * A persistent I/O buffer
  31. *
  32. * This data structure encapsulates a long-lived I/O buffer. The
  33. * buffer may be passed between multiple owners, queued for possible
  34. * retransmission, etc.
  35. */
  36. struct io_buffer {
  37. /** List of which this buffer is a member
  38. *
  39. * The list must belong to the current owner of the buffer.
  40. * Different owners may maintain different lists (e.g. a
  41. * retransmission list for TCP).
  42. */
  43. struct list_head list;
  44. /** Start of the buffer */
  45. void *head;
  46. /** Start of data */
  47. void *data;
  48. /** End of data */
  49. void *tail;
  50. /** End of the buffer */
  51. void *end;
  52. };
  53. /**
  54. * Reserve space at start of I/O buffer
  55. *
  56. * @v iobuf I/O buffer
  57. * @v len Length to reserve
  58. * @ret data Pointer to new start of buffer
  59. */
  60. static inline void * iob_reserve ( struct io_buffer *iobuf, size_t len ) {
  61. iobuf->data += len;
  62. iobuf->tail += len;
  63. assert ( iobuf->tail <= iobuf->end );
  64. return iobuf->data;
  65. }
  66. /**
  67. * Add data to start of I/O buffer
  68. *
  69. * @v iobuf I/O buffer
  70. * @v len Length to add
  71. * @ret data Pointer to new start of buffer
  72. */
  73. static inline void * iob_push ( struct io_buffer *iobuf, size_t len ) {
  74. iobuf->data -= len;
  75. assert ( iobuf->data >= iobuf->head );
  76. return iobuf->data;
  77. }
  78. /**
  79. * Remove data from start of I/O buffer
  80. *
  81. * @v iobuf I/O buffer
  82. * @v len Length to remove
  83. * @ret data Pointer to new start of buffer
  84. */
  85. static inline void * iob_pull ( struct io_buffer *iobuf, size_t len ) {
  86. iobuf->data += len;
  87. assert ( iobuf->data <= iobuf->tail );
  88. return iobuf->data;
  89. }
  90. /**
  91. * Add data to end of I/O buffer
  92. *
  93. * @v iobuf I/O buffer
  94. * @v len Length to add
  95. * @ret data Pointer to newly added space
  96. */
  97. static inline void * iob_put ( struct io_buffer *iobuf, size_t len ) {
  98. void *old_tail = iobuf->tail;
  99. iobuf->tail += len;
  100. assert ( iobuf->tail <= iobuf->end );
  101. return old_tail;
  102. }
  103. /**
  104. * Remove data from end of I/O buffer
  105. *
  106. * @v iobuf I/O buffer
  107. * @v len Length to remove
  108. */
  109. static inline void iob_unput ( struct io_buffer *iobuf, size_t len ) {
  110. iobuf->tail -= len;
  111. assert ( iobuf->tail >= iobuf->data );
  112. }
  113. /**
  114. * Empty an I/O buffer
  115. *
  116. * @v iobuf I/O buffer
  117. */
  118. static inline void iob_empty ( struct io_buffer *iobuf ) {
  119. iobuf->tail = iobuf->data;
  120. }
  121. /**
  122. * Calculate length of data in an I/O buffer
  123. *
  124. * @v iobuf I/O buffer
  125. * @ret len Length of data in buffer
  126. */
  127. static inline size_t iob_len ( struct io_buffer *iobuf ) {
  128. return ( iobuf->tail - iobuf->data );
  129. }
  130. /**
  131. * Calculate available space at start of an I/O buffer
  132. *
  133. * @v iobuf I/O buffer
  134. * @ret len Length of data available at start of buffer
  135. */
  136. static inline size_t iob_headroom ( struct io_buffer *iobuf ) {
  137. return ( iobuf->data - iobuf->head );
  138. }
  139. /**
  140. * Calculate available space at end of an I/O buffer
  141. *
  142. * @v iobuf I/O buffer
  143. * @ret len Length of data available at end of buffer
  144. */
  145. static inline size_t iob_tailroom ( struct io_buffer *iobuf ) {
  146. return ( iobuf->end - iobuf->tail );
  147. }
  148. extern struct io_buffer * alloc_iob ( size_t len );
  149. extern void free_iob ( struct io_buffer *iobuf );
  150. extern void iob_pad ( struct io_buffer *iobuf, size_t min_len );
  151. extern int iob_ensure_headroom ( struct io_buffer *iobuf, size_t len );
  152. #endif /* _GPXE_IOBUF_H */