From 6d639b09f0e3ef0c1cc38606a851e6ae9a4f4e30 Mon Sep 17 00:00:00 2001 From: Andreas Fritiofson Date: Sun, 12 Feb 2012 22:29:50 +0100 Subject: Add a bit-level transfer queue Interface drivers regularly need to keep track of where each part of a long read buffer should be copied, once that data arrives. Both source and destination are often at an arbitrary bit offset. This queued bit-level copy can help with that, by allowing the driver to perform postponed reads from the receive buffer already when building the transmit buffer, and have those reads executed at a later time when data is available. For simplicity, it uses the linked list implementation list.h imported from the Linux kernel. Change-Id: I06862a0a6f057cbbcacfb021f17a795195faded2 Signed-off-by: Andreas Fritiofson Reviewed-on: http://openocd.zylin.com/450 Tested-by: jenkins Reviewed-by: Xiaofan Reviewed-by: Freddie Chopin Reviewed-by: Peter Stuge --- src/helper/binarybuffer.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'src/helper/binarybuffer.c') diff --git a/src/helper/binarybuffer.c b/src/helper/binarybuffer.c index 74af53a9..d98fa162 100644 --- a/src/helper/binarybuffer.c +++ b/src/helper/binarybuffer.c @@ -327,3 +327,46 @@ int str_to_buf(const char *str, unsigned str_len, return i; } + +void bit_copy_queue_init(struct bit_copy_queue *q) +{ + INIT_LIST_HEAD(&q->list); +} + +int bit_copy_queued(struct bit_copy_queue *q, uint8_t *dst, unsigned dst_offset, const uint8_t *src, + unsigned src_offset, unsigned bit_count) +{ + struct bit_copy_queue_entry *qe = malloc(sizeof(*qe)); + if (!qe) + return ERROR_FAIL; + + qe->dst = dst; + qe->dst_offset = dst_offset; + qe->src = src; + qe->src_offset = src_offset; + qe->bit_count = bit_count; + list_add_tail(&qe->list, &q->list); + + return ERROR_OK; +} + +void bit_copy_execute(struct bit_copy_queue *q) +{ + struct bit_copy_queue_entry *qe; + struct bit_copy_queue_entry *tmp; + list_for_each_entry_safe(qe, tmp, &q->list, list) { + bit_copy(qe->dst, qe->dst_offset, qe->src, qe->src_offset, qe->bit_count); + list_del(&qe->list); + free(qe); + } +} + +void bit_copy_discard(struct bit_copy_queue *q) +{ + struct bit_copy_queue_entry *qe; + struct bit_copy_queue_entry *tmp; + list_for_each_entry_safe(qe, tmp, &q->list, list) { + list_del(&qe->list); + free(qe); + } +} -- cgit v1.2.3-18-g5258