aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/dgrp
diff options
context:
space:
mode:
authorBill Pemberton <wfp5p@virginia.edu>2012-09-20 16:55:27 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-09-21 12:04:18 -0400
commit0b52b74972712479ca285c04452db0d4b9025f80 (patch)
tree7e4c77510c7e420dcf672b931d0359cce68755a0 /drivers/staging/dgrp
parent5de69349ed4c10f43fa6dc6617051d94eee04e6c (diff)
staging: Add dgrp driver for Digi Realport devices
This is based on dgrp-1.9 available from ftp://ftp1.digi.com/support/beta/linux/dgrp/dgrp-1.9.tgz Signed-off-by: Bill Pemberton <wfp5p@virginia.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/dgrp')
-rw-r--r--drivers/staging/dgrp/Kconfig9
-rw-r--r--drivers/staging/dgrp/Makefile12
-rw-r--r--drivers/staging/dgrp/README2
-rw-r--r--drivers/staging/dgrp/TODO7
-rw-r--r--drivers/staging/dgrp/dgrp_common.c200
-rw-r--r--drivers/staging/dgrp/dgrp_common.h208
-rw-r--r--drivers/staging/dgrp/dgrp_dpa_ops.c556
-rw-r--r--drivers/staging/dgrp/dgrp_driver.c110
-rw-r--r--drivers/staging/dgrp/dgrp_mon_ops.c346
-rw-r--r--drivers/staging/dgrp/dgrp_net_ops.c3731
-rw-r--r--drivers/staging/dgrp/dgrp_ports_ops.c170
-rw-r--r--drivers/staging/dgrp/dgrp_specproc.c821
-rw-r--r--drivers/staging/dgrp/dgrp_sysfs.c555
-rw-r--r--drivers/staging/dgrp/dgrp_tty.c3331
-rw-r--r--drivers/staging/dgrp/digirp.h129
-rw-r--r--drivers/staging/dgrp/drp.h693
16 files changed, 10880 insertions, 0 deletions
diff --git a/drivers/staging/dgrp/Kconfig b/drivers/staging/dgrp/Kconfig
new file mode 100644
index 00000000000..39f4bb65ec8
--- /dev/null
+++ b/drivers/staging/dgrp/Kconfig
@@ -0,0 +1,9 @@
1config DGRP
2 tristate "Digi Realport driver"
3 default n
4 depends on SYSFS
5 ---help---
6 Support for Digi Realport devices. These devices allow you to
7 access remote serial ports as if they are local tty devices. This
8 will build the kernel driver, you will still need the userspace
9 component to make your Realport device work.
diff --git a/drivers/staging/dgrp/Makefile b/drivers/staging/dgrp/Makefile
new file mode 100644
index 00000000000..d9c3b88d716
--- /dev/null
+++ b/drivers/staging/dgrp/Makefile
@@ -0,0 +1,12 @@
1obj-$(CONFIG_DGRP) += dgrp.o
2
3dgrp-y := \
4 dgrp_common.o \
5 dgrp_dpa_ops.o \
6 dgrp_driver.o \
7 dgrp_mon_ops.o \
8 dgrp_net_ops.o \
9 dgrp_ports_ops.o \
10 dgrp_specproc.o \
11 dgrp_tty.o \
12 dgrp_sysfs.o
diff --git a/drivers/staging/dgrp/README b/drivers/staging/dgrp/README
new file mode 100644
index 00000000000..1d8aaee270e
--- /dev/null
+++ b/drivers/staging/dgrp/README
@@ -0,0 +1,2 @@
1The user space code to work with this driver is located at
2https://github.com/wfp5p/dgrp-utils
diff --git a/drivers/staging/dgrp/TODO b/drivers/staging/dgrp/TODO
new file mode 100644
index 00000000000..63341ade90d
--- /dev/null
+++ b/drivers/staging/dgrp/TODO
@@ -0,0 +1,7 @@
1- Use configfs for config stuff. This will require changes to the
2 user space code.
3
4- Check the calls to tty_register_device. In particular, check to see
5 if there should be some handling for IS_ERR(classp).
6
7- dgrp_send() and dgrp_receive() could use some refactoring
diff --git a/drivers/staging/dgrp/dgrp_common.c b/drivers/staging/dgrp/dgrp_common.c
new file mode 100644
index 00000000000..fce74e7fb83
--- /dev/null
+++ b/drivers/staging/dgrp/dgrp_common.c
@@ -0,0 +1,200 @@
1/*
2 *
3 * Copyright 1999 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 */
17
18/*
19 *
20 * Filename:
21 *
22 * dgrp_common.c
23 *
24 * Description:
25 *
26 * Definitions of global variables and functions which are either
27 * shared by the tty, mon, and net drivers; or which cross them
28 * functionally (like the poller).
29 *
30 * Author:
31 *
32 * James A. Puzzo
33 *
34 */
35
36#include <linux/errno.h>
37#include <linux/tty.h>
38#include <linux/sched.h>
39#include <linux/cred.h>
40
41#include "dgrp_common.h"
42
43/**
44 * dgrp_carrier -- check for carrier change state and act
45 * @ch: struct ch_struct *
46 */
47void dgrp_carrier(struct ch_struct *ch)
48{
49 struct nd_struct *nd;
50
51 int virt_carrier = 0;
52 int phys_carrier = 0;
53
54 /* fix case when the tty has already closed. */
55
56 if (!ch)
57 return;
58 nd = ch->ch_nd;
59 if (!nd)
60 return;
61
62 /*
63 * If we are currently waiting to determine the status of the port,
64 * we don't yet know the state of the modem lines. As a result,
65 * we ignore state changes when we are waiting for the modem lines
66 * to be established. We know, as a result of code in dgrp_net_ops,
67 * that we will be called again immediately following the reception
68 * of the status message with the true modem status flags in it.
69 */
70 if (ch->ch_expect & RR_STATUS)
71 return;
72
73 /*
74 * If CH_HANGUP is set, we gotta keep trying to get all the processes
75 * that have the port open to close the port.
76 * So lets just keep sending a hangup every time we get here.
77 */
78 if ((ch->ch_flag & CH_HANGUP) &&
79 (ch->ch_tun.un_open_count > 0))
80 tty_hangup(ch->ch_tun.un_tty);
81
82 /*
83 * Compute the effective state of both the physical and virtual
84 * senses of carrier.
85 */
86
87 if (ch->ch_s_mlast & DM_CD)
88 phys_carrier = 1;
89
90 if ((ch->ch_s_mlast & DM_CD) ||
91 (ch->ch_digi.digi_flags & DIGI_FORCEDCD) ||
92 (ch->ch_flag & CH_CLOCAL))
93 virt_carrier = 1;
94
95 /*
96 * Test for a VIRTUAL carrier transition to HIGH.
97 *
98 * The CH_HANGUP condition is intended to prevent any action
99 * except for close. As a result, we ignore positive carrier
100 * transitions during CH_HANGUP.
101 */
102 if (((ch->ch_flag & CH_HANGUP) == 0) &&
103 ((ch->ch_flag & CH_VIRT_CD) == 0) &&
104 (virt_carrier == 1)) {
105 /*
106 * When carrier rises, wake any threads waiting
107 * for carrier in the open routine.
108 */
109 nd->nd_tx_work = 1;
110
111 if (waitqueue_active(&ch->ch_flag_wait))
112 wake_up_interruptible(&ch->ch_flag_wait);
113 }
114
115 /*
116 * Test for a PHYSICAL transition to low, so long as we aren't
117 * currently ignoring physical transitions (which is what "virtual
118 * carrier" indicates).
119 *
120 * The transition of the virtual carrier to low really doesn't
121 * matter... it really only means "ignore carrier state", not
122 * "make pretend that carrier is there".
123 */
124 if ((virt_carrier == 0) &&
125 ((ch->ch_flag & CH_PHYS_CD) != 0) &&
126 (phys_carrier == 0)) {
127 /*
128 * When carrier drops:
129 *
130 * Do a Hard Hangup if that is called for.
131 *
132 * Drop carrier on all open units.
133 *
134 * Flush queues, waking up any task waiting in the
135 * line discipline.
136 *
137 * Send a hangup to the control terminal.
138 *
139 * Enable all select calls.
140 */
141
142 nd->nd_tx_work = 1;
143
144 ch->ch_flag &= ~(CH_LOW | CH_EMPTY | CH_DRAIN | CH_INPUT);
145
146 if (waitqueue_active(&ch->ch_flag_wait))
147 wake_up_interruptible(&ch->ch_flag_wait);
148
149 if (ch->ch_tun.un_open_count > 0)
150 tty_hangup(ch->ch_tun.un_tty);
151
152 if (ch->ch_pun.un_open_count > 0)
153 tty_hangup(ch->ch_pun.un_tty);
154 }
155
156 /*
157 * Make sure that our cached values reflect the current reality.
158 */
159 if (virt_carrier == 1)
160 ch->ch_flag |= CH_VIRT_CD;
161 else
162 ch->ch_flag &= ~CH_VIRT_CD;
163
164 if (phys_carrier == 1)
165 ch->ch_flag |= CH_PHYS_CD;
166 else
167 ch->ch_flag &= ~CH_PHYS_CD;
168
169}
170
171/**
172 * dgrp_chk_perm() -- check permissions for net device
173 * @inode: pointer to inode structure for the net communication device
174 * @op: operation to be tested
175 *
176 * The file permissions and ownerships are tested to determine whether
177 * the operation "op" is permitted on the file pointed to by the inode.
178 * Returns 0 if the operation is permitted, -EACCESS otherwise
179 */
180int dgrp_chk_perm(int mode, int op)
181{
182 if (!current_euid())
183 mode >>= 6;
184 else if (in_egroup_p(0))
185 mode >>= 3;
186
187 if ((mode & op & 0007) == op)
188 return 0;
189
190 if (capable(CAP_SYS_ADMIN))
191 return 0;
192
193 return -EACCES;
194}
195
196/* dgrp_chk_perm wrapper for permission call in struct inode_operations */
197int dgrp_inode_permission(struct inode *inode, int op)
198{
199 return dgrp_chk_perm(inode->i_mode, op);
200}
diff --git a/drivers/staging/dgrp/dgrp_common.h b/drivers/staging/dgrp/dgrp_common.h
new file mode 100644
index 00000000000..05ff338471a
--- /dev/null
+++ b/drivers/staging/dgrp/dgrp_common.h
@@ -0,0 +1,208 @@
1/*
2 *
3 * Copyright 1999 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 */
17
18#ifndef __DGRP_COMMON_H
19#define __DGRP_COMMON_H
20
21#define DIGI_VERSION "1.9-29"
22
23#include <linux/fs.h>
24#include <linux/timer.h>
25#include "drp.h"
26
27#define DGRP_TTIME 100
28#define DGRP_RTIME 100
29
30/************************************************************************
31 * All global storage allocation.
32 ************************************************************************/
33
34extern int dgrp_rawreadok; /* Allow raw writing of input */
35extern int dgrp_register_cudevices; /* enable legacy cu devices */
36extern int dgrp_register_prdevices; /* enable transparent print devices */
37extern int dgrp_poll_tick; /* Poll interval - in ms */
38
39extern struct list_head nd_struct_list;
40
41struct dgrp_poll_data {
42 spinlock_t poll_lock;
43 struct timer_list timer;
44 int poll_tick;
45 ulong poll_round; /* Timer rouding factor */
46 long node_active_count;
47};
48
49extern struct dgrp_poll_data dgrp_poll_data;
50extern void dgrp_poll_handler(unsigned long arg);
51
52/* from dgrp_mon_ops.c */
53extern void dgrp_register_mon_hook(struct proc_dir_entry *de);
54
55/* from dgrp_tty.c */
56extern int dgrp_tty_init(struct nd_struct *nd);
57extern void dgrp_tty_uninit(struct nd_struct *nd);
58
59/* from dgrp_ports_ops.c */
60extern void dgrp_register_ports_hook(struct proc_dir_entry *de);
61
62/* from dgrp_net_ops.c */
63extern void dgrp_register_net_hook(struct proc_dir_entry *de);
64
65/* from dgrp_dpa_ops.c */
66extern void dgrp_register_dpa_hook(struct proc_dir_entry *de);
67extern void dgrp_dpa_data(struct nd_struct *, int, u8 *, int);
68
69/* from dgrp_sysfs.c */
70extern void dgrp_create_class_sysfs_files(void);
71extern void dgrp_remove_class_sysfs_files(void);
72
73extern void dgrp_create_node_class_sysfs_files(struct nd_struct *nd);
74extern void dgrp_remove_node_class_sysfs_files(struct nd_struct *nd);
75
76extern void dgrp_create_tty_sysfs(struct un_struct *un, struct device *c);
77extern void dgrp_remove_tty_sysfs(struct device *c);
78
79/* from dgrp_specproc.c */
80/*
81 * The list of DGRP entries with r/w capabilities. These
82 * magic numbers are used for identification purposes.
83 */
84enum {
85 DGRP_CONFIG = 1, /* Configure portservers */
86 DGRP_NETDIR = 2, /* Directory for "net" devices */
87 DGRP_MONDIR = 3, /* Directory for "mon" devices */
88 DGRP_PORTSDIR = 4, /* Directory for "ports" devices */
89 DGRP_INFO = 5, /* Get info. about the running module */
90 DGRP_NODEINFO = 6, /* Get info. about the configured nodes */
91 DGRP_DPADIR = 7, /* Directory for the "dpa" devices */
92};
93
94/*
95 * Directions for proc handlers
96 */
97enum {
98 INBOUND = 1, /* Data being written to kernel */
99 OUTBOUND = 2, /* Data being read from the kernel */
100};
101
102/**
103 * dgrp_proc_entry: structure for dgrp proc dirs
104 * @id: ID number associated with this particular entry. Should be
105 * unique across all of DGRP.
106 * @name: text name associated with the /proc entry
107 * @mode: file access permisssions for the /proc entry
108 * @child: pointer to table describing a subdirectory for this entry
109 * @de: pointer to directory entry for this object once registered. Used
110 * to grab the handle of the object for unregistration
111 * @excl_sem: semaphore to provide exclusive to struct
112 * @excl_cnt: counter of current accesses
113 *
114 * Each entry in a DGRP proc directory is described with a
115 * dgrp_proc_entry structure. A collection of these
116 * entries (in an array) represents the members associated
117 * with a particular /proc directory, and is referred to
118 * as a table. All tables are terminated by an entry with
119 * zeros for every member.
120 */
121struct dgrp_proc_entry {
122 int id; /* Integer identifier */
123 const char *name; /* ASCII identifier */
124 mode_t mode; /* File access permissions */
125 struct dgrp_proc_entry *child; /* Child pointer */
126
127 /* file ops to use, pass NULL to use default */
128 struct file_operations *proc_file_ops;
129
130 struct proc_dir_entry *de; /* proc entry pointer */
131 struct semaphore excl_sem; /* Protects exclusive access var */
132 int excl_cnt; /* Counts number of curr accesses */
133};
134
135extern void dgrp_unregister_proc(void);
136extern void dgrp_register_proc(void);
137
138/*-----------------------------------------------------------------------*
139 *
140 * Declarations for common operations:
141 *
142 * (either used by more than one of net, mon, or tty,
143 * or in interrupt context (i.e. the poller))
144 *
145 *-----------------------------------------------------------------------*/
146
147void dgrp_carrier(struct ch_struct *ch);
148extern int dgrp_inode_permission(struct inode *inode, int op);
149extern int dgrp_chk_perm(int mode, int op);
150
151
152/*
153 * ID manipulation macros (where c1 & c2 are characters, i is
154 * a long integer, and s is a character array of at least three members
155 */
156
157static inline void ID_TO_CHAR(long i, char *s)
158{
159 s[0] = ((i & 0xff00)>>8);
160 s[1] = (i & 0xff);
161 s[2] = 0;
162}
163
164static inline long CHAR_TO_ID(char *s)
165{
166 return ((s[0] & 0xff) << 8) | (s[1] & 0xff);
167}
168
169static inline struct nd_struct *nd_struct_get(long major)
170{
171 struct nd_struct *nd;
172
173 list_for_each_entry(nd, &nd_struct_list, list) {
174 if (major == nd->nd_major)
175 return nd;
176 }
177
178 return NULL;
179}
180
181static inline int nd_struct_add(struct nd_struct *entry)
182{
183 struct nd_struct *ptr;
184
185 ptr = nd_struct_get(entry->nd_major);
186
187 if (ptr)
188 return -EBUSY;
189
190 list_add_tail(&entry->list, &nd_struct_list);
191
192 return 0;
193}
194
195static inline int nd_struct_del(struct nd_struct *entry)
196{
197 struct nd_struct *nd;
198
199 nd = nd_struct_get(entry->nd_major);
200
201 if (!nd)
202 return -ENODEV;
203
204 list_del(&nd->list);
205 return 0;
206}
207
208#endif /* __DGRP_COMMON_H */
diff --git a/drivers/staging/dgrp/dgrp_dpa_ops.c b/drivers/staging/dgrp/dgrp_dpa_ops.c
new file mode 100644
index 00000000000..49e670915e5
--- /dev/null
+++ b/drivers/staging/dgrp/dgrp_dpa_ops.c
@@ -0,0 +1,556 @@
1/*
2 *
3 * Copyright 1999 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 */
17
18/*
19 *
20 * Filename:
21 *
22 * dgrp_dpa_ops.c
23 *
24 * Description:
25 *
26 * Handle the file operations required for the "dpa" devices.
27 * Includes those functions required to register the "dpa" devices
28 * in "/proc".
29 *
30 * Author:
31 *
32 * James A. Puzzo
33 *
34 */
35
36#include <linux/module.h>
37#include <linux/proc_fs.h>
38#include <linux/tty.h>
39#include <linux/poll.h>
40#include <linux/cred.h>
41#include <linux/sched.h>
42#include <linux/ratelimit.h>
43#include <asm/unaligned.h>
44
45#include "dgrp_common.h"
46
47/* File operation declarations */
48static int dgrp_dpa_open(struct inode *, struct file *);
49static int dgrp_dpa_release(struct inode *, struct file *);
50static ssize_t dgrp_dpa_read(struct file *, char __user *, size_t, loff_t *);
51static long dgrp_dpa_ioctl(struct file *file, unsigned int cmd,
52 unsigned long arg);
53static unsigned int dgrp_dpa_select(struct file *, struct poll_table_struct *);
54
55static const struct file_operations dpa_ops = {
56 .owner = THIS_MODULE,
57 .read = dgrp_dpa_read,
58 .poll = dgrp_dpa_select,
59 .unlocked_ioctl = dgrp_dpa_ioctl,
60 .open = dgrp_dpa_open,
61 .release = dgrp_dpa_release,
62};
63
64static struct inode_operations dpa_inode_ops = {
65 .permission = dgrp_inode_permission
66};
67
68
69
70struct digi_node {
71 uint nd_state; /* Node state: 1 = up, 0 = down. */
72 uint nd_chan_count; /* Number of channels found */
73 uint nd_tx_byte; /* Tx data count */
74 uint nd_rx_byte; /* RX data count */
75 u8 nd_ps_desc[MAX_DESC_LEN]; /* Description from PS */
76};
77
78#define DIGI_GETNODE (('d'<<8) | 249) /* get board info */
79
80
81struct digi_chan {
82 uint ch_port; /* Port number to get info on */
83 uint ch_open; /* 1 if open, 0 if not */
84 uint ch_txcount; /* TX data count */
85 uint ch_rxcount; /* RX data count */
86 uint ch_s_brate; /* Realport BRATE */
87 uint ch_s_estat; /* Realport ELAST */
88 uint ch_s_cflag; /* Realport CFLAG */
89 uint ch_s_iflag; /* Realport IFLAG */
90 uint ch_s_oflag; /* Realport OFLAG */
91 uint ch_s_xflag; /* Realport XFLAG */
92 uint ch_s_mstat; /* Realport MLAST */
93};
94
95#define DIGI_GETCHAN (('d'<<8) | 248) /* get channel info */
96
97
98struct digi_vpd {
99 int vpd_len;
100 char vpd_data[VPDSIZE];
101};
102
103#define DIGI_GETVPD (('d'<<8) | 246) /* get VPD info */
104
105
106struct digi_debug {
107 int onoff;
108 int port;
109};
110
111#define DIGI_SETDEBUG (('d'<<8) | 247) /* set debug info */
112
113
114void dgrp_register_dpa_hook(struct proc_dir_entry *de)
115{
116 struct nd_struct *node = de->data;
117
118 de->proc_iops = &dpa_inode_ops;
119 de->proc_fops = &dpa_ops;
120
121 node->nd_dpa_de = de;
122 spin_lock_init(&node->nd_dpa_lock);
123}
124
125/*
126 * dgrp_dpa_open -- open the DPA device for a particular PortServer
127 */
128static int dgrp_dpa_open(struct inode *inode, struct file *file)
129{
130 struct nd_struct *nd;
131 int rtn = 0;
132
133 struct proc_dir_entry *de;
134
135 rtn = try_module_get(THIS_MODULE);
136 if (!rtn)
137 return -ENXIO;
138
139 rtn = 0;
140
141 if (!capable(CAP_SYS_ADMIN)) {
142 rtn = -EPERM;
143 goto done;
144 }
145
146 /*
147 * Make sure that the "private_data" field hasn't already been used.
148 */
149 if (file->private_data) {
150 rtn = -EINVAL;
151 goto done;
152 }
153
154 /*
155 * Get the node pointer, and fail if it doesn't exist.
156 */
157 de = PDE(inode);
158 if (!de) {
159 rtn = -ENXIO;
160 goto done;
161 }
162 nd = (struct nd_struct *)de->data;
163 if (!nd) {
164 rtn = -ENXIO;
165 goto done;
166 }
167
168 file->private_data = (void *) nd;
169
170 /*
171 * Allocate the DPA buffer.
172 */
173
174 if (nd->nd_dpa_buf) {
175 rtn = -EBUSY;
176 } else {
177 nd->nd_dpa_buf = kmalloc(DPA_MAX, GFP_KERNEL);
178
179 if (!nd->nd_dpa_buf) {
180 rtn = -ENOMEM;
181 } else {
182 nd->nd_dpa_out = 0;
183 nd->nd_dpa_in = 0;
184 nd->nd_dpa_lbolt = jiffies;
185 }
186 }
187
188done:
189
190 if (rtn)
191 module_put(THIS_MODULE);
192 return rtn;
193}
194
195/*
196 * dgrp_dpa_release -- close the DPA device for a particular PortServer
197 */
198static int dgrp_dpa_release(struct inode *inode, struct file *file)
199{
200 struct nd_struct *nd;
201 u8 *buf;
202 unsigned long lock_flags;
203
204 /*
205 * Get the node pointer, and quit if it doesn't exist.
206 */
207 nd = (struct nd_struct *)(file->private_data);
208 if (!nd)
209 goto done;
210
211 /*
212 * Free the dpa buffer.
213 */
214
215 spin_lock_irqsave(&nd->nd_dpa_lock, lock_flags);
216
217 buf = nd->nd_dpa_buf;
218
219 nd->nd_dpa_buf = NULL;
220 nd->nd_dpa_out = nd->nd_dpa_in;
221
222 /*
223 * Wakeup any thread waiting for buffer space.
224 */
225
226 if (nd->nd_dpa_flag & DPA_WAIT_SPACE) {
227 nd->nd_dpa_flag &= ~DPA_WAIT_SPACE;
228 wake_up_interruptible(&nd->nd_dpa_wqueue);
229 }
230
231 spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags);
232
233 kfree(buf);
234
235done:
236 module_put(THIS_MODULE);
237 file->private_data = NULL;
238 return 0;
239}
240
241/*
242 * dgrp_dpa_read
243 *
244 * Copy data from the monitoring buffer to the user, freeing space
245 * in the monitoring buffer for more messages
246 */
247static ssize_t dgrp_dpa_read(struct file *file, char __user *buf, size_t count,
248 loff_t *ppos)
249{
250 struct nd_struct *nd;
251 int n;
252 int r;
253 int offset = 0;
254 int res = 0;
255 ssize_t rtn;
256 unsigned long lock_flags;
257
258 /*
259 * Get the node pointer, and quit if it doesn't exist.
260 */
261 nd = (struct nd_struct *)(file->private_data);
262 if (!nd)
263 return -ENXIO;
264
265 /*
266 * Wait for some data to appear in the buffer.
267 */
268
269 spin_lock_irqsave(&nd->nd_dpa_lock, lock_flags);
270
271 for (;;) {
272 n = (nd->nd_dpa_in - nd->nd_dpa_out) & DPA_MASK;
273
274 if (n != 0)
275 break;
276
277 nd->nd_dpa_flag |= DPA_WAIT_DATA;
278
279 spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags);
280
281 /*
282 * Go to sleep waiting until the condition becomes true.
283 */
284 rtn = wait_event_interruptible(nd->nd_dpa_wqueue,
285 ((nd->nd_dpa_flag & DPA_WAIT_DATA) == 0));
286
287 if (rtn)
288 return rtn;
289
290 spin_lock_irqsave(&nd->nd_dpa_lock, lock_flags);
291 }
292
293 /*
294 * Read whatever is there.
295 */
296
297 if (n > count)
298 n = count;
299
300 res = n;
301
302 r = DPA_MAX - nd->nd_dpa_out;
303
304 if (r <= n) {
305
306 spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags);
307 rtn = copy_to_user((void __user *)buf,
308 nd->nd_dpa_buf + nd->nd_dpa_out, r);
309 spin_lock_irqsave(&nd->nd_dpa_lock, lock_flags);
310
311 if (rtn) {
312 rtn = -EFAULT;
313 goto done;
314 }
315
316 nd->nd_dpa_out = 0;
317 n -= r;
318 offset = r;
319 }
320
321 spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags);
322 rtn = copy_to_user((void __user *)buf + offset,
323 nd->nd_dpa_buf + nd->nd_dpa_out, n);
324 spin_lock_irqsave(&nd->nd_dpa_lock, lock_flags);
325
326 if (rtn) {
327 rtn = -EFAULT;
328 goto done;
329 }
330
331 nd->nd_dpa_out += n;
332
333 *ppos += res;
334
335 rtn = res;
336
337 /*
338 * Wakeup any thread waiting for buffer space.
339 */
340
341 n = (nd->nd_dpa_in - nd->nd_dpa_out) & DPA_MASK;
342
343 if (nd->nd_dpa_flag & DPA_WAIT_SPACE &&
344 (DPA_MAX - n) > DPA_HIGH_WATER) {
345 nd->nd_dpa_flag &= ~DPA_WAIT_SPACE;
346 wake_up_interruptible(&nd->nd_dpa_wqueue);
347 }
348
349 done:
350 spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags);
351 return rtn;
352}
353
354static unsigned int dgrp_dpa_select(struct file *file,
355 struct poll_table_struct *table)
356{
357 unsigned int retval = 0;
358 struct nd_struct *nd = file->private_data;
359
360 if (nd->nd_dpa_out != nd->nd_dpa_in)
361 retval |= POLLIN | POLLRDNORM; /* Conditionally readable */
362
363 retval |= POLLOUT | POLLWRNORM; /* Always writeable */
364
365 return retval;
366}
367
368static long dgrp_dpa_ioctl(struct file *file, unsigned int cmd,
369 unsigned long arg)
370{
371
372 struct nd_struct *nd;
373 struct digi_chan getchan;
374 struct digi_node getnode;
375 struct ch_struct *ch;
376 struct digi_debug setdebug;
377 struct digi_vpd vpd;
378 unsigned int port;
379 void __user *uarg = (void __user *) arg;
380
381 nd = file->private_data;
382
383 switch (cmd) {
384 case DIGI_GETCHAN:
385 if (copy_from_user(&getchan, uarg, sizeof(struct digi_chan)))
386 return -EFAULT;
387
388 port = getchan.ch_port;
389
390 if (port < 0 || port > nd->nd_chan_count)
391 return -EINVAL;
392
393 ch = nd->nd_chan + port;
394
395 getchan.ch_open = (ch->ch_open_count > 0) ? 1 : 0;
396 getchan.ch_txcount = ch->ch_txcount;
397 getchan.ch_rxcount = ch->ch_rxcount;
398 getchan.ch_s_brate = ch->ch_s_brate;
399 getchan.ch_s_estat = ch->ch_s_elast;
400 getchan.ch_s_cflag = ch->ch_s_cflag;
401 getchan.ch_s_iflag = ch->ch_s_iflag;
402 getchan.ch_s_oflag = ch->ch_s_oflag;
403 getchan.ch_s_xflag = ch->ch_s_xflag;
404 getchan.ch_s_mstat = ch->ch_s_mlast;
405
406 if (copy_to_user(uarg, &getchan, sizeof(struct digi_chan)))
407 return -EFAULT;
408 break;
409
410
411 case DIGI_GETNODE:
412 getnode.nd_state = (nd->nd_state & NS_READY) ? 1 : 0;
413 getnode.nd_chan_count = nd->nd_chan_count;
414 getnode.nd_tx_byte = nd->nd_tx_byte;
415 getnode.nd_rx_byte = nd->nd_rx_byte;
416
417 memset(&getnode.nd_ps_desc, 0, MAX_DESC_LEN);
418 strncpy(getnode.nd_ps_desc, nd->nd_ps_desc, MAX_DESC_LEN);
419
420 if (copy_to_user(uarg, &getnode, sizeof(struct digi_node)))
421 return -EFAULT;
422 break;
423
424
425 case DIGI_SETDEBUG:
426 if (copy_from_user(&setdebug, uarg, sizeof(struct digi_debug)))
427 return -EFAULT;
428
429 nd->nd_dpa_debug = setdebug.onoff;
430 nd->nd_dpa_port = setdebug.port;
431 break;
432
433
434 case DIGI_GETVPD:
435 if (nd->nd_vpd_len > 0) {
436 vpd.vpd_len = nd->nd_vpd_len;
437 memcpy(&vpd.vpd_data, &nd->nd_vpd, nd->nd_vpd_len);
438 } else {
439 vpd.vpd_len = 0;
440 }
441
442 if (copy_to_user(uarg, &vpd, sizeof(struct digi_vpd)))
443 return -EFAULT;
444 break;
445 }
446
447 return 0;
448}
449
450/**
451 * dgrp_dpa() -- send data to the device monitor queue
452 * @nd: pointer to a node structure
453 * @buf: buffer of data to copy to the monitoring buffer
454 * @len: number of bytes to transfer to the buffer
455 *
456 * Called by the net device routines to send data to the device
457 * monitor queue. If the device monitor buffer is too full to
458 * accept the data, it waits until the buffer is ready.
459 */
460static void dgrp_dpa(struct nd_struct *nd, u8 *buf, int nbuf)
461{
462 int n;
463 int r;
464 unsigned long lock_flags;
465
466 /*
467 * Grab DPA lock.
468 */
469 spin_lock_irqsave(&nd->nd_dpa_lock, lock_flags);
470
471 /*
472 * Loop while data remains.
473 */
474 while (nbuf > 0 && nd->nd_dpa_buf != NULL) {
475
476 n = (nd->nd_dpa_out - nd->nd_dpa_in - 1) & DPA_MASK;
477
478 /*
479 * Enforce flow control on the DPA device.
480 */
481 if (n < (DPA_MAX - DPA_HIGH_WATER))
482 nd->nd_dpa_flag |= DPA_WAIT_SPACE;
483
484 /*
485 * This should never happen, as the flow control above
486 * should have stopped things before they got to this point.
487 */
488 if (n == 0) {
489 spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags);
490 return;
491 }
492
493 /*
494 * Copy as much data as will fit.
495 */
496
497 if (n > nbuf)
498 n = nbuf;
499
500 r = DPA_MAX - nd->nd_dpa_in;
501
502 if (r <= n) {
503 memcpy(nd->nd_dpa_buf + nd->nd_dpa_in, buf, r);
504
505 n -= r;
506
507 nd->nd_dpa_in = 0;
508
509 buf += r;
510 nbuf -= r;
511 }
512
513 memcpy(nd->nd_dpa_buf + nd->nd_dpa_in, buf, n);
514
515 nd->nd_dpa_in += n;
516
517 buf += n;
518 nbuf -= n;
519
520 if (nd->nd_dpa_in >= DPA_MAX)
521 pr_info_ratelimited("%s - nd->nd_dpa_in (%i) >= DPA_MAX\n",
522 __func__, nd->nd_dpa_in);
523
524 /*
525 * Wakeup any thread waiting for data
526 */
527 if (nd->nd_dpa_flag & DPA_WAIT_DATA) {
528 nd->nd_dpa_flag &= ~DPA_WAIT_DATA;
529 wake_up_interruptible(&nd->nd_dpa_wqueue);
530 }
531 }
532
533 /*
534 * Release the DPA lock.
535 */
536 spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags);
537}
538
539/**
540 * dgrp_monitor_data() -- builds a DPA data packet
541 * @nd: pointer to a node structure
542 * @type: type of message to be logged in the DPA buffer
543 * @buf: buffer of data to be logged in the DPA buffer
544 * @size -- number of bytes in the "buf" buffer
545 */
546void dgrp_dpa_data(struct nd_struct *nd, int type, u8 *buf, int size)
547{
548 u8 header[5];
549
550 header[0] = type;
551
552 put_unaligned_be32(size, header + 1);
553
554 dgrp_dpa(nd, header, sizeof(header));
555 dgrp_dpa(nd, buf, size);
556}
diff --git a/drivers/staging/dgrp/dgrp_driver.c b/drivers/staging/dgrp/dgrp_driver.c
new file mode 100644
index 00000000000..6e4a0ebc074
--- /dev/null
+++ b/drivers/staging/dgrp/dgrp_driver.c
@@ -0,0 +1,110 @@
1/*
2 *
3 * Copyright 1999-2003 Digi International (www.digi.com)
4 * Jeff Randall
5 * James Puzzo <jamesp at digi dot com>
6 * Scott Kilau <Scott_Kilau at digi dot com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
15 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 * PURPOSE. See the GNU General Public License for more details.
17 *
18 */
19
20/*
21 * Driver specific includes
22 */
23#include <linux/module.h>
24#include <linux/slab.h>
25#include <linux/tty.h>
26#include <linux/init.h>
27
28/*
29 * PortServer includes
30 */
31#include "dgrp_common.h"
32
33
34MODULE_LICENSE("GPL");
35MODULE_AUTHOR("Digi International, http://www.digi.com");
36MODULE_DESCRIPTION("RealPort driver for Digi's ethernet-based serial connectivity product line");
37MODULE_VERSION(DIGI_VERSION);
38
39struct list_head nd_struct_list;
40struct dgrp_poll_data dgrp_poll_data;
41
42int dgrp_rawreadok = 1; /* Bypass flipbuf on input */
43int dgrp_register_cudevices = 1;/* Turn on/off registering legacy cu devices */
44int dgrp_register_prdevices = 1;/* Turn on/off registering transparent print */
45int dgrp_poll_tick = 20; /* Poll interval - in ms */
46
47module_param_named(rawreadok, dgrp_rawreadok, int, 0644);
48MODULE_PARM_DESC(rawreadok, "Bypass flip buffers on input");
49
50module_param_named(register_cudevices, dgrp_register_cudevices, int, 0644);
51MODULE_PARM_DESC(register_cudevices, "Turn on/off registering legacy cu devices");
52
53module_param_named(register_prdevices, dgrp_register_prdevices, int, 0644);
54MODULE_PARM_DESC(register_prdevices, "Turn on/off registering transparent print devices");
55
56module_param_named(pollrate, dgrp_poll_tick, int, 0644);
57MODULE_PARM_DESC(pollrate, "Poll interval in ms");
58
59/* Driver load/unload functions */
60static int dgrp_init_module(void);
61static void dgrp_cleanup_module(void);
62
63module_init(dgrp_init_module);
64module_exit(dgrp_cleanup_module);
65
66/*
67 * init_module()
68 *
69 * Module load. This is where it all starts.
70 */
71static int dgrp_init_module(void)
72{
73 INIT_LIST_HEAD(&nd_struct_list);
74
75 spin_lock_init(&dgrp_poll_data.poll_lock);
76 init_timer(&dgrp_poll_data.timer);
77 dgrp_poll_data.poll_tick = dgrp_poll_tick;
78 dgrp_poll_data.timer.function = dgrp_poll_handler;
79 dgrp_poll_data.timer.data = (unsigned long) &dgrp_poll_data;
80
81 dgrp_create_class_sysfs_files();
82
83 dgrp_register_proc();
84
85 return 0;
86}
87
88
89/*
90 * Module unload. This is where it all ends.
91 */
92static void dgrp_cleanup_module(void)
93{
94 struct nd_struct *nd, *next;
95
96 /*
97 * Attempting to free resources in backwards
98 * order of allocation, in case that helps
99 * memory pool fragmentation.
100 */
101 dgrp_unregister_proc();
102
103 dgrp_remove_class_sysfs_files();
104
105
106 list_for_each_entry_safe(nd, next, &nd_struct_list, list) {
107 dgrp_tty_uninit(nd);
108 kfree(nd);
109 }
110}
diff --git a/drivers/staging/dgrp/dgrp_mon_ops.c b/drivers/staging/dgrp/dgrp_mon_ops.c
new file mode 100644
index 00000000000..268dcb95204
--- /dev/null
+++ b/drivers/staging/dgrp/dgrp_mon_ops.c
@@ -0,0 +1,346 @@
1/*****************************************************************************
2 *
3 * Copyright 1999 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 */
17
18/*
19 *
20 * Filename:
21 *
22 * dgrp_mon_ops.c
23 *
24 * Description:
25 *
26 * Handle the file operations required for the "monitor" devices.
27 * Includes those functions required to register the "mon" devices
28 * in "/proc".
29 *
30 * Author:
31 *
32 * James A. Puzzo
33 *
34 */
35
36#include <linux/module.h>
37#include <linux/tty.h>
38#include <linux/sched.h>
39#include <asm/unaligned.h>
40#include <linux/proc_fs.h>
41
42#include "dgrp_common.h"
43
44/* File operation declarations */
45static int dgrp_mon_open(struct inode *, struct file *);
46static int dgrp_mon_release(struct inode *, struct file *);
47static ssize_t dgrp_mon_read(struct file *, char __user *, size_t, loff_t *);
48static long dgrp_mon_ioctl(struct file *file, unsigned int cmd,
49 unsigned long arg);
50
51static const struct file_operations mon_ops = {
52 .owner = THIS_MODULE,
53 .read = dgrp_mon_read,
54 .unlocked_ioctl = dgrp_mon_ioctl,
55 .open = dgrp_mon_open,
56 .release = dgrp_mon_release,
57};
58
59static struct inode_operations mon_inode_ops = {
60 .permission = dgrp_inode_permission
61};
62
63void dgrp_register_mon_hook(struct proc_dir_entry *de)
64{
65 struct nd_struct *node = de->data;
66
67 de->proc_iops = &mon_inode_ops;
68 de->proc_fops = &mon_ops;
69 node->nd_mon_de = de;
70 sema_init(&node->nd_mon_semaphore, 1);
71}
72
73/**
74 * dgrp_mon_open() -- open /proc/dgrp/ports device for a PortServer
75 * @inode: struct inode *
76 * @file: struct file *
77 *
78 * Open function to open the /proc/dgrp/ports device for a PortServer.
79 */
80static int dgrp_mon_open(struct inode *inode, struct file *file)
81{
82 struct nd_struct *nd;
83 struct proc_dir_entry *de;
84 struct timeval tv;
85 uint32_t time;
86 u8 *buf;
87 int rtn;
88
89 rtn = try_module_get(THIS_MODULE);
90 if (!rtn)
91 return -ENXIO;
92
93 rtn = 0;
94
95 if (!capable(CAP_SYS_ADMIN)) {
96 rtn = -EPERM;
97 goto done;
98 }
99
100 /*
101 * Make sure that the "private_data" field hasn't already been used.
102 */
103 if (file->private_data) {
104 rtn = -EINVAL;
105 goto done;
106 }
107
108 /*
109 * Get the node pointer, and fail if it doesn't exist.
110 */
111 de = PDE(inode);
112 if (!de) {
113 rtn = -ENXIO;
114 goto done;
115 }
116
117 nd = (struct nd_struct *)de->data;
118 if (!nd) {
119 rtn = -ENXIO;
120 goto done;
121 }
122
123 file->private_data = (void *) nd;
124
125 /*
126 * Allocate the monitor buffer.
127 */
128
129 /*
130 * Grab the MON lock.
131 */
132 down(&nd->nd_mon_semaphore);
133
134 if (nd->nd_mon_buf) {
135 rtn = -EBUSY;
136 goto done_up;
137 }
138
139 nd->nd_mon_buf = kmalloc(MON_MAX, GFP_KERNEL);
140
141 if (!nd->nd_mon_buf) {
142 rtn = -ENOMEM;
143 goto done_up;
144 }
145
146 /*
147 * Enter an RPDUMP file header into the buffer.
148 */
149
150 buf = nd->nd_mon_buf;
151
152 strcpy(buf, RPDUMP_MAGIC);
153 buf += strlen(buf) + 1;
154
155 do_gettimeofday(&tv);
156
157 /*
158 * tv.tv_sec might be a 64 bit quantity. Pare
159 * it down to 32 bits before attempting to encode
160 * it.
161 */
162 time = (uint32_t) (tv.tv_sec & 0xffffffff);
163
164 put_unaligned_be32(time, buf);
165 put_unaligned_be16(0, buf + 4);
166 buf += 6;
167
168 if (nd->nd_tx_module) {
169 buf[0] = RPDUMP_CLIENT;
170 put_unaligned_be32(0, buf + 1);
171 put_unaligned_be16(1, buf + 5);
172 buf[7] = 0xf0 + nd->nd_tx_module;
173 buf += 8;
174 }
175
176 if (nd->nd_rx_module) {
177 buf[0] = RPDUMP_SERVER;
178 put_unaligned_be32(0, buf + 1);
179 put_unaligned_be16(1, buf + 5);
180 buf[7] = 0xf0 + nd->nd_rx_module;
181 buf += 8;
182 }
183
184 nd->nd_mon_out = 0;
185 nd->nd_mon_in = buf - nd->nd_mon_buf;
186 nd->nd_mon_lbolt = jiffies;
187
188done_up:
189 up(&nd->nd_mon_semaphore);
190
191done:
192 if (rtn)
193 module_put(THIS_MODULE);
194 return rtn;
195}
196
197
198/**
199 * dgrp_mon_release() - Close the MON device for a particular PortServer
200 * @inode: struct inode *
201 * @file: struct file *
202 */
203static int dgrp_mon_release(struct inode *inode, struct file *file)
204{
205 struct nd_struct *nd;
206
207 /*
208 * Get the node pointer, and quit if it doesn't exist.
209 */
210 nd = (struct nd_struct *)(file->private_data);
211 if (!nd)
212 goto done;
213
214 /*
215 * Free the monitor buffer.
216 */
217
218 down(&nd->nd_mon_semaphore);
219
220 kfree(nd->nd_mon_buf);
221 nd->nd_mon_buf = NULL;
222 nd->nd_mon_out = nd->nd_mon_in;
223
224 /*
225 * Wakeup any thread waiting for buffer space.
226 */
227
228 if (nd->nd_mon_flag & MON_WAIT_SPACE) {
229 nd->nd_mon_flag &= ~MON_WAIT_SPACE;
230 wake_up_interruptible(&nd->nd_mon_wqueue);
231 }
232
233 up(&nd->nd_mon_semaphore);
234
235 /*
236 * Make sure there is no thread in the middle of writing a packet.
237 */
238 down(&nd->nd_net_semaphore);
239 up(&nd->nd_net_semaphore);
240
241done:
242 module_put(THIS_MODULE);
243 file->private_data = NULL;
244 return 0;
245}
246
247/**
248 * dgrp_mon_read() -- Copy data from the monitoring buffer to the user
249 */
250static ssize_t dgrp_mon_read(struct file *file, char __user *buf, size_t count,
251 loff_t *ppos)
252{
253 struct nd_struct *nd;
254 int r;
255 int offset = 0;
256 int res = 0;
257 ssize_t rtn;
258
259 /*
260 * Get the node pointer, and quit if it doesn't exist.
261 */
262 nd = (struct nd_struct *)(file->private_data);
263 if (!nd)
264 return -ENXIO;
265
266 /*
267 * Wait for some data to appear in the buffer.
268 */
269
270 down(&nd->nd_mon_semaphore);
271
272 for (;;) {
273 res = (nd->nd_mon_in - nd->nd_mon_out) & MON_MASK;
274
275 if (res)
276 break;
277
278 nd->nd_mon_flag |= MON_WAIT_DATA;
279
280 up(&nd->nd_mon_semaphore);
281
282 /*
283 * Go to sleep waiting until the condition becomes true.
284 */
285 rtn = wait_event_interruptible(nd->nd_mon_wqueue,
286 ((nd->nd_mon_flag & MON_WAIT_DATA) == 0));
287
288 if (rtn)
289 return rtn;
290
291 down(&nd->nd_mon_semaphore);
292 }
293
294 /*
295 * Read whatever is there.
296 */
297
298 if (res > count)
299 res = count;
300
301 r = MON_MAX - nd->nd_mon_out;
302
303 if (r <= res) {
304 rtn = copy_to_user((void __user *)buf,
305 nd->nd_mon_buf + nd->nd_mon_out, r);
306 if (rtn) {
307 up(&nd->nd_mon_semaphore);
308 return -EFAULT;
309 }
310
311 nd->nd_mon_out = 0;
312 res -= r;
313 offset = r;
314 }
315
316 rtn = copy_to_user((void __user *) buf + offset,
317 nd->nd_mon_buf + nd->nd_mon_out, res);
318 if (rtn) {
319 up(&nd->nd_mon_semaphore);
320 return -EFAULT;
321 }
322
323 nd->nd_mon_out += res;
324
325 *ppos += res;
326
327 up(&nd->nd_mon_semaphore);
328
329 /*
330 * Wakeup any thread waiting for buffer space.
331 */
332
333 if (nd->nd_mon_flag & MON_WAIT_SPACE) {
334 nd->nd_mon_flag &= ~MON_WAIT_SPACE;
335 wake_up_interruptible(&nd->nd_mon_wqueue);
336 }
337
338 return res;
339}
340
341/* ioctl is not valid on monitor device */
342static long dgrp_mon_ioctl(struct file *file, unsigned int cmd,
343 unsigned long arg)
344{
345 return -EINVAL;
346}
diff --git a/drivers/staging/dgrp/dgrp_net_ops.c b/drivers/staging/dgrp/dgrp_net_ops.c
new file mode 100644
index 00000000000..d9d6b6709e4
--- /dev/null
+++ b/drivers/staging/dgrp/dgrp_net_ops.c
@@ -0,0 +1,3731 @@
1/*
2 *
3 * Copyright 1999 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 */
17
18/*
19 *
20 * Filename:
21 *
22 * dgrp_net_ops.c
23 *
24 * Description:
25 *
26 * Handle the file operations required for the "network" devices.
27 * Includes those functions required to register the "net" devices
28 * in "/proc".
29 *
30 * Author:
31 *
32 * James A. Puzzo
33 *
34 */
35
36#include <linux/module.h>
37#include <linux/proc_fs.h>
38#include <linux/types.h>
39#include <linux/string.h>
40#include <linux/tty.h>
41#include <linux/tty_flip.h>
42#include <linux/spinlock.h>
43#include <linux/poll.h>
44#include <linux/sched.h>
45#include <linux/ratelimit.h>
46#include <asm/unaligned.h>
47
48#define MYFLIPLEN TBUF_MAX
49
50#include "dgrp_common.h"
51
52#define TTY_FLIPBUF_SIZE 512
53#define DEVICE_NAME_SIZE 50
54
55/*
56 * Generic helper function declarations
57 */
58static void parity_scan(struct ch_struct *ch, unsigned char *cbuf,
59 unsigned char *fbuf, int *len);
60
61/*
62 * File operation declarations
63 */
64static int dgrp_net_open(struct inode *, struct file *);
65static int dgrp_net_release(struct inode *, struct file *);
66static ssize_t dgrp_net_read(struct file *, char __user *, size_t, loff_t *);
67static ssize_t dgrp_net_write(struct file *, const char __user *, size_t,
68 loff_t *);
69static long dgrp_net_ioctl(struct file *file, unsigned int cmd,
70 unsigned long arg);
71static unsigned int dgrp_net_select(struct file *file,
72 struct poll_table_struct *table);
73
74static const struct file_operations net_ops = {
75 .owner = THIS_MODULE,
76 .read = dgrp_net_read,
77 .write = dgrp_net_write,
78 .poll = dgrp_net_select,
79 .unlocked_ioctl = dgrp_net_ioctl,
80 .open = dgrp_net_open,
81 .release = dgrp_net_release,
82};
83
84static struct inode_operations net_inode_ops = {
85 .permission = dgrp_inode_permission
86};
87
88void dgrp_register_net_hook(struct proc_dir_entry *de)
89{
90 struct nd_struct *node = de->data;
91
92 de->proc_iops = &net_inode_ops;
93 de->proc_fops = &net_ops;
94 node->nd_net_de = de;
95 sema_init(&node->nd_net_semaphore, 1);
96 node->nd_state = NS_CLOSED;
97 dgrp_create_node_class_sysfs_files(node);
98}
99
100
101/**
102 * dgrp_dump() -- prints memory for debugging purposes.
103 * @mem: Memory location which should be printed to the console
104 * @len: Number of bytes to be dumped
105 */
106static void dgrp_dump(u8 *mem, int len)
107{
108 int i;
109
110 pr_debug("dgrp dump length = %d, data = ", len);
111 for (i = 0; i < len; ++i)
112 pr_debug("%.2x ", mem[i]);
113 pr_debug("\n");
114}
115
116/**
117 * dgrp_read_data_block() -- Read a data block
118 * @ch: struct ch_struct *
119 * @flipbuf: u8 *
120 * @flipbuf_size: size of flipbuf
121 */
122static void dgrp_read_data_block(struct ch_struct *ch, u8 *flipbuf,
123 int flipbuf_size)
124{
125 int t;
126 int n;
127
128 if (flipbuf_size <= 0)
129 return;
130
131 t = RBUF_MAX - ch->ch_rout;
132 n = flipbuf_size;
133
134 if (n >= t) {
135 memcpy(flipbuf, ch->ch_rbuf + ch->ch_rout, t);
136 flipbuf += t;
137 n -= t;
138 ch->ch_rout = 0;
139 }
140
141 memcpy(flipbuf, ch->ch_rbuf + ch->ch_rout, n);
142 flipbuf += n;
143 ch->ch_rout += n;
144}
145
146
147/**
148 * dgrp_input() -- send data to the line disipline
149 * @ch: pointer to channel struct
150 *
151 * Copys the rbuf to the flipbuf and sends to line discipline.
152 * Sends input buffer data to the line discipline.
153 *
154 * There are several modes to consider here:
155 * rawreadok, tty->real_raw, and IF_PARMRK
156 */
157static void dgrp_input(struct ch_struct *ch)
158{
159 struct nd_struct *nd;
160 struct tty_struct *tty;
161 int remain;
162 int data_len;
163 int len;
164 int flip_len;
165 int tty_count;
166 ulong lock_flags;
167 struct tty_ldisc *ld;
168 u8 *myflipbuf;
169 u8 *myflipflagbuf;
170
171 if (!ch)
172 return;
173
174 nd = ch->ch_nd;
175
176 if (!nd)
177 return;
178
179 spin_lock_irqsave(&nd->nd_lock, lock_flags);
180
181 myflipbuf = nd->nd_inputbuf;
182 myflipflagbuf = nd->nd_inputflagbuf;
183
184 if (!ch->ch_open_count) {
185 ch->ch_rout = ch->ch_rin;
186 goto out;
187 }
188
189 if (ch->ch_tun.un_flag & UN_CLOSING) {
190 ch->ch_rout = ch->ch_rin;
191 goto out;
192 }
193
194 tty = (ch->ch_tun).un_tty;
195
196
197 if (!tty || tty->magic != TTY_MAGIC) {
198 ch->ch_rout = ch->ch_rin;
199 goto out;
200 }
201
202 tty_count = tty->count;
203 if (!tty_count) {
204 ch->ch_rout = ch->ch_rin;
205 goto out;
206 }
207
208 if (tty->closing || test_bit(TTY_CLOSING, &tty->flags)) {
209 ch->ch_rout = ch->ch_rin;
210 goto out;
211 }
212
213 spin_unlock_irqrestore(&nd->nd_lock, lock_flags);
214
215 /* Decide how much data we can send into the tty layer */
216 if (dgrp_rawreadok && tty->real_raw)
217 flip_len = MYFLIPLEN;
218 else
219 flip_len = TTY_FLIPBUF_SIZE;
220
221 /* data_len should be the number of chars that we read in */
222 data_len = (ch->ch_rin - ch->ch_rout) & RBUF_MASK;
223 remain = data_len;
224
225 /* len is the amount of data we are going to transfer here */
226 len = min(data_len, flip_len);
227
228 /* take into consideration length of ldisc */
229 len = min(len, (N_TTY_BUF_SIZE - 1) - tty->read_cnt);
230
231 ld = tty_ldisc_ref(tty);
232
233 /*
234 * If we were unable to get a reference to the ld,
235 * don't flush our buffer, and act like the ld doesn't
236 * have any space to put the data right now.
237 */
238 if (!ld) {
239 len = 0;
240 } else if (!ld->ops->receive_buf) {
241 spin_lock_irqsave(&nd->nd_lock, lock_flags);
242 ch->ch_rout = ch->ch_rin;
243 spin_unlock_irqrestore(&nd->nd_lock, lock_flags);
244 len = 0;
245 }
246
247 /* Check DPA flow control */
248 if ((nd->nd_dpa_debug) &&
249 (nd->nd_dpa_flag & DPA_WAIT_SPACE) &&
250 (nd->nd_dpa_port == MINOR(tty_devnum(ch->ch_tun.un_tty))))
251 len = 0;
252
253 if ((len) && !(ch->ch_flag & CH_RXSTOP)) {
254
255 dgrp_read_data_block(ch, myflipbuf, len);
256
257 /*
258 * In high performance mode, we don't have to update
259 * flag_buf or any of the counts or pointers into flip buf.
260 */
261 if (!dgrp_rawreadok || !tty->real_raw) {
262 if (I_PARMRK(tty) || I_BRKINT(tty) || I_INPCK(tty))
263 parity_scan(ch, myflipbuf, myflipflagbuf, &len);
264 else
265 memset(myflipflagbuf, TTY_NORMAL, len);
266 }
267
268 if ((nd->nd_dpa_debug) &&
269 (nd->nd_dpa_port == PORT_NUM(MINOR(tty_devnum(tty)))))
270 dgrp_dpa_data(nd, 1, myflipbuf, len);
271
272 /*
273 * If we're doing raw reads, jam it right into the
274 * line disc bypassing the flip buffers.
275 */
276 if (dgrp_rawreadok && tty->real_raw)
277 ld->ops->receive_buf(tty, myflipbuf, NULL, len);
278 else {
279 len = tty_buffer_request_room(tty, len);
280 tty_insert_flip_string_flags(tty, myflipbuf,
281 myflipflagbuf, len);
282
283 /* Tell the tty layer its okay to "eat" the data now */
284 tty_flip_buffer_push(tty);
285 }
286
287 ch->ch_rxcount += len;
288 }
289
290 if (ld)
291 tty_ldisc_deref(ld);
292
293 /*
294 * Wake up any sleepers (maybe dgrp close) that might be waiting
295 * for a channel flag state change.
296 */
297 wake_up_interruptible(&ch->ch_flag_wait);
298 return;
299
300out:
301 spin_unlock_irqrestore(&nd->nd_lock, lock_flags);
302}
303
304
305/*
306 * parity_scan
307 *
308 * Loop to inspect each single character or 0xFF escape.
309 *
310 * if PARMRK & ~DOSMODE:
311 * 0xFF 0xFF Normal 0xFF character, escaped
312 * to eliminate confusion.
313 * 0xFF 0x00 0x00 Break
314 * 0xFF 0x00 CC Error character CC.
315 * CC Normal character CC.
316 *
317 * if PARMRK & DOSMODE:
318 * 0xFF 0x18 0x00 Break
319 * 0xFF 0x08 0x00 Framing Error
320 * 0xFF 0x04 0x00 Parity error
321 * 0xFF 0x0C 0x00 Both Framing and Parity error
322 *
323 * TODO: do we need to do the XMODEM, XOFF, XON, XANY processing??
324 * as per protocol
325 */
326static void parity_scan(struct ch_struct *ch, unsigned char *cbuf,
327 unsigned char *fbuf, int *len)
328{
329 int l = *len;
330 int count = 0;
331 int DOS = ((ch->ch_iflag & IF_DOSMODE) == 0 ? 0 : 1);
332 unsigned char *cout; /* character buffer */
333 unsigned char *fout; /* flag buffer */
334 unsigned char *in;
335 unsigned char c;
336
337 in = cbuf;
338 cout = cbuf;
339 fout = fbuf;
340
341 while (l--) {
342 c = *in;
343 in++;
344
345 switch (ch->ch_pscan_state) {
346 default:
347 /* reset to sanity and fall through */
348 ch->ch_pscan_state = 0 ;
349
350 case 0:
351 /* No FF seen yet */
352 if (c == 0xff) /* delete this character from stream */
353 ch->ch_pscan_state = 1;
354 else {
355 *cout++ = c;
356 *fout++ = TTY_NORMAL;
357 count += 1;
358 }
359 break;
360
361 case 1:
362 /* first FF seen */
363 if (c == 0xff) {
364 /* doubled ff, transform to single ff */
365 *cout++ = c;
366 *fout++ = TTY_NORMAL;
367 count += 1;
368 ch->ch_pscan_state = 0;
369 } else {
370 /* save value examination in next state */
371 ch->ch_pscan_savechar = c;
372 ch->ch_pscan_state = 2;
373 }
374 break;
375
376 case 2:
377 /* third character of ff sequence */
378 *cout++ = c;
379 if (DOS) {
380 if (ch->ch_pscan_savechar & 0x10)
381 *fout++ = TTY_BREAK;
382 else if (ch->ch_pscan_savechar & 0x08)
383 *fout++ = TTY_FRAME;
384 else
385 /*
386 * either marked as a parity error,
387 * indeterminate, or not in DOSMODE
388 * call it a parity error
389 */
390 *fout++ = TTY_PARITY;
391 } else {
392 /* case FF XX ?? where XX is not 00 */
393 if (ch->ch_pscan_savechar & 0xff) {
394 /* this should not happen */
395 pr_info("%s: parity_scan: error unexpected byte\n",
396 __func__);
397 *fout++ = TTY_PARITY;
398 }
399 /* case FF 00 XX where XX is not 00 */
400 else if (c == 0xff)
401 *fout++ = TTY_PARITY;
402 /* case FF 00 00 */
403 else
404 *fout++ = TTY_BREAK;
405
406 }
407 count += 1;
408 ch->ch_pscan_state = 0;
409 }
410 }
411 *len = count;
412}
413
414
415/**
416 * dgrp_net_idle() -- Idle the network connection
417 * @nd: pointer to node structure to idle
418 */
419static void dgrp_net_idle(struct nd_struct *nd)
420{
421 struct ch_struct *ch;
422 int i;
423
424 nd->nd_tx_work = 1;
425
426 nd->nd_state = NS_IDLE;
427 nd->nd_flag = 0;
428
429 for (i = nd->nd_seq_out; ; i = (i + 1) & SEQ_MASK) {
430 if (!nd->nd_seq_wait[i]) {
431 nd->nd_seq_wait[i] = 0;
432 wake_up_interruptible(&nd->nd_seq_wque[i]);
433 }
434
435 if (i == nd->nd_seq_in)
436 break;
437 }
438
439 nd->nd_seq_out = nd->nd_seq_in;
440
441 nd->nd_unack = 0;
442 nd->nd_remain = 0;
443
444 nd->nd_tx_module = 0x10;
445 nd->nd_rx_module = 0x00;
446
447 for (i = 0, ch = nd->nd_chan; i < CHAN_MAX; i++, ch++) {
448 ch->ch_state = CS_IDLE;
449
450 ch->ch_otype = 0;
451 ch->ch_otype_waiting = 0;
452 }
453}
454
455/*
456 * Increase the number of channels, waking up any
457 * threads that might be waiting for the channels
458 * to appear.
459 */
460static void increase_channel_count(struct nd_struct *nd, int n)
461{
462 struct ch_struct *ch;
463 struct device *classp;
464 char name[DEVICE_NAME_SIZE];
465 int ret;
466 u8 *buf;
467 int i;
468
469 for (i = nd->nd_chan_count; i < n; ++i) {
470 ch = nd->nd_chan + i;
471
472 /* FIXME: return a useful error instead! */
473 buf = kmalloc(TBUF_MAX, GFP_KERNEL);
474 if (!buf)
475 return;
476
477 if (ch->ch_tbuf)
478 pr_info_ratelimited("%s - ch_tbuf was not NULL\n",
479 __func__);
480
481 ch->ch_tbuf = buf;
482
483 buf = kmalloc(RBUF_MAX, GFP_KERNEL);
484 if (!buf)
485 return;
486
487 if (ch->ch_rbuf)
488 pr_info("%s - ch_rbuf was not NULL\n",
489 __func__);
490 ch->ch_rbuf = buf;
491
492 classp = tty_port_register_device(&ch->port,
493 nd->nd_serial_ttdriver, i,
494 NULL);
495
496 ch->ch_tun.un_sysfs = classp;
497 snprintf(name, DEVICE_NAME_SIZE, "tty_%d", i);
498
499 dgrp_create_tty_sysfs(&ch->ch_tun, classp);
500 ret = sysfs_create_link(&nd->nd_class_dev->kobj,
501 &classp->kobj, name);
502
503 /* NOTE: We don't support "cu" devices anymore,
504 * so you will notice we don't register them
505 * here anymore. */
506 if (dgrp_register_prdevices) {
507 classp = tty_register_device(nd->nd_xprint_ttdriver,
508 i, NULL);
509 ch->ch_pun.un_sysfs = classp;
510 snprintf(name, DEVICE_NAME_SIZE, "pr_%d", i);
511
512 dgrp_create_tty_sysfs(&ch->ch_pun, classp);
513 ret = sysfs_create_link(&nd->nd_class_dev->kobj,
514 &classp->kobj, name);
515 }
516
517 nd->nd_chan_count = i + 1;
518 wake_up_interruptible(&ch->ch_flag_wait);
519 }
520}
521
522/*
523 * Decrease the number of channels, and wake up any threads that might
524 * be waiting on the channels that vanished.
525 */
526static void decrease_channel_count(struct nd_struct *nd, int n)
527{
528 struct ch_struct *ch;
529 char name[DEVICE_NAME_SIZE];
530 int i;
531
532 for (i = nd->nd_chan_count - 1; i >= n; --i) {
533 ch = nd->nd_chan + i;
534
535 /*
536 * Make any open ports inoperative.
537 */
538 ch->ch_state = CS_IDLE;
539
540 ch->ch_otype = 0;
541 ch->ch_otype_waiting = 0;
542
543 /*
544 * Only "HANGUP" if we care about carrier
545 * transitions and we are already open.
546 */
547 if (ch->ch_open_count != 0) {
548 ch->ch_flag |= CH_HANGUP;
549 dgrp_carrier(ch);
550 }
551
552 /*
553 * Unlike the CH_HANGUP flag above, use another
554 * flag to indicate to the RealPort state machine
555 * that this port has disappeared.
556 */
557 if (ch->ch_open_count != 0)
558 ch->ch_flag |= CH_PORT_GONE;
559
560 wake_up_interruptible(&ch->ch_flag_wait);
561
562 nd->nd_chan_count = i;
563
564 kfree(ch->ch_tbuf);
565 ch->ch_tbuf = NULL;
566
567 kfree(ch->ch_rbuf);
568 ch->ch_rbuf = NULL;
569
570 nd->nd_chan_count = i;
571
572 dgrp_remove_tty_sysfs(ch->ch_tun.un_sysfs);
573 snprintf(name, DEVICE_NAME_SIZE, "tty_%d", i);
574 sysfs_remove_link(&nd->nd_class_dev->kobj, name);
575 tty_unregister_device(nd->nd_serial_ttdriver, i);
576
577 /*
578 * NOTE: We don't support "cu" devices anymore, so don't
579 * unregister them here anymore.
580 */
581
582 if (dgrp_register_prdevices) {
583 dgrp_remove_tty_sysfs(ch->ch_pun.un_sysfs);
584 snprintf(name, DEVICE_NAME_SIZE, "pr_%d", i);
585 sysfs_remove_link(&nd->nd_class_dev->kobj, name);
586 tty_unregister_device(nd->nd_xprint_ttdriver, i);
587 }
588 }
589}
590
591/**
592 * dgrp_chan_count() -- Adjust the node channel count.
593 * @nd: pointer to a node structure
594 * @n: new value for channel count
595 *
596 * Adjusts the node channel count. If new ports have appeared, it tries
597 * to signal those processes that might have been waiting for ports to
598 * appear. If ports have disappeared it tries to signal those processes
599 * that might be hung waiting for a response for the now non-existant port.
600 */
601static void dgrp_chan_count(struct nd_struct *nd, int n)
602{
603 if (n == nd->nd_chan_count)
604 return;
605
606 if (n > nd->nd_chan_count)
607 increase_channel_count(nd, n);
608
609 if (n < nd->nd_chan_count)
610 decrease_channel_count(nd, n);
611}
612
613/**
614 * dgrp_monitor() -- send data to the device monitor queue
615 * @nd: pointer to a node structure
616 * @buf: data to copy to the monitoring buffer
617 * @len: number of bytes to transfer to the buffer
618 *
619 * Called by the net device routines to send data to the device
620 * monitor queue. If the device monitor buffer is too full to
621 * accept the data, it waits until the buffer is ready.
622 */
623static void dgrp_monitor(struct nd_struct *nd, u8 *buf, int len)
624{
625 int n;
626 int r;
627 int rtn;
628
629 /*
630 * Grab monitor lock.
631 */
632 down(&nd->nd_mon_semaphore);
633
634 /*
635 * Loop while data remains.
636 */
637 while ((len > 0) && (nd->nd_mon_buf)) {
638 /*
639 * Determine the amount of available space left in the
640 * buffer. If there's none, wait until some appears.
641 */
642
643 n = (nd->nd_mon_out - nd->nd_mon_in - 1) & MON_MASK;
644
645 if (!n) {
646 nd->nd_mon_flag |= MON_WAIT_SPACE;
647
648 up(&nd->nd_mon_semaphore);
649
650 /*
651 * Go to sleep waiting until the condition becomes true.
652 */
653 rtn = wait_event_interruptible(nd->nd_mon_wqueue,
654 ((nd->nd_mon_flag & MON_WAIT_SPACE) == 0));
655
656/* FIXME: really ignore rtn? */
657
658 /*
659 * We can't exit here if we receive a signal, since
660 * to do so would trash the debug stream.
661 */
662
663 down(&nd->nd_mon_semaphore);
664
665 continue;
666 }
667
668 /*
669 * Copy as much data as will fit.
670 */
671
672 if (n > len)
673 n = len;
674
675 r = MON_MAX - nd->nd_mon_in;
676
677 if (r <= n) {
678 memcpy(nd->nd_mon_buf + nd->nd_mon_in, buf, r);
679
680 n -= r;
681
682 nd->nd_mon_in = 0;
683
684 buf += r;
685 len -= r;
686 }
687
688 memcpy(nd->nd_mon_buf + nd->nd_mon_in, buf, n);
689
690 nd->nd_mon_in += n;
691
692 buf += n;
693 len -= n;
694
695 if (nd->nd_mon_in >= MON_MAX)
696 pr_info_ratelimited("%s - nd_mon_in (%i) >= MON_MAX\n",
697 __func__, nd->nd_mon_in);
698
699 /*
700 * Wakeup any thread waiting for data
701 */
702
703 if (nd->nd_mon_flag & MON_WAIT_DATA) {
704 nd->nd_mon_flag &= ~MON_WAIT_DATA;
705 wake_up_interruptible(&nd->nd_mon_wqueue);
706 }
707 }
708
709 /*
710 * Release the monitor lock.
711 */
712 up(&nd->nd_mon_semaphore);
713}
714
715/**
716 * dgrp_encode_time() -- Encodes rpdump time into a 4-byte quantity.
717 * @nd: pointer to a node structure
718 * @buf: destination buffer
719 *
720 * Encodes "rpdump" time into a 4-byte quantity. Time is measured since
721 * open.
722 */
723static void dgrp_encode_time(struct nd_struct *nd, u8 *buf)
724{
725 ulong t;
726
727 /*
728 * Convert time in HZ since open to time in milliseconds
729 * since open.
730 */
731 t = jiffies - nd->nd_mon_lbolt;
732 t = 1000 * (t / HZ) + 1000 * (t % HZ) / HZ;
733
734 put_unaligned_be32((uint)(t & 0xffffffff), buf);
735}
736
737
738
739/**
740 * dgrp_monitor_message() -- Builds a rpdump style message.
741 * @nd: pointer to a node structure
742 * @message: destination buffer
743 */
744static void dgrp_monitor_message(struct nd_struct *nd, char *message)
745{
746 u8 header[7];
747 int n;
748
749 header[0] = RPDUMP_MESSAGE;
750
751 dgrp_encode_time(nd, header + 1);
752
753 n = strlen(message);
754
755 put_unaligned_be16(n, header + 5);
756
757 dgrp_monitor(nd, header, sizeof(header));
758 dgrp_monitor(nd, (u8 *) message, n);
759}
760
761
762
763/**
764 * dgrp_monitor_reset() -- Note a reset in the monitoring buffer.
765 * @nd: pointer to a node structure
766 */
767static void dgrp_monitor_reset(struct nd_struct *nd)
768{
769 u8 header[5];
770
771 header[0] = RPDUMP_RESET;
772
773 dgrp_encode_time(nd, header + 1);
774
775 dgrp_monitor(nd, header, sizeof(header));
776}
777
778/**
779 * dgrp_monitor_data() -- builds a monitor data packet
780 * @nd: pointer to a node structure
781 * @type: type of message to be logged
782 * @buf: data to be logged
783 * @size: number of bytes in the buffer
784 */
785static void dgrp_monitor_data(struct nd_struct *nd, u8 type, u8 *buf, int size)
786{
787 u8 header[7];
788
789 header[0] = type;
790
791 dgrp_encode_time(nd, header + 1);
792
793 put_unaligned_be16(size, header + 5);
794
795 dgrp_monitor(nd, header, sizeof(header));
796 dgrp_monitor(nd, buf, size);
797}
798
799static int alloc_nd_buffers(struct nd_struct *nd)
800{
801
802 nd->nd_iobuf = NULL;
803 nd->nd_writebuf = NULL;
804 nd->nd_inputbuf = NULL;
805 nd->nd_inputflagbuf = NULL;
806
807 /*
808 * Allocate the network read/write buffer.
809 */
810 nd->nd_iobuf = kzalloc(UIO_MAX + 10, GFP_KERNEL);
811 if (!nd->nd_iobuf)
812 goto out_err;
813
814 /*
815 * Allocate a buffer for doing the copy from user space to
816 * kernel space in the write routines.
817 */
818 nd->nd_writebuf = kzalloc(WRITEBUFLEN, GFP_KERNEL);
819 if (!nd->nd_writebuf)
820 goto out_err;
821
822 /*
823 * Allocate a buffer for doing the copy from kernel space to
824 * tty buffer space in the read routines.
825 */
826 nd->nd_inputbuf = kzalloc(MYFLIPLEN, GFP_KERNEL);
827 if (!nd->nd_inputbuf)
828 goto out_err;
829
830 /*
831 * Allocate a buffer for doing the copy from kernel space to
832 * tty buffer space in the read routines.
833 */
834 nd->nd_inputflagbuf = kzalloc(MYFLIPLEN, GFP_KERNEL);
835 if (!nd->nd_inputflagbuf)
836 goto out_err;
837
838 return 0;
839
840out_err:
841 kfree(nd->nd_iobuf);
842 kfree(nd->nd_writebuf);
843 kfree(nd->nd_inputbuf);
844 kfree(nd->nd_inputflagbuf);
845 return -ENOMEM;
846}
847
848/*
849 * dgrp_net_open() -- Open the NET device for a particular PortServer
850 */
851static int dgrp_net_open(struct inode *inode, struct file *file)
852{
853 struct nd_struct *nd;
854 struct proc_dir_entry *de;
855 ulong lock_flags;
856 int rtn;
857
858 rtn = try_module_get(THIS_MODULE);
859 if (!rtn)
860 return -EAGAIN;
861
862 if (!capable(CAP_SYS_ADMIN)) {
863 rtn = -EPERM;
864 goto done;
865 }
866
867 /*
868 * Make sure that the "private_data" field hasn't already been used.
869 */
870 if (file->private_data) {
871 rtn = -EINVAL;
872 goto done;
873 }
874
875 /*
876 * Get the node pointer, and fail if it doesn't exist.
877 */
878 de = PDE(inode);
879 if (!de) {
880 rtn = -ENXIO;
881 goto done;
882 }
883
884 nd = (struct nd_struct *) de->data;
885 if (!nd) {
886 rtn = -ENXIO;
887 goto done;
888 }
889
890 file->private_data = (void *) nd;
891
892 /*
893 * Grab the NET lock.
894 */
895 down(&nd->nd_net_semaphore);
896
897 if (nd->nd_state != NS_CLOSED) {
898 rtn = -EBUSY;
899 goto unlock;
900 }
901
902 /*
903 * Initialize the link speed parameters.
904 */
905
906 nd->nd_link.lk_fast_rate = UIO_MAX;
907 nd->nd_link.lk_slow_rate = UIO_MAX;
908
909 nd->nd_link.lk_fast_delay = 1000;
910 nd->nd_link.lk_slow_delay = 1000;
911
912 nd->nd_link.lk_header_size = 46;
913
914
915 rtn = alloc_nd_buffers(nd);
916 if (rtn)
917 goto unlock;
918
919 /*
920 * The port is now open, so move it to the IDLE state
921 */
922 dgrp_net_idle(nd);
923
924 nd->nd_tx_time = jiffies;
925
926 /*
927 * If the polling routing is not running, start it running here
928 */
929 spin_lock_irqsave(&dgrp_poll_data.poll_lock, lock_flags);
930
931 if (!dgrp_poll_data.node_active_count) {
932 dgrp_poll_data.node_active_count = 2;
933 dgrp_poll_data.timer.expires = jiffies +
934 dgrp_poll_tick * HZ / 1000;
935 add_timer(&dgrp_poll_data.timer);
936 }
937
938 spin_unlock_irqrestore(&dgrp_poll_data.poll_lock, lock_flags);
939
940 dgrp_monitor_message(nd, "Net Open");
941
942unlock:
943 /*
944 * Release the NET lock.
945 */
946 up(&nd->nd_net_semaphore);
947
948done:
949 if (rtn)
950 module_put(THIS_MODULE);
951
952 return rtn;
953}
954
955/* dgrp_net_release() -- close the NET device for a particular PortServer */
956static int dgrp_net_release(struct inode *inode, struct file *file)
957{
958 struct nd_struct *nd;
959 ulong lock_flags;
960
961 nd = (struct nd_struct *)(file->private_data);
962 if (!nd)
963 goto done;
964
965/* TODO : historical locking placeholder */
966/*
967 * In the HPUX version of the RealPort driver (which served as a basis
968 * for this driver) this locking code was used. Saved if ever we need
969 * to review the locking under Linux.
970 */
971/* spinlock(&nd->nd_lock); */
972
973
974 /*
975 * Grab the NET lock.
976 */
977 down(&nd->nd_net_semaphore);
978
979 /*
980 * Before "closing" the internal connection, make sure all
981 * ports are "idle".
982 */
983 dgrp_net_idle(nd);
984
985 nd->nd_state = NS_CLOSED;
986 nd->nd_flag = 0;
987
988 /*
989 * TODO ... must the wait queue be reset on close?
990 * should any pending waiters be reset?
991 * Let's decide to assert that the waitq is empty... and see
992 * how soon we break.
993 */
994 if (waitqueue_active(&nd->nd_tx_waitq))
995 pr_info("%s - expected waitqueue_active to be false\n",
996 __func__);
997
998 nd->nd_send = 0;
999
1000 kfree(nd->nd_iobuf);
1001 nd->nd_iobuf = NULL;
1002
1003/* TODO : historical locking placeholder */
1004/*
1005 * In the HPUX version of the RealPort driver (which served as a basis
1006 * for this driver) this locking code was used. Saved if ever we need
1007 * to review the locking under Linux.
1008 */
1009/* spinunlock( &nd->nd_lock ); */
1010
1011
1012 kfree(nd->nd_writebuf);
1013 nd->nd_writebuf = NULL;
1014
1015 kfree(nd->nd_inputbuf);
1016 nd->nd_inputbuf = NULL;
1017
1018 kfree(nd->nd_inputflagbuf);
1019 nd->nd_inputflagbuf = NULL;
1020
1021/* TODO : historical locking placeholder */
1022/*
1023 * In the HPUX version of the RealPort driver (which served as a basis
1024 * for this driver) this locking code was used. Saved if ever we need
1025 * to review the locking under Linux.
1026 */
1027/* spinlock(&nd->nd_lock); */
1028
1029 /*
1030 * Set the active port count to zero.
1031 */
1032 dgrp_chan_count(nd, 0);
1033
1034/* TODO : historical locking placeholder */
1035/*
1036 * In the HPUX version of the RealPort driver (which served as a basis
1037 * for this driver) this locking code was used. Saved if ever we need
1038 * to review the locking under Linux.
1039 */
1040/* spinunlock(&nd->nd_lock); */
1041
1042 /*
1043 * Release the NET lock.
1044 */
1045 up(&nd->nd_net_semaphore);
1046
1047 /*
1048 * Cause the poller to stop scheduling itself if this is
1049 * the last active node.
1050 */
1051 spin_lock_irqsave(&dgrp_poll_data.poll_lock, lock_flags);
1052
1053 if (dgrp_poll_data.node_active_count == 2) {
1054 del_timer(&dgrp_poll_data.timer);
1055 dgrp_poll_data.node_active_count = 0;
1056 }
1057
1058 spin_unlock_irqrestore(&dgrp_poll_data.poll_lock, lock_flags);
1059
1060done:
1061 down(&nd->nd_net_semaphore);
1062
1063 dgrp_monitor_message(nd, "Net Close");
1064
1065 up(&nd->nd_net_semaphore);
1066
1067 module_put(THIS_MODULE);
1068 file->private_data = NULL;
1069 return 0;
1070}
1071
1072/* used in dgrp_send to setup command header */
1073static inline u8 *set_cmd_header(u8 *b, u8 port, u8 cmd)
1074{
1075 *b++ = 0xb0 + (port & 0x0f);
1076 *b++ = cmd;
1077 return b;
1078}
1079
1080/**
1081 * dgrp_send() -- build a packet for transmission to the server
1082 * @nd: pointer to a node structure
1083 * @tmax: maximum bytes to transmit
1084 *
1085 * returns number of bytes sent
1086 */
1087static int dgrp_send(struct nd_struct *nd, long tmax)
1088{
1089 struct ch_struct *ch = nd->nd_chan;
1090 u8 *b;
1091 u8 *buf;
1092 u8 *mbuf;
1093 u8 port;
1094 int mod;
1095 long send;
1096 int maxport;
1097 long lastport = -1;
1098 ushort rwin;
1099 long in;
1100 ushort n;
1101 long t;
1102 long ttotal;
1103 long tchan;
1104 long tsend;
1105 ushort tsafe;
1106 long work;
1107 long send_sync;
1108 long wanted_sync_port = -1;
1109 ushort tdata[CHAN_MAX];
1110 long used_buffer;
1111
1112 mbuf = nd->nd_iobuf + UIO_BASE;
1113 buf = b = mbuf;
1114
1115 send_sync = nd->nd_link.lk_slow_rate < UIO_MAX;
1116
1117 ttotal = 0;
1118 tchan = 0;
1119
1120 memset(tdata, 0, sizeof(tdata));
1121
1122
1123 /*
1124 * If there are any outstanding requests to be serviced,
1125 * service them here.
1126 */
1127 if (nd->nd_send & NR_PASSWORD) {
1128
1129 /*
1130 * Send Password response.
1131 */
1132
1133 b[0] = 0xfc;
1134 b[1] = 0x20;
1135 put_unaligned_be16(strlen(nd->password), b + 2);
1136 b += 4;
1137 b += strlen(nd->password);
1138 nd->nd_send &= ~(NR_PASSWORD);
1139 }
1140
1141
1142 /*
1143 * Loop over all modules to generate commands, and determine
1144 * the amount of data queued for transmit.
1145 */
1146
1147 for (mod = 0, port = 0; port < nd->nd_chan_count; mod++) {
1148 /*
1149 * If this is not the current module, enter a module select
1150 * code in the buffer.
1151 */
1152
1153 if (mod != nd->nd_tx_module)
1154 mbuf = ++b;
1155
1156 /*
1157 * Loop to process one module.
1158 */
1159
1160 maxport = port + 16;
1161
1162 if (maxport > nd->nd_chan_count)
1163 maxport = nd->nd_chan_count;
1164
1165 for (; port < maxport; port++, ch++) {
1166 /*
1167 * Switch based on channel state.
1168 */
1169
1170 switch (ch->ch_state) {
1171 /*
1172 * Send requests when the port is closed, and there
1173 * are no Open, Close or Cancel requests expected.
1174 */
1175
1176 case CS_IDLE:
1177 /*
1178 * Wait until any open error code
1179 * has been delivered to all
1180 * associated ports.
1181 */
1182
1183 if (ch->ch_open_error) {
1184 if (ch->ch_wait_count[ch->ch_otype]) {
1185 work = 1;
1186 break;
1187 }
1188
1189 ch->ch_open_error = 0;
1190 }
1191
1192 /*
1193 * Wait until the channel HANGUP flag is reset
1194 * before sending the first open. We can only
1195 * get to this state after a server disconnect.
1196 */
1197
1198 if ((ch->ch_flag & CH_HANGUP) != 0)
1199 break;
1200
1201 /*
1202 * If recovering from a TCP disconnect, or if
1203 * there is an immediate open pending, send an
1204 * Immediate Open request.
1205 */
1206 if ((ch->ch_flag & CH_PORT_GONE) ||
1207 ch->ch_wait_count[OTYPE_IMMEDIATE] != 0) {
1208 b = set_cmd_header(b, port, 10);
1209 *b++ = 0;
1210
1211 ch->ch_state = CS_WAIT_OPEN;
1212 ch->ch_otype = OTYPE_IMMEDIATE;
1213 break;
1214 }
1215
1216 /*
1217 * If there is no Persistent or Incoming Open on the wait
1218 * list in the server, and a thread is waiting for a
1219 * Persistent or Incoming Open, send a Persistent or Incoming
1220 * Open Request.
1221 */
1222 if (ch->ch_otype_waiting == 0) {
1223 if (ch->ch_wait_count[OTYPE_PERSISTENT] != 0) {
1224 b = set_cmd_header(b, port, 10);
1225 *b++ = 1;
1226
1227 ch->ch_state = CS_WAIT_OPEN;
1228 ch->ch_otype = OTYPE_PERSISTENT;
1229 } else if (ch->ch_wait_count[OTYPE_INCOMING] != 0) {
1230 b = set_cmd_header(b, port, 10);
1231 *b++ = 2;
1232
1233 ch->ch_state = CS_WAIT_OPEN;
1234 ch->ch_otype = OTYPE_INCOMING;
1235 }
1236 break;
1237 }
1238
1239 /*
1240 * If a Persistent or Incoming Open is pending in
1241 * the server, but there is no longer an open
1242 * thread waiting for it, cancel the request.
1243 */
1244
1245 if (ch->ch_wait_count[ch->ch_otype_waiting] == 0) {
1246 b = set_cmd_header(b, port, 10);
1247 *b++ = 4;
1248
1249 ch->ch_state = CS_WAIT_CANCEL;
1250 ch->ch_otype = ch->ch_otype_waiting;
1251 }
1252 break;
1253
1254 /*
1255 * Send port parameter queries.
1256 */
1257 case CS_SEND_QUERY:
1258 /*
1259 * Clear out all FEP state that might remain
1260 * from the last connection.
1261 */
1262
1263 ch->ch_flag |= CH_PARAM;
1264
1265 ch->ch_flag &= ~CH_RX_FLUSH;
1266
1267 ch->ch_expect = 0;
1268
1269 ch->ch_s_tin = 0;
1270 ch->ch_s_tpos = 0;
1271 ch->ch_s_tsize = 0;
1272 ch->ch_s_treq = 0;
1273 ch->ch_s_elast = 0;
1274
1275 ch->ch_s_rin = 0;
1276 ch->ch_s_rwin = 0;
1277 ch->ch_s_rsize = 0;
1278
1279 ch->ch_s_tmax = 0;
1280 ch->ch_s_ttime = 0;
1281 ch->ch_s_rmax = 0;
1282 ch->ch_s_rtime = 0;
1283 ch->ch_s_rlow = 0;
1284 ch->ch_s_rhigh = 0;
1285
1286 ch->ch_s_brate = 0;
1287 ch->ch_s_iflag = 0;
1288 ch->ch_s_cflag = 0;
1289 ch->ch_s_oflag = 0;
1290 ch->ch_s_xflag = 0;
1291
1292 ch->ch_s_mout = 0;
1293 ch->ch_s_mflow = 0;
1294 ch->ch_s_mctrl = 0;
1295 ch->ch_s_xon = 0;
1296 ch->ch_s_xoff = 0;
1297 ch->ch_s_lnext = 0;
1298 ch->ch_s_xxon = 0;
1299 ch->ch_s_xxoff = 0;
1300
1301 /* Send Sequence Request */
1302 b = set_cmd_header(b, port, 14);
1303
1304 /* Configure Event Conditions Packet */
1305 b = set_cmd_header(b, port, 42);
1306 put_unaligned_be16(0x02c0, b);
1307 b += 2;
1308 *b++ = (DM_DTR | DM_RTS | DM_CTS |
1309 DM_DSR | DM_RI | DM_CD);
1310
1311 /* Send Status Request */
1312 b = set_cmd_header(b, port, 16);
1313
1314 /* Send Buffer Request */
1315 b = set_cmd_header(b, port, 20);
1316
1317 /* Send Port Capability Request */
1318 b = set_cmd_header(b, port, 22);
1319
1320 ch->ch_expect = (RR_SEQUENCE |
1321 RR_STATUS |
1322 RR_BUFFER |
1323 RR_CAPABILITY);
1324
1325 ch->ch_state = CS_WAIT_QUERY;
1326
1327 /* Raise modem signals */
1328 b = set_cmd_header(b, port, 44);
1329
1330 if (ch->ch_flag & CH_PORT_GONE)
1331 ch->ch_s_mout = ch->ch_mout;
1332 else
1333 ch->ch_s_mout = ch->ch_mout = DM_DTR | DM_RTS;
1334
1335 *b++ = ch->ch_mout;
1336 *b++ = ch->ch_s_mflow = 0;
1337 *b++ = ch->ch_s_mctrl = ch->ch_mctrl = 0;
1338
1339 if (ch->ch_flag & CH_PORT_GONE)
1340 ch->ch_flag &= ~CH_PORT_GONE;
1341
1342 break;
1343
1344 /*
1345 * Handle normal open and ready mode.
1346 */
1347
1348 case CS_READY:
1349
1350 /*
1351 * If the port is not open, and there are no
1352 * no longer any ports requesting an open,
1353 * then close the port.
1354 */
1355
1356 if (ch->ch_open_count == 0 &&
1357 ch->ch_wait_count[ch->ch_otype] == 0) {
1358 goto send_close;
1359 }
1360
1361 /*
1362 * Process waiting input.
1363 *
1364 * If there is no one to read it, discard the data.
1365 *
1366 * Otherwise if we are not in fastcook mode, or if there is a
1367 * fastcook thread waiting for data, send the data to the
1368 * line discipline.
1369 */
1370 if (ch->ch_rin != ch->ch_rout) {
1371 if (ch->ch_tun.un_open_count == 0 ||
1372 (ch->ch_tun.un_flag & UN_CLOSING) ||
1373 (ch->ch_cflag & CF_CREAD) == 0) {
1374 ch->ch_rout = ch->ch_rin;
1375 } else if ((ch->ch_flag & CH_FAST_READ) == 0 ||
1376 ch->ch_inwait != 0) {
1377 dgrp_input(ch);
1378
1379 if (ch->ch_rin != ch->ch_rout)
1380 work = 1;
1381 }
1382 }
1383
1384 /*
1385 * Handle receive flush, and changes to
1386 * server port parameters.
1387 */
1388
1389 if (ch->ch_flag & (CH_RX_FLUSH | CH_PARAM)) {
1390 /*
1391 * If we are in receive flush mode,
1392 * and enough data has gone by, reset
1393 * receive flush mode.
1394 */
1395 if (ch->ch_flag & CH_RX_FLUSH) {
1396 if (((ch->ch_flush_seq - nd->nd_seq_out) & SEQ_MASK) >
1397 ((nd->nd_seq_in - nd->nd_seq_out) & SEQ_MASK))
1398 ch->ch_flag &= ~CH_RX_FLUSH;
1399 else
1400 work = 1;
1401 }
1402
1403 /*
1404 * Send TMAX, TTIME.
1405 */
1406
1407 if (ch->ch_s_tmax != ch->ch_tmax ||
1408 ch->ch_s_ttime != ch->ch_ttime) {
1409 b = set_cmd_header(b, port, 48);
1410
1411 ch->ch_s_tmax = ch->ch_tmax;
1412 ch->ch_s_ttime = ch->ch_ttime;
1413
1414 put_unaligned_be16(ch->ch_s_tmax,
1415 b);
1416 b += 2;
1417
1418 put_unaligned_be16(ch->ch_s_ttime,
1419 b);
1420 b += 2;
1421 }
1422
1423 /*
1424 * Send RLOW, RHIGH.
1425 */
1426
1427 if (ch->ch_s_rlow != ch->ch_rlow ||
1428 ch->ch_s_rhigh != ch->ch_rhigh) {
1429 b = set_cmd_header(b, port, 45);
1430
1431 ch->ch_s_rlow = ch->ch_rlow;
1432 ch->ch_s_rhigh = ch->ch_rhigh;
1433
1434 put_unaligned_be16(ch->ch_s_rlow,
1435 b);
1436 b += 2;
1437
1438 put_unaligned_be16(ch->ch_s_rhigh,
1439 b);
1440 b += 2;
1441 }
1442
1443 /*
1444 * Send BRATE, CFLAG, IFLAG,
1445 * OFLAG, XFLAG.
1446 */
1447
1448 if (ch->ch_s_brate != ch->ch_brate ||
1449 ch->ch_s_cflag != ch->ch_cflag ||
1450 ch->ch_s_iflag != ch->ch_iflag ||
1451 ch->ch_s_oflag != ch->ch_oflag ||
1452 ch->ch_s_xflag != ch->ch_xflag) {
1453 b = set_cmd_header(b, port, 40);
1454
1455 ch->ch_s_brate = ch->ch_brate;
1456 ch->ch_s_cflag = ch->ch_cflag;
1457 ch->ch_s_iflag = ch->ch_iflag;
1458 ch->ch_s_oflag = ch->ch_oflag;
1459 ch->ch_s_xflag = ch->ch_xflag;
1460
1461 put_unaligned_be16(ch->ch_s_brate,
1462 b);
1463 b += 2;
1464
1465 put_unaligned_be16(ch->ch_s_cflag,
1466 b);
1467 b += 2;
1468
1469 put_unaligned_be16(ch->ch_s_iflag,
1470 b);
1471 b += 2;
1472
1473 put_unaligned_be16(ch->ch_s_oflag,
1474 b);
1475 b += 2;
1476
1477 put_unaligned_be16(ch->ch_s_xflag,
1478 b);
1479 b += 2;
1480 }
1481
1482 /*
1483 * Send MOUT, MFLOW, MCTRL.
1484 */
1485
1486 if (ch->ch_s_mout != ch->ch_mout ||
1487 ch->ch_s_mflow != ch->ch_mflow ||
1488 ch->ch_s_mctrl != ch->ch_mctrl) {
1489 b = set_cmd_header(b, port, 44);
1490
1491 *b++ = ch->ch_s_mout = ch->ch_mout;
1492 *b++ = ch->ch_s_mflow = ch->ch_mflow;
1493 *b++ = ch->ch_s_mctrl = ch->ch_mctrl;
1494 }
1495
1496 /*
1497 * Send Flow control characters.
1498 */
1499
1500 if (ch->ch_s_xon != ch->ch_xon ||
1501 ch->ch_s_xoff != ch->ch_xoff ||
1502 ch->ch_s_lnext != ch->ch_lnext ||
1503 ch->ch_s_xxon != ch->ch_xxon ||
1504 ch->ch_s_xxoff != ch->ch_xxoff) {
1505 b = set_cmd_header(b, port, 46);
1506
1507 *b++ = ch->ch_s_xon = ch->ch_xon;
1508 *b++ = ch->ch_s_xoff = ch->ch_xoff;
1509 *b++ = ch->ch_s_lnext = ch->ch_lnext;
1510 *b++ = ch->ch_s_xxon = ch->ch_xxon;
1511 *b++ = ch->ch_s_xxoff = ch->ch_xxoff;
1512 }
1513
1514 /*
1515 * Send RMAX, RTIME.
1516 */
1517
1518 if (ch->ch_s_rmax != ch->ch_rmax ||
1519 ch->ch_s_rtime != ch->ch_rtime) {
1520 b = set_cmd_header(b, port, 47);
1521
1522 ch->ch_s_rmax = ch->ch_rmax;
1523 ch->ch_s_rtime = ch->ch_rtime;
1524
1525 put_unaligned_be16(ch->ch_s_rmax,
1526 b);
1527 b += 2;
1528
1529 put_unaligned_be16(ch->ch_s_rtime,
1530 b);
1531 b += 2;
1532 }
1533
1534 ch->ch_flag &= ~CH_PARAM;
1535 wake_up_interruptible(&ch->ch_flag_wait);
1536 }
1537
1538
1539 /*
1540 * Handle action commands.
1541 */
1542
1543 if (ch->ch_send != 0) {
1544 /* int send = ch->ch_send & ~ch->ch_expect; */
1545 send = ch->ch_send & ~ch->ch_expect;
1546
1547 /* Send character immediate */
1548 if ((send & RR_TX_ICHAR) != 0) {
1549 b = set_cmd_header(b, port, 60);
1550
1551 *b++ = ch->ch_xon;
1552 ch->ch_expect |= RR_TX_ICHAR;
1553 }
1554
1555 /* BREAK request */
1556 if ((send & RR_TX_BREAK) != 0) {
1557 if (ch->ch_break_time != 0) {
1558 b = set_cmd_header(b, port, 61);
1559 put_unaligned_be16(ch->ch_break_time,
1560 b);
1561 b += 2;
1562
1563 ch->ch_expect |= RR_TX_BREAK;
1564 ch->ch_break_time = 0;
1565 } else {
1566 ch->ch_send &= ~RR_TX_BREAK;
1567 ch->ch_flag &= ~CH_TX_BREAK;
1568 wake_up_interruptible(&ch->ch_flag_wait);
1569 }
1570 }
1571
1572 /*
1573 * Flush input/output buffers.
1574 */
1575
1576 if ((send & (RR_RX_FLUSH | RR_TX_FLUSH)) != 0) {
1577 b = set_cmd_header(b, port, 62);
1578
1579 *b++ = ((send & RR_TX_FLUSH) == 0 ? 1 :
1580 (send & RR_RX_FLUSH) == 0 ? 2 : 3);
1581
1582 if (send & RR_RX_FLUSH) {
1583 ch->ch_flush_seq = nd->nd_seq_in;
1584 ch->ch_flag |= CH_RX_FLUSH;
1585 work = 1;
1586 send_sync = 1;
1587 wanted_sync_port = port;
1588 }
1589
1590 ch->ch_send &= ~(RR_RX_FLUSH | RR_TX_FLUSH);
1591 }
1592
1593 /* Pause input/output */
1594 if ((send & (RR_RX_STOP | RR_TX_STOP)) != 0) {
1595 b = set_cmd_header(b, port, 63);
1596 *b = 0;
1597
1598 if ((send & RR_TX_STOP) != 0)
1599 *b |= EV_OPU;
1600
1601 if ((send & RR_RX_STOP) != 0)
1602 *b |= EV_IPU;
1603
1604 b++;
1605
1606 ch->ch_send &= ~(RR_RX_STOP | RR_TX_STOP);
1607 }
1608
1609 /* Start input/output */
1610 if ((send & (RR_RX_START | RR_TX_START)) != 0) {
1611 b = set_cmd_header(b, port, 64);
1612 *b = 0;
1613
1614 if ((send & RR_TX_START) != 0)
1615 *b |= EV_OPU | EV_OPS | EV_OPX;
1616
1617 if ((send & RR_RX_START) != 0)
1618 *b |= EV_IPU | EV_IPS;
1619
1620 b++;
1621
1622 ch->ch_send &= ~(RR_RX_START | RR_TX_START);
1623 }
1624 }
1625
1626
1627 /*
1628 * Send a window sequence to acknowledge received data.
1629 */
1630
1631 rwin = (ch->ch_s_rin +
1632 ((ch->ch_rout - ch->ch_rin - 1) & RBUF_MASK));
1633
1634 n = (rwin - ch->ch_s_rwin) & 0xffff;
1635
1636 if (n >= RBUF_MAX / 4) {
1637 b[0] = 0xa0 + (port & 0xf);
1638 ch->ch_s_rwin = rwin;
1639 put_unaligned_be16(rwin, b + 1);
1640 b += 3;
1641 }
1642
1643 /*
1644 * If the terminal is waiting on LOW
1645 * water or EMPTY, and the condition
1646 * is now satisfied, call the line
1647 * discipline to put more data in the
1648 * buffer.
1649 */
1650
1651 n = (ch->ch_tin - ch->ch_tout) & TBUF_MASK;
1652
1653 if ((ch->ch_tun.un_flag & (UN_EMPTY|UN_LOW)) != 0) {
1654 if ((ch->ch_tun.un_flag & UN_LOW) != 0 ?
1655 (n <= TBUF_LOW) :
1656 (n == 0 && ch->ch_s_tpos == ch->ch_s_tin)) {
1657 ch->ch_tun.un_flag &= ~(UN_EMPTY|UN_LOW);
1658
1659 if (waitqueue_active(&((ch->ch_tun.un_tty)->write_wait)))
1660 wake_up_interruptible(&((ch->ch_tun.un_tty)->write_wait));
1661 tty_wakeup(ch->ch_tun.un_tty);
1662 n = (ch->ch_tin - ch->ch_tout) & TBUF_MASK;
1663 }
1664 }
1665
1666 /*
1667 * If the printer is waiting on LOW
1668 * water, TIME, EMPTY or PWAIT, and is
1669 * now ready to put more data in the
1670 * buffer, call the line discipline to
1671 * do the job.
1672 */
1673
1674 if (ch->ch_pun.un_open_count &&
1675 (ch->ch_pun.un_flag &
1676 (UN_EMPTY|UN_TIME|UN_LOW|UN_PWAIT)) != 0) {
1677
1678 if ((ch->ch_pun.un_flag & UN_LOW) != 0 ?
1679 (n <= TBUF_LOW) :
1680 (ch->ch_pun.un_flag & UN_TIME) != 0 ?
1681 ((jiffies - ch->ch_waketime) >= 0) :
1682 (n == 0 && ch->ch_s_tpos == ch->ch_s_tin) &&
1683 ((ch->ch_pun.un_flag & UN_EMPTY) != 0 ||
1684 ((ch->ch_tun.un_open_count &&
1685 ch->ch_tun.un_tty->ops->chars_in_buffer) ?
1686 (ch->ch_tun.un_tty->ops->chars_in_buffer)(ch->ch_tun.un_tty) == 0
1687 : 1
1688 )
1689 )) {
1690 ch->ch_pun.un_flag &= ~(UN_EMPTY | UN_TIME | UN_LOW | UN_PWAIT);
1691
1692 if (waitqueue_active(&((ch->ch_pun.un_tty)->write_wait)))
1693 wake_up_interruptible(&((ch->ch_pun.un_tty)->write_wait));
1694 tty_wakeup(ch->ch_pun.un_tty);
1695 n = (ch->ch_tin - ch->ch_tout) & TBUF_MASK;
1696
1697 } else if ((ch->ch_pun.un_flag & UN_TIME) != 0) {
1698 work = 1;
1699 }
1700 }
1701
1702
1703 /*
1704 * Determine the max number of bytes
1705 * this port can send, including
1706 * packet header overhead.
1707 */
1708
1709 t = ((ch->ch_s_tsize + ch->ch_s_tpos - ch->ch_s_tin) & 0xffff);
1710
1711 if (n > t)
1712 n = t;
1713
1714 if (n != 0) {
1715 n += (n <= 8 ? 1 : n <= 255 ? 2 : 3);
1716
1717 tdata[tchan++] = n;
1718 ttotal += n;
1719 }
1720 break;
1721
1722 /*
1723 * Close the port.
1724 */
1725
1726send_close:
1727 case CS_SEND_CLOSE:
1728 b = set_cmd_header(b, port, 10);
1729 if (ch->ch_otype == OTYPE_IMMEDIATE)
1730 *b++ = 3;
1731 else
1732 *b++ = 4;
1733
1734 ch->ch_state = CS_WAIT_CLOSE;
1735 break;
1736
1737 /*
1738 * Wait for a previous server request.
1739 */
1740
1741 case CS_WAIT_OPEN:
1742 case CS_WAIT_CANCEL:
1743 case CS_WAIT_FAIL:
1744 case CS_WAIT_QUERY:
1745 case CS_WAIT_CLOSE:
1746 break;
1747
1748 default:
1749 pr_info("%s - unexpected channel state (%i)\n",
1750 __func__, ch->ch_state);
1751 }
1752 }
1753
1754 /*
1755 * If a module select code is needed, drop one in. If space
1756 * was reserved for one, but none is needed, recover the space.
1757 */
1758
1759 if (mod != nd->nd_tx_module) {
1760 if (b != mbuf) {
1761 mbuf[-1] = 0xf0 | mod;
1762 nd->nd_tx_module = mod;
1763 } else {
1764 b--;
1765 }
1766 }
1767 }
1768
1769 /*
1770 * Adjust "tmax" so that under worst case conditions we do
1771 * not overflow either the daemon buffer or the internal
1772 * buffer in the loop that follows. Leave a safe area
1773 * of 64 bytes so we start getting asserts before we start
1774 * losing data or clobbering memory.
1775 */
1776
1777 n = UIO_MAX - UIO_BASE;
1778
1779 if (tmax > n)
1780 tmax = n;
1781
1782 tmax -= 64;
1783
1784 tsafe = tmax;
1785
1786 /*
1787 * Allocate space for 5 Module Selects, 1 Sequence Request,
1788 * and 1 Set TREQ for each active channel.
1789 */
1790
1791 tmax -= 5 + 3 + 4 * nd->nd_chan_count;
1792
1793 /*
1794 * Further reduce "tmax" to the available transmit credit.
1795 * Note that this is a soft constraint; The transmit credit
1796 * can go negative for a time and then recover.
1797 */
1798
1799 n = nd->nd_tx_deposit - nd->nd_tx_charge - nd->nd_link.lk_header_size;
1800
1801 if (tmax > n)
1802 tmax = n;
1803
1804 /*
1805 * Finally reduce tmax by the number of bytes already in
1806 * the buffer.
1807 */
1808
1809 tmax -= b - buf;
1810
1811 /*
1812 * Suspend data transmit unless every ready channel can send
1813 * at least 1 character.
1814 */
1815 if (tmax < 2 * nd->nd_chan_count) {
1816 tsend = 1;
1817
1818 } else if (tchan > 1 && ttotal > tmax) {
1819
1820 /*
1821 * If transmit is limited by the credit budget, find the
1822 * largest number of characters we can send without driving
1823 * the credit negative.
1824 */
1825
1826 long tm = tmax;
1827 int tc = tchan;
1828 int try;
1829
1830 tsend = tm / tc;
1831
1832 for (try = 0; try < 3; try++) {
1833 int i;
1834 int c = 0;
1835
1836 for (i = 0; i < tc; i++) {
1837 if (tsend < tdata[i])
1838 tdata[c++] = tdata[i];
1839 else
1840 tm -= tdata[i];
1841 }
1842
1843 if (c == tc)
1844 break;
1845
1846 tsend = tm / c;
1847
1848 if (c == 1)
1849 break;
1850
1851 tc = c;
1852 }
1853
1854 tsend = tm / nd->nd_chan_count;
1855
1856 if (tsend < 2)
1857 tsend = 1;
1858
1859 } else {
1860 /*
1861 * If no budgetary constraints, or only one channel ready
1862 * to send, set the character limit to the remaining
1863 * buffer size.
1864 */
1865
1866 tsend = tmax;
1867 }
1868
1869 tsend -= (tsend <= 9) ? 1 : (tsend <= 257) ? 2 : 3;
1870
1871 /*
1872 * Loop over all channels, sending queued data.
1873 */
1874
1875 port = 0;
1876 ch = nd->nd_chan;
1877 used_buffer = tmax;
1878
1879 for (mod = 0; port < nd->nd_chan_count; mod++) {
1880 /*
1881 * If this is not the current module, enter a module select
1882 * code in the buffer.
1883 */
1884
1885 if (mod != nd->nd_tx_module)
1886 mbuf = ++b;
1887
1888 /*
1889 * Loop to process one module.
1890 */
1891
1892 maxport = port + 16;
1893
1894 if (maxport > nd->nd_chan_count)
1895 maxport = nd->nd_chan_count;
1896
1897 for (; port < maxport; port++, ch++) {
1898 if (ch->ch_state != CS_READY)
1899 continue;
1900
1901 lastport = port;
1902
1903 n = (ch->ch_tin - ch->ch_tout) & TBUF_MASK;
1904
1905 /*
1906 * If there is data that can be sent, send it.
1907 */
1908
1909 if (n != 0 && used_buffer > 0) {
1910 t = (ch->ch_s_tsize + ch->ch_s_tpos - ch->ch_s_tin) & 0xffff;
1911
1912 if (n > t)
1913 n = t;
1914
1915 if (n > tsend) {
1916 work = 1;
1917 n = tsend;
1918 }
1919
1920 if (n > used_buffer) {
1921 work = 1;
1922 n = used_buffer;
1923 }
1924
1925 if (n <= 0)
1926 continue;
1927
1928 /*
1929 * Create the correct size transmit header,
1930 * depending on the amount of data to transmit.
1931 */
1932
1933 if (n <= 8) {
1934
1935 b[0] = ((n - 1) << 4) + (port & 0xf);
1936 b += 1;
1937
1938 } else if (n <= 255) {
1939
1940 b[0] = 0x80 + (port & 0xf);
1941 b[1] = n;
1942 b += 2;
1943
1944 } else {
1945
1946 b[0] = 0x90 + (port & 0xf);
1947 put_unaligned_be16(n, b + 1);
1948 b += 3;
1949 }
1950
1951 ch->ch_s_tin = (ch->ch_s_tin + n) & 0xffff;
1952
1953 /*
1954 * Copy transmit data to the packet.
1955 */
1956
1957 t = TBUF_MAX - ch->ch_tout;
1958
1959 if (n >= t) {
1960 memcpy(b, ch->ch_tbuf + ch->ch_tout, t);
1961 b += t;
1962 n -= t;
1963 used_buffer -= t;
1964 ch->ch_tout = 0;
1965 }
1966
1967 memcpy(b, ch->ch_tbuf + ch->ch_tout, n);
1968 b += n;
1969 used_buffer -= n;
1970 ch->ch_tout += n;
1971 n = (ch->ch_tin - ch->ch_tout) & TBUF_MASK;
1972 }
1973
1974 /*
1975 * Wake any terminal unit process waiting in the
1976 * dgrp_write routine for low water.
1977 */
1978
1979 if (n > TBUF_LOW)
1980 continue;
1981
1982 if ((ch->ch_flag & CH_LOW) != 0) {
1983 ch->ch_flag &= ~CH_LOW;
1984 wake_up_interruptible(&ch->ch_flag_wait);
1985 }
1986
1987 /* selwakeup tty_sel */
1988 if (ch->ch_tun.un_open_count) {
1989 struct tty_struct *tty = (ch->ch_tun.un_tty);
1990
1991 if (waitqueue_active(&tty->write_wait))
1992 wake_up_interruptible(&tty->write_wait);
1993
1994 tty_wakeup(tty);
1995 }
1996
1997 if (ch->ch_pun.un_open_count) {
1998 struct tty_struct *tty = (ch->ch_pun.un_tty);
1999
2000 if (waitqueue_active(&tty->write_wait))
2001 wake_up_interruptible(&tty->write_wait);
2002
2003 tty_wakeup(tty);
2004 }
2005
2006 /*
2007 * Do EMPTY processing.
2008 */
2009
2010 if (n != 0)
2011 continue;
2012
2013 if ((ch->ch_flag & (CH_EMPTY | CH_DRAIN)) != 0 ||
2014 (ch->ch_pun.un_flag & UN_EMPTY) != 0) {
2015 /*
2016 * If there is still data in the server, ask the server
2017 * to notify us when its all gone.
2018 */
2019
2020 if (ch->ch_s_treq != ch->ch_s_tin) {
2021 b = set_cmd_header(b, port, 43);
2022
2023 ch->ch_s_treq = ch->ch_s_tin;
2024 put_unaligned_be16(ch->ch_s_treq,
2025 b);
2026 b += 2;
2027 }
2028
2029 /*
2030 * If there is a thread waiting for buffer empty,
2031 * and we are truly empty, wake the thread.
2032 */
2033
2034 else if ((ch->ch_flag & CH_EMPTY) != 0 &&
2035 (ch->ch_send & RR_TX_BREAK) == 0) {
2036 ch->ch_flag &= ~CH_EMPTY;
2037
2038 wake_up_interruptible(&ch->ch_flag_wait);
2039 }
2040 }
2041 }
2042
2043 /*
2044 * If a module select code is needed, drop one in. If space
2045 * was reserved for one, but none is needed, recover the space.
2046 */
2047
2048 if (mod != nd->nd_tx_module) {
2049 if (b != mbuf) {
2050 mbuf[-1] = 0xf0 | mod;
2051 nd->nd_tx_module = mod;
2052 } else {
2053 b--;
2054 }
2055 }
2056 }
2057
2058 /*
2059 * Send a synchronization sequence associated with the last open
2060 * channel that sent data, and remember the time when the data was
2061 * sent.
2062 */
2063
2064 in = nd->nd_seq_in;
2065
2066 if ((send_sync || nd->nd_seq_wait[in] != 0) && lastport >= 0) {
2067 u8 *bb = b;
2068
2069 /*
2070 * Attempt the use the port that really wanted the sync.
2071 * This gets around a race condition where the "lastport" is in
2072 * the middle of the close() routine, and by the time we
2073 * send this command, it will have already acked the close, and
2074 * thus not send the sync response.
2075 */
2076 if (wanted_sync_port >= 0)
2077 lastport = wanted_sync_port;
2078 /*
2079 * Set a flag just in case the port is in the middle of a close,
2080 * it will not be permitted to actually close until we get an
2081 * sync response, and clear the flag there.
2082 */
2083 ch = nd->nd_chan + lastport;
2084 ch->ch_flag |= CH_WAITING_SYNC;
2085
2086 mod = lastport >> 4;
2087
2088 if (mod != nd->nd_tx_module) {
2089 bb[0] = 0xf0 + mod;
2090 bb += 1;
2091
2092 nd->nd_tx_module = mod;
2093 }
2094
2095 bb = set_cmd_header(bb, lastport, 12);
2096 *bb++ = in;
2097
2098 nd->nd_seq_size[in] = bb - buf;
2099 nd->nd_seq_time[in] = jiffies;
2100
2101 if (++in >= SEQ_MAX)
2102 in = 0;
2103
2104 if (in != nd->nd_seq_out) {
2105 b = bb;
2106 nd->nd_seq_in = in;
2107 nd->nd_unack += b - buf;
2108 }
2109 }
2110
2111 /*
2112 * If there are no open ports, a sync cannot be sent.
2113 * There is nothing left to wait for anyway, so wake any
2114 * thread waiting for an acknowledgement.
2115 */
2116
2117 else if (nd->nd_seq_wait[in] != 0) {
2118 nd->nd_seq_wait[in] = 0;
2119
2120 wake_up_interruptible(&nd->nd_seq_wque[in]);
2121 }
2122
2123 /*
2124 * If there is no traffic for an interval of IDLE_MAX, then
2125 * send a single byte packet.
2126 */
2127
2128 if (b != buf) {
2129 nd->nd_tx_time = jiffies;
2130 } else if ((ulong)(jiffies - nd->nd_tx_time) >= IDLE_MAX) {
2131 *b++ = 0xf0 | nd->nd_tx_module;
2132 nd->nd_tx_time = jiffies;
2133 }
2134
2135 n = b - buf;
2136
2137 if (n >= tsafe)
2138 pr_info("%s - n(%i) >= tsafe(%i)\n",
2139 __func__, n, tsafe);
2140
2141 if (tsend < 0)
2142 dgrp_dump(buf, n);
2143
2144 nd->nd_tx_work = work;
2145
2146 return n;
2147}
2148
2149/*
2150 * dgrp_net_read()
2151 * Data to be sent TO the PortServer from the "async." half of the driver.
2152 */
2153static ssize_t dgrp_net_read(struct file *file, char __user *buf, size_t count,
2154 loff_t *ppos)
2155{
2156 struct nd_struct *nd;
2157 long n;
2158 u8 *local_buf;
2159 u8 *b;
2160 ssize_t rtn;
2161
2162 /*
2163 * Get the node pointer, and quit if it doesn't exist.
2164 */
2165 nd = (struct nd_struct *)(file->private_data);
2166 if (!nd)
2167 return -ENXIO;
2168
2169 if (count < UIO_MIN)
2170 return -EINVAL;
2171
2172 /*
2173 * Only one read/write operation may be in progress at
2174 * any given time.
2175 */
2176
2177 /*
2178 * Grab the NET lock.
2179 */
2180 down(&nd->nd_net_semaphore);
2181
2182 nd->nd_read_count++;
2183
2184 nd->nd_tx_ready = 0;
2185
2186 /*
2187 * Determine the effective size of the buffer.
2188 */
2189
2190 if (nd->nd_remain > UIO_BASE)
2191 pr_info_ratelimited("%s - nd_remain(%i) > UIO_BASE\n",
2192 __func__, nd->nd_remain);
2193
2194 b = local_buf = nd->nd_iobuf + UIO_BASE;
2195
2196 /*
2197 * Generate data according to the node state.
2198 */
2199
2200 switch (nd->nd_state) {
2201 /*
2202 * Initialize the connection.
2203 */
2204
2205 case NS_IDLE:
2206 if (nd->nd_mon_buf)
2207 dgrp_monitor_reset(nd);
2208
2209 /*
2210 * Request a Product ID Packet.
2211 */
2212
2213 b[0] = 0xfb;
2214 b[1] = 0x01;
2215 b += 2;
2216
2217 nd->nd_expect |= NR_IDENT;
2218
2219 /*
2220 * Request a Server Capability ID Response.
2221 */
2222
2223 b[0] = 0xfb;
2224 b[1] = 0x02;
2225 b += 2;
2226
2227 nd->nd_expect |= NR_CAPABILITY;
2228
2229 /*
2230 * Request a Server VPD Response.
2231 */
2232
2233 b[0] = 0xfb;
2234 b[1] = 0x18;
2235 b += 2;
2236
2237 nd->nd_expect |= NR_VPD;
2238
2239 nd->nd_state = NS_WAIT_QUERY;
2240 break;
2241
2242 /*
2243 * We do serious communication with the server only in
2244 * the READY state.
2245 */
2246
2247 case NS_READY:
2248 b = dgrp_send(nd, count) + local_buf;
2249 break;
2250
2251 /*
2252 * Send off an error after receiving a bogus message
2253 * from the server.
2254 */
2255
2256 case NS_SEND_ERROR:
2257 n = strlen(nd->nd_error);
2258
2259 b[0] = 0xff;
2260 b[1] = n;
2261 memcpy(b + 2, nd->nd_error, n);
2262 b += 2 + n;
2263
2264 dgrp_net_idle(nd);
2265 /*
2266 * Set the active port count to zero.
2267 */
2268 dgrp_chan_count(nd, 0);
2269 break;
2270
2271 default:
2272 break;
2273 }
2274
2275 n = b - local_buf;
2276
2277 if (n != 0) {
2278 nd->nd_send_count++;
2279
2280 nd->nd_tx_byte += n + nd->nd_link.lk_header_size;
2281 nd->nd_tx_charge += n + nd->nd_link.lk_header_size;
2282 }
2283
2284 rtn = copy_to_user((void __user *)buf, local_buf, n);
2285 if (rtn) {
2286 rtn = -EFAULT;
2287 goto done;
2288 }
2289
2290 *ppos += n;
2291
2292 rtn = n;
2293
2294 if (nd->nd_mon_buf)
2295 dgrp_monitor_data(nd, RPDUMP_CLIENT, local_buf, n);
2296
2297 /*
2298 * Release the NET lock.
2299 */
2300done:
2301 up(&nd->nd_net_semaphore);
2302
2303 return rtn;
2304}
2305
2306/**
2307 * dgrp_receive() -- decode data packets received from the remote PortServer.
2308 * @nd: pointer to a node structure
2309 */
2310static void dgrp_receive(struct nd_struct *nd)
2311{
2312 struct ch_struct *ch;
2313 u8 *buf;
2314 u8 *b;
2315 u8 *dbuf;
2316 char *error;
2317 long port;
2318 long dlen;
2319 long plen;
2320 long remain;
2321 long n;
2322 long mlast;
2323 long elast;
2324 long mstat;
2325 long estat;
2326
2327 char ID[3];
2328
2329 nd->nd_tx_time = jiffies;
2330
2331 ID_TO_CHAR(nd->nd_ID, ID);
2332
2333 b = buf = nd->nd_iobuf;
2334 remain = nd->nd_remain;
2335
2336 /*
2337 * Loop to process Realport protocol packets.
2338 */
2339
2340 while (remain > 0) {
2341 int n0 = b[0] >> 4;
2342 int n1 = b[0] & 0x0f;
2343
2344 if (n0 <= 12) {
2345 port = (nd->nd_rx_module << 4) + n1;
2346
2347 if (port >= nd->nd_chan_count) {
2348 error = "Improper Port Number";
2349 goto prot_error;
2350 }
2351
2352 ch = nd->nd_chan + port;
2353 } else {
2354 port = -1;
2355 ch = NULL;
2356 }
2357
2358 /*
2359 * Process by major packet type.
2360 */
2361
2362 switch (n0) {
2363
2364 /*
2365 * Process 1-byte header data packet.
2366 */
2367
2368 case 0:
2369 case 1:
2370 case 2:
2371 case 3:
2372 case 4:
2373 case 5:
2374 case 6:
2375 case 7:
2376 dlen = n0 + 1;
2377 plen = dlen + 1;
2378
2379 dbuf = b + 1;
2380 goto data;
2381
2382 /*
2383 * Process 2-byte header data packet.
2384 */
2385
2386 case 8:
2387 if (remain < 3)
2388 goto done;
2389
2390 dlen = b[1];
2391 plen = dlen + 2;
2392
2393 dbuf = b + 2;
2394 goto data;
2395
2396 /*
2397 * Process 3-byte header data packet.
2398 */
2399
2400 case 9:
2401 if (remain < 4)
2402 goto done;
2403
2404 dlen = get_unaligned_be16(b + 1);
2405 plen = dlen + 3;
2406
2407 dbuf = b + 3;
2408
2409 /*
2410 * Common packet handling code.
2411 */
2412
2413data:
2414 nd->nd_tx_work = 1;
2415
2416 /*
2417 * Otherwise data should appear only when we are
2418 * in the CS_READY state.
2419 */
2420
2421 if (ch->ch_state < CS_READY) {
2422 error = "Data received before RWIN established";
2423 goto prot_error;
2424 }
2425
2426 /*
2427 * Assure that the data received is within the
2428 * allowable window.
2429 */
2430
2431 n = (ch->ch_s_rwin - ch->ch_s_rin) & 0xffff;
2432
2433 if (dlen > n) {
2434 error = "Receive data overrun";
2435 goto prot_error;
2436 }
2437
2438 /*
2439 * If we received 3 or less characters,
2440 * assume it is a human typing, and set RTIME
2441 * to 10 milliseconds.
2442 *
2443 * If we receive 10 or more characters,
2444 * assume its not a human typing, and set RTIME
2445 * to 100 milliseconds.
2446 */
2447
2448 if (ch->ch_edelay != DGRP_RTIME) {
2449 if (ch->ch_rtime != ch->ch_edelay) {
2450 ch->ch_rtime = ch->ch_edelay;
2451 ch->ch_flag |= CH_PARAM;
2452 }
2453 } else if (dlen <= 3) {
2454 if (ch->ch_rtime != 10) {
2455 ch->ch_rtime = 10;
2456 ch->ch_flag |= CH_PARAM;
2457 }
2458 } else {
2459 if (ch->ch_rtime != DGRP_RTIME) {
2460 ch->ch_rtime = DGRP_RTIME;
2461 ch->ch_flag |= CH_PARAM;
2462 }
2463 }
2464
2465 /*
2466 * If a portion of the packet is outside the
2467 * buffer, shorten the effective length of the
2468 * data packet to be the amount of data received.
2469 */
2470
2471 if (remain < plen)
2472 dlen -= plen - remain;
2473
2474 /*
2475 * Detect if receive flush is now complete.
2476 */
2477
2478 if ((ch->ch_flag & CH_RX_FLUSH) != 0 &&
2479 ((ch->ch_flush_seq - nd->nd_seq_out) & SEQ_MASK) >=
2480 ((nd->nd_seq_in - nd->nd_seq_out) & SEQ_MASK)) {
2481 ch->ch_flag &= ~CH_RX_FLUSH;
2482 }
2483
2484 /*
2485 * If we are ready to receive, move the data into
2486 * the receive buffer.
2487 */
2488
2489 ch->ch_s_rin = (ch->ch_s_rin + dlen) & 0xffff;
2490
2491 if (ch->ch_state == CS_READY &&
2492 (ch->ch_tun.un_open_count != 0) &&
2493 (ch->ch_tun.un_flag & UN_CLOSING) == 0 &&
2494 (ch->ch_cflag & CF_CREAD) != 0 &&
2495 (ch->ch_flag & (CH_BAUD0 | CH_RX_FLUSH)) == 0 &&
2496 (ch->ch_send & RR_RX_FLUSH) == 0) {
2497
2498 if (ch->ch_rin + dlen >= RBUF_MAX) {
2499 n = RBUF_MAX - ch->ch_rin;
2500
2501 memcpy(ch->ch_rbuf + ch->ch_rin, dbuf, n);
2502
2503 ch->ch_rin = 0;
2504 dbuf += n;
2505 dlen -= n;
2506 }
2507
2508 memcpy(ch->ch_rbuf + ch->ch_rin, dbuf, dlen);
2509
2510 ch->ch_rin += dlen;
2511
2512
2513 /*
2514 * If we are not in fastcook mode, or
2515 * if there is a fastcook thread
2516 * waiting for data, send the data to
2517 * the line discipline.
2518 */
2519
2520 if ((ch->ch_flag & CH_FAST_READ) == 0 ||
2521 ch->ch_inwait != 0) {
2522 dgrp_input(ch);
2523 }
2524
2525 /*
2526 * If there is a read thread waiting
2527 * in select, and we are in fastcook
2528 * mode, wake him up.
2529 */
2530
2531 if (waitqueue_active(&ch->ch_tun.un_tty->read_wait) &&
2532 (ch->ch_flag & CH_FAST_READ) != 0)
2533 wake_up_interruptible(&ch->ch_tun.un_tty->read_wait);
2534
2535 /*
2536 * Wake any thread waiting in the
2537 * fastcook loop.
2538 */
2539
2540 if ((ch->ch_flag & CH_INPUT) != 0) {
2541 ch->ch_flag &= ~CH_INPUT;
2542
2543 wake_up_interruptible(&ch->ch_flag_wait);
2544 }
2545 }
2546
2547 /*
2548 * Fabricate and insert a data packet header to
2549 * preceed the remaining data when it comes in.
2550 */
2551
2552 if (remain < plen) {
2553 dlen = plen - remain;
2554 b = buf;
2555
2556 b[0] = 0x90 + n1;
2557 put_unaligned_be16(dlen, b + 1);
2558
2559 remain = 3;
2560 goto done;
2561 }
2562 break;
2563
2564 /*
2565 * Handle Window Sequence packets.
2566 */
2567
2568 case 10:
2569 plen = 3;
2570 if (remain < plen)
2571 goto done;
2572
2573 nd->nd_tx_work = 1;
2574
2575 {
2576 ushort tpos = get_unaligned_be16(b + 1);
2577
2578 ushort ack = (tpos - ch->ch_s_tpos) & 0xffff;
2579 ushort unack = (ch->ch_s_tin - ch->ch_s_tpos) & 0xffff;
2580 ushort notify = (ch->ch_s_treq - ch->ch_s_tpos) & 0xffff;
2581
2582 if (ch->ch_state < CS_READY || ack > unack) {
2583 error = "Improper Window Sequence";
2584 goto prot_error;
2585 }
2586
2587 ch->ch_s_tpos = tpos;
2588
2589 if (notify <= ack)
2590 ch->ch_s_treq = tpos;
2591 }
2592 break;
2593
2594 /*
2595 * Handle Command response packets.
2596 */
2597
2598 case 11:
2599
2600 /*
2601 * RealPort engine fix - 03/11/2004
2602 *
2603 * This check did not used to be here.
2604 *
2605 * We were using b[1] without verifying that the data
2606 * is actually there and valid. On a split packet, it
2607 * might not be yet.
2608 *
2609 * NOTE: I have never actually seen the failure happen
2610 * under Linux, but since I have seen it occur
2611 * under both Solaris and HP-UX, the assumption
2612 * is that it *could* happen here as well...
2613 */
2614 if (remain < 2)
2615 goto done;
2616
2617
2618 switch (b[1]) {
2619
2620 /*
2621 * Handle Open Response.
2622 */
2623
2624 case 11:
2625 plen = 6;
2626 if (remain < plen)
2627 goto done;
2628
2629 nd->nd_tx_work = 1;
2630
2631 {
2632 int req = b[2];
2633 int resp = b[3];
2634 port = get_unaligned_be16(b + 4);
2635
2636 if (port >= nd->nd_chan_count) {
2637 error = "Open channel number out of range";
2638 goto prot_error;
2639 }
2640
2641 ch = nd->nd_chan + port;
2642
2643 /*
2644 * How we handle an open response depends primarily
2645 * on our current channel state.
2646 */
2647
2648 switch (ch->ch_state) {
2649 case CS_IDLE:
2650
2651 /*
2652 * Handle a delayed open.
2653 */
2654
2655 if (ch->ch_otype_waiting != 0 &&
2656 req == ch->ch_otype_waiting &&
2657 resp == 0) {
2658 ch->ch_otype = req;
2659 ch->ch_otype_waiting = 0;
2660 ch->ch_state = CS_SEND_QUERY;
2661 break;
2662 }
2663 goto open_error;
2664
2665 case CS_WAIT_OPEN:
2666
2667 /*
2668 * Handle the open response.
2669 */
2670
2671 if (req == ch->ch_otype) {
2672 switch (resp) {
2673
2674 /*
2675 * On successful response, open the
2676 * port and proceed normally.
2677 */
2678
2679 case 0:
2680 ch->ch_state = CS_SEND_QUERY;
2681 break;
2682
2683 /*
2684 * On a busy response to a persistent open,
2685 * remember that the open is pending.
2686 */
2687
2688 case 1:
2689 case 2:
2690 if (req != OTYPE_IMMEDIATE) {
2691 ch->ch_otype_waiting = req;
2692 ch->ch_state = CS_IDLE;
2693 break;
2694 }
2695
2696 /*
2697 * Otherwise the server open failed. If
2698 * the Unix port is open, hang it up.
2699 */
2700
2701 default:
2702 if (ch->ch_open_count != 0) {
2703 ch->ch_flag |= CH_HANGUP;
2704 dgrp_carrier(ch);
2705 ch->ch_state = CS_IDLE;
2706 break;
2707 }
2708
2709 ch->ch_open_error = resp;
2710 ch->ch_state = CS_IDLE;
2711
2712 wake_up_interruptible(&ch->ch_flag_wait);
2713 }
2714 break;
2715 }
2716
2717 /*
2718 * Handle delayed response arrival preceeding
2719 * the open response we are waiting for.
2720 */
2721
2722 if (ch->ch_otype_waiting != 0 &&
2723 req == ch->ch_otype_waiting &&
2724 resp == 0) {
2725 ch->ch_otype = ch->ch_otype_waiting;
2726 ch->ch_otype_waiting = 0;
2727 ch->ch_state = CS_WAIT_FAIL;
2728 break;
2729 }
2730 goto open_error;
2731
2732
2733 case CS_WAIT_FAIL:
2734
2735 /*
2736 * Handle response to immediate open arriving
2737 * after a delayed open success.
2738 */
2739
2740 if (req == OTYPE_IMMEDIATE) {
2741 ch->ch_state = CS_SEND_QUERY;
2742 break;
2743 }
2744 goto open_error;
2745
2746
2747 case CS_WAIT_CANCEL:
2748 /*
2749 * Handle delayed open response arriving before
2750 * the cancel response.
2751 */
2752
2753 if (req == ch->ch_otype_waiting &&
2754 resp == 0) {
2755 ch->ch_otype_waiting = 0;
2756 break;
2757 }
2758
2759 /*
2760 * Handle cancel response.
2761 */
2762
2763 if (req == 4 && resp == 0) {
2764 ch->ch_otype_waiting = 0;
2765 ch->ch_state = CS_IDLE;
2766 break;
2767 }
2768 goto open_error;
2769
2770
2771 case CS_WAIT_CLOSE:
2772 /*
2773 * Handle a successful response to a port
2774 * close.
2775 */
2776
2777 if (req >= 3) {
2778 ch->ch_state = CS_IDLE;
2779 break;
2780 }
2781 goto open_error;
2782
2783open_error:
2784 default:
2785 {
2786 error = "Improper Open Response";
2787 goto prot_error;
2788 }
2789 }
2790 }
2791 break;
2792
2793 /*
2794 * Handle Synchronize Response.
2795 */
2796
2797 case 13:
2798 plen = 3;
2799 if (remain < plen)
2800 goto done;
2801 {
2802 int seq = b[2];
2803 int s;
2804
2805 /*
2806 * If channel was waiting for this sync response,
2807 * unset the flag, and wake up anyone waiting
2808 * on the event.
2809 */
2810 if (ch->ch_flag & CH_WAITING_SYNC) {
2811 ch->ch_flag &= ~(CH_WAITING_SYNC);
2812 wake_up_interruptible(&ch->ch_flag_wait);
2813 }
2814
2815 if (((seq - nd->nd_seq_out) & SEQ_MASK) >=
2816 ((nd->nd_seq_in - nd->nd_seq_out) & SEQ_MASK)) {
2817 break;
2818 }
2819
2820 for (s = nd->nd_seq_out;; s = (s + 1) & SEQ_MASK) {
2821 if (nd->nd_seq_wait[s] != 0) {
2822 nd->nd_seq_wait[s] = 0;
2823
2824 wake_up_interruptible(&nd->nd_seq_wque[s]);
2825 }
2826
2827 nd->nd_unack -= nd->nd_seq_size[s];
2828
2829 if (s == seq)
2830 break;
2831 }
2832
2833 nd->nd_seq_out = (seq + 1) & SEQ_MASK;
2834 }
2835 break;
2836
2837 /*
2838 * Handle Sequence Response.
2839 */
2840
2841 case 15:
2842 plen = 6;
2843 if (remain < plen)
2844 goto done;
2845
2846 {
2847 /* Record that we have received the Sequence
2848 * Response, but we aren't interested in the
2849 * sequence numbers. We were using RIN like it
2850 * was ROUT and that was causing problems,
2851 * fixed 7-13-2001 David Fries. See comment in
2852 * drp.h for ch_s_rin variable.
2853 int rin = get_unaligned_be16(b + 2);
2854 int tpos = get_unaligned_be16(b + 4);
2855 */
2856
2857 ch->ch_send &= ~RR_SEQUENCE;
2858 ch->ch_expect &= ~RR_SEQUENCE;
2859 }
2860 goto check_query;
2861
2862 /*
2863 * Handle Status Response.
2864 */
2865
2866 case 17:
2867 plen = 5;
2868 if (remain < plen)
2869 goto done;
2870
2871 {
2872 ch->ch_s_elast = get_unaligned_be16(b + 2);
2873 ch->ch_s_mlast = b[4];
2874
2875 ch->ch_expect &= ~RR_STATUS;
2876 ch->ch_send &= ~RR_STATUS;
2877
2878 /*
2879 * CH_PHYS_CD is cleared because something _could_ be
2880 * waiting for the initial sense of carrier... and if
2881 * carrier is high immediately, we want to be sure to
2882 * wake them as soon as possible.
2883 */
2884 ch->ch_flag &= ~CH_PHYS_CD;
2885
2886 dgrp_carrier(ch);
2887 }
2888 goto check_query;
2889
2890 /*
2891 * Handle Line Error Response.
2892 */
2893
2894 case 19:
2895 plen = 14;
2896 if (remain < plen)
2897 goto done;
2898
2899 break;
2900
2901 /*
2902 * Handle Buffer Response.
2903 */
2904
2905 case 21:
2906 plen = 6;
2907 if (remain < plen)
2908 goto done;
2909
2910 {
2911 ch->ch_s_rsize = get_unaligned_be16(b + 2);
2912 ch->ch_s_tsize = get_unaligned_be16(b + 4);
2913
2914 ch->ch_send &= ~RR_BUFFER;
2915 ch->ch_expect &= ~RR_BUFFER;
2916 }
2917 goto check_query;
2918
2919 /*
2920 * Handle Port Capability Response.
2921 */
2922
2923 case 23:
2924 plen = 32;
2925 if (remain < plen)
2926 goto done;
2927
2928 {
2929 ch->ch_send &= ~RR_CAPABILITY;
2930 ch->ch_expect &= ~RR_CAPABILITY;
2931 }
2932
2933 /*
2934 * When all queries are complete, set those parameters
2935 * derived from the query results, then transition
2936 * to the READY state.
2937 */
2938
2939check_query:
2940 if (ch->ch_state == CS_WAIT_QUERY &&
2941 (ch->ch_expect & (RR_SEQUENCE |
2942 RR_STATUS |
2943 RR_BUFFER |
2944 RR_CAPABILITY)) == 0) {
2945 ch->ch_tmax = ch->ch_s_tsize / 4;
2946
2947 if (ch->ch_edelay == DGRP_TTIME)
2948 ch->ch_ttime = DGRP_TTIME;
2949 else
2950 ch->ch_ttime = ch->ch_edelay;
2951
2952 ch->ch_rmax = ch->ch_s_rsize / 4;
2953
2954 if (ch->ch_edelay == DGRP_RTIME)
2955 ch->ch_rtime = DGRP_RTIME;
2956 else
2957 ch->ch_rtime = ch->ch_edelay;
2958
2959 ch->ch_rlow = 2 * ch->ch_s_rsize / 8;
2960 ch->ch_rhigh = 6 * ch->ch_s_rsize / 8;
2961
2962 ch->ch_state = CS_READY;
2963
2964 nd->nd_tx_work = 1;
2965 wake_up_interruptible(&ch->ch_flag_wait);
2966
2967 }
2968 break;
2969
2970 default:
2971 goto decode_error;
2972 }
2973 break;
2974
2975 /*
2976 * Handle Events.
2977 */
2978
2979 case 12:
2980 plen = 4;
2981 if (remain < plen)
2982 goto done;
2983
2984 mlast = ch->ch_s_mlast;
2985 elast = ch->ch_s_elast;
2986
2987 mstat = ch->ch_s_mlast = b[1];
2988 estat = ch->ch_s_elast = get_unaligned_be16(b + 2);
2989
2990 /*
2991 * Handle modem changes.
2992 */
2993
2994 if (((mstat ^ mlast) & DM_CD) != 0)
2995 dgrp_carrier(ch);
2996
2997
2998 /*
2999 * Handle received break.
3000 */
3001
3002 if ((estat & ~elast & EV_RXB) != 0 &&
3003 (ch->ch_tun.un_open_count != 0) &&
3004 I_BRKINT(ch->ch_tun.un_tty) &&
3005 !(I_IGNBRK(ch->ch_tun.un_tty))) {
3006
3007 tty_buffer_request_room(ch->ch_tun.un_tty, 1);
3008 tty_insert_flip_char(ch->ch_tun.un_tty, 0, TTY_BREAK);
3009 tty_flip_buffer_push(ch->ch_tun.un_tty);
3010
3011 }
3012
3013 /*
3014 * On transmit break complete, if more break traffic
3015 * is waiting then send it. Otherwise wake any threads
3016 * waiting for transmitter empty.
3017 */
3018
3019 if ((~estat & elast & EV_TXB) != 0 &&
3020 (ch->ch_expect & RR_TX_BREAK) != 0) {
3021
3022 nd->nd_tx_work = 1;
3023
3024 ch->ch_expect &= ~RR_TX_BREAK;
3025
3026 if (ch->ch_break_time != 0) {
3027 ch->ch_send |= RR_TX_BREAK;
3028 } else {
3029 ch->ch_send &= ~RR_TX_BREAK;
3030 ch->ch_flag &= ~CH_TX_BREAK;
3031 wake_up_interruptible(&ch->ch_flag_wait);
3032 }
3033 }
3034 break;
3035
3036 case 13:
3037 case 14:
3038 error = "Unrecognized command";
3039 goto prot_error;
3040
3041 /*
3042 * Decode Special Codes.
3043 */
3044
3045 case 15:
3046 switch (n1) {
3047 /*
3048 * One byte module select.
3049 */
3050
3051 case 0:
3052 case 1:
3053 case 2:
3054 case 3:
3055 case 4:
3056 case 5:
3057 case 6:
3058 case 7:
3059 plen = 1;
3060 nd->nd_rx_module = n1;
3061 break;
3062
3063 /*
3064 * Two byte module select.
3065 */
3066
3067 case 8:
3068 plen = 2;
3069 if (remain < plen)
3070 goto done;
3071
3072 nd->nd_rx_module = b[1];
3073 break;
3074
3075 /*
3076 * ID Request packet.
3077 */
3078
3079 case 11:
3080 if (remain < 4)
3081 goto done;
3082
3083 plen = get_unaligned_be16(b + 2);
3084
3085 if (plen < 12 || plen > 1000) {
3086 error = "Response Packet length error";
3087 goto prot_error;
3088 }
3089
3090 nd->nd_tx_work = 1;
3091
3092 switch (b[1]) {
3093 /*
3094 * Echo packet.
3095 */
3096
3097 case 0:
3098 nd->nd_send |= NR_ECHO;
3099 break;
3100
3101 /*
3102 * ID Response packet.
3103 */
3104
3105 case 1:
3106 nd->nd_send |= NR_IDENT;
3107 break;
3108
3109 /*
3110 * ID Response packet.
3111 */
3112
3113 case 32:
3114 nd->nd_send |= NR_PASSWORD;
3115 break;
3116
3117 }
3118 break;
3119
3120 /*
3121 * Various node-level response packets.
3122 */
3123
3124 case 12:
3125 if (remain < 4)
3126 goto done;
3127
3128 plen = get_unaligned_be16(b + 2);
3129
3130 if (plen < 4 || plen > 1000) {
3131 error = "Response Packet length error";
3132 goto prot_error;
3133 }
3134
3135 nd->nd_tx_work = 1;
3136
3137 switch (b[1]) {
3138 /*
3139 * Echo packet.
3140 */
3141
3142 case 0:
3143 nd->nd_expect &= ~NR_ECHO;
3144 break;
3145
3146 /*
3147 * Product Response Packet.
3148 */
3149
3150 case 1:
3151 {
3152 int desclen;
3153
3154 nd->nd_hw_ver = (b[8] << 8) | b[9];
3155 nd->nd_sw_ver = (b[10] << 8) | b[11];
3156 nd->nd_hw_id = b[6];
3157 desclen = ((plen - 12) > MAX_DESC_LEN) ? MAX_DESC_LEN :
3158 plen - 12;
3159 strncpy(nd->nd_ps_desc, b + 12, desclen);
3160 nd->nd_ps_desc[desclen] = 0;
3161 }
3162
3163 nd->nd_expect &= ~NR_IDENT;
3164 break;
3165
3166 /*
3167 * Capability Response Packet.
3168 */
3169
3170 case 2:
3171 {
3172 int nn = get_unaligned_be16(b + 4);
3173
3174 if (nn > CHAN_MAX)
3175 nn = CHAN_MAX;
3176
3177 dgrp_chan_count(nd, nn);
3178 }
3179
3180 nd->nd_expect &= ~NR_CAPABILITY;
3181 break;
3182
3183 /*
3184 * VPD Response Packet.
3185 */
3186
3187 case 15:
3188 /*
3189 * NOTE: case 15 is here ONLY because the EtherLite
3190 * is broken, and sends a response to 24 back as 15.
3191 * To resolve this, the EtherLite firmware is now
3192 * fixed to send back 24 correctly, but, for backwards
3193 * compatibility, we now have reserved 15 for the
3194 * bad EtherLite response to 24 as well.
3195 */
3196
3197 /* Fallthru! */
3198
3199 case 24:
3200
3201 /*
3202 * If the product doesn't support VPD,
3203 * it will send back a null IDRESP,
3204 * which is a length of 4 bytes.
3205 */
3206 if (plen > 4) {
3207 memcpy(nd->nd_vpd, b + 4, min(plen - 4, (long) VPDSIZE));
3208 nd->nd_vpd_len = min(plen - 4, (long) VPDSIZE);
3209 }
3210
3211 nd->nd_expect &= ~NR_VPD;
3212 break;
3213
3214 default:
3215 goto decode_error;
3216 }
3217
3218 if (nd->nd_expect == 0 &&
3219 nd->nd_state == NS_WAIT_QUERY) {
3220 nd->nd_state = NS_READY;
3221 }
3222 break;
3223
3224 /*
3225 * Debug packet.
3226 */
3227
3228 case 14:
3229 if (remain < 4)
3230 goto done;
3231
3232 plen = get_unaligned_be16(b + 2) + 4;
3233
3234 if (plen > 1000) {
3235 error = "Debug Packet too large";
3236 goto prot_error;
3237 }
3238
3239 if (remain < plen)
3240 goto done;
3241 break;
3242
3243 /*
3244 * Handle reset packet.
3245 */
3246
3247 case 15:
3248 if (remain < 2)
3249 goto done;
3250
3251 plen = 2 + b[1];
3252
3253 if (remain < plen)
3254 goto done;
3255
3256 nd->nd_tx_work = 1;
3257
3258 n = b[plen];
3259 b[plen] = 0;
3260
3261 b[plen] = n;
3262
3263 error = "Client Reset Acknowledge";
3264 goto prot_error;
3265
3266 default:
3267 goto decode_error;
3268 }
3269 break;
3270
3271 default:
3272 goto decode_error;
3273 }
3274
3275 b += plen;
3276 remain -= plen;
3277 }
3278
3279 /*
3280 * When the buffer is exhausted, copy any data left at the
3281 * top of the buffer back down to the bottom for the next
3282 * read request.
3283 */
3284
3285done:
3286 if (remain > 0 && b != buf)
3287 memcpy(buf, b, remain);
3288
3289 nd->nd_remain = remain;
3290 return;
3291
3292/*
3293 * Handle a decode error.
3294 */
3295
3296decode_error:
3297 error = "Protocol decode error";
3298
3299/*
3300 * Handle a general protocol error.
3301 */
3302
3303prot_error:
3304 nd->nd_remain = 0;
3305 nd->nd_state = NS_SEND_ERROR;
3306 nd->nd_error = error;
3307}
3308
3309/*
3310 * dgrp_net_write() -- write data to the network device.
3311 *
3312 * A zero byte write indicates that the connection to the RealPort
3313 * device has been broken.
3314 *
3315 * A non-zero write indicates data from the RealPort device.
3316 */
3317static ssize_t dgrp_net_write(struct file *file, const char __user *buf,
3318 size_t count, loff_t *ppos)
3319{
3320 struct nd_struct *nd;
3321 ssize_t rtn = 0;
3322 long n;
3323 long total = 0;
3324
3325 /*
3326 * Get the node pointer, and quit if it doesn't exist.
3327 */
3328 nd = (struct nd_struct *)(file->private_data);
3329 if (!nd)
3330 return -ENXIO;
3331
3332 /*
3333 * Grab the NET lock.
3334 */
3335 down(&nd->nd_net_semaphore);
3336
3337 nd->nd_write_count++;
3338
3339 /*
3340 * Handle disconnect.
3341 */
3342
3343 if (count == 0) {
3344 dgrp_net_idle(nd);
3345 /*
3346 * Set the active port count to zero.
3347 */
3348 dgrp_chan_count(nd, 0);
3349 goto unlock;
3350 }
3351
3352 /*
3353 * Loop to process entire receive packet.
3354 */
3355
3356 while (count > 0) {
3357 n = UIO_MAX - nd->nd_remain;
3358
3359 if (n > count)
3360 n = count;
3361
3362 nd->nd_rx_byte += n + nd->nd_link.lk_header_size;
3363
3364 rtn = copy_from_user(nd->nd_iobuf + nd->nd_remain,
3365 (void __user *) buf + total, n);
3366 if (rtn) {
3367 rtn = -EFAULT;
3368 goto unlock;
3369 }
3370
3371 *ppos += n;
3372
3373 total += n;
3374
3375 count -= n;
3376
3377 if (nd->nd_mon_buf)
3378 dgrp_monitor_data(nd, RPDUMP_SERVER,
3379 nd->nd_iobuf + nd->nd_remain, n);
3380
3381 nd->nd_remain += n;
3382
3383 dgrp_receive(nd);
3384 }
3385
3386 rtn = total;
3387
3388unlock:
3389 /*
3390 * Release the NET lock.
3391 */
3392 up(&nd->nd_net_semaphore);
3393
3394 return rtn;
3395}
3396
3397
3398/*
3399 * dgrp_net_select()
3400 * Determine whether a device is ready to be read or written to, and
3401 * sleep if not.
3402 */
3403static unsigned int dgrp_net_select(struct file *file,
3404 struct poll_table_struct *table)
3405{
3406 unsigned int retval = 0;
3407 struct nd_struct *nd = file->private_data;
3408
3409 poll_wait(file, &nd->nd_tx_waitq, table);
3410
3411 if (nd->nd_tx_ready)
3412 retval |= POLLIN | POLLRDNORM; /* Conditionally readable */
3413
3414 retval |= POLLOUT | POLLWRNORM; /* Always writeable */
3415
3416 return retval;
3417}
3418
3419/*
3420 * dgrp_net_ioctl
3421 *
3422 * Implement those functions which allow the network daemon to control
3423 * the network parameters in the driver. The ioctls include ones to
3424 * get and set the link speed parameters for the PortServer.
3425 */
3426static long dgrp_net_ioctl(struct file *file, unsigned int cmd,
3427 unsigned long arg)
3428{
3429 struct nd_struct *nd;
3430 int rtn = 0;
3431 long size = _IOC_SIZE(cmd);
3432 struct link_struct link;
3433
3434 nd = file->private_data;
3435
3436 if (_IOC_DIR(cmd) & _IOC_READ)
3437 rtn = access_ok(VERIFY_WRITE, (void __user *) arg, size);
3438 else if (_IOC_DIR(cmd) & _IOC_WRITE)
3439 rtn = access_ok(VERIFY_READ, (void __user *) arg, size);
3440
3441 if (!rtn)
3442 return rtn;
3443
3444 switch (cmd) {
3445 case DIGI_SETLINK:
3446 if (size != sizeof(struct link_struct))
3447 return -EINVAL;
3448
3449 if (copy_from_user((void *)(&link), (void __user *) arg, size))
3450 return -EFAULT;
3451
3452 if (link.lk_fast_rate < 9600)
3453 link.lk_fast_rate = 9600;
3454
3455 if (link.lk_slow_rate < 2400)
3456 link.lk_slow_rate = 2400;
3457
3458 if (link.lk_fast_rate > 10000000)
3459 link.lk_fast_rate = 10000000;
3460
3461 if (link.lk_slow_rate > link.lk_fast_rate)
3462 link.lk_slow_rate = link.lk_fast_rate;
3463
3464 if (link.lk_fast_delay > 2000)
3465 link.lk_fast_delay = 2000;
3466
3467 if (link.lk_slow_delay > 10000)
3468 link.lk_slow_delay = 10000;
3469
3470 if (link.lk_fast_delay < 60)
3471 link.lk_fast_delay = 60;
3472
3473 if (link.lk_slow_delay < link.lk_fast_delay)
3474 link.lk_slow_delay = link.lk_fast_delay;
3475
3476 if (link.lk_header_size < 2)
3477 link.lk_header_size = 2;
3478
3479 if (link.lk_header_size > 128)
3480 link.lk_header_size = 128;
3481
3482 link.lk_fast_rate /= 8 * 1000 / dgrp_poll_tick;
3483 link.lk_slow_rate /= 8 * 1000 / dgrp_poll_tick;
3484
3485 link.lk_fast_delay /= dgrp_poll_tick;
3486 link.lk_slow_delay /= dgrp_poll_tick;
3487
3488 nd->nd_link = link;
3489
3490 break;
3491
3492 case DIGI_GETLINK:
3493 if (size != sizeof(struct link_struct))
3494 return -EINVAL;
3495
3496 if (copy_to_user((void __user *)arg, (void *)(&nd->nd_link),
3497 size))
3498 return -EFAULT;
3499
3500 break;
3501
3502 default:
3503 return -EINVAL;
3504
3505 }
3506
3507 return 0;
3508}
3509
3510/**
3511 * dgrp_poll_handler() -- handler for poll timer
3512 *
3513 * As each timer expires, it determines (a) whether the "transmit"
3514 * waiter needs to be woken up, and (b) whether the poller needs to
3515 * be rescheduled.
3516 */
3517void dgrp_poll_handler(unsigned long arg)
3518{
3519 struct dgrp_poll_data *poll_data;
3520 struct nd_struct *nd;
3521 struct link_struct *lk;
3522 ulong time;
3523 ulong poll_time;
3524 ulong freq;
3525 ulong lock_flags;
3526
3527 poll_data = (struct dgrp_poll_data *) arg;
3528 freq = 1000 / poll_data->poll_tick;
3529 poll_data->poll_round += 17;
3530
3531 if (poll_data->poll_round >= freq)
3532 poll_data->poll_round -= freq;
3533
3534 /*
3535 * Loop to process all open nodes.
3536 *
3537 * For each node, determine the rate at which it should
3538 * be transmitting data. Then if the node should wake up
3539 * and transmit data now, enable the net receive select
3540 * to get the transmit going.
3541 */
3542
3543 list_for_each_entry(nd, &nd_struct_list, list) {
3544
3545 lk = &nd->nd_link;
3546
3547 /*
3548 * Decrement statistics. These are only for use with
3549 * KME, so don't worry that the operations are done
3550 * unlocked, and so the results are occassionally wrong.
3551 */
3552
3553 nd->nd_read_count -= (nd->nd_read_count +
3554 poll_data->poll_round) / freq;
3555 nd->nd_write_count -= (nd->nd_write_count +
3556 poll_data->poll_round) / freq;
3557 nd->nd_send_count -= (nd->nd_send_count +
3558 poll_data->poll_round) / freq;
3559 nd->nd_tx_byte -= (nd->nd_tx_byte +
3560 poll_data->poll_round) / freq;
3561 nd->nd_rx_byte -= (nd->nd_rx_byte +
3562 poll_data->poll_round) / freq;
3563
3564 /*
3565 * Wake the daemon to transmit data only when there is
3566 * enough byte credit to send data.
3567 *
3568 * The results are approximate because the operations
3569 * are performed unlocked, and we are inspecting
3570 * data asynchronously updated elsewhere. The whole
3571 * thing is just approximation anyway, so that should
3572 * be okay.
3573 */
3574
3575 if (lk->lk_slow_rate >= UIO_MAX) {
3576
3577 nd->nd_delay = 0;
3578 nd->nd_rate = UIO_MAX;
3579
3580 nd->nd_tx_deposit = nd->nd_tx_charge + 3 * UIO_MAX;
3581 nd->nd_tx_credit = 3 * UIO_MAX;
3582
3583 } else {
3584
3585 long rate;
3586 long delay;
3587 long deposit;
3588 long charge;
3589 long size;
3590 long excess;
3591
3592 long seq_in = nd->nd_seq_in;
3593 long seq_out = nd->nd_seq_out;
3594
3595 /*
3596 * If there are no outstanding packets, run at the
3597 * fastest rate.
3598 */
3599
3600 if (seq_in == seq_out) {
3601 delay = 0;
3602 rate = lk->lk_fast_rate;
3603 }
3604
3605 /*
3606 * Otherwise compute the transmit rate based on the
3607 * delay since the oldest packet.
3608 */
3609
3610 else {
3611 /*
3612 * The actual delay is computed as the
3613 * time since the oldest unacknowledged
3614 * packet was sent, minus the time it
3615 * took to send that packet to the server.
3616 */
3617
3618 delay = ((jiffies - nd->nd_seq_time[seq_out])
3619 - (nd->nd_seq_size[seq_out] /
3620 lk->lk_fast_rate));
3621
3622 /*
3623 * If the delay is less than the "fast"
3624 * delay, transmit full speed. If greater
3625 * than the "slow" delay, transmit at the
3626 * "slow" speed. In between, interpolate
3627 * between the fast and slow speeds.
3628 */
3629
3630 rate =
3631 (delay <= lk->lk_fast_delay ?
3632 lk->lk_fast_rate :
3633 delay >= lk->lk_slow_delay ?
3634 lk->lk_slow_rate :
3635 (lk->lk_slow_rate +
3636 (lk->lk_slow_delay - delay) *
3637 (lk->lk_fast_rate - lk->lk_slow_rate) /
3638 (lk->lk_slow_delay - lk->lk_fast_delay)
3639 )
3640 );
3641 }
3642
3643 nd->nd_delay = delay;
3644 nd->nd_rate = rate;
3645
3646 /*
3647 * Increase the transmit credit by depositing the
3648 * current transmit rate.
3649 */
3650
3651 deposit = nd->nd_tx_deposit;
3652 charge = nd->nd_tx_charge;
3653
3654 deposit += rate;
3655
3656 /*
3657 * If the available transmit credit becomes too large,
3658 * reduce the deposit to correct the value.
3659 *
3660 * Too large is the max of:
3661 * 6 times the header size
3662 * 3 times the current transmit rate.
3663 */
3664
3665 size = 2 * nd->nd_link.lk_header_size;
3666
3667 if (size < rate)
3668 size = rate;
3669
3670 size *= 3;
3671
3672 excess = deposit - charge - size;
3673
3674 if (excess > 0)
3675 deposit -= excess;
3676
3677 nd->nd_tx_deposit = deposit;
3678 nd->nd_tx_credit = deposit - charge;
3679
3680 /*
3681 * Wake the transmit task only if the transmit credit
3682 * is at least 3 times the transmit header size.
3683 */
3684
3685 size = 3 * lk->lk_header_size;
3686
3687 if (nd->nd_tx_credit < size)
3688 continue;
3689 }
3690
3691
3692 /*
3693 * Enable the READ select to wake the daemon if there
3694 * is useful work for the drp_read routine to perform.
3695 */
3696
3697 if (waitqueue_active(&nd->nd_tx_waitq) &&
3698 (nd->nd_tx_work != 0 ||
3699 (ulong)(jiffies - nd->nd_tx_time) >= IDLE_MAX)) {
3700 nd->nd_tx_ready = 1;
3701
3702 wake_up_interruptible(&nd->nd_tx_waitq);
3703
3704 /* not needed */
3705 /* nd->nd_flag &= ~ND_SELECT; */
3706 }
3707 }
3708
3709
3710 /*
3711 * Schedule ourself back at the nominal wakeup interval.
3712 */
3713 spin_lock_irqsave(&poll_data->poll_lock, lock_flags);
3714
3715 poll_data->node_active_count--;
3716 if (poll_data->node_active_count > 0) {
3717 poll_data->node_active_count++;
3718 poll_time = poll_data->timer.expires +
3719 poll_data->poll_tick * HZ / 1000;
3720
3721 time = poll_time - jiffies;
3722
3723 if (time >= 2 * poll_data->poll_tick)
3724 poll_time = jiffies + dgrp_poll_tick * HZ / 1000;
3725
3726 poll_data->timer.expires = poll_time;
3727 add_timer(&poll_data->timer);
3728 }
3729
3730 spin_unlock_irqrestore(&poll_data->poll_lock, lock_flags);
3731}
diff --git a/drivers/staging/dgrp/dgrp_ports_ops.c b/drivers/staging/dgrp/dgrp_ports_ops.c
new file mode 100644
index 00000000000..cd1fc208862
--- /dev/null
+++ b/drivers/staging/dgrp/dgrp_ports_ops.c
@@ -0,0 +1,170 @@
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 */
48static int dgrp_ports_open(struct inode *, struct file *);
49
50static 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
58static struct inode_operations ports_inode_ops = {
59 .permission = dgrp_inode_permission
60};
61
62
63void dgrp_register_ports_hook(struct proc_dir_entry *de)
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
72static 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
80static 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
92static void dgrp_ports_seq_stop(struct seq_file *seq, void *v)
93{
94}
95
96static 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
143static 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
150/**
151 * dgrp_ports_open -- open the /proc/dgrp/ports/... device
152 * @inode: struct inode *
153 * @file: struct file *
154 *
155 * Open function to open the /proc/dgrp/ports device for a PortServer.
156 * This is the open function for struct file_operations
157 */
158static 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}
diff --git a/drivers/staging/dgrp/dgrp_specproc.c b/drivers/staging/dgrp/dgrp_specproc.c
new file mode 100644
index 00000000000..259d23aa6c2
--- /dev/null
+++ b/drivers/staging/dgrp/dgrp_specproc.c
@@ -0,0 +1,821 @@
1/*
2 *
3 * Copyright 1999 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 */
17
18/*
19 *
20 * Filename:
21 *
22 * dgrp_specproc.c
23 *
24 * Description:
25 *
26 * Handle the "config" proc entry for the linux realport device driver
27 * and provide slots for the "net" and "mon" devices
28 *
29 * Author:
30 *
31 * James A. Puzzo
32 *
33 */
34
35#include <linux/module.h>
36#include <linux/tty.h>
37#include <linux/sched.h>
38#include <linux/cred.h>
39#include <linux/proc_fs.h>
40#include <linux/ctype.h>
41#include <linux/seq_file.h>
42
43#include "dgrp_common.h"
44
45static struct dgrp_proc_entry dgrp_table[];
46static struct proc_dir_entry *dgrp_proc_dir_entry;
47
48static int dgrp_add_id(long id);
49static int dgrp_remove_nd(struct nd_struct *nd);
50static void unregister_dgrp_device(struct proc_dir_entry *de);
51static void register_dgrp_device(struct nd_struct *node,
52 struct proc_dir_entry *root,
53 void (*register_hook)(struct proc_dir_entry *de));
54
55/* File operation declarations */
56static int dgrp_gen_proc_open(struct inode *, struct file *);
57static int dgrp_gen_proc_close(struct inode *, struct file *);
58static int parse_write_config(char *);
59
60
61static const struct file_operations dgrp_proc_file_ops = {
62 .owner = THIS_MODULE,
63 .open = dgrp_gen_proc_open,
64 .release = dgrp_gen_proc_close,
65};
66
67static struct inode_operations proc_inode_ops = {
68 .permission = dgrp_inode_permission
69};
70
71
72static void register_proc_table(struct dgrp_proc_entry *,
73 struct proc_dir_entry *);
74static void unregister_proc_table(struct dgrp_proc_entry *,
75 struct proc_dir_entry *);
76
77static struct dgrp_proc_entry dgrp_net_table[];
78static struct dgrp_proc_entry dgrp_mon_table[];
79static struct dgrp_proc_entry dgrp_ports_table[];
80static struct dgrp_proc_entry dgrp_dpa_table[];
81
82static ssize_t config_proc_write(struct file *file, const char __user *buffer,
83 size_t count, loff_t *pos);
84
85static int nodeinfo_proc_open(struct inode *inode, struct file *file);
86static int info_proc_open(struct inode *inode, struct file *file);
87static int config_proc_open(struct inode *inode, struct file *file);
88
89static struct file_operations config_proc_file_ops = {
90 .owner = THIS_MODULE,
91 .open = config_proc_open,
92 .read = seq_read,
93 .llseek = seq_lseek,
94 .release = seq_release,
95 .write = config_proc_write
96};
97
98static struct file_operations info_proc_file_ops = {
99 .owner = THIS_MODULE,
100 .open = info_proc_open,
101 .read = seq_read,
102 .llseek = seq_lseek,
103 .release = seq_release,
104};
105
106static struct file_operations nodeinfo_proc_file_ops = {
107 .owner = THIS_MODULE,
108 .open = nodeinfo_proc_open,
109 .read = seq_read,
110 .llseek = seq_lseek,
111 .release = seq_release,
112};
113
114static struct dgrp_proc_entry dgrp_table[] = {
115 {
116 .id = DGRP_CONFIG,
117 .name = "config",
118 .mode = 0644,
119 .proc_file_ops = &config_proc_file_ops,
120 },
121 {
122 .id = DGRP_INFO,
123 .name = "info",
124 .mode = 0644,
125 .proc_file_ops = &info_proc_file_ops,
126 },
127 {
128 .id = DGRP_NODEINFO,
129 .name = "nodeinfo",
130 .mode = 0644,
131 .proc_file_ops = &nodeinfo_proc_file_ops,
132 },
133 {
134 .id = DGRP_NETDIR,
135 .name = "net",
136 .mode = 0500,
137 .child = dgrp_net_table
138 },
139 {
140 .id = DGRP_MONDIR,
141 .name = "mon",
142 .mode = 0500,
143 .child = dgrp_mon_table
144 },
145 {
146 .id = DGRP_PORTSDIR,
147 .name = "ports",
148 .mode = 0500,
149 .child = dgrp_ports_table
150 },
151 {
152 .id = DGRP_DPADIR,
153 .name = "dpa",
154 .mode = 0500,
155 .child = dgrp_dpa_table
156 }
157};
158
159static struct proc_dir_entry *net_entry_pointer;
160static struct proc_dir_entry *mon_entry_pointer;
161static struct proc_dir_entry *dpa_entry_pointer;
162static struct proc_dir_entry *ports_entry_pointer;
163
164static struct dgrp_proc_entry dgrp_net_table[] = {
165 {0}
166};
167
168static struct dgrp_proc_entry dgrp_mon_table[] = {
169 {0}
170};
171
172static struct dgrp_proc_entry dgrp_ports_table[] = {
173 {0}
174};
175
176static struct dgrp_proc_entry dgrp_dpa_table[] = {
177 {0}
178};
179
180void dgrp_unregister_proc(void)
181{
182 unregister_proc_table(dgrp_table, dgrp_proc_dir_entry);
183 net_entry_pointer = NULL;
184 mon_entry_pointer = NULL;
185 dpa_entry_pointer = NULL;
186 ports_entry_pointer = NULL;
187
188 if (dgrp_proc_dir_entry) {
189 remove_proc_entry(dgrp_proc_dir_entry->name,
190 dgrp_proc_dir_entry->parent);
191 dgrp_proc_dir_entry = NULL;
192 }
193
194}
195
196void dgrp_register_proc(void)
197{
198 /*
199 * Register /proc/dgrp
200 */
201 dgrp_proc_dir_entry = proc_create("dgrp", S_IFDIR, NULL,
202 &dgrp_proc_file_ops);
203 register_proc_table(dgrp_table, dgrp_proc_dir_entry);
204}
205
206/*
207 * /proc/sys support
208 */
209static int dgrp_proc_match(int len, const char *name, struct proc_dir_entry *de)
210{
211 if (!de || !de->low_ino)
212 return 0;
213 if (de->namelen != len)
214 return 0;
215 return !memcmp(name, de->name, len);
216}
217
218
219/*
220 * Scan the entries in table and add them all to /proc at the position
221 * referred to by "root"
222 */
223static void register_proc_table(struct dgrp_proc_entry *table,
224 struct proc_dir_entry *root)
225{
226 struct proc_dir_entry *de;
227 int len;
228 mode_t mode;
229
230 for (; table->id; table++) {
231 /* Can't do anything without a proc name. */
232 if (!table->name)
233 continue;
234
235 /* Maybe we can't do anything with it... */
236 if (!table->proc_file_ops &&
237 !table->child) {
238 pr_warn("dgrp: Can't register %s\n",
239 table->name);
240 continue;
241 }
242
243 len = strlen(table->name);
244 mode = table->mode;
245
246 de = NULL;
247 if (!table->child)
248 mode |= S_IFREG;
249 else {
250 mode |= S_IFDIR;
251 for (de = root->subdir; de; de = de->next) {
252 if (dgrp_proc_match(len, table->name, de))
253 break;
254 }
255 /* If the subdir exists already, de is non-NULL */
256 }
257
258 if (!de) {
259 de = create_proc_entry(table->name, mode, root);
260 if (!de)
261 continue;
262 de->data = (void *) table;
263 if (!table->child) {
264 de->proc_iops = &proc_inode_ops;
265 if (table->proc_file_ops)
266 de->proc_fops = table->proc_file_ops;
267 else
268 de->proc_fops = &dgrp_proc_file_ops;
269 }
270 }
271 table->de = de;
272 if (de->mode & S_IFDIR)
273 register_proc_table(table->child, de);
274
275 if (table->id == DGRP_NETDIR)
276 net_entry_pointer = de;
277
278 if (table->id == DGRP_MONDIR)
279 mon_entry_pointer = de;
280
281 if (table->id == DGRP_DPADIR)
282 dpa_entry_pointer = de;
283
284 if (table->id == DGRP_PORTSDIR)
285 ports_entry_pointer = de;
286 }
287}
288
289/*
290 * Unregister a /proc sysctl table and any subdirectories.
291 */
292static void unregister_proc_table(struct dgrp_proc_entry *table,
293 struct proc_dir_entry *root)
294{
295 struct proc_dir_entry *de;
296 struct nd_struct *tmp;
297
298 list_for_each_entry(tmp, &nd_struct_list, list) {
299 if ((table == dgrp_net_table) && (tmp->nd_net_de)) {
300 unregister_dgrp_device(tmp->nd_net_de);
301 dgrp_remove_node_class_sysfs_files(tmp);
302 }
303
304 if ((table == dgrp_mon_table) && (tmp->nd_mon_de))
305 unregister_dgrp_device(tmp->nd_mon_de);
306
307 if ((table == dgrp_dpa_table) && (tmp->nd_dpa_de))
308 unregister_dgrp_device(tmp->nd_dpa_de);
309
310 if ((table == dgrp_ports_table) && (tmp->nd_ports_de))
311 unregister_dgrp_device(tmp->nd_ports_de);
312 }
313
314 for (; table->id; table++) {
315 de = table->de;
316
317 if (!de)
318 continue;
319 if (de->mode & S_IFDIR) {
320 if (!table->child) {
321 pr_alert("dgrp: malformed sysctl tree on free\n");
322 continue;
323 }
324 unregister_proc_table(table->child, de);
325
326 /* Don't unregister directories which still have entries */
327 if (de->subdir)
328 continue;
329 }
330
331 /* Don't unregister proc entries that are still being used.. */
332 if ((atomic_read(&de->count)) != 1) {
333 pr_alert("proc entry %s in use, not removing\n",
334 de->name);
335 continue;
336 }
337
338 remove_proc_entry(de->name, de->parent);
339 table->de = NULL;
340 }
341}
342
343static int dgrp_gen_proc_open(struct inode *inode, struct file *file)
344{
345 struct proc_dir_entry *de;
346 struct dgrp_proc_entry *entry;
347 int ret = 0;
348
349 de = (struct proc_dir_entry *) PDE(file->f_dentry->d_inode);
350 if (!de || !de->data) {
351 ret = -ENXIO;
352 goto done;
353 }
354
355 entry = (struct dgrp_proc_entry *) de->data;
356 if (!entry) {
357 ret = -ENXIO;
358 goto done;
359 }
360
361 down(&entry->excl_sem);
362
363 if (entry->excl_cnt)
364 ret = -EBUSY;
365 else
366 entry->excl_cnt++;
367
368 up(&entry->excl_sem);
369
370done:
371 return ret;
372}
373
374static int dgrp_gen_proc_close(struct inode *inode, struct file *file)
375{
376 struct proc_dir_entry *de;
377 struct dgrp_proc_entry *entry;
378
379 de = (struct proc_dir_entry *) PDE(file->f_dentry->d_inode);
380 if (!de || !de->data)
381 goto done;
382
383 entry = (struct dgrp_proc_entry *) de->data;
384 if (!entry)
385 goto done;
386
387 down(&entry->excl_sem);
388
389 if (entry->excl_cnt)
390 entry->excl_cnt = 0;
391
392 up(&entry->excl_sem);
393
394done:
395 return 0;
396}
397
398static void *config_proc_start(struct seq_file *m, loff_t *pos)
399{
400 return seq_list_start_head(&nd_struct_list, *pos);
401}
402
403static void *config_proc_next(struct seq_file *p, void *v, loff_t *pos)
404{
405 return seq_list_next(v, &nd_struct_list, pos);
406}
407
408static void config_proc_stop(struct seq_file *m, void *v)
409{
410}
411
412static int config_proc_show(struct seq_file *m, void *v)
413{
414 struct nd_struct *nd;
415 char tmp_id[4];
416
417 if (v == &nd_struct_list) {
418 seq_puts(m, "#-----------------------------------------------------------------------------\n");
419 seq_puts(m, "# Avail\n");
420 seq_puts(m, "# ID Major State Ports\n");
421 return 0;
422 }
423
424 nd = list_entry(v, struct nd_struct, list);
425
426 ID_TO_CHAR(nd->nd_ID, tmp_id);
427
428 seq_printf(m, " %-2.2s %-5ld %-10.10s %-5d\n",
429 tmp_id,
430 nd->nd_major,
431 ND_STATE_STR(nd->nd_state),
432 nd->nd_chan_count);
433
434 return 0;
435}
436
437static const struct seq_operations proc_config_ops = {
438 .start = config_proc_start,
439 .next = config_proc_next,
440 .stop = config_proc_stop,
441 .show = config_proc_show
442};
443
444static int config_proc_open(struct inode *inode, struct file *file)
445{
446 return seq_open(file, &proc_config_ops);
447}
448
449
450/*
451 * When writing configuration information, each "record" (i.e. each
452 * write) is treated as an independent request. See the "parse"
453 * description for more details.
454 */
455static ssize_t config_proc_write(struct file *file, const char __user *buffer,
456 size_t count, loff_t *pos)
457{
458 ssize_t retval;
459 char *inbuf, *sp;
460 char *line, *ldelim;
461
462 if (count > 32768)
463 return -EINVAL;
464
465 inbuf = sp = vzalloc(count + 1);
466 if (!inbuf)
467 return -ENOMEM;
468
469 if (copy_from_user(inbuf, buffer, count)) {
470 retval = -EFAULT;
471 goto done;
472 }
473
474 inbuf[count] = 0;
475
476 ldelim = "\n";
477
478 line = strpbrk(sp, ldelim);
479 while (line) {
480 *line = 0;
481 retval = parse_write_config(sp);
482 if (retval)
483 goto done;
484
485 sp = line + 1;
486 line = strpbrk(sp, ldelim);
487 }
488
489 retval = count;
490done:
491 vfree(inbuf);
492 return retval;
493}
494
495/*
496 * ------------------------------------------------------------------------
497 *
498 * The following are the functions to parse input
499 *
500 * ------------------------------------------------------------------------
501 */
502static inline char *skip_past_ws(const char *str)
503{
504 while ((*str) && !isspace(*str))
505 ++str;
506
507 return skip_spaces(str);
508}
509
510static int parse_id(char **c, char *cID)
511{
512 int tmp = **c;
513
514 if (isalnum(tmp) || (tmp == '_'))
515 cID[0] = tmp;
516 else
517 return -EINVAL;
518
519 (*c)++; tmp = **c;
520
521 if (isalnum(tmp) || (tmp == '_')) {
522 cID[1] = tmp;
523 (*c)++;
524 } else
525 cID[1] = 0;
526
527 return 0;
528}
529
530static int parse_add_config(char *buf)
531{
532 char *c = buf;
533 int retval;
534 char cID[2];
535 long ID;
536
537 c = skip_past_ws(c);
538
539 retval = parse_id(&c, cID);
540 if (retval < 0)
541 return retval;
542
543 ID = CHAR_TO_ID(cID);
544
545 c = skip_past_ws(c);
546
547 return dgrp_add_id(ID);
548}
549
550static int parse_del_config(char *buf)
551{
552 char *c = buf;
553 int retval;
554 struct nd_struct *nd;
555 char cID[2];
556 long ID;
557 long major;
558
559 c = skip_past_ws(c);
560
561 retval = parse_id(&c, cID);
562 if (retval < 0)
563 return retval;
564
565 ID = CHAR_TO_ID(cID);
566
567 c = skip_past_ws(c);
568
569 retval = kstrtol(c, 10, &major);
570 if (retval)
571 return retval;
572
573 nd = nd_struct_get(major);
574 if (!nd)
575 return -EINVAL;
576
577 if ((nd->nd_major != major) || (nd->nd_ID != ID))
578 return -EINVAL;
579
580 return dgrp_remove_nd(nd);
581}
582
583static int parse_chg_config(char *buf)
584{
585 return -EINVAL;
586}
587
588/*
589 * The passed character buffer represents a single configuration request.
590 * If the first character is a "+", it is parsed as a request to add a
591 * PortServer
592 * If the first character is a "-", it is parsed as a request to delete a
593 * PortServer
594 * If the first character is a "*", it is parsed as a request to change a
595 * PortServer
596 * Any other character (including whitespace) causes the record to be
597 * ignored.
598 */
599static int parse_write_config(char *buf)
600{
601 int retval;
602
603 switch (buf[0]) {
604 case '+':
605 retval = parse_add_config(buf);
606 break;
607 case '-':
608 retval = parse_del_config(buf);
609 break;
610 case '*':
611 retval = parse_chg_config(buf);
612 break;
613 default:
614 retval = -EINVAL;
615 }
616
617 return retval;
618}
619
620static int info_proc_show(struct seq_file *m, void *v)
621{
622 seq_printf(m, "version: %s\n", DIGI_VERSION);
623 seq_puts(m, "register_with_sysfs: 1\n");
624 seq_printf(m, "rawreadok: 0x%08x\t(%d)\n",
625 dgrp_rawreadok, dgrp_rawreadok);
626 seq_printf(m, "pollrate: 0x%08x\t(%d)\n",
627 dgrp_poll_tick, dgrp_poll_tick);
628
629 return 0;
630}
631
632static int info_proc_open(struct inode *inode, struct file *file)
633{
634 return single_open(file, info_proc_show, NULL);
635}
636
637
638static void *nodeinfo_start(struct seq_file *m, loff_t *pos)
639{
640 return seq_list_start_head(&nd_struct_list, *pos);
641}
642
643static void *nodeinfo_next(struct seq_file *p, void *v, loff_t *pos)
644{
645 return seq_list_next(v, &nd_struct_list, pos);
646}
647
648static void nodeinfo_stop(struct seq_file *m, void *v)
649{
650}
651
652static int nodeinfo_show(struct seq_file *m, void *v)
653{
654 struct nd_struct *nd;
655 char hwver[8];
656 char swver[8];
657 char tmp_id[4];
658
659 if (v == &nd_struct_list) {
660 seq_puts(m, "#-----------------------------------------------------------------------------\n");
661 seq_puts(m, "# HW HW SW\n");
662 seq_puts(m, "# ID State Version ID Version Description\n");
663 return 0;
664 }
665
666 nd = list_entry(v, struct nd_struct, list);
667
668 ID_TO_CHAR(nd->nd_ID, tmp_id);
669
670 if (nd->nd_state == NS_READY) {
671 sprintf(hwver, "%d.%d", (nd->nd_hw_ver >> 8) & 0xff,
672 nd->nd_hw_ver & 0xff);
673 sprintf(swver, "%d.%d", (nd->nd_sw_ver >> 8) & 0xff,
674 nd->nd_sw_ver & 0xff);
675 seq_printf(m, " %-2.2s %-10.10s %-7.7s %-3d %-7.7s %-35.35s\n",
676 tmp_id,
677 ND_STATE_STR(nd->nd_state),
678 hwver,
679 nd->nd_hw_id,
680 swver,
681 nd->nd_ps_desc);
682
683 } else {
684 seq_printf(m, " %-2.2s %-10.10s\n",
685 tmp_id,
686 ND_STATE_STR(nd->nd_state));
687 }
688
689 return 0;
690}
691
692
693static const struct seq_operations nodeinfo_ops = {
694 .start = nodeinfo_start,
695 .next = nodeinfo_next,
696 .stop = nodeinfo_stop,
697 .show = nodeinfo_show
698};
699
700static int nodeinfo_proc_open(struct inode *inode, struct file *file)
701{
702 return seq_open(file, &nodeinfo_ops);
703}
704
705/**
706 * dgrp_add_id() -- creates new nd struct and adds it to list
707 * @id: id of device to add
708 */
709static int dgrp_add_id(long id)
710{
711 struct nd_struct *nd;
712 int ret;
713 int i;
714
715 nd = kzalloc(sizeof(struct nd_struct), GFP_KERNEL);
716 if (!nd)
717 return -ENOMEM;
718
719 nd->nd_major = 0;
720 nd->nd_ID = id;
721
722 spin_lock_init(&nd->nd_lock);
723
724 init_waitqueue_head(&nd->nd_tx_waitq);
725 init_waitqueue_head(&nd->nd_mon_wqueue);
726 init_waitqueue_head(&nd->nd_dpa_wqueue);
727 for (i = 0; i < SEQ_MAX; i++)
728 init_waitqueue_head(&nd->nd_seq_wque[i]);
729
730 /* setup the structures to get the major number */
731 ret = dgrp_tty_init(nd);
732 if (ret)
733 goto error_out;
734
735 nd->nd_major = nd->nd_serial_ttdriver->major;
736
737 ret = nd_struct_add(nd);
738 if (ret)
739 goto error_out;
740
741 register_dgrp_device(nd, net_entry_pointer, dgrp_register_net_hook);
742 register_dgrp_device(nd, mon_entry_pointer, dgrp_register_mon_hook);
743 register_dgrp_device(nd, dpa_entry_pointer, dgrp_register_dpa_hook);
744 register_dgrp_device(nd, ports_entry_pointer,
745 dgrp_register_ports_hook);
746
747 return 0;
748
749error_out:
750 kfree(nd);
751 return ret;
752
753}
754
755static int dgrp_remove_nd(struct nd_struct *nd)
756{
757 int ret;
758
759 /* Check to see if the selected structure is in use */
760 if (nd->nd_tty_ref_cnt)
761 return -EBUSY;
762
763 if (nd->nd_net_de) {
764 unregister_dgrp_device(nd->nd_net_de);
765 dgrp_remove_node_class_sysfs_files(nd);
766 }
767
768 if (nd->nd_mon_de)
769 unregister_dgrp_device(nd->nd_mon_de);
770
771 if (nd->nd_ports_de)
772 unregister_dgrp_device(nd->nd_ports_de);
773
774 if (nd->nd_dpa_de)
775 unregister_dgrp_device(nd->nd_dpa_de);
776
777 dgrp_tty_uninit(nd);
778
779 ret = nd_struct_del(nd);
780 if (ret)
781 return ret;
782
783 kfree(nd);
784 return 0;
785}
786
787static void register_dgrp_device(struct nd_struct *node,
788 struct proc_dir_entry *root,
789 void (*register_hook)(struct proc_dir_entry *de))
790{
791 char buf[3];
792 struct proc_dir_entry *de;
793
794 ID_TO_CHAR(node->nd_ID, buf);
795
796 de = create_proc_entry(buf, 0600 | S_IFREG, root);
797 if (!de)
798 return;
799
800 de->data = (void *) node;
801
802 if (register_hook)
803 register_hook(de);
804
805}
806
807static void unregister_dgrp_device(struct proc_dir_entry *de)
808{
809 if (!de)
810 return;
811
812 /* Don't unregister proc entries that are still being used.. */
813 if ((atomic_read(&de->count)) != 1) {
814 pr_alert("%s - proc entry %s in use. Not removing.\n",
815 __func__, de->name);
816 return;
817 }
818
819 remove_proc_entry(de->name, de->parent);
820 de = NULL;
821}
diff --git a/drivers/staging/dgrp/dgrp_sysfs.c b/drivers/staging/dgrp/dgrp_sysfs.c
new file mode 100644
index 00000000000..e5a3c88d016
--- /dev/null
+++ b/drivers/staging/dgrp/dgrp_sysfs.c
@@ -0,0 +1,555 @@
1/*
2 * Copyright 2004 Digi International (www.digi.com)
3 * Scott H Kilau <Scott_Kilau at digi dot com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
12 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
13 * PURPOSE. See the GNU General Public License for more details.
14 *
15 */
16
17#include "dgrp_common.h"
18
19#include <linux/kernel.h>
20#include <linux/version.h>
21#include <linux/module.h>
22#include <linux/ctype.h>
23#include <linux/string.h>
24#include <linux/serial_reg.h>
25#include <linux/pci.h>
26#include <linux/kdev_t.h>
27
28
29#define PORTSERVER_DIVIDEND 1843200
30#define SERIAL_TYPE_NORMAL 1
31#define SERIAL_TYPE_CALLOUT 2
32#define SERIAL_TYPE_XPRINT 3
33
34
35static struct class *dgrp_class;
36static struct device *dgrp_class_nodes_dev;
37static struct device *dgrp_class_global_settings_dev;
38
39
40static ssize_t dgrp_class_version_show(struct class *class,
41 struct class_attribute *attr, char *buf)
42{
43 return snprintf(buf, PAGE_SIZE, "%s\n", DIGI_VERSION);
44}
45static CLASS_ATTR(driver_version, 0400, dgrp_class_version_show, NULL);
46
47
48static ssize_t dgrp_class_register_with_sysfs_show(struct device *c,
49 struct device_attribute *attr,
50 char *buf)
51{
52 return snprintf(buf, PAGE_SIZE, "1\n");
53}
54static DEVICE_ATTR(register_with_sysfs, 0400,
55 dgrp_class_register_with_sysfs_show, NULL);
56
57
58static ssize_t dgrp_class_rawreadok_show(struct device *c,
59 struct device_attribute *attr,
60 char *buf)
61{
62 return snprintf(buf, PAGE_SIZE, "%d\n", dgrp_rawreadok);
63}
64static ssize_t dgrp_class_rawreadok_store(struct device *c,
65 struct device_attribute *attr,
66 const char *buf, size_t count)
67{
68 sscanf(buf, "0x%x\n", &dgrp_rawreadok);
69 return count;
70}
71static DEVICE_ATTR(rawreadok, 0600, dgrp_class_rawreadok_show,
72 dgrp_class_rawreadok_store);
73
74
75static ssize_t dgrp_class_pollrate_show(struct device *c,
76 struct device_attribute *attr,
77 char *buf)
78{
79 return snprintf(buf, PAGE_SIZE, "%d\n", dgrp_poll_tick);
80}
81
82static ssize_t dgrp_class_pollrate_store(struct device *c,
83 struct device_attribute *attr,
84 const char *buf, size_t count)
85{
86 sscanf(buf, "0x%x\n", &dgrp_poll_tick);
87 return count;
88}
89static DEVICE_ATTR(pollrate, 0600, dgrp_class_pollrate_show,
90 dgrp_class_pollrate_store);
91
92static struct attribute *dgrp_sysfs_global_settings_entries[] = {
93 &dev_attr_pollrate.attr,
94 &dev_attr_rawreadok.attr,
95 &dev_attr_register_with_sysfs.attr,
96 NULL
97};
98
99
100static struct attribute_group dgrp_global_settings_attribute_group = {
101 .name = NULL,
102 .attrs = dgrp_sysfs_global_settings_entries,
103};
104
105
106
107void dgrp_create_class_sysfs_files(void)
108{
109 int ret = 0;
110 int max_majors = 1U << (32 - MINORBITS);
111
112 dgrp_class = class_create(THIS_MODULE, "digi_realport");
113 ret = class_create_file(dgrp_class, &class_attr_driver_version);
114
115 dgrp_class_global_settings_dev = device_create(dgrp_class, NULL,
116 MKDEV(0, max_majors + 1), NULL, "driver_settings");
117
118 ret = sysfs_create_group(&dgrp_class_global_settings_dev->kobj,
119 &dgrp_global_settings_attribute_group);
120 if (ret) {
121 pr_alert("%s: failed to create sysfs global settings device attributes.\n",
122 __func__);
123 sysfs_remove_group(&dgrp_class_global_settings_dev->kobj,
124 &dgrp_global_settings_attribute_group);
125 return;
126 }
127
128 dgrp_class_nodes_dev = device_create(dgrp_class, NULL,
129 MKDEV(0, max_majors + 2), NULL, "nodes");
130
131}
132
133
134void dgrp_remove_class_sysfs_files(void)
135{
136 struct nd_struct *nd;
137 int max_majors = 1U << (32 - MINORBITS);
138
139 list_for_each_entry(nd, &nd_struct_list, list)
140 dgrp_remove_node_class_sysfs_files(nd);
141
142 sysfs_remove_group(&dgrp_class_global_settings_dev->kobj,
143 &dgrp_global_settings_attribute_group);
144
145 class_remove_file(dgrp_class, &class_attr_driver_version);
146
147 device_destroy(dgrp_class, MKDEV(0, max_majors + 1));
148 device_destroy(dgrp_class, MKDEV(0, max_majors + 2));
149 class_destroy(dgrp_class);
150}
151
152static ssize_t dgrp_node_state_show(struct device *c,
153 struct device_attribute *attr, char *buf)
154{
155 struct nd_struct *nd;
156
157 if (!c)
158 return 0;
159 nd = (struct nd_struct *) dev_get_drvdata(c);
160 if (!nd)
161 return 0;
162
163 return snprintf(buf, PAGE_SIZE, "%s\n", ND_STATE_STR(nd->nd_state));
164}
165
166static DEVICE_ATTR(state, 0600, dgrp_node_state_show, NULL);
167
168static ssize_t dgrp_node_description_show(struct device *c,
169 struct device_attribute *attr,
170 char *buf)
171{
172 struct nd_struct *nd;
173
174 if (!c)
175 return 0;
176 nd = (struct nd_struct *) dev_get_drvdata(c);
177 if (!nd)
178 return 0;
179
180 if (nd->nd_state == NS_READY && nd->nd_ps_desc)
181 return snprintf(buf, PAGE_SIZE, "%s\n", nd->nd_ps_desc);
182 return 0;
183}
184static DEVICE_ATTR(description_info, 0600, dgrp_node_description_show, NULL);
185
186static ssize_t dgrp_node_hw_version_show(struct device *c,
187 struct device_attribute *attr,
188 char *buf)
189{
190 struct nd_struct *nd;
191
192 if (!c)
193 return 0;
194 nd = (struct nd_struct *) dev_get_drvdata(c);
195 if (!nd)
196 return 0;
197
198 if (nd->nd_state == NS_READY)
199 return snprintf(buf, PAGE_SIZE, "%d.%d\n",
200 (nd->nd_hw_ver >> 8) & 0xff,
201 nd->nd_hw_ver & 0xff);
202
203 return 0;
204}
205static DEVICE_ATTR(hw_version_info, 0600, dgrp_node_hw_version_show, NULL);
206
207static ssize_t dgrp_node_hw_id_show(struct device *c,
208 struct device_attribute *attr, char *buf)
209{
210 struct nd_struct *nd;
211
212 if (!c)
213 return 0;
214 nd = (struct nd_struct *) dev_get_drvdata(c);
215 if (!nd)
216 return 0;
217
218
219 if (nd->nd_state == NS_READY)
220 return snprintf(buf, PAGE_SIZE, "%d\n", nd->nd_hw_id);
221 return 0;
222}
223static DEVICE_ATTR(hw_id_info, 0600, dgrp_node_hw_id_show, NULL);
224
225static ssize_t dgrp_node_sw_version_show(struct device *c,
226 struct device_attribute *attr,
227 char *buf)
228{
229 struct nd_struct *nd;
230
231 if (!c)
232 return 0;
233
234 nd = (struct nd_struct *) dev_get_drvdata(c);
235 if (!nd)
236 return 0;
237
238 if (nd->nd_state == NS_READY)
239 return snprintf(buf, PAGE_SIZE, "%d.%d\n",
240 (nd->nd_sw_ver >> 8) & 0xff,
241 nd->nd_sw_ver & 0xff);
242
243 return 0;
244}
245static DEVICE_ATTR(sw_version_info, 0600, dgrp_node_sw_version_show, NULL);
246
247
248static struct attribute *dgrp_sysfs_node_entries[] = {
249 &dev_attr_state.attr,
250 &dev_attr_description_info.attr,
251 &dev_attr_hw_version_info.attr,
252 &dev_attr_hw_id_info.attr,
253 &dev_attr_sw_version_info.attr,
254 NULL
255};
256
257
258static struct attribute_group dgrp_node_attribute_group = {
259 .name = NULL,
260 .attrs = dgrp_sysfs_node_entries,
261};
262
263
264void dgrp_create_node_class_sysfs_files(struct nd_struct *nd)
265{
266 int ret;
267 char name[10];
268
269 if (nd->nd_ID)
270 ID_TO_CHAR(nd->nd_ID, name);
271 else
272 sprintf(name, "node%ld", nd->nd_major);
273
274 nd->nd_class_dev = device_create(dgrp_class, dgrp_class_nodes_dev,
275 MKDEV(0, nd->nd_major), NULL, name);
276
277 ret = sysfs_create_group(&nd->nd_class_dev->kobj,
278 &dgrp_node_attribute_group);
279
280 if (ret) {
281 pr_alert("%s: failed to create sysfs node device attributes.\n",
282 __func__);
283 sysfs_remove_group(&nd->nd_class_dev->kobj,
284 &dgrp_node_attribute_group);
285 return;
286 }
287
288 dev_set_drvdata(nd->nd_class_dev, nd);
289
290}
291
292
293void dgrp_remove_node_class_sysfs_files(struct nd_struct *nd)
294{
295 if (nd->nd_class_dev) {
296 sysfs_remove_group(&nd->nd_class_dev->kobj,
297 &dgrp_node_attribute_group);
298
299 device_destroy(dgrp_class, MKDEV(0, nd->nd_major));
300 nd->nd_class_dev = NULL;
301 }
302}
303
304
305
306static ssize_t dgrp_tty_state_show(struct device *d,
307 struct device_attribute *attr, char *buf)
308{
309 struct un_struct *un;
310
311 if (!d)
312 return 0;
313 un = (struct un_struct *) dev_get_drvdata(d);
314 if (!un)
315 return 0;
316
317 return snprintf(buf, PAGE_SIZE, "%s\n",
318 un->un_open_count ? "Open" : "Closed");
319}
320static DEVICE_ATTR(state_info, 0600, dgrp_tty_state_show, NULL);
321
322static ssize_t dgrp_tty_baud_show(struct device *d,
323 struct device_attribute *attr, char *buf)
324{
325 struct ch_struct *ch;
326 struct un_struct *un;
327
328 if (!d)
329 return 0;
330 un = (struct un_struct *) dev_get_drvdata(d);
331 if (!un)
332 return 0;
333 ch = un->un_ch;
334 if (!ch)
335 return 0;
336 return snprintf(buf, PAGE_SIZE, "%d\n",
337 un->un_open_count ? (PORTSERVER_DIVIDEND / ch->ch_s_brate) : 0);
338}
339static DEVICE_ATTR(baud_info, 0400, dgrp_tty_baud_show, NULL);
340
341
342static ssize_t dgrp_tty_msignals_show(struct device *d,
343 struct device_attribute *attr, char *buf)
344{
345 struct ch_struct *ch;
346 struct un_struct *un;
347
348 if (!d)
349 return 0;
350 un = (struct un_struct *) dev_get_drvdata(d);
351 if (!un)
352 return 0;
353 ch = un->un_ch;
354 if (!ch)
355 return 0;
356
357 if (ch->ch_open_count) {
358 return snprintf(buf, PAGE_SIZE, "%s %s %s %s %s %s\n",
359 (ch->ch_s_mlast & DM_RTS) ? "RTS" : "",
360 (ch->ch_s_mlast & DM_CTS) ? "CTS" : "",
361 (ch->ch_s_mlast & DM_DTR) ? "DTR" : "",
362 (ch->ch_s_mlast & DM_DSR) ? "DSR" : "",
363 (ch->ch_s_mlast & DM_CD) ? "DCD" : "",
364 (ch->ch_s_mlast & DM_RI) ? "RI" : "");
365 }
366 return 0;
367}
368static DEVICE_ATTR(msignals_info, 0400, dgrp_tty_msignals_show, NULL);
369
370
371static ssize_t dgrp_tty_iflag_show(struct device *d,
372 struct device_attribute *attr, char *buf)
373{
374 struct ch_struct *ch;
375 struct un_struct *un;
376
377 if (!d)
378 return 0;
379 un = (struct un_struct *) dev_get_drvdata(d);
380 if (!un)
381 return 0;
382 ch = un->un_ch;
383 if (!ch)
384 return 0;
385 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_s_iflag);
386}
387static DEVICE_ATTR(iflag_info, 0600, dgrp_tty_iflag_show, NULL);
388
389
390static ssize_t dgrp_tty_cflag_show(struct device *d,
391 struct device_attribute *attr, char *buf)
392{
393 struct ch_struct *ch;
394 struct un_struct *un;
395
396 if (!d)
397 return 0;
398 un = (struct un_struct *) dev_get_drvdata(d);
399 if (!un)
400 return 0;
401 ch = un->un_ch;
402 if (!ch)
403 return 0;
404 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_s_cflag);
405}
406static DEVICE_ATTR(cflag_info, 0600, dgrp_tty_cflag_show, NULL);
407
408
409static ssize_t dgrp_tty_oflag_show(struct device *d,
410 struct device_attribute *attr, char *buf)
411{
412 struct ch_struct *ch;
413 struct un_struct *un;
414
415 if (!d)
416 return 0;
417 un = (struct un_struct *) dev_get_drvdata(d);
418 if (!un)
419 return 0;
420 ch = un->un_ch;
421 if (!ch)
422 return 0;
423 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_s_oflag);
424}
425static DEVICE_ATTR(oflag_info, 0600, dgrp_tty_oflag_show, NULL);
426
427
428static ssize_t dgrp_tty_digi_flag_show(struct device *d,
429 struct device_attribute *attr, char *buf)
430{
431 struct ch_struct *ch;
432 struct un_struct *un;
433
434 if (!d)
435 return 0;
436 un = (struct un_struct *) dev_get_drvdata(d);
437 if (!un)
438 return 0;
439 ch = un->un_ch;
440 if (!ch)
441 return 0;
442 return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_digi.digi_flags);
443}
444static DEVICE_ATTR(digi_flag_info, 0600, dgrp_tty_digi_flag_show, NULL);
445
446
447static ssize_t dgrp_tty_rxcount_show(struct device *d,
448 struct device_attribute *attr, char *buf)
449{
450 struct ch_struct *ch;
451 struct un_struct *un;
452
453 if (!d)
454 return 0;
455 un = (struct un_struct *) dev_get_drvdata(d);
456 if (!un)
457 return 0;
458 ch = un->un_ch;
459 if (!ch)
460 return 0;
461 return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_rxcount);
462}
463static DEVICE_ATTR(rxcount_info, 0600, dgrp_tty_rxcount_show, NULL);
464
465
466static ssize_t dgrp_tty_txcount_show(struct device *d,
467 struct device_attribute *attr, char *buf)
468{
469 struct ch_struct *ch;
470 struct un_struct *un;
471
472 if (!d)
473 return 0;
474 un = (struct un_struct *) dev_get_drvdata(d);
475 if (!un)
476 return 0;
477 ch = un->un_ch;
478 if (!ch)
479 return 0;
480 return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_txcount);
481}
482static DEVICE_ATTR(txcount_info, 0600, dgrp_tty_txcount_show, NULL);
483
484
485static ssize_t dgrp_tty_name_show(struct device *d,
486 struct device_attribute *attr, char *buf)
487{
488 struct nd_struct *nd;
489 struct ch_struct *ch;
490 struct un_struct *un;
491 char name[10];
492
493 if (!d)
494 return 0;
495 un = (struct un_struct *) dev_get_drvdata(d);
496 if (!un)
497 return 0;
498 ch = un->un_ch;
499 if (!ch)
500 return 0;
501 nd = ch->ch_nd;
502 if (!nd)
503 return 0;
504
505 ID_TO_CHAR(nd->nd_ID, name);
506
507 return snprintf(buf, PAGE_SIZE, "%s%s%02d\n",
508 un->un_type == SERIAL_TYPE_XPRINT ? "pr" : "tty",
509 name, ch->ch_portnum);
510}
511static DEVICE_ATTR(custom_name, 0600, dgrp_tty_name_show, NULL);
512
513
514static struct attribute *dgrp_sysfs_tty_entries[] = {
515 &dev_attr_state_info.attr,
516 &dev_attr_baud_info.attr,
517 &dev_attr_msignals_info.attr,
518 &dev_attr_iflag_info.attr,
519 &dev_attr_cflag_info.attr,
520 &dev_attr_oflag_info.attr,
521 &dev_attr_digi_flag_info.attr,
522 &dev_attr_rxcount_info.attr,
523 &dev_attr_txcount_info.attr,
524 &dev_attr_custom_name.attr,
525 NULL
526};
527
528
529static struct attribute_group dgrp_tty_attribute_group = {
530 .name = NULL,
531 .attrs = dgrp_sysfs_tty_entries,
532};
533
534
535void dgrp_create_tty_sysfs(struct un_struct *un, struct device *c)
536{
537 int ret;
538
539 ret = sysfs_create_group(&c->kobj, &dgrp_tty_attribute_group);
540 if (ret) {
541 pr_alert("%s: failed to create sysfs tty device attributes.\n",
542 __func__);
543 sysfs_remove_group(&c->kobj, &dgrp_tty_attribute_group);
544 return;
545 }
546
547 dev_set_drvdata(c, un);
548
549}
550
551
552void dgrp_remove_tty_sysfs(struct device *c)
553{
554 sysfs_remove_group(&c->kobj, &dgrp_tty_attribute_group);
555}
diff --git a/drivers/staging/dgrp/dgrp_tty.c b/drivers/staging/dgrp/dgrp_tty.c
new file mode 100644
index 00000000000..7d7de873870
--- /dev/null
+++ b/drivers/staging/dgrp/dgrp_tty.c
@@ -0,0 +1,3331 @@
1/*
2 *
3 * Copyright 1999 Digi International (www.digi.com)
4 * Gene Olson <Gene_Olson at digi dot com>
5 * James Puzzo <jamesp at digi dot com>
6 * Jeff Randall
7 * Scott Kilau <scottk at digi dot com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2, or (at your option)
12 * any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
16 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
17 * PURPOSE. See the GNU General Public License for more details.
18 *
19 */
20
21/*
22 *
23 * Filename:
24 *
25 * dgrp_tty.c
26 *
27 * Description:
28 *
29 * This file implements the tty driver functionality for the
30 * RealPort driver software.
31 *
32 * Author:
33 *
34 * James A. Puzzo
35 * Ann-Marie Westgate
36 *
37 */
38
39#include <linux/slab.h>
40#include <linux/tty.h>
41#include <linux/tty_flip.h>
42#include <linux/sched.h>
43
44#include "dgrp_common.h"
45
46#ifndef _POSIX_VDISABLE
47#define _POSIX_VDISABLE ('\0')
48#endif
49
50/*
51 * forward declarations
52 */
53
54static void drp_param(struct ch_struct *);
55static void dgrp_tty_close(struct tty_struct *, struct file *);
56
57/* ioctl helper functions */
58static int set_modem_info(struct ch_struct *, unsigned int, unsigned int *);
59static int get_modem_info(struct ch_struct *, unsigned int *);
60static void dgrp_set_custom_speed(struct ch_struct *, int);
61static int dgrp_tty_digigetedelay(struct tty_struct *, int *);
62static int dgrp_tty_digisetedelay(struct tty_struct *, int *);
63static int dgrp_send_break(struct ch_struct *, int);
64
65static ushort tty_to_ch_flags(struct tty_struct *, char);
66static tcflag_t ch_to_tty_flags(unsigned short, char);
67
68static void dgrp_tty_input_start(struct tty_struct *);
69static void dgrp_tty_input_stop(struct tty_struct *);
70
71static void drp_wmove(struct ch_struct *, int, void*, int);
72
73static int dgrp_tty_open(struct tty_struct *, struct file *);
74static void dgrp_tty_close(struct tty_struct *, struct file *);
75static int dgrp_tty_write(struct tty_struct *, const unsigned char *, int);
76static int dgrp_tty_write_room(struct tty_struct *);
77static void dgrp_tty_flush_buffer(struct tty_struct *);
78static int dgrp_tty_chars_in_buffer(struct tty_struct *);
79static int dgrp_tty_ioctl(struct tty_struct *, unsigned int, unsigned long);
80static void dgrp_tty_set_termios(struct tty_struct *, struct ktermios *);
81static void dgrp_tty_stop(struct tty_struct *);
82static void dgrp_tty_start(struct tty_struct *);
83static void dgrp_tty_throttle(struct tty_struct *);
84static void dgrp_tty_unthrottle(struct tty_struct *);
85static void dgrp_tty_hangup(struct tty_struct *);
86static int dgrp_tty_put_char(struct tty_struct *, unsigned char);
87static int dgrp_tty_tiocmget(struct tty_struct *);
88static int dgrp_tty_tiocmset(struct tty_struct *, unsigned int, unsigned int);
89static int dgrp_tty_send_break(struct tty_struct *, int);
90static void dgrp_tty_send_xchar(struct tty_struct *, char);
91
92/*
93 * tty defines
94 */
95#define SERIAL_TYPE_NORMAL 1
96#define SERIAL_TYPE_CALLOUT 2
97#define SERIAL_TYPE_XPRINT 3
98
99
100/*
101 * tty globals/statics
102 */
103
104
105#define PORTSERVER_DIVIDEND 1843200
106
107/*
108 * Default transparent print information.
109 */
110static struct digi_struct digi_init = {
111 .digi_flags = DIGI_COOK, /* Flags */
112 .digi_maxcps = 100, /* Max CPS */
113 .digi_maxchar = 50, /* Max chars in print queue */
114 .digi_bufsize = 100, /* Printer buffer size */
115 .digi_onlen = 4, /* size of printer on string */
116 .digi_offlen = 4, /* size of printer off string */
117 .digi_onstr = "\033[5i", /* ANSI printer on string */
118 .digi_offstr = "\033[4i", /* ANSI printer off string */
119 .digi_term = "ansi" /* default terminal type */
120};
121
122/*
123 * Define a local default termios struct. All ports will be created
124 * with this termios initially.
125 *
126 * This defines a raw port at 9600 baud, 8 data bits, no parity,
127 * 1 stop bit.
128 */
129static struct ktermios DefaultTermios = {
130 .c_iflag = (ICRNL | IXON),
131 .c_oflag = (OPOST | ONLCR),
132 .c_cflag = (B9600 | CS8 | CREAD | HUPCL | CLOCAL),
133 .c_lflag = (ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL
134 | ECHOKE | IEXTEN),
135 .c_cc = INIT_C_CC,
136 .c_line = 0,
137};
138
139/* Define our tty operations struct */
140static const struct tty_operations dgrp_tty_ops = {
141 .open = dgrp_tty_open,
142 .close = dgrp_tty_close,
143 .write = dgrp_tty_write,
144 .write_room = dgrp_tty_write_room,
145 .flush_buffer = dgrp_tty_flush_buffer,
146 .chars_in_buffer = dgrp_tty_chars_in_buffer,
147 .flush_chars = NULL,
148 .ioctl = dgrp_tty_ioctl,
149 .set_termios = dgrp_tty_set_termios,
150 .stop = dgrp_tty_stop,
151 .start = dgrp_tty_start,
152 .throttle = dgrp_tty_throttle,
153 .unthrottle = dgrp_tty_unthrottle,
154 .hangup = dgrp_tty_hangup,
155 .put_char = dgrp_tty_put_char,
156 .tiocmget = dgrp_tty_tiocmget,
157 .tiocmset = dgrp_tty_tiocmset,
158 .break_ctl = dgrp_tty_send_break,
159 .send_xchar = dgrp_tty_send_xchar
160};
161
162
163static int calc_baud_rate(struct un_struct *un)
164{
165 int i;
166 int brate;
167
168 struct baud_rates {
169 unsigned int rate;
170 unsigned int cflag;
171 };
172
173 static struct baud_rates baud_rates[] = {
174 { 921600, B921600 },
175 { 460800, B460800 },
176 { 230400, B230400 },
177 { 115200, B115200 },
178 { 57600, B57600 },
179 { 38400, B38400 },
180 { 19200, B19200 },
181 { 9600, B9600 },
182 { 4800, B4800 },
183 { 2400, B2400 },
184 { 1200, B1200 },
185 { 600, B600 },
186 { 300, B300 },
187 { 200, B200 },
188 { 150, B150 },
189 { 134, B134 },
190 { 110, B110 },
191 { 75, B75 },
192 { 50, B50 },
193 { 0, B9600 }
194 };
195
196 brate = C_BAUD(un->un_tty);
197
198 for (i = 0; baud_rates[i].rate; i++) {
199 if (baud_rates[i].cflag == brate)
200 break;
201 }
202
203 return baud_rates[i].rate;
204}
205
206static int calc_fastbaud_rate(struct un_struct *un, struct ktermios *uts)
207{
208 int i;
209 int brate;
210
211 ulong bauds[2][16] = {
212 { /* fastbaud*/
213 0, 57600, 76800, 115200,
214 131657, 153600, 230400, 460800,
215 921600, 1200, 1800, 2400,
216 4800, 9600, 19200, 38400 },
217 { /* fastbaud & CBAUDEX */
218 0, 57600, 115200, 230400,
219 460800, 150, 200, 921600,
220 600, 1200, 1800, 2400,
221 4800, 9600, 19200, 38400 }
222 };
223
224 brate = C_BAUD(un->un_tty) & 0xff;
225
226 i = (uts->c_cflag & CBAUDEX) ? 1 : 0;
227
228
229 if ((i >= 0) && (i < 2) && (brate >= 0) && (brate < 16))
230 brate = bauds[i][brate];
231 else
232 brate = 0;
233
234 return brate;
235}
236
237/**
238 * drp_param() -- send parameter values to be sent to the node
239 * @ch: channel structure of port to modify
240 *
241 * Interprets the tty and modem changes made by an application
242 * program (by examining the termios structures) and sets up
243 * parameter values to be sent to the node.
244 */
245static void drp_param(struct ch_struct *ch)
246{
247 struct nd_struct *nd;
248 struct un_struct *un;
249 int brate;
250 int mflow;
251 int xflag;
252 int iflag;
253 struct ktermios *tts, *pts, *uts;
254
255 nd = ch->ch_nd;
256
257 /*
258 * If the terminal device is open, use it to set up all tty
259 * modes and functions. Otherwise use the printer device.
260 */
261
262 if (ch->ch_tun.un_open_count) {
263
264 un = &ch->ch_tun;
265 tts = &ch->ch_tun.un_tty->termios;
266
267 /*
268 * If both devices are open, copy critical line
269 * parameters from the tty device to the printer,
270 * so that if the tty is closed, the printer will
271 * continue without disruption.
272 */
273
274 if (ch->ch_pun.un_open_count) {
275
276 pts = &ch->ch_pun.un_tty->termios;
277
278 pts->c_cflag ^=
279 (pts->c_cflag ^ tts->c_cflag) &
280 (CBAUD | CSIZE | CSTOPB | CREAD | PARENB |
281 PARODD | HUPCL | CLOCAL);
282
283 pts->c_iflag ^=
284 (pts->c_iflag ^ tts->c_iflag) &
285 (IGNBRK | BRKINT | IGNPAR | PARMRK | INPCK |
286 ISTRIP | IXON | IXANY | IXOFF);
287
288 pts->c_cc[VSTART] = tts->c_cc[VSTART];
289 pts->c_cc[VSTOP] = tts->c_cc[VSTOP];
290 }
291 } else if (ch->ch_pun.un_open_count == 0) {
292 pr_warn("%s - ch_pun.un_open_count shouldn't be 0\n",
293 __func__);
294 return;
295 } else {
296 un = &ch->ch_pun;
297 }
298
299 uts = &un->un_tty->termios;
300
301 /*
302 * Determine if FAST writes can be performed.
303 */
304
305 if ((ch->ch_digi.digi_flags & DIGI_COOK) != 0 &&
306 (ch->ch_tun.un_open_count != 0) &&
307 !((un->un_tty)->ldisc->ops->flags & LDISC_FLAG_DEFINED) &&
308 !(L_XCASE(un->un_tty))) {
309 ch->ch_flag |= CH_FAST_WRITE;
310 } else {
311 ch->ch_flag &= ~CH_FAST_WRITE;
312 }
313
314 /*
315 * If FAST writes can be performed, and OPOST is on in the
316 * terminal device, do OPOST handling in the server.
317 */
318
319 if ((ch->ch_flag & CH_FAST_WRITE) &&
320 O_OPOST(un->un_tty) != 0) {
321 int oflag = tty_to_ch_flags(un->un_tty, 'o');
322
323 /* add to ch_ocook any processing flags set in the termio */
324 ch->ch_ocook |= oflag & (OF_OLCUC |
325 OF_ONLCR |
326 OF_OCRNL |
327 OF_ONLRET |
328 OF_TABDLY);
329
330 /*
331 * the hpux driver clears any flags set in ch_ocook
332 * from the termios oflag. It is STILL reported though
333 * by a TCGETA
334 */
335
336 oflag = ch_to_tty_flags(ch->ch_ocook, 'o');
337 uts->c_oflag &= ~oflag;
338
339 } else {
340 /* clear the ch->ch_ocook flag */
341 int oflag = ch_to_tty_flags(ch->ch_ocook, 'o');
342 uts->c_oflag |= oflag;
343 ch->ch_ocook = 0;
344 }
345
346 ch->ch_oflag = ch->ch_ocook;
347
348
349 ch->ch_flag &= ~CH_FAST_READ;
350
351 /*
352 * Generate channel flags
353 */
354
355 if (C_BAUD(un->un_tty) == B0) {
356 if (!(ch->ch_flag & CH_BAUD0)) {
357 /* TODO : the HPUX driver flushes line */
358 /* TODO : discipline, I assume I don't have to */
359
360 ch->ch_tout = ch->ch_tin;
361 ch->ch_rout = ch->ch_rin;
362
363 ch->ch_break_time = 0;
364
365 ch->ch_send |= RR_TX_FLUSH | RR_RX_FLUSH;
366
367 ch->ch_mout &= ~(DM_DTR | DM_RTS);
368
369 ch->ch_flag |= CH_BAUD0;
370 }
371 } else if (ch->ch_custom_speed) {
372 ch->ch_brate = PORTSERVER_DIVIDEND / ch->ch_custom_speed ;
373
374 if (ch->ch_flag & CH_BAUD0) {
375 ch->ch_mout |= DM_DTR | DM_RTS;
376
377 ch->ch_flag &= ~CH_BAUD0;
378 }
379 } else {
380 /*
381 * Baud rate mapping.
382 *
383 * If FASTBAUD isn't on, we can scan the new baud rate list
384 * as required.
385 *
386 * However, if FASTBAUD is on, we must go to the old
387 * baud rate mapping that existed many many moons ago,
388 * for compatibility reasons.
389 */
390
391 if (!(ch->ch_digi.digi_flags & DIGI_FAST))
392 brate = calc_baud_rate(un);
393 else
394 brate = calc_fastbaud_rate(un, uts);
395
396 if (brate == 0)
397 brate = 9600;
398
399 ch->ch_brate = PORTSERVER_DIVIDEND / brate;
400
401 if (ch->ch_flag & CH_BAUD0) {
402 ch->ch_mout |= DM_DTR | DM_RTS;
403
404 ch->ch_flag &= ~CH_BAUD0;
405 }
406 }
407
408 /*
409 * Generate channel cflags from the termio.
410 */
411
412 ch->ch_cflag = tty_to_ch_flags(un->un_tty, 'c');
413
414 /*
415 * Generate channel iflags from the termio.
416 */
417
418 iflag = (int) tty_to_ch_flags(un->un_tty, 'i');
419
420 if (START_CHAR(un->un_tty) == _POSIX_VDISABLE ||
421 STOP_CHAR(un->un_tty) == _POSIX_VDISABLE) {
422 iflag &= ~(IF_IXON | IF_IXANY | IF_IXOFF);
423 }
424
425 ch->ch_iflag = iflag;
426
427 /*
428 * Generate flow control characters
429 */
430
431 /*
432 * From the POSIX.1 spec (7.1.2.6): "If {_POSIX_VDISABLE}
433 * is defined for the terminal device file, and the value
434 * of one of the changable special control characters (see
435 * 7.1.1.9) is {_POSIX_VDISABLE}, that function shall be
436 * disabled, that is, no input data shall be recognized as
437 * the disabled special character."
438 *
439 * OK, so we don't ever assign S/DXB XON or XOFF to _POSIX_VDISABLE.
440 */
441
442 if (uts->c_cc[VSTART] != _POSIX_VDISABLE)
443 ch->ch_xon = uts->c_cc[VSTART];
444 if (uts->c_cc[VSTOP] != _POSIX_VDISABLE)
445 ch->ch_xoff = uts->c_cc[VSTOP];
446
447 ch->ch_lnext = (uts->c_cc[VLNEXT] == _POSIX_VDISABLE ? 0 :
448 uts->c_cc[VLNEXT]);
449
450 /*
451 * Also, if either c_cc[START] or c_cc[STOP] is set to
452 * _POSIX_VDISABLE, we can't really do software flow
453 * control--in either direction--so we turn it off as
454 * far as S/DXB is concerned. In essence, if you disable
455 * one, you disable the other too.
456 */
457 if ((uts->c_cc[VSTART] == _POSIX_VDISABLE) ||
458 (uts->c_cc[VSTOP] == _POSIX_VDISABLE))
459 ch->ch_iflag &= ~(IF_IXOFF | IF_IXON);
460
461 /*
462 * Update xflags.
463 */
464
465 xflag = 0;
466
467 if (ch->ch_digi.digi_flags & DIGI_AIXON)
468 xflag = XF_XIXON;
469
470 if ((ch->ch_xxon == _POSIX_VDISABLE) ||
471 (ch->ch_xxoff == _POSIX_VDISABLE))
472 xflag &= ~XF_XIXON;
473
474 ch->ch_xflag = xflag;
475
476
477 /*
478 * Figure effective DCD value.
479 */
480
481 if (C_CLOCAL(un->un_tty))
482 ch->ch_flag |= CH_CLOCAL;
483 else
484 ch->ch_flag &= ~CH_CLOCAL;
485
486 /*
487 * Check modem signals
488 */
489
490 dgrp_carrier(ch);
491
492 /*
493 * Get hardware handshake value.
494 */
495
496 mflow = 0;
497
498 if (C_CRTSCTS(un->un_tty))
499 mflow |= (DM_RTS | DM_CTS);
500
501 if (ch->ch_digi.digi_flags & RTSPACE)
502 mflow |= DM_RTS;
503
504 if (ch->ch_digi.digi_flags & DTRPACE)
505 mflow |= DM_DTR;
506
507 if (ch->ch_digi.digi_flags & CTSPACE)
508 mflow |= DM_CTS;
509
510 if (ch->ch_digi.digi_flags & DSRPACE)
511 mflow |= DM_DSR;
512
513 if (ch->ch_digi.digi_flags & DCDPACE)
514 mflow |= DM_CD;
515
516 if (ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE)
517 mflow |= DM_RTS_TOGGLE;
518
519 ch->ch_mflow = mflow;
520
521 /*
522 * Send the changes to the server.
523 */
524
525 ch->ch_flag |= CH_PARAM;
526 (ch->ch_nd)->nd_tx_work = 1;
527
528 if (waitqueue_active(&ch->ch_flag_wait))
529 wake_up_interruptible(&ch->ch_flag_wait);
530}
531
532/*
533 * This function is just used as a callback for timeouts
534 * waiting on the ch_sleep flag.
535 */
536static void wake_up_drp_sleep_timer(unsigned long ptr)
537{
538 struct ch_struct *ch = (struct ch_struct *) ptr;
539 if (ch)
540 wake_up(&ch->ch_sleep);
541}
542
543
544/*
545 * Set up our own sleep that can't be cancelled
546 * until our timeout occurs.
547 */
548static void drp_my_sleep(struct ch_struct *ch)
549{
550 struct timer_list drp_wakeup_timer;
551 DECLARE_WAITQUEUE(wait, current);
552
553 /*
554 * First make sure we're ready to receive the wakeup.
555 */
556
557 add_wait_queue(&ch->ch_sleep, &wait);
558 current->state = TASK_UNINTERRUPTIBLE;
559
560 /*
561 * Since we are uninterruptible, set a timer to
562 * unset the uninterruptable state in 1 second.
563 */
564
565 init_timer(&drp_wakeup_timer);
566 drp_wakeup_timer.function = wake_up_drp_sleep_timer;
567 drp_wakeup_timer.data = (unsigned long) ch;
568 drp_wakeup_timer.expires = jiffies + (1 * HZ);
569 add_timer(&drp_wakeup_timer);
570
571 schedule();
572
573 del_timer(&drp_wakeup_timer);
574
575 remove_wait_queue(&ch->ch_sleep, &wait);
576}
577
578/*
579 * dgrp_tty_open()
580 *
581 * returns:
582 * -EBUSY - this is a callout device and the normal device is active
583 * - there is an error in opening the tty
584 * -ENODEV - the channel does not exist
585 * -EAGAIN - we are in the middle of hanging up or closing
586 * - IMMEDIATE_OPEN fails
587 * -ENXIO or -EAGAIN
588 * - if the port is outside physical range
589 * -EINTR - the open is interrupted
590 *
591 */
592static int dgrp_tty_open(struct tty_struct *tty, struct file *file)
593{
594 int retval = 0;
595 struct nd_struct *nd;
596 struct ch_struct *ch;
597 struct un_struct *un;
598 int port;
599 int delay_error;
600 int otype;
601 int unf;
602 int wait_carrier;
603 int category;
604 int counts_were_incremented = 0;
605 ulong lock_flags;
606 DECLARE_WAITQUEUE(wait, current);
607
608 /*
609 * Do some initial checks to see if the node and port exist
610 */
611
612 nd = nd_struct_get(MAJOR(tty_devnum(tty)));
613 port = PORT_NUM(MINOR(tty_devnum(tty)));
614 category = OPEN_CATEGORY(MINOR(tty_devnum(tty)));
615
616 if (!nd)
617 return -ENODEV;
618
619 if (port >= CHAN_MAX)
620 return -ENODEV;
621
622 /*
623 * The channel exists.
624 */
625
626 ch = nd->nd_chan + port;
627
628 un = IS_PRINT(MINOR(tty_devnum(tty))) ? &ch->ch_pun : &ch->ch_tun;
629 un->un_tty = tty;
630 tty->driver_data = un;
631
632 /*
633 * If we are in the middle of hanging up,
634 * then return an error
635 */
636 if (tty_hung_up_p(file)) {
637 retval = ((un->un_flag & UN_HUP_NOTIFY) ?
638 -EAGAIN : -ERESTARTSYS);
639 goto done;
640 }
641
642 /*
643 * If the port is in the middle of closing, then block
644 * until it is done, then try again.
645 */
646 retval = wait_event_interruptible(un->un_close_wait,
647 ((un->un_flag & UN_CLOSING) == 0));
648
649 if (retval)
650 goto done;
651
652 /*
653 * If the port is in the middle of a reopen after a network disconnect,
654 * wait until it is done, then try again.
655 */
656 retval = wait_event_interruptible(ch->ch_flag_wait,
657 ((ch->ch_flag & CH_PORT_GONE) == 0));
658
659 if (retval)
660 goto done;
661
662 /*
663 * If this is a callout device, then just make sure the normal
664 * device isn't being used.
665 */
666
667 if (tty->driver->subtype == SERIAL_TYPE_CALLOUT) {
668 if (un->un_flag & UN_NORMAL_ACTIVE) {
669 retval = -EBUSY;
670 goto done;
671 } else {
672 un->un_flag |= UN_CALLOUT_ACTIVE;
673 }
674 }
675
676 /*
677 * Loop waiting until the open can be successfully completed.
678 */
679
680 spin_lock_irqsave(&nd->nd_lock, lock_flags);
681
682 nd->nd_tx_work = 1;
683
684 for (;;) {
685 wait_carrier = 0;
686
687 /*
688 * Determine the open type from the flags provided.
689 */
690
691 /*
692 * If the port is not enabled, then exit
693 */
694 if (test_bit(TTY_IO_ERROR, &tty->flags)) {
695 /* there was an error in opening the tty */
696 if (un->un_flag & UN_CALLOUT_ACTIVE)
697 retval = -EBUSY;
698 else
699 un->un_flag |= UN_NORMAL_ACTIVE;
700 goto unlock;
701 }
702
703 if (file->f_flags & O_NONBLOCK) {
704
705 /*
706 * if the O_NONBLOCK is set, errors on read and write
707 * must return -EAGAIN immediately and NOT sleep
708 * on the waitqs.
709 */
710 otype = OTYPE_IMMEDIATE;
711 delay_error = -EAGAIN;
712
713 } else if (!OPEN_WAIT_AVAIL(category) ||
714 (file->f_flags & O_NDELAY) != 0) {
715 otype = OTYPE_IMMEDIATE;
716 delay_error = -EBUSY;
717
718 } else if (!OPEN_WAIT_CARRIER(category) ||
719 ((ch->ch_digi.digi_flags & DIGI_FORCEDCD) != 0) ||
720 C_CLOCAL(tty)) {
721 otype = OTYPE_PERSISTENT;
722 delay_error = 0;
723
724 } else {
725 otype = OTYPE_INCOMING;
726 delay_error = 0;
727 }
728
729 /*
730 * Handle port currently outside physical port range.
731 */
732
733 if (port >= nd->nd_chan_count) {
734 if (otype == OTYPE_IMMEDIATE) {
735 retval = (nd->nd_state == NS_READY) ?
736 -ENXIO : -EAGAIN;
737 goto unlock;
738 }
739 }
740
741 /*
742 * Handle port not currently open.
743 */
744
745 else if (ch->ch_open_count == 0) {
746 /*
747 * Return an error when an Incoming Open
748 * response indicates the port is busy.
749 */
750
751 if (ch->ch_open_error != 0 && otype == ch->ch_otype) {
752 retval = (ch->ch_open_error <= 2) ?
753 delay_error : -ENXIO ;
754 goto unlock;
755 }
756
757 /*
758 * Fail any new Immediate open if we do not have
759 * a normal connection to the server.
760 */
761
762 if (nd->nd_state != NS_READY &&
763 otype == OTYPE_IMMEDIATE) {
764 retval = -EAGAIN;
765 goto unlock;
766 }
767
768 /*
769 * If a Realport open of the correct type has
770 * succeeded, complete the open.
771 */
772
773 if (ch->ch_state == CS_READY && ch->ch_otype == otype)
774 break;
775 }
776
777 /*
778 * Handle port already open and active as a device
779 * of same category.
780 */
781
782 else if ((ch->ch_category == category) ||
783 IS_PRINT(MINOR(tty_devnum(tty)))) {
784 /*
785 * Fail if opening the device now would
786 * violate exclusive use.
787 */
788 unf = ch->ch_tun.un_flag | ch->ch_pun.un_flag;
789
790 if ((file->f_flags & O_EXCL) || (unf & UN_EXCL)) {
791 retval = -EBUSY;
792 goto unlock;
793 }
794
795 /*
796 * If the open device is in the hangup state, all
797 * system calls fail except close().
798 */
799
800 /* TODO : check on hangup_p calls */
801
802 if (ch->ch_flag & CH_HANGUP) {
803 retval = -ENXIO;
804 goto unlock;
805 }
806
807 /*
808 * If the port is ready, and carrier is ignored
809 * or present, then complete the open.
810 */
811
812 if (ch->ch_state == CS_READY &&
813 (otype != OTYPE_INCOMING ||
814 ch->ch_flag & CH_VIRT_CD))
815 break;
816
817 wait_carrier = 1;
818 }
819
820 /*
821 * Handle port active with a different category device.
822 */
823
824 else {
825 if (otype == OTYPE_IMMEDIATE) {
826 retval = delay_error;
827 goto unlock;
828 }
829 }
830
831 /*
832 * Wait until conditions change, then take another
833 * try at the open.
834 */
835
836 ch->ch_wait_count[otype]++;
837
838 if (wait_carrier)
839 ch->ch_wait_carrier++;
840
841 /*
842 * Prepare the task to accept the wakeup, then
843 * release our locks and release control.
844 */
845
846 add_wait_queue(&ch->ch_flag_wait, &wait);
847 current->state = TASK_INTERRUPTIBLE;
848
849 spin_unlock_irqrestore(&nd->nd_lock, lock_flags);
850
851 /*
852 * Give up control, we'll come back if we're
853 * interrupted or are woken up.
854 */
855 schedule();
856 remove_wait_queue(&ch->ch_flag_wait, &wait);
857
858 spin_lock_irqsave(&nd->nd_lock, lock_flags);
859
860 current->state = TASK_RUNNING;
861
862 ch->ch_wait_count[otype]--;
863
864 if (wait_carrier)
865 ch->ch_wait_carrier--;
866
867 nd->nd_tx_work = 1;
868
869 if (signal_pending(current)) {
870 retval = -EINTR;
871 goto unlock;
872 }
873 } /* end for(;;) */
874
875 /*
876 * The open has succeeded. No turning back.
877 */
878 counts_were_incremented = 1;
879 un->un_open_count++;
880 ch->ch_open_count++;
881
882 /*
883 * Initialize the channel, if it's not already open.
884 */
885
886 if (ch->ch_open_count == 1) {
887 ch->ch_flag = 0;
888 ch->ch_inwait = 0;
889 ch->ch_category = category;
890 ch->ch_pscan_state = 0;
891
892 /* TODO : find out what PS-1 bug Gene was referring to */
893 /* TODO : in the following comment. */
894
895 ch->ch_send = RR_TX_START | RR_RX_START; /* PS-1 bug */
896
897 if (C_CLOCAL(tty) ||
898 ch->ch_s_mlast & DM_CD ||
899 ch->ch_digi.digi_flags & DIGI_FORCEDCD)
900 ch->ch_flag |= CH_VIRT_CD;
901 else if (OPEN_FORCES_CARRIER(category))
902 ch->ch_flag |= CH_VIRT_CD;
903
904 }
905
906 /*
907 * Initialize the unit, if it is not already open.
908 */
909
910 if (un->un_open_count == 1) {
911 /*
912 * Since all terminal options are always sticky in Linux,
913 * we don't need the UN_STICKY flag to be handled specially.
914 */
915 /* clears all the digi flags, leaves serial flags */
916 un->un_flag &= ~UN_DIGI_MASK;
917
918 if (file->f_flags & O_EXCL)
919 un->un_flag |= UN_EXCL;
920
921 /* TODO : include "session" and "pgrp" */
922
923 /*
924 * In Linux, all terminal parameters are intended to be sticky.
925 * as a result, we "remove" the code which once reset the ports
926 * to sane values.
927 */
928
929 drp_param(ch);
930
931 }
932
933 un->un_flag |= UN_INITIALIZED;
934
935 retval = 0;
936
937unlock:
938
939 spin_unlock_irqrestore(&nd->nd_lock, lock_flags);
940
941done:
942 /*
943 * Linux does a close for every open, even failed ones!
944 */
945 if (!counts_were_incremented) {
946 un->un_open_count++;
947 ch->ch_open_count++;
948 }
949
950 if (retval)
951 dev_err(tty->dev, "tty open bad return (%i)\n", retval);
952
953 return retval;
954}
955
956
957
958
959/*
960 * dgrp_tty_close() -- close function for tty_operations
961 */
962static void dgrp_tty_close(struct tty_struct *tty, struct file *file)
963{
964 struct ch_struct *ch;
965 struct un_struct *un;
966 struct nd_struct *nd;
967 int tpos;
968 int port;
969 int err = 0;
970 int s = 0;
971 ulong waketime;
972 ulong lock_flags;
973 int sent_printer_offstr = 0;
974
975 port = PORT_NUM(MINOR(tty_devnum(tty)));
976
977 un = tty->driver_data;
978
979 if (!un)
980 return;
981
982 ch = un->un_ch;
983
984 if (!ch)
985 return;
986
987 nd = ch->ch_nd;
988
989 if (!nd)
990 return;
991
992 spin_lock_irqsave(&nd->nd_lock, lock_flags);
993
994
995 /* Used to be on channel basis, now we check on a unit basis. */
996 if (un->un_open_count != 1)
997 goto unlock;
998
999 /*
1000 * OK, its the last close on the unit
1001 */
1002 un->un_flag |= UN_CLOSING;
1003
1004 /*
1005 * Notify the discipline to only process XON/XOFF characters.
1006 */
1007 tty->closing = 1;
1008
1009 /*
1010 * Wait for output to drain only if this is
1011 * the last close against the channel
1012 */
1013
1014 if (ch->ch_open_count == 1) {
1015 /*
1016 * If its the print device, we need to ensure at all costs that
1017 * the offstr will fit. If it won't, flush our tbuf.
1018 */
1019 if (IS_PRINT(MINOR(tty_devnum(tty))) &&
1020 (((ch->ch_tout - ch->ch_tin - 1) & TBUF_MASK) <
1021 ch->ch_digi.digi_offlen))
1022 ch->ch_tin = ch->ch_tout;
1023
1024 /*
1025 * Turn off the printer. Don't bother checking to see if its
1026 * IS_PRINT... Since this is the last close the flag is going
1027 * to be cleared, so we MUST make sure the offstr gets inserted
1028 * into tbuf.
1029 */
1030
1031 if ((ch->ch_flag & CH_PRON) != 0) {
1032 drp_wmove(ch, 0, ch->ch_digi.digi_offstr,
1033 ch->ch_digi.digi_offlen);
1034 ch->ch_flag &= ~CH_PRON;
1035 sent_printer_offstr = 1;
1036 }
1037 }
1038
1039 /*
1040 * Wait until either the output queue has drained, or we see
1041 * absolutely no progress for 15 seconds.
1042 */
1043
1044 tpos = ch->ch_s_tpos;
1045
1046 waketime = jiffies + 15 * HZ;
1047
1048 for (;;) {
1049
1050 /*
1051 * Make sure the port still exists.
1052 */
1053
1054 if (port >= nd->nd_chan_count) {
1055 err = 1;
1056 break;
1057 }
1058
1059 if (signal_pending(current)) {
1060 err = 1;
1061 break;
1062 }
1063
1064 /*
1065 * If the port is idle (not opened on the server), we have
1066 * no way of draining/flushing/closing the port on that server.
1067 * So break out of loop.
1068 */
1069 if (ch->ch_state == CS_IDLE)
1070 break;
1071
1072 nd->nd_tx_work = 1;
1073
1074 /*
1075 * Exit if the queues for this unit are empty,
1076 * and either the other unit is still open or all
1077 * data has drained.
1078 */
1079
1080 if ((un->un_tty)->ops->chars_in_buffer ?
1081 ((un->un_tty)->ops->chars_in_buffer)(un->un_tty) == 0 : 1) {
1082
1083 /*
1084 * We don't need to wait for a buffer to drain
1085 * if the other unit is open.
1086 */
1087
1088 if (ch->ch_open_count != un->un_open_count)
1089 break;
1090
1091 /*
1092 * The wait is complete when all queues are
1093 * drained, and any break in progress is complete.
1094 */
1095
1096 if (ch->ch_tin == ch->ch_tout &&
1097 ch->ch_s_tin == ch->ch_s_tpos &&
1098 (ch->ch_send & RR_TX_BREAK) == 0) {
1099 break;
1100 }
1101 }
1102
1103 /*
1104 * Flush TX data and exit the wait if NDELAY is set,
1105 * or this is not a DIGI printer, and the close timeout
1106 * expires.
1107 */
1108
1109 if ((file->f_flags & (O_NDELAY | O_NONBLOCK)) ||
1110 ((long)(jiffies - waketime) >= 0 &&
1111 (ch->ch_digi.digi_flags & DIGI_PRINTER) == 0)) {
1112
1113 /*
1114 * If we sent the printer off string, we cannot
1115 * flush our internal buffers, or we might lose
1116 * the offstr.
1117 */
1118 if (!sent_printer_offstr)
1119 dgrp_tty_flush_buffer(tty);
1120
1121 tty_ldisc_flush(tty);
1122 break;
1123 }
1124
1125 /*
1126 * Otherwise take a short nap.
1127 */
1128
1129 ch->ch_flag |= CH_DRAIN;
1130
1131 spin_unlock_irqrestore(&nd->nd_lock, lock_flags);
1132
1133 schedule_timeout_interruptible(1);
1134 s = signal_pending(current);
1135
1136 spin_lock_irqsave(&nd->nd_lock, lock_flags);
1137
1138 if (s) {
1139 /*
1140 * If we had sent the printer off string, we now have
1141 * some problems.
1142 *
1143 * The system won't let us sleep since we got an error
1144 * back from sleep, presumably because the user did
1145 * a ctrl-c...
1146 * But we need to ensure that the offstr gets sent!
1147 * Thus, we have to do something else besides sleeping.
1148 * The plan:
1149 * 1) Make this task uninterruptable.
1150 * 2) Set up a timer to go off in 1 sec.
1151 * 3) Act as tho we just got out of the sleep above.
1152 *
1153 * Thankfully, in the real world, this just
1154 * never happens.
1155 */
1156
1157 if (sent_printer_offstr) {
1158 spin_unlock_irqrestore(&nd->nd_lock,
1159 lock_flags);
1160 drp_my_sleep(ch);
1161 spin_lock_irqsave(&nd->nd_lock, lock_flags);
1162 } else {
1163 err = 1;
1164 break;
1165 }
1166 }
1167
1168 /*
1169 * Restart the wait if any progress is seen.
1170 */
1171
1172 if (ch->ch_s_tpos != tpos) {
1173 tpos = ch->ch_s_tpos;
1174
1175 /* TODO: this gives us timeout problems with nist ?? */
1176 waketime = jiffies + 15 * HZ;
1177 }
1178 }
1179
1180 /*
1181 * Close the line discipline
1182 */
1183
1184 /* this is done in tty_io.c */
1185 /* if ((un->un_tty)->ldisc.close)
1186 * ((un->un_tty)->ldisc.close)(un->un_tty);
1187 */
1188
1189 /* don't do this here */
1190 /* un->un_flag = 0; */
1191
1192 /*
1193 * Flush the receive buffer on terminal unit close only.
1194 */
1195
1196 if (!IS_PRINT(MINOR(tty_devnum(tty))))
1197 ch->ch_rout = ch->ch_rin;
1198
1199
1200 /*
1201 * Don't permit the close to happen until we get any pending
1202 * sync request responses.
1203 * There could be other ports depending upon the response as well.
1204 *
1205 * Also, don't permit the close to happen until any parameter
1206 * changes have been sent out from the state machine as well.
1207 * This is required because of a ditty -a race with -HUPCL
1208 * We MUST make sure all channel parameters have been sent to the
1209 * Portserver before sending a close.
1210 */
1211
1212 if ((err != 1) && (ch->ch_state != CS_IDLE)) {
1213 spin_unlock_irqrestore(&nd->nd_lock, lock_flags);
1214 s = wait_event_interruptible(ch->ch_flag_wait,
1215 ((ch->ch_flag & (CH_WAITING_SYNC | CH_PARAM)) == 0));
1216 spin_lock_irqsave(&nd->nd_lock, lock_flags);
1217 }
1218
1219 /*
1220 * Cleanup the channel if last unit open.
1221 */
1222
1223 if (ch->ch_open_count == 1) {
1224 ch->ch_flag = 0;
1225 ch->ch_category = 0;
1226 ch->ch_send = 0;
1227 ch->ch_expect = 0;
1228 ch->ch_tout = ch->ch_tin;
1229 /* (un->un_tty)->device = 0; */
1230
1231 if (ch->ch_state == CS_READY)
1232 ch->ch_state = CS_SEND_CLOSE;
1233 }
1234
1235 /*
1236 * Send the changes to the server
1237 */
1238 if (ch->ch_state != CS_IDLE) {
1239 ch->ch_flag |= CH_PARAM;
1240 wake_up_interruptible(&ch->ch_flag_wait);
1241 }
1242
1243 nd->nd_tx_work = 1;
1244 nd->nd_tx_ready = 1;
1245
1246unlock:
1247 tty->closing = 0;
1248
1249 if (ch->ch_open_count <= 0)
1250 dev_info(tty->dev,
1251 "%s - unexpected value for ch->ch_open_count: %i\n",
1252 __func__, ch->ch_open_count);
1253 else
1254 ch->ch_open_count--;
1255
1256 if (un->un_open_count <= 0)
1257 dev_info(tty->dev,
1258 "%s - unexpected value for un->un_open_count: %i\n",
1259 __func__, un->un_open_count);
1260 else
1261 un->un_open_count--;
1262
1263 un->un_flag &= ~(UN_NORMAL_ACTIVE | UN_CALLOUT_ACTIVE | UN_CLOSING);
1264 if (waitqueue_active(&un->un_close_wait))
1265 wake_up_interruptible(&un->un_close_wait);
1266
1267 spin_unlock_irqrestore(&nd->nd_lock, lock_flags);
1268
1269 return;
1270
1271}
1272
1273static void drp_wmove(struct ch_struct *ch, int from_user, void *buf, int count)
1274{
1275 int n;
1276 int ret = 0;
1277
1278 ch->ch_nd->nd_tx_work = 1;
1279
1280 n = TBUF_MAX - ch->ch_tin;
1281
1282 if (count >= n) {
1283 if (from_user)
1284 ret = copy_from_user(ch->ch_tbuf + ch->ch_tin,
1285 (void __user *) buf, n);
1286 else
1287 memcpy(ch->ch_tbuf + ch->ch_tin, buf, n);
1288
1289 buf = (char *) buf + n;
1290 count -= n;
1291 ch->ch_tin = 0;
1292 }
1293
1294 if (from_user)
1295 ret = copy_from_user(ch->ch_tbuf + ch->ch_tin,
1296 (void __user *) buf, count);
1297 else
1298 memcpy(ch->ch_tbuf + ch->ch_tin, buf, count);
1299
1300 ch->ch_tin += count;
1301}
1302
1303
1304static int dgrp_calculate_txprint_bounds(struct ch_struct *ch, int space,
1305 int *un_flag)
1306{
1307 clock_t tt;
1308 clock_t mt;
1309 unsigned short tmax = 0;
1310
1311 /*
1312 * If the terminal device is busy, reschedule when
1313 * the terminal device becomes idle.
1314 */
1315
1316 if (ch->ch_tun.un_open_count != 0 &&
1317 ch->ch_tun.un_tty->ops->chars_in_buffer &&
1318 ((ch->ch_tun.un_tty->ops->chars_in_buffer)(ch->ch_tun.un_tty) != 0)) {
1319 *un_flag = UN_PWAIT;
1320 return 0;
1321 }
1322
1323 /*
1324 * Assure that whenever there is printer data in the output
1325 * buffer, there always remains enough space after it to
1326 * turn the printer off.
1327 */
1328 space -= ch->ch_digi.digi_offlen;
1329
1330 if (space <= 0) {
1331 *un_flag = UN_EMPTY;
1332 return 0;
1333 }
1334
1335 /*
1336 * We measure printer CPS speed by incrementing
1337 * ch_cpstime by (HZ / digi_maxcps) for every
1338 * character we output, restricting output so
1339 * that ch_cpstime never exceeds lbolt.
1340 *
1341 * However if output has not been done for some
1342 * time, lbolt will grow to very much larger than
1343 * ch_cpstime, which would allow essentially
1344 * unlimited amounts of output until ch_cpstime
1345 * finally caught up. To avoid this, we adjust
1346 * cps_time when necessary so the difference
1347 * between lbolt and ch_cpstime never results
1348 * in sending more than digi_bufsize characters.
1349 *
1350 * This nicely models a printer with an internal
1351 * buffer of digi_bufsize characters.
1352 *
1353 * Get the time between lbolt and ch->ch_cpstime;
1354 */
1355
1356 tt = jiffies - ch->ch_cpstime;
1357
1358 /*
1359 * Compute the time required to send digi_bufsize
1360 * characters.
1361 */
1362
1363 mt = HZ * ch->ch_digi.digi_bufsize / ch->ch_digi.digi_maxcps;
1364
1365 /*
1366 * Compute the number of characters that can be sent
1367 * without violating the time constraint. If the
1368 * direct calculation of this number is bigger than
1369 * digi_bufsize, limit the number to digi_bufsize,
1370 * and adjust cpstime to match.
1371 */
1372
1373 if ((clock_t)(tt + HZ) > (clock_t)(mt + HZ)) {
1374 tmax = ch->ch_digi.digi_bufsize;
1375 ch->ch_cpstime = jiffies - mt;
1376 } else {
1377 tmax = ch->ch_digi.digi_maxcps * tt / HZ;
1378 }
1379
1380 /*
1381 * If the time constraint now binds, limit the transmit
1382 * count accordingly, and tentatively arrange to be
1383 * rescheduled based on time.
1384 */
1385
1386 if (tmax < space) {
1387 *un_flag = UN_TIME;
1388 space = tmax;
1389 }
1390
1391 /*
1392 * Compute the total number of characters we can
1393 * output before the total number of characters known
1394 * to be in the output queue exceeds digi_maxchar.
1395 */
1396
1397 tmax = (ch->ch_digi.digi_maxchar -
1398 ((ch->ch_tin - ch->ch_tout) & TBUF_MASK) -
1399 ((ch->ch_s_tin - ch->ch_s_tpos) & 0xffff));
1400
1401
1402 /*
1403 * If the digi_maxchar constraint now holds, limit
1404 * the transmit count accordingly, and arrange to
1405 * be rescheduled when the queue becomes empty.
1406 */
1407
1408 if (space > tmax) {
1409 *un_flag = UN_EMPTY;
1410 space = tmax;
1411 }
1412
1413 if (space <= 0)
1414 *un_flag |= UN_EMPTY;
1415
1416 return space;
1417}
1418
1419
1420static int dgrp_tty_write(struct tty_struct *tty,
1421 const unsigned char *buf,
1422 int count)
1423{
1424 struct nd_struct *nd;
1425 struct un_struct *un;
1426 struct ch_struct *ch;
1427 int space;
1428 int n;
1429 int t;
1430 int sendcount;
1431 int un_flag;
1432 ulong lock_flags;
1433
1434 if (tty == NULL)
1435 return 0;
1436
1437 un = tty->driver_data;
1438 if (!un)
1439 return 0;
1440
1441 ch = un->un_ch;
1442 if (!ch)
1443 return 0;
1444
1445 nd = ch->ch_nd;
1446 if (!nd)
1447 return 0;
1448
1449 /*
1450 * Ignore the request if the channel is not ready.
1451 */
1452 if (ch->ch_state != CS_READY)
1453 return 0;
1454
1455 spin_lock_irqsave(&dgrp_poll_data.poll_lock, lock_flags);
1456
1457 /*
1458 * Ignore the request if output is blocked.
1459 */
1460 if ((un->un_flag & (UN_EMPTY | UN_LOW | UN_TIME | UN_PWAIT)) != 0) {
1461 count = 0;
1462 goto out;
1463 }
1464
1465 /*
1466 * Also ignore the request if DPA has this port open,
1467 * and is flow controlled on reading more data.
1468 */
1469 if (nd->nd_dpa_debug && nd->nd_dpa_flag & DPA_WAIT_SPACE &&
1470 nd->nd_dpa_port == MINOR(tty_devnum(ch->ch_tun.un_tty))) {
1471 count = 0;
1472 goto out;
1473 }
1474
1475 /*
1476 * Limit amount we will write to the amount of space
1477 * available in the channel buffer.
1478 */
1479 sendcount = 0;
1480
1481 space = (ch->ch_tout - ch->ch_tin - 1) & TBUF_MASK;
1482
1483 /*
1484 * Handle the printer device.
1485 */
1486
1487 un_flag = UN_LOW;
1488
1489 if (IS_PRINT(MINOR(tty_devnum(tty)))) {
1490 clock_t tt;
1491 clock_t mt;
1492 unsigned short tmax = 0;
1493
1494 /*
1495 * If the terminal device is busy, reschedule when
1496 * the terminal device becomes idle.
1497 */
1498
1499 if (ch->ch_tun.un_open_count != 0 &&
1500 ((ch->ch_tun.un_tty->ops->chars_in_buffer)(ch->ch_tun.un_tty) != 0)) {
1501 un->un_flag |= UN_PWAIT;
1502 count = 0;
1503 goto out;
1504 }
1505
1506 /*
1507 * Assure that whenever there is printer data in the output
1508 * buffer, there always remains enough space after it to
1509 * turn the printer off.
1510 */
1511 space -= ch->ch_digi.digi_offlen;
1512
1513 /*
1514 * Output the printer on string.
1515 */
1516
1517 if ((ch->ch_flag & CH_PRON) == 0) {
1518 space -= ch->ch_digi.digi_onlen;
1519
1520 if (space < 0) {
1521 un->un_flag |= UN_EMPTY;
1522 (ch->ch_nd)->nd_tx_work = 1;
1523 count = 0;
1524 goto out;
1525 }
1526
1527 drp_wmove(ch, 0, ch->ch_digi.digi_onstr,
1528 ch->ch_digi.digi_onlen);
1529
1530 ch->ch_flag |= CH_PRON;
1531 }
1532
1533 /*
1534 * We measure printer CPS speed by incrementing
1535 * ch_cpstime by (HZ / digi_maxcps) for every
1536 * character we output, restricting output so
1537 * that ch_cpstime never exceeds lbolt.
1538 *
1539 * However if output has not been done for some
1540 * time, lbolt will grow to very much larger than
1541 * ch_cpstime, which would allow essentially
1542 * unlimited amounts of output until ch_cpstime
1543 * finally caught up. To avoid this, we adjust
1544 * cps_time when necessary so the difference
1545 * between lbolt and ch_cpstime never results
1546 * in sending more than digi_bufsize characters.
1547 *
1548 * This nicely models a printer with an internal
1549 * buffer of digi_bufsize characters.
1550 *
1551 * Get the time between lbolt and ch->ch_cpstime;
1552 */
1553
1554 tt = jiffies - ch->ch_cpstime;
1555
1556 /*
1557 * Compute the time required to send digi_bufsize
1558 * characters.
1559 */
1560
1561 mt = HZ * ch->ch_digi.digi_bufsize / ch->ch_digi.digi_maxcps;
1562
1563 /*
1564 * Compute the number of characters that can be sent
1565 * without violating the time constraint. If the
1566 * direct calculation of this number is bigger than
1567 * digi_bufsize, limit the number to digi_bufsize,
1568 * and adjust cpstime to match.
1569 */
1570
1571 if ((clock_t)(tt + HZ) > (clock_t)(mt + HZ)) {
1572 tmax = ch->ch_digi.digi_bufsize;
1573 ch->ch_cpstime = jiffies - mt;
1574 } else {
1575 tmax = ch->ch_digi.digi_maxcps * tt / HZ;
1576 }
1577
1578 /*
1579 * If the time constraint now binds, limit the transmit
1580 * count accordingly, and tentatively arrange to be
1581 * rescheduled based on time.
1582 */
1583
1584 if (tmax < space) {
1585 space = tmax;
1586 un_flag = UN_TIME;
1587 }
1588
1589 /*
1590 * Compute the total number of characters we can
1591 * output before the total number of characters known
1592 * to be in the output queue exceeds digi_maxchar.
1593 */
1594
1595 tmax = (ch->ch_digi.digi_maxchar -
1596 ((ch->ch_tin - ch->ch_tout) & TBUF_MASK) -
1597 ((ch->ch_s_tin - ch->ch_s_tpos) & 0xffff));
1598
1599
1600 /*
1601 * If the digi_maxchar constraint now holds, limit
1602 * the transmit count accordingly, and arrange to
1603 * be rescheduled when the queue becomes empty.
1604 */
1605
1606 if (space > tmax) {
1607 space = tmax;
1608 un_flag = UN_EMPTY;
1609 }
1610
1611 }
1612 /*
1613 * Handle the terminal device.
1614 */
1615 else {
1616
1617 /*
1618 * If the printer device is on, turn it off.
1619 */
1620
1621 if ((ch->ch_flag & CH_PRON) != 0) {
1622
1623 space -= ch->ch_digi.digi_offlen;
1624
1625 drp_wmove(ch, 0, ch->ch_digi.digi_offstr,
1626 ch->ch_digi.digi_offlen);
1627
1628 ch->ch_flag &= ~CH_PRON;
1629 }
1630 }
1631
1632 /*
1633 * If space is 0 and its because the ch->tbuf
1634 * is full, then Linux will handle a callback when queue
1635 * space becomes available.
1636 * tty_write returns count = 0
1637 */
1638
1639 if (space <= 0) {
1640 /* the linux tty_io.c handles this if we return 0 */
1641 /* if (fp->flags & O_NONBLOCK) return -EAGAIN; */
1642
1643 un->un_flag |= UN_EMPTY;
1644 (ch->ch_nd)->nd_tx_work = 1;
1645 count = 0;
1646 goto out;
1647 }
1648
1649 count = min(count, space);
1650
1651 if (count > 0) {
1652
1653 un->un_tbusy++;
1654
1655 /*
1656 * Copy the buffer contents to the ch_tbuf
1657 * being careful to wrap around the circular queue
1658 */
1659
1660 t = TBUF_MAX - ch->ch_tin;
1661 n = count;
1662
1663 if (n >= t) {
1664 memcpy(ch->ch_tbuf + ch->ch_tin, buf, t);
1665 if (nd->nd_dpa_debug && nd->nd_dpa_port == PORT_NUM(MINOR(tty_devnum(un->un_tty))))
1666 dgrp_dpa_data(nd, 0, (char *) buf, t);
1667 buf += t;
1668 n -= t;
1669 ch->ch_tin = 0;
1670 sendcount += n;
1671 }
1672
1673 memcpy(ch->ch_tbuf + ch->ch_tin, buf, n);
1674 if (nd->nd_dpa_debug && nd->nd_dpa_port == PORT_NUM(MINOR(tty_devnum(un->un_tty))))
1675 dgrp_dpa_data(nd, 0, (char *) buf, n);
1676 buf += n;
1677 ch->ch_tin += n;
1678 sendcount += n;
1679
1680 un->un_tbusy--;
1681 (ch->ch_nd)->nd_tx_work = 1;
1682 if (ch->ch_edelay != DGRP_RTIME) {
1683 (ch->ch_nd)->nd_tx_ready = 1;
1684 wake_up_interruptible(&nd->nd_tx_waitq);
1685 }
1686 }
1687
1688 ch->ch_txcount += count;
1689
1690 if (IS_PRINT(MINOR(tty_devnum(tty)))) {
1691
1692 /*
1693 * Adjust ch_cpstime to account
1694 * for the characters just output.
1695 */
1696
1697 if (sendcount > 0) {
1698 int cc = HZ * sendcount + ch->ch_cpsrem;
1699
1700 ch->ch_cpstime += cc / ch->ch_digi.digi_maxcps;
1701 ch->ch_cpsrem = cc % ch->ch_digi.digi_maxcps;
1702 }
1703
1704 /*
1705 * If we are now waiting on time, schedule ourself
1706 * back when we'll be able to send a block of
1707 * digi_maxchar characters.
1708 */
1709
1710 if ((un_flag & UN_TIME) != 0) {
1711 ch->ch_waketime = (ch->ch_cpstime +
1712 (ch->ch_digi.digi_maxchar * HZ /
1713 ch->ch_digi.digi_maxcps));
1714 }
1715 }
1716
1717 /*
1718 * If the printer unit is waiting for completion
1719 * of terminal output, get him going again.
1720 */
1721
1722 if ((ch->ch_pun.un_flag & UN_PWAIT) != 0)
1723 (ch->ch_nd)->nd_tx_work = 1;
1724
1725out:
1726 spin_unlock_irqrestore(&dgrp_poll_data.poll_lock, lock_flags);
1727
1728 return count;
1729}
1730
1731
1732/*
1733 * Put a character into ch->ch_buf
1734 *
1735 * - used by the line discipline for OPOST processing
1736 */
1737
1738static int dgrp_tty_put_char(struct tty_struct *tty, unsigned char new_char)
1739{
1740 struct un_struct *un;
1741 struct ch_struct *ch;
1742 ulong lock_flags;
1743 int space;
1744 int retval = 0;
1745
1746 if (tty == NULL)
1747 return 0;
1748
1749 un = tty->driver_data;
1750 if (!un)
1751 return 0;
1752
1753 ch = un->un_ch;
1754 if (!ch)
1755 return 0;
1756
1757 if (ch->ch_state != CS_READY)
1758 return 0;
1759
1760 spin_lock_irqsave(&dgrp_poll_data.poll_lock, lock_flags);
1761
1762
1763 /*
1764 * If space is 0 and its because the ch->tbuf
1765 * Warn and dump the character, there isn't anything else
1766 * we can do about it. David_Fries@digi.com
1767 */
1768
1769 space = (ch->ch_tout - ch->ch_tin - 1) & TBUF_MASK;
1770
1771 un->un_tbusy++;
1772
1773 /*
1774 * Output the printer on string if device is TXPrint.
1775 */
1776 if (IS_PRINT(MINOR(tty_devnum(tty))) && (ch->ch_flag & CH_PRON) == 0) {
1777 if (space < ch->ch_digi.digi_onlen) {
1778 un->un_tbusy--;
1779 goto out;
1780 }
1781 space -= ch->ch_digi.digi_onlen;
1782 drp_wmove(ch, 0, ch->ch_digi.digi_onstr,
1783 ch->ch_digi.digi_onlen);
1784 ch->ch_flag |= CH_PRON;
1785 }
1786
1787 /*
1788 * Output the printer off string if device is NOT TXPrint.
1789 */
1790
1791 if (!IS_PRINT(MINOR(tty_devnum(tty))) &&
1792 ((ch->ch_flag & CH_PRON) != 0)) {
1793 if (space < ch->ch_digi.digi_offlen) {
1794 un->un_tbusy--;
1795 goto out;
1796 }
1797
1798 space -= ch->ch_digi.digi_offlen;
1799 drp_wmove(ch, 0, ch->ch_digi.digi_offstr,
1800 ch->ch_digi.digi_offlen);
1801 ch->ch_flag &= ~CH_PRON;
1802 }
1803
1804 if (!space) {
1805 un->un_tbusy--;
1806 goto out;
1807 }
1808
1809 /*
1810 * Copy the character to the ch_tbuf being
1811 * careful to wrap around the circular queue
1812 */
1813 ch->ch_tbuf[ch->ch_tin] = new_char;
1814 ch->ch_tin = (1 + ch->ch_tin) & TBUF_MASK;
1815
1816 if (IS_PRINT(MINOR(tty_devnum(tty)))) {
1817
1818 /*
1819 * Adjust ch_cpstime to account
1820 * for the character just output.
1821 */
1822
1823 int cc = HZ + ch->ch_cpsrem;
1824
1825 ch->ch_cpstime += cc / ch->ch_digi.digi_maxcps;
1826 ch->ch_cpsrem = cc % ch->ch_digi.digi_maxcps;
1827
1828 /*
1829 * If we are now waiting on time, schedule ourself
1830 * back when we'll be able to send a block of
1831 * digi_maxchar characters.
1832 */
1833
1834 ch->ch_waketime = (ch->ch_cpstime +
1835 (ch->ch_digi.digi_maxchar * HZ /
1836 ch->ch_digi.digi_maxcps));
1837 }
1838
1839
1840 un->un_tbusy--;
1841 (ch->ch_nd)->nd_tx_work = 1;
1842
1843 retval = 1;
1844out:
1845 spin_unlock_irqrestore(&dgrp_poll_data.poll_lock, lock_flags);
1846 return retval;
1847}
1848
1849
1850
1851/*
1852 * Flush TX buffer (make in == out)
1853 *
1854 * check tty_ioctl.c -- this is called after TCOFLUSH
1855 */
1856static void dgrp_tty_flush_buffer(struct tty_struct *tty)
1857{
1858 struct un_struct *un;
1859 struct ch_struct *ch;
1860
1861 if (!tty)
1862 return;
1863 un = tty->driver_data;
1864 if (!un)
1865 return;
1866
1867 ch = un->un_ch;
1868 if (!ch)
1869 return;
1870
1871 ch->ch_tout = ch->ch_tin;
1872 /* do NOT do this here! */
1873 /* ch->ch_s_tpos = ch->ch_s_tin = 0; */
1874
1875 /* send the flush output command now */
1876 ch->ch_send |= RR_TX_FLUSH;
1877 (ch->ch_nd)->nd_tx_ready = 1;
1878 (ch->ch_nd)->nd_tx_work = 1;
1879 wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq);
1880
1881 if (waitqueue_active(&tty->write_wait))
1882 wake_up_interruptible(&tty->write_wait);
1883
1884 tty_wakeup(tty);
1885
1886}
1887
1888/*
1889 * Return space available in Tx buffer
1890 * count = ( ch->ch_tout - ch->ch_tin ) mod (TBUF_MAX - 1)
1891 */
1892static int dgrp_tty_write_room(struct tty_struct *tty)
1893{
1894 struct un_struct *un;
1895 struct ch_struct *ch;
1896 int count;
1897
1898 if (!tty)
1899 return 0;
1900
1901 un = tty->driver_data;
1902 if (!un)
1903 return 0;
1904
1905 ch = un->un_ch;
1906 if (!ch)
1907 return 0;
1908
1909 count = (ch->ch_tout - ch->ch_tin - 1) & TBUF_MASK;
1910
1911 /* We *MUST* check this, and return 0 if the Printer Unit cannot
1912 * take any more data within its time constraints... If we don't
1913 * return 0 and the printer has hit it time constraint, the ld will
1914 * call us back doing a put_char, which cannot be rejected!!!
1915 */
1916 if (IS_PRINT(MINOR(tty_devnum(tty)))) {
1917 int un_flag = 0;
1918 count = dgrp_calculate_txprint_bounds(ch, count, &un_flag);
1919 if (count <= 0)
1920 count = 0;
1921
1922 ch->ch_pun.un_flag |= un_flag;
1923 (ch->ch_nd)->nd_tx_work = 1;
1924 }
1925
1926 return count;
1927}
1928
1929/*
1930 * Return number of characters that have not been transmitted yet.
1931 * chars_in_buffer = ( ch->ch_tin - ch->ch_tout ) mod (TBUF_MAX - 1)
1932 * + ( ch->ch_s_tin - ch->ch_s_tout ) mod (0xffff)
1933 * = number of characters "in transit"
1934 *
1935 * Remember that sequence number math is always with a sixteen bit
1936 * mask, not the TBUF_MASK.
1937 */
1938
1939static int dgrp_tty_chars_in_buffer(struct tty_struct *tty)
1940{
1941 struct un_struct *un;
1942 struct ch_struct *ch;
1943 int count;
1944 int count1;
1945
1946 if (!tty)
1947 return 0;
1948
1949 un = tty->driver_data;
1950 if (!un)
1951 return 0;
1952
1953 ch = un->un_ch;
1954 if (!ch)
1955 return 0;
1956
1957 count1 = count = (ch->ch_tin - ch->ch_tout) & TBUF_MASK;
1958 count += (ch->ch_s_tin - ch->ch_s_tpos) & 0xffff;
1959 /* one for tbuf, one for the PS */
1960
1961 /*
1962 * If we are busy transmitting add 1
1963 */
1964 count += un->un_tbusy;
1965
1966 return count;
1967}
1968
1969
1970/*****************************************************************************
1971 *
1972 * Helper applications for dgrp_tty_ioctl()
1973 *
1974 *****************************************************************************
1975 */
1976
1977
1978/**
1979 * ch_to_tty_flags() -- convert channel flags to termio flags
1980 * @ch_flag: Digi channel flags
1981 * @flagtype: type of ch_flag (iflag, oflag or cflag)
1982 *
1983 * take the channel flags of the specified type and return the
1984 * corresponding termio flag
1985 */
1986static tcflag_t ch_to_tty_flags(ushort ch_flag, char flagtype)
1987{
1988 tcflag_t retval = 0;
1989
1990 switch (flagtype) {
1991 case 'i':
1992 retval = ((ch_flag & IF_IGNBRK) ? IGNBRK : 0)
1993 | ((ch_flag & IF_BRKINT) ? BRKINT : 0)
1994 | ((ch_flag & IF_IGNPAR) ? IGNPAR : 0)
1995 | ((ch_flag & IF_PARMRK) ? PARMRK : 0)
1996 | ((ch_flag & IF_INPCK) ? INPCK : 0)
1997 | ((ch_flag & IF_ISTRIP) ? ISTRIP : 0)
1998 | ((ch_flag & IF_IXON) ? IXON : 0)
1999 | ((ch_flag & IF_IXANY) ? IXANY : 0)
2000 | ((ch_flag & IF_IXOFF) ? IXOFF : 0);
2001 break;
2002
2003 case 'o':
2004 retval = ((ch_flag & OF_OLCUC) ? OLCUC : 0)
2005 | ((ch_flag & OF_ONLCR) ? ONLCR : 0)
2006 | ((ch_flag & OF_OCRNL) ? OCRNL : 0)
2007 | ((ch_flag & OF_ONOCR) ? ONOCR : 0)
2008 | ((ch_flag & OF_ONLRET) ? ONLRET : 0)
2009 /* | ((ch_flag & OF_OTAB3) ? OFILL : 0) */
2010 | ((ch_flag & OF_TABDLY) ? TABDLY : 0);
2011 break;
2012
2013 case 'c':
2014 retval = ((ch_flag & CF_CSTOPB) ? CSTOPB : 0)
2015 | ((ch_flag & CF_CREAD) ? CREAD : 0)
2016 | ((ch_flag & CF_PARENB) ? PARENB : 0)
2017 | ((ch_flag & CF_PARODD) ? PARODD : 0)
2018 | ((ch_flag & CF_HUPCL) ? HUPCL : 0);
2019
2020 switch (ch_flag & CF_CSIZE) {
2021 case CF_CS5:
2022 retval |= CS5;
2023 break;
2024 case CF_CS6:
2025 retval |= CS6;
2026 break;
2027 case CF_CS7:
2028 retval |= CS7;
2029 break;
2030 case CF_CS8:
2031 retval |= CS8;
2032 break;
2033 default:
2034 retval |= CS8;
2035 break;
2036 }
2037 break;
2038 case 'x':
2039 break;
2040 case 'l':
2041 break;
2042 default:
2043 return 0;
2044 }
2045
2046 return retval;
2047}
2048
2049
2050/**
2051 * tty_to_ch_flags() -- convert termio flags to digi channel flags
2052 * @tty: pointer to a TTY structure holding flag to be converted
2053 * @flagtype: identifies which flag (iflags, oflags, or cflags) should
2054 * be converted
2055 *
2056 * take the termio flag of the specified type and return the
2057 * corresponding Digi version of the flags
2058 */
2059static ushort tty_to_ch_flags(struct tty_struct *tty, char flagtype)
2060{
2061 ushort retval = 0;
2062 tcflag_t tflag = 0;
2063
2064 switch (flagtype) {
2065 case 'i':
2066 tflag = tty->termios.c_iflag;
2067 retval = (I_IGNBRK(tty) ? IF_IGNBRK : 0)
2068 | (I_BRKINT(tty) ? IF_BRKINT : 0)
2069 | (I_IGNPAR(tty) ? IF_IGNPAR : 0)
2070 | (I_PARMRK(tty) ? IF_PARMRK : 0)
2071 | (I_INPCK(tty) ? IF_INPCK : 0)
2072 | (I_ISTRIP(tty) ? IF_ISTRIP : 0)
2073 | (I_IXON(tty) ? IF_IXON : 0)
2074 | (I_IXANY(tty) ? IF_IXANY : 0)
2075 | (I_IXOFF(tty) ? IF_IXOFF : 0);
2076 break;
2077 case 'o':
2078 tflag = tty->termios.c_oflag;
2079 /*
2080 * If OPOST is set, then do the post processing in the
2081 * firmware by setting all the processing flags on.
2082 * If ~OPOST, then make sure we are not doing any
2083 * output processing!!
2084 */
2085 if (!O_OPOST(tty))
2086 retval = 0;
2087 else
2088 retval = (O_OLCUC(tty) ? OF_OLCUC : 0)
2089 | (O_ONLCR(tty) ? OF_ONLCR : 0)
2090 | (O_OCRNL(tty) ? OF_OCRNL : 0)
2091 | (O_ONOCR(tty) ? OF_ONOCR : 0)
2092 | (O_ONLRET(tty) ? OF_ONLRET : 0)
2093 /* | (O_OFILL(tty) ? OF_TAB3 : 0) */
2094 | (O_TABDLY(tty) ? OF_TABDLY : 0);
2095 break;
2096 case 'c':
2097 tflag = tty->termios.c_cflag;
2098 retval = (C_CSTOPB(tty) ? CF_CSTOPB : 0)
2099 | (C_CREAD(tty) ? CF_CREAD : 0)
2100 | (C_PARENB(tty) ? CF_PARENB : 0)
2101 | (C_PARODD(tty) ? CF_PARODD : 0)
2102 | (C_HUPCL(tty) ? CF_HUPCL : 0);
2103 switch (C_CSIZE(tty)) {
2104 case CS8:
2105 retval |= CF_CS8;
2106 break;
2107 case CS7:
2108 retval |= CF_CS7;
2109 break;
2110 case CS6:
2111 retval |= CF_CS6;
2112 break;
2113 case CS5:
2114 retval |= CF_CS5;
2115 break;
2116 default:
2117 retval |= CF_CS8;
2118 break;
2119 }
2120 break;
2121 case 'x':
2122 break;
2123 case 'l':
2124 break;
2125 default:
2126 return 0;
2127 }
2128
2129 return retval;
2130}
2131
2132
2133static int dgrp_tty_send_break(struct tty_struct *tty, int msec)
2134{
2135 struct un_struct *un;
2136 struct ch_struct *ch;
2137 int ret = -EIO;
2138
2139 if (!tty)
2140 return ret;
2141
2142 un = tty->driver_data;
2143 if (!un)
2144 return ret;
2145
2146 ch = un->un_ch;
2147 if (!ch)
2148 return ret;
2149
2150 dgrp_send_break(ch, msec);
2151 return 0;
2152}
2153
2154
2155/*
2156 * This routine sends a break character out the serial port.
2157 *
2158 * duration is in 1/1000's of a second
2159 */
2160static int dgrp_send_break(struct ch_struct *ch, int msec)
2161{
2162 ulong x;
2163
2164 wait_event_interruptible(ch->ch_flag_wait,
2165 ((ch->ch_flag & CH_TX_BREAK) == 0));
2166 ch->ch_break_time += max(msec, 250);
2167 ch->ch_send |= RR_TX_BREAK;
2168 ch->ch_flag |= CH_TX_BREAK;
2169 (ch->ch_nd)->nd_tx_work = 1;
2170
2171 x = (msec * HZ) / 1000;
2172 wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq);
2173
2174 return 0;
2175}
2176
2177
2178/*
2179 * Return modem signals to ld.
2180 */
2181static int dgrp_tty_tiocmget(struct tty_struct *tty)
2182{
2183 unsigned int mlast;
2184 struct un_struct *un = tty->driver_data;
2185 struct ch_struct *ch;
2186
2187 if (!un)
2188 return -ENODEV;
2189
2190 ch = un->un_ch;
2191 if (!ch)
2192 return -ENODEV;
2193
2194 mlast = ((ch->ch_s_mlast & ~(DM_RTS | DM_DTR)) |
2195 (ch->ch_mout & (DM_RTS | DM_DTR)));
2196
2197 /* defined in /usr/include/asm/termios.h */
2198 mlast = ((mlast & DM_RTS) ? TIOCM_RTS : 0)
2199 | ((mlast & DM_DTR) ? TIOCM_DTR : 0)
2200 | ((mlast & DM_CD) ? TIOCM_CAR : 0)
2201 | ((mlast & DM_RI) ? TIOCM_RNG : 0)
2202 | ((mlast & DM_DSR) ? TIOCM_DSR : 0)
2203 | ((mlast & DM_CTS) ? TIOCM_CTS : 0);
2204
2205 return mlast;
2206}
2207
2208
2209/*
2210 * Set modem lines
2211 */
2212static int dgrp_tty_tiocmset(struct tty_struct *tty,
2213 unsigned int set, unsigned int clear)
2214{
2215 ulong lock_flags;
2216 struct un_struct *un = tty->driver_data;
2217 struct ch_struct *ch;
2218
2219 if (!un)
2220 return -ENODEV;
2221
2222 ch = un->un_ch;
2223 if (!ch)
2224 return -ENODEV;
2225
2226 if (set & TIOCM_RTS)
2227 ch->ch_mout |= DM_RTS;
2228
2229 if (set & TIOCM_DTR)
2230 ch->ch_mout |= DM_DTR;
2231
2232 if (clear & TIOCM_RTS)
2233 ch->ch_mout &= ~(DM_RTS);
2234
2235 if (clear & TIOCM_DTR)
2236 ch->ch_mout &= ~(DM_DTR);
2237
2238 spin_lock_irqsave(&(ch->ch_nd)->nd_lock, lock_flags);
2239 ch->ch_flag |= CH_PARAM;
2240 (ch->ch_nd)->nd_tx_work = 1;
2241 wake_up_interruptible(&ch->ch_flag_wait);
2242
2243 spin_unlock_irqrestore(&(ch->ch_nd)->nd_lock, lock_flags);
2244
2245 return 0;
2246}
2247
2248
2249
2250/*
2251 * Get current modem status
2252 */
2253static int get_modem_info(struct ch_struct *ch, unsigned int *value)
2254{
2255 unsigned int mlast;
2256
2257 mlast = ((ch->ch_s_mlast & ~(DM_RTS | DM_DTR)) |
2258 (ch->ch_mout & (DM_RTS | DM_DTR)));
2259
2260 /* defined in /usr/include/asm/termios.h */
2261 mlast = ((mlast & DM_RTS) ? TIOCM_RTS : 0)
2262 | ((mlast & DM_DTR) ? TIOCM_DTR : 0)
2263 | ((mlast & DM_CD) ? TIOCM_CAR : 0)
2264 | ((mlast & DM_RI) ? TIOCM_RNG : 0)
2265 | ((mlast & DM_DSR) ? TIOCM_DSR : 0)
2266 | ((mlast & DM_CTS) ? TIOCM_CTS : 0);
2267 put_user(mlast, (unsigned int __user *) value);
2268
2269 return 0;
2270}
2271
2272/*
2273 * Set modem lines
2274 */
2275static int set_modem_info(struct ch_struct *ch, unsigned int command,
2276 unsigned int *value)
2277{
2278 int error;
2279 unsigned int arg;
2280 int mval = 0;
2281 ulong lock_flags;
2282
2283 error = access_ok(VERIFY_READ, (void __user *) value, sizeof(int));
2284 if (error == 0)
2285 return -EFAULT;
2286
2287 get_user(arg, (unsigned int __user *) value);
2288 mval |= ((arg & TIOCM_RTS) ? DM_RTS : 0)
2289 | ((arg & TIOCM_DTR) ? DM_DTR : 0);
2290
2291 switch (command) {
2292 case TIOCMBIS: /* set flags */
2293 ch->ch_mout |= mval;
2294 break;
2295 case TIOCMBIC: /* clear flags */
2296 ch->ch_mout &= ~mval;
2297 break;
2298 case TIOCMSET:
2299 ch->ch_mout = mval;
2300 break;
2301 default:
2302 return -EINVAL;
2303 }
2304
2305 spin_lock_irqsave(&(ch->ch_nd)->nd_lock, lock_flags);
2306
2307 ch->ch_flag |= CH_PARAM;
2308 (ch->ch_nd)->nd_tx_work = 1;
2309 wake_up_interruptible(&ch->ch_flag_wait);
2310
2311 spin_unlock_irqrestore(&(ch->ch_nd)->nd_lock, lock_flags);
2312
2313 return 0;
2314}
2315
2316
2317/*
2318 * Assign the custom baud rate to the channel structure
2319 */
2320static void dgrp_set_custom_speed(struct ch_struct *ch, int newrate)
2321{
2322 int testdiv;
2323 int testrate_high;
2324 int testrate_low;
2325
2326 int deltahigh, deltalow;
2327
2328 if (newrate < 0)
2329 newrate = 0;
2330
2331 /*
2332 * Since the divisor is stored in a 16-bit integer, we make sure
2333 * we don't allow any rates smaller than a 16-bit integer would allow.
2334 * And of course, rates above the dividend won't fly.
2335 */
2336 if (newrate && newrate < ((PORTSERVER_DIVIDEND / 0xFFFF) + 1))
2337 newrate = ((PORTSERVER_DIVIDEND / 0xFFFF) + 1);
2338 if (newrate && newrate > PORTSERVER_DIVIDEND)
2339 newrate = PORTSERVER_DIVIDEND;
2340
2341 while (newrate > 0) {
2342 testdiv = PORTSERVER_DIVIDEND / newrate;
2343
2344 /*
2345 * If we try to figure out what rate the PortServer would use
2346 * with the test divisor, it will be either equal or higher
2347 * than the requested baud rate. If we then determine the
2348 * rate with a divisor one higher, we will get the next lower
2349 * supported rate below the requested.
2350 */
2351 testrate_high = PORTSERVER_DIVIDEND / testdiv;
2352 testrate_low = PORTSERVER_DIVIDEND / (testdiv + 1);
2353
2354 /*
2355 * If the rate for the requested divisor is correct, just
2356 * use it and be done.
2357 */
2358 if (testrate_high == newrate)
2359 break;
2360
2361 /*
2362 * Otherwise, pick the rate that is closer (i.e. whichever rate
2363 * has a smaller delta).
2364 */
2365 deltahigh = testrate_high - newrate;
2366 deltalow = newrate - testrate_low;
2367
2368 if (deltahigh < deltalow)
2369 newrate = testrate_high;
2370 else
2371 newrate = testrate_low;
2372
2373 break;
2374 }
2375
2376 ch->ch_custom_speed = newrate;
2377
2378 drp_param(ch);
2379
2380 return;
2381}
2382
2383
2384/*
2385 # dgrp_tty_digiseta()
2386 *
2387 * Ioctl to set the information from ditty.
2388 *
2389 * NOTE: DIGI_IXON, DSRPACE, DCDPACE, and DTRPACE are unsupported. JAR 990922
2390 */
2391static int dgrp_tty_digiseta(struct tty_struct *tty,
2392 struct digi_struct *new_info)
2393{
2394 struct un_struct *un = tty->driver_data;
2395 struct ch_struct *ch;
2396
2397 if (!un)
2398 return -ENODEV;
2399
2400 ch = un->un_ch;
2401 if (!ch)
2402 return -ENODEV;
2403
2404 if (copy_from_user(&ch->ch_digi, (void __user *) new_info,
2405 sizeof(struct digi_struct)))
2406 return -EFAULT;
2407
2408 if ((ch->ch_digi.digi_flags & RTSPACE) ||
2409 (ch->ch_digi.digi_flags & CTSPACE))
2410 tty->termios.c_cflag |= CRTSCTS;
2411 else
2412 tty->termios.c_cflag &= ~CRTSCTS;
2413
2414 if (ch->ch_digi.digi_maxcps < 1)
2415 ch->ch_digi.digi_maxcps = 1;
2416
2417 if (ch->ch_digi.digi_maxcps > 10000)
2418 ch->ch_digi.digi_maxcps = 10000;
2419
2420 if (ch->ch_digi.digi_bufsize < 10)
2421 ch->ch_digi.digi_bufsize = 10;
2422
2423 if (ch->ch_digi.digi_maxchar < 1)
2424 ch->ch_digi.digi_maxchar = 1;
2425
2426 if (ch->ch_digi.digi_maxchar > ch->ch_digi.digi_bufsize)
2427 ch->ch_digi.digi_maxchar = ch->ch_digi.digi_bufsize;
2428
2429 if (ch->ch_digi.digi_onlen > DIGI_PLEN)
2430 ch->ch_digi.digi_onlen = DIGI_PLEN;
2431
2432 if (ch->ch_digi.digi_offlen > DIGI_PLEN)
2433 ch->ch_digi.digi_offlen = DIGI_PLEN;
2434
2435 /* make the changes now */
2436 drp_param(ch);
2437
2438 return 0;
2439}
2440
2441
2442
2443/*
2444 * dgrp_tty_digigetedelay()
2445 *
2446 * Ioctl to get the current edelay setting.
2447 *
2448 *
2449 *
2450 */
2451static int dgrp_tty_digigetedelay(struct tty_struct *tty, int *retinfo)
2452{
2453 struct un_struct *un;
2454 struct ch_struct *ch;
2455 int tmp;
2456
2457 if (!retinfo)
2458 return -EFAULT;
2459
2460 if (!tty || tty->magic != TTY_MAGIC)
2461 return -EFAULT;
2462
2463 un = tty->driver_data;
2464
2465 if (!un)
2466 return -ENODEV;
2467
2468 ch = un->un_ch;
2469 if (!ch)
2470 return -ENODEV;
2471
2472 tmp = ch->ch_edelay;
2473
2474 if (copy_to_user((void __user *) retinfo, &tmp, sizeof(*retinfo)))
2475 return -EFAULT;
2476
2477 return 0;
2478}
2479
2480
2481/*
2482 * dgrp_tty_digisetedelay()
2483 *
2484 * Ioctl to set the EDELAY setting
2485 *
2486 */
2487static int dgrp_tty_digisetedelay(struct tty_struct *tty, int *new_info)
2488{
2489 struct un_struct *un;
2490 struct ch_struct *ch;
2491 int new_digi;
2492
2493 if (!tty || tty->magic != TTY_MAGIC)
2494 return -EFAULT;
2495
2496 un = tty->driver_data;
2497
2498 if (!un)
2499 return -ENODEV;
2500
2501 ch = un->un_ch;
2502 if (!ch)
2503 return -ENODEV;
2504
2505 if (copy_from_user(&new_digi, (void __user *)new_info, sizeof(int)))
2506 return -EFAULT;
2507
2508 ch->ch_edelay = new_digi;
2509
2510 /* make the changes now */
2511 drp_param(ch);
2512
2513 return 0;
2514}
2515
2516
2517/*
2518 * The usual assortment of ioctl's
2519 *
2520 * note: use tty_check_change to make sure that we are not
2521 * changing the state of a terminal when we are not a process
2522 * in the forground. See tty_io.c
2523 * rc = tty_check_change(tty);
2524 * if (rc) return rc;
2525 */
2526static int dgrp_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
2527 unsigned long arg)
2528{
2529 struct un_struct *un;
2530 struct ch_struct *ch;
2531 int rc;
2532 struct digiflow_struct dflow;
2533
2534 if (!tty)
2535 return -ENODEV;
2536
2537 un = tty->driver_data;
2538 if (!un)
2539 return -ENODEV;
2540
2541 ch = un->un_ch;
2542 if (!ch)
2543 return -ENODEV;
2544
2545 switch (cmd) {
2546
2547 /*
2548 * Here are all the standard ioctl's that we MUST implement
2549 */
2550
2551 case TCSBRK:
2552 /*
2553 * TCSBRK is SVID version: non-zero arg --> no break
2554 * this behaviour is exploited by tcdrain().
2555 *
2556 * According to POSIX.1 spec (7.2.2.1.2) breaks should be
2557 * between 0.25 and 0.5 seconds
2558 */
2559
2560 rc = tty_check_change(tty);
2561 if (rc)
2562 return rc;
2563 tty_wait_until_sent(tty, 0);
2564
2565 if (!arg)
2566 rc = dgrp_send_break(ch, 250); /* 1/4 second */
2567
2568 if (dgrp_tty_chars_in_buffer(tty) != 0)
2569 return -EINTR;
2570
2571 return 0;
2572
2573 case TCSBRKP:
2574 /* support for POSIX tcsendbreak()
2575 *
2576 * According to POSIX.1 spec (7.2.2.1.2) breaks should be
2577 * between 0.25 and 0.5 seconds so we'll ask for something
2578 * in the middle: 0.375 seconds.
2579 */
2580 rc = tty_check_change(tty);
2581 if (rc)
2582 return rc;
2583 tty_wait_until_sent(tty, 0);
2584
2585 rc = dgrp_send_break(ch, arg ? arg*250 : 250);
2586
2587 if (dgrp_tty_chars_in_buffer(tty) != 0)
2588 return -EINTR;
2589 return 0;
2590
2591 case TIOCSBRK:
2592 rc = tty_check_change(tty);
2593 if (rc)
2594 return rc;
2595 tty_wait_until_sent(tty, 0);
2596
2597 /*
2598 * RealPort doesn't support turning on a break unconditionally.
2599 * The RealPort device will stop sending a break automatically
2600 * after the specified time value that we send in.
2601 */
2602 rc = dgrp_send_break(ch, 250); /* 1/4 second */
2603
2604 if (dgrp_tty_chars_in_buffer(tty) != 0)
2605 return -EINTR;
2606 return 0;
2607
2608 case TIOCCBRK:
2609 /*
2610 * RealPort doesn't support turning off a break unconditionally.
2611 * The RealPort device will stop sending a break automatically
2612 * after the specified time value that was sent when turning on
2613 * the break.
2614 */
2615 return 0;
2616
2617 case TIOCGSOFTCAR:
2618 rc = access_ok(VERIFY_WRITE, (void __user *) arg,
2619 sizeof(long));
2620 if (rc == 0)
2621 return -EFAULT;
2622 put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *) arg);
2623 return 0;
2624
2625 case TIOCSSOFTCAR:
2626 get_user(arg, (unsigned long __user *) arg);
2627 tty->termios.c_cflag =
2628 ((tty->termios.c_cflag & ~CLOCAL) |
2629 (arg ? CLOCAL : 0));
2630 return 0;
2631
2632 case TIOCMGET:
2633 rc = access_ok(VERIFY_WRITE, (void __user *) arg,
2634 sizeof(unsigned int));
2635 if (rc == 0)
2636 return -EFAULT;
2637 return get_modem_info(ch, (unsigned int *) arg);
2638
2639 case TIOCMBIS:
2640 case TIOCMBIC:
2641 case TIOCMSET:
2642 return set_modem_info(ch, cmd, (unsigned int *) arg);
2643
2644 /*
2645 * Here are any additional ioctl's that we want to implement
2646 */
2647
2648 case TCFLSH:
2649 /*
2650 * The linux tty driver doesn't have a flush
2651 * input routine for the driver, assuming all backed
2652 * up data is in the line disc. buffers. However,
2653 * we all know that's not the case. Here, we
2654 * act on the ioctl, but then lie and say we didn't
2655 * so the line discipline will process the flush
2656 * also.
2657 */
2658 rc = tty_check_change(tty);
2659 if (rc)
2660 return rc;
2661
2662 switch (arg) {
2663 case TCIFLUSH:
2664 case TCIOFLUSH:
2665 /* only flush input if this is the only open unit */
2666 if (!IS_PRINT(MINOR(tty_devnum(tty)))) {
2667 ch->ch_rout = ch->ch_rin;
2668 ch->ch_send |= RR_RX_FLUSH;
2669 (ch->ch_nd)->nd_tx_work = 1;
2670 (ch->ch_nd)->nd_tx_ready = 1;
2671 wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq);
2672 }
2673 if (arg == TCIFLUSH)
2674 break;
2675
2676 case TCOFLUSH: /* flush output, or the receive buffer */
2677 /*
2678 * This is handled in the tty_ioctl.c code
2679 * calling tty_flush_buffer
2680 */
2681 break;
2682
2683 default:
2684 /* POSIX.1 says return EINVAL if we got a bad arg */
2685 return -EINVAL;
2686 }
2687 /* pretend we didn't recognize this IOCTL */
2688 return -ENOIOCTLCMD;
2689
2690#ifdef TIOCGETP
2691 case TIOCGETP:
2692#endif
2693 /*****************************************
2694 Linux HPUX Function
2695 TCSETA TCSETA - set the termios
2696 TCSETAF TCSETAF - wait for drain first, then set termios
2697 TCSETAW TCSETAW - wait for drain, flush the input queue, then set termios
2698 - looking at the tty_ioctl code, these command all call our
2699 tty_set_termios at the driver's end, when a TCSETA* is sent,
2700 it is expecting the tty to have a termio structure,
2701 NOT a termios stucture. These two structures differ in size
2702 and the tty_ioctl code does a conversion before processing them both.
2703 - we should treat the TCSETAW TCSETAF ioctls the same, and let
2704 the tty_ioctl code do the conversion stuff.
2705
2706 TCSETS
2707 TCSETSF (none)
2708 TCSETSW
2709 - the associated tty structure has a termios structure.
2710 *****************************************/
2711
2712 case TCGETS:
2713 case TCGETA:
2714 return -ENOIOCTLCMD;
2715
2716 case TCSETAW:
2717 case TCSETAF:
2718 case TCSETSF:
2719 case TCSETSW:
2720 /*
2721 * The linux tty driver doesn't have a flush
2722 * input routine for the driver, assuming all backed
2723 * up data is in the line disc. buffers. However,
2724 * we all know that's not the case. Here, we
2725 * act on the ioctl, but then lie and say we didn't
2726 * so the line discipline will process the flush
2727 * also.
2728 */
2729
2730 /*
2731 * Also, now that we have TXPrint, we have to check
2732 * if this is the TXPrint device and the terminal
2733 * device is open. If so, do NOT run check_change,
2734 * as the terminal device is ALWAYS the parent.
2735 */
2736 if (!IS_PRINT(MINOR(tty_devnum(tty))) ||
2737 !ch->ch_tun.un_open_count) {
2738 rc = tty_check_change(tty);
2739 if (rc)
2740 return rc;
2741 }
2742
2743 /* wait for all the characters in tbuf to drain */
2744 tty_wait_until_sent(tty, 0);
2745
2746 if ((cmd == TCSETSF) || (cmd == TCSETAF)) {
2747 /* flush the contents of the rbuf queue */
2748 /* TODO: check if this is print device? */
2749 ch->ch_send |= RR_RX_FLUSH;
2750 (ch->ch_nd)->nd_tx_ready = 1;
2751 (ch->ch_nd)->nd_tx_work = 1;
2752 wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq);
2753 /* do we need to do this? just to be safe! */
2754 ch->ch_rout = ch->ch_rin;
2755 }
2756
2757 /* pretend we didn't recognize this */
2758 return -ENOIOCTLCMD;
2759
2760 case TCXONC:
2761 /*
2762 * The Linux Line Discipline (LD) would do this for us if we
2763 * let it, but we have the special firmware options to do this
2764 * the "right way" regardless of hardware or software flow
2765 * control so we'll do it outselves instead of letting the LD
2766 * do it.
2767 */
2768 rc = tty_check_change(tty);
2769 if (rc)
2770 return rc;
2771
2772 switch (arg) {
2773 case TCOON:
2774 dgrp_tty_start(tty);
2775 return 0;
2776 case TCOOFF:
2777 dgrp_tty_stop(tty);
2778 return 0;
2779 case TCION:
2780 dgrp_tty_input_start(tty);
2781 return 0;
2782 case TCIOFF:
2783 dgrp_tty_input_stop(tty);
2784 return 0;
2785 default:
2786 return -EINVAL;
2787 }
2788
2789 case DIGI_GETA:
2790 /* get information for ditty */
2791 if (copy_to_user((struct digi_struct __user *) arg,
2792 &ch->ch_digi, sizeof(struct digi_struct)))
2793 return -EFAULT;
2794 break;
2795
2796 case DIGI_SETAW:
2797 case DIGI_SETAF:
2798 /* wait for all the characters in tbuf to drain */
2799 tty_wait_until_sent(tty, 0);
2800
2801 if (cmd == DIGI_SETAF) {
2802 /* flush the contents of the rbuf queue */
2803 /* send down a packet with RR_RX_FLUSH set */
2804 ch->ch_send |= RR_RX_FLUSH;
2805 (ch->ch_nd)->nd_tx_ready = 1;
2806 (ch->ch_nd)->nd_tx_work = 1;
2807 wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq);
2808 /* do we need to do this? just to be safe! */
2809 ch->ch_rout = ch->ch_rin;
2810 }
2811
2812 /* pretend we didn't recognize this */
2813
2814 case DIGI_SETA:
2815 return dgrp_tty_digiseta(tty, (struct digi_struct *) arg);
2816
2817 case DIGI_SEDELAY:
2818 return dgrp_tty_digisetedelay(tty, (int *) arg);
2819
2820 case DIGI_GEDELAY:
2821 return dgrp_tty_digigetedelay(tty, (int *) arg);
2822
2823 case DIGI_GETFLOW:
2824 case DIGI_GETAFLOW:
2825 if (cmd == (DIGI_GETFLOW)) {
2826 dflow.startc = tty->termios.c_cc[VSTART];
2827 dflow.stopc = tty->termios.c_cc[VSTOP];
2828 } else {
2829 dflow.startc = ch->ch_xxon;
2830 dflow.stopc = ch->ch_xxoff;
2831 }
2832
2833 if (copy_to_user((char __user *)arg, &dflow, sizeof(dflow)))
2834 return -EFAULT;
2835 break;
2836
2837 case DIGI_SETFLOW:
2838 case DIGI_SETAFLOW:
2839
2840 if (copy_from_user(&dflow, (char __user *)arg, sizeof(dflow)))
2841 return -EFAULT;
2842
2843 if (cmd == (DIGI_SETFLOW)) {
2844 tty->termios.c_cc[VSTART] = dflow.startc;
2845 tty->termios.c_cc[VSTOP] = dflow.stopc;
2846 } else {
2847 ch->ch_xxon = dflow.startc;
2848 ch->ch_xxoff = dflow.stopc;
2849 }
2850 break;
2851
2852 case DIGI_GETCUSTOMBAUD:
2853 rc = access_ok(VERIFY_WRITE, (void __user *) arg, sizeof(int));
2854 if (rc == 0)
2855 return -EFAULT;
2856 put_user(ch->ch_custom_speed, (unsigned int __user *) arg);
2857 break;
2858
2859 case DIGI_SETCUSTOMBAUD:
2860 {
2861 int new_rate;
2862
2863 get_user(new_rate, (unsigned int __user *) arg);
2864 dgrp_set_custom_speed(ch, new_rate);
2865
2866 break;
2867 }
2868
2869 default:
2870 return -ENOIOCTLCMD;
2871 }
2872
2873 return 0;
2874}
2875
2876/*
2877 * This routine allows the tty driver to be notified when
2878 * the device's termios setting have changed. Note that we
2879 * should be prepared to accept the case where old == NULL
2880 * and try to do something rational.
2881 *
2882 * So we need to make sure that our copies of ch_oflag,
2883 * ch_clag, and ch_iflag reflect the tty->termios flags.
2884 */
2885static void dgrp_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
2886{
2887 struct ktermios *ts;
2888 struct ch_struct *ch;
2889 struct un_struct *un;
2890
2891 /* seems silly, but we have to check all these! */
2892 if (!tty)
2893 return;
2894
2895 un = tty->driver_data;
2896 if (!un)
2897 return;
2898
2899 ts = &tty->termios;
2900
2901 ch = un->un_ch;
2902 if (!ch)
2903 return;
2904
2905 drp_param(ch);
2906
2907 /* the CLOCAL flag has just been set */
2908 if (!(old->c_cflag & CLOCAL) && C_CLOCAL(tty))
2909 wake_up_interruptible(&un->un_open_wait);
2910}
2911
2912
2913/*
2914 * Throttle receiving data. We just set a bit and stop reading
2915 * data out of the channel buffer. It will back up and the
2916 * FEP will do whatever is necessary to stop the far end.
2917 */
2918static void dgrp_tty_throttle(struct tty_struct *tty)
2919{
2920 struct ch_struct *ch;
2921
2922 if (!tty)
2923 return;
2924
2925 ch = ((struct un_struct *) tty->driver_data)->un_ch;
2926 if (!ch)
2927 return;
2928
2929 ch->ch_flag |= CH_RXSTOP;
2930}
2931
2932
2933static void dgrp_tty_unthrottle(struct tty_struct *tty)
2934{
2935 struct ch_struct *ch;
2936
2937 if (!tty)
2938 return;
2939
2940 ch = ((struct un_struct *) tty->driver_data)->un_ch;
2941 if (!ch)
2942 return;
2943
2944 ch->ch_flag &= ~CH_RXSTOP;
2945}
2946
2947/*
2948 * Stop the transmitter
2949 */
2950static void dgrp_tty_stop(struct tty_struct *tty)
2951{
2952 struct ch_struct *ch;
2953
2954 if (!tty)
2955 return;
2956
2957 ch = ((struct un_struct *) tty->driver_data)->un_ch;
2958 if (!ch)
2959 return;
2960
2961 ch->ch_send |= RR_TX_STOP;
2962 ch->ch_send &= ~RR_TX_START;
2963
2964 /* make the change NOW! */
2965 (ch->ch_nd)->nd_tx_ready = 1;
2966 if (waitqueue_active(&(ch->ch_nd)->nd_tx_waitq))
2967 wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq);
2968}
2969
2970/*
2971 * Start the transmitter
2972 */
2973static void dgrp_tty_start(struct tty_struct *tty)
2974{
2975 struct ch_struct *ch;
2976
2977 if (!tty)
2978 return;
2979
2980 ch = ((struct un_struct *) tty->driver_data)->un_ch;
2981 if (!ch)
2982 return;
2983
2984 /* TODO: don't do anything if the transmitter is not stopped */
2985
2986 ch->ch_send |= RR_TX_START;
2987 ch->ch_send &= ~RR_TX_STOP;
2988
2989 /* make the change NOW! */
2990 (ch->ch_nd)->nd_tx_ready = 1;
2991 (ch->ch_nd)->nd_tx_work = 1;
2992 if (waitqueue_active(&(ch->ch_nd)->nd_tx_waitq))
2993 wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq);
2994
2995}
2996
2997/*
2998 * Stop the reciever
2999 */
3000static void dgrp_tty_input_stop(struct tty_struct *tty)
3001{
3002 struct ch_struct *ch;
3003
3004 if (!tty)
3005 return;
3006
3007 ch = ((struct un_struct *) tty->driver_data)->un_ch;
3008 if (!ch)
3009 return;
3010
3011 ch->ch_send |= RR_RX_STOP;
3012 ch->ch_send &= ~RR_RX_START;
3013 (ch->ch_nd)->nd_tx_ready = 1;
3014 if (waitqueue_active(&(ch->ch_nd)->nd_tx_waitq))
3015 wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq);
3016
3017}
3018
3019
3020static void dgrp_tty_send_xchar(struct tty_struct *tty, char c)
3021{
3022 struct un_struct *un;
3023 struct ch_struct *ch;
3024
3025 if (!tty)
3026 return;
3027
3028 un = tty->driver_data;
3029 if (!un)
3030 return;
3031
3032 ch = un->un_ch;
3033 if (!ch)
3034 return;
3035 if (c == STOP_CHAR(tty))
3036 ch->ch_send |= RR_RX_STOP;
3037 else if (c == START_CHAR(tty))
3038 ch->ch_send |= RR_RX_START;
3039
3040 ch->ch_nd->nd_tx_ready = 1;
3041 ch->ch_nd->nd_tx_work = 1;
3042
3043 return;
3044}
3045
3046
3047static void dgrp_tty_input_start(struct tty_struct *tty)
3048{
3049 struct ch_struct *ch;
3050
3051 if (!tty)
3052 return;
3053
3054 ch = ((struct un_struct *) tty->driver_data)->un_ch;
3055 if (!ch)
3056 return;
3057
3058 ch->ch_send |= RR_RX_START;
3059 ch->ch_send &= ~RR_RX_STOP;
3060 (ch->ch_nd)->nd_tx_ready = 1;
3061 (ch->ch_nd)->nd_tx_work = 1;
3062 if (waitqueue_active(&(ch->ch_nd)->nd_tx_waitq))
3063 wake_up_interruptible(&(ch->ch_nd)->nd_tx_waitq);
3064
3065}
3066
3067
3068/*
3069 * Hangup the port. Like a close, but don't wait for output
3070 * to drain.
3071 *
3072 * How do we close all the channels that are open?
3073 */
3074static void dgrp_tty_hangup(struct tty_struct *tty)
3075{
3076 struct ch_struct *ch;
3077 struct nd_struct *nd;
3078 struct un_struct *un;
3079
3080 if (!tty)
3081 return;
3082
3083 un = tty->driver_data;
3084 if (!un)
3085 return;
3086
3087 ch = un->un_ch;
3088 if (!ch)
3089 return;
3090
3091 nd = ch->ch_nd;
3092
3093 if (C_HUPCL(tty)) {
3094 /* LOWER DTR */
3095 ch->ch_mout &= ~DM_DTR;
3096 /* Don't do this here */
3097 /* ch->ch_flag |= CH_HANGUP; */
3098 ch->ch_nd->nd_tx_ready = 1;
3099 ch->ch_nd->nd_tx_work = 1;
3100 if (waitqueue_active(&ch->ch_flag_wait))
3101 wake_up_interruptible(&ch->ch_flag_wait);
3102 }
3103
3104}
3105
3106/************************************************************************/
3107/* */
3108/* TTY Initialization/Cleanup Functions */
3109/* */
3110/************************************************************************/
3111
3112/*
3113 * Uninitialize the TTY portion of the supplied node. Free all
3114 * memory and resources associated with this node. Do it in reverse
3115 * allocation order: this might possibly result in less fragmentation
3116 * of memory, though I don't know this for sure.
3117 */
3118void
3119dgrp_tty_uninit(struct nd_struct *nd)
3120{
3121 char id[3];
3122
3123 ID_TO_CHAR(nd->nd_ID, id);
3124
3125 if (nd->nd_ttdriver_flags & SERIAL_TTDRV_REG) {
3126 tty_unregister_driver(nd->nd_serial_ttdriver);
3127
3128 kfree(nd->nd_serial_ttdriver->ttys);
3129 nd->nd_serial_ttdriver->ttys = NULL;
3130
3131 put_tty_driver(nd->nd_serial_ttdriver);
3132 nd->nd_ttdriver_flags &= ~SERIAL_TTDRV_REG;
3133 }
3134
3135 if (nd->nd_ttdriver_flags & CALLOUT_TTDRV_REG) {
3136 tty_unregister_driver(nd->nd_callout_ttdriver);
3137
3138 kfree(nd->nd_callout_ttdriver->ttys);
3139 nd->nd_callout_ttdriver->ttys = NULL;
3140
3141 put_tty_driver(nd->nd_callout_ttdriver);
3142 nd->nd_ttdriver_flags &= ~CALLOUT_TTDRV_REG;
3143 }
3144
3145 if (nd->nd_ttdriver_flags & XPRINT_TTDRV_REG) {
3146 tty_unregister_driver(nd->nd_xprint_ttdriver);
3147
3148 kfree(nd->nd_xprint_ttdriver->ttys);
3149 nd->nd_xprint_ttdriver->ttys = NULL;
3150
3151 put_tty_driver(nd->nd_xprint_ttdriver);
3152 nd->nd_ttdriver_flags &= ~XPRINT_TTDRV_REG;
3153 }
3154}
3155
3156
3157
3158/*
3159 * Initialize the TTY portion of the supplied node.
3160 */
3161int
3162dgrp_tty_init(struct nd_struct *nd)
3163{
3164 char id[3];
3165 int rc;
3166 int i;
3167
3168 ID_TO_CHAR(nd->nd_ID, id);
3169
3170 /*
3171 * Initialize the TTDRIVER structures.
3172 */
3173
3174 nd->nd_serial_ttdriver = alloc_tty_driver(CHAN_MAX);
3175 sprintf(nd->nd_serial_name, "tty_dgrp_%s_", id);
3176
3177 nd->nd_serial_ttdriver->owner = THIS_MODULE;
3178 nd->nd_serial_ttdriver->name = nd->nd_serial_name;
3179 nd->nd_serial_ttdriver->name_base = 0;
3180 nd->nd_serial_ttdriver->major = 0;
3181 nd->nd_serial_ttdriver->minor_start = 0;
3182 nd->nd_serial_ttdriver->type = TTY_DRIVER_TYPE_SERIAL;
3183 nd->nd_serial_ttdriver->subtype = SERIAL_TYPE_NORMAL;
3184 nd->nd_serial_ttdriver->init_termios = DefaultTermios;
3185 nd->nd_serial_ttdriver->driver_name = "dgrp";
3186 nd->nd_serial_ttdriver->flags = (TTY_DRIVER_REAL_RAW |
3187 TTY_DRIVER_DYNAMIC_DEV |
3188 TTY_DRIVER_HARDWARE_BREAK);
3189
3190 /* The kernel wants space to store pointers to tty_structs. */
3191 nd->nd_serial_ttdriver->ttys =
3192 kzalloc(CHAN_MAX * sizeof(struct tty_struct *), GFP_KERNEL);
3193 if (!nd->nd_serial_ttdriver->ttys)
3194 return -ENOMEM;
3195
3196 tty_set_operations(nd->nd_serial_ttdriver, &dgrp_tty_ops);
3197
3198 if (!(nd->nd_ttdriver_flags & SERIAL_TTDRV_REG)) {
3199 /*
3200 * Register tty devices
3201 */
3202 rc = tty_register_driver(nd->nd_serial_ttdriver);
3203 if (rc < 0) {
3204 /*
3205 * If errno is EBUSY, this means there are no more
3206 * slots available to have us auto-majored.
3207 * (Which is currently supported up to 256)
3208 *
3209 * We can still request majors above 256,
3210 * we just have to do it manually.
3211 */
3212 if (rc == -EBUSY) {
3213 int i;
3214 int max_majors = 1U << (32 - MINORBITS);
3215 for (i = 256; i < max_majors; i++) {
3216 nd->nd_serial_ttdriver->major = i;
3217 rc = tty_register_driver(nd->nd_serial_ttdriver);
3218 if (rc >= 0)
3219 break;
3220 }
3221 /* Really fail now, since we ran out
3222 * of majors to try. */
3223 if (i == max_majors)
3224 return rc;
3225
3226 } else {
3227 return rc;
3228 }
3229 }
3230 nd->nd_ttdriver_flags |= SERIAL_TTDRV_REG;
3231 }
3232
3233 nd->nd_callout_ttdriver = alloc_tty_driver(CHAN_MAX);
3234 sprintf(nd->nd_callout_name, "cu_dgrp_%s_", id);
3235
3236 nd->nd_callout_ttdriver->owner = THIS_MODULE;
3237 nd->nd_callout_ttdriver->name = nd->nd_callout_name;
3238 nd->nd_callout_ttdriver->name_base = 0;
3239 nd->nd_callout_ttdriver->major = nd->nd_serial_ttdriver->major;
3240 nd->nd_callout_ttdriver->minor_start = 0x40;
3241 nd->nd_callout_ttdriver->type = TTY_DRIVER_TYPE_SERIAL;
3242 nd->nd_callout_ttdriver->subtype = SERIAL_TYPE_CALLOUT;
3243 nd->nd_callout_ttdriver->init_termios = DefaultTermios;
3244 nd->nd_callout_ttdriver->driver_name = "dgrp";
3245 nd->nd_callout_ttdriver->flags = (TTY_DRIVER_REAL_RAW |
3246 TTY_DRIVER_DYNAMIC_DEV |
3247 TTY_DRIVER_HARDWARE_BREAK);
3248
3249 /* The kernel wants space to store pointers to tty_structs. */
3250 nd->nd_callout_ttdriver->ttys =
3251 kzalloc(CHAN_MAX * sizeof(struct tty_struct *), GFP_KERNEL);
3252 if (!nd->nd_callout_ttdriver->ttys)
3253 return -ENOMEM;
3254
3255 tty_set_operations(nd->nd_callout_ttdriver, &dgrp_tty_ops);
3256
3257 if (dgrp_register_cudevices) {
3258 if (!(nd->nd_ttdriver_flags & CALLOUT_TTDRV_REG)) {
3259 /*
3260 * Register cu devices
3261 */
3262 rc = tty_register_driver(nd->nd_callout_ttdriver);
3263 if (rc < 0)
3264 return rc;
3265 nd->nd_ttdriver_flags |= CALLOUT_TTDRV_REG;
3266 }
3267 }
3268
3269
3270 nd->nd_xprint_ttdriver = alloc_tty_driver(CHAN_MAX);
3271 sprintf(nd->nd_xprint_name, "pr_dgrp_%s_", id);
3272
3273 nd->nd_xprint_ttdriver->owner = THIS_MODULE;
3274 nd->nd_xprint_ttdriver->name = nd->nd_xprint_name;
3275 nd->nd_xprint_ttdriver->name_base = 0;
3276 nd->nd_xprint_ttdriver->major = nd->nd_serial_ttdriver->major;
3277 nd->nd_xprint_ttdriver->minor_start = 0x80;
3278 nd->nd_xprint_ttdriver->type = TTY_DRIVER_TYPE_SERIAL;
3279 nd->nd_xprint_ttdriver->subtype = SERIAL_TYPE_XPRINT;
3280 nd->nd_xprint_ttdriver->init_termios = DefaultTermios;
3281 nd->nd_xprint_ttdriver->driver_name = "dgrp";
3282 nd->nd_xprint_ttdriver->flags = (TTY_DRIVER_REAL_RAW |
3283 TTY_DRIVER_DYNAMIC_DEV |
3284 TTY_DRIVER_HARDWARE_BREAK);
3285
3286 /* The kernel wants space to store pointers to tty_structs. */
3287 nd->nd_xprint_ttdriver->ttys =
3288 kzalloc(CHAN_MAX * sizeof(struct tty_struct *), GFP_KERNEL);
3289 if (!nd->nd_xprint_ttdriver->ttys)
3290 return -ENOMEM;
3291
3292 tty_set_operations(nd->nd_xprint_ttdriver, &dgrp_tty_ops);
3293
3294 if (dgrp_register_prdevices) {
3295 if (!(nd->nd_ttdriver_flags & XPRINT_TTDRV_REG)) {
3296 /*
3297 * Register transparent print devices
3298 */
3299 rc = tty_register_driver(nd->nd_xprint_ttdriver);
3300 if (rc < 0)
3301 return rc;
3302 nd->nd_ttdriver_flags |= XPRINT_TTDRV_REG;
3303 }
3304 }
3305
3306 for (i = 0; i < CHAN_MAX; i++) {
3307 struct ch_struct *ch = nd->nd_chan + i;
3308
3309 ch->ch_nd = nd;
3310 ch->ch_digi = digi_init;
3311 ch->ch_edelay = 100;
3312 ch->ch_custom_speed = 0;
3313 ch->ch_portnum = i;
3314 ch->ch_tun.un_ch = ch;
3315 ch->ch_pun.un_ch = ch;
3316 ch->ch_tun.un_type = SERIAL_TYPE_NORMAL;
3317 ch->ch_pun.un_type = SERIAL_TYPE_XPRINT;
3318
3319 init_waitqueue_head(&(ch->ch_flag_wait));
3320 init_waitqueue_head(&(ch->ch_sleep));
3321
3322 init_waitqueue_head(&(ch->ch_tun.un_open_wait));
3323 init_waitqueue_head(&(ch->ch_tun.un_close_wait));
3324
3325 init_waitqueue_head(&(ch->ch_pun.un_open_wait));
3326 init_waitqueue_head(&(ch->ch_pun.un_close_wait));
3327 tty_port_init(&ch->port);
3328 tty_port_init(&ch->port);
3329 }
3330 return 0;
3331}
diff --git a/drivers/staging/dgrp/digirp.h b/drivers/staging/dgrp/digirp.h
new file mode 100644
index 00000000000..33c1394fade
--- /dev/null
+++ b/drivers/staging/dgrp/digirp.h
@@ -0,0 +1,129 @@
1/************************************************************************
2 * HP-UX Realport Daemon interface file.
3 *
4 * Copyright (C) 1998, by Digi International. All Rights Reserved.
5 ************************************************************************/
6
7#ifndef _DIGIDRP_H
8#define _DIGIDRP_H
9
10/************************************************************************
11 * This file contains defines for the ioctl() interface to
12 * the realport driver. This ioctl() interface is used by the
13 * daemon to set speed setup parameters honored by the driver.
14 ************************************************************************/
15
16struct link_struct {
17 int lk_fast_rate; /* Fast line rate to be used
18 when the delay is less-equal
19 to lk_fast_delay */
20
21 int lk_fast_delay; /* Fast line rate delay in
22 milliseconds */
23
24 int lk_slow_rate; /* Slow line rate to be used when
25 the delay is greater-equal
26 to lk_slow_delay */
27
28 int lk_slow_delay; /* Slow line rate delay in
29 milliseconds */
30
31 int lk_header_size; /* Estimated packet header size
32 when sent across the slowest
33 link. */
34};
35
36#define DIGI_GETLINK _IOW('e', 103, struct link_struct) /* Get link parameters */
37#define DIGI_SETLINK _IOW('e', 104, struct link_struct) /* Set link parameters */
38
39
40/************************************************************************
41 * This module provides application access to special Digi
42 * serial line enhancements which are not standard UNIX(tm) features.
43 ************************************************************************/
44
45struct digiflow_struct {
46 unsigned char startc; /* flow cntl start char */
47 unsigned char stopc; /* flow cntl stop char */
48};
49
50/************************************************************************
51 * Values for digi_flags
52 ************************************************************************/
53#define DIGI_IXON 0x0001 /* Handle IXON in the FEP */
54#define DIGI_FAST 0x0002 /* Fast baud rates */
55#define RTSPACE 0x0004 /* RTS input flow control */
56#define CTSPACE 0x0008 /* CTS output flow control */
57#define DSRPACE 0x0010 /* DSR output flow control */
58#define DCDPACE 0x0020 /* DCD output flow control */
59#define DTRPACE 0x0040 /* DTR input flow control */
60#define DIGI_COOK 0x0080 /* Cooked processing done in FEP */
61#define DIGI_FORCEDCD 0x0100 /* Force carrier */
62#define DIGI_ALTPIN 0x0200 /* Alternate RJ-45 pin config */
63#define DIGI_AIXON 0x0400 /* Aux flow control in fep */
64#define DIGI_PRINTER 0x0800 /* Hold port open for flow cntrl */
65#define DIGI_PP_INPUT 0x1000 /* Change parallel port to input */
66#define DIGI_422 0x4000 /* Change parallel port to input */
67#define DIGI_RTS_TOGGLE 0x8000 /* Support RTS Toggle */
68
69
70/************************************************************************
71 * Values associated with transparent print
72 ************************************************************************/
73#define DIGI_PLEN 8 /* String length */
74#define DIGI_TSIZ 10 /* Terminal string len */
75
76
77/************************************************************************
78 * Structure used with ioctl commands for DIGI parameters.
79 ************************************************************************/
80struct digi_struct {
81 unsigned short digi_flags; /* Flags (see above) */
82 unsigned short digi_maxcps; /* Max printer CPS */
83 unsigned short digi_maxchar; /* Max chars in print queue */
84 unsigned short digi_bufsize; /* Buffer size */
85 unsigned char digi_onlen; /* Length of ON string */
86 unsigned char digi_offlen; /* Length of OFF string */
87 char digi_onstr[DIGI_PLEN]; /* Printer on string */
88 char digi_offstr[DIGI_PLEN]; /* Printer off string */
89 char digi_term[DIGI_TSIZ]; /* terminal string */
90};
91
92/************************************************************************
93 * Ioctl command arguments for DIGI parameters.
94 ************************************************************************/
95/* Read params */
96#define DIGI_GETA _IOR('e', 94, struct digi_struct)
97
98/* Set params */
99#define DIGI_SETA _IOW('e', 95, struct digi_struct)
100
101/* Drain & set params */
102#define DIGI_SETAW _IOW('e', 96, struct digi_struct)
103
104/* Drain, flush & set params */
105#define DIGI_SETAF _IOW('e', 97, struct digi_struct)
106
107/* Get startc/stopc flow control characters */
108#define DIGI_GETFLOW _IOR('e', 99, struct digiflow_struct)
109
110/* Set startc/stopc flow control characters */
111#define DIGI_SETFLOW _IOW('e', 100, struct digiflow_struct)
112
113/* Get Aux. startc/stopc flow control chars */
114#define DIGI_GETAFLOW _IOR('e', 101, struct digiflow_struct)
115
116/* Set Aux. startc/stopc flow control chars */
117#define DIGI_SETAFLOW _IOW('e', 102, struct digiflow_struct)
118
119/* Set integer baud rate */
120#define DIGI_SETCUSTOMBAUD _IOW('e', 106, int)
121
122/* Get integer baud rate */
123#define DIGI_GETCUSTOMBAUD _IOR('e', 107, int)
124
125#define DIGI_GEDELAY _IOR('d', 246, int) /* Get edelay */
126#define DIGI_SEDELAY _IOW('d', 247, int) /* Get edelay */
127
128
129#endif /* _DIGIDRP_H */
diff --git a/drivers/staging/dgrp/drp.h b/drivers/staging/dgrp/drp.h
new file mode 100644
index 00000000000..84a1e7be489
--- /dev/null
+++ b/drivers/staging/dgrp/drp.h
@@ -0,0 +1,693 @@
1/*
2 *
3 * Copyright 1999 Digi International (www.digi.com)
4 * Gene Olson <gene at digi dot com>
5 * James Puzzo <jamesp at digi dot com>
6 * Scott Kilau <scottk at digi dot com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
15 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 * PURPOSE. See the GNU General Public License for more details.
17 *
18 */
19
20/************************************************************************
21 * Master include file for Linux Realport Driver.
22 ************************************************************************/
23
24#ifndef __DRP_H
25#define __DRP_H
26
27#include <linux/types.h>
28#include <linux/wait.h>
29#include <linux/semaphore.h>
30#include <linux/tty.h>
31
32
33#include "digirp.h"
34
35/************************************************************************
36 * Tuning parameters.
37 ************************************************************************/
38
39#define CHAN_MAX 64 /* Max # ports per server */
40
41#define SEQ_MAX 128 /* Max # transmit sequences (2^n) */
42#define SEQ_MASK (SEQ_MAX-1) /* Sequence buffer modulus mask */
43
44#define TBUF_MAX 4096 /* Size of transmit buffer (2^n) */
45#define RBUF_MAX 4096 /* Size of receive buffer (2^n) */
46
47#define TBUF_MASK (TBUF_MAX-1) /* Transmit buffer modulus mask */
48#define RBUF_MASK (RBUF_MAX-1) /* Receive buffer modulus mask */
49
50#define TBUF_LOW 1000 /* Transmit low water mark */
51
52#define UIO_BASE 1000 /* Base for write operations */
53#define UIO_MIN 2000 /* Minimum size application buffer */
54#define UIO_MAX 8100 /* Unix I/O buffer size */
55
56#define MON_MAX 65536 /* Monitor buffer size (2^n) */
57#define MON_MASK (MON_MAX-1) /* Monitor wrap mask */
58
59#define DPA_MAX 65536 /* DPA buffer size (2^n) */
60#define DPA_MASK (DPA_MAX-1) /* DPA wrap mask */
61#define DPA_HIGH_WATER 58000 /* Enforce flow control when
62 * over this amount
63 */
64
65#define IDLE_MAX (20 * HZ) /* Max TCP link idle time */
66
67#define MAX_DESC_LEN 100 /* Maximum length of stored PS
68 * description
69 */
70
71#define WRITEBUFLEN ((4096) + 4) /* 4 extra for alignment play space */
72
73#define VPDSIZE 512
74
75/************************************************************************
76 * Minor device decoding conventions.
77 ************************************************************************
78 *
79 * For Linux, the net and mon devices are handled via "proc", so we
80 * only have to mux the "tty" devices. Since every PortServer will
81 * have an individual major number, the PortServer number does not
82 * need to be encoded, and in fact, does not need to exist.
83 *
84 */
85
86/*
87 * Port device decoding conventions:
88 *
89 * Device 00 - 3f 64 dial-in modem devices. (tty)
90 * Device 40 - 7f 64 dial-out tty devices. (cu)
91 * Device 80 - bf 64 dial-out printer devices.
92 *
93 * IS_PRINT(dev) This is a printer device.
94 *
95 * OPEN_CATEGORY(dev) Specifies the device category. No two
96 * devices of different categories may be open
97 * at the same time.
98 *
99 * The following require the category returned by OPEN_CATEGORY().
100 *
101 * OPEN_WAIT_AVAIL(cat) Waits on open until the device becomes
102 * available. Fails if NDELAY specified.
103 *
104 * OPEN_WAIT_CARRIER(cat) Waits on open if carrier is not present.
105 * Succeeds if NDELAY is given.
106 *
107 * OPEN_FORCES_CARRIER(cat) Carrier is forced high on open.
108 *
109 */
110
111#define PORT_NUM(dev) ((dev) & 0x3f)
112
113#define OPEN_CATEGORY(dev) ((((dev) & 0x80) & 0x40))
114#define IS_PRINT(dev) (((dev) & 0xff) >= 0x80)
115
116#define OPEN_WAIT_AVAIL(cat) (((cat) & 0x40) == 0x000)
117#define OPEN_WAIT_CARRIER(cat) (((cat) & 0x40) == 0x000)
118#define OPEN_FORCES_CARRIER(cat) (((cat) & 0x40) != 0x000)
119
120
121/************************************************************************
122 * Modem signal defines for 16450/16550 compatible FEP.
123 * set in ch_mout, ch_mflow, ch_mlast etc
124 ************************************************************************/
125
126/* TODO : Re-verify that these modem signal definitions are correct */
127
128#define DM_DTR 0x01
129#define DM_RTS 0x02
130#define DM_RTS_TOGGLE 0x04
131
132#define DM_OUT1 0x04
133#define DM_OUT2 0x08
134
135#define DM_CTS 0x10
136#define DM_DSR 0x20
137#define DM_RI 0x40
138#define DM_CD 0x80 /* This is the DCD flag */
139
140
141/************************************************************************
142 * Realport Event Flags.
143 ************************************************************************/
144
145#define EV_OPU 0x0001 /* Ouput paused by client */
146#define EV_OPS 0x0002 /* Output paused by XOFF */
147#define EV_OPX 0x0004 /* Output paused by XXOFF */
148#define EV_OPH 0x0008 /* Output paused by MFLOW */
149#define EV_IPU 0x0010 /* Input paused by client */
150#define EV_IPS 0x0020 /* Input paused by hi/low water */
151#define EV_TXB 0x0040 /* Transmit break pending */
152#define EV_TXI 0x0080 /* Transmit immediate pending */
153#define EV_TXF 0x0100 /* Transmit flow control pending */
154#define EV_RXB 0x0200 /* Break received */
155
156
157/************************************************************************
158 * Realport CFLAGS.
159 ************************************************************************/
160
161#define CF_CS5 0x0000 /* 5 bit characters */
162#define CF_CS6 0x0010 /* 6 bit characters */
163#define CF_CS7 0x0020 /* 7 bit characters */
164#define CF_CS8 0x0030 /* 8 bit characters */
165#define CF_CSIZE 0x0030 /* Character size */
166#define CF_CSTOPB 0x0040 /* Two stop bits */
167#define CF_CREAD 0x0080 /* Enable receiver */
168#define CF_PARENB 0x0100 /* Enable parity */
169#define CF_PARODD 0x0200 /* Odd parity */
170#define CF_HUPCL 0x0400 /* Drop DTR on close */
171
172
173/************************************************************************
174 * Realport XFLAGS.
175 ************************************************************************/
176
177#define XF_XPAR 0x0001 /* Enable Mark/Space Parity */
178#define XF_XMODEM 0x0002 /* Enable in-band modem signalling */
179#define XF_XCASE 0x0004 /* Convert special characters */
180#define XF_XEDATA 0x0008 /* Error data in stream */
181#define XF_XTOSS 0x0010 /* Toss IXANY characters */
182#define XF_XIXON 0x0020 /* xxon/xxoff enable */
183
184
185/************************************************************************
186 * Realport IFLAGS.
187 ************************************************************************/
188
189#define IF_IGNBRK 0x0001 /* Ignore input break */
190#define IF_BRKINT 0x0002 /* Break interrupt */
191#define IF_IGNPAR 0x0004 /* Ignore error characters */
192#define IF_PARMRK 0x0008 /* Error chars marked with 0xff */
193#define IF_INPCK 0x0010 /* Input parity checking enabled */
194#define IF_ISTRIP 0x0020 /* Input chars masked with 0x7F */
195#define IF_IXON 0x0400 /* Output software flow control */
196#define IF_IXANY 0x0800 /* Restart output on any char */
197#define IF_IXOFF 0x1000 /* Input software flow control */
198#define IF_DOSMODE 0x8000 /* 16450-compatible errors */
199
200
201/************************************************************************
202 * Realport OFLAGS.
203 ************************************************************************/
204
205#define OF_OLCUC 0x0002 /* Map lower to upper case */
206#define OF_ONLCR 0x0004 /* Map NL to CR-NL */
207#define OF_OCRNL 0x0008 /* Map CR to NL */
208#define OF_ONOCR 0x0010 /* No CR output at column 0 */
209#define OF_ONLRET 0x0020 /* Assume NL does NL/CR */
210#define OF_TAB3 0x1800 /* Tabs expand to 8 spaces */
211#define OF_TABDLY 0x1800 /* Tab delay */
212
213/************************************************************************
214 * Unit flag definitions for un_flag.
215 ************************************************************************/
216
217/* These are the DIGI unit flags */
218#define UN_EXCL 0x00010000 /* Exclusive open */
219#define UN_STICKY 0x00020000 /* TTY Settings are now sticky */
220#define UN_BUSY 0x00040000 /* Some work this channel */
221#define UN_PWAIT 0x00080000 /* Printer waiting for terminal */
222#define UN_TIME 0x00100000 /* Waiting on time */
223#define UN_EMPTY 0x00200000 /* Waiting output queue empty */
224#define UN_LOW 0x00400000 /* Waiting output low water */
225#define UN_DIGI_MASK 0x00FF0000 /* Waiting output low water */
226
227/*
228 * Definitions for async_struct (and serial_struct) flags field
229 *
230 * these are the ASYNC flags copied from serial.h
231 *
232 */
233#define UN_HUP_NOTIFY 0x0001 /* Notify getty on hangups and
234 * closes on the callout port
235 */
236#define UN_FOURPORT 0x0002 /* Set OU1, OUT2 per AST Fourport settings */
237#define UN_SAK 0x0004 /* Secure Attention Key (Orange book) */
238#define UN_SPLIT_TERMIOS 0x0008 /* Separate termios for dialin/callout */
239
240#define UN_SPD_MASK 0x0030
241#define UN_SPD_HI 0x0010 /* Use 56000 instead of 38400 bps */
242#define UN_SPD_VHI 0x0020 /* Use 115200 instead of 38400 bps */
243#define UN_SPD_CUST 0x0030 /* Use user-specified divisor */
244
245#define UN_SKIP_TEST 0x0040 /* Skip UART test during autoconfiguration */
246#define UN_AUTO_IRQ 0x0080 /* Do automatic IRQ during autoconfiguration */
247
248#define UN_SESSION_LOCKOUT 0x0100 /* Lock out cua opens based on session */
249#define UN_PGRP_LOCKOUT 0x0200 /* Lock out cua opens based on pgrp */
250#define UN_CALLOUT_NOHUP 0x0400 /* Don't do hangups for cua device */
251
252#define UN_FLAGS 0x0FFF /* Possible legal async flags */
253#define UN_USR_MASK 0x0430 /* Legal flags that non-privileged
254 * users can set or reset
255 */
256
257#define UN_INITIALIZED 0x80000000 /* Serial port was initialized */
258#define UN_CALLOUT_ACTIVE 0x40000000 /* Call out device is active */
259#define UN_NORMAL_ACTIVE 0x20000000 /* Normal device is active */
260#define UN_BOOT_AUTOCONF 0x10000000 /* Autoconfigure port on bootup */
261#define UN_CLOSING 0x08000000 /* Serial port is closing */
262#define UN_CTS_FLOW 0x04000000 /* Do CTS flow control */
263#define UN_CHECK_CD 0x02000000 /* i.e., CLOCAL */
264#define UN_SHARE_IRQ 0x01000000 /* for multifunction cards */
265
266
267/************************************************************************
268 * Structure for terminal or printer unit. struct un_struct
269 *
270 * Note that in some places the code assumes the "tty_t" is placed
271 * first in the structure.
272 ************************************************************************/
273
274struct un_struct {
275 struct tty_struct *un_tty; /* System TTY struct */
276 struct ch_struct *un_ch; /* Associated channel */
277
278 ushort un_open_count; /* Successful open count */
279 int un_flag; /* Unit flags */
280 ushort un_tbusy; /* Busy transmit count */
281
282 wait_queue_head_t un_open_wait;
283 wait_queue_head_t un_close_wait;
284 ushort un_type;
285 struct device *un_sysfs;
286};
287
288
289/************************************************************************
290 * Channel State Numbers for ch_state.
291 ************************************************************************/
292
293/*
294 * The ordering is important.
295 *
296 * state <= CS_WAIT_CANCEL implies the channel is definitely closed.
297 *
298 * state >= CS_WAIT_FAIL implies the channel is definitely open.
299 *
300 * state >= CS_READY implies data is allowed on the channel.
301 */
302
303enum dgrp_ch_state_t {
304 CS_IDLE = 0, /* Channel is idle */
305 CS_WAIT_OPEN = 1, /* Waiting for Immediate Open Resp */
306 CS_WAIT_CANCEL = 2, /* Waiting for Per/Incom Cancel Resp */
307 CS_WAIT_FAIL = 3, /* Waiting for Immed Open Failure */
308 CS_SEND_QUERY = 4, /* Ready to send Port Query */
309 CS_WAIT_QUERY = 5, /* Waiting for Port Query Response */
310 CS_READY = 6, /* Ready to accept commands and data */
311 CS_SEND_CLOSE = 7, /* Ready to send Close Request */
312 CS_WAIT_CLOSE = 8 /* Waiting for Close Response */
313};
314
315/************************************************************************
316 * Device flag definitions for ch_flag.
317 ************************************************************************/
318
319/*
320 * Note that the state of the two carrier based flags is key. When
321 * we check for carrier state transitions, we look at the current
322 * physical state of the DCD line and compare it with PHYS_CD (which
323 * was the state the last time we checked), and we also determine
324 * a new virtual state (composite of the physical state, FORCEDCD,
325 * CLOCAL, etc.) and compare it with VIRT_CD.
326 *
327 * VIRTUAL transitions high will have the side effect of waking blocked
328 * opens.
329 *
330 * PHYSICAL transitions low will cause hangups to occur _IF_ the virtual
331 * state is also low. We DON'T want to hangup on a PURE virtual drop.
332 */
333
334#define CH_HANGUP 0x00002 /* Server port ready to close */
335
336#define CH_VIRT_CD 0x00004 /* Carrier was virtually present */
337#define CH_PHYS_CD 0x00008 /* Carrier was physically present */
338
339#define CH_CLOCAL 0x00010 /* CLOCAL set in cflags */
340#define CH_BAUD0 0x00020 /* Baud rate zero hangup */
341
342#define CH_FAST_READ 0x00040 /* Fast reads are enabled */
343#define CH_FAST_WRITE 0x00080 /* Fast writes are enabled */
344
345#define CH_PRON 0x00100 /* Printer on string active */
346#define CH_RX_FLUSH 0x00200 /* Flushing receive data */
347#define CH_LOW 0x00400 /* Thread waiting for LOW water */
348#define CH_EMPTY 0x00800 /* Thread waiting for EMPTY */
349#define CH_DRAIN 0x01000 /* Close is waiting to drain */
350#define CH_INPUT 0x02000 /* Thread waiting for INPUT */
351#define CH_RXSTOP 0x04000 /* Stop output to ldisc */
352#define CH_PARAM 0x08000 /* A parameter was updated */
353#define CH_WAITING_SYNC 0x10000 /* A pending sync was assigned
354 * to this port.
355 */
356#define CH_PORT_GONE 0x20000 /* Port has disappeared */
357#define CH_TX_BREAK 0x40000 /* TX Break to be sent,
358 * but has not yet.
359 */
360
361/************************************************************************
362 * Types of Open Requests for ch_otype.
363 ************************************************************************/
364
365#define OTYPE_IMMEDIATE 0 /* Immediate Open */
366#define OTYPE_PERSISTENT 1 /* Persistent Open */
367#define OTYPE_INCOMING 2 /* Incoming Open */
368
369
370/************************************************************************
371 * Request/Response flags.
372 ************************************************************************/
373
374#define RR_SEQUENCE 0x0001 /* Get server RLAST, TIN */
375#define RR_STATUS 0x0002 /* Get server MINT, EINT */
376#define RR_BUFFER 0x0004 /* Get server RSIZE, TSIZE */
377#define RR_CAPABILITY 0x0008 /* Get server port capabilities */
378
379#define RR_TX_FLUSH 0x0040 /* Flush output buffers */
380#define RR_RX_FLUSH 0x0080 /* Flush input buffers */
381
382#define RR_TX_STOP 0x0100 /* Pause output */
383#define RR_RX_STOP 0x0200 /* Pause input */
384#define RR_TX_START 0x0400 /* Start output */
385#define RR_RX_START 0x0800 /* Start input */
386
387#define RR_TX_BREAK 0x1000 /* Send BREAK */
388#define RR_TX_ICHAR 0x2000 /* Send character immediate */
389
390
391/************************************************************************
392 * Channel information structure. struct ch_struct
393 ************************************************************************/
394
395struct ch_struct {
396 struct digi_struct ch_digi; /* Digi variables */
397 int ch_edelay; /* Digi edelay */
398
399 struct tty_port port;
400 struct un_struct ch_tun; /* Terminal unit info */
401 struct un_struct ch_pun; /* Printer unit info */
402
403 struct nd_struct *ch_nd; /* Node pointer */
404 u8 *ch_tbuf; /* Local Transmit Buffer */
405 u8 *ch_rbuf; /* Local Receive Buffer */
406 ulong ch_cpstime; /* Printer CPS time */
407 ulong ch_waketime; /* Printer wake time */
408
409 ulong ch_flag; /* CH_* flags */
410
411 enum dgrp_ch_state_t ch_state; /* CS_* Protocol state */
412 ushort ch_send; /* Bit vector of RR_* requests */
413 ushort ch_expect; /* Bit vector of RR_* responses */
414 ushort ch_wait_carrier; /* Thread count waiting for carrier */
415 ushort ch_wait_count[3]; /* Thread count waiting by otype */
416
417 ushort ch_portnum; /* Port number */
418 ushort ch_open_count; /* Successful open count */
419 ushort ch_category; /* Device category */
420 ushort ch_open_error; /* Last open error number */
421 ushort ch_break_time; /* Pending break request time */
422 ushort ch_cpsrem; /* Printer CPS remainder */
423 ushort ch_ocook; /* Realport fastcook oflags */
424 ushort ch_inwait; /* Thread count in CLIST input */
425
426 ushort ch_tin; /* Local transmit buffer in ptr */
427 ushort ch_tout; /* Local transmit buffer out ptr */
428 ushort ch_s_tin; /* Realport TIN */
429 ushort ch_s_tpos; /* Realport TPOS */
430 ushort ch_s_tsize; /* Realport TSIZE */
431 ushort ch_s_treq; /* Realport TREQ */
432 ushort ch_s_elast; /* Realport ELAST */
433
434 ushort ch_rin; /* Local receive buffer in ptr */
435 ushort ch_rout; /* Local receive buffer out ptr */
436 ushort ch_s_rin; /* Realport RIN */
437 /* David Fries 7-13-2001, ch_s_rin should be renamed ch_s_rout because
438 * the variable we want to represent is the PortServer's ROUT, which is
439 * the sequence number for the next byte the PortServer will send us.
440 * RIN is the sequence number for the next byte the PortServer will
441 * receive from the uart. The port server will send data as long as
442 * ROUT is less than RWIN. What would happen is the port is opened, it
443 * receives data, it gives the value of RIN, we set the RWIN to
444 * RIN+RBUF_MAX-1, it sends us RWIN-ROUT bytes which overflows. ROUT
445 * is set to zero when the port is opened, so we start at zero and
446 * count up as data is received.
447 */
448 ushort ch_s_rwin; /* Realport RWIN */
449 ushort ch_s_rsize; /* Realport RSIZE */
450
451 ushort ch_tmax; /* Local TMAX */
452 ushort ch_ttime; /* Local TTIME */
453 ushort ch_rmax; /* Local RMAX */
454 ushort ch_rtime; /* Local RTIME */
455 ushort ch_rlow; /* Local RLOW */
456 ushort ch_rhigh; /* Local RHIGH */
457
458 ushort ch_s_tmax; /* Realport TMAX */
459 ushort ch_s_ttime; /* Realport TTIME */
460 ushort ch_s_rmax; /* Realport RMAX */
461 ushort ch_s_rtime; /* Realport RTIME */
462 ushort ch_s_rlow; /* Realport RLOW */
463 ushort ch_s_rhigh; /* Realport RHIGH */
464
465 ushort ch_brate; /* Local baud rate */
466 ushort ch_cflag; /* Local tty cflags */
467 ushort ch_iflag; /* Local tty iflags */
468 ushort ch_oflag; /* Local tty oflags */
469 ushort ch_xflag; /* Local tty xflags */
470
471 ushort ch_s_brate; /* Realport BRATE */
472 ushort ch_s_cflag; /* Realport CFLAG */
473 ushort ch_s_iflag; /* Realport IFLAG */
474 ushort ch_s_oflag; /* Realport OFLAG */
475 ushort ch_s_xflag; /* Realport XFLAG */
476
477 u8 ch_otype; /* Open request type */
478 u8 ch_pscan_savechar; /* Last character read by parity scan */
479 u8 ch_pscan_state; /* PScan State based on last 2 chars */
480 u8 ch_otype_waiting; /* Type of open pending in server */
481 u8 ch_flush_seq; /* Receive flush end sequence */
482 u8 ch_s_mlast; /* Realport MLAST */
483
484 u8 ch_mout; /* Local MOUT */
485 u8 ch_mflow; /* Local MFLOW */
486 u8 ch_mctrl; /* Local MCTRL */
487 u8 ch_xon; /* Local XON */
488 u8 ch_xoff; /* Local XOFF */
489 u8 ch_lnext; /* Local LNEXT */
490 u8 ch_xxon; /* Local XXON */
491 u8 ch_xxoff; /* Local XXOFF */
492
493 u8 ch_s_mout; /* Realport MOUT */
494 u8 ch_s_mflow; /* Realport MFLOW */
495 u8 ch_s_mctrl; /* Realport MCTRL */
496 u8 ch_s_xon; /* Realport XON */
497 u8 ch_s_xoff; /* Realport XOFF */
498 u8 ch_s_lnext; /* Realport LNEXT */
499 u8 ch_s_xxon; /* Realport XXON */
500 u8 ch_s_xxoff; /* Realport XXOFF */
501
502 wait_queue_head_t ch_flag_wait; /* Wait queue for ch_flag changes */
503 wait_queue_head_t ch_sleep; /* Wait queue for my_sleep() */
504
505 int ch_custom_speed; /* Realport custom speed */
506 int ch_txcount; /* Running TX count */
507 int ch_rxcount; /* Running RX count */
508};
509
510
511/************************************************************************
512 * Node State definitions.
513 ************************************************************************/
514
515enum dgrp_nd_state_t {
516 NS_CLOSED = 0, /* Network device is closed */
517 NS_IDLE = 1, /* Network connection inactive */
518 NS_SEND_QUERY = 2, /* Send server query */
519 NS_WAIT_QUERY = 3, /* Wait for query response */
520 NS_READY = 4, /* Network ready */
521 NS_SEND_ERROR = 5 /* Must send error hangup */
522};
523
524#define ND_STATE_STR(x) \
525 ((x) == NS_CLOSED ? "CLOSED" : \
526 ((x) == NS_IDLE ? "IDLE" : \
527 ((x) == NS_SEND_QUERY ? "SEND_QUERY" : \
528 ((x) == NS_WAIT_QUERY ? "WAIT_QUERY" : \
529 ((x) == NS_READY ? "READY" : \
530 ((x) == NS_SEND_ERROR ? "SEND_ERROR" : "UNKNOWN"))))))
531
532/************************************************************************
533 * Node Flag definitions.
534 ************************************************************************/
535
536#define ND_SELECT 0x0001 /* Multiple net read selects */
537#define ND_DEB_WAIT 0x0002 /* Debug Device waiting */
538
539
540/************************************************************************
541 * Monitoring flag definitions.
542 ************************************************************************/
543
544#define MON_WAIT_DATA 0x0001 /* Waiting for buffer data */
545#define MON_WAIT_SPACE 0x0002 /* Waiting for buffer space */
546
547/************************************************************************
548 * DPA flag definitions.
549 ************************************************************************/
550
551#define DPA_WAIT_DATA 0x0001 /* Waiting for buffer data */
552#define DPA_WAIT_SPACE 0x0002 /* Waiting for buffer space */
553
554
555/************************************************************************
556 * Definitions taken from Realport Dump.
557 ************************************************************************/
558
559#define RPDUMP_MAGIC "Digi-RealPort-1.0"
560
561#define RPDUMP_MESSAGE 0xE2 /* Descriptive message */
562#define RPDUMP_RESET 0xE7 /* Connection reset */
563#define RPDUMP_CLIENT 0xE8 /* Client data */
564#define RPDUMP_SERVER 0xE9 /* Server data */
565
566
567/************************************************************************
568 * Node request/response definitions.
569 ************************************************************************/
570
571#define NR_ECHO 0x0001 /* Server echo packet */
572#define NR_IDENT 0x0002 /* Server Product ID */
573#define NR_CAPABILITY 0x0004 /* Server Capabilties */
574#define NR_VPD 0x0008 /* Server VPD, if any */
575#define NR_PASSWORD 0x0010 /* Server Password */
576
577/************************************************************************
578 * Registration status of the node's Linux struct tty_driver structures.
579 ************************************************************************/
580#define SERIAL_TTDRV_REG 0x0001 /* nd_serial_ttdriver registered */
581#define CALLOUT_TTDRV_REG 0x0002 /* nd_callout_ttdriver registered */
582#define XPRINT_TTDRV_REG 0x0004 /* nd_xprint_ttdriver registered */
583
584
585/************************************************************************
586 * Node structure. There exists one of these for each associated
587 * realport server.
588 ************************************************************************/
589
590struct nd_struct {
591 struct list_head list;
592 long nd_major; /* Node's major number */
593 long nd_ID; /* Node's ID code */
594
595 char nd_serial_name[50]; /* "tty_dgrp_<id>_" + null */
596 char nd_callout_name[50]; /* "cu_dgrp_<id>_" + null */
597 char nd_xprint_name[50]; /* "pr_dgrp_<id>_" + null */
598
599 char password[16]; /* Password for server, if needed */
600 int nd_tty_ref_cnt; /* Linux tty reference count */
601
602 struct proc_dir_entry *nd_net_de; /* Dir entry for /proc/dgrp/net */
603 struct proc_dir_entry *nd_mon_de; /* Dir entry for /proc/dgrp/mon */
604 struct proc_dir_entry *nd_ports_de; /* Dir entry for /proc/dgrp/ports*/
605 struct proc_dir_entry *nd_dpa_de; /* Dir entry for /proc/dgrp/dpa */
606
607 spinlock_t nd_lock; /* General node lock */
608
609 struct semaphore nd_net_semaphore; /* Net read/write lock */
610 struct semaphore nd_mon_semaphore; /* Monitor buffer lock */
611 spinlock_t nd_dpa_lock; /* DPA buffer lock */
612
613 enum dgrp_nd_state_t nd_state; /* NS_* network state */
614 int nd_chan_count; /* # active channels */
615 int nd_flag; /* Node flags */
616 int nd_send; /* Responses to send */
617 int nd_expect; /* Responses we expect */
618
619 u8 *nd_iobuf; /* Network R/W Buffer */
620 wait_queue_head_t nd_tx_waitq; /* Network select wait queue */
621
622 u8 *nd_inputbuf; /* Input Buffer */
623 u8 *nd_inputflagbuf; /* Input Flags Buffer */
624
625 int nd_tx_deposit; /* Accumulated transmit deposits */
626 int nd_tx_charge; /* Accumulated transmit charges */
627 int nd_tx_credit; /* Current TX credit */
628 int nd_tx_ready; /* Ready to transmit */
629 int nd_tx_work; /* TX work waiting */
630 ulong nd_tx_time; /* Last transmit time */
631 ulong nd_poll_time; /* Next scheduled poll time */
632
633 int nd_delay; /* Current TX delay */
634 int nd_rate; /* Current TX rate */
635 struct link_struct nd_link; /* Link speed params. */
636
637 int nd_seq_in; /* TX seq in ptr */
638 int nd_seq_out; /* TX seq out ptr */
639 int nd_unack; /* Unacknowledged byte count */
640 int nd_remain; /* Remaining receive bytes */
641 int nd_tx_module; /* Current TX module # */
642 int nd_rx_module; /* Current RX module # */
643 char *nd_error; /* Protocol error message */
644
645 int nd_write_count; /* drp_write() call count */
646 int nd_read_count; /* drp_read() count */
647 int nd_send_count; /* TCP message sent */
648 int nd_tx_byte; /* Transmit byte count */
649 int nd_rx_byte; /* Receive byte count */
650
651 ulong nd_mon_lbolt; /* Monitor start time */
652 int nd_mon_flag; /* Monitor flags */
653 int nd_mon_in; /* Monitor in pointer */
654 int nd_mon_out; /* Monitor out pointer */
655 wait_queue_head_t nd_mon_wqueue; /* Monitor wait queue (on flags) */
656 u8 *nd_mon_buf; /* Monitor buffer */
657
658 ulong nd_dpa_lbolt; /* DPA start time */
659 int nd_dpa_flag; /* DPA flags */
660 int nd_dpa_in; /* DPA in pointer */
661 int nd_dpa_out; /* DPA out pointer */
662 wait_queue_head_t nd_dpa_wqueue; /* DPA wait queue (on flags) */
663 u8 *nd_dpa_buf; /* DPA buffer */
664
665 uint nd_dpa_debug;
666 uint nd_dpa_port;
667
668 wait_queue_head_t nd_seq_wque[SEQ_MAX]; /* TX thread wait queues */
669 u8 nd_seq_wait[SEQ_MAX]; /* Transmit thread wait count */
670
671 ushort nd_seq_size[SEQ_MAX]; /* Transmit seq packet size */
672 ulong nd_seq_time[SEQ_MAX]; /* Transmit seq packet time */
673
674 ushort nd_hw_ver; /* HW version returned from PS */
675 ushort nd_sw_ver; /* SW version returned from PS */
676 uint nd_hw_id; /* HW ID returned from PS */
677 u8 nd_ps_desc[MAX_DESC_LEN+1]; /* Description from PS */
678 uint nd_vpd_len; /* VPD len, if any */
679 u8 nd_vpd[VPDSIZE]; /* VPD, if any */
680
681 ulong nd_ttdriver_flags; /* Registration status */
682 struct tty_driver *nd_serial_ttdriver; /* Linux TTYDRIVER structure */
683 struct tty_driver *nd_callout_ttdriver; /* Linux TTYDRIVER structure */
684 struct tty_driver *nd_xprint_ttdriver; /* Linux TTYDRIVER structure */
685
686 u8 *nd_writebuf; /* Used to cache data read
687 * from user
688 */
689 struct ch_struct nd_chan[CHAN_MAX]; /* Channel array */
690 struct device *nd_class_dev; /* Hang our sysfs stuff off of here */
691};
692
693#endif /* __DRP_H */