Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dgrp_ports_ops.c
Go to the documentation of this file.
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 static const struct file_operations 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 struct inode_operations ports_inode_ops = {
59  .permission = dgrp_inode_permission
60 };
61 
62 
64 {
65  struct nd_struct *node = de->data;
66 
67  de->proc_iops = &ports_inode_ops;
68  de->proc_fops = &ports_ops;
69  node->nd_ports_de = de;
70 }
71 
72 static void *dgrp_ports_seq_start(struct seq_file *seq, loff_t *pos)
73 {
74  if (*pos == 0)
75  seq_puts(seq, "#num tty_open pr_open tot_wait MSTAT IFLAG OFLAG CFLAG BPS DIGIFLAGS\n");
76 
77  return pos;
78 }
79 
80 static void *dgrp_ports_seq_next(struct seq_file *seq, void *v, loff_t *pos)
81 {
82  struct nd_struct *nd = seq->private;
83 
84  if (*pos >= nd->nd_chan_count)
85  return NULL;
86 
87  *pos += 1;
88 
89  return pos;
90 }
91 
92 static void dgrp_ports_seq_stop(struct seq_file *seq, void *v)
93 {
94 }
95 
96 static int dgrp_ports_seq_show(struct seq_file *seq, void *v)
97 {
98  loff_t *pos = v;
99  struct nd_struct *nd;
100  struct ch_struct *ch;
101  struct un_struct *tun, *pun;
102  unsigned int totcnt;
103 
104  nd = seq->private;
105  if (!nd)
106  return 0;
107 
108  if (*pos >= nd->nd_chan_count)
109  return 0;
110 
111  ch = &nd->nd_chan[*pos];
112  tun = &ch->ch_tun;
113  pun = &ch->ch_pun;
114 
115  /*
116  * If port is not open and no one is waiting to
117  * open it, the modem signal values can't be
118  * trusted, and will be zeroed.
119  */
120  totcnt = tun->un_open_count +
121  pun->un_open_count +
122  ch->ch_wait_count[0] +
123  ch->ch_wait_count[1] +
124  ch->ch_wait_count[2];
125 
126  seq_printf(seq, "%02d %02d %02d %02d 0x%04X 0x%04X 0x%04X 0x%04X %-6d 0x%04X\n",
127  (int) *pos,
128  tun->un_open_count,
129  pun->un_open_count,
130  ch->ch_wait_count[0] +
131  ch->ch_wait_count[1] +
132  ch->ch_wait_count[2],
133  (totcnt ? ch->ch_s_mlast : 0),
134  ch->ch_s_iflag,
135  ch->ch_s_oflag,
136  ch->ch_s_cflag,
137  (ch->ch_s_brate ? (1843200 / ch->ch_s_brate) : 0),
138  ch->ch_digi.digi_flags);
139 
140  return 0;
141 }
142 
143 static const struct seq_operations ports_seq_ops = {
144  .start = dgrp_ports_seq_start,
145  .next = dgrp_ports_seq_next,
146  .stop = dgrp_ports_seq_stop,
147  .show = dgrp_ports_seq_show,
148 };
149 
158 static int dgrp_ports_open(struct inode *inode, struct file *file)
159 {
160  struct seq_file *seq;
161  int rtn;
162 
163  rtn = seq_open(file, &ports_seq_ops);
164  if (!rtn) {
165  seq = file->private_data;
166  seq->private = PDE(inode)->data;
167  }
168 
169  return rtn;
170 }