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