patch-2.4.0-test5 linux/drivers/isdn/avmb1/capi.c

Next file: linux/drivers/isdn/avmb1/kcapi.c
Previous file: linux/drivers/isdn/avmb1/c4.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test4/linux/drivers/isdn/avmb1/capi.c linux/drivers/isdn/avmb1/capi.c
@@ -1,11 +1,20 @@
 /*
- * $Id: capi.c,v 1.35 2000/06/19 15:11:24 keil Exp $
+ * $Id: capi.c,v 1.38 2000/07/24 08:49:09 calle Exp $
  *
  * CAPI 2.0 Interface for Linux
  *
  * Copyright 1996 by Carsten Paeth (calle@calle.in-berlin.de)
  *
  * $Log: capi.c,v $
+ * Revision 1.38  2000/07/24 08:49:09  calle
+ * - Bugfix: capiminor_del_all_ack completely wrong :-(
+ *
+ * Revision 1.37  2000/07/20 10:22:27  calle
+ * - Made procfs function cleaner and removed variable "begin".
+ *
+ * Revision 1.36  2000/06/29 13:59:35  calle
+ * - call to devfs_register was wrong
+ *
  * Revision 1.35  2000/06/19 15:11:24  keil
  * avoid use of freed structs
  * changes from 2.4.0-ac21
@@ -207,7 +216,7 @@
 #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
 #include <linux/slab.h>
 
-static char *revision = "$Revision: 1.35 $";
+static char *revision = "$Revision: 1.38 $";
 
 MODULE_AUTHOR("Carsten Paeth (calle@calle.in-berlin.de)");
 
@@ -364,7 +373,8 @@
 {
 	struct datahandle_queue **pp, *p;
 
-	for (pp = &mp->ackqueue; *pp; pp = &(*pp)->next) {
+	pp = &mp->ackqueue;
+	while (*pp) {
 		p = *pp;
 		*pp = (*pp)->next;
 		kmem_cache_free(capidh_cachep, p);
@@ -380,8 +390,10 @@
 	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;
 	}
@@ -433,6 +445,7 @@
 				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
@@ -1210,6 +1223,7 @@
 	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
@@ -1226,6 +1240,7 @@
 	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
@@ -1836,7 +1851,6 @@
 {
         struct capidev *cdev;
 	int len = 0;
-	off_t begin = 0;
 
 	for (cdev=capidev_openlist; cdev; cdev = cdev->next) {
 		len += sprintf(page+len, "%d %d %lu %lu %lu %lu\n",
@@ -1846,20 +1860,20 @@
 			cdev->nrecvdatapkt,
 			cdev->nsentctlpkt,
 			cdev->nsentdatapkt);
-		if (len+begin > off+count)
-			goto endloop;
-		if (len+begin < off) {
-			begin += len;
+		if (len <= off) {
+			off -= len;
 			len = 0;
+		} else {
+			if (len-off > count)
+				goto endloop;
 		}
 	}
 endloop:
-	if (cdev == 0)
+	if (len < count)
 		*eof = 1;
-	if (off >= len+begin)
-		return 0;
-	*start = page + (off-begin);
-	return ((count < begin+len-off) ? count : begin+len-off);
+	if (len>count) len = count;
+	if (len<0) len = 0;
+	return len;
 }
 
 /*
@@ -1872,7 +1886,6 @@
         struct capidev *cdev;
         struct capincci *np;
 	int len = 0;
-	off_t begin = 0;
 
 	for (cdev=capidev_openlist; cdev; cdev = cdev->next) {
 		for (np=cdev->nccis; np; np = np->next) {
@@ -1884,21 +1897,22 @@
 #else /* CONFIG_ISDN_CAPI_MIDDLEWARE */
 				np->minorp && np->minorp->file ? " open" : "");
 #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
-			if (len+begin > off+count)
-				goto endloop;
-			if (len+begin < off) {
-				begin += len;
+			if (len <= off) {
+				off -= len;
 				len = 0;
+			} else {
+				if (len-off > count)
+					goto endloop;
 			}
 		}
 	}
 endloop:
-	if (cdev == 0)
+	*start = page+off;
+	if (len < count)
 		*eof = 1;
-	if (off >= len+begin)
-		return 0;
-	*start = page + (begin-off);
-	return ((count < begin+len-off) ? count : begin+len-off);
+	if (len>count) len = count;
+	if (len<0) len = 0;
+	return len;
 }
 
 static struct procfsentries {
@@ -2050,6 +2064,8 @@
 {
 	char *p;
 
+	MOD_INC_USE_COUNT;
+
 	if ((p = strchr(revision, ':'))) {
 		strcpy(rev, p + 2);
 		p = strchr(rev, '$');
@@ -2059,6 +2075,7 @@
 
 	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;
 	}
 
@@ -2066,6 +2083,7 @@
 	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,
@@ -2081,6 +2099,7 @@
 
 	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");
@@ -2096,6 +2115,7 @@
 		(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 */
@@ -2116,6 +2136,7 @@
 		devfs_unregister(devfs_find_handle(NULL, "capi20",
 						   capi_major, 0,
 						   DEVFS_SPECIAL_CHR, 0));
+		MOD_DEC_USE_COUNT;
 		return -ENOMEM;
 	}
 
@@ -2124,6 +2145,7 @@
 	printk(KERN_NOTICE "capi20: Rev%s: started up with major %d\n",
 				rev, capi_major);
 
+	MOD_DEC_USE_COUNT;
 	return 0;
 }
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)