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