~ubuntu-branches/debian/wheezy/linux-2.6/wheezy

« back to all changes in this revision

Viewing changes to drivers/tty/n_hdlc.c

  • Committer: Bazaar Package Importer
  • Author(s): Ben Hutchings, Ben Hutchings, Aurelien Jarno, Martin Michlmayr
  • Date: 2011-04-06 13:53:30 UTC
  • mfrom: (43.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20110406135330-wjufxhd0tvn3zx4z
Tags: 2.6.38-3
[ Ben Hutchings ]
* [ppc64] Add to linux-tools package architectures (Closes: #620124)
* [amd64] Save cr4 to mmu_cr4_features at boot time (Closes: #620284)
* appletalk: Fix bugs introduced when removing use of BKL
* ALSA: Fix yet another race in disconnection
* cciss: Fix lost command issue
* ath9k: Fix kernel panic in AR2427
* ses: Avoid kernel panic when lun 0 is not mapped
* PCI/ACPI: Report ASPM support to BIOS if not disabled from command line

[ Aurelien Jarno ]
* rtlwifi: fix build when PCI is not enabled.

[ Martin Michlmayr ]
* rtlwifi: Eliminate udelay calls with too large values (Closes: #620204)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* generic HDLC line discipline for Linux
 
2
 *
 
3
 * Written by Paul Fulghum paulkf@microgate.com
 
4
 * for Microgate Corporation
 
5
 *
 
6
 * Microgate and SyncLink are registered trademarks of Microgate Corporation
 
7
 *
 
8
 * Adapted from ppp.c, written by Michael Callahan <callahan@maths.ox.ac.uk>,
 
9
 *      Al Longyear <longyear@netcom.com>,
 
10
 *      Paul Mackerras <Paul.Mackerras@cs.anu.edu.au>
 
11
 *
 
12
 * Original release 01/11/99
 
13
 *
 
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 separate
 
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
 
 
82
#include <linux/module.h>
 
83
#include <linux/init.h>
 
84
#include <linux/kernel.h>
 
85
#include <linux/sched.h>
 
86
#include <linux/types.h>
 
87
#include <linux/fcntl.h>
 
88
#include <linux/interrupt.h>
 
89
#include <linux/ptrace.h>
 
90
 
 
91
#undef VERSION
 
92
#define VERSION(major,minor,patch) (((((major)<<8)+(minor))<<8)+(patch))
 
93
 
 
94
#include <linux/poll.h>
 
95
#include <linux/in.h>
 
96
#include <linux/ioctl.h>
 
97
#include <linux/slab.h>
 
98
#include <linux/tty.h>
 
99
#include <linux/errno.h>
 
100
#include <linux/smp_lock.h>
 
101
#include <linux/string.h>       /* used in new tty drivers */
 
102
#include <linux/signal.h>       /* used in new tty drivers */
 
103
#include <linux/if.h>
 
104
#include <linux/bitops.h>
 
105
 
 
106
#include <asm/system.h>
 
107
#include <asm/termios.h>
 
108
#include <asm/uaccess.h>
 
109
 
 
110
/*
 
111
 * Buffers for individual HDLC frames
 
112
 */
 
113
#define MAX_HDLC_FRAME_SIZE 65535 
 
114
#define DEFAULT_RX_BUF_COUNT 10
 
115
#define MAX_RX_BUF_COUNT 60
 
116
#define DEFAULT_TX_BUF_COUNT 3
 
117
 
 
118
struct n_hdlc_buf {
 
119
        struct n_hdlc_buf *link;
 
120
        int               count;
 
121
        char              buf[1];
 
122
};
 
123
 
 
124
#define N_HDLC_BUF_SIZE (sizeof(struct n_hdlc_buf) + maxframe)
 
125
 
 
126
struct n_hdlc_buf_list {
 
127
        struct n_hdlc_buf *head;
 
128
        struct n_hdlc_buf *tail;
 
129
        int               count;
 
130
        spinlock_t        spinlock;
 
131
};
 
132
 
 
133
/**
 
134
 * struct n_hdlc - per device instance data structure
 
135
 * @magic - magic value for structure
 
136
 * @flags - miscellaneous control flags
 
137
 * @tty - ptr to TTY structure
 
138
 * @backup_tty - TTY to use if tty gets closed
 
139
 * @tbusy - reentrancy flag for tx wakeup code
 
140
 * @woke_up - FIXME: describe this field
 
141
 * @tbuf - currently transmitting tx buffer
 
142
 * @tx_buf_list - list of pending transmit frame buffers
 
143
 * @rx_buf_list - list of received frame buffers
 
144
 * @tx_free_buf_list - list unused transmit frame buffers
 
145
 * @rx_free_buf_list - list unused received frame buffers
 
146
 */
 
147
struct n_hdlc {
 
148
        int                     magic;
 
149
        __u32                   flags;
 
150
        struct tty_struct       *tty;
 
151
        struct tty_struct       *backup_tty;
 
152
        int                     tbusy;
 
153
        int                     woke_up;
 
154
        struct n_hdlc_buf       *tbuf;
 
155
        struct n_hdlc_buf_list  tx_buf_list;
 
156
        struct n_hdlc_buf_list  rx_buf_list;
 
157
        struct n_hdlc_buf_list  tx_free_buf_list;
 
158
        struct n_hdlc_buf_list  rx_free_buf_list;
 
159
};
 
160
 
 
161
/*
 
162
 * HDLC buffer list manipulation functions
 
163
 */
 
164
static void n_hdlc_buf_list_init(struct n_hdlc_buf_list *list);
 
165
static void n_hdlc_buf_put(struct n_hdlc_buf_list *list,
 
166
                           struct n_hdlc_buf *buf);
 
167
static struct n_hdlc_buf *n_hdlc_buf_get(struct n_hdlc_buf_list *list);
 
168
 
 
169
/* Local functions */
 
170
 
 
171
static struct n_hdlc *n_hdlc_alloc (void);
 
172
 
 
173
/* debug level can be set by insmod for debugging purposes */
 
174
#define DEBUG_LEVEL_INFO        1
 
175
static int debuglevel;
 
176
 
 
177
/* max frame size for memory allocations */
 
178
static int maxframe = 4096;
 
179
 
 
180
/* TTY callbacks */
 
181
 
 
182
static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file,
 
183
                           __u8 __user *buf, size_t nr);
 
184
static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file,
 
185
                            const unsigned char *buf, size_t nr);
 
186
static int n_hdlc_tty_ioctl(struct tty_struct *tty, struct file *file,
 
187
                            unsigned int cmd, unsigned long arg);
 
188
static unsigned int n_hdlc_tty_poll(struct tty_struct *tty, struct file *filp,
 
189
                                    poll_table *wait);
 
190
static int n_hdlc_tty_open(struct tty_struct *tty);
 
191
static void n_hdlc_tty_close(struct tty_struct *tty);
 
192
static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *cp,
 
193
                               char *fp, int count);
 
194
static void n_hdlc_tty_wakeup(struct tty_struct *tty);
 
195
 
 
196
#define bset(p,b)       ((p)[(b) >> 5] |= (1 << ((b) & 0x1f)))
 
197
 
 
198
#define tty2n_hdlc(tty) ((struct n_hdlc *) ((tty)->disc_data))
 
199
#define n_hdlc2tty(n_hdlc)      ((n_hdlc)->tty)
 
200
 
 
201
static void flush_rx_queue(struct tty_struct *tty)
 
202
{
 
203
        struct n_hdlc *n_hdlc = tty2n_hdlc(tty);
 
204
        struct n_hdlc_buf *buf;
 
205
 
 
206
        while ((buf = n_hdlc_buf_get(&n_hdlc->rx_buf_list)))
 
207
                n_hdlc_buf_put(&n_hdlc->rx_free_buf_list, buf);
 
208
}
 
209
 
 
210
static void flush_tx_queue(struct tty_struct *tty)
 
211
{
 
212
        struct n_hdlc *n_hdlc = tty2n_hdlc(tty);
 
213
        struct n_hdlc_buf *buf;
 
214
        unsigned long flags;
 
215
 
 
216
        while ((buf = n_hdlc_buf_get(&n_hdlc->tx_buf_list)))
 
217
                n_hdlc_buf_put(&n_hdlc->tx_free_buf_list, buf);
 
218
        spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock, flags);
 
219
        if (n_hdlc->tbuf) {
 
220
                n_hdlc_buf_put(&n_hdlc->tx_free_buf_list, n_hdlc->tbuf);
 
221
                n_hdlc->tbuf = NULL;
 
222
        }
 
223
        spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock, flags);
 
