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