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