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