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