Merge ../linux-2.6 by hand
[pandora-kernel.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 #include <linux/bitops.h>
116
117 #include <asm/system.h>
118 #include <asm/io.h>
119 #include <asm/irq.h>
120
121 #include <linux/vmalloc.h>
122 #include <linux/init.h>
123
124 #include <asm/uaccess.h>
125
126 #include "./ip2/ip2types.h"
127 #include "./ip2/ip2trace.h"
128 #include "./ip2/ip2ioctl.h"
129 #include "./ip2/ip2.h"
130 #include "./ip2/i2ellis.h"
131 #include "./ip2/i2lib.h"
132
133 /*****************
134  * /proc/ip2mem  *
135  *****************/
136
137 #include <linux/proc_fs.h>
138
139 static int ip2_read_procmem(char *, char **, off_t, int);
140 static int ip2_read_proc(char *, char **, off_t, int, int *, void * );
141
142 /********************/
143 /* Type Definitions */
144 /********************/
145
146 /*************/
147 /* Constants */
148 /*************/
149
150 /* String constants to identify ourselves */
151 static char *pcName    = "Computone IntelliPort Plus multiport driver";
152 static char *pcVersion = "1.2.14";
153
154 /* String constants for port names */
155 static char *pcDriver_name   = "ip2";
156 static char *pcIpl               = "ip2ipl";
157
158 /* Serial subtype definitions */
159 #define SERIAL_TYPE_NORMAL    1
160
161 // cheezy kludge or genius - you decide?
162 int ip2_loadmain(int *, int *, unsigned char *, int);
163 static unsigned char *Fip_firmware;
164 static int Fip_firmware_size;
165
166 /***********************/
167 /* Function Prototypes */
168 /***********************/
169
170 /* Global module entry functions */
171
172 /* Private (static) functions */
173 static int  ip2_open(PTTY, struct file *);
174 static void ip2_close(PTTY, struct file *);
175 static int  ip2_write(PTTY, int, const unsigned char *, int);
176 static void ip2_putchar(PTTY, unsigned char);
177 static void ip2_flush_chars(PTTY);
178 static int  ip2_write_room(PTTY);
179 static int  ip2_chars_in_buf(PTTY);
180 static void ip2_flush_buffer(PTTY);
181 static int  ip2_ioctl(PTTY, struct file *, UINT, ULONG);
182 static void ip2_set_termios(PTTY, struct termios *);
183 static void ip2_set_line_discipline(PTTY);
184 static void ip2_throttle(PTTY);
185 static void ip2_unthrottle(PTTY);
186 static void ip2_stop(PTTY);
187 static void ip2_start(PTTY);
188 static void ip2_hangup(PTTY);
189 static int  ip2_tiocmget(struct tty_struct *tty, struct file *file);
190 static int  ip2_tiocmset(struct tty_struct *tty, struct file *file,
191                          unsigned int set, unsigned int clear);
192
193 static void set_irq(int, int);
194 static void ip2_interrupt_bh(i2eBordStrPtr pB);
195 static irqreturn_t ip2_interrupt(int irq, void *dev_id, struct pt_regs * regs);
196 static void ip2_poll(unsigned long arg);
197 static inline void service_all_boards(void);
198 static void do_input(void *p);
199 static void do_status(void *p);
200
201 static void ip2_wait_until_sent(PTTY,int);
202
203 static void set_params (i2ChanStrPtr, struct termios *);
204 static int get_serial_info(i2ChanStrPtr, struct serial_struct __user *);
205 static int set_serial_info(i2ChanStrPtr, struct serial_struct __user *);
206
207 static ssize_t ip2_ipl_read(struct file *, char __user *, size_t, loff_t *);
208 static ssize_t ip2_ipl_write(struct file *, const char __user *, size_t, loff_t *);
209 static int ip2_ipl_ioctl(struct inode *, struct file *, UINT, ULONG);
210 static int ip2_ipl_open(struct inode *, struct file *);
211
212 static int DumpTraceBuffer(char __user *, int);
213 static int DumpFifoBuffer( char __user *, int);
214
215 static void ip2_init_board(int);
216 static unsigned short find_eisa_board(int);
217
218 /***************/
219 /* Static Data */
220 /***************/
221
222 static struct tty_driver *ip2_tty_driver;
223
224 /* Here, then is a table of board pointers which the interrupt routine should
225  * scan through to determine who it must service.
226  */
227 static unsigned short i2nBoards; // Number of boards here
228
229 static i2eBordStrPtr i2BoardPtrTable[IP2_MAX_BOARDS];
230
231 static i2ChanStrPtr  DevTable[IP2_MAX_PORTS];
232 //DevTableMem just used to save addresses for kfree
233 static void  *DevTableMem[IP2_MAX_BOARDS];
234
235 /* This is the driver descriptor for the ip2ipl device, which is used to
236  * download the loadware to the boards.
237  */
238 static struct file_operations ip2_ipl = {
239         .owner          = THIS_MODULE,
240         .read           = ip2_ipl_read,
241         .write          = ip2_ipl_write,
242         .ioctl          = ip2_ipl_ioctl,
243         .open           = ip2_ipl_open,
244 }; 
245
246 static unsigned long irq_counter = 0;
247 static unsigned long bh_counter = 0;
248
249 // Use immediate queue to service interrupts
250 #define USE_IQI
251 //#define USE_IQ        // PCI&2.2 needs work
252
253 /* The timer_list entry for our poll routine. If interrupt operation is not
254  * selected, the board is serviced periodically to see if anything needs doing.
255  */
256 #define  POLL_TIMEOUT   (jiffies + 1)
257 static DEFINE_TIMER(PollTimer, ip2_poll, 0, 0);
258 static char  TimerOn;
259
260 #ifdef IP2DEBUG_TRACE
261 /* Trace (debug) buffer data */
262 #define TRACEMAX  1000
263 static unsigned long tracebuf[TRACEMAX];
264 static int tracestuff;
265 static int tracestrip;
266 static int tracewrap;
267 #endif
268
269 /**********/
270 /* Macros */
271 /**********/
272
273 #if defined(MODULE) && defined(IP2DEBUG_OPEN)
274 #define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] refc=%d, ttyc=%d, modc=%x -> %s\n", \
275                     tty->name,(pCh->flags),ip2_tty_driver->refcount, \
276                     tty->count,/*GET_USE_COUNT(module)*/0,s)
277 #else
278 #define DBG_CNT(s)
279 #endif
280
281 /********/
282 /* Code */
283 /********/
284
285 #include "./ip2/i2ellis.c"    /* Extremely low-level interface services */
286 #include "./ip2/i2cmd.c"      /* Standard loadware command definitions */
287 #include "./ip2/i2lib.c"      /* High level interface services */
288
289 /* Configuration area for modprobe */
290
291 MODULE_AUTHOR("Doug McNash");
292 MODULE_DESCRIPTION("Computone IntelliPort Plus Driver");
293
294 static int poll_only = 0;
295
296 static int Eisa_irq;
297 static int Eisa_slot;
298
299 static int iindx;
300 static char rirqs[IP2_MAX_BOARDS];
301 static int Valid_Irqs[] = { 3, 4, 5, 7, 10, 11, 12, 15, 0};
302
303 /* for sysfs class support */
304 static struct class *ip2_class;
305
306 // Some functions to keep track of what irq's we have
307
308 static int __init
309 is_valid_irq(int irq)
310 {
311         int *i = Valid_Irqs;
312         
313         while ((*i != 0) && (*i != irq)) {
314                 i++;
315         }
316         return (*i);
317 }
318
319 static void __init
320 mark_requested_irq( char irq )
321 {
322         rirqs[iindx++] = irq;
323 }
324
325 #ifdef MODULE
326 static int __init
327 clear_requested_irq( char irq )
328 {
329         int i;
330         for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
331                 if (rirqs[i] == irq) {
332                         rirqs[i] = 0;
333                         return 1;
334                 }
335         }
336         return 0;
337 }
338 #endif
339
340 static int __init
341 have_requested_irq( char irq )
342 {
343         // array init to zeros so 0 irq will not be requested as a side effect
344         int i;
345         for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
346                 if (rirqs[i] == irq)
347                         return 1;
348         }
349         return 0;
350 }
351
352 /******************************************************************************/
353 /* Function:   init_module()                                                  */
354 /* Parameters: None                                                           */
355 /* Returns:    Success (0)                                                    */
356 /*                                                                            */
357 /* Description:                                                               */
358 /* This is a required entry point for an installable module. It simply calls  */
359 /* the driver initialisation function and returns what it returns.            */
360 /******************************************************************************/
361 #ifdef MODULE
362 int
363 init_module(void)
364 {
365 #ifdef IP2DEBUG_INIT
366         printk (KERN_DEBUG "Loading module ...\n" );
367 #endif
368     return 0;
369 }
370 #endif /* MODULE */
371
372 /******************************************************************************/
373 /* Function:   cleanup_module()                                               */
374 /* Parameters: None                                                           */
375 /* Returns:    Nothing                                                        */
376 /*                                                                            */
377 /* Description:                                                               */
378 /* This is a required entry point for an installable module. It has to return */
379 /* the device and the driver to a passive state. It should not be necessary   */
380 /* to reset the board fully, especially as the loadware is downloaded         */
381 /* externally rather than in the driver. We just want to disable the board    */
382 /* and clear the loadware to a reset state. To allow this there has to be a   */
383 /* way to detect whether the board has the loadware running at init time to   */
384 /* handle subsequent installations of the driver. All memory allocated by the */
385 /* driver should be returned since it may be unloaded from memory.            */
386 /******************************************************************************/
387 #ifdef MODULE
388 void
389 cleanup_module(void)
390 {
391         int err;
392         int i;
393
394 #ifdef IP2DEBUG_INIT
395         printk (KERN_DEBUG "Unloading %s: version %s\n", pcName, pcVersion );
396 #endif
397         /* Stop poll timer if we had one. */
398         if ( TimerOn ) {
399                 del_timer ( &PollTimer );
400                 TimerOn = 0;
401         }
402
403         /* Reset the boards we have. */
404         for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
405                 if ( i2BoardPtrTable[i] ) {
406                         iiReset( i2BoardPtrTable[i] );
407                 }
408         }
409
410         /* The following is done at most once, if any boards were installed. */
411         for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
412                 if ( i2BoardPtrTable[i] ) {
413                         iiResetDelay( i2BoardPtrTable[i] );
414                         /* free io addresses and Tibet */
415                         release_region( ip2config.addr[i], 8 );
416                         class_device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i));
417                         devfs_remove("ip2/ipl%d", i);
418                         class_device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i + 1));
419                         devfs_remove("ip2/stat%d", i);
420                 }
421                 /* Disable and remove interrupt handler. */
422                 if ( (ip2config.irq[i] > 0) && have_requested_irq(ip2config.irq[i]) ) { 
423                         free_irq ( ip2config.irq[i], (void *)&pcName);
424                         clear_requested_irq( ip2config.irq[i]);
425                 }
426         }
427         class_destroy(ip2_class);
428         devfs_remove("ip2");
429         if ( ( err = tty_unregister_driver ( ip2_tty_driver ) ) ) {
430                 printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n", err);
431         }
432         put_tty_driver(ip2_tty_driver);
433         if ( ( err = unregister_chrdev ( IP2_IPL_MAJOR, pcIpl ) ) ) {
434                 printk(KERN_ERR "IP2: failed to unregister IPL driver (%d)\n", err);
435         }
436         remove_proc_entry("ip2mem", &proc_root);
437
438         // free memory
439         for (i = 0; i < IP2_MAX_BOARDS; i++) {
440                 void *pB;
441 #ifdef CONFIG_PCI
442                 if (ip2config.type[i] == PCI && ip2config.pci_dev[i]) {
443                         pci_disable_device(ip2config.pci_dev[i]);
444                         ip2config.pci_dev[i] = NULL;
445                 }
446 #endif
447                 if ((pB = i2BoardPtrTable[i]) != 0 ) {
448                         kfree ( pB );
449                         i2BoardPtrTable[i] = NULL;
450                 }
451                 if ((DevTableMem[i]) != NULL ) {
452                         kfree ( DevTableMem[i]  );
453                         DevTableMem[i] = NULL;
454                 }
455         }
456
457         /* Cleanup the iiEllis subsystem. */
458         iiEllisCleanup();
459 #ifdef IP2DEBUG_INIT
460         printk (KERN_DEBUG "IP2 Unloaded\n" );
461 #endif
462 }
463 #endif /* MODULE */
464
465 static struct tty_operations ip2_ops = {
466         .open            = ip2_open,
467         .close           = ip2_close,
468         .write           = ip2_write,
469         .put_char        = ip2_putchar,
470         .flush_chars     = ip2_flush_chars,
471         .write_room      = ip2_write_room,
472         .chars_in_buffer = ip2_chars_in_buf,
473         .flush_buffer    = ip2_flush_buffer,
474         .ioctl           = ip2_ioctl,
475         .throttle        = ip2_throttle,
476         .unthrottle      = ip2_unthrottle,
477         .set_termios     = ip2_set_termios,
478         .set_ldisc       = ip2_set_line_discipline,
479         .stop            = ip2_stop,
480         .start           = ip2_start,
481         .hangup          = ip2_hangup,
482         .read_proc       = ip2_read_proc,
483         .tiocmget        = ip2_tiocmget,
484         .tiocmset        = ip2_tiocmset,
485 };
486
487 /******************************************************************************/
488 /* Function:   ip2_loadmain()                                                 */
489 /* Parameters: irq, io from command line of insmod et. al.                    */
490 /*              pointer to fip firmware and firmware size for boards          */
491 /* Returns:    Success (0)                                                    */
492 /*                                                                            */
493 /* Description:                                                               */
494 /* This was the required entry point for all drivers (now in ip2.c)           */
495 /* It performs all                                                            */
496 /* initialisation of the devices and driver structures, and registers itself  */
497 /* with the relevant kernel modules.                                          */
498 /******************************************************************************/
499 /* SA_INTERRUPT- if set blocks all interrupts else only this line */
500 /* SA_SHIRQ    - for shared irq PCI or maybe EISA only */
501 /* SA_RANDOM   - can be source for cert. random number generators */
502 #define IP2_SA_FLAGS    0
503
504 int
505 ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) 
506 {
507         int i, j, box;
508         int err = 0;
509         int status = 0;
510         static int loaded;
511         i2eBordStrPtr pB = NULL;
512         int rc = -1;
513
514         ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0 );
515
516         /* process command line arguments to modprobe or
517                 insmod i.e. iop & irqp */
518         /* irqp and iop should ALWAYS be specified now...  But we check
519                 them individually just to be sure, anyways... */
520         for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
521                 if (iop) {
522                         ip2config.addr[i] = iop[i];
523                         if (irqp) {
524                                 if( irqp[i] >= 0 ) {
525                                         ip2config.irq[i] = irqp[i];
526                                 } else {
527                                         ip2config.irq[i] = 0;
528                                 }
529         // This is a little bit of a hack.  If poll_only=1 on command
530         // line back in ip2.c OR all IRQs on all specified boards are
531         // explicitly set to 0, then drop to poll only mode and override
532         // PCI or EISA interrupts.  This superceeds the old hack of
533         // triggering if all interrupts were zero (like da default).
534         // Still a hack but less prone to random acts of terrorism.
535         //
536         // What we really should do, now that the IRQ default is set
537         // to -1, is to use 0 as a hard coded, do not probe.
538         //
539         //      /\/\|=mhw=|\/\/
540                                 poll_only |= irqp[i];
541                         }
542                 }
543         }
544         poll_only = !poll_only;
545
546         Fip_firmware = firmware;
547         Fip_firmware_size = firmsize;
548
549         /* Announce our presence */
550         printk( KERN_INFO "%s version %s\n", pcName, pcVersion );
551
552         // ip2 can be unloaded and reloaded for no good reason
553         // we can't let that happen here or bad things happen
554         // second load hoses board but not system - fixme later
555         if (loaded) {
556                 printk( KERN_INFO "Still loaded\n" );
557                 return 0;
558         }
559         loaded++;
560
561         ip2_tty_driver = alloc_tty_driver(IP2_MAX_PORTS);
562         if (!ip2_tty_driver)
563                 return -ENOMEM;
564
565         /* Initialise the iiEllis subsystem. */
566         iiEllisInit();
567
568         /* Initialize arrays. */
569         memset( i2BoardPtrTable, 0, sizeof i2BoardPtrTable );
570         memset( DevTable, 0, sizeof DevTable );
571
572         /* Initialise all the boards we can find (up to the maximum). */
573         for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
574                 switch ( ip2config.addr[i] ) { 
575                 case 0: /* skip this slot even if card is present */
576                         break;
577                 default: /* ISA */
578                    /* ISA address must be specified */
579                         if ( (ip2config.addr[i] < 0x100) || (ip2config.addr[i] > 0x3f8) ) {
580                                 printk ( KERN_ERR "IP2: Bad ISA board %d address %x\n",
581                                                          i, ip2config.addr[i] );
582                                 ip2config.addr[i] = 0;
583                         } else {
584                                 ip2config.type[i] = ISA;
585
586                                 /* Check for valid irq argument, set for polling if invalid */
587                                 if (ip2config.irq[i] && !is_valid_irq(ip2config.irq[i])) {
588                                         printk(KERN_ERR "IP2: Bad IRQ(%d) specified\n",ip2config.irq[i]);
589                                         ip2config.irq[i] = 0;// 0 is polling and is valid in that sense
590                                 }
591                         }
592                         break;
593                 case PCI:
594 #ifdef CONFIG_PCI
595                         {
596                                 struct pci_dev *pci_dev_i = NULL;
597                                 pci_dev_i = pci_find_device(PCI_VENDOR_ID_COMPUTONE,
598                                                           PCI_DEVICE_ID_COMPUTONE_IP2EX, pci_dev_i);
599                                 if (pci_dev_i != NULL) {
600                                         unsigned int addr;
601
602                                         if (pci_enable_device(pci_dev_i)) {
603                                                 printk( KERN_ERR "IP2: can't enable PCI device at %s\n",
604                                                         pci_name(pci_dev_i));
605                                                 break;
606                                         }
607                                         ip2config.type[i] = PCI;
608                                         ip2config.pci_dev[i] = pci_dev_i;
609                                         status =
610                                         pci_read_config_dword(pci_dev_i, PCI_BASE_ADDRESS_1, &addr);
611                                         if ( addr & 1 ) {
612                                                 ip2config.addr[i]=(USHORT)(addr&0xfffe);
613                                         } else {
614                                                 printk( KERN_ERR "IP2: PCI I/O address error\n");
615                                         }
616
617 //              If the PCI BIOS assigned it, lets try and use it.  If we
618 //              can't acquire it or it screws up, deal with it then.
619
620 //                                      if (!is_valid_irq(pci_irq)) {
621 //                                              printk( KERN_ERR "IP2: Bad PCI BIOS IRQ(%d)\n",pci_irq);
622 //                                              pci_irq = 0;
623 //                                      }
624                                         ip2config.irq[i] = pci_dev_i->irq;
625                                 } else {        // ann error
626                                         ip2config.addr[i] = 0;
627                                         if (status == PCIBIOS_DEVICE_NOT_FOUND) {
628                                                 printk( KERN_ERR "IP2: PCI board %d not found\n", i );
629                                         } else {
630                                                 printk( KERN_ERR "IP2: PCI error 0x%x \n", status );
631                                         }
632                                 } 
633                         }
634 #else
635                         printk( KERN_ERR "IP2: PCI card specified but PCI support not\n");
636                         printk( KERN_ERR "IP2: configured in this kernel.\n");
637                         printk( KERN_ERR "IP2: Recompile kernel with CONFIG_PCI defined!\n");
638 #endif /* CONFIG_PCI */
639                         break;
640                 case EISA:
641                         if ( (ip2config.addr[i] = find_eisa_board( Eisa_slot + 1 )) != 0) {
642                                 /* Eisa_irq set as side effect, boo */
643                                 ip2config.type[i] = EISA;
644                         } 
645                         ip2config.irq[i] = Eisa_irq;
646                         break;
647                 }       /* switch */
648         }       /* for */
649         for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
650                 if ( ip2config.addr[i] ) {
651                         pB = kmalloc( sizeof(i2eBordStr), GFP_KERNEL);
652                         if ( pB != NULL ) {
653                                 i2BoardPtrTable[i] = pB;
654                                 memset( pB, 0, sizeof(i2eBordStr) );
655                                 iiSetAddress( pB, ip2config.addr[i], ii2DelayTimer );
656                                 iiReset( pB );
657                         } else {
658                                 printk(KERN_ERR "IP2: board memory allocation error\n");
659                         }
660                 }
661         }
662         for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
663                 if ( ( pB = i2BoardPtrTable[i] ) != NULL ) {
664                         iiResetDelay( pB );
665                         break;
666                 }
667         }
668         for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
669                 if ( i2BoardPtrTable[i] != NULL ) {
670                         ip2_init_board( i );
671                 }
672         }
673
674         ip2trace (ITRC_NO_PORT, ITRC_INIT, 2, 0 );
675
676         ip2_tty_driver->owner               = THIS_MODULE;
677         ip2_tty_driver->name                 = "ttyF";
678         ip2_tty_driver->devfs_name          = "tts/F";
679         ip2_tty_driver->driver_name          = pcDriver_name;
680         ip2_tty_driver->major                = IP2_TTY_MAJOR;
681         ip2_tty_driver->minor_start          = 0;
682         ip2_tty_driver->type                 = TTY_DRIVER_TYPE_SERIAL;
683         ip2_tty_driver->subtype              = SERIAL_TYPE_NORMAL;
684         ip2_tty_driver->init_termios         = tty_std_termios;
685         ip2_tty_driver->init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL;
686         ip2_tty_driver->flags                = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
687         tty_set_operations(ip2_tty_driver, &ip2_ops);
688
689         ip2trace (ITRC_NO_PORT, ITRC_INIT, 3, 0 );
690
691         /* Register the tty devices. */
692         if ( ( err = tty_register_driver ( ip2_tty_driver ) ) ) {
693                 printk(KERN_ERR "IP2: failed to register tty driver (%d)\n", err);
694                 put_tty_driver(ip2_tty_driver);
695                 return -EINVAL;
696         } else
697         /* Register the IPL driver. */
698         if ( ( err = register_chrdev ( IP2_IPL_MAJOR, pcIpl, &ip2_ipl ) ) ) {
699                 printk(KERN_ERR "IP2: failed to register IPL device (%d)\n", err );
700         } else {
701                 /* create the sysfs class */
702                 ip2_class = class_create(THIS_MODULE, "ip2");
703                 if (IS_ERR(ip2_class)) {
704                         err = PTR_ERR(ip2_class);
705                         goto out_chrdev;        
706                 }
707         }
708         /* Register the read_procmem thing */
709         if (!create_proc_info_entry("ip2mem",0,&proc_root,ip2_read_procmem)) {
710                 printk(KERN_ERR "IP2: failed to register read_procmem\n");
711         } else {
712
713         ip2trace (ITRC_NO_PORT, ITRC_INIT, 4, 0 );
714                 /* Register the interrupt handler or poll handler, depending upon the
715                  * specified interrupt.
716                  */
717
718                 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
719                         if ( 0 == ip2config.addr[i] ) {
720                                 continue;
721                         }
722
723                         if ( NULL != ( pB = i2BoardPtrTable[i] ) ) {
724                                 class_device_create(ip2_class, NULL,
725                                                 MKDEV(IP2_IPL_MAJOR, 4 * i),
726                                                 NULL, "ipl%d", i);
727                                 err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i),
728                                                 S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR,
729                                                 "ip2/ipl%d", i);
730                                 if (err) {
731                                         class_device_destroy(ip2_class,
732                                                 MKDEV(IP2_IPL_MAJOR, 4 * i));
733                                         goto out_class;
734                                 }
735
736                                 class_device_create(ip2_class, NULL,
737                                                 MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
738                                                 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_device_destroy(ip2_class,
744                                                 MKDEV(IP2_IPL_MAJOR, 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_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                         msleep_interruptible(jiffies_to_msecs(pCh->ClosingDelay));
1636                 }
1637                 wake_up_interruptible(&pCh->open_wait);
1638         }
1639
1640         pCh->flags &=~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1641         wake_up_interruptible(&pCh->close_wait);
1642
1643 #ifdef IP2DEBUG_OPEN
1644         DBG_CNT("ip2_close: after wakeups--");
1645 #endif
1646
1647
1648         ip2trace (CHANN, ITRC_CLOSE, ITRC_RETURN, 1, 1 );
1649
1650         return;
1651 }
1652
1653 /******************************************************************************/
1654 /* Function:   ip2_hangup()                                                   */
1655 /* Parameters: Pointer to tty structure                                       */
1656 /* Returns:    Nothing                                                        */
1657 /*                                                                            */
1658 /* Description:                                                               */
1659 /*                                                                            */
1660 /*                                                                            */
1661 /******************************************************************************/
1662 static void
1663 ip2_hangup ( PTTY tty )
1664 {
1665         i2ChanStrPtr  pCh = tty->driver_data;
1666
1667         if( !pCh ) {
1668                 return;
1669         }
1670
1671         ip2trace (CHANN, ITRC_HANGUP, ITRC_ENTER, 0 );
1672
1673         ip2_flush_buffer(tty);
1674
1675         /* disable DSS reporting */
1676
1677         i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_DCD_NREP);
1678         i2QueueCommands(PTYPE_INLINE, pCh, 0, 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB);
1679         if ( (tty->termios->c_cflag & HUPCL) ) {
1680                 i2QueueCommands(PTYPE_BYPASS, pCh, 0, 2, CMD_RTSDN, CMD_DTRDN);
1681                 pCh->dataSetOut &= ~(I2_DTR | I2_RTS);
1682                 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25));
1683         }
1684         i2QueueCommands(PTYPE_INLINE, pCh, 1, 3, 
1685                                 CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);
1686         serviceOutgoingFifo ( pCh->pMyBord );
1687
1688         wake_up_interruptible ( &pCh->delta_msr_wait );
1689
1690         pCh->flags &= ~ASYNC_NORMAL_ACTIVE;
1691         pCh->pTTY = NULL;
1692         wake_up_interruptible ( &pCh->open_wait );
1693
1694         ip2trace (CHANN, ITRC_HANGUP, ITRC_RETURN, 0 );
1695 }
1696
1697 /******************************************************************************/
1698 /******************************************************************************/
1699 /* Device Output Section                                                      */
1700 /******************************************************************************/
1701 /******************************************************************************/
1702
1703 /******************************************************************************/
1704 /* Function:   ip2_write()                                                    */
1705 /* Parameters: Pointer to tty structure                                       */
1706 /*             Flag denoting data is in user (1) or kernel (0) space          */
1707 /*             Pointer to data                                                */
1708 /*             Number of bytes to write                                       */
1709 /* Returns:    Number of bytes actually written                               */
1710 /*                                                                            */
1711 /* Description: (MANDATORY)                                                   */
1712 /*                                                                            */
1713 /*                                                                            */
1714 /******************************************************************************/
1715 static int
1716 ip2_write( PTTY tty, int user, const unsigned char *pData, int count)
1717 {
1718         i2ChanStrPtr  pCh = tty->driver_data;
1719         int bytesSent = 0;
1720         unsigned long flags;
1721
1722         ip2trace (CHANN, ITRC_WRITE, ITRC_ENTER, 2, count, -1 );
1723
1724         /* Flush out any buffered data left over from ip2_putchar() calls. */
1725         ip2_flush_chars( tty );
1726
1727         /* This is the actual move bit. Make sure it does what we need!!!!! */
1728         WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
1729         bytesSent = i2Output( pCh, pData, count, user );
1730         WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
1731
1732         ip2trace (CHANN, ITRC_WRITE, ITRC_RETURN, 1, bytesSent );
1733
1734         return bytesSent > 0 ? bytesSent : 0;
1735 }
1736
1737 /******************************************************************************/
1738 /* Function:   ip2_putchar()                                                  */
1739 /* Parameters: Pointer to tty structure                                       */
1740 /*             Character to write                                             */
1741 /* Returns:    Nothing                                                        */
1742 /*                                                                            */
1743 /* Description:                                                               */
1744 /*                                                                            */
1745 /*                                                                            */
1746 /******************************************************************************/
1747 static void
1748 ip2_putchar( PTTY tty, unsigned char ch )
1749 {
1750         i2ChanStrPtr  pCh = tty->driver_data;
1751         unsigned long flags;
1752
1753 //      ip2trace (CHANN, ITRC_PUTC, ITRC_ENTER, 1, ch );
1754
1755         WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
1756         pCh->Pbuf[pCh->Pbuf_stuff++] = ch;
1757         if ( pCh->Pbuf_stuff == sizeof pCh->Pbuf ) {
1758                 WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
1759                 ip2_flush_chars( tty );
1760         } else
1761                 WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
1762
1763 //      ip2trace (CHANN, ITRC_PUTC, ITRC_RETURN, 1, ch );
1764 }
1765
1766 /******************************************************************************/
1767 /* Function:   ip2_flush_chars()                                              */
1768 /* Parameters: Pointer to tty structure                                       */
1769 /* Returns:    Nothing                                                        */
1770 /*                                                                            */
1771 /* Description:                                                               */
1772 /*                                                                            */
1773 /******************************************************************************/
1774 static void
1775 ip2_flush_chars( PTTY tty )
1776 {
1777         int   strip;
1778         i2ChanStrPtr  pCh = tty->driver_data;
1779         unsigned long flags;
1780
1781         WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
1782         if ( pCh->Pbuf_stuff ) {
1783
1784 //              ip2trace (CHANN, ITRC_PUTC, 10, 1, strip );
1785
1786                 //
1787                 // We may need to restart i2Output if it does not fullfill this request
1788                 //
1789                 strip = i2Output( pCh, pCh->Pbuf, pCh->Pbuf_stuff, 0 );
1790                 if ( strip != pCh->Pbuf_stuff ) {
1791                         memmove( pCh->Pbuf, &pCh->Pbuf[strip], pCh->Pbuf_stuff - strip );
1792                 }
1793                 pCh->Pbuf_stuff -= strip;
1794         }
1795         WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
1796 }
1797
1798 /******************************************************************************/
1799 /* Function:   ip2_write_room()                                               */
1800 /* Parameters: Pointer to tty structure                                       */
1801 /* Returns:    Number of bytes that the driver can accept                     */
1802 /*                                                                            */
1803 /* Description:                                                               */
1804 /*                                                                            */
1805 /******************************************************************************/
1806 static int
1807 ip2_write_room ( PTTY tty )
1808 {
1809         int bytesFree;
1810         i2ChanStrPtr  pCh = tty->driver_data;
1811         unsigned long flags;
1812
1813         READ_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
1814         bytesFree = i2OutputFree( pCh ) - pCh->Pbuf_stuff;
1815         READ_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
1816
1817         ip2trace (CHANN, ITRC_WRITE, 11, 1, bytesFree );
1818
1819         return ((bytesFree > 0) ? bytesFree : 0);
1820 }
1821
1822 /******************************************************************************/
1823 /* Function:   ip2_chars_in_buf()                                             */
1824 /* Parameters: Pointer to tty structure                                       */
1825 /* Returns:    Number of bytes queued for transmission                        */
1826 /*                                                                            */
1827 /* Description:                                                               */
1828 /*                                                                            */
1829 /*                                                                            */
1830 /******************************************************************************/
1831 static int
1832 ip2_chars_in_buf ( PTTY tty )
1833 {
1834         i2ChanStrPtr  pCh = tty->driver_data;
1835         int rc;
1836         unsigned long flags;
1837
1838         ip2trace (CHANN, ITRC_WRITE, 12, 1, pCh->Obuf_char_count + pCh->Pbuf_stuff );
1839
1840 #ifdef IP2DEBUG_WRITE
1841         printk (KERN_DEBUG "IP2: chars in buffer = %d (%d,%d)\n",
1842                                  pCh->Obuf_char_count + pCh->Pbuf_stuff,
1843                                  pCh->Obuf_char_count, pCh->Pbuf_stuff );
1844 #endif
1845         READ_LOCK_IRQSAVE(&pCh->Obuf_spinlock,flags);
1846         rc =  pCh->Obuf_char_count;
1847         READ_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags);
1848         READ_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
1849         rc +=  pCh->Pbuf_stuff;
1850         READ_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
1851         return rc;
1852 }
1853
1854 /******************************************************************************/
1855 /* Function:   ip2_flush_buffer()                                             */
1856 /* Parameters: Pointer to tty structure                                       */
1857 /* Returns:    Nothing                                                        */
1858 /*                                                                            */
1859 /* Description:                                                               */
1860 /*                                                                            */
1861 /*                                                                            */
1862 /******************************************************************************/
1863 static void
1864 ip2_flush_buffer( PTTY tty )
1865 {
1866         i2ChanStrPtr  pCh = tty->driver_data;
1867         unsigned long flags;
1868
1869         ip2trace (CHANN, ITRC_FLUSH, ITRC_ENTER, 0 );
1870
1871 #ifdef IP2DEBUG_WRITE
1872         printk (KERN_DEBUG "IP2: flush buffer\n" );
1873 #endif
1874         WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
1875         pCh->Pbuf_stuff = 0;
1876         WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
1877         i2FlushOutput( pCh );
1878         ip2_owake(tty);
1879
1880         ip2trace (CHANN, ITRC_FLUSH, ITRC_RETURN, 0 );
1881
1882 }
1883
1884 /******************************************************************************/
1885 /* Function:   ip2_wait_until_sent()                                          */
1886 /* Parameters: Pointer to tty structure                                       */
1887 /*             Timeout for wait.                                              */
1888 /* Returns:    Nothing                                                        */
1889 /*                                                                            */
1890 /* Description:                                                               */
1891 /* This function is used in place of the normal tty_wait_until_sent, which    */
1892 /* only waits for the driver buffers to be empty (or rather, those buffers    */
1893 /* reported by chars_in_buffer) which doesn't work for IP2 due to the         */
1894 /* indeterminate number of bytes buffered on the board.                       */
1895 /******************************************************************************/
1896 static void
1897 ip2_wait_until_sent ( PTTY tty, int timeout )
1898 {
1899         int i = jiffies;
1900         i2ChanStrPtr  pCh = tty->driver_data;
1901
1902         tty_wait_until_sent(tty, timeout );
1903         if ( (i = timeout - (jiffies -i)) > 0)
1904                 i2DrainOutput( pCh, i );
1905 }
1906
1907 /******************************************************************************/
1908 /******************************************************************************/
1909 /* Device Input Section                                                       */
1910 /******************************************************************************/
1911 /******************************************************************************/
1912
1913 /******************************************************************************/
1914 /* Function:   ip2_throttle()                                                 */
1915 /* Parameters: Pointer to tty structure                                       */
1916 /* Returns:    Nothing                                                        */
1917 /*                                                                            */
1918 /* Description:                                                               */
1919 /*                                                                            */
1920 /*                                                                            */
1921 /******************************************************************************/
1922 static void
1923 ip2_throttle ( PTTY tty )
1924 {
1925         i2ChanStrPtr  pCh = tty->driver_data;
1926
1927 #ifdef IP2DEBUG_READ
1928         printk (KERN_DEBUG "IP2: throttle\n" );
1929 #endif
1930         /*
1931          * Signal the poll/interrupt handlers not to forward incoming data to
1932          * the line discipline. This will cause the buffers to fill up in the
1933          * library and thus cause the library routines to send the flow control
1934          * stuff.
1935          */
1936         pCh->throttled = 1;
1937 }
1938
1939 /******************************************************************************/
1940 /* Function:   ip2_unthrottle()                                               */
1941 /* Parameters: Pointer to tty structure                                       */
1942 /* Returns:    Nothing                                                        */
1943 /*                                                                            */
1944 /* Description:                                                               */
1945 /*                                                                            */
1946 /*                                                                            */
1947 /******************************************************************************/
1948 static void
1949 ip2_unthrottle ( PTTY tty )
1950 {
1951         i2ChanStrPtr  pCh = tty->driver_data;
1952         unsigned long flags;
1953
1954 #ifdef IP2DEBUG_READ
1955         printk (KERN_DEBUG "IP2: unthrottle\n" );
1956 #endif
1957
1958         /* Pass incoming data up to the line discipline again. */
1959         pCh->throttled = 0;
1960         i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_RESUME);
1961         serviceOutgoingFifo( pCh->pMyBord );
1962         READ_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,flags)
1963         if ( pCh->Ibuf_stuff != pCh->Ibuf_strip ) {
1964                 READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags)
1965 #ifdef IP2DEBUG_READ
1966                 printk (KERN_DEBUG "i2Input called from unthrottle\n" );
1967 #endif
1968                 i2Input( pCh );
1969         } else
1970                 READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags)
1971 }
1972
1973 static void
1974 ip2_start ( PTTY tty )
1975 {
1976         i2ChanStrPtr  pCh = DevTable[tty->index];
1977
1978         i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_RESUME);
1979         i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_UNSUSPEND);
1980         i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_RESUME);
1981 #ifdef IP2DEBUG_WRITE
1982         printk (KERN_DEBUG "IP2: start tx\n" );
1983 #endif
1984 }
1985
1986 static void
1987 ip2_stop ( PTTY tty )
1988 {
1989         i2ChanStrPtr  pCh = DevTable[tty->index];
1990
1991         i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_SUSPEND);
1992 #ifdef IP2DEBUG_WRITE
1993         printk (KERN_DEBUG "IP2: stop tx\n" );
1994 #endif
1995 }
1996
1997 /******************************************************************************/
1998 /* Device Ioctl Section                                                       */
1999 /******************************************************************************/
2000
2001 static int ip2_tiocmget(struct tty_struct *tty, struct file *file)
2002 {
2003         i2ChanStrPtr pCh = DevTable[tty->index];
2004         wait_queue_t wait;
2005
2006         if (pCh == NULL)
2007                 return -ENODEV;
2008
2009 /*
2010         FIXME - the following code is causing a NULL pointer dereference in
2011         2.3.51 in an interrupt handler.  It's suppose to prompt the board
2012         to return the DSS signal status immediately.  Why doesn't it do
2013         the same thing in 2.2.14?
2014 */
2015
2016 /*      This thing is still busted in the 1.2.12 driver on 2.4.x
2017         and even hoses the serial console so the oops can be trapped.
2018                 /\/\|=mhw=|\/\/                 */
2019
2020 #ifdef  ENABLE_DSSNOW
2021         i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DSS_NOW);
2022
2023         init_waitqueue_entry(&wait, current);
2024         add_wait_queue(&pCh->dss_now_wait, &wait);
2025         set_current_state( TASK_INTERRUPTIBLE );
2026
2027         serviceOutgoingFifo( pCh->pMyBord );
2028
2029         schedule();
2030
2031         set_current_state( TASK_RUNNING );
2032         remove_wait_queue(&pCh->dss_now_wait, &wait);
2033
2034         if (signal_pending(current)) {
2035                 return -EINTR;
2036         }
2037 #endif
2038         return  ((pCh->dataSetOut & I2_RTS) ? TIOCM_RTS : 0)
2039               | ((pCh->dataSetOut & I2_DTR) ? TIOCM_DTR : 0)
2040               | ((pCh->dataSetIn  & I2_DCD) ? TIOCM_CAR : 0)
2041               | ((pCh->dataSetIn  & I2_RI)  ? TIOCM_RNG : 0)
2042               | ((pCh->dataSetIn  & I2_DSR) ? TIOCM_DSR : 0)
2043               | ((pCh->dataSetIn  & I2_CTS) ? TIOCM_CTS : 0);
2044 }
2045
2046 static int ip2_tiocmset(struct tty_struct *tty, struct file *file,
2047                         unsigned int set, unsigned int clear)
2048 {
2049         i2ChanStrPtr pCh = DevTable[tty->index];
2050
2051         if (pCh == NULL)
2052                 return -ENODEV;
2053
2054         if (set & TIOCM_RTS) {
2055                 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_RTSUP);
2056                 pCh->dataSetOut |= I2_RTS;
2057         }
2058         if (set & TIOCM_DTR) {
2059                 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DTRUP);
2060                 pCh->dataSetOut |= I2_DTR;
2061         }
2062
2063         if (clear & TIOCM_RTS) {
2064                 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_RTSDN);
2065                 pCh->dataSetOut &= ~I2_RTS;
2066         }
2067         if (clear & TIOCM_DTR) {
2068                 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DTRDN);
2069                 pCh->dataSetOut &= ~I2_DTR;
2070         }
2071         serviceOutgoingFifo( pCh->pMyBord );
2072         return 0;
2073 }
2074
2075 /******************************************************************************/
2076 /* Function:   ip2_ioctl()                                                    */
2077 /* Parameters: Pointer to tty structure                                       */
2078 /*             Pointer to file structure                                      */
2079 /*             Command                                                        */
2080 /*             Argument                                                       */
2081 /* Returns:    Success or failure                                             */
2082 /*                                                                            */
2083 /* Description:                                                               */
2084 /*                                                                            */
2085 /*                                                                            */
2086 /******************************************************************************/
2087 static int
2088 ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg )
2089 {
2090         wait_queue_t wait;
2091         i2ChanStrPtr pCh = DevTable[tty->index];
2092         struct async_icount cprev, cnow;        /* kernel counter temps */
2093         struct serial_icounter_struct __user *p_cuser;
2094         int rc = 0;
2095         unsigned long flags;
2096         void __user *argp = (void __user *)arg;
2097
2098         if ( pCh == NULL ) {
2099                 return -ENODEV;
2100         }
2101
2102         ip2trace (CHANN, ITRC_IOCTL, ITRC_ENTER, 2, cmd, arg );
2103
2104 #ifdef IP2DEBUG_IOCTL
2105         printk(KERN_DEBUG "IP2: ioctl cmd (%x), arg (%lx)\n", cmd, arg );
2106 #endif
2107
2108         switch(cmd) {
2109         case TIOCGSERIAL:
2110
2111                 ip2trace (CHANN, ITRC_IOCTL, 2, 1, rc );
2112
2113                 rc = get_serial_info(pCh, argp);
2114                 if (rc)
2115                         return rc;
2116                 break;
2117
2118         case TIOCSSERIAL:
2119
2120                 ip2trace (CHANN, ITRC_IOCTL, 3, 1, rc );
2121
2122                 rc = set_serial_info(pCh, argp);
2123                 if (rc)
2124                         return rc;
2125                 break;
2126
2127         case TCXONC:
2128                 rc = tty_check_change(tty);
2129                 if (rc)
2130                         return rc;
2131                 switch (arg) {
2132                 case TCOOFF:
2133                         //return  -ENOIOCTLCMD;
2134                         break;
2135                 case TCOON:
2136                         //return  -ENOIOCTLCMD;
2137                         break;
2138                 case TCIOFF:
2139                         if (STOP_CHAR(tty) != __DISABLED_CHAR) {
2140                                 i2QueueCommands( PTYPE_BYPASS, pCh, 100, 1,
2141                                                 CMD_XMIT_NOW(STOP_CHAR(tty)));
2142                         }
2143                         break;
2144                 case TCION:
2145                         if (START_CHAR(tty) != __DISABLED_CHAR) {
2146                                 i2QueueCommands( PTYPE_BYPASS, pCh, 100, 1,
2147                                                 CMD_XMIT_NOW(START_CHAR(tty)));
2148                         }
2149                         break;
2150                 default:
2151                         return -EINVAL;
2152                 }
2153                 return 0;
2154
2155         case TCSBRK:   /* SVID version: non-zero arg --> no break */
2156                 rc = tty_check_change(tty);
2157
2158                 ip2trace (CHANN, ITRC_IOCTL, 4, 1, rc );
2159
2160                 if (!rc) {
2161                         ip2_wait_until_sent(tty,0);
2162                         if (!arg) {
2163                                 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_SEND_BRK(250));
2164                                 serviceOutgoingFifo( pCh->pMyBord );
2165                         }
2166                 }
2167                 break;
2168
2169         case TCSBRKP:  /* support for POSIX tcsendbreak() */
2170                 rc = tty_check_change(tty);
2171
2172                 ip2trace (CHANN, ITRC_IOCTL, 5, 1, rc );
2173
2174                 if (!rc) {
2175                         ip2_wait_until_sent(tty,0);
2176                         i2QueueCommands(PTYPE_INLINE, pCh, 100, 1,
2177                                 CMD_SEND_BRK(arg ? arg*100 : 250));
2178                         serviceOutgoingFifo ( pCh->pMyBord );   
2179                 }
2180                 break;
2181
2182         case TIOCGSOFTCAR:
2183
2184                 ip2trace (CHANN, ITRC_IOCTL, 6, 1, rc );
2185
2186                         rc = put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *)argp);
2187                 if (rc) 
2188                         return rc;
2189         break;
2190
2191         case TIOCSSOFTCAR:
2192
2193                 ip2trace (CHANN, ITRC_IOCTL, 7, 1, rc );
2194
2195                 rc = get_user(arg,(unsigned long __user *) argp);
2196                 if (rc) 
2197                         return rc;
2198                 tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL)
2199                                          | (arg ? CLOCAL : 0));
2200                 
2201                 break;
2202
2203         /*
2204          * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change - mask
2205          * passed in arg for lines of interest (use |'ed TIOCM_RNG/DSR/CD/CTS
2206          * for masking). Caller should use TIOCGICOUNT to see which one it was
2207          */
2208         case TIOCMIWAIT:
2209                 save_flags(flags);cli();
2210                 cprev = pCh->icount;     /* note the counters on entry */
2211                 restore_flags(flags);
2212                 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 4, 
2213                                                 CMD_DCD_REP, CMD_CTS_REP, CMD_DSR_REP, CMD_RI_REP);
2214                 init_waitqueue_entry(&wait, current);
2215                 add_wait_queue(&pCh->delta_msr_wait, &wait);
2216                 set_current_state( TASK_INTERRUPTIBLE );
2217
2218                 serviceOutgoingFifo( pCh->pMyBord );
2219                 for(;;) {
2220                         ip2trace (CHANN, ITRC_IOCTL, 10, 0 );
2221
2222                         schedule();
2223
2224                         ip2trace (CHANN, ITRC_IOCTL, 11, 0 );
2225
2226                         /* see if a signal did it */
2227                         if (signal_pending(current)) {
2228                                 rc = -ERESTARTSYS;
2229                                 break;
2230                         }
2231                         save_flags(flags);cli();
2232                         cnow = pCh->icount; /* atomic copy */
2233                         restore_flags(flags);
2234                         if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
2235                                 cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) {
2236                                 rc =  -EIO; /* no change => rc */
2237                                 break;
2238                         }
2239                         if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
2240                             ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
2241                             ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) ||
2242                             ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
2243                                 rc =  0;
2244                                 break;
2245                         }
2246                         cprev = cnow;
2247                 }
2248                 set_current_state( TASK_RUNNING );
2249                 remove_wait_queue(&pCh->delta_msr_wait, &wait);
2250
2251                 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 3, 
2252                                                  CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);
2253                 if ( ! (pCh->flags      & ASYNC_CHECK_CD)) {
2254                         i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DCD_NREP);
2255                 }
2256                 serviceOutgoingFifo( pCh->pMyBord );
2257                 return rc;
2258                 break;
2259
2260         /*
2261          * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
2262          * Return: write counters to the user passed counter struct
2263          * NB: both 1->0 and 0->1 transitions are counted except for RI where
2264          * only 0->1 is counted. The controller is quite capable of counting
2265          * both, but this done to preserve compatibility with the standard
2266          * serial driver.
2267          */
2268         case TIOCGICOUNT:
2269                 ip2trace (CHANN, ITRC_IOCTL, 11, 1, rc );
2270
2271                 save_flags(flags);cli();
2272                 cnow = pCh->icount;
2273                 restore_flags(flags);
2274                 p_cuser = argp;
2275                 rc = put_user(cnow.cts, &p_cuser->cts);
2276                 rc = put_user(cnow.dsr, &p_cuser->dsr);
2277                 rc = put_user(cnow.rng, &p_cuser->rng);
2278                 rc = put_user(cnow.dcd, &p_cuser->dcd);
2279                 rc = put_user(cnow.rx, &p_cuser->rx);
2280                 rc = put_user(cnow.tx, &p_cuser->tx);
2281                 rc = put_user(cnow.frame, &p_cuser->frame);
2282                 rc = put_user(cnow.overrun, &p_cuser->overrun);
2283                 rc = put_user(cnow.parity, &p_cuser->parity);
2284                 rc = put_user(cnow.brk, &p_cuser->brk);
2285                 rc = put_user(cnow.buf_overrun, &p_cuser->buf_overrun);
2286                 break;
2287
2288         /*
2289          * The rest are not supported by this driver. By returning -ENOIOCTLCMD they
2290          * will be passed to the line discipline for it to handle.
2291          */
2292         case TIOCSERCONFIG:
2293         case TIOCSERGWILD:
2294         case TIOCSERGETLSR:
2295         case TIOCSERSWILD:
2296         case TIOCSERGSTRUCT:
2297         case TIOCSERGETMULTI:
2298         case TIOCSERSETMULTI:
2299
2300         default:
2301                 ip2trace (CHANN, ITRC_IOCTL, 12, 0 );
2302
2303                 rc =  -ENOIOCTLCMD;
2304                 break;
2305         }
2306
2307         ip2trace (CHANN, ITRC_IOCTL, ITRC_RETURN, 0 );
2308
2309         return rc;
2310 }
2311
2312 /******************************************************************************/
2313 /* Function:   GetSerialInfo()                                                */
2314 /* Parameters: Pointer to channel structure                                   */
2315 /*             Pointer to old termios structure                               */
2316 /* Returns:    Nothing                                                        */
2317 /*                                                                            */
2318 /* Description:                                                               */
2319 /* This is to support the setserial command, and requires processing of the   */
2320 /* standard Linux serial structure.                                           */
2321 /******************************************************************************/
2322 static int
2323 get_serial_info ( i2ChanStrPtr pCh, struct serial_struct __user *retinfo )
2324 {
2325         struct serial_struct tmp;
2326
2327         memset ( &tmp, 0, sizeof(tmp) );
2328         tmp.type = pCh->pMyBord->channelBtypes.bid_value[(pCh->port_index & (IP2_PORTS_PER_BOARD-1))/16];
2329         if (BID_HAS_654(tmp.type)) {
2330                 tmp.type = PORT_16650;
2331         } else {
2332                 tmp.type = PORT_CIRRUS;
2333         }
2334         tmp.line = pCh->port_index;
2335         tmp.port = pCh->pMyBord->i2eBase;
2336         tmp.irq  = ip2config.irq[pCh->port_index/64];
2337         tmp.flags = pCh->flags;
2338         tmp.baud_base = pCh->BaudBase;
2339         tmp.close_delay = pCh->ClosingDelay;
2340         tmp.closing_wait = pCh->ClosingWaitTime;
2341         tmp.custom_divisor = pCh->BaudDivisor;
2342         return copy_to_user(retinfo,&tmp,sizeof(*retinfo));
2343 }
2344
2345 /******************************************************************************/
2346 /* Function:   SetSerialInfo()                                                */
2347 /* Parameters: Pointer to channel structure                                   */
2348 /*             Pointer to old termios structure                               */
2349 /* Returns:    Nothing                                                        */
2350 /*                                                                            */
2351 /* Description:                                                               */
2352 /* This function provides support for setserial, which uses the TIOCSSERIAL   */
2353 /* ioctl. Not all setserial parameters are relevant. If the user attempts to  */
2354 /* change the IRQ, address or type of the port the ioctl fails.               */
2355 /******************************************************************************/
2356 static int
2357 set_serial_info( i2ChanStrPtr pCh, struct serial_struct __user *new_info )
2358 {
2359         struct serial_struct ns;
2360         int   old_flags, old_baud_divisor;
2361
2362         if (copy_from_user(&ns, new_info, sizeof (ns)))
2363                 return -EFAULT;
2364
2365         /*
2366          * We don't allow setserial to change IRQ, board address, type or baud
2367          * base. Also line nunber as such is meaningless but we use it for our
2368          * array index so it is fixed also.
2369          */
2370         if ( (ns.irq        != ip2config.irq[pCh->port_index])
2371             || ((int) ns.port      != ((int) (pCh->pMyBord->i2eBase)))
2372             || (ns.baud_base != pCh->BaudBase)
2373             || (ns.line      != pCh->port_index) ) {
2374                 return -EINVAL;
2375         }
2376
2377         old_flags = pCh->flags;
2378         old_baud_divisor = pCh->BaudDivisor;
2379
2380         if ( !capable(CAP_SYS_ADMIN) ) {
2381                 if ( ( ns.close_delay != pCh->ClosingDelay ) ||
2382                     ( (ns.flags & ~ASYNC_USR_MASK) !=
2383                       (pCh->flags & ~ASYNC_USR_MASK) ) ) {
2384                         return -EPERM;
2385                 }
2386
2387                 pCh->flags = (pCh->flags & ~ASYNC_USR_MASK) |
2388                                (ns.flags & ASYNC_USR_MASK);
2389                 pCh->BaudDivisor = ns.custom_divisor;
2390         } else {
2391                 pCh->flags = (pCh->flags & ~ASYNC_FLAGS) |
2392                                (ns.flags & ASYNC_FLAGS);
2393                 pCh->BaudDivisor = ns.custom_divisor;
2394                 pCh->ClosingDelay = ns.close_delay * HZ/100;
2395                 pCh->ClosingWaitTime = ns.closing_wait * HZ/100;
2396         }
2397
2398         if ( ( (old_flags & ASYNC_SPD_MASK) != (pCh->flags & ASYNC_SPD_MASK) )
2399             || (old_baud_divisor != pCh->BaudDivisor) ) {
2400                 // Invalidate speed and reset parameters
2401                 set_params( pCh, NULL );
2402         }
2403
2404         return 0;
2405 }
2406
2407 /******************************************************************************/
2408 /* Function:   ip2_set_termios()                                              */
2409 /* Parameters: Pointer to tty structure                                       */
2410 /*             Pointer to old termios structure                               */
2411 /* Returns:    Nothing                                                        */
2412 /*                                                                            */
2413 /* Description:                                                               */
2414 /*                                                                            */
2415 /*                                                                            */
2416 /******************************************************************************/
2417 static void
2418 ip2_set_termios( PTTY tty, struct termios *old_termios )
2419 {
2420         i2ChanStrPtr pCh = (i2ChanStrPtr)tty->driver_data;
2421
2422 #ifdef IP2DEBUG_IOCTL
2423         printk (KERN_DEBUG "IP2: set termios %p\n", old_termios );
2424 #endif
2425
2426         set_params( pCh, old_termios );
2427 }
2428
2429 /******************************************************************************/
2430 /* Function:   ip2_set_line_discipline()                                      */
2431 /* Parameters: Pointer to tty structure                                       */
2432 /* Returns:    Nothing                                                        */
2433 /*                                                                            */
2434 /* Description:  Does nothing                                                 */
2435 /*                                                                            */
2436 /*                                                                            */
2437 /******************************************************************************/
2438 static void
2439 ip2_set_line_discipline ( PTTY tty )
2440 {
2441 #ifdef IP2DEBUG_IOCTL
2442         printk (KERN_DEBUG "IP2: set line discipline\n" );
2443 #endif
2444
2445         ip2trace (((i2ChanStrPtr)tty->driver_data)->port_index, ITRC_IOCTL, 16, 0 );
2446
2447 }
2448
2449 /******************************************************************************/
2450 /* Function:   SetLine Characteristics()                                      */
2451 /* Parameters: Pointer to channel structure                                   */
2452 /* Returns:    Nothing                                                        */
2453 /*                                                                            */
2454 /* Description:                                                               */
2455 /* This routine is called to update the channel structure with the new line   */
2456 /* characteristics, and send the appropriate commands to the board when they  */
2457 /* change.                                                                    */
2458 /******************************************************************************/
2459 static void
2460 set_params( i2ChanStrPtr pCh, struct termios *o_tios )
2461 {
2462         tcflag_t cflag, iflag, lflag;
2463         char stop_char, start_char;
2464         struct termios dummy;
2465
2466         lflag = pCh->pTTY->termios->c_lflag;
2467         cflag = pCh->pTTY->termios->c_cflag;
2468         iflag = pCh->pTTY->termios->c_iflag;
2469
2470         if (o_tios == NULL) {
2471                 dummy.c_lflag = ~lflag;
2472                 dummy.c_cflag = ~cflag;
2473                 dummy.c_iflag = ~iflag;
2474                 o_tios = &dummy;
2475         }
2476
2477         {
2478                 switch ( cflag & CBAUD ) {
2479                 case B0:
2480                         i2QueueCommands( PTYPE_BYPASS, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN);
2481                         pCh->dataSetOut &= ~(I2_DTR | I2_RTS);
2482                         i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25));
2483                         pCh->pTTY->termios->c_cflag |= (CBAUD & o_tios->c_cflag);
2484                         goto service_it;
2485                         break;
2486                 case B38400:
2487                         /*
2488                          * This is the speed that is overloaded with all the other high
2489                          * speeds, depending upon the flag settings.
2490                          */
2491                         if ( ( pCh->flags & ASYNC_SPD_MASK ) == ASYNC_SPD_HI ) {
2492                                 pCh->speed = CBR_57600;
2493                         } else if ( (pCh->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI ) {
2494                                 pCh->speed = CBR_115200;
2495                         } else if ( (pCh->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST ) {
2496                                 pCh->speed = CBR_C1;
2497                         } else {
2498                                 pCh->speed = CBR_38400;
2499                         }
2500                         break;
2501                 case B50:      pCh->speed = CBR_50;      break;
2502                 case B75:      pCh->speed = CBR_75;      break;
2503                 case B110:     pCh->speed = CBR_110;     break;
2504                 case B134:     pCh->speed = CBR_134;     break;
2505                 case B150:     pCh->speed = CBR_150;     break;
2506                 case B200:     pCh->speed = CBR_200;     break;
2507                 case B300:     pCh->speed = CBR_300;     break;
2508                 case B600:     pCh->speed = CBR_600;     break;
2509                 case B1200:    pCh->speed = CBR_1200;    break;
2510                 case B1800:    pCh->speed = CBR_1800;    break;
2511                 case B2400:    pCh->speed = CBR_2400;    break;
2512                 case B4800:    pCh->speed = CBR_4800;    break;
2513                 case B9600:    pCh->speed = CBR_9600;    break;
2514                 case B19200:   pCh->speed = CBR_19200;   break;
2515                 case B57600:   pCh->speed = CBR_57600;   break;
2516                 case B115200:  pCh->speed = CBR_115200;  break;
2517                 case B153600:  pCh->speed = CBR_153600;  break;
2518                 case B230400:  pCh->speed = CBR_230400;  break;
2519                 case B307200:  pCh->speed = CBR_307200;  break;
2520                 case B460800:  pCh->speed = CBR_460800;  break;
2521                 case B921600:  pCh->speed = CBR_921600;  break;
2522                 default:       pCh->speed = CBR_9600;    break;
2523                 }
2524                 if ( pCh->speed == CBR_C1 ) {
2525                         // Process the custom speed parameters.
2526                         int bps = pCh->BaudBase / pCh->BaudDivisor;
2527                         if ( bps == 921600 ) {
2528                                 pCh->speed = CBR_921600;
2529                         } else {
2530                                 bps = bps/10;
2531                                 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_BAUD_DEF1(bps) );
2532                         }
2533                 }
2534                 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_SETBAUD(pCh->speed));
2535                 
2536                 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 2, CMD_DTRUP, CMD_RTSUP);
2537                 pCh->dataSetOut |= (I2_DTR | I2_RTS);
2538         }
2539         if ( (CSTOPB & cflag) ^ (CSTOPB & o_tios->c_cflag)) 
2540         {
2541                 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1, 
2542                         CMD_SETSTOP( ( cflag & CSTOPB ) ? CST_2 : CST_1));
2543         }
2544         if (((PARENB|PARODD) & cflag) ^ ((PARENB|PARODD) & o_tios->c_cflag)) 
2545         {
2546                 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1,
2547                         CMD_SETPAR( 
2548                                 (cflag & PARENB ?  (cflag & PARODD ? CSP_OD : CSP_EV) : CSP_NP)
2549                         )
2550                 );
2551         }
2552         /* byte size and parity */
2553         if ( (CSIZE & cflag)^(CSIZE & o_tios->c_cflag)) 
2554         {
2555                 int datasize;
2556                 switch ( cflag & CSIZE ) {
2557                 case CS5: datasize = CSZ_5; break;
2558                 case CS6: datasize = CSZ_6; break;
2559                 case CS7: datasize = CSZ_7; break;
2560                 case CS8: datasize = CSZ_8; break;
2561                 default:  datasize = CSZ_5; break;      /* as per serial.c */
2562                 }
2563                 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1, CMD_SETBITS(datasize) );
2564         }
2565         /* Process CTS flow control flag setting */
2566         if ( (cflag & CRTSCTS) ) {
2567                 i2QueueCommands(PTYPE_INLINE, pCh, 100,
2568                                                 2, CMD_CTSFL_ENAB, CMD_RTSFL_ENAB);
2569         } else {
2570                 i2QueueCommands(PTYPE_INLINE, pCh, 100,
2571                                                 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB);
2572         }
2573         //
2574         // Process XON/XOFF flow control flags settings
2575         //
2576         stop_char = STOP_CHAR(pCh->pTTY);
2577         start_char = START_CHAR(pCh->pTTY);
2578
2579         //////////// can't be \000
2580         if (stop_char == __DISABLED_CHAR ) 
2581         {
2582                 stop_char = ~__DISABLED_CHAR; 
2583         }
2584         if (start_char == __DISABLED_CHAR ) 
2585         {
2586                 start_char = ~__DISABLED_CHAR;
2587         }
2588         /////////////////////////////////
2589
2590         if ( o_tios->c_cc[VSTART] != start_char ) 
2591         {
2592                 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DEF_IXON(start_char));
2593                 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DEF_OXON(start_char));
2594         }
2595         if ( o_tios->c_cc[VSTOP] != stop_char ) 
2596         {
2597                  i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DEF_IXOFF(stop_char));
2598                  i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DEF_OXOFF(stop_char));
2599         }
2600         if (stop_char == __DISABLED_CHAR ) 
2601         {
2602                 stop_char = ~__DISABLED_CHAR;  //TEST123
2603                 goto no_xoff;
2604         }
2605         if ((iflag & (IXOFF))^(o_tios->c_iflag & (IXOFF))) 
2606         {
2607                 if ( iflag & IXOFF ) {  // Enable XOFF output flow control
2608                         i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_OXON_OPT(COX_XON));
2609                 } else {        // Disable XOFF output flow control
2610 no_xoff:
2611                         i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_OXON_OPT(COX_NONE));
2612                 }
2613         }
2614         if (start_char == __DISABLED_CHAR ) 
2615         {
2616                 goto no_xon;
2617         }
2618         if ((iflag & (IXON|IXANY)) ^ (o_tios->c_iflag & (IXON|IXANY))) 
2619         {
2620                 if ( iflag & IXON ) {
2621                         if ( iflag & IXANY ) { // Enable XON/XANY output flow control
2622                                 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_XANY));
2623                         } else { // Enable XON output flow control
2624                                 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_XON));
2625                         }
2626                 } else { // Disable XON output flow control
2627 no_xon:
2628                         i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_NONE));
2629                 }
2630         }
2631         if ( (iflag & ISTRIP) ^ ( o_tios->c_iflag & (ISTRIP)) ) 
2632         {
2633                 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, 
2634                                 CMD_ISTRIP_OPT((iflag & ISTRIP ? 1 : 0)));
2635         }
2636         if ( (iflag & INPCK) ^ ( o_tios->c_iflag & (INPCK)) ) 
2637         {
2638                 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, 
2639                                 CMD_PARCHK((iflag & INPCK) ? CPK_ENAB : CPK_DSAB));
2640         }
2641
2642         if ( (iflag & (IGNBRK|PARMRK|BRKINT|IGNPAR)) 
2643                         ^       ( o_tios->c_iflag & (IGNBRK|PARMRK|BRKINT|IGNPAR)) ) 
2644         {
2645                 char brkrpt = 0;
2646                 char parrpt = 0;
2647
2648                 if ( iflag & IGNBRK ) { /* Ignore breaks altogether */
2649                         /* Ignore breaks altogether */
2650                         i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_BRK_NREP);
2651                 } else {
2652                         if ( iflag & BRKINT ) {
2653                                 if ( iflag & PARMRK ) {
2654                                         brkrpt = 0x0a;  // exception an inline triple
2655                                 } else {
2656                                         brkrpt = 0x1a;  // exception and NULL
2657                                 }
2658                                 brkrpt |= 0x04; // flush input
2659                         } else {
2660                                 if ( iflag & PARMRK ) {
2661                                         brkrpt = 0x0b;  //POSIX triple \0377 \0 \0
2662                                 } else {
2663                                         brkrpt = 0x01;  // Null only
2664                                 }
2665                         }
2666                         i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_BRK_REP(brkrpt));
2667                 } 
2668
2669                 if (iflag & IGNPAR) {
2670                         parrpt = 0x20;
2671                                                                                                         /* would be 2 for not cirrus bug */
2672                                                                                                         /* would be 0x20 cept for cirrus bug */
2673                 } else {
2674                         if ( iflag & PARMRK ) {
2675                                 /*
2676                                  * Replace error characters with 3-byte sequence (\0377,\0,char)
2677                                  */
2678                                 parrpt = 0x04 ;
2679                                 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_ISTRIP_OPT((char)0));
2680                         } else {
2681                                 parrpt = 0x03;
2682                         } 
2683                 }
2684                 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_SET_ERROR(parrpt));
2685         }
2686         if (cflag & CLOCAL) {
2687                 // Status reporting fails for DCD if this is off
2688                 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DCD_NREP);
2689                 pCh->flags &= ~ASYNC_CHECK_CD;
2690         } else {
2691                 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DCD_REP);
2692                 pCh->flags      |= ASYNC_CHECK_CD;
2693         }
2694
2695 service_it:
2696         i2DrainOutput( pCh, 100 );              
2697 }
2698
2699 /******************************************************************************/
2700 /* IPL Device Section                                                         */
2701 /******************************************************************************/
2702
2703 /******************************************************************************/
2704 /* Function:   ip2_ipl_read()                                                  */
2705 /* Parameters: Pointer to device inode                                        */
2706 /*             Pointer to file structure                                      */
2707 /*             Pointer to data                                                */
2708 /*             Number of bytes to read                                        */
2709 /* Returns:    Success or failure                                             */
2710 /*                                                                            */
2711 /* Description:   Ugly                                                        */
2712 /*                                                                            */
2713 /*                                                                            */
2714 /******************************************************************************/
2715
2716 static 
2717 ssize_t
2718 ip2_ipl_read(struct file *pFile, char __user *pData, size_t count, loff_t *off )
2719 {
2720         unsigned int minor = iminor(pFile->f_dentry->d_inode);
2721         int rc = 0;
2722
2723 #ifdef IP2DEBUG_IPL
2724         printk (KERN_DEBUG "IP2IPL: read %p, %d bytes\n", pData, count );
2725 #endif
2726
2727         switch( minor ) {
2728         case 0:     // IPL device
2729                 rc = -EINVAL;
2730                 break;
2731         case 1:     // Status dump
2732                 rc = -EINVAL;
2733                 break;
2734         case 2:     // Ping device
2735                 rc = -EINVAL;
2736                 break;
2737         case 3:     // Trace device
2738                 rc = DumpTraceBuffer ( pData, count );
2739                 break;
2740         case 4:     // Trace device
2741                 rc = DumpFifoBuffer ( pData, count );
2742                 break;
2743         default:
2744                 rc = -ENODEV;
2745                 break;
2746         }
2747         return rc;
2748 }
2749
2750 static int
2751 DumpFifoBuffer ( char __user *pData, int count )
2752 {
2753 #ifdef DEBUG_FIFO
2754         int rc;
2755         rc = copy_to_user(pData, DBGBuf, count);
2756
2757         printk(KERN_DEBUG "Last index %d\n", I );
2758
2759         return count;
2760 #endif  /* DEBUG_FIFO */
2761         return 0;
2762 }
2763
2764 static int
2765 DumpTraceBuffer ( char __user *pData, int count )
2766 {
2767 #ifdef IP2DEBUG_TRACE
2768         int rc;
2769         int dumpcount;
2770         int chunk;
2771         int *pIndex = (int __user *)pData;
2772
2773         if ( count < (sizeof(int) * 6) ) {
2774                 return -EIO;
2775         }
2776         rc = put_user(tracewrap, pIndex );
2777         rc = put_user(TRACEMAX, ++pIndex );
2778         rc = put_user(tracestrip, ++pIndex );
2779         rc = put_user(tracestuff, ++pIndex );
2780         pData += sizeof(int) * 6;
2781         count -= sizeof(int) * 6;
2782
2783         dumpcount = tracestuff - tracestrip;
2784         if ( dumpcount < 0 ) {
2785                 dumpcount += TRACEMAX;
2786         }
2787         if ( dumpcount > count ) {
2788                 dumpcount = count;
2789         }
2790         chunk = TRACEMAX - tracestrip;
2791         if ( dumpcount > chunk ) {
2792                 rc = copy_to_user(pData, &tracebuf[tracestrip],
2793                               chunk * sizeof(tracebuf[0]) );
2794                 pData += chunk * sizeof(tracebuf[0]);
2795                 tracestrip = 0;
2796                 chunk = dumpcount - chunk;
2797         } else {
2798                 chunk = dumpcount;
2799         }
2800         rc = copy_to_user(pData, &tracebuf[tracestrip],
2801                       chunk * sizeof(tracebuf[0]) );
2802         tracestrip += chunk;
2803         tracewrap = 0;
2804
2805         rc = put_user(tracestrip, ++pIndex );
2806         rc = put_user(tracestuff, ++pIndex );
2807
2808         return dumpcount;
2809 #else
2810         return 0;
2811 #endif
2812 }
2813
2814 /******************************************************************************/
2815 /* Function:   ip2_ipl_write()                                                 */
2816 /* Parameters:                                                                */
2817 /*             Pointer to file structure                                      */
2818 /*             Pointer to data                                                */
2819 /*             Number of bytes to write                                       */
2820 /* Returns:    Success or failure                                             */
2821 /*                                                                            */
2822 /* Description:                                                               */
2823 /*                                                                            */
2824 /*                                                                            */
2825 /******************************************************************************/
2826 static ssize_t
2827 ip2_ipl_write(struct file *pFile, const char __user *pData, size_t count, loff_t *off)
2828 {
2829 #ifdef IP2DEBUG_IPL
2830         printk (KERN_DEBUG "IP2IPL: write %p, %d bytes\n", pData, count );
2831 #endif
2832         return 0;
2833 }
2834
2835 /******************************************************************************/
2836 /* Function:   ip2_ipl_ioctl()                                                */
2837 /* Parameters: Pointer to device inode                                        */
2838 /*             Pointer to file structure                                      */
2839 /*             Command                                                        */
2840 /*             Argument                                                       */
2841 /* Returns:    Success or failure                                             */
2842 /*                                                                            */
2843 /* Description:                                                               */
2844 /*                                                                            */
2845 /*                                                                            */
2846 /******************************************************************************/
2847 static int
2848 ip2_ipl_ioctl ( struct inode *pInode, struct file *pFile, UINT cmd, ULONG arg )
2849 {
2850         unsigned int iplminor = iminor(pInode);
2851         int rc = 0;
2852         void __user *argp = (void __user *)arg;
2853         ULONG __user *pIndex = argp;
2854         i2eBordStrPtr pB = i2BoardPtrTable[iplminor / 4];
2855         i2ChanStrPtr pCh;
2856
2857 #ifdef IP2DEBUG_IPL
2858         printk (KERN_DEBUG "IP2IPL: ioctl cmd %d, arg %ld\n", cmd, arg );
2859 #endif
2860
2861         switch ( iplminor ) {
2862         case 0:     // IPL device
2863                 rc = -EINVAL;
2864                 break;
2865         case 1:     // Status dump
2866         case 5:
2867         case 9:
2868         case 13:
2869                 switch ( cmd ) {
2870                 case 64:        /* Driver - ip2stat */
2871                         rc = put_user(ip2_tty_driver->refcount, pIndex++ );
2872                         rc = put_user(irq_counter, pIndex++  );
2873                         rc = put_user(bh_counter, pIndex++  );
2874                         break;
2875
2876                 case 65:        /* Board  - ip2stat */
2877                         if ( pB ) {
2878                                 rc = copy_to_user(argp, pB, sizeof(i2eBordStr));
2879                                 rc = put_user(INB(pB->i2eStatus),
2880                                         (ULONG __user *)(arg + (ULONG)(&pB->i2eStatus) - (ULONG)pB ) );
2881                         } else {
2882                                 rc = -ENODEV;
2883                         }
2884                         break;
2885
2886                 default:
2887                         if (cmd < IP2_MAX_PORTS) {
2888                                 pCh = DevTable[cmd];
2889                                 if ( pCh )
2890                                 {
2891                                         rc = copy_to_user(argp, pCh, sizeof(i2ChanStr));
2892                                 } else {
2893                                         rc = -ENODEV;
2894                                 }
2895                         } else {
2896                                 rc = -EINVAL;
2897                         }
2898                 }
2899                 break;
2900
2901         case 2:     // Ping device
2902                 rc = -EINVAL;
2903                 break;
2904         case 3:     // Trace device
2905                 if ( cmd == 1 ) {
2906                         rc = put_user(iiSendPendingMail, pIndex++ );
2907                         rc = put_user(i2InitChannels, pIndex++ );
2908                         rc = put_user(i2QueueNeeds, pIndex++ );
2909                         rc = put_user(i2QueueCommands, pIndex++ );
2910                         rc = put_user(i2GetStatus, pIndex++ );
2911                         rc = put_user(i2Input, pIndex++ );
2912                         rc = put_user(i2InputFlush, pIndex++ );
2913                         rc = put_user(i2Output, pIndex++ );
2914                         rc = put_user(i2FlushOutput, pIndex++ );
2915                         rc = put_user(i2DrainWakeup, pIndex++ );
2916                         rc = put_user(i2DrainOutput, pIndex++ );
2917                         rc = put_user(i2OutputFree, pIndex++ );
2918                         rc = put_user(i2StripFifo, pIndex++ );
2919                         rc = put_user(i2StuffFifoBypass, pIndex++ );
2920                         rc = put_user(i2StuffFifoFlow, pIndex++ );
2921                         rc = put_user(i2StuffFifoInline, pIndex++ );
2922                         rc = put_user(i2ServiceBoard, pIndex++ );
2923                         rc = put_user(serviceOutgoingFifo, pIndex++ );
2924                         // rc = put_user(ip2_init, pIndex++ );
2925                         rc = put_user(ip2_init_board, pIndex++ );
2926                         rc = put_user(find_eisa_board, pIndex++ );
2927                         rc = put_user(set_irq, pIndex++ );
2928                         rc = put_user(ip2_interrupt, pIndex++ );
2929                         rc = put_user(ip2_poll, pIndex++ );
2930                         rc = put_user(service_all_boards, pIndex++ );
2931                         rc = put_user(do_input, pIndex++ );
2932                         rc = put_user(do_status, pIndex++ );
2933 #ifndef IP2DEBUG_OPEN
2934                         rc = put_user(0, pIndex++ );
2935 #else
2936                         rc = put_user(open_sanity_check, pIndex++ );
2937 #endif
2938                         rc = put_user(ip2_open, pIndex++ );
2939                         rc = put_user(ip2_close, pIndex++ );
2940                         rc = put_user(ip2_hangup, pIndex++ );
2941                         rc = put_user(ip2_write, pIndex++ );
2942                         rc = put_user(ip2_putchar, pIndex++ );
2943                         rc = put_user(ip2_flush_chars, pIndex++ );
2944                         rc = put_user(ip2_write_room, pIndex++ );
2945                         rc = put_user(ip2_chars_in_buf, pIndex++ );
2946                         rc = put_user(ip2_flush_buffer, pIndex++ );
2947
2948                         //rc = put_user(ip2_wait_until_sent, pIndex++ );
2949                         rc = put_user(0, pIndex++ );
2950
2951                         rc = put_user(ip2_throttle, pIndex++ );
2952                         rc = put_user(ip2_unthrottle, pIndex++ );
2953                         rc = put_user(ip2_ioctl, pIndex++ );
2954                         rc = put_user(0, pIndex++ );
2955                         rc = put_user(get_serial_info, pIndex++ );
2956                         rc = put_user(set_serial_info, pIndex++ );
2957                         rc = put_user(ip2_set_termios, pIndex++ );
2958                         rc = put_user(ip2_set_line_discipline, pIndex++ );
2959                         rc = put_user(set_params, pIndex++ );
2960                 } else {
2961                         rc = -EINVAL;
2962                 }
2963
2964                 break;
2965
2966         default:
2967                 rc = -ENODEV;
2968                 break;
2969         }
2970         return rc;
2971 }
2972
2973 /******************************************************************************/
2974 /* Function:   ip2_ipl_open()                                                 */
2975 /* Parameters: Pointer to device inode                                        */
2976 /*             Pointer to file structure                                      */
2977 /* Returns:    Success or failure                                             */
2978 /*                                                                            */
2979 /* Description:                                                               */
2980 /*                                                                            */
2981 /*                                                                            */
2982 /******************************************************************************/
2983 static int
2984 ip2_ipl_open( struct inode *pInode, struct file *pFile )
2985 {
2986         unsigned int iplminor = iminor(pInode);
2987         i2eBordStrPtr pB;
2988         i2ChanStrPtr  pCh;
2989
2990 #ifdef IP2DEBUG_IPL
2991         printk (KERN_DEBUG "IP2IPL: open\n" );
2992 #endif
2993
2994         switch(iplminor) {
2995         // These are the IPL devices
2996         case 0:
2997         case 4:
2998         case 8:
2999         case 12:
3000                 break;
3001
3002         // These are the status devices
3003         case 1:
3004         case 5:
3005         case 9:
3006         case 13:
3007                 break;
3008
3009         // These are the debug devices
3010         case 2:
3011         case 6:
3012         case 10:
3013         case 14:
3014                 pB = i2BoardPtrTable[iplminor / 4];
3015                 pCh = (i2ChanStrPtr) pB->i2eChannelPtr;
3016                 break;
3017
3018         // This is the trace device
3019         case 3:
3020                 break;
3021         }
3022         return 0;
3023 }
3024 /******************************************************************************/
3025 /* Function:   ip2_read_procmem                                               */
3026 /* Parameters:                                                                */
3027 /*                                                                            */
3028 /* Returns: Length of output                                                  */
3029 /*                                                                            */
3030 /* Description:                                                               */
3031 /*   Supplies some driver operating parameters                                */
3032 /*      Not real useful unless your debugging the fifo                                                    */
3033 /*                                                                            */
3034 /******************************************************************************/
3035
3036 #define LIMIT  (PAGE_SIZE - 120)
3037
3038 static int
3039 ip2_read_procmem(char *buf, char **start, off_t offset, int len)
3040 {
3041         i2eBordStrPtr  pB;
3042         i2ChanStrPtr  pCh;
3043         PTTY tty;
3044         int i;
3045
3046         len = 0;
3047
3048 #define FMTLINE "%3d: 0x%08x 0x%08x 0%011o 0%011o\n"
3049 #define FMTLIN2 "     0x%04x 0x%04x tx flow 0x%x\n"
3050 #define FMTLIN3 "     0x%04x 0x%04x rc flow\n"
3051
3052         len += sprintf(buf+len,"\n");
3053
3054         for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
3055                 pB = i2BoardPtrTable[i];
3056                 if ( pB ) {
3057                         len += sprintf(buf+len,"board %d:\n",i);
3058                         len += sprintf(buf+len,"\tFifo rem: %d mty: %x outM %x\n",
3059                                 pB->i2eFifoRemains,pB->i2eWaitingForEmptyFifo,pB->i2eOutMailWaiting);
3060                 }
3061         }
3062
3063         len += sprintf(buf+len,"#: tty flags, port flags,     cflags,     iflags\n");
3064         for (i=0; i < IP2_MAX_PORTS; i++) {
3065                 if (len > LIMIT)
3066                         break;
3067                 pCh = DevTable[i];
3068                 if (pCh) {
3069                         tty = pCh->pTTY;
3070                         if (tty && tty->count) {
3071                                 len += sprintf(buf+len,FMTLINE,i,(int)tty->flags,pCh->flags,
3072                                                                         tty->termios->c_cflag,tty->termios->c_iflag);
3073
3074                                 len += sprintf(buf+len,FMTLIN2,
3075                                                 pCh->outfl.asof,pCh->outfl.room,pCh->channelNeeds);
3076                                 len += sprintf(buf+len,FMTLIN3,pCh->infl.asof,pCh->infl.room);
3077                         }
3078                 }
3079         }
3080         return len;
3081 }
3082
3083 /*
3084  * This is the handler for /proc/tty/driver/ip2
3085  *
3086  * This stretch of code has been largely plagerized from at least three
3087  * different sources including ip2mkdev.c and a couple of other drivers.
3088  * The bugs are all mine.  :-)  =mhw=
3089  */
3090 static int ip2_read_proc(char *page, char **start, off_t off,
3091                                 int count, int *eof, void *data)
3092 {
3093         int     i, j, box;
3094         int     len = 0;
3095         int     boxes = 0;
3096         int     ports = 0;
3097         int     tports = 0;
3098         off_t   begin = 0;
3099         i2eBordStrPtr  pB;
3100
3101         len += sprintf(page, "ip2info: 1.0 driver: %s\n", pcVersion );
3102         len += sprintf(page+len, "Driver: SMajor=%d CMajor=%d IMajor=%d MaxBoards=%d MaxBoxes=%d MaxPorts=%d\n",
3103                         IP2_TTY_MAJOR, IP2_CALLOUT_MAJOR, IP2_IPL_MAJOR,
3104                         IP2_MAX_BOARDS, ABS_MAX_BOXES, ABS_BIGGEST_BOX);
3105
3106         for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
3107                 /* This need to be reset for a board by board count... */
3108                 boxes = 0;
3109                 pB = i2BoardPtrTable[i];
3110                 if( pB ) {
3111                         switch( pB->i2ePom.e.porID & ~POR_ID_RESERVED ) 
3112                         {
3113                         case POR_ID_FIIEX:
3114                                 len += sprintf( page+len, "Board %d: EX ports=", i );
3115                                 for( box = 0; box < ABS_MAX_BOXES; ++box )
3116                                 {
3117                                         ports = 0;
3118
3119                                         if( pB->i2eChannelMap[box] != 0 ) ++boxes;
3120                                         for( j = 0; j < ABS_BIGGEST_BOX; ++j ) 
3121                                         {
3122                                                 if( pB->i2eChannelMap[box] & 1<< j ) {
3123                                                         ++ports;
3124                                                 }
3125                                         }
3126                                         len += sprintf( page+len, "%d,", ports );
3127                                         tports += ports;
3128                                 }
3129
3130                                 --len;  /* Backup over that last comma */
3131
3132                                 len += sprintf( page+len, " boxes=%d width=%d", boxes, pB->i2eDataWidth16 ? 16 : 8 );
3133                                 break;
3134
3135                         case POR_ID_II_4:
3136                                 len += sprintf(page+len, "Board %d: ISA-4 ports=4 boxes=1", i );
3137                                 tports = ports = 4;
3138                                 break;
3139
3140                         case POR_ID_II_8:
3141                                 len += sprintf(page+len, "Board %d: ISA-8-std ports=8 boxes=1", i );
3142                                 tports = ports = 8;
3143                                 break;
3144
3145                         case POR_ID_II_8R:
3146                                 len += sprintf(page+len, "Board %d: ISA-8-RJ11 ports=8 boxes=1", i );
3147                                 tports = ports = 8;
3148                                 break;
3149
3150                         default:
3151                                 len += sprintf(page+len, "Board %d: unknown", i );
3152                                 /* Don't try and probe for minor numbers */
3153                                 tports = ports = 0;
3154                         }
3155
3156                 } else {
3157                         /* Don't try and probe for minor numbers */
3158                         len += sprintf(page+len, "Board %d: vacant", i );
3159                         tports = ports = 0;
3160                 }
3161
3162                 if( tports ) {
3163                         len += sprintf(page+len, " minors=" );
3164
3165                         for ( box = 0; box < ABS_MAX_BOXES; ++box )
3166                         {
3167                                 for ( j = 0; j < ABS_BIGGEST_BOX; ++j )
3168                                 {
3169                                         if ( pB->i2eChannelMap[box] & (1 << j) )
3170                                         {
3171                                                 len += sprintf (page+len,"%d,",
3172                                                         j + ABS_BIGGEST_BOX *
3173                                                         (box+i*ABS_MAX_BOXES));
3174                                         }
3175                                 }
3176                         }
3177
3178                         page[ len - 1 ] = '\n'; /* Overwrite that last comma */
3179                 } else {
3180                         len += sprintf (page+len,"\n" );
3181                 }
3182
3183                 if (len+begin > off+count)
3184                         break;
3185                 if (len+begin < off) {
3186                         begin += len;
3187                         len = 0;
3188                 }
3189         }
3190
3191         if (i >= IP2_MAX_BOARDS)
3192                 *eof = 1;
3193         if (off >= len+begin)
3194                 return 0;
3195
3196         *start = page + (off-begin);
3197         return ((count < begin+len-off) ? count : begin+len-off);
3198  }
3199  
3200 /******************************************************************************/
3201 /* Function:   ip2trace()                                                     */
3202 /* Parameters: Value to add to trace buffer                                   */
3203 /* Returns:    Nothing                                                        */
3204 /*                                                                            */
3205 /* Description:                                                               */
3206 /*                                                                            */
3207 /*                                                                            */
3208 /******************************************************************************/
3209 #ifdef IP2DEBUG_TRACE
3210 void
3211 ip2trace (unsigned short pn, unsigned char cat, unsigned char label, unsigned long codes, ...)
3212 {
3213         long flags;
3214         unsigned long *pCode = &codes;
3215         union ip2breadcrumb bc;
3216         i2ChanStrPtr  pCh;
3217
3218
3219         tracebuf[tracestuff++] = jiffies;
3220         if ( tracestuff == TRACEMAX ) {
3221                 tracestuff = 0;
3222         }
3223         if ( tracestuff == tracestrip ) {
3224                 if ( ++tracestrip == TRACEMAX ) {
3225                         tracestrip = 0;
3226                 }
3227                 ++tracewrap;
3228         }
3229
3230         bc.hdr.port  = 0xff & pn;
3231         bc.hdr.cat   = cat;
3232         bc.hdr.codes = (unsigned char)( codes & 0xff );
3233         bc.hdr.label = label;
3234         tracebuf[tracestuff++] = bc.value;
3235
3236         for (;;) {
3237                 if ( tracestuff == TRACEMAX ) {
3238                         tracestuff = 0;
3239                 }
3240                 if ( tracestuff == tracestrip ) {
3241                         if ( ++tracestrip == TRACEMAX ) {
3242                                 tracestrip = 0;
3243                         }
3244                         ++tracewrap;
3245                 }
3246
3247                 if ( !codes-- )
3248                         break;
3249
3250                 tracebuf[tracestuff++] = *++pCode;
3251         }
3252 }
3253 #endif
3254
3255
3256 MODULE_LICENSE("GPL");