Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
staging
dgrp
dgrp_common.c
Go to the documentation of this file.
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
47
void
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
180
int
dgrp_chk_perm
(
int
mode
,
int
op
)
181
{
182
if
(!uid_eq(
GLOBAL_ROOT_UID
,
current_euid
()))
183
mode >>= 6;
184
else
if
(
in_egroup_p
(
GLOBAL_ROOT_GID
))
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 */
197
int
dgrp_inode_permission
(
struct
inode
*
inode
,
int
op
)
198
{
199
return
dgrp_chk_perm
(inode->
i_mode
, op);
200
}
Generated on Thu Jan 10 2013 14:28:08 for Linux Kernel by
1.8.2