1 /* $Id: divamnt.c,v 1.32.6.10 2005/02/11 19:40:25 armin Exp $
3 * Driver for Eicon DIVA Server ISDN cards.
6 * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
7 * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
9 * This software may be used and distributed according to the terms
10 * of the GNU General Public License, incorporated herein by reference.
13 #include <linux/module.h>
14 #include <linux/init.h>
15 #include <linux/kernel.h>
16 #include <linux/poll.h>
17 #include <linux/mutex.h>
18 #include <linux/uaccess.h>
25 static DEFINE_MUTEX(maint_mutex
);
26 static char *main_revision
= "$Revision: 1.32.6.10 $";
30 MODULE_DESCRIPTION("Maint driver for Eicon DIVA Server cards");
31 MODULE_AUTHOR("Cytronics & Melware, Eicon Networks");
32 MODULE_SUPPORTED_DEVICE("DIVA card driver");
33 MODULE_LICENSE("GPL");
35 static int buffer_length
= 128;
36 module_param(buffer_length
, int, 0);
37 static unsigned long diva_dbg_mem
= 0;
38 module_param(diva_dbg_mem
, ulong
, 0);
40 static char *DRIVERNAME
=
41 "Eicon DIVA - MAINT module (http://www.melware.net)";
42 static char *DRIVERLNAME
= "diva_mnt";
43 static char *DEVNAME
= "DivasMAINT";
44 char *DRIVERRELEASE_MNT
= "2.0";
46 static wait_queue_head_t msgwaitq
;
47 static unsigned long opened
;
49 extern int mntfunc_init(int *, void **, unsigned long);
50 extern void mntfunc_finit(void);
51 extern int maint_read_write(void __user
*buf
, int count
);
56 static char *getrev(const char *revision
)
61 if ((p
= strchr(revision
, ':'))) {
72 * kernel/user space copy functions
74 int diva_os_copy_to_user(void *os_handle
, void __user
*dst
, const void *src
,
77 return (copy_to_user(dst
, src
, length
));
79 int diva_os_copy_from_user(void *os_handle
, void *dst
, const void __user
*src
,
82 return (copy_from_user(dst
, src
, length
));
88 void diva_os_get_time(dword
*sec
, dword
*usec
)
90 struct timespec64 time
;
92 ktime_get_ts64(&time
);
94 *sec
= (dword
) time
.tv_sec
;
95 *usec
= (dword
) (time
.tv_nsec
/ NSEC_PER_USEC
);
99 * device node operations
101 static unsigned int maint_poll(struct file
*file
, poll_table
*wait
)
103 unsigned int mask
= 0;
105 poll_wait(file
, &msgwaitq
, wait
);
106 mask
= POLLOUT
| POLLWRNORM
;
107 if (file
->private_data
|| diva_dbg_q_length()) {
108 mask
|= POLLIN
| POLLRDNORM
;
113 static int maint_open(struct inode
*ino
, struct file
*filep
)
117 mutex_lock(&maint_mutex
);
118 /* only one open is allowed, so we test
120 if (test_and_set_bit(0, &opened
))
123 filep
->private_data
= NULL
;
124 ret
= nonseekable_open(ino
, filep
);
126 mutex_unlock(&maint_mutex
);
130 static int maint_close(struct inode
*ino
, struct file
*filep
)
132 if (filep
->private_data
) {
133 diva_os_free(0, filep
->private_data
);
134 filep
->private_data
= NULL
;
137 /* clear 'used' flag */
138 clear_bit(0, &opened
);
143 static ssize_t
divas_maint_write(struct file
*file
, const char __user
*buf
,
144 size_t count
, loff_t
*ppos
)
146 return (maint_read_write((char __user
*) buf
, (int) count
));
149 static ssize_t
divas_maint_read(struct file
*file
, char __user
*buf
,
150 size_t count
, loff_t
*ppos
)
152 return (maint_read_write(buf
, (int) count
));
155 static const struct file_operations divas_maint_fops
= {
156 .owner
= THIS_MODULE
,
158 .read
= divas_maint_read
,
159 .write
= divas_maint_write
,
162 .release
= maint_close
165 static void divas_maint_unregister_chrdev(void)
167 unregister_chrdev(major
, DEVNAME
);
170 static int __init
divas_maint_register_chrdev(void)
172 if ((major
= register_chrdev(0, DEVNAME
, &divas_maint_fops
)) < 0)
174 printk(KERN_ERR
"%s: failed to create /dev entry.\n",
185 void diva_maint_wakeup_read(void)
187 wake_up_interruptible(&msgwaitq
);
193 static int __init
maint_init(void)
199 init_waitqueue_head(&msgwaitq
);
201 printk(KERN_INFO
"%s\n", DRIVERNAME
);
202 printk(KERN_INFO
"%s: Rel:%s Rev:", DRIVERLNAME
, DRIVERRELEASE_MNT
);
203 strcpy(tmprev
, main_revision
);
204 printk("%s Build: %s \n", getrev(tmprev
), DIVA_BUILD
);
206 if (!divas_maint_register_chrdev()) {
211 if (!(mntfunc_init(&buffer_length
, &buffer
, diva_dbg_mem
))) {
212 printk(KERN_ERR
"%s: failed to connect to DIDD.\n",
214 divas_maint_unregister_chrdev();
219 printk(KERN_INFO
"%s: trace buffer = %p - %d kBytes, %s (Major: %d)\n",
220 DRIVERLNAME
, buffer
, (buffer_length
/ 1024),
221 (diva_dbg_mem
== 0) ? "internal" : "external", major
);
230 static void __exit
maint_exit(void)
232 divas_maint_unregister_chrdev();
235 printk(KERN_INFO
"%s: module unloaded.\n", DRIVERLNAME
);
238 module_init(maint_init
);
239 module_exit(maint_exit
);