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