Subversion Repositories shark

Rev

Rev 629 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
629 giacomo 1
/*
2
 * Project: S.Ha.R.K.
3
 *
4
 * Coordinators:
5
 *   Giorgio Buttazzo    <giorgio@sssup.it>
6
 *   Paolo Gai           <pj@gandalf.sssup.it>
7
 *
8
 * Authors     :
9
 *   Paolo Gai           <pj@gandalf.sssup.it>
10
 *   Massimiliano Giorgi <massy@gandalf.sssup.it>
11
 *   Luca Abeni          <luca@gandalf.sssup.it>
12
 *   (see the web pages for full authors list)
13
 *
14
 * ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
15
 *
16
 * http://www.sssup.it
17
 * http://retis.sssup.it
18
 * http://shark.sssup.it
19
 */
20
 
21
/**
22
 ------------
23
 CVS :        $Id: netbuff.c,v 1.3 2004-05-11 14:30:50 giacomo Exp $
24
 
25
 File:        $File$
26
 Revision:    $Revision: 1.3 $
27
 Last update: $Date: 2004-05-11 14:30:50 $
28
 ------------
29
**/
30
 
31
/*
32
 * Copyright (C) 2000 Luca Abeni
33
 *
34
 * This program is free software; you can redistribute it and/or modify
35
 * it under the terms of the GNU General Public License as published by
36
 * the Free Software Foundation; either version 2 of the License, or
37
 * (at your option) any later version.
38
 *
39
 * This program is distributed in the hope that it will be useful,
40
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
41
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
42
 * GNU General Public License for more details.
43
 *
44
 * You should have received a copy of the GNU General Public License
45
 * along with this program; if not, write to the Free Software
46
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
47
 *
48
 */
49
 
50
/* Author:      Luca Abeni                                      */
51
/* Date:        25/9/1997                                       */
52
 
53
/* File:        NetBuff.c                                       */
54
/* Revision:    1.00                                            */
55
 
56
/*
57
   This module manages all the buffers used by the network driver:
58
   the buffers are grouped in netbuff structures (initialized by
59
   netbuff_init) and can be allocated by netbuff_get or released
60
   by netbuff_released. A netbuff_sequentialget function is also
61
   provided for beeing used by tasks that have their own buffer (
62
   if a buffer can be allocated by only one task, it is useless to
63
   allocate it in mutual exclusion). It is usefull for the receive
64
   buffers allocated by the receive process.
65
*/
66
#include <kernel/kern.h>
67
#include <semaphore.h>
68
 
69
#include "netbuff.h"
70
 
71
/* Init the buffer structures */
72
void netbuff_init(struct netbuff *netb, BYTE nbuffs, WORD buffdim)
73
{
74
        int i;
75
 
76
        kern_cli();
77
        netb->b = kern_alloc(nbuffs * buffdim);
78
        netb->pb = kern_alloc(nbuffs * sizeof(void *));
79
        netb->free = kern_alloc(nbuffs * sizeof(char));
80
        kern_sti();
81
        if ((netb->b == 0) || (netb->pb ==0) || (netb->free == 0)) {
82
                kern_raise(XNETBUFF_INIT_EXC,exec_shadow);
83
        }
84
        netb->nbuffs = nbuffs;
85
        for (i = 0; i < nbuffs; i++) {
86
                netb->pb[i] = netb->b + (i * buffdim);
87
                netb->free[i] = 1;
88
        }
89
        sem_init(&(netb->buffersem), 0, nbuffs);
90
}
91
 
92
/*
93
   Get the first free buffer in the netb pool. All the tasks can call this
94
   function, so a kern_cli is needed
95
*/
96
void *netbuff_get(struct netbuff *netb, BYTE to)
97
{
98
        int i, done;
99
        static int mycount = 0;
100
 
101
        if (sem_xwait(&(netb->buffersem), 1, to) != 0) {
102
                return NULL;
103
        } else {
104
                mycount++;
105
        }
106
 
107
        done = 0; i = 0;
108
        kern_cli();
109
        while ((i < netb->nbuffs) && !done) {
110
                if (netb->free[i]) {
111
                        done = 1;
112
                        netb->free[i] = 0;
113
                } else i++;
114
        }
115
        kern_sti();
116
        if (!done) {
117
                kern_raise(XNETBUFF_GET_EXC,exec_shadow);
118
        }
119
        return netb->pb[i];
120
}
121
 
122
/*
123
   Get the first free buffer in the netb pool. This function can be called
124
   only if netb is private of the process that wants to get the buffer, so
125
   kern_cli is not needed
126
*/
127
void *netbuff_sequentialget(struct netbuff *netb, BYTE to)
128
{
129
        int i, done;
130
 
131
        if (!sem_xwait(&(netb->buffersem), 1, to)) {
132
                return NULL;
133
        }
134
 
135
        done = 0; i = 0;
136
        while ((i < netb->nbuffs) && !done) {
137
                if (netb->free[i]) {
138
                        done = 1;
139
                        netb->free[i] = 0;
140
                } else i++;
141
        }
142
        if (!done) {
143
                kern_raise(XNETBUFF_GET_EXC,exec_shadow);
144
        }
145
        return netb->pb[i];
146
}
147
 
148
/* Release the buffer m of the pool netb */
149
void netbuff_release(struct netbuff *netb, void *m)
150
{
151
        int i, done;
152
 
153
        done = 0; i = 0;
154
        while ((i < netb->nbuffs) && !done) {
155
                if (netb->pb[i] == m) {
156
                        if (netb->free[i] == 1) {
157
                                cprintf("Trying to free a free buffer :( \n");
158
                                kern_raise(XNETBUFF_ALREADYFREE_EXC,exec_shadow);
159
                        }
160
                        done = 1;
161
                        netb->free[i] = 1;
162
                } else i++;
163
        }
164
        if (!done) {
165
                cprintf("Trying to free a STRANGE buffer :( \n");
166
                kern_raise(XNETBUFF_RELEASE_EXC,exec_shadow);
167
        }
168
        sem_post(&(netb->buffersem));
169
}