- Linus: drop support for old-style Makefiles entirely. Big.
[davej-history.git] / net / x25 / x25_timer.c
blob20672419e623c54a16cda1bf2d330c5911fc7a9c
1 /*
2 * X.25 Packet Layer release 002
4 * This is ALPHA test software. This code may break your machine, randomly fail to work with new
5 * releases, misbehave and/or generally screw up. It might even work.
7 * This code REQUIRES 2.1.15 or higher
9 * This module:
10 * This module is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
15 * History
16 * X.25 001 Jonathan Naylor Started coding.
17 * X.25 002 Jonathan Naylor New timer architecture.
18 * Centralised disconnection processing.
21 #include <linux/config.h>
22 #if defined(CONFIG_X25) || defined(CONFIG_X25_MODULE)
23 #include <linux/errno.h>
24 #include <linux/types.h>
25 #include <linux/socket.h>
26 #include <linux/in.h>
27 #include <linux/kernel.h>
28 #include <linux/sched.h>
29 #include <linux/timer.h>
30 #include <linux/string.h>
31 #include <linux/sockios.h>
32 #include <linux/net.h>
33 #include <linux/inet.h>
34 #include <linux/netdevice.h>
35 #include <linux/skbuff.h>
36 #include <net/sock.h>
37 #include <asm/segment.h>
38 #include <asm/system.h>
39 #include <linux/fcntl.h>
40 #include <linux/mm.h>
41 #include <linux/interrupt.h>
42 #include <net/x25.h>
44 static void x25_heartbeat_expiry(unsigned long);
45 static void x25_timer_expiry(unsigned long);
47 void x25_start_heartbeat(struct sock *sk)
49 del_timer(&sk->timer);
51 sk->timer.data = (unsigned long)sk;
52 sk->timer.function = &x25_heartbeat_expiry;
53 sk->timer.expires = jiffies + 5 * HZ;
55 add_timer(&sk->timer);
58 void x25_stop_heartbeat(struct sock *sk)
60 del_timer(&sk->timer);
63 void x25_start_t2timer(struct sock *sk)
65 del_timer(&sk->protinfo.x25->timer);
67 sk->protinfo.x25->timer.data = (unsigned long)sk;
68 sk->protinfo.x25->timer.function = &x25_timer_expiry;
69 sk->protinfo.x25->timer.expires = jiffies + sk->protinfo.x25->t2;
71 add_timer(&sk->protinfo.x25->timer);
74 void x25_start_t21timer(struct sock *sk)
76 del_timer(&sk->protinfo.x25->timer);
78 sk->protinfo.x25->timer.data = (unsigned long)sk;
79 sk->protinfo.x25->timer.function = &x25_timer_expiry;
80 sk->protinfo.x25->timer.expires = jiffies + sk->protinfo.x25->t21;
82 add_timer(&sk->protinfo.x25->timer);
85 void x25_start_t22timer(struct sock *sk)
87 del_timer(&sk->protinfo.x25->timer);
89 sk->protinfo.x25->timer.data = (unsigned long)sk;
90 sk->protinfo.x25->timer.function = &x25_timer_expiry;
91 sk->protinfo.x25->timer.expires = jiffies + sk->protinfo.x25->t22;
93 add_timer(&sk->protinfo.x25->timer);
96 void x25_start_t23timer(struct sock *sk)
98 del_timer(&sk->protinfo.x25->timer);
100 sk->protinfo.x25->timer.data = (unsigned long)sk;
101 sk->protinfo.x25->timer.function = &x25_timer_expiry;
102 sk->protinfo.x25->timer.expires = jiffies + sk->protinfo.x25->t23;
104 add_timer(&sk->protinfo.x25->timer);
107 void x25_stop_timer(struct sock *sk)
109 del_timer(&sk->protinfo.x25->timer);
112 unsigned long x25_display_timer(struct sock *sk)
114 if (!timer_pending(&sk->protinfo.x25->timer))
115 return 0;
117 return sk->protinfo.x25->timer.expires - jiffies;
120 static void x25_heartbeat_expiry(unsigned long param)
122 struct sock *sk = (struct sock *)param;
124 switch (sk->protinfo.x25->state) {
126 case X25_STATE_0:
127 /* Magic here: If we listen() and a new link dies before it
128 is accepted() it isn't 'dead' so doesn't get removed. */
129 if (sk->destroy || (sk->state == TCP_LISTEN && sk->dead)) {
130 x25_destroy_socket(sk);
131 return;
133 break;
135 case X25_STATE_3:
137 * Check for the state of the receive buffer.
139 if (atomic_read(&sk->rmem_alloc) < (sk->rcvbuf / 2) &&
140 (sk->protinfo.x25->condition & X25_COND_OWN_RX_BUSY)) {
141 sk->protinfo.x25->condition &= ~X25_COND_OWN_RX_BUSY;
142 sk->protinfo.x25->condition &= ~X25_COND_ACK_PENDING;
143 sk->protinfo.x25->vl = sk->protinfo.x25->vr;
144 x25_write_internal(sk, X25_RR);
145 x25_stop_timer(sk);
146 break;
148 break;
151 x25_start_heartbeat(sk);
155 * Timer has expired, it may have been T2, T21, T22, or T23. We can tell
156 * by the state machine state.
158 static void x25_timer_expiry(unsigned long param)
160 struct sock *sk = (struct sock *)param;
162 switch (sk->protinfo.x25->state) {
164 case X25_STATE_3: /* T2 */
165 if (sk->protinfo.x25->condition & X25_COND_ACK_PENDING) {
166 sk->protinfo.x25->condition &= ~X25_COND_ACK_PENDING;
167 x25_enquiry_response(sk);
169 break;
171 case X25_STATE_1: /* T21 */
172 case X25_STATE_4: /* T22 */
173 x25_write_internal(sk, X25_CLEAR_REQUEST);
174 sk->protinfo.x25->state = X25_STATE_2;
175 x25_start_t23timer(sk);
176 break;
178 case X25_STATE_2: /* T23 */
179 x25_disconnect(sk, ETIMEDOUT, 0, 0);
180 break;
184 #endif