* add p cc
[mascara-docs.git] / i386 / linux / linux-2.3.21 / net / x25 / x25_timer.c
blob90b6513c93c2e528eb96beab6ecb83d7defa655a
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 (sk->protinfo.x25->timer.prev == NULL &&
115 sk->protinfo.x25->timer.next == NULL)
116 return 0;
118 return sk->protinfo.x25->timer.expires - jiffies;
121 static void x25_heartbeat_expiry(unsigned long param)
123 struct sock *sk = (struct sock *)param;
125 switch (sk->protinfo.x25->state) {
127 case X25_STATE_0:
128 /* Magic here: If we listen() and a new link dies before it
129 is accepted() it isn't 'dead' so doesn't get removed. */
130 if (sk->destroy || (sk->state == TCP_LISTEN && sk->dead)) {
131 x25_destroy_socket(sk);
132 return;
134 break;
136 case X25_STATE_3:
138 * Check for the state of the receive buffer.
140 if (atomic_read(&sk->rmem_alloc) < (sk->rcvbuf / 2) &&
141 (sk->protinfo.x25->condition & X25_COND_OWN_RX_BUSY)) {
142 sk->protinfo.x25->condition &= ~X25_COND_OWN_RX_BUSY;
143 sk->protinfo.x25->condition &= ~X25_COND_ACK_PENDING;
144 sk->protinfo.x25->vl = sk->protinfo.x25->vr;
145 x25_write_internal(sk, X25_RR);
146 x25_stop_timer(sk);
147 break;
149 break;
152 x25_start_heartbeat(sk);
156 * Timer has expired, it may have been T2, T21, T22, or T23. We can tell
157 * by the state machine state.
159 static void x25_timer_expiry(unsigned long param)
161 struct sock *sk = (struct sock *)param;
163 switch (sk->protinfo.x25->state) {
165 case X25_STATE_3: /* T2 */
166 if (sk->protinfo.x25->condition & X25_COND_ACK_PENDING) {
167 sk->protinfo.x25->condition &= ~X25_COND_ACK_PENDING;
168 x25_enquiry_response(sk);
170 break;
172 case X25_STATE_1: /* T21 */
173 case X25_STATE_4: /* T22 */
174 x25_write_internal(sk, X25_CLEAR_REQUEST);
175 sk->protinfo.x25->state = X25_STATE_2;
176 x25_start_t23timer(sk);
177 break;
179 case X25_STATE_2: /* T23 */
180 x25_disconnect(sk, ETIMEDOUT, 0, 0);
181 break;
185 #endif