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