Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 pj 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
 
24
  CVS :        $Id: idereq.c,v 1.1.1.1 2002-03-29 14:12:49 pj Exp $
25
 
26
  Revision:    $Revision: 1.1.1.1 $
27
 
28
  Last update: $Date: 2002-03-29 14:12:49 $
29
 
30
  This module manage the ide request structure: it is implemented
31
  a policy for the queueing of the requests made by tasks.
32
 
33
***************************************/
34
 
35
/*
36
 * Copyright (C) 1999 Massimiliano Giorgi
37
 *
38
 * This program is free software; you can redistribute it and/or modify
39
 * it under the terms of the GNU General Public License as published by
40
 * the Free Software Foundation; either version 2 of the License, or
41
 * (at your option) any later version.
42
 *
43
 * This program is distributed in the hope that it will be useful,
44
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
45
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
46
 * GNU General Public License for more details.
47
 *
48
 * You should have received a copy of the GNU General Public License
49
 * along with this program; if not, write to the Free Software
50
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
51
 *
52
 */
53
 
54
#include <fs/assert.h>
55
 
56
#include "glue.h"
57
 
58
#include "ide.h"
59
#include "idereq.h"
60
 
61
/*
62
 * if defined:
63
 * use trc_logevent with event TRC_USER0 to trace head movement
64
 */  
65
#define TRACEMOVEMENT
66
#undef  TRACEMOVEMENT
67
 
68
#ifdef TRACEMOVEMENT
69
#include <trace/types.h>
70
#include <kernel/trace.h>
71
#endif
72
 
73
/*+ a mutex for the  +*/
74
//static __b_fastmutex_t mutex;
75
 
76
/*+ a mutex for the "free request" queue manipulation +*/
77
static __b_fastmutex_t mutexreq;
78
 
79
/*+ the "free request" queue +*/
80
static int freereq=NIL;
81
 
82
/*+ a pool for the ide request (actually all the ide request structure
83
  are statically allocated)
84
  +*/
85
idereq_t idereq[MAXIDEREQUEST];
86
 
87
/*+ is the queue not blocked? +*/
88
int notblockedqueue[MAXIDEINTERFACES];
89
 
90
/*++++++++++++++++++++++++++++++++++++++
91
 
92
  Initialize this module; must be called prior of other call.
93
 
94
  ++++++++++++++++++++++++++++++++++++++*/
95
 
96
void init_idereq(void)
97
{
98
  int i;
99
  //__b_fastmutex_init(&mutex);
100
  __b_fastmutex_init(&mutexreq);
101
  freereq=0;
102
  for (i=0;i<MAXIDEREQUEST;i++) {
103
    idereq[i].next=((i==MAXIDEREQUEST-1)?NIL:i+1);
104
    __b_sem_init(&idereq[i].wait,0);
105
  }
106
  for (i=0;i<MAXIDEINTERFACES;i++)
107
    notblockedqueue[i]=1;
108
}
109
 
110
/*++++++++++++++++++++++++++++++++++++++
111
 
112
  Find and return an ide request structure from the free queue if possible.
113
 
114
  int get_idereq
115
    return an index into idereq[] or NIL
116
  ++++++++++++++++++++++++++++++++++++++*/
117
 
118
int get_idereq(void)
119
{
120
  int ret;
121
  __b_fastmutex_lock(&mutexreq);
122
  if (freereq==NIL)
123
    ret=NIL;
124
  else {
125
    ret=freereq;
126
    freereq=idereq[ret].next;
127
  }
128
  __b_fastmutex_unlock(&mutexreq);
129
  return ret;
130
}
131
 
132
/*++++++++++++++++++++++++++++++++++++++
133
 
134
  Insert an ide request structure into the free queue.
135
 
136
  int req
137
    index into idereq[] to insert into the free queue
138
  ++++++++++++++++++++++++++++++++++++++*/
139
 
140
void free_idereq(int req)
141
{
142
  __b_fastmutex_lock(&mutexreq);
143
  idereq[req].next=freereq;
144
  freereq=req;
145
  __b_fastmutex_unlock(&mutexreq);
146
}
147
 
148
/*
149
 * The following functions can be modificated to implement other policy
150
 * of queueing of the request made by task.
151
 */
152
 
153
static __inline__ int other_request(int ideif)
154
{
155
  return bqueue_numelements(&ide[ideif].queue[0])+
156
    bqueue_numelements(&ide[ideif].queue[1])?1:0;
157
}
158
 
