import of ftp.dlink.com/GPL/DSMG-600_reB/ppclinux.tar.gz
[linux-2.4.21-pre4.git] / drivers / char / n_hdlc.c
1 /* generic HDLC line discipline for Linux
2  *
3  * Written by Paul Fulghum paulkf@microgate.com
4  * for Microgate Corporation
5  *
6  * Microgate and SyncLink are registered trademarks of Microgate Corporation
7  *
8  * Adapted from ppp.c, written by Michael Callahan <callahan@maths.ox.ac.uk>,
9  *      Al Longyear <longyear@netcom.com>, Paul Mackerras <Paul.Mackerras@cs.anu.edu.au>
10  *
11  * Original release 01/11/99
12  * $Id: n_hdlc.c,v 1.1.1.1 2005/04/11 02:50:17 jack Exp $
13  *
14  * This code is released under the GNU General Public License (GPL)
15  *
16  * This module implements the tty line discipline N_HDLC for use with
17  * tty device drivers that support bit-synchronous HDLC communications.
18  *
19  * All HDLC data is frame oriented which means:
20  *
21  * 1. tty write calls represent one complete transmit frame of data
22  *    The device driver should accept the complete frame or none of 
23  *    the frame (busy) in the write method. Each write call should have
24  *    a byte count in the range of 2-65535 bytes (2 is min HDLC frame
25  *    with 1 addr byte and 1 ctrl byte). The max byte count of 65535
26  *    should include any crc bytes required. For example, when using
27  *    CCITT CRC32, 4 crc bytes are required, so the maximum size frame
28  *    the application may transmit is limited to 65531 bytes. For CCITT
29  *    CRC16, the maximum application frame size would be 65533.
30  *
31  *
32  * 2. receive callbacks from the device driver represents
33  *    one received frame. The device driver should bypass
34  *    the tty flip buffer and call the line discipline receive
35  *    callback directly to avoid fragmenting or concatenating
36  *    multiple frames into a single receive callback.
37  *
38  *    The HDLC line discipline queues the receive frames in seperate
39  *    buffers so complete receive frames can be returned by the
40  *    tty read calls.
41  *
42  * 3. tty read calls returns an entire frame of data or nothing.
43  *    
44  * 4. all send and receive data is considered raw. No processing
45  *    or translation is performed by the line discipline, regardless
46  *    of the tty flags
47  *
48  * 5. When line discipline is queried for the amount of receive
49  *    data available (FIOC), 0 is returned if no data available,
50  *    otherwise the count of the next available frame is returned.
51  *    (instead of the sum of all received frame counts).
52  *
53  * These conventions allow the standard tty programming interface
54  * to be used for synchronous HDLC applications when used with
55  * this line discipline (or another line discipline that is frame
56  * oriented such as N_PPP).
57  *
58  * The SyncLink driver (synclink.c) implements both asynchronous
59  * (using standard line discipline N_TTY) and synchronous HDLC
60  * (using N_HDLC) communications, with the latter using the above
61  * conventions.
62  *
63  * This implementation is very basic and does not maintain
64  * any statistics. The main point is to enforce the raw data
65  * and frame orientation of HDLC communications.
66  *
67  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
68  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
69  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
70  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
71  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
72  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
73  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
74  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
75  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
76  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
77  * OF THE POSSIBILITY OF SUCH DAMAGE.
78  */
79
80 #define HDLC_MAGIC 0x239e
81 #define HDLC_VERSION "$Revision: 1.1.1.1 $"
82
83 #include <linux/version.h>
84 #include <linux/config.h>
85 #include <linux/module.h>
86 #include <linux/init.h>
87 #include <linux/kernel.h>
88 #include <linux/sched.h>
89 #include <linux/types.h>
90 #include <linux/fcntl.h>
91 #include <linux/interrupt.h>
92 #include <linux/ptrace.h>
93
94 #undef VERSION
95 #define VERSION(major,minor,patch) (((((major)<<8)+(minor))<<8)+(patch))
96
97 #include <linux/poll.h>
98 #include <linux/in.h>
99 #include <linux/slab.h>
100 #include <linux/tty.h>
101 #include <linux/errno.h>
102 #include <linux/string.h>       /* used in new tty drivers */
103 #include <linux/signal.h>       /* used in new tty drivers */
104 #include <asm/system.h>
105 #include <asm/bitops.h>
106 #include <asm/termios.h>
107 #include <linux/if.h>
108
109 #include <linux/ioctl.h>
110
111 #ifdef CONFIG_KERNELD
112 #include <linux/kerneld.h>
113 #endif
114
115 #include <asm/segment.h>
116 #define GET_USER(error,value,addr) error = get_user(value,addr)
117 #define COPY_FROM_USER(error,dest,src,size) error = copy_from_user(dest,src,size) ? -EFAULT : 0
118 #define PUT_USER(error,value,addr) error = put_user(value,addr)
119 #define COPY_TO_USER(error,dest,src,size) error = copy_to_user(dest,src,size) ? -EFAULT : 0
120
121 #include <asm/uaccess.h>
122
123 typedef ssize_t         rw_ret_t;
124 typedef size_t          rw_count_t;
125
126 /*
127  * Buffers for individual HDLC frames
128  */
129 #define MAX_HDLC_FRAME_SIZE 65535 
130 #define DEFAULT_RX_BUF_COUNT 10
131 #define MAX_RX_BUF_COUNT 60
132 #define DEFAULT_TX_BUF_COUNT 1
133
134
135 typedef struct _n_hdlc_buf
136 {
137         struct _n_hdlc_buf *link;
138         int count;
139         char buf[1];
140 } N_HDLC_BUF;
141
142 #define N_HDLC_BUF_SIZE (sizeof(N_HDLC_BUF)+maxframe)
143
144 typedef struct _n_hdlc_buf_list
145 {
146         N_HDLC_BUF *head;
147         N_HDLC_BUF *tail;
148         int count;
149         spinlock_t spinlock;
150         
151 } N_HDLC_BUF_LIST;
152
153 /*
154  * Per device instance data structure
155  */
156 struct n_hdlc {
157         int             magic;          /* magic value for structure    */
158         __u32           flags;          /* miscellaneous control flags  */
159         
160         struct tty_struct *tty;         /* ptr to TTY structure */
161         struct tty_struct *backup_tty;  /* TTY to use if tty gets closed */
162         
163         int             tbusy;          /* reentrancy flag for tx wakeup code */
164         int             woke_up;
165         N_HDLC_BUF      *tbuf;          /* currently transmitting tx buffer */
166         N_HDLC_BUF_LIST tx_buf_list;    /* list of pending transmit frame buffers */    
167         N_HDLC_BUF_LIST rx_buf_list;    /* list of received frame buffers */
168         N_HDLC_BUF_LIST tx_free_buf_list;       /* list unused transmit frame buffers */        
169         N_HDLC_BUF_LIST rx_free_buf_list;       /* list unused received frame buffers */
170 };
171
172 /*
173  * HDLC buffer list manipulation functions
174  */
175 void n_hdlc_buf_list_init(N_HDLC_BUF_LIST *list);
176 void n_hdlc_buf_put(N_HDLC_BUF_LIST *list,N_HDLC_BUF *buf);
177 N_HDLC_BUF* n_hdlc_buf_get(N_HDLC_BUF_LIST *list);
178
179 /* Local functions */
180
181 static struct n_hdlc *n_hdlc_alloc (void);
182
183 MODULE_PARM(debuglevel, "i");
184 MODULE_PARM(maxframe, "i");
185
186
187 /* debug level can be set by insmod for debugging purposes */
188 #define DEBUG_LEVEL_INFO        1
189 int debuglevel=0;
190
191 /* max frame size for memory allocations */
192 ssize_t maxframe=4096;
193
194 /* TTY callbacks */
195
196 static rw_ret_t n_hdlc_tty_read(struct tty_struct *,
197         struct file *, __u8 *, rw_count_t);
198 static rw_ret_t n_hdlc_tty_write(struct tty_struct *,
199         struct file *, const __u8 *, rw_count_t);
200 static int n_hdlc_tty_ioctl(struct tty_struct *,
201         struct file *, unsigned int, unsigned long);
202 static unsigned int n_hdlc_tty_poll (struct tty_struct *tty, struct file *filp,
203                                   poll_table * wait);
204 static int n_hdlc_tty_open (struct tty_struct *);
205 static void n_hdlc_tty_close (struct tty_struct *);
206 static int n_hdlc_tty_room (struct tty_struct *tty);
207 static void n_hdlc_tty_receive (struct tty_struct *tty,
208         const __u8 * cp, char *fp, int count);
209 static void n_hdlc_tty_wakeup (struct tty_struct *tty);
210
211 #define bset(p,b)       ((p)[(b) >> 5] |= (1 << ((b) & 0x1f)))
212
213 #define tty2n_hdlc(tty) ((struct n_hdlc *) ((tty)->disc_data))
214 #define n_hdlc2tty(n_hdlc)      ((n_hdlc)->tty)
215
216 /* Define this string only once for all macro invocations */
217 static char szVersion[] = HDLC_VERSION;
218
219 /* n_hdlc_release()
220  *
221  *      release an n_hdlc per device line discipline info structure
222  *
223  */
224 static void n_hdlc_release (struct n_hdlc *n_hdlc)
225 {
226         struct tty_struct *tty = n_hdlc2tty (n_hdlc);
227         N_HDLC_BUF *buf;
228         
229         if (debuglevel >= DEBUG_LEVEL_INFO)     
230                 printk("%s(%d)n_hdlc_release() called\n",__FILE__,__LINE__);
231                 
232         /* Ensure that the n_hdlcd process is not hanging on select()/poll() */
233         wake_up_interruptible (&tty->read_wait);
234         wake_up_interruptible (&tty->write_wait);
235
236         if (tty != NULL && tty->disc_data == n_hdlc)
237                 tty->disc_data = NULL;  /* Break the tty->n_hdlc link */
238
239         /* Release transmit and receive buffers */
240         for(;;) {
241                 buf = n_hdlc_buf_get(&n_hdlc->rx_free_buf_list);
242                 if (buf) {
243                         kfree(buf);
244                 } else
245                         break;
246         }
247         for(;;) {
248                 buf = n_hdlc_buf_get(&n_hdlc->tx_free_buf_list);
249                 if (buf) {
250                         kfree(buf);
251                 } else
252                         break;
253         }
254         for(;;) {
255                 buf = n_hdlc_buf_get(&n_hdlc->rx_buf_list);
256                 if (buf) {
257                         kfree(buf);
258                 } else
259                         break;
260         }
261         for(;;) {
262                 buf = n_hdlc_buf_get(&n_hdlc->tx_buf_list);
263                 if (buf) {
264                         kfree(buf);
265                 } else
266                         break;
267         }
268         
269         kfree(n_hdlc);
270         
271 }       /* end of n_hdlc_release() */
272
273 /* n_hdlc_tty_close()
274  *
275  *      Called when the line discipline is changed to something
276  *      else, the tty is closed, or the tty detects a hangup.
277  */
278 static void n_hdlc_tty_close(struct tty_struct *tty)
279 {
280         struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
281
282         if (debuglevel >= DEBUG_LEVEL_INFO)     
283                 printk("%s(%d)n_hdlc_tty_close() called\n",__FILE__,__LINE__);
284                 
285         if (n_hdlc != NULL) {
286                 if (n_hdlc->magic != HDLC_MAGIC) {
287                         printk (KERN_WARNING"n_hdlc: trying to close unopened tty!\n");
288                         return;
289                 }
290 #if defined(TTY_NO_WRITE_SPLIT)
291                 clear_bit(TTY_NO_WRITE_SPLIT,&tty->flags);
292 #endif
293                 tty->disc_data = NULL;
294                 if (tty == n_hdlc->backup_tty)
295                         n_hdlc->backup_tty = 0;
296                 if (tty != n_hdlc->tty)
297                         return;
298                 if (n_hdlc->backup_tty) {
299                         n_hdlc->tty = n_hdlc->backup_tty;
300                 } else {
301                         n_hdlc_release (n_hdlc);
302                         MOD_DEC_USE_COUNT;
303                 }
304         }
305         
306         if (debuglevel >= DEBUG_LEVEL_INFO)     
307                 printk("%s(%d)n_hdlc_tty_close() success\n",__FILE__,__LINE__);
308                 
309 }       /* end of n_hdlc_tty_close() */
310
311 /* n_hdlc_tty_open
312  * 
313  *      called when line discipline changed to n_hdlc
314  *      
315  * Arguments:   tty     pointer to tty info structure
316  * Return Value:        0 if success, otherwise error code
317  */
318 static int n_hdlc_tty_open (struct tty_struct *tty)
319 {
320         struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
321
322         if (debuglevel >= DEBUG_LEVEL_INFO)     
323                 printk("%s(%d)n_hdlc_tty_open() called (major=%u,minor=%u)\n",
324                 __FILE__,__LINE__,
325                 MAJOR(tty->device), MINOR(tty->device));
326                 
327         /* There should not be an existing table for this slot. */
328         if (n_hdlc) {
329                 printk (KERN_ERR"n_hdlc_tty_open:tty already associated!\n" );
330                 return -EEXIST;
331         }
332         
333         n_hdlc = n_hdlc_alloc();
334         if (!n_hdlc) {
335                 printk (KERN_ERR "n_hdlc_alloc failed\n");
336                 return -ENFILE;
337         }
338                 
339         tty->disc_data = n_hdlc;
340         n_hdlc->tty    = tty;
341         
342         MOD_INC_USE_COUNT;
343         
344 #if defined(TTY_NO_WRITE_SPLIT)
345         /* change tty_io write() to not split large writes into 8K chunks */
346         set_bit(TTY_NO_WRITE_SPLIT,&tty->flags);
347 #endif
348         
349         /* Flush any pending characters in the driver and discipline. */
350         
351         if (tty->ldisc.flush_buffer)
352                 tty->ldisc.flush_buffer (tty);
353
354         if (tty->driver.flush_buffer)
355                 tty->driver.flush_buffer (tty);
356                 
357         if (debuglevel >= DEBUG_LEVEL_INFO)     
358                 printk("%s(%d)n_hdlc_tty_open() success\n",__FILE__,__LINE__);
359                 
360         return 0;
361         
362 }       /* end of n_tty_hdlc_open() */
363
364 /* n_hdlc_send_frames()
365  * 
366  *      send frames on pending send buffer list until the
367  *      driver does not accept a frame (busy)
368  *      this function is called after adding a frame to the
369  *      send buffer list and by the tty wakeup callback
370  *      
371  * Arguments:           n_hdlc          pointer to ldisc instance data
372  *                      tty             pointer to tty instance data
373  * Return Value:        None
374  */
375 static void n_hdlc_send_frames (struct n_hdlc *n_hdlc, struct tty_struct *tty)
376 {
377         register int actual;
378         unsigned long flags;
379         N_HDLC_BUF *tbuf;
380
381         if (debuglevel >= DEBUG_LEVEL_INFO)     
382                 printk("%s(%d)n_hdlc_send_frames() called\n",__FILE__,__LINE__);
383  check_again:
384                 
385         save_flags(flags);
386         cli ();
387         if (n_hdlc->tbusy) {
388                 n_hdlc->woke_up = 1;
389                 restore_flags(flags);
390                 return;
391         }
392         n_hdlc->tbusy = 1;
393         n_hdlc->woke_up = 0;
394         restore_flags(flags);
395
396         /* get current transmit buffer or get new transmit */
397         /* buffer from list of pending transmit buffers */
398                 
399         tbuf = n_hdlc->tbuf;
400         if (!tbuf)
401                 tbuf = n_hdlc_buf_get(&n_hdlc->tx_buf_list);
402                 
403         while (tbuf) {
404                 if (debuglevel >= DEBUG_LEVEL_INFO)     
405                         printk("%s(%d)sending frame %p, count=%d\n",
406                                 __FILE__,__LINE__,tbuf,tbuf->count);
407                         
408                 /* Send the next block of data to device */
409                 tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
410                 actual = tty->driver.write(tty, 0, tbuf->buf, tbuf->count);
411                     
412                 /* if transmit error, throw frame away by */
413                 /* pretending it was accepted by driver */
414                 if (actual < 0)
415                         actual = tbuf->count;
416                 
417                 if (actual == tbuf->count) {
418                         if (debuglevel >= DEBUG_LEVEL_INFO)     
419                                 printk("%s(%d)frame %p completed\n",
420                                         __FILE__,__LINE__,tbuf);
421                                         
422                         /* free current transmit buffer */
423                         n_hdlc_buf_put(&n_hdlc->tx_free_buf_list,tbuf);
424                         
425                         /* this tx buffer is done */
426                         n_hdlc->tbuf = NULL;
427                         
428                         /* wait up sleeping writers */
429                         wake_up_interruptible(&tty->write_wait);
430         
431                         /* get next pending transmit buffer */
432                         tbuf = n_hdlc_buf_get(&n_hdlc->tx_buf_list);
433                 } else {
434                         if (debuglevel >= DEBUG_LEVEL_INFO)     
435                                 printk("%s(%d)frame %p pending\n",
436                                         __FILE__,__LINE__,tbuf);
437                                         
438                         /* buffer not accepted by driver */
439                         /* set this buffer as pending buffer */
440                         n_hdlc->tbuf = tbuf;
441                         break;
442                 }
443         }
444         
445         if (!tbuf)
446                 tty->flags  &= ~(1 << TTY_DO_WRITE_WAKEUP);
447         
448         /* Clear the re-entry flag */
449         save_flags(flags);
450         cli ();
451         n_hdlc->tbusy = 0;
452         restore_flags(flags);
453         
454         if (n_hdlc->woke_up)
455           goto check_again;
456
457         if (debuglevel >= DEBUG_LEVEL_INFO)     
458                 printk("%s(%d)n_hdlc_send_frames() exit\n",__FILE__,__LINE__);
459                 
460 }       /* end of n_hdlc_send_frames() */
461
462 /* n_hdlc_tty_wakeup()
463  *
464  *      Callback for transmit wakeup. Called when low level
465  *      device driver can accept more send data.
466  *
467  * Arguments:           tty     pointer to associated tty instance data
468  * Return Value:        None
469  */
470 static void n_hdlc_tty_wakeup (struct tty_struct *tty)
471 {
472         struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
473
474         if (debuglevel >= DEBUG_LEVEL_INFO)     
475                 printk("%s(%d)n_hdlc_tty_wakeup() called\n",__FILE__,__LINE__);
476                 
477         if (!n_hdlc)
478                 return;
479
480         if (tty != n_hdlc->tty) {
481                 tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
482                 return;
483         }
484
485         n_hdlc_send_frames (n_hdlc, tty);
486                 
487 }       /* end of n_hdlc_tty_wakeup() */
488
489 /* n_hdlc_tty_room()
490  * 
491  *      Callback function from tty driver. Return the amount of 
492  *      space left in the receiver's buffer to decide if remote
493  *      transmitter is to be throttled.
494  *
495  * Arguments:           tty     pointer to associated tty instance data
496  * Return Value:        number of bytes left in receive buffer
497  */
498 static int n_hdlc_tty_room (struct tty_struct *tty)
499 {
500         if (debuglevel >= DEBUG_LEVEL_INFO)     
501                 printk("%s(%d)n_hdlc_tty_room() called\n",__FILE__,__LINE__);
502         /* always return a larger number to prevent */
503         /* throttling of remote transmitter. */
504         return 65536;
505 }       /* end of n_hdlc_tty_root() */
506
507 /* n_hdlc_tty_receive()
508  * 
509  *      Called by tty low level driver when receive data is
510  *      available. Data is interpreted as one HDLC frame.
511  *      
512  * Arguments:           tty             pointer to tty isntance data
513  *                      data            pointer to received data
514  *                      flags           pointer to flags for data
515  *                      count           count of received data in bytes
516  *      
517  * Return Value:        None
518  */
519 static void n_hdlc_tty_receive(struct tty_struct *tty,
520         const __u8 * data, char *flags, int count)
521 {
522         register struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
523         register N_HDLC_BUF *buf;
524
525         if (debuglevel >= DEBUG_LEVEL_INFO)     
526                 printk("%s(%d)n_hdlc_tty_receive() called count=%d\n",
527                         __FILE__,__LINE__, count);
528                 
529         /* This can happen if stuff comes in on the backup tty */
530         if (n_hdlc == 0 || tty != n_hdlc->tty)
531                 return;
532                 
533         /* verify line is using HDLC discipline */
534         if (n_hdlc->magic != HDLC_MAGIC) {
535                 printk("%s(%d) line not using HDLC discipline\n",
536                         __FILE__,__LINE__);
537                 return;
538         }
539         
540         if ( count>maxframe ) {
541                 if (debuglevel >= DEBUG_LEVEL_INFO)     
542                         printk("%s(%d) rx count>maxframesize, data discarded\n",
543                                __FILE__,__LINE__);
544                 return;
545         }
546
547         /* get a free HDLC buffer */    
548         buf = n_hdlc_buf_get(&n_hdlc->rx_free_buf_list);
549         if (!buf) {
550                 /* no buffers in free list, attempt to allocate another rx buffer */
551                 /* unless the maximum count has been reached */
552                 if (n_hdlc->rx_buf_list.count < MAX_RX_BUF_COUNT)
553                         buf = (N_HDLC_BUF*)kmalloc(N_HDLC_BUF_SIZE,GFP_ATOMIC);
554         }
555         
556         if (!buf) {
557                 if (debuglevel >= DEBUG_LEVEL_INFO)     
558                         printk("%s(%d) no more rx buffers, data discarded\n",
559                                __FILE__,__LINE__);
560                 return;
561         }
562                 
563         /* copy received data to HDLC buffer */
564         memcpy(buf->buf,data,count);
565         buf->count=count;
566
567         /* add HDLC buffer to list of received frames */
568         n_hdlc_buf_put(&n_hdlc->rx_buf_list,buf);
569         
570         /* wake up any blocked reads and perform async signalling */
571         wake_up_interruptible (&tty->read_wait);
572         if (n_hdlc->tty->fasync != NULL)
573                 kill_fasync (&n_hdlc->tty->fasync, SIGIO, POLL_IN);
574
575 }       /* end of n_hdlc_tty_receive() */
576
577 /* n_hdlc_tty_read()
578  * 
579  *      Called to retreive one frame of data (if available)
580  *      
581  * Arguments:
582  * 
583  *      tty             pointer to tty instance data
584  *      file            pointer to open file object
585  *      buf             pointer to returned data buffer
586  *      nr              size of returned data buffer
587  *      
588  * Return Value:
589  * 
590  *      Number of bytes returned or error code
591  */
592 static rw_ret_t n_hdlc_tty_read (struct tty_struct *tty,
593         struct file *file, __u8 * buf, rw_count_t nr)
594 {
595         struct n_hdlc *n_hdlc = tty2n_hdlc(tty);
596         int error;
597         rw_ret_t ret;
598         N_HDLC_BUF *rbuf;
599
600         if (debuglevel >= DEBUG_LEVEL_INFO)     
601                 printk("%s(%d)n_hdlc_tty_read() called\n",__FILE__,__LINE__);
602                 
603         /* Validate the pointers */
604         if (!n_hdlc)
605                 return -EIO;
606
607         /* verify user access to buffer */
608         error = verify_area (VERIFY_WRITE, buf, nr);
609         if (error != 0) {
610                 printk(KERN_WARNING"%s(%d) n_hdlc_tty_read() can't verify user "
611                 "buffer\n",__FILE__,__LINE__);
612                 return (error);
613         }
614
615         for (;;) {
616                 if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
617                         return -EIO;
618
619                 n_hdlc = tty2n_hdlc (tty);
620                 if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC ||
621                          tty != n_hdlc->tty)
622                         return 0;
623
624                 rbuf = n_hdlc_buf_get(&n_hdlc->rx_buf_list);
625                 if (rbuf)
626                         break;
627                         
628                 /* no data */
629                 if (file->f_flags & O_NONBLOCK)
630                         return -EAGAIN;
631                         
632                 interruptible_sleep_on (&tty->read_wait);
633                 if (signal_pending(current))
634                         return -EINTR;
635         }
636                 
637         if (rbuf->count > nr) {
638                 /* frame too large for caller's buffer (discard frame) */
639                 ret = (rw_ret_t)-EOVERFLOW;
640         } else {
641                 /* Copy the data to the caller's buffer */
642                 COPY_TO_USER(error,buf,rbuf->buf,rbuf->count);
643                 if (error)
644                         ret = (rw_ret_t)error;
645                 else
646                         ret = (rw_ret_t)rbuf->count;
647         }
648         
649         /* return HDLC buffer to free list unless the free list */
650         /* count has exceeded the default value, in which case the */
651         /* buffer is freed back to the OS to conserve memory */
652         if (n_hdlc->rx_free_buf_list.count > DEFAULT_RX_BUF_COUNT)
653                 kfree(rbuf);
654         else    
655                 n_hdlc_buf_put(&n_hdlc->rx_free_buf_list,rbuf);
656         
657         return ret;
658         
659 }       /* end of n_hdlc_tty_read() */
660
661 /* n_hdlc_tty_write()
662  * 
663  *      write a single frame of data to device
664  *      
665  * Arguments:   tty     pointer to associated tty device instance data
666  *              file    pointer to file object data
667  *              data    pointer to transmit data (one frame)
668  *              count   size of transmit frame in bytes
669  *              
670  * Return Value:        number of bytes written (or error code)
671  */
672 static rw_ret_t n_hdlc_tty_write (struct tty_struct *tty, struct file *file,
673         const __u8 * data, rw_count_t count)
674 {
675         struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
676         int error = 0;
677         DECLARE_WAITQUEUE(wait, current);
678         N_HDLC_BUF *tbuf;
679
680         if (debuglevel >= DEBUG_LEVEL_INFO)     
681                 printk("%s(%d)n_hdlc_tty_write() called count=%d\n",
682                         __FILE__,__LINE__,count);
683                 
684         /* Verify pointers */
685         if (!n_hdlc)
686                 return -EIO;
687
688         if (n_hdlc->magic != HDLC_MAGIC)
689                 return -EIO;
690
691         /* verify frame size */
692         if (count > maxframe ) {
693                 if (debuglevel & DEBUG_LEVEL_INFO)
694                         printk (KERN_WARNING
695                                 "n_hdlc_tty_write: truncating user packet "
696                                 "from %lu to %d\n", (unsigned long) count,
697                                 maxframe );
698                 count = maxframe;
699         }
700         
701         add_wait_queue(&tty->write_wait, &wait);
702         set_current_state(TASK_INTERRUPTIBLE);
703         
704         /* Allocate transmit buffer */
705         /* sleep until transmit buffer available */             
706         while (!(tbuf = n_hdlc_buf_get(&n_hdlc->tx_free_buf_list))) {
707                 schedule();
708                         
709                 n_hdlc = tty2n_hdlc (tty);
710                 if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC || 
711                     tty != n_hdlc->tty) {
712                         printk("n_hdlc_tty_write: %p invalid after wait!\n", n_hdlc);
713                         error = -EIO;
714                         break;
715                 }
716                         
717                 if (signal_pending(current)) {
718                         error = -EINTR;
719                         break;
720                 }
721         }
722
723         set_current_state(TASK_RUNNING);
724         remove_wait_queue(&tty->write_wait, &wait);
725
726         if (!error) {           
727                 /* Retrieve the user's buffer */
728                 COPY_FROM_USER (error, tbuf->buf, data, count);
729                 if (error) {
730                         /* return tx buffer to free list */
731                         n_hdlc_buf_put(&n_hdlc->tx_free_buf_list,tbuf);
732                 } else {
733                         /* Send the data */
734                         tbuf->count = error = count;
735                         n_hdlc_buf_put(&n_hdlc->tx_buf_list,tbuf);
736                         n_hdlc_send_frames(n_hdlc,tty);
737                 }
738         }
739
740         return error;
741         
742 }       /* end of n_hdlc_tty_write() */
743
744 /* n_hdlc_tty_ioctl()
745  *
746  *      Process IOCTL system call for the tty device.
747  *
748  * Arguments:
749  *
750  *      tty             pointer to tty instance data
751  *      file            pointer to open file object for device
752  *      cmd             IOCTL command code
753  *      arg             argument for IOCTL call (cmd dependent)
754  *
755  * Return Value:        Command dependent
756  */
757 static int n_hdlc_tty_ioctl (struct tty_struct *tty, struct file * file,
758                unsigned int cmd, unsigned long arg)
759 {
760         struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
761         int error = 0;
762         int count;
763         unsigned long flags;
764         
765         if (debuglevel >= DEBUG_LEVEL_INFO)     
766                 printk("%s(%d)n_hdlc_tty_ioctl() called %d\n",
767                         __FILE__,__LINE__,cmd);
768                 
769         /* Verify the status of the device */
770         if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC)
771                 return -EBADF;
772
773         switch (cmd) {
774         case FIONREAD:
775                 /* report count of read data available */
776                 /* in next available frame (if any) */
777                 spin_lock_irqsave(&n_hdlc->rx_buf_list.spinlock,flags);
778                 if (n_hdlc->rx_buf_list.head)
779                         count = n_hdlc->rx_buf_list.head->count;
780                 else
781                         count = 0;
782                 spin_unlock_irqrestore(&n_hdlc->rx_buf_list.spinlock,flags);
783                 PUT_USER (error, count, (int *) arg);
784                 break;
785
786         case TIOCOUTQ:
787                 /* get the pending tx byte count in the driver */
788                 count = tty->driver.chars_in_buffer ?
789                                 tty->driver.chars_in_buffer(tty) : 0;
790                 /* add size of next output frame in queue */
791                 spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock,flags);
792                 if (n_hdlc->tx_buf_list.head)
793                         count += n_hdlc->tx_buf_list.head->count;
794                 spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock,flags);
795                 PUT_USER (error, count, (int*)arg);
796                 break;
797
798         default:
799                 error = n_tty_ioctl (tty, file, cmd, arg);
800                 break;
801         }
802         return error;
803         
804 }       /* end of n_hdlc_tty_ioctl() */
805
806 /* n_hdlc_tty_poll()
807  * 
808  *      TTY callback for poll system call. Determine which 
809  *      operations (read/write) will not block and return
810  *      info to caller.
811  *      
812  * Arguments:
813  * 
814  *      tty             pointer to tty instance data
815  *      filp            pointer to open file object for device
816  *      poll_table      wait queue for operations
817  * 
818  * Return Value:
819  * 
820  *      bit mask containing info on which ops will not block
821  */
822 static unsigned int n_hdlc_tty_poll (struct tty_struct *tty,
823          struct file *filp, poll_table * wait)
824 {
825         struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
826         unsigned int mask = 0;
827
828         if (debuglevel >= DEBUG_LEVEL_INFO)     
829                 printk("%s(%d)n_hdlc_tty_poll() called\n",__FILE__,__LINE__);
830                 
831         if (n_hdlc && n_hdlc->magic == HDLC_MAGIC && tty == n_hdlc->tty) {
832                 /* queue current process into any wait queue that */
833                 /* may awaken in the future (read and write) */
834
835                 poll_wait(filp, &tty->read_wait, wait);
836                 poll_wait(filp, &tty->write_wait, wait);
837
838                 /* set bits for operations that wont block */
839                 if(n_hdlc->rx_buf_list.head)
840                         mask |= POLLIN | POLLRDNORM;    /* readable */
841                 if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
842                         mask |= POLLHUP;
843                 if(tty_hung_up_p(filp))
844                         mask |= POLLHUP;
845                 if(n_hdlc->tx_free_buf_list.head)
846                         mask |= POLLOUT | POLLWRNORM;   /* writable */
847         }
848         return mask;
849 }       /* end of n_hdlc_tty_poll() */
850
851 /* n_hdlc_alloc()
852  * 
853  *      Allocate an n_hdlc instance data structure
854  *
855  * Arguments:           None
856  * Return Value:        pointer to structure if success, otherwise 0    
857  */
858 static struct n_hdlc *n_hdlc_alloc (void)
859 {
860         struct n_hdlc   *n_hdlc;
861         N_HDLC_BUF      *buf;
862         int             i;
863         
864         n_hdlc = (struct n_hdlc *)kmalloc(sizeof(struct n_hdlc), GFP_KERNEL);
865         if (!n_hdlc)
866                 return 0;
867
868         memset(n_hdlc, 0, sizeof(*n_hdlc));
869
870         n_hdlc_buf_list_init(&n_hdlc->rx_free_buf_list);
871         n_hdlc_buf_list_init(&n_hdlc->tx_free_buf_list);
872         n_hdlc_buf_list_init(&n_hdlc->rx_buf_list);
873         n_hdlc_buf_list_init(&n_hdlc->tx_buf_list);
874         
875         /* allocate free rx buffer list */
876         for(i=0;i<DEFAULT_RX_BUF_COUNT;i++) {
877                 buf = (N_HDLC_BUF*)kmalloc(N_HDLC_BUF_SIZE,GFP_KERNEL);
878                 if (buf)
879                         n_hdlc_buf_put(&n_hdlc->rx_free_buf_list,buf);
880                 else if (debuglevel >= DEBUG_LEVEL_INFO)        
881                         printk("%s(%d)n_hdlc_alloc(), kalloc() failed for rx buffer %d\n",__FILE__,__LINE__, i);
882         }
883         
884         /* allocate free tx buffer list */
885         for(i=0;i<DEFAULT_TX_BUF_COUNT;i++) {
886                 buf = (N_HDLC_BUF*)kmalloc(N_HDLC_BUF_SIZE,GFP_KERNEL);
887                 if (buf)
888                         n_hdlc_buf_put(&n_hdlc->tx_free_buf_list,buf);
889                 else if (debuglevel >= DEBUG_LEVEL_INFO)        
890                         printk("%s(%d)n_hdlc_alloc(), kalloc() failed for tx buffer %d\n",__FILE__,__LINE__, i);
891         }
892         
893         /* Initialize the control block */
894         n_hdlc->magic  = HDLC_MAGIC;
895         n_hdlc->flags  = 0;
896         
897         return n_hdlc;
898         
899 }       /* end of n_hdlc_alloc() */
900
901 /* n_hdlc_buf_list_init()
902  * 
903  *      initialize specified HDLC buffer list
904  *      
905  * Arguments:           list    pointer to buffer list
906  * Return Value:        None    
907  */
908 void n_hdlc_buf_list_init(N_HDLC_BUF_LIST *list)
909 {
910         memset(list,0,sizeof(N_HDLC_BUF_LIST));
911         spin_lock_init(&list->spinlock);
912 }       /* end of n_hdlc_buf_list_init() */
913
914 /* n_hdlc_buf_put()
915  * 
916  *      add specified HDLC buffer to tail of specified list
917  *      
918  * Arguments:
919  * 
920  *      list    pointer to buffer list
921  *      buf     pointer to buffer
922  * 
923  * Return Value:        None    
924  */
925 void n_hdlc_buf_put(N_HDLC_BUF_LIST *list,N_HDLC_BUF *buf)
926 {
927         unsigned long flags;
928         spin_lock_irqsave(&list->spinlock,flags);
929         
930         buf->link=NULL;
931         if(list->tail)
932                 list->tail->link = buf;
933         else
934                 list->head = buf;
935         list->tail = buf;
936         (list->count)++;
937         
938         spin_unlock_irqrestore(&list->spinlock,flags);
939         
940 }       /* end of n_hdlc_buf_put() */
941
942 /* n_hdlc_buf_get()
943  * 
944  *      remove and return an HDLC buffer from the
945  *      head of the specified HDLC buffer list
946  *      
947  * Arguments:
948  * 
949  *      list    pointer to HDLC buffer list
950  *      
951  * Return Value:
952  * 
953  *      pointer to HDLC buffer if available, otherwise NULL
954  */
955 N_HDLC_BUF* n_hdlc_buf_get(N_HDLC_BUF_LIST *list)
956 {
957         unsigned long flags;
958         N_HDLC_BUF *buf;
959         spin_lock_irqsave(&list->spinlock,flags);
960         
961         buf = list->head;
962         if (buf) {
963                 list->head = buf->link;
964                 (list->count)--;
965         }
966         if (!list->head)
967                 list->tail = NULL;
968         
969         spin_unlock_irqrestore(&list->spinlock,flags);
970         return buf;
971         
972 }       /* end of n_hdlc_buf_get() */
973
974 static int __init n_hdlc_init(void)
975 {
976         static struct tty_ldisc n_hdlc_ldisc;
977         int    status;
978
979         /* range check maxframe arg */
980         if ( maxframe<4096)
981                 maxframe=4096;
982         else if ( maxframe>65535)
983                 maxframe=65535;
984
985         printk("HDLC line discipline: version %s, maxframe=%u\n", 
986                 szVersion, maxframe);
987
988         /* Register the tty discipline */
989         
990         memset(&n_hdlc_ldisc, 0, sizeof (n_hdlc_ldisc));
991         n_hdlc_ldisc.magic              = TTY_LDISC_MAGIC;
992         n_hdlc_ldisc.name               = "hdlc";
993         n_hdlc_ldisc.open               = n_hdlc_tty_open;
994         n_hdlc_ldisc.close              = n_hdlc_tty_close;
995         n_hdlc_ldisc.read               = n_hdlc_tty_read;
996         n_hdlc_ldisc.write              = n_hdlc_tty_write;
997         n_hdlc_ldisc.ioctl              = n_hdlc_tty_ioctl;
998         n_hdlc_ldisc.poll               = n_hdlc_tty_poll;
999         n_hdlc_ldisc.receive_room       = n_hdlc_tty_room;
1000         n_hdlc_ldisc.receive_buf        = n_hdlc_tty_receive;
1001         n_hdlc_ldisc.write_wakeup       = n_hdlc_tty_wakeup;
1002
1003         status = tty_register_ldisc(N_HDLC, &n_hdlc_ldisc);
1004         if (!status)
1005                 printk (KERN_INFO"N_HDLC line discipline registered.\n");
1006         else
1007                 printk (KERN_ERR"error registering line discipline: %d\n",status);
1008
1009         if (status)
1010                 printk(KERN_INFO"N_HDLC: init failure %d\n", status);
1011         return (status);
1012         
1013 }       /* end of init_module() */
1014
1015 static void __exit n_hdlc_exit(void)
1016 {
1017         int status;
1018         /* Release tty registration of line discipline */
1019         if ((status = tty_register_ldisc(N_HDLC, NULL)))
1020                 printk("N_HDLC: can't unregister line discipline (err = %d)\n", status);
1021         else
1022                 printk("N_HDLC: line discipline unregistered\n");
1023 }
1024
1025 module_init(n_hdlc_init);
1026 module_exit(n_hdlc_exit);
1027
1028 MODULE_LICENSE("GPL");
1029 EXPORT_NO_SYMBOLS;