~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/net/rose/rose_timer.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *      ROSE release 003
  3  *
  4  *      This code REQUIRES 2.1.15 or higher/ NET3.038
  5  *
  6  *      This module:
  7  *              This module is free software; you can redistribute it and/or
  8  *              modify it under the terms of the GNU General Public License
  9  *              as published by the Free Software Foundation; either version
 10  *              2 of the License, or (at your option) any later version.
 11  *
 12  *      History
 13  *      ROSE 001        Jonathan(G4KLX) Cloned from nr_timer.c
 14  *      ROSE 003        Jonathan(G4KLX) New timer architecture.
 15  *                                      Implemented idle timer.
 16  */
 17 
 18 #include <linux/errno.h>
 19 #include <linux/types.h>
 20 #include <linux/socket.h>
 21 #include <linux/in.h>
 22 #include <linux/kernel.h>
 23 #include <linux/sched.h>
 24 #include <linux/timer.h>
 25 #include <linux/string.h>
 26 #include <linux/sockios.h>
 27 #include <linux/net.h>
 28 #include <net/ax25.h>
 29 #include <linux/inet.h>
 30 #include <linux/netdevice.h>
 31 #include <linux/skbuff.h>
 32 #include <net/sock.h>
 33 #include <asm/segment.h>
 34 #include <asm/system.h>
 35 #include <linux/fcntl.h>
 36 #include <linux/mm.h>
 37 #include <linux/interrupt.h>
 38 #include <net/rose.h>
 39 
 40 static void rose_heartbeat_expiry(unsigned long);
 41 static void rose_timer_expiry(unsigned long);
 42 static void rose_idletimer_expiry(unsigned long);
 43 
 44 void rose_start_heartbeat(struct sock *sk)
 45 {
 46         del_timer(&sk->timer);
 47 
 48         sk->timer.data     = (unsigned long)sk;
 49         sk->timer.function = &rose_heartbeat_expiry;
 50         sk->timer.expires  = jiffies + 5 * HZ;
 51 
 52         add_timer(&sk->timer);
 53 }
 54 
 55 void rose_start_t1timer(struct sock *sk)
 56 {
 57         del_timer(&sk->protinfo.rose->timer);
 58 
 59         sk->protinfo.rose->timer.data     = (unsigned long)sk;
 60         sk->protinfo.rose->timer.function = &rose_timer_expiry;
 61         sk->protinfo.rose->timer.expires  = jiffies + sk->protinfo.rose->t1;
 62 
 63         add_timer(&sk->protinfo.rose->timer);
 64 }
 65 
 66 void rose_start_t2timer(struct sock *sk)
 67 {
 68         del_timer(&sk->protinfo.rose->timer);
 69 
 70         sk->protinfo.rose->timer.data     = (unsigned long)sk;
 71         sk->protinfo.rose->timer.function = &rose_timer_expiry;
 72         sk->protinfo.rose->timer.expires  = jiffies + sk->protinfo.rose->t2;
 73 
 74         add_timer(&sk->protinfo.rose->timer);
 75 }
 76 
 77 void rose_start_t3timer(struct sock *sk)
 78 {
 79         del_timer(&sk->protinfo.rose->timer);
 80 
 81         sk->protinfo.rose->timer.data     = (unsigned long)sk;
 82         sk->protinfo.rose->timer.function = &rose_timer_expiry;
 83         sk->protinfo.rose->timer.expires  = jiffies + sk->protinfo.rose->t3;
 84 
 85         add_timer(&sk->protinfo.rose->timer);
 86 }
 87 
 88 void rose_start_hbtimer(struct sock *sk)
 89 {
 90         del_timer(&sk->protinfo.rose->timer);
 91 
 92         sk->protinfo.rose->timer.data     = (unsigned long)sk;
 93         sk->protinfo.rose->timer.function = &rose_timer_expiry;
 94         sk->protinfo.rose->timer.expires  = jiffies + sk->protinfo.rose->hb;
 95 
 96         add_timer(&sk->protinfo.rose->timer);
 97 }
 98 
 99 void rose_start_idletimer(struct sock *sk)
