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>