224
}
 
225
 
 
226
static struct tty_ldisc_ops n_hdlc_ldisc = {
 
227
        .owner          = THIS_MODULE,
 
228
        .magic          = TTY_LDISC_MAGIC,
 
229
        .name           = "hdlc",
 
230
        .open           = n_hdlc_tty_open,
 
231
        .close          = n_hdlc_tty_close,
 
232
        .read           = n_hdlc_tty_read,
 
233
        .write          = n_hdlc_tty_write,
 
234
        .ioctl          = n_hdlc_tty_ioctl,
 
235
        .poll           = n_hdlc_tty_poll,
 
236
        .receive_buf    = n_hdlc_tty_receive,
 
237
        .write_wakeup   = n_hdlc_tty_wakeup,
 
238
        .flush_buffer   = flush_rx_queue,
 
239
};
 
240
 
 
241
/**
 
242
 * n_hdlc_release - release an n_hdlc per device line discipline info structure
 
243
 * @n_hdlc - per device line discipline info structure
 
244
 */
 
245
static void n_hdlc_release(struct n_hdlc *n_hdlc)
 
246
{
 
247
        struct tty_struct *tty = n_hdlc2tty (n_hdlc);
 
248
        struct n_hdlc_buf *buf;
 
249
        
 
250
        if (debuglevel >= DEBUG_LEVEL_INFO)     
 
251
                printk("%s(%d)n_hdlc_release() called\n",__FILE__,__LINE__);
 
252
                
 
253
        /* Ensure that the n_hdlcd process is not hanging on select()/poll() */
 
254
        wake_up_interruptible (&tty->read_wait);
 
255
        wake_up_interruptible (&tty->write_wait);
 
256
 
 
257
        if (tty->disc_data == n_hdlc)
 
258
                tty->disc_data = NULL;  /* Break the tty->n_hdlc link */
 
259
 
 
260
        /* Release transmit and receive buffers */
 
261
        for(;;) {
 
262
                buf = n_hdlc_buf_get(&n_hdlc->rx_free_buf_list);
 
263
                if (buf) {
 
264
                        kfree(buf);
 
265
                } else
 
266
                        break;
 
267
        }
 
268
        for(;;) {
 
269
                buf = n_hdlc_buf_get(&n_hdlc->tx_free_buf_list);
 
270
                if (buf) {
 
271
                        kfree(buf);
 
272
                } else
 
273
                        break;
 
274
        }
 
275
        for(;;) {
 
276
                buf = n_hdlc_buf_get(&n_hdlc->rx_buf_list);
 
277
                if (buf) {
 
278
                        kfree(buf);
 
279
                } else
 
280
                        break;
 
281
        }
 
282
        for(;;) {
 
283
                buf = n_hdlc_buf_get(&n_hdlc->tx_buf_list);
 
284
                if (buf) {
 
285
                        kfree(buf);
 
286
                } else
 
287
                        break;
 
288
        }
 
289
        kfree(n_hdlc->tbuf);
 
290
        kfree(n_hdlc);
 
291
        
 
292
}       /* end of n_hdlc_release() */
 
