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