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