aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/capi
diff options
context:
space:
mode:
authorAlexey Dobriyan <adobriyan@gmail.com>2010-01-14 06:10:54 -0500
committerDavid S. Miller <davem@davemloft.net>2010-01-14 06:10:54 -0500
commit9a58a80a701bdb2d220cdab4914218df5b48d781 (patch)
tree01eeb65ec70f22ec326d0938d002cc6a2aec73e8 /drivers/isdn/capi
parent508e14b4a4fb1a824a14f2c5b8d7df67b313f8e4 (diff)
proc_fops: convert drivers/isdn/ to seq_file
Convert code away from ->read_proc/->write_proc interfaces. Switch to proc_create()/proc_create_data() which make addition of proc entries reliable wrt NULL ->proc_fops, NULL ->data and so on. Problem with ->read_proc et al is described here commit 786d7e1612f0b0adb6046f19b906609e4fe8b1ba "Fix rmmod/read/write races in /proc entries" [akpm@linux-foundation.org: CONFIG_PROC_FS=n build fix] Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com> Signed-off-by: Tilman Schmidt <tilman@imap.cc> Signed-off-by: Karsten Keil <keil@b1-systems.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/isdn/capi')
-rw-r--r--drivers/isdn/capi/capi.c99
-rw-r--r--drivers/isdn/capi/capidrv.c55
-rw-r--r--drivers/isdn/capi/kcapi.c8
3 files changed, 53 insertions, 109 deletions
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index 65bf91e16a42..79f9364aded6 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -33,6 +33,7 @@
33#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */ 33#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
34#include <linux/skbuff.h> 34#include <linux/skbuff.h>
35#include <linux/proc_fs.h> 35#include <linux/proc_fs.h>
36#include <linux/seq_file.h>
36#include <linux/poll.h> 37#include <linux/poll.h>
37#include <linux/capi.h> 38#include <linux/capi.h>
38#include <linux/kernelcapi.h> 39#include <linux/kernelcapi.h>
@@ -1407,114 +1408,84 @@ static void capinc_tty_exit(void)
1407 * /proc/capi/capi20: 1408 * /proc/capi/capi20:
1408 * minor applid nrecvctlpkt nrecvdatapkt nsendctlpkt nsenddatapkt 1409 * minor applid nrecvctlpkt nrecvdatapkt nsendctlpkt nsenddatapkt
1409 */ 1410 */
1410static int proc_capidev_read_proc(char *page, char **start, off_t off, 1411static int capi20_proc_show(struct seq_file *m, void *v)
1411 int count, int *eof, void *data)
1412{ 1412{
1413 struct capidev *cdev; 1413 struct capidev *cdev;
1414 struct list_head *l; 1414 struct list_head *l;
1415 int len = 0;
1416 1415
1417 read_lock(&capidev_list_lock); 1416 read_lock(&capidev_list_lock);
1418 list_for_each(l, &capidev_list) { 1417 list_for_each(l, &capidev_list) {
1419 cdev = list_entry(l, struct capidev, list); 1418 cdev = list_entry(l, struct capidev, list);
1420 len += sprintf(page+len, "0 %d %lu %lu %lu %lu\n", 1419 seq_printf(m, "0 %d %lu %lu %lu %lu\n",
1421 cdev->ap.applid, 1420 cdev->ap.applid,
1422 cdev->ap.nrecvctlpkt, 1421 cdev->ap.nrecvctlpkt,
1423 cdev->ap.nrecvdatapkt, 1422 cdev->ap.nrecvdatapkt,
1424 cdev->ap.nsentctlpkt, 1423 cdev->ap.nsentctlpkt,
1425 cdev->ap.nsentdatapkt); 1424 cdev->ap.nsentdatapkt);
1426 if (len <= off) {
1427 off -= len;
1428 len = 0;
1429 } else {
1430 if (len-off > count)
1431 goto endloop;
1432 }
1433 } 1425 }
1434
1435endloop:
1436 read_unlock(&capidev_list_lock); 1426 read_unlock(&capidev_list_lock);
1437 if (len < count) 1427 return 0;
1438 *eof = 1;
1439 if (len > count) len = count;
1440 if (len < 0) len = 0;
1441 return len;
1442} 1428}
1443 1429
1430static int capi20_proc_open(struct inode *inode, struct file *file)
1431{
1432 return single_open(file, capi20_proc_show, NULL);
1433}
1434
1435static const struct file_operations capi20_proc_fops = {
1436 .owner = THIS_MODULE,
1437 .open = capi20_proc_open,
1438 .read = seq_read,
1439 .llseek = seq_lseek,
1440 .release = single_release,
1441};
1442
1444/* 1443/*
1445 * /proc/capi/capi20ncci: 1444 * /proc/capi/capi20ncci:
1446 * applid ncci 1445 * applid ncci
1447 */ 1446 */
1448static int proc_capincci_read_proc(char *page, char **start, off_t off, 1447static int capi20ncci_proc_show(struct seq_file *m, void *v)
1449 int count, int *eof, void *data)
1450{ 1448{
1451 struct capidev *cdev; 1449 struct capidev *cdev;
1452 struct capincci *np; 1450 struct capincci *np;
1453 struct list_head *l; 1451 struct list_head *l;
1454 int len = 0;
1455 1452
1456 read_lock(&capidev_list_lock); 1453 read_lock(&capidev_list_lock);
1457 list_for_each(l, &capidev_list) { 1454 list_for_each(l, &capidev_list) {
1458 cdev = list_entry(l, struct capidev, list); 1455 cdev = list_entry(l, struct capidev, list);
1459 for (np=cdev->nccis; np; np = np->next) { 1456 for (np=cdev->nccis; np; np = np->next) {
1460 len += sprintf(page+len, "%d 0x%x\n", 1457 seq_printf(m, "%d 0x%x\n",
1461 cdev->ap.applid, 1458 cdev->ap.applid,
1462 np->ncci); 1459 np->ncci);
1463 if (len <= off) {
1464 off -= len;
1465 len = 0;
1466 } else {
1467 if (len-off > count)
1468 goto endloop;
1469 }
1470 } 1460 }
1471 } 1461 }
1472endloop:
1473 read_unlock(&capidev_list_lock); 1462 read_unlock(&capidev_list_lock);
1474 *start = page+off; 1463 return 0;
1475 if (len < count)
1476 *eof = 1;
1477 if (len>count) len = count;
1478 if (len<0) len = 0;
1479 return len;
1480} 1464}
1481 1465
1482static struct procfsentries { 1466static int capi20ncci_proc_open(struct inode *inode, struct file *file)
1483 char *name; 1467{
1484 mode_t mode; 1468 return single_open(file, capi20ncci_proc_show, NULL);
1485 int (*read_proc)(char *page, char **start, off_t off, 1469}
1486 int count, int *eof, void *data); 1470
1487 struct proc_dir_entry *procent; 1471static const struct file_operations capi20ncci_proc_fops = {
1488} procfsentries[] = { 1472 .owner = THIS_MODULE,
1489 /* { "capi", S_IFDIR, 0 }, */ 1473 .open = capi20ncci_proc_open,
1490 { "capi/capi20", 0 , proc_capidev_read_proc }, 1474 .read = seq_read,
1491 { "capi/capi20ncci", 0 , proc_capincci_read_proc }, 1475 .llseek = seq_lseek,
1476 .release = single_release,
1492}; 1477};
1493 1478
1494static void __init proc_init(void) 1479static void __init proc_init(void)
1495{ 1480{
1496 int nelem = ARRAY_SIZE(procfsentries); 1481 proc_create("capi/capi20", 0, NULL, &capi20_proc_fops);
1497 int i; 1482 proc_create("capi/capi20ncci", 0, NULL, &capi20ncci_proc_fops);
1498
1499 for (i=0; i < nelem; i++) {
1500 struct procfsentries *p = procfsentries + i;
1501 p->procent = create_proc_entry(p->name, p->mode, NULL);
1502 if (p->procent) p->procent->read_proc = p->read_proc;
1503 }
1504} 1483}
1505 1484
1506static void __exit proc_exit(void) 1485static void __exit proc_exit(void)
1507{ 1486{
1508 int nelem = ARRAY_SIZE(procfsentries); 1487 remove_proc_entry("capi/capi20", NULL);
1509 int i; 1488 remove_proc_entry("capi/capi20ncci", NULL);
1510
1511 for (i=nelem-1; i >= 0; i--) {
1512 struct procfsentries *p = procfsentries + i;
1513 if (p->procent) {
1514 remove_proc_entry(p->name, NULL);
1515 p->procent = NULL;
1516 }
1517 }
1518} 1489}
1519 1490
1520/* -------- init function and module interface ---------------------- */ 1491/* -------- init function and module interface ---------------------- */
diff --git a/drivers/isdn/capi/capidrv.c b/drivers/isdn/capi/capidrv.c
index 66b7d7a86474..bb450152fb74 100644
--- a/drivers/isdn/capi/capidrv.c
+++ b/drivers/isdn/capi/capidrv.c
@@ -24,6 +24,7 @@
24#include <linux/isdn.h> 24#include <linux/isdn.h>
25#include <linux/isdnif.h> 25#include <linux/isdnif.h>
26#include <linux/proc_fs.h> 26#include <linux/proc_fs.h>
27#include <linux/seq_file.h>
27#include <linux/capi.h> 28#include <linux/capi.h>
28#include <linux/kernelcapi.h> 29#include <linux/kernelcapi.h>
29#include <linux/ctype.h> 30#include <linux/ctype.h>
@@ -2229,59 +2230,37 @@ static void lower_callback(unsigned int cmd, u32 contr, void *data)
2229 * /proc/capi/capidrv: 2230 * /proc/capi/capidrv:
2230 * nrecvctlpkt nrecvdatapkt nsendctlpkt nsenddatapkt 2231 * nrecvctlpkt nrecvdatapkt nsendctlpkt nsenddatapkt
2231 */ 2232 */
2232static int proc_capidrv_read_proc(char *page, char **start, off_t off, 2233static int capidrv_proc_show(struct seq_file *m, void *v)
2233 int count, int *eof, void *data)
2234{ 2234{
2235 int len = 0; 2235 seq_printf(m, "%lu %lu %lu %lu\n",
2236
2237 len += sprintf(page+len, "%lu %lu %lu %lu\n",
2238 global.ap.nrecvctlpkt, 2236 global.ap.nrecvctlpkt,
2239 global.ap.nrecvdatapkt, 2237 global.ap.nrecvdatapkt,
2240 global.ap.nsentctlpkt, 2238 global.ap.nsentctlpkt,
2241 global.ap.nsentdatapkt); 2239 global.ap.nsentdatapkt);
2242 if (off+count >= len) 2240 return 0;
2243 *eof = 1; 2241}
2244 if (len < off) 2242
2245 return 0; 2243static int capidrv_proc_open(struct inode *inode, struct file *file)
2246 *start = page + off; 2244{
2247 return ((count < len-off) ? count : len-off); 2245 return single_open(file, capidrv_proc_show, NULL);
2248} 2246}
2249 2247
2250static struct procfsentries { 2248static const struct file_operations capidrv_proc_fops = {
2251 char *name; 2249 .owner = THIS_MODULE,
2252 mode_t mode; 2250 .open = capidrv_proc_open,
2253 int (*read_proc)(char *page, char **start, off_t off, 2251 .read = seq_read,
2254 int count, int *eof, void *data); 2252 .llseek = seq_lseek,
2255 struct proc_dir_entry *procent; 2253 .release = single_release,
2256} procfsentries[] = {
2257 /* { "capi", S_IFDIR, 0 }, */
2258 { "capi/capidrv", 0 , proc_capidrv_read_proc },
2259}; 2254};
2260 2255
2261static void __init proc_init(void) 2256static void __init proc_init(void)
2262{ 2257{
2263 int nelem = ARRAY_SIZE(procfsentries); 2258 proc_create("capi/capidrv", 0, NULL, &capidrv_proc_fops);
2264 int i;
2265
2266 for (i=0; i < nelem; i++) {
2267 struct procfsentries *p = procfsentries + i;
2268 p->procent = create_proc_entry(p->name, p->mode, NULL);
2269 if (p->procent) p->procent->read_proc = p->read_proc;
2270 }
2271} 2259}
2272 2260
2273static void __exit proc_exit(void) 2261static void __exit proc_exit(void)
2274{ 2262{
2275 int nelem = ARRAY_SIZE(procfsentries); 2263 remove_proc_entry("capi/capidrv", NULL);
2276 int i;
2277
2278 for (i=nelem-1; i >= 0; i--) {
2279 struct procfsentries *p = procfsentries + i;
2280 if (p->procent) {
2281 remove_proc_entry(p->name, NULL);
2282 p->procent = NULL;
2283 }
2284 }
2285} 2264}
2286 2265
2287static int __init capidrv_init(void) 2266static int __init capidrv_init(void)
diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c
index dc506ab99cac..b0bacf377c18 100644
--- a/drivers/isdn/capi/kcapi.c
+++ b/drivers/isdn/capi/kcapi.c
@@ -490,13 +490,7 @@ attach_capi_ctr(struct capi_ctr *card)
490 card->traceflag = showcapimsgs; 490 card->traceflag = showcapimsgs;
491 491
492 sprintf(card->procfn, "capi/controllers/%d", card->cnr); 492 sprintf(card->procfn, "capi/controllers/%d", card->cnr);
493 card->procent = create_proc_entry(card->procfn, 0, NULL); 493 card->procent = proc_create_data(card->procfn, 0, NULL, card->proc_fops, card);
494 if (card->procent) {
495 card->procent->read_proc =
496 (int (*)(char *,char **,off_t,int,int *,void *))
497 card->ctr_read_proc;
498 card->procent->data = card;
499 }
500 494
501 ncards++; 495 ncards++;
502 printk(KERN_NOTICE "kcapi: Controller [%03d]: %s attached\n", 496 printk(KERN_NOTICE "kcapi: Controller [%03d]: %s attached\n",