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