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