Skip to content

Commit a74b652

Browse files
ananglcfriedt
authored andcommitted
drivers: spi_context: Fix handling of zero-length buffers
In some cases, it is quite useful to have the possibility to also include zero-length buffers in a buffer set used in transfers (for example, when frames in a protocol consist of several parts, of which some are optional). So far, the behavior of spi_context update functions was that the transfer in a given direction was finished when a zero-length buffer was encountered in the buffer set. Change those functions to simply skip such buffers. Correct in the same way also the spi_context_buffers_setup() function. Signed-off-by: Andrzej Głąbek <[email protected]>
1 parent 5db25d9 commit a74b652

File tree

1 file changed

+43
-38
lines changed

1 file changed

+43
-38
lines changed

drivers/spi/spi_context.h

Lines changed: 43 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,25 @@ static inline void spi_context_unlock_unconditionally(struct spi_context *ctx)
248248
}
249249
}
250250

251+
static inline void *spi_context_get_next_buf(const struct spi_buf **current,
252+
size_t *count,
253+
size_t *buf_len,
254+
uint8_t dfs)
255+
{
256+
/* This loop skips zero-length buffers in the set, if any. */
257+
while (*count) {
258+
if (((*current)->len / dfs) != 0) {
259+
*buf_len = (*current)->len / dfs;
260+
return (*current)->buf;
261+
}
262+
++(*current);
263+
--(*count);
264+
}
265+
266+
*buf_len = 0;
267+
return NULL;
268+
}
269+
251270
static inline
252271
void spi_context_buffers_setup(struct spi_context *ctx,
253272
const struct spi_buf_set *tx_bufs,
@@ -256,29 +275,17 @@ void spi_context_buffers_setup(struct spi_context *ctx,
256275
{
257276
LOG_DBG("tx_bufs %p - rx_bufs %p - %u", tx_bufs, rx_bufs, dfs);
258277

259-
if (tx_bufs) {
260-
ctx->current_tx = tx_bufs->buffers;
261-
ctx->tx_count = tx_bufs->count;
262-
ctx->tx_buf = (const uint8_t *)ctx->current_tx->buf;
263-
ctx->tx_len = ctx->current_tx->len / dfs;
264-
} else {
265-
ctx->current_tx = NULL;
266-
ctx->tx_count = 0;
267-
ctx->tx_buf = NULL;
268-
ctx->tx_len = 0;
269-
}
278+
ctx->current_tx = tx_bufs ? tx_bufs->buffers : NULL;
279+
ctx->tx_count = ctx->current_tx ? tx_bufs->count : 0;
280+
ctx->tx_buf = (const uint8_t *)
281+
spi_context_get_next_buf(&ctx->current_tx, &ctx->tx_count,
282+
&ctx->tx_len, dfs);
270283

271-
if (rx_bufs) {
272-
ctx->current_rx = rx_bufs->buffers;
273-
ctx->rx_count = rx_bufs->count;
274-
ctx->rx_buf = (uint8_t *)ctx->current_rx->buf;
275-
ctx->rx_len = ctx->current_rx->len / dfs;
276-
} else {
277-
ctx->current_rx = NULL;
278-
ctx->rx_count = 0;
279-
ctx->rx_buf = NULL;
280-
ctx->rx_len = 0;
281-
}
284+
ctx->current_rx = rx_bufs ? rx_bufs->buffers : NULL;
285+
ctx->rx_count = ctx->current_rx ? rx_bufs->count : 0;
286+
ctx->rx_buf = (uint8_t *)
287+
spi_context_get_next_buf(&ctx->current_rx, &ctx->rx_count,
288+
&ctx->rx_len, dfs);
282289

283290
ctx->sync_status = 0;
284291

@@ -307,14 +314,13 @@ void spi_context_update_tx(struct spi_context *ctx, uint8_t dfs, uint32_t len)
307314

308315
ctx->tx_len -= len;
309316
if (!ctx->tx_len) {
310-
ctx->tx_count--;
311-
if (ctx->tx_count) {
312-
ctx->current_tx++;
313-
ctx->tx_buf = (const uint8_t *)ctx->current_tx->buf;
314-
ctx->tx_len = ctx->current_tx->len / dfs;
315-
} else {
316-
ctx->tx_buf = NULL;
317-
}
317+
/* Current buffer is done. Get the next one to be processed. */
318+
++ctx->current_tx;
319+
--ctx->tx_count;
320+
ctx->tx_buf = (const uint8_t *)
321+
spi_context_get_next_buf(&ctx->current_tx,
322+
&ctx->tx_count,
323+
&ctx->tx_len, dfs);
318324
} else if (ctx->tx_buf) {
319325
ctx->tx_buf += dfs * len;
320326
}
@@ -355,14 +361,13 @@ void spi_context_update_rx(struct spi_context *ctx, uint8_t dfs, uint32_t len)
355361

356362
ctx->rx_len -= len;
357363
if (!ctx->rx_len) {
358-
ctx->rx_count--;
359-
if (ctx->rx_count) {
360-
ctx->current_rx++;
361-
ctx->rx_buf = (uint8_t *)ctx->current_rx->buf;
362-
ctx->rx_len = ctx->current_rx->len / dfs;
363-
} else {
364-
ctx->rx_buf = NULL;
365-
}
364+
/* Current buffer is done. Get the next one to be processed. */
365+
++ctx->current_rx;
366+
--ctx->rx_count;
367+
ctx->rx_buf = (uint8_t *)
368+
spi_context_get_next_buf(&ctx->current_rx,
369+
&ctx->rx_count,
370+
&ctx->rx_len, dfs);
366371
} else if (ctx->rx_buf) {
367372
ctx->rx_buf += dfs * len;
368373
}

0 commit comments

Comments
 (0)