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