1 /* generic HDLC line discipline for Linux
3 * Written by Paul Fulghum paulkf@microgate.com
4 * for Microgate Corporation
6 * Microgate and SyncLink are registered trademarks of Microgate Corporation
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>
11 * Original release 01/11/99
12 * ==FILEDATE 19991217==
14 * This code is released under the GNU General Public License (GPL)
16 * This module implements the tty line discipline N_HDLC for use with
17 * tty device drivers that support bit-synchronous HDLC communications.
19 * All HDLC data is frame oriented which means:
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.
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.
38 * The HDLC line discipline queues the receive frames in seperate
39 * buffers so complete receive frames can be returned by the
42 * 3. tty read calls returns an entire frame of data or nothing.
44 * 4. all send and receive data is considered raw. No processing
45 * or translation is performed by the line discipline, regardless
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).
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).
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
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.
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.
80 #define HDLC_MAGIC 0x239e
81 #define HDLC_VERSION "1.13"
83 #include <linux/version.h>
84 #include <linux/config.h>
85 #include <linux/module.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>
94 #define VERSION(major,minor,patch) (((((major)<<8)+(minor))<<8)+(patch))
96 #if LINUX_VERSION_CODE < VERSION(2,1,14)
97 #include <linux/ioport.h>
100 #if LINUX_VERSION_CODE >= VERSION(2,1,23)
101 #include <linux/poll.h>
104 #include <linux/in.h>
105 #include <linux/malloc.h>
106 #include <linux/tty.h>
107 #include <linux/errno.h>
108 #include <linux/string.h> /* used in new tty drivers */
109 #include <linux/signal.h> /* used in new tty drivers */
110 #include <asm/system.h>
111 #include <asm/bitops.h>
112 #include <asm/termios.h>
113 #include <linux/if.h>
115 #include <linux/ioctl.h>
117 #ifdef CONFIG_KERNELD
118 #include <linux/kerneld.h>
121 #if LINUX_VERSION_CODE < VERSION(2,3,0)
122 typedef struct wait_queue
*wait_queue_head_t
;
123 #define DECLARE_WAITQUEUE(name,task) struct wait_queue (name) = {(task),NULL}
124 #define init_waitqueue_head(head) *(head) = NULL
125 #define set_current_state(a) current->state = (a)
128 #if LINUX_VERSION_CODE >= VERSION(2,1,4)
129 #include <asm/segment.h>
130 #define GET_USER(error,value,addr) error = get_user(value,addr)
131 #define COPY_FROM_USER(error,dest,src,size) error = copy_from_user(dest,src,size) ? -EFAULT : 0
132 #define PUT_USER(error,value,addr) error = put_user(value,addr)
133 #define COPY_TO_USER(error,dest,src,size) error = copy_to_user(dest,src,size) ? -EFAULT : 0
135 #if LINUX_VERSION_CODE >= VERSION(2,1,5)
136 #include <asm/uaccess.h>
139 #else /* 2.0.x and 2.1.x before 2.1.4 */
141 #define GET_USER(error,value,addr) \
143 error = verify_area (VERIFY_READ, (void *) addr, sizeof (value)); \
145 value = get_user(addr); \
148 #define COPY_FROM_USER(error,dest,src,size) \
150 error = verify_area (VERIFY_READ, (void *) src, size); \
152 memcpy_fromfs (dest, src, size); \
155 #define PUT_USER(error,value,addr) \
157 error = verify_area (VERIFY_WRITE, (void *) addr, sizeof (value)); \
159 put_user (value, addr); \
162 #define COPY_TO_USER(error,dest,src,size) \
164 error = verify_area (VERIFY_WRITE, (void *) dest, size); \
166 memcpy_tofs (dest, src, size); \
171 #if LINUX_VERSION_CODE < VERSION(2,1,0)
173 typedef int spinlock_t
;
174 #define spin_lock_init(a)
175 #define spin_lock_irqsave(a,b) {save_flags((b));cli();}
176 #define spin_unlock_irqrestore(a,b) {restore_flags((b));}
178 #define spin_unlock(a)
179 #define schedule_timeout(a){current->timeout = jiffies + (a); schedule();}
182 #if LINUX_VERSION_CODE < VERSION(2,1,37)
183 #define test_and_set_bit(nr, addr) set_bit(nr, addr)
186 #if LINUX_VERSION_CODE < VERSION(2,1,57)
187 #define signal_pending(p) ((p)->signal & ~(p)->blocked)
190 #if LINUX_VERSION_CODE < VERSION(2,1,25)
191 #define net_device_stats enet_statistics
194 #if LINUX_VERSION_CODE < VERSION(2,1,60)
195 typedef int rw_ret_t
;
196 typedef unsigned int rw_count_t
;
198 typedef ssize_t rw_ret_t
;
199 typedef size_t rw_count_t
;
203 * Buffers for individual HDLC frames
205 #define MAX_HDLC_FRAME_SIZE 65535
206 #define DEFAULT_RX_BUF_COUNT 10
207 #define MAX_RX_BUF_COUNT 60
208 #define DEFAULT_TX_BUF_COUNT 1
211 typedef struct _n_hdlc_buf
213 struct _n_hdlc_buf
*link
;
218 #define N_HDLC_BUF_SIZE (sizeof(N_HDLC_BUF)+maxframe)
220 typedef struct _n_hdlc_buf_list
230 * Per device instance data structure
233 int magic
; /* magic value for structure */
234 __u32 flags
; /* miscellaneous control flags */
236 struct tty_struct
*tty
; /* ptr to TTY structure */
237 struct tty_struct
*backup_tty
; /* TTY to use if tty gets closed */
239 /* Queues for select() functionality */
240 wait_queue_head_t read_wait
;
241 wait_queue_head_t write_wait
;
243 int tbusy
; /* reentrancy flag for tx wakeup code */
245 N_HDLC_BUF
*tbuf
; /* currently transmitting tx buffer */
246 N_HDLC_BUF_LIST tx_buf_list
; /* list of pending transmit frame buffers */
247 N_HDLC_BUF_LIST rx_buf_list
; /* list of received frame buffers */
248 N_HDLC_BUF_LIST tx_free_buf_list
; /* list unused transmit frame buffers */
249 N_HDLC_BUF_LIST rx_free_buf_list
; /* list unused received frame buffers */
253 * HDLC buffer list manipulation functions
255 void n_hdlc_buf_list_init(N_HDLC_BUF_LIST
*list
);
256 void n_hdlc_buf_put(N_HDLC_BUF_LIST
*list
,N_HDLC_BUF
*buf
);
257 N_HDLC_BUF
* n_hdlc_buf_get(N_HDLC_BUF_LIST
*list
);
259 /* Local functions */
261 static struct n_hdlc
*n_hdlc_alloc (void);
263 #if LINUX_VERSION_CODE >= VERSION(2,1,19)
264 MODULE_PARM(debuglevel
, "i");
265 MODULE_PARM(maxframe
, "i");
268 /* debug level can be set by insmod for debugging purposes */
269 #define DEBUG_LEVEL_INFO 1
272 /* max frame size for memory allocations */
273 ssize_t maxframe
=4096;
277 static rw_ret_t
n_hdlc_tty_read(struct tty_struct
*,
278 struct file
*, __u8
*, rw_count_t
);
279 static rw_ret_t
n_hdlc_tty_write(struct tty_struct
*,
280 struct file
*, const __u8
*, rw_count_t
);
281 static int n_hdlc_tty_ioctl(struct tty_struct
*,
282 struct file
*, unsigned int, unsigned long);
283 #if LINUX_VERSION_CODE < VERSION(2,1,23)
284 static int n_hdlc_tty_select (struct tty_struct
*tty
, struct inode
*inode
,
285 struct file
*filp
, int sel_type
, select_table
* wait
);
287 static unsigned int n_hdlc_tty_poll (struct tty_struct
*tty
, struct file
*filp
,
290 static int n_hdlc_tty_open (struct tty_struct
*);
291 static void n_hdlc_tty_close (struct tty_struct
*);
292 static int n_hdlc_tty_room (struct tty_struct
*tty
);
293 static void n_hdlc_tty_receive (struct tty_struct
*tty
,
294 const __u8
* cp
, char *fp
, int count
);
295 static void n_hdlc_tty_wakeup (struct tty_struct
*tty
);
297 #define bset(p,b) ((p)[(b) >> 5] |= (1 << ((b) & 0x1f)))
299 #define tty2n_hdlc(tty) ((struct n_hdlc *) ((tty)->disc_data))
300 #define n_hdlc2tty(n_hdlc) ((n_hdlc)->tty)
302 /* Define this string only once for all macro invocations */
303 static char szVersion
[] = HDLC_VERSION
;
307 * release an n_hdlc per device line discipline info structure
310 static void n_hdlc_release (struct n_hdlc
*n_hdlc
)
312 struct tty_struct
*tty
= n_hdlc2tty (n_hdlc
);
315 if (debuglevel
>= DEBUG_LEVEL_INFO
)
316 printk("%s(%d)n_hdlc_release() called\n",__FILE__
,__LINE__
);
318 /* Ensure that the n_hdlcd process is not hanging on select()/poll() */
319 wake_up_interruptible (&n_hdlc
->read_wait
);
320 wake_up_interruptible (&n_hdlc
->write_wait
);
322 if (tty
!= NULL
&& tty
->disc_data
== n_hdlc
)
323 tty
->disc_data
= NULL
; /* Break the tty->n_hdlc link */
325 /* Release transmit and receive buffers */
327 buf
= n_hdlc_buf_get(&n_hdlc
->rx_free_buf_list
);
334 buf
= n_hdlc_buf_get(&n_hdlc
->tx_free_buf_list
);
341 buf
= n_hdlc_buf_get(&n_hdlc
->rx_buf_list
);
348 buf
= n_hdlc_buf_get(&n_hdlc
->tx_buf_list
);
357 } /* end of n_hdlc_release() */
359 /* n_hdlc_tty_close()
361 * Called when the line discipline is changed to something
362 * else, the tty is closed, or the tty detects a hangup.
364 static void n_hdlc_tty_close(struct tty_struct
*tty
)
366 struct n_hdlc
*n_hdlc
= tty2n_hdlc (tty
);
368 if (debuglevel
>= DEBUG_LEVEL_INFO
)
369 printk("%s(%d)n_hdlc_tty_close() called\n",__FILE__
,__LINE__
);
371 if (n_hdlc
!= NULL
) {
372 if (n_hdlc
->magic
!= HDLC_MAGIC
) {
373 printk (KERN_WARNING
"n_hdlc: trying to close unopened tty!\n");
376 #if defined(TTY_NO_WRITE_SPLIT)
377 clear_bit(TTY_NO_WRITE_SPLIT
,&tty
->flags
);
379 tty
->disc_data
= NULL
;
380 if (tty
== n_hdlc
->backup_tty
)
381 n_hdlc
->backup_tty
= 0;
382 if (tty
!= n_hdlc
->tty
)
384 if (n_hdlc
->backup_tty
) {
385 n_hdlc
->tty
= n_hdlc
->backup_tty
;
387 n_hdlc_release (n_hdlc
);
392 if (debuglevel
>= DEBUG_LEVEL_INFO
)
393 printk("%s(%d)n_hdlc_tty_close() success\n",__FILE__
,__LINE__
);
395 } /* end of n_hdlc_tty_close() */
399 * called when line discipline changed to n_hdlc
401 * Arguments: tty pointer to tty info structure
402 * Return Value: 0 if success, otherwise error code
404 static int n_hdlc_tty_open (struct tty_struct
*tty
)
406 struct n_hdlc
*n_hdlc
= tty2n_hdlc (tty
);
408 if (debuglevel
>= DEBUG_LEVEL_INFO
)
409 printk("%s(%d)n_hdlc_tty_open() called (major=%u,minor=%u)\n",
411 MAJOR(tty
->device
), MINOR(tty
->device
));
413 /* There should not be an existing table for this slot. */
415 printk (KERN_ERR
"n_hdlc_tty_open:tty already associated!\n" );
419 n_hdlc
= n_hdlc_alloc();
421 printk (KERN_ERR
"n_hdlc_alloc failed\n");
425 tty
->disc_data
= n_hdlc
;
430 #if defined(TTY_NO_WRITE_SPLIT)
431 /* change tty_io write() to not split large writes into 8K chunks */
432 set_bit(TTY_NO_WRITE_SPLIT
,&tty
->flags
);
435 /* Flush any pending characters in the driver and discipline. */
437 if (tty
->ldisc
.flush_buffer
)
438 tty
->ldisc
.flush_buffer (tty
);
440 if (tty
->driver
.flush_buffer
)
441 tty
->driver
.flush_buffer (tty
);
443 if (debuglevel
>= DEBUG_LEVEL_INFO
)
444 printk("%s(%d)n_hdlc_tty_open() success\n",__FILE__
,__LINE__
);
448 } /* end of n_tty_hdlc_open() */
450 /* n_hdlc_send_frames()
452 * send frames on pending send buffer list until the
453 * driver does not accept a frame (busy)
454 * this function is called after adding a frame to the
455 * send buffer list and by the tty wakeup callback
457 * Arguments: n_hdlc pointer to ldisc instance data
458 * tty pointer to tty instance data
461 static void n_hdlc_send_frames (struct n_hdlc
*n_hdlc
, struct tty_struct
*tty
)
467 if (debuglevel
>= DEBUG_LEVEL_INFO
)
468 printk("%s(%d)n_hdlc_send_frames() called\n",__FILE__
,__LINE__
);
474 restore_flags(flags
);
478 restore_flags(flags
);
480 /* get current transmit buffer or get new transmit */
481 /* buffer from list of pending transmit buffers */
485 tbuf
= n_hdlc_buf_get(&n_hdlc
->tx_buf_list
);
488 if (debuglevel
>= DEBUG_LEVEL_INFO
)
489 printk("%s(%d)sending frame %p, count=%d\n",
490 __FILE__
,__LINE__
,tbuf
,tbuf
->count
);
492 /* Send the next block of data to device */
494 tty
->flags
|= (1 << TTY_DO_WRITE_WAKEUP
);
495 actual
= tty
->driver
.write(tty
, 0, tbuf
->buf
, tbuf
->count
);
497 /* if transmit error, throw frame away by */
498 /* pretending it was accepted by driver */
500 actual
= tbuf
->count
;
502 if (actual
== tbuf
->count
) {
503 if (debuglevel
>= DEBUG_LEVEL_INFO
)
504 printk("%s(%d)frame %p completed\n",
505 __FILE__
,__LINE__
,tbuf
);
507 /* free current transmit buffer */
508 n_hdlc_buf_put(&n_hdlc
->tx_free_buf_list
,tbuf
);
510 /* this tx buffer is done */
513 /* wait up sleeping writers */
514 wake_up_interruptible(&n_hdlc
->write_wait
);
516 /* get next pending transmit buffer */
517 tbuf
= n_hdlc_buf_get(&n_hdlc
->tx_buf_list
);
519 if (debuglevel
>= DEBUG_LEVEL_INFO
)
520 printk("%s(%d)frame %p pending\n",
521 __FILE__
,__LINE__
,tbuf
);
523 /* buffer not accepted by driver */
525 /* check if wake up code called since last write call */
529 /* set this buffer as pending buffer */
536 tty
->flags
&= ~(1 << TTY_DO_WRITE_WAKEUP
);
538 /* Clear the re-entry flag */
542 restore_flags(flags
);
544 if (debuglevel
>= DEBUG_LEVEL_INFO
)
545 printk("%s(%d)n_hdlc_send_frames() exit\n",__FILE__
,__LINE__
);
547 } /* end of n_hdlc_send_frames() */
549 /* n_hdlc_tty_wakeup()
551 * Callback for transmit wakeup. Called when low level
552 * device driver can accept more send data.
554 * Arguments: tty pointer to associated tty instance data
557 static void n_hdlc_tty_wakeup (struct tty_struct
*tty
)
559 struct n_hdlc
*n_hdlc
= tty2n_hdlc (tty
);
561 if (debuglevel
>= DEBUG_LEVEL_INFO
)
562 printk("%s(%d)n_hdlc_tty_wakeup() called\n",__FILE__
,__LINE__
);
567 if (tty
!= n_hdlc
->tty
) {
568 tty
->flags
&= ~(1 << TTY_DO_WRITE_WAKEUP
);
573 tty
->flags
&= ~(1 << TTY_DO_WRITE_WAKEUP
);
575 n_hdlc_send_frames (n_hdlc
, tty
);
577 } /* end of n_hdlc_tty_wakeup() */
581 * Callback function from tty driver. Return the amount of
582 * space left in the receiver's buffer to decide if remote
583 * transmitter is to be throttled.
585 * Arguments: tty pointer to associated tty instance data
586 * Return Value: number of bytes left in receive buffer
588 static int n_hdlc_tty_room (struct tty_struct
*tty
)
590 if (debuglevel
>= DEBUG_LEVEL_INFO
)
591 printk("%s(%d)n_hdlc_tty_room() called\n",__FILE__
,__LINE__
);
592 /* always return a larger number to prevent */
593 /* throttling of remote transmitter. */
595 } /* end of n_hdlc_tty_root() */
597 /* n_hdlc_tty_receive()
599 * Called by tty low level driver when receive data is
600 * available. Data is interpreted as one HDLC frame.
602 * Arguments: tty pointer to tty isntance data
603 * data pointer to received data
604 * flags pointer to flags for data
605 * count count of received data in bytes
609 static void n_hdlc_tty_receive(struct tty_struct
*tty
,
610 const __u8
* data
, char *flags
, int count
)
612 register struct n_hdlc
*n_hdlc
= tty2n_hdlc (tty
);
613 register N_HDLC_BUF
*buf
;
615 if (debuglevel
>= DEBUG_LEVEL_INFO
)
616 printk("%s(%d)n_hdlc_tty_receive() called count=%d\n",
617 __FILE__
,__LINE__
, count
);
619 /* This can happen if stuff comes in on the backup tty */
620 if (n_hdlc
== 0 || tty
!= n_hdlc
->tty
)
623 /* verify line is using HDLC discipline */
624 if (n_hdlc
->magic
!= HDLC_MAGIC
) {
625 printk("%s(%d) line not using HDLC discipline\n",
630 if ( count
>maxframe
) {
631 if (debuglevel
>= DEBUG_LEVEL_INFO
)
632 printk("%s(%d) rx count>maxframesize, data discarded\n",
637 /* get a free HDLC buffer */
638 buf
= n_hdlc_buf_get(&n_hdlc
->rx_free_buf_list
);
640 /* no buffers in free list, attempt to allocate another rx buffer */
641 /* unless the maximum count has been reached */
642 if (n_hdlc
->rx_buf_list
.count
< MAX_RX_BUF_COUNT
)
643 buf
= (N_HDLC_BUF
*)kmalloc(N_HDLC_BUF_SIZE
,GFP_ATOMIC
);
647 if (debuglevel
>= DEBUG_LEVEL_INFO
)
648 printk("%s(%d) no more rx buffers, data discarded\n",
653 /* copy received data to HDLC buffer */
654 memcpy(buf
->buf
,data
,count
);
657 /* add HDLC buffer to list of received frames */
658 n_hdlc_buf_put(&n_hdlc
->rx_buf_list
,buf
);
660 /* wake up any blocked reads and perform async signalling */
661 wake_up_interruptible (&n_hdlc
->read_wait
);
662 if (n_hdlc
->tty
->fasync
!= NULL
)
663 #if LINUX_VERSION_CODE < VERSION(2,3,0)
664 kill_fasync (n_hdlc
->tty
->fasync
, SIGIO
);
666 kill_fasync(&n_hdlc
->tty
->fasync
, SIGIO
, POLL_IN
);
668 } /* end of n_hdlc_tty_receive() */
672 * Called to retreive one frame of data (if available)
676 * tty pointer to tty instance data
677 * file pointer to open file object
678 * buf pointer to returned data buffer
679 * nr size of returned data buffer
683 * Number of bytes returned or error code
685 static rw_ret_t
n_hdlc_tty_read (struct tty_struct
*tty
,
686 struct file
*file
, __u8
* buf
, rw_count_t nr
)
688 struct n_hdlc
*n_hdlc
= tty2n_hdlc(tty
);
693 if (debuglevel
>= DEBUG_LEVEL_INFO
)
694 printk("%s(%d)n_hdlc_tty_read() called\n",__FILE__
,__LINE__
);
696 /* Validate the pointers */
700 /* verify user access to buffer */
701 error
= verify_area (VERIFY_WRITE
, buf
, nr
);
703 printk(KERN_WARNING
"%s(%d) n_hdlc_tty_read() can't verify user "
704 "buffer\n",__FILE__
,__LINE__
);
709 n_hdlc
= tty2n_hdlc (tty
);
710 if (!n_hdlc
|| n_hdlc
->magic
!= HDLC_MAGIC
||
714 rbuf
= n_hdlc_buf_get(&n_hdlc
->rx_buf_list
);
719 if (file
->f_flags
& O_NONBLOCK
)
722 interruptible_sleep_on (&n_hdlc
->read_wait
);
723 if (signal_pending(current
))
727 if (rbuf
->count
> nr
) {
728 /* frame too large for caller's buffer (discard frame) */
729 ret
= (rw_ret_t
)-EOVERFLOW
;
731 /* Copy the data to the caller's buffer */
732 COPY_TO_USER(error
,buf
,rbuf
->buf
,rbuf
->count
);
734 ret
= (rw_ret_t
)error
;
736 ret
= (rw_ret_t
)rbuf
->count
;
739 /* return HDLC buffer to free list unless the free list */
740 /* count has exceeded the default value, in which case the */
741 /* buffer is freed back to the OS to conserve memory */
742 if (n_hdlc
->rx_free_buf_list
.count
> DEFAULT_RX_BUF_COUNT
)
745 n_hdlc_buf_put(&n_hdlc
->rx_free_buf_list
,rbuf
);
749 } /* end of n_hdlc_tty_read() */
751 /* n_hdlc_tty_write()
753 * write a single frame of data to device
755 * Arguments: tty pointer to associated tty device instance data
756 * file pointer to file object data
757 * data pointer to transmit data (one frame)
758 * count size of transmit frame in bytes
760 * Return Value: number of bytes written (or error code)
762 static rw_ret_t
n_hdlc_tty_write (struct tty_struct
*tty
, struct file
*file
,
763 const __u8
* data
, rw_count_t count
)
765 struct n_hdlc
*n_hdlc
= tty2n_hdlc (tty
);
767 DECLARE_WAITQUEUE(wait
, current
);
770 if (debuglevel
>= DEBUG_LEVEL_INFO
)
771 printk("%s(%d)n_hdlc_tty_write() called count=%d\n",
772 __FILE__
,__LINE__
,count
);
774 /* Verify pointers */
778 if (n_hdlc
->magic
!= HDLC_MAGIC
)
781 /* verify frame size */
782 if (count
> maxframe
) {
783 if (debuglevel
& DEBUG_LEVEL_INFO
)
785 "n_hdlc_tty_write: truncating user packet "
786 "from %lu to %d\n", (unsigned long) count
,
791 /* Allocate transmit buffer */
792 tbuf
= n_hdlc_buf_get(&n_hdlc
->tx_free_buf_list
);
794 /* sleep until transmit buffer available */
795 add_wait_queue(&n_hdlc
->write_wait
, &wait
);
797 set_current_state(TASK_INTERRUPTIBLE
);
800 n_hdlc
= tty2n_hdlc (tty
);
801 if (!n_hdlc
|| n_hdlc
->magic
!= HDLC_MAGIC
||
802 tty
!= n_hdlc
->tty
) {
803 printk("n_hdlc_tty_write: %p invalid after wait!\n", n_hdlc
);
808 if (signal_pending(current
)) {
813 tbuf
= n_hdlc_buf_get(&n_hdlc
->tx_free_buf_list
);
815 set_current_state(TASK_RUNNING
);
816 remove_wait_queue(&n_hdlc
->write_wait
, &wait
);
820 /* Retrieve the user's buffer */
821 COPY_FROM_USER (error
, tbuf
->buf
, data
, count
);
823 /* return tx buffer to free list */
824 n_hdlc_buf_put(&n_hdlc
->tx_free_buf_list
,tbuf
);
827 tbuf
->count
= error
= count
;
828 n_hdlc_buf_put(&n_hdlc
->tx_buf_list
,tbuf
);
829 n_hdlc_send_frames(n_hdlc
,tty
);
835 } /* end of n_hdlc_tty_write() */
837 /* n_hdlc_tty_ioctl()
839 * Process IOCTL system call for the tty device.
843 * tty pointer to tty instance data
844 * file pointer to open file object for device
845 * cmd IOCTL command code
846 * arg argument for IOCTL call (cmd dependent)
848 * Return Value: Command dependent
850 static int n_hdlc_tty_ioctl (struct tty_struct
*tty
, struct file
* file
,
851 unsigned int cmd
, unsigned long arg
)
853 struct n_hdlc
*n_hdlc
= tty2n_hdlc (tty
);
858 if (debuglevel
>= DEBUG_LEVEL_INFO
)
859 printk("%s(%d)n_hdlc_tty_ioctl() called %d\n",
860 __FILE__
,__LINE__
,cmd
);
862 /* Verify the status of the device */
863 if (!n_hdlc
|| n_hdlc
->magic
!= HDLC_MAGIC
)
868 /* report count of read data available */
869 /* in next available frame (if any) */
870 spin_lock_irqsave(&n_hdlc
->rx_buf_list
.spinlock
,flags
);
871 if (n_hdlc
->rx_buf_list
.head
)
872 count
= n_hdlc
->rx_buf_list
.head
->count
;
875 spin_unlock_irqrestore(&n_hdlc
->rx_buf_list
.spinlock
,flags
);
876 PUT_USER (error
, count
, (int *) arg
);
880 /* get the pending tx byte count in the driver */
881 count
= tty
->driver
.chars_in_buffer
?
882 tty
->driver
.chars_in_buffer(tty
) : 0;
883 /* add size of next output frame in queue */
884 spin_lock_irqsave(&n_hdlc
->tx_buf_list
.spinlock
,flags
);
885 if (n_hdlc
->tx_buf_list
.head
)
886 count
+= n_hdlc
->tx_buf_list
.head
->count
;
887 spin_unlock_irqrestore(&n_hdlc
->tx_buf_list
.spinlock
,flags
);
888 PUT_USER (error
, count
, (int*)arg
);
892 error
= n_tty_ioctl (tty
, file
, cmd
, arg
);
897 } /* end of n_hdlc_tty_ioctl() */
899 #if LINUX_VERSION_CODE < VERSION(2,1,23)
900 /* n_hdlc_tty_select()
902 * Device select method. Determine if operation requires
903 * blocking and if so put appropriate wait queue in select
904 * table and return 0, otherwise return 1.
908 * tty pointer to tty device instance data
909 * inode pointer to inode for device
910 * filp pointer to file object
911 * sel_type identified the select type (read/write/exception)
912 * wait select table for adding wait queue if appropriate
916 * 1 if no need to block on operation
917 * 0 if must block and wait queue added to select table
919 static int n_hdlc_tty_select (struct tty_struct
*tty
, struct inode
*inode
,
920 struct file
*filp
, int sel_type
, select_table
* wait
)
922 struct n_hdlc
*n_hdlc
= tty2n_hdlc(tty
);
925 if (debuglevel
>= DEBUG_LEVEL_INFO
)
926 printk("%s(%d)n_hdlc_tty_select() called\n",__FILE__
,__LINE__
);
928 /* Verify the status of the device */
932 if (n_hdlc
->magic
!= HDLC_MAGIC
|| tty
!= n_hdlc
->tty
)
937 if (n_hdlc
->rx_buf_list
.head
)
940 case SEL_EX
: /* Exceptions or read errors */
941 /* Is this a pty link and the remote disconnected? */
942 if (tty
->flags
& (1 << TTY_OTHER_CLOSED
))
945 /* Is this a local link and the modem disconnected? */
946 if (tty_hung_up_p (filp
))
949 select_wait (&n_hdlc
->read_wait
, wait
);
953 /* Write mode. A write is allowed if there is no current transmission */
955 if (!n_hdlc
->tx_free_buf_list
.head
) {
956 select_wait (&n_hdlc
->write_wait
, wait
);
962 } /* end of n_hdlc_tty_select() */
964 #else /* 2.1.23 or later */
968 * TTY callback for poll system call. Determine which
969 * operations (read/write) will not block and return
974 * tty pointer to tty instance data
975 * filp pointer to open file object for device
976 * poll_table wait queue for operations
980 * bit mask containing info on which ops will not block
982 * Note: Called without the kernel lock held. Which is fine.
984 static unsigned int n_hdlc_tty_poll (struct tty_struct
*tty
,
985 struct file
*filp
, poll_table
* wait
)
987 struct n_hdlc
*n_hdlc
= tty2n_hdlc (tty
);
988 unsigned int mask
= 0;
990 if (debuglevel
>= DEBUG_LEVEL_INFO
)
991 printk("%s(%d)n_hdlc_tty_poll() called\n",__FILE__
,__LINE__
);
993 if (n_hdlc
&& n_hdlc
->magic
== HDLC_MAGIC
&& tty
== n_hdlc
->tty
) {
994 /* queue current process into any wait queue that */
995 /* may awaken in the future (read and write) */
996 #if LINUX_VERSION_CODE < VERSION(2,1,89)
997 poll_wait(&n_hdlc
->read_wait
, wait
);
998 poll_wait(&n_hdlc
->write_wait
, wait
);
1000 poll_wait(filp
, &n_hdlc
->read_wait
, wait
);
1001 poll_wait(filp
, &n_hdlc
->write_wait
, wait
);
1003 /* set bits for operations that wont block */
1004 if(n_hdlc
->rx_buf_list
.head
)
1005 mask
|= POLLIN
| POLLRDNORM
; /* readable */
1006 if(tty
->flags
& (1 << TTY_OTHER_CLOSED
))
1008 if(tty_hung_up_p(filp
))
1010 if(n_hdlc
->tx_free_buf_list
.head
)
1011 mask
|= POLLOUT
| POLLWRNORM
; /* writable */
1014 } /* end of n_hdlc_tty_poll() */
1020 * Allocate an n_hdlc instance data structure
1023 * Return Value: pointer to structure if success, otherwise 0
1025 static struct n_hdlc
*n_hdlc_alloc (void)
1027 struct n_hdlc
*n_hdlc
;
1031 n_hdlc
= (struct n_hdlc
*)kmalloc(sizeof(struct n_hdlc
), GFP_KERNEL
);
1035 memset(n_hdlc
, 0, sizeof(*n_hdlc
));
1037 n_hdlc_buf_list_init(&n_hdlc
->rx_free_buf_list
);
1038 n_hdlc_buf_list_init(&n_hdlc
->tx_free_buf_list
);
1039 n_hdlc_buf_list_init(&n_hdlc
->rx_buf_list
);
1040 n_hdlc_buf_list_init(&n_hdlc
->tx_buf_list
);
1042 /* allocate free rx buffer list */
1043 for(i
=0;i
<DEFAULT_RX_BUF_COUNT
;i
++) {
1044 buf
= (N_HDLC_BUF
*)kmalloc(N_HDLC_BUF_SIZE
,GFP_KERNEL
);
1046 n_hdlc_buf_put(&n_hdlc
->rx_free_buf_list
,buf
);
1047 else if (debuglevel
>= DEBUG_LEVEL_INFO
)
1048 printk("%s(%d)n_hdlc_alloc(), kalloc() failed for rx buffer %d\n",__FILE__
,__LINE__
, i
);
1051 /* allocate free tx buffer list */
1052 for(i
=0;i
<DEFAULT_TX_BUF_COUNT
;i
++) {
1053 buf
= (N_HDLC_BUF
*)kmalloc(N_HDLC_BUF_SIZE
,GFP_KERNEL
);
1055 n_hdlc_buf_put(&n_hdlc
->tx_free_buf_list
,buf
);
1056 else if (debuglevel
>= DEBUG_LEVEL_INFO
)
1057 printk("%s(%d)n_hdlc_alloc(), kalloc() failed for tx buffer %d\n",__FILE__
,__LINE__
, i
);
1060 /* Initialize the control block */
1061 n_hdlc
->magic
= HDLC_MAGIC
;
1064 init_waitqueue_head(&n_hdlc
->read_wait
);
1065 init_waitqueue_head(&n_hdlc
->write_wait
);
1069 } /* end of n_hdlc_alloc() */
1071 /* n_hdlc_buf_list_init()
1073 * initialize specified HDLC buffer list
1075 * Arguments: list pointer to buffer list
1076 * Return Value: None
1078 void n_hdlc_buf_list_init(N_HDLC_BUF_LIST
*list
)
1080 memset(list
,0,sizeof(N_HDLC_BUF_LIST
));
1081 spin_lock_init(&list
->spinlock
);
1082 } /* end of n_hdlc_buf_list_init() */
1086 * add specified HDLC buffer to tail of specified list
1090 * list pointer to buffer list
1091 * buf pointer to buffer
1093 * Return Value: None
1095 void n_hdlc_buf_put(N_HDLC_BUF_LIST
*list
,N_HDLC_BUF
*buf
)
1097 unsigned long flags
;
1098 spin_lock_irqsave(&list
->spinlock
,flags
);
1102 list
->tail
->link
= buf
;
1108 spin_unlock_irqrestore(&list
->spinlock
,flags
);
1110 } /* end of n_hdlc_buf_put() */
1114 * remove and return an HDLC buffer from the
1115 * head of the specified HDLC buffer list
1119 * list pointer to HDLC buffer list
1123 * pointer to HDLC buffer if available, otherwise NULL
1125 N_HDLC_BUF
* n_hdlc_buf_get(N_HDLC_BUF_LIST
*list
)
1127 unsigned long flags
;
1129 spin_lock_irqsave(&list
->spinlock
,flags
);
1133 list
->head
= buf
->link
;
1139 spin_unlock_irqrestore(&list
->spinlock
,flags
);
1142 } /* end of n_hdlc_buf_get() */
1146 * called when module is loading to register line discipline
1149 * Return Value: 0 if success, otherwise error code
1151 int init_module(void)
1153 static struct tty_ldisc n_hdlc_ldisc
;
1156 /* range check maxframe arg */
1159 else if ( maxframe
>65535)
1162 printk("HDLC line discipline: version %s, maxframe=%u\n",
1163 szVersion
, maxframe
);
1165 /* Register the tty discipline */
1167 memset(&n_hdlc_ldisc
, 0, sizeof (n_hdlc_ldisc
));
1168 n_hdlc_ldisc
.magic
= TTY_LDISC_MAGIC
;
1169 #if LINUX_VERSION_CODE >= VERSION(2,1,28)
1170 n_hdlc_ldisc
.name
= "hdlc";
1172 n_hdlc_ldisc
.open
= n_hdlc_tty_open
;
1173 n_hdlc_ldisc
.close
= n_hdlc_tty_close
;
1174 n_hdlc_ldisc
.read
= n_hdlc_tty_read
;
1175 n_hdlc_ldisc
.write
= n_hdlc_tty_write
;
1176 n_hdlc_ldisc
.ioctl
= n_hdlc_tty_ioctl
;
1177 #if LINUX_VERSION_CODE < VERSION(2,1,23)
1178 n_hdlc_ldisc
.select
= n_hdlc_tty_select
;
1180 n_hdlc_ldisc
.poll
= n_hdlc_tty_poll
;
1182 n_hdlc_ldisc
.receive_room
= n_hdlc_tty_room
;
1183 n_hdlc_ldisc
.receive_buf
= n_hdlc_tty_receive
;
1184 n_hdlc_ldisc
.write_wakeup
= n_hdlc_tty_wakeup
;
1186 status
= tty_register_ldisc(N_HDLC
, &n_hdlc_ldisc
);
1188 printk (KERN_INFO
"N_HDLC line discipline registered.\n");
1190 printk (KERN_ERR
"error registering line discipline: %d\n",status
);
1193 printk(KERN_INFO
"N_HDLC: init failure %d\n", status
);
1196 } /* end of init_module() */
1200 * called when module is unloading to unregister line discipline
1203 * Return Value: None
1205 void cleanup_module(void)
1208 /* Release tty registration of line discipline */
1209 if ((status
= tty_register_ldisc(N_HDLC
, NULL
)))
1210 printk("N_HDLC: can't unregister line discipline (err = %d)\n", status
);
1212 printk("N_HDLC: line discipline unregistered\n");