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, struct buffer_head * bh)
247 {
248 unsigned int major;
249
250 if (!bh)
251 return;
252 if (bh->b_size != 1024) {
253 printk("ll_rw_block: only 1024-char blocks implemented (%d)\n",bh->b_size);
254 bh->b_dirt = bh->b_uptodate = 0;
255 return;
256 }
257 if ((major=MAJOR(bh->b_dev)) >= NR_BLK_DEV ||
258 !(blk_dev[major].request_fn)) {
259 printk("ll_rw_block: Trying to read nonexistent block-device %04x (%d)\n",bh->b_dev,bh->b_blocknr);
260 bh->b_dirt = bh->b_uptodate = 0;
261 return;
262 }
263 if ((rw == WRITE || rw == WRITEA) && is_read_only(bh->b_dev)) {
264 printk("Can't write to read-only device 0x%X\n\r",bh->b_dev);
265 bh->b_dirt = bh->b_uptodate = 0;
266 return;
267 }
268 make_request(major,rw,bh);
269 }
270
271 void ll_rw_swap_file(int rw, int dev, unsigned int *b, int nb, char *buf)
272 {
273 int i;
274 struct request * req;
275 unsigned int major = MAJOR(dev);
276
277 if (major >= NR_BLK_DEV || !(blk_dev[major].request_fn)) {
278 printk("ll_rw_swap_file: trying to swap nonexistent block-device\n\r");
279 return;
280 }
281
282 if (rw!=READ && rw!=WRITE) {
283 printk("ll_rw_swap: bad block dev command, must be R/W");
284 return;
285 }
286 if (rw == WRITE && is_read_only(dev)) {
287 printk("Can't swap to read-only device 0x%X\n\r",dev);
288 return;
289 }
290
291 for (i=0; i<nb; i++, buf += BLOCK_SIZE)
292 {
293 repeat:
294 req = request+NR_REQUEST;
295 while (--req >= request)
296 if (req->dev<0)
297 break;
298 if (req < request) {
299 sleep_on(&wait_for_request);
300 goto repeat;
301 }
302
303 req->dev = dev;
304 req->cmd = rw;
305 req->errors = 0;
306 req->sector = b[i] << 1;
307 req->nr_sectors = 2;
308 req->current_nr_sectors = 2;
309 req->buffer = buf;
310 req->waiting = current;
311 req->bh = NULL;
312 req->next = NULL;
313 current->state = TASK_UNINTERRUPTIBLE;
314 add_request(major+blk_dev,req);
315 schedule();
316 }
317 }
318
319 long blk_dev_init(long mem_start, long mem_end)
320 {
321 int i;
322
323 for (i=0 ; i<NR_REQUEST ; i++) {
324 request[i].dev = -1;
325 request[i].next = NULL;
326 }
327 memset(ro_bits,0,sizeof(ro_bits));
328 #ifdef CONFIG_BLK_DEV_HD
329 mem_start = hd_init(mem_start,mem_end);
330 #endif
331 #ifdef RAMDISK
332 mem_start += rd_init(mem_start, RAMDISK*1024);
333 #endif
334 return mem_start;
335 }