Annotation of margi2/ringbuffy.c, revision 1.1
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:
! 91:
! 92: int ring_read(ringbuffy *rbuf, char *data, int count)
! 93: {
! 94:
! 95: long diff, free, pos, rest;
! 96:
! 97:
! 98: if (count <=0 || !rbuf->buffy) return 0;
! 99: pos = rbuf->read_pos;
! 100: rest = rbuf->size - pos;
! 101: diff = rbuf->write_pos - pos;
! 102: free = (diff >= 0) ? diff : rbuf->size+diff;
! 103:
! 104: if ( free <= 0 ) return 0;
! 105: if ( free < count ) count = free;
! 106:
! 107: if ( count >= rest ){
! 108: memcpy(data,rbuf->buffy+pos,rest);
! 109: if ( count - rest)
! 110: memcpy(data+rest,rbuf->buffy,count-rest);
! 111: rbuf->read_pos = count - rest;
! 112: } else {
! 113: memcpy(data,rbuf->buffy+pos,count);
! 114: rbuf->read_pos += count;
! 115: }
! 116:
! 117: return count;
! 118: }
! 119:
! 120: int ring_read_direct(ringbuffy *rbuf, int addr, int count)
! 121: {
! 122:
! 123: long diff, free, pos, rest;
! 124:
! 125:
! 126: if (count <=0 || !rbuf->buffy) return 0;
! 127: pos = rbuf->read_pos;
! 128: rest = rbuf->size - pos;
! 129: diff = rbuf->write_pos - pos;
! 130: free = (diff >= 0) ? diff : rbuf->size+diff;
! 131:
! 132: if ( free <= 0 ) return 0;
! 133: if ( free < count ) count = free;
! 134:
! 135: if ( count >= rest ){
! 136: outsl_ns(addr,rbuf->buffy+pos,rest/4);
! 137: if ( count - rest)
! 138: outsl_ns(addr,rbuf->buffy,(count-rest)/4);
! 139: rbuf->read_pos = count - rest;
! 140: } else {
! 141: outsl_ns(addr,rbuf->buffy+pos,count/4);
! 142: rbuf->read_pos += count;
! 143: }
! 144:
! 145: return count;
! 146: }
! 147:
! 148:
! 149: long ring_read_rest(ringbuffy *rbuf){
! 150: long diff, free, pos, rest;
! 151:
! 152: if (!rbuf->buffy) return 0;
! 153: pos = rbuf->read_pos;
! 154: rest = rbuf->size - pos;
! 155: diff = rbuf->write_pos - pos;
! 156: free = (diff >= 0) ? diff : rbuf->size+diff;
! 157:
! 158: return free;
! 159: }
! 160:
! 161: long ring_write_rest(ringbuffy *rbuf){
! 162: long diff, free, pos, rest;
! 163:
! 164: if (!rbuf->buffy) return 0;
! 165: pos = rbuf->write_pos;
! 166: rest = rbuf->size - pos;
! 167: diff = rbuf->read_pos - pos;
! 168: free = (diff > 0) ? diff-4 : rbuf->size+diff-4;
! 169:
! 170: return free;
! 171: }
! 172:
! 173: void ring_flush(ringbuffy *rbuf){
! 174: rbuf->read_pos = 0;
! 175: rbuf->write_pos = 0;
! 176: }
LinuxTV legacy CVS <linuxtv.org/cvs>