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