Automatic merge of rsync://rsync.kernel.org/pub/scm/linux/kernel/git/gregkh/driver...
[linux-2.6/verdex.git] / drivers / char / ip2main.c
blobfca9a978fb73fc2662daea26caa6f0744e0a5764
1 /*
3 * (c) 1999 by Computone Corporation
5 ********************************************************************************
7 * PACKAGE: Linux tty Device Driver for IntelliPort family of multiport
8 * serial I/O controllers.
10 * DESCRIPTION: Mainline code for the device driver
12 *******************************************************************************/
13 // ToDo:
15 // Fix the immediate DSS_NOW problem.
16 // Work over the channel stats return logic in ip2_ipl_ioctl so they
17 // make sense for all 256 possible channels and so the user space
18 // utilities will compile and work properly.
20 // Done:
22 // 1.2.14 /\/\|=mhw=|\/\/
23 // Added bounds checking to ip2_ipl_ioctl to avoid potential terroristic acts.
24 // Changed the definition of ip2trace to be more consistent with kernel style
25 // Thanks to Andreas Dilger <adilger@turbolabs.com> for these updates
27 // 1.2.13 /\/\|=mhw=|\/\/
28 // DEVFS: Renamed ttf/{n} to tts/F{n} and cuf/{n} to cua/F{n} to conform
29 // to agreed devfs serial device naming convention.
31 // 1.2.12 /\/\|=mhw=|\/\/
32 // Cleaned up some remove queue cut and paste errors
34 // 1.2.11 /\/\|=mhw=|\/\/
35 // Clean up potential NULL pointer dereferences
36 // Clean up devfs registration
37 // Add kernel command line parsing for io and irq
38 // Compile defaults for io and irq are now set in ip2.c not ip2/ip2.h!
39 // Reworked poll_only hack for explicit parameter setting
40 // You must now EXPLICITLY set poll_only = 1 or set all irqs to 0
41 // Merged ip2_loadmain and old_ip2_init
42 // Converted all instances of interruptible_sleep_on into queue calls
43 // Most of these had no race conditions but better to clean up now
45 // 1.2.10 /\/\|=mhw=|\/\/
46 // Fixed the bottom half interrupt handler and enabled USE_IQI
47 // to split the interrupt handler into a formal top-half / bottom-half
48 // Fixed timing window on high speed processors that queued messages to
49 // the outbound mail fifo faster than the board could handle.
51 // 1.2.9
52 // Four box EX was barfing on >128k kmalloc, made structure smaller by
53 // reducing output buffer size
55 // 1.2.8
56 // Device file system support (MHW)
58 // 1.2.7
59 // Fixed
60 // Reload of ip2 without unloading ip2main hangs system on cat of /proc/modules
62 // 1.2.6
63 //Fixes DCD problems
64 // DCD was not reported when CLOCAL was set on call to TIOCMGET
66 //Enhancements:
67 // TIOCMGET requests and waits for status return
68 // No DSS interrupts enabled except for DCD when needed
70 // For internal use only
72 //#define IP2DEBUG_INIT
73 //#define IP2DEBUG_OPEN
74 //#define IP2DEBUG_WRITE
75 //#define IP2DEBUG_READ
76 //#define IP2DEBUG_IOCTL
77 //#define IP2DEBUG_IPL
79 //#define IP2DEBUG_TRACE
80 //#define DEBUG_FIFO
82 /************/
83 /* Includes */
84 /************/
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>
98 #include <linux/mm.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>
118 #include <asm/io.h>
119 #include <asm/irq.h>
121 #include <linux/vmalloc.h>
122 #include <linux/init.h>
123 #include <asm/serial.h>
125 #include <asm/uaccess.h>
127 #include "./ip2/ip2types.h"
128 #include "./ip2/ip2trace.h"
129 #include "./ip2/ip2ioctl.h"
130 #include "./ip2/ip2.h"
131 #include "./ip2/i2ellis.h"
132 #include "./ip2/i2lib.h"
134 /*****************
135 * /proc/ip2mem *
136 *****************/
138 #include <linux/proc_fs.h>
140 static int ip2_read_procmem(char *, char **, off_t, int);
141 static int ip2_read_proc(char *, char **, off_t, int, int *, void * );
143 /********************/
144 /* Type Definitions */
145 /********************/
147 /*************/
148 /* Constants */
149 /*************/
151 /* String constants to identify ourselves */
152 static char *pcName = "Computone IntelliPort Plus multiport driver";
153 static char *pcVersion = "1.2.14";
155 /* String constants for port names */
156 static char *pcDriver_name = "ip2";
157 static char *pcIpl = "ip2ipl";
159 /* Serial subtype definitions */
160 #define SERIAL_TYPE_NORMAL 1
162 // cheezy kludge or genius - you decide?
163 int ip2_loadmain(int *, int *, unsigned char *, int);
164 static unsigned char *Fip_firmware;
165 static int Fip_firmware_size;
167 /***********************/
168 /* Function Prototypes */
169 /***********************/
171 /* Global module entry functions */
173 /* Private (static) functions */
174 static int ip2_open(PTTY, struct file *);
175 static void ip2_close(PTTY, struct file *);
176 static int ip2_write(PTTY, int, const unsigned char *, int);
177 static void ip2_putchar(PTTY, unsigned char);
178 static void ip2_flush_chars(PTTY);
179 static int ip2_write_room(PTTY);
180 static int ip2_chars_in_buf(PTTY);
181 static void ip2_flush_buffer(PTTY);
182 static int ip2_ioctl(PTTY, struct file *, UINT, ULONG);
183 static void ip2_set_termios(PTTY, struct termios *);
184 static void ip2_set_line_discipline(PTTY);
185 static void ip2_throttle(PTTY);
186 static void ip2_unthrottle(PTTY);
187 static void ip2_stop(PTTY);
188 static void ip2_start(PTTY);
189 static void ip2_hangup(PTTY);
190 static int ip2_tiocmget(struct tty_struct *tty, struct file *file);
191 static int ip2_tiocmset(struct tty_struct *tty, struct file *file,
192 unsigned int set, unsigned int clear);
194 static void set_irq(int, int);
195 static void ip2_interrupt_bh(i2eBordStrPtr pB);
196 static irqreturn_t ip2_interrupt(int irq, void *dev_id, struct pt_regs * regs);
197 static void ip2_poll(unsigned long arg);
198 static inline void service_all_boards(void);
199 static void do_input(void *p);
200 static void do_status(void *p);
202 static void ip2_wait_until_sent(PTTY,int);
204 static void set_params (i2ChanStrPtr, struct termios *);
205 static int get_serial_info(i2ChanStrPtr, struct serial_struct __user *);
206 static int set_serial_info(i2ChanStrPtr, struct serial_struct __user *);
208 static ssize_t ip2_ipl_read(struct file *, char __user *, size_t, loff_t *);
209 static ssize_t ip2_ipl_write(struct file *, const char __user *, size_t, loff_t *);
210 static int ip2_ipl_ioctl(struct inode *, struct file *, UINT, ULONG);
211 static int ip2_ipl_open(struct inode *, struct file *);
213 static int DumpTraceBuffer(char __user *, int);
214 static int DumpFifoBuffer( char __user *, int);
216 static void ip2_init_board(int);
217 static unsigned short find_eisa_board(int);
219 /***************/
220 /* Static Data */
221 /***************/
223 static struct tty_driver *ip2_tty_driver;
225 /* Here, then is a table of board pointers which the interrupt routine should
226 * scan through to determine who it must service.
228 static unsigned short i2nBoards; // Number of boards here
230 static i2eBordStrPtr i2BoardPtrTable[IP2_MAX_BOARDS];
232 static i2ChanStrPtr DevTable[IP2_MAX_PORTS];
233 //DevTableMem just used to save addresses for kfree
234 static void *DevTableMem[IP2_MAX_BOARDS];
236 /* This is the driver descriptor for the ip2ipl device, which is used to
237 * download the loadware to the boards.
239 static struct file_operations ip2_ipl = {
240 .owner = THIS_MODULE,
241 .read = ip2_ipl_read,
242 .write = ip2_ipl_write,
243 .ioctl = ip2_ipl_ioctl,
244 .open = ip2_ipl_open,
247 static unsigned long irq_counter = 0;
248 static unsigned long bh_counter = 0;
250 // Use immediate queue to service interrupts
251 #define USE_IQI
252 //#define USE_IQ // PCI&2.2 needs work
254 /* The timer_list entry for our poll routine. If interrupt operation is not
255 * selected, the board is serviced periodically to see if anything needs doing.
257 #define POLL_TIMEOUT (jiffies + 1)
258 static struct timer_list PollTimer = TIMER_INITIALIZER(ip2_poll, 0, 0);
259 static char TimerOn;
261 #ifdef IP2DEBUG_TRACE
262 /* Trace (debug) buffer data */
263 #define TRACEMAX 1000
264 static unsigned long tracebuf[TRACEMAX];
265 static int tracestuff;
266 static int tracestrip;
267 static int tracewrap;
268 #endif
270 /**********/
271 /* Macros */
272 /**********/
274 #if defined(MODULE) && defined(IP2DEBUG_OPEN)
275 #define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] refc=%d, ttyc=%d, modc=%x -> %s\n", \
276 tty->name,(pCh->flags),ip2_tty_driver->refcount, \
277 tty->count,/*GET_USE_COUNT(module)*/0,s)
278 #else
279 #define DBG_CNT(s)
280 #endif
282 /********/
283 /* Code */
284 /********/
286 #include "./ip2/i2ellis.c" /* Extremely low-level interface services */
287 #include "./ip2/i2cmd.c" /* Standard loadware command definitions */
288 #include "./ip2/i2lib.c" /* High level interface services */
290 /* Configuration area for modprobe */
292 MODULE_AUTHOR("Doug McNash");
293 MODULE_DESCRIPTION("Computone IntelliPort Plus Driver");
295 static int poll_only = 0;
297 static int Eisa_irq;
298 static int Eisa_slot;
300 static int iindx;
301 static char rirqs[IP2_MAX_BOARDS];
302 static int Valid_Irqs[] = { 3, 4, 5, 7, 10, 11, 12, 15, 0};
304 /* for sysfs class support */
305 static struct class_simple *ip2_class;
307 // Some functions to keep track of what irq's we have
309 static int __init
310 is_valid_irq(int irq)
312 int *i = Valid_Irqs;
314 while ((*i != 0) && (*i != irq)) {
315 i++;
317 return (*i);
320 static void __init
321 mark_requested_irq( char irq )
323 rirqs[iindx++] = irq;
326 #ifdef MODULE
327 static int __init
328 clear_requested_irq( char irq )
330 int i;
331 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
332 if (rirqs[i] == irq) {
333 rirqs[i] = 0;
334 return 1;
337 return 0;
339 #endif
341 static int __init
342 have_requested_irq( char irq )
344 // array init to zeros so 0 irq will not be requested as a side effect
345 int i;
346 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
347 if (rirqs[i] == irq)
348 return 1;
350 return 0;
353 /******************************************************************************/
354 /* Function: init_module() */
355 /* Parameters: None */
356 /* Returns: Success (0) */
357 /* */
358 /* Description: */
359 /* This is a required entry point for an installable module. It simply calls */
360 /* the driver initialisation function and returns what it returns. */
361 /******************************************************************************/
362 #ifdef MODULE
364 init_module(void)
366 #ifdef IP2DEBUG_INIT
367 printk (KERN_DEBUG "Loading module ...\n" );
368 #endif
369 return 0;
371 #endif /* MODULE */
373 /******************************************************************************/
374 /* Function: cleanup_module() */
375 /* Parameters: None */
376 /* Returns: Nothing */
377 /* */
378 /* Description: */
379 /* This is a required entry point for an installable module. It has to return */
380 /* the device and the driver to a passive state. It should not be necessary */
381 /* to reset the board fully, especially as the loadware is downloaded */
382 /* externally rather than in the driver. We just want to disable the board */
383 /* and clear the loadware to a reset state. To allow this there has to be a */
384 /* way to detect whether the board has the loadware running at init time to */
385 /* handle subsequent installations of the driver. All memory allocated by the */
386 /* driver should be returned since it may be unloaded from memory. */
387 /******************************************************************************/
388 #ifdef MODULE
389 void
390 cleanup_module(void)
392 int err;
393 int i;
395 #ifdef IP2DEBUG_INIT
396 printk (KERN_DEBUG "Unloading %s: version %s\n", pcName, pcVersion );
397 #endif
398 /* Stop poll timer if we had one. */
399 if ( TimerOn ) {
400 del_timer ( &PollTimer );
401 TimerOn = 0;
404 /* Reset the boards we have. */
405 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
406 if ( i2BoardPtrTable[i] ) {
407 iiReset( i2BoardPtrTable[i] );
411 /* The following is done at most once, if any boards were installed. */
412 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
413 if ( i2BoardPtrTable[i] ) {
414 iiResetDelay( i2BoardPtrTable[i] );
415 /* free io addresses and Tibet */
416 release_region( ip2config.addr[i], 8 );
417 class_simple_device_remove(MKDEV(IP2_IPL_MAJOR, 4 * i));
418 devfs_remove("ip2/ipl%d", i);
419 class_simple_device_remove(MKDEV(IP2_IPL_MAJOR, 4 * i + 1));
420 devfs_remove("ip2/stat%d", i);
422 /* Disable and remove interrupt handler. */
423 if ( (ip2config.irq[i] > 0) && have_requested_irq(ip2config.irq[i]) ) {
424 free_irq ( ip2config.irq[i], (void *)&pcName);
425 clear_requested_irq( ip2config.irq[i]);
428 class_simple_destroy(ip2_class);
429 devfs_remove("ip2");
430 if ( ( err = tty_unregister_driver ( ip2_tty_driver ) ) ) {
431 printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n", err);
433 put_tty_driver(ip2_tty_driver);
434 if ( ( err = unregister_chrdev ( IP2_IPL_MAJOR, pcIpl ) ) ) {
435 printk(KERN_ERR "IP2: failed to unregister IPL driver (%d)\n", err);
437 remove_proc_entry("ip2mem", &proc_root);
439 // free memory
440 for (i = 0; i < IP2_MAX_BOARDS; i++) {
441 void *pB;
442 #ifdef CONFIG_PCI
443 if (ip2config.type[i] == PCI && ip2config.pci_dev[i]) {
444 pci_disable_device(ip2config.pci_dev[i]);
445 ip2config.pci_dev[i] = NULL;
447 #endif
448 if ((pB = i2BoardPtrTable[i]) != 0 ) {
449 kfree ( pB );
450 i2BoardPtrTable[i] = NULL;
452 if ((DevTableMem[i]) != NULL ) {
453 kfree ( DevTableMem[i] );
454 DevTableMem[i] = NULL;
458 /* Cleanup the iiEllis subsystem. */
459 iiEllisCleanup();
460 #ifdef IP2DEBUG_INIT
461 printk (KERN_DEBUG "IP2 Unloaded\n" );
462 #endif
464 #endif /* MODULE */
466 static struct tty_operations ip2_ops = {
467 .open = ip2_open,
468 .close = ip2_close,
469 .write = ip2_write,
470 .put_char = ip2_putchar,
471 .flush_chars = ip2_flush_chars,
472 .write_room = ip2_write_room,
473 .chars_in_buffer = ip2_chars_in_buf,
474 .flush_buffer = ip2_flush_buffer,
475 .ioctl = ip2_ioctl,
476 .throttle = ip2_throttle,
477 .unthrottle = ip2_unthrottle,
478 .set_termios = ip2_set_termios,
479 .set_ldisc = ip2_set_line_discipline,
480 .stop = ip2_stop,
481 .start = ip2_start,
482 .hangup = ip2_hangup,
483 .read_proc = ip2_read_proc,
484 .tiocmget = ip2_tiocmget,
485 .tiocmset = ip2_tiocmset,
488 /******************************************************************************/
489 /* Function: ip2_loadmain() */
490 /* Parameters: irq, io from command line of insmod et. al. */
491 /* pointer to fip firmware and firmware size for boards */
492 /* Returns: Success (0) */
493 /* */
494 /* Description: */
495 /* This was the required entry point for all drivers (now in ip2.c) */
496 /* It performs all */
497 /* initialisation of the devices and driver structures, and registers itself */
498 /* with the relevant kernel modules. */
499 /******************************************************************************/
500 /* SA_INTERRUPT- if set blocks all interrupts else only this line */
501 /* SA_SHIRQ - for shared irq PCI or maybe EISA only */
502 /* SA_RANDOM - can be source for cert. random number generators */
503 #define IP2_SA_FLAGS 0
506 ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize)
508 int i, j, box;
509 int err = 0;
510 int status = 0;
511 static int loaded;
512 i2eBordStrPtr pB = NULL;
513 int rc = -1;
515 ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0 );
517 /* process command line arguments to modprobe or
518 insmod i.e. iop & irqp */
519 /* irqp and iop should ALWAYS be specified now... But we check
520 them individually just to be sure, anyways... */
521 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
522 if (iop) {
523 ip2config.addr[i] = iop[i];
524 if (irqp) {
525 if( irqp[i] >= 0 ) {
526 ip2config.irq[i] = irqp[i];
527 } else {
528 ip2config.irq[i] = 0;
530 // This is a little bit of a hack. If poll_only=1 on command
531 // line back in ip2.c OR all IRQs on all specified boards are
532 // explicitly set to 0, then drop to poll only mode and override
533 // PCI or EISA interrupts. This superceeds the old hack of
534 // triggering if all interrupts were zero (like da default).
535 // Still a hack but less prone to random acts of terrorism.
537 // What we really should do, now that the IRQ default is set
538 // to -1, is to use 0 as a hard coded, do not probe.
540 // /\/\|=mhw=|\/\/
541 poll_only |= irqp[i];
545 poll_only = !poll_only;
547 Fip_firmware = firmware;
548 Fip_firmware_size = firmsize;
550 /* Announce our presence */
551 printk( KERN_INFO "%s version %s\n", pcName, pcVersion );
553 // ip2 can be unloaded and reloaded for no good reason
554 // we can't let that happen here or bad things happen
555 // second load hoses board but not system - fixme later
556 if (loaded) {
557 printk( KERN_INFO "Still loaded\n" );
558 return 0;
560 loaded++;
562 ip2_tty_driver = alloc_tty_driver(IP2_MAX_PORTS);
563 if (!ip2_tty_driver)
564 return -ENOMEM;
566 /* Initialise the iiEllis subsystem. */
567 iiEllisInit();
569 /* Initialize arrays. */
570 memset( i2BoardPtrTable, 0, sizeof i2BoardPtrTable );
571 memset( DevTable, 0, sizeof DevTable );
573 /* Initialise all the boards we can find (up to the maximum). */
574 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
575 switch ( ip2config.addr[i] ) {
576 case 0: /* skip this slot even if card is present */
577 break;
578 default: /* ISA */
579 /* ISA address must be specified */
580 if ( (ip2config.addr[i] < 0x100) || (ip2config.addr[i] > 0x3f8) ) {
581 printk ( KERN_ERR "IP2: Bad ISA board %d address %x\n",
582 i, ip2config.addr[i] );
583 ip2config.addr[i] = 0;
584 } else {
585 ip2config.type[i] = ISA;
587 /* Check for valid irq argument, set for polling if invalid */
588 if (ip2config.irq[i] && !is_valid_irq(ip2config.irq[i])) {
589 printk(KERN_ERR "IP2: Bad IRQ(%d) specified\n",ip2config.irq[i]);
590 ip2config.irq[i] = 0;// 0 is polling and is valid in that sense
593 break;
594 case PCI:
595 #ifdef CONFIG_PCI
597 struct pci_dev *pci_dev_i = NULL;
598 pci_dev_i = pci_find_device(PCI_VENDOR_ID_COMPUTONE,
599 PCI_DEVICE_ID_COMPUTONE_IP2EX, pci_dev_i);
600 if (pci_dev_i != NULL) {
601 unsigned int addr;
603 if (pci_enable_device(pci_dev_i)) {
604 printk( KERN_ERR "IP2: can't enable PCI device at %s\n",
605 pci_name(pci_dev_i));
606 break;
608 ip2config.type[i] = PCI;
609 ip2config.pci_dev[i] = pci_dev_i;
610 status =
611 pci_read_config_dword(pci_dev_i, PCI_BASE_ADDRESS_1, &addr);
612 if ( addr & 1 ) {
613 ip2config.addr[i]=(USHORT)(addr&0xfffe);
614 } else {
615 printk( KERN_ERR "IP2: PCI I/O address error\n");
618 // If the PCI BIOS assigned it, lets try and use it. If we
619 // can't acquire it or it screws up, deal with it then.
621 // if (!is_valid_irq(pci_irq)) {
622 // printk( KERN_ERR "IP2: Bad PCI BIOS IRQ(%d)\n",pci_irq);
623 // pci_irq = 0;
624 // }
625 ip2config.irq[i] = pci_dev_i->irq;
626 } else { // ann error
627 ip2config.addr[i] = 0;
628 if (status == PCIBIOS_DEVICE_NOT_FOUND) {
629 printk( KERN_ERR "IP2: PCI board %d not found\n", i );
630 } else {
631 printk( KERN_ERR "IP2: PCI error 0x%x \n", status );
635 #else
636 printk( KERN_ERR "IP2: PCI card specified but PCI support not\n");
637 printk( KERN_ERR "IP2: configured in this kernel.\n");
638 printk( KERN_ERR "IP2: Recompile kernel with CONFIG_PCI defined!\n");
639 #endif /* CONFIG_PCI */
640 break;
641 case EISA:
642 if ( (ip2config.addr[i] = find_eisa_board( Eisa_slot + 1 )) != 0) {
643 /* Eisa_irq set as side effect, boo */
644 ip2config.type[i] = EISA;
646 ip2config.irq[i] = Eisa_irq;
647 break;
648 } /* switch */
649 } /* for */
650 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
651 if ( ip2config.addr[i] ) {
652 pB = kmalloc( sizeof(i2eBordStr), GFP_KERNEL);
653 if ( pB != NULL ) {
654 i2BoardPtrTable[i] = pB;
655 memset( pB, 0, sizeof(i2eBordStr) );
656 iiSetAddress( pB, ip2config.addr[i], ii2DelayTimer );
657 iiReset( pB );
658 } else {
659 printk(KERN_ERR "IP2: board memory allocation error\n");
663 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
664 if ( ( pB = i2BoardPtrTable[i] ) != NULL ) {
665 iiResetDelay( pB );
666 break;
669 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
670 if ( i2BoardPtrTable[i] != NULL ) {
671 ip2_init_board( i );
675 ip2trace (ITRC_NO_PORT, ITRC_INIT, 2, 0 );
677 ip2_tty_driver->owner = THIS_MODULE;
678 ip2_tty_driver->name = "ttyF";
679 ip2_tty_driver->devfs_name = "tts/F";
680 ip2_tty_driver->driver_name = pcDriver_name;
681 ip2_tty_driver->major = IP2_TTY_MAJOR;
682 ip2_tty_driver->minor_start = 0;
683 ip2_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
684 ip2_tty_driver->subtype = SERIAL_TYPE_NORMAL;
685 ip2_tty_driver->init_termios = tty_std_termios;
686 ip2_tty_driver->init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL;
687 ip2_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
688 tty_set_operations(ip2_tty_driver, &ip2_ops);
690 ip2trace (ITRC_NO_PORT, ITRC_INIT, 3, 0 );
692 /* Register the tty devices. */
693 if ( ( err = tty_register_driver ( ip2_tty_driver ) ) ) {
694 printk(KERN_ERR "IP2: failed to register tty driver (%d)\n", err);
695 put_tty_driver(ip2_tty_driver);
696 return -EINVAL;
697 } else
698 /* Register the IPL driver. */
699 if ( ( err = register_chrdev ( IP2_IPL_MAJOR, pcIpl, &ip2_ipl ) ) ) {
700 printk(KERN_ERR "IP2: failed to register IPL device (%d)\n", err );
701 } else {
702 /* create the sysfs class */
703 ip2_class = class_simple_create(THIS_MODULE, "ip2");
704 if (IS_ERR(ip2_class)) {
705 err = PTR_ERR(ip2_class);
706 goto out_chrdev;
709 /* Register the read_procmem thing */
710 if (!create_proc_info_entry("ip2mem",0,&proc_root,ip2_read_procmem)) {
711 printk(KERN_ERR "IP2: failed to register read_procmem\n");
712 } else {
714 ip2trace (ITRC_NO_PORT, ITRC_INIT, 4, 0 );
715 /* Register the interrupt handler or poll handler, depending upon the
716 * specified interrupt.
719 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
720 if ( 0 == ip2config.addr[i] ) {
721 continue;
724 if ( NULL != ( pB = i2BoardPtrTable[i] ) ) {
725 class_simple_device_add(ip2_class, MKDEV(IP2_IPL_MAJOR,
726 4 * i), NULL, "ipl%d", i);
727 err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i),
728 S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR,
729 "ip2/ipl%d", i);
730 if (err) {
731 class_simple_device_remove(MKDEV(IP2_IPL_MAJOR,
732 4 * i));
733 goto out_class;
736 class_simple_device_add(ip2_class, MKDEV(IP2_IPL_MAJOR,
737 4 * i + 1), NULL, "stat%d", i);
738 err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
739 S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR,
740 "ip2/stat%d", i);
741 if (err) {
742 class_simple_device_remove(MKDEV(IP2_IPL_MAJOR,
743 4 * i + 1));
744 goto out_class;
747 for ( box = 0; box < ABS_MAX_BOXES; ++box )
749 for ( j = 0; j < ABS_BIGGEST_BOX; ++j )
751 if ( pB->i2eChannelMap[box] & (1 << j) )
753 tty_register_device(ip2_tty_driver,
754 j + ABS_BIGGEST_BOX *
755 (box+i*ABS_MAX_BOXES), NULL);
761 if (poll_only) {
762 // Poll only forces driver to only use polling and
763 // to ignore the probed PCI or EISA interrupts.
764 ip2config.irq[i] = CIR_POLL;
766 if ( ip2config.irq[i] == CIR_POLL ) {
767 retry:
768 if (!TimerOn) {
769 PollTimer.expires = POLL_TIMEOUT;
770 add_timer ( &PollTimer );
771 TimerOn = 1;
772 printk( KERN_INFO "IP2: polling\n");
774 } else {
775 if (have_requested_irq(ip2config.irq[i]))
776 continue;
777 rc = request_irq( ip2config.irq[i], ip2_interrupt,
778 IP2_SA_FLAGS | (ip2config.type[i] == PCI ? SA_SHIRQ : 0),
779 pcName, (void *)&pcName);
780 if (rc) {
781 printk(KERN_ERR "IP2: an request_irq failed: error %d\n",rc);
782 ip2config.irq[i] = CIR_POLL;
783 printk( KERN_INFO "IP2: Polling %ld/sec.\n",
784 (POLL_TIMEOUT - jiffies));
785 goto retry;
787 mark_requested_irq(ip2config.irq[i]);
788 /* Initialise the interrupt handler bottom half (aka slih). */
791 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
792 if ( i2BoardPtrTable[i] ) {
793 set_irq( i, ip2config.irq[i] ); /* set and enable board interrupt */
797 ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_RETURN, 0 );
798 goto out;
800 out_class:
801 class_simple_destroy(ip2_class);
802 out_chrdev:
803 unregister_chrdev(IP2_IPL_MAJOR, "ip2");
804 out:
805 return err;
808 EXPORT_SYMBOL(ip2_loadmain);
810 /******************************************************************************/
811 /* Function: ip2_init_board() */
812 /* Parameters: Index of board in configuration structure */
813 /* Returns: Success (0) */
814 /* */
815 /* Description: */
816 /* This function initializes the specified board. The loadware is copied to */
817 /* the board, the channel structures are initialized, and the board details */
818 /* are reported on the console. */
819 /******************************************************************************/
820 static void __init
821 ip2_init_board( int boardnum )
823 int i;
824 int nports = 0, nboxes = 0;
825 i2ChanStrPtr pCh;
826 i2eBordStrPtr pB = i2BoardPtrTable[boardnum];
828 if ( !iiInitialize ( pB ) ) {
829 printk ( KERN_ERR "IP2: Failed to initialize board at 0x%x, error %d\n",
830 pB->i2eBase, pB->i2eError );
831 goto err_initialize;
833 printk(KERN_INFO "IP2: Board %d: addr=0x%x irq=%d\n", boardnum + 1,
834 ip2config.addr[boardnum], ip2config.irq[boardnum] );
836 if (!request_region( ip2config.addr[boardnum], 8, pcName )) {
837 printk(KERN_ERR "IP2: bad addr=0x%x\n", ip2config.addr[boardnum]);
838 goto err_initialize;
841 if ( iiDownloadAll ( pB, (loadHdrStrPtr)Fip_firmware, 1, Fip_firmware_size )
842 != II_DOWN_GOOD ) {
843 printk ( KERN_ERR "IP2: failed to download loadware\n" );
844 goto err_release_region;
845 } else {
846 printk ( KERN_INFO "IP2: fv=%d.%d.%d lv=%d.%d.%d\n",
847 pB->i2ePom.e.porVersion,
848 pB->i2ePom.e.porRevision,
849 pB->i2ePom.e.porSubRev, pB->i2eLVersion,
850 pB->i2eLRevision, pB->i2eLSub );
853 switch ( pB->i2ePom.e.porID & ~POR_ID_RESERVED ) {
855 default:
856 printk( KERN_ERR "IP2: Unknown board type, ID = %x\n",
857 pB->i2ePom.e.porID );
858 nports = 0;
859 goto err_release_region;
860 break;
862 case POR_ID_II_4: /* IntelliPort-II, ISA-4 (4xRJ45) */
863 printk ( KERN_INFO "IP2: ISA-4\n" );
864 nports = 4;
865 break;
867 case POR_ID_II_8: /* IntelliPort-II, 8-port using standard brick. */
868 printk ( KERN_INFO "IP2: ISA-8 std\n" );
869 nports = 8;
870 break;
872 case POR_ID_II_8R: /* IntelliPort-II, 8-port using RJ11's (no CTS) */
873 printk ( KERN_INFO "IP2: ISA-8 RJ11\n" );
874 nports = 8;
875 break;
877 case POR_ID_FIIEX: /* IntelliPort IIEX */
879 int portnum = IP2_PORTS_PER_BOARD * boardnum;
880 int box;
882 for( box = 0; box < ABS_MAX_BOXES; ++box ) {
883 if ( pB->i2eChannelMap[box] != 0 ) {
884 ++nboxes;
886 for( i = 0; i < ABS_BIGGEST_BOX; ++i ) {
887 if ( pB->i2eChannelMap[box] & 1<< i ) {
888 ++nports;
892 DevTableMem[boardnum] = pCh =
893 kmalloc( sizeof(i2ChanStr) * nports, GFP_KERNEL );
894 if ( !pCh ) {
895 printk ( KERN_ERR "IP2: (i2_init_channel:) Out of memory.\n");
896 goto err_release_region;
898 if ( !i2InitChannels( pB, nports, pCh ) ) {
899 printk(KERN_ERR "IP2: i2InitChannels failed: %d\n",pB->i2eError);
900 kfree ( pCh );
901 goto err_release_region;
903 pB->i2eChannelPtr = &DevTable[portnum];
904 pB->i2eChannelCnt = ABS_MOST_PORTS;
906 for( box = 0; box < ABS_MAX_BOXES; ++box, portnum += ABS_BIGGEST_BOX ) {
907 for( i = 0; i < ABS_BIGGEST_BOX; ++i ) {
908 if ( pB->i2eChannelMap[box] & (1 << i) ) {
909 DevTable[portnum + i] = pCh;
910 pCh->port_index = portnum + i;
911 pCh++;
915 printk(KERN_INFO "IP2: EX box=%d ports=%d %d bit\n",
916 nboxes, nports, pB->i2eDataWidth16 ? 16 : 8 );
918 goto ex_exit;
920 DevTableMem[boardnum] = pCh =
921 kmalloc ( sizeof (i2ChanStr) * nports, GFP_KERNEL );
922 if ( !pCh ) {
923 printk ( KERN_ERR "IP2: (i2_init_channel:) Out of memory.\n");
924 goto err_release_region;
926 pB->i2eChannelPtr = pCh;
927 pB->i2eChannelCnt = nports;
928 if ( !i2InitChannels( pB, nports, pCh ) ) {
929 printk(KERN_ERR "IP2: i2InitChannels failed: %d\n",pB->i2eError);
930 kfree ( pCh );
931 goto err_release_region;
933 pB->i2eChannelPtr = &DevTable[IP2_PORTS_PER_BOARD * boardnum];
935 for( i = 0; i < pB->i2eChannelCnt; ++i ) {
936 DevTable[IP2_PORTS_PER_BOARD * boardnum + i] = pCh;
937 pCh->port_index = (IP2_PORTS_PER_BOARD * boardnum) + i;
938 pCh++;
940 ex_exit:
941 INIT_WORK(&pB->tqueue_interrupt, (void(*)(void*)) ip2_interrupt_bh, pB);
942 return;
944 err_release_region:
945 release_region(ip2config.addr[boardnum], 8);
946 err_initialize:
947 kfree ( pB );
948 i2BoardPtrTable[boardnum] = NULL;
949 return;
952 /******************************************************************************/
953 /* Function: find_eisa_board ( int start_slot ) */
954 /* Parameters: First slot to check */
955 /* Returns: Address of EISA IntelliPort II controller */
956 /* */
957 /* Description: */
958 /* This function searches for an EISA IntelliPort controller, starting */
959 /* from the specified slot number. If the motherboard is not identified as an */
960 /* EISA motherboard, or no valid board ID is selected it returns 0. Otherwise */
961 /* it returns the base address of the controller. */
962 /******************************************************************************/
963 static unsigned short __init
964 find_eisa_board( int start_slot )
966 int i, j;
967 unsigned int idm = 0;
968 unsigned int idp = 0;
969 unsigned int base = 0;
970 unsigned int value;
971 int setup_address;
972 int setup_irq;
973 int ismine = 0;
976 * First a check for an EISA motherboard, which we do by comparing the
977 * EISA ID registers for the system board and the first couple of slots.
978 * No slot ID should match the system board ID, but on an ISA or PCI
979 * machine the odds are that an empty bus will return similar values for
980 * each slot.
982 i = 0x0c80;
983 value = (inb(i) << 24) + (inb(i+1) << 16) + (inb(i+2) << 8) + inb(i+3);
984 for( i = 0x1c80; i <= 0x4c80; i += 0x1000 ) {
985 j = (inb(i)<<24)+(inb(i+1)<<16)+(inb(i+2)<<8)+inb(i+3);
986 if ( value == j )
987 return 0;
991 * OK, so we are inclined to believe that this is an EISA machine. Find
992 * an IntelliPort controller.
994 for( i = start_slot; i < 16; i++ ) {
995 base = i << 12;
996 idm = (inb(base + 0xc80) << 8) | (inb(base + 0xc81) & 0xff);
997 idp = (inb(base + 0xc82) << 8) | (inb(base + 0xc83) & 0xff);
998 ismine = 0;
999 if ( idm == 0x0e8e ) {
1000 if ( idp == 0x0281 || idp == 0x0218 ) {
1001 ismine = 1;
1002 } else if ( idp == 0x0282 || idp == 0x0283 ) {
1003 ismine = 3; /* Can do edge-trigger */
1005 if ( ismine ) {
1006 Eisa_slot = i;
1007 break;
1011 if ( !ismine )
1012 return 0;
1014 /* It's some sort of EISA card, but at what address is it configured? */
1016 setup_address = base + 0xc88;
1017 value = inb(base + 0xc86);
1018 setup_irq = (value & 8) ? Valid_Irqs[value & 7] : 0;
1020 if ( (ismine & 2) && !(value & 0x10) ) {
1021 ismine = 1; /* Could be edging, but not */
1024 if ( Eisa_irq == 0 ) {
1025 Eisa_irq = setup_irq;
1026 } else if ( Eisa_irq != setup_irq ) {
1027 printk ( KERN_ERR "IP2: EISA irq mismatch between EISA controllers\n" );
1030 #ifdef IP2DEBUG_INIT
1031 printk(KERN_DEBUG "Computone EISA board in slot %d, I.D. 0x%x%x, Address 0x%x",
1032 base >> 12, idm, idp, setup_address);
1033 if ( Eisa_irq ) {
1034 printk(KERN_DEBUG ", Interrupt %d %s\n",
1035 setup_irq, (ismine & 2) ? "(edge)" : "(level)");
1036 } else {
1037 printk(KERN_DEBUG ", (polled)\n");
1039 #endif
1040 return setup_address;
1043 /******************************************************************************/
1044 /* Function: set_irq() */
1045 /* Parameters: index to board in board table */
1046 /* IRQ to use */
1047 /* Returns: Success (0) */
1048 /* */
1049 /* Description: */
1050 /******************************************************************************/
1051 static void
1052 set_irq( int boardnum, int boardIrq )
1054 unsigned char tempCommand[16];
1055 i2eBordStrPtr pB = i2BoardPtrTable[boardnum];
1056 unsigned long flags;
1059 * Notify the boards they may generate interrupts. This is done by
1060 * sending an in-line command to channel 0 on each board. This is why
1061 * the channels have to be defined already. For each board, if the
1062 * interrupt has never been defined, we must do so NOW, directly, since
1063 * board will not send flow control or even give an interrupt until this
1064 * is done. If polling we must send 0 as the interrupt parameter.
1067 // We will get an interrupt here at the end of this function
1069 iiDisableMailIrq(pB);
1071 /* We build up the entire packet header. */
1072 CHANNEL_OF(tempCommand) = 0;
1073 PTYPE_OF(tempCommand) = PTYPE_INLINE;
1074 CMD_COUNT_OF(tempCommand) = 2;
1075 (CMD_OF(tempCommand))[0] = CMDVALUE_IRQ;
1076 (CMD_OF(tempCommand))[1] = boardIrq;
1078 * Write to FIFO; don't bother to adjust fifo capacity for this, since
1079 * board will respond almost immediately after SendMail hit.
1081 WRITE_LOCK_IRQSAVE(&pB->write_fifo_spinlock,flags);
1082 iiWriteBuf(pB, tempCommand, 4);
1083 WRITE_UNLOCK_IRQRESTORE(&pB->write_fifo_spinlock,flags);
1084 pB->i2eUsingIrq = boardIrq;
1085 pB->i2eOutMailWaiting |= MB_OUT_STUFFED;
1087 /* Need to update number of boards before you enable mailbox int */
1088 ++i2nBoards;
1090 CHANNEL_OF(tempCommand) = 0;
1091 PTYPE_OF(tempCommand) = PTYPE_BYPASS;
1092 CMD_COUNT_OF(tempCommand) = 6;
1093 (CMD_OF(tempCommand))[0] = 88; // SILO
1094 (CMD_OF(tempCommand))[1] = 64; // chars
1095 (CMD_OF(tempCommand))[2] = 32; // ms
1097 (CMD_OF(tempCommand))[3] = 28; // MAX_BLOCK
1098 (CMD_OF(tempCommand))[4] = 64; // chars
1100 (CMD_OF(tempCommand))[5] = 87; // HW_TEST
1101 WRITE_LOCK_IRQSAVE(&pB->write_fifo_spinlock,flags);
1102 iiWriteBuf(pB, tempCommand, 8);
1103 WRITE_UNLOCK_IRQRESTORE(&pB->write_fifo_spinlock,flags);
1105 CHANNEL_OF(tempCommand) = 0;
1106 PTYPE_OF(tempCommand) = PTYPE_BYPASS;
1107 CMD_COUNT_OF(tempCommand) = 1;
1108 (CMD_OF(tempCommand))[0] = 84; /* get BOX_IDS */
1109 iiWriteBuf(pB, tempCommand, 3);
1111 #ifdef XXX
1112 // enable heartbeat for test porpoises
1113 CHANNEL_OF(tempCommand) = 0;
1114 PTYPE_OF(tempCommand) = PTYPE_BYPASS;
1115 CMD_COUNT_OF(tempCommand) = 2;
1116 (CMD_OF(tempCommand))[0] = 44; /* get ping */
1117 (CMD_OF(tempCommand))[1] = 200; /* 200 ms */
1118 WRITE_LOCK_IRQSAVE(&pB->write_fifo_spinlock,flags);
1119 iiWriteBuf(pB, tempCommand, 4);
1120 WRITE_UNLOCK_IRQRESTORE(&pB->write_fifo_spinlock,flags);
1121 #endif
1123 iiEnableMailIrq(pB);
1124 iiSendPendingMail(pB);
1127 /******************************************************************************/
1128 /* Interrupt Handler Section */
1129 /******************************************************************************/
1131 static inline void
1132 service_all_boards(void)
1134 int i;
1135 i2eBordStrPtr pB;
1137 /* Service every board on the list */
1138 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
1139 pB = i2BoardPtrTable[i];
1140 if ( pB ) {
1141 i2ServiceBoard( pB );
1147 /******************************************************************************/
1148 /* Function: ip2_interrupt_bh(pB) */
1149 /* Parameters: pB - pointer to the board structure */
1150 /* Returns: Nothing */
1151 /* */
1152 /* Description: */
1153 /* Service the board in a bottom half interrupt handler and then */
1154 /* reenable the board's interrupts if it has an IRQ number */
1155 /* */
1156 /******************************************************************************/
1157 static void
1158 ip2_interrupt_bh(i2eBordStrPtr pB)
1160 // pB better well be set or we have a problem! We can only get
1161 // here from the IMMEDIATE queue. Here, we process the boards.
1162 // Checking pB doesn't cost much and it saves us from the sanity checkers.
1164 bh_counter++;
1166 if ( pB ) {
1167 i2ServiceBoard( pB );
1168 if( pB->i2eUsingIrq ) {
1169 // Re-enable his interrupts
1170 iiEnableMailIrq(pB);
1176 /******************************************************************************/
1177 /* Function: ip2_interrupt(int irq, void *dev_id, struct pt_regs * regs) */
1178 /* Parameters: irq - interrupt number */
1179 /* pointer to optional device ID structure */
1180 /* pointer to register structure */
1181 /* Returns: Nothing */
1182 /* */
1183 /* Description: */
1184 /* */
1185 /* Our task here is simply to identify each board which needs servicing. */
1186 /* If we are queuing then, queue it to be serviced, and disable its irq */
1187 /* mask otherwise process the board directly. */
1188 /* */
1189 /* We could queue by IRQ but that just complicates things on both ends */
1190 /* with very little gain in performance (how many instructions does */
1191 /* it take to iterate on the immediate queue). */
1192 /* */
1193 /* */
1194 /******************************************************************************/
1195 static irqreturn_t
1196 ip2_interrupt(int irq, void *dev_id, struct pt_regs * regs)
1198 int i;
1199 i2eBordStrPtr pB;
1200 int handled = 0;
1202 ip2trace (ITRC_NO_PORT, ITRC_INTR, 99, 1, irq );
1204 /* Service just the boards on the list using this irq */
1205 for( i = 0; i < i2nBoards; ++i ) {
1206 pB = i2BoardPtrTable[i];
1208 // Only process those boards which match our IRQ.
1209 // IRQ = 0 for polled boards, we won't poll "IRQ" boards
1211 if ( pB && (pB->i2eUsingIrq == irq) ) {
1212 handled = 1;
1213 #ifdef USE_IQI
1215 if (NO_MAIL_HERE != ( pB->i2eStartMail = iiGetMail(pB))) {
1216 // Disable his interrupt (will be enabled when serviced)
1217 // This is mostly to protect from reentrancy.
1218 iiDisableMailIrq(pB);
1220 // Park the board on the immediate queue for processing.
1221 schedule_work(&pB->tqueue_interrupt);
1223 // Make sure the immediate queue is flagged to fire.
1225 #else
1226 // We are using immediate servicing here. This sucks and can
1227 // cause all sorts of havoc with ppp and others. The failsafe
1228 // check on iiSendPendingMail could also throw a hairball.
1229 i2ServiceBoard( pB );
1230 #endif /* USE_IQI */
1234 ++irq_counter;
1236 ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 );
1237 return IRQ_RETVAL(handled);
1240 /******************************************************************************/
1241 /* Function: ip2_poll(unsigned long arg) */
1242 /* Parameters: ? */
1243 /* Returns: Nothing */
1244 /* */
1245 /* Description: */
1246 /* This function calls the library routine i2ServiceBoard for each board in */
1247 /* the board table. This is used instead of the interrupt routine when polled */
1248 /* mode is specified. */
1249 /******************************************************************************/
1250 static void
1251 ip2_poll(unsigned long arg)
1253 ip2trace (ITRC_NO_PORT, ITRC_INTR, 100, 0 );
1255 TimerOn = 0; // it's the truth but not checked in service
1257 // Just polled boards, IRQ = 0 will hit all non-interrupt boards.
1258 // It will NOT poll boards handled by hard interrupts.
1259 // The issue of queued BH interrups is handled in ip2_interrupt().
1260 ip2_interrupt(0, NULL, NULL);
1262 PollTimer.expires = POLL_TIMEOUT;
1263 add_timer( &PollTimer );
1264 TimerOn = 1;
1266 ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 );
1269 static void do_input(void *p)
1271 i2ChanStrPtr pCh = p;
1272 unsigned long flags;
1274 ip2trace(CHANN, ITRC_INPUT, 21, 0 );
1276 // Data input
1277 if ( pCh->pTTY != NULL ) {
1278 READ_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,flags)
1279 if (!pCh->throttled && (pCh->Ibuf_stuff != pCh->Ibuf_strip)) {
1280 READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags)
1281 i2Input( pCh );
1282 } else
1283 READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags)
1284 } else {
1285 ip2trace(CHANN, ITRC_INPUT, 22, 0 );
1287 i2InputFlush( pCh );
1291 // code duplicated from n_tty (ldisc)
1292 static inline void isig(int sig, struct tty_struct *tty, int flush)
1294 if (tty->pgrp > 0)
1295 kill_pg(tty->pgrp, sig, 1);
1296 if (flush || !L_NOFLSH(tty)) {
1297 if ( tty->ldisc.flush_buffer )
1298 tty->ldisc.flush_buffer(tty);
1299 i2InputFlush( tty->driver_data );
1303 static void do_status(void *p)
1305 i2ChanStrPtr pCh = p;
1306 int status;
1308 status = i2GetStatus( pCh, (I2_BRK|I2_PAR|I2_FRA|I2_OVR) );
1310 ip2trace (CHANN, ITRC_STATUS, 21, 1, status );
1312 if (pCh->pTTY && (status & (I2_BRK|I2_PAR|I2_FRA|I2_OVR)) ) {
1313 if ( (status & I2_BRK) ) {
1314 // code duplicated from n_tty (ldisc)
1315 if (I_IGNBRK(pCh->pTTY))
1316 goto skip_this;
1317 if (I_BRKINT(pCh->pTTY)) {
1318 isig(SIGINT, pCh->pTTY, 1);
1319 goto skip_this;
1321 wake_up_interruptible(&pCh->pTTY->read_wait);
1323 #ifdef NEVER_HAPPENS_AS_SETUP_XXX
1324 // and can't work because we don't know the_char
1325 // as the_char is reported on a separate path
1326 // The intelligent board does this stuff as setup
1328 char brkf = TTY_NORMAL;
1329 unsigned char brkc = '\0';
1330 unsigned char tmp;
1331 if ( (status & I2_BRK) ) {
1332 brkf = TTY_BREAK;
1333 brkc = '\0';
1335 else if (status & I2_PAR) {
1336 brkf = TTY_PARITY;
1337 brkc = the_char;
1338 } else if (status & I2_FRA) {
1339 brkf = TTY_FRAME;
1340 brkc = the_char;
1341 } else if (status & I2_OVR) {
1342 brkf = TTY_OVERRUN;
1343 brkc = the_char;
1345 tmp = pCh->pTTY->real_raw;
1346 pCh->pTTY->real_raw = 0;
1347 pCh->pTTY->ldisc.receive_buf( pCh->pTTY, &brkc, &brkf, 1 );
1348 pCh->pTTY->real_raw = tmp;
1350 #endif /* NEVER_HAPPENS_AS_SETUP_XXX */
1352 skip_this:
1354 if ( status & (I2_DDCD | I2_DDSR | I2_DCTS | I2_DRI) ) {
1355 wake_up_interruptible(&pCh->delta_msr_wait);
1357 if ( (pCh->flags & ASYNC_CHECK_CD) && (status & I2_DDCD) ) {
1358 if ( status & I2_DCD ) {
1359 if ( pCh->wopen ) {
1360 wake_up_interruptible ( &pCh->open_wait );
1362 } else {
1363 if (pCh->pTTY && (!(pCh->pTTY->termios->c_cflag & CLOCAL)) ) {
1364 tty_hangup( pCh->pTTY );
1370 ip2trace (CHANN, ITRC_STATUS, 26, 0 );
1373 /******************************************************************************/
1374 /* Device Open/Close/Ioctl Entry Point Section */
1375 /******************************************************************************/
1377 /******************************************************************************/
1378 /* Function: open_sanity_check() */
1379 /* Parameters: Pointer to tty structure */
1380 /* Pointer to file structure */
1381 /* Returns: Success or failure */
1382 /* */
1383 /* Description: */
1384 /* Verifies the structure magic numbers and cross links. */
1385 /******************************************************************************/
1386 #ifdef IP2DEBUG_OPEN
1387 static void
1388 open_sanity_check( i2ChanStrPtr pCh, i2eBordStrPtr pBrd )
1390 if ( pBrd->i2eValid != I2E_MAGIC ) {
1391 printk(KERN_ERR "IP2: invalid board structure\n" );
1392 } else if ( pBrd != pCh->pMyBord ) {
1393 printk(KERN_ERR "IP2: board structure pointer mismatch (%p)\n",
1394 pCh->pMyBord );
1395 } else if ( pBrd->i2eChannelCnt < pCh->port_index ) {
1396 printk(KERN_ERR "IP2: bad device index (%d)\n", pCh->port_index );
1397 } else if (&((i2ChanStrPtr)pBrd->i2eChannelPtr)[pCh->port_index] != pCh) {
1398 } else {
1399 printk(KERN_INFO "IP2: all pointers check out!\n" );
1402 #endif
1405 /******************************************************************************/
1406 /* Function: ip2_open() */
1407 /* Parameters: Pointer to tty structure */
1408 /* Pointer to file structure */
1409 /* Returns: Success or failure */
1410 /* */
1411 /* Description: (MANDATORY) */
1412 /* A successful device open has to run a gauntlet of checks before it */
1413 /* completes. After some sanity checking and pointer setup, the function */
1414 /* blocks until all conditions are satisfied. It then initialises the port to */
1415 /* the default characteristics and returns. */
1416 /******************************************************************************/
1417 static int
1418 ip2_open( PTTY tty, struct file *pFile )
1420 wait_queue_t wait;
1421 int rc = 0;
1422 int do_clocal = 0;
1423 i2ChanStrPtr pCh = DevTable[tty->index];
1425 ip2trace (tty->index, ITRC_OPEN, ITRC_ENTER, 0 );
1427 if ( pCh == NULL ) {
1428 return -ENODEV;
1430 /* Setup pointer links in device and tty structures */
1431 pCh->pTTY = tty;
1432 tty->driver_data = pCh;
1434 #ifdef IP2DEBUG_OPEN
1435 printk(KERN_DEBUG \
1436 "IP2:open(tty=%p,pFile=%p):dev=%s,ch=%d,idx=%d\n",
1437 tty, pFile, tty->name, pCh->infl.hd.i2sChannel, pCh->port_index);
1438 open_sanity_check ( pCh, pCh->pMyBord );
1439 #endif
1441 i2QueueCommands(PTYPE_INLINE, pCh, 100, 3, CMD_DTRUP,CMD_RTSUP,CMD_DCD_REP);
1442 pCh->dataSetOut |= (I2_DTR | I2_RTS);
1443 serviceOutgoingFifo( pCh->pMyBord );
1445 /* Block here until the port is ready (per serial and istallion) */
1447 * 1. If the port is in the middle of closing wait for the completion
1448 * and then return the appropriate error.
1450 init_waitqueue_entry(&wait, current);
1451 add_wait_queue(&pCh->close_wait, &wait);
1452 set_current_state( TASK_INTERRUPTIBLE );
1454 if ( tty_hung_up_p(pFile) || ( pCh->flags & ASYNC_CLOSING )) {
1455 if ( pCh->flags & ASYNC_CLOSING ) {
1456 schedule();
1458 if ( tty_hung_up_p(pFile) ) {
1459 set_current_state( TASK_RUNNING );
1460 remove_wait_queue(&pCh->close_wait, &wait);
1461 return( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EAGAIN : -ERESTARTSYS;
1464 set_current_state( TASK_RUNNING );
1465 remove_wait_queue(&pCh->close_wait, &wait);
1468 * 3. Handle a non-blocking open of a normal port.
1470 if ( (pFile->f_flags & O_NONBLOCK) || (tty->flags & (1<<TTY_IO_ERROR) )) {
1471 pCh->flags |= ASYNC_NORMAL_ACTIVE;
1472 goto noblock;
1475 * 4. Now loop waiting for the port to be free and carrier present
1476 * (if required).
1478 if ( tty->termios->c_cflag & CLOCAL )
1479 do_clocal = 1;
1481 #ifdef IP2DEBUG_OPEN
1482 printk(KERN_DEBUG "OpenBlock: do_clocal = %d\n", do_clocal);
1483 #endif
1485 ++pCh->wopen;
1487 init_waitqueue_entry(&wait, current);
1488 add_wait_queue(&pCh->open_wait, &wait);
1490 for(;;) {
1491 i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_DTRUP, CMD_RTSUP);
1492 pCh->dataSetOut |= (I2_DTR | I2_RTS);
1493 set_current_state( TASK_INTERRUPTIBLE );
1494 serviceOutgoingFifo( pCh->pMyBord );
1495 if ( tty_hung_up_p(pFile) ) {
1496 set_current_state( TASK_RUNNING );
1497 remove_wait_queue(&pCh->open_wait, &wait);
1498 return ( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EBUSY : -ERESTARTSYS;
1500 if (!(pCh->flags & ASYNC_CLOSING) &&
1501 (do_clocal || (pCh->dataSetIn & I2_DCD) )) {
1502 rc = 0;
1503 break;
1506 #ifdef IP2DEBUG_OPEN
1507 printk(KERN_DEBUG "ASYNC_CLOSING = %s\n",
1508 (pCh->flags & ASYNC_CLOSING)?"True":"False");
1509 printk(KERN_DEBUG "OpenBlock: waiting for CD or signal\n");
1510 #endif
1511 ip2trace (CHANN, ITRC_OPEN, 3, 2, 0,
1512 (pCh->flags & ASYNC_CLOSING) );
1513 /* check for signal */
1514 if (signal_pending(current)) {
1515 rc = (( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EAGAIN : -ERESTARTSYS);
1516 break;
1518 schedule();
1520 set_current_state( TASK_RUNNING );
1521 remove_wait_queue(&pCh->open_wait, &wait);
1523 --pCh->wopen; //why count?
1525 ip2trace (CHANN, ITRC_OPEN, 4, 0 );
1527 if (rc != 0 ) {
1528 return rc;
1530 pCh->flags |= ASYNC_NORMAL_ACTIVE;
1532 noblock:
1534 /* first open - Assign termios structure to port */
1535 if ( tty->count == 1 ) {
1536 i2QueueCommands(PTYPE_INLINE, pCh, 0, 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB);
1537 /* Now we must send the termios settings to the loadware */
1538 set_params( pCh, NULL );
1542 * Now set any i2lib options. These may go away if the i2lib code ends
1543 * up rolled into the mainline.
1545 pCh->channelOptions |= CO_NBLOCK_WRITE;
1547 #ifdef IP2DEBUG_OPEN
1548 printk (KERN_DEBUG "IP2: open completed\n" );
1549 #endif
1550 serviceOutgoingFifo( pCh->pMyBord );
1552 ip2trace (CHANN, ITRC_OPEN, ITRC_RETURN, 0 );
1554 return 0;
1557 /******************************************************************************/
1558 /* Function: ip2_close() */
1559 /* Parameters: Pointer to tty structure */
1560 /* Pointer to file structure */
1561 /* Returns: Nothing */
1562 /* */
1563 /* Description: */
1564 /* */
1565 /* */
1566 /******************************************************************************/
1567 static void
1568 ip2_close( PTTY tty, struct file *pFile )
1570 i2ChanStrPtr pCh = tty->driver_data;
1572 if ( !pCh ) {
1573 return;
1576 ip2trace (CHANN, ITRC_CLOSE, ITRC_ENTER, 0 );
1578 #ifdef IP2DEBUG_OPEN
1579 printk(KERN_DEBUG "IP2:close %s:\n",tty->name);
1580 #endif
1582 if ( tty_hung_up_p ( pFile ) ) {
1584 ip2trace (CHANN, ITRC_CLOSE, 2, 1, 2 );
1586 return;
1588 if ( tty->count > 1 ) { /* not the last close */
1590 ip2trace (CHANN, ITRC_CLOSE, 2, 1, 3 );
1592 return;
1594 pCh->flags |= ASYNC_CLOSING; // last close actually
1596 tty->closing = 1;
1598 if (pCh->ClosingWaitTime != ASYNC_CLOSING_WAIT_NONE) {
1600 * Before we drop DTR, make sure the transmitter has completely drained.
1601 * This uses an timeout, after which the close
1602 * completes.
1604 ip2_wait_until_sent(tty, pCh->ClosingWaitTime );
1607 * At this point we stop accepting input. Here we flush the channel
1608 * input buffer which will allow the board to send up more data. Any
1609 * additional input is tossed at interrupt/poll time.
1611 i2InputFlush( pCh );
1613 /* disable DSS reporting */
1614 i2QueueCommands(PTYPE_INLINE, pCh, 100, 4,
1615 CMD_DCD_NREP, CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);
1616 if ( !tty || (tty->termios->c_cflag & HUPCL) ) {
1617 i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN);
1618 pCh->dataSetOut &= ~(I2_DTR | I2_RTS);
1619 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25));
1622 serviceOutgoingFifo ( pCh->pMyBord );
1624 if ( tty->driver->flush_buffer )
1625 tty->driver->flush_buffer(tty);
1626 if ( tty->ldisc.flush_buffer )
1627 tty->ldisc.flush_buffer(tty);
1628 tty->closing = 0;
1630 pCh->pTTY = NULL;
1632 if (pCh->wopen) {
1633 if (pCh->ClosingDelay) {
1634 msleep_interruptible(jiffies_to_msecs(pCh->ClosingDelay));
1636 wake_up_interruptible(&pCh->open_wait);
1639 pCh->flags &=~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1640 wake_up_interruptible(&pCh->close_wait);
1642 #ifdef IP2DEBUG_OPEN
1643 DBG_CNT("ip2_close: after wakeups--");
1644 #endif
1647 ip2trace (CHANN, ITRC_CLOSE, ITRC_RETURN, 1, 1 );
1649 return;
1652 /******************************************************************************/
1653 /* Function: ip2_hangup() */
1654 /* Parameters: Pointer to tty structure */
1655 /* Returns: Nothing */
1656 /* */
1657 /* Description: */
1658 /* */
1659 /* */
1660 /******************************************************************************/
1661 static void
1662 ip2_hangup ( PTTY tty )
1664 i2ChanStrPtr pCh = tty->driver_data;
1666 if( !pCh ) {
1667 return;
1670 ip2trace (CHANN, ITRC_HANGUP, ITRC_ENTER, 0 );
1672 ip2_flush_buffer(tty);
1674 /* disable DSS reporting */
1676 i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_DCD_NREP);
1677 i2QueueCommands(PTYPE_INLINE, pCh, 0, 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB);
1678 if ( (tty->termios->c_cflag & HUPCL) ) {
1679 i2QueueCommands(PTYPE_BYPASS, pCh, 0, 2, CMD_RTSDN, CMD_DTRDN);
1680 pCh->dataSetOut &= ~(I2_DTR | I2_RTS);
1681 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25));
1683 i2QueueCommands(PTYPE_INLINE, pCh, 1, 3,
1684 CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);
1685 serviceOutgoingFifo ( pCh->pMyBord );
1687 wake_up_interruptible ( &pCh->delta_msr_wait );
1689 pCh->flags &= ~ASYNC_NORMAL_ACTIVE;
1690 pCh->pTTY = NULL;
1691 wake_up_interruptible ( &pCh->open_wait );
1693 ip2trace (CHANN, ITRC_HANGUP, ITRC_RETURN, 0 );
1696 /******************************************************************************/
1697 /******************************************************************************/
1698 /* Device Output Section */
1699 /******************************************************************************/
1700 /******************************************************************************/
1702 /******************************************************************************/
1703 /* Function: ip2_write() */
1704 /* Parameters: Pointer to tty structure */
1705 /* Flag denoting data is in user (1) or kernel (0) space */
1706 /* Pointer to data */
1707 /* Number of bytes to write */
1708 /* Returns: Number of bytes actually written */
1709 /* */
1710 /* Description: (MANDATORY) */
1711 /* */
1712 /* */
1713 /******************************************************************************/
1714 static int
1715 ip2_write( PTTY tty, int user, const unsigned char *pData, int count)
1717 i2ChanStrPtr pCh = tty->driver_data;
1718 int bytesSent = 0;
1719 unsigned long flags;
1721 ip2trace (CHANN, ITRC_WRITE, ITRC_ENTER, 2, count, -1 );
1723 /* Flush out any buffered data left over from ip2_putchar() calls. */
1724 ip2_flush_chars( tty );
1726 /* This is the actual move bit. Make sure it does what we need!!!!! */
1727 WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
1728 bytesSent = i2Output( pCh, pData, count, user );
1729 WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
1731 ip2trace (CHANN, ITRC_WRITE, ITRC_RETURN, 1, bytesSent );
1733 return bytesSent > 0 ? bytesSent : 0;
1736 /******************************************************************************/
1737 /* Function: ip2_putchar() */
1738 /* Parameters: Pointer to tty structure */
1739 /* Character to write */
1740 /* Returns: Nothing */
1741 /* */
1742 /* Description: */
1743 /* */
1744 /* */
1745 /******************************************************************************/
1746 static void
1747 ip2_putchar( PTTY tty, unsigned char ch )
1749 i2ChanStrPtr pCh = tty->driver_data;
1750 unsigned long flags;
1752 // ip2trace (CHANN, ITRC_PUTC, ITRC_ENTER, 1, ch );
1754 WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
1755 pCh->Pbuf[pCh->Pbuf_stuff++] = ch;
1756 if ( pCh->Pbuf_stuff == sizeof pCh->Pbuf ) {
1757 WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
1758 ip2_flush_chars( tty );
1759 } else
1760 WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
1762 // ip2trace (CHANN, ITRC_PUTC, ITRC_RETURN, 1, ch );
1765 /******************************************************************************/
1766 /* Function: ip2_flush_chars() */
1767 /* Parameters: Pointer to tty structure */
1768 /* Returns: Nothing */
1769 /* */
1770 /* Description: */
1771 /* */
1772 /******************************************************************************/
1773 static void
1774 ip2_flush_chars( PTTY tty )
1776 int strip;
1777 i2ChanStrPtr pCh = tty->driver_data;
1778 unsigned long flags;
1780 WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
1781 if ( pCh->Pbuf_stuff ) {
1783 // ip2trace (CHANN, ITRC_PUTC, 10, 1, strip );
1786 // We may need to restart i2Output if it does not fullfill this request
1788 strip = i2Output( pCh, pCh->Pbuf, pCh->Pbuf_stuff, 0 );
1789 if ( strip != pCh->Pbuf_stuff ) {
1790 memmove( pCh->Pbuf, &pCh->Pbuf[strip], pCh->Pbuf_stuff - strip );
1792 pCh->Pbuf_stuff -= strip;
1794 WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
1797 /******************************************************************************/
1798 /* Function: ip2_write_room() */
1799 /* Parameters: Pointer to tty structure */
1800 /* Returns: Number of bytes that the driver can accept */
1801 /* */
1802 /* Description: */
1803 /* */
1804 /******************************************************************************/
1805 static int
1806 ip2_write_room ( PTTY tty )
1808 int bytesFree;
1809 i2ChanStrPtr pCh = tty->driver_data;
1810 unsigned long flags;
1812 READ_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
1813 bytesFree = i2OutputFree( pCh ) - pCh->Pbuf_stuff;
1814 READ_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
1816 ip2trace (CHANN, ITRC_WRITE, 11, 1, bytesFree );
1818 return ((bytesFree > 0) ? bytesFree : 0);
1821 /******************************************************************************/
1822 /* Function: ip2_chars_in_buf() */
1823 /* Parameters: Pointer to tty structure */
1824 /* Returns: Number of bytes queued for transmission */
1825 /* */
1826 /* Description: */
1827 /* */
1828 /* */
1829 /******************************************************************************/
1830 static int
1831 ip2_chars_in_buf ( PTTY tty )
1833 i2ChanStrPtr pCh = tty->driver_data;
1834 int rc;
1835 unsigned long flags;
1837 ip2trace (CHANN, ITRC_WRITE, 12, 1, pCh->Obuf_char_count + pCh->Pbuf_stuff );
1839 #ifdef IP2DEBUG_WRITE
1840 printk (KERN_DEBUG "IP2: chars in buffer = %d (%d,%d)\n",
1841 pCh->Obuf_char_count + pCh->Pbuf_stuff,
1842 pCh->Obuf_char_count, pCh->Pbuf_stuff );
1843 #endif
1844 READ_LOCK_IRQSAVE(&pCh->Obuf_spinlock,flags);
1845 rc = pCh->Obuf_char_count;
1846 READ_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags);
1847 READ_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
1848 rc += pCh->Pbuf_stuff;
1849 READ_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
1850 return rc;
1853 /******************************************************************************/
1854 /* Function: ip2_flush_buffer() */
1855 /* Parameters: Pointer to tty structure */
1856 /* Returns: Nothing */
1857 /* */
1858 /* Description: */
1859 /* */
1860 /* */
1861 /******************************************************************************/
1862 static void
1863 ip2_flush_buffer( PTTY tty )
1865 i2ChanStrPtr pCh = tty->driver_data;
1866 unsigned long flags;
1868 ip2trace (CHANN, ITRC_FLUSH, ITRC_ENTER, 0 );
1870 #ifdef IP2DEBUG_WRITE
1871 printk (KERN_DEBUG "IP2: flush buffer\n" );
1872 #endif
1873 WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
1874 pCh->Pbuf_stuff = 0;
1875 WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
1876 i2FlushOutput( pCh );
1877 ip2_owake(tty);
1879 ip2trace (CHANN, ITRC_FLUSH, ITRC_RETURN, 0 );
1883 /******************************************************************************/
1884 /* Function: ip2_wait_until_sent() */
1885 /* Parameters: Pointer to tty structure */
1886 /* Timeout for wait. */
1887 /* Returns: Nothing */
1888 /* */
1889 /* Description: */
1890 /* This function is used in place of the normal tty_wait_until_sent, which */
1891 /* only waits for the driver buffers to be empty (or rather, those buffers */
1892 /* reported by chars_in_buffer) which doesn't work for IP2 due to the */
1893 /* indeterminate number of bytes buffered on the board. */
1894 /******************************************************************************/
1895 static void
1896 ip2_wait_until_sent ( PTTY tty, int timeout )
1898 int i = jiffies;
1899 i2ChanStrPtr pCh = tty->driver_data;
1901 tty_wait_until_sent(tty, timeout );
1902 if ( (i = timeout - (jiffies -i)) > 0)
1903 i2DrainOutput( pCh, i );
1906 /******************************************************************************/
1907 /******************************************************************************/
1908 /* Device Input Section */
1909 /******************************************************************************/
1910 /******************************************************************************/
1912 /******************************************************************************/
1913 /* Function: ip2_throttle() */
1914 /* Parameters: Pointer to tty structure */
1915 /* Returns: Nothing */
1916 /* */
1917 /* Description: */
1918 /* */
1919 /* */
1920 /******************************************************************************/
1921 static void
1922 ip2_throttle ( PTTY tty )
1924 i2ChanStrPtr pCh = tty->driver_data;
1926 #ifdef IP2DEBUG_READ
1927 printk (KERN_DEBUG "IP2: throttle\n" );
1928 #endif
1930 * Signal the poll/interrupt handlers not to forward incoming data to
1931 * the line discipline. This will cause the buffers to fill up in the
1932 * library and thus cause the library routines to send the flow control
1933 * stuff.
1935 pCh->throttled = 1;
1938 /******************************************************************************/
1939 /* Function: ip2_unthrottle() */
1940 /* Parameters: Pointer to tty structure */
1941 /* Returns: Nothing */
1942 /* */
1943 /* Description: */
1944 /* */
1945 /* */
1946 /******************************************************************************/
1947 static void
1948 ip2_unthrottle ( PTTY tty )
1950 i2ChanStrPtr pCh = tty->driver_data;
1951 unsigned long flags;
1953 #ifdef IP2DEBUG_READ
1954 printk (KERN_DEBUG "IP2: unthrottle\n" );
1955 #endif
1957 /* Pass incoming data up to the line discipline again. */
1958 pCh->throttled = 0;
1959 i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_RESUME);
1960 serviceOutgoingFifo( pCh->pMyBord );
1961 READ_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,flags)
1962 if ( pCh->Ibuf_stuff != pCh->Ibuf_strip ) {
1963 READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags)
1964 #ifdef IP2DEBUG_READ
1965 printk (KERN_DEBUG "i2Input called from unthrottle\n" );
1966 #endif
1967 i2Input( pCh );
1968 } else
1969 READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags)
1972 static void
1973 ip2_start ( PTTY tty )
1975 i2ChanStrPtr pCh = DevTable[tty->index];
1977 i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_RESUME);
1978 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_UNSUSPEND);
1979 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_RESUME);
1980 #ifdef IP2DEBUG_WRITE
1981 printk (KERN_DEBUG "IP2: start tx\n" );
1982 #endif
1985 static void
1986 ip2_stop ( PTTY tty )
1988 i2ChanStrPtr pCh = DevTable[tty->index];
1990 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_SUSPEND);
1991 #ifdef IP2DEBUG_WRITE
1992 printk (KERN_DEBUG "IP2: stop tx\n" );
1993 #endif
1996 /******************************************************************************/
1997 /* Device Ioctl Section */
1998 /******************************************************************************/
2000 static int ip2_tiocmget(struct tty_struct *tty, struct file *file)
2002 i2ChanStrPtr pCh = DevTable[tty->index];
2003 wait_queue_t wait;
2005 if (pCh == NULL)
2006 return -ENODEV;
2009 FIXME - the following code is causing a NULL pointer dereference in
2010 2.3.51 in an interrupt handler. It's suppose to prompt the board
2011 to return the DSS signal status immediately. Why doesn't it do
2012 the same thing in 2.2.14?
2015 /* This thing is still busted in the 1.2.12 driver on 2.4.x
2016 and even hoses the serial console so the oops can be trapped.
2017 /\/\|=mhw=|\/\/ */
2019 #ifdef ENABLE_DSSNOW
2020 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DSS_NOW);
2022 init_waitqueue_entry(&wait, current);
2023 add_wait_queue(&pCh->dss_now_wait, &wait);
2024 set_current_state( TASK_INTERRUPTIBLE );
2026 serviceOutgoingFifo( pCh->pMyBord );
2028 schedule();
2030 set_current_state( TASK_RUNNING );
2031 remove_wait_queue(&pCh->dss_now_wait, &wait);
2033 if (signal_pending(current)) {
2034 return -EINTR;
2036 #endif
2037 return ((pCh->dataSetOut & I2_RTS) ? TIOCM_RTS : 0)
2038 | ((pCh->dataSetOut & I2_DTR) ? TIOCM_DTR : 0)
2039 | ((pCh->dataSetIn & I2_DCD) ? TIOCM_CAR : 0)
2040 | ((pCh->dataSetIn & I2_RI) ? TIOCM_RNG : 0)
2041 | ((pCh->dataSetIn & I2_DSR) ? TIOCM_DSR : 0)
2042 | ((pCh->dataSetIn & I2_CTS) ? TIOCM_CTS : 0);
2045 static int ip2_tiocmset(struct tty_struct *tty, struct file *file,
2046 unsigned int set, unsigned int clear)
2048 i2ChanStrPtr pCh = DevTable[tty->index];
2050 if (pCh == NULL)
2051 return -ENODEV;
2053 if (set & TIOCM_RTS) {
2054 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_RTSUP);
2055 pCh->dataSetOut |= I2_RTS;
2057 if (set & TIOCM_DTR) {
2058 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DTRUP);
2059 pCh->dataSetOut |= I2_DTR;
2062 if (clear & TIOCM_RTS) {
2063 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_RTSDN);
2064 pCh->dataSetOut &= ~I2_RTS;
2066 if (clear & TIOCM_DTR) {
2067 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DTRDN);
2068 pCh->dataSetOut &= ~I2_DTR;
2070 serviceOutgoingFifo( pCh->pMyBord );
2071 return 0;
2074 /******************************************************************************/
2075 /* Function: ip2_ioctl() */
2076 /* Parameters: Pointer to tty structure */
2077 /* Pointer to file structure */
2078 /* Command */
2079 /* Argument */
2080 /* Returns: Success or failure */
2081 /* */
2082 /* Description: */
2083 /* */
2084 /* */
2085 /******************************************************************************/
2086 static int
2087 ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg )
2089 wait_queue_t wait;
2090 i2ChanStrPtr pCh = DevTable[tty->index];
2091 struct async_icount cprev, cnow; /* kernel counter temps */
2092 struct serial_icounter_struct __user *p_cuser;
2093 int rc = 0;
2094 unsigned long flags;
2095 void __user *argp = (void __user *)arg;
2097 if ( pCh == NULL ) {
2098 return -ENODEV;
2101 ip2trace (CHANN, ITRC_IOCTL, ITRC_ENTER, 2, cmd, arg );
2103 #ifdef IP2DEBUG_IOCTL
2104 printk(KERN_DEBUG "IP2: ioctl cmd (%x), arg (%lx)\n", cmd, arg );
2105 #endif
2107 switch(cmd) {
2108 case TIOCGSERIAL:
2110 ip2trace (CHANN, ITRC_IOCTL, 2, 1, rc );
2112 rc = get_serial_info(pCh, argp);
2113 if (rc)
2114 return rc;
2115 break;
2117 case TIOCSSERIAL:
2119 ip2trace (CHANN, ITRC_IOCTL, 3, 1, rc );
2121 rc = set_serial_info(pCh, argp);
2122 if (rc)
2123 return rc;
2124 break;
2126 case TCXONC:
2127 rc = tty_check_change(tty);
2128 if (rc)
2129 return rc;
2130 switch (arg) {
2131 case TCOOFF:
2132 //return -ENOIOCTLCMD;
2133 break;
2134 case TCOON:
2135 //return -ENOIOCTLCMD;
2136 break;
2137 case TCIOFF:
2138 if (STOP_CHAR(tty) != __DISABLED_CHAR) {
2139 i2QueueCommands( PTYPE_BYPASS, pCh, 100, 1,
2140 CMD_XMIT_NOW(STOP_CHAR(tty)));
2142 break;
2143 case TCION:
2144 if (START_CHAR(tty) != __DISABLED_CHAR) {
2145 i2QueueCommands( PTYPE_BYPASS, pCh, 100, 1,
2146 CMD_XMIT_NOW(START_CHAR(tty)));
2148 break;
2149 default:
2150 return -EINVAL;
2152 return 0;
2154 case TCSBRK: /* SVID version: non-zero arg --> no break */
2155 rc = tty_check_change(tty);
2157 ip2trace (CHANN, ITRC_IOCTL, 4, 1, rc );
2159 if (!rc) {
2160 ip2_wait_until_sent(tty,0);
2161 if (!arg) {
2162 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_SEND_BRK(250));
2163 serviceOutgoingFifo( pCh->pMyBord );
2166 break;
2168 case TCSBRKP: /* support for POSIX tcsendbreak() */
2169 rc = tty_check_change(tty);
2171 ip2trace (CHANN, ITRC_IOCTL, 5, 1, rc );
2173 if (!rc) {
2174 ip2_wait_until_sent(tty,0);
2175 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1,
2176 CMD_SEND_BRK(arg ? arg*100 : 250));
2177 serviceOutgoingFifo ( pCh->pMyBord );
2179 break;
2181 case TIOCGSOFTCAR:
2183 ip2trace (CHANN, ITRC_IOCTL, 6, 1, rc );
2185 rc = put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *)argp);
2186 if (rc)
2187 return rc;
2188 break;
2190 case TIOCSSOFTCAR:
2192 ip2trace (CHANN, ITRC_IOCTL, 7, 1, rc );
2194 rc = get_user(arg,(unsigned long __user *) argp);
2195 if (rc)
2196 return rc;
2197 tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL)
2198 | (arg ? CLOCAL : 0));
2200 break;
2203 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change - mask
2204 * passed in arg for lines of interest (use |'ed TIOCM_RNG/DSR/CD/CTS
2205 * for masking). Caller should use TIOCGICOUNT to see which one it was
2207 case TIOCMIWAIT:
2208 save_flags(flags);cli();
2209 cprev = pCh->icount; /* note the counters on entry */
2210 restore_flags(flags);
2211 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 4,
2212 CMD_DCD_REP, CMD_CTS_REP, CMD_DSR_REP, CMD_RI_REP);
2213 init_waitqueue_entry(&wait, current);
2214 add_wait_queue(&pCh->delta_msr_wait, &wait);
2215 set_current_state( TASK_INTERRUPTIBLE );
2217 serviceOutgoingFifo( pCh->pMyBord );
2218 for(;;) {
2219 ip2trace (CHANN, ITRC_IOCTL, 10, 0 );
2221 schedule();
2223 ip2trace (CHANN, ITRC_IOCTL, 11, 0 );
2225 /* see if a signal did it */
2226 if (signal_pending(current)) {
2227 rc = -ERESTARTSYS;
2228 break;
2230 save_flags(flags);cli();
2231 cnow = pCh->icount; /* atomic copy */
2232 restore_flags(flags);
2233 if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
2234 cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) {
2235 rc = -EIO; /* no change => rc */
2236 break;
2238 if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
2239 ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
2240 ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
2241 ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
2242 rc = 0;
2243 break;
2245 cprev = cnow;
2247 set_current_state( TASK_RUNNING );
2248 remove_wait_queue(&pCh->delta_msr_wait, &wait);
2250 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 3,
2251 CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);
2252 if ( ! (pCh->flags & ASYNC_CHECK_CD)) {
2253 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DCD_NREP);
2255 serviceOutgoingFifo( pCh->pMyBord );
2256 return rc;
2257 break;
2260 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
2261 * Return: write counters to the user passed counter struct
2262 * NB: both 1->0 and 0->1 transitions are counted except for RI where
2263 * only 0->1 is counted. The controller is quite capable of counting
2264 * both, but this done to preserve compatibility with the standard
2265 * serial driver.
2267 case TIOCGICOUNT:
2268 ip2trace (CHANN, ITRC_IOCTL, 11, 1, rc );
2270 save_flags(flags);cli();
2271 cnow = pCh->icount;
2272 restore_flags(flags);
2273 p_cuser = argp;
2274 rc = put_user(cnow.cts, &p_cuser->cts);
2275 rc = put_user(cnow.dsr, &p_cuser->dsr);
2276 rc = put_user(cnow.rng, &p_cuser->rng);
2277 rc = put_user(cnow.dcd, &p_cuser->dcd);
2278 rc = put_user(cnow.rx, &p_cuser->rx);
2279 rc = put_user(cnow.tx, &p_cuser->tx);
2280 rc = put_user(cnow.frame, &p_cuser->frame);
2281 rc = put_user(cnow.overrun, &p_cuser->overrun);
2282 rc = put_user(cnow.parity, &p_cuser->parity);
2283 rc = put_user(cnow.brk, &p_cuser->brk);
2284 rc = put_user(cnow.buf_overrun, &p_cuser->buf_overrun);
2285 break;
2288 * The rest are not supported by this driver. By returning -ENOIOCTLCMD they
2289 * will be passed to the line discipline for it to handle.
2291 case TIOCSERCONFIG:
2292 case TIOCSERGWILD:
2293 case TIOCSERGETLSR:
2294 case TIOCSERSWILD:
2295 case TIOCSERGSTRUCT:
2296 case TIOCSERGETMULTI:
2297 case TIOCSERSETMULTI:
2299 default:
2300 ip2trace (CHANN, ITRC_IOCTL, 12, 0 );
2302 rc = -ENOIOCTLCMD;
2303 break;
2306 ip2trace (CHANN, ITRC_IOCTL, ITRC_RETURN, 0 );
2308 return rc;
2311 /******************************************************************************/
2312 /* Function: GetSerialInfo() */
2313 /* Parameters: Pointer to channel structure */
2314 /* Pointer to old termios structure */
2315 /* Returns: Nothing */
2316 /* */
2317 /* Description: */
2318 /* This is to support the setserial command, and requires processing of the */
2319 /* standard Linux serial structure. */
2320 /******************************************************************************/
2321 static int
2322 get_serial_info ( i2ChanStrPtr pCh, struct serial_struct __user *retinfo )
2324 struct serial_struct tmp;
2326 memset ( &tmp, 0, sizeof(tmp) );
2327 tmp.type = pCh->pMyBord->channelBtypes.bid_value[(pCh->port_index & (IP2_PORTS_PER_BOARD-1))/16];
2328 if (BID_HAS_654(tmp.type)) {
2329 tmp.type = PORT_16650;
2330 } else {
2331 tmp.type = PORT_CIRRUS;
2333 tmp.line = pCh->port_index;
2334 tmp.port = pCh->pMyBord->i2eBase;
2335 tmp.irq = ip2config.irq[pCh->port_index/64];
2336 tmp.flags = pCh->flags;
2337 tmp.baud_base = pCh->BaudBase;
2338 tmp.close_delay = pCh->ClosingDelay;
2339 tmp.closing_wait = pCh->ClosingWaitTime;
2340 tmp.custom_divisor = pCh->BaudDivisor;
2341 return copy_to_user(retinfo,&tmp,sizeof(*retinfo));
2344 /******************************************************************************/
2345 /* Function: SetSerialInfo() */
2346 /* Parameters: Pointer to channel structure */
2347 /* Pointer to old termios structure */
2348 /* Returns: Nothing */
2349 /* */
2350 /* Description: */
2351 /* This function provides support for setserial, which uses the TIOCSSERIAL */
2352 /* ioctl. Not all setserial parameters are relevant. If the user attempts to */
2353 /* change the IRQ, address or type of the port the ioctl fails. */
2354 /******************************************************************************/
2355 static int
2356 set_serial_info( i2ChanStrPtr pCh, struct serial_struct __user *new_info )
2358 struct serial_struct ns;
2359 int old_flags, old_baud_divisor;
2361 if (copy_from_user(&ns, new_info, sizeof (ns)))
2362 return -EFAULT;
2365 * We don't allow setserial to change IRQ, board address, type or baud
2366 * base. Also line nunber as such is meaningless but we use it for our
2367 * array index so it is fixed also.
2369 if ( (ns.irq != ip2config.irq[pCh->port_index])
2370 || ((int) ns.port != ((int) (pCh->pMyBord->i2eBase)))
2371 || (ns.baud_base != pCh->BaudBase)
2372 || (ns.line != pCh->port_index) ) {
2373 return -EINVAL;
2376 old_flags = pCh->flags;
2377 old_baud_divisor = pCh->BaudDivisor;
2379 if ( !capable(CAP_SYS_ADMIN) ) {
2380 if ( ( ns.close_delay != pCh->ClosingDelay ) ||
2381 ( (ns.flags & ~ASYNC_USR_MASK) !=
2382 (pCh->flags & ~ASYNC_USR_MASK) ) ) {
2383 return -EPERM;
2386 pCh->flags = (pCh->flags & ~ASYNC_USR_MASK) |
2387 (ns.flags & ASYNC_USR_MASK);
2388 pCh->BaudDivisor = ns.custom_divisor;
2389 } else {
2390 pCh->flags = (pCh->flags & ~ASYNC_FLAGS) |
2391 (ns.flags & ASYNC_FLAGS);
2392 pCh->BaudDivisor = ns.custom_divisor;
2393 pCh->ClosingDelay = ns.close_delay * HZ/100;
2394 pCh->ClosingWaitTime = ns.closing_wait * HZ/100;
2397 if ( ( (old_flags & ASYNC_SPD_MASK) != (pCh->flags & ASYNC_SPD_MASK) )
2398 || (old_baud_divisor != pCh->BaudDivisor) ) {
2399 // Invalidate speed and reset parameters
2400 set_params( pCh, NULL );
2403 return 0;
2406 /******************************************************************************/
2407 /* Function: ip2_set_termios() */
2408 /* Parameters: Pointer to tty structure */
2409 /* Pointer to old termios structure */
2410 /* Returns: Nothing */
2411 /* */
2412 /* Description: */
2413 /* */
2414 /* */
2415 /******************************************************************************/
2416 static void
2417 ip2_set_termios( PTTY tty, struct termios *old_termios )
2419 i2ChanStrPtr pCh = (i2ChanStrPtr)tty->driver_data;
2421 #ifdef IP2DEBUG_IOCTL
2422 printk (KERN_DEBUG "IP2: set termios %p\n", old_termios );
2423 #endif
2425 set_params( pCh, old_termios );
2428 /******************************************************************************/
2429 /* Function: ip2_set_line_discipline() */
2430 /* Parameters: Pointer to tty structure */
2431 /* Returns: Nothing */
2432 /* */
2433 /* Description: Does nothing */
2434 /* */
2435 /* */
2436 /******************************************************************************/
2437 static void
2438 ip2_set_line_discipline ( PTTY tty )
2440 #ifdef IP2DEBUG_IOCTL
2441 printk (KERN_DEBUG "IP2: set line discipline\n" );
2442 #endif
2444 ip2trace (((i2ChanStrPtr)tty->driver_data)->port_index, ITRC_IOCTL, 16, 0 );
2448 /******************************************************************************/
2449 /* Function: SetLine Characteristics() */
2450 /* Parameters: Pointer to channel structure */
2451 /* Returns: Nothing */
2452 /* */
2453 /* Description: */
2454 /* This routine is called to update the channel structure with the new line */
2455 /* characteristics, and send the appropriate commands to the board when they */
2456 /* change. */
2457 /******************************************************************************/
2458 static void
2459 set_params( i2ChanStrPtr pCh, struct termios *o_tios )
2461 tcflag_t cflag, iflag, lflag;
2462 char stop_char, start_char;
2463 struct termios dummy;
2465 lflag = pCh->pTTY->termios->c_lflag;
2466 cflag = pCh->pTTY->termios->c_cflag;
2467 iflag = pCh->pTTY->termios->c_iflag;
2469 if (o_tios == NULL) {
2470 dummy.c_lflag = ~lflag;
2471 dummy.c_cflag = ~cflag;
2472 dummy.c_iflag = ~iflag;
2473 o_tios = &dummy;
2477 switch ( cflag & CBAUD ) {
2478 case B0:
2479 i2QueueCommands( PTYPE_BYPASS, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN);
2480 pCh->dataSetOut &= ~(I2_DTR | I2_RTS);
2481 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25));
2482 pCh->pTTY->termios->c_cflag |= (CBAUD & o_tios->c_cflag);
2483 goto service_it;
2484 break;
2485 case B38400:
2487 * This is the speed that is overloaded with all the other high
2488 * speeds, depending upon the flag settings.
2490 if ( ( pCh->flags & ASYNC_SPD_MASK ) == ASYNC_SPD_HI ) {
2491 pCh->speed = CBR_57600;
2492 } else if ( (pCh->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI ) {
2493 pCh->speed = CBR_115200;
2494 } else if ( (pCh->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST ) {
2495 pCh->speed = CBR_C1;
2496 } else {
2497 pCh->speed = CBR_38400;
2499 break;
2500 case B50: pCh->speed = CBR_50; break;
2501 case B75: pCh->speed = CBR_75; break;
2502 case B110: pCh->speed = CBR_110; break;
2503 case B134: pCh->speed = CBR_134; break;
2504 case B150: pCh->speed = CBR_150; break;
2505 case B200: pCh->speed = CBR_200; break;
2506 case B300: pCh->speed = CBR_300; break;
2507 case B600: pCh->speed = CBR_600; break;
2508 case B1200: pCh->speed = CBR_1200; break;
2509 case B1800: pCh->speed = CBR_1800; break;
2510 case B2400: pCh->speed = CBR_2400; break;
2511 case B4800: pCh->speed = CBR_4800; break;
2512 case B9600: pCh->speed = CBR_9600; break;
2513 case B19200: pCh->speed = CBR_19200; break;
2514 case B57600: pCh->speed = CBR_57600; break;
2515 case B115200: pCh->speed = CBR_115200; break;
2516 case B153600: pCh->speed = CBR_153600; break;
2517 case B230400: pCh->speed = CBR_230400; break;
2518 case B307200: pCh->speed = CBR_307200; break;
2519 case B460800: pCh->speed = CBR_460800; break;
2520 case B921600: pCh->speed = CBR_921600; break;
2521 default: pCh->speed = CBR_9600; break;
2523 if ( pCh->speed == CBR_C1 ) {
2524 // Process the custom speed parameters.
2525 int bps = pCh->BaudBase / pCh->BaudDivisor;
2526 if ( bps == 921600 ) {
2527 pCh->speed = CBR_921600;
2528 } else {
2529 bps = bps/10;
2530 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_BAUD_DEF1(bps) );
2533 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_SETBAUD(pCh->speed));
2535 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 2, CMD_DTRUP, CMD_RTSUP);
2536 pCh->dataSetOut |= (I2_DTR | I2_RTS);
2538 if ( (CSTOPB & cflag) ^ (CSTOPB & o_tios->c_cflag))
2540 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1,
2541 CMD_SETSTOP( ( cflag & CSTOPB ) ? CST_2 : CST_1));
2543 if (((PARENB|PARODD) & cflag) ^ ((PARENB|PARODD) & o_tios->c_cflag))
2545 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1,
2546 CMD_SETPAR(
2547 (cflag & PARENB ? (cflag & PARODD ? CSP_OD : CSP_EV) : CSP_NP)
2551 /* byte size and parity */
2552 if ( (CSIZE & cflag)^(CSIZE & o_tios->c_cflag))
2554 int datasize;
2555 switch ( cflag & CSIZE ) {
2556 case CS5: datasize = CSZ_5; break;
2557 case CS6: datasize = CSZ_6; break;
2558 case CS7: datasize = CSZ_7; break;
2559 case CS8: datasize = CSZ_8; break;
2560 default: datasize = CSZ_5; break; /* as per serial.c */
2562 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1, CMD_SETBITS(datasize) );
2564 /* Process CTS flow control flag setting */
2565 if ( (cflag & CRTSCTS) ) {
2566 i2QueueCommands(PTYPE_INLINE, pCh, 100,
2567 2, CMD_CTSFL_ENAB, CMD_RTSFL_ENAB);
2568 } else {
2569 i2QueueCommands(PTYPE_INLINE, pCh, 100,
2570 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB);
2573 // Process XON/XOFF flow control flags settings
2575 stop_char = STOP_CHAR(pCh->pTTY);
2576 start_char = START_CHAR(pCh->pTTY);
2578 //////////// can't be \000
2579 if (stop_char == __DISABLED_CHAR )
2581 stop_char = ~__DISABLED_CHAR;
2583 if (start_char == __DISABLED_CHAR )
2585 start_char = ~__DISABLED_CHAR;
2587 /////////////////////////////////
2589 if ( o_tios->c_cc[VSTART] != start_char )
2591 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DEF_IXON(start_char));
2592 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DEF_OXON(start_char));
2594 if ( o_tios->c_cc[VSTOP] != stop_char )
2596 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DEF_IXOFF(stop_char));
2597 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DEF_OXOFF(stop_char));
2599 if (stop_char == __DISABLED_CHAR )
2601 stop_char = ~__DISABLED_CHAR; //TEST123
2602 goto no_xoff;
2604 if ((iflag & (IXOFF))^(o_tios->c_iflag & (IXOFF)))
2606 if ( iflag & IXOFF ) { // Enable XOFF output flow control
2607 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_OXON_OPT(COX_XON));
2608 } else { // Disable XOFF output flow control
2609 no_xoff:
2610 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_OXON_OPT(COX_NONE));
2613 if (start_char == __DISABLED_CHAR )
2615 goto no_xon;
2617 if ((iflag & (IXON|IXANY)) ^ (o_tios->c_iflag & (IXON|IXANY)))
2619 if ( iflag & IXON ) {
2620 if ( iflag & IXANY ) { // Enable XON/XANY output flow control
2621 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_XANY));
2622 } else { // Enable XON output flow control
2623 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_XON));
2625 } else { // Disable XON output flow control
2626 no_xon:
2627 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_NONE));
2630 if ( (iflag & ISTRIP) ^ ( o_tios->c_iflag & (ISTRIP)) )
2632 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1,
2633 CMD_ISTRIP_OPT((iflag & ISTRIP ? 1 : 0)));
2635 if ( (iflag & INPCK) ^ ( o_tios->c_iflag & (INPCK)) )
2637 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1,
2638 CMD_PARCHK((iflag & INPCK) ? CPK_ENAB : CPK_DSAB));
2641 if ( (iflag & (IGNBRK|PARMRK|BRKINT|IGNPAR))
2642 ^ ( o_tios->c_iflag & (IGNBRK|PARMRK|BRKINT|IGNPAR)) )
2644 char brkrpt = 0;
2645 char parrpt = 0;
2647 if ( iflag & IGNBRK ) { /* Ignore breaks altogether */
2648 /* Ignore breaks altogether */
2649 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_BRK_NREP);
2650 } else {
2651 if ( iflag & BRKINT ) {
2652 if ( iflag & PARMRK ) {
2653 brkrpt = 0x0a; // exception an inline triple
2654 } else {
2655 brkrpt = 0x1a; // exception and NULL
2657 brkrpt |= 0x04; // flush input
2658 } else {
2659 if ( iflag & PARMRK ) {
2660 brkrpt = 0x0b; //POSIX triple \0377 \0 \0
2661 } else {
2662 brkrpt = 0x01; // Null only
2665 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_BRK_REP(brkrpt));
2668 if (iflag & IGNPAR) {
2669 parrpt = 0x20;
2670 /* would be 2 for not cirrus bug */
2671 /* would be 0x20 cept for cirrus bug */
2672 } else {
2673 if ( iflag & PARMRK ) {
2675 * Replace error characters with 3-byte sequence (\0377,\0,char)
2677 parrpt = 0x04 ;
2678 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_ISTRIP_OPT((char)0));
2679 } else {
2680 parrpt = 0x03;
2683 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_SET_ERROR(parrpt));
2685 if (cflag & CLOCAL) {
2686 // Status reporting fails for DCD if this is off
2687 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DCD_NREP);
2688 pCh->flags &= ~ASYNC_CHECK_CD;
2689 } else {
2690 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DCD_REP);
2691 pCh->flags |= ASYNC_CHECK_CD;
2694 #ifdef XXX
2695 do_flags_thing: // This is a test, we don't do the flags thing
2697 if ( (cflag & CRTSCTS) ) {
2698 cflag |= 014000000000;
2700 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1,
2701 CMD_UNIX_FLAGS(iflag,cflag,lflag));
2702 #endif
2704 service_it:
2705 i2DrainOutput( pCh, 100 );
2708 /******************************************************************************/
2709 /* IPL Device Section */
2710 /******************************************************************************/
2712 /******************************************************************************/
2713 /* Function: ip2_ipl_read() */
2714 /* Parameters: Pointer to device inode */
2715 /* Pointer to file structure */
2716 /* Pointer to data */
2717 /* Number of bytes to read */
2718 /* Returns: Success or failure */
2719 /* */
2720 /* Description: Ugly */
2721 /* */
2722 /* */
2723 /******************************************************************************/
2725 static
2726 ssize_t
2727 ip2_ipl_read(struct file *pFile, char __user *pData, size_t count, loff_t *off )
2729 unsigned int minor = iminor(pFile->f_dentry->d_inode);
2730 int rc = 0;
2732 #ifdef IP2DEBUG_IPL
2733 printk (KERN_DEBUG "IP2IPL: read %p, %d bytes\n", pData, count );
2734 #endif
2736 switch( minor ) {
2737 case 0: // IPL device
2738 rc = -EINVAL;
2739 break;
2740 case 1: // Status dump
2741 rc = -EINVAL;
2742 break;
2743 case 2: // Ping device
2744 rc = -EINVAL;
2745 break;
2746 case 3: // Trace device
2747 rc = DumpTraceBuffer ( pData, count );
2748 break;
2749 case 4: // Trace device
2750 rc = DumpFifoBuffer ( pData, count );
2751 break;
2752 default:
2753 rc = -ENODEV;
2754 break;
2756 return rc;
2759 static int
2760 DumpFifoBuffer ( char __user *pData, int count )
2762 #ifdef DEBUG_FIFO
2763 int rc;
2764 rc = copy_to_user(pData, DBGBuf, count);
2766 printk(KERN_DEBUG "Last index %d\n", I );
2768 return count;
2769 #endif /* DEBUG_FIFO */
2770 return 0;
2773 static int
2774 DumpTraceBuffer ( char __user *pData, int count )
2776 #ifdef IP2DEBUG_TRACE
2777 int rc;
2778 int dumpcount;
2779 int chunk;
2780 int *pIndex = (int __user *)pData;
2782 if ( count < (sizeof(int) * 6) ) {
2783 return -EIO;
2785 rc = put_user(tracewrap, pIndex );
2786 rc = put_user(TRACEMAX, ++pIndex );
2787 rc = put_user(tracestrip, ++pIndex );
2788 rc = put_user(tracestuff, ++pIndex );
2789 pData += sizeof(int) * 6;
2790 count -= sizeof(int) * 6;
2792 dumpcount = tracestuff - tracestrip;
2793 if ( dumpcount < 0 ) {
2794 dumpcount += TRACEMAX;
2796 if ( dumpcount > count ) {
2797 dumpcount = count;
2799 chunk = TRACEMAX - tracestrip;
2800 if ( dumpcount > chunk ) {
2801 rc = copy_to_user(pData, &tracebuf[tracestrip],
2802 chunk * sizeof(tracebuf[0]) );
2803 pData += chunk * sizeof(tracebuf[0]);
2804 tracestrip = 0;
2805 chunk = dumpcount - chunk;
2806 } else {
2807 chunk = dumpcount;
2809 rc = copy_to_user(pData, &tracebuf[tracestrip],
2810 chunk * sizeof(tracebuf[0]) );
2811 tracestrip += chunk;
2812 tracewrap = 0;
2814 rc = put_user(tracestrip, ++pIndex );
2815 rc = put_user(tracestuff, ++pIndex );
2817 return dumpcount;
2818 #else
2819 return 0;
2820 #endif
2823 /******************************************************************************/
2824 /* Function: ip2_ipl_write() */
2825 /* Parameters: */
2826 /* Pointer to file structure */
2827 /* Pointer to data */
2828 /* Number of bytes to write */
2829 /* Returns: Success or failure */
2830 /* */
2831 /* Description: */
2832 /* */
2833 /* */
2834 /******************************************************************************/
2835 static ssize_t
2836 ip2_ipl_write(struct file *pFile, const char __user *pData, size_t count, loff_t *off)
2838 #ifdef IP2DEBUG_IPL
2839 printk (KERN_DEBUG "IP2IPL: write %p, %d bytes\n", pData, count );
2840 #endif
2841 return 0;
2844 /******************************************************************************/
2845 /* Function: ip2_ipl_ioctl() */
2846 /* Parameters: Pointer to device inode */
2847 /* Pointer to file structure */
2848 /* Command */
2849 /* Argument */
2850 /* Returns: Success or failure */
2851 /* */
2852 /* Description: */
2853 /* */
2854 /* */
2855 /******************************************************************************/
2856 static int
2857 ip2_ipl_ioctl ( struct inode *pInode, struct file *pFile, UINT cmd, ULONG arg )
2859 unsigned int iplminor = iminor(pInode);
2860 int rc = 0;
2861 void __user *argp = (void __user *)arg;
2862 ULONG __user *pIndex = argp;
2863 i2eBordStrPtr pB = i2BoardPtrTable[iplminor / 4];
2864 i2ChanStrPtr pCh;
2866 #ifdef IP2DEBUG_IPL
2867 printk (KERN_DEBUG "IP2IPL: ioctl cmd %d, arg %ld\n", cmd, arg );
2868 #endif
2870 switch ( iplminor ) {
2871 case 0: // IPL device
2872 rc = -EINVAL;
2873 break;
2874 case 1: // Status dump
2875 case 5:
2876 case 9:
2877 case 13:
2878 switch ( cmd ) {
2879 case 64: /* Driver - ip2stat */
2880 rc = put_user(ip2_tty_driver->refcount, pIndex++ );
2881 rc = put_user(irq_counter, pIndex++ );
2882 rc = put_user(bh_counter, pIndex++ );
2883 break;
2885 case 65: /* Board - ip2stat */
2886 if ( pB ) {
2887 rc = copy_to_user(argp, pB, sizeof(i2eBordStr));
2888 rc = put_user(INB(pB->i2eStatus),
2889 (ULONG __user *)(arg + (ULONG)(&pB->i2eStatus) - (ULONG)pB ) );
2890 } else {
2891 rc = -ENODEV;
2893 break;
2895 default:
2896 if (cmd < IP2_MAX_PORTS) {
2897 pCh = DevTable[cmd];
2898 if ( pCh )
2900 rc = copy_to_user(argp, pCh, sizeof(i2ChanStr));
2901 } else {
2902 rc = -ENODEV;
2904 } else {
2905 rc = -EINVAL;
2908 break;
2910 case 2: // Ping device
2911 rc = -EINVAL;
2912 break;
2913 case 3: // Trace device
2914 if ( cmd == 1 ) {
2915 rc = put_user(iiSendPendingMail, pIndex++ );
2916 rc = put_user(i2InitChannels, pIndex++ );
2917 rc = put_user(i2QueueNeeds, pIndex++ );
2918 rc = put_user(i2QueueCommands, pIndex++ );
2919 rc = put_user(i2GetStatus, pIndex++ );
2920 rc = put_user(i2Input, pIndex++ );
2921 rc = put_user(i2InputFlush, pIndex++ );
2922 rc = put_user(i2Output, pIndex++ );
2923 rc = put_user(i2FlushOutput, pIndex++ );
2924 rc = put_user(i2DrainWakeup, pIndex++ );
2925 rc = put_user(i2DrainOutput, pIndex++ );
2926 rc = put_user(i2OutputFree, pIndex++ );
2927 rc = put_user(i2StripFifo, pIndex++ );
2928 rc = put_user(i2StuffFifoBypass, pIndex++ );
2929 rc = put_user(i2StuffFifoFlow, pIndex++ );
2930 rc = put_user(i2StuffFifoInline, pIndex++ );
2931 rc = put_user(i2ServiceBoard, pIndex++ );
2932 rc = put_user(serviceOutgoingFifo, pIndex++ );
2933 // rc = put_user(ip2_init, pIndex++ );
2934 rc = put_user(ip2_init_board, pIndex++ );
2935 rc = put_user(find_eisa_board, pIndex++ );
2936 rc = put_user(set_irq, pIndex++ );
2937 rc = put_user(ip2_interrupt, pIndex++ );
2938 rc = put_user(ip2_poll, pIndex++ );
2939 rc = put_user(service_all_boards, pIndex++ );
2940 rc = put_user(do_input, pIndex++ );
2941 rc = put_user(do_status, pIndex++ );
2942 #ifndef IP2DEBUG_OPEN
2943 rc = put_user(0, pIndex++ );
2944 #else
2945 rc = put_user(open_sanity_check, pIndex++ );
2946 #endif
2947 rc = put_user(ip2_open, pIndex++ );
2948 rc = put_user(ip2_close, pIndex++ );
2949 rc = put_user(ip2_hangup, pIndex++ );
2950 rc = put_user(ip2_write, pIndex++ );
2951 rc = put_user(ip2_putchar, pIndex++ );
2952 rc = put_user(ip2_flush_chars, pIndex++ );
2953 rc = put_user(ip2_write_room, pIndex++ );
2954 rc = put_user(ip2_chars_in_buf, pIndex++ );
2955 rc = put_user(ip2_flush_buffer, pIndex++ );
2957 //rc = put_user(ip2_wait_until_sent, pIndex++ );
2958 rc = put_user(0, pIndex++ );
2960 rc = put_user(ip2_throttle, pIndex++ );
2961 rc = put_user(ip2_unthrottle, pIndex++ );
2962 rc = put_user(ip2_ioctl, pIndex++ );
2963 rc = put_user(0, pIndex++ );
2964 rc = put_user(get_serial_info, pIndex++ );
2965 rc = put_user(set_serial_info, pIndex++ );
2966 rc = put_user(ip2_set_termios, pIndex++ );
2967 rc = put_user(ip2_set_line_discipline, pIndex++ );
2968 rc = put_user(set_params, pIndex++ );
2969 } else {
2970 rc = -EINVAL;
2973 break;
2975 default:
2976 rc = -ENODEV;
2977 break;
2979 return rc;
2982 /******************************************************************************/
2983 /* Function: ip2_ipl_open() */
2984 /* Parameters: Pointer to device inode */
2985 /* Pointer to file structure */
2986 /* Returns: Success or failure */
2987 /* */
2988 /* Description: */
2989 /* */
2990 /* */
2991 /******************************************************************************/
2992 static int
2993 ip2_ipl_open( struct inode *pInode, struct file *pFile )
2995 unsigned int iplminor = iminor(pInode);
2996 i2eBordStrPtr pB;
2997 i2ChanStrPtr pCh;
2999 #ifdef IP2DEBUG_IPL
3000 printk (KERN_DEBUG "IP2IPL: open\n" );
3001 #endif
3003 switch(iplminor) {
3004 // These are the IPL devices
3005 case 0:
3006 case 4:
3007 case 8:
3008 case 12:
3009 break;
3011 // These are the status devices
3012 case 1:
3013 case 5:
3014 case 9:
3015 case 13:
3016 break;
3018 // These are the debug devices
3019 case 2:
3020 case 6:
3021 case 10:
3022 case 14:
3023 pB = i2BoardPtrTable[iplminor / 4];
3024 pCh = (i2ChanStrPtr) pB->i2eChannelPtr;
3025 break;
3027 // This is the trace device
3028 case 3:
3029 break;
3031 return 0;
3033 /******************************************************************************/
3034 /* Function: ip2_read_procmem */
3035 /* Parameters: */
3036 /* */
3037 /* Returns: Length of output */
3038 /* */
3039 /* Description: */
3040 /* Supplies some driver operating parameters */
3041 /* Not real useful unless your debugging the fifo */
3042 /* */
3043 /******************************************************************************/
3045 #define LIMIT (PAGE_SIZE - 120)
3047 static int
3048 ip2_read_procmem(char *buf, char **start, off_t offset, int len)
3050 i2eBordStrPtr pB;
3051 i2ChanStrPtr pCh;
3052 PTTY tty;
3053 int i;
3055 len = 0;
3057 #define FMTLINE "%3d: 0x%08x 0x%08x 0%011o 0%011o\n"
3058 #define FMTLIN2 " 0x%04x 0x%04x tx flow 0x%x\n"
3059 #define FMTLIN3 " 0x%04x 0x%04x rc flow\n"
3061 len += sprintf(buf+len,"\n");
3063 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
3064 pB = i2BoardPtrTable[i];
3065 if ( pB ) {
3066 len += sprintf(buf+len,"board %d:\n",i);
3067 len += sprintf(buf+len,"\tFifo rem: %d mty: %x outM %x\n",
3068 pB->i2eFifoRemains,pB->i2eWaitingForEmptyFifo,pB->i2eOutMailWaiting);
3072 len += sprintf(buf+len,"#: tty flags, port flags, cflags, iflags\n");
3073 for (i=0; i < IP2_MAX_PORTS; i++) {
3074 if (len > LIMIT)
3075 break;
3076 pCh = DevTable[i];
3077 if (pCh) {
3078 tty = pCh->pTTY;
3079 if (tty && tty->count) {
3080 len += sprintf(buf+len,FMTLINE,i,(int)tty->flags,pCh->flags,
3081 tty->termios->c_cflag,tty->termios->c_iflag);
3083 len += sprintf(buf+len,FMTLIN2,
3084 pCh->outfl.asof,pCh->outfl.room,pCh->channelNeeds);
3085 len += sprintf(buf+len,FMTLIN3,pCh->infl.asof,pCh->infl.room);
3089 return len;
3093 * This is the handler for /proc/tty/driver/ip2
3095 * This stretch of code has been largely plagerized from at least three
3096 * different sources including ip2mkdev.c and a couple of other drivers.
3097 * The bugs are all mine. :-) =mhw=
3099 static int ip2_read_proc(char *page, char **start, off_t off,
3100 int count, int *eof, void *data)
3102 int i, j, box;
3103 int len = 0;
3104 int boxes = 0;
3105 int ports = 0;
3106 int tports = 0;
3107 off_t begin = 0;
3108 i2eBordStrPtr pB;
3110 len += sprintf(page, "ip2info: 1.0 driver: %s\n", pcVersion );
3111 len += sprintf(page+len, "Driver: SMajor=%d CMajor=%d IMajor=%d MaxBoards=%d MaxBoxes=%d MaxPorts=%d\n",
3112 IP2_TTY_MAJOR, IP2_CALLOUT_MAJOR, IP2_IPL_MAJOR,
3113 IP2_MAX_BOARDS, ABS_MAX_BOXES, ABS_BIGGEST_BOX);
3115 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
3116 /* This need to be reset for a board by board count... */
3117 boxes = 0;
3118 pB = i2BoardPtrTable[i];
3119 if( pB ) {
3120 switch( pB->i2ePom.e.porID & ~POR_ID_RESERVED )
3122 case POR_ID_FIIEX:
3123 len += sprintf( page+len, "Board %d: EX ports=", i );
3124 for( box = 0; box < ABS_MAX_BOXES; ++box )
3126 ports = 0;
3128 if( pB->i2eChannelMap[box] != 0 ) ++boxes;
3129 for( j = 0; j < ABS_BIGGEST_BOX; ++j )
3131 if( pB->i2eChannelMap[box] & 1<< j ) {
3132 ++ports;
3135 len += sprintf( page+len, "%d,", ports );
3136 tports += ports;
3139 --len; /* Backup over that last comma */
3141 len += sprintf( page+len, " boxes=%d width=%d", boxes, pB->i2eDataWidth16 ? 16 : 8 );
3142 break;
3144 case POR_ID_II_4:
3145 len += sprintf(page+len, "Board %d: ISA-4 ports=4 boxes=1", i );
3146 tports = ports = 4;
3147 break;
3149 case POR_ID_II_8:
3150 len += sprintf(page+len, "Board %d: ISA-8-std ports=8 boxes=1", i );
3151 tports = ports = 8;
3152 break;
3154 case POR_ID_II_8R:
3155 len += sprintf(page+len, "Board %d: ISA-8-RJ11 ports=8 boxes=1", i );
3156 tports = ports = 8;
3157 break;
3159 default:
3160 len += sprintf(page+len, "Board %d: unknown", i );
3161 /* Don't try and probe for minor numbers */
3162 tports = ports = 0;
3165 } else {
3166 /* Don't try and probe for minor numbers */
3167 len += sprintf(page+len, "Board %d: vacant", i );
3168 tports = ports = 0;
3171 if( tports ) {
3172 len += sprintf(page+len, " minors=" );
3174 for ( box = 0; box < ABS_MAX_BOXES; ++box )
3176 for ( j = 0; j < ABS_BIGGEST_BOX; ++j )
3178 if ( pB->i2eChannelMap[box] & (1 << j) )
3180 len += sprintf (page+len,"%d,",
3181 j + ABS_BIGGEST_BOX *
3182 (box+i*ABS_MAX_BOXES));
3187 page[ len - 1 ] = '\n'; /* Overwrite that last comma */
3188 } else {
3189 len += sprintf (page+len,"\n" );
3192 if (len+begin > off+count)
3193 break;
3194 if (len+begin < off) {
3195 begin += len;
3196 len = 0;
3200 if (i >= IP2_MAX_BOARDS)
3201 *eof = 1;
3202 if (off >= len+begin)
3203 return 0;
3205 *start = page + (off-begin);
3206 return ((count < begin+len-off) ? count : begin+len-off);
3209 /******************************************************************************/
3210 /* Function: ip2trace() */
3211 /* Parameters: Value to add to trace buffer */
3212 /* Returns: Nothing */
3213 /* */
3214 /* Description: */
3215 /* */
3216 /* */
3217 /******************************************************************************/
3218 #ifdef IP2DEBUG_TRACE
3219 void
3220 ip2trace (unsigned short pn, unsigned char cat, unsigned char label, unsigned long codes, ...)
3222 long flags;
3223 unsigned long *pCode = &codes;
3224 union ip2breadcrumb bc;
3225 i2ChanStrPtr pCh;
3228 tracebuf[tracestuff++] = jiffies;
3229 if ( tracestuff == TRACEMAX ) {
3230 tracestuff = 0;
3232 if ( tracestuff == tracestrip ) {
3233 if ( ++tracestrip == TRACEMAX ) {
3234 tracestrip = 0;
3236 ++tracewrap;
3239 bc.hdr.port = 0xff & pn;
3240 bc.hdr.cat = cat;
3241 bc.hdr.codes = (unsigned char)( codes & 0xff );
3242 bc.hdr.label = label;
3243 tracebuf[tracestuff++] = bc.value;
3245 for (;;) {
3246 if ( tracestuff == TRACEMAX ) {
3247 tracestuff = 0;
3249 if ( tracestuff == tracestrip ) {
3250 if ( ++tracestrip == TRACEMAX ) {
3251 tracestrip = 0;
3253 ++tracewrap;
3256 if ( !codes-- )
3257 break;
3259 tracebuf[tracestuff++] = *++pCode;
3262 #endif
3265 MODULE_LICENSE("GPL");