1/* The industrial I/O simple minimally locked ring buffer. 2 * 3 * Copyright (c) 2008 Jonathan Cameron 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 as published by 7 * the Free Software Foundation. 8 * 9 * This code is deliberately kept separate from the main industrialio I/O core 10 * as it is intended that in the future a number of different software ring 11 * buffer implementations will exist with different characteristics to suit 12 * different applications. 13 * 14 * This particular one was designed for a data capture application where it was 15 * particularly important that no userspace reads would interrupt the capture 16 * process. To this end the ring is not locked during a read. 17 * 18 * Comments on this buffer design welcomed. It's far from efficient and some of 19 * my understanding of the effects of scheduling on this are somewhat limited. 20 * Frankly, to my mind, this is the current weak point in the industrial I/O 21 * patch set. 22 */ 23 24#ifndef _IIO_RING_SW_H_ 25#define _IIO_RING_SW_H_ 26/* NEEDS COMMENTS */ 27/* The intention is that this should be a separate module from the iio core. 28 * This is a bit like supporting algorithms dependent on what the device 29 * driver requests - some may support multiple options */ 30 31 32#include "iio.h" 33#include "ring_generic.h" 34 35#if defined CONFIG_IIO_SW_RING || defined CONFIG_IIO_SW_RING_MODULE 36 37/** 38 * iio_create_sw_rb() - software ring buffer allocation 39 * @r: pointer to ring buffer pointer 40 **/ 41int iio_create_sw_rb(struct iio_ring_buffer **r); 42 43/** 44 * iio_init_sw_rb() - initialize the software ring buffer 45 * @r: pointer to a software ring buffer created by an 46 * iio_create_sw_rb call 47 * @indio_dev: industrial I/O device structure 48 **/ 49int iio_init_sw_rb(struct iio_ring_buffer *r, struct iio_dev *indio_dev); 50 51/** 52 * iio_exit_sw_rb() - reverse what was done in iio_init_sw_rb 53 * @r: pointer to a software ring buffer created by an 54 * iio_create_sw_rb call 55 **/ 56void iio_exit_sw_rb(struct iio_ring_buffer *r); 57 58/** 59 * iio_free_sw_rb() - free memory occupied by the core ring buffer struct 60 * @r: pointer to a software ring buffer created by an 61 * iio_create_sw_rb call 62 **/ 63void iio_free_sw_rb(struct iio_ring_buffer *r); 64 65/** 66 * iio_mark_sw_rb_in_use() - reference counting to prevent incorrect chances 67 * @r: pointer to a software ring buffer created by an 68 * iio_create_sw_rb call 69 **/ 70void iio_mark_sw_rb_in_use(struct iio_ring_buffer *r); 71 72/** 73 * iio_unmark_sw_rb_in_use() - notify the ring buffer that we don't care anymore 74 * @r: pointer to a software ring buffer created by an 75 * iio_create_sw_rb call 76 **/ 77void iio_unmark_sw_rb_in_use(struct iio_ring_buffer *r); 78 79/** 80 * iio_read_last_from_sw_rb() - attempt to read the last stored datum from the rb 81 * @r: pointer to a software ring buffer created by an 82 * iio_create_sw_rb call 83 * @data: where to store the last datum 84 **/ 85int iio_read_last_from_sw_rb(struct iio_ring_buffer *r, u8 *data); 86 87/** 88 * iio_store_to_sw_rb() - store a new datum to the ring buffer 89 * @r: pointer to ring buffer instance 90 * @data: the datum to be stored including timestamp if relevant 91 * @timestamp: timestamp which will be attached to buffer events if relevant 92 **/ 93int iio_store_to_sw_rb(struct iio_ring_buffer *r, u8 *data, s64 timestamp); 94 95/** 96 * iio_rip_sw_rb() - attempt to read data from the ring buffer 97 * @r: ring buffer instance 98 * @count: number of datum's to try and read 99 * @buf: userspace buffer into which data is copied 100 * @dead_offset: how much of the stored data was possibly invalidated by 101 * the end of the copy. 102 **/ 103int iio_rip_sw_rb(struct iio_ring_buffer *r, 104 size_t count, 105 char __user *buf, 106 int *dead_offset); 107 108/** 109 * iio_request_update_sw_rb() - update params if update needed 110 * @r: pointer to a software ring buffer created by an 111 * iio_create_sw_rb call 112 **/ 113int iio_request_update_sw_rb(struct iio_ring_buffer *r); 114 115/** 116 * iio_mark_update_needed_sw_rb() - tell the ring buffer it needs a param update 117 * @r: pointer to a software ring buffer created by an 118 * iio_create_sw_rb call 119 **/ 120int iio_mark_update_needed_sw_rb(struct iio_ring_buffer *r); 121 122 123/** 124 * iio_get_bytes_per_datum_sw_rb() - get the datum size in bytes 125 * @r: pointer to a software ring buffer created by an 126 * iio_create_sw_rb call 127 **/ 128int iio_get_bytes_per_datum_sw_rb(struct iio_ring_buffer *r); 129 130/** 131 * iio_set_bytes_per_datum_sw_rb() - set the datum size in bytes 132 * @r: pointer to a software ring buffer created by an 133 * iio_create_sw_rb call 134 * @bpd: bytes per datum value 135 **/ 136int iio_set_bytes_per_datum_sw_rb(struct iio_ring_buffer *r, size_t bpd); 137 138/** 139 * iio_get_length_sw_rb() - get how many datums the rb may contain 140 * @r: pointer to a software ring buffer created by an 141 * iio_create_sw_rb call 142 **/ 143int iio_get_length_sw_rb(struct iio_ring_buffer *r); 144 145/** 146 * iio_set_length_sw_rb() - set how many datums the rb may contain 147 * @r: pointer to a software ring buffer created by an 148 * iio_create_sw_rb call 149 * @length: max number of data items for the ring buffer 150 **/ 151int iio_set_length_sw_rb(struct iio_ring_buffer *r, int length); 152 153/** 154 * iio_ring_sw_register_funcs() - helper function to set up rb access 155 * @ra: pointer to @iio_ring_access_funcs 156 **/ 157static inline void iio_ring_sw_register_funcs(struct iio_ring_access_funcs *ra) 158{ 159 ra->mark_in_use = &iio_mark_sw_rb_in_use; 160 ra->unmark_in_use = &iio_unmark_sw_rb_in_use; 161 162 ra->store_to = &iio_store_to_sw_rb; 163 ra->read_last = &iio_read_last_from_sw_rb; 164 ra->rip_lots = &iio_rip_sw_rb; 165 166 ra->mark_param_change = &iio_mark_update_needed_sw_rb; 167 ra->request_update = &iio_request_update_sw_rb; 168 169 ra->get_bytes_per_datum = &iio_get_bytes_per_datum_sw_rb; 170 ra->set_bytes_per_datum = &iio_set_bytes_per_datum_sw_rb; 171 172 ra->get_length = &iio_get_length_sw_rb; 173 ra->set_length = &iio_set_length_sw_rb; 174}; 175 176/** 177 * struct iio_sw_ring_buffer - software ring buffer 178 * @buf: generic ring buffer elements 179 * @data: the ring buffer memory 180 * @read_p: read pointer (oldest available) 181 * @write_p: write pointer 182 * @last_written_p: read pointer (newest available) 183 * @half_p: half buffer length behind write_p (event generation) 184 * @use_count: reference count to prevent resizing when in use 185 * @update_needed: flag to indicated change in size requested 186 * @use_lock: lock to prevent change in size when in use 187 * 188 * Note that the first element of all ring buffers must be a 189 * struct iio_ring_buffer. 190**/ 191 192struct iio_sw_ring_buffer { 193 struct iio_ring_buffer buf; 194 unsigned char *data; 195 unsigned char *read_p; 196 unsigned char *write_p; 197 unsigned char *last_written_p; 198 /* used to act as a point at which to signal an event */ 199 unsigned char *half_p; 200 int use_count; 201 int update_needed; 202 spinlock_t use_lock; 203}; 204 205#define iio_to_sw_ring(r) container_of(r, struct iio_sw_ring_buffer, buf) 206 207struct iio_ring_buffer *iio_sw_rb_allocate(struct iio_dev *indio_dev); 208void iio_sw_rb_free(struct iio_ring_buffer *ring); 209 210int iio_sw_ring_preenable(struct iio_dev *indio_dev); 211 212struct iio_sw_ring_helper_state { 213 struct work_struct work_trigger_to_ring; 214 struct iio_dev *indio_dev; 215 int (*get_ring_element)(struct iio_sw_ring_helper_state *st, u8 *buf); 216 s64 last_timestamp; 217}; 218 219void iio_sw_poll_func_th(struct iio_dev *indio_dev, s64 time); 220void iio_sw_trigger_bh_to_ring(struct work_struct *work_s); 221 222#else /* CONFIG_IIO_RING_BUFFER*/ 223struct iio_sw_ring_helper_state { 224 struct iio_dev *indio_dev; 225}; 226#endif /* !CONFIG_IIO_RING_BUFFER */ 227#endif /* _IIO_RING_SW_H_ */ 228