Skip to content
Snippets Groups Projects
  • Stephen Warren's avatar
    84d35b28
    common: rework bouncebuf implementation · 84d35b28
    Stephen Warren authored
    
    The current bouncebuf API requires all parameters to be passed to both
    bounce_buffer_start() and bounce_buffer_stop(). Modify the bouncebuf
    start function to accept a state structure as a parameter, and only
    require that state struct to be passed to the stop function. This
    simplifies usage of the bounce buffer by clients.
    
    Don't modify the data pointer, but rather store the temporary buffer in
    this state struct. The bouncebuf code ensures that client code can
    always use a single buffer pointer in the state structure, irrespective
    of whether a bounce buffer actually had to be allocated.
    
    Move cache management logic into the bounce buffer code, so that each
    client doesn't have to duplicate this. I believe there's no need to
    invalidate the buffer before a DMA operation, since flushing the cache
    should prevent any write-backs.
    
    Update the MXS MMC driver for this change.
    
    Signed-off-by: default avatarStephen Warren <swarren@nvidia.com>
    Acked-by: default avatarSimon Glass <sjg@chromium.org>
    Tested-by: default avatarSimon Glass <sjg@chromium.org>
    Signed-off-by: default avatarAndy Fleming <afleming@freescale.com>
    84d35b28
    History
    common: rework bouncebuf implementation
    Stephen Warren authored
    
    The current bouncebuf API requires all parameters to be passed to both
    bounce_buffer_start() and bounce_buffer_stop(). Modify the bouncebuf
    start function to accept a state structure as a parameter, and only
    require that state struct to be passed to the stop function. This
    simplifies usage of the bounce buffer by clients.
    
    Don't modify the data pointer, but rather store the temporary buffer in
    this state struct. The bouncebuf code ensures that client code can
    always use a single buffer pointer in the state structure, irrespective
    of whether a bounce buffer actually had to be allocated.
    
    Move cache management logic into the bounce buffer code, so that each
    client doesn't have to duplicate this. I believe there's no need to
    invalidate the buffer before a DMA operation, since flushing the cache
    should prevent any write-backs.
    
    Update the MXS MMC driver for this change.
    
    Signed-off-by: default avatarStephen Warren <swarren@nvidia.com>
    Acked-by: default avatarSimon Glass <sjg@chromium.org>
    Tested-by: default avatarSimon Glass <sjg@chromium.org>
    Signed-off-by: default avatarAndy Fleming <afleming@freescale.com>
bouncebuf.h 3.17 KiB
/*
 * Generic bounce buffer implementation
 *
 * Copyright (C) 2012 Marek Vasut <marex@denx.de>
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#ifndef __INCLUDE_BOUNCEBUF_H__
#define __INCLUDE_BOUNCEBUF_H__

#include <linux/types.h>

/*
 * GEN_BB_READ -- Data are read from the buffer eg. by DMA hardware.
 * The source buffer is copied into the bounce buffer (if unaligned, otherwise
 * the source buffer is used directly) upon start() call, then the operation
 * requiring the aligned transfer happens, then the bounce buffer is lost upon
 * stop() call.
 */
#define GEN_BB_READ	(1 << 0)
/*
 * GEN_BB_WRITE -- Data are written into the buffer eg. by DMA hardware.
 * The source buffer starts in an undefined state upon start() call, then the
 * operation requiring the aligned transfer happens, then the bounce buffer is
 * copied into the destination buffer (if unaligned, otherwise destination
 * buffer is used directly) upon stop() call.
 */
#define GEN_BB_WRITE	(1 << 1)
/*
 * GEN_BB_RW -- Data are read and written into the buffer eg. by DMA hardware.
 * The source buffer is copied into the bounce buffer (if unaligned, otherwise
 * the source buffer is used directly) upon start() call, then the  operation
 * requiring the aligned transfer happens, then the bounce buffer is  copied
 * into the destination buffer (if unaligned, otherwise destination buffer is
 * used directly) upon stop() call.
 */
#define GEN_BB_RW	(GEN_BB_READ | GEN_BB_WRITE)

struct bounce_buffer {
	/* Copy of data parameter passed to start() */
	void *user_buffer;
	/*
	 * DMA-aligned buffer. This field is always set to the value that
	 * should be used for DMA; either equal to .user_buffer, or to a
	 * freshly allocated aligned buffer.
	 */
	void *bounce_buffer;
	/* Copy of len parameter passed to start() */
	size_t len;
	/* DMA-aligned buffer length */
	size_t len_aligned;
	/* Copy of flags parameter passed to start() */
	unsigned int flags;
};

/**
 * bounce_buffer_start() -- Start the bounce buffer session
 * state:	stores state passed between bounce_buffer_{start,stop}
 * data:	pointer to buffer to be aligned
 * len:		length of the buffer
 * flags:	flags describing the transaction, see above.
 */
int bounce_buffer_start(struct bounce_buffer *state, void *data,
			size_t len, unsigned int flags);
/**
 * bounce_buffer_stop() -- Finish the bounce buffer session
 * state:	stores state passed between bounce_buffer_{start,stop}
 */
int bounce_buffer_stop(struct bounce_buffer *state);

#endif