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