]> Pileus Git - ~andy/linux/blob - drivers/staging/dgrp/dgrp_ports_ops.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[~andy/linux] / drivers / staging / dgrp / dgrp_ports_ops.c
1 /*
2  *
3  * Copyright 1999-2000 Digi International (www.digi.com)
4  *     James Puzzo <jamesp at digi dot com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
13  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14  * PURPOSE.  See the GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  *
20  */
21
22 /*
23  *
24  *  Filename:
25  *
26  *     dgrp_ports_ops.c
27  *
28  *  Description:
29  *
30  *     Handle the file operations required for the /proc/dgrp/ports/...
31  *     devices.  Basically gathers tty status for the node and returns it.
32  *
33  *  Author:
34  *
35  *     James A. Puzzo
36  *
37  */
38
39 #include <linux/module.h>
40 #include <linux/proc_fs.h>
41 #include <linux/tty.h>
42 #include <linux/sched.h>
43 #include <linux/seq_file.h>
44
45 #include "dgrp_common.h"
46
47 /* File operation declarations */
48 static int dgrp_ports_open(struct inode *, struct file *);
49
50 const struct file_operations dgrp_ports_ops = {
51         .owner   = THIS_MODULE,
52         .open    = dgrp_ports_open,
53         .read    = seq_read,
54         .llseek  = seq_lseek,
55         .release = seq_release
56 };
57
58 static void *dgrp_ports_seq_start(struct seq_file *seq, loff_t *pos)
59 {
60         if (*pos == 0)
61                 seq_puts(seq, "#num tty_open pr_open tot_wait MSTAT  IFLAG  OFLAG  CFLAG  BPS    DIGIFLAGS\n");
62
63         return pos;
64 }
65
66 static void *dgrp_ports_seq_next(struct seq_file *seq, void *v, loff_t *pos)
67 {
68         struct nd_struct *nd = seq->private;
69
70         if (*pos >= nd->nd_chan_count)
71                 return NULL;
72
73         *pos += 1;
74
75         return pos;
76 }
77
78 static void dgrp_ports_seq_stop(struct seq_file *seq, void *v)
79 {
80 }
81
82 static int dgrp_ports_seq_show(struct seq_file *seq, void *v)
83 {
84         loff_t *pos = v;
85         struct nd_struct *nd;
86         struct ch_struct *ch;
87         struct un_struct *tun, *pun;
88         unsigned int totcnt;
89
90         nd = seq->private;
91         if (!nd)
92                 return 0;
93
94         if (*pos >= nd->nd_chan_count)
95                 return 0;
96
97         ch = &nd->nd_chan[*pos];
98         tun = &ch->ch_tun;
99         pun = &ch->ch_pun;
100
101         /*
102          * If port is not open and no one is waiting to
103          * open it, the modem signal values can't be
104          * trusted, and will be zeroed.
105          */
106         totcnt = tun->un_open_count +
107                 pun->un_open_count +
108                 ch->ch_wait_count[0] +
109                 ch->ch_wait_count[1] +
110                 ch->ch_wait_count[2];
111
112         seq_printf(seq, "%02d      %02d      %02d      %02d     0x%04X 0x%04X 0x%04X 0x%04X %-6d 0x%04X\n",
113                    (int) *pos,
114                    tun->un_open_count,
115                    pun->un_open_count,
116                    ch->ch_wait_count[0] +
117                    ch->ch_wait_count[1] +
118                    ch->ch_wait_count[2],
119                    (totcnt ? ch->ch_s_mlast : 0),
120                    ch->ch_s_iflag,
121                    ch->ch_s_oflag,
122                    ch->ch_s_cflag,
123                    (ch->ch_s_brate ? (1843200 / ch->ch_s_brate) : 0),
124                    ch->ch_digi.digi_flags);
125
126         return 0;
127 }
128
129 static const struct seq_operations ports_seq_ops = {
130         .start = dgrp_ports_seq_start,
131         .next  = dgrp_ports_seq_next,
132         .stop  = dgrp_ports_seq_stop,
133         .show  = dgrp_ports_seq_show,
134 };
135
136 /**
137  * dgrp_ports_open -- open the /proc/dgrp/ports/... device
138  * @inode: struct inode *
139  * @file: struct file *
140  *
141  * Open function to open the /proc/dgrp/ports device for a PortServer.
142  * This is the open function for struct file_operations
143  */
144 static int dgrp_ports_open(struct inode *inode, struct file *file)
145 {
146         struct seq_file *seq;
147         int rtn;
148
149         rtn = seq_open(file, &ports_seq_ops);
150         if (!rtn) {
151                 seq = file->private_data;
152                 seq->private = PDE_DATA(inode);
153         }
154
155         return rtn;
156 }