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