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>
124 #include <asm/uaccess.h>
126 #include "./ip2/ip2types.h"
127 #include "./ip2/ip2trace.h"
128 #include "./ip2/ip2ioctl.h"
129 #include "./ip2/ip2.h"
130 #include "./ip2/i2ellis.h"
131 #include "./ip2/i2lib.h"
137 #include <linux/proc_fs.h>
139 static int ip2_read_procmem(char *, char **, off_t, int);
140 static int ip2_read_proc(char *, char **, off_t, int, int *, void * );
142 /********************/
143 /* Type Definitions */
144 /********************/
150 /* String constants to identify ourselves */
151 static char *pcName = "Computone IntelliPort Plus multiport driver";
152 static char *pcVersion = "1.2.14";
154 /* String constants for port names */
155 static char *pcDriver_name = "ip2";
156 static char *pcIpl = "ip2ipl";
158 /* Serial subtype definitions */
159 #define SERIAL_TYPE_NORMAL 1
161 // cheezy kludge or genius - you decide?
162 int ip2_loadmain(int *, int *, unsigned char *, int);
163 static unsigned char *Fip_firmware;
164 static int Fip_firmware_size;
166 /***********************/
167 /* Function Prototypes */
168 /***********************/
170 /* Global module entry functions */
172 /* Private (static) functions */
173 static int ip2_open(PTTY, struct file *);
174 static void ip2_close(PTTY, struct file *);
175 static int ip2_write(PTTY, int, const unsigned char *, int);
176 static void ip2_putchar(PTTY, unsigned char);
177 static void ip2_flush_chars(PTTY);
178 static int ip2_write_room(PTTY);
179 static int ip2_chars_in_buf(PTTY);
180 static void ip2_flush_buffer(PTTY);
181 static int ip2_ioctl(PTTY, struct file *, UINT, ULONG);
182 static void ip2_set_termios(PTTY, struct termios *);
183 static void ip2_set_line_discipline(PTTY);
184 static void ip2_throttle(PTTY);
185 static void ip2_unthrottle(PTTY);
186 static void ip2_stop(PTTY);
187 static void ip2_start(PTTY);
188 static void ip2_hangup(PTTY);
189 static int ip2_tiocmget(struct tty_struct *tty, struct file *file);
190 static int ip2_tiocmset(struct tty_struct *tty, struct file *file,
191 unsigned int set, unsigned int clear);
193 static void set_irq(int, int);
194 static void ip2_interrupt_bh(i2eBordStrPtr pB);
195 static irqreturn_t ip2_interrupt(int irq, void *dev_id, struct pt_regs * regs);
196 static void ip2_poll(unsigned long arg);
197 static inline void service_all_boards(void);
198 static void do_input(void *p);
199 static void do_status(void *p);
201 static void ip2_wait_until_sent(PTTY,int);
203 static void set_params (i2ChanStrPtr, struct termios *);
204 static int get_serial_info(i2ChanStrPtr, struct serial_struct __user *);
205 static int set_serial_info(i2ChanStrPtr, struct serial_struct __user *);
207 static ssize_t ip2_ipl_read(struct file *, char __user *, size_t, loff_t *);
208 static ssize_t ip2_ipl_write(struct file *, const char __user *, size_t, loff_t *);
209 static int ip2_ipl_ioctl(struct inode *, struct file *, UINT, ULONG);
210 static int ip2_ipl_open(struct inode *, struct file *);
212 static int DumpTraceBuffer(char __user *, int);
213 static int DumpFifoBuffer( char __user *, int);
215 static void ip2_init_board(int);
216 static unsigned short find_eisa_board(int);
222 static struct tty_driver *ip2_tty_driver;
224 /* Here, then is a table of board pointers which the interrupt routine should
225 * scan through to determine who it must service.
227 static unsigned short i2nBoards; // Number of boards here
229 static i2eBordStrPtr i2BoardPtrTable[IP2_MAX_BOARDS];
231 static i2ChanStrPtr DevTable[IP2_MAX_PORTS];
232 //DevTableMem just used to save addresses for kfree
233 static void *DevTableMem[IP2_MAX_BOARDS];
235 /* This is the driver descriptor for the ip2ipl device, which is used to
236 * download the loadware to the boards.
238 static struct file_operations ip2_ipl = {
239 .owner = THIS_MODULE,
240 .read = ip2_ipl_read,
241 .write = ip2_ipl_write,
242 .ioctl = ip2_ipl_ioctl,
243 .open = ip2_ipl_open,
246 static unsigned long irq_counter = 0;
247 static unsigned long bh_counter = 0;
249 // Use immediate queue to service interrupts
251 //#define USE_IQ // PCI&2.2 needs work
253 /* The timer_list entry for our poll routine. If interrupt operation is not
254 * selected, the board is serviced periodically to see if anything needs doing.
256 #define POLL_TIMEOUT (jiffies + 1)
257 static DEFINE_TIMER(PollTimer, ip2_poll, 0, 0);
260 #ifdef IP2DEBUG_TRACE
261 /* Trace (debug) buffer data */
262 #define TRACEMAX 1000
263 static unsigned long tracebuf[TRACEMAX];
264 static int tracestuff;
265 static int tracestrip;
266 static int tracewrap;
273 #if defined(MODULE) && defined(IP2DEBUG_OPEN)
274 #define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] refc=%d, ttyc=%d, modc=%x -> %s\n", \
275 tty->name,(pCh->flags),ip2_tty_driver->refcount, \
276 tty->count,/*GET_USE_COUNT(module)*/0,s)
285 #include "./ip2/i2ellis.c" /* Extremely low-level interface services */
286 #include "./ip2/i2cmd.c" /* Standard loadware command definitions */
287 #include "./ip2/i2lib.c" /* High level interface services */
289 /* Configuration area for modprobe */
291 MODULE_AUTHOR("Doug McNash");
292 MODULE_DESCRIPTION("Computone IntelliPort Plus Driver");
294 static int poll_only = 0;
297 static int Eisa_slot;
300 static char rirqs[IP2_MAX_BOARDS];
301 static int Valid_Irqs[] = { 3, 4, 5, 7, 10, 11, 12, 15, 0};
303 /* for sysfs class support */
304 static struct class *ip2_class;
306 // Some functions to keep track of what irq's we have
309 is_valid_irq(int irq)
313 while ((*i != 0) && (*i != irq)) {
320 mark_requested_irq( char irq )
322 rirqs[iindx++] = irq;
327 clear_requested_irq( char irq )
330 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
331 if (rirqs[i] == irq) {
341 have_requested_irq( char irq )
343 // array init to zeros so 0 irq will not be requested as a side effect
345 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
352 /******************************************************************************/
353 /* Function: init_module() */
354 /* Parameters: None */
355 /* Returns: Success (0) */
358 /* This is a required entry point for an installable module. It simply calls */
359 /* the driver initialisation function and returns what it returns. */
360 /******************************************************************************/
366 printk (KERN_DEBUG "Loading module ...\n" );
372 /******************************************************************************/
373 /* Function: cleanup_module() */
374 /* Parameters: None */
375 /* Returns: Nothing */
378 /* This is a required entry point for an installable module. It has to return */
379 /* the device and the driver to a passive state. It should not be necessary */
380 /* to reset the board fully, especially as the loadware is downloaded */
381 /* externally rather than in the driver. We just want to disable the board */
382 /* and clear the loadware to a reset state. To allow this there has to be a */
383 /* way to detect whether the board has the loadware running at init time to */
384 /* handle subsequent installations of the driver. All memory allocated by the */
385 /* driver should be returned since it may be unloaded from memory. */
386 /******************************************************************************/
395 printk (KERN_DEBUG "Unloading %s: version %s\n", pcName, pcVersion );
397 /* Stop poll timer if we had one. */
399 del_timer ( &PollTimer );
403 /* Reset the boards we have. */
404 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
405 if ( i2BoardPtrTable[i] ) {
406 iiReset( i2BoardPtrTable[i] );
410 /* The following is done at most once, if any boards were installed. */
411 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
412 if ( i2BoardPtrTable[i] ) {
413 iiResetDelay( i2BoardPtrTable[i] );
414 /* free io addresses and Tibet */
415 release_region( ip2config.addr[i], 8 );
416 class_device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i));
417 devfs_remove("ip2/ipl%d", i);
418 class_device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i + 1));
419 devfs_remove("ip2/stat%d", i);
421 /* Disable and remove interrupt handler. */
422 if ( (ip2config.irq[i] > 0) && have_requested_irq(ip2config.irq[i]) ) {
423 free_irq ( ip2config.irq[i], (void *)&pcName);
424 clear_requested_irq( ip2config.irq[i]);
427 class_destroy(ip2_class);
429 if ( ( err = tty_unregister_driver ( ip2_tty_driver ) ) ) {
430 printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n", err);
432 put_tty_driver(ip2_tty_driver);
433 if ( ( err = unregister_chrdev ( IP2_IPL_MAJOR, pcIpl ) ) ) {
434 printk(KERN_ERR "IP2: failed to unregister IPL driver (%d)\n", err);
436 remove_proc_entry("ip2mem", &proc_root);
439 for (i = 0; i < IP2_MAX_BOARDS; i++) {
442 if (ip2config.type[i] == PCI && ip2config.pci_dev[i]) {
443 pci_disable_device(ip2config.pci_dev[i]);
444 ip2config.pci_dev[i] = NULL;
447 if ((pB = i2BoardPtrTable[i]) != 0 ) {
449 i2BoardPtrTable[i] = NULL;
451 if ((DevTableMem[i]) != NULL ) {
452 kfree ( DevTableMem[i] );
453 DevTableMem[i] = NULL;
457 /* Cleanup the iiEllis subsystem. */
460 printk (KERN_DEBUG "IP2 Unloaded\n" );
465 static struct tty_operations ip2_ops = {
469 .put_char = ip2_putchar,
470 .flush_chars = ip2_flush_chars,
471 .write_room = ip2_write_room,
472 .chars_in_buffer = ip2_chars_in_buf,
473 .flush_buffer = ip2_flush_buffer,
475 .throttle = ip2_throttle,
476 .unthrottle = ip2_unthrottle,
477 .set_termios = ip2_set_termios,
478 .set_ldisc = ip2_set_line_discipline,
481 .hangup = ip2_hangup,
482 .read_proc = ip2_read_proc,
483 .tiocmget = ip2_tiocmget,
484 .tiocmset = ip2_tiocmset,
487 /******************************************************************************/
488 /* Function: ip2_loadmain() */
489 /* Parameters: irq, io from command line of insmod et. al. */
490 /* pointer to fip firmware and firmware size for boards */
491 /* Returns: Success (0) */
494 /* This was the required entry point for all drivers (now in ip2.c) */
495 /* It performs all */
496 /* initialisation of the devices and driver structures, and registers itself */
497 /* with the relevant kernel modules. */
498 /******************************************************************************/
499 /* SA_INTERRUPT- if set blocks all interrupts else only this line */
500 /* SA_SHIRQ - for shared irq PCI or maybe EISA only */
501 /* SA_RANDOM - can be source for cert. random number generators */
502 #define IP2_SA_FLAGS 0
505 ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize)
511 i2eBordStrPtr pB = NULL;
514 ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0 );
516 /* process command line arguments to modprobe or
517 insmod i.e. iop & irqp */
518 /* irqp and iop should ALWAYS be specified now... But we check
519 them individually just to be sure, anyways... */
520 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
522 ip2config.addr[i] = iop[i];
525 ip2config.irq[i] = irqp[i];
527 ip2config.irq[i] = 0;
529 // This is a little bit of a hack. If poll_only=1 on command
530 // line back in ip2.c OR all IRQs on all specified boards are
531 // explicitly set to 0, then drop to poll only mode and override
532 // PCI or EISA interrupts. This superceeds the old hack of
533 // triggering if all interrupts were zero (like da default).
534 // Still a hack but less prone to random acts of terrorism.
536 // What we really should do, now that the IRQ default is set
537 // to -1, is to use 0 as a hard coded, do not probe.
540 poll_only |= irqp[i];
544 poll_only = !poll_only;
546 Fip_firmware = firmware;
547 Fip_firmware_size = firmsize;
549 /* Announce our presence */
550 printk( KERN_INFO "%s version %s\n", pcName, pcVersion );
552 // ip2 can be unloaded and reloaded for no good reason
553 // we can't let that happen here or bad things happen
554 // second load hoses board but not system - fixme later
556 printk( KERN_INFO "Still loaded\n" );
561 ip2_tty_driver = alloc_tty_driver(IP2_MAX_PORTS);
565 /* Initialise the iiEllis subsystem. */
568 /* Initialize arrays. */
569 memset( i2BoardPtrTable, 0, sizeof i2BoardPtrTable );
570 memset( DevTable, 0, sizeof DevTable );
572 /* Initialise all the boards we can find (up to the maximum). */
573 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
574 switch ( ip2config.addr[i] ) {
575 case 0: /* skip this slot even if card is present */
578 /* ISA address must be specified */
579 if ( (ip2config.addr[i] < 0x100) || (ip2config.addr[i] > 0x3f8) ) {
580 printk ( KERN_ERR "IP2: Bad ISA board %d address %x\n",
581 i, ip2config.addr[i] );
582 ip2config.addr[i] = 0;
584 ip2config.type[i] = ISA;
586 /* Check for valid irq argument, set for polling if invalid */
587 if (ip2config.irq[i] && !is_valid_irq(ip2config.irq[i])) {
588 printk(KERN_ERR "IP2: Bad IRQ(%d) specified\n",ip2config.irq[i]);
589 ip2config.irq[i] = 0;// 0 is polling and is valid in that sense
596 struct pci_dev *pci_dev_i = NULL;
597 pci_dev_i = pci_find_device(PCI_VENDOR_ID_COMPUTONE,
598 PCI_DEVICE_ID_COMPUTONE_IP2EX, pci_dev_i);
599 if (pci_dev_i != NULL) {
602 if (pci_enable_device(pci_dev_i)) {
603 printk( KERN_ERR "IP2: can't enable PCI device at %s\n",
604 pci_name(pci_dev_i));
607 ip2config.type[i] = PCI;
608 ip2config.pci_dev[i] = pci_dev_i;
610 pci_read_config_dword(pci_dev_i, PCI_BASE_ADDRESS_1, &addr);
612 ip2config.addr[i]=(USHORT)(addr&0xfffe);
614 printk( KERN_ERR "IP2: PCI I/O address error\n");
617 // If the PCI BIOS assigned it, lets try and use it. If we
618 // can't acquire it or it screws up, deal with it then.
620 // if (!is_valid_irq(pci_irq)) {
621 // printk( KERN_ERR "IP2: Bad PCI BIOS IRQ(%d)\n",pci_irq);
624 ip2config.irq[i] = pci_dev_i->irq;
625 } else { // ann error
626 ip2config.addr[i] = 0;
627 if (status == PCIBIOS_DEVICE_NOT_FOUND) {
628 printk( KERN_ERR "IP2: PCI board %d not found\n", i );
630 printk( KERN_ERR "IP2: PCI error 0x%x \n", status );
635 printk( KERN_ERR "IP2: PCI card specified but PCI support not\n");
636 printk( KERN_ERR "IP2: configured in this kernel.\n");
637 printk( KERN_ERR "IP2: Recompile kernel with CONFIG_PCI defined!\n");
638 #endif /* CONFIG_PCI */
641 if ( (ip2config.addr[i] = find_eisa_board( Eisa_slot + 1 )) != 0) {
642 /* Eisa_irq set as side effect, boo */
643 ip2config.type[i] = EISA;
645 ip2config.irq[i] = Eisa_irq;
649 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
650 if ( ip2config.addr[i] ) {
651 pB = kmalloc( sizeof(i2eBordStr), GFP_KERNEL);
653 i2BoardPtrTable[i] = pB;
654 memset( pB, 0, sizeof(i2eBordStr) );
655 iiSetAddress( pB, ip2config.addr[i], ii2DelayTimer );
658 printk(KERN_ERR "IP2: board memory allocation error\n");
662 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
663 if ( ( pB = i2BoardPtrTable[i] ) != NULL ) {
668 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
669 if ( i2BoardPtrTable[i] != NULL ) {
674 ip2trace (ITRC_NO_PORT, ITRC_INIT, 2, 0 );
676 ip2_tty_driver->owner = THIS_MODULE;
677 ip2_tty_driver->name = "ttyF";
678 ip2_tty_driver->devfs_name = "tts/F";
679 ip2_tty_driver->driver_name = pcDriver_name;
680 ip2_tty_driver->major = IP2_TTY_MAJOR;
681 ip2_tty_driver->minor_start = 0;
682 ip2_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
683 ip2_tty_driver->subtype = SERIAL_TYPE_NORMAL;
684 ip2_tty_driver->init_termios = tty_std_termios;
685 ip2_tty_driver->init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL;
686 ip2_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
687 tty_set_operations(ip2_tty_driver, &ip2_ops);
689 ip2trace (ITRC_NO_PORT, ITRC_INIT, 3, 0 );
691 /* Register the tty devices. */
692 if ( ( err = tty_register_driver ( ip2_tty_driver ) ) ) {
693 printk(KERN_ERR "IP2: failed to register tty driver (%d)\n", err);
694 put_tty_driver(ip2_tty_driver);
697 /* Register the IPL driver. */
698 if ( ( err = register_chrdev ( IP2_IPL_MAJOR, pcIpl, &ip2_ipl ) ) ) {
699 printk(KERN_ERR "IP2: failed to register IPL device (%d)\n", err );
701 /* create the sysfs class */
702 ip2_class = class_create(THIS_MODULE, "ip2");
703 if (IS_ERR(ip2_class)) {
704 err = PTR_ERR(ip2_class);
708 /* Register the read_procmem thing */
709 if (!create_proc_info_entry("ip2mem",0,&proc_root,ip2_read_procmem)) {
710 printk(KERN_ERR "IP2: failed to register read_procmem\n");
713 ip2trace (ITRC_NO_PORT, ITRC_INIT, 4, 0 );
714 /* Register the interrupt handler or poll handler, depending upon the
715 * specified interrupt.
718 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
719 if ( 0 == ip2config.addr[i] ) {
723 if ( NULL != ( pB = i2BoardPtrTable[i] ) ) {
724 class_device_create(ip2_class, MKDEV(IP2_IPL_MAJOR,
725 4 * i), NULL, "ipl%d", i);
726 err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i),
727 S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR,
730 class_device_destroy(ip2_class,
731 MKDEV(IP2_IPL_MAJOR, 4 * i));
735 class_device_create(ip2_class, MKDEV(IP2_IPL_MAJOR,
736 4 * i + 1), NULL, "stat%d", i);
737 err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
738 S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR,
741 class_device_destroy(ip2_class,
742 MKDEV(IP2_IPL_MAJOR, 4 * i + 1));
746 for ( box = 0; box < ABS_MAX_BOXES; ++box )
748 for ( j = 0; j < ABS_BIGGEST_BOX; ++j )
750 if ( pB->i2eChannelMap[box] & (1 << j) )
752 tty_register_device(ip2_tty_driver,
753 j + ABS_BIGGEST_BOX *
754 (box+i*ABS_MAX_BOXES), NULL);
761 // Poll only forces driver to only use polling and
762 // to ignore the probed PCI or EISA interrupts.
763 ip2config.irq[i] = CIR_POLL;
765 if ( ip2config.irq[i] == CIR_POLL ) {
768 PollTimer.expires = POLL_TIMEOUT;
769 add_timer ( &PollTimer );
771 printk( KERN_INFO "IP2: polling\n");
774 if (have_requested_irq(ip2config.irq[i]))
776 rc = request_irq( ip2config.irq[i], ip2_interrupt,
777 IP2_SA_FLAGS | (ip2config.type[i] == PCI ? SA_SHIRQ : 0),
778 pcName, (void *)&pcName);
780 printk(KERN_ERR "IP2: an request_irq failed: error %d\n",rc);
781 ip2config.irq[i] = CIR_POLL;
782 printk( KERN_INFO "IP2: Polling %ld/sec.\n",
783 (POLL_TIMEOUT - jiffies));
786 mark_requested_irq(ip2config.irq[i]);
787 /* Initialise the interrupt handler bottom half (aka slih). */
790 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
791 if ( i2BoardPtrTable[i] ) {
792 set_irq( i, ip2config.irq[i] ); /* set and enable board interrupt */
796 ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_RETURN, 0 );
800 class_destroy(ip2_class);
802 unregister_chrdev(IP2_IPL_MAJOR, "ip2");
807 EXPORT_SYMBOL(ip2_loadmain);
809 /******************************************************************************/
810 /* Function: ip2_init_board() */
811 /* Parameters: Index of board in configuration structure */
812 /* Returns: Success (0) */
815 /* This function initializes the specified board. The loadware is copied to */
816 /* the board, the channel structures are initialized, and the board details */
817 /* are reported on the console. */
818 /******************************************************************************/
820 ip2_init_board( int boardnum )
823 int nports = 0, nboxes = 0;
825 i2eBordStrPtr pB = i2BoardPtrTable[boardnum];
827 if ( !iiInitialize ( pB ) ) {
828 printk ( KERN_ERR "IP2: Failed to initialize board at 0x%x, error %d\n",
829 pB->i2eBase, pB->i2eError );
832 printk(KERN_INFO "IP2: Board %d: addr=0x%x irq=%d\n", boardnum + 1,
833 ip2config.addr[boardnum], ip2config.irq[boardnum] );
835 if (!request_region( ip2config.addr[boardnum], 8, pcName )) {
836 printk(KERN_ERR "IP2: bad addr=0x%x\n", ip2config.addr[boardnum]);
840 if ( iiDownloadAll ( pB, (loadHdrStrPtr)Fip_firmware, 1, Fip_firmware_size )
842 printk ( KERN_ERR "IP2: failed to download loadware\n" );
843 goto err_release_region;
845 printk ( KERN_INFO "IP2: fv=%d.%d.%d lv=%d.%d.%d\n",
846 pB->i2ePom.e.porVersion,
847 pB->i2ePom.e.porRevision,
848 pB->i2ePom.e.porSubRev, pB->i2eLVersion,
849 pB->i2eLRevision, pB->i2eLSub );
852 switch ( pB->i2ePom.e.porID & ~POR_ID_RESERVED ) {
855 printk( KERN_ERR "IP2: Unknown board type, ID = %x\n",
856 pB->i2ePom.e.porID );
858 goto err_release_region;
861 case POR_ID_II_4: /* IntelliPort-II, ISA-4 (4xRJ45) */
862 printk ( KERN_INFO "IP2: ISA-4\n" );
866 case POR_ID_II_8: /* IntelliPort-II, 8-port using standard brick. */
867 printk ( KERN_INFO "IP2: ISA-8 std\n" );
871 case POR_ID_II_8R: /* IntelliPort-II, 8-port using RJ11's (no CTS) */
872 printk ( KERN_INFO "IP2: ISA-8 RJ11\n" );
876 case POR_ID_FIIEX: /* IntelliPort IIEX */
878 int portnum = IP2_PORTS_PER_BOARD * boardnum;
881 for( box = 0; box < ABS_MAX_BOXES; ++box ) {
882 if ( pB->i2eChannelMap[box] != 0 ) {
885 for( i = 0; i < ABS_BIGGEST_BOX; ++i ) {
886 if ( pB->i2eChannelMap[box] & 1<< i ) {
891 DevTableMem[boardnum] = pCh =
892 kmalloc( sizeof(i2ChanStr) * nports, GFP_KERNEL );
894 printk ( KERN_ERR "IP2: (i2_init_channel:) Out of memory.\n");
895 goto err_release_region;
897 if ( !i2InitChannels( pB, nports, pCh ) ) {
898 printk(KERN_ERR "IP2: i2InitChannels failed: %d\n",pB->i2eError);
900 goto err_release_region;
902 pB->i2eChannelPtr = &DevTable[portnum];
903 pB->i2eChannelCnt = ABS_MOST_PORTS;
905 for( box = 0; box < ABS_MAX_BOXES; ++box, portnum += ABS_BIGGEST_BOX ) {
906 for( i = 0; i < ABS_BIGGEST_BOX; ++i ) {
907 if ( pB->i2eChannelMap[box] & (1 << i) ) {
908 DevTable[portnum + i] = pCh;
909 pCh->port_index = portnum + i;
914 printk(KERN_INFO "IP2: EX box=%d ports=%d %d bit\n",
915 nboxes, nports, pB->i2eDataWidth16 ? 16 : 8 );
919 DevTableMem[boardnum] = pCh =
920 kmalloc ( sizeof (i2ChanStr) * nports, GFP_KERNEL );
922 printk ( KERN_ERR "IP2: (i2_init_channel:) Out of memory.\n");
923 goto err_release_region;
925 pB->i2eChannelPtr = pCh;
926 pB->i2eChannelCnt = nports;
927 if ( !i2InitChannels( pB, nports, pCh ) ) {
928 printk(KERN_ERR "IP2: i2InitChannels failed: %d\n",pB->i2eError);
930 goto err_release_region;
932 pB->i2eChannelPtr = &DevTable[IP2_PORTS_PER_BOARD * boardnum];
934 for( i = 0; i < pB->i2eChannelCnt; ++i ) {
935 DevTable[IP2_PORTS_PER_BOARD * boardnum + i] = pCh;
936 pCh->port_index = (IP2_PORTS_PER_BOARD * boardnum) + i;
940 INIT_WORK(&pB->tqueue_interrupt, (void(*)(void*)) ip2_interrupt_bh, pB);
944 release_region(ip2config.addr[boardnum], 8);
947 i2BoardPtrTable[boardnum] = NULL;
951 /******************************************************************************/
952 /* Function: find_eisa_board ( int start_slot ) */
953 /* Parameters: First slot to check */
954 /* Returns: Address of EISA IntelliPort II controller */
957 /* This function searches for an EISA IntelliPort controller, starting */
958 /* from the specified slot number. If the motherboard is not identified as an */
959 /* EISA motherboard, or no valid board ID is selected it returns 0. Otherwise */
960 /* it returns the base address of the controller. */
961 /******************************************************************************/
962 static unsigned short __init
963 find_eisa_board( int start_slot )
966 unsigned int idm = 0;
967 unsigned int idp = 0;
968 unsigned int base = 0;
975 * First a check for an EISA motherboard, which we do by comparing the
976 * EISA ID registers for the system board and the first couple of slots.
977 * No slot ID should match the system board ID, but on an ISA or PCI
978 * machine the odds are that an empty bus will return similar values for
982 value = (inb(i) << 24) + (inb(i+1) << 16) + (inb(i+2) << 8) + inb(i+3);
983 for( i = 0x1c80; i <= 0x4c80; i += 0x1000 ) {
984 j = (inb(i)<<24)+(inb(i+1)<<16)+(inb(i+2)<<8)+inb(i+3);
990 * OK, so we are inclined to believe that this is an EISA machine. Find
991 * an IntelliPort controller.
993 for( i = start_slot; i < 16; i++ ) {
995 idm = (inb(base + 0xc80) << 8) | (inb(base + 0xc81) & 0xff);
996 idp = (inb(base + 0xc82) << 8) | (inb(base + 0xc83) & 0xff);
998 if ( idm == 0x0e8e ) {
999 if ( idp == 0x0281 || idp == 0x0218 ) {
1001 } else if ( idp == 0x0282 || idp == 0x0283 ) {
1002 ismine = 3; /* Can do edge-trigger */
1013 /* It's some sort of EISA card, but at what address is it configured? */
1015 setup_address = base + 0xc88;
1016 value = inb(base + 0xc86);
1017 setup_irq = (value & 8) ? Valid_Irqs[value & 7] : 0;
1019 if ( (ismine & 2) && !(value & 0x10) ) {
1020 ismine = 1; /* Could be edging, but not */
1023 if ( Eisa_irq == 0 ) {
1024 Eisa_irq = setup_irq;
1025 } else if ( Eisa_irq != setup_irq ) {
1026 printk ( KERN_ERR "IP2: EISA irq mismatch between EISA controllers\n" );
1029 #ifdef IP2DEBUG_INIT
1030 printk(KERN_DEBUG "Computone EISA board in slot %d, I.D. 0x%x%x, Address 0x%x",
1031 base >> 12, idm, idp, setup_address);
1033 printk(KERN_DEBUG ", Interrupt %d %s\n",
1034 setup_irq, (ismine & 2) ? "(edge)" : "(level)");
1036 printk(KERN_DEBUG ", (polled)\n");
1039 return setup_address;
1042 /******************************************************************************/
1043 /* Function: set_irq() */
1044 /* Parameters: index to board in board table */
1046 /* Returns: Success (0) */
1049 /******************************************************************************/
1051 set_irq( int boardnum, int boardIrq )
1053 unsigned char tempCommand[16];
1054 i2eBordStrPtr pB = i2BoardPtrTable[boardnum];
1055 unsigned long flags;
1058 * Notify the boards they may generate interrupts. This is done by
1059 * sending an in-line command to channel 0 on each board. This is why
1060 * the channels have to be defined already. For each board, if the
1061 * interrupt has never been defined, we must do so NOW, directly, since
1062 * board will not send flow control or even give an interrupt until this
1063 * is done. If polling we must send 0 as the interrupt parameter.
1066 // We will get an interrupt here at the end of this function
1068 iiDisableMailIrq(pB);
1070 /* We build up the entire packet header. */
1071 CHANNEL_OF(tempCommand) = 0;
1072 PTYPE_OF(tempCommand) = PTYPE_INLINE;
1073 CMD_COUNT_OF(tempCommand) = 2;
1074 (CMD_OF(tempCommand))[0] = CMDVALUE_IRQ;
1075 (CMD_OF(tempCommand))[1] = boardIrq;
1077 * Write to FIFO; don't bother to adjust fifo capacity for this, since
1078 * board will respond almost immediately after SendMail hit.
1080 WRITE_LOCK_IRQSAVE(&pB->write_fifo_spinlock,flags);
1081 iiWriteBuf(pB, tempCommand, 4);
1082 WRITE_UNLOCK_IRQRESTORE(&pB->write_fifo_spinlock,flags);
1083 pB->i2eUsingIrq = boardIrq;
1084 pB->i2eOutMailWaiting |= MB_OUT_STUFFED;
1086 /* Need to update number of boards before you enable mailbox int */
1089 CHANNEL_OF(tempCommand) = 0;
1090 PTYPE_OF(tempCommand) = PTYPE_BYPASS;
1091 CMD_COUNT_OF(tempCommand) = 6;
1092 (CMD_OF(tempCommand))[0] = 88; // SILO
1093 (CMD_OF(tempCommand))[1] = 64; // chars
1094 (CMD_OF(tempCommand))[2] = 32; // ms
1096 (CMD_OF(tempCommand))[3] = 28; // MAX_BLOCK
1097 (CMD_OF(tempCommand))[4] = 64; // chars
1099 (CMD_OF(tempCommand))[5] = 87; // HW_TEST
1100 WRITE_LOCK_IRQSAVE(&pB->write_fifo_spinlock,flags);
1101 iiWriteBuf(pB, tempCommand, 8);
1102 WRITE_UNLOCK_IRQRESTORE(&pB->write_fifo_spinlock,flags);
1104 CHANNEL_OF(tempCommand) = 0;
1105 PTYPE_OF(tempCommand) = PTYPE_BYPASS;
1106 CMD_COUNT_OF(tempCommand) = 1;
1107 (CMD_OF(tempCommand))[0] = 84; /* get BOX_IDS */
1108 iiWriteBuf(pB, tempCommand, 3);
1111 // enable heartbeat for test porpoises
1112 CHANNEL_OF(tempCommand) = 0;
1113 PTYPE_OF(tempCommand) = PTYPE_BYPASS;
1114 CMD_COUNT_OF(tempCommand) = 2;
1115 (CMD_OF(tempCommand))[0] = 44; /* get ping */
1116 (CMD_OF(tempCommand))[1] = 200; /* 200 ms */
1117 WRITE_LOCK_IRQSAVE(&pB->write_fifo_spinlock,flags);
1118 iiWriteBuf(pB, tempCommand, 4);
1119 WRITE_UNLOCK_IRQRESTORE(&pB->write_fifo_spinlock,flags);
1122 iiEnableMailIrq(pB);
1123 iiSendPendingMail(pB);
1126 /******************************************************************************/
1127 /* Interrupt Handler Section */
1128 /******************************************************************************/
1131 service_all_boards(void)
1136 /* Service every board on the list */
1137 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
1138 pB = i2BoardPtrTable[i];
1140 i2ServiceBoard( pB );
1146 /******************************************************************************/
1147 /* Function: ip2_interrupt_bh(pB) */
1148 /* Parameters: pB - pointer to the board structure */
1149 /* Returns: Nothing */
1152 /* Service the board in a bottom half interrupt handler and then */
1153 /* reenable the board's interrupts if it has an IRQ number */
1155 /******************************************************************************/
1157 ip2_interrupt_bh(i2eBordStrPtr pB)
1159 // pB better well be set or we have a problem! We can only get
1160 // here from the IMMEDIATE queue. Here, we process the boards.
1161 // Checking pB doesn't cost much and it saves us from the sanity checkers.
1166 i2ServiceBoard( pB );
1167 if( pB->i2eUsingIrq ) {
1168 // Re-enable his interrupts
1169 iiEnableMailIrq(pB);
1175 /******************************************************************************/
1176 /* Function: ip2_interrupt(int irq, void *dev_id, struct pt_regs * regs) */
1177 /* Parameters: irq - interrupt number */
1178 /* pointer to optional device ID structure */
1179 /* pointer to register structure */
1180 /* Returns: Nothing */
1184 /* Our task here is simply to identify each board which needs servicing. */
1185 /* If we are queuing then, queue it to be serviced, and disable its irq */
1186 /* mask otherwise process the board directly. */
1188 /* We could queue by IRQ but that just complicates things on both ends */
1189 /* with very little gain in performance (how many instructions does */
1190 /* it take to iterate on the immediate queue). */
1193 /******************************************************************************/
1195 ip2_interrupt(int irq, void *dev_id, struct pt_regs * regs)
1201 ip2trace (ITRC_NO_PORT, ITRC_INTR, 99, 1, irq );
1203 /* Service just the boards on the list using this irq */
1204 for( i = 0; i < i2nBoards; ++i ) {
1205 pB = i2BoardPtrTable[i];
1207 // Only process those boards which match our IRQ.
1208 // IRQ = 0 for polled boards, we won't poll "IRQ" boards
1210 if ( pB && (pB->i2eUsingIrq == irq) ) {
1214 if (NO_MAIL_HERE != ( pB->i2eStartMail = iiGetMail(pB))) {
1215 // Disable his interrupt (will be enabled when serviced)
1216 // This is mostly to protect from reentrancy.
1217 iiDisableMailIrq(pB);
1219 // Park the board on the immediate queue for processing.
1220 schedule_work(&pB->tqueue_interrupt);
1222 // Make sure the immediate queue is flagged to fire.
1225 // We are using immediate servicing here. This sucks and can
1226 // cause all sorts of havoc with ppp and others. The failsafe
1227 // check on iiSendPendingMail could also throw a hairball.
1228 i2ServiceBoard( pB );
1229 #endif /* USE_IQI */
1235 ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 );
1236 return IRQ_RETVAL(handled);
1239 /******************************************************************************/
1240 /* Function: ip2_poll(unsigned long arg) */
1242 /* Returns: Nothing */
1245 /* This function calls the library routine i2ServiceBoard for each board in */
1246 /* the board table. This is used instead of the interrupt routine when polled */
1247 /* mode is specified. */
1248 /******************************************************************************/
1250 ip2_poll(unsigned long arg)
1252 ip2trace (ITRC_NO_PORT, ITRC_INTR, 100, 0 );
1254 TimerOn = 0; // it's the truth but not checked in service
1256 // Just polled boards, IRQ = 0 will hit all non-interrupt boards.
1257 // It will NOT poll boards handled by hard interrupts.
1258 // The issue of queued BH interrups is handled in ip2_interrupt().
1259 ip2_interrupt(0, NULL, NULL);
1261 PollTimer.expires = POLL_TIMEOUT;
1262 add_timer( &PollTimer );
1265 ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 );
1268 static void do_input(void *p)
1270 i2ChanStrPtr pCh = p;
1271 unsigned long flags;
1273 ip2trace(CHANN, ITRC_INPUT, 21, 0 );
1276 if ( pCh->pTTY != NULL ) {
1277 READ_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,flags)
1278 if (!pCh->throttled && (pCh->Ibuf_stuff != pCh->Ibuf_strip)) {
1279 READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags)
1282 READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags)
1284 ip2trace(CHANN, ITRC_INPUT, 22, 0 );
1286 i2InputFlush( pCh );
1290 // code duplicated from n_tty (ldisc)
1291 static inline void isig(int sig, struct tty_struct *tty, int flush)
1294 kill_pg(tty->pgrp, sig, 1);
1295 if (flush || !L_NOFLSH(tty)) {
1296 if ( tty->ldisc.flush_buffer )
1297 tty->ldisc.flush_buffer(tty);
1298 i2InputFlush( tty->driver_data );
1302 static void do_status(void *p)
1304 i2ChanStrPtr pCh = p;
1307 status = i2GetStatus( pCh, (I2_BRK|I2_PAR|I2_FRA|I2_OVR) );
1309 ip2trace (CHANN, ITRC_STATUS, 21, 1, status );
1311 if (pCh->pTTY && (status & (I2_BRK|I2_PAR|I2_FRA|I2_OVR)) ) {
1312 if ( (status & I2_BRK) ) {
1313 // code duplicated from n_tty (ldisc)
1314 if (I_IGNBRK(pCh->pTTY))
1316 if (I_BRKINT(pCh->pTTY)) {
1317 isig(SIGINT, pCh->pTTY, 1);
1320 wake_up_interruptible(&pCh->pTTY->read_wait);
1322 #ifdef NEVER_HAPPENS_AS_SETUP_XXX
1323 // and can't work because we don't know the_char
1324 // as the_char is reported on a separate path
1325 // The intelligent board does this stuff as setup
1327 char brkf = TTY_NORMAL;
1328 unsigned char brkc = '\0';
1330 if ( (status & I2_BRK) ) {
1334 else if (status & I2_PAR) {
1337 } else if (status & I2_FRA) {
1340 } else if (status & I2_OVR) {
1344 tmp = pCh->pTTY->real_raw;
1345 pCh->pTTY->real_raw = 0;
1346 pCh->pTTY->ldisc.receive_buf( pCh->pTTY, &brkc, &brkf, 1 );
1347 pCh->pTTY->real_raw = tmp;
1349 #endif /* NEVER_HAPPENS_AS_SETUP_XXX */
1353 if ( status & (I2_DDCD | I2_DDSR | I2_DCTS | I2_DRI) ) {
1354 wake_up_interruptible(&pCh->delta_msr_wait);
1356 if ( (pCh->flags & ASYNC_CHECK_CD) && (status & I2_DDCD) ) {
1357 if ( status & I2_DCD ) {
1359 wake_up_interruptible ( &pCh->open_wait );
1362 if (pCh->pTTY && (!(pCh->pTTY->termios->c_cflag & CLOCAL)) ) {
1363 tty_hangup( pCh->pTTY );
1369 ip2trace (CHANN, ITRC_STATUS, 26, 0 );
1372 /******************************************************************************/
1373 /* Device Open/Close/Ioctl Entry Point Section */
1374 /******************************************************************************/
1376 /******************************************************************************/
1377 /* Function: open_sanity_check() */
1378 /* Parameters: Pointer to tty structure */
1379 /* Pointer to file structure */
1380 /* Returns: Success or failure */
1383 /* Verifies the structure magic numbers and cross links. */
1384 /******************************************************************************/
1385 #ifdef IP2DEBUG_OPEN
1387 open_sanity_check( i2ChanStrPtr pCh, i2eBordStrPtr pBrd )
1389 if ( pBrd->i2eValid != I2E_MAGIC ) {
1390 printk(KERN_ERR "IP2: invalid board structure\n" );
1391 } else if ( pBrd != pCh->pMyBord ) {
1392 printk(KERN_ERR "IP2: board structure pointer mismatch (%p)\n",
1394 } else if ( pBrd->i2eChannelCnt < pCh->port_index ) {
1395 printk(KERN_ERR "IP2: bad device index (%d)\n", pCh->port_index );
1396 } else if (&((i2ChanStrPtr)pBrd->i2eChannelPtr)[pCh->port_index] != pCh) {
1398 printk(KERN_INFO "IP2: all pointers check out!\n" );
1404 /******************************************************************************/
1405 /* Function: ip2_open() */
1406 /* Parameters: Pointer to tty structure */
1407 /* Pointer to file structure */
1408 /* Returns: Success or failure */
1410 /* Description: (MANDATORY) */
1411 /* A successful device open has to run a gauntlet of checks before it */
1412 /* completes. After some sanity checking and pointer setup, the function */
1413 /* blocks until all conditions are satisfied. It then initialises the port to */
1414 /* the default characteristics and returns. */
1415 /******************************************************************************/
1417 ip2_open( PTTY tty, struct file *pFile )
1422 i2ChanStrPtr pCh = DevTable[tty->index];
1424 ip2trace (tty->index, ITRC_OPEN, ITRC_ENTER, 0 );
1426 if ( pCh == NULL ) {
1429 /* Setup pointer links in device and tty structures */
1431 tty->driver_data = pCh;
1433 #ifdef IP2DEBUG_OPEN
1435 "IP2:open(tty=%p,pFile=%p):dev=%s,ch=%d,idx=%d\n",
1436 tty, pFile, tty->name, pCh->infl.hd.i2sChannel, pCh->port_index);
1437 open_sanity_check ( pCh, pCh->pMyBord );
1440 i2QueueCommands(PTYPE_INLINE, pCh, 100, 3, CMD_DTRUP,CMD_RTSUP,CMD_DCD_REP);
1441 pCh->dataSetOut |= (I2_DTR | I2_RTS);
1442 serviceOutgoingFifo( pCh->pMyBord );
1444 /* Block here until the port is ready (per serial and istallion) */
1446 * 1. If the port is in the middle of closing wait for the completion
1447 * and then return the appropriate error.
1449 init_waitqueue_entry(&wait, current);
1450 add_wait_queue(&pCh->close_wait, &wait);
1451 set_current_state( TASK_INTERRUPTIBLE );
1453 if ( tty_hung_up_p(pFile) || ( pCh->flags & ASYNC_CLOSING )) {
1454 if ( pCh->flags & ASYNC_CLOSING ) {
1457 if ( tty_hung_up_p(pFile) ) {
1458 set_current_state( TASK_RUNNING );
1459 remove_wait_queue(&pCh->close_wait, &wait);
1460 return( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EAGAIN : -ERESTARTSYS;
1463 set_current_state( TASK_RUNNING );
1464 remove_wait_queue(&pCh->close_wait, &wait);
1467 * 3. Handle a non-blocking open of a normal port.
1469 if ( (pFile->f_flags & O_NONBLOCK) || (tty->flags & (1<<TTY_IO_ERROR) )) {
1470 pCh->flags |= ASYNC_NORMAL_ACTIVE;
1474 * 4. Now loop waiting for the port to be free and carrier present
1477 if ( tty->termios->c_cflag & CLOCAL )
1480 #ifdef IP2DEBUG_OPEN
1481 printk(KERN_DEBUG "OpenBlock: do_clocal = %d\n", do_clocal);
1486 init_waitqueue_entry(&wait, current);
1487 add_wait_queue(&pCh->open_wait, &wait);
1490 i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_DTRUP, CMD_RTSUP);
1491 pCh->dataSetOut |= (I2_DTR | I2_RTS);
1492 set_current_state( TASK_INTERRUPTIBLE );
1493 serviceOutgoingFifo( pCh->pMyBord );
1494 if ( tty_hung_up_p(pFile) ) {
1495 set_current_state( TASK_RUNNING );
1496 remove_wait_queue(&pCh->open_wait, &wait);
1497 return ( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EBUSY : -ERESTARTSYS;
1499 if (!(pCh->flags & ASYNC_CLOSING) &&
1500 (do_clocal || (pCh->dataSetIn & I2_DCD) )) {
1505 #ifdef IP2DEBUG_OPEN
1506 printk(KERN_DEBUG "ASYNC_CLOSING = %s\n",
1507 (pCh->flags & ASYNC_CLOSING)?"True":"False");
1508 printk(KERN_DEBUG "OpenBlock: waiting for CD or signal\n");
1510 ip2trace (CHANN, ITRC_OPEN, 3, 2, 0,
1511 (pCh->flags & ASYNC_CLOSING) );
1512 /* check for signal */
1513 if (signal_pending(current)) {
1514 rc = (( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EAGAIN : -ERESTARTSYS);
1519 set_current_state( TASK_RUNNING );
1520 remove_wait_queue(&pCh->open_wait, &wait);
1522 --pCh->wopen; //why count?
1524 ip2trace (CHANN, ITRC_OPEN, 4, 0 );
1529 pCh->flags |= ASYNC_NORMAL_ACTIVE;
1533 /* first open - Assign termios structure to port */
1534 if ( tty->count == 1 ) {
1535 i2QueueCommands(PTYPE_INLINE, pCh, 0, 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB);
1536 /* Now we must send the termios settings to the loadware */
1537 set_params( pCh, NULL );
1541 * Now set any i2lib options. These may go away if the i2lib code ends
1542 * up rolled into the mainline.
1544 pCh->channelOptions |= CO_NBLOCK_WRITE;
1546 #ifdef IP2DEBUG_OPEN
1547 printk (KERN_DEBUG "IP2: open completed\n" );
1549 serviceOutgoingFifo( pCh->pMyBord );
1551 ip2trace (CHANN, ITRC_OPEN, ITRC_RETURN, 0 );
1556 /******************************************************************************/
1557 /* Function: ip2_close() */
1558 /* Parameters: Pointer to tty structure */
1559 /* Pointer to file structure */
1560 /* Returns: Nothing */
1565 /******************************************************************************/
1567 ip2_close( PTTY tty, struct file *pFile )
1569 i2ChanStrPtr pCh = tty->driver_data;
1575 ip2trace (CHANN, ITRC_CLOSE, ITRC_ENTER, 0 );
1577 #ifdef IP2DEBUG_OPEN
1578 printk(KERN_DEBUG "IP2:close %s:\n",tty->name);
1581 if ( tty_hung_up_p ( pFile ) ) {
1583 ip2trace (CHANN, ITRC_CLOSE, 2, 1, 2 );
1587 if ( tty->count > 1 ) { /* not the last close */
1589 ip2trace (CHANN, ITRC_CLOSE, 2, 1, 3 );
1593 pCh->flags |= ASYNC_CLOSING; // last close actually
1597 if (pCh->ClosingWaitTime != ASYNC_CLOSING_WAIT_NONE) {
1599 * Before we drop DTR, make sure the transmitter has completely drained.
1600 * This uses an timeout, after which the close
1603 ip2_wait_until_sent(tty, pCh->ClosingWaitTime );
1606 * At this point we stop accepting input. Here we flush the channel
1607 * input buffer which will allow the board to send up more data. Any
1608 * additional input is tossed at interrupt/poll time.
1610 i2InputFlush( pCh );
1612 /* disable DSS reporting */
1613 i2QueueCommands(PTYPE_INLINE, pCh, 100, 4,
1614 CMD_DCD_NREP, CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);
1615 if ( !tty || (tty->termios->c_cflag & HUPCL) ) {
1616 i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN);
1617 pCh->dataSetOut &= ~(I2_DTR | I2_RTS);
1618 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25));
1621 serviceOutgoingFifo ( pCh->pMyBord );
1623 if ( tty->driver->flush_buffer )
1624 tty->driver->flush_buffer(tty);
1625 if ( tty->ldisc.flush_buffer )
1626 tty->ldisc.flush_buffer(tty);
1632 if (pCh->ClosingDelay) {
1633 msleep_interruptible(jiffies_to_msecs(pCh->ClosingDelay));
1635 wake_up_interruptible(&pCh->open_wait);
1638 pCh->flags &=~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1639 wake_up_interruptible(&pCh->close_wait);
1641 #ifdef IP2DEBUG_OPEN
1642 DBG_CNT("ip2_close: after wakeups--");
1646 ip2trace (CHANN, ITRC_CLOSE, ITRC_RETURN, 1, 1 );
1651 /******************************************************************************/
1652 /* Function: ip2_hangup() */
1653 /* Parameters: Pointer to tty structure */
1654 /* Returns: Nothing */
1659 /******************************************************************************/
1661 ip2_hangup ( PTTY tty )
1663 i2ChanStrPtr pCh = tty->driver_data;
1669 ip2trace (CHANN, ITRC_HANGUP, ITRC_ENTER, 0 );
1671 ip2_flush_buffer(tty);
1673 /* disable DSS reporting */
1675 i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_DCD_NREP);
1676 i2QueueCommands(PTYPE_INLINE, pCh, 0, 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB);
1677 if ( (tty->termios->c_cflag & HUPCL) ) {
1678 i2QueueCommands(PTYPE_BYPASS, pCh, 0, 2, CMD_RTSDN, CMD_DTRDN);
1679 pCh->dataSetOut &= ~(I2_DTR | I2_RTS);
1680 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25));
1682 i2QueueCommands(PTYPE_INLINE, pCh, 1, 3,
1683 CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);
1684 serviceOutgoingFifo ( pCh->pMyBord );
1686 wake_up_interruptible ( &pCh->delta_msr_wait );
1688 pCh->flags &= ~ASYNC_NORMAL_ACTIVE;
1690 wake_up_interruptible ( &pCh->open_wait );
1692 ip2trace (CHANN, ITRC_HANGUP, ITRC_RETURN, 0 );
1695 /******************************************************************************/
1696 /******************************************************************************/
1697 /* Device Output Section */
1698 /******************************************************************************/
1699 /******************************************************************************/
1701 /******************************************************************************/
1702 /* Function: ip2_write() */
1703 /* Parameters: Pointer to tty structure */
1704 /* Flag denoting data is in user (1) or kernel (0) space */
1705 /* Pointer to data */
1706 /* Number of bytes to write */
1707 /* Returns: Number of bytes actually written */
1709 /* Description: (MANDATORY) */
1712 /******************************************************************************/
1714 ip2_write( PTTY tty, int user, const unsigned char *pData, int count)
1716 i2ChanStrPtr pCh = tty->driver_data;
1718 unsigned long flags;
1720 ip2trace (CHANN, ITRC_WRITE, ITRC_ENTER, 2, count, -1 );
1722 /* Flush out any buffered data left over from ip2_putchar() calls. */
1723 ip2_flush_chars( tty );
1725 /* This is the actual move bit. Make sure it does what we need!!!!! */
1726 WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
1727 bytesSent = i2Output( pCh, pData, count, user );
1728 WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
1730 ip2trace (CHANN, ITRC_WRITE, ITRC_RETURN, 1, bytesSent );
1732 return bytesSent > 0 ? bytesSent : 0;
1735 /******************************************************************************/
1736 /* Function: ip2_putchar() */
1737 /* Parameters: Pointer to tty structure */
1738 /* Character to write */
1739 /* Returns: Nothing */
1744 /******************************************************************************/
1746 ip2_putchar( PTTY tty, unsigned char ch )
1748 i2ChanStrPtr pCh = tty->driver_data;
1749 unsigned long flags;
1751 // ip2trace (CHANN, ITRC_PUTC, ITRC_ENTER, 1, ch );
1753 WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
1754 pCh->Pbuf[pCh->Pbuf_stuff++] = ch;
1755 if ( pCh->Pbuf_stuff == sizeof pCh->Pbuf ) {
1756 WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
1757 ip2_flush_chars( tty );
1759 WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
1761 // ip2trace (CHANN, ITRC_PUTC, ITRC_RETURN, 1, ch );
1764 /******************************************************************************/
1765 /* Function: ip2_flush_chars() */
1766 /* Parameters: Pointer to tty structure */
1767 /* Returns: Nothing */
1771 /******************************************************************************/
1773 ip2_flush_chars( PTTY tty )
1776 i2ChanStrPtr pCh = tty->driver_data;
1777 unsigned long flags;
1779 WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
1780 if ( pCh->Pbuf_stuff ) {
1782 // ip2trace (CHANN, ITRC_PUTC, 10, 1, strip );
1785 // We may need to restart i2Output if it does not fullfill this request
1787 strip = i2Output( pCh, pCh->Pbuf, pCh->Pbuf_stuff, 0 );
1788 if ( strip != pCh->Pbuf_stuff ) {
1789 memmove( pCh->Pbuf, &pCh->Pbuf[strip], pCh->Pbuf_stuff - strip );
1791 pCh->Pbuf_stuff -= strip;
1793 WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
1796 /******************************************************************************/
1797 /* Function: ip2_write_room() */
1798 /* Parameters: Pointer to tty structure */
1799 /* Returns: Number of bytes that the driver can accept */
1803 /******************************************************************************/
1805 ip2_write_room ( PTTY tty )
1808 i2ChanStrPtr pCh = tty->driver_data;
1809 unsigned long flags;
1811 READ_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
1812 bytesFree = i2OutputFree( pCh ) - pCh->Pbuf_stuff;
1813 READ_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
1815 ip2trace (CHANN, ITRC_WRITE, 11, 1, bytesFree );
1817 return ((bytesFree > 0) ? bytesFree : 0);
1820 /******************************************************************************/
1821 /* Function: ip2_chars_in_buf() */
1822 /* Parameters: Pointer to tty structure */
1823 /* Returns: Number of bytes queued for transmission */
1828 /******************************************************************************/
1830 ip2_chars_in_buf ( PTTY tty )
1832 i2ChanStrPtr pCh = tty->driver_data;
1834 unsigned long flags;
1836 ip2trace (CHANN, ITRC_WRITE, 12, 1, pCh->Obuf_char_count + pCh->Pbuf_stuff );
1838 #ifdef IP2DEBUG_WRITE
1839 printk (KERN_DEBUG "IP2: chars in buffer = %d (%d,%d)\n",
1840 pCh->Obuf_char_count + pCh->Pbuf_stuff,
1841 pCh->Obuf_char_count, pCh->Pbuf_stuff );
1843 READ_LOCK_IRQSAVE(&pCh->Obuf_spinlock,flags);
1844 rc = pCh->Obuf_char_count;
1845 READ_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags);
1846 READ_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
1847 rc += pCh->Pbuf_stuff;
1848 READ_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
1852 /******************************************************************************/
1853 /* Function: ip2_flush_buffer() */
1854 /* Parameters: Pointer to tty structure */
1855 /* Returns: Nothing */
1860 /******************************************************************************/
1862 ip2_flush_buffer( PTTY tty )
1864 i2ChanStrPtr pCh = tty->driver_data;
1865 unsigned long flags;
1867 ip2trace (CHANN, ITRC_FLUSH, ITRC_ENTER, 0 );
1869 #ifdef IP2DEBUG_WRITE
1870 printk (KERN_DEBUG "IP2: flush buffer\n" );
1872 WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
1873 pCh->Pbuf_stuff = 0;
1874 WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
1875 i2FlushOutput( pCh );
1878 ip2trace (CHANN, ITRC_FLUSH, ITRC_RETURN, 0 );
1882 /******************************************************************************/
1883 /* Function: ip2_wait_until_sent() */
1884 /* Parameters: Pointer to tty structure */
1885 /* Timeout for wait. */
1886 /* Returns: Nothing */
1889 /* This function is used in place of the normal tty_wait_until_sent, which */
1890 /* only waits for the driver buffers to be empty (or rather, those buffers */
1891 /* reported by chars_in_buffer) which doesn't work for IP2 due to the */
1892 /* indeterminate number of bytes buffered on the board. */
1893 /******************************************************************************/
1895 ip2_wait_until_sent ( PTTY tty, int timeout )
1898 i2ChanStrPtr pCh = tty->driver_data;
1900 tty_wait_until_sent(tty, timeout );
1901 if ( (i = timeout - (jiffies -i)) > 0)
1902 i2DrainOutput( pCh, i );
1905 /******************************************************************************/
1906 /******************************************************************************/
1907 /* Device Input Section */
1908 /******************************************************************************/
1909 /******************************************************************************/
1911 /******************************************************************************/
1912 /* Function: ip2_throttle() */
1913 /* Parameters: Pointer to tty structure */
1914 /* Returns: Nothing */
1919 /******************************************************************************/
1921 ip2_throttle ( PTTY tty )
1923 i2ChanStrPtr pCh = tty->driver_data;
1925 #ifdef IP2DEBUG_READ
1926 printk (KERN_DEBUG "IP2: throttle\n" );
1929 * Signal the poll/interrupt handlers not to forward incoming data to
1930 * the line discipline. This will cause the buffers to fill up in the
1931 * library and thus cause the library routines to send the flow control
1937 /******************************************************************************/
1938 /* Function: ip2_unthrottle() */
1939 /* Parameters: Pointer to tty structure */
1940 /* Returns: Nothing */
1945 /******************************************************************************/
1947 ip2_unthrottle ( PTTY tty )
1949 i2ChanStrPtr pCh = tty->driver_data;
1950 unsigned long flags;
1952 #ifdef IP2DEBUG_READ
1953 printk (KERN_DEBUG "IP2: unthrottle\n" );
1956 /* Pass incoming data up to the line discipline again. */
1958 i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_RESUME);
1959 serviceOutgoingFifo( pCh->pMyBord );
1960 READ_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,flags)
1961 if ( pCh->Ibuf_stuff != pCh->Ibuf_strip ) {
1962 READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags)
1963 #ifdef IP2DEBUG_READ
1964 printk (KERN_DEBUG "i2Input called from unthrottle\n" );
1968 READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags)
1972 ip2_start ( PTTY tty )
1974 i2ChanStrPtr pCh = DevTable[tty->index];
1976 i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_RESUME);
1977 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_UNSUSPEND);
1978 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_RESUME);
1979 #ifdef IP2DEBUG_WRITE
1980 printk (KERN_DEBUG "IP2: start tx\n" );
1985 ip2_stop ( PTTY tty )
1987 i2ChanStrPtr pCh = DevTable[tty->index];
1989 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_SUSPEND);
1990 #ifdef IP2DEBUG_WRITE
1991 printk (KERN_DEBUG "IP2: stop tx\n" );
1995 /******************************************************************************/
1996 /* Device Ioctl Section */
1997 /******************************************************************************/
1999 static int ip2_tiocmget(struct tty_struct *tty, struct file *file)
2001 i2ChanStrPtr pCh = DevTable[tty->index];
2008 FIXME - the following code is causing a NULL pointer dereference in
2009 2.3.51 in an interrupt handler. It's suppose to prompt the board
2010 to return the DSS signal status immediately. Why doesn't it do
2011 the same thing in 2.2.14?
2014 /* This thing is still busted in the 1.2.12 driver on 2.4.x
2015 and even hoses the serial console so the oops can be trapped.
2018 #ifdef ENABLE_DSSNOW
2019 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DSS_NOW);
2021 init_waitqueue_entry(&wait, current);
2022 add_wait_queue(&pCh->dss_now_wait, &wait);
2023 set_current_state( TASK_INTERRUPTIBLE );
2025 serviceOutgoingFifo( pCh->pMyBord );
2029 set_current_state( TASK_RUNNING );
2030 remove_wait_queue(&pCh->dss_now_wait, &wait);
2032 if (signal_pending(current)) {
2036 return ((pCh->dataSetOut & I2_RTS) ? TIOCM_RTS : 0)
2037 | ((pCh->dataSetOut & I2_DTR) ? TIOCM_DTR : 0)
2038 | ((pCh->dataSetIn & I2_DCD) ? TIOCM_CAR : 0)
2039 | ((pCh->dataSetIn & I2_RI) ? TIOCM_RNG : 0)
2040 | ((pCh->dataSetIn & I2_DSR) ? TIOCM_DSR : 0)
2041 | ((pCh->dataSetIn & I2_CTS) ? TIOCM_CTS : 0);
2044 static int ip2_tiocmset(struct tty_struct *tty, struct file *file,
2045 unsigned int set, unsigned int clear)
2047 i2ChanStrPtr pCh = DevTable[tty->index];
2052 if (set & TIOCM_RTS) {
2053 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_RTSUP);
2054 pCh->dataSetOut |= I2_RTS;
2056 if (set & TIOCM_DTR) {
2057 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DTRUP);
2058 pCh->dataSetOut |= I2_DTR;
2061 if (clear & TIOCM_RTS) {
2062 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_RTSDN);
2063 pCh->dataSetOut &= ~I2_RTS;
2065 if (clear & TIOCM_DTR) {
2066 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DTRDN);
2067 pCh->dataSetOut &= ~I2_DTR;
2069 serviceOutgoingFifo( pCh->pMyBord );
2073 /******************************************************************************/
2074 /* Function: ip2_ioctl() */
2075 /* Parameters: Pointer to tty structure */
2076 /* Pointer to file structure */
2079 /* Returns: Success or failure */
2084 /******************************************************************************/
2086 ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg )
2089 i2ChanStrPtr pCh = DevTable[tty->index];
2090 struct async_icount cprev, cnow; /* kernel counter temps */
2091 struct serial_icounter_struct __user *p_cuser;
2093 unsigned long flags;
2094 void __user *argp = (void __user *)arg;
2096 if ( pCh == NULL ) {
2100 ip2trace (CHANN, ITRC_IOCTL, ITRC_ENTER, 2, cmd, arg );
2102 #ifdef IP2DEBUG_IOCTL
2103 printk(KERN_DEBUG "IP2: ioctl cmd (%x), arg (%lx)\n", cmd, arg );
2109 ip2trace (CHANN, ITRC_IOCTL, 2, 1, rc );
2111 rc = get_serial_info(pCh, argp);
2118 ip2trace (CHANN, ITRC_IOCTL, 3, 1, rc );
2120 rc = set_serial_info(pCh, argp);
2126 rc = tty_check_change(tty);
2131 //return -ENOIOCTLCMD;
2134 //return -ENOIOCTLCMD;
2137 if (STOP_CHAR(tty) != __DISABLED_CHAR) {
2138 i2QueueCommands( PTYPE_BYPASS, pCh, 100, 1,
2139 CMD_XMIT_NOW(STOP_CHAR(tty)));
2143 if (START_CHAR(tty) != __DISABLED_CHAR) {
2144 i2QueueCommands( PTYPE_BYPASS, pCh, 100, 1,
2145 CMD_XMIT_NOW(START_CHAR(tty)));
2153 case TCSBRK: /* SVID version: non-zero arg --> no break */
2154 rc = tty_check_change(tty);
2156 ip2trace (CHANN, ITRC_IOCTL, 4, 1, rc );
2159 ip2_wait_until_sent(tty,0);
2161 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_SEND_BRK(250));
2162 serviceOutgoingFifo( pCh->pMyBord );
2167 case TCSBRKP: /* support for POSIX tcsendbreak() */
2168 rc = tty_check_change(tty);
2170 ip2trace (CHANN, ITRC_IOCTL, 5, 1, rc );
2173 ip2_wait_until_sent(tty,0);
2174 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1,
2175 CMD_SEND_BRK(arg ? arg*100 : 250));
2176 serviceOutgoingFifo ( pCh->pMyBord );
2182 ip2trace (CHANN, ITRC_IOCTL, 6, 1, rc );
2184 rc = put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *)argp);
2191 ip2trace (CHANN, ITRC_IOCTL, 7, 1, rc );
2193 rc = get_user(arg,(unsigned long __user *) argp);
2196 tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL)
2197 | (arg ? CLOCAL : 0));
2202 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change - mask
2203 * passed in arg for lines of interest (use |'ed TIOCM_RNG/DSR/CD/CTS
2204 * for masking). Caller should use TIOCGICOUNT to see which one it was
2207 save_flags(flags);cli();
2208 cprev = pCh->icount; /* note the counters on entry */
2209 restore_flags(flags);
2210 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 4,
2211 CMD_DCD_REP, CMD_CTS_REP, CMD_DSR_REP, CMD_RI_REP);
2212 init_waitqueue_entry(&wait, current);
2213 add_wait_queue(&pCh->delta_msr_wait, &wait);
2214 set_current_state( TASK_INTERRUPTIBLE );
2216 serviceOutgoingFifo( pCh->pMyBord );
2218 ip2trace (CHANN, ITRC_IOCTL, 10, 0 );
2222 ip2trace (CHANN, ITRC_IOCTL, 11, 0 );
2224 /* see if a signal did it */
2225 if (signal_pending(current)) {
2229 save_flags(flags);cli();
2230 cnow = pCh->icount; /* atomic copy */
2231 restore_flags(flags);
2232 if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
2233 cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) {
2234 rc = -EIO; /* no change => rc */
2237 if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
2238 ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
2239 ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
2240 ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
2246 set_current_state( TASK_RUNNING );
2247 remove_wait_queue(&pCh->delta_msr_wait, &wait);
2249 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 3,
2250 CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);
2251 if ( ! (pCh->flags & ASYNC_CHECK_CD)) {
2252 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DCD_NREP);
2254 serviceOutgoingFifo( pCh->pMyBord );
2259 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
2260 * Return: write counters to the user passed counter struct
2261 * NB: both 1->0 and 0->1 transitions are counted except for RI where
2262 * only 0->1 is counted. The controller is quite capable of counting
2263 * both, but this done to preserve compatibility with the standard
2267 ip2trace (CHANN, ITRC_IOCTL, 11, 1, rc );
2269 save_flags(flags);cli();
2271 restore_flags(flags);
2273 rc = put_user(cnow.cts, &p_cuser->cts);
2274 rc = put_user(cnow.dsr, &p_cuser->dsr);
2275 rc = put_user(cnow.rng, &p_cuser->rng);
2276 rc = put_user(cnow.dcd, &p_cuser->dcd);
2277 rc = put_user(cnow.rx, &p_cuser->rx);
2278 rc = put_user(cnow.tx, &p_cuser->tx);
2279 rc = put_user(cnow.frame, &p_cuser->frame);
2280 rc = put_user(cnow.overrun, &p_cuser->overrun);
2281 rc = put_user(cnow.parity, &p_cuser->parity);
2282 rc = put_user(cnow.brk, &p_cuser->brk);
2283 rc = put_user(cnow.buf_overrun, &p_cuser->buf_overrun);
2287 * The rest are not supported by this driver. By returning -ENOIOCTLCMD they
2288 * will be passed to the line discipline for it to handle.
2294 case TIOCSERGSTRUCT:
2295 case TIOCSERGETMULTI:
2296 case TIOCSERSETMULTI:
2299 ip2trace (CHANN, ITRC_IOCTL, 12, 0 );
2305 ip2trace (CHANN, ITRC_IOCTL, ITRC_RETURN, 0 );
2310 /******************************************************************************/
2311 /* Function: GetSerialInfo() */
2312 /* Parameters: Pointer to channel structure */
2313 /* Pointer to old termios structure */
2314 /* Returns: Nothing */
2317 /* This is to support the setserial command, and requires processing of the */
2318 /* standard Linux serial structure. */
2319 /******************************************************************************/
2321 get_serial_info ( i2ChanStrPtr pCh, struct serial_struct __user *retinfo )
2323 struct serial_struct tmp;
2325 memset ( &tmp, 0, sizeof(tmp) );
2326 tmp.type = pCh->pMyBord->channelBtypes.bid_value[(pCh->port_index & (IP2_PORTS_PER_BOARD-1))/16];
2327 if (BID_HAS_654(tmp.type)) {
2328 tmp.type = PORT_16650;
2330 tmp.type = PORT_CIRRUS;
2332 tmp.line = pCh->port_index;
2333 tmp.port = pCh->pMyBord->i2eBase;
2334 tmp.irq = ip2config.irq[pCh->port_index/64];
2335 tmp.flags = pCh->flags;
2336 tmp.baud_base = pCh->BaudBase;
2337 tmp.close_delay = pCh->ClosingDelay;
2338 tmp.closing_wait = pCh->ClosingWaitTime;
2339 tmp.custom_divisor = pCh->BaudDivisor;
2340 return copy_to_user(retinfo,&tmp,sizeof(*retinfo));
2343 /******************************************************************************/
2344 /* Function: SetSerialInfo() */
2345 /* Parameters: Pointer to channel structure */
2346 /* Pointer to old termios structure */
2347 /* Returns: Nothing */
2350 /* This function provides support for setserial, which uses the TIOCSSERIAL */
2351 /* ioctl. Not all setserial parameters are relevant. If the user attempts to */
2352 /* change the IRQ, address or type of the port the ioctl fails. */
2353 /******************************************************************************/
2355 set_serial_info( i2ChanStrPtr pCh, struct serial_struct __user *new_info )
2357 struct serial_struct ns;
2358 int old_flags, old_baud_divisor;
2360 if (copy_from_user(&ns, new_info, sizeof (ns)))
2364 * We don't allow setserial to change IRQ, board address, type or baud
2365 * base. Also line nunber as such is meaningless but we use it for our
2366 * array index so it is fixed also.
2368 if ( (ns.irq != ip2config.irq[pCh->port_index])
2369 || ((int) ns.port != ((int) (pCh->pMyBord->i2eBase)))
2370 || (ns.baud_base != pCh->BaudBase)
2371 || (ns.line != pCh->port_index) ) {
2375 old_flags = pCh->flags;
2376 old_baud_divisor = pCh->BaudDivisor;
2378 if ( !capable(CAP_SYS_ADMIN) ) {
2379 if ( ( ns.close_delay != pCh->ClosingDelay ) ||
2380 ( (ns.flags & ~ASYNC_USR_MASK) !=
2381 (pCh->flags & ~ASYNC_USR_MASK) ) ) {
2385 pCh->flags = (pCh->flags & ~ASYNC_USR_MASK) |
2386 (ns.flags & ASYNC_USR_MASK);
2387 pCh->BaudDivisor = ns.custom_divisor;
2389 pCh->flags = (pCh->flags & ~ASYNC_FLAGS) |
2390 (ns.flags & ASYNC_FLAGS);
2391 pCh->BaudDivisor = ns.custom_divisor;
2392 pCh->ClosingDelay = ns.close_delay * HZ/100;
2393 pCh->ClosingWaitTime = ns.closing_wait * HZ/100;
2396 if ( ( (old_flags & ASYNC_SPD_MASK) != (pCh->flags & ASYNC_SPD_MASK) )
2397 || (old_baud_divisor != pCh->BaudDivisor) ) {
2398 // Invalidate speed and reset parameters
2399 set_params( pCh, NULL );
2405 /******************************************************************************/
2406 /* Function: ip2_set_termios() */
2407 /* Parameters: Pointer to tty structure */
2408 /* Pointer to old termios structure */
2409 /* Returns: Nothing */
2414 /******************************************************************************/
2416 ip2_set_termios( PTTY tty, struct termios *old_termios )
2418 i2ChanStrPtr pCh = (i2ChanStrPtr)tty->driver_data;
2420 #ifdef IP2DEBUG_IOCTL
2421 printk (KERN_DEBUG "IP2: set termios %p\n", old_termios );
2424 set_params( pCh, old_termios );
2427 /******************************************************************************/
2428 /* Function: ip2_set_line_discipline() */
2429 /* Parameters: Pointer to tty structure */
2430 /* Returns: Nothing */
2432 /* Description: Does nothing */
2435 /******************************************************************************/
2437 ip2_set_line_discipline ( PTTY tty )
2439 #ifdef IP2DEBUG_IOCTL
2440 printk (KERN_DEBUG "IP2: set line discipline\n" );
2443 ip2trace (((i2ChanStrPtr)tty->driver_data)->port_index, ITRC_IOCTL, 16, 0 );
2447 /******************************************************************************/
2448 /* Function: SetLine Characteristics() */
2449 /* Parameters: Pointer to channel structure */
2450 /* Returns: Nothing */
2453 /* This routine is called to update the channel structure with the new line */
2454 /* characteristics, and send the appropriate commands to the board when they */
2456 /******************************************************************************/
2458 set_params( i2ChanStrPtr pCh, struct termios *o_tios )
2460 tcflag_t cflag, iflag, lflag;
2461 char stop_char, start_char;
2462 struct termios dummy;
2464 lflag = pCh->pTTY->termios->c_lflag;
2465 cflag = pCh->pTTY->termios->c_cflag;
2466 iflag = pCh->pTTY->termios->c_iflag;
2468 if (o_tios == NULL) {
2469 dummy.c_lflag = ~lflag;
2470 dummy.c_cflag = ~cflag;
2471 dummy.c_iflag = ~iflag;
2476 switch ( cflag & CBAUD ) {
2478 i2QueueCommands( PTYPE_BYPASS, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN);
2479 pCh->dataSetOut &= ~(I2_DTR | I2_RTS);
2480 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25));
2481 pCh->pTTY->termios->c_cflag |= (CBAUD & o_tios->c_cflag);
2486 * This is the speed that is overloaded with all the other high
2487 * speeds, depending upon the flag settings.
2489 if ( ( pCh->flags & ASYNC_SPD_MASK ) == ASYNC_SPD_HI ) {
2490 pCh->speed = CBR_57600;
2491 } else if ( (pCh->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI ) {
2492 pCh->speed = CBR_115200;
2493 } else if ( (pCh->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST ) {
2494 pCh->speed = CBR_C1;
2496 pCh->speed = CBR_38400;
2499 case B50: pCh->speed = CBR_50; break;
2500 case B75: pCh->speed = CBR_75; break;
2501 case B110: pCh->speed = CBR_110; break;
2502 case B134: pCh->speed = CBR_134; break;
2503 case B150: pCh->speed = CBR_150; break;
2504 case B200: pCh->speed = CBR_200; break;
2505 case B300: pCh->speed = CBR_300; break;
2506 case B600: pCh->speed = CBR_600; break;
2507 case B1200: pCh->speed = CBR_1200; break;
2508 case B1800: pCh->speed = CBR_1800; break;
2509 case B2400: pCh->speed = CBR_2400; break;
2510 case B4800: pCh->speed = CBR_4800; break;
2511 case B9600: pCh->speed = CBR_9600; break;
2512 case B19200: pCh->speed = CBR_19200; break;
2513 case B57600: pCh->speed = CBR_57600; break;
2514 case B115200: pCh->speed = CBR_115200; break;
2515 case B153600: pCh->speed = CBR_153600; break;
2516 case B230400: pCh->speed = CBR_230400; break;
2517 case B307200: pCh->speed = CBR_307200; break;
2518 case B460800: pCh->speed = CBR_460800; break;
2519 case B921600: pCh->speed = CBR_921600; break;
2520 default: pCh->speed = CBR_9600; break;
2522 if ( pCh->speed == CBR_C1 ) {
2523 // Process the custom speed parameters.
2524 int bps = pCh->BaudBase / pCh->BaudDivisor;
2525 if ( bps == 921600 ) {
2526 pCh->speed = CBR_921600;
2529 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_BAUD_DEF1(bps) );
2532 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_SETBAUD(pCh->speed));
2534 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 2, CMD_DTRUP, CMD_RTSUP);
2535 pCh->dataSetOut |= (I2_DTR | I2_RTS);
2537 if ( (CSTOPB & cflag) ^ (CSTOPB & o_tios->c_cflag))
2539 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1,
2540 CMD_SETSTOP( ( cflag & CSTOPB ) ? CST_2 : CST_1));
2542 if (((PARENB|PARODD) & cflag) ^ ((PARENB|PARODD) & o_tios->c_cflag))
2544 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1,
2546 (cflag & PARENB ? (cflag & PARODD ? CSP_OD : CSP_EV) : CSP_NP)
2550 /* byte size and parity */
2551 if ( (CSIZE & cflag)^(CSIZE & o_tios->c_cflag))
2554 switch ( cflag & CSIZE ) {
2555 case CS5: datasize = CSZ_5; break;
2556 case CS6: datasize = CSZ_6; break;
2557 case CS7: datasize = CSZ_7; break;
2558 case CS8: datasize = CSZ_8; break;
2559 default: datasize = CSZ_5; break; /* as per serial.c */
2561 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1, CMD_SETBITS(datasize) );
2563 /* Process CTS flow control flag setting */
2564 if ( (cflag & CRTSCTS) ) {
2565 i2QueueCommands(PTYPE_INLINE, pCh, 100,
2566 2, CMD_CTSFL_ENAB, CMD_RTSFL_ENAB);
2568 i2QueueCommands(PTYPE_INLINE, pCh, 100,
2569 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB);
2572 // Process XON/XOFF flow control flags settings
2574 stop_char = STOP_CHAR(pCh->pTTY);
2575 start_char = START_CHAR(pCh->pTTY);
2577 //////////// can't be \000
2578 if (stop_char == __DISABLED_CHAR )
2580 stop_char = ~__DISABLED_CHAR;
2582 if (start_char == __DISABLED_CHAR )
2584 start_char = ~__DISABLED_CHAR;
2586 /////////////////////////////////
2588 if ( o_tios->c_cc[VSTART] != start_char )
2590 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DEF_IXON(start_char));
2591 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DEF_OXON(start_char));
2593 if ( o_tios->c_cc[VSTOP] != stop_char )
2595 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DEF_IXOFF(stop_char));
2596 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DEF_OXOFF(stop_char));
2598 if (stop_char == __DISABLED_CHAR )
2600 stop_char = ~__DISABLED_CHAR; //TEST123
2603 if ((iflag & (IXOFF))^(o_tios->c_iflag & (IXOFF)))
2605 if ( iflag & IXOFF ) { // Enable XOFF output flow control
2606 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_OXON_OPT(COX_XON));
2607 } else { // Disable XOFF output flow control
2609 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_OXON_OPT(COX_NONE));
2612 if (start_char == __DISABLED_CHAR )
2616 if ((iflag & (IXON|IXANY)) ^ (o_tios->c_iflag & (IXON|IXANY)))
2618 if ( iflag & IXON ) {
2619 if ( iflag & IXANY ) { // Enable XON/XANY output flow control
2620 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_XANY));
2621 } else { // Enable XON output flow control
2622 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_XON));
2624 } else { // Disable XON output flow control
2626 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_NONE));
2629 if ( (iflag & ISTRIP) ^ ( o_tios->c_iflag & (ISTRIP)) )
2631 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1,
2632 CMD_ISTRIP_OPT((iflag & ISTRIP ? 1 : 0)));
2634 if ( (iflag & INPCK) ^ ( o_tios->c_iflag & (INPCK)) )
2636 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1,
2637 CMD_PARCHK((iflag & INPCK) ? CPK_ENAB : CPK_DSAB));
2640 if ( (iflag & (IGNBRK|PARMRK|BRKINT|IGNPAR))
2641 ^ ( o_tios->c_iflag & (IGNBRK|PARMRK|BRKINT|IGNPAR)) )
2646 if ( iflag & IGNBRK ) { /* Ignore breaks altogether */
2647 /* Ignore breaks altogether */
2648 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_BRK_NREP);
2650 if ( iflag & BRKINT ) {
2651 if ( iflag & PARMRK ) {
2652 brkrpt = 0x0a; // exception an inline triple
2654 brkrpt = 0x1a; // exception and NULL
2656 brkrpt |= 0x04; // flush input
2658 if ( iflag & PARMRK ) {
2659 brkrpt = 0x0b; //POSIX triple \0377 \0 \0
2661 brkrpt = 0x01; // Null only
2664 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_BRK_REP(brkrpt));
2667 if (iflag & IGNPAR) {
2669 /* would be 2 for not cirrus bug */
2670 /* would be 0x20 cept for cirrus bug */
2672 if ( iflag & PARMRK ) {
2674 * Replace error characters with 3-byte sequence (\0377,\0,char)
2677 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_ISTRIP_OPT((char)0));
2682 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_SET_ERROR(parrpt));
2684 if (cflag & CLOCAL) {
2685 // Status reporting fails for DCD if this is off
2686 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DCD_NREP);
2687 pCh->flags &= ~ASYNC_CHECK_CD;
2689 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DCD_REP);
2690 pCh->flags |= ASYNC_CHECK_CD;
2694 i2DrainOutput( pCh, 100 );
2697 /******************************************************************************/
2698 /* IPL Device Section */
2699 /******************************************************************************/
2701 /******************************************************************************/
2702 /* Function: ip2_ipl_read() */
2703 /* Parameters: Pointer to device inode */
2704 /* Pointer to file structure */
2705 /* Pointer to data */
2706 /* Number of bytes to read */
2707 /* Returns: Success or failure */
2709 /* Description: Ugly */
2712 /******************************************************************************/
2716 ip2_ipl_read(struct file *pFile, char __user *pData, size_t count, loff_t *off )
2718 unsigned int minor = iminor(pFile->f_dentry->d_inode);
2722 printk (KERN_DEBUG "IP2IPL: read %p, %d bytes\n", pData, count );
2726 case 0: // IPL device
2729 case 1: // Status dump
2732 case 2: // Ping device
2735 case 3: // Trace device
2736 rc = DumpTraceBuffer ( pData, count );
2738 case 4: // Trace device
2739 rc = DumpFifoBuffer ( pData, count );
2749 DumpFifoBuffer ( char __user *pData, int count )
2753 rc = copy_to_user(pData, DBGBuf, count);
2755 printk(KERN_DEBUG "Last index %d\n", I );
2758 #endif /* DEBUG_FIFO */
2763 DumpTraceBuffer ( char __user *pData, int count )
2765 #ifdef IP2DEBUG_TRACE
2769 int *pIndex = (int __user *)pData;
2771 if ( count < (sizeof(int) * 6) ) {
2774 rc = put_user(tracewrap, pIndex );
2775 rc = put_user(TRACEMAX, ++pIndex );
2776 rc = put_user(tracestrip, ++pIndex );
2777 rc = put_user(tracestuff, ++pIndex );
2778 pData += sizeof(int) * 6;
2779 count -= sizeof(int) * 6;
2781 dumpcount = tracestuff - tracestrip;
2782 if ( dumpcount < 0 ) {
2783 dumpcount += TRACEMAX;
2785 if ( dumpcount > count ) {
2788 chunk = TRACEMAX - tracestrip;
2789 if ( dumpcount > chunk ) {
2790 rc = copy_to_user(pData, &tracebuf[tracestrip],
2791 chunk * sizeof(tracebuf[0]) );
2792 pData += chunk * sizeof(tracebuf[0]);
2794 chunk = dumpcount - chunk;
2798 rc = copy_to_user(pData, &tracebuf[tracestrip],
2799 chunk * sizeof(tracebuf[0]) );
2800 tracestrip += chunk;
2803 rc = put_user(tracestrip, ++pIndex );
2804 rc = put_user(tracestuff, ++pIndex );
2812 /******************************************************************************/
2813 /* Function: ip2_ipl_write() */
2815 /* Pointer to file structure */
2816 /* Pointer to data */
2817 /* Number of bytes to write */
2818 /* Returns: Success or failure */
2823 /******************************************************************************/
2825 ip2_ipl_write(struct file *pFile, const char __user *pData, size_t count, loff_t *off)
2828 printk (KERN_DEBUG "IP2IPL: write %p, %d bytes\n", pData, count );
2833 /******************************************************************************/
2834 /* Function: ip2_ipl_ioctl() */
2835 /* Parameters: Pointer to device inode */
2836 /* Pointer to file structure */
2839 /* Returns: Success or failure */
2844 /******************************************************************************/
2846 ip2_ipl_ioctl ( struct inode *pInode, struct file *pFile, UINT cmd, ULONG arg )
2848 unsigned int iplminor = iminor(pInode);
2850 void __user *argp = (void __user *)arg;
2851 ULONG __user *pIndex = argp;
2852 i2eBordStrPtr pB = i2BoardPtrTable[iplminor / 4];
2856 printk (KERN_DEBUG "IP2IPL: ioctl cmd %d, arg %ld\n", cmd, arg );
2859 switch ( iplminor ) {
2860 case 0: // IPL device
2863 case 1: // Status dump
2868 case 64: /* Driver - ip2stat */
2869 rc = put_user(ip2_tty_driver->refcount, pIndex++ );
2870 rc = put_user(irq_counter, pIndex++ );
2871 rc = put_user(bh_counter, pIndex++ );
2874 case 65: /* Board - ip2stat */
2876 rc = copy_to_user(argp, pB, sizeof(i2eBordStr));
2877 rc = put_user(INB(pB->i2eStatus),
2878 (ULONG __user *)(arg + (ULONG)(&pB->i2eStatus) - (ULONG)pB ) );
2885 if (cmd < IP2_MAX_PORTS) {
2886 pCh = DevTable[cmd];
2889 rc = copy_to_user(argp, pCh, sizeof(i2ChanStr));
2899 case 2: // Ping device
2902 case 3: // Trace device
2904 rc = put_user(iiSendPendingMail, pIndex++ );
2905 rc = put_user(i2InitChannels, pIndex++ );
2906 rc = put_user(i2QueueNeeds, pIndex++ );
2907 rc = put_user(i2QueueCommands, pIndex++ );
2908 rc = put_user(i2GetStatus, pIndex++ );
2909 rc = put_user(i2Input, pIndex++ );
2910 rc = put_user(i2InputFlush, pIndex++ );
2911 rc = put_user(i2Output, pIndex++ );
2912 rc = put_user(i2FlushOutput, pIndex++ );
2913 rc = put_user(i2DrainWakeup, pIndex++ );
2914 rc = put_user(i2DrainOutput, pIndex++ );
2915 rc = put_user(i2OutputFree, pIndex++ );
2916 rc = put_user(i2StripFifo, pIndex++ );
2917 rc = put_user(i2StuffFifoBypass, pIndex++ );
2918 rc = put_user(i2StuffFifoFlow, pIndex++ );
2919 rc = put_user(i2StuffFifoInline, pIndex++ );
2920 rc = put_user(i2ServiceBoard, pIndex++ );
2921 rc = put_user(serviceOutgoingFifo, pIndex++ );
2922 // rc = put_user(ip2_init, pIndex++ );
2923 rc = put_user(ip2_init_board, pIndex++ );
2924 rc = put_user(find_eisa_board, pIndex++ );
2925 rc = put_user(set_irq, pIndex++ );
2926 rc = put_user(ip2_interrupt, pIndex++ );
2927 rc = put_user(ip2_poll, pIndex++ );
2928 rc = put_user(service_all_boards, pIndex++ );
2929 rc = put_user(do_input, pIndex++ );
2930 rc = put_user(do_status, pIndex++ );
2931 #ifndef IP2DEBUG_OPEN
2932 rc = put_user(0, pIndex++ );
2934 rc = put_user(open_sanity_check, pIndex++ );
2936 rc = put_user(ip2_open, pIndex++ );
2937 rc = put_user(ip2_close, pIndex++ );
2938 rc = put_user(ip2_hangup, pIndex++ );
2939 rc = put_user(ip2_write, pIndex++ );
2940 rc = put_user(ip2_putchar, pIndex++ );
2941 rc = put_user(ip2_flush_chars, pIndex++ );
2942 rc = put_user(ip2_write_room, pIndex++ );
2943 rc = put_user(ip2_chars_in_buf, pIndex++ );
2944 rc = put_user(ip2_flush_buffer, pIndex++ );
2946 //rc = put_user(ip2_wait_until_sent, pIndex++ );
2947 rc = put_user(0, pIndex++ );
2949 rc = put_user(ip2_throttle, pIndex++ );
2950 rc = put_user(ip2_unthrottle, pIndex++ );
2951 rc = put_user(ip2_ioctl, pIndex++ );
2952 rc = put_user(0, pIndex++ );
2953 rc = put_user(get_serial_info, pIndex++ );
2954 rc = put_user(set_serial_info, pIndex++ );
2955 rc = put_user(ip2_set_termios, pIndex++ );
2956 rc = put_user(ip2_set_line_discipline, pIndex++ );
2957 rc = put_user(set_params, pIndex++ );
2971 /******************************************************************************/
2972 /* Function: ip2_ipl_open() */
2973 /* Parameters: Pointer to device inode */
2974 /* Pointer to file structure */
2975 /* Returns: Success or failure */
2980 /******************************************************************************/
2982 ip2_ipl_open( struct inode *pInode, struct file *pFile )
2984 unsigned int iplminor = iminor(pInode);
2989 printk (KERN_DEBUG "IP2IPL: open\n" );
2993 // These are the IPL devices
3000 // These are the status devices
3007 // These are the debug devices
3012 pB = i2BoardPtrTable[iplminor / 4];
3013 pCh = (i2ChanStrPtr) pB->i2eChannelPtr;
3016 // This is the trace device
3022 /******************************************************************************/
3023 /* Function: ip2_read_procmem */
3026 /* Returns: Length of output */
3029 /* Supplies some driver operating parameters */
3030 /* Not real useful unless your debugging the fifo */
3032 /******************************************************************************/
3034 #define LIMIT (PAGE_SIZE - 120)
3037 ip2_read_procmem(char *buf, char **start, off_t offset, int len)
3046 #define FMTLINE "%3d: 0x%08x 0x%08x 0%011o 0%011o\n"
3047 #define FMTLIN2 " 0x%04x 0x%04x tx flow 0x%x\n"
3048 #define FMTLIN3 " 0x%04x 0x%04x rc flow\n"
3050 len += sprintf(buf+len,"\n");
3052 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
3053 pB = i2BoardPtrTable[i];
3055 len += sprintf(buf+len,"board %d:\n",i);
3056 len += sprintf(buf+len,"\tFifo rem: %d mty: %x outM %x\n",
3057 pB->i2eFifoRemains,pB->i2eWaitingForEmptyFifo,pB->i2eOutMailWaiting);
3061 len += sprintf(buf+len,"#: tty flags, port flags, cflags, iflags\n");
3062 for (i=0; i < IP2_MAX_PORTS; i++) {
3068 if (tty && tty->count) {
3069 len += sprintf(buf+len,FMTLINE,i,(int)tty->flags,pCh->flags,
3070 tty->termios->c_cflag,tty->termios->c_iflag);
3072 len += sprintf(buf+len,FMTLIN2,
3073 pCh->outfl.asof,pCh->outfl.room,pCh->channelNeeds);
3074 len += sprintf(buf+len,FMTLIN3,pCh->infl.asof,pCh->infl.room);
3082 * This is the handler for /proc/tty/driver/ip2
3084 * This stretch of code has been largely plagerized from at least three
3085 * different sources including ip2mkdev.c and a couple of other drivers.
3086 * The bugs are all mine. :-) =mhw=
3088 static int ip2_read_proc(char *page, char **start, off_t off,
3089 int count, int *eof, void *data)
3099 len += sprintf(page, "ip2info: 1.0 driver: %s\n", pcVersion );
3100 len += sprintf(page+len, "Driver: SMajor=%d CMajor=%d IMajor=%d MaxBoards=%d MaxBoxes=%d MaxPorts=%d\n",
3101 IP2_TTY_MAJOR, IP2_CALLOUT_MAJOR, IP2_IPL_MAJOR,
3102 IP2_MAX_BOARDS, ABS_MAX_BOXES, ABS_BIGGEST_BOX);
3104 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
3105 /* This need to be reset for a board by board count... */
3107 pB = i2BoardPtrTable[i];
3109 switch( pB->i2ePom.e.porID & ~POR_ID_RESERVED )
3112 len += sprintf( page+len, "Board %d: EX ports=", i );
3113 for( box = 0; box < ABS_MAX_BOXES; ++box )
3117 if( pB->i2eChannelMap[box] != 0 ) ++boxes;
3118 for( j = 0; j < ABS_BIGGEST_BOX; ++j )
3120 if( pB->i2eChannelMap[box] & 1<< j ) {
3124 len += sprintf( page+len, "%d,", ports );
3128 --len; /* Backup over that last comma */
3130 len += sprintf( page+len, " boxes=%d width=%d", boxes, pB->i2eDataWidth16 ? 16 : 8 );
3134 len += sprintf(page+len, "Board %d: ISA-4 ports=4 boxes=1", i );
3139 len += sprintf(page+len, "Board %d: ISA-8-std ports=8 boxes=1", i );
3144 len += sprintf(page+len, "Board %d: ISA-8-RJ11 ports=8 boxes=1", i );
3149 len += sprintf(page+len, "Board %d: unknown", i );
3150 /* Don't try and probe for minor numbers */
3155 /* Don't try and probe for minor numbers */
3156 len += sprintf(page+len, "Board %d: vacant", i );
3161 len += sprintf(page+len, " minors=" );
3163 for ( box = 0; box < ABS_MAX_BOXES; ++box )
3165 for ( j = 0; j < ABS_BIGGEST_BOX; ++j )
3167 if ( pB->i2eChannelMap[box] & (1 << j) )
3169 len += sprintf (page+len,"%d,",
3170 j + ABS_BIGGEST_BOX *
3171 (box+i*ABS_MAX_BOXES));
3176 page[ len - 1 ] = '\n'; /* Overwrite that last comma */
3178 len += sprintf (page+len,"\n" );
3181 if (len+begin > off+count)
3183 if (len+begin < off) {
3189 if (i >= IP2_MAX_BOARDS)
3191 if (off >= len+begin)
3194 *start = page + (off-begin);
3195 return ((count < begin+len-off) ? count : begin+len-off);
3198 /******************************************************************************/
3199 /* Function: ip2trace() */
3200 /* Parameters: Value to add to trace buffer */
3201 /* Returns: Nothing */
3206 /******************************************************************************/
3207 #ifdef IP2DEBUG_TRACE
3209 ip2trace (unsigned short pn, unsigned char cat, unsigned char label, unsigned long codes, ...)
3212 unsigned long *pCode = &codes;
3213 union ip2breadcrumb bc;
3217 tracebuf[tracestuff++] = jiffies;
3218 if ( tracestuff == TRACEMAX ) {
3221 if ( tracestuff == tracestrip ) {
3222 if ( ++tracestrip == TRACEMAX ) {
3228 bc.hdr.port = 0xff & pn;
3230 bc.hdr.codes = (unsigned char)( codes & 0xff );
3231 bc.hdr.label = label;
3232 tracebuf[tracestuff++] = bc.value;
3235 if ( tracestuff == TRACEMAX ) {
3238 if ( tracestuff == tracestrip ) {
3239 if ( ++tracestrip == TRACEMAX ) {
3248 tracebuf[tracestuff++] = *++pCode;
3254 MODULE_LICENSE("GPL");