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