293
 
 
294
/**
 
295
 * n_hdlc_tty_close - line discipline close
 
296
 * @tty - pointer to tty info structure
 
297
 *
 
298
 * Called when the line discipline is changed to something
 
299
 * else, the tty is closed, or the tty detects a hangup.
 
300
 */
 
301
static void n_hdlc_tty_close(struct tty_struct *tty)
 
302
{
 
303
        struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
 
304
 
 
305
        if (debuglevel >= DEBUG_LEVEL_INFO)     
 
306
                printk("%s(%d)n_hdlc_tty_close() called\n",__FILE__,__LINE__);
 
307
                
 
308
        if (n_hdlc != NULL) {
 
309
                if (n_hdlc->magic != HDLC_MAGIC) {
 
310
                        printk (KERN_WARNING"n_hdlc: trying to close unopened tty!\n");
 
311
                        return;
 
312
                }
 
313
#if defined(TTY_NO_WRITE_SPLIT)
 
314
                clear_bit(TTY_NO_WRITE_SPLIT,&tty->flags);
 
315
#endif
 
316
                tty->disc_data = NULL;
 
317
                if (tty == n_hdlc->backup_tty)
 
318
                        n_hdlc->backup_tty = NULL;
 
319
                if (tty != n_hdlc->tty)
 
320
                        return;
 
321
                if (n_hdlc->backup_tty) {
 
322
                        n_hdlc->tty = n_hdlc->backup_tty;
 
323
                } else {
 
324
                        n_hdlc_release (n_hdlc);
 
325
                }
 
326
        }
 
327
        
 
328
        if (debuglevel >= DEBUG_LEVEL_INFO)     
 
329
                printk("%s(%d)n_hdlc_tty_close() success\n",__FILE__,__LINE__);
 
330
                
 
331
}       /* end of n_hdlc_tty_close() */
 
332
 
 
333
/**
 
334
 * n_hdlc_tty_open - called when line discipline changed to n_hdlc
 
335
 * @tty - pointer to tty info structure
 
336
 *
 
337
 * Returns 0 if success, otherwise error code
 
338
 */
 
339
static int n_hdlc_tty_open (struct tty_struct *tty)
 
340
{
 
341
        struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
 
342
 
 
343
        if (debuglevel >= DEBUG_LEVEL_INFO)     
 
344
                printk("%s(%d)n_hdlc_tty_open() called (device=%s)\n",
 
345
                __FILE__,__LINE__,
 
346
                tty->name);
 
347
                
 
348
        /* There should not be an existing table for this slot. */
 
349
        if (n_hdlc) {
 
350
                printk (KERN_ERR"n_hdlc_tty_open:tty already associated!\n" );
 
351
                return -EEXIST;
 
352
        }
 
353
        
 
354
        n_hdlc = n_hdlc_alloc();
 
355
        if (!n_hdlc) {
 
356
                printk (KERN_ERR "n_hdlc_alloc failed\n");
 
357
                return -ENFILE;
 
358
        }
 
359
                
 
360
        tty->disc_data = n_hdlc;
 
361
        n_hdlc->tty    = tty;
 
362
        tty->receive_room = 65536;
 
363
        
 
364
#if defined(TTY_NO_WRITE_SPLIT)
 
365
        /* change tty_io write() to not split large writes into 8K chunks */
 
366
        set_bit(TTY_NO_WRITE_SPLIT,&tty->flags);
 
367
#endif
 
368
        
 
369
        /* flush receive data from driver */
 
370
        tty_driver_flush_buffer(tty);
 
371
                
 
372
        if (debuglevel >= DEBUG_LEVEL_INFO)     
 
373
                printk("%s(%d)n_hdlc_tty_open() success\n",__FILE__,__LINE__);
 
374
                
 
375
        return 0;
 
376
        
 
377
}       /* end of n_tty_hdlc_open() */
 
378
 
 
379
/**
 
380
 * n_hdlc_send_frames - send frames on pending send buffer list
 
381
 * @n_hdlc - pointer to ldisc instance data
 
382
 * @tty - pointer to tty instance data
 
383
 *
 
384
 * Send frames on pending send buffer list until the driver does not accept a
 
385
 * frame (busy) this function is called after adding a frame to the send buffer
 
386
 * list and by the tty wakeup callback.
 
387
 */
 
388
static void n_hdlc_send_frames(struct n_hdlc *n_hdlc, struct tty_struct *tty)
 