159
/*++++++++++++++++++++++++++++++++++++++
160
 
161
  Insert an ide request structure into an ide interface struct for
162
  processing a request.
163
  It is inserted into the tail.
164
 
165
  int insert_idereq
166
    return 1 if this is the first request of the queue, 0 if there are
167
    already other requests into the queue; if 1 is returned the calling
168
    thread should wake up the server
169
 
170
  int ideif
171
    interface queue to use (an index into ide[] structure)
172
 
173
  int req
174
    index into idereq[] of the request struct to insert
175
  ++++++++++++++++++++++++++++++++++++++*/
176
 
177
int insert_idereq(int ideif, int drive, int req)
178
{
179
  int ret;
180
  bqueue_insertrequest(&ide[ideif].queue[drive],
181
                       (request_prologue_t *)&idereq[req]
182
                       );
183
 
184
  ret=bqueue_numelements(&ide[ideif].queue[drive]);
185
  if (ret==1)
186
    /* means: wake up the server if the queue is not blocked */    
187
    ret=notblockedqueue[ideif];
188
  else
189
    /* means: not wake up the server (it is already running) */
190
    ret=0;
191
 
192
  return ret;
193
}
194
 
195
/*++++++++++++++++++++++++++++++++++++++
196
 
197
  Release a blocked queue.
198
 
199
  int releasequeue_idereq
200
    return 1 if there are request in queue, 0 if not
201
 
202
  int ideif
203
    interface queue to use (an index into ide[] structure)
204
  ++++++++++++++++++++++++++++++++++++++*/
205
 
206
int releasequeue_idereq(int ideif)
207
{
208
  notblockedqueue[ideif]=1;
209
  return other_request(ideif);
210
}
211
 
212
int first_idereq(int ideif)
213
{
214
  request_prologue_t *ptr;
215
 
216
  assertk(ide[ideif].actreq==-1);
217
 
218
  //__b_fastmutex_lock(&mutex);
219
  ptr=bqueue_getrequest(&ide[ideif].queue[0]);
220
 
221
  //cprintf("°%p,%p,%li°",ptr,idereq,((idereq_t*)ptr)-idereq);
222
 
223
  if (ptr==NULL) {
224
    ptr=bqueue_getrequest(&ide[ideif].queue[1]);
225
    if (ptr==NULL) {
226
      //__b_fastmutex_unlock(&mutex);
227
      return NIL;
228
    } else
229
      ide[ideif].actdrv=1;      
230
  } else
231
    ide[ideif].actdrv=0;
232
  ide[ideif].actreq=((idereq_t*)ptr)-idereq;
233
  //__b_fastmutex_unlock(&mutex);
234
 
235
#ifdef TRACEMOVEMENT
236
  {
237
    long cylinder;
238
    cylinder=ptr->cylinder;
239
    trc_logevent(TRC_USER0,&cylinder);
240
  }
241
#endif
242
 
243
  return ide[ideif].actreq;
244
}
245
 
246
int actual_idereq(ideif)
247
{
248
  assertk(ide[ideif].actreq!=-1);
249
  return ide[ideif].actreq;
250
}
251
 
252
/*++++++++++++++++++++++++++++++++++++++
253
 
254
  Remove the first request from the queue of an ide interface.
255
 
256
  int remove_idereq
257
    return 1 if there are other request in queue, 0 if not
258
 
259
  int ideif
260
    interface queue to use (an index into ide[] structure)
261
 
262
  int req
263
    index into idereq[] of the request struct to insert
264
  ++++++++++++++++++++++++++++++++++++++*/
265
 
266
int remove_idereq(int ideif)
267
{
268
  assertk(ide[ideif].actreq!=-1);
269
  bqueue_removerequest(&ide[ideif].queue[ide[ideif].actdrv]);
270
  ide[ideif].actreq=-1;
271
  return other_request(ideif)?1:0;
272
}
273
 
274
/*++++++++++++++++++++++++++++++++++++++
275
 
276
  Remove the first request from the queue of an ide interface
277
  blocking the queue.
278
 
279
  int remove_idereq
280
    return 1 if there are other request in queue, 0 if not
281
 
282
  int ideif
283
    interface queue to use (an index into ide[] structure)
284
 
285
  int req
286
    index into idereq[] of the request struct to insert
287
  ++++++++++++++++++++++++++++++++++++++*/
288
 
289
int remove_idereq_blocking(int ideif)
290
{
291
  assertk(ide[ideif].actreq!=-1);
292
  bqueue_removerequest(&ide[ideif].queue[ide[ideif].actdrv]);
293
  notblockedqueue[ideif]=0;
294
  ide[ideif].actreq=-1;
295
  return other_request(ideif);
296
}