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 3.7 2003/05/01 15:45:29 paulkf 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: 3.7 $"
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 static void n_hdlc_buf_list_init(N_HDLC_BUF_LIST *list);
176 static void n_hdlc_buf_put(N_HDLC_BUF_LIST *list,N_HDLC_BUF *buf);
177 static 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 #ifdef MODULE_LICENSE
187 MODULE_LICENSE("GPL");
188 #endif
189 
190 /* debug level can be set by insmod for debugging purposes */
191 #define DEBUG_LEVEL_INFO	1
192 static int debuglevel=0;
193 
194 /* max frame size for memory allocations */
195 static ssize_t	maxframe=4096;
196 
197 /* TTY callbacks */
198 
199 static rw_ret_t n_hdlc_tty_read(struct tty_struct *,
200 	struct file *, __u8 *, rw_count_t);
201 static rw_ret_t n_hdlc_tty_write(struct tty_struct *,
202 	struct file *, const __u8 *, rw_count_t);
203 static int n_hdlc_tty_ioctl(struct tty_struct *,
204 	struct file *, unsigned int, unsigned long);
205 static unsigned int n_hdlc_tty_poll (struct tty_struct *tty, struct file *filp,
206 				  poll_table * wait);
207 static int n_hdlc_tty_open (struct tty_struct *);
208 static void n_hdlc_tty_close (struct tty_struct *);
209 static int n_hdlc_tty_room (struct tty_struct *tty);
210 static void n_hdlc_tty_receive (struct tty_struct *tty,
211 	const __u8 * cp, char *fp, int count);
212 static void n_hdlc_tty_wakeup (struct tty_struct *tty);
213 
214 #define bset(p,b)	((p)[(b) >> 5] |= (1 << ((b) & 0x1f)))
215 
216 #define tty2n_hdlc(tty)	((struct n_hdlc *) ((tty)->disc_data))
217 #define n_hdlc2tty(n_hdlc)	((n_hdlc)->tty)
218 
219 /* Define this string only once for all macro invocations */
220 static char szVersion[] = HDLC_VERSION;
221 
222 /* n_hdlc_release()
223  *
224  *	release an n_hdlc per device line discipline info structure
225  *
226  */
n_hdlc_release(struct n_hdlc * n_hdlc)227 static void n_hdlc_release (struct n_hdlc *n_hdlc)
228 {
229 	struct tty_struct *tty = n_hdlc2tty (n_hdlc);
230 	N_HDLC_BUF *buf;
231 
232 	if (debuglevel >= DEBUG_LEVEL_INFO)
233 		printk("%s(%d)n_hdlc_release() called\n",__FILE__,__LINE__);
234 
235 	/* Ensure that the n_hdlcd process is not hanging on select()/poll() */
236 	wake_up_interruptible (&tty->read_wait);
237 	wake_up_interruptible (&tty->write_wait);
238 
239 	if (tty != NULL && tty->disc_data == n_hdlc)
240 		tty->disc_data = NULL;	/* Break the tty->n_hdlc link */
241 
242 	/* Release transmit and receive buffers */
243 	for(;;) {
244 		buf = n_hdlc_buf_get(&n_hdlc->rx_free_buf_list);
245 		if (buf) {
246 			kfree(buf);
247 		} else
248 			break;
249 	}
250 	for(;;) {
251 		buf = n_hdlc_buf_get(&n_hdlc->tx_free_buf_list);
252 		if (buf) {
253 			kfree(buf);
254 		} else
255 			break;
256 	}
257 	for(;;) {
258 		buf = n_hdlc_buf_get(&n_hdlc->rx_buf_list);
259 		if (buf) {
260 			kfree(buf);
261 		} else
262 			break;
263 	}
264 	for(;;) {
265 		buf = n_hdlc_buf_get(&n_hdlc->tx_buf_list);
266 		if (buf) {
267 			kfree(buf);
268 		} else
269 			break;
270 	}
271 	if (n_hdlc->tbuf)
272 		kfree(n_hdlc->tbuf);
273 	kfree(n_hdlc);
274 
275 }	/* end of n_hdlc_release() */
276 
277 /* n_hdlc_tty_close()
278  *
279  *	Called when the line discipline is changed to something
280  *	else, the tty is closed, or the tty detects a hangup.
281  */
n_hdlc_tty_close(struct tty_struct * tty)282 static void n_hdlc_tty_close(struct tty_struct *tty)
283 {
284 	struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
285 
286 	if (debuglevel >= DEBUG_LEVEL_INFO)
287 		printk("%s(%d)n_hdlc_tty_close() called\n",__FILE__,__LINE__);
288 
289 	if (n_hdlc != NULL) {
290 		if (n_hdlc->magic != HDLC_MAGIC) {
291 			printk (KERN_WARNING"n_hdlc: trying to close unopened tty!\n");
292 			return;
293 		}
294 #if defined(TTY_NO_WRITE_SPLIT)
295 		clear_bit(TTY_NO_WRITE_SPLIT,&tty->flags);
296 #endif
297 		tty->disc_data = NULL;
298 		if (tty == n_hdlc->backup_tty)
299 			n_hdlc->backup_tty = 0;
300 		if (tty != n_hdlc->tty)
301 			return;
302 		if (n_hdlc->backup_tty) {
303 			n_hdlc->tty = n_hdlc->backup_tty;
304 		} else {
305 			n_hdlc_release (n_hdlc);
306 			MOD_DEC_USE_COUNT;
307 		}
308 	}
309 
310 	if (debuglevel >= DEBUG_LEVEL_INFO)
311 		printk("%s(%d)n_hdlc_tty_close() success\n",__FILE__,__LINE__);
312 
313 }	/* end of n_hdlc_tty_close() */
314 
315 /* n_hdlc_tty_open
316  *
317  * 	called when line discipline changed to n_hdlc
318  *
319  * Arguments:	tty	pointer to tty info structure
320  * Return Value:	0 if success, otherwise error code
321  */
n_hdlc_tty_open(struct tty_struct * tty)322 static int n_hdlc_tty_open (struct tty_struct *tty)
323 {
324 	struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
325 
326 	if (debuglevel >= DEBUG_LEVEL_INFO)
327 		printk("%s(%d)n_hdlc_tty_open() called (major=%u,minor=%u)\n",
328 		__FILE__,__LINE__,
329 		MAJOR(tty->device), MINOR(tty->device));
330 
331 	/* There should not be an existing table for this slot. */
332 	if (n_hdlc) {
333 		printk (KERN_ERR"n_hdlc_tty_open:tty already associated!\n" );
334 		return -EEXIST;
335 	}
336 
337 	n_hdlc = n_hdlc_alloc();
338 	if (!n_hdlc) {
339 		printk (KERN_ERR "n_hdlc_alloc failed\n");
340 		return -ENFILE;
341 	}
342 
343 	tty->disc_data = n_hdlc;
344 	n_hdlc->tty    = tty;
345 
346 	MOD_INC_USE_COUNT;
347 
348 #if defined(TTY_NO_WRITE_SPLIT)
349 	/* change tty_io write() to not split large writes into 8K chunks */
350 	set_bit(TTY_NO_WRITE_SPLIT,&tty->flags);
351 #endif
352 
353 	/* Flush any pending characters in the driver and discipline. */
354 
355 	tty_ldisc_flush(tty);
356 
357 	if (tty->driver.flush_buffer)
358 		tty->driver.flush_buffer (tty);
359 
360 	if (debuglevel >= DEBUG_LEVEL_INFO)
361 		printk("%s(%d)n_hdlc_tty_open() success\n",__FILE__,__LINE__);
362 
363 	return 0;
364 
365 }	/* end of n_tty_hdlc_open() */
366 
367 /* n_hdlc_send_frames()
368  *
369  * 	send frames on pending send buffer list until the
370  * 	driver does not accept a frame (busy)
371  * 	this function is called after adding a frame to the
372  * 	send buffer list and by the tty wakeup callback
373  *
374  * Arguments:		n_hdlc		pointer to ldisc instance data
375  * 			tty		pointer to tty instance data
376  * Return Value:	None
377  */
n_hdlc_send_frames(struct n_hdlc * n_hdlc,struct tty_struct * tty)378 static void n_hdlc_send_frames (struct n_hdlc *n_hdlc, struct tty_struct *tty)
379 {
380 	register int actual;
381 	unsigned long flags;
382 	N_HDLC_BUF *tbuf;
383 
384 	if (debuglevel >= DEBUG_LEVEL_INFO)
385 		printk("%s(%d)n_hdlc_send_frames() called\n",__FILE__,__LINE__);
386  check_again:
387 
388 	save_flags(flags);
389 	cli ();
390 	if (n_hdlc->tbusy) {
391 		n_hdlc->woke_up = 1;
392 		restore_flags(flags);
393 		return;
394 	}
395 	n_hdlc->tbusy = 1;
396 	n_hdlc->woke_up = 0;
397 	restore_flags(flags);
398 
399 	/* get current transmit buffer or get new transmit */
400 	/* buffer from list of pending transmit buffers */
401 
402 	tbuf = n_hdlc->tbuf;
403 	if (!tbuf)
404 		tbuf = n_hdlc_buf_get(&n_hdlc->tx_buf_list);
405 
406 	while (tbuf) {
407 		if (debuglevel >= DEBUG_LEVEL_INFO)
408 			printk("%s(%d)sending frame %p, count=%d\n",
409 				__FILE__,__LINE__,tbuf,tbuf->count);
410 
411 		/* Send the next block of data to device */
412 		tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
413 		actual = tty->driver.write(tty, 0, tbuf->buf, tbuf->count);
414 
415 		/* if transmit error, throw frame away by */
416 		/* pretending it was accepted by driver */
417 		if (actual < 0)
418 			actual = tbuf->count;
419 
420 		if (actual == tbuf->count) {
421 			if (debuglevel >= DEBUG_LEVEL_INFO)
422 				printk("%s(%d)frame %p completed\n",
423 					__FILE__,__LINE__,tbuf);
424 
425 			/* free current transmit buffer */
426 			n_hdlc_buf_put(&n_hdlc->tx_free_buf_list,tbuf);
427 
428 			/* this tx buffer is done */
429 			n_hdlc->tbuf = NULL;
430 
431 			/* wait up sleeping writers */
432 			wake_up_interruptible(&tty->write_wait);
433 
434 			/* get next pending transmit buffer */
435 			tbuf = n_hdlc_buf_get(&n_hdlc->tx_buf_list);
436 		} else {
437 			if (debuglevel >= DEBUG_LEVEL_INFO)
438 				printk("%s(%d)frame %p pending\n",
439 					__FILE__,__LINE__,tbuf);
440 
441 			/* buffer not accepted by driver */
442 			/* set this buffer as pending buffer */
443 			n_hdlc->tbuf = tbuf;
444 			break;
445 		}
446 	}
447 
448 	if (!tbuf)
449 		tty->flags  &= ~(1 << TTY_DO_WRITE_WAKEUP);
450 
451 	/* Clear the re-entry flag */
452 	save_flags(flags);
453 	cli ();
454 	n_hdlc->tbusy = 0;
455 	restore_flags(flags);
456 
457         if (n_hdlc->woke_up)
458 	  goto check_again;
459 
460 	if (debuglevel >= DEBUG_LEVEL_INFO)
461 		printk("%s(%d)n_hdlc_send_frames() exit\n",__FILE__,__LINE__);
462 
463 }	/* end of n_hdlc_send_frames() */
464 
465 /* n_hdlc_tty_wakeup()
466  *
467  *	Callback for transmit wakeup. Called when low level
468  *	device driver can accept more send data.
469  *
470  * Arguments:		tty	pointer to associated tty instance data
471  * Return Value:	None
472  */
n_hdlc_tty_wakeup(struct tty_struct * tty)473 static void n_hdlc_tty_wakeup (struct tty_struct *tty)
474 {
475 	struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
476 
477 	if (debuglevel >= DEBUG_LEVEL_INFO)
478 		printk("%s(%d)n_hdlc_tty_wakeup() called\n",__FILE__,__LINE__);
479 
480 	if (!n_hdlc)
481 		return;
482 
483 	if (tty != n_hdlc->tty) {
484 		tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
485 		return;
486 	}
487 
488 	n_hdlc_send_frames (n_hdlc, tty);
489 
490 }	/* end of n_hdlc_tty_wakeup() */
491 
492 /* n_hdlc_tty_room()
493  *
494  *	Callback function from tty driver. Return the amount of
495  *	space left in the receiver's buffer to decide if remote
496  *	transmitter is to be throttled.
497  *
498  * Arguments:		tty	pointer to associated tty instance data
499  * Return Value:	number of bytes left in receive buffer
500  */
n_hdlc_tty_room(struct tty_struct * tty)501 static int n_hdlc_tty_room (struct tty_struct *tty)
502 {
503 	if (debuglevel >= DEBUG_LEVEL_INFO)
504 		printk("%s(%d)n_hdlc_tty_room() called\n",__FILE__,__LINE__);
505 	/* always return a larger number to prevent */
506 	/* throttling of remote transmitter. */
507 	return 65536;
508 }	/* end of n_hdlc_tty_root() */
509 
510 /* n_hdlc_tty_receive()
511  *
512  * 	Called by tty low level driver when receive data is
513  * 	available. Data is interpreted as one HDLC frame.
514  *
515  * Arguments:	 	tty		pointer to tty isntance data
516  * 			data		pointer to received data
517  * 			flags		pointer to flags for data
518  * 			count		count of received data in bytes
519  *
520  * Return Value:	None
521  */
n_hdlc_tty_receive(struct tty_struct * tty,const __u8 * data,char * flags,int count)522 static void n_hdlc_tty_receive(struct tty_struct *tty,
523 	const __u8 * data, char *flags, int count)
524 {
525 	register struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
526 	register N_HDLC_BUF *buf;
527 
528 	if (debuglevel >= DEBUG_LEVEL_INFO)
529 		printk("%s(%d)n_hdlc_tty_receive() called count=%d\n",
530 			__FILE__,__LINE__, count);
531 
532 	/* This can happen if stuff comes in on the backup tty */
533 	if (n_hdlc == 0 || tty != n_hdlc->tty)
534 		return;
535 
536 	/* verify line is using HDLC discipline */
537 	if (n_hdlc->magic != HDLC_MAGIC) {
538 		printk("%s(%d) line not using HDLC discipline\n",
539 			__FILE__,__LINE__);
540 		return;
541 	}
542 
543 	if ( count>maxframe ) {
544 		if (debuglevel >= DEBUG_LEVEL_INFO)
545 			printk("%s(%d) rx count>maxframesize, data discarded\n",
546 			       __FILE__,__LINE__);
547 		return;
548 	}
549 
550 	/* get a free HDLC buffer */
551 	buf = n_hdlc_buf_get(&n_hdlc->rx_free_buf_list);
552 	if (!buf) {
553 		/* no buffers in free list, attempt to allocate another rx buffer */
554 		/* unless the maximum count has been reached */
555 		if (n_hdlc->rx_buf_list.count < MAX_RX_BUF_COUNT)
556 			buf = (N_HDLC_BUF*)kmalloc(N_HDLC_BUF_SIZE,GFP_ATOMIC);
557 	}
558 
559 	if (!buf) {
560 		if (debuglevel >= DEBUG_LEVEL_INFO)
561 			printk("%s(%d) no more rx buffers, data discarded\n",
562 			       __FILE__,__LINE__);
563 		return;
564 	}
565 
566 	/* copy received data to HDLC buffer */
567 	memcpy(buf->buf,data,count);
568 	buf->count=count;
569 
570 	/* add HDLC buffer to list of received frames */
571 	n_hdlc_buf_put(&n_hdlc->rx_buf_list,buf);
572 
573 	/* wake up any blocked reads and perform async signalling */
574 	wake_up_interruptible (&tty->read_wait);
575 	if (n_hdlc->tty->fasync != NULL)
576 		kill_fasync (&n_hdlc->tty->fasync, SIGIO, POLL_IN);
577 
578 }	/* end of n_hdlc_tty_receive() */
579 
580 /* n_hdlc_tty_read()
581  *
582  * 	Called to retreive one frame of data (if available)
583  *
584  * Arguments:
585  *
586  * 	tty		pointer to tty instance data
587  * 	file		pointer to open file object
588  * 	buf		pointer to returned data buffer
589  * 	nr		size of returned data buffer
590  *
591  * Return Value:
592  *
593  * 	Number of bytes returned or error code
594  */
n_hdlc_tty_read(struct tty_struct * tty,struct file * file,__u8 * buf,rw_count_t nr)595 static rw_ret_t n_hdlc_tty_read (struct tty_struct *tty,
596 	struct file *file, __u8 * buf, rw_count_t nr)
597 {
598 	struct n_hdlc *n_hdlc = tty2n_hdlc(tty);
599 	int error;
600 	rw_ret_t ret;
601 	N_HDLC_BUF *rbuf;
602 
603 	if (debuglevel >= DEBUG_LEVEL_INFO)
604 		printk("%s(%d)n_hdlc_tty_read() called\n",__FILE__,__LINE__);
605 
606 	/* Validate the pointers */
607 	if (!n_hdlc)
608 		return -EIO;
609 
610 	/* verify user access to buffer */
611 	error = verify_area (VERIFY_WRITE, buf, nr);
612 	if (error != 0) {
613 		printk(KERN_WARNING"%s(%d) n_hdlc_tty_read() can't verify user "
614 		"buffer\n",__FILE__,__LINE__);
615 		return (error);
616 	}
617 
618 	for (;;) {
619 		if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
620 			return -EIO;
621 
622 		n_hdlc = tty2n_hdlc (tty);
623 		if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC ||
624 			 tty != n_hdlc->tty)
625 			return 0;
626 
627 		rbuf = n_hdlc_buf_get(&n_hdlc->rx_buf_list);
628 		if (rbuf)
629 			break;
630 
631 		/* no data */
632 		if (file->f_flags & O_NONBLOCK)
633 			return -EAGAIN;
634 
635 		interruptible_sleep_on (&tty->read_wait);
636 		if (signal_pending(current))
637 			return -EINTR;
638 	}
639 
640 	if (rbuf->count > nr) {
641 		/* frame too large for caller's buffer (discard frame) */
642 		ret = (rw_ret_t)-EOVERFLOW;
643 	} else {
644 		/* Copy the data to the caller's buffer */
645 		COPY_TO_USER(error,buf,rbuf->buf,rbuf->count);
646 		if (error)
647 			ret = (rw_ret_t)error;
648 		else
649 			ret = (rw_ret_t)rbuf->count;
650 	}
651 
652 	/* return HDLC buffer to free list unless the free list */
653 	/* count has exceeded the default value, in which case the */
654 	/* buffer is freed back to the OS to conserve memory */
655 	if (n_hdlc->rx_free_buf_list.count > DEFAULT_RX_BUF_COUNT)
656 		kfree(rbuf);
657 	else
658 		n_hdlc_buf_put(&n_hdlc->rx_free_buf_list,rbuf);
659 
660 	return ret;
661 
662 }	/* end of n_hdlc_tty_read() */
663 
664 /* n_hdlc_tty_write()
665  *
666  * 	write a single frame of data to device
667  *
668  * Arguments:	tty	pointer to associated tty device instance data
669  * 		file	pointer to file object data
670  * 		data	pointer to transmit data (one frame)
671  * 		count	size of transmit frame in bytes
672  *
673  * Return Value:	number of bytes written (or error code)
674  */
n_hdlc_tty_write(struct tty_struct * tty,struct file * file,const __u8 * data,rw_count_t count)675 static rw_ret_t n_hdlc_tty_write (struct tty_struct *tty, struct file *file,
676 	const __u8 * data, rw_count_t count)
677 {
678 	struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
679 	int error = 0;
680 	DECLARE_WAITQUEUE(wait, current);
681 	N_HDLC_BUF *tbuf;
682 
683 	if (debuglevel >= DEBUG_LEVEL_INFO)
684 		printk("%s(%d)n_hdlc_tty_write() called count=%d\n",
685 			__FILE__,__LINE__,count);
686 
687 	/* Verify pointers */
688 	if (!n_hdlc)
689 		return -EIO;
690 
691 	if (n_hdlc->magic != HDLC_MAGIC)
692 		return -EIO;
693 
694 	/* verify frame size */
695 	if (count > maxframe ) {
696 		if (debuglevel & DEBUG_LEVEL_INFO)
697 			printk (KERN_WARNING
698 				"n_hdlc_tty_write: truncating user packet "
699 				"from %lu to %d\n", (unsigned long) count,
700 				maxframe );
701 		count = maxframe;
702 	}
703 
704 	add_wait_queue(&tty->write_wait, &wait);
705 	set_current_state(TASK_INTERRUPTIBLE);
706 
707 	/* Allocate transmit buffer */
708 	/* sleep until transmit buffer available */
709 	while (!(tbuf = n_hdlc_buf_get(&n_hdlc->tx_free_buf_list))) {
710 		schedule();
711 
712 		n_hdlc = tty2n_hdlc (tty);
713 		if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC ||
714 		    tty != n_hdlc->tty) {
715 			printk("n_hdlc_tty_write: %p invalid after wait!\n", n_hdlc);
716 			error = -EIO;
717 			break;
718 		}
719 
720 		if (signal_pending(current)) {
721 			error = -EINTR;
722 			break;
723 		}
724 	}
725 
726 	set_current_state(TASK_RUNNING);
727 	remove_wait_queue(&tty->write_wait, &wait);
728 
729 	if (!error) {
730 		/* Retrieve the user's buffer */
731 		COPY_FROM_USER (error, tbuf->buf, data, count);
732 		if (error) {
733 			/* return tx buffer to free list */
734 			n_hdlc_buf_put(&n_hdlc->tx_free_buf_list,tbuf);
735 		} else {
736 			/* Send the data */
737 			tbuf->count = error = count;
738 			n_hdlc_buf_put(&n_hdlc->tx_buf_list,tbuf);
739 			n_hdlc_send_frames(n_hdlc,tty);
740 		}
741 	}
742 
743 	return error;
744 
745 }	/* end of n_hdlc_tty_write() */
746 
747 /* n_hdlc_tty_ioctl()
748  *
749  *	Process IOCTL system call for the tty device.
750  *
751  * Arguments:
752  *
753  *	tty		pointer to tty instance data
754  *	file		pointer to open file object for device
755  *	cmd		IOCTL command code
756  *	arg		argument for IOCTL call (cmd dependent)
757  *
758  * Return Value:	Command dependent
759  */
n_hdlc_tty_ioctl(struct tty_struct * tty,struct file * file,unsigned int cmd,unsigned long arg)760 static int n_hdlc_tty_ioctl (struct tty_struct *tty, struct file * file,
761                unsigned int cmd, unsigned long arg)
762 {
763 	struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
764 	int error = 0;
765 	int count;
766 	unsigned long flags;
767 
768 	if (debuglevel >= DEBUG_LEVEL_INFO)
769 		printk("%s(%d)n_hdlc_tty_ioctl() called %d\n",
770 			__FILE__,__LINE__,cmd);
771 
772 	/* Verify the status of the device */
773 	if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC)
774 		return -EBADF;
775 
776 	switch (cmd) {
777 	case FIONREAD:
778 		/* report count of read data available */
779 		/* in next available frame (if any) */
780 		spin_lock_irqsave(&n_hdlc->rx_buf_list.spinlock,flags);
781 		if (n_hdlc->rx_buf_list.head)
782 			count = n_hdlc->rx_buf_list.head->count;
783 		else
784 			count = 0;
785 		spin_unlock_irqrestore(&n_hdlc->rx_buf_list.spinlock,flags);
786 		PUT_USER (error, count, (int *) arg);
787 		break;
788 
789 	case TIOCOUTQ:
790 		/* get the pending tx byte count in the driver */
791 		count = tty->driver.chars_in_buffer ?
792 				tty->driver.chars_in_buffer(tty) : 0;
793 		/* add size of next output frame in queue */
794 		spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock,flags);
795 		if (n_hdlc->tx_buf_list.head)
796 			count += n_hdlc->tx_buf_list.head->count;
797 		spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock,flags);
798 		PUT_USER (error, count, (int*)arg);
799 		break;
800 
801 	default:
802 		error = n_tty_ioctl (tty, file, cmd, arg);
803 		break;
804 	}
805 	return error;
806 
807 }	/* end of n_hdlc_tty_ioctl() */
808 
809 /* n_hdlc_tty_poll()
810  *
811  * 	TTY callback for poll system call. Determine which
812  * 	operations (read/write) will not block and return
813  * 	info to caller.
814  *
815  * Arguments:
816  *
817  * 	tty		pointer to tty instance data
818  * 	filp		pointer to open file object for device
819  * 	poll_table	wait queue for operations
820  *
821  * Return Value:
822  *
823  * 	bit mask containing info on which ops will not block
824  */
n_hdlc_tty_poll(struct tty_struct * tty,struct file * filp,poll_table * wait)825 static unsigned int n_hdlc_tty_poll (struct tty_struct *tty,
826 	 struct file *filp, poll_table * wait)
827 {
828 	struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
829 	unsigned int mask = 0;
830 
831 	if (debuglevel >= DEBUG_LEVEL_INFO)
832 		printk("%s(%d)n_hdlc_tty_poll() called\n",__FILE__,__LINE__);
833 
834 	if (n_hdlc && n_hdlc->magic == HDLC_MAGIC && tty == n_hdlc->tty) {
835 		/* queue current process into any wait queue that */
836 		/* may awaken in the future (read and write) */
837 
838 		poll_wait(filp, &tty->read_wait, wait);
839 		poll_wait(filp, &tty->write_wait, wait);
840 
841 		/* set bits for operations that wont block */
842 		if(n_hdlc->rx_buf_list.head)
843 			mask |= POLLIN | POLLRDNORM;	/* readable */
844 		if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
845 			mask |= POLLHUP;
846 		if(tty_hung_up_p(filp))
847 			mask |= POLLHUP;
848 		if(n_hdlc->tx_free_buf_list.head)
849 			mask |= POLLOUT | POLLWRNORM;	/* writable */
850 	}
851 	return mask;
852 }	/* end of n_hdlc_tty_poll() */
853 
854 /* n_hdlc_alloc()
855  *
856  * 	Allocate an n_hdlc instance data structure
857  *
858  * Arguments:		None
859  * Return Value:	pointer to structure if success, otherwise 0
860  */
n_hdlc_alloc(void)861 static struct n_hdlc *n_hdlc_alloc (void)
862 {
863 	struct n_hdlc	*n_hdlc;
864 	N_HDLC_BUF	*buf;
865 	int		i;
866 
867 	n_hdlc = (struct n_hdlc *)kmalloc(sizeof(struct n_hdlc), GFP_KERNEL);
868 	if (!n_hdlc)
869 		return 0;
870 
871 	memset(n_hdlc, 0, sizeof(*n_hdlc));
872 
873 	n_hdlc_buf_list_init(&n_hdlc->rx_free_buf_list);
874 	n_hdlc_buf_list_init(&n_hdlc->tx_free_buf_list);
875 	n_hdlc_buf_list_init(&n_hdlc->rx_buf_list);
876 	n_hdlc_buf_list_init(&n_hdlc->tx_buf_list);
877 
878 	/* allocate free rx buffer list */
879 	for(i=0;i<DEFAULT_RX_BUF_COUNT;i++) {
880 		buf = (N_HDLC_BUF*)kmalloc(N_HDLC_BUF_SIZE,GFP_KERNEL);
881 		if (buf)
882 			n_hdlc_buf_put(&n_hdlc->rx_free_buf_list,buf);
883 		else if (debuglevel >= DEBUG_LEVEL_INFO)
884 			printk("%s(%d)n_hdlc_alloc(), kalloc() failed for rx buffer %d\n",__FILE__,__LINE__, i);
885 	}
886 
887 	/* allocate free tx buffer list */
888 	for(i=0;i<DEFAULT_TX_BUF_COUNT;i++) {
889 		buf = (N_HDLC_BUF*)kmalloc(N_HDLC_BUF_SIZE,GFP_KERNEL);
890 		if (buf)
891 			n_hdlc_buf_put(&n_hdlc->tx_free_buf_list,buf);
892 		else if (debuglevel >= DEBUG_LEVEL_INFO)
893 			printk("%s(%d)n_hdlc_alloc(), kalloc() failed for tx buffer %d\n",__FILE__,__LINE__, i);
894 	}
895 
896 	/* Initialize the control block */
897 	n_hdlc->magic  = HDLC_MAGIC;
898 	n_hdlc->flags  = 0;
899 
900 	return n_hdlc;
901 
902 }	/* end of n_hdlc_alloc() */
903 
904 /* n_hdlc_buf_list_init()
905  *
906  * 	initialize specified HDLC buffer list
907  *
908  * Arguments:	 	list	pointer to buffer list
909  * Return Value:	None
910  */
n_hdlc_buf_list_init(N_HDLC_BUF_LIST * list)911 static void n_hdlc_buf_list_init(N_HDLC_BUF_LIST *list)
912 {
913 	memset(list,0,sizeof(N_HDLC_BUF_LIST));
914 	spin_lock_init(&list->spinlock);
915 }	/* end of n_hdlc_buf_list_init() */
916 
917 /* n_hdlc_buf_put()
918  *
919  * 	add specified HDLC buffer to tail of specified list
920  *
921  * Arguments:
922  *
923  * 	list	pointer to buffer list
924  * 	buf	pointer to buffer
925  *
926  * Return Value:	None
927  */
n_hdlc_buf_put(N_HDLC_BUF_LIST * list,N_HDLC_BUF * buf)928 static void n_hdlc_buf_put(N_HDLC_BUF_LIST *list,N_HDLC_BUF *buf)
929 {
930 	unsigned long flags;
931 	spin_lock_irqsave(&list->spinlock,flags);
932 
933 	buf->link=NULL;
934 	if(list->tail)
935 		list->tail->link = buf;
936 	else
937 		list->head = buf;
938 	list->tail = buf;
939 	(list->count)++;
940 
941 	spin_unlock_irqrestore(&list->spinlock,flags);
942 
943 }	/* end of n_hdlc_buf_put() */
944 
945 /* n_hdlc_buf_get()
946  *
947  * 	remove and return an HDLC buffer from the
948  * 	head of the specified HDLC buffer list
949  *
950  * Arguments:
951  *
952  * 	list	pointer to HDLC buffer list
953  *
954  * Return Value:
955  *
956  * 	pointer to HDLC buffer if available, otherwise NULL
957  */
n_hdlc_buf_get(N_HDLC_BUF_LIST * list)958 static N_HDLC_BUF* n_hdlc_buf_get(N_HDLC_BUF_LIST *list)
959 {
960 	unsigned long flags;
961 	N_HDLC_BUF *buf;
962 	spin_lock_irqsave(&list->spinlock,flags);
963 
964 	buf = list->head;
965 	if (buf) {
966 		list->head = buf->link;
967 		(list->count)--;
968 	}
969 	if (!list->head)
970 		list->tail = NULL;
971 
972 	spin_unlock_irqrestore(&list->spinlock,flags);
973 	return buf;
974 
975 }	/* end of n_hdlc_buf_get() */
976 
n_hdlc_init(void)977 static int __init n_hdlc_init(void)
978 {
979 	static struct tty_ldisc	n_hdlc_ldisc;
980 	int    status;
981 
982 	/* range check maxframe arg */
983 	if ( maxframe<4096)
984 		maxframe=4096;
985 	else if ( maxframe>65535)
986 		maxframe=65535;
987 
988 	printk("HDLC line discipline: version %s, maxframe=%u\n",
989 		szVersion, maxframe);
990 
991 	/* Register the tty discipline */
992 
993 	memset(&n_hdlc_ldisc, 0, sizeof (n_hdlc_ldisc));
994 	n_hdlc_ldisc.magic		= TTY_LDISC_MAGIC;
995 	n_hdlc_ldisc.name          	= "hdlc";
996 	n_hdlc_ldisc.open		= n_hdlc_tty_open;
997 	n_hdlc_ldisc.close		= n_hdlc_tty_close;
998 	n_hdlc_ldisc.read		= n_hdlc_tty_read;
999 	n_hdlc_ldisc.write		= n_hdlc_tty_write;
1000 	n_hdlc_ldisc.ioctl		= n_hdlc_tty_ioctl;
1001 	n_hdlc_ldisc.poll		= n_hdlc_tty_poll;
1002 	n_hdlc_ldisc.receive_room	= n_hdlc_tty_room;
1003 	n_hdlc_ldisc.receive_buf	= n_hdlc_tty_receive;
1004 	n_hdlc_ldisc.write_wakeup	= n_hdlc_tty_wakeup;
1005 
1006 	status = tty_register_ldisc(N_HDLC, &n_hdlc_ldisc);
1007 	if (!status)
1008 		printk (KERN_INFO"N_HDLC line discipline registered.\n");
1009 	else
1010 		printk (KERN_ERR"error registering line discipline: %d\n",status);
1011 
1012 	if (status)
1013 		printk(KERN_INFO"N_HDLC: init failure %d\n", status);
1014 	return (status);
1015 
1016 }	/* end of init_module() */
1017 
n_hdlc_exit(void)1018 static void __exit n_hdlc_exit(void)
1019 {
1020 	int status;
1021 	/* Release tty registration of line discipline */
1022 	if ((status = tty_register_ldisc(N_HDLC, NULL)))
1023 		printk("N_HDLC: can't unregister line discipline (err = %d)\n", status);
1024 	else
1025 		printk("N_HDLC: line discipline unregistered\n");
1026 }
1027 
1028 module_init(n_hdlc_init);
1029 module_exit(n_hdlc_exit);
1030 
1031 EXPORT_NO_SYMBOLS;
1032