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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [telephony/] [phonedev.c] - Blame information for rev 1779

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *            Telephony registration for Linux
3
 *
4
 *              (c) Copyright 1999 Red Hat Software Inc.
5
 *
6
 *              This program is free software; you can redistribute it and/or
7
 *              modify it under the terms of the GNU General Public License
8
 *              as published by the Free Software Foundation; either version
9
 *              2 of the License, or (at your option) any later version.
10
 *
11
 * Author:      Alan Cox, <alan@redhat.com>
12
 *
13
 * Fixes:       Mar 01 2000 Thomas Sparr, <thomas.l.sparr@telia.com>
14
 *              phone_register_device now works with unit!=PHONE_UNIT_ANY
15
 */
16
 
17
#include <linux/version.h>
18
#include <linux/module.h>
19
#include <linux/types.h>
20
#include <linux/kernel.h>
21
#include <linux/sched.h>
22
#include <linux/mm.h>
23
#include <linux/string.h>
24
#include <linux/errno.h>
25
#include <linux/phonedev.h>
26
#include <linux/init.h>
27
#include <asm/uaccess.h>
28
#include <asm/system.h>
29
 
30
#include <linux/kmod.h>
31
#include <linux/sem.h>
32
 
33
 
34
#define PHONE_NUM_DEVICES       256
35
 
36
/*
37
 *    Active devices
38
 */
39
 
40
static struct phone_device *phone_device[PHONE_NUM_DEVICES];
41
static DECLARE_MUTEX(phone_lock);
42
 
43
/*
44
 *    Open a phone device.
45
 */
46
 
47
static int phone_open(struct inode *inode, struct file *file)
48
{
49
        unsigned int minor = MINOR(inode->i_rdev);
50
        int err = 0;
51
        struct phone_device *p;
52
        struct file_operations *old_fops, *new_fops = NULL;
53
 
54
        if (minor >= PHONE_NUM_DEVICES)
55
                return -ENODEV;
56
 
57
        down(&phone_lock);
58
        p = phone_device[minor];
59
        if (p)
60
                new_fops = fops_get(p->f_op);
61
        if (!new_fops) {
62
                char modname[32];
63
 
64
                up(&phone_lock);
65
                sprintf(modname, "char-major-%d-%d", PHONE_MAJOR, minor);
66
                request_module(modname);
67
                down(&phone_lock);
68
                p = phone_device[minor];
69
                if (p == NULL || (new_fops = fops_get(p->f_op)) == NULL)
70
                {
71
                        err=-ENODEV;
72
                        goto end;
73
                }
74
        }
75
        old_fops = file->f_op;
76
        file->f_op = new_fops;
77
        if (p->open)
78
                err = p->open(p, file); /* Tell the device it is open */
79
        if (err) {
80
                fops_put(file->f_op);
81
                file->f_op = fops_get(old_fops);
82
        }
83
        fops_put(old_fops);
84
end:
85
        up(&phone_lock);
86
        return err;
87
}
88
 
89
/*
90
 *    Telephony For Linux device drivers request registration here.
91
 */
92
 
93
int phone_register_device(struct phone_device *p, int unit)
94
{
95
        int base;
96
        int end;
97
        int i;
98
 
99
        base = 0;
100
        end = PHONE_NUM_DEVICES - 1;
101
 
102
        if (unit != PHONE_UNIT_ANY) {
103
                base = unit;
104
                end = unit + 1;  /* enter the loop at least one time */
105
        }
106
 
107
        down(&phone_lock);
108
        for (i = base; i < end; i++) {
109
                if (phone_device[i] == NULL) {
110
                        phone_device[i] = p;
111
                        p->minor = i;
112
                        MOD_INC_USE_COUNT;
113
                        up(&phone_lock);
114
                        return 0;
115
                }
116
        }
117
        up(&phone_lock);
118
        return -ENFILE;
119
}
120
 
121
/*
122
 *    Unregister an unused Telephony for linux device
123
 */
124
 
125
void phone_unregister_device(struct phone_device *pfd)
126
{
127
        down(&phone_lock);
128
        if (phone_device[pfd->minor] != pfd)
129
                panic("phone: bad unregister");
130
        phone_device[pfd->minor] = NULL;
131
        up(&phone_lock);
132
        MOD_DEC_USE_COUNT;
133
}
134
 
135
 
136
static struct file_operations phone_fops =
137
{
138
        owner:          THIS_MODULE,
139
        open:           phone_open,
140
};
141
 
142
/*
143
 *      Board init functions
144
 */
145
 
146
 
147
/*
148
 *    Initialise Telephony for linux
149
 */
150
 
151
static int __init telephony_init(void)
152
{
153
        printk(KERN_INFO "Linux telephony interface: v1.00\n");
154
        if (register_chrdev(PHONE_MAJOR, "telephony", &phone_fops)) {
155
                printk("phonedev: unable to get major %d\n", PHONE_MAJOR);
156
                return -EIO;
157
        }
158
 
159
        return 0;
160
}
161
 
162
static void __exit telephony_exit(void)
163
{
164
        unregister_chrdev(PHONE_MAJOR, "telephony");
165
}
166
 
167
module_init(telephony_init);
168
module_exit(telephony_exit);
169
 
170
MODULE_LICENSE("GPL");
171
 
172
EXPORT_SYMBOL(phone_register_device);
173
EXPORT_SYMBOL(phone_unregister_device);

powered by: WebSVN 2.1.0

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