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