iobuf.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License as
00006  * published by the Free Software Foundation; either version 2 of the
00007  * License, or any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00017  */
00018 
00019 FILE_LICENCE ( GPL2_OR_LATER );
00020 
00021 #include <stdint.h>
00022 #include <errno.h>
00023 #include <gpxe/malloc.h>
00024 #include <gpxe/iobuf.h>
00025 
00026 /** @file
00027  *
00028  * I/O buffers
00029  *
00030  */
00031 
00032 /**
00033  * Allocate I/O buffer
00034  *
00035  * @v len       Required length of buffer
00036  * @ret iobuf   I/O buffer, or NULL if none available
00037  *
00038  * The I/O buffer will be physically aligned to a multiple of
00039  * @c IOBUF_SIZE.
00040  */
00041 struct io_buffer * alloc_iob ( size_t len ) {
00042         struct io_buffer *iobuf = NULL;
00043         void *data;
00044 
00045         /* Pad to minimum length */
00046         if ( len < IOB_ZLEN )
00047                 len = IOB_ZLEN;
00048 
00049         /* Align buffer length */
00050         len = ( len + __alignof__( *iobuf ) - 1 ) &
00051                 ~( __alignof__( *iobuf ) - 1 );
00052         
00053         /* Allocate memory for buffer plus descriptor */
00054         data = malloc_dma ( len + sizeof ( *iobuf ), IOB_ALIGN );
00055         if ( ! data )
00056                 return NULL;
00057 
00058         iobuf = ( struct io_buffer * ) ( data + len );
00059         iobuf->head = iobuf->data = iobuf->tail = data;
00060         iobuf->end = iobuf;
00061         return iobuf;
00062 }
00063 
00064 /**
00065  * Free I/O buffer
00066  *
00067  * @v iobuf     I/O buffer
00068  */
00069 void free_iob ( struct io_buffer *iobuf ) {
00070         if ( iobuf ) {
00071                 assert ( iobuf->head <= iobuf->data );
00072                 assert ( iobuf->data <= iobuf->tail );
00073                 assert ( iobuf->tail <= iobuf->end );
00074                 free_dma ( iobuf->head,
00075                            ( iobuf->end - iobuf->head ) + sizeof ( *iobuf ) );
00076         }
00077 }
00078 
00079 /**
00080  * Ensure I/O buffer has sufficient headroom
00081  *
00082  * @v iobuf     I/O buffer
00083  * @v len       Required headroom
00084  *
00085  * This function currently only checks for the required headroom; it
00086  * does not reallocate the I/O buffer if required.  If we ever have a
00087  * code path that requires this functionality, it's a fairly trivial
00088  * change to make.
00089  */
00090 int iob_ensure_headroom ( struct io_buffer *iobuf, size_t len ) {
00091 
00092         if ( iob_headroom ( iobuf ) >= len )
00093                 return 0;
00094         return -ENOBUFS;
00095 }
00096 

Generated on Tue Apr 6 20:00:51 2010 for gPXE by  doxygen 1.5.7.1