3 * Copyright 1999 Digi International (www.digi.com)
4 * James Puzzo <jamesp at digi dot com>
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)
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.
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).
36 #include <linux/errno.h>
37 #include <linux/tty.h>
38 #include <linux/sched.h>
39 #include <linux/cred.h>
41 #include "dgrp_common.h"
44 * dgrp_carrier -- check for carrier change state and act
45 * @ch: struct ch_struct *
47 void dgrp_carrier(struct ch_struct *ch)
54 /* fix case when the tty has already closed. */
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.
70 if (ch->ch_expect & RR_STATUS)
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.
78 if ((ch->ch_flag & CH_HANGUP) &&
79 (ch->ch_tun.un_open_count > 0))
80 tty_hangup(ch->ch_tun.un_tty);
83 * Compute the effective state of both the physical and virtual
87 if (ch->ch_s_mlast & DM_CD)
90 if ((ch->ch_s_mlast & DM_CD) ||
91 (ch->ch_digi.digi_flags & DIGI_FORCEDCD) ||
92 (ch->ch_flag & CH_CLOCAL))
96 * Test for a VIRTUAL carrier transition to HIGH.
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.
102 if (((ch->ch_flag & CH_HANGUP) == 0) &&
103 ((ch->ch_flag & CH_VIRT_CD) == 0) &&
104 (virt_carrier == 1)) {
106 * When carrier rises, wake any threads waiting
107 * for carrier in the open routine.
111 if (waitqueue_active(&ch->ch_flag_wait))
112 wake_up_interruptible(&ch->ch_flag_wait);
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).
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".
124 if ((virt_carrier == 0) &&
125 ((ch->ch_flag & CH_PHYS_CD) != 0) &&
126 (phys_carrier == 0)) {
128 * When carrier drops:
130 * Do a Hard Hangup if that is called for.
132 * Drop carrier on all open units.
134 * Flush queues, waking up any task waiting in the
137 * Send a hangup to the control terminal.
139 * Enable all select calls.
144 ch->ch_flag &= ~(CH_LOW | CH_EMPTY | CH_DRAIN | CH_INPUT);
146 if (waitqueue_active(&ch->ch_flag_wait))
147 wake_up_interruptible(&ch->ch_flag_wait);
149 if (ch->ch_tun.un_open_count > 0)
150 tty_hangup(ch->ch_tun.un_tty);
152 if (ch->ch_pun.un_open_count > 0)
153 tty_hangup(ch->ch_pun.un_tty);
157 * Make sure that our cached values reflect the current reality.
159 if (virt_carrier == 1)
160 ch->ch_flag |= CH_VIRT_CD;
162 ch->ch_flag &= ~CH_VIRT_CD;
164 if (phys_carrier == 1)
165 ch->ch_flag |= CH_PHYS_CD;
167 ch->ch_flag &= ~CH_PHYS_CD;