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