Source
x
* @length number of bytes to copy. may reach this limit before exhausting
/*
* Copyright 2016 Broadcom
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2, as
* published by the Free Software Foundation (the "GPL").
*
* 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 version 2 (GPLv2) for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 (GPLv2) along with this source code.
*/
/* offset of SPU_OFIFO_CTRL register */
/**
* spu_sg_at_offset() - Find the scatterlist entry at a given distance from the
* start of a scatterlist.
* @sg: [in] Start of a scatterlist
* @skip: [in] Distance from the start of the scatterlist, in bytes
* @sge: [out] Scatterlist entry at skip bytes from start
* @sge_offset: [out] Number of bytes from start of sge buffer to get to
* requested distance.
*
* Return: 0 if entry found at requested distance
* < 0 otherwise
*/
int spu_sg_at_offset(struct scatterlist *sg, unsigned int skip,
struct scatterlist **sge, unsigned int *sge_offset)
{
/* byte index from start of sg to the end of the previous entry */
unsigned int index = 0;
/* byte index from start of sg to the end of the current entry */
unsigned int next_index;
next_index = sg->length;
while (next_index <= skip) {
sg = sg_next(sg);
index = next_index;
if (!sg)
return -EINVAL;
next_index += sg->length;
}
*sge_offset = skip - index;
*sge = sg;
return 0;
}
/* Copy len bytes of sg data, starting at offset skip, to a dest buffer */
void sg_copy_part_to_buf(struct scatterlist *src, u8 *dest,
unsigned int len, unsigned int skip)
{
size_t copied;
unsigned int nents = sg_nents(src);
copied = sg_pcopy_to_buffer(src, nents, dest, len, skip);
if (copied != len) {
flow_log("%s copied %u bytes of %u requested. ",
__func__, (u32)copied, len);
flow_log("sg with %u entries and skip %u\n", nents, skip);
}
}
/*
* Copy data into a scatterlist starting at a specified offset in the
* scatterlist. Specifically, copy len bytes of data in the buffer src
* into the scatterlist dest, starting skip bytes into the scatterlist.
*/
void sg_copy_part_from_buf(struct scatterlist *dest, u8 *src,
unsigned int len, unsigned int skip)
{
size_t copied;
unsigned int nents = sg_nents(dest);
copied = sg_pcopy_from_buffer(dest, nents, src, len, skip);
if (copied != len) {
flow_log("%s copied %u bytes of %u requested. ",
__func__, (u32)copied, len);
flow_log("sg with %u entries and skip %u\n", nents, skip);
}
}