diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-07-15 03:32:22 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-07-15 03:32:22 +0000 |
commit | f1da2c3860e301527d56a1ef0b56c649ee7c4b1b (patch) | |
tree | 562b5d2e8b9cb62eb983d78ff6bcf9789e08fcf6 /drivers/isdn | |
parent | 00f11569ac8ca73cbcdef8822de1583e79aee571 (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.c | 18 | ||||
-rw-r--r-- | drivers/isdn/divert/divert_procfs.c | 2 | ||||
-rw-r--r-- | drivers/isdn/hysdn/hysdn_procconf.c | 3 | ||||
-rw-r--r-- | drivers/isdn/hysdn/hysdn_procfs.c | 3 | ||||
-rw-r--r-- | drivers/isdn/hysdn/hysdn_proclog.c | 2 | ||||
-rw-r--r-- | drivers/isdn/isdn_common.c | 43 |
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, |