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