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 *******************************************************************************/
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.
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/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.
52 // Four box EX was barfing on >128k kmalloc, made structure smaller by
53 // reducing output buffer size
56 // Device file system support (MHW)
60 // Reload of ip2 without unloading ip2main hangs system on cat of /proc/modules
64 // DCD was not reported when CLOCAL was set on call to TIOCMGET
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
85 #include <linux/config.h>
87 #include <linux/ctype.h>
88 #include <linux/string.h>
89 #include <linux/fcntl.h>
90 #include <linux/errno.h>
91 #include <linux/module.h>
92 #include <linux/signal.h>
93 #include <linux/sched.h>
94 #include <linux/devfs_fs_kernel.h>
95 #include <linux/timer.h>
96 #include <linux/interrupt.h>
97 #include <linux/pci.h>
99 #include <linux/slab.h>
100 #include <linux/major.h>
101 #include <linux/wait.h>
102 #include <linux/device.h>
104 #include <linux/tty.h>
105 #include <linux/tty_flip.h>
106 #include <linux/termios.h>
107 #include <linux/tty_driver.h>
108 #include <linux/serial.h>
109 #include <linux/ptrace.h>
110 #include <linux/ioport.h>
112 #include <linux/cdk.h>
113 #include <linux/comstats.h>
114 #include <linux/delay.h>
115 #include <linux/bitops.h>
117 #include <asm/system.h>
121 #include <linux/vmalloc.h>
122 #include <linux/init.h>
123 #include <asm/serial.h>
125 #include <asm/uaccess.h>
127 #include "./ip2/ip2types.h"
128 #include "./ip2/ip2trace.h"
129 #include "./ip2/ip2ioctl.h"
130 #include "./ip2/ip2.h"
131 #include "./ip2/i2ellis.h"
132 #include "./ip2/i2lib.h"
138 #include <linux/proc_fs.h>
140 static int ip2_read_procmem(char *, char **, off_t, int);
141 static int ip2_read_proc(char *, char **, off_t, int, int *, void * );
143 /********************/
144 /* Type Definitions */
145 /********************/
151 /* String constants to identify ourselves */
152 static char *pcName = "Computone IntelliPort Plus multiport driver";
153 static char *pcVersion = "1.2.14";
155 /* String constants for port names */
156 static char *pcDriver_name = "ip2";
157 static char *pcIpl = "ip2ipl";
159 /* Serial subtype definitions */
160 #define SERIAL_TYPE_NORMAL 1
162 // cheezy kludge or genius - you decide?
163 int ip2_loadmain(int *, int *, unsigned char *, int);
164 static unsigned char *Fip_firmware;
165 static int Fip_firmware_size;
167 /***********************/
168 /* Function Prototypes */
169 /***********************/
171 /* Global module entry functions */
173 /* Private (static) functions */
174 static int ip2_open(PTTY, struct file *);
175 static void ip2_close(PTTY, struct file *);
176 static int ip2_write(PTTY, int, const unsigned char *, int);
177 static void ip2_putchar(PTTY, unsigned char);
178 static void ip2_flush_chars(PTTY);
179 static int ip2_write_room(PTTY);
180 static int ip2_chars_in_buf(PTTY);
181 static void ip2_flush_buffer(PTTY);
182 static int ip2_ioctl(PTTY, struct file *, UINT, ULONG);
183 static void ip2_set_termios(PTTY, struct termios *);
184 static void ip2_set_line_discipline(PTTY);
185 static void ip2_throttle(PTTY);
186 static void ip2_unthrottle(PTTY);
187 static void ip2_stop(PTTY);
188 static void ip2_start(PTTY);
189 static void ip2_hangup(PTTY);
190 static int ip2_tiocmget(struct tty_struct *tty, struct file *file);
191 static int ip2_tiocmset(struct tty_struct *tty, struct file *file,
192 unsigned int set, unsigned int clear);
194 static void set_irq(int, int);
195 static void ip2_interrupt_bh(i2eBordStrPtr pB);
196 static irqreturn_t ip2_interrupt(int irq, void *dev_id, struct pt_regs * regs);
197 static void ip2_poll(unsigned long arg);
198 static inline void service_all_boards(void);
199 static void do_input(void *p);
200 static void do_status(void *p);
202 static void ip2_wait_until_sent(PTTY,int);
204 static void set_params (i2ChanStrPtr, struct termios *);
205 static int get_serial_info(i2ChanStrPtr, struct serial_struct __user *);
206 static int set_serial_info(i2ChanStrPtr, struct serial_struct __user *);
208 static ssize_t ip2_ipl_read(struct file *, char __user *, size_t, loff_t *);
209 static ssize_t ip2_ipl_write(struct file *, const char __user *, size_t, loff_t *);
210 static int ip2_ipl_ioctl(struct inode *, struct file *, UINT, ULONG);
211 static int ip2_ipl_open(struct inode *, struct file *);
213 static int DumpTraceBuffer(char __user *, int);
214 static int DumpFifoBuffer( char __user *, int);
216 static void ip2_init_board(int);
217 static unsigned short find_eisa_board(int);
223 static struct tty_driver *ip2_tty_driver;
225 /* Here, then is a table of board pointers which the interrupt routine should
226 * scan through to determine who it must service.
228 static unsigned short i2nBoards; // Number of boards here
230 static i2eBordStrPtr i2BoardPtrTable[IP2_MAX_BOARDS];
232 static i2ChanStrPtr DevTable[IP2_MAX_PORTS];
233 //DevTableMem just used to save addresses for kfree
234 static void *DevTableMem[IP2_MAX_BOARDS];
236 /* This is the driver descriptor for the ip2ipl device, which is used to
237 * download the loadware to the boards.
239 static struct file_operations ip2_ipl = {
240 .owner = THIS_MODULE,
241 .read = ip2_ipl_read,
242 .write = ip2_ipl_write,
243 .ioctl = ip2_ipl_ioctl,
244 .open = ip2_ipl_open,
247 static unsigned long irq_counter = 0;
248 static unsigned long bh_counter = 0;
250 // Use immediate queue to service interrupts
252 //#define USE_IQ // PCI&2.2 needs work
254 /* The timer_list entry for our poll routine. If interrupt operation is not
255 * selected, the board is serviced periodically to see if anything needs doing.
257 #define POLL_TIMEOUT (jiffies + 1)
258 static struct timer_list PollTimer = TIMER_INITIALIZER(ip2_poll, 0, 0);
261 #ifdef IP2DEBUG_TRACE
262 /* Trace (debug) buffer data */
263 #define TRACEMAX 1000
264 static unsigned long tracebuf[TRACEMAX];
265 static int tracestuff;
266 static int tracestrip;
267 static int tracewrap;
274 #if defined(MODULE) && defined(IP2DEBUG_OPEN)
275 #define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] refc=%d, ttyc=%d, modc=%x -> %s\n", \
276 tty->name,(pCh->flags),ip2_tty_driver->refcount, \
277 tty->count,/*GET_USE_COUNT(module)*/0,s)
286 #include "./ip2/i2ellis.c" /* Extremely low-level interface services */
287 #include "./ip2/i2cmd.c" /* Standard loadware command definitions */
288 #include "./ip2/i2lib.c" /* High level interface services */
290 /* Configuration area for modprobe */
292 MODULE_AUTHOR("Doug McNash");
293 MODULE_DESCRIPTION("Computone IntelliPort Plus Driver");
295 static int poll_only = 0;
298 static int Eisa_slot;
301 static char rirqs[IP2_MAX_BOARDS];
302 static int Valid_Irqs[] = { 3, 4, 5, 7, 10, 11, 12, 15, 0};
304 /* for sysfs class support */
305 static struct class_simple *ip2_class;
307 // Some functions to keep track of what irq's we have
310 is_valid_irq(int irq)
314 while ((*i != 0) && (*i != irq)) {
321 mark_requested_irq( char irq )
323 rirqs[iindx++] = irq;
328 clear_requested_irq( char irq )
331 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
332 if (rirqs[i] == irq) {
342 have_requested_irq( char irq )
344 // array init to zeros so 0 irq will not be requested as a side effect
346 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
353 /******************************************************************************/
354 /* Function: init_module() */
355 /* Parameters: None */
356 /* Returns: Success (0) */
359 /* This is a required entry point for an installable module. It simply calls */
360 /* the driver initialisation function and returns what it returns. */
361 /******************************************************************************/
367 printk (KERN_DEBUG "Loading module ...\n" );
373 /******************************************************************************/
374 /* Function: cleanup_module() */
375 /* Parameters: None */
376 /* Returns: Nothing */
379 /* This is a required entry point for an installable module. It has to return */
380 /* the device and the driver to a passive state. It should not be necessary */
381 /* to reset the board fully, especially as the loadware is downloaded */
382 /* externally rather than in the driver. We just want to disable the board */
383 /* and clear the loadware to a reset state. To allow this there has to be a */
384 /* way to detect whether the board has the loadware running at init time to */
385 /* handle subsequent installations of the driver. All memory allocated by the */
386 /* driver should be returned since it may be unloaded from memory. */
387 /******************************************************************************/
396 printk (KERN_DEBUG "Unloading %s: version %s\n", pcName, pcVersion );
398 /* Stop poll timer if we had one. */
400 del_timer ( &PollTimer );
404 /* Reset the boards we have. */
405 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
406 if ( i2BoardPtrTable[i] ) {
407 iiReset( i2BoardPtrTable[i] );
411 /* The following is done at most once, if any boards were installed. */
412 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
413 if ( i2BoardPtrTable[i] ) {
414 iiResetDelay( i2BoardPtrTable[i] );
415 /* free io addresses and Tibet */
416 release_region( ip2config.addr[i], 8 );
417 class_simple_device_remove(MKDEV(IP2_IPL_MAJOR, 4 * i));
418 devfs_remove("ip2/ipl%d", i);
419 class_simple_device_remove(MKDEV(IP2_IPL_MAJOR, 4 * i + 1));
420 devfs_remove("ip2/stat%d", i);
422 /* Disable and remove interrupt handler. */
423 if ( (ip2config.irq[i] > 0) && have_requested_irq(ip2config.irq[i]) ) {
424 free_irq ( ip2config.irq[i], (void *)&pcName);
425 clear_requested_irq( ip2config.irq[i]);
428 class_simple_destroy(ip2_class);
430 if ( ( err = tty_unregister_driver ( ip2_tty_driver ) ) ) {
431 printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n", err);
433 put_tty_driver(ip2_tty_driver);
434 if ( ( err = unregister_chrdev ( IP2_IPL_MAJOR, pcIpl ) ) ) {
435 printk(KERN_ERR "IP2: failed to unregister IPL driver (%d)\n", err);
437 remove_proc_entry("ip2mem", &proc_root);
440 for (i = 0; i < IP2_MAX_BOARDS; i++) {
443 if (ip2config.type[i] == PCI && ip2config.pci_dev[i]) {
444 pci_disable_device(ip2config.pci_dev[i]);
445 ip2config.pci_dev[i] = NULL;
448 if ((pB = i2BoardPtrTable[i]) != 0 ) {
450 i2BoardPtrTable[i] = NULL;
452 if ((DevTableMem[i]) != NULL ) {
453 kfree ( DevTableMem[i] );
454 DevTableMem[i] = NULL;
458 /* Cleanup the iiEllis subsystem. */
461 printk (KERN_DEBUG "IP2 Unloaded\n" );
466 static struct tty_operations ip2_ops = {
470 .put_char = ip2_putchar,
471 .flush_chars = ip2_flush_chars,
472 .write_room = ip2_write_room,
473 .chars_in_buffer = ip2_chars_in_buf,
474 .flush_buffer = ip2_flush_buffer,
476 .throttle = ip2_throttle,
477 .unthrottle = ip2_unthrottle,
478 .set_termios = ip2_set_termios,
479 .set_ldisc = ip2_set_line_discipline,
482 .hangup = ip2_hangup,
483 .read_proc = ip2_read_proc,
484 .tiocmget = ip2_tiocmget,
485 .tiocmset = ip2_tiocmset,
488 /******************************************************************************/
489 /* Function: ip2_loadmain() */
490 /* Parameters: irq, io from command line of insmod et. al. */
491 /* pointer to fip firmware and firmware size for boards */
492 /* Returns: Success (0) */
495 /* This was the required entry point for all drivers (now in ip2.c) */
496 /* It performs all */
497 /* initialisation of the devices and driver structures, and registers itself */
498 /* with the relevant kernel modules. */
499 /******************************************************************************/
500 /* SA_INTERRUPT- if set blocks all interrupts else only this line */
501 /* SA_SHIRQ - for shared irq PCI or maybe EISA only */
502 /* SA_RANDOM - can be source for cert. random number generators */
503 #define IP2_SA_FLAGS 0
506 ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize)
512 i2eBordStrPtr pB = NULL;
515 ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0 );
517 /* process command line arguments to modprobe or
518 insmod i.e. iop & irqp */
519 /* irqp and iop should ALWAYS be specified now... But we check
520 them individually just to be sure, anyways... */
521 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
523 ip2config.addr[i] = iop[i];
526 ip2config.irq[i] = irqp[i];
528 ip2config.irq[i] = 0;
530 // This is a little bit of a hack. If poll_only=1 on command
531 // line back in ip2.c OR all IRQs on all specified boards are
532 // explicitly set to 0, then drop to poll only mode and override
533 // PCI or EISA interrupts. This superceeds the old hack of
534 // triggering if all interrupts were zero (like da default).
535 // Still a hack but less prone to random acts of terrorism.
537 // What we really should do, now that the IRQ default is set
538 // to -1, is to use 0 as a hard coded, do not probe.
541 poll_only |= irqp[i];
545 poll_only = !poll_only;
547 Fip_firmware = firmware;
548 Fip_firmware_size = firmsize;
550 /* Announce our presence */
551 printk( KERN_INFO "%s version %s\n", pcName, pcVersion );
553 // ip2 can be unloaded and reloaded for no good reason
554 // we can't let that happen here or bad things happen
555 // second load hoses board but not system - fixme later
557 printk( KERN_INFO "Still loaded\n" );
562 ip2_tty_driver = alloc_tty_driver(IP2_MAX_PORTS);
566 /* Initialise the iiEllis subsystem. */
569 /* Initialize arrays. */
570 memset( i2BoardPtrTable, 0, sizeof i2BoardPtrTable );
571 memset( DevTable, 0, sizeof DevTable );
573 /* Initialise all the boards we can find (up to the maximum). */
574 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
575 switch ( ip2config.addr[i] ) {
576 case 0: /* skip this slot even if card is present */
579 /* ISA address must be specified */
580 if ( (ip2config.addr[i] < 0x100) || (ip2config.addr[i] > 0x3f8) ) {
581 printk ( KERN_ERR "IP2: Bad ISA board %d address %x\n",
582 i, ip2config.addr[i] );
583 ip2config.addr[i] = 0;
585 ip2config.type[i] = ISA;
587 /* Check for valid irq argument, set for polling if invalid */
588 if (ip2config.irq[i] && !is_valid_irq(ip2config.irq[i])) {
589 printk(KERN_ERR "IP2: Bad IRQ(%d) specified\n",ip2config.irq[i]);
590 ip2config.irq[i] = 0;// 0 is polling and is valid in that sense
597 struct pci_dev *pci_dev_i = NULL;
598 pci_dev_i = pci_find_device(PCI_VENDOR_ID_COMPUTONE,
599 PCI_DEVICE_ID_COMPUTONE_IP2EX, pci_dev_i);
600 if (pci_dev_i != NULL) {
603 if (pci_enable_device(pci_dev_i)) {
604 printk( KERN_ERR "IP2: can't enable PCI device at %s\n",
605 pci_name(pci_dev_i));
608 ip2config.type[i] = PCI;
609 ip2config.pci_dev[i] = pci_dev_i;
611 pci_read_config_dword(pci_dev_i, PCI_BASE_ADDRESS_1, &addr);
613 ip2config.addr[i]=(USHORT)(addr&0xfffe);
615 printk( KERN_ERR "IP2: PCI I/O address error\n");
618 // If the PCI BIOS assigned it, lets try and use it. If we
619 // can't acquire it or it screws up, deal with it then.
621 // if (!is_valid_irq(pci_irq)) {
622 // printk( KERN_ERR "IP2: Bad PCI BIOS IRQ(%d)\n",pci_irq);
625 ip2config.irq[i] = pci_dev_i->irq;
626 } else { // ann error
627 ip2config.addr[i] = 0;
628 if (status == PCIBIOS_DEVICE_NOT_FOUND) {
629 printk( KERN_ERR "IP2: PCI board %d not found\n", i );
631 printk( KERN_ERR "IP2: PCI error 0x%x \n", status );
636 printk( KERN_ERR "IP2: PCI card specified but PCI support not\n");
637 printk( KERN_ERR "IP2: configured in this kernel.\n");
638 printk( KERN_ERR "IP2: Recompile kernel with CONFIG_PCI defined!\n");
639 #endif /* CONFIG_PCI */
642 if ( (ip2config.addr[i] = find_eisa_board( Eisa_slot + 1 )) != 0) {
643 /* Eisa_irq set as side effect, boo */
644 ip2config.type[i] = EISA;
646 ip2config.irq[i] = Eisa_irq;
650 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
651 if ( ip2config.addr[i] ) {
652 pB = kmalloc( sizeof(i2eBordStr), GFP_KERNEL);
654 i2BoardPtrTable[i] = pB;
655 memset( pB, 0, sizeof(i2eBordStr) );
656 iiSetAddress( pB, ip2config.addr[i], ii2DelayTimer );
659 printk(KERN_ERR "IP2: board memory allocation error\n");
663 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
664 if ( ( pB = i2BoardPtrTable[i] ) != NULL ) {
669 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
670 if ( i2BoardPtrTable[i] != NULL ) {
675 ip2trace (ITRC_NO_PORT, ITRC_INIT, 2, 0 );
677 ip2_tty_driver->owner = THIS_MODULE;
678 ip2_tty_driver->name = "ttyF";
679 ip2_tty_driver->devfs_name = "tts/F";
680 ip2_tty_driver->driver_name = pcDriver_name;
681 ip2_tty_driver->major = IP2_TTY_MAJOR;
682 ip2_tty_driver->minor_start = 0;
683 ip2_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
684 ip2_tty_driver->subtype = SERIAL_TYPE_NORMAL;
685 ip2_tty_driver->init_termios = tty_std_termios;
686 ip2_tty_driver->init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL;
687 ip2_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
688 tty_set_operations(ip2_tty_driver, &ip2_ops);
690 ip2trace (ITRC_NO_PORT, ITRC_INIT, 3, 0 );
692 /* Register the tty devices. */
693 if ( ( err = tty_register_driver ( ip2_tty_driver ) ) ) {
694 printk(KERN_ERR "IP2: failed to register tty driver (%d)\n", err);
695 put_tty_driver(ip2_tty_driver);
698 /* Register the IPL driver. */
699 if ( ( err = register_chrdev ( IP2_IPL_MAJOR, pcIpl, &ip2_ipl ) ) ) {
700 printk(KERN_ERR "IP2: failed to register IPL device (%d)\n", err );
702 /* create the sysfs class */
703 ip2_class = class_simple_create(THIS_MODULE, "ip2");
704 if (IS_ERR(ip2_class)) {
705 err = PTR_ERR(ip2_class);
709 /* Register the read_procmem thing */
710 if (!create_proc_info_entry("ip2mem",0,&proc_root,ip2_read_procmem)) {
711 printk(KERN_ERR "IP2: failed to register read_procmem\n");
714 ip2trace (ITRC_NO_PORT, ITRC_INIT, 4, 0 );
715 /* Register the interrupt handler or poll handler, depending upon the
716 * specified interrupt.
719 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
720 if ( 0 == ip2config.addr[i] ) {
724 if ( NULL != ( pB = i2BoardPtrTable[i] ) ) {
725 class_simple_device_add(ip2_class, MKDEV(IP2_IPL_MAJOR,
726 4 * i), NULL, "ipl%d", i);
727 err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i),
728 S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR,
731 class_simple_device_remove(MKDEV(IP2_IPL_MAJOR,
736 class_simple_device_add(ip2_class, MKDEV(IP2_IPL_MAJOR,
737 4 * i + 1), NULL, "stat%d", i);
738 err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
739 S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR,
742 class_simple_device_remove(MKDEV(IP2_IPL_MAJOR,
747 for ( box = 0; box < ABS_MAX_BOXES; ++box )
749 for ( j = 0; j < ABS_BIGGEST_BOX; ++j )
751 if ( pB->i2eChannelMap[box] & (1 << j) )
753 tty_register_device(ip2_tty_driver,
754 j + ABS_BIGGEST_BOX *
755 (box+i*ABS_MAX_BOXES), NULL);
762 // Poll only forces driver to only use polling and
763 // to ignore the probed PCI or EISA interrupts.
764 ip2config.irq[i] = CIR_POLL;
766 if ( ip2config.irq[i] == CIR_POLL ) {
769 PollTimer.expires = POLL_TIMEOUT;
770 add_timer ( &PollTimer );
772 printk( KERN_INFO "IP2: polling\n");
775 if (have_requested_irq(ip2config.irq[i]))
777 rc = request_irq( ip2config.irq[i], ip2_interrupt,
778 IP2_SA_FLAGS | (ip2config.type[i] == PCI ? SA_SHIRQ : 0),
779 pcName, (void *)&pcName);
781 printk(KERN_ERR "IP2: an request_irq failed: error %d\n",rc);
782 ip2config.irq[i] = CIR_POLL;
783 printk( KERN_INFO "IP2: Polling %ld/sec.\n",
784 (POLL_TIMEOUT - jiffies));
787 mark_requested_irq(ip2config.irq[i]);
788 /* Initialise the interrupt handler bottom half (aka slih). */
791 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
792 if ( i2BoardPtrTable[i] ) {
793 set_irq( i, ip2config.irq[i] ); /* set and enable board interrupt */
797 ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_RETURN, 0 );
801 class_simple_destroy(ip2_class);
803 unregister_chrdev(IP2_IPL_MAJOR, "ip2");
808 EXPORT_SYMBOL(ip2_loadmain);
810 /******************************************************************************/
811 /* Function: ip2_init_board() */
812 /* Parameters: Index of board in configuration structure */
813 /* Returns: Success (0) */
816 /* This function initializes the specified board. The loadware is copied to */
817 /* the board, the channel structures are initialized, and the board details */
818 /* are reported on the console. */
819 /******************************************************************************/
821 ip2_init_board( int boardnum )
824 int nports = 0, nboxes = 0;
826 i2eBordStrPtr pB = i2BoardPtrTable[boardnum];
828 if ( !iiInitialize ( pB ) ) {
829 printk ( KERN_ERR "IP2: Failed to initialize board at 0x%x, error %d\n",
830 pB->i2eBase, pB->i2eError );
833 printk(KERN_INFO "IP2: Board %d: addr=0x%x irq=%d\n", boardnum + 1,
834 ip2config.addr[boardnum], ip2config.irq[boardnum] );
836 if (!request_region( ip2config.addr[boardnum], 8, pcName )) {
837 printk(KERN_ERR "IP2: bad addr=0x%x\n", ip2config.addr[boardnum]);
841 if ( iiDownloadAll ( pB, (loadHdrStrPtr)Fip_firmware, 1, Fip_firmware_size )
843 printk ( KERN_ERR "IP2: failed to download loadware\n" );
844 goto err_release_region;
846 printk ( KERN_INFO "IP2: fv=%d.%d.%d lv=%d.%d.%d\n",
847 pB->i2ePom.e.porVersion,
848 pB->i2ePom.e.porRevision,
849 pB->i2ePom.e.porSubRev, pB->i2eLVersion,
850 pB->i2eLRevision, pB->i2eLSub );
853 switch ( pB->i2ePom.e.porID & ~POR_ID_RESERVED ) {
856 printk( KERN_ERR "IP2: Unknown board type, ID = %x\n",
857 pB->i2ePom.e.porID );
859 goto err_release_region;
862 case POR_ID_II_4: /* IntelliPort-II, ISA-4 (4xRJ45) */
863 printk ( KERN_INFO "IP2: ISA-4\n" );
867 case POR_ID_II_8: /* IntelliPort-II, 8-port using standard brick. */
868 printk ( KERN_INFO "IP2: ISA-8 std\n" );
872 case POR_ID_II_8R: /* IntelliPort-II, 8-port using RJ11's (no CTS) */
873 printk ( KERN_INFO "IP2: ISA-8 RJ11\n" );
877 case POR_ID_FIIEX: /* IntelliPort IIEX */
879 int portnum = IP2_PORTS_PER_BOARD * boardnum;
882 for( box = 0; box < ABS_MAX_BOXES; ++box ) {
883 if ( pB->i2eChannelMap[box] != 0 ) {
886 for( i = 0; i < ABS_BIGGEST_BOX; ++i ) {
887 if ( pB->i2eChannelMap[box] & 1<< i ) {
892 DevTableMem[boardnum] = pCh =
893 kmalloc( sizeof(i2ChanStr) * nports, GFP_KERNEL );
895 printk ( KERN_ERR "IP2: (i2_init_channel:) Out of memory.\n");
896 goto err_release_region;
898 if ( !i2InitChannels( pB, nports, pCh ) ) {
899 printk(KERN_ERR "IP2: i2InitChannels failed: %d\n",pB->i2eError);
901 goto err_release_region;
903 pB->i2eChannelPtr = &DevTable[portnum];
904 pB->i2eChannelCnt = ABS_MOST_PORTS;
906 for( box = 0; box < ABS_MAX_BOXES; ++box, portnum += ABS_BIGGEST_BOX ) {
907 for( i = 0; i < ABS_BIGGEST_BOX; ++i ) {
908 if ( pB->i2eChannelMap[box] & (1 << i) ) {
909 DevTable[portnum + i] = pCh;
910 pCh->port_index = portnum + i;
915 printk(KERN_INFO "IP2: EX box=%d ports=%d %d bit\n",
916 nboxes, nports, pB->i2eDataWidth16 ? 16 : 8 );
920 DevTableMem[boardnum] = pCh =
921 kmalloc ( sizeof (i2ChanStr) * nports, GFP_KERNEL );
923 printk ( KERN_ERR "IP2: (i2_init_channel:) Out of memory.\n");
924 goto err_release_region;
926 pB->i2eChannelPtr = pCh;
927 pB->i2eChannelCnt = nports;
928 if ( !i2InitChannels( pB, nports, pCh ) ) {
929 printk(KERN_ERR "IP2: i2InitChannels failed: %d\n",pB->i2eError);
931 goto err_release_region;
933 pB->i2eChannelPtr = &DevTable[IP2_PORTS_PER_BOARD * boardnum];
935 for( i = 0; i < pB->i2eChannelCnt; ++i ) {
936 DevTable[IP2_PORTS_PER_BOARD * boardnum + i] = pCh;
937 pCh->port_index = (IP2_PORTS_PER_BOARD * boardnum) + i;
941 INIT_WORK(&pB->tqueue_interrupt, (void(*)(void*)) ip2_interrupt_bh, pB);
945 release_region(ip2config.addr[boardnum], 8);
948 i2BoardPtrTable[boardnum] = NULL;
952 /******************************************************************************/
953 /* Function: find_eisa_board ( int start_slot ) */
954 /* Parameters: First slot to check */
955 /* Returns: Address of EISA IntelliPort II controller */
958 /* This function searches for an EISA IntelliPort controller, starting */
959 /* from the specified slot number. If the motherboard is not identified as an */
960 /* EISA motherboard, or no valid board ID is selected it returns 0. Otherwise */
961 /* it returns the base address of the controller. */
962 /******************************************************************************/
963 static unsigned short __init
964 find_eisa_board( int start_slot )
967 unsigned int idm = 0;
968 unsigned int idp = 0;
969 unsigned int base = 0;
976 * First a check for an EISA motherboard, which we do by comparing the
977 * EISA ID registers for the system board and the first couple of slots.
978 * No slot ID should match the system board ID, but on an ISA or PCI
979 * machine the odds are that an empty bus will return similar values for
983 value = (inb(i) << 24) + (inb(i+1) << 16) + (inb(i+2) << 8) + inb(i+3);
984 for( i = 0x1c80; i <= 0x4c80; i += 0x1000 ) {
985 j = (inb(i)<<24)+(inb(i+1)<<16)+(inb(i+2)<<8)+inb(i+3);
991 * OK, so we are inclined to believe that this is an EISA machine. Find
992 * an IntelliPort controller.
994 for( i = start_slot; i < 16; i++ ) {
996 idm = (inb(base + 0xc80) << 8) | (inb(base + 0xc81) & 0xff);
997 idp = (inb(base + 0xc82) << 8) | (inb(base + 0xc83) & 0xff);
999 if ( idm == 0x0e8e ) {
1000 if ( idp == 0x0281 || idp == 0x0218 ) {
1002 } else if ( idp == 0x0282 || idp == 0x0283 ) {
1003 ismine = 3; /* Can do edge-trigger */
1014 /* It's some sort of EISA card, but at what address is it configured? */
1016 setup_address = base + 0xc88;
1017 value = inb(base + 0xc86);
1018 setup_irq = (value & 8) ? Valid_Irqs[value & 7] : 0;
1020 if ( (ismine & 2) && !(value & 0x10) ) {
1021 ismine = 1; /* Could be edging, but not */
1024 if ( Eisa_irq == 0 ) {
1025 Eisa_irq = setup_irq;
1026 } else if ( Eisa_irq != setup_irq ) {
1027 printk ( KERN_ERR "IP2: EISA irq mismatch between EISA controllers\n" );
1030 #ifdef IP2DEBUG_INIT
1031 printk(KERN_DEBUG "Computone EISA board in slot %d, I.D. 0x%x%x, Address 0x%x",
1032 base >> 12, idm, idp, setup_address);
1034 printk(KERN_DEBUG ", Interrupt %d %s\n",
1035 setup_irq, (ismine & 2) ? "(edge)" : "(level)");
1037 printk(KERN_DEBUG ", (polled)\n");
1040 return setup_address;
1043 /******************************************************************************/
1044 /* Function: set_irq() */
1045 /* Parameters: index to board in board table */
1047 /* Returns: Success (0) */
1050 /******************************************************************************/
1052 set_irq( int boardnum, int boardIrq )
1054 unsigned char tempCommand[16];
1055 i2eBordStrPtr pB = i2BoardPtrTable[boardnum];
1056 unsigned long flags;
1059 * Notify the boards they may generate interrupts. This is done by
1060 * sending an in-line command to channel 0 on each board. This is why
1061 * the channels have to be defined already. For each board, if the
1062 * interrupt has never been defined, we must do so NOW, directly, since
1063 * board will not send flow control or even give an interrupt until this
1064 * is done. If polling we must send 0 as the interrupt parameter.
1067 // We will get an interrupt here at the end of this function
1069 iiDisableMailIrq(pB);
1071 /* We build up the entire packet header. */
1072 CHANNEL_OF(tempCommand) = 0;
1073 PTYPE_OF(tempCommand) = PTYPE_INLINE;
1074 CMD_COUNT_OF(tempCommand) = 2;
1075 (CMD_OF(tempCommand))[0] = CMDVALUE_IRQ;
1076 (CMD_OF(tempCommand))[1] = boardIrq;
1078 * Write to FIFO; don't bother to adjust fifo capacity for this, since
1079 * board will respond almost immediately after SendMail hit.
1081 WRITE_LOCK_IRQSAVE(&pB->write_fifo_spinlock,flags);
1082 iiWriteBuf(pB, tempCommand, 4);
1083 WRITE_UNLOCK_IRQRESTORE(&pB->write_fifo_spinlock,flags);
1084 pB->i2eUsingIrq = boardIrq;
1085 pB->i2eOutMailWaiting |= MB_OUT_STUFFED;
1087 /* Need to update number of boards before you enable mailbox int */
1090 CHANNEL_OF(tempCommand) = 0;
1091 PTYPE_OF(tempCommand) = PTYPE_BYPASS;
1092 CMD_COUNT_OF(tempCommand) = 6;
1093 (CMD_OF(tempCommand))[0] = 88; // SILO
1094 (CMD_OF(tempCommand))[1] = 64; // chars
1095 (CMD_OF(tempCommand))[2] = 32; // ms
1097 (CMD_OF(tempCommand))[3] = 28; // MAX_BLOCK
1098 (CMD_OF(tempCommand))[4] = 64; // chars
1100 (CMD_OF(tempCommand))[5] = 87; // HW_TEST
1101 WRITE_LOCK_IRQSAVE(&pB->write_fifo_spinlock,flags);
1102 iiWriteBuf(pB, tempCommand, 8);
1103 WRITE_UNLOCK_IRQRESTORE(&pB->write_fifo_spinlock,flags);
1105 CHANNEL_OF(tempCommand) = 0;
1106 PTYPE_OF(tempCommand) = PTYPE_BYPASS;
1107 CMD_COUNT_OF(tempCommand) = 1;
1108 (CMD_OF(tempCommand))[0] = 84; /* get BOX_IDS */
1109 iiWriteBuf(pB, tempCommand, 3);
1112 // enable heartbeat for test porpoises
1113 CHANNEL_OF(tempCommand) = 0;
1114 PTYPE_OF(tempCommand) = PTYPE_BYPASS;
1115 CMD_COUNT_OF(tempCommand) = 2;
1116 (CMD_OF(tempCommand))[0] = 44; /* get ping */
1117 (CMD_OF(tempCommand))[1] = 200; /* 200 ms */
1118 WRITE_LOCK_IRQSAVE(&pB->write_fifo_spinlock,flags);
1119 iiWriteBuf(pB, tempCommand, 4);
1120 WRITE_UNLOCK_IRQRESTORE(&pB->write_fifo_spinlock,flags);
1123 iiEnableMailIrq(pB);
1124 iiSendPendingMail(pB);
1127 /******************************************************************************/
1128 /* Interrupt Handler Section */
1129 /******************************************************************************/
1132 service_all_boards(void)
1137 /* Service every board on the list */
1138 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
1139 pB = i2BoardPtrTable[i];
1141 i2ServiceBoard( pB );
1147 /******************************************************************************/
1148 /* Function: ip2_interrupt_bh(pB) */
1149 /* Parameters: pB - pointer to the board structure */
1150 /* Returns: Nothing */
1153 /* Service the board in a bottom half interrupt handler and then */
1154 /* reenable the board's interrupts if it has an IRQ number */
1156 /******************************************************************************/
1158 ip2_interrupt_bh(i2eBordStrPtr pB)
1160 // pB better well be set or we have a problem! We can only get
1161 // here from the IMMEDIATE queue. Here, we process the boards.
1162 // Checking pB doesn't cost much and it saves us from the sanity checkers.
1167 i2ServiceBoard( pB );
1168 if( pB->i2eUsingIrq ) {
1169 // Re-enable his interrupts
1170 iiEnableMailIrq(pB);
1176 /******************************************************************************/
1177 /* Function: ip2_interrupt(int irq, void *dev_id, struct pt_regs * regs) */
1178 /* Parameters: irq - interrupt number */
1179 /* pointer to optional device ID structure */
1180 /* pointer to register structure */
1181 /* Returns: Nothing */
1185 /* Our task here is simply to identify each board which needs servicing. */
1186 /* If we are queuing then, queue it to be serviced, and disable its irq */
1187 /* mask otherwise process the board directly. */
1189 /* We could queue by IRQ but that just complicates things on both ends */
1190 /* with very little gain in performance (how many instructions does */
1191 /* it take to iterate on the immediate queue). */
1194 /******************************************************************************/
1196 ip2_interrupt(int irq, void *dev_id, struct pt_regs * regs)
1202 ip2trace (ITRC_NO_PORT, ITRC_INTR, 99, 1, irq );
1204 /* Service just the boards on the list using this irq */
1205 for( i = 0; i < i2nBoards; ++i ) {
1206 pB = i2BoardPtrTable[i];
1208 // Only process those boards which match our IRQ.
1209 // IRQ = 0 for polled boards, we won't poll "IRQ" boards
1211 if ( pB && (pB->i2eUsingIrq == irq) ) {
1215 if (NO_MAIL_HERE != ( pB->i2eStartMail = iiGetMail(pB))) {
1216 // Disable his interrupt (will be enabled when serviced)
1217 // This is mostly to protect from reentrancy.
1218 iiDisableMailIrq(pB);
1220 // Park the board on the immediate queue for processing.
1221 schedule_work(&pB->tqueue_interrupt);
1223 // Make sure the immediate queue is flagged to fire.
1226 // We are using immediate servicing here. This sucks and can
1227 // cause all sorts of havoc with ppp and others. The failsafe
1228 // check on iiSendPendingMail could also throw a hairball.
1229 i2ServiceBoard( pB );
1230 #endif /* USE_IQI */
1236 ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 );
1237 return IRQ_RETVAL(handled);
1240 /******************************************************************************/
1241 /* Function: ip2_poll(unsigned long arg) */
1243 /* Returns: Nothing */
1246 /* This function calls the library routine i2ServiceBoard for each board in */
1247 /* the board table. This is used instead of the interrupt routine when polled */
1248 /* mode is specified. */
1249 /******************************************************************************/
1251 ip2_poll(unsigned long arg)
1253 ip2trace (ITRC_NO_PORT, ITRC_INTR, 100, 0 );
1255 TimerOn = 0; // it's the truth but not checked in service
1257 // Just polled boards, IRQ = 0 will hit all non-interrupt boards.
1258 // It will NOT poll boards handled by hard interrupts.
1259 // The issue of queued BH interrups is handled in ip2_interrupt().
1260 ip2_interrupt(0, NULL, NULL);
1262 PollTimer.expires = POLL_TIMEOUT;
1263 add_timer( &PollTimer );
1266 ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 );
1269 static void do_input(void *p)
1271 i2ChanStrPtr pCh = p;
1272 unsigned long flags;
1274 ip2trace(CHANN, ITRC_INPUT, 21, 0 );
1277 if ( pCh->pTTY != NULL ) {
1278 READ_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,flags)
1279 if (!pCh->throttled && (pCh->Ibuf_stuff != pCh->Ibuf_strip)) {
1280 READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags)
1283 READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags)
1285 ip2trace(CHANN, ITRC_INPUT, 22, 0 );
1287 i2InputFlush( pCh );
1291 // code duplicated from n_tty (ldisc)
1292 static inline void isig(int sig, struct tty_struct *tty, int flush)
1295 kill_pg(tty->pgrp, sig, 1);
1296 if (flush || !L_NOFLSH(tty)) {
1297 if ( tty->ldisc.flush_buffer )
1298 tty->ldisc.flush_buffer(tty);
1299 i2InputFlush( tty->driver_data );
1303 static void do_status(void *p)
1305 i2ChanStrPtr pCh = p;
1308 status = i2GetStatus( pCh, (I2_BRK|I2_PAR|I2_FRA|I2_OVR) );
1310 ip2trace (CHANN, ITRC_STATUS, 21, 1, status );
1312 if (pCh->pTTY && (status & (I2_BRK|I2_PAR|I2_FRA|I2_OVR)) ) {
1313 if ( (status & I2_BRK) ) {
1314 // code duplicated from n_tty (ldisc)
1315 if (I_IGNBRK(pCh->pTTY))
1317 if (I_BRKINT(pCh->pTTY)) {
1318 isig(SIGINT, pCh->pTTY, 1);
1321 wake_up_interruptible(&pCh->pTTY->read_wait);
1323 #ifdef NEVER_HAPPENS_AS_SETUP_XXX
1324 // and can't work because we don't know the_char
1325 // as the_char is reported on a separate path
1326 // The intelligent board does this stuff as setup
1328 char brkf = TTY_NORMAL;
1329 unsigned char brkc = '\0';
1331 if ( (status & I2_BRK) ) {
1335 else if (status & I2_PAR) {
1338 } else if (status & I2_FRA) {
1341 } else if (status & I2_OVR) {
1345 tmp = pCh->pTTY->real_raw;
1346 pCh->pTTY->real_raw = 0;
1347 pCh->pTTY->ldisc.receive_buf( pCh->pTTY, &brkc, &brkf, 1 );
1348 pCh->pTTY->real_raw = tmp;
1350 #endif /* NEVER_HAPPENS_AS_SETUP_XXX */
1354 if ( status & (I2_DDCD | I2_DDSR | I2_DCTS | I2_DRI) ) {
1355 wake_up_interruptible(&pCh->delta_msr_wait);
1357 if ( (pCh->flags & ASYNC_CHECK_CD) && (status & I2_DDCD) ) {
1358 if ( status & I2_DCD ) {
1360 wake_up_interruptible ( &pCh->open_wait );
1363 if (pCh->pTTY && (!(pCh->pTTY->termios->c_cflag & CLOCAL)) ) {
1364 tty_hangup( pCh->pTTY );
1370 ip2trace (CHANN, ITRC_STATUS, 26, 0 );
1373 /******************************************************************************/
1374 /* Device Open/Close/Ioctl Entry Point Section */
1375 /******************************************************************************/
1377 /******************************************************************************/
1378 /* Function: open_sanity_check() */
1379 /* Parameters: Pointer to tty structure */
1380 /* Pointer to file structure */
1381 /* Returns: Success or failure */
1384 /* Verifies the structure magic numbers and cross links. */
1385 /******************************************************************************/
1386 #ifdef IP2DEBUG_OPEN
1388 open_sanity_check( i2ChanStrPtr pCh, i2eBordStrPtr pBrd )
1390 if ( pBrd->i2eValid != I2E_MAGIC ) {
1391 printk(KERN_ERR "IP2: invalid board structure\n" );
1392 } else if ( pBrd != pCh->pMyBord ) {
1393 printk(KERN_ERR "IP2: board structure pointer mismatch (%p)\n",
1395 } else if ( pBrd->i2eChannelCnt < pCh->port_index ) {
1396 printk(KERN_ERR "IP2: bad device index (%d)\n", pCh->port_index );
1397 } else if (&((i2ChanStrPtr)pBrd->i2eChannelPtr)[pCh->port_index] != pCh) {
1399 printk(KERN_INFO "IP2: all pointers check out!\n" );
1405 /******************************************************************************/
1406 /* Function: ip2_open() */
1407 /* Parameters: Pointer to tty structure */
1408 /* Pointer to file structure */
1409 /* Returns: Success or failure */
1411 /* Description: (MANDATORY) */
1412 /* A successful device open has to run a gauntlet of checks before it */
1413 /* completes. After some sanity checking and pointer setup, the function */
1414 /* blocks until all conditions are satisfied. It then initialises the port to */
1415 /* the default characteristics and returns. */
1416 /******************************************************************************/
1418 ip2_open( PTTY tty, struct file *pFile )
1423 i2ChanStrPtr pCh = DevTable[tty->index];
1425 ip2trace (tty->index, ITRC_OPEN, ITRC_ENTER, 0 );
1427 if ( pCh == NULL ) {
1430 /* Setup pointer links in device and tty structures */
1432 tty->driver_data = pCh;
1434 #ifdef IP2DEBUG_OPEN
1436 "IP2:open(tty=%p,pFile=%p):dev=%s,ch=%d,idx=%d\n",
1437 tty, pFile, tty->name, pCh->infl.hd.i2sChannel, pCh->port_index);
1438 open_sanity_check ( pCh, pCh->pMyBord );
1441 i2QueueCommands(PTYPE_INLINE, pCh, 100, 3, CMD_DTRUP,CMD_RTSUP,CMD_DCD_REP);
1442 pCh->dataSetOut |= (I2_DTR | I2_RTS);
1443 serviceOutgoingFifo( pCh->pMyBord );
1445 /* Block here until the port is ready (per serial and istallion) */
1447 * 1. If the port is in the middle of closing wait for the completion
1448 * and then return the appropriate error.
1450 init_waitqueue_entry(&wait, current);
1451 add_wait_queue(&pCh->close_wait, &wait);
1452 set_current_state( TASK_INTERRUPTIBLE );
1454 if ( tty_hung_up_p(pFile) || ( pCh->flags & ASYNC_CLOSING )) {
1455 if ( pCh->flags & ASYNC_CLOSING ) {
1458 if ( tty_hung_up_p(pFile) ) {
1459 set_current_state( TASK_RUNNING );
1460 remove_wait_queue(&pCh->close_wait, &wait);
1461 return( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EAGAIN : -ERESTARTSYS;
1464 set_current_state( TASK_RUNNING );
1465 remove_wait_queue(&pCh->close_wait, &wait);
1468 * 3. Handle a non-blocking open of a normal port.
1470 if ( (pFile->f_flags & O_NONBLOCK) || (tty->flags & (1<<TTY_IO_ERROR) )) {
1471 pCh->flags |= ASYNC_NORMAL_ACTIVE;
1475 * 4. Now loop waiting for the port to be free and carrier present
1478 if ( tty->termios->c_cflag & CLOCAL )
1481 #ifdef IP2DEBUG_OPEN
1482 printk(KERN_DEBUG "OpenBlock: do_clocal = %d\n", do_clocal);
1487 init_waitqueue_entry(&wait, current);
1488 add_wait_queue(&pCh->open_wait, &wait);
1491 i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_DTRUP, CMD_RTSUP);
1492 pCh->dataSetOut |= (I2_DTR | I2_RTS);
1493 set_current_state( TASK_INTERRUPTIBLE );
1494 serviceOutgoingFifo( pCh->pMyBord );
1495 if ( tty_hung_up_p(pFile) ) {
1496 set_current_state( TASK_RUNNING );
1497 remove_wait_queue(&pCh->open_wait, &wait);
1498 return ( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EBUSY : -ERESTARTSYS;
1500 if (!(pCh->flags & ASYNC_CLOSING) &&
1501 (do_clocal || (pCh->dataSetIn & I2_DCD) )) {
1506 #ifdef IP2DEBUG_OPEN
1507 printk(KERN_DEBUG "ASYNC_CLOSING = %s\n",
1508 (pCh->flags & ASYNC_CLOSING)?"True":"False");
1509 printk(KERN_DEBUG "OpenBlock: waiting for CD or signal\n");
1511 ip2trace (CHANN, ITRC_OPEN, 3, 2, 0,
1512 (pCh->flags & ASYNC_CLOSING) );
1513 /* check for signal */
1514 if (signal_pending(current)) {
1515 rc = (( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EAGAIN : -ERESTARTSYS);
1520 set_current_state( TASK_RUNNING );
1521 remove_wait_queue(&pCh->open_wait, &wait);
1523 --pCh->wopen; //why count?
1525 ip2trace (CHANN, ITRC_OPEN, 4, 0 );
1530 pCh->flags |= ASYNC_NORMAL_ACTIVE;
1534 /* first open - Assign termios structure to port */
1535 if ( tty->count == 1 ) {
1536 i2QueueCommands(PTYPE_INLINE, pCh, 0, 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB);
1537 /* Now we must send the termios settings to the loadware */
1538 set_params( pCh, NULL );
1542 * Now set any i2lib options. These may go away if the i2lib code ends
1543 * up rolled into the mainline.
1545 pCh->channelOptions |= CO_NBLOCK_WRITE;
1547 #ifdef IP2DEBUG_OPEN
1548 printk (KERN_DEBUG "IP2: open completed\n" );
1550 serviceOutgoingFifo( pCh->pMyBord );
1552 ip2trace (CHANN, ITRC_OPEN, ITRC_RETURN, 0 );
1557 /******************************************************************************/
1558 /* Function: ip2_close() */
1559 /* Parameters: Pointer to tty structure */
1560 /* Pointer to file structure */
1561 /* Returns: Nothing */
1566 /******************************************************************************/
1568 ip2_close( PTTY tty, struct file *pFile )
1570 i2ChanStrPtr pCh = tty->driver_data;
1576 ip2trace (CHANN, ITRC_CLOSE, ITRC_ENTER, 0 );
1578 #ifdef IP2DEBUG_OPEN
1579 printk(KERN_DEBUG "IP2:close %s:\n",tty->name);
1582 if ( tty_hung_up_p ( pFile ) ) {
1584 ip2trace (CHANN, ITRC_CLOSE, 2, 1, 2 );
1588 if ( tty->count > 1 ) { /* not the last close */
1590 ip2trace (CHANN, ITRC_CLOSE, 2, 1, 3 );
1594 pCh->flags |= ASYNC_CLOSING; // last close actually
1598 if (pCh->ClosingWaitTime != ASYNC_CLOSING_WAIT_NONE) {
1600 * Before we drop DTR, make sure the transmitter has completely drained.
1601 * This uses an timeout, after which the close
1604 ip2_wait_until_sent(tty, pCh->ClosingWaitTime );
1607 * At this point we stop accepting input. Here we flush the channel
1608 * input buffer which will allow the board to send up more data. Any
1609 * additional input is tossed at interrupt/poll time.
1611 i2InputFlush( pCh );
1613 /* disable DSS reporting */
1614 i2QueueCommands(PTYPE_INLINE, pCh, 100, 4,
1615 CMD_DCD_NREP, CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);
1616 if ( !tty || (tty->termios->c_cflag & HUPCL) ) {
1617 i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN);
1618 pCh->dataSetOut &= ~(I2_DTR | I2_RTS);
1619 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25));
1622 serviceOutgoingFifo ( pCh->pMyBord );
1624 if ( tty->driver->flush_buffer )
1625 tty->driver->flush_buffer(tty);
1626 if ( tty->ldisc.flush_buffer )
1627 tty->ldisc.flush_buffer(tty);
1633 if (pCh->ClosingDelay) {
1634 msleep_interruptible(jiffies_to_msecs(pCh->ClosingDelay));
1636 wake_up_interruptible(&pCh->open_wait);
1639 pCh->flags &=~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1640 wake_up_interruptible(&pCh->close_wait);
1642 #ifdef IP2DEBUG_OPEN
1643 DBG_CNT("ip2_close: after wakeups--");
1647 ip2trace (CHANN, ITRC_CLOSE, ITRC_RETURN, 1, 1 );
1652 /******************************************************************************/
1653 /* Function: ip2_hangup() */
1654 /* Parameters: Pointer to tty structure */
1655 /* Returns: Nothing */
1660 /******************************************************************************/
1662 ip2_hangup ( PTTY tty )
1664 i2ChanStrPtr pCh = tty->driver_data;
1670 ip2trace (CHANN, ITRC_HANGUP, ITRC_ENTER, 0 );
1672 ip2_flush_buffer(tty);
1674 /* disable DSS reporting */
1676 i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_DCD_NREP);
1677 i2QueueCommands(PTYPE_INLINE, pCh, 0, 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB);
1678 if ( (tty->termios->c_cflag & HUPCL) ) {
1679 i2QueueCommands(PTYPE_BYPASS, pCh, 0, 2, CMD_RTSDN, CMD_DTRDN);
1680 pCh->dataSetOut &= ~(I2_DTR | I2_RTS);
1681 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25));
1683 i2QueueCommands(PTYPE_INLINE, pCh, 1, 3,
1684 CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);
1685 serviceOutgoingFifo ( pCh->pMyBord );
1687 wake_up_interruptible ( &pCh->delta_msr_wait );
1689 pCh->flags &= ~ASYNC_NORMAL_ACTIVE;
1691 wake_up_interruptible ( &pCh->open_wait );
1693 ip2trace (CHANN, ITRC_HANGUP, ITRC_RETURN, 0 );
1696 /******************************************************************************/
1697 /******************************************************************************/
1698 /* Device Output Section */
1699 /******************************************************************************/
1700 /******************************************************************************/
1702 /******************************************************************************/
1703 /* Function: ip2_write() */
1704 /* Parameters: Pointer to tty structure */
1705 /* Flag denoting data is in user (1) or kernel (0) space */
1706 /* Pointer to data */
1707 /* Number of bytes to write */
1708 /* Returns: Number of bytes actually written */
1710 /* Description: (MANDATORY) */
1713 /******************************************************************************/
1715 ip2_write( PTTY tty, int user, const unsigned char *pData, int count)
1717 i2ChanStrPtr pCh = tty->driver_data;
1719 unsigned long flags;
1721 ip2trace (CHANN, ITRC_WRITE, ITRC_ENTER, 2, count, -1 );
1723 /* Flush out any buffered data left over from ip2_putchar() calls. */
1724 ip2_flush_chars( tty );
1726 /* This is the actual move bit. Make sure it does what we need!!!!! */
1727 WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
1728 bytesSent = i2Output( pCh, pData, count, user );
1729 WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
1731 ip2trace (CHANN, ITRC_WRITE, ITRC_RETURN, 1, bytesSent );
1733 return bytesSent > 0 ? bytesSent : 0;
1736 /******************************************************************************/
1737 /* Function: ip2_putchar() */
1738 /* Parameters: Pointer to tty structure */
1739 /* Character to write */
1740 /* Returns: Nothing */
1745 /******************************************************************************/
1747 ip2_putchar( PTTY tty, unsigned char ch )
1749 i2ChanStrPtr pCh = tty->driver_data;
1750 unsigned long flags;
1752 // ip2trace (CHANN, ITRC_PUTC, ITRC_ENTER, 1, ch );
1754 WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
1755 pCh->Pbuf[pCh->Pbuf_stuff++] = ch;
1756 if ( pCh->Pbuf_stuff == sizeof pCh->Pbuf ) {
1757 WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
1758 ip2_flush_chars( tty );
1760 WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
1762 // ip2trace (CHANN, ITRC_PUTC, ITRC_RETURN, 1, ch );
1765 /******************************************************************************/
1766 /* Function: ip2_flush_chars() */
1767 /* Parameters: Pointer to tty structure */
1768 /* Returns: Nothing */
1772 /******************************************************************************/
1774 ip2_flush_chars( PTTY tty )
1777 i2ChanStrPtr pCh = tty->driver_data;
1778 unsigned long flags;
1780 WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
1781 if ( pCh->Pbuf_stuff ) {
1783 // ip2trace (CHANN, ITRC_PUTC, 10, 1, strip );
1786 // We may need to restart i2Output if it does not fullfill this request
1788 strip = i2Output( pCh, pCh->Pbuf, pCh->Pbuf_stuff, 0 );
1789 if ( strip != pCh->Pbuf_stuff ) {
1790 memmove( pCh->Pbuf, &pCh->Pbuf[strip], pCh->Pbuf_stuff - strip );
1792 pCh->Pbuf_stuff -= strip;
1794 WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
1797 /******************************************************************************/
1798 /* Function: ip2_write_room() */
1799 /* Parameters: Pointer to tty structure */
1800 /* Returns: Number of bytes that the driver can accept */
1804 /******************************************************************************/
1806 ip2_write_room ( PTTY tty )
1809 i2ChanStrPtr pCh = tty->driver_data;
1810 unsigned long flags;
1812 READ_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
1813 bytesFree = i2OutputFree( pCh ) - pCh->Pbuf_stuff;
1814 READ_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
1816 ip2trace (CHANN, ITRC_WRITE, 11, 1, bytesFree );
1818 return ((bytesFree > 0) ? bytesFree : 0);
1821 /******************************************************************************/
1822 /* Function: ip2_chars_in_buf() */
1823 /* Parameters: Pointer to tty structure */
1824 /* Returns: Number of bytes queued for transmission */
1829 /******************************************************************************/
1831 ip2_chars_in_buf ( PTTY tty )
1833 i2ChanStrPtr pCh = tty->driver_data;
1835 unsigned long flags;
1837 ip2trace (CHANN, ITRC_WRITE, 12, 1, pCh->Obuf_char_count + pCh->Pbuf_stuff );
1839 #ifdef IP2DEBUG_WRITE
1840 printk (KERN_DEBUG "IP2: chars in buffer = %d (%d,%d)\n",
1841 pCh->Obuf_char_count + pCh->Pbuf_stuff,
1842 pCh->Obuf_char_count, pCh->Pbuf_stuff );
1844 READ_LOCK_IRQSAVE(&pCh->Obuf_spinlock,flags);
1845 rc = pCh->Obuf_char_count;
1846 READ_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags);
1847 READ_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
1848 rc += pCh->Pbuf_stuff;
1849 READ_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
1853 /******************************************************************************/
1854 /* Function: ip2_flush_buffer() */
1855 /* Parameters: Pointer to tty structure */
1856 /* Returns: Nothing */
1861 /******************************************************************************/
1863 ip2_flush_buffer( PTTY tty )
1865 i2ChanStrPtr pCh = tty->driver_data;
1866 unsigned long flags;
1868 ip2trace (CHANN, ITRC_FLUSH, ITRC_ENTER, 0 );
1870 #ifdef IP2DEBUG_WRITE
1871 printk (KERN_DEBUG "IP2: flush buffer\n" );
1873 WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
1874 pCh->Pbuf_stuff = 0;
1875 WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
1876 i2FlushOutput( pCh );
1879 ip2trace (CHANN, ITRC_FLUSH, ITRC_RETURN, 0 );
1883 /******************************************************************************/
1884 /* Function: ip2_wait_until_sent() */
1885 /* Parameters: Pointer to tty structure */
1886 /* Timeout for wait. */
1887 /* Returns: Nothing */
1890 /* This function is used in place of the normal tty_wait_until_sent, which */
1891 /* only waits for the driver buffers to be empty (or rather, those buffers */
1892 /* reported by chars_in_buffer) which doesn't work for IP2 due to the */
1893 /* indeterminate number of bytes buffered on the board. */
1894 /******************************************************************************/
1896 ip2_wait_until_sent ( PTTY tty, int timeout )
1899 i2ChanStrPtr pCh = tty->driver_data;
1901 tty_wait_until_sent(tty, timeout );
1902 if ( (i = timeout - (jiffies -i)) > 0)
1903 i2DrainOutput( pCh, i );
1906 /******************************************************************************/
1907 /******************************************************************************/
1908 /* Device Input Section */
1909 /******************************************************************************/
1910 /******************************************************************************/
1912 /******************************************************************************/
1913 /* Function: ip2_throttle() */
1914 /* Parameters: Pointer to tty structure */
1915 /* Returns: Nothing */
1920 /******************************************************************************/
1922 ip2_throttle ( PTTY tty )
1924 i2ChanStrPtr pCh = tty->driver_data;
1926 #ifdef IP2DEBUG_READ
1927 printk (KERN_DEBUG "IP2: throttle\n" );
1930 * Signal the poll/interrupt handlers not to forward incoming data to
1931 * the line discipline. This will cause the buffers to fill up in the
1932 * library and thus cause the library routines to send the flow control
1938 /******************************************************************************/
1939 /* Function: ip2_unthrottle() */
1940 /* Parameters: Pointer to tty structure */
1941 /* Returns: Nothing */
1946 /******************************************************************************/
1948 ip2_unthrottle ( PTTY tty )
1950 i2ChanStrPtr pCh = tty->driver_data;
1951 unsigned long flags;
1953 #ifdef IP2DEBUG_READ
1954 printk (KERN_DEBUG "IP2: unthrottle\n" );
1957 /* Pass incoming data up to the line discipline again. */
1959 i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_RESUME);
1960 serviceOutgoingFifo( pCh->pMyBord );
1961 READ_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,flags)
1962 if ( pCh->Ibuf_stuff != pCh->Ibuf_strip ) {
1963 READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags)
1964 #ifdef IP2DEBUG_READ
1965 printk (KERN_DEBUG "i2Input called from unthrottle\n" );
1969 READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags)
1973 ip2_start ( PTTY tty )
1975 i2ChanStrPtr pCh = DevTable[tty->index];
1977 i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_RESUME);
1978 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_UNSUSPEND);
1979 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_RESUME);
1980 #ifdef IP2DEBUG_WRITE
1981 printk (KERN_DEBUG "IP2: start tx\n" );
1986 ip2_stop ( PTTY tty )
1988 i2ChanStrPtr pCh = DevTable[tty->index];
1990 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_SUSPEND);
1991 #ifdef IP2DEBUG_WRITE
1992 printk (KERN_DEBUG "IP2: stop tx\n" );
1996 /******************************************************************************/
1997 /* Device Ioctl Section */
1998 /******************************************************************************/
2000 static int ip2_tiocmget(struct tty_struct *tty, struct file *file)
2002 i2ChanStrPtr pCh = DevTable[tty->index];
2009 FIXME - the following code is causing a NULL pointer dereference in
2010 2.3.51 in an interrupt handler. It's suppose to prompt the board
2011 to return the DSS signal status immediately. Why doesn't it do
2012 the same thing in 2.2.14?
2015 /* This thing is still busted in the 1.2.12 driver on 2.4.x
2016 and even hoses the serial console so the oops can be trapped.
2019 #ifdef ENABLE_DSSNOW
2020 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DSS_NOW);
2022 init_waitqueue_entry(&wait, current);
2023 add_wait_queue(&pCh->dss_now_wait, &wait);
2024 set_current_state( TASK_INTERRUPTIBLE );
2026 serviceOutgoingFifo( pCh->pMyBord );
2030 set_current_state( TASK_RUNNING );
2031 remove_wait_queue(&pCh->dss_now_wait, &wait);
2033 if (signal_pending(current)) {
2037 return ((pCh->dataSetOut & I2_RTS) ? TIOCM_RTS : 0)
2038 | ((pCh->dataSetOut & I2_DTR) ? TIOCM_DTR : 0)
2039 | ((pCh->dataSetIn & I2_DCD) ? TIOCM_CAR : 0)
2040 | ((pCh->dataSetIn & I2_RI) ? TIOCM_RNG : 0)
2041 | ((pCh->dataSetIn & I2_DSR) ? TIOCM_DSR : 0)
2042 | ((pCh->dataSetIn & I2_CTS) ? TIOCM_CTS : 0);
2045 static int ip2_tiocmset(struct tty_struct *tty, struct file *file,
2046 unsigned int set, unsigned int clear)
2048 i2ChanStrPtr pCh = DevTable[tty->index];
2053 if (set & TIOCM_RTS) {
2054 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_RTSUP);
2055 pCh->dataSetOut |= I2_RTS;
2057 if (set & TIOCM_DTR) {
2058 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DTRUP);
2059 pCh->dataSetOut |= I2_DTR;
2062 if (clear & TIOCM_RTS) {
2063 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_RTSDN);
2064 pCh->dataSetOut &= ~I2_RTS;
2066 if (clear & TIOCM_DTR) {
2067 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DTRDN);
2068 pCh->dataSetOut &= ~I2_DTR;
2070 serviceOutgoingFifo( pCh->pMyBord );
2074 /******************************************************************************/
2075 /* Function: ip2_ioctl() */
2076 /* Parameters: Pointer to tty structure */
2077 /* Pointer to file structure */
2080 /* Returns: Success or failure */
2085 /******************************************************************************/
2087 ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg )
2090 i2ChanStrPtr pCh = DevTable[tty->index];
2091 struct async_icount cprev, cnow; /* kernel counter temps */
2092 struct serial_icounter_struct __user *p_cuser;
2094 unsigned long flags;
2095 void __user *argp = (void __user *)arg;
2097 if ( pCh == NULL ) {
2101 ip2trace (CHANN, ITRC_IOCTL, ITRC_ENTER, 2, cmd, arg );
2103 #ifdef IP2DEBUG_IOCTL
2104 printk(KERN_DEBUG "IP2: ioctl cmd (%x), arg (%lx)\n", cmd, arg );
2110 ip2trace (CHANN, ITRC_IOCTL, 2, 1, rc );
2112 rc = get_serial_info(pCh, argp);
2119 ip2trace (CHANN, ITRC_IOCTL, 3, 1, rc );
2121 rc = set_serial_info(pCh, argp);
2127 rc = tty_check_change(tty);
2132 //return -ENOIOCTLCMD;
2135 //return -ENOIOCTLCMD;
2138 if (STOP_CHAR(tty) != __DISABLED_CHAR) {
2139 i2QueueCommands( PTYPE_BYPASS, pCh, 100, 1,
2140 CMD_XMIT_NOW(STOP_CHAR(tty)));
2144 if (START_CHAR(tty) != __DISABLED_CHAR) {
2145 i2QueueCommands( PTYPE_BYPASS, pCh, 100, 1,
2146 CMD_XMIT_NOW(START_CHAR(tty)));
2154 case TCSBRK: /* SVID version: non-zero arg --> no break */
2155 rc = tty_check_change(tty);
2157 ip2trace (CHANN, ITRC_IOCTL, 4, 1, rc );
2160 ip2_wait_until_sent(tty,0);
2162 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_SEND_BRK(250));
2163 serviceOutgoingFifo( pCh->pMyBord );
2168 case TCSBRKP: /* support for POSIX tcsendbreak() */
2169 rc = tty_check_change(tty);
2171 ip2trace (CHANN, ITRC_IOCTL, 5, 1, rc );
2174 ip2_wait_until_sent(tty,0);
2175 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1,
2176 CMD_SEND_BRK(arg ? arg*100 : 250));
2177 serviceOutgoingFifo ( pCh->pMyBord );
2183 ip2trace (CHANN, ITRC_IOCTL, 6, 1, rc );
2185 rc = put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *)argp);
2192 ip2trace (CHANN, ITRC_IOCTL, 7, 1, rc );
2194 rc = get_user(arg,(unsigned long __user *) argp);
2197 tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL)
2198 | (arg ? CLOCAL : 0));
2203 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change - mask
2204 * passed in arg for lines of interest (use |'ed TIOCM_RNG/DSR/CD/CTS
2205 * for masking). Caller should use TIOCGICOUNT to see which one it was
2208 save_flags(flags);cli();
2209 cprev = pCh->icount; /* note the counters on entry */
2210 restore_flags(flags);
2211 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 4,
2212 CMD_DCD_REP, CMD_CTS_REP, CMD_DSR_REP, CMD_RI_REP);
2213 init_waitqueue_entry(&wait, current);
2214 add_wait_queue(&pCh->delta_msr_wait, &wait);
2215 set_current_state( TASK_INTERRUPTIBLE );
2217 serviceOutgoingFifo( pCh->pMyBord );
2219 ip2trace (CHANN, ITRC_IOCTL, 10, 0 );
2223 ip2trace (CHANN, ITRC_IOCTL, 11, 0 );
2225 /* see if a signal did it */
2226 if (signal_pending(current)) {
2230 save_flags(flags);cli();
2231 cnow = pCh->icount; /* atomic copy */
2232 restore_flags(flags);
2233 if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
2234 cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) {
2235 rc = -EIO; /* no change => rc */
2238 if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
2239 ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
2240 ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
2241 ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
2247 set_current_state( TASK_RUNNING );
2248 remove_wait_queue(&pCh->delta_msr_wait, &wait);
2250 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 3,
2251 CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);
2252 if ( ! (pCh->flags & ASYNC_CHECK_CD)) {
2253 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DCD_NREP);
2255 serviceOutgoingFifo( pCh->pMyBord );
2260 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
2261 * Return: write counters to the user passed counter struct
2262 * NB: both 1->0 and 0->1 transitions are counted except for RI where
2263 * only 0->1 is counted. The controller is quite capable of counting
2264 * both, but this done to preserve compatibility with the standard
2268 ip2trace (CHANN, ITRC_IOCTL, 11, 1, rc );
2270 save_flags(flags);cli();
2272 restore_flags(flags);
2274 rc = put_user(cnow.cts, &p_cuser->cts);
2275 rc = put_user(cnow.dsr, &p_cuser->dsr);
2276 rc = put_user(cnow.rng, &p_cuser->rng);
2277 rc = put_user(cnow.dcd, &p_cuser->dcd);
2278 rc = put_user(cnow.rx, &p_cuser->rx);
2279 rc = put_user(cnow.tx, &p_cuser->tx);
2280 rc = put_user(cnow.frame, &p_cuser->frame);
2281 rc = put_user(cnow.overrun, &p_cuser->overrun);
2282 rc = put_user(cnow.parity, &p_cuser->parity);
2283 rc = put_user(cnow.brk, &p_cuser->brk);
2284 rc = put_user(cnow.buf_overrun, &p_cuser->buf_overrun);
2288 * The rest are not supported by this driver. By returning -ENOIOCTLCMD they
2289 * will be passed to the line discipline for it to handle.
2295 case TIOCSERGSTRUCT:
2296 case TIOCSERGETMULTI:
2297 case TIOCSERSETMULTI:
2300 ip2trace (CHANN, ITRC_IOCTL, 12, 0 );
2306 ip2trace (CHANN, ITRC_IOCTL, ITRC_RETURN, 0 );
2311 /******************************************************************************/
2312 /* Function: GetSerialInfo() */
2313 /* Parameters: Pointer to channel structure */
2314 /* Pointer to old termios structure */
2315 /* Returns: Nothing */
2318 /* This is to support the setserial command, and requires processing of the */
2319 /* standard Linux serial structure. */
2320 /******************************************************************************/
2322 get_serial_info ( i2ChanStrPtr pCh, struct serial_struct __user *retinfo )
2324 struct serial_struct tmp;
2326 memset ( &tmp, 0, sizeof(tmp) );
2327 tmp.type = pCh->pMyBord->channelBtypes.bid_value[(pCh->port_index & (IP2_PORTS_PER_BOARD-1))/16];
2328 if (BID_HAS_654(tmp.type)) {
2329 tmp.type = PORT_16650;
2331 tmp.type = PORT_CIRRUS;
2333 tmp.line = pCh->port_index;
2334 tmp.port = pCh->pMyBord->i2eBase;
2335 tmp.irq = ip2config.irq[pCh->port_index/64];
2336 tmp.flags = pCh->flags;
2337 tmp.baud_base = pCh->BaudBase;
2338 tmp.close_delay = pCh->ClosingDelay;
2339 tmp.closing_wait = pCh->ClosingWaitTime;
2340 tmp.custom_divisor = pCh->BaudDivisor;
2341 return copy_to_user(retinfo,&tmp,sizeof(*retinfo));
2344 /******************************************************************************/
2345 /* Function: SetSerialInfo() */
2346 /* Parameters: Pointer to channel structure */
2347 /* Pointer to old termios structure */
2348 /* Returns: Nothing */
2351 /* This function provides support for setserial, which uses the TIOCSSERIAL */
2352 /* ioctl. Not all setserial parameters are relevant. If the user attempts to */
2353 /* change the IRQ, address or type of the port the ioctl fails. */
2354 /******************************************************************************/
2356 set_serial_info( i2ChanStrPtr pCh, struct serial_struct __user *new_info )
2358 struct serial_struct ns;
2359 int old_flags, old_baud_divisor;
2361 if (copy_from_user(&ns, new_info, sizeof (ns)))
2365 * We don't allow setserial to change IRQ, board address, type or baud
2366 * base. Also line nunber as such is meaningless but we use it for our
2367 * array index so it is fixed also.
2369 if ( (ns.irq != ip2config.irq[pCh->port_index])
2370 || ((int) ns.port != ((int) (pCh->pMyBord->i2eBase)))
2371 || (ns.baud_base != pCh->BaudBase)
2372 || (ns.line != pCh->port_index) ) {
2376 old_flags = pCh->flags;
2377 old_baud_divisor = pCh->BaudDivisor;
2379 if ( !capable(CAP_SYS_ADMIN) ) {
2380 if ( ( ns.close_delay != pCh->ClosingDelay ) ||
2381 ( (ns.flags & ~ASYNC_USR_MASK) !=
2382 (pCh->flags & ~ASYNC_USR_MASK) ) ) {
2386 pCh->flags = (pCh->flags & ~ASYNC_USR_MASK) |
2387 (ns.flags & ASYNC_USR_MASK);
2388 pCh->BaudDivisor = ns.custom_divisor;
2390 pCh->flags = (pCh->flags & ~ASYNC_FLAGS) |
2391 (ns.flags & ASYNC_FLAGS);
2392 pCh->BaudDivisor = ns.custom_divisor;
2393 pCh->ClosingDelay = ns.close_delay * HZ/100;
2394 pCh->ClosingWaitTime = ns.closing_wait * HZ/100;
2397 if ( ( (old_flags & ASYNC_SPD_MASK) != (pCh->flags & ASYNC_SPD_MASK) )
2398 || (old_baud_divisor != pCh->BaudDivisor) ) {
2399 // Invalidate speed and reset parameters
2400 set_params( pCh, NULL );
2406 /******************************************************************************/
2407 /* Function: ip2_set_termios() */
2408 /* Parameters: Pointer to tty structure */
2409 /* Pointer to old termios structure */
2410 /* Returns: Nothing */
2415 /******************************************************************************/
2417 ip2_set_termios( PTTY tty, struct termios *old_termios )
2419 i2ChanStrPtr pCh = (i2ChanStrPtr)tty->driver_data;
2421 #ifdef IP2DEBUG_IOCTL
2422 printk (KERN_DEBUG "IP2: set termios %p\n", old_termios );
2425 set_params( pCh, old_termios );
2428 /******************************************************************************/
2429 /* Function: ip2_set_line_discipline() */
2430 /* Parameters: Pointer to tty structure */
2431 /* Returns: Nothing */
2433 /* Description: Does nothing */
2436 /******************************************************************************/
2438 ip2_set_line_discipline ( PTTY tty )
2440 #ifdef IP2DEBUG_IOCTL
2441 printk (KERN_DEBUG "IP2: set line discipline\n" );
2444 ip2trace (((i2ChanStrPtr)tty->driver_data)->port_index, ITRC_IOCTL, 16, 0 );
2448 /******************************************************************************/
2449 /* Function: SetLine Characteristics() */
2450 /* Parameters: Pointer to channel structure */
2451 /* Returns: Nothing */
2454 /* This routine is called to update the channel structure with the new line */
2455 /* characteristics, and send the appropriate commands to the board when they */
2457 /******************************************************************************/
2459 set_params( i2ChanStrPtr pCh, struct termios *o_tios )
2461 tcflag_t cflag, iflag, lflag;
2462 char stop_char, start_char;
2463 struct termios dummy;
2465 lflag = pCh->pTTY->termios->c_lflag;
2466 cflag = pCh->pTTY->termios->c_cflag;
2467 iflag = pCh->pTTY->termios->c_iflag;
2469 if (o_tios == NULL) {
2470 dummy.c_lflag = ~lflag;
2471 dummy.c_cflag = ~cflag;
2472 dummy.c_iflag = ~iflag;
2477 switch ( cflag & CBAUD ) {
2479 i2QueueCommands( PTYPE_BYPASS, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN);
2480 pCh->dataSetOut &= ~(I2_DTR | I2_RTS);
2481 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25));
2482 pCh->pTTY->termios->c_cflag |= (CBAUD & o_tios->c_cflag);
2487 * This is the speed that is overloaded with all the other high
2488 * speeds, depending upon the flag settings.
2490 if ( ( pCh->flags & ASYNC_SPD_MASK ) == ASYNC_SPD_HI ) {
2491 pCh->speed = CBR_57600;
2492 } else if ( (pCh->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI ) {
2493 pCh->speed = CBR_115200;
2494 } else if ( (pCh->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST ) {
2495 pCh->speed = CBR_C1;
2497 pCh->speed = CBR_38400;
2500 case B50: pCh->speed = CBR_50; break;
2501 case B75: pCh->speed = CBR_75; break;
2502 case B110: pCh->speed = CBR_110; break;
2503 case B134: pCh->speed = CBR_134; break;
2504 case B150: pCh->speed = CBR_150; break;
2505 case B200: pCh->speed = CBR_200; break;
2506 case B300: pCh->speed = CBR_300; break;
2507 case B600: pCh->speed = CBR_600; break;
2508 case B1200: pCh->speed = CBR_1200; break;
2509 case B1800: pCh->speed = CBR_1800; break;
2510 case B2400: pCh->speed = CBR_2400; break;
2511 case B4800: pCh->speed = CBR_4800; break;
2512 case B9600: pCh->speed = CBR_9600; break;
2513 case B19200: pCh->speed = CBR_19200; break;
2514 case B57600: pCh->speed = CBR_57600; break;
2515 case B115200: pCh->speed = CBR_115200; break;
2516 case B153600: pCh->speed = CBR_153600; break;
2517 case B230400: pCh->speed = CBR_230400; break;
2518 case B307200: pCh->speed = CBR_307200; break;
2519 case B460800: pCh->speed = CBR_460800; break;
2520 case B921600: pCh->speed = CBR_921600; break;
2521 default: pCh->speed = CBR_9600; break;
2523 if ( pCh->speed == CBR_C1 ) {
2524 // Process the custom speed parameters.
2525 int bps = pCh->BaudBase / pCh->BaudDivisor;
2526 if ( bps == 921600 ) {
2527 pCh->speed = CBR_921600;
2530 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_BAUD_DEF1(bps) );
2533 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_SETBAUD(pCh->speed));
2535 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 2, CMD_DTRUP, CMD_RTSUP);
2536 pCh->dataSetOut |= (I2_DTR | I2_RTS);
2538 if ( (CSTOPB & cflag) ^ (CSTOPB & o_tios->c_cflag))
2540 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1,
2541 CMD_SETSTOP( ( cflag & CSTOPB ) ? CST_2 : CST_1));
2543 if (((PARENB|PARODD) & cflag) ^ ((PARENB|PARODD) & o_tios->c_cflag))
2545 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1,
2547 (cflag & PARENB ? (cflag & PARODD ? CSP_OD : CSP_EV) : CSP_NP)
2551 /* byte size and parity */
2552 if ( (CSIZE & cflag)^(CSIZE & o_tios->c_cflag))
2555 switch ( cflag & CSIZE ) {
2556 case CS5: datasize = CSZ_5; break;
2557 case CS6: datasize = CSZ_6; break;
2558 case CS7: datasize = CSZ_7; break;
2559 case CS8: datasize = CSZ_8; break;
2560 default: datasize = CSZ_5; break; /* as per serial.c */
2562 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1, CMD_SETBITS(datasize) );
2564 /* Process CTS flow control flag setting */
2565 if ( (cflag & CRTSCTS) ) {
2566 i2QueueCommands(PTYPE_INLINE, pCh, 100,
2567 2, CMD_CTSFL_ENAB, CMD_RTSFL_ENAB);
2569 i2QueueCommands(PTYPE_INLINE, pCh, 100,
2570 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB);
2573 // Process XON/XOFF flow control flags settings
2575 stop_char = STOP_CHAR(pCh->pTTY);
2576 start_char = START_CHAR(pCh->pTTY);
2578 //////////// can't be \000
2579 if (stop_char == __DISABLED_CHAR )
2581 stop_char = ~__DISABLED_CHAR;
2583 if (start_char == __DISABLED_CHAR )
2585 start_char = ~__DISABLED_CHAR;
2587 /////////////////////////////////
2589 if ( o_tios->c_cc[VSTART] != start_char )
2591 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DEF_IXON(start_char));
2592 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DEF_OXON(start_char));
2594 if ( o_tios->c_cc[VSTOP] != stop_char )
2596 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DEF_IXOFF(stop_char));
2597 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DEF_OXOFF(stop_char));
2599 if (stop_char == __DISABLED_CHAR )
2601 stop_char = ~__DISABLED_CHAR; //TEST123
2604 if ((iflag & (IXOFF))^(o_tios->c_iflag & (IXOFF)))
2606 if ( iflag & IXOFF ) { // Enable XOFF output flow control
2607 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_OXON_OPT(COX_XON));
2608 } else { // Disable XOFF output flow control
2610 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_OXON_OPT(COX_NONE));
2613 if (start_char == __DISABLED_CHAR )
2617 if ((iflag & (IXON|IXANY)) ^ (o_tios->c_iflag & (IXON|IXANY)))
2619 if ( iflag & IXON ) {
2620 if ( iflag & IXANY ) { // Enable XON/XANY output flow control
2621 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_XANY));
2622 } else { // Enable XON output flow control
2623 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_XON));
2625 } else { // Disable XON output flow control
2627 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_NONE));
2630 if ( (iflag & ISTRIP) ^ ( o_tios->c_iflag & (ISTRIP)) )
2632 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1,
2633 CMD_ISTRIP_OPT((iflag & ISTRIP ? 1 : 0)));
2635 if ( (iflag & INPCK) ^ ( o_tios->c_iflag & (INPCK)) )
2637 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1,
2638 CMD_PARCHK((iflag & INPCK) ? CPK_ENAB : CPK_DSAB));
2641 if ( (iflag & (IGNBRK|PARMRK|BRKINT|IGNPAR))
2642 ^ ( o_tios->c_iflag & (IGNBRK|PARMRK|BRKINT|IGNPAR)) )
2647 if ( iflag & IGNBRK ) { /* Ignore breaks altogether */
2648 /* Ignore breaks altogether */
2649 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_BRK_NREP);
2651 if ( iflag & BRKINT ) {
2652 if ( iflag & PARMRK ) {
2653 brkrpt = 0x0a; // exception an inline triple
2655 brkrpt = 0x1a; // exception and NULL
2657 brkrpt |= 0x04; // flush input
2659 if ( iflag & PARMRK ) {
2660 brkrpt = 0x0b; //POSIX triple \0377 \0 \0
2662 brkrpt = 0x01; // Null only
2665 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_BRK_REP(brkrpt));
2668 if (iflag & IGNPAR) {
2670 /* would be 2 for not cirrus bug */
2671 /* would be 0x20 cept for cirrus bug */
2673 if ( iflag & PARMRK ) {
2675 * Replace error characters with 3-byte sequence (\0377,\0,char)
2678 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_ISTRIP_OPT((char)0));
2683 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_SET_ERROR(parrpt));
2685 if (cflag & CLOCAL) {
2686 // Status reporting fails for DCD if this is off
2687 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DCD_NREP);
2688 pCh->flags &= ~ASYNC_CHECK_CD;
2690 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DCD_REP);
2691 pCh->flags |= ASYNC_CHECK_CD;
2695 do_flags_thing: // This is a test, we don't do the flags thing
2697 if ( (cflag & CRTSCTS) ) {
2698 cflag |= 014000000000;
2700 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1,
2701 CMD_UNIX_FLAGS(iflag,cflag,lflag));
2705 i2DrainOutput( pCh, 100 );
2708 /******************************************************************************/
2709 /* IPL Device Section */
2710 /******************************************************************************/
2712 /******************************************************************************/
2713 /* Function: ip2_ipl_read() */
2714 /* Parameters: Pointer to device inode */
2715 /* Pointer to file structure */
2716 /* Pointer to data */
2717 /* Number of bytes to read */
2718 /* Returns: Success or failure */
2720 /* Description: Ugly */
2723 /******************************************************************************/
2727 ip2_ipl_read(struct file *pFile, char __user *pData, size_t count, loff_t *off )
2729 unsigned int minor = iminor(pFile->f_dentry->d_inode);
2733 printk (KERN_DEBUG "IP2IPL: read %p, %d bytes\n", pData, count );
2737 case 0: // IPL device
2740 case 1: // Status dump
2743 case 2: // Ping device
2746 case 3: // Trace device
2747 rc = DumpTraceBuffer ( pData, count );
2749 case 4: // Trace device
2750 rc = DumpFifoBuffer ( pData, count );
2760 DumpFifoBuffer ( char __user *pData, int count )
2764 rc = copy_to_user(pData, DBGBuf, count);
2766 printk(KERN_DEBUG "Last index %d\n", I );
2769 #endif /* DEBUG_FIFO */
2774 DumpTraceBuffer ( char __user *pData, int count )
2776 #ifdef IP2DEBUG_TRACE
2780 int *pIndex = (int __user *)pData;
2782 if ( count < (sizeof(int) * 6) ) {
2785 rc = put_user(tracewrap, pIndex );
2786 rc = put_user(TRACEMAX, ++pIndex );
2787 rc = put_user(tracestrip, ++pIndex );
2788 rc = put_user(tracestuff, ++pIndex );
2789 pData += sizeof(int) * 6;
2790 count -= sizeof(int) * 6;
2792 dumpcount = tracestuff - tracestrip;
2793 if ( dumpcount < 0 ) {
2794 dumpcount += TRACEMAX;
2796 if ( dumpcount > count ) {
2799 chunk = TRACEMAX - tracestrip;
2800 if ( dumpcount > chunk ) {
2801 rc = copy_to_user(pData, &tracebuf[tracestrip],
2802 chunk * sizeof(tracebuf[0]) );
2803 pData += chunk * sizeof(tracebuf[0]);
2805 chunk = dumpcount - chunk;
2809 rc = copy_to_user(pData, &tracebuf[tracestrip],
2810 chunk * sizeof(tracebuf[0]) );
2811 tracestrip += chunk;
2814 rc = put_user(tracestrip, ++pIndex );
2815 rc = put_user(tracestuff, ++pIndex );
2823 /******************************************************************************/
2824 /* Function: ip2_ipl_write() */
2826 /* Pointer to file structure */
2827 /* Pointer to data */
2828 /* Number of bytes to write */
2829 /* Returns: Success or failure */
2834 /******************************************************************************/
2836 ip2_ipl_write(struct file *pFile, const char __user *pData, size_t count, loff_t *off)
2839 printk (KERN_DEBUG "IP2IPL: write %p, %d bytes\n", pData, count );
2844 /******************************************************************************/
2845 /* Function: ip2_ipl_ioctl() */
2846 /* Parameters: Pointer to device inode */
2847 /* Pointer to file structure */
2850 /* Returns: Success or failure */
2855 /******************************************************************************/
2857 ip2_ipl_ioctl ( struct inode *pInode, struct file *pFile, UINT cmd, ULONG arg )
2859 unsigned int iplminor = iminor(pInode);
2861 void __user *argp = (void __user *)arg;
2862 ULONG __user *pIndex = argp;
2863 i2eBordStrPtr pB = i2BoardPtrTable[iplminor / 4];
2867 printk (KERN_DEBUG "IP2IPL: ioctl cmd %d, arg %ld\n", cmd, arg );
2870 switch ( iplminor ) {
2871 case 0: // IPL device
2874 case 1: // Status dump
2879 case 64: /* Driver - ip2stat */
2880 rc = put_user(ip2_tty_driver->refcount, pIndex++ );
2881 rc = put_user(irq_counter, pIndex++ );
2882 rc = put_user(bh_counter, pIndex++ );
2885 case 65: /* Board - ip2stat */
2887 rc = copy_to_user(argp, pB, sizeof(i2eBordStr));
2888 rc = put_user(INB(pB->i2eStatus),
2889 (ULONG __user *)(arg + (ULONG)(&pB->i2eStatus) - (ULONG)pB ) );
2896 if (cmd < IP2_MAX_PORTS) {
2897 pCh = DevTable[cmd];
2900 rc = copy_to_user(argp, pCh, sizeof(i2ChanStr));
2910 case 2: // Ping device
2913 case 3: // Trace device
2915 rc = put_user(iiSendPendingMail, pIndex++ );
2916 rc = put_user(i2InitChannels, pIndex++ );
2917 rc = put_user(i2QueueNeeds, pIndex++ );
2918 rc = put_user(i2QueueCommands, pIndex++ );
2919 rc = put_user(i2GetStatus, pIndex++ );
2920 rc = put_user(i2Input, pIndex++ );
2921 rc = put_user(i2InputFlush, pIndex++ );
2922 rc = put_user(i2Output, pIndex++ );
2923 rc = put_user(i2FlushOutput, pIndex++ );
2924 rc = put_user(i2DrainWakeup, pIndex++ );
2925 rc = put_user(i2DrainOutput, pIndex++ );
2926 rc = put_user(i2OutputFree, pIndex++ );
2927 rc = put_user(i2StripFifo, pIndex++ );
2928 rc = put_user(i2StuffFifoBypass, pIndex++ );
2929 rc = put_user(i2StuffFifoFlow, pIndex++ );
2930 rc = put_user(i2StuffFifoInline, pIndex++ );
2931 rc = put_user(i2ServiceBoard, pIndex++ );
2932 rc = put_user(serviceOutgoingFifo, pIndex++ );
2933 // rc = put_user(ip2_init, pIndex++ );
2934 rc = put_user(ip2_init_board, pIndex++ );
2935 rc = put_user(find_eisa_board, pIndex++ );
2936 rc = put_user(set_irq, pIndex++ );
2937 rc = put_user(ip2_interrupt, pIndex++ );
2938 rc = put_user(ip2_poll, pIndex++ );
2939 rc = put_user(service_all_boards, pIndex++ );
2940 rc = put_user(do_input, pIndex++ );
2941 rc = put_user(do_status, pIndex++ );
2942 #ifndef IP2DEBUG_OPEN
2943 rc = put_user(0, pIndex++ );
2945 rc = put_user(open_sanity_check, pIndex++ );
2947 rc = put_user(ip2_open, pIndex++ );
2948 rc = put_user(ip2_close, pIndex++ );
2949 rc = put_user(ip2_hangup, pIndex++ );
2950 rc = put_user(ip2_write, pIndex++ );
2951 rc = put_user(ip2_putchar, pIndex++ );
2952 rc = put_user(ip2_flush_chars, pIndex++ );
2953 rc = put_user(ip2_write_room, pIndex++ );
2954 rc = put_user(ip2_chars_in_buf, pIndex++ );
2955 rc = put_user(ip2_flush_buffer, pIndex++ );
2957 //rc = put_user(ip2_wait_until_sent, pIndex++ );
2958 rc = put_user(0, pIndex++ );
2960 rc = put_user(ip2_throttle, pIndex++ );
2961 rc = put_user(ip2_unthrottle, pIndex++ );
2962 rc = put_user(ip2_ioctl, pIndex++ );
2963 rc = put_user(0, pIndex++ );
2964 rc = put_user(get_serial_info, pIndex++ );
2965 rc = put_user(set_serial_info, pIndex++ );
2966 rc = put_user(ip2_set_termios, pIndex++ );
2967 rc = put_user(ip2_set_line_discipline, pIndex++ );
2968 rc = put_user(set_params, pIndex++ );
2982 /******************************************************************************/
2983 /* Function: ip2_ipl_open() */
2984 /* Parameters: Pointer to device inode */
2985 /* Pointer to file structure */
2986 /* Returns: Success or failure */
2991 /******************************************************************************/
2993 ip2_ipl_open( struct inode *pInode, struct file *pFile )
2995 unsigned int iplminor = iminor(pInode);
3000 printk (KERN_DEBUG "IP2IPL: open\n" );
3004 // These are the IPL devices
3011 // These are the status devices
3018 // These are the debug devices
3023 pB = i2BoardPtrTable[iplminor / 4];
3024 pCh = (i2ChanStrPtr) pB->i2eChannelPtr;
3027 // This is the trace device
3033 /******************************************************************************/
3034 /* Function: ip2_read_procmem */
3037 /* Returns: Length of output */
3040 /* Supplies some driver operating parameters */
3041 /* Not real useful unless your debugging the fifo */
3043 /******************************************************************************/
3045 #define LIMIT (PAGE_SIZE - 120)
3048 ip2_read_procmem(char *buf, char **start, off_t offset, int len)
3057 #define FMTLINE "%3d: 0x%08x 0x%08x 0%011o 0%011o\n"
3058 #define FMTLIN2 " 0x%04x 0x%04x tx flow 0x%x\n"
3059 #define FMTLIN3 " 0x%04x 0x%04x rc flow\n"
3061 len += sprintf(buf+len,"\n");
3063 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
3064 pB = i2BoardPtrTable[i];
3066 len += sprintf(buf+len,"board %d:\n",i);
3067 len += sprintf(buf+len,"\tFifo rem: %d mty: %x outM %x\n",
3068 pB->i2eFifoRemains,pB->i2eWaitingForEmptyFifo,pB->i2eOutMailWaiting);
3072 len += sprintf(buf+len,"#: tty flags, port flags, cflags, iflags\n");
3073 for (i=0; i < IP2_MAX_PORTS; i++) {
3079 if (tty && tty->count) {
3080 len += sprintf(buf+len,FMTLINE,i,(int)tty->flags,pCh->flags,
3081 tty->termios->c_cflag,tty->termios->c_iflag);
3083 len += sprintf(buf+len,FMTLIN2,
3084 pCh->outfl.asof,pCh->outfl.room,pCh->channelNeeds);
3085 len += sprintf(buf+len,FMTLIN3,pCh->infl.asof,pCh->infl.room);
3093 * This is the handler for /proc/tty/driver/ip2
3095 * This stretch of code has been largely plagerized from at least three
3096 * different sources including ip2mkdev.c and a couple of other drivers.
3097 * The bugs are all mine. :-) =mhw=
3099 static int ip2_read_proc(char *page, char **start, off_t off,
3100 int count, int *eof, void *data)
3110 len += sprintf(page, "ip2info: 1.0 driver: %s\n", pcVersion );
3111 len += sprintf(page+len, "Driver: SMajor=%d CMajor=%d IMajor=%d MaxBoards=%d MaxBoxes=%d MaxPorts=%d\n",
3112 IP2_TTY_MAJOR, IP2_CALLOUT_MAJOR, IP2_IPL_MAJOR,
3113 IP2_MAX_BOARDS, ABS_MAX_BOXES, ABS_BIGGEST_BOX);
3115 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
3116 /* This need to be reset for a board by board count... */
3118 pB = i2BoardPtrTable[i];
3120 switch( pB->i2ePom.e.porID & ~POR_ID_RESERVED )
3123 len += sprintf( page+len, "Board %d: EX ports=", i );
3124 for( box = 0; box < ABS_MAX_BOXES; ++box )
3128 if( pB->i2eChannelMap[box] != 0 ) ++boxes;
3129 for( j = 0; j < ABS_BIGGEST_BOX; ++j )
3131 if( pB->i2eChannelMap[box] & 1<< j ) {
3135 len += sprintf( page+len, "%d,", ports );
3139 --len; /* Backup over that last comma */
3141 len += sprintf( page+len, " boxes=%d width=%d", boxes, pB->i2eDataWidth16 ? 16 : 8 );
3145 len += sprintf(page+len, "Board %d: ISA-4 ports=4 boxes=1", i );
3150 len += sprintf(page+len, "Board %d: ISA-8-std ports=8 boxes=1", i );
3155 len += sprintf(page+len, "Board %d: ISA-8-RJ11 ports=8 boxes=1", i );
3160 len += sprintf(page+len, "Board %d: unknown", i );
3161 /* Don't try and probe for minor numbers */
3166 /* Don't try and probe for minor numbers */
3167 len += sprintf(page+len, "Board %d: vacant", i );
3172 len += sprintf(page+len, " minors=" );
3174 for ( box = 0; box < ABS_MAX_BOXES; ++box )
3176 for ( j = 0; j < ABS_BIGGEST_BOX; ++j )
3178 if ( pB->i2eChannelMap[box] & (1 << j) )
3180 len += sprintf (page+len,"%d,",
3181 j + ABS_BIGGEST_BOX *
3182 (box+i*ABS_MAX_BOXES));
3187 page[ len - 1 ] = '\n'; /* Overwrite that last comma */
3189 len += sprintf (page+len,"\n" );
3192 if (len+begin > off+count)
3194 if (len+begin < off) {
3200 if (i >= IP2_MAX_BOARDS)
3202 if (off >= len+begin)
3205 *start = page + (off-begin);
3206 return ((count < begin+len-off) ? count : begin+len-off);
3209 /******************************************************************************/
3210 /* Function: ip2trace() */
3211 /* Parameters: Value to add to trace buffer */
3212 /* Returns: Nothing */
3217 /******************************************************************************/
3218 #ifdef IP2DEBUG_TRACE
3220 ip2trace (unsigned short pn, unsigned char cat, unsigned char label, unsigned long codes, ...)
3223 unsigned long *pCode = &codes;
3224 union ip2breadcrumb bc;
3228 tracebuf[tracestuff++] = jiffies;
3229 if ( tracestuff == TRACEMAX ) {
3232 if ( tracestuff == tracestrip ) {
3233 if ( ++tracestrip == TRACEMAX ) {
3239 bc.hdr.port = 0xff & pn;
3241 bc.hdr.codes = (unsigned char)( codes & 0xff );
3242 bc.hdr.label = label;
3243 tracebuf[tracestuff++] = bc.value;
3246 if ( tracestuff == TRACEMAX ) {
3249 if ( tracestuff == tracestrip ) {
3250 if ( ++tracestrip == TRACEMAX ) {
3259 tracebuf[tracestuff++] = *++pCode;
3265 MODULE_LICENSE("GPL");