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