summaryrefslogtreecommitdiffstats
path: root/drivers/isdn
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-07-15 03:32:22 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-07-15 03:32:22 +0000
commitf1da2c3860e301527d56a1ef0b56c649ee7c4b1b (patch)
tree562b5d2e8b9cb62eb983d78ff6bcf9789e08fcf6 /drivers/isdn
parent00f11569ac8ca73cbcdef8822de1583e79aee571 (diff)
Merge with Linux 2.4.0-test5-pre1. This works again on Origin UP.
The IP22 cache bugs which are plaguing some machines are still unfixed.
Diffstat (limited to 'drivers/isdn')
-rw-r--r--drivers/isdn/avmb1/capi.c18
-rw-r--r--drivers/isdn/divert/divert_procfs.c2
-rw-r--r--drivers/isdn/hysdn/hysdn_procconf.c3
-rw-r--r--drivers/isdn/hysdn/hysdn_procfs.c3
-rw-r--r--drivers/isdn/hysdn/hysdn_proclog.c2
-rw-r--r--drivers/isdn/isdn_common.c43
6 files changed, 44 insertions, 27 deletions
diff --git a/drivers/isdn/avmb1/capi.c b/drivers/isdn/avmb1/capi.c
index 06ddc8199..4c7e68266 100644
--- a/drivers/isdn/avmb1/capi.c
+++ b/drivers/isdn/avmb1/capi.c
@@ -182,6 +182,7 @@
#include <linux/fs.h>
#include <linux/signal.h>
#include <linux/mm.h>
+#include <linux/smp_lock.h>
#include <linux/timer.h>
#include <linux/wait.h>
#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
@@ -379,10 +380,8 @@ struct capiminor *capiminor_alloc(__u16 applid, __u32 ncci)
struct capiminor *mp, **pp;
unsigned int minor = 0;
- MOD_INC_USE_COUNT;
mp = (struct capiminor *)kmem_cache_alloc(capiminor_cachep, GFP_ATOMIC);
if (!mp) {
- MOD_DEC_USE_COUNT;
printk(KERN_ERR "capi: can't alloc capiminor\n");
return 0;
}
@@ -434,7 +433,6 @@ void capiminor_free(struct capiminor *mp)
kfree_skb(skb);
capiminor_del_all_ack(mp);
kmem_cache_free(capiminor_cachep, mp);
- MOD_DEC_USE_COUNT;
#ifdef _DEBUG_REFCOUNT
printk(KERN_DEBUG "capiminor_free %d\n", GET_USE_COUNT(THIS_MODULE));
#endif
@@ -1212,7 +1210,6 @@ capi_open(struct inode *inode, struct file *file)
if ((file->private_data = capidev_alloc(file)) == 0)
return -ENOMEM;
- MOD_INC_USE_COUNT;
#ifdef _DEBUG_REFCOUNT
printk(KERN_DEBUG "capi_open %d\n", GET_USE_COUNT(THIS_MODULE));
#endif
@@ -1224,14 +1221,15 @@ capi_release(struct inode *inode, struct file *file)
{
struct capidev *cdev = (struct capidev *)file->private_data;
+ lock_kernel();
capincci_free(cdev, 0xffffffff);
capidev_free(cdev);
file->private_data = NULL;
- MOD_DEC_USE_COUNT;
#ifdef _DEBUG_REFCOUNT
printk(KERN_DEBUG "capi_release %d\n", GET_USE_COUNT(THIS_MODULE));
#endif
+ unlock_kernel();
return 0;
}
@@ -1414,11 +1412,13 @@ capinc_raw_release(struct inode *inode, struct file *file)
struct capiminor *mp = (struct capiminor *)file->private_data;
if (mp) {
+ lock_kernel();
mp->file = 0;
if (mp->nccip == 0) {
capiminor_free(mp);
file->private_data = NULL;
}
+ unlock_kernel();
}
#ifdef _DEBUG_REFCOUNT
@@ -2050,8 +2050,6 @@ int capi_init(void)
{
char *p;
- MOD_INC_USE_COUNT;
-
if ((p = strchr(revision, ':'))) {
strcpy(rev, p + 2);
p = strchr(rev, '$');
@@ -2061,7 +2059,6 @@ int capi_init(void)
if (devfs_register_chrdev(capi_major, "capi20", &capi_fops)) {
printk(KERN_ERR "capi20: unable to get major %d\n", capi_major);
- MOD_DEC_USE_COUNT;
return -EIO;
}
@@ -2069,7 +2066,6 @@ int capi_init(void)
if (devfs_register_chrdev(capi_rawmajor, "capi/r%d", &capinc_raw_fops)) {
devfs_unregister_chrdev(capi_major, "capi20");
printk(KERN_ERR "capi20: unable to get major %d\n", capi_rawmajor);
- MOD_DEC_USE_COUNT;
return -EIO;
}
devfs_register_series (NULL, "capi/r%u", CAPINC_NR_PORTS,
@@ -2085,7 +2081,6 @@ int capi_init(void)
if ((capifuncs = attach_capi_interface(&cuser)) == 0) {
- MOD_DEC_USE_COUNT;
devfs_unregister_chrdev(capi_major, "capi20");
#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
devfs_unregister_chrdev(capi_rawmajor, "capi/r%d");
@@ -2101,7 +2096,6 @@ int capi_init(void)
(void) detach_capi_interface(&cuser);
devfs_unregister_chrdev(capi_major, "capi20");
devfs_unregister_chrdev(capi_rawmajor, "capi/r%d");
- MOD_DEC_USE_COUNT;
return -ENOMEM;
}
#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
@@ -2122,7 +2116,6 @@ int capi_init(void)
devfs_unregister(devfs_find_handle(NULL, "capi20",
capi_major, 0,
DEVFS_SPECIAL_CHR, 0));
- MOD_DEC_USE_COUNT;
return -ENOMEM;
}
@@ -2131,7 +2124,6 @@ int capi_init(void)
printk(KERN_NOTICE "capi20: Rev%s: started up with major %d\n",
rev, capi_major);
- MOD_DEC_USE_COUNT;
return 0;
}
diff --git a/drivers/isdn/divert/divert_procfs.c b/drivers/isdn/divert/divert_procfs.c
index f7d7ee8d5..bd065a48d 100644
--- a/drivers/isdn/divert/divert_procfs.c
+++ b/drivers/isdn/divert/divert_procfs.c
@@ -199,6 +199,7 @@ isdn_divert_close(struct inode *ino, struct file *filep)
struct divert_info *inf;
int flags;
+ lock_kernel();
save_flags(flags);
cli();
if_used--;
@@ -214,6 +215,7 @@ isdn_divert_close(struct inode *ino, struct file *filep)
divert_info_head = divert_info_head->next;
kfree(inf);
}
+ unlock_kernel();
return (0);
} /* isdn_divert_close */
diff --git a/drivers/isdn/hysdn/hysdn_procconf.c b/drivers/isdn/hysdn/hysdn_procconf.c
index c27c926a1..c28aedc1f 100644
--- a/drivers/isdn/hysdn/hysdn_procconf.c
+++ b/drivers/isdn/hysdn/hysdn_procconf.c
@@ -372,6 +372,7 @@ hysdn_conf_close(struct inode *ino, struct file *filep)
int retval = 0;
struct proc_dir_entry *pd;
+ lock_kernel();
/* search the addressed card */
card = card_root;
while (card) {
@@ -381,6 +382,7 @@ hysdn_conf_close(struct inode *ino, struct file *filep)
card = card->next; /* search next entry */
}
if (!card) {
+ unlock_kernel();
return (-ENODEV); /* device is unknown/invalid */
}
if (card->debug_flags & (LOG_PROC_OPEN | LOG_PROC_ALL))
@@ -403,6 +405,7 @@ hysdn_conf_close(struct inode *ino, struct file *filep)
if (filep->private_data)
kfree(filep->private_data); /* release memory */
}
+ unlock_kernel();
return (retval);
} /* hysdn_conf_close */
diff --git a/drivers/isdn/hysdn/hysdn_procfs.c b/drivers/isdn/hysdn/hysdn_procfs.c
index ae07f6597..864935625 100644
--- a/drivers/isdn/hysdn/hysdn_procfs.c
+++ b/drivers/isdn/hysdn/hysdn_procfs.c
@@ -254,7 +254,7 @@ hysdn_log_close(struct inode *ino, struct file *filep)
hysdn_card *card;
int flags, retval = 0;
-
+ lock_kernel();
if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) {
/* write only access -> write debug completely written */
retval = 0; /* success */
@@ -297,6 +297,7 @@ hysdn_log_close(struct inode *ino, struct file *filep)
}
} /* read access */
+ unlock_kernel();
return (retval);
} /* hysdn_log_close */
diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c
index 1a2980f02..ba454b9dc 100644
--- a/drivers/isdn/hysdn/hysdn_proclog.c
+++ b/drivers/isdn/hysdn/hysdn_proclog.c
@@ -345,6 +345,7 @@ hysdn_log_close(struct inode *ino, struct file *filep)
int flags, retval = 0;
+ lock_kernel();
if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) {
/* write only access -> write debug level written */
retval = 0; /* success */
@@ -386,6 +387,7 @@ hysdn_log_close(struct inode *ino, struct file *filep)
kfree(inf);
}
} /* read access */
+ unlock_kernel();
return (retval);
} /* hysdn_log_close */
diff --git a/drivers/isdn/isdn_common.c b/drivers/isdn/isdn_common.c
index f6c326301..b543d8690 100644
--- a/drivers/isdn/isdn_common.c
+++ b/drivers/isdn/isdn_common.c
@@ -439,6 +439,7 @@
#include <linux/poll.h>
#include <linux/vmalloc.h>
#include <linux/isdn.h>
+#include <linux/smp_lock.h>
#include "isdn_common.h"
#include "isdn_tty.h"
#include "isdn_net.h"
@@ -485,11 +486,10 @@ static void isdn_register_devfs(int);
static void isdn_unregister_devfs(int);
void
-isdn_MOD_INC_USE_COUNT(void)
+isdn_lock_drivers(void)
{
int i;
- MOD_INC_USE_COUNT;
for (i = 0; i < dev->drivers; i++) {
isdn_ctrl cmd;
@@ -502,11 +502,17 @@ isdn_MOD_INC_USE_COUNT(void)
}
void
-isdn_MOD_DEC_USE_COUNT(void)
+isdn_MOD_INC_USE_COUNT(void)
+{
+ MOD_INC_USE_COUNT;
+ isdn_lock_drivers();
+}
+
+void
+isdn_unlock_drivers(void)
{
int i;
- MOD_DEC_USE_COUNT;
for (i = 0; i < dev->drivers; i++)
if (dev->drv[i]->locks > 0) {
isdn_ctrl cmd;
@@ -519,6 +525,13 @@ isdn_MOD_DEC_USE_COUNT(void)
}
}
+void
+isdn_MOD_DEC_USE_COUNT(void)
+{
+ MOD_DEC_USE_COUNT;
+ isdn_unlock_drivers();
+}
+
#if defined(ISDN_DEBUG_NET_DUMP) || defined(ISDN_DEBUG_MODEM_DUMP)
void
isdn_dumppkt(char *s, u_char * p, int len, int dumplen)
@@ -1976,8 +1989,6 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
/*
* Open the device code.
- * MOD_INC_USE_COUNT make sure that the driver memory is not freed
- * while the device is in use.
*/
static int
isdn_open(struct inode *ino, struct file *filep)
@@ -1990,7 +2001,6 @@ isdn_open(struct inode *ino, struct file *filep)
infostruct *p;
if ((p = (infostruct *) kmalloc(sizeof(infostruct), GFP_KERNEL))) {
- MOD_INC_USE_COUNT;
p->next = (char *) dev->infochain;
p->private = (char *) &(filep->private_data);
dev->infochain = p;
@@ -2011,21 +2021,21 @@ isdn_open(struct inode *ino, struct file *filep)
return -ENODEV;
if (!(dev->drv[drvidx]->online & (1 << chidx)))
return -ENODEV;
- isdn_MOD_INC_USE_COUNT();
+ isdn_lock_drivers();
return 0;
}
if (minor <= ISDN_MINOR_CTRLMAX) {
drvidx = isdn_minor2drv(minor - ISDN_MINOR_CTRL);
if (drvidx < 0)
return -ENODEV;
- isdn_MOD_INC_USE_COUNT();
+ isdn_lock_drivers();
return 0;
}
#ifdef CONFIG_ISDN_PPP
if (minor <= ISDN_MINOR_PPPMAX) {
int ret;
if (!(ret = isdn_ppp_open(minor - ISDN_MINOR_PPP, filep)))
- isdn_MOD_INC_USE_COUNT();
+ isdn_lock_drivers();
return ret;
}
#endif
@@ -2037,11 +2047,11 @@ isdn_close(struct inode *ino, struct file *filep)
{
uint minor = MINOR(ino->i_rdev);
+ lock_kernel();
if (minor == ISDN_MINOR_STATUS) {
infostruct *p = dev->infochain;
infostruct *q = NULL;
- MOD_DEC_USE_COUNT;
while (p) {
if (p->private == (char *) &(filep->private_data)) {
if (q)
@@ -2049,31 +2059,38 @@ isdn_close(struct inode *ino, struct file *filep)
else
dev->infochain = (infostruct *) (p->next);
kfree(p);
+ unlock_kernel();
return 0;
}
q = p;
p = (infostruct *) (p->next);
}
printk(KERN_WARNING "isdn: No private data while closing isdnctrl\n");
+ unlock_kernel();
return 0;
}
- isdn_MOD_DEC_USE_COUNT();
- if (minor < ISDN_MINOR_CTRL)
+ isdn_unlock_drivers();
+ if (minor < ISDN_MINOR_CTRL) {
+ unlock_kernel();
return 0;
+ }
if (minor <= ISDN_MINOR_CTRLMAX) {
if (dev->profd == current)
dev->profd = NULL;
+ unlock_kernel();
return 0;
}
#ifdef CONFIG_ISDN_PPP
if (minor <= ISDN_MINOR_PPPMAX)
isdn_ppp_release(minor - ISDN_MINOR_PPP, filep);
#endif
+ unlock_kernel();
return 0;
}
static struct file_operations isdn_fops =
{
+ owner: THIS_MODULE,
llseek: isdn_lseek,
read: isdn_read,
write: isdn_write,