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.c 2.4KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /*
  2. * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 2 of the
  7. * License, or any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18. #include <stdint.h>
  19. #include <errno.h>
  20. #include <gpxe/malloc.h>
  21. #include <gpxe/iobuf.h>
  22. /** @file
  23. *
  24. * I/O buffers
  25. *
  26. */
  27. /**
  28. * Allocate I/O buffer
  29. *
  30. * @v len Required length of buffer
  31. * @ret iobuf I/O buffer, or NULL if none available
  32. *
  33. * The I/O buffer will be physically aligned to a multiple of
  34. * @c IOBUF_SIZE.
  35. */
  36. struct io_buffer * alloc_iob ( size_t len ) {
  37. struct io_buffer *iobuf = NULL;
  38. void *data;
  39. /* Pad to minimum length */
  40. if ( len < IOB_ZLEN )
  41. len = IOB_ZLEN;
  42. /* Align buffer length */
  43. len = ( len + __alignof__( *iobuf ) - 1 ) &
  44. ~( __alignof__( *iobuf ) - 1 );
  45. /* Allocate memory for buffer plus descriptor */
  46. data = malloc_dma ( len + sizeof ( *iobuf ), IOB_ALIGN );
  47. if ( ! data )
  48. return NULL;
  49. iobuf = ( struct io_buffer * ) ( data + len );
  50. iobuf->head = iobuf->data = iobuf->tail = data;
  51. iobuf->end = iobuf;
  52. return iobuf;
  53. }
  54. /**
  55. * Free I/O buffer
  56. *
  57. * @v iobuf I/O buffer
  58. */
  59. void free_iob ( struct io_buffer *iobuf ) {
  60. if ( iobuf ) {
  61. assert ( iobuf->head <= iobuf->data );
  62. assert ( iobuf->data <= iobuf->tail );
  63. assert ( iobuf->tail <= iobuf->end );
  64. free_dma ( iobuf->head,
  65. ( iobuf->end - iobuf->head ) + sizeof ( *iobuf ) );
  66. }
  67. }
  68. /**
  69. * Ensure I/O buffer has sufficient headroom
  70. *
  71. * @v iobuf I/O buffer
  72. * @v len Required headroom
  73. *
  74. * This function currently only checks for the required headroom; it
  75. * does not reallocate the I/O buffer if required. If we ever have a
  76. * code path that requires this functionality, it's a fairly trivial
  77. * change to make.
  78. */
  79. int iob_ensure_headroom ( struct io_buffer *iobuf, size_t len ) {
  80. if ( iob_headroom ( iobuf ) >= len )
  81. return 0;
  82. return -ENOBUFS;
  83. }