2 * driver/driver_to_buffer.c
3 * @author Alexander Aksenov <a.aksenov@samsung.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 * Copyright (C) Samsung Electronics, 2013
25 * @section DESCRIPTION
27 * Driver and buffer interaction interface implementation.
30 #include <linux/string.h>
31 #include <linux/slab.h>
32 #include <linux/splice.h>
33 #include <asm/uaccess.h>
34 #include <linux/spinlock.h>
37 #include <buffer/swap_buffer_module.h>
38 #include <buffer/swap_buffer_errors.h>
39 #include <buffer/buffer_description.h>
40 #include <writer/swap_writer_module.h>
42 #include "driver_defs.h"
43 #include "swap_driver_errors.h"
44 #include "device_driver_to_driver_to_buffer.h"
45 #include "app_manage.h"
47 /* Current busy buffer */
48 static struct swap_subbuffer *busy_buffer = NULL;
50 /* Buffers count ready to be read */
51 static int buffers_to_read = 0;
53 /* Pages count in one subbuffer */
54 static int pages_per_buffer = 0;
56 /* Used to sync changes of the buffers_to_read var */
57 static spinlock_t buf_to_read;
60 static inline void init_buffers_to_read(void)
62 spin_lock_init(&buf_to_read);
66 static inline void inc_buffers_to_read(void)
70 spin_lock_irqsave(&buf_to_read, flags);
72 spin_unlock_irqrestore(&buf_to_read, flags);
75 static inline void dec_buffers_to_read(void)
79 spin_lock_irqsave(&buf_to_read, flags);
81 spin_unlock_irqrestore(&buf_to_read, flags);
84 static inline void set_buffers_to_read(int count)
88 spin_lock_irqsave(&buf_to_read, flags);
89 buffers_to_read = count;
90 spin_unlock_irqrestore(&buf_to_read, flags);
93 static inline int something_to_read(void)
98 spin_lock_irqsave(&buf_to_read, flags);
99 result = buffers_to_read;
100 spin_unlock_irqrestore(&buf_to_read, flags);
105 /* TODO Get subbuffer for reading */
106 static size_t driver_to_buffer_get(void)
110 /* If there is no readable buffers, return error */
111 result = swap_buffer_get(&busy_buffer);
112 if (result == -E_SB_NO_READABLE_BUFFERS) {
114 return -E_SD_NO_DATA_TO_READ;
115 } else if (result < 0) {
116 print_err("swap_buffer_get unhandle error %d\n", result);
117 return -E_SD_BUFFER_ERROR;
120 return busy_buffer->full_buffer_part;
123 /* TODO Release subbuffer */
124 static int driver_to_buffer_release(void)
129 return -E_SD_NO_BUSY_SUBBUFFER;
131 result = swap_buffer_release(&busy_buffer);
132 if (result == -E_SB_NO_SUBBUFFER_IN_BUSY) {
133 return -E_SD_WRONG_SUBBUFFER_PTR;
134 } else if (result < 0) {
135 print_err("swap_buffer_release unhandle error %d\n", result);
136 return -E_SD_BUFFER_ERROR;
145 * @brief Buffers callback function
149 int driver_to_buffer_callback(void)
151 /* Increment buffers_to_read counter */
152 inc_buffers_to_read();
153 swap_device_wake_up_process();
159 * @brief Copies data from subbuffer to userspace.
161 * @param[out] buf Pointer to userspace memory area whereto copy data from
163 * @param count Size of data to be read.
164 * @return Read data size on success, negative error code on error.
166 ssize_t driver_to_buffer_read(char __user *buf, size_t count)
168 size_t bytes_to_copy;
169 size_t bytes_to_read = 0;
170 int page_counter = 0;
172 /* Reading from swap_device means reading only current busy_buffer. So, if
173 * there is no busy_buffer, we don't get next to read, we just read nothing.
174 * In this case, or if there is nothing to read from busy_buffer - return
175 * -E_SD_NO_DATA_TO_READ. It should be correctly handled in device_driver */
176 if (!busy_buffer || !busy_buffer->full_buffer_part)
177 return -E_SD_NO_DATA_TO_READ;
179 /* Bytes count that we're going to copy to user buffer is equal to user
180 * buffer size or to subbuffer readable size whichever is less */
181 bytes_to_copy = (count > busy_buffer->full_buffer_part) ?
182 busy_buffer->full_buffer_part : count;
184 /* Copy data from each page to buffer */
185 while(bytes_to_copy > 0) {
186 /* Get size that should be copied from current page */
187 size_t read_from_this_page = (bytes_to_copy > PAGE_SIZE) ? PAGE_SIZE
190 /* Copy and add size to copied bytes count */
192 // TODO Check with more than one page
193 bytes_to_read += read_from_this_page -
194 copy_to_user(buf, page_address(busy_buffer->data_buffer) +
195 (sizeof(struct page*) *
197 read_from_this_page);
198 bytes_to_copy -= read_from_this_page;
202 return bytes_to_read;
206 * @brief Flushes SWAP buffer.
210 int driver_to_buffer_flush(void)
212 unsigned int flushed;
214 flushed = swap_buffer_flush();
215 set_buffers_to_read(flushed);
216 swap_device_wake_up_process();
222 * @brief Fills spd structure.
224 * @param[out] spd Pointer to the splice_pipe_desc struct that should be filled.
225 * @return 0 on success, negative error code on error.
227 int driver_to_buffer_fill_spd(struct splice_pipe_desc *spd)
229 size_t data_to_splice = busy_buffer->full_buffer_part;
230 struct page **pages = spd->pages;
231 struct partial_page *partial = spd->partial;
233 while (data_to_splice) {
234 size_t read_from_current_page = min(data_to_splice, (size_t)PAGE_SIZE);
236 pages[spd->nr_pages] = alloc_page(GFP_KERNEL);
237 if (!pages[spd->nr_pages]) {
238 print_err("Cannot alloc page for splice\n");
242 /* FIXME: maybe there is more efficient way */
243 memcpy(page_address(pages[spd->nr_pages]),
244 page_address(&busy_buffer->data_buffer[spd->nr_pages]),
245 read_from_current_page);
247 /* Always beginning of the page */
248 partial[spd->nr_pages].offset = 0;
249 partial[spd->nr_pages].len = read_from_current_page;
251 /* Private is not used */
252 partial[spd->nr_pages].private = 0;
255 data_to_splice -= read_from_current_page;
257 /* TODO: add check for pipe->buffers exceeding */
258 /* if (spd->nr_pages == pipe->buffers) { */
266 * @brief Check for subbuffer ready to be read.
268 * @return 1 if there is subbuffer to be read, 0 - if there isn't.
270 int driver_to_buffer_buffer_to_read(void)
272 return busy_buffer ? 1 : 0;
276 * @brief Initializes SWAP buffer.
278 * @param size Size of one subbuffer.
279 * @param count Count of subbuffers.
280 * @return 0 on success, negative error code on error.
282 int driver_to_buffer_initialize(size_t size, unsigned int count)
285 struct buffer_init_t buf_init = {
286 .subbuffer_size = size,
287 .nr_subbuffers = count,
288 .subbuffer_full_cb = driver_to_buffer_callback,
289 .lower_threshold = 20,
290 .low_mem_cb = app_manage_pause_apps,
292 .enough_mem_cb = app_manage_cont_apps,
295 if (size == 0 && count == 0) {
296 return -E_SD_WRONG_ARGS;
299 result = swap_buffer_init(&buf_init);
300 if (result == -E_SB_NO_MEM_QUEUE_BUSY
301 || result == -E_SB_NO_MEM_BUFFER_STRUCT) {
302 return -E_SD_NO_MEMORY;
305 // TODO Race condition: buffer can be used in other thread till we're in
307 /* Initialize driver_to_buffer variables */
308 pages_per_buffer = result;
310 init_buffers_to_read();
316 * @brief Uninitializes buffer.
318 * @return 0 on success, negative error code on error.
320 int driver_to_buffer_uninitialize(void)
324 /* Release occupied buffer */
326 result = driver_to_buffer_release();
327 // TODO Maybe release anyway
334 result = swap_buffer_uninit();
335 if (result == -E_SB_UNRELEASED_BUFFERS) {
336 print_err("Can't uninit buffer! There are busy subbuffers!\n");
337 result = -E_SD_BUFFER_ERROR;
338 } else if (result < 0) {
339 print_err("swap_buffer_uninit error %d\n", result);
340 result = -E_SD_BUFFER_ERROR;
342 result = E_SD_SUCCESS;
345 /* Reinit driver_to_buffer vars */
346 init_buffers_to_read();
347 pages_per_buffer = 0;
353 * @brief Get next buffer to read.
355 * @return 0 on success, negative error code on error, E_SD_NO_DATA_TO_READ if
356 * there is nothing to be read.
358 int driver_to_buffer_next_buffer_to_read(void)
362 /* If there is busy_buffer first release it */
364 result = driver_to_buffer_release();
369 /* If there is no buffers to read, return E_SD_NO_DATA_TO_READ.
370 * SHOULD BE POSITIVE, cause there is no real error. */
371 if (!something_to_read()) {
372 return E_SD_NO_DATA_TO_READ;
375 /* Get next buffer to read */
376 result = driver_to_buffer_get();
378 print_err("buffer_to_reads > 0, but there are no buffers to read\n");
382 /* Decrement buffers_to_read counter */
383 dec_buffers_to_read();