389
{
 
390
        register int actual;
 
391
        unsigned long flags;
 
392
        struct n_hdlc_buf *tbuf;
 
393
 
 
394
        if (debuglevel >= DEBUG_LEVEL_INFO)     
 
395
                printk("%s(%d)n_hdlc_send_frames() called\n",__FILE__,__LINE__);
 
396
 check_again:
 
397
                
 
398
        spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock, flags);
 
399
        if (n_hdlc->tbusy) {
 
400
                n_hdlc->woke_up = 1;
 
401
                spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock, flags);
 
402
                return;
 
403
        }
 
404
        n_hdlc->tbusy = 1;
 
405
        n_hdlc->woke_up = 0;
 
406
        spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock, flags);
 
407
 
 
408
        /* get current transmit buffer or get new transmit */
 
409
        /* buffer from list of pending transmit buffers */
 
410
                
 
411
        tbuf = n_hdlc->tbuf;
 
412
        if (!tbuf)
 
413
                tbuf = n_hdlc_buf_get(&n_hdlc->tx_buf_list);
 
414
                
 
415
        while (tbuf) {
 
416
                if (debuglevel >= DEBUG_LEVEL_INFO)     
 
417
                        printk("%s(%d)sending frame %p, count=%d\n",
 
418
                                __FILE__,__LINE__,tbuf,tbuf->count);
 
419
                        
 
420
                /* Send the next block of data to device */
 
421
                tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
 
422
                actual = tty->ops->write(tty, tbuf->buf, tbuf->count);
 
423
 
 
424
                /* rollback was possible and has been done */
 
425
                if (actual == -ERESTARTSYS) {
 
426
                        n_hdlc->tbuf = tbuf;
 
427
                        break;
 
428
                }
 
429
                /* if transmit error, throw frame away by */
 
430
                /* pretending it was accepted by driver */
 
431
                if (actual < 0)
 
432
                        actual = tbuf->count;
 
433
                
 
434
                if (actual == tbuf->count) {
 
435
                        if (debuglevel >= DEBUG_LEVEL_INFO)     
 
436
                                printk("%s(%d)frame %p completed\n",
 
437
                                        __FILE__,__LINE__,tbuf);
 
438
                                        
 
439
                        /* free current transmit buffer */
 
440
                        n_hdlc_buf_put(&n_hdlc->tx_free_buf_list, tbuf);
 
441
                        
 
442
                        /* this tx buffer is done */
 
443
                        n_hdlc->tbuf = NULL;
 
444
                        
 
445
                        /* wait up sleeping writers */
 
446
                        wake_up_interruptible(&tty->write_wait);
 
447
        
 
448
                        /* get next pending transmit buffer */
 
449
                        tbuf = n_hdlc_buf_get(&n_hdlc->tx_buf_list);
 
450
                } else {
 
451
                        if (debuglevel >= DEBUG_LEVEL_INFO)     
 
452
                                printk("%s(%d)frame %p pending\n",
 
453
                                        __FILE__,__LINE__,tbuf);
 
454
                                        
 
455
                        /* buffer not accepted by driver */
 
456
                        /* set this buffer as pending buffer */
 
457
                        n_hdlc->tbuf = tbuf;
 
458
                        break;
 
459
                }
 
460
        }
 
461
        
 
462
        if (!tbuf)
 
463
                tty->flags  &= ~(1 << TTY_DO_WRITE_WAKEUP);
 
464
        
 
465
        /* Clear the re-entry flag */
 
466
        spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock, flags);
 
467
        n_hdlc->tbusy = 0;
 
468
        spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock, flags); 
 
469
        
 
470
        if (n_hdlc->woke_up)
 
471
          goto check_again;
 
472
 
 
473
        if (debuglevel >= DEBUG_LEVEL_INFO)     
 
474
                printk("%s(%d)n_hdlc_send_frames() exit\n",__FILE__,__LINE__);
 
475
                
 
476
}       /* end of n_hdlc_send_frames() */
 
477
 
 
478
/**
 
479
 * n_hdlc_tty_wakeup - Callback for transmit wakeup
 
480
 * @tty - pointer to associated tty instance data
 
481
 *
 
482
 * Called when low level device driver can accept more send data.
 
483
 */
 
484
static void n_hdlc_tty_wakeup(struct tty_struct *tty)
 
485
{
 
486
        struct n_hdlc *n_hdlc = tty2n_hdlc(tty);
 
487
 
 
488
        if (debuglevel >= DEBUG_LEVEL_INFO)     
 
489
                printk("%s(%d)n_hdlc_tty_wakeup() called\n",__FILE__,__LINE__);
 
490
                
 
491
        if (!n_hdlc)
 
492
                return;
 
493
 
 
494
        if (tty != n_hdlc->tty) {
 
495
                tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
 
496
                return;
 
497
        }
 
498
 
 
499
        n_hdlc_send_frames (n_hdlc, tty);
 
500
                
 
501
}       /* end of n_hdlc_tty_wakeup() */
 
502
 
 
503
/**
 
504
 * n_hdlc_tty_receive - Called by tty driver when receive data is available
 
505
 * @tty - pointer to tty instance data
 
506
 * @data - pointer to received data
 
507
 * @flags - pointer to flags for data
 
508
 * @count - count of received data in bytes
 
509
 *
 
510
 * Called by tty low level driver when receive data is available. Data is
 
511
 * interpreted as one HDLC frame.
 
512
 */
 
513
static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data,
 
514
                               char *flags, int count)
 
