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.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
86 #include <linux/ctype.h>
87 #include <linux/string.h>
88 #include <linux/fcntl.h>
89 #include <linux/errno.h>
90 #include <linux/module.h>
91 #include <linux/signal.h>
92 #include <linux/sched.h>
93 #include <linux/timer.h>
94 #include <linux/interrupt.h>
95 #include <linux/pci.h>
97 #include <linux/slab.h>
98 #include <linux/major.h>
99 #include <linux/wait.h>
100 #include <linux/device.h>
102 #include <linux/tty.h>
103 #include <linux/tty_flip.h>
104 #include <linux/termios.h>
105 #include <linux/tty_driver.h>
106 #include <linux/serial.h>
107 #include <linux/ptrace.h>
108 #include <linux/ioport.h>
110 #include <linux/cdk.h>
111 #include <linux/comstats.h>
112 #include <linux/delay.h>
113 #include <linux/bitops.h>
115 #include <asm/system.h>
119 #include <linux/vmalloc.h>
120 #include <linux/init.h>
122 #include <asm/uaccess.h>
124 #include "ip2types.h"
125 #include "ip2trace.h"
126 #include "ip2ioctl.h"
135 #include <linux/proc_fs.h>
136 #include <linux/seq_file.h>
138 static const struct file_operations ip2mem_proc_fops;
139 static int ip2_read_proc(char *, char **, off_t, int, int *, void * );
141 /********************/
142 /* Type Definitions */
143 /********************/
149 /* String constants to identify ourselves */
150 static char *pcName = "Computone IntelliPort Plus multiport driver";
151 static char *pcVersion = "1.2.14";
153 /* String constants for port names */
154 static char *pcDriver_name = "ip2";
155 static char *pcIpl = "ip2ipl";
157 // cheezy kludge or genius - you decide?
158 int ip2_loadmain(int *, int *, unsigned char *, int);
159 static unsigned char *Fip_firmware;
160 static int Fip_firmware_size;
162 /***********************/
163 /* Function Prototypes */
164 /***********************/
166 /* Global module entry functions */
168 /* Private (static) functions */
169 static int ip2_open(PTTY, struct file *);
170 static void ip2_close(PTTY, struct file *);
171 static int ip2_write(PTTY, const unsigned char *, int);
172 static int ip2_putchar(PTTY, unsigned char);
173 static void ip2_flush_chars(PTTY);
174 static int ip2_write_room(PTTY);
175 static int ip2_chars_in_buf(PTTY);
176 static void ip2_flush_buffer(PTTY);
177 static int ip2_ioctl(PTTY, struct file *, UINT, ULONG);
178 static void ip2_set_termios(PTTY, struct ktermios *);
179 static void ip2_set_line_discipline(PTTY);
180 static void ip2_throttle(PTTY);
181 static void ip2_unthrottle(PTTY);
182 static void ip2_stop(PTTY);
183 static void ip2_start(PTTY);
184 static void ip2_hangup(PTTY);
185 static int ip2_tiocmget(struct tty_struct *tty, struct file *file);
186 static int ip2_tiocmset(struct tty_struct *tty, struct file *file,
187 unsigned int set, unsigned int clear);
189 static void set_irq(int, int);
190 static void ip2_interrupt_bh(struct work_struct *work);
191 static irqreturn_t ip2_interrupt(int irq, void *dev_id);
192 static void ip2_poll(unsigned long arg);
193 static inline void service_all_boards(void);
194 static void do_input(struct work_struct *);
195 static void do_status(struct work_struct *);
197 static void ip2_wait_until_sent(PTTY,int);
199 static void set_params (i2ChanStrPtr, struct ktermios *);
200 static int get_serial_info(i2ChanStrPtr, struct serial_struct __user *);
201 static int set_serial_info(i2ChanStrPtr, struct serial_struct __user *);
203 static ssize_t ip2_ipl_read(struct file *, char __user *, size_t, loff_t *);
204 static ssize_t ip2_ipl_write(struct file *, const char __user *, size_t, loff_t *);
205 static int ip2_ipl_ioctl(struct inode *, struct file *, UINT, ULONG);
206 static int ip2_ipl_open(struct inode *, struct file *);
208 static int DumpTraceBuffer(char __user *, int);
209 static int DumpFifoBuffer( char __user *, int);
211 static void ip2_init_board(int);
212 static unsigned short find_eisa_board(int);
218 static struct tty_driver *ip2_tty_driver;
220 /* Here, then is a table of board pointers which the interrupt routine should
221 * scan through to determine who it must service.
223 static unsigned short i2nBoards; // Number of boards here
225 static i2eBordStrPtr i2BoardPtrTable[IP2_MAX_BOARDS];
227 static i2ChanStrPtr DevTable[IP2_MAX_PORTS];
228 //DevTableMem just used to save addresses for kfree
229 static void *DevTableMem[IP2_MAX_BOARDS];
231 /* This is the driver descriptor for the ip2ipl device, which is used to
232 * download the loadware to the boards.
234 static const struct file_operations ip2_ipl = {
235 .owner = THIS_MODULE,
236 .read = ip2_ipl_read,
237 .write = ip2_ipl_write,
238 .ioctl = ip2_ipl_ioctl,
239 .open = ip2_ipl_open,
242 static unsigned long irq_counter = 0;
243 static unsigned long bh_counter = 0;
245 // Use immediate queue to service interrupts
247 //#define USE_IQ // PCI&2.2 needs work
249 /* The timer_list entry for our poll routine. If interrupt operation is not
250 * selected, the board is serviced periodically to see if anything needs doing.
252 #define POLL_TIMEOUT (jiffies + 1)
253 static DEFINE_TIMER(PollTimer, ip2_poll, 0, 0);
256 #ifdef IP2DEBUG_TRACE
257 /* Trace (debug) buffer data */
258 #define TRACEMAX 1000
259 static unsigned long tracebuf[TRACEMAX];
260 static int tracestuff;
261 static int tracestrip;
262 static int tracewrap;
269 #if defined(MODULE) && defined(IP2DEBUG_OPEN)
270 #define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] refc=%d, ttyc=%d, modc=%x -> %s\n", \
271 tty->name,(pCh->flags),ip2_tty_driver->refcount, \
272 tty->count,/*GET_USE_COUNT(module)*/0,s)
281 #include "i2ellis.c" /* Extremely low-level interface services */
282 #include "i2cmd.c" /* Standard loadware command definitions */
283 #include "i2lib.c" /* High level interface services */
285 /* Configuration area for modprobe */
287 MODULE_AUTHOR("Doug McNash");
288 MODULE_DESCRIPTION("Computone IntelliPort Plus Driver");
290 static int poll_only = 0;
293 static int Eisa_slot;
296 static char rirqs[IP2_MAX_BOARDS];
297 static int Valid_Irqs[] = { 3, 4, 5, 7, 10, 11, 12, 15, 0};
299 /* for sysfs class support */
300 static struct class *ip2_class;
302 // Some functions to keep track of what irq's we have
305 is_valid_irq(int irq)
309 while ((*i != 0) && (*i != irq)) {
316 mark_requested_irq( char irq )
318 rirqs[iindx++] = irq;
323 clear_requested_irq( char irq )
326 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
327 if (rirqs[i] == irq) {
337 have_requested_irq( char irq )
339 // array init to zeros so 0 irq will not be requested as a side effect
341 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
348 /******************************************************************************/
349 /* Function: cleanup_module() */
350 /* Parameters: None */
351 /* Returns: Nothing */
354 /* This is a required entry point for an installable module. It has to return */
355 /* the device and the driver to a passive state. It should not be necessary */
356 /* to reset the board fully, especially as the loadware is downloaded */
357 /* externally rather than in the driver. We just want to disable the board */
358 /* and clear the loadware to a reset state. To allow this there has to be a */
359 /* way to detect whether the board has the loadware running at init time to */
360 /* handle subsequent installations of the driver. All memory allocated by the */
361 /* driver should be returned since it may be unloaded from memory. */
362 /******************************************************************************/
365 ip2_cleanup_module(void)
371 printk (KERN_DEBUG "Unloading %s: version %s\n", pcName, pcVersion );
373 /* Stop poll timer if we had one. */
375 del_timer ( &PollTimer );
379 /* Reset the boards we have. */
380 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
381 if ( i2BoardPtrTable[i] ) {
382 iiReset( i2BoardPtrTable[i] );
386 /* The following is done at most once, if any boards were installed. */
387 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
388 if ( i2BoardPtrTable[i] ) {
389 iiResetDelay( i2BoardPtrTable[i] );
390 /* free io addresses and Tibet */
391 release_region( ip2config.addr[i], 8 );
392 device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i));
393 device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i + 1));
395 /* Disable and remove interrupt handler. */
396 if ( (ip2config.irq[i] > 0) && have_requested_irq(ip2config.irq[i]) ) {
397 free_irq ( ip2config.irq[i], (void *)&pcName);
398 clear_requested_irq( ip2config.irq[i]);
401 class_destroy(ip2_class);
402 if ( ( err = tty_unregister_driver ( ip2_tty_driver ) ) ) {
403 printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n", err);
405 put_tty_driver(ip2_tty_driver);
406 unregister_chrdev(IP2_IPL_MAJOR, pcIpl);
407 remove_proc_entry("ip2mem", NULL);
410 for (i = 0; i < IP2_MAX_BOARDS; i++) {
413 if (ip2config.type[i] == PCI && ip2config.pci_dev[i]) {
414 pci_disable_device(ip2config.pci_dev[i]);
415 pci_dev_put(ip2config.pci_dev[i]);
416 ip2config.pci_dev[i] = NULL;
419 if ((pB = i2BoardPtrTable[i]) != 0 ) {
421 i2BoardPtrTable[i] = NULL;
423 if ((DevTableMem[i]) != NULL ) {
424 kfree ( DevTableMem[i] );
425 DevTableMem[i] = NULL;
429 /* Cleanup the iiEllis subsystem. */
432 printk (KERN_DEBUG "IP2 Unloaded\n" );
435 module_exit(ip2_cleanup_module);
438 static const struct tty_operations ip2_ops = {
442 .put_char = ip2_putchar,
443 .flush_chars = ip2_flush_chars,
444 .write_room = ip2_write_room,
445 .chars_in_buffer = ip2_chars_in_buf,
446 .flush_buffer = ip2_flush_buffer,
448 .throttle = ip2_throttle,
449 .unthrottle = ip2_unthrottle,
450 .set_termios = ip2_set_termios,
451 .set_ldisc = ip2_set_line_discipline,
454 .hangup = ip2_hangup,
455 .read_proc = ip2_read_proc,
456 .tiocmget = ip2_tiocmget,
457 .tiocmset = ip2_tiocmset,
460 /******************************************************************************/
461 /* Function: ip2_loadmain() */
462 /* Parameters: irq, io from command line of insmod et. al. */
463 /* pointer to fip firmware and firmware size for boards */
464 /* Returns: Success (0) */
467 /* This was the required entry point for all drivers (now in ip2.c) */
468 /* It performs all */
469 /* initialisation of the devices and driver structures, and registers itself */
470 /* with the relevant kernel modules. */
471 /******************************************************************************/
472 /* IRQF_DISABLED - if set blocks all interrupts else only this line */
473 /* IRQF_SHARED - for shared irq PCI or maybe EISA only */
474 /* SA_RANDOM - can be source for cert. random number generators */
475 #define IP2_SA_FLAGS 0
478 ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize)
483 i2eBordStrPtr pB = NULL;
485 static struct pci_dev *pci_dev_i = NULL;
487 ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0 );
489 /* process command line arguments to modprobe or
490 insmod i.e. iop & irqp */
491 /* irqp and iop should ALWAYS be specified now... But we check
492 them individually just to be sure, anyways... */
493 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
495 ip2config.addr[i] = iop[i];
498 ip2config.irq[i] = irqp[i];
500 ip2config.irq[i] = 0;
502 // This is a little bit of a hack. If poll_only=1 on command
503 // line back in ip2.c OR all IRQs on all specified boards are
504 // explicitly set to 0, then drop to poll only mode and override
505 // PCI or EISA interrupts. This superceeds the old hack of
506 // triggering if all interrupts were zero (like da default).
507 // Still a hack but less prone to random acts of terrorism.
509 // What we really should do, now that the IRQ default is set
510 // to -1, is to use 0 as a hard coded, do not probe.
513 poll_only |= irqp[i];
517 poll_only = !poll_only;
519 Fip_firmware = firmware;
520 Fip_firmware_size = firmsize;
522 /* Announce our presence */
523 printk( KERN_INFO "%s version %s\n", pcName, pcVersion );
525 // ip2 can be unloaded and reloaded for no good reason
526 // we can't let that happen here or bad things happen
527 // second load hoses board but not system - fixme later
529 printk( KERN_INFO "Still loaded\n" );
534 ip2_tty_driver = alloc_tty_driver(IP2_MAX_PORTS);
538 /* Initialise the iiEllis subsystem. */
541 /* Initialize arrays. */
542 memset( i2BoardPtrTable, 0, sizeof i2BoardPtrTable );
543 memset( DevTable, 0, sizeof DevTable );
545 /* Initialise all the boards we can find (up to the maximum). */
546 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
547 switch ( ip2config.addr[i] ) {
548 case 0: /* skip this slot even if card is present */
551 /* ISA address must be specified */
552 if ( (ip2config.addr[i] < 0x100) || (ip2config.addr[i] > 0x3f8) ) {
553 printk ( KERN_ERR "IP2: Bad ISA board %d address %x\n",
554 i, ip2config.addr[i] );
555 ip2config.addr[i] = 0;
557 ip2config.type[i] = ISA;
559 /* Check for valid irq argument, set for polling if invalid */
560 if (ip2config.irq[i] && !is_valid_irq(ip2config.irq[i])) {
561 printk(KERN_ERR "IP2: Bad IRQ(%d) specified\n",ip2config.irq[i]);
562 ip2config.irq[i] = 0;// 0 is polling and is valid in that sense
571 pci_dev_i = pci_get_device(PCI_VENDOR_ID_COMPUTONE,
572 PCI_DEVICE_ID_COMPUTONE_IP2EX, pci_dev_i);
573 if (pci_dev_i != NULL) {
576 if (pci_enable_device(pci_dev_i)) {
577 printk( KERN_ERR "IP2: can't enable PCI device at %s\n",
578 pci_name(pci_dev_i));
581 ip2config.type[i] = PCI;
582 ip2config.pci_dev[i] = pci_dev_get(pci_dev_i);
584 pci_read_config_dword(pci_dev_i, PCI_BASE_ADDRESS_1, &addr);
586 ip2config.addr[i]=(USHORT)(addr&0xfffe);
588 printk( KERN_ERR "IP2: PCI I/O address error\n");
591 // If the PCI BIOS assigned it, lets try and use it. If we
592 // can't acquire it or it screws up, deal with it then.
594 // if (!is_valid_irq(pci_irq)) {
595 // printk( KERN_ERR "IP2: Bad PCI BIOS IRQ(%d)\n",pci_irq);
598 ip2config.irq[i] = pci_dev_i->irq;
599 } else { // ann error
600 ip2config.addr[i] = 0;
601 printk(KERN_ERR "IP2: PCI board %d not found\n", i);
605 printk( KERN_ERR "IP2: PCI card specified but PCI support not\n");
606 printk( KERN_ERR "IP2: configured in this kernel.\n");
607 printk( KERN_ERR "IP2: Recompile kernel with CONFIG_PCI defined!\n");
608 #endif /* CONFIG_PCI */
611 if ( (ip2config.addr[i] = find_eisa_board( Eisa_slot + 1 )) != 0) {
612 /* Eisa_irq set as side effect, boo */
613 ip2config.type[i] = EISA;
615 ip2config.irq[i] = Eisa_irq;
620 pci_dev_put(pci_dev_i);
622 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
623 if ( ip2config.addr[i] ) {
624 pB = kzalloc(sizeof(i2eBordStr), GFP_KERNEL);
626 i2BoardPtrTable[i] = pB;
627 iiSetAddress( pB, ip2config.addr[i], ii2DelayTimer );
630 printk(KERN_ERR "IP2: board memory allocation error\n");
634 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
635 if ( ( pB = i2BoardPtrTable[i] ) != NULL ) {
640 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
641 if ( i2BoardPtrTable[i] != NULL ) {
646 ip2trace (ITRC_NO_PORT, ITRC_INIT, 2, 0 );
648 ip2_tty_driver->owner = THIS_MODULE;
649 ip2_tty_driver->name = "ttyF";
650 ip2_tty_driver->driver_name = pcDriver_name;
651 ip2_tty_driver->major = IP2_TTY_MAJOR;
652 ip2_tty_driver->minor_start = 0;
653 ip2_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
654 ip2_tty_driver->subtype = SERIAL_TYPE_NORMAL;
655 ip2_tty_driver->init_termios = tty_std_termios;
656 ip2_tty_driver->init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL;
657 ip2_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
658 tty_set_operations(ip2_tty_driver, &ip2_ops);
660 ip2trace (ITRC_NO_PORT, ITRC_INIT, 3, 0 );
662 /* Register the tty devices. */
663 if ( ( err = tty_register_driver ( ip2_tty_driver ) ) ) {
664 printk(KERN_ERR "IP2: failed to register tty driver (%d)\n", err);
665 put_tty_driver(ip2_tty_driver);
668 /* Register the IPL driver. */
669 if ( ( err = register_chrdev ( IP2_IPL_MAJOR, pcIpl, &ip2_ipl ) ) ) {
670 printk(KERN_ERR "IP2: failed to register IPL device (%d)\n", err );
672 /* create the sysfs class */
673 ip2_class = class_create(THIS_MODULE, "ip2");
674 if (IS_ERR(ip2_class)) {
675 err = PTR_ERR(ip2_class);
679 /* Register the read_procmem thing */
680 if (!proc_create("ip2mem",0,NULL,&ip2mem_proc_fops)) {
681 printk(KERN_ERR "IP2: failed to register read_procmem\n");
684 ip2trace (ITRC_NO_PORT, ITRC_INIT, 4, 0 );
685 /* Register the interrupt handler or poll handler, depending upon the
686 * specified interrupt.
689 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
690 if ( 0 == ip2config.addr[i] ) {
694 if ( NULL != ( pB = i2BoardPtrTable[i] ) ) {
695 device_create(ip2_class, NULL,
696 MKDEV(IP2_IPL_MAJOR, 4 * i),
698 device_create(ip2_class, NULL,
699 MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
702 for ( box = 0; box < ABS_MAX_BOXES; ++box )
704 for ( j = 0; j < ABS_BIGGEST_BOX; ++j )
706 if ( pB->i2eChannelMap[box] & (1 << j) )
708 tty_register_device(ip2_tty_driver,
709 j + ABS_BIGGEST_BOX *
710 (box+i*ABS_MAX_BOXES), NULL);
717 // Poll only forces driver to only use polling and
718 // to ignore the probed PCI or EISA interrupts.
719 ip2config.irq[i] = CIR_POLL;
721 if ( ip2config.irq[i] == CIR_POLL ) {
724 PollTimer.expires = POLL_TIMEOUT;
725 add_timer ( &PollTimer );
727 printk( KERN_INFO "IP2: polling\n");
730 if (have_requested_irq(ip2config.irq[i]))
732 rc = request_irq( ip2config.irq[i], ip2_interrupt,
733 IP2_SA_FLAGS | (ip2config.type[i] == PCI ? IRQF_SHARED : 0),
734 pcName, i2BoardPtrTable[i]);
736 printk(KERN_ERR "IP2: an request_irq failed: error %d\n",rc);
737 ip2config.irq[i] = CIR_POLL;
738 printk( KERN_INFO "IP2: Polling %ld/sec.\n",
739 (POLL_TIMEOUT - jiffies));
742 mark_requested_irq(ip2config.irq[i]);
743 /* Initialise the interrupt handler bottom half (aka slih). */
746 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
747 if ( i2BoardPtrTable[i] ) {
748 set_irq( i, ip2config.irq[i] ); /* set and enable board interrupt */
752 ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_RETURN, 0 );
756 unregister_chrdev(IP2_IPL_MAJOR, "ip2");
761 /******************************************************************************/
762 /* Function: ip2_init_board() */
763 /* Parameters: Index of board in configuration structure */
764 /* Returns: Success (0) */
767 /* This function initializes the specified board. The loadware is copied to */
768 /* the board, the channel structures are initialized, and the board details */
769 /* are reported on the console. */
770 /******************************************************************************/
772 ip2_init_board( int boardnum )
775 int nports = 0, nboxes = 0;
777 i2eBordStrPtr pB = i2BoardPtrTable[boardnum];
779 if ( !iiInitialize ( pB ) ) {
780 printk ( KERN_ERR "IP2: Failed to initialize board at 0x%x, error %d\n",
781 pB->i2eBase, pB->i2eError );
784 printk(KERN_INFO "IP2: Board %d: addr=0x%x irq=%d\n", boardnum + 1,
785 ip2config.addr[boardnum], ip2config.irq[boardnum] );
787 if (!request_region( ip2config.addr[boardnum], 8, pcName )) {
788 printk(KERN_ERR "IP2: bad addr=0x%x\n", ip2config.addr[boardnum]);
792 if ( iiDownloadAll ( pB, (loadHdrStrPtr)Fip_firmware, 1, Fip_firmware_size )
794 printk ( KERN_ERR "IP2: failed to download loadware\n" );
795 goto err_release_region;
797 printk ( KERN_INFO "IP2: fv=%d.%d.%d lv=%d.%d.%d\n",
798 pB->i2ePom.e.porVersion,
799 pB->i2ePom.e.porRevision,
800 pB->i2ePom.e.porSubRev, pB->i2eLVersion,
801 pB->i2eLRevision, pB->i2eLSub );
804 switch ( pB->i2ePom.e.porID & ~POR_ID_RESERVED ) {
807 printk( KERN_ERR "IP2: Unknown board type, ID = %x\n",
808 pB->i2ePom.e.porID );
810 goto err_release_region;
813 case POR_ID_II_4: /* IntelliPort-II, ISA-4 (4xRJ45) */
814 printk ( KERN_INFO "IP2: ISA-4\n" );
818 case POR_ID_II_8: /* IntelliPort-II, 8-port using standard brick. */
819 printk ( KERN_INFO "IP2: ISA-8 std\n" );
823 case POR_ID_II_8R: /* IntelliPort-II, 8-port using RJ11's (no CTS) */
824 printk ( KERN_INFO "IP2: ISA-8 RJ11\n" );
828 case POR_ID_FIIEX: /* IntelliPort IIEX */
830 int portnum = IP2_PORTS_PER_BOARD * boardnum;
833 for( box = 0; box < ABS_MAX_BOXES; ++box ) {
834 if ( pB->i2eChannelMap[box] != 0 ) {
837 for( i = 0; i < ABS_BIGGEST_BOX; ++i ) {
838 if ( pB->i2eChannelMap[box] & 1<< i ) {
843 DevTableMem[boardnum] = pCh =
844 kmalloc( sizeof(i2ChanStr) * nports, GFP_KERNEL );
846 printk ( KERN_ERR "IP2: (i2_init_channel:) Out of memory.\n");
847 goto err_release_region;
849 if ( !i2InitChannels( pB, nports, pCh ) ) {
850 printk(KERN_ERR "IP2: i2InitChannels failed: %d\n",pB->i2eError);
852 goto err_release_region;
854 pB->i2eChannelPtr = &DevTable[portnum];
855 pB->i2eChannelCnt = ABS_MOST_PORTS;
857 for( box = 0; box < ABS_MAX_BOXES; ++box, portnum += ABS_BIGGEST_BOX ) {
858 for( i = 0; i < ABS_BIGGEST_BOX; ++i ) {
859 if ( pB->i2eChannelMap[box] & (1 << i) ) {
860 DevTable[portnum + i] = pCh;
861 pCh->port_index = portnum + i;
866 printk(KERN_INFO "IP2: EX box=%d ports=%d %d bit\n",
867 nboxes, nports, pB->i2eDataWidth16 ? 16 : 8 );
871 DevTableMem[boardnum] = pCh =
872 kmalloc ( sizeof (i2ChanStr) * nports, GFP_KERNEL );
874 printk ( KERN_ERR "IP2: (i2_init_channel:) Out of memory.\n");
875 goto err_release_region;
877 pB->i2eChannelPtr = pCh;
878 pB->i2eChannelCnt = nports;
879 if ( !i2InitChannels( pB, nports, pCh ) ) {
880 printk(KERN_ERR "IP2: i2InitChannels failed: %d\n",pB->i2eError);
882 goto err_release_region;
884 pB->i2eChannelPtr = &DevTable[IP2_PORTS_PER_BOARD * boardnum];
886 for( i = 0; i < pB->i2eChannelCnt; ++i ) {
887 DevTable[IP2_PORTS_PER_BOARD * boardnum + i] = pCh;
888 pCh->port_index = (IP2_PORTS_PER_BOARD * boardnum) + i;
892 INIT_WORK(&pB->tqueue_interrupt, ip2_interrupt_bh);
896 release_region(ip2config.addr[boardnum], 8);
899 i2BoardPtrTable[boardnum] = NULL;
903 /******************************************************************************/
904 /* Function: find_eisa_board ( int start_slot ) */
905 /* Parameters: First slot to check */
906 /* Returns: Address of EISA IntelliPort II controller */
909 /* This function searches for an EISA IntelliPort controller, starting */
910 /* from the specified slot number. If the motherboard is not identified as an */
911 /* EISA motherboard, or no valid board ID is selected it returns 0. Otherwise */
912 /* it returns the base address of the controller. */
913 /******************************************************************************/
914 static unsigned short
915 find_eisa_board( int start_slot )
918 unsigned int idm = 0;
919 unsigned int idp = 0;
920 unsigned int base = 0;
927 * First a check for an EISA motherboard, which we do by comparing the
928 * EISA ID registers for the system board and the first couple of slots.
929 * No slot ID should match the system board ID, but on an ISA or PCI
930 * machine the odds are that an empty bus will return similar values for
934 value = (inb(i) << 24) + (inb(i+1) << 16) + (inb(i+2) << 8) + inb(i+3);
935 for( i = 0x1c80; i <= 0x4c80; i += 0x1000 ) {
936 j = (inb(i)<<24)+(inb(i+1)<<16)+(inb(i+2)<<8)+inb(i+3);
942 * OK, so we are inclined to believe that this is an EISA machine. Find
943 * an IntelliPort controller.
945 for( i = start_slot; i < 16; i++ ) {
947 idm = (inb(base + 0xc80) << 8) | (inb(base + 0xc81) & 0xff);
948 idp = (inb(base + 0xc82) << 8) | (inb(base + 0xc83) & 0xff);
950 if ( idm == 0x0e8e ) {
951 if ( idp == 0x0281 || idp == 0x0218 ) {
953 } else if ( idp == 0x0282 || idp == 0x0283 ) {
954 ismine = 3; /* Can do edge-trigger */
965 /* It's some sort of EISA card, but at what address is it configured? */
967 setup_address = base + 0xc88;
968 value = inb(base + 0xc86);
969 setup_irq = (value & 8) ? Valid_Irqs[value & 7] : 0;
971 if ( (ismine & 2) && !(value & 0x10) ) {
972 ismine = 1; /* Could be edging, but not */
975 if ( Eisa_irq == 0 ) {
976 Eisa_irq = setup_irq;
977 } else if ( Eisa_irq != setup_irq ) {
978 printk ( KERN_ERR "IP2: EISA irq mismatch between EISA controllers\n" );
982 printk(KERN_DEBUG "Computone EISA board in slot %d, I.D. 0x%x%x, Address 0x%x",
983 base >> 12, idm, idp, setup_address);
985 printk(KERN_DEBUG ", Interrupt %d %s\n",
986 setup_irq, (ismine & 2) ? "(edge)" : "(level)");
988 printk(KERN_DEBUG ", (polled)\n");
991 return setup_address;
994 /******************************************************************************/
995 /* Function: set_irq() */
996 /* Parameters: index to board in board table */
998 /* Returns: Success (0) */
1001 /******************************************************************************/
1003 set_irq( int boardnum, int boardIrq )
1005 unsigned char tempCommand[16];
1006 i2eBordStrPtr pB = i2BoardPtrTable[boardnum];
1007 unsigned long flags;
1010 * Notify the boards they may generate interrupts. This is done by
1011 * sending an in-line command to channel 0 on each board. This is why
1012 * the channels have to be defined already. For each board, if the
1013 * interrupt has never been defined, we must do so NOW, directly, since
1014 * board will not send flow control or even give an interrupt until this
1015 * is done. If polling we must send 0 as the interrupt parameter.
1018 // We will get an interrupt here at the end of this function
1020 iiDisableMailIrq(pB);
1022 /* We build up the entire packet header. */
1023 CHANNEL_OF(tempCommand) = 0;
1024 PTYPE_OF(tempCommand) = PTYPE_INLINE;
1025 CMD_COUNT_OF(tempCommand) = 2;
1026 (CMD_OF(tempCommand))[0] = CMDVALUE_IRQ;
1027 (CMD_OF(tempCommand))[1] = boardIrq;
1029 * Write to FIFO; don't bother to adjust fifo capacity for this, since
1030 * board will respond almost immediately after SendMail hit.
1032 write_lock_irqsave(&pB->write_fifo_spinlock, flags);
1033 iiWriteBuf(pB, tempCommand, 4);
1034 write_unlock_irqrestore(&pB->write_fifo_spinlock, flags);
1035 pB->i2eUsingIrq = boardIrq;
1036 pB->i2eOutMailWaiting |= MB_OUT_STUFFED;
1038 /* Need to update number of boards before you enable mailbox int */
1041 CHANNEL_OF(tempCommand) = 0;
1042 PTYPE_OF(tempCommand) = PTYPE_BYPASS;
1043 CMD_COUNT_OF(tempCommand) = 6;
1044 (CMD_OF(tempCommand))[0] = 88; // SILO
1045 (CMD_OF(tempCommand))[1] = 64; // chars
1046 (CMD_OF(tempCommand))[2] = 32; // ms
1048 (CMD_OF(tempCommand))[3] = 28; // MAX_BLOCK
1049 (CMD_OF(tempCommand))[4] = 64; // chars
1051 (CMD_OF(tempCommand))[5] = 87; // HW_TEST
1052 write_lock_irqsave(&pB->write_fifo_spinlock, flags);
1053 iiWriteBuf(pB, tempCommand, 8);
1054 write_unlock_irqrestore(&pB->write_fifo_spinlock, flags);
1056 CHANNEL_OF(tempCommand) = 0;
1057 PTYPE_OF(tempCommand) = PTYPE_BYPASS;
1058 CMD_COUNT_OF(tempCommand) = 1;
1059 (CMD_OF(tempCommand))[0] = 84; /* get BOX_IDS */
1060 iiWriteBuf(pB, tempCommand, 3);
1063 // enable heartbeat for test porpoises
1064 CHANNEL_OF(tempCommand) = 0;
1065 PTYPE_OF(tempCommand) = PTYPE_BYPASS;
1066 CMD_COUNT_OF(tempCommand) = 2;
1067 (CMD_OF(tempCommand))[0] = 44; /* get ping */
1068 (CMD_OF(tempCommand))[1] = 200; /* 200 ms */
1069 write_lock_irqsave(&pB->write_fifo_spinlock, flags);
1070 iiWriteBuf(pB, tempCommand, 4);
1071 write_unlock_irqrestore(&pB->write_fifo_spinlock, flags);
1074 iiEnableMailIrq(pB);
1075 iiSendPendingMail(pB);
1078 /******************************************************************************/
1079 /* Interrupt Handler Section */
1080 /******************************************************************************/
1083 service_all_boards(void)
1088 /* Service every board on the list */
1089 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
1090 pB = i2BoardPtrTable[i];
1092 i2ServiceBoard( pB );
1098 /******************************************************************************/
1099 /* Function: ip2_interrupt_bh(work) */
1100 /* Parameters: work - pointer to the board structure */
1101 /* Returns: Nothing */
1104 /* Service the board in a bottom half interrupt handler and then */
1105 /* reenable the board's interrupts if it has an IRQ number */
1107 /******************************************************************************/
1109 ip2_interrupt_bh(struct work_struct *work)
1111 i2eBordStrPtr pB = container_of(work, i2eBordStr, tqueue_interrupt);
1112 // pB better well be set or we have a problem! We can only get
1113 // here from the IMMEDIATE queue. Here, we process the boards.
1114 // Checking pB doesn't cost much and it saves us from the sanity checkers.
1119 i2ServiceBoard( pB );
1120 if( pB->i2eUsingIrq ) {
1121 // Re-enable his interrupts
1122 iiEnableMailIrq(pB);
1128 /******************************************************************************/
1129 /* Function: ip2_interrupt(int irq, void *dev_id) */
1130 /* Parameters: irq - interrupt number */
1131 /* pointer to optional device ID structure */
1132 /* Returns: Nothing */
1136 /* Our task here is simply to identify each board which needs servicing. */
1137 /* If we are queuing then, queue it to be serviced, and disable its irq */
1138 /* mask otherwise process the board directly. */
1140 /* We could queue by IRQ but that just complicates things on both ends */
1141 /* with very little gain in performance (how many instructions does */
1142 /* it take to iterate on the immediate queue). */
1145 /******************************************************************************/
1147 ip2_irq_work(i2eBordStrPtr pB)
1150 if (NO_MAIL_HERE != ( pB->i2eStartMail = iiGetMail(pB))) {
1151 // Disable his interrupt (will be enabled when serviced)
1152 // This is mostly to protect from reentrancy.
1153 iiDisableMailIrq(pB);
1155 // Park the board on the immediate queue for processing.
1156 schedule_work(&pB->tqueue_interrupt);
1158 // Make sure the immediate queue is flagged to fire.
1162 // We are using immediate servicing here. This sucks and can
1163 // cause all sorts of havoc with ppp and others. The failsafe
1164 // check on iiSendPendingMail could also throw a hairball.
1166 i2ServiceBoard( pB );
1168 #endif /* USE_IQI */
1172 ip2_polled_interrupt(void)
1178 ip2trace (ITRC_NO_PORT, ITRC_INTR, 99, 1, irq );
1180 /* Service just the boards on the list using this irq */
1181 for( i = 0; i < i2nBoards; ++i ) {
1182 pB = i2BoardPtrTable[i];
1184 // Only process those boards which match our IRQ.
1185 // IRQ = 0 for polled boards, we won't poll "IRQ" boards
1187 if ( pB && (pB->i2eUsingIrq == irq) ) {
1194 ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 );
1198 ip2_interrupt(int irq, void *dev_id)
1200 i2eBordStrPtr pB = dev_id;
1202 ip2trace (ITRC_NO_PORT, ITRC_INTR, 99, 1, pB->i2eUsingIrq );
1208 ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 );
1212 /******************************************************************************/
1213 /* Function: ip2_poll(unsigned long arg) */
1215 /* Returns: Nothing */
1218 /* This function calls the library routine i2ServiceBoard for each board in */
1219 /* the board table. This is used instead of the interrupt routine when polled */
1220 /* mode is specified. */
1221 /******************************************************************************/
1223 ip2_poll(unsigned long arg)
1225 ip2trace (ITRC_NO_PORT, ITRC_INTR, 100, 0 );
1227 TimerOn = 0; // it's the truth but not checked in service
1229 // Just polled boards, IRQ = 0 will hit all non-interrupt boards.
1230 // It will NOT poll boards handled by hard interrupts.
1231 // The issue of queued BH interrupts is handled in ip2_interrupt().
1232 ip2_polled_interrupt();
1234 PollTimer.expires = POLL_TIMEOUT;
1235 add_timer( &PollTimer );
1238 ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 );
1241 static void do_input(struct work_struct *work)
1243 i2ChanStrPtr pCh = container_of(work, i2ChanStr, tqueue_input);
1244 unsigned long flags;
1246 ip2trace(CHANN, ITRC_INPUT, 21, 0 );
1249 if ( pCh->pTTY != NULL ) {
1250 read_lock_irqsave(&pCh->Ibuf_spinlock, flags);
1251 if (!pCh->throttled && (pCh->Ibuf_stuff != pCh->Ibuf_strip)) {
1252 read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags);
1255 read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags);
1257 ip2trace(CHANN, ITRC_INPUT, 22, 0 );
1259 i2InputFlush( pCh );
1263 // code duplicated from n_tty (ldisc)
1264 static inline void isig(int sig, struct tty_struct *tty, int flush)
1267 kill_pgrp(tty->pgrp, sig, 1);
1268 if (flush || !L_NOFLSH(tty)) {
1269 if ( tty->ldisc.flush_buffer )
1270 tty->ldisc.flush_buffer(tty);
1271 i2InputFlush( tty->driver_data );
1275 static void do_status(struct work_struct *work)
1277 i2ChanStrPtr pCh = container_of(work, i2ChanStr, tqueue_status);
1280 status = i2GetStatus( pCh, (I2_BRK|I2_PAR|I2_FRA|I2_OVR) );
1282 ip2trace (CHANN, ITRC_STATUS, 21, 1, status );
1284 if (pCh->pTTY && (status & (I2_BRK|I2_PAR|I2_FRA|I2_OVR)) ) {
1285 if ( (status & I2_BRK) ) {
1286 // code duplicated from n_tty (ldisc)
1287 if (I_IGNBRK(pCh->pTTY))
1289 if (I_BRKINT(pCh->pTTY)) {
1290 isig(SIGINT, pCh->pTTY, 1);
1293 wake_up_interruptible(&pCh->pTTY->read_wait);
1295 #ifdef NEVER_HAPPENS_AS_SETUP_XXX
1296 // and can't work because we don't know the_char
1297 // as the_char is reported on a separate path
1298 // The intelligent board does this stuff as setup
1300 char brkf = TTY_NORMAL;
1301 unsigned char brkc = '\0';
1303 if ( (status & I2_BRK) ) {
1307 else if (status & I2_PAR) {
1310 } else if (status & I2_FRA) {
1313 } else if (status & I2_OVR) {
1317 tmp = pCh->pTTY->real_raw;
1318 pCh->pTTY->real_raw = 0;
1319 pCh->pTTY->ldisc.receive_buf( pCh->pTTY, &brkc, &brkf, 1 );
1320 pCh->pTTY->real_raw = tmp;
1322 #endif /* NEVER_HAPPENS_AS_SETUP_XXX */
1326 if ( status & (I2_DDCD | I2_DDSR | I2_DCTS | I2_DRI) ) {
1327 wake_up_interruptible(&pCh->delta_msr_wait);
1329 if ( (pCh->flags & ASYNC_CHECK_CD) && (status & I2_DDCD) ) {
1330 if ( status & I2_DCD ) {
1332 wake_up_interruptible ( &pCh->open_wait );
1335 if (pCh->pTTY && (!(pCh->pTTY->termios->c_cflag & CLOCAL)) ) {
1336 tty_hangup( pCh->pTTY );
1342 ip2trace (CHANN, ITRC_STATUS, 26, 0 );
1345 /******************************************************************************/
1346 /* Device Open/Close/Ioctl Entry Point Section */
1347 /******************************************************************************/
1349 /******************************************************************************/
1350 /* Function: open_sanity_check() */
1351 /* Parameters: Pointer to tty structure */
1352 /* Pointer to file structure */
1353 /* Returns: Success or failure */
1356 /* Verifies the structure magic numbers and cross links. */
1357 /******************************************************************************/
1358 #ifdef IP2DEBUG_OPEN
1360 open_sanity_check( i2ChanStrPtr pCh, i2eBordStrPtr pBrd )
1362 if ( pBrd->i2eValid != I2E_MAGIC ) {
1363 printk(KERN_ERR "IP2: invalid board structure\n" );
1364 } else if ( pBrd != pCh->pMyBord ) {
1365 printk(KERN_ERR "IP2: board structure pointer mismatch (%p)\n",
1367 } else if ( pBrd->i2eChannelCnt < pCh->port_index ) {
1368 printk(KERN_ERR "IP2: bad device index (%d)\n", pCh->port_index );
1369 } else if (&((i2ChanStrPtr)pBrd->i2eChannelPtr)[pCh->port_index] != pCh) {
1371 printk(KERN_INFO "IP2: all pointers check out!\n" );
1377 /******************************************************************************/
1378 /* Function: ip2_open() */
1379 /* Parameters: Pointer to tty structure */
1380 /* Pointer to file structure */
1381 /* Returns: Success or failure */
1383 /* Description: (MANDATORY) */
1384 /* A successful device open has to run a gauntlet of checks before it */
1385 /* completes. After some sanity checking and pointer setup, the function */
1386 /* blocks until all conditions are satisfied. It then initialises the port to */
1387 /* the default characteristics and returns. */
1388 /******************************************************************************/
1390 ip2_open( PTTY tty, struct file *pFile )
1395 i2ChanStrPtr pCh = DevTable[tty->index];
1397 ip2trace (tty->index, ITRC_OPEN, ITRC_ENTER, 0 );
1399 if ( pCh == NULL ) {
1402 /* Setup pointer links in device and tty structures */
1404 tty->driver_data = pCh;
1406 #ifdef IP2DEBUG_OPEN
1408 "IP2:open(tty=%p,pFile=%p):dev=%s,ch=%d,idx=%d\n",
1409 tty, pFile, tty->name, pCh->infl.hd.i2sChannel, pCh->port_index);
1410 open_sanity_check ( pCh, pCh->pMyBord );
1413 i2QueueCommands(PTYPE_INLINE, pCh, 100, 3, CMD_DTRUP,CMD_RTSUP,CMD_DCD_REP);
1414 pCh->dataSetOut |= (I2_DTR | I2_RTS);
1415 serviceOutgoingFifo( pCh->pMyBord );
1417 /* Block here until the port is ready (per serial and istallion) */
1419 * 1. If the port is in the middle of closing wait for the completion
1420 * and then return the appropriate error.
1422 init_waitqueue_entry(&wait, current);
1423 add_wait_queue(&pCh->close_wait, &wait);
1424 set_current_state( TASK_INTERRUPTIBLE );
1426 if ( tty_hung_up_p(pFile) || ( pCh->flags & ASYNC_CLOSING )) {
1427 if ( pCh->flags & ASYNC_CLOSING ) {
1430 if ( tty_hung_up_p(pFile) ) {
1431 set_current_state( TASK_RUNNING );
1432 remove_wait_queue(&pCh->close_wait, &wait);
1433 return( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EAGAIN : -ERESTARTSYS;
1436 set_current_state( TASK_RUNNING );
1437 remove_wait_queue(&pCh->close_wait, &wait);
1440 * 3. Handle a non-blocking open of a normal port.
1442 if ( (pFile->f_flags & O_NONBLOCK) || (tty->flags & (1<<TTY_IO_ERROR) )) {
1443 pCh->flags |= ASYNC_NORMAL_ACTIVE;
1447 * 4. Now loop waiting for the port to be free and carrier present
1450 if ( tty->termios->c_cflag & CLOCAL )
1453 #ifdef IP2DEBUG_OPEN
1454 printk(KERN_DEBUG "OpenBlock: do_clocal = %d\n", do_clocal);
1459 init_waitqueue_entry(&wait, current);
1460 add_wait_queue(&pCh->open_wait, &wait);
1463 i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_DTRUP, CMD_RTSUP);
1464 pCh->dataSetOut |= (I2_DTR | I2_RTS);
1465 set_current_state( TASK_INTERRUPTIBLE );
1466 serviceOutgoingFifo( pCh->pMyBord );
1467 if ( tty_hung_up_p(pFile) ) {
1468 set_current_state( TASK_RUNNING );
1469 remove_wait_queue(&pCh->open_wait, &wait);
1470 return ( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EBUSY : -ERESTARTSYS;
1472 if (!(pCh->flags & ASYNC_CLOSING) &&
1473 (do_clocal || (pCh->dataSetIn & I2_DCD) )) {
1478 #ifdef IP2DEBUG_OPEN
1479 printk(KERN_DEBUG "ASYNC_CLOSING = %s\n",
1480 (pCh->flags & ASYNC_CLOSING)?"True":"False");
1481 printk(KERN_DEBUG "OpenBlock: waiting for CD or signal\n");
1483 ip2trace (CHANN, ITRC_OPEN, 3, 2, 0,
1484 (pCh->flags & ASYNC_CLOSING) );
1485 /* check for signal */
1486 if (signal_pending(current)) {
1487 rc = (( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EAGAIN : -ERESTARTSYS);
1492 set_current_state( TASK_RUNNING );
1493 remove_wait_queue(&pCh->open_wait, &wait);
1495 --pCh->wopen; //why count?
1497 ip2trace (CHANN, ITRC_OPEN, 4, 0 );
1502 pCh->flags |= ASYNC_NORMAL_ACTIVE;
1506 /* first open - Assign termios structure to port */
1507 if ( tty->count == 1 ) {
1508 i2QueueCommands(PTYPE_INLINE, pCh, 0, 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB);
1509 /* Now we must send the termios settings to the loadware */
1510 set_params( pCh, NULL );
1514 * Now set any i2lib options. These may go away if the i2lib code ends
1515 * up rolled into the mainline.
1517 pCh->channelOptions |= CO_NBLOCK_WRITE;
1519 #ifdef IP2DEBUG_OPEN
1520 printk (KERN_DEBUG "IP2: open completed\n" );
1522 serviceOutgoingFifo( pCh->pMyBord );
1524 ip2trace (CHANN, ITRC_OPEN, ITRC_RETURN, 0 );
1529 /******************************************************************************/
1530 /* Function: ip2_close() */
1531 /* Parameters: Pointer to tty structure */
1532 /* Pointer to file structure */
1533 /* Returns: Nothing */
1538 /******************************************************************************/
1540 ip2_close( PTTY tty, struct file *pFile )
1542 i2ChanStrPtr pCh = tty->driver_data;
1548 ip2trace (CHANN, ITRC_CLOSE, ITRC_ENTER, 0 );
1550 #ifdef IP2DEBUG_OPEN
1551 printk(KERN_DEBUG "IP2:close %s:\n",tty->name);
1554 if ( tty_hung_up_p ( pFile ) ) {
1556 ip2trace (CHANN, ITRC_CLOSE, 2, 1, 2 );
1560 if ( tty->count > 1 ) { /* not the last close */
1562 ip2trace (CHANN, ITRC_CLOSE, 2, 1, 3 );
1566 pCh->flags |= ASYNC_CLOSING; // last close actually
1570 if (pCh->ClosingWaitTime != ASYNC_CLOSING_WAIT_NONE) {
1572 * Before we drop DTR, make sure the transmitter has completely drained.
1573 * This uses an timeout, after which the close
1576 ip2_wait_until_sent(tty, pCh->ClosingWaitTime );
1579 * At this point we stop accepting input. Here we flush the channel
1580 * input buffer which will allow the board to send up more data. Any
1581 * additional input is tossed at interrupt/poll time.
1583 i2InputFlush( pCh );
1585 /* disable DSS reporting */
1586 i2QueueCommands(PTYPE_INLINE, pCh, 100, 4,
1587 CMD_DCD_NREP, CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);
1588 if ( !tty || (tty->termios->c_cflag & HUPCL) ) {
1589 i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN);
1590 pCh->dataSetOut &= ~(I2_DTR | I2_RTS);
1591 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25));
1594 serviceOutgoingFifo ( pCh->pMyBord );
1596 tty_ldisc_flush(tty);
1597 tty_driver_flush_buffer(tty);
1603 if (pCh->ClosingDelay) {
1604 msleep_interruptible(jiffies_to_msecs(pCh->ClosingDelay));
1606 wake_up_interruptible(&pCh->open_wait);
1609 pCh->flags &=~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1610 wake_up_interruptible(&pCh->close_wait);
1612 #ifdef IP2DEBUG_OPEN
1613 DBG_CNT("ip2_close: after wakeups--");
1617 ip2trace (CHANN, ITRC_CLOSE, ITRC_RETURN, 1, 1 );
1622 /******************************************************************************/
1623 /* Function: ip2_hangup() */
1624 /* Parameters: Pointer to tty structure */
1625 /* Returns: Nothing */
1630 /******************************************************************************/
1632 ip2_hangup ( PTTY tty )
1634 i2ChanStrPtr pCh = tty->driver_data;
1640 ip2trace (CHANN, ITRC_HANGUP, ITRC_ENTER, 0 );
1642 ip2_flush_buffer(tty);
1644 /* disable DSS reporting */
1646 i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_DCD_NREP);
1647 i2QueueCommands(PTYPE_INLINE, pCh, 0, 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB);
1648 if ( (tty->termios->c_cflag & HUPCL) ) {
1649 i2QueueCommands(PTYPE_BYPASS, pCh, 0, 2, CMD_RTSDN, CMD_DTRDN);
1650 pCh->dataSetOut &= ~(I2_DTR | I2_RTS);
1651 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25));
1653 i2QueueCommands(PTYPE_INLINE, pCh, 1, 3,
1654 CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);
1655 serviceOutgoingFifo ( pCh->pMyBord );
1657 wake_up_interruptible ( &pCh->delta_msr_wait );
1659 pCh->flags &= ~ASYNC_NORMAL_ACTIVE;
1661 wake_up_interruptible ( &pCh->open_wait );
1663 ip2trace (CHANN, ITRC_HANGUP, ITRC_RETURN, 0 );
1666 /******************************************************************************/
1667 /******************************************************************************/
1668 /* Device Output Section */
1669 /******************************************************************************/
1670 /******************************************************************************/
1672 /******************************************************************************/
1673 /* Function: ip2_write() */
1674 /* Parameters: Pointer to tty structure */
1675 /* Flag denoting data is in user (1) or kernel (0) space */
1676 /* Pointer to data */
1677 /* Number of bytes to write */
1678 /* Returns: Number of bytes actually written */
1680 /* Description: (MANDATORY) */
1683 /******************************************************************************/
1685 ip2_write( PTTY tty, const unsigned char *pData, int count)
1687 i2ChanStrPtr pCh = tty->driver_data;
1689 unsigned long flags;
1691 ip2trace (CHANN, ITRC_WRITE, ITRC_ENTER, 2, count, -1 );
1693 /* Flush out any buffered data left over from ip2_putchar() calls. */
1694 ip2_flush_chars( tty );
1696 /* This is the actual move bit. Make sure it does what we need!!!!! */
1697 write_lock_irqsave(&pCh->Pbuf_spinlock, flags);
1698 bytesSent = i2Output( pCh, pData, count);
1699 write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1701 ip2trace (CHANN, ITRC_WRITE, ITRC_RETURN, 1, bytesSent );
1703 return bytesSent > 0 ? bytesSent : 0;
1706 /******************************************************************************/
1707 /* Function: ip2_putchar() */
1708 /* Parameters: Pointer to tty structure */
1709 /* Character to write */
1710 /* Returns: Nothing */
1715 /******************************************************************************/
1717 ip2_putchar( PTTY tty, unsigned char ch )
1719 i2ChanStrPtr pCh = tty->driver_data;
1720 unsigned long flags;
1722 // ip2trace (CHANN, ITRC_PUTC, ITRC_ENTER, 1, ch );
1724 write_lock_irqsave(&pCh->Pbuf_spinlock, flags);
1725 pCh->Pbuf[pCh->Pbuf_stuff++] = ch;
1726 if ( pCh->Pbuf_stuff == sizeof pCh->Pbuf ) {
1727 write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1728 ip2_flush_chars( tty );
1730 write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1733 // ip2trace (CHANN, ITRC_PUTC, ITRC_RETURN, 1, ch );
1736 /******************************************************************************/
1737 /* Function: ip2_flush_chars() */
1738 /* Parameters: Pointer to tty structure */
1739 /* Returns: Nothing */
1743 /******************************************************************************/
1745 ip2_flush_chars( PTTY tty )
1748 i2ChanStrPtr pCh = tty->driver_data;
1749 unsigned long flags;
1751 write_lock_irqsave(&pCh->Pbuf_spinlock, flags);
1752 if ( pCh->Pbuf_stuff ) {
1754 // ip2trace (CHANN, ITRC_PUTC, 10, 1, strip );
1757 // We may need to restart i2Output if it does not fullfill this request
1759 strip = i2Output( pCh, pCh->Pbuf, pCh->Pbuf_stuff);
1760 if ( strip != pCh->Pbuf_stuff ) {
1761 memmove( pCh->Pbuf, &pCh->Pbuf[strip], pCh->Pbuf_stuff - strip );
1763 pCh->Pbuf_stuff -= strip;
1765 write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1768 /******************************************************************************/
1769 /* Function: ip2_write_room() */
1770 /* Parameters: Pointer to tty structure */
1771 /* Returns: Number of bytes that the driver can accept */
1775 /******************************************************************************/
1777 ip2_write_room ( PTTY tty )
1780 i2ChanStrPtr pCh = tty->driver_data;
1781 unsigned long flags;
1783 read_lock_irqsave(&pCh->Pbuf_spinlock, flags);
1784 bytesFree = i2OutputFree( pCh ) - pCh->Pbuf_stuff;
1785 read_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1787 ip2trace (CHANN, ITRC_WRITE, 11, 1, bytesFree );
1789 return ((bytesFree > 0) ? bytesFree : 0);
1792 /******************************************************************************/
1793 /* Function: ip2_chars_in_buf() */
1794 /* Parameters: Pointer to tty structure */
1795 /* Returns: Number of bytes queued for transmission */
1800 /******************************************************************************/
1802 ip2_chars_in_buf ( PTTY tty )
1804 i2ChanStrPtr pCh = tty->driver_data;
1806 unsigned long flags;
1808 ip2trace (CHANN, ITRC_WRITE, 12, 1, pCh->Obuf_char_count + pCh->Pbuf_stuff );
1810 #ifdef IP2DEBUG_WRITE
1811 printk (KERN_DEBUG "IP2: chars in buffer = %d (%d,%d)\n",
1812 pCh->Obuf_char_count + pCh->Pbuf_stuff,
1813 pCh->Obuf_char_count, pCh->Pbuf_stuff );
1815 read_lock_irqsave(&pCh->Obuf_spinlock, flags);
1816 rc = pCh->Obuf_char_count;
1817 read_unlock_irqrestore(&pCh->Obuf_spinlock, flags);
1818 read_lock_irqsave(&pCh->Pbuf_spinlock, flags);
1819 rc += pCh->Pbuf_stuff;
1820 read_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1824 /******************************************************************************/
1825 /* Function: ip2_flush_buffer() */
1826 /* Parameters: Pointer to tty structure */
1827 /* Returns: Nothing */
1832 /******************************************************************************/
1834 ip2_flush_buffer( PTTY tty )
1836 i2ChanStrPtr pCh = tty->driver_data;
1837 unsigned long flags;
1839 ip2trace (CHANN, ITRC_FLUSH, ITRC_ENTER, 0 );
1841 #ifdef IP2DEBUG_WRITE
1842 printk (KERN_DEBUG "IP2: flush buffer\n" );
1844 write_lock_irqsave(&pCh->Pbuf_spinlock, flags);
1845 pCh->Pbuf_stuff = 0;
1846 write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1847 i2FlushOutput( pCh );
1850 ip2trace (CHANN, ITRC_FLUSH, ITRC_RETURN, 0 );
1854 /******************************************************************************/
1855 /* Function: ip2_wait_until_sent() */
1856 /* Parameters: Pointer to tty structure */
1857 /* Timeout for wait. */
1858 /* Returns: Nothing */
1861 /* This function is used in place of the normal tty_wait_until_sent, which */
1862 /* only waits for the driver buffers to be empty (or rather, those buffers */
1863 /* reported by chars_in_buffer) which doesn't work for IP2 due to the */
1864 /* indeterminate number of bytes buffered on the board. */
1865 /******************************************************************************/
1867 ip2_wait_until_sent ( PTTY tty, int timeout )
1870 i2ChanStrPtr pCh = tty->driver_data;
1872 tty_wait_until_sent(tty, timeout );
1873 if ( (i = timeout - (jiffies -i)) > 0)
1874 i2DrainOutput( pCh, i );
1877 /******************************************************************************/
1878 /******************************************************************************/
1879 /* Device Input Section */
1880 /******************************************************************************/
1881 /******************************************************************************/
1883 /******************************************************************************/
1884 /* Function: ip2_throttle() */
1885 /* Parameters: Pointer to tty structure */
1886 /* Returns: Nothing */
1891 /******************************************************************************/
1893 ip2_throttle ( PTTY tty )
1895 i2ChanStrPtr pCh = tty->driver_data;
1897 #ifdef IP2DEBUG_READ
1898 printk (KERN_DEBUG "IP2: throttle\n" );
1901 * Signal the poll/interrupt handlers not to forward incoming data to
1902 * the line discipline. This will cause the buffers to fill up in the
1903 * library and thus cause the library routines to send the flow control
1909 /******************************************************************************/
1910 /* Function: ip2_unthrottle() */
1911 /* Parameters: Pointer to tty structure */
1912 /* Returns: Nothing */
1917 /******************************************************************************/
1919 ip2_unthrottle ( PTTY tty )
1921 i2ChanStrPtr pCh = tty->driver_data;
1922 unsigned long flags;
1924 #ifdef IP2DEBUG_READ
1925 printk (KERN_DEBUG "IP2: unthrottle\n" );
1928 /* Pass incoming data up to the line discipline again. */
1930 i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_RESUME);
1931 serviceOutgoingFifo( pCh->pMyBord );
1932 read_lock_irqsave(&pCh->Ibuf_spinlock, flags);
1933 if ( pCh->Ibuf_stuff != pCh->Ibuf_strip ) {
1934 read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags);
1935 #ifdef IP2DEBUG_READ
1936 printk (KERN_DEBUG "i2Input called from unthrottle\n" );
1940 read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags);
1944 ip2_start ( PTTY tty )
1946 i2ChanStrPtr pCh = DevTable[tty->index];
1948 i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_RESUME);
1949 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_UNSUSPEND);
1950 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_RESUME);
1951 #ifdef IP2DEBUG_WRITE
1952 printk (KERN_DEBUG "IP2: start tx\n" );
1957 ip2_stop ( PTTY tty )
1959 i2ChanStrPtr pCh = DevTable[tty->index];
1961 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_SUSPEND);
1962 #ifdef IP2DEBUG_WRITE
1963 printk (KERN_DEBUG "IP2: stop tx\n" );
1967 /******************************************************************************/
1968 /* Device Ioctl Section */
1969 /******************************************************************************/
1971 static int ip2_tiocmget(struct tty_struct *tty, struct file *file)
1973 i2ChanStrPtr pCh = DevTable[tty->index];
1974 #ifdef ENABLE_DSSNOW
1982 FIXME - the following code is causing a NULL pointer dereference in
1983 2.3.51 in an interrupt handler. It's suppose to prompt the board
1984 to return the DSS signal status immediately. Why doesn't it do
1985 the same thing in 2.2.14?
1988 /* This thing is still busted in the 1.2.12 driver on 2.4.x
1989 and even hoses the serial console so the oops can be trapped.
1992 #ifdef ENABLE_DSSNOW
1993 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DSS_NOW);
1995 init_waitqueue_entry(&wait, current);
1996 add_wait_queue(&pCh->dss_now_wait, &wait);
1997 set_current_state( TASK_INTERRUPTIBLE );
1999 serviceOutgoingFifo( pCh->pMyBord );
2003 set_current_state( TASK_RUNNING );
2004 remove_wait_queue(&pCh->dss_now_wait, &wait);
2006 if (signal_pending(current)) {
2010 return ((pCh->dataSetOut & I2_RTS) ? TIOCM_RTS : 0)
2011 | ((pCh->dataSetOut & I2_DTR) ? TIOCM_DTR : 0)
2012 | ((pCh->dataSetIn & I2_DCD) ? TIOCM_CAR : 0)
2013 | ((pCh->dataSetIn & I2_RI) ? TIOCM_RNG : 0)
2014 | ((pCh->dataSetIn & I2_DSR) ? TIOCM_DSR : 0)
2015 | ((pCh->dataSetIn & I2_CTS) ? TIOCM_CTS : 0);
2018 static int ip2_tiocmset(struct tty_struct *tty, struct file *file,
2019 unsigned int set, unsigned int clear)
2021 i2ChanStrPtr pCh = DevTable[tty->index];
2026 if (set & TIOCM_RTS) {
2027 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_RTSUP);
2028 pCh->dataSetOut |= I2_RTS;
2030 if (set & TIOCM_DTR) {
2031 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DTRUP);
2032 pCh->dataSetOut |= I2_DTR;
2035 if (clear & TIOCM_RTS) {
2036 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_RTSDN);
2037 pCh->dataSetOut &= ~I2_RTS;
2039 if (clear & TIOCM_DTR) {
2040 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DTRDN);
2041 pCh->dataSetOut &= ~I2_DTR;
2043 serviceOutgoingFifo( pCh->pMyBord );
2047 /******************************************************************************/
2048 /* Function: ip2_ioctl() */
2049 /* Parameters: Pointer to tty structure */
2050 /* Pointer to file structure */
2053 /* Returns: Success or failure */
2058 /******************************************************************************/
2060 ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg )
2063 i2ChanStrPtr pCh = DevTable[tty->index];
2065 struct async_icount cprev, cnow; /* kernel counter temps */
2066 struct serial_icounter_struct __user *p_cuser;
2068 unsigned long flags;
2069 void __user *argp = (void __user *)arg;
2076 ip2trace (CHANN, ITRC_IOCTL, ITRC_ENTER, 2, cmd, arg );
2078 #ifdef IP2DEBUG_IOCTL
2079 printk(KERN_DEBUG "IP2: ioctl cmd (%x), arg (%lx)\n", cmd, arg );
2085 ip2trace (CHANN, ITRC_IOCTL, 2, 1, rc );
2087 rc = get_serial_info(pCh, argp);
2094 ip2trace (CHANN, ITRC_IOCTL, 3, 1, rc );
2096 rc = set_serial_info(pCh, argp);
2102 rc = tty_check_change(tty);
2107 //return -ENOIOCTLCMD;
2110 //return -ENOIOCTLCMD;
2113 if (STOP_CHAR(tty) != __DISABLED_CHAR) {
2114 i2QueueCommands( PTYPE_BYPASS, pCh, 100, 1,
2115 CMD_XMIT_NOW(STOP_CHAR(tty)));
2119 if (START_CHAR(tty) != __DISABLED_CHAR) {
2120 i2QueueCommands( PTYPE_BYPASS, pCh, 100, 1,
2121 CMD_XMIT_NOW(START_CHAR(tty)));
2129 case TCSBRK: /* SVID version: non-zero arg --> no break */
2130 rc = tty_check_change(tty);
2132 ip2trace (CHANN, ITRC_IOCTL, 4, 1, rc );
2135 ip2_wait_until_sent(tty,0);
2137 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_SEND_BRK(250));
2138 serviceOutgoingFifo( pCh->pMyBord );
2143 case TCSBRKP: /* support for POSIX tcsendbreak() */
2144 rc = tty_check_change(tty);
2146 ip2trace (CHANN, ITRC_IOCTL, 5, 1, rc );
2149 ip2_wait_until_sent(tty,0);
2150 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1,
2151 CMD_SEND_BRK(arg ? arg*100 : 250));
2152 serviceOutgoingFifo ( pCh->pMyBord );
2158 ip2trace (CHANN, ITRC_IOCTL, 6, 1, rc );
2160 rc = put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *)argp);
2167 ip2trace (CHANN, ITRC_IOCTL, 7, 1, rc );
2169 rc = get_user(arg,(unsigned long __user *) argp);
2172 tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL)
2173 | (arg ? CLOCAL : 0));
2178 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change - mask
2179 * passed in arg for lines of interest (use |'ed TIOCM_RNG/DSR/CD/CTS
2180 * for masking). Caller should use TIOCGICOUNT to see which one it was
2183 write_lock_irqsave(&pB->read_fifo_spinlock, flags);
2184 cprev = pCh->icount; /* note the counters on entry */
2185 write_unlock_irqrestore(&pB->read_fifo_spinlock, flags);
2186 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 4,
2187 CMD_DCD_REP, CMD_CTS_REP, CMD_DSR_REP, CMD_RI_REP);
2188 init_waitqueue_entry(&wait, current);
2189 add_wait_queue(&pCh->delta_msr_wait, &wait);
2190 set_current_state( TASK_INTERRUPTIBLE );
2192 serviceOutgoingFifo( pCh->pMyBord );
2194 ip2trace (CHANN, ITRC_IOCTL, 10, 0 );
2198 ip2trace (CHANN, ITRC_IOCTL, 11, 0 );
2200 /* see if a signal did it */
2201 if (signal_pending(current)) {
2205 write_lock_irqsave(&pB->read_fifo_spinlock, flags);
2206 cnow = pCh->icount; /* atomic copy */
2207 write_unlock_irqrestore(&pB->read_fifo_spinlock, flags);
2208 if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
2209 cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) {
2210 rc = -EIO; /* no change => rc */
2213 if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
2214 ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
2215 ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
2216 ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
2222 set_current_state( TASK_RUNNING );
2223 remove_wait_queue(&pCh->delta_msr_wait, &wait);
2225 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 3,
2226 CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);
2227 if ( ! (pCh->flags & ASYNC_CHECK_CD)) {
2228 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DCD_NREP);
2230 serviceOutgoingFifo( pCh->pMyBord );
2235 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
2236 * Return: write counters to the user passed counter struct
2237 * NB: both 1->0 and 0->1 transitions are counted except for RI where
2238 * only 0->1 is counted. The controller is quite capable of counting
2239 * both, but this done to preserve compatibility with the standard
2243 ip2trace (CHANN, ITRC_IOCTL, 11, 1, rc );
2245 write_lock_irqsave(&pB->read_fifo_spinlock, flags);
2247 write_unlock_irqrestore(&pB->read_fifo_spinlock, flags);
2249 rc = put_user(cnow.cts, &p_cuser->cts);
2250 rc = put_user(cnow.dsr, &p_cuser->dsr);
2251 rc = put_user(cnow.rng, &p_cuser->rng);
2252 rc = put_user(cnow.dcd, &p_cuser->dcd);
2253 rc = put_user(cnow.rx, &p_cuser->rx);
2254 rc = put_user(cnow.tx, &p_cuser->tx);
2255 rc = put_user(cnow.frame, &p_cuser->frame);
2256 rc = put_user(cnow.overrun, &p_cuser->overrun);
2257 rc = put_user(cnow.parity, &p_cuser->parity);
2258 rc = put_user(cnow.brk, &p_cuser->brk);
2259 rc = put_user(cnow.buf_overrun, &p_cuser->buf_overrun);
2263 * The rest are not supported by this driver. By returning -ENOIOCTLCMD they
2264 * will be passed to the line discipline for it to handle.
2270 case TIOCSERGSTRUCT:
2271 case TIOCSERGETMULTI:
2272 case TIOCSERSETMULTI:
2275 ip2trace (CHANN, ITRC_IOCTL, 12, 0 );
2281 ip2trace (CHANN, ITRC_IOCTL, ITRC_RETURN, 0 );
2286 /******************************************************************************/
2287 /* Function: GetSerialInfo() */
2288 /* Parameters: Pointer to channel structure */
2289 /* Pointer to old termios structure */
2290 /* Returns: Nothing */
2293 /* This is to support the setserial command, and requires processing of the */
2294 /* standard Linux serial structure. */
2295 /******************************************************************************/
2297 get_serial_info ( i2ChanStrPtr pCh, struct serial_struct __user *retinfo )
2299 struct serial_struct tmp;
2301 memset ( &tmp, 0, sizeof(tmp) );
2302 tmp.type = pCh->pMyBord->channelBtypes.bid_value[(pCh->port_index & (IP2_PORTS_PER_BOARD-1))/16];
2303 if (BID_HAS_654(tmp.type)) {
2304 tmp.type = PORT_16650;
2306 tmp.type = PORT_CIRRUS;
2308 tmp.line = pCh->port_index;
2309 tmp.port = pCh->pMyBord->i2eBase;
2310 tmp.irq = ip2config.irq[pCh->port_index/64];
2311 tmp.flags = pCh->flags;
2312 tmp.baud_base = pCh->BaudBase;
2313 tmp.close_delay = pCh->ClosingDelay;
2314 tmp.closing_wait = pCh->ClosingWaitTime;
2315 tmp.custom_divisor = pCh->BaudDivisor;
2316 return copy_to_user(retinfo,&tmp,sizeof(*retinfo));
2319 /******************************************************************************/
2320 /* Function: SetSerialInfo() */
2321 /* Parameters: Pointer to channel structure */
2322 /* Pointer to old termios structure */
2323 /* Returns: Nothing */
2326 /* This function provides support for setserial, which uses the TIOCSSERIAL */
2327 /* ioctl. Not all setserial parameters are relevant. If the user attempts to */
2328 /* change the IRQ, address or type of the port the ioctl fails. */
2329 /******************************************************************************/
2331 set_serial_info( i2ChanStrPtr pCh, struct serial_struct __user *new_info )
2333 struct serial_struct ns;
2334 int old_flags, old_baud_divisor;
2336 if (copy_from_user(&ns, new_info, sizeof (ns)))
2340 * We don't allow setserial to change IRQ, board address, type or baud
2341 * base. Also line nunber as such is meaningless but we use it for our
2342 * array index so it is fixed also.
2344 if ( (ns.irq != ip2config.irq[pCh->port_index])
2345 || ((int) ns.port != ((int) (pCh->pMyBord->i2eBase)))
2346 || (ns.baud_base != pCh->BaudBase)
2347 || (ns.line != pCh->port_index) ) {
2351 old_flags = pCh->flags;
2352 old_baud_divisor = pCh->BaudDivisor;
2354 if ( !capable(CAP_SYS_ADMIN) ) {
2355 if ( ( ns.close_delay != pCh->ClosingDelay ) ||
2356 ( (ns.flags & ~ASYNC_USR_MASK) !=
2357 (pCh->flags & ~ASYNC_USR_MASK) ) ) {
2361 pCh->flags = (pCh->flags & ~ASYNC_USR_MASK) |
2362 (ns.flags & ASYNC_USR_MASK);
2363 pCh->BaudDivisor = ns.custom_divisor;
2365 pCh->flags = (pCh->flags & ~ASYNC_FLAGS) |
2366 (ns.flags & ASYNC_FLAGS);
2367 pCh->BaudDivisor = ns.custom_divisor;
2368 pCh->ClosingDelay = ns.close_delay * HZ/100;
2369 pCh->ClosingWaitTime = ns.closing_wait * HZ/100;
2372 if ( ( (old_flags & ASYNC_SPD_MASK) != (pCh->flags & ASYNC_SPD_MASK) )
2373 || (old_baud_divisor != pCh->BaudDivisor) ) {
2374 // Invalidate speed and reset parameters
2375 set_params( pCh, NULL );
2381 /******************************************************************************/
2382 /* Function: ip2_set_termios() */
2383 /* Parameters: Pointer to tty structure */
2384 /* Pointer to old termios structure */
2385 /* Returns: Nothing */
2390 /******************************************************************************/
2392 ip2_set_termios( PTTY tty, struct ktermios *old_termios )
2394 i2ChanStrPtr pCh = (i2ChanStrPtr)tty->driver_data;
2396 #ifdef IP2DEBUG_IOCTL
2397 printk (KERN_DEBUG "IP2: set termios %p\n", old_termios );
2400 set_params( pCh, old_termios );
2403 /******************************************************************************/
2404 /* Function: ip2_set_line_discipline() */
2405 /* Parameters: Pointer to tty structure */
2406 /* Returns: Nothing */
2408 /* Description: Does nothing */
2411 /******************************************************************************/
2413 ip2_set_line_discipline ( PTTY tty )
2415 #ifdef IP2DEBUG_IOCTL
2416 printk (KERN_DEBUG "IP2: set line discipline\n" );
2419 ip2trace (((i2ChanStrPtr)tty->driver_data)->port_index, ITRC_IOCTL, 16, 0 );
2423 /******************************************************************************/
2424 /* Function: SetLine Characteristics() */
2425 /* Parameters: Pointer to channel structure */
2426 /* Returns: Nothing */
2429 /* This routine is called to update the channel structure with the new line */
2430 /* characteristics, and send the appropriate commands to the board when they */
2432 /******************************************************************************/
2434 set_params( i2ChanStrPtr pCh, struct ktermios *o_tios )
2436 tcflag_t cflag, iflag, lflag;
2437 char stop_char, start_char;
2438 struct ktermios dummy;
2440 lflag = pCh->pTTY->termios->c_lflag;
2441 cflag = pCh->pTTY->termios->c_cflag;
2442 iflag = pCh->pTTY->termios->c_iflag;
2444 if (o_tios == NULL) {
2445 dummy.c_lflag = ~lflag;
2446 dummy.c_cflag = ~cflag;
2447 dummy.c_iflag = ~iflag;
2452 switch ( cflag & CBAUD ) {
2454 i2QueueCommands( PTYPE_BYPASS, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN);
2455 pCh->dataSetOut &= ~(I2_DTR | I2_RTS);
2456 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25));
2457 pCh->pTTY->termios->c_cflag |= (CBAUD & o_tios->c_cflag);
2462 * This is the speed that is overloaded with all the other high
2463 * speeds, depending upon the flag settings.
2465 if ( ( pCh->flags & ASYNC_SPD_MASK ) == ASYNC_SPD_HI ) {
2466 pCh->speed = CBR_57600;
2467 } else if ( (pCh->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI ) {
2468 pCh->speed = CBR_115200;
2469 } else if ( (pCh->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST ) {
2470 pCh->speed = CBR_C1;
2472 pCh->speed = CBR_38400;
2475 case B50: pCh->speed = CBR_50; break;
2476 case B75: pCh->speed = CBR_75; break;
2477 case B110: pCh->speed = CBR_110; break;
2478 case B134: pCh->speed = CBR_134; break;
2479 case B150: pCh->speed = CBR_150; break;
2480 case B200: pCh->speed = CBR_200; break;
2481 case B300: pCh->speed = CBR_300; break;
2482 case B600: pCh->speed = CBR_600; break;
2483 case B1200: pCh->speed = CBR_1200; break;
2484 case B1800: pCh->speed = CBR_1800; break;
2485 case B2400: pCh->speed = CBR_2400; break;
2486 case B4800: pCh->speed = CBR_4800; break;
2487 case B9600: pCh->speed = CBR_9600; break;
2488 case B19200: pCh->speed = CBR_19200; break;
2489 case B57600: pCh->speed = CBR_57600; break;
2490 case B115200: pCh->speed = CBR_115200; break;
2491 case B153600: pCh->speed = CBR_153600; break;
2492 case B230400: pCh->speed = CBR_230400; break;
2493 case B307200: pCh->speed = CBR_307200; break;
2494 case B460800: pCh->speed = CBR_460800; break;
2495 case B921600: pCh->speed = CBR_921600; break;
2496 default: pCh->speed = CBR_9600; break;
2498 if ( pCh->speed == CBR_C1 ) {
2499 // Process the custom speed parameters.
2500 int bps = pCh->BaudBase / pCh->BaudDivisor;
2501 if ( bps == 921600 ) {
2502 pCh->speed = CBR_921600;
2505 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_BAUD_DEF1(bps) );
2508 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_SETBAUD(pCh->speed));
2510 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 2, CMD_DTRUP, CMD_RTSUP);
2511 pCh->dataSetOut |= (I2_DTR | I2_RTS);
2513 if ( (CSTOPB & cflag) ^ (CSTOPB & o_tios->c_cflag))
2515 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1,
2516 CMD_SETSTOP( ( cflag & CSTOPB ) ? CST_2 : CST_1));
2518 if (((PARENB|PARODD) & cflag) ^ ((PARENB|PARODD) & o_tios->c_cflag))
2520 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1,
2522 (cflag & PARENB ? (cflag & PARODD ? CSP_OD : CSP_EV) : CSP_NP)
2526 /* byte size and parity */
2527 if ( (CSIZE & cflag)^(CSIZE & o_tios->c_cflag))
2530 switch ( cflag & CSIZE ) {
2531 case CS5: datasize = CSZ_5; break;
2532 case CS6: datasize = CSZ_6; break;
2533 case CS7: datasize = CSZ_7; break;
2534 case CS8: datasize = CSZ_8; break;
2535 default: datasize = CSZ_5; break; /* as per serial.c */
2537 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1, CMD_SETBITS(datasize) );
2539 /* Process CTS flow control flag setting */
2540 if ( (cflag & CRTSCTS) ) {
2541 i2QueueCommands(PTYPE_INLINE, pCh, 100,
2542 2, CMD_CTSFL_ENAB, CMD_RTSFL_ENAB);
2544 i2QueueCommands(PTYPE_INLINE, pCh, 100,
2545 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB);
2548 // Process XON/XOFF flow control flags settings
2550 stop_char = STOP_CHAR(pCh->pTTY);
2551 start_char = START_CHAR(pCh->pTTY);
2553 //////////// can't be \000
2554 if (stop_char == __DISABLED_CHAR )
2556 stop_char = ~__DISABLED_CHAR;
2558 if (start_char == __DISABLED_CHAR )
2560 start_char = ~__DISABLED_CHAR;
2562 /////////////////////////////////
2564 if ( o_tios->c_cc[VSTART] != start_char )
2566 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DEF_IXON(start_char));
2567 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DEF_OXON(start_char));
2569 if ( o_tios->c_cc[VSTOP] != stop_char )
2571 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DEF_IXOFF(stop_char));
2572 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DEF_OXOFF(stop_char));
2574 if (stop_char == __DISABLED_CHAR )
2576 stop_char = ~__DISABLED_CHAR; //TEST123
2579 if ((iflag & (IXOFF))^(o_tios->c_iflag & (IXOFF)))
2581 if ( iflag & IXOFF ) { // Enable XOFF output flow control
2582 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_OXON_OPT(COX_XON));
2583 } else { // Disable XOFF output flow control
2585 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_OXON_OPT(COX_NONE));
2588 if (start_char == __DISABLED_CHAR )
2592 if ((iflag & (IXON|IXANY)) ^ (o_tios->c_iflag & (IXON|IXANY)))
2594 if ( iflag & IXON ) {
2595 if ( iflag & IXANY ) { // Enable XON/XANY output flow control
2596 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_XANY));
2597 } else { // Enable XON output flow control
2598 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_XON));
2600 } else { // Disable XON output flow control
2602 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_NONE));
2605 if ( (iflag & ISTRIP) ^ ( o_tios->c_iflag & (ISTRIP)) )
2607 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1,
2608 CMD_ISTRIP_OPT((iflag & ISTRIP ? 1 : 0)));
2610 if ( (iflag & INPCK) ^ ( o_tios->c_iflag & (INPCK)) )
2612 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1,
2613 CMD_PARCHK((iflag & INPCK) ? CPK_ENAB : CPK_DSAB));
2616 if ( (iflag & (IGNBRK|PARMRK|BRKINT|IGNPAR))
2617 ^ ( o_tios->c_iflag & (IGNBRK|PARMRK|BRKINT|IGNPAR)) )
2622 if ( iflag & IGNBRK ) { /* Ignore breaks altogether */
2623 /* Ignore breaks altogether */
2624 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_BRK_NREP);
2626 if ( iflag & BRKINT ) {
2627 if ( iflag & PARMRK ) {
2628 brkrpt = 0x0a; // exception an inline triple
2630 brkrpt = 0x1a; // exception and NULL
2632 brkrpt |= 0x04; // flush input
2634 if ( iflag & PARMRK ) {
2635 brkrpt = 0x0b; //POSIX triple \0377 \0 \0
2637 brkrpt = 0x01; // Null only
2640 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_BRK_REP(brkrpt));
2643 if (iflag & IGNPAR) {
2645 /* would be 2 for not cirrus bug */
2646 /* would be 0x20 cept for cirrus bug */
2648 if ( iflag & PARMRK ) {
2650 * Replace error characters with 3-byte sequence (\0377,\0,char)
2653 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_ISTRIP_OPT((char)0));
2658 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_SET_ERROR(parrpt));
2660 if (cflag & CLOCAL) {
2661 // Status reporting fails for DCD if this is off
2662 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DCD_NREP);
2663 pCh->flags &= ~ASYNC_CHECK_CD;
2665 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DCD_REP);
2666 pCh->flags |= ASYNC_CHECK_CD;
2670 i2DrainOutput( pCh, 100 );
2673 /******************************************************************************/
2674 /* IPL Device Section */
2675 /******************************************************************************/
2677 /******************************************************************************/
2678 /* Function: ip2_ipl_read() */
2679 /* Parameters: Pointer to device inode */
2680 /* Pointer to file structure */
2681 /* Pointer to data */
2682 /* Number of bytes to read */
2683 /* Returns: Success or failure */
2685 /* Description: Ugly */
2688 /******************************************************************************/
2692 ip2_ipl_read(struct file *pFile, char __user *pData, size_t count, loff_t *off )
2694 unsigned int minor = iminor(pFile->f_path.dentry->d_inode);
2698 printk (KERN_DEBUG "IP2IPL: read %p, %d bytes\n", pData, count );
2702 case 0: // IPL device
2705 case 1: // Status dump
2708 case 2: // Ping device
2711 case 3: // Trace device
2712 rc = DumpTraceBuffer ( pData, count );
2714 case 4: // Trace device
2715 rc = DumpFifoBuffer ( pData, count );
2725 DumpFifoBuffer ( char __user *pData, int count )
2729 rc = copy_to_user(pData, DBGBuf, count);
2731 printk(KERN_DEBUG "Last index %d\n", I );
2734 #endif /* DEBUG_FIFO */
2739 DumpTraceBuffer ( char __user *pData, int count )
2741 #ifdef IP2DEBUG_TRACE
2745 int *pIndex = (int __user *)pData;
2747 if ( count < (sizeof(int) * 6) ) {
2750 rc = put_user(tracewrap, pIndex );
2751 rc = put_user(TRACEMAX, ++pIndex );
2752 rc = put_user(tracestrip, ++pIndex );
2753 rc = put_user(tracestuff, ++pIndex );
2754 pData += sizeof(int) * 6;
2755 count -= sizeof(int) * 6;
2757 dumpcount = tracestuff - tracestrip;
2758 if ( dumpcount < 0 ) {
2759 dumpcount += TRACEMAX;
2761 if ( dumpcount > count ) {
2764 chunk = TRACEMAX - tracestrip;
2765 if ( dumpcount > chunk ) {
2766 rc = copy_to_user(pData, &tracebuf[tracestrip],
2767 chunk * sizeof(tracebuf[0]) );
2768 pData += chunk * sizeof(tracebuf[0]);
2770 chunk = dumpcount - chunk;
2774 rc = copy_to_user(pData, &tracebuf[tracestrip],
2775 chunk * sizeof(tracebuf[0]) );
2776 tracestrip += chunk;
2779 rc = put_user(tracestrip, ++pIndex );
2780 rc = put_user(tracestuff, ++pIndex );
2788 /******************************************************************************/
2789 /* Function: ip2_ipl_write() */
2791 /* Pointer to file structure */
2792 /* Pointer to data */
2793 /* Number of bytes to write */
2794 /* Returns: Success or failure */
2799 /******************************************************************************/
2801 ip2_ipl_write(struct file *pFile, const char __user *pData, size_t count, loff_t *off)
2804 printk (KERN_DEBUG "IP2IPL: write %p, %d bytes\n", pData, count );
2809 /******************************************************************************/
2810 /* Function: ip2_ipl_ioctl() */
2811 /* Parameters: Pointer to device inode */
2812 /* Pointer to file structure */
2815 /* Returns: Success or failure */
2820 /******************************************************************************/
2822 ip2_ipl_ioctl ( struct inode *pInode, struct file *pFile, UINT cmd, ULONG arg )
2824 unsigned int iplminor = iminor(pInode);
2826 void __user *argp = (void __user *)arg;
2827 ULONG __user *pIndex = argp;
2828 i2eBordStrPtr pB = i2BoardPtrTable[iplminor / 4];
2832 printk (KERN_DEBUG "IP2IPL: ioctl cmd %d, arg %ld\n", cmd, arg );
2835 switch ( iplminor ) {
2836 case 0: // IPL device
2839 case 1: // Status dump
2844 case 64: /* Driver - ip2stat */
2845 rc = put_user(ip2_tty_driver->refcount, pIndex++ );
2846 rc = put_user(irq_counter, pIndex++ );
2847 rc = put_user(bh_counter, pIndex++ );
2850 case 65: /* Board - ip2stat */
2852 rc = copy_to_user(argp, pB, sizeof(i2eBordStr));
2853 rc = put_user(inb(pB->i2eStatus),
2854 (ULONG __user *)(arg + (ULONG)(&pB->i2eStatus) - (ULONG)pB ) );
2861 if (cmd < IP2_MAX_PORTS) {
2862 pCh = DevTable[cmd];
2865 rc = copy_to_user(argp, pCh, sizeof(i2ChanStr));
2875 case 2: // Ping device
2878 case 3: // Trace device
2880 * akpm: This used to write a whole bunch of function addresses
2881 * to userspace, which generated lots of put_user() warnings.
2882 * I killed it all. Just return "success" and don't do
2898 /******************************************************************************/
2899 /* Function: ip2_ipl_open() */
2900 /* Parameters: Pointer to device inode */
2901 /* Pointer to file structure */
2902 /* Returns: Success or failure */
2907 /******************************************************************************/
2909 ip2_ipl_open( struct inode *pInode, struct file *pFile )
2911 unsigned int iplminor = iminor(pInode);
2916 printk (KERN_DEBUG "IP2IPL: open\n" );
2920 // These are the IPL devices
2927 // These are the status devices
2934 // These are the debug devices
2939 pB = i2BoardPtrTable[iplminor / 4];
2940 pCh = (i2ChanStrPtr) pB->i2eChannelPtr;
2943 // This is the trace device
2951 proc_ip2mem_show(struct seq_file *m, void *v)
2958 #define FMTLINE "%3d: 0x%08x 0x%08x 0%011o 0%011o\n"
2959 #define FMTLIN2 " 0x%04x 0x%04x tx flow 0x%x\n"
2960 #define FMTLIN3 " 0x%04x 0x%04x rc flow\n"
2964 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
2965 pB = i2BoardPtrTable[i];
2967 seq_printf(m,"board %d:\n",i);
2968 seq_printf(m,"\tFifo rem: %d mty: %x outM %x\n",
2969 pB->i2eFifoRemains,pB->i2eWaitingForEmptyFifo,pB->i2eOutMailWaiting);
2973 seq_printf(m,"#: tty flags, port flags, cflags, iflags\n");
2974 for (i=0; i < IP2_MAX_PORTS; i++) {
2978 if (tty && tty->count) {
2979 seq_printf(m,FMTLINE,i,(int)tty->flags,pCh->flags,
2980 tty->termios->c_cflag,tty->termios->c_iflag);
2982 seq_printf(m,FMTLIN2,
2983 pCh->outfl.asof,pCh->outfl.room,pCh->channelNeeds);
2984 seq_printf(m,FMTLIN3,pCh->infl.asof,pCh->infl.room);
2991 static int proc_ip2mem_open(struct inode *inode, struct file *file)
2993 return single_open(file, proc_ip2mem_show, NULL);
2996 static const struct file_operations ip2mem_proc_fops = {
2997 .owner = THIS_MODULE,
2998 .open = proc_ip2mem_open,
3000 .llseek = seq_lseek,
3001 .release = single_release,
3005 * This is the handler for /proc/tty/driver/ip2
3007 * This stretch of code has been largely plagerized from at least three
3008 * different sources including ip2mkdev.c and a couple of other drivers.
3009 * The bugs are all mine. :-) =mhw=
3011 static int ip2_read_proc(char *page, char **start, off_t off,
3012 int count, int *eof, void *data)
3022 len += sprintf(page, "ip2info: 1.0 driver: %s\n", pcVersion );
3023 len += sprintf(page+len, "Driver: SMajor=%d CMajor=%d IMajor=%d MaxBoards=%d MaxBoxes=%d MaxPorts=%d\n",
3024 IP2_TTY_MAJOR, IP2_CALLOUT_MAJOR, IP2_IPL_MAJOR,
3025 IP2_MAX_BOARDS, ABS_MAX_BOXES, ABS_BIGGEST_BOX);
3027 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
3028 /* This need to be reset for a board by board count... */
3030 pB = i2BoardPtrTable[i];
3032 switch( pB->i2ePom.e.porID & ~POR_ID_RESERVED )
3035 len += sprintf( page+len, "Board %d: EX ports=", i );
3036 for( box = 0; box < ABS_MAX_BOXES; ++box )
3040 if( pB->i2eChannelMap[box] != 0 ) ++boxes;
3041 for( j = 0; j < ABS_BIGGEST_BOX; ++j )
3043 if( pB->i2eChannelMap[box] & 1<< j ) {
3047 len += sprintf( page+len, "%d,", ports );
3051 --len; /* Backup over that last comma */
3053 len += sprintf( page+len, " boxes=%d width=%d", boxes, pB->i2eDataWidth16 ? 16 : 8 );
3057 len += sprintf(page+len, "Board %d: ISA-4 ports=4 boxes=1", i );
3062 len += sprintf(page+len, "Board %d: ISA-8-std ports=8 boxes=1", i );
3067 len += sprintf(page+len, "Board %d: ISA-8-RJ11 ports=8 boxes=1", i );
3072 len += sprintf(page+len, "Board %d: unknown", i );
3073 /* Don't try and probe for minor numbers */
3078 /* Don't try and probe for minor numbers */
3079 len += sprintf(page+len, "Board %d: vacant", i );
3084 len += sprintf(page+len, " minors=" );
3086 for ( box = 0; box < ABS_MAX_BOXES; ++box )
3088 for ( j = 0; j < ABS_BIGGEST_BOX; ++j )
3090 if ( pB->i2eChannelMap[box] & (1 << j) )
3092 len += sprintf (page+len,"%d,",
3093 j + ABS_BIGGEST_BOX *
3094 (box+i*ABS_MAX_BOXES));
3099 page[ len - 1 ] = '\n'; /* Overwrite that last comma */
3101 len += sprintf (page+len,"\n" );
3104 if (len+begin > off+count)
3106 if (len+begin < off) {
3112 if (i >= IP2_MAX_BOARDS)
3114 if (off >= len+begin)
3117 *start = page + (off-begin);
3118 return ((count < begin+len-off) ? count : begin+len-off);
3121 /******************************************************************************/
3122 /* Function: ip2trace() */
3123 /* Parameters: Value to add to trace buffer */
3124 /* Returns: Nothing */
3129 /******************************************************************************/
3130 #ifdef IP2DEBUG_TRACE
3132 ip2trace (unsigned short pn, unsigned char cat, unsigned char label, unsigned long codes, ...)
3135 unsigned long *pCode = &codes;
3136 union ip2breadcrumb bc;
3140 tracebuf[tracestuff++] = jiffies;
3141 if ( tracestuff == TRACEMAX ) {
3144 if ( tracestuff == tracestrip ) {
3145 if ( ++tracestrip == TRACEMAX ) {
3151 bc.hdr.port = 0xff & pn;
3153 bc.hdr.codes = (unsigned char)( codes & 0xff );
3154 bc.hdr.label = label;
3155 tracebuf[tracestuff++] = bc.value;
3158 if ( tracestuff == TRACEMAX ) {
3161 if ( tracestuff == tracestrip ) {
3162 if ( ++tracestrip == TRACEMAX ) {
3171 tracebuf[tracestuff++] = *++pCode;
3177 MODULE_LICENSE("GPL");
3179 static struct pci_device_id ip2main_pci_tbl[] __devinitdata = {
3180 { PCI_DEVICE(PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_IP2EX) },
3184 MODULE_DEVICE_TABLE(pci, ip2main_pci_tbl);