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 2008/10/15 03:26:26 james26_jang 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
123typedef ssize_t		rw_ret_t;
124typedef 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
135typedef 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
144typedef 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 */
156struct 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 */
175void n_hdlc_buf_list_init(N_HDLC_BUF_LIST *list);
176void n_hdlc_buf_put(N_HDLC_BUF_LIST *list,N_HDLC_BUF *buf);
177N_HDLC_BUF* n_hdlc_buf_get(N_HDLC_BUF_LIST *list);
178
179/* Local functions */
180
181static struct n_hdlc *n_hdlc_alloc (void);
182
183MODULE_PARM(debuglevel, "i");
184MODULE_PARM(maxframe, "i");
185
186
187/* debug level can be set by insmod for debugging purposes */
188#define DEBUG_LEVEL_INFO	1
189int debuglevel=0;
190
191/* max frame size for memory allocations */
192ssize_t	maxframe=4096;
193
194/* TTY callbacks */
195
196static rw_ret_t n_hdlc_tty_read(struct tty_struct *,
197	struct file *, __u8 *, rw_count_t);
198static rw_ret_t n_hdlc_tty_write(struct tty_struct *,
199	struct file *, const __u8 *, rw_count_t);
200static int n_hdlc_tty_ioctl(struct tty_struct *,
201	struct file *, unsigned int, unsigned long);
202static unsigned int n_hdlc_tty_poll (struct tty_struct *tty, struct file *filp,
203				  poll_table * wait);
204static int n_hdlc_tty_open (struct tty_struct *);
205static void n_hdlc_tty_close (struct tty_struct *);
206static int n_hdlc_tty_room (struct tty_struct *tty);
207static void n_hdlc_tty_receive (struct tty_struct *tty,
208	const __u8 * cp, char *fp, int count);
209static 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 */
217static char szVersion[] = HDLC_VERSION;
218
219/* n_hdlc_release()
220 *
221 *	release an n_hdlc per device line discipline info structure
222 *
223 */
224static 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 */
278static 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 */
318static 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 */
375static 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 */
470static 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 */
498static 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 */
519static 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 */
592static 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 */
672static 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 */
757static 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 */
822static 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 */
858static 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 */
908void 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 */
925void 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 */
955N_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
974static 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
1015static 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
1025module_init(n_hdlc_init);
1026module_exit(n_hdlc_exit);
1027
1028MODULE_LICENSE("GPL");
1029EXPORT_NO_SYMBOLS;
1030