515
{
 
516
        register struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
 
517
        register struct n_hdlc_buf *buf;
 
518
 
 
519
        if (debuglevel >= DEBUG_LEVEL_INFO)     
 
520
                printk("%s(%d)n_hdlc_tty_receive() called count=%d\n",
 
521
                        __FILE__,__LINE__, count);
 
522
                
 
523
        /* This can happen if stuff comes in on the backup tty */
 
524
        if (!n_hdlc || tty != n_hdlc->tty)
 
525
                return;
 
526
                
 
527
        /* verify line is using HDLC discipline */
 
528
        if (n_hdlc->magic != HDLC_MAGIC) {
 
529
                printk("%s(%d) line not using HDLC discipline\n",
 
530
                        __FILE__,__LINE__);
 
531
                return;
 
532
        }
 
533
        
 
534
        if ( count>maxframe ) {
 
535
                if (debuglevel >= DEBUG_LEVEL_INFO)     
 
536
                        printk("%s(%d) rx count>maxframesize, data discarded\n",
 
537
                               __FILE__,__LINE__);
 
538
                return;
 
539
        }
 
540
 
 
541
        /* get a free HDLC buffer */    
 
542
        buf = n_hdlc_buf_get(&n_hdlc->rx_free_buf_list);
 
543
        if (!buf) {
 
544
                /* no buffers in free list, attempt to allocate another rx buffer */
 
545
                /* unless the maximum count has been reached */
 
546
                if (n_hdlc->rx_buf_list.count < MAX_RX_BUF_COUNT)
 
547
                        buf = kmalloc(N_HDLC_BUF_SIZE, GFP_ATOMIC);
 
548
        }
 
549
        
 
550
        if (!buf) {
 
551
                if (debuglevel >= DEBUG_LEVEL_INFO)     
 
552
                        printk("%s(%d) no more rx buffers, data discarded\n",
 
553
                               __FILE__,__LINE__);
 
554
                return;
 
555
        }
 
556
                
 
557
        /* copy received data to HDLC buffer */
 
558
        memcpy(buf->buf,data,count);
 
559
        buf->count=count;
 
560
 
 
561
        /* add HDLC buffer to list of received frames */
 
562
        n_hdlc_buf_put(&n_hdlc->rx_buf_list, buf);
 
563
        
 
564
        /* wake up any blocked reads and perform async signalling */
 
565
        wake_up_interruptible (&tty->read_wait);
 
566
        if (n_hdlc->tty->fasync != NULL)
 
567
                kill_fasync (&n_hdlc->tty->fasync, SIGIO, POLL_IN);
 
568
 
 
569
}       /* end of n_hdlc_tty_receive() */
 
570
 
 
571
/**
 
572
 * n_hdlc_tty_read - Called to retrieve one frame of data (if available)
 
573
 * @tty - pointer to tty instance data
 
574
 * @file - pointer to open file object
 
575
 * @buf - pointer to returned data buffer
 
576
 * @nr - size of returned data buffer
 
577
 *      
 
578
 * Returns the number of bytes returned or error code.
 
579
 */
 
580
static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file,
 
581
                           __u8 __user *buf, size_t nr)
 
582
{
 
583
        struct n_hdlc *n_hdlc = tty2n_hdlc(tty);
 
584
        int ret = 0;
 
585
        struct n_hdlc_buf *rbuf;
 
586
        DECLARE_WAITQUEUE(wait, current);
 
587
 
 
588
        if (debuglevel >= DEBUG_LEVEL_INFO)     
 
589
                printk("%s(%d)n_hdlc_tty_read() called\n",__FILE__,__LINE__);
 
590
                
 
591
        /* Validate the pointers */
 
592
        if (!n_hdlc)
 
593
                return -EIO;
 
594
 
 
595
        /* verify user access to buffer */
 
596
        if (!access_ok(VERIFY_WRITE, buf, nr)) {
 
597
                printk(KERN_WARNING "%s(%d) n_hdlc_tty_read() can't verify user "
 
598
                "buffer\n", __FILE__, __LINE__);
 
599
                return -EFAULT;
 
600
        }
 
601
 
 
602
        add_wait_queue(&tty->read_wait, &wait);
 
603
 
 
604
        for (;;) {
 
605
                if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
 
606
                        ret = -EIO;
 
607
                        break;
 
608
                }
 
609
                if (tty_hung_up_p(file))
 
610
                        break;
 
611
 
 
612
                set_current_state(TASK_INTERRUPTIBLE);
 
613
 
 
614
                rbuf = n_hdlc_buf_get(&n_hdlc->rx_buf_list);
 
615
                if (rbuf) {
 
616
                        if (rbuf->count > nr) {
 
617
                                /* too large for caller's buffer */
 
618
                                ret = -EOVERFLOW;
 
619
                        } else {
 
620
                                if (copy_to_user(buf, rbuf->buf, rbuf->count))
 
621
                                        ret = -EFAULT;
 
622
                                else
 
623
                                        ret = rbuf->count;
 
624
                        }
 
625
 
 
626
                        if (n_hdlc->rx_free_buf_list.count >
 
627
                            DEFAULT_RX_BUF_COUNT)
 
628
                                kfree(rbuf);
 
629
                        else
 
630
                                n_hdlc_buf_put(&n_hdlc->rx_free_buf_list, rbuf);
 
631
                        break;
 
632
                }
 
633
                        
 
634
                /* no data */
 
635
                if (file->f_flags & O_NONBLOCK) {
 
636
                        ret = -EAGAIN;
 
637
                        break;
 
638
                }
 
639
 
 
640
                schedule();
 
641
 
 
642
                if (signal_pending(current)) {
 
643
                        ret = -EINTR;
 
644
                        break;
 
645
                }
 
646
        }
 
