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