Annotation of margi2/ringbuffy.c, revision 1.5

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: {
1.4       mocm       28:        rbuf->size = 0;
                     29:        rbuf->read_pos = 0;     
                     30:        rbuf->write_pos = 0;
1.1       cvs        31:        
                     32:        if (size > 0){
                     33:                if( !(rbuf->buffy = (char *) vmalloc(sizeof(char)*size)) ){
1.3       mocm       34:                        MDEBUG(0, 
1.1       cvs        35:                               "Not enough memory for ringbuffy\n");
                     36:                        return -1;
                     37:                }
                     38:        } else {
1.3       mocm       39:                MDEBUG(0, "Wrong size for ringbuffy\n");
1.1       cvs        40:                return -1;
                     41:        }
                     42: 
1.4       mocm       43:        rbuf->size = size;
1.1       cvs        44:        return 0;
                     45: }
                     46: 
                     47: 
                     48: void ring_destroy(ringbuffy *rbuf)
                     49: {
                     50:        if (rbuf->size){
                     51:                vfree(rbuf->buffy);
                     52:                rbuf->buffy = NULL;
                     53:        }
                     54:        rbuf->size = 0;
                     55:        rbuf->read_pos = 0;     
                     56:        rbuf->write_pos = 0;
                     57: }
                     58: 
                     59: 
                     60: int ring_write(ringbuffy *rbuf, const char *data, int count)
                     61: {
                     62: 
                     63:        long diff, free, pos, rest;
                     64: 
                     65:       
                     66:        if (count <=0 || !rbuf->buffy) return 0;
                     67:                pos  = rbuf->write_pos;
                     68:        rest = rbuf->size - pos;
                     69:        diff = rbuf->read_pos - pos;
                     70:        free = (diff > 0) ? diff-4 : rbuf->size+diff-4;
                     71: 
                     72:        if ( free <= 0 ) return 0;
                     73:        if ( free < count ) count = free;
                     74:        
                     75:        if (count >= rest){
                     76:                if(copy_from_user (rbuf->buffy+pos, data, rest))
                     77:                  return -EFAULT;
                     78:                if (count - rest)
                     79:                        if(copy_from_user(rbuf->buffy, data+rest, 
                     80:                                          count - rest))
                     81:                          return -EFAULT;
                     82:                rbuf->write_pos = count - rest;
                     83:        } else {
                     84:                copy_from_user (rbuf->buffy+pos, data, count);
                     85:                rbuf->write_pos += count;
                     86:        }
                     87: 
                     88:        return count;
                     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){
1.2       mocm      150:                long diff, free, pos;
1.1       cvs       151: 
                    152:        if (!rbuf->buffy) return 0;
                    153:        pos  = rbuf->read_pos;
                    154:        diff = rbuf->write_pos - pos;
                    155:        free = (diff >= 0) ? diff : rbuf->size+diff;
                    156:        
                    157:        return free;
                    158: }
                    159: 
                    160: long ring_write_rest(ringbuffy *rbuf){
1.2       mocm      161:                long diff, free, pos;
1.1       cvs       162: 
                    163:        if (!rbuf->buffy) return 0;
                    164:                pos  = rbuf->write_pos;
                    165:        diff = rbuf->read_pos - pos;
                    166:        free = (diff > 0) ? diff-4 : rbuf->size+diff-4;
                    167:        
                    168:        return free;
                    169: }
                    170: 
                    171: void ring_flush(ringbuffy *rbuf){
                    172:        rbuf->read_pos  = 0;
                    173:        rbuf->write_pos = 0;
                    174: }

LinuxTV legacy CVS <linuxtv.org/cvs>