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