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