OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [char/] [ftape/] [zftape/] [zftape-init.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *      Copyright (C) 1996, 1997 Claus-Justus Heine.
3
 
4
 This program is free software; you can redistribute it and/or modify
5
 it under the terms of the GNU General Public License as published by
6
 the Free Software Foundation; either version 2, or (at your option)
7
 any later version.
8
 
9
 This program is distributed in the hope that it will be useful,
10
 but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 GNU General Public License for more details.
13
 
14
 You should have received a copy of the GNU General Public License
15
 along with this program; see the file COPYING.  If not, write to
16
 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
17
 
18
 *
19
 *      This file contains the code that registers the zftape frontend
20
 *      to the ftape floppy tape driver for Linux
21
 */
22
 
23
#include <linux/config.h>
24
#include <linux/module.h>
25
#include <linux/errno.h>
26
#include <linux/version.h>
27
#include <linux/fs.h>
28
#include <asm/segment.h>
29
#include <linux/kernel.h>
30
#include <linux/signal.h>
31
#include <linux/major.h>
32
#include <linux/slab.h>
33
#ifdef CONFIG_KMOD
34
#include <linux/kmod.h>
35
#endif
36
#include <linux/fcntl.h>
37
#include <linux/wrapper.h>
38
#include <linux/smp_lock.h>
39
#include <linux/devfs_fs_kernel.h>
40
 
41
#include <linux/zftape.h>
42
#include <linux/init.h>
43
 
44
#include "../zftape/zftape-init.h"
45
#include "../zftape/zftape-read.h"
46
#include "../zftape/zftape-write.h"
47
#include "../zftape/zftape-ctl.h"
48
#include "../zftape/zftape-buffers.h"
49
#include "../zftape/zftape_syms.h"
50
 
51
char zft_src[] __initdata = "$Source: /home/marcus/revision_ctrl_test/oc_cvs/cvs/or1k/linux/linux-2.4/drivers/char/ftape/zftape/zftape-init.c,v $";
52
char zft_rev[] __initdata = "$Revision: 1.1.1.1 $";
53
char zft_dat[] __initdata = "$Date: 2004-04-15 02:02:27 $";
54
 
55
MODULE_AUTHOR("(c) 1996, 1997 Claus-Justus Heine "
56
              "(claus@momo.math.rwth-aachen.de)");
57
MODULE_DESCRIPTION(ZFTAPE_VERSION " - "
58
                   "VFS interface for the Linux floppy tape driver. "
59
                   "Support for QIC-113 compatible volume table "
60
                   "and builtin compression (lzrw3 algorithm)");
61
MODULE_SUPPORTED_DEVICE("char-major-27");
62
MODULE_LICENSE("GPL");
63
 
64
/*      Global vars.
65
 */
66
struct zft_cmpr_ops *zft_cmpr_ops = NULL;
67
const ftape_info *zft_status;
68
 
69
/*      Local vars.
70
 */
71
static int busy_flag = 0;
72
static sigset_t orig_sigmask;
73
 
74
/*  the interface to the kernel vfs layer
75
 */
76
 
77
/* Note about llseek():
78
 *
79
 * st.c and tpqic.c update fp->f_pos but don't implment llseek() and
80
 * initialize the llseek component of the file_ops struct with NULL.
81
 * This means that the user will get the default seek, but the tape
82
 * device will not respect the new position, but happily read from the
83
 * old position. Think a zftape specific llseek() function would be
84
 * better, returning -ESPIPE. TODO.
85
 */
86
 
87
static int  zft_open (struct inode *ino, struct file *filep);
88
static int zft_close(struct inode *ino, struct file *filep);
89
static int  zft_ioctl(struct inode *ino, struct file *filep,
90
                      unsigned int command, unsigned long arg);
91
static int  zft_mmap(struct file *filep, struct vm_area_struct *vma);
92
static ssize_t zft_read (struct file *fp, char *buff,
93
                         size_t req_len, loff_t *ppos);
94
static ssize_t zft_write(struct file *fp, const char *buff,
95
                         size_t req_len, loff_t *ppos);
96
 
97
static struct file_operations zft_cdev =
98
{
99
        owner:          THIS_MODULE,
100
        read:           zft_read,
101
        write:          zft_write,
102
        ioctl:          zft_ioctl,
103
        mmap:           zft_mmap,
104
        open:           zft_open,
105
        release:        zft_close,
106
};
107
 
108
/*      Open floppy tape device
109
 */
110
static int zft_open(struct inode *ino, struct file *filep)
111
{
112
        int result;
113
        TRACE_FUN(ft_t_flow);
114
 
115
        TRACE(ft_t_flow, "called for minor %d", MINOR(ino->i_rdev));
116
        if (busy_flag) {
117
                TRACE_ABORT(-EBUSY, ft_t_warn, "failed: already busy");
118
        }
119
        busy_flag = 1;
120
        if ((MINOR(ino->i_rdev) & ~(ZFT_MINOR_OP_MASK | FTAPE_NO_REWIND))
121
             >
122
            FTAPE_SEL_D) {
123
                busy_flag = 0;
124
                TRACE_ABORT(-ENXIO, ft_t_err, "failed: illegal unit nr");
125
        }
126
        orig_sigmask = current->blocked;
127
        sigfillset(&current->blocked);
128
        result = _zft_open(MINOR(ino->i_rdev), filep->f_flags & O_ACCMODE);
129
        if (result < 0) {
130
                current->blocked = orig_sigmask; /* restore mask */
131
                busy_flag = 0;
132
                TRACE_ABORT(result, ft_t_err, "_ftape_open failed");
133
        } else {
134
                /* Mask signals that will disturb proper operation of the
135
                 * program that is calling.
136
                 */
137
                current->blocked = orig_sigmask;
138
                sigaddsetmask (&current->blocked, _DO_BLOCK);
139
                TRACE_EXIT 0;
140
        }
141
}
142
 
143
/*      Close floppy tape device
144
 */
145
static int zft_close(struct inode *ino, struct file *filep)
146
{
147
        int result;
148
        TRACE_FUN(ft_t_flow);
149
 
150
        lock_kernel();
151
        if (!busy_flag || MINOR(ino->i_rdev) != zft_unit) {
152
                TRACE(ft_t_err, "failed: not busy or wrong unit");
153
                unlock_kernel();
154
                TRACE_EXIT 0;
155
        }
156
        sigfillset(&current->blocked);
157
        result = _zft_close();
158
        if (result < 0) {
159
                TRACE(ft_t_err, "_zft_close failed");
160
        }
161
        current->blocked = orig_sigmask; /* restore before open state */
162
        busy_flag = 0;
163
        unlock_kernel();
164
        TRACE_EXIT 0;
165
}
166
 
167
/*      Ioctl for floppy tape device
168
 */
169
static int zft_ioctl(struct inode *ino, struct file *filep,
170
                     unsigned int command, unsigned long arg)
171
{
172
        int result = -EIO;
173
        sigset_t old_sigmask;
174
        TRACE_FUN(ft_t_flow);
175
 
176
        if (!busy_flag || MINOR(ino->i_rdev) != zft_unit || ft_failure) {
177
                TRACE_ABORT(-EIO, ft_t_err,
178
                            "failed: not busy, failure or wrong unit");
179
        }
180
        old_sigmask = current->blocked; /* save mask */
181
        sigfillset(&current->blocked);
182
        /* This will work as long as sizeof(void *) == sizeof(long) */
183
        result = _zft_ioctl(command, (void *) arg);
184
        current->blocked = old_sigmask; /* restore mask */
185
        TRACE_EXIT result;
186
}
187
 
188
/*      Ioctl for floppy tape device
189
 */
190
static int  zft_mmap(struct file *filep, struct vm_area_struct *vma)
191
{
192
        int result = -EIO;
193
        sigset_t old_sigmask;
194
        TRACE_FUN(ft_t_flow);
195
 
196
        if (!busy_flag ||
197
            MINOR(filep->f_dentry->d_inode->i_rdev) != zft_unit ||
198
            ft_failure)
199
        {
200
                TRACE_ABORT(-EIO, ft_t_err,
201
                            "failed: not busy, failure or wrong unit");
202
        }
203
        old_sigmask = current->blocked; /* save mask */
204
        sigfillset(&current->blocked);
205
        lock_kernel();
206
        if ((result = ftape_mmap(vma)) >= 0) {
207
#ifndef MSYNC_BUG_WAS_FIXED
208
                static struct vm_operations_struct dummy = { NULL, };
209
                vma->vm_ops = &dummy;
210
#endif
211
        }
212
        unlock_kernel();
213
        current->blocked = old_sigmask; /* restore mask */
214
        TRACE_EXIT result;
215
}
216
 
217
/*      Read from floppy tape device
218
 */
219
static ssize_t zft_read(struct file *fp, char *buff,
220
                        size_t req_len, loff_t *ppos)
221
{
222
        int result = -EIO;
223
        sigset_t old_sigmask;
224
        struct inode *ino = fp->f_dentry->d_inode;
225
        TRACE_FUN(ft_t_flow);
226
 
227
        TRACE(ft_t_data_flow, "called with count: %ld", (unsigned long)req_len);
228
        if (!busy_flag || MINOR(ino->i_rdev) != zft_unit || ft_failure) {
229
                TRACE_ABORT(-EIO, ft_t_err,
230
                            "failed: not busy, failure or wrong unit");
231
        }
232
        old_sigmask = current->blocked; /* save mask */
233
        sigfillset(&current->blocked);
234
        result = _zft_read(buff, req_len);
235
        current->blocked = old_sigmask; /* restore mask */
236
        TRACE(ft_t_data_flow, "return with count: %d", result);
237
        TRACE_EXIT result;
238
}
239
 
240
/*      Write to tape device
241
 */
242
static ssize_t zft_write(struct file *fp, const char *buff,
243
                         size_t req_len, loff_t *ppos)
244
{
245
        int result = -EIO;
246
        sigset_t old_sigmask;
247
        struct inode *ino = fp->f_dentry->d_inode;
248
        TRACE_FUN(ft_t_flow);
249
 
250
        TRACE(ft_t_flow, "called with count: %ld", (unsigned long)req_len);
251
        if (!busy_flag || MINOR(ino->i_rdev) != zft_unit || ft_failure) {
252
                TRACE_ABORT(-EIO, ft_t_err,
253
                            "failed: not busy, failure or wrong unit");
254
        }
255
        old_sigmask = current->blocked; /* save mask */
256
        sigfillset(&current->blocked);
257
        result = _zft_write(buff, req_len);
258
        current->blocked = old_sigmask; /* restore mask */
259
        TRACE(ft_t_data_flow, "return with count: %d", result);
260
        TRACE_EXIT result;
261
}
262
 
263
/*                    END OF VFS INTERFACE
264
 *
265
 *****************************************************************************/
266
 
267
/*  driver/module initialization
268
 */
269
 
270
/*  the compression module has to call this function to hook into the zftape
271
 *  code
272
 */
273
int zft_cmpr_register(struct zft_cmpr_ops *new_ops)
274
{
275
        TRACE_FUN(ft_t_flow);
276
 
277
        if (zft_cmpr_ops != NULL) {
278
                TRACE_EXIT -EBUSY;
279
        } else {
280
                zft_cmpr_ops = new_ops;
281
                TRACE_EXIT 0;
282
        }
283
}
284
 
285
struct zft_cmpr_ops *zft_cmpr_unregister(void)
286
{
287
        struct zft_cmpr_ops *old_ops = zft_cmpr_ops;
288
        TRACE_FUN(ft_t_flow);
289
 
290
        zft_cmpr_ops = NULL;
291
        TRACE_EXIT old_ops;
292
}
293
 
294
/*  lock the zft-compressor() module.
295
 */
296
int zft_cmpr_lock(int try_to_load)
297
{
298
        if (zft_cmpr_ops == NULL) {
299
#ifdef CONFIG_KMOD
300
                if (try_to_load) {
301
                        request_module("zft-compressor");
302
                        if (zft_cmpr_ops == NULL) {
303
                                return -ENOSYS;
304
                        }
305
                } else {
306
                        return -ENOSYS;
307
                }
308
#else
309
                return -ENOSYS;
310
#endif
311
        }
312
        (*zft_cmpr_ops->lock)();
313
        return 0;
314
}
315
 
316
#ifdef CONFIG_ZFT_COMPRESSOR
317
extern int zft_compressor_init(void);
318
#endif
319
 
320
/*  Called by modules package when installing the driver or by kernel
321
 *  during the initialization phase
322
 */
323
int __init zft_init(void)
324
{
325
        int i;
326
        TRACE_FUN(ft_t_flow);
327
 
328
#ifdef MODULE
329
        printk(KERN_INFO ZFTAPE_VERSION "\n");
330
        if (TRACE_LEVEL >= ft_t_info) {
331
                printk(
332
KERN_INFO
333
"(c) 1996, 1997 Claus-Justus Heine (claus@momo.math.rwth-aachen.de)\n"
334
KERN_INFO
335
"vfs interface for ftape floppy tape driver.\n"
336
KERN_INFO
337
"Support for QIC-113 compatible volume table, dynamic memory allocation\n"
338
KERN_INFO
339
"and builtin compression (lzrw3 algorithm).\n"
340
KERN_INFO
341
"Compiled for Linux version %s"
342
#ifdef MODVERSIONS
343
                       " with versioned symbols"
344
#endif
345
                       "\n", UTS_RELEASE);
346
        }
347
#else /* !MODULE */
348
        /* print a short no-nonsense boot message */
349
        printk(KERN_INFO ZFTAPE_VERSION " for Linux " UTS_RELEASE "\n");
350
#endif /* MODULE */
351
        TRACE(ft_t_info, "zft_init @ 0x%p", zft_init);
352
        TRACE(ft_t_info,
353
              "installing zftape VFS interface for ftape driver ...");
354
        TRACE_CATCH(devfs_register_chrdev(QIC117_TAPE_MAJOR, "zft", &zft_cdev),);
355
 
356
        for (i = 0; i < 4; i++) {
357
                char devname[9];
358
 
359
                sprintf (devname, "qft%i", i);
360
                devfs_register (NULL, devname, DEVFS_FL_DEFAULT,
361
                                QIC117_TAPE_MAJOR, i,
362
                                S_IFCHR | S_IRUSR | S_IWUSR,
363
                                &zft_cdev, NULL);
364
                sprintf (devname, "nqft%i", i);
365
                devfs_register (NULL, devname, DEVFS_FL_DEFAULT,
366
                                QIC117_TAPE_MAJOR, i + 4,
367
                                S_IFCHR | S_IRUSR | S_IWUSR,
368
                                &zft_cdev, NULL);
369
                sprintf (devname, "zqft%i", i);
370
                devfs_register (NULL, devname, DEVFS_FL_DEFAULT,
371
                                QIC117_TAPE_MAJOR, i + 16,
372
                                S_IFCHR | S_IRUSR | S_IWUSR,
373
                                &zft_cdev, NULL);
374
                sprintf (devname, "nzqft%i", i);
375
                devfs_register (NULL, devname, DEVFS_FL_DEFAULT,
376
                                QIC117_TAPE_MAJOR, i + 20,
377
                                S_IFCHR | S_IRUSR | S_IWUSR,
378
                                &zft_cdev, NULL);
379
                sprintf (devname, "rawqft%i", i);
380
                devfs_register (NULL, devname, DEVFS_FL_DEFAULT,
381
                                QIC117_TAPE_MAJOR, i + 32,
382
                                S_IFCHR | S_IRUSR | S_IWUSR,
383
                                &zft_cdev, NULL);
384
                sprintf (devname, "nrawqft%i", i);
385
                devfs_register (NULL, devname, DEVFS_FL_DEFAULT,
386
                                QIC117_TAPE_MAJOR, i + 36,
387
                                S_IFCHR | S_IRUSR | S_IWUSR,
388
                                &zft_cdev, NULL);
389
        }
390
 
391
#ifdef CONFIG_ZFT_COMPRESSOR
392
        (void)zft_compressor_init();
393
#endif
394
        zft_status = ftape_get_status(); /*  fetch global data of ftape
395
                                          *  hardware driver
396
                                          */
397
        TRACE_EXIT 0;
398
}
399
 
400
 
401
#ifdef MODULE
402
/* Called by modules package before trying to unload the module
403
 */
404
static int can_unload(void)
405
{
406
        return (GET_USE_COUNT(THIS_MODULE)||zft_dirty()||busy_flag)?-EBUSY:0;
407
}
408
/* Called by modules package when installing the driver
409
 */
410
int init_module(void)
411
{
412
        if (!mod_member_present(&__this_module, can_unload)) {
413
                return -EBUSY;
414
        }
415
        __this_module.can_unload = can_unload;
416
        return zft_init();
417
}
418
 
419
/* Called by modules package when removing the driver
420
 */
421
void cleanup_module(void)
422
{
423
        int i;
424
        char devname[9];
425
 
426
        TRACE_FUN(ft_t_flow);
427
 
428
        if (devfs_unregister_chrdev(QIC117_TAPE_MAJOR, "zft") != 0) {
429
                TRACE(ft_t_warn, "failed");
430
        } else {
431
                TRACE(ft_t_info, "successful");
432
        }
433
        for (i = 0; i < 4; i++) {
434
                sprintf(devname, "qft%i", i);
435
                devfs_unregister(devfs_find_handle(NULL, devname, QIC117_TAPE_MAJOR, i, DEVFS_SPECIAL_CHR, 0));
436
                sprintf(devname, "nqft%i", i);
437
                devfs_unregister(devfs_find_handle(NULL, devname, QIC117_TAPE_MAJOR, i + 4, DEVFS_SPECIAL_CHR, 0));
438
                sprintf(devname, "zqft%i", i);
439
                devfs_unregister(devfs_find_handle(NULL, devname, QIC117_TAPE_MAJOR, i + 16, DEVFS_SPECIAL_CHR, 0));
440
                sprintf(devname, "nzqft%i", i);
441
                devfs_unregister(devfs_find_handle(NULL, devname, QIC117_TAPE_MAJOR, i + 20, DEVFS_SPECIAL_CHR, 0));
442
                sprintf(devname, "rawqft%i", i);
443
                devfs_unregister(devfs_find_handle(NULL, devname, QIC117_TAPE_MAJOR, i + 32, DEVFS_SPECIAL_CHR, 0));
444
                sprintf(devname, "nrawqft%i", i);
445
                devfs_unregister(devfs_find_handle(NULL, devname, QIC117_TAPE_MAJOR, i + 36, DEVFS_SPECIAL_CHR, 0));
446
        }
447
        zft_uninit_mem(); /* release remaining memory, if any */
448
        printk(KERN_INFO "zftape successfully unloaded.\n");
449
        TRACE_EXIT;
450
}
451
 
452
#endif /* MODULE */

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.