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