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