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