100 {
101         del_timer(&sk->protinfo.rose->idletimer);
102 
103         if (sk->protinfo.rose->idle > 0) {
104                 sk->protinfo.rose->idletimer.data     = (unsigned long)sk;
105                 sk->protinfo.rose->idletimer.function = &rose_idletimer_expiry;
106                 sk->protinfo.rose->idletimer.expires  = jiffies + sk->protinfo.rose->idle;
107 
108                 add_timer(&sk->protinfo.rose->idletimer);
109         }
110 }
111 
112 void rose_stop_heartbeat(struct sock *sk)
113 {
114         del_timer(&sk->timer);
115 }
116 
117 void rose_stop_timer(struct sock *sk)
118 {
119         del_timer(&sk->protinfo.rose->timer);
120 }
121 
122 void rose_stop_idletimer(struct sock *sk)
123 {
124         del_timer(&sk->protinfo.rose->idletimer);
125 }
126 
127 static void rose_heartbeat_expiry(unsigned long param)
128 {
129         struct sock *sk = (struct sock *)param;
130 
131         switch (sk->protinfo.rose->state) {
132 
133                 case ROSE_STATE_0:
134                         /* Magic here: If we listen() and a new link dies before it
135                            is accepted() it isn't 'dead' so doesn't get removed. */
136                         if (sk->destroy || (sk->state == TCP_LISTEN && sk->dead)) {
137                                 rose_destroy_socket(sk);
138                                 return;
139                         }
140                         break;
141 
142                 case ROSE_STATE_3:
143                         /*
144                          * Check for the state of the receive buffer.
145                          */
146                         if (atomic_read(&sk->rmem_alloc) < (sk->rcvbuf / 2) &&
147                             (sk->protinfo.rose->condition & ROSE_COND_OWN_RX_BUSY)) {
148                                 sk->protinfo.rose->condition &= ~ROSE_COND_OWN_RX_BUSY;
149                                 sk->protinfo.rose->condition &= ~ROSE_COND_ACK_PENDING;
150                                 sk->protinfo.rose->vl         = sk->protinfo.rose->vr;
151                                 rose_write_internal(sk, ROSE_RR);
152                                 rose_stop_timer(sk);    /* HB */
153                                 break;
154                         }
155                         break;
156         }
157 
158         rose_start_heartbeat(sk);
159 }
160 
161 static void rose_timer_expiry(unsigned long param)
162 {
163         struct sock *sk = (struct sock *)param;
164 
165         switch (sk->protinfo.rose->state) {
166 
167                 case ROSE_STATE_1:      /* T1 */
168                 case ROSE_STATE_4:      /* T2 */
169                         rose_write_internal(sk, ROSE_CLEAR_REQUEST);
170                         sk->protinfo.rose->state = ROSE_STATE_2;
171                         rose_start_t3timer(sk);
172                         break;
173 
174                 case ROSE_STATE_2:      /* T3 */
175                         sk->protinfo.rose->neighbour->use--;
176                         rose_disconnect(sk, ETIMEDOUT, -1, -1);
177                         break;
178 
179                 case ROSE_STATE_3:      /* HB */
180                         if (sk->protinfo.rose->condition & ROSE_COND_ACK_PENDING) {
181                                 sk->protinfo.rose->condition &= ~ROSE_COND_ACK_PENDING;
182                                 rose_enquiry_response(sk);
183                         }
184                         break;
185         }
186 }
187 
188 static void rose_idletimer_expiry(unsigned long param)
189 {
190         struct sock *sk = (struct sock *)param;
191 
192         rose_clear_queues(sk);
193 
194         rose_write_internal(sk, ROSE_CLEAR_REQUEST);
195         sk->protinfo.rose->state = ROSE_STATE_2;
196 
197         rose_start_t3timer(sk);
198 
199         sk->state     = TCP_CLOSE;
200         sk->err       = 0;
201         sk->shutdown |= SEND_SHUTDOWN;  
202 
203         if (!sk->dead)
204                 sk->state_change(sk);
205 
206         sk->dead = 1;
207 }
208 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.