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>