n_hdlc.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:27k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  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.3 2001/11/08 16:16:03 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. #define HDLC_MAGIC 0x239e
  80. #define HDLC_VERSION "$Revision: 3.3 $"
  81. #include <linux/version.h>
  82. #include <linux/config.h>
  83. #include <linux/module.h>
  84. #include <linux/init.h>
  85. #include <linux/kernel.h>
  86. #include <linux/sched.h>
  87. #include <linux/types.h>
  88. #include <linux/fcntl.h>
  89. #include <linux/interrupt.h>
  90. #include <linux/ptrace.h>
  91. #undef VERSION
  92. #define VERSION(major,minor,patch) (((((major)<<8)+(minor))<<8)+(patch))
  93. #include <linux/poll.h>
  94. #include <linux/in.h>
  95. #include <linux/slab.h>
  96. #include <linux/tty.h>
  97. #include <linux/errno.h>
  98. #include <linux/string.h> /* used in new tty drivers */
  99. #include <linux/signal.h> /* used in new tty drivers */
  100. #include <asm/system.h>
  101. #include <asm/bitops.h>
  102. #include <asm/termios.h>
  103. #include <linux/if.h>
  104. #include <linux/ioctl.h>
  105. #ifdef CONFIG_KERNELD
  106. #include <linux/kerneld.h>
  107. #endif
  108. #include <asm/segment.h>
  109. #define GET_USER(error,value,addr) error = get_user(value,addr)
  110. #define COPY_FROM_USER(error,dest,src,size) error = copy_from_user(dest,src,size) ? -EFAULT : 0
  111. #define PUT_USER(error,value,addr) error = put_user(value,addr)
  112. #define COPY_TO_USER(error,dest,src,size) error = copy_to_user(dest,src,size) ? -EFAULT : 0
  113. #include <asm/uaccess.h>
  114. typedef ssize_t rw_ret_t;
  115. typedef size_t rw_count_t;
  116. /*
  117.  * Buffers for individual HDLC frames
  118.  */
  119. #define MAX_HDLC_FRAME_SIZE 65535 
  120. #define DEFAULT_RX_BUF_COUNT 10
  121. #define MAX_RX_BUF_COUNT 60
  122. #define DEFAULT_TX_BUF_COUNT 1
  123. typedef struct _n_hdlc_buf
  124. {
  125. struct _n_hdlc_buf *link;
  126. int count;
  127. char buf[1];
  128. } N_HDLC_BUF;
  129. #define N_HDLC_BUF_SIZE (sizeof(N_HDLC_BUF)+maxframe)
  130. typedef struct _n_hdlc_buf_list
  131. {
  132. N_HDLC_BUF *head;
  133. N_HDLC_BUF *tail;
  134. int count;
  135. spinlock_t spinlock;
  136. } N_HDLC_BUF_LIST;
  137. /*
  138.  * Per device instance data structure
  139.  */
  140. struct n_hdlc {
  141. int magic; /* magic value for structure */
  142. __u32 flags; /* miscellaneous control flags */
  143. struct tty_struct *tty; /* ptr to TTY structure */
  144. struct tty_struct *backup_tty; /* TTY to use if tty gets closed */
  145. int tbusy; /* reentrancy flag for tx wakeup code */
  146. int woke_up;
  147. N_HDLC_BUF *tbuf; /* currently transmitting tx buffer */
  148. N_HDLC_BUF_LIST tx_buf_list; /* list of pending transmit frame buffers */
  149. N_HDLC_BUF_LIST rx_buf_list; /* list of received frame buffers */
  150. N_HDLC_BUF_LIST tx_free_buf_list; /* list unused transmit frame buffers */
  151. N_HDLC_BUF_LIST rx_free_buf_list; /* list unused received frame buffers */
  152. };
  153. /*
  154.  * HDLC buffer list manipulation functions
  155.  */
  156. void n_hdlc_buf_list_init(N_HDLC_BUF_LIST *list);
  157. void n_hdlc_buf_put(N_HDLC_BUF_LIST *list,N_HDLC_BUF *buf);
  158. N_HDLC_BUF* n_hdlc_buf_get(N_HDLC_BUF_LIST *list);
  159. /* Local functions */
  160. static struct n_hdlc *n_hdlc_alloc (void);
  161. MODULE_PARM(debuglevel, "i");
  162. MODULE_PARM(maxframe, "i");
  163. /* debug level can be set by insmod for debugging purposes */
  164. #define DEBUG_LEVEL_INFO 1
  165. int debuglevel=0;
  166. /* max frame size for memory allocations */
  167. ssize_t maxframe=4096;
  168. /* TTY callbacks */
  169. static rw_ret_t n_hdlc_tty_read(struct tty_struct *,
  170. struct file *, __u8 *, rw_count_t);
  171. static rw_ret_t n_hdlc_tty_write(struct tty_struct *,
  172. struct file *, const __u8 *, rw_count_t);
  173. static int n_hdlc_tty_ioctl(struct tty_struct *,
  174. struct file *, unsigned int, unsigned long);
  175. static unsigned int n_hdlc_tty_poll (struct tty_struct *tty, struct file *filp,
  176.   poll_table * wait);
  177. static int n_hdlc_tty_open (struct tty_struct *);
  178. static void n_hdlc_tty_close (struct tty_struct *);
  179. static int n_hdlc_tty_room (struct tty_struct *tty);
  180. static void n_hdlc_tty_receive (struct tty_struct *tty,
  181. const __u8 * cp, char *fp, int count);
  182. static void n_hdlc_tty_wakeup (struct tty_struct *tty);
  183. #define bset(p,b) ((p)[(b) >> 5] |= (1 << ((b) & 0x1f)))
  184. #define tty2n_hdlc(tty) ((struct n_hdlc *) ((tty)->disc_data))
  185. #define n_hdlc2tty(n_hdlc) ((n_hdlc)->tty)
  186. /* Define this string only once for all macro invocations */
  187. static char szVersion[] = HDLC_VERSION;
  188. /* n_hdlc_release()
  189.  *
  190.  * release an n_hdlc per device line discipline info structure
  191.  *
  192.  */
  193. static void n_hdlc_release (struct n_hdlc *n_hdlc)
  194. {
  195. struct tty_struct *tty = n_hdlc2tty (n_hdlc);
  196. N_HDLC_BUF *buf;
  197. if (debuglevel >= DEBUG_LEVEL_INFO)
  198. printk("%s(%d)n_hdlc_release() calledn",__FILE__,__LINE__);
  199. /* Ensure that the n_hdlcd process is not hanging on select()/poll() */
  200. wake_up_interruptible (&tty->read_wait);
  201. wake_up_interruptible (&tty->write_wait);
  202. if (tty != NULL && tty->disc_data == n_hdlc)
  203. tty->disc_data = NULL; /* Break the tty->n_hdlc link */
  204. /* Release transmit and receive buffers */
  205. for(;;) {
  206. buf = n_hdlc_buf_get(&n_hdlc->rx_free_buf_list);
  207. if (buf) {
  208. kfree(buf);
  209. } else
  210. break;
  211. }
  212. for(;;) {
  213. buf = n_hdlc_buf_get(&n_hdlc->tx_free_buf_list);
  214. if (buf) {
  215. kfree(buf);
  216. } else
  217. break;
  218. }
  219. for(;;) {
  220. buf = n_hdlc_buf_get(&n_hdlc->rx_buf_list);
  221. if (buf) {
  222. kfree(buf);
  223. } else
  224. break;
  225. }
  226. for(;;) {
  227. buf = n_hdlc_buf_get(&n_hdlc->tx_buf_list);
  228. if (buf) {
  229. kfree(buf);
  230. } else
  231. break;
  232. }
  233. kfree(n_hdlc);
  234. } /* end of n_hdlc_release() */
  235. /* n_hdlc_tty_close()
  236.  *
  237.  * Called when the line discipline is changed to something
  238.  * else, the tty is closed, or the tty detects a hangup.
  239.  */
  240. static void n_hdlc_tty_close(struct tty_struct *tty)
  241. {
  242. struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
  243. if (debuglevel >= DEBUG_LEVEL_INFO)
  244. printk("%s(%d)n_hdlc_tty_close() calledn",__FILE__,__LINE__);
  245. if (n_hdlc != NULL) {
  246. if (n_hdlc->magic != HDLC_MAGIC) {
  247. printk (KERN_WARNING"n_hdlc: trying to close unopened tty!n");
  248. return;
  249. }
  250. #if defined(TTY_NO_WRITE_SPLIT)
  251. clear_bit(TTY_NO_WRITE_SPLIT,&tty->flags);
  252. #endif
  253. tty->disc_data = NULL;
  254. if (tty == n_hdlc->backup_tty)
  255. n_hdlc->backup_tty = 0;
  256. if (tty != n_hdlc->tty)
  257. return;
  258. if (n_hdlc->backup_tty) {
  259. n_hdlc->tty = n_hdlc->backup_tty;
  260. } else {
  261. n_hdlc_release (n_hdlc);
  262. MOD_DEC_USE_COUNT;
  263. }
  264. }
  265. if (debuglevel >= DEBUG_LEVEL_INFO)
  266. printk("%s(%d)n_hdlc_tty_close() successn",__FILE__,__LINE__);
  267. } /* end of n_hdlc_tty_close() */
  268. /* n_hdlc_tty_open
  269.  * 
  270.  *  called when line discipline changed to n_hdlc
  271.  * 
  272.  * Arguments: tty pointer to tty info structure
  273.  * Return Value: 0 if success, otherwise error code
  274.  */
  275. static int n_hdlc_tty_open (struct tty_struct *tty)
  276. {
  277. struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
  278. if (debuglevel >= DEBUG_LEVEL_INFO)
  279. printk("%s(%d)n_hdlc_tty_open() called (major=%u,minor=%u)n",
  280. __FILE__,__LINE__,
  281. MAJOR(tty->device), MINOR(tty->device));
  282. /* There should not be an existing table for this slot. */
  283. if (n_hdlc) {
  284. printk (KERN_ERR"n_hdlc_tty_open:tty already associated!n" );
  285. return -EEXIST;
  286. }
  287. n_hdlc = n_hdlc_alloc();
  288. if (!n_hdlc) {
  289. printk (KERN_ERR "n_hdlc_alloc failedn");
  290. return -ENFILE;
  291. }
  292. tty->disc_data = n_hdlc;
  293. n_hdlc->tty    = tty;
  294. MOD_INC_USE_COUNT;
  295. #if defined(TTY_NO_WRITE_SPLIT)
  296. /* change tty_io write() to not split large writes into 8K chunks */
  297. set_bit(TTY_NO_WRITE_SPLIT,&tty->flags);
  298. #endif
  299. /* Flush any pending characters in the driver and discipline. */
  300. if (tty->ldisc.flush_buffer)
  301. tty->ldisc.flush_buffer (tty);
  302. if (tty->driver.flush_buffer)
  303. tty->driver.flush_buffer (tty);
  304. if (debuglevel >= DEBUG_LEVEL_INFO)
  305. printk("%s(%d)n_hdlc_tty_open() successn",__FILE__,__LINE__);
  306. return 0;
  307. } /* end of n_tty_hdlc_open() */
  308. /* n_hdlc_send_frames()
  309.  * 
  310.  *  send frames on pending send buffer list until the
  311.  *  driver does not accept a frame (busy)
  312.  *  this function is called after adding a frame to the
  313.  *  send buffer list and by the tty wakeup callback
  314.  * 
  315.  * Arguments: n_hdlc pointer to ldisc instance data
  316.  *  tty pointer to tty instance data
  317.  * Return Value: None
  318.  */
  319. static void n_hdlc_send_frames (struct n_hdlc *n_hdlc, struct tty_struct *tty)
  320. {
  321. register int actual;
  322. unsigned long flags;
  323. N_HDLC_BUF *tbuf;
  324. if (debuglevel >= DEBUG_LEVEL_INFO)
  325. printk("%s(%d)n_hdlc_send_frames() calledn",__FILE__,__LINE__);
  326.  check_again:
  327. save_flags(flags);
  328. cli ();
  329. if (n_hdlc->tbusy) {
  330. n_hdlc->woke_up = 1;
  331. restore_flags(flags);
  332. return;
  333. }
  334. n_hdlc->tbusy = 1;
  335. n_hdlc->woke_up = 0;
  336. restore_flags(flags);
  337. /* get current transmit buffer or get new transmit */
  338. /* buffer from list of pending transmit buffers */
  339. tbuf = n_hdlc->tbuf;
  340. if (!tbuf)
  341. tbuf = n_hdlc_buf_get(&n_hdlc->tx_buf_list);
  342. while (tbuf) {
  343. if (debuglevel >= DEBUG_LEVEL_INFO)
  344. printk("%s(%d)sending frame %p, count=%dn",
  345. __FILE__,__LINE__,tbuf,tbuf->count);
  346. /* Send the next block of data to device */
  347. tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
  348. actual = tty->driver.write(tty, 0, tbuf->buf, tbuf->count);
  349.     
  350. /* if transmit error, throw frame away by */
  351. /* pretending it was accepted by driver */
  352. if (actual < 0)
  353. actual = tbuf->count;
  354. if (actual == tbuf->count) {
  355. if (debuglevel >= DEBUG_LEVEL_INFO)
  356. printk("%s(%d)frame %p completedn",
  357. __FILE__,__LINE__,tbuf);
  358. /* free current transmit buffer */
  359. n_hdlc_buf_put(&n_hdlc->tx_free_buf_list,tbuf);
  360. /* this tx buffer is done */
  361. n_hdlc->tbuf = NULL;
  362. /* wait up sleeping writers */
  363. wake_up_interruptible(&tty->write_wait);
  364. /* get next pending transmit buffer */
  365. tbuf = n_hdlc_buf_get(&n_hdlc->tx_buf_list);
  366. } else {
  367. if (debuglevel >= DEBUG_LEVEL_INFO)
  368. printk("%s(%d)frame %p pendingn",
  369. __FILE__,__LINE__,tbuf);
  370. /* buffer not accepted by driver */
  371. /* set this buffer as pending buffer */
  372. n_hdlc->tbuf = tbuf;
  373. break;
  374. }
  375. }
  376. if (!tbuf)
  377. tty->flags  &= ~(1 << TTY_DO_WRITE_WAKEUP);
  378. /* Clear the re-entry flag */
  379. save_flags(flags);
  380. cli ();
  381. n_hdlc->tbusy = 0;
  382. restore_flags(flags);
  383.         if (n_hdlc->woke_up)
  384.   goto check_again;
  385. if (debuglevel >= DEBUG_LEVEL_INFO)
  386. printk("%s(%d)n_hdlc_send_frames() exitn",__FILE__,__LINE__);
  387. } /* end of n_hdlc_send_frames() */
  388. /* n_hdlc_tty_wakeup()
  389.  *
  390.  * Callback for transmit wakeup. Called when low level
  391.  * device driver can accept more send data.
  392.  *
  393.  * Arguments: tty pointer to associated tty instance data
  394.  * Return Value: None
  395.  */
  396. static void n_hdlc_tty_wakeup (struct tty_struct *tty)
  397. {
  398. struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
  399. if (debuglevel >= DEBUG_LEVEL_INFO)
  400. printk("%s(%d)n_hdlc_tty_wakeup() calledn",__FILE__,__LINE__);
  401. if (!n_hdlc)
  402. return;
  403. if (tty != n_hdlc->tty) {
  404. tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
  405. return;
  406. }
  407. n_hdlc_send_frames (n_hdlc, tty);
  408. } /* end of n_hdlc_tty_wakeup() */
  409. /* n_hdlc_tty_room()
  410.  * 
  411.  * Callback function from tty driver. Return the amount of 
  412.  * space left in the receiver's buffer to decide if remote
  413.  * transmitter is to be throttled.
  414.  *
  415.  * Arguments: tty pointer to associated tty instance data
  416.  * Return Value: number of bytes left in receive buffer
  417.  */
  418. static int n_hdlc_tty_room (struct tty_struct *tty)
  419. {
  420. if (debuglevel >= DEBUG_LEVEL_INFO)
  421. printk("%s(%d)n_hdlc_tty_room() calledn",__FILE__,__LINE__);
  422. /* always return a larger number to prevent */
  423. /* throttling of remote transmitter. */
  424. return 65536;
  425. } /* end of n_hdlc_tty_root() */
  426. /* n_hdlc_tty_receive()
  427.  * 
  428.  *  Called by tty low level driver when receive data is
  429.  *  available. Data is interpreted as one HDLC frame.
  430.  * 
  431.  * Arguments:   tty pointer to tty isntance data
  432.  *  data pointer to received data
  433.  *  flags pointer to flags for data
  434.  *  count count of received data in bytes
  435.  * 
  436.  * Return Value: None
  437.  */
  438. static void n_hdlc_tty_receive(struct tty_struct *tty,
  439. const __u8 * data, char *flags, int count)
  440. {
  441. register struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
  442. register N_HDLC_BUF *buf;
  443. if (debuglevel >= DEBUG_LEVEL_INFO)
  444. printk("%s(%d)n_hdlc_tty_receive() called count=%dn",
  445. __FILE__,__LINE__, count);
  446. /* This can happen if stuff comes in on the backup tty */
  447. if (n_hdlc == 0 || tty != n_hdlc->tty)
  448. return;
  449. /* verify line is using HDLC discipline */
  450. if (n_hdlc->magic != HDLC_MAGIC) {
  451. printk("%s(%d) line not using HDLC disciplinen",
  452. __FILE__,__LINE__);
  453. return;
  454. }
  455. if ( count>maxframe ) {
  456. if (debuglevel >= DEBUG_LEVEL_INFO)
  457. printk("%s(%d) rx count>maxframesize, data discardedn",
  458.        __FILE__,__LINE__);
  459. return;
  460. }
  461. /* get a free HDLC buffer */
  462. buf = n_hdlc_buf_get(&n_hdlc->rx_free_buf_list);
  463. if (!buf) {
  464. /* no buffers in free list, attempt to allocate another rx buffer */
  465. /* unless the maximum count has been reached */
  466. if (n_hdlc->rx_buf_list.count < MAX_RX_BUF_COUNT)
  467. buf = (N_HDLC_BUF*)kmalloc(N_HDLC_BUF_SIZE,GFP_ATOMIC);
  468. }
  469. if (!buf) {
  470. if (debuglevel >= DEBUG_LEVEL_INFO)
  471. printk("%s(%d) no more rx buffers, data discardedn",
  472.        __FILE__,__LINE__);
  473. return;
  474. }
  475. /* copy received data to HDLC buffer */
  476. memcpy(buf->buf,data,count);
  477. buf->count=count;
  478. /* add HDLC buffer to list of received frames */
  479. n_hdlc_buf_put(&n_hdlc->rx_buf_list,buf);
  480. /* wake up any blocked reads and perform async signalling */
  481. wake_up_interruptible (&tty->read_wait);
  482. if (n_hdlc->tty->fasync != NULL)
  483. kill_fasync (&n_hdlc->tty->fasync, SIGIO, POLL_IN);
  484. } /* end of n_hdlc_tty_receive() */
  485. /* n_hdlc_tty_read()
  486.  * 
  487.  *  Called to retreive one frame of data (if available)
  488.  * 
  489.  * Arguments:
  490.  * 
  491.  *  tty pointer to tty instance data
  492.  *  file pointer to open file object
  493.  *  buf pointer to returned data buffer
  494.  *  nr size of returned data buffer
  495.  * 
  496.  * Return Value:
  497.  * 
  498.  *  Number of bytes returned or error code
  499.  */
  500. static rw_ret_t n_hdlc_tty_read (struct tty_struct *tty,
  501. struct file *file, __u8 * buf, rw_count_t nr)
  502. {
  503. struct n_hdlc *n_hdlc = tty2n_hdlc(tty);
  504. int error;
  505. rw_ret_t ret;
  506. N_HDLC_BUF *rbuf;
  507. if (debuglevel >= DEBUG_LEVEL_INFO)
  508. printk("%s(%d)n_hdlc_tty_read() calledn",__FILE__,__LINE__);
  509. /* Validate the pointers */
  510. if (!n_hdlc)
  511. return -EIO;
  512. /* verify user access to buffer */
  513. error = verify_area (VERIFY_WRITE, buf, nr);
  514. if (error != 0) {
  515. printk(KERN_WARNING"%s(%d) n_hdlc_tty_read() can't verify user "
  516. "buffern",__FILE__,__LINE__);
  517. return (error);
  518. }
  519. for (;;) {
  520. if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
  521. return -EIO;
  522. n_hdlc = tty2n_hdlc (tty);
  523. if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC ||
  524.  tty != n_hdlc->tty)
  525. return 0;
  526. rbuf = n_hdlc_buf_get(&n_hdlc->rx_buf_list);
  527. if (rbuf)
  528. break;
  529. /* no data */
  530. if (file->f_flags & O_NONBLOCK)
  531. return -EAGAIN;
  532. interruptible_sleep_on (&tty->read_wait);
  533. if (signal_pending(current))
  534. return -EINTR;
  535. }
  536. if (rbuf->count > nr) {
  537. /* frame too large for caller's buffer (discard frame) */
  538. ret = (rw_ret_t)-EOVERFLOW;
  539. } else {
  540. /* Copy the data to the caller's buffer */
  541. COPY_TO_USER(error,buf,rbuf->buf,rbuf->count);
  542. if (error)
  543. ret = (rw_ret_t)error;
  544. else
  545. ret = (rw_ret_t)rbuf->count;
  546. }
  547. /* return HDLC buffer to free list unless the free list */
  548. /* count has exceeded the default value, in which case the */
  549. /* buffer is freed back to the OS to conserve memory */
  550. if (n_hdlc->rx_free_buf_list.count > DEFAULT_RX_BUF_COUNT)
  551. kfree(rbuf);
  552. else
  553. n_hdlc_buf_put(&n_hdlc->rx_free_buf_list,rbuf);
  554. return ret;
  555. } /* end of n_hdlc_tty_read() */
  556. /* n_hdlc_tty_write()
  557.  * 
  558.  *  write a single frame of data to device
  559.  * 
  560.  * Arguments: tty pointer to associated tty device instance data
  561.  *  file pointer to file object data
  562.  *  data pointer to transmit data (one frame)
  563.  *  count size of transmit frame in bytes
  564.  * 
  565.  * Return Value: number of bytes written (or error code)
  566.  */
  567. static rw_ret_t n_hdlc_tty_write (struct tty_struct *tty, struct file *file,
  568. const __u8 * data, rw_count_t count)
  569. {
  570. struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
  571. int error = 0;
  572. DECLARE_WAITQUEUE(wait, current);
  573. N_HDLC_BUF *tbuf;
  574. if (debuglevel >= DEBUG_LEVEL_INFO)
  575. printk("%s(%d)n_hdlc_tty_write() called count=%dn",
  576. __FILE__,__LINE__,count);
  577. /* Verify pointers */
  578. if (!n_hdlc)
  579. return -EIO;
  580. if (n_hdlc->magic != HDLC_MAGIC)
  581. return -EIO;
  582. /* verify frame size */
  583. if (count > maxframe ) {
  584. if (debuglevel & DEBUG_LEVEL_INFO)
  585. printk (KERN_WARNING
  586. "n_hdlc_tty_write: truncating user packet "
  587. "from %lu to %dn", (unsigned long) count,
  588. maxframe );
  589. count = maxframe;
  590. }
  591. add_wait_queue(&tty->write_wait, &wait);
  592. set_current_state(TASK_INTERRUPTIBLE);
  593. /* Allocate transmit buffer */
  594. /* sleep until transmit buffer available */
  595. while (!(tbuf = n_hdlc_buf_get(&n_hdlc->tx_free_buf_list))) {
  596. schedule();
  597. n_hdlc = tty2n_hdlc (tty);
  598. if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC || 
  599.     tty != n_hdlc->tty) {
  600. printk("n_hdlc_tty_write: %p invalid after wait!n", n_hdlc);
  601. error = -EIO;
  602. break;
  603. }
  604. if (signal_pending(current)) {
  605. error = -EINTR;
  606. break;
  607. }
  608. }
  609. set_current_state(TASK_RUNNING);
  610. remove_wait_queue(&tty->write_wait, &wait);
  611. if (!error) {
  612. /* Retrieve the user's buffer */
  613. COPY_FROM_USER (error, tbuf->buf, data, count);
  614. if (error) {
  615. /* return tx buffer to free list */
  616. n_hdlc_buf_put(&n_hdlc->tx_free_buf_list,tbuf);
  617. } else {
  618. /* Send the data */
  619. tbuf->count = error = count;
  620. n_hdlc_buf_put(&n_hdlc->tx_buf_list,tbuf);
  621. n_hdlc_send_frames(n_hdlc,tty);
  622. }
  623. }
  624. return error;
  625. } /* end of n_hdlc_tty_write() */
  626. /* n_hdlc_tty_ioctl()
  627.  *
  628.  * Process IOCTL system call for the tty device.
  629.  *
  630.  * Arguments:
  631.  *
  632.  * tty pointer to tty instance data
  633.  * file pointer to open file object for device
  634.  * cmd IOCTL command code
  635.  * arg argument for IOCTL call (cmd dependent)
  636.  *
  637.  * Return Value: Command dependent
  638.  */
  639. static int n_hdlc_tty_ioctl (struct tty_struct *tty, struct file * file,
  640.                unsigned int cmd, unsigned long arg)
  641. {
  642. struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
  643. int error = 0;
  644. int count;
  645. unsigned long flags;
  646. if (debuglevel >= DEBUG_LEVEL_INFO)
  647. printk("%s(%d)n_hdlc_tty_ioctl() called %dn",
  648. __FILE__,__LINE__,cmd);
  649. /* Verify the status of the device */
  650. if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC)
  651. return -EBADF;
  652. switch (cmd) {
  653. case FIONREAD:
  654. /* report count of read data available */
  655. /* in next available frame (if any) */
  656. spin_lock_irqsave(&n_hdlc->rx_buf_list.spinlock,flags);
  657. if (n_hdlc->rx_buf_list.head)
  658. count = n_hdlc->rx_buf_list.head->count;
  659. else
  660. count = 0;
  661. spin_unlock_irqrestore(&n_hdlc->rx_buf_list.spinlock,flags);
  662. PUT_USER (error, count, (int *) arg);
  663. break;
  664. case TIOCOUTQ:
  665. /* get the pending tx byte count in the driver */
  666. count = tty->driver.chars_in_buffer ?
  667. tty->driver.chars_in_buffer(tty) : 0;
  668. /* add size of next output frame in queue */
  669. spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock,flags);
  670. if (n_hdlc->tx_buf_list.head)
  671. count += n_hdlc->tx_buf_list.head->count;
  672. spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock,flags);
  673. PUT_USER (error, count, (int*)arg);
  674. break;
  675. default:
  676. error = n_tty_ioctl (tty, file, cmd, arg);
  677. break;
  678. }
  679. return error;
  680. } /* end of n_hdlc_tty_ioctl() */
  681. /* n_hdlc_tty_poll()
  682.  * 
  683.  *  TTY callback for poll system call. Determine which 
  684.  *  operations (read/write) will not block and return
  685.  *  info to caller.
  686.  * 
  687.  * Arguments:
  688.  * 
  689.  *  tty pointer to tty instance data
  690.  *  filp pointer to open file object for device
  691.  *  poll_table wait queue for operations
  692.  * 
  693.  * Return Value:
  694.  * 
  695.  *  bit mask containing info on which ops will not block
  696.  */
  697. static unsigned int n_hdlc_tty_poll (struct tty_struct *tty,
  698.  struct file *filp, poll_table * wait)
  699. {
  700. struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
  701. unsigned int mask = 0;
  702. if (debuglevel >= DEBUG_LEVEL_INFO)
  703. printk("%s(%d)n_hdlc_tty_poll() calledn",__FILE__,__LINE__);
  704. if (n_hdlc && n_hdlc->magic == HDLC_MAGIC && tty == n_hdlc->tty) {
  705. /* queue current process into any wait queue that */
  706. /* may awaken in the future (read and write) */
  707. poll_wait(filp, &tty->read_wait, wait);
  708. poll_wait(filp, &tty->write_wait, wait);
  709. /* set bits for operations that wont block */
  710. if(n_hdlc->rx_buf_list.head)
  711. mask |= POLLIN | POLLRDNORM; /* readable */
  712. if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
  713. mask |= POLLHUP;
  714. if(tty_hung_up_p(filp))
  715. mask |= POLLHUP;
  716. if(n_hdlc->tx_free_buf_list.head)
  717. mask |= POLLOUT | POLLWRNORM; /* writable */
  718. }
  719. return mask;
  720. } /* end of n_hdlc_tty_poll() */
  721. /* n_hdlc_alloc()
  722.  * 
  723.  *  Allocate an n_hdlc instance data structure
  724.  *
  725.  * Arguments: None
  726.  * Return Value: pointer to structure if success, otherwise 0
  727.  */
  728. static struct n_hdlc *n_hdlc_alloc (void)
  729. {
  730. struct n_hdlc *n_hdlc;
  731. N_HDLC_BUF *buf;
  732. int i;
  733. n_hdlc = (struct n_hdlc *)kmalloc(sizeof(struct n_hdlc), GFP_KERNEL);
  734. if (!n_hdlc)
  735. return 0;
  736. memset(n_hdlc, 0, sizeof(*n_hdlc));
  737. n_hdlc_buf_list_init(&n_hdlc->rx_free_buf_list);
  738. n_hdlc_buf_list_init(&n_hdlc->tx_free_buf_list);
  739. n_hdlc_buf_list_init(&n_hdlc->rx_buf_list);
  740. n_hdlc_buf_list_init(&n_hdlc->tx_buf_list);
  741. /* allocate free rx buffer list */
  742. for(i=0;i<DEFAULT_RX_BUF_COUNT;i++) {
  743. buf = (N_HDLC_BUF*)kmalloc(N_HDLC_BUF_SIZE,GFP_KERNEL);
  744. if (buf)
  745. n_hdlc_buf_put(&n_hdlc->rx_free_buf_list,buf);
  746. else if (debuglevel >= DEBUG_LEVEL_INFO)
  747. printk("%s(%d)n_hdlc_alloc(), kalloc() failed for rx buffer %dn",__FILE__,__LINE__, i);
  748. }
  749. /* allocate free tx buffer list */
  750. for(i=0;i<DEFAULT_TX_BUF_COUNT;i++) {
  751. buf = (N_HDLC_BUF*)kmalloc(N_HDLC_BUF_SIZE,GFP_KERNEL);
  752. if (buf)
  753. n_hdlc_buf_put(&n_hdlc->tx_free_buf_list,buf);
  754. else if (debuglevel >= DEBUG_LEVEL_INFO)
  755. printk("%s(%d)n_hdlc_alloc(), kalloc() failed for tx buffer %dn",__FILE__,__LINE__, i);
  756. }
  757. /* Initialize the control block */
  758. n_hdlc->magic  = HDLC_MAGIC;
  759. n_hdlc->flags  = 0;
  760. return n_hdlc;
  761. } /* end of n_hdlc_alloc() */
  762. /* n_hdlc_buf_list_init()
  763.  * 
  764.  *  initialize specified HDLC buffer list
  765.  * 
  766.  * Arguments:   list pointer to buffer list
  767.  * Return Value: None
  768.  */
  769. void n_hdlc_buf_list_init(N_HDLC_BUF_LIST *list)
  770. {
  771. memset(list,0,sizeof(N_HDLC_BUF_LIST));
  772. spin_lock_init(&list->spinlock);
  773. } /* end of n_hdlc_buf_list_init() */
  774. /* n_hdlc_buf_put()
  775.  * 
  776.  *  add specified HDLC buffer to tail of specified list
  777.  * 
  778.  * Arguments:
  779.  * 
  780.  *  list pointer to buffer list
  781.  *  buf pointer to buffer
  782.  * 
  783.  * Return Value: None
  784.  */
  785. void n_hdlc_buf_put(N_HDLC_BUF_LIST *list,N_HDLC_BUF *buf)
  786. {
  787. unsigned long flags;
  788. spin_lock_irqsave(&list->spinlock,flags);
  789. buf->link=NULL;
  790. if(list->tail)
  791. list->tail->link = buf;
  792. else
  793. list->head = buf;
  794. list->tail = buf;
  795. (list->count)++;
  796. spin_unlock_irqrestore(&list->spinlock,flags);
  797. } /* end of n_hdlc_buf_put() */
  798. /* n_hdlc_buf_get()
  799.  * 
  800.  *  remove and return an HDLC buffer from the
  801.  *  head of the specified HDLC buffer list
  802.  * 
  803.  * Arguments:
  804.  * 
  805.  *  list pointer to HDLC buffer list
  806.  * 
  807.  * Return Value:
  808.  * 
  809.  *  pointer to HDLC buffer if available, otherwise NULL
  810.  */
  811. N_HDLC_BUF* n_hdlc_buf_get(N_HDLC_BUF_LIST *list)
  812. {
  813. unsigned long flags;
  814. N_HDLC_BUF *buf;
  815. spin_lock_irqsave(&list->spinlock,flags);
  816. buf = list->head;
  817. if (buf) {
  818. list->head = buf->link;
  819. (list->count)--;
  820. }
  821. if (!list->head)
  822. list->tail = NULL;
  823. spin_unlock_irqrestore(&list->spinlock,flags);
  824. return buf;
  825. } /* end of n_hdlc_buf_get() */
  826. static int __init n_hdlc_init(void)
  827. {
  828. static struct tty_ldisc n_hdlc_ldisc;
  829. int    status;
  830. /* range check maxframe arg */
  831. if ( maxframe<4096)
  832. maxframe=4096;
  833. else if ( maxframe>65535)
  834. maxframe=65535;
  835. printk("HDLC line discipline: version %s, maxframe=%un", 
  836. szVersion, maxframe);
  837. /* Register the tty discipline */
  838. memset(&n_hdlc_ldisc, 0, sizeof (n_hdlc_ldisc));
  839. n_hdlc_ldisc.magic = TTY_LDISC_MAGIC;
  840. n_hdlc_ldisc.name           = "hdlc";
  841. n_hdlc_ldisc.open = n_hdlc_tty_open;
  842. n_hdlc_ldisc.close = n_hdlc_tty_close;
  843. n_hdlc_ldisc.read = n_hdlc_tty_read;
  844. n_hdlc_ldisc.write = n_hdlc_tty_write;
  845. n_hdlc_ldisc.ioctl = n_hdlc_tty_ioctl;
  846. n_hdlc_ldisc.poll = n_hdlc_tty_poll;
  847. n_hdlc_ldisc.receive_room = n_hdlc_tty_room;
  848. n_hdlc_ldisc.receive_buf = n_hdlc_tty_receive;
  849. n_hdlc_ldisc.write_wakeup = n_hdlc_tty_wakeup;
  850. status = tty_register_ldisc(N_HDLC, &n_hdlc_ldisc);
  851. if (!status)
  852. printk (KERN_INFO"N_HDLC line discipline registered.n");
  853. else
  854. printk (KERN_ERR"error registering line discipline: %dn",status);
  855. if (status)
  856. printk(KERN_INFO"N_HDLC: init failure %dn", status);
  857. return (status);
  858. } /* end of init_module() */
  859. static void __exit n_hdlc_exit(void)
  860. {
  861. int status;
  862. /* Release tty registration of line discipline */
  863. if ((status = tty_register_ldisc(N_HDLC, NULL)))
  864. printk("N_HDLC: can't unregister line discipline (err = %d)n", status);
  865. else
  866. printk("N_HDLC: line discipline unregisteredn");
  867. }
  868. module_init(n_hdlc_init);
  869. module_exit(n_hdlc_exit);
  870. MODULE_LICENSE("GPL");
  871. EXPORT_NO_SYMBOLS;