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