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
786d7e1612 "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>
This commit is contained in:
Alexey Dobriyan 2010-01-14 03:10:54 -08:00 committed by David S. Miller
parent 508e14b4a4
commit 9a58a80a70
21 changed files with 407 additions and 454 deletions

View File

@ -149,10 +149,11 @@ char *(*procinfo)(struct capi_ctr *ctrlr)
pointer to a callback function returning the entry for the device in pointer to a callback function returning the entry for the device in
the CAPI controller info table, /proc/capi/controller the CAPI controller info table, /proc/capi/controller
read_proc_t *ctr_read_proc const struct file_operations *proc_fops
pointer to the read_proc callback function for the device's proc file pointers to callback functions for the device's proc file
system entry, /proc/capi/controllers/<n>; will be called with a system entry, /proc/capi/controllers/<n>; pointer to the device's
pointer to the device's capi_ctr structure as the last (data) argument capi_ctr structure is available from struct proc_dir_entry::data
which is available from struct inode.
Note: Callback functions except send_message() are never called in interrupt Note: Callback functions except send_message() are never called in interrupt
context. context.

View File

@ -33,6 +33,7 @@
#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */ #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/poll.h> #include <linux/poll.h>
#include <linux/capi.h> #include <linux/capi.h>
#include <linux/kernelcapi.h> #include <linux/kernelcapi.h>
@ -1407,114 +1408,84 @@ static void capinc_tty_exit(void)
* /proc/capi/capi20: * /proc/capi/capi20:
* minor applid nrecvctlpkt nrecvdatapkt nsendctlpkt nsenddatapkt * minor applid nrecvctlpkt nrecvdatapkt nsendctlpkt nsenddatapkt
*/ */
static int proc_capidev_read_proc(char *page, char **start, off_t off, static int capi20_proc_show(struct seq_file *m, void *v)
int count, int *eof, void *data)
{ {
struct capidev *cdev; struct capidev *cdev;
struct list_head *l; struct list_head *l;
int len = 0;
read_lock(&capidev_list_lock); read_lock(&capidev_list_lock);
list_for_each(l, &capidev_list) { list_for_each(l, &capidev_list) {
cdev = list_entry(l, struct capidev, list); cdev = list_entry(l, struct capidev, list);
len += sprintf(page+len, "0 %d %lu %lu %lu %lu\n", seq_printf(m, "0 %d %lu %lu %lu %lu\n",
cdev->ap.applid, cdev->ap.applid,
cdev->ap.nrecvctlpkt, cdev->ap.nrecvctlpkt,
cdev->ap.nrecvdatapkt, cdev->ap.nrecvdatapkt,
cdev->ap.nsentctlpkt, cdev->ap.nsentctlpkt,
cdev->ap.nsentdatapkt); cdev->ap.nsentdatapkt);
if (len <= off) {
off -= len;
len = 0;
} else {
if (len-off > count)
goto endloop;
}
} }
endloop:
read_unlock(&capidev_list_lock); read_unlock(&capidev_list_lock);
if (len < count) return 0;
*eof = 1;
if (len > count) len = count;
if (len < 0) len = 0;
return len;
} }
static int capi20_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, capi20_proc_show, NULL);
}
static const struct file_operations capi20_proc_fops = {
.owner = THIS_MODULE,
.open = capi20_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
/* /*
* /proc/capi/capi20ncci: * /proc/capi/capi20ncci:
* applid ncci * applid ncci
*/ */
static int proc_capincci_read_proc(char *page, char **start, off_t off, static int capi20ncci_proc_show(struct seq_file *m, void *v)
int count, int *eof, void *data)
{ {
struct capidev *cdev; struct capidev *cdev;
struct capincci *np; struct capincci *np;
struct list_head *l; struct list_head *l;
int len = 0;
read_lock(&capidev_list_lock); read_lock(&capidev_list_lock);
list_for_each(l, &capidev_list) { list_for_each(l, &capidev_list) {
cdev = list_entry(l, struct capidev, list); cdev = list_entry(l, struct capidev, list);
for (np=cdev->nccis; np; np = np->next) { for (np=cdev->nccis; np; np = np->next) {
len += sprintf(page+len, "%d 0x%x\n", seq_printf(m, "%d 0x%x\n",
cdev->ap.applid, cdev->ap.applid,
np->ncci); np->ncci);
if (len <= off) {
off -= len;
len = 0;
} else {
if (len-off > count)
goto endloop;
}
} }
} }
endloop:
read_unlock(&capidev_list_lock); read_unlock(&capidev_list_lock);
*start = page+off; return 0;
if (len < count)
*eof = 1;
if (len>count) len = count;
if (len<0) len = 0;
return len;
} }
static struct procfsentries { static int capi20ncci_proc_open(struct inode *inode, struct file *file)
char *name; {
mode_t mode; return single_open(file, capi20ncci_proc_show, NULL);
int (*read_proc)(char *page, char **start, off_t off, }
int count, int *eof, void *data);
struct proc_dir_entry *procent; static const struct file_operations capi20ncci_proc_fops = {
} procfsentries[] = { .owner = THIS_MODULE,
/* { "capi", S_IFDIR, 0 }, */ .open = capi20ncci_proc_open,
{ "capi/capi20", 0 , proc_capidev_read_proc }, .read = seq_read,
{ "capi/capi20ncci", 0 , proc_capincci_read_proc }, .llseek = seq_lseek,
.release = single_release,
}; };
static void __init proc_init(void) static void __init proc_init(void)
{ {
int nelem = ARRAY_SIZE(procfsentries); proc_create("capi/capi20", 0, NULL, &capi20_proc_fops);
int i; proc_create("capi/capi20ncci", 0, NULL, &capi20ncci_proc_fops);
for (i=0; i < nelem; i++) {
struct procfsentries *p = procfsentries + i;
p->procent = create_proc_entry(p->name, p->mode, NULL);
if (p->procent) p->procent->read_proc = p->read_proc;
}
} }
static void __exit proc_exit(void) static void __exit proc_exit(void)
{ {
int nelem = ARRAY_SIZE(procfsentries); remove_proc_entry("capi/capi20", NULL);
int i; remove_proc_entry("capi/capi20ncci", NULL);
for (i=nelem-1; i >= 0; i--) {
struct procfsentries *p = procfsentries + i;
if (p->procent) {
remove_proc_entry(p->name, NULL);
p->procent = NULL;
}
}
} }
/* -------- init function and module interface ---------------------- */ /* -------- init function and module interface ---------------------- */

View File

@ -24,6 +24,7 @@
#include <linux/isdn.h> #include <linux/isdn.h>
#include <linux/isdnif.h> #include <linux/isdnif.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/capi.h> #include <linux/capi.h>
#include <linux/kernelcapi.h> #include <linux/kernelcapi.h>
#include <linux/ctype.h> #include <linux/ctype.h>
@ -2229,59 +2230,37 @@ static void lower_callback(unsigned int cmd, u32 contr, void *data)
* /proc/capi/capidrv: * /proc/capi/capidrv:
* nrecvctlpkt nrecvdatapkt nsendctlpkt nsenddatapkt * nrecvctlpkt nrecvdatapkt nsendctlpkt nsenddatapkt
*/ */
static int proc_capidrv_read_proc(char *page, char **start, off_t off, static int capidrv_proc_show(struct seq_file *m, void *v)
int count, int *eof, void *data)
{ {
int len = 0; seq_printf(m, "%lu %lu %lu %lu\n",
len += sprintf(page+len, "%lu %lu %lu %lu\n",
global.ap.nrecvctlpkt, global.ap.nrecvctlpkt,
global.ap.nrecvdatapkt, global.ap.nrecvdatapkt,
global.ap.nsentctlpkt, global.ap.nsentctlpkt,
global.ap.nsentdatapkt); global.ap.nsentdatapkt);
if (off+count >= len) return 0;
*eof = 1;
if (len < off)
return 0;
*start = page + off;
return ((count < len-off) ? count : len-off);
} }
static struct procfsentries { static int capidrv_proc_open(struct inode *inode, struct file *file)
char *name; {
mode_t mode; return single_open(file, capidrv_proc_show, NULL);
int (*read_proc)(char *page, char **start, off_t off, }
int count, int *eof, void *data);
struct proc_dir_entry *procent; static const struct file_operations capidrv_proc_fops = {
} procfsentries[] = { .owner = THIS_MODULE,
/* { "capi", S_IFDIR, 0 }, */ .open = capidrv_proc_open,
{ "capi/capidrv", 0 , proc_capidrv_read_proc }, .read = seq_read,
.llseek = seq_lseek,
.release = single_release,
}; };
static void __init proc_init(void) static void __init proc_init(void)
{ {
int nelem = ARRAY_SIZE(procfsentries); proc_create("capi/capidrv", 0, NULL, &capidrv_proc_fops);
int i;
for (i=0; i < nelem; i++) {
struct procfsentries *p = procfsentries + i;
p->procent = create_proc_entry(p->name, p->mode, NULL);
if (p->procent) p->procent->read_proc = p->read_proc;
}
} }
static void __exit proc_exit(void) static void __exit proc_exit(void)
{ {
int nelem = ARRAY_SIZE(procfsentries); remove_proc_entry("capi/capidrv", NULL);
int i;
for (i=nelem-1; i >= 0; i--) {
struct procfsentries *p = procfsentries + i;
if (p->procent) {
remove_proc_entry(p->name, NULL);
p->procent = NULL;
}
}
} }
static int __init capidrv_init(void) static int __init capidrv_init(void)

View File

@ -490,13 +490,7 @@ attach_capi_ctr(struct capi_ctr *card)
card->traceflag = showcapimsgs; card->traceflag = showcapimsgs;
sprintf(card->procfn, "capi/controllers/%d", card->cnr); sprintf(card->procfn, "capi/controllers/%d", card->cnr);
card->procent = create_proc_entry(card->procfn, 0, NULL); card->procent = proc_create_data(card->procfn, 0, NULL, card->proc_fops, card);
if (card->procent) {
card->procent->read_proc =
(int (*)(char *,char **,off_t,int,int *,void *))
card->ctr_read_proc;
card->procent->data = card;
}
ncards++; ncards++;
printk(KERN_NOTICE "kcapi: Controller [%03d]: %s attached\n", printk(KERN_NOTICE "kcapi: Controller [%03d]: %s attached\n",

View File

@ -13,6 +13,8 @@
#include "gigaset.h" #include "gigaset.h"
#include <linux/ctype.h> #include <linux/ctype.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/isdn/capilli.h> #include <linux/isdn/capilli.h>
#include <linux/isdn/capicmd.h> #include <linux/isdn/capicmd.h>
#include <linux/isdn/capiutil.h> #include <linux/isdn/capiutil.h>
@ -2106,35 +2108,22 @@ static char *gigaset_procinfo(struct capi_ctr *ctr)
return ctr->name; /* ToDo: more? */ return ctr->name; /* ToDo: more? */
} }
/** static int gigaset_proc_show(struct seq_file *m, void *v)
* gigaset_ctr_read_proc() - build controller proc file entry
* @page: buffer of PAGE_SIZE bytes for receiving the entry.
* @start: unused.
* @off: unused.
* @count: unused.
* @eof: unused.
* @ctr: controller descriptor structure.
*
* Return value: length of generated entry
*/
static int gigaset_ctr_read_proc(char *page, char **start, off_t off,
int count, int *eof, struct capi_ctr *ctr)
{ {
struct capi_ctr *ctr = m->private;
struct cardstate *cs = ctr->driverdata; struct cardstate *cs = ctr->driverdata;
char *s; char *s;
int i; int i;
int len = 0;
len += sprintf(page+len, "%-16s %s\n", "name", ctr->name); seq_printf(m, "%-16s %s\n", "name", ctr->name);
len += sprintf(page+len, "%-16s %s %s\n", "dev", seq_printf(m, "%-16s %s %s\n", "dev",
dev_driver_string(cs->dev), dev_name(cs->dev)); dev_driver_string(cs->dev), dev_name(cs->dev));
len += sprintf(page+len, "%-16s %d\n", "id", cs->myid); seq_printf(m, "%-16s %d\n", "id", cs->myid);
if (cs->gotfwver) if (cs->gotfwver)
len += sprintf(page+len, "%-16s %d.%d.%d.%d\n", "firmware", seq_printf(m, "%-16s %d.%d.%d.%d\n", "firmware",
cs->fwver[0], cs->fwver[1], cs->fwver[2], cs->fwver[3]); cs->fwver[0], cs->fwver[1], cs->fwver[2], cs->fwver[3]);
len += sprintf(page+len, "%-16s %d\n", "channels", seq_printf(m, "%-16s %d\n", "channels", cs->channels);
cs->channels); seq_printf(m, "%-16s %s\n", "onechannel", cs->onechannel ? "yes" : "no");
len += sprintf(page+len, "%-16s %s\n", "onechannel",
cs->onechannel ? "yes" : "no");
switch (cs->mode) { switch (cs->mode) {
case M_UNKNOWN: case M_UNKNOWN:
@ -2152,7 +2141,7 @@ static int gigaset_ctr_read_proc(char *page, char **start, off_t off,
default: default:
s = "??"; s = "??";
} }
len += sprintf(page+len, "%-16s %s\n", "mode", s); seq_printf(m, "%-16s %s\n", "mode", s);
switch (cs->mstate) { switch (cs->mstate) {
case MS_UNINITIALIZED: case MS_UNINITIALIZED:
@ -2176,25 +2165,21 @@ static int gigaset_ctr_read_proc(char *page, char **start, off_t off,
default: default:
s = "??"; s = "??";
} }
len += sprintf(page+len, "%-16s %s\n", "mstate", s); seq_printf(m, "%-16s %s\n", "mstate", s);
len += sprintf(page+len, "%-16s %s\n", "running", seq_printf(m, "%-16s %s\n", "running", cs->running ? "yes" : "no");
cs->running ? "yes" : "no"); seq_printf(m, "%-16s %s\n", "connected", cs->connected ? "yes" : "no");
len += sprintf(page+len, "%-16s %s\n", "connected", seq_printf(m, "%-16s %s\n", "isdn_up", cs->isdn_up ? "yes" : "no");
cs->connected ? "yes" : "no"); seq_printf(m, "%-16s %s\n", "cidmode", cs->cidmode ? "yes" : "no");
len += sprintf(page+len, "%-16s %s\n", "isdn_up",
cs->isdn_up ? "yes" : "no");
len += sprintf(page+len, "%-16s %s\n", "cidmode",
cs->cidmode ? "yes" : "no");
for (i = 0; i < cs->channels; i++) { for (i = 0; i < cs->channels; i++) {
len += sprintf(page+len, "[%d]%-13s %d\n", i, "corrupted", seq_printf(m, "[%d]%-13s %d\n", i, "corrupted",
cs->bcs[i].corrupted); cs->bcs[i].corrupted);
len += sprintf(page+len, "[%d]%-13s %d\n", i, "trans_down", seq_printf(m, "[%d]%-13s %d\n", i, "trans_down",
cs->bcs[i].trans_down); cs->bcs[i].trans_down);
len += sprintf(page+len, "[%d]%-13s %d\n", i, "trans_up", seq_printf(m, "[%d]%-13s %d\n", i, "trans_up",
cs->bcs[i].trans_up); cs->bcs[i].trans_up);
len += sprintf(page+len, "[%d]%-13s %d\n", i, "chstate", seq_printf(m, "[%d]%-13s %d\n", i, "chstate",
cs->bcs[i].chstate); cs->bcs[i].chstate);
switch (cs->bcs[i].proto2) { switch (cs->bcs[i].proto2) {
case L2_BITSYNC: case L2_BITSYNC:
@ -2209,11 +2194,23 @@ static int gigaset_ctr_read_proc(char *page, char **start, off_t off,
default: default:
s = "??"; s = "??";
} }
len += sprintf(page+len, "[%d]%-13s %s\n", i, "proto2", s); seq_printf(m, "[%d]%-13s %s\n", i, "proto2", s);
} }
return len; return 0;
} }
static int gigaset_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, gigaset_proc_show, PDE(inode)->data);
}
static const struct file_operations gigaset_proc_fops = {
.owner = THIS_MODULE,
.open = gigaset_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static struct capi_driver capi_driver_gigaset = { static struct capi_driver capi_driver_gigaset = {
.name = "gigaset", .name = "gigaset",
@ -2256,7 +2253,7 @@ int gigaset_isdn_register(struct cardstate *cs, const char *isdnid)
iif->ctr.release_appl = gigaset_release_appl; iif->ctr.release_appl = gigaset_release_appl;
iif->ctr.send_message = gigaset_send_message; iif->ctr.send_message = gigaset_send_message;
iif->ctr.procinfo = gigaset_procinfo; iif->ctr.procinfo = gigaset_procinfo;
iif->ctr.ctr_read_proc = gigaset_ctr_read_proc; iif->ctr.proc_fops = &gigaset_proc_fops;
INIT_LIST_HEAD(&iif->appls); INIT_LIST_HEAD(&iif->appls);
skb_queue_head_init(&iif->sendqueue); skb_queue_head_init(&iif->sendqueue);
atomic_set(&iif->sendqlen, 0); atomic_set(&iif->sendqlen, 0);

View File

@ -556,8 +556,7 @@ u16 b1_send_message(struct capi_ctr *ctrl, struct sk_buff *skb);
void b1_parse_version(avmctrl_info *card); void b1_parse_version(avmctrl_info *card);
irqreturn_t b1_interrupt(int interrupt, void *devptr); irqreturn_t b1_interrupt(int interrupt, void *devptr);
int b1ctl_read_proc(char *page, char **start, off_t off, extern const struct file_operations b1ctl_proc_fops;
int count, int *eof, struct capi_ctr *ctrl);
avmcard_dmainfo *avmcard_dma_alloc(char *name, struct pci_dev *, avmcard_dmainfo *avmcard_dma_alloc(char *name, struct pci_dev *,
long rsize, long ssize); long rsize, long ssize);
@ -577,7 +576,6 @@ void b1dma_register_appl(struct capi_ctr *ctrl,
capi_register_params *rp); capi_register_params *rp);
void b1dma_release_appl(struct capi_ctr *ctrl, u16 appl); void b1dma_release_appl(struct capi_ctr *ctrl, u16 appl);
u16 b1dma_send_message(struct capi_ctr *ctrl, struct sk_buff *skb); u16 b1dma_send_message(struct capi_ctr *ctrl, struct sk_buff *skb);
int b1dmactl_read_proc(char *page, char **start, off_t off, extern const struct file_operations b1dmactl_proc_fops;
int count, int *eof, struct capi_ctr *ctrl);
#endif /* _AVMCARD_H_ */ #endif /* _AVMCARD_H_ */

View File

@ -12,6 +12,8 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/mm.h> #include <linux/mm.h>
@ -634,18 +636,17 @@ irqreturn_t b1_interrupt(int interrupt, void *devptr)
} }
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
int b1ctl_read_proc(char *page, char **start, off_t off, static int b1ctl_proc_show(struct seq_file *m, void *v)
int count, int *eof, struct capi_ctr *ctrl)
{ {
struct capi_ctr *ctrl = m->private;
avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
avmcard *card = cinfo->card; avmcard *card = cinfo->card;
u8 flag; u8 flag;
int len = 0;
char *s; char *s;
len += sprintf(page+len, "%-16s %s\n", "name", card->name); seq_printf(m, "%-16s %s\n", "name", card->name);
len += sprintf(page+len, "%-16s 0x%x\n", "io", card->port); seq_printf(m, "%-16s 0x%x\n", "io", card->port);
len += sprintf(page+len, "%-16s %d\n", "irq", card->irq); seq_printf(m, "%-16s %d\n", "irq", card->irq);
switch (card->cardtype) { switch (card->cardtype) {
case avm_b1isa: s = "B1 ISA"; break; case avm_b1isa: s = "B1 ISA"; break;
case avm_b1pci: s = "B1 PCI"; break; case avm_b1pci: s = "B1 PCI"; break;
@ -658,20 +659,20 @@ int b1ctl_read_proc(char *page, char **start, off_t off,
case avm_c2: s = "C2"; break; case avm_c2: s = "C2"; break;
default: s = "???"; break; default: s = "???"; break;
} }
len += sprintf(page+len, "%-16s %s\n", "type", s); seq_printf(m, "%-16s %s\n", "type", s);
if (card->cardtype == avm_t1isa) if (card->cardtype == avm_t1isa)
len += sprintf(page+len, "%-16s %d\n", "cardnr", card->cardnr); seq_printf(m, "%-16s %d\n", "cardnr", card->cardnr);
if ((s = cinfo->version[VER_DRIVER]) != NULL) if ((s = cinfo->version[VER_DRIVER]) != NULL)
len += sprintf(page+len, "%-16s %s\n", "ver_driver", s); seq_printf(m, "%-16s %s\n", "ver_driver", s);
if ((s = cinfo->version[VER_CARDTYPE]) != NULL) if ((s = cinfo->version[VER_CARDTYPE]) != NULL)
len += sprintf(page+len, "%-16s %s\n", "ver_cardtype", s); seq_printf(m, "%-16s %s\n", "ver_cardtype", s);
if ((s = cinfo->version[VER_SERIAL]) != NULL) if ((s = cinfo->version[VER_SERIAL]) != NULL)
len += sprintf(page+len, "%-16s %s\n", "ver_serial", s); seq_printf(m, "%-16s %s\n", "ver_serial", s);
if (card->cardtype != avm_m1) { if (card->cardtype != avm_m1) {
flag = ((u8 *)(ctrl->profile.manu))[3]; flag = ((u8 *)(ctrl->profile.manu))[3];
if (flag) if (flag)
len += sprintf(page+len, "%-16s%s%s%s%s%s%s%s\n", seq_printf(m, "%-16s%s%s%s%s%s%s%s\n",
"protocol", "protocol",
(flag & 0x01) ? " DSS1" : "", (flag & 0x01) ? " DSS1" : "",
(flag & 0x02) ? " CT1" : "", (flag & 0x02) ? " CT1" : "",
@ -685,7 +686,7 @@ int b1ctl_read_proc(char *page, char **start, off_t off,
if (card->cardtype != avm_m1) { if (card->cardtype != avm_m1) {
flag = ((u8 *)(ctrl->profile.manu))[5]; flag = ((u8 *)(ctrl->profile.manu))[5];
if (flag) if (flag)
len += sprintf(page+len, "%-16s%s%s%s%s\n", seq_printf(m, "%-16s%s%s%s%s\n",
"linetype", "linetype",
(flag & 0x01) ? " point to point" : "", (flag & 0x01) ? " point to point" : "",
(flag & 0x02) ? " point to multipoint" : "", (flag & 0x02) ? " point to multipoint" : "",
@ -693,16 +694,25 @@ int b1ctl_read_proc(char *page, char **start, off_t off,
(flag & 0x04) ? " leased line with D-channel" : "" (flag & 0x04) ? " leased line with D-channel" : ""
); );
} }
len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname); seq_printf(m, "%-16s %s\n", "cardname", cinfo->cardname);
if (off+count >= len) return 0;
*eof = 1;
if (len < off)
return 0;
*start = page + off;
return ((count < len-off) ? count : len-off);
} }
static int b1ctl_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, b1ctl_proc_show, PDE(inode)->data);
}
const struct file_operations b1ctl_proc_fops = {
.owner = THIS_MODULE,
.open = b1ctl_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
EXPORT_SYMBOL(b1ctl_proc_fops);
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
@ -781,8 +791,6 @@ EXPORT_SYMBOL(b1_send_message);
EXPORT_SYMBOL(b1_parse_version); EXPORT_SYMBOL(b1_parse_version);
EXPORT_SYMBOL(b1_interrupt); EXPORT_SYMBOL(b1_interrupt);
EXPORT_SYMBOL(b1ctl_read_proc);
static int __init b1_init(void) static int __init b1_init(void)
{ {
char *p; char *p;

View File

@ -11,6 +11,8 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/mm.h> #include <linux/mm.h>
@ -855,21 +857,20 @@ u16 b1dma_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
int b1dmactl_read_proc(char *page, char **start, off_t off, static int b1dmactl_proc_show(struct seq_file *m, void *v)
int count, int *eof, struct capi_ctr *ctrl)
{ {
struct capi_ctr *ctrl = m->private;
avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
avmcard *card = cinfo->card; avmcard *card = cinfo->card;
u8 flag; u8 flag;
int len = 0;
char *s; char *s;
u32 txoff, txlen, rxoff, rxlen, csr; u32 txoff, txlen, rxoff, rxlen, csr;
unsigned long flags; unsigned long flags;
len += sprintf(page+len, "%-16s %s\n", "name", card->name); seq_printf(m, "%-16s %s\n", "name", card->name);
len += sprintf(page+len, "%-16s 0x%x\n", "io", card->port); seq_printf(m, "%-16s 0x%x\n", "io", card->port);
len += sprintf(page+len, "%-16s %d\n", "irq", card->irq); seq_printf(m, "%-16s %d\n", "irq", card->irq);
len += sprintf(page+len, "%-16s 0x%lx\n", "membase", card->membase); seq_printf(m, "%-16s 0x%lx\n", "membase", card->membase);
switch (card->cardtype) { switch (card->cardtype) {
case avm_b1isa: s = "B1 ISA"; break; case avm_b1isa: s = "B1 ISA"; break;
case avm_b1pci: s = "B1 PCI"; break; case avm_b1pci: s = "B1 PCI"; break;
@ -882,18 +883,18 @@ int b1dmactl_read_proc(char *page, char **start, off_t off,
case avm_c2: s = "C2"; break; case avm_c2: s = "C2"; break;
default: s = "???"; break; default: s = "???"; break;
} }
len += sprintf(page+len, "%-16s %s\n", "type", s); seq_printf(m, "%-16s %s\n", "type", s);
if ((s = cinfo->version[VER_DRIVER]) != NULL) if ((s = cinfo->version[VER_DRIVER]) != NULL)
len += sprintf(page+len, "%-16s %s\n", "ver_driver", s); seq_printf(m, "%-16s %s\n", "ver_driver", s);
if ((s = cinfo->version[VER_CARDTYPE]) != NULL) if ((s = cinfo->version[VER_CARDTYPE]) != NULL)
len += sprintf(page+len, "%-16s %s\n", "ver_cardtype", s); seq_printf(m, "%-16s %s\n", "ver_cardtype", s);
if ((s = cinfo->version[VER_SERIAL]) != NULL) if ((s = cinfo->version[VER_SERIAL]) != NULL)
len += sprintf(page+len, "%-16s %s\n", "ver_serial", s); seq_printf(m, "%-16s %s\n", "ver_serial", s);
if (card->cardtype != avm_m1) { if (card->cardtype != avm_m1) {
flag = ((u8 *)(ctrl->profile.manu))[3]; flag = ((u8 *)(ctrl->profile.manu))[3];
if (flag) if (flag)
len += sprintf(page+len, "%-16s%s%s%s%s%s%s%s\n", seq_printf(m, "%-16s%s%s%s%s%s%s%s\n",
"protocol", "protocol",
(flag & 0x01) ? " DSS1" : "", (flag & 0x01) ? " DSS1" : "",
(flag & 0x02) ? " CT1" : "", (flag & 0x02) ? " CT1" : "",
@ -907,7 +908,7 @@ int b1dmactl_read_proc(char *page, char **start, off_t off,
if (card->cardtype != avm_m1) { if (card->cardtype != avm_m1) {
flag = ((u8 *)(ctrl->profile.manu))[5]; flag = ((u8 *)(ctrl->profile.manu))[5];
if (flag) if (flag)
len += sprintf(page+len, "%-16s%s%s%s%s\n", seq_printf(m, "%-16s%s%s%s%s\n",
"linetype", "linetype",
(flag & 0x01) ? " point to point" : "", (flag & 0x01) ? " point to point" : "",
(flag & 0x02) ? " point to multipoint" : "", (flag & 0x02) ? " point to multipoint" : "",
@ -915,7 +916,7 @@ int b1dmactl_read_proc(char *page, char **start, off_t off,
(flag & 0x04) ? " leased line with D-channel" : "" (flag & 0x04) ? " leased line with D-channel" : ""
); );
} }
len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname); seq_printf(m, "%-16s %s\n", "cardname", cinfo->cardname);
spin_lock_irqsave(&card->lock, flags); spin_lock_irqsave(&card->lock, flags);
@ -930,27 +931,30 @@ int b1dmactl_read_proc(char *page, char **start, off_t off,
spin_unlock_irqrestore(&card->lock, flags); spin_unlock_irqrestore(&card->lock, flags);
len += sprintf(page+len, "%-16s 0x%lx\n", seq_printf(m, "%-16s 0x%lx\n", "csr (cached)", (unsigned long)card->csr);
"csr (cached)", (unsigned long)card->csr); seq_printf(m, "%-16s 0x%lx\n", "csr", (unsigned long)csr);
len += sprintf(page+len, "%-16s 0x%lx\n", seq_printf(m, "%-16s %lu\n", "txoff", (unsigned long)txoff);
"csr", (unsigned long)csr); seq_printf(m, "%-16s %lu\n", "txlen", (unsigned long)txlen);
len += sprintf(page+len, "%-16s %lu\n", seq_printf(m, "%-16s %lu\n", "rxoff", (unsigned long)rxoff);
"txoff", (unsigned long)txoff); seq_printf(m, "%-16s %lu\n", "rxlen", (unsigned long)rxlen);
len += sprintf(page+len, "%-16s %lu\n",
"txlen", (unsigned long)txlen);
len += sprintf(page+len, "%-16s %lu\n",
"rxoff", (unsigned long)rxoff);
len += sprintf(page+len, "%-16s %lu\n",
"rxlen", (unsigned long)rxlen);
if (off+count >= len) return 0;
*eof = 1;
if (len < off)
return 0;
*start = page + off;
return ((count < len-off) ? count : len-off);
} }
static int b1dmactl_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, b1dmactl_proc_show, PDE(inode)->data);
}
const struct file_operations b1dmactl_proc_fops = {
.owner = THIS_MODULE,
.open = b1dmactl_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
EXPORT_SYMBOL(b1dmactl_proc_fops);
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
EXPORT_SYMBOL(b1dma_reset); EXPORT_SYMBOL(b1dma_reset);
@ -963,7 +967,6 @@ EXPORT_SYMBOL(b1dma_reset_ctr);
EXPORT_SYMBOL(b1dma_register_appl); EXPORT_SYMBOL(b1dma_register_appl);
EXPORT_SYMBOL(b1dma_release_appl); EXPORT_SYMBOL(b1dma_release_appl);
EXPORT_SYMBOL(b1dma_send_message); EXPORT_SYMBOL(b1dma_send_message);
EXPORT_SYMBOL(b1dmactl_read_proc);
static int __init b1dma_init(void) static int __init b1dma_init(void)
{ {

View File

@ -121,7 +121,7 @@ static int b1isa_probe(struct pci_dev *pdev)
cinfo->capi_ctrl.load_firmware = b1_load_firmware; cinfo->capi_ctrl.load_firmware = b1_load_firmware;
cinfo->capi_ctrl.reset_ctr = b1_reset_ctr; cinfo->capi_ctrl.reset_ctr = b1_reset_ctr;
cinfo->capi_ctrl.procinfo = b1isa_procinfo; cinfo->capi_ctrl.procinfo = b1isa_procinfo;
cinfo->capi_ctrl.ctr_read_proc = b1ctl_read_proc; cinfo->capi_ctrl.proc_fops = &b1ctl_proc_fops;
strcpy(cinfo->capi_ctrl.name, card->name); strcpy(cinfo->capi_ctrl.name, card->name);
retval = attach_capi_ctr(&cinfo->capi_ctrl); retval = attach_capi_ctr(&cinfo->capi_ctrl);

View File

@ -112,7 +112,7 @@ static int b1pci_probe(struct capicardparams *p, struct pci_dev *pdev)
cinfo->capi_ctrl.load_firmware = b1_load_firmware; cinfo->capi_ctrl.load_firmware = b1_load_firmware;
cinfo->capi_ctrl.reset_ctr = b1_reset_ctr; cinfo->capi_ctrl.reset_ctr = b1_reset_ctr;
cinfo->capi_ctrl.procinfo = b1pci_procinfo; cinfo->capi_ctrl.procinfo = b1pci_procinfo;
cinfo->capi_ctrl.ctr_read_proc = b1ctl_read_proc; cinfo->capi_ctrl.proc_fops = &b1ctl_proc_fops;
strcpy(cinfo->capi_ctrl.name, card->name); strcpy(cinfo->capi_ctrl.name, card->name);
cinfo->capi_ctrl.owner = THIS_MODULE; cinfo->capi_ctrl.owner = THIS_MODULE;
@ -251,7 +251,7 @@ static int b1pciv4_probe(struct capicardparams *p, struct pci_dev *pdev)
cinfo->capi_ctrl.load_firmware = b1dma_load_firmware; cinfo->capi_ctrl.load_firmware = b1dma_load_firmware;
cinfo->capi_ctrl.reset_ctr = b1dma_reset_ctr; cinfo->capi_ctrl.reset_ctr = b1dma_reset_ctr;
cinfo->capi_ctrl.procinfo = b1pciv4_procinfo; cinfo->capi_ctrl.procinfo = b1pciv4_procinfo;
cinfo->capi_ctrl.ctr_read_proc = b1dmactl_read_proc; cinfo->capi_ctrl.proc_fops = &b1dmactl_proc_fops;
strcpy(cinfo->capi_ctrl.name, card->name); strcpy(cinfo->capi_ctrl.name, card->name);
retval = attach_capi_ctr(&cinfo->capi_ctrl); retval = attach_capi_ctr(&cinfo->capi_ctrl);

View File

@ -108,7 +108,7 @@ static int b1pcmcia_add_card(unsigned int port, unsigned irq,
cinfo->capi_ctrl.load_firmware = b1_load_firmware; cinfo->capi_ctrl.load_firmware = b1_load_firmware;
cinfo->capi_ctrl.reset_ctr = b1_reset_ctr; cinfo->capi_ctrl.reset_ctr = b1_reset_ctr;
cinfo->capi_ctrl.procinfo = b1pcmcia_procinfo; cinfo->capi_ctrl.procinfo = b1pcmcia_procinfo;
cinfo->capi_ctrl.ctr_read_proc = b1ctl_read_proc; cinfo->capi_ctrl.proc_fops = &b1ctl_proc_fops;
strcpy(cinfo->capi_ctrl.name, card->name); strcpy(cinfo->capi_ctrl.name, card->name);
retval = attach_capi_ctr(&cinfo->capi_ctrl); retval = attach_capi_ctr(&cinfo->capi_ctrl);

View File

@ -11,6 +11,8 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/mm.h> #include <linux/mm.h>
@ -1062,19 +1064,18 @@ static char *c4_procinfo(struct capi_ctr *ctrl)
return cinfo->infobuf; return cinfo->infobuf;
} }
static int c4_read_proc(char *page, char **start, off_t off, static int c4_proc_show(struct seq_file *m, void *v)
int count, int *eof, struct capi_ctr *ctrl)
{ {
struct capi_ctr *ctrl = m->private;
avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
avmcard *card = cinfo->card; avmcard *card = cinfo->card;
u8 flag; u8 flag;
int len = 0;
char *s; char *s;
len += sprintf(page+len, "%-16s %s\n", "name", card->name); seq_printf(m, "%-16s %s\n", "name", card->name);
len += sprintf(page+len, "%-16s 0x%x\n", "io", card->port); seq_printf(m, "%-16s 0x%x\n", "io", card->port);
len += sprintf(page+len, "%-16s %d\n", "irq", card->irq); seq_printf(m, "%-16s %d\n", "irq", card->irq);
len += sprintf(page+len, "%-16s 0x%lx\n", "membase", card->membase); seq_printf(m, "%-16s 0x%lx\n", "membase", card->membase);
switch (card->cardtype) { switch (card->cardtype) {
case avm_b1isa: s = "B1 ISA"; break; case avm_b1isa: s = "B1 ISA"; break;
case avm_b1pci: s = "B1 PCI"; break; case avm_b1pci: s = "B1 PCI"; break;
@ -1087,18 +1088,18 @@ static int c4_read_proc(char *page, char **start, off_t off,
case avm_c2: s = "C2"; break; case avm_c2: s = "C2"; break;
default: s = "???"; break; default: s = "???"; break;
} }
len += sprintf(page+len, "%-16s %s\n", "type", s); seq_printf(m, "%-16s %s\n", "type", s);
if ((s = cinfo->version[VER_DRIVER]) != NULL) if ((s = cinfo->version[VER_DRIVER]) != NULL)
len += sprintf(page+len, "%-16s %s\n", "ver_driver", s); seq_printf(m, "%-16s %s\n", "ver_driver", s);
if ((s = cinfo->version[VER_CARDTYPE]) != NULL) if ((s = cinfo->version[VER_CARDTYPE]) != NULL)
len += sprintf(page+len, "%-16s %s\n", "ver_cardtype", s); seq_printf(m, "%-16s %s\n", "ver_cardtype", s);
if ((s = cinfo->version[VER_SERIAL]) != NULL) if ((s = cinfo->version[VER_SERIAL]) != NULL)
len += sprintf(page+len, "%-16s %s\n", "ver_serial", s); seq_printf(m, "%-16s %s\n", "ver_serial", s);
if (card->cardtype != avm_m1) { if (card->cardtype != avm_m1) {
flag = ((u8 *)(ctrl->profile.manu))[3]; flag = ((u8 *)(ctrl->profile.manu))[3];
if (flag) if (flag)
len += sprintf(page+len, "%-16s%s%s%s%s%s%s%s\n", seq_printf(m, "%-16s%s%s%s%s%s%s%s\n",
"protocol", "protocol",
(flag & 0x01) ? " DSS1" : "", (flag & 0x01) ? " DSS1" : "",
(flag & 0x02) ? " CT1" : "", (flag & 0x02) ? " CT1" : "",
@ -1112,7 +1113,7 @@ static int c4_read_proc(char *page, char **start, off_t off,
if (card->cardtype != avm_m1) { if (card->cardtype != avm_m1) {
flag = ((u8 *)(ctrl->profile.manu))[5]; flag = ((u8 *)(ctrl->profile.manu))[5];
if (flag) if (flag)
len += sprintf(page+len, "%-16s%s%s%s%s\n", seq_printf(m, "%-16s%s%s%s%s\n",
"linetype", "linetype",
(flag & 0x01) ? " point to point" : "", (flag & 0x01) ? " point to point" : "",
(flag & 0x02) ? " point to multipoint" : "", (flag & 0x02) ? " point to multipoint" : "",
@ -1120,16 +1121,24 @@ static int c4_read_proc(char *page, char **start, off_t off,
(flag & 0x04) ? " leased line with D-channel" : "" (flag & 0x04) ? " leased line with D-channel" : ""
); );
} }
len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname); seq_printf(m, "%-16s %s\n", "cardname", cinfo->cardname);
if (off+count >= len) return 0;
*eof = 1;
if (len < off)
return 0;
*start = page + off;
return ((count < len-off) ? count : len-off);
} }
static int c4_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, c4_proc_show, PDE(inode)->data);
}
static const struct file_operations c4_proc_fops = {
.owner = THIS_MODULE,
.open = c4_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
static int c4_add_card(struct capicardparams *p, struct pci_dev *dev, static int c4_add_card(struct capicardparams *p, struct pci_dev *dev,
@ -1201,7 +1210,7 @@ static int c4_add_card(struct capicardparams *p, struct pci_dev *dev,
cinfo->capi_ctrl.load_firmware = c4_load_firmware; cinfo->capi_ctrl.load_firmware = c4_load_firmware;
cinfo->capi_ctrl.reset_ctr = c4_reset_ctr; cinfo->capi_ctrl.reset_ctr = c4_reset_ctr;
cinfo->capi_ctrl.procinfo = c4_procinfo; cinfo->capi_ctrl.procinfo = c4_procinfo;
cinfo->capi_ctrl.ctr_read_proc = c4_read_proc; cinfo->capi_ctrl.proc_fops = &c4_proc_fops;
strcpy(cinfo->capi_ctrl.name, card->name); strcpy(cinfo->capi_ctrl.name, card->name);
retval = attach_capi_ctr(&cinfo->capi_ctrl); retval = attach_capi_ctr(&cinfo->capi_ctrl);

View File

@ -429,7 +429,7 @@ static int t1isa_probe(struct pci_dev *pdev, int cardnr)
cinfo->capi_ctrl.load_firmware = t1isa_load_firmware; cinfo->capi_ctrl.load_firmware = t1isa_load_firmware;
cinfo->capi_ctrl.reset_ctr = t1isa_reset_ctr; cinfo->capi_ctrl.reset_ctr = t1isa_reset_ctr;
cinfo->capi_ctrl.procinfo = t1isa_procinfo; cinfo->capi_ctrl.procinfo = t1isa_procinfo;
cinfo->capi_ctrl.ctr_read_proc = b1ctl_read_proc; cinfo->capi_ctrl.proc_fops = &b1ctl_proc_fops;
strcpy(cinfo->capi_ctrl.name, card->name); strcpy(cinfo->capi_ctrl.name, card->name);
retval = attach_capi_ctr(&cinfo->capi_ctrl); retval = attach_capi_ctr(&cinfo->capi_ctrl);

View File

@ -119,7 +119,7 @@ static int t1pci_add_card(struct capicardparams *p, struct pci_dev *pdev)
cinfo->capi_ctrl.load_firmware = b1dma_load_firmware; cinfo->capi_ctrl.load_firmware = b1dma_load_firmware;
cinfo->capi_ctrl.reset_ctr = b1dma_reset_ctr; cinfo->capi_ctrl.reset_ctr = b1dma_reset_ctr;
cinfo->capi_ctrl.procinfo = t1pci_procinfo; cinfo->capi_ctrl.procinfo = t1pci_procinfo;
cinfo->capi_ctrl.ctr_read_proc = b1dmactl_read_proc; cinfo->capi_ctrl.proc_fops = &b1dmactl_proc_fops;
strcpy(cinfo->capi_ctrl.name, card->name); strcpy(cinfo->capi_ctrl.name, card->name);
retval = attach_capi_ctr(&cinfo->capi_ctrl); retval = attach_capi_ctr(&cinfo->capi_ctrl);

View File

@ -13,6 +13,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <linux/seq_file.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include "os_capi.h" #include "os_capi.h"
@ -75,25 +76,32 @@ void diva_os_free_message_buffer(diva_os_message_buffer_s * dmb)
/* /*
* proc function for controller info * proc function for controller info
*/ */
static int diva_ctl_read_proc(char *page, char **start, off_t off, static int diva_ctl_proc_show(struct seq_file *m, void *v)
int count, int *eof, struct capi_ctr *ctrl)
{ {
struct capi_ctr *ctrl = m->private;
diva_card *card = (diva_card *) ctrl->driverdata; diva_card *card = (diva_card *) ctrl->driverdata;
int len = 0;
len += sprintf(page + len, "%s\n", ctrl->name); seq_printf(m, "%s\n", ctrl->name);
len += sprintf(page + len, "Serial No. : %s\n", ctrl->serial); seq_printf(m, "Serial No. : %s\n", ctrl->serial);
len += sprintf(page + len, "Id : %d\n", card->Id); seq_printf(m, "Id : %d\n", card->Id);
len += sprintf(page + len, "Channels : %d\n", card->d.channels); seq_printf(m, "Channels : %d\n", card->d.channels);
if (off + count >= len) return 0;
*eof = 1;
if (len < off)
return 0;
*start = page + off;
return ((count < len - off) ? count : len - off);
} }
static int diva_ctl_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, diva_ctl_proc_show, NULL);
}
static const struct file_operations diva_ctl_proc_fops = {
.owner = THIS_MODULE,
.open = diva_ctl_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
/* /*
* set additional os settings in capi_ctr struct * set additional os settings in capi_ctr struct
*/ */
@ -102,7 +110,7 @@ void diva_os_set_controller_struct(struct capi_ctr *ctrl)
ctrl->driver_name = DRIVERLNAME; ctrl->driver_name = DRIVERLNAME;
ctrl->load_firmware = NULL; ctrl->load_firmware = NULL;
ctrl->reset_ctr = NULL; ctrl->reset_ctr = NULL;
ctrl->ctr_read_proc = diva_ctl_read_proc; ctrl->proc_fops = &diva_ctl_proc_fops;
ctrl->owner = THIS_MODULE; ctrl->owner = THIS_MODULE;
} }

View File

@ -15,6 +15,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <net/net_namespace.h> #include <net/net_namespace.h>
#include "platform.h" #include "platform.h"
@ -62,39 +63,41 @@ static char *getrev(const char *revision)
return rev; return rev;
} }
static int static int divadidd_proc_show(struct seq_file *m, void *v)
proc_read(char *page, char **start, off_t off, int count, int *eof,
void *data)
{ {
int len = 0;
char tmprev[32]; char tmprev[32];
strcpy(tmprev, main_revision); strcpy(tmprev, main_revision);
len += sprintf(page + len, "%s\n", DRIVERNAME); seq_printf(m, "%s\n", DRIVERNAME);
len += sprintf(page + len, "name : %s\n", DRIVERLNAME); seq_printf(m, "name : %s\n", DRIVERLNAME);
len += sprintf(page + len, "release : %s\n", DRIVERRELEASE_DIDD); seq_printf(m, "release : %s\n", DRIVERRELEASE_DIDD);
len += sprintf(page + len, "build : %s(%s)\n", seq_printf(m, "build : %s(%s)\n",
diva_didd_common_code_build, DIVA_BUILD); diva_didd_common_code_build, DIVA_BUILD);
len += sprintf(page + len, "revision : %s\n", getrev(tmprev)); seq_printf(m, "revision : %s\n", getrev(tmprev));
if (off + count >= len) return 0;
*eof = 1;
if (len < off)
return 0;
*start = page + off;
return ((count < len - off) ? count : len - off);
} }
static int divadidd_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, divadidd_proc_show, NULL);
}
static const struct file_operations divadidd_proc_fops = {
.owner = THIS_MODULE,
.open = divadidd_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int DIVA_INIT_FUNCTION create_proc(void) static int DIVA_INIT_FUNCTION create_proc(void)
{ {
proc_net_eicon = proc_mkdir("eicon", init_net.proc_net); proc_net_eicon = proc_mkdir("eicon", init_net.proc_net);
if (proc_net_eicon) { if (proc_net_eicon) {
if ((proc_didd = proc_didd = proc_create(DRIVERLNAME, S_IRUGO, proc_net_eicon,
create_proc_entry(DRIVERLNAME, S_IFREG | S_IRUGO, &divadidd_proc_fops);
proc_net_eicon))) {
proc_didd->read_proc = proc_read;
}
return (1); return (1);
} }
return (0); return (0);

View File

@ -17,6 +17,7 @@
#include <linux/poll.h> #include <linux/poll.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/seq_file.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
@ -86,39 +87,40 @@ static void diva_um_timer_function(unsigned long data);
extern struct proc_dir_entry *proc_net_eicon; extern struct proc_dir_entry *proc_net_eicon;
static struct proc_dir_entry *um_idi_proc_entry = NULL; static struct proc_dir_entry *um_idi_proc_entry = NULL;
static int static int um_idi_proc_show(struct seq_file *m, void *v)
um_idi_proc_read(char *page, char **start, off_t off, int count, int *eof,
void *data)
{ {
int len = 0;
char tmprev[32]; char tmprev[32];
len += sprintf(page + len, "%s\n", DRIVERNAME); seq_printf(m, "%s\n", DRIVERNAME);
len += sprintf(page + len, "name : %s\n", DRIVERLNAME); seq_printf(m, "name : %s\n", DRIVERLNAME);
len += sprintf(page + len, "release : %s\n", DRIVERRELEASE_IDI); seq_printf(m, "release : %s\n", DRIVERRELEASE_IDI);
strcpy(tmprev, main_revision); strcpy(tmprev, main_revision);
len += sprintf(page + len, "revision : %s\n", getrev(tmprev)); seq_printf(m, "revision : %s\n", getrev(tmprev));
len += sprintf(page + len, "build : %s\n", DIVA_BUILD); seq_printf(m, "build : %s\n", DIVA_BUILD);
len += sprintf(page + len, "major : %d\n", major); seq_printf(m, "major : %d\n", major);
if (off + count >= len) return 0;
*eof = 1;
if (len < off)
return 0;
*start = page + off;
return ((count < len - off) ? count : len - off);
} }
static int um_idi_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, um_idi_proc_show, NULL);
}
static const struct file_operations um_idi_proc_fops = {
.owner = THIS_MODULE,
.open = um_idi_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int DIVA_INIT_FUNCTION create_um_idi_proc(void) static int DIVA_INIT_FUNCTION create_um_idi_proc(void)
{ {
um_idi_proc_entry = create_proc_entry(DRIVERLNAME, um_idi_proc_entry = proc_create(DRIVERLNAME, S_IRUGO, proc_net_eicon,
S_IFREG | S_IRUGO | S_IWUSR, &um_idi_proc_fops);
proc_net_eicon);
if (!um_idi_proc_entry) if (!um_idi_proc_entry)
return (0); return (0);
um_idi_proc_entry->read_proc = um_idi_proc_read;
return (1); return (1);
} }

View File

@ -14,6 +14,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/poll.h> #include <linux/poll.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/list.h> #include <linux/list.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
@ -141,14 +142,10 @@ void remove_divas_proc(void)
} }
} }
/* static ssize_t grp_opt_proc_write(struct file *file, const char __user *buffer,
** write group_optimization size_t count, loff_t *pos)
*/
static int
write_grp_opt(struct file *file, const char __user *buffer, unsigned long count,
void *data)
{ {
diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) data; diva_os_xdi_adapter_t *a = PDE(file->f_path.dentry->d_inode)->data;
PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1]; PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1];
if ((count == 1) || (count == 2)) { if ((count == 1) || (count == 2)) {
@ -172,14 +169,10 @@ write_grp_opt(struct file *file, const char __user *buffer, unsigned long count,
return (-EINVAL); return (-EINVAL);
} }
/* static ssize_t d_l1_down_proc_write(struct file *file, const char __user *buffer,
** write dynamic_l1_down size_t count, loff_t *pos)
*/
static int
write_d_l1_down(struct file *file, const char __user *buffer, unsigned long count,
void *data)
{ {
diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) data; diva_os_xdi_adapter_t *a = PDE(file->f_path.dentry->d_inode)->data;
PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1]; PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1];
if ((count == 1) || (count == 2)) { if ((count == 1) || (count == 2)) {
@ -203,63 +196,62 @@ write_d_l1_down(struct file *file, const char __user *buffer, unsigned long coun
return (-EINVAL); return (-EINVAL);
} }
static int d_l1_down_proc_show(struct seq_file *m, void *v)
/*
** read dynamic_l1_down
*/
static int
read_d_l1_down(char *page, char **start, off_t off, int count, int *eof,
void *data)
{ {
int len = 0; diva_os_xdi_adapter_t *a = m->private;
diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) data;
PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1]; PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1];
len += sprintf(page + len, "%s\n", seq_printf(m, "%s\n",
(IoAdapter->capi_cfg. (IoAdapter->capi_cfg.
cfg_1 & DIVA_XDI_CAPI_CFG_1_DYNAMIC_L1_ON) ? "1" : cfg_1 & DIVA_XDI_CAPI_CFG_1_DYNAMIC_L1_ON) ? "1" :
"0"); "0");
return 0;
if (off + count >= len)
*eof = 1;
if (len < off)
return 0;
*start = page + off;
return ((count < len - off) ? count : len - off);
} }
/* static int d_l1_down_proc_open(struct inode *inode, struct file *file)
** read group_optimization
*/
static int
read_grp_opt(char *page, char **start, off_t off, int count, int *eof,
void *data)
{ {
int len = 0; return single_open(file, d_l1_down_proc_show, PDE(inode)->data);
diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) data; }
static const struct file_operations d_l1_down_proc_fops = {
.owner = THIS_MODULE,
.open = d_l1_down_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
.write = d_l1_down_proc_write,
};
static int grp_opt_proc_show(struct seq_file *m, void *v)
{
diva_os_xdi_adapter_t *a = m->private;
PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1]; PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1];
len += sprintf(page + len, "%s\n", seq_printf(m, "%s\n",
(IoAdapter->capi_cfg. (IoAdapter->capi_cfg.
cfg_1 & DIVA_XDI_CAPI_CFG_1_GROUP_POPTIMIZATION_ON) cfg_1 & DIVA_XDI_CAPI_CFG_1_GROUP_POPTIMIZATION_ON)
? "1" : "0"); ? "1" : "0");
return 0;
if (off + count >= len)
*eof = 1;
if (len < off)
return 0;
*start = page + off;
return ((count < len - off) ? count : len - off);
} }
/* static int grp_opt_proc_open(struct inode *inode, struct file *file)
** info write
*/
static int
info_write(struct file *file, const char __user *buffer, unsigned long count,
void *data)
{ {
diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) data; return single_open(file, grp_opt_proc_show, PDE(inode)->data);
}
static const struct file_operations grp_opt_proc_fops = {
.owner = THIS_MODULE,
.open = grp_opt_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
.write = grp_opt_proc_write,
};
static ssize_t info_proc_write(struct file *file, const char __user *buffer,
size_t count, loff_t *pos)
{
diva_os_xdi_adapter_t *a = PDE(file->f_path.dentry->d_inode)->data;
PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1]; PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1];
char c[4]; char c[4];
@ -277,63 +269,46 @@ info_write(struct file *file, const char __user *buffer, unsigned long count,
return (-EINVAL); return (-EINVAL);
} }
/* static int info_proc_show(struct seq_file *m, void *v)
** info read
*/
static int
info_read(char *page, char **start, off_t off, int count, int *eof,
void *data)
{ {
int i = 0; int i = 0;
int len = 0;
char *p; char *p;
char tmpser[16]; char tmpser[16];
diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) data; diva_os_xdi_adapter_t *a = m->private;
PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1]; PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1];
len += seq_printf(m, "Name : %s\n", IoAdapter->Properties.Name);
sprintf(page + len, "Name : %s\n", seq_printf(m, "DSP state : %08x\n", a->dsp_mask);
IoAdapter->Properties.Name); seq_printf(m, "Channels : %02d\n", IoAdapter->Properties.Channels);
len += sprintf(page + len, "DSP state : %08x\n", a->dsp_mask); seq_printf(m, "E. max/used : %03d/%03d\n",
len += sprintf(page + len, "Channels : %02d\n",
IoAdapter->Properties.Channels);
len += sprintf(page + len, "E. max/used : %03d/%03d\n",
IoAdapter->e_max, IoAdapter->e_count); IoAdapter->e_max, IoAdapter->e_count);
diva_get_vserial_number(IoAdapter, tmpser); diva_get_vserial_number(IoAdapter, tmpser);
len += sprintf(page + len, "Serial : %s\n", tmpser); seq_printf(m, "Serial : %s\n", tmpser);
len += seq_printf(m, "IRQ : %d\n", IoAdapter->irq_info.irq_nr);
sprintf(page + len, "IRQ : %d\n", seq_printf(m, "CardIndex : %d\n", a->CardIndex);
IoAdapter->irq_info.irq_nr); seq_printf(m, "CardOrdinal : %d\n", a->CardOrdinal);
len += sprintf(page + len, "CardIndex : %d\n", a->CardIndex); seq_printf(m, "Controller : %d\n", a->controller);
len += sprintf(page + len, "CardOrdinal : %d\n", a->CardOrdinal); seq_printf(m, "Bus-Type : %s\n",
len += sprintf(page + len, "Controller : %d\n", a->controller);
len += sprintf(page + len, "Bus-Type : %s\n",
(a->Bus == (a->Bus ==
DIVAS_XDI_ADAPTER_BUS_ISA) ? "ISA" : "PCI"); DIVAS_XDI_ADAPTER_BUS_ISA) ? "ISA" : "PCI");
len += sprintf(page + len, "Port-Name : %s\n", a->port_name); seq_printf(m, "Port-Name : %s\n", a->port_name);
if (a->Bus == DIVAS_XDI_ADAPTER_BUS_PCI) { if (a->Bus == DIVAS_XDI_ADAPTER_BUS_PCI) {
len += seq_printf(m, "PCI-bus : %d\n", a->resources.pci.bus);
sprintf(page + len, "PCI-bus : %d\n", seq_printf(m, "PCI-func : %d\n", a->resources.pci.func);
a->resources.pci.bus);
len +=
sprintf(page + len, "PCI-func : %d\n",
a->resources.pci.func);
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
if (a->resources.pci.bar[i]) { if (a->resources.pci.bar[i]) {
len += seq_printf(m,
sprintf(page + len,
"Mem / I/O %d : 0x%x / mapped : 0x%lx", "Mem / I/O %d : 0x%x / mapped : 0x%lx",
i, a->resources.pci.bar[i], i, a->resources.pci.bar[i],
(unsigned long) a->resources. (unsigned long) a->resources.
pci.addr[i]); pci.addr[i]);
if (a->resources.pci.length[i]) { if (a->resources.pci.length[i]) {
len += seq_printf(m,
sprintf(page + len,
" / length : %d", " / length : %d",
a->resources.pci. a->resources.pci.
length[i]); length[i]);
} }
len += sprintf(page + len, "\n"); seq_putc(m, '\n');
} }
} }
} }
@ -353,16 +328,25 @@ info_read(char *page, char **start, off_t off, int count, int *eof,
} else { } else {
p = "ready"; p = "ready";
} }
len += sprintf(page + len, "State : %s\n", p); seq_printf(m, "State : %s\n", p);
if (off + count >= len) return 0;
*eof = 1;
if (len < off)
return 0;
*start = page + off;
return ((count < len - off) ? count : len - off);
} }
static int info_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, info_proc_show, PDE(inode)->data);
}
static const struct file_operations info_proc_fops = {
.owner = THIS_MODULE,
.open = info_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
.write = info_proc_write,
};
/* /*
** adapter proc init/de-init ** adapter proc init/de-init
*/ */
@ -380,28 +364,20 @@ int create_adapter_proc(diva_os_xdi_adapter_t * a)
return (0); return (0);
a->proc_adapter_dir = (void *) de; a->proc_adapter_dir = (void *) de;
if (!(pe = pe = proc_create_data(info_proc_name, S_IRUGO | S_IWUSR, de,
create_proc_entry(info_proc_name, S_IFREG | S_IRUGO | S_IWUSR, de))) &info_proc_fops, a);
if (!pe)
return (0); return (0);
a->proc_info = (void *) pe; a->proc_info = (void *) pe;
pe->write_proc = info_write;
pe->read_proc = info_read;
pe->data = a;
if ((pe = create_proc_entry(grp_opt_proc_name, pe = proc_create_data(grp_opt_proc_name, S_IRUGO | S_IWUSR, de,
S_IFREG | S_IRUGO | S_IWUSR, de))) { &grp_opt_proc_fops, a);
if (pe)
a->proc_grp_opt = (void *) pe; a->proc_grp_opt = (void *) pe;
pe->write_proc = write_grp_opt; pe = proc_create_data(d_l1_down_proc_name, S_IRUGO | S_IWUSR, de,
pe->read_proc = read_grp_opt; &d_l1_down_proc_fops, a);
pe->data = a; if (pe)
}
if ((pe = create_proc_entry(d_l1_down_proc_name,
S_IFREG | S_IRUGO | S_IWUSR, de))) {
a->proc_d_l1_down = (void *) pe; a->proc_d_l1_down = (void *) pe;
pe->write_proc = write_d_l1_down;
pe->read_proc = read_d_l1_down;
pe->data = a;
}
DBG_TRC(("proc entry %s created", tmp)); DBG_TRC(("proc entry %s created", tmp));

