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