This source file includes following definitions.
- is_read_only
- set_device_ro
- add_request
- make_request
- ll_rw_page
- ll_rw_block
- ll_rw_swap_file
- blk_dev_init
1
2
3
4
5
6
7
8
9
10 #include <linux/sched.h>
11 #include <linux/kernel.h>
12 #include <linux/errno.h>
13 #include <linux/string.h>
14 #include <linux/config.h>
15 #include <linux/locks.h>
16
17 #include <asm/system.h>
18
19 #include "blk.h"
20
21 extern long rd_init(long mem_start, int length);
22
23
24
25
26
27 struct request request[NR_REQUEST];
28
29
30
31
32 struct wait_queue * wait_for_request = NULL;
33
34
35
36
37
38 struct blk_dev_struct blk_dev[NR_BLK_DEV] = {
39 { NULL, NULL },
40 { NULL, NULL },
41 { NULL, NULL },
42 { NULL, NULL },
43 { NULL, NULL },
44 { NULL, NULL },
45 { NULL, NULL },
46 { NULL, NULL },
47 { NULL, NULL },
48 { NULL, NULL }
49 };
50
51
52
53
54
55
56
57
58 int * blk_size[NR_BLK_DEV] = { NULL, NULL, };
59
60
61
62 static long ro_bits[NR_BLK_DEV][8];
63
64 int is_read_only(int dev)
65 {
66 int minor,major;
67
68 major = MAJOR(dev);
69 minor = MINOR(dev);
70 if (major < 0 || major >= NR_BLK_DEV) return 0;
71 return ro_bits[major][minor >> 5] & (1 << (minor & 31));
72 }
73
74 void set_device_ro(int dev,int flag)
75 {
76 int minor,major;
77
78 major = MAJOR(dev);
79 minor = MINOR(dev);
80 if (major < 0 || major >= NR_BLK_DEV) return;
81 if (flag) ro_bits[major][minor >> 5] |= 1 << (minor & 31);
82 else ro_bits[major][minor >> 5] &= ~(1 << (minor & 31));
83 }
84
85
86
87
88
89
90 static void add_request(struct blk_dev_struct * dev, struct request * req)
91 {
92 struct request * tmp;
93
94 req->next = NULL;
95 cli();
96 if (req->bh)
97 req->bh->b_dirt = 0;
98 if (!(tmp = dev->current_request)) {
99 dev->current_request = req;
100 (dev->request_fn)();
101 sti();
102 return;
103 }
104 for ( ; tmp->next ; tmp = tmp->next) {
105 if ((IN_ORDER(tmp,req) ||
106 !IN_ORDER(tmp,tmp->next)) &&
107 IN_ORDER(req,tmp->next))
108 break;
109 }
110 req->next = tmp->next;
111 tmp->next = req;
112 sti();
113 }
114
115 static void make_request(int major,int rw, struct buffer_head * bh)
116 {
117 unsigned int sector, count;
118 struct request * req;
119 int rw_ahead;
120
121
122
123 if (rw_ahead = (rw == READA || rw == WRITEA)) {
124 if (bh->b_lock)
125 return;
126 if (rw == READA)
127 rw = READ;
128 else
129 rw = WRITE;
130 }
131 if (rw!=READ && rw!=WRITE) {
132 printk("Bad block dev command, must be R/W/RA/WA\n");
133 return;
134 }
135 count = bh->b_size >> 9;
136 sector = bh->b_blocknr * count;
137 if (blk_size[major])
138 if (blk_size[major][MINOR(bh->b_dev)] < (sector + count)>>1) {
139 bh->b_dirt = bh->b_uptodate = 0;
140 return;
141 }
142 lock_buffer(bh);
143 if ((rw == WRITE && !bh->b_dirt) || (rw == READ && bh->b_uptodate)) {
144 unlock_buffer(bh);
145 return;
146 }
147 repeat:
148 cli();
149 if ((major == 3 || major == 8 || major == 11)&& (req = blk_dev[major].current_request)) {
150 while (req = req->next) {
151 if (req->dev == bh->b_dev &&
152 !req->waiting &&
153 req->cmd == rw &&
154 req->sector + req->nr_sectors == sector &&
155 req->nr_sectors < 254) {
156 req->bhtail->b_reqnext = bh;
157 req->bhtail = bh;
158 req->nr_sectors += count;
159 bh->b_dirt = 0;
160 sti();
161 return;
162 }
163 }
164 }
165
166
167
168
169 if (rw == READ)
170 req = request+NR_REQUEST;
171 else
172 req = request+(NR_REQUEST/2);
173
174 while (--req >= request)
175 if (req->dev < 0)
176 goto found;
177
178 if (rw_ahead) {
179 sti();
180 unlock_buffer(bh);
181 return;
182 }
183 sleep_on(&wait_for_request);
184 sti();
185 goto repeat;
186
187 found:
188
189 req->dev = bh->b_dev;
190 sti();
191 req->cmd = rw;
192 req->errors = 0;
193 req->sector = sector;
194 req->nr_sectors = count;
195 req->current_nr_sectors = count;
196 req->buffer = bh->b_data;
197 req->waiting = NULL;
198 req->bh = bh;
199 req->bhtail = bh;
200 req->next = NULL;
201 add_request(major+blk_dev,req);
202 }
203
204 void ll_rw_page(int rw, int dev, int page, char * buffer)
205 {
206 struct request * req;
207 unsigned int major = MAJOR(dev);
208
209 if (major >= NR_BLK_DEV || !(blk_dev[major].request_fn)) {
210 printk("Trying to read nonexistent block-device %04x (%d)\n",dev,page*8);
211 return;
212 }
213 if (rw!=READ && rw!=WRITE)
214 panic("Bad block dev command, must be R/W");
215 if (rw == WRITE && is_read_only(dev)) {
216 printk("Can't page to read-only device 0x%X\n\r",dev);
217 return;
218 }
219 cli();
220 repeat:
221 req = request+NR_REQUEST;
222 while (--req >= request)
223 if (req->dev<0)
224 break;
225 if (req < request) {
226 sleep_on(&wait_for_request);
227 goto repeat;
228 }
229 sti();
230
231 req->dev = dev;
232 req->cmd = rw;
233 req->errors = 0;
234 req->sector = page<<3;
235 req->nr_sectors = 8;
236 req->current_nr_sectors = 8;
237 req->buffer = buffer;
238 req->waiting = current;
239 req->bh = NULL;
240 req->next = NULL;
241 current->state = TASK_UNINTERRUPTIBLE;
242 add_request(major+blk_dev,req);
243 schedule();
244 }
245
246 void ll_rw_block(int rw, int nr, struct buffer_head * bh[])
247 {
248 unsigned int major;
249
250 if (nr!=1) panic("ll_rw_block: only one block at a time implemented");
251 if (!bh[0])
252 return;
253 if (bh[0]->b_size != 1024) {
254 printk("ll_rw_block: only 1024-char blocks implemented (%d)\n",bh[0]->b_size);
255 bh[0]->b_dirt = bh[0]->b_uptodate = 0;
256 return;
257 }
258 if ((major=MAJOR(bh[0]->b_dev)) >= NR_BLK_DEV ||
259 !(blk_dev[major].request_fn)) {
260 printk("ll_rw_block: Trying to read nonexistent block-device %04x (%d)\n",bh[0]->b_dev,bh[0]->b_blocknr);
261 bh[0]->b_dirt = bh[0]->b_uptodate = 0;
262 return;
263 }
264 if ((rw == WRITE || rw == WRITEA) && is_read_only(bh[0]->b_dev)) {
265 printk("Can't write to read-only device 0x%X\n\r",bh[0]->b_dev);
266 bh[0]->b_dirt = bh[0]->b_uptodate = 0;
267 return;
268 }
269 make_request(major,rw,bh[0]);
270 }
271
272 void ll_rw_swap_file(int rw, int dev, unsigned int *b, int nb, char *buf)
273 {
274 int i;
275 struct request * req;
276 unsigned int major = MAJOR(dev);
277
278 if (major >= NR_BLK_DEV || !(blk_dev[major].request_fn)) {
279 printk("ll_rw_swap_file: trying to swap nonexistent block-device\n\r");
280 return;
281 }
282
283 if (rw!=READ && rw!=WRITE) {
284 printk("ll_rw_swap: bad block dev command, must be R/W");
285 return;
286 }
287 if (rw == WRITE && is_read_only(dev)) {
288 printk("Can't swap to read-only device 0x%X\n\r",dev);
289 return;
290 }
291
292 for (i=0; i<nb; i++, buf += BLOCK_SIZE)
293 {
294 repeat:
295 req = request+NR_REQUEST;
296 while (--req >= request)
297 if (req->dev<0)
298 break;
299 if (req < request) {
300 sleep_on(&wait_for_request);
301 goto repeat;
302 }
303
304 req->dev = dev;
305 req->cmd = rw;
306 req->errors = 0;
307 req->sector = b[i] << 1;
308 req->nr_sectors = 2;
309 req->current_nr_sectors = 2;
310 req->buffer = buf;
311 req->waiting = current;
312 req->bh = NULL;
313 req->next = NULL;
314 current->state = TASK_UNINTERRUPTIBLE;
315 add_request(major+blk_dev,req);
316 schedule();
317 }
318 }
319
320 long blk_dev_init(long mem_start, long mem_end)
321 {
322 int i;
323
324 for (i=0 ; i<NR_REQUEST ; i++) {
325 request[i].dev = -1;
326 request[i].next = NULL;
327 }
328 memset(ro_bits,0,sizeof(ro_bits));
329 #ifdef CONFIG_BLK_DEV_HD
330 mem_start = hd_init(mem_start,mem_end);
331 #endif
332 #ifdef RAMDISK
333 mem_start += rd_init(mem_start, RAMDISK*1024);
334 #endif
335 return mem_start;
336 }