Annotation of margi2/ringbuffy.c, revision 1.4

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: 
1.2       mocm       92: int ring_writek(ringbuffy *rbuf, const 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->write_pos;
                    100:        rest = rbuf->size - pos;
                    101:        diff = rbuf->read_pos - pos;
                    102:        free = (diff > 0) ? diff-4 : rbuf->size+diff-4;
                    103: 
                    104:        if ( free <= 0 ) return 0;
                    105:        if ( free < count ) count = free;
                    106:        
                    107:        if (count >= rest){
                    108:                if(memcpy(rbuf->buffy+pos, data, rest))
                    109:                  return -EFAULT;
                    110:                if (count - rest)
                    111:                        if(memcpy(rbuf->buffy, data+rest, 
                    112:                                          count - rest))
                    113:                          return -EFAULT;
                    114:                rbuf->write_pos = count - rest;
                    115:        } else {
                    116:                memcpy(rbuf->buffy+pos, data, count);
                    117:                rbuf->write_pos += count;
                    118:        }
                    119: 
                    120:        return count;
                    121: }
                    122: 
                    123: 
                    124: 
1.1       cvs       125: 
                    126: int ring_read(ringbuffy *rbuf, char *data, int count)
                    127: {
                    128: 
                    129:        long diff, free, pos, rest;
                    130: 
                    131: 
                    132:        if (count <=0 || !rbuf->buffy) return 0;
                    133:        pos  = rbuf->read_pos;
                    134:        rest = rbuf->size - pos;
                    135:        diff = rbuf->write_pos - pos;
                    136:        free = (diff >= 0) ? diff : rbuf->size+diff;
                    137: 
                    138:        if ( free <= 0 ) return 0;
                    139:        if ( free < count ) count = free;
                    140:        
                    141:        if ( count >= rest ){
                    142:                memcpy(data,rbuf->buffy+pos,rest);
                    143:                if ( count - rest)
                    144:                        memcpy(data+rest,rbuf->buffy,count-rest);
                    145:                rbuf->read_pos = count - rest;
                    146:        } else {
                    147:                memcpy(data,rbuf->buffy+pos,count);
                    148:                rbuf->read_pos += count;
                    149:        }
                    150: 
                    151:        return count;
                    152: }
                    153: 
                    154: int ring_read_direct(ringbuffy *rbuf, int addr, int count)
                    155: {
                    156: 
                    157:        long diff, free, pos, rest;
                    158: 
                    159: 
                    160:        if (count <=0 || !rbuf->buffy) return 0;
                    161:        pos  = rbuf->read_pos;
                    162:        rest = rbuf->size - pos;
                    163:        diff = rbuf->write_pos - pos;
                    164:        free = (diff >= 0) ? diff : rbuf->size+diff;
                    165: 
                    166:        if ( free <= 0 ) return 0;
                    167:        if ( free < count ) count = free;
                    168:        
                    169:        if ( count >= rest ){
                    170:                outsl_ns(addr,rbuf->buffy+pos,rest/4);
                    171:                if ( count - rest)
                    172:                        outsl_ns(addr,rbuf->buffy,(count-rest)/4);
                    173:                rbuf->read_pos = count - rest;
                    174:        } else {
                    175:                outsl_ns(addr,rbuf->buffy+pos,count/4);
                    176:                rbuf->read_pos += count;
                    177:        }
                    178: 
                    179:        return count;
                    180: }
                    181: 
                    182: 
                    183: long ring_read_rest(ringbuffy *rbuf){
1.2       mocm      184:                long diff, free, pos;
1.1       cvs       185: 
                    186:        if (!rbuf->buffy) return 0;
                    187:        pos  = rbuf->read_pos;
                    188:        diff = rbuf->write_pos - pos;
                    189:        free = (diff >= 0) ? diff : rbuf->size+diff;
                    190:        
                    191:        return free;
                    192: }
                    193: 
                    194: long ring_write_rest(ringbuffy *rbuf){
1.2       mocm      195:                long diff, free, pos;
1.1       cvs       196: 
                    197:        if (!rbuf->buffy) return 0;
                    198:                pos  = rbuf->write_pos;
                    199:        diff = rbuf->read_pos - pos;
                    200:        free = (diff > 0) ? diff-4 : rbuf->size+diff-4;
                    201:        
                    202:        return free;
                    203: }
                    204: 
                    205: void ring_flush(ringbuffy *rbuf){
                    206:        rbuf->read_pos  = 0;
                    207:        rbuf->write_pos = 0;
                    208: }

LinuxTV legacy CVS <linuxtv.org/cvs>