647
 
 
648
        remove_wait_queue(&tty->read_wait, &wait);
 
649
        __set_current_state(TASK_RUNNING);
 
650
 
 
651
        return ret;
 
652
        
 
653
}       /* end of n_hdlc_tty_read() */
 
654
 
 
655
/**
 
656
 * n_hdlc_tty_write - write a single frame of data to device
 
657
 * @tty - pointer to associated tty device instance data
 
658
 * @file - pointer to file object data
 
659
 * @data - pointer to transmit data (one frame)
 
660
 * @count - size of transmit frame in bytes
 
661
 *              
 
662
 * Returns the number of bytes written (or error code).
 
663
 */
 
664
static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file,
 
665
                            const unsigned char *data, size_t count)
 
666
{
 
667
        struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
 
668
        int error = 0;
 
669
        DECLARE_WAITQUEUE(wait, current);
 
670
        struct n_hdlc_buf *tbuf;
 
671
 
 
672
        if (debuglevel >= DEBUG_LEVEL_INFO)     
 
673
                printk("%s(%d)n_hdlc_tty_write() called count=%Zd\n",
 
674
                        __FILE__,__LINE__,count);
 
675
                
 
676
        /* Verify pointers */
 
677
        if (!n_hdlc)
 
678
                return -EIO;
 
679
 
 
680
        if (n_hdlc->magic != HDLC_MAGIC)
 
681
                return -EIO;
 
682
 
 
683
        /* verify frame size */
 
684
        if (count > maxframe ) {
 
685
                if (debuglevel & DEBUG_LEVEL_INFO)
 
686
                        printk (KERN_WARNING
 
687
                                "n_hdlc_tty_write: truncating user packet "
 
688
                                "from %lu to %d\n", (unsigned long) count,
 
689
                                maxframe );
 
690
                count = maxframe;
 
691
        }
 
692
        
 
693
        add_wait_queue(&tty->write_wait, &wait);
 
694
 
 
695
        for (;;) {
 
696
                set_current_state(TASK_INTERRUPTIBLE);
 
697
        
 
698
                tbuf = n_hdlc_buf_get(&n_hdlc->tx_free_buf_list);
 
699
                if (tbuf)
 
700
                        break;
 
701
 
 
702
                if (file->f_flags & O_NONBLOCK) {
 
703
                        error = -EAGAIN;
 
704
                        break;
 
705
                }
 
706
                schedule();
 
707
                        
 
708
                n_hdlc = tty2n_hdlc (tty);
 
709
                if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC || 
 
710
                    tty != n_hdlc->tty) {
 
711
                        printk("n_hdlc_tty_write: %p invalid after wait!\n", n_hdlc);
 
712
                        error = -EIO;
 
713
                        break;
 
714
                }
 
715
                        
 
716
                if (signal_pending(current)) {
 
717
                        error = -EINTR;
 
718
                        break;
 
719
                }
 
720
        }
 
721
 
 
722
        __set_current_state(TASK_RUNNING);
 
723
        remove_wait_queue(&tty->write_wait, &wait);
 
724
 
 
725
        if (!error) {           
 
726
                /* Retrieve the user's buffer */
 
727
                memcpy(tbuf->buf, data, count);
 
728
 
 
729
                /* Send the data */
 
730
                tbuf->count = error = count;
 
731
                n_hdlc_buf_put(&n_hdlc->tx_buf_list,tbuf);
 
732
                n_hdlc_send_frames(n_hdlc,tty);
 
733
        }
 
734
 
 
735
        return error;
 
736
        
 
737
}       /* end of n_hdlc_tty_write() */
 
738
 
 
739
/**
 
740
 * n_hdlc_tty_ioctl - process IOCTL system call for the tty device.
 
741
 * @tty - pointer to tty instance data
 
742
 * @file - pointer to open file object for device
 
743
 * @cmd - IOCTL command code
 
744
 * @arg - argument for IOCTL call (cmd dependent)
 
745
 *
 
746
 * Returns command dependent result.
 
747
 */
 
748
static int n_hdlc_tty_ioctl(struct tty_struct *tty, struct file *file,
 
749
                            unsigned int cmd, unsigned long arg)
 
750
{
 
751
        struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
 
752
        int error = 0;
 
753
        int count;
 
754
        unsigned long flags;
 
755
        
 
756
        if (debuglevel >= DEBUG_LEVEL_INFO)     
 
757
                printk("%s(%d)n_hdlc_tty_ioctl() called %d\n",
 
758
                        __FILE__,__LINE__,cmd);
 
759
                
 
760
        /* Verify the status of the device */
 
761
        if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC)
 
762
                return -EBADF;
 