View File

@ -11,6 +11,8 @@
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
@ -432,26 +434,16 @@ static u16 hycapi_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
return retval; return retval;
} }
/********************************************************************* static int hycapi_proc_show(struct seq_file *m, void *v)
hycapi_read_proc
Informations provided in the /proc/capi-entries.
*********************************************************************/
static int hycapi_read_proc(char *page, char **start, off_t off,
int count, int *eof, struct capi_ctr *ctrl)
{ {
struct capi_ctr *ctrl = m->private;
hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata); hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata);
hysdn_card *card = cinfo->card; hysdn_card *card = cinfo->card;
int len = 0;
char *s; char *s;
#ifdef HYCAPI_PRINTFNAMES
printk(KERN_NOTICE "hycapi_read_proc\n"); seq_printf(m, "%-16s %s\n", "name", cinfo->cardname);
#endif seq_printf(m, "%-16s 0x%x\n", "io", card->iobase);
len += sprintf(page+len, "%-16s %s\n", "name", cinfo->cardname); seq_printf(m, "%-16s %d\n", "irq", card->irq);
len += sprintf(page+len, "%-16s 0x%x\n", "io", card->iobase);
len += sprintf(page+len, "%-16s %d\n", "irq", card->irq);
switch (card->brdtype) { switch (card->brdtype) {
case BD_PCCARD: s = "HYSDN Hycard"; break; case BD_PCCARD: s = "HYSDN Hycard"; break;
@ -461,24 +453,32 @@ static int hycapi_read_proc(char *page, char **start, off_t off,
case BD_PLEXUS: s = "HYSDN Plexus30"; break; case BD_PLEXUS: s = "HYSDN Plexus30"; break;
default: s = "???"; break; default: s = "???"; break;
} }
len += sprintf(page+len, "%-16s %s\n", "type", s); seq_printf(m, "%-16s %s\n", "type", s);
if ((s = cinfo->version[VER_DRIVER]) != NULL) if ((s = cinfo->version[VER_DRIVER]) != NULL)
len += sprintf(page+len, "%-16s %s\n", "ver_driver", s); seq_printf(m, "%-16s %s\n", "ver_driver", s);
if ((s = cinfo->version[VER_CARDTYPE]) != NULL) if ((s = cinfo->version[VER_CARDTYPE]) != NULL)
len += sprintf(page+len, "%-16s %s\n", "ver_cardtype", s); seq_printf(m, "%-16s %s\n", "ver_cardtype", s);
if ((s = cinfo->version[VER_SERIAL]) != NULL) if ((s = cinfo->version[VER_SERIAL]) != NULL)
len += sprintf(page+len, "%-16s %s\n", "ver_serial", s); seq_printf(m, "%-16s %s\n", "ver_serial", s);
len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname); seq_printf(m, "%-16s %s\n", "cardname", cinfo->cardname);
if (off+count >= len) return 0;
*eof = 1;
if (len < off)
return 0;
*start = page + off;
return ((count < len-off) ? count : len-off);
} }
static int hycapi_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, hycapi_proc_show, PDE(inode)->data);
}
static const struct file_operations hycapi_proc_fops = {
.owner = THIS_MODULE,
.open = hycapi_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
/************************************************************** /**************************************************************
hycapi_load_firmware hycapi_load_firmware
@ -774,7 +774,7 @@ hycapi_capi_create(hysdn_card *card)
ctrl->load_firmware = hycapi_load_firmware; ctrl->load_firmware = hycapi_load_firmware;
ctrl->reset_ctr = hycapi_reset_ctr; ctrl->reset_ctr = hycapi_reset_ctr;
ctrl->procinfo = hycapi_procinfo; ctrl->procinfo = hycapi_procinfo;
ctrl->ctr_read_proc = hycapi_read_proc; ctrl->proc_fops = &hycapi_proc_fops;
strcpy(ctrl->name, cinfo->cardname); strcpy(ctrl->name, cinfo->cardname);
ctrl->owner = THIS_MODULE; ctrl->owner = THIS_MODULE;

View File

@ -50,8 +50,7 @@ struct capi_ctr {
u16 (*send_message)(struct capi_ctr *, struct sk_buff *skb); u16 (*send_message)(struct capi_ctr *, struct sk_buff *skb);
char *(*procinfo)(struct capi_ctr *); char *(*procinfo)(struct capi_ctr *);
int (*ctr_read_proc)(char *page, char **start, off_t off, const struct file_operations *proc_fops;
int count, int *eof, struct capi_ctr *card);
/* filled in before calling ready callback */ /* filled in before calling ready callback */
u8 manu[CAPI_MANUFACTURER_LEN]; /* CAPI_GET_MANUFACTURER */ u8 manu[CAPI_MANUFACTURER_LEN]; /* CAPI_GET_MANUFACTURER */

View File

@ -21,7 +21,8 @@
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/kernel.h> #include <linux/kernel.h>
@ -516,33 +517,37 @@ static char *cmtp_procinfo(struct capi_ctr *ctrl)
return "CAPI Message Transport Protocol"; return "CAPI Message Transport Protocol";
} }
static int cmtp_ctr_read_proc(char *page, char **start, off_t off, int count, int *eof, struct capi_ctr *ctrl) static int cmtp_proc_show(struct seq_file *m, void *v)
{ {
struct capi_ctr *ctrl = m->private;
struct cmtp_session *session = ctrl->driverdata; struct cmtp_session *session = ctrl->driverdata;
struct cmtp_application *app; struct cmtp_application *app;
struct list_head *p, *n; struct list_head *p, *n;
int len = 0;
len += sprintf(page + len, "%s\n\n", cmtp_procinfo(ctrl)); seq_printf(m, "%s\n\n", cmtp_procinfo(ctrl));
len += sprintf(page + len, "addr %s\n", session->name); seq_printf(m, "addr %s\n", session->name);
len += sprintf(page + len, "ctrl %d\n", session->num); seq_printf(m, "ctrl %d\n", session->num);
list_for_each_safe(p, n, &session->applications) { list_for_each_safe(p, n, &session->applications) {
app = list_entry(p, struct cmtp_application, list); app = list_entry(p, struct cmtp_application, list);
len += sprintf(page + len, "appl %d -> %d\n", app->appl, app->mapping); seq_printf(m, "appl %d -> %d\n", app->appl, app->mapping);
} }
if (off + count >= len) return 0;
*eof = 1;
if (len < off)
return 0;
*start = page + off;
return ((count < len - off) ? count : len - off);
} }
static int cmtp_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, cmtp_proc_show, PDE(inode)->data);
}
static const struct file_operations cmtp_proc_fops = {
.owner = THIS_MODULE,
.open = cmtp_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
int cmtp_attach_device(struct cmtp_session *session) int cmtp_attach_device(struct cmtp_session *session)
{ {
@ -582,7 +587,7 @@ int cmtp_attach_device(struct cmtp_session *session)
session->ctrl.send_message = cmtp_send_message; session->ctrl.send_message = cmtp_send_message;
session->ctrl.procinfo = cmtp_procinfo; session->ctrl.procinfo = cmtp_procinfo;
session->ctrl.ctr_read_proc = cmtp_ctr_read_proc; session->ctrl.proc_fops = &cmtp_proc_fops;
if (attach_capi_ctr(&session->ctrl) < 0) { if (attach_capi_ctr(&session->ctrl) < 0) {
BT_ERR("Can't attach new controller"); BT_ERR("Can't attach new controller");