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