763
 
 
764
        switch (cmd) {
 
765
        case FIONREAD:
 
766
                /* report count of read data available */
 
767
                /* in next available frame (if any) */
 
768
                spin_lock_irqsave(&n_hdlc->rx_buf_list.spinlock,flags);
 
769
                if (n_hdlc->rx_buf_list.head)
 
770
                        count = n_hdlc->rx_buf_list.head->count;
 
771
                else
 
772
                        count = 0;
 
773
                spin_unlock_irqrestore(&n_hdlc->rx_buf_list.spinlock,flags);
 
774
                error = put_user(count, (int __user *)arg);
 
775
                break;
 
776
 
 
777
        case TIOCOUTQ:
 
778
                /* get the pending tx byte count in the driver */
 
779
                count = tty_chars_in_buffer(tty);
 
780
                /* add size of next output frame in queue */
 
781
                spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock,flags);
 
782
                if (n_hdlc->tx_buf_list.head)
 
783
                        count += n_hdlc->tx_buf_list.head->count;
 
784
                spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock,flags);
 
785
                error = put_user(count, (int __user *)arg);
 
786
                break;
 
787
 
 
788
        case TCFLSH:
 
789
                switch (arg) {
 
790
                case TCIOFLUSH:
 
791
                case TCOFLUSH:
 
792
                        flush_tx_queue(tty);
 
793
                }
 
794
                /* fall through to default */
 
795
 
 
796
        default:
 
797
                error = n_tty_ioctl_helper(tty, file, cmd, arg);
 
798
                break;
 
799
        }
 
800
        return error;
 
801
        
 
802
}       /* end of n_hdlc_tty_ioctl() */
 
803
 
 
804
/**
 
805
 * n_hdlc_tty_poll - TTY callback for poll system call
 
806
 * @tty - pointer to tty instance data
 
807
 * @filp - pointer to open file object for device
 
808
 * @poll_table - wait queue for operations
 
809
 * 
 
810
 * Determine which operations (read/write) will not block and return info
 
811
 * to caller.
 
812
 * Returns a bit mask containing info on which ops will not block.
 
813
 */
 
814
static unsigned int n_hdlc_tty_poll(struct tty_struct *tty, struct file *filp,
 
815
                                    poll_table *wait)
 
816
{
 
817
        struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
 
818
        unsigned int mask = 0;
 
819
 
 
820
        if (debuglevel >= DEBUG_LEVEL_INFO)     
 
821
                printk("%s(%d)n_hdlc_tty_poll() called\n",__FILE__,__LINE__);
 
822
                
 
823
        if (n_hdlc && n_hdlc->magic == HDLC_MAGIC && tty == n_hdlc->tty) {
 
824
                /* queue current process into any wait queue that */
 
825
                /* may awaken in the future (read and write) */
 
826
 
 
827
                poll_wait(filp, &tty->read_wait, wait);
 
828
                poll_wait(filp, &tty->write_wait, wait);
 
829
 
 
830
                /* set bits for operations that won't block */
 
831
                if (n_hdlc->rx_buf_list.head)
 
832
                        mask |= POLLIN | POLLRDNORM;    /* readable */
 
833
                if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
 
834
                        mask |= POLLHUP;
 
835
                if (tty_hung_up_p(filp))
 
836
                        mask |= POLLHUP;
 
837
                if (!tty_is_writelocked(tty) &&
 
838
                                n_hdlc->tx_free_buf_list.head)
 
839
                        mask |= POLLOUT | POLLWRNORM;   /* writable */
 
840
        }
 
841
        return mask;
 
842
}       /* end of n_hdlc_tty_poll() */
 
843
 
 
844
/**
 
845
 * n_hdlc_alloc - allocate an n_hdlc instance data structure
 
846
 *
 
847
 * Returns a pointer to newly created structure if success, otherwise %NULL
 
848
 */
 
849
static struct n_hdlc *n_hdlc_alloc(void)
 
850
{
 
851
        struct n_hdlc_buf *buf;
 
852
        int i;
 
853
        struct n_hdlc *n_hdlc = kmalloc(sizeof(*n_hdlc), GFP_KERNEL);
 
854
 
 
855
        if (!n_hdlc)
 
856
                return NULL;
 
857
 
 
858
        memset(n_hdlc, 0, sizeof(*n_hdlc));
 
859
 
 
860
        n_hdlc_buf_list_init(&n_hdlc->rx_free_buf_list);
 
861
        n_hdlc_buf_list_init(&n_hdlc->tx_free_buf_list);
 
862
        n_hdlc_buf_list_init(&n_hdlc->rx_buf_list);
 
863
        n_hdlc_buf_list_init(&n_hdlc->tx_buf_list);
 
864
        
 
865
        /* allocate free rx buffer list */
 
866
        for(i=0;i<DEFAULT_RX_BUF_COUNT;i++) {
 
867
                buf = kmalloc(N_HDLC_BUF_SIZE, GFP_KERNEL);
 
868
                if (buf)
 
869
                        n_hdlc_buf_put(&n_hdlc->rx_free_buf_list,buf);
 
870
                else if (debuglevel >= DEBUG_LEVEL_INFO)        
 
871
                        printk("%s(%d)n_hdlc_alloc(), kalloc() failed for rx buffer %d\n",__FILE__,__LINE__, i);
 
872
        }
 
873
        
 
874
        /* allocate free tx buffer list */
 
875
        for(i=0;i<DEFAULT_TX_BUF_COUNT;i++) {
 
876
                buf = kmalloc(N_HDLC_BUF_SIZE, GFP_KERNEL);
 
877
                if (buf)
 
878
                        n_hdlc_buf_put(&n_hdlc->tx_free_buf_list,buf);
 
879
                else if (debuglevel >= DEBUG_LEVEL_INFO)        
 
880
                        printk("%s(%d)n_hdlc_alloc(), kalloc() failed for tx buffer %d\n",__FILE__,__LINE__, i);
 
881
        }
 
882
        
 
883
        /* Initialize the control block */
 
884
        n_hdlc->magic  = HDLC_MAGIC;
 
885
        n_hdlc->flags  = 0;
 
886
        
 
887
        return n_hdlc;
 
888
        
 
889
}       /* end of n_hdlc_alloc() */
 
