3 * (c) 1999 by Computone Corporation
5 ********************************************************************************
7 * PACKAGE: Linux tty Device Driver for IntelliPort family of multiport
8 * serial I/O controllers.
10 * DESCRIPTION: Mainline code for the device driver
12 *******************************************************************************/
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.
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
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.
31 // 1.2.12 /\/\|=mhw=|\/\/
32 // Cleaned up some remove queue cut and paste errors
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
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.
52 // Four box EX was barfing on >128k kmalloc, made structure smaller by
53 // reducing output buffer size
56 // Device file system support (MHW)
60 // Reload of ip2 without unloading ip2main hangs system on cat of /proc/modules
64 // DCD was not reported when CLOCAL was set on call to TIOCMGET
67 // TIOCMGET requests and waits for status return
68 // No DSS interrupts enabled except for DCD when needed
70 // For internal use only
72 //#define IP2DEBUG_INIT
73 //#define IP2DEBUG_OPEN
74 //#define IP2DEBUG_WRITE
75 //#define IP2DEBUG_READ
76 //#define IP2DEBUG_IOCTL
77 //#define IP2DEBUG_IPL
79 //#define IP2DEBUG_TRACE
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>
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>
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>
113 #include <linux/cdk.h>
114 #include <linux/comstats.h>
115 #include <linux/delay.h>
116 #include <linux/bitops.h>
118 #include <asm/system.h>
122 #include <linux/vmalloc.h>
123 #include <linux/init.h>
125 #include <asm/uaccess.h>
127 #include "ip2types.h"
128 #include "ip2trace.h"
129 #include "ip2ioctl.h"
138 #include <linux/proc_fs.h>
139 #include <linux/seq_file.h>
141 static DEFINE_MUTEX(ip2_mutex);
142 static const struct file_operations ip2mem_proc_fops;
143 static const struct file_operations ip2_proc_fops;
145 /********************/
146 /* Type Definitions */
147 /********************/
153 /* String constants to identify ourselves */
154 static const char pcName[] = "Computone IntelliPort Plus multiport driver";
155 static const char pcVersion[] = "1.2.14";
157 /* String constants for port names */
158 static const char pcDriver_name[] = "ip2";
159 static const char pcIpl[] = "ip2ipl";
161 /***********************/
162 /* Function Prototypes */
163 /***********************/
165 /* Global module entry functions */
167 /* Private (static) functions */
168 static int ip2_open(PTTY, struct file *);
169 static void ip2_close(PTTY, struct file *);
170 static int ip2_write(PTTY, const unsigned char *, int);
171 static int ip2_putchar(PTTY, unsigned char);
172 static void ip2_flush_chars(PTTY);
173 static int ip2_write_room(PTTY);
174 static int ip2_chars_in_buf(PTTY);
175 static void ip2_flush_buffer(PTTY);
176 static int ip2_ioctl(PTTY, UINT, ULONG);
177 static void ip2_set_termios(PTTY, struct ktermios *);
178 static void ip2_set_line_discipline(PTTY);
179 static void ip2_throttle(PTTY);
180 static void ip2_unthrottle(PTTY);
181 static void ip2_stop(PTTY);
182 static void ip2_start(PTTY);
183 static void ip2_hangup(PTTY);
184 static int ip2_tiocmget(struct tty_struct *tty);
185 static int ip2_tiocmset(struct tty_struct *tty,
186 unsigned int set, unsigned int clear);
187 static int ip2_get_icount(struct tty_struct *tty,
188 struct serial_icounter_struct *icount);
190 static void set_irq(int, int);
191 static void ip2_interrupt_bh(struct work_struct *work);
192 static irqreturn_t ip2_interrupt(int irq, void *dev_id);
193 static void ip2_poll(unsigned long arg);
194 static inline void service_all_boards(void);
195 static void do_input(struct work_struct *);
196 static void do_status(struct work_struct *);
198 static void ip2_wait_until_sent(PTTY,int);
200 static void set_params (i2ChanStrPtr, struct ktermios *);
201 static int get_serial_info(i2ChanStrPtr, struct serial_struct __user *);
202 static int set_serial_info(i2ChanStrPtr, struct serial_struct __user *);
204 static ssize_t ip2_ipl_read(struct file *, char __user *, size_t, loff_t *);
205 static ssize_t ip2_ipl_write(struct file *, const char __user *, size_t, loff_t *);
206 static long ip2_ipl_ioctl(struct file *, UINT, ULONG);
207 static int ip2_ipl_open(struct inode *, struct file *);
209 static int DumpTraceBuffer(char __user *, int);
210 static int DumpFifoBuffer( char __user *, int);
212 static void ip2_init_board(int, const struct firmware *);
213 static unsigned short find_eisa_board(int);
214 static int ip2_setup(char *str);
220 static struct tty_driver *ip2_tty_driver;
222 /* Here, then is a table of board pointers which the interrupt routine should
223 * scan through to determine who it must service.
225 static unsigned short i2nBoards; // Number of boards here
227 static i2eBordStrPtr i2BoardPtrTable[IP2_MAX_BOARDS];
229 static i2ChanStrPtr DevTable[IP2_MAX_PORTS];
230 //DevTableMem just used to save addresses for kfree
231 static void *DevTableMem[IP2_MAX_BOARDS];
233 /* This is the driver descriptor for the ip2ipl device, which is used to
234 * download the loadware to the boards.
236 static 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,
245 static unsigned long irq_counter;
246 static unsigned long bh_counter;
248 // Use immediate queue to service interrupts
250 //#define USE_IQ // PCI&2.2 needs work
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.
255 #define POLL_TIMEOUT (jiffies + 1)
256 static DEFINE_TIMER(PollTimer, ip2_poll, 0, 0);
258 #ifdef IP2DEBUG_TRACE
259 /* Trace (debug) buffer data */
260 #define TRACEMAX 1000
261 static unsigned long tracebuf[TRACEMAX];
262 static int tracestuff;
263 static int tracestrip;
264 static int tracewrap;
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)
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 */
287 /* Configuration area for modprobe */
289 MODULE_AUTHOR("Doug McNash");
290 MODULE_DESCRIPTION("Computone IntelliPort Plus Driver");
291 MODULE_LICENSE("GPL");
293 #define MAX_CMD_STR 50
295 static int poll_only;
296 static char cmd[MAX_CMD_STR];
299 static int Eisa_slot;
302 static char rirqs[IP2_MAX_BOARDS];
303 static int Valid_Irqs[] = { 3, 4, 5, 7, 10, 11, 12, 15, 0};
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=
309 static int io[IP2_MAX_BOARDS];
310 static int irq[IP2_MAX_BOARDS] = { -1, -1, -1, -1 };
312 MODULE_AUTHOR("Doug McNash");
313 MODULE_DESCRIPTION("Computone IntelliPort Plus Driver");
314 module_param_array(irq, int, NULL, 0);
315 MODULE_PARM_DESC(irq, "Interrupts for IntelliPort Cards");
316 module_param_array(io, int, NULL, 0);
317 MODULE_PARM_DESC(io, "I/O ports for IntelliPort Cards");
318 module_param(poll_only, bool, 0);
319 MODULE_PARM_DESC(poll_only, "Do not use card interrupts");
320 module_param_string(ip2, cmd, MAX_CMD_STR, 0);
321 MODULE_PARM_DESC(ip2, "Contains module parameter passed with 'ip2='");
323 /* for sysfs class support */
324 static struct class *ip2_class;
326 /* Some functions to keep track of what irqs we have */
328 static int __init is_valid_irq(int irq)
332 while (*i != 0 && *i != irq)
338 static void __init mark_requested_irq(char irq)
340 rirqs[iindx++] = irq;
343 static int __exit clear_requested_irq(char irq)
346 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
347 if (rirqs[i] == irq) {
355 static int have_requested_irq(char irq)
357 /* array init to zeros so 0 irq will not be requested as a side
360 for (i = 0; i < IP2_MAX_BOARDS; ++i)
366 /******************************************************************************/
367 /* Function: cleanup_module() */
368 /* Parameters: None */
369 /* Returns: Nothing */
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 /******************************************************************************/
381 static void __exit ip2_cleanup_module(void)
386 del_timer_sync(&PollTimer);
388 /* Reset the boards we have. */
389 for (i = 0; i < IP2_MAX_BOARDS; i++)
390 if (i2BoardPtrTable[i])
391 iiReset(i2BoardPtrTable[i]);
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,
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]);
410 class_destroy(ip2_class);
411 err = tty_unregister_driver(ip2_tty_driver);
413 printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n",
415 put_tty_driver(ip2_tty_driver);
416 unregister_chrdev(IP2_IPL_MAJOR, pcIpl);
417 remove_proc_entry("ip2mem", NULL);
420 for (i = 0; i < IP2_MAX_BOARDS; i++) {
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;
429 pB = i2BoardPtrTable[i];
432 i2BoardPtrTable[i] = NULL;
434 if (DevTableMem[i] != NULL) {
435 kfree(DevTableMem[i]);
436 DevTableMem[i] = NULL;
440 module_exit(ip2_cleanup_module);
442 static const struct tty_operations ip2_ops = {
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,
452 .throttle = ip2_throttle,
453 .unthrottle = ip2_unthrottle,
454 .set_termios = ip2_set_termios,
455 .set_ldisc = ip2_set_line_discipline,
458 .hangup = ip2_hangup,
459 .tiocmget = ip2_tiocmget,
460 .tiocmset = ip2_tiocmset,
461 .get_icount = ip2_get_icount,
462 .proc_fops = &ip2_proc_fops,
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) */
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
483 static const struct firmware *ip2_request_firmware(void)
485 struct platform_device *pdev;
486 const struct firmware *fw;
488 pdev = platform_device_register_simple("ip2", 0, NULL, 0);
490 printk(KERN_ERR "Failed to register platform device for ip2\n");
493 if (request_firmware(&fw, "intelliport2.bin", &pdev->dev)) {
494 printk(KERN_ERR "Failed to load firmware 'intelliport2.bin'\n");
497 platform_device_unregister(pdev);
501 /******************************************************************************
503 * str: kernel command line string
505 * Can't autoprobe the boards so user must specify configuration on
506 * kernel command line. Sane people build it modular but the others
509 * Alternating pairs of io,irq for up to 4 boards.
510 * ip2=io0,irq0,io1,irq1,io2,irq2,io3,irq3
515 * else => ISA I/O address
517 * irq=0 or invalid for ISA will revert to polling mode
519 * Any value = -1, do not overwrite compiled in value.
521 ******************************************************************************/
522 static int __init ip2_setup(char *str)
524 int j, ints[10]; /* 4 boards, 2 parameters + 2 */
527 str = get_options(str, ARRAY_SIZE(ints), ints);
529 for (i = 0, j = 1; i < 4; i++) {
543 __setup("ip2=", ip2_setup);
545 static int __init ip2_loadmain(void)
549 i2eBordStrPtr pB = NULL;
551 const struct firmware *fw = NULL;
557 /* Hard lock the interrupts to zero */
558 irq[0] = irq[1] = irq[2] = irq[3] = poll_only = 0;
561 /* Check module parameter with 'ip2=' has been passed or not */
562 if (!poll_only && (!strncmp(str, "ip2=", 4)))
565 ip2trace(ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0);
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];
574 ip2config.irq[i] = irq[i];
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.
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.
591 poll_only = !poll_only;
593 /* Announce our presence */
594 printk(KERN_INFO "%s version %s\n", pcName, pcVersion);
596 ip2_tty_driver = alloc_tty_driver(IP2_MAX_PORTS);
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 */
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 "
612 ip2config.addr[i] = 0;
615 ip2config.type[i] = ISA;
617 /* Check for valid irq argument, set for polling if
619 if (ip2config.irq[i] &&
620 !is_valid_irq(ip2config.irq[i])) {
621 printk(KERN_ERR "IP2: Bad IRQ(%d) specified\n",
623 /* 0 is polling and is valid in that sense */
624 ip2config.irq[i] = 0;
630 struct pci_dev *pdev = NULL;
634 pdev = pci_get_device(PCI_VENDOR_ID_COMPUTONE,
635 PCI_DEVICE_ID_COMPUTONE_IP2EX, pdev);
637 ip2config.addr[i] = 0;
638 printk(KERN_ERR "IP2: PCI board %d not "
643 if (pci_enable_device(pdev)) {
644 dev_err(&pdev->dev, "can't enable device\n");
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,
652 ip2config.addr[i] = (USHORT)(addr & 0xfffe);
654 dev_err(&pdev->dev, "I/O address error\n");
656 ip2config.irq[i] = pdev->irq;
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 "
665 #endif /* CONFIG_PCI */
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;
673 ip2config.irq[i] = Eisa_irq;
678 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
679 if (ip2config.addr[i]) {
680 pB = kzalloc(sizeof(i2eBordStr), GFP_KERNEL);
682 i2BoardPtrTable[i] = pB;
683 iiSetAddress(pB, ip2config.addr[i],
687 printk(KERN_ERR "IP2: board memory allocation "
691 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
692 pB = i2BoardPtrTable[i];
698 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
699 /* We don't want to request the firmware unless we have at
701 if (i2BoardPtrTable[i] != NULL) {
703 fw = ip2_request_firmware();
706 ip2_init_board(i, fw);
710 release_firmware(fw);
712 ip2trace(ITRC_NO_PORT, ITRC_INIT, 2, 0);
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);
727 ip2trace(ITRC_NO_PORT, ITRC_INIT, 3, 0);
729 err = tty_register_driver(ip2_tty_driver);
731 printk(KERN_ERR "IP2: failed to register tty driver\n");
732 put_tty_driver(ip2_tty_driver);
733 return err; /* leaking resources */
736 err = register_chrdev(IP2_IPL_MAJOR, pcIpl, &ip2_ipl);
738 printk(KERN_ERR "IP2: failed to register IPL device (%d)\n",
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);
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 */
754 ip2trace(ITRC_NO_PORT, ITRC_INIT, 4, 0);
755 /* Register the interrupt handler or poll handler, depending upon the
756 * specified interrupt.
759 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
760 if (ip2config.addr[i] == 0)
763 pB = i2BoardPtrTable[i];
765 device_create(ip2_class, NULL,
766 MKDEV(IP2_IPL_MAJOR, 4 * i),
768 device_create(ip2_class, NULL,
769 MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
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))
777 j + ABS_BIGGEST_BOX *
778 (box+i*ABS_MAX_BOXES),
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;
787 if (ip2config.irq[i] == CIR_POLL) {
789 if (!timer_pending(&PollTimer)) {
790 mod_timer(&PollTimer, POLL_TIMEOUT);
791 printk(KERN_INFO "IP2: polling\n");
794 if (have_requested_irq(ip2config.irq[i]))
796 rc = request_irq(ip2config.irq[i], ip2_interrupt,
798 (ip2config.type[i] == PCI ? IRQF_SHARED : 0),
799 pcName, i2BoardPtrTable[i]);
801 printk(KERN_ERR "IP2: request_irq failed: "
803 ip2config.irq[i] = CIR_POLL;
804 printk(KERN_INFO "IP2: Polling %ld/sec.\n",
805 (POLL_TIMEOUT - jiffies));
808 mark_requested_irq(ip2config.irq[i]);
809 /* Initialise the interrupt handler bottom half
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]);
821 ip2trace(ITRC_NO_PORT, ITRC_INIT, ITRC_RETURN, 0);
826 unregister_chrdev(IP2_IPL_MAJOR, "ip2");
827 /* unregister and put tty here */
830 module_init(ip2_loadmain);
832 /******************************************************************************/
833 /* Function: ip2_init_board() */
834 /* Parameters: Index of board in configuration structure */
835 /* Returns: Success (0) */
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 /******************************************************************************/
843 ip2_init_board(int boardnum, const struct firmware *fw)
846 int nports = 0, nboxes = 0;
848 i2eBordStrPtr pB = i2BoardPtrTable[boardnum];
850 if ( !iiInitialize ( pB ) ) {
851 printk ( KERN_ERR "IP2: Failed to initialize board at 0x%x, error %d\n",
852 pB->i2eBase, pB->i2eError );
855 printk(KERN_INFO "IP2: Board %d: addr=0x%x irq=%d\n", boardnum + 1,
856 ip2config.addr[boardnum], ip2config.irq[boardnum] );
858 if (!request_region( ip2config.addr[boardnum], 8, pcName )) {
859 printk(KERN_ERR "IP2: bad addr=0x%x\n", ip2config.addr[boardnum]);
863 if ( iiDownloadAll ( pB, (loadHdrStrPtr)fw->data, 1, fw->size )
865 printk ( KERN_ERR "IP2: failed to download loadware\n" );
866 goto err_release_region;
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 );
875 switch ( pB->i2ePom.e.porID & ~POR_ID_RESERVED ) {
878 printk( KERN_ERR "IP2: Unknown board type, ID = %x\n",
879 pB->i2ePom.e.porID );
881 goto err_release_region;
884 case POR_ID_II_4: /* IntelliPort-II, ISA-4 (4xRJ45) */
885 printk ( KERN_INFO "IP2: ISA-4\n" );
889 case POR_ID_II_8: /* IntelliPort-II, 8-port using standard brick. */
890 printk ( KERN_INFO "IP2: ISA-8 std\n" );
894 case POR_ID_II_8R: /* IntelliPort-II, 8-port using RJ11's (no CTS) */
895 printk ( KERN_INFO "IP2: ISA-8 RJ11\n" );
899 case POR_ID_FIIEX: /* IntelliPort IIEX */
901 int portnum = IP2_PORTS_PER_BOARD * boardnum;
904 for( box = 0; box < ABS_MAX_BOXES; ++box ) {
905 if ( pB->i2eChannelMap[box] != 0 ) {
908 for( i = 0; i < ABS_BIGGEST_BOX; ++i ) {
909 if ( pB->i2eChannelMap[box] & 1<< i ) {
914 DevTableMem[boardnum] = pCh =
915 kmalloc( sizeof(i2ChanStr) * nports, GFP_KERNEL );
917 printk ( KERN_ERR "IP2: (i2_init_channel:) Out of memory.\n");
918 goto err_release_region;
920 if ( !i2InitChannels( pB, nports, pCh ) ) {
921 printk(KERN_ERR "IP2: i2InitChannels failed: %d\n",pB->i2eError);
923 goto err_release_region;
925 pB->i2eChannelPtr = &DevTable[portnum];
926 pB->i2eChannelCnt = ABS_MOST_PORTS;
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;
937 printk(KERN_INFO "IP2: EX box=%d ports=%d %d bit\n",
938 nboxes, nports, pB->i2eDataWidth16 ? 16 : 8 );
942 DevTableMem[boardnum] = pCh =
943 kmalloc ( sizeof (i2ChanStr) * nports, GFP_KERNEL );
945 printk ( KERN_ERR "IP2: (i2_init_channel:) Out of memory.\n");
946 goto err_release_region;
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);
953 goto err_release_region;
955 pB->i2eChannelPtr = &DevTable[IP2_PORTS_PER_BOARD * boardnum];
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;
963 INIT_WORK(&pB->tqueue_interrupt, ip2_interrupt_bh);
967 release_region(ip2config.addr[boardnum], 8);
970 i2BoardPtrTable[boardnum] = NULL;
974 /******************************************************************************/
975 /* Function: find_eisa_board ( int start_slot ) */
976 /* Parameters: First slot to check */
977 /* Returns: Address of EISA IntelliPort II controller */
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 /******************************************************************************/
985 static unsigned short
986 find_eisa_board( int start_slot )
989 unsigned int idm = 0;
990 unsigned int idp = 0;
991 unsigned int base = 0;
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
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);
1013 * OK, so we are inclined to believe that this is an EISA machine. Find
1014 * an IntelliPort controller.
1016 for( i = start_slot; i < 16; i++ ) {
1018 idm = (inb(base + 0xc80) << 8) | (inb(base + 0xc81) & 0xff);
1019 idp = (inb(base + 0xc82) << 8) | (inb(base + 0xc83) & 0xff);
1021 if ( idm == 0x0e8e ) {
1022 if ( idp == 0x0281 || idp == 0x0218 ) {
1024 } else if ( idp == 0x0282 || idp == 0x0283 ) {
1025 ismine = 3; /* Can do edge-trigger */
1036 /* It's some sort of EISA card, but at what address is it configured? */
1038 setup_address = base + 0xc88;
1039 value = inb(base + 0xc86);
1040 setup_irq = (value & 8) ? Valid_Irqs[value & 7] : 0;
1042 if ( (ismine & 2) && !(value & 0x10) ) {
1043 ismine = 1; /* Could be edging, but not */
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" );
1052 #ifdef IP2DEBUG_INIT
1053 printk(KERN_DEBUG "Computone EISA board in slot %d, I.D. 0x%x%x, Address 0x%x",
1054 base >> 12, idm, idp, setup_address);
1056 printk(KERN_DEBUG ", Interrupt %d %s\n",
1057 setup_irq, (ismine & 2) ? "(edge)" : "(level)");
1059 printk(KERN_DEBUG ", (polled)\n");
1062 return setup_address;
1065 /******************************************************************************/
1066 /* Function: set_irq() */
1067 /* Parameters: index to board in board table */
1069 /* Returns: Success (0) */
1072 /******************************************************************************/
1074 set_irq( int boardnum, int boardIrq )
1076 unsigned char tempCommand[16];
1077 i2eBordStrPtr pB = i2BoardPtrTable[boardnum];
1078 unsigned long flags;
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.
1089 // We will get an interrupt here at the end of this function
1091 iiDisableMailIrq(pB);
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;
1100 * Write to FIFO; don't bother to adjust fifo capacity for this, since
1101 * board will respond almost immediately after SendMail hit.
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;
1109 /* Need to update number of boards before you enable mailbox int */
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
1119 (CMD_OF(tempCommand))[3] = 28; // MAX_BLOCK
1120 (CMD_OF(tempCommand))[4] = 64; // chars
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);
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);
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);
1145 iiEnableMailIrq(pB);
1146 iiSendPendingMail(pB);
1149 /******************************************************************************/
1150 /* Interrupt Handler Section */
1151 /******************************************************************************/
1154 service_all_boards(void)
1159 /* Service every board on the list */
1160 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
1161 pB = i2BoardPtrTable[i];
1163 i2ServiceBoard( pB );
1169 /******************************************************************************/
1170 /* Function: ip2_interrupt_bh(work) */
1171 /* Parameters: work - pointer to the board structure */
1172 /* Returns: Nothing */
1175 /* Service the board in a bottom half interrupt handler and then */
1176 /* reenable the board's interrupts if it has an IRQ number */
1178 /******************************************************************************/
1180 ip2_interrupt_bh(struct work_struct *work)
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.
1190 i2ServiceBoard( pB );
1191 if( pB->i2eUsingIrq ) {
1192 // Re-enable his interrupts
1193 iiEnableMailIrq(pB);
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 */
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. */
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). */
1216 /******************************************************************************/
1218 ip2_irq_work(i2eBordStrPtr pB)
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);
1226 // Park the board on the immediate queue for processing.
1227 schedule_work(&pB->tqueue_interrupt);
1229 // Make sure the immediate queue is flagged to fire.
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.
1237 i2ServiceBoard( pB );
1239 #endif /* USE_IQI */
1243 ip2_polled_interrupt(void)
1248 ip2trace(ITRC_NO_PORT, ITRC_INTR, 99, 1, 0);
1250 /* Service just the boards on the list using this irq */
1251 for( i = 0; i < i2nBoards; ++i ) {
1252 pB = i2BoardPtrTable[i];
1254 // Only process those boards which match our IRQ.
1255 // IRQ = 0 for polled boards, we won't poll "IRQ" boards
1257 if (pB && pB->i2eUsingIrq == 0)
1263 ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 );
1267 ip2_interrupt(int irq, void *dev_id)
1269 i2eBordStrPtr pB = dev_id;
1271 ip2trace (ITRC_NO_PORT, ITRC_INTR, 99, 1, pB->i2eUsingIrq );
1277 ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 );
1281 /******************************************************************************/
1282 /* Function: ip2_poll(unsigned long arg) */
1284 /* Returns: Nothing */
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 /******************************************************************************/
1292 ip2_poll(unsigned long arg)
1294 ip2trace (ITRC_NO_PORT, ITRC_INTR, 100, 0 );
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();
1301 mod_timer(&PollTimer, POLL_TIMEOUT);
1303 ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 );
1306 static void do_input(struct work_struct *work)
1308 i2ChanStrPtr pCh = container_of(work, i2ChanStr, tqueue_input);
1309 unsigned long flags;
1311 ip2trace(CHANN, ITRC_INPUT, 21, 0 );
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);
1320 read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags);
1322 ip2trace(CHANN, ITRC_INPUT, 22, 0 );
1324 i2InputFlush( pCh );
1328 // code duplicated from n_tty (ldisc)
1329 static inline void isig(int sig, struct tty_struct *tty, int flush)
1331 /* FIXME: This is completely bogus */
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 );
1341 static void do_status(struct work_struct *work)
1343 i2ChanStrPtr pCh = container_of(work, i2ChanStr, tqueue_status);
1346 status = i2GetStatus( pCh, (I2_BRK|I2_PAR|I2_FRA|I2_OVR) );
1348 ip2trace (CHANN, ITRC_STATUS, 21, 1, status );
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))
1355 if (I_BRKINT(pCh->pTTY)) {
1356 isig(SIGINT, pCh->pTTY, 1);
1359 wake_up_interruptible(&pCh->pTTY->read_wait);
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
1366 char brkf = TTY_NORMAL;
1367 unsigned char brkc = '\0';
1369 if ( (status & I2_BRK) ) {
1373 else if (status & I2_PAR) {
1376 } else if (status & I2_FRA) {
1379 } else if (status & I2_OVR) {
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;
1388 #endif /* NEVER_HAPPENS_AS_SETUP_XXX */
1392 if ( status & (I2_DDCD | I2_DDSR | I2_DCTS | I2_DRI) ) {
1393 wake_up_interruptible(&pCh->delta_msr_wait);
1395 if ( (pCh->flags & ASYNC_CHECK_CD) && (status & I2_DDCD) ) {
1396 if ( status & I2_DCD ) {
1398 wake_up_interruptible ( &pCh->open_wait );
1401 if (pCh->pTTY && (!(pCh->pTTY->termios->c_cflag & CLOCAL)) ) {
1402 tty_hangup( pCh->pTTY );
1408 ip2trace (CHANN, ITRC_STATUS, 26, 0 );
1411 /******************************************************************************/
1412 /* Device Open/Close/Ioctl Entry Point Section */
1413 /******************************************************************************/
1415 /******************************************************************************/
1416 /* Function: open_sanity_check() */
1417 /* Parameters: Pointer to tty structure */
1418 /* Pointer to file structure */
1419 /* Returns: Success or failure */
1422 /* Verifies the structure magic numbers and cross links. */
1423 /******************************************************************************/
1424 #ifdef IP2DEBUG_OPEN
1426 open_sanity_check( i2ChanStrPtr pCh, i2eBordStrPtr pBrd )
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",
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) {
1437 printk(KERN_INFO "IP2: all pointers check out!\n" );
1443 /******************************************************************************/
1444 /* Function: ip2_open() */
1445 /* Parameters: Pointer to tty structure */
1446 /* Pointer to file structure */
1447 /* Returns: Success or failure */
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 /******************************************************************************/
1456 ip2_open( PTTY tty, struct file *pFile )
1461 i2ChanStrPtr pCh = DevTable[tty->index];
1463 ip2trace (tty->index, ITRC_OPEN, ITRC_ENTER, 0 );
1465 if ( pCh == NULL ) {
1468 /* Setup pointer links in device and tty structures */
1470 tty->driver_data = pCh;
1472 #ifdef IP2DEBUG_OPEN
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 );
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 );
1483 /* Block here until the port is ready (per serial and istallion) */
1485 * 1. If the port is in the middle of closing wait for the completion
1486 * and then return the appropriate error.
1488 init_waitqueue_entry(&wait, current);
1489 add_wait_queue(&pCh->close_wait, &wait);
1490 set_current_state( TASK_INTERRUPTIBLE );
1492 if ( tty_hung_up_p(pFile) || ( pCh->flags & ASYNC_CLOSING )) {
1493 if ( pCh->flags & ASYNC_CLOSING ) {
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;
1504 set_current_state( TASK_RUNNING );
1505 remove_wait_queue(&pCh->close_wait, &wait);
1508 * 3. Handle a non-blocking open of a normal port.
1510 if ( (pFile->f_flags & O_NONBLOCK) || (tty->flags & (1<<TTY_IO_ERROR) )) {
1511 pCh->flags |= ASYNC_NORMAL_ACTIVE;
1515 * 4. Now loop waiting for the port to be free and carrier present
1518 if ( tty->termios->c_cflag & CLOCAL )
1521 #ifdef IP2DEBUG_OPEN
1522 printk(KERN_DEBUG "OpenBlock: do_clocal = %d\n", do_clocal);
1527 init_waitqueue_entry(&wait, current);
1528 add_wait_queue(&pCh->open_wait, &wait);
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;
1540 if (!(pCh->flags & ASYNC_CLOSING) &&
1541 (do_clocal || (pCh->dataSetIn & I2_DCD) )) {
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");
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);
1562 set_current_state( TASK_RUNNING );
1563 remove_wait_queue(&pCh->open_wait, &wait);
1565 --pCh->wopen; //why count?
1567 ip2trace (CHANN, ITRC_OPEN, 4, 0 );
1572 pCh->flags |= ASYNC_NORMAL_ACTIVE;
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 );
1584 * Now set any i2lib options. These may go away if the i2lib code ends
1585 * up rolled into the mainline.
1587 pCh->channelOptions |= CO_NBLOCK_WRITE;
1589 #ifdef IP2DEBUG_OPEN
1590 printk (KERN_DEBUG "IP2: open completed\n" );
1592 serviceOutgoingFifo( pCh->pMyBord );
1594 ip2trace (CHANN, ITRC_OPEN, ITRC_RETURN, 0 );
1599 /******************************************************************************/
1600 /* Function: ip2_close() */
1601 /* Parameters: Pointer to tty structure */
1602 /* Pointer to file structure */
1603 /* Returns: Nothing */
1608 /******************************************************************************/
1610 ip2_close( PTTY tty, struct file *pFile )
1612 i2ChanStrPtr pCh = tty->driver_data;
1618 ip2trace (CHANN, ITRC_CLOSE, ITRC_ENTER, 0 );
1620 #ifdef IP2DEBUG_OPEN
1621 printk(KERN_DEBUG "IP2:close %s:\n",tty->name);
1624 if ( tty_hung_up_p ( pFile ) ) {
1626 ip2trace (CHANN, ITRC_CLOSE, 2, 1, 2 );
1630 if ( tty->count > 1 ) { /* not the last close */
1632 ip2trace (CHANN, ITRC_CLOSE, 2, 1, 3 );
1636 pCh->flags |= ASYNC_CLOSING; // last close actually
1640 if (pCh->ClosingWaitTime != ASYNC_CLOSING_WAIT_NONE) {
1642 * Before we drop DTR, make sure the transmitter has completely drained.
1643 * This uses an timeout, after which the close
1646 ip2_wait_until_sent(tty, pCh->ClosingWaitTime );
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.
1653 i2InputFlush( pCh );
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));
1664 serviceOutgoingFifo ( pCh->pMyBord );
1666 tty_ldisc_flush(tty);
1667 tty_driver_flush_buffer(tty);
1673 if (pCh->ClosingDelay) {
1674 msleep_interruptible(jiffies_to_msecs(pCh->ClosingDelay));
1676 wake_up_interruptible(&pCh->open_wait);
1679 pCh->flags &=~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1680 wake_up_interruptible(&pCh->close_wait);
1682 #ifdef IP2DEBUG_OPEN
1683 DBG_CNT("ip2_close: after wakeups--");
1687 ip2trace (CHANN, ITRC_CLOSE, ITRC_RETURN, 1, 1 );
1692 /******************************************************************************/
1693 /* Function: ip2_hangup() */
1694 /* Parameters: Pointer to tty structure */
1695 /* Returns: Nothing */
1700 /******************************************************************************/
1702 ip2_hangup ( PTTY tty )
1704 i2ChanStrPtr pCh = tty->driver_data;
1710 ip2trace (CHANN, ITRC_HANGUP, ITRC_ENTER, 0 );
1712 ip2_flush_buffer(tty);
1714 /* disable DSS reporting */
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));
1723 i2QueueCommands(PTYPE_INLINE, pCh, 1, 3,
1724 CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);
1725 serviceOutgoingFifo ( pCh->pMyBord );
1727 wake_up_interruptible ( &pCh->delta_msr_wait );
1729 pCh->flags &= ~ASYNC_NORMAL_ACTIVE;
1731 wake_up_interruptible ( &pCh->open_wait );
1733 ip2trace (CHANN, ITRC_HANGUP, ITRC_RETURN, 0 );
1736 /******************************************************************************/
1737 /******************************************************************************/
1738 /* Device Output Section */
1739 /******************************************************************************/
1740 /******************************************************************************/
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 */
1750 /* Description: (MANDATORY) */
1753 /******************************************************************************/
1755 ip2_write( PTTY tty, const unsigned char *pData, int count)
1757 i2ChanStrPtr pCh = tty->driver_data;
1759 unsigned long flags;
1761 ip2trace (CHANN, ITRC_WRITE, ITRC_ENTER, 2, count, -1 );
1763 /* Flush out any buffered data left over from ip2_putchar() calls. */
1764 ip2_flush_chars( tty );
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);
1771 ip2trace (CHANN, ITRC_WRITE, ITRC_RETURN, 1, bytesSent );
1773 return bytesSent > 0 ? bytesSent : 0;
1776 /******************************************************************************/
1777 /* Function: ip2_putchar() */
1778 /* Parameters: Pointer to tty structure */
1779 /* Character to write */
1780 /* Returns: Nothing */
1785 /******************************************************************************/
1787 ip2_putchar( PTTY tty, unsigned char ch )
1789 i2ChanStrPtr pCh = tty->driver_data;
1790 unsigned long flags;
1792 // ip2trace (CHANN, ITRC_PUTC, ITRC_ENTER, 1, ch );
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 );
1800 write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1803 // ip2trace (CHANN, ITRC_PUTC, ITRC_RETURN, 1, ch );
1806 /******************************************************************************/
1807 /* Function: ip2_flush_chars() */
1808 /* Parameters: Pointer to tty structure */
1809 /* Returns: Nothing */
1813 /******************************************************************************/
1815 ip2_flush_chars( PTTY tty )
1818 i2ChanStrPtr pCh = tty->driver_data;
1819 unsigned long flags;
1821 write_lock_irqsave(&pCh->Pbuf_spinlock, flags);
1822 if ( pCh->Pbuf_stuff ) {
1824 // ip2trace (CHANN, ITRC_PUTC, 10, 1, strip );
1827 // We may need to restart i2Output if it does not fullfill this request
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 );
1833 pCh->Pbuf_stuff -= strip;
1835 write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1838 /******************************************************************************/
1839 /* Function: ip2_write_room() */
1840 /* Parameters: Pointer to tty structure */
1841 /* Returns: Number of bytes that the driver can accept */
1845 /******************************************************************************/
1847 ip2_write_room ( PTTY tty )
1850 i2ChanStrPtr pCh = tty->driver_data;
1851 unsigned long flags;
1853 read_lock_irqsave(&pCh->Pbuf_spinlock, flags);
1854 bytesFree = i2OutputFree( pCh ) - pCh->Pbuf_stuff;
1855 read_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1857 ip2trace (CHANN, ITRC_WRITE, 11, 1, bytesFree );
1859 return ((bytesFree > 0) ? bytesFree : 0);
1862 /******************************************************************************/
1863 /* Function: ip2_chars_in_buf() */
1864 /* Parameters: Pointer to tty structure */
1865 /* Returns: Number of bytes queued for transmission */
1870 /******************************************************************************/
1872 ip2_chars_in_buf ( PTTY tty )
1874 i2ChanStrPtr pCh = tty->driver_data;
1876 unsigned long flags;
1878 ip2trace (CHANN, ITRC_WRITE, 12, 1, pCh->Obuf_char_count + pCh->Pbuf_stuff );
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 );
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);
1894 /******************************************************************************/
1895 /* Function: ip2_flush_buffer() */
1896 /* Parameters: Pointer to tty structure */
1897 /* Returns: Nothing */
1902 /******************************************************************************/
1904 ip2_flush_buffer( PTTY tty )
1906 i2ChanStrPtr pCh = tty->driver_data;
1907 unsigned long flags;
1909 ip2trace (CHANN, ITRC_FLUSH, ITRC_ENTER, 0 );
1911 #ifdef IP2DEBUG_WRITE
1912 printk (KERN_DEBUG "IP2: flush buffer\n" );
1914 write_lock_irqsave(&pCh->Pbuf_spinlock, flags);
1915 pCh->Pbuf_stuff = 0;
1916 write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1917 i2FlushOutput( pCh );
1920 ip2trace (CHANN, ITRC_FLUSH, ITRC_RETURN, 0 );
1924 /******************************************************************************/
1925 /* Function: ip2_wait_until_sent() */
1926 /* Parameters: Pointer to tty structure */
1927 /* Timeout for wait. */
1928 /* Returns: Nothing */
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 /******************************************************************************/
1937 ip2_wait_until_sent ( PTTY tty, int timeout )
1940 i2ChanStrPtr pCh = tty->driver_data;
1942 tty_wait_until_sent(tty, timeout );
1943 if ( (i = timeout - (jiffies -i)) > 0)
1944 i2DrainOutput( pCh, i );
1947 /******************************************************************************/
1948 /******************************************************************************/
1949 /* Device Input Section */
1950 /******************************************************************************/
1951 /******************************************************************************/
1953 /******************************************************************************/
1954 /* Function: ip2_throttle() */
1955 /* Parameters: Pointer to tty structure */
1956 /* Returns: Nothing */
1961 /******************************************************************************/
1963 ip2_throttle ( PTTY tty )
1965 i2ChanStrPtr pCh = tty->driver_data;
1967 #ifdef IP2DEBUG_READ
1968 printk (KERN_DEBUG "IP2: throttle\n" );
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
1979 /******************************************************************************/
1980 /* Function: ip2_unthrottle() */
1981 /* Parameters: Pointer to tty structure */
1982 /* Returns: Nothing */
1987 /******************************************************************************/
1989 ip2_unthrottle ( PTTY tty )
1991 i2ChanStrPtr pCh = tty->driver_data;
1992 unsigned long flags;
1994 #ifdef IP2DEBUG_READ
1995 printk (KERN_DEBUG "IP2: unthrottle\n" );
1998 /* Pass incoming data up to the line discipline again. */
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" );
2010 read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags);
2014 ip2_start ( PTTY tty )
2016 i2ChanStrPtr pCh = DevTable[tty->index];
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" );
2027 ip2_stop ( PTTY tty )
2029 i2ChanStrPtr pCh = DevTable[tty->index];
2031 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_SUSPEND);
2032 #ifdef IP2DEBUG_WRITE
2033 printk (KERN_DEBUG "IP2: stop tx\n" );
2037 /******************************************************************************/
2038 /* Device Ioctl Section */
2039 /******************************************************************************/
2041 static int ip2_tiocmget(struct tty_struct *tty)
2043 i2ChanStrPtr pCh = DevTable[tty->index];
2044 #ifdef ENABLE_DSSNOW
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?
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.
2062 #ifdef ENABLE_DSSNOW
2063 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DSS_NOW);
2065 init_waitqueue_entry(&wait, current);
2066 add_wait_queue(&pCh->dss_now_wait, &wait);
2067 set_current_state( TASK_INTERRUPTIBLE );
2069 serviceOutgoingFifo( pCh->pMyBord );
2073 set_current_state( TASK_RUNNING );
2074 remove_wait_queue(&pCh->dss_now_wait, &wait);
2076 if (signal_pending(current)) {
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);
2088 static int ip2_tiocmset(struct tty_struct *tty,
2089 unsigned int set, unsigned int clear)
2091 i2ChanStrPtr pCh = DevTable[tty->index];
2096 if (set & TIOCM_RTS) {
2097 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_RTSUP);
2098 pCh->dataSetOut |= I2_RTS;
2100 if (set & TIOCM_DTR) {
2101 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DTRUP);
2102 pCh->dataSetOut |= I2_DTR;
2105 if (clear & TIOCM_RTS) {
2106 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_RTSDN);
2107 pCh->dataSetOut &= ~I2_RTS;
2109 if (clear & TIOCM_DTR) {
2110 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DTRDN);
2111 pCh->dataSetOut &= ~I2_DTR;
2113 serviceOutgoingFifo( pCh->pMyBord );
2117 /******************************************************************************/
2118 /* Function: ip2_ioctl() */
2119 /* Parameters: Pointer to tty structure */
2120 /* Pointer to file structure */
2123 /* Returns: Success or failure */
2128 /******************************************************************************/
2130 ip2_ioctl ( PTTY tty, UINT cmd, ULONG arg )
2133 i2ChanStrPtr pCh = DevTable[tty->index];
2135 struct async_icount cprev, cnow; /* kernel counter temps */
2137 unsigned long flags;
2138 void __user *argp = (void __user *)arg;
2145 ip2trace (CHANN, ITRC_IOCTL, ITRC_ENTER, 2, cmd, arg );
2147 #ifdef IP2DEBUG_IOCTL
2148 printk(KERN_DEBUG "IP2: ioctl cmd (%x), arg (%lx)\n", cmd, arg );
2154 ip2trace (CHANN, ITRC_IOCTL, 2, 1, rc );
2156 rc = get_serial_info(pCh, argp);
2163 ip2trace (CHANN, ITRC_IOCTL, 3, 1, rc );
2165 rc = set_serial_info(pCh, argp);
2171 rc = tty_check_change(tty);
2176 //return -ENOIOCTLCMD;
2179 //return -ENOIOCTLCMD;
2182 if (STOP_CHAR(tty) != __DISABLED_CHAR) {
2183 i2QueueCommands( PTYPE_BYPASS, pCh, 100, 1,
2184 CMD_XMIT_NOW(STOP_CHAR(tty)));
2188 if (START_CHAR(tty) != __DISABLED_CHAR) {
2189 i2QueueCommands( PTYPE_BYPASS, pCh, 100, 1,
2190 CMD_XMIT_NOW(START_CHAR(tty)));
2198 case TCSBRK: /* SVID version: non-zero arg --> no break */
2199 rc = tty_check_change(tty);
2201 ip2trace (CHANN, ITRC_IOCTL, 4, 1, rc );
2204 ip2_wait_until_sent(tty,0);
2206 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_SEND_BRK(250));
2207 serviceOutgoingFifo( pCh->pMyBord );
2212 case TCSBRKP: /* support for POSIX tcsendbreak() */
2213 rc = tty_check_change(tty);
2215 ip2trace (CHANN, ITRC_IOCTL, 5, 1, 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 );
2227 ip2trace (CHANN, ITRC_IOCTL, 6, 1, rc );
2229 rc = put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *)argp);
2236 ip2trace (CHANN, ITRC_IOCTL, 7, 1, rc );
2238 rc = get_user(arg,(unsigned long __user *) argp);
2241 tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL)
2242 | (arg ? CLOCAL : 0));
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
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 );
2261 serviceOutgoingFifo( pCh->pMyBord );
2263 ip2trace (CHANN, ITRC_IOCTL, 10, 0 );
2267 ip2trace (CHANN, ITRC_IOCTL, 11, 0 );
2269 /* see if a signal did it */
2270 if (signal_pending(current)) {
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 */
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)) ) {
2291 set_current_state( TASK_RUNNING );
2292 remove_wait_queue(&pCh->delta_msr_wait, &wait);
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);
2299 serviceOutgoingFifo( pCh->pMyBord );
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.
2311 case TIOCSERGSTRUCT:
2312 case TIOCSERGETMULTI:
2313 case TIOCSERSETMULTI:
2316 ip2trace (CHANN, ITRC_IOCTL, 12, 0 );
2322 ip2trace (CHANN, ITRC_IOCTL, ITRC_RETURN, 0 );
2327 static int ip2_get_icount(struct tty_struct *tty,
2328 struct serial_icounter_struct *icount)
2330 i2ChanStrPtr pCh = DevTable[tty->index];
2332 struct async_icount cnow; /* kernel counter temp */
2333 unsigned long flags;
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
2349 write_lock_irqsave(&pB->read_fifo_spinlock, flags);
2351 write_unlock_irqrestore(&pB->read_fifo_spinlock, flags);
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;
2367 /******************************************************************************/
2368 /* Function: GetSerialInfo() */
2369 /* Parameters: Pointer to channel structure */
2370 /* Pointer to old termios structure */
2371 /* Returns: Nothing */
2374 /* This is to support the setserial command, and requires processing of the */
2375 /* standard Linux serial structure. */
2376 /******************************************************************************/
2378 get_serial_info ( i2ChanStrPtr pCh, struct serial_struct __user *retinfo )
2380 struct serial_struct tmp;
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;
2387 tmp.type = PORT_CIRRUS;
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));
2400 /******************************************************************************/
2401 /* Function: SetSerialInfo() */
2402 /* Parameters: Pointer to channel structure */
2403 /* Pointer to old termios structure */
2404 /* Returns: Nothing */
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 /******************************************************************************/
2412 set_serial_info( i2ChanStrPtr pCh, struct serial_struct __user *new_info )
2414 struct serial_struct ns;
2415 int old_flags, old_baud_divisor;
2417 if (copy_from_user(&ns, new_info, sizeof (ns)))
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.
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) ) {
2432 old_flags = pCh->flags;
2433 old_baud_divisor = pCh->BaudDivisor;
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) ) ) {
2442 pCh->flags = (pCh->flags & ~ASYNC_USR_MASK) |
2443 (ns.flags & ASYNC_USR_MASK);
2444 pCh->BaudDivisor = ns.custom_divisor;
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;
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 );
2462 /******************************************************************************/
2463 /* Function: ip2_set_termios() */
2464 /* Parameters: Pointer to tty structure */
2465 /* Pointer to old termios structure */
2466 /* Returns: Nothing */
2471 /******************************************************************************/
2473 ip2_set_termios( PTTY tty, struct ktermios *old_termios )
2475 i2ChanStrPtr pCh = (i2ChanStrPtr)tty->driver_data;
2477 #ifdef IP2DEBUG_IOCTL
2478 printk (KERN_DEBUG "IP2: set termios %p\n", old_termios );
2481 set_params( pCh, old_termios );
2484 /******************************************************************************/
2485 /* Function: ip2_set_line_discipline() */
2486 /* Parameters: Pointer to tty structure */
2487 /* Returns: Nothing */
2489 /* Description: Does nothing */
2492 /******************************************************************************/
2494 ip2_set_line_discipline ( PTTY tty )
2496 #ifdef IP2DEBUG_IOCTL
2497 printk (KERN_DEBUG "IP2: set line discipline\n" );
2500 ip2trace (((i2ChanStrPtr)tty->driver_data)->port_index, ITRC_IOCTL, 16, 0 );
2504 /******************************************************************************/
2505 /* Function: SetLine Characteristics() */
2506 /* Parameters: Pointer to channel structure */
2507 /* Returns: Nothing */
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 */
2513 /******************************************************************************/
2515 set_params( i2ChanStrPtr pCh, struct ktermios *o_tios )
2517 tcflag_t cflag, iflag, lflag;
2518 char stop_char, start_char;
2519 struct ktermios dummy;
2521 lflag = pCh->pTTY->termios->c_lflag;
2522 cflag = pCh->pTTY->termios->c_cflag;
2523 iflag = pCh->pTTY->termios->c_iflag;
2525 if (o_tios == NULL) {
2526 dummy.c_lflag = ~lflag;
2527 dummy.c_cflag = ~cflag;
2528 dummy.c_iflag = ~iflag;
2533 switch ( cflag & CBAUD ) {
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);
2543 * This is the speed that is overloaded with all the other high
2544 * speeds, depending upon the flag settings.
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;
2553 pCh->speed = CBR_38400;
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;
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;
2586 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_BAUD_DEF1(bps) );
2589 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_SETBAUD(pCh->speed));
2591 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 2, CMD_DTRUP, CMD_RTSUP);
2592 pCh->dataSetOut |= (I2_DTR | I2_RTS);
2594 if ( (CSTOPB & cflag) ^ (CSTOPB & o_tios->c_cflag))
2596 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1,
2597 CMD_SETSTOP( ( cflag & CSTOPB ) ? CST_2 : CST_1));
2599 if (((PARENB|PARODD) & cflag) ^ ((PARENB|PARODD) & o_tios->c_cflag))
2601 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1,
2603 (cflag & PARENB ? (cflag & PARODD ? CSP_OD : CSP_EV) : CSP_NP)
2607 /* byte size and parity */
2608 if ( (CSIZE & cflag)^(CSIZE & o_tios->c_cflag))
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 */
2618 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1, CMD_SETBITS(datasize) );
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);
2625 i2QueueCommands(PTYPE_INLINE, pCh, 100,
2626 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB);
2629 // Process XON/XOFF flow control flags settings
2631 stop_char = STOP_CHAR(pCh->pTTY);
2632 start_char = START_CHAR(pCh->pTTY);
2634 //////////// can't be \000
2635 if (stop_char == __DISABLED_CHAR )
2637 stop_char = ~__DISABLED_CHAR;
2639 if (start_char == __DISABLED_CHAR )
2641 start_char = ~__DISABLED_CHAR;
2643 /////////////////////////////////
2645 if ( o_tios->c_cc[VSTART] != start_char )
2647 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DEF_IXON(start_char));
2648 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DEF_OXON(start_char));
2650 if ( o_tios->c_cc[VSTOP] != stop_char )
2652 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DEF_IXOFF(stop_char));
2653 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DEF_OXOFF(stop_char));
2655 if (stop_char == __DISABLED_CHAR )
2657 stop_char = ~__DISABLED_CHAR; //TEST123
2660 if ((iflag & (IXOFF))^(o_tios->c_iflag & (IXOFF)))
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
2666 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_OXON_OPT(COX_NONE));
2669 if (start_char == __DISABLED_CHAR )
2673 if ((iflag & (IXON|IXANY)) ^ (o_tios->c_iflag & (IXON|IXANY)))
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));
2681 } else { // Disable XON output flow control
2683 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_NONE));
2686 if ( (iflag & ISTRIP) ^ ( o_tios->c_iflag & (ISTRIP)) )
2688 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1,
2689 CMD_ISTRIP_OPT((iflag & ISTRIP ? 1 : 0)));
2691 if ( (iflag & INPCK) ^ ( o_tios->c_iflag & (INPCK)) )
2693 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1,
2694 CMD_PARCHK((iflag & INPCK) ? CPK_ENAB : CPK_DSAB));
2697 if ( (iflag & (IGNBRK|PARMRK|BRKINT|IGNPAR))
2698 ^ ( o_tios->c_iflag & (IGNBRK|PARMRK|BRKINT|IGNPAR)) )
2703 if ( iflag & IGNBRK ) { /* Ignore breaks altogether */
2704 /* Ignore breaks altogether */
2705 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_BRK_NREP);
2707 if ( iflag & BRKINT ) {
2708 if ( iflag & PARMRK ) {
2709 brkrpt = 0x0a; // exception an inline triple
2711 brkrpt = 0x1a; // exception and NULL
2713 brkrpt |= 0x04; // flush input
2715 if ( iflag & PARMRK ) {
2716 brkrpt = 0x0b; //POSIX triple \0377 \0 \0
2718 brkrpt = 0x01; // Null only
2721 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_BRK_REP(brkrpt));
2724 if (iflag & IGNPAR) {
2726 /* would be 2 for not cirrus bug */
2727 /* would be 0x20 cept for cirrus bug */
2729 if ( iflag & PARMRK ) {
2731 * Replace error characters with 3-byte sequence (\0377,\0,char)
2734 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_ISTRIP_OPT((char)0));
2739 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_SET_ERROR(parrpt));
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;
2746 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DCD_REP);
2747 pCh->flags |= ASYNC_CHECK_CD;
2751 i2DrainOutput( pCh, 100 );
2754 /******************************************************************************/
2755 /* IPL Device Section */
2756 /******************************************************************************/
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 */
2766 /* Description: Ugly */
2769 /******************************************************************************/
2773 ip2_ipl_read(struct file *pFile, char __user *pData, size_t count, loff_t *off )
2775 unsigned int minor = iminor(pFile->f_path.dentry->d_inode);
2779 printk (KERN_DEBUG "IP2IPL: read %p, %d bytes\n", pData, count );
2783 case 0: // IPL device
2786 case 1: // Status dump
2789 case 2: // Ping device
2792 case 3: // Trace device
2793 rc = DumpTraceBuffer ( pData, count );
2795 case 4: // Trace device
2796 rc = DumpFifoBuffer ( pData, count );
2806 DumpFifoBuffer ( char __user *pData, int count )
2810 rc = copy_to_user(pData, DBGBuf, count);
2812 printk(KERN_DEBUG "Last index %d\n", I );
2815 #endif /* DEBUG_FIFO */
2820 DumpTraceBuffer ( char __user *pData, int count )
2822 #ifdef IP2DEBUG_TRACE
2826 int *pIndex = (int __user *)pData;
2828 if ( count < (sizeof(int) * 6) ) {
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;
2838 dumpcount = tracestuff - tracestrip;
2839 if ( dumpcount < 0 ) {
2840 dumpcount += TRACEMAX;
2842 if ( dumpcount > count ) {
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]);
2851 chunk = dumpcount - chunk;
2855 rc = copy_to_user(pData, &tracebuf[tracestrip],
2856 chunk * sizeof(tracebuf[0]) );
2857 tracestrip += chunk;
2860 rc = put_user(tracestrip, ++pIndex );
2861 rc = put_user(tracestuff, ++pIndex );
2869 /******************************************************************************/
2870 /* Function: ip2_ipl_write() */
2872 /* Pointer to file structure */
2873 /* Pointer to data */
2874 /* Number of bytes to write */
2875 /* Returns: Success or failure */
2880 /******************************************************************************/
2882 ip2_ipl_write(struct file *pFile, const char __user *pData, size_t count, loff_t *off)
2885 printk (KERN_DEBUG "IP2IPL: write %p, %d bytes\n", pData, count );
2890 /******************************************************************************/
2891 /* Function: ip2_ipl_ioctl() */
2892 /* Parameters: Pointer to device inode */
2893 /* Pointer to file structure */
2896 /* Returns: Success or failure */
2901 /******************************************************************************/
2903 ip2_ipl_ioctl (struct file *pFile, UINT cmd, ULONG arg )
2905 unsigned int iplminor = iminor(pFile->f_path.dentry->d_inode);
2907 void __user *argp = (void __user *)arg;
2908 ULONG __user *pIndex = argp;
2909 i2eBordStrPtr pB = i2BoardPtrTable[iplminor / 4];
2913 printk (KERN_DEBUG "IP2IPL: ioctl cmd %d, arg %ld\n", cmd, arg );
2916 mutex_lock(&ip2_mutex);
2918 switch ( iplminor ) {
2919 case 0: // IPL device
2922 case 1: // Status dump
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++ );
2933 case 65: /* Board - ip2stat */
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 ) );
2944 if (cmd < IP2_MAX_PORTS) {
2945 pCh = DevTable[cmd];
2948 rc = copy_to_user(argp, pCh, sizeof(i2ChanStr));
2960 case 2: // Ping device
2963 case 3: // Trace device
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
2980 mutex_unlock(&ip2_mutex);
2984 /******************************************************************************/
2985 /* Function: ip2_ipl_open() */
2986 /* Parameters: Pointer to device inode */
2987 /* Pointer to file structure */
2988 /* Returns: Success or failure */
2993 /******************************************************************************/
2995 ip2_ipl_open( struct inode *pInode, struct file *pFile )
2999 printk (KERN_DEBUG "IP2IPL: open\n" );
3005 proc_ip2mem_show(struct seq_file *m, void *v)
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"
3018 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
3019 pB = i2BoardPtrTable[i];
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);
3027 seq_printf(m,"#: tty flags, port flags, cflags, iflags\n");
3028 for (i=0; i < IP2_MAX_PORTS; i++) {
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);
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);
3045 static int proc_ip2mem_open(struct inode *inode, struct file *file)
3047 return single_open(file, proc_ip2mem_show, NULL);
3050 static const struct file_operations ip2mem_proc_fops = {
3051 .owner = THIS_MODULE,
3052 .open = proc_ip2mem_open,
3054 .llseek = seq_lseek,
3055 .release = single_release,
3059 * This is the handler for /proc/tty/driver/ip2
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=
3065 static int ip2_proc_show(struct seq_file *m, void *v)
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);
3079 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
3080 /* This need to be reset for a board by board count... */
3082 pB = i2BoardPtrTable[i];
3084 switch( pB->i2ePom.e.porID & ~POR_ID_RESERVED )
3087 seq_printf(m, "Board %d: EX ports=", i);
3089 for( box = 0; box < ABS_MAX_BOXES; ++box )
3093 if( pB->i2eChannelMap[box] != 0 ) ++boxes;
3094 for( j = 0; j < ABS_BIGGEST_BOX; ++j )
3096 if( pB->i2eChannelMap[box] & 1<< j ) {
3100 seq_printf(m, "%s%d", sep, ports);
3104 seq_printf(m, " boxes=%d width=%d", boxes, pB->i2eDataWidth16 ? 16 : 8);
3108 seq_printf(m, "Board %d: ISA-4 ports=4 boxes=1", i);
3113 seq_printf(m, "Board %d: ISA-8-std ports=8 boxes=1", i);
3118 seq_printf(m, "Board %d: ISA-8-RJ11 ports=8 boxes=1", i);
3123 seq_printf(m, "Board %d: unknown", i);
3124 /* Don't try and probe for minor numbers */
3129 /* Don't try and probe for minor numbers */
3130 seq_printf(m, "Board %d: vacant", i);
3135 seq_puts(m, " minors=");
3137 for ( box = 0; box < ABS_MAX_BOXES; ++box )
3139 for ( j = 0; j < ABS_BIGGEST_BOX; ++j )
3141 if ( pB->i2eChannelMap[box] & (1 << j) )
3143 seq_printf(m, "%s%d", sep,
3144 j + ABS_BIGGEST_BOX *
3145 (box+i*ABS_MAX_BOXES));
3156 static int ip2_proc_open(struct inode *inode, struct file *file)
3158 return single_open(file, ip2_proc_show, NULL);
3161 static const struct file_operations ip2_proc_fops = {
3162 .owner = THIS_MODULE,
3163 .open = ip2_proc_open,
3165 .llseek = seq_lseek,
3166 .release = single_release,
3169 /******************************************************************************/
3170 /* Function: ip2trace() */
3171 /* Parameters: Value to add to trace buffer */
3172 /* Returns: Nothing */
3177 /******************************************************************************/
3178 #ifdef IP2DEBUG_TRACE
3180 ip2trace (unsigned short pn, unsigned char cat, unsigned char label, unsigned long codes, ...)
3183 unsigned long *pCode = &codes;
3184 union ip2breadcrumb bc;
3188 tracebuf[tracestuff++] = jiffies;
3189 if ( tracestuff == TRACEMAX ) {
3192 if ( tracestuff == tracestrip ) {
3193 if ( ++tracestrip == TRACEMAX ) {
3199 bc.hdr.port = 0xff & pn;
3201 bc.hdr.codes = (unsigned char)( codes & 0xff );
3202 bc.hdr.label = label;
3203 tracebuf[tracestuff++] = bc.value;
3206 if ( tracestuff == TRACEMAX ) {
3209 if ( tracestuff == tracestrip ) {
3210 if ( ++tracestrip == TRACEMAX ) {
3219 tracebuf[tracestuff++] = *++pCode;
3225 MODULE_LICENSE("GPL");
3227 static struct pci_device_id ip2main_pci_tbl[] __devinitdata __used = {
3228 { PCI_DEVICE(PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_IP2EX) },
3232 MODULE_DEVICE_TABLE(pci, ip2main_pci_tbl);
3234 MODULE_FIRMWARE("intelliport2.bin");