This source file includes following definitions.
- __get_order
- dmaalloc
- dmafree
- ftape_init
- cleanup_module
- ftape_open
- ftape_close
- ftape_ioctl
- ftape_read
- ftape_write
- ftape_lseek
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 #include <linux/module.h>
24 #include <linux/version.h>
25 #include <linux/errno.h>
26 #include <linux/fs.h>
27 #include <asm/segment.h>
28 #include <linux/kernel.h>
29 #include <linux/signal.h>
30 #include <linux/major.h>
31 #include <linux/malloc.h>
32 #include <linux/ftape.h>
33 #include <asm/dma.h>
34
35 #include "tracing.h"
36 #include "kernel-interface.h"
37 #include "ftape-read.h"
38 #include "ftape-write.h"
39 #include "ftape-io.h"
40 #include "ftape-ctl.h"
41 #include "ftape-rw.h"
42 #include "fdc-io.h"
43
44
45
46
47
48
49
50
51
52
53 byte *tape_buffer[NR_BUFFERS] =
54 {NULL};
55
56 #ifdef MODULE
57 char kernel_version[] = UTS_RELEASE;
58 #endif
59
60
61
62 static int busy_flag = 0;
63 static int old_sigmask;
64
65 static int ftape_open(struct inode *ino, struct file *filep);
66 static void ftape_close(struct inode *ino, struct file *filep);
67 static int ftape_ioctl(struct inode *ino, struct file *filep,
68 unsigned int command, unsigned long arg);
69 static int ftape_read(struct inode *ino, struct file *fp, char *buff,
70 int req_len);
71 static int ftape_write(struct inode *ino, struct file *fp, const char *buff,
72 int req_len);
73 static int ftape_lseek(struct inode *ino, struct file *filep,
74 off_t offset, int origin);
75 #if 0
76 static int ftape_select(void);
77 static int ftape_mmap(int dev, unsigned off, int prot);
78 #else
79 #define ftape_select NULL
80 #define ftape_mmap NULL
81 #endif
82
83 static struct file_operations ftape_cdev =
84 {
85 ftape_lseek,
86 ftape_read,
87 ftape_write,
88 NULL,
89 ftape_select,
90 ftape_ioctl,
91 ftape_mmap,
92 ftape_open,
93 ftape_close,
94 NULL,
95 };
96
97
98
99
100
101 static inline
102 int __get_order(int size)
103 {
104 int order;
105
106 for (order = 0; order < NR_MEM_LISTS; ++order)
107 if (size <= (PAGE_SIZE << order))
108 return order;
109 return -1;
110 }
111
112 static inline
113 void *dmaalloc(int order)
114 {
115 return (void *) __get_dma_pages(GFP_KERNEL, order);
116 }
117
118 static inline
119 void dmafree(void *addr, int order)
120 {
121 free_pages((unsigned long) addr, order);
122 }
123
124
125
126
127
128
129 #ifdef MODULE
130 #define ftape_init init_module
131 #endif
132
133 int ftape_init(void)
134 {
135 int n;
136 int order;
137 TRACE_FUN(5, "init_module");
138 #ifdef MODULE
139 printk(KERN_INFO "ftape-2.07 960304\n"
140 KERN_INFO " (c) 1993-1995 Bas Laarhoven (bas@vimec.nl)\n"
141 KERN_INFO " (c) 1995-1996 Kai Harrekilde-Petersen (khp@pip.dknet.dk)\n"
142 KERN_INFO " QIC-117 driver for QIC-40/80/3010/3020 tape drives\n"
143 KERN_INFO " Compiled for kernel version %s"
144 #ifdef MODVERSIONS
145 " with versioned symbols"
146 #endif
147 "\n", kernel_version);
148 #else
149
150 printk("ftape-2.07 960304 for Linux 1.3.70\n");
151 #endif
152 TRACE(3, "installing QIC-117 ftape driver...");
153 if (register_chrdev(QIC117_TAPE_MAJOR, "ftape", &ftape_cdev)) {
154 TRACE(1, "register_chrdev failed");
155 TRACE_EXIT;
156 return -EIO;
157 }
158 TRACEx1(3, "init_module @ 0x%p", init_module);
159
160
161
162 order = __get_order(BUFF_SIZE);
163 if (order < 0) {
164 TRACE(1, "__get_order failed (no memory?)");
165 if (unregister_chrdev(QIC117_TAPE_MAJOR, "ftape") != 0) {
166 TRACE(3, "unregister_chrdev failed");
167 }
168 return -ENOMEM;
169 }
170 for (n = 0; n < NR_BUFFERS; n++) {
171 tape_buffer[n] = (byte *) dmaalloc(order);
172 if (!tape_buffer[n]) {
173 TRACE(1, "dmaalloc() failed");
174 for (n = 0; n < NR_BUFFERS; n++) {
175 if (tape_buffer[n]) {
176 dmafree(tape_buffer[n], order);
177 tape_buffer[n] = NULL;
178 }
179 }
180 current->blocked = old_sigmask;
181 if (unregister_chrdev(QIC117_TAPE_MAJOR, "ftape") != 0) {
182 TRACE(3, "unregister_chrdev failed");
183 }
184 TRACE_EXIT;
185 return -ENOMEM;
186 } else {
187 TRACEx2(3, "dma-buffer #%d @ %p", n, tape_buffer[n]);
188 }
189 }
190 busy_flag = 0;
191 ftape_unit = -1;
192 ftape_failure = 1;
193 udelay_calibrate();
194 fdc_wait_calibrate();
195 TRACE_EXIT;
196 #ifdef MODULE
197 register_symtab(0);
198 #endif
199 return 0;
200 }
201
202
203 #ifdef MODULE
204
205
206 void cleanup_module(void)
207 {
208 int n;
209 int order;
210 TRACE_FUN(5, "cleanup_module");
211
212 if (unregister_chrdev(QIC117_TAPE_MAJOR, "ftape") != 0) {
213 TRACE(3, "failed");
214 } else {
215 TRACE(3, "successful");
216 }
217 order = __get_order(BUFF_SIZE);
218 if (order < 0) {
219 TRACE(1, "__get_order failed (but why?!)");
220 } else {
221 for (n = 0; n < NR_BUFFERS; n++) {
222 if (tape_buffer[n]) {
223 dmafree(tape_buffer[n], order);
224 tape_buffer[n] = NULL;
225 TRACEx1(3, "removed dma-buffer #%d", n);
226 } else {
227 TRACEx1(1, "dma-buffer #%d == NULL (bug?)", n);
228 }
229 }
230 }
231 TRACE_EXIT;
232 }
233 #endif
234
235
236
237 static int ftape_open(struct inode *ino, struct file *filep)
238 {
239 TRACE_FUN(4, "ftape_open");
240 int result;
241 MOD_INC_USE_COUNT;
242
243 TRACEi(5, "called for minor", MINOR(ino->i_rdev));
244 if (busy_flag) {
245 TRACE(1, "failed: already busy");
246 MOD_DEC_USE_COUNT;
247 TRACE_EXIT;
248 return -EBUSY;
249 }
250 if ((MINOR(ino->i_rdev) & ~FTAPE_NO_REWIND) > 3) {
251 TRACE(1, "failed: illegal unit nr");
252 MOD_DEC_USE_COUNT;
253 TRACE_EXIT;
254 return -ENXIO;
255 }
256 if (ftape_unit == -1 || FTAPE_UNIT != (MINOR(ino->i_rdev) & 3)) {
257
258
259 ftape_init_driver();
260 }
261 ftape_unit = MINOR(ino->i_rdev);
262 ftape_failure = 0;
263 old_sigmask = current->blocked;
264 current->blocked = _BLOCK_ALL;
265 fdc_save_drive_specs();
266 result = _ftape_open();
267 if (result < 0) {
268 TRACE(1, "_ftape_open failed");
269 current->blocked = old_sigmask;
270 MOD_DEC_USE_COUNT;
271 TRACE_EXIT;
272 return result;
273 } else {
274 busy_flag = 1;
275
276
277
278 current->blocked = old_sigmask | _DO_BLOCK;
279 TRACE_EXIT;
280 return 0;
281 }
282 }
283
284
285
286 static void ftape_close(struct inode *ino, struct file *filep)
287 {
288 TRACE_FUN(4, "ftape_close");
289 int result;
290
291 if (!busy_flag || MINOR(ino->i_rdev) != ftape_unit) {
292 TRACE(1, "failed: not busy or wrong unit");
293 TRACE_EXIT;
294 return;
295 }
296 current->blocked = _BLOCK_ALL;
297 result = _ftape_close();
298 if (result < 0) {
299 TRACE(1, "_ftape_close failed");
300 }
301 fdc_restore_drive_specs();
302 ftape_failure = 1;
303 busy_flag = 0;
304 current->blocked = old_sigmask;
305 TRACE_EXIT;
306 MOD_DEC_USE_COUNT;
307 }
308
309
310
311 static int ftape_ioctl(struct inode *ino, struct file *filep,
312 unsigned int command, unsigned long arg)
313 {
314 TRACE_FUN(4, "ftape_ioctl");
315 int result = -EIO;
316 int old_sigmask;
317
318 if (!busy_flag || MINOR(ino->i_rdev) != ftape_unit || ftape_failure) {
319 TRACE(1, "failed: not busy, failure or wrong unit");
320 TRACE_EXIT;
321 return -EIO;
322 }
323 old_sigmask = current->blocked;
324 current->blocked = _BLOCK_ALL;
325
326
327 result = _ftape_ioctl(command, (void *) arg);
328 current->blocked = old_sigmask;
329 TRACE_EXIT;
330 return result;
331 }
332
333
334
335 static int ftape_read(struct inode *ino, struct file *fp, char *buff, int req_len)
336 {
337 TRACE_FUN(5, "ftape_read");
338 int result = -EIO;
339 int old_sigmask;
340
341 TRACEi(5, "called with count:", req_len);
342 if (!busy_flag || MINOR(ino->i_rdev) != ftape_unit || ftape_failure) {
343 TRACE(1, "failed: not busy, failure or wrong unit");
344 TRACE_EXIT;
345 return -EIO;
346 }
347 old_sigmask = current->blocked;
348 current->blocked = _BLOCK_ALL;
349 result = _ftape_read(buff, req_len);
350 TRACEi(7, "return with count:", result);
351 current->blocked = old_sigmask;
352 TRACE_EXIT;
353 return result;
354 }
355
356
357
358 static int ftape_write(struct inode *ino, struct file *fp, const char *buff, int req_len)
359 {
360 TRACE_FUN(8, "ftape_write");
361 int result = -EIO;
362 int old_sigmask;
363
364 TRACEi(5, "called with count:", req_len);
365 if (!busy_flag || MINOR(ino->i_rdev) != ftape_unit || ftape_failure) {
366 TRACE(1, "failed: not busy, failure or wrong unit");
367 TRACE_EXIT;
368 return -EIO;
369 }
370 old_sigmask = current->blocked;
371 current->blocked = _BLOCK_ALL;
372 result = _ftape_write(buff, req_len);
373 TRACEi(7, "return with count:", result);
374 current->blocked = old_sigmask;
375 TRACE_EXIT;
376 return result;
377 }
378
379
380
381 static int ftape_lseek(struct inode *ino, struct file *filep, off_t offset, int origin)
382 {
383 return -ESPIPE;
384 }