890
 
 
891
/**
 
892
 * n_hdlc_buf_list_init - initialize specified HDLC buffer list
 
893
 * @list - pointer to buffer list
 
894
 */
 
895
static void n_hdlc_buf_list_init(struct n_hdlc_buf_list *list)
 
896
{
 
897
        memset(list, 0, sizeof(*list));
 
898
        spin_lock_init(&list->spinlock);
 
899
}       /* end of n_hdlc_buf_list_init() */
 
900
 
 
901
/**
 
902
 * n_hdlc_buf_put - add specified HDLC buffer to tail of specified list
 
903
 * @list - pointer to buffer list
 
904
 * @buf - pointer to buffer
 
905
 */
 
906
static void n_hdlc_buf_put(struct n_hdlc_buf_list *list,
 
907
                           struct n_hdlc_buf *buf)
 
908
{
 
909
        unsigned long flags;
 
910
        spin_lock_irqsave(&list->spinlock,flags);
 
911
        
 
912
        buf->link=NULL;
 
913
        if (list->tail)
 
914
                list->tail->link = buf;
 
915
        else
 
916
                list->head = buf;
 
917
        list->tail = buf;
 
918
        (list->count)++;
 
919
        
 
920
        spin_unlock_irqrestore(&list->spinlock,flags);
 
921
        
 
922
}       /* end of n_hdlc_buf_put() */
 
923
 
 
924
/**
 
925
 * n_hdlc_buf_get - remove and return an HDLC buffer from list
 
926
 * @list - pointer to HDLC buffer list
 
927
 * 
 
928
 * Remove and return an HDLC buffer from the head of the specified HDLC buffer
 
929
 * list.
 
930
 * Returns a pointer to HDLC buffer if available, otherwise %NULL.
 
931
 */
 
932
static struct n_hdlc_buf* n_hdlc_buf_get(struct n_hdlc_buf_list *list)
 
933
{
 
934
        unsigned long flags;
 
935
        struct n_hdlc_buf *buf;
 
936
        spin_lock_irqsave(&list->spinlock,flags);
 
937
        
 
938
        buf = list->head;
 
939
        if (buf) {
 
940
                list->head = buf->link;
 
941
                (list->count)--;
 
942
        }
 
943
        if (!list->head)
 
944
                list->tail = NULL;
 
945
        
 
946
        spin_unlock_irqrestore(&list->spinlock,flags);
 
947
        return buf;
 
948
        
 
949
}       /* end of n_hdlc_buf_get() */
 
950
 
 
951
static char hdlc_banner[] __initdata =
 
952
        KERN_INFO "HDLC line discipline maxframe=%u\n";
 
953
static char hdlc_register_ok[] __initdata =
 
954
        KERN_INFO "N_HDLC line discipline registered.\n";
 
955
static char hdlc_register_fail[] __initdata =
 
956
        KERN_ERR "error registering line discipline: %d\n";
 
957
static char hdlc_init_fail[] __initdata =
 
958
        KERN_INFO "N_HDLC: init failure %d\n";
 
959
 
 
960
static int __init n_hdlc_init(void)
 
961
{
 
962
        int status;
 
963
 
 
964
        /* range check maxframe arg */
 
965
        if (maxframe < 4096)
 
966
                maxframe = 4096;
 
967
        else if (maxframe > 65535)
 
968
                maxframe = 65535;
 
969
 
 
970
        printk(hdlc_banner, maxframe);
 
971
 
 
972
        status = tty_register_ldisc(N_HDLC, &n_hdlc_ldisc);
 
973
        if (!status)
 
974
                printk(hdlc_register_ok);
 
975
        else
 
976
                printk(hdlc_register_fail, status);
 
977
 
 
978
        if (status)
 
979
                printk(hdlc_init_fail, status);
 
980
        return status;
 
981
        
 
982
}       /* end of init_module() */
 
983
 
 
984
static char hdlc_unregister_ok[] __exitdata =
 
985
        KERN_INFO "N_HDLC: line discipline unregistered\n";
 
986
static char hdlc_unregister_fail[] __exitdata =
 
987
        KERN_ERR "N_HDLC: can't unregister line discipline (err = %d)\n";
 
988
 
 
989
static void __exit n_hdlc_exit(void)
 
990
{
 
991
        /* Release tty registration of line discipline */
 
992
        int status = tty_unregister_ldisc(N_HDLC);
 
993
 
 
994
        if (status)
 
995
                printk(hdlc_unregister_fail, status);
 
996
        else
 
997
                printk(hdlc_unregister_ok);
 
998
}
 
999
 
 
1000
module_init(n_hdlc_init);
 
1001
module_exit(n_hdlc_exit);
 
1002
 
 
1003
MODULE_LICENSE("GPL");
 
1004
MODULE_AUTHOR("Paul Fulghum paulkf@microgate.com");
 
1005
module_param(debuglevel, int, 0);
 
1006
module_param(maxframe, int, 0);
 
1007
MODULE_ALIAS_LDISC(N_HDLC);