Annotation of margi2/ringbuffy.c, revision 1.2
1.1 cvs 1: /*
2: ringbuffy.c
3:
4: Copyright (C) Marcus Metzler for convergence integrated media.
5:
6: This program is free software; you can redistribute it and/or modify
7: it under the terms of the GNU General Public License as published by
8: the Free Software Foundation; either version 2 of the License, or
9: (at your option) any later version.
10:
11: This program is distributed in the hope that it will be useful,
12: but WITHOUT ANY WARRANTY; without even the implied warranty of
13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14: GNU General Public License for more details.
15:
16: You should have received a copy of the GNU General Public License
17: along with this program; if not, write to the Free Software
18: Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19: */
20:
21: #define __NO_VERSION__
22:
23: #include "margi.h"
24: #include "ringbuffy.h"
25:
26: int ring_init (ringbuffy *rbuf, long size)
27: {
28:
29: if (size > 0){
30: rbuf->size = size;
31: if( !(rbuf->buffy = (char *) vmalloc(sizeof(char)*size)) ){
32: printk(KERN_DEBUG LOGNAME
33: "Not enough memory for ringbuffy\n");
34: return -1;
35: }
36: } else {
37: printk(KERN_DEBUG LOGNAME "Wrong size for ringbuffy\n");
38: return -1;
39: }
40:
41: rbuf->read_pos = 0;
42: rbuf->write_pos = 0;
43: return 0;
44: }
45:
46:
47: void ring_destroy(ringbuffy *rbuf)
48: {
49: if (rbuf->size){
50: vfree(rbuf->buffy);
51: rbuf->buffy = NULL;
52: }
53: rbuf->size = 0;
54: rbuf->read_pos = 0;
55: rbuf->write_pos = 0;
56: }
57:
58:
59: int ring_write(ringbuffy *rbuf, const char *data, int count)
60: {
61:
62: long diff, free, pos, rest;
63:
64:
65: if (count <=0 || !rbuf->buffy) return 0;
66: pos = rbuf->write_pos;
67: rest = rbuf->size - pos;
68: diff = rbuf->read_pos - pos;
69: free = (diff > 0) ? diff-4 : rbuf->size+diff-4;
70:
71: if ( free <= 0 ) return 0;
72: if ( free < count ) count = free;
73:
74: if (count >= rest){
75: if(copy_from_user (rbuf->buffy+pos, data, rest))
76: return -EFAULT;
77: if (count - rest)
78: if(copy_from_user(rbuf->buffy, data+rest,
79: count - rest))
80: return -EFAULT;
81: rbuf->write_pos = count - rest;
82: } else {
83: copy_from_user (rbuf->buffy+pos, data, count);
84: rbuf->write_pos += count;
85: }
86:
87: return count;
88: }
89:
90:
1.2 ! mocm 91: int ring_writek(ringbuffy *rbuf, const char *data, int count)
! 92: {
! 93:
! 94: long diff, free, pos, rest;
! 95:
! 96:
! 97: if (count <=0 || !rbuf->buffy) return 0;
! 98: pos = rbuf->write_pos;
! 99: rest = rbuf->size - pos;
! 100: diff = rbuf->read_pos - pos;
! 101: free = (diff > 0) ? diff-4 : rbuf->size+diff-4;
! 102:
! 103: if ( free <= 0 ) return 0;
! 104: if ( free < count ) count = free;
! 105:
! 106: if (count >= rest){
! 107: if(memcpy(rbuf->buffy+pos, data, rest))
! 108: return -EFAULT;
! 109: if (count - rest)
! 110: if(memcpy(rbuf->buffy, data+rest,
! 111: count - rest))
! 112: return -EFAULT;
! 113: rbuf->write_pos = count - rest;
! 114: } else {
! 115: memcpy(rbuf->buffy+pos, data, count);
! 116: rbuf->write_pos += count;
! 117: }
! 118:
! 119: return count;
! 120: }
! 121:
! 122:
! 123:
1.1 cvs 124:
125: int ring_read(ringbuffy *rbuf, char *data, int count)
126: {
127:
128: long diff, free, pos, rest;
129:
130:
131: if (count <=0 || !rbuf->buffy) return 0;
132: pos = rbuf->read_pos;
133: rest = rbuf->size - pos;
134: diff = rbuf->write_pos - pos;
135: free = (diff >= 0) ? diff : rbuf->size+diff;
136:
137: if ( free <= 0 ) return 0;
138: if ( free < count ) count = free;
139:
140: if ( count >= rest ){
141: memcpy(data,rbuf->buffy+pos,rest);
142: if ( count - rest)
143: memcpy(data+rest,rbuf->buffy,count-rest);
144: rbuf->read_pos = count - rest;
145: } else {
146: memcpy(data,rbuf->buffy+pos,count);
147: rbuf->read_pos += count;
148: }
149:
150: return count;
151: }
152:
153: int ring_read_direct(ringbuffy *rbuf, int addr, int count)
154: {
155:
156: long diff, free, pos, rest;
157:
158:
159: if (count <=0 || !rbuf->buffy) return 0;
160: pos = rbuf->read_pos;
161: rest = rbuf->size - pos;
162: diff = rbuf->write_pos - pos;
163: free = (diff >= 0) ? diff : rbuf->size+diff;
164:
165: if ( free <= 0 ) return 0;
166: if ( free < count ) count = free;
167:
168: if ( count >= rest ){
169: outsl_ns(addr,rbuf->buffy+pos,rest/4);
170: if ( count - rest)
171: outsl_ns(addr,rbuf->buffy,(count-rest)/4);
172: rbuf->read_pos = count - rest;
173: } else {
174: outsl_ns(addr,rbuf->buffy+pos,count/4);
175: rbuf->read_pos += count;
176: }
177:
178: return count;
179: }
180:
181:
182: long ring_read_rest(ringbuffy *rbuf){
1.2 ! mocm 183: long diff, free, pos;
1.1 cvs 184:
185: if (!rbuf->buffy) return 0;
186: pos = rbuf->read_pos;
187: diff = rbuf->write_pos - pos;
188: free = (diff >= 0) ? diff : rbuf->size+diff;
189:
190: return free;
191: }
192:
193: long ring_write_rest(ringbuffy *rbuf){
1.2 ! mocm 194: long diff, free, pos;
1.1 cvs 195:
196: if (!rbuf->buffy) return 0;
197: pos = rbuf->write_pos;
198: diff = rbuf->read_pos - pos;
199: free = (diff > 0) ? diff-4 : rbuf->size+diff-4;
200:
201: return free;
202: }
203:
204: void ring_flush(ringbuffy *rbuf){
205: rbuf->read_pos = 0;
206: rbuf->write_pos = 0;
207: }
LinuxTV legacy CVS <linuxtv.org/cvs>