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