]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/staging/dgnc/dgnc_tty.c
staging: dgnc: add dgnc digi driver
[mirror_ubuntu-artful-kernel.git] / drivers / staging / dgnc / dgnc_tty.c
CommitLineData
0b99d589
LL
1/*
2 * Copyright 2003 Digi International (www.digi.com)
3 * Scott H Kilau <Scott_Kilau at digi dot com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
12 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
13 * PURPOSE. See the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 *
19 *
20 * NOTE TO LINUX KERNEL HACKERS: DO NOT REFORMAT THIS CODE!
21 *
22 * This is shared code between Digi's CVS archive and the
23 * Linux Kernel sources.
24 * Changing the source just for reformatting needlessly breaks
25 * our CVS diff history.
26 *
27 * Send any bug fixes/changes to: Eng.Linux at digi dot com.
28 * Thank you.
29 */
30
31/************************************************************************
32 *
33 * This file implements the tty driver functionality for the
34 * Neo and ClassicBoard PCI based product lines.
35 *
36 ************************************************************************
37 *
38 * $Id: dgnc_tty.c,v 1.5 2013/04/30 19:18:30 markh Exp $
39 */
40
41#include <linux/kernel.h>
42#include <linux/version.h>
43#include <linux/sched.h> /* For jiffies, task states */
44#include <linux/interrupt.h> /* For tasklet and interrupt structs/defines */
45#include <linux/module.h>
46#include <linux/ctype.h>
47#include <linux/tty.h>
48#include <linux/tty_flip.h>
49#include <linux/serial_reg.h>
50#include <linux/slab.h>
51#include <linux/delay.h> /* For udelay */
52#include <asm/uaccess.h> /* For copy_from_user/copy_to_user */
53#include <linux/pci.h>
54
55#include "dgnc_driver.h"
56#include "dgnc_tty.h"
57#include "dgnc_types.h"
58#include "dgnc_trace.h"
59#include "dgnc_neo.h"
60#include "dgnc_cls.h"
61#include "dpacompat.h"
62#include "dgnc_sysfs.h"
63
64#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
65#define init_MUTEX(sem) sema_init(sem, 1)
66#define DECLARE_MUTEX(name) \
67 struct semaphore name = __SEMAPHORE_INITIALIZER(name, 1)
68#endif
69
70/*
71 * internal variables
72 */
73static struct board_t *dgnc_BoardsByMajor[256];
74static uchar *dgnc_TmpWriteBuf = NULL;
75static DECLARE_MUTEX(dgnc_TmpWriteSem);
76
77/*
78 * Default transparent print information.
79 */
80static struct digi_t dgnc_digi_init = {
81 .digi_flags = DIGI_COOK, /* Flags */
82 .digi_maxcps = 100, /* Max CPS */
83 .digi_maxchar = 50, /* Max chars in print queue */
84 .digi_bufsize = 100, /* Printer buffer size */
85 .digi_onlen = 4, /* size of printer on string */
86 .digi_offlen = 4, /* size of printer off string */
87 .digi_onstr = "\033[5i", /* ANSI printer on string ] */
88 .digi_offstr = "\033[4i", /* ANSI printer off string ] */
89 .digi_term = "ansi" /* default terminal type */
90};
91
92
93/*
94 * Define a local default termios struct. All ports will be created
95 * with this termios initially.
96 *
97 * This defines a raw port at 9600 baud, 8 data bits, no parity,
98 * 1 stop bit.
99 */
100static struct ktermios DgncDefaultTermios =
101{
102 .c_iflag = (DEFAULT_IFLAGS), /* iflags */
103 .c_oflag = (DEFAULT_OFLAGS), /* oflags */
104 .c_cflag = (DEFAULT_CFLAGS), /* cflags */
105 .c_lflag = (DEFAULT_LFLAGS), /* lflags */
106 .c_cc = INIT_C_CC,
107 .c_line = 0,
108};
109
110
111/* Our function prototypes */
112static int dgnc_tty_open(struct tty_struct *tty, struct file *file);
113static void dgnc_tty_close(struct tty_struct *tty, struct file *file);
114static int dgnc_block_til_ready(struct tty_struct *tty, struct file *file, struct channel_t *ch);
115static int dgnc_tty_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg);
116static int dgnc_tty_digigeta(struct tty_struct *tty, struct digi_t __user *retinfo);
117static int dgnc_tty_digiseta(struct tty_struct *tty, struct digi_t __user *new_info);
118static int dgnc_tty_write_room(struct tty_struct* tty);
119static int dgnc_tty_put_char(struct tty_struct *tty, unsigned char c);
120static int dgnc_tty_chars_in_buffer(struct tty_struct* tty);
121static void dgnc_tty_start(struct tty_struct *tty);
122static void dgnc_tty_stop(struct tty_struct *tty);
123static void dgnc_tty_throttle(struct tty_struct *tty);
124static void dgnc_tty_unthrottle(struct tty_struct *tty);
125static void dgnc_tty_flush_chars(struct tty_struct *tty);
126static void dgnc_tty_flush_buffer(struct tty_struct *tty);
127static void dgnc_tty_hangup(struct tty_struct *tty);
128static int dgnc_set_modem_info(struct tty_struct *tty, unsigned int command, unsigned int __user *value);
129static int dgnc_get_modem_info(struct channel_t *ch, unsigned int __user *value);
130#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
131static int dgnc_tty_tiocmget(struct tty_struct *tty);
132static int dgnc_tty_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear);
133#else
134static int dgnc_tty_tiocmget(struct tty_struct *tty, struct file *file);
135static int dgnc_tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear);
136#endif
137static int dgnc_tty_send_break(struct tty_struct *tty, int msec);
138static void dgnc_tty_wait_until_sent(struct tty_struct *tty, int timeout);
139static int dgnc_tty_write(struct tty_struct *tty, const unsigned char *buf, int count);
140static void dgnc_tty_set_termios(struct tty_struct *tty, struct ktermios *old_termios);
141static void dgnc_tty_send_xchar(struct tty_struct *tty, char ch);
142
143
144static const struct tty_operations dgnc_tty_ops = {
145 .open = dgnc_tty_open,
146 .close = dgnc_tty_close,
147 .write = dgnc_tty_write,
148 .write_room = dgnc_tty_write_room,
149 .flush_buffer = dgnc_tty_flush_buffer,
150 .chars_in_buffer = dgnc_tty_chars_in_buffer,
151 .flush_chars = dgnc_tty_flush_chars,
152 .ioctl = dgnc_tty_ioctl,
153 .set_termios = dgnc_tty_set_termios,
154 .stop = dgnc_tty_stop,
155 .start = dgnc_tty_start,
156 .throttle = dgnc_tty_throttle,
157 .unthrottle = dgnc_tty_unthrottle,
158 .hangup = dgnc_tty_hangup,
159 .put_char = dgnc_tty_put_char,
160 .tiocmget = dgnc_tty_tiocmget,
161 .tiocmset = dgnc_tty_tiocmset,
162 .break_ctl = dgnc_tty_send_break,
163 .wait_until_sent = dgnc_tty_wait_until_sent,
164 .send_xchar = dgnc_tty_send_xchar
165};
166
167/************************************************************************
168 *
169 * TTY Initialization/Cleanup Functions
170 *
171 ************************************************************************/
172
173/*
174 * dgnc_tty_preinit()
175 *
176 * Initialize any global tty related data before we download any boards.
177 */
178int dgnc_tty_preinit(void)
179{
180 /*
181 * Allocate a buffer for doing the copy from user space to
182 * kernel space in dgnc_write(). We only use one buffer and
183 * control access to it with a semaphore. If we are paging, we
184 * are already in trouble so one buffer won't hurt much anyway.
185 *
186 * We are okay to sleep in the malloc, as this routine
187 * is only called during module load, (not in interrupt context),
188 * and with no locks held.
189 */
190 dgnc_TmpWriteBuf = kmalloc(WRITEBUFLEN, GFP_KERNEL);
191
192 if (!dgnc_TmpWriteBuf) {
193 DPR_INIT(("unable to allocate tmp write buf"));
194 return (-ENOMEM);
195 }
196
197 return(0);
198}
199
200
201/*
202 * dgnc_tty_register()
203 *
204 * Init the tty subsystem for this board.
205 */
206int dgnc_tty_register(struct board_t *brd)
207{
208 int rc = 0;
209
210 DPR_INIT(("tty_register start\n"));
211
212 memset(&brd->SerialDriver, 0, sizeof(struct tty_driver));
213 memset(&brd->PrintDriver, 0, sizeof(struct tty_driver));
214
215 brd->SerialDriver.magic = TTY_DRIVER_MAGIC;
216
217 snprintf(brd->SerialName, MAXTTYNAMELEN, "tty_dgnc_%d_", brd->boardnum);
218
219 brd->SerialDriver.name = brd->SerialName;
220 brd->SerialDriver.name_base = 0;
221 brd->SerialDriver.major = 0;
222 brd->SerialDriver.minor_start = 0;
223 brd->SerialDriver.num = brd->maxports;
224 brd->SerialDriver.type = TTY_DRIVER_TYPE_SERIAL;
225 brd->SerialDriver.subtype = SERIAL_TYPE_NORMAL;
226 brd->SerialDriver.init_termios = DgncDefaultTermios;
227 brd->SerialDriver.driver_name = DRVSTR;
228 brd->SerialDriver.flags = (TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_HARDWARE_BREAK);
229
230 /*
231 * The kernel wants space to store pointers to
232 * tty_struct's and termios's.
233 */
234 brd->SerialDriver.ttys = dgnc_driver_kzmalloc(brd->maxports * sizeof(struct tty_struct *), GFP_KERNEL);
235 if (!brd->SerialDriver.ttys)
236 return(-ENOMEM);
237
238#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
239 brd->SerialDriver.refcount = brd->TtyRefCnt;
240#else
241 kref_init(&brd->SerialDriver.kref);
242#endif
243
244 brd->SerialDriver.termios = dgnc_driver_kzmalloc(brd->maxports * sizeof(struct ktermios *), GFP_KERNEL);
245 if (!brd->SerialDriver.termios)
246 return(-ENOMEM);
247
248#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)
249 brd->SerialDriver.termios_locked = dgnc_driver_kzmalloc(brd->maxports * sizeof(struct ktermios *), GFP_KERNEL);
250 if (!brd->SerialDriver.termios_locked)
251 return(-ENOMEM);
252#endif
253 /*
254 * Entry points for driver. Called by the kernel from
255 * tty_io.c and n_tty.c.
256 */
257 tty_set_operations(&brd->SerialDriver, &dgnc_tty_ops);
258
259 if (!brd->dgnc_Major_Serial_Registered) {
260 /* Register tty devices */
261 rc = tty_register_driver(&brd->SerialDriver);
262 if (rc < 0) {
263 APR(("Can't register tty device (%d)\n", rc));
264 return(rc);
265 }
266 brd->dgnc_Major_Serial_Registered = TRUE;
267 }
268
269 /*
270 * If we're doing transparent print, we have to do all of the above
271 * again, seperately so we don't get the LD confused about what major
272 * we are when we get into the dgnc_tty_open() routine.
273 */
274 brd->PrintDriver.magic = TTY_DRIVER_MAGIC;
275 snprintf(brd->PrintName, MAXTTYNAMELEN, "pr_dgnc_%d_", brd->boardnum);
276
277 brd->PrintDriver.name = brd->PrintName;
278 brd->PrintDriver.name_base = 0;
279 brd->PrintDriver.major = brd->SerialDriver.major;
280 brd->PrintDriver.minor_start = 0x80;
281 brd->PrintDriver.num = brd->maxports;
282 brd->PrintDriver.type = TTY_DRIVER_TYPE_SERIAL;
283 brd->PrintDriver.subtype = SERIAL_TYPE_NORMAL;
284 brd->PrintDriver.init_termios = DgncDefaultTermios;
285 brd->PrintDriver.driver_name = DRVSTR;
286 brd->PrintDriver.flags = (TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_HARDWARE_BREAK);
287
288 /*
289 * The kernel wants space to store pointers to
290 * tty_struct's and termios's. Must be seperate from
291 * the Serial Driver so we don't get confused
292 */
293 brd->PrintDriver.ttys = dgnc_driver_kzmalloc(brd->maxports * sizeof(struct tty_struct *), GFP_KERNEL);
294 if (!brd->PrintDriver.ttys)
295 return(-ENOMEM);
296
297#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
298 brd->PrintDriver.refcount = brd->TtyRefCnt;
299#else
300 kref_init(&brd->PrintDriver.kref);
301#endif
302
303 brd->PrintDriver.termios = dgnc_driver_kzmalloc(brd->maxports * sizeof(struct ktermios *), GFP_KERNEL);
304 if (!brd->PrintDriver.termios)
305 return(-ENOMEM);
306
307#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)
308 brd->PrintDriver.termios_locked = dgnc_driver_kzmalloc(brd->maxports * sizeof(struct ktermios *), GFP_KERNEL);
309 if (!brd->PrintDriver.termios_locked)
310 return(-ENOMEM);
311#endif
312
313 /*
314 * Entry points for driver. Called by the kernel from
315 * tty_io.c and n_tty.c.
316 */
317 tty_set_operations(&brd->PrintDriver, &dgnc_tty_ops);
318
319 if (!brd->dgnc_Major_TransparentPrint_Registered) {
320 /* Register Transparent Print devices */
321 rc = tty_register_driver(&brd->PrintDriver);
322 if (rc < 0) {
323 APR(("Can't register Transparent Print device (%d)\n", rc));
324 return(rc);
325 }
326 brd->dgnc_Major_TransparentPrint_Registered = TRUE;
327 }
328
329 dgnc_BoardsByMajor[brd->SerialDriver.major] = brd;
330 brd->dgnc_Serial_Major = brd->SerialDriver.major;
331 brd->dgnc_TransparentPrint_Major = brd->PrintDriver.major;
332
333 DPR_INIT(("DGNC REGISTER TTY: MAJOR: %d\n", brd->SerialDriver.major));
334
335 return (rc);
336}
337
338
339/*
340 * dgnc_tty_init()
341 *
342 * Init the tty subsystem. Called once per board after board has been
343 * downloaded and init'ed.
344 */
345int dgnc_tty_init(struct board_t *brd)
346{
347 int i;
348 uchar *vaddr;
349 struct channel_t *ch;
350
351 if (!brd)
352 return (-ENXIO);
353
354 DPR_INIT(("dgnc_tty_init start\n"));
355
356 /*
357 * Initialize board structure elements.
358 */
359
360 vaddr = brd->re_map_membase;
361
362 brd->nasync = brd->maxports;
363
364 /*
365 * Allocate channel memory that might not have been allocated
366 * when the driver was first loaded.
367 */
368 for (i = 0; i < brd->nasync; i++) {
369 if (!brd->channels[i]) {
370
371 /*
372 * Okay to malloc with GFP_KERNEL, we are not at
373 * interrupt context, and there are no locks held.
374 */
375 brd->channels[i] = dgnc_driver_kzmalloc(sizeof(struct channel_t), GFP_KERNEL);
376 if (!brd->channels[i]) {
377 DPR_CORE(("%s:%d Unable to allocate memory for channel struct\n",
378 __FILE__, __LINE__));
379 }
380 }
381 }
382
383 ch = brd->channels[0];
384 vaddr = brd->re_map_membase;
385
386 /* Set up channel variables */
387 for (i = 0; i < brd->nasync; i++, ch = brd->channels[i]) {
388
389 if (!brd->channels[i])
390 continue;
391
392 DGNC_SPINLOCK_INIT(ch->ch_lock);
393
394 /* Store all our magic numbers */
395 ch->magic = DGNC_CHANNEL_MAGIC;
396 ch->ch_tun.magic = DGNC_UNIT_MAGIC;
397 ch->ch_tun.un_ch = ch;
398 ch->ch_tun.un_type = DGNC_SERIAL;
399 ch->ch_tun.un_dev = i;
400
401 ch->ch_pun.magic = DGNC_UNIT_MAGIC;
402 ch->ch_pun.un_ch = ch;
403 ch->ch_pun.un_type = DGNC_PRINT;
404 ch->ch_pun.un_dev = i + 128;
405
406 if (brd->bd_uart_offset == 0x200)
407 ch->ch_neo_uart = (struct neo_uart_struct *) ((ulong) vaddr + (brd->bd_uart_offset * i));
408 else
409 ch->ch_cls_uart = (struct cls_uart_struct *) ((ulong) vaddr + (brd->bd_uart_offset * i));
410
411 ch->ch_bd = brd;
412 ch->ch_portnum = i;
413 ch->ch_digi = dgnc_digi_init;
414
415 /* .25 second delay */
416 ch->ch_close_delay = 250;
417
418 init_waitqueue_head(&ch->ch_flags_wait);
419 init_waitqueue_head(&ch->ch_tun.un_flags_wait);
420 init_waitqueue_head(&ch->ch_pun.un_flags_wait);
421 init_waitqueue_head(&ch->ch_sniff_wait);
422
423 {
424 struct device *classp;
425 classp = tty_register_device(&brd->SerialDriver, i,
426 &(ch->ch_bd->pdev->dev));
427 ch->ch_tun.un_sysfs = classp;
428 dgnc_create_tty_sysfs(&ch->ch_tun, classp);
429
430 classp = tty_register_device(&brd->PrintDriver, i,
431 &(ch->ch_bd->pdev->dev));
432 ch->ch_pun.un_sysfs = classp;
433 dgnc_create_tty_sysfs(&ch->ch_pun, classp);
434 }
435
436 }
437
438 DPR_INIT(("dgnc_tty_init finish\n"));
439
440 return (0);
441}
442
443
444/*
445 * dgnc_tty_post_uninit()
446 *
447 * UnInitialize any global tty related data.
448 */
449void dgnc_tty_post_uninit(void)
450{
451 if (dgnc_TmpWriteBuf) {
452 kfree(dgnc_TmpWriteBuf);
453 dgnc_TmpWriteBuf = NULL;
454 }
455}
456
457
458/*
459 * dgnc_tty_uninit()
460 *
461 * Uninitialize the TTY portion of this driver. Free all memory and
462 * resources.
463 */
464void dgnc_tty_uninit(struct board_t *brd)
465{
466 int i = 0;
467
468 if (brd->dgnc_Major_Serial_Registered) {
469 dgnc_BoardsByMajor[brd->SerialDriver.major] = NULL;
470 brd->dgnc_Serial_Major = 0;
471 for (i = 0; i < brd->nasync; i++) {
472 dgnc_remove_tty_sysfs(brd->channels[i]->ch_tun.un_sysfs);
473 tty_unregister_device(&brd->SerialDriver, i);
474 }
475 tty_unregister_driver(&brd->SerialDriver);
476 brd->dgnc_Major_Serial_Registered = FALSE;
477 }
478
479 if (brd->dgnc_Major_TransparentPrint_Registered) {
480 dgnc_BoardsByMajor[brd->PrintDriver.major] = NULL;
481 brd->dgnc_TransparentPrint_Major = 0;
482 for (i = 0; i < brd->nasync; i++) {
483 dgnc_remove_tty_sysfs(brd->channels[i]->ch_pun.un_sysfs);
484 tty_unregister_device(&brd->PrintDriver, i);
485 }
486 tty_unregister_driver(&brd->PrintDriver);
487 brd->dgnc_Major_TransparentPrint_Registered = FALSE;
488 }
489
490 if (brd->SerialDriver.ttys) {
491 kfree(brd->SerialDriver.ttys);
492 brd->SerialDriver.ttys = NULL;
493 }
494 if (brd->PrintDriver.ttys) {
495 kfree(brd->PrintDriver.ttys);
496 brd->PrintDriver.ttys = NULL;
497 }
498}
499
500
501#define TMPBUFLEN (1024)
502
503/*
504 * dgnc_sniff - Dump data out to the "sniff" buffer if the
505 * proc sniff file is opened...
506 */
507void dgnc_sniff_nowait_nolock(struct channel_t *ch, uchar *text, uchar *buf, int len)
508{
509 struct timeval tv;
510 int n;
511 int r;
512 int nbuf;
513 int i;
514 int tmpbuflen;
515 char tmpbuf[TMPBUFLEN];
516 char *p = tmpbuf;
517 int too_much_data;
518
519 /* Leave if sniff not open */
520 if (!(ch->ch_sniff_flags & SNIFF_OPEN))
521 return;
522
523 do_gettimeofday(&tv);
524
525 /* Create our header for data dump */
526 p += sprintf(p, "<%ld %ld><%s><", tv.tv_sec, tv.tv_usec, text);
527 tmpbuflen = p - tmpbuf;
528
529 do {
530 too_much_data = 0;
531
532 for (i = 0; i < len && tmpbuflen < (TMPBUFLEN - 4); i++) {
533 p += sprintf(p, "%02x ", *buf);
534 buf++;
535 tmpbuflen = p - tmpbuf;
536 }
537
538 if (tmpbuflen < (TMPBUFLEN - 4)) {
539 if (i > 0)
540 p += sprintf(p - 1, "%s\n", ">");
541 else
542 p += sprintf(p, "%s\n", ">");
543 } else {
544 too_much_data = 1;
545 len -= i;
546 }
547
548 nbuf = strlen(tmpbuf);
549 p = tmpbuf;
550
551 /*
552 * Loop while data remains.
553 */
554 while (nbuf > 0 && ch->ch_sniff_buf != 0) {
555 /*
556 * Determine the amount of available space left in the
557 * buffer. If there's none, wait until some appears.
558 */
559 n = (ch->ch_sniff_out - ch->ch_sniff_in - 1) & SNIFF_MASK;
560
561 /*
562 * If there is no space left to write to in our sniff buffer,
563 * we have no choice but to drop the data.
564 * We *cannot* sleep here waiting for space, because this
565 * function was probably called by the interrupt/timer routines!
566 */
567 if (n == 0) {
568 return;
569 }
570
571 /*
572 * Copy as much data as will fit.
573 */
574
575 if (n > nbuf)
576 n = nbuf;
577
578 r = SNIFF_MAX - ch->ch_sniff_in;
579
580 if (r <= n) {
581 memcpy(ch->ch_sniff_buf + ch->ch_sniff_in, p, r);
582
583 n -= r;
584 ch->ch_sniff_in = 0;
585 p += r;
586 nbuf -= r;
587 }
588
589 memcpy(ch->ch_sniff_buf + ch->ch_sniff_in, p, n);
590
591 ch->ch_sniff_in += n;
592 p += n;
593 nbuf -= n;
594
595 /*
596 * Wakeup any thread waiting for data
597 */
598 if (ch->ch_sniff_flags & SNIFF_WAIT_DATA) {
599 ch->ch_sniff_flags &= ~SNIFF_WAIT_DATA;
600 wake_up_interruptible(&ch->ch_sniff_wait);
601 }
602 }
603
604 /*
605 * If the user sent us too much data to push into our tmpbuf,
606 * we need to keep looping around on all the data.
607 */
608 if (too_much_data) {
609 p = tmpbuf;
610 tmpbuflen = 0;
611 }
612
613 } while (too_much_data);
614}
615
616
617/*=======================================================================
618 *
619 * dgnc_wmove - Write data to transmit queue.
620 *
621 * ch - Pointer to channel structure.
622 * buf - Poiter to characters to be moved.
623 * n - Number of characters to move.
624 *
625 *=======================================================================*/
626static void dgnc_wmove(struct channel_t *ch, char *buf, uint n)
627{
628 int remain;
629 uint head;
630
631 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
632 return;
633
634 head = ch->ch_w_head & WQUEUEMASK;
635
636 /*
637 * If the write wraps over the top of the circular buffer,
638 * move the portion up to the wrap point, and reset the
639 * pointers to the bottom.
640 */
641 remain = WQUEUESIZE - head;
642
643 if (n >= remain) {
644 n -= remain;
645 memcpy(ch->ch_wqueue + head, buf, remain);
646 head = 0;
647 buf += remain;
648 }
649
650 if (n > 0) {
651 /*
652 * Move rest of data.
653 */
654 remain = n;
655 memcpy(ch->ch_wqueue + head, buf, remain);
656 head += remain;
657 }
658
659 head &= WQUEUEMASK;
660 ch->ch_w_head = head;
661}
662
663
664
665
666/*=======================================================================
667 *
668 * dgnc_input - Process received data.
669 *
670 * ch - Pointer to channel structure.
671 *
672 *=======================================================================*/
673void dgnc_input(struct channel_t *ch)
674{
675 struct board_t *bd;
676 struct tty_struct *tp;
677 struct tty_ldisc *ld;
678 uint rmask;
679 ushort head;
680 ushort tail;
681 int data_len;
682 ulong lock_flags;
683 int flip_len;
684 int len = 0;
685 int n = 0;
686 char *buf = NULL;
687 int s = 0;
688 int i = 0;
689
690 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
691 return;
692
693 tp = ch->ch_tun.un_tty;
694
695 bd = ch->ch_bd;
696 if(!bd || bd->magic != DGNC_BOARD_MAGIC)
697 return;
698
699 DGNC_LOCK(ch->ch_lock, lock_flags);
700
701 /*
702 * Figure the number of characters in the buffer.
703 * Exit immediately if none.
704 */
705 rmask = RQUEUEMASK;
706 head = ch->ch_r_head & rmask;
707 tail = ch->ch_r_tail & rmask;
708 data_len = (head - tail) & rmask;
709
710 if (data_len == 0) {
711 DGNC_UNLOCK(ch->ch_lock, lock_flags);
712 return;
713 }
714
715 DPR_READ(("dgnc_input start\n"));
716
717 /*
718 * If the device is not open, or CREAD is off,
719 * flush input data and return immediately.
720 */
721 if (!tp || (tp->magic != TTY_MAGIC) || !(ch->ch_tun.un_flags & UN_ISOPEN) ||
722 !(tp->termios->c_cflag & CREAD) || (ch->ch_tun.un_flags & UN_CLOSING)) {
723
724 DPR_READ(("input. dropping %d bytes on port %d...\n", data_len, ch->ch_portnum));
725 DPR_READ(("input. tp: %p tp->magic: %x MAGIC:%x ch flags: %x\n",
726 tp, tp ? tp->magic : 0, TTY_MAGIC, ch->ch_tun.un_flags));
727
728 ch->ch_r_head = tail;
729
730 /* Force queue flow control to be released, if needed */
731 dgnc_check_queue_flow_control(ch);
732
733 DGNC_UNLOCK(ch->ch_lock, lock_flags);
734 return;
735 }
736
737 /*
738 * If we are throttled, simply don't read any data.
739 */
740 if (ch->ch_flags & CH_FORCED_STOPI) {
741 DGNC_UNLOCK(ch->ch_lock, lock_flags);
742 DPR_READ(("Port %d throttled, not reading any data. head: %x tail: %x\n",
743 ch->ch_portnum, head, tail));
744 return;
745 }
746
747 DPR_READ(("dgnc_input start 2\n"));
748
749 /* Decide how much data we can send into the tty layer */
750 if (dgnc_rawreadok && tp->real_raw)
751 flip_len = MYFLIPLEN;
752 else
753 flip_len = TTY_FLIPBUF_SIZE;
754
755 /* Chop down the length, if needed */
756 len = min(data_len, flip_len);
757 len = min(len, (N_TTY_BUF_SIZE - 1) - tp->read_cnt);
758
759 ld = tty_ldisc_ref(tp);
760
761#ifdef TTY_DONT_FLIP
762 /*
763 * If the DONT_FLIP flag is on, don't flush our buffer, and act
764 * like the ld doesn't have any space to put the data right now.
765 */
766 if (test_bit(TTY_DONT_FLIP, &tp->flags))
767 len = 0;
768#endif
769
770 /*
771 * If we were unable to get a reference to the ld,
772 * don't flush our buffer, and act like the ld doesn't
773 * have any space to put the data right now.
774 */
775 if (!ld) {
776 len = 0;
777 } else {
778 /*
779 * If ld doesn't have a pointer to a receive_buf function,
780 * flush the data, then act like the ld doesn't have any
781 * space to put the data right now.
782 */
783 if (!ld->ops->receive_buf) {
784 ch->ch_r_head = ch->ch_r_tail;
785 len = 0;
786 }
787 }
788
789 if (len <= 0) {
790 DGNC_UNLOCK(ch->ch_lock, lock_flags);
791 if (ld)
792 tty_ldisc_deref(ld);
793 return;
794 }
795
796 /*
797 * The tty layer in the kernel has changed in 2.6.16+.
798 *
799 * The flip buffers in the tty structure are no longer exposed,
800 * and probably will be going away eventually.
801 *
802 * If we are completely raw, we don't need to go through a lot
803 * of the tty layers that exist.
804 * In this case, we take the shortest and fastest route we
805 * can to relay the data to the user.
806 *
807 * On the other hand, if we are not raw, we need to go through
808 * the new 2.6.16+ tty layer, which has its API more well defined.
809 */
810 if (dgnc_rawreadok && tp->real_raw) {
811
812 if (ch->ch_flags & CH_FLIPBUF_IN_USE) {
813 DPR_READ(("DGNC - FLIPBUF in use. delaying input\n"));
814 DGNC_UNLOCK(ch->ch_lock, lock_flags);
815 if (ld)
816 tty_ldisc_deref(ld);
817 return;
818 }
819
820 ch->ch_flags |= CH_FLIPBUF_IN_USE;
821 buf = ch->ch_bd->flipbuf;
822
823 n = len;
824
825 /*
826 * n now contains the most amount of data we can copy,
827 * bounded either by the flip buffer size or the amount
828 * of data the card actually has pending...
829 */
830 while (n) {
831 s = ((head >= tail) ? head : RQUEUESIZE) - tail;
832 s = min(s, n);
833
834 if (s <= 0)
835 break;
836
837 memcpy(buf, ch->ch_rqueue + tail, s);
838 dgnc_sniff_nowait_nolock(ch, "USER READ", ch->ch_rqueue + tail, s);
839
840 tail += s;
841 buf += s;
842
843 n -= s;
844 /* Flip queue if needed */
845 tail &= rmask;
846 }
847
848 ch->ch_r_tail = tail & rmask;
849 ch->ch_e_tail = tail & rmask;
850
851 dgnc_check_queue_flow_control(ch);
852
853 /* !!! WE *MUST* LET GO OF ALL LOCKS BEFORE CALLING RECEIVE BUF !!! */
854
855 DGNC_UNLOCK(ch->ch_lock, lock_flags);
856
857 DPR_READ(("dgnc_input. %d real_raw len:%d calling receive_buf for buffer for board %d\n",
858 __LINE__, len, ch->ch_bd->boardnum));
859
860#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)
861 tp->ldisc->ops->receive_buf(tp, ch->ch_bd->flipbuf, NULL, len);
862#else
863 tp->ldisc.ops->receive_buf(tp, ch->ch_bd->flipbuf, NULL, len);
864#endif
865
866 /* Allow use of channel flip buffer again */
867 DGNC_LOCK(ch->ch_lock, lock_flags);
868 ch->ch_flags &= ~CH_FLIPBUF_IN_USE;
869 DGNC_UNLOCK(ch->ch_lock, lock_flags);
870
871 }
872 else {
873 len = tty_buffer_request_room(tp, len);
874 n = len;
875
876 /*
877 * n now contains the most amount of data we can copy,
878 * bounded either by how much the Linux tty layer can handle,
879 * or the amount of data the card actually has pending...
880 */
881 while (n) {
882 s = ((head >= tail) ? head : RQUEUESIZE) - tail;
883 s = min(s, n);
884
885 if (s <= 0)
886 break;
887
888 /*
889 * If conditions are such that ld needs to see all
890 * UART errors, we will have to walk each character
891 * and error byte and send them to the buffer one at
892 * a time.
893 */
894 if (I_PARMRK(tp) || I_BRKINT(tp) || I_INPCK(tp)) {
895 for (i = 0; i < s; i++) {
896 if (*(ch->ch_equeue + tail + i) & UART_LSR_BI)
897 tty_insert_flip_char(tp, *(ch->ch_rqueue + tail + i), TTY_BREAK);
898 else if (*(ch->ch_equeue + tail + i) & UART_LSR_PE)
899 tty_insert_flip_char(tp, *(ch->ch_rqueue + tail + i), TTY_PARITY);
900 else if (*(ch->ch_equeue + tail + i) & UART_LSR_FE)
901 tty_insert_flip_char(tp, *(ch->ch_rqueue + tail + i), TTY_FRAME);
902 else
903 tty_insert_flip_char(tp, *(ch->ch_rqueue + tail + i), TTY_NORMAL);
904 }
905 }
906 else {
907 tty_insert_flip_string(tp, ch->ch_rqueue + tail, s);
908 }
909
910 dgnc_sniff_nowait_nolock(ch, "USER READ", ch->ch_rqueue + tail, s);
911
912 tail += s;
913 n -= s;
914 /* Flip queue if needed */
915 tail &= rmask;
916 }
917
918 ch->ch_r_tail = tail & rmask;
919 ch->ch_e_tail = tail & rmask;
920 dgnc_check_queue_flow_control(ch);
921 DGNC_UNLOCK(ch->ch_lock, lock_flags);
922
923 /* Tell the tty layer its okay to "eat" the data now */
924 tty_flip_buffer_push(tp);
925 }
926
927 if (ld)
928 tty_ldisc_deref(ld);
929
930 DPR_READ(("dgnc_input - finish\n"));
931}
932
933
934/************************************************************************
935 * Determines when CARRIER changes state and takes appropriate
936 * action.
937 ************************************************************************/
938void dgnc_carrier(struct channel_t *ch)
939{
940 struct board_t *bd;
941
942 int virt_carrier = 0;
943 int phys_carrier = 0;
944
945 DPR_CARR(("dgnc_carrier called...\n"));
946
947 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
948 return;
949
950 bd = ch->ch_bd;
951
952 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
953 return;
954
955 if (ch->ch_mistat & UART_MSR_DCD) {
956 DPR_CARR(("mistat: %x D_CD: %x\n", ch->ch_mistat, ch->ch_mistat & UART_MSR_DCD));
957 phys_carrier = 1;
958 }
959
960 if (ch->ch_digi.digi_flags & DIGI_FORCEDCD) {
961 virt_carrier = 1;
962 }
963
964 if (ch->ch_c_cflag & CLOCAL) {
965 virt_carrier = 1;
966 }
967
968
969 DPR_CARR(("DCD: physical: %d virt: %d\n", phys_carrier, virt_carrier));
970
971 /*
972 * Test for a VIRTUAL carrier transition to HIGH.
973 */
974 if (((ch->ch_flags & CH_FCAR) == 0) && (virt_carrier == 1)) {
975
976 /*
977 * When carrier rises, wake any threads waiting
978 * for carrier in the open routine.
979 */
980
981 DPR_CARR(("carrier: virt DCD rose\n"));
982
983 if (waitqueue_active(&(ch->ch_flags_wait)))
984 wake_up_interruptible(&ch->ch_flags_wait);
985 }
986
987 /*
988 * Test for a PHYSICAL carrier transition to HIGH.
989 */
990 if (((ch->ch_flags & CH_CD) == 0) && (phys_carrier == 1)) {
991
992 /*
993 * When carrier rises, wake any threads waiting
994 * for carrier in the open routine.
995 */
996
997 DPR_CARR(("carrier: physical DCD rose\n"));
998
999 if (waitqueue_active(&(ch->ch_flags_wait)))
1000 wake_up_interruptible(&ch->ch_flags_wait);
1001 }
1002
1003 /*
1004 * Test for a PHYSICAL transition to low, so long as we aren't
1005 * currently ignoring physical transitions (which is what "virtual
1006 * carrier" indicates).
1007 *
1008 * The transition of the virtual carrier to low really doesn't
1009 * matter... it really only means "ignore carrier state", not
1010 * "make pretend that carrier is there".
1011 */
1012 if ((virt_carrier == 0) && ((ch->ch_flags & CH_CD) != 0) &&
1013 (phys_carrier == 0))
1014 {
1015
1016 /*
1017 * When carrier drops:
1018 *
1019 * Drop carrier on all open units.
1020 *
1021 * Flush queues, waking up any task waiting in the
1022 * line discipline.
1023 *
1024 * Send a hangup to the control terminal.
1025 *
1026 * Enable all select calls.
1027 */
1028 if (waitqueue_active(&(ch->ch_flags_wait)))
1029 wake_up_interruptible(&ch->ch_flags_wait);
1030
1031 if (ch->ch_tun.un_open_count > 0) {
1032 DPR_CARR(("Sending tty hangup\n"));
1033 tty_hangup(ch->ch_tun.un_tty);
1034 }
1035
1036 if (ch->ch_pun.un_open_count > 0) {
1037 DPR_CARR(("Sending pr hangup\n"));
1038 tty_hangup(ch->ch_pun.un_tty);
1039 }
1040 }
1041
1042 /*
1043 * Make sure that our cached values reflect the current reality.
1044 */
1045 if (virt_carrier == 1)
1046 ch->ch_flags |= CH_FCAR;
1047 else
1048 ch->ch_flags &= ~CH_FCAR;
1049
1050 if (phys_carrier == 1)
1051 ch->ch_flags |= CH_CD;
1052 else
1053 ch->ch_flags &= ~CH_CD;
1054}
1055
1056/*
1057 * Assign the custom baud rate to the channel structure
1058 */
1059static void dgnc_set_custom_speed(struct channel_t *ch, uint newrate)
1060{
1061 int testdiv;
1062 int testrate_high;
1063 int testrate_low;
1064 int deltahigh;
1065 int deltalow;
1066
1067 if (newrate < 0)
1068 newrate = 0;
1069
1070 /*
1071 * Since the divisor is stored in a 16-bit integer, we make sure
1072 * we don't allow any rates smaller than a 16-bit integer would allow.
1073 * And of course, rates above the dividend won't fly.
1074 */
1075 if (newrate && newrate < ((ch->ch_bd->bd_dividend / 0xFFFF) + 1))
1076 newrate = ((ch->ch_bd->bd_dividend / 0xFFFF) + 1);
1077
1078 if (newrate && newrate > ch->ch_bd->bd_dividend)
1079 newrate = ch->ch_bd->bd_dividend;
1080
1081 while (newrate > 0) {
1082 testdiv = ch->ch_bd->bd_dividend / newrate;
1083
1084 /*
1085 * If we try to figure out what rate the board would use
1086 * with the test divisor, it will be either equal or higher
1087 * than the requested baud rate. If we then determine the
1088 * rate with a divisor one higher, we will get the next lower
1089 * supported rate below the requested.
1090 */
1091 testrate_high = ch->ch_bd->bd_dividend / testdiv;
1092 testrate_low = ch->ch_bd->bd_dividend / (testdiv + 1);
1093
1094 /*
1095 * If the rate for the requested divisor is correct, just
1096 * use it and be done.
1097 */
1098 if (testrate_high == newrate )
1099 break;
1100
1101 /*
1102 * Otherwise, pick the rate that is closer (i.e. whichever rate
1103 * has a smaller delta).
1104 */
1105 deltahigh = testrate_high - newrate;
1106 deltalow = newrate - testrate_low;
1107
1108 if (deltahigh < deltalow) {
1109 newrate = testrate_high;
1110 } else {
1111 newrate = testrate_low;
1112 }
1113
1114 break;
1115 }
1116
1117 ch->ch_custom_speed = newrate;
1118
1119 return;
1120}
1121
1122
1123void dgnc_check_queue_flow_control(struct channel_t *ch)
1124{
1125 int qleft = 0;
1126
1127 /* Store how much space we have left in the queue */
1128 if ((qleft = ch->ch_r_tail - ch->ch_r_head - 1) < 0)
1129 qleft += RQUEUEMASK + 1;
1130
1131 /*
1132 * Check to see if we should enforce flow control on our queue because
1133 * the ld (or user) isn't reading data out of our queue fast enuf.
1134 *
1135 * NOTE: This is done based on what the current flow control of the
1136 * port is set for.
1137 *
1138 * 1) HWFLOW (RTS) - Turn off the UART's Receive interrupt.
1139 * This will cause the UART's FIFO to back up, and force
1140 * the RTS signal to be dropped.
1141 * 2) SWFLOW (IXOFF) - Keep trying to send a stop character to
1142 * the other side, in hopes it will stop sending data to us.
1143 * 3) NONE - Nothing we can do. We will simply drop any extra data
1144 * that gets sent into us when the queue fills up.
1145 */
1146 if (qleft < 256) {
1147 /* HWFLOW */
1148 if (ch->ch_digi.digi_flags & CTSPACE || ch->ch_c_cflag & CRTSCTS) {
1149 if(!(ch->ch_flags & CH_RECEIVER_OFF)) {
1150 ch->ch_bd->bd_ops->disable_receiver(ch);
1151 ch->ch_flags |= (CH_RECEIVER_OFF);
1152 DPR_READ(("Internal queue hit hilevel mark (%d)! Turning off interrupts.\n",
1153 qleft));
1154 }
1155 }
1156 /* SWFLOW */
1157 else if (ch->ch_c_iflag & IXOFF) {
1158 if (ch->ch_stops_sent <= MAX_STOPS_SENT) {
1159 ch->ch_bd->bd_ops->send_stop_character(ch);
1160 ch->ch_stops_sent++;
1161 DPR_READ(("Sending stop char! Times sent: %x\n", ch->ch_stops_sent));
1162 }
1163 }
1164 /* No FLOW */
1165 else {
1166 /* Empty... Can't do anything about the impending overflow... */
1167 }
1168 }
1169
1170 /*
1171 * Check to see if we should unenforce flow control because
1172 * ld (or user) finally read enuf data out of our queue.
1173 *
1174 * NOTE: This is done based on what the current flow control of the
1175 * port is set for.
1176 *
1177 * 1) HWFLOW (RTS) - Turn back on the UART's Receive interrupt.
1178 * This will cause the UART's FIFO to raise RTS back up,
1179 * which will allow the other side to start sending data again.
1180 * 2) SWFLOW (IXOFF) - Send a start character to
1181 * the other side, so it will start sending data to us again.
1182 * 3) NONE - Do nothing. Since we didn't do anything to turn off the
1183 * other side, we don't need to do anything now.
1184 */
1185 if (qleft > (RQUEUESIZE / 2)) {
1186 /* HWFLOW */
1187 if (ch->ch_digi.digi_flags & RTSPACE || ch->ch_c_cflag & CRTSCTS) {
1188 if (ch->ch_flags & CH_RECEIVER_OFF) {
1189 ch->ch_bd->bd_ops->enable_receiver(ch);
1190 ch->ch_flags &= ~(CH_RECEIVER_OFF);
1191 DPR_READ(("Internal queue hit lowlevel mark (%d)! Turning on interrupts.\n",
1192 qleft));
1193 }
1194 }
1195 /* SWFLOW */
1196 else if (ch->ch_c_iflag & IXOFF && ch->ch_stops_sent) {
1197 ch->ch_stops_sent = 0;
1198 ch->ch_bd->bd_ops->send_start_character(ch);
1199 DPR_READ(("Sending start char!\n"));
1200 }
1201 /* No FLOW */
1202 else {
1203 /* Nothing needed. */
1204 }
1205 }
1206}
1207
1208
1209void dgnc_wakeup_writes(struct channel_t *ch)
1210{
1211 int qlen = 0;
1212 ulong lock_flags;
1213
1214 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
1215 return;
1216
1217 DGNC_LOCK(ch->ch_lock, lock_flags);
1218
1219 /*
1220 * If channel now has space, wake up anyone waiting on the condition.
1221 */
1222 if ((qlen = ch->ch_w_head - ch->ch_w_tail) < 0)
1223 qlen += WQUEUESIZE;
1224
1225 if (qlen >= (WQUEUESIZE - 256)) {
1226 DGNC_UNLOCK(ch->ch_lock, lock_flags);
1227 return;
1228 }
1229
1230 if (ch->ch_tun.un_flags & UN_ISOPEN) {
1231#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)
1232 if ((ch->ch_tun.un_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
1233 ch->ch_tun.un_tty->ldisc->ops->write_wakeup)
1234 {
1235 DGNC_UNLOCK(ch->ch_lock, lock_flags);
1236 (ch->ch_tun.un_tty->ldisc->ops->write_wakeup)(ch->ch_tun.un_tty);
1237 DGNC_LOCK(ch->ch_lock, lock_flags);
1238 }
1239#else
1240 if ((ch->ch_tun.un_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
1241 ch->ch_tun.un_tty->ldisc.ops->write_wakeup)
1242 {
1243 DGNC_UNLOCK(ch->ch_lock, lock_flags);
1244 (ch->ch_tun.un_tty->ldisc.ops->write_wakeup)(ch->ch_tun.un_tty);
1245 DGNC_LOCK(ch->ch_lock, lock_flags);
1246 }
1247#endif
1248
1249 wake_up_interruptible(&ch->ch_tun.un_tty->write_wait);
1250
1251 /*
1252 * If unit is set to wait until empty, check to make sure
1253 * the queue AND FIFO are both empty.
1254 */
1255 if (ch->ch_tun.un_flags & UN_EMPTY) {
1256 if ((qlen == 0) && (ch->ch_bd->bd_ops->get_uart_bytes_left(ch) == 0)) {
1257 ch->ch_tun.un_flags &= ~(UN_EMPTY);
1258
1259 /*
1260 * If RTS Toggle mode is on, whenever
1261 * the queue and UART is empty, keep RTS low.
1262 */
1263 if (ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE) {
1264 ch->ch_mostat &= ~(UART_MCR_RTS);
1265 ch->ch_bd->bd_ops->assert_modem_signals(ch);
1266 }
1267
1268 /*
1269 * If DTR Toggle mode is on, whenever
1270 * the queue and UART is empty, keep DTR low.
1271 */
1272 if (ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE) {
1273 ch->ch_mostat &= ~(UART_MCR_DTR);
1274 ch->ch_bd->bd_ops->assert_modem_signals(ch);
1275 }
1276 }
1277 }
1278
1279 wake_up_interruptible(&ch->ch_tun.un_flags_wait);
1280 }
1281
1282 if (ch->ch_pun.un_flags & UN_ISOPEN) {
1283#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)
1284 if ((ch->ch_pun.un_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
1285 ch->ch_pun.un_tty->ldisc->ops->write_wakeup)
1286 {
1287 DGNC_UNLOCK(ch->ch_lock, lock_flags);
1288 (ch->ch_pun.un_tty->ldisc->ops->write_wakeup)(ch->ch_pun.un_tty);
1289 DGNC_LOCK(ch->ch_lock, lock_flags);
1290 }
1291#else
1292 if ((ch->ch_pun.un_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
1293 ch->ch_pun.un_tty->ldisc.ops->write_wakeup)
1294 {
1295 DGNC_UNLOCK(ch->ch_lock, lock_flags);
1296 (ch->ch_pun.un_tty->ldisc.ops->write_wakeup)(ch->ch_pun.un_tty);
1297 DGNC_LOCK(ch->ch_lock, lock_flags);
1298 }
1299#endif
1300
1301 wake_up_interruptible(&ch->ch_pun.un_tty->write_wait);
1302
1303 /*
1304 * If unit is set to wait until empty, check to make sure
1305 * the queue AND FIFO are both empty.
1306 */
1307 if (ch->ch_pun.un_flags & UN_EMPTY) {
1308 if ((qlen == 0) && (ch->ch_bd->bd_ops->get_uart_bytes_left(ch) == 0)) {
1309 ch->ch_pun.un_flags &= ~(UN_EMPTY);
1310 }
1311 }
1312
1313 wake_up_interruptible(&ch->ch_pun.un_flags_wait);
1314 }
1315
1316 DGNC_UNLOCK(ch->ch_lock, lock_flags);
1317}
1318
1319
1320
1321/************************************************************************
1322 *
1323 * TTY Entry points and helper functions
1324 *
1325 ************************************************************************/
1326
1327/*
1328 * dgnc_tty_open()
1329 *
1330 */
1331static int dgnc_tty_open(struct tty_struct *tty, struct file *file)
1332{
1333 struct board_t *brd;
1334 struct channel_t *ch;
1335 struct un_t *un;
1336 uint major = 0;
1337 uint minor = 0;
1338 int rc = 0;
1339 ulong lock_flags;
1340
1341 rc = 0;
1342
1343 major = MAJOR(tty_devnum(tty));
1344 minor = MINOR(tty_devnum(tty));
1345
1346 if (major > 255) {
1347 return -ENXIO;
1348 }
1349
1350 /* Get board pointer from our array of majors we have allocated */
1351 brd = dgnc_BoardsByMajor[major];
1352 if (!brd) {
1353 return -ENXIO;
1354 }
1355
1356 /*
1357 * If board is not yet up to a state of READY, go to
1358 * sleep waiting for it to happen or they cancel the open.
1359 */
1360 rc = wait_event_interruptible(brd->state_wait,
1361 (brd->state & BOARD_READY));
1362
1363 if (rc) {
1364 return rc;
1365 }
1366
1367 DGNC_LOCK(brd->bd_lock, lock_flags);
1368
1369 /* If opened device is greater than our number of ports, bail. */
1370 if (PORT_NUM(minor) > brd->nasync) {
1371 DGNC_UNLOCK(brd->bd_lock, lock_flags);
1372 return -ENXIO;
1373 }
1374
1375 ch = brd->channels[PORT_NUM(minor)];
1376 if (!ch) {
1377 DGNC_UNLOCK(brd->bd_lock, lock_flags);
1378 return -ENXIO;
1379 }
1380
1381 /* Drop board lock */
1382 DGNC_UNLOCK(brd->bd_lock, lock_flags);
1383
1384 /* Grab channel lock */
1385 DGNC_LOCK(ch->ch_lock, lock_flags);
1386
1387 /* Figure out our type */
1388 if (!IS_PRINT(minor)) {
1389 un = &brd->channels[PORT_NUM(minor)]->ch_tun;
1390 un->un_type = DGNC_SERIAL;
1391 }
1392 else if (IS_PRINT(minor)) {
1393 un = &brd->channels[PORT_NUM(minor)]->ch_pun;
1394 un->un_type = DGNC_PRINT;
1395 }
1396 else {
1397 DGNC_UNLOCK(ch->ch_lock, lock_flags);
1398 DPR_OPEN(("%d Unknown TYPE!\n", __LINE__));
1399 return -ENXIO;
1400 }
1401
1402 /*
1403 * If the port is still in a previous open, and in a state
1404 * where we simply cannot safely keep going, wait until the
1405 * state clears.
1406 */
1407 DGNC_UNLOCK(ch->ch_lock, lock_flags);
1408
1409 rc = wait_event_interruptible(ch->ch_flags_wait, ((ch->ch_flags & CH_OPENING) == 0));
1410
1411 /* If ret is non-zero, user ctrl-c'ed us */
1412 if (rc) {
1413 DPR_OPEN(("%d User ctrl c'ed\n", __LINE__));
1414 return -EINTR;
1415 }
1416
1417 /*
1418 * If either unit is in the middle of the fragile part of close,
1419 * we just cannot touch the channel safely.
1420 * Go to sleep, knowing that when the channel can be
1421 * touched safely, the close routine will signal the
1422 * ch_flags_wait to wake us back up.
1423 */
1424 rc = wait_event_interruptible(ch->ch_flags_wait,
1425 (((ch->ch_tun.un_flags | ch->ch_pun.un_flags) & UN_CLOSING) == 0));
1426
1427 /* If ret is non-zero, user ctrl-c'ed us */
1428 if (rc) {
1429 DPR_OPEN(("%d User ctrl c'ed\n", __LINE__));
1430 return -EINTR;
1431 }
1432
1433 DGNC_LOCK(ch->ch_lock, lock_flags);
1434
1435
1436 /* Store our unit into driver_data, so we always have it available. */
1437 tty->driver_data = un;
1438
1439 DPR_OPEN(("Open called. MAJOR: %d MINOR:%d PORT_NUM: %x unit: %p NAME: %s\n",
1440 MAJOR(tty_devnum(tty)), MINOR(tty_devnum(tty)), PORT_NUM(minor), un, brd->name));
1441
1442 DPR_OPEN(("%d: tflag=%x pflag=%x\n", __LINE__, ch->ch_tun.un_flags, ch->ch_pun.un_flags));
1443
1444 /*
1445 * Initialize tty's
1446 */
1447 if (!(un->un_flags & UN_ISOPEN)) {
1448 /* Store important variables. */
1449 un->un_tty = tty;
1450
1451 /* Maybe do something here to the TTY struct as well? */
1452 }
1453
1454
1455 /*
1456 * Allocate channel buffers for read/write/error.
1457 * Set flag, so we don't get trounced on.
1458 */
1459 ch->ch_flags |= (CH_OPENING);
1460
1461 /* Drop locks, as malloc with GFP_KERNEL can sleep */
1462 DGNC_UNLOCK(ch->ch_lock, lock_flags);
1463
1464 if (!ch->ch_rqueue)
1465 ch->ch_rqueue = dgnc_driver_kzmalloc(RQUEUESIZE, GFP_KERNEL);
1466 if (!ch->ch_equeue)
1467 ch->ch_equeue = dgnc_driver_kzmalloc(EQUEUESIZE, GFP_KERNEL);
1468 if (!ch->ch_wqueue)
1469 ch->ch_wqueue = dgnc_driver_kzmalloc(WQUEUESIZE, GFP_KERNEL);
1470
1471 DGNC_LOCK(ch->ch_lock, lock_flags);
1472
1473 ch->ch_flags &= ~(CH_OPENING);
1474 wake_up_interruptible(&ch->ch_flags_wait);
1475
1476 /*
1477 * Initialize if neither terminal or printer is open.
1478 */
1479 if (!((ch->ch_tun.un_flags | ch->ch_pun.un_flags) & UN_ISOPEN)) {
1480
1481 DPR_OPEN(("dgnc_open: initializing channel in open...\n"));
1482
1483 /*
1484 * Flush input queues.
1485 */
1486 ch->ch_r_head = ch->ch_r_tail = 0;
1487 ch->ch_e_head = ch->ch_e_tail = 0;
1488 ch->ch_w_head = ch->ch_w_tail = 0;
1489
1490 brd->bd_ops->flush_uart_write(ch);
1491 brd->bd_ops->flush_uart_read(ch);
1492
1493 ch->ch_flags = 0;
1494 ch->ch_cached_lsr = 0;
1495 ch->ch_stop_sending_break = 0;
1496 ch->ch_stops_sent = 0;
1497
1498 ch->ch_c_cflag = tty->termios->c_cflag;
1499 ch->ch_c_iflag = tty->termios->c_iflag;
1500 ch->ch_c_oflag = tty->termios->c_oflag;
1501 ch->ch_c_lflag = tty->termios->c_lflag;
1502 ch->ch_startc = tty->termios->c_cc[VSTART];
1503 ch->ch_stopc = tty->termios->c_cc[VSTOP];
1504
1505 /*
1506 * Bring up RTS and DTR...
1507 * Also handle RTS or DTR toggle if set.
1508 */
1509 if (!(ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE))
1510 ch->ch_mostat |= (UART_MCR_RTS);
1511 if (!(ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE))
1512 ch->ch_mostat |= (UART_MCR_DTR);
1513
1514 /* Tell UART to init itself */
1515 brd->bd_ops->uart_init(ch);
1516 }
1517
1518 /*
1519 * Run param in case we changed anything
1520 */
1521 brd->bd_ops->param(tty);
1522
1523 dgnc_carrier(ch);
1524
1525 /*
1526 * follow protocol for opening port
1527 */
1528
1529 DGNC_UNLOCK(ch->ch_lock, lock_flags);
1530
1531 rc = dgnc_block_til_ready(tty, file, ch);
1532
1533 if (rc) {
1534 DPR_OPEN(("dgnc_tty_open returning after dgnc_block_til_ready "
1535 "with %d\n", rc));
1536 }
1537
1538 /* No going back now, increment our unit and channel counters */
1539 DGNC_LOCK(ch->ch_lock, lock_flags);
1540 ch->ch_open_count++;
1541 un->un_open_count++;
1542 un->un_flags |= (UN_ISOPEN);
1543 DGNC_UNLOCK(ch->ch_lock, lock_flags);
1544
1545 DPR_OPEN(("dgnc_tty_open finished\n"));
1546 return (rc);
1547}
1548
1549
1550/*
1551 * dgnc_block_til_ready()
1552 *
1553 * Wait for DCD, if needed.
1554 */
1555static int dgnc_block_til_ready(struct tty_struct *tty, struct file *file, struct channel_t *ch)
1556{
1557 int retval = 0;
1558 struct un_t *un = NULL;
1559 ulong lock_flags;
1560 uint old_flags = 0;
1561 int sleep_on_un_flags = 0;
1562
1563 if (!tty || tty->magic != TTY_MAGIC || !file || !ch || ch->magic != DGNC_CHANNEL_MAGIC) {
1564 return (-ENXIO);
1565 }
1566
1567 un = tty->driver_data;
1568 if (!un || un->magic != DGNC_UNIT_MAGIC) {
1569 return (-ENXIO);
1570 }
1571
1572 DPR_OPEN(("dgnc_block_til_ready - before block.\n"));
1573
1574 DGNC_LOCK(ch->ch_lock, lock_flags);
1575
1576 ch->ch_wopen++;
1577
1578 /* Loop forever */
1579 while (1) {
1580
1581 sleep_on_un_flags = 0;
1582
1583 /*
1584 * If board has failed somehow during our sleep, bail with error.
1585 */
1586 if (ch->ch_bd->state == BOARD_FAILED) {
1587 retval = -ENXIO;
1588 break;
1589 }
1590
1591 /* If tty was hung up, break out of loop and set error. */
1592 if (tty_hung_up_p(file)) {
1593 retval = -EAGAIN;
1594 break;
1595 }
1596
1597 /*
1598 * If either unit is in the middle of the fragile part of close,
1599 * we just cannot touch the channel safely.
1600 * Go back to sleep, knowing that when the channel can be
1601 * touched safely, the close routine will signal the
1602 * ch_wait_flags to wake us back up.
1603 */
1604 if (!((ch->ch_tun.un_flags | ch->ch_pun.un_flags) & UN_CLOSING)) {
1605
1606 /*
1607 * Our conditions to leave cleanly and happily:
1608 * 1) NONBLOCKING on the tty is set.
1609 * 2) CLOCAL is set.
1610 * 3) DCD (fake or real) is active.
1611 */
1612
1613 if (file->f_flags & O_NONBLOCK) {
1614 break;
1615 }
1616
1617 if (tty->flags & (1 << TTY_IO_ERROR)) {
1618 retval = -EIO;
1619 break;
1620 }
1621
1622 if (ch->ch_flags & CH_CD) {
1623 DPR_OPEN(("%d: ch_flags: %x\n", __LINE__, ch->ch_flags));
1624 break;
1625 }
1626
1627 if (ch->ch_flags & CH_FCAR) {
1628 DPR_OPEN(("%d: ch_flags: %x\n", __LINE__, ch->ch_flags));
1629 break;
1630 }
1631 }
1632 else {
1633 sleep_on_un_flags = 1;
1634 }
1635
1636 /*
1637 * If there is a signal pending, the user probably
1638 * interrupted (ctrl-c) us.
1639 * Leave loop with error set.
1640 */
1641 if (signal_pending(current)) {
1642 DPR_OPEN(("%d: signal pending...\n", __LINE__));
1643 retval = -ERESTARTSYS;
1644 break;
1645 }
1646
1647 DPR_OPEN(("dgnc_block_til_ready - blocking.\n"));
1648
1649 /*
1650 * Store the flags before we let go of channel lock
1651 */
1652 if (sleep_on_un_flags)
1653 old_flags = ch->ch_tun.un_flags | ch->ch_pun.un_flags;
1654 else
1655 old_flags = ch->ch_flags;
1656
1657 /*
1658 * Let go of channel lock before calling schedule.
1659 * Our poller will get any FEP events and wake us up when DCD
1660 * eventually goes active.
1661 */
1662
1663 DGNC_UNLOCK(ch->ch_lock, lock_flags);
1664
1665 DPR_OPEN(("Going to sleep on %s flags...\n",
1666 (sleep_on_un_flags ? "un" : "ch")));
1667
1668 /*
1669 * Wait for something in the flags to change from the current value.
1670 */
1671 if (sleep_on_un_flags) {
1672 retval = wait_event_interruptible(un->un_flags_wait,
1673 (old_flags != (ch->ch_tun.un_flags | ch->ch_pun.un_flags)));
1674 }
1675 else {
1676 retval = wait_event_interruptible(ch->ch_flags_wait,
1677 (old_flags != ch->ch_flags));
1678 }
1679
1680 DPR_OPEN(("After sleep... retval: %x\n", retval));
1681
1682 /*
1683 * We got woken up for some reason.
1684 * Before looping around, grab our channel lock.
1685 */
1686 DGNC_LOCK(ch->ch_lock, lock_flags);
1687 }
1688
1689 ch->ch_wopen--;
1690
1691 DGNC_UNLOCK(ch->ch_lock, lock_flags);
1692
1693 DPR_OPEN(("dgnc_block_til_ready - after blocking.\n"));
1694
1695 if (retval) {
1696 DPR_OPEN(("dgnc_block_til_ready - done. error. retval: %x\n", retval));
1697 return(retval);
1698 }
1699
1700 DPR_OPEN(("dgnc_block_til_ready - done no error. jiffies: %lu\n", jiffies));
1701
1702 return(0);
1703}
1704
1705
1706/*
1707 * dgnc_tty_hangup()
1708 *
1709 * Hangup the port. Like a close, but don't wait for output to drain.
1710 */
1711static void dgnc_tty_hangup(struct tty_struct *tty)
1712{
1713 struct un_t *un;
1714
1715 if (!tty || tty->magic != TTY_MAGIC)
1716 return;
1717
1718 un = tty->driver_data;
1719 if (!un || un->magic != DGNC_UNIT_MAGIC)
1720 return;
1721
1722 DPR_CLOSE(("dgnc_hangup called. ch->ch_open_count: %d un->un_open_count: %d\n",
1723 un->un_ch->ch_open_count, un->un_open_count));
1724
1725 /* flush the transmit queues */
1726 dgnc_tty_flush_buffer(tty);
1727
1728 DPR_CLOSE(("dgnc_hangup finished. ch->ch_open_count: %d un->un_open_count: %d\n",
1729 un->un_ch->ch_open_count, un->un_open_count));
1730}
1731
1732
1733/*
1734 * dgnc_tty_close()
1735 *
1736 */
1737static void dgnc_tty_close(struct tty_struct *tty, struct file *file)
1738{
1739 struct ktermios *ts;
1740 struct board_t *bd;
1741 struct channel_t *ch;
1742 struct un_t *un;
1743 ulong lock_flags;
1744 int rc = 0;
1745
1746 if (!tty || tty->magic != TTY_MAGIC)
1747 return;
1748
1749 un = tty->driver_data;
1750 if (!un || un->magic != DGNC_UNIT_MAGIC)
1751 return;
1752
1753 ch = un->un_ch;
1754 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
1755 return;
1756
1757 bd = ch->ch_bd;
1758 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
1759 return;
1760
1761 ts = tty->termios;
1762
1763 DPR_CLOSE(("Close called\n"));
1764
1765 DGNC_LOCK(ch->ch_lock, lock_flags);
1766
1767 /*
1768 * Determine if this is the last close or not - and if we agree about
1769 * which type of close it is with the Line Discipline
1770 */
1771 if ((tty->count == 1) && (un->un_open_count != 1)) {
1772 /*
1773 * Uh, oh. tty->count is 1, which means that the tty
1774 * structure will be freed. un_open_count should always
1775 * be one in these conditions. If it's greater than
1776 * one, we've got real problems, since it means the
1777 * serial port won't be shutdown.
1778 */
1779 APR(("tty->count is 1, un open count is %d\n", un->un_open_count));
1780 un->un_open_count = 1;
1781 }
1782
1783 if (--un->un_open_count < 0) {
1784 APR(("bad serial port open count of %d\n", un->un_open_count));
1785 un->un_open_count = 0;
1786 }
1787
1788 ch->ch_open_count--;
1789
1790 if (ch->ch_open_count && un->un_open_count) {
1791 DPR_CLOSE(("dgnc_tty_close: not last close ch: %d un:%d\n",
1792 ch->ch_open_count, un->un_open_count));
1793
1794 DGNC_UNLOCK(ch->ch_lock, lock_flags);
1795 return;
1796 }
1797
1798 /* OK, its the last close on the unit */
1799 DPR_CLOSE(("dgnc_tty_close - last close on unit procedures\n"));
1800
1801 un->un_flags |= UN_CLOSING;
1802
1803 tty->closing = 1;
1804
1805
1806 /*
1807 * Only officially close channel if count is 0 and
1808 * DIGI_PRINTER bit is not set.
1809 */
1810 if ((ch->ch_open_count == 0) && !(ch->ch_digi.digi_flags & DIGI_PRINTER)) {
1811
1812 ch->ch_flags &= ~(CH_STOPI | CH_FORCED_STOPI);
1813
1814 /*
1815 * turn off print device when closing print device.
1816 */
1817 if ((un->un_type == DGNC_PRINT) && (ch->ch_flags & CH_PRON) ) {
1818 dgnc_wmove(ch, ch->ch_digi.digi_offstr,
1819 (int) ch->ch_digi.digi_offlen);
1820 ch->ch_flags &= ~CH_PRON;
1821 }
1822
1823 DGNC_UNLOCK(ch->ch_lock, lock_flags);
1824 /* wait for output to drain */
1825 /* This will also return if we take an interrupt */
1826
1827 DPR_CLOSE(("Calling wait_for_drain\n"));
1828 rc = bd->bd_ops->drain(tty, 0);
1829
1830 DPR_CLOSE(("After calling wait_for_drain\n"));
1831
1832 if (rc) {
1833 DPR_BASIC(("dgnc_tty_close - bad return: %d ", rc));
1834 }
1835
1836 dgnc_tty_flush_buffer(tty);
1837 tty_ldisc_flush(tty);
1838
1839 DGNC_LOCK(ch->ch_lock, lock_flags);
1840
1841 tty->closing = 0;
1842
1843 /*
1844 * If we have HUPCL set, lower DTR and RTS
1845 */
1846 if (ch->ch_c_cflag & HUPCL) {
1847 DPR_CLOSE(("Close. HUPCL set, dropping DTR/RTS\n"));
1848
1849 /* Drop RTS/DTR */
1850 ch->ch_mostat &= ~(UART_MCR_DTR | UART_MCR_RTS);
1851 bd->bd_ops->assert_modem_signals(ch);
1852
1853 /*
1854 * Go to sleep to ensure RTS/DTR
1855 * have been dropped for modems to see it.
1856 */
1857 if (ch->ch_close_delay) {
1858 DPR_CLOSE(("Close. Sleeping for RTS/DTR drop\n"));
1859
1860 DGNC_UNLOCK(ch->ch_lock, lock_flags);
1861 dgnc_ms_sleep(ch->ch_close_delay);
1862 DGNC_LOCK(ch->ch_lock, lock_flags);
1863
1864 DPR_CLOSE(("Close. After sleeping for RTS/DTR drop\n"));
1865 }
1866 }
1867
1868 ch->ch_old_baud = 0;
1869
1870 /* Turn off UART interrupts for this port */
1871 ch->ch_bd->bd_ops->uart_off(ch);
1872 }
1873 else {
1874 /*
1875 * turn off print device when closing print device.
1876 */
1877 if ((un->un_type == DGNC_PRINT) && (ch->ch_flags & CH_PRON) ) {
1878 dgnc_wmove(ch, ch->ch_digi.digi_offstr,
1879 (int) ch->ch_digi.digi_offlen);
1880 ch->ch_flags &= ~CH_PRON;
1881 }
1882 }
1883
1884 un->un_tty = NULL;
1885 un->un_flags &= ~(UN_ISOPEN | UN_CLOSING);
1886
1887 DPR_CLOSE(("Close. Doing wakeups\n"));
1888 wake_up_interruptible(&ch->ch_flags_wait);
1889 wake_up_interruptible(&un->un_flags_wait);
1890
1891 DGNC_UNLOCK(ch->ch_lock, lock_flags);
1892
1893 DPR_BASIC(("dgnc_tty_close - complete\n"));
1894}
1895
1896
1897/*
1898 * dgnc_tty_chars_in_buffer()
1899 *
1900 * Return number of characters that have not been transmitted yet.
1901 *
1902 * This routine is used by the line discipline to determine if there
1903 * is data waiting to be transmitted/drained/flushed or not.
1904 */
1905static int dgnc_tty_chars_in_buffer(struct tty_struct *tty)
1906{
1907 struct channel_t *ch = NULL;
1908 struct un_t *un = NULL;
1909 ushort thead;
1910 ushort ttail;
1911 uint tmask;
1912 uint chars = 0;
1913 ulong lock_flags = 0;
1914
1915 if (tty == NULL)
1916 return(0);
1917
1918 un = tty->driver_data;
1919 if (!un || un->magic != DGNC_UNIT_MAGIC)
1920 return (0);
1921
1922 ch = un->un_ch;
1923 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
1924 return (0);
1925
1926 DGNC_LOCK(ch->ch_lock, lock_flags);
1927
1928 tmask = WQUEUEMASK;
1929 thead = ch->ch_w_head & tmask;
1930 ttail = ch->ch_w_tail & tmask;
1931
1932 DGNC_UNLOCK(ch->ch_lock, lock_flags);
1933
1934 if (ttail == thead) {
1935 chars = 0;
1936 } else {
1937 if (thead >= ttail)
1938 chars = thead - ttail;
1939 else
1940 chars = thead - ttail + WQUEUESIZE;
1941 }
1942
1943 DPR_WRITE(("dgnc_tty_chars_in_buffer. Port: %x - %d (head: %d tail: %d)\n",
1944 ch->ch_portnum, chars, thead, ttail));
1945
1946 return(chars);
1947}
1948
1949
1950/*
1951 * dgnc_maxcps_room
1952 *
1953 * Reduces bytes_available to the max number of characters
1954 * that can be sent currently given the maxcps value, and
1955 * returns the new bytes_available. This only affects printer
1956 * output.
1957 */
1958static int dgnc_maxcps_room(struct tty_struct *tty, int bytes_available)
1959{
1960 struct channel_t *ch = NULL;
1961 struct un_t *un = NULL;
1962
1963 if (!tty)
1964 return (bytes_available);
1965
1966 un = tty->driver_data;
1967 if (!un || un->magic != DGNC_UNIT_MAGIC)
1968 return (bytes_available);
1969
1970 ch = un->un_ch;
1971 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
1972 return (bytes_available);
1973
1974 /*
1975 * If its not the Transparent print device, return
1976 * the full data amount.
1977 */
1978 if (un->un_type != DGNC_PRINT)
1979 return (bytes_available);
1980
1981 if (ch->ch_digi.digi_maxcps > 0 && ch->ch_digi.digi_bufsize > 0 ) {
1982 int cps_limit = 0;
1983 unsigned long current_time = jiffies;
1984 unsigned long buffer_time = current_time +
1985 (HZ * ch->ch_digi.digi_bufsize) / ch->ch_digi.digi_maxcps;
1986
1987 if (ch->ch_cpstime < current_time) {
1988 /* buffer is empty */
1989 ch->ch_cpstime = current_time; /* reset ch_cpstime */
1990 cps_limit = ch->ch_digi.digi_bufsize;
1991 }
1992 else if (ch->ch_cpstime < buffer_time) {
1993 /* still room in the buffer */
1994 cps_limit = ((buffer_time - ch->ch_cpstime) * ch->ch_digi.digi_maxcps) / HZ;
1995 }
1996 else {
1997 /* no room in the buffer */
1998 cps_limit = 0;
1999 }
2000
2001 bytes_available = min(cps_limit, bytes_available);
2002 }
2003
2004 return (bytes_available);
2005}
2006
2007
2008/*
2009 * dgnc_tty_write_room()
2010 *
2011 * Return space available in Tx buffer
2012 */
2013static int dgnc_tty_write_room(struct tty_struct *tty)
2014{
2015 struct channel_t *ch = NULL;
2016 struct un_t *un = NULL;
2017 ushort head;
2018 ushort tail;
2019 ushort tmask;
2020 int ret = 0;
2021 ulong lock_flags = 0;
2022
2023 if (tty == NULL || dgnc_TmpWriteBuf == NULL)
2024 return(0);
2025
2026 un = tty->driver_data;
2027 if (!un || un->magic != DGNC_UNIT_MAGIC)
2028 return (0);
2029
2030 ch = un->un_ch;
2031 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
2032 return (0);
2033
2034 DGNC_LOCK(ch->ch_lock, lock_flags);
2035
2036 tmask = WQUEUEMASK;
2037 head = (ch->ch_w_head) & tmask;
2038 tail = (ch->ch_w_tail) & tmask;
2039
2040 if ((ret = tail - head - 1) < 0)
2041 ret += WQUEUESIZE;
2042
2043 /* Limit printer to maxcps */
2044 ret = dgnc_maxcps_room(tty, ret);
2045
2046 /*
2047 * If we are printer device, leave space for
2048 * possibly both the on and off strings.
2049 */
2050 if (un->un_type == DGNC_PRINT) {
2051 if (!(ch->ch_flags & CH_PRON))
2052 ret -= ch->ch_digi.digi_onlen;
2053 ret -= ch->ch_digi.digi_offlen;
2054 }
2055 else {
2056 if (ch->ch_flags & CH_PRON)
2057 ret -= ch->ch_digi.digi_offlen;
2058 }
2059
2060 if (ret < 0)
2061 ret = 0;
2062
2063 DGNC_UNLOCK(ch->ch_lock, lock_flags);
2064
2065 DPR_WRITE(("dgnc_tty_write_room - %d tail: %d head: %d\n", ret, tail, head));
2066
2067 return(ret);
2068}
2069
2070
2071/*
2072 * dgnc_tty_put_char()
2073 *
2074 * Put a character into ch->ch_buf
2075 *
2076 * - used by the line discipline for OPOST processing
2077 */
2078static int dgnc_tty_put_char(struct tty_struct *tty, unsigned char c)
2079{
2080 /*
2081 * Simply call tty_write.
2082 */
2083 DPR_WRITE(("dgnc_tty_put_char called\n"));
2084 dgnc_tty_write(tty, &c, 1);
2085 return 1;
2086}
2087
2088
2089/*
2090 * dgnc_tty_write()
2091 *
2092 * Take data from the user or kernel and send it out to the FEP.
2093 * In here exists all the Transparent Print magic as well.
2094 */
2095static int dgnc_tty_write(struct tty_struct *tty,
2096 const unsigned char *buf, int count)
2097{
2098 struct channel_t *ch = NULL;
2099 struct un_t *un = NULL;
2100 int bufcount = 0, n = 0;
2101 int orig_count = 0;
2102 ulong lock_flags;
2103 ushort head;
2104 ushort tail;
2105 ushort tmask;
2106 uint remain;
2107 int from_user = 0;
2108
2109 if (tty == NULL || dgnc_TmpWriteBuf == NULL)
2110 return(0);
2111
2112 un = tty->driver_data;
2113 if (!un || un->magic != DGNC_UNIT_MAGIC)
2114 return(0);
2115
2116 ch = un->un_ch;
2117 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
2118 return(0);
2119
2120 if (!count)
2121 return(0);
2122
2123 DPR_WRITE(("dgnc_tty_write: Port: %x tty=%p user=%d len=%d\n",
2124 ch->ch_portnum, tty, from_user, count));
2125
2126 /*
2127 * Store original amount of characters passed in.
2128 * This helps to figure out if we should ask the FEP
2129 * to send us an event when it has more space available.
2130 */
2131 orig_count = count;
2132
2133 DGNC_LOCK(ch->ch_lock, lock_flags);
2134
2135 /* Get our space available for the channel from the board */
2136 tmask = WQUEUEMASK;
2137 head = (ch->ch_w_head) & tmask;
2138 tail = (ch->ch_w_tail) & tmask;
2139
2140 if ((bufcount = tail - head - 1) < 0)
2141 bufcount += WQUEUESIZE;
2142
2143 DPR_WRITE(("%d: bufcount: %x count: %x tail: %x head: %x tmask: %x\n",
2144 __LINE__, bufcount, count, tail, head, tmask));
2145
2146 /*
2147 * Limit printer output to maxcps overall, with bursts allowed
2148 * up to bufsize characters.
2149 */
2150 bufcount = dgnc_maxcps_room(tty, bufcount);
2151
2152 /*
2153 * Take minimum of what the user wants to send, and the
2154 * space available in the FEP buffer.
2155 */
2156 count = min(count, bufcount);
2157
2158 /*
2159 * Bail if no space left.
2160 */
2161 if (count <= 0) {
2162 DGNC_UNLOCK(ch->ch_lock, lock_flags);
2163 return(0);
2164 }
2165
2166 /*
2167 * Output the printer ON string, if we are in terminal mode, but
2168 * need to be in printer mode.
2169 */
2170 if ((un->un_type == DGNC_PRINT) && !(ch->ch_flags & CH_PRON)) {
2171 dgnc_wmove(ch, ch->ch_digi.digi_onstr,
2172 (int) ch->ch_digi.digi_onlen);
2173 head = (ch->ch_w_head) & tmask;
2174 ch->ch_flags |= CH_PRON;
2175 }
2176
2177 /*
2178 * On the other hand, output the printer OFF string, if we are
2179 * currently in printer mode, but need to output to the terminal.
2180 */
2181 if ((un->un_type != DGNC_PRINT) && (ch->ch_flags & CH_PRON)) {
2182 dgnc_wmove(ch, ch->ch_digi.digi_offstr,
2183 (int) ch->ch_digi.digi_offlen);
2184 head = (ch->ch_w_head) & tmask;
2185 ch->ch_flags &= ~CH_PRON;
2186 }
2187
2188 /*
2189 * If there is nothing left to copy, or I can't handle any more data, leave.
2190 */
2191 if (count <= 0) {
2192 DGNC_UNLOCK(ch->ch_lock, lock_flags);
2193 return(0);
2194 }
2195
2196 if (from_user) {
2197
2198 count = min(count, WRITEBUFLEN);
2199
2200 DGNC_UNLOCK(ch->ch_lock, lock_flags);
2201
2202 /*
2203 * If data is coming from user space, copy it into a temporary
2204 * buffer so we don't get swapped out while doing the copy to
2205 * the board.
2206 */
2207 /* we're allowed to block if it's from_user */
2208 if (down_interruptible(&dgnc_TmpWriteSem)) {
2209 return (-EINTR);
2210 }
2211
2212 /*
2213 * copy_from_user() returns the number
2214 * of bytes that could *NOT* be copied.
2215 */
2216 count -= copy_from_user(dgnc_TmpWriteBuf, (const uchar __user *) buf, count);
2217
2218 if (!count) {
2219 up(&dgnc_TmpWriteSem);
2220 return(-EFAULT);
2221 }
2222
2223 DGNC_LOCK(ch->ch_lock, lock_flags);
2224
2225 buf = dgnc_TmpWriteBuf;
2226
2227 }
2228
2229 n = count;
2230
2231 /*
2232 * If the write wraps over the top of the circular buffer,
2233 * move the portion up to the wrap point, and reset the
2234 * pointers to the bottom.
2235 */
2236 remain = WQUEUESIZE - head;
2237
2238 if (n >= remain) {
2239 n -= remain;
2240 memcpy(ch->ch_wqueue + head, buf, remain);
2241 dgnc_sniff_nowait_nolock(ch, "USER WRITE", ch->ch_wqueue + head, remain);
2242 head = 0;
2243 buf += remain;
2244 }
2245
2246 if (n > 0) {
2247 /*
2248 * Move rest of data.
2249 */
2250 remain = n;
2251 memcpy(ch->ch_wqueue + head, buf, remain);
2252 dgnc_sniff_nowait_nolock(ch, "USER WRITE", ch->ch_wqueue + head, remain);
2253 head += remain;
2254 }
2255
2256 if (count) {
2257 head &= tmask;
2258 ch->ch_w_head = head;
2259 }
2260
2261#if 0
2262 /*
2263 * If this is the print device, and the
2264 * printer is still on, we need to turn it
2265 * off before going idle.
2266 */
2267 if (count == orig_count) {
2268 if ((un->un_type == DGNC_PRINT) && (ch->ch_flags & CH_PRON)) {
2269 head &= tmask;
2270 ch->ch_w_head = head;
2271 dgnc_wmove(ch, ch->ch_digi.digi_offstr,
2272 (int) ch->ch_digi.digi_offlen);
2273 head = (ch->ch_w_head) & tmask;
2274 ch->ch_flags &= ~CH_PRON;
2275 }
2276 }
2277#endif
2278
2279 /* Update printer buffer empty time. */
2280 if ((un->un_type == DGNC_PRINT) && (ch->ch_digi.digi_maxcps > 0)
2281 && (ch->ch_digi.digi_bufsize > 0)) {
2282 ch->ch_cpstime += (HZ * count) / ch->ch_digi.digi_maxcps;
2283 }
2284
2285 if (from_user) {
2286 DGNC_UNLOCK(ch->ch_lock, lock_flags);
2287 up(&dgnc_TmpWriteSem);
2288 } else {
2289 DGNC_UNLOCK(ch->ch_lock, lock_flags);
2290 }
2291
2292 DPR_WRITE(("Write finished - Write %d bytes of %d.\n", count, orig_count));
2293
2294 if (count) {
2295 /*
2296 * Channel lock is grabbed and then released
2297 * inside this routine.
2298 */
2299 ch->ch_bd->bd_ops->copy_data_from_queue_to_uart(ch);
2300 }
2301
2302 return (count);
2303}
2304
2305
2306/*
2307 * Return modem signals to ld.
2308 */
2309#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
2310static int dgnc_tty_tiocmget(struct tty_struct *tty)
2311#else
2312static int dgnc_tty_tiocmget(struct tty_struct *tty, struct file *file)
2313#endif
2314{
2315 struct channel_t *ch;
2316 struct un_t *un;
2317 int result = -EIO;
2318 uchar mstat = 0;
2319 ulong lock_flags;
2320
2321 if (!tty || tty->magic != TTY_MAGIC)
2322 return result;
2323
2324 un = tty->driver_data;
2325 if (!un || un->magic != DGNC_UNIT_MAGIC)
2326 return result;
2327
2328 ch = un->un_ch;
2329 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
2330 return result;
2331
2332 DPR_IOCTL(("dgnc_tty_tiocmget start\n"));
2333
2334 DGNC_LOCK(ch->ch_lock, lock_flags);
2335
2336 mstat = (ch->ch_mostat | ch->ch_mistat);
2337
2338 DGNC_UNLOCK(ch->ch_lock, lock_flags);
2339
2340 result = 0;
2341
2342 if (mstat & UART_MCR_DTR)
2343 result |= TIOCM_DTR;
2344 if (mstat & UART_MCR_RTS)
2345 result |= TIOCM_RTS;
2346 if (mstat & UART_MSR_CTS)
2347 result |= TIOCM_CTS;
2348 if (mstat & UART_MSR_DSR)
2349 result |= TIOCM_DSR;
2350 if (mstat & UART_MSR_RI)
2351 result |= TIOCM_RI;
2352 if (mstat & UART_MSR_DCD)
2353 result |= TIOCM_CD;
2354
2355 DPR_IOCTL(("dgnc_tty_tiocmget finish\n"));
2356
2357 return result;
2358}
2359
2360
2361/*
2362 * dgnc_tty_tiocmset()
2363 *
2364 * Set modem signals, called by ld.
2365 */
2366#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
2367static int dgnc_tty_tiocmset(struct tty_struct *tty,
2368 unsigned int set, unsigned int clear)
2369#else
2370static int dgnc_tty_tiocmset(struct tty_struct *tty, struct file *file,
2371 unsigned int set, unsigned int clear)
2372#endif
2373{
2374 struct board_t *bd;
2375 struct channel_t *ch;
2376 struct un_t *un;
2377 int ret = -EIO;
2378 ulong lock_flags;
2379
2380 if (!tty || tty->magic != TTY_MAGIC)
2381 return ret;
2382
2383 un = tty->driver_data;
2384 if (!un || un->magic != DGNC_UNIT_MAGIC)
2385 return ret;
2386
2387 ch = un->un_ch;
2388 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
2389 return ret;
2390
2391 bd = ch->ch_bd;
2392 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
2393 return ret;
2394
2395 DPR_IOCTL(("dgnc_tty_tiocmset start\n"));
2396
2397
2398 DGNC_LOCK(ch->ch_lock, lock_flags);
2399
2400 if (set & TIOCM_RTS) {
2401 ch->ch_mostat |= UART_MCR_RTS;
2402 }
2403
2404 if (set & TIOCM_DTR) {
2405 ch->ch_mostat |= UART_MCR_DTR;
2406 }
2407
2408 if (clear & TIOCM_RTS) {
2409 ch->ch_mostat &= ~(UART_MCR_RTS);
2410 }
2411
2412 if (clear & TIOCM_DTR) {
2413 ch->ch_mostat &= ~(UART_MCR_DTR);
2414 }
2415
2416 ch->ch_bd->bd_ops->assert_modem_signals(ch);
2417
2418 DGNC_UNLOCK(ch->ch_lock, lock_flags);
2419
2420 DPR_IOCTL(("dgnc_tty_tiocmset finish\n"));
2421
2422 return (0);
2423}
2424
2425
2426/*
2427 * dgnc_tty_send_break()
2428 *
2429 * Send a Break, called by ld.
2430 */
2431static int dgnc_tty_send_break(struct tty_struct *tty, int msec)
2432{
2433 struct board_t *bd;
2434 struct channel_t *ch;
2435 struct un_t *un;
2436 int ret = -EIO;
2437 ulong lock_flags;
2438
2439 if (!tty || tty->magic != TTY_MAGIC)
2440 return ret;
2441
2442 un = tty->driver_data;
2443 if (!un || un->magic != DGNC_UNIT_MAGIC)
2444 return ret;
2445
2446 ch = un->un_ch;
2447 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
2448 return ret;
2449
2450 bd = ch->ch_bd;
2451 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
2452 return ret;
2453
2454 switch (msec) {
2455 case -1:
2456 msec = 0xFFFF;
2457 break;
2458 case 0:
2459 msec = 0;
2460 break;
2461 default:
2462 break;
2463 }
2464
2465 DPR_IOCTL(("dgnc_tty_send_break start 1. %lx\n", jiffies));
2466
2467 DGNC_LOCK(ch->ch_lock, lock_flags);
2468
2469 ch->ch_bd->bd_ops->send_break(ch, msec);
2470
2471 DGNC_UNLOCK(ch->ch_lock, lock_flags);
2472
2473 DPR_IOCTL(("dgnc_tty_send_break finish\n"));
2474
2475 return (0);
2476
2477}
2478
2479
2480/*
2481 * dgnc_tty_wait_until_sent()
2482 *
2483 * wait until data has been transmitted, called by ld.
2484 */
2485static void dgnc_tty_wait_until_sent(struct tty_struct *tty, int timeout)
2486{
2487 struct board_t *bd;
2488 struct channel_t *ch;
2489 struct un_t *un;
2490 int rc;
2491
2492 if (!tty || tty->magic != TTY_MAGIC)
2493 return;
2494
2495 un = tty->driver_data;
2496 if (!un || un->magic != DGNC_UNIT_MAGIC)
2497 return;
2498
2499 ch = un->un_ch;
2500 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
2501 return;
2502
2503 bd = ch->ch_bd;
2504 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
2505 return;
2506
2507 rc = bd->bd_ops->drain(tty, 0);
2508 if (rc) {
2509 DPR_IOCTL(("dgnc_tty_ioctl - bad return: %d ", rc));
2510 return;
2511 }
2512 return;
2513}
2514
2515
2516/*
2517 * dgnc_send_xchar()
2518 *
2519 * send a high priority character, called by ld.
2520 */
2521static void dgnc_tty_send_xchar(struct tty_struct *tty, char c)
2522{
2523 struct board_t *bd;
2524 struct channel_t *ch;
2525 struct un_t *un;
2526 ulong lock_flags;
2527
2528 if (!tty || tty->magic != TTY_MAGIC)
2529 return;
2530
2531 un = tty->driver_data;
2532 if (!un || un->magic != DGNC_UNIT_MAGIC)
2533 return;
2534
2535 ch = un->un_ch;
2536 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
2537 return;
2538
2539 bd = ch->ch_bd;
2540 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
2541 return;
2542
2543 DPR_IOCTL(("dgnc_tty_send_xchar start\n"));
2544 printk("dgnc_tty_send_xchar start\n");
2545
2546 DGNC_LOCK(ch->ch_lock, lock_flags);
2547 bd->bd_ops->send_immediate_char(ch, c);
2548 DGNC_UNLOCK(ch->ch_lock, lock_flags);
2549
2550 DPR_IOCTL(("dgnc_tty_send_xchar finish\n"));
2551 printk("dgnc_tty_send_xchar finish\n");
2552 return;
2553}
2554
2555
2556
2557
2558/*
2559 * Return modem signals to ld.
2560 */
2561static inline int dgnc_get_mstat(struct channel_t *ch)
2562{
2563 unsigned char mstat;
2564 int result = -EIO;
2565 ulong lock_flags;
2566
2567 DPR_IOCTL(("dgnc_getmstat start\n"));
2568
2569 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
2570 return(-ENXIO);
2571
2572 DGNC_LOCK(ch->ch_lock, lock_flags);
2573
2574 mstat = (ch->ch_mostat | ch->ch_mistat);
2575
2576 DGNC_UNLOCK(ch->ch_lock, lock_flags);
2577
2578 result = 0;
2579
2580 if (mstat & UART_MCR_DTR)
2581 result |= TIOCM_DTR;
2582 if (mstat & UART_MCR_RTS)
2583 result |= TIOCM_RTS;
2584 if (mstat & UART_MSR_CTS)
2585 result |= TIOCM_CTS;
2586 if (mstat & UART_MSR_DSR)
2587 result |= TIOCM_DSR;
2588 if (mstat & UART_MSR_RI)
2589 result |= TIOCM_RI;
2590 if (mstat & UART_MSR_DCD)
2591 result |= TIOCM_CD;
2592
2593 DPR_IOCTL(("dgnc_getmstat finish\n"));
2594
2595 return(result);
2596}
2597
2598
2599
2600/*
2601 * Return modem signals to ld.
2602 */
2603static int dgnc_get_modem_info(struct channel_t *ch, unsigned int __user *value)
2604{
2605 int result;
2606 int rc;
2607
2608 DPR_IOCTL(("dgnc_get_modem_info start\n"));
2609
2610 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
2611 return(-ENXIO);
2612
2613 result = dgnc_get_mstat(ch);
2614
2615 if (result < 0)
2616 return (-ENXIO);
2617
2618 rc = put_user(result, value);
2619
2620 DPR_IOCTL(("dgnc_get_modem_info finish\n"));
2621 return(rc);
2622}
2623
2624
2625/*
2626 * dgnc_set_modem_info()
2627 *
2628 * Set modem signals, called by ld.
2629 */
2630static int dgnc_set_modem_info(struct tty_struct *tty, unsigned int command, unsigned int __user *value)
2631{
2632 struct board_t *bd;
2633 struct channel_t *ch;
2634 struct un_t *un;
2635 int ret = -ENXIO;
2636 unsigned int arg = 0;
2637 ulong lock_flags;
2638
2639 if (!tty || tty->magic != TTY_MAGIC)
2640 return ret;
2641
2642 un = tty->driver_data;
2643 if (!un || un->magic != DGNC_UNIT_MAGIC)
2644 return ret;
2645
2646 ch = un->un_ch;
2647 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
2648 return ret;
2649
2650 bd = ch->ch_bd;
2651 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
2652 return ret;
2653
2654 ret = 0;
2655
2656 DPR_IOCTL(("dgnc_set_modem_info() start\n"));
2657
2658 ret = get_user(arg, value);
2659 if (ret)
2660 return(ret);
2661
2662 switch (command) {
2663 case TIOCMBIS:
2664 if (arg & TIOCM_RTS) {
2665 ch->ch_mostat |= UART_MCR_RTS;
2666 }
2667
2668 if (arg & TIOCM_DTR) {
2669 ch->ch_mostat |= UART_MCR_DTR;
2670 }
2671
2672 break;
2673
2674 case TIOCMBIC:
2675 if (arg & TIOCM_RTS) {
2676 ch->ch_mostat &= ~(UART_MCR_RTS);
2677 }
2678
2679 if (arg & TIOCM_DTR) {
2680 ch->ch_mostat &= ~(UART_MCR_DTR);
2681 }
2682
2683 break;
2684
2685 case TIOCMSET:
2686
2687 if (arg & TIOCM_RTS) {
2688 ch->ch_mostat |= UART_MCR_RTS;
2689 }
2690 else {
2691 ch->ch_mostat &= ~(UART_MCR_RTS);
2692 }
2693
2694 if (arg & TIOCM_DTR) {
2695 ch->ch_mostat |= UART_MCR_DTR;
2696 }
2697 else {
2698 ch->ch_mostat &= ~(UART_MCR_DTR);
2699 }
2700
2701 break;
2702
2703 default:
2704 return(-EINVAL);
2705 }
2706
2707 DGNC_LOCK(ch->ch_lock, lock_flags);
2708
2709 ch->ch_bd->bd_ops->assert_modem_signals(ch);
2710
2711 DGNC_UNLOCK(ch->ch_lock, lock_flags);
2712
2713 DPR_IOCTL(("dgnc_set_modem_info finish\n"));
2714
2715 return (0);
2716}
2717
2718
2719/*
2720 * dgnc_tty_digigeta()
2721 *
2722 * Ioctl to get the information for ditty.
2723 *
2724 *
2725 *
2726 */
2727static int dgnc_tty_digigeta(struct tty_struct *tty, struct digi_t __user *retinfo)
2728{
2729 struct channel_t *ch;
2730 struct un_t *un;
2731 struct digi_t tmp;
2732 ulong lock_flags;
2733
2734 if (!retinfo)
2735 return (-EFAULT);
2736
2737 if (!tty || tty->magic != TTY_MAGIC)
2738 return (-EFAULT);
2739
2740 un = tty->driver_data;
2741 if (!un || un->magic != DGNC_UNIT_MAGIC)
2742 return (-EFAULT);
2743
2744 ch = un->un_ch;
2745 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
2746 return (-EFAULT);
2747
2748 memset(&tmp, 0, sizeof(tmp));
2749
2750 DGNC_LOCK(ch->ch_lock, lock_flags);
2751 memcpy(&tmp, &ch->ch_digi, sizeof(tmp));
2752 DGNC_UNLOCK(ch->ch_lock, lock_flags);
2753
2754 if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
2755 return (-EFAULT);
2756
2757 return (0);
2758}
2759
2760
2761/*
2762 * dgnc_tty_digiseta()
2763 *
2764 * Ioctl to set the information for ditty.
2765 *
2766 *
2767 *
2768 */
2769static int dgnc_tty_digiseta(struct tty_struct *tty, struct digi_t __user *new_info)
2770{
2771 struct board_t *bd;
2772 struct channel_t *ch;
2773 struct un_t *un;
2774 struct digi_t new_digi;
2775 ulong lock_flags;
2776
2777 DPR_IOCTL(("DIGI_SETA start\n"));
2778
2779 if (!tty || tty->magic != TTY_MAGIC)
2780 return (-EFAULT);
2781
2782 un = tty->driver_data;
2783 if (!un || un->magic != DGNC_UNIT_MAGIC)
2784 return (-EFAULT);
2785
2786 ch = un->un_ch;
2787 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
2788 return (-EFAULT);
2789
2790 bd = ch->ch_bd;
2791 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
2792 return (-EFAULT);
2793
2794 if (copy_from_user(&new_digi, new_info, sizeof(struct digi_t))) {
2795 DPR_IOCTL(("DIGI_SETA failed copy_from_user\n"));
2796 return(-EFAULT);
2797 }
2798
2799 DGNC_LOCK(ch->ch_lock, lock_flags);
2800
2801 /*
2802 * Handle transistions to and from RTS Toggle.
2803 */
2804 if (!(ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE) && (new_digi.digi_flags & DIGI_RTS_TOGGLE))
2805 ch->ch_mostat &= ~(UART_MCR_RTS);
2806 if ((ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE) && !(new_digi.digi_flags & DIGI_RTS_TOGGLE))
2807 ch->ch_mostat |= (UART_MCR_RTS);
2808
2809 /*
2810 * Handle transistions to and from DTR Toggle.
2811 */
2812 if (!(ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE) && (new_digi.digi_flags & DIGI_DTR_TOGGLE))
2813 ch->ch_mostat &= ~(UART_MCR_DTR);
2814 if ((ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE) && !(new_digi.digi_flags & DIGI_DTR_TOGGLE))
2815 ch->ch_mostat |= (UART_MCR_DTR);
2816
2817 memcpy(&ch->ch_digi, &new_digi, sizeof(struct digi_t));
2818
2819 if (ch->ch_digi.digi_maxcps < 1)
2820 ch->ch_digi.digi_maxcps = 1;
2821
2822 if (ch->ch_digi.digi_maxcps > 10000)
2823 ch->ch_digi.digi_maxcps = 10000;
2824
2825 if (ch->ch_digi.digi_bufsize < 10)
2826 ch->ch_digi.digi_bufsize = 10;
2827
2828 if (ch->ch_digi.digi_maxchar < 1)
2829 ch->ch_digi.digi_maxchar = 1;
2830
2831 if (ch->ch_digi.digi_maxchar > ch->ch_digi.digi_bufsize)
2832 ch->ch_digi.digi_maxchar = ch->ch_digi.digi_bufsize;
2833
2834 if (ch->ch_digi.digi_onlen > DIGI_PLEN)
2835 ch->ch_digi.digi_onlen = DIGI_PLEN;
2836
2837 if (ch->ch_digi.digi_offlen > DIGI_PLEN)
2838 ch->ch_digi.digi_offlen = DIGI_PLEN;
2839
2840 ch->ch_bd->bd_ops->param(tty);
2841
2842 DGNC_UNLOCK(ch->ch_lock, lock_flags);
2843
2844 DPR_IOCTL(("DIGI_SETA finish\n"));
2845
2846 return(0);
2847}
2848
2849
2850/*
2851 * dgnc_set_termios()
2852 */
2853static void dgnc_tty_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
2854{
2855 struct board_t *bd;
2856 struct channel_t *ch;
2857 struct un_t *un;
2858 unsigned long lock_flags;
2859
2860 if (!tty || tty->magic != TTY_MAGIC)
2861 return;
2862
2863 un = tty->driver_data;
2864 if (!un || un->magic != DGNC_UNIT_MAGIC)
2865 return;
2866
2867 ch = un->un_ch;
2868 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
2869 return;
2870
2871 bd = ch->ch_bd;
2872 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
2873 return;
2874
2875 DGNC_LOCK(ch->ch_lock, lock_flags);
2876
2877 ch->ch_c_cflag = tty->termios->c_cflag;
2878 ch->ch_c_iflag = tty->termios->c_iflag;
2879 ch->ch_c_oflag = tty->termios->c_oflag;
2880 ch->ch_c_lflag = tty->termios->c_lflag;
2881 ch->ch_startc = tty->termios->c_cc[VSTART];
2882 ch->ch_stopc = tty->termios->c_cc[VSTOP];
2883
2884 ch->ch_bd->bd_ops->param(tty);
2885 dgnc_carrier(ch);
2886
2887 DGNC_UNLOCK(ch->ch_lock, lock_flags);
2888}
2889
2890
2891static void dgnc_tty_throttle(struct tty_struct *tty)
2892{
2893 struct channel_t *ch;
2894 struct un_t *un;
2895 ulong lock_flags = 0;
2896
2897 if (!tty || tty->magic != TTY_MAGIC)
2898 return;
2899
2900 un = tty->driver_data;
2901 if (!un || un->magic != DGNC_UNIT_MAGIC)
2902 return;
2903
2904 ch = un->un_ch;
2905 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
2906 return;
2907
2908 DPR_IOCTL(("dgnc_tty_throttle start\n"));
2909
2910 DGNC_LOCK(ch->ch_lock, lock_flags);
2911
2912 ch->ch_flags |= (CH_FORCED_STOPI);
2913
2914 DGNC_UNLOCK(ch->ch_lock, lock_flags);
2915
2916 DPR_IOCTL(("dgnc_tty_throttle finish\n"));
2917}
2918
2919
2920static void dgnc_tty_unthrottle(struct tty_struct *tty)
2921{
2922 struct channel_t *ch;
2923 struct un_t *un;
2924 ulong lock_flags;
2925
2926 if (!tty || tty->magic != TTY_MAGIC)
2927 return;
2928
2929 un = tty->driver_data;
2930 if (!un || un->magic != DGNC_UNIT_MAGIC)
2931 return;
2932
2933 ch = un->un_ch;
2934 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
2935 return;
2936
2937 DPR_IOCTL(("dgnc_tty_unthrottle start\n"));
2938
2939 DGNC_LOCK(ch->ch_lock, lock_flags);
2940
2941 ch->ch_flags &= ~(CH_FORCED_STOPI);
2942
2943 DGNC_UNLOCK(ch->ch_lock, lock_flags);
2944
2945 DPR_IOCTL(("dgnc_tty_unthrottle finish\n"));
2946}
2947
2948
2949static void dgnc_tty_start(struct tty_struct *tty)
2950{
2951 struct board_t *bd;
2952 struct channel_t *ch;
2953 struct un_t *un;
2954 ulong lock_flags;
2955
2956 if (!tty || tty->magic != TTY_MAGIC)
2957 return;
2958
2959 un = tty->driver_data;
2960 if (!un || un->magic != DGNC_UNIT_MAGIC)
2961 return;
2962
2963 ch = un->un_ch;
2964 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
2965 return;
2966
2967 bd = ch->ch_bd;
2968 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
2969 return;
2970
2971 DPR_IOCTL(("dgcn_tty_start start\n"));
2972
2973 DGNC_LOCK(ch->ch_lock, lock_flags);
2974
2975 ch->ch_flags &= ~(CH_FORCED_STOP);
2976
2977 DGNC_UNLOCK(ch->ch_lock, lock_flags);
2978
2979 DPR_IOCTL(("dgnc_tty_start finish\n"));
2980}
2981
2982
2983static void dgnc_tty_stop(struct tty_struct *tty)
2984{
2985 struct board_t *bd;
2986 struct channel_t *ch;
2987 struct un_t *un;
2988 ulong lock_flags;
2989
2990 if (!tty || tty->magic != TTY_MAGIC)
2991 return;
2992
2993 un = tty->driver_data;
2994 if (!un || un->magic != DGNC_UNIT_MAGIC)
2995 return;
2996
2997 ch = un->un_ch;
2998 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
2999 return;
3000
3001 bd = ch->ch_bd;
3002 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
3003 return;
3004
3005 DPR_IOCTL(("dgnc_tty_stop start\n"));
3006
3007 DGNC_LOCK(ch->ch_lock, lock_flags);
3008
3009 ch->ch_flags |= (CH_FORCED_STOP);
3010
3011 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3012
3013 DPR_IOCTL(("dgnc_tty_stop finish\n"));
3014}
3015
3016
3017/*
3018 * dgnc_tty_flush_chars()
3019 *
3020 * Flush the cook buffer
3021 *
3022 * Note to self, and any other poor souls who venture here:
3023 *
3024 * flush in this case DOES NOT mean dispose of the data.
3025 * instead, it means "stop buffering and send it if you
3026 * haven't already." Just guess how I figured that out... SRW 2-Jun-98
3027 *
3028 * It is also always called in interrupt context - JAR 8-Sept-99
3029 */
3030static void dgnc_tty_flush_chars(struct tty_struct *tty)
3031{
3032 struct board_t *bd;
3033 struct channel_t *ch;
3034 struct un_t *un;
3035 ulong lock_flags;
3036
3037 if (!tty || tty->magic != TTY_MAGIC)
3038 return;
3039
3040 un = tty->driver_data;
3041 if (!un || un->magic != DGNC_UNIT_MAGIC)
3042 return;
3043
3044 ch = un->un_ch;
3045 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
3046 return;
3047
3048 bd = ch->ch_bd;
3049 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
3050 return;
3051
3052 DPR_IOCTL(("dgnc_tty_flush_chars start\n"));
3053
3054 DGNC_LOCK(ch->ch_lock, lock_flags);
3055
3056 /* Do something maybe here */
3057
3058 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3059
3060 DPR_IOCTL(("dgnc_tty_flush_chars finish\n"));
3061}
3062
3063
3064
3065/*
3066 * dgnc_tty_flush_buffer()
3067 *
3068 * Flush Tx buffer (make in == out)
3069 */
3070static void dgnc_tty_flush_buffer(struct tty_struct *tty)
3071{
3072 struct channel_t *ch;
3073 struct un_t *un;
3074 ulong lock_flags;
3075
3076 if (!tty || tty->magic != TTY_MAGIC)
3077 return;
3078
3079 un = tty->driver_data;
3080 if (!un || un->magic != DGNC_UNIT_MAGIC)
3081 return;
3082
3083 ch = un->un_ch;
3084 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
3085 return;
3086
3087 DPR_IOCTL(("dgnc_tty_flush_buffer on port: %d start\n", ch->ch_portnum));
3088
3089 DGNC_LOCK(ch->ch_lock, lock_flags);
3090
3091 ch->ch_flags &= ~CH_STOP;
3092
3093 /* Flush our write queue */
3094 ch->ch_w_head = ch->ch_w_tail;
3095
3096 /* Flush UARTs transmit FIFO */
3097 ch->ch_bd->bd_ops->flush_uart_write(ch);
3098
3099 if (ch->ch_tun.un_flags & (UN_LOW|UN_EMPTY)) {
3100 ch->ch_tun.un_flags &= ~(UN_LOW|UN_EMPTY);
3101 wake_up_interruptible(&ch->ch_tun.un_flags_wait);
3102 }
3103 if (ch->ch_pun.un_flags & (UN_LOW|UN_EMPTY)) {
3104 ch->ch_pun.un_flags &= ~(UN_LOW|UN_EMPTY);
3105 wake_up_interruptible(&ch->ch_pun.un_flags_wait);
3106 }
3107
3108 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3109
3110 DPR_IOCTL(("dgnc_tty_flush_buffer finish\n"));
3111}
3112
3113
3114
3115/*****************************************************************************
3116 *
3117 * The IOCTL function and all of its helpers
3118 *
3119 *****************************************************************************/
3120
3121/*
3122 * dgnc_tty_ioctl()
3123 *
3124 * The usual assortment of ioctl's
3125 */
3126static int dgnc_tty_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd,
3127 unsigned long arg)
3128{
3129 struct board_t *bd;
3130 struct channel_t *ch;
3131 struct un_t *un;
3132 int rc;
3133 ulong lock_flags;
3134 void __user *uarg = (void __user *) arg;
3135
3136 if (!tty || tty->magic != TTY_MAGIC)
3137 return (-ENODEV);
3138
3139 un = tty->driver_data;
3140 if (!un || un->magic != DGNC_UNIT_MAGIC)
3141 return (-ENODEV);
3142
3143 ch = un->un_ch;
3144 if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
3145 return (-ENODEV);
3146
3147 bd = ch->ch_bd;
3148 if (!bd || bd->magic != DGNC_BOARD_MAGIC)
3149 return (-ENODEV);
3150
3151 DPR_IOCTL(("dgnc_tty_ioctl start on port %d - cmd %s (%x), arg %lx\n",
3152 ch->ch_portnum, dgnc_ioctl_name(cmd), cmd, arg));
3153
3154 DGNC_LOCK(ch->ch_lock, lock_flags);
3155
3156 if (un->un_open_count <= 0) {
3157 DPR_BASIC(("dgnc_tty_ioctl - unit not open.\n"));
3158 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3159 return(-EIO);
3160 }
3161
3162 switch (cmd) {
3163
3164 /* Here are all the standard ioctl's that we MUST implement */
3165
3166 case TCSBRK:
3167 /*
3168 * TCSBRK is SVID version: non-zero arg --> no break
3169 * this behaviour is exploited by tcdrain().
3170 *
3171 * According to POSIX.1 spec (7.2.2.1.2) breaks should be
3172 * between 0.25 and 0.5 seconds so we'll ask for something
3173 * in the middle: 0.375 seconds.
3174 */
3175 rc = tty_check_change(tty);
3176 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3177 if (rc) {
3178 return(rc);
3179 }
3180
3181 rc = ch->ch_bd->bd_ops->drain(tty, 0);
3182
3183 if (rc) {
3184 DPR_IOCTL(("dgnc_tty_ioctl - bad return: %d ", rc));
3185 return(-EINTR);
3186 }
3187
3188 DGNC_LOCK(ch->ch_lock, lock_flags);
3189
3190 if(((cmd == TCSBRK) && (!arg)) || (cmd == TCSBRKP)) {
3191 ch->ch_bd->bd_ops->send_break(ch, 250);
3192 }
3193
3194 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3195
3196 DPR_IOCTL(("dgnc_tty_ioctl finish on port %d - cmd %s (%x), arg %lx\n",
3197 ch->ch_portnum, dgnc_ioctl_name(cmd), cmd, arg));
3198
3199 return(0);
3200
3201
3202 case TCSBRKP:
3203 /* support for POSIX tcsendbreak()
3204 * According to POSIX.1 spec (7.2.2.1.2) breaks should be
3205 * between 0.25 and 0.5 seconds so we'll ask for something
3206 * in the middle: 0.375 seconds.
3207 */
3208 rc = tty_check_change(tty);
3209 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3210 if (rc) {
3211 return(rc);
3212 }
3213
3214 rc = ch->ch_bd->bd_ops->drain(tty, 0);
3215 if (rc) {
3216 DPR_IOCTL(("dgnc_tty_ioctl - bad return: %d ", rc));
3217 return(-EINTR);
3218 }
3219
3220 DGNC_LOCK(ch->ch_lock, lock_flags);
3221
3222 ch->ch_bd->bd_ops->send_break(ch, 250);
3223
3224 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3225
3226 DPR_IOCTL(("dgnc_tty_ioctl finish on port %d - cmd %s (%x), arg %lx\n",
3227 ch->ch_portnum, dgnc_ioctl_name(cmd), cmd, arg));
3228
3229 return(0);
3230
3231 case TIOCSBRK:
3232 rc = tty_check_change(tty);
3233 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3234 if (rc) {
3235 return(rc);
3236 }
3237
3238 rc = ch->ch_bd->bd_ops->drain(tty, 0);
3239 if (rc) {
3240 DPR_IOCTL(("dgnc_tty_ioctl - bad return: %d ", rc));
3241 return(-EINTR);
3242 }
3243
3244 DGNC_LOCK(ch->ch_lock, lock_flags);
3245
3246 ch->ch_bd->bd_ops->send_break(ch, 250);
3247
3248 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3249
3250 DPR_IOCTL(("dgnc_tty_ioctl finish on port %d - cmd %s (%x), arg %lx\n",
3251 ch->ch_portnum, dgnc_ioctl_name(cmd), cmd, arg));
3252
3253 return(0);
3254
3255 case TIOCCBRK:
3256 /* Do Nothing */
3257 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3258 return 0;
3259
3260 case TIOCGSOFTCAR:
3261
3262 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3263
3264 rc = put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *) arg);
3265 return(rc);
3266
3267 case TIOCSSOFTCAR:
3268
3269 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3270 rc = get_user(arg, (unsigned long __user *) arg);
3271 if (rc)
3272 return(rc);
3273
3274 DGNC_LOCK(ch->ch_lock, lock_flags);
3275 tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) | (arg ? CLOCAL : 0));
3276 ch->ch_bd->bd_ops->param(tty);
3277 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3278
3279 return(0);
3280
3281 case TIOCMGET:
3282 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3283 return(dgnc_get_modem_info(ch, uarg));
3284
3285 case TIOCMBIS:
3286 case TIOCMBIC:
3287 case TIOCMSET:
3288 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3289 return(dgnc_set_modem_info(tty, cmd, uarg));
3290
3291 /*
3292 * Here are any additional ioctl's that we want to implement
3293 */
3294
3295 case TCFLSH:
3296 /*
3297 * The linux tty driver doesn't have a flush
3298 * input routine for the driver, assuming all backed
3299 * up data is in the line disc. buffers. However,
3300 * we all know that's not the case. Here, we
3301 * act on the ioctl, but then lie and say we didn't
3302 * so the line discipline will process the flush
3303 * also.
3304 */
3305 rc = tty_check_change(tty);
3306 if (rc) {
3307 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3308 return(rc);
3309 }
3310
3311 if ((arg == TCIFLUSH) || (arg == TCIOFLUSH)) {
3312 ch->ch_r_head = ch->ch_r_tail;
3313 ch->ch_bd->bd_ops->flush_uart_read(ch);
3314 /* Force queue flow control to be released, if needed */
3315 dgnc_check_queue_flow_control(ch);
3316 }
3317
3318 if ((arg == TCOFLUSH) || (arg == TCIOFLUSH)) {
3319 if (!(un->un_type == DGNC_PRINT)) {
3320 ch->ch_w_head = ch->ch_w_tail;
3321 ch->ch_bd->bd_ops->flush_uart_write(ch);
3322
3323 if (ch->ch_tun.un_flags & (UN_LOW|UN_EMPTY)) {
3324 ch->ch_tun.un_flags &= ~(UN_LOW|UN_EMPTY);
3325 wake_up_interruptible(&ch->ch_tun.un_flags_wait);
3326 }
3327
3328 if (ch->ch_pun.un_flags & (UN_LOW|UN_EMPTY)) {
3329 ch->ch_pun.un_flags &= ~(UN_LOW|UN_EMPTY);
3330 wake_up_interruptible(&ch->ch_pun.un_flags_wait);
3331 }
3332
3333 }
3334 }
3335
3336 /* pretend we didn't recognize this IOCTL */
3337 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3338 return(-ENOIOCTLCMD);
3339
3340#ifdef TIOCGETP
3341 case TIOCGETP:
3342#endif
3343 case TCGETS:
3344 case TCGETA:
3345#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)
3346 if (tty->ldisc->ops->ioctl) {
3347#else
3348 if (tty->ldisc.ops->ioctl) {
3349#endif
3350 int retval = (-ENXIO);
3351
3352 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3353
3354 if (tty->termios) {
3355#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)
3356 retval = ((tty->ldisc->ops->ioctl) (tty, file, cmd, arg));
3357#else
3358 retval = ((tty->ldisc.ops->ioctl) (tty, file, cmd, arg));
3359#endif
3360 }
3361
3362 DPR_IOCTL(("dgnc_tty_ioctl (LINE:%d) finish on port %d - cmd %s (%x), arg %lx\n",
3363 __LINE__, ch->ch_portnum, dgnc_ioctl_name(cmd), cmd, arg));
3364 return(retval);
3365 }
3366
3367 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3368 DPR_IOCTL(("dgnc_tty_ioctl (LINE:%d) finish on port %d - cmd %s (%x), arg %lx\n",
3369 __LINE__, ch->ch_portnum, dgnc_ioctl_name(cmd), cmd, arg));
3370
3371 return(-ENOIOCTLCMD);
3372
3373 case TCSETSF:
3374 case TCSETSW:
3375 /*
3376 * The linux tty driver doesn't have a flush
3377 * input routine for the driver, assuming all backed
3378 * up data is in the line disc. buffers. However,
3379 * we all know that's not the case. Here, we
3380 * act on the ioctl, but then lie and say we didn't
3381 * so the line discipline will process the flush
3382 * also.
3383 */
3384 if (cmd == TCSETSF) {
3385 /* flush rx */
3386 ch->ch_flags &= ~CH_STOP;
3387 ch->ch_r_head = ch->ch_r_tail;
3388 ch->ch_bd->bd_ops->flush_uart_read(ch);
3389 /* Force queue flow control to be released, if needed */
3390 dgnc_check_queue_flow_control(ch);
3391 }
3392
3393 /* now wait for all the output to drain */
3394 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3395 rc = ch->ch_bd->bd_ops->drain(tty, 0);
3396 if (rc) {
3397 DPR_IOCTL(("dgnc_tty_ioctl - bad return: %d\n", rc));
3398 return(-EINTR);
3399 }
3400
3401 DPR_IOCTL(("dgnc_tty_ioctl finish on port %d - cmd %s (%x), arg %lx\n",
3402 ch->ch_portnum, dgnc_ioctl_name(cmd), cmd, arg));
3403
3404 /* pretend we didn't recognize this */
3405 return(-ENOIOCTLCMD);
3406
3407 case TCSETAW:
3408
3409 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3410 rc = ch->ch_bd->bd_ops->drain(tty, 0);
3411 if (rc) {
3412 DPR_IOCTL(("dgnc_tty_ioctl - bad return: %d ", rc));
3413 return(-EINTR);
3414 }
3415
3416 /* pretend we didn't recognize this */
3417 return(-ENOIOCTLCMD);
3418
3419 case TCXONC:
3420 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3421 /* Make the ld do it */
3422 return(-ENOIOCTLCMD);
3423
3424 case DIGI_GETA:
3425 /* get information for ditty */
3426 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3427 return(dgnc_tty_digigeta(tty, uarg));
3428
3429 case DIGI_SETAW:
3430 case DIGI_SETAF:
3431
3432 /* set information for ditty */
3433 if (cmd == (DIGI_SETAW)) {
3434
3435 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3436 rc = ch->ch_bd->bd_ops->drain(tty, 0);
3437 if (rc) {
3438 DPR_IOCTL(("dgnc_tty_ioctl - bad return: %d ", rc));
3439 return(-EINTR);
3440 }
3441 DGNC_LOCK(ch->ch_lock, lock_flags);
3442 }
3443 else {
3444 tty_ldisc_flush(tty);
3445 }
3446 /* fall thru */
3447
3448 case DIGI_SETA:
3449 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3450 return(dgnc_tty_digiseta(tty, uarg));
3451
3452 case DIGI_LOOPBACK:
3453 {
3454 uint loopback = 0;
3455 /* Let go of locks when accessing user space, could sleep */
3456 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3457 rc = get_user(loopback, (unsigned int __user *) arg);
3458 if (rc)
3459 return(rc);
3460 DGNC_LOCK(ch->ch_lock, lock_flags);
3461
3462 /* Enable/disable internal loopback for this port */
3463 if (loopback)
3464 ch->ch_flags |= CH_LOOPBACK;
3465 else
3466 ch->ch_flags &= ~(CH_LOOPBACK);
3467
3468 ch->ch_bd->bd_ops->param(tty);
3469 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3470 return(0);
3471 }
3472
3473 case DIGI_GETCUSTOMBAUD:
3474 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3475 rc = put_user(ch->ch_custom_speed, (unsigned int __user *) arg);
3476 return(rc);
3477
3478 case DIGI_SETCUSTOMBAUD:
3479 {
3480 uint new_rate;
3481 /* Let go of locks when accessing user space, could sleep */
3482 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3483 rc = get_user(new_rate, (unsigned int __user *) arg);
3484 if (rc)
3485 return(rc);
3486 DGNC_LOCK(ch->ch_lock, lock_flags);
3487 dgnc_set_custom_speed(ch, new_rate);
3488 ch->ch_bd->bd_ops->param(tty);
3489 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3490 return(0);
3491 }
3492
3493 /*
3494 * This ioctl allows insertion of a character into the front
3495 * of any pending data to be transmitted.
3496 *
3497 * This ioctl is to satify the "Send Character Immediate"
3498 * call that the RealPort protocol spec requires.
3499 */
3500 case DIGI_REALPORT_SENDIMMEDIATE:
3501 {
3502 unsigned char c;
3503 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3504 rc = get_user(c, (unsigned char __user *) arg);
3505 if (rc)
3506 return(rc);
3507 DGNC_LOCK(ch->ch_lock, lock_flags);
3508 ch->ch_bd->bd_ops->send_immediate_char(ch, c);
3509 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3510 return(0);
3511 }
3512
3513 /*
3514 * This ioctl returns all the current counts for the port.
3515 *
3516 * This ioctl is to satify the "Line Error Counters"
3517 * call that the RealPort protocol spec requires.
3518 */
3519 case DIGI_REALPORT_GETCOUNTERS:
3520 {
3521 struct digi_getcounter buf;
3522
3523 buf.norun = ch->ch_err_overrun;
3524 buf.noflow = 0; /* The driver doesn't keep this stat */
3525 buf.nframe = ch->ch_err_frame;
3526 buf.nparity = ch->ch_err_parity;
3527 buf.nbreak = ch->ch_err_break;
3528 buf.rbytes = ch->ch_rxcount;
3529 buf.tbytes = ch->ch_txcount;
3530
3531 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3532
3533 if (copy_to_user(uarg, &buf, sizeof(struct digi_getcounter))) {
3534 return (-EFAULT);
3535 }
3536 return(0);
3537 }
3538
3539 /*
3540 * This ioctl returns all current events.
3541 *
3542 * This ioctl is to satify the "Event Reporting"
3543 * call that the RealPort protocol spec requires.
3544 */
3545 case DIGI_REALPORT_GETEVENTS:
3546 {
3547 unsigned int events = 0;
3548
3549 /* NOTE: MORE EVENTS NEEDS TO BE ADDED HERE */
3550 if (ch->ch_flags & CH_BREAK_SENDING)
3551 events |= EV_TXB;
3552 if ((ch->ch_flags & CH_STOP) || (ch->ch_flags & CH_FORCED_STOP)) {
3553 events |= (EV_OPU | EV_OPS);
3554 }
3555 if ((ch->ch_flags & CH_STOPI) || (ch->ch_flags & CH_FORCED_STOPI)) {
3556 events |= (EV_IPU | EV_IPS);
3557 }
3558
3559 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3560 rc = put_user(events, (unsigned int __user *) arg);
3561 return(rc);
3562 }
3563
3564 /*
3565 * This ioctl returns TOUT and TIN counters based
3566 * upon the values passed in by the RealPort Server.
3567 * It also passes back whether the UART Transmitter is
3568 * empty as well.
3569 */
3570 case DIGI_REALPORT_GETBUFFERS:
3571 {
3572 struct digi_getbuffer buf;
3573 int tdist;
3574 int count;
3575
3576 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3577
3578 /*
3579 * Get data from user first.
3580 */
3581 if (copy_from_user(&buf, uarg, sizeof(struct digi_getbuffer))) {
3582 return (-EFAULT);
3583 }
3584
3585 DGNC_LOCK(ch->ch_lock, lock_flags);
3586
3587 /*
3588 * Figure out how much data is in our RX and TX queues.
3589 */
3590 buf.rxbuf = (ch->ch_r_head - ch->ch_r_tail) & RQUEUEMASK;
3591 buf.txbuf = (ch->ch_w_head - ch->ch_w_tail) & WQUEUEMASK;
3592
3593 /*
3594 * Is the UART empty? Add that value to whats in our TX queue.
3595 */
3596 count = buf.txbuf + ch->ch_bd->bd_ops->get_uart_bytes_left(ch);
3597
3598 /*
3599 * Figure out how much data the RealPort Server believes should
3600 * be in our TX queue.
3601 */
3602 tdist = (buf.tIn - buf.tOut) & 0xffff;
3603
3604 /*
3605 * If we have more data than the RealPort Server believes we
3606 * should have, reduce our count to its amount.
3607 *
3608 * This count difference CAN happen because the Linux LD can
3609 * insert more characters into our queue for OPOST processing
3610 * that the RealPort Server doesn't know about.
3611 */
3612 if (buf.txbuf > tdist) {
3613 buf.txbuf = tdist;
3614 }
3615
3616 /*
3617 * Report whether our queue and UART TX are completely empty.
3618 */
3619 if (count) {
3620 buf.txdone = 0;
3621 } else {
3622 buf.txdone = 1;
3623 }
3624
3625 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3626
3627 if (copy_to_user(uarg, &buf, sizeof(struct digi_getbuffer))) {
3628 return (-EFAULT);
3629 }
3630 return(0);
3631 }
3632 default:
3633 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3634
3635 DPR_IOCTL(("dgnc_tty_ioctl - in default\n"));
3636 DPR_IOCTL(("dgnc_tty_ioctl end - cmd %s (%x), arg %lx\n",
3637 dgnc_ioctl_name(cmd), cmd, arg));
3638
3639 return(-ENOIOCTLCMD);
3640 }
3641
3642 DGNC_UNLOCK(ch->ch_lock, lock_flags);
3643
3644 DPR_IOCTL(("dgnc_tty_ioctl end - cmd %s (%x), arg %lx\n",
3645 dgnc_ioctl_name(cmd), cmd, arg));
3646
3647 return(0);
3648}