PM: OMAP3: Removed a couple of unused variables from DVFS code
[linux-ginger.git] / drivers / char / ip2 / ip2main.c
blob517271c762e6b620b1323da302c5cd837985c626
1 /*
3 * (c) 1999 by Computone Corporation
5 ********************************************************************************
7 * PACKAGE: Linux tty Device Driver for IntelliPort family of multiport
8 * serial I/O controllers.
10 * DESCRIPTION: Mainline code for the device driver
12 *******************************************************************************/
13 // ToDo:
15 // Fix the immediate DSS_NOW problem.
16 // Work over the channel stats return logic in ip2_ipl_ioctl so they
17 // make sense for all 256 possible channels and so the user space
18 // utilities will compile and work properly.
20 // Done:
22 // 1.2.14 /\/\|=mhw=|\/\/
23 // Added bounds checking to ip2_ipl_ioctl to avoid potential terroristic acts.
24 // Changed the definition of ip2trace to be more consistent with kernel style
25 // Thanks to Andreas Dilger <adilger@turbolabs.com> for these updates
27 // 1.2.13 /\/\|=mhw=|\/\/
28 // DEVFS: Renamed ttf/{n} to tts/F{n} and cuf/{n} to cua/F{n} to conform
29 // to agreed devfs serial device naming convention.
31 // 1.2.12 /\/\|=mhw=|\/\/
32 // Cleaned up some remove queue cut and paste errors
34 // 1.2.11 /\/\|=mhw=|\/\/
35 // Clean up potential NULL pointer dereferences
36 // Clean up devfs registration
37 // Add kernel command line parsing for io and irq
38 // Compile defaults for io and irq are now set in ip2.c not ip2.h!
39 // Reworked poll_only hack for explicit parameter setting
40 // You must now EXPLICITLY set poll_only = 1 or set all irqs to 0
41 // Merged ip2_loadmain and old_ip2_init
42 // Converted all instances of interruptible_sleep_on into queue calls
43 // Most of these had no race conditions but better to clean up now
45 // 1.2.10 /\/\|=mhw=|\/\/
46 // Fixed the bottom half interrupt handler and enabled USE_IQI
47 // to split the interrupt handler into a formal top-half / bottom-half
48 // Fixed timing window on high speed processors that queued messages to
49 // the outbound mail fifo faster than the board could handle.
51 // 1.2.9
52 // Four box EX was barfing on >128k kmalloc, made structure smaller by
53 // reducing output buffer size
55 // 1.2.8
56 // Device file system support (MHW)
58 // 1.2.7
59 // Fixed
60 // Reload of ip2 without unloading ip2main hangs system on cat of /proc/modules
62 // 1.2.6
63 //Fixes DCD problems
64 // DCD was not reported when CLOCAL was set on call to TIOCMGET
66 //Enhancements:
67 // TIOCMGET requests and waits for status return
68 // No DSS interrupts enabled except for DCD when needed
70 // For internal use only
72 //#define IP2DEBUG_INIT
73 //#define IP2DEBUG_OPEN
74 //#define IP2DEBUG_WRITE
75 //#define IP2DEBUG_READ
76 //#define IP2DEBUG_IOCTL
77 //#define IP2DEBUG_IPL
79 //#define IP2DEBUG_TRACE
80 //#define DEBUG_FIFO
82 /************/
83 /* Includes */
84 /************/
86 #include <linux/ctype.h>
87 #include <linux/string.h>
88 #include <linux/fcntl.h>
89 #include <linux/errno.h>
90 #include <linux/module.h>
91 #include <linux/signal.h>
92 #include <linux/sched.h>
93 #include <linux/timer.h>
94 #include <linux/interrupt.h>
95 #include <linux/pci.h>
96 #include <linux/mm.h>
97 #include <linux/slab.h>
98 #include <linux/major.h>
99 #include <linux/wait.h>
100 #include <linux/device.h>
101 #include <linux/smp_lock.h>
102 #include <linux/firmware.h>
103 #include <linux/platform_device.h>
105 #include <linux/tty.h>
106 #include <linux/tty_flip.h>
107 #include <linux/termios.h>
108 #include <linux/tty_driver.h>
109 #include <linux/serial.h>
110 #include <linux/ptrace.h>
111 #include <linux/ioport.h>
113 #include <linux/cdk.h>
114 #include <linux/comstats.h>
115 #include <linux/delay.h>
116 #include <linux/bitops.h>
118 #include <asm/system.h>
119 #include <asm/io.h>
120 #include <asm/irq.h>
122 #include <linux/vmalloc.h>
123 #include <linux/init.h>
125 #include <asm/uaccess.h>
127 #include "ip2types.h"
128 #include "ip2trace.h"
129 #include "ip2ioctl.h"
130 #include "ip2.h"
131 #include "i2ellis.h"
132 #include "i2lib.h"
134 /*****************
135 * /proc/ip2mem *
136 *****************/
138 #include <linux/proc_fs.h>
139 #include <linux/seq_file.h>
141 static const struct file_operations ip2mem_proc_fops;
142 static const struct file_operations ip2_proc_fops;
144 /********************/
145 /* Type Definitions */
146 /********************/
148 /*************/
149 /* Constants */
150 /*************/
152 /* String constants to identify ourselves */
153 static const char pcName[] = "Computone IntelliPort Plus multiport driver";
154 static const char pcVersion[] = "1.2.14";
156 /* String constants for port names */
157 static const char pcDriver_name[] = "ip2";
158 static const char pcIpl[] = "ip2ipl";
160 /***********************/
161 /* Function Prototypes */
162 /***********************/
164 /* Global module entry functions */
166 /* Private (static) functions */
167 static int ip2_open(PTTY, struct file *);
168 static void ip2_close(PTTY, struct file *);
169 static int ip2_write(PTTY, const unsigned char *, int);
170 static int ip2_putchar(PTTY, unsigned char);
171 static void ip2_flush_chars(PTTY);
172 static int ip2_write_room(PTTY);
173 static int ip2_chars_in_buf(PTTY);
174 static void ip2_flush_buffer(PTTY);
175 static int ip2_ioctl(PTTY, struct file *, UINT, ULONG);
176 static void ip2_set_termios(PTTY, struct ktermios *);
177 static void ip2_set_line_discipline(PTTY);
178 static void ip2_throttle(PTTY);
179 static void ip2_unthrottle(PTTY);
180 static void ip2_stop(PTTY);
181 static void ip2_start(PTTY);
182 static void ip2_hangup(PTTY);
183 static int ip2_tiocmget(struct tty_struct *tty, struct file *file);
184 static int ip2_tiocmset(struct tty_struct *tty, struct file *file,
185 unsigned int set, unsigned int clear);
187 static void set_irq(int, int);
188 static void ip2_interrupt_bh(struct work_struct *work);
189 static irqreturn_t ip2_interrupt(int irq, void *dev_id);
190 static void ip2_poll(unsigned long arg);
191 static inline void service_all_boards(void);
192 static void do_input(struct work_struct *);
193 static void do_status(struct work_struct *);
195 static void ip2_wait_until_sent(PTTY,int);
197 static void set_params (i2ChanStrPtr, struct ktermios *);
198 static int get_serial_info(i2ChanStrPtr, struct serial_struct __user *);
199 static int set_serial_info(i2ChanStrPtr, struct serial_struct __user *);
201 static ssize_t ip2_ipl_read(struct file *, char __user *, size_t, loff_t *);
202 static ssize_t ip2_ipl_write(struct file *, const char __user *, size_t, loff_t *);
203 static long ip2_ipl_ioctl(struct file *, UINT, ULONG);
204 static int ip2_ipl_open(struct inode *, struct file *);
206 static int DumpTraceBuffer(char __user *, int);
207 static int DumpFifoBuffer( char __user *, int);
209 static void ip2_init_board(int, const struct firmware *);
210 static unsigned short find_eisa_board(int);
212 /***************/
213 /* Static Data */
214 /***************/
216 static struct tty_driver *ip2_tty_driver;
218 /* Here, then is a table of board pointers which the interrupt routine should
219 * scan through to determine who it must service.
221 static unsigned short i2nBoards; // Number of boards here
223 static i2eBordStrPtr i2BoardPtrTable[IP2_MAX_BOARDS];
225 static i2ChanStrPtr DevTable[IP2_MAX_PORTS];
226 //DevTableMem just used to save addresses for kfree
227 static void *DevTableMem[IP2_MAX_BOARDS];
229 /* This is the driver descriptor for the ip2ipl device, which is used to
230 * download the loadware to the boards.
232 static const struct file_operations ip2_ipl = {
233 .owner = THIS_MODULE,
234 .read = ip2_ipl_read,
235 .write = ip2_ipl_write,
236 .unlocked_ioctl = ip2_ipl_ioctl,
237 .open = ip2_ipl_open,
240 static unsigned long irq_counter;
241 static unsigned long bh_counter;
243 // Use immediate queue to service interrupts
244 #define USE_IQI
245 //#define USE_IQ // PCI&2.2 needs work
247 /* The timer_list entry for our poll routine. If interrupt operation is not
248 * selected, the board is serviced periodically to see if anything needs doing.
250 #define POLL_TIMEOUT (jiffies + 1)
251 static DEFINE_TIMER(PollTimer, ip2_poll, 0, 0);
253 #ifdef IP2DEBUG_TRACE
254 /* Trace (debug) buffer data */
255 #define TRACEMAX 1000
256 static unsigned long tracebuf[TRACEMAX];
257 static int tracestuff;
258 static int tracestrip;
259 static int tracewrap;
260 #endif
262 /**********/
263 /* Macros */
264 /**********/
266 #if defined(MODULE) && defined(IP2DEBUG_OPEN)
267 #define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] ttyc=%d, modc=%x -> %s\n", \
268 tty->name,(pCh->flags), \
269 tty->count,/*GET_USE_COUNT(module)*/0,s)
270 #else
271 #define DBG_CNT(s)
272 #endif
274 /********/
275 /* Code */
276 /********/
278 #include "i2ellis.c" /* Extremely low-level interface services */
279 #include "i2cmd.c" /* Standard loadware command definitions */
280 #include "i2lib.c" /* High level interface services */
282 /* Configuration area for modprobe */
284 MODULE_AUTHOR("Doug McNash");
285 MODULE_DESCRIPTION("Computone IntelliPort Plus Driver");
286 MODULE_LICENSE("GPL");
288 static int poll_only;
290 static int Eisa_irq;
291 static int Eisa_slot;
293 static int iindx;
294 static char rirqs[IP2_MAX_BOARDS];
295 static int Valid_Irqs[] = { 3, 4, 5, 7, 10, 11, 12, 15, 0};
297 /* Note: Add compiled in defaults to these arrays, not to the structure
298 in ip2.h any longer. That structure WILL get overridden
299 by these values, or command line values, or insmod values!!! =mhw=
301 static int io[IP2_MAX_BOARDS];
302 static int irq[IP2_MAX_BOARDS] = { -1, -1, -1, -1 };
304 MODULE_AUTHOR("Doug McNash");
305 MODULE_DESCRIPTION("Computone IntelliPort Plus Driver");
306 module_param_array(irq, int, NULL, 0);
307 MODULE_PARM_DESC(irq, "Interrupts for IntelliPort Cards");
308 module_param_array(io, int, NULL, 0);
309 MODULE_PARM_DESC(io, "I/O ports for IntelliPort Cards");
310 module_param(poll_only, bool, 0);
311 MODULE_PARM_DESC(poll_only, "Do not use card interrupts");
313 /* for sysfs class support */
314 static struct class *ip2_class;
316 /* Some functions to keep track of what irqs we have */
318 static int __init is_valid_irq(int irq)
320 int *i = Valid_Irqs;
322 while (*i != 0 && *i != irq)
323 i++;
325 return *i;
328 static void __init mark_requested_irq(char irq)
330 rirqs[iindx++] = irq;
333 static int __exit clear_requested_irq(char irq)
335 int i;
336 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
337 if (rirqs[i] == irq) {
338 rirqs[i] = 0;
339 return 1;
342 return 0;
345 static int have_requested_irq(char irq)
347 /* array init to zeros so 0 irq will not be requested as a side
348 * effect */
349 int i;
350 for (i = 0; i < IP2_MAX_BOARDS; ++i)
351 if (rirqs[i] == irq)
352 return 1;
353 return 0;
356 /******************************************************************************/
357 /* Function: cleanup_module() */
358 /* Parameters: None */
359 /* Returns: Nothing */
360 /* */
361 /* Description: */
362 /* This is a required entry point for an installable module. It has to return */
363 /* the device and the driver to a passive state. It should not be necessary */
364 /* to reset the board fully, especially as the loadware is downloaded */
365 /* externally rather than in the driver. We just want to disable the board */
366 /* and clear the loadware to a reset state. To allow this there has to be a */
367 /* way to detect whether the board has the loadware running at init time to */
368 /* handle subsequent installations of the driver. All memory allocated by the */
369 /* driver should be returned since it may be unloaded from memory. */
370 /******************************************************************************/
371 static void __exit ip2_cleanup_module(void)
373 int err;
374 int i;
376 del_timer_sync(&PollTimer);
378 /* Reset the boards we have. */
379 for (i = 0; i < IP2_MAX_BOARDS; i++)
380 if (i2BoardPtrTable[i])
381 iiReset(i2BoardPtrTable[i]);
383 /* The following is done at most once, if any boards were installed. */
384 for (i = 0; i < IP2_MAX_BOARDS; i++) {
385 if (i2BoardPtrTable[i]) {
386 iiResetDelay(i2BoardPtrTable[i]);
387 /* free io addresses and Tibet */
388 release_region(ip2config.addr[i], 8);
389 device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i));
390 device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR,
391 4 * i + 1));
393 /* Disable and remove interrupt handler. */
394 if (ip2config.irq[i] > 0 &&
395 have_requested_irq(ip2config.irq[i])) {
396 free_irq(ip2config.irq[i], (void *)&pcName);
397 clear_requested_irq(ip2config.irq[i]);
400 class_destroy(ip2_class);
401 err = tty_unregister_driver(ip2_tty_driver);
402 if (err)
403 printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n",
404 err);
405 put_tty_driver(ip2_tty_driver);
406 unregister_chrdev(IP2_IPL_MAJOR, pcIpl);
407 remove_proc_entry("ip2mem", NULL);
409 /* free memory */
410 for (i = 0; i < IP2_MAX_BOARDS; i++) {
411 void *pB;
412 #ifdef CONFIG_PCI
413 if (ip2config.type[i] == PCI && ip2config.pci_dev[i]) {
414 pci_disable_device(ip2config.pci_dev[i]);
415 pci_dev_put(ip2config.pci_dev[i]);
416 ip2config.pci_dev[i] = NULL;
418 #endif
419 pB = i2BoardPtrTable[i];
420 if (pB != NULL) {
421 kfree(pB);
422 i2BoardPtrTable[i] = NULL;
424 if (DevTableMem[i] != NULL) {
425 kfree(DevTableMem[i]);
426 DevTableMem[i] = NULL;
430 module_exit(ip2_cleanup_module);
432 static const struct tty_operations ip2_ops = {
433 .open = ip2_open,
434 .close = ip2_close,
435 .write = ip2_write,
436 .put_char = ip2_putchar,
437 .flush_chars = ip2_flush_chars,
438 .write_room = ip2_write_room,
439 .chars_in_buffer = ip2_chars_in_buf,
440 .flush_buffer = ip2_flush_buffer,
441 .ioctl = ip2_ioctl,
442 .throttle = ip2_throttle,
443 .unthrottle = ip2_unthrottle,
444 .set_termios = ip2_set_termios,
445 .set_ldisc = ip2_set_line_discipline,
446 .stop = ip2_stop,
447 .start = ip2_start,
448 .hangup = ip2_hangup,
449 .tiocmget = ip2_tiocmget,
450 .tiocmset = ip2_tiocmset,
451 .proc_fops = &ip2_proc_fops,
454 /******************************************************************************/
455 /* Function: ip2_loadmain() */
456 /* Parameters: irq, io from command line of insmod et. al. */
457 /* pointer to fip firmware and firmware size for boards */
458 /* Returns: Success (0) */
459 /* */
460 /* Description: */
461 /* This was the required entry point for all drivers (now in ip2.c) */
462 /* It performs all */
463 /* initialisation of the devices and driver structures, and registers itself */
464 /* with the relevant kernel modules. */
465 /******************************************************************************/
466 /* IRQF_DISABLED - if set blocks all interrupts else only this line */
467 /* IRQF_SHARED - for shared irq PCI or maybe EISA only */
468 /* SA_RANDOM - can be source for cert. random number generators */
469 #define IP2_SA_FLAGS 0
472 static const struct firmware *ip2_request_firmware(void)
474 struct platform_device *pdev;
475 const struct firmware *fw;
477 pdev = platform_device_register_simple("ip2", 0, NULL, 0);
478 if (IS_ERR(pdev)) {
479 printk(KERN_ERR "Failed to register platform device for ip2\n");
480 return NULL;
482 if (request_firmware(&fw, "intelliport2.bin", &pdev->dev)) {
483 printk(KERN_ERR "Failed to load firmware 'intelliport2.bin'\n");
484 fw = NULL;
486 platform_device_unregister(pdev);
487 return fw;
490 #ifndef MODULE
491 /******************************************************************************
492 * ip2_setup:
493 * str: kernel command line string
495 * Can't autoprobe the boards so user must specify configuration on
496 * kernel command line. Sane people build it modular but the others
497 * come here.
499 * Alternating pairs of io,irq for up to 4 boards.
500 * ip2=io0,irq0,io1,irq1,io2,irq2,io3,irq3
502 * io=0 => No board
503 * io=1 => PCI
504 * io=2 => EISA
505 * else => ISA I/O address
507 * irq=0 or invalid for ISA will revert to polling mode
509 * Any value = -1, do not overwrite compiled in value.
511 ******************************************************************************/
512 static int __init ip2_setup(char *str)
514 int j, ints[10]; /* 4 boards, 2 parameters + 2 */
515 unsigned int i;
517 str = get_options(str, ARRAY_SIZE(ints), ints);
519 for (i = 0, j = 1; i < 4; i++) {
520 if (j > ints[0])
521 break;
522 if (ints[j] >= 0)
523 io[i] = ints[j];
524 j++;
525 if (j > ints[0])
526 break;
527 if (ints[j] >= 0)
528 irq[i] = ints[j];
529 j++;
531 return 1;
533 __setup("ip2=", ip2_setup);
534 #endif /* !MODULE */
536 static int __init ip2_loadmain(void)
538 int i, j, box;
539 int err = 0;
540 i2eBordStrPtr pB = NULL;
541 int rc = -1;
542 struct pci_dev *pdev = NULL;
543 const struct firmware *fw = NULL;
545 if (poll_only) {
546 /* Hard lock the interrupts to zero */
547 irq[0] = irq[1] = irq[2] = irq[3] = poll_only = 0;
550 ip2trace(ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0);
552 /* process command line arguments to modprobe or
553 insmod i.e. iop & irqp */
554 /* irqp and iop should ALWAYS be specified now... But we check
555 them individually just to be sure, anyways... */
556 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
557 ip2config.addr[i] = io[i];
558 if (irq[i] >= 0)
559 ip2config.irq[i] = irq[i];
560 else
561 ip2config.irq[i] = 0;
562 /* This is a little bit of a hack. If poll_only=1 on command
563 line back in ip2.c OR all IRQs on all specified boards are
564 explicitly set to 0, then drop to poll only mode and override
565 PCI or EISA interrupts. This superceeds the old hack of
566 triggering if all interrupts were zero (like da default).
567 Still a hack but less prone to random acts of terrorism.
569 What we really should do, now that the IRQ default is set
570 to -1, is to use 0 as a hard coded, do not probe.
572 /\/\|=mhw=|\/\/
574 poll_only |= irq[i];
576 poll_only = !poll_only;
578 /* Announce our presence */
579 printk(KERN_INFO "%s version %s\n", pcName, pcVersion);
581 ip2_tty_driver = alloc_tty_driver(IP2_MAX_PORTS);
582 if (!ip2_tty_driver)
583 return -ENOMEM;
585 /* Initialise all the boards we can find (up to the maximum). */
586 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
587 switch (ip2config.addr[i]) {
588 case 0: /* skip this slot even if card is present */
589 break;
590 default: /* ISA */
591 /* ISA address must be specified */
592 if (ip2config.addr[i] < 0x100 ||
593 ip2config.addr[i] > 0x3f8) {
594 printk(KERN_ERR "IP2: Bad ISA board %d "
595 "address %x\n", i,
596 ip2config.addr[i]);
597 ip2config.addr[i] = 0;
598 break;
600 ip2config.type[i] = ISA;
602 /* Check for valid irq argument, set for polling if
603 * invalid */
604 if (ip2config.irq[i] &&
605 !is_valid_irq(ip2config.irq[i])) {
606 printk(KERN_ERR "IP2: Bad IRQ(%d) specified\n",
607 ip2config.irq[i]);
608 /* 0 is polling and is valid in that sense */
609 ip2config.irq[i] = 0;
611 break;
612 case PCI:
613 #ifdef CONFIG_PCI
615 u32 addr;
616 int status;
618 pdev = pci_get_device(PCI_VENDOR_ID_COMPUTONE,
619 PCI_DEVICE_ID_COMPUTONE_IP2EX, pdev);
620 if (pdev == NULL) {
621 ip2config.addr[i] = 0;
622 printk(KERN_ERR "IP2: PCI board %d not "
623 "found\n", i);
624 break;
627 if (pci_enable_device(pdev)) {
628 dev_err(&pdev->dev, "can't enable device\n");
629 break;
631 ip2config.type[i] = PCI;
632 ip2config.pci_dev[i] = pci_dev_get(pdev);
633 status = pci_read_config_dword(pdev, PCI_BASE_ADDRESS_1,
634 &addr);
635 if (addr & 1)
636 ip2config.addr[i] = (USHORT)(addr & 0xfffe);
637 else
638 dev_err(&pdev->dev, "I/O address error\n");
640 ip2config.irq[i] = pdev->irq;
642 #else
643 printk(KERN_ERR "IP2: PCI card specified but PCI "
644 "support not enabled.\n");
645 printk(KERN_ERR "IP2: Recompile kernel with CONFIG_PCI "
646 "defined!\n");
647 #endif /* CONFIG_PCI */
648 break;
649 case EISA:
650 ip2config.addr[i] = find_eisa_board(Eisa_slot + 1);
651 if (ip2config.addr[i] != 0) {
652 /* Eisa_irq set as side effect, boo */
653 ip2config.type[i] = EISA;
655 ip2config.irq[i] = Eisa_irq;
656 break;
657 } /* switch */
658 } /* for */
659 pci_dev_put(pdev);
661 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
662 if (ip2config.addr[i]) {
663 pB = kzalloc(sizeof(i2eBordStr), GFP_KERNEL);
664 if (pB) {
665 i2BoardPtrTable[i] = pB;
666 iiSetAddress(pB, ip2config.addr[i],
667 ii2DelayTimer);
668 iiReset(pB);
669 } else
670 printk(KERN_ERR "IP2: board memory allocation "
671 "error\n");
674 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
675 pB = i2BoardPtrTable[i];
676 if (pB != NULL) {
677 iiResetDelay(pB);
678 break;
681 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
682 /* We don't want to request the firmware unless we have at
683 least one board */
684 if (i2BoardPtrTable[i] != NULL) {
685 if (!fw)
686 fw = ip2_request_firmware();
687 if (!fw)
688 break;
689 ip2_init_board(i, fw);
692 if (fw)
693 release_firmware(fw);
695 ip2trace(ITRC_NO_PORT, ITRC_INIT, 2, 0);
697 ip2_tty_driver->owner = THIS_MODULE;
698 ip2_tty_driver->name = "ttyF";
699 ip2_tty_driver->driver_name = pcDriver_name;
700 ip2_tty_driver->major = IP2_TTY_MAJOR;
701 ip2_tty_driver->minor_start = 0;
702 ip2_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
703 ip2_tty_driver->subtype = SERIAL_TYPE_NORMAL;
704 ip2_tty_driver->init_termios = tty_std_termios;
705 ip2_tty_driver->init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL;
706 ip2_tty_driver->flags = TTY_DRIVER_REAL_RAW |
707 TTY_DRIVER_DYNAMIC_DEV;
708 tty_set_operations(ip2_tty_driver, &ip2_ops);
710 ip2trace(ITRC_NO_PORT, ITRC_INIT, 3, 0);
712 err = tty_register_driver(ip2_tty_driver);
713 if (err) {
714 printk(KERN_ERR "IP2: failed to register tty driver\n");
715 put_tty_driver(ip2_tty_driver);
716 return err; /* leaking resources */
719 err = register_chrdev(IP2_IPL_MAJOR, pcIpl, &ip2_ipl);
720 if (err) {
721 printk(KERN_ERR "IP2: failed to register IPL device (%d)\n",
722 err);
723 } else {
724 /* create the sysfs class */
725 ip2_class = class_create(THIS_MODULE, "ip2");
726 if (IS_ERR(ip2_class)) {
727 err = PTR_ERR(ip2_class);
728 goto out_chrdev;
731 /* Register the read_procmem thing */
732 if (!proc_create("ip2mem",0,NULL,&ip2mem_proc_fops)) {
733 printk(KERN_ERR "IP2: failed to register read_procmem\n");
734 return -EIO; /* leaking resources */
737 ip2trace(ITRC_NO_PORT, ITRC_INIT, 4, 0);
738 /* Register the interrupt handler or poll handler, depending upon the
739 * specified interrupt.
742 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
743 if (ip2config.addr[i] == 0)
744 continue;
746 pB = i2BoardPtrTable[i];
747 if (pB != NULL) {
748 device_create(ip2_class, NULL,
749 MKDEV(IP2_IPL_MAJOR, 4 * i),
750 NULL, "ipl%d", i);
751 device_create(ip2_class, NULL,
752 MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
753 NULL, "stat%d", i);
755 for (box = 0; box < ABS_MAX_BOXES; box++)
756 for (j = 0; j < ABS_BIGGEST_BOX; j++)
757 if (pB->i2eChannelMap[box] & (1 << j))
758 tty_register_device(
759 ip2_tty_driver,
760 j + ABS_BIGGEST_BOX *
761 (box+i*ABS_MAX_BOXES),
762 NULL);
765 if (poll_only) {
766 /* Poll only forces driver to only use polling and
767 to ignore the probed PCI or EISA interrupts. */
768 ip2config.irq[i] = CIR_POLL;
770 if (ip2config.irq[i] == CIR_POLL) {
771 retry:
772 if (!timer_pending(&PollTimer)) {
773 mod_timer(&PollTimer, POLL_TIMEOUT);
774 printk(KERN_INFO "IP2: polling\n");
776 } else {
777 if (have_requested_irq(ip2config.irq[i]))
778 continue;
779 rc = request_irq(ip2config.irq[i], ip2_interrupt,
780 IP2_SA_FLAGS |
781 (ip2config.type[i] == PCI ? IRQF_SHARED : 0),
782 pcName, i2BoardPtrTable[i]);
783 if (rc) {
784 printk(KERN_ERR "IP2: request_irq failed: "
785 "error %d\n", rc);
786 ip2config.irq[i] = CIR_POLL;
787 printk(KERN_INFO "IP2: Polling %ld/sec.\n",
788 (POLL_TIMEOUT - jiffies));
789 goto retry;
791 mark_requested_irq(ip2config.irq[i]);
792 /* Initialise the interrupt handler bottom half
793 * (aka slih). */
797 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
798 if (i2BoardPtrTable[i]) {
799 /* set and enable board interrupt */
800 set_irq(i, ip2config.irq[i]);
804 ip2trace(ITRC_NO_PORT, ITRC_INIT, ITRC_RETURN, 0);
806 return 0;
808 out_chrdev:
809 unregister_chrdev(IP2_IPL_MAJOR, "ip2");
810 /* unregister and put tty here */
811 return err;
813 module_init(ip2_loadmain);
815 /******************************************************************************/
816 /* Function: ip2_init_board() */
817 /* Parameters: Index of board in configuration structure */
818 /* Returns: Success (0) */
819 /* */
820 /* Description: */
821 /* This function initializes the specified board. The loadware is copied to */
822 /* the board, the channel structures are initialized, and the board details */
823 /* are reported on the console. */
824 /******************************************************************************/
825 static void
826 ip2_init_board(int boardnum, const struct firmware *fw)
828 int i;
829 int nports = 0, nboxes = 0;
830 i2ChanStrPtr pCh;
831 i2eBordStrPtr pB = i2BoardPtrTable[boardnum];
833 if ( !iiInitialize ( pB ) ) {
834 printk ( KERN_ERR "IP2: Failed to initialize board at 0x%x, error %d\n",
835 pB->i2eBase, pB->i2eError );
836 goto err_initialize;
838 printk(KERN_INFO "IP2: Board %d: addr=0x%x irq=%d\n", boardnum + 1,
839 ip2config.addr[boardnum], ip2config.irq[boardnum] );
841 if (!request_region( ip2config.addr[boardnum], 8, pcName )) {
842 printk(KERN_ERR "IP2: bad addr=0x%x\n", ip2config.addr[boardnum]);
843 goto err_initialize;
846 if ( iiDownloadAll ( pB, (loadHdrStrPtr)fw->data, 1, fw->size )
847 != II_DOWN_GOOD ) {
848 printk ( KERN_ERR "IP2: failed to download loadware\n" );
849 goto err_release_region;
850 } else {
851 printk ( KERN_INFO "IP2: fv=%d.%d.%d lv=%d.%d.%d\n",
852 pB->i2ePom.e.porVersion,
853 pB->i2ePom.e.porRevision,
854 pB->i2ePom.e.porSubRev, pB->i2eLVersion,
855 pB->i2eLRevision, pB->i2eLSub );
858 switch ( pB->i2ePom.e.porID & ~POR_ID_RESERVED ) {
860 default:
861 printk( KERN_ERR "IP2: Unknown board type, ID = %x\n",
862 pB->i2ePom.e.porID );
863 nports = 0;
864 goto err_release_region;
865 break;
867 case POR_ID_II_4: /* IntelliPort-II, ISA-4 (4xRJ45) */
868 printk ( KERN_INFO "IP2: ISA-4\n" );
869 nports = 4;
870 break;
872 case POR_ID_II_8: /* IntelliPort-II, 8-port using standard brick. */
873 printk ( KERN_INFO "IP2: ISA-8 std\n" );
874 nports = 8;
875 break;
877 case POR_ID_II_8R: /* IntelliPort-II, 8-port using RJ11's (no CTS) */
878 printk ( KERN_INFO "IP2: ISA-8 RJ11\n" );
879 nports = 8;
880 break;
882 case POR_ID_FIIEX: /* IntelliPort IIEX */
884 int portnum = IP2_PORTS_PER_BOARD * boardnum;
885 int box;
887 for( box = 0; box < ABS_MAX_BOXES; ++box ) {
888 if ( pB->i2eChannelMap[box] != 0 ) {
889 ++nboxes;
891 for( i = 0; i < ABS_BIGGEST_BOX; ++i ) {
892 if ( pB->i2eChannelMap[box] & 1<< i ) {
893 ++nports;
897 DevTableMem[boardnum] = pCh =
898 kmalloc( sizeof(i2ChanStr) * nports, GFP_KERNEL );
899 if ( !pCh ) {
900 printk ( KERN_ERR "IP2: (i2_init_channel:) Out of memory.\n");
901 goto err_release_region;
903 if ( !i2InitChannels( pB, nports, pCh ) ) {
904 printk(KERN_ERR "IP2: i2InitChannels failed: %d\n",pB->i2eError);
905 kfree ( pCh );
906 goto err_release_region;
908 pB->i2eChannelPtr = &DevTable[portnum];
909 pB->i2eChannelCnt = ABS_MOST_PORTS;
911 for( box = 0; box < ABS_MAX_BOXES; ++box, portnum += ABS_BIGGEST_BOX ) {
912 for( i = 0; i < ABS_BIGGEST_BOX; ++i ) {
913 if ( pB->i2eChannelMap[box] & (1 << i) ) {
914 DevTable[portnum + i] = pCh;
915 pCh->port_index = portnum + i;
916 pCh++;
920 printk(KERN_INFO "IP2: EX box=%d ports=%d %d bit\n",
921 nboxes, nports, pB->i2eDataWidth16 ? 16 : 8 );
923 goto ex_exit;
925 DevTableMem[boardnum] = pCh =
926 kmalloc ( sizeof (i2ChanStr) * nports, GFP_KERNEL );
927 if ( !pCh ) {
928 printk ( KERN_ERR "IP2: (i2_init_channel:) Out of memory.\n");
929 goto err_release_region;
931 pB->i2eChannelPtr = pCh;
932 pB->i2eChannelCnt = nports;
933 if ( !i2InitChannels( pB, nports, pCh ) ) {
934 printk(KERN_ERR "IP2: i2InitChannels failed: %d\n",pB->i2eError);
935 kfree ( pCh );
936 goto err_release_region;
938 pB->i2eChannelPtr = &DevTable[IP2_PORTS_PER_BOARD * boardnum];
940 for( i = 0; i < pB->i2eChannelCnt; ++i ) {
941 DevTable[IP2_PORTS_PER_BOARD * boardnum + i] = pCh;
942 pCh->port_index = (IP2_PORTS_PER_BOARD * boardnum) + i;
943 pCh++;
945 ex_exit:
946 INIT_WORK(&pB->tqueue_interrupt, ip2_interrupt_bh);
947 return;
949 err_release_region:
950 release_region(ip2config.addr[boardnum], 8);
951 err_initialize:
952 kfree ( pB );
953 i2BoardPtrTable[boardnum] = NULL;
954 return;
957 /******************************************************************************/
958 /* Function: find_eisa_board ( int start_slot ) */
959 /* Parameters: First slot to check */
960 /* Returns: Address of EISA IntelliPort II controller */
961 /* */
962 /* Description: */
963 /* This function searches for an EISA IntelliPort controller, starting */
964 /* from the specified slot number. If the motherboard is not identified as an */
965 /* EISA motherboard, or no valid board ID is selected it returns 0. Otherwise */
966 /* it returns the base address of the controller. */
967 /******************************************************************************/
968 static unsigned short
969 find_eisa_board( int start_slot )
971 int i, j;
972 unsigned int idm = 0;
973 unsigned int idp = 0;
974 unsigned int base = 0;
975 unsigned int value;
976 int setup_address;
977 int setup_irq;
978 int ismine = 0;
981 * First a check for an EISA motherboard, which we do by comparing the
982 * EISA ID registers for the system board and the first couple of slots.
983 * No slot ID should match the system board ID, but on an ISA or PCI
984 * machine the odds are that an empty bus will return similar values for
985 * each slot.
987 i = 0x0c80;
988 value = (inb(i) << 24) + (inb(i+1) << 16) + (inb(i+2) << 8) + inb(i+3);
989 for( i = 0x1c80; i <= 0x4c80; i += 0x1000 ) {
990 j = (inb(i)<<24)+(inb(i+1)<<16)+(inb(i+2)<<8)+inb(i+3);
991 if ( value == j )
992 return 0;
996 * OK, so we are inclined to believe that this is an EISA machine. Find
997 * an IntelliPort controller.
999 for( i = start_slot; i < 16; i++ ) {
1000 base = i << 12;
1001 idm = (inb(base + 0xc80) << 8) | (inb(base + 0xc81) & 0xff);
1002 idp = (inb(base + 0xc82) << 8) | (inb(base + 0xc83) & 0xff);
1003 ismine = 0;
1004 if ( idm == 0x0e8e ) {
1005 if ( idp == 0x0281 || idp == 0x0218 ) {
1006 ismine = 1;
1007 } else if ( idp == 0x0282 || idp == 0x0283 ) {
1008 ismine = 3; /* Can do edge-trigger */
1010 if ( ismine ) {
1011 Eisa_slot = i;
1012 break;
1016 if ( !ismine )
1017 return 0;
1019 /* It's some sort of EISA card, but at what address is it configured? */
1021 setup_address = base + 0xc88;
1022 value = inb(base + 0xc86);
1023 setup_irq = (value & 8) ? Valid_Irqs[value & 7] : 0;
1025 if ( (ismine & 2) && !(value & 0x10) ) {
1026 ismine = 1; /* Could be edging, but not */
1029 if ( Eisa_irq == 0 ) {
1030 Eisa_irq = setup_irq;
1031 } else if ( Eisa_irq != setup_irq ) {
1032 printk ( KERN_ERR "IP2: EISA irq mismatch between EISA controllers\n" );
1035 #ifdef IP2DEBUG_INIT
1036 printk(KERN_DEBUG "Computone EISA board in slot %d, I.D. 0x%x%x, Address 0x%x",
1037 base >> 12, idm, idp, setup_address);
1038 if ( Eisa_irq ) {
1039 printk(KERN_DEBUG ", Interrupt %d %s\n",
1040 setup_irq, (ismine & 2) ? "(edge)" : "(level)");
1041 } else {
1042 printk(KERN_DEBUG ", (polled)\n");
1044 #endif
1045 return setup_address;
1048 /******************************************************************************/
1049 /* Function: set_irq() */
1050 /* Parameters: index to board in board table */
1051 /* IRQ to use */
1052 /* Returns: Success (0) */
1053 /* */
1054 /* Description: */
1055 /******************************************************************************/
1056 static void
1057 set_irq( int boardnum, int boardIrq )
1059 unsigned char tempCommand[16];
1060 i2eBordStrPtr pB = i2BoardPtrTable[boardnum];
1061 unsigned long flags;
1064 * Notify the boards they may generate interrupts. This is done by
1065 * sending an in-line command to channel 0 on each board. This is why
1066 * the channels have to be defined already. For each board, if the
1067 * interrupt has never been defined, we must do so NOW, directly, since
1068 * board will not send flow control or even give an interrupt until this
1069 * is done. If polling we must send 0 as the interrupt parameter.
1072 // We will get an interrupt here at the end of this function
1074 iiDisableMailIrq(pB);
1076 /* We build up the entire packet header. */
1077 CHANNEL_OF(tempCommand) = 0;
1078 PTYPE_OF(tempCommand) = PTYPE_INLINE;
1079 CMD_COUNT_OF(tempCommand) = 2;
1080 (CMD_OF(tempCommand))[0] = CMDVALUE_IRQ;
1081 (CMD_OF(tempCommand))[1] = boardIrq;
1083 * Write to FIFO; don't bother to adjust fifo capacity for this, since
1084 * board will respond almost immediately after SendMail hit.
1086 write_lock_irqsave(&pB->write_fifo_spinlock, flags);
1087 iiWriteBuf(pB, tempCommand, 4);
1088 write_unlock_irqrestore(&pB->write_fifo_spinlock, flags);
1089 pB->i2eUsingIrq = boardIrq;
1090 pB->i2eOutMailWaiting |= MB_OUT_STUFFED;
1092 /* Need to update number of boards before you enable mailbox int */
1093 ++i2nBoards;
1095 CHANNEL_OF(tempCommand) = 0;
1096 PTYPE_OF(tempCommand) = PTYPE_BYPASS;
1097 CMD_COUNT_OF(tempCommand) = 6;
1098 (CMD_OF(tempCommand))[0] = 88; // SILO
1099 (CMD_OF(tempCommand))[1] = 64; // chars
1100 (CMD_OF(tempCommand))[2] = 32; // ms
1102 (CMD_OF(tempCommand))[3] = 28; // MAX_BLOCK
1103 (CMD_OF(tempCommand))[4] = 64; // chars
1105 (CMD_OF(tempCommand))[5] = 87; // HW_TEST
1106 write_lock_irqsave(&pB->write_fifo_spinlock, flags);
1107 iiWriteBuf(pB, tempCommand, 8);
1108 write_unlock_irqrestore(&pB->write_fifo_spinlock, flags);
1110 CHANNEL_OF(tempCommand) = 0;
1111 PTYPE_OF(tempCommand) = PTYPE_BYPASS;
1112 CMD_COUNT_OF(tempCommand) = 1;
1113 (CMD_OF(tempCommand))[0] = 84; /* get BOX_IDS */
1114 iiWriteBuf(pB, tempCommand, 3);
1116 #ifdef XXX
1117 // enable heartbeat for test porpoises
1118 CHANNEL_OF(tempCommand) = 0;
1119 PTYPE_OF(tempCommand) = PTYPE_BYPASS;
1120 CMD_COUNT_OF(tempCommand) = 2;
1121 (CMD_OF(tempCommand))[0] = 44; /* get ping */
1122 (CMD_OF(tempCommand))[1] = 200; /* 200 ms */
1123 write_lock_irqsave(&pB->write_fifo_spinlock, flags);
1124 iiWriteBuf(pB, tempCommand, 4);
1125 write_unlock_irqrestore(&pB->write_fifo_spinlock, flags);
1126 #endif
1128 iiEnableMailIrq(pB);
1129 iiSendPendingMail(pB);
1132 /******************************************************************************/
1133 /* Interrupt Handler Section */
1134 /******************************************************************************/
1136 static inline void
1137 service_all_boards(void)
1139 int i;
1140 i2eBordStrPtr pB;
1142 /* Service every board on the list */
1143 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
1144 pB = i2BoardPtrTable[i];
1145 if ( pB ) {
1146 i2ServiceBoard( pB );
1152 /******************************************************************************/
1153 /* Function: ip2_interrupt_bh(work) */
1154 /* Parameters: work - pointer to the board structure */
1155 /* Returns: Nothing */
1156 /* */
1157 /* Description: */
1158 /* Service the board in a bottom half interrupt handler and then */
1159 /* reenable the board's interrupts if it has an IRQ number */
1160 /* */
1161 /******************************************************************************/
1162 static void
1163 ip2_interrupt_bh(struct work_struct *work)
1165 i2eBordStrPtr pB = container_of(work, i2eBordStr, tqueue_interrupt);
1166 // pB better well be set or we have a problem! We can only get
1167 // here from the IMMEDIATE queue. Here, we process the boards.
1168 // Checking pB doesn't cost much and it saves us from the sanity checkers.
1170 bh_counter++;
1172 if ( pB ) {
1173 i2ServiceBoard( pB );
1174 if( pB->i2eUsingIrq ) {
1175 // Re-enable his interrupts
1176 iiEnableMailIrq(pB);
1182 /******************************************************************************/
1183 /* Function: ip2_interrupt(int irq, void *dev_id) */
1184 /* Parameters: irq - interrupt number */
1185 /* pointer to optional device ID structure */
1186 /* Returns: Nothing */
1187 /* */
1188 /* Description: */
1189 /* */
1190 /* Our task here is simply to identify each board which needs servicing. */
1191 /* If we are queuing then, queue it to be serviced, and disable its irq */
1192 /* mask otherwise process the board directly. */
1193 /* */
1194 /* We could queue by IRQ but that just complicates things on both ends */
1195 /* with very little gain in performance (how many instructions does */
1196 /* it take to iterate on the immediate queue). */
1197 /* */
1198 /* */
1199 /******************************************************************************/
1200 static void
1201 ip2_irq_work(i2eBordStrPtr pB)
1203 #ifdef USE_IQI
1204 if (NO_MAIL_HERE != ( pB->i2eStartMail = iiGetMail(pB))) {
1205 // Disable his interrupt (will be enabled when serviced)
1206 // This is mostly to protect from reentrancy.
1207 iiDisableMailIrq(pB);
1209 // Park the board on the immediate queue for processing.
1210 schedule_work(&pB->tqueue_interrupt);
1212 // Make sure the immediate queue is flagged to fire.
1214 #else
1216 // We are using immediate servicing here. This sucks and can
1217 // cause all sorts of havoc with ppp and others. The failsafe
1218 // check on iiSendPendingMail could also throw a hairball.
1220 i2ServiceBoard( pB );
1222 #endif /* USE_IQI */
1225 static void
1226 ip2_polled_interrupt(void)
1228 int i;
1229 i2eBordStrPtr pB;
1231 ip2trace(ITRC_NO_PORT, ITRC_INTR, 99, 1, 0);
1233 /* Service just the boards on the list using this irq */
1234 for( i = 0; i < i2nBoards; ++i ) {
1235 pB = i2BoardPtrTable[i];
1237 // Only process those boards which match our IRQ.
1238 // IRQ = 0 for polled boards, we won't poll "IRQ" boards
1240 if (pB && pB->i2eUsingIrq == 0)
1241 ip2_irq_work(pB);
1244 ++irq_counter;
1246 ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 );
1249 static irqreturn_t
1250 ip2_interrupt(int irq, void *dev_id)
1252 i2eBordStrPtr pB = dev_id;
1254 ip2trace (ITRC_NO_PORT, ITRC_INTR, 99, 1, pB->i2eUsingIrq );
1256 ip2_irq_work(pB);
1258 ++irq_counter;
1260 ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 );
1261 return IRQ_HANDLED;
1264 /******************************************************************************/
1265 /* Function: ip2_poll(unsigned long arg) */
1266 /* Parameters: ? */
1267 /* Returns: Nothing */
1268 /* */
1269 /* Description: */
1270 /* This function calls the library routine i2ServiceBoard for each board in */
1271 /* the board table. This is used instead of the interrupt routine when polled */
1272 /* mode is specified. */
1273 /******************************************************************************/
1274 static void
1275 ip2_poll(unsigned long arg)
1277 ip2trace (ITRC_NO_PORT, ITRC_INTR, 100, 0 );
1279 // Just polled boards, IRQ = 0 will hit all non-interrupt boards.
1280 // It will NOT poll boards handled by hard interrupts.
1281 // The issue of queued BH interrupts is handled in ip2_interrupt().
1282 ip2_polled_interrupt();
1284 mod_timer(&PollTimer, POLL_TIMEOUT);
1286 ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 );
1289 static void do_input(struct work_struct *work)
1291 i2ChanStrPtr pCh = container_of(work, i2ChanStr, tqueue_input);
1292 unsigned long flags;
1294 ip2trace(CHANN, ITRC_INPUT, 21, 0 );
1296 // Data input
1297 if ( pCh->pTTY != NULL ) {
1298 read_lock_irqsave(&pCh->Ibuf_spinlock, flags);
1299 if (!pCh->throttled && (pCh->Ibuf_stuff != pCh->Ibuf_strip)) {
1300 read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags);
1301 i2Input( pCh );
1302 } else
1303 read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags);
1304 } else {
1305 ip2trace(CHANN, ITRC_INPUT, 22, 0 );
1307 i2InputFlush( pCh );
1311 // code duplicated from n_tty (ldisc)
1312 static inline void isig(int sig, struct tty_struct *tty, int flush)
1314 /* FIXME: This is completely bogus */
1315 if (tty->pgrp)
1316 kill_pgrp(tty->pgrp, sig, 1);
1317 if (flush || !L_NOFLSH(tty)) {
1318 if ( tty->ldisc->ops->flush_buffer )
1319 tty->ldisc->ops->flush_buffer(tty);
1320 i2InputFlush( tty->driver_data );
1324 static void do_status(struct work_struct *work)
1326 i2ChanStrPtr pCh = container_of(work, i2ChanStr, tqueue_status);
1327 int status;
1329 status = i2GetStatus( pCh, (I2_BRK|I2_PAR|I2_FRA|I2_OVR) );
1331 ip2trace (CHANN, ITRC_STATUS, 21, 1, status );
1333 if (pCh->pTTY && (status & (I2_BRK|I2_PAR|I2_FRA|I2_OVR)) ) {
1334 if ( (status & I2_BRK) ) {
1335 // code duplicated from n_tty (ldisc)
1336 if (I_IGNBRK(pCh->pTTY))
1337 goto skip_this;
1338 if (I_BRKINT(pCh->pTTY)) {
1339 isig(SIGINT, pCh->pTTY, 1);
1340 goto skip_this;
1342 wake_up_interruptible(&pCh->pTTY->read_wait);
1344 #ifdef NEVER_HAPPENS_AS_SETUP_XXX
1345 // and can't work because we don't know the_char
1346 // as the_char is reported on a separate path
1347 // The intelligent board does this stuff as setup
1349 char brkf = TTY_NORMAL;
1350 unsigned char brkc = '\0';
1351 unsigned char tmp;
1352 if ( (status & I2_BRK) ) {
1353 brkf = TTY_BREAK;
1354 brkc = '\0';
1356 else if (status & I2_PAR) {
1357 brkf = TTY_PARITY;
1358 brkc = the_char;
1359 } else if (status & I2_FRA) {
1360 brkf = TTY_FRAME;
1361 brkc = the_char;
1362 } else if (status & I2_OVR) {
1363 brkf = TTY_OVERRUN;
1364 brkc = the_char;
1366 tmp = pCh->pTTY->real_raw;
1367 pCh->pTTY->real_raw = 0;
1368 pCh->pTTY->ldisc->ops.receive_buf( pCh->pTTY, &brkc, &brkf, 1 );
1369 pCh->pTTY->real_raw = tmp;
1371 #endif /* NEVER_HAPPENS_AS_SETUP_XXX */
1373 skip_this:
1375 if ( status & (I2_DDCD | I2_DDSR | I2_DCTS | I2_DRI) ) {
1376 wake_up_interruptible(&pCh->delta_msr_wait);
1378 if ( (pCh->flags & ASYNC_CHECK_CD) && (status & I2_DDCD) ) {
1379 if ( status & I2_DCD ) {
1380 if ( pCh->wopen ) {
1381 wake_up_interruptible ( &pCh->open_wait );
1383 } else {
1384 if (pCh->pTTY && (!(pCh->pTTY->termios->c_cflag & CLOCAL)) ) {
1385 tty_hangup( pCh->pTTY );
1391 ip2trace (CHANN, ITRC_STATUS, 26, 0 );
1394 /******************************************************************************/
1395 /* Device Open/Close/Ioctl Entry Point Section */
1396 /******************************************************************************/
1398 /******************************************************************************/
1399 /* Function: open_sanity_check() */
1400 /* Parameters: Pointer to tty structure */
1401 /* Pointer to file structure */
1402 /* Returns: Success or failure */
1403 /* */
1404 /* Description: */
1405 /* Verifies the structure magic numbers and cross links. */
1406 /******************************************************************************/
1407 #ifdef IP2DEBUG_OPEN
1408 static void
1409 open_sanity_check( i2ChanStrPtr pCh, i2eBordStrPtr pBrd )
1411 if ( pBrd->i2eValid != I2E_MAGIC ) {
1412 printk(KERN_ERR "IP2: invalid board structure\n" );
1413 } else if ( pBrd != pCh->pMyBord ) {
1414 printk(KERN_ERR "IP2: board structure pointer mismatch (%p)\n",
1415 pCh->pMyBord );
1416 } else if ( pBrd->i2eChannelCnt < pCh->port_index ) {
1417 printk(KERN_ERR "IP2: bad device index (%d)\n", pCh->port_index );
1418 } else if (&((i2ChanStrPtr)pBrd->i2eChannelPtr)[pCh->port_index] != pCh) {
1419 } else {
1420 printk(KERN_INFO "IP2: all pointers check out!\n" );
1423 #endif
1426 /******************************************************************************/
1427 /* Function: ip2_open() */
1428 /* Parameters: Pointer to tty structure */
1429 /* Pointer to file structure */
1430 /* Returns: Success or failure */
1431 /* */
1432 /* Description: (MANDATORY) */
1433 /* A successful device open has to run a gauntlet of checks before it */
1434 /* completes. After some sanity checking and pointer setup, the function */
1435 /* blocks until all conditions are satisfied. It then initialises the port to */
1436 /* the default characteristics and returns. */
1437 /******************************************************************************/
1438 static int
1439 ip2_open( PTTY tty, struct file *pFile )
1441 wait_queue_t wait;
1442 int rc = 0;
1443 int do_clocal = 0;
1444 i2ChanStrPtr pCh = DevTable[tty->index];
1446 ip2trace (tty->index, ITRC_OPEN, ITRC_ENTER, 0 );
1448 if ( pCh == NULL ) {
1449 return -ENODEV;
1451 /* Setup pointer links in device and tty structures */
1452 pCh->pTTY = tty;
1453 tty->driver_data = pCh;
1455 #ifdef IP2DEBUG_OPEN
1456 printk(KERN_DEBUG \
1457 "IP2:open(tty=%p,pFile=%p):dev=%s,ch=%d,idx=%d\n",
1458 tty, pFile, tty->name, pCh->infl.hd.i2sChannel, pCh->port_index);
1459 open_sanity_check ( pCh, pCh->pMyBord );
1460 #endif
1462 i2QueueCommands(PTYPE_INLINE, pCh, 100, 3, CMD_DTRUP,CMD_RTSUP,CMD_DCD_REP);
1463 pCh->dataSetOut |= (I2_DTR | I2_RTS);
1464 serviceOutgoingFifo( pCh->pMyBord );
1466 /* Block here until the port is ready (per serial and istallion) */
1468 * 1. If the port is in the middle of closing wait for the completion
1469 * and then return the appropriate error.
1471 init_waitqueue_entry(&wait, current);
1472 add_wait_queue(&pCh->close_wait, &wait);
1473 set_current_state( TASK_INTERRUPTIBLE );
1475 if ( tty_hung_up_p(pFile) || ( pCh->flags & ASYNC_CLOSING )) {
1476 if ( pCh->flags & ASYNC_CLOSING ) {
1477 schedule();
1479 if ( tty_hung_up_p(pFile) ) {
1480 set_current_state( TASK_RUNNING );
1481 remove_wait_queue(&pCh->close_wait, &wait);
1482 return( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EAGAIN : -ERESTARTSYS;
1485 set_current_state( TASK_RUNNING );
1486 remove_wait_queue(&pCh->close_wait, &wait);
1489 * 3. Handle a non-blocking open of a normal port.
1491 if ( (pFile->f_flags & O_NONBLOCK) || (tty->flags & (1<<TTY_IO_ERROR) )) {
1492 pCh->flags |= ASYNC_NORMAL_ACTIVE;
1493 goto noblock;
1496 * 4. Now loop waiting for the port to be free and carrier present
1497 * (if required).
1499 if ( tty->termios->c_cflag & CLOCAL )
1500 do_clocal = 1;
1502 #ifdef IP2DEBUG_OPEN
1503 printk(KERN_DEBUG "OpenBlock: do_clocal = %d\n", do_clocal);
1504 #endif
1506 ++pCh->wopen;
1508 init_waitqueue_entry(&wait, current);
1509 add_wait_queue(&pCh->open_wait, &wait);
1511 for(;;) {
1512 i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_DTRUP, CMD_RTSUP);
1513 pCh->dataSetOut |= (I2_DTR | I2_RTS);
1514 set_current_state( TASK_INTERRUPTIBLE );
1515 serviceOutgoingFifo( pCh->pMyBord );
1516 if ( tty_hung_up_p(pFile) ) {
1517 set_current_state( TASK_RUNNING );
1518 remove_wait_queue(&pCh->open_wait, &wait);
1519 return ( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EBUSY : -ERESTARTSYS;
1521 if (!(pCh->flags & ASYNC_CLOSING) &&
1522 (do_clocal || (pCh->dataSetIn & I2_DCD) )) {
1523 rc = 0;
1524 break;
1527 #ifdef IP2DEBUG_OPEN
1528 printk(KERN_DEBUG "ASYNC_CLOSING = %s\n",
1529 (pCh->flags & ASYNC_CLOSING)?"True":"False");
1530 printk(KERN_DEBUG "OpenBlock: waiting for CD or signal\n");
1531 #endif
1532 ip2trace (CHANN, ITRC_OPEN, 3, 2, 0,
1533 (pCh->flags & ASYNC_CLOSING) );
1534 /* check for signal */
1535 if (signal_pending(current)) {
1536 rc = (( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EAGAIN : -ERESTARTSYS);
1537 break;
1539 schedule();
1541 set_current_state( TASK_RUNNING );
1542 remove_wait_queue(&pCh->open_wait, &wait);
1544 --pCh->wopen; //why count?
1546 ip2trace (CHANN, ITRC_OPEN, 4, 0 );
1548 if (rc != 0 ) {
1549 return rc;
1551 pCh->flags |= ASYNC_NORMAL_ACTIVE;
1553 noblock:
1555 /* first open - Assign termios structure to port */
1556 if ( tty->count == 1 ) {
1557 i2QueueCommands(PTYPE_INLINE, pCh, 0, 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB);
1558 /* Now we must send the termios settings to the loadware */
1559 set_params( pCh, NULL );
1563 * Now set any i2lib options. These may go away if the i2lib code ends
1564 * up rolled into the mainline.
1566 pCh->channelOptions |= CO_NBLOCK_WRITE;
1568 #ifdef IP2DEBUG_OPEN
1569 printk (KERN_DEBUG "IP2: open completed\n" );
1570 #endif
1571 serviceOutgoingFifo( pCh->pMyBord );
1573 ip2trace (CHANN, ITRC_OPEN, ITRC_RETURN, 0 );
1575 return 0;
1578 /******************************************************************************/
1579 /* Function: ip2_close() */
1580 /* Parameters: Pointer to tty structure */
1581 /* Pointer to file structure */
1582 /* Returns: Nothing */
1583 /* */
1584 /* Description: */
1585 /* */
1586 /* */
1587 /******************************************************************************/
1588 static void
1589 ip2_close( PTTY tty, struct file *pFile )
1591 i2ChanStrPtr pCh = tty->driver_data;
1593 if ( !pCh ) {
1594 return;
1597 ip2trace (CHANN, ITRC_CLOSE, ITRC_ENTER, 0 );
1599 #ifdef IP2DEBUG_OPEN
1600 printk(KERN_DEBUG "IP2:close %s:\n",tty->name);
1601 #endif
1603 if ( tty_hung_up_p ( pFile ) ) {
1605 ip2trace (CHANN, ITRC_CLOSE, 2, 1, 2 );
1607 return;
1609 if ( tty->count > 1 ) { /* not the last close */
1611 ip2trace (CHANN, ITRC_CLOSE, 2, 1, 3 );
1613 return;
1615 pCh->flags |= ASYNC_CLOSING; // last close actually
1617 tty->closing = 1;
1619 if (pCh->ClosingWaitTime != ASYNC_CLOSING_WAIT_NONE) {
1621 * Before we drop DTR, make sure the transmitter has completely drained.
1622 * This uses an timeout, after which the close
1623 * completes.
1625 ip2_wait_until_sent(tty, pCh->ClosingWaitTime );
1628 * At this point we stop accepting input. Here we flush the channel
1629 * input buffer which will allow the board to send up more data. Any
1630 * additional input is tossed at interrupt/poll time.
1632 i2InputFlush( pCh );
1634 /* disable DSS reporting */
1635 i2QueueCommands(PTYPE_INLINE, pCh, 100, 4,
1636 CMD_DCD_NREP, CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);
1637 if ( !tty || (tty->termios->c_cflag & HUPCL) ) {
1638 i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN);
1639 pCh->dataSetOut &= ~(I2_DTR | I2_RTS);
1640 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25));
1643 serviceOutgoingFifo ( pCh->pMyBord );
1645 tty_ldisc_flush(tty);
1646 tty_driver_flush_buffer(tty);
1647 tty->closing = 0;
1649 pCh->pTTY = NULL;
1651 if (pCh->wopen) {
1652 if (pCh->ClosingDelay) {
1653 msleep_interruptible(jiffies_to_msecs(pCh->ClosingDelay));
1655 wake_up_interruptible(&pCh->open_wait);
1658 pCh->flags &=~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1659 wake_up_interruptible(&pCh->close_wait);
1661 #ifdef IP2DEBUG_OPEN
1662 DBG_CNT("ip2_close: after wakeups--");
1663 #endif
1666 ip2trace (CHANN, ITRC_CLOSE, ITRC_RETURN, 1, 1 );
1668 return;
1671 /******************************************************************************/
1672 /* Function: ip2_hangup() */
1673 /* Parameters: Pointer to tty structure */
1674 /* Returns: Nothing */
1675 /* */
1676 /* Description: */
1677 /* */
1678 /* */
1679 /******************************************************************************/
1680 static void
1681 ip2_hangup ( PTTY tty )
1683 i2ChanStrPtr pCh = tty->driver_data;
1685 if( !pCh ) {
1686 return;
1689 ip2trace (CHANN, ITRC_HANGUP, ITRC_ENTER, 0 );
1691 ip2_flush_buffer(tty);
1693 /* disable DSS reporting */
1695 i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_DCD_NREP);
1696 i2QueueCommands(PTYPE_INLINE, pCh, 0, 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB);
1697 if ( (tty->termios->c_cflag & HUPCL) ) {
1698 i2QueueCommands(PTYPE_BYPASS, pCh, 0, 2, CMD_RTSDN, CMD_DTRDN);
1699 pCh->dataSetOut &= ~(I2_DTR | I2_RTS);
1700 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25));
1702 i2QueueCommands(PTYPE_INLINE, pCh, 1, 3,
1703 CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);
1704 serviceOutgoingFifo ( pCh->pMyBord );
1706 wake_up_interruptible ( &pCh->delta_msr_wait );
1708 pCh->flags &= ~ASYNC_NORMAL_ACTIVE;
1709 pCh->pTTY = NULL;
1710 wake_up_interruptible ( &pCh->open_wait );
1712 ip2trace (CHANN, ITRC_HANGUP, ITRC_RETURN, 0 );
1715 /******************************************************************************/
1716 /******************************************************************************/
1717 /* Device Output Section */
1718 /******************************************************************************/
1719 /******************************************************************************/
1721 /******************************************************************************/
1722 /* Function: ip2_write() */
1723 /* Parameters: Pointer to tty structure */
1724 /* Flag denoting data is in user (1) or kernel (0) space */
1725 /* Pointer to data */
1726 /* Number of bytes to write */
1727 /* Returns: Number of bytes actually written */
1728 /* */
1729 /* Description: (MANDATORY) */
1730 /* */
1731 /* */
1732 /******************************************************************************/
1733 static int
1734 ip2_write( PTTY tty, const unsigned char *pData, int count)
1736 i2ChanStrPtr pCh = tty->driver_data;
1737 int bytesSent = 0;
1738 unsigned long flags;
1740 ip2trace (CHANN, ITRC_WRITE, ITRC_ENTER, 2, count, -1 );
1742 /* Flush out any buffered data left over from ip2_putchar() calls. */
1743 ip2_flush_chars( tty );
1745 /* This is the actual move bit. Make sure it does what we need!!!!! */
1746 write_lock_irqsave(&pCh->Pbuf_spinlock, flags);
1747 bytesSent = i2Output( pCh, pData, count);
1748 write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1750 ip2trace (CHANN, ITRC_WRITE, ITRC_RETURN, 1, bytesSent );
1752 return bytesSent > 0 ? bytesSent : 0;
1755 /******************************************************************************/
1756 /* Function: ip2_putchar() */
1757 /* Parameters: Pointer to tty structure */
1758 /* Character to write */
1759 /* Returns: Nothing */
1760 /* */
1761 /* Description: */
1762 /* */
1763 /* */
1764 /******************************************************************************/
1765 static int
1766 ip2_putchar( PTTY tty, unsigned char ch )
1768 i2ChanStrPtr pCh = tty->driver_data;
1769 unsigned long flags;
1771 // ip2trace (CHANN, ITRC_PUTC, ITRC_ENTER, 1, ch );
1773 write_lock_irqsave(&pCh->Pbuf_spinlock, flags);
1774 pCh->Pbuf[pCh->Pbuf_stuff++] = ch;
1775 if ( pCh->Pbuf_stuff == sizeof pCh->Pbuf ) {
1776 write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1777 ip2_flush_chars( tty );
1778 } else
1779 write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1780 return 1;
1782 // ip2trace (CHANN, ITRC_PUTC, ITRC_RETURN, 1, ch );
1785 /******************************************************************************/
1786 /* Function: ip2_flush_chars() */
1787 /* Parameters: Pointer to tty structure */
1788 /* Returns: Nothing */
1789 /* */
1790 /* Description: */
1791 /* */
1792 /******************************************************************************/
1793 static void
1794 ip2_flush_chars( PTTY tty )
1796 int strip;
1797 i2ChanStrPtr pCh = tty->driver_data;
1798 unsigned long flags;
1800 write_lock_irqsave(&pCh->Pbuf_spinlock, flags);
1801 if ( pCh->Pbuf_stuff ) {
1803 // ip2trace (CHANN, ITRC_PUTC, 10, 1, strip );
1806 // We may need to restart i2Output if it does not fullfill this request
1808 strip = i2Output( pCh, pCh->Pbuf, pCh->Pbuf_stuff);
1809 if ( strip != pCh->Pbuf_stuff ) {
1810 memmove( pCh->Pbuf, &pCh->Pbuf[strip], pCh->Pbuf_stuff - strip );
1812 pCh->Pbuf_stuff -= strip;
1814 write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1817 /******************************************************************************/
1818 /* Function: ip2_write_room() */
1819 /* Parameters: Pointer to tty structure */
1820 /* Returns: Number of bytes that the driver can accept */
1821 /* */
1822 /* Description: */
1823 /* */
1824 /******************************************************************************/
1825 static int
1826 ip2_write_room ( PTTY tty )
1828 int bytesFree;
1829 i2ChanStrPtr pCh = tty->driver_data;
1830 unsigned long flags;
1832 read_lock_irqsave(&pCh->Pbuf_spinlock, flags);
1833 bytesFree = i2OutputFree( pCh ) - pCh->Pbuf_stuff;
1834 read_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1836 ip2trace (CHANN, ITRC_WRITE, 11, 1, bytesFree );
1838 return ((bytesFree > 0) ? bytesFree : 0);
1841 /******************************************************************************/
1842 /* Function: ip2_chars_in_buf() */
1843 /* Parameters: Pointer to tty structure */
1844 /* Returns: Number of bytes queued for transmission */
1845 /* */
1846 /* Description: */
1847 /* */
1848 /* */
1849 /******************************************************************************/
1850 static int
1851 ip2_chars_in_buf ( PTTY tty )
1853 i2ChanStrPtr pCh = tty->driver_data;
1854 int rc;
1855 unsigned long flags;
1857 ip2trace (CHANN, ITRC_WRITE, 12, 1, pCh->Obuf_char_count + pCh->Pbuf_stuff );
1859 #ifdef IP2DEBUG_WRITE
1860 printk (KERN_DEBUG "IP2: chars in buffer = %d (%d,%d)\n",
1861 pCh->Obuf_char_count + pCh->Pbuf_stuff,
1862 pCh->Obuf_char_count, pCh->Pbuf_stuff );
1863 #endif
1864 read_lock_irqsave(&pCh->Obuf_spinlock, flags);
1865 rc = pCh->Obuf_char_count;
1866 read_unlock_irqrestore(&pCh->Obuf_spinlock, flags);
1867 read_lock_irqsave(&pCh->Pbuf_spinlock, flags);
1868 rc += pCh->Pbuf_stuff;
1869 read_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1870 return rc;
1873 /******************************************************************************/
1874 /* Function: ip2_flush_buffer() */
1875 /* Parameters: Pointer to tty structure */
1876 /* Returns: Nothing */
1877 /* */
1878 /* Description: */
1879 /* */
1880 /* */
1881 /******************************************************************************/
1882 static void
1883 ip2_flush_buffer( PTTY tty )
1885 i2ChanStrPtr pCh = tty->driver_data;
1886 unsigned long flags;
1888 ip2trace (CHANN, ITRC_FLUSH, ITRC_ENTER, 0 );
1890 #ifdef IP2DEBUG_WRITE
1891 printk (KERN_DEBUG "IP2: flush buffer\n" );
1892 #endif
1893 write_lock_irqsave(&pCh->Pbuf_spinlock, flags);
1894 pCh->Pbuf_stuff = 0;
1895 write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1896 i2FlushOutput( pCh );
1897 ip2_owake(tty);
1899 ip2trace (CHANN, ITRC_FLUSH, ITRC_RETURN, 0 );
1903 /******************************************************************************/
1904 /* Function: ip2_wait_until_sent() */
1905 /* Parameters: Pointer to tty structure */
1906 /* Timeout for wait. */
1907 /* Returns: Nothing */
1908 /* */
1909 /* Description: */
1910 /* This function is used in place of the normal tty_wait_until_sent, which */
1911 /* only waits for the driver buffers to be empty (or rather, those buffers */
1912 /* reported by chars_in_buffer) which doesn't work for IP2 due to the */
1913 /* indeterminate number of bytes buffered on the board. */
1914 /******************************************************************************/
1915 static void
1916 ip2_wait_until_sent ( PTTY tty, int timeout )
1918 int i = jiffies;
1919 i2ChanStrPtr pCh = tty->driver_data;
1921 tty_wait_until_sent(tty, timeout );
1922 if ( (i = timeout - (jiffies -i)) > 0)
1923 i2DrainOutput( pCh, i );
1926 /******************************************************************************/
1927 /******************************************************************************/
1928 /* Device Input Section */
1929 /******************************************************************************/
1930 /******************************************************************************/
1932 /******************************************************************************/
1933 /* Function: ip2_throttle() */
1934 /* Parameters: Pointer to tty structure */
1935 /* Returns: Nothing */
1936 /* */
1937 /* Description: */
1938 /* */
1939 /* */
1940 /******************************************************************************/
1941 static void
1942 ip2_throttle ( PTTY tty )
1944 i2ChanStrPtr pCh = tty->driver_data;
1946 #ifdef IP2DEBUG_READ
1947 printk (KERN_DEBUG "IP2: throttle\n" );
1948 #endif
1950 * Signal the poll/interrupt handlers not to forward incoming data to
1951 * the line discipline. This will cause the buffers to fill up in the
1952 * library and thus cause the library routines to send the flow control
1953 * stuff.
1955 pCh->throttled = 1;
1958 /******************************************************************************/
1959 /* Function: ip2_unthrottle() */
1960 /* Parameters: Pointer to tty structure */
1961 /* Returns: Nothing */
1962 /* */
1963 /* Description: */
1964 /* */
1965 /* */
1966 /******************************************************************************/
1967 static void
1968 ip2_unthrottle ( PTTY tty )
1970 i2ChanStrPtr pCh = tty->driver_data;
1971 unsigned long flags;
1973 #ifdef IP2DEBUG_READ
1974 printk (KERN_DEBUG "IP2: unthrottle\n" );
1975 #endif
1977 /* Pass incoming data up to the line discipline again. */
1978 pCh->throttled = 0;
1979 i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_RESUME);
1980 serviceOutgoingFifo( pCh->pMyBord );
1981 read_lock_irqsave(&pCh->Ibuf_spinlock, flags);
1982 if ( pCh->Ibuf_stuff != pCh->Ibuf_strip ) {
1983 read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags);
1984 #ifdef IP2DEBUG_READ
1985 printk (KERN_DEBUG "i2Input called from unthrottle\n" );
1986 #endif
1987 i2Input( pCh );
1988 } else
1989 read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags);
1992 static void
1993 ip2_start ( PTTY tty )
1995 i2ChanStrPtr pCh = DevTable[tty->index];
1997 i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_RESUME);
1998 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_UNSUSPEND);
1999 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_RESUME);
2000 #ifdef IP2DEBUG_WRITE
2001 printk (KERN_DEBUG "IP2: start tx\n" );
2002 #endif
2005 static void
2006 ip2_stop ( PTTY tty )
2008 i2ChanStrPtr pCh = DevTable[tty->index];
2010 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_SUSPEND);
2011 #ifdef IP2DEBUG_WRITE
2012 printk (KERN_DEBUG "IP2: stop tx\n" );
2013 #endif
2016 /******************************************************************************/
2017 /* Device Ioctl Section */
2018 /******************************************************************************/
2020 static int ip2_tiocmget(struct tty_struct *tty, struct file *file)
2022 i2ChanStrPtr pCh = DevTable[tty->index];
2023 #ifdef ENABLE_DSSNOW
2024 wait_queue_t wait;
2025 #endif
2027 if (pCh == NULL)
2028 return -ENODEV;
2031 FIXME - the following code is causing a NULL pointer dereference in
2032 2.3.51 in an interrupt handler. It's suppose to prompt the board
2033 to return the DSS signal status immediately. Why doesn't it do
2034 the same thing in 2.2.14?
2037 /* This thing is still busted in the 1.2.12 driver on 2.4.x
2038 and even hoses the serial console so the oops can be trapped.
2039 /\/\|=mhw=|\/\/ */
2041 #ifdef ENABLE_DSSNOW
2042 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DSS_NOW);
2044 init_waitqueue_entry(&wait, current);
2045 add_wait_queue(&pCh->dss_now_wait, &wait);
2046 set_current_state( TASK_INTERRUPTIBLE );
2048 serviceOutgoingFifo( pCh->pMyBord );
2050 schedule();
2052 set_current_state( TASK_RUNNING );
2053 remove_wait_queue(&pCh->dss_now_wait, &wait);
2055 if (signal_pending(current)) {
2056 return -EINTR;
2058 #endif
2059 return ((pCh->dataSetOut & I2_RTS) ? TIOCM_RTS : 0)
2060 | ((pCh->dataSetOut & I2_DTR) ? TIOCM_DTR : 0)
2061 | ((pCh->dataSetIn & I2_DCD) ? TIOCM_CAR : 0)
2062 | ((pCh->dataSetIn & I2_RI) ? TIOCM_RNG : 0)
2063 | ((pCh->dataSetIn & I2_DSR) ? TIOCM_DSR : 0)
2064 | ((pCh->dataSetIn & I2_CTS) ? TIOCM_CTS : 0);
2067 static int ip2_tiocmset(struct tty_struct *tty, struct file *file,
2068 unsigned int set, unsigned int clear)
2070 i2ChanStrPtr pCh = DevTable[tty->index];
2072 if (pCh == NULL)
2073 return -ENODEV;
2075 if (set & TIOCM_RTS) {
2076 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_RTSUP);
2077 pCh->dataSetOut |= I2_RTS;
2079 if (set & TIOCM_DTR) {
2080 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DTRUP);
2081 pCh->dataSetOut |= I2_DTR;
2084 if (clear & TIOCM_RTS) {
2085 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_RTSDN);
2086 pCh->dataSetOut &= ~I2_RTS;
2088 if (clear & TIOCM_DTR) {
2089 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DTRDN);
2090 pCh->dataSetOut &= ~I2_DTR;
2092 serviceOutgoingFifo( pCh->pMyBord );
2093 return 0;
2096 /******************************************************************************/
2097 /* Function: ip2_ioctl() */
2098 /* Parameters: Pointer to tty structure */
2099 /* Pointer to file structure */
2100 /* Command */
2101 /* Argument */
2102 /* Returns: Success or failure */
2103 /* */
2104 /* Description: */
2105 /* */
2106 /* */
2107 /******************************************************************************/
2108 static int
2109 ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg )
2111 wait_queue_t wait;
2112 i2ChanStrPtr pCh = DevTable[tty->index];
2113 i2eBordStrPtr pB;
2114 struct async_icount cprev, cnow; /* kernel counter temps */
2115 struct serial_icounter_struct __user *p_cuser;
2116 int rc = 0;
2117 unsigned long flags;
2118 void __user *argp = (void __user *)arg;
2120 if ( pCh == NULL )
2121 return -ENODEV;
2123 pB = pCh->pMyBord;
2125 ip2trace (CHANN, ITRC_IOCTL, ITRC_ENTER, 2, cmd, arg );
2127 #ifdef IP2DEBUG_IOCTL
2128 printk(KERN_DEBUG "IP2: ioctl cmd (%x), arg (%lx)\n", cmd, arg );
2129 #endif
2131 switch(cmd) {
2132 case TIOCGSERIAL:
2134 ip2trace (CHANN, ITRC_IOCTL, 2, 1, rc );
2136 rc = get_serial_info(pCh, argp);
2137 if (rc)
2138 return rc;
2139 break;
2141 case TIOCSSERIAL:
2143 ip2trace (CHANN, ITRC_IOCTL, 3, 1, rc );
2145 rc = set_serial_info(pCh, argp);
2146 if (rc)
2147 return rc;
2148 break;
2150 case TCXONC:
2151 rc = tty_check_change(tty);
2152 if (rc)
2153 return rc;
2154 switch (arg) {
2155 case TCOOFF:
2156 //return -ENOIOCTLCMD;
2157 break;
2158 case TCOON:
2159 //return -ENOIOCTLCMD;
2160 break;
2161 case TCIOFF:
2162 if (STOP_CHAR(tty) != __DISABLED_CHAR) {
2163 i2QueueCommands( PTYPE_BYPASS, pCh, 100, 1,
2164 CMD_XMIT_NOW(STOP_CHAR(tty)));
2166 break;
2167 case TCION:
2168 if (START_CHAR(tty) != __DISABLED_CHAR) {
2169 i2QueueCommands( PTYPE_BYPASS, pCh, 100, 1,
2170 CMD_XMIT_NOW(START_CHAR(tty)));
2172 break;
2173 default:
2174 return -EINVAL;
2176 return 0;
2178 case TCSBRK: /* SVID version: non-zero arg --> no break */
2179 rc = tty_check_change(tty);
2181 ip2trace (CHANN, ITRC_IOCTL, 4, 1, rc );
2183 if (!rc) {
2184 ip2_wait_until_sent(tty,0);
2185 if (!arg) {
2186 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_SEND_BRK(250));
2187 serviceOutgoingFifo( pCh->pMyBord );
2190 break;
2192 case TCSBRKP: /* support for POSIX tcsendbreak() */
2193 rc = tty_check_change(tty);
2195 ip2trace (CHANN, ITRC_IOCTL, 5, 1, rc );
2197 if (!rc) {
2198 ip2_wait_until_sent(tty,0);
2199 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1,
2200 CMD_SEND_BRK(arg ? arg*100 : 250));
2201 serviceOutgoingFifo ( pCh->pMyBord );
2203 break;
2205 case TIOCGSOFTCAR:
2207 ip2trace (CHANN, ITRC_IOCTL, 6, 1, rc );
2209 rc = put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *)argp);
2210 if (rc)
2211 return rc;
2212 break;
2214 case TIOCSSOFTCAR:
2216 ip2trace (CHANN, ITRC_IOCTL, 7, 1, rc );
2218 rc = get_user(arg,(unsigned long __user *) argp);
2219 if (rc)
2220 return rc;
2221 tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL)
2222 | (arg ? CLOCAL : 0));
2224 break;
2227 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change - mask
2228 * passed in arg for lines of interest (use |'ed TIOCM_RNG/DSR/CD/CTS
2229 * for masking). Caller should use TIOCGICOUNT to see which one it was
2231 case TIOCMIWAIT:
2232 write_lock_irqsave(&pB->read_fifo_spinlock, flags);
2233 cprev = pCh->icount; /* note the counters on entry */
2234 write_unlock_irqrestore(&pB->read_fifo_spinlock, flags);
2235 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 4,
2236 CMD_DCD_REP, CMD_CTS_REP, CMD_DSR_REP, CMD_RI_REP);
2237 init_waitqueue_entry(&wait, current);
2238 add_wait_queue(&pCh->delta_msr_wait, &wait);
2239 set_current_state( TASK_INTERRUPTIBLE );
2241 serviceOutgoingFifo( pCh->pMyBord );
2242 for(;;) {
2243 ip2trace (CHANN, ITRC_IOCTL, 10, 0 );
2245 schedule();
2247 ip2trace (CHANN, ITRC_IOCTL, 11, 0 );
2249 /* see if a signal did it */
2250 if (signal_pending(current)) {
2251 rc = -ERESTARTSYS;
2252 break;
2254 write_lock_irqsave(&pB->read_fifo_spinlock, flags);
2255 cnow = pCh->icount; /* atomic copy */
2256 write_unlock_irqrestore(&pB->read_fifo_spinlock, flags);
2257 if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
2258 cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) {
2259 rc = -EIO; /* no change => rc */
2260 break;
2262 if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
2263 ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
2264 ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
2265 ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
2266 rc = 0;
2267 break;
2269 cprev = cnow;
2271 set_current_state( TASK_RUNNING );
2272 remove_wait_queue(&pCh->delta_msr_wait, &wait);
2274 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 3,
2275 CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);
2276 if ( ! (pCh->flags & ASYNC_CHECK_CD)) {
2277 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DCD_NREP);
2279 serviceOutgoingFifo( pCh->pMyBord );
2280 return rc;
2281 break;
2284 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
2285 * Return: write counters to the user passed counter struct
2286 * NB: both 1->0 and 0->1 transitions are counted except for RI where
2287 * only 0->1 is counted. The controller is quite capable of counting
2288 * both, but this done to preserve compatibility with the standard
2289 * serial driver.
2291 case TIOCGICOUNT:
2292 ip2trace (CHANN, ITRC_IOCTL, 11, 1, rc );
2294 write_lock_irqsave(&pB->read_fifo_spinlock, flags);
2295 cnow = pCh->icount;
2296 write_unlock_irqrestore(&pB->read_fifo_spinlock, flags);
2297 p_cuser = argp;
2298 rc = put_user(cnow.cts, &p_cuser->cts);
2299 rc = put_user(cnow.dsr, &p_cuser->dsr);
2300 rc = put_user(cnow.rng, &p_cuser->rng);
2301 rc = put_user(cnow.dcd, &p_cuser->dcd);
2302 rc = put_user(cnow.rx, &p_cuser->rx);
2303 rc = put_user(cnow.tx, &p_cuser->tx);
2304 rc = put_user(cnow.frame, &p_cuser->frame);
2305 rc = put_user(cnow.overrun, &p_cuser->overrun);
2306 rc = put_user(cnow.parity, &p_cuser->parity);
2307 rc = put_user(cnow.brk, &p_cuser->brk);
2308 rc = put_user(cnow.buf_overrun, &p_cuser->buf_overrun);
2309 break;
2312 * The rest are not supported by this driver. By returning -ENOIOCTLCMD they
2313 * will be passed to the line discipline for it to handle.
2315 case TIOCSERCONFIG:
2316 case TIOCSERGWILD:
2317 case TIOCSERGETLSR:
2318 case TIOCSERSWILD:
2319 case TIOCSERGSTRUCT:
2320 case TIOCSERGETMULTI:
2321 case TIOCSERSETMULTI:
2323 default:
2324 ip2trace (CHANN, ITRC_IOCTL, 12, 0 );
2326 rc = -ENOIOCTLCMD;
2327 break;
2330 ip2trace (CHANN, ITRC_IOCTL, ITRC_RETURN, 0 );
2332 return rc;
2335 /******************************************************************************/
2336 /* Function: GetSerialInfo() */
2337 /* Parameters: Pointer to channel structure */
2338 /* Pointer to old termios structure */
2339 /* Returns: Nothing */
2340 /* */
2341 /* Description: */
2342 /* This is to support the setserial command, and requires processing of the */
2343 /* standard Linux serial structure. */
2344 /******************************************************************************/
2345 static int
2346 get_serial_info ( i2ChanStrPtr pCh, struct serial_struct __user *retinfo )
2348 struct serial_struct tmp;
2350 memset ( &tmp, 0, sizeof(tmp) );
2351 tmp.type = pCh->pMyBord->channelBtypes.bid_value[(pCh->port_index & (IP2_PORTS_PER_BOARD-1))/16];
2352 if (BID_HAS_654(tmp.type)) {
2353 tmp.type = PORT_16650;
2354 } else {
2355 tmp.type = PORT_CIRRUS;
2357 tmp.line = pCh->port_index;
2358 tmp.port = pCh->pMyBord->i2eBase;
2359 tmp.irq = ip2config.irq[pCh->port_index/64];
2360 tmp.flags = pCh->flags;
2361 tmp.baud_base = pCh->BaudBase;
2362 tmp.close_delay = pCh->ClosingDelay;
2363 tmp.closing_wait = pCh->ClosingWaitTime;
2364 tmp.custom_divisor = pCh->BaudDivisor;
2365 return copy_to_user(retinfo,&tmp,sizeof(*retinfo));
2368 /******************************************************************************/
2369 /* Function: SetSerialInfo() */
2370 /* Parameters: Pointer to channel structure */
2371 /* Pointer to old termios structure */
2372 /* Returns: Nothing */
2373 /* */
2374 /* Description: */
2375 /* This function provides support for setserial, which uses the TIOCSSERIAL */
2376 /* ioctl. Not all setserial parameters are relevant. If the user attempts to */
2377 /* change the IRQ, address or type of the port the ioctl fails. */
2378 /******************************************************************************/
2379 static int
2380 set_serial_info( i2ChanStrPtr pCh, struct serial_struct __user *new_info )
2382 struct serial_struct ns;
2383 int old_flags, old_baud_divisor;
2385 if (copy_from_user(&ns, new_info, sizeof (ns)))
2386 return -EFAULT;
2389 * We don't allow setserial to change IRQ, board address, type or baud
2390 * base. Also line nunber as such is meaningless but we use it for our
2391 * array index so it is fixed also.
2393 if ( (ns.irq != ip2config.irq[pCh->port_index])
2394 || ((int) ns.port != ((int) (pCh->pMyBord->i2eBase)))
2395 || (ns.baud_base != pCh->BaudBase)
2396 || (ns.line != pCh->port_index) ) {
2397 return -EINVAL;
2400 old_flags = pCh->flags;
2401 old_baud_divisor = pCh->BaudDivisor;
2403 if ( !capable(CAP_SYS_ADMIN) ) {
2404 if ( ( ns.close_delay != pCh->ClosingDelay ) ||
2405 ( (ns.flags & ~ASYNC_USR_MASK) !=
2406 (pCh->flags & ~ASYNC_USR_MASK) ) ) {
2407 return -EPERM;
2410 pCh->flags = (pCh->flags & ~ASYNC_USR_MASK) |
2411 (ns.flags & ASYNC_USR_MASK);
2412 pCh->BaudDivisor = ns.custom_divisor;
2413 } else {
2414 pCh->flags = (pCh->flags & ~ASYNC_FLAGS) |
2415 (ns.flags & ASYNC_FLAGS);
2416 pCh->BaudDivisor = ns.custom_divisor;
2417 pCh->ClosingDelay = ns.close_delay * HZ/100;
2418 pCh->ClosingWaitTime = ns.closing_wait * HZ/100;
2421 if ( ( (old_flags & ASYNC_SPD_MASK) != (pCh->flags & ASYNC_SPD_MASK) )
2422 || (old_baud_divisor != pCh->BaudDivisor) ) {
2423 // Invalidate speed and reset parameters
2424 set_params( pCh, NULL );
2427 return 0;
2430 /******************************************************************************/
2431 /* Function: ip2_set_termios() */
2432 /* Parameters: Pointer to tty structure */
2433 /* Pointer to old termios structure */
2434 /* Returns: Nothing */
2435 /* */
2436 /* Description: */
2437 /* */
2438 /* */
2439 /******************************************************************************/
2440 static void
2441 ip2_set_termios( PTTY tty, struct ktermios *old_termios )
2443 i2ChanStrPtr pCh = (i2ChanStrPtr)tty->driver_data;
2445 #ifdef IP2DEBUG_IOCTL
2446 printk (KERN_DEBUG "IP2: set termios %p\n", old_termios );
2447 #endif
2449 set_params( pCh, old_termios );
2452 /******************************************************************************/
2453 /* Function: ip2_set_line_discipline() */
2454 /* Parameters: Pointer to tty structure */
2455 /* Returns: Nothing */
2456 /* */
2457 /* Description: Does nothing */
2458 /* */
2459 /* */
2460 /******************************************************************************/
2461 static void
2462 ip2_set_line_discipline ( PTTY tty )
2464 #ifdef IP2DEBUG_IOCTL
2465 printk (KERN_DEBUG "IP2: set line discipline\n" );
2466 #endif
2468 ip2trace (((i2ChanStrPtr)tty->driver_data)->port_index, ITRC_IOCTL, 16, 0 );
2472 /******************************************************************************/
2473 /* Function: SetLine Characteristics() */
2474 /* Parameters: Pointer to channel structure */
2475 /* Returns: Nothing */
2476 /* */
2477 /* Description: */
2478 /* This routine is called to update the channel structure with the new line */
2479 /* characteristics, and send the appropriate commands to the board when they */
2480 /* change. */
2481 /******************************************************************************/
2482 static void
2483 set_params( i2ChanStrPtr pCh, struct ktermios *o_tios )
2485 tcflag_t cflag, iflag, lflag;
2486 char stop_char, start_char;
2487 struct ktermios dummy;
2489 lflag = pCh->pTTY->termios->c_lflag;
2490 cflag = pCh->pTTY->termios->c_cflag;
2491 iflag = pCh->pTTY->termios->c_iflag;
2493 if (o_tios == NULL) {
2494 dummy.c_lflag = ~lflag;
2495 dummy.c_cflag = ~cflag;
2496 dummy.c_iflag = ~iflag;
2497 o_tios = &dummy;
2501 switch ( cflag & CBAUD ) {
2502 case B0:
2503 i2QueueCommands( PTYPE_BYPASS, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN);
2504 pCh->dataSetOut &= ~(I2_DTR | I2_RTS);
2505 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25));
2506 pCh->pTTY->termios->c_cflag |= (CBAUD & o_tios->c_cflag);
2507 goto service_it;
2508 break;
2509 case B38400:
2511 * This is the speed that is overloaded with all the other high
2512 * speeds, depending upon the flag settings.
2514 if ( ( pCh->flags & ASYNC_SPD_MASK ) == ASYNC_SPD_HI ) {
2515 pCh->speed = CBR_57600;
2516 } else if ( (pCh->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI ) {
2517 pCh->speed = CBR_115200;
2518 } else if ( (pCh->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST ) {
2519 pCh->speed = CBR_C1;
2520 } else {
2521 pCh->speed = CBR_38400;
2523 break;
2524 case B50: pCh->speed = CBR_50; break;
2525 case B75: pCh->speed = CBR_75; break;
2526 case B110: pCh->speed = CBR_110; break;
2527 case B134: pCh->speed = CBR_134; break;
2528 case B150: pCh->speed = CBR_150; break;
2529 case B200: pCh->speed = CBR_200; break;
2530 case B300: pCh->speed = CBR_300; break;
2531 case B600: pCh->speed = CBR_600; break;
2532 case B1200: pCh->speed = CBR_1200; break;
2533 case B1800: pCh->speed = CBR_1800; break;
2534 case B2400: pCh->speed = CBR_2400; break;
2535 case B4800: pCh->speed = CBR_4800; break;
2536 case B9600: pCh->speed = CBR_9600; break;
2537 case B19200: pCh->speed = CBR_19200; break;
2538 case B57600: pCh->speed = CBR_57600; break;
2539 case B115200: pCh->speed = CBR_115200; break;
2540 case B153600: pCh->speed = CBR_153600; break;
2541 case B230400: pCh->speed = CBR_230400; break;
2542 case B307200: pCh->speed = CBR_307200; break;
2543 case B460800: pCh->speed = CBR_460800; break;
2544 case B921600: pCh->speed = CBR_921600; break;
2545 default: pCh->speed = CBR_9600; break;
2547 if ( pCh->speed == CBR_C1 ) {
2548 // Process the custom speed parameters.
2549 int bps = pCh->BaudBase / pCh->BaudDivisor;
2550 if ( bps == 921600 ) {
2551 pCh->speed = CBR_921600;
2552 } else {
2553 bps = bps/10;
2554 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_BAUD_DEF1(bps) );
2557 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_SETBAUD(pCh->speed));
2559 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 2, CMD_DTRUP, CMD_RTSUP);
2560 pCh->dataSetOut |= (I2_DTR | I2_RTS);
2562 if ( (CSTOPB & cflag) ^ (CSTOPB & o_tios->c_cflag))
2564 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1,
2565 CMD_SETSTOP( ( cflag & CSTOPB ) ? CST_2 : CST_1));
2567 if (((PARENB|PARODD) & cflag) ^ ((PARENB|PARODD) & o_tios->c_cflag))
2569 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1,
2570 CMD_SETPAR(
2571 (cflag & PARENB ? (cflag & PARODD ? CSP_OD : CSP_EV) : CSP_NP)
2575 /* byte size and parity */
2576 if ( (CSIZE & cflag)^(CSIZE & o_tios->c_cflag))
2578 int datasize;
2579 switch ( cflag & CSIZE ) {
2580 case CS5: datasize = CSZ_5; break;
2581 case CS6: datasize = CSZ_6; break;
2582 case CS7: datasize = CSZ_7; break;
2583 case CS8: datasize = CSZ_8; break;
2584 default: datasize = CSZ_5; break; /* as per serial.c */
2586 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1, CMD_SETBITS(datasize) );
2588 /* Process CTS flow control flag setting */
2589 if ( (cflag & CRTSCTS) ) {
2590 i2QueueCommands(PTYPE_INLINE, pCh, 100,
2591 2, CMD_CTSFL_ENAB, CMD_RTSFL_ENAB);
2592 } else {
2593 i2QueueCommands(PTYPE_INLINE, pCh, 100,
2594 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB);
2597 // Process XON/XOFF flow control flags settings
2599 stop_char = STOP_CHAR(pCh->pTTY);
2600 start_char = START_CHAR(pCh->pTTY);
2602 //////////// can't be \000
2603 if (stop_char == __DISABLED_CHAR )
2605 stop_char = ~__DISABLED_CHAR;
2607 if (start_char == __DISABLED_CHAR )
2609 start_char = ~__DISABLED_CHAR;
2611 /////////////////////////////////
2613 if ( o_tios->c_cc[VSTART] != start_char )
2615 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DEF_IXON(start_char));
2616 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DEF_OXON(start_char));
2618 if ( o_tios->c_cc[VSTOP] != stop_char )
2620 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DEF_IXOFF(stop_char));
2621 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DEF_OXOFF(stop_char));
2623 if (stop_char == __DISABLED_CHAR )
2625 stop_char = ~__DISABLED_CHAR; //TEST123
2626 goto no_xoff;
2628 if ((iflag & (IXOFF))^(o_tios->c_iflag & (IXOFF)))
2630 if ( iflag & IXOFF ) { // Enable XOFF output flow control
2631 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_OXON_OPT(COX_XON));
2632 } else { // Disable XOFF output flow control
2633 no_xoff:
2634 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_OXON_OPT(COX_NONE));
2637 if (start_char == __DISABLED_CHAR )
2639 goto no_xon;
2641 if ((iflag & (IXON|IXANY)) ^ (o_tios->c_iflag & (IXON|IXANY)))
2643 if ( iflag & IXON ) {
2644 if ( iflag & IXANY ) { // Enable XON/XANY output flow control
2645 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_XANY));
2646 } else { // Enable XON output flow control
2647 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_XON));
2649 } else { // Disable XON output flow control
2650 no_xon:
2651 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_NONE));
2654 if ( (iflag & ISTRIP) ^ ( o_tios->c_iflag & (ISTRIP)) )
2656 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1,
2657 CMD_ISTRIP_OPT((iflag & ISTRIP ? 1 : 0)));
2659 if ( (iflag & INPCK) ^ ( o_tios->c_iflag & (INPCK)) )
2661 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1,
2662 CMD_PARCHK((iflag & INPCK) ? CPK_ENAB : CPK_DSAB));
2665 if ( (iflag & (IGNBRK|PARMRK|BRKINT|IGNPAR))
2666 ^ ( o_tios->c_iflag & (IGNBRK|PARMRK|BRKINT|IGNPAR)) )
2668 char brkrpt = 0;
2669 char parrpt = 0;
2671 if ( iflag & IGNBRK ) { /* Ignore breaks altogether */
2672 /* Ignore breaks altogether */
2673 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_BRK_NREP);
2674 } else {
2675 if ( iflag & BRKINT ) {
2676 if ( iflag & PARMRK ) {
2677 brkrpt = 0x0a; // exception an inline triple
2678 } else {
2679 brkrpt = 0x1a; // exception and NULL
2681 brkrpt |= 0x04; // flush input
2682 } else {
2683 if ( iflag & PARMRK ) {
2684 brkrpt = 0x0b; //POSIX triple \0377 \0 \0
2685 } else {
2686 brkrpt = 0x01; // Null only
2689 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_BRK_REP(brkrpt));
2692 if (iflag & IGNPAR) {
2693 parrpt = 0x20;
2694 /* would be 2 for not cirrus bug */
2695 /* would be 0x20 cept for cirrus bug */
2696 } else {
2697 if ( iflag & PARMRK ) {
2699 * Replace error characters with 3-byte sequence (\0377,\0,char)
2701 parrpt = 0x04 ;
2702 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_ISTRIP_OPT((char)0));
2703 } else {
2704 parrpt = 0x03;
2707 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_SET_ERROR(parrpt));
2709 if (cflag & CLOCAL) {
2710 // Status reporting fails for DCD if this is off
2711 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DCD_NREP);
2712 pCh->flags &= ~ASYNC_CHECK_CD;
2713 } else {
2714 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DCD_REP);
2715 pCh->flags |= ASYNC_CHECK_CD;
2718 service_it:
2719 i2DrainOutput( pCh, 100 );
2722 /******************************************************************************/
2723 /* IPL Device Section */
2724 /******************************************************************************/
2726 /******************************************************************************/
2727 /* Function: ip2_ipl_read() */
2728 /* Parameters: Pointer to device inode */
2729 /* Pointer to file structure */
2730 /* Pointer to data */
2731 /* Number of bytes to read */
2732 /* Returns: Success or failure */
2733 /* */
2734 /* Description: Ugly */
2735 /* */
2736 /* */
2737 /******************************************************************************/
2739 static
2740 ssize_t
2741 ip2_ipl_read(struct file *pFile, char __user *pData, size_t count, loff_t *off )
2743 unsigned int minor = iminor(pFile->f_path.dentry->d_inode);
2744 int rc = 0;
2746 #ifdef IP2DEBUG_IPL
2747 printk (KERN_DEBUG "IP2IPL: read %p, %d bytes\n", pData, count );
2748 #endif
2750 switch( minor ) {
2751 case 0: // IPL device
2752 rc = -EINVAL;
2753 break;
2754 case 1: // Status dump
2755 rc = -EINVAL;
2756 break;
2757 case 2: // Ping device
2758 rc = -EINVAL;
2759 break;
2760 case 3: // Trace device
2761 rc = DumpTraceBuffer ( pData, count );
2762 break;
2763 case 4: // Trace device
2764 rc = DumpFifoBuffer ( pData, count );
2765 break;
2766 default:
2767 rc = -ENODEV;
2768 break;
2770 return rc;
2773 static int
2774 DumpFifoBuffer ( char __user *pData, int count )
2776 #ifdef DEBUG_FIFO
2777 int rc;
2778 rc = copy_to_user(pData, DBGBuf, count);
2780 printk(KERN_DEBUG "Last index %d\n", I );
2782 return count;
2783 #endif /* DEBUG_FIFO */
2784 return 0;
2787 static int
2788 DumpTraceBuffer ( char __user *pData, int count )
2790 #ifdef IP2DEBUG_TRACE
2791 int rc;
2792 int dumpcount;
2793 int chunk;
2794 int *pIndex = (int __user *)pData;
2796 if ( count < (sizeof(int) * 6) ) {
2797 return -EIO;
2799 rc = put_user(tracewrap, pIndex );
2800 rc = put_user(TRACEMAX, ++pIndex );
2801 rc = put_user(tracestrip, ++pIndex );
2802 rc = put_user(tracestuff, ++pIndex );
2803 pData += sizeof(int) * 6;
2804 count -= sizeof(int) * 6;
2806 dumpcount = tracestuff - tracestrip;
2807 if ( dumpcount < 0 ) {
2808 dumpcount += TRACEMAX;
2810 if ( dumpcount > count ) {
2811 dumpcount = count;
2813 chunk = TRACEMAX - tracestrip;
2814 if ( dumpcount > chunk ) {
2815 rc = copy_to_user(pData, &tracebuf[tracestrip],
2816 chunk * sizeof(tracebuf[0]) );
2817 pData += chunk * sizeof(tracebuf[0]);
2818 tracestrip = 0;
2819 chunk = dumpcount - chunk;
2820 } else {
2821 chunk = dumpcount;
2823 rc = copy_to_user(pData, &tracebuf[tracestrip],
2824 chunk * sizeof(tracebuf[0]) );
2825 tracestrip += chunk;
2826 tracewrap = 0;
2828 rc = put_user(tracestrip, ++pIndex );
2829 rc = put_user(tracestuff, ++pIndex );
2831 return dumpcount;
2832 #else
2833 return 0;
2834 #endif
2837 /******************************************************************************/
2838 /* Function: ip2_ipl_write() */
2839 /* Parameters: */
2840 /* Pointer to file structure */
2841 /* Pointer to data */
2842 /* Number of bytes to write */
2843 /* Returns: Success or failure */
2844 /* */
2845 /* Description: */
2846 /* */
2847 /* */
2848 /******************************************************************************/
2849 static ssize_t
2850 ip2_ipl_write(struct file *pFile, const char __user *pData, size_t count, loff_t *off)
2852 #ifdef IP2DEBUG_IPL
2853 printk (KERN_DEBUG "IP2IPL: write %p, %d bytes\n", pData, count );
2854 #endif
2855 return 0;
2858 /******************************************************************************/
2859 /* Function: ip2_ipl_ioctl() */
2860 /* Parameters: Pointer to device inode */
2861 /* Pointer to file structure */
2862 /* Command */
2863 /* Argument */
2864 /* Returns: Success or failure */
2865 /* */
2866 /* Description: */
2867 /* */
2868 /* */
2869 /******************************************************************************/
2870 static long
2871 ip2_ipl_ioctl (struct file *pFile, UINT cmd, ULONG arg )
2873 unsigned int iplminor = iminor(pFile->f_path.dentry->d_inode);
2874 int rc = 0;
2875 void __user *argp = (void __user *)arg;
2876 ULONG __user *pIndex = argp;
2877 i2eBordStrPtr pB = i2BoardPtrTable[iplminor / 4];
2878 i2ChanStrPtr pCh;
2880 #ifdef IP2DEBUG_IPL
2881 printk (KERN_DEBUG "IP2IPL: ioctl cmd %d, arg %ld\n", cmd, arg );
2882 #endif
2884 lock_kernel();
2886 switch ( iplminor ) {
2887 case 0: // IPL device
2888 rc = -EINVAL;
2889 break;
2890 case 1: // Status dump
2891 case 5:
2892 case 9:
2893 case 13:
2894 switch ( cmd ) {
2895 case 64: /* Driver - ip2stat */
2896 rc = put_user(-1, pIndex++ );
2897 rc = put_user(irq_counter, pIndex++ );
2898 rc = put_user(bh_counter, pIndex++ );
2899 break;
2901 case 65: /* Board - ip2stat */
2902 if ( pB ) {
2903 rc = copy_to_user(argp, pB, sizeof(i2eBordStr));
2904 rc = put_user(inb(pB->i2eStatus),
2905 (ULONG __user *)(arg + (ULONG)(&pB->i2eStatus) - (ULONG)pB ) );
2906 } else {
2907 rc = -ENODEV;
2909 break;
2911 default:
2912 if (cmd < IP2_MAX_PORTS) {
2913 pCh = DevTable[cmd];
2914 if ( pCh )
2916 rc = copy_to_user(argp, pCh, sizeof(i2ChanStr));
2917 } else {
2918 rc = -ENODEV;
2920 } else {
2921 rc = -EINVAL;
2924 break;
2926 case 2: // Ping device
2927 rc = -EINVAL;
2928 break;
2929 case 3: // Trace device
2931 * akpm: This used to write a whole bunch of function addresses
2932 * to userspace, which generated lots of put_user() warnings.
2933 * I killed it all. Just return "success" and don't do
2934 * anything.
2936 if (cmd == 1)
2937 rc = 0;
2938 else
2939 rc = -EINVAL;
2940 break;
2942 default:
2943 rc = -ENODEV;
2944 break;
2946 unlock_kernel();
2947 return rc;
2950 /******************************************************************************/
2951 /* Function: ip2_ipl_open() */
2952 /* Parameters: Pointer to device inode */
2953 /* Pointer to file structure */
2954 /* Returns: Success or failure */
2955 /* */
2956 /* Description: */
2957 /* */
2958 /* */
2959 /******************************************************************************/
2960 static int
2961 ip2_ipl_open( struct inode *pInode, struct file *pFile )
2964 #ifdef IP2DEBUG_IPL
2965 printk (KERN_DEBUG "IP2IPL: open\n" );
2966 #endif
2967 cycle_kernel_lock();
2968 return 0;
2971 static int
2972 proc_ip2mem_show(struct seq_file *m, void *v)
2974 i2eBordStrPtr pB;
2975 i2ChanStrPtr pCh;
2976 PTTY tty;
2977 int i;
2979 #define FMTLINE "%3d: 0x%08x 0x%08x 0%011o 0%011o\n"
2980 #define FMTLIN2 " 0x%04x 0x%04x tx flow 0x%x\n"
2981 #define FMTLIN3 " 0x%04x 0x%04x rc flow\n"
2983 seq_printf(m,"\n");
2985 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
2986 pB = i2BoardPtrTable[i];
2987 if ( pB ) {
2988 seq_printf(m,"board %d:\n",i);
2989 seq_printf(m,"\tFifo rem: %d mty: %x outM %x\n",
2990 pB->i2eFifoRemains,pB->i2eWaitingForEmptyFifo,pB->i2eOutMailWaiting);
2994 seq_printf(m,"#: tty flags, port flags, cflags, iflags\n");
2995 for (i=0; i < IP2_MAX_PORTS; i++) {
2996 pCh = DevTable[i];
2997 if (pCh) {
2998 tty = pCh->pTTY;
2999 if (tty && tty->count) {
3000 seq_printf(m,FMTLINE,i,(int)tty->flags,pCh->flags,
3001 tty->termios->c_cflag,tty->termios->c_iflag);
3003 seq_printf(m,FMTLIN2,
3004 pCh->outfl.asof,pCh->outfl.room,pCh->channelNeeds);
3005 seq_printf(m,FMTLIN3,pCh->infl.asof,pCh->infl.room);
3009 return 0;
3012 static int proc_ip2mem_open(struct inode *inode, struct file *file)
3014 return single_open(file, proc_ip2mem_show, NULL);
3017 static const struct file_operations ip2mem_proc_fops = {
3018 .owner = THIS_MODULE,
3019 .open = proc_ip2mem_open,
3020 .read = seq_read,
3021 .llseek = seq_lseek,
3022 .release = single_release,
3026 * This is the handler for /proc/tty/driver/ip2
3028 * This stretch of code has been largely plagerized from at least three
3029 * different sources including ip2mkdev.c and a couple of other drivers.
3030 * The bugs are all mine. :-) =mhw=
3032 static int ip2_proc_show(struct seq_file *m, void *v)
3034 int i, j, box;
3035 int boxes = 0;
3036 int ports = 0;
3037 int tports = 0;
3038 i2eBordStrPtr pB;
3039 char *sep;
3041 seq_printf(m, "ip2info: 1.0 driver: %s\n", pcVersion);
3042 seq_printf(m, "Driver: SMajor=%d CMajor=%d IMajor=%d MaxBoards=%d MaxBoxes=%d MaxPorts=%d\n",
3043 IP2_TTY_MAJOR, IP2_CALLOUT_MAJOR, IP2_IPL_MAJOR,
3044 IP2_MAX_BOARDS, ABS_MAX_BOXES, ABS_BIGGEST_BOX);
3046 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
3047 /* This need to be reset for a board by board count... */
3048 boxes = 0;
3049 pB = i2BoardPtrTable[i];
3050 if( pB ) {
3051 switch( pB->i2ePom.e.porID & ~POR_ID_RESERVED )
3053 case POR_ID_FIIEX:
3054 seq_printf(m, "Board %d: EX ports=", i);
3055 sep = "";
3056 for( box = 0; box < ABS_MAX_BOXES; ++box )
3058 ports = 0;
3060 if( pB->i2eChannelMap[box] != 0 ) ++boxes;
3061 for( j = 0; j < ABS_BIGGEST_BOX; ++j )
3063 if( pB->i2eChannelMap[box] & 1<< j ) {
3064 ++ports;
3067 seq_printf(m, "%s%d", sep, ports);
3068 sep = ",";
3069 tports += ports;
3071 seq_printf(m, " boxes=%d width=%d", boxes, pB->i2eDataWidth16 ? 16 : 8);
3072 break;
3074 case POR_ID_II_4:
3075 seq_printf(m, "Board %d: ISA-4 ports=4 boxes=1", i);
3076 tports = ports = 4;
3077 break;
3079 case POR_ID_II_8:
3080 seq_printf(m, "Board %d: ISA-8-std ports=8 boxes=1", i);
3081 tports = ports = 8;
3082 break;
3084 case POR_ID_II_8R:
3085 seq_printf(m, "Board %d: ISA-8-RJ11 ports=8 boxes=1", i);
3086 tports = ports = 8;
3087 break;
3089 default:
3090 seq_printf(m, "Board %d: unknown", i);
3091 /* Don't try and probe for minor numbers */
3092 tports = ports = 0;
3095 } else {
3096 /* Don't try and probe for minor numbers */
3097 seq_printf(m, "Board %d: vacant", i);
3098 tports = ports = 0;
3101 if( tports ) {
3102 seq_puts(m, " minors=");
3103 sep = "";
3104 for ( box = 0; box < ABS_MAX_BOXES; ++box )
3106 for ( j = 0; j < ABS_BIGGEST_BOX; ++j )
3108 if ( pB->i2eChannelMap[box] & (1 << j) )
3110 seq_printf(m, "%s%d", sep,
3111 j + ABS_BIGGEST_BOX *
3112 (box+i*ABS_MAX_BOXES));
3113 sep = ",";
3118 seq_putc(m, '\n');
3120 return 0;
3123 static int ip2_proc_open(struct inode *inode, struct file *file)
3125 return single_open(file, ip2_proc_show, NULL);
3128 static const struct file_operations ip2_proc_fops = {
3129 .owner = THIS_MODULE,
3130 .open = ip2_proc_open,
3131 .read = seq_read,
3132 .llseek = seq_lseek,
3133 .release = single_release,
3136 /******************************************************************************/
3137 /* Function: ip2trace() */
3138 /* Parameters: Value to add to trace buffer */
3139 /* Returns: Nothing */
3140 /* */
3141 /* Description: */
3142 /* */
3143 /* */
3144 /******************************************************************************/
3145 #ifdef IP2DEBUG_TRACE
3146 void
3147 ip2trace (unsigned short pn, unsigned char cat, unsigned char label, unsigned long codes, ...)
3149 long flags;
3150 unsigned long *pCode = &codes;
3151 union ip2breadcrumb bc;
3152 i2ChanStrPtr pCh;
3155 tracebuf[tracestuff++] = jiffies;
3156 if ( tracestuff == TRACEMAX ) {
3157 tracestuff = 0;
3159 if ( tracestuff == tracestrip ) {
3160 if ( ++tracestrip == TRACEMAX ) {
3161 tracestrip = 0;
3163 ++tracewrap;
3166 bc.hdr.port = 0xff & pn;
3167 bc.hdr.cat = cat;
3168 bc.hdr.codes = (unsigned char)( codes & 0xff );
3169 bc.hdr.label = label;
3170 tracebuf[tracestuff++] = bc.value;
3172 for (;;) {
3173 if ( tracestuff == TRACEMAX ) {
3174 tracestuff = 0;
3176 if ( tracestuff == tracestrip ) {
3177 if ( ++tracestrip == TRACEMAX ) {
3178 tracestrip = 0;
3180 ++tracewrap;
3183 if ( !codes-- )
3184 break;
3186 tracebuf[tracestuff++] = *++pCode;
3189 #endif
3192 MODULE_LICENSE("GPL");
3194 static struct pci_device_id ip2main_pci_tbl[] __devinitdata = {
3195 { PCI_DEVICE(PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_IP2EX) },
3199 MODULE_DEVICE_TABLE(pci, ip2main_pci_tbl);